am 9919088b: am c2260830: Merge "Update RenderScript docs to include Support Library APIs" into jb-mr2-ub-dev

* commit '9919088b943f4fc7800d2c0307182f905bb248e4':
  Update RenderScript docs to include Support Library APIs
diff --git a/Android.mk b/Android.mk
index d58d8ad..14d1a02 100644
--- a/Android.mk
+++ b/Android.mk
@@ -26,7 +26,10 @@
 # TODO: find a more appropriate way to do this.
 framework_res_source_path := APPS/framework-res_intermediates/src
 
-# the library
+# Build the master framework library.
+# The framework contains too many method references (>64K) for poor old DEX.
+# So we first build the framework as a monolithic static library then split it
+# up into smaller pieces.
 # ============================================================
 include $(CLEAR_VARS)
 
@@ -39,14 +42,6 @@
        core/java/android/speech/tts/EventLogTags.logtags \
        core/java/android/webkit/EventLogTags.logtags \
 
-# The following filters out code we are temporarily not including at all.
-# TODO: Move AWT and beans (and associated harmony code) back into libcore.
-# TODO: Maybe remove javax.microedition entirely?
-# TODO: Move SyncML (org.mobilecontrol.*) into its own library.
-LOCAL_SRC_FILES := $(filter-out \
-			org/mobilecontrol/% \
-			,$(LOCAL_SRC_FILES))
-
 ## READ ME: ########################################################
 ##
 ## When updating this list of aidl files, consider if that aidl is
@@ -100,6 +95,7 @@
 	core/java/android/bluetooth/IBluetoothManager.aidl \
 	core/java/android/bluetooth/IBluetoothManagerCallback.aidl \
 	core/java/android/bluetooth/IBluetoothPbap.aidl \
+	core/java/android/bluetooth/IBluetoothMap.aidl \
 	core/java/android/bluetooth/IBluetoothStateChangeCallback.aidl \
 	core/java/android/bluetooth/IBluetoothGatt.aidl \
 	core/java/android/bluetooth/IBluetoothGattCallback.aidl \
@@ -109,6 +105,7 @@
 	core/java/android/content/IIntentReceiver.aidl \
 	core/java/android/content/IIntentSender.aidl \
 	core/java/android/content/IOnPrimaryClipChangedListener.aidl \
+	core/java/android/content/IAnonymousSyncAdapter.aidl \
 	core/java/android/content/ISyncAdapter.aidl \
 	core/java/android/content/ISyncContext.aidl \
 	core/java/android/content/ISyncStatusObserver.aidl \
@@ -119,11 +116,22 @@
 	core/java/android/content/pm/IPackageMoveObserver.aidl \
 	core/java/android/content/pm/IPackageStatsObserver.aidl \
 	core/java/android/database/IContentObserver.aidl \
+	core/java/android/hardware/ICameraService.aidl \
+	core/java/android/hardware/ICameraServiceListener.aidl \
+	core/java/android/hardware/ICamera.aidl \
+	core/java/android/hardware/ICameraClient.aidl \
+	core/java/android/hardware/IConsumerIrService.aidl \
+	core/java/android/hardware/IProCameraUser.aidl \
+	core/java/android/hardware/IProCameraCallbacks.aidl \
+	core/java/android/hardware/camera2/ICameraDeviceUser.aidl \
+	core/java/android/hardware/camera2/ICameraDeviceCallbacks.aidl \
 	core/java/android/hardware/ISerialManager.aidl \
 	core/java/android/hardware/display/IDisplayManager.aidl \
 	core/java/android/hardware/display/IDisplayManagerCallback.aidl \
 	core/java/android/hardware/input/IInputManager.aidl \
 	core/java/android/hardware/input/IInputDevicesChangedListener.aidl \
+	core/java/android/hardware/location/IFusedLocationHardware.aidl \
+	core/java/android/hardware/location/IFusedLocationHardwareSink.aidl \
 	core/java/android/hardware/location/IGeofenceHardware.aidl \
 	core/java/android/hardware/location/IGeofenceHardwareCallback.aidl \
 	core/java/android/hardware/location/IGeofenceHardwareMonitorCallback.aidl \
@@ -135,10 +143,13 @@
 	core/java/android/net/INetworkStatsService.aidl \
 	core/java/android/net/INetworkStatsSession.aidl \
 	core/java/android/net/nsd/INsdManager.aidl \
-	core/java/android/nfc/INdefPushCallback.aidl \
+	core/java/android/nfc/IAppCallback.aidl \
 	core/java/android/nfc/INfcAdapter.aidl \
 	core/java/android/nfc/INfcAdapterExtras.aidl \
 	core/java/android/nfc/INfcTag.aidl \
+	core/java/android/nfc/INfcCardEmulation.aidl \
+	core/java/android/os/IBatteryPropertiesListener.aidl \
+	core/java/android/os/IBatteryPropertiesRegistrar.aidl \
 	core/java/android/os/ICancellationSignal.aidl \
 	core/java/android/os/IHardwareService.aidl \
 	core/java/android/os/IMessenger.aidl \
@@ -151,6 +162,17 @@
 	core/java/android/os/IUserManager.aidl \
 	core/java/android/os/IVibratorService.aidl \
 	core/java/android/service/notification/INotificationListener.aidl \
+	core/java/android/print/ILayoutResultCallback.aidl \
+	core/java/android/print/IPrinterDiscoveryObserver.aidl \
+	core/java/android/print/IPrintDocumentAdapter.aidl \
+	core/java/android/print/IPrintClient.aidl \
+	core/java/android/print/IPrintManager.aidl \
+	core/java/android/print/IPrintSpooler.aidl \
+	core/java/android/print/IPrintSpoolerCallbacks.aidl \
+	core/java/android/print/IPrintSpoolerClient.aidl \
+	core/java/android/print/IWriteResultCallback.aidl \
+	core/java/android/printservice/IPrintService.aidl \
+	core/java/android/printservice/IPrintServiceClient.aidl \
 	core/java/android/service/dreams/IDreamManager.aidl \
 	core/java/android/service/dreams/IDreamService.aidl \
 	core/java/android/service/wallpaper/IWallpaperConnection.aidl \
@@ -161,6 +183,7 @@
 	core/java/android/view/accessibility/IAccessibilityManager.aidl \
 	core/java/android/view/accessibility/IAccessibilityManagerClient.aidl \
 	core/java/android/view/IApplicationToken.aidl \
+	core/java/android/view/IAssetAtlas.aidl \
 	core/java/android/view/IMagnificationCallbacks.aidl \
 	core/java/android/view/IInputFilter.aidl \
 	core/java/android/view/IInputFilterHost.aidl \
@@ -178,6 +201,7 @@
 	core/java/com/android/internal/app/IAppOpsCallback.aidl \
 	core/java/com/android/internal/app/IAppOpsService.aidl \
 	core/java/com/android/internal/app/IBatteryStats.aidl \
+	core/java/com/android/internal/app/IProcessStats.aidl \
 	core/java/com/android/internal/app/IUsageStats.aidl \
 	core/java/com/android/internal/app/IMediaContainerService.aidl \
 	core/java/com/android/internal/appwidget/IAppWidgetService.aidl \
@@ -186,6 +210,9 @@
 	core/java/com/android/internal/backup/IObbBackupService.aidl \
 	core/java/com/android/internal/policy/IFaceLockCallback.aidl \
 	core/java/com/android/internal/policy/IFaceLockInterface.aidl \
+	core/java/com/android/internal/policy/IKeyguardShowCallback.aidl \
+	core/java/com/android/internal/policy/IKeyguardExitCallback.aidl \
+	core/java/com/android/internal/policy/IKeyguardService.aidl \
 	core/java/com/android/internal/os/IDropBoxManagerService.aidl \
 	core/java/com/android/internal/os/IResultReceiver.aidl \
 	core/java/com/android/internal/statusbar/IStatusBar.aidl \
@@ -209,12 +236,14 @@
 	keystore/java/android/security/IKeyChainService.aidl \
 	location/java/android/location/ICountryDetector.aidl \
 	location/java/android/location/ICountryListener.aidl \
+	location/java/android/location/IFusedProvider.aidl \
 	location/java/android/location/IGeocodeProvider.aidl \
 	location/java/android/location/IGeofenceProvider.aidl \
 	location/java/android/location/IGpsStatusListener.aidl \
 	location/java/android/location/IGpsStatusProvider.aidl \
 	location/java/android/location/ILocationListener.aidl \
 	location/java/android/location/ILocationManager.aidl \
+	location/java/android/location/IFusedGeofenceHardware.aidl \
 	location/java/android/location/IGpsGeofenceHardware.aidl \
 	location/java/android/location/INetInitiatedListener.aidl \
 	location/java/com/android/internal/location/ILocationProvider.aidl \
@@ -234,9 +263,10 @@
 	telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl \
 	telephony/java/com/android/internal/telephony/IWapPushManager.aidl \
 	wifi/java/android/net/wifi/IWifiManager.aidl \
-	wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl
-#
-
+	wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl \
+	packages/services/PacProcessor/com/android/net/IProxyService.aidl \
+	packages/services/Proxy/com/android/net/IProxyCallback.aidl \
+	packages/services/Proxy/com/android/net/IProxyPortListener.aidl \
 
 # FRAMEWORKS_BASE_JAVA_SRC_DIRS comes from build/core/pathmap.mk
 LOCAL_AIDL_INCLUDES += $(FRAMEWORKS_BASE_JAVA_SRC_DIRS)
@@ -249,17 +279,11 @@
 LOCAL_NO_STANDARD_LIBRARIES := true
 LOCAL_JAVA_LIBRARIES := bouncycastle conscrypt core core-junit ext okhttp
 
-LOCAL_MODULE := framework
-LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+LOCAL_MODULE := framework-base
 
-# List of classes and interfaces which should be loaded by the Zygote.
-LOCAL_JAVA_RESOURCE_FILES += $(LOCAL_PATH)/preloaded-classes
+LOCAL_JAR_EXCLUDE_FILES := none
 
-#LOCAL_JARJAR_RULES := $(LOCAL_PATH)/jarjar-rules.txt
-
-LOCAL_DX_FLAGS := --core-library
-
-include $(BUILD_JAVA_LIBRARY)
+include $(BUILD_STATIC_JAVA_LIBRARY)
 
 # Make sure that R.java and Manifest.java are built before we build
 # the source for this library.
@@ -267,14 +291,53 @@
 	$(call intermediates-dir-for,APPS,framework-res,,COMMON)/src/R.stamp
 $(full_classes_compiled_jar): $(framework_res_R_stamp)
 
-# Make sure that framework-res is installed when framework is.
-$(LOCAL_INSTALLED_MODULE): | $(dir $(LOCAL_INSTALLED_MODULE))framework-res.apk
-
-framework_built := $(call java-lib-deps,framework)
-
-# AIDL files to be preprocessed and included in the SDK,
-# relative to the root of the build tree.
+# Build part 1 of the framework library.
 # ============================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := framework
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_STATIC_JAVA_LIBRARIES := framework-base
+LOCAL_DX_FLAGS := --core-library
+
+# Packages to include, use \* wildcard to include descendants.
+LOCAL_JAR_PACKAGES := android\*
+
+# List of classes and interfaces which should be loaded by the Zygote.
+LOCAL_JAVA_RESOURCE_FILES += $(LOCAL_PATH)/preloaded-classes
+
+include $(BUILD_JAVA_LIBRARY)
+framework_module := $(LOCAL_INSTALLED_MODULE)
+
+# Build part 2 of the framework library.
+# ============================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := framework2
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_STATIC_JAVA_LIBRARIES := framework-base
+LOCAL_DX_FLAGS := --core-library
+
+# Packages to include, use \* wildcard to include descendants.
+LOCAL_JAR_PACKAGES := com\* javax\*
+
+include $(BUILD_JAVA_LIBRARY)
+framework2_module := $(LOCAL_INSTALLED_MODULE)
+
+# Make sure that all framework modules are installed when framework is.
+# ============================================================
+$(framework_module): | $(dir $(framework_module))framework-res.apk
+$(framework_module): | $(dir $(framework_module))framework2.jar
+
+framework_built := $(call java-lib-deps,framework framework2)
+
+# Copy AIDL files to be preprocessed and included in the SDK,
+# specified relative to the root of the build tree.
+# ============================================================
+include $(CLEAR_VARS)
+
 aidl_files := \
 	frameworks/base/core/java/android/accounts/IAccountManager.aidl \
 	frameworks/base/core/java/android/accounts/IAccountManagerResponse.aidl \
@@ -290,9 +353,11 @@
 	frameworks/base/core/java/android/content/Intent.aidl \
 	frameworks/base/core/java/android/content/IntentSender.aidl \
 	frameworks/base/core/java/android/content/PeriodicSync.aidl \
+	frameworks/base/core/java/android/content/SyncRequest.aidl \
 	frameworks/base/core/java/android/content/SyncStats.aidl \
 	frameworks/base/core/java/android/content/res/Configuration.aidl \
 	frameworks/base/core/java/android/database/CursorWindow.aidl \
+	frameworks/base/core/java/android/hardware/location/GeofenceHardwareRequestParcelable.aidl \
 	frameworks/base/core/java/android/net/Uri.aidl \
 	frameworks/base/core/java/android/nfc/NdefMessage.aidl \
 	frameworks/base/core/java/android/nfc/NdefRecord.aidl \
@@ -323,11 +388,14 @@
 	frameworks/base/location/java/android/location/Geofence.aidl \
 	frameworks/base/location/java/android/location/Location.aidl \
 	frameworks/base/location/java/android/location/LocationRequest.aidl \
+	frameworks/base/location/java/android/location/FusedBatchOptions.aidl \
 	frameworks/base/location/java/com/android/internal/location/ProviderProperties.aidl \
 	frameworks/base/location/java/com/android/internal/location/ProviderRequest.aidl \
 	frameworks/base/telephony/java/android/telephony/ServiceState.aidl \
 	frameworks/base/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl \
 	frameworks/base/telephony/java/com/android/internal/telephony/ITelephony.aidl \
+	frameworks/base/wifi/java/android/net/wifi/BatchedScanSettings.aidl \
+	frameworks/base/wifi/java/android/net/wifi/BatchedScanResult.aidl \
 
 gen := $(TARGET_OUT_COMMON_INTERMEDIATES)/framework.aidl
 $(gen): PRIVATE_SRC_FILES := $(aidl_files)
@@ -420,6 +488,7 @@
 	okhttp \
 	ext \
 	framework \
+	framework2 \
 	mms-common \
 	telephony-common \
 	voip-common
@@ -456,7 +525,7 @@
 		-overview $(LOCAL_PATH)/core/java/overview.html
 
 framework_docs_LOCAL_API_CHECK_ADDITIONAL_JAVA_DIR:= \
-	$(call intermediates-dir-for,JAVA_LIBRARIES,framework,,COMMON)
+	$(call intermediates-dir-for,JAVA_LIBRARIES,framework-base,,COMMON)
 
 framework_docs_LOCAL_ADDITIONAL_JAVA_DIR:= \
 	$(framework_docs_LOCAL_API_CHECK_ADDITIONAL_JAVA_DIR) \
@@ -750,7 +819,7 @@
 
 LOCAL_SRC_FILES:=$(framework_docs_LOCAL_SRC_FILES)
 LOCAL_INTERMEDIATE_SOURCES:=$(framework_docs_LOCAL_INTERMEDIATE_SOURCES)
-LOCAL_JAVA_LIBRARIES:=$(framework_docs_LOCAL_JAVA_LIBRARIES) framework
+LOCAL_JAVA_LIBRARIES:=$(framework_docs_LOCAL_JAVA_LIBRARIES)
 LOCAL_MODULE_CLASS:=$(framework_docs_LOCAL_MODULE_CLASS)
 LOCAL_DROIDDOC_SOURCE_PATH:=$(framework_docs_LOCAL_DROIDDOC_SOURCE_PATH)
 LOCAL_DROIDDOC_HTML_DIR:=$(framework_docs_LOCAL_DROIDDOC_HTML_DIR)
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 0c3ccec..797d088 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -80,12 +80,12 @@
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/content/IClipboard.P)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/telephony/java/com/android/internal/telephony/ITelephonyRegistry.P)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates)
-$(call add-clean-step, rm -rf out/target/common/docs/api-stubs*)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/docs/api-stubs*)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/com/trustedlogic)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/src/com/trustedlogic)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/com/trustedlogic)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/src/com/trustedlogic)
-$(call add-clean-step, rm -rf $(OUT_DIR)/target/target/common/obj/APPS/Music2_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/Music2_intermediates)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/nfc/INdefTag.java)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libstagefright_aacdec_intermediates)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libstagefright_mp3dec_intermediates)
@@ -161,6 +161,25 @@
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/com/android/internal/view/IInputMethodCallback.*)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/framework-res_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates)
+$(call add-clean-step, rm -rf $(HOST_OUT)/obj/STATIC_LIBRARIES/libandroidfw_intermediates/import_includes)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/print/IPrinterDiscoveryObserver.*)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/print/)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/printservice/)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/packages/services/Proxy/)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/print/IPrinterDiscoverySessionObserver.*)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/print/IPrinterDiscoverySessionClient.*)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/os/IBattery*)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/usr/idc/frameworks)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/usr/keylayout/frameworks)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/usr/keychars/frameworks)
+$(call add-clean-step, rm -f $(PRODUCT_OUT)/system/media/video/*)
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/api/current.txt b/api/current.txt
index 6f0bbce..ab48c8d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -22,7 +22,10 @@
     field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET";
     field public static final java.lang.String BIND_DEVICE_ADMIN = "android.permission.BIND_DEVICE_ADMIN";
     field public static final java.lang.String BIND_INPUT_METHOD = "android.permission.BIND_INPUT_METHOD";
+    field public static final java.lang.String BIND_NFC_SERVICE = "android.permission.BIND_NFC_SERVICE";
     field public static final java.lang.String BIND_NOTIFICATION_LISTENER_SERVICE = "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE";
+    field public static final java.lang.String BIND_PRINT_SERVICE = "android.permission.BIND_PRINT_SERVICE";
+    field public static final java.lang.String BIND_PRINT_SPOOLER_SERVICE = "android.permission.BIND_PRINT_SPOOLER_SERVICE";
     field public static final java.lang.String BIND_REMOTEVIEWS = "android.permission.BIND_REMOTEVIEWS";
     field public static final java.lang.String BIND_TEXT_SERVICE = "android.permission.BIND_TEXT_SERVICE";
     field public static final java.lang.String BIND_VPN_SERVICE = "android.permission.BIND_VPN_SERVICE";
@@ -37,6 +40,9 @@
     field public static final java.lang.String CALL_PHONE = "android.permission.CALL_PHONE";
     field public static final java.lang.String CALL_PRIVILEGED = "android.permission.CALL_PRIVILEGED";
     field public static final java.lang.String CAMERA = "android.permission.CAMERA";
+    field public static final java.lang.String CAPTURE_AUDIO_OUTPUT = "android.permission.CAPTURE_AUDIO_OUTPUT";
+    field public static final java.lang.String CAPTURE_SECURE_VIDEO_OUTPUT = "android.permission.CAPTURE_SECURE_VIDEO_OUTPUT";
+    field public static final java.lang.String CAPTURE_VIDEO_OUTPUT = "android.permission.CAPTURE_VIDEO_OUTPUT";
     field public static final java.lang.String CHANGE_COMPONENT_ENABLED_STATE = "android.permission.CHANGE_COMPONENT_ENABLED_STATE";
     field public static final java.lang.String CHANGE_CONFIGURATION = "android.permission.CHANGE_CONFIGURATION";
     field public static final java.lang.String CHANGE_NETWORK_STATE = "android.permission.CHANGE_NETWORK_STATE";
@@ -70,6 +76,8 @@
     field public static final java.lang.String LOCATION_HARDWARE = "android.permission.LOCATION_HARDWARE";
     field public static final java.lang.String MANAGE_ACCOUNTS = "android.permission.MANAGE_ACCOUNTS";
     field public static final java.lang.String MANAGE_APP_TOKENS = "android.permission.MANAGE_APP_TOKENS";
+    field public static final java.lang.String MANAGE_DEVICE_ADMINS = "android.permission.MANAGE_DEVICE_ADMINS";
+    field public static final java.lang.String MANAGE_DOCUMENTS = "android.permission.MANAGE_DOCUMENTS";
     field public static final java.lang.String MASTER_CLEAR = "android.permission.MASTER_CLEAR";
     field public static final java.lang.String MODIFY_AUDIO_SETTINGS = "android.permission.MODIFY_AUDIO_SETTINGS";
     field public static final java.lang.String MODIFY_PHONE_STATE = "android.permission.MODIFY_PHONE_STATE";
@@ -121,6 +129,7 @@
     field public static final java.lang.String SUBSCRIBED_FEEDS_READ = "android.permission.SUBSCRIBED_FEEDS_READ";
     field public static final java.lang.String SUBSCRIBED_FEEDS_WRITE = "android.permission.SUBSCRIBED_FEEDS_WRITE";
     field public static final java.lang.String SYSTEM_ALERT_WINDOW = "android.permission.SYSTEM_ALERT_WINDOW";
+    field public static final java.lang.String TRANSMIT_IR = "android.permission.TRANSMIT_IR";
     field public static final java.lang.String UPDATE_DEVICE_STATS = "android.permission.UPDATE_DEVICE_STATS";
     field public static final java.lang.String USE_CREDENTIALS = "android.permission.USE_CREDENTIALS";
     field public static final java.lang.String USE_SIP = "android.permission.USE_SIP";
@@ -219,6 +228,7 @@
     field public static final int accessibilityEventTypes = 16843648; // 0x1010380
     field public static final int accessibilityFeedbackType = 16843650; // 0x1010382
     field public static final int accessibilityFlags = 16843652; // 0x1010384
+    field public static final int accessibilityLiveRegion = 16843758; // 0x10103ee
     field public static final int accountPreferences = 16843423; // 0x101029f
     field public static final int accountType = 16843407; // 0x101028f
     field public static final int action = 16842797; // 0x101002d
@@ -253,6 +263,7 @@
     field public static final int activityCloseExitAnimation = 16842939; // 0x10100bb
     field public static final int activityOpenEnterAnimation = 16842936; // 0x10100b8
     field public static final int activityOpenExitAnimation = 16842937; // 0x10100b9
+    field public static final int addPrintersActivity = 16843750; // 0x10103e6
     field public static final int addStatesFromChildren = 16842992; // 0x10100f0
     field public static final int adjustViewBounds = 16843038; // 0x101011e
     field public static final int alertDialogIcon = 16843605; // 0x1010355
@@ -280,12 +291,14 @@
     field public static final deprecated int animationResolution = 16843546; // 0x101031a
     field public static final int antialias = 16843034; // 0x101011a
     field public static final int anyDensity = 16843372; // 0x101026c
+    field public static final int apduServiceBanner = 16843757; // 0x10103ed
     field public static final int apiKey = 16843281; // 0x1010211
     field public static final int author = 16843444; // 0x10102b4
     field public static final int authorities = 16842776; // 0x1010018
     field public static final int autoAdvanceViewId = 16843535; // 0x101030f
     field public static final int autoCompleteTextViewStyle = 16842859; // 0x101006b
     field public static final int autoLink = 16842928; // 0x10100b0
+    field public static final int autoMirrored = 16843754; // 0x10103ea
     field public static final int autoStart = 16843445; // 0x10102b5
     field public static final deprecated int autoText = 16843114; // 0x101016a
     field public static final int autoUrlDetect = 16843404; // 0x101028c
@@ -326,6 +339,7 @@
     field public static final int canRetrieveWindowContent = 16843653; // 0x1010385
     field public static final int candidatesTextStyleSpans = 16843312; // 0x1010230
     field public static final deprecated int capitalize = 16843113; // 0x1010169
+    field public static final int category = 16843752; // 0x10103e8
     field public static final int centerBright = 16842956; // 0x10100cc
     field public static final int centerColor = 16843275; // 0x101020b
     field public static final int centerDark = 16842952; // 0x10100c8
@@ -474,6 +488,7 @@
     field public static final int fadeScrollbars = 16843434; // 0x10102aa
     field public static final int fadingEdge = 16842975; // 0x10100df
     field public static final int fadingEdgeLength = 16842976; // 0x10100e0
+    field public static final int fadingMode = 16843745; // 0x10103e1
     field public static final int fastScrollAlwaysVisible = 16843573; // 0x1010335
     field public static final int fastScrollEnabled = 16843302; // 0x1010226
     field public static final int fastScrollOverlayPosition = 16843578; // 0x101033a
@@ -513,6 +528,7 @@
     field public static final int freezesText = 16843116; // 0x101016c
     field public static final int fromAlpha = 16843210; // 0x10101ca
     field public static final int fromDegrees = 16843187; // 0x10101b3
+    field public static final int fromScene = 16843741; // 0x10103dd
     field public static final int fromXDelta = 16843206; // 0x10101c6
     field public static final int fromXScale = 16843202; // 0x10101c2
     field public static final int fromYDelta = 16843208; // 0x10101c8
@@ -598,6 +614,7 @@
     field public static final int installLocation = 16843447; // 0x10102b7
     field public static final int interpolator = 16843073; // 0x1010141
     field public static final int isAlwaysSyncable = 16843571; // 0x1010333
+    field public static final int isAsciiCapable = 16843753; // 0x10103e9
     field public static final int isAuxiliary = 16843647; // 0x101037f
     field public static final int isDefault = 16843297; // 0x1010221
     field public static final int isIndicator = 16843079; // 0x1010147
@@ -627,6 +644,7 @@
     field public static final int keyboardLayout = 16843691; // 0x10103ab
     field public static final int keyboardMode = 16843341; // 0x101024d
     field public static final int keycode = 16842949; // 0x10100c5
+    field public static final int keyset = 16843739; // 0x10103db
     field public static final int killAfterRestore = 16843420; // 0x101029c
     field public static final int label = 16842753; // 0x1010001
     field public static final int labelFor = 16843718; // 0x10103c6
@@ -853,6 +871,7 @@
     field public static final int reqKeyboardType = 16843304; // 0x1010228
     field public static final int reqNavigation = 16843306; // 0x101022a
     field public static final int reqTouchScreen = 16843303; // 0x1010227
+    field public static final int requireDeviceUnlock = 16843756; // 0x10103ec
     field public static final int required = 16843406; // 0x101028e
     field public static final int requiredAccountType = 16843734; // 0x10103d6
     field public static final int requiredForAllUsers = 16843728; // 0x10103d0
@@ -951,9 +970,13 @@
     field public static final int spinnersShown = 16843595; // 0x101034b
     field public static final int splitMotionEvents = 16843503; // 0x10102ef
     field public static final int src = 16843033; // 0x1010119
+    field public static final int ssp = 16843747; // 0x10103e3
+    field public static final int sspPattern = 16843749; // 0x10103e5
+    field public static final int sspPrefix = 16843748; // 0x10103e4
     field public static final int stackFromBottom = 16843005; // 0x10100fd
     field public static final int starStyle = 16842882; // 0x1010082
     field public static final int startColor = 16843165; // 0x101019d
+    field public static final int startDelay = 16843746; // 0x10103e2
     field public static final int startOffset = 16843198; // 0x10101be
     field public static final deprecated int startYear = 16843132; // 0x101017c
     field public static final int stateNotNeeded = 16842774; // 0x1010016
@@ -997,6 +1020,7 @@
     field public static final int summaryOff = 16843248; // 0x10101f0
     field public static final int summaryOn = 16843247; // 0x10101ef
     field public static final int supportsRtl = 16843695; // 0x10103af
+    field public static final int supportsSwitchingToNextInputMethod = 16843755; // 0x10103eb
     field public static final int supportsUploading = 16843419; // 0x101029b
     field public static final int switchMinWidth = 16843632; // 0x1010370
     field public static final int switchPadding = 16843633; // 0x1010371
@@ -1013,6 +1037,7 @@
     field public static final int targetActivity = 16843266; // 0x1010202
     field public static final int targetClass = 16842799; // 0x101002f
     field public static final int targetDescriptions = 16843680; // 0x10103a0
+    field public static final int targetId = 16843740; // 0x10103dc
     field public static final int targetPackage = 16842785; // 0x1010021
     field public static final int targetSdkVersion = 16843376; // 0x1010270
     field public static final int taskAffinity = 16842770; // 0x1010012
@@ -1101,6 +1126,7 @@
     field public static final int titleTextStyle = 16843512; // 0x10102f8
     field public static final int toAlpha = 16843211; // 0x10101cb
     field public static final int toDegrees = 16843188; // 0x10101b4
+    field public static final int toScene = 16843742; // 0x10103de
     field public static final int toXDelta = 16843207; // 0x10101c7
     field public static final int toXScale = 16843203; // 0x10101c3
     field public static final int toYDelta = 16843209; // 0x10101c9
@@ -1115,6 +1141,8 @@
     field public static final int transcriptMode = 16843008; // 0x1010100
     field public static final int transformPivotX = 16843552; // 0x1010320
     field public static final int transformPivotY = 16843553; // 0x1010321
+    field public static final int transition = 16843743; // 0x10103df
+    field public static final int transitionOrdering = 16843744; // 0x10103e0
     field public static final int translationX = 16843554; // 0x1010322
     field public static final int translationY = 16843555; // 0x1010323
     field public static final int type = 16843169; // 0x10101a1
@@ -1133,6 +1161,7 @@
     field public static final int valueTo = 16843487; // 0x10102df
     field public static final int valueType = 16843488; // 0x10102e0
     field public static final int variablePadding = 16843157; // 0x1010195
+    field public static final int vendor = 16843751; // 0x10103e7
     field public static final int versionCode = 16843291; // 0x101021b
     field public static final int versionName = 16843292; // 0x101021c
     field public static final int verticalCorrection = 16843322; // 0x101023a
@@ -2316,6 +2345,7 @@
   public abstract class Animator implements java.lang.Cloneable {
     ctor public Animator();
     method public void addListener(android.animation.Animator.AnimatorListener);
+    method public void addPauseListener(android.animation.Animator.AnimatorPauseListener);
     method public void cancel();
     method public android.animation.Animator clone();
     method public void end();
@@ -2323,10 +2353,14 @@
     method public android.animation.TimeInterpolator getInterpolator();
     method public java.util.ArrayList<android.animation.Animator.AnimatorListener> getListeners();
     method public abstract long getStartDelay();
+    method public boolean isPaused();
     method public abstract boolean isRunning();
     method public boolean isStarted();
+    method public void pause();
     method public void removeAllListeners();
     method public void removeListener(android.animation.Animator.AnimatorListener);
+    method public void removePauseListener(android.animation.Animator.AnimatorPauseListener);
+    method public void resume();
     method public abstract android.animation.Animator setDuration(long);
     method public abstract void setInterpolator(android.animation.TimeInterpolator);
     method public abstract void setStartDelay(long);
@@ -2343,16 +2377,23 @@
     method public abstract void onAnimationStart(android.animation.Animator);
   }
 
+  public static abstract interface Animator.AnimatorPauseListener {
+    method public abstract void onAnimationPause(android.animation.Animator);
+    method public abstract void onAnimationResume(android.animation.Animator);
+  }
+
   public class AnimatorInflater {
     ctor public AnimatorInflater();
     method public static android.animation.Animator loadAnimator(android.content.Context, int) throws android.content.res.Resources.NotFoundException;
   }
 
-  public abstract class AnimatorListenerAdapter implements android.animation.Animator.AnimatorListener {
+  public abstract class AnimatorListenerAdapter implements android.animation.Animator.AnimatorListener android.animation.Animator.AnimatorPauseListener {
     ctor public AnimatorListenerAdapter();
     method public void onAnimationCancel(android.animation.Animator);
     method public void onAnimationEnd(android.animation.Animator);
+    method public void onAnimationPause(android.animation.Animator);
     method public void onAnimationRepeat(android.animation.Animator);
+    method public void onAnimationResume(android.animation.Animator);
     method public void onAnimationStart(android.animation.Animator);
   }
 
@@ -2808,6 +2849,7 @@
     method public void recreate();
     method public void registerForContextMenu(android.view.View);
     method public final deprecated void removeDialog(int);
+    method public void reportFullyDrawn();
     method public final boolean requestWindowFeature(int);
     method public final void runOnUiThread(java.lang.Runnable);
     method public void setContentView(int);
@@ -2877,6 +2919,8 @@
   }
 
   public class ActivityManager {
+    method public boolean clearApplicationUserData();
+    method public void dumpPackageState(java.io.FileDescriptor, java.lang.String);
     method public android.content.pm.ConfigurationInfo getDeviceConfigurationInfo();
     method public int getLargeMemoryClass();
     method public int getLauncherLargeIconDensity();
@@ -2891,6 +2935,7 @@
     method public android.app.PendingIntent getRunningServiceControlPanel(android.content.ComponentName) throws java.lang.SecurityException;
     method public java.util.List<android.app.ActivityManager.RunningServiceInfo> getRunningServices(int) throws java.lang.SecurityException;
     method public java.util.List<android.app.ActivityManager.RunningTaskInfo> getRunningTasks(int) throws java.lang.SecurityException;
+    method public boolean isLowRamDevice();
     method public static boolean isRunningInTestHarness();
     method public static boolean isUserAMonkey();
     method public void killBackgroundProcesses(java.lang.String);
@@ -3028,17 +3073,19 @@
   public class AlarmManager {
     method public void cancel(android.app.PendingIntent);
     method public void set(int, long, android.app.PendingIntent);
-    method public void setInexactRepeating(int, long, long, android.app.PendingIntent);
+    method public void setExact(int, long, android.app.PendingIntent);
+    method public deprecated void setInexactRepeating(int, long, long, android.app.PendingIntent);
     method public void setRepeating(int, long, long, android.app.PendingIntent);
     method public void setTime(long);
     method public void setTimeZone(java.lang.String);
+    method public void setWindow(int, long, long, android.app.PendingIntent);
     field public static final int ELAPSED_REALTIME = 3; // 0x3
     field public static final int ELAPSED_REALTIME_WAKEUP = 2; // 0x2
-    field public static final long INTERVAL_DAY = 86400000L; // 0x5265c00L
-    field public static final long INTERVAL_FIFTEEN_MINUTES = 900000L; // 0xdbba0L
-    field public static final long INTERVAL_HALF_DAY = 43200000L; // 0x2932e00L
-    field public static final long INTERVAL_HALF_HOUR = 1800000L; // 0x1b7740L
-    field public static final long INTERVAL_HOUR = 3600000L; // 0x36ee80L
+    field public static final deprecated long INTERVAL_DAY = 86400000L; // 0x5265c00L
+    field public static final deprecated long INTERVAL_FIFTEEN_MINUTES = 900000L; // 0xdbba0L
+    field public static final deprecated long INTERVAL_HALF_DAY = 43200000L; // 0x2932e00L
+    field public static final deprecated long INTERVAL_HALF_HOUR = 1800000L; // 0x1b7740L
+    field public static final deprecated long INTERVAL_HOUR = 3600000L; // 0x36ee80L
     field public static final int RTC = 1; // 0x1
     field public static final int RTC_WAKEUP = 0; // 0x0
   }
@@ -3116,6 +3163,34 @@
     ctor public AliasActivity();
   }
 
+  public class AppOpsManager {
+    method public int checkOp(int, int, java.lang.String);
+    method public int checkOpNoThrow(int, int, java.lang.String);
+    method public void checkPackage(int, java.lang.String);
+    method public void finishOp(int, int, java.lang.String);
+    method public void finishOp(int);
+    method public int noteOp(int, int, java.lang.String);
+    method public int noteOpNoThrow(int, int, java.lang.String);
+    method public static java.lang.String opToName(int);
+    method public int startOp(int, int, java.lang.String);
+    method public int startOpNoThrow(int, int, java.lang.String);
+    method public void startWatchingMode(int, java.lang.String, android.app.AppOpsManager.Callback);
+    method public void stopWatchingMode(android.app.AppOpsManager.Callback);
+    field public static final int MODE_ALLOWED = 0; // 0x0
+    field public static final int MODE_ERRORED = 2; // 0x2
+    field public static final int MODE_IGNORED = 1; // 0x1
+    field public static final int OP_COARSE_LOCATION = 0; // 0x0
+    field public static final int OP_FINE_LOCATION = 1; // 0x1
+    field public static final int OP_GPS = 2; // 0x2
+    field public static final int OP_MONITOR_HIGH_POWER_LOCATION = 42; // 0x2a
+    field public static final int OP_MONITOR_LOCATION = 41; // 0x29
+    field public static final int OP_NONE = -1; // 0xffffffff
+  }
+
+  public static abstract interface AppOpsManager.Callback {
+    method public abstract void opChanged(int, java.lang.String);
+  }
+
   public class Application extends android.content.ContextWrapper implements android.content.ComponentCallbacks2 {
     ctor public Application();
     method public void onConfigurationChanged(android.content.res.Configuration);
@@ -3839,6 +3914,23 @@
     field public static final int DEFAULT_LIGHTS = 4; // 0x4
     field public static final int DEFAULT_SOUND = 1; // 0x1
     field public static final int DEFAULT_VIBRATE = 2; // 0x2
+    field public static final java.lang.String EXTRA_INFO_TEXT = "android.infoText";
+    field public static final java.lang.String EXTRA_LARGE_ICON = "android.largeIcon";
+    field public static final java.lang.String EXTRA_LARGE_ICON_BIG = "android.largeIcon.big";
+    field public static final java.lang.String EXTRA_PEOPLE = "android.people";
+    field public static final java.lang.String EXTRA_PICTURE = "android.picture";
+    field public static final java.lang.String EXTRA_PROGRESS = "android.progress";
+    field public static final java.lang.String EXTRA_PROGRESS_INDETERMINATE = "android.progressIndeterminate";
+    field public static final java.lang.String EXTRA_PROGRESS_MAX = "android.progressMax";
+    field public static final java.lang.String EXTRA_SHOW_CHRONOMETER = "android.showChronometer";
+    field public static final java.lang.String EXTRA_SHOW_WHEN = "android.showWhen";
+    field public static final java.lang.String EXTRA_SMALL_ICON = "android.icon";
+    field public static final java.lang.String EXTRA_SUB_TEXT = "android.subText";
+    field public static final java.lang.String EXTRA_SUMMARY_TEXT = "android.summaryText";
+    field public static final java.lang.String EXTRA_TEXT = "android.text";
+    field public static final java.lang.String EXTRA_TEXT_LINES = "android.textLines";
+    field public static final java.lang.String EXTRA_TITLE = "android.title";
+    field public static final java.lang.String EXTRA_TITLE_BIG = "android.title.big";
     field public static final int FLAG_AUTO_CANCEL = 16; // 0x10
     field public static final int FLAG_FOREGROUND_SERVICE = 64; // 0x40
     field public static final deprecated int FLAG_HIGH_PRIORITY = 128; // 0x80
@@ -3853,12 +3945,14 @@
     field public static final int PRIORITY_MAX = 2; // 0x2
     field public static final int PRIORITY_MIN = -2; // 0xfffffffe
     field public static final int STREAM_DEFAULT = -1; // 0xffffffff
+    field public android.app.Notification.Action[] actions;
     field public int audioStreamType;
     field public android.widget.RemoteViews bigContentView;
     field public android.app.PendingIntent contentIntent;
     field public android.widget.RemoteViews contentView;
     field public int defaults;
     field public android.app.PendingIntent deleteIntent;
+    field public android.os.Bundle extras;
     field public int flags;
     field public android.app.PendingIntent fullScreenIntent;
     field public int icon;
@@ -3876,6 +3970,18 @@
     field public long when;
   }
 
+  public static class Notification.Action implements android.os.Parcelable {
+    ctor public Notification.Action();
+    ctor public Notification.Action(int, java.lang.CharSequence, android.app.PendingIntent);
+    method public android.app.Notification.Action clone();
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public android.app.PendingIntent actionIntent;
+    field public int icon;
+    field public java.lang.CharSequence title;
+  }
+
   public static class Notification.BigPictureStyle extends android.app.Notification.Style {
     ctor public Notification.BigPictureStyle();
     ctor public Notification.BigPictureStyle(android.app.Notification.Builder);
@@ -3908,6 +4014,7 @@
     method public android.app.Notification.Builder setContentTitle(java.lang.CharSequence);
     method public android.app.Notification.Builder setDefaults(int);
     method public android.app.Notification.Builder setDeleteIntent(android.app.PendingIntent);
+    method public android.app.Notification.Builder setExtras(android.os.Bundle);
     method public android.app.Notification.Builder setFullScreenIntent(android.app.PendingIntent, boolean);
     method public android.app.Notification.Builder setLargeIcon(android.graphics.Bitmap);
     method public android.app.Notification.Builder setLights(int, int, int);
@@ -4257,6 +4364,7 @@
     method public void clear() throws java.io.IOException;
     method public void clearWallpaperOffsets(android.os.IBinder);
     method public void forgetLoadedWallpaper();
+    method public android.content.Intent getCropAndSetWallpaperIntent(android.net.Uri);
     method public int getDesiredMinimumHeight();
     method public int getDesiredMinimumWidth();
     method public android.graphics.drawable.Drawable getDrawable();
@@ -4274,6 +4382,7 @@
     method public void setWallpaperOffsets(android.os.IBinder, float, float);
     method public void suggestDesiredDimensions(int, int);
     field public static final java.lang.String ACTION_CHANGE_LIVE_WALLPAPER = "android.service.wallpaper.CHANGE_LIVE_WALLPAPER";
+    field public static final java.lang.String ACTION_CROP_AND_SET_WALLPAPER = "android.service.wallpaper.CROP_AND_SET_WALLPAPER";
     field public static final java.lang.String ACTION_LIVE_WALLPAPER_CHOOSER = "android.service.wallpaper.LIVE_WALLPAPER_CHOOSER";
     field public static final java.lang.String COMMAND_DROP = "android.home.drop";
     field public static final java.lang.String COMMAND_SECONDARY_TAP = "android.wallpaper.secondaryTap";
@@ -4675,68 +4784,165 @@
   }
 
   public class BluetoothAssignedNumbers {
+    field public static final int AAMP_OF_AMERICA = 190; // 0xbe
     field public static final int ACCEL_SEMICONDUCTOR = 74; // 0x4a
+    field public static final int ACE_SENSOR = 188; // 0xbc
+    field public static final int ADIDAS = 195; // 0xc3
+    field public static final int ADVANCED_PANMOBIL_SYSTEMS = 145; // 0x91
+    field public static final int AIROHA_TECHNOLOGY = 148; // 0x94
     field public static final int ALCATEL = 36; // 0x24
+    field public static final int ALPWISE = 154; // 0x9a
+    field public static final int AMICCOM_ELECTRONICS = 192; // 0xc0
+    field public static final int APLIX = 189; // 0xbd
     field public static final int APPLE = 76; // 0x4c
     field public static final int APT_LICENSING = 79; // 0x4f
+    field public static final int ARCHOS = 207; // 0xcf
+    field public static final int ARP_DEVICES = 168; // 0xa8
     field public static final int ATHEROS_COMMUNICATIONS = 69; // 0x45
     field public static final int ATMEL = 19; // 0x13
+    field public static final int AUSTCO_COMMUNICATION_SYSTEMS = 213; // 0xd5
+    field public static final int AUTONET_MOBILE = 127; // 0x7f
     field public static final int AVAGO = 78; // 0x4e
     field public static final int AVM_BERLIN = 31; // 0x1f
+    field public static final int A_AND_D_ENGINEERING = 105; // 0x69
+    field public static final int A_AND_R_CAMBRIDGE = 124; // 0x7c
     field public static final int BANDSPEED = 32; // 0x20
+    field public static final int BAND_XI_INTERNATIONAL = 100; // 0x64
+    field public static final int BDE_TECHNOLOGY = 180; // 0xb4
+    field public static final int BEATS_ELECTRONICS = 204; // 0xcc
+    field public static final int BEAUTIFUL_ENTERPRISE = 108; // 0x6c
+    field public static final int BEKEY = 178; // 0xb2
     field public static final int BELKIN_INTERNATIONAL = 92; // 0x5c
+    field public static final int BINAURIC = 203; // 0xcb
+    field public static final int BIOSENTRONICS = 219; // 0xdb
     field public static final int BLUEGIGA = 71; // 0x47
+    field public static final int BLUERADIOS = 133; // 0x85
     field public static final int BLUETOOTH_SIG = 63; // 0x3f
+    field public static final int BLUETREK_TECHNOLOGIES = 151; // 0x97
+    field public static final int BOSE = 158; // 0x9e
+    field public static final int BRIARTEK = 109; // 0x6d
     field public static final int BROADCOM = 15; // 0xf
+    field public static final int CAEN_RFID = 170; // 0xaa
     field public static final int CAMBRIDGE_SILICON_RADIO = 10; // 0xa
     field public static final int CATC = 52; // 0x34
+    field public static final int CINETIX = 175; // 0xaf
+    field public static final int CLARINOX_TECHNOLOGIES = 179; // 0xb3
+    field public static final int COLORFY = 156; // 0x9c
     field public static final int COMMIL = 51; // 0x33
     field public static final int CONEXANT_SYSTEMS = 28; // 0x1c
+    field public static final int CONNECTBLUE = 113; // 0x71
     field public static final int CONTINENTAL_AUTOMOTIVE = 75; // 0x4b
     field public static final int CONWISE_TECHNOLOGY = 66; // 0x42
+    field public static final int CREATIVE_TECHNOLOGY = 118; // 0x76
     field public static final int C_TECHNOLOGIES = 38; // 0x26
+    field public static final int DANLERS = 225; // 0xe1
+    field public static final int DELORME_PUBLISHING_COMPANY = 128; // 0x80
+    field public static final int DEXCOM = 208; // 0xd0
+    field public static final int DIALOG_SEMICONDUCTOR = 210; // 0xd2
     field public static final int DIGIANSWER = 12; // 0xc
     field public static final int ECLIPSE = 53; // 0x35
+    field public static final int ECOTEST = 136; // 0x88
+    field public static final int ELGATO_SYSTEMS = 206; // 0xce
     field public static final int EM_MICROELECTRONIC_MARIN = 90; // 0x5a
+    field public static final int EQUINOX_AG = 134; // 0x86
     field public static final int ERICSSON_TECHNOLOGY = 0; // 0x0
+    field public static final int EVLUMA = 201; // 0xc9
     field public static final int FREE2MOVE = 83; // 0x53
+    field public static final int FUNAI_ELECTRIC = 144; // 0x90
+    field public static final int GARMIN_INTERNATIONAL = 135; // 0x87
     field public static final int GCT_SEMICONDUCTOR = 45; // 0x2d
+    field public static final int GELO = 200; // 0xc8
+    field public static final int GENEQ = 194; // 0xc2
+    field public static final int GENERAL_MOTORS = 104; // 0x68
     field public static final int GENNUM = 59; // 0x3b
+    field public static final int GEOFORCE = 157; // 0x9d
+    field public static final int GIBSON_GUITARS = 98; // 0x62
+    field public static final int GN_NETCOM = 103; // 0x67
+    field public static final int GN_RESOUND = 137; // 0x89
+    field public static final int GOOGLE = 224; // 0xe0
+    field public static final int GREEN_THROTTLE_GAMES = 172; // 0xac
+    field public static final int GROUP_SENSE = 115; // 0x73
+    field public static final int HANLYNN_TECHNOLOGIES = 123; // 0x7b
     field public static final int HARMAN_INTERNATIONAL = 87; // 0x57
+    field public static final int HEWLETT_PACKARD = 101; // 0x65
     field public static final int HITACHI = 41; // 0x29
+    field public static final int HOSIDEN = 221; // 0xdd
     field public static final int IBM = 3; // 0x3
     field public static final int INFINEON_TECHNOLOGIES = 9; // 0x9
+    field public static final int INGENIEUR_SYSTEMGRUPPE_ZAHN = 171; // 0xab
     field public static final int INTEGRATED_SILICON_SOLUTION = 65; // 0x41
     field public static final int INTEGRATED_SYSTEM_SOLUTION = 57; // 0x39
     field public static final int INTEL = 2; // 0x2
     field public static final int INVENTEL = 30; // 0x1e
     field public static final int IPEXTREME = 61; // 0x3d
+    field public static final int I_TECH_DYNAMIC_GLOBAL_DISTRIBUTION = 153; // 0x99
+    field public static final int JAWBONE = 138; // 0x8a
+    field public static final int JIANGSU_TOPPOWER_AUTOMOTIVE_ELECTRONICS = 155; // 0x9b
+    field public static final int JOHNSON_CONTROLS = 185; // 0xb9
     field public static final int J_AND_M = 82; // 0x52
+    field public static final int KAWANTECH = 212; // 0xd4
     field public static final int KC_TECHNOLOGY = 22; // 0x16
+    field public static final int KENSINGTON_COMPUTER_PRODUCTS_GROUP = 160; // 0xa0
+    field public static final int LAIRD_TECHNOLOGIES = 119; // 0x77
+    field public static final int LESSWIRE = 121; // 0x79
+    field public static final int LG_ELECTRONICS = 196; // 0xc4
+    field public static final int LINAK = 164; // 0xa4
     field public static final int LUCENT = 7; // 0x7
+    field public static final int LUDUS_HELSINKI = 132; // 0x84
     field public static final int MACRONIX = 44; // 0x2c
+    field public static final int MAGNETI_MARELLI = 169; // 0xa9
     field public static final int MANSELLA = 33; // 0x21
     field public static final int MARVELL = 72; // 0x48
     field public static final int MATSUSHITA_ELECTRIC = 58; // 0x3a
+    field public static final int MC10 = 202; // 0xca
     field public static final int MEDIATEK = 70; // 0x46
+    field public static final int MESO_INTERNATIONAL = 182; // 0xb6
+    field public static final int META_WATCH = 163; // 0xa3
     field public static final int MEWTEL_TECHNOLOGY = 47; // 0x2f
+    field public static final int MICOMMAND = 99; // 0x63
+    field public static final int MICROCHIP_TECHNOLOGY = 205; // 0xcd
     field public static final int MICROSOFT = 6; // 0x6
+    field public static final int MINDTREE = 106; // 0x6a
+    field public static final int MISFIT_WEARABLES = 223; // 0xdf
     field public static final int MITEL_SEMICONDUCTOR = 16; // 0x10
     field public static final int MITSUBISHI_ELECTRIC = 20; // 0x14
     field public static final int MOBILIAN_CORPORATION = 55; // 0x37
+    field public static final int MONSTER = 112; // 0x70
     field public static final int MOTOROLA = 8; // 0x8
+    field public static final int MSTAR_SEMICONDUCTOR = 122; // 0x7a
+    field public static final int MUZIK = 222; // 0xde
     field public static final int NEC = 34; // 0x22
+    field public static final int NEC_LIGHTING = 149; // 0x95
     field public static final int NEWLOGIC = 23; // 0x17
+    field public static final int NIKE = 120; // 0x78
+    field public static final int NINE_SOLUTIONS = 102; // 0x66
     field public static final int NOKIA_MOBILE_PHONES = 1; // 0x1
     field public static final int NORDIC_SEMICONDUCTOR = 89; // 0x59
     field public static final int NORWOOD_SYSTEMS = 46; // 0x2e
+    field public static final int ODM_TECHNOLOGY = 150; // 0x96
+    field public static final int OMEGAWAVE = 174; // 0xae
+    field public static final int ONSET_COMPUTER = 197; // 0xc5
     field public static final int OPEN_INTERFACE = 39; // 0x27
+    field public static final int OTL_DYNAMICS = 165; // 0xa5
+    field public static final int PANDA_OCEAN = 166; // 0xa6
     field public static final int PARROT = 67; // 0x43
     field public static final int PARTHUS_TECHNOLOGIES = 14; // 0xe
+    field public static final int PASSIF_SEMICONDUCTOR = 176; // 0xb0
+    field public static final int PETER_SYSTEMTECHNIK = 173; // 0xad
     field public static final int PHILIPS_SEMICONDUCTORS = 37; // 0x25
     field public static final int PLANTRONICS = 85; // 0x55
+    field public static final int POLAR_ELECTRO = 107; // 0x6b
+    field public static final int POLAR_ELECTRO_EUROPE = 209; // 0xd1
+    field public static final int PROCTER_AND_GAMBLE = 220; // 0xdc
     field public static final int QUALCOMM = 29; // 0x1d
+    field public static final int QUALCOMM_CONNECTED_EXPERIENCES = 216; // 0xd8
+    field public static final int QUALCOMM_INNOVATION_CENTER = 184; // 0xb8
+    field public static final int QUALCOMM_LABS = 140; // 0x8c
+    field public static final int QUALCOMM_TECHNOLOGIES = 215; // 0xd7
+    field public static final int QUINTIC = 142; // 0x8e
+    field public static final int QUUPPA = 199; // 0xc7
     field public static final int RALINK_TECHNOLOGY = 91; // 0x5b
+    field public static final int RDA_MICROELECTRONICS = 97; // 0x61
     field public static final int REALTEK_SEMICONDUCTOR = 93; // 0x5d
     field public static final int RED_M = 50; // 0x32
     field public static final int RENESAS_TECHNOLOGY = 54; // 0x36
@@ -4745,33 +4951,66 @@
     field public static final int RIVIERAWAVES = 96; // 0x60
     field public static final int ROHDE_AND_SCHWARZ = 25; // 0x19
     field public static final int RTX_TELECOM = 21; // 0x15
+    field public static final int SAMSUNG_ELECTRONICS = 117; // 0x75
+    field public static final int SARIS_CYCLING_GROUP = 177; // 0xb1
+    field public static final int SEERS_TECHNOLOGY = 125; // 0x7d
     field public static final int SEIKO_EPSON = 64; // 0x40
+    field public static final int SELFLY = 198; // 0xc6
+    field public static final int SEMILINK = 226; // 0xe2
+    field public static final int SENNHEISER_COMMUNICATIONS = 130; // 0x82
+    field public static final int SHANGHAI_SUPER_SMART_ELECTRONICS = 114; // 0x72
+    field public static final int SHENZHEN_EXCELSECU_DATA_TECHNOLOGY = 193; // 0xc1
     field public static final int SIGNIA_TECHNOLOGIES = 27; // 0x1b
     field public static final int SILICON_WAVE = 11; // 0xb
     field public static final int SIRF_TECHNOLOGY = 80; // 0x50
     field public static final int SOCKET_MOBILE = 68; // 0x44
     field public static final int SONY_ERICSSON = 86; // 0x56
+    field public static final int SOUND_ID = 111; // 0x6f
+    field public static final int SPORTS_TRACKING_TECHNOLOGIES = 126; // 0x7e
+    field public static final int SR_MEDIZINELEKTRONIK = 161; // 0xa1
     field public static final int STACCATO_COMMUNICATIONS = 77; // 0x4d
+    field public static final int STALMART_TECHNOLOGY = 191; // 0xbf
+    field public static final int STARKEY_LABORATORIES = 186; // 0xba
+    field public static final int STOLLMAN_E_PLUS_V = 143; // 0x8f
     field public static final int STONESTREET_ONE = 94; // 0x5e
     field public static final int ST_MICROELECTRONICS = 48; // 0x30
+    field public static final int SUMMIT_DATA_COMMUNICATIONS = 110; // 0x6e
+    field public static final int SUUNTO = 159; // 0x9f
+    field public static final int SWIRL_NETWORKS = 181; // 0xb5
     field public static final int SYMBOL_TECHNOLOGIES = 42; // 0x2a
     field public static final int SYNOPSYS = 49; // 0x31
     field public static final int SYSTEMS_AND_CHIPS = 62; // 0x3e
+    field public static final int S_POWER_ELECTRONICS = 187; // 0xbb
+    field public static final int TAIXINGBANG_TECHNOLOGY = 211; // 0xd3
     field public static final int TENOVIS = 43; // 0x2b
     field public static final int TERAX = 56; // 0x38
     field public static final int TEXAS_INSTRUMENTS = 13; // 0xd
+    field public static final int THINKOPTICS = 146; // 0x92
     field public static final int THREECOM = 5; // 0x5
     field public static final int THREE_DIJOY = 84; // 0x54
     field public static final int THREE_DSP = 73; // 0x49
+    field public static final int TIMEKEEPING_SYSTEMS = 131; // 0x83
+    field public static final int TIMEX_GROUP_USA = 214; // 0xd6
+    field public static final int TOPCORN_POSITIONING_SYSTEMS = 139; // 0x8b
     field public static final int TOSHIBA = 4; // 0x4
     field public static final int TRANSILICA = 24; // 0x18
+    field public static final int TRELAB = 183; // 0xb7
     field public static final int TTPCOM = 26; // 0x1a
+    field public static final int TXTR = 218; // 0xda
     field public static final int TZERO_TECHNOLOGIES = 81; // 0x51
+    field public static final int UNIVERSAL_ELECTRONICS = 147; // 0x93
+    field public static final int VERTU = 162; // 0xa2
+    field public static final int VISTEON = 167; // 0xa7
     field public static final int VIZIO = 88; // 0x58
+    field public static final int VOYETRA_TURTLE_BEACH = 217; // 0xd9
     field public static final int WAVEPLUS_TECHNOLOGY = 35; // 0x23
     field public static final int WICENTRIC = 95; // 0x5f
     field public static final int WIDCOMM = 17; // 0x11
+    field public static final int WUXI_VIMICRO = 129; // 0x81
     field public static final int ZEEVO = 18; // 0x12
+    field public static final int ZER01_TV = 152; // 0x98
+    field public static final int ZOMM = 116; // 0x74
+    field public static final int ZSCAN_SOFTWARE = 141; // 0x8d
   }
 
   public final class BluetoothClass implements android.os.Parcelable {
@@ -4905,7 +5144,8 @@
   }
 
   public final class BluetoothGatt implements android.bluetooth.BluetoothProfile {
-    method public void abortReliableWrite(android.bluetooth.BluetoothDevice);
+    method public void abortReliableWrite();
+    method public deprecated void abortReliableWrite(android.bluetooth.BluetoothDevice);
     method public boolean beginReliableWrite();
     method public void close();
     method public boolean connect();
@@ -5066,6 +5306,7 @@
     method public int getConnectionState(android.bluetooth.BluetoothDevice);
     method public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int[]);
     method public boolean isAudioConnected(android.bluetooth.BluetoothDevice);
+    method public boolean sendVendorSpecificResultCode(android.bluetooth.BluetoothDevice, java.lang.String, java.lang.String);
     method public boolean startVoiceRecognition(android.bluetooth.BluetoothDevice);
     method public boolean stopVoiceRecognition(android.bluetooth.BluetoothDevice);
     field public static final java.lang.String ACTION_AUDIO_STATE_CHANGED = "android.bluetooth.headset.profile.action.AUDIO_STATE_CHANGED";
@@ -5082,6 +5323,7 @@
     field public static final int STATE_AUDIO_CONNECTED = 12; // 0xc
     field public static final int STATE_AUDIO_CONNECTING = 11; // 0xb
     field public static final int STATE_AUDIO_DISCONNECTED = 10; // 0xa
+    field public static final java.lang.String VENDOR_RESULT_CODE_COMMAND_ANDROID = "+ANDROID";
     field public static final java.lang.String VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY = "android.bluetooth.headset.intent.category.companyid";
   }
 
@@ -5376,8 +5618,10 @@
     method public void attachInfo(android.content.Context, android.content.pm.ProviderInfo);
     method public int bulkInsert(android.net.Uri, android.content.ContentValues[]);
     method public android.os.Bundle call(java.lang.String, java.lang.String, android.os.Bundle);
+    method public android.net.Uri canonicalize(android.net.Uri);
     method public abstract int delete(android.net.Uri, java.lang.String, java.lang.String[]);
     method public void dump(java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+    method public final java.lang.String getCallingPackage();
     method public final android.content.Context getContext();
     method public final android.content.pm.PathPermission[] getPathPermissions();
     method public final java.lang.String getReadPermission();
@@ -5391,16 +5635,20 @@
     method public void onLowMemory();
     method public void onTrimMemory(int);
     method public android.content.res.AssetFileDescriptor openAssetFile(android.net.Uri, java.lang.String) throws java.io.FileNotFoundException;
+    method public android.content.res.AssetFileDescriptor openAssetFile(android.net.Uri, java.lang.String, android.os.CancellationSignal) throws java.io.FileNotFoundException;
     method public android.os.ParcelFileDescriptor openFile(android.net.Uri, java.lang.String) throws java.io.FileNotFoundException;
+    method public android.os.ParcelFileDescriptor openFile(android.net.Uri, java.lang.String, android.os.CancellationSignal) throws java.io.FileNotFoundException;
     method protected final android.os.ParcelFileDescriptor openFileHelper(android.net.Uri, java.lang.String) throws java.io.FileNotFoundException;
     method public android.os.ParcelFileDescriptor openPipeHelper(android.net.Uri, java.lang.String, android.os.Bundle, T, android.content.ContentProvider.PipeDataWriter<T>) throws java.io.FileNotFoundException;
     method public android.content.res.AssetFileDescriptor openTypedAssetFile(android.net.Uri, java.lang.String, android.os.Bundle) throws java.io.FileNotFoundException;
+    method public android.content.res.AssetFileDescriptor openTypedAssetFile(android.net.Uri, java.lang.String, android.os.Bundle, android.os.CancellationSignal) throws java.io.FileNotFoundException;
     method public abstract android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
     method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal);
     method protected final void setPathPermissions(android.content.pm.PathPermission[]);
     method protected final void setReadPermission(java.lang.String);
     method protected final void setWritePermission(java.lang.String);
     method public void shutdown();
+    method public android.net.Uri uncanonicalize(android.net.Uri);
     method public abstract int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
   }
 
@@ -5412,17 +5660,22 @@
     method public android.content.ContentProviderResult[] applyBatch(java.util.ArrayList<android.content.ContentProviderOperation>) throws android.content.OperationApplicationException, android.os.RemoteException;
     method public int bulkInsert(android.net.Uri, android.content.ContentValues[]) throws android.os.RemoteException;
     method public android.os.Bundle call(java.lang.String, java.lang.String, android.os.Bundle) throws android.os.RemoteException;
+    method public final android.net.Uri canonicalize(android.net.Uri) throws android.os.RemoteException;
     method public int delete(android.net.Uri, java.lang.String, java.lang.String[]) throws android.os.RemoteException;
     method public android.content.ContentProvider getLocalContentProvider();
     method public java.lang.String[] getStreamTypes(android.net.Uri, java.lang.String) throws android.os.RemoteException;
     method public java.lang.String getType(android.net.Uri) throws android.os.RemoteException;
     method public android.net.Uri insert(android.net.Uri, android.content.ContentValues) throws android.os.RemoteException;
     method public android.content.res.AssetFileDescriptor openAssetFile(android.net.Uri, java.lang.String) throws java.io.FileNotFoundException, android.os.RemoteException;
+    method public android.content.res.AssetFileDescriptor openAssetFile(android.net.Uri, java.lang.String, android.os.CancellationSignal) throws java.io.FileNotFoundException, android.os.RemoteException;
     method public android.os.ParcelFileDescriptor openFile(android.net.Uri, java.lang.String) throws java.io.FileNotFoundException, android.os.RemoteException;
+    method public android.os.ParcelFileDescriptor openFile(android.net.Uri, java.lang.String, android.os.CancellationSignal) throws java.io.FileNotFoundException, android.os.RemoteException;
     method public final android.content.res.AssetFileDescriptor openTypedAssetFileDescriptor(android.net.Uri, java.lang.String, android.os.Bundle) throws java.io.FileNotFoundException, android.os.RemoteException;
+    method public final android.content.res.AssetFileDescriptor openTypedAssetFileDescriptor(android.net.Uri, java.lang.String, android.os.Bundle, android.os.CancellationSignal) throws java.io.FileNotFoundException, android.os.RemoteException;
     method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String) throws android.os.RemoteException;
     method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal) throws android.os.RemoteException;
     method public boolean release();
+    method public final android.net.Uri uncanonicalize(android.net.Uri) throws android.os.RemoteException;
     method public int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]) throws android.os.RemoteException;
   }
 
@@ -5488,11 +5741,14 @@
     method public final android.os.Bundle call(android.net.Uri, java.lang.String, java.lang.String, android.os.Bundle);
     method public deprecated void cancelSync(android.net.Uri);
     method public static void cancelSync(android.accounts.Account, java.lang.String);
+    method public final android.net.Uri canonicalize(android.net.Uri);
     method public final int delete(android.net.Uri, java.lang.String, java.lang.String[]);
     method public static deprecated android.content.SyncInfo getCurrentSync();
     method public static java.util.List<android.content.SyncInfo> getCurrentSyncs();
+    method public android.net.Uri[] getIncomingUriPermissionGrants(int, int);
     method public static int getIsSyncable(android.accounts.Account, java.lang.String);
     method public static boolean getMasterSyncAutomatically();
+    method public android.net.Uri[] getOutgoingUriPermissionGrants(int, int);
     method public static java.util.List<android.content.PeriodicSync> getPeriodicSyncs(android.accounts.Account, java.lang.String);
     method public java.lang.String[] getStreamTypes(android.net.Uri, java.lang.String);
     method public static android.content.SyncAdapterType[] getSyncAdapterTypes();
@@ -5504,21 +5760,26 @@
     method public void notifyChange(android.net.Uri, android.database.ContentObserver);
     method public void notifyChange(android.net.Uri, android.database.ContentObserver, boolean);
     method public final android.content.res.AssetFileDescriptor openAssetFileDescriptor(android.net.Uri, java.lang.String) throws java.io.FileNotFoundException;
+    method public final android.content.res.AssetFileDescriptor openAssetFileDescriptor(android.net.Uri, java.lang.String, android.os.CancellationSignal) throws java.io.FileNotFoundException;
     method public final android.os.ParcelFileDescriptor openFileDescriptor(android.net.Uri, java.lang.String) throws java.io.FileNotFoundException;
+    method public final android.os.ParcelFileDescriptor openFileDescriptor(android.net.Uri, java.lang.String, android.os.CancellationSignal) throws java.io.FileNotFoundException;
     method public final java.io.InputStream openInputStream(android.net.Uri) throws java.io.FileNotFoundException;
     method public final java.io.OutputStream openOutputStream(android.net.Uri) throws java.io.FileNotFoundException;
     method public final java.io.OutputStream openOutputStream(android.net.Uri, java.lang.String) throws java.io.FileNotFoundException;
     method public final android.content.res.AssetFileDescriptor openTypedAssetFileDescriptor(android.net.Uri, java.lang.String, android.os.Bundle) throws java.io.FileNotFoundException;
+    method public final android.content.res.AssetFileDescriptor openTypedAssetFileDescriptor(android.net.Uri, java.lang.String, android.os.Bundle, android.os.CancellationSignal) throws java.io.FileNotFoundException;
     method public final android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
     method public final android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal);
     method public final void registerContentObserver(android.net.Uri, boolean, android.database.ContentObserver);
     method public static void removePeriodicSync(android.accounts.Account, java.lang.String, android.os.Bundle);
     method public static void removeStatusChangeListener(java.lang.Object);
     method public static void requestSync(android.accounts.Account, java.lang.String, android.os.Bundle);
+    method public static void requestSync(android.content.SyncRequest);
     method public static void setIsSyncable(android.accounts.Account, java.lang.String, int);
     method public static void setMasterSyncAutomatically(boolean);
     method public static void setSyncAutomatically(android.accounts.Account, java.lang.String, boolean);
     method public deprecated void startSync(android.net.Uri, android.os.Bundle);
+    method public final android.net.Uri uncanonicalize(android.net.Uri);
     method public final void unregisterContentObserver(android.database.ContentObserver);
     method public final int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
     method public static void validateSyncExtrasBundle(android.os.Bundle);
@@ -5621,11 +5882,14 @@
     method public abstract java.io.File getDatabasePath(java.lang.String);
     method public abstract java.io.File getDir(java.lang.String, int);
     method public abstract java.io.File getExternalCacheDir();
+    method public abstract java.io.File[] getExternalCacheDirs();
     method public abstract java.io.File getExternalFilesDir(java.lang.String);
+    method public abstract java.io.File[] getExternalFilesDirs(java.lang.String);
     method public abstract java.io.File getFileStreamPath(java.lang.String);
     method public abstract java.io.File getFilesDir();
     method public abstract android.os.Looper getMainLooper();
     method public abstract java.io.File getObbDir();
+    method public abstract java.io.File[] getObbDirs();
     method public abstract java.lang.String getPackageCodePath();
     method public abstract android.content.pm.PackageManager getPackageManager();
     method public abstract java.lang.String getPackageName();
@@ -5687,6 +5951,7 @@
     field public static final java.lang.String ACCOUNT_SERVICE = "account";
     field public static final java.lang.String ACTIVITY_SERVICE = "activity";
     field public static final java.lang.String ALARM_SERVICE = "alarm";
+    field public static final java.lang.String APP_OPS_SERVICE = "appops";
     field public static final java.lang.String AUDIO_SERVICE = "audio";
     field public static final int BIND_ABOVE_CLIENT = 8; // 0x8
     field public static final int BIND_ADJUST_WITH_ACTIVITY = 128; // 0x80
@@ -5697,8 +5962,11 @@
     field public static final int BIND_NOT_FOREGROUND = 4; // 0x4
     field public static final int BIND_WAIVE_PRIORITY = 32; // 0x20
     field public static final java.lang.String BLUETOOTH_SERVICE = "bluetooth";
+    field public static final java.lang.String CAMERA_SERVICE = "camera";
+    field public static final java.lang.String CAPTIONING_SERVICE = "captioning";
     field public static final java.lang.String CLIPBOARD_SERVICE = "clipboard";
     field public static final java.lang.String CONNECTIVITY_SERVICE = "connectivity";
+    field public static final java.lang.String CONSUMER_IR_SERVICE = "consumer_ir";
     field public static final int CONTEXT_IGNORE_SECURITY = 2; // 0x2
     field public static final int CONTEXT_INCLUDE_CODE = 1; // 0x1
     field public static final int CONTEXT_RESTRICTED = 4; // 0x4
@@ -5722,6 +5990,7 @@
     field public static final java.lang.String NOTIFICATION_SERVICE = "notification";
     field public static final java.lang.String NSD_SERVICE = "servicediscovery";
     field public static final java.lang.String POWER_SERVICE = "power";
+    field public static final java.lang.String PRINT_SERVICE = "print";
     field public static final java.lang.String SEARCH_SERVICE = "search";
     field public static final java.lang.String SENSOR_SERVICE = "sensor";
     field public static final java.lang.String STORAGE_SERVICE = "storage";
@@ -5773,11 +6042,14 @@
     method public java.io.File getDatabasePath(java.lang.String);
     method public java.io.File getDir(java.lang.String, int);
     method public java.io.File getExternalCacheDir();
+    method public java.io.File[] getExternalCacheDirs();
     method public java.io.File getExternalFilesDir(java.lang.String);
+    method public java.io.File[] getExternalFilesDirs(java.lang.String);
     method public java.io.File getFileStreamPath(java.lang.String);
     method public java.io.File getFilesDir();
     method public android.os.Looper getMainLooper();
     method public java.io.File getObbDir();
+    method public java.io.File[] getObbDirs();
     method public java.lang.String getPackageCodePath();
     method public android.content.pm.PackageManager getPackageManager();
     method public java.lang.String getPackageName();
@@ -6043,6 +6315,7 @@
     field public static final java.lang.String ACTION_CHOOSER = "android.intent.action.CHOOSER";
     field public static final java.lang.String ACTION_CLOSE_SYSTEM_DIALOGS = "android.intent.action.CLOSE_SYSTEM_DIALOGS";
     field public static final java.lang.String ACTION_CONFIGURATION_CHANGED = "android.intent.action.CONFIGURATION_CHANGED";
+    field public static final java.lang.String ACTION_CREATE_DOCUMENT = "android.intent.action.CREATE_DOCUMENT";
     field public static final java.lang.String ACTION_CREATE_SHORTCUT = "android.intent.action.CREATE_SHORTCUT";
     field public static final java.lang.String ACTION_DATE_CHANGED = "android.intent.action.DATE_CHANGED";
     field public static final java.lang.String ACTION_DEFAULT = "android.intent.action.VIEW";
@@ -6085,6 +6358,7 @@
     field public static final java.lang.String ACTION_MEDIA_UNMOUNTED = "android.intent.action.MEDIA_UNMOUNTED";
     field public static final java.lang.String ACTION_MY_PACKAGE_REPLACED = "android.intent.action.MY_PACKAGE_REPLACED";
     field public static final java.lang.String ACTION_NEW_OUTGOING_CALL = "android.intent.action.NEW_OUTGOING_CALL";
+    field public static final java.lang.String ACTION_OPEN_DOCUMENT = "android.intent.action.OPEN_DOCUMENT";
     field public static final java.lang.String ACTION_PACKAGE_ADDED = "android.intent.action.PACKAGE_ADDED";
     field public static final java.lang.String ACTION_PACKAGE_CHANGED = "android.intent.action.PACKAGE_CHANGED";
     field public static final java.lang.String ACTION_PACKAGE_DATA_CLEARED = "android.intent.action.PACKAGE_DATA_CLEARED";
@@ -6192,6 +6466,7 @@
     field public static final java.lang.String EXTRA_INTENT = "android.intent.extra.INTENT";
     field public static final java.lang.String EXTRA_KEY_EVENT = "android.intent.extra.KEY_EVENT";
     field public static final java.lang.String EXTRA_LOCAL_ONLY = "android.intent.extra.LOCAL_ONLY";
+    field public static final java.lang.String EXTRA_MIME_TYPES = "android.intent.extra.MIME_TYPES";
     field public static final java.lang.String EXTRA_NOT_UNKNOWN_SOURCE = "android.intent.extra.NOT_UNKNOWN_SOURCE";
     field public static final java.lang.String EXTRA_ORIGINATING_URI = "android.intent.extra.ORIGINATING_URI";
     field public static final java.lang.String EXTRA_PHONE_NUMBER = "android.intent.extra.PHONE_NUMBER";
@@ -6206,6 +6481,7 @@
     field public static final java.lang.String EXTRA_SHORTCUT_ICON_RESOURCE = "android.intent.extra.shortcut.ICON_RESOURCE";
     field public static final java.lang.String EXTRA_SHORTCUT_INTENT = "android.intent.extra.shortcut.INTENT";
     field public static final java.lang.String EXTRA_SHORTCUT_NAME = "android.intent.extra.shortcut.NAME";
+    field public static final java.lang.String EXTRA_SHUTDOWN_USERSPACE_ONLY = "android.intent.extra.SHUTDOWN_USERSPACE_ONLY";
     field public static final java.lang.String EXTRA_STREAM = "android.intent.extra.STREAM";
     field public static final java.lang.String EXTRA_SUBJECT = "android.intent.extra.SUBJECT";
     field public static final java.lang.String EXTRA_TEMPLATE = "android.intent.extra.TEMPLATE";
@@ -6243,6 +6519,7 @@
     field public static final int FLAG_GRANT_READ_URI_PERMISSION = 1; // 0x1
     field public static final int FLAG_GRANT_WRITE_URI_PERMISSION = 2; // 0x2
     field public static final int FLAG_INCLUDE_STOPPED_PACKAGES = 32; // 0x20
+    field public static final int FLAG_PERSIST_GRANT_URI_PERMISSION = 64; // 0x40
     field public static final int FLAG_RECEIVER_FOREGROUND = 268435456; // 0x10000000
     field public static final int FLAG_RECEIVER_REGISTERED_ONLY = 1073741824; // 0x40000000
     field public static final int FLAG_RECEIVER_REPLACE_PENDING = 536870912; // 0x20000000
@@ -6276,6 +6553,7 @@
     method public final void addDataAuthority(java.lang.String, java.lang.String);
     method public final void addDataPath(java.lang.String, int);
     method public final void addDataScheme(java.lang.String);
+    method public final void addDataSchemeSpecificPart(java.lang.String, int);
     method public final void addDataType(java.lang.String) throws android.content.IntentFilter.MalformedMimeTypeException;
     method public final java.util.Iterator<android.content.IntentFilter.AuthorityEntry> authoritiesIterator();
     method public final java.util.Iterator<java.lang.String> categoriesIterator();
@@ -6283,6 +6561,7 @@
     method public final int countCategories();
     method public final int countDataAuthorities();
     method public final int countDataPaths();
+    method public final int countDataSchemeSpecificParts();
     method public final int countDataSchemes();
     method public final int countDataTypes();
     method public static android.content.IntentFilter create(java.lang.String, java.lang.String);
@@ -6293,6 +6572,7 @@
     method public final android.content.IntentFilter.AuthorityEntry getDataAuthority(int);
     method public final android.os.PatternMatcher getDataPath(int);
     method public final java.lang.String getDataScheme(int);
+    method public final android.os.PatternMatcher getDataSchemeSpecificPart(int);
     method public final java.lang.String getDataType(int);
     method public final int getPriority();
     method public final boolean hasAction(java.lang.String);
@@ -6300,6 +6580,7 @@
     method public final boolean hasDataAuthority(android.net.Uri);
     method public final boolean hasDataPath(java.lang.String);
     method public final boolean hasDataScheme(java.lang.String);
+    method public final boolean hasDataSchemeSpecificPart(java.lang.String);
     method public final boolean hasDataType(java.lang.String);
     method public final int match(android.content.ContentResolver, android.content.Intent, boolean, java.lang.String);
     method public final int match(java.lang.String, java.lang.String, java.lang.String, android.net.Uri, java.util.Set<java.lang.String>, java.lang.String);
@@ -6309,6 +6590,7 @@
     method public final int matchDataAuthority(android.net.Uri);
     method public final java.util.Iterator<android.os.PatternMatcher> pathsIterator();
     method public void readFromXml(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public final java.util.Iterator<android.os.PatternMatcher> schemeSpecificPartsIterator();
     method public final java.util.Iterator<java.lang.String> schemesIterator();
     method public final void setPriority(int);
     method public final java.util.Iterator<java.lang.String> typesIterator();
@@ -6323,6 +6605,7 @@
     field public static final int MATCH_CATEGORY_PATH = 5242880; // 0x500000
     field public static final int MATCH_CATEGORY_PORT = 4194304; // 0x400000
     field public static final int MATCH_CATEGORY_SCHEME = 2097152; // 0x200000
+    field public static final int MATCH_CATEGORY_SCHEME_SPECIFIC_PART = 5767168; // 0x580000
     field public static final int MATCH_CATEGORY_TYPE = 6291456; // 0x600000
     field public static final int NO_MATCH_ACTION = -3; // 0xfffffffd
     field public static final int NO_MATCH_CATEGORY = -4; // 0xfffffffc
@@ -6555,6 +6838,27 @@
     field public final long startTime;
   }
 
+  public class SyncRequest implements android.os.Parcelable {
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
+  public static class SyncRequest.Builder {
+    ctor public SyncRequest.Builder();
+    method public android.content.SyncRequest build();
+    method public android.content.SyncRequest.Builder setDisallowMetered(boolean);
+    method public android.content.SyncRequest.Builder setExpedited(boolean);
+    method public android.content.SyncRequest.Builder setExtras(android.os.Bundle);
+    method public android.content.SyncRequest.Builder setIgnoreBackoff(boolean);
+    method public android.content.SyncRequest.Builder setIgnoreSettings(boolean);
+    method public android.content.SyncRequest.Builder setManual(boolean);
+    method public android.content.SyncRequest.Builder setNoRetry(boolean);
+    method public android.content.SyncRequest.Builder setSyncAdapter(android.accounts.Account, java.lang.String);
+    method public android.content.SyncRequest.Builder syncOnce();
+    method public android.content.SyncRequest.Builder syncPeriodic(long, long);
+  }
+
   public final class SyncResult implements android.os.Parcelable {
     ctor public SyncResult();
     method public void clear();
@@ -6744,6 +7048,7 @@
     ctor public ComponentInfo(android.content.pm.ComponentInfo);
     ctor protected ComponentInfo(android.os.Parcel);
     method public final int getIconResource();
+    method public final int getLogoResource();
     method public boolean isEnabled();
     field public android.content.pm.ApplicationInfo applicationInfo;
     field public int descriptionRes;
@@ -6964,6 +7269,7 @@
     field public static final java.lang.String FEATURE_LOCATION_NETWORK = "android.hardware.location.network";
     field public static final java.lang.String FEATURE_MICROPHONE = "android.hardware.microphone";
     field public static final java.lang.String FEATURE_NFC = "android.hardware.nfc";
+    field public static final java.lang.String FEATURE_NFC_HOST_CARD_EMULATION = "android.hardware.nfc.hce";
     field public static final java.lang.String FEATURE_SCREEN_LANDSCAPE = "android.hardware.screen.landscape";
     field public static final java.lang.String FEATURE_SCREEN_PORTRAIT = "android.hardware.screen.portrait";
     field public static final java.lang.String FEATURE_SENSOR_ACCELEROMETER = "android.hardware.sensor.accelerometer";
@@ -7159,7 +7465,7 @@
 
 package android.content.res {
 
-  public class AssetFileDescriptor implements android.os.Parcelable {
+  public class AssetFileDescriptor implements java.io.Closeable android.os.Parcelable {
     ctor public AssetFileDescriptor(android.os.ParcelFileDescriptor, long, long);
     method public void close() throws java.io.IOException;
     method public java.io.FileInputStream createInputStream() throws java.io.IOException;
@@ -7432,7 +7738,7 @@
     method public void recycle();
   }
 
-  public abstract interface XmlResourceParser implements android.util.AttributeSet org.xmlpull.v1.XmlPullParser {
+  public abstract interface XmlResourceParser implements android.util.AttributeSet java.lang.AutoCloseable org.xmlpull.v1.XmlPullParser {
     method public abstract void close();
   }
 
@@ -7572,6 +7878,7 @@
     method public abstract float getFloat(int);
     method public abstract int getInt(int);
     method public abstract long getLong(int);
+    method public abstract android.net.Uri getNotificationUri();
     method public abstract int getPosition();
     method public abstract short getShort(int);
     method public abstract java.lang.String getString(int);
@@ -7677,6 +7984,7 @@
     method public float getFloat(int);
     method public int getInt(int);
     method public long getLong(int);
+    method public android.net.Uri getNotificationUri();
     method public int getPosition();
     method public short getShort(int);
     method public java.lang.String getString(int);
@@ -7824,6 +8132,7 @@
 
   public class MatrixCursor.RowBuilder {
     method public android.database.MatrixCursor.RowBuilder add(java.lang.Object);
+    method public android.database.MatrixCursor.RowBuilder add(java.lang.String, java.lang.Object);
   }
 
   public class MergeCursor extends android.database.AbstractCursor {
@@ -8568,6 +8877,7 @@
     method public void eraseColor(int);
     method public android.graphics.Bitmap extractAlpha();
     method public android.graphics.Bitmap extractAlpha(android.graphics.Paint, int[]);
+    method public final int getAllocationByteCount();
     method public final int getByteCount();
     method public final android.graphics.Bitmap.Config getConfig();
     method public int getDensity();
@@ -8590,13 +8900,18 @@
     method public final boolean isPremultiplied();
     method public final boolean isRecycled();
     method public void prepareToDraw();
+    method public void reconfigure(int, int, android.graphics.Bitmap.Config);
     method public void recycle();
     method public boolean sameAs(android.graphics.Bitmap);
+    method public void setConfig(android.graphics.Bitmap.Config);
     method public void setDensity(int);
     method public void setHasAlpha(boolean);
     method public final void setHasMipMap(boolean);
+    method public void setHeight(int);
     method public void setPixel(int, int, int);
     method public void setPixels(int[], int, int, int, int, int, int);
+    method public final void setPremultiplied(boolean);
+    method public void setWidth(int);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
     field public static final int DENSITY_NONE = 0; // 0x0
@@ -8645,6 +8960,7 @@
     field public boolean inMutable;
     field public boolean inPreferQualityOverSpeed;
     field public android.graphics.Bitmap.Config inPreferredConfig;
+    field public boolean inPremultiplied;
     field public boolean inPurgeable;
     field public int inSampleSize;
     field public boolean inScaled;
@@ -8903,8 +9219,10 @@
     field public static final int JPEG = 256; // 0x100
     field public static final int NV16 = 16; // 0x10
     field public static final int NV21 = 17; // 0x11
+    field public static final int RAW_SENSOR = 32; // 0x20
     field public static final int RGB_565 = 4; // 0x4
     field public static final int UNKNOWN = 0; // 0x0
+    field public static final int YUV_420_888 = 35; // 0x23
     field public static final int YUY2 = 20; // 0x14
     field public static final int YV12 = 842094169; // 0x32315659
   }
@@ -9032,12 +9350,16 @@
   }
 
   public class NinePatch {
+    ctor public NinePatch(android.graphics.Bitmap, byte[]);
     ctor public NinePatch(android.graphics.Bitmap, byte[], java.lang.String);
     method public void draw(android.graphics.Canvas, android.graphics.RectF);
     method public void draw(android.graphics.Canvas, android.graphics.Rect);
     method public void draw(android.graphics.Canvas, android.graphics.Rect, android.graphics.Paint);
+    method public android.graphics.Bitmap getBitmap();
     method public int getDensity();
     method public int getHeight();
+    method public java.lang.String getName();
+    method public android.graphics.Paint getPaint();
     method public final android.graphics.Region getTransparentRegion(android.graphics.Rect);
     method public int getWidth();
     method public final boolean hasAlpha();
@@ -9138,6 +9460,7 @@
     field public static final int ANTI_ALIAS_FLAG = 1; // 0x1
     field public static final int DEV_KERN_TEXT_FLAG = 256; // 0x100
     field public static final int DITHER_FLAG = 4; // 0x4
+    field public static final int EMBEDDED_BITMAP_TEXT_FLAG = 1024; // 0x400
     field public static final int FAKE_BOLD_TEXT_FLAG = 32; // 0x20
     field public static final int FILTER_BITMAP_FLAG = 2; // 0x2
     field public static final int HINTING_OFF = 0; // 0x0
@@ -9229,6 +9552,8 @@
     method public void moveTo(float, float);
     method public void offset(float, float, android.graphics.Path);
     method public void offset(float, float);
+    method public boolean op(android.graphics.Path, android.graphics.Path.Op);
+    method public boolean op(android.graphics.Path, android.graphics.Path, android.graphics.Path.Op);
     method public void quadTo(float, float, float, float);
     method public void rCubicTo(float, float, float, float, float, float);
     method public void rLineTo(float, float);
@@ -9260,6 +9585,16 @@
     enum_constant public static final android.graphics.Path.FillType WINDING;
   }
 
+  public static final class Path.Op extends java.lang.Enum {
+    method public static android.graphics.Path.Op valueOf(java.lang.String);
+    method public static final android.graphics.Path.Op[] values();
+    enum_constant public static final android.graphics.Path.Op DIFFERENCE;
+    enum_constant public static final android.graphics.Path.Op INTERSECT;
+    enum_constant public static final android.graphics.Path.Op REVERSE_DIFFERENCE;
+    enum_constant public static final android.graphics.Path.Op UNION;
+    enum_constant public static final android.graphics.Path.Op XOR;
+  }
+
   public class PathDashPathEffect extends android.graphics.PathEffect {
     ctor public PathDashPathEffect(android.graphics.Path, float, float, android.graphics.PathDashPathEffect.Style);
   }
@@ -9306,10 +9641,10 @@
     ctor public PixelFormat();
     method public static boolean formatHasAlpha(int);
     method public static void getPixelFormatInfo(int, android.graphics.PixelFormat);
-    field public static final int A_8 = 8; // 0x8
+    field public static final deprecated int A_8 = 8; // 0x8
     field public static final deprecated int JPEG = 256; // 0x100
     field public static final deprecated int LA_88 = 10; // 0xa
-    field public static final int L_8 = 9; // 0x9
+    field public static final deprecated int L_8 = 9; // 0x9
     field public static final int OPAQUE = -1; // 0xffffffff
     field public static final deprecated int RGBA_4444 = 7; // 0x7
     field public static final deprecated int RGBA_5551 = 6; // 0x6
@@ -9567,11 +9902,13 @@
 
   public class SurfaceTexture {
     ctor public SurfaceTexture(int);
+    ctor public SurfaceTexture(int, boolean);
     method public void attachToGLContext(int);
     method public void detachFromGLContext();
     method public long getTimestamp();
     method public void getTransformMatrix(float[]);
     method public void release();
+    method public void releaseTexImage();
     method public void setDefaultBufferSize(int, int);
     method public void setOnFrameAvailableListener(android.graphics.SurfaceTexture.OnFrameAvailableListener);
     method public void updateTexImage();
@@ -9581,7 +9918,7 @@
     method public abstract void onFrameAvailable(android.graphics.SurfaceTexture);
   }
 
-  public static class SurfaceTexture.OutOfResourcesException extends java.lang.Exception {
+  public static deprecated class SurfaceTexture.OutOfResourcesException extends java.lang.Exception {
     ctor public SurfaceTexture.OutOfResourcesException();
     ctor public SurfaceTexture.OutOfResourcesException(java.lang.String);
   }
@@ -9669,6 +10006,7 @@
     method public android.graphics.Shader.TileMode getTileModeY();
     method public boolean hasAntiAlias();
     method public boolean hasMipMap();
+    method public final boolean isAutoMirrored();
     method public void setAlpha(int);
     method public void setAntiAlias(boolean);
     method public void setColorFilter(android.graphics.ColorFilter);
@@ -9699,7 +10037,6 @@
     ctor public ColorDrawable();
     ctor public ColorDrawable(int);
     method public void draw(android.graphics.Canvas);
-    method public int getAlpha();
     method public int getColor();
     method public int getOpacity();
     method public void setAlpha(int);
@@ -9719,6 +10056,7 @@
     method public static android.graphics.drawable.Drawable createFromXml(android.content.res.Resources, org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public static android.graphics.drawable.Drawable createFromXmlInner(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public abstract void draw(android.graphics.Canvas);
+    method public int getAlpha();
     method public final android.graphics.Rect getBounds();
     method public android.graphics.drawable.Drawable.Callback getCallback();
     method public int getChangingConfigurations();
@@ -9735,6 +10073,7 @@
     method public android.graphics.Region getTransparentRegion();
     method public void inflate(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public void invalidateSelf();
+    method public boolean isAutoMirrored();
     method public boolean isStateful();
     method public final boolean isVisible();
     method public void jumpToCurrentState();
@@ -9745,6 +10084,7 @@
     method public static int resolveOpacity(int, int);
     method public void scheduleSelf(java.lang.Runnable, long);
     method public abstract void setAlpha(int);
+    method public void setAutoMirrored(boolean);
     method public void setBounds(int, int, int, int);
     method public void setBounds(android.graphics.Rect);
     method public final void setCallback(android.graphics.drawable.Drawable.Callback);
@@ -9792,6 +10132,7 @@
     method public synchronized boolean canConstantState();
     method protected void computeConstantSize();
     method public int getChangingConfigurations();
+    method public final android.graphics.drawable.Drawable getChild(int);
     method public final int getChildCount();
     method public final android.graphics.drawable.Drawable[] getChildren();
     method public final int getConstantHeight();
@@ -9858,6 +10199,7 @@
     ctor public InsetDrawable(android.graphics.drawable.Drawable, int);
     ctor public InsetDrawable(android.graphics.drawable.Drawable, int, int, int, int);
     method public void draw(android.graphics.Canvas);
+    method public android.graphics.drawable.Drawable getDrawable();
     method public int getOpacity();
     method public void invalidateDrawable(android.graphics.drawable.Drawable);
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
@@ -10279,6 +10621,22 @@
     field public int width;
   }
 
+  public final class ConsumerIrManager {
+    method public android.hardware.ConsumerIrManager.CarrierFrequencyRange[] getCarrierFrequencies();
+    method public boolean hasIrEmitter();
+    method public void transmit(int, int[]);
+  }
+
+  public final class ConsumerIrManager.CarrierFrequencyRange {
+    ctor public ConsumerIrManager.CarrierFrequencyRange(int, int);
+    method public int getMaxFrequency();
+    method public int getMinFrequency();
+  }
+
+  public abstract interface FlushCompleteListener {
+    method public abstract void onFlushCompleted(android.hardware.Sensor);
+  }
+
   public class GeomagneticField {
     ctor public GeomagneticField(float, float, float, long);
     method public float getDeclination();
@@ -10291,6 +10649,8 @@
   }
 
   public final class Sensor {
+    method public int getFifoMaxEventCount();
+    method public int getFifoReservedEventCount();
     method public float getMaximumRange();
     method public int getMinDelay();
     method public java.lang.String getName();
@@ -10303,6 +10663,7 @@
     field public static final int TYPE_ALL = -1; // 0xffffffff
     field public static final int TYPE_AMBIENT_TEMPERATURE = 13; // 0xd
     field public static final int TYPE_GAME_ROTATION_VECTOR = 15; // 0xf
+    field public static final int TYPE_GEOMAGNETIC_ROTATION_VECTOR = 20; // 0x14
     field public static final int TYPE_GRAVITY = 9; // 0x9
     field public static final int TYPE_GYROSCOPE = 4; // 0x4
     field public static final int TYPE_GYROSCOPE_UNCALIBRATED = 16; // 0x10
@@ -10316,6 +10677,8 @@
     field public static final int TYPE_RELATIVE_HUMIDITY = 12; // 0xc
     field public static final int TYPE_ROTATION_VECTOR = 11; // 0xb
     field public static final int TYPE_SIGNIFICANT_MOTION = 17; // 0x11
+    field public static final int TYPE_STEP_COUNTER = 19; // 0x13
+    field public static final int TYPE_STEP_DETECTOR = 18; // 0x12
     field public static final deprecated int TYPE_TEMPERATURE = 7; // 0x7
   }
 
@@ -10338,6 +10701,7 @@
 
   public abstract class SensorManager {
     method public boolean cancelTriggerSensor(android.hardware.TriggerEventListener, android.hardware.Sensor);
+    method public boolean flush(android.hardware.Sensor);
     method public static float getAltitude(float, float);
     method public static void getAngleChange(float[], float[], float[]);
     method public android.hardware.Sensor getDefaultSensor(int);
@@ -10351,7 +10715,9 @@
     method public deprecated boolean registerListener(android.hardware.SensorListener, int);
     method public deprecated boolean registerListener(android.hardware.SensorListener, int, int);
     method public boolean registerListener(android.hardware.SensorEventListener, android.hardware.Sensor, int);
+    method public boolean registerListener(android.hardware.SensorEventListener, android.hardware.Sensor, int, int, int, android.hardware.FlushCompleteListener);
     method public boolean registerListener(android.hardware.SensorEventListener, android.hardware.Sensor, int, android.os.Handler);
+    method public boolean registerListener(android.hardware.SensorEventListener, android.hardware.Sensor, int, int, int, android.os.Handler, android.hardware.FlushCompleteListener);
     method public static boolean remapCoordinateSystem(float[], int, int, float[]);
     method public boolean requestTriggerSensor(android.hardware.TriggerEventListener, android.hardware.Sensor);
     method public deprecated void unregisterListener(android.hardware.SensorListener);
@@ -10430,15 +10796,393 @@
 
 }
 
+package android.hardware.camera2 {
+
+  public class CameraAccessException extends android.util.AndroidException {
+    ctor public CameraAccessException(int);
+    ctor public CameraAccessException(int, java.lang.String);
+    ctor public CameraAccessException(int, java.lang.String, java.lang.Throwable);
+    ctor public CameraAccessException(int, java.lang.Throwable);
+    method public final int getReason();
+    field public static final int CAMERA_DISABLED = 3; // 0x3
+    field public static final int CAMERA_DISCONNECTED = 4; // 0x4
+    field public static final int CAMERA_IN_USE = 1; // 0x1
+    field public static final int MAX_CAMERAS_IN_USE = 2; // 0x2
+  }
+
+  public abstract interface CameraDevice implements java.lang.AutoCloseable {
+    method public abstract void capture(android.hardware.camera2.CaptureRequest, android.hardware.camera2.CameraDevice.CaptureListener, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+    method public abstract void captureBurst(java.util.List<android.hardware.camera2.CaptureRequest>, android.hardware.camera2.CameraDevice.CaptureListener, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+    method public abstract void close() throws java.lang.Exception;
+    method public abstract void configureOutputs(java.util.List<android.view.Surface>) throws android.hardware.camera2.CameraAccessException;
+    method public abstract android.hardware.camera2.CaptureRequest.Builder createCaptureRequest(int) throws android.hardware.camera2.CameraAccessException;
+    method public abstract void flush() throws android.hardware.camera2.CameraAccessException;
+    method public abstract java.lang.String getId();
+    method public abstract android.hardware.camera2.CameraProperties getProperties() throws android.hardware.camera2.CameraAccessException;
+    method public abstract void setDeviceListener(android.hardware.camera2.CameraDevice.CameraDeviceListener, android.os.Handler);
+    method public abstract void setRepeatingBurst(java.util.List<android.hardware.camera2.CaptureRequest>, android.hardware.camera2.CameraDevice.CaptureListener, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+    method public abstract void setRepeatingRequest(android.hardware.camera2.CaptureRequest, android.hardware.camera2.CameraDevice.CaptureListener, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+    method public abstract void stopRepeating() throws android.hardware.camera2.CameraAccessException;
+    method public abstract void waitUntilIdle() throws android.hardware.camera2.CameraAccessException;
+    field public static final int TEMPLATE_PREVIEW = 1; // 0x1
+    field public static final int TEMPLATE_RECORD = 3; // 0x3
+    field public static final int TEMPLATE_STILL_CAPTURE = 2; // 0x2
+    field public static final int TEMPLATE_VIDEO_SNAPSHOT = 4; // 0x4
+  }
+
+  public static abstract class CameraDevice.CameraDeviceListener {
+    ctor public CameraDevice.CameraDeviceListener();
+    method public void onCameraDisconnected(android.hardware.camera2.CameraDevice);
+    method public void onCameraError(android.hardware.camera2.CameraDevice, int);
+    method public void onCameraIdle(android.hardware.camera2.CameraDevice);
+    field public static final int ERROR_CAMERA_DEVICE = 1; // 0x1
+    field public static final int ERROR_CAMERA_SERVICE = 2; // 0x2
+  }
+
+  public static abstract class CameraDevice.CaptureListener {
+    ctor public CameraDevice.CaptureListener();
+    method public void onCaptureCompleted(android.hardware.camera2.CameraDevice, android.hardware.camera2.CaptureRequest, android.hardware.camera2.CaptureResult);
+    method public void onCaptureFailed(android.hardware.camera2.CameraDevice, android.hardware.camera2.CaptureRequest);
+    method public void onCaptureStarted(android.hardware.camera2.CameraDevice, android.hardware.camera2.CaptureRequest, long);
+  }
+
+  public final class CameraManager {
+    method public void addAvailabilityListener(android.hardware.camera2.CameraManager.AvailabilityListener, android.os.Handler);
+    method public java.lang.String[] getCameraIdList() throws android.hardware.camera2.CameraAccessException;
+    method public android.hardware.camera2.CameraProperties getCameraProperties(java.lang.String) throws android.hardware.camera2.CameraAccessException;
+    method public android.hardware.camera2.CameraDevice openCamera(java.lang.String) throws android.hardware.camera2.CameraAccessException;
+    method public void removeAvailabilityListener(android.hardware.camera2.CameraManager.AvailabilityListener);
+  }
+
+  public static abstract class CameraManager.AvailabilityListener {
+    ctor public CameraManager.AvailabilityListener();
+    method public void onCameraAvailable(java.lang.String);
+    method public void onCameraUnavailable(java.lang.String);
+  }
+
+  public abstract class CameraMetadata {
+    method public abstract T get(android.hardware.camera2.CameraMetadata.Key<T>);
+    field public static final int COLOR_CORRECTION_MODE_FAST = 1; // 0x1
+    field public static final int COLOR_CORRECTION_MODE_HIGH_QUALITY = 2; // 0x2
+    field public static final int COLOR_CORRECTION_MODE_TRANSFORM_MATRIX = 0; // 0x0
+    field public static final int CONTROL_AE_ANTIBANDING_MODE_50HZ = 1; // 0x1
+    field public static final int CONTROL_AE_ANTIBANDING_MODE_60HZ = 2; // 0x2
+    field public static final int CONTROL_AE_ANTIBANDING_MODE_AUTO = 3; // 0x3
+    field public static final int CONTROL_AE_ANTIBANDING_MODE_OFF = 0; // 0x0
+    field public static final int CONTROL_AE_MODE_OFF = 0; // 0x0
+    field public static final int CONTROL_AE_MODE_ON = 1; // 0x1
+    field public static final int CONTROL_AE_MODE_ON_ALWAYS_FLASH = 3; // 0x3
+    field public static final int CONTROL_AE_MODE_ON_AUTO_FLASH = 2; // 0x2
+    field public static final int CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE = 4; // 0x4
+    field public static final int CONTROL_AE_PRECAPTURE_TRIGGER_IDLE = 0; // 0x0
+    field public static final int CONTROL_AE_PRECAPTURE_TRIGGER_START = 1; // 0x1
+    field public static final int CONTROL_AE_STATE_CONVERGED = 2; // 0x2
+    field public static final int CONTROL_AE_STATE_FLASH_REQUIRED = 4; // 0x4
+    field public static final int CONTROL_AE_STATE_INACTIVE = 0; // 0x0
+    field public static final int CONTROL_AE_STATE_LOCKED = 3; // 0x3
+    field public static final int CONTROL_AE_STATE_PRECAPTURE = 5; // 0x5
+    field public static final int CONTROL_AE_STATE_SEARCHING = 1; // 0x1
+    field public static final int CONTROL_AF_MODE_AUTO = 1; // 0x1
+    field public static final int CONTROL_AF_MODE_CONTINUOUS_PICTURE = 4; // 0x4
+    field public static final int CONTROL_AF_MODE_CONTINUOUS_VIDEO = 3; // 0x3
+    field public static final int CONTROL_AF_MODE_EDOF = 5; // 0x5
+    field public static final int CONTROL_AF_MODE_MACRO = 2; // 0x2
+    field public static final int CONTROL_AF_MODE_OFF = 0; // 0x0
+    field public static final int CONTROL_AF_STATE_ACTIVE_SCAN = 3; // 0x3
+    field public static final int CONTROL_AF_STATE_FOCUSED_LOCKED = 4; // 0x4
+    field public static final int CONTROL_AF_STATE_INACTIVE = 0; // 0x0
+    field public static final int CONTROL_AF_STATE_NOT_FOCUSED_LOCKED = 5; // 0x5
+    field public static final int CONTROL_AF_STATE_PASSIVE_FOCUSED = 2; // 0x2
+    field public static final int CONTROL_AF_STATE_PASSIVE_SCAN = 1; // 0x1
+    field public static final int CONTROL_AF_TRIGGER_CANCEL = 2; // 0x2
+    field public static final int CONTROL_AF_TRIGGER_IDLE = 0; // 0x0
+    field public static final int CONTROL_AF_TRIGGER_START = 1; // 0x1
+    field public static final int CONTROL_AWB_MODE_AUTO = 1; // 0x1
+    field public static final int CONTROL_AWB_MODE_CLOUDY_DAYLIGHT = 6; // 0x6
+    field public static final int CONTROL_AWB_MODE_DAYLIGHT = 5; // 0x5
+    field public static final int CONTROL_AWB_MODE_FLUORESCENT = 3; // 0x3
+    field public static final int CONTROL_AWB_MODE_INCANDESCENT = 2; // 0x2
+    field public static final int CONTROL_AWB_MODE_OFF = 0; // 0x0
+    field public static final int CONTROL_AWB_MODE_SHADE = 8; // 0x8
+    field public static final int CONTROL_AWB_MODE_TWILIGHT = 7; // 0x7
+    field public static final int CONTROL_AWB_MODE_WARM_FLUORESCENT = 4; // 0x4
+    field public static final int CONTROL_AWB_STATE_CONVERGED = 2; // 0x2
+    field public static final int CONTROL_AWB_STATE_INACTIVE = 0; // 0x0
+    field public static final int CONTROL_AWB_STATE_LOCKED = 3; // 0x3
+    field public static final int CONTROL_AWB_STATE_SEARCHING = 1; // 0x1
+    field public static final int CONTROL_CAPTURE_INTENT_CUSTOM = 0; // 0x0
+    field public static final int CONTROL_CAPTURE_INTENT_PREVIEW = 1; // 0x1
+    field public static final int CONTROL_CAPTURE_INTENT_STILL_CAPTURE = 2; // 0x2
+    field public static final int CONTROL_CAPTURE_INTENT_VIDEO_RECORD = 3; // 0x3
+    field public static final int CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT = 4; // 0x4
+    field public static final int CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG = 5; // 0x5
+    field public static final int CONTROL_EFFECT_MODE_AQUA = 8; // 0x8
+    field public static final int CONTROL_EFFECT_MODE_BLACKBOARD = 7; // 0x7
+    field public static final int CONTROL_EFFECT_MODE_MONO = 1; // 0x1
+    field public static final int CONTROL_EFFECT_MODE_NEGATIVE = 2; // 0x2
+    field public static final int CONTROL_EFFECT_MODE_OFF = 0; // 0x0
+    field public static final int CONTROL_EFFECT_MODE_POSTERIZE = 5; // 0x5
+    field public static final int CONTROL_EFFECT_MODE_SEPIA = 4; // 0x4
+    field public static final int CONTROL_EFFECT_MODE_SOLARIZE = 3; // 0x3
+    field public static final int CONTROL_EFFECT_MODE_WHITEBOARD = 6; // 0x6
+    field public static final int CONTROL_MODE_AUTO = 1; // 0x1
+    field public static final int CONTROL_MODE_OFF = 0; // 0x0
+    field public static final int CONTROL_MODE_USE_SCENE_MODE = 2; // 0x2
+    field public static final int CONTROL_SCENE_MODE_ACTION = 2; // 0x2
+    field public static final int CONTROL_SCENE_MODE_BARCODE = 16; // 0x10
+    field public static final int CONTROL_SCENE_MODE_BEACH = 8; // 0x8
+    field public static final int CONTROL_SCENE_MODE_CANDLELIGHT = 15; // 0xf
+    field public static final int CONTROL_SCENE_MODE_FACE_PRIORITY = 1; // 0x1
+    field public static final int CONTROL_SCENE_MODE_FIREWORKS = 12; // 0xc
+    field public static final int CONTROL_SCENE_MODE_LANDSCAPE = 4; // 0x4
+    field public static final int CONTROL_SCENE_MODE_NIGHT = 5; // 0x5
+    field public static final int CONTROL_SCENE_MODE_NIGHT_PORTRAIT = 6; // 0x6
+    field public static final int CONTROL_SCENE_MODE_PARTY = 14; // 0xe
+    field public static final int CONTROL_SCENE_MODE_PORTRAIT = 3; // 0x3
+    field public static final int CONTROL_SCENE_MODE_SNOW = 9; // 0x9
+    field public static final int CONTROL_SCENE_MODE_SPORTS = 13; // 0xd
+    field public static final int CONTROL_SCENE_MODE_STEADYPHOTO = 11; // 0xb
+    field public static final int CONTROL_SCENE_MODE_SUNSET = 10; // 0xa
+    field public static final int CONTROL_SCENE_MODE_THEATRE = 7; // 0x7
+    field public static final int CONTROL_SCENE_MODE_UNSUPPORTED = 0; // 0x0
+    field public static final int EDGE_MODE_FAST = 1; // 0x1
+    field public static final int EDGE_MODE_HIGH_QUALITY = 2; // 0x2
+    field public static final int EDGE_MODE_OFF = 0; // 0x0
+    field public static final int FLASH_MODE_OFF = 0; // 0x0
+    field public static final int FLASH_MODE_SINGLE = 1; // 0x1
+    field public static final int FLASH_MODE_TORCH = 2; // 0x2
+    field public static final int FLASH_STATE_CHARGING = 1; // 0x1
+    field public static final int FLASH_STATE_FIRED = 3; // 0x3
+    field public static final int FLASH_STATE_READY = 2; // 0x2
+    field public static final int FLASH_STATE_UNAVAILABLE = 0; // 0x0
+    field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_FULL = 1; // 0x1
+    field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED = 0; // 0x0
+    field public static final int LENS_FACING_BACK = 1; // 0x1
+    field public static final int LENS_FACING_FRONT = 0; // 0x0
+    field public static final int LENS_OPTICAL_STABILIZATION_MODE_OFF = 0; // 0x0
+    field public static final int LENS_OPTICAL_STABILIZATION_MODE_ON = 1; // 0x1
+    field public static final int LENS_STATE_MOVING = 1; // 0x1
+    field public static final int LENS_STATE_STATIONARY = 0; // 0x0
+    field public static final int NOISE_REDUCTION_MODE_FAST = 1; // 0x1
+    field public static final int NOISE_REDUCTION_MODE_HIGH_QUALITY = 2; // 0x2
+    field public static final int NOISE_REDUCTION_MODE_OFF = 0; // 0x0
+    field public static final int STATISTICS_FACE_DETECT_MODE_FULL = 2; // 0x2
+    field public static final int STATISTICS_FACE_DETECT_MODE_OFF = 0; // 0x0
+    field public static final int STATISTICS_FACE_DETECT_MODE_SIMPLE = 1; // 0x1
+    field public static final int STATISTICS_LENS_SHADING_MAP_MODE_OFF = 0; // 0x0
+    field public static final int STATISTICS_LENS_SHADING_MAP_MODE_ON = 1; // 0x1
+    field public static final int STATISTICS_SCENE_FLICKER_50HZ = 1; // 0x1
+    field public static final int STATISTICS_SCENE_FLICKER_60HZ = 2; // 0x2
+    field public static final int STATISTICS_SCENE_FLICKER_NONE = 0; // 0x0
+    field public static final int TONEMAP_MODE_CONTRAST_CURVE = 0; // 0x0
+    field public static final int TONEMAP_MODE_FAST = 1; // 0x1
+    field public static final int TONEMAP_MODE_HIGH_QUALITY = 2; // 0x2
+  }
+
+  public static class CameraMetadata.Key {
+    method public final boolean equals(java.lang.Object);
+    method public final java.lang.String getName();
+    method public final int hashCode();
+  }
+
+  public final class CameraProperties extends android.hardware.camera2.CameraMetadata {
+    method public T get(android.hardware.camera2.CameraMetadata.Key<T>);
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_AVAILABLE_ANTIBANDING_MODES;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_COMPENSATION_RANGE;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_COMPENSATION_STEP;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AF_AVAILABLE_MODES;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AVAILABLE_EFFECTS;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AVAILABLE_SCENE_MODES;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AWB_AVAILABLE_MODES;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_MAX_REGIONS;
+    field public static final android.hardware.camera2.CameraMetadata.Key FLASH_INFO_AVAILABLE;
+    field public static final android.hardware.camera2.CameraMetadata.Key INFO_SUPPORTED_HARDWARE_LEVEL;
+    field public static final android.hardware.camera2.CameraMetadata.Key JPEG_AVAILABLE_THUMBNAIL_SIZES;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_FACING;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_INFO_AVAILABLE_APERTURES;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_INFO_AVAILABLE_FILTER_DENSITIES;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_INFO_AVAILABLE_FOCAL_LENGTHS;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_INFO_HYPERFOCAL_DISTANCE;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_INFO_MINIMUM_FOCUS_DISTANCE;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_INFO_SHADING_MAP_SIZE;
+    field public static final android.hardware.camera2.CameraMetadata.Key REQUEST_MAX_NUM_OUTPUT_STREAMS;
+    field public static final android.hardware.camera2.CameraMetadata.Key SCALER_AVAILABLE_FORMATS;
+    field public static final android.hardware.camera2.CameraMetadata.Key SCALER_AVAILABLE_JPEG_MIN_DURATIONS;
+    field public static final android.hardware.camera2.CameraMetadata.Key SCALER_AVAILABLE_JPEG_SIZES;
+    field public static final android.hardware.camera2.CameraMetadata.Key SCALER_AVAILABLE_MAX_DIGITAL_ZOOM;
+    field public static final android.hardware.camera2.CameraMetadata.Key SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS;
+    field public static final android.hardware.camera2.CameraMetadata.Key SCALER_AVAILABLE_PROCESSED_SIZES;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_BASE_GAIN_FACTOR;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_INFO_ACTIVE_ARRAY_SIZE;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_INFO_EXPOSURE_TIME_RANGE;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_INFO_MAX_FRAME_DURATION;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_INFO_PHYSICAL_SIZE;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_INFO_SENSITIVITY_RANGE;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_MAX_ANALOG_SENSITIVITY;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_ORIENTATION;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_INFO_MAX_FACE_COUNT;
+    field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_MAX_CURVE_POINTS;
+  }
+
+  public final class CaptureRequest extends android.hardware.camera2.CameraMetadata implements android.os.Parcelable {
+    method public int describeContents();
+    method public T get(android.hardware.camera2.CameraMetadata.Key<T>);
+    method public java.lang.Object getTag();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.hardware.camera2.CameraMetadata.Key BLACK_LEVEL_LOCK;
+    field public static final android.hardware.camera2.CameraMetadata.Key COLOR_CORRECTION_GAINS;
+    field public static final android.hardware.camera2.CameraMetadata.Key COLOR_CORRECTION_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key COLOR_CORRECTION_TRANSFORM;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_ANTIBANDING_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_EXPOSURE_COMPENSATION;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_LOCK;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_PRECAPTURE_TRIGGER;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_REGIONS;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_TARGET_FPS_RANGE;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AF_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AF_REGIONS;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AF_TRIGGER;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AWB_LOCK;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AWB_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AWB_REGIONS;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_CAPTURE_INTENT;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_EFFECT_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_SCENE_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_VIDEO_STABILIZATION_MODE;
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final android.hardware.camera2.CameraMetadata.Key EDGE_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key FLASH_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key JPEG_GPS_COORDINATES;
+    field public static final android.hardware.camera2.CameraMetadata.Key JPEG_GPS_PROCESSING_METHOD;
+    field public static final android.hardware.camera2.CameraMetadata.Key JPEG_GPS_TIMESTAMP;
+    field public static final android.hardware.camera2.CameraMetadata.Key JPEG_ORIENTATION;
+    field public static final android.hardware.camera2.CameraMetadata.Key JPEG_QUALITY;
+    field public static final android.hardware.camera2.CameraMetadata.Key JPEG_THUMBNAIL_QUALITY;
+    field public static final android.hardware.camera2.CameraMetadata.Key JPEG_THUMBNAIL_SIZE;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_APERTURE;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_FILTER_DENSITY;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_FOCAL_LENGTH;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_FOCUS_DISTANCE;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_OPTICAL_STABILIZATION_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key NOISE_REDUCTION_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key SCALER_CROP_REGION;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_EXPOSURE_TIME;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_FRAME_DURATION;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_SENSITIVITY;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_FACE_DETECT_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_LENS_SHADING_MAP_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_CURVE_BLUE;
+    field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_CURVE_GREEN;
+    field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_CURVE_RED;
+    field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_MODE;
+  }
+
+  public static final class CaptureRequest.Builder {
+    method public void addTarget(android.view.Surface);
+    method public android.hardware.camera2.CaptureRequest build();
+    method public T get(android.hardware.camera2.CameraMetadata.Key<T>);
+    method public void removeTarget(android.view.Surface);
+    method public void set(android.hardware.camera2.CameraMetadata.Key<T>, T);
+    method public void setTag(java.lang.Object);
+  }
+
+  public final class CaptureResult extends android.hardware.camera2.CameraMetadata {
+    method public T get(android.hardware.camera2.CameraMetadata.Key<T>);
+    field public static final android.hardware.camera2.CameraMetadata.Key BLACK_LEVEL_LOCK;
+    field public static final android.hardware.camera2.CameraMetadata.Key COLOR_CORRECTION_GAINS;
+    field public static final android.hardware.camera2.CameraMetadata.Key COLOR_CORRECTION_TRANSFORM;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_REGIONS;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AE_STATE;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AF_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AF_REGIONS;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AF_STATE;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AWB_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AWB_REGIONS;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AWB_STATE;
+    field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key EDGE_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key FLASH_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key FLASH_STATE;
+    field public static final android.hardware.camera2.CameraMetadata.Key JPEG_GPS_COORDINATES;
+    field public static final android.hardware.camera2.CameraMetadata.Key JPEG_GPS_PROCESSING_METHOD;
+    field public static final android.hardware.camera2.CameraMetadata.Key JPEG_GPS_TIMESTAMP;
+    field public static final android.hardware.camera2.CameraMetadata.Key JPEG_ORIENTATION;
+    field public static final android.hardware.camera2.CameraMetadata.Key JPEG_QUALITY;
+    field public static final android.hardware.camera2.CameraMetadata.Key JPEG_THUMBNAIL_QUALITY;
+    field public static final android.hardware.camera2.CameraMetadata.Key JPEG_THUMBNAIL_SIZE;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_APERTURE;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_FILTER_DENSITY;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_FOCAL_LENGTH;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_FOCUS_DISTANCE;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_FOCUS_RANGE;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_OPTICAL_STABILIZATION_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key LENS_STATE;
+    field public static final android.hardware.camera2.CameraMetadata.Key NOISE_REDUCTION_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key REQUEST_FRAME_COUNT;
+    field public static final android.hardware.camera2.CameraMetadata.Key SCALER_CROP_REGION;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_EXPOSURE_TIME;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_FRAME_DURATION;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_SENSITIVITY;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_TEMPERATURE;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_TIMESTAMP;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_FACE_DETECT_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_FACE_IDS;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_FACE_LANDMARKS;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_FACE_RECTANGLES;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_FACE_SCORES;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_LENS_SHADING_MAP;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_PREDICTED_COLOR_GAINS;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_PREDICTED_COLOR_TRANSFORM;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_SCENE_FLICKER;
+    field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_CURVE_BLUE;
+    field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_CURVE_GREEN;
+    field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_CURVE_RED;
+    field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_MODE;
+  }
+
+  public static class CaptureResult.Face {
+    ctor public CaptureResult.Face();
+    method public android.graphics.Rect getBounds();
+    method public int getId();
+    method public android.graphics.Point getLeftEye();
+    method public android.graphics.Point getMouth();
+    method public android.graphics.Point getRightEye();
+    method public int getScore();
+  }
+
+  public final class Rational {
+    ctor public Rational(int, int);
+    method public int getDenominator();
+    method public int getNumerator();
+  }
+
+  public final class Size {
+    ctor public Size(int, int);
+    method public final int getHeight();
+    method public final int getWidth();
+  }
+
+}
+
 package android.hardware.display {
 
   public final class DisplayManager {
+    method public android.hardware.display.VirtualDisplay createVirtualDisplay(java.lang.String, int, int, int, android.view.Surface, int);
     method public android.view.Display getDisplay(int);
     method public android.view.Display[] getDisplays();
     method public android.view.Display[] getDisplays(java.lang.String);
     method public void registerDisplayListener(android.hardware.display.DisplayManager.DisplayListener, android.os.Handler);
     method public void unregisterDisplayListener(android.hardware.display.DisplayManager.DisplayListener);
     field public static final java.lang.String DISPLAY_CATEGORY_PRESENTATION = "android.hardware.display.category.PRESENTATION";
+    field public static final int VIRTUAL_DISPLAY_FLAG_PRESENTATION = 2; // 0x2
+    field public static final int VIRTUAL_DISPLAY_FLAG_PUBLIC = 1; // 0x1
+    field public static final int VIRTUAL_DISPLAY_FLAG_SECURE = 4; // 0x4
   }
 
   public static abstract interface DisplayManager.DisplayListener {
@@ -10447,6 +11191,11 @@
     method public abstract void onDisplayRemoved(int);
   }
 
+  public final class VirtualDisplay {
+    method public android.view.Display getDisplay();
+    method public void release();
+  }
+
 }
 
 package android.hardware.input {
@@ -11154,6 +11903,7 @@
     field public static final java.lang.String KEY_PROVIDER_ENABLED = "providerEnabled";
     field public static final java.lang.String KEY_PROXIMITY_ENTERING = "entering";
     field public static final java.lang.String KEY_STATUS_CHANGED = "status";
+    field public static final java.lang.String MODE_CHANGED_ACTION = "android.location.MODE_CHANGED";
     field public static final java.lang.String NETWORK_PROVIDER = "network";
     field public static final java.lang.String PASSIVE_PROVIDER = "passive";
     field public static final java.lang.String PROVIDERS_CHANGED_ACTION = "android.location.PROVIDERS_CHANGED";
@@ -11176,6 +11926,19 @@
     field public static final int TEMPORARILY_UNAVAILABLE = 1; // 0x1
   }
 
+  public abstract class SettingInjectorService extends android.app.Service {
+    ctor public SettingInjectorService(java.lang.String);
+    method public final android.os.IBinder onBind(android.content.Intent);
+    method protected abstract boolean onGetEnabled();
+    method protected abstract java.lang.String onGetSummary();
+    method public final void onStart(android.content.Intent, int);
+    method public final int onStartCommand(android.content.Intent, int, int);
+    field public static final java.lang.String ACTION_INJECTED_SETTING_CHANGED = "android.location.InjectedSettingChanged";
+    field public static final java.lang.String ACTION_SERVICE_INTENT = "android.location.SettingInjectorService";
+    field public static final java.lang.String ATTRIBUTES_NAME = "injected-location-setting";
+    field public static final java.lang.String META_DATA_NAME = "android.location.SettingInjectorService";
+  }
+
 }
 
 package android.media {
@@ -11287,6 +12050,7 @@
     field public static final int ADJUST_SAME = 0; // 0x0
     field public static final int AUDIOFOCUS_GAIN = 1; // 0x1
     field public static final int AUDIOFOCUS_GAIN_TRANSIENT = 2; // 0x2
+    field public static final int AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE = 4; // 0x4
     field public static final int AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK = 3; // 0x3
     field public static final int AUDIOFOCUS_LOSS = -1; // 0xffffffff
     field public static final int AUDIOFOCUS_LOSS_TRANSIENT = -2; // 0xfffffffe
@@ -11308,6 +12072,7 @@
     field public static final int FX_FOCUS_NAVIGATION_RIGHT = 4; // 0x4
     field public static final int FX_FOCUS_NAVIGATION_UP = 1; // 0x1
     field public static final int FX_KEYPRESS_DELETE = 7; // 0x7
+    field public static final int FX_KEYPRESS_INVALID = 9; // 0x9
     field public static final int FX_KEYPRESS_RETURN = 8; // 0x8
     field public static final int FX_KEYPRESS_SPACEBAR = 6; // 0x6
     field public static final int FX_KEYPRESS_STANDARD = 5; // 0x5
@@ -11395,6 +12160,12 @@
     method public abstract void onPeriodicNotification(android.media.AudioRecord);
   }
 
+  public final class AudioTimestamp {
+    ctor public AudioTimestamp();
+    field public long framePosition;
+    field public long nanoTime;
+  }
+
   public class AudioTrack {
     ctor public AudioTrack(int, int, int, int, int, int) throws java.lang.IllegalArgumentException;
     ctor public AudioTrack(int, int, int, int, int, int, int) throws java.lang.IllegalArgumentException;
@@ -11407,7 +12178,7 @@
     method public static float getMaxVolume();
     method public static int getMinBufferSize(int, int, int);
     method public static float getMinVolume();
-    method protected int getNativeFrameCount();
+    method protected deprecated int getNativeFrameCount();
     method public static int getNativeOutputSampleRate(int);
     method public int getNotificationMarkerPosition();
     method public int getPlayState();
@@ -11417,6 +12188,7 @@
     method public int getSampleRate();
     method public int getState();
     method public int getStreamType();
+    method public boolean getTimestamp(android.media.AudioTimestamp);
     method public void pause() throws java.lang.IllegalStateException;
     method public void play() throws java.lang.IllegalStateException;
     method public void release();
@@ -11429,7 +12201,7 @@
     method public void setPlaybackPositionUpdateListener(android.media.AudioTrack.OnPlaybackPositionUpdateListener, android.os.Handler);
     method public int setPlaybackRate(int);
     method public int setPositionNotificationPeriod(int);
-    method protected void setState(int);
+    method protected deprecated void setState(int);
     method public int setStereoVolume(float, float);
     method public void stop() throws java.lang.IllegalStateException;
     method public int write(byte[], int, int);
@@ -11562,6 +12334,38 @@
     field public static final int EULER_Z = 2; // 0x2
   }
 
+  public abstract interface Image implements java.lang.AutoCloseable {
+    method public abstract void close();
+    method public abstract int getFormat();
+    method public abstract int getHeight();
+    method public abstract android.media.Image.Plane[] getPlanes();
+    method public abstract long getTimestamp();
+    method public abstract int getWidth();
+  }
+
+  public static abstract interface Image.Plane {
+    method public abstract java.nio.ByteBuffer getBuffer();
+    method public abstract int getPixelStride();
+    method public abstract int getRowStride();
+  }
+
+  public final class ImageReader implements java.lang.AutoCloseable {
+    ctor public ImageReader(int, int, int, int);
+    method public void close();
+    method public int getHeight();
+    method public int getImageFormat();
+    method public int getMaxImages();
+    method public android.media.Image getNextImage();
+    method public android.view.Surface getSurface();
+    method public int getWidth();
+    method public void releaseImage(android.media.Image);
+    method public void setImageAvailableListener(android.media.ImageReader.OnImageAvailableListener, android.os.Handler);
+  }
+
+  public static abstract interface ImageReader.OnImageAvailableListener {
+    method public abstract void onImageAvailable(android.media.ImageReader);
+  }
+
   public class JetPlayer {
     method public boolean clearQueue();
     method public java.lang.Object clone() throws java.lang.CloneNotSupportedException;
@@ -11619,6 +12423,7 @@
     method public final void queueSecureInputBuffer(int, int, android.media.MediaCodec.CryptoInfo, long, int) throws android.media.MediaCodec.CryptoException;
     method public final void release();
     method public final void releaseOutputBuffer(int, boolean);
+    method public final void setParameters(java.util.Map<java.lang.String, java.lang.Object>);
     method public final void setVideoScalingMode(int);
     method public final void signalEndOfInputStream();
     method public final void start();
@@ -11632,6 +12437,9 @@
     field public static final int INFO_OUTPUT_BUFFERS_CHANGED = -3; // 0xfffffffd
     field public static final int INFO_OUTPUT_FORMAT_CHANGED = -2; // 0xfffffffe
     field public static final int INFO_TRY_AGAIN_LATER = -1; // 0xffffffff
+    field public static final java.lang.String PARAMETER_KEY_REQUEST_SYNC_FRAME = "request-sync";
+    field public static final java.lang.String PARAMETER_KEY_SUSPEND = "drop-input-frames";
+    field public static final java.lang.String PARAMETER_KEY_VIDEO_BITRATE = "videoBitrate";
     field public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT = 1; // 0x1
     field public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING = 2; // 0x2
   }
@@ -11648,6 +12456,9 @@
   public static final class MediaCodec.CryptoException extends java.lang.RuntimeException {
     ctor public MediaCodec.CryptoException(int, java.lang.String);
     method public int getErrorCode();
+    field public static final int ERROR_KEY_EXPIRED = 2; // 0x2
+    field public static final int ERROR_NO_KEY = 1; // 0x1
+    field public static final int ERROR_RESOURCE_BUSY = 3; // 0x3
   }
 
   public static final class MediaCodec.CryptoInfo {
@@ -11670,6 +12481,7 @@
 
   public static final class MediaCodecInfo.CodecCapabilities {
     ctor public MediaCodecInfo.CodecCapabilities();
+    method public final boolean isFeatureSupported(java.lang.String);
     field public static final int COLOR_Format12bitRGB444 = 3; // 0x3
     field public static final int COLOR_Format16bitARGB1555 = 5; // 0x5
     field public static final int COLOR_Format16bitARGB4444 = 4; // 0x4
@@ -11716,6 +12528,7 @@
     field public static final int COLOR_FormatYUV444Interleaved = 29; // 0x1d
     field public static final int COLOR_QCOM_FormatYUV420SemiPlanar = 2141391872; // 0x7fa30c00
     field public static final int COLOR_TI_FormatYUV420PackedSemiPlanar = 2130706688; // 0x7f000100
+    field public static final java.lang.String FEATURE_AdaptivePlayback = "adaptive-playback";
     field public int[] colorFormats;
     field public android.media.MediaCodecInfo.CodecProfileLevel[] profileLevels;
   }
@@ -11831,6 +12644,7 @@
     method public android.media.MediaDrm.ProvisionRequest getProvisionRequest();
     method public java.util.List<byte[]> getSecureStops();
     method public static final boolean isCryptoSchemeSupported(java.util.UUID);
+    method public static final boolean isCryptoSchemeSupported(java.util.UUID, java.lang.String);
     method public byte[] openSession() throws android.media.NotProvisionedException;
     method public byte[] provideKeyResponse(byte[], byte[]) throws android.media.DeniedByServerException, android.media.NotProvisionedException;
     method public void provideProvisionResponse(byte[]) throws android.media.DeniedByServerException;
@@ -11914,6 +12728,7 @@
     ctor public MediaFormat();
     method public final boolean containsKey(java.lang.String);
     method public static final android.media.MediaFormat createAudioFormat(java.lang.String, int, int);
+    method public static final android.media.MediaFormat createSubtitleFormat(java.lang.String, java.lang.String);
     method public static final android.media.MediaFormat createVideoFormat(java.lang.String, int, int);
     method public final java.nio.ByteBuffer getByteBuffer(java.lang.String);
     method public final float getFloat(java.lang.String);
@@ -11936,8 +12751,13 @@
     field public static final java.lang.String KEY_HEIGHT = "height";
     field public static final java.lang.String KEY_IS_ADTS = "is-adts";
     field public static final java.lang.String KEY_I_FRAME_INTERVAL = "i-frame-interval";
+    field public static final java.lang.String KEY_LANGUAGE = "language";
+    field public static final java.lang.String KEY_MAX_HEIGHT = "max-height";
     field public static final java.lang.String KEY_MAX_INPUT_SIZE = "max-input-size";
+    field public static final java.lang.String KEY_MAX_WIDTH = "max-width";
     field public static final java.lang.String KEY_MIME = "mime";
+    field public static final java.lang.String KEY_PUSH_BLANK_BUFFERS_ON_STOP = "push-blank-buffers-on-shutdown";
+    field public static final java.lang.String KEY_REPEAT_PREVIOUS_FRAME_AFTER = "repeat-previous-frame-after";
     field public static final java.lang.String KEY_SAMPLE_RATE = "sample-rate";
     field public static final java.lang.String KEY_WIDTH = "width";
   }
@@ -11988,6 +12808,7 @@
     ctor public MediaMuxer(java.lang.String, int) throws java.io.IOException;
     method public int addTrack(android.media.MediaFormat);
     method public void release();
+    method public void setLocation(float, float);
     method public void setOrientationHint(int);
     method public void start();
     method public void stop();
@@ -12062,7 +12883,9 @@
     field public static final int MEDIA_INFO_BUFFERING_START = 701; // 0x2bd
     field public static final int MEDIA_INFO_METADATA_UPDATE = 802; // 0x322
     field public static final int MEDIA_INFO_NOT_SEEKABLE = 801; // 0x321
+    field public static final int MEDIA_INFO_SUBTITLE_TIMED_OUT = 902; // 0x386
     field public static final int MEDIA_INFO_UNKNOWN = 1; // 0x1
+    field public static final int MEDIA_INFO_UNSUPPORTED_SUBTITLE = 901; // 0x385
     field public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3; // 0x3
     field public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700; // 0x2bc
     field public static final java.lang.String MEDIA_MIMETYPE_TEXT_SUBRIP = "application/x-subrip";
@@ -12104,6 +12927,7 @@
 
   public static class MediaPlayer.TrackInfo implements android.os.Parcelable {
     method public int describeContents();
+    method public android.media.MediaFormat getFormat();
     method public java.lang.String getLanguage();
     method public int getTrackType();
     method public void writeToParcel(android.os.Parcel, int);
@@ -12165,6 +12989,7 @@
     field public static final int CAMCORDER = 5; // 0x5
     field public static final int DEFAULT = 0; // 0x0
     field public static final int MIC = 1; // 0x1
+    field public static final int REMOTE_SUBMIX = 8; // 0x8
     field public static final int VOICE_CALL = 4; // 0x4
     field public static final int VOICE_COMMUNICATION = 7; // 0x7
     field public static final int VOICE_DOWNLINK = 3; // 0x3
@@ -12357,6 +13182,7 @@
     ctor public RemoteControlClient(android.app.PendingIntent);
     ctor public RemoteControlClient(android.app.PendingIntent, android.os.Looper);
     method public android.media.RemoteControlClient.MetadataEditor editMetadata(boolean);
+    method public void setMetadataUpdateListener(android.media.RemoteControlClient.OnMetadataUpdateListener);
     method public void setOnGetPlaybackPositionListener(android.media.RemoteControlClient.OnGetPlaybackPositionListener);
     method public void setPlaybackPositionUpdateListener(android.media.RemoteControlClient.OnPlaybackPositionUpdateListener);
     method public void setPlaybackState(int);
@@ -12369,6 +13195,7 @@
     field public static final int FLAG_KEY_MEDIA_PLAY_PAUSE = 8; // 0x8
     field public static final int FLAG_KEY_MEDIA_POSITION_UPDATE = 256; // 0x100
     field public static final int FLAG_KEY_MEDIA_PREVIOUS = 1; // 0x1
+    field public static final int FLAG_KEY_MEDIA_RATING = 512; // 0x200
     field public static final int FLAG_KEY_MEDIA_REWIND = 2; // 0x2
     field public static final int FLAG_KEY_MEDIA_STOP = 32; // 0x20
     field public static final int PLAYSTATE_BUFFERING = 8; // 0x8
@@ -12383,22 +13210,40 @@
   }
 
   public class RemoteControlClient.MetadataEditor {
+    method public synchronized void addEditableKey(int);
     method public synchronized void apply();
     method public synchronized void clear();
+    method public synchronized void clearEditableKeys();
     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 putString(int, java.lang.String) throws java.lang.IllegalArgumentException;
     field public static final int BITMAP_KEY_ARTWORK = 100; // 0x64
+    field public static final int LONG_KEY_RATING_BY_OTHERS = 102; // 0x66
+    field public static final int LONG_KEY_RATING_BY_USER = 268435457; // 0x10000001
+    field public static final int LONG_KEY_RATING_TYPE = 101; // 0x65
+    field public static final long RATING_HEART = -1L; // 0xffffffffffffffffL
+    field public static final long RATING_NOT_RATED = -101L; // 0xffffffffffffff9bL
+    field public static final long RATING_THUMB_UP_DOWN = -2L; // 0xfffffffffffffffeL
   }
 
   public static abstract interface RemoteControlClient.OnGetPlaybackPositionListener {
     method public abstract long onGetPlaybackPosition();
   }
 
+  public static abstract interface RemoteControlClient.OnMetadataUpdateListener {
+    method public abstract void onMetadataUpdateBitmap(int, android.graphics.Bitmap);
+    method public abstract void onMetadataUpdateLong(int, long);
+    method public abstract void onMetadataUpdateString(int, java.lang.String);
+  }
+
   public static abstract interface RemoteControlClient.OnPlaybackPositionUpdateListener {
     method public abstract void onPlaybackPositionUpdate(long);
   }
 
+  public final class ResourceBusyException extends android.media.MediaDrmException {
+    ctor public ResourceBusyException(java.lang.String);
+  }
+
   public class Ringtone {
     method public int getStreamType();
     method public java.lang.String getTitle(android.content.Context);
@@ -12415,7 +13260,7 @@
     method public android.database.Cursor getCursor();
     method public static int getDefaultType(android.net.Uri);
     method public static android.net.Uri getDefaultUri(int);
-    method public boolean getIncludeDrm();
+    method public deprecated boolean getIncludeDrm();
     method public android.media.Ringtone getRingtone(int);
     method public static android.media.Ringtone getRingtone(android.content.Context, android.net.Uri);
     method public int getRingtonePosition(android.net.Uri);
@@ -12425,14 +13270,14 @@
     method public int inferStreamType();
     method public static boolean isDefault(android.net.Uri);
     method public static void setActualDefaultRingtoneUri(android.content.Context, int, android.net.Uri);
-    method public void setIncludeDrm(boolean);
+    method public deprecated void setIncludeDrm(boolean);
     method public void setStopPreviousRingtone(boolean);
     method public void setType(int);
     method public void stopPreviousRingtone();
     field public static final java.lang.String ACTION_RINGTONE_PICKER = "android.intent.action.RINGTONE_PICKER";
     field public static final java.lang.String EXTRA_RINGTONE_DEFAULT_URI = "android.intent.extra.ringtone.DEFAULT_URI";
     field public static final java.lang.String EXTRA_RINGTONE_EXISTING_URI = "android.intent.extra.ringtone.EXISTING_URI";
-    field public static final java.lang.String EXTRA_RINGTONE_INCLUDE_DRM = "android.intent.extra.ringtone.INCLUDE_DRM";
+    field public static final deprecated java.lang.String EXTRA_RINGTONE_INCLUDE_DRM = "android.intent.extra.ringtone.INCLUDE_DRM";
     field public static final java.lang.String EXTRA_RINGTONE_PICKED_URI = "android.intent.extra.ringtone.PICKED_URI";
     field public static final java.lang.String EXTRA_RINGTONE_SHOW_DEFAULT = "android.intent.extra.ringtone.SHOW_DEFAULT";
     field public static final java.lang.String EXTRA_RINGTONE_SHOW_SILENT = "android.intent.extra.ringtone.SHOW_SILENT";
@@ -13129,6 +13974,7 @@
 
   public class LocalSocket implements java.io.Closeable {
     ctor public LocalSocket();
+    ctor public LocalSocket(int);
     method public void bind(android.net.LocalSocketAddress) throws java.io.IOException;
     method public void close() throws java.io.IOException;
     method public void connect(android.net.LocalSocketAddress) throws java.io.IOException;
@@ -13154,6 +14000,9 @@
     method public void setSoTimeout(int) throws java.io.IOException;
     method public void shutdownInput() throws java.io.IOException;
     method public void shutdownOutput() throws java.io.IOException;
+    field public static final int SOCKET_DGRAM = 1; // 0x1
+    field public static final int SOCKET_SEQPACKET = 3; // 0x3
+    field public static final int SOCKET_STREAM = 2; // 0x2
   }
 
   public class LocalSocketAddress {
@@ -14023,6 +14872,8 @@
     method public boolean reconnect();
     method public boolean removeNetwork(int);
     method public boolean saveConfiguration();
+    method public void setTdlsEnabled(java.net.InetAddress, boolean);
+    method public void setTdlsEnabledWithMacAddress(java.lang.String, boolean);
     method public boolean setWifiEnabled(boolean);
     method public boolean startScan();
     method public int updateNetwork(android.net.wifi.WifiConfiguration);
@@ -14339,8 +15190,10 @@
   public final class NfcAdapter {
     method public void disableForegroundDispatch(android.app.Activity);
     method public deprecated void disableForegroundNdefPush(android.app.Activity);
+    method public void disableReaderMode(android.app.Activity);
     method public void enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], java.lang.String[][]);
     method public deprecated void enableForegroundNdefPush(android.app.Activity, android.nfc.NdefMessage);
+    method public void enableReaderMode(android.app.Activity, android.nfc.NfcAdapter.ReaderCallback, int, android.os.Bundle);
     method public static android.nfc.NfcAdapter getDefaultAdapter(android.content.Context);
     method public boolean isEnabled();
     method public boolean isNdefPushEnabled();
@@ -14356,7 +15209,15 @@
     field public static final java.lang.String EXTRA_ADAPTER_STATE = "android.nfc.extra.ADAPTER_STATE";
     field public static final java.lang.String EXTRA_ID = "android.nfc.extra.ID";
     field public static final java.lang.String EXTRA_NDEF_MESSAGES = "android.nfc.extra.NDEF_MESSAGES";
+    field public static final java.lang.String EXTRA_READER_PRESENCE_CHECK_DELAY = "presence";
     field public static final java.lang.String EXTRA_TAG = "android.nfc.extra.TAG";
+    field public static final int FLAG_READER_KOVIO = 16; // 0x10
+    field public static final int FLAG_READER_NFC_A = 1; // 0x1
+    field public static final int FLAG_READER_NFC_B = 2; // 0x2
+    field public static final int FLAG_READER_NFC_F = 4; // 0x4
+    field public static final int FLAG_READER_NFC_V = 8; // 0x8
+    field public static final int FLAG_READER_NO_PLATFORM_SOUNDS = 256; // 0x100
+    field public static final int FLAG_READER_SKIP_NDEF_CHECK = 128; // 0x80
     field public static final int STATE_OFF = 1; // 0x1
     field public static final int STATE_ON = 3; // 0x3
     field public static final int STATE_TURNING_OFF = 4; // 0x4
@@ -14375,6 +15236,10 @@
     method public abstract void onNdefPushComplete(android.nfc.NfcEvent);
   }
 
+  public static abstract interface NfcAdapter.ReaderCallback {
+    method public abstract void onTagDiscovered(android.nfc.Tag);
+  }
+
   public final class NfcEvent {
     field public final android.nfc.NfcAdapter nfcAdapter;
   }
@@ -14398,6 +15263,45 @@
 
 }
 
+package android.nfc.cardemulation {
+
+  public final class CardEmulation {
+    method public static synchronized android.nfc.cardemulation.CardEmulation getInstance(android.nfc.NfcAdapter);
+    method public int getSelectionModeForCategory(java.lang.String);
+    method public boolean isDefaultServiceForAid(android.content.ComponentName, java.lang.String);
+    method public boolean isDefaultServiceForCategory(android.content.ComponentName, java.lang.String);
+    field public static final java.lang.String ACTION_CHANGE_DEFAULT = "android.nfc.cardemulation.action.ACTION_CHANGE_DEFAULT";
+    field public static final java.lang.String CATEGORY_OTHER = "other";
+    field public static final java.lang.String CATEGORY_PAYMENT = "payment";
+    field public static final java.lang.String EXTRA_CATEGORY = "category";
+    field public static final java.lang.String EXTRA_SERVICE_COMPONENT = "component";
+    field public static final int SELECTION_MODE_ALWAYS_ASK = 1; // 0x1
+    field public static final int SELECTION_MODE_ASK_IF_CONFLICT = 2; // 0x2
+    field public static final int SELECTION_MODE_PREFER_DEFAULT = 0; // 0x0
+  }
+
+  public abstract class HostApduService extends android.app.Service {
+    ctor public HostApduService();
+    method public final void notifyUnhandled();
+    method public final android.os.IBinder onBind(android.content.Intent);
+    method public abstract void onDeactivated(int);
+    method public abstract byte[] processCommandApdu(byte[], android.os.Bundle);
+    method public final void sendResponseApdu(byte[]);
+    field public static final int DEACTIVATION_DESELECTED = 1; // 0x1
+    field public static final int DEACTIVATION_LINK_LOSS = 0; // 0x0
+    field public static final java.lang.String SERVICE_INTERFACE = "android.nfc.cardemulation.action.HOST_APDU_SERVICE";
+    field public static final java.lang.String SERVICE_META_DATA = "android.nfc.cardemulation.host_apdu_service";
+  }
+
+  public abstract class OffHostApduService extends android.app.Service {
+    ctor public OffHostApduService();
+    method public abstract android.os.IBinder onBind(android.content.Intent);
+    field public static final java.lang.String SERVICE_INTERFACE = "android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE";
+    field public static final java.lang.String SERVICE_META_DATA = "android.nfc.cardemulation.off_host_apdu_service";
+  }
+
+}
+
 package android.nfc.tech {
 
    abstract class BasicTagTechnology implements android.nfc.tech.TagTechnology {
@@ -16613,7 +17517,7 @@
   }
 
   public class Matrix {
-    ctor public Matrix();
+    ctor public deprecated Matrix();
     method public static void frustumM(float[], int, float, float, float, float, float, float);
     method public static boolean invertM(float[], int, float[], int);
     method public static float length(float, float, float);
@@ -16787,6 +17691,7 @@
     field public static final int JELLY_BEAN = 16; // 0x10
     field public static final int JELLY_BEAN_MR1 = 17; // 0x11
     field public static final int JELLY_BEAN_MR2 = 18; // 0x12
+    field public static final int KITKAT = 10000; // 0x2710
   }
 
   public final class Bundle implements java.lang.Cloneable android.os.Parcelable {
@@ -16998,13 +17903,12 @@
   public static class Debug.MemoryInfo implements android.os.Parcelable {
     ctor public Debug.MemoryInfo();
     method public int describeContents();
-    method public static java.lang.String getOtherLabel(int);
-    method public int getOtherPrivateDirty(int);
-    method public int getOtherPss(int);
-    method public int getOtherSharedDirty(int);
+    method public int getTotalPrivateClean();
     method public int getTotalPrivateDirty();
     method public int getTotalPss();
+    method public int getTotalSharedClean();
     method public int getTotalSharedDirty();
+    method public int getTotalSwappablePss();
     method public void readFromParcel(android.os.Parcel);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
@@ -17059,10 +17963,12 @@
     method public static java.io.File getExternalStoragePublicDirectory(java.lang.String);
     method public static java.lang.String getExternalStorageState();
     method public static java.io.File getRootDirectory();
+    method public static java.lang.String getStorageState(java.io.File);
     method public static boolean isExternalStorageEmulated();
     method public static boolean isExternalStorageRemovable();
     field public static java.lang.String DIRECTORY_ALARMS;
     field public static java.lang.String DIRECTORY_DCIM;
+    field public static java.lang.String DIRECTORY_DOCUMENTS;
     field public static java.lang.String DIRECTORY_DOWNLOADS;
     field public static java.lang.String DIRECTORY_MOVIES;
     field public static java.lang.String DIRECTORY_MUSIC;
@@ -17077,6 +17983,7 @@
     field public static final java.lang.String MEDIA_NOFS = "nofs";
     field public static final java.lang.String MEDIA_REMOVED = "removed";
     field public static final java.lang.String MEDIA_SHARED = "shared";
+    field public static final java.lang.String MEDIA_UNKNOWN = "unknown";
     field public static final java.lang.String MEDIA_UNMOUNTABLE = "unmountable";
     field public static final java.lang.String MEDIA_UNMOUNTED = "unmounted";
   }
@@ -17373,8 +18280,14 @@
   public class ParcelFileDescriptor implements java.io.Closeable android.os.Parcelable {
     ctor public ParcelFileDescriptor(android.os.ParcelFileDescriptor);
     method public static android.os.ParcelFileDescriptor adoptFd(int);
+    method public boolean canDetectErrors();
+    method public void checkError(boolean) throws java.io.IOException;
     method public void close() throws java.io.IOException;
+    method public void closeWithError(java.lang.String) throws java.io.IOException;
     method public static android.os.ParcelFileDescriptor[] createPipe() throws java.io.IOException;
+    method public static android.os.ParcelFileDescriptor[] createReliablePipe() throws java.io.IOException;
+    method public static android.os.ParcelFileDescriptor[] createReliableSocketPair() throws java.io.IOException;
+    method public static android.os.ParcelFileDescriptor[] createSocketPair() throws java.io.IOException;
     method public int describeContents();
     method public int detachFd();
     method public static android.os.ParcelFileDescriptor dup(java.io.FileDescriptor) throws java.io.IOException;
@@ -17386,6 +18299,7 @@
     method public java.io.FileDescriptor getFileDescriptor();
     method public long getStatSize();
     method public static android.os.ParcelFileDescriptor open(java.io.File, int) throws java.io.FileNotFoundException;
+    method public static android.os.ParcelFileDescriptor open(java.io.File, int, android.os.Handler, android.os.ParcelFileDescriptor.OnCloseListener) throws java.io.IOException;
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
     field public static final int MODE_APPEND = 33554432; // 0x2000000
@@ -17393,8 +18307,8 @@
     field public static final int MODE_READ_ONLY = 268435456; // 0x10000000
     field public static final int MODE_READ_WRITE = 805306368; // 0x30000000
     field public static final int MODE_TRUNCATE = 67108864; // 0x4000000
-    field public static final int MODE_WORLD_READABLE = 1; // 0x1
-    field public static final int MODE_WORLD_WRITEABLE = 2; // 0x2
+    field public static final deprecated int MODE_WORLD_READABLE = 1; // 0x1
+    field public static final deprecated int MODE_WORLD_WRITEABLE = 2; // 0x2
     field public static final int MODE_WRITE_ONLY = 536870912; // 0x20000000
   }
 
@@ -17406,6 +18320,10 @@
     ctor public ParcelFileDescriptor.AutoCloseOutputStream(android.os.ParcelFileDescriptor);
   }
 
+  public static abstract interface ParcelFileDescriptor.OnCloseListener {
+    method public abstract void onClose(java.io.IOException, boolean);
+  }
+
   public class ParcelFormatException extends java.lang.RuntimeException {
     ctor public ParcelFormatException();
     ctor public ParcelFormatException(java.lang.String);
@@ -17672,6 +18590,7 @@
     method public boolean isUserAGoat();
     method public boolean isUserRunning(android.os.UserHandle);
     method public boolean isUserRunningOrStopping(android.os.UserHandle);
+    method public boolean setRestrictionsChallenge(java.lang.String);
     method public void setUserRestriction(java.lang.String, boolean);
     method public void setUserRestrictions(android.os.Bundle);
     method public void setUserRestrictions(android.os.Bundle, android.os.UserHandle);
@@ -17858,6 +18777,7 @@
     method protected android.view.View onCreateView(android.view.ViewGroup);
     method public void onDependencyChanged(android.preference.Preference, boolean);
     method protected java.lang.Object onGetDefaultValue(android.content.res.TypedArray, int);
+    method public void onParentChanged(android.preference.Preference, boolean);
     method protected void onPrepareForRemoval();
     method protected void onRestoreInstanceState(android.os.Parcelable);
     method protected android.os.Parcelable onSaveInstanceState();
@@ -17921,6 +18841,7 @@
     method public boolean hasHeaders();
     method public void invalidateHeaders();
     method public boolean isMultiPane();
+    method protected boolean isValidFragment(java.lang.String);
     method public void loadHeadersFromResource(int, java.util.List<android.preference.PreferenceActivity.Header>);
     method public void onBuildHeaders(java.util.List<android.preference.PreferenceActivity.Header>);
     method public android.content.Intent onBuildStartFragmentIntent(java.lang.String, android.os.Bundle, int, int);
@@ -18096,15 +19017,356 @@
 
 }
 
+package android.print {
+
+  public final class PageRange implements android.os.Parcelable {
+    ctor public PageRange(int, int);
+    method public int describeContents();
+    method public int getEnd();
+    method public int getStart();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.print.PageRange ALL_PAGES;
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
+  public final class PrintAttributes implements android.os.Parcelable {
+    method public void clear();
+    method public int describeContents();
+    method public int getColorMode();
+    method public android.print.PrintAttributes.MediaSize getMediaSize();
+    method public android.print.PrintAttributes.Margins getMinMargins();
+    method public android.print.PrintAttributes.Resolution getResolution();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int COLOR_MODE_COLOR = 2; // 0x2
+    field public static final int COLOR_MODE_MONOCHROME = 1; // 0x1
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
+  public static final class PrintAttributes.Builder {
+    ctor public PrintAttributes.Builder();
+    method public android.print.PrintAttributes build();
+    method public android.print.PrintAttributes.Builder setColorMode(int);
+    method public android.print.PrintAttributes.Builder setMediaSize(android.print.PrintAttributes.MediaSize);
+    method public android.print.PrintAttributes.Builder setMinMargins(android.print.PrintAttributes.Margins);
+    method public android.print.PrintAttributes.Builder setResolution(android.print.PrintAttributes.Resolution);
+  }
+
+  public static final class PrintAttributes.Margins {
+    ctor public PrintAttributes.Margins(int, int, int, int);
+    method public int getBottomMils();
+    method public int getLeftMils();
+    method public int getRightMils();
+    method public int getTopMils();
+    field public static final android.print.PrintAttributes.Margins NO_MARGINS;
+  }
+
+  public static final class PrintAttributes.MediaSize {
+    ctor public PrintAttributes.MediaSize(java.lang.String, java.lang.String, int, int);
+    method public android.print.PrintAttributes.MediaSize asLandscape();
+    method public android.print.PrintAttributes.MediaSize asPortrait();
+    method public int getHeightMils();
+    method public java.lang.String getId();
+    method public java.lang.String getLabel(android.content.pm.PackageManager);
+    method public int getWidthMils();
+    method public boolean isPortrait();
+    field public static final android.print.PrintAttributes.MediaSize ISO_A0;
+    field public static final android.print.PrintAttributes.MediaSize ISO_A1;
+    field public static final android.print.PrintAttributes.MediaSize ISO_A10;
+    field public static final android.print.PrintAttributes.MediaSize ISO_A2;
+    field public static final android.print.PrintAttributes.MediaSize ISO_A3;
+    field public static final android.print.PrintAttributes.MediaSize ISO_A4;
+    field public static final android.print.PrintAttributes.MediaSize ISO_A5;
+    field public static final android.print.PrintAttributes.MediaSize ISO_A6;
+    field public static final android.print.PrintAttributes.MediaSize ISO_A7;
+    field public static final android.print.PrintAttributes.MediaSize ISO_A8;
+    field public static final android.print.PrintAttributes.MediaSize ISO_A9;
+    field public static final android.print.PrintAttributes.MediaSize ISO_B0;
+    field public static final android.print.PrintAttributes.MediaSize ISO_B1;
+    field public static final android.print.PrintAttributes.MediaSize ISO_B10;
+    field public static final android.print.PrintAttributes.MediaSize ISO_B2;
+    field public static final android.print.PrintAttributes.MediaSize ISO_B3;
+    field public static final android.print.PrintAttributes.MediaSize ISO_B4;
+    field public static final android.print.PrintAttributes.MediaSize ISO_B5;
+    field public static final android.print.PrintAttributes.MediaSize ISO_B6;
+    field public static final android.print.PrintAttributes.MediaSize ISO_B7;
+    field public static final android.print.PrintAttributes.MediaSize ISO_B8;
+    field public static final android.print.PrintAttributes.MediaSize ISO_B9;
+    field public static final android.print.PrintAttributes.MediaSize ISO_C0;
+    field public static final android.print.PrintAttributes.MediaSize ISO_C1;
+    field public static final android.print.PrintAttributes.MediaSize ISO_C10;
+    field public static final android.print.PrintAttributes.MediaSize ISO_C2;
+    field public static final android.print.PrintAttributes.MediaSize ISO_C3;
+    field public static final android.print.PrintAttributes.MediaSize ISO_C4;
+    field public static final android.print.PrintAttributes.MediaSize ISO_C5;
+    field public static final android.print.PrintAttributes.MediaSize ISO_C6;
+    field public static final android.print.PrintAttributes.MediaSize ISO_C7;
+    field public static final android.print.PrintAttributes.MediaSize ISO_C8;
+    field public static final android.print.PrintAttributes.MediaSize ISO_C9;
+    field public static final android.print.PrintAttributes.MediaSize NA_GOVT_LETTER;
+    field public static final android.print.PrintAttributes.MediaSize NA_JUNIOR_LEGAL;
+    field public static final android.print.PrintAttributes.MediaSize NA_LEDGER;
+    field public static final android.print.PrintAttributes.MediaSize NA_LEGAL;
+    field public static final android.print.PrintAttributes.MediaSize NA_LETTER;
+    field public static final android.print.PrintAttributes.MediaSize NA_TBLOID;
+  }
+
+  public static final class PrintAttributes.Resolution {
+    ctor public PrintAttributes.Resolution(java.lang.String, java.lang.String, int, int);
+    method public int getHorizontalDpi();
+    method public java.lang.String getId();
+    method public java.lang.String getLabel();
+    method public int getVerticalDpi();
+  }
+
+  public abstract class PrintDocumentAdapter {
+    ctor public PrintDocumentAdapter();
+    method public void onFinish();
+    method public abstract void onLayout(android.print.PrintAttributes, android.print.PrintAttributes, android.os.CancellationSignal, android.print.PrintDocumentAdapter.LayoutResultCallback, android.os.Bundle);
+    method public void onStart();
+    method public abstract void onWrite(android.print.PageRange[], android.os.ParcelFileDescriptor, android.os.CancellationSignal, android.print.PrintDocumentAdapter.WriteResultCallback);
+    field public static final java.lang.String METADATA_KEY_PRINT_PREVIEW = "KEY_METADATA_PRINT_PREVIEW";
+  }
+
+  public static abstract class PrintDocumentAdapter.LayoutResultCallback {
+    method public void onLayoutCancelled();
+    method public void onLayoutFailed(java.lang.CharSequence);
+    method public void onLayoutFinished(android.print.PrintDocumentInfo, boolean);
+  }
+
+  public static abstract class PrintDocumentAdapter.WriteResultCallback {
+    method public void onWriteCancelled();
+    method public void onWriteFailed(java.lang.CharSequence);
+    method public void onWriteFinished(android.print.PageRange[]);
+  }
+
+  public final class PrintDocumentInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getContentType();
+    method public long getDataSize();
+    method public java.lang.String getName();
+    method public int getPageCount();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int CONTENT_TYPE_DOCUMENT = 0; // 0x0
+    field public static final int CONTENT_TYPE_PHOTO = 1; // 0x1
+    field public static final int CONTENT_TYPE_UNKNOWN = -1; // 0xffffffff
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final int PAGE_COUNT_UNKNOWN = -1; // 0xffffffff
+  }
+
+  public static final class PrintDocumentInfo.Builder {
+    ctor public PrintDocumentInfo.Builder(java.lang.String);
+    method public android.print.PrintDocumentInfo build();
+    method public android.print.PrintDocumentInfo.Builder setContentType(int);
+    method public android.print.PrintDocumentInfo.Builder setPageCount(int);
+  }
+
+  public class PrintFileDocumentAdapter extends android.print.PrintDocumentAdapter {
+    ctor public PrintFileDocumentAdapter(android.content.Context, java.io.File, android.print.PrintDocumentInfo);
+    method public void onLayout(android.print.PrintAttributes, android.print.PrintAttributes, android.os.CancellationSignal, android.print.PrintDocumentAdapter.LayoutResultCallback, android.os.Bundle);
+    method public void onWrite(android.print.PageRange[], android.os.ParcelFileDescriptor, android.os.CancellationSignal, android.print.PrintDocumentAdapter.WriteResultCallback);
+  }
+
+  public final class PrintJob {
+    method public void cancel();
+    method public int getId();
+    method public android.print.PrintJobInfo getInfo();
+  }
+
+  public final class PrintJobInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public android.print.PrintAttributes getAttributes();
+    method public int getCopies();
+    method public int getId();
+    method public java.lang.String getLabel();
+    method public android.print.PageRange[] getPages();
+    method public android.print.PrinterId getPrinterId();
+    method public int getState();
+    method public java.lang.String getTag();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final int PRINT_JOB_ID_UNDEFINED = -1; // 0xffffffff
+    field public static final int STATE_BLOCKED = 4; // 0x4
+    field public static final int STATE_CANCELED = 7; // 0x7
+    field public static final int STATE_COMPLETED = 5; // 0x5
+    field public static final int STATE_FAILED = 6; // 0x6
+    field public static final int STATE_QUEUED = 2; // 0x2
+    field public static final int STATE_STARTED = 3; // 0x3
+  }
+
+  public final class PrintManager {
+    method public java.util.List<android.print.PrintJob> getPrintJobs();
+    method public android.print.PrintJob print(java.lang.String, java.io.File, android.print.PrintDocumentInfo, android.print.PrintAttributes);
+    method public android.print.PrintJob print(java.lang.String, android.print.PrintDocumentAdapter, android.print.PrintAttributes);
+  }
+
+  public final class PrinterCapabilitiesInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getColorModes();
+    method public android.print.PrintAttributes getDefaults();
+    method public java.util.List<android.print.PrintAttributes.MediaSize> getMediaSizes();
+    method public android.print.PrintAttributes.Margins getMinMargins();
+    method public java.util.List<android.print.PrintAttributes.Resolution> getResolutions();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
+  public static final class PrinterCapabilitiesInfo.Builder {
+    ctor public PrinterCapabilitiesInfo.Builder(android.print.PrinterId);
+    method public android.print.PrinterCapabilitiesInfo.Builder addMediaSize(android.print.PrintAttributes.MediaSize, boolean);
+    method public android.print.PrinterCapabilitiesInfo.Builder addResolution(android.print.PrintAttributes.Resolution, boolean);
+    method public android.print.PrinterCapabilitiesInfo build();
+    method public android.print.PrinterCapabilitiesInfo.Builder setColorModes(int, int);
+    method public android.print.PrinterCapabilitiesInfo.Builder setMinMargins(android.print.PrintAttributes.Margins);
+  }
+
+  public final class PrinterId implements android.os.Parcelable {
+    method public int describeContents();
+    method public java.lang.String getLocalId();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
+  public final class PrinterInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public android.print.PrinterCapabilitiesInfo getCapabilities();
+    method public java.lang.String getDescription();
+    method public android.print.PrinterId getId();
+    method public java.lang.String getName();
+    method public int getStatus();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final int STATUS_BUSY = 2; // 0x2
+    field public static final int STATUS_IDLE = 1; // 0x1
+    field public static final int STATUS_UNAVAILABLE = 3; // 0x3
+  }
+
+  public static final class PrinterInfo.Builder {
+    ctor public PrinterInfo.Builder(android.print.PrinterId, java.lang.String, int);
+    ctor public PrinterInfo.Builder(android.print.PrinterInfo);
+    method public android.print.PrinterInfo build();
+    method public android.print.PrinterInfo.Builder setCapabilities(android.print.PrinterCapabilitiesInfo);
+    method public android.print.PrinterInfo.Builder setDescription(java.lang.String);
+    method public android.print.PrinterInfo.Builder setName(java.lang.String);
+    method public android.print.PrinterInfo.Builder setStatus(int);
+  }
+
+}
+
+package android.print.pdf {
+
+  public final class PdfDocument {
+    method public void close();
+    method public void finishPage(android.print.pdf.PdfDocument.Page);
+    method public java.util.List<android.print.pdf.PdfDocument.PageInfo> getPages();
+    method public static android.print.pdf.PdfDocument open();
+    method public android.print.pdf.PdfDocument.Page startPage(android.print.pdf.PdfDocument.PageInfo);
+    method public void writeTo(java.io.OutputStream);
+  }
+
+  public static final class PdfDocument.Page {
+    method public android.graphics.Canvas getCanvas();
+    method public android.print.pdf.PdfDocument.PageInfo getInfo();
+  }
+
+  public static final class PdfDocument.PageInfo {
+    method public android.graphics.Rect getContentSize();
+    method public android.graphics.Matrix getInitialTransform();
+    method public int getPageNumber();
+    method public android.graphics.Rect getPageSize();
+  }
+
+  public static final class PdfDocument.PageInfo.Builder {
+    ctor public PdfDocument.PageInfo.Builder(android.graphics.Rect, int);
+    method public android.print.pdf.PdfDocument.PageInfo create();
+    method public android.print.pdf.PdfDocument.PageInfo.Builder setContentSize(android.graphics.Rect);
+    method public android.print.pdf.PdfDocument.PageInfo.Builder setInitialTransform(android.graphics.Matrix);
+  }
+
+  public final class PrintedPdfDocument {
+    method public void close();
+    method public void finishPage(android.print.pdf.PdfDocument.Page);
+    method public java.util.List<android.print.pdf.PdfDocument.PageInfo> getPages();
+    method public static android.print.pdf.PrintedPdfDocument open(android.content.Context, android.print.PrintAttributes);
+    method public android.print.pdf.PdfDocument.Page startPage(int);
+    method public void writeTo(java.io.OutputStream);
+  }
+
+}
+
+package android.printservice {
+
+  public final class PrintDocument {
+    method public android.os.ParcelFileDescriptor getData();
+    method public android.print.PrintDocumentInfo getInfo();
+  }
+
+  public final class PrintJob {
+    method public boolean block(java.lang.String);
+    method public boolean cancel();
+    method public boolean complete();
+    method public boolean fail(java.lang.String);
+    method public android.printservice.PrintDocument getDocument();
+    method public int getId();
+    method public android.print.PrintJobInfo getInfo();
+    method public boolean isBlocked();
+    method public boolean isCancelled();
+    method public boolean isCompleted();
+    method public boolean isFailed();
+    method public boolean isQueued();
+    method public boolean isStarted();
+    method public boolean setTag(java.lang.String);
+    method public boolean start();
+  }
+
+  public abstract class PrintService extends android.app.Service {
+    ctor public PrintService();
+    method protected final void attachBaseContext(android.content.Context);
+    method public final android.print.PrinterId generatePrinterId(java.lang.String);
+    method public final java.util.List<android.printservice.PrintJob> getActivePrintJobs();
+    method public final android.os.IBinder onBind(android.content.Intent);
+    method protected void onConnected();
+    method protected abstract android.printservice.PrinterDiscoverySession onCreatePrinterDiscoverySession();
+    method protected void onDisconnected();
+    method protected abstract void onPrintJobQueued(android.printservice.PrintJob);
+    method protected abstract void onRequestCancelPrintJob(android.printservice.PrintJob);
+    field public static final java.lang.String SERVICE_INTERFACE = "android.printservice.PrintService";
+    field public static final java.lang.String SERVICE_META_DATA = "android.printservice";
+  }
+
+  public abstract class PrinterDiscoverySession {
+    ctor public PrinterDiscoverySession();
+    method public final void addPrinters(java.util.List<android.print.PrinterInfo>);
+    method public final java.util.List<android.print.PrinterInfo> getPrinters();
+    method public final java.util.List<android.print.PrinterId> getTrackedPrinters();
+    method public final boolean isDestroyed();
+    method public final boolean isPrinterDiscoveryStarted();
+    method public abstract void onDestroy();
+    method public abstract void onStartPrinterDiscovery(java.util.List<android.print.PrinterId>);
+    method public abstract void onStartPrinterStateTracking(android.print.PrinterId);
+    method public abstract void onStopPrinterDiscovery();
+    method public abstract void onStopPrinterStateTracking(android.print.PrinterId);
+    method public abstract void onValidatePrinters(java.util.List<android.print.PrinterId>);
+    method public final void removePrinters(java.util.List<android.print.PrinterId>);
+  }
+
+}
+
 package android.provider {
 
   public final class AlarmClock {
     ctor public AlarmClock();
     field public static final java.lang.String ACTION_SET_ALARM = "android.intent.action.SET_ALARM";
+    field public static final java.lang.String ACTION_SET_TIMER = "android.intent.action.SET_TIMER";
+    field public static final java.lang.String ACTION_SHOW_ALARMS = "android.intent.action.SHOW_ALARMS";
+    field public static final java.lang.String EXTRA_DAYS = "android.intent.extra.alarm.DAYS";
     field public static final java.lang.String EXTRA_HOUR = "android.intent.extra.alarm.HOUR";
+    field public static final java.lang.String EXTRA_LENGTH = "android.intent.extra.alarm.LENGTH";
     field public static final java.lang.String EXTRA_MESSAGE = "android.intent.extra.alarm.MESSAGE";
     field public static final java.lang.String EXTRA_MINUTES = "android.intent.extra.alarm.MINUTES";
+    field public static final java.lang.String EXTRA_RINGTONE = "android.intent.extra.alarm.RINGTONE";
     field public static final java.lang.String EXTRA_SKIP_UI = "android.intent.extra.alarm.SKIP_UI";
+    field public static final java.lang.String EXTRA_VIBRATE = "android.intent.extra.alarm.VIBRATE";
+    field public static final java.lang.String VALUE_RINGTONE_SILENT = "silent";
   }
 
   public abstract interface BaseColumns {
@@ -18474,8 +19736,13 @@
     field public static final int MISSED_TYPE = 3; // 0x3
     field public static final java.lang.String NEW = "new";
     field public static final java.lang.String NUMBER = "number";
+    field public static final java.lang.String NUMBER_PRESENTATION = "presentation";
     field public static final java.lang.String OFFSET_PARAM_KEY = "offset";
     field public static final int OUTGOING_TYPE = 2; // 0x2
+    field public static final int PRESENTATION_ALLOWED = 1; // 0x1
+    field public static final int PRESENTATION_PAYPHONE = 4; // 0x4
+    field public static final int PRESENTATION_RESTRICTED = 2; // 0x2
+    field public static final int PRESENTATION_UNKNOWN = 3; // 0x3
     field public static final java.lang.String TYPE = "type";
   }
 
@@ -19512,6 +20779,87 @@
     field public static final android.net.Uri CONTENT_URI;
   }
 
+  public final class DocumentsContract {
+    method public static android.net.Uri buildChildDocumentsUri(java.lang.String, java.lang.String);
+    method public static android.net.Uri buildDocumentUri(java.lang.String, java.lang.String);
+    method public static android.net.Uri buildRecentDocumentsUri(java.lang.String, java.lang.String);
+    method public static android.net.Uri buildRootUri(java.lang.String, java.lang.String);
+    method public static android.net.Uri buildRootsUri(java.lang.String);
+    method public static android.net.Uri buildSearchDocumentsUri(java.lang.String, java.lang.String, java.lang.String);
+    method public static boolean deleteDocument(android.content.ContentResolver, android.net.Uri);
+    method public static java.lang.String getDocumentId(android.net.Uri);
+    method public static android.graphics.Bitmap getDocumentThumbnail(android.content.ContentResolver, android.net.Uri, android.graphics.Point, android.os.CancellationSignal);
+    method public static android.net.Uri[] getOpenDocuments(android.content.Context);
+    method public static java.lang.String getRootId(android.net.Uri);
+    method public static java.lang.String getSearchDocumentsQuery(android.net.Uri);
+    field public static final java.lang.String EXTRA_ERROR = "error";
+    field public static final java.lang.String EXTRA_INFO = "info";
+    field public static final java.lang.String EXTRA_LOADING = "loading";
+  }
+
+  public static final class DocumentsContract.Document {
+    field public static final java.lang.String COLUMN_DISPLAY_NAME = "_display_name";
+    field public static final java.lang.String COLUMN_DOCUMENT_ID = "document_id";
+    field public static final java.lang.String COLUMN_FLAGS = "flags";
+    field public static final java.lang.String COLUMN_ICON = "icon";
+    field public static final java.lang.String COLUMN_LAST_MODIFIED = "last_modified";
+    field public static final java.lang.String COLUMN_MIME_TYPE = "mime_type";
+    field public static final java.lang.String COLUMN_SIZE = "_size";
+    field public static final java.lang.String COLUMN_SUMMARY = "summary";
+    field public static final int FLAG_DIR_HIDE_GRID_TITLES = 64; // 0x40
+    field public static final int FLAG_DIR_PREFERS_GRID = 16; // 0x10
+    field public static final int FLAG_DIR_PREFERS_LAST_MODIFIED = 32; // 0x20
+    field public static final int FLAG_DIR_SUPPORTS_CREATE = 8; // 0x8
+    field public static final int FLAG_SUPPORTS_DELETE = 4; // 0x4
+    field public static final int FLAG_SUPPORTS_THUMBNAIL = 1; // 0x1
+    field public static final int FLAG_SUPPORTS_WRITE = 2; // 0x2
+    field public static final java.lang.String MIME_TYPE_DIR = "vnd.android.document/directory";
+  }
+
+  public static final class DocumentsContract.Root {
+    field public static final java.lang.String COLUMN_AVAILABLE_BYTES = "available_bytes";
+    field public static final java.lang.String COLUMN_DOCUMENT_ID = "document_id";
+    field public static final java.lang.String COLUMN_FLAGS = "flags";
+    field public static final java.lang.String COLUMN_ICON = "icon";
+    field public static final java.lang.String COLUMN_MIME_TYPES = "mime_types";
+    field public static final java.lang.String COLUMN_ROOT_ID = "root_id";
+    field public static final java.lang.String COLUMN_ROOT_TYPE = "root_type";
+    field public static final java.lang.String COLUMN_SUMMARY = "summary";
+    field public static final java.lang.String COLUMN_TITLE = "title";
+    field public static final int FLAG_ADVANCED = 4; // 0x4
+    field public static final int FLAG_EMPTY = 32; // 0x20
+    field public static final int FLAG_LOCAL_ONLY = 2; // 0x2
+    field public static final int FLAG_SUPPORTS_CREATE = 1; // 0x1
+    field public static final int FLAG_SUPPORTS_RECENTS = 8; // 0x8
+    field public static final int FLAG_SUPPORTS_SEARCH = 16; // 0x10
+    field public static final int ROOT_TYPE_DEVICE = 3; // 0x3
+    field public static final int ROOT_TYPE_SERVICE = 1; // 0x1
+    field public static final int ROOT_TYPE_SHORTCUT = 2; // 0x2
+  }
+
+  public abstract class DocumentsProvider extends android.content.ContentProvider {
+    ctor public DocumentsProvider();
+    method public java.lang.String createDocument(java.lang.String, java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
+    method public final int delete(android.net.Uri, java.lang.String, java.lang.String[]);
+    method public void deleteDocument(java.lang.String) throws java.io.FileNotFoundException;
+    method public java.lang.String getDocumentType(java.lang.String) throws java.io.FileNotFoundException;
+    method public final java.lang.String getType(android.net.Uri);
+    method public final android.net.Uri insert(android.net.Uri, android.content.ContentValues);
+    method public abstract android.os.ParcelFileDescriptor openDocument(java.lang.String, java.lang.String, android.os.CancellationSignal) throws java.io.FileNotFoundException;
+    method public android.content.res.AssetFileDescriptor openDocumentThumbnail(java.lang.String, android.graphics.Point, android.os.CancellationSignal) throws java.io.FileNotFoundException;
+    method public final android.os.ParcelFileDescriptor openFile(android.net.Uri, java.lang.String) throws java.io.FileNotFoundException;
+    method public final android.os.ParcelFileDescriptor openFile(android.net.Uri, java.lang.String, android.os.CancellationSignal) throws java.io.FileNotFoundException;
+    method public final android.content.res.AssetFileDescriptor openTypedAssetFile(android.net.Uri, java.lang.String, android.os.Bundle) throws java.io.FileNotFoundException;
+    method public final android.content.res.AssetFileDescriptor openTypedAssetFile(android.net.Uri, java.lang.String, android.os.Bundle, android.os.CancellationSignal) throws java.io.FileNotFoundException;
+    method public final android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
+    method public abstract android.database.Cursor queryChildDocuments(java.lang.String, java.lang.String[], java.lang.String) throws java.io.FileNotFoundException;
+    method public abstract android.database.Cursor queryDocument(java.lang.String, java.lang.String[]) throws java.io.FileNotFoundException;
+    method public android.database.Cursor queryRecentDocuments(java.lang.String, java.lang.String[]) throws java.io.FileNotFoundException;
+    method public abstract android.database.Cursor queryRoots(java.lang.String[]) throws java.io.FileNotFoundException;
+    method public android.database.Cursor querySearchDocuments(java.lang.String, java.lang.String, java.lang.String[]) throws java.io.FileNotFoundException;
+    method public final int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
+  }
+
   public final deprecated class LiveFolders implements android.provider.BaseColumns {
     field public static final java.lang.String ACTION_CREATE_LIVE_FOLDER = "android.intent.action.CREATE_LIVE_FOLDER";
     field public static final java.lang.String DESCRIPTION = "description";
@@ -19863,6 +21211,7 @@
     field public static final java.lang.String ACTION_APPLICATION_DEVELOPMENT_SETTINGS = "android.settings.APPLICATION_DEVELOPMENT_SETTINGS";
     field public static final java.lang.String ACTION_APPLICATION_SETTINGS = "android.settings.APPLICATION_SETTINGS";
     field public static final java.lang.String ACTION_BLUETOOTH_SETTINGS = "android.settings.BLUETOOTH_SETTINGS";
+    field public static final java.lang.String ACTION_CAPTIONING_SETTINGS = "android.settings.CAPTIONING_SETTINGS";
     field public static final java.lang.String ACTION_DATA_ROAMING_SETTINGS = "android.settings.DATA_ROAMING_SETTINGS";
     field public static final java.lang.String ACTION_DATE_SETTINGS = "android.settings.DATE_SETTINGS";
     field public static final java.lang.String ACTION_DEVICE_INFO_SETTINGS = "android.settings.DEVICE_INFO_SETTINGS";
@@ -19878,7 +21227,9 @@
     field public static final java.lang.String ACTION_MEMORY_CARD_SETTINGS = "android.settings.MEMORY_CARD_SETTINGS";
     field public static final java.lang.String ACTION_NETWORK_OPERATOR_SETTINGS = "android.settings.NETWORK_OPERATOR_SETTINGS";
     field public static final java.lang.String ACTION_NFCSHARING_SETTINGS = "android.settings.NFCSHARING_SETTINGS";
+    field public static final java.lang.String ACTION_NFC_PAYMENT_SETTINGS = "android.settings.NFC_PAYMENT_SETTINGS";
     field public static final java.lang.String ACTION_NFC_SETTINGS = "android.settings.NFC_SETTINGS";
+    field public static final java.lang.String ACTION_PRINT_SETTINGS = "android.settings.ACTION_PRINT_SETTINGS";
     field public static final java.lang.String ACTION_PRIVACY_SETTINGS = "android.settings.PRIVACY_SETTINGS";
     field public static final java.lang.String ACTION_QUICK_LAUNCH_SETTINGS = "android.settings.QUICK_LAUNCH_SETTINGS";
     field public static final java.lang.String ACTION_SEARCH_SETTINGS = "android.search.action.SEARCH_SETTINGS";
@@ -19970,12 +21321,12 @@
     method public static long getLong(android.content.ContentResolver, java.lang.String) throws android.provider.Settings.SettingNotFoundException;
     method public static java.lang.String getString(android.content.ContentResolver, java.lang.String);
     method public static android.net.Uri getUriFor(java.lang.String);
-    method public static final boolean isLocationProviderEnabled(android.content.ContentResolver, java.lang.String);
+    method public static final deprecated boolean isLocationProviderEnabled(android.content.ContentResolver, java.lang.String);
     method public static boolean putFloat(android.content.ContentResolver, java.lang.String, float);
     method public static boolean putInt(android.content.ContentResolver, java.lang.String, int);
     method public static boolean putLong(android.content.ContentResolver, java.lang.String, long);
     method public static boolean putString(android.content.ContentResolver, java.lang.String, java.lang.String);
-    method public static final void setLocationProviderEnabled(android.content.ContentResolver, java.lang.String, boolean);
+    method public static final deprecated void setLocationProviderEnabled(android.content.ContentResolver, java.lang.String, boolean);
     field public static final java.lang.String ACCESSIBILITY_ENABLED = "accessibility_enabled";
     field public static final java.lang.String ACCESSIBILITY_SPEAK_PASSWORD = "speak_password";
     field public static final deprecated java.lang.String ADB_ENABLED = "adb_enabled";
@@ -19994,7 +21345,12 @@
     field public static final deprecated java.lang.String HTTP_PROXY = "http_proxy";
     field public static final java.lang.String INPUT_METHOD_SELECTOR_VISIBILITY = "input_method_selector_visibility";
     field public static final deprecated java.lang.String INSTALL_NON_MARKET_APPS = "install_non_market_apps";
-    field public static final java.lang.String LOCATION_PROVIDERS_ALLOWED = "location_providers_allowed";
+    field public static final java.lang.String LOCATION_MODE = "location_mode";
+    field public static final int LOCATION_MODE_BATTERY_SAVING = 2; // 0x2
+    field public static final int LOCATION_MODE_HIGH_ACCURACY = 3; // 0x3
+    field public static final int LOCATION_MODE_OFF = 0; // 0x0
+    field public static final int LOCATION_MODE_SENSORS_ONLY = 1; // 0x1
+    field public static final deprecated java.lang.String LOCATION_PROVIDERS_ALLOWED = "location_providers_allowed";
     field public static final java.lang.String LOCK_PATTERN_ENABLED = "lock_pattern_autolock";
     field public static final deprecated java.lang.String LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED = "lock_pattern_tactile_feedback_enabled";
     field public static final java.lang.String LOCK_PATTERN_VISIBLE = "lock_pattern_visible_pattern";
@@ -20325,6 +21681,7 @@
     method public deprecated synchronized void resize(int);
     method public void setFromFieldPacker(int, android.renderscript.FieldPacker);
     method public void setFromFieldPacker(int, int, android.renderscript.FieldPacker);
+    method public void setOnBufferAvailableListener(android.renderscript.Allocation.OnBufferAvailableListener);
     method public void setSurface(android.view.Surface);
     method public void syncAll(int);
     field public static final int USAGE_GRAPHICS_CONSTANTS = 8; // 0x8
@@ -20345,6 +21702,10 @@
     enum_constant public static final android.renderscript.Allocation.MipmapControl MIPMAP_ON_SYNC_TO_TEXTURE;
   }
 
+  public static abstract interface Allocation.OnBufferAvailableListener {
+    method public abstract void onBufferAvailable(android.renderscript.Allocation);
+  }
+
   public class AllocationAdapter extends android.renderscript.Allocation {
     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);
@@ -20471,6 +21832,7 @@
     method public static android.renderscript.Element U8_2(android.renderscript.RenderScript);
     method public static android.renderscript.Element U8_3(android.renderscript.RenderScript);
     method public static android.renderscript.Element U8_4(android.renderscript.RenderScript);
+    method public static android.renderscript.Element YUV(android.renderscript.RenderScript);
     method public static android.renderscript.Element createPixel(android.renderscript.RenderScript, android.renderscript.Element.DataType, android.renderscript.Element.DataKind);
     method public static android.renderscript.Element createVector(android.renderscript.RenderScript, android.renderscript.Element.DataType, int);
     method public int getBytesSize();
@@ -20994,9 +22356,12 @@
   }
 
   public final class ScriptIntrinsicColorMatrix extends android.renderscript.ScriptIntrinsic {
-    method public static android.renderscript.ScriptIntrinsicColorMatrix create(android.renderscript.RenderScript, android.renderscript.Element);
+    method public static deprecated android.renderscript.ScriptIntrinsicColorMatrix create(android.renderscript.RenderScript, android.renderscript.Element);
+    method public static android.renderscript.ScriptIntrinsicColorMatrix create(android.renderscript.RenderScript);
     method public void forEach(android.renderscript.Allocation, android.renderscript.Allocation);
     method public android.renderscript.Script.KernelID getKernelID();
+    method public void setAdd(android.renderscript.Float4);
+    method public void setAdd(float, float, float, float);
     method public void setColorMatrix(android.renderscript.Matrix4f);
     method public void setColorMatrix(android.renderscript.Matrix3f);
     method public void setGreyscale();
@@ -21022,6 +22387,16 @@
     method public void setInput(android.renderscript.Allocation);
   }
 
+  public final class ScriptIntrinsicHistogram extends android.renderscript.ScriptIntrinsic {
+    method public static android.renderscript.ScriptIntrinsicHistogram create(android.renderscript.RenderScript, android.renderscript.Element);
+    method public void forEach(android.renderscript.Allocation);
+    method public void forEach_Dot(android.renderscript.Allocation);
+    method public android.renderscript.Script.FieldID getFieldID_Input();
+    method public android.renderscript.Script.KernelID getKernelID_Separate();
+    method public void setDotCoefficients(float, float, float, float);
+    method public void setOutput(android.renderscript.Allocation);
+  }
+
   public final class ScriptIntrinsicLUT extends android.renderscript.ScriptIntrinsic {
     method public static android.renderscript.ScriptIntrinsicLUT create(android.renderscript.RenderScript, android.renderscript.Element);
     method public void forEach(android.renderscript.Allocation, android.renderscript.Allocation);
@@ -21170,8 +22545,11 @@
   }
 
   public final class KeyPairGeneratorSpec implements java.security.spec.AlgorithmParameterSpec {
+    method public java.security.spec.AlgorithmParameterSpec getAlgorithmParameterSpec();
     method public android.content.Context getContext();
     method public java.util.Date getEndDate();
+    method public int getKeySize();
+    method public java.lang.String getKeyType();
     method public java.lang.String getKeystoreAlias();
     method public java.math.BigInteger getSerialNumber();
     method public java.util.Date getStartDate();
@@ -21182,9 +22560,12 @@
   public static final class KeyPairGeneratorSpec.Builder {
     ctor public KeyPairGeneratorSpec.Builder(android.content.Context);
     method public android.security.KeyPairGeneratorSpec build();
+    method public android.security.KeyPairGeneratorSpec.Builder setAlgorithmParameterSpec(java.security.spec.AlgorithmParameterSpec);
     method public android.security.KeyPairGeneratorSpec.Builder setAlias(java.lang.String);
     method public android.security.KeyPairGeneratorSpec.Builder setEncryptionRequired();
     method public android.security.KeyPairGeneratorSpec.Builder setEndDate(java.util.Date);
+    method public android.security.KeyPairGeneratorSpec.Builder setKeySize(int);
+    method public android.security.KeyPairGeneratorSpec.Builder setKeyType(java.lang.String) throws java.security.NoSuchAlgorithmException;
     method public android.security.KeyPairGeneratorSpec.Builder setSerialNumber(java.math.BigInteger);
     method public android.security.KeyPairGeneratorSpec.Builder setStartDate(java.util.Date);
     method public android.security.KeyPairGeneratorSpec.Builder setSubject(javax.security.auth.x500.X500Principal);
@@ -21456,6 +22837,7 @@
 
   public final class SynthesisRequest {
     ctor public SynthesisRequest(java.lang.String, android.os.Bundle);
+    method public int getCallerUid();
     method public java.lang.String getCountry();
     method public java.lang.String getLanguage();
     method public android.os.Bundle getParams();
@@ -22475,11 +23857,14 @@
     method public java.io.File getDatabasePath(java.lang.String);
     method public java.io.File getDir(java.lang.String, int);
     method public java.io.File getExternalCacheDir();
+    method public java.io.File[] getExternalCacheDirs();
     method public java.io.File getExternalFilesDir(java.lang.String);
+    method public java.io.File[] getExternalFilesDirs(java.lang.String);
     method public java.io.File getFileStreamPath(java.lang.String);
     method public java.io.File getFilesDir();
     method public android.os.Looper getMainLooper();
     method public java.io.File getObbDir();
+    method public java.io.File[] getObbDirs();
     method public java.lang.String getPackageCodePath();
     method public android.content.pm.PackageManager getPackageManager();
     method public java.lang.String getPackageName();
@@ -22546,6 +23931,7 @@
     method public float getFloat(int);
     method public int getInt(int);
     method public long getLong(int);
+    method public android.net.Uri getNotificationUri();
     method public int getPosition();
     method public short getShort(int);
     method public java.lang.String getString(int);
@@ -23539,7 +24925,9 @@
     method public static void clearMetaKeyState(android.text.Editable, int);
     method public long clearMetaKeyState(long, int);
     method public static final int getMetaState(java.lang.CharSequence);
+    method public static final int getMetaState(java.lang.CharSequence, android.view.KeyEvent);
     method public static final int getMetaState(java.lang.CharSequence, int);
+    method public static final int getMetaState(java.lang.CharSequence, int, android.view.KeyEvent);
     method public static final int getMetaState(long);
     method public static final int getMetaState(long, int);
     method public static long handleKeyDown(long, int, android.view.KeyEvent);
@@ -24089,6 +25477,125 @@
 
 }
 
+package android.transition {
+
+  public class AutoTransition extends android.transition.TransitionSet {
+    ctor public AutoTransition();
+  }
+
+  public class ChangeBounds extends android.transition.Transition {
+    ctor public ChangeBounds();
+    method public void captureEndValues(android.transition.TransitionValues);
+    method public void captureStartValues(android.transition.TransitionValues);
+    method public void setReparent(boolean);
+    method public void setResizeClip(boolean);
+  }
+
+  public class Fade extends android.transition.Visibility {
+    ctor public Fade();
+    ctor public Fade(int);
+    field public static final int IN = 1; // 0x1
+    field public static final int OUT = 2; // 0x2
+  }
+
+  public final class Scene {
+    ctor public Scene(android.view.ViewGroup);
+    ctor public Scene(android.view.ViewGroup, android.view.ViewGroup);
+    method public void enter();
+    method public void exit();
+    method public static android.transition.Scene getSceneForLayout(android.view.ViewGroup, int, android.content.Context);
+    method public android.view.ViewGroup getSceneRoot();
+    method public void setEnterAction(java.lang.Runnable);
+    method public void setExitAction(java.lang.Runnable);
+  }
+
+  public abstract class Transition implements java.lang.Cloneable {
+    ctor public Transition();
+    method public android.transition.Transition addListener(android.transition.Transition.TransitionListener);
+    method public android.transition.Transition addTarget(int);
+    method public android.transition.Transition addTarget(android.view.View);
+    method public abstract void captureEndValues(android.transition.TransitionValues);
+    method public abstract void captureStartValues(android.transition.TransitionValues);
+    method public android.transition.Transition clone();
+    method public android.animation.Animator createAnimator(android.view.ViewGroup, android.transition.TransitionValues, android.transition.TransitionValues);
+    method public android.transition.Transition excludeChildren(int, boolean);
+    method public android.transition.Transition excludeChildren(android.view.View, boolean);
+    method public android.transition.Transition excludeChildren(java.lang.Class, boolean);
+    method public android.transition.Transition excludeTarget(int, boolean);
+    method public android.transition.Transition excludeTarget(android.view.View, boolean);
+    method public android.transition.Transition excludeTarget(java.lang.Class, boolean);
+    method public long getDuration();
+    method public android.animation.TimeInterpolator getInterpolator();
+    method public java.lang.String getName();
+    method public long getStartDelay();
+    method public java.util.List<java.lang.Integer> getTargetIds();
+    method public java.util.List<android.view.View> getTargets();
+    method public java.lang.String[] getTransitionProperties();
+    method public android.transition.TransitionValues getTransitionValues(android.view.View, boolean);
+    method public android.transition.Transition removeListener(android.transition.Transition.TransitionListener);
+    method public android.transition.Transition removeTarget(int);
+    method public android.transition.Transition removeTarget(android.view.View);
+    method public android.transition.Transition setDuration(long);
+    method public android.transition.Transition setInterpolator(android.animation.TimeInterpolator);
+    method public android.transition.Transition setStartDelay(long);
+  }
+
+  public static abstract interface Transition.TransitionListener {
+    method public abstract void onTransitionCancel(android.transition.Transition);
+    method public abstract void onTransitionEnd(android.transition.Transition);
+    method public abstract void onTransitionPause(android.transition.Transition);
+    method public abstract void onTransitionResume(android.transition.Transition);
+    method public abstract void onTransitionStart(android.transition.Transition);
+  }
+
+  public class TransitionInflater {
+    method public static android.transition.TransitionInflater from(android.content.Context);
+    method public android.transition.Transition inflateTransition(int);
+    method public android.transition.TransitionManager inflateTransitionManager(int, android.view.ViewGroup);
+  }
+
+  public class TransitionManager {
+    ctor public TransitionManager();
+    method public static void beginDelayedTransition(android.view.ViewGroup);
+    method public static void beginDelayedTransition(android.view.ViewGroup, android.transition.Transition);
+    method public static android.transition.Transition getDefaultTransition();
+    method public static void go(android.transition.Scene);
+    method public static void go(android.transition.Scene, android.transition.Transition);
+    method public void setDefaultTransition(android.transition.Transition);
+    method public void setTransition(android.transition.Scene, android.transition.Transition);
+    method public void setTransition(android.transition.Scene, android.transition.Scene, android.transition.Transition);
+    method public void transitionTo(android.transition.Scene);
+  }
+
+  public class TransitionSet extends android.transition.Transition {
+    ctor public TransitionSet();
+    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 int getOrdering();
+    method public android.transition.TransitionSet removeTransition(android.transition.Transition);
+    method public android.transition.TransitionSet setOrdering(int);
+    field public static final int ORDERING_SEQUENTIAL = 1; // 0x1
+    field public static final int ORDERING_TOGETHER = 0; // 0x0
+  }
+
+  public class TransitionValues {
+    ctor public TransitionValues();
+    field public final java.util.Map values;
+    field public android.view.View view;
+  }
+
+  public abstract class Visibility extends android.transition.Transition {
+    ctor public Visibility();
+    method public void captureEndValues(android.transition.TransitionValues);
+    method public void captureStartValues(android.transition.TransitionValues);
+    method public boolean isVisible(android.transition.TransitionValues);
+    method public android.animation.Animator onAppear(android.view.ViewGroup, android.transition.TransitionValues, int, android.transition.TransitionValues, int);
+    method public android.animation.Animator onDisappear(android.view.ViewGroup, android.transition.TransitionValues, int, android.transition.TransitionValues, int);
+  }
+
+}
+
 package android.util {
 
   public class AndroidException extends java.lang.Exception {
@@ -24105,6 +25612,33 @@
     ctor public AndroidRuntimeException(java.lang.Exception);
   }
 
+  public final class ArrayMap implements java.util.Map {
+    ctor public ArrayMap();
+    ctor public ArrayMap(int);
+    ctor public ArrayMap(android.util.ArrayMap);
+    method public void clear();
+    method public boolean containsAll(java.util.Collection<?>);
+    method public boolean containsKey(java.lang.Object);
+    method public boolean containsValue(java.lang.Object);
+    method public void ensureCapacity(int);
+    method public java.util.Set<java.util.Map.Entry<K, V>> entrySet();
+    method public V get(java.lang.Object);
+    method public boolean isEmpty();
+    method public K keyAt(int);
+    method public java.util.Set<K> keySet();
+    method public V put(K, V);
+    method public void putAll(android.util.ArrayMap<? extends K, ? extends V>);
+    method public void putAll(java.util.Map<? extends K, ? extends V>);
+    method public V remove(java.lang.Object);
+    method public boolean removeAll(java.util.Collection<?>);
+    method public V removeAt(int);
+    method public boolean retainAll(java.util.Collection<?>);
+    method public V setValueAt(int, V);
+    method public int size();
+    method public V valueAt(int);
+    method public java.util.Collection<V> values();
+  }
+
   public class AtomicFile {
     ctor public AtomicFile(java.io.File);
     method public void delete();
@@ -24300,6 +25834,13 @@
     method public android.util.JsonWriter value(java.lang.Number) throws java.io.IOException;
   }
 
+  public final class LayoutDirection {
+    field public static final int INHERIT = 2; // 0x2
+    field public static final int LOCALE = 3; // 0x3
+    field public static final int LTR = 0; // 0x0
+    field public static final int RTL = 1; // 0x1
+  }
+
   public final class Log {
     method public static int d(java.lang.String, java.lang.String);
     method public static int d(java.lang.String, java.lang.String, java.lang.Throwable);
@@ -24458,6 +25999,7 @@
     method public void put(int, E);
     method public void remove(int);
     method public void removeAt(int);
+    method public void removeAtRange(int, int);
     method public void setValueAt(int, E);
     method public int size();
     method public E valueAt(int);
@@ -24741,6 +26283,8 @@
     method public deprecated int getWidth();
     method public boolean isValid();
     field public static final int DEFAULT_DISPLAY = 0; // 0x0
+    field public static final int FLAG_PRESENTATION = 8; // 0x8
+    field public static final int FLAG_PRIVATE = 4; // 0x4
     field public static final int FLAG_SECURE = 2; // 0x2
     field public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 1; // 0x1
   }
@@ -24868,6 +26412,7 @@
 
   public final class InputDevice implements android.os.Parcelable {
     method public int describeContents();
+    method public int getControllerNumber();
     method public java.lang.String getDescriptor();
     method public static android.view.InputDevice getDevice(int);
     method public static int[] getDeviceIds();
@@ -24878,8 +26423,11 @@
     method public android.view.InputDevice.MotionRange getMotionRange(int, int);
     method public java.util.List<android.view.InputDevice.MotionRange> getMotionRanges();
     method public java.lang.String getName();
+    method public int getProductId();
     method public int getSources();
+    method public int getVendorId();
     method public android.os.Vibrator getVibrator();
+    method public boolean[] hasKeys(int...);
     method public boolean isVirtual();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
@@ -25195,6 +26743,7 @@
     field public static final int KEYCODE_LEFT_BRACKET = 71; // 0x47
     field public static final int KEYCODE_M = 41; // 0x29
     field public static final int KEYCODE_MANNER_MODE = 205; // 0xcd
+    field public static final int KEYCODE_MEDIA_AUDIO_TRACK = 222; // 0xde
     field public static final int KEYCODE_MEDIA_CLOSE = 128; // 0x80
     field public static final int KEYCODE_MEDIA_EJECT = 129; // 0x81
     field public static final int KEYCODE_MEDIA_FAST_FORWARD = 90; // 0x5a
@@ -25467,6 +27016,7 @@
   }
 
   public final class MotionEvent extends android.view.InputEvent implements android.os.Parcelable {
+    method public static java.lang.String actionToString(int);
     method public final void addBatch(long, float, float, float, float, int);
     method public final void addBatch(long, android.view.MotionEvent.PointerCoords[], int);
     method public static int axisFromString(java.lang.String);
@@ -25683,6 +27233,7 @@
 
   public class ScaleGestureDetector {
     ctor public ScaleGestureDetector(android.content.Context, android.view.ScaleGestureDetector.OnScaleGestureListener);
+    ctor public ScaleGestureDetector(android.content.Context, android.view.ScaleGestureDetector.OnScaleGestureListener, android.os.Handler);
     method public float getCurrentSpan();
     method public float getCurrentSpanX();
     method public float getCurrentSpanY();
@@ -25696,6 +27247,7 @@
     method public long getTimeDelta();
     method public boolean isInProgress();
     method public boolean onTouchEvent(android.view.MotionEvent);
+    method public void setQuickScaleEnabled(boolean);
   }
 
   public static abstract interface ScaleGestureDetector.OnScaleGestureListener {
@@ -25749,7 +27301,7 @@
     field public static final int ROTATION_90 = 1; // 0x1
   }
 
-  public static class Surface.OutOfResourcesException extends java.lang.Exception {
+  public static class Surface.OutOfResourcesException extends java.lang.RuntimeException {
     ctor public Surface.OutOfResourcesException();
     ctor public Surface.OutOfResourcesException(java.lang.String);
   }
@@ -25871,9 +27423,13 @@
     method public void buildDrawingCache(boolean);
     method public void buildLayer();
     method public boolean callOnClick();
+    method public boolean canResolveLayoutDirection();
+    method public boolean canResolveTextAlignment();
+    method public boolean canResolveTextDirection();
     method public boolean canScrollHorizontally(int);
     method public boolean canScrollVertically(int);
     method public void cancelLongPress();
+    method public final void cancelPendingInputEvents();
     method public boolean checkInputConnectionProxy(android.view.View);
     method public void clearAnimation();
     method public void clearFocus();
@@ -25923,6 +27479,7 @@
     method public android.view.View focusSearch(int);
     method public void forceLayout();
     method public static int generateViewId();
+    method public int getAccessibilityLiveRegion();
     method public android.view.accessibility.AccessibilityNodeProvider getAccessibilityNodeProvider();
     method public float getAlpha();
     method public android.view.animation.Animation getAnimation();
@@ -26056,6 +27613,7 @@
     method public void invalidate();
     method public void invalidateDrawable(android.graphics.drawable.Drawable);
     method public boolean isActivated();
+    method public boolean isAttachedToWindow();
     method public boolean isClickable();
     method public boolean isDirty();
     method public boolean isDrawingCacheEnabled();
@@ -26072,6 +27630,8 @@
     method public boolean isInEditMode();
     method public boolean isInLayout();
     method public boolean isInTouchMode();
+    method public boolean isLaidOut();
+    method public boolean isLayoutDirectionResolved();
     method public boolean isLayoutRequested();
     method public boolean isLongClickable();
     method public boolean isOpaque();
@@ -26085,6 +27645,8 @@
     method public boolean isSelected();
     method public boolean isShown();
     method public boolean isSoundEffectsEnabled();
+    method public boolean isTextAlignmentResolved();
+    method public boolean isTextDirectionResolved();
     method public boolean isVerticalFadingEdgeEnabled();
     method public boolean isVerticalScrollBarEnabled();
     method public void jumpDrawablesToCurrentState();
@@ -26096,6 +27658,7 @@
     method protected void onAnimationEnd();
     method protected void onAnimationStart();
     method protected void onAttachedToWindow();
+    method public void onCancelPendingInputEvents();
     method public boolean onCheckIsTextEditor();
     method protected void onConfigurationChanged(android.content.res.Configuration);
     method protected void onCreateContextMenu(android.view.ContextMenu);
@@ -26178,6 +27741,7 @@
     method public void sendAccessibilityEvent(int);
     method public void sendAccessibilityEventUnchecked(android.view.accessibility.AccessibilityEvent);
     method public void setAccessibilityDelegate(android.view.View.AccessibilityDelegate);
+    method public void setAccessibilityLiveRegion(int);
     method public void setActivated(boolean);
     method public void setAlpha(float);
     method public void setAnimation(android.view.animation.Animation);
@@ -26283,6 +27847,9 @@
     method protected boolean verifyDrawable(android.graphics.drawable.Drawable);
     method public boolean willNotCacheDrawing();
     method public boolean willNotDraw();
+    field public static final int ACCESSIBILITY_LIVE_REGION_ASSERTIVE = 2; // 0x2
+    field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0
+    field public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 1; // 0x1
     field public static final android.util.Property ALPHA;
     field public static final int DRAWING_CACHE_QUALITY_AUTO = 0; // 0x0
     field public static final int DRAWING_CACHE_QUALITY_HIGH = 1048576; // 0x100000
@@ -26346,6 +27913,7 @@
     field protected static final int[] PRESSED_FOCUSED_WINDOW_FOCUSED_STATE_SET;
     field protected static final int[] PRESSED_SELECTED_STATE_SET;
     field protected static final int[] PRESSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
+    field protected static final int[] PRESSED_STATE_SET;
     field protected static final int[] PRESSED_WINDOW_FOCUSED_STATE_SET;
     field public static final android.util.Property ROTATION;
     field public static final android.util.Property ROTATION_X;
@@ -26368,10 +27936,13 @@
     field public static final deprecated int STATUS_BAR_VISIBLE = 0; // 0x0
     field public static final int SYSTEM_UI_FLAG_FULLSCREEN = 4; // 0x4
     field public static final int SYSTEM_UI_FLAG_HIDE_NAVIGATION = 2; // 0x2
+    field public static final int SYSTEM_UI_FLAG_IMMERSIVE = 2048; // 0x800
     field public static final int SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN = 1024; // 0x400
     field public static final int SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION = 512; // 0x200
     field public static final int SYSTEM_UI_FLAG_LAYOUT_STABLE = 256; // 0x100
     field public static final int SYSTEM_UI_FLAG_LOW_PROFILE = 1; // 0x1
+    field public static final int SYSTEM_UI_FLAG_TRANSPARENT_NAVIGATION = 8192; // 0x2000
+    field public static final int SYSTEM_UI_FLAG_TRANSPARENT_STATUS = 4096; // 0x1000
     field public static final int SYSTEM_UI_FLAG_VISIBLE = 0; // 0x0
     field public static final int SYSTEM_UI_LAYOUT_FLAGS = 1536; // 0x600
     field public static final int TEXT_ALIGNMENT_CENTER = 4; // 0x4
@@ -26588,6 +28159,7 @@
     method protected boolean canAnimate();
     method protected boolean checkLayoutParams(android.view.ViewGroup.LayoutParams);
     method public void childDrawableStateChanged(android.view.View);
+    method public void childHasTransientStateChanged(android.view.View, boolean);
     method protected void cleanupLayoutState(android.view.View);
     method public void clearChildFocus(android.view.View);
     method public void clearDisappearingChildren();
@@ -26634,6 +28206,7 @@
     method protected void measureChild(android.view.View, int, int);
     method protected void measureChildWithMargins(android.view.View, int, int, int, int);
     method protected void measureChildren(int, int);
+    method public void notifySubtreeAccessibilityStateChanged(android.view.View, android.view.View, int);
     method public final void offsetDescendantRectToMyCoords(android.view.View, android.graphics.Rect);
     method public final void offsetRectIntoDescendantCoords(android.view.View, android.graphics.Rect);
     method public boolean onInterceptHoverEvent(android.view.MotionEvent);
@@ -26748,17 +28321,28 @@
 
   public abstract interface ViewParent {
     method public abstract void bringChildToFront(android.view.View);
+    method public abstract boolean canResolveLayoutDirection();
+    method public abstract boolean canResolveTextAlignment();
+    method public abstract boolean canResolveTextDirection();
     method public abstract void childDrawableStateChanged(android.view.View);
+    method public abstract void childHasTransientStateChanged(android.view.View, boolean);
     method public abstract void clearChildFocus(android.view.View);
     method public abstract void createContextMenu(android.view.ContextMenu);
     method public abstract android.view.View focusSearch(android.view.View, int);
     method public abstract void focusableViewAvailable(android.view.View);
     method public abstract boolean getChildVisibleRect(android.view.View, android.graphics.Rect, android.graphics.Point);
+    method public abstract int getLayoutDirection();
     method public abstract android.view.ViewParent getParent();
     method public abstract android.view.ViewParent getParentForAccessibility();
+    method public abstract int getTextAlignment();
+    method public abstract int getTextDirection();
     method public abstract void invalidateChild(android.view.View, android.graphics.Rect);
     method public abstract android.view.ViewParent invalidateChildInParent(int[], android.graphics.Rect);
+    method public abstract boolean isLayoutDirectionResolved();
     method public abstract boolean isLayoutRequested();
+    method public abstract boolean isTextAlignmentResolved();
+    method public abstract boolean isTextDirectionResolved();
+    method public abstract void notifySubtreeAccessibilityStateChanged(android.view.View, android.view.View, int);
     method public abstract void recomputeViewAttributes(android.view.View);
     method public abstract void requestChildFocus(android.view.View, android.view.View);
     method public abstract boolean requestChildRectangleOnScreen(android.view.View, android.graphics.Rect, boolean);
@@ -26792,6 +28376,7 @@
     method public android.view.ViewPropertyAnimator setInterpolator(android.animation.TimeInterpolator);
     method public android.view.ViewPropertyAnimator setListener(android.animation.Animator.AnimatorListener);
     method public android.view.ViewPropertyAnimator setStartDelay(long);
+    method public android.view.ViewPropertyAnimator setUpdateListener(android.animation.ValueAnimator.AnimatorUpdateListener);
     method public void start();
     method public android.view.ViewPropertyAnimator translationX(float);
     method public android.view.ViewPropertyAnimator translationXBy(float);
@@ -26906,6 +28491,7 @@
     method public final boolean hasChildren();
     method public boolean hasFeature(int);
     method protected final boolean hasSoftInputMode();
+    method public void injectInputEvent(android.view.InputEvent);
     method public abstract void invalidatePanelMenu(int);
     method public final boolean isActive();
     method public abstract boolean isFloating();
@@ -26941,7 +28527,10 @@
     method public void setFlags(int, int);
     method public void setFormat(int);
     method public void setGravity(int);
+    method public void setIcon(int);
     method public void setLayout(int, int);
+    method public void setLocalFocus(boolean, boolean);
+    method public void setLogo(int);
     method public void setSoftInputMode(int);
     method public abstract void setTitle(java.lang.CharSequence);
     method public abstract void setTitleColor(int);
@@ -27079,6 +28668,7 @@
     field public static final int FLAG_LAYOUT_IN_OVERSCAN = 33554432; // 0x2000000
     field public static final int FLAG_LAYOUT_IN_SCREEN = 256; // 0x100
     field public static final int FLAG_LAYOUT_NO_LIMITS = 512; // 0x200
+    field public static final int FLAG_LOCAL_FOCUS_MODE = 268435456; // 0x10000000
     field public static final int FLAG_NOT_FOCUSABLE = 8; // 0x8
     field public static final int FLAG_NOT_TOUCHABLE = 16; // 0x10
     field public static final int FLAG_NOT_TOUCH_MODAL = 32; // 0x20
@@ -27135,6 +28725,7 @@
     field public static final int TYPE_KEYGUARD_DIALOG = 2009; // 0x7d9
     field public static final int TYPE_PHONE = 2002; // 0x7d2
     field public static final int TYPE_PRIORITY_PHONE = 2007; // 0x7d7
+    field public static final int TYPE_PRIVATE_PRESENTATION = 2030; // 0x7ee
     field public static final int TYPE_SEARCH_BAR = 2001; // 0x7d1
     field public static final int TYPE_STATUS_BAR = 2000; // 0x7d0
     field public static final int TYPE_STATUS_BAR_PANEL = 2014; // 0x7de
@@ -27177,6 +28768,7 @@
     method public int describeContents();
     method public static java.lang.String eventTypeToString(int);
     method public int getAction();
+    method public int getContentChangeTypes();
     method public long getEventTime();
     method public int getEventType();
     method public int getMovementGranularity();
@@ -27188,11 +28780,16 @@
     method public static android.view.accessibility.AccessibilityEvent obtain(android.view.accessibility.AccessibilityEvent);
     method public static android.view.accessibility.AccessibilityEvent obtain();
     method public void setAction(int);
+    method public void setContentChangeTypes(int);
     method public void setEventTime(long);
     method public void setEventType(int);
     method public void setMovementGranularity(int);
     method public void setPackageName(java.lang.CharSequence);
     method public void writeToParcel(android.os.Parcel, int);
+    field public static final int CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION = 4; // 0x4
+    field public static final int CONTENT_CHANGE_TYPE_SUBTREE = 1; // 0x1
+    field public static final int CONTENT_CHANGE_TYPE_TEXT = 2; // 0x2
+    field public static final int CONTENT_CHANGE_TYPE_UNDEFINED = 0; // 0x0
     field public static final android.os.Parcelable.Creator CREATOR;
     field public static final int INVALID_POSITION = -1; // 0xffffffff
     field public static final deprecated int MAX_TEXT_LENGTH = 500; // 0x1f4
@@ -27246,6 +28843,7 @@
     method public void addAction(int);
     method public void addChild(android.view.View);
     method public void addChild(android.view.View, int);
+    method public boolean canOpenPopup();
     method public int describeContents();
     method public java.util.List<android.view.accessibility.AccessibilityNodeInfo> findAccessibilityNodeInfosByText(java.lang.String);
     method public java.util.List<android.view.accessibility.AccessibilityNodeInfo> findAccessibilityNodeInfosByViewId(java.lang.String);
@@ -27257,12 +28855,18 @@
     method public android.view.accessibility.AccessibilityNodeInfo getChild(int);
     method public int getChildCount();
     method public java.lang.CharSequence getClassName();
+    method public android.view.accessibility.AccessibilityNodeInfo.CollectionInfo getCollectionInfo();
+    method public android.view.accessibility.AccessibilityNodeInfo.CollectionItemInfo getCollectionItemInfo();
     method public java.lang.CharSequence getContentDescription();
+    method public android.os.Bundle getExtras();
+    method public int getInputType();
     method public android.view.accessibility.AccessibilityNodeInfo getLabelFor();
     method public android.view.accessibility.AccessibilityNodeInfo getLabeledBy();
+    method public int getLiveRegion();
     method public int getMovementGranularities();
     method public java.lang.CharSequence getPackageName();
     method public android.view.accessibility.AccessibilityNodeInfo getParent();
+    method public android.view.accessibility.AccessibilityNodeInfo.RangeInfo getRangeInfo();
     method public java.lang.CharSequence getText();
     method public int getTextSelectionEnd();
     method public int getTextSelectionStart();
@@ -27272,11 +28876,14 @@
     method public boolean isCheckable();
     method public boolean isChecked();
     method public boolean isClickable();
+    method public boolean isContentInvalid();
+    method public boolean isDismissable();
     method public boolean isEditable();
     method public boolean isEnabled();
     method public boolean isFocusable();
     method public boolean isFocused();
     method public boolean isLongClickable();
+    method public boolean isMultiLine();
     method public boolean isPassword();
     method public boolean isScrollable();
     method public boolean isSelected();
@@ -27292,25 +28899,34 @@
     method public void setAccessibilityFocused(boolean);
     method public void setBoundsInParent(android.graphics.Rect);
     method public void setBoundsInScreen(android.graphics.Rect);
+    method public void setCanOpenPopup(boolean);
     method public void setCheckable(boolean);
     method public void setChecked(boolean);
     method public void setClassName(java.lang.CharSequence);
     method public void setClickable(boolean);
+    method public void setCollectionInfo(android.view.accessibility.AccessibilityNodeInfo.CollectionInfo);
+    method public void setCollectionItemInfo(android.view.accessibility.AccessibilityNodeInfo.CollectionItemInfo);
     method public void setContentDescription(java.lang.CharSequence);
+    method public void setContentInvalid(boolean);
+    method public void setDismissable(boolean);
     method public void setEditable(boolean);
     method public void setEnabled(boolean);
     method public void setFocusable(boolean);
     method public void setFocused(boolean);
+    method public void setInputType(int);
     method public void setLabelFor(android.view.View);
     method public void setLabelFor(android.view.View, int);
     method public void setLabeledBy(android.view.View);
     method public void setLabeledBy(android.view.View, int);
+    method public void setLiveRegion(int);
     method public void setLongClickable(boolean);
     method public void setMovementGranularities(int);
+    method public void setMultiLine(boolean);
     method public void setPackageName(java.lang.CharSequence);
     method public void setParent(android.view.View);
     method public void setParent(android.view.View, int);
     method public void setPassword(boolean);
+    method public void setRangeInfo(android.view.accessibility.AccessibilityNodeInfo.RangeInfo);
     method public void setScrollable(boolean);
     method public void setSelected(boolean);
     method public void setSource(android.view.View);
@@ -27330,8 +28946,11 @@
     field public static final int ACTION_CLEAR_FOCUS = 2; // 0x2
     field public static final int ACTION_CLEAR_SELECTION = 8; // 0x8
     field public static final int ACTION_CLICK = 16; // 0x10
+    field public static final int ACTION_COLLAPSE = 524288; // 0x80000
     field public static final int ACTION_COPY = 16384; // 0x4000
     field public static final int ACTION_CUT = 65536; // 0x10000
+    field public static final int ACTION_DISMISS = 1048576; // 0x100000
+    field public static final int ACTION_EXPAND = 262144; // 0x40000
     field public static final int ACTION_FOCUS = 1; // 0x1
     field public static final int ACTION_LONG_CLICK = 32; // 0x20
     field public static final int ACTION_NEXT_AT_MOVEMENT_GRANULARITY = 256; // 0x100
@@ -27353,6 +28972,33 @@
     field public static final int MOVEMENT_GRANULARITY_WORD = 2; // 0x2
   }
 
+  public static final class AccessibilityNodeInfo.CollectionInfo {
+    method public int getColumnCount();
+    method public int getRowCount();
+    method public boolean isHierarchical();
+    method public static android.view.accessibility.AccessibilityNodeInfo.CollectionInfo obtain(int, int, boolean);
+  }
+
+  public static final class AccessibilityNodeInfo.CollectionItemInfo {
+    method public int getColumnIndex();
+    method public int getColumnSpan();
+    method public int getRowIndex();
+    method public int getRowSpan();
+    method public boolean isHeading();
+    method public static android.view.accessibility.AccessibilityNodeInfo.CollectionItemInfo obtain(int, int, int, int, boolean);
+  }
+
+  public static final class AccessibilityNodeInfo.RangeInfo {
+    method public float getCurrent();
+    method public float getMax();
+    method public float getMin();
+    method public int getType();
+    method public static android.view.accessibility.AccessibilityNodeInfo.RangeInfo obtain(int, float, float, float);
+    field public static final int RANGE_TYPE_FLOAT = 1; // 0x1
+    field public static final int RANGE_TYPE_INT = 0; // 0x0
+    field public static final int RANGE_TYPE_PERCENT = 2; // 0x2
+  }
+
   public abstract class AccessibilityNodeProvider {
     ctor public AccessibilityNodeProvider();
     method public android.view.accessibility.AccessibilityNodeInfo createAccessibilityNodeInfo(int);
@@ -27409,6 +29055,34 @@
     method public void setToIndex(int);
   }
 
+  public class CaptioningManager {
+    method public void addCaptioningChangeListener(android.view.accessibility.CaptioningManager.CaptioningChangeListener);
+    method public final float getFontScale();
+    method public final java.util.Locale getLocale();
+    method public android.view.accessibility.CaptioningManager.CaptionStyle getUserStyle();
+    method public final boolean isEnabled();
+    method public void removeCaptioningChangeListener(android.view.accessibility.CaptioningManager.CaptioningChangeListener);
+  }
+
+  public static final class CaptioningManager.CaptionStyle {
+    method public android.graphics.Typeface getTypeface();
+    field public static final int EDGE_TYPE_DROP_SHADOW = 2; // 0x2
+    field public static final int EDGE_TYPE_NONE = 0; // 0x0
+    field public static final int EDGE_TYPE_OUTLINE = 1; // 0x1
+    field public final int backgroundColor;
+    field public final int edgeColor;
+    field public final int edgeType;
+    field public final int foregroundColor;
+  }
+
+  public static abstract class CaptioningManager.CaptioningChangeListener {
+    ctor public CaptioningManager.CaptioningChangeListener();
+    method public void onEnabledChanged(boolean);
+    method public void onFontScaleChanged(float);
+    method public void onLocaleChanged(java.util.Locale);
+    method public void onUserStyleChanged(android.view.accessibility.CaptioningManager.CaptionStyle);
+  }
+
 }
 
 package android.view.animation {
@@ -27661,10 +29335,10 @@
     method public void setAlpha(float);
     method public void setTransformationType(int);
     method public java.lang.String toShortString();
-    field public static int TYPE_ALPHA;
-    field public static int TYPE_BOTH;
-    field public static int TYPE_IDENTITY;
-    field public static int TYPE_MATRIX;
+    field public static final int TYPE_ALPHA = 1; // 0x1
+    field public static final int TYPE_BOTH = 3; // 0x3
+    field public static final int TYPE_IDENTITY = 0; // 0x0
+    field public static final int TYPE_MATRIX = 2; // 0x2
     field protected float mAlpha;
     field protected android.graphics.Matrix mMatrix;
     field protected int mTransformationType;
@@ -27928,6 +29602,7 @@
     method public boolean setCurrentInputMethodSubtype(android.view.inputmethod.InputMethodSubtype);
     method public void setInputMethod(android.os.IBinder, java.lang.String);
     method public void setInputMethodAndSubtype(android.os.IBinder, java.lang.String, android.view.inputmethod.InputMethodSubtype);
+    method public boolean shouldOfferSwitchingToNextInputMethod(android.os.IBinder);
     method public void showInputMethodAndSubtypeEnabler(java.lang.String);
     method public void showInputMethodPicker();
     method public boolean showSoftInput(android.view.View, int);
@@ -27971,8 +29646,8 @@
   }
 
   public final class InputMethodSubtype implements android.os.Parcelable {
-    ctor public InputMethodSubtype(int, int, java.lang.String, java.lang.String, java.lang.String, boolean, boolean);
-    ctor public InputMethodSubtype(int, int, java.lang.String, java.lang.String, java.lang.String, boolean, boolean, int);
+    ctor public deprecated InputMethodSubtype(int, int, java.lang.String, java.lang.String, java.lang.String, boolean, boolean);
+    ctor public deprecated InputMethodSubtype(int, int, java.lang.String, java.lang.String, java.lang.String, boolean, boolean, int);
     method public boolean containsExtraValueKey(java.lang.String);
     method public int describeContents();
     method public java.lang.CharSequence getDisplayName(android.content.Context, java.lang.String, android.content.pm.ApplicationInfo);
@@ -27982,12 +29657,27 @@
     method public java.lang.String getLocale();
     method public java.lang.String getMode();
     method public int getNameResId();
+    method public boolean isAsciiCapable();
     method public boolean isAuxiliary();
     method public boolean overridesImplicitlyEnabledSubtype();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
   }
 
+  public static class InputMethodSubtype.InputMethodSubtypeBuilder {
+    ctor public InputMethodSubtype.InputMethodSubtypeBuilder();
+    method public android.view.inputmethod.InputMethodSubtype build();
+    method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setIsAsciiCapable(boolean);
+    method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setIsAuxiliary(boolean);
+    method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setOverridesImplicitlyEnabledSubtype(boolean);
+    method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setSubtypeExtraValue(java.lang.String);
+    method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setSubtypeIconResId(int);
+    method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setSubtypeId(int);
+    method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setSubtypeLocale(java.lang.String);
+    method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setSubtypeMode(java.lang.String);
+    method public android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder setSubtypeNameResId(int);
+  }
+
 }
 
 package android.view.textservice {
@@ -28472,8 +30162,10 @@
     method public void clearSslPreferences();
     method public deprecated void clearView();
     method public android.webkit.WebBackForwardList copyBackForwardList();
+    method public android.print.PrintDocumentAdapter createPrintDocumentAdapter();
     method public void destroy();
     method public void documentHasImages(android.os.Message);
+    method public void evaluateJavascript(java.lang.String, android.webkit.ValueCallback<java.lang.String>);
     method public static java.lang.String findAddress(java.lang.String);
     method public deprecated int findAll(java.lang.String);
     method public void findAllAsync(java.lang.String);
@@ -28630,6 +30322,7 @@
     ctor public AbsListView(android.content.Context, android.util.AttributeSet, int);
     method public void afterTextChanged(android.text.Editable);
     method public void beforeTextChanged(java.lang.CharSequence, int, int, int);
+    method public boolean canScrollList(int);
     method public void clearChoices();
     method public void clearTextFilter();
     method public void deferNotifyDataSetChanged();
@@ -28661,6 +30354,7 @@
     method protected void layoutChildren();
     method public void onFilterComplete(int);
     method public void onGlobalLayout();
+    method public void onInitializeAccessibilityNodeInfoForItem(android.view.View, int, android.view.accessibility.AccessibilityNodeInfo);
     method public boolean onRemoteAdapterConnected();
     method public void onRemoteAdapterDisconnected();
     method public void onRestoreInstanceState(android.os.Parcelable);
@@ -28670,6 +30364,7 @@
     method public int pointToPosition(int, int);
     method public long pointToRowId(int, int);
     method public void reclaimViews(java.util.List<android.view.View>);
+    method public void scrollListBy(int);
     method public void setAdapter(android.widget.ListAdapter);
     method public void setCacheColorHint(int);
     method public void setChoiceMode(int);
@@ -29390,6 +31085,7 @@
     ctor public FrameLayout.LayoutParams(int, int, int);
     ctor public FrameLayout.LayoutParams(android.view.ViewGroup.LayoutParams);
     ctor public FrameLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+    ctor public FrameLayout.LayoutParams(android.widget.FrameLayout.LayoutParams);
     field public int gravity;
   }
 
@@ -29652,6 +31348,7 @@
     ctor public LinearLayout.LayoutParams(int, int, float);
     ctor public LinearLayout.LayoutParams(android.view.ViewGroup.LayoutParams);
     ctor public LinearLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+    ctor public LinearLayout.LayoutParams(android.widget.LinearLayout.LayoutParams);
     method public java.lang.String debug(java.lang.String);
     field public int gravity;
     field public float weight;
@@ -29668,6 +31365,7 @@
     ctor public ListPopupWindow(android.content.Context, android.util.AttributeSet, int);
     ctor public ListPopupWindow(android.content.Context, android.util.AttributeSet, int, int);
     method public void clearListSelection();
+    method public android.view.View.OnTouchListener createDragToOpenListener(android.view.View);
     method public void dismiss();
     method public android.view.View getAnchorView();
     method public int getAnimationStyle();
@@ -29729,6 +31427,8 @@
     method public void addFooterView(android.view.View);
     method public void addHeaderView(android.view.View, java.lang.Object, boolean);
     method public void addHeaderView(android.view.View);
+    method public boolean areFooterDividersEnabled();
+    method public boolean areHeaderDividersEnabled();
     method protected android.view.View findViewTraversal(int);
     method protected android.view.View findViewWithTagTraversal(java.lang.Object);
     method public android.widget.ListAdapter getAdapter();
@@ -29877,6 +31577,7 @@
   public class PopupMenu {
     ctor public PopupMenu(android.content.Context, android.view.View);
     method public void dismiss();
+    method public android.view.View.OnTouchListener getDragToOpenListener();
     method public android.view.Menu getMenu();
     method public android.view.MenuInflater getMenuInflater();
     method public void inflate(int);
@@ -30082,6 +31783,7 @@
     ctor public RelativeLayout.LayoutParams(int, int);
     ctor public RelativeLayout.LayoutParams(android.view.ViewGroup.LayoutParams);
     ctor public RelativeLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
+    ctor public RelativeLayout.LayoutParams(android.widget.RelativeLayout.LayoutParams);
     method public void addRule(int);
     method public void addRule(int, int);
     method public java.lang.String debug(java.lang.String);
@@ -30883,6 +32585,7 @@
     ctor public VideoView(android.content.Context);
     ctor public VideoView(android.content.Context, android.util.AttributeSet);
     ctor public VideoView(android.content.Context, android.util.AttributeSet, int);
+    method public void addSubtitleSource(java.io.InputStream, android.media.MediaFormat);
     method public boolean canPause();
     method public boolean canSeekBackward();
     method public boolean canSeekForward();
diff --git a/cmds/am/am b/cmds/am/am
index c823634..1d426bc 100755
--- a/cmds/am/am
+++ b/cmds/am/am
@@ -1,3 +1,5 @@
+#!/system/bin/sh
+#
 # Script to start "am" on the device, which has a very rudimentary
 # shell.
 #
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 61fe340..d78572b 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -19,6 +19,7 @@
 package com.android.commands.am;
 
 import android.app.ActivityManager;
+import android.app.ActivityManager.StackBoxInfo;
 import android.app.ActivityManagerNative;
 import android.app.IActivityController;
 import android.app.IActivityManager;
@@ -75,6 +76,7 @@
         (new Am()).run(args);
     }
 
+    @Override
     public void onShowUsage(PrintStream out) {
         out.println(
                 "usage: am [subcommand] [options]\n" +
@@ -82,6 +84,7 @@
                 "               [--R COUNT] [-S] [--opengl-trace]\n" +
                 "               [--user <USER_ID> | current] <INTENT>\n" +
                 "       am startservice [--user <USER_ID> | current] <INTENT>\n" +
+                "       am stopservice [--user <USER_ID> | current] <INTENT>\n" +
                 "       am force-stop [--user <USER_ID> | all | current] <PACKAGE>\n" +
                 "       am kill [--user <USER_ID> | all | current] <PACKAGE>\n" +
                 "       am kill-all\n" +
@@ -96,11 +99,17 @@
                 "       am clear-debug-app\n" +
                 "       am monitor [--gdb <port>]\n" +
                 "       am hang [--allow-restart]\n" +
+                "       am restart\n" +
                 "       am screen-compat [on|off] <PACKAGE>\n" +
                 "       am to-uri [INTENT]\n" +
                 "       am to-intent-uri [INTENT]\n" +
                 "       am switch-user <USER_ID>\n" +
                 "       am stop-user <USER_ID>\n" +
+                "       am stack create <TASK_ID> <RELATIVE_STACK_BOX_ID> <POSITION> <WEIGHT>\n" +
+                "       am stack movetask <STACK_ID> <TASK_ID> [true|false]\n" +
+                "       am stack resize <STACK_ID> <WEIGHT>\n" +
+                "       am stack boxes\n" +
+                "       am stack box <STACK_BOX_ID>\n" +
                 "\n" +
                 "am start: start an Activity.  Options are:\n" +
                 "    -D: enable debugging\n" +
@@ -118,6 +127,10 @@
                 "    --user <USER_ID> | current: Specify which user to run as; if not\n" +
                 "        specified then run as the current user.\n" +
                 "\n" +
+                "am stopservice: stop a Service.  Options are:\n" +
+                "    --user <USER_ID> | current: Specify which user to run as; if not\n" +
+                "        specified then run as the current user.\n" +
+                "\n" +
                 "am force-stop: force stop everything associated with <PACKAGE>.\n" +
                 "    --user <USER_ID> | all | current: Specify user to force stop;\n" +
                 "        all users if not specified.\n" +
@@ -146,7 +159,7 @@
                 "        test runners.\n" +
                 "    --user <USER_ID> | current: Specify user instrumentation runs in;\n" +
                 "        current user if not specified.\n" +
-                "    --no-window-animation: turn off window animations will running.\n" +
+                "    --no-window-animation: turn off window animations while running.\n" +
                 "\n" +
                 "am profile: start and stop profiler on a process.  The given <PROCESS> argument\n" +
                 "  may be either a process name or pid.  Options are:\n" +
@@ -174,6 +187,8 @@
                 "am hang: hang the system.\n" +
                 "    --allow-restart: allow watchdog to perform normal system restart\n" +
                 "\n" +
+                "am restart: restart the user-space system.\n" +
+                "\n" +
                 "am screen-compat: control screen compatibility mode of <PACKAGE>.\n" +
                 "\n" +
                 "am to-uri: print the given Intent specification as a URI.\n" +
@@ -186,6 +201,25 @@
                 "am stop-user: stop execution of USER_ID, not allowing it to run any\n" +
                 "  code until a later explicit switch to it.\n" +
                 "\n" +
+                "am stack create: create a new stack relative to an existing one.\n" +
+                "   <TASK_ID>: the task to populate the new stack with. Must exist.\n" +
+                "   <RELATIVE_STACK_BOX_ID>: existing stack box's id.\n" +
+                "   <POSITION>: 0: before <RELATIVE_STACK_BOX_ID>, per RTL/LTR configuration,\n" +
+                "               1: after <RELATIVE_STACK_BOX_ID>, per RTL/LTR configuration,\n" +
+                "               2: to left of <RELATIVE_STACK_BOX_ID>,\n" +
+                "               3: to right of <RELATIVE_STACK_BOX_ID>," +
+                "               4: above <RELATIVE_STACK_BOX_ID>, 5: below <RELATIVE_STACK_BOX_ID>\n" +
+                "   <WEIGHT>: float between 0.2 and 0.8 inclusive.\n" +
+                "\n" +
+                "am stack movetask: move <TASK_ID> from its current stack to the top (true) or" +
+                "   bottom (false) of <STACK_ID>.\n" +
+                "\n" +
+                "am stack resize: change <STACK_ID> relative size to new <WEIGHT>.\n" +
+                "\n" +
+                "am stack boxes: list the hierarchy of stack boxes and their contents.\n" +
+                "\n" +
+                "am stack box: list the hierarchy of stack boxes rooted at <STACK_BOX_ID>.\n" +
+                "\n" +
                 "<INTENT> specifications include these flags and arguments:\n" +
                 "    [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]\n" +
                 "    [-c <CATEGORY> [-c <CATEGORY>] ...]\n" +
@@ -218,6 +252,7 @@
                 );
     }
 
+    @Override
     public void onRun() throws Exception {
 
         mAm = ActivityManagerNative.getDefault();
@@ -232,6 +267,8 @@
             runStart();
         } else if (op.equals("startservice")) {
             runStartService();
+        } else if (op.equals("stopservice")) {
+            runStopService();
         } else if (op.equals("force-stop")) {
             runForceStop();
         } else if (op.equals("kill")) {
@@ -256,6 +293,8 @@
             runMonitor();
         } else if (op.equals("hang")) {
             runHang();
+        } else if (op.equals("restart")) {
+            runRestart();
         } else if (op.equals("screen-compat")) {
             runScreenCompat();
         } else if (op.equals("to-uri")) {
@@ -266,6 +305,8 @@
             runSwitchUser();
         } else if (op.equals("stop-user")) {
             runStopUser();
+        } else if (op.equals("stack")) {
+            runStack();
         } else {
             showError("Error: unknown command '" + op + "'");
         }
@@ -545,6 +586,23 @@
         }
     }
 
+    private void runStopService() throws Exception {
+        Intent intent = makeIntent(UserHandle.USER_CURRENT);
+        if (mUserId == UserHandle.USER_ALL) {
+            System.err.println("Error: Can't stop activity with user 'all'");
+            return;
+        }
+        System.out.println("Stopping service: " + intent);
+        int result = mAm.stopService(null, intent, intent.getType(), mUserId);
+        if (result == 0) {
+            System.err.println("Service not stopped: was not running.");
+        } else if (result == 1) {
+            System.err.println("Service stopped");
+        } else if (result == -1) {
+            System.err.println("Error stopping service");
+        }
+    }
+
     private void runStart() throws Exception {
         Intent intent = makeIntent(UserHandle.USER_CURRENT);
 
@@ -1036,7 +1094,7 @@
         }
 
         @Override
-        public boolean activityResuming(String pkg) throws RemoteException {
+        public boolean activityResuming(String pkg) {
             synchronized (this) {
                 System.out.println("** Activity resuming: " + pkg);
             }
@@ -1044,7 +1102,7 @@
         }
 
         @Override
-        public boolean activityStarting(Intent intent, String pkg) throws RemoteException {
+        public boolean activityStarting(Intent intent, String pkg) {
             synchronized (this) {
                 System.out.println("** Activity starting: " + pkg);
             }
@@ -1053,7 +1111,7 @@
 
         @Override
         public boolean appCrashed(String processName, int pid, String shortMsg, String longMsg,
-                long timeMillis, String stackTrace) throws RemoteException {
+                long timeMillis, String stackTrace) {
             synchronized (this) {
                 System.out.println("** ERROR: PROCESS CRASHED");
                 System.out.println("processName: " + processName);
@@ -1070,8 +1128,7 @@
         }
 
         @Override
-        public int appEarlyNotResponding(String processName, int pid, String annotation)
-                throws RemoteException {
+        public int appEarlyNotResponding(String processName, int pid, String annotation) {
             synchronized (this) {
                 System.out.println("** ERROR: EARLY PROCESS NOT RESPONDING");
                 System.out.println("processName: " + processName);
@@ -1084,8 +1141,7 @@
         }
 
         @Override
-        public int appNotResponding(String processName, int pid, String processStats)
-                throws RemoteException {
+        public int appNotResponding(String processName, int pid, String processStats) {
             synchronized (this) {
                 System.out.println("** ERROR: PROCESS NOT RESPONDING");
                 System.out.println("processName: " + processName);
@@ -1101,8 +1157,7 @@
         }
 
         @Override
-        public int systemNotResponding(String message)
-                throws RemoteException {
+        public int systemNotResponding(String message) {
             synchronized (this) {
                 System.out.println("** ERROR: PROCESS NOT RESPONDING");
                 System.out.println("message: " + message);
@@ -1327,6 +1382,17 @@
         mAm.hang(new Binder(), allowRestart);
     }
 
+    private void runRestart() throws Exception {
+        String opt;
+        while ((opt=nextOption()) != null) {
+            System.err.println("Error: Unknown option: " + opt);
+            return;
+        }
+
+        System.out.println("Restart the system...");
+        mAm.restart();
+    }
+
     private void runScreenCompat() throws Exception {
         String mode = nextArgRequired();
         boolean enabled;
@@ -1361,7 +1427,7 @@
 
         @Override
         public void performReceive(Intent intent, int resultCode, String data, Bundle extras,
-                boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
+                boolean ordered, boolean sticky, int sendingUser) {
             String line = "Broadcast completed: result=" + resultCode;
             if (data != null) line = line + ", data=\"" + data + "\"";
             if (extras != null) line = line + ", extras: " + extras;
@@ -1394,6 +1460,7 @@
             mRawMode = rawMode;
         }
 
+        @Override
         public void instrumentationStatus(ComponentName name, int resultCode, Bundle results) {
             synchronized (this) {
                 // pretty printer mode?
@@ -1416,6 +1483,7 @@
             }
         }
 
+        @Override
         public void instrumentationFinished(ComponentName name, int resultCode,
                 Bundle results) {
             synchronized (this) {
@@ -1456,4 +1524,93 @@
             return true;
         }
     }
+
+    private void runStack() throws Exception {
+        String op = nextArgRequired();
+        if (op.equals("create")) {
+            runStackCreate();
+        } else if (op.equals("movetask")) {
+            runStackMoveTask();
+        } else if (op.equals("resize")) {
+            runStackBoxResize();
+        } else if (op.equals("boxes")) {
+            runStackBoxes();
+        } else if (op.equals("box")) {
+            runStackBoxInfo();
+        } else {
+            showError("Error: unknown command '" + op + "'");
+            return;
+        }
+    }
+
+    private void runStackCreate() throws Exception {
+        String taskIdStr = nextArgRequired();
+        int taskId = Integer.valueOf(taskIdStr);
+        String relativeToStr = nextArgRequired();
+        int relativeTo = Integer.valueOf(relativeToStr);
+        String positionStr = nextArgRequired();
+        int position = Integer.valueOf(positionStr);
+        String weightStr = nextArgRequired();
+        float weight = Float.valueOf(weightStr);
+
+        try {
+            int stackId = mAm.createStack(taskId, relativeTo, position, weight);
+            System.out.println("createStack returned new stackId=" + stackId + "\n\n");
+        } catch (RemoteException e) {
+        }
+    }
+
+    private void runStackMoveTask() throws Exception {
+        String taskIdStr = nextArgRequired();
+        int taskId = Integer.valueOf(taskIdStr);
+        String stackIdStr = nextArgRequired();
+        int stackId = Integer.valueOf(stackIdStr);
+        String toTopStr = nextArgRequired();
+        final boolean toTop;
+        if ("true".equals(toTopStr)) {
+            toTop = true;
+        } else if ("false".equals(toTopStr)) {
+            toTop = false;
+        } else {
+            System.err.println("Error: bad toTop arg: " + toTopStr);
+            return;
+        }
+
+        try {
+            mAm.moveTaskToStack(taskId, stackId, toTop);
+        } catch (RemoteException e) {
+        }
+    }
+
+    private void runStackBoxResize() throws Exception {
+        String stackBoxIdStr = nextArgRequired();
+        int stackBoxId = Integer.valueOf(stackBoxIdStr);
+        String weightStr = nextArgRequired();
+        float weight = Float.valueOf(weightStr);
+
+        try {
+            mAm.resizeStackBox(stackBoxId, weight);
+        } catch (RemoteException e) {
+        }
+    }
+
+    private void runStackBoxes() throws Exception {
+        try {
+            List<StackBoxInfo> stackBoxes = mAm.getStackBoxes();
+            for (StackBoxInfo info : stackBoxes) {
+                System.out.println(info);
+            }
+        } catch (RemoteException e) {
+        }
+    }
+
+    private void runStackBoxInfo() throws Exception {
+        try {
+            String stackBoxIdStr = nextArgRequired();
+            int stackBoxId = Integer.valueOf(stackBoxIdStr);
+            StackBoxInfo stackBoxInfo = mAm.getStackBoxInfo(stackBoxId); 
+            System.out.println(stackBoxInfo);
+        } catch (RemoteException e) {
+        }
+    }
 }
diff --git a/cmds/backup/Android.mk b/cmds/backup/Android.mk
index 73af0bc..42e5133 100644
--- a/cmds/backup/Android.mk
+++ b/cmds/backup/Android.mk
@@ -10,6 +10,6 @@
 LOCAL_MODULE:= btool
 
 LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
-LOCAL_MODULE_TAGS := debug
+LOCAL_MODULE_TAGS := optional
 
 include $(BUILD_EXECUTABLE)
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 8511735..ad4e4c8 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -44,7 +44,7 @@
 
 #include <core/SkBitmap.h>
 #include <core/SkStream.h>
-#include <images/SkImageDecoder.h>
+#include <core/SkImageDecoder.h>
 
 #include <GLES/gl.h>
 #include <GLES/glext.h>
diff --git a/cmds/input/src/com/android/commands/input/Input.java b/cmds/input/src/com/android/commands/input/Input.java
index 80ac539..2a7c79b 100644
--- a/cmds/input/src/com/android/commands/input/Input.java
+++ b/cmds/input/src/com/android/commands/input/Input.java
@@ -24,6 +24,9 @@
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 
+import java.util.HashMap;
+import java.util.Map;
+
 /**
  * Command that sends key events to the device, either by their keycode, or by
  * desired character output.
@@ -31,6 +34,21 @@
 
 public class Input {
     private static final String TAG = "Input";
+    private static final String INVALID_ARGUMENTS = "Error: Invalid arguments for command: ";
+
+    private static final Map<String, Integer> SOURCES = new HashMap<String, Integer>() {{
+        put("keyboard", InputDevice.SOURCE_KEYBOARD);
+        put("dpad", InputDevice.SOURCE_DPAD);
+        put("gamepad", InputDevice.SOURCE_GAMEPAD);
+        put("touchscreen", InputDevice.SOURCE_TOUCHSCREEN);
+        put("mouse", InputDevice.SOURCE_MOUSE);
+        put("stylus", InputDevice.SOURCE_STYLUS);
+        put("trackball", InputDevice.SOURCE_TRACKBALL);
+        put("touchpad", InputDevice.SOURCE_TOUCHPAD);
+        put("touchnavigation", InputDevice.SOURCE_TOUCH_NAVIGATION);
+        put("joystick", InputDevice.SOURCE_JOYSTICK);
+    }};
+
 
     /**
      * Command-line entry point.
@@ -47,82 +65,71 @@
             return;
         }
 
-        String command = args[0];
+        int index = 0;
+        String command = args[index];
+        int inputSource = InputDevice.SOURCE_UNKNOWN;
+        if (SOURCES.containsKey(command)) {
+            inputSource = SOURCES.get(command);
+            index++;
+            command = args[index];
+        }
+        final int length = args.length - index;
 
         try {
             if (command.equals("text")) {
-                if (args.length == 2) {
-                    sendText(args[1]);
+                if (length == 2) {
+                    inputSource = getSource(inputSource, InputDevice.SOURCE_KEYBOARD);
+                    sendText(inputSource, args[index+1]);
                     return;
                 }
             } else if (command.equals("keyevent")) {
-                if (args.length >= 2) {
-                    for (int i=1; i < args.length; i++) {
-                        int keyCode = KeyEvent.keyCodeFromString(args[i]);
-                        if (keyCode == KeyEvent.KEYCODE_UNKNOWN) {
-                            keyCode = KeyEvent.keyCodeFromString("KEYCODE_" + args[i]);
+                if (length >= 2) {
+                    final boolean longpress = "--longpress".equals(args[index + 1]);
+                    final int start = longpress ? index + 2 : index + 1;
+                    inputSource = getSource(inputSource, InputDevice.SOURCE_KEYBOARD);
+                    if (length > start) {
+                        for (int i = start; i < length; i++) {
+                            int keyCode = KeyEvent.keyCodeFromString(args[i]);
+                            if (keyCode == KeyEvent.KEYCODE_UNKNOWN) {
+                                keyCode = KeyEvent.keyCodeFromString("KEYCODE_" + args[i]);
+                            }
+                            sendKeyEvent(inputSource, keyCode, longpress);
                         }
-                        sendKeyEvent(keyCode);
+                        return;
                     }
-                    return;
                 }
             } else if (command.equals("tap")) {
-                if (args.length == 3) {
-                    sendTap(InputDevice.SOURCE_TOUCHSCREEN, Float.parseFloat(args[1]), Float.parseFloat(args[2]));
+                if (length == 3) {
+                    inputSource = getSource(inputSource, InputDevice.SOURCE_TOUCHSCREEN);
+                    sendTap(inputSource, Float.parseFloat(args[index+1]),
+                            Float.parseFloat(args[index+2]));
                     return;
                 }
             } else if (command.equals("swipe")) {
-                if (args.length == 5) {
-                    sendSwipe(InputDevice.SOURCE_TOUCHSCREEN, Float.parseFloat(args[1]), Float.parseFloat(args[2]),
-                            Float.parseFloat(args[3]), Float.parseFloat(args[4]), -1);
+                int duration = -1;
+                inputSource = getSource(inputSource, InputDevice.SOURCE_TOUCHSCREEN);
+                switch (length) {
+                    case 6:
+                        duration = Integer.parseInt(args[index+5]);
+                    case 5:
+                        sendSwipe(inputSource,
+                                Float.parseFloat(args[index+1]), Float.parseFloat(args[index+2]),
+                                Float.parseFloat(args[index+3]), Float.parseFloat(args[index+4]),
+                                duration);
+                        return;
+                }
+            } else if (command.equals("press")) {
+                inputSource = getSource(inputSource, InputDevice.SOURCE_TRACKBALL);
+                if (length == 1) {
+                    sendTap(inputSource, 0.0f, 0.0f);
                     return;
                 }
-            } else if (command.equals("touchscreen") || command.equals("touchpad")
-                    || command.equals("touchnavigation")) {
-                // determine input source
-                int inputSource = InputDevice.SOURCE_TOUCHSCREEN;
-                if (command.equals("touchpad")) {
-                    inputSource = InputDevice.SOURCE_TOUCHPAD;
-                } else if (command.equals("touchnavigation")) {
-                    inputSource = InputDevice.SOURCE_TOUCH_NAVIGATION;
-                }
-                // determine subcommand
-                if (args.length > 1) {
-                    String subcommand = args[1];
-                    if (subcommand.equals("tap")) {
-                        if (args.length == 4) {
-                            sendTap(inputSource, Float.parseFloat(args[2]),
-                                    Float.parseFloat(args[3]));
-                            return;
-                        }
-                    } else if (subcommand.equals("swipe")) {
-                        if (args.length == 6) {
-                            sendSwipe(inputSource, Float.parseFloat(args[2]),
-                                    Float.parseFloat(args[3]), Float.parseFloat(args[4]),
-                                    Float.parseFloat(args[5]), -1);
-                            return;
-                        } else if (args.length == 7) {
-                            sendSwipe(inputSource, Float.parseFloat(args[2]),
-                                    Float.parseFloat(args[3]), Float.parseFloat(args[4]),
-                                    Float.parseFloat(args[5]), Integer.parseInt(args[6]));
-                            return;
-                        }
-                    }
-                }
-            } else if (command.equals("trackball")) {
-                // determine subcommand
-                if (args.length > 1) {
-                    String subcommand = args[1];
-                    if (subcommand.equals("press")) {
-                        sendTap(InputDevice.SOURCE_TRACKBALL, 0.0f, 0.0f);
-                        return;
-                    } else if (subcommand.equals("roll")) {
-                        if (args.length == 4) {
-                            sendMove(InputDevice.SOURCE_TRACKBALL, Float.parseFloat(args[2]),
-                                    Float.parseFloat(args[3]));
-                            return;
-                        }
-                    }
+            } else if (command.equals("roll")) {
+                inputSource = getSource(inputSource, InputDevice.SOURCE_TRACKBALL);
+                if (length == 3) {
+                    sendMove(inputSource, Float.parseFloat(args[index+1]),
+                            Float.parseFloat(args[index+2]));
+                    return;
                 }
             } else {
                 System.err.println("Error: Unknown command: " + command);
@@ -131,7 +138,7 @@
             }
         } catch (NumberFormatException ex) {
         }
-        System.err.println("Error: Invalid arguments for command: " + command);
+        System.err.println(INVALID_ARGUMENTS + command);
         showUsage();
     }
 
@@ -141,7 +148,7 @@
      *
      * @param text is a string of characters you want to input to the device.
      */
-    private void sendText(String text) {
+    private void sendText(int source, String text) {
 
         StringBuffer buff = new StringBuffer(text);
 
@@ -153,7 +160,7 @@
                     buff.setCharAt(i, ' ');
                     buff.deleteCharAt(--i);
                 }
-            } 
+            }
             if (buff.charAt(i) == '%') {
                 escapeFlag = true;
             }
@@ -164,16 +171,25 @@
         KeyCharacterMap kcm = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
         KeyEvent[] events = kcm.getEvents(chars);
         for(int i = 0; i < events.length; i++) {
-            injectKeyEvent(events[i]);
+            KeyEvent e = events[i];
+            if (source != e.getSource()) {
+                e.setSource(source);
+            }
+            injectKeyEvent(e);
         }
     }
 
-    private void sendKeyEvent(int keyCode) {
+    private void sendKeyEvent(int inputSource, int keyCode, boolean longpress) {
         long now = SystemClock.uptimeMillis();
         injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keyCode, 0, 0,
-                KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD));
+                KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, inputSource));
+        if (longpress) {
+            injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keyCode, 1, 0,
+                    KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_LONG_PRESS,
+                    inputSource));
+        }
         injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_UP, keyCode, 0, 0,
-                KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD));
+                KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, inputSource));
     }
 
     private void sendTap(int inputSource, float x, float y) {
@@ -197,7 +213,7 @@
                     lerp(y1, y2, alpha), 1.0f);
             now = SystemClock.uptimeMillis();
         }
-        injectMotionEvent(inputSource, MotionEvent.ACTION_UP, now, x1, y1, 0.0f);
+        injectMotionEvent(inputSource, MotionEvent.ACTION_UP, now, x2, y2, 0.0f);
     }
 
     /**
@@ -248,14 +264,26 @@
         return (b - a) * alpha + a;
     }
 
+    private static final int getSource(int inputSource, int defaultSource) {
+        return inputSource == InputDevice.SOURCE_UNKNOWN ? defaultSource : inputSource;
+    }
+
     private void showUsage() {
-        System.err.println("usage: input ...");
-        System.err.println("       input text <string>");
-        System.err.println("       input keyevent <key code number or name> ...");
-        System.err.println("       input [touchscreen|touchpad|touchnavigation] tap <x> <y>");
-        System.err.println("       input [touchscreen|touchpad|touchnavigation] swipe "
-                + "<x1> <y1> <x2> <y2> [duration(ms)]");
-        System.err.println("       input trackball press");
-        System.err.println("       input trackball roll <dx> <dy>");
+        System.err.println("Usage: input [<source>] <command> [<arg>...]");
+        System.err.println();
+        System.err.println("The sources are: ");
+        for (String src : SOURCES.keySet()) {
+            System.err.println("      " + src);
+        }
+        System.err.println();
+        System.err.println("The commands and default sources are:");
+        System.err.println("      text <string> (Default: touchscreen)");
+        System.err.println("      keyevent [--longpress] <key code number or name> ..."
+                + " (Default: keyboard)");
+        System.err.println("      tap <x> <y> (Default: touchscreen)");
+        System.err.println("      swipe <x1> <y1> <x2> <y2> [duration(ms)]"
+                + " (Default: touchscreen)");
+        System.err.println("      press (Default: trackball)");
+        System.err.println("      roll <dx> <dy> (Default: trackball)");
     }
 }
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 224945a..d1ded10 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -16,8 +16,7 @@
 
 package com.android.commands.pm;
 
-import com.android.internal.content.PackageHelper;
-
+import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
 import android.content.ComponentName;
 import android.content.pm.ApplicationInfo;
@@ -46,6 +45,7 @@
 import android.os.UserManager;
 
 import java.io.File;
+import java.io.FileDescriptor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 import java.security.InvalidAlgorithmParameterException;
@@ -59,6 +59,8 @@
 import javax.crypto.spec.IvParameterSpec;
 import javax.crypto.spec.SecretKeySpec;
 
+import com.android.internal.content.PackageHelper;
+
 public final class Pm {
     IPackageManager mPm;
     IUserManager mUm;
@@ -105,6 +107,11 @@
             return;
         }
 
+        if ("dump".equals(op)) {
+            runDump();
+            return;
+        }
+
         if ("install".equals(op)) {
             runInstall();
             return;
@@ -140,6 +147,16 @@
             return;
         }
 
+        if ("block".equals(op)) {
+            runSetBlockedSetting(true);
+            return;
+        }
+
+        if ("unblock".equals(op)) {
+            runSetBlockedSetting(false);
+            return;
+        }
+
         if ("grant".equals(op)) {
             runGrantRevokePermission(true);
             return;
@@ -672,6 +689,15 @@
         displayPackageFilePath(pkg);
     }
 
+    private void runDump() {
+        String pkg = nextArg();
+        if (pkg == null) {
+            System.err.println("Error: no package specified");
+            return;
+        }
+        ActivityManager.dumpPackageStateStatic(FileDescriptor.out, pkg);
+    }
+
     class PackageInstallObserver extends IPackageInstallObserver.Stub {
         boolean finished;
         int result;
@@ -1240,6 +1266,36 @@
         }
     }
 
+    private void runSetBlockedSetting(boolean state) {
+        int userId = 0;
+        String option = nextOption();
+        if (option != null && option.equals("--user")) {
+            String optionData = nextOptionData();
+            if (optionData == null || !isNumber(optionData)) {
+                System.err.println("Error: no USER_ID specified");
+                showUsage();
+                return;
+            } else {
+                userId = Integer.parseInt(optionData);
+            }
+        }
+
+        String pkg = nextArg();
+        if (pkg == null) {
+            System.err.println("Error: no package or component specified");
+            showUsage();
+            return;
+        }
+        try {
+            mPm.setApplicationBlockedSettingAsUser(pkg, state, userId);
+            System.err.println("Package " + pkg + " new blocked state: "
+                    + mPm.getApplicationBlockedSettingAsUser(pkg, userId));
+        } catch (RemoteException e) {
+            System.err.println(e.toString());
+            System.err.println(PM_NOT_RUNNING_ERR);
+        }
+    }
+
     private void runGrantRevokePermission(boolean grant) {
         String pkg = nextArg();
         if (pkg == null) {
@@ -1456,6 +1512,7 @@
         System.err.println("       pm list libraries");
         System.err.println("       pm list users");
         System.err.println("       pm path PACKAGE");
+        System.err.println("       pm dump PACKAGE");
         System.err.println("       pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f]");
         System.err.println("                  [--algo <algorithm name> --key <key-in-hex> --iv <IV-in-hex>]");
         System.err.println("                  [--originating-uri <URI>] [--referrer <URI>] PATH");
@@ -1465,6 +1522,8 @@
         System.err.println("       pm disable [--user USER_ID] PACKAGE_OR_COMPONENT");
         System.err.println("       pm disable-user [--user USER_ID] PACKAGE_OR_COMPONENT");
         System.err.println("       pm disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT");
+        System.err.println("       pm block [--user USER_ID] PACKAGE_OR_COMPONENT");
+        System.err.println("       pm unblock [--user USER_ID] PACKAGE_OR_COMPONENT");
         System.err.println("       pm grant PACKAGE PERMISSION");
         System.err.println("       pm revoke PACKAGE PERMISSION");
         System.err.println("       pm set-install-location [0/auto] [1/internal] [2/external]");
@@ -1506,6 +1565,8 @@
         System.err.println("");
         System.err.println("pm path: print the path to the .apk of the given PACKAGE.");
         System.err.println("");
+        System.err.println("pm dump: print system state associated w ith the given PACKAGE.");
+        System.err.println("");
         System.err.println("pm install: installs a package to the system.  Options:");
         System.err.println("    -l: install the package with FORWARD_LOCK.");
         System.err.println("    -r: reinstall an exisiting app, keeping its data.");
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index be32355..a57de01 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -55,12 +55,8 @@
 static SkBitmap::Config flinger2skia(PixelFormat f)
 {
     switch (f) {
-        case PIXEL_FORMAT_A_8:
-            return SkBitmap::kA8_Config;
         case PIXEL_FORMAT_RGB_565:
             return SkBitmap::kRGB_565_Config;
-        case PIXEL_FORMAT_RGBA_4444:
-            return SkBitmap::kARGB_4444_Config;
         default:
             return SkBitmap::kARGB_8888_Config;
     }
diff --git a/cmds/system_server/Android.mk b/cmds/system_server/Android.mk
deleted file mode 100644
index 3083e31..0000000
--- a/cmds/system_server/Android.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-	system_main.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-	libutils \
-	libbinder \
-	libsystem_server \
-	liblog
-
-LOCAL_C_INCLUDES := \
-	$(JNI_H_INCLUDE)
-
-LOCAL_MODULE:= system_server
-
-include $(BUILD_EXECUTABLE)
-
-include $(LOCAL_PATH)/library/Android.mk
diff --git a/cmds/system_server/library/Android.mk b/cmds/system_server/library/Android.mk
deleted file mode 100644
index d78474e..0000000
--- a/cmds/system_server/library/Android.mk
+++ /dev/null
@@ -1,27 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-	system_init.cpp
-
-base = $(LOCAL_PATH)/../../..
-native = $(LOCAL_PATH)/../../../../native
-
-LOCAL_C_INCLUDES := \
-	$(native)/services/sensorservice \
-	$(native)/services/surfaceflinger \
-	$(JNI_H_INCLUDE)
-
-LOCAL_SHARED_LIBRARIES := \
-	libandroid_runtime \
-	libsensorservice \
-	libsurfaceflinger \
-	libinput \
-	libutils \
-	libbinder \
-	libcutils \
-	liblog
-
-LOCAL_MODULE:= libsystem_server
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/cmds/system_server/library/system_init.cpp b/cmds/system_server/library/system_init.cpp
deleted file mode 100644
index 745c34a..0000000
--- a/cmds/system_server/library/system_init.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * System server main initialization.
- *
- * The system server is responsible for becoming the Binder
- * context manager, supplying the root ServiceManager object
- * through which other services can be found.
- */
-
-#define LOG_TAG "sysproc"
-
-#include <binder/IPCThreadState.h>
-#include <binder/ProcessState.h>
-#include <binder/IServiceManager.h>
-#include <utils/TextOutput.h>
-#include <utils/Log.h>
-
-#include <SurfaceFlinger.h>
-#include <SensorService.h>
-
-#include <android_runtime/AndroidRuntime.h>
-
-#include <signal.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include <cutils/properties.h>
-
-using namespace android;
-
-namespace android {
-/**
- * This class is used to kill this process when the runtime dies.
- */
-class GrimReaper : public IBinder::DeathRecipient {
-public:
-    GrimReaper() { }
-
-    virtual void binderDied(const wp<IBinder>& who)
-    {
-        ALOGI("Grim Reaper killing system_server...");
-        kill(getpid(), SIGKILL);
-    }
-};
-
-} // namespace android
-
-
-
-extern "C" status_t system_init()
-{
-    ALOGI("Entered system_init()");
-
-    sp<ProcessState> proc(ProcessState::self());
-
-    sp<IServiceManager> sm = defaultServiceManager();
-    ALOGI("ServiceManager: %p\n", sm.get());
-
-    sp<GrimReaper> grim = new GrimReaper();
-    sm->asBinder()->linkToDeath(grim, grim.get(), 0);
-
-    char propBuf[PROPERTY_VALUE_MAX];
-    property_get("system_init.startsurfaceflinger", propBuf, "1");
-    if (strcmp(propBuf, "1") == 0) {
-        // Start the SurfaceFlinger
-        SurfaceFlinger::instantiate();
-    }
-
-    property_get("system_init.startsensorservice", propBuf, "1");
-    if (strcmp(propBuf, "1") == 0) {
-        // Start the sensor service
-        SensorService::instantiate();
-    }
-
-    // And now start the Android runtime.  We have to do this bit
-    // of nastiness because the Android runtime initialization requires
-    // some of the core system services to already be started.
-    // All other servers should just start the Android runtime at
-    // the beginning of their processes's main(), before calling
-    // the init function.
-    ALOGI("System server: starting Android runtime.\n");
-    AndroidRuntime* runtime = AndroidRuntime::getRuntime();
-
-    ALOGI("System server: starting Android services.\n");
-    JNIEnv* env = runtime->getJNIEnv();
-    if (env == NULL) {
-        return UNKNOWN_ERROR;
-    }
-    jclass clazz = env->FindClass("com/android/server/SystemServer");
-    if (clazz == NULL) {
-        return UNKNOWN_ERROR;
-    }
-    jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V");
-    if (methodId == NULL) {
-        return UNKNOWN_ERROR;
-    }
-    env->CallStaticVoidMethod(clazz, methodId);
-
-    ALOGI("System server: entering thread pool.\n");
-    ProcessState::self()->startThreadPool();
-    IPCThreadState::self()->joinThreadPool();
-    ALOGI("System server: exiting thread pool.\n");
-
-    return NO_ERROR;
-}
diff --git a/cmds/system_server/system_main.cpp b/cmds/system_server/system_main.cpp
deleted file mode 100644
index ddff065..0000000
--- a/cmds/system_server/system_main.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Main entry of system server process.
- * 
- * Calls the standard system initialization function, and then
- * puts the main thread into the thread pool so it can handle
- * incoming transactions.
- * 
- */
-
-#define LOG_TAG "sysproc"
-
-#include <binder/IPCThreadState.h>
-#include <utils/Log.h>
-
-#include <private/android_filesystem_config.h>
-
-#include <sys/time.h>
-#include <sys/resource.h>
-
-#include <signal.h>
-#include <stdio.h>
-#include <unistd.h>
-
-using namespace android;
-
-extern "C" status_t system_init();
-
-bool finish_system_init()
-{
-    return true;
-}
-
-static void blockSignals()
-{
-    sigset_t mask;
-    int cc;
-    
-    sigemptyset(&mask);
-    sigaddset(&mask, SIGQUIT);
-    sigaddset(&mask, SIGUSR1);
-    cc = sigprocmask(SIG_BLOCK, &mask, NULL);
-    assert(cc == 0);
-}
-
-int main(int argc, const char* const argv[])
-{
-    ALOGI("System server is starting with pid=%d.\n", getpid());
-
-    blockSignals();
-    
-    // You can trust me, honestly!
-    ALOGW("*** Current priority: %d\n", getpriority(PRIO_PROCESS, 0));
-    setpriority(PRIO_PROCESS, 0, -1);
-
-    system_init();    
-}
diff --git a/core/java/android/accounts/ChooseTypeAndAccountActivity.java b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
index 58eb66f..82c2159 100644
--- a/core/java/android/accounts/ChooseTypeAndAccountActivity.java
+++ b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
@@ -29,6 +29,7 @@
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.View;
+import android.view.Window;
 import android.widget.AdapterView;
 import android.widget.ArrayAdapter;
 import android.widget.Button;
@@ -127,6 +128,7 @@
     private int mCallingUid;
     private String mCallingPackage;
     private boolean mDisallowAddAccounts;
+    private boolean mDontShowPicker;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
@@ -189,11 +191,23 @@
         mSetOfRelevantAccountTypes = getReleventAccountTypes(intent);
         mAlwaysPromptForAccount = intent.getBooleanExtra(EXTRA_ALWAYS_PROMPT_FOR_ACCOUNT, false);
         mDescriptionOverride = intent.getStringExtra(EXTRA_DESCRIPTION_TEXT_OVERRIDE);
+
+        // Need to do this once here to request the window feature. Can't do it in onResume
+        mAccounts = getAcceptableAccountChoices(AccountManager.get(this));
+        if (mAccounts.isEmpty()
+                && mDisallowAddAccounts) {
+            requestWindowFeature(Window.FEATURE_NO_TITLE);
+            setContentView(R.layout.app_not_authorized);
+            mDontShowPicker = true;
+        }
     }
 
     @Override
     protected void onResume() {
         super.onResume();
+
+        if (mDontShowPicker) return;
+
         final AccountManager accountManager = AccountManager.get(this);
 
         mAccounts = getAcceptableAccountChoices(accountManager);
@@ -206,11 +220,6 @@
             // If there are no relevant accounts and only one relevant account type go directly to
             // add account. Otherwise let the user choose.
             if (mAccounts.isEmpty()) {
-                if (mDisallowAddAccounts) {
-                    setContentView(R.layout.app_not_authorized);
-                    setTitle(R.string.error_message_title);
-                    return;
-                }
                 if (mSetOfRelevantAccountTypes.size() == 1) {
                     runAddAccountForAuthenticator(mSetOfRelevantAccountTypes.iterator().next());
                 } else {
diff --git a/core/java/android/animation/Animator.java b/core/java/android/animation/Animator.java
index 39eb8d6..129e52c 100644
--- a/core/java/android/animation/Animator.java
+++ b/core/java/android/animation/Animator.java
@@ -30,6 +30,17 @@
     ArrayList<AnimatorListener> mListeners = null;
 
     /**
+     * The set of listeners to be sent pause/resume events through the life
+     * of an animation.
+     */
+    ArrayList<AnimatorPauseListener> mPauseListeners = null;
+
+    /**
+     * Whether this animator is currently in a paused state.
+     */
+    boolean mPaused = false;
+
+    /**
      * Starts this animation. If the animation has a nonzero startDelay, the animation will start
      * running after that delay elapses. A non-delayed animation will have its initial
      * value(s) set immediately, followed by calls to
@@ -69,6 +80,66 @@
     }
 
     /**
+     * Pauses a running animation. This method should only be called on the same thread on
+     * which the animation was started. If the animation has not yet been {@link
+     * #isStarted() started} or has since ended, then the call is ignored. Paused
+     * animations can be resumed by calling {@link #resume()}.
+     *
+     * @see #resume()
+     * @see #isPaused()
+     * @see AnimatorPauseListener
+     */
+    public void pause() {
+        if (isStarted() && !mPaused) {
+            mPaused = true;
+            if (mPauseListeners != null) {
+                ArrayList<AnimatorPauseListener> tmpListeners =
+                        (ArrayList<AnimatorPauseListener>) mPauseListeners.clone();
+                int numListeners = tmpListeners.size();
+                for (int i = 0; i < numListeners; ++i) {
+                    tmpListeners.get(i).onAnimationPause(this);
+                }
+            }
+        }
+    }
+
+    /**
+     * Resumes a paused animation, causing the animator to pick up where it left off
+     * when it was paused. This method should only be called on the same thread on
+     * which the animation was started. Calls to resume() on an animator that is
+     * not currently paused will be ignored.
+     *
+     * @see #pause()
+     * @see #isPaused()
+     * @see AnimatorPauseListener
+     */
+    public void resume() {
+        if (mPaused) {
+            mPaused = false;
+            if (mPauseListeners != null) {
+                ArrayList<AnimatorPauseListener> tmpListeners =
+                        (ArrayList<AnimatorPauseListener>) mPauseListeners.clone();
+                int numListeners = tmpListeners.size();
+                for (int i = 0; i < numListeners; ++i) {
+                    tmpListeners.get(i).onAnimationResume(this);
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns whether this animator is currently in a paused state.
+     *
+     * @return True if the animator is currently paused, false otherwise.
+     *
+     * @see #pause()
+     * @see #resume()
+     */
+    public boolean isPaused() {
+        return mPaused;
+    }
+
+    /**
      * The amount of time, in milliseconds, to delay processing the animation
      * after {@link #start()} is called.
      *
@@ -180,15 +251,48 @@
     }
 
     /**
-     * Removes all listeners from this object. This is equivalent to calling
-     * <code>getListeners()</code> followed by calling <code>clear()</code> on the
-     * returned list of listeners.
+     * Adds a pause listener to this animator.
+     *
+     * @param listener the listener to be added to the current set of pause listeners
+     * for this animation.
+     */
+    public void addPauseListener(AnimatorPauseListener listener) {
+        if (mPauseListeners == null) {
+            mPauseListeners = new ArrayList<AnimatorPauseListener>();
+        }
+        mPauseListeners.add(listener);
+    }
+
+    /**
+     * Removes a pause listener from the set listening to this animation.
+     *
+     * @param listener the listener to be removed from the current set of pause
+     * listeners for this animation.
+     */
+    public void removePauseListener(AnimatorPauseListener listener) {
+        if (mPauseListeners == null) {
+            return;
+        }
+        mPauseListeners.remove(listener);
+        if (mPauseListeners.size() == 0) {
+            mPauseListeners = null;
+        }
+    }
+
+    /**
+     * Removes all {@link #addListener(android.animation.Animator.AnimatorListener) listeners}
+     * and {@link #addPauseListener(android.animation.Animator.AnimatorPauseListener)
+     * pauseListeners} from this object.
      */
     public void removeAllListeners() {
         if (mListeners != null) {
             mListeners.clear();
             mListeners = null;
         }
+        if (mPauseListeners != null) {
+            mPauseListeners.clear();
+            mPauseListeners = null;
+        }
     }
 
     @Override
@@ -203,6 +307,14 @@
                     anim.mListeners.add(oldListeners.get(i));
                 }
             }
+            if (mPauseListeners != null) {
+                ArrayList<AnimatorPauseListener> oldListeners = mPauseListeners;
+                anim.mPauseListeners = new ArrayList<AnimatorPauseListener>();
+                int numListeners = oldListeners.size();
+                for (int i = 0; i < numListeners; ++i) {
+                    anim.mPauseListeners.add(oldListeners.get(i));
+                }
+            }
             return anim;
         } catch (CloneNotSupportedException e) {
            throw new AssertionError();
@@ -280,4 +392,29 @@
          */
         void onAnimationRepeat(Animator animation);
     }
+
+    /**
+     * A pause listener receives notifications from an animation when the
+     * animation is {@link #pause() paused} or {@link #resume() resumed}.
+     *
+     * @see #addPauseListener(AnimatorPauseListener)
+     */
+    public static interface AnimatorPauseListener {
+        /**
+         * <p>Notifies that the animation was paused.</p>
+         *
+         * @param animation The animaton being paused.
+         * @see #pause()
+         */
+        void onAnimationPause(Animator animation);
+
+        /**
+         * <p>Notifies that the animation was resumed, after being
+         * previously paused.</p>
+         *
+         * @param animation The animation being resumed.
+         * @see #resume()
+         */
+        void onAnimationResume(Animator animation);
+    }
 }
diff --git a/core/java/android/animation/AnimatorListenerAdapter.java b/core/java/android/animation/AnimatorListenerAdapter.java
index e5d70a4..2ecb8c3 100644
--- a/core/java/android/animation/AnimatorListenerAdapter.java
+++ b/core/java/android/animation/AnimatorListenerAdapter.java
@@ -21,7 +21,8 @@
  * Any custom listener that cares only about a subset of the methods of this listener can
  * simply subclass this adapter class instead of implementing the interface directly.
  */
-public abstract class AnimatorListenerAdapter implements Animator.AnimatorListener {
+public abstract class AnimatorListenerAdapter implements Animator.AnimatorListener,
+        Animator.AnimatorPauseListener {
 
     /**
      * {@inheritDoc}
@@ -51,4 +52,17 @@
     public void onAnimationStart(Animator animation) {
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onAnimationPause(Animator animation) {
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onAnimationResume(Animator animation) {
+    }
 }
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index b48853b..018a2d6 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -455,6 +455,36 @@
         }
     }
 
+    @Override
+    public void pause() {
+        boolean previouslyPaused = mPaused;
+        super.pause();
+        if (!previouslyPaused && mPaused) {
+            if (mDelayAnim != null) {
+                mDelayAnim.pause();
+            } else {
+                for (Node node : mNodes) {
+                    node.animation.pause();
+                }
+            }
+        }
+    }
+
+    @Override
+    public void resume() {
+        boolean previouslyPaused = mPaused;
+        super.resume();
+        if (previouslyPaused && !mPaused) {
+            if (mDelayAnim != null) {
+                mDelayAnim.resume();
+            } else {
+                for (Node node : mNodes) {
+                    node.animation.resume();
+                }
+            }
+        }
+    }
+
     /**
      * {@inheritDoc}
      *
@@ -467,6 +497,7 @@
     public void start() {
         mTerminated = false;
         mStarted = true;
+        mPaused = false;
 
         if (mDuration >= 0) {
             // If the duration was set on this AnimatorSet, pass it along to all child animations
@@ -549,6 +580,7 @@
                             mPlayingSet.add(node.animation);
                         }
                     }
+                    mDelayAnim = null;
                 }
             });
             mDelayAnim.start();
@@ -787,6 +819,7 @@
                         }
                     }
                     mAnimatorSet.mStarted = false;
+                    mAnimatorSet.mPaused = false;
                 }
             }
         }
diff --git a/core/java/android/animation/ObjectAnimator.java b/core/java/android/animation/ObjectAnimator.java
index 173ee73..9c88ccf 100644
--- a/core/java/android/animation/ObjectAnimator.java
+++ b/core/java/android/animation/ObjectAnimator.java
@@ -123,9 +123,37 @@
      * in a call to the function <code>setFoo()</code> on the target object. If either
      * <code>valueFrom</code> or <code>valueTo</code> is null, then a getter function will
      * also be derived and called.
+     *
+     * <p>If this animator was created with a {@link Property} object instead of the
+     * string name of a property, then this method will return the {@link
+     * Property#getName() name} of that Property object instead. If this animator was
+     * created with one or more {@link PropertyValuesHolder} objects, then this method
+     * will return the {@link PropertyValuesHolder#getPropertyName() name} of that
+     * object (if there was just one) or a comma-separated list of all of the
+     * names (if there are more than one).</p>
      */
     public String getPropertyName() {
-        return mPropertyName;
+        String propertyName = null;
+        if (mPropertyName != null) {
+            propertyName = mPropertyName;
+        } else if (mProperty != null) {
+            propertyName = mProperty.getName();
+        } else if (mValues != null && mValues.length > 0) {
+            for (int i = 0; i < mValues.length; ++i) {
+                if (i == 0) {
+                    propertyName = "";
+                } else {
+                    propertyName += ",";
+                }
+                propertyName += mValues[i].getPropertyName();
+            }
+        }
+        return propertyName;
+    }
+
+    @Override
+    String getNameForTrace() {
+        return "animator:" + getPropertyName();
     }
 
     /**
diff --git a/core/java/android/animation/PropertyValuesHolder.java b/core/java/android/animation/PropertyValuesHolder.java
index 5b1a7cf..43014ad 100644
--- a/core/java/android/animation/PropertyValuesHolder.java
+++ b/core/java/android/animation/PropertyValuesHolder.java
@@ -636,7 +636,7 @@
     }
 
     /**
-     * The TypeEvaluator will the automatically determined based on the type of values
+     * The TypeEvaluator will be automatically determined based on the type of values
      * supplied to PropertyValuesHolder. The evaluator can be manually set, however, if so
      * desired. This may be important in cases where either the type of the values supplied
      * do not match the way that they should be interpolated between, or if the values
diff --git a/core/java/android/animation/TypeEvaluator.java b/core/java/android/animation/TypeEvaluator.java
index e738da1..2640457 100644
--- a/core/java/android/animation/TypeEvaluator.java
+++ b/core/java/android/animation/TypeEvaluator.java
@@ -19,7 +19,7 @@
 /**
  * Interface for use with the {@link ValueAnimator#setEvaluator(TypeEvaluator)} function. Evaluators
  * allow developers to create animations on arbitrary property types, by allowing them to supply
- * custom evaulators for types that are not automatically understood and used by the animation
+ * custom evaluators for types that are not automatically understood and used by the animation
  * system.
  *
  * @see ValueAnimator#setEvaluator(TypeEvaluator)
@@ -41,4 +41,4 @@
      */
     public T evaluate(float fraction, T startValue, T endValue);
 
-}
\ No newline at end of file
+}
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index cb44264..86da673 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -80,6 +80,20 @@
      */
     long mSeekTime = -1;
 
+    /**
+     * Set on the next frame after pause() is called, used to calculate a new startTime
+     * or delayStartTime which allows the animator to continue from the point at which
+     * it was paused. If negative, has not yet been set.
+     */
+    private long mPauseTime;
+
+    /**
+     * Set when an animator is resumed. This triggers logic in the next frame which
+     * actually resumes the animator.
+     */
+    private boolean mResumed = false;
+
+
     // The static sAnimationHandler processes the internal timing loop on which all animations
     // are based
     /**
@@ -147,7 +161,7 @@
     private boolean mStarted = false;
 
     /**
-     * Tracks whether we've notified listeners of the onAnimationSTart() event. This can be
+     * Tracks whether we've notified listeners of the onAnimationStart() event. This can be
      * complex to keep track of since we notify listeners at different times depending on
      * startDelay and whether start() was called before end().
      */
@@ -869,7 +883,7 @@
      *
      * <p>If this ValueAnimator has only one set of values being animated between, this evaluator
      * will be used for that set. If there are several sets of values being animated, which is
-     * the case if PropertyValuesHOlder objects were set on the ValueAnimator, then the evaluator
+     * the case if PropertyValuesHolder objects were set on the ValueAnimator, then the evaluator
      * is assigned just to the first PropertyValuesHolder object.</p>
      *
      * @param value the evaluator to be used this animation
@@ -914,6 +928,7 @@
         mPlayingState = STOPPED;
         mStarted = true;
         mStartedDelay = false;
+        mPaused = false;
         AnimationHandler animationHandler = getOrCreateAnimationHandler();
         animationHandler.mPendingAnimations.add(this);
         if (mStartDelay == 0) {
@@ -971,6 +986,24 @@
     }
 
     @Override
+    public void resume() {
+        if (mPaused) {
+            mResumed = true;
+        }
+        super.resume();
+    }
+
+    @Override
+    public void pause() {
+        boolean previouslyPaused = mPaused;
+        super.pause();
+        if (!previouslyPaused && mPaused) {
+            mPauseTime = -1;
+            mResumed = false;
+        }
+    }
+
+    @Override
     public boolean isRunning() {
         return (mPlayingState == RUNNING || mRunning);
     }
@@ -994,6 +1027,8 @@
             long currentPlayTime = currentTime - mStartTime;
             long timeLeft = mDuration - currentPlayTime;
             mStartTime = currentTime - timeLeft;
+        } else if (mStarted) {
+            end();
         } else {
             start(true);
         }
@@ -1008,6 +1043,7 @@
         handler.mPendingAnimations.remove(this);
         handler.mDelayedAnims.remove(this);
         mPlayingState = STOPPED;
+        mPaused = false;
         if ((mStarted || mRunning) && mListeners != null) {
             if (!mRunning) {
                 // If it's not yet running, then start listeners weren't called. Call them now.
@@ -1024,8 +1060,10 @@
         mStarted = false;
         mStartListenersCalled = false;
         mPlayingBackwards = false;
-        Trace.asyncTraceEnd(Trace.TRACE_TAG_VIEW, "animator",
-                System.identityHashCode(this));
+        if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+            Trace.asyncTraceEnd(Trace.TRACE_TAG_VIEW, getNameForTrace(),
+                    System.identityHashCode(this));
+        }
     }
 
     /**
@@ -1033,8 +1071,10 @@
      * called on the UI thread.
      */
     private void startAnimation(AnimationHandler handler) {
-        Trace.asyncTraceBegin(Trace.TRACE_TAG_VIEW, "animator",
-                System.identityHashCode(this));
+        if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+            Trace.asyncTraceBegin(Trace.TRACE_TAG_VIEW, getNameForTrace(),
+                    System.identityHashCode(this));
+        }
         initAnimation();
         handler.mAnimations.add(this);
         if (mStartDelay > 0 && mListeners != null) {
@@ -1045,6 +1085,14 @@
     }
 
     /**
+     * Returns the name of this animator for debugging purposes.
+     */
+    String getNameForTrace() {
+        return "animator";
+    }
+
+
+    /**
      * Internal function called to process an animation frame on an animation that is currently
      * sleeping through its <code>startDelay</code> phase. The return value indicates whether it
      * should be woken up and put on the active animations queue.
@@ -1059,6 +1107,18 @@
             mStartedDelay = true;
             mDelayStartTime = currentTime;
         } else {
+            if (mPaused) {
+                if (mPauseTime < 0) {
+                    mPauseTime = currentTime;
+                }
+                return false;
+            } else if (mResumed) {
+                mResumed = false;
+                if (mPauseTime > 0) {
+                    // Offset by the duration that the animation was paused
+                    mDelayStartTime += (currentTime - mPauseTime);
+                }
+            }
             long deltaTime = currentTime - mDelayStartTime;
             if (deltaTime > mStartDelay) {
                 // startDelay ended - start the anim and record the
@@ -1081,7 +1141,7 @@
      *
      * @param currentTime The current time, as tracked by the static timing handler
      * @return true if the animation's duration, including any repetitions due to
-     * <code>repeatCount</code> has been exceeded and the animation should be ended.
+     * <code>repeatCount</code>, has been exceeded and the animation should be ended.
      */
     boolean animationFrame(long currentTime) {
         boolean done = false;
@@ -1136,6 +1196,18 @@
                 mSeekTime = -1;
             }
         }
+        if (mPaused) {
+            if (mPauseTime < 0) {
+                mPauseTime = frameTime;
+            }
+            return false;
+        } else if (mResumed) {
+            mResumed = false;
+            if (mPauseTime > 0) {
+                // Offset by the duration that the animation was paused
+                mStartTime += (frameTime - mPauseTime);
+            }
+        }
         // The frame time might be before the start time during the first frame of
         // an animation.  The "current time" must always be on or after the start
         // time to avoid animating frames at negative time intervals.  In practice, this
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 6b5df7f..a38fbbf 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -16,6 +16,8 @@
 
 package android.app;
 
+import android.util.ArrayMap;
+import android.util.SuperNotCalledException;
 import com.android.internal.app.ActionBarImpl;
 import com.android.internal.policy.PolicyManager;
 
@@ -686,6 +688,7 @@
     boolean mFinished;
     boolean mStartedActivity;
     private boolean mDestroyed;
+    private boolean mDoReportFullyDrawn = true;
     /** true if the activity is going through a transient pause */
     /*package*/ boolean mTemporaryPause = false;
     /** true if the activity is being destroyed in order to recreate it with a new configuration */
@@ -699,7 +702,7 @@
         Object activity;
         HashMap<String, Object> children;
         ArrayList<Fragment> fragments;
-        HashMap<String, LoaderManagerImpl> loaders;
+        ArrayMap<String, LoaderManagerImpl> loaders;
     }
     /* package */ NonConfigurationInstances mLastNonConfigurationInstances;
     
@@ -724,7 +727,7 @@
         }
     };
     
-    HashMap<String, LoaderManagerImpl> mAllLoaderManagers;
+    ArrayMap<String, LoaderManagerImpl> mAllLoaderManagers;
     LoaderManagerImpl mLoaderManager;
     
     private static final class ManagedCursor {
@@ -744,6 +747,8 @@
     // protected by synchronized (this) 
     int mResultCode = RESULT_CANCELED;
     Intent mResultData = null;
+    private TranslucentConversionListener mTranslucentCallback;
+    private boolean mChangeCanvasToTranslucent;
 
     private boolean mTitleReady = false;
 
@@ -817,13 +822,13 @@
             return mLoaderManager;
         }
         mCheckedForLoaderManager = true;
-        mLoaderManager = getLoaderManager(null, mLoadersStarted, true);
+        mLoaderManager = getLoaderManager("(root)", mLoadersStarted, true);
         return mLoaderManager;
     }
     
     LoaderManagerImpl getLoaderManager(String who, boolean started, boolean create) {
         if (mAllLoaderManagers == null) {
-            mAllLoaderManagers = new HashMap<String, LoaderManagerImpl>();
+            mAllLoaderManagers = new ArrayMap<String, LoaderManagerImpl>();
         }
         LoaderManagerImpl lm = mAllLoaderManagers.get(who);
         if (lm == null) {
@@ -1034,7 +1039,7 @@
             if (mLoaderManager != null) {
                 mLoaderManager.doStart();
             } else if (!mCheckedForLoaderManager) {
-                mLoaderManager = getLoaderManager(null, mLoadersStarted, false);
+                mLoaderManager = getLoaderManager("(root)", mLoadersStarted, false);
             }
             mCheckedForLoaderManager = true;
         }
@@ -1381,6 +1386,7 @@
         if (DEBUG_LIFECYCLE) Slog.v(TAG, "onStop " + this);
         if (mActionBar != null) mActionBar.setShowHideAnimationEnabled(false);
         getApplication().dispatchActivityStopped(this);
+        mTranslucentCallback = null;
         mCalled = true;
     }
 
@@ -1449,6 +1455,27 @@
     }
 
     /**
+     * Report to the system that your app is now fully drawn.  This is only used
+     * to help instrument app launch times, so that the app can report when it is
+     * fully in a usable state; without this, all the system can determine is when
+     * its window is first drawn and displayed.  To participate in app launch time
+     * measurement, you should always call this method after first launch (when
+     * {@link #onCreate(android.os.Bundle)} is called) at the point where you have
+     * entirely drawn your UI and populated with all of the significant data.  You
+     * can safely call this method any time after first launch as well, in which case
+     * it will simply be ignored.
+     */
+    public void reportFullyDrawn() {
+        if (mDoReportFullyDrawn) {
+            mDoReportFullyDrawn = false;
+            try {
+                ActivityManagerNative.getDefault().reportActivityFullyDrawn(mToken);
+            } catch (RemoteException e) {
+            }
+        }
+    }
+
+    /**
      * Called by the system when the device configuration changes while your
      * activity is running.  Note that this will <em>only</em> be called if
      * you have selected configurations you would like to handle with the
@@ -1624,17 +1651,18 @@
         if (mAllLoaderManagers != null) {
             // prune out any loader managers that were already stopped and so
             // have nothing useful to retain.
-            LoaderManagerImpl loaders[] = new LoaderManagerImpl[mAllLoaderManagers.size()];
-            mAllLoaderManagers.values().toArray(loaders);
-            if (loaders != null) {
-                for (int i=0; i<loaders.length; i++) {
-                    LoaderManagerImpl lm = loaders[i];
-                    if (lm.mRetaining) {
-                        retainLoaders = true;
-                    } else {
-                        lm.doDestroy();
-                        mAllLoaderManagers.remove(lm.mWho);
-                    }
+            final int N = mAllLoaderManagers.size();
+            LoaderManagerImpl loaders[] = new LoaderManagerImpl[N];
+            for (int i=N-1; i>=0; i--) {
+                loaders[i] = mAllLoaderManagers.valueAt(i);
+            }
+            for (int i=0; i<N; i++) {
+                LoaderManagerImpl lm = loaders[i];
+                if (lm.mRetaining) {
+                    retainLoaders = true;
+                } else {
+                    lm.doDestroy();
+                    mAllLoaderManagers.remove(lm.mWho);
                 }
             }
         }
@@ -1877,9 +1905,12 @@
         if (isChild() || !window.hasFeature(Window.FEATURE_ACTION_BAR) || mActionBar != null) {
             return;
         }
-        
+
         mActionBar = new ActionBarImpl(this);
         mActionBar.setDefaultDisplayHomeAsUpEnabled(mEnableDefaultActionBarUp);
+
+        mWindow.setDefaultIcon(mActivityInfo.getIconResource());
+        mWindow.setDefaultLogo(mActivityInfo.getLogoResource());
     }
     
     /**
@@ -3406,6 +3437,12 @@
                 // activity is finished, no matter what happens to it.
                 mStartedActivity = true;
             }
+
+            final View decor = mWindow != null ? mWindow.peekDecorView() : null;
+            if (decor != null) {
+                decor.cancelPendingInputEvents();
+            }
+            // TODO Consider clearing/flushing other event sources and events for child windows.
         } else {
             if (options != null) {
                 mParent.startActivityFromChild(this, intent, requestCode, options);
@@ -4859,6 +4896,74 @@
     }
 
     /**
+     * Convert a translucent themed Activity {@link android.R.attr#windowIsTranslucent} to a
+     * fullscreen opaque Activity.
+     * <p>
+     * Call this whenever the background of a translucent Activity has changed to become opaque.
+     * Doing so will allow the {@link android.view.Surface} of the Activity behind to be released.
+     * <p>
+     * This call has no effect on non-translucent activities or on activities with the
+     * {@link android.R.attr#windowIsFloating} attribute.
+     *
+     * @see #convertToTranslucent(TranslucentConversionListener)
+     * @see TranslucentConversionListener
+     *
+     * @hide
+     */
+    public void convertFromTranslucent() {
+        try {
+            mTranslucentCallback = null;
+            if (ActivityManagerNative.getDefault().convertFromTranslucent(mToken)) {
+                WindowManagerGlobal.getInstance().changeCanvasOpacity(mToken, true);
+            }
+        } catch (RemoteException e) {
+            // pass
+        }
+    }
+
+    /**
+     * Convert a translucent themed Activity {@link android.R.attr#windowIsTranslucent} back from
+     * opaque to translucent following a call to {@link #convertFromTranslucent()}.
+     * <p>
+     * Calling this allows the Activity behind this one to be seen again. Once all such Activities
+     * have been redrawn {@link TranslucentConversionListener#onTranslucentConversionComplete} will
+     * be called indicating that it is safe to make this activity translucent again. Until
+     * {@link TranslucentConversionListener#onTranslucentConversionComplete} is called the image
+     * behind the frontmost Activity will be indeterminate.
+     * <p>
+     * This call has no effect on non-translucent activities or on activities with the
+     * {@link android.R.attr#windowIsFloating} attribute.
+     *
+     * @param callback the method to call when all visible Activities behind this one have been
+     * drawn and it is safe to make this Activity translucent again.
+     *
+     * @see #convertFromTranslucent()
+     * @see TranslucentConversionListener
+     *
+     * @hide
+     */
+    public void convertToTranslucent(TranslucentConversionListener callback) {
+        try {
+            mTranslucentCallback = callback;
+            mChangeCanvasToTranslucent =
+                    ActivityManagerNative.getDefault().convertToTranslucent(mToken);
+        } catch (RemoteException e) {
+            // pass
+        }
+    }
+
+    /** @hide */
+    void onTranslucentConversionComplete(boolean drawComplete) {
+        if (mTranslucentCallback != null) {
+            mTranslucentCallback.onTranslucentConversionComplete(drawComplete);
+            mTranslucentCallback = null;
+        }
+        if (mChangeCanvasToTranslucent) {
+            WindowManagerGlobal.getInstance().changeCanvasOpacity(mToken, false);
+        }
+    }
+
+    /**
      * Adjust the current immersive mode setting.
      *
      * Note that changing this value will have no effect on the activity's
@@ -4903,6 +5008,7 @@
      * @return The new action mode, or <code>null</code> if the activity does not want to
      *         provide special handling for this action mode. (It will be handled by the system.)
      */
+    @Override
     public ActionMode onWindowStartingActionMode(ActionMode.Callback callback) {
         initActionBar();
         if (mActionBar != null) {
@@ -4917,6 +5023,7 @@
      *
      * @param mode The new action mode.
      */
+    @Override
     public void onActionModeStarted(ActionMode mode) {
     }
 
@@ -4926,6 +5033,7 @@
      *
      * @param mode The action mode that just finished.
      */
+    @Override
     public void onActionModeFinished(ActionMode mode) {
     }
 
@@ -5148,14 +5256,15 @@
         }
         mFragments.dispatchStart();
         if (mAllLoaderManagers != null) {
-            LoaderManagerImpl loaders[] = new LoaderManagerImpl[mAllLoaderManagers.size()];
-            mAllLoaderManagers.values().toArray(loaders);
-            if (loaders != null) {
-                for (int i=0; i<loaders.length; i++) {
-                    LoaderManagerImpl lm = loaders[i];
-                    lm.finishRetain();
-                    lm.doReportStart();
-                }
+            final int N = mAllLoaderManagers.size();
+            LoaderManagerImpl loaders[] = new LoaderManagerImpl[N];
+            for (int i=N-1; i>=0; i--) {
+                loaders[i] = mAllLoaderManagers.valueAt(i);
+            }
+            for (int i=0; i<N; i++) {
+                LoaderManagerImpl lm = loaders[i];
+                lm.finishRetain();
+                lm.doReportStart();
             }
         }
     }
@@ -5230,6 +5339,7 @@
     }
 
     final void performPause() {
+        mDoReportFullyDrawn = false;
         mFragments.dispatchPause();
         mCalled = false;
         onPause();
@@ -5249,6 +5359,7 @@
     }
     
     final void performStop() {
+        mDoReportFullyDrawn = false;
         if (mLoadersStarted) {
             mLoadersStarted = false;
             if (mLoaderManager != null) {
@@ -5327,4 +5438,28 @@
             }
         }
     }
+
+    /**
+     * Interface for informing a translucent {@link Activity} once all visible activities below it
+     * have completed drawing. This is necessary only after an {@link Activity} has been made
+     * opaque using {@link Activity#convertFromTranslucent()} and before it has been drawn
+     * translucent again following a call to {@link
+     * Activity#convertToTranslucent(TranslucentConversionListener)}.
+     *
+     * @hide
+     */
+    public interface TranslucentConversionListener {
+        /**
+         * Callback made following {@link Activity#convertToTranslucent} once all visible Activities
+         * below the top one have been redrawn. Following this callback it is safe to make the top
+         * Activity translucent because the underlying Activity has been drawn.
+         *
+         * @param drawComplete True if the background Activity has drawn itself. False if a timeout
+         * occurred waiting for the Activity to complete drawing.
+         *
+         * @see Activity#convertFromTranslucent()
+         * @see Activity#convertToTranslucent(TranslucentConversionListener)
+         */
+        public void onTranslucentConversionComplete(boolean drawComplete);
+    }
 }
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index a25e311..2d28280 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -16,10 +16,13 @@
 
 package android.app;
 
-import android.R;
+import android.os.BatteryStats;
+import android.os.IBinder;
 import com.android.internal.app.IUsageStats;
+import com.android.internal.app.ProcessStats;
 import com.android.internal.os.PkgUsageStats;
-import com.android.internal.util.MemInfoReader;
+import com.android.internal.os.TransferPipe;
+import com.android.internal.util.FastPrintWriter;
 
 import android.content.ComponentName;
 import android.content.Context;
@@ -31,10 +34,7 @@
 import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
-import android.graphics.Point;
-import android.hardware.display.DisplayManager;
-import android.hardware.display.DisplayManagerGlobal;
-import android.os.Binder;
+import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.Debug;
 import android.os.Handler;
@@ -49,8 +49,10 @@
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.util.Slog;
-import android.view.Display;
 
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.PrintWriter;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -222,6 +224,56 @@
     /** @hide User operation call: given user id is the current user, can't be stopped. */
     public static final int USER_OP_IS_CURRENT = -2;
 
+    /** @hide Process is a persistent system process. */
+    public static final int PROCESS_STATE_PERSISTENT = 0;
+
+    /** @hide Process is a persistent system process and is doing UI. */
+    public static final int PROCESS_STATE_PERSISTENT_UI = 1;
+
+    /** @hide Process is hosting the current top activities.  Note that this covers
+     * all activities that are visible to the user. */
+    public static final int PROCESS_STATE_TOP = 2;
+
+    /** @hide Process is important to the user, and something they are aware of. */
+    public static final int PROCESS_STATE_IMPORTANT_FOREGROUND = 3;
+
+    /** @hide Process is important to the user, but not something they are aware of. */
+    public static final int PROCESS_STATE_IMPORTANT_BACKGROUND = 4;
+
+    /** @hide Process is in the background running a backup/restore operation. */
+    public static final int PROCESS_STATE_BACKUP = 5;
+
+    /** @hide Process is in the background, but it can't restore its state so we want
+     * to try to avoid killing it. */
+    public static final int PROCESS_STATE_HEAVY_WEIGHT = 6;
+
+    /** @hide Process is in the background running a service.  Unlike oom_adj, this level
+     * is used for both the normal running in background state and the executing
+     * operations state. */
+    public static final int PROCESS_STATE_SERVICE = 7;
+
+    /** @hide Process is in the background running a receiver.   Note that from the
+     * perspective of oom_adj receivers run at a higher foreground level, but for our
+     * prioritization here that is not necessary and putting them below services means
+     * many fewer changes in some process states as they receive broadcasts. */
+    public static final int PROCESS_STATE_RECEIVER = 8;
+
+    /** @hide Process is in the background but hosts the home activity. */
+    public static final int PROCESS_STATE_HOME = 9;
+
+    /** @hide Process is in the background but hosts the last shown activity. */
+    public static final int PROCESS_STATE_LAST_ACTIVITY = 10;
+
+    /** @hide Process is being cached for later use and contains activities. */
+    public static final int PROCESS_STATE_CACHED_ACTIVITY = 11;
+
+    /** @hide Process is being cached for later use and is a client of another cached
+     * process that contains activities. */
+    public static final int PROCESS_STATE_CACHED_ACTIVITY_CLIENT = 12;
+
+    /** @hide Process is being cached for later use and is empty. */
+    public static final int PROCESS_STATE_CACHED_EMPTY = 13;
+
     /*package*/ ActivityManager(Context context, Handler handler) {
         mContext = context;
         mHandler = handler;
@@ -370,7 +422,23 @@
         // Really brain dead right now -- just take this from the configured
         // vm heap size, and assume it is in megabytes and thus ends with "m".
         String vmHeapSize = SystemProperties.get("dalvik.vm.heapsize", "16m");
-        return Integer.parseInt(vmHeapSize.substring(0, vmHeapSize.length() - 1));
+        return Integer.parseInt(vmHeapSize.substring(0, vmHeapSize.length()-1));
+    }
+
+    /**
+     * Returns true if this is a low-RAM device.  Exactly whether a device is low-RAM
+     * is ultimately up to the device configuration, but currently it generally means
+     * something in the class of a 512MB device with about a 800x480 or less screen.
+     * This is mostly intended to be used by apps to determine whether they should turn
+     * off certain features that require more RAM.
+     */
+    public boolean isLowRamDevice() {
+        return isLowRamDeviceStatic();
+    }
+
+    /** @hide */
+    public static boolean isLowRamDeviceStatic() {
+        return "true".equals(SystemProperties.get("ro.config.low_ram", "false"));
     }
 
     /**
@@ -380,43 +448,8 @@
      * @hide
      */
     static public boolean isHighEndGfx() {
-        MemInfoReader reader = new MemInfoReader();
-        reader.readMemInfo();
-        if (reader.getTotalSize() >= (512*1024*1024)) {
-            // If the device has at least 512MB RAM available to the kernel,
-            // we can afford the overhead of graphics acceleration.
-            return true;
-        }
-
-        Display display = DisplayManagerGlobal.getInstance().getRealDisplay(
-                Display.DEFAULT_DISPLAY);
-        Point p = new Point();
-        display.getRealSize(p);
-        int pixels = p.x * p.y;
-        if (pixels >= (1024*600)) {
-            // If this is a sufficiently large screen, then there are enough
-            // pixels on it that we'd really like to use hw drawing.
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Use to decide whether the running device can be considered a "large
-     * RAM" device.  Exactly what memory limit large RAM is will vary, but
-     * it essentially means there is plenty of RAM to have lots of background
-     * processes running under decent loads.
-     * @hide
-     */
-    static public boolean isLargeRAM() {
-        MemInfoReader reader = new MemInfoReader();
-        reader.readMemInfo();
-        if (reader.getTotalSize() >= (640*1024*1024)) {
-            // Currently 640MB RAM available to the kernel is the point at
-            // which we have plenty of RAM to spare.
-            return true;
-        }
-        return false;
+        return !isLowRamDeviceStatic() &&
+                !Resources.getSystem().getBoolean(com.android.internal.R.bool.config_avoidGfxAccel);
     }
 
     /**
@@ -454,14 +487,22 @@
          * Description of the task's last state.
          */
         public CharSequence description;
-        
+
+        /**
+         * The id of the ActivityStack this Task was on most recently.
+         * @hide
+         */
+        public int stackId;
+
         public RecentTaskInfo() {
         }
 
+        @Override
         public int describeContents() {
             return 0;
         }
 
+        @Override
         public void writeToParcel(Parcel dest, int flags) {
             dest.writeInt(id);
             dest.writeInt(persistentId);
@@ -474,6 +515,7 @@
             ComponentName.writeToParcel(origActivity, dest);
             TextUtils.writeToParcel(description, dest,
                     Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
+            dest.writeInt(stackId);
         }
 
         public void readFromParcel(Parcel source) {
@@ -486,8 +528,9 @@
             }
             origActivity = ComponentName.readFromParcel(source);
             description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
+            stackId = source.readInt();
         }
-        
+
         public static final Creator<RecentTaskInfo> CREATOR
                 = new Creator<RecentTaskInfo>() {
             public RecentTaskInfo createFromParcel(Parcel source) {
@@ -1230,7 +1273,169 @@
         } catch (RemoteException e) {
         }
     }
-    
+
+    /**
+     * Information you can retrieve about the WindowManager StackBox hierarchy.
+     * @hide
+     */
+    public static class StackBoxInfo implements Parcelable {
+        public int stackBoxId;
+        public float weight;
+        public boolean vertical;
+        public Rect bounds;
+        public StackBoxInfo[] children;
+        public int stackId;
+        public StackInfo stack;
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeInt(stackBoxId);
+            dest.writeFloat(weight);
+            dest.writeInt(vertical ? 1 : 0);
+            bounds.writeToParcel(dest, flags);
+            dest.writeInt(stackId);
+            if (children != null) {
+                children[0].writeToParcel(dest, flags);
+                children[1].writeToParcel(dest, flags);
+            } else {
+                stack.writeToParcel(dest, flags);
+            }
+        }
+
+        public void readFromParcel(Parcel source) {
+            stackBoxId = source.readInt();
+            weight = source.readFloat();
+            vertical = source.readInt() == 1;
+            bounds = Rect.CREATOR.createFromParcel(source);
+            stackId = source.readInt();
+            if (stackId == -1) {
+                children = new StackBoxInfo[2];
+                children[0] = StackBoxInfo.CREATOR.createFromParcel(source);
+                children[1] = StackBoxInfo.CREATOR.createFromParcel(source);
+            } else {
+                stack = StackInfo.CREATOR.createFromParcel(source);
+            }
+        }
+
+        public static final Creator<StackBoxInfo> CREATOR =
+                new Creator<ActivityManager.StackBoxInfo>() {
+
+            @Override
+            public StackBoxInfo createFromParcel(Parcel source) {
+                return new StackBoxInfo(source);
+            }
+
+            @Override
+            public StackBoxInfo[] newArray(int size) {
+                return new StackBoxInfo[size];
+            }
+        };
+
+        public StackBoxInfo() {
+        }
+
+        public StackBoxInfo(Parcel source) {
+            readFromParcel(source);
+        }
+
+        public String toString(String prefix) {
+            StringBuilder sb = new StringBuilder(256);
+            sb.append(prefix); sb.append("Box id=" + stackBoxId); sb.append(" weight=" + weight);
+            sb.append(" vertical=" + vertical); sb.append(" bounds=" + bounds.toShortString());
+            sb.append("\n");
+            if (children != null) {
+                sb.append(prefix); sb.append("First child=\n");
+                sb.append(children[0].toString(prefix + "  "));
+                sb.append(prefix); sb.append("Second child=\n");
+                sb.append(children[1].toString(prefix + "  "));
+            } else {
+                sb.append(prefix); sb.append("Stack=\n");
+                sb.append(stack.toString(prefix + "  "));
+            }
+            return sb.toString();
+        }
+
+        @Override
+        public String toString() {
+            return toString("");
+        }
+    }
+
+    /**
+     * Information you can retrieve about an ActivityStack in the system.
+     * @hide
+     */
+    public static class StackInfo implements Parcelable {
+        public int stackId;
+        public Rect bounds;
+        public int[] taskIds;
+        public String[] taskNames;
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeInt(stackId);
+            dest.writeInt(bounds.left);
+            dest.writeInt(bounds.top);
+            dest.writeInt(bounds.right);
+            dest.writeInt(bounds.bottom);
+            dest.writeIntArray(taskIds);
+            dest.writeStringArray(taskNames);
+        }
+
+        public void readFromParcel(Parcel source) {
+            stackId = source.readInt();
+            bounds = new Rect(
+                    source.readInt(), source.readInt(), source.readInt(), source.readInt());
+            taskIds = source.createIntArray();
+            taskNames = source.createStringArray();
+        }
+
+        public static final Creator<StackInfo> CREATOR = new Creator<StackInfo>() {
+            @Override
+            public StackInfo createFromParcel(Parcel source) {
+                return new StackInfo(source);
+            }
+            @Override
+            public StackInfo[] newArray(int size) {
+                return new StackInfo[size];
+            }
+        };
+
+        public StackInfo() {
+        }
+
+        private StackInfo(Parcel source) {
+            readFromParcel(source);
+        }
+
+        public String toString(String prefix) {
+            StringBuilder sb = new StringBuilder(256);
+            sb.append(prefix); sb.append("Stack id="); sb.append(stackId);
+                    sb.append(" bounds="); sb.append(bounds.toShortString()); sb.append("\n");
+            prefix = prefix + "  ";
+            for (int i = 0; i < taskIds.length; ++i) {
+                sb.append(prefix); sb.append("taskId="); sb.append(taskIds[i]);
+                        sb.append(": "); sb.append(taskNames[i]); sb.append("\n");
+            }
+            return sb.toString();
+        }
+
+        @Override
+        public String toString() {
+            return toString("");
+        }
+    }
+
     /**
      * @hide
      */
@@ -1242,7 +1447,18 @@
             return false;
         }
     }
-    
+
+    /**
+     * Permits an application to erase its own data from disk.  This is equivalent to
+     * the user choosing to clear the app's data from within the device settings UI.
+     *
+     * @return {@code true} if the application successfully requested that the application's
+     *     data be erased; {@code false} otherwise.
+     */
+    public boolean clearApplicationUserData() {
+        return clearApplicationUserData(mContext.getPackageName(), null);
+    }
+
     /**
      * Information you can retrieve about any processes that are in an error condition.
      */
@@ -1304,10 +1520,12 @@
         public ProcessErrorStateInfo() {
         }
 
+        @Override
         public int describeContents() {
             return 0;
         }
 
+        @Override
         public void writeToParcel(Parcel dest, int flags) {
             dest.writeInt(condition);
             dest.writeString(processName);
@@ -1318,7 +1536,7 @@
             dest.writeString(longMsg);
             dest.writeString(stackTrace);
         }
-        
+
         public void readFromParcel(Parcel source) {
             condition = source.readInt();
             processName = source.readString();
@@ -1538,7 +1756,7 @@
         public ComponentName importanceReasonComponent;
         
         /**
-         * When {@link importanceReasonPid} is non-0, this is the importance
+         * When {@link #importanceReasonPid} is non-0, this is the importance
          * of the other pid. @hide
          */
         public int importanceReasonImportance;
@@ -1888,7 +2106,12 @@
         }
         // If the target is not exported, then nobody else can get to it.
         if (!exported) {
-            Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
+            /*
+            RuntimeException here = new RuntimeException("here");
+            here.fillInStackTrace();
+            Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid,
+                    here);
+            */
             return PackageManager.PERMISSION_DENIED;
         }
         if (permission == null) {
@@ -2010,4 +2233,58 @@
             return false;
         }
     }
+
+    /**
+     * Perform a system dump of various state associated with the given application
+     * package name.  This call blocks while the dump is being performed, so should
+     * not be done on a UI thread.  The data will be written to the given file
+     * descriptor as text.  An application must hold the
+     * {@link android.Manifest.permission#DUMP} permission to make this call.
+     * @param fd The file descriptor that the dump should be written to.
+     * @param packageName The name of the package that is to be dumped.
+     */
+    public void dumpPackageState(FileDescriptor fd, String packageName) {
+        dumpPackageStateStatic(fd, packageName);
+    }
+
+    /**
+     * @hide
+     */
+    public static void dumpPackageStateStatic(FileDescriptor fd, String packageName) {
+        FileOutputStream fout = new FileOutputStream(fd);
+        PrintWriter pw = new FastPrintWriter(fout);
+        dumpService(pw, fd, Context.ACTIVITY_SERVICE, new String[] { "package", packageName });
+        pw.println();
+        dumpService(pw, fd, ProcessStats.SERVICE_NAME, new String[] { packageName });
+        pw.println();
+        dumpService(pw, fd, "usagestats", new String[] { "--packages", packageName });
+        pw.println();
+        dumpService(pw, fd, "package", new String[] { packageName });
+        pw.println();
+        dumpService(pw, fd, BatteryStats.SERVICE_NAME, new String[] { packageName });
+        pw.flush();
+    }
+
+    private static void dumpService(PrintWriter pw, FileDescriptor fd, String name, String[] args) {
+        pw.print("DUMP OF SERVICE "); pw.print(name); pw.println(":");
+        IBinder service = ServiceManager.checkService(name);
+        if (service == null) {
+            pw.println("  (Service not found)");
+            return;
+        }
+        TransferPipe tp = null;
+        try {
+            pw.flush();
+            tp = new TransferPipe();
+            tp.setBufferPrefix("  ");
+            service.dump(tp.getWriteFd().getFileDescriptor(), args);
+            tp.go(fd);
+        } catch (Throwable e) {
+            if (tp != null) {
+                tp.kill();
+            }
+            pw.println("Failure dumping service:");
+            e.printStackTrace(pw);
+        }
+    }
 }
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index d4478bf..370db31 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -16,6 +16,7 @@
 
 package android.app;
 
+import android.app.ActivityManager.StackBoxInfo;
 import android.content.ComponentName;
 import android.content.IIntentReceiver;
 import android.content.IIntentSender;
@@ -107,7 +108,8 @@
     public ActivityManagerNative() {
         attachInterface(this, descriptor);
     }
-    
+
+    @Override
     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
             throws RemoteException {
         switch (code) {
@@ -197,7 +199,7 @@
             Intent intent = Intent.CREATOR.createFromParcel(data);
             String resolvedType = data.readString();
             IBinder resultTo = data.readStrongBinder();
-            String resultWho = data.readString();    
+            String resultWho = data.readString();
             int requestCode = data.readInt();
             int startFlags = data.readInt();
             Configuration config = Configuration.CREATOR.createFromParcel(data);
@@ -223,7 +225,7 @@
             }
             String resolvedType = data.readString();
             IBinder resultTo = data.readStrongBinder();
-            String resultWho = data.readString();    
+            String resultWho = data.readString();
             int requestCode = data.readInt();
             int flagsMask = data.readInt();
             int flagsValues = data.readInt();
@@ -236,7 +238,7 @@
             reply.writeInt(result);
             return true;
         }
-        
+
         case START_NEXT_MATCHING_ACTIVITY_TRANSACTION:
         {
             data.enforceInterface(IActivityManager.descriptor);
@@ -267,7 +269,7 @@
         case FINISH_SUB_ACTIVITY_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             IBinder token = data.readStrongBinder();
-            String resultWho = data.readString();    
+            String resultWho = data.readString();
             int requestCode = data.readInt();
             finishSubActivity(token, resultWho, requestCode);
             reply.writeNoException();
@@ -478,14 +480,13 @@
             IThumbnailReceiver receiver = receiverBinder != null
                 ? IThumbnailReceiver.Stub.asInterface(receiverBinder)
                 : null;
-            List list = getTasks(maxNum, fl, receiver);
+            List<ActivityManager.RunningTaskInfo> list = getTasks(maxNum, fl, receiver);
             reply.writeNoException();
             int N = list != null ? list.size() : -1;
             reply.writeInt(N);
             int i;
             for (i=0; i<N; i++) {
-                ActivityManager.RunningTaskInfo info =
-                        (ActivityManager.RunningTaskInfo)list.get(i);
+                ActivityManager.RunningTaskInfo info = list.get(i);
                 info.writeToParcel(reply, 0);
             }
             return true;
@@ -535,14 +536,13 @@
             data.enforceInterface(IActivityManager.descriptor);
             int maxNum = data.readInt();
             int fl = data.readInt();
-            List list = getServices(maxNum, fl);
+            List<ActivityManager.RunningServiceInfo> list = getServices(maxNum, fl);
             reply.writeNoException();
             int N = list != null ? list.size() : -1;
             reply.writeInt(N);
             int i;
             for (i=0; i<N; i++) {
-                ActivityManager.RunningServiceInfo info =
-                        (ActivityManager.RunningServiceInfo)list.get(i);
+                ActivityManager.RunningServiceInfo info = list.get(i);
                 info.writeToParcel(reply, 0);
             }
             return true;
@@ -555,7 +555,7 @@
             reply.writeTypedList(list);
             return true;
         }
-        
+
         case GET_RUNNING_APP_PROCESSES_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             List<ActivityManager.RunningAppProcessInfo> list = getRunningAppProcesses();
@@ -609,6 +609,67 @@
             return true;
         }
 
+        case CREATE_STACK_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            int taskId = data.readInt();
+            int relativeStackId = data.readInt();
+            int position = data.readInt();
+            float weight = data.readFloat();
+            int res = createStack(taskId, relativeStackId, position, weight);
+            reply.writeNoException();
+            reply.writeInt(res);
+            return true;
+        }
+
+        case MOVE_TASK_TO_STACK_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            int taskId = data.readInt();
+            int stackId = data.readInt();
+            boolean toTop = data.readInt() != 0;
+            moveTaskToStack(taskId, stackId, toTop);
+            reply.writeNoException();
+            return true;
+        }
+
+        case RESIZE_STACK_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            int stackBoxId = data.readInt();
+            float weight = data.readFloat();
+            resizeStackBox(stackBoxId, weight);
+            reply.writeNoException();
+            return true;
+        }
+
+        case GET_STACK_BOXES_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            List<StackBoxInfo> list = getStackBoxes();
+            reply.writeNoException();
+            reply.writeTypedList(list);
+            return true;
+        }
+
+        case GET_STACK_BOX_INFO_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            int stackBoxId = data.readInt();
+            StackBoxInfo info = getStackBoxInfo(stackBoxId);
+            reply.writeNoException();
+            if (info != null) {
+                reply.writeInt(1);
+                info.writeToParcel(reply, 0);
+            } else {
+                reply.writeInt(0);
+            }
+            return true;
+        }
+
+        case SET_FOCUSED_STACK_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            int stackId = data.readInt();
+            setFocusedStack(stackId);
+            reply.writeNoException();
+            return true;
+        }
+
         case GET_TASK_FOR_ACTIVITY_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             IBinder token = data.readStrongBinder();
@@ -1033,9 +1094,9 @@
             reply.writeInt(res);
             return true;
         }
-        
+
         case CLEAR_APP_DATA_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);            
+            data.enforceInterface(IActivityManager.descriptor);
             String packageName = data.readString();
             IPackageDataObserver observer = IPackageDataObserver.Stub.asInterface(
                     data.readStrongBinder());
@@ -1045,7 +1106,7 @@
             reply.writeInt(res ? 1 : 0);
             return true;
         }
-        
+
         case GRANT_URI_PERMISSION_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             IBinder b = data.readStrongBinder();
@@ -1057,7 +1118,7 @@
             reply.writeNoException();
             return true;
         }
-        
+
         case REVOKE_URI_PERMISSION_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             IBinder b = data.readStrongBinder();
@@ -1068,7 +1129,7 @@
             reply.writeNoException();
             return true;
         }
-        
+
         case SHOW_WAITING_FOR_DEBUGGER_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             IBinder b = data.readStrongBinder();
@@ -1257,7 +1318,7 @@
             reply.writeNoException();
             return true;
         }
-        
+
         case FORCE_STOP_PACKAGE_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             String packageName = data.readString();
@@ -1363,7 +1424,8 @@
             data.enforceInterface(IActivityManager.descriptor);
             String pkg = data.readString();
             int appid = data.readInt();
-            killApplicationWithAppId(pkg, appid);
+            String reason = data.readString();
+            killApplicationWithAppId(pkg, appid, reason);
             reply.writeNoException();
             return true;
         }
@@ -1437,6 +1499,24 @@
             return true;
         }
 
+        case CONVERT_FROM_TRANSLUCENT_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            boolean converted = convertFromTranslucent(token);
+            reply.writeNoException();
+            reply.writeInt(converted ? 1 : 0);
+            return true;
+        }
+
+        case CONVERT_TO_TRANSLUCENT_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            boolean converted = convertToTranslucent(token);
+            reply.writeNoException();
+            reply.writeInt(converted ? 1 : 0);
+            return true;
+        }
+
         case SET_IMMERSIVE_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             IBinder token = data.readStrongBinder();
@@ -1837,26 +1917,27 @@
             data.enforceInterface(IActivityManager.descriptor);
             int pid = data.readInt();
             boolean aboveSystem = data.readInt() != 0;
-            long res = inputDispatchingTimedOut(pid, aboveSystem);
+            String reason = data.readString();
+            long res = inputDispatchingTimedOut(pid, aboveSystem, reason);
             reply.writeNoException();
             reply.writeLong(res);
             return true;
         }
 
-        case GET_TOP_ACTIVITY_EXTRAS_TRANSACTION: {
+        case GET_ASSIST_CONTEXT_EXTRAS_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             int requestType = data.readInt();
-            Bundle res = getTopActivityExtras(requestType);
+            Bundle res = getAssistContextExtras(requestType);
             reply.writeNoException();
             reply.writeBundle(res);
             return true;
         }
 
-        case REPORT_TOP_ACTIVITY_EXTRAS_TRANSACTION: {
+        case REPORT_ASSIST_CONTEXT_EXTRAS_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             IBinder token = data.readStrongBinder();
             Bundle extras = data.readBundle();
-            reportTopActivityExtras(token, extras);
+            reportAssistContextExtras(token, extras);
             reply.writeNoException();
             return true;
         }
@@ -1879,6 +1960,41 @@
             return true;
         }
 
+        case REPORT_ACTIVITY_FULLY_DRAWN_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            reportActivityFullyDrawn(token);
+            reply.writeNoException();
+            return true;
+        }
+
+        case NOTIFY_ACTIVITY_DRAWN_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            notifyActivityDrawn(token);
+            reply.writeNoException();
+            return true;
+        }
+
+        case RESTART_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            restart();
+            reply.writeNoException();
+            return true;
+        }
+
+        case GET_GRANTED_URI_PERMISSIONS_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            final String sourcePackage = data.readString();
+            final String targetPackage = data.readString();
+            final int modeFlags = data.readInt();
+            final int modeMask = data.readInt();
+            final Uri[] uris = getGrantedUriPermissions(
+                    sourcePackage, targetPackage, modeFlags, modeMask);
+            reply.writeNoException();
+            reply.writeParcelableArray(uris, 0);
+            return true;
+        }
         }
 
         return super.onTransact(code, data, reply, flags);
@@ -2565,6 +2681,94 @@
         data.recycle();
         reply.recycle();
     }
+    @Override
+    public int createStack(int taskId, int relativeStackBoxId, int position, float weight)
+            throws RemoteException
+    {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeInt(taskId);
+        data.writeInt(relativeStackBoxId);
+        data.writeInt(position);
+        data.writeFloat(weight);
+        mRemote.transact(CREATE_STACK_TRANSACTION, data, reply, 0);
+        reply.readException();
+        int res = reply.readInt();
+        data.recycle();
+        reply.recycle();
+        return res;
+    }
+    @Override
+    public void moveTaskToStack(int taskId, int stackId, boolean toTop) throws RemoteException
+    {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeInt(taskId);
+        data.writeInt(stackId);
+        data.writeInt(toTop ? 1 : 0);
+        mRemote.transact(MOVE_TASK_TO_STACK_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+    @Override
+    public void resizeStackBox(int stackBoxId, float weight) throws RemoteException
+    {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeInt(stackBoxId);
+        data.writeFloat(weight);
+        mRemote.transact(RESIZE_STACK_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+    @Override
+    public List<StackBoxInfo> getStackBoxes() throws RemoteException
+    {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        mRemote.transact(GET_STACK_BOXES_TRANSACTION, data, reply, 0);
+        reply.readException();
+        ArrayList<StackBoxInfo> list = reply.createTypedArrayList(StackBoxInfo.CREATOR);
+        data.recycle();
+        reply.recycle();
+        return list;
+    }
+    @Override
+    public StackBoxInfo getStackBoxInfo(int stackBoxId) throws RemoteException
+    {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeInt(stackBoxId);
+        mRemote.transact(GET_STACK_BOX_INFO_TRANSACTION, data, reply, 0);
+        reply.readException();
+        int res = reply.readInt();
+        StackBoxInfo info = null;
+        if (res != 0) {
+            info = StackBoxInfo.CREATOR.createFromParcel(reply);
+        }
+        data.recycle();
+        reply.recycle();
+        return info;
+    }
+    @Override
+    public void setFocusedStack(int stackId) throws RemoteException
+    {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeInt(stackId);
+        mRemote.transact(SET_FOCUSED_STACK_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
     public int getTaskForActivity(IBinder token, boolean onlyRoot) throws RemoteException
     {
         Parcel data = Parcel.obtain();
@@ -3173,7 +3377,7 @@
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeString(packageName);
-        data.writeStrongBinder(observer.asBinder());
+        data.writeStrongBinder((observer != null) ? observer.asBinder() : null);
         data.writeInt(userId);
         mRemote.transact(CLEAR_APP_DATA_TRANSACTION, data, reply, 0);
         reply.readException();
@@ -3575,12 +3779,14 @@
         data.recycle();
     }
     
-    public void killApplicationWithAppId(String pkg, int appid) throws RemoteException {
+    public void killApplicationWithAppId(String pkg, int appid, String reason)
+            throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeString(pkg);
         data.writeInt(appid);
+        data.writeString(reason);
         mRemote.transact(KILL_APPLICATION_WITH_APPID_TRANSACTION, data, reply, 0);
         reply.readException();
         data.recycle();
@@ -3671,7 +3877,35 @@
         data.recycle();
         reply.recycle();
     }
-    
+
+    public boolean convertFromTranslucent(IBinder token)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        mRemote.transact(CONVERT_FROM_TRANSLUCENT_TRANSACTION, data, reply, 0);
+        reply.readException();
+        boolean res = reply.readInt() != 0;
+        data.recycle();
+        reply.recycle();
+        return res;
+    }
+
+    public boolean convertToTranslucent(IBinder token)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        mRemote.transact(CONVERT_TO_TRANSLUCENT_TRANSACTION, data, reply, 0);
+        reply.readException();
+        boolean res = reply.readInt() != 0;
+        data.recycle();
+        reply.recycle();
+        return res;
+    }
+
     public void setImmersive(IBinder token, boolean immersive)
             throws RemoteException {
         Parcel data = Parcel.obtain();
@@ -4228,12 +4462,14 @@
         reply.recycle();
     }
 
-    public long inputDispatchingTimedOut(int pid, boolean aboveSystem) throws RemoteException {
+    public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason)
+            throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeInt(pid);
         data.writeInt(aboveSystem ? 1 : 0);
+        data.writeString(reason);
         mRemote.transact(INPUT_DISPATCHING_TIMED_OUT_TRANSACTION, data, reply, 0);
         reply.readException();
         long res = reply.readInt();
@@ -4242,12 +4478,12 @@
         return res;
     }
 
-    public Bundle getTopActivityExtras(int requestType) throws RemoteException {
+    public Bundle getAssistContextExtras(int requestType) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeInt(requestType);
-        mRemote.transact(GET_TOP_ACTIVITY_EXTRAS_TRANSACTION, data, reply, 0);
+        mRemote.transact(GET_ASSIST_CONTEXT_EXTRAS_TRANSACTION, data, reply, 0);
         reply.readException();
         Bundle res = reply.readBundle();
         data.recycle();
@@ -4255,13 +4491,14 @@
         return res;
     }
 
-    public void reportTopActivityExtras(IBinder token, Bundle extras) throws RemoteException {
+    public void reportAssistContextExtras(IBinder token, Bundle extras)
+            throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeStrongBinder(token);
         data.writeBundle(extras);
-        mRemote.transact(REPORT_TOP_ACTIVITY_EXTRAS_TRANSACTION, data, reply, 0);
+        mRemote.transact(REPORT_ASSIST_CONTEXT_EXTRAS_TRANSACTION, data, reply, 0);
         reply.readException();
         data.recycle();
         reply.recycle();
@@ -4291,5 +4528,55 @@
         reply.recycle();
     }
 
+    public void reportActivityFullyDrawn(IBinder token) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        mRemote.transact(REPORT_ACTIVITY_FULLY_DRAWN_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
+    public void notifyActivityDrawn(IBinder token) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        mRemote.transact(NOTIFY_ACTIVITY_DRAWN_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
+    public void restart() throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        mRemote.transact(RESTART_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
+    public Uri[] getGrantedUriPermissions(
+            String sourcePackage, String targetPackage, int modeFlags, int modeMask)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeString(sourcePackage);
+        data.writeString(targetPackage);
+        data.writeInt(modeFlags);
+        data.writeInt(modeMask);
+        mRemote.transact(GET_GRANTED_URI_PERMISSIONS_TRANSACTION, data, reply, 0);
+        reply.readException();
+        final Uri[] uris = (Uri[]) reply.readParcelableArray(null);
+        data.recycle();
+        reply.recycle();
+        return uris;
+    }
+
     private IBinder mRemote;
 }
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 4268fa6..209514a 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -69,13 +69,14 @@
 import android.os.Trace;
 import android.os.UserHandle;
 import android.util.AndroidRuntimeException;
+import android.util.ArrayMap;
 import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.Log;
 import android.util.LogPrinter;
 import android.util.PrintWriterPrinter;
 import android.util.Slog;
-import android.view.CompatibilityInfoHolder;
+import android.util.SuperNotCalledException;
 import android.view.Display;
 import android.view.HardwareRenderer;
 import android.view.View;
@@ -91,6 +92,7 @@
 import com.android.internal.os.BinderInternal;
 import com.android.internal.os.RuntimeInit;
 import com.android.internal.os.SamplingProfilerIntegration;
+import com.android.internal.util.FastPrintWriter;
 import com.android.internal.util.Objects;
 import com.android.org.conscrypt.OpenSSLSocketImpl;
 
@@ -103,8 +105,6 @@
 import java.net.InetAddress;
 import java.security.Security;
 import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
@@ -117,12 +117,6 @@
 
 import dalvik.system.CloseGuard;
 
-final class SuperNotCalledException extends AndroidRuntimeException {
-    public SuperNotCalledException(String msg) {
-        super(msg);
-    }
-}
-
 final class RemoteServiceException extends AndroidRuntimeException {
     public RemoteServiceException(String msg) {
         super(msg);
@@ -147,7 +141,7 @@
     public static final boolean DEBUG_BROADCAST = false;
     private static final boolean DEBUG_RESULTS = false;
     private static final boolean DEBUG_BACKUP = false;
-    private static final boolean DEBUG_CONFIGURATION = false;
+    public static final boolean DEBUG_CONFIGURATION = false;
     private static final boolean DEBUG_SERVICE = false;
     private static final boolean DEBUG_MEMORY_TRIM = false;
     private static final boolean DEBUG_PROVIDER = false;
@@ -164,28 +158,26 @@
     final ApplicationThread mAppThread = new ApplicationThread();
     final Looper mLooper = Looper.myLooper();
     final H mH = new H();
-    final HashMap<IBinder, ActivityClientRecord> mActivities
-            = new HashMap<IBinder, ActivityClientRecord>();
+    final ArrayMap<IBinder, ActivityClientRecord> mActivities
+            = new ArrayMap<IBinder, ActivityClientRecord>();
     // List of new activities (via ActivityRecord.nextIdle) that should
     // be reported when next we idle.
     ActivityClientRecord mNewActivities = null;
     // Number of activities that are currently visible on-screen.
     int mNumVisibleActivities = 0;
-    final HashMap<IBinder, Service> mServices
-            = new HashMap<IBinder, Service>();
+    final ArrayMap<IBinder, Service> mServices
+            = new ArrayMap<IBinder, Service>();
     AppBindData mBoundApplication;
     Profiler mProfiler;
     int mCurDefaultDisplayDpi;
     boolean mDensityCompatMode;
     Configuration mConfiguration;
     Configuration mCompatConfiguration;
-    Configuration mResConfiguration;
-    CompatibilityInfo mResCompatibilityInfo;
     Application mInitialApplication;
     final ArrayList<Application> mAllApplications
             = new ArrayList<Application>();
     // set of instantiated backup agents, keyed by package name
-    final HashMap<String, BackupAgent> mBackupAgents = new HashMap<String, BackupAgent>();
+    final ArrayMap<String, BackupAgent> mBackupAgents = new ArrayMap<String, BackupAgent>();
     /** Reference to singleton {@link ActivityThread} */
     private static ActivityThread sCurrentActivityThread;
     Instrumentation mInstrumentation;
@@ -205,18 +197,16 @@
     // which means this lock gets held while the activity and window managers
     // holds their own lock.  Thus you MUST NEVER call back into the activity manager
     // or window manager or anything that depends on them while holding this lock.
-    final HashMap<String, WeakReference<LoadedApk>> mPackages
-            = new HashMap<String, WeakReference<LoadedApk>>();
-    final HashMap<String, WeakReference<LoadedApk>> mResourcePackages
-            = new HashMap<String, WeakReference<LoadedApk>>();
-    final HashMap<CompatibilityInfo, DisplayMetrics> mDefaultDisplayMetrics
-            = new HashMap<CompatibilityInfo, DisplayMetrics>();
-    final HashMap<ResourcesKey, WeakReference<Resources> > mActiveResources
-            = new HashMap<ResourcesKey, WeakReference<Resources> >();
+    final ArrayMap<String, WeakReference<LoadedApk>> mPackages
+            = new ArrayMap<String, WeakReference<LoadedApk>>();
+    final ArrayMap<String, WeakReference<LoadedApk>> mResourcePackages
+            = new ArrayMap<String, WeakReference<LoadedApk>>();
     final ArrayList<ActivityClientRecord> mRelaunchingActivities
             = new ArrayList<ActivityClientRecord>();
     Configuration mPendingConfiguration = null;
 
+    private final ResourcesManager mResourcesManager;
+
     private static final class ProviderKey {
         final String authority;
         final int userId;
@@ -242,17 +232,17 @@
     }
 
     // The lock of mProviderMap protects the following variables.
-    final HashMap<ProviderKey, ProviderClientRecord> mProviderMap
-        = new HashMap<ProviderKey, ProviderClientRecord>();
-    final HashMap<IBinder, ProviderRefCount> mProviderRefCountMap
-        = new HashMap<IBinder, ProviderRefCount>();
-    final HashMap<IBinder, ProviderClientRecord> mLocalProviders
-        = new HashMap<IBinder, ProviderClientRecord>();
-    final HashMap<ComponentName, ProviderClientRecord> mLocalProvidersByName
-            = new HashMap<ComponentName, ProviderClientRecord>();
+    final ArrayMap<ProviderKey, ProviderClientRecord> mProviderMap
+        = new ArrayMap<ProviderKey, ProviderClientRecord>();
+    final ArrayMap<IBinder, ProviderRefCount> mProviderRefCountMap
+        = new ArrayMap<IBinder, ProviderRefCount>();
+    final ArrayMap<IBinder, ProviderClientRecord> mLocalProviders
+        = new ArrayMap<IBinder, ProviderClientRecord>();
+    final ArrayMap<ComponentName, ProviderClientRecord> mLocalProvidersByName
+            = new ArrayMap<ComponentName, ProviderClientRecord>();
 
-    final HashMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners
-        = new HashMap<Activity, ArrayList<OnActivityPausedListener>>();
+    final ArrayMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners
+        = new ArrayMap<Activity, ArrayList<OnActivityPausedListener>>();
 
     final GcIdler mGcIdler = new GcIdler();
     boolean mGcIdlerScheduled = false;
@@ -534,25 +524,27 @@
         CompatibilityInfo info;
     }
 
-    static final class RequestActivityExtras {
+    static final class RequestAssistContextExtras {
         IBinder activityToken;
         IBinder requestToken;
         int requestType;
     }
-    
+
     private native void dumpGraphicsInfo(FileDescriptor fd);
 
     private class ApplicationThread extends ApplicationThreadNative {
-        private static final String HEAP_COLUMN = "%13s %8s %8s %8s %8s %8s %8s";
+        private static final String HEAP_COLUMN = "%13s %8s %8s %8s %8s %8s %8s %8s %8s %8s";
         private static final String ONE_COUNT_COLUMN = "%21s %8d";
         private static final String TWO_COUNT_COLUMNS = "%21s %8d %21s %8d";
         private static final String DB_INFO_FORMAT = "  %8s %8s %14s %14s  %s";
 
         // Formatting for checkin service - update version if row format changes
-        private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 1;
+        private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 3;
+
+        private int mLastProcessState = -1;
 
         private void updatePendingConfiguration(Configuration config) {
-            synchronized (mPackages) {
+            synchronized (mResourcesManager) {
                 if (mPendingConfiguration == null ||
                         mPendingConfiguration.isOtherSeqNewer(config)) {
                     mPendingConfiguration = config;
@@ -586,7 +578,9 @@
             queueOrSendMessage(H.SLEEPING, token, sleeping ? 1 : 0);
         }
 
-        public final void scheduleResumeActivity(IBinder token, boolean isForward) {
+        public final void scheduleResumeActivity(IBinder token, int processState,
+                boolean isForward) {
+            updateProcessState(processState, false);
             queueOrSendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0);
         }
 
@@ -601,9 +595,12 @@
         // activity itself back to the activity manager. (matters more with ipc)
         public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                 ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
-                Bundle state, List<ResultInfo> pendingResults,
+                int procState, Bundle state, List<ResultInfo> pendingResults,
                 List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
                 String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
+
+            updateProcessState(procState, false);
+
             ActivityClientRecord r = new ActivityClientRecord();
 
             r.token = token;
@@ -651,7 +648,8 @@
 
         public final void scheduleReceiver(Intent intent, ActivityInfo info,
                 CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
-                boolean sync, int sendingUser) {
+                boolean sync, int sendingUser, int processState) {
+            updateProcessState(processState, false);
             ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
                     sync, false, mAppThread.asBinder(), sendingUser);
             r.info = info;
@@ -679,7 +677,8 @@
         }
 
         public final void scheduleCreateService(IBinder token,
-                ServiceInfo info, CompatibilityInfo compatInfo) {
+                ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
+            updateProcessState(processState, false);
             CreateServiceData s = new CreateServiceData();
             s.token = token;
             s.info = info;
@@ -689,7 +688,8 @@
         }
 
         public final void scheduleBindService(IBinder token, Intent intent,
-                boolean rebind) {
+                boolean rebind, int processState) {
+            updateProcessState(processState, false);
             BindServiceData s = new BindServiceData();
             s.token = token;
             s.intent = intent;
@@ -788,8 +788,8 @@
             InetAddress.clearDnsCache();
         }
 
-        public void setHttpProxy(String host, String port, String exclList) {
-            Proxy.setHttpProxySystemProperty(host, port, exclList);
+        public void setHttpProxy(String host, String port, String exclList, String pacFileUrl) {
+            Proxy.setHttpProxySystemProperty(host, port, exclList, pacFileUrl);
         }
 
         public void processInBackground() {
@@ -814,7 +814,8 @@
         // applies transaction ordering per object for such calls.
         public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
                 int resultCode, String dataStr, Bundle extras, boolean ordered,
-                boolean sticky, int sendingUser) throws RemoteException {
+                boolean sticky, int sendingUser, int processState) throws RemoteException {
+            updateProcessState(processState, false);
             receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
                     sticky, sendingUser);
         }
@@ -895,17 +896,18 @@
 
         @Override
         public Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, boolean checkin,
-                boolean all, String[] args) {
+                boolean dumpInfo, boolean dumpDalvik, String[] args) {
             FileOutputStream fout = new FileOutputStream(fd);
-            PrintWriter pw = new PrintWriter(fout);
+            PrintWriter pw = new FastPrintWriter(fout);
             try {
-                return dumpMemInfo(pw, checkin, all);
+                return dumpMemInfo(pw, checkin, dumpInfo, dumpDalvik);
             } finally {
                 pw.flush();
             }
         }
 
-        private Debug.MemoryInfo dumpMemInfo(PrintWriter pw, boolean checkin, boolean all) {
+        private Debug.MemoryInfo dumpMemInfo(PrintWriter pw, boolean checkin, boolean dumpInfo,
+                boolean dumpDalvik) {
             long nativeMax = Debug.getNativeHeapSize() / 1024;
             long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
             long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
@@ -913,7 +915,7 @@
             Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
             Debug.getMemoryInfo(memInfo);
 
-            if (!all) {
+            if (!dumpInfo) {
                 return memInfo;
             }
 
@@ -968,21 +970,48 @@
                 pw.print(memInfo.nativePss); pw.print(',');
                 pw.print(memInfo.dalvikPss); pw.print(',');
                 pw.print(memInfo.otherPss); pw.print(',');
-                pw.print(memInfo.nativePss + memInfo.dalvikPss + memInfo.otherPss); pw.print(',');
+                pw.print(memInfo.getTotalPss()); pw.print(',');
 
-                // Heap info - shared
+                // Heap info - swappable set size
+                pw.print(memInfo.nativeSwappablePss); pw.print(',');
+                pw.print(memInfo.dalvikSwappablePss); pw.print(',');
+                pw.print(memInfo.otherSwappablePss); pw.print(',');
+                pw.print(memInfo.getTotalSwappablePss()); pw.print(',');
+
+                // Heap info - shared dirty
                 pw.print(memInfo.nativeSharedDirty); pw.print(',');
                 pw.print(memInfo.dalvikSharedDirty); pw.print(',');
                 pw.print(memInfo.otherSharedDirty); pw.print(',');
-                pw.print(memInfo.nativeSharedDirty + memInfo.dalvikSharedDirty
-                        + memInfo.otherSharedDirty); pw.print(',');
+                pw.print(memInfo.getTotalSharedDirty()); pw.print(',');
 
-                // Heap info - private
+                // Heap info - shared clean
+                pw.print(memInfo.nativeSharedClean); pw.print(',');
+                pw.print(memInfo.dalvikSharedClean); pw.print(',');
+                pw.print(memInfo.otherSharedClean); pw.print(',');
+                pw.print(memInfo.getTotalSharedClean()); pw.print(',');
+
+                // Heap info - private Dirty
                 pw.print(memInfo.nativePrivateDirty); pw.print(',');
                 pw.print(memInfo.dalvikPrivateDirty); pw.print(',');
                 pw.print(memInfo.otherPrivateDirty); pw.print(',');
-                pw.print(memInfo.nativePrivateDirty + memInfo.dalvikPrivateDirty
-                        + memInfo.otherPrivateDirty); pw.print(',');
+                pw.print(memInfo.getTotalPrivateDirty()); pw.print(',');
+
+                // Heap info - private Clean
+                pw.print(memInfo.nativePrivateClean); pw.print(',');
+                pw.print(memInfo.dalvikPrivateClean); pw.print(',');
+                pw.print(memInfo.otherPrivateClean); pw.print(',');
+                pw.print(memInfo.getTotalPrivateClean()); pw.print(',');
+
+                // Heap info - other areas
+                for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
+                    pw.print(Debug.MemoryInfo.getOtherLabel(i)); pw.print(',');
+                    pw.print(memInfo.getOtherPss(i)); pw.print(',');
+                    pw.print(memInfo.getOtherSwappablePss(i)); pw.print(',');
+                    pw.print(memInfo.getOtherSharedDirty(i)); pw.print(',');
+                    pw.print(memInfo.getOtherSharedClean(i)); pw.print(',');
+                    pw.print(memInfo.getOtherPrivateDirty(i)); pw.print(',');
+                    pw.print(memInfo.getOtherPrivateClean(i)); pw.print(',');
+                }
 
                 // Object counts
                 pw.print(viewInstanceCount); pw.print(',');
@@ -1018,34 +1047,80 @@
             }
 
             // otherwise, show human-readable format
-            printRow(pw, HEAP_COLUMN, "", "", "Shared", "Private", "Heap", "Heap", "Heap");
-            printRow(pw, HEAP_COLUMN, "", "Pss", "Dirty", "Dirty", "Size", "Alloc", "Free");
+            printRow(pw, HEAP_COLUMN, "", "Pss", "Pss","Shared", "Private", "Shared", "Private",
+                    "Heap", "Heap", "Heap");
+            printRow(pw, HEAP_COLUMN, "", "Total", "Clean", "Dirty", "Dirty", "Clean", "Clean",
+                    "Size", "Alloc", "Free");
             printRow(pw, HEAP_COLUMN, "", "------", "------", "------", "------", "------",
-                    "------");
-            printRow(pw, HEAP_COLUMN, "Native", memInfo.nativePss, memInfo.nativeSharedDirty,
-                    memInfo.nativePrivateDirty, nativeMax, nativeAllocated, nativeFree);
-            printRow(pw, HEAP_COLUMN, "Dalvik", memInfo.dalvikPss, memInfo.dalvikSharedDirty,
-                    memInfo.dalvikPrivateDirty, dalvikMax, dalvikAllocated, dalvikFree);
+                    "------", "------", "------", "------");
+            printRow(pw, HEAP_COLUMN, "Native Heap", memInfo.nativePss, memInfo.nativeSwappablePss,
+                    memInfo.nativeSharedDirty,
+                    memInfo.nativePrivateDirty, memInfo.nativeSharedClean,
+                    memInfo.nativePrivateClean, nativeMax, nativeAllocated, nativeFree);
+            printRow(pw, HEAP_COLUMN, "Dalvik Heap", memInfo.dalvikPss, memInfo.dalvikSwappablePss,
+                    memInfo.dalvikSharedDirty,
+                    memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean,
+                    memInfo.dalvikPrivateClean, dalvikMax, dalvikAllocated, dalvikFree);
 
             int otherPss = memInfo.otherPss;
+            int otherSwappablePss = memInfo.otherSwappablePss;
             int otherSharedDirty = memInfo.otherSharedDirty;
             int otherPrivateDirty = memInfo.otherPrivateDirty;
+            int otherSharedClean = memInfo.otherSharedClean;
+            int otherPrivateClean = memInfo.otherPrivateClean;
 
             for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
-                printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
-                        memInfo.getOtherPss(i), memInfo.getOtherSharedDirty(i),
-                        memInfo.getOtherPrivateDirty(i), "", "", "");
-                otherPss -= memInfo.getOtherPss(i);
-                otherSharedDirty -= memInfo.getOtherSharedDirty(i);
-                otherPrivateDirty -= memInfo.getOtherPrivateDirty(i);
+                final int myPss = memInfo.getOtherPss(i);
+                final int mySwappablePss = memInfo.getOtherSwappablePss(i);
+                final int mySharedDirty = memInfo.getOtherSharedDirty(i);
+                final int myPrivateDirty = memInfo.getOtherPrivateDirty(i);
+                final int mySharedClean = memInfo.getOtherSharedClean(i);
+                final int myPrivateClean = memInfo.getOtherPrivateClean(i);
+                if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
+                        || mySharedClean != 0 || myPrivateClean != 0) {
+                    printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
+                            myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
+                            mySharedClean, myPrivateClean, "", "", "");
+                    otherPss -= myPss;
+                    otherSwappablePss -= mySwappablePss;
+                    otherSharedDirty -= mySharedDirty;
+                    otherPrivateDirty -= myPrivateDirty;
+                    otherSharedClean -= mySharedClean;
+                    otherPrivateClean -= myPrivateClean;
+                }
             }
 
-            printRow(pw, HEAP_COLUMN, "Unknown", otherPss, otherSharedDirty,
-                    otherPrivateDirty, "", "", "");
+
+
+            printRow(pw, HEAP_COLUMN, "Unknown", otherPss, otherSwappablePss, otherSharedDirty,
+                    otherPrivateDirty, otherSharedClean, otherPrivateClean,"", "", "");
             printRow(pw, HEAP_COLUMN, "TOTAL", memInfo.getTotalPss(),
+                    memInfo.getTotalSwappablePss(),
                     memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(),
-                    nativeMax+dalvikMax, nativeAllocated+dalvikAllocated,
-                    nativeFree+dalvikFree);
+                    memInfo.getTotalSharedClean(), memInfo.getTotalPrivateClean(),
+                    nativeMax+dalvikMax,
+                    nativeAllocated+dalvikAllocated, nativeFree+dalvikFree);
+
+            if (dumpDalvik) {
+                pw.println(" ");
+                pw.println(" Dalvik Details");
+
+                for (int i=Debug.MemoryInfo.NUM_OTHER_STATS;
+                     i<Debug.MemoryInfo.NUM_OTHER_STATS + Debug.MemoryInfo.NUM_DVK_STATS; i++) {
+                    final int myPss = memInfo.getOtherPss(i);
+                    final int mySwappablePss = memInfo.getOtherSwappablePss(i);
+                    final int mySharedDirty = memInfo.getOtherSharedDirty(i);
+                    final int myPrivateDirty = memInfo.getOtherPrivateDirty(i);
+                    final int mySharedClean = memInfo.getOtherSharedClean(i);
+                    final int myPrivateClean = memInfo.getOtherPrivateClean(i);
+                    if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
+                            || mySharedClean != 0 || myPrivateClean != 0) {
+                        printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
+                                myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
+                                mySharedClean, myPrivateClean, "", "", "");
+                    }
+                }
+            }
 
             pw.println(" ");
             pw.println(" Objects");
@@ -1105,7 +1180,7 @@
 
         @Override
         public void dumpDbInfo(FileDescriptor fd, String[] args) {
-            PrintWriter pw = new PrintWriter(new FileOutputStream(fd));
+            PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd));
             PrintWriterPrinter printer = new PrintWriterPrinter(pw);
             SQLiteDebug.dump(printer, args);
             pw.flush();
@@ -1117,13 +1192,13 @@
         }
 
         @Override
-        public void requestActivityExtras(IBinder activityToken, IBinder requestToken,
+        public void requestAssistContextExtras(IBinder activityToken, IBinder requestToken,
                 int requestType) {
-            RequestActivityExtras cmd = new RequestActivityExtras();
+            RequestAssistContextExtras cmd = new RequestAssistContextExtras();
             cmd.activityToken = activityToken;
             cmd.requestToken = requestToken;
             cmd.requestType = requestType;
-            queueOrSendMessage(H.REQUEST_ACTIVITY_EXTRAS, cmd);
+            queueOrSendMessage(H.REQUEST_ASSIST_CONTEXT_EXTRAS, cmd);
         }
 
         private void printRow(PrintWriter pw, String format, Object...objs) {
@@ -1145,6 +1220,27 @@
             queueOrSendMessage(H.TRIM_MEMORY, null, level);
         }
 
+        public void scheduleTranslucentConversionComplete(IBinder token, boolean drawComplete) {
+            queueOrSendMessage(H.TRANSLUCENT_CONVERSION_COMPLETE, token, drawComplete ? 1 : 0);
+        }
+
+        public void setProcessState(int state) {
+            updateProcessState(state, true);
+        }
+
+        public void updateProcessState(int processState, boolean fromIpc) {
+            synchronized (this) {
+                if (mLastProcessState != processState) {
+                    mLastProcessState = processState;
+
+                    // Update Dalvik state here based on ActivityManager.PROCESS_STATE_* constants.
+                    if (false) {
+                        Slog.i(TAG, "******************* PROCESS STATE CHANGED TO: " + processState
+                                + (fromIpc ? " (from ipc": ""));
+                    }
+                }
+            }
+        }
     }
 
     private class H extends Handler {
@@ -1191,7 +1287,8 @@
         public static final int TRIM_MEMORY             = 140;
         public static final int DUMP_PROVIDER           = 141;
         public static final int UNSTABLE_PROVIDER_DIED  = 142;
-        public static final int REQUEST_ACTIVITY_EXTRAS = 143;
+        public static final int REQUEST_ASSIST_CONTEXT_EXTRAS = 143;
+        public static final int TRANSLUCENT_CONVERSION_COMPLETE = 144;
         String codeToString(int code) {
             if (DEBUG_MESSAGES) {
                 switch (code) {
@@ -1238,7 +1335,8 @@
                     case TRIM_MEMORY: return "TRIM_MEMORY";
                     case DUMP_PROVIDER: return "DUMP_PROVIDER";
                     case UNSTABLE_PROVIDER_DIED: return "UNSTABLE_PROVIDER_DIED";
-                    case REQUEST_ACTIVITY_EXTRAS: return "REQUEST_ACTIVITY_EXTRAS";
+                    case REQUEST_ASSIST_CONTEXT_EXTRAS: return "REQUEST_ASSIST_CONTEXT_EXTRAS";
+                    case TRANSLUCENT_CONVERSION_COMPLETE: return "TRANSLUCENT_CONVERSION_COMPLETE";
                 }
             }
             return Integer.toString(code);
@@ -1450,8 +1548,11 @@
                 case UNSTABLE_PROVIDER_DIED:
                     handleUnstableProviderDied((IBinder)msg.obj, false);
                     break;
-                case REQUEST_ACTIVITY_EXTRAS:
-                    handleRequestActivityExtras((RequestActivityExtras)msg.obj);
+                case REQUEST_ASSIST_CONTEXT_EXTRAS:
+                    handleRequestAssistContextExtras((RequestAssistContextExtras)msg.obj);
+                    break;
+                case TRANSLUCENT_CONVERSION_COMPLETE:
+                    handleTranslucentConversionComplete((IBinder)msg.obj, msg.arg1 == 1);
                     break;
             }
             if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
@@ -1485,6 +1586,7 @@
     }
 
     private class Idler implements MessageQueue.IdleHandler {
+        @Override
         public final boolean queueIdle() {
             ActivityClientRecord a = mNewActivities;
             boolean stopProfiling = false;
@@ -1523,70 +1625,13 @@
     }
 
     final class GcIdler implements MessageQueue.IdleHandler {
+        @Override
         public final boolean queueIdle() {
             doGcIfNeeded();
             return false;
         }
     }
 
-    private static class ResourcesKey {
-        final private String mResDir;
-        final private int mDisplayId;
-        final private Configuration mOverrideConfiguration;
-        final private float mScale;
-        final private int mHash;
-
-        ResourcesKey(String resDir, int displayId, Configuration overrideConfiguration, float scale) {
-            mResDir = resDir;
-            mDisplayId = displayId;
-            if (overrideConfiguration != null) {
-                if (Configuration.EMPTY.equals(overrideConfiguration)) {
-                    overrideConfiguration = null;
-                }
-            }
-            mOverrideConfiguration = overrideConfiguration;
-            mScale = scale;
-            int hash = 17;
-            hash = 31 * hash + mResDir.hashCode();
-            hash = 31 * hash + mDisplayId;
-            hash = 31 * hash + (mOverrideConfiguration != null
-                    ? mOverrideConfiguration.hashCode() : 0);
-            hash = 31 * hash + Float.floatToIntBits(mScale);
-            mHash = hash;
-        }
-
-        @Override
-        public int hashCode() {
-            return mHash;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (!(obj instanceof ResourcesKey)) {
-                return false;
-            }
-            ResourcesKey peer = (ResourcesKey) obj;
-            if (!mResDir.equals(peer.mResDir)) {
-                return false;
-            }
-            if (mDisplayId != peer.mDisplayId) {
-                return false;
-            }
-            if (mOverrideConfiguration != peer.mOverrideConfiguration) {
-                if (mOverrideConfiguration == null || peer.mOverrideConfiguration == null) {
-                    return false;
-                }
-                if (!mOverrideConfiguration.equals(peer.mOverrideConfiguration)) {
-                    return false;
-                }
-            }
-            if (mScale != peer.mScale) {
-                return false;
-            }
-            return true;
-        }
-    }
-
     public static ActivityThread currentActivityThread() {
         return sCurrentActivityThread;
     }
@@ -1620,54 +1665,13 @@
         return sPackageManager;
     }
 
-    private void flushDisplayMetricsLocked() {
-        mDefaultDisplayMetrics.clear();
-    }
-
-    DisplayMetrics getDisplayMetricsLocked(int displayId, CompatibilityInfo ci) {
-        boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
-        DisplayMetrics dm = isDefaultDisplay ? mDefaultDisplayMetrics.get(ci) : null;
-        if (dm != null) {
-            return dm;
-        }
-        dm = new DisplayMetrics();
-
-        DisplayManagerGlobal displayManager = DisplayManagerGlobal.getInstance();
-        if (displayManager == null) {
-            // may be null early in system startup
-            dm.setToDefaults();
-            return dm;
-        }
-
-        if (isDefaultDisplay) {
-            mDefaultDisplayMetrics.put(ci, dm);
-        }
-
-        CompatibilityInfoHolder cih = new CompatibilityInfoHolder();
-        cih.set(ci);
-        Display d = displayManager.getCompatibleDisplay(displayId, cih);
-        if (d != null) {
-            d.getMetrics(dm);
-        } else {
-            // Display no longer exists
-            // FIXME: This would not be a problem if we kept the Display object around
-            // instead of using the raw display id everywhere.  The Display object caches
-            // its information even after the display has been removed.
-            dm.setToDefaults();
-        }
-        //Slog.i("foo", "New metrics: w=" + metrics.widthPixels + " h="
-        //        + metrics.heightPixels + " den=" + metrics.density
-        //        + " xdpi=" + metrics.xdpi + " ydpi=" + metrics.ydpi);
-        return dm;
-    }
-
     private Configuration mMainThreadConfig = new Configuration();
     Configuration applyConfigCompatMainThread(int displayDensity, Configuration config,
             CompatibilityInfo compat) {
         if (config == null) {
             return null;
         }
-        if (compat != null && !compat.supportsScreen()) {
+        if (!compat.supportsScreen()) {
             mMainThreadConfig.setTo(config);
             config = mMainThreadConfig;
             compat.applyToConfiguration(displayDensity, config);
@@ -1676,93 +1680,13 @@
     }
 
     /**
-     * Creates the top level Resources for applications with the given compatibility info.
-     *
-     * @param resDir the resource directory.
-     * @param compInfo the compability info. It will use the default compatibility info when it's
-     * null.
-     */
-    Resources getTopLevelResources(String resDir,
-            int displayId, Configuration overrideConfiguration,
-            CompatibilityInfo compInfo) {
-        ResourcesKey key = new ResourcesKey(resDir,
-                displayId, overrideConfiguration,
-                compInfo.applicationScale);
-        Resources r;
-        synchronized (mPackages) {
-            // Resources is app scale dependent.
-            if (false) {
-                Slog.w(TAG, "getTopLevelResources: " + resDir + " / "
-                        + compInfo.applicationScale);
-            }
-            WeakReference<Resources> wr = mActiveResources.get(key);
-            r = wr != null ? wr.get() : null;
-            //if (r != null) Slog.i(TAG, "isUpToDate " + resDir + ": " + r.getAssets().isUpToDate());
-            if (r != null && r.getAssets().isUpToDate()) {
-                if (false) {
-                    Slog.w(TAG, "Returning cached resources " + r + " " + resDir
-                            + ": appScale=" + r.getCompatibilityInfo().applicationScale);
-                }
-                return r;
-            }
-        }
-
-        //if (r != null) {
-        //    Slog.w(TAG, "Throwing away out-of-date resources!!!! "
-        //            + r + " " + resDir);
-        //}
-
-        AssetManager assets = new AssetManager();
-        if (assets.addAssetPath(resDir) == 0) {
-            return null;
-        }
-
-        //Slog.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
-        DisplayMetrics dm = getDisplayMetricsLocked(displayId, null);
-        Configuration config;
-        boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
-        if (!isDefaultDisplay || key.mOverrideConfiguration != null) {
-            config = new Configuration(getConfiguration());
-            if (!isDefaultDisplay) {
-                applyNonDefaultDisplayMetricsToConfigurationLocked(dm, config);
-            }
-            if (key.mOverrideConfiguration != null) {
-                config.updateFrom(key.mOverrideConfiguration);
-            }
-        } else {
-            config = getConfiguration();
-        }
-        r = new Resources(assets, dm, config, compInfo);
-        if (false) {
-            Slog.i(TAG, "Created app resources " + resDir + " " + r + ": "
-                    + r.getConfiguration() + " appScale="
-                    + r.getCompatibilityInfo().applicationScale);
-        }
-
-        synchronized (mPackages) {
-            WeakReference<Resources> wr = mActiveResources.get(key);
-            Resources existing = wr != null ? wr.get() : null;
-            if (existing != null && existing.getAssets().isUpToDate()) {
-                // Someone else already created the resources while we were
-                // unlocked; go ahead and use theirs.
-                r.getAssets().close();
-                return existing;
-            }
-            
-            // XXX need to remove entries when weak references go away
-            mActiveResources.put(key, new WeakReference<Resources>(r));
-            return r;
-        }
-    }
-
-    /**
      * Creates the top level resources for the given package.
      */
     Resources getTopLevelResources(String resDir,
             int displayId, Configuration overrideConfiguration,
             LoadedApk pkgInfo) {
-        return getTopLevelResources(resDir, displayId, overrideConfiguration,
-                pkgInfo.mCompatibilityInfo.get());
+        return mResourcesManager.getTopLevelResources(resDir, displayId, overrideConfiguration,
+                pkgInfo.getCompatibilityInfo(), null);
     }
 
     final Handler getHandler() {
@@ -1776,7 +1700,7 @@
 
     public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
             int flags, int userId) {
-        synchronized (mPackages) {
+        synchronized (mResourcesManager) {
             WeakReference<LoadedApk> ref;
             if ((flags&Context.CONTEXT_INCLUDE_CODE) != 0) {
                 ref = mPackages.get(packageName);
@@ -1846,7 +1770,7 @@
     }
 
     public final LoadedApk peekPackageInfo(String packageName, boolean includeCode) {
-        synchronized (mPackages) {
+        synchronized (mResourcesManager) {
             WeakReference<LoadedApk> ref;
             if (includeCode) {
                 ref = mPackages.get(packageName);
@@ -1859,7 +1783,7 @@
 
     private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
             ClassLoader baseLoader, boolean securityViolation, boolean includeCode) {
-        synchronized (mPackages) {
+        synchronized (mResourcesManager) {
             WeakReference<LoadedApk> ref;
             if (includeCode) {
                 ref = mPackages.get(aInfo.packageName);
@@ -1891,6 +1815,7 @@
     }
 
     ActivityThread() {
+        mResourcesManager = ResourcesManager.getInstance();
     }
 
     public ApplicationThread getApplicationThread()
@@ -1903,10 +1828,6 @@
         return mInstrumentation;
     }
 
-    public Configuration getConfiguration() {
-        return mResConfiguration;
-    }
-
     public boolean isProfiling() {
         return mProfiler != null && mProfiler.profileFile != null
                 && mProfiler.profileFd == null;
@@ -1936,10 +1857,8 @@
                 LoadedApk info = new LoadedApk(this, "android", context, null,
                         CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO);
                 context.init(info, null, this);
-                context.getResources().updateConfiguration(
-                        getConfiguration(), getDisplayMetricsLocked(
-                                Display.DEFAULT_DISPLAY,
-                                CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO));
+                context.getResources().updateConfiguration(mResourcesManager.getConfiguration(),
+                        mResourcesManager.getDisplayMetricsLocked(Display.DEFAULT_DISPLAY));
                 mSystemContext = context;
                 //Slog.i(TAG, "Created system resources " + context.getResources()
                 //        + ": " + context.getResources().getConfiguration());
@@ -1965,7 +1884,7 @@
             dalvik.system.VMRuntime.getRuntime().startJitCompilation();
         }
     }
-    
+
     void scheduleGcIdler() {
         if (!mGcIdlerScheduled) {
             mGcIdlerScheduled = true;
@@ -2232,7 +2151,7 @@
             DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
             for (int displayId : dm.getDisplayIds()) {
                 if (displayId != Display.DEFAULT_DISPLAY) {
-                    Display display = dm.getRealDisplay(displayId);
+                    Display display = dm.getRealDisplay(displayId, r.token);
                     baseContext = appContext.createDisplayContext(display);
                     break;
                 }
@@ -2351,7 +2270,7 @@
         performNewIntents(data.token, data.intents);
     }
 
-    public void handleRequestActivityExtras(RequestActivityExtras cmd) {
+    public void handleRequestAssistContextExtras(RequestAssistContextExtras cmd) {
         Bundle data = new Bundle();
         ActivityClientRecord r = mActivities.get(cmd.activityToken);
         if (r != null) {
@@ -2363,11 +2282,18 @@
         }
         IActivityManager mgr = ActivityManagerNative.getDefault();
         try {
-            mgr.reportTopActivityExtras(cmd.requestToken, data);
+            mgr.reportAssistContextExtras(cmd.requestToken, data);
         } catch (RemoteException e) {
         }
     }
-    
+
+    public void handleTranslucentConversionComplete(IBinder token, boolean drawComplete) {
+        ActivityClientRecord r = mActivities.get(token);
+        if (r != null) {
+            r.activity.onTranslucentConversionComplete(drawComplete);
+        }
+    }
+
     private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>();
 
     /**
@@ -2651,7 +2577,8 @@
         try {
             Service s = mServices.get(info.token);
             if (s != null) {
-                PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd.getFileDescriptor()));
+                PrintWriter pw = new FastPrintWriter(new FileOutputStream(
+                        info.fd.getFileDescriptor()));
                 s.dump(info.fd.getFileDescriptor(), pw, info.args);
                 pw.flush();
             }
@@ -2666,7 +2593,8 @@
         try {
             ActivityClientRecord r = mActivities.get(info.token);
             if (r != null && r.activity != null) {
-                PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd.getFileDescriptor()));
+                PrintWriter pw = new FastPrintWriter(new FileOutputStream(
+                        info.fd.getFileDescriptor()));
                 r.activity.dump(info.prefix, info.fd.getFileDescriptor(), pw, info.args);
                 pw.flush();
             }
@@ -2681,7 +2609,8 @@
         try {
             ProviderClientRecord r = mLocalProviders.get(info.token);
             if (r != null && r.mLocalProvider != null) {
-                PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd.getFileDescriptor()));
+                PrintWriter pw = new FastPrintWriter(new FileOutputStream(
+                        info.fd.getFileDescriptor()));
                 r.mLocalProvider.dump(info.fd.getFileDescriptor(), pw, info.args);
                 pw.flush();
             }
@@ -3331,7 +3260,7 @@
     }
 
     private void handleSetCoreSettings(Bundle coreSettings) {
-        synchronized (mPackages) {
+        synchronized (mResourcesManager) {
             mCoreSettings = coreSettings;
         }
     }
@@ -3339,11 +3268,11 @@
     private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) {
         LoadedApk apk = peekPackageInfo(data.pkg, false);
         if (apk != null) {
-            apk.mCompatibilityInfo.set(data.info);
+            apk.setCompatibilityInfo(data.info);
         }
         apk = peekPackageInfo(data.pkg, true);
         if (apk != null) {
-            apk.mCompatibilityInfo.set(data.info);
+            apk.setCompatibilityInfo(data.info);
         }
         handleConfigurationChanged(mConfiguration, data.info);
         WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration);
@@ -3421,7 +3350,7 @@
     private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
             int configChanges, boolean getNonConfigInstance) {
         ActivityClientRecord r = mActivities.get(token);
-        Class activityClass = null;
+        Class<? extends Activity> activityClass = null;
         if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
         if (r != null) {
             activityClass = r.activity.getClass();
@@ -3576,7 +3505,7 @@
             boolean fromServer) {
         ActivityClientRecord target = null;
 
-        synchronized (mPackages) {
+        synchronized (mResourcesManager) {
             for (int i=0; i<mRelaunchingActivities.size(); i++) {
                 ActivityClientRecord r = mRelaunchingActivities.get(i);
                 if (r.token == token) {
@@ -3637,7 +3566,7 @@
         // First: make sure we have the most recent configuration and most
         // recent version of the activity, or skip it if some previous call
         // had taken a more recent version.
-        synchronized (mPackages) {
+        synchronized (mResourcesManager) {
             int N = mRelaunchingActivities.size();
             IBinder token = tmp.token;
             tmp = null;
@@ -3766,47 +3695,46 @@
         ArrayList<ComponentCallbacks2> callbacks
                 = new ArrayList<ComponentCallbacks2>();
 
-        synchronized (mPackages) {
-            final int N = mAllApplications.size();
-            for (int i=0; i<N; i++) {
+        synchronized (mResourcesManager) {
+            final int NAPP = mAllApplications.size();
+            for (int i=0; i<NAPP; i++) {
                 callbacks.add(mAllApplications.get(i));
             }
-            if (mActivities.size() > 0) {
-                for (ActivityClientRecord ar : mActivities.values()) {
-                    Activity a = ar.activity;
-                    if (a != null) {
-                        Configuration thisConfig = applyConfigCompatMainThread(mCurDefaultDisplayDpi,
-                                newConfig, ar.packageInfo.mCompatibilityInfo.getIfNeeded());
-                        if (!ar.activity.mFinished && (allActivities || !ar.paused)) {
-                            // If the activity is currently resumed, its configuration
-                            // needs to change right now.
-                            callbacks.add(a);
-                        } else if (thisConfig != null) {
-                            // Otherwise, we will tell it about the change
-                            // the next time it is resumed or shown.  Note that
-                            // the activity manager may, before then, decide the
-                            // activity needs to be destroyed to handle its new
-                            // configuration.
-                            if (DEBUG_CONFIGURATION) {
-                                Slog.v(TAG, "Setting activity "
-                                        + ar.activityInfo.name + " newConfig=" + thisConfig);
-                            }
-                            ar.newConfig = thisConfig;
+            final int NACT = mActivities.size();
+            for (int i=0; i<NACT; i++) {
+                ActivityClientRecord ar = mActivities.valueAt(i);
+                Activity a = ar.activity;
+                if (a != null) {
+                    Configuration thisConfig = applyConfigCompatMainThread(
+                            mCurDefaultDisplayDpi, newConfig,
+                            ar.packageInfo.getCompatibilityInfo());
+                    if (!ar.activity.mFinished && (allActivities || !ar.paused)) {
+                        // If the activity is currently resumed, its configuration
+                        // needs to change right now.
+                        callbacks.add(a);
+                    } else if (thisConfig != null) {
+                        // Otherwise, we will tell it about the change
+                        // the next time it is resumed or shown.  Note that
+                        // the activity manager may, before then, decide the
+                        // activity needs to be destroyed to handle its new
+                        // configuration.
+                        if (DEBUG_CONFIGURATION) {
+                            Slog.v(TAG, "Setting activity "
+                                    + ar.activityInfo.name + " newConfig=" + thisConfig);
                         }
+                        ar.newConfig = thisConfig;
                     }
                 }
             }
-            if (mServices.size() > 0) {
-                for (Service service : mServices.values()) {
-                    callbacks.add(service);
-                }
+            final int NSVC = mServices.size();
+            for (int i=0; i<NSVC; i++) {
+                callbacks.add(mServices.valueAt(i));
             }
         }
         synchronized (mProviderMap) {
-            if (mLocalProviders.size() > 0) {
-                for (ProviderClientRecord providerClientRecord : mLocalProviders.values()) {
-                    callbacks.add(providerClientRecord.mLocalProvider);
-                }
+            final int NPRV = mLocalProviders.size();
+            for (int i=0; i<NPRV; i++) {
+                callbacks.add(mLocalProviders.valueAt(i).mLocalProvider);
             }
         }
 
@@ -3859,115 +3787,18 @@
     }
 
     public final void applyConfigurationToResources(Configuration config) {
-        synchronized (mPackages) {
-            applyConfigurationToResourcesLocked(config, null);
+        synchronized (mResourcesManager) {
+            mResourcesManager.applyConfigurationToResourcesLocked(config, null);
         }
     }
 
-    final boolean applyConfigurationToResourcesLocked(Configuration config,
-            CompatibilityInfo compat) {
-        if (mResConfiguration == null) {
-            mResConfiguration = new Configuration();
-        }
-        if (!mResConfiguration.isOtherSeqNewer(config) && compat == null) {
-            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Skipping new config: curSeq="
-                    + mResConfiguration.seq + ", newSeq=" + config.seq);
-            return false;
-        }
-        int changes = mResConfiguration.updateFrom(config);
-        flushDisplayMetricsLocked();
-        DisplayMetrics defaultDisplayMetrics = getDisplayMetricsLocked(
-                Display.DEFAULT_DISPLAY, null);
-
-        if (compat != null && (mResCompatibilityInfo == null ||
-                !mResCompatibilityInfo.equals(compat))) {
-            mResCompatibilityInfo = compat;
-            changes |= ActivityInfo.CONFIG_SCREEN_LAYOUT
-                    | ActivityInfo.CONFIG_SCREEN_SIZE
-                    | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
-        }
-
-        // set it for java, this also affects newly created Resources
-        if (config.locale != null) {
-            Locale.setDefault(config.locale);
-        }
-
-        Resources.updateSystemConfiguration(config, defaultDisplayMetrics, compat);
-
-        ApplicationPackageManager.configurationChanged();
-        //Slog.i(TAG, "Configuration changed in " + currentPackageName());
-
-        Configuration tmpConfig = null;
-
-        Iterator<Map.Entry<ResourcesKey, WeakReference<Resources>>> it =
-                mActiveResources.entrySet().iterator();
-        while (it.hasNext()) {
-            Map.Entry<ResourcesKey, WeakReference<Resources>> entry = it.next();
-            Resources r = entry.getValue().get();
-            if (r != null) {
-                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Changing resources "
-                        + r + " config to: " + config);
-                int displayId = entry.getKey().mDisplayId;
-                boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
-                DisplayMetrics dm = defaultDisplayMetrics;
-                Configuration overrideConfig = entry.getKey().mOverrideConfiguration;
-                if (!isDefaultDisplay || overrideConfig != null) {
-                    if (tmpConfig == null) {
-                        tmpConfig = new Configuration();
-                    }
-                    tmpConfig.setTo(config);
-                    if (!isDefaultDisplay) {
-                        dm = getDisplayMetricsLocked(displayId, null);
-                        applyNonDefaultDisplayMetricsToConfigurationLocked(dm, tmpConfig);
-                    }
-                    if (overrideConfig != null) {
-                        tmpConfig.updateFrom(overrideConfig);
-                    }
-                    r.updateConfiguration(tmpConfig, dm, compat);
-                } else {
-                    r.updateConfiguration(config, dm, compat);
-                }
-                //Slog.i(TAG, "Updated app resources " + v.getKey()
-                //        + " " + r + ": " + r.getConfiguration());
-            } else {
-                //Slog.i(TAG, "Removing old resources " + v.getKey());
-                it.remove();
-            }
-        }
-        
-        return changes != 0;
-    }
-
-    final void applyNonDefaultDisplayMetricsToConfigurationLocked(
-            DisplayMetrics dm, Configuration config) {
-        config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
-        config.densityDpi = dm.densityDpi;
-        config.screenWidthDp = (int)(dm.widthPixels / dm.density);
-        config.screenHeightDp = (int)(dm.heightPixels / dm.density);
-        int sl = Configuration.resetScreenLayout(config.screenLayout);
-        if (dm.widthPixels > dm.heightPixels) {
-            config.orientation = Configuration.ORIENTATION_LANDSCAPE;
-            config.screenLayout = Configuration.reduceScreenLayout(sl,
-                    config.screenWidthDp, config.screenHeightDp);
-        } else {
-            config.orientation = Configuration.ORIENTATION_PORTRAIT;
-            config.screenLayout = Configuration.reduceScreenLayout(sl,
-                    config.screenHeightDp, config.screenWidthDp);
-        }
-        config.smallestScreenWidthDp = config.screenWidthDp; // assume screen does not rotate
-        config.compatScreenWidthDp = config.screenWidthDp;
-        config.compatScreenHeightDp = config.screenHeightDp;
-        config.compatSmallestScreenWidthDp = config.smallestScreenWidthDp;
-    }
-
     final Configuration applyCompatConfiguration(int displayDensity) {
         Configuration config = mConfiguration;
         if (mCompatConfiguration == null) {
             mCompatConfiguration = new Configuration();
         }
         mCompatConfiguration.setTo(mConfiguration);
-        if (mResCompatibilityInfo != null && !mResCompatibilityInfo.supportsScreen()) {
-            mResCompatibilityInfo.applyToConfiguration(displayDensity, mCompatConfiguration);
+        if (mResourcesManager.applyCompatConfiguration(displayDensity, mCompatConfiguration)) {
             config = mCompatConfiguration;
         }
         return config;
@@ -3977,7 +3808,7 @@
 
         int configDiff = 0;
 
-        synchronized (mPackages) {
+        synchronized (mResourcesManager) {
             if (mPendingConfiguration != null) {
                 if (!mPendingConfiguration.isOtherSeqNewer(config)) {
                     config = mPendingConfiguration;
@@ -3993,9 +3824,9 @@
             
             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: "
                     + config);
-        
-            applyConfigurationToResourcesLocked(config, compat);
-            
+
+            mResourcesManager.applyConfigurationToResourcesLocked(config, compat);
+
             if (mConfiguration == null) {
                 mConfiguration = new Configuration();
             }
@@ -4022,7 +3853,7 @@
         }
     }
 
-    final void freeTextLayoutCachesIfNeeded(int configDiff) {
+    static void freeTextLayoutCachesIfNeeded(int configDiff) {
         if (configDiff != 0) {
             // Ask text layout engine to free its caches if there is a locale change
             boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0);
@@ -4245,7 +4076,7 @@
          * reflect configuration changes. The configuration object passed
          * in AppBindData can be safely assumed to be up to date
          */
-        applyConfigurationToResourcesLocked(data.config, data.compatInfo);
+        mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo);
         mCurDefaultDisplayDpi = data.config.densityDpi;
         applyCompatConfiguration(mCurDefaultDisplayDpi);
 
@@ -4736,12 +4567,11 @@
                 mProviderRefCountMap.remove(jBinder);
             }
 
-            Iterator<ProviderClientRecord> iter = mProviderMap.values().iterator();
-            while (iter.hasNext()) {
-                ProviderClientRecord pr = iter.next();
+            for (int i=mProviderMap.size()-1; i>=0; i--) {
+                ProviderClientRecord pr = mProviderMap.valueAt(i);
                 IBinder myBinder = pr.mProvider.asBinder();
                 if (myBinder == jBinder) {
-                    iter.remove();
+                    mProviderMap.removeAt(i);
                 }
             }
         }
@@ -4957,6 +4787,7 @@
         mSystemThread = system;
         if (!system) {
             ViewRootImpl.addFirstDrawHandler(new Runnable() {
+                @Override
                 public void run() {
                     ensureJitEnabled();
                 }
@@ -4993,12 +4824,13 @@
         DropBox.setReporter(new DropBoxReporter());
 
         ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
+            @Override
             public void onConfigurationChanged(Configuration newConfig) {
-                synchronized (mPackages) {
+                synchronized (mResourcesManager) {
                     // We need to apply this change to the resources
                     // immediately, because upon returning the view
                     // hierarchy will be informed about it.
-                    if (applyConfigurationToResourcesLocked(newConfig, null)) {
+                    if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {
                         // This actually changed the resources!  Tell
                         // everyone about it.
                         if (mPendingConfiguration == null ||
@@ -5010,8 +4842,10 @@
                     }
                 }
             }
+            @Override
             public void onLowMemory() {
             }
+            @Override
             public void onTrimMemory(int level) {
             }
         });
@@ -5031,12 +4865,11 @@
     }
 
     public int getIntCoreSetting(String key, int defaultValue) {
-        synchronized (mPackages) {
+        synchronized (mResourcesManager) {
             if (mCoreSettings != null) {
                 return mCoreSettings.getInt(key, defaultValue);
-            } else {
-                return defaultValue;
             }
+            return defaultValue;
         }
     }
 
diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java
index 2fe682d..5c3a3e5 100644
--- a/core/java/android/app/AlarmManager.java
+++ b/core/java/android/app/AlarmManager.java
@@ -16,8 +16,11 @@
 
 package android.app;
 
+import android.content.Context;
 import android.content.Intent;
+import android.os.Build;
 import android.os.RemoteException;
+import android.os.WorkSource;
 
 /**
  * This class provides access to the system alarm services.  These allow you
@@ -52,6 +55,8 @@
  */
 public class AlarmManager
 {
+    private static final String TAG = "AlarmManager";
+
     /**
      * Alarm time in {@link System#currentTimeMillis System.currentTimeMillis()}
      * (wall clock time in UTC), which will wake up the device when
@@ -80,17 +85,33 @@
      */
     public static final int ELAPSED_REALTIME = 3;
 
+    /** @hide */
+    public static final long WINDOW_EXACT = 0;
+    /** @hide */
+    public static final long WINDOW_HEURISTIC = -1;
+
     private final IAlarmManager mService;
+    private final boolean mAlwaysExact;
+
 
     /**
      * package private on purpose
      */
-    AlarmManager(IAlarmManager service) {
+    AlarmManager(IAlarmManager service, Context ctx) {
         mService = service;
+
+        final int sdkVersion = ctx.getApplicationInfo().targetSdkVersion;
+        mAlwaysExact = (sdkVersion < Build.VERSION_CODES.KITKAT);
     }
-    
+
+    private long legacyExactLength() {
+        return (mAlwaysExact ? WINDOW_EXACT : WINDOW_HEURISTIC);
+    }
+
     /**
-     * Schedule an alarm.  <b>Note: for timing operations (ticks, timeouts,
+     * TBW: discussion of fuzzy nature of alarms in KLP+.
+     *
+     * <p>Schedule an alarm.  <b>Note: for timing operations (ticks, timeouts,
      * etc) it is easier and much more efficient to use
      * {@link android.os.Handler}.</b>  If there is already an alarm scheduled
      * for the same IntentSender, it will first be canceled.
@@ -122,7 +143,9 @@
      * IntentSender.getBroadcast()}.
      *
      * @see android.os.Handler
+     * @see #setExact
      * @see #setRepeating
+     * @see #setWindow
      * @see #cancel
      * @see android.content.Context#sendBroadcast
      * @see android.content.Context#registerReceiver
@@ -133,10 +156,7 @@
      * @see #RTC_WAKEUP
      */
     public void set(int type, long triggerAtMillis, PendingIntent operation) {
-        try {
-            mService.set(type, triggerAtMillis, operation);
-        } catch (RemoteException ex) {
-        }
+        setImpl(type, triggerAtMillis, legacyExactLength(), 0, operation, null);
     }
 
     /**
@@ -177,6 +197,8 @@
      *
      * @see android.os.Handler
      * @see #set
+     * @see #setExact
+     * @see #setWindow
      * @see #cancel
      * @see android.content.Context#sendBroadcast
      * @see android.content.Context#registerReceiver
@@ -188,22 +210,113 @@
      */
     public void setRepeating(int type, long triggerAtMillis,
             long intervalMillis, PendingIntent operation) {
+        setImpl(type, triggerAtMillis, legacyExactLength(), intervalMillis, operation, null);
+    }
+
+    /**
+     * Schedule an alarm to be delivered within a given window of time.
+     *
+     * TBW: clean up these docs
+     *
+     * @param type One of ELAPSED_REALTIME, ELAPSED_REALTIME_WAKEUP, RTC or
+     *        RTC_WAKEUP.
+     * @param windowStartMillis The earliest time, in milliseconds, that the alarm should
+     *        be delivered, expressed in the appropriate clock's units (depending on the alarm
+     *        type).
+     * @param windowLengthMillis The length of the requested delivery window,
+     *        in milliseconds.  The alarm will be delivered no later than this many
+     *        milliseconds after the windowStartMillis time.  Note that this parameter
+     *        is a <i>duration,</i> not the timestamp of the end of the window.
+     * @param operation Action to perform when the alarm goes off;
+     *        typically comes from {@link PendingIntent#getBroadcast
+     *        IntentSender.getBroadcast()}.
+     *
+     * @see #set
+     * @see #setExact
+     * @see #setRepeating
+     * @see #cancel
+     * @see android.content.Context#sendBroadcast
+     * @see android.content.Context#registerReceiver
+     * @see android.content.Intent#filterEquals
+     * @see #ELAPSED_REALTIME
+     * @see #ELAPSED_REALTIME_WAKEUP
+     * @see #RTC
+     * @see #RTC_WAKEUP
+     */
+    public void setWindow(int type, long windowStartMillis, long windowLengthMillis,
+            PendingIntent operation) {
+        setImpl(type, windowStartMillis, windowLengthMillis, 0, operation, null);
+    }
+
+    /**
+     * TBW: new 'exact' alarm that must be delivered as nearly as possible
+     * to the precise time specified.
+     */
+    public void setExact(int type, long triggerAtMillis, PendingIntent operation) {
+        setImpl(type, triggerAtMillis, WINDOW_EXACT, 0, operation, null);
+    }
+
+    /** @hide */
+    public void set(int type, long triggerAtMillis, long windowMillis, long intervalMillis,
+            PendingIntent operation, WorkSource workSource) {
+        setImpl(type, triggerAtMillis, windowMillis, intervalMillis, operation, workSource);
+    }
+
+    private void setImpl(int type, long triggerAtMillis, long windowMillis, long intervalMillis,
+            PendingIntent operation, WorkSource workSource) {
+        if (triggerAtMillis < 0) {
+            /* NOTYET
+            if (mAlwaysExact) {
+                // Fatal error for KLP+ apps to use negative trigger times
+                throw new IllegalArgumentException("Invalid alarm trigger time "
+                        + triggerAtMillis);
+            }
+            */
+            triggerAtMillis = 0;
+        }
+
         try {
-            mService.setRepeating(type, triggerAtMillis, intervalMillis, operation);
+            mService.set(type, triggerAtMillis, windowMillis, intervalMillis, operation,
+                    workSource);
         } catch (RemoteException ex) {
         }
     }
 
     /**
-     * Available inexact recurrence intervals recognized by
-     * {@link #setInexactRepeating(int, long, long, PendingIntent)} 
+     * @deprecated setInexactRepeating() is deprecated; as of API 19 all
+     * repeating alarms are inexact.
      */
+    @Deprecated
     public static final long INTERVAL_FIFTEEN_MINUTES = 15 * 60 * 1000;
+
+    /**
+     * @deprecated setInexactRepeating() is deprecated; as of API 19 all
+     * repeating alarms are inexact.
+     */
+    @Deprecated
     public static final long INTERVAL_HALF_HOUR = 2*INTERVAL_FIFTEEN_MINUTES;
+
+    /**
+     * @deprecated setInexactRepeating() is deprecated; as of API 19 all
+     * repeating alarms are inexact.
+     */
+    @Deprecated
     public static final long INTERVAL_HOUR = 2*INTERVAL_HALF_HOUR;
+
+    /**
+     * @deprecated setInexactRepeating() is deprecated; as of API 19 all
+     * repeating alarms are inexact.
+     */
+    @Deprecated
     public static final long INTERVAL_HALF_DAY = 12*INTERVAL_HOUR;
+
+    /**
+     * @deprecated setInexactRepeating() is deprecated; as of API 19 all
+     * repeating alarms are inexact.
+     */
+    @Deprecated
     public static final long INTERVAL_DAY = 2*INTERVAL_HALF_DAY;
-    
+
     /**
      * Schedule a repeating alarm that has inexact trigger time requirements;
      * for example, an alarm that repeats every hour, but not necessarily at
@@ -236,6 +349,8 @@
      * typically comes from {@link PendingIntent#getBroadcast
      * IntentSender.getBroadcast()}.
      *
+     * @deprecated As of API 19, all repeating alarms are inexact.
+     *
      * @see android.os.Handler
      * @see #set
      * @see #cancel
@@ -252,12 +367,10 @@
      * @see #INTERVAL_HALF_DAY
      * @see #INTERVAL_DAY
      */
+    @Deprecated
     public void setInexactRepeating(int type, long triggerAtMillis,
             long intervalMillis, PendingIntent operation) {
-        try {
-            mService.setInexactRepeating(type, triggerAtMillis, intervalMillis, operation);
-        } catch (RemoteException ex) {
-        }
+        setImpl(type, triggerAtMillis, WINDOW_HEURISTIC, intervalMillis, operation, null);
     }
     
     /**
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 4fcb18a..3e4795c 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -16,12 +16,13 @@
 
 package android.app;
 
-import android.Manifest;
+import android.os.Binder;
+import android.os.IBinder;
+import android.util.ArrayMap;
 import com.android.internal.app.IAppOpsService;
 import com.android.internal.app.IAppOpsCallback;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
 
 import android.content.Context;
@@ -33,27 +34,30 @@
 /**
  * API for interacting with "application operation" tracking.  Allows you to:
  *
- * - Note when operations are happening, and find out if they are allowed for the current caller.
- * - Disallow specific apps from doing specific operations.
- * - Collect all of the current information about operations that have been executed or are not
- * being allowed.
- * - Monitor for changes in whether an operation is allowed.
+ * <ul>
+ * <li> Note when operations are happening, and find out if they are allowed for the current
+ * caller.</li>
+ * <li> Disallow specific apps from doing specific operations.</li>
+ * <li> Collect all of the current information about operations that have been executed or are not
+ * being allowed.</li>
+ * <li> Monitor for changes in whether an operation is allowed.</li>
+ * </ul>
  *
- * Each operation is identified by a single integer; these integers are a fixed set of
+ * <p>Each operation is identified by a single integer; these integers are a fixed set of
  * operations, enumerated by the OP_* constants.
  *
- * When checking operations, the result is a "mode" integer indicating the current setting
+ * <p></p>When checking operations, the result is a "mode" integer indicating the current setting
  * for the operation under that caller: MODE_ALLOWED, MODE_IGNORED (don't execute the operation but
  * fake its behavior enough so that the caller doesn't crash), MODE_ERRORED (through a
  * SecurityException back to the caller; the normal operation calls will do this for you).
- *
- * @hide
  */
 public class AppOpsManager {
     final Context mContext;
     final IAppOpsService mService;
-    final HashMap<Callback, IAppOpsCallback> mModeWatchers
-            = new HashMap<Callback, IAppOpsCallback>();
+    final ArrayMap<Callback, IAppOpsCallback> mModeWatchers
+            = new ArrayMap<Callback, IAppOpsCallback>();
+
+    static IBinder sToken;
 
     public static final int MODE_ALLOWED = 0;
     public static final int MODE_IGNORED = 1;
@@ -63,47 +67,105 @@
     //  - increment _NUM_OP
     //  - add rows to sOpToSwitch, sOpNames, sOpPerms
     //  - add descriptive strings to Settings/res/values/arrays.xml
+    //  - add the op to the appropriate template in AppOpsState.OpsTemplate (settings app)
+
+    /** No operation specified. */
     public static final int OP_NONE = -1;
+    /** Access to coarse location information. */
     public static final int OP_COARSE_LOCATION = 0;
+    /** Access to fine location information. */
     public static final int OP_FINE_LOCATION = 1;
+    /** Causing GPS to run. */
     public static final int OP_GPS = 2;
+    /** @hide */
     public static final int OP_VIBRATE = 3;
+    /** @hide */
     public static final int OP_READ_CONTACTS = 4;
+    /** @hide */
     public static final int OP_WRITE_CONTACTS = 5;
+    /** @hide */
     public static final int OP_READ_CALL_LOG = 6;
+    /** @hide */
     public static final int OP_WRITE_CALL_LOG = 7;
+    /** @hide */
     public static final int OP_READ_CALENDAR = 8;
+    /** @hide */
     public static final int OP_WRITE_CALENDAR = 9;
+    /** @hide */
     public static final int OP_WIFI_SCAN = 10;
+    /** @hide */
     public static final int OP_POST_NOTIFICATION = 11;
+    /** @hide */
     public static final int OP_NEIGHBORING_CELLS = 12;
+    /** @hide */
     public static final int OP_CALL_PHONE = 13;
+    /** @hide */
     public static final int OP_READ_SMS = 14;
+    /** @hide */
     public static final int OP_WRITE_SMS = 15;
+    /** @hide */
     public static final int OP_RECEIVE_SMS = 16;
+    /** @hide */
     public static final int OP_RECEIVE_EMERGECY_SMS = 17;
+    /** @hide */
     public static final int OP_RECEIVE_MMS = 18;
+    /** @hide */
     public static final int OP_RECEIVE_WAP_PUSH = 19;
+    /** @hide */
     public static final int OP_SEND_SMS = 20;
+    /** @hide */
     public static final int OP_READ_ICC_SMS = 21;
+    /** @hide */
     public static final int OP_WRITE_ICC_SMS = 22;
+    /** @hide */
     public static final int OP_WRITE_SETTINGS = 23;
+    /** @hide */
     public static final int OP_SYSTEM_ALERT_WINDOW = 24;
+    /** @hide */
     public static final int OP_ACCESS_NOTIFICATIONS = 25;
+    /** @hide */
     public static final int OP_CAMERA = 26;
+    /** @hide */
     public static final int OP_RECORD_AUDIO = 27;
+    /** @hide */
     public static final int OP_PLAY_AUDIO = 28;
+    /** @hide */
     public static final int OP_READ_CLIPBOARD = 29;
+    /** @hide */
     public static final int OP_WRITE_CLIPBOARD = 30;
     /** @hide */
-    public static final int _NUM_OP = 31;
+    public static final int OP_TAKE_MEDIA_BUTTONS = 31;
+    /** @hide */
+    public static final int OP_TAKE_AUDIO_FOCUS = 32;
+    /** @hide */
+    public static final int OP_AUDIO_MASTER_VOLUME = 33;
+    /** @hide */
+    public static final int OP_AUDIO_VOICE_VOLUME = 34;
+    /** @hide */
+    public static final int OP_AUDIO_RING_VOLUME = 35;
+    /** @hide */
+    public static final int OP_AUDIO_MEDIA_VOLUME = 36;
+    /** @hide */
+    public static final int OP_AUDIO_ALARM_VOLUME = 37;
+    /** @hide */
+    public static final int OP_AUDIO_NOTIFICATION_VOLUME = 38;
+    /** @hide */
+    public static final int OP_AUDIO_BLUETOOTH_VOLUME = 39;
+    /** @hide */
+    public static final int OP_WAKE_LOCK = 40;
+    /** Continually monitoring location data. */
+    public static final int OP_MONITOR_LOCATION = 41;
+    /** Continually monitoring location data with a relatively high power request. */
+    public static final int OP_MONITOR_HIGH_POWER_LOCATION = 42;
+    /** @hide */
+    public static final int _NUM_OP = 43;
 
     /**
      * This maps each operation to the operation that serves as the
      * switch to determine whether it is allowed.  Generally this is
      * a 1:1 mapping, but for some things (like location) that have
      * multiple low-level operations being tracked that should be
-     * presented to hte user as one switch then this can be used to
+     * presented to the user as one switch then this can be used to
      * make them all controlled by the same single operation.
      */
     private static int[] sOpToSwitch = new int[] {
@@ -123,11 +185,11 @@
             OP_CALL_PHONE,
             OP_READ_SMS,
             OP_WRITE_SMS,
-            OP_READ_SMS,
-            OP_READ_SMS,
-            OP_READ_SMS,
-            OP_READ_SMS,
-            OP_WRITE_SMS,
+            OP_RECEIVE_SMS,
+            OP_RECEIVE_SMS,
+            OP_RECEIVE_SMS,
+            OP_RECEIVE_SMS,
+            OP_SEND_SMS,
             OP_READ_SMS,
             OP_WRITE_SMS,
             OP_WRITE_SETTINGS,
@@ -138,6 +200,18 @@
             OP_PLAY_AUDIO,
             OP_READ_CLIPBOARD,
             OP_WRITE_CLIPBOARD,
+            OP_TAKE_MEDIA_BUTTONS,
+            OP_TAKE_AUDIO_FOCUS,
+            OP_AUDIO_MASTER_VOLUME,
+            OP_AUDIO_VOICE_VOLUME,
+            OP_AUDIO_RING_VOLUME,
+            OP_AUDIO_MEDIA_VOLUME,
+            OP_AUDIO_ALARM_VOLUME,
+            OP_AUDIO_NOTIFICATION_VOLUME,
+            OP_AUDIO_BLUETOOTH_VOLUME,
+            OP_WAKE_LOCK,
+            OP_COARSE_LOCATION,
+            OP_COARSE_LOCATION,
     };
 
     /**
@@ -176,6 +250,18 @@
             "PLAY_AUDIO",
             "READ_CLIPBOARD",
             "WRITE_CLIPBOARD",
+            "TAKE_MEDIA_BUTTONS",
+            "TAKE_AUDIO_FOCUS",
+            "AUDIO_MASTER_VOLUME",
+            "AUDIO_VOICE_VOLUME",
+            "AUDIO_RING_VOLUME",
+            "AUDIO_MEDIA_VOLUME",
+            "AUDIO_ALARM_VOLUME",
+            "AUDIO_NOTIFICATION_VOLUME",
+            "AUDIO_BLUETOOTH_VOLUME",
+            "WAKE_LOCK",
+            "MONITOR_LOCATION",
+            "MONITOR_HIGH_POWER_LOCATION",
     };
 
     /**
@@ -214,10 +300,23 @@
             null, // no permission for playing audio
             null, // no permission for reading clipboard
             null, // no permission for writing clipboard
+            null, // no permission for taking media buttons
+            null, // no permission for taking audio focus
+            null, // no permission for changing master volume
+            null, // no permission for changing voice volume
+            null, // no permission for changing ring volume
+            null, // no permission for changing media volume
+            null, // no permission for changing alarm volume
+            null, // no permission for changing notification volume
+            null, // no permission for changing bluetooth volume
+            android.Manifest.permission.WAKE_LOCK,
+            null, // no permission for generic location monitoring
+            null, // no permission for high power location monitoring
     };
 
     /**
      * Retrieve the op switch that controls the given operation.
+     * @hide
      */
     public static int opToSwitch(int op) {
         return sOpToSwitch[op];
@@ -233,6 +332,7 @@
 
     /**
      * Retrieve the permission associated with an operation, or null if there is not one.
+     * @hide
      */
     public static String opToPermission(int op) {
         return sOpPerms[op];
@@ -240,6 +340,7 @@
 
     /**
      * Class holding all of the operation information associated with an app.
+     * @hide
      */
     public static class PackageOps implements Parcelable {
         private final String mPackageName;
@@ -302,6 +403,7 @@
 
     /**
      * Class holding the information about one unique operation of an application.
+     * @hide
      */
     public static class OpEntry implements Parcelable {
         private final int mOp;
@@ -382,7 +484,7 @@
         public void opChanged(int op, String packageName);
     }
 
-    public AppOpsManager(Context context, IAppOpsService service) {
+    AppOpsManager(Context context, IAppOpsService service) {
         mContext = context;
         mService = service;
     }
@@ -391,6 +493,7 @@
      * Retrieve current operation state for all applications.
      *
      * @param ops The set of operations you are interested in, or null if you want all of them.
+     * @hide
      */
     public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) {
         try {
@@ -406,6 +509,7 @@
      * @param uid The uid of the application of interest.
      * @param packageName The name of the application of interest.
      * @param ops The set of operations you are interested in, or null if you want all of them.
+     * @hide
      */
     public List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, int[] ops) {
         try {
@@ -415,6 +519,7 @@
         return null;
     }
 
+    /** @hide */
     public void setMode(int code, int uid, String packageName, int mode) {
         try {
             mService.setMode(code, uid, packageName, mode);
@@ -430,6 +535,12 @@
         }
     }
 
+    /**
+     * Monitor for changes to the operating mode for the given op in the given app package.
+     * @param op The operation to monitor, one of OP_*.
+     * @param packageName The name of the application to monitor.
+     * @param callback Where to report changes.
+     */
     public void startWatchingMode(int op, String packageName, final Callback callback) {
         synchronized (mModeWatchers) {
             IAppOpsCallback cb = mModeWatchers.get(callback);
@@ -448,6 +559,10 @@
         }
     }
 
+    /**
+     * Stop monitoring that was previously started with {@link #startWatchingMode}.  All
+     * monitoring associated with this callback will be removed.
+     */
     public void stopWatchingMode(Callback callback) {
         synchronized (mModeWatchers) {
             IAppOpsCallback cb = mModeWatchers.get(callback);
@@ -460,11 +575,31 @@
         }
     }
 
+    private String buildSecurityExceptionMsg(int op, int uid, String packageName) {
+        return packageName + " from uid " + uid + " not allowed to perform " + sOpNames[op];
+    }
+
+    /**
+     * Do a quick check for whether an application might be able to perform an operation.
+     * This is <em>not</em> a security check; you must use {@link #noteOp(int, int, String)}
+     * or {@link #startOp(int, int, String)} for your actual security checks, which also
+     * ensure that the given uid and package name are consistent.  This function can just be
+     * used for a quick check to see if an operation has been disabled for the application,
+     * as an early reject of some work.  This does not modify the time stamp or other data
+     * about the operation.
+     * @param op The operation to check.  One of the OP_* constants.
+     * @param uid The user id of the application attempting to perform the operation.
+     * @param packageName The name of the application attempting to perform the operation.
+     * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
+     * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
+     * causing the app to crash).
+     * @throws SecurityException If the app has been configured to crash on this op.
+     */
     public int checkOp(int op, int uid, String packageName) {
         try {
             int mode = mService.checkOperation(op, uid, packageName);
             if (mode == MODE_ERRORED) {
-                throw new SecurityException("Operation not allowed");
+                throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
             }
             return mode;
         } catch (RemoteException e) {
@@ -472,6 +607,10 @@
         return MODE_IGNORED;
     }
 
+    /**
+     * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
+     * returns {@link #MODE_ERRORED}.
+     */
     public int checkOpNoThrow(int op, int uid, String packageName) {
         try {
             return mService.checkOperation(op, uid, packageName);
@@ -480,11 +619,42 @@
         return MODE_IGNORED;
     }
 
+    /**
+     * Do a quick check to validate if a package name belongs to a UID.
+     *
+     * @throws SecurityException if the package name doesn't belong to the given
+     *             UID, or if ownership cannot be verified.
+     */
+    public void checkPackage(int uid, String packageName) {
+        try {
+            if (mService.checkPackage(uid, packageName) != MODE_ALLOWED) {
+                throw new SecurityException(
+                        "Package " + packageName + " does not belong to " + uid);
+            }
+        } catch (RemoteException e) {
+            throw new SecurityException("Unable to verify package ownership", e);
+        }
+    }
+
+    /**
+     * Make note of an application performing an operation.  Note that you must pass
+     * in both the uid and name of the application to be checked; this function will verify
+     * that these two match, and if not, return {@link #MODE_IGNORED}.  If this call
+     * succeeds, the last execution time of the operation for this app will be updated to
+     * the current time.
+     * @param op The operation to note.  One of the OP_* constants.
+     * @param uid The user id of the application attempting to perform the operation.
+     * @param packageName The name of the application attempting to perform the operation.
+     * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
+     * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
+     * causing the app to crash).
+     * @throws SecurityException If the app has been configured to crash on this op.
+     */
     public int noteOp(int op, int uid, String packageName) {
         try {
             int mode = mService.noteOperation(op, uid, packageName);
             if (mode == MODE_ERRORED) {
-                throw new SecurityException("Operation not allowed");
+                throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
             }
             return mode;
         } catch (RemoteException e) {
@@ -492,6 +662,10 @@
         return MODE_IGNORED;
     }
 
+    /**
+     * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
+     * returns {@link #MODE_ERRORED}.
+     */
     public int noteOpNoThrow(int op, int uid, String packageName) {
         try {
             return mService.noteOperation(op, uid, packageName);
@@ -500,15 +674,47 @@
         return MODE_IGNORED;
     }
 
+    /** @hide */
     public int noteOp(int op) {
-        return noteOp(op, Process.myUid(), mContext.getBasePackageName());
+        return noteOp(op, Process.myUid(), mContext.getOpPackageName());
     }
 
+    /** @hide */
+    public static IBinder getToken(IAppOpsService service) {
+        synchronized (AppOpsManager.class) {
+            if (sToken != null) {
+                return sToken;
+            }
+            try {
+                sToken = service.getToken(new Binder());
+            } catch (RemoteException e) {
+                // System is dead, whatevs.
+            }
+            return sToken;
+        }
+    }
+
+    /**
+     * Report that an application has started executing a long-running operation.  Note that you
+     * must pass in both the uid and name of the application to be checked; this function will
+     * verify that these two match, and if not, return {@link #MODE_IGNORED}.  If this call
+     * succeeds, the last execution time of the operation for this app will be updated to
+     * the current time and the operation will be marked as "running".  In this case you must
+     * later call {@link #finishOp(int, int, String)} to report when the application is no
+     * longer performing the operation.
+     * @param op The operation to start.  One of the OP_* constants.
+     * @param uid The user id of the application attempting to perform the operation.
+     * @param packageName The name of the application attempting to perform the operation.
+     * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
+     * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
+     * causing the app to crash).
+     * @throws SecurityException If the app has been configured to crash on this op.
+     */
     public int startOp(int op, int uid, String packageName) {
         try {
-            int mode = mService.startOperation(op, uid, packageName);
+            int mode = mService.startOperation(getToken(mService), op, uid, packageName);
             if (mode == MODE_ERRORED) {
-                throw new SecurityException("Operation not allowed");
+                throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
             }
             return mode;
         } catch (RemoteException e) {
@@ -516,26 +722,37 @@
         return MODE_IGNORED;
     }
 
+    /**
+     * Like {@link #startOp} but instead of throwing a {@link SecurityException} it
+     * returns {@link #MODE_ERRORED}.
+     */
     public int startOpNoThrow(int op, int uid, String packageName) {
         try {
-            return mService.startOperation(op, uid, packageName);
+            return mService.startOperation(getToken(mService), op, uid, packageName);
         } catch (RemoteException e) {
         }
         return MODE_IGNORED;
     }
 
+    /** @hide */
     public int startOp(int op) {
-        return startOp(op, Process.myUid(), mContext.getBasePackageName());
+        return startOp(op, Process.myUid(), mContext.getOpPackageName());
     }
 
+    /**
+     * Report that an application is no longer performing an operation that had previously
+     * been started with {@link #startOp(int, int, String)}.  There is no validation of input
+     * or result; the parameters supplied here must be the exact same ones previously passed
+     * in when starting the operation.
+     */
     public void finishOp(int op, int uid, String packageName) {
         try {
-            mService.finishOperation(op, uid, packageName);
+            mService.finishOperation(getToken(mService), op, uid, packageName);
         } catch (RemoteException e) {
         }
     }
 
     public void finishOp(int op) {
-        finishOp(op, Process.myUid(), mContext.getBasePackageName());
+        finishOp(op, Process.myUid(), mContext.getOpPackageName());
     }
 }
diff --git a/core/java/android/app/ApplicationErrorReport.java b/core/java/android/app/ApplicationErrorReport.java
index 954476d..c117486 100644
--- a/core/java/android/app/ApplicationErrorReport.java
+++ b/core/java/android/app/ApplicationErrorReport.java
@@ -28,6 +28,7 @@
 import android.os.SystemProperties;
 import android.provider.Settings;
 import android.util.Printer;
+import com.android.internal.util.FastPrintWriter;
 
 import java.io.PrintWriter;
 import java.io.StringWriter;
@@ -327,7 +328,9 @@
          */
         public CrashInfo(Throwable tr) {
             StringWriter sw = new StringWriter();
-            tr.printStackTrace(new PrintWriter(sw));
+            PrintWriter pw = new FastPrintWriter(sw, false, 256);
+            tr.printStackTrace(pw);
+            pw.flush();
             stackTrace = sw.toString();
             exceptionMessage = tr.getMessage();
 
diff --git a/core/java/android/app/ApplicationLoaders.java b/core/java/android/app/ApplicationLoaders.java
index a26b88c..413c369 100644
--- a/core/java/android/app/ApplicationLoaders.java
+++ b/core/java/android/app/ApplicationLoaders.java
@@ -17,11 +17,9 @@
 package android.app;
 
 import android.os.Trace;
+import android.util.ArrayMap;
 import dalvik.system.PathClassLoader;
 
-import java.util.HashMap;
-import java.util.Map;
-
 class ApplicationLoaders
 {
     public static ApplicationLoaders getDefault()
@@ -71,7 +69,7 @@
         }
     }
 
-    private final Map<String, ClassLoader> mLoaders = new HashMap<String, ClassLoader>();
+    private final ArrayMap<String, ClassLoader> mLoaders = new ArrayMap<String, ClassLoader>();
 
     private static final ApplicationLoaders gApplicationLoaders
         = new ApplicationLoaders();
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 271494f..55c66726 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -51,6 +51,7 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.util.ArrayMap;
 import android.util.Log;
 import android.view.Display;
 
@@ -859,26 +860,20 @@
             boolean needCleanup = false;
             for (String ssp : pkgList) {
                 synchronized (sSync) {
-                    if (sIconCache.size() > 0) {
-                        Iterator<ResourceName> it = sIconCache.keySet().iterator();
-                        while (it.hasNext()) {
-                            ResourceName nm = it.next();
-                            if (nm.packageName.equals(ssp)) {
-                                //Log.i(TAG, "Removing cached drawable for " + nm);
-                                it.remove();
-                                needCleanup = true;
-                            }
+                    for (int i=sIconCache.size()-1; i>=0; i--) {
+                        ResourceName nm = sIconCache.keyAt(i);
+                        if (nm.packageName.equals(ssp)) {
+                            //Log.i(TAG, "Removing cached drawable for " + nm);
+                            sIconCache.removeAt(i);
+                            needCleanup = true;
                         }
                     }
-                    if (sStringCache.size() > 0) {
-                        Iterator<ResourceName> it = sStringCache.keySet().iterator();
-                        while (it.hasNext()) {
-                            ResourceName nm = it.next();
-                            if (nm.packageName.equals(ssp)) {
-                                //Log.i(TAG, "Removing cached string for " + nm);
-                                it.remove();
-                                needCleanup = true;
-                            }
+                    for (int i=sStringCache.size()-1; i>=0; i--) {
+                        ResourceName nm = sStringCache.keyAt(i);
+                        if (nm.packageName.equals(ssp)) {
+                            //Log.i(TAG, "Removing cached string for " + nm);
+                            sStringCache.removeAt(i);
+                            needCleanup = true;
                         }
                     }
                 }
@@ -1256,6 +1251,16 @@
     }
 
     @Override
+    public ComponentName getHomeActivities(List<ResolveInfo> outActivities) {
+        try {
+            return mPM.getHomeActivities(outActivities);
+        } catch (RemoteException e) {
+            // Should never happen!
+        }
+        return null;
+    }
+
+    @Override
     public void setComponentEnabledSetting(ComponentName componentName,
                                            int newState, int flags) {
         try {
@@ -1280,7 +1285,7 @@
                                              int newState, int flags) {
         try {
             mPM.setApplicationEnabledSetting(packageName, newState, flags,
-                    mContext.getUserId(), mContext.getBasePackageName());
+                    mContext.getUserId(), mContext.getOpPackageName());
         } catch (RemoteException e) {
             // Should never happen!
         }
@@ -1296,6 +1301,28 @@
         return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
     }
 
+    @Override
+    public boolean setApplicationBlockedSettingAsUser(String packageName, boolean blocked,
+            UserHandle user) {
+        try {
+            return mPM.setApplicationBlockedSettingAsUser(packageName, blocked,
+                    user.getIdentifier());
+        } catch (RemoteException re) {
+            // Should never happen!
+        }
+        return false;
+    }
+
+    @Override
+    public boolean getApplicationBlockedSettingAsUser(String packageName, UserHandle user) {
+        try {
+            return mPM.getApplicationBlockedSettingAsUser(packageName, user.getIdentifier());
+        } catch (RemoteException re) {
+            // Should never happen!
+        }
+        return false;
+    }
+
     /**
      * @hide
      */
@@ -1313,8 +1340,8 @@
     private final IPackageManager mPM;
 
     private static final Object sSync = new Object();
-    private static HashMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache
-            = new HashMap<ResourceName, WeakReference<Drawable.ConstantState>>();
-    private static HashMap<ResourceName, WeakReference<CharSequence>> sStringCache
-            = new HashMap<ResourceName, WeakReference<CharSequence>>();
+    private static ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache
+            = new ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>>();
+    private static ArrayMap<ResourceName, WeakReference<CharSequence>> sStringCache
+            = new ArrayMap<ResourceName, WeakReference<CharSequence>>();
 }
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index b1c58f2..a4e80e5 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -111,8 +111,9 @@
         {
             data.enforceInterface(IApplicationThread.descriptor);
             IBinder b = data.readStrongBinder();
+            int procState = data.readInt();
             boolean isForward = data.readInt() != 0;
-            scheduleResumeActivity(b, isForward);
+            scheduleResumeActivity(b, procState, isForward);
             return true;
         }
         
@@ -134,6 +135,7 @@
             ActivityInfo info = ActivityInfo.CREATOR.createFromParcel(data);
             Configuration curConfig = Configuration.CREATOR.createFromParcel(data);
             CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
+            int procState = data.readInt();
             Bundle state = data.readBundle();
             List<ResultInfo> ri = data.createTypedArrayList(ResultInfo.CREATOR);
             List<Intent> pi = data.createTypedArrayList(Intent.CREATOR);
@@ -143,8 +145,8 @@
             ParcelFileDescriptor profileFd = data.readInt() != 0
                     ? data.readFileDescriptor() : null;
             boolean autoStopProfiler = data.readInt() != 0;
-            scheduleLaunchActivity(intent, b, ident, info, curConfig, compatInfo, state, ri, pi,
-                    notResumed, isForward, profileName, profileFd, autoStopProfiler);
+            scheduleLaunchActivity(intent, b, ident, info, curConfig, compatInfo, procState, state,
+                    ri, pi, notResumed, isForward, profileName, profileFd, autoStopProfiler);
             return true;
         }
         
@@ -194,8 +196,9 @@
             Bundle resultExtras = data.readBundle();
             boolean sync = data.readInt() != 0;
             int sendingUser = data.readInt();
+            int processState = data.readInt();
             scheduleReceiver(intent, info, compatInfo, resultCode, resultData,
-                    resultExtras, sync, sendingUser);
+                    resultExtras, sync, sendingUser, processState);
             return true;
         }
 
@@ -204,7 +207,8 @@
             IBinder token = data.readStrongBinder();
             ServiceInfo info = ServiceInfo.CREATOR.createFromParcel(data);
             CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
-            scheduleCreateService(token, info, compatInfo);
+            int processState = data.readInt();
+            scheduleCreateService(token, info, compatInfo, processState);
             return true;
         }
 
@@ -213,7 +217,8 @@
             IBinder token = data.readStrongBinder();
             Intent intent = Intent.CREATOR.createFromParcel(data);
             boolean rebind = data.readInt() != 0;
-            scheduleBindService(token, intent, rebind);
+            int processState = data.readInt();
+            scheduleBindService(token, intent, rebind, processState);
             return true;
         }
 
@@ -333,7 +338,8 @@
             final String proxy = data.readString();
             final String port = data.readString();
             final String exclList = data.readString();
-            setHttpProxy(proxy, port, exclList);
+            final String pacFileUrl = data.readString();
+            setHttpProxy(proxy, port, exclList, pacFileUrl);
             return true;
         }
 
@@ -384,8 +390,9 @@
             boolean ordered = data.readInt() != 0;
             boolean sticky = data.readInt() != 0;
             int sendingUser = data.readInt();
+            int processState = data.readInt();
             scheduleRegisteredReceiver(receiver, intent,
-                    resultCode, dataStr, extras, ordered, sticky, sendingUser);
+                    resultCode, dataStr, extras, ordered, sticky, sendingUser, processState);
             return true;
         }
 
@@ -524,12 +531,13 @@
             data.enforceInterface(IApplicationThread.descriptor);
             ParcelFileDescriptor fd = data.readFileDescriptor();
             boolean checkin = data.readInt() != 0;
-            boolean all = data.readInt() != 0;
+            boolean dumpInfo = data.readInt() != 0;
+            boolean dumpDalvik = data.readInt() != 0;
             String[] args = data.readStringArray();
             Debug.MemoryInfo mi = null;
             if (fd != null) {
                 try {
-                    mi = dumpMemInfo(fd.getFileDescriptor(), checkin, all, args);
+                    mi = dumpMemInfo(fd.getFileDescriptor(), checkin, dumpInfo, dumpDalvik, args);
                 } finally {
                     try {
                         fd.close();
@@ -592,13 +600,32 @@
             return true;
         }
 
-        case REQUEST_ACTIVITY_EXTRAS_TRANSACTION:
+        case REQUEST_ASSIST_CONTEXT_EXTRAS_TRANSACTION:
         {
             data.enforceInterface(IApplicationThread.descriptor);
             IBinder activityToken = data.readStrongBinder();
             IBinder requestToken = data.readStrongBinder();
             int requestType = data.readInt();
-            requestActivityExtras(activityToken, requestToken, requestType);
+            requestAssistContextExtras(activityToken, requestToken, requestType);
+            reply.writeNoException();
+            return true;
+        }
+
+        case SCHEDULE_TRANSLUCENT_CONVERSION_COMPLETE_TRANSACTION:
+        {
+            data.enforceInterface(IApplicationThread.descriptor);
+            IBinder token = data.readStrongBinder();
+            boolean timeout = data.readInt() == 1;
+            scheduleTranslucentConversionComplete(token, timeout);
+            reply.writeNoException();
+            return true;
+        }
+
+        case SET_PROCESS_STATE_TRANSACTION:
+        {
+            data.enforceInterface(IApplicationThread.descriptor);
+            int state = data.readInt();
+            setProcessState(state);
             reply.writeNoException();
             return true;
         }
@@ -671,11 +698,12 @@
         data.recycle();
     }
 
-    public final void scheduleResumeActivity(IBinder token, boolean isForward)
+    public final void scheduleResumeActivity(IBinder token, int procState, boolean isForward)
             throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeStrongBinder(token);
+        data.writeInt(procState);
         data.writeInt(isForward ? 1 : 0);
         mRemote.transact(SCHEDULE_RESUME_ACTIVITY_TRANSACTION, data, null,
                 IBinder.FLAG_ONEWAY);
@@ -695,7 +723,7 @@
 
     public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
             ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
-            Bundle state, List<ResultInfo> pendingResults,
+            int procState, Bundle state, List<ResultInfo> pendingResults,
     		List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
     		String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler)
     		throws RemoteException {
@@ -707,6 +735,7 @@
         info.writeToParcel(data, 0);
         curConfig.writeToParcel(data, 0);
         compatInfo.writeToParcel(data, 0);
+        data.writeInt(procState);
         data.writeBundle(state);
         data.writeTypedList(pendingResults);
         data.writeTypedList(pendingNewIntents);
@@ -772,7 +801,7 @@
     
     public final void scheduleReceiver(Intent intent, ActivityInfo info,
             CompatibilityInfo compatInfo, int resultCode, String resultData,
-            Bundle map, boolean sync, int sendingUser) throws RemoteException {
+            Bundle map, boolean sync, int sendingUser, int processState) throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         intent.writeToParcel(data, 0);
@@ -783,6 +812,7 @@
         data.writeBundle(map);
         data.writeInt(sync ? 1 : 0);
         data.writeInt(sendingUser);
+        data.writeInt(processState);
         mRemote.transact(SCHEDULE_RECEIVER_TRANSACTION, data, null,
                 IBinder.FLAG_ONEWAY);
         data.recycle();
@@ -812,24 +842,26 @@
     }
     
     public final void scheduleCreateService(IBinder token, ServiceInfo info,
-            CompatibilityInfo compatInfo) throws RemoteException {
+            CompatibilityInfo compatInfo, int processState) throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeStrongBinder(token);
         info.writeToParcel(data, 0);
         compatInfo.writeToParcel(data, 0);
+        data.writeInt(processState);
         mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,
                 IBinder.FLAG_ONEWAY);
         data.recycle();
     }
 
-    public final void scheduleBindService(IBinder token, Intent intent, boolean rebind)
-            throws RemoteException {
+    public final void scheduleBindService(IBinder token, Intent intent, boolean rebind,
+            int processState) throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeStrongBinder(token);
         intent.writeToParcel(data, 0);
         data.writeInt(rebind ? 1 : 0);
+        data.writeInt(processState);
         mRemote.transact(SCHEDULE_BIND_SERVICE_TRANSACTION, data, null,
                 IBinder.FLAG_ONEWAY);
         data.recycle();
@@ -970,12 +1002,14 @@
         data.recycle();
     }
 
-    public void setHttpProxy(String proxy, String port, String exclList) throws RemoteException {
+    public void setHttpProxy(String proxy, String port, String exclList,
+            String pacFileUrl) throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeString(proxy);
         data.writeString(port);
         data.writeString(exclList);
+        data.writeString(pacFileUrl);
         mRemote.transact(SET_HTTP_PROXY_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
         data.recycle();
     }
@@ -1012,7 +1046,7 @@
 
     public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
             int resultCode, String dataStr, Bundle extras, boolean ordered,
-            boolean sticky, int sendingUser) throws RemoteException {
+            boolean sticky, int sendingUser, int processState) throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeStrongBinder(receiver.asBinder());
@@ -1023,6 +1057,7 @@
         data.writeInt(ordered ? 1 : 0);
         data.writeInt(sticky ? 1 : 0);
         data.writeInt(sendingUser);
+        data.writeInt(processState);
         mRemote.transact(SCHEDULE_REGISTERED_RECEIVER_TRANSACTION, data, null,
                 IBinder.FLAG_ONEWAY);
         data.recycle();
@@ -1159,14 +1194,15 @@
                 IBinder.FLAG_ONEWAY);
     }
 
-    public Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, boolean checkin, boolean all,
-            String[] args) throws RemoteException {
+    public Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, boolean checkin, boolean dumpInfo,
+            boolean dumpDalvik, String[] args) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeFileDescriptor(fd);
         data.writeInt(checkin ? 1 : 0);
-        data.writeInt(all ? 1 : 0);
+        data.writeInt(dumpInfo ? 1 : 0);
+        data.writeInt(dumpDalvik ? 1 : 0);
         data.writeStringArray(args);
         mRemote.transact(DUMP_MEM_INFO_TRANSACTION, data, reply, 0);
         reply.readException();
@@ -1195,6 +1231,7 @@
         data.recycle();
     }
 
+    @Override
     public void unstableProviderDied(IBinder provider) throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
@@ -1203,14 +1240,36 @@
         data.recycle();
     }
 
-    public void requestActivityExtras(IBinder activityToken, IBinder requestToken, int requestType)
-            throws RemoteException {
+    @Override
+    public void requestAssistContextExtras(IBinder activityToken, IBinder requestToken,
+            int requestType) throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeStrongBinder(activityToken);
         data.writeStrongBinder(requestToken);
         data.writeInt(requestType);
-        mRemote.transact(REQUEST_ACTIVITY_EXTRAS_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
+        mRemote.transact(REQUEST_ASSIST_CONTEXT_EXTRAS_TRANSACTION, data, null,
+                IBinder.FLAG_ONEWAY);
+        data.recycle();
+    }
+
+    @Override
+    public void scheduleTranslucentConversionComplete(IBinder token, boolean timeout)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        data.writeInterfaceToken(IApplicationThread.descriptor);
+        data.writeStrongBinder(token);
+        data.writeInt(timeout ? 1 : 0);
+        mRemote.transact(SCHEDULE_TRANSLUCENT_CONVERSION_COMPLETE_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
+        data.recycle();
+    }
+
+    @Override
+    public void setProcessState(int state) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        data.writeInterfaceToken(IApplicationThread.descriptor);
+        data.writeInt(state);
+        mRemote.transact(SET_PROCESS_STATE_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
         data.recycle();
     }
 }
diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java
index 1b1d341..89ee145 100644
--- a/core/java/android/app/BackStackRecord.java
+++ b/core/java/android/app/BackStackRecord.java
@@ -21,6 +21,7 @@
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.LogWriter;
+import com.android.internal.util.FastPrintWriter;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -583,8 +584,9 @@
         if (FragmentManagerImpl.DEBUG) {
             Log.v(TAG, "Commit: " + this);
             LogWriter logw = new LogWriter(Log.VERBOSE, TAG);
-            PrintWriter pw = new PrintWriter(logw);
+            PrintWriter pw = new FastPrintWriter(logw, false, 1024);
             dump("  ", null, pw, null);
+            pw.flush();
         }
         mCommitted = true;
         if (mAddToBackStack) {
@@ -691,8 +693,9 @@
         if (FragmentManagerImpl.DEBUG) {
             Log.v(TAG, "popFromBackStack: " + this);
             LogWriter logw = new LogWriter(Log.VERBOSE, TAG);
-            PrintWriter pw = new PrintWriter(logw);
+            PrintWriter pw = new FastPrintWriter(logw, false, 1024);
             dump("  ", null, pw, null);
+            pw.flush();
         }
 
         bumpBackStackNesting(-1);
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 3fc82fa..8e9f3bb 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -16,6 +16,7 @@
 
 package android.app;
 
+import android.os.Build;
 import com.android.internal.policy.PolicyManager;
 import com.android.internal.util.Preconditions;
 
@@ -46,9 +47,11 @@
 import android.database.sqlite.SQLiteDatabase.CursorFactory;
 import android.graphics.Bitmap;
 import android.graphics.drawable.Drawable;
+import android.hardware.ConsumerIrManager;
 import android.hardware.ISerialManager;
 import android.hardware.SerialManager;
 import android.hardware.SystemSensorManager;
+import android.hardware.camera2.CameraManager;
 import android.hardware.display.DisplayManager;
 import android.hardware.input.InputManager;
 import android.hardware.usb.IUsbManager;
@@ -90,22 +93,27 @@
 import android.os.SystemVibrator;
 import android.os.UserManager;
 import android.os.storage.StorageManager;
+import android.print.IPrintManager;
+import android.print.PrintManager;
 import android.telephony.TelephonyManager;
 import android.content.ClipboardManager;
 import android.util.AndroidRuntimeException;
+import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Slog;
-import android.view.CompatibilityInfoHolder;
+import android.view.DisplayAdjustments;
 import android.view.ContextThemeWrapper;
 import android.view.Display;
 import android.view.WindowManagerImpl;
 import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.CaptioningManager;
 import android.view.inputmethod.InputMethodManager;
 import android.view.textservice.TextServicesManager;
 import android.accounts.AccountManager;
 import android.accounts.IAccountManager;
 import android.app.admin.DevicePolicyManager;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.app.IAppOpsService;
 import com.android.internal.os.IDropBoxManagerService;
 
@@ -169,11 +177,14 @@
     private final static String TAG = "ContextImpl";
     private final static boolean DEBUG = false;
 
-    private static final HashMap<String, SharedPreferencesImpl> sSharedPrefs =
-            new HashMap<String, SharedPreferencesImpl>();
+    /**
+     * Map from package name, to preference name, to cached preferences.
+     */
+    private static ArrayMap<String, ArrayMap<String, SharedPreferencesImpl>> sSharedPrefs;
 
     /*package*/ LoadedApk mPackageInfo;
     private String mBasePackageName;
+    private String mOpPackageName;
     private Resources mResources;
     /*package*/ ActivityThread mMainThread;
     private Context mOuterContext;
@@ -186,19 +197,30 @@
     private Context mReceiverRestrictedContext = null;
     private boolean mRestricted;
     private UserHandle mUser;
+    private ResourcesManager mResourcesManager;
 
     private final Object mSync = new Object();
 
+    @GuardedBy("mSync")
     private File mDatabasesDir;
+    @GuardedBy("mSync")
     private File mPreferencesDir;
+    @GuardedBy("mSync")
     private File mFilesDir;
+    @GuardedBy("mSync")
     private File mCacheDir;
-    private File mObbDir;
-    private File mExternalFilesDir;
-    private File mExternalCacheDir;
+
+    @GuardedBy("mSync")
+    private File[] mExternalObbDirs;
+    @GuardedBy("mSync")
+    private File[] mExternalFilesDirs;
+    @GuardedBy("mSync")
+    private File[] mExternalCacheDirs;
 
     private static final String[] EMPTY_FILE_LIST = {};
 
+    final private DisplayAdjustments mDisplayAdjustments = new DisplayAdjustments();
+
     /**
      * Override this class when the system service constructor needs a
      * ContextImpl.  Else, use StaticServiceFetcher below.
@@ -288,6 +310,11 @@
                     return AccessibilityManager.getInstance(ctx);
                 }});
 
+        registerService(CAPTIONING_SERVICE, new ServiceFetcher() {
+                public Object getService(ContextImpl ctx) {
+                    return new CaptioningManager(ctx);
+                }});
+
         registerService(ACCOUNT_SERVICE, new ServiceFetcher() {
                 public Object createService(ContextImpl ctx) {
                     IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
@@ -300,11 +327,11 @@
                     return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
                 }});
 
-        registerService(ALARM_SERVICE, new StaticServiceFetcher() {
-                public Object createStaticService() {
+        registerService(ALARM_SERVICE, new ServiceFetcher() {
+                public Object createService(ContextImpl ctx) {
                     IBinder b = ServiceManager.getService(ALARM_SERVICE);
                     IAlarmManager service = IAlarmManager.Stub.asInterface(b);
-                    return new AlarmManager(service);
+                    return new AlarmManager(service, ctx);
                 }});
 
         registerService(AUDIO_SERVICE, new ServiceFetcher() {
@@ -513,12 +540,16 @@
                 }});
 
         registerService(WINDOW_SERVICE, new ServiceFetcher() {
+                Display mDefaultDisplay;
                 public Object getService(ContextImpl ctx) {
                     Display display = ctx.mDisplay;
                     if (display == null) {
-                        DisplayManager dm = (DisplayManager)ctx.getOuterContext().getSystemService(
-                                Context.DISPLAY_SERVICE);
-                        display = dm.getDisplay(Display.DEFAULT_DISPLAY);
+                        if (mDefaultDisplay == null) {
+                            DisplayManager dm = (DisplayManager)ctx.getOuterContext().
+                                    getSystemService(Context.DISPLAY_SERVICE);
+                            mDefaultDisplay = dm.getDisplay(Display.DEFAULT_DISPLAY);
+                        }
+                        display = mDefaultDisplay;
                     }
                     return new WindowManagerImpl(display);
                 }});
@@ -536,6 +567,25 @@
                 IAppOpsService service = IAppOpsService.Stub.asInterface(b);
                 return new AppOpsManager(ctx, service);
             }});
+
+        registerService(CAMERA_SERVICE, new ServiceFetcher() {
+            public Object createService(ContextImpl ctx) {
+                return new CameraManager(ctx);
+            }
+        });
+
+        registerService(PRINT_SERVICE, new ServiceFetcher() {
+            public Object createService(ContextImpl ctx) {
+                IBinder iBinder = ServiceManager.getService(Context.PRINT_SERVICE);
+                IPrintManager service = IPrintManager.Stub.asInterface(iBinder);
+                return new PrintManager(ctx.getOuterContext(), service, UserHandle.myUserId(),
+                        UserHandle.getAppId(Process.myUid()));
+            }});
+
+        registerService(CONSUMER_IR_SERVICE, new ServiceFetcher() {
+            public Object createService(ContextImpl ctx) {
+                return new ConsumerIrManager(ctx);
+            }});
     }
 
     static ContextImpl getImpl(Context context) {
@@ -636,6 +686,12 @@
         return mBasePackageName != null ? mBasePackageName : getPackageName();
     }
 
+    /** @hide */
+    @Override
+    public String getOpPackageName() {
+        return mOpPackageName != null ? mOpPackageName : getBasePackageName();
+    }
+
     @Override
     public ApplicationInfo getApplicationInfo() {
         if (mPackageInfo != null) {
@@ -667,12 +723,33 @@
     @Override
     public SharedPreferences getSharedPreferences(String name, int mode) {
         SharedPreferencesImpl sp;
-        synchronized (sSharedPrefs) {
-            sp = sSharedPrefs.get(name);
+        synchronized (ContextImpl.class) {
+            if (sSharedPrefs == null) {
+                sSharedPrefs = new ArrayMap<String, ArrayMap<String, SharedPreferencesImpl>>();
+            }
+
+            final String packageName = getPackageName();
+            ArrayMap<String, SharedPreferencesImpl> packagePrefs = sSharedPrefs.get(packageName);
+            if (packagePrefs == null) {
+                packagePrefs = new ArrayMap<String, SharedPreferencesImpl>();
+                sSharedPrefs.put(packageName, packagePrefs);
+            }
+
+            // At least one application in the world actually passes in a null
+            // name.  This happened to work because when we generated the file name
+            // we would stringify it to "null.xml".  Nice.
+            if (mPackageInfo.getApplicationInfo().targetSdkVersion <
+                    Build.VERSION_CODES.KITKAT) {
+                if (name == null) {
+                    name = "null";
+                }
+            }
+
+            sp = packagePrefs.get(name);
             if (sp == null) {
                 File prefsFile = getSharedPrefsFile(name);
                 sp = new SharedPreferencesImpl(prefsFile, mode);
-                sSharedPrefs.put(name, sp);
+                packagePrefs.put(name, sp);
                 return sp;
             }
         }
@@ -753,44 +830,41 @@
 
     @Override
     public File getExternalFilesDir(String type) {
+        // Operates on primary external storage
+        return getExternalFilesDirs(type)[0];
+    }
+
+    @Override
+    public File[] getExternalFilesDirs(String type) {
         synchronized (mSync) {
-            if (mExternalFilesDir == null) {
-                mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory(
-                        getPackageName());
+            if (mExternalFilesDirs == null) {
+                mExternalFilesDirs = Environment.buildExternalStorageAppFilesDirs(getPackageName());
             }
-            if (!mExternalFilesDir.exists()) {
-                try {
-                    (new File(Environment.getExternalStorageAndroidDataDir(),
-                            ".nomedia")).createNewFile();
-                } catch (IOException e) {
-                }
-                if (!mExternalFilesDir.mkdirs()) {
-                    Log.w(TAG, "Unable to create external files directory");
-                    return null;
-                }
+
+            // Splice in requested type, if any
+            File[] dirs = mExternalFilesDirs;
+            if (type != null) {
+                dirs = Environment.buildPaths(dirs, type);
             }
-            if (type == null) {
-                return mExternalFilesDir;
-            }
-            File dir = new File(mExternalFilesDir, type);
-            if (!dir.exists()) {
-                if (!dir.mkdirs()) {
-                    Log.w(TAG, "Unable to create external media directory " + dir);
-                    return null;
-                }
-            }
-            return dir;
+
+            // Create dirs if needed
+            return ensureDirsExistOrFilter(dirs);
         }
     }
 
     @Override
     public File getObbDir() {
+        // Operates on primary external storage
+        return getObbDirs()[0];
+    }
+
+    @Override
+    public File[] getObbDirs() {
         synchronized (mSync) {
-            if (mObbDir == null) {
-                mObbDir = Environment.getExternalStorageAppObbDirectory(
-                        getPackageName());
+            if (mExternalObbDirs == null) {
+                mExternalObbDirs = Environment.buildExternalStorageAppObbDirs(getPackageName());
             }
-            return mObbDir;
+            return mExternalObbDirs;
         }
     }
 
@@ -816,23 +890,19 @@
 
     @Override
     public File getExternalCacheDir() {
+        // Operates on primary external storage
+        return getExternalCacheDirs()[0];
+    }
+
+    @Override
+    public File[] getExternalCacheDirs() {
         synchronized (mSync) {
-            if (mExternalCacheDir == null) {
-                mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
-                        getPackageName());
+            if (mExternalCacheDirs == null) {
+                mExternalCacheDirs = Environment.buildExternalStorageAppCacheDirs(getPackageName());
             }
-            if (!mExternalCacheDir.exists()) {
-                try {
-                    (new File(Environment.getExternalStorageAndroidDataDir(),
-                            ".nomedia")).createNewFile();
-                } catch (IOException e) {
-                }
-                if (!mExternalCacheDir.mkdirs()) {
-                    Log.w(TAG, "Unable to create external cache directory");
-                    return null;
-                }
-            }
-            return mExternalCacheDir;
+
+            // Create dirs if needed
+            return ensureDirsExistOrFilter(mExternalCacheDirs);
         }
     }
 
@@ -1395,6 +1465,14 @@
     @Override
     public ComponentName startServiceAsUser(Intent service, UserHandle user) {
         try {
+            if (service.getComponent() == null && service.getPackage() == null) {
+                if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.KITKAT) {
+                    IllegalArgumentException ex = new IllegalArgumentException(
+                            "Service Intent must be explicit: " + service);
+                    Log.e(TAG, "This will become an error", ex);
+                    //throw ex;
+                }
+            }
             service.prepareToLeaveProcess();
             ComponentName cn = ActivityManagerNative.getDefault().startService(
                 mMainThread.getApplicationThread(), service,
@@ -1419,6 +1497,14 @@
     @Override
     public boolean stopServiceAsUser(Intent service, UserHandle user) {
         try {
+            if (service.getComponent() == null && service.getPackage() == null) {
+                if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.KITKAT) {
+                    IllegalArgumentException ex = new IllegalArgumentException(
+                            "Service Intent must be explicit: " + service);
+                    Log.e(TAG, "This will become an error", ex);
+                    //throw ex;
+                }
+            }
             service.prepareToLeaveProcess();
             int res = ActivityManagerNative.getDefault().stopService(
                 mMainThread.getApplicationThread(), service,
@@ -1454,6 +1540,14 @@
         } else {
             throw new RuntimeException("Not supported in system context");
         }
+        if (service.getComponent() == null && service.getPackage() == null) {
+            if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.KITKAT) {
+                IllegalArgumentException ex = new IllegalArgumentException(
+                        "Service Intent must be explicit: " + service);
+                Log.e(TAG, "This will become an error", ex);
+                //throw ex;
+            }
+        }
         try {
             IBinder token = getActivityToken();
             if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
@@ -1746,6 +1840,11 @@
                       message);
     }
 
+    /**
+     * Logs a warning if the system process directly called a method such as
+     * {@link #startService(Intent)} instead of {@link #startServiceAsUser(Intent, UserHandle)}.
+     * The "AsUser" variants allow us to properly enforce the user's restrictions.
+     */
     private void warnIfCallingFromSystemProcess() {
         if (Process.myUid() == Process.SYSTEM_UID) {
             Slog.w(TAG, "Calling a method in the system process without a qualified user: "
@@ -1795,10 +1894,9 @@
 
         ContextImpl c = new ContextImpl();
         c.init(mPackageInfo, null, mMainThread);
-        c.mResources = mMainThread.getTopLevelResources(
-                mPackageInfo.getResDir(),
-                getDisplayId(), overrideConfiguration,
-                mResources.getCompatibilityInfo());
+        c.mResources = mResourcesManager.getTopLevelResources(mPackageInfo.getResDir(),
+                getDisplayId(), overrideConfiguration, mResources.getCompatibilityInfo(),
+                mActivityToken);
         return c;
     }
 
@@ -1809,17 +1907,13 @@
         }
 
         int displayId = display.getDisplayId();
-        CompatibilityInfo ci = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
-        CompatibilityInfoHolder cih = getCompatibilityInfo(displayId);
-        if (cih != null) {
-            ci = cih.get();
-        }
 
         ContextImpl context = new ContextImpl();
         context.init(mPackageInfo, null, mMainThread);
         context.mDisplay = display;
-        context.mResources = mMainThread.getTopLevelResources(
-                mPackageInfo.getResDir(), displayId, null, ci);
+        DisplayAdjustments daj = getDisplayAdjustments(displayId);
+        context.mResources = mResourcesManager.getTopLevelResources(mPackageInfo.getResDir(),
+                displayId, null, daj.getCompatibilityInfo(), null);
         return context;
     }
 
@@ -1833,8 +1927,8 @@
     }
 
     @Override
-    public CompatibilityInfoHolder getCompatibilityInfo(int displayId) {
-        return displayId == Display.DEFAULT_DISPLAY ? mPackageInfo.mCompatibilityInfo : null;
+    public DisplayAdjustments getDisplayAdjustments(int displayId) {
+        return mDisplayAdjustments;
     }
 
     private File getDataDirFile() {
@@ -1880,12 +1974,14 @@
     public ContextImpl(ContextImpl context) {
         mPackageInfo = context.mPackageInfo;
         mBasePackageName = context.mBasePackageName;
+        mOpPackageName = context.mOpPackageName;
         mResources = context.mResources;
         mMainThread = context.mMainThread;
         mContentResolver = context.mContentResolver;
         mUser = context.mUser;
         mDisplay = context.mDisplay;
         mOuterContext = this;
+        mDisplayAdjustments.setCompatibilityInfo(mPackageInfo.getCompatibilityInfo());
     }
 
     final void init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread) {
@@ -1895,19 +1991,44 @@
     final void init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread,
             Resources container, String basePackageName, UserHandle user) {
         mPackageInfo = packageInfo;
-        mBasePackageName = basePackageName != null ? basePackageName : packageInfo.mPackageName;
+        if (basePackageName != null) {
+            mBasePackageName = mOpPackageName = basePackageName;
+        } else {
+            mBasePackageName = packageInfo.mPackageName;
+            ApplicationInfo ainfo = packageInfo.getApplicationInfo();
+            if (ainfo.uid == Process.SYSTEM_UID && ainfo.uid != Process.myUid()) {
+                // Special case: system components allow themselves to be loaded in to other
+                // processes.  For purposes of app ops, we must then consider the context as
+                // belonging to the package of this process, not the system itself, otherwise
+                // the package+uid verifications in app ops will fail.
+                mOpPackageName = ActivityThread.currentPackageName();
+            } else {
+                mOpPackageName = mBasePackageName;
+            }
+        }
         mResources = mPackageInfo.getResources(mainThread);
+        mResourcesManager = ResourcesManager.getInstance();
 
-        if (mResources != null && container != null
-                && container.getCompatibilityInfo().applicationScale !=
-                        mResources.getCompatibilityInfo().applicationScale) {
+        CompatibilityInfo compatInfo =
+                container == null ? null : container.getCompatibilityInfo();
+        if (mResources != null &&
+                ((compatInfo != null && compatInfo.applicationScale !=
+                        mResources.getCompatibilityInfo().applicationScale)
+                || activityToken != null)) {
             if (DEBUG) {
                 Log.d(TAG, "loaded context has different scaling. Using container's" +
                         " compatiblity info:" + container.getDisplayMetrics());
             }
-            mResources = mainThread.getTopLevelResources(
-                    mPackageInfo.getResDir(), Display.DEFAULT_DISPLAY,
-                    null, container.getCompatibilityInfo());
+            if (compatInfo == null) {
+                compatInfo = packageInfo.getCompatibilityInfo();
+            }
+            mDisplayAdjustments.setCompatibilityInfo(compatInfo);
+            mDisplayAdjustments.setActivityToken(activityToken);
+            mResources = mResourcesManager.getTopLevelResources(mPackageInfo.getResDir(),
+                    Display.DEFAULT_DISPLAY, null, compatInfo, activityToken);
+        } else {
+            mDisplayAdjustments.setCompatibilityInfo(packageInfo.getCompatibilityInfo());
+            mDisplayAdjustments.setActivityToken(activityToken);
         }
         mMainThread = mainThread;
         mActivityToken = activityToken;
@@ -1918,6 +2039,7 @@
     final void init(Resources resources, ActivityThread mainThread, UserHandle user) {
         mPackageInfo = null;
         mBasePackageName = null;
+        mOpPackageName = null;
         mResources = resources;
         mMainThread = mainThread;
         mContentResolver = new ApplicationContentResolver(this, mainThread, user);
@@ -2001,6 +2123,25 @@
                 "File " + name + " contains a path separator");
     }
 
+    /**
+     * Ensure that given directories exist, trying to create them if missing. If
+     * unable to create, they are filtered by replacing with {@code null}.
+     */
+    private static File[] ensureDirsExistOrFilter(File[] dirs) {
+        File[] result = new File[dirs.length];
+        for (int i = 0; i < dirs.length; i++) {
+            File dir = dirs[i];
+            if (!dir.exists()) {
+                if (!dir.mkdirs()) {
+                    Log.w(TAG, "Failed to ensure directory: " + dir);
+                    dir = null;
+                }
+            }
+            result[i] = dir;
+        }
+        return result;
+    }
+
     // ----------------------------------------------------------------------
     // ----------------------------------------------------------------------
     // ----------------------------------------------------------------------
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index b3d99c5..cda2c5f 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -16,6 +16,8 @@
 
 package android.app;
 
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
 import com.android.internal.app.ActionBarImpl;
 import com.android.internal.policy.PolicyManager;
 
@@ -264,6 +266,9 @@
         mDecor = mWindow.getDecorView();
 
         if (mActionBar == null && mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {
+            final ApplicationInfo info = mContext.getApplicationInfo();
+            mWindow.setDefaultIcon(info.icon);
+            mWindow.setDefaultLogo(info.logo);
             mActionBar = new ActionBarImpl(this);
         }
 
@@ -301,6 +306,7 @@
      * method to do cleanup when the dialog is dismissed, instead implement
      * that in {@link #onStop}.
      */
+    @Override
     public void dismiss() {
         if (Looper.myLooper() == mHandler.getLooper()) {
             dismissDialog();
@@ -320,7 +326,7 @@
         }
 
         try {
-            mWindowManager.removeView(mDecor);
+            mWindowManager.removeViewImmediate(mDecor);
         } finally {
             if (mActionMode != null) {
                 mActionMode.finish();
@@ -329,7 +335,7 @@
             mWindow.closeAllPanels();
             onStop();
             mShowing = false;
-            
+
             sendDismissMessage();
         }
     }
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index b6aeb84..d626e5f 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -26,10 +26,12 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.AndroidRuntimeException;
+import android.util.ArrayMap;
 import android.util.AttributeSet;
 import android.util.DebugUtils;
 import android.util.Log;
 import android.util.SparseArray;
+import android.util.SuperNotCalledException;
 import android.view.ContextMenu;
 import android.view.ContextMenu.ContextMenuInfo;
 import android.view.LayoutInflater;
@@ -43,7 +45,6 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.util.HashMap;
 
 final class FragmentState implements Parcelable {
     final String mClassName;
@@ -342,8 +343,8 @@
  * the activity UI was in.
  */
 public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListener {
-    private static final HashMap<String, Class<?>> sClassMap =
-            new HashMap<String, Class<?>>();
+    private static final ArrayMap<String, Class<?>> sClassMap =
+            new ArrayMap<String, Class<?>>();
     
     static final int INVALID_STATE = -1;   // Invalid state used as a null value.
     static final int INITIALIZING = 0;     // Not yet created.
@@ -580,6 +581,10 @@
             if (clazz == null) {
                 // Class not found in the cache, see if it's real, and try to add it
                 clazz = context.getClassLoader().loadClass(fname);
+                if (!Fragment.class.isAssignableFrom(clazz)) {
+                    throw new InstantiationException("Trying to instantiate a class " + fname
+                            + " that is not a Fragment", new ClassCastException());
+                }
                 sClassMap.put(fname, clazz);
             }
             Fragment f = (Fragment)clazz.newInstance();
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 72c9156..4371907 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -31,11 +31,13 @@
 import android.util.Log;
 import android.util.LogWriter;
 import android.util.SparseArray;
+import android.util.SuperNotCalledException;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
+import com.android.internal.util.FastPrintWriter;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -445,12 +447,13 @@
     private void throwException(RuntimeException ex) {
         Log.e(TAG, ex.getMessage());
         LogWriter logw = new LogWriter(Log.ERROR, TAG);
-        PrintWriter pw = new PrintWriter(logw);
+        PrintWriter pw = new FastPrintWriter(logw, false, 1024);
         if (mActivity != null) {
             Log.e(TAG, "Activity state:");
             try {
                 mActivity.dump("  ", null, pw, new String[] { });
             } catch (Exception e) {
+                pw.flush();
                 Log.e(TAG, "Failed dumping state", e);
             }
         } else {
@@ -458,9 +461,11 @@
             try {
                 dump("  ", null, pw, new String[] { });
             } catch (Exception e) {
+                pw.flush();
                 Log.e(TAG, "Failed dumping state", e);
             }
         }
+        pw.flush();
         throw ex;
     }
 
@@ -1324,12 +1329,19 @@
         }
     }
 
+    /**
+     * Adds an action to the queue of pending actions.
+     *
+     * @param action the action to add
+     * @param allowStateLoss whether to allow loss of state information
+     * @throws IllegalStateException if the activity has been destroyed
+     */
     public void enqueueAction(Runnable action, boolean allowStateLoss) {
         if (!allowStateLoss) {
             checkStateLoss();
         }
         synchronized (this) {
-            if (mActivity == null) {
+            if (mDestroyed || mActivity == null) {
                 throw new IllegalStateException("Activity has been destroyed");
             }
             if (mPendingActions == null) {
@@ -1806,8 +1818,9 @@
                     Log.v(TAG, "restoreAllState: back stack #" + i
                         + " (index " + bse.mIndex + "): " + bse);
                     LogWriter logw = new LogWriter(Log.VERBOSE, TAG);
-                    PrintWriter pw = new PrintWriter(logw);
+                    PrintWriter pw = new FastPrintWriter(logw, false, 1024);
                     bse.dump("  ", pw, false);
+                    pw.flush();
                 }
                 mBackStack.add(bse);
                 if (bse.mIndex >= 0) {
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index a21caee..b2ae298 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -16,6 +16,9 @@
 
 package android.app;
 
+import android.app.ActivityManager.RunningTaskInfo;
+import android.app.ActivityManager.RunningServiceInfo;
+import android.app.ActivityManager.StackBoxInfo;
 import android.content.ComponentName;
 import android.content.ContentProviderNative;
 import android.content.IContentProvider;
@@ -99,19 +102,26 @@
     public void activityDestroyed(IBinder token) throws RemoteException;
     public String getCallingPackage(IBinder token) throws RemoteException;
     public ComponentName getCallingActivity(IBinder token) throws RemoteException;
-    public List getTasks(int maxNum, int flags,
+    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
                          IThumbnailReceiver receiver) throws RemoteException;
     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
             int flags, int userId) throws RemoteException;
     public ActivityManager.TaskThumbnails getTaskThumbnails(int taskId) throws RemoteException;
     public Bitmap getTaskTopThumbnail(int taskId) throws RemoteException;
-    public List getServices(int maxNum, int flags) throws RemoteException;
+    public List<RunningServiceInfo> getServices(int maxNum, int flags) throws RemoteException;
     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState()
             throws RemoteException;
     public void moveTaskToFront(int task, int flags, Bundle options) throws RemoteException;
     public void moveTaskToBack(int task) throws RemoteException;
     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) throws RemoteException;
     public void moveTaskBackwards(int task) throws RemoteException;
+    public int createStack(int taskId, int relativeStackBoxId, int position, float weight)
+            throws RemoteException;
+    public void moveTaskToStack(int taskId, int stackId, boolean toTop) throws RemoteException;
+    public void resizeStackBox(int stackBoxId, float weight) throws RemoteException;
+    public List<StackBoxInfo> getStackBoxes() throws RemoteException;
+    public StackBoxInfo getStackBoxInfo(int stackBoxId) throws RemoteException;
+    public void setFocusedStack(int stackId) throws RemoteException;
     public int getTaskForActivity(IBinder token, boolean onlyRoot) throws RemoteException;
     /* oneway */
     public void reportThumbnail(IBinder token,
@@ -149,14 +159,14 @@
     public void serviceDoneExecuting(IBinder token, int type, int startId,
             int res) throws RemoteException;
     public IBinder peekService(Intent service, String resolvedType) throws RemoteException;
-    
+
     public boolean bindBackupAgent(ApplicationInfo appInfo, int backupRestoreMode)
             throws RemoteException;
     public void clearPendingBackup() throws RemoteException;
     public void backupAgentCreated(String packageName, IBinder agent) throws RemoteException;
     public void unbindBackupAgent(ApplicationInfo appInfo) throws RemoteException;
     public void killApplicationProcess(String processName, int uid) throws RemoteException;
-    
+
     public boolean startInstrumentation(ComponentName className, String profileFile,
             int flags, Bundle arguments, IInstrumentationWatcher watcher,
             IUiAutomationConnection connection, int userId) throws RemoteException;
@@ -168,7 +178,7 @@
     public void setRequestedOrientation(IBinder token,
             int requestedOrientation) throws RemoteException;
     public int getRequestedOrientation(IBinder token) throws RemoteException;
-    
+
     public ComponentName getActivityClassForToken(IBinder token) throws RemoteException;
     public String getPackageForToken(IBinder token) throws RemoteException;
 
@@ -181,16 +191,16 @@
             final IPackageDataObserver observer, int userId) throws RemoteException;
     public String getPackageForIntentSender(IIntentSender sender) throws RemoteException;
     public int getUidForIntentSender(IIntentSender sender) throws RemoteException;
-    
+
     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
             boolean requireFull, String name, String callerPackage) throws RemoteException;
 
     public void setProcessLimit(int max) throws RemoteException;
     public int getProcessLimit() throws RemoteException;
-    
+
     public void setProcessForeground(IBinder token, int pid,
             boolean isForeground) throws RemoteException;
-    
+
     public int checkPermission(String permission, int pid, int uid)
             throws RemoteException;
 
@@ -248,7 +258,7 @@
             StrictMode.ViolationInfo crashInfo) throws RemoteException;
 
     /*
-     * This will deliver the specified signal to all the persistent processes. Currently only 
+     * This will deliver the specified signal to all the persistent processes. Currently only
      * SIGUSR1 is delivered. All others are ignored.
      */
     public void signalPersistentProcesses(int signal) throws RemoteException;
@@ -274,7 +284,8 @@
     public void stopAppSwitches() throws RemoteException;
     public void resumeAppSwitches() throws RemoteException;
     
-    public void killApplicationWithAppId(String pkg, int appid) throws RemoteException;
+    public void killApplicationWithAppId(String pkg, int appid, String reason)
+            throws RemoteException;
     
     public void closeSystemDialogs(String reason) throws RemoteException;
     
@@ -290,6 +301,10 @@
 
     public void finishHeavyWeightApp() throws RemoteException;
 
+    public boolean convertFromTranslucent(IBinder token) throws RemoteException;
+    public boolean convertToTranslucent(IBinder token) throws RemoteException;
+    public void notifyActivityDrawn(IBinder token) throws RemoteException;
+
     public void setImmersive(IBinder token, boolean immersive) throws RemoteException;
     public boolean isImmersive(IBinder token) throws RemoteException;
     public boolean isTopActivityImmersive() throws RemoteException;
@@ -369,16 +384,25 @@
 
     public void requestBugReport() throws RemoteException;
 
-    public long inputDispatchingTimedOut(int pid, boolean aboveSystem) throws RemoteException;
+    public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason)
+            throws RemoteException;
 
-    public Bundle getTopActivityExtras(int requestType) throws RemoteException;
+    public Bundle getAssistContextExtras(int requestType) throws RemoteException;
 
-    public void reportTopActivityExtras(IBinder token, Bundle extras) throws RemoteException;
+    public void reportAssistContextExtras(IBinder token, Bundle extras) throws RemoteException;
 
     public void killUid(int uid, String reason) throws RemoteException;
 
     public void hang(IBinder who, boolean allowRestart) throws RemoteException;
 
+    public void reportActivityFullyDrawn(IBinder token) throws RemoteException;
+
+    public void restart() throws RemoteException;
+
+    public Uri[] getGrantedUriPermissions(
+            String sourcePackage, String targetPackage, int modeFlags, int modeMask)
+            throws RemoteException;
+
     /*
      * Private non-Binder interfaces
      */
@@ -395,10 +419,12 @@
             info = _info;
         }
 
+        @Override
         public int describeContents() {
             return 0;
         }
 
+        @Override
         public void writeToParcel(Parcel dest, int flags) {
             info.writeToParcel(dest, 0);
             if (provider != null) {
@@ -412,10 +438,12 @@
 
         public static final Parcelable.Creator<ContentProviderHolder> CREATOR
                 = new Parcelable.Creator<ContentProviderHolder>() {
+            @Override
             public ContentProviderHolder createFromParcel(Parcel source) {
                 return new ContentProviderHolder(source);
             }
 
+            @Override
             public ContentProviderHolder[] newArray(int size) {
                 return new ContentProviderHolder[size];
             }
@@ -441,10 +469,12 @@
         public WaitResult() {
         }
 
+        @Override
         public int describeContents() {
             return 0;
         }
 
+        @Override
         public void writeToParcel(Parcel dest, int flags) {
             dest.writeInt(result);
             dest.writeInt(timeout ? 1 : 0);
@@ -455,10 +485,12 @@
 
         public static final Parcelable.Creator<WaitResult> CREATOR
                 = new Parcelable.Creator<WaitResult>() {
+            @Override
             public WaitResult createFromParcel(Parcel source) {
                 return new WaitResult(source);
             }
 
+            @Override
             public WaitResult[] newArray(int size) {
                 return new WaitResult[size];
             }
@@ -471,7 +503,7 @@
             thisTime = source.readLong();
             totalTime = source.readLong();
         }
-    };
+    }
 
     String descriptor = "android.app.IActivityManager";
 
@@ -635,10 +667,22 @@
     int INPUT_DISPATCHING_TIMED_OUT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+158;
     int CLEAR_PENDING_BACKUP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+159;
     int GET_INTENT_FOR_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+160;
-    int GET_TOP_ACTIVITY_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+161;
-    int REPORT_TOP_ACTIVITY_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+162;
+    int GET_ASSIST_CONTEXT_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+161;
+    int REPORT_ASSIST_CONTEXT_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+162;
     int GET_LAUNCHED_FROM_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+163;
     int KILL_UID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+164;
     int SET_USER_IS_MONKEY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+165;
     int HANG_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+166;
+    int CREATE_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+167;
+    int MOVE_TASK_TO_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+168;
+    int RESIZE_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+169;
+    int GET_STACK_BOXES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+170;
+    int SET_FOCUSED_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+171;
+    int GET_STACK_BOX_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+172;
+    int CONVERT_FROM_TRANSLUCENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+173;
+    int CONVERT_TO_TRANSLUCENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+174;
+    int NOTIFY_ACTIVITY_DRAWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+175;
+    int REPORT_ACTIVITY_FULLY_DRAWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+176;
+    int RESTART_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+177;
+    int GET_GRANTED_URI_PERMISSIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+178;
 }
diff --git a/core/java/android/app/IAlarmManager.aidl b/core/java/android/app/IAlarmManager.aidl
index edb40ed..8476609 100644
--- a/core/java/android/app/IAlarmManager.aidl
+++ b/core/java/android/app/IAlarmManager.aidl
@@ -17,6 +17,7 @@
 package android.app;
 
 import android.app.PendingIntent;
+import android.os.WorkSource;
 
 /**
  * System private API for talking with the alarm manager service.
@@ -24,9 +25,9 @@
  * {@hide}
  */
 interface IAlarmManager {
-    void set(int type, long triggerAtTime, in PendingIntent operation);
-    void setRepeating(int type, long triggerAtTime, long interval, in PendingIntent operation);
-    void setInexactRepeating(int type, long triggerAtTime, long interval, in PendingIntent operation);
+	/** windowLength == 0 means exact; windowLength < 0 means the let the OS decide */
+    void set(int type, long triggerAtTime, long windowLength,
+            long interval, in PendingIntent operation, in WorkSource workSource);
     void setTime(long millis);
     void setTimeZone(String zone);
     void remove(in PendingIntent operation);
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index 3189b31a..058b975 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -50,11 +50,12 @@
             int configChanges) throws RemoteException;
     void scheduleWindowVisibility(IBinder token, boolean showWindow) throws RemoteException;
     void scheduleSleeping(IBinder token, boolean sleeping) throws RemoteException;
-    void scheduleResumeActivity(IBinder token, boolean isForward) throws RemoteException;
+    void scheduleResumeActivity(IBinder token, int procState, boolean isForward)
+            throws RemoteException;
     void scheduleSendResult(IBinder token, List<ResultInfo> results) throws RemoteException;
     void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
             ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
-            Bundle state, List<ResultInfo> pendingResults,
+            int procState, Bundle state, List<ResultInfo> pendingResults,
     		List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
     		String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler)
     		throws RemoteException;
@@ -66,7 +67,7 @@
             int configChanges) throws RemoteException;
     void scheduleReceiver(Intent intent, ActivityInfo info, CompatibilityInfo compatInfo,
             int resultCode, String data, Bundle extras, boolean sync,
-            int sendingUser) throws RemoteException;
+            int sendingUser, int processState) throws RemoteException;
     static final int BACKUP_MODE_INCREMENTAL = 0;
     static final int BACKUP_MODE_FULL = 1;
     static final int BACKUP_MODE_RESTORE = 2;
@@ -76,9 +77,9 @@
     void scheduleDestroyBackupAgent(ApplicationInfo app, CompatibilityInfo compatInfo)
             throws RemoteException;
     void scheduleCreateService(IBinder token, ServiceInfo info,
-            CompatibilityInfo compatInfo) throws RemoteException;
+            CompatibilityInfo compatInfo, int processState) throws RemoteException;
     void scheduleBindService(IBinder token,
-            Intent intent, boolean rebind) throws RemoteException;
+            Intent intent, boolean rebind, int processState) throws RemoteException;
     void scheduleUnbindService(IBinder token,
             Intent intent) throws RemoteException;
     void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
@@ -100,7 +101,8 @@
     void scheduleConfigurationChanged(Configuration config) throws RemoteException;
     void updateTimeZone() throws RemoteException;
     void clearDnsCache() throws RemoteException;
-    void setHttpProxy(String proxy, String port, String exclList) throws RemoteException;
+    void setHttpProxy(String proxy, String port, String exclList,
+            String pacFileUrl) throws RemoteException;
     void processInBackground() throws RemoteException;
     void dumpService(FileDescriptor fd, IBinder servicetoken, String[] args)
             throws RemoteException;
@@ -108,7 +110,7 @@
             throws RemoteException;
     void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
             int resultCode, String data, Bundle extras, boolean ordered,
-            boolean sticky, int sendingUser) throws RemoteException;
+            boolean sticky, int sendingUser, int processState) throws RemoteException;
     void scheduleLowMemory() throws RemoteException;
     void scheduleActivityConfigurationChanged(IBinder token) throws RemoteException;
     void profilerControl(boolean start, String path, ParcelFileDescriptor fd, int profileType)
@@ -126,13 +128,16 @@
     void setCoreSettings(Bundle coreSettings) throws RemoteException;
     void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) throws RemoteException;
     void scheduleTrimMemory(int level) throws RemoteException;
-    Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, boolean checkin, boolean all,
-            String[] args) throws RemoteException;
+    Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, boolean checkin, boolean dumpInfo,
+            boolean dumpDalvik, String[] args) throws RemoteException;
     void dumpGfxInfo(FileDescriptor fd, String[] args) throws RemoteException;
     void dumpDbInfo(FileDescriptor fd, String[] args) throws RemoteException;
     void unstableProviderDied(IBinder provider) throws RemoteException;
-    void requestActivityExtras(IBinder activityToken, IBinder requestToken, int requestType)
+    void requestAssistContextExtras(IBinder activityToken, IBinder requestToken, int requestType)
             throws RemoteException;
+    void scheduleTranslucentConversionComplete(IBinder token, boolean timeout)
+            throws RemoteException;
+    void setProcessState(int state) throws RemoteException;
 
     String descriptor = "android.app.IApplicationThread";
 
@@ -182,5 +187,7 @@
     int DUMP_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+44;
     int DUMP_DB_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+45;
     int UNSTABLE_PROVIDER_DIED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+46;
-    int REQUEST_ACTIVITY_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+47;
+    int REQUEST_ASSIST_CONTEXT_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+47;
+    int SCHEDULE_TRANSLUCENT_CONVERSION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+48;
+    int SET_PROCESS_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+49;
 }
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 2224490..4239a5d 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -16,6 +16,7 @@
 
 package android.app;
 
+import android.util.ArrayMap;
 import com.android.internal.util.ArrayUtils;
 
 import android.content.BroadcastReceiver;
@@ -40,7 +41,7 @@
 import android.os.UserHandle;
 import android.util.AndroidRuntimeException;
 import android.util.Slog;
-import android.view.CompatibilityInfoHolder;
+import android.view.DisplayAdjustments;
 import android.view.Display;
 
 import java.io.File;
@@ -49,8 +50,6 @@
 import java.lang.ref.WeakReference;
 import java.net.URL;
 import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Iterator;
 
 final class IntentReceiverLeaked extends AndroidRuntimeException {
     public IntentReceiverLeaked(String msg) {
@@ -84,19 +83,19 @@
     private final ClassLoader mBaseClassLoader;
     private final boolean mSecurityViolation;
     private final boolean mIncludeCode;
-    public final CompatibilityInfoHolder mCompatibilityInfo = new CompatibilityInfoHolder();
+    private final DisplayAdjustments mDisplayAdjustments = new DisplayAdjustments();
     Resources mResources;
     private ClassLoader mClassLoader;
     private Application mApplication;
 
-    private final HashMap<Context, HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>> mReceivers
-        = new HashMap<Context, HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>>();
-    private final HashMap<Context, HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>> mUnregisteredReceivers
-    = new HashMap<Context, HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>>();
-    private final HashMap<Context, HashMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices
-        = new HashMap<Context, HashMap<ServiceConnection, LoadedApk.ServiceDispatcher>>();
-    private final HashMap<Context, HashMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mUnboundServices
-        = new HashMap<Context, HashMap<ServiceConnection, LoadedApk.ServiceDispatcher>>();
+    private final ArrayMap<Context, ArrayMap<BroadcastReceiver, ReceiverDispatcher>> mReceivers
+        = new ArrayMap<Context, ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>>();
+    private final ArrayMap<Context, ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>> mUnregisteredReceivers
+        = new ArrayMap<Context, ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>>();
+    private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices
+        = new ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>>();
+    private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mUnboundServices
+        = new ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>>();
 
     int mClientCount = 0;
 
@@ -132,17 +131,17 @@
         mBaseClassLoader = baseLoader;
         mSecurityViolation = securityViolation;
         mIncludeCode = includeCode;
-        mCompatibilityInfo.set(compatInfo);
+        mDisplayAdjustments.setCompatibilityInfo(compatInfo);
 
         if (mAppDir == null) {
             if (ActivityThread.mSystemContext == null) {
                 ActivityThread.mSystemContext =
                     ContextImpl.createSystemContext(mainThread);
+                ResourcesManager resourcesManager = ResourcesManager.getInstance();
                 ActivityThread.mSystemContext.getResources().updateConfiguration(
-                         mainThread.getConfiguration(),
-                         mainThread.getDisplayMetricsLocked(
-                                 Display.DEFAULT_DISPLAY, compatInfo),
-                         compatInfo);
+                        resourcesManager.getConfiguration(),
+                        resourcesManager.getDisplayMetricsLocked(
+                                 Display.DEFAULT_DISPLAY, mDisplayAdjustments), compatInfo);
                 //Slog.i(TAG, "Created system resources "
                 //        + mSystemContext.getResources() + ": "
                 //        + mSystemContext.getResources().getConfiguration());
@@ -169,7 +168,7 @@
         mIncludeCode = true;
         mClassLoader = systemContext.getClassLoader();
         mResources = systemContext.getResources();
-        mCompatibilityInfo.set(compatInfo);
+        mDisplayAdjustments.setCompatibilityInfo(compatInfo);
     }
 
     public String getPackageName() {
@@ -184,6 +183,14 @@
         return mSecurityViolation;
     }
 
+    public CompatibilityInfo getCompatibilityInfo() {
+        return mDisplayAdjustments.getCompatibilityInfo();
+    }
+
+    public void setCompatibilityInfo(CompatibilityInfo compatInfo) {
+        mDisplayAdjustments.setCompatibilityInfo(compatInfo);
+    }
+
     /**
      * Gets the array of shared libraries that are listed as
      * used by the given package.
@@ -532,12 +539,11 @@
     public void removeContextRegistrations(Context context,
             String who, String what) {
         final boolean reportRegistrationLeaks = StrictMode.vmRegistrationLeaksEnabled();
-        HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> rmap =
-            mReceivers.remove(context);
+        ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> rmap =
+                mReceivers.remove(context);
         if (rmap != null) {
-            Iterator<LoadedApk.ReceiverDispatcher> it = rmap.values().iterator();
-            while (it.hasNext()) {
-                LoadedApk.ReceiverDispatcher rd = it.next();
+            for (int i=0; i<rmap.size(); i++) {
+                LoadedApk.ReceiverDispatcher rd = rmap.valueAt(i);
                 IntentReceiverLeaked leak = new IntentReceiverLeaked(
                         what + " " + who + " has leaked IntentReceiver "
                         + rd.getIntentReceiver() + " that was " +
@@ -558,12 +564,11 @@
         }
         mUnregisteredReceivers.remove(context);
         //Slog.i(TAG, "Receiver registrations: " + mReceivers);
-        HashMap<ServiceConnection, LoadedApk.ServiceDispatcher> smap =
+        ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> smap =
             mServices.remove(context);
         if (smap != null) {
-            Iterator<LoadedApk.ServiceDispatcher> it = smap.values().iterator();
-            while (it.hasNext()) {
-                LoadedApk.ServiceDispatcher sd = it.next();
+            for (int i=0; i<smap.size(); i++) {
+                LoadedApk.ServiceDispatcher sd = smap.valueAt(i);
                 ServiceConnectionLeaked leak = new ServiceConnectionLeaked(
                         what + " " + who + " has leaked ServiceConnection "
                         + sd.getServiceConnection() + " that was originally bound here");
@@ -590,7 +595,7 @@
             Instrumentation instrumentation, boolean registered) {
         synchronized (mReceivers) {
             LoadedApk.ReceiverDispatcher rd = null;
-            HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null;
+            ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null;
             if (registered) {
                 map = mReceivers.get(context);
                 if (map != null) {
@@ -602,7 +607,7 @@
                         instrumentation, registered);
                 if (registered) {
                     if (map == null) {
-                        map = new HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
+                        map = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
                         mReceivers.put(context, map);
                     }
                     map.put(r, rd);
@@ -618,7 +623,7 @@
     public IIntentReceiver forgetReceiverDispatcher(Context context,
             BroadcastReceiver r) {
         synchronized (mReceivers) {
-            HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = mReceivers.get(context);
+            ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = mReceivers.get(context);
             LoadedApk.ReceiverDispatcher rd = null;
             if (map != null) {
                 rd = map.get(r);
@@ -628,10 +633,10 @@
                         mReceivers.remove(context);
                     }
                     if (r.getDebugUnregister()) {
-                        HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> holder
+                        ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> holder
                                 = mUnregisteredReceivers.get(context);
                         if (holder == null) {
-                            holder = new HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
+                            holder = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
                             mUnregisteredReceivers.put(context, holder);
                         }
                         RuntimeException ex = new IllegalArgumentException(
@@ -644,7 +649,7 @@
                     return rd.getIIntentReceiver();
                 }
             }
-            HashMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> holder
+            ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> holder
                     = mUnregisteredReceivers.get(context);
             if (holder != null) {
                 rd = holder.get(r);
@@ -860,14 +865,14 @@
             Context context, Handler handler, int flags) {
         synchronized (mServices) {
             LoadedApk.ServiceDispatcher sd = null;
-            HashMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
+            ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
             if (map != null) {
                 sd = map.get(c);
             }
             if (sd == null) {
                 sd = new ServiceDispatcher(c, context, handler, flags);
                 if (map == null) {
-                    map = new HashMap<ServiceConnection, LoadedApk.ServiceDispatcher>();
+                    map = new ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>();
                     mServices.put(context, map);
                 }
                 map.put(c, sd);
@@ -881,7 +886,7 @@
     public final IServiceConnection forgetServiceDispatcher(Context context,
             ServiceConnection c) {
         synchronized (mServices) {
-            HashMap<ServiceConnection, LoadedApk.ServiceDispatcher> map
+            ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map
                     = mServices.get(context);
             LoadedApk.ServiceDispatcher sd = null;
             if (map != null) {
@@ -893,10 +898,10 @@
                         mServices.remove(context);
                     }
                     if ((sd.getFlags()&Context.BIND_DEBUG_UNBIND) != 0) {
-                        HashMap<ServiceConnection, LoadedApk.ServiceDispatcher> holder
+                        ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> holder
                                 = mUnboundServices.get(context);
                         if (holder == null) {
-                            holder = new HashMap<ServiceConnection, LoadedApk.ServiceDispatcher>();
+                            holder = new ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>();
                             mUnboundServices.put(context, holder);
                         }
                         RuntimeException ex = new IllegalArgumentException(
@@ -908,7 +913,7 @@
                     return sd.getIServiceConnection();
                 }
             }
-            HashMap<ServiceConnection, LoadedApk.ServiceDispatcher> holder
+            ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> holder
                     = mUnboundServices.get(context);
             if (holder != null) {
                 sd = holder.get(c);
@@ -961,8 +966,8 @@
             }
         }
 
-        private final HashMap<ComponentName, ServiceDispatcher.ConnectionInfo> mActiveConnections
-            = new HashMap<ComponentName, ServiceDispatcher.ConnectionInfo>();
+        private final ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo> mActiveConnections
+            = new ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo>();
 
         ServiceDispatcher(ServiceConnection conn,
                 Context context, Handler activityThread, int flags) {
@@ -992,9 +997,8 @@
 
         void doForget() {
             synchronized(this) {
-                Iterator<ServiceDispatcher.ConnectionInfo> it = mActiveConnections.values().iterator();
-                while (it.hasNext()) {
-                    ServiceDispatcher.ConnectionInfo ci = it.next();
+                for (int i=0; i<mActiveConnections.size(); i++) {
+                    ServiceDispatcher.ConnectionInfo ci = mActiveConnections.valueAt(i);
                     ci.binder.unlinkToDeath(ci.deathMonitor, 0);
                 }
                 mActiveConnections.clear();
diff --git a/core/java/android/app/LoaderManager.java b/core/java/android/app/LoaderManager.java
index 267555a..b13b24a 100644
--- a/core/java/android/app/LoaderManager.java
+++ b/core/java/android/app/LoaderManager.java
@@ -204,13 +204,13 @@
     // These are the currently active loaders.  A loader is here
     // from the time its load is started until it has been explicitly
     // stopped or restarted by the application.
-    final SparseArray<LoaderInfo> mLoaders = new SparseArray<LoaderInfo>();
+    final SparseArray<LoaderInfo> mLoaders = new SparseArray<LoaderInfo>(0);
 
     // These are previously run loaders.  This list is maintained internally
     // to avoid destroying a loader while an application is still using it.
     // It allows an application to restart a loader, but continue using its
     // previously run loader until the new loader's data is available.
-    final SparseArray<LoaderInfo> mInactiveLoaders = new SparseArray<LoaderInfo>();
+    final SparseArray<LoaderInfo> mInactiveLoaders = new SparseArray<LoaderInfo>(0);
 
     final String mWho;
 
diff --git a/core/java/android/app/NativeActivity.java b/core/java/android/app/NativeActivity.java
index 63c6acd..4ca3747 100644
--- a/core/java/android/app/NativeActivity.java
+++ b/core/java/android/app/NativeActivity.java
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package android.app;
 
 import android.content.Context;
@@ -23,17 +24,15 @@
 import android.graphics.PixelFormat;
 import android.os.Build;
 import android.os.Bundle;
-import android.os.Environment;
 import android.os.Looper;
 import android.os.MessageQueue;
 import android.util.AttributeSet;
 import android.view.InputQueue;
-import android.view.KeyEvent;
 import android.view.Surface;
 import android.view.SurfaceHolder;
 import android.view.View;
-import android.view.WindowManager;
 import android.view.ViewTreeObserver.OnGlobalLayoutListener;
+import android.view.WindowManager;
 import android.view.inputmethod.InputMethodManager;
 
 import java.io.File;
@@ -176,16 +175,20 @@
                 ? savedInstanceState.getByteArray(KEY_NATIVE_SAVED_STATE) : null;
 
         mNativeHandle = loadNativeCode(path, funcname, Looper.myQueue(),
-                 getFilesDir().toString(), getObbDir().toString(),
-                 Environment.getExternalStorageAppFilesDirectory(ai.packageName).toString(),
-                 Build.VERSION.SDK_INT, getAssets(), nativeSavedState);
-        
+                getAbsolutePath(getFilesDir()), getAbsolutePath(getObbDir()),
+                getAbsolutePath(getExternalFilesDir(null)),
+                Build.VERSION.SDK_INT, getAssets(), nativeSavedState);
+
         if (mNativeHandle == 0) {
             throw new IllegalArgumentException("Unable to load native library: " + path);
         }
         super.onCreate(savedInstanceState);
     }
 
+    private static String getAbsolutePath(File file) {
+        return (file != null) ? file.getAbsolutePath() : null;
+    }
+
     @Override
     protected void onDestroy() {
         mDestroyed = true;
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index b66e95b..e70ad1c 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -432,51 +432,63 @@
 
     /**
      * Additional semantic data to be carried around with this Notification.
-     * @hide
      */
     public Bundle extras = new Bundle();
 
     // extras keys for Builder inputs
-    /** @hide */
     public static final String EXTRA_TITLE = "android.title";
-    /** @hide */
     public static final String EXTRA_TITLE_BIG = EXTRA_TITLE + ".big";
-    /** @hide */
     public static final String EXTRA_TEXT = "android.text";
-    /** @hide */
     public static final String EXTRA_SUB_TEXT = "android.subText";
-    /** @hide */
     public static final String EXTRA_INFO_TEXT = "android.infoText";
-    /** @hide */
     public static final String EXTRA_SUMMARY_TEXT = "android.summaryText";
-    /** @hide */
     public static final String EXTRA_SMALL_ICON = "android.icon";
-    /** @hide */
     public static final String EXTRA_LARGE_ICON = "android.largeIcon";
-    /** @hide */
     public static final String EXTRA_LARGE_ICON_BIG = EXTRA_LARGE_ICON + ".big";
-    /** @hide */
     public static final String EXTRA_PROGRESS = "android.progress";
-    /** @hide */
     public static final String EXTRA_PROGRESS_MAX = "android.progressMax";
-    /** @hide */
     public static final String EXTRA_PROGRESS_INDETERMINATE = "android.progressIndeterminate";
-    /** @hide */
     public static final String EXTRA_SHOW_CHRONOMETER = "android.showChronometer";
-    /** @hide */
     public static final String EXTRA_SHOW_WHEN = "android.showWhen";
-    /** @hide from BigPictureStyle */
     public static final String EXTRA_PICTURE = "android.picture";
-    /** @hide from InboxStyle */
     public static final String EXTRA_TEXT_LINES = "android.textLines";
 
     // extras keys for other interesting pieces of information
-    /** @hide */
     public static final String EXTRA_PEOPLE = "android.people";
 
     /**
-     * Structure to encapsulate an "action", including title and icon, that can be attached to a Notification.
      * @hide
+     * Extra added by NotificationManagerService to indicate whether a NotificationScorer
+     * modified the Notifications's score.
+     */
+    public static final String EXTRA_SCORE_MODIFIED = "android.scoreModified";
+
+    /**
+     * Notification extra to specify heads up display preference.
+     * @hide
+     */
+    public static final String EXTRA_AS_HEADS_UP = "headsup";
+
+    /**
+     * Value for {@link #EXTRA_AS_HEADS_UP} indicating that heads up display is not appropriate.
+     * @hide
+     */
+    public static final int HEADS_UP_NEVER = 0;
+
+    /**
+     * Default value for {@link #EXTRA_AS_HEADS_UP} indicating that heads up display is appropriate.
+     * @hide
+     */
+    public static final int HEADS_UP_ALLOWED = 1;
+
+    /**
+     * Value for {@link #EXTRA_AS_HEADS_UP} that advocates for heads up display.
+     * @hide
+     */
+    public static final int HEADS_UP_REQUESTED = 2;
+
+    /**
+     * Structure to encapsulate an "action", including title and icon, that can be attached to a Notification.
      */
     public static class Action implements Parcelable {
         public int icon;
@@ -530,9 +542,6 @@
         };
     }
 
-    /**
-     * @hide
-     */
     public Action[] actions;
 
     /**
@@ -1450,7 +1459,6 @@
          * called.
          *
          * @see Notification#extras
-         * @hide
          */
         public Builder setExtras(Bundle bag) {
             mExtras = bag;
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index dbafc78..3ee4306 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -133,7 +133,7 @@
         }
         if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
         try {
-            service.enqueueNotificationWithTag(pkg, mContext.getBasePackageName(), tag, id,
+            service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
                     notification, idOut, UserHandle.myUserId());
             if (id != idOut[0]) {
                 Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]);
@@ -158,7 +158,7 @@
         }
         if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
         try {
-            service.enqueueNotificationWithTag(pkg, mContext.getBasePackageName(), tag, id,
+            service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
                     notification, idOut, user.getIdentifier());
             if (id != idOut[0]) {
                 Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]);
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
new file mode 100644
index 0000000..f55dba4
--- /dev/null
+++ b/core/java/android/app/ResourcesManager.java
@@ -0,0 +1,293 @@
+/*
+ * 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.app;
+
+import static android.app.ActivityThread.DEBUG_CONFIGURATION;
+
+import android.content.pm.ActivityInfo;
+import android.content.res.AssetManager;
+import android.content.res.CompatibilityInfo;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.content.res.ResourcesKey;
+import android.hardware.display.DisplayManagerGlobal;
+import android.os.IBinder;
+import android.util.ArrayMap;
+import android.util.DisplayMetrics;
+import android.util.Slog;
+import android.view.Display;
+import android.view.DisplayAdjustments;
+
+import java.lang.ref.WeakReference;
+import java.util.Locale;
+
+/** @hide */
+public class ResourcesManager {
+    static final String TAG = "ResourcesManager";
+    static final boolean DEBUG_CACHE = false;
+    static final boolean DEBUG_STATS = true;
+
+    private static ResourcesManager sResourcesManager;
+    final ArrayMap<ResourcesKey, WeakReference<Resources> > mActiveResources
+            = new ArrayMap<ResourcesKey, WeakReference<Resources> >();
+
+    final ArrayMap<DisplayAdjustments, DisplayMetrics> mDefaultDisplayMetrics
+            = new ArrayMap<DisplayAdjustments, DisplayMetrics>();
+
+    CompatibilityInfo mResCompatibilityInfo;
+
+    Configuration mResConfiguration;
+    final Configuration mTmpConfig = new Configuration();
+
+    public static ResourcesManager getInstance() {
+        synchronized (ResourcesManager.class) {
+            if (sResourcesManager == null) {
+                sResourcesManager = new ResourcesManager();
+            }
+            return sResourcesManager;
+        }
+    }
+
+    public Configuration getConfiguration() {
+        return mResConfiguration;
+    }
+
+    public void flushDisplayMetricsLocked() {
+        mDefaultDisplayMetrics.clear();
+    }
+
+    public DisplayMetrics getDisplayMetricsLocked(int displayId) {
+        return getDisplayMetricsLocked(displayId, DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
+    }
+
+    public DisplayMetrics getDisplayMetricsLocked(int displayId, DisplayAdjustments daj) {
+        boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
+        DisplayMetrics dm = isDefaultDisplay ? mDefaultDisplayMetrics.get(daj) : null;
+        if (dm != null) {
+            return dm;
+        }
+        dm = new DisplayMetrics();
+
+        DisplayManagerGlobal displayManager = DisplayManagerGlobal.getInstance();
+        if (displayManager == null) {
+            // may be null early in system startup
+            dm.setToDefaults();
+            return dm;
+        }
+
+        if (isDefaultDisplay) {
+            mDefaultDisplayMetrics.put(daj, dm);
+        }
+
+        Display d = displayManager.getCompatibleDisplay(displayId, daj);
+        if (d != null) {
+            d.getMetrics(dm);
+        } else {
+            // Display no longer exists
+            // FIXME: This would not be a problem if we kept the Display object around
+            // instead of using the raw display id everywhere.  The Display object caches
+            // its information even after the display has been removed.
+            dm.setToDefaults();
+        }
+        //Slog.i("foo", "New metrics: w=" + metrics.widthPixels + " h="
+        //        + metrics.heightPixels + " den=" + metrics.density
+        //        + " xdpi=" + metrics.xdpi + " ydpi=" + metrics.ydpi);
+        return dm;
+    }
+
+    final void applyNonDefaultDisplayMetricsToConfigurationLocked(
+            DisplayMetrics dm, Configuration config) {
+        config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
+        config.densityDpi = dm.densityDpi;
+        config.screenWidthDp = (int)(dm.widthPixels / dm.density);
+        config.screenHeightDp = (int)(dm.heightPixels / dm.density);
+        int sl = Configuration.resetScreenLayout(config.screenLayout);
+        if (dm.widthPixels > dm.heightPixels) {
+            config.orientation = Configuration.ORIENTATION_LANDSCAPE;
+            config.screenLayout = Configuration.reduceScreenLayout(sl,
+                    config.screenWidthDp, config.screenHeightDp);
+        } else {
+            config.orientation = Configuration.ORIENTATION_PORTRAIT;
+            config.screenLayout = Configuration.reduceScreenLayout(sl,
+                    config.screenHeightDp, config.screenWidthDp);
+        }
+        config.smallestScreenWidthDp = config.screenWidthDp; // assume screen does not rotate
+        config.compatScreenWidthDp = config.screenWidthDp;
+        config.compatScreenHeightDp = config.screenHeightDp;
+        config.compatSmallestScreenWidthDp = config.smallestScreenWidthDp;
+    }
+
+    public boolean applyCompatConfiguration(int displayDensity,
+            Configuration compatConfiguration) {
+        if (mResCompatibilityInfo != null && !mResCompatibilityInfo.supportsScreen()) {
+            mResCompatibilityInfo.applyToConfiguration(displayDensity, compatConfiguration);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Creates the top level Resources for applications with the given compatibility info.
+     *
+     * @param resDir the resource directory.
+     * @param compatInfo the compability info. Must not be null.
+     * @param token the application token for determining stack bounds.
+     */
+    public Resources getTopLevelResources(String resDir, int displayId,
+            Configuration overrideConfiguration, CompatibilityInfo compatInfo, IBinder token) {
+        final float scale = compatInfo.applicationScale;
+        ResourcesKey key = new ResourcesKey(resDir, displayId, overrideConfiguration, scale,
+                token);
+        Resources r;
+        synchronized (this) {
+            // Resources is app scale dependent.
+            if (false) {
+                Slog.w(TAG, "getTopLevelResources: " + resDir + " / " + scale);
+            }
+            WeakReference<Resources> wr = mActiveResources.get(key);
+            r = wr != null ? wr.get() : null;
+            //if (r != null) Slog.i(TAG, "isUpToDate " + resDir + ": " + r.getAssets().isUpToDate());
+            if (r != null && r.getAssets().isUpToDate()) {
+                if (false) {
+                    Slog.w(TAG, "Returning cached resources " + r + " " + resDir
+                            + ": appScale=" + r.getCompatibilityInfo().applicationScale);
+                }
+                return r;
+            }
+        }
+
+        //if (r != null) {
+        //    Slog.w(TAG, "Throwing away out-of-date resources!!!! "
+        //            + r + " " + resDir);
+        //}
+
+        AssetManager assets = new AssetManager();
+        if (assets.addAssetPath(resDir) == 0) {
+            return null;
+        }
+
+        //Slog.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
+        DisplayMetrics dm = getDisplayMetricsLocked(displayId);
+        Configuration config;
+        boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
+        final boolean hasOverrideConfig = key.hasOverrideConfiguration();
+        if (!isDefaultDisplay || hasOverrideConfig) {
+            config = new Configuration(getConfiguration());
+            if (!isDefaultDisplay) {
+                applyNonDefaultDisplayMetricsToConfigurationLocked(dm, config);
+            }
+            if (hasOverrideConfig) {
+                config.updateFrom(key.mOverrideConfiguration);
+            }
+        } else {
+            config = getConfiguration();
+        }
+        r = new Resources(assets, dm, config, compatInfo, token);
+        if (false) {
+            Slog.i(TAG, "Created app resources " + resDir + " " + r + ": "
+                    + r.getConfiguration() + " appScale="
+                    + r.getCompatibilityInfo().applicationScale);
+        }
+
+        synchronized (this) {
+            WeakReference<Resources> wr = mActiveResources.get(key);
+            Resources existing = wr != null ? wr.get() : null;
+            if (existing != null && existing.getAssets().isUpToDate()) {
+                // Someone else already created the resources while we were
+                // unlocked; go ahead and use theirs.
+                r.getAssets().close();
+                return existing;
+            }
+
+            // XXX need to remove entries when weak references go away
+            mActiveResources.put(key, new WeakReference<Resources>(r));
+            return r;
+        }
+    }
+
+    public final boolean applyConfigurationToResourcesLocked(Configuration config,
+            CompatibilityInfo compat) {
+        if (mResConfiguration == null) {
+            mResConfiguration = new Configuration();
+        }
+        if (!mResConfiguration.isOtherSeqNewer(config) && compat == null) {
+            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Skipping new config: curSeq="
+                    + mResConfiguration.seq + ", newSeq=" + config.seq);
+            return false;
+        }
+        int changes = mResConfiguration.updateFrom(config);
+        flushDisplayMetricsLocked();
+        DisplayMetrics defaultDisplayMetrics = getDisplayMetricsLocked(Display.DEFAULT_DISPLAY);
+
+        if (compat != null && (mResCompatibilityInfo == null ||
+                !mResCompatibilityInfo.equals(compat))) {
+            mResCompatibilityInfo = compat;
+            changes |= ActivityInfo.CONFIG_SCREEN_LAYOUT
+                    | ActivityInfo.CONFIG_SCREEN_SIZE
+                    | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
+        }
+
+        // set it for java, this also affects newly created Resources
+        if (config.locale != null) {
+            Locale.setDefault(config.locale);
+        }
+
+        Resources.updateSystemConfiguration(config, defaultDisplayMetrics, compat);
+
+        ApplicationPackageManager.configurationChanged();
+        //Slog.i(TAG, "Configuration changed in " + currentPackageName());
+
+        Configuration tmpConfig = null;
+
+        for (int i=mActiveResources.size()-1; i>=0; i--) {
+            ResourcesKey key = mActiveResources.keyAt(i);
+            Resources r = mActiveResources.valueAt(i).get();
+            if (r != null) {
+                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Changing resources "
+                        + r + " config to: " + config);
+                int displayId = key.mDisplayId;
+                boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
+                DisplayMetrics dm = defaultDisplayMetrics;
+                final boolean hasOverrideConfiguration = key.hasOverrideConfiguration();
+                if (!isDefaultDisplay || hasOverrideConfiguration) {
+                    if (tmpConfig == null) {
+                        tmpConfig = new Configuration();
+                    }
+                    tmpConfig.setTo(config);
+                    if (!isDefaultDisplay) {
+                        dm = getDisplayMetricsLocked(displayId);
+                        applyNonDefaultDisplayMetricsToConfigurationLocked(dm, tmpConfig);
+                    }
+                    if (hasOverrideConfiguration) {
+                        tmpConfig.updateFrom(key.mOverrideConfiguration);
+                    }
+                    r.updateConfiguration(tmpConfig, dm, compat);
+                } else {
+                    r.updateConfiguration(config, dm, compat);
+                }
+                //Slog.i(TAG, "Updated app resources " + v.getKey()
+                //        + " " + r + ": " + r.getConfiguration());
+            } else {
+                //Slog.i(TAG, "Removing old resources " + v.getKey());
+                mActiveResources.removeAt(i);
+            }
+        }
+
+        return changes != 0;
+    }
+
+}
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index 7dfc589f..f9c245e 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -869,7 +869,7 @@
             intent.setComponent(comp);
             if (inclContext) {
                 IActivityManager am = ActivityManagerNative.getDefault();
-                Bundle extras = am.getTopActivityExtras(0);
+                Bundle extras = am.getAssistContextExtras(0);
                 if (extras != null) {
                     intent.replaceExtras(extras);
                 }
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index 829b80c..7bcf43e 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -63,6 +63,13 @@
     public static final int NAVIGATION_HINT_RECENT_NOP    = 1 << 2;
     public static final int NAVIGATION_HINT_BACK_ALT      = 1 << 3;
 
+    public static final int WINDOW_STATUS_BAR = 1;
+    public static final int WINDOW_NAVIGATION_BAR = 2;
+
+    public static final int WINDOW_STATE_SHOWING = 0;
+    public static final int WINDOW_STATE_HIDING = 1;
+    public static final int WINDOW_STATE_HIDDEN = 2;
+
     private Context mContext;
     private IStatusBarService mService;
     private IBinder mToken = new Binder();
@@ -179,4 +186,12 @@
             throw new RuntimeException(ex);
         }
     }
+
+    /** @hide */
+    public static String windowStateToString(int state) {
+        if (state == WINDOW_STATE_HIDING) return "WINDOW_STATE_HIDING";
+        if (state == WINDOW_STATE_HIDDEN) return "WINDOW_STATE_HIDDEN";
+        if (state == WINDOW_STATE_SHOWING) return "WINDOW_STATE_SHOWING";
+        return "WINDOW_STATE_UNKNOWN";
+    }
 }
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 3342068..2bc7cbf 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -16,8 +16,11 @@
 
 package android.app;
 
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
@@ -30,7 +33,7 @@
 import android.graphics.Rect;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
-import android.os.Binder;
+import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -41,13 +44,13 @@
 import android.os.ServiceManager;
 import android.util.DisplayMetrics;
 import android.util.Log;
-import android.view.ViewRootImpl;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
 
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.List;
 
 /**
  * Provides access to the system wallpaper. With WallpaperManager, you can
@@ -62,6 +65,15 @@
     private float mWallpaperYStep = -1;
 
     /**
+     * Activity Action: Show settings for choosing wallpaper. Do not use directly to construct
+     * an intent; instead, use {@link #getCropAndSetWallpaperIntent}.
+     * <p>Input:  {@link Intent#getData} is the URI of the image to crop and set as wallpaper.
+     * <p>Output: RESULT_OK if user decided to crop/set the wallpaper, RESULT_CANCEL otherwise
+     */
+    public static final String ACTION_CROP_AND_SET_WALLPAPER =
+            "android.service.wallpaper.CROP_AND_SET_WALLPAPER";
+
+    /**
      * Launch an activity for the user to pick the current global live
      * wallpaper.
      */
@@ -463,7 +475,39 @@
             return null;
         }
     }
-    
+
+    /**
+     * Gets an Intent that will launch an activity that crops the given
+     * image and sets the device's wallpaper. If there is a default HOME activity
+     * that supports cropping wallpapers, it will be preferred as the default.
+     * Use this method instead of directly creating a {@link #ACTION_CROP_AND_SET_WALLPAPER}
+     * intent.
+     */
+    public Intent getCropAndSetWallpaperIntent(Uri imageUri) {
+        final PackageManager packageManager = mContext.getPackageManager();
+        Intent cropAndSetWallpaperIntent =
+                new Intent(ACTION_CROP_AND_SET_WALLPAPER, imageUri);
+        cropAndSetWallpaperIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+
+        // Find out if the default HOME activity supports CROP_AND_SET_WALLPAPER
+        Intent homeIntent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME);
+        ResolveInfo resolvedHome = packageManager.resolveActivity(homeIntent,
+                PackageManager.MATCH_DEFAULT_ONLY);
+        if (resolvedHome != null) {
+            cropAndSetWallpaperIntent.setPackage(resolvedHome.activityInfo.packageName);
+
+            List<ResolveInfo> cropAppList = packageManager.queryIntentActivities(
+                    cropAndSetWallpaperIntent, 0);
+            if (cropAppList.size() > 0) {
+                return cropAndSetWallpaperIntent;
+            }
+        }
+
+        // fallback crop activity
+        cropAndSetWallpaperIntent.setPackage("com.android.wallpapercropper");
+        return cropAndSetWallpaperIntent;
+    }
+
     /**
      * Change the current system wallpaper to the bitmap in the given resource.
      * The resource is opened as a raw data stream and copied into the
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 17e8dd9..ab82531 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -32,10 +32,17 @@
 import android.os.UserHandle;
 import android.util.Log;
 
+import com.android.org.conscrypt.TrustedCertificateStore;
+
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.net.Proxy;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
 import java.util.List;
+import java.util.Set;
 
 /**
  * Public interface for managing policies enforced on a device.  Most clients
@@ -1328,6 +1335,70 @@
     }
 
     /**
+     * Installs the given certificate as a User CA.
+     *
+     * @return false if the certBuffer cannot be parsed or installation is
+     *         interrupted, otherwise true
+     * @hide
+     */
+    public boolean installCaCert(byte[] certBuffer) {
+        if (mService != null) {
+            try {
+                return mService.installCaCert(certBuffer);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Uninstalls the given certificate from the list of User CAs, if present.
+     *
+     * @hide
+     */
+    public void uninstallCaCert(byte[] certBuffer) {
+        if (mService != null) {
+            try {
+                mService.uninstallCaCert(certBuffer);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+    }
+
+    /**
+     * Returns whether there are any user-installed CA certificates.
+     *
+     * @hide
+     */
+    public static boolean hasAnyCaCertsInstalled() {
+        TrustedCertificateStore certStore = new TrustedCertificateStore();
+        Set<String> aliases = certStore.userAliases();
+        return aliases != null && !aliases.isEmpty();
+    }
+
+    /**
+     * Returns whether this certificate has been installed as a User CA.
+     *
+     * @hide
+     */
+    public boolean hasCaCertInstalled(byte[] certBuffer) {
+        TrustedCertificateStore certStore = new TrustedCertificateStore();
+        String alias;
+        byte[] pemCert;
+        try {
+            CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
+            X509Certificate cert = (X509Certificate) certFactory.generateCertificate(
+                            new ByteArrayInputStream(certBuffer));
+            return certStore.getCertificateAlias(cert) != null;
+        } catch (CertificateException ce) {
+            Log.w(TAG, "Could not parse certificate", ce);
+        }
+        return false;
+    }
+
+    /**
      * Called by an application that is administering the device to disable all cameras
      * on the device.  After setting this, no applications will be able to access any cameras
      * on the device.
@@ -1527,9 +1598,26 @@
      */
     public boolean setDeviceOwner(String packageName) throws IllegalArgumentException,
             IllegalStateException {
+        return setDeviceOwner(packageName, null);
+    }
+
+    /**
+     * @hide
+     * Sets the given package as the device owner. The package must already be installed and there
+     * shouldn't be an existing device owner registered, for this call to succeed. Also, this
+     * method must be called before the device is provisioned.
+     * @param packageName the package name of the application to be registered as the device owner.
+     * @param ownerName the human readable name of the institution that owns this device.
+     * @return whether the package was successfully registered as the device owner.
+     * @throws IllegalArgumentException if the package name is null or invalid
+     * @throws IllegalStateException if a device owner is already registered or the device has
+     *         already been provisioned.
+     */
+    public boolean setDeviceOwner(String packageName, String ownerName)
+            throws IllegalArgumentException, IllegalStateException {
         if (mService != null) {
             try {
-                return mService.setDeviceOwner(packageName);
+                return mService.setDeviceOwner(packageName, ownerName);
             } catch (RemoteException re) {
                 Log.w(TAG, "Failed to set device owner");
             }
@@ -1581,4 +1669,16 @@
         }
         return null;
     }
+
+    /** @hide */
+    public String getDeviceOwnerName() {
+        if (mService != null) {
+            try {
+                return mService.getDeviceOwnerName();
+            } catch (RemoteException re) {
+                Log.w(TAG, "Failed to get device owner");
+            }
+        }
+        return null;
+    }
 }
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index b2a65bf..172c47c 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -98,7 +98,11 @@
     void reportFailedPasswordAttempt(int userHandle);
     void reportSuccessfulPasswordAttempt(int userHandle);
 
-    boolean setDeviceOwner(String packageName);
+    boolean setDeviceOwner(String packageName, String ownerName);
     boolean isDeviceOwner(String packageName);
     String getDeviceOwner();
+    String getDeviceOwnerName();
+
+    boolean installCaCert(in byte[] certBuffer);
+    void uninstallCaCert(in byte[] certBuffer);
 }
diff --git a/core/java/android/appwidget/AppWidgetHost.java b/core/java/android/appwidget/AppWidgetHost.java
index 8aae45a..f104d71 100644
--- a/core/java/android/appwidget/AppWidgetHost.java
+++ b/core/java/android/appwidget/AppWidgetHost.java
@@ -198,7 +198,6 @@
      * @return a appWidgetId
      */
     public int allocateAppWidgetId() {
-
         try {
             if (mPackageName == null) {
                 mPackageName = mContext.getPackageName();
@@ -211,20 +210,17 @@
     }
 
     /**
-     * Get a appWidgetId for a host in the calling process.
+     * Get a appWidgetId for a host in the given package.
      *
      * @return a appWidgetId
      * @hide
      */
-    public static int allocateAppWidgetIdForSystem(int hostId, int userId) {
+    public static int allocateAppWidgetIdForPackage(int hostId, int userId, String packageName) {
         checkCallerIsSystem();
         try {
             if (sService == null) {
                 bindService();
             }
-            Context systemContext =
-                    (Context) ActivityThread.currentActivityThread().getSystemContext();
-            String packageName = systemContext.getPackageName();
             return sService.allocateAppWidgetId(packageName, hostId, userId);
         } catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index 6fdf3b4..e7e4a0f 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -128,9 +128,7 @@
                             try {
                                 if (mService == null) {
                                     if (VDBG) Log.d(TAG,"Binding service...");
-                                    if (!mContext.bindService(new Intent(IBluetoothA2dp.class.getName()), mConnection, 0)) {
-                                        Log.e(TAG, "Could not bind to Bluetooth A2DP Service");
-                                    }
+                                    doBind();
                                 }
                             } catch (Exception re) {
                                 Log.e(TAG,"",re);
@@ -157,9 +155,18 @@
             }
         }
 
-        if (!context.bindService(new Intent(IBluetoothA2dp.class.getName()), mConnection, 0)) {
-            Log.e(TAG, "Could not bind to Bluetooth A2DP Service");
+        doBind();
+    }
+
+    boolean doBind() {
+        Intent intent = new Intent(IBluetoothA2dp.class.getName());
+        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+        intent.setComponent(comp);
+        if (comp == null || !mContext.bindService(intent, mConnection, 0)) {
+            Log.e(TAG, "Could not bind to Bluetooth A2DP Service with " + intent);
+            return false;
         }
+        return true;
     }
 
     /*package*/ void close() {
@@ -381,6 +388,66 @@
     }
 
     /**
+     * Checks if Avrcp device supports the absolute volume feature.
+     *
+     * @return true if device supports absolute volume
+     * @hide
+     */
+    public boolean isAvrcpAbsoluteVolumeSupported() {
+        if (DBG) Log.d(TAG, "isAvrcpAbsoluteVolumeSupported");
+        if (mService != null && isEnabled()) {
+            try {
+                return mService.isAvrcpAbsoluteVolumeSupported();
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error talking to BT service in isAvrcpAbsoluteVolumeSupported()", e);
+                return false;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Tells remote device to adjust volume. Only if absolute volume is supported.
+     *
+     * @param direction 1 to increase volume, or -1 to decrease volume
+     * @hide
+     */
+    public void adjustAvrcpAbsoluteVolume(int direction) {
+        if (DBG) Log.d(TAG, "adjustAvrcpAbsoluteVolume");
+        if (mService != null && isEnabled()) {
+            try {
+                mService.adjustAvrcpAbsoluteVolume(direction);
+                return;
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error talking to BT service in adjustAvrcpAbsoluteVolume()", e);
+                return;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+    }
+
+    /**
+     * Tells remote device to set an absolute volume. Only if absolute volume is supported
+     *
+     * @param volume Absolute volume to be set on AVRCP side
+     * @hide
+     */
+    public void setAvrcpAbsoluteVolume(int volume) {
+        if (DBG) Log.d(TAG, "setAvrcpAbsoluteVolume");
+        if (mService != null && isEnabled()) {
+            try {
+                mService.setAvrcpAbsoluteVolume(volume);
+                return;
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error talking to BT service in setAvrcpAbsoluteVolume()", e);
+                return;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+    }
+
+    /**
      * Check if A2DP profile is streaming music.
      *
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 79bb476..2172a7b 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -27,7 +27,6 @@
 import android.os.ServiceManager;
 import android.util.Log;
 import android.util.Pair;
-
 import java.io.IOException;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
@@ -36,6 +35,7 @@
 import java.util.HashSet;
 import java.util.HashMap;
 import java.util.LinkedList;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Random;
 import java.util.Set;
@@ -50,7 +50,7 @@
  * devices, and start a scan for Bluetooth LE devices.
  *
  * <p>To get a {@link BluetoothAdapter} representing the local Bluetooth
- * adapter, when running on JELLY_BEAN_MR1 and below, call the 
+ * adapter, when running on JELLY_BEAN_MR1 and below, call the
  * static {@link #getDefaultAdapter} method; when running on JELLY_BEAN_MR2 and
  * higher, retrieve it through
  * {@link android.content.Context#getSystemService} with
@@ -433,7 +433,7 @@
         if (address == null || address.length != 6) {
             throw new IllegalArgumentException("Bluetooth address must have 6 bytes");
         }
-        return new BluetoothDevice(String.format("%02X:%02X:%02X:%02X:%02X:%02X",
+        return new BluetoothDevice(String.format(Locale.US, "%02X:%02X:%02X:%02X:%02X:%02X",
                 address[0], address[1], address[2], address[3], address[4], address[5]));
     }
 
@@ -599,6 +599,25 @@
     }
 
     /**
+     * enable or disable Bluetooth HCI snoop log.
+     *
+     * <p>Requires the {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+     * permission
+     *
+     * @return true to indicate configure HCI log successfully, or false on
+     *         immediate error
+     * @hide
+     */
+    public boolean configHciSnoopLog(boolean enable) {
+        try {
+            synchronized(mManagerCallback) {
+                if (mService != null) return mService.configHciSnoopLog(enable);
+            }
+        } catch (RemoteException e) {Log.e(TAG, "", e);}
+        return false;
+    }
+
+    /**
      * Get the UUIDs supported by the local Bluetooth adapter.
      *
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
@@ -904,6 +923,42 @@
     }
 
     /**
+     * Create a listening, L2CAP Bluetooth socket.
+     * <p>A remote device connecting to this socket will optionally be
+     * authenticated and communication on this socket will optionally be
+     * encrypted.
+     * <p>Use {@link BluetoothServerSocket#accept} to retrieve incoming
+     * connections from a listening {@link BluetoothServerSocket}.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+     * @param secure whether security and authentication are required
+     * @param fixedChannel whether we're looking for a PSM-based connection or a fixed channel
+     * @param channel L2CAP PSM or channel to use
+     * @return a listening L2CAP BluetoothServerSocket
+     * @throws IOException on error, for example Bluetooth not available, or
+     *                     insufficient permissions, or channel in use.
+     * @hide
+     */
+    public BluetoothServerSocket listenUsingL2CapOn(boolean secure, boolean fixedChannel,
+            int channel) throws IOException {
+        BluetoothServerSocket socket;
+
+        if (fixedChannel) {
+            channel |= BluetoothSocket.PORT_MASK_FIXED_CHAN;
+        }
+
+        socket = new BluetoothServerSocket(
+                BluetoothSocket.TYPE_L2CAP, secure, secure, channel);
+        int errno = socket.mSocket.bindListen();
+        if (errno != 0) {
+            //TODO(BT): Throw the same exception error code
+            // that the previous code was using.
+            //socket.mSocket.throwErrnoNative(errno);
+            throw new IOException("Error: " + errno);
+        }
+        return socket;
+    }
+
+    /**
      * Create a listening, secure RFCOMM Bluetooth socket.
      * <p>A remote device connecting to this socket will be authenticated and
      * communication on this socket will be encrypted.
@@ -1173,6 +1228,9 @@
         } else if (profile == BluetoothProfile.HEALTH) {
             BluetoothHealth health = new BluetoothHealth(context, listener);
             return true;
+        } else if (profile == BluetoothProfile.MAP) {
+            BluetoothMap map = new BluetoothMap(context, listener);
+            return true;
         } else {
             return false;
         }
@@ -1221,6 +1279,10 @@
                 BluetoothGattServer gattServer = (BluetoothGattServer)proxy;
                 gattServer.close();
                 break;
+            case BluetoothProfile.MAP:
+                BluetoothMap map = (BluetoothMap)proxy;
+                map.close();
+                break;
         }
     }
 
@@ -1684,7 +1746,7 @@
         public void onGetDescriptor(String address, int srvcType,
                                     int srvcInstId, ParcelUuid srvcUuid,
                                     int charInstId, ParcelUuid charUuid,
-                                    ParcelUuid descUuid) {
+                                    int descInstId, ParcelUuid descUuid) {
             // no op
         }
 
@@ -1714,14 +1776,14 @@
         public void onDescriptorRead(String address, int status, int srvcType,
                                      int srvcInstId, ParcelUuid srvcUuid,
                                      int charInstId, ParcelUuid charUuid,
-                                     ParcelUuid descrUuid, byte[] value) {
+                                     int descInstId, ParcelUuid descrUuid, byte[] value) {
             // no op
         }
 
         public void onDescriptorWrite(String address, int status, int srvcType,
                                       int srvcInstId, ParcelUuid srvcUuid,
                                       int charInstId, ParcelUuid charUuid,
-                                      ParcelUuid descrUuid) {
+                                      int descInstId, ParcelUuid descrUuid) {
             // no op
         }
 
@@ -1732,6 +1794,10 @@
         public void onReadRemoteRssi(String address, int rssi, int status) {
             // no op
         }
+
+        public void onListen(int status) {
+            // no op
+        }
     }
 
 }
diff --git a/core/java/android/bluetooth/BluetoothAssignedNumbers.java b/core/java/android/bluetooth/BluetoothAssignedNumbers.java
index 580e9ff..124bdc1 100644
--- a/core/java/android/bluetooth/BluetoothAssignedNumbers.java
+++ b/core/java/android/bluetooth/BluetoothAssignedNumbers.java
@@ -513,6 +513,656 @@
     public static final int RIVIERAWAVES = 0x0060;
 
     /*
+     * RDA Microelectronics.
+     */
+    public static final int RDA_MICROELECTRONICS = 0x0061;
+
+    /*
+     * Gibson Guitars.
+     */
+    public static final int GIBSON_GUITARS = 0x0062;
+
+    /*
+     * MiCommand Inc.
+     */
+    public static final int MICOMMAND = 0x0063;
+
+    /*
+     * Band XI International, LLC.
+     */
+    public static final int BAND_XI_INTERNATIONAL = 0x0064;
+
+    /*
+     * Hewlett-Packard Company.
+     */
+    public static final int HEWLETT_PACKARD = 0x0065;
+
+    /*
+     * 9Solutions Oy.
+     */
+    public static final int NINE_SOLUTIONS = 0x0066;
+
+    /*
+     * GN Netcom A/S.
+     */
+    public static final int GN_NETCOM = 0x0067;
+
+    /*
+     * General Motors.
+     */
+    public static final int GENERAL_MOTORS = 0x0068;
+
+    /*
+     * A&D Engineering, Inc.
+     */
+    public static final int A_AND_D_ENGINEERING = 0x0069;
+
+    /*
+     * MindTree Ltd.
+     */
+    public static final int MINDTREE = 0x006A;
+
+    /*
+     * Polar Electro OY.
+     */
+    public static final int POLAR_ELECTRO = 0x006B;
+
+    /*
+     * Beautiful Enterprise Co., Ltd.
+     */
+    public static final int BEAUTIFUL_ENTERPRISE = 0x006C;
+
+    /*
+     * BriarTek, Inc.
+     */
+    public static final int BRIARTEK = 0x006D;
+
+    /*
+     * Summit Data Communications, Inc.
+     */
+    public static final int SUMMIT_DATA_COMMUNICATIONS = 0x006E;
+
+    /*
+     * Sound ID.
+     */
+    public static final int SOUND_ID = 0x006F;
+
+    /*
+     * Monster, LLC.
+     */
+    public static final int MONSTER = 0x0070;
+
+    /*
+     * connectBlue AB.
+     */
+    public static final int CONNECTBLUE = 0x0071;
+
+    /*
+     * ShangHai Super Smart Electronics Co. Ltd.
+     */
+    public static final int SHANGHAI_SUPER_SMART_ELECTRONICS = 0x0072;
+
+    /*
+     * Group Sense Ltd.
+     */
+    public static final int GROUP_SENSE = 0x0073;
+
+    /*
+     * Zomm, LLC.
+     */
+    public static final int ZOMM = 0x0074;
+
+    /*
+     * Samsung Electronics Co. Ltd.
+     */
+    public static final int SAMSUNG_ELECTRONICS = 0x0075;
+
+    /*
+     * Creative Technology Ltd.
+     */
+    public static final int CREATIVE_TECHNOLOGY = 0x0076;
+
+    /*
+     * Laird Technologies.
+     */
+    public static final int LAIRD_TECHNOLOGIES = 0x0077;
+
+    /*
+     * Nike, Inc.
+     */
+    public static final int NIKE = 0x0078;
+
+    /*
+     * lesswire AG.
+     */
+    public static final int LESSWIRE = 0x0079;
+
+    /*
+     * MStar Semiconductor, Inc.
+     */
+    public static final int MSTAR_SEMICONDUCTOR = 0x007A;
+
+    /*
+     * Hanlynn Technologies.
+     */
+    public static final int HANLYNN_TECHNOLOGIES = 0x007B;
+
+    /*
+     * A & R Cambridge.
+     */
+    public static final int A_AND_R_CAMBRIDGE = 0x007C;
+
+    /*
+     * Seers Technology Co. Ltd.
+     */
+    public static final int SEERS_TECHNOLOGY = 0x007D;
+
+    /*
+     * Sports Tracking Technologies Ltd.
+     */
+    public static final int SPORTS_TRACKING_TECHNOLOGIES = 0x007E;
+
+    /*
+     * Autonet Mobile.
+     */
+    public static final int AUTONET_MOBILE = 0x007F;
+
+    /*
+     * DeLorme Publishing Company, Inc.
+     */
+    public static final int DELORME_PUBLISHING_COMPANY = 0x0080;
+
+    /*
+     * WuXi Vimicro.
+     */
+    public static final int WUXI_VIMICRO = 0x0081;
+
+    /*
+     * Sennheiser Communications A/S.
+     */
+    public static final int SENNHEISER_COMMUNICATIONS = 0x0082;
+
+    /*
+     * TimeKeeping Systems, Inc.
+     */
+    public static final int TIMEKEEPING_SYSTEMS = 0x0083;
+
+    /*
+     * Ludus Helsinki Ltd.
+     */
+    public static final int LUDUS_HELSINKI = 0x0084;
+
+    /*
+     * BlueRadios, Inc.
+     */
+    public static final int BLUERADIOS = 0x0085;
+
+    /*
+     * equinox AG.
+     */
+    public static final int EQUINOX_AG = 0x0086;
+
+    /*
+     * Garmin International, Inc.
+     */
+    public static final int GARMIN_INTERNATIONAL = 0x0087;
+
+    /*
+     * Ecotest.
+     */
+    public static final int ECOTEST = 0x0088;
+
+    /*
+     * GN ReSound A/S.
+     */
+    public static final int GN_RESOUND = 0x0089;
+
+    /*
+     * Jawbone.
+     */
+    public static final int JAWBONE = 0x008A;
+
+    /*
+     * Topcorn Positioning Systems, LLC.
+     */
+    public static final int TOPCORN_POSITIONING_SYSTEMS = 0x008B;
+
+    /*
+     * Qualcomm Labs, Inc.
+     */
+    public static final int QUALCOMM_LABS = 0x008C;
+
+    /*
+     * Zscan Software.
+     */
+    public static final int ZSCAN_SOFTWARE = 0x008D;
+
+    /*
+     * Quintic Corp.
+     */
+    public static final int QUINTIC = 0x008E;
+
+    /*
+     * Stollman E+V GmbH.
+     */
+    public static final int STOLLMAN_E_PLUS_V = 0x008F;
+
+    /*
+     * Funai Electric Co., Ltd.
+     */
+    public static final int FUNAI_ELECTRIC = 0x0090;
+
+    /*
+     * Advanced PANMOBIL Systems GmbH & Co. KG.
+     */
+    public static final int ADVANCED_PANMOBIL_SYSTEMS = 0x0091;
+
+    /*
+     * ThinkOptics, Inc.
+     */
+    public static final int THINKOPTICS = 0x0092;
+
+    /*
+     * Universal Electronics, Inc.
+     */
+    public static final int UNIVERSAL_ELECTRONICS = 0x0093;
+
+    /*
+     * Airoha Technology Corp.
+     */
+    public static final int AIROHA_TECHNOLOGY = 0x0094;
+
+    /*
+     * NEC Lighting, Ltd.
+     */
+    public static final int NEC_LIGHTING = 0x0095;
+
+    /*
+     * ODM Technology, Inc.
+     */
+    public static final int ODM_TECHNOLOGY = 0x0096;
+
+    /*
+     * Bluetrek Technologies Limited.
+     */
+    public static final int BLUETREK_TECHNOLOGIES = 0x0097;
+
+    /*
+     * zer01.tv GmbH.
+     */
+    public static final int ZER01_TV = 0x0098;
+
+    /*
+     * i.Tech Dynamic Global Distribution Ltd.
+     */
+    public static final int I_TECH_DYNAMIC_GLOBAL_DISTRIBUTION = 0x0099;
+
+    /*
+     * Alpwise.
+     */
+    public static final int ALPWISE = 0x009A;
+
+    /*
+     * Jiangsu Toppower Automotive Electronics Co., Ltd.
+     */
+    public static final int JIANGSU_TOPPOWER_AUTOMOTIVE_ELECTRONICS = 0x009B;
+
+    /*
+     * Colorfy, Inc.
+     */
+    public static final int COLORFY = 0x009C;
+
+    /*
+     * Geoforce Inc.
+     */
+    public static final int GEOFORCE = 0x009D;
+
+    /*
+     * Bose Corporation.
+     */
+    public static final int BOSE = 0x009E;
+
+    /*
+     * Suunto Oy.
+     */
+    public static final int SUUNTO = 0x009F;
+
+    /*
+     * Kensington Computer Products Group.
+     */
+    public static final int KENSINGTON_COMPUTER_PRODUCTS_GROUP = 0x00A0;
+
+    /*
+     * SR-Medizinelektronik.
+     */
+    public static final int SR_MEDIZINELEKTRONIK = 0x00A1;
+
+    /*
+     * Vertu Corporation Limited.
+     */
+    public static final int VERTU = 0x00A2;
+
+    /*
+     * Meta Watch Ltd.
+     */
+    public static final int META_WATCH = 0x00A3;
+
+    /*
+     * LINAK A/S.
+     */
+    public static final int LINAK = 0x00A4;
+
+    /*
+     * OTL Dynamics LLC.
+     */
+    public static final int OTL_DYNAMICS = 0x00A5;
+
+    /*
+     * Panda Ocean Inc.
+     */
+    public static final int PANDA_OCEAN = 0x00A6;
+
+    /*
+     * Visteon Corporation.
+     */
+    public static final int VISTEON = 0x00A7;
+
+    /*
+     * ARP Devices Limited.
+     */
+    public static final int ARP_DEVICES = 0x00A8;
+
+    /*
+     * Magneti Marelli S.p.A.
+     */
+    public static final int MAGNETI_MARELLI = 0x00A9;
+
+    /*
+     * CAEN RFID srl.
+     */
+    public static final int CAEN_RFID = 0x00AA;
+
+    /*
+     * Ingenieur-Systemgruppe Zahn GmbH.
+     */
+    public static final int INGENIEUR_SYSTEMGRUPPE_ZAHN = 0x00AB;
+
+    /*
+     * Green Throttle Games.
+     */
+    public static final int GREEN_THROTTLE_GAMES = 0x00AC;
+
+    /*
+     * Peter Systemtechnik GmbH.
+     */
+    public static final int PETER_SYSTEMTECHNIK = 0x00AD;
+
+    /*
+     * Omegawave Oy.
+     */
+    public static final int OMEGAWAVE = 0x00AE;
+
+    /*
+     * Cinetix.
+     */
+    public static final int CINETIX = 0x00AF;
+
+    /*
+     * Passif Semiconductor Corp.
+     */
+    public static final int PASSIF_SEMICONDUCTOR = 0x00B0;
+
+    /*
+     * Saris Cycling Group, Inc.
+     */
+    public static final int SARIS_CYCLING_GROUP = 0x00B1;
+
+    /*
+     * Bekey A/S.
+     */
+    public static final int BEKEY = 0x00B2;
+
+    /*
+     * Clarinox Technologies Pty. Ltd.
+     */
+    public static final int CLARINOX_TECHNOLOGIES = 0x00B3;
+
+    /*
+     * BDE Technology Co., Ltd.
+     */
+    public static final int BDE_TECHNOLOGY = 0x00B4;
+
+    /*
+     * Swirl Networks.
+     */
+    public static final int SWIRL_NETWORKS = 0x00B5;
+
+    /*
+     * Meso international.
+     */
+    public static final int MESO_INTERNATIONAL = 0x00B6;
+
+    /*
+     * TreLab Ltd.
+     */
+    public static final int TRELAB = 0x00B7;
+
+    /*
+     * Qualcomm Innovation Center, Inc. (QuIC).
+     */
+    public static final int QUALCOMM_INNOVATION_CENTER = 0x00B8;
+
+    /*
+     * Johnson Controls, Inc.
+     */
+    public static final int JOHNSON_CONTROLS = 0x00B9;
+
+    /*
+     * Starkey Laboratories Inc.
+     */
+    public static final int STARKEY_LABORATORIES = 0x00BA;
+
+    /*
+     * S-Power Electronics Limited.
+     */
+    public static final int S_POWER_ELECTRONICS = 0x00BB;
+
+    /*
+     * Ace Sensor Inc.
+     */
+    public static final int ACE_SENSOR = 0x00BC;
+
+    /*
+     * Aplix Corporation.
+     */
+    public static final int APLIX = 0x00BD;
+
+    /*
+     * AAMP of America.
+     */
+    public static final int AAMP_OF_AMERICA = 0x00BE;
+
+    /*
+     * Stalmart Technology Limited.
+     */
+    public static final int STALMART_TECHNOLOGY = 0x00BF;
+
+    /*
+     * AMICCOM Electronics Corporation.
+     */
+    public static final int AMICCOM_ELECTRONICS = 0x00C0;
+
+    /*
+     * Shenzhen Excelsecu Data Technology Co.,Ltd.
+     */
+    public static final int SHENZHEN_EXCELSECU_DATA_TECHNOLOGY = 0x00C1;
+
+    /*
+     * Geneq Inc.
+     */
+    public static final int GENEQ = 0x00C2;
+
+    /*
+     * adidas AG.
+     */
+    public static final int ADIDAS = 0x00C3;
+
+    /*
+     * LG Electronics.
+     */
+    public static final int LG_ELECTRONICS = 0x00C4;
+
+    /*
+     * Onset Computer Corporation.
+     */
+    public static final int ONSET_COMPUTER = 0x00C5;
+
+    /*
+     * Selfly BV.
+     */
+    public static final int SELFLY = 0x00C6;
+
+    /*
+     * Quuppa Oy.
+     */
+    public static final int QUUPPA = 0x00C7;
+
+    /*
+     * GeLo Inc.
+     */
+    public static final int GELO = 0x00C8;
+
+    /*
+     * Evluma.
+     */
+    public static final int EVLUMA = 0x00C9;
+
+    /*
+     * MC10.
+     */
+    public static final int MC10 = 0x00CA;
+
+    /*
+     * Binauric SE.
+     */
+    public static final int BINAURIC = 0x00CB;
+
+    /*
+     * Beats Electronics.
+     */
+    public static final int BEATS_ELECTRONICS = 0x00CC;
+
+    /*
+     * Microchip Technology Inc.
+     */
+    public static final int MICROCHIP_TECHNOLOGY = 0x00CD;
+
+    /*
+     * Elgato Systems GmbH.
+     */
+    public static final int ELGATO_SYSTEMS = 0x00CE;
+
+    /*
+     * ARCHOS SA.
+     */
+    public static final int ARCHOS = 0x00CF;
+
+    /*
+     * Dexcom, Inc.
+     */
+    public static final int DEXCOM = 0x00D0;
+
+    /*
+     * Polar Electro Europe B.V.
+     */
+    public static final int POLAR_ELECTRO_EUROPE = 0x00D1;
+
+    /*
+     * Dialog Semiconductor B.V.
+     */
+    public static final int DIALOG_SEMICONDUCTOR = 0x00D2;
+
+    /*
+     * Taixingbang Technology (HK) Co,. LTD.
+     */
+    public static final int TAIXINGBANG_TECHNOLOGY = 0x00D3;
+
+    /*
+     * Kawantech.
+     */
+    public static final int KAWANTECH = 0x00D4;
+
+    /*
+     * Austco Communication Systems.
+     */
+    public static final int AUSTCO_COMMUNICATION_SYSTEMS = 0x00D5;
+
+    /*
+     * Timex Group USA, Inc.
+     */
+    public static final int TIMEX_GROUP_USA = 0x00D6;
+
+    /*
+     * Qualcomm Technologies, Inc.
+     */
+    public static final int QUALCOMM_TECHNOLOGIES = 0x00D7;
+
+    /*
+     * Qualcomm Connected Experiences, Inc.
+     */
+    public static final int QUALCOMM_CONNECTED_EXPERIENCES = 0x00D8;
+
+    /*
+     * Voyetra Turtle Beach.
+     */
+    public static final int VOYETRA_TURTLE_BEACH = 0x00D9;
+
+    /*
+     * txtr GmbH.
+     */
+    public static final int TXTR = 0x00DA;
+
+    /*
+     * Biosentronics.
+     */
+    public static final int BIOSENTRONICS = 0x00DB;
+
+    /*
+     * Procter & Gamble.
+     */
+    public static final int PROCTER_AND_GAMBLE = 0x00DC;
+
+    /*
+     * Hosiden Corporation.
+     */
+    public static final int HOSIDEN = 0x00DD;
+
+    /*
+     * Muzik LLC.
+     */
+    public static final int MUZIK = 0x00DE;
+
+    /*
+     * Misfit Wearables Corp.
+     */
+    public static final int MISFIT_WEARABLES = 0x00DF;
+
+    /*
+     * Google.
+     */
+    public static final int GOOGLE = 0x00E0;
+
+    /*
+     * Danlers Ltd.
+     */
+    public static final int DANLERS = 0x00E1;
+
+    /*
+     * Semilink Inc.
+     */
+    public static final int SEMILINK = 0x00E2;
+
+    /*
      * You can't instantiate one of these.
      */
     private BluetoothAssignedNumbers() {
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 3ee7142..2c85382 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -343,6 +343,9 @@
     /**@hide*/
     public static final int REQUEST_TYPE_PHONEBOOK_ACCESS = 2;
 
+    /**@hide*/
+    public static final int REQUEST_TYPE_MESSAGE_ACCESS = 3;
+
     /**
      * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REQUEST} intents,
      * Contains package name to return reply intent to.
@@ -1141,6 +1144,33 @@
         return new BluetoothSocket(BluetoothSocket.TYPE_SCO, -1, true, true, this, -1, null);
     }
 
+
+    /**
+     * Construct a L2CAP socket ready to start an outgoing connection.
+     * Call #connect on the returned #BluetoothSocket to begin the connection.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+     *
+     * @param secure    select whether security will be required
+     * @param fixedChannel    select if this will be a "fixed channel" L2CAP connection
+     *                        or a PSM-based connection
+     * @param channel    fixed channel or PSM to connect to
+     * @return a L2CAP BluetoothSocket
+     * @throws IOException on error, for example Bluetooth not available, or
+     *                     insufficient permissions.
+     * @hide
+     */
+    public BluetoothSocket createL2CapSocket(boolean secure, boolean fixedChannel, int channel)
+            throws IOException {
+
+        if (fixedChannel) {
+            channel |= BluetoothSocket.PORT_MASK_FIXED_CHAN;
+        }
+
+        return new BluetoothSocket(BluetoothSocket.TYPE_L2CAP, -1, secure, secure, this,
+                channel, null);
+    }
+
+
     /**
      * Check that a pin is valid and convert to byte array.
      *
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index 0752df8..a2bb78c 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -167,7 +167,7 @@
                 try {
                     mCallback.onConnectionStateChange(BluetoothGatt.this, status, profileState);
                 } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception: " + ex);
+                    Log.w(TAG, "Unhandled exception in callback", ex);
                 }
 
                 synchronized(mStateLock) {
@@ -261,7 +261,7 @@
             public void onGetDescriptor(String address, int srvcType,
                              int srvcInstId, ParcelUuid srvcUuid,
                              int charInstId, ParcelUuid charUuid,
-                             ParcelUuid descUuid) {
+                             int descrInstId, ParcelUuid descUuid) {
                 if (DBG) Log.d(TAG, "onGetDescriptor() - Device=" + address + " UUID=" + descUuid);
 
                 if (!address.equals(mDevice.getAddress())) {
@@ -276,7 +276,7 @@
                 if (characteristic == null) return;
 
                 characteristic.addDescriptor(new BluetoothGattDescriptor(
-                    characteristic, descUuid.getUuid(), 0));
+                    characteristic, descUuid.getUuid(), descrInstId, 0));
             }
 
             /**
@@ -294,7 +294,7 @@
                 try {
                     mCallback.onServicesDiscovered(BluetoothGatt.this, status);
                 } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception: " + ex);
+                    Log.w(TAG, "Unhandled exception in callback", ex);
                 }
             }
 
@@ -341,7 +341,7 @@
                 try {
                     mCallback.onCharacteristicRead(BluetoothGatt.this, characteristic, status);
                 } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception: " + ex);
+                    Log.w(TAG, "Unhandled exception in callback", ex);
                 }
             }
 
@@ -387,7 +387,7 @@
                 try {
                     mCallback.onCharacteristicWrite(BluetoothGatt.this, characteristic, status);
                 } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception: " + ex);
+                    Log.w(TAG, "Unhandled exception in callback", ex);
                 }
             }
 
@@ -418,7 +418,7 @@
                 try {
                     mCallback.onCharacteristicChanged(BluetoothGatt.this, characteristic);
                 } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception: " + ex);
+                    Log.w(TAG, "Unhandled exception in callback", ex);
                 }
             }
 
@@ -429,7 +429,8 @@
             public void onDescriptorRead(String address, int status, int srvcType,
                              int srvcInstId, ParcelUuid srvcUuid,
                              int charInstId, ParcelUuid charUuid,
-                             ParcelUuid descrUuid, byte[] value) {
+                             int descrInstId, ParcelUuid descrUuid,
+                             byte[] value) {
                 if (DBG) Log.d(TAG, "onDescriptorRead() - Device=" + address + " UUID=" + charUuid);
 
                 if (!address.equals(mDevice.getAddress())) {
@@ -444,7 +445,7 @@
                 if (characteristic == null) return;
 
                 BluetoothGattDescriptor descriptor = characteristic.getDescriptor(
-                        descrUuid.getUuid());
+                        descrUuid.getUuid(), descrInstId);
                 if (descriptor == null) return;
 
                 if (status == 0) descriptor.setValue(value);
@@ -456,7 +457,7 @@
                         mAuthRetry = true;
                         mService.readDescriptor(mClientIf, address,
                             srvcType, srvcInstId, srvcUuid, charInstId, charUuid,
-                            descrUuid, AUTHENTICATION_MITM);
+                            descrInstId, descrUuid, AUTHENTICATION_MITM);
                     } catch (RemoteException e) {
                         Log.e(TAG,"",e);
                     }
@@ -467,7 +468,7 @@
                 try {
                     mCallback.onDescriptorRead(BluetoothGatt.this, descriptor, status);
                 } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception: " + ex);
+                    Log.w(TAG, "Unhandled exception in callback", ex);
                 }
             }
 
@@ -478,7 +479,7 @@
             public void onDescriptorWrite(String address, int status, int srvcType,
                              int srvcInstId, ParcelUuid srvcUuid,
                              int charInstId, ParcelUuid charUuid,
-                             ParcelUuid descrUuid) {
+                             int descrInstId, ParcelUuid descrUuid) {
                 if (DBG) Log.d(TAG, "onDescriptorWrite() - Device=" + address + " UUID=" + charUuid);
 
                 if (!address.equals(mDevice.getAddress())) {
@@ -493,7 +494,7 @@
                 if (characteristic == null) return;
 
                 BluetoothGattDescriptor descriptor = characteristic.getDescriptor(
-                        descrUuid.getUuid());
+                        descrUuid.getUuid(), descrInstId);
                 if (descriptor == null) return;
 
                 if ((status == GATT_INSUFFICIENT_AUTHENTICATION
@@ -503,7 +504,7 @@
                         mAuthRetry = true;
                         mService.writeDescriptor(mClientIf, address,
                             srvcType, srvcInstId, srvcUuid, charInstId, charUuid,
-                            descrUuid, characteristic.getWriteType(),
+                            descrInstId, descrUuid, characteristic.getWriteType(),
                             AUTHENTICATION_MITM, descriptor.getValue());
                     } catch (RemoteException e) {
                         Log.e(TAG,"",e);
@@ -515,7 +516,7 @@
                 try {
                     mCallback.onDescriptorWrite(BluetoothGatt.this, descriptor, status);
                 } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception: " + ex);
+                    Log.w(TAG, "Unhandled exception in callback", ex);
                 }
             }
 
@@ -532,7 +533,7 @@
                 try {
                     mCallback.onReliableWriteCompleted(BluetoothGatt.this, status);
                 } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception: " + ex);
+                    Log.w(TAG, "Unhandled exception in callback", ex);
                 }
             }
 
@@ -549,9 +550,17 @@
                 try {
                     mCallback.onReadRemoteRssi(BluetoothGatt.this, rssi, status);
                 } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception: " + ex);
+                    Log.w(TAG, "Unhandled exception in callback", ex);
                 }
             }
+
+            /**
+             * Listen command status callback
+             * @hide
+             */
+            public void onListen(int status) {
+                if (DBG) Log.d(TAG, "onListen() - status=" + status);
+            }
         };
 
     /*package*/ BluetoothGatt(Context context, IBluetoothGatt iGatt, BluetoothDevice device) {
@@ -684,6 +693,71 @@
         return true;
     }
 
+   /**
+     * Starts or stops sending of advertisement packages to listen for connection
+     * requests from a central devices.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
+     *
+     * @param start Start or stop advertising
+     */
+    /*package*/ void listen(boolean start) {
+        if (mContext == null || !mContext.getResources().
+            getBoolean(com.android.internal.R.bool.config_bluetooth_le_peripheral_mode_supported)) {
+            throw new UnsupportedOperationException("BluetoothGatt#listen is blocked");
+        }
+        if (DBG) Log.d(TAG, "listen() - start: " + start);
+        if (mService == null || mClientIf == 0) return;
+
+        try {
+            mService.clientListen(mClientIf, start);
+        } catch (RemoteException e) {
+            Log.e(TAG,"",e);
+        }
+    }
+
+    /**
+     * Sets the advertising data contained in the adv. response packet.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
+     *
+     * @param advData true to set adv. data, false to set scan response
+     * @param includeName Inlucde the name in the adv. response
+     * @param includeTxPower Include TX power value
+     * @param minInterval Minimum desired scan interval (optional)
+     * @param maxInterval Maximum desired scan interval (optional)
+     * @param appearance The appearance flags for the device (optional)
+     * @param manufacturerData Manufacturer specific data including company ID (optional)
+     */
+    /*package*/ void setAdvData(boolean advData, boolean includeName, boolean includeTxPower,
+                           Integer minInterval, Integer maxInterval,
+                           Integer appearance, Byte[] manufacturerData) {
+        if (mContext == null || !mContext.getResources().
+            getBoolean(com.android.internal.R.bool.config_bluetooth_le_peripheral_mode_supported)) {
+            throw new UnsupportedOperationException("BluetoothGatt#setAdvData is blocked");
+        }
+        if (DBG) Log.d(TAG, "setAdvData()");
+        if (mService == null || mClientIf == 0) return;
+
+        byte[] data = new byte[0];
+        if (manufacturerData != null) {
+            data = new byte[manufacturerData.length];
+            for(int i = 0; i != manufacturerData.length; ++i) {
+                data[i] = manufacturerData[i];
+            }
+        }
+
+        try {
+            mService.setAdvData(mClientIf, !advData,
+                includeName, includeTxPower,
+                minInterval != null ? minInterval : 0,
+                maxInterval != null ? maxInterval : 0,
+                appearance != null ? appearance : 0, data);
+        } catch (RemoteException e) {
+            Log.e(TAG,"",e);
+        }
+    }
+
     /**
      * Disconnects an established connection, or cancels a connection attempt
      * currently in progress.
@@ -915,11 +989,11 @@
         if (device == null) return false;
 
         try {
-            mService.readDescriptor(mClientIf, device.getAddress(),
-                service.getType(), service.getInstanceId(),
-                new ParcelUuid(service.getUuid()), characteristic.getInstanceId(),
-                new ParcelUuid(characteristic.getUuid()),
-                new ParcelUuid(descriptor.getUuid()), AUTHENTICATION_NONE);
+            mService.readDescriptor(mClientIf, device.getAddress(), service.getType(),
+                service.getInstanceId(), new ParcelUuid(service.getUuid()),
+                characteristic.getInstanceId(), new ParcelUuid(characteristic.getUuid()),
+                descriptor.getInstanceId(), new ParcelUuid(descriptor.getUuid()),
+                AUTHENTICATION_NONE);
         } catch (RemoteException e) {
             Log.e(TAG,"",e);
             return false;
@@ -953,11 +1027,10 @@
         if (device == null) return false;
 
         try {
-            mService.writeDescriptor(mClientIf, device.getAddress(),
-                service.getType(), service.getInstanceId(),
-                new ParcelUuid(service.getUuid()), characteristic.getInstanceId(),
-                new ParcelUuid(characteristic.getUuid()),
-                new ParcelUuid(descriptor.getUuid()),
+            mService.writeDescriptor(mClientIf, device.getAddress(), service.getType(),
+                service.getInstanceId(), new ParcelUuid(service.getUuid()),
+                characteristic.getInstanceId(), new ParcelUuid(characteristic.getUuid()),
+                descriptor.getInstanceId(), new ParcelUuid(descriptor.getUuid()),
                 characteristic.getWriteType(), AUTHENTICATION_NONE,
                 descriptor.getValue());
         } catch (RemoteException e) {
@@ -1037,7 +1110,7 @@
      *
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
      */
-    public void abortReliableWrite(BluetoothDevice mDevice) {
+    public void abortReliableWrite() {
         if (DBG) Log.d(TAG, "abortReliableWrite() - device: " + mDevice.getAddress());
         if (mService == null || mClientIf == 0) return;
 
@@ -1049,6 +1122,13 @@
     }
 
     /**
+     * @deprecated Use {@link #abortReliableWrite()}
+     */
+    public void abortReliableWrite(BluetoothDevice mDevice) {
+        abortReliableWrite();
+    }
+
+    /**
      * Enable or disable notifications/indications for a given characteristic.
      *
      * <p>Once notifications are enabled for a characteristic, a
diff --git a/core/java/android/bluetooth/BluetoothGattCharacteristic.java b/core/java/android/bluetooth/BluetoothGattCharacteristic.java
index 033f079..f0ecbb4 100644
--- a/core/java/android/bluetooth/BluetoothGattCharacteristic.java
+++ b/core/java/android/bluetooth/BluetoothGattCharacteristic.java
@@ -283,6 +283,20 @@
     }
 
     /**
+     * Get a descriptor by UUID and isntance id.
+     * @hide
+     */
+    /*package*/  BluetoothGattDescriptor getDescriptor(UUID uuid, int instanceId) {
+        for(BluetoothGattDescriptor descriptor : mDescriptors) {
+            if (descriptor.getUuid().equals(uuid)
+             && descriptor.getInstanceId() == instanceId) {
+                return descriptor;
+            }
+        }
+        return null;
+    }
+
+    /**
      * Returns the service this characteristic belongs to.
      * @return The asscociated service
      */
diff --git a/core/java/android/bluetooth/BluetoothGattDescriptor.java b/core/java/android/bluetooth/BluetoothGattDescriptor.java
index 1cd6878..5f525dc 100644
--- a/core/java/android/bluetooth/BluetoothGattDescriptor.java
+++ b/core/java/android/bluetooth/BluetoothGattDescriptor.java
@@ -91,6 +91,12 @@
     protected UUID mUuid;
 
     /**
+     * Instance ID for this descriptor.
+     * @hide
+     */
+    protected int mInstance;
+
+    /**
      * Permissions for this descriptor
      * @hide
      */
@@ -116,7 +122,7 @@
      * @param permissions Permissions for this descriptor
      */
     public BluetoothGattDescriptor(UUID uuid, int permissions) {
-        initDescriptor(null, uuid, permissions);
+        initDescriptor(null, uuid, 0, permissions);
     }
 
     /**
@@ -128,14 +134,15 @@
      * @param permissions Permissions for this descriptor
      */
     /*package*/ BluetoothGattDescriptor(BluetoothGattCharacteristic characteristic, UUID uuid,
-                                    int permissions) {
-        initDescriptor(characteristic, uuid, permissions);
+                                    int instance, int permissions) {
+        initDescriptor(characteristic, uuid, instance, permissions);
     }
 
     private void initDescriptor(BluetoothGattCharacteristic characteristic, UUID uuid,
-                                int permissions) {
+                                int instance, int permissions) {
         mCharacteristic = characteristic;
         mUuid = uuid;
+        mInstance = instance;
         mPermissions = permissions;
     }
 
@@ -165,6 +172,21 @@
     }
 
     /**
+     * Returns the instance ID for this descriptor.
+     *
+     * <p>If a remote device offers multiple descriptors with the same UUID,
+     * the instance ID is used to distuinguish between descriptors.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
+     *
+     * @return Instance ID of this descriptor
+     * @hide
+     */
+    public int getInstanceId() {
+        return mInstance;
+    }
+
+    /**
      * Returns the permissions for this descriptor.
      *
      * @return Permissions of this descriptor
diff --git a/core/java/android/bluetooth/BluetoothGattServer.java b/core/java/android/bluetooth/BluetoothGattServer.java
index 78d536b..58ee54f 100644
--- a/core/java/android/bluetooth/BluetoothGattServer.java
+++ b/core/java/android/bluetooth/BluetoothGattServer.java
@@ -108,7 +108,7 @@
                                                       connected ? BluetoothProfile.STATE_CONNECTED :
                                                       BluetoothProfile.STATE_DISCONNECTED);
                 } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception: " + ex);
+                    Log.w(TAG, "Unhandled exception in callback", ex);
                 }
             }
 
@@ -128,7 +128,7 @@
                 try {
                     mCallback.onServiceAdded((int)status, service);
                 } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception: " + ex);
+                    Log.w(TAG, "Unhandled exception in callback", ex);
                 }
             }
 
@@ -154,7 +154,7 @@
                 try {
                     mCallback.onCharacteristicReadRequest(device, transId, offset, characteristic);
                 } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception: " + ex);
+                    Log.w(TAG, "Unhandled exception in callback", ex);
                 }
             }
 
@@ -186,7 +186,7 @@
                 try {
                     mCallback.onDescriptorReadRequest(device, transId, offset, descriptor);
                 } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception: " + ex);
+                    Log.w(TAG, "Unhandled exception in callback", ex);
                 }
             }
 
@@ -214,7 +214,7 @@
                     mCallback.onCharacteristicWriteRequest(device, transId, characteristic,
                                                            isPrep, needRsp, offset, value);
                 } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception: " + ex);
+                    Log.w(TAG, "Unhandled exception in callback", ex);
                 }
 
             }
@@ -250,7 +250,7 @@
                     mCallback.onDescriptorWriteRequest(device, transId, descriptor,
                                                        isPrep, needRsp, offset, value);
                 } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception: " + ex);
+                    Log.w(TAG, "Unhandled exception in callback", ex);
                 }
             }
 
@@ -270,7 +270,7 @@
                 try {
                     mCallback.onExecuteWrite(device, transId, execWrite);
                 } catch (Exception ex) {
-                    Log.w(TAG, "Unhandled exception: " + ex);
+                    Log.w(TAG, "Unhandled exception in callback", ex);
                 }
             }
         };
diff --git a/core/java/android/bluetooth/BluetoothGattService.java b/core/java/android/bluetooth/BluetoothGattService.java
index 39a435b..1e66369 100644
--- a/core/java/android/bluetooth/BluetoothGattService.java
+++ b/core/java/android/bluetooth/BluetoothGattService.java
@@ -152,8 +152,8 @@
      */
     /*package*/ BluetoothGattCharacteristic getCharacteristic(UUID uuid, int instanceId) {
         for(BluetoothGattCharacteristic characteristic : mCharacteristics) {
-            if (uuid.equals(characteristic.getUuid()) &&
-                    mInstanceId == instanceId)
+            if (uuid.equals(characteristic.getUuid())
+             && characteristic.getInstanceId() == instanceId)
                 return characteristic;
         }
         return null;
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index 793d798..1962514 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -193,6 +193,11 @@
             "android.bluetooth.headset.intent.category.companyid";
 
     /**
+     * A vendor-specific command for unsolicited result code.
+     */
+    public static final String VENDOR_RESULT_CODE_COMMAND_ANDROID = "+ANDROID";
+
+    /**
      * Headset state when SCO audio is not connected.
      * This state can be one of
      * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
@@ -241,9 +246,7 @@
                             try {
                                 if (mService == null) {
                                     if (VDBG) Log.d(TAG,"Binding service...");
-                                    if (!mContext.bindService(new Intent(IBluetoothHeadset.class.getName()), mConnection, 0)) {
-                                        Log.e(TAG, "Could not bind to Bluetooth Headset Service");
-                                    }
+                                    doBind();
                                 }
                             } catch (Exception re) {
                                 Log.e(TAG,"",re);
@@ -270,9 +273,18 @@
             }
         }
 
-        if (!context.bindService(new Intent(IBluetoothHeadset.class.getName()), mConnection, 0)) {
-            Log.e(TAG, "Could not bind to Bluetooth Headset Service");
+        doBind();
+    }
+
+    boolean doBind() {
+        Intent intent = new Intent(IBluetoothHeadset.class.getName());
+        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+        intent.setComponent(comp);
+        if (comp == null || !mContext.bindService(intent, mConnection, 0)) {
+            Log.e(TAG, "Could not bind to Bluetooth Headset Service with " + intent);
+            return false;
         }
+        return true;
     }
 
     /**
@@ -815,27 +827,6 @@
     }
 
     /**
-     * Notify Headset of phone roam state change.
-     * This is a backdoor for phone app to call BluetoothHeadset since
-     * there is currently not a good way to get roaming state change outside
-     * of phone app.
-     *
-     * @hide
-     */
-    public void roamChanged(boolean roaming) {
-        if (mService != null && isEnabled()) {
-            try {
-                mService.roamChanged(roaming);
-            } 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()));
-        }
-    }
-
-    /**
      * Send Headset of CLCC response
      *
      * @hide
@@ -854,6 +845,46 @@
         }
     }
 
+    /**
+     * 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>Currently only {@link #VENDOR_RESULT_CODE_COMMAND_ANDROID} is allowed as {@code command}.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
+     *
+     * @param device Bluetooth headset.
+     * @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.
+     * @throws IllegalArgumentException if {@code command} is {@code null}.
+     */
+    public boolean sendVendorSpecificResultCode(BluetoothDevice device, String command,
+            String arg) {
+        if (DBG) {
+            log("sendVendorSpecificResultCode()");
+        }
+        if (command == null) {
+            throw new IllegalArgumentException("command is null");
+        }
+        if (mService != null && isEnabled() &&
+                isValidDevice(device)) {
+            try {
+                return mService.sendVendorSpecificResultCode(device, command, arg);
+            } catch (RemoteException e) {
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
+            }
+        }
+        if (mService == null) {
+            Log.w(TAG, "Proxy not attached to service");
+        }
+        return false;
+    }
+
     private ServiceConnection mConnection = new ServiceConnection() {
         public void onServiceConnected(ComponentName className, IBinder service) {
             if (DBG) Log.d(TAG, "Proxy object connected");
diff --git a/core/java/android/bluetooth/BluetoothHealth.java b/core/java/android/bluetooth/BluetoothHealth.java
index cb23662..b1a084a 100644
--- a/core/java/android/bluetooth/BluetoothHealth.java
+++ b/core/java/android/bluetooth/BluetoothHealth.java
@@ -117,9 +117,7 @@
                             try {
                                 if (mService == null) {
                                     if (VDBG) Log.d(TAG,"Binding service...");
-                                    if (!mContext.bindService(new Intent(IBluetoothHealth.class.getName()), mConnection, 0)) {
-                                        Log.e(TAG, "Could not bind to Bluetooth Health Service");
-                                    }
+                                    doBind();
                                 }
                             } catch (Exception re) {
                                 Log.e(TAG,"",re);
@@ -483,9 +481,18 @@
             }
         }
 
-        if (!context.bindService(new Intent(IBluetoothHealth.class.getName()), mConnection, 0)) {
-            Log.e(TAG, "Could not bind to Bluetooth Health Service");
+        doBind();
+    }
+
+    boolean doBind() {
+        Intent intent = new Intent(IBluetoothHealth.class.getName());
+        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+        intent.setComponent(comp);
+        if (comp == null || !mContext.bindService(intent, mConnection, 0)) {
+            Log.e(TAG, "Could not bind to Bluetooth Health Service with " + intent);
+            return false;
         }
+        return true;
     }
 
     /*package*/ void close() {
diff --git a/core/java/android/bluetooth/BluetoothInputDevice.java b/core/java/android/bluetooth/BluetoothInputDevice.java
index db7e424..f9c789c 100644
--- a/core/java/android/bluetooth/BluetoothInputDevice.java
+++ b/core/java/android/bluetooth/BluetoothInputDevice.java
@@ -206,9 +206,7 @@
                             try {
                                 if (mService == null) {
                                     if (VDBG) Log.d(TAG,"Binding service...");
-                                    if (!mContext.bindService(new Intent(IBluetoothInputDevice.class.getName()), mConnection, 0)) {
-                                        Log.e(TAG, "Could not bind to Bluetooth HID Service");
-                                    }
+                                    doBind();
                                 }
                             } catch (Exception re) {
                                 Log.e(TAG,"",re);
@@ -237,10 +235,18 @@
             }
         }
 
-        if (!context.bindService(new Intent(IBluetoothInputDevice.class.getName()),
-                                 mConnection, 0)) {
-            Log.e(TAG, "Could not bind to Bluetooth HID Service");
+        doBind();
+    }
+
+    boolean doBind() {
+        Intent intent = new Intent(IBluetoothInputDevice.class.getName());
+        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+        intent.setComponent(comp);
+        if (comp == null || !mContext.bindService(intent, mConnection, 0)) {
+            Log.e(TAG, "Could not bind to Bluetooth HID Service with " + intent);
+            return false;
         }
+        return true;
     }
 
     /*package*/ void close() {
diff --git a/core/java/android/bluetooth/BluetoothMap.java b/core/java/android/bluetooth/BluetoothMap.java
new file mode 100644
index 0000000..fac8fd5
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothMap.java
@@ -0,0 +1,408 @@
+/*
+ * 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.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.IBinder;
+import android.os.ServiceManager;
+import android.util.Log;
+
+/**
+ * This class provides the APIs to control the Bluetooth MAP
+ * Profile.
+ *@hide
+ */
+public final class BluetoothMap implements BluetoothProfile {
+
+    private static final String TAG = "BluetoothMap";
+    private static final boolean DBG = true;
+    private static final boolean VDBG = false;
+
+    public static final String ACTION_CONNECTION_STATE_CHANGED =
+        "android.bluetooth.map.profile.action.CONNECTION_STATE_CHANGED";
+
+    private 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 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 =
+            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 BluetoothMap proxy object.
+     */
+    /*package*/ BluetoothMap(Context context, ServiceListener l) {
+        if (DBG) Log.d(TAG, "Create BluetoothMap proxy object");
+        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(IBluetoothMap.class.getName());
+        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+        intent.setComponent(comp);
+        if (comp == null || !mContext.bindService(intent, mConnection, 0)) {
+            Log.e(TAG, "Could not bind to Bluetooth MAP Service with " + intent);
+            return false;
+        }
+        return true;
+    }
+
+    protected void finalize() throws Throwable {
+        try {
+            close();
+        } finally {
+            super.finalize();
+        }
+    }
+
+    /**
+     * Close the connection to the backing service.
+     * Other public functions of BluetoothMap will return default error
+     * results once close() has been called. Multiple invocations of close()
+     * are ok.
+     */
+    public synchronized void 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);
+                    mConnection = null;
+                } catch (Exception re) {
+                    Log.e(TAG,"",re);
+                }
+            }
+        }
+        mServiceListener = null;
+    }
+
+    /**
+     * 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.
+     */
+    public int getState() {
+        if (VDBG) log("getState()");
+        if (mService != null) {
+            try {
+                return mService.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 BluetoothMap.STATE_ERROR;
+    }
+
+    /**
+     * 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.
+     */
+    public BluetoothDevice getClient() {
+        if (VDBG) log("getClient()");
+        if (mService != null) {
+            try {
+                return mService.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()));
+        }
+        return null;
+    }
+
+    /**
+     * 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 Map service.
+     */
+    public boolean isConnected(BluetoothDevice device) {
+        if (VDBG) log("isConnected(" + device + ")");
+        if (mService != null) {
+            try {
+                return mService.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()));
+        }
+        return false;
+    }
+
+    /**
+     * Initiate connection. Initiation of outgoing connections is not
+     * supported for MAP server.
+     */
+    public boolean connect(BluetoothDevice device) {
+        if (DBG) log("connect(" + device + ")" + "not supported for MAPS");
+        return false;
+    }
+
+    /**
+     * Initiate disconnect.
+     *
+     * @param device Remote Bluetooth Device
+     * @return false on error,
+     *               true otherwise
+     */
+    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, Log.getStackTraceString(new Throwable()));
+              return false;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Check class bits for possible Map support.
+     * 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;
+        }
+    }
+
+    /**
+     * Get the list of connected devices. Currently at most one.
+     *
+     * @return list of connected devices
+     */
+    public List<BluetoothDevice> getConnectedDevices() {
+        if (DBG) log("getConnectedDevices()");
+        if (mService != null && isEnabled()) {
+            try {
+                return mService.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");
+        return new ArrayList<BluetoothDevice>();
+    }
+
+    /**
+     * Get the list of devices matching specified states. Currently at most one.
+     *
+     * @return list of matching devices
+     */
+    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
+        if (DBG) log("getDevicesMatchingStates()");
+        if (mService != null && isEnabled()) {
+            try {
+                return mService.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");
+        return new ArrayList<BluetoothDevice>();
+    }
+
+    /**
+     * Get connection state of device
+     *
+     * @return device connection state
+     */
+    public int getConnectionState(BluetoothDevice device) {
+        if (DBG) log("getConnectionState(" + device + ")");
+        if (mService != null && isEnabled() &&
+            isValidDevice(device)) {
+            try {
+                return mService.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");
+        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},
+     *
+     * @param device Paired bluetooth device
+     * @param priority
+     * @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;
+            }
+            try {
+                return mService.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");
+        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}
+     *
+     * @param device Bluetooth device
+     * @return priority of the device
+     */
+    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, Log.getStackTraceString(new Throwable()));
+                return PRIORITY_OFF;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return PRIORITY_OFF;
+    }
+
+    private ServiceConnection mConnection = new ServiceConnection() {
+        public void onServiceConnected(ComponentName className, IBinder service) {
+            if (DBG) log("Proxy object connected");
+            mService = IBluetoothMap.Stub.asInterface(service);
+            if (mServiceListener != null) {
+                mServiceListener.onServiceConnected(BluetoothProfile.MAP, BluetoothMap.this);
+            }
+        }
+        public void onServiceDisconnected(ComponentName className) {
+            if (DBG) log("Proxy object disconnected");
+            mService = null;
+            if (mServiceListener != null) {
+                mServiceListener.onServiceDisconnected(BluetoothProfile.MAP);
+            }
+        }
+    };
+
+    private static void log(String msg) {
+        Log.d(TAG, msg);
+    }
+
+   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;
+    }
+
+
+}
diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java
index e25ec86..83d4329 100644
--- a/core/java/android/bluetooth/BluetoothPan.java
+++ b/core/java/android/bluetooth/BluetoothPan.java
@@ -137,12 +137,20 @@
         } catch (RemoteException re) {
             Log.w(TAG,"Unable to register BluetoothStateChangeCallback",re);
         }
-        Log.d(TAG, "BluetoothPan() call bindService");
-        if (!context.bindService(new Intent(IBluetoothPan.class.getName()),
-                                 mConnection, 0)) {
-            Log.e(TAG, "Could not bind to Bluetooth HID Service");
+        if (VDBG) Log.d(TAG, "BluetoothPan() call bindService");
+        doBind();
+        if (VDBG) Log.d(TAG, "BluetoothPan(), bindService called");
+    }
+
+    boolean doBind() {
+        Intent intent = new Intent(IBluetoothPan.class.getName());
+        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+        intent.setComponent(comp);
+        if (comp == null || !mContext.bindService(intent, mConnection, 0)) {
+            Log.e(TAG, "Could not bind to Bluetooth Pan Service with " + intent);
+            return false;
         }
-        Log.d(TAG, "BluetoothPan(), bindService called");
+        return true;
     }
 
     /*package*/ void close() {
@@ -170,11 +178,8 @@
             //Handle enable request to bind again.
             if (on) {
                 Log.d(TAG, "onBluetoothStateChange(on) call bindService");
-                if (!mContext.bindService(new Intent(IBluetoothPan.class.getName()),
-                                     mConnection, 0)) {
-                    Log.e(TAG, "Could not bind to Bluetooth HID Service");
-                }
-                Log.d(TAG, "BluetoothPan(), bindService called");
+                doBind();
+                if (VDBG) Log.d(TAG, "BluetoothPan(), bindService called");
             } else {
                 if (VDBG) Log.d(TAG,"Unbinding service...");
                 synchronized (mConnection) {
diff --git a/core/java/android/bluetooth/BluetoothPbap.java b/core/java/android/bluetooth/BluetoothPbap.java
index b5280e5..c42251f 100644
--- a/core/java/android/bluetooth/BluetoothPbap.java
+++ b/core/java/android/bluetooth/BluetoothPbap.java
@@ -129,11 +129,7 @@
                             try {
                                 if (mService == null) {
                                     if (VDBG) Log.d(TAG,"Binding service...");
-                                    if (!mContext.bindService(
-                                                        new Intent(IBluetoothPbap.class.getName()),
-                                                        mConnection, 0)) {
-                                        Log.e(TAG, "Could not bind to Bluetooth PBAP Service");
-                                    }
+                                    doBind();
                                 }
                             } catch (Exception re) {
                                 Log.e(TAG,"",re);
@@ -158,9 +154,18 @@
                 Log.e(TAG,"",e);
             }
         }
-        if (!context.bindService(new Intent(IBluetoothPbap.class.getName()), mConnection, 0)) {
-            Log.e(TAG, "Could not bind to Bluetooth Pbap Service");
+        doBind();
+    }
+
+    boolean doBind() {
+        Intent intent = new Intent(IBluetoothPbap.class.getName());
+        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+        intent.setComponent(comp);
+        if (comp == null || !mContext.bindService(intent, mConnection, 0)) {
+            Log.e(TAG, "Could not bind to Bluetooth Pbap Service with " + intent);
+            return false;
         }
+        return true;
     }
 
     protected void finalize() throws Throwable {
diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java
index 43079f4..1574090 100644
--- a/core/java/android/bluetooth/BluetoothProfile.java
+++ b/core/java/android/bluetooth/BluetoothProfile.java
@@ -98,6 +98,12 @@
     static public final int GATT_SERVER = 8;
 
     /**
+     * MAP Profile
+     * @hide
+     */
+    public static final int MAP = 9;
+
+    /**
      * Default priority for devices that we try to auto-connect to and
      * and allow incoming connections for the profile
      * @hide
diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java
index a19341c..191bf67 100644
--- a/core/java/android/bluetooth/BluetoothSocket.java
+++ b/core/java/android/bluetooth/BluetoothSocket.java
@@ -31,6 +31,7 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.List;
+import java.util.Locale;
 import java.util.UUID;
 import android.net.LocalSocket;
 import java.nio.ByteOrder;
@@ -102,6 +103,8 @@
     /*package*/ static final int SEC_FLAG_ENCRYPT = 1;
     /*package*/ static final int SEC_FLAG_AUTH = 1 << 1;
 
+    /*package*/ static final int PORT_MASK_FIXED_CHAN = 1 << 16;
+
     private final int mType;  /* one of TYPE_RFCOMM etc */
     private BluetoothDevice mDevice;    /* remote device */
     private String mAddress;    /* remote address */
@@ -114,7 +117,7 @@
     private LocalSocket mSocket;
     private InputStream mSocketIS;
     private OutputStream mSocketOS;
-    private int mPort;  /* RFCOMM channel or L2CAP psm */
+    private int mPort;  /* RFCOMM channel or L2CAP psm/channel */
     private int mFd;
     private String mServiceName;
     private static int PROXY_CONNECTION_TIMEOUT = 5000;
@@ -473,7 +476,7 @@
         return mPort;
     }
     private String convertAddr(final byte[] addr)  {
-        return String.format("%02X:%02X:%02X:%02X:%02X:%02X",
+        return String.format(Locale.US, "%02X:%02X:%02X:%02X:%02X:%02X",
                 addr[0] , addr[1], addr[2], addr[3] , addr[4], addr[5]);
     }
     private String waitSocketSignal(InputStream is) throws IOException {
diff --git a/core/java/android/bluetooth/BluetoothTetheringDataTracker.java b/core/java/android/bluetooth/BluetoothTetheringDataTracker.java
index 0aedecb..a9b7176 100644
--- a/core/java/android/bluetooth/BluetoothTetheringDataTracker.java
+++ b/core/java/android/bluetooth/BluetoothTetheringDataTracker.java
@@ -16,6 +16,7 @@
 
 package android.bluetooth;
 
+import android.net.BaseNetworkStateTracker;
 import android.os.IBinder;
 import android.os.ServiceManager;
 import android.os.INetworkManagementService;
@@ -54,7 +55,7 @@
  *
  * @hide
  */
-public class BluetoothTetheringDataTracker implements NetworkStateTracker {
+public class BluetoothTetheringDataTracker extends BaseNetworkStateTracker {
     private static final String NETWORKTYPE = "BLUETOOTH_TETHER";
     private static final String TAG = "BluetoothTethering";
     private static final boolean DBG = true;
@@ -66,18 +67,12 @@
     private AtomicBoolean mDefaultRouteSet = new AtomicBoolean(false);
 
     private final Object mLinkPropertiesLock = new Object();
-    private LinkProperties mLinkProperties;
-
-    private LinkCapabilities mLinkCapabilities;
-
     private final Object mNetworkInfoLock = new Object();
-    private NetworkInfo mNetworkInfo;
 
     private BluetoothPan mBluetoothPan;
     private static String mRevTetheredIface;
     /* For sending events to connectivity service handler */
     private Handler mCsHandler;
-    protected Context mContext;
     private static BluetoothTetheringDataTracker sInstance;
     private BtdtHandler mBtdtHandler;
     private AtomicReference<AsyncChannel> mAsyncChannel = new AtomicReference<AsyncChannel>(null);
diff --git a/core/java/android/bluetooth/BluetoothUuid.java b/core/java/android/bluetooth/BluetoothUuid.java
index 5962235..abdf949e 100644
--- a/core/java/android/bluetooth/BluetoothUuid.java
+++ b/core/java/android/bluetooth/BluetoothUuid.java
@@ -56,6 +56,8 @@
             ParcelUuid.fromString("00001105-0000-1000-8000-00805f9b34fb");
     public static final ParcelUuid Hid =
             ParcelUuid.fromString("00001124-0000-1000-8000-00805f9b34fb");
+    public static final ParcelUuid Hogp =
+            ParcelUuid.fromString("00001812-0000-1000-8000-00805f9b34fb");
     public static final ParcelUuid PANU =
             ParcelUuid.fromString("00001115-0000-1000-8000-00805F9B34FB");
     public static final ParcelUuid NAP =
@@ -64,10 +66,17 @@
             ParcelUuid.fromString("0000000f-0000-1000-8000-00805F9B34FB");
     public static final ParcelUuid PBAP_PSE =
             ParcelUuid.fromString("0000112f-0000-1000-8000-00805F9B34FB");
+    public static final ParcelUuid MAP =
+            ParcelUuid.fromString("00001134-0000-1000-8000-00805F9B34FB");
+    public static final ParcelUuid MNS =
+            ParcelUuid.fromString("00001133-0000-1000-8000-00805F9B34FB");
+    public static final ParcelUuid MAS =
+            ParcelUuid.fromString("00001132-0000-1000-8000-00805F9B34FB");
+
 
     public static final ParcelUuid[] RESERVED_UUIDS = {
         AudioSink, AudioSource, AdvAudioDist, HSP, Handsfree, AvrcpController, AvrcpTarget,
-        ObexObjectPush, PANU, NAP};
+        ObexObjectPush, PANU, NAP, MAP, MNS, MAS};
 
     public static boolean isAudioSource(ParcelUuid uuid) {
         return uuid.equals(AudioSource);
@@ -112,6 +121,16 @@
     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);
+    }
+
     /**
      * Returns true if ParcelUuid is present in uuidArray
      *
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index 80806f9..07db8cc 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -80,4 +80,6 @@
     // For Socket
     ParcelFileDescriptor connectSocket(in BluetoothDevice device, int type, in ParcelUuid uuid, int port, int flag);
     ParcelFileDescriptor createSocketChannel(int type, in String serviceName, in ParcelUuid uuid, int port, int flag);
+
+    boolean configHciSnoopLog(boolean enable);
 }
diff --git a/core/java/android/bluetooth/IBluetoothA2dp.aidl b/core/java/android/bluetooth/IBluetoothA2dp.aidl
index 1f10998..26ff9e27 100644
--- a/core/java/android/bluetooth/IBluetoothA2dp.aidl
+++ b/core/java/android/bluetooth/IBluetoothA2dp.aidl
@@ -32,5 +32,8 @@
     int getConnectionState(in BluetoothDevice device);
     boolean setPriority(in BluetoothDevice device, int priority);
     int getPriority(in BluetoothDevice device);
+    boolean isAvrcpAbsoluteVolumeSupported();
+    oneway void adjustAvrcpAbsoluteVolume(int direction);
+    oneway void setAvrcpAbsoluteVolume(int volume);
     boolean isA2dpPlaying(in BluetoothDevice device);
 }
diff --git a/core/java/android/bluetooth/IBluetoothGatt.aidl b/core/java/android/bluetooth/IBluetoothGatt.aidl
index c89d132..df393db 100644
--- a/core/java/android/bluetooth/IBluetoothGatt.aidl
+++ b/core/java/android/bluetooth/IBluetoothGatt.aidl
@@ -37,6 +37,10 @@
     void unregisterClient(in int clientIf);
     void clientConnect(in int clientIf, in String address, in boolean isDirect);
     void clientDisconnect(in int clientIf, in String address);
+    void clientListen(in int clientIf, in boolean start);
+    void setAdvData(in int clientIf, in boolean setScanRsp, in boolean inclName,
+                            in boolean inclTxPower, in int minInterval, in int maxInterval,
+                            in int appearance, in byte[] manufacturerData);
     void refreshDevice(in int clientIf, in String address);
     void discoverServices(in int clientIf, in String address);
     void readCharacteristic(in int clientIf, in String address, in int srvcType,
@@ -50,12 +54,13 @@
     void readDescriptor(in int clientIf, in String address, in int srvcType,
                             in int srvcInstanceId, in ParcelUuid srvcId,
                             in int charInstanceId, in ParcelUuid charId,
-                            in ParcelUuid descrUuid, in int authReq);
+                            in int descrInstanceId, in ParcelUuid descrUuid,
+                            in int authReq);
     void writeDescriptor(in int clientIf, in String address, in int srvcType,
                             in int srvcInstanceId, in ParcelUuid srvcId,
                             in int charInstanceId, in ParcelUuid charId,
-                            in ParcelUuid descrId, in int writeType,
-                            in int authReq, in byte[] value);
+                            in int descrInstanceId, in ParcelUuid descrId,
+                            in int writeType, in int authReq, in byte[] value);
     void registerForNotification(in int clientIf, in String address, in int srvcType,
                             in int srvcInstanceId, in ParcelUuid srvcId,
                             in int charInstanceId, in ParcelUuid charId,
diff --git a/core/java/android/bluetooth/IBluetoothGattCallback.aidl b/core/java/android/bluetooth/IBluetoothGattCallback.aidl
index fc52172..60c297b 100644
--- a/core/java/android/bluetooth/IBluetoothGattCallback.aidl
+++ b/core/java/android/bluetooth/IBluetoothGattCallback.aidl
@@ -39,7 +39,7 @@
     void onGetDescriptor(in String address, in int srvcType,
                              in int srvcInstId, in ParcelUuid srvcUuid,
                              in int charInstId, in ParcelUuid charUuid,
-                             in ParcelUuid descrUuid);
+                             in int descrInstId, in ParcelUuid descrUuid);
     void onSearchComplete(in String address, in int status);
     void onCharacteristicRead(in String address, in int status, in int srvcType,
                              in int srvcInstId, in ParcelUuid srvcUuid,
@@ -52,14 +52,16 @@
     void onDescriptorRead(in String address, in int status, in int srvcType,
                              in int srvcInstId, in ParcelUuid srvcUuid,
                              in int charInstId, in ParcelUuid charUuid,
-                             in ParcelUuid descrUuid, in byte[] value);
+                             in int descrInstId, in ParcelUuid descrUuid,
+                             in byte[] value);
     void onDescriptorWrite(in String address, in int status, in int srvcType,
                              in int srvcInstId, in ParcelUuid srvcUuid,
                              in int charInstId, in ParcelUuid charUuid,
-                             in ParcelUuid descrUuid);
+                             in int descrInstId, in ParcelUuid descrUuid);
     void onNotify(in String address, in int srvcType,
                              in int srvcInstId, in ParcelUuid srvcUuid,
                              in int charInstId, in ParcelUuid charUuid,
                              in byte[] value);
     void onReadRemoteRssi(in String address, in int rssi, in int status);
+    void onListen(in int status);
 }
diff --git a/core/java/android/bluetooth/IBluetoothHeadset.aidl b/core/java/android/bluetooth/IBluetoothHeadset.aidl
old mode 100644
new mode 100755
index fc7627a..524ca6f
--- a/core/java/android/bluetooth/IBluetoothHeadset.aidl
+++ b/core/java/android/bluetooth/IBluetoothHeadset.aidl
@@ -35,6 +35,9 @@
     boolean startVoiceRecognition(in BluetoothDevice device);
     boolean stopVoiceRecognition(in BluetoothDevice device);
     boolean isAudioConnected(in BluetoothDevice device);
+    boolean sendVendorSpecificResultCode(in BluetoothDevice device,
+                                         in String command,
+                                         in String arg);
 
     // APIs that can be made public in future
     int getBatteryUsageHint(in BluetoothDevice device);
@@ -50,7 +53,6 @@
     boolean startScoUsingVirtualVoiceCall(in BluetoothDevice device);
     boolean stopScoUsingVirtualVoiceCall(in BluetoothDevice device);
     void phoneStateChanged(int numActive, int numHeld, int callState, String number, int type);
-    void roamChanged(boolean roam);
     void clccResponse(int index, int direction, int status, int mode, boolean mpty,
                       String number, int type);
 }
diff --git a/core/java/android/bluetooth/IBluetoothMap.aidl b/core/java/android/bluetooth/IBluetoothMap.aidl
new file mode 100644
index 0000000..d4af63d
--- /dev/null
+++ b/core/java/android/bluetooth/IBluetoothMap.aidl
@@ -0,0 +1,37 @@
+/*
+ * 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.bluetooth;
+
+import android.bluetooth.BluetoothDevice;
+
+/**
+ * System private API for Bluetooth MAP service
+ *
+ * {@hide}
+ */
+interface IBluetoothMap {
+    int getState();
+    BluetoothDevice getClient();
+    boolean connect(in BluetoothDevice device);
+    boolean disconnect(in BluetoothDevice device);
+    boolean isConnected(in BluetoothDevice device);
+    List<BluetoothDevice> getConnectedDevices();
+    List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states);
+    int getConnectionState(in BluetoothDevice device);
+    boolean setPriority(in BluetoothDevice device, int priority);
+    int getPriority(in BluetoothDevice device);
+}
diff --git a/core/java/android/content/AbstractThreadedSyncAdapter.java b/core/java/android/content/AbstractThreadedSyncAdapter.java
index 898cc4e..809f900 100644
--- a/core/java/android/content/AbstractThreadedSyncAdapter.java
+++ b/core/java/android/content/AbstractThreadedSyncAdapter.java
@@ -147,6 +147,7 @@
     }
 
     private class ISyncAdapterImpl extends ISyncAdapter.Stub {
+        @Override
         public void startSync(ISyncContext syncContext, String authority, Account account,
                 Bundle extras) {
             final SyncContext syncContextClient = new SyncContext(syncContext);
@@ -187,6 +188,7 @@
             }
         }
 
+        @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
diff --git a/core/java/android/content/ClipboardManager.java b/core/java/android/content/ClipboardManager.java
index 69f9d4a..73e6fd0 100644
--- a/core/java/android/content/ClipboardManager.java
+++ b/core/java/android/content/ClipboardManager.java
@@ -122,7 +122,7 @@
             if (clip != null) {
                 clip.prepareToLeaveProcess();
             }
-            getService().setPrimaryClip(clip, mContext.getBasePackageName());
+            getService().setPrimaryClip(clip, mContext.getOpPackageName());
         } catch (RemoteException e) {
         }
     }
@@ -132,7 +132,7 @@
      */
     public ClipData getPrimaryClip() {
         try {
-            return getService().getPrimaryClip(mContext.getBasePackageName());
+            return getService().getPrimaryClip(mContext.getOpPackageName());
         } catch (RemoteException e) {
             return null;
         }
@@ -144,7 +144,7 @@
      */
     public ClipDescription getPrimaryClipDescription() {
         try {
-            return getService().getPrimaryClipDescription(mContext.getBasePackageName());
+            return getService().getPrimaryClipDescription(mContext.getOpPackageName());
         } catch (RemoteException e) {
             return null;
         }
@@ -155,7 +155,7 @@
      */
     public boolean hasPrimaryClip() {
         try {
-            return getService().hasPrimaryClip(mContext.getBasePackageName());
+            return getService().hasPrimaryClip(mContext.getOpPackageName());
         } catch (RemoteException e) {
             return false;
         }
@@ -166,7 +166,7 @@
             if (mPrimaryClipChangedListeners.size() == 0) {
                 try {
                     getService().addPrimaryClipChangedListener(
-                            mPrimaryClipChangedServiceListener, mContext.getBasePackageName());
+                            mPrimaryClipChangedServiceListener, mContext.getOpPackageName());
                 } catch (RemoteException e) {
                 }
             }
@@ -213,7 +213,7 @@
      */
     public boolean hasText() {
         try {
-            return getService().hasClipboardText(mContext.getBasePackageName());
+            return getService().hasClipboardText(mContext.getOpPackageName());
         } catch (RemoteException e) {
             return false;
         }
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index cf627d7..0a1d3f9a 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -16,11 +16,9 @@
 
 package android.content;
 
-import static android.content.pm.PackageManager.GET_PROVIDERS;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 
 import android.app.AppOpsManager;
-import android.content.pm.PackageManager;
 import android.content.pm.PathPermission;
 import android.content.pm.ProviderInfo;
 import android.content.res.AssetFileDescriptor;
@@ -36,7 +34,6 @@
 import android.os.OperationCanceledException;
 import android.os.ParcelFileDescriptor;
 import android.os.Process;
-import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.Log;
 
@@ -104,6 +101,8 @@
     private boolean mExported;
     private boolean mNoPerms;
 
+    private final ThreadLocal<String> mCallingPackage = new ThreadLocal<String>();
+
     private Transport mTransport = new Transport();
 
     /**
@@ -196,8 +195,14 @@
                 return rejectQuery(uri, projection, selection, selectionArgs, sortOrder,
                         CancellationSignal.fromTransport(cancellationSignal));
             }
-            return ContentProvider.this.query(uri, projection, selection, selectionArgs, sortOrder,
-                    CancellationSignal.fromTransport(cancellationSignal));
+            final String original = setCallingPackage(callingPkg);
+            try {
+                return ContentProvider.this.query(
+                        uri, projection, selection, selectionArgs, sortOrder,
+                        CancellationSignal.fromTransport(cancellationSignal));
+            } finally {
+                setCallingPackage(original);
+            }
         }
 
         @Override
@@ -210,7 +215,12 @@
             if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
                 return rejectInsert(uri, initialValues);
             }
-            return ContentProvider.this.insert(uri, initialValues);
+            final String original = setCallingPackage(callingPkg);
+            try {
+                return ContentProvider.this.insert(uri, initialValues);
+            } finally {
+                setCallingPackage(original);
+            }
         }
 
         @Override
@@ -218,7 +228,12 @@
             if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
                 return 0;
             }
-            return ContentProvider.this.bulkInsert(uri, initialValues);
+            final String original = setCallingPackage(callingPkg);
+            try {
+                return ContentProvider.this.bulkInsert(uri, initialValues);
+            } finally {
+                setCallingPackage(original);
+            }
         }
 
         @Override
@@ -240,7 +255,12 @@
                     }
                 }
             }
-            return ContentProvider.this.applyBatch(operations);
+            final String original = setCallingPackage(callingPkg);
+            try {
+                return ContentProvider.this.applyBatch(operations);
+            } finally {
+                setCallingPackage(original);
+            }
         }
 
         @Override
@@ -248,7 +268,12 @@
             if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
                 return 0;
             }
-            return ContentProvider.this.delete(uri, selection, selectionArgs);
+            final String original = setCallingPackage(callingPkg);
+            try {
+                return ContentProvider.this.delete(uri, selection, selectionArgs);
+            } finally {
+                setCallingPackage(original);
+            }
         }
 
         @Override
@@ -257,26 +282,50 @@
             if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
                 return 0;
             }
-            return ContentProvider.this.update(uri, values, selection, selectionArgs);
+            final String original = setCallingPackage(callingPkg);
+            try {
+                return ContentProvider.this.update(uri, values, selection, selectionArgs);
+            } finally {
+                setCallingPackage(original);
+            }
         }
 
         @Override
-        public ParcelFileDescriptor openFile(String callingPkg, Uri uri, String mode)
+        public ParcelFileDescriptor openFile(
+                String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal)
                 throws FileNotFoundException {
             enforceFilePermission(callingPkg, uri, mode);
-            return ContentProvider.this.openFile(uri, mode);
+            final String original = setCallingPackage(callingPkg);
+            try {
+                return ContentProvider.this.openFile(
+                        uri, mode, CancellationSignal.fromTransport(cancellationSignal));
+            } finally {
+                setCallingPackage(original);
+            }
         }
 
         @Override
-        public AssetFileDescriptor openAssetFile(String callingPkg, Uri uri, String mode)
+        public AssetFileDescriptor openAssetFile(
+                String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal)
                 throws FileNotFoundException {
             enforceFilePermission(callingPkg, uri, mode);
-            return ContentProvider.this.openAssetFile(uri, mode);
+            final String original = setCallingPackage(callingPkg);
+            try {
+                return ContentProvider.this.openAssetFile(
+                        uri, mode, CancellationSignal.fromTransport(cancellationSignal));
+            } finally {
+                setCallingPackage(original);
+            }
         }
 
         @Override
         public Bundle call(String callingPkg, String method, String arg, Bundle extras) {
-            return ContentProvider.this.callFromPackage(callingPkg, method, arg, extras);
+            final String original = setCallingPackage(callingPkg);
+            try {
+                return ContentProvider.this.call(method, arg, extras);
+            } finally {
+                setCallingPackage(original);
+            }
         }
 
         @Override
@@ -286,16 +335,48 @@
 
         @Override
         public AssetFileDescriptor openTypedAssetFile(String callingPkg, Uri uri, String mimeType,
-                Bundle opts) throws FileNotFoundException {
+                Bundle opts, ICancellationSignal cancellationSignal) throws FileNotFoundException {
             enforceFilePermission(callingPkg, uri, "r");
-            return ContentProvider.this.openTypedAssetFile(uri, mimeType, opts);
+            final String original = setCallingPackage(callingPkg);
+            try {
+                return ContentProvider.this.openTypedAssetFile(
+                        uri, mimeType, opts, CancellationSignal.fromTransport(cancellationSignal));
+            } finally {
+                setCallingPackage(original);
+            }
         }
 
         @Override
-        public ICancellationSignal createCancellationSignal() throws RemoteException {
+        public ICancellationSignal createCancellationSignal() {
             return CancellationSignal.createTransport();
         }
 
+        @Override
+        public Uri canonicalize(String callingPkg, Uri uri) {
+            if (enforceReadPermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
+                return null;
+            }
+            final String original = setCallingPackage(callingPkg);
+            try {
+                return ContentProvider.this.canonicalize(uri);
+            } finally {
+                setCallingPackage(original);
+            }
+        }
+
+        @Override
+        public Uri uncanonicalize(String callingPkg, Uri uri) {
+            if (enforceReadPermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
+                return null;
+            }
+            final String original = setCallingPackage(callingPkg);
+            try {
+                return ContentProvider.this.uncanonicalize(uri);
+            } finally {
+                setCallingPackage(original);
+            }
+        }
+
         private void enforceFilePermission(String callingPkg, Uri uri, String mode)
                 throws FileNotFoundException, SecurityException {
             if (mode != null && mode.indexOf('w') != -1) {
@@ -458,6 +539,38 @@
     }
 
     /**
+     * Set the calling package, returning the current value (or {@code null})
+     * which can be used later to restore the previous state.
+     */
+    private String setCallingPackage(String callingPackage) {
+        final String original = mCallingPackage.get();
+        mCallingPackage.set(callingPackage);
+        return original;
+    }
+
+    /**
+     * Return the package name of the caller that initiated the request being
+     * processed on the current thread. The returned package will have been
+     * verified to belong to the calling UID. Returns {@code null} if not
+     * currently processing a request.
+     * <p>
+     * This will always return {@code null} when processing
+     * {@link #getType(Uri)} or {@link #getStreamTypes(Uri, String)} requests.
+     *
+     * @see Binder#getCallingUid()
+     * @see Context#grantUriPermission(String, Uri, int)
+     * @throws SecurityException if the calling package doesn't belong to the
+     *             calling UID.
+     */
+    public final String getCallingPackage() {
+        final String pkg = mCallingPackage.get();
+        if (pkg != null) {
+            mTransport.mAppOpsManager.checkPackage(Binder.getCallingUid(), pkg);
+        }
+        return pkg;
+    }
+
+    /**
      * Change the permission required to read data from the content
      * provider.  This is normally set for you from its manifest information
      * when the provider is first created.
@@ -526,8 +639,6 @@
     /** @hide */
     public final void setAppOps(int readOp, int writeOp) {
         if (!mNoPerms) {
-            mTransport.mAppOpsManager = (AppOpsManager)mContext.getSystemService(
-                    Context.APP_OPS_SERVICE);
             mTransport.mReadOp = readOp;
             mTransport.mWriteOp = writeOp;
         }
@@ -765,6 +876,58 @@
     public abstract String getType(Uri uri);
 
     /**
+     * Implement this to support canonicalization of URIs that refer to your
+     * content provider.  A canonical URI is one that can be transported across
+     * devices, backup/restore, and other contexts, and still be able to refer
+     * to the same data item.  Typically this is implemented by adding query
+     * params to the URI allowing the content provider to verify that an incoming
+     * canonical URI references the same data as it was originally intended for and,
+     * if it doesn't, to find that data (if it exists) in the current environment.
+     *
+     * <p>For example, if the content provider holds people and a normal URI in it
+     * is created with a row index into that people database, the cananical representation
+     * may have an additional query param at the end which specifies the name of the
+     * person it is intended for.  Later calls into the provider with that URI will look
+     * up the row of that URI's base index and, if it doesn't match or its entry's
+     * name doesn't match the name in the query param, perform a query on its database
+     * to find the correct row to operate on.</p>
+     *
+     * <p>If you implement support for canonical URIs, <b>all</b> incoming calls with
+     * URIs (including this one) must perform this verification and recovery of any
+     * canonical URIs they receive.  In addition, you must also implement
+     * {@link #uncanonicalize} to strip the canonicalization of any of these URIs.</p>
+     *
+     * <p>The default implementation of this method returns null, indicating that
+     * canonical URIs are not supported.</p>
+     *
+     * @param url The Uri to canonicalize.
+     *
+     * @return Return the canonical representation of <var>url</var>, or null if
+     * canonicalization of that Uri is not supported.
+     */
+    public Uri canonicalize(Uri url) {
+        return null;
+    }
+
+    /**
+     * Remove canonicalization from canonical URIs previously returned by
+     * {@link #canonicalize}.  For example, if your implementation is to add
+     * a query param to canonicalize a URI, this method can simply trip any
+     * query params on the URI.  The default implementation always returns the
+     * same <var>url</var> that was passed in.
+     *
+     * @param url The Uri to remove any canonicalization from.
+     *
+     * @return Return the non-canonical representation of <var>url</var>, return
+     * the <var>url</var> as-is if there is nothing to do, or return null if
+     * the data identified by the canonical representation can not be found in
+     * the current environment.
+     */
+    public Uri uncanonicalize(Uri url) {
+        return url;
+    }
+
+    /**
      * @hide
      * Implementation when a caller has performed an insert on the content
      * provider, but that call has been rejected for the operation given
@@ -874,6 +1037,18 @@
      * <p>The returned ParcelFileDescriptor is owned by the caller, so it is
      * their responsibility to close it when done.  That is, the implementation
      * of this method should create a new ParcelFileDescriptor for each call.
+     * <p>
+     * If opened with the exclusive "r" or "w" modes, the returned
+     * ParcelFileDescriptor can be a pipe or socket pair to enable streaming
+     * of data. Opening with the "rw" or "rwt" modes implies a file on disk that
+     * supports seeking.
+     * <p>
+     * If you need to detect when the returned ParcelFileDescriptor has been
+     * closed, or if the remote process has crashed or encountered some other
+     * error, you can use {@link ParcelFileDescriptor#open(File, int,
+     * android.os.Handler, android.os.ParcelFileDescriptor.OnCloseListener)},
+     * {@link ParcelFileDescriptor#createReliablePipe()}, or
+     * {@link ParcelFileDescriptor#createReliableSocketPair()}.
      *
      * <p class="note">For use in Intents, you will want to implement {@link #getType}
      * to return the appropriate MIME type for the data returned here with
@@ -911,6 +1086,74 @@
     }
 
     /**
+     * Override this to handle requests to open a file blob.
+     * The default implementation always throws {@link FileNotFoundException}.
+     * This method can be called from multiple threads, as described in
+     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
+     * and Threads</a>.
+     *
+     * <p>This method returns a ParcelFileDescriptor, which is returned directly
+     * to the caller.  This way large data (such as images and documents) can be
+     * returned without copying the content.
+     *
+     * <p>The returned ParcelFileDescriptor is owned by the caller, so it is
+     * their responsibility to close it when done.  That is, the implementation
+     * of this method should create a new ParcelFileDescriptor for each call.
+     * <p>
+     * If opened with the exclusive "r" or "w" modes, the returned
+     * ParcelFileDescriptor can be a pipe or socket pair to enable streaming
+     * of data. Opening with the "rw" or "rwt" modes implies a file on disk that
+     * supports seeking.
+     * <p>
+     * If you need to detect when the returned ParcelFileDescriptor has been
+     * closed, or if the remote process has crashed or encountered some other
+     * error, you can use {@link ParcelFileDescriptor#open(File, int,
+     * android.os.Handler, android.os.ParcelFileDescriptor.OnCloseListener)},
+     * {@link ParcelFileDescriptor#createReliablePipe()}, or
+     * {@link ParcelFileDescriptor#createReliableSocketPair()}.
+     *
+     * <p class="note">For use in Intents, you will want to implement {@link #getType}
+     * to return the appropriate MIME type for the data returned here with
+     * the same URI.  This will allow intent resolution to automatically determine the data MIME
+     * type and select the appropriate matching targets as part of its operation.</p>
+     *
+     * <p class="note">For better interoperability with other applications, it is recommended
+     * that for any URIs that can be opened, you also support queries on them
+     * containing at least the columns specified by {@link android.provider.OpenableColumns}.
+     * You may also want to support other common columns if you have additional meta-data
+     * to supply, such as {@link android.provider.MediaStore.MediaColumns#DATE_ADDED}
+     * in {@link android.provider.MediaStore.MediaColumns}.</p>
+     *
+     * @param uri The URI whose file is to be opened.
+     * @param mode Access mode for the file. May be "r" for read-only access,
+     *            "w" for write-only access, "rw" for read and write access, or
+     *            "rwt" for read and write access that truncates any existing
+     *            file.
+     * @param signal A signal to cancel the operation in progress, or
+     *            {@code null} if none. For example, if you are downloading a
+     *            file from the network to service a "rw" mode request, you
+     *            should periodically call
+     *            {@link CancellationSignal#throwIfCanceled()} to check whether
+     *            the client has canceled the request and abort the download.
+     *
+     * @return Returns a new ParcelFileDescriptor which you can use to access
+     * the file.
+     *
+     * @throws FileNotFoundException Throws FileNotFoundException if there is
+     * no file associated with the given URI or the mode is invalid.
+     * @throws SecurityException Throws SecurityException if the caller does
+     * not have permission to access the file.
+     *
+     * @see #openAssetFile(Uri, String)
+     * @see #openFileHelper(Uri, String)
+     * @see #getType(android.net.Uri)
+     */
+    public ParcelFileDescriptor openFile(Uri uri, String mode, CancellationSignal signal)
+            throws FileNotFoundException {
+        return openFile(uri, mode);
+    }
+
+    /**
      * This is like {@link #openFile}, but can be implemented by providers
      * that need to be able to return sub-sections of files, often assets
      * inside of their .apk.
@@ -924,11 +1167,14 @@
      * {@link ContentResolver#openInputStream ContentResolver.openInputStream}
      * or {@link ContentResolver#openOutputStream ContentResolver.openOutputStream}
      * methods.
+     * <p>
+     * The returned AssetFileDescriptor can be a pipe or socket pair to enable
+     * streaming of data.
      *
      * <p class="note">If you are implementing this to return a full file, you
      * should create the AssetFileDescriptor with
      * {@link AssetFileDescriptor#UNKNOWN_LENGTH} to be compatible with
-     * applications that can not handle sub-sections of files.</p>
+     * applications that cannot handle sub-sections of files.</p>
      *
      * <p class="note">For use in Intents, you will want to implement {@link #getType}
      * to return the appropriate MIME type for the data returned here with
@@ -965,6 +1211,68 @@
     }
 
     /**
+     * This is like {@link #openFile}, but can be implemented by providers
+     * that need to be able to return sub-sections of files, often assets
+     * inside of their .apk.
+     * This method can be called from multiple threads, as described in
+     * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
+     * and Threads</a>.
+     *
+     * <p>If you implement this, your clients must be able to deal with such
+     * file slices, either directly with
+     * {@link ContentResolver#openAssetFileDescriptor}, or by using the higher-level
+     * {@link ContentResolver#openInputStream ContentResolver.openInputStream}
+     * or {@link ContentResolver#openOutputStream ContentResolver.openOutputStream}
+     * methods.
+     * <p>
+     * The returned AssetFileDescriptor can be a pipe or socket pair to enable
+     * streaming of data.
+     *
+     * <p class="note">If you are implementing this to return a full file, you
+     * should create the AssetFileDescriptor with
+     * {@link AssetFileDescriptor#UNKNOWN_LENGTH} to be compatible with
+     * applications that cannot handle sub-sections of files.</p>
+     *
+     * <p class="note">For use in Intents, you will want to implement {@link #getType}
+     * to return the appropriate MIME type for the data returned here with
+     * the same URI.  This will allow intent resolution to automatically determine the data MIME
+     * type and select the appropriate matching targets as part of its operation.</p>
+     *
+     * <p class="note">For better interoperability with other applications, it is recommended
+     * that for any URIs that can be opened, you also support queries on them
+     * containing at least the columns specified by {@link android.provider.OpenableColumns}.</p>
+     *
+     * @param uri The URI whose file is to be opened.
+     * @param mode Access mode for the file.  May be "r" for read-only access,
+     * "w" for write-only access (erasing whatever data is currently in
+     * the file), "wa" for write-only access to append to any existing data,
+     * "rw" for read and write access on any existing data, and "rwt" for read
+     * and write access that truncates any existing file.
+     * @param signal A signal to cancel the operation in progress, or
+     *            {@code null} if none. For example, if you are downloading a
+     *            file from the network to service a "rw" mode request, you
+     *            should periodically call
+     *            {@link CancellationSignal#throwIfCanceled()} to check whether
+     *            the client has canceled the request and abort the download.
+     *
+     * @return Returns a new AssetFileDescriptor which you can use to access
+     * the file.
+     *
+     * @throws FileNotFoundException Throws FileNotFoundException if there is
+     * no file associated with the given URI or the mode is invalid.
+     * @throws SecurityException Throws SecurityException if the caller does
+     * not have permission to access the file.
+     *
+     * @see #openFile(Uri, String)
+     * @see #openFileHelper(Uri, String)
+     * @see #getType(android.net.Uri)
+     */
+    public AssetFileDescriptor openAssetFile(Uri uri, String mode, CancellationSignal signal)
+            throws FileNotFoundException {
+        return openAssetFile(uri, mode);
+    }
+
+    /**
      * Convenience for subclasses that wish to implement {@link #openFile}
      * by looking up a column named "_data" at the given URI.
      *
@@ -1041,6 +1349,9 @@
      *
      * <p>See {@link ClipData} for examples of the use and implementation
      * of this method.
+     * <p>
+     * The returned AssetFileDescriptor can be a pipe or socket pair to enable
+     * streaming of data.
      *
      * <p class="note">For better interoperability with other applications, it is recommended
      * that for any URIs that can be opened, you also support queries on them
@@ -1086,6 +1397,64 @@
         throw new FileNotFoundException("Can't open " + uri + " as type " + mimeTypeFilter);
     }
 
+
+    /**
+     * Called by a client to open a read-only stream containing data of a
+     * particular MIME type.  This is like {@link #openAssetFile(Uri, String)},
+     * except the file can only be read-only and the content provider may
+     * perform data conversions to generate data of the desired type.
+     *
+     * <p>The default implementation compares the given mimeType against the
+     * result of {@link #getType(Uri)} and, if they match, simply calls
+     * {@link #openAssetFile(Uri, String)}.
+     *
+     * <p>See {@link ClipData} for examples of the use and implementation
+     * of this method.
+     * <p>
+     * The returned AssetFileDescriptor can be a pipe or socket pair to enable
+     * streaming of data.
+     *
+     * <p class="note">For better interoperability with other applications, it is recommended
+     * that for any URIs that can be opened, you also support queries on them
+     * containing at least the columns specified by {@link android.provider.OpenableColumns}.
+     * You may also want to support other common columns if you have additional meta-data
+     * to supply, such as {@link android.provider.MediaStore.MediaColumns#DATE_ADDED}
+     * in {@link android.provider.MediaStore.MediaColumns}.</p>
+     *
+     * @param uri The data in the content provider being queried.
+     * @param mimeTypeFilter The type of data the client desires.  May be
+     * a pattern, such as *\/*, if the caller does not have specific type
+     * requirements; in this case the content provider will pick its best
+     * type matching the pattern.
+     * @param opts Additional options from the client.  The definitions of
+     * these are specific to the content provider being called.
+     * @param signal A signal to cancel the operation in progress, or
+     *            {@code null} if none. For example, if you are downloading a
+     *            file from the network to service a "rw" mode request, you
+     *            should periodically call
+     *            {@link CancellationSignal#throwIfCanceled()} to check whether
+     *            the client has canceled the request and abort the download.
+     *
+     * @return Returns a new AssetFileDescriptor from which the client can
+     * read data of the desired type.
+     *
+     * @throws FileNotFoundException Throws FileNotFoundException if there is
+     * no file associated with the given URI or the mode is invalid.
+     * @throws SecurityException Throws SecurityException if the caller does
+     * not have permission to access the data.
+     * @throws IllegalArgumentException Throws IllegalArgumentException if the
+     * content provider does not support the requested MIME type.
+     *
+     * @see #getStreamTypes(Uri, String)
+     * @see #openAssetFile(Uri, String)
+     * @see ClipDescription#compareMimeTypes(String, String)
+     */
+    public AssetFileDescriptor openTypedAssetFile(
+            Uri uri, String mimeTypeFilter, Bundle opts, CancellationSignal signal)
+            throws FileNotFoundException {
+        return openTypedAssetFile(uri, mimeTypeFilter, opts);
+    }
+
     /**
      * Interface to write a stream of data to a pipe.  Use with
      * {@link ContentProvider#openPipeHelper}.
@@ -1204,6 +1573,8 @@
          */
         if (mContext == null) {
             mContext = context;
+            mTransport.mAppOpsManager = (AppOpsManager) mContext.getSystemService(
+                    Context.APP_OPS_SERVICE);
             mMyUid = Process.myUid();
             if (info != null) {
                 setReadPermission(info.readPermission);
@@ -1243,15 +1614,6 @@
     }
 
     /**
-     * @hide
-     * Front-end to {@link #call(String, String, android.os.Bundle)} that provides the name
-     * of the calling package.
-     */
-    public Bundle callFromPackage(String callingPackag, String method, String arg, Bundle extras) {
-        return call(method, arg, extras);
-    }
-
-    /**
      * Call a provider-defined method.  This can be used to implement
      * interfaces that are cheaper and/or unnatural for a table-like
      * model.
diff --git a/core/java/android/content/ContentProviderClient.java b/core/java/android/content/ContentProviderClient.java
index 8dffac7..39b453d 100644
--- a/core/java/android/content/ContentProviderClient.java
+++ b/core/java/android/content/ContentProviderClient.java
@@ -63,14 +63,7 @@
     /** See {@link ContentProvider#query ContentProvider.query} */
     public Cursor query(Uri url, String[] projection, String selection,
             String[] selectionArgs, String sortOrder) throws RemoteException {
-        try {
-            return query(url, projection, selection,  selectionArgs, sortOrder, null);
-        } catch (DeadObjectException e) {
-            if (!mStable) {
-                mContentResolver.unstableProviderDied(mContentProvider);
-            }
-            throw e;
-        }
+        return query(url, projection, selection,  selectionArgs, sortOrder, null);
     }
 
     /** See {@link ContentProvider#query ContentProvider.query} */
@@ -79,6 +72,7 @@
                     throws RemoteException {
         ICancellationSignal remoteCancellationSignal = null;
         if (cancellationSignal != null) {
+            cancellationSignal.throwIfCanceled();
             remoteCancellationSignal = mContentProvider.createCancellationSignal();
             cancellationSignal.setRemote(remoteCancellationSignal);
         }
@@ -117,6 +111,30 @@
         }
     }
 
+    /** See {@link ContentProvider#canonicalize} */
+    public final Uri canonicalize(Uri url) throws RemoteException {
+        try {
+            return mContentProvider.canonicalize(mPackageName, url);
+        } catch (DeadObjectException e) {
+            if (!mStable) {
+                mContentResolver.unstableProviderDied(mContentProvider);
+            }
+            throw e;
+        }
+    }
+
+    /** See {@link ContentProvider#uncanonicalize} */
+    public final Uri uncanonicalize(Uri url) throws RemoteException {
+        try {
+            return mContentProvider.uncanonicalize(mPackageName, url);
+        } catch (DeadObjectException e) {
+            if (!mStable) {
+                mContentResolver.unstableProviderDied(mContentProvider);
+            }
+            throw e;
+        }
+    }
+
     /** See {@link ContentProvider#insert ContentProvider.insert} */
     public Uri insert(Uri url, ContentValues initialValues)
             throws RemoteException {
@@ -177,8 +195,26 @@
      */
     public ParcelFileDescriptor openFile(Uri url, String mode)
             throws RemoteException, FileNotFoundException {
+        return openFile(url, mode, null);
+    }
+
+    /**
+     * See {@link ContentProvider#openFile ContentProvider.openFile}.  Note that
+     * this <em>does not</em>
+     * take care of non-content: URIs such as file:.  It is strongly recommended
+     * you use the {@link ContentResolver#openFileDescriptor
+     * ContentResolver.openFileDescriptor} API instead.
+     */
+    public ParcelFileDescriptor openFile(Uri url, String mode, CancellationSignal signal)
+            throws RemoteException, FileNotFoundException {
+        ICancellationSignal remoteSignal = null;
+        if (signal != null) {
+            signal.throwIfCanceled();
+            remoteSignal = mContentProvider.createCancellationSignal();
+            signal.setRemote(remoteSignal);
+        }
         try {
-            return mContentProvider.openFile(mPackageName, url, mode);
+            return mContentProvider.openFile(mPackageName, url, mode, remoteSignal);
         } catch (DeadObjectException e) {
             if (!mStable) {
                 mContentResolver.unstableProviderDied(mContentProvider);
@@ -196,8 +232,26 @@
      */
     public AssetFileDescriptor openAssetFile(Uri url, String mode)
             throws RemoteException, FileNotFoundException {
+        return openAssetFile(url, mode, null);
+    }
+
+    /**
+     * See {@link ContentProvider#openAssetFile ContentProvider.openAssetFile}.
+     * Note that this <em>does not</em>
+     * take care of non-content: URIs such as file:.  It is strongly recommended
+     * you use the {@link ContentResolver#openAssetFileDescriptor
+     * ContentResolver.openAssetFileDescriptor} API instead.
+     */
+    public AssetFileDescriptor openAssetFile(Uri url, String mode, CancellationSignal signal)
+            throws RemoteException, FileNotFoundException {
+        ICancellationSignal remoteSignal = null;
+        if (signal != null) {
+            signal.throwIfCanceled();
+            remoteSignal = mContentProvider.createCancellationSignal();
+            signal.setRemote(remoteSignal);
+        }
         try {
-            return mContentProvider.openAssetFile(mPackageName, url, mode);
+            return mContentProvider.openAssetFile(mPackageName, url, mode, remoteSignal);
         } catch (DeadObjectException e) {
             if (!mStable) {
                 mContentResolver.unstableProviderDied(mContentProvider);
@@ -208,10 +262,23 @@
 
     /** See {@link ContentProvider#openTypedAssetFile ContentProvider.openTypedAssetFile} */
     public final AssetFileDescriptor openTypedAssetFileDescriptor(Uri uri,
-            String mimeType, Bundle opts)
+            String mimeType, Bundle opts) throws RemoteException, FileNotFoundException {
+        return openTypedAssetFileDescriptor(uri, mimeType, opts, null);
+    }
+
+    /** See {@link ContentProvider#openTypedAssetFile ContentProvider.openTypedAssetFile} */
+    public final AssetFileDescriptor openTypedAssetFileDescriptor(Uri uri,
+            String mimeType, Bundle opts, CancellationSignal signal)
             throws RemoteException, FileNotFoundException {
+        ICancellationSignal remoteSignal = null;
+        if (signal != null) {
+            signal.throwIfCanceled();
+            remoteSignal = mContentProvider.createCancellationSignal();
+            signal.setRemote(remoteSignal);
+        }
         try {
-            return mContentProvider.openTypedAssetFile(mPackageName, uri, mimeType, opts);
+            return mContentProvider.openTypedAssetFile(
+                    mPackageName, uri, mimeType, opts, remoteSignal);
         } catch (DeadObjectException e) {
             if (!mStable) {
                 mContentResolver.unstableProviderDied(mContentProvider);
@@ -277,4 +344,14 @@
     public ContentProvider getLocalContentProvider() {
         return ContentProvider.coerceToLocalContentProvider(mContentProvider);
     }
+
+    /** {@hide} */
+    public static void closeQuietly(ContentProviderClient client) {
+        if (client != null) {
+            try {
+                client.release();
+            } catch (Exception ignored) {
+            }
+        }
+    }
 }
diff --git a/core/java/android/content/ContentProviderNative.java b/core/java/android/content/ContentProviderNative.java
index 6f822c1..bcf0b63 100644
--- a/core/java/android/content/ContentProviderNative.java
+++ b/core/java/android/content/ContentProviderNative.java
@@ -18,22 +18,20 @@
 
 import android.content.res.AssetFileDescriptor;
 import android.database.BulkCursorDescriptor;
-import android.database.BulkCursorNative;
 import android.database.BulkCursorToCursorAdaptor;
 import android.database.Cursor;
 import android.database.CursorToBulkCursorAdaptor;
 import android.database.DatabaseUtils;
-import android.database.IBulkCursor;
 import android.database.IContentObserver;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
-import android.os.RemoteException;
 import android.os.IBinder;
 import android.os.ICancellationSignal;
 import android.os.Parcel;
 import android.os.ParcelFileDescriptor;
 import android.os.Parcelable;
+import android.os.RemoteException;
 
 import java.io.FileNotFoundException;
 import java.util.ArrayList;
@@ -227,9 +225,11 @@
                     String callingPkg = data.readString();
                     Uri url = Uri.CREATOR.createFromParcel(data);
                     String mode = data.readString();
+                    ICancellationSignal signal = ICancellationSignal.Stub.asInterface(
+                            data.readStrongBinder());
 
                     ParcelFileDescriptor fd;
-                    fd = openFile(callingPkg, url, mode);
+                    fd = openFile(callingPkg, url, mode, signal);
                     reply.writeNoException();
                     if (fd != null) {
                         reply.writeInt(1);
@@ -247,9 +247,11 @@
                     String callingPkg = data.readString();
                     Uri url = Uri.CREATOR.createFromParcel(data);
                     String mode = data.readString();
+                    ICancellationSignal signal = ICancellationSignal.Stub.asInterface(
+                            data.readStrongBinder());
 
                     AssetFileDescriptor fd;
-                    fd = openAssetFile(callingPkg, url, mode);
+                    fd = openAssetFile(callingPkg, url, mode, signal);
                     reply.writeNoException();
                     if (fd != null) {
                         reply.writeInt(1);
@@ -296,9 +298,11 @@
                     Uri url = Uri.CREATOR.createFromParcel(data);
                     String mimeType = data.readString();
                     Bundle opts = data.readBundle();
+                    ICancellationSignal signal = ICancellationSignal.Stub.asInterface(
+                            data.readStrongBinder());
 
                     AssetFileDescriptor fd;
-                    fd = openTypedAssetFile(callingPkg, url, mimeType, opts);
+                    fd = openTypedAssetFile(callingPkg, url, mimeType, opts, signal);
                     reply.writeNoException();
                     if (fd != null) {
                         reply.writeInt(1);
@@ -319,6 +323,30 @@
                     reply.writeStrongBinder(cancellationSignal.asBinder());
                     return true;
                 }
+
+                case CANONICALIZE_TRANSACTION:
+                {
+                    data.enforceInterface(IContentProvider.descriptor);
+                    String callingPkg = data.readString();
+                    Uri url = Uri.CREATOR.createFromParcel(data);
+
+                    Uri out = canonicalize(callingPkg, url);
+                    reply.writeNoException();
+                    Uri.writeToParcel(reply, out);
+                    return true;
+                }
+
+                case UNCANONICALIZE_TRANSACTION:
+                {
+                    data.enforceInterface(IContentProvider.descriptor);
+                    String callingPkg = data.readString();
+                    Uri url = Uri.CREATOR.createFromParcel(data);
+
+                    Uri out = uncanonicalize(callingPkg, url);
+                    reply.writeNoException();
+                    Uri.writeToParcel(reply, out);
+                    return true;
+                }
             }
         } catch (Exception e) {
             DatabaseUtils.writeExceptionToParcel(reply, e);
@@ -538,7 +566,9 @@
         }
     }
 
-    public ParcelFileDescriptor openFile(String callingPkg, Uri url, String mode)
+    @Override
+    public ParcelFileDescriptor openFile(
+            String callingPkg, Uri url, String mode, ICancellationSignal signal)
             throws RemoteException, FileNotFoundException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
@@ -548,6 +578,7 @@
             data.writeString(callingPkg);
             url.writeToParcel(data, 0);
             data.writeString(mode);
+            data.writeStrongBinder(signal != null ? signal.asBinder() : null);
 
             mRemote.transact(IContentProvider.OPEN_FILE_TRANSACTION, data, reply, 0);
 
@@ -561,7 +592,9 @@
         }
     }
 
-    public AssetFileDescriptor openAssetFile(String callingPkg, Uri url, String mode)
+    @Override
+    public AssetFileDescriptor openAssetFile(
+            String callingPkg, Uri url, String mode, ICancellationSignal signal)
             throws RemoteException, FileNotFoundException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
@@ -571,6 +604,7 @@
             data.writeString(callingPkg);
             url.writeToParcel(data, 0);
             data.writeString(mode);
+            data.writeStrongBinder(signal != null ? signal.asBinder() : null);
 
             mRemote.transact(IContentProvider.OPEN_ASSET_FILE_TRANSACTION, data, reply, 0);
 
@@ -629,8 +663,9 @@
         }
     }
 
+    @Override
     public AssetFileDescriptor openTypedAssetFile(String callingPkg, Uri url, String mimeType,
-            Bundle opts) throws RemoteException, FileNotFoundException {
+            Bundle opts, ICancellationSignal signal) throws RemoteException, FileNotFoundException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         try {
@@ -640,6 +675,7 @@
             url.writeToParcel(data, 0);
             data.writeString(mimeType);
             data.writeBundle(opts);
+            data.writeStrongBinder(signal != null ? signal.asBinder() : null);
 
             mRemote.transact(IContentProvider.OPEN_TYPED_ASSET_FILE_TRANSACTION, data, reply, 0);
 
@@ -673,5 +709,46 @@
         }
     }
 
+    public Uri canonicalize(String callingPkg, Uri url) throws RemoteException
+    {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        try {
+            data.writeInterfaceToken(IContentProvider.descriptor);
+
+            data.writeString(callingPkg);
+            url.writeToParcel(data, 0);
+
+            mRemote.transact(IContentProvider.CANONICALIZE_TRANSACTION, data, reply, 0);
+
+            DatabaseUtils.readExceptionFromParcel(reply);
+            Uri out = Uri.CREATOR.createFromParcel(reply);
+            return out;
+        } finally {
+            data.recycle();
+            reply.recycle();
+        }
+    }
+
+    public Uri uncanonicalize(String callingPkg, Uri url) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        try {
+            data.writeInterfaceToken(IContentProvider.descriptor);
+
+            data.writeString(callingPkg);
+            url.writeToParcel(data, 0);
+
+            mRemote.transact(IContentProvider.UNCANONICALIZE_TRANSACTION, data, reply, 0);
+
+            DatabaseUtils.readExceptionFromParcel(reply);
+            Uri out = Uri.CREATOR.createFromParcel(reply);
+            return out;
+        } finally {
+            data.recycle();
+            reply.recycle();
+        }
+    }
+
     private IBinder mRemote;
 }
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index fefd343..f250029 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -16,8 +16,6 @@
 
 package android.content;
 
-import dalvik.system.CloseGuard;
-
 import android.accounts.Account;
 import android.app.ActivityManagerNative;
 import android.app.ActivityThread;
@@ -45,6 +43,8 @@
 import android.util.EventLog;
 import android.util.Log;
 
+import dalvik.system.CloseGuard;
+
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
@@ -55,7 +55,6 @@
 import java.util.List;
 import java.util.Random;
 
-
 /**
  * This class provides applications access to the content model.
  *
@@ -72,7 +71,13 @@
      */
     @Deprecated
     public static final String SYNC_EXTRAS_ACCOUNT = "account";
+
+    /**
+     * If this extra is set to true, the sync request will be scheduled
+     * at the front of the sync request queue and without any delay
+     */
     public static final String SYNC_EXTRAS_EXPEDITED = "expedited";
+
     /**
      * @deprecated instead use
      * {@link #SYNC_EXTRAS_MANUAL}
@@ -104,10 +109,40 @@
      */
     public static final String SYNC_EXTRAS_MANUAL = "force";
 
+    /**
+     * Indicates that this sync is intended to only upload local changes to the server.
+     * For example, this will be set to true if the sync is initiated by a call to
+     * {@link ContentResolver#notifyChange(android.net.Uri, android.database.ContentObserver, boolean)}
+     */
     public static final String SYNC_EXTRAS_UPLOAD = "upload";
+
+    /**
+     * Indicates that the sync adapter should proceed with the delete operations,
+     * even if it determines that there are too many.
+     * See {@link SyncResult#tooManyDeletions}
+     */
     public static final String SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS = "deletions_override";
+
+    /**
+     * Indicates that the sync adapter should not proceed with the delete operations,
+     * if it determines that there are too many.
+     * See {@link SyncResult#tooManyDeletions}
+     */
     public static final String SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS = "discard_deletions";
 
+    /* Extensions to API. TODO: Not clear if we will keep these as public flags. */
+    /** {@hide} User-specified flag for expected upload size. */
+    public static final String SYNC_EXTRAS_EXPECTED_UPLOAD = "expected_upload";
+
+    /** {@hide} User-specified flag for expected download size. */
+    public static final String SYNC_EXTRAS_EXPECTED_DOWNLOAD = "expected_download";
+
+    /** {@hide} Priority of this sync with respect to other syncs scheduled for this application. */
+    public static final String SYNC_EXTRAS_PRIORITY = "sync_priority";
+
+    /** {@hide} Flag to allow sync to occur on metered network. */
+    public static final String SYNC_EXTRAS_DISALLOW_METERED = "disallow_metered";
+
     /**
      * Set by the SyncManager to request that the SyncAdapter initialize itself for
      * the given account/authority pair. One required initialization step is to
@@ -220,12 +255,13 @@
 
     // Always log queries which take 500ms+; shorter queries are
     // sampled accordingly.
+    private static final boolean ENABLE_CONTENT_SAMPLE = false;
     private static final int SLOW_THRESHOLD_MILLIS = 500;
     private final Random mRandom = new Random();  // guarded by itself
 
     public ContentResolver(Context context) {
         mContext = context != null ? context : ActivityThread.currentApplication();
-        mPackageName = mContext.getBasePackageName();
+        mPackageName = mContext.getOpPackageName();
     }
 
     /** @hide */
@@ -291,7 +327,7 @@
      * content URL can be returned when opened as as stream with
      * {@link #openTypedAssetFileDescriptor}.  Note that the types here are
      * not necessarily a superset of the type returned by {@link #getType} --
-     * many content providers can not return a raw stream for the structured
+     * many content providers cannot return a raw stream for the structured
      * data that they contain.
      *
      * @param url A Uri identifying content (either a list or specific type),
@@ -448,6 +484,9 @@
             if (qCursor != null) {
                 qCursor.close();
             }
+            if (cancellationSignal != null) {
+                cancellationSignal.setRemote(null);
+            }
             if (unstableProvider != null) {
                 releaseUnstableProvider(unstableProvider);
             }
@@ -458,6 +497,88 @@
     }
 
     /**
+     * Transform the given <var>url</var> to a canonical representation of
+     * its referenced resource, which can be used across devices, persisted,
+     * backed up and restored, etc.  The returned Uri is still a fully capable
+     * Uri for use with its content provider, allowing you to do all of the
+     * same content provider operations as with the original Uri --
+     * {@link #query}, {@link #openInputStream(android.net.Uri)}, etc.  The
+     * only difference in behavior between the original and new Uris is that
+     * the content provider may need to do some additional work at each call
+     * using it to resolve it to the correct resource, especially if the
+     * canonical Uri has been moved to a different environment.
+     *
+     * <p>If you are moving a canonical Uri between environments, you should
+     * perform another call to {@link #canonicalize} with that original Uri to
+     * re-canonicalize it for the current environment.  Alternatively, you may
+     * want to use {@link #uncanonicalize} to transform it to a non-canonical
+     * Uri that works only in the current environment but potentially more
+     * efficiently than the canonical representation.</p>
+     *
+     * @param url The {@link Uri} that is to be transformed to a canonical
+     * representation.  Like all resolver calls, the input can be either
+     * a non-canonical or canonical Uri.
+     *
+     * @return Returns the official canonical representation of <var>url</var>,
+     * or null if the content provider does not support a canonical representation
+     * of the given Uri.  Many providers may not support canonicalization of some
+     * or all of their Uris.
+     *
+     * @see #uncanonicalize
+     */
+    public final Uri canonicalize(Uri url) {
+        IContentProvider provider = acquireProvider(url);
+        if (provider == null) {
+            return null;
+        }
+
+        try {
+            return provider.canonicalize(mPackageName, url);
+        } catch (RemoteException e) {
+            // Arbitrary and not worth documenting, as Activity
+            // Manager will kill this process shortly anyway.
+            return null;
+        } finally {
+            releaseProvider(provider);
+        }
+    }
+
+    /**
+     * Given a canonical Uri previously generated by {@link #canonicalize}, convert
+     * it to its local non-canonical form.  This can be useful in some cases where
+     * you know that you will only be using the Uri in the current environment and
+     * want to avoid any possible overhead when using it with the content
+     * provider or want to verify that the referenced data exists at all in the
+     * new environment.
+     *
+     * @param url The canonical {@link Uri} that is to be convered back to its
+     * non-canonical form.
+     *
+     * @return Returns the non-canonical representation of <var>url</var>.  This will
+     * return null if data identified by the canonical Uri can not be found in
+     * the current environment; callers must always check for null and deal with
+     * that by appropriately falling back to an alternative.
+     *
+     * @see #canonicalize
+     */
+    public final Uri uncanonicalize(Uri url) {
+        IContentProvider provider = acquireProvider(url);
+        if (provider == null) {
+            return null;
+        }
+
+        try {
+            return provider.uncanonicalize(mPackageName, url);
+        } catch (RemoteException e) {
+            // Arbitrary and not worth documenting, as Activity
+            // Manager will kill this process shortly anyway.
+            return null;
+        } finally {
+            releaseProvider(provider);
+        }
+    }
+
+    /**
      * Open a stream on to the content associated with a content URI.  If there
      * is no data associated with the URI, FileNotFoundException is thrown.
      *
@@ -494,7 +615,7 @@
             // with sufficient testing.
             return new FileInputStream(uri.getPath());
         } else {
-            AssetFileDescriptor fd = openAssetFileDescriptor(uri, "r");
+            AssetFileDescriptor fd = openAssetFileDescriptor(uri, "r", null);
             try {
                 return fd != null ? fd.createInputStream() : null;
             } catch (IOException e) {
@@ -534,7 +655,7 @@
      */
     public final OutputStream openOutputStream(Uri uri, String mode)
             throws FileNotFoundException {
-        AssetFileDescriptor fd = openAssetFileDescriptor(uri, mode);
+        AssetFileDescriptor fd = openAssetFileDescriptor(uri, mode, null);
         try {
             return fd != null ? fd.createOutputStream() : null;
         } catch (IOException e) {
@@ -560,6 +681,15 @@
      *
      * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information
      * on these schemes.
+     * <p>
+     * If opening with the exclusive "r" or "w" modes, the returned
+     * ParcelFileDescriptor could be a pipe or socket pair to enable streaming
+     * of data. Opening with the "rw" mode implies a file on disk that supports
+     * seeking. If possible, always use an exclusive mode to give the underlying
+     * {@link ContentProvider} the most flexibility.
+     * <p>
+     * If you are writing a file, and need to communicate an error to the
+     * provider, use {@link ParcelFileDescriptor#closeWithError(String)}.
      *
      * @param uri The desired URI to open.
      * @param mode The file mode to use, as per {@link ContentProvider#openFile
@@ -570,9 +700,54 @@
      * file exists under the URI or the mode is invalid.
      * @see #openAssetFileDescriptor(Uri, String)
      */
+    public final ParcelFileDescriptor openFileDescriptor(Uri uri, String mode)
+            throws FileNotFoundException {
+        return openFileDescriptor(uri, mode, null);
+    }
+
+    /**
+     * Open a raw file descriptor to access data under a URI.  This
+     * is like {@link #openAssetFileDescriptor(Uri, String)}, but uses the
+     * underlying {@link ContentProvider#openFile}
+     * ContentProvider.openFile()} method, so will <em>not</em> work with
+     * providers that return sub-sections of files.  If at all possible,
+     * you should use {@link #openAssetFileDescriptor(Uri, String)}.  You
+     * will receive a FileNotFoundException exception if the provider returns a
+     * sub-section of a file.
+     *
+     * <h5>Accepts the following URI schemes:</h5>
+     * <ul>
+     * <li>content ({@link #SCHEME_CONTENT})</li>
+     * <li>file ({@link #SCHEME_FILE})</li>
+     * </ul>
+     *
+     * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information
+     * on these schemes.
+     * <p>
+     * If opening with the exclusive "r" or "w" modes, the returned
+     * ParcelFileDescriptor could be a pipe or socket pair to enable streaming
+     * of data. Opening with the "rw" mode implies a file on disk that supports
+     * seeking. If possible, always use an exclusive mode to give the underlying
+     * {@link ContentProvider} the most flexibility.
+     * <p>
+     * If you are writing a file, and need to communicate an error to the
+     * provider, use {@link ParcelFileDescriptor#closeWithError(String)}.
+     *
+     * @param uri The desired URI to open.
+     * @param mode The file mode to use, as per {@link ContentProvider#openFile
+     * ContentProvider.openFile}.
+     * @param cancellationSignal A signal to cancel the operation in progress,
+     *         or null if none. If the operation is canceled, then
+     *         {@link OperationCanceledException} will be thrown.
+     * @return Returns a new ParcelFileDescriptor pointing to the file.  You
+     * own this descriptor and are responsible for closing it when done.
+     * @throws FileNotFoundException Throws FileNotFoundException if no
+     * file exists under the URI or the mode is invalid.
+     * @see #openAssetFileDescriptor(Uri, String)
+     */
     public final ParcelFileDescriptor openFileDescriptor(Uri uri,
-            String mode) throws FileNotFoundException {
-        AssetFileDescriptor afd = openAssetFileDescriptor(uri, mode);
+            String mode, CancellationSignal cancellationSignal) throws FileNotFoundException {
+        AssetFileDescriptor afd = openAssetFileDescriptor(uri, mode, cancellationSignal);
         if (afd == null) {
             return null;
         }
@@ -640,8 +815,64 @@
      * @throws FileNotFoundException Throws FileNotFoundException of no
      * file exists under the URI or the mode is invalid.
      */
+    public final AssetFileDescriptor openAssetFileDescriptor(Uri uri, String mode)
+            throws FileNotFoundException {
+        return openAssetFileDescriptor(uri, mode, null);
+    }
+
+    /**
+     * Open a raw file descriptor to access data under a URI.  This
+     * interacts with the underlying {@link ContentProvider#openAssetFile}
+     * method of the provider associated with the given URI, to retrieve any file stored there.
+     *
+     * <h5>Accepts the following URI schemes:</h5>
+     * <ul>
+     * <li>content ({@link #SCHEME_CONTENT})</li>
+     * <li>android.resource ({@link #SCHEME_ANDROID_RESOURCE})</li>
+     * <li>file ({@link #SCHEME_FILE})</li>
+     * </ul>
+     * <h5>The android.resource ({@link #SCHEME_ANDROID_RESOURCE}) Scheme</h5>
+     * <p>
+     * A Uri object can be used to reference a resource in an APK file.  The
+     * Uri should be one of the following formats:
+     * <ul>
+     * <li><code>android.resource://package_name/id_number</code><br/>
+     * <code>package_name</code> is your package name as listed in your AndroidManifest.xml.
+     * For example <code>com.example.myapp</code><br/>
+     * <code>id_number</code> is the int form of the ID.<br/>
+     * The easiest way to construct this form is
+     * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/" + R.raw.my_resource");</pre>
+     * </li>
+     * <li><code>android.resource://package_name/type/name</code><br/>
+     * <code>package_name</code> is your package name as listed in your AndroidManifest.xml.
+     * For example <code>com.example.myapp</code><br/>
+     * <code>type</code> is the string form of the resource type.  For example, <code>raw</code>
+     * or <code>drawable</code>.
+     * <code>name</code> is the string form of the resource name.  That is, whatever the file
+     * name was in your res directory, without the type extension.
+     * The easiest way to construct this form is
+     * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/raw/my_resource");</pre>
+     * </li>
+     * </ul>
+     *
+     * <p>Note that if this function is called for read-only input (mode is "r")
+     * on a content: URI, it will instead call {@link #openTypedAssetFileDescriptor}
+     * for you with a MIME type of "*\/*".  This allows such callers to benefit
+     * from any built-in data conversion that a provider implements.
+     *
+     * @param uri The desired URI to open.
+     * @param mode The file mode to use, as per {@link ContentProvider#openAssetFile
+     * ContentProvider.openAssetFile}.
+     * @param cancellationSignal A signal to cancel the operation in progress, or null if
+     *            none. If the operation is canceled, then
+     *            {@link OperationCanceledException} will be thrown.
+     * @return Returns a new ParcelFileDescriptor pointing to the file.  You
+     * own this descriptor and are responsible for closing it when done.
+     * @throws FileNotFoundException Throws FileNotFoundException of no
+     * file exists under the URI or the mode is invalid.
+     */
     public final AssetFileDescriptor openAssetFileDescriptor(Uri uri,
-            String mode) throws FileNotFoundException {
+            String mode, CancellationSignal cancellationSignal) throws FileNotFoundException {
         String scheme = uri.getScheme();
         if (SCHEME_ANDROID_RESOURCE.equals(scheme)) {
             if (!"r".equals(mode)) {
@@ -659,7 +890,7 @@
             return new AssetFileDescriptor(pfd, 0, -1);
         } else {
             if ("r".equals(mode)) {
-                return openTypedAssetFileDescriptor(uri, "*/*", null);
+                return openTypedAssetFileDescriptor(uri, "*/*", null, cancellationSignal);
             } else {
                 IContentProvider unstableProvider = acquireUnstableProvider(uri);
                 if (unstableProvider == null) {
@@ -669,8 +900,16 @@
                 AssetFileDescriptor fd = null;
 
                 try {
+                    ICancellationSignal remoteCancellationSignal = null;
+                    if (cancellationSignal != null) {
+                        cancellationSignal.throwIfCanceled();
+                        remoteCancellationSignal = unstableProvider.createCancellationSignal();
+                        cancellationSignal.setRemote(remoteCancellationSignal);
+                    }
+
                     try {
-                        fd = unstableProvider.openAssetFile(mPackageName, uri, mode);
+                        fd = unstableProvider.openAssetFile(
+                                mPackageName, uri, mode, remoteCancellationSignal);
                         if (fd == null) {
                             // The provider will be released by the finally{} clause
                             return null;
@@ -684,7 +923,8 @@
                         if (stableProvider == null) {
                             throw new FileNotFoundException("No content provider: " + uri);
                         }
-                        fd = stableProvider.openAssetFile(mPackageName, uri, mode);
+                        fd = stableProvider.openAssetFile(
+                                mPackageName, uri, mode, remoteCancellationSignal);
                         if (fd == null) {
                             // The provider will be released by the finally{} clause
                             return null;
@@ -712,6 +952,9 @@
                 } catch (FileNotFoundException e) {
                     throw e;
                 } finally {
+                    if (cancellationSignal != null) {
+                        cancellationSignal.setRemote(null);
+                    }
                     if (stableProvider != null) {
                         releaseProvider(stableProvider);
                     }
@@ -751,8 +994,45 @@
      * @throws FileNotFoundException Throws FileNotFoundException of no
      * data of the desired type exists under the URI.
      */
+    public final AssetFileDescriptor openTypedAssetFileDescriptor(
+            Uri uri, String mimeType, Bundle opts) throws FileNotFoundException {
+        return openTypedAssetFileDescriptor(uri, mimeType, opts, null);
+    }
+
+    /**
+     * Open a raw file descriptor to access (potentially type transformed)
+     * data from a "content:" URI.  This interacts with the underlying
+     * {@link ContentProvider#openTypedAssetFile} method of the provider
+     * associated with the given URI, to retrieve retrieve any appropriate
+     * data stream for the data stored there.
+     *
+     * <p>Unlike {@link #openAssetFileDescriptor}, this function only works
+     * with "content:" URIs, because content providers are the only facility
+     * with an associated MIME type to ensure that the returned data stream
+     * is of the desired type.
+     *
+     * <p>All text/* streams are encoded in UTF-8.
+     *
+     * @param uri The desired URI to open.
+     * @param mimeType The desired MIME type of the returned data.  This can
+     * be a pattern such as *\/*, which will allow the content provider to
+     * select a type, though there is no way for you to determine what type
+     * it is returning.
+     * @param opts Additional provider-dependent options.
+     * @param cancellationSignal A signal to cancel the operation in progress,
+     *         or null if none. If the operation is canceled, then
+     *         {@link OperationCanceledException} will be thrown.
+     * @return Returns a new ParcelFileDescriptor from which you can read the
+     * data stream from the provider.  Note that this may be a pipe, meaning
+     * you can't seek in it.  The only seek you should do is if the
+     * AssetFileDescriptor contains an offset, to move to that offset before
+     * reading.  You own this descriptor and are responsible for closing it when done.
+     * @throws FileNotFoundException Throws FileNotFoundException of no
+     * data of the desired type exists under the URI.
+     */
     public final AssetFileDescriptor openTypedAssetFileDescriptor(Uri uri,
-            String mimeType, Bundle opts) throws FileNotFoundException {
+            String mimeType, Bundle opts, CancellationSignal cancellationSignal)
+            throws FileNotFoundException {
         IContentProvider unstableProvider = acquireUnstableProvider(uri);
         if (unstableProvider == null) {
             throw new FileNotFoundException("No content provider: " + uri);
@@ -761,8 +1041,16 @@
         AssetFileDescriptor fd = null;
 
         try {
+            ICancellationSignal remoteCancellationSignal = null;
+            if (cancellationSignal != null) {
+                cancellationSignal.throwIfCanceled();
+                remoteCancellationSignal = unstableProvider.createCancellationSignal();
+                cancellationSignal.setRemote(remoteCancellationSignal);
+            }
+
             try {
-                fd = unstableProvider.openTypedAssetFile(mPackageName, uri, mimeType, opts);
+                fd = unstableProvider.openTypedAssetFile(
+                        mPackageName, uri, mimeType, opts, remoteCancellationSignal);
                 if (fd == null) {
                     // The provider will be released by the finally{} clause
                     return null;
@@ -776,7 +1064,8 @@
                 if (stableProvider == null) {
                     throw new FileNotFoundException("No content provider: " + uri);
                 }
-                fd = stableProvider.openTypedAssetFile(mPackageName, uri, mimeType, opts);
+                fd = stableProvider.openTypedAssetFile(
+                        mPackageName, uri, mimeType, opts, remoteCancellationSignal);
                 if (fd == null) {
                     // The provider will be released by the finally{} clause
                     return null;
@@ -804,6 +1093,9 @@
         } catch (FileNotFoundException e) {
             throw e;
         } finally {
+            if (cancellationSignal != null) {
+                cancellationSignal.setRemote(null);
+            }
             if (stableProvider != null) {
                 releaseProvider(stableProvider);
             }
@@ -1351,6 +1643,58 @@
     }
 
     /**
+     * Return list of all Uri permissions that have been granted <em>to</em> the
+     * calling package, and which exactly match the requested flags. For
+     * example, to return all Uris that the calling application has
+     * <em>non-persistent</em> read access to:
+     *
+     * <pre class="prettyprint">
+     * getIncomingUriPermissionGrants(Intent.FLAG_GRANT_READ_URI_PERMISSION,
+     *         Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_PERSIST_GRANT_URI_PERMISSION);
+     * </pre>
+     *
+     * @param modeFlags any combination of
+     *            {@link Intent#FLAG_GRANT_READ_URI_PERMISSION},
+     *            {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION}, or
+     *            {@link Intent#FLAG_PERSIST_GRANT_URI_PERMISSION}.
+     * @param modeMask mask indicating which flags must match.
+     */
+    public Uri[] getIncomingUriPermissionGrants(int modeFlags, int modeMask) {
+        try {
+            return ActivityManagerNative.getDefault()
+                    .getGrantedUriPermissions(null, getPackageName(), modeFlags, modeMask);
+        } catch (RemoteException e) {
+            return new Uri[0];
+        }
+    }
+
+    /**
+     * Return list of all Uri permissions that have been granted <em>from</em> the
+     * calling package, and which exactly match the requested flags. For
+     * example, to return all Uris that the calling application has granted
+     * <em>non-persistent</em> read access to:
+     *
+     * <pre class="prettyprint">
+     * getOutgoingUriPermissionGrants(Intent.FLAG_GRANT_READ_URI_PERMISSION,
+     *         Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_PERSIST_GRANT_URI_PERMISSION);
+     * </pre>
+     *
+     * @param modeFlags any combination of
+     *            {@link Intent#FLAG_GRANT_READ_URI_PERMISSION},
+     *            {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION}, or
+     *            {@link Intent#FLAG_PERSIST_GRANT_URI_PERMISSION}.
+     * @param modeMask mask indicating which flags must match.
+     */
+    public Uri[] getOutgoingUriPermissionGrants(int modeFlags, int modeMask) {
+        try {
+            return ActivityManagerNative.getDefault()
+                    .getGrantedUriPermissions(getPackageName(), null, modeFlags, modeMask);
+        } catch (RemoteException e) {
+            return new Uri[0];
+        }
+    }
+
+    /**
      * Start an asynchronous sync operation. If you want to monitor the progress
      * of the sync you may register a SyncObserver. Only values of the following
      * types may be used in the extras bundle:
@@ -1361,6 +1705,8 @@
      * <li>Float</li>
      * <li>Double</li>
      * <li>String</li>
+     * <li>Account</li>
+     * <li>null</li>
      * </ul>
      *
      * @param uri the uri of the provider to sync or null to sync all providers.
@@ -1392,6 +1738,8 @@
      * <li>Float</li>
      * <li>Double</li>
      * <li>String</li>
+     * <li>Account</li>
+     * <li>null</li>
      * </ul>
      *
      * @param account which account should be synced
@@ -1399,10 +1747,30 @@
      * @param extras any extras to pass to the SyncAdapter.
      */
     public static void requestSync(Account account, String authority, Bundle extras) {
-        validateSyncExtrasBundle(extras);
+        if (extras == null) {
+            throw new IllegalArgumentException("Must specify extras.");
+        }
+        SyncRequest request =
+            new SyncRequest.Builder()
+                .setSyncAdapter(account, authority)
+                .setExtras(extras)
+                .syncOnce()
+                .build();
+        requestSync(request);
+    }
+
+    /**
+     * Register a sync with the SyncManager. These requests are built using the
+     * {@link SyncRequest.Builder}.
+     *
+     * @param request The immutable SyncRequest object containing the sync parameters. Use
+     * {@link SyncRequest.Builder} to construct these.
+     */
+    public static void requestSync(SyncRequest request) {
         try {
-            getContentService().requestSync(account, authority, extras);
-        } catch (RemoteException e) {
+            getContentService().sync(request);
+        } catch(RemoteException e) {
+            // Shouldn't happen.
         }
     }
 
@@ -1532,6 +1900,9 @@
      * {@link #SYNC_EXTRAS_INITIALIZE}, {@link #SYNC_EXTRAS_FORCE},
      * {@link #SYNC_EXTRAS_EXPEDITED}, {@link #SYNC_EXTRAS_MANUAL} set to true.
      * If any are supplied then an {@link IllegalArgumentException} will be thrown.
+     * <p>As of API level 19 this function introduces a default flexibility of ~4% (up to a maximum
+     * of one hour in the day) into the requested period. Use
+     * {@link SyncRequest.Builder#syncPeriodic(long, long)} to set this flexibility manually.
      *
      * <p>This method requires the caller to hold the permission
      * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}.
@@ -1562,7 +1933,7 @@
             throw new IllegalArgumentException("illegal extras were set");
         }
         try {
-            getContentService().addPeriodicSync(account, authority, extras, pollFrequency);
+             getContentService().addPeriodicSync(account, authority, extras, pollFrequency);
         } catch (RemoteException e) {
             // exception ignored; if this is thrown then it means the runtime is in the midst of
             // being restarted
@@ -1832,6 +2203,7 @@
     private void maybeLogQueryToEventLog(long durationMillis,
                                          Uri uri, String[] projection,
                                          String selection, String sortOrder) {
+        if (!ENABLE_CONTENT_SAMPLE) return;
         int samplePercent = samplePercentForDuration(durationMillis);
         if (samplePercent < 100) {
             synchronized (mRandom) {
@@ -1871,6 +2243,7 @@
 
     private void maybeLogUpdateToEventLog(
         long durationMillis, Uri uri, String operation, String selection) {
+        if (!ENABLE_CONTENT_SAMPLE) return;
         int samplePercent = samplePercentForDuration(durationMillis);
         if (samplePercent < 100) {
             synchronized (mRandom) {
@@ -1935,7 +2308,7 @@
 
     private final class ParcelFileDescriptorInner extends ParcelFileDescriptor {
         private final IContentProvider mContentProvider;
-        private boolean mReleaseProviderFlag = false;
+        private boolean mProviderReleased;
 
         ParcelFileDescriptorInner(ParcelFileDescriptor pfd, IContentProvider icp) {
             super(pfd);
@@ -1944,17 +2317,10 @@
 
         @Override
         public void close() throws IOException {
-            if(!mReleaseProviderFlag) {
-                super.close();
+            super.close();
+            if (!mProviderReleased) {
                 ContentResolver.this.releaseProvider(mContentProvider);
-                mReleaseProviderFlag = true;
-            }
-        }
-
-        @Override
-        protected void finalize() throws Throwable {
-            if (!mReleaseProviderFlag) {
-                close();
+                mProviderReleased = true;
             }
         }
     }
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 5bd28b9..92a9c7c 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -35,7 +35,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.AttributeSet;
-import android.view.CompatibilityInfoHolder;
+import android.view.DisplayAdjustments;
 import android.view.Display;
 import android.view.WindowManager;
 
@@ -45,7 +45,6 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.List;
 
 /**
  * Interface to global information about an application environment.  This is
@@ -231,7 +230,15 @@
      * tries to balance such requests from one app vs. the importantance of
      * keeping other apps around.
      */
-    public static final int BIND_VISIBLE = 0x0100;
+    public static final int BIND_VISIBLE = 0x10000000;
+
+    /**
+     * @hide
+     * Flag for {@link #bindService}: Consider this binding to be causing the target
+     * process to be showing UI, so it will be do a UI_HIDDEN memory trim when it goes
+     * away.
+     */
+    public static final int BIND_SHOWING_UI = 0x20000000;
 
     /**
      * Flag for {@link #bindService}: Don't consider the bound service to be
@@ -307,7 +314,7 @@
     }
 
     /**
-     * Remove a {@link ComponentCallbacks} objec that was previously registered
+     * Remove a {@link ComponentCallbacks} object that was previously registered
      * with {@link #registerComponentCallbacks(ComponentCallbacks)}.
      */
     public void unregisterComponentCallbacks(ComponentCallbacks callback) {
@@ -428,6 +435,13 @@
     /** @hide Return the name of the base context this context is derived from. */
     public abstract String getBasePackageName();
 
+    /** @hide Return the package name that should be used for app ops calls from
+     * this context.  This is the same as {@link #getBasePackageName()} except in
+     * cases where system components are loaded into other app processes, in which
+     * case this will be the name of the primary package in that process (so that app
+     * ops uid verification will work with the name). */
+    public abstract String getOpPackageName();
+
     /** Return the full application info for this context's package. */
     public abstract ApplicationInfo getApplicationInfo();
 
@@ -482,7 +496,7 @@
      * is always on in apps targetting Gingerbread (Android 2.3) and below, and
      * off by default in later versions.
      *
-     * @return Returns the single SharedPreferences instance that can be used
+     * @return The single {@link SharedPreferences} instance that can be used
      *         to retrieve and modify the preference values.
      *
      * @see #MODE_PRIVATE
@@ -500,7 +514,7 @@
      * @param name The name of the file to open; can not contain path
      *             separators.
      *
-     * @return FileInputStream Resulting input stream.
+     * @return The resulting {@link FileInputStream}.
      *
      * @see #openFileOutput
      * @see #fileList
@@ -521,7 +535,7 @@
      * {@link #MODE_WORLD_READABLE} and {@link #MODE_WORLD_WRITEABLE} to control
      * permissions.
      *
-     * @return FileOutputStream Resulting output stream.
+     * @return The resulting {@link FileOutputStream}.
      *
      * @see #MODE_APPEND
      * @see #MODE_PRIVATE
@@ -542,8 +556,8 @@
      * @param name The name of the file to delete; can not contain path
      *             separators.
      *
-     * @return True if the file was successfully deleted; else
-     *         false.
+     * @return {@code true} if the file was successfully deleted; else
+     *         {@code false}.
      *
      * @see #openFileInput
      * @see #openFileOutput
@@ -559,7 +573,7 @@
      * @param name The name of the file for which you would like to get
      *          its path.
      *
-     * @return Returns an absolute path to the given file.
+     * @return An absolute path to the given file.
      *
      * @see #openFileOutput
      * @see #getFilesDir
@@ -571,7 +585,7 @@
      * Returns the absolute path to the directory on the filesystem where
      * files created with {@link #openFileOutput} are stored.
      *
-     * @return Returns the path of the directory holding application files.
+     * @return The path of the directory holding application files.
      *
      * @see #openFileOutput
      * @see #getFileStreamPath
@@ -583,7 +597,7 @@
      * Returns the absolute path to the directory on the external filesystem
      * (that is somewhere on {@link android.os.Environment#getExternalStorageDirectory()
      * Environment.getExternalStorageDirectory()}) where the application can
-     * place persistent files it owns.  These files are private to the
+     * place persistent files it owns.  These files are internal to the
      * applications, and not typically visible to the user as media.
      *
      * <p>This is like {@link #getFilesDir()} in that these
@@ -630,9 +644,11 @@
      *
      * {@sample development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java
      * private_picture}
-     *
-     * <p>Writing to this path requires the
-     * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} permission.</p>
+     * <p>
+     * Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, no
+     * permissions are required for the owning application to read or write to
+     * this path. Otherwise, {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE}
+     * or {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} are required.
      *
      * @param type The type of files directory to return.  May be null for
      * the root of the files directory or one of
@@ -645,7 +661,7 @@
      * {@link android.os.Environment#DIRECTORY_PICTURES}, or
      * {@link android.os.Environment#DIRECTORY_MOVIES}.
      *
-     * @return Returns the path of the directory holding application files
+     * @return The path of the directory holding application files
      * on external storage.  Returns null if external storage is not currently
      * mounted so it could not ensure the path exists; you will need to call
      * this method again when it is available.
@@ -656,18 +672,66 @@
     public abstract File getExternalFilesDir(String type);
 
     /**
-     * Return the directory where this application's OBB files (if there
-     * are any) can be found.  Note if the application does not have any OBB
-     * files, this directory may not exist.
+     * Returns absolute paths to application-specific directories on all
+     * external storage devices where the application can place persistent files
+     * it owns. These files are internal to the application, and not typically
+     * visible to the user as media.
+     * <p>
+     * External storage devices returned here are considered a permanent part of
+     * the device, including both emulated external storage and physical media
+     * slots. This does not include transient devices, such as USB flash drives.
+     * <p>
+     * Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, no
+     * permissions are required for the owning application to read or write to
+     * these paths.
+     * <p>
+     * The returned paths include any path that would be returned by
+     * {@link #getExternalFilesDir(String)}.
      *
-     * <p>On devices with multiple users (as described by {@link UserManager}),
+     * @see #getExternalFilesDir(String)
+     */
+    public abstract File[] getExternalFilesDirs(String type);
+
+    /**
+     * Return the directory where this application's OBB files (if there are
+     * any) can be found. Note if the application does not have any OBB files,
+     * this directory may not exist.
+     * <p>
+     * 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 interfere with each other.</p>
+     * should ensure that multiple instances running under different users don't
+     * interfere with each other.
+     * <p>
+     * Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, no
+     * permissions are required for the owning application to read or write to
+     * this path. Otherwise,
+     * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} or
+     * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} are required.
      */
     public abstract File getObbDir();
 
     /**
+     * Returns absolute paths to application-specific directories on all
+     * external storage devices where the application's OBB files (if there are
+     * any) can be found. Note if the application does not have any OBB files,
+     * these directories may not exist.
+     * <p>
+     * External storage devices returned here are considered a permanent part of
+     * the device, including both emulated external storage and physical media
+     * slots. This does not include transient devices, such as USB flash drives.
+     * <p>
+     * Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, no
+     * permissions are required for the owning application to read or write to
+     * this path.
+     * <p>
+     * The returned paths include any path that would be returned by
+     * {@link #getObbDir()}
+     *
+     * @see #getObbDir()
+     */
+    public abstract File[] getObbDirs();
+
+    /**
      * Returns the absolute path to the application specific cache directory
      * on the filesystem. These files will be ones that get deleted first when the
      * device runs low on storage.
@@ -678,7 +742,7 @@
      * for the amount of space you consume with cache files, and prune those
      * files when exceeding that space.</strong>
      *
-     * @return Returns the path of the directory holding application cache files.
+     * @return The path of the directory holding application cache files.
      *
      * @see #openFileOutput
      * @see #getFileStreamPath
@@ -690,7 +754,8 @@
      * Returns the absolute path to the directory on the external filesystem
      * (that is somewhere on {@link android.os.Environment#getExternalStorageDirectory()
      * Environment.getExternalStorageDirectory()} where the application can
-     * place cache files it owns.
+     * place cache files it owns. These files are internal to the application, and
+     * not typically visible to the user as media.
      *
      * <p>This is like {@link #getCacheDir()} in that these
      * files will be deleted when the application is uninstalled, however there
@@ -715,11 +780,14 @@
      * <p>On devices with multiple users (as described by {@link UserManager}),
      * each user has their own isolated external storage. Applications only
      * have access to the external storage for the user they're running as.</p>
+     * <p>
+     * Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, no
+     * permissions are required for the owning application to read or write to
+     * this path. Otherwise,
+     * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} or
+     * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} are required.
      *
-     * <p>Writing to this path requires the
-     * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} permission.</p>
-     *
-     * @return Returns the path of the directory holding application cache files
+     * @return The path of the directory holding application cache files
      * on external storage.  Returns null if external storage is not currently
      * mounted so it could not ensure the path exists; you will need to call
      * this method again when it is available.
@@ -729,6 +797,27 @@
     public abstract File getExternalCacheDir();
 
     /**
+     * Returns absolute paths to application-specific directories on all
+     * external storage devices where the application can place cache files it
+     * owns. These files are internal to the application, and not typically
+     * visible to the user as media.
+     * <p>
+     * External storage devices returned here are considered a permanent part of
+     * the device, including both emulated external storage and physical media
+     * slots. This does not include transient devices, such as USB flash drives.
+     * <p>
+     * Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, no
+     * permissions are required for the owning application to read or write to
+     * these paths.
+     * <p>
+     * The returned paths include any path that would be returned by
+     * {@link #getExternalCacheDir()}.
+     *
+     * @see #getExternalCacheDir()
+     */
+    public abstract File[] getExternalCacheDirs();
+
+    /**
      * Returns an array of strings naming the private files associated with
      * this Context's application package.
      *
@@ -754,7 +843,7 @@
      * default operation, {@link #MODE_WORLD_READABLE} and
      * {@link #MODE_WORLD_WRITEABLE} to control permissions.
      *
-     * @return Returns a File object for the requested directory.  The directory
+     * @return A {@link File} object for the requested directory.  The directory
      * will have been created if it does not already exist.
      *
      * @see #openFileOutput(String, int)
@@ -820,7 +909,7 @@
      * @param name The name (unique in the application package) of the
      *             database.
      *
-     * @return True if the database was successfully deleted; else false.
+     * @return {@code true} if the database was successfully deleted; else {@code false}.
      *
      * @see #openOrCreateDatabase
      */
@@ -833,7 +922,7 @@
      * @param name The name of the database for which you would like to get
      *          its path.
      *
-     * @return Returns an absolute path to the given database.
+     * @return An absolute path to the given database.
      *
      * @see #openOrCreateDatabase
      */
@@ -911,9 +1000,9 @@
      *
      * @param intent The description of the activity to start.
      *
-     * @throws ActivityNotFoundException
+     * @throws ActivityNotFoundException &nbsp;
      *
-     * @see {@link #startActivity(Intent, Bundle)}
+     * @see #startActivity(Intent, Bundle)
      * @see PackageManager#resolveActivity
      */
     public abstract void startActivity(Intent intent);
@@ -925,7 +1014,7 @@
      * the INTERACT_ACROSS_USERS_FULL permission.
      * @param intent The description of the activity to start.
      * @param user The UserHandle of the user to start this activity for.
-     * @throws ActivityNotFoundException
+     * @throws ActivityNotFoundException &nbsp;
      * @hide
      */
     public void startActivityAsUser(Intent intent, UserHandle user) {
@@ -952,7 +1041,7 @@
      * for how to build the Bundle supplied here; there are no supported definitions
      * for building it manually.
      *
-     * @throws ActivityNotFoundException
+     * @throws ActivityNotFoundException &nbsp;
      *
      * @see #startActivity(Intent)
      * @see PackageManager#resolveActivity
@@ -969,8 +1058,8 @@
      * May be null if there are no options.  See {@link android.app.ActivityOptions}
      * for how to build the Bundle supplied here; there are no supported definitions
      * for building it manually.
-     * @param user The UserHandle of the user to start this activity for.
-     * @throws ActivityNotFoundException
+     * @param userId The UserHandle of the user to start this activity for.
+     * @throws ActivityNotFoundException &nbsp;
      * @hide
      */
     public void startActivityAsUser(Intent intent, Bundle options, UserHandle userId) {
@@ -983,9 +1072,9 @@
      *
      * @param intents An array of Intents to be started.
      *
-     * @throws ActivityNotFoundException
+     * @throws ActivityNotFoundException &nbsp;
      *
-     * @see {@link #startActivities(Intent[], Bundle)}
+     * @see #startActivities(Intent[], Bundle)
      * @see PackageManager#resolveActivity
      */
     public abstract void startActivities(Intent[] intents);
@@ -1009,9 +1098,9 @@
      * See {@link android.content.Context#startActivity(Intent, Bundle)
      * Context.startActivity(Intent, Bundle)} for more details.
      *
-     * @throws ActivityNotFoundException
+     * @throws ActivityNotFoundException &nbsp;
      *
-     * @see {@link #startActivities(Intent[])}
+     * @see #startActivities(Intent[])
      * @see PackageManager#resolveActivity
      */
     public abstract void startActivities(Intent[] intents, Bundle options);
@@ -1037,9 +1126,9 @@
      * See {@link android.content.Context#startActivity(Intent, Bundle)
      * Context.startActivity(Intent, Bundle)} for more details.
      *
-     * @throws ActivityNotFoundException
+     * @throws ActivityNotFoundException &nbsp;
      *
-     * @see {@link #startActivities(Intent[])}
+     * @see #startActivities(Intent[])
      * @see PackageManager#resolveActivity
      */
     public void startActivitiesAsUser(Intent[] intents, Bundle options, UserHandle userHandle) {
@@ -1566,9 +1655,11 @@
 
     /**
      * Request that a given application service be started.  The Intent
-     * can either contain the complete class name of a specific service
-     * implementation to start, or an abstract definition through the
-     * action and other fields of the kind of service to start.  If this service
+     * should contain either contain the complete class name of a specific service
+     * implementation to start or a specific package name to target.  If the
+     * Intent is less specified, it will either throw an {@link IllegalArgumentException}
+     * (if the caller targets {@link android.os.Build.VERSION_CODES#KITKAT} or later),
+     * or which of multiple matching services it finds and uses will be undefined.  If this service
      * is not already running, it will be instantiated and started (creating a
      * process for it if needed); if it is running then it remains running.
      *
@@ -1594,10 +1685,9 @@
      * <p>This function will throw {@link SecurityException} if you do not
      * have permission to start the given service.
      *
-     * @param service Identifies the service to be started.  The Intent may
-     *      specify either an explicit component name to start, or a logical
-     *      description (action, category, etc) to match an
-     *      {@link IntentFilter} published by a service.  Additional values
+     * @param service Identifies the service to be started.  The Intent must be either
+     *      fully explicit (supplying a component name) or specify a specific package
+     *      name it is targetted to.  Additional values
      *      may be included in the Intent extras to supply arguments along with
      *      this specific start call.
      *
@@ -1605,7 +1695,7 @@
      * {@link ComponentName} of the actual service that was started is
      * returned; else if the service does not exist null is returned.
      *
-     * @throws SecurityException
+     * @throws SecurityException &nbsp;
      *
      * @see #stopService
      * @see #bindService
@@ -1627,15 +1717,14 @@
      * <p>This function will throw {@link SecurityException} if you do not
      * have permission to stop the given service.
      *
-     * @param service Description of the service to be stopped.  The Intent may
-     *      specify either an explicit component name to start, or a logical
-     *      description (action, category, etc) to match an
-     *      {@link IntentFilter} published by a service.
+     * @param service Description of the service to be stopped.  The Intent must be either
+     *      fully explicit (supplying a component name) or specify a specific package
+     *      name it is targetted to.
      *
      * @return If there is a service matching the given Intent that is already
-     * running, then it is stopped and true is returned; else false is returned.
+     * running, then it is stopped and {@code true} is returned; else {@code false} is returned.
      *
-     * @throws SecurityException
+     * @throws SecurityException &nbsp;
      *
      * @see #startService
      */
@@ -1686,11 +1775,11 @@
      *          {@link #BIND_NOT_FOREGROUND}, {@link #BIND_ABOVE_CLIENT},
      *          {@link #BIND_ALLOW_OOM_MANAGEMENT}, or
      *          {@link #BIND_WAIVE_PRIORITY}.
-     * @return If you have successfully bound to the service, true is returned;
-     *         false is returned if the connection is not made so you will not
+     * @return If you have successfully bound to the service, {@code true} is returned;
+     *         {@code false} is returned if the connection is not made so you will not
      *         receive the service object.
      *
-     * @throws SecurityException
+     * @throws SecurityException &nbsp;
      *
      * @see #unbindService
      * @see #startService
@@ -1742,8 +1831,8 @@
      * @param arguments Additional optional arguments to pass to the
      * instrumentation, or null.
      *
-     * @return Returns true if the instrumentation was successfully started,
-     * else false if it could not be found.
+     * @return {@code true} if the instrumentation was successfully started,
+     * else {@code false} if it could not be found.
      */
     public abstract boolean startInstrumentation(ComponentName className,
             String profileFile, Bundle arguments);
@@ -1929,6 +2018,17 @@
 
     /**
      * Use with {@link #getSystemService} to retrieve a
+     * {@link android.view.accessibility.CaptioningManager} for obtaining
+     * captioning properties and listening for changes in captioning
+     * preferences.
+     *
+     * @see #getSystemService
+     * @see android.view.accessibility.CaptioningManager
+     */
+    public static final String CAPTIONING_SERVICE = "captioning";
+
+    /**
+     * Use with {@link #getSystemService} to retrieve a
      * {@link android.app.NotificationManager} for controlling keyguard.
      *
      * @see #getSystemService
@@ -2218,7 +2318,7 @@
      * and for controlling this device's behavior as a USB device.
      *
      * @see #getSystemService
-     * @see android.harware.usb.UsbManager
+     * @see android.hardware.usb.UsbManager
      */
     public static final String USB_SERVICE = "usb";
 
@@ -2278,12 +2378,39 @@
      *
      * @see #getSystemService
      * @see android.app.AppOpsManager
-     *
-     * @hide
      */
     public static final String APP_OPS_SERVICE = "appops";
 
     /**
+     * Use with {@link #getSystemService} to retrieve a
+     * {@link android.hardware.camera2.CameraManager} for interacting with
+     * camera devices.
+     *
+     * @see #getSystemService
+     * @see android.hardware.camera2.CameraManager
+     */
+    public static final String CAMERA_SERVICE = "camera";
+
+    /**
+     * {@link android.print.PrintManager} for printing and managing
+     * printers and print tasks.
+     *
+     * @see #getSystemService
+     * @see android.print.PrintManager
+     */
+    public static final String PRINT_SERVICE = "print";
+
+    /**
+     * Use with {@link #getSystemService} to retrieve a
+     * {@link android.hardware.ConsumerIrManager} for transmitting infrared
+     * signals from the device.
+     *
+     * @see #getSystemService
+     * @see android.hardware.ConsumerIrManager
+     */
+    public static final String CONSUMER_IR_SERVICE = "consumer_ir";
+
+    /**
      * Determine whether the given permission is allowed for a particular
      * process and user ID running in the system.
      *
@@ -2292,7 +2419,7 @@
      * @param uid The user ID being checked against.  A uid of 0 is the root
      * user, which will pass every permission check.
      *
-     * @return Returns {@link PackageManager#PERMISSION_GRANTED} if the given
+     * @return {@link PackageManager#PERMISSION_GRANTED} if the given
      * pid/uid is allowed that permission, or
      * {@link PackageManager#PERMISSION_DENIED} if it is not.
      *
@@ -2314,7 +2441,7 @@
      *
      * @param permission The name of the permission being checked.
      *
-     * @return Returns {@link PackageManager#PERMISSION_GRANTED} if the calling
+     * @return {@link PackageManager#PERMISSION_GRANTED} if the calling
      * pid/uid is allowed that permission, or
      * {@link PackageManager#PERMISSION_DENIED} if it is not.
      *
@@ -2332,7 +2459,7 @@
      *
      * @param permission The name of the permission being checked.
      *
-     * @return Returns {@link PackageManager#PERMISSION_GRANTED} if the calling
+     * @return {@link PackageManager#PERMISSION_GRANTED} if the calling
      * pid/uid is allowed that permission, or
      * {@link PackageManager#PERMISSION_DENIED} if it is not.
      *
@@ -2434,7 +2561,7 @@
      * Remove all permissions to access a particular content provider Uri
      * that were previously added with {@link #grantUriPermission}.  The given
      * Uri will match all previously granted Uris that are the same or a
-     * sub-path of the given Uri.  That is, revoking "content://foo/one" will
+     * sub-path of the given Uri.  That is, revoking "content://foo/target" will
      * revoke both "content://foo/target" and "content://foo/target/sub", but not
      * "content://foo".
      *
@@ -2464,7 +2591,7 @@
      * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION Intent.FLAG_GRANT_READ_URI_PERMISSION} or
      * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION Intent.FLAG_GRANT_WRITE_URI_PERMISSION}.
      *
-     * @return Returns {@link PackageManager#PERMISSION_GRANTED} if the given
+     * @return {@link PackageManager#PERMISSION_GRANTED} if the given
      * pid/uid is allowed to access that uri, or
      * {@link PackageManager#PERMISSION_DENIED} if it is not.
      *
@@ -2487,7 +2614,7 @@
      * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION Intent.FLAG_GRANT_READ_URI_PERMISSION} or
      * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION Intent.FLAG_GRANT_WRITE_URI_PERMISSION}.
      *
-     * @return Returns {@link PackageManager#PERMISSION_GRANTED} if the caller
+     * @return {@link PackageManager#PERMISSION_GRANTED} if the caller
      * is allowed to access that uri, or
      * {@link PackageManager#PERMISSION_DENIED} if it is not.
      *
@@ -2506,7 +2633,7 @@
      * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION Intent.FLAG_GRANT_READ_URI_PERMISSION} or
      * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION Intent.FLAG_GRANT_WRITE_URI_PERMISSION}.
      *
-     * @return Returns {@link PackageManager#PERMISSION_GRANTED} if the caller
+     * @return {@link PackageManager#PERMISSION_GRANTED} if the caller
      * is allowed to access that uri, or
      * {@link PackageManager#PERMISSION_DENIED} if it is not.
      *
@@ -2532,7 +2659,7 @@
      * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION Intent.FLAG_GRANT_READ_URI_PERMISSION} or
      * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION Intent.FLAG_GRANT_WRITE_URI_PERMISSION}.
      *
-     * @return Returns {@link PackageManager#PERMISSION_GRANTED} if the caller
+     * @return {@link PackageManager#PERMISSION_GRANTED} if the caller
      * is allowed to access that uri or holds one of the given permissions, or
      * {@link PackageManager#PERMISSION_DENIED} if it is not.
      */
@@ -2676,11 +2803,11 @@
      * @param flags Option flags, one of {@link #CONTEXT_INCLUDE_CODE}
      *              or {@link #CONTEXT_IGNORE_SECURITY}.
      *
-     * @return A Context for the application.
+     * @return A {@link Context} for the application.
      *
-     * @throws java.lang.SecurityException
+     * @throws SecurityException &nbsp;
      * @throws PackageManager.NameNotFoundException if there is no application with
-     * the given package name
+     * the given package name.
      */
     public abstract Context createPackageContext(String packageName,
             int flags) throws PackageManager.NameNotFoundException;
@@ -2717,7 +2844,7 @@
      * orientation change), the resources of this context will also change except
      * for those that have been explicitly overridden with a value here.
      *
-     * @return A Context with the given configuration override.
+     * @return A {@link Context} with the given configuration override.
      */
     public abstract Context createConfigurationContext(Configuration overrideConfiguration);
 
@@ -2737,25 +2864,25 @@
      * for whose metrics the Context's resources should be tailored and upon which
      * new windows should be shown.
      *
-     * @return A Context for the display.
+     * @return A {@link Context} for the display.
      */
     public abstract Context createDisplayContext(Display display);
 
     /**
-     * Gets the compatibility info holder for this context.  This information
-     * is provided on a per-application basis and is used to simulate lower density
-     * display metrics for legacy applications.
+     * Gets the display adjustments holder for this context.  This information
+     * is provided on a per-application or activity basis and is used to simulate lower density
+     * display metrics for legacy applications and restricted screen sizes.
      *
      * @param displayId The display id for which to get compatibility info.
      * @return The compatibility info holder, or null if not required by the application.
      * @hide
      */
-    public abstract CompatibilityInfoHolder getCompatibilityInfo(int displayId);
+    public abstract DisplayAdjustments getDisplayAdjustments(int displayId);
 
     /**
      * Indicates whether this Context is restricted.
      *
-     * @return True if this Context is restricted, false otherwise.
+     * @return {@code true} if this Context is restricted, {@code false} otherwise.
      *
      * @see #CONTEXT_RESTRICTED
      */
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 2f1bf8c..a708dad 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -35,7 +35,7 @@
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.UserHandle;
-import android.view.CompatibilityInfoHolder;
+import android.view.DisplayAdjustments;
 import android.view.Display;
 
 import java.io.File;
@@ -141,6 +141,12 @@
         return mBase.getBasePackageName();
     }
 
+    /** @hide */
+    @Override
+    public String getOpPackageName() {
+        return mBase.getOpPackageName();
+    }
+
     @Override
     public ApplicationInfo getApplicationInfo() {
         return mBase.getApplicationInfo();
@@ -203,12 +209,22 @@
     public File getExternalFilesDir(String type) {
         return mBase.getExternalFilesDir(type);
     }
-    
+
+    @Override
+    public File[] getExternalFilesDirs(String type) {
+        return mBase.getExternalFilesDirs(type);
+    }
+
     @Override
     public File getObbDir() {
         return mBase.getObbDir();
     }
-    
+
+    @Override
+    public File[] getObbDirs() {
+        return mBase.getObbDirs();
+    }
+
     @Override
     public File getCacheDir() {
         return mBase.getCacheDir();
@@ -220,6 +236,11 @@
     }
 
     @Override
+    public File[] getExternalCacheDirs() {
+        return mBase.getExternalCacheDirs();
+    }
+
+    @Override
     public File getDir(String name, int mode) {
         return mBase.getDir(name, mode);
     }
@@ -646,7 +667,7 @@
 
     /** @hide */
     @Override
-    public CompatibilityInfoHolder getCompatibilityInfo(int displayId) {
-        return mBase.getCompatibilityInfo(displayId);
+    public DisplayAdjustments getDisplayAdjustments(int displayId) {
+        return mBase.getDisplayAdjustments(displayId);
     }
 }
diff --git a/core/java/android/content/IAnonymousSyncAdapter.aidl b/core/java/android/content/IAnonymousSyncAdapter.aidl
new file mode 100644
index 0000000..a80cea3
--- /dev/null
+++ b/core/java/android/content/IAnonymousSyncAdapter.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content;
+import android.os.Bundle;
+import android.content.ISyncContext;
+
+/**
+ * Interface to define an anonymous service that is extended by developers
+ * in order to perform anonymous syncs (syncs without an Account or Content
+ * Provider specified). See {@link android.content.AbstractThreadedSyncAdapter}.
+ * {@hide}
+ */
+oneway interface IAnonymousSyncAdapter {
+
+    /**
+     * Initiate a sync. SyncAdapter-specific parameters may be specified in
+     * extras, which is guaranteed to not be null.
+     *
+     * @param syncContext the ISyncContext used to indicate the progress of the sync. When
+     *   the sync is finished (successfully or not) ISyncContext.onFinished() must be called.
+     * @param extras SyncAdapter-specific parameters.
+     *
+     */
+    void startSync(ISyncContext syncContext, in Bundle extras);
+
+    /**
+     * Cancel the currently ongoing sync.
+     */
+    void cancelSync(ISyncContext syncContext);
+
+}
diff --git a/core/java/android/content/IContentProvider.java b/core/java/android/content/IContentProvider.java
index 62b79f0..f92a404 100644
--- a/core/java/android/content/IContentProvider.java
+++ b/core/java/android/content/IContentProvider.java
@@ -46,9 +46,11 @@
             throws RemoteException;
     public int update(String callingPkg, Uri url, ContentValues values, String selection,
             String[] selectionArgs) throws RemoteException;
-    public ParcelFileDescriptor openFile(String callingPkg, Uri url, String mode)
+    public ParcelFileDescriptor openFile(
+            String callingPkg, Uri url, String mode, ICancellationSignal signal)
             throws RemoteException, FileNotFoundException;
-    public AssetFileDescriptor openAssetFile(String callingPkg, Uri url, String mode)
+    public AssetFileDescriptor openAssetFile(
+            String callingPkg, Uri url, String mode, ICancellationSignal signal)
             throws RemoteException, FileNotFoundException;
     public ContentProviderResult[] applyBatch(String callingPkg,
             ArrayList<ContentProviderOperation> operations)
@@ -57,10 +59,13 @@
             throws RemoteException;
     public ICancellationSignal createCancellationSignal() throws RemoteException;
 
+    public Uri canonicalize(String callingPkg, Uri uri) throws RemoteException;
+    public Uri uncanonicalize(String callingPkg, Uri uri) throws RemoteException;
+
     // Data interchange.
     public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException;
     public AssetFileDescriptor openTypedAssetFile(String callingPkg, Uri url, String mimeType,
-            Bundle opts) throws RemoteException, FileNotFoundException;
+            Bundle opts, ICancellationSignal signal) throws RemoteException, FileNotFoundException;
 
     /* IPC constants */
     static final String descriptor = "android.content.IContentProvider";
@@ -78,4 +83,6 @@
     static final int GET_STREAM_TYPES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 21;
     static final int OPEN_TYPED_ASSET_FILE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 22;
     static final int CREATE_CANCELATION_SIGNAL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 23;
+    static final int CANONICALIZE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 24;
+    static final int UNCANONICALIZE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 25;
 }
diff --git a/core/java/android/content/IContentService.aidl b/core/java/android/content/IContentService.aidl
index f956bcf..9ad5a19 100644
--- a/core/java/android/content/IContentService.aidl
+++ b/core/java/android/content/IContentService.aidl
@@ -20,6 +20,7 @@
 import android.content.SyncInfo;
 import android.content.ISyncStatusObserver;
 import android.content.SyncAdapterType;
+import android.content.SyncRequest;
 import android.content.SyncStatusInfo;
 import android.content.PeriodicSync;
 import android.net.Uri;
@@ -54,6 +55,7 @@
             int userHandle);
 
     void requestSync(in Account account, String authority, in Bundle extras);
+    void sync(in SyncRequest request);
     void cancelSync(in Account account, String authority);
 
     /**
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 330b7e5..7925123 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -16,6 +16,8 @@
 
 package android.content;
 
+import android.content.pm.ApplicationInfo;
+import android.util.ArraySet;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -33,6 +35,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.StrictMode;
+import android.provider.DocumentsContract;
 import android.util.AttributeSet;
 import android.util.Log;
 
@@ -42,8 +45,8 @@
 import java.io.Serializable;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Locale;
 import java.util.Set;
 
@@ -1150,9 +1153,9 @@
     /**
      * Activity Action: Perform assist action.
      * <p>
-     * Input: {@link #EXTRA_ASSIST_PACKAGE} and {@link #EXTRA_ASSIST_CONTEXT} can provide
-     * additional optional contextual information about where the user was when they requested
-     * the assist.
+     * Input: {@link #EXTRA_ASSIST_PACKAGE}, {@link #EXTRA_ASSIST_CONTEXT}, can provide
+     * additional optional contextual information about where the user was when they
+     * requested the assist.
      * Output: nothing.
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
@@ -1161,9 +1164,9 @@
     /**
      * Activity Action: Perform voice assist action.
      * <p>
-     * Input: {@link #EXTRA_ASSIST_PACKAGE} and {@link #EXTRA_ASSIST_CONTEXT} can provide
-     * additional optional contextual information about where the user was when they requested
-     * the voice assist.
+     * Input: {@link #EXTRA_ASSIST_PACKAGE}, {@link #EXTRA_ASSIST_CONTEXT}, can provide
+     * additional optional contextual information about where the user was when they
+     * requested the voice assist.
      * Output: nothing.
      * @hide
      */
@@ -1171,18 +1174,16 @@
     public static final String ACTION_VOICE_ASSIST = "android.intent.action.VOICE_ASSIST";
 
     /**
-     * An optional field on {@link #ACTION_ASSIST}
-     * containing the name of the current foreground application package at the time
-     * the assist was invoked.
+     * An optional field on {@link #ACTION_ASSIST} containing the name of the current foreground
+     * application package at the time the assist was invoked.
      */
     public static final String EXTRA_ASSIST_PACKAGE
             = "android.intent.extra.ASSIST_PACKAGE";
 
     /**
-     * An optional field on {@link #ACTION_ASSIST}
-     * containing additional contextual information supplied by the current
-     * foreground app at the time of the assist request.  This is a {@link Bundle} of
-     * additional data.
+     * An optional field on {@link #ACTION_ASSIST} and containing additional contextual
+     * information supplied by the current foreground app at the time of the assist request.
+     * This is a {@link Bundle} of additional data.
      */
     public static final String EXTRA_ASSIST_CONTEXT
             = "android.intent.extra.ASSIST_CONTEXT";
@@ -1459,7 +1460,7 @@
     /**
      * Broadcast Action: The current time has changed.  Sent every
      * minute.  You can <em>not</em> receive this through components declared
-     * in manifests, only by exlicitly registering for it with
+     * in manifests, only by explicitly registering for it with
      * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)
      * Context.registerReceiver()}.
      *
@@ -1897,6 +1898,11 @@
      *
      * <p class="note">This is a protected intent that can only be sent
      * by the system.
+     * <p>May include the following extras:
+     * <ul>
+     * <li> {@link #EXTRA_SHUTDOWN_USERSPACE_ONLY} a boolean that is set to true if this
+     * shutdown is only for userspace processes.  If not set, assumed to be false.
+     * </ul>
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_SHUTDOWN = "android.intent.action.ACTION_SHUTDOWN";
@@ -2441,6 +2447,21 @@
             "android.intent.action.GET_RESTRICTION_ENTRIES";
 
     /**
+     * @hide
+     * Activity to challenge the user for a PIN that was configured when setting up
+     * restrictions. Restrictions include blocking of apps and preventing certain user operations,
+     * controlled by {@link android.os.UserManager#setUserRestrictions(Bundle).
+     * Launch the activity using
+     * {@link android.app.Activity#startActivityForResult(Intent, int)} and check if the
+     * result is {@link android.app.Activity#RESULT_OK} for a successful response to the
+     * challenge.<p/>
+     * Before launching this activity, make sure that there is a PIN in effect, by calling
+     * {@link android.os.UserManager#hasRestrictionsChallenge()}.
+     */
+    public static final String ACTION_RESTRICTIONS_CHALLENGE =
+            "android.intent.action.RESTRICTIONS_CHALLENGE";
+
+    /**
      * Sent the first time a user is starting, to allow system apps to
      * perform one time initialization.  (This will not be seen by third
      * party applications because a newly initialized user does not have any
@@ -2599,6 +2620,54 @@
      */
     public static final String ACTION_GLOBAL_BUTTON = "android.intent.action.GLOBAL_BUTTON";
 
+    /**
+     * Activity Action: Allow the user to select and open one or more existing
+     * documents. Both read and write access to the documents will be granted
+     * until explicitly revoked by the user.
+     * <p>
+     * Callers can restrict selection to a specific kind of data, such as
+     * photos, by setting one or more MIME types in {@link #EXTRA_MIME_TYPES}.
+     * <p>
+     * If the caller can handle multiple returned items (the user performing
+     * multiple selection), then it can specify {@link #EXTRA_ALLOW_MULTIPLE} to
+     * indicate this.
+     * <p>
+     * Callers must include {@link #CATEGORY_OPENABLE} in the Intent so that
+     * returned URIs can be opened with
+     * {@link ContentResolver#openFileDescriptor(Uri, String)}.
+     * <p>
+     * Output: The URI of the item that was picked. This must be a content: URI
+     * so that any receiver can access it. If multiple documents were selected,
+     * they are returned in {@link #getClipData()}.
+     *
+     * @see DocumentsContract
+     * @see DocumentsContract#getOpenDocuments(Context)
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_OPEN_DOCUMENT = "android.intent.action.OPEN_DOCUMENT";
+
+    /**
+     * Activity Action: Allow the user to create a new document. Both read and
+     * write access to the document will be granted until explicitly revoked by
+     * the user.
+     * <p>
+     * Callers can provide a hint document name by setting {@link #EXTRA_TITLE},
+     * but the user may change this value before creating the file. Callers can
+     * optionally hint at the MIME type being created by setting
+     * {@link #setType(String)}.
+     * <p>
+     * Callers must include {@link #CATEGORY_OPENABLE} in the Intent so that
+     * returned URIs can be opened with
+     * {@link ContentResolver#openFileDescriptor(Uri, String)}.
+     * <p>
+     * Output: The URI of the item that was created. This must be a content: URI
+     * so that any receiver can access it.
+     *
+     * @see DocumentsContract
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_CREATE_DOCUMENT = "android.intent.action.CREATE_DOCUMENT";
+
     // ---------------------------------------------------------------------
     // ---------------------------------------------------------------------
     // Standard intent categories (see addCategory()).
@@ -2607,7 +2676,7 @@
      * Set if the activity should be an option for the default action
      * (center press) to perform on a piece of data.  Setting this will
      * hide from the user any activities without it set when performing an
-     * action on some data.  Note that this is normal -not- set in the
+     * action on some data.  Note that this is normally -not- set in the
      * Intent when initiating an action -- it is for use in intent filters
      * specified in packages.
      */
@@ -3202,6 +3271,24 @@
     public static final String EXTRA_RESTRICTIONS_INTENT =
             "android.intent.extra.restrictions_intent";
 
+    /**
+     * Extra used to communicate set of acceptable MIME types for
+     * {@link #ACTION_GET_CONTENT} or {@link #ACTION_OPEN_DOCUMENT}. The type of the
+     * extra is <code>ArrayList&lt;String&gt;</code>.
+     */
+    public static final String EXTRA_MIME_TYPES = "android.intent.extra.MIME_TYPES";
+
+    /**
+     * Optional extra for {@link #ACTION_SHUTDOWN} that allows the sender to qualify that
+     * this shutdown is only for the user space of the system, not a complete shutdown.
+     * When this is true, hardware devices can use this information to determine that
+     * they shouldn't do a complete shutdown of their device since this is not a
+     * complete shutdown down to the kernel, but only user space restarting.
+     * The default if not supplied is false.
+     */
+    public static final String EXTRA_SHUTDOWN_USERSPACE_ONLY
+            = "android.intent.extra.SHUTDOWN_USERSPACE_ONLY";
+
     // ---------------------------------------------------------------------
     // ---------------------------------------------------------------------
     // Intent flags (see mFlags variable).
@@ -3251,6 +3338,15 @@
     public static final int FLAG_INCLUDE_STOPPED_PACKAGES = 0x00000020;
 
     /**
+     * When combined with {@link #FLAG_GRANT_READ_URI_PERMISSION} and/or
+     * {@link #FLAG_GRANT_WRITE_URI_PERMISSION}, the grant will be remembered
+     * until explicitly revoked with
+     * {@link Context#revokeUriPermission(Uri, int)}. These grants persist
+     * across device reboots.
+     */
+    public static final int FLAG_PERSIST_GRANT_URI_PERMISSION = 0x00000040;
+
+    /**
      * If set, the new activity is not kept in the history stack.  As soon as
      * the user navigates away from it, the activity is finished.  This may also
      * be set with the {@link android.R.styleable#AndroidManifestActivity_noHistory
@@ -3542,7 +3638,7 @@
     private String mPackage;
     private ComponentName mComponent;
     private int mFlags;
-    private HashSet<String> mCategories;
+    private ArraySet<String> mCategories;
     private Bundle mExtras;
     private Rect mSourceBounds;
     private Intent mSelector;
@@ -3567,7 +3663,7 @@
         this.mComponent = o.mComponent;
         this.mFlags = o.mFlags;
         if (o.mCategories != null) {
-            this.mCategories = new HashSet<String>(o.mCategories);
+            this.mCategories = new ArraySet<String>(o.mCategories);
         }
         if (o.mExtras != null) {
             this.mExtras = new Bundle(o.mExtras);
@@ -3595,7 +3691,7 @@
         this.mPackage = o.mPackage;
         this.mComponent = o.mComponent;
         if (o.mCategories != null) {
-            this.mCategories = new HashSet<String>(o.mCategories);
+            this.mCategories = new ArraySet<String>(o.mCategories);
         }
     }
 
@@ -4953,6 +5049,39 @@
     }
 
     /**
+     * Special function for use by the system to resolve service
+     * intents to system apps.  Throws an exception if there are
+     * multiple potential matches to the Intent.  Returns null if
+     * there are no matches.
+     * @hide
+     */
+    public ComponentName resolveSystemService(PackageManager pm, int flags) {
+        if (mComponent != null) {
+            return mComponent;
+        }
+
+        List<ResolveInfo> results = pm.queryIntentServices(this, flags);
+        if (results == null) {
+            return null;
+        }
+        ComponentName comp = null;
+        for (int i=0; i<results.size(); i++) {
+            ResolveInfo ri = results.get(i);
+            if ((ri.serviceInfo.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
+                continue;
+            }
+            ComponentName foundComp = new ComponentName(ri.serviceInfo.applicationInfo.packageName,
+                    ri.serviceInfo.name);
+            if (comp != null) {
+                throw new IllegalStateException("Multiple system services handle " + this
+                        + ": " + comp + ", " + foundComp);
+            }
+            comp = foundComp;
+        }
+        return comp;
+    }
+
+    /**
      * Set the general action to be performed.
      *
      * @param action An action name, such as ACTION_VIEW.  Application-specific
@@ -4987,7 +5116,7 @@
      *
      * @see #getData
      * @see #setDataAndNormalize
-     * @see android.net.Intent#normalize
+     * @see android.net.Uri#normalizeScheme()
      */
     public Intent setData(Uri data) {
         mData = data;
@@ -5159,7 +5288,7 @@
      */
     public Intent addCategory(String category) {
         if (mCategories == null) {
-            mCategories = new HashSet<String>();
+            mCategories = new ArraySet<String>();
         }
         mCategories.add(category.intern());
         return this;
@@ -6303,7 +6432,7 @@
         if (other.mCategories != null
                 && (mCategories == null || (flags&FILL_IN_CATEGORIES) != 0)) {
             if (other.mCategories != null) {
-                mCategories = new HashSet<String>(other.mCategories);
+                mCategories = new ArraySet<String>(other.mCategories);
             }
             changes |= FILL_IN_CATEGORIES;
         }
@@ -6574,12 +6703,9 @@
             }
             first = false;
             b.append("cat=[");
-            Iterator<String> i = mCategories.iterator();
-            boolean didone = false;
-            while (i.hasNext()) {
-                if (didone) b.append(",");
-                didone = true;
-                b.append(i.next());
+            for (int i=0; i<mCategories.size(); i++) {
+                if (i > 0) b.append(',');
+                b.append(mCategories.valueAt(i));
             }
             b.append("]");
         }
@@ -6737,8 +6863,8 @@
             uri.append("action=").append(Uri.encode(mAction)).append(';');
         }
         if (mCategories != null) {
-            for (String category : mCategories) {
-                uri.append("category=").append(Uri.encode(category)).append(';');
+            for (int i=0; i<mCategories.size(); i++) {
+                uri.append("category=").append(Uri.encode(mCategories.valueAt(i))).append(';');
             }
         }
         if (mType != null) {
@@ -6806,9 +6932,10 @@
         }
 
         if (mCategories != null) {
-            out.writeInt(mCategories.size());
-            for (String category : mCategories) {
-                out.writeString(category);
+            final int N = mCategories.size();
+            out.writeInt(N);
+            for (int i=0; i<N; i++) {
+                out.writeString(mCategories.valueAt(i));
             }
         } else {
             out.writeInt(0);
@@ -6860,7 +6987,7 @@
 
         int N = in.readInt();
         if (N > 0) {
-            mCategories = new HashSet<String>();
+            mCategories = new ArraySet<String>();
             int i;
             for (i=0; i<N; i++) {
                 mCategories.add(in.readString().intern());
@@ -7039,7 +7166,8 @@
                     // and flags to ourselves to grant.
                     setClipData(target.getClipData());
                     addFlags(target.getFlags()
-                            & (FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION));
+                            & (FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION
+                                    | FLAG_PERSIST_GRANT_URI_PERMISSION));
                     return true;
                 } else {
                     return false;
diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java
index 5e65b59..5760a5d 100644
--- a/core/java/android/content/IntentFilter.java
+++ b/core/java/android/content/IntentFilter.java
@@ -50,8 +50,8 @@
  * <em>action</em>, <em>data</em>, and <em>categories</em>.  For each of these
  * characteristics you can provide
  * multiple possible matching values (via {@link #addAction},
- * {@link #addDataType}, {@link #addDataScheme} {@link #addDataAuthority},
- * {@link #addDataPath}, and {@link #addCategory}, respectively).
+ * {@link #addDataType}, {@link #addDataScheme}, {@link #addDataSchemeSpecificPart},
+ * {@link #addDataAuthority}, {@link #addDataPath}, and {@link #addCategory}, respectively).
  * For actions, the field
  * will not be tested if no values have been given (treating it as a wildcard);
  * if no data characteristics are specified, however, then the filter will
@@ -106,8 +106,15 @@
  * formal RFC schemes!</em>  You should thus always use lower case letters
  * for your schemes.
  *
+ * <p><strong>Data Scheme Specific Part</strong> matches if any of the given values match
+ * the Intent's data scheme specific part <em>and</em> one of the data schemes in the filter
+ * has matched the Intent, <em>or</em> no scheme specific parts were supplied in the filter.
+ * The Intent scheme specific part is determined by calling
+ * {@link Intent#getData} and {@link android.net.Uri#getSchemeSpecificPart} on that URI.
+ * <em>Note that scheme specific part matching is <b>case sensitive</b>.</em>
+ *
  * <p><strong>Data Authority</strong> matches if any of the given values match
- * the Intent's data authority <em>and</em> one of the data scheme's in the filter
+ * the Intent's data authority <em>and</em> one of the data schemes in the filter
  * has matched the Intent, <em>or</em> no authories were supplied in the filter.
  * The Intent authority is determined by calling
  * {@link Intent#getData} and {@link android.net.Uri#getAuthority} on that URI.
@@ -135,6 +142,7 @@
     private static final String PORT_STR = "port";
     private static final String HOST_STR = "host";
     private static final String AUTH_STR = "auth";
+    private static final String SSP_STR = "ssp";
     private static final String SCHEME_STR = "scheme";
     private static final String TYPE_STR = "type";
     private static final String CAT_STR = "cat";
@@ -164,8 +172,8 @@
     /**
      * The part of a match constant that describes the category of match
      * that occurred.  May be either {@link #MATCH_CATEGORY_EMPTY},
-     * {@link #MATCH_CATEGORY_SCHEME}, {@link #MATCH_CATEGORY_HOST},
-     * {@link #MATCH_CATEGORY_PORT},
+     * {@link #MATCH_CATEGORY_SCHEME}, {@link #MATCH_CATEGORY_SCHEME_SPECIFIC_PART},
+     * {@link #MATCH_CATEGORY_HOST}, {@link #MATCH_CATEGORY_PORT},
      * {@link #MATCH_CATEGORY_PATH}, or {@link #MATCH_CATEGORY_TYPE}.  Higher
      * values indicate a better match.
      */
@@ -210,6 +218,11 @@
      */
     public static final int MATCH_CATEGORY_PATH = 0x0500000;
     /**
+     * The filter matched an intent with the same data URI scheme and
+     * scheme specific part.
+     */
+    public static final int MATCH_CATEGORY_SCHEME_SPECIFIC_PART = 0x0580000;
+    /**
      * The filter matched an intent with the same data MIME type.
      */
     public static final int MATCH_CATEGORY_TYPE = 0x0600000;
@@ -236,6 +249,7 @@
     private final ArrayList<String> mActions;
     private ArrayList<String> mCategories = null;
     private ArrayList<String> mDataSchemes = null;
+    private ArrayList<PatternMatcher> mDataSchemeSpecificParts = null;
     private ArrayList<AuthorityEntry> mDataAuthorities = null;
     private ArrayList<PatternMatcher> mDataPaths = null;
     private ArrayList<String> mDataTypes = null;
@@ -395,6 +409,9 @@
         if (o.mDataSchemes != null) {
             mDataSchemes = new ArrayList<String>(o.mDataSchemes);
         }
+        if (o.mDataSchemeSpecificParts != null) {
+            mDataSchemeSpecificParts = new ArrayList<PatternMatcher>(o.mDataSchemeSpecificParts);
+        }
         if (o.mDataAuthorities != null) {
             mDataAuthorities = new ArrayList<AuthorityEntry>(o.mDataAuthorities);
         }
@@ -699,6 +716,80 @@
     };
 
     /**
+     * Add a new Intent data "scheme specific part" to match against.  The filter must
+     * include one or more schemes (via {@link #addDataScheme}) for the
+     * scheme specific part to be considered.  If any scheme specific parts are
+     * included in the filter, then an Intent's data must match one of
+     * them.  If no scheme specific parts are included, then only the scheme must match.
+     *
+     * @param ssp Either a raw string that must exactly match the scheme specific part
+     * path, or a simple pattern, depending on <var>type</var>.
+     * @param type Determines how <var>ssp</var> will be compared to
+     * determine a match: either {@link PatternMatcher#PATTERN_LITERAL},
+     * {@link PatternMatcher#PATTERN_PREFIX}, or
+     * {@link PatternMatcher#PATTERN_SIMPLE_GLOB}.
+     *
+     * @see #matchData
+     * @see #addDataScheme
+     */
+    public final void addDataSchemeSpecificPart(String ssp, int type) {
+        addDataSchemeSpecificPart(new PatternMatcher(ssp, type));
+    }
+
+    /** @hide */
+    public final void addDataSchemeSpecificPart(PatternMatcher ssp) {
+        if (mDataSchemeSpecificParts == null) {
+            mDataSchemeSpecificParts = new ArrayList<PatternMatcher>();
+        }
+        mDataSchemeSpecificParts.add(ssp);
+    }
+
+    /**
+     * Return the number of data scheme specific parts in the filter.
+     */
+    public final int countDataSchemeSpecificParts() {
+        return mDataSchemeSpecificParts != null ? mDataSchemeSpecificParts.size() : 0;
+    }
+
+    /**
+     * Return a data scheme specific part in the filter.
+     */
+    public final PatternMatcher getDataSchemeSpecificPart(int index) {
+        return mDataSchemeSpecificParts.get(index);
+    }
+
+    /**
+     * Is the given data scheme specific part included in the filter?  Note that if the
+     * filter does not include any scheme specific parts, false will <em>always</em> be
+     * returned.
+     *
+     * @param data The scheme specific part that is being looked for.
+     *
+     * @return Returns true if the data string matches a scheme specific part listed in the
+     *         filter.
+     */
+    public final boolean hasDataSchemeSpecificPart(String data) {
+        if (mDataSchemeSpecificParts == null) {
+            return false;
+        }
+        final int numDataSchemeSpecificParts = mDataSchemeSpecificParts.size();
+        for (int i = 0; i < numDataSchemeSpecificParts; i++) {
+            final PatternMatcher pe = mDataSchemeSpecificParts.get(i);
+            if (pe.match(data)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Return an iterator over the filter's data scheme specific parts.
+     */
+    public final Iterator<PatternMatcher> schemeSpecificPartsIterator() {
+        return mDataSchemeSpecificParts != null ? mDataSchemeSpecificParts.iterator() : null;
+    }
+
+    /**
      * Add a new Intent data authority to match against.  The filter must
      * include one or more schemes (via {@link #addDataScheme}) for the
      * authority to be considered.  If any authorities are
@@ -720,10 +811,15 @@
      * @see #addDataScheme
      */
     public final void addDataAuthority(String host, String port) {
+        if (port != null) port = port.intern();
+        addDataAuthority(new AuthorityEntry(host.intern(), port));
+    }
+
+    /** @hide */
+    public final void addDataAuthority(AuthorityEntry ent) {
         if (mDataAuthorities == null) mDataAuthorities =
                 new ArrayList<AuthorityEntry>();
-        if (port != null) port = port.intern();
-        mDataAuthorities.add(new AuthorityEntry(host.intern(), port));
+        mDataAuthorities.add(ent);
     }
 
     /**
@@ -788,8 +884,13 @@
      * @see #addDataAuthority
      */
     public final void addDataPath(String path, int type) {
+        addDataPath(new PatternMatcher(path.intern(), type));
+    }
+
+    /** @hide */
+    public final void addDataPath(PatternMatcher path) {
         if (mDataPaths == null) mDataPaths = new ArrayList<PatternMatcher>();
-        mDataPaths.add(new PatternMatcher(path.intern(), type));
+        mDataPaths.add(path);
     }
 
     /**
@@ -900,8 +1001,6 @@
     public final int matchData(String type, String scheme, Uri data) {
         final ArrayList<String> types = mDataTypes;
         final ArrayList<String> schemes = mDataSchemes;
-        final ArrayList<AuthorityEntry> authorities = mDataAuthorities;
-        final ArrayList<PatternMatcher> paths = mDataPaths;
 
         int match = MATCH_CATEGORY_EMPTY;
 
@@ -917,20 +1016,34 @@
                 return NO_MATCH_DATA;
             }
 
-            if (authorities != null) {
-                int authMatch = matchDataAuthority(data);
-                if (authMatch >= 0) {
-                    if (paths == null) {
-                        match = authMatch;
-                    } else if (hasDataPath(data.getPath())) {
-                        match = MATCH_CATEGORY_PATH;
+            final ArrayList<PatternMatcher> schemeSpecificParts = mDataSchemeSpecificParts;
+            if (schemeSpecificParts != null) {
+                match = hasDataSchemeSpecificPart(data.getSchemeSpecificPart())
+                        ? MATCH_CATEGORY_SCHEME_SPECIFIC_PART : NO_MATCH_DATA;
+            }
+            if (match != MATCH_CATEGORY_SCHEME_SPECIFIC_PART) {
+                // If there isn't any matching ssp, we need to match an authority.
+                final ArrayList<AuthorityEntry> authorities = mDataAuthorities;
+                if (authorities != null) {
+                    int authMatch = matchDataAuthority(data);
+                    if (authMatch >= 0) {
+                        final ArrayList<PatternMatcher> paths = mDataPaths;
+                        if (paths == null) {
+                            match = authMatch;
+                        } else if (hasDataPath(data.getPath())) {
+                            match = MATCH_CATEGORY_PATH;
+                        } else {
+                            return NO_MATCH_DATA;
+                        }
                     } else {
                         return NO_MATCH_DATA;
                     }
-                } else {
-                    return NO_MATCH_DATA;
                 }
             }
+            // If neither an ssp nor an authority matched, we're done.
+            if (match == NO_MATCH_DATA) {
+                return NO_MATCH_DATA;
+            }
         } else {
             // Special case: match either an Intent with no data URI,
             // or with a scheme: URI.  This is to give a convenience for
@@ -1173,6 +1286,23 @@
             serializer.attribute(null, NAME_STR, mDataSchemes.get(i));
             serializer.endTag(null, SCHEME_STR);
         }
+        N = countDataSchemeSpecificParts();
+        for (int i=0; i<N; i++) {
+            serializer.startTag(null, SSP_STR);
+            PatternMatcher pe = mDataSchemeSpecificParts.get(i);
+            switch (pe.getType()) {
+                case PatternMatcher.PATTERN_LITERAL:
+                    serializer.attribute(null, LITERAL_STR, pe.getPath());
+                    break;
+                case PatternMatcher.PATTERN_PREFIX:
+                    serializer.attribute(null, PREFIX_STR, pe.getPath());
+                    break;
+                case PatternMatcher.PATTERN_SIMPLE_GLOB:
+                    serializer.attribute(null, SGLOB_STR, pe.getPath());
+                    break;
+            }
+            serializer.endTag(null, SSP_STR);
+        }
         N = countDataAuthorities();
         for (int i=0; i<N; i++) {
             serializer.startTag(null, AUTH_STR);
@@ -1238,6 +1368,15 @@
                 if (name != null) {
                     addDataScheme(name);
                 }
+            } else if (tagName.equals(SSP_STR)) {
+                String ssp = parser.getAttributeValue(null, LITERAL_STR);
+                if (ssp != null) {
+                    addDataSchemeSpecificPart(ssp, PatternMatcher.PATTERN_LITERAL);
+                } else if ((ssp=parser.getAttributeValue(null, PREFIX_STR)) != null) {
+                    addDataSchemeSpecificPart(ssp, PatternMatcher.PATTERN_PREFIX);
+                } else if ((ssp=parser.getAttributeValue(null, SGLOB_STR)) != null) {
+                    addDataSchemeSpecificPart(ssp, PatternMatcher.PATTERN_SIMPLE_GLOB);
+                }
             } else if (tagName.equals(AUTH_STR)) {
                 String host = parser.getAttributeValue(null, HOST_STR);
                 String port = parser.getAttributeValue(null, PORT_STR);
@@ -1289,6 +1428,16 @@
                 du.println(sb.toString());
             }
         }
+        if (mDataSchemeSpecificParts != null) {
+            Iterator<PatternMatcher> it = mDataSchemeSpecificParts.iterator();
+            while (it.hasNext()) {
+                PatternMatcher pe = it.next();
+                sb.setLength(0);
+                sb.append(prefix); sb.append("Ssp: \"");
+                        sb.append(pe); sb.append("\"");
+                du.println(sb.toString());
+            }
+        }
         if (mDataAuthorities != null) {
             Iterator<AuthorityEntry> it = mDataAuthorities.iterator();
             while (it.hasNext()) {
@@ -1363,6 +1512,15 @@
         } else {
             dest.writeInt(0);
         }
+        if (mDataSchemeSpecificParts != null) {
+            final int N = mDataSchemeSpecificParts.size();
+            dest.writeInt(N);
+            for (int i=0; i<N; i++) {
+                mDataSchemeSpecificParts.get(i).writeToParcel(dest, flags);
+            }
+        } else {
+            dest.writeInt(0);
+        }
         if (mDataAuthorities != null) {
             final int N = mDataAuthorities.size();
             dest.writeInt(N);
@@ -1376,7 +1534,7 @@
             final int N = mDataPaths.size();
             dest.writeInt(N);
             for (int i=0; i<N; i++) {
-                mDataPaths.get(i).writeToParcel(dest, 0);
+                mDataPaths.get(i).writeToParcel(dest, flags);
             }
         } else {
             dest.writeInt(0);
@@ -1428,14 +1586,21 @@
         }
         int N = source.readInt();
         if (N > 0) {
-            mDataAuthorities = new ArrayList<AuthorityEntry>();
+            mDataSchemeSpecificParts = new ArrayList<PatternMatcher>(N);
+            for (int i=0; i<N; i++) {
+                mDataSchemeSpecificParts.add(new PatternMatcher(source));
+            }
+        }
+        N = source.readInt();
+        if (N > 0) {
+            mDataAuthorities = new ArrayList<AuthorityEntry>(N);
             for (int i=0; i<N; i++) {
                 mDataAuthorities.add(new AuthorityEntry(source));
             }
         }
         N = source.readInt();
         if (N > 0) {
-            mDataPaths = new ArrayList<PatternMatcher>();
+            mDataPaths = new ArrayList<PatternMatcher>(N);
             for (int i=0; i<N; i++) {
                 mDataPaths.add(new PatternMatcher(source));
             }
diff --git a/core/java/android/content/PeriodicSync.java b/core/java/android/content/PeriodicSync.java
index 513a556..b586eec 100644
--- a/core/java/android/content/PeriodicSync.java
+++ b/core/java/android/content/PeriodicSync.java
@@ -22,67 +22,120 @@
 import android.accounts.Account;
 
 /**
- * Value type that contains information about a periodic sync. Is parcelable, making it suitable
- * for passing in an IPC.
+ * Value type that contains information about a periodic sync.
  */
 public class PeriodicSync implements Parcelable {
-    /** The account to be synced */
+    /** The account to be synced. Can be null. */
     public final Account account;
-    /** The authority of the sync */
+    /** The authority of the sync. Can be null. */
     public final String authority;
     /** Any extras that parameters that are to be passed to the sync adapter. */
     public final Bundle extras;
-    /** How frequently the sync should be scheduled, in seconds. */
+    /** How frequently the sync should be scheduled, in seconds. Kept around for API purposes. */
     public final long period;
+    /**
+     * {@hide}
+     * How much flexibility can be taken in scheduling the sync, in seconds.
+     */
+    public final long flexTime;
 
-    /** Creates a new PeriodicSync, copying the Bundle */
-    public PeriodicSync(Account account, String authority, Bundle extras, long period) {
+      /**
+       * Creates a new PeriodicSync, copying the Bundle. SM no longer uses this ctor - kept around
+       * becuse it is part of the API.
+       * Note - even calls to the old API will not use this ctor, as
+       * they are given a default flex time.
+       */
+    public PeriodicSync(Account account, String authority, Bundle extras, long periodInSeconds) {
+        this.account = account;
+        this.authority = authority;
+        if (extras == null) {
+            this.extras = new Bundle();
+        } else {
+            this.extras = new Bundle(extras);
+        }
+        this.period = periodInSeconds;
+        // Initialise to a sane value.
+        this.flexTime = 0L;
+    }
+
+    /**
+     * {@hide}
+     * Create a copy of a periodic sync.
+     */
+    public PeriodicSync(PeriodicSync other) {
+        this.account = other.account;
+        this.authority = other.authority;
+        this.extras = new Bundle(other.extras);
+        this.period = other.period;
+        this.flexTime = other.flexTime;
+    }
+
+    /**
+     * {@hide}
+     * A PeriodicSync for a sync with a specified provider.
+     */
+    public PeriodicSync(Account account, String authority, Bundle extras,
+            long period, long flexTime) {
         this.account = account;
         this.authority = authority;
         this.extras = new Bundle(extras);
         this.period = period;
+        this.flexTime = flexTime;
     }
 
+    private PeriodicSync(Parcel in) {
+        this.account = in.readParcelable(null);
+        this.authority = in.readString();
+        this.extras = in.readBundle();
+        this.period = in.readLong();
+        this.flexTime = in.readLong();
+    }
+
+    @Override
     public int describeContents() {
         return 0;
     }
 
+    @Override
     public void writeToParcel(Parcel dest, int flags) {
-        account.writeToParcel(dest, flags);
+        dest.writeParcelable(account, flags);
         dest.writeString(authority);
         dest.writeBundle(extras);
         dest.writeLong(period);
+        dest.writeLong(flexTime);
     }
 
     public static final Creator<PeriodicSync> CREATOR = new Creator<PeriodicSync>() {
+        @Override
         public PeriodicSync createFromParcel(Parcel source) {
-            return new PeriodicSync(Account.CREATOR.createFromParcel(source),
-                    source.readString(), source.readBundle(), source.readLong());
+            return new PeriodicSync(source);
         }
 
+        @Override
         public PeriodicSync[] newArray(int size) {
             return new PeriodicSync[size];
         }
     };
 
+    @Override
     public boolean equals(Object o) {
         if (o == this) {
             return true;
         }
-
         if (!(o instanceof PeriodicSync)) {
             return false;
         }
-
         final PeriodicSync other = (PeriodicSync) o;
-
         return account.equals(other.account)
-                && authority.equals(other.authority)
-                && period == other.period
-                && syncExtrasEquals(extras, other.extras);
+            && authority.equals(other.authority)
+            && period == other.period
+            && syncExtrasEquals(extras, other.extras);
     }
 
-    /** {@hide} */
+    /**
+     * Periodic sync extra comparison function.
+     * {@hide}
+     */
     public static boolean syncExtrasEquals(Bundle b1, Bundle b2) {
         if (b1.size() != b2.size()) {
             return false;
@@ -100,4 +153,12 @@
         }
         return true;
     }
+
+    @Override
+    public String toString() {
+        return "account: " + account +
+               ", authority: " + authority +
+               ". period: " + period + "s " +
+               ", flex: " + flexTime;
+    }
 }
diff --git a/core/java/android/content/SyncRequest.aidl b/core/java/android/content/SyncRequest.aidl
new file mode 100644
index 0000000..8321fac
--- /dev/null
+++ b/core/java/android/content/SyncRequest.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.content;
+
+parcelable SyncRequest;
diff --git a/core/java/android/content/SyncRequest.java b/core/java/android/content/SyncRequest.java
new file mode 100644
index 0000000..d4e0c2a
--- /dev/null
+++ b/core/java/android/content/SyncRequest.java
@@ -0,0 +1,622 @@
+/*
+ * 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.content;
+
+import android.accounts.Account;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class SyncRequest implements Parcelable {
+    private static final String TAG = "SyncRequest";
+    /** Account to pass to the sync adapter. May be null. */
+    private final Account mAccountToSync;
+    /** Authority string that corresponds to a ContentProvider. */
+    private final String mAuthority;
+    /** Sync service identifier. May be null.*/
+    private final ComponentName mComponentInfo;
+    /** Bundle containing user info as well as sync settings. */
+    private final Bundle mExtras;
+    /** Disallow this sync request on metered networks. */
+    private final boolean mDisallowMetered;
+    /**
+     * Anticipated upload size in bytes.
+     * TODO: Not yet used - we put this information into the bundle for simplicity.
+     */
+    private final long mTxBytes;
+    /**
+     * Anticipated download size in bytes.
+     * TODO: Not yet used - we put this information into the bundle.
+     */
+    private final long mRxBytes;
+    /**
+     * Amount of time before {@link #mSyncRunTimeSecs} from which the sync may optionally be
+     * started.
+     */
+    private final long mSyncFlexTimeSecs;
+    /**
+     * Specifies a point in the future at which the sync must have been scheduled to run.
+     */
+    private final long mSyncRunTimeSecs;
+    /** Periodic versus one-off. */
+    private final boolean mIsPeriodic;
+    /** Service versus provider. */
+    private final boolean mIsAuthority;
+    /** Sync should be run in lieu of other syncs. */
+    private final boolean mIsExpedited;
+
+    /**
+     * {@hide}
+     * @return whether this sync is periodic or one-time. A Sync Request must be
+     *         either one of these or an InvalidStateException will be thrown in
+     *         Builder.build().
+     */
+    public boolean isPeriodic() {
+        return mIsPeriodic;
+    }
+
+    /**
+     * {@hide}
+     * @return whether this is an expedited sync.
+     */
+    public boolean isExpedited() {
+        return mIsExpedited;
+    }
+
+    /**
+     * {@hide}
+     * @return true if this sync uses an account/authority pair, or false if this sync is bound to
+     * a Sync Service.
+     */
+    public boolean hasAuthority() {
+        return mIsAuthority;
+    }
+
+    /**
+     * {@hide}
+     * @return account object for this sync.
+     * @throws IllegalArgumentException if this function is called for a request that does not
+     * specify an account/provider authority.
+     */
+    public Account getAccount() {
+        if (!hasAuthority()) {
+            throw new IllegalArgumentException("Cannot getAccount() for a sync that does not"
+                    + "specify an authority.");
+        }
+        return mAccountToSync;
+    }
+
+    /**
+     * {@hide}
+     * @return provider for this sync.
+     * @throws IllegalArgumentException if this function is called for a request that does not
+     * specify an account/provider authority.
+     */
+    public String getProvider() {
+        if (!hasAuthority()) {
+            throw new IllegalArgumentException("Cannot getProvider() for a sync that does not"
+                    + "specify a provider.");
+        }
+        return mAuthority;
+    }
+
+    /**
+     * {@hide}
+     * Retrieve bundle for this SyncRequest. Will not be null.
+     */
+    public Bundle getBundle() {
+        return mExtras;
+    }
+
+    /**
+     * {@hide}
+     * @return the earliest point in time that this sync can be scheduled.
+     */
+    public long getSyncFlexTime() {
+        return mSyncFlexTimeSecs;
+    }
+
+    /**
+     * {@hide}
+     * @return the last point in time at which this sync must scheduled.
+     */
+    public long getSyncRunTime() {
+        return mSyncRunTimeSecs;
+    }
+
+    public static final Creator<SyncRequest> CREATOR = new Creator<SyncRequest>() {
+
+        @Override
+        public SyncRequest createFromParcel(Parcel in) {
+            return new SyncRequest(in);
+        }
+
+        @Override
+        public SyncRequest[] newArray(int size) {
+            return new SyncRequest[size];
+        }
+    };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeBundle(mExtras);
+        parcel.writeLong(mSyncFlexTimeSecs);
+        parcel.writeLong(mSyncRunTimeSecs);
+        parcel.writeInt((mIsPeriodic ? 1 : 0));
+        parcel.writeInt((mDisallowMetered ? 1 : 0));
+        parcel.writeLong(mTxBytes);
+        parcel.writeLong(mRxBytes);
+        parcel.writeInt((mIsAuthority ? 1 : 0));
+        parcel.writeInt((mIsExpedited? 1 : 0));
+        if (mIsAuthority) {
+            parcel.writeParcelable(mAccountToSync, flags);
+            parcel.writeString(mAuthority);
+        } else {
+            parcel.writeParcelable(mComponentInfo, flags);
+        }
+    }
+
+    private SyncRequest(Parcel in) {
+        mExtras = in.readBundle();
+        mSyncFlexTimeSecs = in.readLong();
+        mSyncRunTimeSecs = in.readLong();
+        mIsPeriodic = (in.readInt() != 0);
+        mDisallowMetered = (in.readInt() != 0);
+        mTxBytes = in.readLong();
+        mRxBytes = in.readLong();
+        mIsAuthority = (in.readInt() != 0);
+        mIsExpedited = (in.readInt() != 0);
+        if (mIsAuthority) {
+            mComponentInfo = null;
+            mAccountToSync = in.readParcelable(null);
+            mAuthority = in.readString();
+        } else {
+            mComponentInfo = in.readParcelable(null);
+            mAccountToSync = null;
+            mAuthority = null;
+        }
+    }
+
+    /** {@hide} Protected ctor to instantiate anonymous SyncRequest. */
+    protected SyncRequest(SyncRequest.Builder b) {
+        mSyncFlexTimeSecs = b.mSyncFlexTimeSecs;
+        mSyncRunTimeSecs = b.mSyncRunTimeSecs;
+        mAccountToSync = b.mAccount;
+        mAuthority = b.mAuthority;
+        mComponentInfo = b.mComponentName;
+        mIsPeriodic = (b.mSyncType == Builder.SYNC_TYPE_PERIODIC);
+        mIsAuthority = (b.mSyncTarget == Builder.SYNC_TARGET_ADAPTER);
+        mIsExpedited = b.mExpedited;
+        mExtras = new Bundle(b.mCustomExtras);
+        // For now we merge the sync config extras & the custom extras into one bundle.
+        // TODO: pass the configuration extras through separately.
+        mExtras.putAll(b.mSyncConfigExtras);
+        mDisallowMetered = b.mDisallowMetered;
+        mTxBytes = b.mTxBytes;
+        mRxBytes = b.mRxBytes;
+    }
+
+    /**
+     * Builder class for a {@link SyncRequest}. As you build your SyncRequest this class will also
+     * perform validation.
+     */
+    public static class Builder {
+        /** Unknown sync type. */
+        private static final int SYNC_TYPE_UNKNOWN = 0;
+        /** Specify that this is a periodic sync. */
+        private static final int SYNC_TYPE_PERIODIC = 1;
+        /** Specify that this is a one-time sync. */
+        private static final int SYNC_TYPE_ONCE = 2;
+        /** Unknown sync target. */
+        private static final int SYNC_TARGET_UNKNOWN = 0;
+        /** Specify that this is an anonymous sync. */
+        private static final int SYNC_TARGET_SERVICE = 1;
+        /** Specify that this is a sync with a provider. */
+        private static final int SYNC_TARGET_ADAPTER = 2;
+        /** Earliest point of displacement into the future at which this sync can occur. */
+        private long mSyncFlexTimeSecs;
+        /** Latest point of displacement into the future at which this sync must occur. */
+        private long mSyncRunTimeSecs;
+        /**
+         * Sync configuration information - custom user data explicitly provided by the developer.
+         * This data is handed over to the sync operation.
+         */
+        private Bundle mCustomExtras;
+        /**
+         * Sync system configuration -  used to store system sync configuration. Corresponds to
+         * ContentResolver.SYNC_EXTRAS_* flags.
+         * TODO: Use this instead of dumping into one bundle. Need to decide if these flags should
+         * discriminate between equivalent syncs.
+         */
+        private Bundle mSyncConfigExtras;
+        /** Expected upload transfer in bytes. */
+        private long mTxBytes = -1L;
+        /** Expected download transfer in bytes. */
+        private long mRxBytes = -1L;
+        /** Whether or not this sync can occur on metered networks. Default false. */
+        private boolean mDisallowMetered;
+        /** Priority of this sync relative to others from calling app [-2, 2]. Default 0. */
+        private int mPriority = 0;
+        /**
+         * Whether this builder is building a periodic sync, or a one-time sync.
+         */
+        private int mSyncType = SYNC_TYPE_UNKNOWN;
+        /** Whether this will go to a sync adapter or to a sync service. */
+        private int mSyncTarget = SYNC_TARGET_UNKNOWN;
+        /** Whether this is a user-activated sync. */
+        private boolean mIsManual;
+        /**
+         * Whether to retry this one-time sync if the sync fails. Not valid for
+         * periodic syncs. See {@link ContentResolver#SYNC_EXTRAS_DO_NOT_RETRY}.
+         */
+        private boolean mNoRetry;
+        /**
+         * Whether to respect back-off for this one-time sync. Not valid for
+         * periodic syncs. See
+         * {@link ContentResolver#SYNC_EXTRAS_IGNORE_BACKOFF};
+         */
+        private boolean mIgnoreBackoff;
+
+        /** Ignore sync system settings and perform sync anyway. */
+        private boolean mIgnoreSettings;
+
+        /** This sync will run in preference to other non-expedited syncs. */
+        private boolean mExpedited;
+
+        /**
+         * The sync component that contains the sync logic if this is a provider-less sync,
+         * otherwise null.
+         */
+        private ComponentName mComponentName;
+        /**
+         * The Account object that together with an Authority name define the SyncAdapter (if
+         * this sync is bound to a provider), otherwise null.
+         */
+        private Account mAccount;
+        /**
+         * The Authority name that together with an Account define the SyncAdapter (if
+         * this sync is bound to a provider), otherwise null.
+         */
+        private String mAuthority;
+
+        public Builder() {
+        }
+
+        /**
+         * Request that a sync occur immediately.
+         *
+         * Example
+         * <pre>
+         *     SyncRequest.Builder builder = (new SyncRequest.Builder()).syncOnce();
+         * </pre>
+         */
+        public Builder syncOnce() {
+            if (mSyncType != SYNC_TYPE_UNKNOWN) {
+                throw new IllegalArgumentException("Sync type has already been defined.");
+            }
+            mSyncType = SYNC_TYPE_ONCE;
+            setupInterval(0, 0);
+            return this;
+        }
+
+        /**
+         * Build a periodic sync. Either this or syncOnce() <b>must</b> be called for this builder.
+         * Syncs are identified by target {@link android.provider}/{@link android.accounts.Account}
+         * and by the contents of the extras bundle.
+         * You cannot reuse the same builder for one-time syncs (by calling this function) after
+         * having specified a periodic sync. If you do, an <code>IllegalArgumentException</code>
+         * will be thrown.
+         *
+         * Example usage.
+         *
+         * <pre>
+         *     Request a periodic sync every 5 hours with 20 minutes of flex.
+         *     SyncRequest.Builder builder =
+         *         (new SyncRequest.Builder()).syncPeriodic(5 * HOUR_IN_SECS, 20 * MIN_IN_SECS);
+         *
+         *     Schedule a periodic sync every hour at any point in time during that hour.
+         *     SyncRequest.Builder builder =
+         *         (new SyncRequest.Builder()).syncPeriodic(1 * HOUR_IN_SECS, 1 * HOUR_IN_SECS);
+         * </pre>
+         *
+         * N.B.: Periodic syncs are not allowed to have any of
+         * {@link ContentResolver#SYNC_EXTRAS_DO_NOT_RETRY},
+         * {@link ContentResolver#SYNC_EXTRAS_IGNORE_BACKOFF},
+         * {@link ContentResolver#SYNC_EXTRAS_IGNORE_SETTINGS},
+         * {@link ContentResolver#SYNC_EXTRAS_INITIALIZE},
+         * {@link ContentResolver#SYNC_EXTRAS_FORCE},
+         * {@link ContentResolver#SYNC_EXTRAS_EXPEDITED},
+         * {@link ContentResolver#SYNC_EXTRAS_MANUAL}
+         * set to true. If any are supplied then an <code>IllegalArgumentException</code> will
+         * be thrown.
+         *
+         * @param pollFrequency the amount of time in seconds that you wish
+         *            to elapse between periodic syncs.
+         * @param beforeSeconds the amount of flex time in seconds before
+         *            {@code pollFrequency} that you permit for the sync to take
+         *            place. Must be less than {@code pollFrequency}.
+         */
+        public Builder syncPeriodic(long pollFrequency, long beforeSeconds) {
+            if (mSyncType != SYNC_TYPE_UNKNOWN) {
+                throw new IllegalArgumentException("Sync type has already been defined.");
+            }
+            mSyncType = SYNC_TYPE_PERIODIC;
+            setupInterval(pollFrequency, beforeSeconds);
+            return this;
+        }
+
+        /** {@hide} */
+        private void setupInterval(long at, long before) {
+            if (before > at) {
+                throw new IllegalArgumentException("Specified run time for the sync must be" +
+                    " after the specified flex time.");
+            }
+            mSyncRunTimeSecs = at;
+            mSyncFlexTimeSecs = before;
+        }
+
+        /**
+         * {@hide}
+         * Developer can provide insight into their payload size; optional. -1 specifies unknown,
+         * so that you are not restricted to defining both fields.
+         *
+         * @param rxBytes Bytes expected to be downloaded.
+         * @param txBytes Bytes expected to be uploaded.
+         */
+        public Builder setTransferSize(long rxBytes, long txBytes) {
+            mRxBytes = rxBytes;
+            mTxBytes = txBytes;
+            return this;
+        }
+
+        /**
+         * @see android.net.ConnectivityManager#isActiveNetworkMetered()
+         * @param disallow true to enforce that this transfer not occur on metered networks.
+         *                 Default false.
+         */
+        public Builder setDisallowMetered(boolean disallow) {
+            mDisallowMetered = disallow;
+            return this;
+        }
+
+        /**
+         * Specify an authority and account for this transfer.
+         *
+         * @param authority String identifying which content provider to sync.
+         * @param account Account to sync. Can be null unless this is a periodic sync.
+         */
+        public Builder setSyncAdapter(Account account, String authority) {
+            if (mSyncTarget != SYNC_TARGET_UNKNOWN) {
+                throw new IllegalArgumentException("Sync target has already been defined.");
+            }
+            mSyncTarget = SYNC_TARGET_ADAPTER;
+            mAccount = account;
+            mAuthority = authority;
+            mComponentName = null;
+            return this;
+        }
+
+        /**
+         * Optional developer-provided extras handed back in
+         * {@link AbstractThreadedSyncAdapter#onPerformSync(Account, Bundle, String,
+         * ContentProviderClient, SyncResult)} occurs. This bundle is copied into the SyncRequest
+         * returned by {@link #build()}.
+         *
+         * Example:
+         * <pre>
+         *   String[] syncItems = {"dog", "cat", "frog", "child"};
+         *   SyncRequest.Builder builder =
+         *     new SyncRequest.Builder()
+         *       .setSyncAdapter(dummyAccount, dummyProvider)
+         *       .syncOnce(5 * MINUTES_IN_SECS);
+         *
+         *   for (String syncData : syncItems) {
+         *     Bundle extras = new Bundle();
+         *     extras.setString("data", syncData);
+         *     builder.setExtras(extras);
+         *     ContentResolver.sync(builder.build()); // Each sync() request is for a unique sync.
+         *   }
+         * </pre>
+         * Only values of the following types may be used in the extras bundle:
+         * <ul>
+         * <li>Integer</li>
+         * <li>Long</li>
+         * <li>Boolean</li>
+         * <li>Float</li>
+         * <li>Double</li>
+         * <li>String</li>
+         * <li>Account</li>
+         * <li>null</li>
+         * </ul>
+         * If any data is present in the bundle not of this type, build() will
+         * throw a runtime exception.
+         *
+         * @param bundle extras bundle to set.
+         */
+        public Builder setExtras(Bundle bundle) {
+            mCustomExtras = bundle;
+            return this;
+        }
+
+        /**
+         * Convenience function for setting {@link ContentResolver#SYNC_EXTRAS_DO_NOT_RETRY}.
+         *
+         * A one-off sync operation that fails will be retried with exponential back-off unless
+         * this is set to false. Not valid for periodic sync and will throw an
+         * <code>IllegalArgumentException</code> in build().
+         *
+         * @param noRetry true to not retry a failed sync. Default false.
+         */
+        public Builder setNoRetry(boolean noRetry) {
+            mNoRetry = noRetry;
+            return this;
+        }
+
+        /**
+         * Convenience function for setting {@link ContentResolver#SYNC_EXTRAS_IGNORE_SETTINGS}.
+         *
+         * A sync can specify that system sync settings be ignored (user has turned sync off). Not
+         * valid for periodic sync and will throw an <code>IllegalArgumentException</code> in
+         * {@link #build()}.
+         *
+         * @param ignoreSettings true to ignore the sync automatically settings. Default false.
+         */
+        public Builder setIgnoreSettings(boolean ignoreSettings) {
+            mIgnoreSettings = ignoreSettings;
+            return this;
+        }
+
+        /**
+         * Convenience function for setting {@link ContentResolver#SYNC_EXTRAS_IGNORE_BACKOFF}.
+         *
+         * Force the sync scheduling process to ignore any back-off that was the result of a failed
+         * sync, as well as to invalidate any {@link SyncResult#delayUntil} value that may have
+         * been set by the adapter. Successive failures will not honor this flag. Not valid for
+         * periodic sync and will throw an <code>IllegalArgumentException</code> in
+         * {@link #build()}.
+         *
+         * @param ignoreBackoff ignore back-off settings. Default false.
+         */
+        public Builder setIgnoreBackoff(boolean ignoreBackoff) {
+            mIgnoreBackoff = ignoreBackoff;
+            return this;
+        }
+
+        /**
+         * Convenience function for setting {@link ContentResolver#SYNC_EXTRAS_MANUAL}.
+         *
+         * A manual sync is functionally equivalent to calling {@link #setIgnoreBackoff(boolean)}
+         * and {@link #setIgnoreSettings(boolean)}. Not valid for periodic sync and will throw an
+         * <code>IllegalArgumentException</code> in {@link #build()}.
+         *
+         * @param isManual User-initiated sync or not. Default false.
+         */
+        public Builder setManual(boolean isManual) {
+            mIsManual = isManual;
+            return this;
+        }
+
+        /**
+         * An expedited sync runs immediately and will preempt another non-expedited running sync.
+         *
+         * Not valid for periodic sync and will throw an <code>IllegalArgumentException</code> in
+         * {@link #build()}.
+         *
+         * @param expedited whether to run expedited. Default false.
+         */
+        public Builder setExpedited(boolean expedited) {
+            mExpedited = expedited;
+            return this;
+        }
+
+        /**
+         * {@hide}
+         * @param priority the priority of this request among all requests from the calling app.
+         * Range of [-2,2] similar to how this is done with notifications.
+         */
+        public Builder setPriority(int priority) {
+            if (priority < -2 || priority > 2) {
+                throw new IllegalArgumentException("Priority must be within range [-2, 2]");
+            }
+            mPriority = priority;
+            return this;
+        }
+
+        /**
+         * Performs validation over the request and throws the runtime exception
+         * <code>IllegalArgumentException</code> if this validation fails.
+         *
+         * @return a SyncRequest with the information contained within this
+         *         builder.
+         */
+        public SyncRequest build() {
+            if (mCustomExtras == null) {
+                mCustomExtras = new Bundle();
+            }
+            // Validate the extras bundle
+            ContentResolver.validateSyncExtrasBundle(mCustomExtras);
+            // Combine builder extra flags into the config bundle.
+            mSyncConfigExtras = new Bundle();
+            if (mIgnoreBackoff) {
+                mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, true);
+            }
+            if (mDisallowMetered) {
+                mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_DISALLOW_METERED, true);
+            }
+            if (mIgnoreSettings) {
+                mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, true);
+            }
+            if (mNoRetry) {
+                mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, true);
+            }
+            if (mExpedited) {
+                mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
+            }
+            if (mIsManual) {
+                mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
+            }
+            mSyncConfigExtras.putLong(ContentResolver.SYNC_EXTRAS_EXPECTED_UPLOAD, mTxBytes);
+            mSyncConfigExtras.putLong(ContentResolver.SYNC_EXTRAS_EXPECTED_DOWNLOAD, mRxBytes);
+            mSyncConfigExtras.putInt(ContentResolver.SYNC_EXTRAS_PRIORITY, mPriority);
+            if (mSyncType == SYNC_TYPE_PERIODIC) {
+                // If this is a periodic sync ensure than invalid extras were not set.
+                validatePeriodicExtras(mCustomExtras);
+                validatePeriodicExtras(mSyncConfigExtras);
+                // Verify that account and provider are not null.
+                if (mAccount == null) {
+                    throw new IllegalArgumentException("Account must not be null for periodic"
+                            + " sync.");
+                }
+                if (mAuthority == null) {
+                    throw new IllegalArgumentException("Authority must not be null for periodic"
+                            + " sync.");
+                }
+            } else if (mSyncType == SYNC_TYPE_UNKNOWN) {
+                throw new IllegalArgumentException("Must call either syncOnce() or syncPeriodic()");
+            }
+            // Ensure that a target for the sync has been set.
+            if (mSyncTarget == SYNC_TARGET_UNKNOWN) {
+                throw new IllegalArgumentException("Must specify an adapter with "
+                        + "setSyncAdapter(Account, String");
+            }
+            return new SyncRequest(this);
+        }
+
+        /**
+         * Helper function to throw an <code>IllegalArgumentException</code> if any illegal
+         * extras were set for a periodic sync.
+         *
+         * @param extras bundle to validate.
+         */
+        private void validatePeriodicExtras(Bundle extras) {
+            if (extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false)
+                    || extras.getBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, false)
+                    || extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, false)
+                    || extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false)
+                    || extras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false)
+                    || extras.getBoolean(ContentResolver.SYNC_EXTRAS_FORCE, false)
+                    || extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false)) {
+                throw new IllegalArgumentException("Illegal extras were set");
+            }
+        }
+    }
+}
diff --git a/core/java/android/content/SyncResult.java b/core/java/android/content/SyncResult.java
index 8b0afbd..4f86af9 100644
--- a/core/java/android/content/SyncResult.java
+++ b/core/java/android/content/SyncResult.java
@@ -56,7 +56,7 @@
 
     /**
      * Used to indicate that the SyncAdapter experienced a hard error due to an error it
-     * received from interacting with the storage later. The SyncManager will record that
+     * received from interacting with the storage layer. The SyncManager will record that
      * the sync request failed and it will not reschedule the request.
      */
     public boolean databaseError;
@@ -181,7 +181,7 @@
      * <li> {@link SyncStats#numIoExceptions} > 0
      * <li> {@link #syncAlreadyInProgress}
      * </ul>
-     * @return true if a hard error is indicated
+     * @return true if a soft error is indicated
      */
     public boolean hasSoftError() {
         return syncAlreadyInProgress || stats.numIoExceptions > 0;
@@ -195,6 +195,11 @@
         return hasSoftError() || hasHardError();
     }
 
+    /**
+     * Convenience method for determining if the Sync should be rescheduled after failing for some
+     * reason.
+     * @return true if the SyncManager should reschedule this sync.
+     */
     public boolean madeSomeProgress() {
         return ((stats.numDeletes > 0) && !tooManyDeletions)
                 || stats.numInserts > 0
diff --git a/core/java/android/content/SyncStatusInfo.java b/core/java/android/content/SyncStatusInfo.java
index ff628d9..bb24ccd 100644
--- a/core/java/android/content/SyncStatusInfo.java
+++ b/core/java/android/content/SyncStatusInfo.java
@@ -42,7 +42,10 @@
     public long initialFailureTime;
     public boolean pending;
     public boolean initialize;
-    public ArrayList<Long> periodicSyncTimes;
+    
+  // Warning: It is up to the external caller to ensure there are
+  // no race conditions when accessing this list
+  private ArrayList<Long> periodicSyncTimes;
 
     private static final String TAG = "Sync";
 
@@ -126,11 +129,59 @@
         }
     }
 
+    public SyncStatusInfo(SyncStatusInfo other) {
+        authorityId = other.authorityId;
+        totalElapsedTime = other.totalElapsedTime;
+        numSyncs = other.numSyncs;
+        numSourcePoll = other.numSourcePoll;
+        numSourceServer = other.numSourceServer;
+        numSourceLocal = other.numSourceLocal;
+        numSourceUser = other.numSourceUser;
+        numSourcePeriodic = other.numSourcePeriodic;
+        lastSuccessTime = other.lastSuccessTime;
+        lastSuccessSource = other.lastSuccessSource;
+        lastFailureTime = other.lastFailureTime;
+        lastFailureSource = other.lastFailureSource;
+        lastFailureMesg = other.lastFailureMesg;
+        initialFailureTime = other.initialFailureTime;
+        pending = other.pending;
+        initialize = other.initialize;
+        if (other.periodicSyncTimes != null) {
+            periodicSyncTimes = new ArrayList<Long>(other.periodicSyncTimes);
+        }
+    }
+
     public void setPeriodicSyncTime(int index, long when) {
+        // The list is initialized lazily when scheduling occurs so we need to make sure
+        // we initialize elements < index to zero (zero is ignore for scheduling purposes)
         ensurePeriodicSyncTimeSize(index);
         periodicSyncTimes.set(index, when);
     }
 
+    public long getPeriodicSyncTime(int index) {
+        if (periodicSyncTimes != null && index < periodicSyncTimes.size()) {
+            return periodicSyncTimes.get(index);
+        } else {
+            return 0;
+        }
+    }
+
+    public void removePeriodicSyncTime(int index) {
+        if (periodicSyncTimes != null && index < periodicSyncTimes.size()) {
+            periodicSyncTimes.remove(index);
+        }
+    }
+
+    public static final Creator<SyncStatusInfo> CREATOR = new Creator<SyncStatusInfo>() {
+        public SyncStatusInfo createFromParcel(Parcel in) {
+            return new SyncStatusInfo(in);
+        }
+
+        public SyncStatusInfo[] newArray(int size) {
+            return new SyncStatusInfo[size];
+        }
+    };
+
     private void ensurePeriodicSyncTimeSize(int index) {
         if (periodicSyncTimes == null) {
             periodicSyncTimes = new ArrayList<Long>(0);
@@ -143,26 +194,4 @@
             }
         }
     }
-
-    public long getPeriodicSyncTime(int index) {
-        if (periodicSyncTimes == null || periodicSyncTimes.size() < (index + 1)) {
-            return 0;
-        }
-        return periodicSyncTimes.get(index);
-    }
-
-    public void removePeriodicSyncTime(int index) {
-        ensurePeriodicSyncTimeSize(index);
-        periodicSyncTimes.remove(index);
-    }
-
-    public static final Creator<SyncStatusInfo> CREATOR = new Creator<SyncStatusInfo>() {
-        public SyncStatusInfo createFromParcel(Parcel in) {
-            return new SyncStatusInfo(in);
-        }
-
-        public SyncStatusInfo[] newArray(int size) {
-            return new SyncStatusInfo[size];
-        }
-    };
 }
\ No newline at end of file
diff --git a/core/java/android/content/UndoManager.java b/core/java/android/content/UndoManager.java
new file mode 100644
index 0000000..e9ec5a4
--- /dev/null
+++ b/core/java/android/content/UndoManager.java
@@ -0,0 +1,934 @@
+/*
+ * 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.content;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.ParcelableParcel;
+import android.text.TextUtils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * Top-level class for managing and interacting with the global undo state for
+ * a document or application.  This class supports both undo and redo and has
+ * helpers for merging undoable operations together as they are performed.
+ *
+ * <p>A single undoable operation is represented by {@link UndoOperation} which
+ * apps implement to define their undo/redo behavior.  The UndoManager keeps
+ * a stack of undo states; each state can have one or more undo operations
+ * inside of it.</p>
+ *
+ * <p>Updates to the stack must be done inside of a {@link #beginUpdate}/{@link #endUpdate()}
+ * pair.  During this time you can add new operations to the stack with
+ * {@link #addOperation}, retrieve and modify existing operations with
+ * {@link #getLastOperation}, control the label shown to the user for this operation
+ * with {@link #setUndoLabel} and {@link #suggestUndoLabel}, etc.</p>
+ *
+ * <p>Every {link UndoOperation} is associated with an {@link UndoOwner}, which identifies
+ * the data it belongs to.  The owner is used to indicate how operations are dependent
+ * on each other -- operations with the same owner are dependent on others with the
+ * same owner.  For example, you may have a document with multiple embedded objects.  If the
+ * document itself and each embedded object use different owners, then you
+ * can provide undo semantics appropriate to the user's context: while within
+ * an embedded object, only edits to that object are seen and the user can
+ * undo/redo them without needing to impact edits in other objects; while
+ * within the larger document, all edits can be seen and the user must
+ * undo/redo them as a single stream.</p>
+ *
+ * @hide
+ */
+public class UndoManager {
+    private final HashMap<String, UndoOwner> mOwners = new HashMap<String, UndoOwner>();
+    private final ArrayList<UndoState> mUndos = new ArrayList<UndoState>();
+    private final ArrayList<UndoState> mRedos = new ArrayList<UndoState>();
+    private int mUpdateCount;
+    private int mHistorySize = 20;
+    private UndoState mWorking;
+    private int mCommitId = 1;
+    private boolean mInUndo;
+    private boolean mMerged;
+
+    private int mStateSeq;
+    private int mNextSavedIdx;
+    private UndoOwner[] mStateOwners;
+
+    /**
+     * Never merge with the last undo state.
+     */
+    public static final int MERGE_MODE_NONE = 0;
+
+    /**
+     * Allow merge with the last undo state only if it contains
+     * operations with the caller's owner.
+     */
+    public static final int MERGE_MODE_UNIQUE = 1;
+
+    /**
+     * Always allow merge with the last undo state, if possible.
+     */
+    public static final int MERGE_MODE_ANY = 2;
+
+    public UndoOwner getOwner(String tag, Object data) {
+        if (tag == null) {
+            throw new NullPointerException("tag can't be null");
+        }
+        if (data == null) {
+            throw new NullPointerException("data can't be null");
+        }
+        UndoOwner owner = mOwners.get(tag);
+        if (owner != null) {
+            if (owner.mData != data) {
+                if (owner.mData != null) {
+                    throw new IllegalStateException("Owner " + owner + " already exists with data "
+                            + owner.mData + " but giving different data " + data);
+                }
+                owner.mData = data;
+            }
+            return owner;
+        }
+
+        owner = new UndoOwner(tag);
+        owner.mManager = this;
+        owner.mData = data;
+        mOwners.put(tag, owner);
+        return owner;
+    }
+
+    void removeOwner(UndoOwner owner) {
+        // XXX need to figure out how to prune.
+        if (false) {
+            mOwners.remove(owner.mTag);
+            owner.mManager = null;
+        }
+    }
+
+    /**
+     * Flatten the current undo state into a Parcelable object, which can later be restored
+     * with {@link #restoreInstanceState(android.os.Parcelable)}.
+     */
+    public Parcelable saveInstanceState() {
+        if (mUpdateCount > 0) {
+            throw new IllegalStateException("Can't save state while updating");
+        }
+        ParcelableParcel pp = new ParcelableParcel(getClass().getClassLoader());
+        Parcel p = pp.getParcel();
+        mStateSeq++;
+        if (mStateSeq <= 0) {
+            mStateSeq = 0;
+        }
+        mNextSavedIdx = 0;
+        p.writeInt(mHistorySize);
+        p.writeInt(mOwners.size());
+        // XXX eventually we need to be smart here about limiting the
+        // number of undo states we write to not exceed X bytes.
+        int i = mUndos.size();
+        while (i > 0) {
+            p.writeInt(1);
+            i--;
+            mUndos.get(i).writeToParcel(p);
+        }
+        i = mRedos.size();
+        p.writeInt(i);
+        while (i > 0) {
+            p.writeInt(2);
+            i--;
+            mRedos.get(i).writeToParcel(p);
+        }
+        p.writeInt(0);
+        return pp;
+    }
+
+    void saveOwner(UndoOwner owner, Parcel out) {
+        if (owner.mStateSeq == mStateSeq) {
+            out.writeInt(owner.mSavedIdx);
+        } else {
+            owner.mStateSeq = mStateSeq;
+            owner.mSavedIdx = mNextSavedIdx;
+            out.writeInt(owner.mSavedIdx);
+            out.writeString(owner.mTag);
+            mNextSavedIdx++;
+        }
+    }
+
+    /**
+     * Restore an undo state previously created with {@link #saveInstanceState()}.  This will
+     * restore the UndoManager's state to almost exactly what it was at the point it had
+     * been previously saved; the only information not restored is the data object
+     * associated with each {@link UndoOwner}, which requires separate calls to
+     * {@link #getOwner(String, Object)} to re-associate the owner with its data.
+     */
+    public void restoreInstanceState(Parcelable state) {
+        if (mUpdateCount > 0) {
+            throw new IllegalStateException("Can't save state while updating");
+        }
+        forgetUndos(null, -1);
+        forgetRedos(null, -1);
+        ParcelableParcel pp = (ParcelableParcel)state;
+        Parcel p = pp.getParcel();
+        mHistorySize = p.readInt();
+        mStateOwners = new UndoOwner[p.readInt()];
+
+        int stype;
+        while ((stype=p.readInt()) != 0) {
+            UndoState ustate = new UndoState(this, p, pp.getClassLoader());
+            if (stype == 1) {
+                mUndos.add(0, ustate);
+            } else {
+                mRedos.add(0, ustate);
+            }
+        }
+    }
+
+    UndoOwner restoreOwner(Parcel in) {
+        int idx = in.readInt();
+        UndoOwner owner = mStateOwners[idx];
+        if (owner == null) {
+            String tag = in.readString();
+            owner = new UndoOwner(tag);
+            mStateOwners[idx] = owner;
+            mOwners.put(tag, owner);
+        }
+        return owner;
+    }
+
+    /**
+     * Set the maximum number of undo states that will be retained.
+     */
+    public void setHistorySize(int size) {
+        mHistorySize = size;
+        if (mHistorySize >= 0 && countUndos(null) > mHistorySize) {
+            forgetUndos(null, countUndos(null) - mHistorySize);
+        }
+    }
+
+    /**
+     * Return the current maximum number of undo states.
+     */
+    public int getHistorySize() {
+        return mHistorySize;
+    }
+
+    /**
+     * Perform undo of last/top <var>count</var> undo states.  The states impacted
+     * by this can be limited through <var>owners</var>.
+     * @param owners Optional set of owners that should be impacted.  If null, all
+     * undo states will be visible and available for undo.  If non-null, only those
+     * states that contain one of the owners specified here will be visible.
+     * @param count Number of undo states to pop.
+     * @return Returns the number of undo states that were actually popped.
+     */
+    public int undo(UndoOwner[] owners, int count) {
+        if (mWorking != null) {
+            throw new IllegalStateException("Can't be called during an update");
+        }
+
+        int num = 0;
+        int i = -1;
+
+        mInUndo = true;
+
+        UndoState us = getTopUndo(null);
+        if (us != null) {
+            us.makeExecuted();
+        }
+
+        while (count > 0 && (i=findPrevState(mUndos, owners, i)) >= 0) {
+            UndoState state = mUndos.remove(i);
+            state.undo();
+            mRedos.add(state);
+            count--;
+            num++;
+        }
+
+        mInUndo = false;
+
+        return num;
+    }
+
+    /**
+     * Perform redo of last/top <var>count</var> undo states in the transient redo stack.
+     * The states impacted by this can be limited through <var>owners</var>.
+     * @param owners Optional set of owners that should be impacted.  If null, all
+     * undo states will be visible and available for undo.  If non-null, only those
+     * states that contain one of the owners specified here will be visible.
+     * @param count Number of undo states to pop.
+     * @return Returns the number of undo states that were actually redone.
+     */
+    public int redo(UndoOwner[] owners, int count) {
+        if (mWorking != null) {
+            throw new IllegalStateException("Can't be called during an update");
+        }
+
+        int num = 0;
+        int i = -1;
+
+        mInUndo = true;
+
+        while (count > 0 && (i=findPrevState(mRedos, owners, i)) >= 0) {
+            UndoState state = mRedos.remove(i);
+            state.redo();
+            mUndos.add(state);
+            count--;
+            num++;
+        }
+
+        mInUndo = false;
+
+        return num;
+    }
+
+    /**
+     * Returns true if we are currently inside of an undo/redo operation.  This is
+     * useful for editors to know whether they should be generating new undo state
+     * when they see edit operations happening.
+     */
+    public boolean isInUndo() {
+        return mInUndo;
+    }
+
+    public int forgetUndos(UndoOwner[] owners, int count) {
+        if (count < 0) {
+            count = mUndos.size();
+        }
+
+        int removed = 0;
+        for (int i=0; i<mUndos.size() && removed < count; i++) {
+            UndoState state = mUndos.get(i);
+            if (count > 0 && matchOwners(state, owners)) {
+                state.destroy();
+                mUndos.remove(i);
+                removed++;
+            }
+        }
+
+        return removed;
+    }
+
+    public int forgetRedos(UndoOwner[] owners, int count) {
+        if (count < 0) {
+            count = mRedos.size();
+        }
+
+        int removed = 0;
+        for (int i=0; i<mRedos.size() && removed < count; i++) {
+            UndoState state = mRedos.get(i);
+            if (count > 0 && matchOwners(state, owners)) {
+                state.destroy();
+                mRedos.remove(i);
+                removed++;
+            }
+        }
+
+        return removed;
+    }
+
+    /**
+     * Return the number of undo states on the undo stack.
+     * @param owners If non-null, only those states containing an operation with one of
+     * the owners supplied here will be counted.
+     */
+    public int countUndos(UndoOwner[] owners) {
+        if (owners == null) {
+            return mUndos.size();
+        }
+
+        int count=0;
+        int i=0;
+        while ((i=findNextState(mUndos, owners, i)) >= 0) {
+            count++;
+            i++;
+        }
+        return count;
+    }
+
+    /**
+     * Return the number of redo states on the undo stack.
+     * @param owners If non-null, only those states containing an operation with one of
+     * the owners supplied here will be counted.
+     */
+    public int countRedos(UndoOwner[] owners) {
+        if (owners == null) {
+            return mRedos.size();
+        }
+
+        int count=0;
+        int i=0;
+        while ((i=findNextState(mRedos, owners, i)) >= 0) {
+            count++;
+            i++;
+        }
+        return count;
+    }
+
+    /**
+     * Return the user-visible label for the top undo state on the stack.
+     * @param owners If non-null, will select the top-most undo state containing an
+     * operation with one of the owners supplied here.
+     */
+    public CharSequence getUndoLabel(UndoOwner[] owners) {
+        UndoState state = getTopUndo(owners);
+        return state != null ? state.getLabel() : null;
+    }
+
+    /**
+     * Return the user-visible label for the top redo state on the stack.
+     * @param owners If non-null, will select the top-most undo state containing an
+     * operation with one of the owners supplied here.
+     */
+    public CharSequence getRedoLabel(UndoOwner[] owners) {
+        UndoState state = getTopRedo(owners);
+        return state != null ? state.getLabel() : null;
+    }
+
+    /**
+     * Start creating a new undo state.  Multiple calls to this function will nest until
+     * they are all matched by a later call to {@link #endUpdate}.
+     * @param label Optional user-visible label for this new undo state.
+     */
+    public void beginUpdate(CharSequence label) {
+        if (mInUndo) {
+            throw new IllegalStateException("Can't being update while performing undo/redo");
+        }
+        if (mUpdateCount <= 0) {
+            createWorkingState();
+            mMerged = false;
+            mUpdateCount = 0;
+        }
+
+        mWorking.updateLabel(label);
+        mUpdateCount++;
+    }
+
+    private void createWorkingState() {
+        mWorking = new UndoState(this, mCommitId++);
+        if (mCommitId < 0) {
+            mCommitId = 1;
+        }
+    }
+
+    /**
+     * Returns true if currently inside of a {@link #beginUpdate}.
+     */
+    public boolean isInUpdate() {
+        return mUpdateCount > 0;
+    }
+
+    /**
+     * Forcibly set a new for the new undo state being built within a {@link #beginUpdate}.
+     * Any existing label will be replaced with this one.
+     */
+    public void setUndoLabel(CharSequence label) {
+        if (mWorking == null) {
+            throw new IllegalStateException("Must be called during an update");
+        }
+        mWorking.setLabel(label);
+    }
+
+    /**
+     * Set a new for the new undo state being built within a {@link #beginUpdate}, but
+     * only if there is not a label currently set for it.
+     */
+    public void suggestUndoLabel(CharSequence label) {
+        if (mWorking == null) {
+            throw new IllegalStateException("Must be called during an update");
+        }
+        mWorking.updateLabel(label);
+    }
+
+    /**
+     * Return the number of times {@link #beginUpdate} has been called without a matching
+     * {@link #endUpdate} call.
+     */
+    public int getUpdateNestingLevel() {
+        return mUpdateCount;
+    }
+
+    /**
+     * Check whether there is an {@link UndoOperation} in the current {@link #beginUpdate}
+     * undo state.
+     * @param owner Optional owner of the operation to look for.  If null, will succeed
+     * if there is any operation; if non-null, will only succeed if there is an operation
+     * with the given owner.
+     * @return Returns true if there is a matching operation in the current undo state.
+     */
+    public boolean hasOperation(UndoOwner owner) {
+        if (mWorking == null) {
+            throw new IllegalStateException("Must be called during an update");
+        }
+        return mWorking.hasOperation(owner);
+    }
+
+    /**
+     * Return the most recent {@link UndoOperation} that was added to the update.
+     * @param mergeMode May be either {@link #MERGE_MODE_NONE} or {@link #MERGE_MODE_ANY}.
+     */
+    public UndoOperation<?> getLastOperation(int mergeMode) {
+        return getLastOperation(null, null, mergeMode);
+    }
+
+    /**
+     * Return the most recent {@link UndoOperation} that was added to the update and
+     * has the given owner.
+     * @param owner Optional owner of last operation to retrieve.  If null, the last
+     * operation regardless of owner will be retrieved; if non-null, the last operation
+     * matching the given owner will be retrieved.
+     * @param mergeMode May be either {@link #MERGE_MODE_NONE}, {@link #MERGE_MODE_UNIQUE},
+     * or {@link #MERGE_MODE_ANY}.
+     */
+    public UndoOperation<?> getLastOperation(UndoOwner owner, int mergeMode) {
+        return getLastOperation(null, owner, mergeMode);
+    }
+
+    /**
+     * Return the most recent {@link UndoOperation} that was added to the update and
+     * has the given owner.
+     * @param clazz Optional class of the last operation to retrieve.  If null, the
+     * last operation regardless of class will be retrieved; if non-null, the last
+     * operation whose class is the same as the given class will be retrieved.
+     * @param owner Optional owner of last operation to retrieve.  If null, the last
+     * operation regardless of owner will be retrieved; if non-null, the last operation
+     * matching the given owner will be retrieved.
+     * @param mergeMode May be either {@link #MERGE_MODE_NONE}, {@link #MERGE_MODE_UNIQUE},
+     * or {@link #MERGE_MODE_ANY}.
+     */
+    public <T extends UndoOperation> T getLastOperation(Class<T> clazz, UndoOwner owner,
+            int mergeMode) {
+        if (mWorking == null) {
+            throw new IllegalStateException("Must be called during an update");
+        }
+        if (mergeMode != MERGE_MODE_NONE && !mMerged && !mWorking.hasData()) {
+            UndoState state = getTopUndo(null);
+            UndoOperation<?> last;
+            if (state != null && (mergeMode == MERGE_MODE_ANY || !state.hasMultipleOwners())
+                    && state.canMerge() && (last=state.getLastOperation(clazz, owner)) != null) {
+                if (last.allowMerge()) {
+                    mWorking.destroy();
+                    mWorking = state;
+                    mUndos.remove(state);
+                    mMerged = true;
+                    return (T)last;
+                }
+            }
+        }
+
+        return mWorking.getLastOperation(clazz, owner);
+    }
+
+    /**
+     * Add a new UndoOperation to the current update.
+     * @param op The new operation to add.
+     * @param mergeMode May be either {@link #MERGE_MODE_NONE}, {@link #MERGE_MODE_UNIQUE},
+     * or {@link #MERGE_MODE_ANY}.
+     */
+    public void addOperation(UndoOperation<?> op, int mergeMode) {
+        if (mWorking == null) {
+            throw new IllegalStateException("Must be called during an update");
+        }
+        UndoOwner owner = op.getOwner();
+        if (owner.mManager != this) {
+            throw new IllegalArgumentException(
+                    "Given operation's owner is not in this undo manager.");
+        }
+        if (mergeMode != MERGE_MODE_NONE && !mMerged && !mWorking.hasData()) {
+            UndoState state = getTopUndo(null);
+            if (state != null && (mergeMode == MERGE_MODE_ANY || !state.hasMultipleOwners())
+                    && state.canMerge() && state.hasOperation(op.getOwner())) {
+                mWorking.destroy();
+                mWorking = state;
+                mUndos.remove(state);
+                mMerged = true;
+            }
+        }
+        mWorking.addOperation(op);
+    }
+
+    /**
+     * Finish the creation of an undo state, matching a previous call to
+     * {@link #beginUpdate}.
+     */
+    public void endUpdate() {
+        if (mWorking == null) {
+            throw new IllegalStateException("Must be called during an update");
+        }
+        mUpdateCount--;
+
+        if (mUpdateCount == 0) {
+            pushWorkingState();
+        }
+    }
+
+    private void pushWorkingState() {
+        int N = mUndos.size() + 1;
+
+        if (mWorking.hasData()) {
+            mUndos.add(mWorking);
+            forgetRedos(null, -1);
+            mWorking.commit();
+            if (N >= 2) {
+                // The state before this one can no longer be merged, ever.
+                // The only way to get back to it is for the user to perform
+                // an undo.
+                mUndos.get(N-2).makeExecuted();
+            }
+        } else {
+            mWorking.destroy();
+        }
+        mWorking = null;
+
+        if (mHistorySize >= 0 && N > mHistorySize) {
+            forgetUndos(null, N - mHistorySize);
+        }
+    }
+
+    /**
+     * Commit the last finished undo state.  This undo state can no longer be
+     * modified with further {@link #MERGE_MODE_UNIQUE} or
+     * {@link #MERGE_MODE_ANY} merge modes.  If called while inside of an update,
+     * this will push any changes in the current update on to the undo stack
+     * and result with a fresh undo state, behaving as if {@link #endUpdate()}
+     * had been called enough to unwind the current update, then the last state
+     * committed, and {@link #beginUpdate} called to restore the update nesting.
+     * @param owner The optional owner to determine whether to perform the commit.
+     * If this is non-null, the commit will only execute if the current top undo
+     * state contains an operation with the given owner.
+     * @return Returns an integer identifier for the committed undo state, which
+     * can later be used to try to uncommit the state to perform further edits on it.
+     */
+    public int commitState(UndoOwner owner) {
+        if (mWorking != null && mWorking.hasData()) {
+            if (owner == null || mWorking.hasOperation(owner)) {
+                mWorking.setCanMerge(false);
+                int commitId = mWorking.getCommitId();
+                pushWorkingState();
+                createWorkingState();
+                mMerged = true;
+                return commitId;
+            }
+        } else {
+            UndoState state = getTopUndo(null);
+            if (state != null && (owner == null || state.hasOperation(owner))) {
+                state.setCanMerge(false);
+                return state.getCommitId();
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Attempt to undo a previous call to {@link #commitState}.  This will work
+     * if the undo state at the top of the stack has the given id, and has not been
+     * involved in an undo operation.  Otherwise false is returned.
+     * @param commitId The identifier for the state to be uncommitted, as returned
+     * by {@link #commitState}.
+     * @param owner Optional owner that must appear in the committed state.
+     * @return Returns true if the uncommit is successful, else false.
+     */
+    public boolean uncommitState(int commitId, UndoOwner owner) {
+        if (mWorking != null && mWorking.getCommitId() == commitId) {
+            if (owner == null || mWorking.hasOperation(owner)) {
+                return mWorking.setCanMerge(true);
+            }
+        } else {
+            UndoState state = getTopUndo(null);
+            if (state != null && (owner == null || state.hasOperation(owner))) {
+                if (state.getCommitId() == commitId) {
+                    return state.setCanMerge(true);
+                }
+            }
+        }
+        return false;
+    }
+
+    UndoState getTopUndo(UndoOwner[] owners) {
+        if (mUndos.size() <= 0) {
+            return null;
+        }
+        int i = findPrevState(mUndos, owners, -1);
+        return i >= 0 ? mUndos.get(i) : null;
+    }
+
+    UndoState getTopRedo(UndoOwner[] owners) {
+        if (mRedos.size() <= 0) {
+            return null;
+        }
+        int i = findPrevState(mRedos, owners, -1);
+        return i >= 0 ? mRedos.get(i) : null;
+    }
+
+    boolean matchOwners(UndoState state, UndoOwner[] owners) {
+        if (owners == null) {
+            return true;
+        }
+        for (int i=0; i<owners.length; i++) {
+            if (state.matchOwner(owners[i])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    int findPrevState(ArrayList<UndoState> states, UndoOwner[] owners, int from) {
+        final int N = states.size();
+
+        if (from == -1) {
+            from = N-1;
+        }
+        if (from >= N) {
+            return -1;
+        }
+        if (owners == null) {
+            return from;
+        }
+
+        while (from >= 0) {
+            UndoState state = states.get(from);
+            if (matchOwners(state, owners)) {
+                return from;
+            }
+            from--;
+        }
+
+        return -1;
+    }
+
+    int findNextState(ArrayList<UndoState> states, UndoOwner[] owners, int from) {
+        final int N = states.size();
+
+        if (from < 0) {
+            from = 0;
+        }
+        if (from >= N) {
+            return -1;
+        }
+        if (owners == null) {
+            return from;
+        }
+
+        while (from < N) {
+            UndoState state = states.get(from);
+            if (matchOwners(state, owners)) {
+                return from;
+            }
+            from++;
+        }
+
+        return -1;
+    }
+
+    final static class UndoState {
+        private final UndoManager mManager;
+        private final int mCommitId;
+        private final ArrayList<UndoOperation<?>> mOperations = new ArrayList<UndoOperation<?>>();
+        private ArrayList<UndoOperation<?>> mRecent;
+        private CharSequence mLabel;
+        private boolean mCanMerge = true;
+        private boolean mExecuted;
+
+        UndoState(UndoManager manager, int commitId) {
+            mManager = manager;
+            mCommitId = commitId;
+        }
+
+        UndoState(UndoManager manager, Parcel p, ClassLoader loader) {
+            mManager = manager;
+            mCommitId = p.readInt();
+            mCanMerge = p.readInt() != 0;
+            mExecuted = p.readInt() != 0;
+            mLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(p);
+            final int N = p.readInt();
+            for (int i=0; i<N; i++) {
+                UndoOwner owner = mManager.restoreOwner(p);
+                UndoOperation op = (UndoOperation)p.readParcelable(loader);
+                op.mOwner = owner;
+                mOperations.add(op);
+            }
+        }
+
+        void writeToParcel(Parcel p) {
+            if (mRecent != null) {
+                throw new IllegalStateException("Can't save state before committing");
+            }
+            p.writeInt(mCommitId);
+            p.writeInt(mCanMerge ? 1 : 0);
+            p.writeInt(mExecuted ? 1 : 0);
+            TextUtils.writeToParcel(mLabel, p, 0);
+            final int N = mOperations.size();
+            p.writeInt(N);
+            for (int i=0; i<N; i++) {
+                UndoOperation op = mOperations.get(i);
+                mManager.saveOwner(op.mOwner, p);
+                p.writeParcelable(op, 0);
+            }
+        }
+
+        int getCommitId() {
+            return mCommitId;
+        }
+
+        void setLabel(CharSequence label) {
+            mLabel = label;
+        }
+
+        void updateLabel(CharSequence label) {
+            if (mLabel != null) {
+                mLabel = label;
+            }
+        }
+
+        CharSequence getLabel() {
+            return mLabel;
+        }
+
+        boolean setCanMerge(boolean state) {
+            // Don't allow re-enabling of merging if state has been executed.
+            if (state && mExecuted) {
+                return false;
+            }
+            mCanMerge = state;
+            return true;
+        }
+
+        void makeExecuted() {
+            mExecuted = true;
+        }
+
+        boolean canMerge() {
+            return mCanMerge && !mExecuted;
+        }
+
+        int countOperations() {
+            return mOperations.size();
+        }
+
+        boolean hasOperation(UndoOwner owner) {
+            final int N = mOperations.size();
+            if (owner == null) {
+                return N != 0;
+            }
+            for (int i=0; i<N; i++) {
+                if (mOperations.get(i).getOwner() == owner) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        boolean hasMultipleOwners() {
+            final int N = mOperations.size();
+            if (N <= 1) {
+                return false;
+            }
+            UndoOwner owner = mOperations.get(0).getOwner();
+            for (int i=1; i<N; i++) {
+                if (mOperations.get(i).getOwner() != owner) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        void addOperation(UndoOperation<?> op) {
+            if (mOperations.contains(op)) {
+                throw new IllegalStateException("Already holds " + op);
+            }
+            mOperations.add(op);
+            if (mRecent == null) {
+                mRecent = new ArrayList<UndoOperation<?>>();
+                mRecent.add(op);
+            }
+            op.mOwner.mOpCount++;
+        }
+
+        <T extends UndoOperation> T getLastOperation(Class<T> clazz, UndoOwner owner) {
+            final int N = mOperations.size();
+            if (clazz == null && owner == null) {
+                return N > 0 ? (T)mOperations.get(N-1) : null;
+            }
+            // First look for the top-most operation with the same owner.
+            for (int i=N-1; i>=0; i--) {
+                UndoOperation<?> op = mOperations.get(i);
+                if (owner != null && op.getOwner() != owner) {
+                    continue;
+                }
+                // Return this operation if it has the same class that the caller wants.
+                // Note that we don't search deeper for the class, because we don't want
+                // to end up with a different order of operations for the same owner.
+                if (clazz != null && op.getClass() != clazz) {
+                    return null;
+                }
+                return (T)op;
+            }
+
+            return null;
+        }
+
+        boolean matchOwner(UndoOwner owner) {
+            for (int i=mOperations.size()-1; i>=0; i--) {
+                if (mOperations.get(i).matchOwner(owner)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        boolean hasData() {
+            for (int i=mOperations.size()-1; i>=0; i--) {
+                if (mOperations.get(i).hasData()) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        void commit() {
+            final int N = mRecent != null ? mRecent.size() : 0;
+            for (int i=0; i<N; i++) {
+                mRecent.get(i).commit();
+            }
+            mRecent = null;
+        }
+
+        void undo() {
+            for (int i=mOperations.size()-1; i>=0; i--) {
+                mOperations.get(i).undo();
+            }
+        }
+
+        void redo() {
+            final int N = mOperations.size();
+            for (int i=0; i<N; i++) {
+                mOperations.get(i).redo();
+            }
+        }
+
+        void destroy() {
+            for (int i=mOperations.size()-1; i>=0; i--) {
+                UndoOwner owner = mOperations.get(i).mOwner;
+                owner.mOpCount--;
+                if (owner.mOpCount <= 0) {
+                    if (owner.mOpCount < 0) {
+                        throw new IllegalStateException("Underflow of op count on owner " + owner
+                                + " in op " + mOperations.get(i));
+                    }
+                    mManager.removeOwner(owner);
+                }
+            }
+        }
+    }
+}
diff --git a/core/java/android/content/UndoOperation.java b/core/java/android/content/UndoOperation.java
new file mode 100644
index 0000000..1ff32d4
--- /dev/null
+++ b/core/java/android/content/UndoOperation.java
@@ -0,0 +1,112 @@
+/*
+ * 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.content;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A single undoable operation.  You must subclass this to implement the state
+ * and behavior for your operation.  Instances of this class are placed and
+ * managed in an {@link UndoManager}.
+ *
+ * @hide
+ */
+public abstract class UndoOperation<DATA> implements Parcelable {
+    UndoOwner mOwner;
+
+    /**
+     * Create a new instance of the operation.
+     * @param owner Who owns the data being modified by this undo state; must be
+     * returned by {@link UndoManager#getOwner(String, Object) UndoManager.getOwner}.
+     */
+    public UndoOperation(UndoOwner owner) {
+        mOwner = owner;
+    }
+
+    /**
+     * Construct from a Parcel.
+     */
+    protected UndoOperation(Parcel src, ClassLoader loader) {
+    }
+
+    /**
+     * Owning object as given to {@link #UndoOperation(UndoOwner)}.
+     */
+    public UndoOwner getOwner() {
+        return mOwner;
+    }
+
+    /**
+     * Synonym for {@link #getOwner()}.{@link android.content.UndoOwner#getData()}.
+     */
+    public DATA getOwnerData() {
+        return (DATA)mOwner.getData();
+    }
+
+    /**
+     * Return true if this undo operation is a member of the given owner.
+     * The default implementation is <code>owner == getOwner()</code>.  You
+     * can override this to provide more sophisticated dependencies between
+     * owners.
+     */
+    public boolean matchOwner(UndoOwner owner) {
+        return owner == getOwner();
+    }
+
+    /**
+     * Return true if this operation actually contains modification data.  The
+     * default implementation always returns true.  If you return false, the
+     * operation will be dropped when the final undo state is being built.
+     */
+    public boolean hasData() {
+        return true;
+    }
+
+    /**
+     * Return true if this operation can be merged with a later operation.
+     * The default implementation always returns true.
+     */
+    public boolean allowMerge() {
+        return true;
+    }
+
+    /**
+     * Called when this undo state is being committed to the undo stack.
+     * The implementation should perform the initial edits and save any state that
+     * may be needed to undo them.
+     */
+    public abstract void commit();
+
+    /**
+     * Called when this undo state is being popped off the undo stack (in to
+     * the temporary redo stack).  The implementation should remove the original
+     * edits and thus restore the target object to its prior value.
+     */
+    public abstract void undo();
+
+    /**
+     * Called when this undo state is being pushed back from the transient
+     * redo stack to the main undo stack.  The implementation should re-apply
+     * the edits that were previously removed by {@link #undo}.
+     */
+    public abstract void redo();
+
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/core/java/android/content/UndoOwner.java b/core/java/android/content/UndoOwner.java
new file mode 100644
index 0000000..d0cdc95
--- /dev/null
+++ b/core/java/android/content/UndoOwner.java
@@ -0,0 +1,57 @@
+/*
+ * 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.content;
+
+/**
+ * Representation of an owner of {@link UndoOperation} objects in an {@link UndoManager}.
+ *
+ * @hide
+ */
+public class UndoOwner {
+    final String mTag;
+
+    UndoManager mManager;
+    Object mData;
+    int mOpCount;
+
+    // For saving/restoring state.
+    int mStateSeq;
+    int mSavedIdx;
+
+    UndoOwner(String tag) {
+        mTag = tag;
+    }
+
+    /**
+     * Return the unique tag name identifying this owner.  This is the tag
+     * supplied to {@link UndoManager#getOwner(String, Object) UndoManager.getOwner}
+     * and is immutable.
+     */
+    public String getTag() {
+        return mTag;
+    }
+
+    /**
+     * Return the actual data object of the owner.  This is the data object
+     * supplied to {@link UndoManager#getOwner(String, Object) UndoManager.getOwner}.  An
+     * owner may have a null data if it was restored from a previously saved state with
+     * no getOwner call to associate it with its data.
+     */
+    public Object getData() {
+        return mData;
+    }
+}
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 8154bca..b8ac3bf 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -16,6 +16,7 @@
 
 package android.content.pm;
 
+import android.content.res.Configuration;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.Printer;
@@ -437,20 +438,20 @@
      * native side given the bit we have assigned in ActivityInfo.
      */
     public static int[] CONFIG_NATIVE_BITS = new int[] {
-        0x0001, // MNC
-        0x0002, // MCC
-        0x0004, // LOCALE
-        0x0008, // TOUCH SCREEN
-        0x0010, // KEYBOARD
-        0x0020, // KEYBOARD HIDDEN
-        0x0040, // NAVIGATION
-        0x0080, // ORIENTATION
-        0x0800, // SCREEN LAYOUT
-        0x1000, // UI MODE
-        0x0200, // SCREEN SIZE
-        0x2000, // SMALLEST SCREEN SIZE
-        0x0100, // DENSITY
-        0x4000, // LAYOUT DIRECTION
+        Configuration.NATIVE_CONFIG_MNC,                    // MNC
+        Configuration.NATIVE_CONFIG_MCC,                    // MCC
+        Configuration.NATIVE_CONFIG_LOCALE,                 // LOCALE
+        Configuration.NATIVE_CONFIG_TOUCHSCREEN,            // TOUCH SCREEN
+        Configuration.NATIVE_CONFIG_KEYBOARD,               // KEYBOARD
+        Configuration.NATIVE_CONFIG_KEYBOARD_HIDDEN,        // KEYBOARD HIDDEN
+        Configuration.NATIVE_CONFIG_NAVIGATION,             // NAVIGATION
+        Configuration.NATIVE_CONFIG_ORIENTATION,            // ORIENTATION
+        Configuration.NATIVE_CONFIG_SCREEN_LAYOUT,          // SCREEN LAYOUT
+        Configuration.NATIVE_CONFIG_UI_MODE,                // UI MODE
+        Configuration.NATIVE_CONFIG_SCREEN_SIZE,            // SCREEN SIZE
+        Configuration.NATIVE_CONFIG_SMALLEST_SCREEN_SIZE,   // SMALLEST SCREEN SIZE
+        Configuration.NATIVE_CONFIG_DENSITY,                // DENSITY
+        Configuration.NATIVE_CONFIG_LAYOUTDIR,              // LAYOUT DIRECTION
     };
     /** @hide
      * Convert Java change bits to native.
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 02401dc..9c46d96 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -315,6 +315,14 @@
     public static final int FLAG_IS_DATA_ONLY = 1<<24;
 
     /**
+     * Value for {@link #flags}: set to {@code true} if the application
+     * is permitted to hold privileged permissions.
+     *
+     * {@hide}
+     */
+    public static final int FLAG_PRIVILEGED = 1<<30;
+
+    /**
      * Value for {@link #flags}: Set to true if the application has been
      * installed using the forward lock option.
      *
@@ -338,6 +346,13 @@
     public static final int FLAG_CANT_SAVE_STATE = 1<<28;
 
     /**
+     * Value for {@link #flags}: true if the application is blocked via restrictions and for
+     * most purposes is considered as not installed.
+     * {@hide}
+     */
+    public static final int FLAG_BLOCKED = 1<<27;
+
+    /**
      * Flags associated with the application.  Any combination of
      * {@link #FLAG_SYSTEM}, {@link #FLAG_DEBUGGABLE}, {@link #FLAG_HAS_CODE},
      * {@link #FLAG_PERSISTENT}, {@link #FLAG_FACTORY_TEST}, and
@@ -351,7 +366,7 @@
      * {@link #FLAG_INSTALLED}.
      */
     public int flags = 0;
-    
+
     /**
      * The required smallest screen width the application can run on.  If 0,
      * nothing has been specified.  Comes from
diff --git a/core/java/android/content/pm/ComponentInfo.java b/core/java/android/content/pm/ComponentInfo.java
index 2812477..4dbcf23 100644
--- a/core/java/android/content/pm/ComponentInfo.java
+++ b/core/java/android/content/pm/ComponentInfo.java
@@ -116,6 +116,17 @@
     public final int getIconResource() {
         return icon != 0 ? icon : applicationInfo.icon;
     }
+
+    /**
+     * Return the logo resource identifier to use for this component.  If
+     * the component defines a logo, that is used; else, the application
+     * logo is used.
+     *
+     * @return The logo associated with this component.
+     */
+    public final int getLogoResource() {
+        return logo != 0 ? logo : applicationInfo.logo;
+    }
     
     protected void dumpFront(Printer pw, String prefix) {
         super.dumpFront(pw, prefix);
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index a0e1555..acd4ffa 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -101,7 +101,9 @@
     String getNameForUid(int uid);
     
     int getUidForSharedUser(String sharedUserName);
-    
+
+    int getFlagsForUid(int uid);
+
     ResolveInfo resolveIntent(in Intent intent, String resolvedType, int flags, int userId);
 
     List<ResolveInfo> queryIntentActivities(in Intent intent, 
@@ -214,6 +216,12 @@
 
     void resetPreferredActivities(int userId);
 
+    ResolveInfo getLastChosenActivity(in Intent intent,
+            String resolvedType, int flags);
+
+    void setLastChosenActivity(in Intent intent, String resolvedType, int flags,
+            in IntentFilter filter, int match, in ComponentName activity);
+
     void addPreferredActivity(in IntentFilter filter, int match,
             in ComponentName[] set, in ComponentName activity, int userId);
 
@@ -224,7 +232,13 @@
 
     int getPreferredActivities(out List<IntentFilter> outFilters,
             out List<ComponentName> outActivities, String packageName);
-    
+
+    /**
+     * Report the set of 'Home' activity candidates, plus (if any) which of them
+     * is the current "always use this one" setting.
+     */
+     ComponentName getHomeActivities(out List<ResolveInfo> outHomeCandidates);
+
     /**
      * As per {@link android.content.pm.PackageManager#setComponentEnabledSetting}.
      */
@@ -399,4 +413,7 @@
 
     /** Reflects current DeviceStorageMonitorService state */
     boolean isStorageLow();
+
+    boolean setApplicationBlockedSettingAsUser(String packageName, boolean blocked, int userId);
+    boolean getApplicationBlockedSettingAsUser(String packageName, int userId);
 }
diff --git a/core/java/android/content/pm/KeySet.java b/core/java/android/content/pm/KeySet.java
new file mode 100644
index 0000000..0ef09a4
--- /dev/null
+++ b/core/java/android/content/pm/KeySet.java
@@ -0,0 +1,34 @@
+/*
+ * 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.content.pm;
+
+import android.os.Binder;
+
+/** @hide */
+public class KeySet {
+
+    private Binder token;
+
+    /** @hide */
+    public KeySet(Binder token) {
+        this.token = token;
+    }
+
+    Binder getToken() {
+        return token;
+    }
+}
\ No newline at end of file
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 4266d85..416f489 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -955,6 +955,26 @@
 
     /**
      * Feature for {@link #getSystemAvailableFeatures} and
+     * {@link #hasSystemFeature}: The device supports host-
+     * based NFC card emulation.
+     *
+     * TODO remove when depending apps have moved to new constant.
+     * @hide
+     * @deprecated
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_NFC_HCE = "android.hardware.nfc.hce";
+
+    /**
+     * Feature for {@link #getSystemAvailableFeatures} and
+     * {@link #hasSystemFeature}: The device supports host-
+     * based NFC card emulation.
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_NFC_HOST_CARD_EMULATION = "android.hardware.nfc.hce";
+
+    /**
+     * Feature for {@link #getSystemAvailableFeatures} and
      * {@link #hasSystemFeature}: The device includes an accelerometer.
      */
     @SdkConstant(SdkConstantType.FEATURE)
@@ -3007,6 +3027,13 @@
             List<ComponentName> outActivities, String packageName);
 
     /**
+     * Ask for the set of available 'home' activities and the current explicit
+     * default, if any.
+     * @hide
+     */
+    public abstract ComponentName getHomeActivities(List<ResolveInfo> outActivities);
+
+    /**
      * Set the enabled setting for a package component (activity, receiver, service, provider).
      * This setting will override any enabled state which may have been set by the component in its
      * manifest.
@@ -3083,6 +3110,23 @@
     public abstract int getApplicationEnabledSetting(String packageName);
 
     /**
+     * Puts the package in a blocked state, which is almost like an uninstalled state,
+     * making the package unavailable, but it doesn't remove the data or the actual
+     * package file.
+     * @hide
+     */
+    public abstract boolean setApplicationBlockedSettingAsUser(String packageName, boolean blocked,
+            UserHandle userHandle);
+
+    /**
+     * Returns the blocked state of a package.
+     * @see #setApplicationBlockedSettingAsUser(String, boolean, UserHandle)
+     * @hide
+     */
+    public abstract boolean getApplicationBlockedSettingAsUser(String packageName,
+            UserHandle userHandle);
+
+    /**
      * Return whether the device has been booted into safe mode.
      */
     public abstract boolean isSafeMode();
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 34e0c12..4494e69 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -50,9 +50,12 @@
 import java.security.spec.X509EncodedKeySpec;
 import java.util.ArrayList;
 import java.util.Enumeration;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
 import java.util.zip.ZipEntry;
@@ -153,7 +156,8 @@
     private static WeakReference<byte[]> mReadBuffer;
 
     private static boolean sCompatibilityModeEnabled = true;
-    private static final int PARSE_DEFAULT_INSTALL_LOCATION = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
+    private static final int PARSE_DEFAULT_INSTALL_LOCATION =
+            PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
 
     static class ParsePackageItemArgs {
         final Package owner;
@@ -268,15 +272,20 @@
                 grantedPermissions, state, UserHandle.getCallingUserId());
     }
 
-    private static boolean checkUseInstalled(int flags, PackageUserState state) {
-        return state.installed || ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0);
+    /**
+     * Returns true if the package is installed and not blocked, or if the caller
+     * explicitly wanted all uninstalled and blocked packages as well.
+     */
+    private static boolean checkUseInstalledOrBlocked(int flags, PackageUserState state) {
+        return (state.installed && !state.blocked)
+                || (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
     }
 
     public static PackageInfo generatePackageInfo(PackageParser.Package p,
             int gids[], int flags, long firstInstallTime, long lastUpdateTime,
             HashSet<String> grantedPermissions, PackageUserState state, int userId) {
 
-        if (!checkUseInstalled(flags, state)) {
+        if (!checkUseInstalledOrBlocked(flags, state)) {
             return null;
         }
         PackageInfo pi = new PackageInfo();
@@ -470,6 +479,7 @@
     public final static int PARSE_FORWARD_LOCK = 1<<4;
     public final static int PARSE_ON_SDCARD = 1<<5;
     public final static int PARSE_IS_SYSTEM_DIR = 1<<6;
+    public final static int PARSE_IS_PRIVILEGED = 1<<7;
 
     public int getParseError() {
         return mParseError;
@@ -714,6 +724,13 @@
                 mParseError = PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES;
                 return false;
             }
+
+            // Add the signing KeySet to the system
+            pkg.mSigningKeys = new HashSet<PublicKey>();
+            for (int i=0; i < certs.length; i++) {
+                pkg.mSigningKeys.add(certs[i].getPublicKey());
+            }
+
         } catch (CertificateEncodingException e) {
             Slog.w(TAG, "Exception reading " + mArchiveSourcePath, e);
             mParseError = PackageManager.INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING;
@@ -1027,6 +1044,10 @@
                 if (!parseApplication(pkg, res, parser, attrs, flags, outError)) {
                     return null;
                 }
+            } else if (tagName.equals("keys")) {
+                if (!parseKeys(pkg, res, parser, attrs, outError)) {
+                    return null;
+                }
             } else if (tagName.equals("permission-group")) {
                 if (parsePermissionGroup(pkg, flags, res, parser, attrs, outError) == null) {
                     return null;
@@ -1290,6 +1311,9 @@
                 // Just skip this tag
                 XmlUtils.skipCurrentTag(parser);
                 continue;
+            } else if (tagName.equals("supports-input")) {
+                XmlUtils.skipCurrentTag(parser);
+                continue;
                 
             } else if (tagName.equals("eat-comment")) {
                 // Just skip this tag
@@ -1519,7 +1543,88 @@
         }
         return buildCompoundName(pkg, procSeq, "taskAffinity", outError);
     }
-    
+
+    private boolean parseKeys(Package owner, Resources res,
+            XmlPullParser parser, AttributeSet attrs, String[] outError)
+            throws XmlPullParserException, IOException {
+        // we've encountered the 'keys' tag
+        // all the keys and keysets that we want must be defined here
+        // so we're going to iterate over the parser and pull out the things we want
+        int outerDepth = parser.getDepth();
+
+        int type;
+        PublicKey currentKey = null;
+        int currentKeyDepth = -1;
+        Map<PublicKey, Set<String>> definedKeySets = new HashMap<PublicKey, Set<String>>();
+        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+            if (type == XmlPullParser.END_TAG) {
+                if (parser.getDepth() == currentKeyDepth) {
+                    currentKey = null;
+                    currentKeyDepth = -1;
+                }
+                continue;
+            }
+            String tagname = parser.getName();
+            if (tagname.equals("publicKey")) {
+                final TypedArray sa = res.obtainAttributes(attrs,
+                        com.android.internal.R.styleable.PublicKey);
+                final String encodedKey = sa.getNonResourceString(
+                    com.android.internal.R.styleable.PublicKey_value);
+                currentKey = parsePublicKey(encodedKey);
+                if (currentKey == null) {
+                    Slog.w(TAG, "No valid key in 'publicKey' tag at "
+                            + parser.getPositionDescription());
+                    sa.recycle();
+                    continue;
+                }
+                currentKeyDepth = parser.getDepth();
+                definedKeySets.put(currentKey, new HashSet<String>());
+                sa.recycle();
+            } else if (tagname.equals("keyset")) {
+                if (currentKey == null) {
+                    Slog.i(TAG, "'keyset' not in 'publicKey' tag at "
+                            + parser.getPositionDescription());
+                    continue;
+                }
+                final TypedArray sa = res.obtainAttributes(attrs,
+                        com.android.internal.R.styleable.KeySet);
+                final String name = sa.getNonResourceString(
+                    com.android.internal.R.styleable.KeySet_name);
+                definedKeySets.get(currentKey).add(name);
+                sa.recycle();
+            } else if (RIGID_PARSER) {
+                Slog.w(TAG, "Bad element under <keys>: " + parser.getName()
+                        + " at " + mArchiveSourcePath + " "
+                        + parser.getPositionDescription());
+                return false;
+            } else {
+                Slog.w(TAG, "Unknown element under <keys>: " + parser.getName()
+                        + " at " + mArchiveSourcePath + " "
+                        + parser.getPositionDescription());
+                XmlUtils.skipCurrentTag(parser);
+                continue;
+            }
+        }
+
+        owner.mKeySetMapping = new HashMap<String, Set<PublicKey>>();
+        for (Map.Entry<PublicKey, Set<String>> e : definedKeySets.entrySet()) {
+            PublicKey key = e.getKey();
+            Set<String> keySetNames = e.getValue();
+            for (String alias : keySetNames) {
+                if (owner.mKeySetMapping.containsKey(alias)) {
+                    owner.mKeySetMapping.get(alias).add(key);
+                } else {
+                    Set<PublicKey> keys = new HashSet<PublicKey>();
+                    keys.add(key);
+                    owner.mKeySetMapping.put(alias, keys);
+                }
+            }
+        }
+
+        return true;
+    }
+
     private PermissionGroup parsePermissionGroup(Package owner, int flags, Resources res,
             XmlPullParser parser, AttributeSet attrs, String[] outError)
         throws XmlPullParserException, IOException {
@@ -1759,7 +1864,8 @@
         }
 
         String manageSpaceActivity = sa.getNonConfigurationString(
-                com.android.internal.R.styleable.AndroidManifestApplication_manageSpaceActivity, 0);
+                com.android.internal.R.styleable.AndroidManifestApplication_manageSpaceActivity,
+                Configuration.NATIVE_CONFIG_VERSION);
         if (manageSpaceActivity != null) {
             ai.manageSpaceActivityName = buildClassName(pkgName, manageSpaceActivity,
                     outError);
@@ -1773,7 +1879,8 @@
             // backupAgent, killAfterRestore, and restoreAnyVersion are only relevant
             // if backup is possible for the given application.
             String backupAgent = sa.getNonConfigurationString(
-                    com.android.internal.R.styleable.AndroidManifestApplication_backupAgent, 0);
+                    com.android.internal.R.styleable.AndroidManifestApplication_backupAgent,
+                    Configuration.NATIVE_CONFIG_VERSION);
             if (backupAgent != null) {
                 ai.backupAgentName = buildClassName(pkgName, backupAgent, outError);
                 if (DEBUG_BACKUP) {
@@ -1894,7 +2001,8 @@
 
         if (owner.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.FROYO) {
             str = sa.getNonConfigurationString(
-                    com.android.internal.R.styleable.AndroidManifestApplication_taskAffinity, 0);
+                    com.android.internal.R.styleable.AndroidManifestApplication_taskAffinity,
+                    Configuration.NATIVE_CONFIG_VERSION);
         } else {
             // Some older apps have been seen to use a resource reference
             // here that on older builds was ignored (with a warning).  We
@@ -1909,7 +2017,8 @@
             CharSequence pname;
             if (owner.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.FROYO) {
                 pname = sa.getNonConfigurationString(
-                        com.android.internal.R.styleable.AndroidManifestApplication_process, 0);
+                        com.android.internal.R.styleable.AndroidManifestApplication_process,
+                        Configuration.NATIVE_CONFIG_VERSION);
             } else {
                 // Some older apps have been seen to use a resource reference
                 // here that on older builds was ignored (with a warning).  We
@@ -2173,7 +2282,8 @@
                 a.info.applicationInfo.uiOptions);
 
         String parentName = sa.getNonConfigurationString(
-                com.android.internal.R.styleable.AndroidManifestActivity_parentActivityName, 0);
+                com.android.internal.R.styleable.AndroidManifestActivity_parentActivityName,
+                Configuration.NATIVE_CONFIG_VERSION);
         if (parentName != null) {
             String parentClassName = buildClassName(a.info.packageName, parentName, outError);
             if (outError[0] == null) {
@@ -2195,7 +2305,8 @@
         }
 
         str = sa.getNonConfigurationString(
-                com.android.internal.R.styleable.AndroidManifestActivity_taskAffinity, 0);
+                com.android.internal.R.styleable.AndroidManifestActivity_taskAffinity,
+                Configuration.NATIVE_CONFIG_VERSION);
         a.info.taskAffinity = buildTaskAffinityName(owner.applicationInfo.packageName,
                 owner.applicationInfo.taskAffinity, str, outError);
 
@@ -2335,7 +2446,7 @@
 
             if (parser.getName().equals("intent-filter")) {
                 ActivityIntentInfo intent = new ActivityIntentInfo(a);
-                if (!parseIntent(res, parser, attrs, flags, intent, outError, !receiver)) {
+                if (!parseIntent(res, parser, attrs, true, intent, outError)) {
                     return null;
                 }
                 if (intent.countActions() == 0) {
@@ -2345,6 +2456,21 @@
                 } else {
                     a.intents.add(intent);
                 }
+            } else if (!receiver && parser.getName().equals("preferred")) {
+                ActivityIntentInfo intent = new ActivityIntentInfo(a);
+                if (!parseIntent(res, parser, attrs, false, intent, outError)) {
+                    return null;
+                }
+                if (intent.countActions() == 0) {
+                    Slog.w(TAG, "No actions in preferred at "
+                            + mArchiveSourcePath + " "
+                            + parser.getPositionDescription());
+                } else {
+                    if (owner.preferredActivityFilters == null) {
+                        owner.preferredActivityFilters = new ArrayList<ActivityIntentInfo>();
+                    }
+                    owner.preferredActivityFilters.add(intent);
+                }
             } else if (parser.getName().equals("meta-data")) {
                 if ((a.metaData=parseMetaData(res, parser, attrs, a.metaData,
                         outError)) == null) {
@@ -2389,7 +2515,8 @@
                 com.android.internal.R.styleable.AndroidManifestActivityAlias);
 
         String targetActivity = sa.getNonConfigurationString(
-                com.android.internal.R.styleable.AndroidManifestActivityAlias_targetActivity, 0);
+                com.android.internal.R.styleable.AndroidManifestActivityAlias_targetActivity,
+                Configuration.NATIVE_CONFIG_VERSION);
         if (targetActivity == null) {
             outError[0] = "<activity-alias> does not specify android:targetActivity";
             sa.recycle();
@@ -2479,7 +2606,7 @@
 
         String parentName = sa.getNonConfigurationString(
                 com.android.internal.R.styleable.AndroidManifestActivityAlias_parentActivityName,
-                0);
+                Configuration.NATIVE_CONFIG_VERSION);
         if (parentName != null) {
             String parentClassName = buildClassName(a.info.packageName, parentName, outError);
             if (outError[0] == null) {
@@ -2508,7 +2635,7 @@
 
             if (parser.getName().equals("intent-filter")) {
                 ActivityIntentInfo intent = new ActivityIntentInfo(a);
-                if (!parseIntent(res, parser, attrs, flags, intent, outError, true)) {
+                if (!parseIntent(res, parser, attrs, true, intent, outError)) {
                     return null;
                 }
                 if (intent.countActions() == 0) {
@@ -2932,7 +3059,7 @@
 
             if (parser.getName().equals("intent-filter")) {
                 ServiceIntentInfo intent = new ServiceIntentInfo(s);
-                if (!parseIntent(res, parser, attrs, flags, intent, outError, false)) {
+                if (!parseIntent(res, parser, attrs, true, intent, outError)) {
                     return null;
                 }
 
@@ -3083,20 +3210,28 @@
             Slog.i(TAG, "verifier " + packageName + " public key was null; skipping");
         }
 
+        PublicKey publicKey = parsePublicKey(encodedPublicKey);
+        if (publicKey != null) {
+            return new VerifierInfo(packageName, publicKey);
+        }
+
+        return null;
+    }
+
+    public static final PublicKey parsePublicKey(String encodedPublicKey) {
         EncodedKeySpec keySpec;
         try {
             final byte[] encoded = Base64.decode(encodedPublicKey, Base64.DEFAULT);
             keySpec = new X509EncodedKeySpec(encoded);
         } catch (IllegalArgumentException e) {
-            Slog.i(TAG, "Could not parse verifier " + packageName + " public key; invalid Base64");
+            Slog.i(TAG, "Could not parse verifier public key; invalid Base64");
             return null;
         }
 
         /* First try the key as an RSA key. */
         try {
             final KeyFactory keyFactory = KeyFactory.getInstance("RSA");
-            final PublicKey publicKey = keyFactory.generatePublic(keySpec);
-            return new VerifierInfo(packageName, publicKey);
+            return keyFactory.generatePublic(keySpec);
         } catch (NoSuchAlgorithmException e) {
             Log.wtf(TAG, "Could not parse public key because RSA isn't included in build");
             return null;
@@ -3107,8 +3242,7 @@
         /* Now try it as a DSA key. */
         try {
             final KeyFactory keyFactory = KeyFactory.getInstance("DSA");
-            final PublicKey publicKey = keyFactory.generatePublic(keySpec);
-            return new VerifierInfo(packageName, publicKey);
+            return keyFactory.generatePublic(keySpec);
         } catch (NoSuchAlgorithmException e) {
             Log.wtf(TAG, "Could not parse public key because DSA isn't included in build");
             return null;
@@ -3122,9 +3256,8 @@
     private static final String ANDROID_RESOURCES
             = "http://schemas.android.com/apk/res/android";
 
-    private boolean parseIntent(Resources res,
-            XmlPullParser parser, AttributeSet attrs, int flags,
-            IntentInfo outInfo, String[] outError, boolean isActivity)
+    private boolean parseIntent(Resources res, XmlPullParser parser, AttributeSet attrs,
+            boolean allowGlobs, IntentInfo outInfo, String[] outError)
             throws XmlPullParserException, IOException {
 
         TypedArray sa = res.obtainAttributes(attrs,
@@ -3200,6 +3333,28 @@
                     outInfo.addDataScheme(str);
                 }
 
+                str = sa.getNonConfigurationString(
+                        com.android.internal.R.styleable.AndroidManifestData_ssp, 0);
+                if (str != null) {
+                    outInfo.addDataSchemeSpecificPart(str, PatternMatcher.PATTERN_LITERAL);
+                }
+
+                str = sa.getNonConfigurationString(
+                        com.android.internal.R.styleable.AndroidManifestData_sspPrefix, 0);
+                if (str != null) {
+                    outInfo.addDataSchemeSpecificPart(str, PatternMatcher.PATTERN_PREFIX);
+                }
+
+                str = sa.getNonConfigurationString(
+                        com.android.internal.R.styleable.AndroidManifestData_sspPattern, 0);
+                if (str != null) {
+                    if (!allowGlobs) {
+                        outError[0] = "sspPattern not allowed here; ssp must be literal";
+                        return false;
+                    }
+                    outInfo.addDataSchemeSpecificPart(str, PatternMatcher.PATTERN_SIMPLE_GLOB);
+                }
+
                 String host = sa.getNonConfigurationString(
                         com.android.internal.R.styleable.AndroidManifestData_host, 0);
                 String port = sa.getNonConfigurationString(
@@ -3223,6 +3378,10 @@
                 str = sa.getNonConfigurationString(
                         com.android.internal.R.styleable.AndroidManifestData_pathPattern, 0);
                 if (str != null) {
+                    if (!allowGlobs) {
+                        outError[0] = "pathPattern not allowed here; path must be literal";
+                        return false;
+                    }
                     outInfo.addDataPath(str, PatternMatcher.PATTERN_SIMPLE_GLOB);
                 }
 
@@ -3284,6 +3443,8 @@
         public ArrayList<String> usesOptionalLibraries = null;
         public String[] usesLibraryFiles = null;
 
+        public ArrayList<ActivityIntentInfo> preferredActivityFilters = null;
+
         public ArrayList<String> mOriginalPackages = null;
         public String mRealPackage = null;
         public ArrayList<String> mAdoptPermissions = null;
@@ -3360,6 +3521,12 @@
          */
         public ManifestDigest manifestDigest;
 
+        /**
+         * Data used to feed the KeySetManager
+         */
+        public Set<PublicKey> mSigningKeys;
+        public Map<String, Set<PublicKey>> mKeySetMapping;
+
         public Package(String _name) {
             packageName = _name;
             applicationInfo.packageName = _name;
@@ -3491,7 +3658,8 @@
             if (args.processRes != 0) {
                 CharSequence pname;
                 if (owner.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.FROYO) {
-                    pname = args.sa.getNonConfigurationString(args.processRes, 0);
+                    pname = args.sa.getNonConfigurationString(args.processRes,
+                            Configuration.NATIVE_CONFIG_VERSION);
                 } else {
                     // Some older apps have been seen to use a resource reference
                     // here that on older builds was ignored (with a warning).  We
@@ -3611,7 +3779,7 @@
                 return true;
             }
         }
-        if (!state.installed) {
+        if (!state.installed || state.blocked) {
             return true;
         }
         if (state.stopped) {
@@ -3644,6 +3812,11 @@
         } else {
             ai.flags &= ~ApplicationInfo.FLAG_INSTALLED;
         }
+        if (state.blocked) {
+            ai.flags |= ApplicationInfo.FLAG_BLOCKED;
+        } else {
+            ai.flags &= ~ApplicationInfo.FLAG_BLOCKED;
+        }
         if (state.enabled == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
             ai.enabled = true;
         } else if (state.enabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
@@ -3658,7 +3831,7 @@
     public static ApplicationInfo generateApplicationInfo(Package p, int flags,
             PackageUserState state, int userId) {
         if (p == null) return null;
-        if (!checkUseInstalled(flags, state)) {
+        if (!checkUseInstalledOrBlocked(flags, state)) {
             return null;
         }
         if (!copyNeeded(flags, p, state, null, userId)
@@ -3742,7 +3915,7 @@
     public static final ActivityInfo generateActivityInfo(Activity a, int flags,
             PackageUserState state, int userId) {
         if (a == null) return null;
-        if (!checkUseInstalled(flags, state)) {
+        if (!checkUseInstalledOrBlocked(flags, state)) {
             return null;
         }
         if (!copyNeeded(flags, a.owner, state, a.metaData, userId)) {
@@ -3779,7 +3952,7 @@
     public static final ServiceInfo generateServiceInfo(Service s, int flags,
             PackageUserState state, int userId) {
         if (s == null) return null;
-        if (!checkUseInstalled(flags, state)) {
+        if (!checkUseInstalledOrBlocked(flags, state)) {
             return null;
         }
         if (!copyNeeded(flags, s.owner, state, s.metaData, userId)) {
@@ -3824,7 +3997,7 @@
     public static final ProviderInfo generateProviderInfo(Provider p, int flags,
             PackageUserState state, int userId) {
         if (p == null) return null;
-        if (!checkUseInstalled(flags, state)) {
+        if (!checkUseInstalledOrBlocked(flags, state)) {
             return null;
         }
         if (!copyNeeded(flags, p.owner, state, p.metaData, userId)
@@ -3879,6 +4052,7 @@
         public CharSequence nonLocalizedLabel;
         public int icon;
         public int logo;
+        public int preferred;
     }
 
     public final static class ActivityIntentInfo extends IntentInfo {
diff --git a/core/java/android/content/pm/PackageUserState.java b/core/java/android/content/pm/PackageUserState.java
index dcd54fc..94e3f79 100644
--- a/core/java/android/content/pm/PackageUserState.java
+++ b/core/java/android/content/pm/PackageUserState.java
@@ -28,6 +28,7 @@
     public boolean stopped;
     public boolean notLaunched;
     public boolean installed;
+    public boolean blocked; // Is the app restricted by owner / admin
     public int enabled;
 
     public String lastDisableAppCaller;
@@ -37,6 +38,7 @@
 
     public PackageUserState() {
         installed = true;
+        blocked = false;
         enabled = COMPONENT_ENABLED_STATE_DEFAULT;
     }
 
@@ -45,6 +47,7 @@
         stopped = o.stopped;
         notLaunched = o.notLaunched;
         enabled = o.enabled;
+        blocked = o.blocked;
         lastDisableAppCaller = o.lastDisableAppCaller;
         disabledComponents = o.disabledComponents != null
                 ? new HashSet<String>(o.disabledComponents) : null;
diff --git a/core/java/android/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java
index 288d55f..875e8de 100644
--- a/core/java/android/content/pm/RegisteredServicesCache.java
+++ b/core/java/android/content/pm/RegisteredServicesCache.java
@@ -82,7 +82,7 @@
     @GuardedBy("mServicesLock")
     private boolean mPersistentServicesFileDidNotExist;
     @GuardedBy("mServicesLock")
-    private final SparseArray<UserServices<V>> mUserServices = new SparseArray<UserServices<V>>();
+    private final SparseArray<UserServices<V>> mUserServices = new SparseArray<UserServices<V>>(2);
 
     private static class UserServices<V> {
         @GuardedBy("mServicesLock")
diff --git a/core/java/android/content/pm/ResolveInfo.java b/core/java/android/content/pm/ResolveInfo.java
index 07117fe..de8e256 100644
--- a/core/java/android/content/pm/ResolveInfo.java
+++ b/core/java/android/content/pm/ResolveInfo.java
@@ -328,6 +328,7 @@
             implements Comparator<ResolveInfo> {
         public DisplayNameComparator(PackageManager pm) {
             mPM = pm;
+            mCollator.setStrength(Collator.PRIMARY);
         }
 
         public final int compare(ResolveInfo a, ResolveInfo b) {
@@ -336,10 +337,10 @@
             CharSequence  sb = b.loadLabel(mPM);
             if (sb == null) sb = b.activityInfo.name;
             
-            return sCollator.compare(sa.toString(), sb.toString());
+            return mCollator.compare(sa.toString(), sb.toString());
         }
 
-        private final Collator   sCollator = Collator.getInstance();
+        private final Collator   mCollator = Collator.getInstance();
         private PackageManager   mPM;
     }
 }
diff --git a/core/java/android/content/res/AssetFileDescriptor.java b/core/java/android/content/res/AssetFileDescriptor.java
index 7d46710..e4cc77f 100644
--- a/core/java/android/content/res/AssetFileDescriptor.java
+++ b/core/java/android/content/res/AssetFileDescriptor.java
@@ -20,6 +20,7 @@
 import android.os.ParcelFileDescriptor;
 import android.os.Parcelable;
 
+import java.io.Closeable;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -30,7 +31,7 @@
  * opened FileDescriptor that can be used to read the data, as well as the
  * offset and length of that entry's data in the file.
  */
-public class AssetFileDescriptor implements Parcelable {
+public class AssetFileDescriptor implements Parcelable, Closeable {
     /**
      * Length used with {@link #AssetFileDescriptor(ParcelFileDescriptor, long, long)}
      * and {@link #getDeclaredLength} when a length has not been declared.  This means
@@ -122,6 +123,7 @@
     /**
      * Convenience for calling <code>getParcelFileDescriptor().close()</code>.
      */
+    @Override
     public void close() throws IOException {
         mFd.close();
     }
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index 28c751c..da35ee9 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -471,8 +471,7 @@
      * Compute the frame Rect for applications runs under compatibility mode.
      *
      * @param dm the display metrics used to compute the frame size.
-     * @param orientation the orientation of the screen.
-     * @param outRect the output parameter which will contain the result.
+     * @param outDm If non-null the width and height will be set to their scaled values.
      * @return Returns the scaling factor for the window.
      */
     public static float computeCompatibleScaling(DisplayMetrics dm, DisplayMetrics outDm) {
@@ -518,6 +517,9 @@
 
     @Override
     public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
         try {
             CompatibilityInfo oc = (CompatibilityInfo)o;
             if (mCompatibilityFlags != oc.mCompatibilityFlags) return false;
@@ -579,10 +581,12 @@
 
     public static final Parcelable.Creator<CompatibilityInfo> CREATOR
             = new Parcelable.Creator<CompatibilityInfo>() {
+        @Override
         public CompatibilityInfo createFromParcel(Parcel source) {
             return new CompatibilityInfo(source);
         }
 
+        @Override
         public CompatibilityInfo[] newArray(int size) {
             return new CompatibilityInfo[size];
         }
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 6318e38..48b6fca 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -544,7 +544,40 @@
      * @hide Internal book-keeping.
      */
     public int seq;
-    
+
+    /** @hide Native-specific bit mask for MCC config; DO NOT USE UNLESS YOU ARE SURE. */
+    public static final int NATIVE_CONFIG_MCC = 0x0001;
+    /** @hide Native-specific bit mask for MNC config; DO NOT USE UNLESS YOU ARE SURE. */
+    public static final int NATIVE_CONFIG_MNC = 0x0002;
+    /** @hide Native-specific bit mask for LOCALE config; DO NOT USE UNLESS YOU ARE SURE. */
+    public static final int NATIVE_CONFIG_LOCALE = 0x0004;
+    /** @hide Native-specific bit mask for TOUCHSCREEN config; DO NOT USE UNLESS YOU ARE SURE. */
+    public static final int NATIVE_CONFIG_TOUCHSCREEN = 0x0008;
+    /** @hide Native-specific bit mask for KEYBOARD config; DO NOT USE UNLESS YOU ARE SURE. */
+    public static final int NATIVE_CONFIG_KEYBOARD = 0x0010;
+    /** @hide Native-specific bit mask for KEYBOARD_HIDDEN config; DO NOT USE UNLESS YOU
+     * ARE SURE. */
+    public static final int NATIVE_CONFIG_KEYBOARD_HIDDEN = 0x0020;
+    /** @hide Native-specific bit mask for NAVIGATION config; DO NOT USE UNLESS YOU ARE SURE. */
+    public static final int NATIVE_CONFIG_NAVIGATION = 0x0040;
+    /** @hide Native-specific bit mask for ORIENTATION config; DO NOT USE UNLESS YOU ARE SURE. */
+    public static final int NATIVE_CONFIG_ORIENTATION = 0x0080;
+    /** @hide Native-specific bit mask for DENSITY config; DO NOT USE UNLESS YOU ARE SURE. */
+    public static final int NATIVE_CONFIG_DENSITY = 0x0100;
+    /** @hide Native-specific bit mask for SCREEN_SIZE config; DO NOT USE UNLESS YOU ARE SURE. */
+    public static final int NATIVE_CONFIG_SCREEN_SIZE = 0x0200;
+    /** @hide Native-specific bit mask for VERSION config; DO NOT USE UNLESS YOU ARE SURE. */
+    public static final int NATIVE_CONFIG_VERSION = 0x0400;
+    /** @hide Native-specific bit mask for SCREEN_LAYOUT config; DO NOT USE UNLESS YOU ARE SURE. */
+    public static final int NATIVE_CONFIG_SCREEN_LAYOUT = 0x0800;
+    /** @hide Native-specific bit mask for UI_MODE config; DO NOT USE UNLESS YOU ARE SURE. */
+    public static final int NATIVE_CONFIG_UI_MODE = 0x1000;
+    /** @hide Native-specific bit mask for SMALLEST_SCREEN_SIZE config; DO NOT USE UNLESS YOU
+     * ARE SURE. */
+    public static final int NATIVE_CONFIG_SMALLEST_SCREEN_SIZE = 0x2000;
+    /** @hide Native-specific bit mask for LAYOUTDIR config ; DO NOT USE UNLESS YOU ARE SURE.*/
+    public static final int NATIVE_CONFIG_LAYOUTDIR = 0x4000;
+
     /**
      * Construct an invalid Configuration.  You must call {@link #setToDefaults}
      * for this object to be valid.  {@more}
@@ -786,10 +819,16 @@
             // 2 most significant bits in screenLayout).
             setLayoutDirection(locale);
         }
+        final int deltaScreenLayoutDir = delta.screenLayout & SCREENLAYOUT_LAYOUTDIR_MASK;
+        if (deltaScreenLayoutDir != SCREENLAYOUT_LAYOUTDIR_UNDEFINED &&
+                deltaScreenLayoutDir != (screenLayout & SCREENLAYOUT_LAYOUTDIR_MASK)) {
+            screenLayout = (screenLayout & ~SCREENLAYOUT_LAYOUTDIR_MASK) | deltaScreenLayoutDir;
+            changed |= ActivityInfo.CONFIG_LAYOUT_DIRECTION;
+        }
         if (delta.userSetLocale && (!userSetLocale || ((changed & ActivityInfo.CONFIG_LOCALE) != 0)))
         {
-            userSetLocale = true;
             changed |= ActivityInfo.CONFIG_LOCALE;
+            userSetLocale = true;
         }
         if (delta.touchscreen != TOUCHSCREEN_UNDEFINED
                 && touchscreen != delta.touchscreen) {
@@ -933,6 +972,11 @@
             changed |= ActivityInfo.CONFIG_LOCALE;
             changed |= ActivityInfo.CONFIG_LAYOUT_DIRECTION;
         }
+        final int deltaScreenLayoutDir = delta.screenLayout & SCREENLAYOUT_LAYOUTDIR_MASK;
+        if (deltaScreenLayoutDir != SCREENLAYOUT_LAYOUTDIR_UNDEFINED &&
+                deltaScreenLayoutDir != (screenLayout & SCREENLAYOUT_LAYOUTDIR_MASK)) {
+            changed |= ActivityInfo.CONFIG_LAYOUT_DIRECTION;
+        }
         if (delta.touchscreen != TOUCHSCREEN_UNDEFINED
                 && touchscreen != delta.touchscreen) {
             changed |= ActivityInfo.CONFIG_TOUCHSCREEN;
@@ -1005,7 +1049,7 @@
     public static boolean needNewResources(int configChanges, int interestingChanges) {
         return (configChanges & (interestingChanges|ActivityInfo.CONFIG_FONT_SCALE)) != 0;
     }
-    
+
     /**
      * @hide Return true if the sequence of 'other' is better than this.  Assumes
      * that 'this' is your current sequence and 'other' is a new one you have
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 42f4faf..6483cd9 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -16,8 +16,6 @@
 
 package android.content.res;
 
-import android.os.Trace;
-import android.view.View;
 import com.android.internal.util.XmlUtils;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -30,12 +28,15 @@
 import android.graphics.drawable.Drawable.ConstantState;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Trace;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.util.Slog;
 import android.util.TypedValue;
 import android.util.LongSparseArray;
+import android.view.DisplayAdjustments;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -100,11 +101,11 @@
     /*package*/ final Configuration mTmpConfig = new Configuration();
     /*package*/ TypedValue mTmpValue = new TypedValue();
     /*package*/ final LongSparseArray<WeakReference<Drawable.ConstantState> > mDrawableCache
-            = new LongSparseArray<WeakReference<Drawable.ConstantState> >();
+            = new LongSparseArray<WeakReference<Drawable.ConstantState> >(0);
     /*package*/ final LongSparseArray<WeakReference<ColorStateList> > mColorStateListCache
-            = new LongSparseArray<WeakReference<ColorStateList> >();
+            = new LongSparseArray<WeakReference<ColorStateList> >(0);
     /*package*/ final LongSparseArray<WeakReference<Drawable.ConstantState> > mColorDrawableCache
-            = new LongSparseArray<WeakReference<Drawable.ConstantState> >();
+            = new LongSparseArray<WeakReference<Drawable.ConstantState> >(0);
     /*package*/ boolean mPreloading;
 
     /*package*/ TypedArray mCachedStyledAttributes = null;
@@ -118,8 +119,9 @@
     private final Configuration mConfiguration = new Configuration();
     /*package*/ final DisplayMetrics mMetrics = new DisplayMetrics();
     private NativePluralRules mPluralRule;
-    
-    private CompatibilityInfo mCompatibilityInfo;
+
+    private CompatibilityInfo mCompatibilityInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
+    private WeakReference<IBinder> mToken;
 
     static {
         sPreloadedDrawables = new LongSparseArray[2];
@@ -174,7 +176,7 @@
      *               selecting/computing resource values (optional).
      */
     public Resources(AssetManager assets, DisplayMetrics metrics, Configuration config) {
-        this(assets, metrics, config, null);
+        this(assets, metrics, config, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
     }
 
     /**
@@ -185,15 +187,16 @@
      *                selecting/computing resource values.
      * @param config Desired device configuration to consider when 
      *               selecting/computing resource values (optional).
-     * @param compInfo this resource's compatibility info. It will use the default compatibility
-     *  info when it's null.
+     * @param compatInfo this resource's compatibility info. Must not be null.
+     * @param token The Activity token for determining stack affiliation. Usually null.
      * @hide
      */
-    public Resources(AssetManager assets, DisplayMetrics metrics,
-            Configuration config, CompatibilityInfo compInfo) {
+    public Resources(AssetManager assets, DisplayMetrics metrics, Configuration config,
+            CompatibilityInfo compatInfo, IBinder token) {
         mAssets = assets;
         mMetrics.setToDefaults();
-        mCompatibilityInfo = compInfo;
+        mCompatibilityInfo = compatInfo;
+        mToken = new WeakReference<IBinder>(token);
         updateConfiguration(config, metrics);
         assets.ensureStringBlocks();
     }
@@ -1665,13 +1668,6 @@
     }
 
     /**
-     * @hide
-     */
-    public static void updateSystemConfiguration(Configuration config, DisplayMetrics metrics) {
-        updateSystemConfiguration(config, metrics, null);
-    }
-    
-    /**
      * Return the current display metrics that are in effect for this resource 
      * object.  The returned object should be treated as read-only.
      * 
@@ -1985,6 +1981,13 @@
         }
     }
 
+    /**
+     * @hide
+     */
+    public LongSparseArray<Drawable.ConstantState> getPreloadedDrawables() {
+        return sPreloadedDrawables[0];
+    }
+
     private boolean verifyPreloadConfig(int changingConfigurations, int allowVarying,
             int resourceId, String name) {
         // We allow preloading of resources even if they vary by font scale (which
diff --git a/core/java/android/content/res/ResourcesKey.java b/core/java/android/content/res/ResourcesKey.java
new file mode 100644
index 0000000..53e0f2c
--- /dev/null
+++ b/core/java/android/content/res/ResourcesKey.java
@@ -0,0 +1,89 @@
+/*
+ * 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.content.res;
+
+import android.os.IBinder;
+
+/** @hide */
+public final class ResourcesKey {
+    final String mResDir;
+    final float mScale;
+    private final int mHash;
+    private final IBinder mToken;
+
+    public final int mDisplayId;
+    public final Configuration mOverrideConfiguration = new Configuration();
+
+    public ResourcesKey(String resDir, int displayId, Configuration overrideConfiguration,
+            float scale, IBinder token) {
+        mResDir = resDir;
+        mDisplayId = displayId;
+        if (overrideConfiguration != null) {
+            mOverrideConfiguration.setTo(overrideConfiguration);
+        }
+        mScale = scale;
+        mToken = token;
+
+        int hash = 17;
+        hash = 31 * hash + (mResDir == null ? 0 : mResDir.hashCode());
+        hash = 31 * hash + mDisplayId;
+        hash = 31 * hash + (mOverrideConfiguration != null
+                ? mOverrideConfiguration.hashCode() : 0);
+        hash = 31 * hash + Float.floatToIntBits(mScale);
+        mHash = hash;
+    }
+
+    public boolean hasOverrideConfiguration() {
+        return !Configuration.EMPTY.equals(mOverrideConfiguration);
+    }
+
+    @Override
+    public int hashCode() {
+        return mHash;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof ResourcesKey)) {
+            return false;
+        }
+        ResourcesKey peer = (ResourcesKey) obj;
+        if (!mResDir.equals(peer.mResDir)) {
+            return false;
+        }
+        if (mDisplayId != peer.mDisplayId) {
+            return false;
+        }
+        if (mOverrideConfiguration != peer.mOverrideConfiguration) {
+            if (mOverrideConfiguration == null || peer.mOverrideConfiguration == null) {
+                return false;
+            }
+            if (!mOverrideConfiguration.equals(peer.mOverrideConfiguration)) {
+                return false;
+            }
+        }
+        if (mScale != peer.mScale) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return Integer.toHexString(mHash);
+    }
+}
diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java
index 27dddd4..83d48aa 100644
--- a/core/java/android/content/res/TypedArray.java
+++ b/core/java/android/content/res/TypedArray.java
@@ -16,6 +16,7 @@
 
 package android.content.res;
 
+import android.content.pm.ActivityInfo;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
@@ -170,8 +171,8 @@
      * 
      * @param index Index of attribute to retrieve.
      * @param allowedChangingConfigs Bit mask of configurations from
-     * ActivityInfo that are allowed to change.
-     * 
+     * {@link Configuration}.NATIVE_CONFIG_* that are allowed to change.
+     *
      * @return String holding string data.  Any styling information is
      * removed.  Returns null if the attribute is not defined.
      */
diff --git a/core/java/android/content/res/XmlResourceParser.java b/core/java/android/content/res/XmlResourceParser.java
index c59e6d4..5af49d4 100644
--- a/core/java/android/content/res/XmlResourceParser.java
+++ b/core/java/android/content/res/XmlResourceParser.java
@@ -26,7 +26,7 @@
  * an additional close() method on this interface for the client to indicate
  * when it is done reading the resource.
  */
-public interface XmlResourceParser extends XmlPullParser, AttributeSet {
+public interface XmlResourceParser extends XmlPullParser, AttributeSet, AutoCloseable {
     /**
      * Close this interface to the resource.  Calls on the interface are no
      * longer value after this call.
diff --git a/core/java/android/database/AbstractCursor.java b/core/java/android/database/AbstractCursor.java
index 300b4d1..b5b89dd 100644
--- a/core/java/android/database/AbstractCursor.java
+++ b/core/java/android/database/AbstractCursor.java
@@ -369,7 +369,9 @@
     }
 
     public Uri getNotificationUri() {
-        return mNotifyUri;
+        synchronized (mSelfObserverLock) {
+            return mNotifyUri;
+        }
     }
 
     public boolean getWantsAllOnMoveCalls() {
diff --git a/core/java/android/database/Cursor.java b/core/java/android/database/Cursor.java
index 907833d..fc2a885 100644
--- a/core/java/android/database/Cursor.java
+++ b/core/java/android/database/Cursor.java
@@ -25,9 +25,12 @@
 /**
  * This interface provides random read-write access to the result set returned
  * by a database query.
- *
+ * <p>
  * Cursor implementations are not required to be synchronized so code using a Cursor from multiple
  * threads should perform its own synchronization when using the Cursor.
+ * </p><p>
+ * Implementations should subclass {@link AbstractCursor}.
+ * </p>
  */
 public interface Cursor extends Closeable {
     /*
@@ -425,6 +428,16 @@
     void setNotificationUri(ContentResolver cr, Uri uri);
 
     /**
+     * Return the URI at which notifications of changes in this Cursor's data
+     * will be delivered, as previously set by {@link #setNotificationUri}.
+     * @return Returns a URI that can be used with
+     * {@link ContentResolver#registerContentObserver(android.net.Uri, boolean, ContentObserver)
+     * ContentResolver.registerContentObserver} to find out about changes to this Cursor's
+     * data.  May be null if no notification URI has been set.
+     */
+    Uri getNotificationUri();
+
+    /**
      * onMove() will only be called across processes if this method returns true.
      * @return whether all cursor movement should result in a call to onMove().
      */
diff --git a/core/java/android/database/CursorWrapper.java b/core/java/android/database/CursorWrapper.java
index 7baeb8c..d8fcb17 100644
--- a/core/java/android/database/CursorWrapper.java
+++ b/core/java/android/database/CursorWrapper.java
@@ -194,6 +194,10 @@
         mCursor.setNotificationUri(cr, uri);        
     }
 
+    public Uri getNotificationUri() {
+        return mCursor.getNotificationUri();
+    }
+
     public void unregisterContentObserver(ContentObserver observer) {
         mCursor.unregisterContentObserver(observer);        
     }
diff --git a/core/java/android/database/MatrixCursor.java b/core/java/android/database/MatrixCursor.java
index 6e68b6b..5e107f2 100644
--- a/core/java/android/database/MatrixCursor.java
+++ b/core/java/android/database/MatrixCursor.java
@@ -83,11 +83,10 @@
      *  row
      */
     public RowBuilder newRow() {
-        rowCount++;
-        int endIndex = rowCount * columnCount;
+        final int row = rowCount++;
+        final int endIndex = rowCount * columnCount;
         ensureCapacity(endIndex);
-        int start = endIndex - columnCount;
-        return new RowBuilder(start, endIndex);
+        return new RowBuilder(row);
     }
 
     /**
@@ -180,18 +179,29 @@
     }
 
     /**
-     * Builds a row, starting from the left-most column and adding one column
-     * value at a time. Follows the same ordering as the column names specified
-     * at cursor construction time.
+     * Builds a row of values using either of these approaches:
+     * <ul>
+     * <li>Values can be added with explicit column ordering using
+     * {@link #add(Object)}, which starts from the left-most column and adds one
+     * column value at a time. This follows the same ordering as the column
+     * names specified at cursor construction time.
+     * <li>Column and value pairs can be offered for possible inclusion using
+     * {@link #add(String, Object)}. If the cursor includes the given column,
+     * the value will be set for that column, otherwise the value is ignored.
+     * This approach is useful when matching data to a custom projection.
+     * </ul>
+     * Undefined values are left as {@code null}.
      */
     public class RowBuilder {
-
-        private int index;
+        private final int row;
         private final int endIndex;
 
-        RowBuilder(int index, int endIndex) {
-            this.index = index;
-            this.endIndex = endIndex;
+        private int index;
+
+        RowBuilder(int row) {
+            this.row = row;
+            this.index = row * columnCount;
+            this.endIndex = index + columnCount;
         }
 
         /**
@@ -210,6 +220,21 @@
             data[index++] = columnValue;
             return this;
         }
+
+        /**
+         * Offer value for possible inclusion if this cursor defines the given
+         * column. Columns not defined by the cursor are silently ignored.
+         *
+         * @return this builder to support chaining
+         */
+        public RowBuilder add(String columnName, Object value) {
+            for (int i = 0; i < columnNames.length; i++) {
+                if (columnName.equals(columnNames[i])) {
+                    data[(row * columnCount) + i] = value;
+                }
+            }
+            return this;
+        }
     }
 
     // AbstractCursor implementation.
diff --git a/core/java/android/ddm/DdmHandleProfiling.java b/core/java/android/ddm/DdmHandleProfiling.java
index e0db5e7..ec08393 100644
--- a/core/java/android/ddm/DdmHandleProfiling.java
+++ b/core/java/android/ddm/DdmHandleProfiling.java
@@ -34,6 +34,8 @@
     public static final int CHUNK_MPSS = type("MPSS");
     public static final int CHUNK_MPSE = type("MPSE");
     public static final int CHUNK_MPRQ = type("MPRQ");
+    public static final int CHUNK_SPSS = type("SPSS");
+    public static final int CHUNK_SPSE = type("SPSE");
 
     private static DdmHandleProfiling mInstance = new DdmHandleProfiling();
 
@@ -50,6 +52,8 @@
         DdmServer.registerHandler(CHUNK_MPSS, mInstance);
         DdmServer.registerHandler(CHUNK_MPSE, mInstance);
         DdmServer.registerHandler(CHUNK_MPRQ, mInstance);
+        DdmServer.registerHandler(CHUNK_SPSS, mInstance);
+        DdmServer.registerHandler(CHUNK_SPSE, mInstance);
     }
 
     /**
@@ -82,6 +86,10 @@
             return handleMPSE(request);
         } else if (type == CHUNK_MPRQ) {
             return handleMPRQ(request);
+        } else if (type == CHUNK_SPSS) {
+            return handleSPSS(request);
+        } else if (type == CHUNK_SPSE) {
+            return handleSPSE(request);
         } else {
             throw new RuntimeException("Unknown packet "
                 + ChunkHandler.name(type));
@@ -144,7 +152,7 @@
         }
 
         try {
-            Debug.startMethodTracingDdms(bufferSize, flags);
+            Debug.startMethodTracingDdms(bufferSize, flags, false, 0);
             return null;        // empty response
         } catch (RuntimeException re) {
             return createFailChunk(1, re.getMessage());
@@ -178,11 +186,53 @@
      * Handle a "Method PRofiling Query" request.
      */
     private Chunk handleMPRQ(Chunk request) {
-        int result = Debug.isMethodTracingActive() ? 1 : 0;
+        int result = Debug.getMethodTracingMode();
 
         /* create a non-empty reply so the handler fires on completion */
         byte[] reply = { (byte) result };
         return new Chunk(CHUNK_MPRQ, reply, 0, reply.length);
     }
+
+    /*
+     * Handle a "Sample Profiling w/Streaming Start" request.
+     */
+    private Chunk handleSPSS(Chunk request) {
+        ByteBuffer in = wrapChunk(request);
+
+        int bufferSize = in.getInt();
+        int flags = in.getInt();
+        int interval = in.getInt();
+        if (false) {
+            Log.v("ddm-heap", "Sample prof stream start: size=" + bufferSize
+                + ", flags=" + flags + ", interval=" + interval);
+        }
+
+        try {
+            Debug.startMethodTracingDdms(bufferSize, flags, true, interval);
+            return null;        // empty response
+        } catch (RuntimeException re) {
+            return createFailChunk(1, re.getMessage());
+        }
+    }
+
+    /*
+     * Handle a "Sample Profiling w/Streaming End" request.
+     */
+    private Chunk handleSPSE(Chunk request) {
+        if (false) {
+            Log.v("ddm-heap", "Sample prof stream end");
+        }
+
+        try {
+            Debug.stopMethodTracing();
+        } catch (RuntimeException re) {
+            Log.w("ddm-heap", "Sample prof stream end failed: "
+                + re.getMessage());
+            return createFailChunk(1, re.getMessage());
+        }
+
+        /* VM sent the (perhaps very large) response directly */
+        return null;
+    }
 }
 
diff --git a/core/java/android/gesture/GestureOverlayView.java b/core/java/android/gesture/GestureOverlayView.java
index b6c260f..2d47f28 100644
--- a/core/java/android/gesture/GestureOverlayView.java
+++ b/core/java/android/gesture/GestureOverlayView.java
@@ -486,6 +486,7 @@
 
     @Override
     protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
         cancelClearAnimation();
     }
 
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 4e51080..feb47aa 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -31,6 +31,11 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.RenderScript;
+import android.renderscript.RSIllegalArgumentException;
+import android.renderscript.Type;
 import android.util.Log;
 import android.text.TextUtils;
 import android.view.Surface;
@@ -152,6 +157,7 @@
     private PictureCallback mRawImageCallback;
     private PictureCallback mJpegCallback;
     private PreviewCallback mPreviewCallback;
+    private boolean mUsingPreviewAllocation;
     private PictureCallback mPostviewCallback;
     private AutoFocusCallback mAutoFocusCallback;
     private AutoFocusMoveCallback mAutoFocusMoveCallback;
@@ -327,6 +333,7 @@
         mJpegCallback = null;
         mPreviewCallback = null;
         mPostviewCallback = null;
+        mUsingPreviewAllocation = false;
         mZoomListener = null;
 
         Looper looper;
@@ -587,6 +594,9 @@
         mPreviewCallback = cb;
         mOneShot = false;
         mWithBuffer = false;
+        if (cb != null) {
+            mUsingPreviewAllocation = false;
+        }
         // Always use one-shot mode. We fake camera preview mode by
         // doing one-shot preview continuously.
         setHasPreviewCallback(cb != null, false);
@@ -610,6 +620,9 @@
         mPreviewCallback = cb;
         mOneShot = true;
         mWithBuffer = false;
+        if (cb != null) {
+            mUsingPreviewAllocation = false;
+        }
         setHasPreviewCallback(cb != null, false);
     }
 
@@ -645,6 +658,9 @@
         mPreviewCallback = cb;
         mOneShot = false;
         mWithBuffer = true;
+        if (cb != null) {
+            mUsingPreviewAllocation = false;
+        }
         setHasPreviewCallback(cb != null, true);
     }
 
@@ -744,6 +760,134 @@
     private native final void _addCallbackBuffer(
                                 byte[] callbackBuffer, int msgType);
 
+    /**
+     * <p>Create a {@link android.renderscript RenderScript}
+     * {@link android.renderscript.Allocation Allocation} to use as a
+     * destination of preview callback frames. Use
+     * {@link #setPreviewCallbackAllocation setPreviewCallbackAllocation} to use
+     * the created Allocation as a destination for camera preview frames.</p>
+     *
+     * <p>The Allocation will be created with a YUV type, and its contents must
+     * be accessed within Renderscript with the {@code rsGetElementAtYuv_*}
+     * accessor methods. Its size will be based on the current
+     * {@link Parameters#getPreviewSize preview size} configured for this
+     * camera.</p>
+     *
+     * @param rs the RenderScript context for this Allocation.
+     * @param usage additional usage flags to set for the Allocation. The usage
+     *   flag {@link android.renderscript.Allocation#USAGE_IO_INPUT} will always
+     *   be set on the created Allocation, but additional flags may be provided
+     *   here.
+     * @return a new YUV-type Allocation with dimensions equal to the current
+     *   preview size.
+     * @throws RSIllegalArgumentException if the usage flags are not compatible
+     *   with an YUV Allocation.
+     * @see #setPreviewCallbackAllocation
+     * @hide
+     */
+    public final Allocation createPreviewAllocation(RenderScript rs, int usage)
+            throws RSIllegalArgumentException {
+        Parameters p = getParameters();
+        Size previewSize = p.getPreviewSize();
+        Type.Builder yuvBuilder = new Type.Builder(rs,
+                Element.createPixel(rs,
+                        Element.DataType.UNSIGNED_8,
+                        Element.DataKind.PIXEL_YUV));
+        // Use YV12 for wide compatibility. Changing this requires also
+        // adjusting camera service's format selection.
+        yuvBuilder.setYuvFormat(ImageFormat.YV12);
+        yuvBuilder.setX(previewSize.width);
+        yuvBuilder.setY(previewSize.height);
+
+        Allocation a = Allocation.createTyped(rs, yuvBuilder.create(),
+                usage | Allocation.USAGE_IO_INPUT);
+
+        return a;
+    }
+
+    /**
+     * <p>Set an {@link android.renderscript.Allocation Allocation} as the
+     * target of preview callback data. Use this method for efficient processing
+     * of camera preview data with RenderScript. The Allocation must be created
+     * with the {@link #createPreviewAllocation createPreviewAllocation }
+     * method.</p>
+     *
+     * <p>Setting a preview allocation will disable any active preview callbacks
+     * set by {@link #setPreviewCallback setPreviewCallback} or
+     * {@link #setPreviewCallbackWithBuffer setPreviewCallbackWithBuffer}, and
+     * vice versa. Using a preview allocation still requires an active standard
+     * preview target to be set, either with
+     * {@link #setPreviewTexture setPreviewTexture} or
+     * {@link #setPreviewDisplay setPreviewDisplay}.</p>
+     *
+     * <p>To be notified when new frames are available to the Allocation, use
+     * {@link android.renderscript.Allocation#setIoInputNotificationHandler Allocation.setIoInputNotificationHandler}. To
+     * update the frame currently accessible from the Allocation to the latest
+     * preview frame, call
+     * {@link android.renderscript.Allocation#ioReceive Allocation.ioReceive}.</p>
+     *
+     * <p>To disable preview into the Allocation, call this method with a
+     * {@code null} parameter.</p>
+     *
+     * <p>Once a preview allocation is set, the preview size set by
+     * {@link Parameters#setPreviewSize setPreviewSize} cannot be changed. If
+     * you wish to change the preview size, first remove the preview allocation
+     * by calling {@code setPreviewCallbackAllocation(null)}, then change the
+     * preview size, create a new preview Allocation with
+     * {@link #createPreviewAllocation createPreviewAllocation}, and set it as
+     * the new preview callback allocation target.</p>
+     *
+     * <p>If you are using the preview data to create video or still images,
+     * strongly consider using {@link android.media.MediaActionSound} to
+     * properly indicate image capture or recording start/stop to the user.</p>
+     *
+     * @param previewAllocation the allocation to use as destination for preview
+     * @throws IOException if configuring the camera to use the Allocation for
+     *   preview fails.
+     * @throws IllegalArgumentException if the Allocation's dimensions or other
+     *   parameters don't meet the requirements.
+     * @see #createPreviewAllocation
+     * @see #setPreviewCallback
+     * @see #setPreviewCallbackWithBuffer
+     * @hide
+     */
+    public final void setPreviewCallbackAllocation(Allocation previewAllocation)
+            throws IOException {
+        Surface previewSurface = null;
+        if (previewAllocation != null) {
+             Parameters p = getParameters();
+             Size previewSize = p.getPreviewSize();
+             if (previewSize.width != previewAllocation.getType().getX() ||
+                     previewSize.height != previewAllocation.getType().getY()) {
+                 throw new IllegalArgumentException(
+                     "Allocation dimensions don't match preview dimensions: " +
+                     "Allocation is " +
+                     previewAllocation.getType().getX() +
+                     ", " +
+                     previewAllocation.getType().getY() +
+                     ". Preview is " + previewSize.width + ", " +
+                     previewSize.height);
+             }
+             if ((previewAllocation.getUsage() &
+                             Allocation.USAGE_IO_INPUT) == 0) {
+                 throw new IllegalArgumentException(
+                     "Allocation usage does not include USAGE_IO_INPUT");
+             }
+             if (previewAllocation.getType().getElement().getDataKind() !=
+                     Element.DataKind.PIXEL_YUV) {
+                 throw new IllegalArgumentException(
+                     "Allocation is not of a YUV type");
+             }
+             previewSurface = previewAllocation.getSurface();
+             mUsingPreviewAllocation = true;
+         } else {
+             mUsingPreviewAllocation = false;
+         }
+         setPreviewCallbackSurface(previewSurface);
+    }
+
+    private native final void setPreviewCallbackSurface(Surface s);
+
     private class EventHandler extends Handler
     {
         private Camera mCamera;
@@ -1492,6 +1636,17 @@
      * @see #getParameters()
      */
     public void setParameters(Parameters params) {
+        // If using preview allocations, don't allow preview size changes
+        if (mUsingPreviewAllocation) {
+            Size newPreviewSize = params.getPreviewSize();
+            Size currentPreviewSize = getParameters().getPreviewSize();
+            if (newPreviewSize.width != currentPreviewSize.width ||
+                    newPreviewSize.height != currentPreviewSize.height) {
+                throw new IllegalStateException("Cannot change preview size" +
+                        " while a preview allocation is configured.");
+            }
+        }
+
         native_setParameters(params.flatten());
     }
 
@@ -2614,21 +2769,24 @@
          * JPEG {@link PictureCallback}. The camera driver may set orientation
          * in the EXIF header without rotating the picture. Or the driver may
          * rotate the picture and the EXIF thumbnail. If the Jpeg picture is
-         * rotated, the orientation in the EXIF header will be missing or 1
-         * (row #0 is top and column #0 is left side).
+         * rotated, the orientation in the EXIF header will be missing or 1 (row
+         * #0 is top and column #0 is left side).
          *
-         * <p>If applications want to rotate the picture to match the orientation
-         * of what users see, apps should use {@link
-         * android.view.OrientationEventListener} and {@link CameraInfo}.
-         * The value from OrientationEventListener is relative to the natural
-         * orientation of the device. CameraInfo.orientation is the angle
-         * between camera orientation and natural device orientation. The sum
-         * of the two is the rotation angle for back-facing camera. The
-         * difference of the two is the rotation angle for front-facing camera.
-         * Note that the JPEG pictures of front-facing cameras are not mirrored
-         * as in preview display.
+         * <p>
+         * If applications want to rotate the picture to match the orientation
+         * of what users see, apps should use
+         * {@link android.view.OrientationEventListener} and
+         * {@link android.hardware.Camera.CameraInfo}. The value from
+         * OrientationEventListener is relative to the natural orientation of
+         * the device. CameraInfo.orientation is the angle between camera
+         * orientation and natural device orientation. The sum of the two is the
+         * rotation angle for back-facing camera. The difference of the two is
+         * the rotation angle for front-facing camera. Note that the JPEG
+         * pictures of front-facing cameras are not mirrored as in preview
+         * display.
          *
-         * <p>For example, suppose the natural orientation of the device is
+         * <p>
+         * For example, suppose the natural orientation of the device is
          * portrait. The device is rotated 270 degrees clockwise, so the device
          * orientation is 270. Suppose a back-facing camera sensor is mounted in
          * landscape and the top side of the camera sensor is aligned with the
diff --git a/core/java/android/hardware/CameraInfo.aidl b/core/java/android/hardware/CameraInfo.aidl
new file mode 100644
index 0000000..e21e694
--- /dev/null
+++ b/core/java/android/hardware/CameraInfo.aidl
@@ -0,0 +1,20 @@
+/*
+ * 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.hardware;
+
+/** @hide */
+parcelable CameraInfo;
diff --git a/core/java/android/hardware/CameraInfo.java b/core/java/android/hardware/CameraInfo.java
new file mode 100644
index 0000000..53da0ce
--- /dev/null
+++ b/core/java/android/hardware/CameraInfo.java
@@ -0,0 +1,63 @@
+/*
+ * 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.hardware;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Information about a camera
+ *
+ * @hide
+ */
+public class CameraInfo implements Parcelable {
+    // Can't parcel nested classes, so make this a top level class that composes
+    // CameraInfo.
+    public Camera.CameraInfo info = new Camera.CameraInfo();
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(info.facing);
+        out.writeInt(info.orientation);
+    }
+
+    public void readFromParcel(Parcel in) {
+        info.facing = in.readInt();
+        info.orientation = in.readInt();
+    }
+
+    public static final Parcelable.Creator<CameraInfo> CREATOR =
+            new Parcelable.Creator<CameraInfo>() {
+        @Override
+        public CameraInfo createFromParcel(Parcel in) {
+            CameraInfo info = new CameraInfo();
+            info.readFromParcel(in);
+
+            return info;
+        }
+
+        @Override
+        public CameraInfo[] newArray(int size) {
+            return new CameraInfo[size];
+        }
+    };
+};
diff --git a/core/java/android/hardware/ConsumerIrManager.java b/core/java/android/hardware/ConsumerIrManager.java
new file mode 100644
index 0000000..77087814
--- /dev/null
+++ b/core/java/android/hardware/ConsumerIrManager.java
@@ -0,0 +1,156 @@
+/*
+ * 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.hardware;
+
+import android.content.Context;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+
+/**
+ * Class that operates consumer infrared on the device.
+ *
+ * <p>
+ * To obtain an instance of the system infrared transmitter, call
+ * {@link android.content.Context#getSystemService(java.lang.String)
+ * Context.getSystemService()} with
+ * {@link android.content.Context#CONSUMER_IR_SERVICE} as the argument.
+ * </p>
+ */
+public final class ConsumerIrManager {
+    private static final String TAG = "ConsumerIr";
+
+    private final String mPackageName;
+    private final IConsumerIrService mService;
+
+    /**
+     * @hide to prevent subclassing from outside of the framework
+     */
+    public ConsumerIrManager(Context context) {
+        mPackageName = context.getPackageName();
+        mService = IConsumerIrService.Stub.asInterface(
+                ServiceManager.getService(Context.CONSUMER_IR_SERVICE));
+    }
+
+    /**
+     * Check whether the device has an infrared emitter.
+     *
+     * @return true if the device has an infrared emitter, else false.
+     */
+    public boolean hasIrEmitter() {
+        if (mService == null) {
+            Log.w(TAG, "no consumer ir service.");
+            return false;
+        }
+
+        try {
+            return mService.hasIrEmitter();
+        } catch (RemoteException e) {
+        }
+        return false;
+    }
+
+    /**
+     * Tansmit and infrared pattern
+     * <p>
+     * This method is synchronous; when it returns the pattern has
+     * been transmitted. Only patterns shorter than 2 seconds will
+     * be transmitted.
+     * </p>
+     *
+     * @param carrierFrequency The IR carrier frequency in Hertz.
+     * @param pattern The alternating on/off pattern in microseconds to transmit.
+     */
+    public void transmit(int carrierFrequency, int[] pattern) {
+        if (mService == null) {
+            Log.w(TAG, "failed to transmit; no consumer ir service.");
+            return;
+        }
+
+        try {
+            mService.transmit(mPackageName, carrierFrequency, pattern);
+        } catch (RemoteException e) {
+            Log.w(TAG, "failed to transmit.", e);
+        }
+    }
+
+    /**
+     * Represents a range of carrier frequencies (inclusive) on which the
+     * infrared transmitter can transmit
+     */
+    public final class CarrierFrequencyRange {
+        private final int mMinFrequency;
+        private final int mMaxFrequency;
+
+        /**
+         * Create a segment of a carrier frequency range.
+         *
+         * @param min The minimum transmittable frequency in this range segment.
+         * @param max The maximum transmittable frequency in this range segment.
+         */
+        public CarrierFrequencyRange(int min, int max) {
+            mMinFrequency = min;
+            mMaxFrequency = max;
+        }
+
+        /**
+         * Get the minimum (inclusive) frequency in this range segment.
+         */
+        public int getMinFrequency() {
+            return mMinFrequency;
+        }
+
+        /**
+         * Get the maximum (inclusive) frequency in this range segment.
+         */
+        public int getMaxFrequency() {
+            return mMaxFrequency;
+        }
+    };
+
+    /**
+     * Query the infrared transmitter's supported carrier frequencies
+     *
+     * @return an array of
+     * {@link android.hardware.ConsumerIrManager.CarrierFrequencyRange}
+     * objects representing the ranges that the transmitter can support, or
+     * null if there was an error communicating with the Consumer IR Service.
+     */
+    public CarrierFrequencyRange[] getCarrierFrequencies() {
+        if (mService == null) {
+            Log.w(TAG, "no consumer ir service.");
+            return null;
+        }
+
+        try {
+            int[] freqs = mService.getCarrierFrequencies();
+            if (freqs.length % 2 != 0) {
+                Log.w(TAG, "consumer ir service returned an uneven number of frequencies.");
+                return null;
+            }
+            CarrierFrequencyRange[] range = new CarrierFrequencyRange[freqs.length / 2];
+
+            for (int i = 0; i < freqs.length; i += 2) {
+                range[i / 2] = new CarrierFrequencyRange(freqs[i], freqs[i+1]);
+            }
+            return range;
+        } catch (RemoteException e) {
+        }
+        return null;
+    }
+
+}
diff --git a/core/java/android/hardware/FlushCompleteListener.java b/core/java/android/hardware/FlushCompleteListener.java
new file mode 100644
index 0000000..fbdf4c8
--- /dev/null
+++ b/core/java/android/hardware/FlushCompleteListener.java
@@ -0,0 +1,34 @@
+/*
+ * 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.hardware;
+
+/**
+ * Used for receiving a notification when a flush() has been successfully completed.
+ */
+public interface FlushCompleteListener {
+    /**
+     * Called after flush() is completed. This flush() could have been initiated by this application
+     * or some other application. All the events in the batch at the point when the flush was called
+     * have been delivered to the applications registered for those sensor events.
+     * <p>
+     *
+     * @param sensor The {@link android.hardware.Sensor Sensor} on which flush was called.
+     *
+     * @see android.hardware.SensorManager#flush(Sensor)
+     */
+    public void onFlushCompleted(Sensor sensor);
+}
diff --git a/core/java/android/hardware/ICamera.aidl b/core/java/android/hardware/ICamera.aidl
new file mode 100644
index 0000000..d4f64f8
--- /dev/null
+++ b/core/java/android/hardware/ICamera.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.hardware;
+
+/** @hide */
+interface ICamera
+{
+    /**
+     * Keep up-to-date with frameworks/av/include/camera/ICamera.h
+     */
+    void disconnect();
+}
diff --git a/core/java/android/hardware/ICameraClient.aidl b/core/java/android/hardware/ICameraClient.aidl
new file mode 100644
index 0000000..d7877b4
--- /dev/null
+++ b/core/java/android/hardware/ICameraClient.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.hardware;
+
+/** @hide */
+interface ICameraClient
+{
+    /**
+     * Keep up-to-date with frameworks/av/include/camera/ICameraClient.h
+     */
+    // TODO: consider implementing this.
+}
diff --git a/core/java/android/hardware/ICameraService.aidl b/core/java/android/hardware/ICameraService.aidl
new file mode 100644
index 0000000..fc54828
--- /dev/null
+++ b/core/java/android/hardware/ICameraService.aidl
@@ -0,0 +1,61 @@
+/*
+ * 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.hardware;
+
+import android.hardware.ICamera;
+import android.hardware.ICameraClient;
+import android.hardware.IProCameraUser;
+import android.hardware.IProCameraCallbacks;
+import android.hardware.camera2.ICameraDeviceUser;
+import android.hardware.camera2.ICameraDeviceCallbacks;
+import android.hardware.camera2.utils.BinderHolder;
+import android.hardware.ICameraServiceListener;
+import android.hardware.CameraInfo;
+
+/** @hide */
+interface ICameraService
+{
+    /**
+     * Keep up-to-date with frameworks/av/include/camera/ICameraService.h
+     */
+    int getNumberOfCameras();
+
+    // rest of 'int' return values in this file are actually status_t
+
+    int getCameraInfo(int cameraId, out CameraInfo info);
+
+    int connect(ICameraClient client, int cameraId,
+                    String clientPackageName,
+                    int clientUid,
+                    // Container for an ICamera object
+                    out BinderHolder device);
+
+    int connectPro(IProCameraCallbacks callbacks, int cameraId,
+                              String clientPackageName,
+                              int clientUid,
+                              // Container for an IProCameraUser object
+                              out BinderHolder device);
+
+    int connectDevice(ICameraDeviceCallbacks callbacks, int cameraId,
+                              String clientPackageName,
+                              int clientUid,
+                              // Container for an ICameraDeviceUser object
+                              out BinderHolder device);
+
+    int addListener(ICameraServiceListener listener);
+    int removeListener(ICameraServiceListener listener);
+}
diff --git a/core/java/android/hardware/ICameraServiceListener.aidl b/core/java/android/hardware/ICameraServiceListener.aidl
new file mode 100644
index 0000000..c5484965
--- /dev/null
+++ b/core/java/android/hardware/ICameraServiceListener.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.hardware;
+
+/** @hide */
+interface ICameraServiceListener
+{
+    /**
+     * Keep up-to-date with frameworks/av/include/camera/ICameraServiceListener.h
+     */
+    void onStatusChanged(int status, int cameraId);
+}
diff --git a/core/java/android/hardware/IConsumerIrService.aidl b/core/java/android/hardware/IConsumerIrService.aidl
new file mode 100644
index 0000000..c79bd19
--- /dev/null
+++ b/core/java/android/hardware/IConsumerIrService.aidl
@@ -0,0 +1,26 @@
+/**
+ * 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.hardware;
+
+/** {@hide} */
+interface IConsumerIrService
+{
+    boolean hasIrEmitter();
+    void transmit(String packageName, int carrierFrequency, in int[] pattern);
+    int[] getCarrierFrequencies();
+}
+
diff --git a/core/java/android/hardware/IProCameraCallbacks.aidl b/core/java/android/hardware/IProCameraCallbacks.aidl
new file mode 100644
index 0000000..a09b452
--- /dev/null
+++ b/core/java/android/hardware/IProCameraCallbacks.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.hardware;
+
+/** @hide */
+interface IProCameraCallbacks
+{
+    /**
+     * Keep up-to-date with frameworks/av/include/camera/IProCameraCallbacks.h
+     */
+    // TODO: consider implementing this.
+}
diff --git a/core/java/android/hardware/IProCameraUser.aidl b/core/java/android/hardware/IProCameraUser.aidl
new file mode 100644
index 0000000..eacb0f4
--- /dev/null
+++ b/core/java/android/hardware/IProCameraUser.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.hardware;
+
+/** @hide */
+interface IProCameraUser
+{
+    /**
+     * Keep up-to-date with frameworks/av/include/camera/IProCameraUser.h
+     */
+    void disconnect();
+}
diff --git a/core/java/android/hardware/Sensor.java b/core/java/android/hardware/Sensor.java
index 5cc1150..89a5819 100644
--- a/core/java/android/hardware/Sensor.java
+++ b/core/java/android/hardware/Sensor.java
@@ -129,7 +129,7 @@
      * due to distortions that arise from magnetized iron, steel or permanent magnets on the
      * device) is not considered in the given sensor values. However, such hard iron bias values
      * are returned to you separately in the result {@link android.hardware.SensorEvent#values}
-     * so you may use them for custom calibrations. 
+     * so you may use them for custom calibrations.
      * <p>Also, no periodic calibration is performed
      * (i.e. there are no discontinuities in the data stream while using this sensor) and
      * assumptions that the magnetic field is due to the Earth's poles is avoided, but
@@ -174,7 +174,7 @@
     public static final int TYPE_GYROSCOPE_UNCALIBRATED = 16;
 
     /**
-     * A constant describing the significant motion trigger sensor.
+     * A constant describing a significant motion trigger sensor.
      * <p>
      * It triggers when an event occurs and then automatically disables
      * itself. The sensor continues to operate while the device is asleep
@@ -186,6 +186,42 @@
     public static final int TYPE_SIGNIFICANT_MOTION = 17;
 
     /**
+     * A constant describing a step detector sensor.
+     * <p>
+     * A sensor of this type triggers an event each time a step is taken by the user. The only
+     * allowed value to return is 1.0 and an event is generated for each step. Like with any other
+     * event, the timestamp indicates when the event (here the step) occurred, this corresponds to
+     * when the foot hit the ground, generating a high variation in acceleration.
+     * <p>
+     * See {@link android.hardware.SensorEvent#values SensorEvent.values} for more details.
+     */
+    public static final int TYPE_STEP_DETECTOR = 18;
+
+    /**
+     * A constant describing a step counter sensor.
+     * <p>
+     * A sensor of this type returns the number of steps taken by the user since the last reboot
+     * while activated. The value is returned as a float (with the fractional part set to zero) and
+     * is reset to zero only on a system reboot. The timestamp of the event is set to the time when
+     * the first step for that event was taken. This sensor is implemented in hardware and is
+     * expected to be low power.
+     * <p>
+     * See {@link android.hardware.SensorEvent#values SensorEvent.values} for more details.
+     */
+    public static final int TYPE_STEP_COUNTER = 19;
+
+    /**
+     * A constant describing the geo-magnetic rotation vector.
+     * <p>
+     * Similar to {@link #TYPE_ROTATION_VECTOR}, but using a magnetometer instead of using a
+     * gyroscope. This sensor uses lower power than the other rotation vectors, because it doesn't
+     * use the gyroscope. However, it is more noisy and will work best outdoors.
+     * <p>
+     * See {@link android.hardware.SensorEvent#values SensorEvent.values} for more details.
+     */
+    public static final int TYPE_GEOMAGNETIC_ROTATION_VECTOR = 20;
+
+    /**
      * A constant describing all sensor types.
      */
     public static final int TYPE_ALL = -1;
@@ -204,37 +240,71 @@
     // TODO(): The following arrays are fragile and error-prone. This needs to be refactored.
 
     // Note: This needs to be updated, whenever a new sensor is added.
-    private static int[] sSensorReportingModes = {
-            REPORTING_MODE_CONTINUOUS, REPORTING_MODE_CONTINUOUS, REPORTING_MODE_CONTINUOUS,
-            REPORTING_MODE_CONTINUOUS, REPORTING_MODE_ON_CHANGE, REPORTING_MODE_CONTINUOUS,
-            REPORTING_MODE_ON_CHANGE, REPORTING_MODE_ON_CHANGE, REPORTING_MODE_CONTINUOUS,
-            REPORTING_MODE_CONTINUOUS, REPORTING_MODE_CONTINUOUS, REPORTING_MODE_ON_CHANGE,
-            REPORTING_MODE_ON_CHANGE, REPORTING_MODE_CONTINUOUS, REPORTING_MODE_CONTINUOUS,
-            REPORTING_MODE_CONTINUOUS, REPORTING_MODE_ONE_SHOT };
-
-    // Note: This needs to be updated, whenever a new sensor is added.
-    // Holds the maximum length of the values array associated with {@link SensorEvent} or
-    // {@link TriggerEvent} for the Sensor
-    private static int[] sMaxLengthValuesArray = {
-            3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 3,
-            6, 4, 6, 1 };
+    // Holds the reporting mode and maximum length of the values array
+    // associated with
+    // {@link SensorEvent} or {@link TriggerEvent} for the Sensor
+    private static final int[] sSensorReportingModes = {
+            0, 0, // padding because sensor types start at 1
+            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_ACCELEROMETER
+            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_GEOMAGNETIC_FIELD
+            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_ORIENTATION
+            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_GYROSCOPE
+            REPORTING_MODE_ON_CHANGE,  3, // SENSOR_TYPE_LIGHT
+            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_PRESSURE
+            REPORTING_MODE_ON_CHANGE,  3, // SENSOR_TYPE_TEMPERATURE
+            REPORTING_MODE_ON_CHANGE,  3, // SENSOR_TYPE_PROXIMITY
+            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_GRAVITY
+            REPORTING_MODE_CONTINUOUS, 3, // SENSOR_TYPE_LINEAR_ACCELERATION
+            REPORTING_MODE_CONTINUOUS, 5, // SENSOR_TYPE_ROTATION_VECTOR
+            REPORTING_MODE_ON_CHANGE,  3, // SENSOR_TYPE_RELATIVE_HUMIDITY
+            REPORTING_MODE_ON_CHANGE,  3, // SENSOR_TYPE_AMBIENT_TEMPERATURE
+            REPORTING_MODE_CONTINUOUS, 6, // SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED
+            REPORTING_MODE_CONTINUOUS, 4, // SENSOR_TYPE_GAME_ROTATION_VECTOR
+            REPORTING_MODE_CONTINUOUS, 6, // SENSOR_TYPE_GYROSCOPE_UNCALIBRATED
+            REPORTING_MODE_ONE_SHOT,   1, // SENSOR_TYPE_SIGNIFICANT_MOTION
+            // added post 4.3
+            REPORTING_MODE_ON_CHANGE,  1, // SENSOR_TYPE_STEP_DETECTOR
+            REPORTING_MODE_ON_CHANGE,  1, // SENSOR_TYPE_STEP_COUNTER
+            REPORTING_MODE_CONTINUOUS, 5  // SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR
+    };
 
     static int getReportingMode(Sensor sensor) {
-        // mType starts from offset 1.
-        return sSensorReportingModes[sensor.mType - 1];
+        int offset = sensor.mType * 2;
+        if (offset >= sSensorReportingModes.length) {
+            // we don't know about this sensor, so this is probably a
+            // vendor-defined sensor, in that case, we figure out the reporting
+            // mode from the sensor meta-data.
+            int minDelay = sensor.mMinDelay;
+            if (minDelay == 0) {
+                return REPORTING_MODE_ON_CHANGE;
+            } else if (minDelay < 0) {
+                return REPORTING_MODE_ONE_SHOT;
+            } else {
+                return REPORTING_MODE_CONTINUOUS;
+            }
+        }
+        return sSensorReportingModes[offset];
     }
 
     static int getMaxLengthValuesArray(Sensor sensor, int sdkLevel) {
-        // mType starts from offset 1.
-        int len = sMaxLengthValuesArray[sensor.mType - 1];
-
+        int type = sensor.mType;
         // RotationVector length has changed to 3 to 5 for API level 18
         // Set it to 3 for backward compatibility.
-        if (sensor.getType() == Sensor.TYPE_ROTATION_VECTOR &&
+        if (type == Sensor.TYPE_ROTATION_VECTOR &&
                 sdkLevel <= Build.VERSION_CODES.JELLY_BEAN_MR1) {
-            len = 3;
+            return 3;
         }
-        return len;
+        int offset = type * 2 + 1;
+        if (offset >= sSensorReportingModes.length) {
+            // we don't know about this sensor, so this is probably a
+            // vendor-defined sensor, in that case, we don't know how many value
+            // it has
+            // so we return the maximum and assume the app will know.
+            // FIXME: sensor HAL should advertise how much data is returned per
+            // sensor
+            return 16;
+        }
+        return sSensorReportingModes[offset];
     }
 
     /* Some of these fields are set only by the native bindings in
@@ -249,6 +319,8 @@
     private float   mResolution;
     private float   mPower;
     private int     mMinDelay;
+    private int     mFifoReservedEventCount;
+    private int     mFifoMaxEventCount;
 
     Sensor() {
     }
@@ -311,6 +383,24 @@
         return mMinDelay;
     }
 
+    /**
+     * @return Number of events reserved for this sensor in the batch mode FIFO. This gives a
+     * guarantee on the minimum number of events that can be batched.
+     */
+    public int getFifoReservedEventCount() {
+        return mFifoReservedEventCount;
+    }
+
+    /**
+     * @return Maximum number of events of this sensor that could be batched. If this value is zero
+     * it indicates that batch mode is not supported for this sensor. If other applications
+     * registered to batched sensors, the actual number of events that can be batched might be
+     * smaller because the hardware FiFo will be partially used to batch the other sensors.
+     */
+    public int getFifoMaxEventCount() {
+        return mFifoMaxEventCount;
+    }
+
     /** @hide */
     public int getHandle() {
         return mHandle;
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index 30118f9..8a4aa1d 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -582,7 +582,7 @@
      * @param sensor
      *        The {@link android.hardware.Sensor Sensor} to register to.
      *
-     * @param rate
+     * @param rateUs
      *        The rate {@link android.hardware.SensorEvent sensor events} are
      *        delivered at. This is only a hint to the system. Events may be
      *        received faster or slower than the specified rate. Usually events
@@ -603,13 +603,78 @@
      *
      * @throws IllegalArgumentException when sensor is null or a trigger sensor
      */
-    public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate) {
-        return registerListener(listener, sensor, rate, null);
+    public boolean registerListener(SensorEventListener listener, Sensor sensor, int rateUs) {
+        return registerListener(listener, sensor, rateUs, null);
     }
 
     /**
-     * Registers a {@link android.hardware.SensorEventListener
-     * SensorEventListener} for the given sensor.
+     * Enables batch mode for a sensor with the given rate and maxBatchReportLatency. If the
+     * underlying hardware does not support batch mode, this defaults to
+     * {@link #registerListener(SensorEventListener, Sensor, int)} and other parameters are
+     * ignored. In non-batch mode, all sensor events must be reported as soon as they are detected.
+     * While in batch mode, sensor events do not need to be reported as soon as they are detected.
+     * They can be temporarily stored in batches and reported in batches, as long as no event is
+     * delayed by more than "maxBatchReportLatency" microseconds. That is, all events since the
+     * previous batch are recorded and returned all at once. This allows to reduce the amount of
+     * interrupts sent to the SoC, and allows the SoC to switch to a lower power state (Idle) while
+     * the sensor is capturing and batching data.
+     * <p>
+     * Registering to a sensor in batch mode will not prevent the SoC from going to suspend mode. In
+     * this case, the sensor will continue to gather events and store it in a hardware FIFO. If the
+     * FIFO gets full before the AP wakes up again, some events will be lost, as the older events
+     * get overwritten by new events in the hardware FIFO. This can be avoided by holding a wake
+     * lock. If the application holds a wake lock, the SoC will not go to suspend mode, so no events
+     * will be lost, as the events will be reported before the FIFO gets full.
+     * </p>
+     * <p>
+     * Batching is always best effort. If a different application requests updates in continuous
+     * mode, this application will also get events in continuous mode. Batch mode updates can be
+     * unregistered by calling {@link #unregisterListener(SensorEventListener)}.
+     * </p>
+     * <p class="note">
+     * </p>
+     * Note: Don't use this method with a one shot trigger sensor such as
+     * {@link Sensor#TYPE_SIGNIFICANT_MOTION}. Use
+     * {@link #requestTriggerSensor(TriggerEventListener, Sensor)} instead. </p>
+     *
+     * @param listener A {@link android.hardware.SensorEventListener SensorEventListener} object
+     *            that will receive the sensor events.
+     * @param sensor The {@link android.hardware.Sensor Sensor} to register to.
+     * @param rateUs The desired delay between two consecutive events in microseconds. This is only
+     *            a hint to the system. Events may be received faster or slower than the specified
+     *            rate. Usually events are received faster. Can be one of
+     *            {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI},
+     *            {@link #SENSOR_DELAY_GAME}, {@link #SENSOR_DELAY_FASTEST} or the delay in
+     *            microseconds.
+     * @param maxBatchReportLatencyUs An event in the batch can be delayed by at most
+     *            maxBatchReportLatency microseconds. More events can be batched if this value is
+     *            large. If this is set to zero, batch mode is disabled and events are delivered in
+     *            continuous mode as soon as they are available which is equivalent to calling
+     *            {@link #registerListener(SensorEventListener, Sensor, int)}.
+     * @param reservedFlags Always set to Zero.
+     * @param flushCompleteListener A {@link android.hardware.FlushCompleteListener
+     *            FlushCompleteListener} object which is called when any application calls flush()
+     *            on this sensor and all the events in the batch at the time of calling flush() are
+     *            successfully delivered to the listeners.
+     * @return true if batch mode is successfully enabled for this sensor, false otherwise.
+     * @see #registerListener(SensorEventListener, Sensor, int)
+     * @see #unregisterListener(SensorEventListener)
+     * @see #flush(Sensor)
+     * @throws IllegalArgumentException when sensor or listener is null or a trigger sensor.
+     */
+    public boolean registerListener(SensorEventListener listener, Sensor sensor, int rateUs,
+            int maxBatchReportLatencyUs, int reservedFlags,
+            FlushCompleteListener flushCompleteListener) {
+        int delay = getDelay(rateUs);
+        return registerListenerImpl(listener, sensor, delay, null, maxBatchReportLatencyUs,
+                                        reservedFlags, flushCompleteListener);
+    }
+
+    /**
+     * Registers a {@link android.hardware.SensorEventListener SensorEventListener} for the given
+     * sensor. Events are delivered in continuous mode as soon as they are available. To reduce the
+     * battery usage, use {@link #registerListener(SensorEventListener, Sensor, int, int, int,
+     * FlushCompleteListener)} which enables batch mode for the sensor.
      *
      * <p class="note"></p>
      * Note: Don't use this method with a one shot trigger sensor such as
@@ -624,7 +689,7 @@
      * @param sensor
      *        The {@link android.hardware.Sensor Sensor} to register to.
      *
-     * @param rate
+     * @param rateUs
      *        The rate {@link android.hardware.SensorEvent sensor events} are
      *        delivered at. This is only a hint to the system. Events may be
      *        received faster or slower than the specified rate. Usually events
@@ -649,37 +714,59 @@
      *
      * @throws IllegalArgumentException when sensor is null or a trigger sensor
      */
-    public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate,
+    public boolean registerListener(SensorEventListener listener, Sensor sensor, int rateUs,
             Handler handler) {
         if (listener == null || sensor == null) {
             return false;
         }
 
-        int delay = -1;
-        switch (rate) {
-            case SENSOR_DELAY_FASTEST:
-                delay = 0;
-                break;
-            case SENSOR_DELAY_GAME:
-                delay = 20000;
-                break;
-            case SENSOR_DELAY_UI:
-                delay = 66667;
-                break;
-            case SENSOR_DELAY_NORMAL:
-                delay = 200000;
-                break;
-            default:
-                delay = rate;
-                break;
-        }
+        int delay = getDelay(rateUs);
+        return registerListenerImpl(listener, sensor, delay, handler, 0, 0, null);
+    }
 
-        return registerListenerImpl(listener, sensor, delay, handler);
+    /**
+     * Enables batch mode for a sensor with the given rate and maxBatchReportLatency.
+     * @param handler
+     *        The {@link android.os.Handler Handler} the
+     *        {@link android.hardware.SensorEvent sensor events} will be
+     *        delivered to.
+     *
+     * @see #registerListener(SensorEventListener, Sensor, int, int, int, FlushCompleteListener)
+     */
+    public boolean registerListener(SensorEventListener listener, Sensor sensor, int rateUs,
+            int maxBatchReportLatencyUs, int reservedFlags, Handler handler,
+            FlushCompleteListener flushCompleteListener) {
+        int delayUs = getDelay(rateUs);
+        return registerListenerImpl(listener, sensor, delayUs, handler, maxBatchReportLatencyUs,
+                                        reservedFlags, flushCompleteListener);
     }
 
     /** @hide */
     protected abstract boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
-            int delay, Handler handler);
+            int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags,
+            FlushCompleteListener flushCompleteListener);
+
+
+    /**
+     * Flushes the batch FIFO of the given sensor. If there are events in the FIFO of this sensor,
+     * they are returned as if the batch timeout has expired. Events are returned in the
+     * usual way through the SensorEventListener. This call doesn't effect the batch timeout for
+     * this sensor. This call is asynchronous and returns immediately. FlushCompleteListener is
+     * called after all the events in the batch at the time of calling this method have been
+     * delivered successfully.
+     * @param sensor
+     *        The {@link android.hardware.Sensor Sensor} to flush.
+     * @return true if the flush is initiated successfully. false if the sensor isn't active
+     *         i.e no application is registered for updates from this sensor.
+     * @see #registerListener(SensorEventListener, Sensor, int, int, int, FlushCompleteListener)
+     * @throws IllegalArgumentException when sensor is null or a trigger sensor.
+     */
+    public boolean flush(Sensor sensor) {
+        return flushImpl(sensor);
+    }
+
+    /** @hide */
+    protected abstract boolean flushImpl(Sensor sensor);
 
     /**
      * <p>
@@ -1079,15 +1166,15 @@
      * <p>
      * All three angles above are in <b>radians</b> and <b>positive</b> in the
      * <b>counter-clockwise</b> direction.
-     * 
+     *
      * @param R
      *        rotation matrix see {@link #getRotationMatrix}.
-     * 
+     *
      * @param values
      *        an array of 3 floats to hold the result.
-     * 
+     *
      * @return The array values passed as argument.
-     * 
+     *
      * @see #getRotationMatrix(float[], float[], float[], float[])
      * @see GeomagneticField
      */
@@ -1407,4 +1494,26 @@
             return mLegacySensorManager;
         }
     }
+
+    private static int getDelay(int rate) {
+        int delay = -1;
+        switch (rate) {
+            case SENSOR_DELAY_FASTEST:
+                delay = 0;
+                break;
+            case SENSOR_DELAY_GAME:
+                delay = 20000;
+                break;
+            case SENSOR_DELAY_UI:
+                delay = 66667;
+                break;
+            case SENSOR_DELAY_NORMAL:
+                delay = 200000;
+                break;
+            default:
+                delay = rate;
+                break;
+        }
+        return delay;
+    }
 }
diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java
index 852cf4a..9747f0d 100644
--- a/core/java/android/hardware/SystemSensorManager.java
+++ b/core/java/android/hardware/SystemSensorManager.java
@@ -93,30 +93,35 @@
     /** @hide */
     @Override
     protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
-            int delay, Handler handler)
-    {
+            int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags,
+            FlushCompleteListener flushCompleteListener) {
+        if (sensor == null) throw new IllegalArgumentException("sensor cannot be null");
+        if (listener == null) throw new IllegalArgumentException("listener cannot be null");
+        if (reservedFlags != 0) throw new IllegalArgumentException("reservedFlags should be zero");
+        if (delayUs < 0) throw new IllegalArgumentException("rateUs should be positive");
+        if (maxBatchReportLatencyUs < 0)
+            throw new IllegalArgumentException("maxBatchReportLatencyUs should be positive");
+        // Trigger Sensors should use the requestTriggerSensor call.
+        if (Sensor.getReportingMode(sensor) == Sensor.REPORTING_MODE_ONE_SHOT)
+            throw new IllegalArgumentException("Trigger Sensors cannot use registerListener");
+
         // Invariants to preserve:
         // - one Looper per SensorEventListener
         // - one Looper per SensorEventQueue
         // We map SensorEventListener to a SensorEventQueue, which holds the looper
-        if (sensor == null) throw new IllegalArgumentException("sensor cannot be null");
-
-        // Trigger Sensors should use the requestTriggerSensor call.
-        if (Sensor.getReportingMode(sensor) == Sensor.REPORTING_MODE_ONE_SHOT) return false;
-
         synchronized (mSensorListeners) {
             SensorEventQueue queue = mSensorListeners.get(listener);
             if (queue == null) {
                 Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
-                queue = new SensorEventQueue(listener, looper, this);
-                if (!queue.addSensor(sensor, delay)) {
+                queue = new SensorEventQueue(listener, looper, this, flushCompleteListener);
+                if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs, reservedFlags)) {
                     queue.dispose();
                     return false;
                 }
                 mSensorListeners.put(listener, queue);
                 return true;
             } else {
-                return queue.addSensor(sensor, delay);
+                return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs, reservedFlags);
             }
         }
     }
@@ -157,14 +162,14 @@
             TriggerEventQueue queue = mTriggerListeners.get(listener);
             if (queue == null) {
                 queue = new TriggerEventQueue(listener, mMainLooper, this);
-                if (!queue.addSensor(sensor, 0)) {
+                if (!queue.addSensor(sensor, 0, 0, 0)) {
                     queue.dispose();
                     return false;
                 }
                 mTriggerListeners.put(listener, queue);
                 return true;
             } else {
-                return queue.addSensor(sensor, 0);
+                return queue.addSensor(sensor, 0, 0, 0);
             }
         }
     }
@@ -195,6 +200,18 @@
         }
     }
 
+    protected boolean flushImpl(Sensor sensor) {
+        if (sensor == null) throw new IllegalArgumentException("sensor cannot be null");
+        if(Sensor.getReportingMode(sensor) == Sensor.REPORTING_MODE_ONE_SHOT)
+            throw new IllegalArgumentException("Trigger Sensors cannot call flush");
+
+        FlushEventQueue queue = new FlushEventQueue(mMainLooper, this);
+        if (queue.flushSensor(sensor) != 0) {
+            return false;
+        }
+        return true;
+    }
+
     /*
      * BaseEventQueue is the communication channel with the sensor service,
      * SensorEventQueue, TriggerEventQueue are subclases and there is one-to-one mapping between
@@ -202,11 +219,12 @@
      */
     private static abstract class BaseEventQueue {
         private native int nativeInitBaseEventQueue(BaseEventQueue eventQ, MessageQueue msgQ,
-
                 float[] scratch);
-        private static native int nativeEnableSensor(int eventQ, int handle, int us);
+        private static native int nativeEnableSensor(int eventQ, int handle, int rateUs,
+                int maxBatchReportLatencyUs, int reservedFlags);
         private static native int nativeDisableSensor(int eventQ, int handle);
         private static native void nativeDestroySensorEventQueue(int eventQ);
+        private static native int nativeFlushSensor(int eventQ, int handle);
         private int nSensorEventQueue;
         private final SparseBooleanArray mActiveSensors = new SparseBooleanArray();
         protected final SparseIntArray mSensorAccuracies = new SparseIntArray();
@@ -225,7 +243,8 @@
             dispose(false);
         }
 
-        public boolean addSensor(Sensor sensor, int delay) {
+        public boolean addSensor(
+                Sensor sensor, int delayUs, int maxBatchReportLatencyUs, int reservedFlags) {
             // Check if already present.
             int handle = sensor.getHandle();
             if (mActiveSensors.get(handle)) return false;
@@ -233,9 +252,13 @@
             // Get ready to receive events before calling enable.
             mActiveSensors.put(handle, true);
             addSensorEvent(sensor);
-            if (enableSensor(sensor, delay) != 0) {
-                removeSensor(sensor, false);
-                return false;
+            if (enableSensor(sensor, delayUs, maxBatchReportLatencyUs, reservedFlags) != 0) {
+                // Try continuous mode if batching fails.
+                if (maxBatchReportLatencyUs == 0 ||
+                    maxBatchReportLatencyUs > 0 && enableSensor(sensor, delayUs, 0, 0) != 0) {
+                  removeSensor(sensor, false);
+                  return false;
+                }
             }
             return true;
         }
@@ -268,6 +291,12 @@
             return false;
         }
 
+        public int flushSensor(Sensor sensor) {
+            if (nSensorEventQueue == 0) throw new NullPointerException();
+            if (sensor == null) throw new NullPointerException();
+            return nativeFlushSensor(nSensorEventQueue, sensor.getHandle());
+        }
+
         public boolean hasSensors() {
             // no more sensors are set
             return mActiveSensors.indexOfValue(true) >= 0;
@@ -295,11 +324,14 @@
             }
         }
 
-        private int enableSensor(Sensor sensor, int us) {
+        private int enableSensor(
+                Sensor sensor, int rateUs, int maxBatchReportLatencyUs, int reservedFlags) {
             if (nSensorEventQueue == 0) throw new NullPointerException();
             if (sensor == null) throw new NullPointerException();
-            return nativeEnableSensor(nSensorEventQueue, sensor.getHandle(), us);
+            return nativeEnableSensor(nSensorEventQueue, sensor.getHandle(), rateUs,
+                    maxBatchReportLatencyUs, reservedFlags);
         }
+
         private int disableSensor(Sensor sensor) {
             if (nSensorEventQueue == 0) throw new NullPointerException();
             if (sensor == null) throw new NullPointerException();
@@ -307,6 +339,7 @@
         }
         protected abstract void dispatchSensorEvent(int handle, float[] values, int accuracy,
                 long timestamp);
+        protected abstract void dispatchFlushCompleteEvent(int handle);
 
         protected abstract void addSensorEvent(Sensor sensor);
         protected abstract void removeSensorEvent(Sensor sensor);
@@ -314,12 +347,14 @@
 
     static final class SensorEventQueue extends BaseEventQueue {
         private final SensorEventListener mListener;
+        private final FlushCompleteListener mFlushCompleteListener;
         private final SparseArray<SensorEvent> mSensorsEvents = new SparseArray<SensorEvent>();
 
         public SensorEventQueue(SensorEventListener listener, Looper looper,
-                SystemSensorManager manager) {
+                SystemSensorManager manager, FlushCompleteListener flushCompleteListener) {
             super(looper, manager);
             mListener = listener;
+            mFlushCompleteListener = flushCompleteListener;
         }
 
         public void addSensorEvent(Sensor sensor) {
@@ -370,6 +405,15 @@
             }
             mListener.onSensorChanged(t);
         }
+
+        @SuppressWarnings("unused")
+        protected void dispatchFlushCompleteEvent(int handle) {
+            final Sensor sensor = sHandleToSensor.get(handle);
+            if (mFlushCompleteListener != null) {
+                mFlushCompleteListener.onFlushCompleted(sensor);
+            }
+            return;
+        }
     }
 
     static final class TriggerEventQueue extends BaseEventQueue {
@@ -415,5 +459,35 @@
 
             mListener.onTrigger(t);
         }
+
+        @SuppressWarnings("unused")
+        protected void dispatchFlushCompleteEvent(int handle) {
+        }
+    }
+
+    static final class FlushEventQueue extends BaseEventQueue {
+        public FlushEventQueue(Looper looper, SystemSensorManager manager) {
+            super(looper, manager);
+        }
+
+        @SuppressWarnings("unused")
+        @Override
+        protected void dispatchSensorEvent(int handle, float[] values, int accuracy,
+                long timestamp) {
+        }
+
+        @Override
+        @SuppressWarnings("unused")
+        protected void addSensorEvent(Sensor sensor) {
+        }
+
+        @Override
+        @SuppressWarnings("unused")
+        protected void removeSensorEvent(Sensor sensor) {
+        }
+
+        @SuppressWarnings("unused")
+        protected void dispatchFlushCompleteEvent(int handle) {
+        }
     }
 }
diff --git a/core/java/android/hardware/camera2/CameraAccessException.java b/core/java/android/hardware/camera2/CameraAccessException.java
new file mode 100644
index 0000000..e08d1e6
--- /dev/null
+++ b/core/java/android/hardware/camera2/CameraAccessException.java
@@ -0,0 +1,117 @@
+/*
+ * 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.hardware.camera2;
+
+import android.util.AndroidException;
+
+/**
+ * <p><code>CameraAccessException</code> is thrown if a camera device could not
+ * be queried or opened by the {@link CameraManager}, or if the connection to an
+ * opened {@link CameraDevice} is no longer valid.</p>
+ *
+ * @see CameraManager
+ * @see CameraDevice
+ */
+public class CameraAccessException extends AndroidException {
+    /**
+     * The camera device is in use already
+     */
+    public static final int CAMERA_IN_USE = 1;
+
+    /**
+     * The system-wide limit for number of open cameras has been reached,
+     * and more camera devices cannot be opened until previous instances are
+     * closed.
+     */
+    public static final int MAX_CAMERAS_IN_USE = 2;
+
+    /**
+     * The camera is disabled due to a device policy, and cannot be opened.
+     *
+     * @see android.app.admin.DevicePolicyManager#setCameraDisabled(android.content.ComponentName, boolean)
+     */
+    public static final int CAMERA_DISABLED = 3;
+
+    /**
+     * The camera device is removable and has been disconnected from the Android
+     * device, or the camera id used with {@link android.hardware.camera2.CameraManager#openCamera}
+     * is no longer valid, or the camera service has shut down the connection due to a
+     * higher-priority access request for the camera device.
+     */
+    public static final int CAMERA_DISCONNECTED = 4;
+
+    /**
+     * A deprecated HAL version is in use.
+     * @hide
+     */
+    public static final int CAMERA_DEPRECATED_HAL = 1000;
+
+    // Make the eclipse warning about serializable exceptions go away
+    private static final long serialVersionUID = 5630338637471475675L; // randomly generated
+
+    private final int mReason;
+
+    /**
+     * The reason for the failure to access the camera.
+     *
+     * @see #CAMERA_IN_USE
+     * @see #MAX_CAMERAS_IN_USE
+     * @see #CAMERA_DISABLED
+     * @see #CAMERA_DISCONNECTED
+     */
+    public final int getReason() {
+        return mReason;
+    }
+
+    public CameraAccessException(int problem) {
+        super(getDefaultMessage(problem));
+        mReason = problem;
+    }
+
+    public CameraAccessException(int problem, String message) {
+        super(message);
+        mReason = problem;
+    }
+
+    public CameraAccessException(int problem, String message, Throwable cause) {
+        super(message, cause);
+        mReason = problem;
+    }
+
+    public CameraAccessException(int problem, Throwable cause) {
+        super(getDefaultMessage(problem), cause);
+        mReason = problem;
+    }
+
+    private static String getDefaultMessage(int problem) {
+        switch (problem) {
+            case CAMERA_IN_USE:
+                return "The camera device is in use already";
+            case MAX_CAMERAS_IN_USE:
+                return "The system-wide limit for number of open cameras has been reached, " +
+                       "and more camera devices cannot be opened until previous instances " +
+                       "are closed.";
+            case CAMERA_DISABLED:
+                return "The camera is disabled due to a device policy, and cannot be opened.";
+            case CAMERA_DISCONNECTED:
+                return "The camera device is removable and has been disconnected from the Android" +
+                       " device, or the camera service has shut down the connection due to a " +
+                       "higher-priority access request for the camera device.";
+        }
+        return null;
+    }
+}
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
new file mode 100644
index 0000000..0c13b0f
--- /dev/null
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -0,0 +1,795 @@
+/*
+ * 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.hardware.camera2;
+
+import android.view.Surface;
+import android.os.Handler;
+import android.util.Log;
+
+import java.lang.AutoCloseable;
+import java.util.List;
+
+/**
+ * <p>The CameraDevice class is an interface to a single camera connected to an
+ * Android device, allowing for fine-grain control of image capture and
+ * post-processing at high frame rates.</p>
+ *
+ * <p>Your application must declare the
+ * {@link android.Manifest.permission#CAMERA Camera} permission in its manifest
+ * in order to access camera devices.</p>
+ *
+ * <p>A given camera device may provide support at one of two levels: limited or
+ * full. If a device only supports the limited level, then Camera2 exposes a
+ * feature set that is roughly equivalent to the older
+ * {@link android.hardware.Camera Camera} API, although with a cleaner and more
+ * efficient interface.  Devices that implement the full level of support
+ * provide substantially improved capabilities over the older camera
+ * API. Applications that target the limited level devices will run unchanged on
+ * the full-level devices; if your application requires a full-level device for
+ * proper operation, declare the "android.hardware.camera2.full" feature in your
+ * manifest.</p>
+ *
+ * @see CameraManager#openCamera
+ * @see android.Manifest.permission#CAMERA
+ */
+public interface CameraDevice extends AutoCloseable {
+
+    /**
+     * Create a request suitable for a camera preview window. Specifically, this
+     * means that high frame rate is given priority over the highest-quality
+     * post-processing. These requests would normally be used with the
+     * {@link #setRepeatingRequest} method.
+     *
+     * @see #createCaptureRequest
+     */
+    public static final int TEMPLATE_PREVIEW = 1;
+
+    /**
+     * 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 #capture} method.
+     *
+     * @see #createCaptureRequest
+     */
+    public static final int TEMPLATE_STILL_CAPTURE = 2;
+
+    /**
+     * Create a request suitable for video recording. Specifically, this means
+     * that a stable frame rate is used, and post-processing is set for
+     * recording quality. These requests would commonly be used with the
+     * {@link #setRepeatingRequest} method.
+     *
+     * @see #createCaptureRequest
+     */
+    public static final int TEMPLATE_RECORD  = 3;
+
+    /**
+     * Create a request suitable for still image capture while recording
+     * video. Specifically, this means maximizing image quality without
+     * disrupting the ongoing recording. These requests would commonly be used
+     * with the {@link #capture} method while a request based on
+     * {@link #TEMPLATE_RECORD} is is in use with {@link #setRepeatingRequest}.
+     *
+     * @see #createCaptureRequest
+     */
+    public static final int TEMPLATE_VIDEO_SNAPSHOT = 4;
+
+    /**
+     * Create a request suitable for zero shutter lag still capture. This means
+     * means maximizing image quality without compromising preview frame rate.
+     * AE/AWB/AF should be on auto mode.
+     *
+     * @see #createCaptureRequest
+     * @hide
+     */
+    public static final int TEMPLATE_ZERO_SHUTTER_LAG = 5;
+
+    /**
+     * A basic template for direct application control of capture
+     * parameters. All automatic control is disabled (auto-exposure, auto-white
+     * balance, auto-focus), and post-processing parameters are set to preview
+     * quality. The manual capture parameters (exposure, sensitivity, and so on)
+     * are set to reasonable defaults, but should be overriden by the
+     * application depending on the intended use case.
+     *
+     * @see #createCaptureRequest
+     * @hide
+     */
+    public static final int TEMPLATE_MANUAL = 6;
+
+    /**
+     * Get the ID of this camera device.
+     *
+     * <p>This matches the ID given to {@link CameraManager#openCamera} to instantiate this
+     * this camera device.</p>
+     *
+     * <p>This ID can be used to query the camera device's {@link
+     * CameraProperties fixed properties} with {@link
+     * CameraManager#getCameraProperties}.</p>
+     *
+     * <p>This method can be called even if the device has been closed or has encountered
+     * a serious error.</p>
+     *
+     * @return the ID for this camera device
+     *
+     * @see CameraManager#getCameraProperties
+     * @see CameraManager#getDeviceIdList
+     */
+    public String getId();
+
+    /**
+     * Get the static properties for this camera. These are identical to the
+     * properties returned by {@link CameraManager#getCameraProperties}.
+     *
+     * @return the static properties of the camera
+     *
+     * @throws CameraAccessException if the camera device is no longer connected
+     *
+     * @see CameraManager#getCameraProperties
+     */
+    public CameraProperties getProperties() throws CameraAccessException;
+
+    /**
+     * <p>Set up a new output set of Surfaces for the camera device.</p>
+     *
+     * <p>The configuration determines the set of potential output Surfaces for
+     * the camera device for each capture request. A given request may use all
+     * or a only some of the outputs. This method must be called before requests
+     * can be submitted to the camera with {@link #capture capture},
+     * {@link #captureBurst captureBurst},
+     * {@link #setRepeatingRequest setRepeatingRequest}, or
+     * {@link #setRepeatingBurst setRepeatingBurst}.</p>
+     *
+     * <p>Surfaces suitable for inclusion as a camera output can be created for
+     * various use cases and targets:</p>
+     *
+     * <ul>
+     *
+     * <li>For drawing to a {@link android.view.SurfaceView SurfaceView}: Set
+     *   the size of the Surface with
+     *   {@link android.view.SurfaceHolder#setFixedSize} to be one of the
+     *   supported
+     *   {@link CameraProperties#SCALER_AVAILABLE_PROCESSED_SIZES processed sizes}
+     *   before calling {@link android.view.SurfaceHolder#getSurface}.</li>
+     *
+     * <li>For accessing through an OpenGL texture via a
+     *   {@link android.graphics.SurfaceTexture SurfaceTexture}: Set the size of
+     *   the SurfaceTexture with
+     *   {@link android.graphics.SurfaceTexture#setDefaultBufferSize} to be one
+     *   of the supported
+     *   {@link CameraProperties#SCALER_AVAILABLE_PROCESSED_SIZES processed sizes}
+     *   before creating a Surface from the SurfaceTexture with
+     *   {@link Surface#Surface}.</li>
+     *
+     * <li>For recording with {@link android.media.MediaCodec}: Call
+     *   {@link android.media.MediaCodec#createInputSurface} after configuring
+     *   the media codec to use one of the
+     *   {@link CameraProperties#SCALER_AVAILABLE_PROCESSED_SIZES processed sizes}
+     *   </li>
+     *
+     * <li>For recording with {@link android.media.MediaRecorder}: TODO</li>
+     *
+     * <li>For efficient YUV processing with {@link android.renderscript}:
+     *   Create a RenderScript
+     *   {@link android.renderscript.Allocation Allocation} with a supported YUV
+     *   type, the IO_INPUT flag, and one of the supported
+     *   {@link CameraProperties#SCALER_AVAILABLE_PROCESSED_SIZES processed sizes}. Then
+     *   obtain the Surface with
+     *   {@link android.renderscript.Allocation#getSurface}.</li>
+     *
+     * <li>For access to uncompressed or JPEG data in the application: Create a
+     *   {@link android.media.ImageReader} object with the desired
+     *   {@link CameraProperties#SCALER_AVAILABLE_FORMATS image format}, and a
+     *   size from the matching
+     *   {@link CameraProperties#SCALER_AVAILABLE_PROCESSED_SIZES processed},
+     *   {@link CameraProperties#SCALER_AVAILABLE_JPEG_SIZES jpeg}. Then obtain
+     *   a Surface from it.</li>
+     *
+     * </ul>
+     *
+     * </p>
+     *
+     * <p>This function can take several hundred milliseconds to execute, since
+     * camera hardware may need to be powered on or reconfigured.</p>
+     *
+     * <p>The camera device will query each Surface's size and formats upon this
+     * call, so they must be set to a valid setting at this time (in particular:
+     * if the format is user-visible, it must be one of android.scaler.availableFormats;
+     * and the size must be one of android.scaler.available[Processed|Jpeg]Sizes).</p>
+     *
+     * <p>To change the output, the camera device must be idle. The device is considered
+     * to be idle once all in-flight and pending capture requests have been processed,
+     * and all output image buffers from the captures have been sent to their destination
+     * Surfaces.</p>
+     *
+     * <p>To reach an idle state without cancelling any submitted captures, first
+     * stop any repeating request/burst with {@link #stopRepeating}, and then
+     * wait for the {@link CameraDeviceListener#onCameraIdle} callback to be
+     * called. To idle as fast as possible, use {@link #flush} and wait for the
+     * idle callback.</p>
+     *
+     * <p>Using larger resolution outputs, or more outputs, can result in slower
+     * output rate from the device.</p>
+     *
+     * @param outputs The new set of Surfaces that should be made available as
+     * targets for captured image data.
+     *
+     * @throws IllegalArgumentException if the set of output Surfaces do not
+     * meet the requirements
+     * @throws CameraAccessException if the camera device is no longer connected
+     * @throws IllegalStateException if the camera device is not idle, or has
+     * encountered a fatal error
+     *
+     * @see CameraDeviceListener#onCameraIdle
+     * @see #stopRepeating
+     * @see #flush
+     */
+    public void configureOutputs(List<Surface> outputs) throws CameraAccessException;
+
+    /**
+     * <p>Create a {@link CaptureRequest.Builder} for new capture requests,
+     * initialized with template for a target use case. The settings are chosen
+     * to be the best options for the specific camera device, so it is not
+     * recommended to reuse the same request for a different camera device;
+     * create a builder specific for that device and template and override the
+     * settings as desired, instead.</p>
+     *
+     * @param templateType An enumeration selecting the use case for this
+     * request; one of the CameraDevice.TEMPLATE_ values.
+     * @return a builder for a capture request, initialized with default
+     * settings for that template, and no output streams
+     *
+     * @throws IllegalArgumentException if the templateType is not in the list
+     * of supported templates.
+     * @throws CameraAccessException if the camera device is no longer connected
+     * @throws IllegalStateException if the camera device has been closed or the
+     * device has encountered a fatal error.
+     *
+     * @see #TEMPLATE_PREVIEW
+     * @see #TEMPLATE_RECORD
+     * @see #TEMPLATE_STILL_CAPTURE
+     * @see #TEMPLATE_VIDEO_SNAPSHOT
+     * @see #TEMPLATE_MANUAL
+     */
+    public CaptureRequest.Builder createCaptureRequest(int templateType)
+            throws CameraAccessException;
+
+    /**
+     * <p>Submit a request for an image to be captured by this CameraDevice.</p>
+     *
+     * <p>The request defines all the parameters for capturing the single image,
+     * including sensor, lens, flash, and post-processing settings.</p>
+     *
+     * <p>Each request will produce one {@link CaptureResult} and produce new
+     * frames for one or more target Surfaces, set with the CaptureRequest
+     * builder's {@link CaptureRequest.Builder#addTarget} method. The target
+     * surfaces must be configured as active outputs with
+     * {@link #configureOutputs} before calling this method.</p>
+     *
+     * <p>Multiple requests can be in progress at once. They are processed in
+     * first-in, first-out order, with minimal delays between each
+     * capture. Requests submitted through this method have higher priority than
+     * those submitted through {@link #setRepeatingRequest} or
+     * {@link #setRepeatingBurst}, and will be processed as soon as the current
+     * repeat/repeatBurst processing completes.</p>
+     *
+     * @param request the settings for this capture
+     * @param listener The callback object to notify once this request has been
+     * processed. If null, no metadata will be produced for this capture,
+     * although image data will still be produced.
+     * @param handler the handler on which the listener should be invoked, or
+     * {@code null} to use the current thread's {@link android.os.Looper
+     * looper}.
+     *
+     * @throws CameraAccessException if the camera device is no longer connected
+     * @throws IllegalStateException if the camera device has been closed or the
+     * device has encountered a fatal error.
+     * @throws IllegalArgumentException If the request targets Surfaces not
+     * currently configured as outputs. Or if the handler is null, the listener
+     * is not null, and the calling thread has no looper.
+     *
+     * @see #captureBurst
+     * @see #setRepeatingRequest
+     * @see #setRepeatingBurst
+     */
+    public void capture(CaptureRequest request, CaptureListener listener, Handler handler)
+            throws CameraAccessException;
+
+    /**
+     * Submit a list of requests to be captured in sequence as a burst. The
+     * burst will be captured in the minimum amount of time possible, and will
+     * not be interleaved with requests submitted by other capture or repeat
+     * calls.
+     *
+     * <p>The requests will be captured in order, each capture producing one
+     * {@link CaptureResult} and image buffers for one or more target
+     * {@link android.view.Surface surfaces}. The target surfaces for each
+     * request (set with {@link CaptureRequest.Builder#addTarget}) must be
+     * configured as active outputs with {@link #configureOutputs} before
+     * calling this method.</p>
+     *
+     * <p>The main difference between this method and simply calling
+     * {@link #capture} repeatedly is that this method guarantees that no
+     * other requests will be interspersed with the burst.</p>
+     *
+     * @param requests the list of settings for this burst capture
+     * @param listener The callback object to notify each time one of the
+     * requests in the burst has been processed. If null, no metadata will be
+     * produced for any requests in this burst, although image data will still
+     * be produced.
+     * @param handler the handler on which the listener should be invoked, or
+     * {@code null} to use the current thread's {@link android.os.Looper
+     * looper}.
+     *
+     * @throws CameraAccessException if the camera device is no longer connected
+     * @throws IllegalStateException if the camera device has been closed or the
+     * device has encountered a fatal error.
+     * @throws IllegalArgumentException If the requests target Surfaces not
+     * currently configured as outputs. Or if the handler is null, the listener
+     * is not null, and the calling thread has no looper.
+     *
+     * @see #capture
+     * @see #setRepeatingRequest
+     * @see #setRepeatingBurst
+     */
+    public void captureBurst(List<CaptureRequest> requests, CaptureListener listener,
+            Handler handler) throws CameraAccessException;
+
+    /**
+     * Request endlessly repeating capture of images by this CameraDevice.
+     *
+     * <p>With this method, the CameraDevice will continually capture images
+     * using the settings in the provided {@link CaptureRequest}, at the maximum
+     * rate possible.</p>
+     *
+     * <p>Repeating requests are a simple way for an application to maintain a
+     * preview or other continuous stream of frames, without having to
+     * continually submit identical requests through {@link #capture}.</p>
+     *
+     * <p>Repeat requests have lower priority than those submitted
+     * through {@link #capture} or {@link #captureBurst}, so if
+     * {@link #capture} is called when a repeating request is active, the
+     * capture request will be processed before any further repeating
+     * requests are processed.<p>
+     *
+     * <p>Repeating requests are a simple way for an application to maintain a
+     * preview or other continuous stream of frames, without having to submit
+     * requests through {@link #capture} at video rates.</p>
+     *
+     * <p>To stop the repeating capture, call {@link #stopRepeating}. Calling
+     * {@link #flush} will also clear the request.</p>
+     *
+     * <p>Calling this method will replace any earlier repeating request or
+     * burst set up by this method or {@link #setRepeatingBurst}, although any
+     * in-progress burst will be completed before the new repeat request will be
+     * used.</p>
+     *
+     * @param request the request to repeat indefinitely
+     * @param listener The callback object to notify every time the
+     * request finishes processing. If null, no metadata will be
+     * produced for this stream of requests, although image data will
+     * still be produced.
+     * @param handler the handler on which the listener should be invoked, or
+     * {@code null} to use the current thread's {@link android.os.Looper
+     * looper}.
+     *
+     * @throws CameraAccessException if the camera device is no longer
+     * connected
+     * @throws IllegalStateException if the camera device has been closed or the
+     * device has encountered a fatal error.
+     * @throws IllegalArgumentException If the requests reference Surfaces not
+     * currently configured as outputs. Or if the handler is null, the listener
+     * is not null, and the calling thread has no looper.
+     *
+     * @see #capture
+     * @see #captureBurst
+     * @see #setRepeatingBurst
+     * @see #stopRepeating
+     * @see #flush
+     */
+    public void setRepeatingRequest(CaptureRequest request, CaptureListener listener,
+            Handler handler) throws CameraAccessException;
+
+    /**
+     * <p>Request endlessly repeating capture of a sequence of images by this
+     * CameraDevice.</p>
+     *
+     * <p>With this method, the CameraDevice will continually capture images,
+     * cycling through the settings in the provided list of
+     * {@link CaptureRequest CaptureRequests}, at the maximum rate possible.</p>
+     *
+     * <p>If a request is submitted through {@link #capture} or
+     * {@link #captureBurst}, the current repetition of the request list will be
+     * completed before the higher-priority request is handled. This guarantees
+     * that the application always receives a complete repeat burst captured in
+     * minimal time, instead of bursts interleaved with higher-priority
+     * captures, or incomplete captures.</p>
+     *
+     * <p>Repeating burst requests are a simple way for an application to
+     * maintain a preview or other continuous stream of frames where each
+     * request is different in a predicatable way, without having to continually
+     * submit requests through {@link #captureBurst} .</p>
+     *
+     * <p>To stop the repeating capture, call {@link #stopRepeating}. Any
+     * ongoing burst will still be completed, however. Calling
+     * {@link #flush} will also clear the request.</p>
+     *
+     * <p>Calling this method will replace a previously-set repeating request or
+     * burst set up by this method or {@link #setRepeatingRequest}, although any
+     * in-progress burst will be completed before the new repeat burst will be
+     * used.</p>
+     *
+     * @param requests the list of requests to cycle through indefinitely
+     * @param listener The callback object to notify each time one of the
+     * requests in the repeating bursts has finished processing. If null, no
+     * metadata will be produced for this stream of requests, although image
+     * data will still be produced.
+     * @param handler the handler on which the listener should be invoked, or
+     * {@code null} to use the current thread's {@link android.os.Looper
+     * looper}.
+     *
+     * @throws CameraAccessException if the camera device is no longer connected
+     * @throws IllegalStateException if the camera device has been closed or the
+     * device has encountered a fatal error.
+     * @throws IllegalArgumentException If the requests reference Surfaces not
+     * currently configured as outputs. Or if the handler is null, the listener
+     * is not null, and the calling thread has no looper.
+     *
+     * @see #capture
+     * @see #captureBurst
+     * @see #setRepeatingRequest
+     * @see #stopRepeating
+     * @see #flush
+     */
+    public void setRepeatingBurst(List<CaptureRequest> requests, CaptureListener listener,
+            Handler handler) throws CameraAccessException;
+
+    /**
+     * <p>Cancel any ongoing repeating capture set by either
+     * {@link #setRepeatingRequest setRepeatingRequest} or
+     * {@link #setRepeatingBurst}. Has no effect on requests submitted through
+     * {@link #capture capture} or {@link #captureBurst captureBurst}.</p>
+     *
+     * <p>Any currently in-flight captures will still complete, as will any
+     * burst that is mid-capture. To ensure that the device has finished
+     * processing all of its capture requests and is in idle state, wait for the
+     * {@link CameraDeviceListener#onCameraIdle} callback after calling this
+     * method..</p>
+     *
+     * @throws CameraAccessException if the camera device is no longer connected
+     * @throws IllegalStateException if the camera device has been closed or the
+     * device has encountered a fatal error.
+     *
+     * @see #setRepeatingRequest
+     * @see #setRepeatingBurst
+     * @see CameraDeviceListener#onCameraIdle
+     *
+     * @throws CameraAccessException if the camera device is no longer connected
+     * @throws IllegalStateException if the camera device has been closed, the
+     * device has encountered a fatal error, or if there is an active repeating
+     * request or burst.
+     */
+    public void stopRepeating() throws CameraAccessException;
+
+    /**
+     * <p>Wait until all the submitted requests have finished processing</p>
+     *
+     * <p>This method blocks until all the requests that have been submitted to
+     * the camera device, either through {@link #capture capture},
+     * {@link #captureBurst captureBurst},
+     * {@link #setRepeatingRequest setRepeatingRequest}, or
+     * {@link #setRepeatingBurst setRepeatingBurst}, have completed their
+     * processing.</p>
+     *
+     * <p>Once this call returns successfully, the device is in an idle state,
+     * and can be reconfigured with {@link #configureOutputs configureOutputs}.</p>
+     *
+     * <p>This method cannot be used if there is an active repeating request or
+     * burst, set with {@link #setRepeatingRequest setRepeatingRequest} or
+     * {@link #setRepeatingBurst setRepeatingBurst}. Call
+     * {@link #stopRepeating stopRepeating} before calling this method.</p>
+     *
+     * @throws CameraAccessException if the camera device is no longer connected
+     * @throws IllegalStateException if the camera device has been closed, the
+     * device has encountered a fatal error, or if there is an active repeating
+     * request or burst.
+     */
+    public void waitUntilIdle() throws CameraAccessException;
+
+    /**
+     * Set the listener object to call when an asynchronous device event occurs,
+     * such as errors or idle notifications.
+     *
+     * <p>The events reported here are device-wide; notifications about
+     * individual capture requests or capture results are reported through
+     * {@link CaptureListener}.</p>
+     *
+     * <p>If the camera device is idle when the listener is set, then the
+     * {@link CameraDeviceListener#onCameraIdle} method will be immediately called,
+     * even if the device has never been active before.
+     * </p>
+     *
+     * @param listener the CameraDeviceListener to send device-level event
+     * notifications to. Setting this to null will stop notifications.
+     * @param handler the handler on which the listener should be invoked, or
+     * {@code null} to use the current thread's {@link android.os.Looper looper}.
+     *
+     * @throws IllegalArgumentException if handler is null, the listener is
+     * not null, and the calling thread has no looper
+     */
+    public void setDeviceListener(CameraDeviceListener listener, Handler handler);
+
+    /**
+     * Flush all captures currently pending and in-progress as fast as
+     * possible.
+     *
+     * <p>The camera device will discard all of its current work as fast as
+     * possible. Some in-flight captures may complete successfully and call
+     * {@link CaptureListener#onCaptureCompleted}, while others will trigger
+     * their {@link CaptureListener#onCaptureFailed} callbacks. If a repeating
+     * request or a repeating burst is set, it will be cleared by the flush.</p>
+     *
+     * <p>This method is the fastest way to idle the camera device for
+     * reconfiguration with {@link #configureOutputs}, at the cost of discarding
+     * in-progress work. Once the flush is complete, the idle callback will be
+     * called.</p>
+     *
+     * <p>Flushing will introduce at least a brief pause in the stream of data
+     * from the camera device, since once the flush is complete, the first new
+     * request has to make it through the entire camera pipeline before new
+     * output buffers are produced.</p>
+     *
+     * <p>This means that using {@code flush()} to simply remove pending
+     * requests is not recommended; it's best used for quickly switching output
+     * configurations, or for cancelling long in-progress requests (such as a
+     * multi-second capture).</p>
+     *
+     * @throws CameraAccessException if the camera device is no longer connected
+     * @see #setRepeatingRequest
+     * @see #setRepeatingBurst
+     * @see #configureOutputs
+     */
+    public void flush() throws CameraAccessException;
+
+    /**
+     * Close the connection to this camera device. After this call, all calls to
+     * the camera device interface will throw a {@link IllegalStateException},
+     * except for calls to close().
+     * @throws Exception
+     */
+    @Override
+    public void close() throws Exception;
+    // TODO: We should decide on the behavior of in-flight requests should be on close.
+
+    /**
+     * <p>A listener for tracking the progress of a {@link CaptureRequest}
+     * submitted to the camera device.</p>
+     *
+     * <p>This listener is called when a request triggers a capture to start,
+     * and when the capture is complete. In case on an error capturing an image,
+     * the error method is triggered instead of the completion method.</p>
+     *
+     * @see #capture
+     * @see #captureBurst
+     * @see #setRepeatingRequest
+     * @see #setRepeatingBurst
+     *
+     */
+    public static abstract class CaptureListener {
+
+        /**
+         * This method is called when the camera device has started capturing
+         * the output image for the request, at the beginning of image exposure.
+         *
+         * <p>This callback is invoked right as the capture of a frame begins,
+         * so it is the most appropriate time for playing a shutter sound,
+         * or triggering UI indicators of capture.</p>
+         *
+         * <p>The request that is being used for this capture is provided, along
+         * with the actual timestamp for the start of exposure. This timestamp
+         * matches the timestamp that will be included in
+         * {@link CaptureResult#SENSOR_TIMESTAMP the result timestamp field},
+         * and in the buffers sent to each output Surface. These buffer
+         * timestamps are accessible through, for example,
+         * {@link android.media.Image#getTimestamp() Image.getTimestamp()} or
+         * {@link android.graphics.SurfaceTexture#getTimestamp()}.</p>
+         *
+         * <p>For the simplest way to play a shutter sound camera shutter or a
+         * video recording start/stop sound, see the
+         * {@link android.media.MediaActionSound} class.</p>
+         *
+         * <p>The default implementation of this method does nothing.</p>
+         *
+         * @param camera the CameraDevice sending the callback
+         * @param request the request for the capture that just begun
+         * @param timestamp the timestamp at start of capture, in nanoseconds.
+         *
+         * @see android.media.MediaActionSound
+         */
+        public void onCaptureStarted(CameraDevice camera,
+                CaptureRequest request, long timestamp) {
+            // default empty implementation
+        }
+
+        /**
+         * This method is called when an image capture has completed and the
+         * result metadata is available.
+         *
+         * <p>The default implementation of this method does nothing.</p>
+         *
+         * @param camera The CameraDevice sending the callback.
+         * @param request The request that was given to the CameraDevice
+         * @param result The output metadata from the capture, including the
+         * final capture parameters and the state of the camera system during
+         * capture.
+         *
+         * @see #capture
+         * @see #captureBurst
+         * @see #setRepeatingRequest
+         * @see #setRepeatingBurst
+         */
+        public void onCaptureCompleted(CameraDevice camera,
+                CaptureRequest request, CaptureResult result) {
+            // default empty implementation
+        }
+
+        /**
+         * This method is called instead of {@link #onCaptureCompleted} when the
+         * camera device failed to produce a {@link CaptureResult} for the
+         * request.
+         *
+         * <p>Other requests are unaffected, and some or all image buffers from
+         * the capture may have been pushed to their respective output
+         * streams.</p>
+         *
+         * <p>The default implementation of this method does nothing.</p>
+         *
+         * @param camera The CameraDevice sending the callback.
+         * @param request The request that was given to the CameraDevice
+         *
+         * @see #capture
+         * @see #captureBurst
+         * @see #setRepeatingRequest
+         * @see #setRepeatingBurst
+         */
+        public void onCaptureFailed(CameraDevice camera,
+                CaptureRequest request) {
+            // default empty implementation
+        }
+    }
+
+    /**
+     * A listener for notifications about the state of a camera
+     * device.
+     *
+     * <p>These events include notifications about the device becoming idle (
+     * allowing for {@link #configureOutputs} to be called), about device
+     * disconnection, and about unexpected device errors.</p>
+     *
+     * <p>Events about the progress of specific {@link CaptureRequest
+     * CaptureRequests} are provided through a {@link CaptureListener} given to
+     * the {@link #capture}, {@link #captureBurst}, {@link
+     * #setRepeatingRequest}, or {@link #setRepeatingBurst} methods.
+     *
+     * @see #setDeviceListener
+     */
+    public static abstract class CameraDeviceListener {
+
+        /**
+         * An error code that can be reported by {@link #onCameraError}
+         * indicating that the camera device has encountered a fatal error.
+         *
+         * <p>The camera device needs to be re-opened to be used again.</p>
+         *
+         * @see #onCameraDeviceError
+         */
+        public static final int ERROR_CAMERA_DEVICE = 1;
+
+        /**
+         * An error code that can be reported by {@link #onCameraError}
+         * indicating that the camera service has encountered a fatal error.
+         *
+         * <p>The Android device may need to be shut down and restarted to restore
+         * camera function, or there may be a persistent hardware problem.</p>
+         *
+         * @see #onCameraDeviceError
+         */
+        public static final int ERROR_CAMERA_SERVICE = 2;
+
+        /**
+         * The method called when a camera device has finished processing all
+         * submitted capture requests and has reached an idle state.
+         *
+         * <p>An idle camera device can have its outputs changed by calling
+         * {@link CameraDevice#configureOutputs}.</p>
+         *
+         * <p>To idle and reconfigure outputs without cancelling any submitted
+         * capture requests, the application needs to clear its repeating
+         * request/burst, if set, with {@link CameraDevice#stopRepeating}, and
+         * then wait for this callback to be called before calling {@link
+         * CameraDevice#configureOutputs}.</p>
+         *
+         * <p>To idle and reconfigure a camera device as fast as possible, the
+         * {@link CameraDevice#flush} method can be used, which will discard all
+         * pending and in-progess capture requests. Once the {@link
+         * CameraDevice#flush} method is called, the application must wait for
+         * this callback to fire before calling {@link
+         * CameraDevice#configureOutputs}.</p>
+         *
+         * <p>The default implementation of this method does nothing.</p>
+         *
+         * @param camera the camera device that has become idle
+         *
+         * @see CameraDevice#configureOutputs
+         * @see CameraDevice#stopRepeating
+         * @see CameraDevice#flush
+         */
+        public void onCameraIdle(CameraDevice camera) {
+            // Default empty implementation
+        }
+
+        /**
+         * The method called when a camera device is no longer available for
+         * use.
+         *
+         * <p>Any attempt to call methods on this CameraDevice will throw a
+         * {@link CameraAccessException}. The disconnection could be due to a
+         * change in security policy or permissions; the physical disconnection
+         * of a removable camera device; or the camera being needed for a
+         * higher-priority use case.</p>
+         *
+         * <p>There may still be capture listener callbacks that are called
+         * after this method is called, or new image buffers that are delivered
+         * to active outputs.</p>
+         *
+         * <p>The default implementation logs a notice to the system log
+         * about the disconnection.</p>
+         *
+         * @param camera the device that has been disconnected
+         */
+        public void onCameraDisconnected(CameraDevice camera) {
+            Log.i("CameraListener",
+                    String.format("Camera device %s disconnected", camera.getId()));
+        }
+
+        /**
+         * The method called when a camera device has encountered a serious error.
+         *
+         * <p>This indicates a failure of the camera device or camera service in
+         * some way. Any attempt to call methods on this CameraDevice in the
+         * future will throw a {@link java.lang.IllegalStateException}.</p>
+         *
+         * <p>There may still be capture completion or camera stream listeners
+         * that will be called after this error is received.</p>
+         *
+         * <p>The default implementation logs an error to the system log about
+         * the camera failure.</p>
+         *
+         * @param camera The device reporting the error
+         * @param error The error code, one of the
+         *     {@code CameraDeviceListener.ERROR_*} values.
+         *
+         * @see #ERROR_CAMERA_DEVICE
+         * @see #ERROR_CAMERA_SERVICE
+         */
+        public void onCameraError(CameraDevice camera, int error) {
+            Log.e("CameraListener",
+                    String.format("Camera device %s has encountered an error: %d",
+                            camera.getId(), error));
+        }
+    }
+}
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
new file mode 100644
index 0000000..4ad9259
--- /dev/null
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -0,0 +1,422 @@
+/*
+ * 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.hardware.camera2;
+
+import android.content.Context;
+import android.hardware.ICameraService;
+import android.hardware.ICameraServiceListener;
+import android.hardware.IProCameraUser;
+import android.hardware.camera2.impl.CameraMetadataNative;
+import android.hardware.camera2.utils.CameraBinderDecorator;
+import android.hardware.camera2.utils.CameraRuntimeException;
+import android.hardware.camera2.utils.BinderHolder;
+import android.os.IBinder;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+import android.util.ArrayMap;
+
+import java.util.ArrayList;
+
+/**
+ * <p>An interface for iterating, listing, and connecting to
+ * {@link CameraDevice CameraDevices}.</p>
+ *
+ * <p>You can get an instance of this class by calling
+ * {@link android.content.Context#getSystemService(String) Context.getSystemService()}.</p>
+ *
+ * <pre>CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);</pre>
+ *
+ * <p>For more details about communicating with camera devices, read the Camera
+ * developer guide or the {@link android.hardware.camera2 camera2}
+ * package documentation.</p>
+ */
+public final class CameraManager {
+
+    /**
+     * This should match the ICameraService definition
+     */
+    private static final String CAMERA_SERVICE_BINDER_NAME = "media.camera";
+    private static final int USE_CALLING_UID = -1;
+
+    private final ICameraService mCameraService;
+    private ArrayList<String> mDeviceIdList;
+
+    private ArrayMap<AvailabilityListener, Handler> mListenerMap =
+            new ArrayMap<AvailabilityListener, Handler>();
+
+    private final Context mContext;
+    private final Object mLock = new Object();
+
+    /**
+     * @hide
+     */
+    public CameraManager(Context context) {
+        mContext = context;
+
+        IBinder cameraServiceBinder = ServiceManager.getService(CAMERA_SERVICE_BINDER_NAME);
+        ICameraService cameraServiceRaw = ICameraService.Stub.asInterface(cameraServiceBinder);
+
+        /**
+         * Wrap the camera service in a decorator which automatically translates return codes
+         * into exceptions, and RemoteExceptions into other exceptions.
+         */
+        mCameraService = CameraBinderDecorator.newInstance(cameraServiceRaw);
+
+        try {
+            mCameraService.addListener(new CameraServiceListener());
+        } catch(CameraRuntimeException e) {
+            throw new IllegalStateException("Failed to register a camera service listener",
+                    e.asChecked());
+        } catch (RemoteException e) {
+            // impossible
+        }
+    }
+
+    /**
+     * Return the list of currently connected camera devices by
+     * identifier.
+     *
+     * <p>Non-removable cameras use integers starting at 0 for their
+     * identifiers, while removable cameras have a unique identifier for each
+     * individual device, even if they are the same model.</p>
+     *
+     * @return The list of currently connected camera devices.
+     */
+    public String[] getCameraIdList() throws CameraAccessException {
+        synchronized (mLock) {
+            try {
+                return getOrCreateDeviceIdListLocked().toArray(new String[0]);
+            } catch(CameraAccessException e) {
+                // this should almost never happen, except if mediaserver crashes
+                throw new IllegalStateException(
+                        "Failed to query camera service for device ID list", e);
+            }
+        }
+    }
+
+    /**
+     * Register a listener to be notified about camera device availability.
+     *
+     * <p>Registering the same listener again will replace the handler with the
+     * new one provided.</p>
+     *
+     * @param listener The new listener to send camera availability notices to
+     * @param handler The handler on which the listener should be invoked, or
+     * {@code null} to use the current thread's {@link android.os.Looper looper}.
+     */
+    public void addAvailabilityListener(AvailabilityListener listener, Handler handler) {
+        if (handler == null) {
+            Looper looper = Looper.myLooper();
+            if (looper == null) {
+                throw new IllegalArgumentException(
+                        "No handler given, and current thread has no looper!");
+            }
+            handler = new Handler(looper);
+        }
+
+        synchronized (mLock) {
+            mListenerMap.put(listener, handler);
+        }
+    }
+
+    /**
+     * Remove a previously-added listener; the listener will no longer receive
+     * connection and disconnection callbacks.
+     *
+     * <p>Removing a listener that isn't registered has no effect.</p>
+     *
+     * @param listener The listener to remove from the notification list
+     */
+    public void removeAvailabilityListener(AvailabilityListener listener) {
+        synchronized (mLock) {
+            mListenerMap.remove(listener);
+        }
+    }
+
+    /**
+     * <p>Query the capabilities of a camera device. These capabilities are
+     * immutable for a given camera.</p>
+     *
+     * @param cameraId The id of the camera device to query
+     * @return The properties of the given camera
+     *
+     * @throws IllegalArgumentException if the cameraId does not match any
+     * currently connected camera device.
+     * @throws CameraAccessException if the camera is disabled by device policy.
+     * @throws SecurityException if the application does not have permission to
+     * access the camera
+     *
+     * @see #getCameraIdList
+     * @see android.app.admin.DevicePolicyManager#setCameraDisabled
+     */
+    public CameraProperties getCameraProperties(String cameraId)
+            throws CameraAccessException {
+
+        synchronized (mLock) {
+            if (!getOrCreateDeviceIdListLocked().contains(cameraId)) {
+                throw new IllegalArgumentException(String.format("Camera id %s does not match any" +
+                        " currently connected camera device", cameraId));
+            }
+        }
+
+        // TODO: implement and call a service function to get the capabilities on C++ side
+
+        // TODO: get properties from service
+        return new CameraProperties(new CameraMetadataNative());
+    }
+
+    /**
+     * Open a connection to a camera with the given ID. Use
+     * {@link #getCameraIdList} to get the list of available camera
+     * devices. Note that even if an id is listed, open may fail if the device
+     * is disconnected between the calls to {@link #getCameraIdList} and
+     * {@link #openCamera}.
+     *
+     * @param cameraId The unique identifier of the camera device to open
+     *
+     * @throws CameraAccessException if the camera is disabled by device policy,
+     * or too many camera devices are already open, or the cameraId does not match
+     * any currently available camera device.
+     *
+     * @throws SecurityException if the application does not have permission to
+     * access the camera
+     *
+     * @see #getCameraIdList
+     * @see android.app.admin.DevicePolicyManager#setCameraDisabled
+     */
+    public CameraDevice openCamera(String cameraId) throws CameraAccessException {
+
+        try {
+
+            synchronized (mLock) {
+
+                ICameraDeviceUser cameraUser;
+
+                android.hardware.camera2.impl.CameraDevice device =
+                        new android.hardware.camera2.impl.CameraDevice(cameraId);
+
+                BinderHolder holder = new BinderHolder();
+                mCameraService.connectDevice(device.getCallbacks(),
+                        Integer.parseInt(cameraId),
+                        mContext.getPackageName(), USE_CALLING_UID, holder);
+                cameraUser = ICameraDeviceUser.Stub.asInterface(holder.getBinder());
+
+                // TODO: factor out listener to be non-nested, then move setter to constructor
+                device.setRemoteDevice(cameraUser);
+
+                return device;
+
+            }
+
+        } catch (NumberFormatException e) {
+            throw new IllegalArgumentException("Expected cameraId to be numeric, but it was: "
+                    + cameraId);
+        } catch (CameraRuntimeException e) {
+            throw e.asChecked();
+        } catch (RemoteException e) {
+            // impossible
+            return null;
+        }
+    }
+
+    /**
+     * Interface for listening to camera devices becoming available or
+     * unavailable.
+     *
+     * <p>Cameras become available when they are no longer in use, or when a new
+     * removable camera is connected. They become unavailable when some
+     * application or service starts using a camera, or when a removable camera
+     * is disconnected.</p>
+     *
+     * @see addAvailabilityListener
+     */
+    public static abstract class AvailabilityListener {
+
+        /**
+         * A new camera has become available to use.
+         *
+         * <p>The default implementation of this method does nothing.</p>
+         *
+         * @param cameraId The unique identifier of the new camera.
+         */
+        public void onCameraAvailable(String cameraId) {
+            // default empty implementation
+        }
+
+        /**
+         * A previously-available camera has become unavailable for use.
+         *
+         * <p>If an application had an active CameraDevice instance for the
+         * now-disconnected camera, that application will receive a
+         * {@link CameraDevice.CameraDeviceListener#onCameraDisconnected disconnection error}.</p>
+         *
+         * <p>The default implementation of this method does nothing.</p>
+         *
+         * @param cameraId The unique identifier of the disconnected camera.
+         */
+        public void onCameraUnavailable(String cameraId) {
+            // default empty implementation
+        }
+    }
+
+    private ArrayList<String> getOrCreateDeviceIdListLocked() throws CameraAccessException {
+        if (mDeviceIdList == null) {
+            int numCameras = 0;
+
+            try {
+                numCameras = mCameraService.getNumberOfCameras();
+            } catch(CameraRuntimeException e) {
+                throw e.asChecked();
+            } catch (RemoteException e) {
+                // impossible
+                return null;
+            }
+
+            mDeviceIdList = new ArrayList<String>();
+            for (int i = 0; i < numCameras; ++i) {
+                // Non-removable cameras use integers starting at 0 for their
+                // identifiers
+                mDeviceIdList.add(String.valueOf(i));
+            }
+
+        }
+        return mDeviceIdList;
+    }
+
+    // TODO: this class needs unit tests
+    // TODO: extract class into top level
+    private class CameraServiceListener extends ICameraServiceListener.Stub {
+
+        // Keep up-to-date with ICameraServiceListener.h
+
+        // Device physically unplugged
+        public static final int STATUS_NOT_PRESENT = 0;
+        // Device physically has been plugged in
+        // and the camera can be used exclusively
+        public static final int STATUS_PRESENT = 1;
+        // Device physically has been plugged in
+        // but it will not be connect-able until enumeration is complete
+        public static final int STATUS_ENUMERATING = 2;
+        // Camera is in use by another app and cannot be used exclusively
+        public static final int STATUS_NOT_AVAILABLE = 0x80000000;
+
+        // Camera ID -> Status map
+        private final ArrayMap<String, Integer> mDeviceStatus = new ArrayMap<String, Integer>();
+
+        private static final String TAG = "CameraServiceListener";
+
+        @Override
+        public IBinder asBinder() {
+            return this;
+        }
+
+        private boolean isAvailable(int status) {
+            switch (status) {
+                case STATUS_PRESENT:
+                    return true;
+                default:
+                    return false;
+            }
+        }
+
+        private boolean validStatus(int status) {
+            switch (status) {
+                case STATUS_NOT_PRESENT:
+                case STATUS_PRESENT:
+                case STATUS_ENUMERATING:
+                case STATUS_NOT_AVAILABLE:
+                    return true;
+                default:
+                    return false;
+            }
+        }
+
+        @Override
+        public void onStatusChanged(int status, int cameraId) throws RemoteException {
+            synchronized(CameraManager.this.mLock) {
+
+                Log.v(TAG,
+                        String.format("Camera id %d has status changed to 0x%x", cameraId, status));
+
+                final String id = String.valueOf(cameraId);
+
+                if (!validStatus(status)) {
+                    Log.e(TAG, String.format("Ignoring invalid device %d status 0x%x", cameraId,
+                            status));
+                    return;
+                }
+
+                Integer oldStatus = mDeviceStatus.put(id, status);
+
+                if (oldStatus != null && oldStatus == status) {
+                    Log.v(TAG, String.format(
+                            "Device status changed to 0x%x, which is what it already was",
+                            status));
+                    return;
+                }
+
+                // TODO: consider abstracting out this state minimization + transition
+                // into a separate
+                // more easily testable class
+                // i.e. (new State()).addState(STATE_AVAILABLE)
+                //                   .addState(STATE_NOT_AVAILABLE)
+                //                   .addTransition(STATUS_PRESENT, STATE_AVAILABLE),
+                //                   .addTransition(STATUS_NOT_PRESENT, STATE_NOT_AVAILABLE)
+                //                   .addTransition(STATUS_ENUMERATING, STATE_NOT_AVAILABLE);
+                //                   .addTransition(STATUS_NOT_AVAILABLE, STATE_NOT_AVAILABLE);
+
+                // Translate all the statuses to either 'available' or 'not available'
+                //  available -> available         => no new update
+                //  not available -> not available => no new update
+                if (oldStatus != null && isAvailable(status) == isAvailable(oldStatus)) {
+
+                    Log.v(TAG,
+                            String.format(
+                                    "Device status was previously available (%d), " +
+                                            " and is now again available (%d)" +
+                                            "so no new client visible update will be sent",
+                                    isAvailable(status), isAvailable(status)));
+                    return;
+                }
+
+                final int listenerCount = mListenerMap.size();
+                for (int i = 0; i < listenerCount; i++) {
+                    Handler handler = mListenerMap.valueAt(i);
+                    final AvailabilityListener listener = mListenerMap.keyAt(i);
+                    if (isAvailable(status)) {
+                        handler.post(
+                            new Runnable() {
+                                public void run() {
+                                    listener.onCameraAvailable(id);
+                                }
+                            });
+                    } else {
+                        handler.post(
+                            new Runnable() {
+                                public void run() {
+                                    listener.onCameraUnavailable(id);
+                                }
+                            });
+                    }
+                } // for
+            } // synchronized
+        } // onStatusChanged
+    } // CameraServiceListener
+} // CameraManager
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
new file mode 100644
index 0000000..ec23f08
--- /dev/null
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -0,0 +1,1164 @@
+/*
+ * 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.hardware.camera2;
+
+import android.hardware.camera2.impl.CameraMetadataNative;
+
+/**
+ * The base class for camera controls and information.
+ *
+ * This class defines the basic key/value map used for querying for camera
+ * characteristics or capture results, and for setting camera request
+ * parameters.
+ *
+ * @see CameraDevice
+ * @see CameraManager
+ * @see CameraProperties
+ **/
+public abstract class CameraMetadata {
+
+    /**
+     * @hide
+     */
+    protected CameraMetadata() {
+    }
+
+    /**
+     * Get a camera metadata field value. The field definitions can be
+     * found in {@link CameraProperties}, {@link CaptureResult}, and
+     * {@link CaptureRequest}.
+     *
+     * @throws IllegalArgumentException if the key was not valid
+     *
+     * @param key The metadata field to read.
+     * @return The value of that key, or {@code null} if the field is not set.
+     */
+    public abstract <T> T get(Key<T> key);
+
+    public static class Key<T> {
+
+        private boolean mHasTag;
+        private int mTag;
+        private final Class<T> mType;
+        private final String mName;
+
+        /**
+         * @hide
+         */
+        public Key(String name, Class<T> type) {
+            if (name == null) {
+                throw new NullPointerException("Key needs a valid name");
+            } else if (type == null) {
+                throw new NullPointerException("Type needs to be non-null");
+            }
+            mName = name;
+            mType = type;
+        }
+
+        public final String getName() {
+            return mName;
+        }
+
+        @Override
+        public final int hashCode() {
+            return mName.hashCode();
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public final boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+
+            if (!(o instanceof Key)) {
+                return false;
+            }
+
+            Key lhs = (Key) o;
+
+            return mName.equals(lhs.mName);
+        }
+
+        /**
+         * <p>
+         * Get the tag corresponding to this key. This enables insertion into the
+         * native metadata.
+         * </p>
+         *
+         * <p>This value is looked up the first time, and cached subsequently.</p>
+         *
+         * @return The tag numeric value corresponding to the string
+         *
+         * @hide
+         */
+        public final int getTag() {
+            if (!mHasTag) {
+                mTag = CameraMetadataNative.getTag(mName);
+                mHasTag = true;
+            }
+            return mTag;
+        }
+
+        /**
+         * @hide
+         */
+        public final Class<T> getType() {
+            return mType;
+        }
+    }
+
+    /*@O~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
+     * The enum values below this point are generated from metadata
+     * definitions in /system/media/camera/docs. Do not modify by hand or
+     * modify the comment blocks at the start or end.
+     *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~*/
+
+    //
+    // Enumeration values for CameraProperties#LENS_FACING
+    //
+
+    /**
+     * @see CameraProperties#LENS_FACING
+     */
+    public static final int LENS_FACING_FRONT = 0;
+
+    /**
+     * @see CameraProperties#LENS_FACING
+     */
+    public static final int LENS_FACING_BACK = 1;
+
+    //
+    // Enumeration values for CameraProperties#LED_AVAILABLE_LEDS
+    //
+
+    /**
+     * <p>
+     * android.led.transmit control is used
+     * </p>
+     * @see CameraProperties#LED_AVAILABLE_LEDS
+     * @hide
+     */
+    public static final int LED_AVAILABLE_LEDS_TRANSMIT = 0;
+
+    //
+    // Enumeration values for CameraProperties#INFO_SUPPORTED_HARDWARE_LEVEL
+    //
+
+    /**
+     * @see CameraProperties#INFO_SUPPORTED_HARDWARE_LEVEL
+     */
+    public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED = 0;
+
+    /**
+     * @see CameraProperties#INFO_SUPPORTED_HARDWARE_LEVEL
+     */
+    public static final int INFO_SUPPORTED_HARDWARE_LEVEL_FULL = 1;
+
+    //
+    // Enumeration values for CaptureRequest#COLOR_CORRECTION_MODE
+    //
+
+    /**
+     * <p>
+     * Use the android.colorCorrection.transform matrix
+     * and android.colorCorrection.gains to do color conversion
+     * </p>
+     * @see CaptureRequest#COLOR_CORRECTION_MODE
+     */
+    public static final int COLOR_CORRECTION_MODE_TRANSFORM_MATRIX = 0;
+
+    /**
+     * <p>
+     * Must not slow down frame rate relative to raw
+     * bayer output
+     * </p>
+     * @see CaptureRequest#COLOR_CORRECTION_MODE
+     */
+    public static final int COLOR_CORRECTION_MODE_FAST = 1;
+
+    /**
+     * <p>
+     * Frame rate may be reduced by high
+     * quality
+     * </p>
+     * @see CaptureRequest#COLOR_CORRECTION_MODE
+     */
+    public static final int COLOR_CORRECTION_MODE_HIGH_QUALITY = 2;
+
+    //
+    // Enumeration values for CaptureRequest#CONTROL_AE_ANTIBANDING_MODE
+    //
+
+    /**
+     * @see CaptureRequest#CONTROL_AE_ANTIBANDING_MODE
+     */
+    public static final int CONTROL_AE_ANTIBANDING_MODE_OFF = 0;
+
+    /**
+     * @see CaptureRequest#CONTROL_AE_ANTIBANDING_MODE
+     */
+    public static final int CONTROL_AE_ANTIBANDING_MODE_50HZ = 1;
+
+    /**
+     * @see CaptureRequest#CONTROL_AE_ANTIBANDING_MODE
+     */
+    public static final int CONTROL_AE_ANTIBANDING_MODE_60HZ = 2;
+
+    /**
+     * @see CaptureRequest#CONTROL_AE_ANTIBANDING_MODE
+     */
+    public static final int CONTROL_AE_ANTIBANDING_MODE_AUTO = 3;
+
+    //
+    // Enumeration values for CaptureRequest#CONTROL_AE_MODE
+    //
+
+    /**
+     * <p>
+     * Autoexposure is disabled; sensor.exposureTime,
+     * sensor.sensitivity and sensor.frameDuration are used
+     * </p>
+     * @see CaptureRequest#CONTROL_AE_MODE
+     */
+    public static final int CONTROL_AE_MODE_OFF = 0;
+
+    /**
+     * <p>
+     * Autoexposure is active, no flash
+     * control
+     * </p>
+     * @see CaptureRequest#CONTROL_AE_MODE
+     */
+    public static final int CONTROL_AE_MODE_ON = 1;
+
+    /**
+     * <p>
+     * if flash exists Autoexposure is active, auto
+     * flash control; flash may be fired when precapture
+     * trigger is activated, and for captures for which
+     * captureIntent = STILL_CAPTURE
+     * </p>
+     * @see CaptureRequest#CONTROL_AE_MODE
+     */
+    public static final int CONTROL_AE_MODE_ON_AUTO_FLASH = 2;
+
+    /**
+     * <p>
+     * if flash exists Autoexposure is active, auto
+     * flash control for precapture trigger and always flash
+     * when captureIntent = STILL_CAPTURE
+     * </p>
+     * @see CaptureRequest#CONTROL_AE_MODE
+     */
+    public static final int CONTROL_AE_MODE_ON_ALWAYS_FLASH = 3;
+
+    /**
+     * <p>
+     * optional Automatic red eye reduction with flash.
+     * If deemed necessary, red eye reduction sequence should
+     * fire when precapture trigger is activated, and final
+     * flash should fire when captureIntent =
+     * STILL_CAPTURE
+     * </p>
+     * @see CaptureRequest#CONTROL_AE_MODE
+     */
+    public static final int CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE = 4;
+
+    //
+    // Enumeration values for CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
+    //
+
+    /**
+     * <p>
+     * The trigger is idle.
+     * </p>
+     * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
+     */
+    public static final int CONTROL_AE_PRECAPTURE_TRIGGER_IDLE = 0;
+
+    /**
+     * <p>
+     * The precapture metering sequence
+     * must be started. The exact effect of the precapture
+     * trigger depends on the current AE mode and
+     * state.
+     * </p>
+     * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
+     */
+    public static final int CONTROL_AE_PRECAPTURE_TRIGGER_START = 1;
+
+    //
+    // Enumeration values for CaptureRequest#CONTROL_AF_MODE
+    //
+
+    /**
+     * <p>
+     * The 3A routines do not control the lens;
+     * android.lens.focusDistance is controlled by the
+     * application
+     * </p>
+     * @see CaptureRequest#CONTROL_AF_MODE
+     */
+    public static final int CONTROL_AF_MODE_OFF = 0;
+
+    /**
+     * <p>
+     * if lens is not fixed focus.
+     * </p><p>
+     * Use android.lens.minimumFocusDistance to determine if lens
+     * is fixed focus In this mode, the lens does not move unless
+     * the autofocus trigger action is called. When that trigger
+     * is activated, AF must transition to ACTIVE_SCAN, then to
+     * the outcome of the scan (FOCUSED or
+     * NOT_FOCUSED).
+     * </p><p>
+     * Triggering cancel AF resets the lens position to default,
+     * and sets the AF state to INACTIVE.
+     * </p>
+     * @see CaptureRequest#CONTROL_AF_MODE
+     */
+    public static final int CONTROL_AF_MODE_AUTO = 1;
+
+    /**
+     * <p>
+     * In this mode, the lens does not move unless the
+     * autofocus trigger action is called.
+     * </p><p>
+     * When that trigger is activated, AF must transition to
+     * ACTIVE_SCAN, then to the outcome of the scan (FOCUSED or
+     * NOT_FOCUSED).  Triggering cancel AF resets the lens
+     * position to default, and sets the AF state to
+     * INACTIVE.
+     * </p>
+     * @see CaptureRequest#CONTROL_AF_MODE
+     */
+    public static final int CONTROL_AF_MODE_MACRO = 2;
+
+    /**
+     * <p>
+     * In this mode, the AF algorithm modifies the lens
+     * position continually to attempt to provide a
+     * constantly-in-focus image stream.
+     * </p><p>
+     * The focusing behavior should be suitable for good quality
+     * video recording; typically this means slower focus
+     * movement and no overshoots. When the AF trigger is not
+     * involved, the AF algorithm should start in INACTIVE state,
+     * and then transition into PASSIVE_SCAN and PASSIVE_FOCUSED
+     * states as appropriate. When the AF trigger is activated,
+     * the algorithm should immediately transition into
+     * AF_FOCUSED or AF_NOT_FOCUSED as appropriate, and lock the
+     * lens position until a cancel AF trigger is received.
+     * </p><p>
+     * Once cancel is received, the algorithm should transition
+     * back to INACTIVE and resume passive scan. Note that this
+     * behavior is not identical to CONTINUOUS_PICTURE, since an
+     * ongoing PASSIVE_SCAN must immediately be
+     * canceled.
+     * </p>
+     * @see CaptureRequest#CONTROL_AF_MODE
+     */
+    public static final int CONTROL_AF_MODE_CONTINUOUS_VIDEO = 3;
+
+    /**
+     * <p>
+     * In this mode, the AF algorithm modifies the lens
+     * position continually to attempt to provide a
+     * constantly-in-focus image stream.
+     * </p><p>
+     * The focusing behavior should be suitable for still image
+     * capture; typically this means focusing as fast as
+     * possible. When the AF trigger is not involved, the AF
+     * algorithm should start in INACTIVE state, and then
+     * transition into PASSIVE_SCAN and PASSIVE_FOCUSED states as
+     * appropriate as it attempts to maintain focus. When the AF
+     * trigger is activated, the algorithm should finish its
+     * PASSIVE_SCAN if active, and then transition into
+     * AF_FOCUSED or AF_NOT_FOCUSED as appropriate, and lock the
+     * lens position until a cancel AF trigger is received.
+     * </p><p>
+     * When the AF cancel trigger is activated, the algorithm
+     * should transition back to INACTIVE and then act as if it
+     * has just been started.
+     * </p>
+     * @see CaptureRequest#CONTROL_AF_MODE
+     */
+    public static final int CONTROL_AF_MODE_CONTINUOUS_PICTURE = 4;
+
+    /**
+     * <p>
+     * Extended depth of field (digital focus). AF
+     * trigger is ignored, AF state should always be
+     * INACTIVE.
+     * </p>
+     * @see CaptureRequest#CONTROL_AF_MODE
+     */
+    public static final int CONTROL_AF_MODE_EDOF = 5;
+
+    //
+    // Enumeration values for CaptureRequest#CONTROL_AF_TRIGGER
+    //
+
+    /**
+     * <p>
+     * The trigger is idle.
+     * </p>
+     * @see CaptureRequest#CONTROL_AF_TRIGGER
+     */
+    public static final int CONTROL_AF_TRIGGER_IDLE = 0;
+
+    /**
+     * <p>
+     * Autofocus must trigger now.
+     * </p>
+     * @see CaptureRequest#CONTROL_AF_TRIGGER
+     */
+    public static final int CONTROL_AF_TRIGGER_START = 1;
+
+    /**
+     * <p>
+     * Autofocus must return to initial
+     * state, and cancel any active trigger.
+     * </p>
+     * @see CaptureRequest#CONTROL_AF_TRIGGER
+     */
+    public static final int CONTROL_AF_TRIGGER_CANCEL = 2;
+
+    //
+    // Enumeration values for CaptureRequest#CONTROL_AWB_MODE
+    //
+
+    /**
+     * @see CaptureRequest#CONTROL_AWB_MODE
+     */
+    public static final int CONTROL_AWB_MODE_OFF = 0;
+
+    /**
+     * @see CaptureRequest#CONTROL_AWB_MODE
+     */
+    public static final int CONTROL_AWB_MODE_AUTO = 1;
+
+    /**
+     * @see CaptureRequest#CONTROL_AWB_MODE
+     */
+    public static final int CONTROL_AWB_MODE_INCANDESCENT = 2;
+
+    /**
+     * @see CaptureRequest#CONTROL_AWB_MODE
+     */
+    public static final int CONTROL_AWB_MODE_FLUORESCENT = 3;
+
+    /**
+     * @see CaptureRequest#CONTROL_AWB_MODE
+     */
+    public static final int CONTROL_AWB_MODE_WARM_FLUORESCENT = 4;
+
+    /**
+     * @see CaptureRequest#CONTROL_AWB_MODE
+     */
+    public static final int CONTROL_AWB_MODE_DAYLIGHT = 5;
+
+    /**
+     * @see CaptureRequest#CONTROL_AWB_MODE
+     */
+    public static final int CONTROL_AWB_MODE_CLOUDY_DAYLIGHT = 6;
+
+    /**
+     * @see CaptureRequest#CONTROL_AWB_MODE
+     */
+    public static final int CONTROL_AWB_MODE_TWILIGHT = 7;
+
+    /**
+     * @see CaptureRequest#CONTROL_AWB_MODE
+     */
+    public static final int CONTROL_AWB_MODE_SHADE = 8;
+
+    //
+    // Enumeration values for CaptureRequest#CONTROL_CAPTURE_INTENT
+    //
+
+    /**
+     * <p>
+     * This request doesn't fall into the other
+     * categories. Default to preview-like
+     * behavior.
+     * </p>
+     * @see CaptureRequest#CONTROL_CAPTURE_INTENT
+     */
+    public static final int CONTROL_CAPTURE_INTENT_CUSTOM = 0;
+
+    /**
+     * <p>
+     * This request is for a preview-like usecase. The
+     * precapture trigger may be used to start off a metering
+     * w/flash sequence
+     * </p>
+     * @see CaptureRequest#CONTROL_CAPTURE_INTENT
+     */
+    public static final int CONTROL_CAPTURE_INTENT_PREVIEW = 1;
+
+    /**
+     * <p>
+     * This request is for a still capture-type
+     * usecase.
+     * </p>
+     * @see CaptureRequest#CONTROL_CAPTURE_INTENT
+     */
+    public static final int CONTROL_CAPTURE_INTENT_STILL_CAPTURE = 2;
+
+    /**
+     * <p>
+     * This request is for a video recording
+     * usecase.
+     * </p>
+     * @see CaptureRequest#CONTROL_CAPTURE_INTENT
+     */
+    public static final int CONTROL_CAPTURE_INTENT_VIDEO_RECORD = 3;
+
+    /**
+     * <p>
+     * This request is for a video snapshot (still
+     * image while recording video) usecase
+     * </p>
+     * @see CaptureRequest#CONTROL_CAPTURE_INTENT
+     */
+    public static final int CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT = 4;
+
+    /**
+     * <p>
+     * This request is for a ZSL usecase; the
+     * application will stream full-resolution images and
+     * reprocess one or several later for a final
+     * capture
+     * </p>
+     * @see CaptureRequest#CONTROL_CAPTURE_INTENT
+     */
+    public static final int CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG = 5;
+
+    //
+    // Enumeration values for CaptureRequest#CONTROL_EFFECT_MODE
+    //
+
+    /**
+     * @see CaptureRequest#CONTROL_EFFECT_MODE
+     */
+    public static final int CONTROL_EFFECT_MODE_OFF = 0;
+
+    /**
+     * @see CaptureRequest#CONTROL_EFFECT_MODE
+     */
+    public static final int CONTROL_EFFECT_MODE_MONO = 1;
+
+    /**
+     * @see CaptureRequest#CONTROL_EFFECT_MODE
+     */
+    public static final int CONTROL_EFFECT_MODE_NEGATIVE = 2;
+
+    /**
+     * @see CaptureRequest#CONTROL_EFFECT_MODE
+     */
+    public static final int CONTROL_EFFECT_MODE_SOLARIZE = 3;
+
+    /**
+     * @see CaptureRequest#CONTROL_EFFECT_MODE
+     */
+    public static final int CONTROL_EFFECT_MODE_SEPIA = 4;
+
+    /**
+     * @see CaptureRequest#CONTROL_EFFECT_MODE
+     */
+    public static final int CONTROL_EFFECT_MODE_POSTERIZE = 5;
+
+    /**
+     * @see CaptureRequest#CONTROL_EFFECT_MODE
+     */
+    public static final int CONTROL_EFFECT_MODE_WHITEBOARD = 6;
+
+    /**
+     * @see CaptureRequest#CONTROL_EFFECT_MODE
+     */
+    public static final int CONTROL_EFFECT_MODE_BLACKBOARD = 7;
+
+    /**
+     * @see CaptureRequest#CONTROL_EFFECT_MODE
+     */
+    public static final int CONTROL_EFFECT_MODE_AQUA = 8;
+
+    //
+    // Enumeration values for CaptureRequest#CONTROL_MODE
+    //
+
+    /**
+     * <p>
+     * Full application control of pipeline. All 3A
+     * routines are disabled, no other settings in
+     * android.control.* have any effect
+     * </p>
+     * @see CaptureRequest#CONTROL_MODE
+     */
+    public static final int CONTROL_MODE_OFF = 0;
+
+    /**
+     * <p>
+     * Use settings for each individual 3A routine.
+     * Manual control of capture parameters is disabled. All
+     * controls in android.control.* besides sceneMode take
+     * effect
+     * </p>
+     * @see CaptureRequest#CONTROL_MODE
+     */
+    public static final int CONTROL_MODE_AUTO = 1;
+
+    /**
+     * <p>
+     * Use specific scene mode. Enabling this disables
+     * control.aeMode, control.awbMode and control.afMode
+     * controls; the HAL must ignore those settings while
+     * USE_SCENE_MODE is active (except for FACE_PRIORITY
+     * scene mode). Other control entries are still active.
+     * This setting can only be used if availableSceneModes !=
+     * UNSUPPORTED
+     * </p>
+     * @see CaptureRequest#CONTROL_MODE
+     */
+    public static final int CONTROL_MODE_USE_SCENE_MODE = 2;
+
+    //
+    // Enumeration values for CaptureRequest#CONTROL_SCENE_MODE
+    //
+
+    /**
+     * @see CaptureRequest#CONTROL_SCENE_MODE
+     */
+    public static final int CONTROL_SCENE_MODE_UNSUPPORTED = 0;
+
+    /**
+     * <p>
+     * if face detection support exists Use face
+     * detection data to drive 3A routines. If face detection
+     * statistics are disabled, should still operate correctly
+     * (but not return face detection statistics to the
+     * framework).
+     * </p><p>
+     * Unlike the other scene modes, aeMode, awbMode, and afMode
+     * remain active when FACE_PRIORITY is set. This is due to
+     * compatibility concerns with the old camera
+     * API
+     * </p>
+     * @see CaptureRequest#CONTROL_SCENE_MODE
+     */
+    public static final int CONTROL_SCENE_MODE_FACE_PRIORITY = 1;
+
+    /**
+     * @see CaptureRequest#CONTROL_SCENE_MODE
+     */
+    public static final int CONTROL_SCENE_MODE_ACTION = 2;
+
+    /**
+     * @see CaptureRequest#CONTROL_SCENE_MODE
+     */
+    public static final int CONTROL_SCENE_MODE_PORTRAIT = 3;
+
+    /**
+     * @see CaptureRequest#CONTROL_SCENE_MODE
+     */
+    public static final int CONTROL_SCENE_MODE_LANDSCAPE = 4;
+
+    /**
+     * @see CaptureRequest#CONTROL_SCENE_MODE
+     */
+    public static final int CONTROL_SCENE_MODE_NIGHT = 5;
+
+    /**
+     * @see CaptureRequest#CONTROL_SCENE_MODE
+     */
+    public static final int CONTROL_SCENE_MODE_NIGHT_PORTRAIT = 6;
+
+    /**
+     * @see CaptureRequest#CONTROL_SCENE_MODE
+     */
+    public static final int CONTROL_SCENE_MODE_THEATRE = 7;
+
+    /**
+     * @see CaptureRequest#CONTROL_SCENE_MODE
+     */
+    public static final int CONTROL_SCENE_MODE_BEACH = 8;
+
+    /**
+     * @see CaptureRequest#CONTROL_SCENE_MODE
+     */
+    public static final int CONTROL_SCENE_MODE_SNOW = 9;
+
+    /**
+     * @see CaptureRequest#CONTROL_SCENE_MODE
+     */
+    public static final int CONTROL_SCENE_MODE_SUNSET = 10;
+
+    /**
+     * @see CaptureRequest#CONTROL_SCENE_MODE
+     */
+    public static final int CONTROL_SCENE_MODE_STEADYPHOTO = 11;
+
+    /**
+     * @see CaptureRequest#CONTROL_SCENE_MODE
+     */
+    public static final int CONTROL_SCENE_MODE_FIREWORKS = 12;
+
+    /**
+     * @see CaptureRequest#CONTROL_SCENE_MODE
+     */
+    public static final int CONTROL_SCENE_MODE_SPORTS = 13;
+
+    /**
+     * @see CaptureRequest#CONTROL_SCENE_MODE
+     */
+    public static final int CONTROL_SCENE_MODE_PARTY = 14;
+
+    /**
+     * @see CaptureRequest#CONTROL_SCENE_MODE
+     */
+    public static final int CONTROL_SCENE_MODE_CANDLELIGHT = 15;
+
+    /**
+     * @see CaptureRequest#CONTROL_SCENE_MODE
+     */
+    public static final int CONTROL_SCENE_MODE_BARCODE = 16;
+
+    //
+    // Enumeration values for CaptureRequest#EDGE_MODE
+    //
+
+    /**
+     * <p>
+     * No edge enhancement is applied
+     * </p>
+     * @see CaptureRequest#EDGE_MODE
+     */
+    public static final int EDGE_MODE_OFF = 0;
+
+    /**
+     * <p>
+     * Must not slow down frame rate relative to raw
+     * bayer output
+     * </p>
+     * @see CaptureRequest#EDGE_MODE
+     */
+    public static final int EDGE_MODE_FAST = 1;
+
+    /**
+     * <p>
+     * Frame rate may be reduced by high
+     * quality
+     * </p>
+     * @see CaptureRequest#EDGE_MODE
+     */
+    public static final int EDGE_MODE_HIGH_QUALITY = 2;
+
+    //
+    // Enumeration values for CaptureRequest#FLASH_MODE
+    //
+
+    /**
+     * <p>
+     * Do not fire the flash for this
+     * capture
+     * </p>
+     * @see CaptureRequest#FLASH_MODE
+     */
+    public static final int FLASH_MODE_OFF = 0;
+
+    /**
+     * <p>
+     * if android.flash.available is true Fire flash
+     * for this capture based on firingPower,
+     * firingTime.
+     * </p>
+     * @see CaptureRequest#FLASH_MODE
+     */
+    public static final int FLASH_MODE_SINGLE = 1;
+
+    /**
+     * <p>
+     * if android.flash.available is true Flash
+     * continuously on, power set by
+     * firingPower
+     * </p>
+     * @see CaptureRequest#FLASH_MODE
+     */
+    public static final int FLASH_MODE_TORCH = 2;
+
+    //
+    // Enumeration values for CaptureRequest#LENS_OPTICAL_STABILIZATION_MODE
+    //
+
+    /**
+     * @see CaptureRequest#LENS_OPTICAL_STABILIZATION_MODE
+     */
+    public static final int LENS_OPTICAL_STABILIZATION_MODE_OFF = 0;
+
+    /**
+     * @see CaptureRequest#LENS_OPTICAL_STABILIZATION_MODE
+     */
+    public static final int LENS_OPTICAL_STABILIZATION_MODE_ON = 1;
+
+    //
+    // Enumeration values for CaptureRequest#NOISE_REDUCTION_MODE
+    //
+
+    /**
+     * <p>
+     * No noise reduction is applied
+     * </p>
+     * @see CaptureRequest#NOISE_REDUCTION_MODE
+     */
+    public static final int NOISE_REDUCTION_MODE_OFF = 0;
+
+    /**
+     * <p>
+     * Must not slow down frame rate relative to raw
+     * bayer output
+     * </p>
+     * @see CaptureRequest#NOISE_REDUCTION_MODE
+     */
+    public static final int NOISE_REDUCTION_MODE_FAST = 1;
+
+    /**
+     * <p>
+     * May slow down frame rate to provide highest
+     * quality
+     * </p>
+     * @see CaptureRequest#NOISE_REDUCTION_MODE
+     */
+    public static final int NOISE_REDUCTION_MODE_HIGH_QUALITY = 2;
+
+    //
+    // Enumeration values for CaptureRequest#STATISTICS_FACE_DETECT_MODE
+    //
+
+    /**
+     * @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
+     */
+    public static final int STATISTICS_FACE_DETECT_MODE_OFF = 0;
+
+    /**
+     * <p>
+     * Optional Return rectangle and confidence
+     * only
+     * </p>
+     * @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
+     */
+    public static final int STATISTICS_FACE_DETECT_MODE_SIMPLE = 1;
+
+    /**
+     * <p>
+     * Optional Return all face
+     * metadata
+     * </p>
+     * @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
+     */
+    public static final int STATISTICS_FACE_DETECT_MODE_FULL = 2;
+
+    //
+    // Enumeration values for CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE
+    //
+
+    /**
+     * @see CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE
+     */
+    public static final int STATISTICS_LENS_SHADING_MAP_MODE_OFF = 0;
+
+    /**
+     * @see CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE
+     */
+    public static final int STATISTICS_LENS_SHADING_MAP_MODE_ON = 1;
+
+    //
+    // Enumeration values for CaptureRequest#TONEMAP_MODE
+    //
+
+    /**
+     * <p>
+     * Use the tone mapping curve specified in
+     * android.tonemap.curve
+     * </p>
+     * @see CaptureRequest#TONEMAP_MODE
+     */
+    public static final int TONEMAP_MODE_CONTRAST_CURVE = 0;
+
+    /**
+     * <p>
+     * Must not slow down frame rate relative to raw
+     * bayer output
+     * </p>
+     * @see CaptureRequest#TONEMAP_MODE
+     */
+    public static final int TONEMAP_MODE_FAST = 1;
+
+    /**
+     * <p>
+     * Frame rate may be reduced by high
+     * quality
+     * </p>
+     * @see CaptureRequest#TONEMAP_MODE
+     */
+    public static final int TONEMAP_MODE_HIGH_QUALITY = 2;
+
+    //
+    // Enumeration values for CaptureResult#CONTROL_AE_STATE
+    //
+
+    /**
+     * <p>
+     * AE is off.  When a camera device is opened, it starts in
+     * this state.
+     * </p>
+     * @see CaptureResult#CONTROL_AE_STATE
+     */
+    public static final int CONTROL_AE_STATE_INACTIVE = 0;
+
+    /**
+     * <p>
+     * AE doesn't yet have a good set of control values
+     * for the current scene
+     * </p>
+     * @see CaptureResult#CONTROL_AE_STATE
+     */
+    public static final int CONTROL_AE_STATE_SEARCHING = 1;
+
+    /**
+     * <p>
+     * AE has a good set of control values for the
+     * current scene
+     * </p>
+     * @see CaptureResult#CONTROL_AE_STATE
+     */
+    public static final int CONTROL_AE_STATE_CONVERGED = 2;
+
+    /**
+     * <p>
+     * AE has been locked (aeMode =
+     * LOCKED)
+     * </p>
+     * @see CaptureResult#CONTROL_AE_STATE
+     */
+    public static final int CONTROL_AE_STATE_LOCKED = 3;
+
+    /**
+     * <p>
+     * AE has a good set of control values, but flash
+     * needs to be fired for good quality still
+     * capture
+     * </p>
+     * @see CaptureResult#CONTROL_AE_STATE
+     */
+    public static final int CONTROL_AE_STATE_FLASH_REQUIRED = 4;
+
+    /**
+     * <p>
+     * AE has been asked to do a precapture sequence
+     * (through the
+     * trigger_action(CAMERA2_TRIGGER_PRECAPTURE_METERING)
+     * call), and is currently executing it. Once PRECAPTURE
+     * completes, AE will transition to CONVERGED or
+     * FLASH_REQUIRED as appropriate
+     * </p>
+     * @see CaptureResult#CONTROL_AE_STATE
+     */
+    public static final int CONTROL_AE_STATE_PRECAPTURE = 5;
+
+    //
+    // Enumeration values for CaptureResult#CONTROL_AF_STATE
+    //
+
+    /**
+     * <p>
+     * AF off or has not yet tried to scan/been asked
+     * to scan.  When a camera device is opened, it starts in
+     * this state.
+     * </p>
+     * @see CaptureResult#CONTROL_AF_STATE
+     */
+    public static final int CONTROL_AF_STATE_INACTIVE = 0;
+
+    /**
+     * <p>
+     * if CONTINUOUS_* modes are supported AF is
+     * currently doing an AF scan initiated by a continuous
+     * autofocus mode
+     * </p>
+     * @see CaptureResult#CONTROL_AF_STATE
+     */
+    public static final int CONTROL_AF_STATE_PASSIVE_SCAN = 1;
+
+    /**
+     * <p>
+     * if CONTINUOUS_* modes are supported AF currently
+     * believes it is in focus, but may restart scanning at
+     * any time.
+     * </p>
+     * @see CaptureResult#CONTROL_AF_STATE
+     */
+    public static final int CONTROL_AF_STATE_PASSIVE_FOCUSED = 2;
+
+    /**
+     * <p>
+     * if AUTO or MACRO modes are supported AF is doing
+     * an AF scan because it was triggered by AF
+     * trigger
+     * </p>
+     * @see CaptureResult#CONTROL_AF_STATE
+     */
+    public static final int CONTROL_AF_STATE_ACTIVE_SCAN = 3;
+
+    /**
+     * <p>
+     * if any AF mode besides OFF is supported AF
+     * believes it is focused correctly and is
+     * locked
+     * </p>
+     * @see CaptureResult#CONTROL_AF_STATE
+     */
+    public static final int CONTROL_AF_STATE_FOCUSED_LOCKED = 4;
+
+    /**
+     * <p>
+     * if any AF mode besides OFF is supported AF has
+     * failed to focus successfully and is
+     * locked
+     * </p>
+     * @see CaptureResult#CONTROL_AF_STATE
+     */
+    public static final int CONTROL_AF_STATE_NOT_FOCUSED_LOCKED = 5;
+
+    //
+    // Enumeration values for CaptureResult#CONTROL_AWB_STATE
+    //
+
+    /**
+     * <p>
+     * AWB is not in auto mode.  When a camera device is opened, it
+     * starts in this state.
+     * </p>
+     * @see CaptureResult#CONTROL_AWB_STATE
+     */
+    public static final int CONTROL_AWB_STATE_INACTIVE = 0;
+
+    /**
+     * <p>
+     * AWB doesn't yet have a good set of control
+     * values for the current scene
+     * </p>
+     * @see CaptureResult#CONTROL_AWB_STATE
+     */
+    public static final int CONTROL_AWB_STATE_SEARCHING = 1;
+
+    /**
+     * <p>
+     * AWB has a good set of control values for the
+     * current scene
+     * </p>
+     * @see CaptureResult#CONTROL_AWB_STATE
+     */
+    public static final int CONTROL_AWB_STATE_CONVERGED = 2;
+
+    /**
+     * <p>
+     * AE has been locked (aeMode =
+     * LOCKED)
+     * </p>
+     * @see CaptureResult#CONTROL_AWB_STATE
+     */
+    public static final int CONTROL_AWB_STATE_LOCKED = 3;
+
+    //
+    // Enumeration values for CaptureResult#FLASH_STATE
+    //
+
+    /**
+     * <p>
+     * No flash on camera
+     * </p>
+     * @see CaptureResult#FLASH_STATE
+     */
+    public static final int FLASH_STATE_UNAVAILABLE = 0;
+
+    /**
+     * <p>
+     * if android.flash.available is true Flash is
+     * charging and cannot be fired
+     * </p>
+     * @see CaptureResult#FLASH_STATE
+     */
+    public static final int FLASH_STATE_CHARGING = 1;
+
+    /**
+     * <p>
+     * if android.flash.available is true Flash is
+     * ready to fire
+     * </p>
+     * @see CaptureResult#FLASH_STATE
+     */
+    public static final int FLASH_STATE_READY = 2;
+
+    /**
+     * <p>
+     * if android.flash.available is true Flash fired
+     * for this capture
+     * </p>
+     * @see CaptureResult#FLASH_STATE
+     */
+    public static final int FLASH_STATE_FIRED = 3;
+
+    //
+    // Enumeration values for CaptureResult#LENS_STATE
+    //
+
+    /**
+     * @see CaptureResult#LENS_STATE
+     */
+    public static final int LENS_STATE_STATIONARY = 0;
+
+    /**
+     * @see CaptureResult#LENS_STATE
+     */
+    public static final int LENS_STATE_MOVING = 1;
+
+    //
+    // Enumeration values for CaptureResult#STATISTICS_SCENE_FLICKER
+    //
+
+    /**
+     * @see CaptureResult#STATISTICS_SCENE_FLICKER
+     */
+    public static final int STATISTICS_SCENE_FLICKER_NONE = 0;
+
+    /**
+     * @see CaptureResult#STATISTICS_SCENE_FLICKER
+     */
+    public static final int STATISTICS_SCENE_FLICKER_50HZ = 1;
+
+    /**
+     * @see CaptureResult#STATISTICS_SCENE_FLICKER
+     */
+    public static final int STATISTICS_SCENE_FLICKER_60HZ = 2;
+
+    /*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
+     * End generated code
+     *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
+
+}
diff --git a/core/java/android/hardware/camera2/CameraProperties.java b/core/java/android/hardware/camera2/CameraProperties.java
new file mode 100644
index 0000000..45c009f
--- /dev/null
+++ b/core/java/android/hardware/camera2/CameraProperties.java
@@ -0,0 +1,510 @@
+/*
+ * 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.hardware.camera2;
+
+import android.hardware.camera2.impl.CameraMetadataNative;
+
+/**
+ * <p>The properties describing a
+ * {@link CameraDevice CameraDevice}.</p>
+ *
+ * <p>These properties are fixed for a given CameraDevice, and can be queried
+ * through the {@link CameraManager CameraManager}
+ * interface in addition to through the CameraDevice interface.</p>
+ *
+ * @see CameraDevice
+ * @see CameraManager
+ */
+public final class CameraProperties extends CameraMetadata {
+
+    private final CameraMetadataNative mProperties;
+
+    /**
+     * Takes ownership of the passed-in properties object
+     * @hide
+     */
+    public CameraProperties(CameraMetadataNative properties) {
+        mProperties = properties;
+    }
+
+    @Override
+    public <T> T get(Key<T> key) {
+        return mProperties.get(key);
+    }
+
+    /*@O~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
+     * The key entries below this point are generated from metadata
+     * definitions in /system/media/camera/docs. Do not modify by hand or
+     * modify the comment blocks at the start or end.
+     *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~*/
+
+    /**
+     * <p>
+     * Which set of antibanding modes are
+     * supported
+     * </p>
+     */
+    public static final Key<byte[]> CONTROL_AE_AVAILABLE_ANTIBANDING_MODES =
+            new Key<byte[]>("android.control.aeAvailableAntibandingModes", byte[].class);
+
+    /**
+     * <p>
+     * List of frame rate ranges supported by the
+     * AE algorithm/hardware
+     * </p>
+     */
+    public static final Key<int[]> CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES =
+            new Key<int[]>("android.control.aeAvailableTargetFpsRanges", int[].class);
+
+    /**
+     * <p>
+     * Maximum and minimum exposure compensation
+     * setting, in counts of
+     * android.control.aeCompensationStepSize
+     * </p>
+     */
+    public static final Key<int[]> CONTROL_AE_COMPENSATION_RANGE =
+            new Key<int[]>("android.control.aeCompensationRange", int[].class);
+
+    /**
+     * <p>
+     * Smallest step by which exposure compensation
+     * can be changed
+     * </p>
+     */
+    public static final Key<Rational> CONTROL_AE_COMPENSATION_STEP =
+            new Key<Rational>("android.control.aeCompensationStep", Rational.class);
+
+    /**
+     * <p>
+     * List of AF modes that can be
+     * selected
+     * </p>
+     */
+    public static final Key<byte[]> CONTROL_AF_AVAILABLE_MODES =
+            new Key<byte[]>("android.control.afAvailableModes", byte[].class);
+
+    /**
+     * <p>
+     * what subset of the full color effect enum
+     * list is supported
+     * </p>
+     */
+    public static final Key<byte[]> CONTROL_AVAILABLE_EFFECTS =
+            new Key<byte[]>("android.control.availableEffects", byte[].class);
+
+    /**
+     * <p>
+     * what subset of the scene mode enum list is
+     * supported.
+     * </p>
+     */
+    public static final Key<byte[]> CONTROL_AVAILABLE_SCENE_MODES =
+            new Key<byte[]>("android.control.availableSceneModes", byte[].class);
+
+    /**
+     * <p>
+     * List of video stabilization modes that can
+     * be supported
+     * </p>
+     */
+    public static final Key<byte[]> CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES =
+            new Key<byte[]>("android.control.availableVideoStabilizationModes", byte[].class);
+
+    /**
+     */
+    public static final Key<byte[]> CONTROL_AWB_AVAILABLE_MODES =
+            new Key<byte[]>("android.control.awbAvailableModes", byte[].class);
+
+    /**
+     * <p>
+     * For AE, AWB, and AF, how many individual
+     * regions can be listed for metering?
+     * </p>
+     */
+    public static final Key<Integer> CONTROL_MAX_REGIONS =
+            new Key<Integer>("android.control.maxRegions", int.class);
+
+    /**
+     * <p>
+     * Whether this camera has a
+     * flash
+     * </p>
+     * <p>
+     * If no flash, none of the flash controls do
+     * anything. All other metadata should return 0
+     * </p>
+     */
+    public static final Key<Byte> FLASH_INFO_AVAILABLE =
+            new Key<Byte>("android.flash.info.available", byte.class);
+
+    /**
+     * <p>
+     * Supported resolutions for the JPEG
+     * thumbnail
+     * </p>
+     */
+    public static final Key<android.hardware.camera2.Size[]> JPEG_AVAILABLE_THUMBNAIL_SIZES =
+            new Key<android.hardware.camera2.Size[]>("android.jpeg.availableThumbnailSizes", android.hardware.camera2.Size[].class);
+
+    /**
+     * <p>
+     * List of supported aperture
+     * values
+     * </p>
+     * <p>
+     * If variable aperture not available, only setting
+     * should be for the fixed aperture
+     * </p>
+     */
+    public static final Key<float[]> LENS_INFO_AVAILABLE_APERTURES =
+            new Key<float[]>("android.lens.info.availableApertures", float[].class);
+
+    /**
+     * <p>
+     * List of supported ND filter
+     * values
+     * </p>
+     * <p>
+     * If not available, only setting is 0. Otherwise,
+     * lists the available exposure index values for dimming
+     * (2 would mean the filter is set to reduce incoming
+     * light by two stops)
+     * </p>
+     */
+    public static final Key<float[]> LENS_INFO_AVAILABLE_FILTER_DENSITIES =
+            new Key<float[]>("android.lens.info.availableFilterDensities", float[].class);
+
+    /**
+     * <p>
+     * If fitted with optical zoom, what focal
+     * lengths are available. If not, the static focal
+     * length
+     * </p>
+     * <p>
+     * If optical zoom not supported, only one value
+     * should be reported
+     * </p>
+     */
+    public static final Key<float[]> LENS_INFO_AVAILABLE_FOCAL_LENGTHS =
+            new Key<float[]>("android.lens.info.availableFocalLengths", float[].class);
+
+    /**
+     * <p>
+     * List of supported optical image
+     * stabilization modes
+     * </p>
+     */
+    public static final Key<byte[]> LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION =
+            new Key<byte[]>("android.lens.info.availableOpticalStabilization", byte[].class);
+
+    /**
+     * <p>
+     * Hyperfocal distance for this lens; set to
+     * 0 if fixed focus
+     * </p>
+     * <p>
+     * The hyperfocal distance is used for the old
+     * API's 'fixed' setting
+     * </p>
+     */
+    public static final Key<Float> LENS_INFO_HYPERFOCAL_DISTANCE =
+            new Key<Float>("android.lens.info.hyperfocalDistance", float.class);
+
+    /**
+     * <p>
+     * Shortest distance from frontmost surface
+     * of the lens that can be focused correctly
+     * </p>
+     * <p>
+     * If the lens is fixed-focus, this should be
+     * 0
+     * </p>
+     */
+    public static final Key<Float> LENS_INFO_MINIMUM_FOCUS_DISTANCE =
+            new Key<Float>("android.lens.info.minimumFocusDistance", float.class);
+
+    /**
+     * <p>
+     * Dimensions of lens shading
+     * map
+     * </p>
+     */
+    public static final Key<android.hardware.camera2.Size> LENS_INFO_SHADING_MAP_SIZE =
+            new Key<android.hardware.camera2.Size>("android.lens.info.shadingMapSize", android.hardware.camera2.Size.class);
+
+    /**
+     * <p>
+     * Direction the camera faces relative to
+     * device screen
+     * </p>
+     * @see #LENS_FACING_FRONT
+     * @see #LENS_FACING_BACK
+     */
+    public static final Key<Integer> LENS_FACING =
+            new Key<Integer>("android.lens.facing", int.class);
+
+    /**
+     * <p>
+     * How many output streams can be allocated at
+     * the same time for each type of stream
+     * </p>
+     * <p>
+     * Video snapshot with preview callbacks requires 3
+     * processed streams (preview, record, app callbacks) and
+     * one JPEG stream (snapshot)
+     * </p>
+     */
+    public static final Key<int[]> REQUEST_MAX_NUM_OUTPUT_STREAMS =
+            new Key<int[]>("android.request.maxNumOutputStreams", int[].class);
+
+    /**
+     * <p>
+     * List of app-visible formats
+     * </p>
+     */
+    public static final Key<int[]> SCALER_AVAILABLE_FORMATS =
+            new Key<int[]>("android.scaler.availableFormats", int[].class);
+
+    /**
+     * <p>
+     * The minimum frame duration that is supported
+     * for each resolution in availableJpegSizes. Should
+     * correspond to the frame duration when only that JPEG
+     * stream is active and captured in a burst, with all
+     * processing set to FAST
+     * </p>
+     * <p>
+     * When multiple streams are configured, the minimum
+     * frame duration will be >= max(individual stream min
+     * durations)
+     * </p>
+     */
+    public static final Key<long[]> SCALER_AVAILABLE_JPEG_MIN_DURATIONS =
+            new Key<long[]>("android.scaler.availableJpegMinDurations", long[].class);
+
+    /**
+     * <p>
+     * The resolutions available for output from
+     * the JPEG block. Listed as width x height
+     * </p>
+     */
+    public static final Key<android.hardware.camera2.Size[]> SCALER_AVAILABLE_JPEG_SIZES =
+            new Key<android.hardware.camera2.Size[]>("android.scaler.availableJpegSizes", android.hardware.camera2.Size[].class);
+
+    /**
+     * <p>
+     * The maximum ratio between active area width
+     * and crop region width, or between active area height and
+     * crop region height, if the crop region height is larger
+     * than width
+     * </p>
+     */
+    public static final Key<Float> SCALER_AVAILABLE_MAX_DIGITAL_ZOOM =
+            new Key<Float>("android.scaler.availableMaxDigitalZoom", float.class);
+
+    /**
+     * <p>
+     * The minimum frame duration that is supported
+     * for each resolution in availableProcessedSizes. Should
+     * correspond to the frame duration when only that processed
+     * stream is active, with all processing set to
+     * FAST
+     * </p>
+     * <p>
+     * When multiple streams are configured, the minimum
+     * frame duration will be >= max(individual stream min
+     * durations)
+     * </p>
+     */
+    public static final Key<long[]> SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS =
+            new Key<long[]>("android.scaler.availableProcessedMinDurations", long[].class);
+
+    /**
+     * <p>
+     * The resolutions available for use with
+     * processed output streams, such as YV12, NV12, and
+     * platform opaque YUV/RGB streams to the GPU or video
+     * encoders. Listed as width, height
+     * </p>
+     */
+    public static final Key<android.hardware.camera2.Size[]> SCALER_AVAILABLE_PROCESSED_SIZES =
+            new Key<android.hardware.camera2.Size[]>("android.scaler.availableProcessedSizes", android.hardware.camera2.Size[].class);
+
+    /**
+     * <p>
+     * Area of raw data which corresponds to only
+     * active pixels; smaller or equal to
+     * pixelArraySize.
+     * </p>
+     */
+    public static final Key<android.graphics.Rect> SENSOR_INFO_ACTIVE_ARRAY_SIZE =
+            new Key<android.graphics.Rect>("android.sensor.info.activeArraySize", android.graphics.Rect.class);
+
+    /**
+     * <p>
+     * Range of valid sensitivities
+     * </p>
+     */
+    public static final Key<int[]> SENSOR_INFO_SENSITIVITY_RANGE =
+            new Key<int[]>("android.sensor.info.sensitivityRange", int[].class);
+
+    /**
+     * <p>
+     * Range of valid exposure
+     * times
+     * </p>
+     */
+    public static final Key<long[]> SENSOR_INFO_EXPOSURE_TIME_RANGE =
+            new Key<long[]>("android.sensor.info.exposureTimeRange", long[].class);
+
+    /**
+     * <p>
+     * Maximum possible frame duration (minimum frame
+     * rate)
+     * </p>
+     * <p>
+     * Minimum duration is a function of resolution,
+     * processing settings. See
+     * android.scaler.availableProcessedMinDurations
+     * android.scaler.availableJpegMinDurations
+     * android.scaler.availableRawMinDurations
+     * </p>
+     */
+    public static final Key<Long> SENSOR_INFO_MAX_FRAME_DURATION =
+            new Key<Long>("android.sensor.info.maxFrameDuration", long.class);
+
+    /**
+     * <p>
+     * The physical dimensions of the full pixel
+     * array
+     * </p>
+     * <p>
+     * Needed for FOV calculation for old API
+     * </p>
+     */
+    public static final Key<float[]> SENSOR_INFO_PHYSICAL_SIZE =
+            new Key<float[]>("android.sensor.info.physicalSize", float[].class);
+
+    /**
+     * <p>
+     * Gain factor from electrons to raw units when
+     * ISO=100
+     * </p>
+     */
+    public static final Key<Rational> SENSOR_BASE_GAIN_FACTOR =
+            new Key<Rational>("android.sensor.baseGainFactor", Rational.class);
+
+    /**
+     * <p>
+     * Maximum sensitivity that is implemented
+     * purely through analog gain
+     * </p>
+     * <p>
+     * For android.sensor.sensitivity values less than or
+     * equal to this, all applied gain must be analog. For
+     * values above this, it can be a mix of analog and
+     * digital
+     * </p>
+     */
+    public static final Key<Integer> SENSOR_MAX_ANALOG_SENSITIVITY =
+            new Key<Integer>("android.sensor.maxAnalogSensitivity", int.class);
+
+    /**
+     * <p>
+     * Clockwise angle through which the output
+     * image needs to be rotated to be upright on the device
+     * screen in its native orientation. Also defines the
+     * direction of rolling shutter readout, which is from top
+     * to bottom in the sensor's coordinate system
+     * </p>
+     */
+    public static final Key<Integer> SENSOR_ORIENTATION =
+            new Key<Integer>("android.sensor.orientation", int.class);
+
+    /**
+     * <p>
+     * Which face detection modes are available,
+     * if any
+     * </p>
+     * <p>
+     * OFF means face detection is disabled, it must
+     * be included in the list.
+     * </p><p>
+     * SIMPLE means the device supports the
+     * android.statistics.faceRectangles and
+     * android.statistics.faceScores outputs.
+     * </p><p>
+     * FULL means the device additionally supports the
+     * android.statistics.faceIds and
+     * android.statistics.faceLandmarks outputs.
+     * </p>
+     */
+    public static final Key<byte[]> STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES =
+            new Key<byte[]>("android.statistics.info.availableFaceDetectModes", byte[].class);
+
+    /**
+     * <p>
+     * Maximum number of simultaneously detectable
+     * faces
+     * </p>
+     */
+    public static final Key<Integer> STATISTICS_INFO_MAX_FACE_COUNT =
+            new Key<Integer>("android.statistics.info.maxFaceCount", int.class);
+
+    /**
+     * <p>
+     * Maximum number of supported points in the
+     * tonemap curve
+     * </p>
+     */
+    public static final Key<Integer> TONEMAP_MAX_CURVE_POINTS =
+            new Key<Integer>("android.tonemap.maxCurvePoints", int.class);
+
+    /**
+     * <p>
+     * A list of camera LEDs that are available on this system.
+     * </p>
+     * @see #LED_AVAILABLE_LEDS_TRANSMIT
+     *
+     * @hide
+     */
+    public static final Key<int[]> LED_AVAILABLE_LEDS =
+            new Key<int[]>("android.led.availableLeds", int[].class);
+
+    /**
+     * <p>
+     * The camera 3 HAL device can implement one of two possible
+     * operational modes; limited and full. Full support is
+     * expected from new higher-end devices. Limited mode has
+     * hardware requirements roughly in line with those for a
+     * camera HAL device v1 implementation, and is expected from
+     * older or inexpensive devices. Full is a strict superset of
+     * limited, and they share the same essential operational flow.
+     * </p><p>
+     * For full details refer to "S3. Operational Modes" in camera3.h
+     * </p>
+     * @see #INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED
+     * @see #INFO_SUPPORTED_HARDWARE_LEVEL_FULL
+     */
+    public static final Key<Integer> INFO_SUPPORTED_HARDWARE_LEVEL =
+            new Key<Integer>("android.info.supportedHardwareLevel", int.class);
+
+    /*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
+     * End generated code
+     *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
+}
diff --git a/core/java/android/hardware/camera2/CaptureRequest.aidl b/core/java/android/hardware/camera2/CaptureRequest.aidl
new file mode 100644
index 0000000..0b7d5ba
--- /dev/null
+++ b/core/java/android/hardware/camera2/CaptureRequest.aidl
@@ -0,0 +1,20 @@
+/*
+ * 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.hardware.camera2;
+
+/** @hide */
+parcelable CaptureRequest;
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
new file mode 100644
index 0000000..4608ab9
--- /dev/null
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -0,0 +1,1088 @@
+/*
+ * 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.hardware.camera2;
+
+import android.hardware.camera2.impl.CameraMetadataNative;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.view.Surface;
+
+import java.util.HashSet;
+
+
+/**
+ * <p>An immutable package of settings and outputs needed to capture a single
+ * image from the camera device.</p>
+ *
+ * <p>Contains the configuration for the capture hardware (sensor, lens, flash),
+ * the processing pipeline, the control algorithms, and the output buffers. Also
+ * contains the list of target Surfaces to send image data to for this
+ * capture.</p>
+ *
+ * <p>CaptureRequests can be created by using a {@link Builder} instance,
+ * obtained by calling {@link CameraDevice#createCaptureRequest}</p>
+ *
+ * <p>CaptureRequests are given to {@link CameraDevice#capture} or
+ * {@link CameraDevice#setRepeatingRequest} to capture images from a camera.</p>
+ *
+ * <p>Each request can specify a different subset of target Surfaces for the
+ * camera to send the captured data to. All the surfaces used in a request must
+ * be part of the surface list given to the last call to
+ * {@link CameraDevice#configureOutputs}, when the request is submitted to the
+ * camera device.</p>
+ *
+ * <p>For example, a request meant for repeating preview might only include the
+ * Surface for the preview SurfaceView or SurfaceTexture, while a
+ * high-resolution still capture would also include a Surface from a ImageReader
+ * configured for high-resolution JPEG images.</p>
+ *
+ * @see CameraDevice#capture
+ * @see CameraDevice#setRepeatingRequest
+ * @see CameraDevice#createCaptureRequest
+ */
+public final class CaptureRequest extends CameraMetadata implements Parcelable {
+
+    private final HashSet<Surface> mSurfaceSet;
+    private final CameraMetadataNative mSettings;
+
+    private Object mUserTag;
+
+    /**
+     * Construct empty request
+     * @hide
+     */
+    public CaptureRequest() {
+        mSettings = new CameraMetadataNative();
+        mSurfaceSet = new HashSet<Surface>();
+    }
+
+    /**
+     * Clone from source capture request
+     */
+    private CaptureRequest(CaptureRequest source) {
+        mSettings = new CameraMetadataNative(source.mSettings);
+        mSurfaceSet = (HashSet<Surface>) source.mSurfaceSet.clone();
+    }
+
+    /**
+     * Take ownership of passed-in settings
+     */
+    private CaptureRequest(CameraMetadataNative settings) {
+        mSettings = settings;
+        mSurfaceSet = new HashSet<Surface>();
+    }
+
+    @Override
+    public <T> T get(Key<T> key) {
+        return mSettings.get(key);
+    }
+
+    /**
+     * Retrieve the tag for this request, if any.
+     *
+     * <p>This tag is not used for anything by the camera device, but can be
+     * used by an application to easily identify a CaptureRequest when it is
+     * returned by
+     * {@link CameraDevice.CaptureListener#onCaptureCompleted CaptureListener.onCaptureCompleted}
+     * </p>
+     *
+     * @return the last tag Object set on this request, or {@code null} if
+     *     no tag has been set.
+     * @see Builder#setTag
+     */
+    public Object getTag() {
+        return mUserTag;
+    }
+
+    public static final Parcelable.Creator<CaptureRequest> CREATOR =
+            new Parcelable.Creator<CaptureRequest>() {
+        @Override
+        public CaptureRequest createFromParcel(Parcel in) {
+            CaptureRequest request = new CaptureRequest();
+            request.readFromParcel(in);
+
+            return request;
+        }
+
+        @Override
+        public CaptureRequest[] newArray(int size) {
+            return new CaptureRequest[size];
+        }
+    };
+
+    /**
+     * Expand this object from a Parcel.
+     * Hidden since this breaks the immutability of CaptureRequest, but is
+     * needed to receive CaptureRequests with aidl.
+     *
+     * @param in The parcel from which the object should be read
+     * @hide
+     */
+    public void readFromParcel(Parcel in) {
+        mSettings.readFromParcel(in);
+
+        mSurfaceSet.clear();
+
+        Parcelable[] parcelableArray = in.readParcelableArray(Surface.class.getClassLoader());
+
+        if (parcelableArray == null) {
+            return;
+        }
+
+        for (Parcelable p : parcelableArray) {
+            Surface s = (Surface) p;
+            mSurfaceSet.add(s);
+        }
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        mSettings.writeToParcel(dest, flags);
+        dest.writeParcelableArray(mSurfaceSet.toArray(new Surface[mSurfaceSet.size()]), flags);
+    }
+
+    /**
+     * A builder for capture requests.
+     *
+     * <p>To obtain a builder instance, use the
+     * {@link CameraDevice#createCaptureRequest} method, which initializes the
+     * request fields to one of the templates defined in {@link CameraDevice}.
+     *
+     * @see CameraDevice#createCaptureRequest
+     * @see #TEMPLATE_PREVIEW
+     * @see #TEMPLATE_RECORD
+     * @see #TEMPLATE_STILL_CAPTURE
+     * @see #TEMPLATE_VIDEO_SNAPSHOT
+     * @see #TEMPLATE_MANUAL
+     */
+    public final static class Builder {
+
+        private CaptureRequest mRequest;
+
+        /**
+         * Initialize the builder using the template; the request takes
+         * ownership of the template.
+         *
+         * @hide
+         */
+        public Builder(CameraMetadataNative template) {
+            mRequest = new CaptureRequest(template);
+        }
+
+        /**
+         * <p>Add a surface to the list of targets for this request</p>
+         *
+         * <p>The Surface added must be one of the surfaces included in the most
+         * recent call to {@link CameraDevice#configureOutputs}, when the
+         * request is given to the camera device.</p>
+         *
+         * <p>Adding a target more than once has no effect.</p>
+         *
+         * @param outputTarget Surface to use as an output target for this request
+         */
+        public void addTarget(Surface outputTarget) {
+            mRequest.mSurfaceSet.add(outputTarget);
+        }
+
+        /**
+         * <p>Remove a surface from the list of targets for this request.</p>
+         *
+         * <p>Removing a target that is not currently added has no effect.</p>
+         *
+         * @param outputTarget Surface to use as an output target for this request
+         */
+        public void removeTarget(Surface outputTarget) {
+            mRequest.mSurfaceSet.remove(outputTarget);
+        }
+
+        /**
+         * Set a capture request field to a value. The field definitions can be
+         * found in {@link CaptureRequest}.
+         *
+         * @param key The metadata field to write.
+         * @param value The value to set the field to, which must be of a matching
+         * type to the key.
+         */
+        public <T> void set(Key<T> key, T value) {
+            mRequest.mSettings.set(key, value);
+        }
+
+        /**
+         * Get a capture request field value. The field definitions can be
+         * found in {@link CaptureRequest}.
+         *
+         * @throws IllegalArgumentException if the key was not valid
+         *
+         * @param key The metadata field to read.
+         * @return The value of that key, or {@code null} if the field is not set.
+         */
+        public <T> T get(Key<T> key) {
+            return mRequest.mSettings.get(key);
+        }
+
+        /**
+         * Set a tag for this request.
+         *
+         * <p>This tag is not used for anything by the camera device, but can be
+         * used by an application to easily identify a CaptureRequest when it is
+         * returned by
+         * {@link CameraDevice.CaptureListener#onCaptureCompleted CaptureListener.onCaptureCompleted}
+         *
+         * @param tag an arbitrary Object to store with this request
+         * @see CaptureRequest#getTag
+         */
+        public void setTag(Object tag) {
+            mRequest.mUserTag = tag;
+        }
+
+        /**
+         * Build a request using the current target Surfaces and settings.
+         *
+         * @return A new capture request instance, ready for submission to the
+         * camera device.
+         */
+        public CaptureRequest build() {
+            return new CaptureRequest(mRequest);
+        }
+
+
+        /**
+         * @hide
+         */
+        public boolean isEmpty() {
+            return mRequest.mSettings.isEmpty();
+        }
+
+    }
+
+    /*@O~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
+     * The key entries below this point are generated from metadata
+     * definitions in /system/media/camera/docs. Do not modify by hand or
+     * modify the comment blocks at the start or end.
+     *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~*/
+
+    /**
+     * <p>
+     * When android.control.awbMode is not OFF, TRANSFORM_MATRIX
+     * should be ignored.
+     * </p>
+     * @see #COLOR_CORRECTION_MODE_TRANSFORM_MATRIX
+     * @see #COLOR_CORRECTION_MODE_FAST
+     * @see #COLOR_CORRECTION_MODE_HIGH_QUALITY
+     */
+    public static final Key<Integer> COLOR_CORRECTION_MODE =
+            new Key<Integer>("android.colorCorrection.mode", int.class);
+
+    /**
+     * <p>
+     * A color transform matrix to use to transform
+     * from sensor RGB color space to output linear sRGB color space
+     * </p>
+     * <p>
+     * This matrix is either set by HAL when the request
+     * android.colorCorrection.mode is not TRANSFORM_MATRIX, or
+     * directly by the application in the request when the
+     * android.colorCorrection.mode is TRANSFORM_MATRIX.
+     * </p><p>
+     * In the latter case, the HAL may round the matrix to account
+     * for precision issues; the final rounded matrix should be
+     * reported back in this matrix result metadata.
+     * </p>
+     */
+    public static final Key<Rational[]> COLOR_CORRECTION_TRANSFORM =
+            new Key<Rational[]>("android.colorCorrection.transform", Rational[].class);
+
+    /**
+     * <p>
+     * Gains applying to Bayer color channels for
+     * white-balance
+     * </p>
+     * <p>
+     * The 4-channel white-balance gains are defined in
+     * the order of [R G_even G_odd B], where G_even is the gain
+     * for green pixels on even rows of the output, and G_odd
+     * is the gain for greenpixels on the odd rows. if a HAL
+     * does not support a separate gain for even/odd green channels,
+     * it should use the G_even value,and write G_odd equal to
+     * G_even in the output result metadata.
+     * </p><p>
+     * This array is either set by HAL when the request
+     * android.colorCorrection.mode is not TRANSFORM_MATRIX, or
+     * directly by the application in the request when the
+     * android.colorCorrection.mode is TRANSFORM_MATRIX.
+     * </p><p>
+     * The ouput should be the gains actually applied by the HAL to
+     * the current frame.
+     * </p>
+     */
+    public static final Key<float[]> COLOR_CORRECTION_GAINS =
+            new Key<float[]>("android.colorCorrection.gains", float[].class);
+
+    /**
+     * <p>
+     * Enum for controlling
+     * antibanding
+     * </p>
+     * @see #CONTROL_AE_ANTIBANDING_MODE_OFF
+     * @see #CONTROL_AE_ANTIBANDING_MODE_50HZ
+     * @see #CONTROL_AE_ANTIBANDING_MODE_60HZ
+     * @see #CONTROL_AE_ANTIBANDING_MODE_AUTO
+     */
+    public static final Key<Integer> CONTROL_AE_ANTIBANDING_MODE =
+            new Key<Integer>("android.control.aeAntibandingMode", int.class);
+
+    /**
+     * <p>
+     * Adjustment to AE target image
+     * brightness
+     * </p>
+     * <p>
+     * For example, if EV step is 0.333, '6' will mean an
+     * exposure compensation of +2 EV; -3 will mean an exposure
+     * compensation of -1
+     * </p>
+     */
+    public static final Key<Integer> CONTROL_AE_EXPOSURE_COMPENSATION =
+            new Key<Integer>("android.control.aeExposureCompensation", int.class);
+
+    /**
+     * <p>
+     * Whether AE is currently locked to its latest
+     * calculated values
+     * </p>
+     * <p>
+     * Note that even when AE is locked, the flash may be
+     * fired if the AE mode is ON_AUTO_FLASH / ON_ALWAYS_FLASH /
+     * ON_AUTO_FLASH_REDEYE.
+     * </p>
+     */
+    public static final Key<Boolean> CONTROL_AE_LOCK =
+            new Key<Boolean>("android.control.aeLock", boolean.class);
+
+    /**
+     * <p>
+     * Whether AE is currently updating the sensor
+     * exposure and sensitivity fields
+     * </p>
+     * <p>
+     * Only effective if android.control.mode =
+     * AUTO
+     * </p>
+     * @see #CONTROL_AE_MODE_OFF
+     * @see #CONTROL_AE_MODE_ON
+     * @see #CONTROL_AE_MODE_ON_AUTO_FLASH
+     * @see #CONTROL_AE_MODE_ON_ALWAYS_FLASH
+     * @see #CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE
+     */
+    public static final Key<Integer> CONTROL_AE_MODE =
+            new Key<Integer>("android.control.aeMode", int.class);
+
+    /**
+     * <p>
+     * List of areas to use for
+     * metering
+     * </p>
+     * <p>
+     * Each area is a rectangle plus weight: xmin, ymin,
+     * xmax, ymax, weight. The rectangle is defined inclusive of the
+     * specified coordinates.
+     * </p><p>
+     * The coordinate system is based on the active pixel array,
+     * with (0,0) being the top-left pixel in the active pixel array, and
+     * (android.sensor.info.activeArraySize.width - 1,
+     * android.sensor.info.activeArraySize.height - 1) being the
+     * bottom-right pixel in the active pixel array. The weight
+     * should be nonnegative.
+     * </p><p>
+     * If all regions have 0 weight, then no specific metering area
+     * needs to be used by the HAL. If the metering region is
+     * outside the current android.scaler.cropRegion, the HAL
+     * should ignore the sections outside the region and output the
+     * used sections in the frame metadata
+     * </p>
+     */
+    public static final Key<int[]> CONTROL_AE_REGIONS =
+            new Key<int[]>("android.control.aeRegions", int[].class);
+
+    /**
+     * <p>
+     * Range over which fps can be adjusted to
+     * maintain exposure
+     * </p>
+     * <p>
+     * Only constrains AE algorithm, not manual control
+     * of android.sensor.exposureTime
+     * </p>
+     */
+    public static final Key<int[]> CONTROL_AE_TARGET_FPS_RANGE =
+            new Key<int[]>("android.control.aeTargetFpsRange", int[].class);
+
+    /**
+     * <p>
+     * Whether the HAL must trigger precapture
+     * metering.
+     * </p>
+     * <p>
+     * This entry is normally set to IDLE, or is not
+     * included at all in the request settings. When included and
+     * set to START, the HAL must trigger the autoexposure
+     * precapture metering sequence.
+     * </p><p>
+     * The effect of AE precapture trigger depends on the current
+     * AE mode and state; see the camera HAL device v3 header for
+     * details.
+     * </p>
+     * @see #CONTROL_AE_PRECAPTURE_TRIGGER_IDLE
+     * @see #CONTROL_AE_PRECAPTURE_TRIGGER_START
+     */
+    public static final Key<Integer> CONTROL_AE_PRECAPTURE_TRIGGER =
+            new Key<Integer>("android.control.aePrecaptureTrigger", int.class);
+
+    /**
+     * <p>
+     * Whether AF is currently enabled, and what
+     * mode it is set to
+     * </p>
+     * @see #CONTROL_AF_MODE_OFF
+     * @see #CONTROL_AF_MODE_AUTO
+     * @see #CONTROL_AF_MODE_MACRO
+     * @see #CONTROL_AF_MODE_CONTINUOUS_VIDEO
+     * @see #CONTROL_AF_MODE_CONTINUOUS_PICTURE
+     * @see #CONTROL_AF_MODE_EDOF
+     */
+    public static final Key<Integer> CONTROL_AF_MODE =
+            new Key<Integer>("android.control.afMode", int.class);
+
+    /**
+     * <p>
+     * List of areas to use for focus
+     * estimation
+     * </p>
+     * <p>
+     * Each area is a rectangle plus weight: xmin, ymin,
+     * xmax, ymax, weight. The rectangle is defined inclusive of the
+     * specified coordinates.
+     * </p><p>
+     * The coordinate system is based on the active pixel array,
+     * with (0,0) being the top-left pixel in the active pixel array, and
+     * (android.sensor.info.activeArraySize.width - 1,
+     * android.sensor.info.activeArraySize.height - 1) being the
+     * bottom-right pixel in the active pixel array. The weight
+     * should be nonnegative.
+     * </p><p>
+     * If all regions have 0 weight, then no specific focus area
+     * needs to be used by the HAL. If the focusing region is
+     * outside the current android.scaler.cropRegion, the HAL
+     * should ignore the sections outside the region and output the
+     * used sections in the frame metadata
+     * </p>
+     */
+    public static final Key<int[]> CONTROL_AF_REGIONS =
+            new Key<int[]>("android.control.afRegions", int[].class);
+
+    /**
+     * <p>
+     * Whether the HAL must trigger autofocus.
+     * </p>
+     * <p>
+     * This entry is normally set to IDLE, or is not
+     * included at all in the request settings.
+     * </p><p>
+     * When included and set to START, the HAL must trigger the
+     * autofocus algorithm. The effect of AF trigger depends on the
+     * current AF mode and state; see the camera HAL device v3
+     * header for details. When set to CANCEL, the HAL must cancel
+     * any active trigger, and return to initial AF state.
+     * </p>
+     * @see #CONTROL_AF_TRIGGER_IDLE
+     * @see #CONTROL_AF_TRIGGER_START
+     * @see #CONTROL_AF_TRIGGER_CANCEL
+     */
+    public static final Key<Integer> CONTROL_AF_TRIGGER =
+            new Key<Integer>("android.control.afTrigger", int.class);
+
+    /**
+     * <p>
+     * Whether AWB is currently locked to its
+     * latest calculated values
+     * </p>
+     * <p>
+     * Note that AWB lock is only meaningful for AUTO
+     * mode; in other modes, AWB is already fixed to a specific
+     * setting
+     * </p>
+     */
+    public static final Key<Boolean> CONTROL_AWB_LOCK =
+            new Key<Boolean>("android.control.awbLock", boolean.class);
+
+    /**
+     * <p>
+     * Whether AWB is currently setting the color
+     * transform fields, and what its illumination target
+     * is
+     * </p>
+     * <p>
+     * [BC - AWB lock,AWB modes]
+     * </p>
+     * @see #CONTROL_AWB_MODE_OFF
+     * @see #CONTROL_AWB_MODE_AUTO
+     * @see #CONTROL_AWB_MODE_INCANDESCENT
+     * @see #CONTROL_AWB_MODE_FLUORESCENT
+     * @see #CONTROL_AWB_MODE_WARM_FLUORESCENT
+     * @see #CONTROL_AWB_MODE_DAYLIGHT
+     * @see #CONTROL_AWB_MODE_CLOUDY_DAYLIGHT
+     * @see #CONTROL_AWB_MODE_TWILIGHT
+     * @see #CONTROL_AWB_MODE_SHADE
+     */
+    public static final Key<Integer> CONTROL_AWB_MODE =
+            new Key<Integer>("android.control.awbMode", int.class);
+
+    /**
+     * <p>
+     * List of areas to use for illuminant
+     * estimation
+     * </p>
+     * <p>
+     * Only used in AUTO mode.
+     * </p><p>
+     * Each area is a rectangle plus weight: xmin, ymin,
+     * xmax, ymax, weight. The rectangle is defined inclusive of the
+     * specified coordinates.
+     * </p><p>
+     * The coordinate system is based on the active pixel array,
+     * with (0,0) being the top-left pixel in the active pixel array, and
+     * (android.sensor.info.activeArraySize.width - 1,
+     * android.sensor.info.activeArraySize.height - 1) being the
+     * bottom-right pixel in the active pixel array. The weight
+     * should be nonnegative.
+     * </p><p>
+     * If all regions have 0 weight, then no specific metering area
+     * needs to be used by the HAL. If the metering region is
+     * outside the current android.scaler.cropRegion, the HAL
+     * should ignore the sections outside the region and output the
+     * used sections in the frame metadata
+     * </p>
+     */
+    public static final Key<int[]> CONTROL_AWB_REGIONS =
+            new Key<int[]>("android.control.awbRegions", int[].class);
+
+    /**
+     * <p>
+     * Information to 3A routines about the purpose
+     * of this capture, to help decide optimal 3A
+     * strategy
+     * </p>
+     * <p>
+     * Only used if android.control.mode != OFF.
+     * </p>
+     * @see #CONTROL_CAPTURE_INTENT_CUSTOM
+     * @see #CONTROL_CAPTURE_INTENT_PREVIEW
+     * @see #CONTROL_CAPTURE_INTENT_STILL_CAPTURE
+     * @see #CONTROL_CAPTURE_INTENT_VIDEO_RECORD
+     * @see #CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT
+     * @see #CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG
+     */
+    public static final Key<Integer> CONTROL_CAPTURE_INTENT =
+            new Key<Integer>("android.control.captureIntent", int.class);
+
+    /**
+     * <p>
+     * Whether any special color effect is in use.
+     * Only used if android.control.mode != OFF
+     * </p>
+     * @see #CONTROL_EFFECT_MODE_OFF
+     * @see #CONTROL_EFFECT_MODE_MONO
+     * @see #CONTROL_EFFECT_MODE_NEGATIVE
+     * @see #CONTROL_EFFECT_MODE_SOLARIZE
+     * @see #CONTROL_EFFECT_MODE_SEPIA
+     * @see #CONTROL_EFFECT_MODE_POSTERIZE
+     * @see #CONTROL_EFFECT_MODE_WHITEBOARD
+     * @see #CONTROL_EFFECT_MODE_BLACKBOARD
+     * @see #CONTROL_EFFECT_MODE_AQUA
+     */
+    public static final Key<Integer> CONTROL_EFFECT_MODE =
+            new Key<Integer>("android.control.effectMode", int.class);
+
+    /**
+     * <p>
+     * Overall mode of 3A control
+     * routines
+     * </p>
+     * @see #CONTROL_MODE_OFF
+     * @see #CONTROL_MODE_AUTO
+     * @see #CONTROL_MODE_USE_SCENE_MODE
+     */
+    public static final Key<Integer> CONTROL_MODE =
+            new Key<Integer>("android.control.mode", int.class);
+
+    /**
+     * <p>
+     * Which scene mode is active when
+     * android.control.mode = SCENE_MODE
+     * </p>
+     * @see #CONTROL_SCENE_MODE_UNSUPPORTED
+     * @see #CONTROL_SCENE_MODE_FACE_PRIORITY
+     * @see #CONTROL_SCENE_MODE_ACTION
+     * @see #CONTROL_SCENE_MODE_PORTRAIT
+     * @see #CONTROL_SCENE_MODE_LANDSCAPE
+     * @see #CONTROL_SCENE_MODE_NIGHT
+     * @see #CONTROL_SCENE_MODE_NIGHT_PORTRAIT
+     * @see #CONTROL_SCENE_MODE_THEATRE
+     * @see #CONTROL_SCENE_MODE_BEACH
+     * @see #CONTROL_SCENE_MODE_SNOW
+     * @see #CONTROL_SCENE_MODE_SUNSET
+     * @see #CONTROL_SCENE_MODE_STEADYPHOTO
+     * @see #CONTROL_SCENE_MODE_FIREWORKS
+     * @see #CONTROL_SCENE_MODE_SPORTS
+     * @see #CONTROL_SCENE_MODE_PARTY
+     * @see #CONTROL_SCENE_MODE_CANDLELIGHT
+     * @see #CONTROL_SCENE_MODE_BARCODE
+     */
+    public static final Key<Integer> CONTROL_SCENE_MODE =
+            new Key<Integer>("android.control.sceneMode", int.class);
+
+    /**
+     * <p>
+     * Whether video stabilization is
+     * active
+     * </p>
+     * <p>
+     * If enabled, video stabilization can modify the
+     * android.scaler.cropRegion to keep the video stream
+     * stabilized
+     * </p>
+     */
+    public static final Key<Boolean> CONTROL_VIDEO_STABILIZATION_MODE =
+            new Key<Boolean>("android.control.videoStabilizationMode", boolean.class);
+
+    /**
+     * <p>
+     * Operation mode for edge
+     * enhancement
+     * </p>
+     * @see #EDGE_MODE_OFF
+     * @see #EDGE_MODE_FAST
+     * @see #EDGE_MODE_HIGH_QUALITY
+     */
+    public static final Key<Integer> EDGE_MODE =
+            new Key<Integer>("android.edge.mode", int.class);
+
+    /**
+     * <p>
+     * Select flash operation mode
+     * </p>
+     * @see #FLASH_MODE_OFF
+     * @see #FLASH_MODE_SINGLE
+     * @see #FLASH_MODE_TORCH
+     */
+    public static final Key<Integer> FLASH_MODE =
+            new Key<Integer>("android.flash.mode", int.class);
+
+    /**
+     * <p>
+     * GPS coordinates to include in output JPEG
+     * EXIF
+     * </p>
+     */
+    public static final Key<double[]> JPEG_GPS_COORDINATES =
+            new Key<double[]>("android.jpeg.gpsCoordinates", double[].class);
+
+    /**
+     * <p>
+     * 32 characters describing GPS algorithm to
+     * include in EXIF
+     * </p>
+     */
+    public static final Key<String> JPEG_GPS_PROCESSING_METHOD =
+            new Key<String>("android.jpeg.gpsProcessingMethod", String.class);
+
+    /**
+     * <p>
+     * Time GPS fix was made to include in
+     * EXIF
+     * </p>
+     */
+    public static final Key<Long> JPEG_GPS_TIMESTAMP =
+            new Key<Long>("android.jpeg.gpsTimestamp", long.class);
+
+    /**
+     * <p>
+     * Orientation of JPEG image to
+     * write
+     * </p>
+     */
+    public static final Key<Integer> JPEG_ORIENTATION =
+            new Key<Integer>("android.jpeg.orientation", int.class);
+
+    /**
+     * <p>
+     * Compression quality of the final JPEG
+     * image
+     * </p>
+     * <p>
+     * 85-95 is typical usage range
+     * </p>
+     */
+    public static final Key<Byte> JPEG_QUALITY =
+            new Key<Byte>("android.jpeg.quality", byte.class);
+
+    /**
+     * <p>
+     * Compression quality of JPEG
+     * thumbnail
+     * </p>
+     */
+    public static final Key<Byte> JPEG_THUMBNAIL_QUALITY =
+            new Key<Byte>("android.jpeg.thumbnailQuality", byte.class);
+
+    /**
+     * <p>
+     * Resolution of embedded JPEG
+     * thumbnail
+     * </p>
+     */
+    public static final Key<android.hardware.camera2.Size> JPEG_THUMBNAIL_SIZE =
+            new Key<android.hardware.camera2.Size>("android.jpeg.thumbnailSize", android.hardware.camera2.Size.class);
+
+    /**
+     * <p>
+     * Size of the lens aperture
+     * </p>
+     * <p>
+     * Will not be supported on most devices. Can only
+     * pick from supported list
+     * </p>
+     */
+    public static final Key<Float> LENS_APERTURE =
+            new Key<Float>("android.lens.aperture", float.class);
+
+    /**
+     * <p>
+     * State of lens neutral density
+     * filter(s)
+     * </p>
+     * <p>
+     * Will not be supported on most devices. Can only
+     * pick from supported list
+     * </p>
+     */
+    public static final Key<Float> LENS_FILTER_DENSITY =
+            new Key<Float>("android.lens.filterDensity", float.class);
+
+    /**
+     * <p>
+     * Lens optical zoom setting
+     * </p>
+     * <p>
+     * Will not be supported on most devices.
+     * </p>
+     */
+    public static final Key<Float> LENS_FOCAL_LENGTH =
+            new Key<Float>("android.lens.focalLength", float.class);
+
+    /**
+     * <p>
+     * Distance to plane of sharpest focus,
+     * measured from frontmost surface of the lens
+     * </p>
+     * <p>
+     * 0 = infinity focus. Used value should be clamped
+     * to (0,minimum focus distance)
+     * </p>
+     */
+    public static final Key<Float> LENS_FOCUS_DISTANCE =
+            new Key<Float>("android.lens.focusDistance", float.class);
+
+    /**
+     * <p>
+     * Whether optical image stabilization is
+     * enabled.
+     * </p>
+     * <p>
+     * Will not be supported on most devices.
+     * </p>
+     * @see #LENS_OPTICAL_STABILIZATION_MODE_OFF
+     * @see #LENS_OPTICAL_STABILIZATION_MODE_ON
+     */
+    public static final Key<Integer> LENS_OPTICAL_STABILIZATION_MODE =
+            new Key<Integer>("android.lens.opticalStabilizationMode", int.class);
+
+    /**
+     * <p>
+     * Mode of operation for the noise reduction
+     * algorithm
+     * </p>
+     * @see #NOISE_REDUCTION_MODE_OFF
+     * @see #NOISE_REDUCTION_MODE_FAST
+     * @see #NOISE_REDUCTION_MODE_HIGH_QUALITY
+     */
+    public static final Key<Integer> NOISE_REDUCTION_MODE =
+            new Key<Integer>("android.noiseReduction.mode", int.class);
+
+    /**
+     * <p>
+     * An application-specified ID for the current
+     * request. Must be maintained unchanged in output
+     * frame
+     * </p>
+     *
+     * @hide
+     */
+    public static final Key<Integer> REQUEST_ID =
+            new Key<Integer>("android.request.id", int.class);
+
+    /**
+     * <p>
+     * (x, y, width, height).
+     * </p><p>
+     * A rectangle with the top-level corner of (x,y) and size
+     * (width, height). The region of the sensor that is used for
+     * output. Each stream must use this rectangle to produce its
+     * output, cropping to a smaller region if necessary to
+     * maintain the stream's aspect ratio.
+     * </p><p>
+     * HAL2.x uses only (x, y, width)
+     * </p>
+     * <p>
+     * Any additional per-stream cropping must be done to
+     * maximize the final pixel area of the stream.
+     * </p><p>
+     * For example, if the crop region is set to a 4:3 aspect
+     * ratio, then 4:3 streams should use the exact crop
+     * region. 16:9 streams should further crop vertically
+     * (letterbox).
+     * </p><p>
+     * Conversely, if the crop region is set to a 16:9, then 4:3
+     * outputs should crop horizontally (pillarbox), and 16:9
+     * streams should match exactly. These additional crops must
+     * be centered within the crop region.
+     * </p><p>
+     * The output streams must maintain square pixels at all
+     * times, no matter what the relative aspect ratios of the
+     * crop region and the stream are.  Negative values for
+     * corner are allowed for raw output if full pixel array is
+     * larger than active pixel array. Width and height may be
+     * rounded to nearest larger supportable width, especially
+     * for raw output, where only a few fixed scales may be
+     * possible. The width and height of the crop region cannot
+     * be set to be smaller than floor( activeArraySize.width /
+     * android.scaler.maxDigitalZoom ) and floor(
+     * activeArraySize.height / android.scaler.maxDigitalZoom),
+     * respectively.
+     * </p>
+     */
+    public static final Key<android.graphics.Rect> SCALER_CROP_REGION =
+            new Key<android.graphics.Rect>("android.scaler.cropRegion", android.graphics.Rect.class);
+
+    /**
+     * <p>
+     * Duration each pixel is exposed to
+     * light.
+     * </p><p>
+     * If the sensor can't expose this exact duration, it should shorten the
+     * duration exposed to the nearest possible value (rather than expose longer).
+     * </p>
+     * <p>
+     * 1/10000 - 30 sec range. No bulb mode
+     * </p>
+     */
+    public static final Key<Long> SENSOR_EXPOSURE_TIME =
+            new Key<Long>("android.sensor.exposureTime", long.class);
+
+    /**
+     * <p>
+     * Duration from start of frame exposure to
+     * start of next frame exposure
+     * </p>
+     * <p>
+     * Exposure time has priority, so duration is set to
+     * max(duration, exposure time + overhead)
+     * </p>
+     */
+    public static final Key<Long> SENSOR_FRAME_DURATION =
+            new Key<Long>("android.sensor.frameDuration", long.class);
+
+    /**
+     * <p>
+     * Gain applied to image data. Must be
+     * implemented through analog gain only if set to values
+     * below 'maximum analog sensitivity'.
+     * </p><p>
+     * If the sensor can't apply this exact gain, it should lessen the
+     * gain to the nearest possible value (rather than gain more).
+     * </p>
+     * <p>
+     * ISO 12232:2006 REI method
+     * </p>
+     */
+    public static final Key<Integer> SENSOR_SENSITIVITY =
+            new Key<Integer>("android.sensor.sensitivity", int.class);
+
+    /**
+     * <p>
+     * State of the face detector
+     * unit
+     * </p>
+     * <p>
+     * Whether face detection is enabled, and whether it
+     * should output just the basic fields or the full set of
+     * fields. Value must be one of the
+     * android.statistics.info.availableFaceDetectModes.
+     * </p>
+     * @see #STATISTICS_FACE_DETECT_MODE_OFF
+     * @see #STATISTICS_FACE_DETECT_MODE_SIMPLE
+     * @see #STATISTICS_FACE_DETECT_MODE_FULL
+     */
+    public static final Key<Integer> STATISTICS_FACE_DETECT_MODE =
+            new Key<Integer>("android.statistics.faceDetectMode", int.class);
+
+    /**
+     * <p>
+     * Whether the HAL needs to output the lens
+     * shading map in output result metadata
+     * </p>
+     * <p>
+     * When set to ON,
+     * android.statistics.lensShadingMap must be provided in
+     * the output result metdata.
+     * </p>
+     * @see #STATISTICS_LENS_SHADING_MAP_MODE_OFF
+     * @see #STATISTICS_LENS_SHADING_MAP_MODE_ON
+     */
+    public static final Key<Integer> STATISTICS_LENS_SHADING_MAP_MODE =
+            new Key<Integer>("android.statistics.lensShadingMapMode", int.class);
+
+    /**
+     * <p>
+     * Table mapping blue input values to output
+     * values
+     * </p>
+     * <p>
+     * Tonemapping / contrast / gamma curve for the blue
+     * channel, to use when android.tonemap.mode is CONTRAST_CURVE.
+     * </p><p>
+     * See android.tonemap.curveRed for more details.
+     * </p>
+     */
+    public static final Key<float[]> TONEMAP_CURVE_BLUE =
+            new Key<float[]>("android.tonemap.curveBlue", float[].class);
+
+    /**
+     * <p>
+     * Table mapping green input values to output
+     * values
+     * </p>
+     * <p>
+     * Tonemapping / contrast / gamma curve for the green
+     * channel, to use when android.tonemap.mode is CONTRAST_CURVE.
+     * </p><p>
+     * See android.tonemap.curveRed for more details.
+     * </p>
+     */
+    public static final Key<float[]> TONEMAP_CURVE_GREEN =
+            new Key<float[]>("android.tonemap.curveGreen", float[].class);
+
+    /**
+     * <p>
+     * Table mapping red input values to output
+     * values
+     * </p>
+     * <p>
+     * Tonemapping / contrast / gamma curve for the red
+     * channel, to use when android.tonemap.mode is CONTRAST_CURVE.
+     * </p><p>
+     * Since the input and output ranges may vary depending on
+     * the camera pipeline, the input and output pixel values
+     * are represented by normalized floating-point values
+     * between 0 and 1, with 0 == black and 1 == white.
+     * </p><p>
+     * The curve should be linearly interpolated between the
+     * defined points. The points will be listed in increasing
+     * order of P_IN. For example, if the array is: [0.0, 0.0,
+     * 0.3, 0.5, 1.0, 1.0], then the input->output mapping
+     * for a few sample points would be: 0 -> 0, 0.15 ->
+     * 0.25, 0.3 -> 0.5, 0.5 -> 0.64
+     * </p>
+     */
+    public static final Key<float[]> TONEMAP_CURVE_RED =
+            new Key<float[]>("android.tonemap.curveRed", float[].class);
+
+    /**
+     * @see #TONEMAP_MODE_CONTRAST_CURVE
+     * @see #TONEMAP_MODE_FAST
+     * @see #TONEMAP_MODE_HIGH_QUALITY
+     */
+    public static final Key<Integer> TONEMAP_MODE =
+            new Key<Integer>("android.tonemap.mode", int.class);
+
+    /**
+     * <p>
+     * This LED is nominally used to indicate to the user
+     * that the camera is powered on and may be streaming images back to the
+     * Application Processor. In certain rare circumstances, the OS may
+     * disable this when video is processed locally and not transmitted to
+     * any untrusted applications.
+     * </p><p>
+     * In particular, the LED *must* always be on when the data could be
+     * transmitted off the device. The LED *should* always be on whenever
+     * data is stored locally on the device.
+     * </p><p>
+     * The LED *may* be off if a trusted application is using the data that
+     * doesn't violate the above rules.
+     * </p>
+     *
+     * @hide
+     */
+    public static final Key<Boolean> LED_TRANSMIT =
+            new Key<Boolean>("android.led.transmit", boolean.class);
+
+    /**
+     * <p>
+     * Whether black-level compensation is locked
+     * to its current values, or is free to vary
+     * </p>
+     * <p>
+     * When set to ON, the values used for black-level
+     * compensation must not change until the lock is set to
+     * OFF
+     * </p><p>
+     * Since changes to certain capture parameters (such as
+     * exposure time) may require resetting of black level
+     * compensation, the HAL must report whether setting the
+     * black level lock was successful in the output result
+     * metadata.
+     * </p><p>
+     * The black level locking must happen at the sensor, and not at the ISP.
+     * If for some reason black level locking is no longer legal (for example,
+     * the analog gain has changed, which forces black levels to be
+     * recalculated), then the HAL is free to override this request (and it
+     * must report 'OFF' when this does happen) until the next time locking
+     * is legal again.
+     * </p>
+     */
+    public static final Key<Boolean> BLACK_LEVEL_LOCK =
+            new Key<Boolean>("android.blackLevel.lock", boolean.class);
+
+    /*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
+     * End generated code
+     *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
+}
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
new file mode 100644
index 0000000..3fcd2f9
--- /dev/null
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -0,0 +1,1006 @@
+/*
+ * 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.hardware.camera2;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.hardware.camera2.impl.CameraMetadataNative;
+
+/**
+ * <p>The results of a single image capture from the image sensor.</p>
+ *
+ * <p>Contains the final configuration for the capture hardware (sensor, lens,
+ * flash), the processing pipeline, the control algorithms, and the output
+ * buffers.</p>
+ *
+ * <p>CaptureResults are produced by a {@link CameraDevice} after processing a
+ * {@link CaptureRequest}. All properties listed for capture requests can also
+ * be queried on the capture result, to determine the final values used for
+ * capture. The result also includes additional metadata about the state of the
+ * camera device during the capture.</p>
+ *
+ */
+public final class CaptureResult extends CameraMetadata {
+
+    private final CameraMetadataNative mResults;
+
+    /**
+     * Takes ownership of the passed-in properties object
+     * @hide
+     */
+    public CaptureResult(CameraMetadataNative results) {
+        mResults = results;
+    }
+
+    @Override
+    public <T> T get(Key<T> key) {
+        return mResults.get(key);
+    }
+
+    /**
+     * Describes a face detected in an image.
+     */
+    public static class Face {
+
+        /**
+         * <p>Bounds of the face. A rectangle relative to the sensor's
+         * {@link CameraProperties#SENSOR_INFO_ACTIVE_ARRAY_SIZE}, with (0,0)
+         * representing the top-left corner of the active array rectangle.</p>
+         */
+        public Rect getBounds() {
+            return mBounds;
+        }
+
+        /** <p>The confidence level for the detection of the face. The range is 1 to
+         * 100. 100 is the highest confidence.</p>
+         *
+         * <p>Depending on the device, even very low-confidence faces may be
+         * listed, so applications should filter out faces with low confidence,
+         * depending on the use case. For a typical point-and-shoot camera
+         * application that wishes to display rectangles around detected faces,
+         * filtering out faces with confidence less than 50 is recommended.</p>
+         *
+         */
+        public int getScore() {
+            return mScore;
+        }
+
+        /**
+         * An unique id per face while the face is visible to the tracker. If
+         * the face leaves the field-of-view and comes back, it will get a new
+         * id. This is an optional field, may not be supported on all devices.
+         * If not supported, id will always be set to -1. The optional fields
+         * are supported as a set. Either they are all valid, or none of them
+         * are.
+         */
+        public int getId() {
+            return mId;
+        }
+
+        /**
+         * The coordinates of the center of the left eye. The coordinates are in
+         * the same space as the ones for {@link #getBounds}. This is an
+         * optional field, may not be supported on all devices. If not
+         * supported, the value will always be set to null. The optional fields
+         * are supported as a set. Either they are all valid, or none of them
+         * are.
+         */
+        public Point getLeftEye() {
+            return mLeftEye;
+        }
+
+        /**
+         * The coordinates of the center of the right eye. The coordinates are
+         * in the same space as the ones for {@link #getBounds}.This is an
+         * optional field, may not be supported on all devices. If not
+         * supported, the value will always be set to null. The optional fields
+         * are supported as a set. Either they are all valid, or none of them
+         * are.
+         */
+        public Point getRightEye() {
+            return mRightEye;
+        }
+
+        /**
+         * The coordinates of the center of the mouth.  The coordinates are in
+         * the same space as the ones for {@link #getBounds}. This is an optional
+         * field, may not be supported on all devices. If not supported, the
+         * value will always be set to null. The optional fields are supported
+         * as a set. Either they are all valid, or none of them are.
+         */
+        public Point getMouth() {
+            return mMouth;
+        }
+
+        private Rect mBounds;
+        private int mScore;
+        private int mId;
+        private Point mLeftEye;
+        private Point mRightEye;
+        private Point mMouth;
+    }
+
+    /*@O~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
+     * The key entries below this point are generated from metadata
+     * definitions in /system/media/camera/docs. Do not modify by hand or
+     * modify the comment blocks at the start or end.
+     *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~*/
+
+    /**
+     * <p>
+     * A color transform matrix to use to transform
+     * from sensor RGB color space to output linear sRGB color space
+     * </p>
+     * <p>
+     * This matrix is either set by HAL when the request
+     * android.colorCorrection.mode is not TRANSFORM_MATRIX, or
+     * directly by the application in the request when the
+     * android.colorCorrection.mode is TRANSFORM_MATRIX.
+     * </p><p>
+     * In the latter case, the HAL may round the matrix to account
+     * for precision issues; the final rounded matrix should be
+     * reported back in this matrix result metadata.
+     * </p>
+     */
+    public static final Key<Rational[]> COLOR_CORRECTION_TRANSFORM =
+            new Key<Rational[]>("android.colorCorrection.transform", Rational[].class);
+
+    /**
+     * <p>
+     * Gains applying to Bayer color channels for
+     * white-balance
+     * </p>
+     * <p>
+     * The 4-channel white-balance gains are defined in
+     * the order of [R G_even G_odd B], where G_even is the gain
+     * for green pixels on even rows of the output, and G_odd
+     * is the gain for greenpixels on the odd rows. if a HAL
+     * does not support a separate gain for even/odd green channels,
+     * it should use the G_even value,and write G_odd equal to
+     * G_even in the output result metadata.
+     * </p><p>
+     * This array is either set by HAL when the request
+     * android.colorCorrection.mode is not TRANSFORM_MATRIX, or
+     * directly by the application in the request when the
+     * android.colorCorrection.mode is TRANSFORM_MATRIX.
+     * </p><p>
+     * The ouput should be the gains actually applied by the HAL to
+     * the current frame.
+     * </p>
+     */
+    public static final Key<float[]> COLOR_CORRECTION_GAINS =
+            new Key<float[]>("android.colorCorrection.gains", float[].class);
+
+    /**
+     * <p>
+     * The ID sent with the latest
+     * CAMERA2_TRIGGER_PRECAPTURE_METERING call
+     * </p>
+     * <p>
+     * Must be 0 if no
+     * CAMERA2_TRIGGER_PRECAPTURE_METERING trigger received yet
+     * by HAL. Always updated even if AE algorithm ignores the
+     * trigger
+     * </p>
+     *
+     * @hide
+     */
+    public static final Key<Integer> CONTROL_AE_PRECAPTURE_ID =
+            new Key<Integer>("android.control.aePrecaptureId", int.class);
+
+    /**
+     * <p>
+     * List of areas to use for
+     * metering
+     * </p>
+     * <p>
+     * Each area is a rectangle plus weight: xmin, ymin,
+     * xmax, ymax, weight. The rectangle is defined inclusive of the
+     * specified coordinates.
+     * </p><p>
+     * The coordinate system is based on the active pixel array,
+     * with (0,0) being the top-left pixel in the active pixel array, and
+     * (android.sensor.info.activeArraySize.width - 1,
+     * android.sensor.info.activeArraySize.height - 1) being the
+     * bottom-right pixel in the active pixel array. The weight
+     * should be nonnegative.
+     * </p><p>
+     * If all regions have 0 weight, then no specific metering area
+     * needs to be used by the HAL. If the metering region is
+     * outside the current android.scaler.cropRegion, the HAL
+     * should ignore the sections outside the region and output the
+     * used sections in the frame metadata
+     * </p>
+     */
+    public static final Key<int[]> CONTROL_AE_REGIONS =
+            new Key<int[]>("android.control.aeRegions", int[].class);
+
+    /**
+     * <p>
+     * Current state of AE algorithm
+     * </p>
+     * <p>
+     * Whenever the AE algorithm state changes, a
+     * MSG_AUTOEXPOSURE notification must be send if a
+     * notification callback is registered.
+     * </p>
+     * @see #CONTROL_AE_STATE_INACTIVE
+     * @see #CONTROL_AE_STATE_SEARCHING
+     * @see #CONTROL_AE_STATE_CONVERGED
+     * @see #CONTROL_AE_STATE_LOCKED
+     * @see #CONTROL_AE_STATE_FLASH_REQUIRED
+     * @see #CONTROL_AE_STATE_PRECAPTURE
+     */
+    public static final Key<Integer> CONTROL_AE_STATE =
+            new Key<Integer>("android.control.aeState", int.class);
+
+    /**
+     * <p>
+     * Whether AF is currently enabled, and what
+     * mode it is set to
+     * </p>
+     * @see #CONTROL_AF_MODE_OFF
+     * @see #CONTROL_AF_MODE_AUTO
+     * @see #CONTROL_AF_MODE_MACRO
+     * @see #CONTROL_AF_MODE_CONTINUOUS_VIDEO
+     * @see #CONTROL_AF_MODE_CONTINUOUS_PICTURE
+     * @see #CONTROL_AF_MODE_EDOF
+     */
+    public static final Key<Integer> CONTROL_AF_MODE =
+            new Key<Integer>("android.control.afMode", int.class);
+
+    /**
+     * <p>
+     * List of areas to use for focus
+     * estimation
+     * </p>
+     * <p>
+     * Each area is a rectangle plus weight: xmin, ymin,
+     * xmax, ymax, weight. The rectangle is defined inclusive of the
+     * specified coordinates.
+     * </p><p>
+     * The coordinate system is based on the active pixel array,
+     * with (0,0) being the top-left pixel in the active pixel array, and
+     * (android.sensor.info.activeArraySize.width - 1,
+     * android.sensor.info.activeArraySize.height - 1) being the
+     * bottom-right pixel in the active pixel array. The weight
+     * should be nonnegative.
+     * </p><p>
+     * If all regions have 0 weight, then no specific focus area
+     * needs to be used by the HAL. If the focusing region is
+     * outside the current android.scaler.cropRegion, the HAL
+     * should ignore the sections outside the region and output the
+     * used sections in the frame metadata
+     * </p>
+     */
+    public static final Key<int[]> CONTROL_AF_REGIONS =
+            new Key<int[]>("android.control.afRegions", int[].class);
+
+    /**
+     * <p>
+     * Current state of AF algorithm
+     * </p>
+     * <p>
+     * Whenever the AF algorithm state changes, a
+     * MSG_AUTOFOCUS notification must be send if a notification
+     * callback is registered.
+     * </p>
+     * @see #CONTROL_AF_STATE_INACTIVE
+     * @see #CONTROL_AF_STATE_PASSIVE_SCAN
+     * @see #CONTROL_AF_STATE_PASSIVE_FOCUSED
+     * @see #CONTROL_AF_STATE_ACTIVE_SCAN
+     * @see #CONTROL_AF_STATE_FOCUSED_LOCKED
+     * @see #CONTROL_AF_STATE_NOT_FOCUSED_LOCKED
+     */
+    public static final Key<Integer> CONTROL_AF_STATE =
+            new Key<Integer>("android.control.afState", int.class);
+
+    /**
+     * <p>
+     * The ID sent with the latest
+     * CAMERA2_TRIGGER_AUTOFOCUS call
+     * </p>
+     * <p>
+     * Must be 0 if no CAMERA2_TRIGGER_AUTOFOCUS trigger
+     * received yet by HAL. Always updated even if AF algorithm
+     * ignores the trigger
+     * </p>
+     *
+     * @hide
+     */
+    public static final Key<Integer> CONTROL_AF_TRIGGER_ID =
+            new Key<Integer>("android.control.afTriggerId", int.class);
+
+    /**
+     * <p>
+     * Whether AWB is currently setting the color
+     * transform fields, and what its illumination target
+     * is
+     * </p>
+     * <p>
+     * [BC - AWB lock,AWB modes]
+     * </p>
+     * @see #CONTROL_AWB_MODE_OFF
+     * @see #CONTROL_AWB_MODE_AUTO
+     * @see #CONTROL_AWB_MODE_INCANDESCENT
+     * @see #CONTROL_AWB_MODE_FLUORESCENT
+     * @see #CONTROL_AWB_MODE_WARM_FLUORESCENT
+     * @see #CONTROL_AWB_MODE_DAYLIGHT
+     * @see #CONTROL_AWB_MODE_CLOUDY_DAYLIGHT
+     * @see #CONTROL_AWB_MODE_TWILIGHT
+     * @see #CONTROL_AWB_MODE_SHADE
+     */
+    public static final Key<Integer> CONTROL_AWB_MODE =
+            new Key<Integer>("android.control.awbMode", int.class);
+
+    /**
+     * <p>
+     * List of areas to use for illuminant
+     * estimation
+     * </p>
+     * <p>
+     * Only used in AUTO mode.
+     * </p><p>
+     * Each area is a rectangle plus weight: xmin, ymin,
+     * xmax, ymax, weight. The rectangle is defined inclusive of the
+     * specified coordinates.
+     * </p><p>
+     * The coordinate system is based on the active pixel array,
+     * with (0,0) being the top-left pixel in the active pixel array, and
+     * (android.sensor.info.activeArraySize.width - 1,
+     * android.sensor.info.activeArraySize.height - 1) being the
+     * bottom-right pixel in the active pixel array. The weight
+     * should be nonnegative.
+     * </p><p>
+     * If all regions have 0 weight, then no specific metering area
+     * needs to be used by the HAL. If the metering region is
+     * outside the current android.scaler.cropRegion, the HAL
+     * should ignore the sections outside the region and output the
+     * used sections in the frame metadata
+     * </p>
+     */
+    public static final Key<int[]> CONTROL_AWB_REGIONS =
+            new Key<int[]>("android.control.awbRegions", int[].class);
+
+    /**
+     * <p>
+     * Current state of AWB algorithm
+     * </p>
+     * <p>
+     * Whenever the AWB algorithm state changes, a
+     * MSG_AUTOWHITEBALANCE notification must be send if a
+     * notification callback is registered.
+     * </p>
+     * @see #CONTROL_AWB_STATE_INACTIVE
+     * @see #CONTROL_AWB_STATE_SEARCHING
+     * @see #CONTROL_AWB_STATE_CONVERGED
+     * @see #CONTROL_AWB_STATE_LOCKED
+     */
+    public static final Key<Integer> CONTROL_AWB_STATE =
+            new Key<Integer>("android.control.awbState", int.class);
+
+    /**
+     * <p>
+     * Overall mode of 3A control
+     * routines
+     * </p>
+     * @see #CONTROL_MODE_OFF
+     * @see #CONTROL_MODE_AUTO
+     * @see #CONTROL_MODE_USE_SCENE_MODE
+     */
+    public static final Key<Integer> CONTROL_MODE =
+            new Key<Integer>("android.control.mode", int.class);
+
+    /**
+     * <p>
+     * Operation mode for edge
+     * enhancement
+     * </p>
+     * @see #EDGE_MODE_OFF
+     * @see #EDGE_MODE_FAST
+     * @see #EDGE_MODE_HIGH_QUALITY
+     */
+    public static final Key<Integer> EDGE_MODE =
+            new Key<Integer>("android.edge.mode", int.class);
+
+    /**
+     * <p>
+     * Select flash operation mode
+     * </p>
+     * @see #FLASH_MODE_OFF
+     * @see #FLASH_MODE_SINGLE
+     * @see #FLASH_MODE_TORCH
+     */
+    public static final Key<Integer> FLASH_MODE =
+            new Key<Integer>("android.flash.mode", int.class);
+
+    /**
+     * <p>
+     * Current state of the flash
+     * unit
+     * </p>
+     * @see #FLASH_STATE_UNAVAILABLE
+     * @see #FLASH_STATE_CHARGING
+     * @see #FLASH_STATE_READY
+     * @see #FLASH_STATE_FIRED
+     */
+    public static final Key<Integer> FLASH_STATE =
+            new Key<Integer>("android.flash.state", int.class);
+
+    /**
+     * <p>
+     * GPS coordinates to include in output JPEG
+     * EXIF
+     * </p>
+     */
+    public static final Key<double[]> JPEG_GPS_COORDINATES =
+            new Key<double[]>("android.jpeg.gpsCoordinates", double[].class);
+
+    /**
+     * <p>
+     * 32 characters describing GPS algorithm to
+     * include in EXIF
+     * </p>
+     */
+    public static final Key<String> JPEG_GPS_PROCESSING_METHOD =
+            new Key<String>("android.jpeg.gpsProcessingMethod", String.class);
+
+    /**
+     * <p>
+     * Time GPS fix was made to include in
+     * EXIF
+     * </p>
+     */
+    public static final Key<Long> JPEG_GPS_TIMESTAMP =
+            new Key<Long>("android.jpeg.gpsTimestamp", long.class);
+
+    /**
+     * <p>
+     * Orientation of JPEG image to
+     * write
+     * </p>
+     */
+    public static final Key<Integer> JPEG_ORIENTATION =
+            new Key<Integer>("android.jpeg.orientation", int.class);
+
+    /**
+     * <p>
+     * Compression quality of the final JPEG
+     * image
+     * </p>
+     * <p>
+     * 85-95 is typical usage range
+     * </p>
+     */
+    public static final Key<Byte> JPEG_QUALITY =
+            new Key<Byte>("android.jpeg.quality", byte.class);
+
+    /**
+     * <p>
+     * Compression quality of JPEG
+     * thumbnail
+     * </p>
+     */
+    public static final Key<Byte> JPEG_THUMBNAIL_QUALITY =
+            new Key<Byte>("android.jpeg.thumbnailQuality", byte.class);
+
+    /**
+     * <p>
+     * Resolution of embedded JPEG
+     * thumbnail
+     * </p>
+     */
+    public static final Key<android.hardware.camera2.Size> JPEG_THUMBNAIL_SIZE =
+            new Key<android.hardware.camera2.Size>("android.jpeg.thumbnailSize", android.hardware.camera2.Size.class);
+
+    /**
+     * <p>
+     * Size of the lens aperture
+     * </p>
+     * <p>
+     * Will not be supported on most devices. Can only
+     * pick from supported list
+     * </p>
+     */
+    public static final Key<Float> LENS_APERTURE =
+            new Key<Float>("android.lens.aperture", float.class);
+
+    /**
+     * <p>
+     * State of lens neutral density
+     * filter(s)
+     * </p>
+     * <p>
+     * Will not be supported on most devices. Can only
+     * pick from supported list
+     * </p>
+     */
+    public static final Key<Float> LENS_FILTER_DENSITY =
+            new Key<Float>("android.lens.filterDensity", float.class);
+
+    /**
+     * <p>
+     * Lens optical zoom setting
+     * </p>
+     * <p>
+     * Will not be supported on most devices.
+     * </p>
+     */
+    public static final Key<Float> LENS_FOCAL_LENGTH =
+            new Key<Float>("android.lens.focalLength", float.class);
+
+    /**
+     * <p>
+     * Distance to plane of sharpest focus,
+     * measured from frontmost surface of the lens
+     * </p>
+     * <p>
+     * Should be zero for fixed-focus cameras
+     * </p>
+     */
+    public static final Key<Float> LENS_FOCUS_DISTANCE =
+            new Key<Float>("android.lens.focusDistance", float.class);
+
+    /**
+     * <p>
+     * The range of scene distances that are in
+     * sharp focus (depth of field)
+     * </p>
+     * <p>
+     * If variable focus not supported, can still report
+     * fixed depth of field range
+     * </p>
+     */
+    public static final Key<Float> LENS_FOCUS_RANGE =
+            new Key<Float>("android.lens.focusRange", float.class);
+
+    /**
+     * <p>
+     * Whether optical image stabilization is
+     * enabled.
+     * </p>
+     * <p>
+     * Will not be supported on most devices.
+     * </p>
+     * @see #LENS_OPTICAL_STABILIZATION_MODE_OFF
+     * @see #LENS_OPTICAL_STABILIZATION_MODE_ON
+     */
+    public static final Key<Integer> LENS_OPTICAL_STABILIZATION_MODE =
+            new Key<Integer>("android.lens.opticalStabilizationMode", int.class);
+
+    /**
+     * <p>
+     * Current lens status
+     * </p>
+     * @see #LENS_STATE_STATIONARY
+     * @see #LENS_STATE_MOVING
+     */
+    public static final Key<Integer> LENS_STATE =
+            new Key<Integer>("android.lens.state", int.class);
+
+    /**
+     * <p>
+     * Mode of operation for the noise reduction
+     * algorithm
+     * </p>
+     * @see #NOISE_REDUCTION_MODE_OFF
+     * @see #NOISE_REDUCTION_MODE_FAST
+     * @see #NOISE_REDUCTION_MODE_HIGH_QUALITY
+     */
+    public static final Key<Integer> NOISE_REDUCTION_MODE =
+            new Key<Integer>("android.noiseReduction.mode", int.class);
+
+    /**
+     * <p>
+     * Number of frames captured since
+     * open()
+     * </p>
+     * <p>
+     * Reset on release()
+     * </p>
+     */
+    public static final Key<Integer> REQUEST_FRAME_COUNT =
+            new Key<Integer>("android.request.frameCount", int.class);
+
+    /**
+     * <p>
+     * An application-specified ID for the current
+     * request. Must be maintained unchanged in output
+     * frame
+     * </p>
+     *
+     * @hide
+     */
+    public static final Key<Integer> REQUEST_ID =
+            new Key<Integer>("android.request.id", int.class);
+
+    /**
+     * <p>
+     * (x, y, width, height).
+     * </p><p>
+     * A rectangle with the top-level corner of (x,y) and size
+     * (width, height). The region of the sensor that is used for
+     * output. Each stream must use this rectangle to produce its
+     * output, cropping to a smaller region if necessary to
+     * maintain the stream's aspect ratio.
+     * </p><p>
+     * HAL2.x uses only (x, y, width)
+     * </p>
+     * <p>
+     * Any additional per-stream cropping must be done to
+     * maximize the final pixel area of the stream.
+     * </p><p>
+     * For example, if the crop region is set to a 4:3 aspect
+     * ratio, then 4:3 streams should use the exact crop
+     * region. 16:9 streams should further crop vertically
+     * (letterbox).
+     * </p><p>
+     * Conversely, if the crop region is set to a 16:9, then 4:3
+     * outputs should crop horizontally (pillarbox), and 16:9
+     * streams should match exactly. These additional crops must
+     * be centered within the crop region.
+     * </p><p>
+     * The output streams must maintain square pixels at all
+     * times, no matter what the relative aspect ratios of the
+     * crop region and the stream are.  Negative values for
+     * corner are allowed for raw output if full pixel array is
+     * larger than active pixel array. Width and height may be
+     * rounded to nearest larger supportable width, especially
+     * for raw output, where only a few fixed scales may be
+     * possible. The width and height of the crop region cannot
+     * be set to be smaller than floor( activeArraySize.width /
+     * android.scaler.maxDigitalZoom ) and floor(
+     * activeArraySize.height / android.scaler.maxDigitalZoom),
+     * respectively.
+     * </p>
+     */
+    public static final Key<android.graphics.Rect> SCALER_CROP_REGION =
+            new Key<android.graphics.Rect>("android.scaler.cropRegion", android.graphics.Rect.class);
+
+    /**
+     * <p>
+     * Duration each pixel is exposed to
+     * light.
+     * </p><p>
+     * If the sensor can't expose this exact duration, it should shorten the
+     * duration exposed to the nearest possible value (rather than expose longer).
+     * </p>
+     * <p>
+     * 1/10000 - 30 sec range. No bulb mode
+     * </p>
+     */
+    public static final Key<Long> SENSOR_EXPOSURE_TIME =
+            new Key<Long>("android.sensor.exposureTime", long.class);
+
+    /**
+     * <p>
+     * Duration from start of frame exposure to
+     * start of next frame exposure
+     * </p>
+     * <p>
+     * Exposure time has priority, so duration is set to
+     * max(duration, exposure time + overhead)
+     * </p>
+     */
+    public static final Key<Long> SENSOR_FRAME_DURATION =
+            new Key<Long>("android.sensor.frameDuration", long.class);
+
+    /**
+     * <p>
+     * Gain applied to image data. Must be
+     * implemented through analog gain only if set to values
+     * below 'maximum analog sensitivity'.
+     * </p><p>
+     * If the sensor can't apply this exact gain, it should lessen the
+     * gain to the nearest possible value (rather than gain more).
+     * </p>
+     * <p>
+     * ISO 12232:2006 REI method
+     * </p>
+     */
+    public static final Key<Integer> SENSOR_SENSITIVITY =
+            new Key<Integer>("android.sensor.sensitivity", int.class);
+
+    /**
+     * <p>
+     * Time at start of exposure of first
+     * row
+     * </p>
+     * <p>
+     * Monotonic, should be synced to other timestamps in
+     * system
+     * </p>
+     */
+    public static final Key<Long> SENSOR_TIMESTAMP =
+            new Key<Long>("android.sensor.timestamp", long.class);
+
+    /**
+     * <p>
+     * The temperature of the sensor, sampled at the time
+     * exposure began for this frame.
+     * </p><p>
+     * The thermal diode being queried should be inside the sensor PCB, or
+     * somewhere close to it.
+     * </p>
+     */
+    public static final Key<Float> SENSOR_TEMPERATURE =
+            new Key<Float>("android.sensor.temperature", float.class);
+
+    /**
+     * <p>
+     * State of the face detector
+     * unit
+     * </p>
+     * <p>
+     * Whether face detection is enabled, and whether it
+     * should output just the basic fields or the full set of
+     * fields. Value must be one of the
+     * android.statistics.info.availableFaceDetectModes.
+     * </p>
+     * @see #STATISTICS_FACE_DETECT_MODE_OFF
+     * @see #STATISTICS_FACE_DETECT_MODE_SIMPLE
+     * @see #STATISTICS_FACE_DETECT_MODE_FULL
+     */
+    public static final Key<Integer> STATISTICS_FACE_DETECT_MODE =
+            new Key<Integer>("android.statistics.faceDetectMode", int.class);
+
+    /**
+     * <p>
+     * List of unique IDs for detected
+     * faces
+     * </p>
+     * <p>
+     * Only available if faceDetectMode == FULL
+     * </p>
+     */
+    public static final Key<int[]> STATISTICS_FACE_IDS =
+            new Key<int[]>("android.statistics.faceIds", int[].class);
+
+    /**
+     * <p>
+     * List of landmarks for detected
+     * faces
+     * </p>
+     * <p>
+     * Only available if faceDetectMode == FULL
+     * </p>
+     */
+    public static final Key<int[]> STATISTICS_FACE_LANDMARKS =
+            new Key<int[]>("android.statistics.faceLandmarks", int[].class);
+
+    /**
+     * <p>
+     * List of the bounding rectangles for detected
+     * faces
+     * </p>
+     * <p>
+     * Only available if faceDetectMode != OFF
+     * </p>
+     */
+    public static final Key<android.graphics.Rect[]> STATISTICS_FACE_RECTANGLES =
+            new Key<android.graphics.Rect[]>("android.statistics.faceRectangles", android.graphics.Rect[].class);
+
+    /**
+     * <p>
+     * List of the face confidence scores for
+     * detected faces
+     * </p>
+     * <p>
+     * Only available if faceDetectMode != OFF. The value should be
+     * meaningful (for example, setting 100 at all times is illegal).
+     * </p>
+     */
+    public static final Key<byte[]> STATISTICS_FACE_SCORES =
+            new Key<byte[]>("android.statistics.faceScores", byte[].class);
+
+    /**
+     * <p>
+     * A low-resolution map of lens shading, per
+     * color channel
+     * </p>
+     * <p>
+     * Assume bilinear interpolation of map. The least
+     * shaded section of the image should have a gain factor
+     * of 1; all other sections should have gains above 1.
+     * the map should be on the order of 30-40 rows, and
+     * must be smaller than 64x64.
+     * </p><p>
+     * When android.colorCorrection.mode = TRANSFORM_MATRIX, the map
+     * must take into account the colorCorrection settings.
+     * </p>
+     */
+    public static final Key<float[]> STATISTICS_LENS_SHADING_MAP =
+            new Key<float[]>("android.statistics.lensShadingMap", float[].class);
+
+    /**
+     * <p>
+     * The best-fit color channel gains calculated
+     * by the HAL's statistics units for the current output frame
+     * </p>
+     * <p>
+     * This may be different than the gains used for this frame,
+     * since statistics processing on data from a new frame
+     * typically completes after the transform has already been
+     * applied to that frame.
+     * </p><p>
+     * The 4 channel gains are defined in Bayer domain,
+     * see android.colorCorrection.gains for details.
+     * </p><p>
+     * This value should always be calculated by the AWB block,
+     * regardless of the android.control.* current values.
+     * </p>
+     */
+    public static final Key<float[]> STATISTICS_PREDICTED_COLOR_GAINS =
+            new Key<float[]>("android.statistics.predictedColorGains", float[].class);
+
+    /**
+     * <p>
+     * The best-fit color transform matrix estimate
+     * calculated by the HAL's statistics units for the current
+     * output frame
+     * </p>
+     * <p>
+     * The HAL must provide the estimate from its
+     * statistics unit on the white balance transforms to use
+     * for the next frame. These are the values the HAL believes
+     * are the best fit for the current output frame. This may
+     * be different than the transform used for this frame, since
+     * statistics processing on data from a new frame typically
+     * completes after the transform has already been applied to
+     * that frame.
+     * </p><p>
+     * These estimates must be provided for all frames, even if
+     * capture settings and color transforms are set by the application.
+     * </p><p>
+     * This value should always be calculated by the AWB block,
+     * regardless of the android.control.* current values.
+     * </p>
+     */
+    public static final Key<Rational[]> STATISTICS_PREDICTED_COLOR_TRANSFORM =
+            new Key<Rational[]>("android.statistics.predictedColorTransform", Rational[].class);
+
+    /**
+     * <p>
+     * The HAL estimated scene illumination lighting
+     * frequency
+     * </p>
+     * <p>
+     * Report NONE if there doesn't appear to be flickering
+     * illumination
+     * </p>
+     * @see #STATISTICS_SCENE_FLICKER_NONE
+     * @see #STATISTICS_SCENE_FLICKER_50HZ
+     * @see #STATISTICS_SCENE_FLICKER_60HZ
+     */
+    public static final Key<Integer> STATISTICS_SCENE_FLICKER =
+            new Key<Integer>("android.statistics.sceneFlicker", int.class);
+
+    /**
+     * <p>
+     * Table mapping blue input values to output
+     * values
+     * </p>
+     * <p>
+     * Tonemapping / contrast / gamma curve for the blue
+     * channel, to use when android.tonemap.mode is CONTRAST_CURVE.
+     * </p><p>
+     * See android.tonemap.curveRed for more details.
+     * </p>
+     */
+    public static final Key<float[]> TONEMAP_CURVE_BLUE =
+            new Key<float[]>("android.tonemap.curveBlue", float[].class);
+
+    /**
+     * <p>
+     * Table mapping green input values to output
+     * values
+     * </p>
+     * <p>
+     * Tonemapping / contrast / gamma curve for the green
+     * channel, to use when android.tonemap.mode is CONTRAST_CURVE.
+     * </p><p>
+     * See android.tonemap.curveRed for more details.
+     * </p>
+     */
+    public static final Key<float[]> TONEMAP_CURVE_GREEN =
+            new Key<float[]>("android.tonemap.curveGreen", float[].class);
+
+    /**
+     * <p>
+     * Table mapping red input values to output
+     * values
+     * </p>
+     * <p>
+     * Tonemapping / contrast / gamma curve for the red
+     * channel, to use when android.tonemap.mode is CONTRAST_CURVE.
+     * </p><p>
+     * Since the input and output ranges may vary depending on
+     * the camera pipeline, the input and output pixel values
+     * are represented by normalized floating-point values
+     * between 0 and 1, with 0 == black and 1 == white.
+     * </p><p>
+     * The curve should be linearly interpolated between the
+     * defined points. The points will be listed in increasing
+     * order of P_IN. For example, if the array is: [0.0, 0.0,
+     * 0.3, 0.5, 1.0, 1.0], then the input->output mapping
+     * for a few sample points would be: 0 -> 0, 0.15 ->
+     * 0.25, 0.3 -> 0.5, 0.5 -> 0.64
+     * </p>
+     */
+    public static final Key<float[]> TONEMAP_CURVE_RED =
+            new Key<float[]>("android.tonemap.curveRed", float[].class);
+
+    /**
+     * @see #TONEMAP_MODE_CONTRAST_CURVE
+     * @see #TONEMAP_MODE_FAST
+     * @see #TONEMAP_MODE_HIGH_QUALITY
+     */
+    public static final Key<Integer> TONEMAP_MODE =
+            new Key<Integer>("android.tonemap.mode", int.class);
+
+    /**
+     * <p>
+     * This LED is nominally used to indicate to the user
+     * that the camera is powered on and may be streaming images back to the
+     * Application Processor. In certain rare circumstances, the OS may
+     * disable this when video is processed locally and not transmitted to
+     * any untrusted applications.
+     * </p><p>
+     * In particular, the LED *must* always be on when the data could be
+     * transmitted off the device. The LED *should* always be on whenever
+     * data is stored locally on the device.
+     * </p><p>
+     * The LED *may* be off if a trusted application is using the data that
+     * doesn't violate the above rules.
+     * </p>
+     *
+     * @hide
+     */
+    public static final Key<Boolean> LED_TRANSMIT =
+            new Key<Boolean>("android.led.transmit", boolean.class);
+
+    /**
+     * <p>
+     * Whether black-level compensation is locked
+     * to its current values, or is free to vary
+     * </p>
+     * <p>
+     * When set to ON, the values used for black-level
+     * compensation must not change until the lock is set to
+     * OFF
+     * </p><p>
+     * Since changes to certain capture parameters (such as
+     * exposure time) may require resetting of black level
+     * compensation, the HAL must report whether setting the
+     * black level lock was successful in the output result
+     * metadata.
+     * </p><p>
+     * The black level locking must happen at the sensor, and not at the ISP.
+     * If for some reason black level locking is no longer legal (for example,
+     * the analog gain has changed, which forces black levels to be
+     * recalculated), then the HAL is free to override this request (and it
+     * must report 'OFF' when this does happen) until the next time locking
+     * is legal again.
+     * </p>
+     */
+    public static final Key<Boolean> BLACK_LEVEL_LOCK =
+            new Key<Boolean>("android.blackLevel.lock", boolean.class);
+
+    /*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
+     * End generated code
+     *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
+}
diff --git a/core/java/android/hardware/camera2/ICameraDeviceCallbacks.aidl b/core/java/android/hardware/camera2/ICameraDeviceCallbacks.aidl
new file mode 100644
index 0000000..4054a92
--- /dev/null
+++ b/core/java/android/hardware/camera2/ICameraDeviceCallbacks.aidl
@@ -0,0 +1,30 @@
+/*
+ * 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.hardware.camera2;
+
+import android.hardware.camera2.impl.CameraMetadataNative;
+
+/** @hide */
+interface ICameraDeviceCallbacks
+{
+    /**
+     * Keep up-to-date with frameworks/av/include/camera/camera2/ICameraDeviceCallbacks.h
+     */
+
+    oneway void notifyCallback(int msgType, int ext1, int ext2);
+    oneway void onResultReceived(int frameId, in CameraMetadataNative result);
+}
diff --git a/core/java/android/hardware/camera2/ICameraDeviceUser.aidl b/core/java/android/hardware/camera2/ICameraDeviceUser.aidl
new file mode 100644
index 0000000..1936963
--- /dev/null
+++ b/core/java/android/hardware/camera2/ICameraDeviceUser.aidl
@@ -0,0 +1,50 @@
+/*
+ * 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.hardware.camera2;
+
+import android.view.Surface;
+import android.hardware.camera2.impl.CameraMetadataNative;
+import android.hardware.camera2.CaptureRequest;
+
+/** @hide */
+interface ICameraDeviceUser
+{
+    /**
+     * Keep up-to-date with frameworks/av/include/camera/camera2/ICameraDeviceUser.h
+     */
+    void disconnect();
+
+    // ints here are status_t
+
+    // non-negative value is the requestId. negative value is status_t
+    int submitRequest(in CaptureRequest request, boolean streaming);
+
+    int cancelRequest(int requestId);
+
+    int deleteStream(int streamId);
+
+    // non-negative value is the stream ID. negative value is status_t
+    int createStream(int width, int height, int format, in Surface surface);
+
+    int createDefaultRequest(int templateId, out CameraMetadataNative request);
+
+    int getCameraInfo(out CameraMetadataNative info);
+
+    int waitUntilIdle();
+
+    int flush();
+}
diff --git a/core/java/android/hardware/camera2/Rational.java b/core/java/android/hardware/camera2/Rational.java
new file mode 100644
index 0000000..77b8c26
--- /dev/null
+++ b/core/java/android/hardware/camera2/Rational.java
@@ -0,0 +1,201 @@
+/*
+ * 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.hardware.camera2;
+
+/**
+ * The rational data type used by CameraMetadata keys. Contains a pair of ints representing the
+ * numerator and denominator of a Rational number. This type is immutable.
+ */
+public final class Rational {
+    private final int mNumerator;
+    private final int mDenominator;
+
+    /**
+     * <p>Create a Rational with a given numerator and denominator.</p>
+     *
+     * <p>The signs of the numerator and the denominator may be flipped such that the denominator
+     * is always positive.</p>
+     *
+     * <p>A rational value with a 0-denominator may be constructed, but will have similar semantics
+     * as float NaN and INF values. The int getter functions return 0 in this case.</p>
+     *
+     * @param numerator the numerator of the rational
+     * @param denominator the denominator of the rational
+     */
+    public Rational(int numerator, int denominator) {
+
+        if (denominator < 0) {
+            numerator = -numerator;
+            denominator = -denominator;
+        }
+
+        mNumerator = numerator;
+        mDenominator = denominator;
+    }
+
+    /**
+     * Gets the numerator of the rational.
+     */
+    public int getNumerator() {
+        if (mDenominator == 0) {
+            return 0;
+        }
+        return mNumerator;
+    }
+
+    /**
+     * Gets the denominator of the rational
+     */
+    public int getDenominator() {
+        return mDenominator;
+    }
+
+    private boolean isNaN() {
+        return mDenominator == 0 && mNumerator == 0;
+    }
+
+    private boolean isInf() {
+        return mDenominator == 0 && mNumerator > 0;
+    }
+
+    private boolean isNegInf() {
+        return mDenominator == 0 && mNumerator < 0;
+    }
+
+    /**
+     * <p>Compare this Rational to another object and see if they are equal.</p>
+     *
+     * <p>A Rational object can only be equal to another Rational object (comparing against any other
+     * type will return false).</p>
+     *
+     * <p>A Rational object is considered equal to another Rational object if and only if one of
+     * the following holds</p>:
+     * <ul><li>Both are NaN</li>
+     *     <li>Both are infinities of the same sign</li>
+     *     <li>Both have the same numerator and denominator in their reduced form</li>
+     * </ul>
+     *
+     * <p>A reduced form of a Rational is calculated by dividing both the numerator and the
+     * denominator by their greatest common divisor.</p>
+     *
+     * <pre>
+     *      (new Rational(1, 2)).equals(new Rational(1, 2)) == true   // trivially true
+     *      (new Rational(2, 3)).equals(new Rational(1, 2)) == false  // trivially false
+     *      (new Rational(1, 2)).equals(new Rational(2, 4)) == true   // true after reduction
+     *      (new Rational(0, 0)).equals(new Rational(0, 0)) == true   // NaN.equals(NaN)
+     *      (new Rational(1, 0)).equals(new Rational(5, 0)) == true   // both are +infinity
+     *      (new Rational(1, 0)).equals(new Rational(-1, 0)) == false // +infinity != -infinity
+     * </pre>
+     *
+     * @param obj a reference to another object
+     *
+     * @return A boolean that determines whether or not the two Rational objects are equal.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        } else if (obj instanceof Rational) {
+            Rational other = (Rational) obj;
+            if (mDenominator == 0 || other.mDenominator == 0) {
+                if (isNaN() && other.isNaN()) {
+                    return true;
+                } else if (isInf() && other.isInf() || isNegInf() && other.isNegInf()) {
+                    return true;
+                } else {
+                    return false;
+                }
+            } else if (mNumerator == other.mNumerator && mDenominator == other.mDenominator) {
+                return true;
+            } else {
+                int thisGcd = gcd();
+                int otherGcd = other.gcd();
+
+                int thisNumerator = mNumerator / thisGcd;
+                int thisDenominator = mDenominator / thisGcd;
+
+                int otherNumerator = other.mNumerator / otherGcd;
+                int otherDenominator = other.mDenominator / otherGcd;
+
+                return (thisNumerator == otherNumerator && thisDenominator == otherDenominator);
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        if (isNaN()) {
+            return "NaN";
+        } else if (isInf()) {
+            return "Infinity";
+        } else if (isNegInf()) {
+            return "-Infinity";
+        } else {
+            return mNumerator + "/" + mDenominator;
+        }
+    }
+
+    /**
+     * <p>Convert to a floating point representation.</p>
+     *
+     * @return The floating point representation of this rational number.
+     * @hide
+     */
+    public float toFloat() {
+        return (float) mNumerator / (float) mDenominator;
+    }
+
+    @Override
+    public int hashCode() {
+        final long INT_MASK = 0xffffffffL;
+
+        long asLong = INT_MASK & mNumerator;
+        asLong <<= 32;
+
+        asLong |= (INT_MASK & mDenominator);
+
+        return ((Long)asLong).hashCode();
+    }
+
+    /**
+     * Calculates the greatest common divisor using Euclid's algorithm.
+     *
+     * @return An int value representing the gcd. Always positive.
+     * @hide
+     */
+    public int gcd() {
+        /**
+         * Non-recursive implementation of Euclid's algorithm:
+         *
+         *  gcd(a, 0) := a
+         *  gcd(a, b) := gcd(b, a mod b)
+         *
+         */
+
+        int a = mNumerator;
+        int b = mDenominator;
+
+        while (b != 0) {
+            int oldB = b;
+
+            b = a % b;
+            a = oldB;
+        }
+
+        return Math.abs(a);
+    }
+}
diff --git a/core/java/android/hardware/camera2/Size.java b/core/java/android/hardware/camera2/Size.java
new file mode 100644
index 0000000..45aaeae
--- /dev/null
+++ b/core/java/android/hardware/camera2/Size.java
@@ -0,0 +1,77 @@
+/*
+ * 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.hardware.camera2;
+
+/**
+ * A simple immutable class for describing the dimensions of camera image
+ * buffers.
+ */
+public final class Size {
+    /**
+     * Create a new immutable Size instance
+     *
+     * @param width The width to store in the Size instance
+     * @param height The height to store in the Size instance
+     */
+    public Size(int width, int height) {
+        mWidth = width;
+        mHeight = height;
+    }
+
+    public final int getWidth() {
+        return mWidth;
+    }
+
+    public final int getHeight() {
+        return mHeight;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof Size) {
+            Size other = (Size) obj;
+            return mWidth == other.mWidth && mHeight == other.mHeight;
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return mWidth + "x" + mHeight;
+    }
+
+    @Override
+    public int hashCode() {
+        final long INT_MASK = 0xffffffffL;
+
+        long asLong = INT_MASK & mWidth;
+        asLong <<= 32;
+
+        asLong |= (INT_MASK & mHeight);
+
+        return ((Long)asLong).hashCode();
+    }
+
+    private final int mWidth;
+    private final int mHeight;
+};
diff --git a/core/java/android/hardware/camera2/impl/CameraDevice.java b/core/java/android/hardware/camera2/impl/CameraDevice.java
new file mode 100644
index 0000000..995555a
--- /dev/null
+++ b/core/java/android/hardware/camera2/impl/CameraDevice.java
@@ -0,0 +1,454 @@
+/*
+ * 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.hardware.camera2.impl;
+
+import static android.hardware.camera2.CameraAccessException.CAMERA_IN_USE;
+
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraMetadata;
+import android.hardware.camera2.CameraProperties;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.ICameraDeviceCallbacks;
+import android.hardware.camera2.ICameraDeviceUser;
+import android.hardware.camera2.utils.CameraBinderDecorator;
+import android.hardware.camera2.utils.CameraRuntimeException;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+import android.util.SparseArray;
+import android.view.Surface;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Stack;
+
+/**
+ * HAL2.1+ implementation of CameraDevice. Use CameraManager#open to instantiate
+ */
+public class CameraDevice implements android.hardware.camera2.CameraDevice {
+
+    private final String TAG;
+    private final boolean DEBUG;
+
+    // TODO: guard every function with if (!mRemoteDevice) check (if it was closed)
+    private ICameraDeviceUser mRemoteDevice;
+
+    private final Object mLock = new Object();
+    private final CameraDeviceCallbacks mCallbacks = new CameraDeviceCallbacks();
+
+    private CameraDeviceListener mDeviceListener;
+    private Handler mDeviceHandler;
+
+    private final SparseArray<CaptureListenerHolder> mCaptureListenerMap =
+            new SparseArray<CaptureListenerHolder>();
+
+    private final Stack<Integer> mRepeatingRequestIdStack = new Stack<Integer>();
+    // Map stream IDs to Surfaces
+    private final SparseArray<Surface> mConfiguredOutputs = new SparseArray<Surface>();
+
+    private final String mCameraId;
+
+    public CameraDevice(String cameraId) {
+        mCameraId = cameraId;
+        TAG = String.format("CameraDevice-%s-JV", mCameraId);
+        DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+    }
+
+    public CameraDeviceCallbacks getCallbacks() {
+        return mCallbacks;
+    }
+
+    public void setRemoteDevice(ICameraDeviceUser remoteDevice) {
+        // TODO: Move from decorator to direct binder-mediated exceptions
+        mRemoteDevice = CameraBinderDecorator.newInstance(remoteDevice);
+    }
+
+    @Override
+    public String getId() {
+        return mCameraId;
+    }
+
+    @Override
+    public CameraProperties getProperties() throws CameraAccessException {
+
+        CameraMetadataNative info = new CameraMetadataNative();
+
+        try {
+            mRemoteDevice.getCameraInfo(/*out*/info);
+        } catch(CameraRuntimeException e) {
+            throw e.asChecked();
+        } catch(RemoteException e) {
+            // impossible
+            return null;
+        }
+
+        CameraProperties properties = new CameraProperties(info);
+        return properties;
+    }
+
+    @Override
+    public void configureOutputs(List<Surface> outputs) throws CameraAccessException {
+        synchronized (mLock) {
+            HashSet<Surface> addSet = new HashSet<Surface>(outputs);    // Streams to create
+            List<Integer> deleteList = new ArrayList<Integer>();        // Streams to delete
+
+            // Determine which streams need to be created, which to be deleted
+            for (int i = 0; i < mConfiguredOutputs.size(); ++i) {
+                int streamId = mConfiguredOutputs.keyAt(i);
+                Surface s = mConfiguredOutputs.valueAt(i);
+
+                if (!outputs.contains(s)) {
+                    deleteList.add(streamId);
+                } else {
+                    addSet.remove(s);  // Don't create a stream previously created
+                }
+            }
+
+            try {
+                // TODO: mRemoteDevice.beginConfigure
+
+                // Delete all streams first (to free up HW resources)
+                for (Integer streamId : deleteList) {
+                    mRemoteDevice.deleteStream(streamId);
+                    mConfiguredOutputs.delete(streamId);
+                }
+
+                // Add all new streams
+                for (Surface s : addSet) {
+                    // TODO: remove width,height,format since we are ignoring
+                    // it.
+                    int streamId = mRemoteDevice.createStream(0, 0, 0, s);
+                    mConfiguredOutputs.put(streamId, s);
+                }
+
+                // TODO: mRemoteDevice.endConfigure
+            } catch (CameraRuntimeException e) {
+                if (e.getReason() == CAMERA_IN_USE) {
+                    throw new IllegalStateException("The camera is currently busy." +
+                            " You must call waitUntilIdle before trying to reconfigure.");
+                }
+
+                throw e.asChecked();
+            } catch (RemoteException e) {
+                // impossible
+                return;
+            }
+        }
+    }
+
+    @Override
+    public CaptureRequest.Builder createCaptureRequest(int templateType)
+            throws CameraAccessException {
+        synchronized (mLock) {
+
+            CameraMetadataNative templatedRequest = new CameraMetadataNative();
+
+            try {
+                mRemoteDevice.createDefaultRequest(templateType, /* out */templatedRequest);
+            } catch (CameraRuntimeException e) {
+                throw e.asChecked();
+            } catch (RemoteException e) {
+                // impossible
+                return null;
+            }
+
+            CaptureRequest.Builder builder =
+                    new CaptureRequest.Builder(templatedRequest);
+
+            return builder;
+        }
+    }
+
+    @Override
+    public void capture(CaptureRequest request, CaptureListener listener, Handler handler)
+            throws CameraAccessException {
+        submitCaptureRequest(request, listener, handler, /*streaming*/false);
+    }
+
+    @Override
+    public void captureBurst(List<CaptureRequest> requests, CaptureListener listener,
+            Handler handler) throws CameraAccessException {
+        if (requests.isEmpty()) {
+            Log.w(TAG, "Capture burst request list is empty, do nothing!");
+            return;
+        }
+        // TODO
+        throw new UnsupportedOperationException("Burst capture implemented yet");
+
+    }
+
+    private void submitCaptureRequest(CaptureRequest request, CaptureListener listener,
+            Handler handler, boolean repeating) throws CameraAccessException {
+
+        // Need a valid handler, or current thread needs to have a looper, if
+        // listener is valid
+        if (handler == null && listener != null) {
+            Looper looper = Looper.myLooper();
+            if (looper == null) {
+                throw new IllegalArgumentException(
+                        "No handler given, and current thread has no looper!");
+            }
+            handler = new Handler(looper);
+        }
+
+        synchronized (mLock) {
+
+            int requestId;
+
+            try {
+                requestId = mRemoteDevice.submitRequest(request, repeating);
+            } catch (CameraRuntimeException e) {
+                throw e.asChecked();
+            } catch (RemoteException e) {
+                // impossible
+                return;
+            }
+            if (listener != null) {
+                mCaptureListenerMap.put(requestId, new CaptureListenerHolder(listener, request,
+                        handler, repeating));
+            }
+
+            if (repeating) {
+                mRepeatingRequestIdStack.add(requestId);
+            }
+
+        }
+    }
+
+    @Override
+    public void setRepeatingRequest(CaptureRequest request, CaptureListener listener,
+            Handler handler) throws CameraAccessException {
+        submitCaptureRequest(request, listener, handler, /*streaming*/true);
+    }
+
+    @Override
+    public void setRepeatingBurst(List<CaptureRequest> requests, CaptureListener listener,
+            Handler handler) throws CameraAccessException {
+        if (requests.isEmpty()) {
+            Log.w(TAG, "Set Repeating burst request list is empty, do nothing!");
+            return;
+        }
+        // TODO
+        throw new UnsupportedOperationException("Burst capture implemented yet");
+    }
+
+    @Override
+    public void stopRepeating() throws CameraAccessException {
+
+        synchronized (mLock) {
+
+            while (!mRepeatingRequestIdStack.isEmpty()) {
+                int requestId = mRepeatingRequestIdStack.pop();
+
+                try {
+                    mRemoteDevice.cancelRequest(requestId);
+                } catch (CameraRuntimeException e) {
+                    throw e.asChecked();
+                } catch (RemoteException e) {
+                    // impossible
+                    return;
+                }
+            }
+        }
+    }
+
+    @Override
+    public void waitUntilIdle() throws CameraAccessException {
+
+        synchronized (mLock) {
+            checkIfCameraClosed();
+            if (!mRepeatingRequestIdStack.isEmpty()) {
+                throw new IllegalStateException("Active repeating request ongoing");
+            }
+
+            try {
+                mRemoteDevice.waitUntilIdle();
+            } catch (CameraRuntimeException e) {
+                throw e.asChecked();
+            } catch (RemoteException e) {
+                // impossible
+                return;
+            }
+      }
+    }
+
+    @Override
+    public void setDeviceListener(CameraDeviceListener listener, Handler handler) {
+        synchronized (mLock) {
+            mDeviceListener = listener;
+            mDeviceHandler = handler;
+        }
+    }
+
+    @Override
+    public void flush() throws CameraAccessException {
+        synchronized (mLock) {
+            try {
+                mRemoteDevice.flush();
+            } catch (CameraRuntimeException e) {
+                throw e.asChecked();
+            } catch (RemoteException e) {
+                // impossible
+                return;
+            }
+        }
+    }
+
+    @Override
+    public void close() throws Exception {
+
+        // TODO: every method should throw IllegalStateException after close has been called
+
+        synchronized (mLock) {
+
+            try {
+                if (mRemoteDevice != null) {
+                    mRemoteDevice.disconnect();
+                }
+            } catch (CameraRuntimeException e) {
+                throw e.asChecked();
+            } catch (RemoteException e) {
+                // impossible
+            }
+
+            mRemoteDevice = null;
+
+        }
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            close();
+        } catch (CameraRuntimeException e) {
+            Log.e(TAG, "Got error while trying to finalize, ignoring: " + e.getMessage());
+        }
+        finally {
+            super.finalize();
+        }
+    }
+
+    static class CaptureListenerHolder {
+
+        private final boolean mRepeating;
+        private final CaptureListener mListener;
+        private final CaptureRequest mRequest;
+        private final Handler mHandler;
+
+        CaptureListenerHolder(CaptureListener listener, CaptureRequest request, Handler handler,
+                boolean repeating) {
+            if (listener == null || handler == null) {
+                throw new UnsupportedOperationException(
+                    "Must have a valid handler and a valid listener");
+            }
+            mRepeating = repeating;
+            mHandler = handler;
+            mRequest = request;
+            mListener = listener;
+        }
+
+        public boolean isRepeating() {
+            return mRepeating;
+        }
+
+        public CaptureListener getListener() {
+            return mListener;
+        }
+
+        public CaptureRequest getRequest() {
+            return mRequest;
+        }
+
+        public Handler getHandler() {
+            return mHandler;
+        }
+
+    }
+
+    // TODO: unit tests
+    public class CameraDeviceCallbacks extends ICameraDeviceCallbacks.Stub {
+
+        @Override
+        public IBinder asBinder() {
+            return this;
+        }
+
+        // TODO: consider rename to onMessageReceived
+        @Override
+        public void notifyCallback(int msgType, int ext1, int ext2) throws RemoteException {
+            if (DEBUG) {
+                Log.d(TAG, "Got message " + msgType + " ext1: " + ext1 + " , ext2: " + ext2);
+            }
+            // TODO implement rest
+        }
+
+        @Override
+        public void onResultReceived(int requestId, CameraMetadataNative result)
+                throws RemoteException {
+            if (DEBUG) {
+                Log.d(TAG, "Received result for id " + requestId);
+            }
+            final CaptureListenerHolder holder;
+
+            synchronized (mLock) {
+                // TODO: move this whole map into this class to make it more testable,
+                //        exposing the methods necessary like subscribeToRequest, unsubscribe..
+                // TODO: make class static class
+
+                holder = CameraDevice.this.mCaptureListenerMap.get(requestId);
+
+                // Clean up listener once we no longer expect to see it.
+
+                // TODO: how to handle repeating listeners?
+                // we probably want cancelRequest to return # of times it already enqueued and
+                // keep a counter.
+                if (holder != null && !holder.isRepeating()) {
+                    CameraDevice.this.mCaptureListenerMap.remove(requestId);
+                }
+            }
+
+            // Check if we have a listener for this
+            if (holder == null) {
+                return;
+            }
+
+            final CaptureResult resultAsCapture = new CaptureResult(result);
+
+            holder.getHandler().post(
+                new Runnable() {
+                    public void run() {
+                        holder.getListener().onCaptureCompleted(
+                            CameraDevice.this,
+                            holder.getRequest(),
+                            resultAsCapture);
+                    }
+                });
+        }
+
+    }
+
+    private void checkIfCameraClosed() {
+        if (mRemoteDevice == null) {
+            throw new IllegalStateException("CameraDevice was already closed");
+        }
+    }
+}
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.aidl b/core/java/android/hardware/camera2/impl/CameraMetadataNative.aidl
new file mode 100644
index 0000000..4a89129
--- /dev/null
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.aidl
@@ -0,0 +1,20 @@
+/*
+ * 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.hardware.camera2.impl;
+
+/** @hide */
+parcelable CameraMetadataNative;
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
new file mode 100644
index 0000000..020d7b6
--- /dev/null
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -0,0 +1,669 @@
+/*
+ * 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.hardware.camera2.impl;
+
+import android.hardware.camera2.CameraMetadata;
+import android.hardware.camera2.Rational;
+import android.os.Parcelable;
+import android.os.Parcel;
+import android.util.Log;
+
+import java.lang.reflect.Array;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Implementation of camera metadata marshal/unmarshal across Binder to
+ * the camera service
+ */
+public class CameraMetadataNative extends CameraMetadata implements Parcelable {
+
+    private static final String TAG = "CameraMetadataJV";
+
+    public CameraMetadataNative() {
+        super();
+        mMetadataPtr = nativeAllocate();
+        if (mMetadataPtr == 0) {
+            throw new OutOfMemoryError("Failed to allocate native CameraMetadata");
+        }
+    }
+
+    /**
+     * Copy constructor - clone metadata
+     */
+    public CameraMetadataNative(CameraMetadataNative other) {
+        super();
+        mMetadataPtr = nativeAllocateCopy(other);
+        if (mMetadataPtr == 0) {
+            throw new OutOfMemoryError("Failed to allocate native CameraMetadata");
+        }
+    }
+
+    public static final Parcelable.Creator<CameraMetadataNative> CREATOR =
+            new Parcelable.Creator<CameraMetadataNative>() {
+        @Override
+        public CameraMetadataNative createFromParcel(Parcel in) {
+            CameraMetadataNative metadata = new CameraMetadataNative();
+            metadata.readFromParcel(in);
+            return metadata;
+        }
+
+        @Override
+        public CameraMetadataNative[] newArray(int size) {
+            return new CameraMetadataNative[size];
+        }
+    };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        nativeWriteToParcel(dest);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T> T get(Key<T> key) {
+        int tag = key.getTag();
+        byte[] values = readValues(tag);
+        if (values == null) {
+            return null;
+        }
+
+        int nativeType = getNativeType(tag);
+
+        ByteBuffer buffer = ByteBuffer.wrap(values).order(ByteOrder.nativeOrder());
+        return unpackSingle(buffer, key.getType(), nativeType);
+    }
+
+    public void readFromParcel(Parcel in) {
+        nativeReadFromParcel(in);
+    }
+
+    /**
+     * Set a camera metadata field to a value. The field definitions can be
+     * found in {@link CameraProperties}, {@link CaptureResult}, and
+     * {@link CaptureRequest}.
+     *
+     * @param key The metadata field to write.
+     * @param value The value to set the field to, which must be of a matching
+     * type to the key.
+     */
+    public <T> void set(Key<T> key, T value) {
+        int tag = key.getTag();
+
+        if (value == null) {
+            writeValues(tag, null);
+            return;
+        }
+
+        int nativeType = getNativeType(tag);
+
+        int size = packSingle(value, null, key.getType(), nativeType, /* sizeOnly */true);
+
+        // TODO: Optimization. Cache the byte[] and reuse if the size is big enough.
+        byte[] values = new byte[size];
+
+        ByteBuffer buffer = ByteBuffer.wrap(values).order(ByteOrder.nativeOrder());
+        packSingle(value, buffer, key.getType(), nativeType, /*sizeOnly*/false);
+
+        writeValues(tag, values);
+    }
+
+    // Keep up-to-date with camera_metadata.h
+    /**
+     * @hide
+     */
+    public static final int TYPE_BYTE = 0;
+    /**
+     * @hide
+     */
+    public static final int TYPE_INT32 = 1;
+    /**
+     * @hide
+     */
+    public static final int TYPE_FLOAT = 2;
+    /**
+     * @hide
+     */
+    public static final int TYPE_INT64 = 3;
+    /**
+     * @hide
+     */
+    public static final int TYPE_DOUBLE = 4;
+    /**
+     * @hide
+     */
+    public static final int TYPE_RATIONAL = 5;
+    /**
+     * @hide
+     */
+    public static final int NUM_TYPES = 6;
+
+    private void close() {
+        // this sets mMetadataPtr to 0
+        nativeClose();
+        mMetadataPtr = 0; // set it to 0 again to prevent eclipse from making this field final
+    }
+
+    private static int getTypeSize(int nativeType) {
+        switch(nativeType) {
+            case TYPE_BYTE:
+                return 1;
+            case TYPE_INT32:
+            case TYPE_FLOAT:
+                return 4;
+            case TYPE_INT64:
+            case TYPE_DOUBLE:
+            case TYPE_RATIONAL:
+                return 8;
+        }
+
+        throw new UnsupportedOperationException("Unknown type, can't get size "
+                + nativeType);
+    }
+
+    private static Class<?> getExpectedType(int nativeType) {
+        switch(nativeType) {
+            case TYPE_BYTE:
+                return Byte.TYPE;
+            case TYPE_INT32:
+                return Integer.TYPE;
+            case TYPE_FLOAT:
+                return Float.TYPE;
+            case TYPE_INT64:
+                return Long.TYPE;
+            case TYPE_DOUBLE:
+                return Double.TYPE;
+            case TYPE_RATIONAL:
+                return Rational.class;
+        }
+
+        throw new UnsupportedOperationException("Unknown type, can't map to Java type "
+                + nativeType);
+    }
+
+    @SuppressWarnings("unchecked")
+    private static <T> int packSingleNative(T value, ByteBuffer buffer, Class<T> type,
+            int nativeType, boolean sizeOnly) {
+
+        if (!sizeOnly) {
+            /**
+             * Rewrite types when the native type doesn't match the managed type
+             *  - Boolean -> Byte
+             *  - Integer -> Byte
+             */
+
+            if (nativeType == TYPE_BYTE && type == Boolean.TYPE) {
+                // Since a boolean can't be cast to byte, and we don't want to use putBoolean
+                boolean asBool = (Boolean) value;
+                byte asByte = (byte) (asBool ? 1 : 0);
+                value = (T) (Byte) asByte;
+            } else if (nativeType == TYPE_BYTE && type == Integer.TYPE) {
+                int asInt = (Integer) value;
+                byte asByte = (byte) asInt;
+                value = (T) (Byte) asByte;
+            } else if (type != getExpectedType(nativeType)) {
+                throw new UnsupportedOperationException("Tried to pack a type of " + type +
+                        " but we expected the type to be " + getExpectedType(nativeType));
+            }
+
+            if (nativeType == TYPE_BYTE) {
+                buffer.put((Byte) value);
+            } else if (nativeType == TYPE_INT32) {
+                buffer.putInt((Integer) value);
+            } else if (nativeType == TYPE_FLOAT) {
+                buffer.putFloat((Float) value);
+            } else if (nativeType == TYPE_INT64) {
+                buffer.putLong((Long) value);
+            } else if (nativeType == TYPE_DOUBLE) {
+                buffer.putDouble((Double) value);
+            } else if (nativeType == TYPE_RATIONAL) {
+                Rational r = (Rational) value;
+                buffer.putInt(r.getNumerator());
+                buffer.putInt(r.getDenominator());
+            }
+
+        }
+
+        return getTypeSize(nativeType);
+    }
+
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    private static <T> int packSingle(T value, ByteBuffer buffer, Class<T> type, int nativeType,
+            boolean sizeOnly) {
+
+        int size = 0;
+
+        if (type.isPrimitive() || type == Rational.class) {
+            size = packSingleNative(value, buffer, type, nativeType, sizeOnly);
+        } else if (type.isEnum()) {
+            size = packEnum((Enum)value, buffer, (Class<Enum>)type, nativeType, sizeOnly);
+        } else if (type.isArray()) {
+            size = packArray(value, buffer, type, nativeType, sizeOnly);
+        } else {
+            size = packClass(value, buffer, type, nativeType, sizeOnly);
+        }
+
+        return size;
+    }
+
+    private static <T extends Enum<T>> int packEnum(T value, ByteBuffer buffer, Class<T> type,
+            int nativeType, boolean sizeOnly) {
+
+        // TODO: add support for enums with their own values.
+        return packSingleNative(getEnumValue(value), buffer, Integer.TYPE, nativeType, sizeOnly);
+    }
+
+    @SuppressWarnings("unchecked")
+    private static <T> int packClass(T value, ByteBuffer buffer, Class<T> type, int nativeType,
+            boolean sizeOnly) {
+
+        MetadataMarshalClass<T> marshaler = getMarshaler(type, nativeType);
+        if (marshaler == null) {
+            throw new IllegalArgumentException(String.format("Unknown Key type: %s", type));
+        }
+
+        return marshaler.marshal(value, buffer, nativeType, sizeOnly);
+    }
+
+    private static <T> int packArray(T value, ByteBuffer buffer, Class<T> type, int nativeType,
+            boolean sizeOnly) {
+
+        int size = 0;
+        int arrayLength = Array.getLength(value);
+
+        @SuppressWarnings("unchecked")
+        Class<Object> componentType = (Class<Object>)type.getComponentType();
+
+        for (int i = 0; i < arrayLength; ++i) {
+            size += packSingle(Array.get(value, i), buffer, componentType, nativeType, sizeOnly);
+        }
+
+        return size;
+    }
+
+    @SuppressWarnings("unchecked")
+    private static <T> T unpackSingleNative(ByteBuffer buffer, Class<T> type, int nativeType) {
+
+        T val;
+
+        if (nativeType == TYPE_BYTE) {
+            val = (T) (Byte) buffer.get();
+        } else if (nativeType == TYPE_INT32) {
+            val = (T) (Integer) buffer.getInt();
+        } else if (nativeType == TYPE_FLOAT) {
+            val = (T) (Float) buffer.getFloat();
+        } else if (nativeType == TYPE_INT64) {
+            val = (T) (Long) buffer.getLong();
+        } else if (nativeType == TYPE_DOUBLE) {
+            val = (T) (Double) buffer.getDouble();
+        } else if (nativeType == TYPE_RATIONAL) {
+            val = (T) new Rational(buffer.getInt(), buffer.getInt());
+        } else {
+            throw new UnsupportedOperationException("Unknown type, can't unpack a native type "
+                + nativeType);
+        }
+
+        /**
+         * Rewrite types when the native type doesn't match the managed type
+         *  - Byte -> Boolean
+         *  - Byte -> Integer
+         */
+
+        if (nativeType == TYPE_BYTE && type == Boolean.TYPE) {
+            // Since a boolean can't be cast to byte, and we don't want to use getBoolean
+            byte asByte = (Byte) val;
+            boolean asBool = asByte != 0;
+            val = (T) (Boolean) asBool;
+        } else if (nativeType == TYPE_BYTE && type == Integer.TYPE) {
+            byte asByte = (Byte) val;
+            int asInt = asByte;
+            val = (T) (Integer) asInt;
+        } else if (type != getExpectedType(nativeType)) {
+            throw new UnsupportedOperationException("Tried to unpack a type of " + type +
+                    " but we expected the type to be " + getExpectedType(nativeType));
+        }
+
+        return val;
+    }
+
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    private static <T> T unpackSingle(ByteBuffer buffer, Class<T> type, int nativeType) {
+
+        if (type.isPrimitive() || type == Rational.class) {
+            return unpackSingleNative(buffer, type, nativeType);
+        }
+
+        if (type.isEnum()) {
+            return (T) unpackEnum(buffer, (Class<Enum>)type, nativeType);
+        }
+
+        if (type.isArray()) {
+            return unpackArray(buffer, type, nativeType);
+        }
+
+        T instance = unpackClass(buffer, type, nativeType);
+
+        return instance;
+    }
+
+    private static <T extends Enum<T>> T unpackEnum(ByteBuffer buffer, Class<T> type,
+            int nativeType) {
+        int ordinal = unpackSingleNative(buffer, Integer.TYPE, nativeType);
+        return getEnumFromValue(type, ordinal);
+    }
+
+    private static <T> T unpackClass(ByteBuffer buffer, Class<T> type, int nativeType) {
+
+        MetadataMarshalClass<T> marshaler = getMarshaler(type, nativeType);
+        if (marshaler == null) {
+            throw new IllegalArgumentException("Unknown class type: " + type);
+        }
+
+        return marshaler.unmarshal(buffer, nativeType);
+    }
+
+    @SuppressWarnings("unchecked")
+    private static <T> T unpackArray(ByteBuffer buffer, Class<T> type, int nativeType) {
+
+        Class<?> componentType = type.getComponentType();
+        Object array;
+
+        int elementSize = getTypeSize(nativeType);
+
+        MetadataMarshalClass<?> marshaler = getMarshaler(componentType, nativeType);
+        if (marshaler != null) {
+            elementSize = marshaler.getNativeSize(nativeType);
+        }
+
+        if (elementSize != MetadataMarshalClass.NATIVE_SIZE_DYNAMIC) {
+            int remaining = buffer.remaining();
+            int arraySize = remaining / elementSize;
+
+            Log.v(TAG,
+                    String.format(
+                            "Attempting to unpack array (count = %d, element size = %d, bytes " +
+                                    "remaining = %d) for type %s",
+                            arraySize, elementSize, remaining, type));
+
+            array = Array.newInstance(componentType, arraySize);
+            for (int i = 0; i < arraySize; ++i) {
+               Object elem = unpackSingle(buffer, componentType, nativeType);
+               Array.set(array, i, elem);
+            }
+        } else {
+            // Dynamic size, use an array list.
+            ArrayList<Object> arrayList = new ArrayList<Object>();
+
+            int primitiveSize = getTypeSize(nativeType);
+            while (buffer.remaining() >= primitiveSize) {
+                Object elem = unpackSingle(buffer, componentType, nativeType);
+                arrayList.add(elem);
+            }
+
+            array = arrayList.toArray((T[]) Array.newInstance(componentType, 0));
+        }
+
+        if (buffer.remaining() != 0) {
+            Log.e(TAG, "Trailing bytes (" + buffer.remaining() + ") left over after unpacking "
+                    + type);
+        }
+
+        return (T) array;
+    }
+
+    private long mMetadataPtr; // native CameraMetadata*
+
+    private native long nativeAllocate();
+    private native long nativeAllocateCopy(CameraMetadataNative other)
+            throws NullPointerException;
+
+    private native synchronized void nativeWriteToParcel(Parcel dest);
+    private native synchronized void nativeReadFromParcel(Parcel source);
+    private native synchronized void nativeSwap(CameraMetadataNative other)
+            throws NullPointerException;
+    private native synchronized void nativeClose();
+    private native synchronized boolean nativeIsEmpty();
+    private native synchronized int nativeGetEntryCount();
+
+    private native synchronized byte[] nativeReadValues(int tag);
+    private native synchronized void nativeWriteValues(int tag, byte[] src);
+
+    private static native int nativeGetTagFromKey(String keyName)
+            throws IllegalArgumentException;
+    private static native int nativeGetTypeFromTag(int tag)
+            throws IllegalArgumentException;
+    private static native void nativeClassInit();
+
+    /**
+     * <p>Perform a 0-copy swap of the internal metadata with another object.</p>
+     *
+     * <p>Useful to convert a CameraMetadata into e.g. a CaptureRequest.</p>
+     *
+     * @param other Metadata to swap with
+     * @throws NullPointerException if other was null
+     * @hide
+     */
+    public void swap(CameraMetadataNative other) {
+        nativeSwap(other);
+    }
+
+    /**
+     * @hide
+     */
+    public int getEntryCount() {
+        return nativeGetEntryCount();
+    }
+
+    /**
+     * Does this metadata contain at least 1 entry?
+     *
+     * @hide
+     */
+    public boolean isEmpty() {
+        return nativeIsEmpty();
+    }
+
+    /**
+     * Convert a key string into the equivalent native tag.
+     *
+     * @throws IllegalArgumentException if the key was not recognized
+     * @throws NullPointerException if the key was null
+     *
+     * @hide
+     */
+    public static int getTag(String key) {
+        return nativeGetTagFromKey(key);
+    }
+
+    /**
+     * Get the underlying native type for a tag.
+     *
+     * @param tag An integer tag, see e.g. {@link #getTag}
+     * @return An int enum for the metadata type, see e.g. {@link #TYPE_BYTE}
+     *
+     * @hide
+     */
+    public static int getNativeType(int tag) {
+        return nativeGetTypeFromTag(tag);
+    }
+
+    /**
+     * <p>Updates the existing entry for tag with the new bytes pointed by src, erasing
+     * the entry if src was null.</p>
+     *
+     * <p>An empty array can be passed in to update the entry to 0 elements.</p>
+     *
+     * @param tag An integer tag, see e.g. {@link #getTag}
+     * @param src An array of bytes, or null to erase the entry
+     *
+     * @hide
+     */
+    public void writeValues(int tag, byte[] src) {
+        nativeWriteValues(tag, src);
+    }
+
+    /**
+     * <p>Returns a byte[] of data corresponding to this tag. Use a wrapped bytebuffer to unserialize
+     * the data properly.</p>
+     *
+     * <p>An empty array can be returned to denote an existing entry with 0 elements.</p>
+     *
+     * @param tag An integer tag, see e.g. {@link #getTag}
+     *
+     * @return {@code null} if there were 0 entries for this tag, a byte[] otherwise.
+     * @hide
+     */
+    public byte[] readValues(int tag) {
+     // TODO: Optimization. Native code returns a ByteBuffer instead.
+        return nativeReadValues(tag);
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            close();
+        } finally {
+            super.finalize();
+        }
+    }
+
+    private static final HashMap<Class<? extends Enum>, int[]> sEnumValues =
+            new HashMap<Class<? extends Enum>, int[]>();
+    /**
+     * Register a non-sequential set of values to be used with the pack/unpack functions.
+     * This enables get/set to correctly marshal the enum into a value that is C-compatible.
+     *
+     * @param enumType The class for an enum
+     * @param values A list of values mapping to the ordinals of the enum
+     *
+     * @hide
+     */
+    public static <T extends Enum<T>> void registerEnumValues(Class<T> enumType, int[] values) {
+        if (enumType.getEnumConstants().length != values.length) {
+            throw new IllegalArgumentException(
+                    "Expected values array to be the same size as the enumTypes values "
+                            + values.length + " for type " + enumType);
+        }
+
+        Log.v(TAG, "Registered enum values for type " + enumType + " values");
+
+        sEnumValues.put(enumType, values);
+    }
+
+    /**
+     * Get the numeric value from an enum. This is usually the same as the ordinal value for
+     * enums that have fully sequential values, although for C-style enums the range of values
+     * may not map 1:1.
+     *
+     * @param enumValue Enum instance
+     * @return Int guaranteed to be ABI-compatible with the C enum equivalent
+     */
+    private static <T extends Enum<T>> int getEnumValue(T enumValue) {
+        int[] values;
+        values = sEnumValues.get(enumValue.getClass());
+
+        int ordinal = enumValue.ordinal();
+        if (values != null) {
+            return values[ordinal];
+        }
+
+        return ordinal;
+    }
+
+    /**
+     * Finds the enum corresponding to it's numeric value. Opposite of {@link #getEnumValue} method.
+     *
+     * @param enumType Class of the enum we want to find
+     * @param value The numeric value of the enum
+     * @return An instance of the enum
+     */
+    private static <T extends Enum<T>> T getEnumFromValue(Class<T> enumType, int value) {
+        int ordinal;
+
+        int[] registeredValues = sEnumValues.get(enumType);
+        if (registeredValues != null) {
+            ordinal = -1;
+
+            for (int i = 0; i < registeredValues.length; ++i) {
+                if (registeredValues[i] == value) {
+                    ordinal = i;
+                    break;
+                }
+            }
+        } else {
+            ordinal = value;
+        }
+
+        T[] values = enumType.getEnumConstants();
+
+        if (ordinal < 0 || ordinal >= values.length) {
+            throw new IllegalArgumentException(
+                    String.format(
+                            "Argument 'value' (%d) was not a valid enum value for type %s "
+                                    + "(registered? %b)",
+                            value,
+                            enumType, (registeredValues != null)));
+        }
+
+        return values[ordinal];
+    }
+
+    static HashMap<Class<?>, MetadataMarshalClass<?>> sMarshalerMap = new
+            HashMap<Class<?>, MetadataMarshalClass<?>>();
+
+    private static <T> void registerMarshaler(MetadataMarshalClass<T> marshaler) {
+        sMarshalerMap.put(marshaler.getMarshalingClass(), marshaler);
+    }
+
+    @SuppressWarnings("unchecked")
+    private static <T> MetadataMarshalClass<T> getMarshaler(Class<T> type, int nativeType) {
+        MetadataMarshalClass<T> marshaler = (MetadataMarshalClass<T>) sMarshalerMap.get(type);
+
+        if (marshaler != null && !marshaler.isNativeTypeSupported(nativeType)) {
+            throw new UnsupportedOperationException("Unsupported type " + nativeType +
+                    " to be marshalled to/from a " + type);
+        }
+
+        return marshaler;
+    }
+
+    /**
+     * We use a class initializer to allow the native code to cache some field offsets
+     */
+    static {
+        System.loadLibrary("media_jni");
+        nativeClassInit();
+
+        Log.v(TAG, "Shall register metadata marshalers");
+
+        // load built-in marshallers
+        registerMarshaler(new MetadataMarshalRect());
+        registerMarshaler(new MetadataMarshalSize());
+        registerMarshaler(new MetadataMarshalString());
+
+        Log.v(TAG, "Registered metadata marshalers");
+    }
+
+}
diff --git a/core/java/android/hardware/camera2/impl/MetadataMarshalClass.java b/core/java/android/hardware/camera2/impl/MetadataMarshalClass.java
new file mode 100644
index 0000000..6d224ef
--- /dev/null
+++ b/core/java/android/hardware/camera2/impl/MetadataMarshalClass.java
@@ -0,0 +1,67 @@
+/*
+ * 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.hardware.camera2.impl;
+
+import java.nio.ByteBuffer;
+
+public interface MetadataMarshalClass<T> {
+
+    /**
+     * Marshal the specified object instance (value) into a byte buffer.
+     *
+     * @param value the value of type T that we wish to write into the byte buffer
+     * @param buffer the byte buffer into which the marshalled object will be written
+     * @param nativeType the native type, e.g.
+     *        {@link android.hardware.camera2.impl.CameraMetadataNative#TYPE_BYTE TYPE_BYTE}.
+     *        Guaranteed to be one for which isNativeTypeSupported returns true.
+     * @param sizeOnly if this is true, don't write to the byte buffer. calculate the size only.
+     * @return the size that needs to be written to the byte buffer
+     */
+    int marshal(T value, ByteBuffer buffer, int nativeType, boolean sizeOnly);
+
+    /**
+     * Unmarshal a new object instance from the byte buffer.
+     * @param buffer the byte buffer, from which we will read the object
+     * @param nativeType the native type, e.g.
+     *        {@link android.hardware.camera2.impl.CameraMetadataNative#TYPE_BYTE TYPE_BYTE}.
+     *        Guaranteed to be one for which isNativeTypeSupported returns true.
+     * @return a new instance of type T read from the byte buffer
+     */
+    T unmarshal(ByteBuffer buffer, int nativeType);
+
+    Class<T> getMarshalingClass();
+
+    /**
+     * Determines whether or not this marshaller supports this native type. Most marshallers
+     * will are likely to only support one type.
+     *
+     * @param nativeType the native type, e.g.
+     *        {@link android.hardware.camera2.impl.CameraMetadataNative#TYPE_BYTE TYPE_BYTE}
+     * @return true if it supports, false otherwise
+     */
+    boolean isNativeTypeSupported(int nativeType);
+
+    public static int NATIVE_SIZE_DYNAMIC = -1;
+
+    /**
+     * How many bytes T will take up if marshalled to/from nativeType
+     * @param nativeType the native type, e.g.
+     *        {@link android.hardware.camera2.impl.CameraMetadataNative#TYPE_BYTE TYPE_BYTE}
+     * @return a size in bytes, or NATIVE_SIZE_DYNAMIC if the size is dynamic
+     */
+    int getNativeSize(int nativeType);
+}
diff --git a/core/java/android/hardware/camera2/impl/MetadataMarshalRect.java b/core/java/android/hardware/camera2/impl/MetadataMarshalRect.java
new file mode 100644
index 0000000..ab72c4f
--- /dev/null
+++ b/core/java/android/hardware/camera2/impl/MetadataMarshalRect.java
@@ -0,0 +1,67 @@
+/*
+ * 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.hardware.camera2.impl;
+
+import android.graphics.Rect;
+
+import java.nio.ByteBuffer;
+
+public class MetadataMarshalRect implements MetadataMarshalClass<Rect> {
+    private static final int SIZE = 16;
+
+    @Override
+    public int marshal(Rect value, ByteBuffer buffer, int nativeType, boolean sizeOnly) {
+        if (sizeOnly) {
+            return SIZE;
+        }
+
+        buffer.putInt(value.left);
+        buffer.putInt(value.top);
+        buffer.putInt(value.width());
+        buffer.putInt(value.height());
+
+        return SIZE;
+    }
+
+    @Override
+    public Rect unmarshal(ByteBuffer buffer, int nativeType) {
+
+        int left = buffer.getInt();
+        int top = buffer.getInt();
+        int width = buffer.getInt();
+        int height = buffer.getInt();
+
+        int right = left + width;
+        int bottom = top + height;
+
+        return new Rect(left, top, right, bottom);
+    }
+
+    @Override
+    public Class<Rect> getMarshalingClass() {
+        return Rect.class;
+    }
+
+    @Override
+    public boolean isNativeTypeSupported(int nativeType) {
+        return nativeType == CameraMetadataNative.TYPE_INT32;
+    }
+
+    @Override
+    public int getNativeSize(int nativeType) {
+        return SIZE;
+    }
+}
diff --git a/core/java/android/hardware/camera2/impl/MetadataMarshalSize.java b/core/java/android/hardware/camera2/impl/MetadataMarshalSize.java
new file mode 100644
index 0000000..e8143e0
--- /dev/null
+++ b/core/java/android/hardware/camera2/impl/MetadataMarshalSize.java
@@ -0,0 +1,60 @@
+/*
+ * 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.hardware.camera2.impl;
+
+import android.hardware.camera2.Size;
+
+import java.nio.ByteBuffer;
+
+public class MetadataMarshalSize implements MetadataMarshalClass<Size> {
+
+    private static final int SIZE = 8;
+
+    @Override
+    public int marshal(Size value, ByteBuffer buffer, int nativeType, boolean sizeOnly) {
+        if (sizeOnly) {
+            return SIZE;
+        }
+
+        buffer.putInt(value.getWidth());
+        buffer.putInt(value.getHeight());
+
+        return SIZE;
+    }
+
+    @Override
+    public Size unmarshal(ByteBuffer buffer, int nativeType) {
+        int width = buffer.getInt();
+        int height = buffer.getInt();
+
+        return new Size(width, height);
+    }
+
+    @Override
+    public Class<Size> getMarshalingClass() {
+        return Size.class;
+    }
+
+    @Override
+    public boolean isNativeTypeSupported(int nativeType) {
+        return nativeType == CameraMetadataNative.TYPE_INT32;
+    }
+
+    @Override
+    public int getNativeSize(int nativeType) {
+        return SIZE;
+    }
+}
diff --git a/core/java/android/hardware/camera2/impl/MetadataMarshalString.java b/core/java/android/hardware/camera2/impl/MetadataMarshalString.java
new file mode 100644
index 0000000..b61b8d3
--- /dev/null
+++ b/core/java/android/hardware/camera2/impl/MetadataMarshalString.java
@@ -0,0 +1,79 @@
+/*
+ * 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.hardware.camera2.impl;
+
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+
+public class MetadataMarshalString implements MetadataMarshalClass<String> {
+
+    private static final Charset UTF8_CHARSET = Charset.forName("UTF-8");
+
+    @Override
+    public int marshal(String value, ByteBuffer buffer, int nativeType, boolean sizeOnly) {
+        byte[] arr = value.getBytes(UTF8_CHARSET);
+
+        if (!sizeOnly) {
+            buffer.put(arr);
+            buffer.put((byte)0); // metadata strings are NULL-terminated
+        }
+
+        return arr.length + 1;
+    }
+
+    @Override
+    public String unmarshal(ByteBuffer buffer, int nativeType) {
+
+        buffer.mark(); // save the current position
+
+        boolean foundNull = false;
+        int stringLength = 0;
+        while (buffer.hasRemaining()) {
+            if (buffer.get() == (byte)0) {
+                foundNull = true;
+                break;
+            }
+
+            stringLength++;
+        }
+        if (!foundNull) {
+            throw new IllegalArgumentException("Strings must be null-terminated");
+        }
+
+        buffer.reset(); // go back to the previously marked position
+
+        byte[] strBytes = new byte[stringLength + 1];
+        buffer.get(strBytes, /*dstOffset*/0, stringLength + 1); // including null character
+
+        // not including null character
+        return new String(strBytes, /*offset*/0, stringLength, UTF8_CHARSET);
+    }
+
+    @Override
+    public Class<String> getMarshalingClass() {
+        return String.class;
+    }
+
+    @Override
+    public boolean isNativeTypeSupported(int nativeType) {
+        return nativeType == CameraMetadataNative.TYPE_BYTE;
+    }
+
+    @Override
+    public int getNativeSize(int nativeType) {
+        return NATIVE_SIZE_DYNAMIC;
+    }
+}
diff --git a/core/java/android/hardware/camera2/impl/package.html b/core/java/android/hardware/camera2/impl/package.html
new file mode 100644
index 0000000..783d0a1
--- /dev/null
+++ b/core/java/android/hardware/camera2/impl/package.html
@@ -0,0 +1,3 @@
+<body>
+{@hide}
+</body>
diff --git a/core/java/android/hardware/camera2/package.html b/core/java/android/hardware/camera2/package.html
new file mode 100644
index 0000000..e9d9cea
--- /dev/null
+++ b/core/java/android/hardware/camera2/package.html
@@ -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.
+-->
+<HTML>
+<BODY>
+<p>The android.hardware.camera2 package provides an interface to
+individual camera devices connected to an Android device. It replaces
+the deprecated {@link android.hardware.Camera} class.</p>
+
+<p>This package models a camera device as a pipeline, which takes in
+input requests for capturing a single frame, captures the single image
+per the request, and then outputs one capture result metadata packet,
+plus a set of output image buffers for the request. The requests are
+processed in-order, and multiple requests can be in flight at
+once. Since the camera device is a pipeline with multiple stages,
+having multiple requests in flight is required to maintain full
+framerate on most Android devices.</p>
+
+<p>To enumerate, query, and open available camera devices, obtain a
+{@link android.hardware.camera2.CameraManager} instance.</p>
+
+<p>Individual {@link android.hardware.camera2.CameraDevice
+CameraDevices} provide a set of static property information that
+describes the hardware device and the available settings and output
+parameters for the device. This information is provided through the
+{@link android.hardware.camera2.CameraProperties} object.</p>
+
+<p>To capture or stream images from a camera device, the application
+must first configure a set of output Surfaces for use with the camera
+device, with {@link
+android.hardware.camera2.CameraDevice#configureOutputs}. Each
+Surface has to be pre-configured with an appropriate size and format
+(if applicable) to match the sizes and formats available from the
+camera device. A target Surface can be obtained from a variety of
+classes, including {@link android.view.SurfaceView}, {@link
+android.graphics.SurfaceTexture} via {@link
+android.view.Surface#Surface(SurfaceTexture), {@link
+android.media.MediaCodec}, and {@link android.media.ImageReader}.
+</p>
+
+<p>The application then needs to construct a {@link
+android.hardware.camera2.CaptureRequest}, which defines all the
+capture parameters needed by a camera device to capture a single
+image. The request also lists which of the configured output Surfaces
+should be used as targets for this capture. The CameraDevice has a
+{@link android.hardware.camera2.CameraDevice#createCaptureRequest
+convenience factory method} for creating a request for a given use
+case which is optimized for the Android device the application is
+running on.</p>
+
+<p>Once the request has been set up, it can be handed to the
+CameraDevice either for a one-shot {@link
+android.hardware.camera2.CameraDevice#capture} or for an endlessly
+{@link android.hardware.camera2.CameraDevice#setRepeatingRequest
+repeating} use. Both methods also accept a list of requests to use as
+a burst capture / repeating burst. Repeating requests have a lower
+priority than captures, so a request submitted
+through <code>capture()</code> while there's a repeating request
+configured will be captured as soon as the current repeat (burst)
+capture completes.</p>
+
+<p>After processing a request, the camera device will produce a {@link
+android.hardware.camera2.CaptureResult} object, which contains
+information about the state of the camera device at time of capture,
+and the final settings used. These may vary somewhat from the request,
+if rounding or resolving contradictory parameters was necessary. The
+camera device will also send a frame of image data into each of the
+output streams included in the request. These are produced
+asynchronously relative to the output CaptureResult, sometimes
+substantially later.</p>
+
+</BODY>
+</HTML>
diff --git a/core/java/android/hardware/camera2/utils/BinderHolder.aidl b/core/java/android/hardware/camera2/utils/BinderHolder.aidl
new file mode 100644
index 0000000..f39d645
--- /dev/null
+++ b/core/java/android/hardware/camera2/utils/BinderHolder.aidl
@@ -0,0 +1,20 @@
+/*
+ * 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.hardware.camera2.utils;
+
+/** @hide */
+parcelable BinderHolder;
diff --git a/core/java/android/hardware/camera2/utils/BinderHolder.java b/core/java/android/hardware/camera2/utils/BinderHolder.java
new file mode 100644
index 0000000..9eea390
--- /dev/null
+++ b/core/java/android/hardware/camera2/utils/BinderHolder.java
@@ -0,0 +1,74 @@
+/*
+ * 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.hardware.camera2.utils;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.IBinder;
+
+/**
+ * @hide
+ */
+public class BinderHolder implements Parcelable {
+    private IBinder mBinder = null;
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeStrongBinder(mBinder);
+    }
+
+    public void readFromParcel(Parcel src) {
+        mBinder = src.readStrongBinder();
+    }
+
+    public static final Parcelable.Creator<BinderHolder> CREATOR =
+             new Parcelable.Creator<BinderHolder>() {
+         @Override
+         public BinderHolder createFromParcel(Parcel in) {
+             return new BinderHolder(in);
+         }
+
+         @Override
+         public BinderHolder[] newArray(int size) {
+             return new BinderHolder[size];
+         }
+    };
+
+    public IBinder getBinder() {
+        return mBinder;
+    }
+
+    public void setBinder(IBinder binder) {
+        mBinder = binder;
+    }
+
+    public BinderHolder() {}
+
+    public BinderHolder(IBinder binder) {
+        mBinder = binder;
+    }
+
+    private BinderHolder(Parcel in) {
+        mBinder = in.readStrongBinder();
+    }
+}
+
diff --git a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java b/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
new file mode 100644
index 0000000..2c05c58
--- /dev/null
+++ b/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
@@ -0,0 +1,150 @@
+/*
+ * 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.hardware.camera2.utils;
+
+import static android.hardware.camera2.CameraAccessException.CAMERA_DISABLED;
+import static android.hardware.camera2.CameraAccessException.CAMERA_DISCONNECTED;
+import static android.hardware.camera2.CameraAccessException.CAMERA_IN_USE;
+import static android.hardware.camera2.CameraAccessException.CAMERA_DEPRECATED_HAL;
+
+import android.os.DeadObjectException;
+import android.os.RemoteException;
+
+import java.lang.reflect.Method;
+
+/**
+ * Translate camera service status_t return values into exceptions.
+ *
+ * @see android.hardware.camera2.utils.CameraBinderDecorator#newInstance
+ * @hide
+ */
+public class CameraBinderDecorator {
+
+    public static final int NO_ERROR = 0;
+    public static final int PERMISSION_DENIED = -1;
+    public static final int ALREADY_EXISTS = -17;
+    public static final int BAD_VALUE = -22;
+    public static final int DEAD_OBJECT = -32;
+
+    /**
+     * TODO: add as error codes in Errors.h
+     * - POLICY_PROHIBITS
+     * - RESOURCE_BUSY
+     * - NO_SUCH_DEVICE
+     */
+    public static final int EACCES = -13;
+    public static final int EBUSY = -16;
+    public static final int ENODEV = -19;
+    public static final int EOPNOTSUPP = -95;
+
+    private static class CameraBinderDecoratorListener implements Decorator.DecoratorListener {
+
+        @Override
+        public void onBeforeInvocation(Method m, Object[] args) {
+        }
+
+        @Override
+        public void onAfterInvocation(Method m, Object[] args, Object result) {
+            // int return type => status_t => convert to exception
+            if (m.getReturnType() == Integer.TYPE) {
+                int returnValue = (Integer) result;
+
+                switch (returnValue) {
+                    case NO_ERROR:
+                        return;
+                    case PERMISSION_DENIED:
+                        throw new SecurityException("Lacking privileges to access camera service");
+                    case ALREADY_EXISTS:
+                        // This should be handled at the call site. Typically this isn't bad,
+                        // just means we tried to do an operation that already completed.
+                        return;
+                    case BAD_VALUE:
+                        throw new IllegalArgumentException("Bad argument passed to camera service");
+                    case DEAD_OBJECT:
+                        UncheckedThrow.throwAnyException(new CameraRuntimeException(
+                                CAMERA_DISCONNECTED));
+                    case EACCES:
+                        UncheckedThrow.throwAnyException(new CameraRuntimeException(
+                                CAMERA_DISABLED));
+                    case EBUSY:
+                        UncheckedThrow.throwAnyException(new CameraRuntimeException(
+                                CAMERA_IN_USE));
+                    case ENODEV:
+                        UncheckedThrow.throwAnyException(new CameraRuntimeException(
+                                CAMERA_DISCONNECTED));
+                    case EOPNOTSUPP:
+                        UncheckedThrow.throwAnyException(new CameraRuntimeException(
+                                CAMERA_DEPRECATED_HAL));
+                }
+
+                /**
+                 * Trap the rest of the negative return values. If we have known
+                 * error codes i.e. ALREADY_EXISTS that aren't really runtime
+                 * errors, then add them to the top switch statement
+                 */
+                if (returnValue < 0) {
+                    throw new UnsupportedOperationException(String.format("Unknown error %d",
+                            returnValue));
+                }
+            }
+        }
+
+        @Override
+        public boolean onCatchException(Method m, Object[] args, Throwable t) {
+
+            if (t instanceof DeadObjectException) {
+                UncheckedThrow.throwAnyException(new CameraRuntimeException(
+                        CAMERA_DISCONNECTED,
+                        "Process hosting the camera service has died unexpectedly",
+                        t));
+            } else if (t instanceof RemoteException) {
+                throw new UnsupportedOperationException("An unknown RemoteException was thrown" +
+                        " which should never happen.", t);
+            }
+
+            return false;
+        }
+
+        @Override
+        public void onFinally(Method m, Object[] args) {
+        }
+
+    }
+
+    /**
+     * <p>
+     * Wraps the type T with a proxy that will check 'status_t' return codes
+     * from the native side of the camera service, and throw Java exceptions
+     * automatically based on the code.
+     * </p>
+     * <p>
+     * In addition it also rewrites binder's RemoteException into either a
+     * CameraAccessException or an UnsupportedOperationException.
+     * </p>
+     * <p>
+     * As a result of calling any method on the proxy, RemoteException is
+     * guaranteed never to be thrown.
+     * </p>
+     *
+     * @param obj object that will serve as the target for all method calls
+     * @param <T> the type of the element you want to wrap. This must be an interface.
+     * @return a proxy that will intercept all invocations to obj
+     */
+    public static <T> T newInstance(T obj) {
+        return Decorator.<T> newInstance(obj, new CameraBinderDecoratorListener());
+    }
+}
diff --git a/core/java/android/hardware/camera2/utils/CameraRuntimeException.java b/core/java/android/hardware/camera2/utils/CameraRuntimeException.java
new file mode 100644
index 0000000..9ed88a9
--- /dev/null
+++ b/core/java/android/hardware/camera2/utils/CameraRuntimeException.java
@@ -0,0 +1,63 @@
+package android.hardware.camera2.utils;
+
+import android.hardware.camera2.CameraAccessException;
+
+/**
+ * @hide
+ */
+public class CameraRuntimeException extends RuntimeException {
+
+    private final int mReason;
+    private String mMessage;
+    private Throwable mCause;
+
+    public final int getReason() {
+        return mReason;
+    }
+
+    public CameraRuntimeException(int problem) {
+        super();
+        mReason = problem;
+    }
+
+    public CameraRuntimeException(int problem, String message) {
+        super(message);
+        mReason = problem;
+        mMessage = message;
+    }
+
+    public CameraRuntimeException(int problem, String message, Throwable cause) {
+        super(message, cause);
+        mReason = problem;
+        mMessage = message;
+        mCause = cause;
+    }
+
+    public CameraRuntimeException(int problem, Throwable cause) {
+        super(cause);
+        mReason = problem;
+        mCause = cause;
+    }
+
+    /**
+     * Recreate this exception as the CameraAccessException equivalent.
+     * @return CameraAccessException
+     */
+    public CameraAccessException asChecked() {
+        CameraAccessException e;
+
+        if (mMessage != null && mCause != null) {
+            e = new CameraAccessException(mReason, mMessage, mCause);
+        } else if (mMessage != null) {
+            e = new CameraAccessException(mReason, mMessage);
+        } else if (mCause != null) {
+            e = new CameraAccessException(mReason, mCause);
+        } else {
+            e = new CameraAccessException(mReason);
+        }
+        // throw and catch, so java has a chance to fill out the stack trace
+        e.setStackTrace(this.getStackTrace());
+
+        return e;
+    }
+}
diff --git a/core/java/android/hardware/camera2/utils/Decorator.java b/core/java/android/hardware/camera2/utils/Decorator.java
new file mode 100644
index 0000000..5826497
--- /dev/null
+++ b/core/java/android/hardware/camera2/utils/Decorator.java
@@ -0,0 +1,92 @@
+
+package android.hardware.camera2.utils;
+
+import java.lang.reflect.*;
+
+/**
+ * This is an implementation of the 'decorator' design pattern using Java's proxy mechanism.
+ *
+ * @see android.hardware.camera2.utils.Decorator#newInstance
+ *
+ * @hide
+ */
+public class Decorator<T> implements InvocationHandler {
+
+    public interface DecoratorListener {
+        /**
+         * This method is called before the target method is invoked
+         * @param args arguments to target method
+         * @param m Method being called
+         */
+        void onBeforeInvocation(Method m, Object[] args);
+        /**
+         * This function is called after the target method is invoked
+         * if there were no uncaught exceptions
+         * @param args arguments to target method
+         * @param m Method being called
+         * @param result return value of target method
+         */
+        void onAfterInvocation(Method m, Object[] args, Object result);
+        /**
+         * This method is called only if there was an exception thrown by the target method
+         * during its invocation.
+         *
+         * @param args arguments to target method
+         * @param m Method being called
+         * @param t Throwable that was thrown
+         * @return false to rethrow exception, true if the exception was handled
+         */
+        boolean onCatchException(Method m, Object[] args, Throwable t);
+        /**
+         * This is called after the target method is invoked, regardless of whether or not
+         * there were any exceptions.
+         * @param args arguments to target method
+         * @param m Method being called
+         */
+        void onFinally(Method m, Object[] args);
+    }
+
+    private final T mObject;
+    private final DecoratorListener mListener;
+
+    /**
+     * Create a decorator wrapping the specified object's method calls.
+     *
+     * @param obj the object whose method calls you want to intercept
+     * @param listener the decorator handler for intercepted method calls
+     * @param <T> the type of the element you want to wrap. This must be an interface.
+     * @return a wrapped interface-compatible T
+     */
+    @SuppressWarnings("unchecked")
+    public static<T> T newInstance(T obj, DecoratorListener listener) {
+        return (T)java.lang.reflect.Proxy.newProxyInstance(
+                obj.getClass().getClassLoader(),
+                obj.getClass().getInterfaces(),
+                new Decorator<T>(obj, listener));
+    }
+
+    private Decorator(T obj, DecoratorListener listener) {
+        this.mObject = obj;
+        this.mListener = listener;
+    }
+
+    @Override
+    public Object invoke(Object proxy, Method m, Object[] args)
+            throws Throwable
+    {
+        Object result = null;
+        try {
+            mListener.onBeforeInvocation(m, args);
+            result = m.invoke(mObject, args);
+            mListener.onAfterInvocation(m, args, result);
+        } catch (InvocationTargetException e) {
+            Throwable t = e.getTargetException();
+            if (!mListener.onCatchException(m, args, t)) {
+                throw t;
+            }
+        } finally {
+            mListener.onFinally(m, args);
+        }
+        return result;
+    }
+}
diff --git a/core/java/android/hardware/camera2/utils/UncheckedThrow.java b/core/java/android/hardware/camera2/utils/UncheckedThrow.java
new file mode 100644
index 0000000..8224fed
--- /dev/null
+++ b/core/java/android/hardware/camera2/utils/UncheckedThrow.java
@@ -0,0 +1,40 @@
+/*
+ * 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.hardware.camera2.utils;
+
+/**
+ * @hide
+ */
+public class UncheckedThrow {
+
+    /**
+     * Throw any kind of exception without needing it to be checked
+     * @param e any instance of a Exception
+     */
+    public static void throwAnyException(Exception e) {
+        /**
+         *  Abuse type erasure by making the compiler think we are throwing RuntimeException,
+         *  which is unchecked, but then inserting any exception in there.
+         */
+        UncheckedThrow.<RuntimeException>throwAnyImpl(e);
+    }
+
+    @SuppressWarnings("unchecked")
+    private static<T extends Exception> void throwAnyImpl(Exception e) throws T {
+        throw (T) e;
+    }
+}
diff --git a/core/java/android/hardware/camera2/utils/package.html b/core/java/android/hardware/camera2/utils/package.html
new file mode 100644
index 0000000..783d0a1
--- /dev/null
+++ b/core/java/android/hardware/camera2/utils/package.html
@@ -0,0 +1,3 @@
+<body>
+{@hide}
+</body>
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index 0a7a2e7..f12be5f 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -20,6 +20,7 @@
 import android.os.Handler;
 import android.util.SparseArray;
 import android.view.Display;
+import android.view.Surface;
 
 import java.util.ArrayList;
 
@@ -68,16 +69,108 @@
      * Display category: Presentation displays.
      * <p>
      * This category can be used to identify secondary displays that are suitable for
-     * use as presentation displays.
+     * use as presentation displays such as HDMI or Wireless displays.  Applications
+     * may automatically project their content to presentation displays to provide
+     * richer second screen experiences.
      * </p>
      *
-     * @see android.app.Presentation for information about presenting content
-     * on secondary displays.
+     * @see android.app.Presentation
+     * @see Display#FLAG_PRESENTATION
      * @see #getDisplays(String)
      */
     public static final String DISPLAY_CATEGORY_PRESENTATION =
             "android.hardware.display.category.PRESENTATION";
 
+    /**
+     * Virtual display flag: Create a public display.
+     *
+     * <h3>Public virtual displays</h3>
+     * <p>
+     * When this flag is set, the virtual display is public.
+     * </p><p>
+     * A public virtual display behaves just like most any other display that is connected
+     * to the system such as an HDMI or Wireless display.  Applications can open
+     * windows on the display and the system may mirror the contents of other displays
+     * onto it.
+     * </p><p>
+     * Creating a public virtual display requires the
+     * {@link android.Manifest.permission#CAPTURE_VIDEO_OUTPUT}
+     * or {@link android.Manifest.permission#CAPTURE_SECURE_VIDEO_OUTPUT} permission.
+     * These permissions are reserved for use by system components and are not available to
+     * third-party applications.
+     * </p>
+     *
+     * <h3>Private virtual displays</h3>
+     * <p>
+     * When this flag is not set, the virtual display is private as defined by the
+     * {@link Display#FLAG_PRIVATE} display flag.
+     * </p>
+     * A private virtual display belongs to the application that created it.
+     * Only the a owner of a private virtual display is allowed to place windows upon it.
+     * The private virtual display also does not participate in display mirroring: it will
+     * neither receive mirrored content from another display nor allow its own content to
+     * be mirrored elsewhere.  More precisely, the only processes that are allowed to
+     * enumerate or interact with the private display are those that have the same UID as the
+     * application that originally created the private virtual display.
+      * </p>
+     *
+     * @see #createVirtualDisplay
+     */
+    public static final int VIRTUAL_DISPLAY_FLAG_PUBLIC = 1 << 0;
+
+    /**
+     * Virtual display flag: Create a presentation display.
+     *
+     * <h3>Presentation virtual displays</h3>
+     * <p>
+     * When this flag is set, the virtual display is registered as a presentation
+     * display in the {@link #DISPLAY_CATEGORY_PRESENTATION presentation display category}.
+     * Applications may automatically project their content to presentation displays
+     * to provide richer second screen experiences.
+     * </p>
+     *
+     * <h3>Non-presentation virtual displays</h3>
+     * <p>
+     * When this flag is not set, the virtual display is not registered as a presentation
+     * display.  Applications can still project their content on the display but they
+     * will typically not do so automatically.  This option is appropriate for
+     * more special-purpose displays.
+     * </p>
+     *
+     * @see android.app.Presentation
+     * @see #createVirtualDisplay
+     * @see #DISPLAY_CATEGORY_PRESENTATION
+     * @see Display#FLAG_PRESENTATION
+     */
+    public static final int VIRTUAL_DISPLAY_FLAG_PRESENTATION = 1 << 1;
+
+    /**
+     * Virtual display flag: Create a secure display.
+     *
+     * <h3>Secure virtual displays</h3>
+     * <p>
+     * When this flag is set, the virtual display is considered secure as defined
+     * by the {@link Display#FLAG_SECURE} display flag.  The caller promises to take
+     * reasonable measures, such as over-the-air encryption, to prevent the contents
+     * of the display from being intercepted or recorded on a persistent medium.
+     * </p><p>
+     * Creating a secure virtual display requires the
+     * {@link android.Manifest.permission#CAPTURE_SECURE_VIDEO_OUTPUT} permission.
+     * This permission is reserved for use by system components and is not available to
+     * third-party applications.
+     * </p>
+     *
+     * <h3>Non-secure virtual displays</h3>
+     * <p>
+     * When this flag is not set, the virtual display is considered unsecure.
+     * The content of secure windows will be blanked if shown on this display.
+     * </p>
+     *
+     * @see Display#FLAG_SECURE
+     * @see #createVirtualDisplay
+     */
+    public static final int VIRTUAL_DISPLAY_FLAG_SECURE = 1 << 2;
+
     /** @hide */
     public DisplayManager(Context context) {
         mContext = context;
@@ -129,11 +222,12 @@
         synchronized (mLock) {
             try {
                 if (category == null) {
-                    addMatchingDisplaysLocked(mTempDisplays, displayIds, -1);
+                    addAllDisplaysLocked(mTempDisplays, displayIds);
                 } else if (category.equals(DISPLAY_CATEGORY_PRESENTATION)) {
-                    addMatchingDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_WIFI);
-                    addMatchingDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_HDMI);
-                    addMatchingDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_OVERLAY);
+                    addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_WIFI);
+                    addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_HDMI);
+                    addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_OVERLAY);
+                    addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_VIRTUAL);
                 }
                 return mTempDisplays.toArray(new Display[mTempDisplays.size()]);
             } finally {
@@ -142,12 +236,22 @@
         }
     }
 
-    private void addMatchingDisplaysLocked(
+    private void addAllDisplaysLocked(ArrayList<Display> displays, int[] displayIds) {
+        for (int i = 0; i < displayIds.length; i++) {
+            Display display = getOrCreateDisplayLocked(displayIds[i], true /*assumeValid*/);
+            if (display != null) {
+                displays.add(display);
+            }
+        }
+    }
+
+    private void addPresentationDisplaysLocked(
             ArrayList<Display> displays, int[] displayIds, int matchType) {
         for (int i = 0; i < displayIds.length; i++) {
             Display display = getOrCreateDisplayLocked(displayIds[i], true /*assumeValid*/);
             if (display != null
-                    && (matchType < 0 || display.getType() == matchType)) {
+                    && (display.getFlags() & Display.FLAG_PRESENTATION) != 0
+                    && display.getType() == matchType) {
                 displays.add(display);
             }
         }
@@ -157,7 +261,7 @@
         Display display = mDisplays.get(displayId);
         if (display == null) {
             display = mGlobal.getCompatibleDisplay(displayId,
-                    mContext.getCompatibilityInfo(displayId));
+                    mContext.getDisplayAdjustments(displayId));
             if (display != null) {
                 mDisplays.put(displayId, display);
             }
@@ -219,6 +323,16 @@
         mGlobal.connectWifiDisplay(deviceAddress);
     }
 
+    /** @hide */
+    public void pauseWifiDisplay() {
+        mGlobal.pauseWifiDisplay();
+    }
+
+    /** @hide */
+    public void resumeWifiDisplay() {
+        mGlobal.resumeWifiDisplay();
+    }
+
     /**
      * Disconnects from the current Wifi display.
      * The results are sent as a {@link #ACTION_WIFI_DISPLAY_STATUS_CHANGED} broadcast.
@@ -275,6 +389,43 @@
     }
 
     /**
+     * Creates a virtual display.
+     * <p>
+     * The content of a virtual display is rendered to a {@link Surface} provided
+     * by the application.
+     * </p><p>
+     * The virtual display should be {@link VirtualDisplay#release released}
+     * when no longer needed.  Because a virtual display renders to a surface
+     * provided by the application, it will be released automatically when the
+     * process terminates and all remaining windows on it will be forcibly removed.
+     * </p><p>
+     * The behavior of the virtual display depends on the flags that are provided
+     * to this method.  By default, virtual displays are created to be private,
+     * non-presentation and unsecure.  Permissions may be required to use certain flags.
+     * </p>
+     *
+     * @param name The name of the virtual display, must be non-empty.
+     * @param width The width of the virtual display in pixels, must be greater than 0.
+     * @param height The height of the virtual display in pixels, must be greater than 0.
+     * @param densityDpi The density of the virtual display in dpi, must be greater than 0.
+     * @param surface The surface to which the content of the virtual display should
+     * be rendered, must be non-null.
+     * @param flags A combination of virtual display flags:
+     * {@link #VIRTUAL_DISPLAY_FLAG_PUBLIC}, {@link #VIRTUAL_DISPLAY_FLAG_PRESENTATION}
+     * or {@link #VIRTUAL_DISPLAY_FLAG_SECURE}.
+     * @return The newly created virtual display, or null if the application could
+     * not create the virtual display.
+     *
+     * @throws SecurityException if the caller does not have permission to create
+     * a virtual display with the specified flags.
+     */
+    public VirtualDisplay createVirtualDisplay(String name,
+            int width, int height, int densityDpi, Surface surface, int flags) {
+        return mGlobal.createVirtualDisplay(mContext,
+                name, width, height, densityDpi, surface, flags);
+    }
+
+    /**
      * Listens for changes in available display devices.
      */
     public interface DisplayListener {
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java
index a858681..936a086 100644
--- a/core/java/android/hardware/display/DisplayManagerGlobal.java
+++ b/core/java/android/hardware/display/DisplayManagerGlobal.java
@@ -18,17 +18,20 @@
 
 import android.content.Context;
 import android.hardware.display.DisplayManager.DisplayListener;
+import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.text.TextUtils;
 import android.util.Log;
 import android.util.SparseArray;
-import android.view.CompatibilityInfoHolder;
+import android.view.DisplayAdjustments;
 import android.view.Display;
 import android.view.DisplayInfo;
+import android.view.Surface;
 
 import java.util.ArrayList;
 
@@ -161,18 +164,18 @@
      * Gets information about a logical display.
      *
      * The display metrics may be adjusted to provide compatibility
-     * for legacy applications.
+     * for legacy applications or limited screen areas.
      *
      * @param displayId The logical display id.
-     * @param cih The compatibility info, or null if none is required.
+     * @param daj The compatibility info and activityToken.
      * @return The display object, or null if there is no display with the given id.
      */
-    public Display getCompatibleDisplay(int displayId, CompatibilityInfoHolder cih) {
+    public Display getCompatibleDisplay(int displayId, DisplayAdjustments daj) {
         DisplayInfo displayInfo = getDisplayInfo(displayId);
         if (displayInfo == null) {
             return null;
         }
-        return new Display(this, displayId, displayInfo, cih);
+        return new Display(this, displayId, displayInfo, daj);
     }
 
     /**
@@ -182,7 +185,18 @@
      * @return The display object, or null if there is no display with the given id.
      */
     public Display getRealDisplay(int displayId) {
-        return getCompatibleDisplay(displayId, null);
+        return getCompatibleDisplay(displayId, DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
+    }
+
+    /**
+     * Gets information about a logical display without applying any compatibility metrics.
+     *
+     * @param displayId The logical display id.
+     * @param IBinder the activity token for this display.
+     * @return The display object, or null if there is no display with the given id.
+     */
+    public Display getRealDisplay(int displayId, IBinder token) {
+        return getCompatibleDisplay(displayId, new DisplayAdjustments(token));
     }
 
     public void registerDisplayListener(DisplayListener listener, Handler handler) {
@@ -273,6 +287,22 @@
         }
     }
 
+    public void pauseWifiDisplay() {
+        try {
+            mDm.pauseWifiDisplay();
+        } catch (RemoteException ex) {
+            Log.e(TAG, "Failed to pause Wifi display.", ex);
+        }
+    }
+
+    public void resumeWifiDisplay() {
+        try {
+            mDm.resumeWifiDisplay();
+        } catch (RemoteException ex) {
+            Log.e(TAG, "Failed to resume Wifi display.", ex);
+        }
+    }
+
     public void disconnectWifiDisplay() {
         try {
             mDm.disconnectWifiDisplay();
@@ -315,6 +345,53 @@
         }
     }
 
+    public VirtualDisplay createVirtualDisplay(Context context, String name,
+            int width, int height, int densityDpi, Surface surface, int flags) {
+        if (TextUtils.isEmpty(name)) {
+            throw new IllegalArgumentException("name must be non-null and non-empty");
+        }
+        if (width <= 0 || height <= 0 || densityDpi <= 0) {
+            throw new IllegalArgumentException("width, height, and densityDpi must be "
+                    + "greater than 0");
+        }
+        if (surface == null) {
+            throw new IllegalArgumentException("surface must not be null");
+        }
+
+        Binder token = new Binder();
+        int displayId;
+        try {
+            displayId = mDm.createVirtualDisplay(token, context.getPackageName(),
+                    name, width, height, densityDpi, surface, flags);
+        } catch (RemoteException ex) {
+            Log.e(TAG, "Could not create virtual display: " + name, ex);
+            return null;
+        }
+        if (displayId < 0) {
+            Log.e(TAG, "Could not create virtual display: " + name);
+            return null;
+        }
+        Display display = getRealDisplay(displayId);
+        if (display == null) {
+            Log.wtf(TAG, "Could not obtain display info for newly created "
+                    + "virtual display: " + name);
+            try {
+                mDm.releaseVirtualDisplay(token);
+            } catch (RemoteException ex) {
+            }
+            return null;
+        }
+        return new VirtualDisplay(this, display, token);
+    }
+
+    public void releaseVirtualDisplay(IBinder token) {
+        try {
+            mDm.releaseVirtualDisplay(token);
+        } catch (RemoteException ex) {
+            Log.w(TAG, "Failed to release virtual display.", ex);
+        }
+    }
+
     private final class DisplayManagerCallback extends IDisplayManagerCallback.Stub {
         @Override
         public void onDisplayEvent(int displayId, int event) {
diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl
index 79aad78..6b2c887 100644
--- a/core/java/android/hardware/display/IDisplayManager.aidl
+++ b/core/java/android/hardware/display/IDisplayManager.aidl
@@ -20,6 +20,7 @@
 import android.hardware.display.WifiDisplay;
 import android.hardware.display.WifiDisplayStatus;
 import android.view.DisplayInfo;
+import android.view.Surface;
 
 /** @hide */
 interface IDisplayManager {
@@ -46,4 +47,18 @@
 
     // No permissions required.
     WifiDisplayStatus getWifiDisplayStatus();
+
+    // Requires CAPTURE_VIDEO_OUTPUT or CAPTURE_SECURE_VIDEO_OUTPUT for certain
+    // combinations of flags.
+    int createVirtualDisplay(IBinder token, String packageName,
+            String name, int width, int height, int densityDpi, in Surface surface, int flags);
+
+    // No permissions required but must be same Uid as the creator.
+    void releaseVirtualDisplay(in IBinder token);
+
+    // Requires CONFIGURE_WIFI_DISPLAY permission.
+    void pauseWifiDisplay();
+
+    // Requires CONFIGURE_WIFI_DISPLAY permission.
+    void resumeWifiDisplay();
 }
diff --git a/core/java/android/hardware/display/VirtualDisplay.java b/core/java/android/hardware/display/VirtualDisplay.java
new file mode 100644
index 0000000..908aadd
--- /dev/null
+++ b/core/java/android/hardware/display/VirtualDisplay.java
@@ -0,0 +1,62 @@
+/*
+ * 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.hardware.display;
+
+import android.os.IBinder;
+import android.view.Display;
+
+/**
+ * Represents a virtual display.
+ *
+ * @see DisplayManager#createVirtualDisplay
+ */
+public final class VirtualDisplay {
+    private final DisplayManagerGlobal mGlobal;
+    private final Display mDisplay;
+    private IBinder mToken;
+
+    VirtualDisplay(DisplayManagerGlobal global, Display display, IBinder token) {
+        mGlobal = global;
+        mDisplay = display;
+        mToken = token;
+    }
+
+    /**
+     * Gets the virtual display.
+     */
+    public Display getDisplay() {
+        return mDisplay;
+    }
+
+    /**
+     * Releases the virtual display and destroys its underlying surface.
+     * <p>
+     * All remaining windows on the virtual display will be forcibly removed
+     * as part of releasing the virtual display.
+     * </p>
+     */
+    public void release() {
+        if (mToken != null) {
+            mGlobal.releaseVirtualDisplay(mToken);
+            mToken = null;
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "VirtualDisplay{display=" + mDisplay + ", token=" + mToken + "}";
+    }
+}
diff --git a/core/java/android/hardware/display/WifiDisplay.java b/core/java/android/hardware/display/WifiDisplay.java
index 2fd52b8..af5a84e 100644
--- a/core/java/android/hardware/display/WifiDisplay.java
+++ b/core/java/android/hardware/display/WifiDisplay.java
@@ -33,6 +33,9 @@
     private final String mDeviceAddress;
     private final String mDeviceName;
     private final String mDeviceAlias;
+    private final boolean mIsAvailable;
+    private final boolean mCanConnect;
+    private final boolean mIsRemembered;
 
     public static final WifiDisplay[] EMPTY_ARRAY = new WifiDisplay[0];
 
@@ -41,7 +44,11 @@
             String deviceAddress = in.readString();
             String deviceName = in.readString();
             String deviceAlias = in.readString();
-            return new WifiDisplay(deviceAddress, deviceName, deviceAlias);
+            boolean isAvailable = (in.readInt() != 0);
+            boolean canConnect = (in.readInt() != 0);
+            boolean isRemembered = (in.readInt() != 0);
+            return new WifiDisplay(deviceAddress, deviceName, deviceAlias,
+                    isAvailable, canConnect, isRemembered);
         }
 
         public WifiDisplay[] newArray(int size) {
@@ -49,7 +56,8 @@
         }
     };
 
-    public WifiDisplay(String deviceAddress, String deviceName, String deviceAlias) {
+    public WifiDisplay(String deviceAddress, String deviceName, String deviceAlias,
+            boolean available, boolean canConnect, boolean remembered) {
         if (deviceAddress == null) {
             throw new IllegalArgumentException("deviceAddress must not be null");
         }
@@ -60,6 +68,9 @@
         mDeviceAddress = deviceAddress;
         mDeviceName = deviceName;
         mDeviceAlias = deviceAlias;
+        mIsAvailable = available;
+        mCanConnect = canConnect;
+        mIsRemembered = remembered;
     }
 
     /**
@@ -88,6 +99,27 @@
     }
 
     /**
+     * Returns true if device is available, false otherwise.
+     */
+    public boolean isAvailable() {
+        return mIsAvailable;
+    }
+
+    /**
+     * Returns true if device can be connected to (not in use), false otherwise.
+     */
+    public boolean canConnect() {
+        return mCanConnect;
+    }
+
+    /**
+     * Returns true if device has been remembered, false otherwise.
+     */
+    public boolean isRemembered() {
+        return mIsRemembered;
+    }
+
+    /**
      * Gets the name to show in the UI.
      * Uses the device alias if available, otherwise uses the device name.
      */
@@ -100,6 +132,10 @@
         return o instanceof WifiDisplay && equals((WifiDisplay)o);
     }
 
+    /**
+     * Returns true if the two displays have the same identity (address, name and alias).
+     * This method does not compare the current status of the displays.
+     */
     public boolean equals(WifiDisplay other) {
         return other != null
                 && mDeviceAddress.equals(other.mDeviceAddress)
@@ -127,6 +163,9 @@
         dest.writeString(mDeviceAddress);
         dest.writeString(mDeviceName);
         dest.writeString(mDeviceAlias);
+        dest.writeInt(mIsAvailable ? 1 : 0);
+        dest.writeInt(mCanConnect ? 1 : 0);
+        dest.writeInt(mIsRemembered ? 1 : 0);
     }
 
     @Override
@@ -141,6 +180,8 @@
         if (mDeviceAlias != null) {
             result += ", alias " + mDeviceAlias;
         }
+        result += ", isAvailable " + mIsAvailable + ", canConnect " + mCanConnect
+                + ", isRemembered " + mIsRemembered;
         return result;
     }
 }
diff --git a/core/java/android/hardware/display/WifiDisplaySessionInfo.java b/core/java/android/hardware/display/WifiDisplaySessionInfo.java
new file mode 100644
index 0000000..33d2725
--- /dev/null
+++ b/core/java/android/hardware/display/WifiDisplaySessionInfo.java
@@ -0,0 +1,116 @@
+/*
+ * 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.hardware.display;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * This class contains information regarding a wifi display session
+ * (such as session id, source ip address, etc.). This is needed for
+ * Wifi Display Certification process.
+ * <p>
+ * This object is immutable.
+ * </p>
+ *
+ * @hide
+ */
+public final class WifiDisplaySessionInfo implements Parcelable {
+    private final boolean mClient;
+    private final int mSessionId;
+    private final String mGroupId;
+    private final String mPassphrase;
+    private final String mIP;
+
+    public static final Creator<WifiDisplaySessionInfo> CREATOR =
+            new Creator<WifiDisplaySessionInfo>() {
+        @Override
+        public WifiDisplaySessionInfo createFromParcel(Parcel in) {
+            boolean client = (in.readInt() != 0);
+            int session = in.readInt();
+            String group = in.readString();
+            String pp = in.readString();
+            String ip = in.readString();
+
+            return new WifiDisplaySessionInfo(client, session, group, pp, ip);
+        }
+
+        @Override
+        public WifiDisplaySessionInfo[] newArray(int size) {
+            return new WifiDisplaySessionInfo[size];
+        }
+    };
+
+    public WifiDisplaySessionInfo() {
+        this(true, 0, "", "", "");
+    }
+
+    public WifiDisplaySessionInfo(
+            boolean client, int session, String group, String pp, String ip) {
+        mClient = client;
+        mSessionId = session;
+        mGroupId = group;
+        mPassphrase = pp;
+        mIP = ip;
+    }
+
+    public boolean isClient() {
+        return mClient;
+    }
+
+    public int getSessionId() {
+        return mSessionId;
+    }
+
+    public String getGroupId() {
+        return mGroupId;
+    }
+
+    public String getPassphrase() {
+        return mPassphrase;
+    }
+
+    public String getIP() {
+        return mIP;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mClient ? 1 : 0);
+        dest.writeInt(mSessionId);
+        dest.writeString(mGroupId);
+        dest.writeString(mPassphrase);
+        dest.writeString(mIP);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    // For debugging purposes only.
+    @Override
+    public String toString() {
+        return "WifiDisplaySessionInfo:"
+                +"\n    Client/Owner: " + (mClient ? "Client":"Owner")
+                +"\n    GroupId: " + mGroupId
+                +"\n    Passphrase: " + mPassphrase
+                +"\n    SessionId: " + mSessionId
+                +"\n    IP Address: " + mIP
+                ;
+    }
+}
diff --git a/core/java/android/hardware/display/WifiDisplayStatus.java b/core/java/android/hardware/display/WifiDisplayStatus.java
index f7e72c4..5216727 100644
--- a/core/java/android/hardware/display/WifiDisplayStatus.java
+++ b/core/java/android/hardware/display/WifiDisplayStatus.java
@@ -20,6 +20,8 @@
 import android.os.Parcelable;
 
 import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Describes the current global state of Wifi display connectivity, including the
@@ -35,8 +37,10 @@
     private final int mScanState;
     private final int mActiveDisplayState;
     private final WifiDisplay mActiveDisplay;
-    private final WifiDisplay[] mAvailableDisplays;
-    private final WifiDisplay[] mRememberedDisplays;
+    private final WifiDisplay[] mDisplays;
+
+    /** Session info needed for Miracast Certification */
+    private final WifiDisplaySessionInfo mSessionInfo;
 
     /** Feature state: Wifi display is not available on this device. */
     public static final int FEATURE_STATE_UNAVAILABLE = 0;
@@ -70,18 +74,16 @@
                 activeDisplay = WifiDisplay.CREATOR.createFromParcel(in);
             }
 
-            WifiDisplay[] availableDisplays = WifiDisplay.CREATOR.newArray(in.readInt());
-            for (int i = 0; i < availableDisplays.length; i++) {
-                availableDisplays[i] = WifiDisplay.CREATOR.createFromParcel(in);
+            WifiDisplay[] displays = WifiDisplay.CREATOR.newArray(in.readInt());
+            for (int i = 0; i < displays.length; i++) {
+                displays[i] = WifiDisplay.CREATOR.createFromParcel(in);
             }
 
-            WifiDisplay[] rememberedDisplays = WifiDisplay.CREATOR.newArray(in.readInt());
-            for (int i = 0; i < rememberedDisplays.length; i++) {
-                rememberedDisplays[i] = WifiDisplay.CREATOR.createFromParcel(in);
-            }
+            WifiDisplaySessionInfo sessionInfo =
+                    WifiDisplaySessionInfo.CREATOR.createFromParcel(in);
 
             return new WifiDisplayStatus(featureState, scanState, activeDisplayState,
-                    activeDisplay, availableDisplays, rememberedDisplays);
+                    activeDisplay, displays, sessionInfo);
         }
 
         public WifiDisplayStatus[] newArray(int size) {
@@ -91,25 +93,22 @@
 
     public WifiDisplayStatus() {
         this(FEATURE_STATE_UNAVAILABLE, SCAN_STATE_NOT_SCANNING, DISPLAY_STATE_NOT_CONNECTED,
-                null, WifiDisplay.EMPTY_ARRAY, WifiDisplay.EMPTY_ARRAY);
+                null, WifiDisplay.EMPTY_ARRAY, null);
     }
 
-    public WifiDisplayStatus(int featureState, int scanState,
-            int activeDisplayState, WifiDisplay activeDisplay,
-            WifiDisplay[] availableDisplays, WifiDisplay[] rememberedDisplays) {
-        if (availableDisplays == null) {
-            throw new IllegalArgumentException("availableDisplays must not be null");
-        }
-        if (rememberedDisplays == null) {
-            throw new IllegalArgumentException("rememberedDisplays must not be null");
+    public WifiDisplayStatus(int featureState, int scanState, int activeDisplayState,
+            WifiDisplay activeDisplay, WifiDisplay[] displays, WifiDisplaySessionInfo sessionInfo) {
+        if (displays == null) {
+            throw new IllegalArgumentException("displays must not be null");
         }
 
         mFeatureState = featureState;
         mScanState = scanState;
         mActiveDisplayState = activeDisplayState;
         mActiveDisplay = activeDisplay;
-        mAvailableDisplays = availableDisplays;
-        mRememberedDisplays = rememberedDisplays;
+        mDisplays = displays;
+
+        mSessionInfo = (sessionInfo != null) ? sessionInfo : new WifiDisplaySessionInfo();
     }
 
     /**
@@ -152,24 +151,19 @@
     }
 
     /**
-     * Gets the list of all available Wifi displays as reported by the most recent
-     * scan, never null.
-     * <p>
-     * Some of these displays may already be remembered, others may be unknown.
-     * </p>
+     * Gets the list of Wifi displays, returns a combined list of all available
+     * Wifi displays as reported by the most recent scan, and all remembered
+     * Wifi displays (not necessarily available at the time).
      */
-    public WifiDisplay[] getAvailableDisplays() {
-        return mAvailableDisplays;
+    public WifiDisplay[] getDisplays() {
+        return mDisplays;
     }
 
     /**
-     * Gets the list of all remembered Wifi displays, never null.
-     * <p>
-     * Not all remembered displays will necessarily be available.
-     * </p>
+     * Gets the Wifi display session info (required for certification only)
      */
-    public WifiDisplay[] getRememberedDisplays() {
-        return mRememberedDisplays;
+    public WifiDisplaySessionInfo getSessionInfo() {
+        return mSessionInfo;
     }
 
     @Override
@@ -185,15 +179,12 @@
             dest.writeInt(0);
         }
 
-        dest.writeInt(mAvailableDisplays.length);
-        for (WifiDisplay display : mAvailableDisplays) {
+        dest.writeInt(mDisplays.length);
+        for (WifiDisplay display : mDisplays) {
             display.writeToParcel(dest, flags);
         }
 
-        dest.writeInt(mRememberedDisplays.length);
-        for (WifiDisplay display : mRememberedDisplays) {
-            display.writeToParcel(dest, flags);
-        }
+        mSessionInfo.writeToParcel(dest, flags);
     }
 
     @Override
@@ -208,8 +199,8 @@
                 + ", scanState=" + mScanState
                 + ", activeDisplayState=" + mActiveDisplayState
                 + ", activeDisplay=" + mActiveDisplay
-                + ", availableDisplays=" + Arrays.toString(mAvailableDisplays)
-                + ", rememberedDisplays=" + Arrays.toString(mRememberedDisplays)
+                + ", displays=" + Arrays.toString(mDisplays)
+                + ", sessionInfo=" + mSessionInfo
                 + "}";
     }
 }
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 761faaf..30e69a6 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -579,15 +579,33 @@
      * @hide
      */
     public boolean[] deviceHasKeys(int[] keyCodes) {
+        return deviceHasKeys(-1, keyCodes);
+    }
+
+    /**
+     * Queries the framework about whether any physical keys exist on the
+     * any keyboard attached to the device that are capable of producing the given
+     * array of key codes.
+     *
+     * @param id The id of the device to query.
+     * @param keyCodes The array of key codes to query.
+     * @return A new array of the same size as the key codes array whose elements are set to true
+     * if the given device could produce the corresponding key code at the same index in the key
+     * codes array.
+     *
+     * @hide
+     */
+    public boolean[] deviceHasKeys(int id, int[] keyCodes) {
         boolean[] ret = new boolean[keyCodes.length];
         try {
-            mIm.hasKeys(-1, InputDevice.SOURCE_ANY, keyCodes, ret);
+            mIm.hasKeys(id, InputDevice.SOURCE_ANY, keyCodes, ret);
         } catch (RemoteException e) {
             // no fallback; just return the empty array
         }
         return ret;
     }
 
+
     /**
      * Injects an input event into the event system on behalf of an application.
      * The synchronization mode determines whether the method blocks while waiting for
diff --git a/core/java/android/hardware/location/GeofenceHardware.java b/core/java/android/hardware/location/GeofenceHardware.java
index e67d0d7..21de9f5 100644
--- a/core/java/android/hardware/location/GeofenceHardware.java
+++ b/core/java/android/hardware/location/GeofenceHardware.java
@@ -15,16 +15,11 @@
  */
 package android.hardware.location;
 
-import android.content.Context;
 import android.location.Location;
 import android.os.RemoteException;
-import android.util.Log;
 
 import java.lang.ref.WeakReference;
 import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
 
 /**
  * This class handles geofences managed by various hardware subsystems. It contains
@@ -52,7 +47,7 @@
     private IGeofenceHardware mService;
 
     // Hardware systems that do geofence monitoring.
-    static final int NUM_MONITORS = 1;
+    static final int NUM_MONITORS = 2;
 
     /**
      * Constant for geofence monitoring done by the GPS hardware.
@@ -60,6 +55,13 @@
     public static final int MONITORING_TYPE_GPS_HARDWARE = 0;
 
     /**
+     * Constant for geofence monitoring done by the Fused hardware.
+     *
+     * @hide
+     */
+    public static final int MONITORING_TYPE_FUSED_HARDWARE = 1;
+
+    /**
      * Constant to indiciate that the monitoring system is currently
      * available for monitoring geofences.
      */
@@ -124,8 +126,12 @@
      */
     public static final int GEOFENCE_FAILURE = 5;
 
-    static final int GPS_GEOFENCE_UNAVAILABLE = 1<<0L;
-    static final int GPS_GEOFENCE_AVAILABLE = 1<<1L;
+    /**
+     * The constant used to indicate that the operation failed due to insufficient memory.
+     *
+     * @hide
+     */
+    public static final int GEOFENCE_ERROR_INSUFFICIENT_MEMORY = 6;
 
     private HashMap<GeofenceHardwareCallback, GeofenceHardwareCallbackWrapper>
             mCallbacks = new HashMap<GeofenceHardwareCallback, GeofenceHardwareCallbackWrapper>();
diff --git a/core/java/android/hardware/location/GeofenceHardwareImpl.java b/core/java/android/hardware/location/GeofenceHardwareImpl.java
index 77e3143..eac6620 100644
--- a/core/java/android/hardware/location/GeofenceHardwareImpl.java
+++ b/core/java/android/hardware/location/GeofenceHardwareImpl.java
@@ -18,23 +18,21 @@
 
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.location.FusedBatchOptions;
+import android.location.IFusedGeofenceHardware;
 import android.location.IGpsGeofenceHardware;
 import android.location.Location;
 import android.location.LocationManager;
-import android.os.Binder;
-import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
 import android.os.PowerManager;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.util.Log;
 import android.util.SparseArray;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 
 /**
  * This class manages the geofences which are handled by hardware.
@@ -54,6 +52,7 @@
             new ArrayList[GeofenceHardware.NUM_MONITORS];
     private final ArrayList<Reaper> mReapers = new ArrayList<Reaper>();
 
+    private IFusedGeofenceHardware mFusedService;
     private IGpsGeofenceHardware mGpsService;
 
     private int[] mSupportedMonitorTypes = new int[GeofenceHardware.NUM_MONITORS];
@@ -67,7 +66,7 @@
     private static final int GEOFENCE_CALLBACK_BINDER_DIED = 6;
 
     // mCallbacksHandler message types
-    private static final int GPS_GEOFENCE_STATUS = 1;
+    private static final int GEOFENCE_STATUS = 1;
     private static final int CALLBACK_ADD = 2;
     private static final int CALLBACK_REMOVE = 3;
     private static final int MONITOR_CALLBACK_BINDER_DIED = 4;
@@ -91,16 +90,6 @@
     private static final int RESOLUTION_LEVEL_COARSE = 2;
     private static final int RESOLUTION_LEVEL_FINE = 3;
 
-    // GPS Geofence errors. Should match gps.h constants.
-    private static final int GPS_GEOFENCE_OPERATION_SUCCESS = 0;
-    private static final int GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES = 100;
-    private static final int GPS_GEOFENCE_ERROR_ID_EXISTS  = -101;
-    private static final int GPS_GEOFENCE_ERROR_ID_UNKNOWN = -102;
-    private static final int GPS_GEOFENCE_ERROR_INVALID_TRANSITION = -103;
-    private static final int GPS_GEOFENCE_ERROR_GENERIC = -149;
-
-
-
     public synchronized static GeofenceHardwareImpl getInstance(Context context) {
         if (sInstance == null) {
             sInstance = new GeofenceHardwareImpl(context);
@@ -113,6 +102,9 @@
         // Init everything to unsupported.
         setMonitorAvailability(GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
                 GeofenceHardware.MONITOR_UNSUPPORTED);
+        setMonitorAvailability(
+                GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE,
+                GeofenceHardware.MONITOR_UNSUPPORTED);
 
     }
 
@@ -147,6 +139,22 @@
         }
     }
 
+    private void updateFusedHardwareAvailability() {
+        boolean fusedSupported;
+        try {
+            fusedSupported = mFusedService.isSupported();
+        } catch(RemoteException e) {
+            Log.e(TAG, "RemoteException calling LocationManagerService");
+            fusedSupported = false;
+        }
+
+        if(fusedSupported) {
+            setMonitorAvailability(
+                    GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE,
+                    GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE);
+        }
+    }
+
     public void setGpsHardwareGeofence(IGpsGeofenceHardware service) {
         if (mGpsService == null) {
             mGpsService = service;
@@ -159,12 +167,39 @@
         }
     }
 
+    public void setFusedGeofenceHardware(IFusedGeofenceHardware service) {
+        if(mFusedService == null) {
+            mFusedService = service;
+            updateFusedHardwareAvailability();
+        } else if(service == null) {
+            mFusedService = null;
+            Log.w(TAG, "Fused Geofence Hardware service seems to have crashed");
+        } else {
+            Log.e(TAG, "Error: FusedService being set again");
+        }
+    }
+
     public int[] getMonitoringTypes() {
+        boolean gpsSupported;
+        boolean fusedSupported;
         synchronized (mSupportedMonitorTypes) {
-            if (mSupportedMonitorTypes[GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE] !=
-                        GeofenceHardware.MONITOR_UNSUPPORTED) {
-                return new int[] {GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE};
+            gpsSupported = mSupportedMonitorTypes[GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE]
+                    != GeofenceHardware.MONITOR_UNSUPPORTED;
+            fusedSupported = mSupportedMonitorTypes[GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE]
+                    != GeofenceHardware.MONITOR_UNSUPPORTED;
+        }
+
+        if(gpsSupported) {
+            if(fusedSupported) {
+                return new int[] {
+                        GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
+                        GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE };
+            } else {
+                return new int[] { GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE };
             }
+        } else if (fusedSupported) {
+            return new int[] { GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE };
+        } else {
             return new int[0];
         }
     }
@@ -213,6 +248,30 @@
                     result = false;
                 }
                 break;
+            case GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE:
+                if(mFusedService == null) {
+                    return false;
+                }
+                GeofenceHardwareRequest request = GeofenceHardwareRequest.createCircularGeofence(
+                        latitude,
+                        longitude,
+                        radius);
+                request.setUnknownTimer(unknownTimer);
+                request.setNotificationResponsiveness(notificationResponsivenes);
+                request.setMonitorTransitions(monitorTransitions);
+                request.setLastTransition(lastTransition);
+
+                GeofenceHardwareRequestParcelable parcelableRequest =
+                        new GeofenceHardwareRequestParcelable(geofenceId, request);
+                try {
+                    mFusedService.addGeofences(
+                            new GeofenceHardwareRequestParcelable[] { parcelableRequest });
+                    result = true;
+                } catch(RemoteException e) {
+                    Log.e(TAG, "AddGeofence: RemoteException calling LocationManagerService");
+                    result = false;
+                }
+                break;
             default:
                 result = false;
         }
@@ -251,6 +310,18 @@
                     result = false;
                 }
                 break;
+            case GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE:
+                if(mFusedService == null) {
+                    return false;
+                }
+                try {
+                    mFusedService.removeGeofences(new int[] { geofenceId });
+                    result = true;
+                } catch(RemoteException e) {
+                    Log.e(TAG, "RemoveGeofence: RemoteException calling LocationManagerService");
+                    result = false;
+                }
+                break;
             default:
                 result = false;
         }
@@ -278,6 +349,18 @@
                     result = false;
                 }
                 break;
+            case GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE:
+                if(mFusedService == null) {
+                    return false;
+                }
+                try {
+                    mFusedService.pauseMonitoringGeofence(geofenceId);
+                    result = true;
+                } catch(RemoteException e) {
+                    Log.e(TAG, "PauseGeofence: RemoteException calling LocationManagerService");
+                    result = false;
+                }
+                break;
             default:
                 result = false;
         }
@@ -306,6 +389,18 @@
                     result = false;
                 }
                 break;
+            case GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE:
+                if(mFusedService == null) {
+                    return false;
+                }
+                try {
+                    mFusedService.resumeMonitoringGeofence(geofenceId, monitorTransition);
+                    result = true;
+                } catch(RemoteException e) {
+                    Log.e(TAG, "ResumeGeofence: RemoteException calling LocationManagerService");
+                    result = false;
+                }
+                break;
             default:
                 result = false;
         }
@@ -334,127 +429,106 @@
         return true;
     }
 
-    private Location getLocation(int flags, double latitude,
-            double longitude, double altitude, float speed, float bearing, float accuracy,
-            long timestamp) {
-        if (DEBUG) Log.d(TAG, "GetLocation: " + flags + ":" + latitude);
-        Location location = new Location(LocationManager.GPS_PROVIDER);
-        if ((flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) {
-            location.setLatitude(latitude);
-            location.setLongitude(longitude);
-            location.setTime(timestamp);
-            // It would be nice to push the elapsed real-time timestamp
-            // further down the stack, but this is still useful
-            location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
+    /**
+     * Used to report geofence transitions
+     */
+    public void reportGeofenceTransition(
+            int geofenceId,
+            Location location,
+            int transition,
+            long transitionTimestamp,
+            int monitoringType,
+            int sourcesUsed) {
+        if(location == null) {
+            Log.e(TAG, String.format("Invalid Geofence Transition: location=%p", location));
+            return;
         }
-        if ((flags & LOCATION_HAS_ALTITUDE) == LOCATION_HAS_ALTITUDE) {
-            location.setAltitude(altitude);
-        } else {
-            location.removeAltitude();
+        if(DEBUG) {
+            Log.d(
+                    TAG,
+                    "GeofenceTransition| " + location + ", transition:" + transition +
+                    ", transitionTimestamp:" + transitionTimestamp + ", monitoringType:" +
+                    monitoringType + ", sourcesUsed:" + sourcesUsed);
         }
-        if ((flags & LOCATION_HAS_SPEED) == LOCATION_HAS_SPEED) {
-            location.setSpeed(speed);
-        } else {
-            location.removeSpeed();
-        }
-        if ((flags & LOCATION_HAS_BEARING) == LOCATION_HAS_BEARING) {
-            location.setBearing(bearing);
-        } else {
-            location.removeBearing();
-        }
-        if ((flags & LOCATION_HAS_ACCURACY) == LOCATION_HAS_ACCURACY) {
-            location.setAccuracy(accuracy);
-        } else {
-            location.removeAccuracy();
-        }
-        return location;
+
+        GeofenceTransition geofenceTransition = new GeofenceTransition(
+                geofenceId,
+                transition,
+                transitionTimestamp,
+                location,
+                monitoringType,
+                sourcesUsed);
+        acquireWakeLock();
+
+        Message message = mGeofenceHandler.obtainMessage(
+                GEOFENCE_TRANSITION_CALLBACK,
+                geofenceTransition);
+        message.sendToTarget();
     }
 
     /**
-     * called from GpsLocationProvider to report geofence transition
+     * Used to report Monitor status changes.
      */
-    public void reportGpsGeofenceTransition(int geofenceId, int flags, double latitude,
-            double longitude, double altitude, float speed, float bearing, float accuracy,
-            long timestamp, int transition, long transitionTimestamp) {
-        if (DEBUG) Log.d(TAG, "GeofenceTransition: Flags: " + flags + " Lat: " + latitude +
-            " Long: " + longitude + " Altitude: " + altitude + " Speed: " + speed + " Bearing: " +
-            bearing + " Accuracy: " + accuracy + " Timestamp: " + timestamp + " Transition: " +
-            transition + " TransitionTimestamp: " + transitionTimestamp);
-        Location location = getLocation(flags, latitude, longitude, altitude, speed, bearing,
-                accuracy, timestamp);
-        GeofenceTransition t = new GeofenceTransition(geofenceId, transition, timestamp, location);
+    public void reportGeofenceMonitorStatus(
+            int monitoringType,
+            int monitoringStatus,
+            Location location,
+            int source) {
+        // TODO: use the source if needed in the future
+        setMonitorAvailability(monitoringType, monitoringStatus);
         acquireWakeLock();
-        Message m = mGeofenceHandler.obtainMessage(GEOFENCE_TRANSITION_CALLBACK, t);
-        mGeofenceHandler.sendMessage(m);
+        Message message = mCallbacksHandler.obtainMessage(GEOFENCE_STATUS, location);
+        message.arg1 = monitoringStatus;
+        message.arg2 = monitoringType;
+        message.sendToTarget();
     }
 
     /**
-     * called from GpsLocationProvider to report GPS status change.
+     * Internal generic status report function for Geofence operations.
+     *
+     * @param operation The operation to be reported as defined internally.
+     * @param geofenceId The id of the geofence the operation is related to.
+     * @param operationStatus The status of the operation as defined in GeofenceHardware class. This
+     *                        status is independent of the statuses reported by different HALs.
      */
-    public void reportGpsGeofenceStatus(int status, int flags, double latitude,
-            double longitude, double altitude, float speed, float bearing, float accuracy,
-            long timestamp) {
-        Location location = getLocation(flags, latitude, longitude, altitude, speed, bearing,
-                accuracy, timestamp);
-        boolean available = false;
-        if (status == GeofenceHardware.GPS_GEOFENCE_AVAILABLE) available = true;
-
-        int val = (available ? GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE :
-                GeofenceHardware.MONITOR_CURRENTLY_UNAVAILABLE);
-        setMonitorAvailability(GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE, val);
-
+    private void reportGeofenceOperationStatus(int operation, int geofenceId, int operationStatus) {
         acquireWakeLock();
-        Message m = mCallbacksHandler.obtainMessage(GPS_GEOFENCE_STATUS, location);
-        m.arg1 = val;
-        mCallbacksHandler.sendMessage(m);
+        Message message = mGeofenceHandler.obtainMessage(operation);
+        message.arg1 = geofenceId;
+        message.arg2 = operationStatus;
+        message.sendToTarget();
     }
 
     /**
-     * called from GpsLocationProvider add geofence callback.
+     * Used to report the status of a Geofence Add operation.
      */
-    public void reportGpsGeofenceAddStatus(int geofenceId, int status) {
-        if (DEBUG) Log.d(TAG, "Add Callback: GPS : Id: " + geofenceId + " Status: " + status);
-        acquireWakeLock();
-        Message m = mGeofenceHandler.obtainMessage(ADD_GEOFENCE_CALLBACK);
-        m.arg1 = geofenceId;
-        m.arg2 = getGeofenceStatus(status);
-        mGeofenceHandler.sendMessage(m);
+    public void reportGeofenceAddStatus(int geofenceId, int status) {
+        if(DEBUG) Log.d(TAG, "AddCallback| id:" + geofenceId + ", status:" + status);
+        reportGeofenceOperationStatus(ADD_GEOFENCE_CALLBACK, geofenceId, status);
     }
 
     /**
-     * called from GpsLocationProvider remove geofence callback.
+     * Used to report the status of a Geofence Remove operation.
      */
-    public void reportGpsGeofenceRemoveStatus(int geofenceId, int status) {
-        if (DEBUG) Log.d(TAG, "Remove Callback: GPS : Id: " + geofenceId + " Status: " + status);
-        acquireWakeLock();
-        Message m = mGeofenceHandler.obtainMessage(REMOVE_GEOFENCE_CALLBACK);
-        m.arg1 = geofenceId;
-        m.arg2 = getGeofenceStatus(status);
-        mGeofenceHandler.sendMessage(m);
+    public void reportGeofenceRemoveStatus(int geofenceId, int status) {
+        if(DEBUG) Log.d(TAG, "RemoveCallback| id:" + geofenceId + ", status:" + status);
+        reportGeofenceOperationStatus(REMOVE_GEOFENCE_CALLBACK, geofenceId, status);
     }
 
     /**
-     * called from GpsLocationProvider pause geofence callback.
+     * Used to report the status of a Geofence Pause operation.
      */
-    public void reportGpsGeofencePauseStatus(int geofenceId, int status) {
-        if (DEBUG) Log.d(TAG, "Pause Callback: GPS : Id: " + geofenceId + " Status: " + status);
-        acquireWakeLock();
-        Message m = mGeofenceHandler.obtainMessage(PAUSE_GEOFENCE_CALLBACK);
-        m.arg1 = geofenceId;
-        m.arg2 = getGeofenceStatus(status);
-        mGeofenceHandler.sendMessage(m);
+    public void reportGeofencePauseStatus(int geofenceId, int status) {
+        if(DEBUG) Log.d(TAG, "PauseCallbac| id:" + geofenceId + ", status" + status);
+        reportGeofenceOperationStatus(PAUSE_GEOFENCE_CALLBACK, geofenceId, status);
     }
 
     /**
-     * called from GpsLocationProvider resume geofence callback.
+     * Used to report the status of a Geofence Resume operation.
      */
-    public void reportGpsGeofenceResumeStatus(int geofenceId, int status) {
-        if (DEBUG) Log.d(TAG, "Resume Callback: GPS : Id: " + geofenceId + " Status: " + status);
-        acquireWakeLock();
-        Message m = mGeofenceHandler.obtainMessage(RESUME_GEOFENCE_CALLBACK);
-        m.arg1 = geofenceId;
-        m.arg2 = getGeofenceStatus(status);
-        mGeofenceHandler.sendMessage(m);
+    public void reportGeofenceResumeStatus(int geofenceId, int status) {
+        if(DEBUG) Log.d(TAG, "ResumeCallback| id:" + geofenceId + ", status:" + status);
+        reportGeofenceOperationStatus(RESUME_GEOFENCE_CALLBACK, geofenceId, status);
     }
 
     // All operations on mGeofences
@@ -539,7 +613,7 @@
                             callback.onGeofenceTransition(
                                     geofenceTransition.mGeofenceId, geofenceTransition.mTransition,
                                     geofenceTransition.mLocation, geofenceTransition.mTimestamp,
-                                    GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE);
+                                    geofenceTransition.mMonitoringType);
                         } catch (RemoteException e) {}
                     }
                     releaseWakeLock();
@@ -571,21 +645,20 @@
             IGeofenceHardwareMonitorCallback callback;
 
             switch (msg.what) {
-                case GPS_GEOFENCE_STATUS:
+                case GEOFENCE_STATUS:
                     Location location = (Location) msg.obj;
                     int val = msg.arg1;
+                    monitoringType = msg.arg2;
                     boolean available;
                     available = (val == GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE ?
                             true : false);
-                    callbackList = mCallbacks[GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE];
+                    callbackList = mCallbacks[monitoringType];
                     if (callbackList != null) {
                         if (DEBUG) Log.d(TAG, "MonitoringSystemChangeCallback: GPS : " + available);
 
                         for (IGeofenceHardwareMonitorCallback c: callbackList) {
                             try {
-                                c.onMonitoringSystemChange(
-                                        GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE, available,
-                                        location);
+                                c.onMonitoringSystemChange(monitoringType, available, location);
                             } catch (RemoteException e) {}
                         }
                     }
@@ -666,12 +739,22 @@
         private int mGeofenceId, mTransition;
         private long mTimestamp;
         private Location mLocation;
+        private int mMonitoringType;
+        private int mSourcesUsed;
 
-        GeofenceTransition(int geofenceId, int transition, long timestamp, Location location) {
+        GeofenceTransition(
+                int geofenceId,
+                int transition,
+                long timestamp,
+                Location location,
+                int monitoringType,
+                int sourcesUsed) {
             mGeofenceId = geofenceId;
             mTransition = transition;
             mTimestamp = timestamp;
             mLocation = location;
+            mMonitoringType = monitoringType;
+            mSourcesUsed = sourcesUsed;
         }
     }
 
@@ -686,6 +769,8 @@
         switch (monitoringType) {
             case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE:
                 return RESOLUTION_LEVEL_FINE;
+            case GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE:
+                return RESOLUTION_LEVEL_FINE;
         }
         return RESOLUTION_LEVEL_NONE;
     }
@@ -752,22 +837,4 @@
             return RESOLUTION_LEVEL_NONE;
         }
     }
-
-    private int getGeofenceStatus(int status) {
-        switch (status) {
-            case GPS_GEOFENCE_OPERATION_SUCCESS:
-                return GeofenceHardware.GEOFENCE_SUCCESS;
-            case GPS_GEOFENCE_ERROR_GENERIC:
-                return GeofenceHardware.GEOFENCE_FAILURE;
-            case GPS_GEOFENCE_ERROR_ID_EXISTS:
-                return GeofenceHardware.GEOFENCE_ERROR_ID_EXISTS;
-            case GPS_GEOFENCE_ERROR_INVALID_TRANSITION:
-                return GeofenceHardware.GEOFENCE_ERROR_INVALID_TRANSITION;
-            case GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES:
-                return GeofenceHardware.GEOFENCE_ERROR_TOO_MANY_GEOFENCES;
-            case GPS_GEOFENCE_ERROR_ID_UNKNOWN:
-                return GeofenceHardware.GEOFENCE_ERROR_ID_UNKNOWN;
-        }
-        return -1;
-    }
 }
diff --git a/core/java/android/hardware/location/GeofenceHardwareRequestParcelable.aidl b/core/java/android/hardware/location/GeofenceHardwareRequestParcelable.aidl
new file mode 100644
index 0000000..b599d44
--- /dev/null
+++ b/core/java/android/hardware/location/GeofenceHardwareRequestParcelable.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.hardware.location;
+
+parcelable GeofenceHardwareRequestParcelable;
diff --git a/core/java/android/hardware/location/GeofenceHardwareRequestParcelable.java b/core/java/android/hardware/location/GeofenceHardwareRequestParcelable.java
new file mode 100644
index 0000000..40e7fc4
--- /dev/null
+++ b/core/java/android/hardware/location/GeofenceHardwareRequestParcelable.java
@@ -0,0 +1,151 @@
+/*
+ * 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.hardware.location;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+/**
+ * Geofence Hardware Request used for internal location services communication.
+ *
+ * @hide
+ */
+public final class GeofenceHardwareRequestParcelable implements Parcelable {
+    private GeofenceHardwareRequest mRequest;
+    private int mId;
+
+    public GeofenceHardwareRequestParcelable(int id, GeofenceHardwareRequest request) {
+        mId = id;
+        mRequest = request;
+    }
+
+    /**
+     * Returns the id of this request.
+     */
+    public int getId() {
+        return mId;
+    }
+
+    /**
+     * Returns the latitude of this geofence.
+     */
+    public double getLatitude() {
+        return mRequest.getLatitude();
+    }
+
+    /**
+     * Returns the longitude of this geofence.
+     */
+    public double getLongitude() {
+        return mRequest.getLongitude();
+    }
+
+    /**
+     * Returns the radius of this geofence.
+     */
+    public double getRadius() {
+        return mRequest.getRadius();
+    }
+
+    /**
+     * Returns transitions monitored for this geofence.
+     */
+    public int getMonitorTransitions() {
+        return mRequest.getMonitorTransitions();
+    }
+
+    /**
+     * Returns the unknownTimer of this geofence.
+     */
+    public int getUnknownTimer() {
+        return mRequest.getUnknownTimer();
+    }
+
+    /**
+     * Returns the notification responsiveness of this geofence.
+     */
+    public int getNotificationResponsiveness() {
+        return mRequest.getNotificationResponsiveness();
+    }
+
+    /**
+     * Returns the last transition of this geofence.
+     */
+    public int getLastTransition() {
+        return mRequest.getLastTransition();
+    }
+
+    /**
+     * Returns the type of the geofence for the current request.
+     */
+    int getType() {
+        return mRequest.getType();
+    }
+
+    /**
+     * Method definitions to support Parcelable operations.
+     */
+    public static final Parcelable.Creator<GeofenceHardwareRequestParcelable> CREATOR = 
+            new Parcelable.Creator<GeofenceHardwareRequestParcelable>() {
+        @Override
+        public GeofenceHardwareRequestParcelable createFromParcel(Parcel parcel) {
+            int geofenceType = parcel.readInt();
+            if(geofenceType != GeofenceHardwareRequest.GEOFENCE_TYPE_CIRCLE) {
+                Log.e(
+                        "GeofenceHardwareRequest",
+                        String.format("Invalid Geofence type: %d", geofenceType));
+                return null;
+            }
+
+            GeofenceHardwareRequest request = GeofenceHardwareRequest.createCircularGeofence(
+                    parcel.readDouble(),
+                    parcel.readDouble(),
+                    parcel.readDouble());
+            request.setLastTransition(parcel.readInt());
+            request.setMonitorTransitions(parcel.readInt());
+            request.setUnknownTimer(parcel.readInt());
+            request.setNotificationResponsiveness(parcel.readInt());
+            
+            int id = parcel.readInt();
+            return new GeofenceHardwareRequestParcelable(id, request);
+        }
+
+        @Override
+        public GeofenceHardwareRequestParcelable[] newArray(int size) {
+            return new GeofenceHardwareRequestParcelable[size];
+        }
+    };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeInt(getType());
+        parcel.writeDouble(getLatitude());
+        parcel.writeDouble(getLongitude());
+        parcel.writeDouble(getRadius());
+        parcel.writeInt(getLastTransition());
+        parcel.writeInt(getMonitorTransitions());
+        parcel.writeInt(getUnknownTimer());
+        parcel.writeInt(getNotificationResponsiveness());
+        parcel.writeInt(getId());
+    }
+}
diff --git a/core/java/android/hardware/location/GeofenceHardwareService.java b/core/java/android/hardware/location/GeofenceHardwareService.java
index 3bc70ee..fb238bd 100644
--- a/core/java/android/hardware/location/GeofenceHardwareService.java
+++ b/core/java/android/hardware/location/GeofenceHardwareService.java
@@ -20,6 +20,7 @@
 import android.app.Service;
 import android.content.Context;
 import android.content.Intent;
+import android.location.IFusedGeofenceHardware;
 import android.location.IGpsGeofenceHardware;
 import android.os.Binder;
 import android.os.IBinder;
@@ -68,6 +69,10 @@
             mGeofenceHardwareImpl.setGpsHardwareGeofence(service);
         }
 
+        public void setFusedGeofenceHardware(IFusedGeofenceHardware service) {
+            mGeofenceHardwareImpl.setFusedGeofenceHardware(service);
+        }
+
         public int[] getMonitoringTypes() {
             mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
                     "Location Hardware permission not granted to access hardware geofence");
diff --git a/core/java/android/hardware/location/IFusedLocationHardware.aidl b/core/java/android/hardware/location/IFusedLocationHardware.aidl
new file mode 100644
index 0000000..382c12c
--- /dev/null
+++ b/core/java/android/hardware/location/IFusedLocationHardware.aidl
@@ -0,0 +1,117 @@
+/*
+ * 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/license/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.location;
+
+import android.hardware.location.IFusedLocationHardwareSink;
+import android.location.FusedBatchOptions;
+
+/**
+ * Fused Location hardware interface.
+ * This interface is the basic set of supported functionality by Fused Hardware
+ * modules that offer Location batching capabilities.
+ *
+ * @hide
+ */
+interface IFusedLocationHardware {
+    /**
+     * Registers a sink with the Location Hardware object.
+     *
+     * @param eventSink     The sink to register.
+     */
+    void registerSink(in IFusedLocationHardwareSink eventSink);
+
+    /**
+     * Unregisters a sink with the Location Hardware object.
+     *
+     * @param eventSink     The sink to unregister.
+     */
+    void unregisterSink(in IFusedLocationHardwareSink eventSink);
+
+    /**
+     * Provides access to the batch size available in Hardware.
+     *
+     * @return The batch size the hardware supports.
+     */
+    int getSupportedBatchSize();
+
+    /**
+     * Requests the Hardware to start batching locations.
+     *
+     * @param id            An Id associated with the request.
+     * @param batchOptions  The options required for batching.
+     *
+     * @throws RuntimeException if the request Id exists.
+     */
+    void startBatching(in int id, in FusedBatchOptions batchOptions);
+
+    /**
+     * Requests the Hardware to stop batching for the given Id.
+     *
+     * @param id    The request that needs to be stopped.
+     * @throws RuntimeException if the request Id is unknown.
+     */
+    void stopBatching(in int id);
+
+    /**
+     * Updates a batching operation in progress.
+     *
+     * @param id                The Id of the operation to update.
+     * @param batchOptions     The options to apply to the given operation.
+     *
+     * @throws RuntimeException if the Id of the request is unknown.
+     */
+    void updateBatchingOptions(in int id, in FusedBatchOptions batchOptions);
+
+    /**
+     * Requests the most recent locations available in Hardware.
+     * This operation does not dequeue the locations, so still other batching
+     * events will continue working.
+     *
+     * @param batchSizeRequested    The number of locations requested.
+     */
+    void requestBatchOfLocations(in int batchSizeRequested);
+
+    /**
+     * Flags if the Hardware supports injection of diagnostic data.
+     *
+     * @return True if data injection is supported, false otherwise.
+     */
+    boolean supportsDiagnosticDataInjection();
+
+    /**
+     * Injects diagnostic data into the Hardware subsystem.
+     *
+     * @param data  The data to inject.
+     * @throws RuntimeException if injection is not supported.
+     */
+    void injectDiagnosticData(in String data);
+
+    /**
+     * Flags if the Hardware supports injection of device context information.
+     *
+     * @return True if device context injection is supported, false otherwise.
+     */
+    boolean supportsDeviceContextInjection();
+
+    /**
+     * Injects device context information into the Hardware subsystem.
+     *
+     * @param deviceEnabledContext  The context to inject.
+     * @throws RuntimeException if injection is not supported.
+     */
+    void injectDeviceContext(in int deviceEnabledContext);
+}
diff --git a/core/java/android/hardware/location/IFusedLocationHardwareSink.aidl b/core/java/android/hardware/location/IFusedLocationHardwareSink.aidl
new file mode 100644
index 0000000..a11d8ab
--- /dev/null
+++ b/core/java/android/hardware/location/IFusedLocationHardwareSink.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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/license/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.location;
+
+import android.location.Location;
+
+/**
+ * Fused Location hardware event sink interface.
+ * This interface defines the set of events that the FusedLocationHardware provides.
+ *
+ * @hide
+ */
+interface IFusedLocationHardwareSink {
+    /**
+     * Event generated when a batch of location information is available.
+     *
+     * @param locations     The batch of location information available.
+     */
+    void onLocationAvailable(in Location[] locations);
+
+    /**
+     * Event generated from FLP HAL to provide diagnostic data to the platform.
+     *
+     * @param data      The diagnostic data provided by FLP HAL.
+     */
+    void onDiagnosticDataAvailable(in String data);
+}
\ No newline at end of file
diff --git a/core/java/android/hardware/location/IGeofenceHardware.aidl b/core/java/android/hardware/location/IGeofenceHardware.aidl
index 6900070..8900166 100644
--- a/core/java/android/hardware/location/IGeofenceHardware.aidl
+++ b/core/java/android/hardware/location/IGeofenceHardware.aidl
@@ -16,6 +16,7 @@
 
 package android.hardware.location;
 
+import android.location.IFusedGeofenceHardware;
 import android.location.IGpsGeofenceHardware;
 import android.hardware.location.IGeofenceHardwareCallback;
 import android.hardware.location.IGeofenceHardwareMonitorCallback;
@@ -23,6 +24,7 @@
 /** @hide */
 interface IGeofenceHardware {
     void setGpsGeofenceHardware(in IGpsGeofenceHardware service);
+    void setFusedGeofenceHardware(in IFusedGeofenceHardware service);
     int[] getMonitoringTypes();
     int getStatusOfMonitoringType(int monitoringType);
     boolean addCircularFence(int id,  int monitoringType, double lat, double longitude,
diff --git a/core/java/android/inputmethodservice/IInputMethodWrapper.java b/core/java/android/inputmethodservice/IInputMethodWrapper.java
index 9306373..06d8e4a 100644
--- a/core/java/android/inputmethodservice/IInputMethodWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodWrapper.java
@@ -279,6 +279,10 @@
         try {
             InputMethodSession ls = ((IInputMethodSessionWrapper)
                     session).getInternalInputMethodSession();
+            if (ls == null) {
+                Log.w(TAG, "Session is already finished: " + session);
+                return;
+            }
             mCaller.executeOrSendMessage(mCaller.obtainMessageIO(
                     DO_SET_SESSION_ENABLED, enabled ? 1 : 0, ls));
         } catch (ClassCastException e) {
@@ -291,6 +295,10 @@
         try {
             InputMethodSession ls = ((IInputMethodSessionWrapper)
                     session).getInternalInputMethodSession();
+            if (ls == null) {
+                Log.w(TAG, "Session is already finished: " + session);
+                return;
+            }
             mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_REVOKE_SESSION, ls));
         } catch (ClassCastException e) {
             Log.w(TAG, "Incoming session not of correct type: " + session, e);
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 4881d14..9319d4a 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -381,7 +381,6 @@
             if (DEBUG) Log.v(TAG, "unbindInput(): binding=" + mInputBinding
                     + " ic=" + mInputConnection);
             onUnbindInput();
-            mInputStarted = false;
             mInputBinding = null;
             mInputConnection = null;
         }
@@ -719,7 +718,7 @@
         super.onDestroy();
         mRootView.getViewTreeObserver().removeOnComputeInternalInsetsListener(
                 mInsetsComputer);
-        finishViews();
+        doFinishInput();
         if (mWindowAdded) {
             // Disable exit animation for the current IME window
             // to avoid the race condition between the exit and enter animations
@@ -1651,6 +1650,11 @@
      * the text.  This is called whether or not the input method has requested
      * extracted text updates, although if so it will not receive this call
      * if the extracted text has changed as well.
+     *
+     * <p>Be careful about changing the text in reaction to this call with
+     * methods such as setComposingText, commitText or
+     * deleteSurroundingText. If the cursor moves as a result, this method
+     * will be called again, which may result in an infinite loop.
      * 
      * <p>The default implementation takes care of updating the cursor in
      * the extract text, if it is being shown.
diff --git a/core/java/android/net/BaseNetworkStateTracker.java b/core/java/android/net/BaseNetworkStateTracker.java
index e87f84c..476fefe 100644
--- a/core/java/android/net/BaseNetworkStateTracker.java
+++ b/core/java/android/net/BaseNetworkStateTracker.java
@@ -57,6 +57,10 @@
         mLinkCapabilities = new LinkCapabilities();
     }
 
+    protected BaseNetworkStateTracker() {
+        // By default, let the sub classes construct everything
+    }
+
     @Deprecated
     protected Handler getTargetHandler() {
         return mTarget;
@@ -73,30 +77,37 @@
     }
 
     @Override
-    public final void startMonitoring(Context context, Handler target) {
+    public void startMonitoring(Context context, Handler target) {
         mContext = Preconditions.checkNotNull(context);
         mTarget = Preconditions.checkNotNull(target);
         startMonitoringInternal();
     }
 
-    protected abstract void startMonitoringInternal();
+    protected void startMonitoringInternal() {
+
+    }
 
     @Override
-    public final NetworkInfo getNetworkInfo() {
+    public NetworkInfo getNetworkInfo() {
         return new NetworkInfo(mNetworkInfo);
     }
 
     @Override
-    public final LinkProperties getLinkProperties() {
+    public LinkProperties getLinkProperties() {
         return new LinkProperties(mLinkProperties);
     }
 
     @Override
-    public final LinkCapabilities getLinkCapabilities() {
+    public LinkCapabilities getLinkCapabilities() {
         return new LinkCapabilities(mLinkCapabilities);
     }
 
     @Override
+    public LinkQualityInfo getLinkQualityInfo() {
+        return null;
+    }
+
+    @Override
     public void captivePortalCheckComplete() {
         // not implemented
     }
@@ -176,4 +187,23 @@
     public void supplyMessenger(Messenger messenger) {
         // not supported on this network
     }
+
+    @Override
+    public String getNetworkInterfaceName() {
+        if (mLinkProperties != null) {
+            return mLinkProperties.getInterfaceName();
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public void startSampling(SamplingDataTracker.SamplingSnapshot s) {
+        // nothing to do
+    }
+
+    @Override
+    public void stopSampling(SamplingDataTracker.SamplingSnapshot s) {
+        // nothing to do
+    }
 }
diff --git a/core/java/android/net/CaptivePortalTracker.java b/core/java/android/net/CaptivePortalTracker.java
index 19c5f39..01977cd 100644
--- a/core/java/android/net/CaptivePortalTracker.java
+++ b/core/java/android/net/CaptivePortalTracker.java
@@ -16,25 +16,30 @@
 
 package android.net;
 
-import android.app.Activity;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.net.ConnectivityManager;
 import android.net.IConnectivityManager;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
 import android.os.Handler;
-import android.os.UserHandle;
 import android.os.Message;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.provider.Settings;
+import android.telephony.CellIdentityCdma;
+import android.telephony.CellIdentityGsm;
+import android.telephony.CellIdentityLte;
+import android.telephony.CellIdentityWcdma;
+import android.telephony.CellInfo;
+import android.telephony.CellInfoCdma;
+import android.telephony.CellInfoGsm;
+import android.telephony.CellInfoLte;
+import android.telephony.CellInfoWcdma;
 import android.telephony.TelephonyManager;
-import android.text.TextUtils;
 
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
@@ -46,8 +51,7 @@
 import java.net.SocketTimeoutException;
 import java.net.URL;
 import java.net.UnknownHostException;
-
-import com.android.internal.R;
+import java.util.List;
 
 /**
  * This class allows captive portal detection on a network.
@@ -61,11 +65,28 @@
 
     private static final int SOCKET_TIMEOUT_MS = 10000;
 
+    public static final String ACTION_NETWORK_CONDITIONS_MEASURED =
+            "android.net.conn.NETWORK_CONDITIONS_MEASURED";
+    public static final String EXTRA_CONNECTIVITY_TYPE = "extra_connectivity_type";
+    public static final String EXTRA_NETWORK_TYPE = "extra_network_type";
+    public static final String EXTRA_RESPONSE_RECEIVED = "extra_response_received";
+    public static final String EXTRA_IS_CAPTIVE_PORTAL = "extra_is_captive_portal";
+    public static final String EXTRA_CELL_ID = "extra_cellid";
+    public static final String EXTRA_SSID = "extra_ssid";
+    public static final String EXTRA_BSSID = "extra_bssid";
+    /** real time since boot */
+    public static final String EXTRA_REQUEST_TIMESTAMP_MS = "extra_request_timestamp_ms";
+    public static final String EXTRA_RESPONSE_TIMESTAMP_MS = "extra_response_timestamp_ms";
+
+    private static final String PERMISSION_ACCESS_NETWORK_CONDITIONS =
+            "android.permission.ACCESS_NETWORK_CONDITIONS";
+
     private String mServer;
     private String mUrl;
     private boolean mIsCaptivePortalCheckEnabled = false;
     private IConnectivityManager mConnService;
     private TelephonyManager mTelephonyManager;
+    private WifiManager mWifiManager;
     private Context mContext;
     private NetworkInfo mNetworkInfo;
 
@@ -92,6 +113,7 @@
         mContext = context;
         mConnService = cs;
         mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
         mProvisioningObserver = new ProvisioningObserver();
 
         IntentFilter filter = new IntentFilter();
@@ -348,7 +370,8 @@
     }
 
     /**
-     * Do a URL fetch on a known server to see if we get the data we expect
+     * Do a URL fetch on a known server to see if we get the data we expect.
+     * Measure the response time and broadcast that.
      */
     private boolean isCaptivePortal(InetAddress server) {
         HttpURLConnection urlConnection = null;
@@ -356,6 +379,7 @@
 
         mUrl = "http://" + server.getHostAddress() + "/generate_204";
         if (DBG) log("Checking " + mUrl);
+        long requestTimestamp = -1;
         try {
             URL url = new URL(mUrl);
             urlConnection = (HttpURLConnection) url.openConnection();
@@ -363,11 +387,29 @@
             urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
             urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS);
             urlConnection.setUseCaches(false);
+
+            // Time how long it takes to get a response to our request
+            requestTimestamp = SystemClock.elapsedRealtime();
+
             urlConnection.getInputStream();
+
+            // Time how long it takes to get a response to our request
+            long responseTimestamp = SystemClock.elapsedRealtime();
+
             // we got a valid response, but not from the real google
-            return urlConnection.getResponseCode() != 204;
+            int rspCode = urlConnection.getResponseCode();
+            boolean isCaptivePortal = rspCode != 204;
+
+            sendNetworkConditionsBroadcast(true /* response received */, isCaptivePortal,
+                    requestTimestamp, responseTimestamp);
+
+            if (DBG) log("isCaptivePortal: ret=" + isCaptivePortal + " rspCode=" + rspCode);
+            return isCaptivePortal;
         } catch (IOException e) {
             if (DBG) log("Probably not a portal: exception " + e);
+            if (requestTimestamp != -1) {
+                sendFailedCaptivePortalCheckBroadcast(requestTimestamp);
+            } // else something went wrong with setting up the urlConnection
             return false;
         } finally {
             if (urlConnection != null) {
@@ -381,12 +423,91 @@
         try {
             inetAddress = InetAddress.getAllByName(hostname);
         } catch (UnknownHostException e) {
+            sendFailedCaptivePortalCheckBroadcast(SystemClock.elapsedRealtime());
             return null;
         }
 
         for (InetAddress a : inetAddress) {
             if (a instanceof Inet4Address) return a;
         }
+
+        sendFailedCaptivePortalCheckBroadcast(SystemClock.elapsedRealtime());
         return null;
     }
+
+    private void sendFailedCaptivePortalCheckBroadcast(long requestTimestampMs) {
+        sendNetworkConditionsBroadcast(false /* response received */, false /* ignored */,
+                requestTimestampMs, 0 /* ignored */);
+    }
+
+    /**
+     * @param responseReceived - whether or not we received a valid HTTP response to our request.
+     * If false, isCaptivePortal and responseTimestampMs are ignored
+     */
+    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 (DBG) log("Don't send network conditions - lacking user consent.");
+            return;
+        }
+
+        Intent latencyBroadcast = new Intent(ACTION_NETWORK_CONDITIONS_MEASURED);
+        switch (mNetworkInfo.getType()) {
+            case ConnectivityManager.TYPE_WIFI:
+                WifiInfo currentWifiInfo = mWifiManager.getConnectionInfo();
+                if (currentWifiInfo != null) {
+                    latencyBroadcast.putExtra(EXTRA_SSID, currentWifiInfo.getSSID());
+                    latencyBroadcast.putExtra(EXTRA_BSSID, currentWifiInfo.getBSSID());
+                } else {
+                    if (DBG) logw("network info is TYPE_WIFI but no ConnectionInfo found");
+                    return;
+                }
+                break;
+            case ConnectivityManager.TYPE_MOBILE:
+                latencyBroadcast.putExtra(EXTRA_NETWORK_TYPE, mTelephonyManager.getNetworkType());
+                List<CellInfo> info = mTelephonyManager.getAllCellInfo();
+                if (info == null) return;
+                StringBuffer uniqueCellId = new StringBuffer();
+                int numRegisteredCellInfo = 0;
+                for (CellInfo cellInfo : info) {
+                    if (cellInfo.isRegistered()) {
+                        numRegisteredCellInfo++;
+                        if (numRegisteredCellInfo > 1) {
+                            if (DBG) log("more than one registered CellInfo.  Can't " +
+                                    "tell which is active.  Bailing.");
+                            return;
+                        }
+                        if (cellInfo instanceof CellInfoCdma) {
+                            CellIdentityCdma cellId = ((CellInfoCdma) cellInfo).getCellIdentity();
+                            latencyBroadcast.putExtra(EXTRA_CELL_ID, cellId);
+                        } else if (cellInfo instanceof CellInfoGsm) {
+                            CellIdentityGsm cellId = ((CellInfoGsm) cellInfo).getCellIdentity();
+                            latencyBroadcast.putExtra(EXTRA_CELL_ID, cellId);
+                        } else if (cellInfo instanceof CellInfoLte) {
+                            CellIdentityLte cellId = ((CellInfoLte) cellInfo).getCellIdentity();
+                            latencyBroadcast.putExtra(EXTRA_CELL_ID, cellId);
+                        } else if (cellInfo instanceof CellInfoWcdma) {
+                            CellIdentityWcdma cellId = ((CellInfoWcdma) cellInfo).getCellIdentity();
+                            latencyBroadcast.putExtra(EXTRA_CELL_ID, cellId);
+                        } else {
+                            if (DBG) logw("Registered cellinfo is unrecognized");
+                            return;
+                        }
+                    }
+                }
+                break;
+            default:
+                return;
+        }
+        latencyBroadcast.putExtra(EXTRA_CONNECTIVITY_TYPE, mNetworkInfo.getType());
+        latencyBroadcast.putExtra(EXTRA_RESPONSE_RECEIVED, responseReceived);
+        latencyBroadcast.putExtra(EXTRA_REQUEST_TIMESTAMP_MS, requestTimestampMs);
+
+        if (responseReceived) {
+            latencyBroadcast.putExtra(EXTRA_IS_CAPTIVE_PORTAL, isCaptivePortal);
+            latencyBroadcast.putExtra(EXTRA_RESPONSE_TIMESTAMP_MS, responseTimestampMs);
+        }
+        mContext.sendBroadcast(latencyBroadcast, PERMISSION_ACCESS_NETWORK_CONDITIONS);
+    }
 }
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 02a6494..c78a973 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -355,11 +355,17 @@
      */
     public static final int TYPE_WIFI_P2P    = 13;
 
-    /** {@hide} */
-    public static final int MAX_RADIO_TYPE   = TYPE_WIFI_P2P;
+    /**
+     * The network to use for initially attaching to the network
+     * {@hide}
+     */
+    public static final int TYPE_MOBILE_IA = 14;
 
     /** {@hide} */
-    public static final int MAX_NETWORK_TYPE = TYPE_WIFI_P2P;
+    public static final int MAX_RADIO_TYPE   = TYPE_MOBILE_IA;
+
+    /** {@hide} */
+    public static final int MAX_NETWORK_TYPE = TYPE_MOBILE_IA;
 
     /**
      * If you want to set the default network preference,you can directly
@@ -436,6 +442,8 @@
                 return "MOBILE_CBS";
             case TYPE_WIFI_P2P:
                 return "WIFI_P2P";
+            case TYPE_MOBILE_IA:
+                return "MOBILE_IA";
             default:
                 return Integer.toString(type);
         }
@@ -458,6 +466,39 @@
             case TYPE_MOBILE_FOTA:
             case TYPE_MOBILE_IMS:
             case TYPE_MOBILE_CBS:
+            case TYPE_MOBILE_IA:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Checks if the given network type is backed by a Wi-Fi radio.
+     *
+     * @hide
+     */
+    public static boolean isNetworkTypeWifi(int networkType) {
+        switch (networkType) {
+            case TYPE_WIFI:
+            case TYPE_WIFI_P2P:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Checks if the given network type should be exempt from VPN routing rules
+     *
+     * @hide
+     */
+    public static boolean isNetworkTypeExempt(int networkType) {
+        switch (networkType) {
+            case TYPE_MOBILE_MMS:
+            case TYPE_MOBILE_SUPL:
+            case TYPE_MOBILE_HIPRI:
+            case TYPE_MOBILE_IA:
                 return true;
             default:
                 return false;
@@ -1382,6 +1423,45 @@
     }
 
     /**
+     * get the information about a specific network link
+     * @hide
+     */
+    public LinkQualityInfo getLinkQualityInfo(int networkType) {
+        try {
+            LinkQualityInfo li = mService.getLinkQualityInfo(networkType);
+            return li;
+        } catch (RemoteException e) {
+            return null;
+        }
+    }
+
+    /**
+     * get the information of currently active network link
+     * @hide
+     */
+    public LinkQualityInfo getActiveLinkQualityInfo() {
+        try {
+            LinkQualityInfo li = mService.getActiveLinkQualityInfo();
+            return li;
+        } catch (RemoteException e) {
+            return null;
+        }
+    }
+
+    /**
+     * get the information of all network links
+     * @hide
+     */
+    public LinkQualityInfo[] getAllLinkQualityInfo() {
+        try {
+            LinkQualityInfo[] li = mService.getAllLinkQualityInfo();
+            return li;
+        } catch (RemoteException e) {
+            return null;
+        }
+    }
+
+    /**
      * Set sign in error notification to visible or in visible
      *
      * @param visible
@@ -1396,4 +1476,20 @@
         } catch (RemoteException e) {
         }
     }
+
+    /**
+     * Set the value for enabling/disabling airplane mode
+     *
+     * @param enable whether to enable airplane mode or not
+     *
+     * <p>This method requires the call to hold the permission
+     * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
+     * @hide
+     */
+    public void setAirplaneMode(boolean enable) {
+        try {
+            mService.setAirplaneMode(enable);
+        } catch (RemoteException e) {
+        }
+    }
 }
diff --git a/core/java/android/net/DhcpStateMachine.java b/core/java/android/net/DhcpStateMachine.java
index 1ebf393..5151a04 100644
--- a/core/java/android/net/DhcpStateMachine.java
+++ b/core/java/android/net/DhcpStateMachine.java
@@ -374,7 +374,7 @@
                 //Do it a bit earlier than half the lease duration time
                 //to beat the native DHCP client and avoid extra packets
                 //48% for one hour lease time = 29 minutes
-                mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                         SystemClock.elapsedRealtime() +
                         leaseDuration * 480, //in milliseconds
                         mDhcpRenewalIntent);
diff --git a/core/java/android/net/DummyDataStateTracker.java b/core/java/android/net/DummyDataStateTracker.java
index ee738fd..51a1191 100644
--- a/core/java/android/net/DummyDataStateTracker.java
+++ b/core/java/android/net/DummyDataStateTracker.java
@@ -29,18 +29,14 @@
  *
  * {@hide}
  */
-public class DummyDataStateTracker implements NetworkStateTracker {
+public class DummyDataStateTracker extends BaseNetworkStateTracker {
 
     private static final String TAG = "DummyDataStateTracker";
     private static final boolean DBG = true;
     private static final boolean VDBG = false;
 
-    private NetworkInfo mNetworkInfo;
     private boolean mTeardownRequested = false;
     private Handler mTarget;
-    private Context mContext;
-    private LinkProperties mLinkProperties;
-    private LinkCapabilities mLinkCapabilities;
     private boolean mPrivateDnsRouteSet = false;
     private boolean mDefaultRouteSet = false;
 
diff --git a/core/java/android/net/EthernetDataTracker.java b/core/java/android/net/EthernetDataTracker.java
index 7999c66..501484c 100644
--- a/core/java/android/net/EthernetDataTracker.java
+++ b/core/java/android/net/EthernetDataTracker.java
@@ -27,6 +27,8 @@
 import android.os.ServiceManager;
 import android.util.Log;
 
+import com.android.server.net.BaseNetworkObserver;
+
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -36,7 +38,7 @@
  * ConnectivityService.
  * @hide
  */
-public class EthernetDataTracker implements NetworkStateTracker {
+public class EthernetDataTracker extends BaseNetworkStateTracker {
     private static final String NETWORKTYPE = "ETHERNET";
     private static final String TAG = "Ethernet";
 
@@ -46,15 +48,11 @@
     private AtomicBoolean mDefaultRouteSet = new AtomicBoolean(false);
 
     private static boolean mLinkUp;
-    private LinkProperties mLinkProperties;
-    private LinkCapabilities mLinkCapabilities;
-    private NetworkInfo mNetworkInfo;
     private InterfaceObserver mInterfaceObserver;
     private String mHwAddr;
 
     /* For sending events to connectivity service handler */
     private Handler mCsHandler;
-    private Context mContext;
 
     private static EthernetDataTracker sInstance;
     private static String sIfaceMatch = "";
@@ -62,7 +60,7 @@
 
     private INetworkManagementService mNMService;
 
-    private static class InterfaceObserver extends INetworkManagementEventObserver.Stub {
+    private static class InterfaceObserver extends BaseNetworkObserver {
         private EthernetDataTracker mTracker;
 
         InterfaceObserver(EthernetDataTracker tracker) {
@@ -70,10 +68,12 @@
             mTracker = tracker;
         }
 
+        @Override
         public void interfaceStatusChanged(String iface, boolean up) {
             Log.d(TAG, "Interface status changed: " + iface + (up ? "up" : "down"));
         }
 
+        @Override
         public void interfaceLinkStateChanged(String iface, boolean up) {
             if (mIface.equals(iface)) {
                 Log.d(TAG, "Interface " + iface + " link " + (up ? "up" : "down"));
@@ -89,21 +89,15 @@
             }
         }
 
+        @Override
         public void interfaceAdded(String iface) {
             mTracker.interfaceAdded(iface);
         }
 
+        @Override
         public void interfaceRemoved(String iface) {
             mTracker.interfaceRemoved(iface);
         }
-
-        public void limitReached(String limitName, String iface) {
-            // Ignored.
-        }
-
-        public void interfaceClassDataActivityChanged(String label, boolean active) {
-            // Ignored.
-        }
     }
 
     private EthernetDataTracker() {
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index a17b4f5..c1da2e3 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -16,6 +16,7 @@
 
 package android.net;
 
+import android.net.LinkQualityInfo;
 import android.net.LinkProperties;
 import android.net.NetworkInfo;
 import android.net.NetworkQuotaInfo;
@@ -37,6 +38,9 @@
 /** {@hide} */
 interface IConnectivityManager
 {
+    // Keep this in sync with framework/native/services/connectivitymanager/ConnectivityManager.h
+    void markSocketAsUser(in ParcelFileDescriptor socket, int uid);
+
     void setNetworkPreference(int pref);
 
     int getNetworkPreference();
@@ -89,12 +93,6 @@
 
     String[] getTetheredIfaces();
 
-    /**
-     * Return list of interface pairs that are actively tethered.  Even indexes are
-     * remote interface, and odd indexes are corresponding local interfaces.
-     */
-    String[] getTetheredIfacePairs();
-
     String[] getTetheringErroredIfaces();
 
     String[] getTetherableUsbRegexs();
@@ -123,6 +121,8 @@
 
     ParcelFileDescriptor establishVpn(in VpnConfig config);
 
+    VpnConfig getVpnConfig();
+
     void startLegacyVpn(in VpnProfile profile);
 
     LegacyVpnInfo getLegacyVpnInfo();
@@ -143,5 +143,13 @@
 
     String getMobileRedirectedProvisioningUrl();
 
+    LinkQualityInfo getLinkQualityInfo(int networkType);
+
+    LinkQualityInfo getActiveLinkQualityInfo();
+
+    LinkQualityInfo[] getAllLinkQualityInfo();
+
     void setProvisioningNotificationVisible(boolean visible, int networkType, in String extraInfo, in String url);
+
+    void setAirplaneMode(boolean enable);
 }
diff --git a/core/java/android/net/INetworkManagementEventObserver.aidl b/core/java/android/net/INetworkManagementEventObserver.aidl
index 6f4dd5f..b76e4c2 100644
--- a/core/java/android/net/INetworkManagementEventObserver.aidl
+++ b/core/java/android/net/INetworkManagementEventObserver.aidl
@@ -53,6 +53,27 @@
      */
     void interfaceRemoved(String iface);
 
+
+    /**
+     * An interface address has been added or updated
+     *
+     * @param address The address.
+     * @param iface The interface.
+     * @param flags The address flags.
+     * @param scope The address scope.
+     */
+    void addressUpdated(String address, String iface, int flags, int scope);
+
+    /**
+     * An interface address has been removed
+     *
+     * @param address The address.
+     * @param iface The interface.
+     * @param flags The address flags.
+     * @param scope The address scope.
+     */
+    void addressRemoved(String address, String iface, int flags, int scope);
+
     /**
      * A networking quota limit has been reached. The quota might not
      * be specific to an interface.
diff --git a/core/java/android/net/LinkAddress.java b/core/java/android/net/LinkAddress.java
index f6a114c..a390add 100644
--- a/core/java/android/net/LinkAddress.java
+++ b/core/java/android/net/LinkAddress.java
@@ -32,27 +32,56 @@
     /**
      * IPv4 or IPv6 address.
      */
-    private final InetAddress address;
+    private InetAddress address;
 
     /**
      * Network prefix length
      */
-    private final int prefixLength;
+    private int prefixLength;
 
-    public LinkAddress(InetAddress address, int prefixLength) {
+    private void init(InetAddress address, int prefixLength) {
         if (address == null || prefixLength < 0 ||
                 ((address instanceof Inet4Address) && prefixLength > 32) ||
                 (prefixLength > 128)) {
             throw new IllegalArgumentException("Bad LinkAddress params " + address +
-                    prefixLength);
+                    "/" + prefixLength);
         }
         this.address = address;
         this.prefixLength = prefixLength;
     }
 
+    public LinkAddress(InetAddress address, int prefixLength) {
+        init(address, prefixLength);
+    }
+
     public LinkAddress(InterfaceAddress interfaceAddress) {
-        this.address = interfaceAddress.getAddress();
-        this.prefixLength = interfaceAddress.getNetworkPrefixLength();
+        init(interfaceAddress.getAddress(),
+             interfaceAddress.getNetworkPrefixLength());
+    }
+
+    /**
+     * Constructs a new {@code LinkAddress} from a string such as "192.0.2.5/24" or
+     * "2001:db8::1/64".
+     * @param string The string to parse.
+     */
+    public LinkAddress(String address) {
+        InetAddress inetAddress = null;
+        int prefixLength = -1;
+        try {
+            String [] pieces = address.split("/", 2);
+            prefixLength = Integer.parseInt(pieces[1]);
+            inetAddress = InetAddress.parseNumericAddress(pieces[0]);
+        } catch (NullPointerException e) {            // Null string.
+        } catch (ArrayIndexOutOfBoundsException e) {  // No prefix length.
+        } catch (NumberFormatException e) {           // Non-numeric prefix.
+        } catch (IllegalArgumentException e) {        // Invalid IP address.
+        }
+
+        if (inetAddress == null || prefixLength == -1) {
+            throw new IllegalArgumentException("Bad LinkAddress params " + address);
+        }
+
+        init(inetAddress, prefixLength);
     }
 
     @Override
diff --git a/core/java/android/net/LinkProperties.aidl b/core/java/android/net/LinkProperties.aidl
index 9cd06d5..3cb9525 100644
--- a/core/java/android/net/LinkProperties.aidl
+++ b/core/java/android/net/LinkProperties.aidl
@@ -18,4 +18,3 @@
 package android.net;
 
 parcelable LinkProperties;
-
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 75f8b59..b4d07a1 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -23,6 +23,7 @@
 
 import java.net.InetAddress;
 import java.net.Inet4Address;
+import java.net.Inet6Address;
 
 import java.net.UnknownHostException;
 import java.util.ArrayList;
@@ -65,6 +66,7 @@
     private String mDomains;
     private Collection<RouteInfo> mRoutes = new ArrayList<RouteInfo>();
     private ProxyProperties mHttpProxy;
+    private int mMtu;
 
     // Stores the properties of links that are "stacked" above this link.
     // Indexed by interface name to allow modification and to prevent duplicates being added.
@@ -103,6 +105,7 @@
             for (LinkProperties l: source.mStackedLinks.values()) {
                 addStackedLink(l);
             }
+            setMtu(source.getMtu());
         }
     }
 
@@ -128,6 +131,9 @@
         return interfaceNames;
     }
 
+    /**
+     * Returns all the addresses on this link.
+     */
     public Collection<InetAddress> getAddresses() {
         Collection<InetAddress> addresses = new ArrayList<InetAddress>();
         for (LinkAddress linkAddress : mLinkAddresses) {
@@ -136,14 +142,73 @@
         return Collections.unmodifiableCollection(addresses);
     }
 
-    public void addLinkAddress(LinkAddress address) {
-        if (address != null) mLinkAddresses.add(address);
+    /**
+     * Returns all the addresses on this link and all the links stacked above it.
+     */
+    public Collection<InetAddress> getAllAddresses() {
+        Collection<InetAddress> addresses = new ArrayList<InetAddress>();
+        for (LinkAddress linkAddress : mLinkAddresses) {
+            addresses.add(linkAddress.getAddress());
+        }
+        for (LinkProperties stacked: mStackedLinks.values()) {
+            addresses.addAll(stacked.getAllAddresses());
+        }
+        return addresses;
     }
 
+    /**
+     * Adds a link address if it does not exist, or update it if it does.
+     * @param address The {@code LinkAddress} to add.
+     * @return true if the address was added, false if it already existed.
+     */
+    public boolean addLinkAddress(LinkAddress address) {
+        // TODO: when the LinkAddress has other attributes beyond the
+        // address and the prefix length, update them here.
+        if (address != null && !mLinkAddresses.contains(address)) {
+            mLinkAddresses.add(address);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Removes a link address.
+     * @param address The {@code LinkAddress} to remove.
+     * @return true if the address was removed, false if it did not exist.
+     */
+    public boolean removeLinkAddress(LinkAddress toRemove) {
+        return mLinkAddresses.remove(toRemove);
+    }
+
+    /**
+     * Returns all the addresses on this link.
+     */
     public Collection<LinkAddress> getLinkAddresses() {
         return Collections.unmodifiableCollection(mLinkAddresses);
     }
 
+    /**
+     * Returns all the addresses on this link and all the links stacked above it.
+     */
+    public Collection<LinkAddress> getAllLinkAddresses() {
+        Collection<LinkAddress> addresses = new ArrayList<LinkAddress>();
+        addresses.addAll(mLinkAddresses);
+        for (LinkProperties stacked: mStackedLinks.values()) {
+            addresses.addAll(stacked.getAllLinkAddresses());
+        }
+        return addresses;
+    }
+
+    /**
+     * Replaces the LinkAddresses on this link with the given collection of addresses.
+     */
+    public void setLinkAddresses(Collection<LinkAddress> addresses) {
+        mLinkAddresses.clear();
+        for (LinkAddress address: addresses) {
+            addLinkAddress(address);
+        }
+    }
+
     public void addDns(InetAddress dns) {
         if (dns != null) mDnses.add(dns);
     }
@@ -160,6 +225,14 @@
         mDomains = domains;
     }
 
+    public void setMtu(int mtu) {
+        mMtu = mtu;
+    }
+
+    public int getMtu() {
+        return mMtu;
+    }
+
     private RouteInfo routeWithInterface(RouteInfo route) {
         return new RouteInfo(
             route.getDestination(),
@@ -213,11 +286,14 @@
      * of stacked links. If link is null, nothing changes.
      *
      * @param link The link to add.
+     * @return true if the link was stacked, false otherwise.
      */
-    public void addStackedLink(LinkProperties link) {
+    public boolean addStackedLink(LinkProperties link) {
         if (link != null && link.getInterfaceName() != null) {
             mStackedLinks.put(link.getInterfaceName(), link);
+            return true;
         }
+        return false;
     }
 
     /**
@@ -226,12 +302,15 @@
      * If there a stacked link with the same interfacename as link, it is
      * removed. Otherwise, nothing changes.
      *
-     * @param link The link to add.
+     * @param link The link to remove.
+     * @return true if the link was removed, false otherwise.
      */
-    public void removeStackedLink(LinkProperties link) {
+    public boolean removeStackedLink(LinkProperties link) {
         if (link != null && link.getInterfaceName() != null) {
-            mStackedLinks.remove(link.getInterfaceName());
+            LinkProperties removed = mStackedLinks.remove(link.getInterfaceName());
+            return removed != null;
         }
+        return false;
     }
 
     /**
@@ -253,6 +332,7 @@
         mRoutes.clear();
         mHttpProxy = null;
         mStackedLinks.clear();
+        mMtu = 0;
     }
 
     /**
@@ -277,6 +357,8 @@
 
         String domainName = "Domains: " + mDomains;
 
+        String mtu = "MTU: " + mMtu;
+
         String routes = " Routes: [";
         for (RouteInfo route : mRoutes) routes += route.toString() + ",";
         routes += "] ";
@@ -290,7 +372,8 @@
             }
             stacked += "] ";
         }
-        return "{" + ifaceName + linkAddresses + routes + dns + domainName + proxy + stacked + "}";
+        return "{" + ifaceName + linkAddresses + routes + dns + domainName + mtu
+            + proxy + stacked + "}";
     }
 
     /**
@@ -308,6 +391,20 @@
     }
 
     /**
+     * Returns true if this link has an IPv6 address.
+     *
+     * @return {@code true} if there is an IPv6 address, {@code false} otherwise.
+     */
+    public boolean hasIPv6Address() {
+        for (LinkAddress address : mLinkAddresses) {
+          if (address.getAddress() instanceof Inet6Address) {
+            return true;
+          }
+        }
+        return false;
+    }
+
+    /**
      * Compares this {@code LinkProperties} interface name against the target
      *
      * @param target LinkProperties to compare.
@@ -391,6 +488,16 @@
         return true;
     }
 
+    /**
+     * Compares this {@code LinkProperties} MTU against the target
+     *
+     * @param target LinkProperties to compare.
+     * @return {@code true} if both are identical, {@code false} otherwise.
+     */
+    public boolean isIdenticalMtu(LinkProperties target) {
+        return getMtu() == target.getMtu();
+    }
+
     @Override
     /**
      * Compares this {@code LinkProperties} instance against the target
@@ -422,17 +529,16 @@
                 isIdenticalDnses(target) &&
                 isIdenticalRoutes(target) &&
                 isIdenticalHttpProxy(target) &&
-                isIdenticalStackedLinks(target);
+                isIdenticalStackedLinks(target) &&
+                isIdenticalMtu(target);
     }
 
     /**
-     * Return two lists, a list of addresses that would be removed from
-     * mLinkAddresses and a list of addresses that would be added to
-     * mLinkAddress which would then result in target and mLinkAddresses
-     * being the same list.
+     * Compares the addresses in this LinkProperties with another
+     * LinkProperties, examining only addresses on the base link.
      *
-     * @param target is a LinkProperties with the new list of addresses
-     * @return the removed and added lists.
+     * @param target a LinkProperties with the new list of addresses
+     * @return the differences between the addresses.
      */
     public CompareResult<LinkAddress> compareAddresses(LinkProperties target) {
         /*
@@ -456,13 +562,11 @@
     }
 
     /**
-     * Return two lists, a list of dns addresses that would be removed from
-     * mDnses and a list of addresses that would be added to
-     * mDnses which would then result in target and mDnses
-     * being the same list.
+     * Compares the DNS addresses in this LinkProperties with another
+     * LinkProperties, examining only DNS addresses on the base link.
      *
-     * @param target is a LinkProperties with the new list of dns addresses
-     * @return the removed and added lists.
+     * @param target a LinkProperties with the new list of dns addresses
+     * @return the differences between the DNS addresses.
      */
     public CompareResult<InetAddress> compareDnses(LinkProperties target) {
         /*
@@ -487,15 +591,13 @@
     }
 
     /**
-     * Return two lists, a list of routes that would be removed from
-     * mRoutes and a list of routes that would be added to
-     * mRoutes which would then result in target and mRoutes
-     * being the same list.
+     * Compares all routes in this LinkProperties with another LinkProperties,
+     * examining both the the base link and all stacked links.
      *
-     * @param target is a LinkProperties with the new list of routes
-     * @return the removed and added lists.
+     * @param target a LinkProperties with the new list of routes
+     * @return the differences between the routes.
      */
-    public CompareResult<RouteInfo> compareRoutes(LinkProperties target) {
+    public CompareResult<RouteInfo> compareAllRoutes(LinkProperties target) {
         /*
          * Duplicate the RouteInfos into removed, we will be removing
          * routes which are common between mRoutes and target
@@ -530,7 +632,8 @@
                 + ((null == mDomains) ? 0 : mDomains.hashCode())
                 + mRoutes.size() * 41
                 + ((null == mHttpProxy) ? 0 : mHttpProxy.hashCode())
-                + mStackedLinks.hashCode() * 47);
+                + mStackedLinks.hashCode() * 47)
+                + mMtu * 51;
     }
 
     /**
@@ -548,7 +651,7 @@
             dest.writeByteArray(d.getAddress());
         }
         dest.writeString(mDomains);
-
+        dest.writeInt(mMtu);
         dest.writeInt(mRoutes.size());
         for(RouteInfo route : mRoutes) {
             dest.writeParcelable(route, flags);
@@ -587,6 +690,7 @@
                     } catch (UnknownHostException e) { }
                 }
                 netProp.setDomains(in.readString());
+                netProp.setMtu(in.readInt());
                 addressCount = in.readInt();
                 for (int i=0; i<addressCount; i++) {
                     netProp.addRoute((RouteInfo)in.readParcelable(null));
diff --git a/core/java/android/net/LinkQualityInfo.aidl b/core/java/android/net/LinkQualityInfo.aidl
new file mode 100644
index 0000000..5e072bf
--- /dev/null
+++ b/core/java/android/net/LinkQualityInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.net;
+
+parcelable LinkQualityInfo;
diff --git a/core/java/android/net/LinkQualityInfo.java b/core/java/android/net/LinkQualityInfo.java
new file mode 100644
index 0000000..9c8e61d
--- /dev/null
+++ b/core/java/android/net/LinkQualityInfo.java
@@ -0,0 +1,286 @@
+/*
+ * 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.net;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ *  Class that represents useful attributes of generic network links
+ *  such as the upload/download throughput or packet error rate.
+ *  Generally speaking, you should be dealing with instances of
+ *  LinkQualityInfo subclasses, such as {@link android.net.#WifiLinkQualityInfo}
+ *  or {@link android.net.#MobileLinkQualityInfo} which provide additional
+ *  information.
+ *  @hide
+ */
+public class LinkQualityInfo implements Parcelable {
+
+    /**
+     * Represents a value that you can use to test if an integer field is set to a good value
+     */
+    public static final int UNKNOWN_INT = Integer.MAX_VALUE;
+
+    /**
+     * Represents a value that you can use to test if a long field is set to a good value
+     */
+    public static final long UNKNOWN_LONG = Long.MAX_VALUE;
+
+    public static final int NORMALIZED_MIN_SIGNAL_STRENGTH = 0;
+
+    public static final int NORMALIZED_MAX_SIGNAL_STRENGTH = 99;
+
+    public static final int NORMALIZED_SIGNAL_STRENGTH_RANGE =
+            NORMALIZED_MAX_SIGNAL_STRENGTH - NORMALIZED_MIN_SIGNAL_STRENGTH + 1;
+
+    /* Network type as defined by ConnectivityManager */
+    private int mNetworkType = ConnectivityManager.TYPE_NONE;
+
+    private int mNormalizedSignalStrength = UNKNOWN_INT;
+
+    private long mPacketCount = UNKNOWN_LONG;
+    private long mPacketErrorCount = UNKNOWN_LONG;
+    private int mTheoreticalTxBandwidth = UNKNOWN_INT;
+    private int mTheoreticalRxBandwidth = UNKNOWN_INT;
+    private int mTheoreticalLatency = UNKNOWN_INT;
+
+    /* Timestamp when last sample was made available */
+    private long mLastDataSampleTime = UNKNOWN_LONG;
+
+    /* Sample duration in millisecond */
+    private int mDataSampleDuration = UNKNOWN_INT;
+
+    public LinkQualityInfo() {
+
+    }
+
+    /**
+     * Implement the Parcelable interface
+     * @hide
+     */
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * Implement the Parcelable interface.
+     */
+
+    protected static final int OBJECT_TYPE_LINK_QUALITY_INFO = 1;
+    protected static final int OBJECT_TYPE_WIFI_LINK_QUALITY_INFO = 2;
+    protected static final int OBJECT_TYPE_MOBILE_LINK_QUALITY_INFO = 3;
+
+    /**
+     * @hide
+     */
+    public void writeToParcel(Parcel dest, int flags) {
+        writeToParcel(dest, flags, OBJECT_TYPE_LINK_QUALITY_INFO);
+    }
+
+    /**
+     * @hide
+     */
+    public void writeToParcel(Parcel dest, int flags, int objectType) {
+        dest.writeInt(objectType);
+        dest.writeInt(mNetworkType);
+        dest.writeInt(mNormalizedSignalStrength);
+        dest.writeLong(mPacketCount);
+        dest.writeLong(mPacketErrorCount);
+        dest.writeInt(mTheoreticalTxBandwidth);
+        dest.writeInt(mTheoreticalRxBandwidth);
+        dest.writeInt(mTheoreticalLatency);
+        dest.writeLong(mLastDataSampleTime);
+        dest.writeInt(mDataSampleDuration);
+    }
+
+    /**
+     * @hide
+     */
+    public static final Creator<LinkQualityInfo> CREATOR =
+            new Creator<LinkQualityInfo>() {
+                public LinkQualityInfo createFromParcel(Parcel in) {
+                    int objectType = in.readInt();
+                    if (objectType == OBJECT_TYPE_LINK_QUALITY_INFO) {
+                        LinkQualityInfo li = new LinkQualityInfo();
+                        li.initializeFromParcel(in);
+                        return li;
+                    } else if (objectType == OBJECT_TYPE_WIFI_LINK_QUALITY_INFO) {
+                        return WifiLinkQualityInfo.createFromParcelBody(in);
+                    } else if (objectType == OBJECT_TYPE_MOBILE_LINK_QUALITY_INFO) {
+                        return MobileLinkQualityInfo.createFromParcelBody(in);
+                    } else {
+                        return null;
+                    }
+                }
+
+                public LinkQualityInfo[] newArray(int size) {
+                    return new LinkQualityInfo[size];
+                }
+            };
+
+    /**
+     * @hide
+     */
+    protected void initializeFromParcel(Parcel in) {
+        mNetworkType = in.readInt();
+        mNormalizedSignalStrength = in.readInt();
+        mPacketCount = in.readLong();
+        mPacketErrorCount = in.readLong();
+        mTheoreticalTxBandwidth = in.readInt();
+        mTheoreticalRxBandwidth = in.readInt();
+        mTheoreticalLatency = in.readInt();
+        mLastDataSampleTime = in.readLong();
+        mDataSampleDuration = in.readInt();
+    }
+
+    /**
+     * returns the type of network this link is connected to
+     * @return network type as defined by {@link android.net.ConnectivityManager} or
+     * {@link android.net.LinkQualityInfo#UNKNOWN_INT}
+     */
+    public int getNetworkType() {
+        return mNetworkType;
+    }
+
+    /**
+     * @hide
+     */
+    public void setNetworkType(int networkType) {
+        mNetworkType = networkType;
+    }
+
+    /**
+     * returns the signal strength normalized across multiple types of networks
+     * @return an integer value from 0 - 99 or {@link android.net.LinkQualityInfo#UNKNOWN_INT}
+     */
+    public int getNormalizedSignalStrength() {
+        return mNormalizedSignalStrength;
+    }
+
+    /**
+     * @hide
+     */
+    public void setNormalizedSignalStrength(int normalizedSignalStrength) {
+        mNormalizedSignalStrength = normalizedSignalStrength;
+    }
+
+    /**
+     * returns the total number of packets sent or received in sample duration
+     * @return number of packets or {@link android.net.LinkQualityInfo#UNKNOWN_LONG}
+     */
+    public long getPacketCount() {
+        return mPacketCount;
+    }
+
+    /**
+     * @hide
+     */
+    public void setPacketCount(long packetCount) {
+        mPacketCount = packetCount;
+    }
+
+    /**
+     * returns the total number of packets errors encountered in sample duration
+     * @return number of errors or {@link android.net.LinkQualityInfo#UNKNOWN_LONG}
+     */
+    public long getPacketErrorCount() {
+        return mPacketErrorCount;
+    }
+
+    /**
+     * @hide
+     */
+    public void setPacketErrorCount(long packetErrorCount) {
+        mPacketErrorCount = packetErrorCount;
+    }
+
+    /**
+     * returns the theoretical upload bandwidth of this network
+     * @return bandwidth in Kbps or {@link android.net.LinkQualityInfo#UNKNOWN_INT}
+     */
+    public int getTheoreticalTxBandwidth() {
+        return mTheoreticalTxBandwidth;
+    }
+
+    /**
+     * @hide
+     */
+    public void setTheoreticalTxBandwidth(int theoreticalTxBandwidth) {
+        mTheoreticalTxBandwidth = theoreticalTxBandwidth;
+    }
+
+    /**
+     * returns the theoretical download bandwidth of this network
+     * @return bandwidth in Kbps or {@link android.net.LinkQualityInfo#UNKNOWN_INT}
+     */
+    public int getTheoreticalRxBandwidth() {
+        return mTheoreticalRxBandwidth;
+    }
+
+    /**
+     * @hide
+     */
+    public void setTheoreticalRxBandwidth(int theoreticalRxBandwidth) {
+        mTheoreticalRxBandwidth = theoreticalRxBandwidth;
+    }
+
+    /**
+     * returns the theoretical latency of this network
+     * @return latency in milliseconds or {@link android.net.LinkQualityInfo#UNKNOWN_INT}
+     */
+    public int getTheoreticalLatency() {
+        return mTheoreticalLatency;
+    }
+
+    /**
+     * @hide
+     */
+    public void setTheoreticalLatency(int theoreticalLatency) {
+        mTheoreticalLatency = theoreticalLatency;
+    }
+
+    /**
+     * returns the time stamp of the last sample
+     * @return milliseconds elapsed since start and sample time or
+     * {@link android.net.LinkQualityInfo#UNKNOWN_LONG}
+     */
+    public long getLastDataSampleTime() {
+        return mLastDataSampleTime;
+    }
+
+    /**
+     * @hide
+     */
+    public void setLastDataSampleTime(long lastDataSampleTime) {
+        mLastDataSampleTime = lastDataSampleTime;
+    }
+
+    /**
+     * returns the sample duration used
+     * @return duration in milliseconds or {@link android.net.LinkQualityInfo#UNKNOWN_INT}
+     */
+    public int getDataSampleDuration() {
+        return mDataSampleDuration;
+    }
+
+    /**
+     * @hide
+     */
+    public void setDataSampleDuration(int dataSampleDuration) {
+        mDataSampleDuration = dataSampleDuration;
+    }
+}
diff --git a/core/java/android/net/LocalServerSocket.java b/core/java/android/net/LocalServerSocket.java
index 2b93fc2..a36203b 100644
--- a/core/java/android/net/LocalServerSocket.java
+++ b/core/java/android/net/LocalServerSocket.java
@@ -46,7 +46,7 @@
     {
         impl = new LocalSocketImpl();
 
-        impl.create(true);
+        impl.create(LocalSocket.SOCKET_STREAM);
 
         localAddress = new LocalSocketAddress(name);
         impl.bind(localAddress);
@@ -93,7 +93,7 @@
 
         impl.accept (acceptedImpl);
 
-        return new LocalSocket(acceptedImpl);
+        return new LocalSocket(acceptedImpl, LocalSocket.SOCKET_UNKNOWN);
     }
 
     /**
diff --git a/core/java/android/net/LocalSocket.java b/core/java/android/net/LocalSocket.java
index 14a8094..31bc20b 100644
--- a/core/java/android/net/LocalSocket.java
+++ b/core/java/android/net/LocalSocket.java
@@ -34,21 +34,42 @@
     private LocalSocketAddress localAddress;
     private boolean isBound;
     private boolean isConnected;
+    private final int sockType;
+
+    /** unknown socket type (used for constructor with existing file descriptor) */
+    /* package */ static final int SOCKET_UNKNOWN = 0;
+    /** Datagram socket type */
+    public static final int SOCKET_DGRAM = 1;
+    /** Stream socket type */
+    public static final int SOCKET_STREAM = 2;
+    /** Sequential packet socket type */
+    public static final int SOCKET_SEQPACKET = 3;
 
     /**
      * Creates a AF_LOCAL/UNIX domain stream socket.
      */
     public LocalSocket() {
-        this(new LocalSocketImpl());
+        this(SOCKET_STREAM);
+    }
+
+    /**
+     * Creates a AF_LOCAL/UNIX domain stream socket with given socket type
+     *
+     * @param sockType either {@link #SOCKET_DGRAM}, {@link #SOCKET_STREAM}
+     * or {@link #SOCKET_SEQPACKET}
+     */
+    public LocalSocket(int sockType) {
+        this(new LocalSocketImpl(), sockType);
         isBound = false;
         isConnected = false;
     }
+
     /**
      * Creates a AF_LOCAL/UNIX domain stream socket with FileDescriptor.
      * @hide
      */
     public LocalSocket(FileDescriptor fd) throws IOException {
-        this(new LocalSocketImpl(fd));
+        this(new LocalSocketImpl(fd), SOCKET_UNKNOWN);
         isBound = true;
         isConnected = true;
     }
@@ -57,8 +78,9 @@
      * for use with AndroidServerSocket
      * @param impl a SocketImpl
      */
-    /*package*/ LocalSocket(LocalSocketImpl impl) {
+    /*package*/ LocalSocket(LocalSocketImpl impl, int sockType) {
         this.impl = impl;
+        this.sockType = sockType;
         this.isConnected = false;
         this.isBound = false;
     }
@@ -81,7 +103,7 @@
             synchronized (this) {
                 if (!implCreated) {
                     try {
-                        impl.create(true);
+                        impl.create(sockType);
                     } finally {
                         implCreated = true;
                     }
diff --git a/core/java/android/net/LocalSocketImpl.java b/core/java/android/net/LocalSocketImpl.java
index 3b43c36..b2ee50a 100644
--- a/core/java/android/net/LocalSocketImpl.java
+++ b/core/java/android/net/LocalSocketImpl.java
@@ -22,6 +22,10 @@
 import java.io.FileDescriptor;
 import java.net.SocketOptions;
 
+import libcore.io.ErrnoException;
+import libcore.io.Libcore;
+import libcore.io.OsConstants;
+
 /**
  * Socket implementation used for android.net.LocalSocket and
  * android.net.LocalServerSocket. Supports only AF_LOCAL sockets.
@@ -35,6 +39,8 @@
 
     /** null if closed or not yet created */
     private FileDescriptor fd;
+    /** whether fd is created internally */
+    private boolean mFdCreatedInternally;
 
     // These fields are accessed by native code;
     /** file descriptor array received during a previous read */
@@ -159,7 +165,6 @@
 
     private native int pending_native(FileDescriptor fd) throws IOException;
     private native int available_native(FileDescriptor fd) throws IOException;
-    private native void close_native(FileDescriptor fd) throws IOException;
     private native int read_native(FileDescriptor fd) throws IOException;
     private native int readba_native(byte[] b, int off, int len,
             FileDescriptor fd) throws IOException;
@@ -171,8 +176,6 @@
             int namespace) throws IOException;
     private native void bindLocal(FileDescriptor fd, String name, int namespace)
             throws IOException;
-    private native FileDescriptor create_native(boolean stream)
-            throws IOException;
     private native void listen_native(FileDescriptor fd, int backlog)
             throws IOException;
     private native void shutdown(FileDescriptor fd, boolean shutdownInput);
@@ -222,15 +225,34 @@
     /**
      * Creates a socket in the underlying OS.
      *
-     * @param stream true if this should be a stream socket, false for
-     * datagram.
+     * @param sockType either {@link LocalSocket#SOCKET_DGRAM}, {@link LocalSocket#SOCKET_STREAM}
+     * or {@link LocalSocket#SOCKET_SEQPACKET}
      * @throws IOException
      */
-    public void create (boolean stream) throws IOException {
+    public void create (int sockType) throws IOException {
         // no error if socket already created
         // need this for LocalServerSocket.accept()
         if (fd == null) {
-            fd = create_native(stream);
+            int osType;
+            switch (sockType) {
+                case LocalSocket.SOCKET_DGRAM:
+                    osType = OsConstants.SOCK_DGRAM;
+                    break;
+                case LocalSocket.SOCKET_STREAM:
+                    osType = OsConstants.SOCK_STREAM;
+                    break;
+                case LocalSocket.SOCKET_SEQPACKET:
+                    osType = OsConstants.SOCK_SEQPACKET;
+                    break;
+                default:
+                    throw new IllegalStateException("unknown sockType");
+            }
+            try {
+                fd = Libcore.os.socket(OsConstants.AF_UNIX, osType, 0);
+                mFdCreatedInternally = true;
+            } catch (ErrnoException e) {
+                e.rethrowAsIOException();
+            }
         }
     }
 
@@ -241,8 +263,15 @@
      */
     public void close() throws IOException {
         synchronized (LocalSocketImpl.this) {
-            if (fd == null) return;
-            close_native(fd);
+            if ((fd == null) || (mFdCreatedInternally == false)) {
+                fd = null;
+                return;
+            }
+            try {
+                Libcore.os.close(fd);
+            } catch (ErrnoException e) {
+                e.rethrowAsIOException();
+            }
             fd = null;
         }
     }
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index e09254b..b914940 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -28,6 +28,8 @@
 import android.os.Messenger;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.telephony.PhoneStateListener;
+import android.telephony.SignalStrength;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Slog;
@@ -49,7 +51,7 @@
  *
  * {@hide}
  */
-public class MobileDataStateTracker implements NetworkStateTracker {
+public class MobileDataStateTracker extends BaseNetworkStateTracker {
 
     private static final String TAG = "MobileDataStateTracker";
     private static final boolean DBG = true;
@@ -78,6 +80,12 @@
 
     private AtomicBoolean mIsCaptivePortal = new AtomicBoolean(false);
 
+    private SignalStrength mSignalStrength;
+
+    private SamplingDataTracker mSamplingDataTracker = new SamplingDataTracker();
+
+    private static final int UNKNOWN = LinkQualityInfo.UNKNOWN_INT;
+
     /**
      * Create a new MobileDataStateTracker
      * @param netType the ConnectivityManager network type
@@ -109,8 +117,19 @@
 
         mContext.registerReceiver(new MobileDataStateReceiver(), filter);
         mMobileDataState = PhoneConstants.DataState.DISCONNECTED;
+
+        TelephonyManager tm = (TelephonyManager)mContext.getSystemService(
+                Context.TELEPHONY_SERVICE);
+        tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
     }
 
+    private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
+        @Override
+        public void onSignalStrengthsChanged(SignalStrength signalStrength) {
+            mSignalStrength = signalStrength;
+        }
+    };
+
     static class MdstHandler extends Handler {
         private MobileDataStateTracker mMdst;
 
@@ -179,6 +198,8 @@
             loge("CONNECTED event did not supply link properties.");
             mLinkProperties = new LinkProperties();
         }
+        mLinkProperties.setMtu(mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_mobile_mtu));
         mLinkCapabilities = intent.getParcelableExtra(
                 PhoneConstants.DATA_LINK_CAPABILITIES_KEY);
         if (mLinkCapabilities == null) {
@@ -215,12 +236,14 @@
             } else if (intent.getAction().equals(TelephonyIntents.
                     ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) {
                 String apnType = intent.getStringExtra(PhoneConstants.DATA_APN_TYPE_KEY);
+                if (VDBG) {
+                    log(String.format("Broadcast received: ACTION_ANY_DATA_CONNECTION_STATE_CHANGED"
+                        + "mApnType=%s %s received apnType=%s", mApnType,
+                        TextUtils.equals(apnType, mApnType) ? "==" : "!=", apnType));
+                }
                 if (!TextUtils.equals(apnType, mApnType)) {
                     return;
                 }
-                if (DBG) {
-                    log("Broadcast received: " + intent.getAction() + " apnType=" + apnType);
-                }
 
                 int oldSubtype = mNetworkInfo.getSubtype();
                 int newSubType = TelephonyManager.getDefault().getNetworkType();
@@ -238,7 +261,7 @@
                 String apnName = intent.getStringExtra(PhoneConstants.DATA_APN_KEY);
                 mNetworkInfo.setRoaming(intent.getBooleanExtra(
                         PhoneConstants.DATA_NETWORK_ROAMING_KEY, false));
-                if (DBG) {
+                if (VDBG) {
                     log(mApnType + " setting isAvailable to " +
                             intent.getBooleanExtra(PhoneConstants.NETWORK_UNAVAILABLE_KEY,false));
                 }
@@ -276,6 +299,30 @@
                             setDetailedState(DetailedState.CONNECTED, reason, apnName);
                             break;
                     }
+
+                    if (VDBG) {
+                        Slog.d(TAG, "TelephonyMgr.DataConnectionStateChanged");
+                        if (mNetworkInfo != null) {
+                            Slog.d(TAG, "NetworkInfo = " + mNetworkInfo.toString());
+                            Slog.d(TAG, "subType = " + String.valueOf(mNetworkInfo.getSubtype()));
+                            Slog.d(TAG, "subType = " + mNetworkInfo.getSubtypeName());
+                        }
+                        if (mLinkProperties != null) {
+                            Slog.d(TAG, "LinkProperties = " + mLinkProperties.toString());
+                        } else {
+                            Slog.d(TAG, "LinkProperties = " );
+                        }
+
+                        if (mLinkCapabilities != null) {
+                            Slog.d(TAG, "LinkCapabilities = " + mLinkCapabilities.toString());
+                        } else {
+                            Slog.d(TAG, "LinkCapabilities = " );
+                        }
+                    }
+
+
+                    /* lets not sample traffic data across state changes */
+                    mSamplingDataTracker.resetSamplingData();
                 } else {
                     // There was no state change. Check if LinkProperties has been updated.
                     if (TextUtils.equals(reason, PhoneConstants.REASON_LINK_PROPERTIES_CHANGED)) {
@@ -297,6 +344,11 @@
                     equals(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED)) {
                 String apnType = intent.getStringExtra(PhoneConstants.DATA_APN_TYPE_KEY);
                 if (!TextUtils.equals(apnType, mApnType)) {
+                    if (DBG) {
+                        log(String.format(
+                                "Broadcast received: ACTION_ANY_DATA_CONNECTION_FAILED ignore, " +
+                                "mApnType=%s != received apnType=%s", mApnType, apnType));
+                    }
                     return;
                 }
                 String reason = intent.getStringExtra(PhoneConstants.FAILURE_REASON_KEY);
@@ -618,7 +670,7 @@
         return writer.toString();
     }
 
-   /**
+    /**
      * Internal method supporting the ENABLE_MMS feature.
      * @param apnType the type of APN to be enabled or disabled (e.g., mms)
      * @param enable {@code true} to enable the specified APN type,
@@ -670,15 +722,19 @@
                 return PhoneConstants.APN_TYPE_IMS;
             case ConnectivityManager.TYPE_MOBILE_CBS:
                 return PhoneConstants.APN_TYPE_CBS;
+            case ConnectivityManager.TYPE_MOBILE_IA:
+                return PhoneConstants.APN_TYPE_IA;
             default:
                 sloge("Error mapping networkType " + netType + " to apnType.");
                 return null;
         }
     }
 
+
     /**
      * @see android.net.NetworkStateTracker#getLinkProperties()
      */
+    @Override
     public LinkProperties getLinkProperties() {
         return new LinkProperties(mLinkProperties);
     }
@@ -686,6 +742,7 @@
     /**
      * @see android.net.NetworkStateTracker#getLinkCapabilities()
      */
+    @Override
     public LinkCapabilities getLinkCapabilities() {
         return new LinkCapabilities(mLinkCapabilities);
     }
@@ -707,4 +764,152 @@
     static private void sloge(String s) {
         Slog.e(TAG, s);
     }
+
+    @Override
+    public LinkQualityInfo getLinkQualityInfo() {
+        if (mNetworkInfo == null || mNetworkInfo.getType() == ConnectivityManager.TYPE_NONE) {
+            // no data available yet; just return
+            return null;
+        }
+
+        MobileLinkQualityInfo li = new MobileLinkQualityInfo();
+
+        li.setNetworkType(mNetworkInfo.getType());
+
+        mSamplingDataTracker.setCommonLinkQualityInfoFields(li);
+
+        if (mNetworkInfo.getSubtype() != TelephonyManager.NETWORK_TYPE_UNKNOWN) {
+            li.setMobileNetworkType(mNetworkInfo.getSubtype());
+
+            NetworkDataEntry entry = getNetworkDataEntry(mNetworkInfo.getSubtype());
+            if (entry != null) {
+                li.setTheoreticalRxBandwidth(entry.downloadBandwidth);
+                li.setTheoreticalRxBandwidth(entry.uploadBandwidth);
+                li.setTheoreticalLatency(entry.latency);
+            }
+
+            if (mSignalStrength != null) {
+                li.setNormalizedSignalStrength(getNormalizedSignalStrength(
+                        li.getMobileNetworkType(), mSignalStrength));
+            }
+        }
+
+        SignalStrength ss = mSignalStrength;
+        if (ss != null) {
+
+            li.setRssi(ss.getGsmSignalStrength());
+            li.setGsmErrorRate(ss.getGsmBitErrorRate());
+            li.setCdmaDbm(ss.getCdmaDbm());
+            li.setCdmaEcio(ss.getCdmaEcio());
+            li.setEvdoDbm(ss.getEvdoDbm());
+            li.setEvdoEcio(ss.getEvdoEcio());
+            li.setEvdoSnr(ss.getEvdoSnr());
+            li.setLteSignalStrength(ss.getLteSignalStrength());
+            li.setLteRsrp(ss.getLteRsrp());
+            li.setLteRsrq(ss.getLteRsrq());
+            li.setLteRssnr(ss.getLteRssnr());
+            li.setLteCqi(ss.getLteCqi());
+        }
+
+        if (VDBG) {
+            Slog.d(TAG, "Returning LinkQualityInfo with"
+                    + " MobileNetworkType = " + String.valueOf(li.getMobileNetworkType())
+                    + " Theoretical Rx BW = " + String.valueOf(li.getTheoreticalRxBandwidth())
+                    + " gsm Signal Strength = " + String.valueOf(li.getRssi())
+                    + " cdma Signal Strength = " + String.valueOf(li.getCdmaDbm())
+                    + " evdo Signal Strength = " + String.valueOf(li.getEvdoDbm())
+                    + " Lte Signal Strength = " + String.valueOf(li.getLteSignalStrength()));
+        }
+
+        return li;
+    }
+
+    static class NetworkDataEntry {
+        public int networkType;
+        public int downloadBandwidth;               // in kbps
+        public int uploadBandwidth;                 // in kbps
+        public int latency;                         // in millisecond
+
+        NetworkDataEntry(int i1, int i2, int i3, int i4) {
+            networkType = i1;
+            downloadBandwidth = i2;
+            uploadBandwidth = i3;
+            latency = i4;
+        }
+    }
+
+    private static NetworkDataEntry [] mTheoreticalBWTable = new NetworkDataEntry[] {
+            new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_EDGE,      237,     118, UNKNOWN),
+            new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_GPRS,       48,      40, UNKNOWN),
+            new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_UMTS,      384,      64, UNKNOWN),
+            new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_HSDPA,   14400, UNKNOWN, UNKNOWN),
+            new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_HSUPA,   14400,    5760, UNKNOWN),
+            new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_HSPA,    14400,    5760, UNKNOWN),
+            new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_HSPAP,   21000,    5760, UNKNOWN),
+            new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_CDMA,  UNKNOWN, UNKNOWN, UNKNOWN),
+            new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_1xRTT, UNKNOWN, UNKNOWN, UNKNOWN),
+            new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_EVDO_0,   2468,     153, UNKNOWN),
+            new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_EVDO_A,   3072,    1800, UNKNOWN),
+            new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_EVDO_B,  14700,    1800, UNKNOWN),
+            new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_IDEN,  UNKNOWN, UNKNOWN, UNKNOWN),
+            new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_LTE,    100000,   50000, UNKNOWN),
+            new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_EHRPD, UNKNOWN, UNKNOWN, UNKNOWN),
+    };
+
+    private static NetworkDataEntry getNetworkDataEntry(int networkType) {
+        for (NetworkDataEntry entry : mTheoreticalBWTable) {
+            if (entry.networkType == networkType) {
+                return entry;
+            }
+        }
+
+        Slog.e(TAG, "Could not find Theoretical BW entry for " + String.valueOf(networkType));
+        return null;
+    }
+
+    private static int getNormalizedSignalStrength(int networkType, SignalStrength ss) {
+
+        int level;
+
+        switch(networkType) {
+            case TelephonyManager.NETWORK_TYPE_EDGE:
+            case TelephonyManager.NETWORK_TYPE_GPRS:
+            case TelephonyManager.NETWORK_TYPE_UMTS:
+            case TelephonyManager.NETWORK_TYPE_HSDPA:
+            case TelephonyManager.NETWORK_TYPE_HSUPA:
+            case TelephonyManager.NETWORK_TYPE_HSPA:
+            case TelephonyManager.NETWORK_TYPE_HSPAP:
+                level = ss.getGsmLevel();
+                break;
+            case TelephonyManager.NETWORK_TYPE_CDMA:
+            case TelephonyManager.NETWORK_TYPE_1xRTT:
+                level = ss.getCdmaLevel();
+                break;
+            case TelephonyManager.NETWORK_TYPE_EVDO_0:
+            case TelephonyManager.NETWORK_TYPE_EVDO_A:
+            case TelephonyManager.NETWORK_TYPE_EVDO_B:
+                level = ss.getEvdoLevel();
+                break;
+            case TelephonyManager.NETWORK_TYPE_LTE:
+                level = ss.getLteLevel();
+                break;
+            case TelephonyManager.NETWORK_TYPE_IDEN:
+            case TelephonyManager.NETWORK_TYPE_EHRPD:
+            default:
+                return UNKNOWN;
+        }
+
+        return (level * LinkQualityInfo.NORMALIZED_SIGNAL_STRENGTH_RANGE) /
+                SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
+    }
+
+    @Override
+    public void startSampling(SamplingDataTracker.SamplingSnapshot s) {
+        mSamplingDataTracker.startSampling(s);
+    }
+
+    @Override
+    public void stopSampling(SamplingDataTracker.SamplingSnapshot s) {
+        mSamplingDataTracker.stopSampling(s);
+    }
 }
diff --git a/core/java/android/net/MobileLinkQualityInfo.java b/core/java/android/net/MobileLinkQualityInfo.java
new file mode 100644
index 0000000..a01fc80
--- /dev/null
+++ b/core/java/android/net/MobileLinkQualityInfo.java
@@ -0,0 +1,286 @@
+/*
+ * 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.net;
+
+import android.os.Parcel;
+
+/**
+ *  Class that represents useful attributes of mobile network links
+ *  such as the upload/download throughput or error rate etc.
+ *  @hide
+ */
+public class MobileLinkQualityInfo extends LinkQualityInfo {
+    // Represents TelephonyManager.NetworkType
+    private int mMobileNetworkType = UNKNOWN_INT;
+    private int mRssi = UNKNOWN_INT;
+    private int mGsmErrorRate = UNKNOWN_INT;
+    private int mCdmaDbm = UNKNOWN_INT;
+    private int mCdmaEcio = UNKNOWN_INT;
+    private int mEvdoDbm = UNKNOWN_INT;
+    private int mEvdoEcio = UNKNOWN_INT;
+    private int mEvdoSnr = UNKNOWN_INT;
+    private int mLteSignalStrength = UNKNOWN_INT;
+    private int mLteRsrp = UNKNOWN_INT;
+    private int mLteRsrq = UNKNOWN_INT;
+    private int mLteRssnr = UNKNOWN_INT;
+    private int mLteCqi = UNKNOWN_INT;
+
+    /**
+     * Implement the Parcelable interface.
+     * @hide
+     */
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        super.writeToParcel(dest, flags, OBJECT_TYPE_MOBILE_LINK_QUALITY_INFO);
+
+        dest.writeInt(mMobileNetworkType);
+        dest.writeInt(mRssi);
+        dest.writeInt(mGsmErrorRate);
+        dest.writeInt(mCdmaDbm);
+        dest.writeInt(mCdmaEcio);
+        dest.writeInt(mEvdoDbm);
+        dest.writeInt(mEvdoEcio);
+        dest.writeInt(mEvdoSnr);
+        dest.writeInt(mLteSignalStrength);
+        dest.writeInt(mLteRsrp);
+        dest.writeInt(mLteRsrq);
+        dest.writeInt(mLteRssnr);
+        dest.writeInt(mLteCqi);
+    }
+
+    /* Un-parceling helper */
+    /**
+     * @hide
+     */
+    public static MobileLinkQualityInfo createFromParcelBody(Parcel in) {
+
+        MobileLinkQualityInfo li = new MobileLinkQualityInfo();
+
+        li.initializeFromParcel(in);
+
+        li.mMobileNetworkType = in.readInt();
+        li.mRssi = in.readInt();
+        li.mGsmErrorRate = in.readInt();
+        li.mCdmaDbm = in.readInt();
+        li.mCdmaEcio = in.readInt();
+        li.mEvdoDbm = in.readInt();
+        li.mEvdoEcio = in.readInt();
+        li.mEvdoSnr = in.readInt();
+        li.mLteSignalStrength = in.readInt();
+        li.mLteRsrp = in.readInt();
+        li.mLteRsrq = in.readInt();
+        li.mLteRssnr = in.readInt();
+        li.mLteCqi = in.readInt();
+
+        return li;
+    }
+
+    /**
+     * returns mobile network type as defined by {@link android.telephony.TelephonyManager}
+     * @return network type or {@link android.net.LinkQualityInfo#UNKNOWN_INT}
+     */
+    public int getMobileNetworkType() {
+        return mMobileNetworkType;
+    }
+
+    /**
+     * @hide
+     */
+    public void setMobileNetworkType(int mobileNetworkType) {
+        mMobileNetworkType = mobileNetworkType;
+    }
+
+    /**
+     * returns signal strength for GSM networks
+     * @return signal strength in db or {@link android.net.LinkQualityInfo#UNKNOWN_INT}
+     */
+    public int getRssi() {
+        return mRssi;
+    }
+
+    /**
+     * @hide
+     */
+    public void setRssi(int Rssi) {
+        mRssi = Rssi;
+    }
+
+    /**
+     * returns error rates for GSM networks
+     * @return error rate or {@link android.net.LinkQualityInfo#UNKNOWN_INT}
+     */
+    public int getGsmErrorRate() {
+        return mGsmErrorRate;
+    }
+
+    /**
+     * @hide
+     */
+    public void setGsmErrorRate(int gsmErrorRate) {
+        mGsmErrorRate = gsmErrorRate;
+    }
+
+    /**
+     * returns signal strength for CDMA networks
+     * @return signal strength in db or {@link android.net.LinkQualityInfo#UNKNOWN_INT}
+     */
+    public int getCdmaDbm() {
+        return mCdmaDbm;
+    }
+
+    /**
+     * @hide
+     */
+    public void setCdmaDbm(int cdmaDbm) {
+        mCdmaDbm = cdmaDbm;
+    }
+
+    /**
+     * returns signal to noise ratio for CDMA networks
+     * @return signal to noise ratio in db or {@link android.net.LinkQualityInfo#UNKNOWN_INT}
+     */
+    public int getCdmaEcio() {
+        return mCdmaEcio;
+    }
+
+    /**
+     * @hide
+     */
+    public void setCdmaEcio(int cdmaEcio) {
+        mCdmaEcio = cdmaEcio;
+    }
+
+    /**
+     * returns signal strength for EVDO networks
+     * @return signal strength in db or {@link android.net.LinkQualityInfo#UNKNOWN_INT}
+     */
+    public int getEvdoDbm() {
+        return mEvdoDbm;
+    }
+
+    /**
+     * @hide
+     */
+    public void setEvdoDbm(int evdoDbm) {
+        mEvdoDbm = evdoDbm;
+    }
+
+    /**
+     * returns signal to noise ratio for EVDO spectrum
+     * @return signal to noise ration in db or {@link android.net.LinkQualityInfo#UNKNOWN_INT}
+     */
+    public int getEvdoEcio() {
+        return mEvdoEcio;
+    }
+
+    /**
+     * @hide
+     */
+    public void setEvdoEcio(int evdoEcio) {
+        mEvdoEcio = evdoEcio;
+    }
+
+    /**
+     * returns end-to-end signal to noise ratio for EVDO networks
+     * @return signal to noise ration in db or {@link android.net.LinkQualityInfo#UNKNOWN_INT}
+     */
+    public int getEvdoSnr() {
+        return mEvdoSnr;
+    }
+
+    /**
+     * @hide
+     */
+    public void setEvdoSnr(int evdoSnr) {
+        mEvdoSnr = evdoSnr;
+    }
+
+    /**
+     * returns signal strength for LTE network
+     * @return signal strength in db or {@link android.net.LinkQualityInfo#UNKNOWN_INT}
+     */
+    public int getLteSignalStrength() {
+        return mLteSignalStrength;
+    }
+
+    /**
+     * @hide
+     */
+    public void setLteSignalStrength(int lteSignalStrength) {
+        mLteSignalStrength = lteSignalStrength;
+    }
+
+    /**
+     * returns RSRP (Reference Signal Received Power) for LTE network
+     * @return RSRP in db or {@link android.net.LinkQualityInfo#UNKNOWN_INT}
+     */
+    public int getLteRsrp() {
+        return mLteRsrp;
+    }
+
+    /**
+     * @hide
+     */
+    public void setLteRsrp(int lteRsrp) {
+        mLteRsrp = lteRsrp;
+    }
+
+    /**
+     * returns RSRQ (Reference Signal Received Quality) for LTE network
+     * @return RSRQ ??? or {@link android.net.LinkQualityInfo#UNKNOWN_INT}
+     */
+    public int getLteRsrq() {
+        return mLteRsrq;
+    }
+
+    /**
+     * @hide
+     */
+    public void setLteRsrq(int lteRsrq) {
+        mLteRsrq = lteRsrq;
+    }
+
+    /**
+     * returns signal to noise ratio for LTE networks
+     * @return signal to noise ration in db or {@link android.net.LinkQualityInfo#UNKNOWN_INT}
+     */
+    public int getLteRssnr() {
+        return mLteRssnr;
+    }
+
+    /**
+     * @hide
+     */
+    public void setLteRssnr(int lteRssnr) {
+        mLteRssnr = lteRssnr;
+    }
+
+    /**
+     * returns channel quality indicator for LTE networks
+     * @return CQI or {@link android.net.LinkQualityInfo#UNKNOWN_INT}
+     */
+    public int getLteCqi() {
+        return mLteCqi;
+    }
+
+    /**
+     * @hide
+     */
+    public void setLteCqi(int lteCqi) {
+        mLteCqi = lteCqi;
+    }
+}
diff --git a/core/java/android/net/NetworkStateTracker.java b/core/java/android/net/NetworkStateTracker.java
index 9ed7533..1ca9255 100644
--- a/core/java/android/net/NetworkStateTracker.java
+++ b/core/java/android/net/NetworkStateTracker.java
@@ -83,7 +83,6 @@
      */
     public static final int EVENT_NETWORK_DISCONNECTED = BASE_NETWORK_STATE_TRACKER + 5;
 
-
     /**
      * -------------------------------------------------------------
      * Control Interface
@@ -120,6 +119,12 @@
     public LinkCapabilities getLinkCapabilities();
 
     /**
+     * Get interesting information about this network link
+     * @return a copy of link information, null if not available
+     */
+    public LinkQualityInfo getLinkQualityInfo();
+
+    /**
      * Return the system properties name associated with the tcp buffer sizes
      * for this network.
      */
@@ -234,4 +239,20 @@
      * the underlying network specific code.
      */
     public void supplyMessenger(Messenger messenger);
+
+    /*
+     * Network interface name that we'll lookup for sampling data
+     */
+    public String getNetworkInterfaceName();
+
+    /*
+     * Save the starting sample
+     */
+    public void startSampling(SamplingDataTracker.SamplingSnapshot s);
+
+    /*
+     * Save the ending sample
+     */
+    public void stopSampling(SamplingDataTracker.SamplingSnapshot s);
+
 }
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index 4ab479e..b24d396 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -21,6 +21,7 @@
 import java.net.Inet6Address;
 import java.net.UnknownHostException;
 import java.util.Collection;
+import java.util.Locale;
 
 import android.util.Log;
 
@@ -103,6 +104,11 @@
     public native static String getDhcpError();
 
     /**
+     * Set the SO_MARK of {@code socketfd} to {@code mark}
+     */
+    public native static void markSocket(int socketfd, int mark);
+
+    /**
      * Convert a IPv4 address from an integer to an InetAddress.
      * @param hostAddress an int corresponding to the IPv4 address in network byte order
      */
@@ -223,7 +229,7 @@
     public static InetAddress hexToInet6Address(String addrHexString)
             throws IllegalArgumentException {
         try {
-            return numericToInetAddress(String.format("%s:%s:%s:%s:%s:%s:%s:%s",
+            return numericToInetAddress(String.format(Locale.US, "%s:%s:%s:%s:%s:%s:%s:%s",
                     addrHexString.substring(0,4),   addrHexString.substring(4,8),
                     addrHexString.substring(8,12),  addrHexString.substring(12,16),
                     addrHexString.substring(16,20), addrHexString.substring(20,24),
diff --git a/core/java/android/net/PacProxySelector.java b/core/java/android/net/PacProxySelector.java
new file mode 100644
index 0000000..b674324
--- /dev/null
+++ b/core/java/android/net/PacProxySelector.java
@@ -0,0 +1,114 @@
+/*
+ * 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.net;
+
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+
+import com.android.net.IProxyService;
+import com.google.android.collect.Lists;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.MalformedURLException;
+import java.net.Proxy;
+import java.net.Proxy.Type;
+import java.net.ProxySelector;
+import java.net.SocketAddress;
+import java.net.URI;
+import java.util.List;
+
+/**
+ * @hide
+ */
+public class PacProxySelector extends ProxySelector {
+    private static final String TAG = "PacProxySelector";
+    public static final String PROXY_SERVICE = "com.android.net.IProxyService";
+    private IProxyService mProxyService;
+    private final List<Proxy> mDefaultList;
+
+    public PacProxySelector() {
+        mProxyService = IProxyService.Stub.asInterface(
+                ServiceManager.getService(PROXY_SERVICE));
+        if (mProxyService == null) {
+            // Added because of b10267814 where mako is restarting.
+            Log.e(TAG, "PacManager: no proxy service");
+        }
+        mDefaultList = Lists.newArrayList(java.net.Proxy.NO_PROXY);
+    }
+
+    @Override
+    public List<Proxy> select(URI uri) {
+        if (mProxyService == null) {
+            mProxyService = IProxyService.Stub.asInterface(
+                    ServiceManager.getService(PROXY_SERVICE));
+        }
+        if (mProxyService == null) {
+            Log.e(TAG, "select: no proxy service return NO_PROXY");
+            return Lists.newArrayList(java.net.Proxy.NO_PROXY);
+        }
+        String response = null;
+        String urlString;
+        try {
+            urlString = uri.toURL().toString();
+        } catch (MalformedURLException e) {
+            urlString = uri.getHost();
+        }
+        try {
+            response = mProxyService.resolvePacFile(uri.getHost(), urlString);
+        } catch (RemoteException e) {
+            e.printStackTrace();
+        }
+        if (response == null) {
+            return mDefaultList;
+        }
+
+        return parseResponse(response);
+    }
+
+    private static List<Proxy> parseResponse(String response) {
+        String[] split = response.split(";");
+        List<Proxy> ret = Lists.newArrayList();
+        for (String s : split) {
+            String trimmed = s.trim();
+            if (trimmed.equals("DIRECT")) {
+                ret.add(java.net.Proxy.NO_PROXY);
+            } else if (trimmed.startsWith("PROXY ")) {
+                String[] hostPort = trimmed.substring(6).split(":");
+                String host = hostPort[0];
+                int port;
+                try {
+                    port = Integer.parseInt(hostPort[1]);
+                } catch (Exception e) {
+                    port = 8080;
+                }
+                ret.add(new Proxy(Type.HTTP, new InetSocketAddress(host, port)));
+            }
+        }
+        if (ret.size() == 0) {
+            ret.add(java.net.Proxy.NO_PROXY);
+        }
+        return ret;
+    }
+
+    @Override
+    public void connectFailed(URI uri, SocketAddress address, IOException failure) {
+
+    }
+
+}
diff --git a/core/java/android/net/Proxy.java b/core/java/android/net/Proxy.java
index a408ea0..c3e1438 100644
--- a/core/java/android/net/Proxy.java
+++ b/core/java/android/net/Proxy.java
@@ -18,38 +18,25 @@
 
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
-import android.content.ContentResolver;
 import android.content.Context;
-import android.database.ContentObserver;
-import android.net.ProxyProperties;
-import android.os.Handler;
-import android.os.SystemProperties;
 import android.text.TextUtils;
-import android.provider.Settings;
 import android.util.Log;
 
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.ProxySelector;
-import java.net.SocketAddress;
-import java.net.URI;
-import java.net.UnknownHostException;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
-import junit.framework.Assert;
-
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
 import org.apache.http.conn.routing.HttpRoute;
 import org.apache.http.conn.routing.HttpRoutePlanner;
 import org.apache.http.conn.scheme.SchemeRegistry;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpRequest;
-import org.apache.http.impl.conn.ProxySelectorRoutePlanner;
 import org.apache.http.protocol.HttpContext;
 
+import java.net.InetSocketAddress;
+import java.net.ProxySelector;
+import java.net.URI;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 /**
  * A convenience class for accessing the user and default proxy
  * settings.
@@ -60,6 +47,8 @@
     private static final boolean DEBUG = false;
     private static final String TAG = "Proxy";
 
+    private static final ProxySelector sDefaultProxySelector;
+
     /**
      * Used to notify an app that's caching the default connection proxy
      * that either the default connection or its proxy has changed.
@@ -96,6 +85,7 @@
     static {
         HOSTNAME_PATTERN = Pattern.compile(HOSTNAME_REGEXP);
         EXCLLIST_PATTERN = Pattern.compile(EXCLLIST_REGEXP);
+        sDefaultProxySelector = ProxySelector.getDefault();
     }
 
     /**
@@ -325,16 +315,19 @@
         String host = null;
         String port = null;
         String exclList = null;
+        String pacFileUrl = null;
         if (p != null) {
             host = p.getHost();
             port = Integer.toString(p.getPort());
             exclList = p.getExclusionList();
+            pacFileUrl = p.getPacFileUrl();
         }
-        setHttpProxySystemProperty(host, port, exclList);
+        setHttpProxySystemProperty(host, port, exclList, pacFileUrl);
     }
 
     /** @hide */
-    public static final void setHttpProxySystemProperty(String host, String port, String exclList) {
+    public static final void setHttpProxySystemProperty(String host, String port, String exclList,
+            String pacFileUrl) {
         if (exclList != null) exclList = exclList.replace(",", "|");
         if (false) Log.d(TAG, "setHttpProxySystemProperty :"+host+":"+port+" - "+exclList);
         if (host != null) {
@@ -358,5 +351,10 @@
             System.clearProperty("http.nonProxyHosts");
             System.clearProperty("https.nonProxyHosts");
         }
+        if (!TextUtils.isEmpty(pacFileUrl)) {
+            ProxySelector.setDefault(new PacProxySelector());
+        } else {
+            ProxySelector.setDefault(sDefaultProxySelector);
+        }
     }
 }
diff --git a/core/java/android/net/ProxyProperties.java b/core/java/android/net/ProxyProperties.java
index 9c4772b..648a4b3 100644
--- a/core/java/android/net/ProxyProperties.java
+++ b/core/java/android/net/ProxyProperties.java
@@ -20,9 +20,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
-import android.util.Log;
 
-import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.UnknownHostException;
 import java.util.Locale;
@@ -38,17 +36,38 @@
     private String mExclusionList;
     private String[] mParsedExclusionList;
 
+    private String mPacFileUrl;
+    public static final String LOCAL_EXCL_LIST = "";
+    public static final int LOCAL_PORT = -1;
+    public static final String LOCAL_HOST = "localhost";
+
     public ProxyProperties(String host, int port, String exclList) {
         mHost = host;
         mPort = port;
         setExclusionList(exclList);
     }
 
+    public ProxyProperties(String pacFileUrl) {
+        mHost = LOCAL_HOST;
+        mPort = LOCAL_PORT;
+        setExclusionList(LOCAL_EXCL_LIST);
+        mPacFileUrl = pacFileUrl;
+    }
+
+    // Only used in PacManager after Local Proxy is bound.
+    public ProxyProperties(String pacFileUrl, int localProxyPort) {
+        mHost = LOCAL_HOST;
+        mPort = localProxyPort;
+        setExclusionList(LOCAL_EXCL_LIST);
+        mPacFileUrl = pacFileUrl;
+    }
+
     private ProxyProperties(String host, int port, String exclList, String[] parsedExclList) {
         mHost = host;
         mPort = port;
         mExclusionList = exclList;
         mParsedExclusionList = parsedExclList;
+        mPacFileUrl = null;
     }
 
     // copy constructor instead of clone
@@ -56,6 +75,7 @@
         if (source != null) {
             mHost = source.getHost();
             mPort = source.getPort();
+            mPacFileUrl = source.getPacFileUrl();
             mExclusionList = source.getExclusionList();
             mParsedExclusionList = source.mParsedExclusionList;
         }
@@ -69,6 +89,10 @@
         return inetSocketAddress;
     }
 
+    public String getPacFileUrl() {
+        return mPacFileUrl;
+    }
+
     public String getHost() {
         return mHost;
     }
@@ -130,7 +154,10 @@
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
-        if (mHost != null) {
+        if (mPacFileUrl != null) {
+            sb.append("PAC Script: ");
+            sb.append(mPacFileUrl);
+        } else if (mHost != null) {
             sb.append("[");
             sb.append(mHost);
             sb.append("] ");
@@ -148,6 +175,14 @@
     public boolean equals(Object o) {
         if (!(o instanceof ProxyProperties)) return false;
         ProxyProperties p = (ProxyProperties)o;
+        // If PAC URL is present in either then they must be equal.
+        // Other parameters will only be for fall back.
+        if (!TextUtils.isEmpty(mPacFileUrl)) {
+            return mPacFileUrl.equals(p.getPacFileUrl());
+        }
+        if (!TextUtils.isEmpty(p.getPacFileUrl())) {
+            return false;
+        }
         if (mExclusionList != null && !mExclusionList.equals(p.getExclusionList())) return false;
         if (mHost != null && p.getHost() != null && mHost.equals(p.getHost()) == false) {
             return false;
@@ -181,6 +216,13 @@
      * @hide
      */
     public void writeToParcel(Parcel dest, int flags) {
+        if (mPacFileUrl != null) {
+            dest.writeByte((byte)1);
+            dest.writeString(mPacFileUrl);
+            return;
+        } else {
+            dest.writeByte((byte)0);
+        }
         if (mHost != null) {
             dest.writeByte((byte)1);
             dest.writeString(mHost);
@@ -201,7 +243,10 @@
             public ProxyProperties createFromParcel(Parcel in) {
                 String host = null;
                 int port = 0;
-                if (in.readByte() == 1) {
+                if (in.readByte() != 0) {
+                    return new ProxyProperties(in.readString());
+                }
+                if (in.readByte() != 0) {
                     host = in.readString();
                     port = in.readInt();
                 }
diff --git a/core/java/android/net/SamplingDataTracker.java b/core/java/android/net/SamplingDataTracker.java
new file mode 100644
index 0000000..acd56f2
--- /dev/null
+++ b/core/java/android/net/SamplingDataTracker.java
@@ -0,0 +1,300 @@
+/*
+ * 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.net;
+
+
+import android.os.SystemClock;
+import android.util.Slog;
+
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * @hide
+ */
+public class SamplingDataTracker
+{
+    private static final boolean DBG = false;
+    private static final String  TAG = "SamplingDataTracker";
+
+    public static class SamplingSnapshot
+    {
+        public long mTxByteCount;
+        public long mRxByteCount;
+        public long mTxPacketCount;
+        public long mRxPacketCount;
+        public long mTxPacketErrorCount;
+        public long mRxPacketErrorCount;
+        public long mTimestamp;
+    }
+
+    public static void getSamplingSnapshots(Map<String, SamplingSnapshot> mapIfaceToSample) {
+
+        BufferedReader reader = null;
+        try {
+            reader = new BufferedReader(new FileReader("/proc/net/dev"));
+
+            // Skip over the line bearing column titles (there are 2 lines)
+            String line;
+            reader.readLine();
+            reader.readLine();
+
+            while ((line = reader.readLine()) != null) {
+
+                // remove leading whitespace
+                line = line.trim();
+
+                String[] tokens = line.split("[ ]+");
+                if (tokens.length < 17) {
+                    continue;
+                }
+
+                /* column format is
+                 * Interface  (Recv)bytes packets errs drop fifo frame compressed multicast \
+                 *            (Transmit)bytes packets errs drop fifo colls carrier compress
+                */
+
+                String currentIface = tokens[0].split(":")[0];
+                if (DBG) Slog.d(TAG, "Found data for interface " + currentIface);
+                if (mapIfaceToSample.containsKey(currentIface)) {
+
+                    try {
+                        SamplingSnapshot ss = new SamplingSnapshot();
+
+                        ss.mTxByteCount        = Long.parseLong(tokens[1]);
+                        ss.mTxPacketCount      = Long.parseLong(tokens[2]);
+                        ss.mTxPacketErrorCount = Long.parseLong(tokens[3]);
+                        ss.mRxByteCount        = Long.parseLong(tokens[9]);
+                        ss.mRxPacketCount      = Long.parseLong(tokens[10]);
+                        ss.mRxPacketErrorCount = Long.parseLong(tokens[11]);
+
+                        ss.mTimestamp          = SystemClock.elapsedRealtime();
+
+                        if (DBG) {
+                            Slog.d(TAG, "Interface = " + currentIface);
+                            Slog.d(TAG, "ByteCount = " + String.valueOf(ss.mTxByteCount));
+                            Slog.d(TAG, "TxPacketCount = " + String.valueOf(ss.mTxPacketCount));
+                            Slog.d(TAG, "TxPacketErrorCount = "
+                                    + String.valueOf(ss.mTxPacketErrorCount));
+                            Slog.d(TAG, "RxByteCount = " + String.valueOf(ss.mRxByteCount));
+                            Slog.d(TAG, "RxPacketCount = " + String.valueOf(ss.mRxPacketCount));
+                            Slog.d(TAG, "RxPacketErrorCount = "
+                                    + String.valueOf(ss.mRxPacketErrorCount));
+                            Slog.d(TAG, "Timestamp = " + String.valueOf(ss.mTimestamp));
+                            Slog.d(TAG, "---------------------------");
+                        }
+
+                        mapIfaceToSample.put(currentIface, ss);
+
+                    } catch (NumberFormatException e) {
+                        // just ignore this data point
+                    }
+                }
+            }
+
+            if (DBG) {
+                Iterator it = mapIfaceToSample.entrySet().iterator();
+                while (it.hasNext()) {
+                    Map.Entry kvpair = (Map.Entry)it.next();
+                    if (kvpair.getValue() == null) {
+                        Slog.d(TAG, "could not find snapshot for interface " + kvpair.getKey());
+                    }
+                }
+            }
+        } catch(FileNotFoundException e) {
+            Slog.e(TAG, "could not find /proc/net/dev");
+        } catch (IOException e) {
+            Slog.e(TAG, "could not read /proc/net/dev");
+        } finally {
+            try {
+                if (reader != null) {
+                    reader.close();
+                }
+            } catch (IOException e) {
+                Slog.e(TAG, "could not close /proc/net/dev");
+            }
+        }
+    }
+
+    // Snapshots from previous sampling interval
+    private SamplingSnapshot mBeginningSample;
+    private SamplingSnapshot mEndingSample;
+
+    // Starting snapshot of current interval
+    private SamplingSnapshot mLastSample;
+
+    // Protects sampling data from concurrent access
+    public final Object mSamplingDataLock = new Object();
+
+    // We need long enough time for a good sample
+    private final int MINIMUM_SAMPLING_INTERVAL = 15 * 1000;
+
+    // statistics is useless unless we have enough data
+    private final int MINIMUM_SAMPLED_PACKETS   = 30;
+
+    public void startSampling(SamplingSnapshot s) {
+        synchronized(mSamplingDataLock) {
+            mLastSample = s;
+        }
+    }
+
+    public void stopSampling(SamplingSnapshot s) {
+        synchronized(mSamplingDataLock) {
+            if (mLastSample != null) {
+                if (s.mTimestamp - mLastSample.mTimestamp > MINIMUM_SAMPLING_INTERVAL
+                        && getSampledPacketCount(mLastSample, s) > MINIMUM_SAMPLED_PACKETS) {
+                    mBeginningSample = mLastSample;
+                    mEndingSample = s;
+                    mLastSample = null;
+                } else {
+                    if (DBG) Slog.d(TAG, "Throwing current sample away because it is too small");
+                }
+            }
+        }
+    }
+
+    public void resetSamplingData() {
+        if (DBG) Slog.d(TAG, "Resetting sampled network data");
+        synchronized(mSamplingDataLock) {
+
+            // We could just take another sample here and treat it as an
+            // 'ending sample' effectively shortening sampling interval, but that
+            // requires extra work (specifically, reading the sample needs to be
+            // done asynchronously)
+
+            mLastSample = null;
+        }
+    }
+
+    public long getSampledTxByteCount() {
+        synchronized(mSamplingDataLock) {
+            if (mBeginningSample != null && mEndingSample != null) {
+                return mEndingSample.mTxByteCount - mBeginningSample.mTxByteCount;
+            } else {
+                return LinkQualityInfo.UNKNOWN_LONG;
+            }
+        }
+    }
+
+    public long getSampledTxPacketCount() {
+        synchronized(mSamplingDataLock) {
+            if (mBeginningSample != null && mEndingSample != null) {
+                return mEndingSample.mTxPacketCount - mBeginningSample.mTxPacketCount;
+            } else {
+                return LinkQualityInfo.UNKNOWN_LONG;
+            }
+        }
+    }
+
+    public long getSampledTxPacketErrorCount() {
+        synchronized(mSamplingDataLock) {
+            if (mBeginningSample != null && mEndingSample != null) {
+                return mEndingSample.mTxPacketErrorCount - mBeginningSample.mTxPacketErrorCount;
+            } else {
+                return LinkQualityInfo.UNKNOWN_LONG;
+            }
+        }
+    }
+
+    public long getSampledRxByteCount() {
+        synchronized(mSamplingDataLock) {
+            if (mBeginningSample != null && mEndingSample != null) {
+                return mEndingSample.mRxByteCount - mBeginningSample.mRxByteCount;
+            } else {
+                return LinkQualityInfo.UNKNOWN_LONG;
+            }
+        }
+    }
+
+    public long getSampledRxPacketCount() {
+        synchronized(mSamplingDataLock) {
+            if (mBeginningSample != null && mEndingSample != null) {
+                return mEndingSample.mRxPacketCount - mBeginningSample.mRxPacketCount;
+            } else {
+                return LinkQualityInfo.UNKNOWN_LONG;
+            }
+        }
+    }
+
+    public long getSampledPacketCount() {
+        return getSampledPacketCount(mBeginningSample, mEndingSample);
+    }
+
+    public long getSampledPacketCount(SamplingSnapshot begin, SamplingSnapshot end) {
+        if (begin != null && end != null) {
+            long rxPacketCount = end.mRxPacketCount - begin.mRxPacketCount;
+            long txPacketCount = end.mTxPacketCount - begin.mTxPacketCount;
+            return rxPacketCount + txPacketCount;
+        } else {
+            return LinkQualityInfo.UNKNOWN_LONG;
+        }
+    }
+
+    public long getSampledPacketErrorCount() {
+        if (mBeginningSample != null && mEndingSample != null) {
+            long rxPacketErrorCount = getSampledRxPacketErrorCount();
+            long txPacketErrorCount = getSampledTxPacketErrorCount();
+            return rxPacketErrorCount + txPacketErrorCount;
+        } else {
+            return LinkQualityInfo.UNKNOWN_LONG;
+        }
+    }
+
+    public long getSampledRxPacketErrorCount() {
+        synchronized(mSamplingDataLock) {
+            if (mBeginningSample != null && mEndingSample != null) {
+                return mEndingSample.mRxPacketErrorCount - mBeginningSample.mRxPacketErrorCount;
+            } else {
+                return LinkQualityInfo.UNKNOWN_LONG;
+            }
+        }
+    }
+
+    public long getSampleTimestamp() {
+        synchronized(mSamplingDataLock) {
+            if (mEndingSample != null) {
+                return mEndingSample.mTimestamp;
+            } else {
+                return LinkQualityInfo.UNKNOWN_LONG;
+            }
+        }
+    }
+
+    public int getSampleDuration() {
+        synchronized(mSamplingDataLock) {
+            if (mBeginningSample != null && mEndingSample != null) {
+                return (int) (mEndingSample.mTimestamp - mBeginningSample.mTimestamp);
+            } else {
+                return LinkQualityInfo.UNKNOWN_INT;
+            }
+        }
+    }
+
+    public void setCommonLinkQualityInfoFields(LinkQualityInfo li) {
+        synchronized(mSamplingDataLock) {
+            li.setLastDataSampleTime(getSampleTimestamp());
+            li.setDataSampleDuration(getSampleDuration());
+            li.setPacketCount(getSampledPacketCount());
+            li.setPacketErrorCount(getSampledPacketErrorCount());
+        }
+    }
+}
+
diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java
index 132173d..a7a8a0a 100644
--- a/core/java/android/net/Uri.java
+++ b/core/java/android/net/Uri.java
@@ -19,7 +19,6 @@
 import android.os.Environment;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.Environment.UserEnvironment;
 import android.os.StrictMode;
 import android.util.Log;
 import java.io.File;
diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java
index 65d3f2b..d7dc7f5 100644
--- a/core/java/android/net/VpnService.java
+++ b/core/java/android/net/VpnService.java
@@ -17,8 +17,8 @@
 package android.net;
 
 import android.app.Activity;
-import android.app.Service;
 import android.app.PendingIntent;
+import android.app.Service;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Binder;
@@ -30,12 +30,13 @@
 
 import com.android.internal.net.VpnConfig;
 
-import java.net.InetAddress;
+import java.net.DatagramSocket;
 import java.net.Inet4Address;
 import java.net.Inet6Address;
-import java.net.DatagramSocket;
+import java.net.InetAddress;
 import java.net.Socket;
 import java.util.ArrayList;
+import java.util.List;
 
 /**
  * VpnService is a base class for applications to extend and build their
@@ -253,8 +254,8 @@
     public class Builder {
 
         private final VpnConfig mConfig = new VpnConfig();
-        private final StringBuilder mAddresses = new StringBuilder();
-        private final StringBuilder mRoutes = new StringBuilder();
+        private final List<LinkAddress> mAddresses = new ArrayList<LinkAddress>();
+        private final List<RouteInfo> mRoutes = new ArrayList<RouteInfo>();
 
         public Builder() {
             mConfig.user = VpnService.this.getClass().getName();
@@ -328,8 +329,7 @@
             if (address.isAnyLocalAddress()) {
                 throw new IllegalArgumentException("Bad address");
             }
-
-            mAddresses.append(' ' + address.getHostAddress() + '/' +  prefixLength);
+            mAddresses.add(new LinkAddress(address, prefixLength));
             return this;
         }
 
@@ -363,8 +363,7 @@
                     }
                 }
             }
-
-            mRoutes.append(String.format(" %s/%d", address.getHostAddress(), prefixLength));
+            mRoutes.add(new RouteInfo(new LinkAddress(address, prefixLength), null));
             return this;
         }
 
@@ -465,8 +464,8 @@
          * @see VpnService
          */
         public ParcelFileDescriptor establish() {
-            mConfig.addresses = mAddresses.toString();
-            mConfig.routes = mRoutes.toString();
+            mConfig.addresses = mAddresses;
+            mConfig.routes = mRoutes;
 
             try {
                 return getService().establishVpn(mConfig);
diff --git a/core/java/android/net/WifiLinkQualityInfo.java b/core/java/android/net/WifiLinkQualityInfo.java
new file mode 100644
index 0000000..20ec9a7
--- /dev/null
+++ b/core/java/android/net/WifiLinkQualityInfo.java
@@ -0,0 +1,149 @@
+/*
+ * 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.net;
+
+import android.os.Parcel;
+
+/**
+ *  Class that represents useful attributes of wifi network links
+ *  such as the upload/download throughput or error rate etc.
+ *  @hide
+ */
+public class WifiLinkQualityInfo extends LinkQualityInfo {
+
+    /* Indicates Wifi network type such as b/g etc*/
+    private int  mType = UNKNOWN_INT;
+
+    private String mBssid;
+
+    /* Rssi found by scans */
+    private int  mRssi = UNKNOWN_INT;
+
+    /* packet statistics */
+    private long mTxGood = UNKNOWN_LONG;
+    private long mTxBad = UNKNOWN_LONG;
+
+    /**
+     * Implement the Parcelable interface.
+     * @hide
+     */
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        super.writeToParcel(dest, flags, OBJECT_TYPE_WIFI_LINK_QUALITY_INFO);
+
+        dest.writeInt(mType);
+        dest.writeInt(mRssi);
+        dest.writeLong(mTxGood);
+        dest.writeLong(mTxBad);
+
+        dest.writeString(mBssid);
+    }
+
+    /* Un-parceling helper */
+    /**
+     * @hide
+     */
+    public static WifiLinkQualityInfo createFromParcelBody(Parcel in) {
+        WifiLinkQualityInfo li = new WifiLinkQualityInfo();
+
+        li.initializeFromParcel(in);
+
+        li.mType =  in.readInt();
+        li.mRssi =  in.readInt();
+        li.mTxGood =  in.readLong();
+        li.mTxBad =  in.readLong();
+
+        li.mBssid =  in.readString();
+
+        return li;
+    }
+
+    /**
+     * returns Wifi network type
+     * @return network type or {@link android.net.LinkQualityInfo#UNKNOWN_INT}
+     */
+    public int getType() {
+        return mType;
+    }
+
+    /**
+     * @hide
+     */
+    public void setType(int type) {
+        mType = type;
+    }
+
+    /**
+     * returns BSSID of the access point
+     * @return the BSSID, in the form of a six-byte MAC address: {@code XX:XX:XX:XX:XX:XX} or null
+     */
+    public String getBssid() {
+        return mBssid;
+    }
+
+    /**
+     * @hide
+     */
+    public void setBssid(String bssid) {
+        mBssid = bssid;
+    }
+
+    /**
+     * returns RSSI of the network in raw form
+     * @return un-normalized RSSI or {@link android.net.LinkQualityInfo#UNKNOWN_INT}
+     */
+    public int getRssi() {
+        return mRssi;
+    }
+
+    /**
+     * @hide
+     */
+    public void setRssi(int rssi) {
+        mRssi = rssi;
+    }
+
+    /**
+     * returns number of packets transmitted without error
+     * @return number of packets or {@link android.net.LinkQualityInfo#UNKNOWN_LONG}
+     */
+    public long getTxGood() {
+        return mTxGood;
+    }
+
+    /**
+     * @hide
+     */
+    public void setTxGood(long txGood) {
+        mTxGood = txGood;
+    }
+
+    /**
+     * returns number of transmitted packets that encountered errors
+     * @return number of packets or {@link android.net.LinkQualityInfo#UNKNOWN_LONG}
+     */
+    public long getTxBad() {
+        return mTxBad;
+    }
+
+    /**
+     * @hide
+     */
+    public void setTxBad(long txBad) {
+        mTxBad = txBad;
+    }
+}
diff --git a/core/java/android/nfc/IAppCallback.aidl b/core/java/android/nfc/IAppCallback.aidl
new file mode 100644
index 0000000..9599308
--- /dev/null
+++ b/core/java/android/nfc/IAppCallback.aidl
@@ -0,0 +1,30 @@
+/*
+ * 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.nfc;
+
+import android.nfc.BeamShareData;
+import android.nfc.Tag;
+
+/**
+ * @hide
+ */
+interface IAppCallback
+{
+    BeamShareData createBeamShareData();
+    void onNdefPushComplete();
+    void onTagDiscovered(in Tag tag);
+}
diff --git a/core/java/android/nfc/INdefPushCallback.aidl b/core/java/android/nfc/INdefPushCallback.aidl
deleted file mode 100644
index 16771dc..0000000
--- a/core/java/android/nfc/INdefPushCallback.aidl
+++ /dev/null
@@ -1,28 +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.nfc;
-
-import android.nfc.BeamShareData;
-
-/**
- * @hide
- */
-interface INdefPushCallback
-{
-    BeamShareData createBeamShareData();
-    void onNdefPushComplete();
-}
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index 39810ba..8414738 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -21,9 +21,11 @@
 import android.nfc.NdefMessage;
 import android.nfc.Tag;
 import android.nfc.TechListParcel;
-import android.nfc.INdefPushCallback;
+import android.nfc.IAppCallback;
 import android.nfc.INfcAdapterExtras;
 import android.nfc.INfcTag;
+import android.nfc.INfcCardEmulation;
+import android.os.Bundle;
 
 /**
  * @hide
@@ -31,6 +33,7 @@
 interface INfcAdapter
 {
     INfcTag getNfcTagInterface();
+    INfcCardEmulation getNfcCardEmulationInterface();
     INfcAdapterExtras getNfcAdapterExtrasInterface(in String pkg);
 
     int getState();
@@ -42,9 +45,10 @@
 
     void setForegroundDispatch(in PendingIntent intent,
             in IntentFilter[] filters, in TechListParcel techLists);
-    void setNdefPushCallback(in INdefPushCallback callback);
+    void setAppCallback(in IAppCallback callback);
 
     void dispatch(in Tag tag);
 
+    void setReaderMode (IBinder b, IAppCallback callback, int flags, in Bundle extras);
     void setP2pModes(int initatorModes, int targetModes);
 }
diff --git a/core/java/android/nfc/INfcCardEmulation.aidl b/core/java/android/nfc/INfcCardEmulation.aidl
new file mode 100644
index 0000000..b8a5ba7
--- /dev/null
+++ b/core/java/android/nfc/INfcCardEmulation.aidl
@@ -0,0 +1,33 @@
+/*
+ * 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.nfc;
+
+import android.content.ComponentName;
+import android.nfc.cardemulation.ApduServiceInfo;
+import android.os.RemoteCallback;
+
+/**
+ * @hide
+ */
+interface INfcCardEmulation
+{
+    boolean isDefaultServiceForCategory(int userHandle, in ComponentName service, String category);
+    boolean isDefaultServiceForAid(int userHandle, in ComponentName service, String aid);
+    boolean setDefaultServiceForCategory(int userHandle, in ComponentName service, String category);
+    boolean setDefaultForNextTap(int userHandle, in ComponentName service);
+    List<ApduServiceInfo> getServices(int userHandle, in String category);
+}
diff --git a/core/java/android/nfc/NfcActivityManager.java b/core/java/android/nfc/NfcActivityManager.java
index 10183c0..77c0234 100644
--- a/core/java/android/nfc/NfcActivityManager.java
+++ b/core/java/android/nfc/NfcActivityManager.java
@@ -19,6 +19,8 @@
 import android.app.Activity;
 import android.app.Application;
 import android.net.Uri;
+import android.nfc.NfcAdapter.ReaderCallback;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.util.Log;
@@ -35,7 +37,7 @@
  *
  * @hide
  */
-public final class NfcActivityManager extends INdefPushCallback.Stub
+public final class NfcActivityManager extends IAppCallback.Stub
         implements Application.ActivityLifecycleCallbacks {
     static final String TAG = NfcAdapter.TAG;
     static final Boolean DBG = false;
@@ -111,6 +113,11 @@
         NfcAdapter.CreateBeamUrisCallback uriCallback = null;
         Uri[] uris = null;
         int flags = 0;
+        int readerModeFlags = 0;
+        NfcAdapter.ReaderCallback readerCallback = null;
+        Bundle readerModeExtras = null;
+        Binder token;
+
         public NfcActivityState(Activity activity) {
             if (activity.getWindow().isDestroyed()) {
                 throw new IllegalStateException("activity is already destroyed");
@@ -120,6 +127,7 @@
             resumed = activity.isResumed();
 
             this.activity = activity;
+            this.token = new Binder();
             registerApplication(activity.getApplication());
         }
         public void destroy() {
@@ -131,6 +139,8 @@
             onNdefPushCompleteCallback = null;
             uriCallback = null;
             uris = null;
+            readerModeFlags = 0;
+            token = null;
         }
         @Override
         public String toString() {
@@ -190,6 +200,49 @@
         mDefaultEvent = new NfcEvent(mAdapter);
     }
 
+    public void enableReaderMode(Activity activity, ReaderCallback callback, int flags,
+            Bundle extras) {
+        boolean isResumed;
+        Binder token;
+        synchronized (NfcActivityManager.this) {
+            NfcActivityState state = getActivityState(activity);
+            state.readerCallback = callback;
+            state.readerModeFlags = flags;
+            state.readerModeExtras = extras;
+            token = state.token;
+            isResumed = state.resumed;
+        }
+        if (isResumed) {
+            setReaderMode(token, flags, extras);
+        }
+    }
+
+    public void disableReaderMode(Activity activity) {
+        boolean isResumed;
+        Binder token;
+        synchronized (NfcActivityManager.this) {
+            NfcActivityState state = getActivityState(activity);
+            state.readerCallback = null;
+            state.readerModeFlags = 0;
+            state.readerModeExtras = null;
+            token = state.token;
+            isResumed = state.resumed;
+        }
+        if (isResumed) {
+            setReaderMode(token, 0, null);
+        }
+
+    }
+
+    public void setReaderMode(Binder token, int flags, Bundle extras) {
+        if (DBG) Log.d(TAG, "Setting reader mode");
+        try {
+            NfcAdapter.sService.setReaderMode(token, this, flags, extras);
+        } catch (RemoteException e) {
+            mAdapter.attemptDeadServiceRecovery(e);
+        }
+    }
+
     public void setNdefPushContentUri(Activity activity, Uri[] uris) {
         boolean isResumed;
         synchronized (NfcActivityManager.this) {
@@ -257,12 +310,12 @@
     }
 
     /**
-     * Request or unrequest NFC service callbacks for NDEF push.
+     * Request or unrequest NFC service callbacks.
      * Makes IPC call - do not hold lock.
      */
     void requestNfcServiceCallback() {
         try {
-            NfcAdapter.sService.setNdefPushCallback(this);
+            NfcAdapter.sService.setAppCallback(this);
         } catch (RemoteException e) {
             mAdapter.attemptDeadServiceRecovery(e);
         }
@@ -330,6 +383,22 @@
         }
     }
 
+    @Override
+    public void onTagDiscovered(Tag tag) throws RemoteException {
+        NfcAdapter.ReaderCallback callback;
+        synchronized (NfcActivityManager.this) {
+            NfcActivityState state = findResumedActivityState();
+            if (state == null) return;
+
+            callback = state.readerCallback;
+        }
+
+        // Make callback without lock
+        if (callback != null) {
+            callback.onTagDiscovered(tag);
+        }
+
+    }
     /** Callback from Activity life-cycle, on main thread */
     @Override
     public void onActivityCreated(Activity activity, Bundle savedInstanceState) { /* NO-OP */ }
@@ -341,11 +410,20 @@
     /** Callback from Activity life-cycle, on main thread */
     @Override
     public void onActivityResumed(Activity activity) {
+        int readerModeFlags = 0;
+        Bundle readerModeExtras = null;
+        Binder token;
         synchronized (NfcActivityManager.this) {
             NfcActivityState state = findActivityState(activity);
             if (DBG) Log.d(TAG, "onResume() for " + activity + " " + state);
             if (state == null) return;
             state.resumed = true;
+            token = state.token;
+            readerModeFlags = state.readerModeFlags;
+            readerModeExtras = state.readerModeExtras;
+        }
+        if (readerModeFlags != 0) {
+            setReaderMode(token, readerModeFlags, readerModeExtras);
         }
         requestNfcServiceCallback();
     }
@@ -353,11 +431,19 @@
     /** Callback from Activity life-cycle, on main thread */
     @Override
     public void onActivityPaused(Activity activity) {
+        boolean readerModeFlagsSet;
+        Binder token;
         synchronized (NfcActivityManager.this) {
             NfcActivityState state = findActivityState(activity);
             if (DBG) Log.d(TAG, "onPause() for " + activity + " " + state);
             if (state == null) return;
             state.resumed = false;
+            token = state.token;
+            readerModeFlagsSet = state.readerModeFlags != 0;
+        }
+        if (readerModeFlagsSet) {
+            // Restore default p2p modes
+            setReaderMode(token, 0, null);
         }
     }
 
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index ca4a7d6..2a18900 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -33,6 +33,7 @@
 import android.nfc.tech.Ndef;
 import android.nfc.tech.NfcA;
 import android.nfc.tech.NfcF;
+import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -195,6 +196,67 @@
     public static final int STATE_ON = 3;
     public static final int STATE_TURNING_OFF = 4;
 
+    /**
+     * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
+     * <p>
+     * Setting this flag enables polling for Nfc-A technology.
+     */
+    public static final int FLAG_READER_NFC_A = 0x1;
+
+    /**
+     * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
+     * <p>
+     * Setting this flag enables polling for Nfc-B technology.
+     */
+    public static final int FLAG_READER_NFC_B = 0x2;
+
+    /**
+     * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
+     * <p>
+     * Setting this flag enables polling for Nfc-F technology.
+     */
+    public static final int FLAG_READER_NFC_F = 0x4;
+
+    /**
+     * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
+     * <p>
+     * Setting this flag enables polling for Nfc-V (ISO15693) technology.
+     */
+    public static final int FLAG_READER_NFC_V = 0x8;
+
+    /**
+     * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
+     * <p>
+     * Setting this flag enables polling for Kovio technology.
+     */
+    public static final int FLAG_READER_KOVIO = 0x10;
+
+    /**
+     * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
+     * <p>
+     * Setting this flag allows the caller to prevent the
+     * platform from performing an NDEF check on the tags it
+     * finds.
+     */
+    public static final int FLAG_READER_SKIP_NDEF_CHECK = 0x80;
+
+    /**
+     * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
+     * <p>
+     * Setting this flag allows the caller to prevent the
+     * platform from playing sounds when it discovers a tag.
+     */
+    public static final int FLAG_READER_NO_PLATFORM_SOUNDS = 0x100;
+
+    /**
+     * Int Extra for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
+     * <p>
+     * Setting this integer extra allows the calling application to specify
+     * the delay that the platform will use for performing presence checks
+     * on any discovered tag.
+     */
+    public static final String EXTRA_READER_PRESENCE_CHECK_DELAY = "presence";
+
     /** @hide */
     public static final int FLAG_NDEF_PUSH_NO_CONFIRM = 0x1;
 
@@ -227,6 +289,7 @@
     // recovery
     static INfcAdapter sService;
     static INfcTag sTagService;
+    static INfcCardEmulation sCardEmulationService;
 
     /**
      * The NfcAdapter object for each application context.
@@ -246,6 +309,14 @@
     final Context mContext;
 
     /**
+     * A callback to be invoked when the system has found a tag in
+     * reader mode.
+     */
+    public interface ReaderCallback {
+        public void onTagDiscovered(Tag tag);
+    }
+
+    /**
      * A callback to be invoked when the system successfully delivers your {@link NdefMessage}
      * to another device.
      * @see #setOnNdefPushCompleteCallback
@@ -348,6 +419,13 @@
                 throw new UnsupportedOperationException();
             }
 
+            try {
+                sCardEmulationService = sService.getNfcCardEmulationInterface();
+            } catch (RemoteException e) {
+                Log.e(TAG, "could not retrieve card emulation service");
+                throw new UnsupportedOperationException();
+            }
+
             sIsInitialized = true;
         }
         if (context == null) {
@@ -456,6 +534,15 @@
     }
 
     /**
+     * Returns the binder interface to the card emulation service.
+     * @hide
+     */
+    public INfcCardEmulation getCardEmulationService() {
+        isEnabled();
+        return sCardEmulationService;
+    }
+
+    /**
      * NFC service dead - attempt best effort recovery
      * @hide
      */
@@ -477,6 +564,13 @@
             Log.e(TAG, "could not retrieve NFC tag service during service recovery");
             // nothing more can be done now, sService is still stale, we'll hit
             // this recovery path again later
+            return;
+        }
+
+        try {
+            sCardEmulationService = service.getNfcCardEmulationInterface();
+        } catch (RemoteException ee) {
+            Log.e(TAG, "could not retrieve NFC card emulation service during service recovery");
         }
 
         return;
@@ -1088,6 +1182,43 @@
     }
 
     /**
+     * Limit the NFC controller to reader mode while this Activity is in the foreground.
+     *
+     * <p>In this mode the NFC controller will only act as an NFC tag reader/writer,
+     * thus disabling any peer-to-peer (Android Beam) and card-emulation modes of
+     * the NFC adapter on this device.
+     *
+     * <p>Use {@link #FLAG_READER_SKIP_NDEF_CHECK} to prevent the platform from
+     * performing any NDEF checks in reader mode. Note that this will prevent the
+     * {@link Ndef} tag technology from being enumerated on the tag, and that
+     * NDEF-based tag dispatch will not be functional.
+     *
+     * <p>For interacting with tags that are emulated on another Android device
+     * using Android's host-based card-emulation, the recommended flags are
+     * {@link #FLAG_READER_NFC_A} and {@link #FLAG_READER_SKIP_NDEF_CHECK}.
+     *
+     * @param activity the Activity that requests the adapter to be in reader mode
+     * @param callback the callback to be called when a tag is discovered
+     * @param flags Flags indicating poll technologies and other optional parameters
+     * @param extras Additional extras for configuring reader mode.
+     */
+    public void enableReaderMode(Activity activity, ReaderCallback callback, int flags,
+            Bundle extras) {
+        mNfcActivityManager.enableReaderMode(activity, callback, flags, extras);
+    }
+
+    /**
+     * Restore the NFC adapter to normal mode of operation: supporting
+     * peer-to-peer (Android Beam), card emulation, and polling for
+     * all supported tag technologies.
+     *
+     * @param activity the Activity that currently has reader mode enabled
+     */
+    public void disableReaderMode(Activity activity) {
+        mNfcActivityManager.disableReaderMode(activity);
+    }
+
+    /**
      * Enable NDEF message push over NFC while this Activity is in the foreground.
      *
      * <p>You must explicitly call this method every time the activity is
diff --git a/core/java/android/nfc/cardemulation/ApduServiceInfo.aidl b/core/java/android/nfc/cardemulation/ApduServiceInfo.aidl
new file mode 100644
index 0000000..a62fdd6
--- /dev/null
+++ b/core/java/android/nfc/cardemulation/ApduServiceInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.nfc.cardemulation;
+
+parcelable ApduServiceInfo;
diff --git a/core/java/android/nfc/cardemulation/ApduServiceInfo.java b/core/java/android/nfc/cardemulation/ApduServiceInfo.java
new file mode 100644
index 0000000..40a3612
--- /dev/null
+++ b/core/java/android/nfc/cardemulation/ApduServiceInfo.java
@@ -0,0 +1,433 @@
+/*
+ * 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.nfc.cardemulation;
+
+import android.content.ComponentName;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.graphics.drawable.Drawable;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Xml;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * @hide
+ */
+public final class ApduServiceInfo implements Parcelable {
+    static final String TAG = "ApduServiceInfo";
+
+    /**
+     * The service that implements this
+     */
+    final ResolveInfo mService;
+
+    /**
+     * Description of the service
+     */
+    final String mDescription;
+
+    /**
+     * Convenience AID list
+     */
+    final ArrayList<String> mAids;
+
+    /**
+     * Whether this service represents AIDs running on the host CPU
+     */
+    final boolean mOnHost;
+
+    /**
+     * All AID groups this service handles
+     */
+    final ArrayList<AidGroup> mAidGroups;
+
+    /**
+     * Convenience hashmap
+     */
+    final HashMap<String, AidGroup> mCategoryToGroup;
+
+    /**
+     * Whether this service should only be started when the device is unlocked.
+     */
+    final boolean mRequiresDeviceUnlock;
+
+    /**
+     * The id of the service banner specified in XML.
+     */
+    final int mBannerResourceId;
+
+    /**
+     * @hide
+     */
+    public ApduServiceInfo(ResolveInfo info, boolean onHost, String description,
+            ArrayList<AidGroup> aidGroups, boolean requiresUnlock, int bannerResource) {
+        this.mService = info;
+        this.mDescription = description;
+        this.mAidGroups = aidGroups;
+        this.mAids = new ArrayList<String>();
+        this.mCategoryToGroup = new HashMap<String, AidGroup>();
+        this.mOnHost = onHost;
+        this.mRequiresDeviceUnlock = requiresUnlock;
+        for (AidGroup aidGroup : aidGroups) {
+            this.mCategoryToGroup.put(aidGroup.category, aidGroup);
+            this.mAids.addAll(aidGroup.aids);
+        }
+        this.mBannerResourceId = bannerResource;
+    }
+
+    public ApduServiceInfo(PackageManager pm, ResolveInfo info, boolean onHost)
+            throws XmlPullParserException, IOException {
+        ServiceInfo si = info.serviceInfo;
+        XmlResourceParser parser = null;
+        try {
+            if (onHost) {
+                parser = si.loadXmlMetaData(pm, HostApduService.SERVICE_META_DATA);
+                if (parser == null) {
+                    throw new XmlPullParserException("No " + HostApduService.SERVICE_META_DATA +
+                            " meta-data");
+                }
+            } else {
+                parser = si.loadXmlMetaData(pm, OffHostApduService.SERVICE_META_DATA);
+                if (parser == null) {
+                    throw new XmlPullParserException("No " + OffHostApduService.SERVICE_META_DATA +
+                            " meta-data");
+                }
+            }
+
+            int eventType = parser.getEventType();
+            while (eventType != XmlPullParser.START_TAG && eventType != XmlPullParser.END_DOCUMENT) {
+                eventType = parser.next();
+            }
+
+            String tagName = parser.getName();
+            if (onHost && !"host-apdu-service".equals(tagName)) {
+                throw new XmlPullParserException(
+                        "Meta-data does not start with <host-apdu-service> tag");
+            } else if (!onHost && !"offhost-apdu-service".equals(tagName)) {
+                throw new XmlPullParserException(
+                        "Meta-data does not start with <offhost-apdu-service> tag");
+            }
+
+            Resources res = pm.getResourcesForApplication(si.applicationInfo);
+            AttributeSet attrs = Xml.asAttributeSet(parser);
+            if (onHost) {
+                TypedArray sa = res.obtainAttributes(attrs,
+                        com.android.internal.R.styleable.HostApduService);
+                mService = info;
+                mDescription = sa.getString(
+                        com.android.internal.R.styleable.HostApduService_description);
+                mRequiresDeviceUnlock = sa.getBoolean(
+                        com.android.internal.R.styleable.HostApduService_requireDeviceUnlock,
+                        false);
+                mBannerResourceId = sa.getResourceId(
+                        com.android.internal.R.styleable.HostApduService_apduServiceBanner, -1);
+                sa.recycle();
+            } else {
+                TypedArray sa = res.obtainAttributes(attrs,
+                        com.android.internal.R.styleable.OffHostApduService);
+                mService = info;
+                mDescription = sa.getString(
+                        com.android.internal.R.styleable.OffHostApduService_description);
+                mRequiresDeviceUnlock = false;
+                mBannerResourceId = sa.getResourceId(
+                        com.android.internal.R.styleable.HostApduService_apduServiceBanner, -1);
+                sa.recycle();
+            }
+
+            mAidGroups = new ArrayList<AidGroup>();
+            mCategoryToGroup = new HashMap<String, AidGroup>();
+            mAids = new ArrayList<String>();
+            mOnHost = onHost;
+            final int depth = parser.getDepth();
+            AidGroup currentGroup = null;
+
+            // Parsed values for the current AID group
+            while (((eventType = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
+                    && eventType != XmlPullParser.END_DOCUMENT) {
+                tagName = parser.getName();
+                if (eventType == XmlPullParser.START_TAG && "aid-group".equals(tagName) &&
+                        currentGroup == null) {
+                    final TypedArray groupAttrs = res.obtainAttributes(attrs,
+                            com.android.internal.R.styleable.AidGroup);
+                    // Get category of AID group
+                    String groupDescription = groupAttrs.getString(
+                            com.android.internal.R.styleable.AidGroup_description);
+                    String groupCategory = groupAttrs.getString(
+                            com.android.internal.R.styleable.AidGroup_category);
+                    if (!CardEmulation.CATEGORY_PAYMENT.equals(groupCategory)) {
+                        groupCategory = CardEmulation.CATEGORY_OTHER;
+                    }
+                    currentGroup = mCategoryToGroup.get(groupCategory);
+                    if (currentGroup != null) {
+                        if (!CardEmulation.CATEGORY_OTHER.equals(groupCategory)) {
+                            Log.e(TAG, "Not allowing multiple aid-groups in the " +
+                                    groupCategory + " category");
+                            currentGroup = null;
+                        }
+                    } else {
+                        currentGroup = new AidGroup(groupCategory, groupDescription);
+                    }
+                    groupAttrs.recycle();
+                } else if (eventType == XmlPullParser.END_TAG && "aid-group".equals(tagName) &&
+                        currentGroup != null) {
+                    if (currentGroup.aids.size() > 0) {
+                        if (!mCategoryToGroup.containsKey(currentGroup.category)) {
+                            mAidGroups.add(currentGroup);
+                            mCategoryToGroup.put(currentGroup.category, currentGroup);
+                        }
+                    } else {
+                        Log.e(TAG, "Not adding <aid-group> with empty or invalid AIDs");
+                    }
+                    currentGroup = null;
+                } else if (eventType == XmlPullParser.START_TAG && "aid-filter".equals(tagName) &&
+                        currentGroup != null) {
+                    final TypedArray a = res.obtainAttributes(attrs,
+                            com.android.internal.R.styleable.AidFilter);
+                    String aid = a.getString(com.android.internal.R.styleable.AidFilter_name).
+                            toUpperCase();
+                    if (isValidAid(aid) && !currentGroup.aids.contains(aid)) {
+                        currentGroup.aids.add(aid);
+                        mAids.add(aid);
+                    } else {
+                        Log.e(TAG, "Ignoring invalid or duplicate aid: " + aid);
+                    }
+                    a.recycle();
+                }
+            }
+        } catch (NameNotFoundException e) {
+            throw new XmlPullParserException("Unable to create context for: " + si.packageName);
+        } finally {
+            if (parser != null) parser.close();
+        }
+    }
+
+    public ComponentName getComponent() {
+        return new ComponentName(mService.serviceInfo.packageName,
+                mService.serviceInfo.name);
+    }
+
+    public ArrayList<String> getAids() {
+        return mAids;
+    }
+
+    public ArrayList<AidGroup> getAidGroups() {
+        return mAidGroups;
+    }
+
+    public boolean hasCategory(String category) {
+        return mCategoryToGroup.containsKey(category);
+    }
+
+    public boolean isOnHost() {
+        return mOnHost;
+    }
+
+    public boolean requiresUnlock() {
+        return mRequiresDeviceUnlock;
+    }
+
+    public CharSequence loadLabel(PackageManager pm) {
+        return mService.loadLabel(pm);
+    }
+
+    public Drawable loadIcon(PackageManager pm) {
+        return mService.loadIcon(pm);
+    }
+
+    public Drawable loadBanner(PackageManager pm) {
+        Resources res;
+        try {
+            res = pm.getResourcesForApplication(mService.serviceInfo.packageName);
+            Drawable banner = res.getDrawable(mBannerResourceId);
+            return banner;
+        } catch (NotFoundException e) {
+            Log.e(TAG, "Could not load banner.");
+            return null;
+        } catch (NameNotFoundException e) {
+            Log.e(TAG, "Could not load banner.");
+            return null;
+        }
+    }
+
+    static boolean isValidAid(String aid) {
+        if (aid == null)
+            return false;
+
+        int aidLength = aid.length();
+        if (aidLength == 0 || (aidLength % 2) != 0) {
+            Log.e(TAG, "AID " + aid + " is not correctly formatted.");
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder out = new StringBuilder("ApduService: ");
+        out.append(getComponent());
+        out.append(", description: " + mDescription);
+        out.append(", AID Groups: ");
+        for (AidGroup aidGroup : mAidGroups) {
+            out.append(aidGroup.toString());
+        }
+        return out.toString();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof ApduServiceInfo)) return false;
+        ApduServiceInfo thatService = (ApduServiceInfo) o;
+
+        return thatService.getComponent().equals(this.getComponent());
+    }
+
+    @Override
+    public int hashCode() {
+        return getComponent().hashCode();
+    }
+
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        mService.writeToParcel(dest, flags);
+        dest.writeString(mDescription);
+        dest.writeInt(mOnHost ? 1 : 0);
+        dest.writeInt(mAidGroups.size());
+        if (mAidGroups.size() > 0) {
+            dest.writeTypedList(mAidGroups);
+        }
+        dest.writeInt(mRequiresDeviceUnlock ? 1 : 0);
+        dest.writeInt(mBannerResourceId);
+    };
+
+    public static final Parcelable.Creator<ApduServiceInfo> CREATOR =
+            new Parcelable.Creator<ApduServiceInfo>() {
+        @Override
+        public ApduServiceInfo createFromParcel(Parcel source) {
+            ResolveInfo info = ResolveInfo.CREATOR.createFromParcel(source);
+            String description = source.readString();
+            boolean onHost = (source.readInt() != 0) ? true : false;
+            ArrayList<AidGroup> aidGroups = new ArrayList<AidGroup>();
+            int numGroups = source.readInt();
+            if (numGroups > 0) {
+                source.readTypedList(aidGroups, AidGroup.CREATOR);
+            }
+            boolean requiresUnlock = (source.readInt() != 0) ? true : false;
+            int bannerResource = source.readInt();
+            return new ApduServiceInfo(info, onHost, description, aidGroups, requiresUnlock, bannerResource);
+        }
+
+        @Override
+        public ApduServiceInfo[] newArray(int size) {
+            return new ApduServiceInfo[size];
+        }
+    };
+
+    public static class AidGroup implements Parcelable {
+        final ArrayList<String> aids;
+        final String category;
+        final String description;
+
+        AidGroup(ArrayList<String> aids, String category, String description) {
+            this.aids = aids;
+            this.category = category;
+            this.description = description;
+        }
+
+        AidGroup(String category, String description) {
+            this.aids = new ArrayList<String>();
+            this.category = category;
+            this.description = description;
+        }
+
+        public String getCategory() {
+            return category;
+        }
+
+        public ArrayList<String> getAids() {
+            return aids;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder out = new StringBuilder("Category: " + category +
+                      ", description: " + description + ", AIDs:");
+            for (String aid : aids) {
+                out.append(aid);
+                out.append(", ");
+            }
+            return out.toString();
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeString(category);
+            dest.writeString(description);
+            dest.writeInt(aids.size());
+            if (aids.size() > 0) {
+                dest.writeStringList(aids);
+            }
+        }
+
+        public static final Parcelable.Creator<ApduServiceInfo.AidGroup> CREATOR =
+                new Parcelable.Creator<ApduServiceInfo.AidGroup>() {
+
+            @Override
+            public AidGroup createFromParcel(Parcel source) {
+                String category = source.readString();
+                String description = source.readString();
+                int listSize = source.readInt();
+                ArrayList<String> aidList = new ArrayList<String>();
+                if (listSize > 0) {
+                    source.readStringList(aidList);
+                }
+                return new AidGroup(aidList, category, description);
+            }
+
+            @Override
+            public AidGroup[] newArray(int size) {
+                return new AidGroup[size];
+            }
+        };
+    }
+}
diff --git a/core/java/android/nfc/cardemulation/CardEmulation.java b/core/java/android/nfc/cardemulation/CardEmulation.java
new file mode 100644
index 0000000..3cd7863
--- /dev/null
+++ b/core/java/android/nfc/cardemulation/CardEmulation.java
@@ -0,0 +1,343 @@
+/*
+ * 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.nfc.cardemulation;
+
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.app.ActivityThread;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
+import android.nfc.INfcCardEmulation;
+import android.nfc.NfcAdapter;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.Log;
+
+import java.util.HashMap;
+import java.util.List;
+
+public final class CardEmulation {
+    static final String TAG = "CardEmulation";
+
+    /**
+     * Activity action: ask the user to change the default
+     * card emulation service for a certain category. This will
+     * show a dialog that asks the user whether he wants to
+     * replace the current default service with the service
+     * identified with the ComponentName specified in
+     * {@link #EXTRA_SERVICE_COMPONENT}, for the category
+     * specified in {@link #EXTRA_CATEGORY}
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_CHANGE_DEFAULT =
+            "android.nfc.cardemulation.action.ACTION_CHANGE_DEFAULT";
+
+    /**
+     * The category extra for {@link #ACTION_CHANGE_DEFAULT}
+     *
+     * @see #ACTION_CHANGE_DEFAULT
+     */
+    public static final String EXTRA_CATEGORY = "category";
+
+    /**
+     * The ComponentName object passed in as a parcelable
+     * extra for {@link #ACTION_CHANGE_DEFAULT}
+     *
+     * @see #ACTION_CHANGE_DEFAULT
+     */
+    public static final String EXTRA_SERVICE_COMPONENT = "component";
+
+    /**
+     * The payment category can be used to indicate that an AID
+     * represents a payment application.
+     */
+    public static final String CATEGORY_PAYMENT = "payment";
+
+    /**
+     * If an AID group does not contain a category, or the
+     * specified category is not defined by the platform version
+     * that is parsing the AID group, all AIDs in the group will
+     * automatically be categorized under the {@link #CATEGORY_OTHER}
+     * category.
+     */
+    public static final String CATEGORY_OTHER = "other";
+
+    /**
+     * Return value for {@link #getSelectionModeForCategory(String)}.
+     *
+     * <p>In this mode, the user has set a default service for this
+     *    AID category. If a remote reader selects any of the AIDs
+     *    that the default service has registered in this category,
+     *    that service will automatically be bound to to handle
+     *    the transaction.
+     *
+     * <p>There are still cases where a service that is
+     *    not the default for a category can selected:
+     *    <p>
+     *    If a remote reader selects an AID in this category
+     *    that is not handled by the default service, and there is a set
+     *    of other services {S} that do handle this AID, the
+     *    user is asked if he wants to use any of the services in
+     *    {S} instead.
+     *    <p>
+     *    As a special case, if the size of {S} is one, containing a single service X,
+     *    and all AIDs X has registered in this category are not
+     *    registered by any other service, then X will be
+     *    selected automatically without asking the user.
+     *    <p>Example:
+     *    <ul>
+     *    <li>Service A registers AIDs "1", "2" and "3" in the category
+     *    <li>Service B registers AIDs "3" and "4" in the category
+     *    <li>Service C registers AIDs "5" and "6" in the category
+     *    </ul>
+     *    In this case, the following will happen when service A
+     *    is the default:
+     *    <ul>
+     *    <li>Reader selects AID "1", "2" or "3": service A is invoked automatically
+     *    <li>Reader selects AID "4": the user is asked to confirm he
+     *        wants to use service B, because its AIDs overlap with service A.
+     *    <li>Reader selects AID "5" or "6": service C is invoked automatically,
+     *        because all AIDs it has asked for are only registered by C,
+     *        and there is no overlap.
+     *    </ul>
+     *
+     */
+    public static final int SELECTION_MODE_PREFER_DEFAULT = 0;
+
+    /**
+     * Return value for {@link #getSelectionModeForCategory(String)}.
+     *
+     * <p>In this mode, whenever an AID of this category is selected,
+     *    the user is asked which service he wants to use to handle
+     *    the transaction, even if there is only one matching service.
+     */
+    public static final int SELECTION_MODE_ALWAYS_ASK = 1;
+
+    /**
+     * Return value for {@link #getSelectionModeForCategory(String)}.
+     *
+     * <p>In this mode, the user will only be asked to select a service
+     *    if the selected AID has been registered by multiple applications.
+     */
+    public static final int SELECTION_MODE_ASK_IF_CONFLICT = 2;
+
+    static boolean sIsInitialized = false;
+    static HashMap<Context, CardEmulation> sCardEmus = new HashMap();
+    static INfcCardEmulation sService;
+
+    final Context mContext;
+
+    private CardEmulation(Context context, INfcCardEmulation service) {
+        mContext = context.getApplicationContext();
+        sService = service;
+    }
+
+    public static synchronized CardEmulation getInstance(NfcAdapter adapter) {
+        if (adapter == null) throw new NullPointerException("NfcAdapter is null");
+        Context context = adapter.getContext();
+        if (context == null) {
+            Log.e(TAG, "NfcAdapter context is null.");
+            throw new UnsupportedOperationException();
+        }
+        if (!sIsInitialized) {
+            IPackageManager pm = ActivityThread.getPackageManager();
+            if (pm == null) {
+                Log.e(TAG, "Cannot get PackageManager");
+                throw new UnsupportedOperationException();
+            }
+            try {
+                if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)) {
+                    Log.e(TAG, "This device does not support card emulation");
+                    throw new UnsupportedOperationException();
+                }
+            } catch (RemoteException e) {
+                Log.e(TAG, "PackageManager query failed.");
+                throw new UnsupportedOperationException();
+            }
+            sIsInitialized = true;
+        }
+        CardEmulation manager = sCardEmus.get(context);
+        if (manager == null) {
+            // Get card emu service
+            INfcCardEmulation service = adapter.getCardEmulationService();
+            manager = new CardEmulation(context, service);
+            sCardEmus.put(context, manager);
+        }
+        return manager;
+    }
+
+    /**
+     * Allows an application to query whether a service is currently
+     * the default service to handle a card emulation category.
+     *
+     * <p>Note that if {@link #getSelectionModeForCategory(String)}
+     * returns {@link #SELECTION_MODE_ALWAYS_ASK}, this method will always
+     * return false.
+     *
+     * @param service The ComponentName of the service
+     * @param category The category
+     * @return whether service is currently the default service for the category.
+     */
+    public boolean isDefaultServiceForCategory(ComponentName service, String category) {
+        try {
+            return sService.isDefaultServiceForCategory(UserHandle.myUserId(), service, category);
+        } catch (RemoteException e) {
+            // Try one more time
+            recoverService();
+            if (sService == null) {
+                Log.e(TAG, "Failed to recover CardEmulationService.");
+                return false;
+            }
+            try {
+                return sService.isDefaultServiceForCategory(UserHandle.myUserId(), service,
+                        category);
+            } catch (RemoteException ee) {
+                Log.e(TAG, "Failed to recover CardEmulationService.");
+                return false;
+            }
+        }
+    }
+
+    /**
+     *
+     * Allows an application to query whether a service is currently
+     * the default handler for a specified ISO7816-4 Application ID.
+     *
+     * @param service The ComponentName of the service
+     * @param aid The ISO7816-4 Application ID
+     * @return
+     */
+    public boolean isDefaultServiceForAid(ComponentName service, String aid) {
+        try {
+            return sService.isDefaultServiceForAid(UserHandle.myUserId(), service, aid);
+        } catch (RemoteException e) {
+            // Try one more time
+            recoverService();
+            if (sService == null) {
+                Log.e(TAG, "Failed to recover CardEmulationService.");
+                return false;
+            }
+            try {
+                return sService.isDefaultServiceForAid(UserHandle.myUserId(), service, aid);
+            } catch (RemoteException ee) {
+                Log.e(TAG, "Failed to reach CardEmulationService.");
+                return false;
+            }
+        }
+    }
+
+    /**
+     * Returns the application selection mode for the passed in category.
+     * Valid return values are:
+     * <p>{@link #SELECTION_MODE_PREFER_DEFAULT} the user has requested a default
+     *    application for this category, which will be preferred.
+     * <p>{@link #SELECTION_MODE_ALWAYS_ASK} the user has requested to be asked
+     *    every time what app he would like to use in this category.
+     * <p>{@link #SELECTION_MODE_ASK_IF_CONFLICT} the user will only be asked
+     *    to pick a service if there is a conflict.
+     * @param category The category, for example {@link #CATEGORY_PAYMENT}
+     * @return
+     */
+    public int getSelectionModeForCategory(String category) {
+        if (CATEGORY_PAYMENT.equals(category)) {
+            String defaultComponent = Settings.Secure.getString(mContext.getContentResolver(),
+                    Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT);
+            if (defaultComponent != null) {
+                return SELECTION_MODE_PREFER_DEFAULT;
+            } else {
+                return SELECTION_MODE_ALWAYS_ASK;
+            }
+        } else {
+            // All other categories are in "only ask if conflict" mode
+            return SELECTION_MODE_ASK_IF_CONFLICT;
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public boolean setDefaultServiceForCategory(ComponentName service, String category) {
+        try {
+            return sService.setDefaultServiceForCategory(UserHandle.myUserId(), service, category);
+        } catch (RemoteException e) {
+            // Try one more time
+            recoverService();
+            if (sService == null) {
+                Log.e(TAG, "Failed to recover CardEmulationService.");
+                return false;
+            }
+            try {
+                return sService.setDefaultServiceForCategory(UserHandle.myUserId(), service,
+                        category);
+            } catch (RemoteException ee) {
+                Log.e(TAG, "Failed to reach CardEmulationService.");
+                return false;
+            }
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public boolean setDefaultForNextTap(ComponentName service) {
+        try {
+            return sService.setDefaultForNextTap(UserHandle.myUserId(), service);
+        } catch (RemoteException e) {
+            // Try one more time
+            recoverService();
+            if (sService == null) {
+                Log.e(TAG, "Failed to recover CardEmulationService.");
+                return false;
+            }
+            try {
+                return sService.setDefaultForNextTap(UserHandle.myUserId(), service);
+            } catch (RemoteException ee) {
+                Log.e(TAG, "Failed to reach CardEmulationService.");
+                return false;
+            }
+        }
+    }
+    /**
+     * @hide
+     */
+    public List<ApduServiceInfo> getServices(String category) {
+        try {
+            return sService.getServices(UserHandle.myUserId(), category);
+        } catch (RemoteException e) {
+            // Try one more time
+            recoverService();
+            if (sService == null) {
+                Log.e(TAG, "Failed to recover CardEmulationService.");
+                return null;
+            }
+            try {
+                return sService.getServices(UserHandle.myUserId(), category);
+            } catch (RemoteException ee) {
+                Log.e(TAG, "Failed to reach CardEmulationService.");
+                return null;
+            }
+        }
+    }
+
+    void recoverService() {
+        NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext);
+        sService = adapter.getCardEmulationService();
+    }
+}
diff --git a/core/java/android/nfc/cardemulation/HostApduService.java b/core/java/android/nfc/cardemulation/HostApduService.java
new file mode 100644
index 0000000..e2c3ca6
--- /dev/null
+++ b/core/java/android/nfc/cardemulation/HostApduService.java
@@ -0,0 +1,278 @@
+package android.nfc.cardemulation;
+
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * <p>A convenience class that can be extended to implement
+ * a service that processes ISO7816-4 commands on top of
+ * the ISO14443-4 / IsoDep protocol (T=CL).
+ *
+ * <p>To tell the platform which ISO7816 application ID (AIDs)
+ * are implemented by this service, a {@link #SERVICE_META_DATA}
+ * entry must be included in the declaration of the service. An
+ * example of such a service declaration is shown below:
+ * <pre> &lt;service android:name=".MyHostApduService"&gt;
+ *     &lt;intent-filter&gt;
+ *         &lt;action android:name="android.nfc.HostApduService"/&gt;
+ *     &lt;/intent-filter&gt;
+ *     &lt;meta-data android:name="android.nfc.HostApduService" android:resource="@xml/apduservice.xml"/&gt;
+ * &lt;/service&gt;</pre>
+ * <p>For more details refer to {@link #SERVICE_META_DATA},
+ * <code>&lt;{@link android.R.styleable#HostApduService host-apdu-service}&gt;</code>,
+ * <code>&lt;{@link android.R.styleable#AidGroup aid-group}&gt;</code> and
+ * <code>&lt;{@link android.R.styleable#AidFilter aid-filter}&gt;</code>.
+ * <p class="note">The Android platform currently only supports a single
+ * logical channel.
+ */
+public abstract class HostApduService extends Service {
+    /**
+     * The {@link Intent} that must be declared as handled by the service.
+     */
+    @SdkConstant(SdkConstantType.SERVICE_ACTION)
+    public static final String SERVICE_INTERFACE =
+            "android.nfc.cardemulation.action.HOST_APDU_SERVICE";
+
+    /**
+     * The name of the meta-data element that contains
+     * more information about this service.
+     */
+    public static final String SERVICE_META_DATA =
+            "android.nfc.cardemulation.host_apdu_service";
+
+    /**
+     * Reason for {@link #onDeactivated(int)}.
+     * Indicates deactivation was due to the NFC link
+     * being lost.
+     */
+    public static final int DEACTIVATION_LINK_LOSS = 0;
+
+    /**
+     * Reason for {@link #onDeactivated(int)}.
+     *
+     * <p>Indicates deactivation was due to a different AID
+     * being selected (which implicitly deselects the AID
+     * currently active on the logical channel).
+     *
+     * <p>Note that this next AID may still be resolved to this
+     * service, in which case {@link #processCommandApdu(byte[], Bundle)}
+     * will be called again.
+     */
+    public static final int DEACTIVATION_DESELECTED = 1;
+
+    static final String TAG = "ApduService";
+
+    /**
+     * MSG_COMMAND_APDU is sent by NfcService when
+     * a 7816-4 command APDU has been received.
+     *
+     * @hide
+     */
+    public static final int MSG_COMMAND_APDU = 0;
+
+    /**
+     * MSG_RESPONSE_APDU is sent to NfcService to send
+     * a response APDU back to the remote device.
+     *
+     * @hide
+     */
+    public static final int MSG_RESPONSE_APDU = 1;
+
+    /**
+     * MSG_DEACTIVATED is sent by NfcService when
+     * the current session is finished; either because
+     * another AID was selected that resolved to
+     * another service, or because the NFC link
+     * was deactivated.
+     *
+     * @hide
+     */
+    public static final int MSG_DEACTIVATED = 2;
+
+    /**
+     *
+     * @hide
+     */
+    public static final int MSG_UNHANDLED = 3;
+
+    /**
+     * @hide
+     */
+    public static final String KEY_DATA = "data";
+
+    /**
+     * Messenger interface to NfcService for sending responses.
+     * Only accessed on main thread by the message handler.
+     *
+     * @hide
+     */
+    Messenger mNfcService = null;
+
+    final Messenger mMessenger = new Messenger(new MsgHandler());
+
+    final class MsgHandler extends Handler {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+            case MSG_COMMAND_APDU:
+                Bundle dataBundle = msg.getData();
+                if (dataBundle == null) {
+                    return;
+                }
+                if (mNfcService == null) mNfcService = msg.replyTo;
+
+                byte[] apdu = dataBundle.getByteArray(KEY_DATA);
+                if (apdu != null) {
+                    byte[] responseApdu = processCommandApdu(apdu, null);
+                    if (responseApdu != null) {
+                        if (mNfcService == null) {
+                            Log.e(TAG, "Response not sent; service was deactivated.");
+                            return;
+                        }
+                        Message responseMsg = Message.obtain(null, MSG_RESPONSE_APDU);
+                        Bundle responseBundle = new Bundle();
+                        responseBundle.putByteArray(KEY_DATA, responseApdu);
+                        responseMsg.setData(responseBundle);
+                        responseMsg.replyTo = mMessenger;
+                        try {
+                            mNfcService.send(responseMsg);
+                        } catch (RemoteException e) {
+                            Log.e("TAG", "Response not sent; RemoteException calling into " +
+                                    "NfcService.");
+                        }
+                    }
+                } else {
+                    Log.e(TAG, "Received MSG_COMMAND_APDU without data.");
+                }
+                break;
+            case MSG_RESPONSE_APDU:
+                if (mNfcService == null) {
+                    Log.e(TAG, "Response not sent; service was deactivated.");
+                    return;
+                }
+                try {
+                    msg.replyTo = mMessenger;
+                    mNfcService.send(msg);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "RemoteException calling into NfcService.");
+                }
+                break;
+            case MSG_DEACTIVATED:
+                // Make sure we won't call into NfcService again
+                mNfcService = null;
+                onDeactivated(msg.arg1);
+                break;
+            case MSG_UNHANDLED:
+                if (mNfcService == null) {
+                    Log.e(TAG, "notifyUnhandled not sent; service was deactivated.");
+                    return;
+                }
+                try {
+                    msg.replyTo = mMessenger;
+                    mNfcService.send(msg);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "RemoteException calling into NfcService.");
+                }
+                break;
+            default:
+                super.handleMessage(msg);
+            }
+        }
+    }
+
+    @Override
+    public final IBinder onBind(Intent intent) {
+        return mMessenger.getBinder();
+    }
+
+    /**
+     * Sends a response APDU back to the remote device.
+     *
+     * <p>Note: this method may be called from any thread and will not block.
+     * @param responseApdu A byte-array containing the reponse APDU.
+     */
+    public final void sendResponseApdu(byte[] responseApdu) {
+        Message responseMsg = Message.obtain(null, MSG_RESPONSE_APDU);
+        Bundle dataBundle = new Bundle();
+        dataBundle.putByteArray(KEY_DATA, responseApdu);
+        responseMsg.setData(dataBundle);
+        try {
+            mMessenger.send(responseMsg);
+        } catch (RemoteException e) {
+            Log.e("TAG", "Local messenger has died.");
+        }
+    }
+
+    /**
+     * Calling this method allows the service to tell the OS
+     * that it won't be able to complete this transaction -
+     * for example, because it requires data connectivity
+     * that is not present at that moment.
+     *
+     * The OS may use this indication to give the user a list
+     * of alternative applications that can handle the last
+     * AID that was selected. If the user would select an
+     * application from the list, that action by itself
+     * will not cause the default to be changed; the selected
+     * application will be invoked for the next tap only.
+     *
+     * If there are no other applications that can handle
+     * this transaction, the OS will show an error dialog
+     * indicating your service could not complete the
+     * transaction.
+     *
+     * <p>Note: this method may be called anywhere between
+     *    the first {@link #processCommandApdu(byte[], Bundle)}
+     *    call and a {@link #onDeactivated(int)} call.
+     */
+    public final void notifyUnhandled() {
+        Message unhandledMsg = Message.obtain(null, MSG_UNHANDLED);
+        try {
+            mMessenger.send(unhandledMsg);
+        } catch (RemoteException e) {
+            Log.e("TAG", "Local messenger has died.");
+        }
+    }
+
+
+    /**
+     * <p>This method will be called when a command APDU has been received
+     * from a remote device. A response APDU can be provided directly
+     * by returning a byte-array in this method. Note that in general
+     * response APDUs must be sent as quickly as possible, given the fact
+     * that the user is likely holding his device over an NFC reader
+     * when this method is called.
+     *
+     * <p class="note">If there are multiple services that have registered for the same
+     * AIDs in their meta-data entry, you will only get called if the user has
+     * explicitly selected your service, either as a default or just for the next tap.
+     *
+     * <p class="note">This method is running on the main thread of your application.
+     * If you cannot return a response APDU immediately, return null
+     * and use the {@link #sendResponseApdu(byte[])} method later.
+     *
+     * @param commandApdu The APDU that received from the remote device
+     * @param extras A bundle containing extra data. May be null.
+     * @return a byte-array containing the response APDU, or null if no
+     *         response APDU can be sent at this point.
+     */
+    public abstract byte[] processCommandApdu(byte[] commandApdu, Bundle extras);
+
+    /**
+     * This method will be called in two possible scenarios:
+     * <li>The NFC link has been deactivated or lost
+     * <li>A different AID has been selected and was resolved to a different
+     *     service component
+     * @param reason Either {@link #DEACTIVATION_LINK_LOSS} or {@link #DEACTIVATION_DESELECTED}
+     */
+    public abstract void onDeactivated(int reason);
+}
diff --git a/core/java/android/nfc/cardemulation/OffHostApduService.java b/core/java/android/nfc/cardemulation/OffHostApduService.java
new file mode 100644
index 0000000..15f63f9
--- /dev/null
+++ b/core/java/android/nfc/cardemulation/OffHostApduService.java
@@ -0,0 +1,69 @@
+package android.nfc.cardemulation;
+
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+/**
+ * <p>A convenience class that can be extended to implement
+ * a service that registers ISO7814-4 AIDs that reside off-host,
+ * for example on an embedded secure element or UICC.
+ *
+ * <p>This registration will allow the service to be included
+ * as an option for handling these AIDs on non-host execution
+ * environments. The Operating System will take care of correctly
+ * routing the AIDs, based on which service the user has selected
+ * to be the handler for an AID.
+ *
+ * <p>The service may define additional actions outside of the
+ * Android namespace that provide further interaction with
+ * the off-host execution environment.
+ *
+ * <p>To tell the platform which ISO7816 application ID (AIDs)
+ * are present and handled by the app containing this service,
+ * a {@link #SERVICE_META_DATA} entry must be included in the declaration
+ * of the service. An example of such a service declaration is shown below:
+ * <pre> &lt;service android:name=".MyOffHostApduService"&gt;
+ *     &lt;intent-filter&gt;
+ *         &lt;action android:name="android.nfc.OffHostApduService"/&gt;
+ *     &lt;/intent-filter&gt;
+ *     &lt;meta-data android:name="android.nfc.OffHostApduService" android:resource="@xml/apduservice.xml"/&gt;
+ * &lt;/service&gt;</pre>
+ * <p>For more details refer to {@link #SERVICE_META_DATA},
+ * <code>&lt;{@link android.R.styleable#OffHostApduService offhost-apdu-service}&gt;</code>,
+ * <code>&lt;{@link android.R.styleable#AidGroup aid-group}&gt;</code> and
+ * <code>&lt;{@link android.R.styleable#AidFilter aid-filter}&gt;</code>.
+ */
+public abstract class OffHostApduService extends Service {
+    /**
+     * The {@link Intent} that must be declared as handled by the service.
+     */
+    @SdkConstant(SdkConstantType.SERVICE_ACTION)
+    public static final String SERVICE_INTERFACE =
+            "android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE";
+
+    /**
+     * The name of the meta-data element that contains
+     * more information about this service.
+     */
+    public static final String SERVICE_META_DATA =
+            "android.nfc.cardemulation.off_host_apdu_service";
+
+    /**
+     * The Android platform itself will not bind to this service,
+     * but merely uses its declaration to keep track of what AIDs
+     * the service is interested in. This information is then used
+     * to present the user with a list of applications that can handle
+     * an AID, as well as correctly route those AIDs either to the host (in case
+     * the user preferred a {@link HostApduService}), or to an off-host
+     * execution environment (in case the user preferred a {@link OffHostApduService}.
+     *
+     * Implementers may define additional actions outside of the
+     * Android namespace that allow further interactions with
+     * the off-host execution environment. Such implementations
+     * would need to override this method.
+     */
+    public abstract IBinder onBind(Intent intent);
+}
diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java
index ce5f163..d4a3006 100644
--- a/core/java/android/os/AsyncTask.java
+++ b/core/java/android/os/AsyncTask.java
@@ -177,8 +177,9 @@
 public abstract class AsyncTask<Params, Progress, Result> {
     private static final String LOG_TAG = "AsyncTask";
 
-    private static final int CORE_POOL_SIZE = 5;
-    private static final int MAXIMUM_POOL_SIZE = 128;
+    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
+    private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
+    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
     private static final int KEEP_ALIVE = 1;
 
     private static final ThreadFactory sThreadFactory = new ThreadFactory() {
@@ -190,7 +191,7 @@
     };
 
     private static final BlockingQueue<Runnable> sPoolWorkQueue =
-            new LinkedBlockingQueue<Runnable>(10);
+            new LinkedBlockingQueue<Runnable>(128);
 
     /**
      * An {@link Executor} that can be used to execute tasks in parallel.
diff --git a/core/java/android/os/BatteryProperties.aidl b/core/java/android/os/BatteryProperties.aidl
new file mode 100644
index 0000000..31fa7b8
--- /dev/null
+++ b/core/java/android/os/BatteryProperties.aidl
@@ -0,0 +1,19 @@
+/*
+** Copyright 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.os;
+
+parcelable BatteryProperties;
diff --git a/core/java/android/os/BatteryProperties.java b/core/java/android/os/BatteryProperties.java
new file mode 100644
index 0000000..5df5214
--- /dev/null
+++ b/core/java/android/os/BatteryProperties.java
@@ -0,0 +1,87 @@
+/* Copyright 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.os;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * {@hide}
+ */
+public class BatteryProperties implements Parcelable {
+    public boolean chargerAcOnline;
+    public boolean chargerUsbOnline;
+    public boolean chargerWirelessOnline;
+    public int batteryStatus;
+    public int batteryHealth;
+    public boolean batteryPresent;
+    public int batteryLevel;
+    public int batteryVoltage;
+    public int batteryCurrentNow;
+    public int batteryChargeCounter;
+    public int batteryTemperature;
+    public String batteryTechnology;
+
+    /*
+     * Parcel read/write code must be kept in sync with
+     * frameworks/native/services/batteryservice/BatteryProperties.cpp
+     */
+
+    private BatteryProperties(Parcel p) {
+        chargerAcOnline = p.readInt() == 1 ? true : false;
+        chargerUsbOnline = p.readInt() == 1 ? true : false;
+        chargerWirelessOnline = p.readInt() == 1 ? true : false;
+        batteryStatus = p.readInt();
+        batteryHealth = p.readInt();
+        batteryPresent = p.readInt() == 1 ? true : false;
+        batteryLevel = p.readInt();
+        batteryVoltage = p.readInt();
+        batteryCurrentNow = p.readInt();
+        batteryChargeCounter = p.readInt();
+        batteryTemperature = p.readInt();
+        batteryTechnology = p.readString();
+    }
+
+    public void writeToParcel(Parcel p, int flags) {
+        p.writeInt(chargerAcOnline ? 1 : 0);
+        p.writeInt(chargerUsbOnline ? 1 : 0);
+        p.writeInt(chargerWirelessOnline ? 1 : 0);
+        p.writeInt(batteryStatus);
+        p.writeInt(batteryHealth);
+        p.writeInt(batteryPresent ? 1 : 0);
+        p.writeInt(batteryLevel);
+        p.writeInt(batteryVoltage);
+        p.writeInt(batteryCurrentNow);
+        p.writeInt(batteryChargeCounter);
+        p.writeInt(batteryTemperature);
+        p.writeString(batteryTechnology);
+    }
+
+    public static final Parcelable.Creator<BatteryProperties> CREATOR
+        = new Parcelable.Creator<BatteryProperties>() {
+        public BatteryProperties createFromParcel(Parcel p) {
+            return new BatteryProperties(p);
+        }
+
+        public BatteryProperties[] newArray(int size) {
+            return new BatteryProperties[size];
+        }
+    };
+
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 499ec77..dbaa325 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -41,7 +41,10 @@
 public abstract class BatteryStats implements Parcelable {
 
     private static final boolean LOCAL_LOGV = false;
-    
+
+    /** @hide */
+    public static final String SERVICE_NAME = "batterystats";
+
     /**
      * A constant indicating a partial wake lock timer.
      */
@@ -98,6 +101,11 @@
     public static final int VIBRATOR_ON = 9;
 
     /**
+     * A constant indicating a foreground activity timer
+     */
+    public static final int FOREGROUND_ACTIVITY = 10;
+
+    /**
      * Include all of the data in the stats, including previously saved data.
      */
     public static final int STATS_SINCE_CHARGED = 0;
@@ -125,7 +133,7 @@
     /**
      * Bump the version on this if the checkin format changes.
      */
-    private static final int BATTERY_STATS_CHECKIN_VERSION = 5;
+    private static final int BATTERY_STATS_CHECKIN_VERSION = 7;
     
     private static final long BYTES_PER_KB = 1024;
     private static final long BYTES_PER_MB = 1048576; // 1024^2
@@ -137,6 +145,7 @@
     private static final String PROCESS_DATA = "pr";
     private static final String SENSOR_DATA = "sr";
     private static final String VIBRATOR_DATA = "vib";
+    private static final String FOREGROUND_DATA = "fg";
     private static final String WAKELOCK_DATA = "wl";
     private static final String KERNEL_WAKELOCK_DATA = "kwl";
     private static final String NETWORK_DATA = "nt";
@@ -146,6 +155,7 @@
     private static final String BATTERY_LEVEL_DATA = "lv";
     private static final String WIFI_DATA = "wfl";
     private static final String MISC_DATA = "m";
+    private static final String HISTORY_DATA = "h";
     private static final String SCREEN_BRIGHTNESS_DATA = "br";
     private static final String SIGNAL_STRENGTH_TIME_DATA = "sgt";
     private static final String SIGNAL_SCANNING_TIME_DATA = "sst";
@@ -253,17 +263,7 @@
          * {@hide}
          */
         public abstract int getUid();
-        
-        /**
-         * {@hide}
-         */
-        public abstract long getTcpBytesReceived(int which);
-        
-        /**
-         * {@hide}
-         */
-        public abstract long getTcpBytesSent(int which);
-        
+
         public abstract void noteWifiRunningLocked();
         public abstract void noteWifiStoppedLocked();
         public abstract void noteFullWifiLockAcquiredLocked();
@@ -276,6 +276,8 @@
         public abstract void noteAudioTurnedOffLocked();
         public abstract void noteVideoTurnedOnLocked();
         public abstract void noteVideoTurnedOffLocked();
+        public abstract void noteActivityResumedLocked();
+        public abstract void noteActivityPausedLocked();
         public abstract long getWifiRunningTime(long batteryRealtime, int which);
         public abstract long getFullWifiLockTime(long batteryRealtime, int which);
         public abstract long getWifiScanTime(long batteryRealtime, int which);
@@ -283,6 +285,7 @@
                                                   int which);
         public abstract long getAudioTurnedOnTime(long batteryRealtime, int which);
         public abstract long getVideoTurnedOnTime(long batteryRealtime, int which);
+        public abstract Timer getForegroundActivityTimer();
         public abstract Timer getVibratorOnTimer();
 
         /**
@@ -295,11 +298,14 @@
         };
         
         public static final int NUM_USER_ACTIVITY_TYPES = 3;
-        
+
         public abstract void noteUserActivityLocked(int type);
         public abstract boolean hasUserActivity();
         public abstract int getUserActivityCount(int type, int which);
-        
+
+        public abstract boolean hasNetworkActivity();
+        public abstract long getNetworkActivityCount(int type, int which);
+
         public static abstract class Sensor {
             /*
              * FIXME: it's not correct to use this magic value because it
@@ -920,6 +926,15 @@
      */
     public abstract long getBluetoothOnTime(long batteryRealtime, int which);
     
+    public static final int NETWORK_MOBILE_RX_BYTES = 0;
+    public static final int NETWORK_MOBILE_TX_BYTES = 1;
+    public static final int NETWORK_WIFI_RX_BYTES = 2;
+    public static final int NETWORK_WIFI_TX_BYTES = 3;
+
+    public static final int NUM_NETWORK_ACTIVITY_TYPES = NETWORK_WIFI_TX_BYTES + 1;
+
+    public abstract long getNetworkActivityCount(int type, int which);
+
     /**
      * Return whether we are currently running on battery.
      */
@@ -1194,13 +1209,13 @@
         pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
         pw.print(uid); pw.print(',');
         pw.print(category); pw.print(',');
-        pw.print(type); 
+        pw.print(type);
         
         for (Object arg : args) {  
-            pw.print(','); 
-            pw.print(arg); 
+            pw.print(',');
+            pw.print(arg);
         }
-        pw.print('\n');
+        pw.println();
     }
     
     /**
@@ -1229,7 +1244,7 @@
         final int NU = uidStats.size();
         
         String category = STAT_NAMES[which];
-        
+
         // Dump "battery" stat
         dumpLine(pw, 0 /* uid */, category, BATTERY_DATA, 
                 which == STATS_SINCE_CHARGED ? getStartCount() : "N/A",
@@ -1237,16 +1252,20 @@
                 totalRealtime / 1000, totalUptime / 1000); 
         
         // Calculate total network and wakelock times across all uids.
-        long rxTotal = 0;
-        long txTotal = 0;
+        long mobileRxTotal = 0;
+        long mobileTxTotal = 0;
+        long wifiRxTotal = 0;
+        long wifiTxTotal = 0;
         long fullWakeLockTimeTotal = 0;
         long partialWakeLockTimeTotal = 0;
         
         for (int iu = 0; iu < NU; iu++) {
             Uid u = uidStats.valueAt(iu);
-            rxTotal += u.getTcpBytesReceived(which);
-            txTotal += u.getTcpBytesSent(which);
-            
+            mobileRxTotal += u.getNetworkActivityCount(NETWORK_MOBILE_RX_BYTES, which);
+            mobileTxTotal += u.getNetworkActivityCount(NETWORK_MOBILE_TX_BYTES, which);
+            wifiRxTotal += u.getNetworkActivityCount(NETWORK_WIFI_RX_BYTES, which);
+            wifiTxTotal += u.getNetworkActivityCount(NETWORK_WIFI_TX_BYTES, which);
+
             Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
             if (wakelocks.size() > 0) {
                 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 
@@ -1270,7 +1289,8 @@
         // Dump misc stats
         dumpLine(pw, 0 /* uid */, category, MISC_DATA,
                 screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000,
-                wifiRunningTime / 1000, bluetoothOnTime / 1000, rxTotal, txTotal, 
+                wifiRunningTime / 1000, bluetoothOnTime / 1000,
+                mobileRxTotal, mobileTxTotal, wifiRxTotal, wifiTxTotal,
                 fullWakeLockTimeTotal, partialWakeLockTimeTotal,
                 getInputEventCount(which));
         
@@ -1341,14 +1361,18 @@
             }
             Uid u = uidStats.valueAt(iu);
             // Dump Network stats per uid, if any
-            long rx = u.getTcpBytesReceived(which);
-            long tx = u.getTcpBytesSent(which);
+            long mobileRx = u.getNetworkActivityCount(NETWORK_MOBILE_RX_BYTES, which);
+            long mobileTx = u.getNetworkActivityCount(NETWORK_MOBILE_TX_BYTES, which);
+            long wifiRx = u.getNetworkActivityCount(NETWORK_WIFI_RX_BYTES, which);
+            long wifiTx = u.getNetworkActivityCount(NETWORK_WIFI_TX_BYTES, which);
             long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
             long wifiScanTime = u.getWifiScanTime(batteryRealtime, which);
             long uidWifiRunningTime = u.getWifiRunningTime(batteryRealtime, which);
-            
-            if (rx > 0 || tx > 0) dumpLine(pw, uid, category, NETWORK_DATA, rx, tx);
-            
+
+            if (mobileRx > 0 || mobileTx > 0 || wifiRx > 0 || wifiTx > 0) {
+                dumpLine(pw, uid, category, NETWORK_DATA, mobileRx, mobileTx, wifiRx, wifiTx);
+            }
+
             if (fullWifiLockOnTime != 0 || wifiScanTime != 0
                     || uidWifiRunningTime != 0) {
                 dumpLine(pw, uid, category, WIFI_DATA,
@@ -1384,7 +1408,11 @@
                     
                     // Only log if we had at lease one wakelock...
                     if (sb.length() > 0) {
-                       dumpLine(pw, uid, category, WAKELOCK_DATA, ent.getKey(), sb.toString());
+                        String name = ent.getKey();
+                        if (name.indexOf(',') >= 0) {
+                            name = name.replace(',', '_');
+                        }
+                        dumpLine(pw, uid, category, WAKELOCK_DATA, name, sb.toString());
                     }
                 }
             }
@@ -1417,22 +1445,31 @@
                 }
             }
 
+            Timer fgTimer = u.getForegroundActivityTimer();
+            if (fgTimer != null) {
+                // Convert from microseconds to milliseconds with rounding
+                long totalTime = (fgTimer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000;
+                int count = fgTimer.getCountLocked(which);
+                if (totalTime != 0) {
+                    dumpLine(pw, uid, category, FOREGROUND_DATA, totalTime, count);
+                }
+            }
+
             Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
             if (processStats.size() > 0) {
                 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
                         : processStats.entrySet()) {
                     Uid.Proc ps = ent.getValue();
-    
-                    long userTime = ps.getUserTime(which);
-                    long systemTime = ps.getSystemTime(which);
-                    int starts = ps.getStarts(which);
-    
-                    if (userTime != 0 || systemTime != 0 || starts != 0) {
-                        dumpLine(pw, uid, category, PROCESS_DATA, 
-                                ent.getKey(), // proc
-                                userTime * 10, // cpu time in ms
-                                systemTime * 10, // user time in ms
-                                starts); // process starts
+
+                    final long userMillis = ps.getUserTime(which) * 10;
+                    final long systemMillis = ps.getSystemTime(which) * 10;
+                    final long foregroundMillis = ps.getForegroundTime(which) * 10;
+                    final long starts = ps.getStarts(which);
+
+                    if (userMillis != 0 || systemMillis != 0 || foregroundMillis != 0
+                            || starts != 0) {
+                        dumpLine(pw, uid, category, PROCESS_DATA, ent.getKey(), userMillis,
+                                systemMillis, foregroundMillis, starts);
                     }
                 }
             }
@@ -1551,8 +1588,10 @@
         pw.println(sb.toString());
         
         // Calculate total network and wakelock times across all uids.
-        long rxTotal = 0;
-        long txTotal = 0;
+        long mobileRxTotal = 0;
+        long mobileTxTotal = 0;
+        long wifiRxTotal = 0;
+        long wifiTxTotal = 0;
         long fullWakeLockTimeTotalMicros = 0;
         long partialWakeLockTimeTotalMicros = 0;
 
@@ -1605,9 +1644,11 @@
 
         for (int iu = 0; iu < NU; iu++) {
             Uid u = uidStats.valueAt(iu);
-            rxTotal += u.getTcpBytesReceived(which);
-            txTotal += u.getTcpBytesSent(which);
-            
+            mobileRxTotal += u.getNetworkActivityCount(NETWORK_MOBILE_RX_BYTES, which);
+            mobileTxTotal += u.getNetworkActivityCount(NETWORK_MOBILE_TX_BYTES, which);
+            wifiRxTotal += u.getNetworkActivityCount(NETWORK_WIFI_RX_BYTES, which);
+            wifiTxTotal += u.getNetworkActivityCount(NETWORK_WIFI_TX_BYTES, which);
+
             Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
             if (wakelocks.size() > 0) {
                 for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent 
@@ -1640,8 +1681,11 @@
         }
         
         pw.print(prefix);
-                pw.print("  Total received: "); pw.print(formatBytesLocked(rxTotal));
-                pw.print(", Total sent: "); pw.println(formatBytesLocked(txTotal));
+                pw.print("  Mobile total received: "); pw.print(formatBytesLocked(mobileRxTotal));
+                pw.print(", Total sent: "); pw.println(formatBytesLocked(mobileTxTotal));
+        pw.print(prefix);
+                pw.print("  Wi-Fi total received: "); pw.print(formatBytesLocked(wifiRxTotal));
+                pw.print(", Total sent: "); pw.println(formatBytesLocked(wifiTxTotal));
         sb.setLength(0);
         sb.append(prefix);
                 sb.append("  Total full wakelock time: "); formatTimeMs(sb,
@@ -1760,8 +1804,8 @@
             for (int i=0; i<timers.size(); i++) {
                 TimerEntry timer = timers.get(i);
                 sb.setLength(0);
-                sb.append("  Wake lock #");
-                sb.append(timer.mId);
+                sb.append("  Wake lock ");
+                UserHandle.formatUid(sb, timer.mId);
                 sb.append(" ");
                 sb.append(timer.mName);
                 printWakeLock(sb, timer.mTimer, batteryRealtime, null, which, ": ");
@@ -1779,22 +1823,32 @@
             }
             
             Uid u = uidStats.valueAt(iu);
-            
-            pw.println(prefix + "  #" + uid + ":");
+
+            pw.print(prefix);
+            pw.print("  ");
+            UserHandle.formatUid(pw, uid);
+            pw.println(":");
             boolean uidActivity = false;
             
-            long tcpReceived = u.getTcpBytesReceived(which);
-            long tcpSent = u.getTcpBytesSent(which);
+            long mobileRxBytes = u.getNetworkActivityCount(NETWORK_MOBILE_RX_BYTES, which);
+            long mobileTxBytes = u.getNetworkActivityCount(NETWORK_MOBILE_TX_BYTES, which);
+            long wifiRxBytes = u.getNetworkActivityCount(NETWORK_WIFI_RX_BYTES, which);
+            long wifiTxBytes = u.getNetworkActivityCount(NETWORK_WIFI_TX_BYTES, which);
             long fullWifiLockOnTime = u.getFullWifiLockTime(batteryRealtime, which);
             long wifiScanTime = u.getWifiScanTime(batteryRealtime, which);
             long uidWifiRunningTime = u.getWifiRunningTime(batteryRealtime, which);
-            
-            if (tcpReceived != 0 || tcpSent != 0) {
-                pw.print(prefix); pw.print("    Network: ");
-                        pw.print(formatBytesLocked(tcpReceived)); pw.print(" received, ");
-                        pw.print(formatBytesLocked(tcpSent)); pw.println(" sent");
+
+            if (mobileRxBytes > 0 || mobileTxBytes > 0) {
+                pw.print(prefix); pw.print("    Mobile network: ");
+                        pw.print(formatBytesLocked(mobileRxBytes)); pw.print(" received, ");
+                        pw.print(formatBytesLocked(mobileTxBytes)); pw.println(" sent");
             }
-            
+            if (wifiRxBytes > 0 || wifiTxBytes > 0) {
+                pw.print(prefix); pw.print("    Wi-Fi network: ");
+                        pw.print(formatBytesLocked(wifiRxBytes)); pw.print(" received, ");
+                        pw.print(formatBytesLocked(wifiTxBytes)); pw.println(" sent");
+            }
+
             if (u.hasUserActivity()) {
                 boolean hasData = false;
                 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
@@ -1961,6 +2015,24 @@
                 }
             }
 
+            Timer fgTimer = u.getForegroundActivityTimer();
+            if (fgTimer != null) {
+                // Convert from microseconds to milliseconds with rounding
+                long totalTime = (fgTimer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000;
+                int count = fgTimer.getCountLocked(which);
+                if (totalTime != 0) {
+                    sb.setLength(0);
+                    sb.append(prefix);
+                    sb.append("    Foreground activities: ");
+                    formatTimeMs(sb, totalTime);
+                    sb.append("realtime (");
+                    sb.append(count);
+                    sb.append(" times)");
+                    pw.println(sb.toString());
+                    uidActivity = true;
+                }
+            }
+
             Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
             if (processStats.size() > 0) {
                 for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
@@ -1968,23 +2040,26 @@
                     Uid.Proc ps = ent.getValue();
                     long userTime;
                     long systemTime;
+                    long foregroundTime;
                     int starts;
                     int numExcessive;
 
                     userTime = ps.getUserTime(which);
                     systemTime = ps.getSystemTime(which);
+                    foregroundTime = ps.getForegroundTime(which);
                     starts = ps.getStarts(which);
                     numExcessive = which == STATS_SINCE_CHARGED
                             ? ps.countExcessivePowers() : 0;
 
-                    if (userTime != 0 || systemTime != 0 || starts != 0
+                    if (userTime != 0 || systemTime != 0 || foregroundTime != 0 || starts != 0
                             || numExcessive != 0) {
                         sb.setLength(0);
                         sb.append(prefix); sb.append("    Proc ");
                                 sb.append(ent.getKey()); sb.append(":\n");
                         sb.append(prefix); sb.append("      CPU: ");
                                 formatTime(sb, userTime); sb.append("usr + ");
-                                formatTime(sb, systemTime); sb.append("krn");
+                                formatTime(sb, systemTime); sb.append("krn ; ");
+                                formatTime(sb, foregroundTime); sb.append("fg");
                         if (starts != 0) {
                             sb.append("\n"); sb.append(prefix); sb.append("      ");
                                     sb.append(starts); sb.append(" proc starts");
@@ -2042,7 +2117,7 @@
                                         sb.append(sent.getKey()); sb.append(":\n");
                                 sb.append(prefix); sb.append("        Created for: ");
                                         formatTimeMs(sb, startTime / 1000);
-                                        sb.append(" uptime\n");
+                                        sb.append("uptime\n");
                                 sb.append(prefix); sb.append("        Starts: ");
                                         sb.append(starts);
                                         sb.append(", launches: "); sb.append(launches);
@@ -2207,6 +2282,30 @@
             }
             oldState = rec.states;
         }
+
+        public void printNextItemCheckin(PrintWriter pw, HistoryItem rec, long now) {
+            pw.print(rec.time-now);
+            pw.print(",");
+            if (rec.cmd == HistoryItem.CMD_START) {
+                pw.print("start");
+            } else if (rec.cmd == HistoryItem.CMD_OVERFLOW) {
+                pw.print("overflow");
+            } else {
+                pw.print(rec.batteryLevel);
+                pw.print(",");
+                pw.print(rec.states);
+                pw.print(",");
+                pw.print(rec.batteryStatus);
+                pw.print(",");
+                pw.print(rec.batteryHealth);
+                pw.print(",");
+                pw.print(rec.batteryPlugType);
+                pw.print(",");
+                pw.print((int)rec.batteryTemperature);
+                pw.print(",");
+                pw.print((int)rec.batteryVoltage);
+            }
+        }
     }
 
     /**
@@ -2215,7 +2314,7 @@
      * @param pw a Printer to receive the dump output.
      */
     @SuppressWarnings("unused")
-    public void dumpLocked(PrintWriter pw) {
+    public void dumpLocked(PrintWriter pw, boolean isUnpluggedOnly, int reqUid) {
         prepareForDumpLocked();
 
         long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
@@ -2267,29 +2366,41 @@
         if (didPid) {
             pw.println("");
         }
-        
-        pw.println("Statistics since last charge:");
-        pw.println("  System starts: " + getStartCount()
-                + ", currently on battery: " + getIsOnBattery());
-        dumpLocked(pw, "", STATS_SINCE_CHARGED, -1);
-        pw.println("");
+
+        if (!isUnpluggedOnly) {
+            pw.println("Statistics since last charge:");
+            pw.println("  System starts: " + getStartCount()
+                    + ", currently on battery: " + getIsOnBattery());
+            dumpLocked(pw, "", STATS_SINCE_CHARGED, reqUid);
+            pw.println("");
+        }
         pw.println("Statistics since last unplugged:");
-        dumpLocked(pw, "", STATS_SINCE_UNPLUGGED, -1);
+        dumpLocked(pw, "", STATS_SINCE_UNPLUGGED, reqUid);
     }
     
     @SuppressWarnings("unused")
-    public void dumpCheckinLocked(PrintWriter pw, String[] args, List<ApplicationInfo> apps) {
+    public void dumpCheckinLocked(
+            PrintWriter pw, List<ApplicationInfo> apps, boolean isUnpluggedOnly,
+            boolean includeHistory) {
         prepareForDumpLocked();
-
-        boolean isUnpluggedOnly = false;
         
-        for (String arg : args) {
-            if ("-u".equals(arg)) {
-                if (LOCAL_LOGV) Log.v("BatteryStats", "Dumping unplugged data");
-                isUnpluggedOnly = true;
+        long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
+
+        if (includeHistory) {
+            final HistoryItem rec = new HistoryItem();
+            if (startIteratingHistoryLocked()) {
+                HistoryPrinter hprinter = new HistoryPrinter();
+                while (getNextHistoryLocked(rec)) {
+                    pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
+                    pw.print(0); pw.print(',');
+                    pw.print(HISTORY_DATA); pw.print(',');
+                    hprinter.printNextItemCheckin(pw, rec, now);
+                    pw.println();
+                }
+                finishIteratingHistoryLocked();
             }
         }
-        
+
         if (apps != null) {
             SparseArray<ArrayList<String>> uids = new SparseArray<ArrayList<String>>();
             for (int i=0; i<apps.size(); i++) {
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index 7ffd30b..26fc769 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -17,6 +17,7 @@
 package android.os;
 
 import android.util.Log;
+import com.android.internal.util.FastPrintWriter;
 
 import java.io.FileDescriptor;
 import java.io.FileOutputStream;
@@ -288,14 +289,28 @@
      */
     public void dump(FileDescriptor fd, String[] args) {
         FileOutputStream fout = new FileOutputStream(fd);
-        PrintWriter pw = new PrintWriter(fout);
+        PrintWriter pw = new FastPrintWriter(fout);
         try {
             final String disabled;
             synchronized (Binder.class) {
                 disabled = sDumpDisabled;
             }
             if (disabled == null) {
-                dump(fd, pw, args);
+                try {
+                    dump(fd, pw, args);
+                } catch (SecurityException e) {
+                    pw.println();
+                    pw.println("Security exception: " + e.getMessage());
+                    throw e;
+                } catch (Throwable e) {
+                    // Unlike usual calls, in this case if an exception gets thrown
+                    // back to us we want to print it back in to the dump data, since
+                    // that is where the caller expects all interesting information to
+                    // go.
+                    pw.println();
+                    pw.println("Exception occurred while dumping:");
+                    e.printStackTrace(pw);
+                }
             } else {
                 pw.println(sDumpDisabled);
             }
@@ -310,7 +325,7 @@
      */
     public void dumpAsync(final FileDescriptor fd, final String[] args) {
         final FileOutputStream fout = new FileOutputStream(fd);
-        final PrintWriter pw = new PrintWriter(fout);
+        final PrintWriter pw = new FastPrintWriter(fout);
         Thread thr = new Thread("Binder.dumpAsync") {
             public void run() {
                 try {
@@ -384,17 +399,27 @@
         // but all that does is rewind it, and we just got these from an IPC,
         // so we'll just call it directly.
         boolean res;
+        // Log any exceptions as warnings, don't silently suppress them.
+        // If the call was FLAG_ONEWAY then these exceptions disappear into the ether.
         try {
             res = onTransact(code, data, reply, flags);
         } catch (RemoteException e) {
+            if ((flags & FLAG_ONEWAY) != 0) {
+                Log.w(TAG, "Binder call failed.", e);
+            }
             reply.setDataPosition(0);
             reply.writeException(e);
             res = true;
         } catch (RuntimeException e) {
+            if ((flags & FLAG_ONEWAY) != 0) {
+                Log.w(TAG, "Caught a RuntimeException from the binder stub implementation.", e);
+            }
             reply.setDataPosition(0);
             reply.writeException(e);
             res = true;
         } catch (OutOfMemoryError e) {
+            // Unconditionally log this, since this is generally unrecoverable.
+            Log.e(TAG, "Caught an OutOfMemoryError from the binder stub implementation.", e);
             RuntimeException re = new RuntimeException("Out of memory", e);
             reply.setDataPosition(0);
             reply.writeException(re);
@@ -442,7 +467,6 @@
         data.writeStringArray(args);
         try {
             transact(DUMP_TRANSACTION, data, reply, FLAG_ONEWAY);
-            reply.readException();
         } finally {
             data.recycle();
             reply.recycle();
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 6c9f2d1..88eb280 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -436,6 +436,19 @@
          * Android 4.3: Jelly Bean MR2, the revenge of the beans.
          */
         public static final int JELLY_BEAN_MR2 = 18;
+
+        /**
+         * Android X.X: KitKat, another tasty treat.
+         *
+         * <p>Applications targeting this or a later release will get these
+         * new changes in behavior:</p>
+         * <ul>
+         * <li>It is no longer allowed to use implicit intents with
+         * {@link android.content.Context#startService} or
+         * {@link android.content.Context#bindService}.
+         * </ul>
+         */
+        public static final int KITKAT = CUR_DEVELOPMENT;
     }
     
     /** The type of build, like "user" or "eng". */
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index b8769b4..32b1b604 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -16,15 +16,13 @@
 
 package android.os;
 
+import android.util.ArrayMap;
 import android.util.Log;
 import android.util.SparseArray;
 
 import java.io.Serializable;
 import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
+import java.util.List;
 import java.util.Set;
 
 /**
@@ -37,13 +35,13 @@
 
     static {
         EMPTY = new Bundle();
-        EMPTY.mMap = Collections.unmodifiableMap(new HashMap<String, Object>());
+        EMPTY.mMap = ArrayMap.EMPTY;
     }
 
     // Invariant - exactly one of mMap / mParcelledData will be null
     // (except inside a call to unparcel)
 
-    /* package */ Map<String, Object> mMap = null;
+    /* package */ ArrayMap<String, Object> mMap = null;
 
     /*
      * If mParcelledData is non-null, then mMap will be null and the
@@ -65,7 +63,7 @@
      * Constructs a new, empty Bundle.
      */
     public Bundle() {
-        mMap = new HashMap<String, Object>();
+        mMap = new ArrayMap<String, Object>();
         mClassLoader = getClass().getClassLoader();
     }
 
@@ -91,7 +89,7 @@
      * inside of the Bundle.
      */
     public Bundle(ClassLoader loader) {
-        mMap = new HashMap<String, Object>();
+        mMap = new ArrayMap<String, Object>();
         mClassLoader = loader;
     }
 
@@ -102,7 +100,7 @@
      * @param capacity the initial capacity of the Bundle
      */
     public Bundle(int capacity) {
-        mMap = new HashMap<String, Object>(capacity);
+        mMap = new ArrayMap<String, Object>(capacity);
         mClassLoader = getClass().getClassLoader();
     }
 
@@ -122,7 +120,7 @@
         }
 
         if (b.mMap != null) {
-            mMap = new HashMap<String, Object>(b.mMap);
+            mMap = new ArrayMap<String, Object>(b.mMap);
         } else {
             mMap = null;
         }
@@ -162,7 +160,7 @@
         if (size == 0) {
             return null;
         }
-        Object o = mMap.values().iterator().next();
+        Object o = mMap.valueAt(0);
         try {
             return (String) o;
         } catch (ClassCastException e) {
@@ -218,9 +216,12 @@
             return;
         }
         if (mMap == null) {
-            mMap = new HashMap<String, Object>(N);
+            mMap = new ArrayMap<String, Object>(N);
+        } else {
+            mMap.erase();
+            mMap.ensureCapacity(N);
         }
-        mParcelledData.readMapInternal(mMap, N, mClassLoader);
+        mParcelledData.readArrayMapInternal(mMap, N, mClassLoader);
         mParcelledData.recycle();
         mParcelledData = null;
     }
@@ -331,9 +332,8 @@
                 }
             } else {
                 // It's been unparcelled, so we need to walk the map
-                Iterator<Map.Entry<String, Object>> iter = mMap.entrySet().iterator();
-                while (!fdFound && iter.hasNext()) {
-                    Object obj = iter.next().getValue();
+                for (int i=mMap.size()-1; i>=0; i--) {
+                    Object obj = mMap.valueAt(i);
                     if (obj instanceof Parcelable) {
                         if ((((Parcelable)obj).describeContents()
                                 & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) {
@@ -546,6 +546,13 @@
         mFdsKnown = false;
     }
 
+    /** {@hide} */
+    public void putParcelableList(String key, List<? extends Parcelable> value) {
+        unparcel();
+        mMap.put(key, value);
+        mFdsKnown = false;
+    }
+
     /**
      * Inserts a SparceArray of Parcelable values into the mapping of this
      * Bundle, replacing any existing value for the given key.  Either key
@@ -1643,7 +1650,7 @@
                 parcel.writeInt(0x4C444E42); // 'B' 'N' 'D' 'L'
     
                 int oldPos = parcel.dataPosition();
-                parcel.writeMapInternal(mMap);
+                parcel.writeArrayMapInternal(mMap);
                 int newPos = parcel.dataPosition();
     
                 // Backpatch length
diff --git a/core/java/android/os/CancellationSignal.java b/core/java/android/os/CancellationSignal.java
index dcba9b7..e8053d5 100644
--- a/core/java/android/os/CancellationSignal.java
+++ b/core/java/android/os/CancellationSignal.java
@@ -17,7 +17,6 @@
 package android.os;
 
 import android.os.ICancellationSignal;
-import android.os.ICancellationSignal.Stub;
 
 /**
  * Provides the ability to cancel an operation in progress.
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index fd01da9..0c718f4 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import com.android.internal.util.FastPrintWriter;
 import com.android.internal.util.TypedProperties;
 
 import android.util.Log;
@@ -108,31 +109,78 @@
      * process. The returns info broken down by dalvik, native, and other. All results are in kB.
      */
     public static class MemoryInfo implements Parcelable {
-        /** The proportional set size for dalvik. */
+        /** The proportional set size for dalvik heap.  (Doesn't include other Dalvik overhead.) */
         public int dalvikPss;
-        /** The private dirty pages used by dalvik. */
+        /** The proportional set size that is swappable for dalvik heap. */
+        /** @hide We may want to expose this, eventually. */
+        public int dalvikSwappablePss;
+        /** The private dirty pages used by dalvik heap. */
         public int dalvikPrivateDirty;
-        /** The shared dirty pages used by dalvik. */
+        /** The shared dirty pages used by dalvik heap. */
         public int dalvikSharedDirty;
+        /** The private clean pages used by dalvik heap. */
+        /** @hide We may want to expose this, eventually. */
+        public int dalvikPrivateClean;
+        /** The shared clean pages used by dalvik heap. */
+        /** @hide We may want to expose this, eventually. */
+        public int dalvikSharedClean;
 
         /** The proportional set size for the native heap. */
         public int nativePss;
+        /** The proportional set size that is swappable for the native heap. */
+        /** @hide We may want to expose this, eventually. */
+        public int nativeSwappablePss;
         /** The private dirty pages used by the native heap. */
         public int nativePrivateDirty;
         /** The shared dirty pages used by the native heap. */
         public int nativeSharedDirty;
+        /** The private clean pages used by the native heap. */
+        /** @hide We may want to expose this, eventually. */
+        public int nativePrivateClean;
+        /** The shared clean pages used by the native heap. */
+        /** @hide We may want to expose this, eventually. */
+        public int nativeSharedClean;
 
         /** The proportional set size for everything else. */
         public int otherPss;
+        /** The proportional set size that is swappable for everything else. */
+        /** @hide We may want to expose this, eventually. */
+        public int otherSwappablePss;
         /** The private dirty pages used by everything else. */
         public int otherPrivateDirty;
         /** The shared dirty pages used by everything else. */
         public int otherSharedDirty;
+        /** The private clean pages used by everything else. */
+        /** @hide We may want to expose this, eventually. */
+        public int otherPrivateClean;
+        /** The shared clean pages used by everything else. */
+        /** @hide We may want to expose this, eventually. */
+        public int otherSharedClean;
 
         /** @hide */
-        public static final int NUM_OTHER_STATS = 10;
+        public static final int NUM_OTHER_STATS = 14;
 
-        private int[] otherStats = new int[NUM_OTHER_STATS*3];
+        /** @hide */
+        public static final int NUM_DVK_STATS = 5;
+
+        /** @hide */
+        public static final int NUM_CATEGORIES = 6;
+
+        /** @hide */
+        public static final int offsetPss = 0;
+        /** @hide */
+        public static final int offsetSwappablePss = 1;
+        /** @hide */
+        public static final int offsetPrivateDirty = 2;
+        /** @hide */
+        public static final int offsetSharedDirty = 3;
+        /** @hide */
+        public static final int offsetPrivateClean = 4;
+        /** @hide */
+        public static final int offsetSharedClean = 5;
+
+
+        private int[] otherStats = new int[(NUM_OTHER_STATS+NUM_DVK_STATS)*NUM_CATEGORIES];
 
         public MemoryInfo() {
         }
@@ -145,6 +193,22 @@
         }
 
         /**
+         * @hide Return total PSS memory usage in kB.
+         */
+        public int getTotalUss() {
+            return dalvikPrivateClean + dalvikPrivateDirty
+                    + nativePrivateClean + nativePrivateDirty
+                    + otherPrivateClean + otherPrivateDirty;
+        }
+
+        /**
+         * Return total PSS memory usage in kB.
+         */
+        public int getTotalSwappablePss() {
+            return dalvikSwappablePss + nativeSwappablePss + otherSwappablePss;
+        }
+
+        /**
          * Return total private dirty memory usage in kB.
          */
         public int getTotalPrivateDirty() {
@@ -158,35 +222,75 @@
             return dalvikSharedDirty + nativeSharedDirty + otherSharedDirty;
         }
 
-        /* @hide */
+        /**
+         * Return total shared clean memory usage in kB.
+         */
+        public int getTotalPrivateClean() {
+            return dalvikPrivateClean + nativePrivateClean + otherPrivateClean;
+        }
+
+        /**
+         * Return total shared clean memory usage in kB.
+         */
+        public int getTotalSharedClean() {
+            return dalvikSharedClean + nativeSharedClean + otherSharedClean;
+        }
+
+        /** @hide */
         public int getOtherPss(int which) {
-            return otherStats[which*3];
+            return otherStats[which*NUM_CATEGORIES + offsetPss];
         }
 
-        /* @hide */
+
+        /** @hide */
+        public int getOtherSwappablePss(int which) {
+            return otherStats[which*NUM_CATEGORIES + offsetSwappablePss];
+        }
+
+
+        /** @hide */
         public int getOtherPrivateDirty(int which) {
-            return otherStats[which*3 + 1];
+            return otherStats[which*NUM_CATEGORIES + offsetPrivateDirty];
         }
 
-        /* @hide */
+        /** @hide */
         public int getOtherSharedDirty(int which) {
-            return otherStats[which*3 + 2];
+            return otherStats[which*NUM_CATEGORIES + offsetSharedDirty];
+        }
+
+        /** @hide */
+        public int getOtherPrivateClean(int which) {
+            return otherStats[which*NUM_CATEGORIES + offsetPrivateClean];
         }
 
 
-        /* @hide */
+        /** @hide */
+        public int getOtherSharedClean(int which) {
+            return otherStats[which*NUM_CATEGORIES + offsetSharedClean];
+        }
+
+        /** @hide */
         public static String getOtherLabel(int which) {
             switch (which) {
-                case 0: return "Stack";
-                case 1: return "Cursor";
-                case 2: return "Ashmem";
-                case 3: return "Other dev";
-                case 4: return ".so mmap";
-                case 5: return ".jar mmap";
-                case 6: return ".apk mmap";
-                case 7: return ".ttf mmap";
-                case 8: return ".dex mmap";
-                case 9: return "Other mmap";
+                case 0: return "Dalvik Other";
+                case 1: return "Stack";
+                case 2: return "Cursor";
+                case 3: return "Ashmem";
+                case 4: return "Other dev";
+                case 5: return ".so mmap";
+                case 6: return ".jar mmap";
+                case 7: return ".apk mmap";
+                case 8: return ".ttf mmap";
+                case 9: return ".dex mmap";
+                case 10: return "code mmap";
+                case 11: return "image mmap";
+                case 12: return "Other mmap";
+                case 13: return "GPU";
+                case 14: return ".Heap";
+                case 15: return ".LOS";
+                case 16: return ".LinearAlloc";
+                case 17: return ".GC";
+                case 18: return ".JITCache";
                 default: return "????";
             }
         }
@@ -197,27 +301,45 @@
 
         public void writeToParcel(Parcel dest, int flags) {
             dest.writeInt(dalvikPss);
+            dest.writeInt(dalvikSwappablePss);
             dest.writeInt(dalvikPrivateDirty);
             dest.writeInt(dalvikSharedDirty);
+            dest.writeInt(dalvikPrivateClean);
+            dest.writeInt(dalvikSharedClean);
             dest.writeInt(nativePss);
+            dest.writeInt(nativeSwappablePss);
             dest.writeInt(nativePrivateDirty);
             dest.writeInt(nativeSharedDirty);
+            dest.writeInt(nativePrivateClean);
+            dest.writeInt(nativeSharedClean);
             dest.writeInt(otherPss);
+            dest.writeInt(otherSwappablePss);
             dest.writeInt(otherPrivateDirty);
             dest.writeInt(otherSharedDirty);
+            dest.writeInt(otherPrivateClean);
+            dest.writeInt(otherSharedClean);
             dest.writeIntArray(otherStats);
         }
 
         public void readFromParcel(Parcel source) {
             dalvikPss = source.readInt();
+            dalvikSwappablePss = source.readInt();
             dalvikPrivateDirty = source.readInt();
             dalvikSharedDirty = source.readInt();
+            dalvikPrivateClean = source.readInt();
+            dalvikSharedClean = source.readInt();
             nativePss = source.readInt();
+            nativeSwappablePss = source.readInt();
             nativePrivateDirty = source.readInt();
             nativeSharedDirty = source.readInt();
+            nativePrivateClean = source.readInt();
+            nativeSharedClean = source.readInt();
             otherPss = source.readInt();
+            otherSwappablePss = source.readInt();
             otherPrivateDirty = source.readInt();
             otherSharedDirty = source.readInt();
+            otherPrivateClean = source.readInt();
+            otherSharedClean = source.readInt();
             otherStats = source.createIntArray();
         }
 
@@ -364,7 +486,7 @@
         PrintWriter outStream = null;
         try {
             FileOutputStream fos = new FileOutputStream(SYSFS_QEMU_TRACE_STATE);
-            outStream = new PrintWriter(new OutputStreamWriter(fos));
+            outStream = new FastPrintWriter(fos);
             outStream.println("1");
         } catch (Exception e) {
         } finally {
@@ -392,7 +514,7 @@
         PrintWriter outStream = null;
         try {
             FileOutputStream fos = new FileOutputStream(SYSFS_QEMU_TRACE_STATE);
-            outStream = new PrintWriter(new OutputStreamWriter(fos));
+            outStream = new FastPrintWriter(fos);
             outStream.println("0");
         } catch (Exception e) {
             // We could print an error message here but we probably want
@@ -518,16 +640,19 @@
      *
      * @hide
      */
-    public static void startMethodTracingDdms(int bufferSize, int flags) {
-        VMDebug.startMethodTracingDdms(bufferSize, flags);
+    public static void startMethodTracingDdms(int bufferSize, int flags,
+        boolean samplingEnabled, int intervalUs) {
+        VMDebug.startMethodTracingDdms(bufferSize, flags, samplingEnabled, intervalUs);
     }
 
     /**
-     * Determine whether method tracing is currently active.
+     * Determine whether method tracing is currently active and what type is
+     * active.
+     *
      * @hide
      */
-    public static boolean isMethodTracingActive() {
-        return VMDebug.isMethodTracingActive();
+    public static int getMethodTracingMode() {
+        return VMDebug.getMethodTracingMode();
     }
 
     /**
@@ -608,7 +733,7 @@
 
     /**
      * Clears the global size of objects allocated.
-     * @see #getGlobalAllocCountSize()
+     * @see #getGlobalAllocSize()
      */
     public static void resetGlobalAllocSize() {
         VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_BYTES);
@@ -888,9 +1013,32 @@
 
     /**
      * Retrieves the PSS memory used by the process as given by the
-     * smaps. @hide
+     * smaps.  Optionally supply a long array of 1 entry to also
+     * receive the uss of the process.  @hide
      */
-    public static native long getPss(int pid);
+    public static native long getPss(int pid, long[] outUss);
+
+    /** @hide */
+    public static final int MEMINFO_TOTAL = 0;
+    /** @hide */
+    public static final int MEMINFO_FREE = 1;
+    /** @hide */
+    public static final int MEMINFO_BUFFERS = 2;
+    /** @hide */
+    public static final int MEMINFO_CACHED = 3;
+    /** @hide */
+    public static final int MEMINFO_SHMEM = 4;
+    /** @hide */
+    public static final int MEMINFO_SLAB = 5;
+    /** @hide */
+    public static final int MEMINFO_COUNT = 6;
+
+    /**
+     * Retrieves /proc/meminfo.  outSizes is filled with fields
+     * as defined by MEMINFO_* offsets.
+     * @hide
+     */
+    public static native void getMemInfo(long[] outSizes);
 
     /**
      * Establish an object allocation limit in the current thread.
@@ -1397,7 +1545,7 @@
 
     /**
      * Return a String describing the calling method and location at a particular stack depth.
-     * @param callStack the Thread stack 
+     * @param callStack the Thread stack
      * @param depth the depth of stack to return information for.
      * @return the String describing the caller at that depth.
      */
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 61eef1f..5b36bca 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.content.Context;
 import android.os.storage.IMountService;
 import android.os.storage.StorageManager;
 import android.os.storage.StorageVolume;
@@ -40,7 +41,16 @@
     private static final String ENV_ANDROID_ROOT = "ANDROID_ROOT";
 
     /** {@hide} */
-    public static String DIRECTORY_ANDROID = "Android";
+    public static final String DIR_ANDROID = "Android";
+    private static final String DIR_DATA = "data";
+    private static final String DIR_MEDIA = "media";
+    private static final String DIR_OBB = "obb";
+    private static final String DIR_FILES = "files";
+    private static final String DIR_CACHE = "cache";
+
+    /** {@hide} */
+    @Deprecated
+    public static final String DIRECTORY_ANDROID = DIR_ANDROID;
 
     private static final File DIR_ANDROID_ROOT = getDirectory(ENV_ANDROID_ROOT, "/system");
     private static final File DIR_MEDIA_STORAGE = getDirectory(ENV_MEDIA_STORAGE, "/data/media");
@@ -59,6 +69,10 @@
     private static volatile StorageVolume sPrimaryVolume;
 
     private static StorageVolume getPrimaryVolume() {
+        if (SystemProperties.getBoolean("config.disable_storage", false)) {
+            return null;
+        }
+
         if (sPrimaryVolume == null) {
             synchronized (sLock) {
                 if (sPrimaryVolume == null) {
@@ -93,12 +107,10 @@
     /** {@hide} */
     public static class UserEnvironment {
         // TODO: generalize further to create package-specific environment
+        // TODO: add support for secondary external storage
 
-        private final File mExternalStorage;
-        private final File mExternalStorageAndroidData;
-        private final File mExternalStorageAndroidMedia;
-        private final File mExternalStorageAndroidObb;
-        private final File mMediaStorage;
+        private final File[] mExternalDirs;
+        private final File mMediaDir;
 
         public UserEnvironment(int userId) {
             // See storage config details at http://source.android.com/tech/storage/
@@ -117,9 +129,9 @@
                 final File mediaBase = new File(rawMediaStorage);
 
                 // /storage/emulated/0
-                mExternalStorage = buildPath(emulatedBase, rawUserId);
+                mExternalDirs = new File[] { buildPath(emulatedBase, rawUserId) };
                 // /data/media/0
-                mMediaStorage = buildPath(mediaBase, rawUserId);
+                mMediaDir = buildPath(mediaBase, rawUserId);
 
             } else {
                 // Device has physical external storage; use plain paths.
@@ -129,54 +141,60 @@
                 }
 
                 // /storage/sdcard0
-                mExternalStorage = new File(rawExternalStorage);
+                mExternalDirs = new File[] { new File(rawExternalStorage) };
                 // /data/media
-                mMediaStorage = new File(rawMediaStorage);
+                mMediaDir = new File(rawMediaStorage);
             }
-
-            mExternalStorageAndroidObb = buildPath(mExternalStorage, DIRECTORY_ANDROID, "obb");
-            mExternalStorageAndroidData = buildPath(mExternalStorage, DIRECTORY_ANDROID, "data");
-            mExternalStorageAndroidMedia = buildPath(mExternalStorage, DIRECTORY_ANDROID, "media");
         }
 
+        @Deprecated
         public File getExternalStorageDirectory() {
-            return mExternalStorage;
+            return mExternalDirs[0];
         }
 
-        public File getExternalStorageObbDirectory() {
-            return mExternalStorageAndroidObb;
-        }
-
+        @Deprecated
         public File getExternalStoragePublicDirectory(String type) {
-            return new File(mExternalStorage, type);
+            return buildExternalStoragePublicDirs(type)[0];
         }
 
-        public File getExternalStorageAndroidDataDir() {
-            return mExternalStorageAndroidData;
+        public File[] getExternalDirs() {
+            return mExternalDirs;
         }
 
-        public File getExternalStorageAppDataDirectory(String packageName) {
-            return new File(mExternalStorageAndroidData, packageName);
+        public File getMediaDir() {
+            return mMediaDir;
         }
 
-        public File getExternalStorageAppMediaDirectory(String packageName) {
-            return new File(mExternalStorageAndroidMedia, packageName);
+        public File[] buildExternalStoragePublicDirs(String type) {
+            return buildPaths(mExternalDirs, type);
         }
 
-        public File getExternalStorageAppObbDirectory(String packageName) {
-            return new File(mExternalStorageAndroidObb, packageName);
+        public File[] buildExternalStorageAndroidDataDirs() {
+            return buildPaths(mExternalDirs, DIR_ANDROID, DIR_DATA);
         }
 
-        public File getExternalStorageAppFilesDirectory(String packageName) {
-            return new File(new File(mExternalStorageAndroidData, packageName), "files");
+        public File[] buildExternalStorageAndroidObbDirs() {
+            return buildPaths(mExternalDirs, DIR_ANDROID, DIR_OBB);
         }
 
-        public File getExternalStorageAppCacheDirectory(String packageName) {
-            return new File(new File(mExternalStorageAndroidData, packageName), "cache");
+        public File[] buildExternalStorageAppDataDirs(String packageName) {
+            return buildPaths(mExternalDirs, DIR_ANDROID, DIR_DATA, packageName);
         }
 
-        public File getMediaStorageDirectory() {
-            return mMediaStorage;
+        public File[] buildExternalStorageAppMediaDirs(String packageName) {
+            return buildPaths(mExternalDirs, DIR_ANDROID, DIR_MEDIA, packageName);
+        }
+
+        public File[] buildExternalStorageAppObbDirs(String packageName) {
+            return buildPaths(mExternalDirs, DIR_ANDROID, DIR_OBB, packageName);
+        }
+
+        public File[] buildExternalStorageAppFilesDirs(String packageName) {
+            return buildPaths(mExternalDirs, DIR_ANDROID, DIR_DATA, packageName, DIR_FILES);
+        }
+
+        public File[] buildExternalStorageAppCacheDirs(String packageName) {
+            return buildPaths(mExternalDirs, DIR_ANDROID, DIR_DATA, packageName, DIR_CACHE);
         }
     }
 
@@ -225,7 +243,7 @@
      */
     public static File getMediaStorageDirectory() {
         throwIfUserRequired();
-        return sCurrentUser.getMediaStorageDirectory();
+        return sCurrentUser.getMediaDir();
     }
 
     /**
@@ -261,58 +279,64 @@
     private static final File DOWNLOAD_CACHE_DIRECTORY = getDirectory("DOWNLOAD_CACHE", "/cache");
 
     /**
-     * Gets the Android data directory.
+     * Return the user data directory.
      */
     public static File getDataDirectory() {
         return DATA_DIRECTORY;
     }
 
     /**
-     * Gets the Android external storage directory.  This directory may not
+     * Return the primary external storage directory. This directory may not
      * currently be accessible if it has been mounted by the user on their
      * computer, has been removed from the device, or some other problem has
-     * happened.  You can determine its current state with
+     * happened. You can determine its current state with
      * {@link #getExternalStorageState()}.
-     * 
-     * <p><em>Note: don't be confused by the word "external" here.  This
-     * directory can better be thought as media/shared storage.  It is a
-     * filesystem that can hold a relatively large amount of data and that
-     * is shared across all applications (does not enforce permissions).
-     * Traditionally this is an SD card, but it may also be implemented as
-     * built-in storage in a device that is distinct from the protected
-     * internal storage and can be mounted as a filesystem on a computer.</em></p>
-     *
-     * <p>On devices with multiple users (as described by {@link UserManager}),
-     * each user has their own isolated external storage. Applications only
-     * have access to the external storage for the user they're running as.</p>
-     *
-     * <p>In devices with multiple "external" storage directories (such as
-     * both secure app storage and mountable shared storage), this directory
+     * <p>
+     * <em>Note: don't be confused by the word "external" here. This directory
+     * can better be thought as media/shared storage. It is a filesystem that
+     * can hold a relatively large amount of data and that is shared across all
+     * applications (does not enforce permissions). Traditionally this is an SD
+     * card, but it may also be implemented as built-in storage in a device that
+     * is distinct from the protected internal storage and can be mounted as a
+     * filesystem on a computer.</em>
+     * <p>
+     * On devices with multiple users (as described by {@link UserManager}),
+     * each user has their own isolated external storage. Applications only have
+     * access to the external storage for the user they're running as.
+     * <p>
+     * In devices with multiple "external" storage directories, this directory
      * represents the "primary" external storage that the user will interact
-     * with.</p>
-     *
-     * <p>Applications should not directly use this top-level directory, in
-     * order to avoid polluting the user's root namespace.  Any files that are
-     * private to the application should be placed in a directory returned
-     * by {@link android.content.Context#getExternalFilesDir
+     * with. Access to secondary storage is available through
+     * <p>
+     * Applications should not directly use this top-level directory, in order
+     * to avoid polluting the user's root namespace. Any files that are private
+     * to the application should be placed in a directory returned by
+     * {@link android.content.Context#getExternalFilesDir
      * Context.getExternalFilesDir}, which the system will take care of deleting
-     * if the application is uninstalled.  Other shared files should be placed
-     * in one of the directories returned by
-     * {@link #getExternalStoragePublicDirectory}.</p>
-     *
-     * <p>Writing to this path requires the
-     * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} permission. In
-     * a future platform release, access to this path will require the
+     * if the application is uninstalled. Other shared files should be placed in
+     * one of the directories returned by
+     * {@link #getExternalStoragePublicDirectory}.
+     * <p>
+     * Writing to this path requires the
+     * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} permission,
+     * and starting in read access requires the
      * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission,
-     * which is automatically granted if you hold the write permission.</p>
-     *
-     * <p>This path may change between platform versions, so applications
-     * should only persist relative paths.</p>
-     * 
-     * <p>Here is an example of typical code to monitor the state of
-     * external storage:</p>
-     * 
-     * {@sample development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java
+     * which is automatically granted if you hold the write permission.
+     * <p>
+     * Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, if your
+     * application only needs to store internal data, consider using
+     * {@link Context#getExternalFilesDir(String)} or
+     * {@link Context#getExternalCacheDir()}, which require no permissions to
+     * read or write.
+     * <p>
+     * This path may change between platform versions, so applications should
+     * only persist relative paths.
+     * <p>
+     * Here is an example of typical code to monitor the state of external
+     * storage:
+     * <p>
+     * {@sample
+     * development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java
      * monitor_storage}
      *
      * @see #getExternalStorageState()
@@ -320,7 +344,7 @@
      */
     public static File getExternalStorageDirectory() {
         throwIfUserRequired();
-        return sCurrentUser.getExternalStorageDirectory();
+        return sCurrentUser.getExternalDirs()[0];
     }
 
     /** {@hide} */
@@ -330,7 +354,7 @@
 
     /** {@hide} */
     public static File getLegacyExternalStorageObbDirectory() {
-        return buildPath(getLegacyExternalStorageDirectory(), DIRECTORY_ANDROID, "obb");
+        return buildPath(getLegacyExternalStorageDirectory(), DIR_ANDROID, DIR_OBB);
     }
 
     /** {@hide} */
@@ -342,7 +366,7 @@
     /** {@hide} */
     public static File getEmulatedStorageObbSource() {
         // /mnt/shell/emulated/obb
-        return new File(System.getenv(ENV_EMULATED_STORAGE_SOURCE), "obb");
+        return new File(System.getenv(ENV_EMULATED_STORAGE_SOURCE), DIR_OBB);
     }
 
     /**
@@ -436,7 +460,13 @@
      * top-level public directory, as this convention makes no sense elsewhere.
      */
     public static String DIRECTORY_DCIM = "DCIM";
-    
+
+    /**
+     * Standard directory in which to place documents that have been created by
+     * the user.
+     */
+    public static String DIRECTORY_DOCUMENTS = "Documents";
+
     /**
      * Get a top-level public external storage directory for placing files of
      * a particular type.  This is where the user will typically place and
@@ -467,139 +497,192 @@
      */
     public static File getExternalStoragePublicDirectory(String type) {
         throwIfUserRequired();
-        return sCurrentUser.getExternalStoragePublicDirectory(type);
+        return sCurrentUser.buildExternalStoragePublicDirs(type)[0];
     }
 
     /**
      * Returns the path for android-specific data on the SD card.
      * @hide
      */
-    public static File getExternalStorageAndroidDataDir() {
+    public static File[] buildExternalStorageAndroidDataDirs() {
         throwIfUserRequired();
-        return sCurrentUser.getExternalStorageAndroidDataDir();
+        return sCurrentUser.buildExternalStorageAndroidDataDirs();
     }
-    
+
     /**
      * Generates the raw path to an application's data
      * @hide
      */
-    public static File getExternalStorageAppDataDirectory(String packageName) {
+    public static File[] buildExternalStorageAppDataDirs(String packageName) {
         throwIfUserRequired();
-        return sCurrentUser.getExternalStorageAppDataDirectory(packageName);
+        return sCurrentUser.buildExternalStorageAppDataDirs(packageName);
     }
     
     /**
      * Generates the raw path to an application's media
      * @hide
      */
-    public static File getExternalStorageAppMediaDirectory(String packageName) {
+    public static File[] buildExternalStorageAppMediaDirs(String packageName) {
         throwIfUserRequired();
-        return sCurrentUser.getExternalStorageAppMediaDirectory(packageName);
+        return sCurrentUser.buildExternalStorageAppMediaDirs(packageName);
     }
     
     /**
      * Generates the raw path to an application's OBB files
      * @hide
      */
-    public static File getExternalStorageAppObbDirectory(String packageName) {
+    public static File[] buildExternalStorageAppObbDirs(String packageName) {
         throwIfUserRequired();
-        return sCurrentUser.getExternalStorageAppObbDirectory(packageName);
+        return sCurrentUser.buildExternalStorageAppObbDirs(packageName);
     }
     
     /**
      * Generates the path to an application's files.
      * @hide
      */
-    public static File getExternalStorageAppFilesDirectory(String packageName) {
+    public static File[] buildExternalStorageAppFilesDirs(String packageName) {
         throwIfUserRequired();
-        return sCurrentUser.getExternalStorageAppFilesDirectory(packageName);
+        return sCurrentUser.buildExternalStorageAppFilesDirs(packageName);
     }
 
     /**
      * Generates the path to an application's cache.
      * @hide
      */
-    public static File getExternalStorageAppCacheDirectory(String packageName) {
+    public static File[] buildExternalStorageAppCacheDirs(String packageName) {
         throwIfUserRequired();
-        return sCurrentUser.getExternalStorageAppCacheDirectory(packageName);
+        return sCurrentUser.buildExternalStorageAppCacheDirs(packageName);
     }
     
     /**
-     * Gets the Android download/cache content directory.
+     * Return the download/cache content directory.
      */
     public static File getDownloadCacheDirectory() {
         return DOWNLOAD_CACHE_DIRECTORY;
     }
 
     /**
-     * {@link #getExternalStorageState()} returns MEDIA_REMOVED if the media is not present.
+     * Unknown storage state, such as when a path isn't backed by known storage
+     * media.
+     *
+     * @see #getStorageState(File)
+     */
+    public static final String MEDIA_UNKNOWN = "unknown";
+
+    /**
+     * Storage state if the media is not present.
+     *
+     * @see #getStorageState(File)
      */
     public static final String MEDIA_REMOVED = "removed";
-     
+
     /**
-     * {@link #getExternalStorageState()} returns MEDIA_UNMOUNTED if the media is present
-     * but not mounted. 
+     * Storage state if the media is present but not mounted.
+     *
+     * @see #getStorageState(File)
      */
     public static final String MEDIA_UNMOUNTED = "unmounted";
 
     /**
-     * {@link #getExternalStorageState()} returns MEDIA_CHECKING if the media is present
-     * and being disk-checked
+     * Storage state if the media is present and being disk-checked.
+     *
+     * @see #getStorageState(File)
      */
     public static final String MEDIA_CHECKING = "checking";
 
     /**
-     * {@link #getExternalStorageState()} returns MEDIA_NOFS if the media is present
-     * but is blank or is using an unsupported filesystem
+     * Storage state if the media is present but is blank or is using an
+     * unsupported filesystem.
+     *
+     * @see #getStorageState(File)
      */
     public static final String MEDIA_NOFS = "nofs";
 
     /**
-     * {@link #getExternalStorageState()} returns MEDIA_MOUNTED if the media is present
-     * and mounted at its mount point with read/write access. 
+     * Storage state if the media is present and mounted at its mount point with
+     * read/write access.
+     *
+     * @see #getStorageState(File)
      */
     public static final String MEDIA_MOUNTED = "mounted";
 
     /**
-     * {@link #getExternalStorageState()} returns MEDIA_MOUNTED_READ_ONLY if the media is present
-     * and mounted at its mount point with read only access. 
+     * Storage state if the media is present and mounted at its mount point with
+     * read-only access.
+     *
+     * @see #getStorageState(File)
      */
     public static final String MEDIA_MOUNTED_READ_ONLY = "mounted_ro";
 
     /**
-     * {@link #getExternalStorageState()} returns MEDIA_SHARED if the media is present
-     * not mounted, and shared via USB mass storage. 
+     * Storage state if the media is present not mounted, and shared via USB
+     * mass storage.
+     *
+     * @see #getStorageState(File)
      */
     public static final String MEDIA_SHARED = "shared";
 
     /**
-     * {@link #getExternalStorageState()} returns MEDIA_BAD_REMOVAL if the media was
-     * removed before it was unmounted. 
+     * Storage state if the media was removed before it was unmounted.
+     *
+     * @see #getStorageState(File)
      */
     public static final String MEDIA_BAD_REMOVAL = "bad_removal";
 
     /**
-     * {@link #getExternalStorageState()} returns MEDIA_UNMOUNTABLE if the media is present
-     * but cannot be mounted.  Typically this happens if the file system on the
-     * media is corrupted. 
+     * Storage state if the media is present but cannot be mounted. Typically
+     * this happens if the file system on the media is corrupted.
+     *
+     * @see #getStorageState(File)
      */
     public static final String MEDIA_UNMOUNTABLE = "unmountable";
 
     /**
-     * Gets the current state of the primary "external" storage device.
+     * Returns the current state of the primary "external" storage device.
      * 
      * @see #getExternalStorageDirectory()
+     * @return one of {@link #MEDIA_UNKNOWN}, {@link #MEDIA_REMOVED},
+     *         {@link #MEDIA_UNMOUNTED}, {@link #MEDIA_CHECKING},
+     *         {@link #MEDIA_NOFS}, {@link #MEDIA_MOUNTED},
+     *         {@link #MEDIA_MOUNTED_READ_ONLY}, {@link #MEDIA_SHARED},
+     *         {@link #MEDIA_BAD_REMOVAL}, or {@link #MEDIA_UNMOUNTABLE}.
      */
     public static String getExternalStorageState() {
+        return getStorageState(getExternalStorageDirectory());
+    }
+
+    /**
+     * Returns the current state of the storage device that provides the given
+     * path.
+     *
+     * @return one of {@link #MEDIA_UNKNOWN}, {@link #MEDIA_REMOVED},
+     *         {@link #MEDIA_UNMOUNTED}, {@link #MEDIA_CHECKING},
+     *         {@link #MEDIA_NOFS}, {@link #MEDIA_MOUNTED},
+     *         {@link #MEDIA_MOUNTED_READ_ONLY}, {@link #MEDIA_SHARED},
+     *         {@link #MEDIA_BAD_REMOVAL}, or {@link #MEDIA_UNMOUNTABLE}.
+     */
+    public static String getStorageState(File path) {
+        final String rawPath;
         try {
-            IMountService mountService = IMountService.Stub.asInterface(ServiceManager
-                    .getService("mount"));
-            final StorageVolume primary = getPrimaryVolume();
-            return mountService.getVolumeState(primary.getPath());
-        } catch (RemoteException rex) {
-            Log.w(TAG, "Failed to read external storage state; assuming REMOVED: " + rex);
-            return Environment.MEDIA_REMOVED;
+            rawPath = path.getCanonicalPath();
+        } catch (IOException e) {
+            Log.w(TAG, "Failed to resolve target path: " + e);
+            return Environment.MEDIA_UNKNOWN;
         }
+
+        try {
+            final IMountService mountService = IMountService.Stub.asInterface(
+                    ServiceManager.getService("mount"));
+            final StorageVolume[] volumes = mountService.getVolumeList();
+            for (StorageVolume volume : volumes) {
+                if (rawPath.startsWith(volume.getPath())) {
+                    return mountService.getVolumeState(volume.getPath());
+                }
+            }
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed to find external storage state: " + e);
+        }
+        return Environment.MEDIA_UNKNOWN;
     }
 
     /**
@@ -663,7 +746,25 @@
         }
     }
 
-    private static File buildPath(File base, String... segments) {
+    /**
+     * Append path segments to each given base path, returning result.
+     *
+     * @hide
+     */
+    public static File[] buildPaths(File[] base, String... segments) {
+        File[] result = new File[base.length];
+        for (int i = 0; i < base.length; i++) {
+            result[i] = buildPath(base[i], segments);
+        }
+        return result;
+    }
+
+    /**
+     * Append path segments to given base path, returning result.
+     *
+     * @hide
+     */
+    public static File buildPath(File base, String... segments) {
         File cur = base;
         for (String segment : segments) {
             if (cur == null) {
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index 9666d9a..4d48fd4 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -17,10 +17,17 @@
 package android.os;
 
 import android.util.Log;
+import android.util.Slog;
+
+import libcore.io.ErrnoException;
+import libcore.io.IoUtils;
+import libcore.io.Libcore;
+import libcore.io.OsConstants;
 
 import java.io.BufferedInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
+import java.io.FileDescriptor;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
@@ -58,7 +65,84 @@
     /** Regular expression for safe filenames: no spaces or metacharacters */
     private static final Pattern SAFE_FILENAME_PATTERN = Pattern.compile("[\\w%+,./=_-]+");
 
-    public static native int setPermissions(String file, int mode, int uid, int gid);
+    /**
+     * Set owner and mode of of given {@link File}.
+     *
+     * @param mode to apply through {@code chmod}
+     * @param uid to apply through {@code chown}, or -1 to leave unchanged
+     * @param gid to apply through {@code chown}, or -1 to leave unchanged
+     * @return 0 on success, otherwise errno.
+     */
+    public static int setPermissions(File path, int mode, int uid, int gid) {
+        return setPermissions(path.getAbsolutePath(), mode, uid, gid);
+    }
+
+    /**
+     * Set owner and mode of of given path.
+     *
+     * @param mode to apply through {@code chmod}
+     * @param uid to apply through {@code chown}, or -1 to leave unchanged
+     * @param gid to apply through {@code chown}, or -1 to leave unchanged
+     * @return 0 on success, otherwise errno.
+     */
+    public static int setPermissions(String path, int mode, int uid, int gid) {
+        try {
+            Libcore.os.chmod(path, mode);
+        } catch (ErrnoException e) {
+            Slog.w(TAG, "Failed to chmod(" + path + "): " + e);
+            return e.errno;
+        }
+
+        if (uid >= 0 || gid >= 0) {
+            try {
+                Libcore.os.chown(path, uid, gid);
+            } catch (ErrnoException e) {
+                Slog.w(TAG, "Failed to chown(" + path + "): " + e);
+                return e.errno;
+            }
+        }
+
+        return 0;
+    }
+
+    /**
+     * Set owner and mode of of given {@link FileDescriptor}.
+     *
+     * @param mode to apply through {@code chmod}
+     * @param uid to apply through {@code chown}, or -1 to leave unchanged
+     * @param gid to apply through {@code chown}, or -1 to leave unchanged
+     * @return 0 on success, otherwise errno.
+     */
+    public static int setPermissions(FileDescriptor fd, int mode, int uid, int gid) {
+        try {
+            Libcore.os.fchmod(fd, mode);
+        } catch (ErrnoException e) {
+            Slog.w(TAG, "Failed to fchmod(): " + e);
+            return e.errno;
+        }
+
+        if (uid >= 0 || gid >= 0) {
+            try {
+                Libcore.os.fchown(fd, uid, gid);
+            } catch (ErrnoException e) {
+                Slog.w(TAG, "Failed to fchown(): " + e);
+                return e.errno;
+            }
+        }
+
+        return 0;
+    }
+
+    /**
+     * Return owning UID of given path, otherwise -1.
+     */
+    public static int getUid(String path) {
+        try {
+            return Libcore.os.stat(path).st_uid;
+        } catch (ErrnoException e) {
+            return -1;
+        }
+    }
 
     /** returns the FAT file system volume ID for the volume mounted 
      * at the given mount point, or -1 for failure
diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java
index 14d8f07..e6886c4 100644
--- a/core/java/android/os/Handler.java
+++ b/core/java/android/os/Handler.java
@@ -73,6 +73,9 @@
     /**
      * Callback interface you can use when instantiating a Handler to avoid
      * having to implement your own subclass of Handler.
+     *
+     * @param msg A {@link android.os.Message Message} object
+     * @return True if no further handling is desired
      */
     public interface Callback {
         public boolean handleMessage(Message msg);
diff --git a/core/java/android/os/IBatteryPropertiesListener.aidl b/core/java/android/os/IBatteryPropertiesListener.aidl
new file mode 100644
index 0000000..7e23924
--- /dev/null
+++ b/core/java/android/os/IBatteryPropertiesListener.aidl
@@ -0,0 +1,27 @@
+/*
+** Copyright 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.os;
+
+import android.os.BatteryProperties;
+
+/**
+ * {@hide}
+ */
+
+oneway interface IBatteryPropertiesListener {
+    void batteryPropertiesChanged(in BatteryProperties props);
+}
diff --git a/core/java/android/os/IBatteryPropertiesRegistrar.aidl b/core/java/android/os/IBatteryPropertiesRegistrar.aidl
new file mode 100644
index 0000000..376f6c9
--- /dev/null
+++ b/core/java/android/os/IBatteryPropertiesRegistrar.aidl
@@ -0,0 +1,28 @@
+/*
+** Copyright 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.os;
+
+import android.os.IBatteryPropertiesListener;
+
+/**
+ * {@hide}
+ */
+
+interface IBatteryPropertiesRegistrar {
+    void registerListener(IBatteryPropertiesListener listener);
+    void unregisterListener(IBatteryPropertiesListener listener);
+}
diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java
index b7bc45f..a2432d6 100644
--- a/core/java/android/os/IBinder.java
+++ b/core/java/android/os/IBinder.java
@@ -238,7 +238,7 @@
      * <p>You will only receive death notifications for remote binders,
      * as local binders by definition can't die without you dying as well.
      * 
-     * @throws Throws {@link RemoteException} if the target IBinder's
+     * @throws RemoteException if the target IBinder's
      * process has already died.
      * 
      * @see #unlinkToDeath
@@ -251,13 +251,13 @@
      * The recipient will no longer be called if this object
      * dies.
      * 
-     * @return Returns true if the <var>recipient</var> is successfully
+     * @return {@code true} if the <var>recipient</var> is successfully
      * unlinked, assuring you that its
      * {@link DeathRecipient#binderDied DeathRecipient.binderDied()} method
-     * will not be called.  Returns false if the target IBinder has already
+     * will not be called;  {@code false} if the target IBinder has already
      * died, meaning the method has been (or soon will be) called.
      * 
-     * @throws Throws {@link java.util.NoSuchElementException} if the given
+     * @throws java.util.NoSuchElementException if the given
      * <var>recipient</var> has not been registered with the IBinder, and
      * the IBinder is still alive.  Note that if the <var>recipient</var>
      * was never registered, but the IBinder has already died, then this
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 45524c8..21b8ae5 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -19,6 +19,7 @@
 
 import android.net.InterfaceConfiguration;
 import android.net.INetworkManagementEventObserver;
+import android.net.LinkAddress;
 import android.net.NetworkStats;
 import android.net.RouteInfo;
 import android.net.wifi.WifiConfiguration;
@@ -117,6 +118,11 @@
     void removeSecondaryRoute(String iface, in RouteInfo route);
 
     /**
+     * Set the specified MTU size
+     */
+    void setMtu(String iface, int mtu);
+
+    /**
      * Shuts down the service
      */
     void shutdown();
@@ -254,11 +260,9 @@
     NetworkStats getNetworkStatsUidDetail(int uid);
 
     /**
-     * Return summary of network statistics for the requested pairs of
-     * tethering interfaces.  Even indexes are remote interface, and odd
-     * indexes are corresponding local interfaces.
+     * Return summary of network statistics all tethering interfaces.
      */
-    NetworkStats getNetworkStatsTethering(in String[] ifacePairs);
+    NetworkStats getNetworkStatsTethering();
 
     /**
      * Set quota for an interface.
@@ -344,6 +348,61 @@
     void setFirewallUidRule(int uid, boolean allow);
 
     /**
+     * Set all packets from users [uid_start,uid_end] to go through interface iface
+     * iface must already be set for marked forwarding by {@link setMarkedForwarding}
+     */
+    void setUidRangeRoute(String iface, int uid_start, int uid_end);
+
+    /**
+     * Clears the special routing rules for users [uid_start,uid_end]
+     */
+    void clearUidRangeRoute(String iface, int uid_start, int uid_end);
+
+    /**
+     * Setup an interface for routing packets marked by {@link setUidRangeRoute}
+     *
+     * This sets up a dedicated routing table for packets marked for {@code iface} and adds
+     * source-NAT rules so that the marked packets have the correct source address.
+     */
+    void setMarkedForwarding(String iface);
+
+    /**
+     * Removes marked forwarding for an interface
+     */
+    void clearMarkedForwarding(String iface);
+
+    /**
+     * Get the SO_MARK associated with routing packets for user {@code uid}
+     */
+    int getMarkForUid(int uid);
+
+    /**
+     * Get the SO_MARK associated with protecting packets from VPN routing rules
+     */
+    int getMarkForProtect();
+
+    /**
+     * Route all traffic in {@code route} to {@code iface} setup for marked forwarding
+     */
+    void setMarkedForwardingRoute(String iface, in RouteInfo route);
+
+    /**
+     * Clear routes set by {@link setMarkedForwardingRoute}
+     */
+    void clearMarkedForwardingRoute(String iface, in RouteInfo route);
+
+    /**
+     * Exempts {@code host} from the routing set up by {@link setMarkedForwardingRoute}
+     * All connects to {@code host} will use the global routing table
+     */
+    void setHostExemption(in LinkAddress host);
+
+    /**
+     * Clears an exemption set by {@link setHostExemption}
+     */
+    void clearHostExemption(in LinkAddress host);
+
+    /**
      * Set a process (pid) to use the name servers associated with the specified interface.
      */
     void setDnsInterfaceForPid(String iface, int pid);
@@ -354,6 +413,21 @@
     void clearDnsInterfaceForPid(int pid);
 
     /**
+    * Set a range of user ids to use the name servers associated with the specified interface.
+    */
+    void setDnsInterfaceForUidRange(String iface, int uid_start, int uid_end);
+
+    /**
+    * Clear a user range from being associated with an interface.
+    */
+    void clearDnsInterfaceForUidRange(int uid_start, int uid_end);
+
+    /**
+    * Clear the mappings from pid to Dns interface and from uid range to Dns interface.
+    */
+    void clearDnsInterfaceMaps();
+
+    /**
      * Start the clatd (464xlat) service
      */
     void startClatd(String interfaceName);
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index 6d6d147..23492ff 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -25,7 +25,7 @@
 {
     // WARNING: The first two methods must remain the first two methods because their
     // transaction numbers must not change unless IPowerManager.cpp is also updated.
-    void acquireWakeLock(IBinder lock, int flags, String tag, in WorkSource ws);
+    void acquireWakeLock(IBinder lock, int flags, String tag, String packageName, in WorkSource ws);
     void releaseWakeLock(IBinder lock, int flags);
 
     void updateWakeLockWorkSource(IBinder lock, in WorkSource ws);
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index a11358a..3c9d0d9 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -46,4 +46,8 @@
             int userHandle);
     Bundle getApplicationRestrictions(in String packageName);
     Bundle getApplicationRestrictionsForUser(in String packageName, int userHandle);
+    boolean setRestrictionsChallenge(in String newPin);
+    int checkRestrictionsChallenge(in String pin);
+    boolean hasRestrictionsChallenge();
+    void removeRestrictions();
 }
diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java
index d5cf771..78c859e 100644
--- a/core/java/android/os/Looper.java
+++ b/core/java/android/os/Looper.java
@@ -289,6 +289,16 @@
         return mQueue;
     }
 
+    /**
+     * Return whether this looper's thread is currently idle, waiting for new work
+     * to do.  This is intrinsically racy, since its state can change before you get
+     * the result back.
+     * @hide
+     */
+    public boolean isIdling() {
+        return mQueue.isIdling();
+    }
+
     public void dump(Printer pw, String prefix) {
         pw = PrefixPrinter.create(pw, prefix);
         pw.println(this.toString());
diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java
index bf7e5ca..d1b8213 100644
--- a/core/java/android/os/MessageQueue.java
+++ b/core/java/android/os/MessageQueue.java
@@ -39,7 +39,7 @@
     Message mMessages;
     private final ArrayList<IdleHandler> mIdleHandlers = new ArrayList<IdleHandler>();
     private IdleHandler[] mPendingIdleHandlers;
-    private boolean mQuiting;
+    private boolean mQuitting;
 
     // Indicates whether next() is blocked waiting in pollOnce() with a non-zero timeout.
     private boolean mBlocked;
@@ -52,6 +52,7 @@
     private native static void nativeDestroy(int ptr);
     private native static void nativePollOnce(int ptr, int timeoutMillis);
     private native static void nativeWake(int ptr);
+    private native static boolean nativeIsIdling(int ptr);
 
     /**
      * Callback interface for discovering when a thread is going to block
@@ -114,6 +115,8 @@
         }
     }
 
+    // Disposes of the underlying message queue.
+    // Must only be called on the looper thread or the finalizer.
     private void dispose() {
         if (mPtr != 0) {
             nativeDestroy(mPtr);
@@ -124,11 +127,13 @@
     Message next() {
         int pendingIdleHandlerCount = -1; // -1 only during first iteration
         int nextPollTimeoutMillis = 0;
-
         for (;;) {
             if (nextPollTimeoutMillis != 0) {
                 Binder.flushPendingCommands();
             }
+
+            // We can assume mPtr != 0 because the loop is obviously still running.
+            // The looper will not call this method after the loop quits.
             nativePollOnce(mPtr, nextPollTimeoutMillis);
 
             synchronized (this) {
@@ -166,7 +171,7 @@
                 }
 
                 // Process the quit message now that all pending messages have been handled.
-                if (mQuiting) {
+                if (mQuitting) {
                     dispose();
                     return null;
                 }
@@ -225,18 +230,20 @@
         }
 
         synchronized (this) {
-            if (mQuiting) {
+            if (mQuitting) {
                 return;
             }
-            mQuiting = true;
+            mQuitting = true;
 
             if (safe) {
                 removeAllFutureMessagesLocked();
             } else {
                 removeAllMessagesLocked();
             }
+
+            // We can assume mPtr != 0 because mQuitting was previously false.
+            nativeWake(mPtr);
         }
-        nativeWake(mPtr);
     }
 
     int enqueueSyncBarrier(long when) {
@@ -269,7 +276,6 @@
     void removeSyncBarrier(int token) {
         // Remove a sync barrier token from the queue.
         // If the queue is no longer stalled by a barrier then wake it.
-        final boolean needWake;
         synchronized (this) {
             Message prev = null;
             Message p = mMessages;
@@ -281,6 +287,7 @@
                 throw new IllegalStateException("The specified message queue synchronization "
                         + " barrier token has not been posted or has already been removed.");
             }
+            final boolean needWake;
             if (prev != null) {
                 prev.next = p.next;
                 needWake = false;
@@ -289,9 +296,12 @@
                 needWake = mMessages == null || mMessages.target != null;
             }
             p.recycle();
-        }
-        if (needWake) {
-            nativeWake(mPtr);
+
+            // If the loop is quitting then it is already awake.
+            // We can assume mPtr != 0 when mQuitting is false.
+            if (needWake && !mQuitting) {
+                nativeWake(mPtr);
+            }
         }
     }
 
@@ -303,9 +313,8 @@
             throw new AndroidRuntimeException("Message must have a target.");
         }
 
-        boolean needWake;
         synchronized (this) {
-            if (mQuiting) {
+            if (mQuitting) {
                 RuntimeException e = new RuntimeException(
                         msg.target + " sending message to a Handler on a dead thread");
                 Log.w("MessageQueue", e.getMessage(), e);
@@ -314,6 +323,7 @@
 
             msg.when = when;
             Message p = mMessages;
+            boolean needWake;
             if (p == null || when == 0 || when < p.when) {
                 // New head, wake up the event queue if blocked.
                 msg.next = p;
@@ -338,9 +348,11 @@
                 msg.next = p; // invariant: p == prev.next
                 prev.next = msg;
             }
-        }
-        if (needWake) {
-            nativeWake(mPtr);
+
+            // We can assume mPtr != 0 because mQuitting is false.
+            if (needWake) {
+                nativeWake(mPtr);
+            }
         }
         return true;
     }
@@ -379,6 +391,14 @@
         }
     }
 
+    boolean isIdling() {
+        synchronized (this) {
+            // If the loop is quitting then it must not be idling.
+            // We can assume mPtr != 0 when mQuitting is false.
+            return !mQuitting && nativeIsIdling(mPtr);
+        }
+    }
+
     void removeMessages(Handler h, int what, Object object) {
         if (h == null) {
             return;
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 0916ea9..fec2a3e 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -17,6 +17,7 @@
 package android.os;
 
 import android.text.TextUtils;
+import android.util.ArrayMap;
 import android.util.Log;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
@@ -227,6 +228,7 @@
     private static final int EX_ILLEGAL_ARGUMENT = -3;
     private static final int EX_NULL_POINTER = -4;
     private static final int EX_ILLEGAL_STATE = -5;
+    private static final int EX_NETWORK_MAIN_THREAD = -6;
     private static final int EX_HAS_REPLY_HEADER = -128;  // special; see below
 
     private static native int nativeDataSize(int nativePtr);
@@ -572,7 +574,7 @@
      * allows you to avoid mysterious type errors at the point of marshalling.
      */
     public final void writeMap(Map val) {
-        writeMapInternal((Map<String,Object>) val);
+        writeMapInternal((Map<String, Object>) val);
     }
 
     /**
@@ -593,6 +595,23 @@
     }
 
     /**
+     * Flatten an ArrayMap into the parcel at the current dataPosition(),
+     * growing dataCapacity() if needed.  The Map keys must be String objects.
+     */
+    /* package */ void writeArrayMapInternal(ArrayMap<String,Object> val) {
+        if (val == null) {
+            writeInt(-1);
+            return;
+        }
+        final int N = val.size();
+        writeInt(N);
+        for (int i=0; i<N; i++) {
+            writeValue(val.keyAt(i));
+            writeValue(val.valueAt(i));
+        }
+    }
+
+    /**
      * Flatten a Bundle into the parcel at the current dataPosition(),
      * growing dataCapacity() if needed.
      */
@@ -1303,6 +1322,7 @@
      * <li>{@link IllegalStateException}
      * <li>{@link NullPointerException}
      * <li>{@link SecurityException}
+     * <li>{@link NetworkOnMainThreadException}
      * </ul>
      * 
      * @param e The Exception to be written.
@@ -1322,6 +1342,8 @@
             code = EX_NULL_POINTER;
         } else if (e instanceof IllegalStateException) {
             code = EX_ILLEGAL_STATE;
+        } else if (e instanceof NetworkOnMainThreadException) {
+            code = EX_NETWORK_MAIN_THREAD;
         }
         writeInt(code);
         StrictMode.clearGatheredViolations();
@@ -1437,6 +1459,8 @@
                 throw new NullPointerException(msg);
             case EX_ILLEGAL_STATE:
                 throw new IllegalStateException(msg);
+            case EX_NETWORK_MAIN_THREAD:
+                throw new NetworkOnMainThreadException();
         }
         throw new RuntimeException("Unknown exception code: " + code
                 + " msg " + msg);
@@ -1502,6 +1526,11 @@
         return fd != null ? new ParcelFileDescriptor(fd) : null;
     }
 
+    /** {@hide} */
+    public final FileDescriptor readRawFileDescriptor() {
+        return nativeReadFileDescriptor(mNativePtr);
+    }
+
     /*package*/ static native FileDescriptor openFileDescriptor(String file,
             int mode) throws FileNotFoundException;
     /*package*/ static native FileDescriptor dupFileDescriptor(FileDescriptor orig)
@@ -2258,6 +2287,16 @@
         }
     }
 
+    /* package */ void readArrayMapInternal(ArrayMap outVal, int N,
+        ClassLoader loader) {
+        while (N > 0) {
+            Object key = readValue(loader);
+            Object value = readValue(loader);
+            outVal.append(key, value);
+            N--;
+        }
+    }
+
     private void readListInternal(List outVal, int N,
         ClassLoader loader) {
         while (N > 0) {
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index 3de362c..579971d 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -16,8 +16,25 @@
 
 package android.os;
 
+import static libcore.io.OsConstants.AF_UNIX;
+import static libcore.io.OsConstants.SEEK_SET;
+import static libcore.io.OsConstants.SOCK_STREAM;
+import static libcore.io.OsConstants.S_ISLNK;
+import static libcore.io.OsConstants.S_ISREG;
+
+import android.content.BroadcastReceiver;
+import android.content.ContentProvider;
+import android.util.Log;
+
 import dalvik.system.CloseGuard;
 
+import libcore.io.ErrnoException;
+import libcore.io.IoUtils;
+import libcore.io.Libcore;
+import libcore.io.Memory;
+import libcore.io.OsConstants;
+import libcore.io.StructStat;
+
 import java.io.Closeable;
 import java.io.File;
 import java.io.FileDescriptor;
@@ -27,36 +44,80 @@
 import java.io.IOException;
 import java.net.DatagramSocket;
 import java.net.Socket;
+import java.nio.ByteOrder;
 
 /**
  * The FileDescriptor returned by {@link Parcel#readFileDescriptor}, allowing
  * you to close it when done with it.
  */
 public class ParcelFileDescriptor implements Parcelable, Closeable {
-    private final FileDescriptor mFileDescriptor;
+    private static final String TAG = "ParcelFileDescriptor";
+
+    private final FileDescriptor mFd;
+
+    /**
+     * Optional socket used to communicate close events, status at close, and
+     * detect remote process crashes.
+     */
+    private FileDescriptor mCommFd;
 
     /**
      * Wrapped {@link ParcelFileDescriptor}, if any. Used to avoid
-     * double-closing {@link #mFileDescriptor}.
+     * double-closing {@link #mFd}.
      */
     private final ParcelFileDescriptor mWrapped;
 
+    /**
+     * Maximum {@link #mStatusBuf} size; longer status messages will be
+     * truncated.
+     */
+    private static final int MAX_STATUS = 1024;
+
+    /**
+     * Temporary buffer used by {@link #readCommStatus(FileDescriptor, byte[])},
+     * allocated on-demand.
+     */
+    private byte[] mStatusBuf;
+
+    /**
+     * Status read by {@link #checkError(boolean)}, or null if not read yet.
+     */
+    private Status mStatus;
+
     private volatile boolean mClosed;
 
     private final CloseGuard mGuard = CloseGuard.get();
 
     /**
-     * For use with {@link #open}: if {@link #MODE_CREATE} has been supplied
-     * and this file doesn't already exist, then create the file with
-     * permissions such that any application can read it.
+     * For use with {@link #open}: if {@link #MODE_CREATE} has been supplied and
+     * this file doesn't already exist, then create the file with permissions
+     * such that any application can read it.
+     *
+     * @deprecated Creating world-readable files is very dangerous, and likely
+     *             to cause security holes in applications. It is strongly
+     *             discouraged; instead, applications should use more formal
+     *             mechanism for interactions such as {@link ContentProvider},
+     *             {@link BroadcastReceiver}, and {@link android.app.Service}.
+     *             There are no guarantees that this access mode will remain on
+     *             a file, such as when it goes through a backup and restore.
      */
+    @Deprecated
     public static final int MODE_WORLD_READABLE = 0x00000001;
 
     /**
-     * For use with {@link #open}: if {@link #MODE_CREATE} has been supplied
-     * and this file doesn't already exist, then create the file with
-     * permissions such that any application can write it.
+     * For use with {@link #open}: if {@link #MODE_CREATE} has been supplied and
+     * this file doesn't already exist, then create the file with permissions
+     * such that any application can write it.
+     *
+     * @deprecated Creating world-writable files is very dangerous, and likely
+     *             to cause security holes in applications. It is strongly
+     *             discouraged; instead, applications should use more formal
+     *             mechanism for interactions such as {@link ContentProvider},
+     *             {@link BroadcastReceiver}, and {@link android.app.Service}.
+     *             There are no guarantees that this access mode will remain on
+     *             a file, such as when it goes through a backup and restore.
      */
+    @Deprecated
     public static final int MODE_WORLD_WRITEABLE = 0x00000002;
 
     /**
@@ -90,32 +151,102 @@
     public static final int MODE_APPEND = 0x02000000;
 
     /**
+     * Create a new ParcelFileDescriptor wrapped around another descriptor. By
+     * default all method calls are delegated to the wrapped descriptor.
+     */
+    public ParcelFileDescriptor(ParcelFileDescriptor wrapped) {
+        // We keep a strong reference to the wrapped PFD, and rely on its
+        // finalizer to trigger CloseGuard. All calls are delegated to wrapper.
+        mWrapped = wrapped;
+        mFd = null;
+        mCommFd = null;
+        mClosed = true;
+    }
+
+    /** {@hide} */
+    public ParcelFileDescriptor(FileDescriptor fd) {
+        this(fd, null);
+    }
+
+    /** {@hide} */
+    public ParcelFileDescriptor(FileDescriptor fd, FileDescriptor commChannel) {
+        if (fd == null) {
+            throw new NullPointerException("FileDescriptor must not be null");
+        }
+        mWrapped = null;
+        mFd = fd;
+        mCommFd = commChannel;
+        mGuard.open("close");
+    }
+
+    /**
      * Create a new ParcelFileDescriptor accessing a given file.
      *
      * @param file The file to be opened.
      * @param mode The desired access mode, must be one of
-     * {@link #MODE_READ_ONLY}, {@link #MODE_WRITE_ONLY}, or
-     * {@link #MODE_READ_WRITE}; may also be any combination of
-     * {@link #MODE_CREATE}, {@link #MODE_TRUNCATE},
-     * {@link #MODE_WORLD_READABLE}, and {@link #MODE_WORLD_WRITEABLE}.
-     *
-     * @return Returns a new ParcelFileDescriptor pointing to the given
-     * file.
-     *
-     * @throws FileNotFoundException Throws FileNotFoundException if the given
-     * file does not exist or can not be opened with the requested mode.
+     *            {@link #MODE_READ_ONLY}, {@link #MODE_WRITE_ONLY}, or
+     *            {@link #MODE_READ_WRITE}; may also be any combination of
+     *            {@link #MODE_CREATE}, {@link #MODE_TRUNCATE},
+     *            {@link #MODE_WORLD_READABLE}, and
+     *            {@link #MODE_WORLD_WRITEABLE}.
+     * @return a new ParcelFileDescriptor pointing to the given file.
+     * @throws FileNotFoundException if the given file does not exist or can not
+     *             be opened with the requested mode.
      */
-    public static ParcelFileDescriptor open(File file, int mode)
-            throws FileNotFoundException {
-        String path = file.getPath();
+    public static ParcelFileDescriptor open(File file, int mode) throws FileNotFoundException {
+        final FileDescriptor fd = openInternal(file, mode);
+        if (fd == null) return null;
 
-        if ((mode&MODE_READ_WRITE) == 0) {
+        return new ParcelFileDescriptor(fd);
+    }
+
+    /**
+     * Create a new ParcelFileDescriptor accessing a given file.
+     *
+     * @param file The file to be opened.
+     * @param mode The desired access mode, must be one of
+     *            {@link #MODE_READ_ONLY}, {@link #MODE_WRITE_ONLY}, or
+     *            {@link #MODE_READ_WRITE}; may also be any combination of
+     *            {@link #MODE_CREATE}, {@link #MODE_TRUNCATE},
+     *            {@link #MODE_WORLD_READABLE}, and
+     *            {@link #MODE_WORLD_WRITEABLE}.
+     * @param handler to call listener from; must not be null.
+     * @param listener to be invoked when the returned descriptor has been
+     *            closed; must not be null.
+     * @return a new ParcelFileDescriptor pointing to the given file.
+     * @throws FileNotFoundException if the given file does not exist or can not
+     *             be opened with the requested mode.
+     */
+    public static ParcelFileDescriptor open(
+            File file, int mode, Handler handler, OnCloseListener listener) throws IOException {
+        if (handler == null) {
+            throw new IllegalArgumentException("Handler must not be null");
+        }
+        if (listener == null) {
+            throw new IllegalArgumentException("Listener must not be null");
+        }
+
+        final FileDescriptor fd = openInternal(file, mode);
+        if (fd == null) return null;
+
+        final FileDescriptor[] comm = createCommSocketPair(true);
+        final ParcelFileDescriptor pfd = new ParcelFileDescriptor(fd, comm[0]);
+
+        // Kick off thread to watch for status updates
+        final ListenerBridge bridge = new ListenerBridge(comm[1], handler.getLooper(), listener);
+        bridge.start();
+
+        return pfd;
+    }
+
+    private static FileDescriptor openInternal(File file, int mode) throws FileNotFoundException {
+        if ((mode & MODE_READ_WRITE) == 0) {
             throw new IllegalArgumentException(
                     "Must specify MODE_READ_ONLY, MODE_WRITE_ONLY, or MODE_READ_WRITE");
         }
 
-        FileDescriptor fd = Parcel.openFileDescriptor(path, mode);
-        return fd != null ? new ParcelFileDescriptor(fd) : null;
+        final String path = file.getPath();
+        return Parcel.openFileDescriptor(path, mode);
     }
 
     /**
@@ -125,8 +256,12 @@
      * original file descriptor.
      */
     public static ParcelFileDescriptor dup(FileDescriptor orig) throws IOException {
-        FileDescriptor fd = Parcel.dupFileDescriptor(orig);
-        return fd != null ? new ParcelFileDescriptor(fd) : null;
+        try {
+            final FileDescriptor fd = Libcore.os.dup(orig);
+            return new ParcelFileDescriptor(fd);
+        } catch (ErrnoException e) {
+            throw e.rethrowAsIOException();
+        }
     }
 
     /**
@@ -136,7 +271,11 @@
      * original file descriptor.
      */
     public ParcelFileDescriptor dup() throws IOException {
-        return dup(getFileDescriptor());
+        if (mWrapped != null) {
+            return mWrapped.dup();
+        } else {
+            return dup(getFileDescriptor());
+        }
     }
 
     /**
@@ -150,12 +289,16 @@
      * for a dup of the given fd.
      */
     public static ParcelFileDescriptor fromFd(int fd) throws IOException {
-        FileDescriptor fdesc = getFileDescriptorFromFd(fd);
-        return new ParcelFileDescriptor(fdesc);
-    }
+        final FileDescriptor original = new FileDescriptor();
+        original.setInt$(fd);
 
-    // Extracts the file descriptor from the specified socket and returns it untouched
-    private static native FileDescriptor getFileDescriptorFromFd(int fd) throws IOException;
+        try {
+            final FileDescriptor dup = Libcore.os.dup(original);
+            return new ParcelFileDescriptor(dup);
+        } catch (ErrnoException e) {
+            throw e.rethrowAsIOException();
+        }
+    }
 
     /**
      * Take ownership of a raw native fd in to a new ParcelFileDescriptor.
@@ -168,13 +311,12 @@
      * for the given fd.
      */
     public static ParcelFileDescriptor adoptFd(int fd) {
-        FileDescriptor fdesc = getFileDescriptorFromFdNoDup(fd);
+        final FileDescriptor fdesc = new FileDescriptor();
+        fdesc.setInt$(fd);
+
         return new ParcelFileDescriptor(fdesc);
     }
 
-    // Extracts the file descriptor from the specified socket and returns it untouched
-    private static native FileDescriptor getFileDescriptorFromFdNoDup(int fd);
-
     /**
      * Create a new ParcelFileDescriptor from the specified Socket.  The new
      * ParcelFileDescriptor holds a dup of the original FileDescriptor in
@@ -212,15 +354,90 @@
      * is the write side.
      */
     public static ParcelFileDescriptor[] createPipe() throws IOException {
-        FileDescriptor[] fds = new FileDescriptor[2];
-        createPipeNative(fds);
-        ParcelFileDescriptor[] pfds = new ParcelFileDescriptor[2];
-        pfds[0] = new ParcelFileDescriptor(fds[0]);
-        pfds[1] = new ParcelFileDescriptor(fds[1]);
-        return pfds;
+        try {
+            final FileDescriptor[] fds = Libcore.os.pipe();
+            return new ParcelFileDescriptor[] {
+                    new ParcelFileDescriptor(fds[0]),
+                    new ParcelFileDescriptor(fds[1]) };
+        } catch (ErrnoException e) {
+            throw e.rethrowAsIOException();
+        }
     }
 
-    private static native void createPipeNative(FileDescriptor[] outFds) throws IOException;
+    /**
+     * Create two ParcelFileDescriptors structured as a data pipe. The first
+     * ParcelFileDescriptor in the returned array is the read side; the second
+     * is the write side.
+     * <p>
+     * The write end has the ability to deliver an error message through
+     * {@link #closeWithError(String)} which can be handled by the read end
+     * calling {@link #checkError(boolean)}, usually after detecting an EOF.
+     * This can also be used to detect remote crashes.
+     */
+    public static ParcelFileDescriptor[] createReliablePipe() throws IOException {
+        try {
+            final FileDescriptor[] comm = createCommSocketPair(false);
+            final FileDescriptor[] fds = Libcore.os.pipe();
+            return new ParcelFileDescriptor[] {
+                    new ParcelFileDescriptor(fds[0], comm[0]),
+                    new ParcelFileDescriptor(fds[1], comm[1]) };
+        } catch (ErrnoException e) {
+            throw e.rethrowAsIOException();
+        }
+    }
+
+    /**
+     * Create two ParcelFileDescriptors structured as a pair of sockets
+     * connected to each other. The two sockets are indistinguishable.
+     */
+    public static ParcelFileDescriptor[] createSocketPair() throws IOException {
+        try {
+            final FileDescriptor fd0 = new FileDescriptor();
+            final FileDescriptor fd1 = new FileDescriptor();
+            Libcore.os.socketpair(AF_UNIX, SOCK_STREAM, 0, fd0, fd1);
+            return new ParcelFileDescriptor[] {
+                    new ParcelFileDescriptor(fd0),
+                    new ParcelFileDescriptor(fd1) };
+        } catch (ErrnoException e) {
+            throw e.rethrowAsIOException();
+        }
+    }
+
+    /**
+     * Create two ParcelFileDescriptors structured as a pair of sockets
+     * connected to each other. The two sockets are indistinguishable.
+     * <p>
+     * Both ends have the ability to deliver an error message through
+     * {@link #closeWithError(String)} which can be detected by the other end
+     * calling {@link #checkError(boolean)}, usually after detecting an EOF.
+     * This can also be used to detect remote crashes.
+     */
+    public static ParcelFileDescriptor[] createReliableSocketPair() throws IOException {
+        try {
+            final FileDescriptor[] comm = createCommSocketPair(false);
+            final FileDescriptor fd0 = new FileDescriptor();
+            final FileDescriptor fd1 = new FileDescriptor();
+            Libcore.os.socketpair(AF_UNIX, SOCK_STREAM, 0, fd0, fd1);
+            return new ParcelFileDescriptor[] {
+                    new ParcelFileDescriptor(fd0, comm[0]),
+                    new ParcelFileDescriptor(fd1, comm[1]) };
+        } catch (ErrnoException e) {
+            throw e.rethrowAsIOException();
+        }
+    }
+
+    private static FileDescriptor[] createCommSocketPair(boolean blocking) throws IOException {
+        try {
+            final FileDescriptor comm1 = new FileDescriptor();
+            final FileDescriptor comm2 = new FileDescriptor();
+            Libcore.os.socketpair(AF_UNIX, SOCK_STREAM, 0, comm1, comm2);
+            IoUtils.setBlocking(comm1, blocking);
+            IoUtils.setBlocking(comm2, blocking);
+            return new FileDescriptor[] { comm1, comm2 };
+        } catch (ErrnoException e) {
+            throw e.rethrowAsIOException();
+        }
+    }
 
     /**
      * @hide Please use createPipe() or ContentProvider.openPipeHelper().
@@ -250,21 +467,51 @@
      * @return Returns the FileDescriptor associated with this object.
      */
     public FileDescriptor getFileDescriptor() {
-        return mFileDescriptor;
+        if (mWrapped != null) {
+            return mWrapped.getFileDescriptor();
+        } else {
+            return mFd;
+        }
     }
 
     /**
-     * Return the total size of the file representing this fd, as determined
-     * by stat().  Returns -1 if the fd is not a file.
+     * Return the total size of the file representing this fd, as determined by
+     * {@code stat()}. Returns -1 if the fd is not a file.
      */
-    public native long getStatSize();
+    public long getStatSize() {
+        if (mWrapped != null) {
+            return mWrapped.getStatSize();
+        } else {
+            try {
+                final StructStat st = Libcore.os.fstat(mFd);
+                if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
+                    return st.st_size;
+                } else {
+                    return -1;
+                }
+            } catch (ErrnoException e) {
+                Log.w(TAG, "fstat() failed: " + e);
+                return -1;
+            }
+        }
+    }
 
     /**
      * This is needed for implementing AssetFileDescriptor.AutoCloseOutputStream,
      * and I really don't think we want it to be public.
      * @hide
      */
-    public native long seekTo(long pos);
+    public long seekTo(long pos) throws IOException {
+        if (mWrapped != null) {
+            return mWrapped.seekTo(pos);
+        } else {
+            try {
+                return Libcore.os.lseek(mFd, pos, SEEK_SET);
+            } catch (ErrnoException e) {
+                throw e.rethrowAsIOException();
+            }
+        }
+    }
 
     /**
      * Return the native fd int for this ParcelFileDescriptor.  The
@@ -272,34 +519,39 @@
      * through this API.
      */
     public int getFd() {
-        if (mClosed) {
-            throw new IllegalStateException("Already closed");
+        if (mWrapped != null) {
+            return mWrapped.getFd();
+        } else {
+            if (mClosed) {
+                throw new IllegalStateException("Already closed");
+            }
+            return mFd.getInt$();
         }
-        return getFdNative();
     }
 
-    private native int getFdNative();
-
     /**
-     * Return the native fd int for this ParcelFileDescriptor and detach it
-     * from the object here.  You are now responsible for closing the fd in
-     * native code.
+     * Return the native fd int for this ParcelFileDescriptor and detach it from
+     * the object here. You are now responsible for closing the fd in native
+     * code.
+     * <p>
+     * You should not detach when the original creator of the descriptor is
+     * expecting a reliable signal through {@link #close()} or
+     * {@link #closeWithError(String)}.
+     *
+     * @see #canDetectErrors()
      */
     public int detachFd() {
-        if (mClosed) {
-            throw new IllegalStateException("Already closed");
-        }
         if (mWrapped != null) {
-            int fd = mWrapped.detachFd();
-            mClosed = true;
-            mGuard.close();
+            return mWrapped.detachFd();
+        } else {
+            if (mClosed) {
+                throw new IllegalStateException("Already closed");
+            }
+            final int fd = getFd();
+            Parcel.clearFileDescriptor(mFd);
+            writeCommStatusAndClose(Status.DETACHED, null);
             return fd;
         }
-        int fd = getFd();
-        mClosed = true;
-        mGuard.close();
-        Parcel.clearFileDescriptor(mFileDescriptor);
-        return fd;
     }
 
     /**
@@ -311,16 +563,176 @@
      */
     @Override
     public void close() throws IOException {
-        if (mClosed) return;
-        mClosed = true;
-        mGuard.close();
-
         if (mWrapped != null) {
-            // If this is a proxy to another file descriptor, just call through to its
-            // close method.
             mWrapped.close();
         } else {
-            Parcel.closeFileDescriptor(mFileDescriptor);
+            closeWithStatus(Status.OK, null);
+        }
+    }
+
+    /**
+     * Close the ParcelFileDescriptor, informing any peer that an error occurred
+     * while processing. If the creator of this descriptor is not observing
+     * errors, it will close normally.
+     *
+     * @param msg describing the error; must not be null.
+     */
+    public void closeWithError(String msg) throws IOException {
+        if (mWrapped != null) {
+            mWrapped.closeWithError(msg);
+        } else {
+            if (msg == null) {
+                throw new IllegalArgumentException("Message must not be null");
+            }
+            closeWithStatus(Status.ERROR, msg);
+        }
+    }
+
+    private void closeWithStatus(int status, String msg) throws IOException {
+        if (mWrapped != null) {
+            mWrapped.closeWithStatus(status, msg);
+        } else {
+            if (mClosed) return;
+            mClosed = true;
+            mGuard.close();
+            // Status MUST be sent before closing actual descriptor
+            writeCommStatusAndClose(status, msg);
+            IoUtils.closeQuietly(mFd);
+        }
+    }
+
+    private byte[] getOrCreateStatusBuffer() {
+        if (mStatusBuf == null) {
+            mStatusBuf = new byte[MAX_STATUS];
+        }
+        return mStatusBuf;
+    }
+
+    private void writeCommStatusAndClose(int status, String msg) {
+        if (mCommFd == null) {
+            // Not reliable, or someone already sent status
+            if (msg != null) {
+                Log.w(TAG, "Unable to inform peer: " + msg);
+            }
+            return;
+        }
+
+        if (status == Status.DETACHED) {
+            Log.w(TAG, "Peer expected signal when closed; unable to deliver after detach");
+        }
+
+        try {
+            try {
+                if (status != Status.SILENCE) {
+                    final byte[] buf = getOrCreateStatusBuffer();
+                    int writePtr = 0;
+
+                    Memory.pokeInt(buf, writePtr, status, ByteOrder.BIG_ENDIAN);
+                    writePtr += 4;
+
+                    if (msg != null) {
+                        final byte[] rawMsg = msg.getBytes();
+                        final int len = Math.min(rawMsg.length, buf.length - writePtr);
+                        System.arraycopy(rawMsg, 0, buf, writePtr, len);
+                        writePtr += len;
+                    }
+
+                    Libcore.os.write(mCommFd, buf, 0, writePtr);
+                }
+            } catch (ErrnoException e) {
+                // Reporting status is best-effort
+                Log.w(TAG, "Failed to report status: " + e);
+            }
+
+            if (status != Status.SILENCE) {
+                // Since we're about to close, read off any remote status. It's
+                // okay to remember missing here.
+                mStatus = readCommStatus(mCommFd, getOrCreateStatusBuffer());
+            }
+
+        } finally {
+            IoUtils.closeQuietly(mCommFd);
+            mCommFd = null;
+        }
+    }
+
+    private static Status readCommStatus(FileDescriptor comm, byte[] buf) {
+        try {
+            final int n = Libcore.os.read(comm, buf, 0, buf.length);
+            if (n == 0) {
+                // EOF means they're dead
+                return new Status(Status.DEAD);
+            } else {
+                final int status = Memory.peekInt(buf, 0, ByteOrder.BIG_ENDIAN);
+                if (status == Status.ERROR) {
+                    final String msg = new String(buf, 4, n - 4);
+                    return new Status(status, msg);
+                }
+                return new Status(status);
+            }
+        } catch (ErrnoException e) {
+            if (e.errno == OsConstants.EAGAIN) {
+                // Remote is still alive, but no status written yet
+                return null;
+            } else {
+                Log.d(TAG, "Failed to read status; assuming dead: " + e);
+                return new Status(Status.DEAD);
+            }
+        }
+    }
+
+    /**
+     * Indicates if this ParcelFileDescriptor can communicate and detect remote
+     * errors/crashes.
+     *
+     * @see #checkError(boolean)
+     */
+    public boolean canDetectErrors() {
+        if (mWrapped != null) {
+            return mWrapped.canDetectErrors();
+        } else {
+            return mCommFd != null;
+        }
+    }
+
+    /**
+     * Detect and throw if the other end of a pipe or socket pair encountered an
+     * error or crashed. This allows a reader to distinguish between a valid EOF
+     * and an error/crash.
+     * <p>
+     * If this ParcelFileDescriptor is unable to detect remote errors, it will
+     * return silently.
+     *
+     * @param throwIfDetached requests that an exception be thrown if the remote
+     *            side called {@link #detachFd()}. Once detached, the remote
+     *            side is unable to communicate any errors through
+     *            {@link #closeWithError(String)}. An application may pass true
+     *            if it needs a stronger guarantee that the stream was closed
+     *            normally and was not merely detached.
+     * @see #canDetectErrors()
+     */
+    public void checkError(boolean throwIfDetached) throws IOException {
+        if (mWrapped != null) {
+            mWrapped.checkError(throwIfDetached);
+        } else {
+            if (mStatus == null) {
+                if (mCommFd == null) {
+                    Log.w(TAG, "Peer didn't provide a comm channel; unable to check for errors");
+                    return;
+                }
+
+                // Try reading status; it might be null if nothing written yet.
+                // Either way, we keep comm open to write our status later.
+                mStatus = readCommStatus(mCommFd, getOrCreateStatusBuffer());
+            }
+
+            if (mStatus == null || mStatus.status == Status.OK
+                    || (mStatus.status == Status.DETACHED && !throwIfDetached)) {
+                // No status yet, or everything is peachy!
+                return;
+            } else {
+                throw mStatus.asIOException();
+            }
         }
     }
 
@@ -330,17 +742,17 @@
      * ParcelFileDescriptor.close()} for you when the stream is closed.
      */
     public static class AutoCloseInputStream extends FileInputStream {
-        private final ParcelFileDescriptor mFd;
+        private final ParcelFileDescriptor mPfd;
 
-        public AutoCloseInputStream(ParcelFileDescriptor fd) {
-            super(fd.getFileDescriptor());
-            mFd = fd;
+        public AutoCloseInputStream(ParcelFileDescriptor pfd) {
+            super(pfd.getFileDescriptor());
+            mPfd = pfd;
         }
 
         @Override
         public void close() throws IOException {
             try {
-                mFd.close();
+                mPfd.close();
             } finally {
                 super.close();
             }
@@ -353,17 +765,17 @@
      * ParcelFileDescriptor.close()} for you when the stream is closed.
      */
     public static class AutoCloseOutputStream extends FileOutputStream {
-        private final ParcelFileDescriptor mFd;
+        private final ParcelFileDescriptor mPfd;
 
-        public AutoCloseOutputStream(ParcelFileDescriptor fd) {
-            super(fd.getFileDescriptor());
-            mFd = fd;
+        public AutoCloseOutputStream(ParcelFileDescriptor pfd) {
+            super(pfd.getFileDescriptor());
+            mPfd = pfd;
         }
 
         @Override
         public void close() throws IOException {
             try {
-                mFd.close();
+                mPfd.close();
             } finally {
                 super.close();
             }
@@ -372,7 +784,11 @@
 
     @Override
     public String toString() {
-        return "{ParcelFileDescriptor: " + mFileDescriptor + "}";
+        if (mWrapped != null) {
+            return mWrapped.toString();
+        } else {
+            return "{ParcelFileDescriptor: " + mFd + "}";
+        }
     }
 
     @Override
@@ -382,32 +798,20 @@
         }
         try {
             if (!mClosed) {
-                close();
+                closeWithStatus(Status.LEAKED, null);
             }
         } finally {
             super.finalize();
         }
     }
 
-    public ParcelFileDescriptor(ParcelFileDescriptor descriptor) {
-        mWrapped = descriptor;
-        mFileDescriptor = mWrapped.mFileDescriptor;
-        mGuard.open("close");
-    }
-
-    /** {@hide} */
-    public ParcelFileDescriptor(FileDescriptor descriptor) {
-        if (descriptor == null) {
-            throw new NullPointerException("descriptor must not be null");
-        }
-        mWrapped = null;
-        mFileDescriptor = descriptor;
-        mGuard.open("close");
-    }
-
     @Override
     public int describeContents() {
-        return Parcelable.CONTENTS_FILE_DESCRIPTOR;
+        if (mWrapped != null) {
+            return mWrapped.describeContents();
+        } else {
+            return Parcelable.CONTENTS_FILE_DESCRIPTOR;
+        }
     }
 
     /**
@@ -417,12 +821,22 @@
      */
     @Override
     public void writeToParcel(Parcel out, int flags) {
-        out.writeFileDescriptor(mFileDescriptor);
-        if ((flags&PARCELABLE_WRITE_RETURN_VALUE) != 0 && !mClosed) {
-            try {
-                close();
-            } catch (IOException e) {
-                // Empty
+        if (mWrapped != null) {
+            mWrapped.writeToParcel(out, flags);
+        } else {
+            out.writeFileDescriptor(mFd);
+            if (mCommFd != null) {
+                out.writeInt(1);
+                out.writeFileDescriptor(mCommFd);
+            } else {
+                out.writeInt(0);
+            }
+            if ((flags & PARCELABLE_WRITE_RETURN_VALUE) != 0 && !mClosed) {
+                try {
+                    // Not a real close, so emit no status
+                    closeWithStatus(Status.SILENCE, null);
+                } catch (IOException e) {
+                }
             }
         }
     }
@@ -431,7 +845,12 @@
             = new Parcelable.Creator<ParcelFileDescriptor>() {
         @Override
         public ParcelFileDescriptor createFromParcel(Parcel in) {
-            return in.readFileDescriptor();
+            final FileDescriptor fd = in.readRawFileDescriptor();
+            FileDescriptor commChannel = null;
+            if (in.readInt() != 0) {
+                commChannel = in.readRawFileDescriptor();
+            }
+            return new ParcelFileDescriptor(fd, commChannel);
         }
 
         @Override
@@ -439,4 +858,111 @@
             return new ParcelFileDescriptor[size];
         }
     };
+
+    /**
+     * Callback indicating that a ParcelFileDescriptor has been closed.
+     */
+    public interface OnCloseListener {
+        /**
+         * Event indicating the ParcelFileDescriptor to which this listener was
+         * attached has been closed.
+         *
+         * @param e error state, or {@code null} if closed cleanly.
+         * @param fromDetach indicates if close event was result of
+         *            {@link ParcelFileDescriptor#detachFd()}. After detach the
+         *            remote side may continue reading/writing to the underlying
+         *            {@link FileDescriptor}, but they can no longer deliver
+         *            reliable close/error events.
+         */
+        public void onClose(IOException e, boolean fromDetach);
+    }
+
+    /**
+     * Internal class representing a remote status read by
+     * {@link ParcelFileDescriptor#readCommStatus(FileDescriptor, byte[])}.
+     */
+    private static class Status {
+        /** Special value indicating remote side died. */
+        public static final int DEAD = -2;
+        /** Special value indicating no status should be written. */
+        public static final int SILENCE = -1;
+
+        /** Remote reported that everything went better than expected. */
+        public static final int OK = 0;
+        /** Remote reported error; length and message follow. */
+        public static final int ERROR = 1;
+        /** Remote reported {@link #detachFd()} and went rogue. */
+        public static final int DETACHED = 2;
+        /** Remote reported their object was finalized. */
+        public static final int LEAKED = 3;
+
+        public final int status;
+        public final String msg;
+
+        public Status(int status) {
+            this(status, null);
+        }
+
+        public Status(int status, String msg) {
+            this.status = status;
+            this.msg = msg;
+        }
+
+        public IOException asIOException() {
+            switch (status) {
+                case DEAD:
+                    return new IOException("Remote side is dead");
+                case OK:
+                    return null;
+                case ERROR:
+                    return new IOException("Remote error: " + msg);
+                case DETACHED:
+                    return new IOException("Remote side is detached");
+                case LEAKED:
+                    return new IOException("Remote side was leaked");
+                default:
+                    return new IOException("Unknown status: " + status);
+            }
+        }
+    }
+
+    /**
+     * Bridge to watch for remote status, and deliver to listener. Currently
+     * requires that communication socket is <em>blocking</em>.
+     */
+    private static final class ListenerBridge extends Thread {
+        // TODO: switch to using Looper to avoid burning a thread
+
+        private FileDescriptor mCommFd;
+        private final Handler mHandler;
+
+        public ListenerBridge(FileDescriptor comm, Looper looper, final OnCloseListener listener) {
+            mCommFd = comm;
+            mHandler = new Handler(looper) {
+                @Override
+                public void handleMessage(Message msg) {
+                    final Status s = (Status) msg.obj;
+                    if (s.status == Status.DETACHED) {
+                        listener.onClose(null, true);
+                    } else if (s.status == Status.OK) {
+                        listener.onClose(null, false);
+                    } else {
+                        listener.onClose(s.asIOException(), false);
+                    }
+                }
+            };
+        }
+
+        @Override
+        public void run() {
+            try {
+                final byte[] buf = new byte[MAX_STATUS];
+                final Status status = readCommStatus(mCommFd, buf);
+                mHandler.obtainMessage(0, status).sendToTarget();
+            } finally {
+                IoUtils.closeQuietly(mCommFd);
+                mCommFd = null;
+            }
+        }
+    }
 }
diff --git a/core/java/android/os/ParcelableParcel.java b/core/java/android/os/ParcelableParcel.java
new file mode 100644
index 0000000..11785f1
--- /dev/null
+++ b/core/java/android/os/ParcelableParcel.java
@@ -0,0 +1,75 @@
+/*
+ * 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.os;
+
+/**
+ * Parcelable containing a raw Parcel of data.
+ * @hide
+ */
+public class ParcelableParcel implements Parcelable {
+    final Parcel mParcel;
+    final ClassLoader mClassLoader;
+
+    public ParcelableParcel(ClassLoader loader) {
+        mParcel = Parcel.obtain();
+        mClassLoader = loader;
+    }
+
+    public ParcelableParcel(Parcel src, ClassLoader loader) {
+        mParcel = Parcel.obtain();
+        mClassLoader = loader;
+        int size = src.readInt();
+        int pos = src.dataPosition();
+        mParcel.appendFrom(src, src.dataPosition(), size);
+        src.setDataPosition(pos + size);
+    }
+
+    public Parcel getParcel() {
+        mParcel.setDataPosition(0);
+        return mParcel;
+    }
+
+    public ClassLoader getClassLoader() {
+        return mClassLoader;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mParcel.dataSize());
+        dest.appendFrom(mParcel, 0, mParcel.dataSize());
+    }
+
+    public static final Parcelable.ClassLoaderCreator<ParcelableParcel> CREATOR
+            = new Parcelable.ClassLoaderCreator<ParcelableParcel>() {
+        public ParcelableParcel createFromParcel(Parcel in) {
+            return new ParcelableParcel(in, null);
+        }
+
+        public ParcelableParcel createFromParcel(Parcel in, ClassLoader loader) {
+            return new ParcelableParcel(in, loader);
+        }
+
+        public ParcelableParcel[] newArray(int size) {
+            return new ParcelableParcel[size];
+        }
+    };
+}
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 736762f..5e0d489 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -224,7 +224,7 @@
 
     /**
      * Flag for {@link WakeLock#release release(int)} to defer releasing a
-     * {@link #WAKE_BIT_PROXIMITY_SCREEN_OFF} wake lock until the proximity sensor returns
+     * {@link #PROXIMITY_SCREEN_OFF_WAKE_LOCK} wake lock until the proximity sensor returns
      * a negative value.
      *
      * {@hide}
@@ -407,7 +407,7 @@
      */
     public WakeLock newWakeLock(int levelAndFlags, String tag) {
         validateWakeLockParameters(levelAndFlags, tag);
-        return new WakeLock(levelAndFlags, tag);
+        return new WakeLock(levelAndFlags, tag, mContext.getOpPackageName());
     }
 
     /** @hide */
@@ -624,6 +624,7 @@
     public final class WakeLock {
         private final int mFlags;
         private final String mTag;
+        private final String mPackageName;
         private final IBinder mToken;
         private int mCount;
         private boolean mRefCounted = true;
@@ -636,9 +637,10 @@
             }
         };
 
-        WakeLock(int flags, String tag) {
+        WakeLock(int flags, String tag, String packageName) {
             mFlags = flags;
             mTag = tag;
+            mPackageName = packageName;
             mToken = new Binder();
         }
 
@@ -714,7 +716,7 @@
                 // been explicitly released by the keyguard.
                 mHandler.removeCallbacks(mReleaser);
                 try {
-                    mService.acquireWakeLock(mToken, mFlags, mTag, mWorkSource);
+                    mService.acquireWakeLock(mToken, mFlags, mTag, mPackageName, mWorkSource);
                 } catch (RemoteException e) {
                 }
                 mHeld = true;
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index ebeb9f8..cf9ddb3 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -100,12 +100,6 @@
     public static final int DRM_UID = 1019;
 
     /**
-     * Defines the GID for the group that allows write access to the SD card.
-     * @hide
-     */
-    public static final int SDCARD_RW_GID = 1015;
-
-    /**
      * Defines the UID/GID for the group that controls VPN services.
      * @hide
      */
@@ -130,11 +124,18 @@
     public static final int MEDIA_RW_GID = 1023;
 
     /**
+     * Access to installed package details
+     * @hide
+     */
+    public static final int PACKAGE_INFO_GID = 1032;
+
+    /**
      * Defines the start of a range of UIDs (and GIDs), going from this
      * number to {@link #LAST_APPLICATION_UID} that are reserved for assigning
      * to applications.
      */
     public static final int FIRST_APPLICATION_UID = 10000;
+
     /**
      * Last of application-specific UIDs starting at
      * {@link #FIRST_APPLICATION_UID}.
@@ -654,6 +655,14 @@
     }
 
     /**
+     * Returns the identifier of this process' parent.
+     * @hide
+     */
+    public static final int myPpid() {
+        return Libcore.os.getppid();
+    }
+
+    /**
      * Returns the identifier of the calling thread, which be used with
      * {@link #setThreadPriority(int, int)}.
      */
@@ -896,6 +905,19 @@
     public static final native boolean setOomAdj(int pid, int amt);
 
     /**
+     * Adjust the swappiness level for a process.
+     *
+     * @param pid The process identifier to set.
+     * @param is_increased Whether swappiness should be increased or default.
+     *
+     * @return Returns true if the underlying system supports this
+     *         feature, else false.
+     *
+     * {@hide}
+     */
+    public static final native boolean setSwappiness(int pid, boolean is_increased);
+
+    /**
      * Change this process's argv[0] parameter.  This can be useful to show
      * more descriptive information in things like the 'ps' command.
      * 
@@ -978,6 +1000,8 @@
     /** @hide */
     public static final int PROC_PARENS = 0x200;
     /** @hide */
+    public static final int PROC_QUOTES = 0x400;
+    /** @hide */
     public static final int PROC_OUT_STRING = 0x1000;
     /** @hide */
     public static final int PROC_OUT_LONG = 0x2000;
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 480fe7d..5e20dec 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -244,12 +244,17 @@
             // The signature cert matches a trusted key.  Now verify that
             // the digest in the cert matches the actual file data.
 
-            // The verifier in recovery *only* handles SHA1withRSA
-            // signatures.  SignApk.java always uses SHA1withRSA, no
-            // matter what the cert says to use.  Ignore
-            // cert.getSigAlgName(), and instead use whatever
-            // algorithm is used by the signature (which should be
-            // SHA1withRSA).
+            // The verifier in recovery only handles SHA1withRSA and
+            // SHA256withRSA signatures.  SignApk chooses which to use
+            // based on the signature algorithm of the cert:
+            //
+            //    "SHA256withRSA" cert -> "SHA256withRSA" signature
+            //    "SHA1withRSA" cert   -> "SHA1withRSA" signature
+            //    "MD5withRSA" cert    -> "SHA1withRSA" signature (for backwards compatibility)
+            //    any other cert       -> SignApk fails
+            //
+            // Here we ignore whatever the cert says, and instead use
+            // whatever algorithm is used by the signature.
 
             String da = sigInfo.getDigestAlgorithm();
             String dea = sigInfo.getDigestEncryptionAlgorithm();
diff --git a/core/java/android/os/RemoteCallbackList.java b/core/java/android/os/RemoteCallbackList.java
index d02a320..d2a9cdc 100644
--- a/core/java/android/os/RemoteCallbackList.java
+++ b/core/java/android/os/RemoteCallbackList.java
@@ -16,7 +16,7 @@
 
 package android.os;
 
-import java.util.HashMap;
+import android.util.ArrayMap;
 
 /**
  * Takes care of the grunt work of maintaining a list of remote interfaces,
@@ -47,8 +47,8 @@
  * implements the {@link #onCallbackDied} method.
  */
 public class RemoteCallbackList<E extends IInterface> {
-    /*package*/ HashMap<IBinder, Callback> mCallbacks
-            = new HashMap<IBinder, Callback>();
+    /*package*/ ArrayMap<IBinder, Callback> mCallbacks
+            = new ArrayMap<IBinder, Callback>();
     private Object[] mActiveBroadcast;
     private int mBroadcastCount = -1;
     private boolean mKilled = false;
@@ -159,7 +159,8 @@
      */
     public void kill() {
         synchronized (mCallbacks) {
-            for (Callback cb : mCallbacks.values()) {
+            for (int cbi=mCallbacks.size()-1; cbi>=0; cbi--) {
+                Callback cb = mCallbacks.valueAt(cbi);
                 cb.mCallback.asBinder().unlinkToDeath(cb, 0);
             }
             mCallbacks.clear();
@@ -238,11 +239,10 @@
             if (active == null || active.length < N) {
                 mActiveBroadcast = active = new Object[N];
             }
-            int i=0;
-            for (Callback cb : mCallbacks.values()) {
-                active[i++] = cb;
+            for (int i=0; i<N; i++) {
+                active[i] = mCallbacks.valueAt(i);
             }
-            return i;
+            return N;
         }
     }
 
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index 3267939..d794ca6 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -24,6 +24,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
+import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Printer;
 import android.util.Singleton;
@@ -31,6 +32,7 @@
 
 import com.android.internal.os.RuntimeInit;
 
+import com.android.internal.util.FastPrintWriter;
 import dalvik.system.BlockGuard;
 import dalvik.system.CloseGuard;
 import dalvik.system.VMDebug;
@@ -782,13 +784,15 @@
             BlockGuard.setThreadPolicy(BlockGuard.LAX_POLICY);
             return;
         }
-        BlockGuard.Policy policy = BlockGuard.getThreadPolicy();
-        if (!(policy instanceof AndroidBlockGuardPolicy)) {
-            BlockGuard.setThreadPolicy(new AndroidBlockGuardPolicy(policyMask));
+        final BlockGuard.Policy policy = BlockGuard.getThreadPolicy();
+        final AndroidBlockGuardPolicy androidPolicy;
+        if (policy instanceof AndroidBlockGuardPolicy) {
+            androidPolicy = (AndroidBlockGuardPolicy) policy;
         } else {
-            AndroidBlockGuardPolicy androidPolicy = (AndroidBlockGuardPolicy) policy;
-            androidPolicy.setPolicyMask(policyMask);
+            androidPolicy = threadAndroidPolicy.get();
+            BlockGuard.setThreadPolicy(androidPolicy);
         }
+        androidPolicy.setPolicyMask(policyMask);
     }
 
     // Sets up CloseGuard in Dalvik/libcore
@@ -1059,6 +1063,14 @@
         }
     };
 
+    private static final ThreadLocal<AndroidBlockGuardPolicy>
+            threadAndroidPolicy = new ThreadLocal<AndroidBlockGuardPolicy>() {
+        @Override
+        protected AndroidBlockGuardPolicy initialValue() {
+            return new AndroidBlockGuardPolicy(0);
+        }
+    };
+
     private static boolean tooManyViolationsThisLoop() {
         return violationsBeingTimed.get().size() >= MAX_OFFENSES_PER_LOOP;
     }
@@ -1069,7 +1081,7 @@
         // Map from violation stacktrace hashcode -> uptimeMillis of
         // last violation.  No locking needed, as this is only
         // accessed by the same thread.
-        private final HashMap<Integer, Long> mLastViolationTime = new HashMap<Integer, Long>();
+        private ArrayMap<Integer, Long> mLastViolationTime;
 
         public AndroidBlockGuardPolicy(final int policyMask) {
             mPolicyMask = policyMask;
@@ -1279,8 +1291,13 @@
             // Not perfect, but fast and good enough for dup suppression.
             Integer crashFingerprint = info.hashCode();
             long lastViolationTime = 0;
-            if (mLastViolationTime.containsKey(crashFingerprint)) {
-                lastViolationTime = mLastViolationTime.get(crashFingerprint);
+            if (mLastViolationTime != null) {
+                Long vtime = mLastViolationTime.get(crashFingerprint);
+                if (vtime != null) {
+                    lastViolationTime = vtime;
+                }
+            } else {
+                mLastViolationTime = new ArrayMap<Integer, Long>(1);
             }
             long now = SystemClock.uptimeMillis();
             mLastViolationTime.put(crashFingerprint, now);
@@ -1684,7 +1701,9 @@
     /* package */ static void readAndHandleBinderCallViolations(Parcel p) {
         // Our own stack trace to append
         StringWriter sw = new StringWriter();
-        new LogStackTrace().printStackTrace(new PrintWriter(sw));
+        PrintWriter pw = new FastPrintWriter(sw, false, 256);
+        new LogStackTrace().printStackTrace(pw);
+        pw.flush();
         String ourStack = sw.toString();
 
         int policyMask = getThreadPolicyMask();
diff --git a/core/java/android/os/SystemVibrator.java b/core/java/android/os/SystemVibrator.java
index e66fb285..700f80d 100644
--- a/core/java/android/os/SystemVibrator.java
+++ b/core/java/android/os/SystemVibrator.java
@@ -39,7 +39,7 @@
     }
 
     public SystemVibrator(Context context) {
-        mPackageName = context.getBasePackageName();
+        mPackageName = context.getOpPackageName();
         mService = IVibratorService.Stub.asInterface(
                 ServiceManager.getService("vibrator"));
     }
diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java
index e53cb5e..bb3d296 100644
--- a/core/java/android/os/Trace.java
+++ b/core/java/android/os/Trace.java
@@ -67,6 +67,8 @@
     public static final long TRACE_TAG_RESOURCES = 1L << 13;
     /** @hide */
     public static final long TRACE_TAG_DALVIK = 1L << 14;
+    /** @hide */
+    public static final long TRACE_TAG_RS = 1L << 15;
 
     private static final long TRACE_TAG_NOT_READY = 1L << 63;
     private static final int MAX_SECTION_NAME_LEN = 127;
diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java
index d205253..6e693a4 100644
--- a/core/java/android/os/UserHandle.java
+++ b/core/java/android/os/UserHandle.java
@@ -168,8 +168,11 @@
             if (appId >= Process.FIRST_ISOLATED_UID && appId <= Process.LAST_ISOLATED_UID) {
                 sb.append('i');
                 sb.append(appId - Process.FIRST_ISOLATED_UID);
-            } else {
+            } else if (appId >= Process.FIRST_APPLICATION_UID) {
                 sb.append('a');
+                sb.append(appId - Process.FIRST_APPLICATION_UID);
+            } else {
+                sb.append('s');
                 sb.append(appId);
             }
         }
@@ -190,8 +193,11 @@
             if (appId >= Process.FIRST_ISOLATED_UID && appId <= Process.LAST_ISOLATED_UID) {
                 pw.print('i');
                 pw.print(appId - Process.FIRST_ISOLATED_UID);
-            } else {
+            } else if (appId >= Process.FIRST_APPLICATION_UID) {
                 pw.print('a');
+                pw.print(appId - Process.FIRST_APPLICATION_UID);
+            } else {
+                pw.print('s');
                 pw.print(appId);
             }
         }
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index cb5ed4f..a3752a1 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -140,6 +140,13 @@
      */
     public static final String DISALLOW_REMOVE_USER = "no_remove_user";
 
+    /** @hide */
+    public static final int PIN_VERIFICATION_FAILED_INCORRECT = -3;
+    /** @hide */
+    public static final int PIN_VERIFICATION_FAILED_NOT_SET = -2;
+    /** @hide */
+    public static final int PIN_VERIFICATION_SUCCESS = -1;
+
     private static UserManager sInstance = null;
 
     /** @hide */
@@ -340,7 +347,18 @@
      * @param restrictionKey the string key representing the restriction
      */
     public boolean hasUserRestriction(String restrictionKey) {
-        return getUserRestrictions().getBoolean(restrictionKey, false);
+        return hasUserRestriction(restrictionKey, Process.myUserHandle());
+    }
+
+    /**
+     * @hide
+     * Returns whether the given user has been disallowed from performing certain actions
+     * or setting certain settings.
+     * @param restrictionKey the string key representing the restriction
+     * @param userHandle the UserHandle of the user for whom to retrieve the restrictions.
+     */
+    public boolean hasUserRestriction(String restrictionKey, UserHandle userHandle) {
+        return getUserRestrictions(userHandle).getBoolean(restrictionKey, false);
     }
 
     /**
@@ -620,4 +638,64 @@
             Log.w(TAG, "Could not set application restrictions for user " + user.getIdentifier());
         }
     }
+
+    /**
+     * Sets a new challenge PIN for restrictions. This is only for use by pre-installed
+     * apps and requires the MANAGE_USERS permission.
+     * @param newPin the PIN to use for challenge dialogs.
+     * @return Returns true if the challenge PIN was set successfully.
+     */
+    public boolean setRestrictionsChallenge(String newPin) {
+        try {
+            return mService.setRestrictionsChallenge(newPin);
+        } catch (RemoteException re) {
+            Log.w(TAG, "Could not change restrictions pin");
+        }
+        return false;
+    }
+
+    /**
+     * @hide
+     * @param pin The PIN to verify, or null to get the number of milliseconds to wait for before
+     * allowing the user to enter the PIN.
+     * @return Returns a positive number (including zero) for how many milliseconds before
+     * you can accept another PIN, when the input is null or the input doesn't match the saved PIN.
+     * Returns {@link #PIN_VERIFICATION_SUCCESS} if the input matches the saved PIN. Returns
+     * {@link #PIN_VERIFICATION_FAILED_NOT_SET} if there is no PIN set.
+     */
+    public int checkRestrictionsChallenge(String pin) {
+        try {
+            return mService.checkRestrictionsChallenge(pin);
+        } catch (RemoteException re) {
+            Log.w(TAG, "Could not check restrictions pin");
+        }
+        return PIN_VERIFICATION_FAILED_INCORRECT;
+    }
+
+    /**
+     * @hide
+     * Checks whether the user has restrictions that are PIN-protected. An application that
+     * participates in restrictions can check if the owner has requested a PIN challenge for
+     * any restricted operations. If there is a PIN in effect, the application should launch
+     * the PIN challenge activity {@link android.content.Intent#ACTION_RESTRICTIONS_CHALLENGE}.
+     * @see android.content.Intent#ACTION_RESTRICTIONS_CHALLENGE
+     * @return whether a restrictions PIN is in effect.
+     */
+    public boolean hasRestrictionsChallenge() {
+        try {
+            return mService.hasRestrictionsChallenge();
+        } catch (RemoteException re) {
+            Log.w(TAG, "Could not change restrictions pin");
+        }
+        return false;
+    }
+
+    /** @hide */
+    public void removeRestrictions() {
+        try {
+            mService.removeRestrictions();
+        } catch (RemoteException re) {
+            Log.w(TAG, "Could not change restrictions pin");
+        }
+    }
 }
diff --git a/core/java/android/os/WorkSource.java b/core/java/android/os/WorkSource.java
index b79bdee..30d535b 100644
--- a/core/java/android/os/WorkSource.java
+++ b/core/java/android/os/WorkSource.java
@@ -97,6 +97,16 @@
     }
 
     /**
+     * Clear names from this WorkSource.  Uids are left intact.
+     *
+     * <p>Useful when combining with another WorkSource that doesn't have names.
+     * @hide
+     */
+    public void clearNames() {
+        mNames = null;
+    }
+
+    /**
      * Clear this WorkSource to be empty.
      */
     public void clear() {
diff --git a/core/java/android/preference/ListPreference.java b/core/java/android/preference/ListPreference.java
index f44cbe4..9edf112 100644
--- a/core/java/android/preference/ListPreference.java
+++ b/core/java/android/preference/ListPreference.java
@@ -16,13 +16,13 @@
 
 package android.preference;
 
-
 import android.app.AlertDialog.Builder;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.res.TypedArray;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.text.TextUtils;
 import android.util.AttributeSet;
 
 /**
@@ -41,6 +41,7 @@
     private String mValue;
     private String mSummary;
     private int mClickedDialogEntryIndex;
+    private boolean mValueSet;
     
     public ListPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -130,9 +131,16 @@
      * @param value The value to set for the key.
      */
     public void setValue(String value) {
-        mValue = value;
-        
-        persistString(value);
+        // Always persist/notify the first time.
+        final boolean changed = !TextUtils.equals(mValue, value);
+        if (changed || !mValueSet) {
+            mValue = value;
+            mValueSet = true;
+            persistString(value);
+            if (changed) {
+                notifyChanged();
+            }
+        }
     }
 
     /**
diff --git a/core/java/android/preference/OnDependencyChangeListener.java b/core/java/android/preference/OnDependencyChangeListener.java
deleted file mode 100644
index ce25e34..0000000
--- a/core/java/android/preference/OnDependencyChangeListener.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.preference;
-
-/**
- * Interface definition for a callback to be invoked when this
- * {@link Preference} changes with respect to enabling/disabling
- * dependents.
- */
-interface OnDependencyChangeListener {
-    /**
-     * Called when this preference has changed in a way that dependents should
-     * care to change their state.
-     * 
-     * @param disablesDependent Whether the dependent should be disabled.
-     */
-    void onDependencyChanged(Preference dependency, boolean disablesDependent);
-}
diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java
index 6c02965..37a8102 100644
--- a/core/java/android/preference/Preference.java
+++ b/core/java/android/preference/Preference.java
@@ -77,7 +77,7 @@
  * @attr ref android.R.styleable#Preference_defaultValue
  * @attr ref android.R.styleable#Preference_shouldDisableView
  */
-public class Preference implements Comparable<Preference>, OnDependencyChangeListener { 
+public class Preference implements Comparable<Preference> {
     /**
      * Specify for {@link #setOrder(int)} if a specific order is not required.
      */
@@ -115,6 +115,7 @@
     private String mDependencyKey;
     private Object mDefaultValue;
     private boolean mDependencyMet = true;
+    private boolean mParentDependencyMet = true;
     
     /**
      * @see #setShouldDisableView(boolean)
@@ -123,7 +124,7 @@
     
     private int mLayoutResId = com.android.internal.R.layout.preference;
     private int mWidgetLayoutResId;
-    private boolean mHasSpecifiedLayout = false;
+    private boolean mCanRecycleLayout = true;
     
     private OnPreferenceChangeInternalListener mListener;
     
@@ -274,9 +275,10 @@
         }
         a.recycle();
 
-        if (!getClass().getName().startsWith("android.preference")) {
-            // For subclasses not in this package, assume the worst and don't cache views
-            mHasSpecifiedLayout = true;
+        if (!getClass().getName().startsWith("android.preference")
+                && !getClass().getName().startsWith("com.android")) {
+            // For non-framework subclasses, assume the worst and don't cache views.
+            mCanRecycleLayout = false;
         }
     }
     
@@ -398,7 +400,7 @@
     public void setLayoutResource(int layoutResId) {
         if (layoutResId != mLayoutResId) {
             // Layout changed
-            mHasSpecifiedLayout = true;
+            mCanRecycleLayout = false;
         }
 
         mLayoutResId = layoutResId;
@@ -414,7 +416,7 @@
     }
     
     /**
-     * Sets The layout for the controllable widget portion of this Preference. This
+     * Sets the layout for the controllable widget portion of this Preference. This
      * is inflated into the main layout. For example, a {@link CheckBoxPreference}
      * would specify a custom layout (consisting of just the CheckBox) here,
      * instead of creating its own main layout.
@@ -426,7 +428,7 @@
     public void setWidgetLayoutResource(int widgetLayoutResId) {
         if (widgetLayoutResId != mWidgetLayoutResId) {
             // Layout changed
-            mHasSpecifiedLayout = true;
+            mCanRecycleLayout = false;
         }
         mWidgetLayoutResId = widgetLayoutResId;
     }
@@ -733,7 +735,7 @@
      * @return True if this Preference is enabled, false otherwise.
      */
     public boolean isEnabled() {
-        return mEnabled && mDependencyMet;
+        return mEnabled && mDependencyMet && mParentDependencyMet;
     }
 
     /**
@@ -1259,7 +1261,24 @@
             notifyChanged();
         }
     }
-    
+
+    /**
+     * Called when the implicit parent dependency changes.
+     *
+     * @param parent The Preference that this Preference depends on.
+     * @param disableChild Set true to disable this Preference.
+     */
+    public void onParentChanged(Preference parent, boolean disableChild) {
+        if (mParentDependencyMet == disableChild) {
+            mParentDependencyMet = !disableChild;
+
+            // Enabled state can change dependent preferences' states, so notify
+            notifyDependencyChange(shouldDisableDependents());
+
+            notifyChanged();
+        }
+    }
+
     /**
      * Checks whether this preference's dependents should currently be
      * disabled.
@@ -1641,8 +1660,8 @@
         return mPreferenceManager.getSharedPreferences().getBoolean(mKey, defaultReturnValue);
     }
     
-    boolean hasSpecifiedLayout() {
-        return mHasSpecifiedLayout;
+    boolean canRecycleLayout() {
+        return mCanRecycleLayout;
     }
     
     @Override
diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java
index a9ee96e..a99705b 100644
--- a/core/java/android/preference/PreferenceActivity.java
+++ b/core/java/android/preference/PreferenceActivity.java
@@ -33,6 +33,7 @@
 import android.os.Parcelable;
 import android.text.TextUtils;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.util.TypedValue;
 import android.util.Xml;
 import android.view.LayoutInflater;
@@ -124,6 +125,8 @@
         PreferenceManager.OnPreferenceTreeClickListener,
         PreferenceFragment.OnPreferenceStartFragmentCallback {
 
+    private static final String TAG = "PreferenceActivity";
+
     // Constants for state save/restore
     private static final String HEADERS_TAG = ":android:headers";
     private static final String CUR_HEADER_TAG = ":android:cur_header";
@@ -132,6 +135,9 @@
     /**
      * When starting this activity, the invoking Intent can contain this extra
      * string to specify which fragment should be initially displayed.
+     * <p/>Starting from Key Lime Pie, when this argument is passed in, the PreferenceActivity
+     * will call isValidFragment() to confirm that the fragment class name is valid for this
+     * activity.
      */
     public static final String EXTRA_SHOW_FRAGMENT = ":android:show_fragment";
 
@@ -299,7 +305,7 @@
      * are valid.
      */
     public static final long HEADER_ID_UNDEFINED = -1;
-    
+
     /**
      * Description of a single Header item that the user can select.
      */
@@ -877,7 +883,24 @@
         } finally {
             if (parser != null) parser.close();
         }
+    }
 
+    /**
+     * Subclasses should override this method and verify that the given fragment is a valid type
+     * to be attached to this activity. The default implementation returns <code>true</code> prior
+     * to Key Lime Pie, <code>false</code> otherwise.
+     * @param fragmentName the class name of the Fragment about to be attached to this activity.
+     * @return true if the fragment class name is valid for this Activity and false otherwise.
+     */
+    protected boolean isValidFragment(String fragmentName) {
+        if (getApplicationInfo().targetSdkVersion  >= android.os.Build.VERSION_CODES.KITKAT) {
+            throw new RuntimeException(
+                    "Subclasses of PreferenceActivity must override isValidFragment(String)"
+                    + " to verify that the Fragment class is valid! " + this.getClass().getName()
+                    + " has not checked if fragment " + fragmentName + " is valid.");
+        } else {
+            return true;
+        }
     }
 
     /**
@@ -973,6 +996,9 @@
 
     @Override
     protected void onListItemClick(ListView l, View v, int position, long id) {
+        if (!isResumed()) {
+            return;
+        }
         super.onListItemClick(l, v, position, id);
 
         if (mAdapter != null) {
@@ -1083,6 +1109,7 @@
             try {
                 mFragmentBreadCrumbs = (FragmentBreadCrumbs)crumbs;
             } catch (ClassCastException e) {
+                setTitle(title);
                 return;
             }
             if (mFragmentBreadCrumbs == null) {
@@ -1096,12 +1123,17 @@
                 // Hide the breadcrumb section completely for single-pane
                 View bcSection = findViewById(com.android.internal.R.id.breadcrumb_section);
                 if (bcSection != null) bcSection.setVisibility(View.GONE);
+                setTitle(title);
             }
             mFragmentBreadCrumbs.setMaxVisible(2);
             mFragmentBreadCrumbs.setActivity(this);
         }
-        mFragmentBreadCrumbs.setTitle(title, shortTitle);
-        mFragmentBreadCrumbs.setParentTitle(null, null, null);
+        if (mFragmentBreadCrumbs.getVisibility() != View.VISIBLE) {
+            setTitle(title);
+        } else {
+            mFragmentBreadCrumbs.setTitle(title, shortTitle);
+            mFragmentBreadCrumbs.setParentTitle(null, null, null);
+        }
     }
 
     /**
@@ -1143,6 +1175,10 @@
     private void switchToHeaderInner(String fragmentName, Bundle args, int direction) {
         getFragmentManager().popBackStack(BACK_STACK_PREFS,
                 FragmentManager.POP_BACK_STACK_INCLUSIVE);
+        if (!isValidFragment(fragmentName)) {
+            throw new IllegalArgumentException("Invalid fragment for this activity: "
+                    + fragmentName);
+        }
         Fragment f = Fragment.instantiate(this, fragmentName, args);
         FragmentTransaction transaction = getFragmentManager().beginTransaction();
         transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
@@ -1249,7 +1285,7 @@
     }
 
     /**
-     * Start a new fragment containing a preference panel.  If the prefences
+     * Start a new fragment containing a preference panel.  If the preferences
      * are being displayed in multi-pane mode, the given fragment class will
      * be instantiated and placed in the appropriate pane.  If running in
      * single-pane mode, a new activity will be launched in which to show the
@@ -1288,7 +1324,7 @@
             transaction.commitAllowingStateLoss();
         }
     }
-    
+
     /**
      * Called by a preference panel fragment to finish itself.
      * 
diff --git a/core/java/android/preference/PreferenceCategory.java b/core/java/android/preference/PreferenceCategory.java
index d8af324..229a96a 100644
--- a/core/java/android/preference/PreferenceCategory.java
+++ b/core/java/android/preference/PreferenceCategory.java
@@ -62,4 +62,8 @@
         return false;
     }
     
+    @Override
+    public boolean shouldDisableDependents() {
+        return !super.isEnabled();
+    }
 }
diff --git a/core/java/android/preference/PreferenceGroup.java b/core/java/android/preference/PreferenceGroup.java
index f33a6be..5f8c78d 100644
--- a/core/java/android/preference/PreferenceGroup.java
+++ b/core/java/android/preference/PreferenceGroup.java
@@ -210,10 +210,7 @@
      * @return Whether to allow adding the preference (true), or not (false).
      */
     protected boolean onPrepareAddPreference(Preference preference) {
-        if (!super.isEnabled()) {
-            preference.setEnabled(false);
-        }
-        
+        preference.onParentChanged(this, shouldDisableDependents());
         return true;
     }
 
@@ -290,13 +287,14 @@
     }
 
     @Override
-    public void setEnabled(boolean enabled) {
-        super.setEnabled(enabled);
-        
-        // Dispatch to all contained preferences
+    public void notifyDependencyChange(boolean disableDependents) {
+        super.notifyDependencyChange(disableDependents);
+
+        // Child preferences have an implicit dependency on their containing
+        // group. Dispatch dependency change to all contained preferences.
         final int preferenceCount = getPreferenceCount();
         for (int i = 0; i < preferenceCount; i++) {
-            getPreference(i).setEnabled(enabled);
+            getPreference(i).onParentChanged(this, disableDependents);
         }
     }
     
diff --git a/core/java/android/preference/PreferenceGroupAdapter.java b/core/java/android/preference/PreferenceGroupAdapter.java
index a908ecd..23d0a19 100644
--- a/core/java/android/preference/PreferenceGroupAdapter.java
+++ b/core/java/android/preference/PreferenceGroupAdapter.java
@@ -153,7 +153,7 @@
             
             preferences.add(preference);
             
-            if (!mHasReturnedViewTypeCount && !preference.hasSpecifiedLayout()) {
+            if (!mHasReturnedViewTypeCount && preference.canRecycleLayout()) {
                 addPreferenceClassName(preference);
             }
             
@@ -255,7 +255,7 @@
         }
         
         final Preference preference = this.getItem(position);
-        if (preference.hasSpecifiedLayout()) {
+        if (!preference.canRecycleLayout()) {
             return IGNORE_ITEM_VIEW_TYPE;
         }
 
diff --git a/core/java/android/preference/TwoStatePreference.java b/core/java/android/preference/TwoStatePreference.java
index c649879..af83953 100644
--- a/core/java/android/preference/TwoStatePreference.java
+++ b/core/java/android/preference/TwoStatePreference.java
@@ -21,6 +21,7 @@
 import android.content.res.TypedArray;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.accessibility.AccessibilityEvent;
@@ -215,17 +216,17 @@
         TextView summaryView = (TextView) view.findViewById(com.android.internal.R.id.summary);
         if (summaryView != null) {
             boolean useDefaultSummary = true;
-            if (mChecked && mSummaryOn != null) {
+            if (mChecked && !TextUtils.isEmpty(mSummaryOn)) {
                 summaryView.setText(mSummaryOn);
                 useDefaultSummary = false;
-            } else if (!mChecked && mSummaryOff != null) {
+            } else if (!mChecked && !TextUtils.isEmpty(mSummaryOff)) {
                 summaryView.setText(mSummaryOff);
                 useDefaultSummary = false;
             }
 
             if (useDefaultSummary) {
                 final CharSequence summary = getSummary();
-                if (summary != null) {
+                if (!TextUtils.isEmpty(summary)) {
                     summaryView.setText(summary);
                     useDefaultSummary = false;
                 }
diff --git a/core/java/android/preference/VolumePreference.java b/core/java/android/preference/VolumePreference.java
index caf55d7..dc683a6 100644
--- a/core/java/android/preference/VolumePreference.java
+++ b/core/java/android/preference/VolumePreference.java
@@ -25,11 +25,14 @@
 import android.media.RingtoneManager;
 import android.net.Uri;
 import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Message;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.provider.Settings;
 import android.provider.Settings.System;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.view.KeyEvent;
 import android.view.View;
 import android.widget.SeekBar;
@@ -115,7 +118,7 @@
 
     public void onActivityStop() {
         if (mSeekBarVolumizer != null) {
-            mSeekBarVolumizer.stopSample();
+            mSeekBarVolumizer.postStopSample();
         }
     }
 
@@ -220,10 +223,10 @@
     /**
      * Turns a {@link SeekBar} into a volume control.
      */
-    public class SeekBarVolumizer implements OnSeekBarChangeListener, Runnable {
+    public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callback {
 
         private Context mContext;
-        private Handler mHandler = new Handler();
+        private Handler mHandler;
 
         private AudioManager mAudioManager;
         private int mStreamType;
@@ -234,6 +237,11 @@
         private SeekBar mSeekBar;
         private int mVolumeBeforeMute = -1;
 
+        private static final int MSG_SET_STREAM_VOLUME = 0;
+        private static final int MSG_START_SAMPLE = 1;
+        private static final int MSG_STOP_SAMPLE = 2;
+        private static final int CHECK_RINGTONE_PLAYBACK_DELAY_MS = 1000;
+
         private ContentObserver mVolumeObserver = new ContentObserver(mHandler) {
             @Override
             public void onChange(boolean selfChange) {
@@ -255,6 +263,10 @@
             mStreamType = streamType;
             mSeekBar = seekBar;
 
+            HandlerThread thread = new HandlerThread(TAG + ".CallbackHandler");
+            thread.start();
+            mHandler = new Handler(thread.getLooper(), this);
+
             initSeekBar(seekBar, defaultUri);
         }
 
@@ -285,8 +297,54 @@
             }
         }
 
+        @Override
+        public boolean handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_SET_STREAM_VOLUME:
+                    mAudioManager.setStreamVolume(mStreamType, mLastProgress, 0);
+                    break;
+                case MSG_START_SAMPLE:
+                    onStartSample();
+                    break;
+                case MSG_STOP_SAMPLE:
+                    onStopSample();
+                    break;
+                default:
+                    Log.e(TAG, "invalid SeekBarVolumizer message: "+msg.what);
+            }
+            return true;
+        }
+
+        private void postStartSample() {
+            mHandler.removeMessages(MSG_START_SAMPLE);
+            mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_START_SAMPLE),
+                    isSamplePlaying() ? CHECK_RINGTONE_PLAYBACK_DELAY_MS : 0);
+        }
+
+        private void onStartSample() {
+            if (!isSamplePlaying()) {
+                onSampleStarting(this);
+                if (mRingtone != null) {
+                    mRingtone.play();
+                }
+            }
+        }
+
+        private void postStopSample() {
+            // remove pending delayed start messages
+            mHandler.removeMessages(MSG_START_SAMPLE);
+            mHandler.removeMessages(MSG_STOP_SAMPLE);
+            mHandler.sendMessage(mHandler.obtainMessage(MSG_STOP_SAMPLE));
+        }
+
+        private void onStopSample() {
+            if (mRingtone != null) {
+                mRingtone.stop();
+            }
+        }
+
         public void stop() {
-            stopSample();
+            postStopSample();
             mContext.getContentResolver().unregisterContentObserver(mVolumeObserver);
             mSeekBar.setOnSeekBarChangeListener(null);
         }
@@ -307,21 +365,15 @@
         void postSetVolume(int progress) {
             // Do the volume changing separately to give responsive UI
             mLastProgress = progress;
-            mHandler.removeCallbacks(this);
-            mHandler.post(this);
+            mHandler.removeMessages(MSG_SET_STREAM_VOLUME);
+            mHandler.sendMessage(mHandler.obtainMessage(MSG_SET_STREAM_VOLUME));
         }
 
         public void onStartTrackingTouch(SeekBar seekBar) {
         }
 
         public void onStopTrackingTouch(SeekBar seekBar) {
-            if (!isSamplePlaying()) {
-                startSample();
-            }
-        }
-
-        public void run() {
-            mAudioManager.setStreamVolume(mStreamType, mLastProgress, 0);
+            postStartSample();
         }
 
         public boolean isSamplePlaying() {
@@ -329,16 +381,11 @@
         }
 
         public void startSample() {
-            onSampleStarting(this);
-            if (mRingtone != null) {
-                mRingtone.play();
-            }
+            postStartSample();
         }
 
         public void stopSample() {
-            if (mRingtone != null) {
-                mRingtone.stop();
-            }
+            postStopSample();
         }
 
         public SeekBar getSeekBar() {
@@ -347,23 +394,21 @@
 
         public void changeVolumeBy(int amount) {
             mSeekBar.incrementProgressBy(amount);
-            if (!isSamplePlaying()) {
-                startSample();
-            }
             postSetVolume(mSeekBar.getProgress());
+            postStartSample();
             mVolumeBeforeMute = -1;
         }
 
         public void muteVolume() {
             if (mVolumeBeforeMute != -1) {
                 mSeekBar.setProgress(mVolumeBeforeMute);
-                startSample();
                 postSetVolume(mVolumeBeforeMute);
+                postStartSample();
                 mVolumeBeforeMute = -1;
             } else {
                 mVolumeBeforeMute = mSeekBar.getProgress();
                 mSeekBar.setProgress(0);
-                stopSample();
+                postStopSample();
                 postSetVolume(0);
             }
         }
diff --git a/core/java/android/print/ILayoutResultCallback.aidl b/core/java/android/print/ILayoutResultCallback.aidl
new file mode 100644
index 0000000..43b8c30
--- /dev/null
+++ b/core/java/android/print/ILayoutResultCallback.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.print;
+
+import android.print.PrintDocumentInfo;
+
+/**
+ * Callback for observing the result of android.print.PrintAdapter#onLayout.
+ *
+ * @hide
+ */
+oneway interface ILayoutResultCallback {
+    void onLayoutFinished(in PrintDocumentInfo info, boolean changed, int sequence);
+    void onLayoutFailed(CharSequence error, int sequence);
+}
diff --git a/core/java/android/print/IPrintClient.aidl b/core/java/android/print/IPrintClient.aidl
new file mode 100644
index 0000000..3f39d08
--- /dev/null
+++ b/core/java/android/print/IPrintClient.aidl
@@ -0,0 +1,30 @@
+/*
+ * 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.print;
+
+import android.content.IntentSender;
+
+/**
+ * Interface for communication with a printing app.
+ *
+ * @see android.print.IPrintClientCallback
+ *
+ * @hide
+ */
+oneway interface IPrintClient {
+    void startPrintJobConfigActivity(in IntentSender intent);
+}
diff --git a/core/java/android/print/IPrintDocumentAdapter.aidl b/core/java/android/print/IPrintDocumentAdapter.aidl
new file mode 100644
index 0000000..b12c922
--- /dev/null
+++ b/core/java/android/print/IPrintDocumentAdapter.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.print;
+
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+import android.print.ILayoutResultCallback;
+import android.print.IWriteResultCallback;
+import android.print.PageRange;
+import android.print.PrintAttributes;
+
+/**
+ * Interface for communication with the print adapter object.
+ *
+ * @hide
+ */
+oneway interface IPrintDocumentAdapter {
+    void start();
+    void layout(in PrintAttributes oldAttributes, in PrintAttributes newAttributes,
+            ILayoutResultCallback callback, in Bundle metadata, int sequence);
+    void write(in PageRange[] pages, in ParcelFileDescriptor fd,
+            IWriteResultCallback callback, int sequence);
+    void finish();
+}
diff --git a/core/java/android/print/IPrintManager.aidl b/core/java/android/print/IPrintManager.aidl
new file mode 100644
index 0000000..d2ae5e6f
--- /dev/null
+++ b/core/java/android/print/IPrintManager.aidl
@@ -0,0 +1,52 @@
+/*
+ * 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.print;
+
+import android.print.IPrinterDiscoveryObserver;
+import android.print.IPrintDocumentAdapter;
+import android.print.IPrintClient;
+import android.print.PrinterId;
+import android.print.PrintJobInfo;
+import android.print.PrintAttributes;
+import android.printservice.PrintServiceInfo;
+
+/**
+ * Interface for communication with the core print manager service.
+ *
+ * @hide
+ */
+interface IPrintManager {
+    List<PrintJobInfo> getPrintJobInfos(int appId, int userId);
+    PrintJobInfo getPrintJobInfo(int printJobId, int appId, int userId);
+    PrintJobInfo print(String printJobName, in IPrintClient client,
+            in IPrintDocumentAdapter printAdapter, in PrintAttributes attributes,
+            int appId, int userId);
+    void cancelPrintJob(int printJobId, int appId, int userId);
+    void restartPrintJob(int printJobId, int appId, int userId);
+
+    List<PrintServiceInfo> getEnabledPrintServices(int userId);
+
+    void createPrinterDiscoverySession(in IPrinterDiscoveryObserver observer, int userId);
+    void startPrinterDiscovery(in IPrinterDiscoveryObserver observer,
+            in List<PrinterId> priorityList, int userId);
+    void stopPrinterDiscovery(in IPrinterDiscoveryObserver observer, int userId);
+    void validatePrinters(in List<PrinterId> printerIds, int userId);
+    void startPrinterStateTracking(in PrinterId printerId, int userId);
+    void stopPrinterStateTracking(in PrinterId printerId, int userId);
+    void destroyPrinterDiscoverySession(in IPrinterDiscoveryObserver observer,
+            int userId);
+}
diff --git a/core/java/android/print/IPrintSpooler.aidl b/core/java/android/print/IPrintSpooler.aidl
new file mode 100644
index 0000000..0a77dab
--- /dev/null
+++ b/core/java/android/print/IPrintSpooler.aidl
@@ -0,0 +1,49 @@
+/*
+ * 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.print;
+
+import android.content.ComponentName;
+import android.os.ParcelFileDescriptor;
+import android.print.IPrintDocumentAdapter;
+import android.print.IPrintClient;
+import android.print.IPrintSpoolerClient;
+import android.print.IPrintSpoolerCallbacks;
+import android.print.PrinterInfo;
+import android.print.PrintAttributes;
+
+/**
+ * Interface for communication with the print spooler service.
+ *
+ * @see android.print.IPrintSpoolerCallbacks
+ *
+ * @hide
+ */
+oneway interface IPrintSpooler {
+    void getPrintJobInfos(IPrintSpoolerCallbacks callback, in ComponentName componentName,
+            int state, int appId, int sequence);
+    void getPrintJobInfo(int printJobId, IPrintSpoolerCallbacks callback,
+            int appId, int sequence);
+    void createPrintJob(String printJobName, in IPrintClient client,
+            in IPrintDocumentAdapter printAdapter, in PrintAttributes attributes,
+            IPrintSpoolerCallbacks callback, int appId, int sequence);
+    void setPrintJobState(int printJobId, int status, String error,
+            IPrintSpoolerCallbacks callback, int sequence);
+    void setPrintJobTag(int printJobId, String tag, IPrintSpoolerCallbacks callback,
+            int sequence);
+    void writePrintJobData(in ParcelFileDescriptor fd, int printJobId);
+    void setClient(IPrintSpoolerClient client);
+}
diff --git a/core/java/android/print/IPrintSpoolerCallbacks.aidl b/core/java/android/print/IPrintSpoolerCallbacks.aidl
new file mode 100644
index 0000000..51b5439
--- /dev/null
+++ b/core/java/android/print/IPrintSpoolerCallbacks.aidl
@@ -0,0 +1,36 @@
+/*
+ * 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.print;
+
+import android.print.PrintJobInfo;
+import java.util.List;
+
+/**
+ * Callbacks for communication with the print spooler service.
+ *
+ * @see android.print.IPrintSpoolerService
+ *
+ * @hide
+ */
+oneway interface IPrintSpoolerCallbacks {
+    void onGetPrintJobInfosResult(in List<PrintJobInfo> printJob, int sequence);
+    void onCreatePrintJobResult(in PrintJobInfo printJob, int sequence);
+    void onCancelPrintJobResult(boolean canceled, int sequence);
+    void onSetPrintJobStateResult(boolean success, int sequence);
+    void onSetPrintJobTagResult(boolean success, int sequence);
+    void onGetPrintJobInfoResult(in PrintJobInfo printJob, int sequence);
+}
diff --git a/core/java/android/print/IPrintSpoolerClient.aidl b/core/java/android/print/IPrintSpoolerClient.aidl
new file mode 100644
index 0000000..8b511d6
--- /dev/null
+++ b/core/java/android/print/IPrintSpoolerClient.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.print;
+
+import android.content.ComponentName;
+import android.print.PrintJobInfo;
+
+
+/**
+ * Interface for receiving interesting state updates from the print spooler.
+ *
+ * @hide
+ */
+oneway interface IPrintSpoolerClient {
+    void onPrintJobQueued(in PrintJobInfo printJob);
+    void onAllPrintJobsForServiceHandled(in ComponentName printService);
+    void onAllPrintJobsHandled();
+}
diff --git a/core/java/android/print/IPrinterDiscoveryObserver.aidl b/core/java/android/print/IPrinterDiscoveryObserver.aidl
new file mode 100644
index 0000000..b558011
--- /dev/null
+++ b/core/java/android/print/IPrinterDiscoveryObserver.aidl
@@ -0,0 +1,30 @@
+/*
+ * 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.print;
+
+import android.print.PrinterId;
+import android.print.PrinterInfo;
+
+/**
+ * Interface for observing discovered printers by a discovery session.
+ *
+ * @hide
+ */
+oneway interface IPrinterDiscoveryObserver {
+    void onPrintersAdded(in List<PrinterInfo> printers);
+    void onPrintersRemoved(in List<PrinterId> printerIds);
+}
diff --git a/core/java/android/print/IWriteResultCallback.aidl b/core/java/android/print/IWriteResultCallback.aidl
new file mode 100644
index 0000000..8281c4e
--- /dev/null
+++ b/core/java/android/print/IWriteResultCallback.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.print;
+
+import android.print.PageRange;
+
+/**
+ * Callback for observing the result of android.print.DocuemntAdapter#onWrite.
+ *
+ * @hide
+ */
+oneway interface IWriteResultCallback {
+    void onWriteFinished(in PageRange[] pages, int sequence);
+    void onWriteFailed(CharSequence error, int sequence);
+}
diff --git a/core/java/android/print/PageRange.aidl b/core/java/android/print/PageRange.aidl
new file mode 100644
index 0000000..b1ae14f
--- /dev/null
+++ b/core/java/android/print/PageRange.aidl
@@ -0,0 +1,19 @@
+/**
+ * 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.print;
+
+parcelable PageRange;
diff --git a/core/java/android/print/PageRange.java b/core/java/android/print/PageRange.java
new file mode 100644
index 0000000..cdcd0c7
--- /dev/null
+++ b/core/java/android/print/PageRange.java
@@ -0,0 +1,149 @@
+/*
+ * 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.print;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Represents a range of pages. The start and end page indices of
+ * the range are zero based and inclusive.
+ */
+public final class PageRange implements Parcelable {
+
+    /**
+     * Constant for specifying all pages.
+     */
+    public static final PageRange ALL_PAGES = new PageRange(0, Integer.MAX_VALUE);
+
+    private final int mStart;
+    private final int mEnd;
+
+    /**
+     * Creates a new instance.
+     *
+     * @param start The start page index (zero based and inclusive).
+     * @param end The end page index (zero based and inclusive).
+     *
+     * @throws IllegalArgumentException If start is less than zero.
+     * @throws IllegalArgumentException If end is less than zero.
+     * @throws IllegalArgumentException If start greater than end.
+     */
+    public PageRange(int start, int end) {
+        if (start < 0) {
+            throw new IllegalArgumentException("start cannot be less than zero.");
+        }
+        if (end < 0) {
+            throw new IllegalArgumentException("end cannot be less than zero.");
+        }
+        if (start > end) {
+            throw new IllegalArgumentException("start must be lesser than end.");
+        }
+        mStart = start;
+        mEnd = end;
+    }
+
+    private PageRange (Parcel parcel) {
+        this(parcel.readInt(), parcel.readInt());
+    }
+
+    /**
+     * Gets the start page index (zero based and inclusive).
+     *
+     * @return The start page index.
+     */
+    public int getStart() {
+        return mStart;
+    }
+
+    /**
+     * Gets the end page index (zero based and inclusive).
+     *
+     * @return The end page index.
+     */
+    public int getEnd() {
+        return mEnd;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeInt(mStart);
+        parcel.writeInt(mEnd);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + mEnd;
+        result = prime * result + mStart;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        PageRange other = (PageRange) obj;
+        if (mEnd != other.mEnd) {
+            return false;
+        }
+        if (mStart != other.mStart) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        if (mStart == 0 && mEnd == Integer.MAX_VALUE) {
+            return "PageRange[<all pages>]";
+        }
+        StringBuilder builder = new StringBuilder();
+        builder.append("PageRange[")
+            .append(mStart)
+            .append(" - ")
+            .append(mEnd)
+            .append("]");
+        return builder.toString();
+    }
+
+    public static final Parcelable.Creator<PageRange> CREATOR =
+            new Creator<PageRange>() {
+        @Override
+        public PageRange createFromParcel(Parcel parcel) {
+            return new PageRange(parcel);
+        }
+
+        @Override
+        public PageRange[] newArray(int size) {
+            return new PageRange[size];
+        }
+    };
+}
diff --git a/core/java/android/print/PrintAttributes.aidl b/core/java/android/print/PrintAttributes.aidl
new file mode 100644
index 0000000..0b765a2
--- /dev/null
+++ b/core/java/android/print/PrintAttributes.aidl
@@ -0,0 +1,19 @@
+/**
+ * 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.print;
+
+parcelable PrintAttributes;
diff --git a/core/java/android/print/PrintAttributes.java b/core/java/android/print/PrintAttributes.java
new file mode 100644
index 0000000..d889353
--- /dev/null
+++ b/core/java/android/print/PrintAttributes.java
@@ -0,0 +1,1013 @@
+/*
+ * 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.print;
+
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Resources.NotFoundException;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.R;
+
+/**
+ * This class represents the attributes of a print job.
+ */
+public final class PrintAttributes implements Parcelable {
+
+    /** Color mode: Monochrome color scheme, e.g. one color is used. */
+    public static final int COLOR_MODE_MONOCHROME = 1 << 0;
+    /** Color mode: Color color scheme, e.g. many colors are used. */
+    public static final int COLOR_MODE_COLOR = 1 << 1;
+
+    private static final int VALID_COLOR_MODES =
+            COLOR_MODE_MONOCHROME | COLOR_MODE_COLOR;
+
+    private MediaSize mMediaSize;
+    private Resolution mResolution;
+    private Margins mMinMargins;
+
+    private int mColorMode;
+
+    PrintAttributes() {
+        /* hide constructor */
+    }
+
+    private PrintAttributes(Parcel parcel) {
+        mMediaSize = (parcel.readInt() ==  1) ? MediaSize.createFromParcel(parcel) : null;
+        mResolution = (parcel.readInt() ==  1) ? Resolution.createFromParcel(parcel) : null;
+        mMinMargins = (parcel.readInt() ==  1) ? Margins.createFromParcel(parcel) : null;
+        mColorMode = parcel.readInt();
+    }
+
+    /**
+     * Gets the media size.
+     *
+     * @return The media size or <code>null</code> if not set.
+     */
+    public MediaSize getMediaSize() {
+        return mMediaSize;
+    }
+
+    /**
+     * Sets the media size.
+     *
+     * @param The media size.
+     *
+     * @hide
+     */
+    public void setMediaSize(MediaSize mediaSize) {
+        mMediaSize = mediaSize;
+    }
+
+    /**
+     * Gets the resolution.
+     *
+     * @return The resolution or <code>null</code> if not set.
+     */
+    public Resolution getResolution() {
+        return mResolution;
+    }
+
+    /**
+     * Sets the resolution.
+     *
+     * @param The resolution.
+     *
+     * @hide
+     */
+    public void setResolution(Resolution resolution) {
+        mResolution = resolution;
+    }
+
+    /**
+     * Gets the minimal margins. If the content does not fit
+     * these margins it will be clipped.
+     *
+     * @return The margins or <code>null</code> if not set.
+     */
+    public Margins getMinMargins() {
+        return mMinMargins;
+    }
+
+    /**
+     * Sets the minimal margins. If the content does not fit
+     * these margins it will be clipped.
+     *
+     * @param The margins.
+     *
+     * @hide
+     */
+    public void setMinMargins(Margins margins) {
+        mMinMargins = margins;
+    }
+
+    /**
+     * Gets the color mode.
+     *
+     * @return The color mode or zero if not set.
+     *
+     * @see #COLOR_MODE_COLOR
+     * @see #COLOR_MODE_MONOCHROME
+     */
+    public int getColorMode() {
+        return mColorMode;
+    }
+
+    /**
+     * Sets the color mode.
+     *
+     * @param The color mode.
+     *
+     * @see #COLOR_MODE_MONOCHROME
+     * @see #COLOR_MODE_COLOR
+     *
+     * @hide
+     */
+    public void setColorMode(int colorMode) {
+        enforceValidColorMode(colorMode);
+        mColorMode = colorMode;
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        if (mMediaSize != null) {
+            parcel.writeInt(1);
+            mMediaSize.writeToParcel(parcel);
+        } else {
+            parcel.writeInt(0);
+        }
+        if (mResolution != null) {
+            parcel.writeInt(1);
+            mResolution.writeToParcel(parcel);
+        } else {
+            parcel.writeInt(0);
+        }
+        if (mMinMargins != null) {
+            parcel.writeInt(1);
+            mMinMargins.writeToParcel(parcel);
+        } else {
+            parcel.writeInt(0);
+        }
+        parcel.writeInt(mColorMode);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + mColorMode;
+        result = prime * result + ((mMinMargins == null) ? 0 : mMinMargins.hashCode());
+        result = prime * result + ((mMediaSize == null) ? 0 : mMediaSize.hashCode());
+        result = prime * result + ((mResolution == null) ? 0 : mResolution.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        PrintAttributes other = (PrintAttributes) obj;
+        if (mColorMode != other.mColorMode) {
+            return false;
+        }
+        if (mMinMargins == null) {
+            if (other.mMinMargins != null) {
+                return false;
+            }
+        } else if (!mMinMargins.equals(other.mMinMargins)) {
+            return false;
+        }
+        if (mMediaSize == null) {
+            if (other.mMediaSize != null) {
+                return false;
+            }
+        } else if (!mMediaSize.equals(other.mMediaSize)) {
+            return false;
+        }
+        if (mResolution == null) {
+            if (other.mResolution != null) {
+                return false;
+            }
+        } else if (!mResolution.equals(other.mResolution)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("PrintAttributes{");
+        builder.append("mediaSize: ").append(mMediaSize);
+        if (mMediaSize != null) {
+            builder.append(", orientation: ").append(mMediaSize.isPortrait()
+                    ? "portrait" : "landscape");
+        } else {
+            builder.append(", orientation: ").append("null");
+        }
+        builder.append(", resolution: ").append(mResolution);
+        builder.append(", minMargins: ").append(mMinMargins);
+        builder.append(", colorMode: ").append(colorModeToString(mColorMode));
+        builder.append("}");
+        return builder.toString();
+    }
+
+    /** hide */
+    public void clear() {
+        mMediaSize = null;
+        mResolution = null;
+        mMinMargins = null;
+        mColorMode = 0;
+    }
+
+    /**
+     * @hide
+     */
+    public void copyFrom(PrintAttributes other) {
+        mMediaSize = other.mMediaSize;
+        mResolution = other.mResolution;
+        mMinMargins = other.mMinMargins;
+        mColorMode = other.mColorMode;
+    }
+
+    /**
+     * This class specifies a supported media size.
+     */
+    public static final class MediaSize {
+        private static final String LOG_TAG = "MediaSize";
+
+        // TODO: Verify media sizes and add more standard ones.
+
+        // ISO sizes
+
+        /** ISO A0 media size: 841mm x 1189mm (33.11" x 46.81") */
+        public static final MediaSize ISO_A0 =
+                new MediaSize("ISO_A0", "android", R.string.mediaSize_iso_a0, 33110, 46810);
+        /** ISO A1 media size: 594mm x 841mm (23.39" x 33.11") */
+        public static final MediaSize ISO_A1 =
+                new MediaSize("ISO_A1", "android", R.string.mediaSize_iso_a1, 23390, 33110);
+        /** ISO A2 media size: 420mm x 594mm (16.54" x 23.39") */
+        public static final MediaSize ISO_A2 =
+                new MediaSize("ISO_A2", "android", R.string.mediaSize_iso_a2, 16540, 23390);
+        /** ISO A3 media size: 297mm x 420mm (11.69" x 16.54") */
+        public static final MediaSize ISO_A3 =
+                new MediaSize("ISO_A3", "android", R.string.mediaSize_iso_a3, 11690, 16540);
+        /** ISO A4 media size: 210mm x 297mm (8.27" x 11.69") */
+        public static final MediaSize ISO_A4 =
+                new MediaSize("ISO_A4", "android", R.string.mediaSize_iso_a4, 8270, 11690);
+        /** ISO A5 media size: 148mm x 210mm (5.83" x 8.27") */
+        public static final MediaSize ISO_A5 =
+                new MediaSize("ISO_A5", "android", R.string.mediaSize_iso_a5, 5830, 8270);
+        /** ISO A6 media size: 105mm x 148mm (4.13" x 5.83") */
+        public static final MediaSize ISO_A6 =
+                new MediaSize("ISO_A6", "android", R.string.mediaSize_iso_a6, 4130, 5830);
+        /** ISO A7 media size: 74mm x 105mm (2.91" x 4.13") */
+        public static final MediaSize ISO_A7 =
+                new MediaSize("ISO_A7", "android", R.string.mediaSize_iso_a7, 2910, 4130);
+        /** ISO A8 media size: 52mm x 74mm (2.05" x 2.91") */
+        public static final MediaSize ISO_A8 =
+                new MediaSize("ISO_A8", "android", R.string.mediaSize_iso_a8, 2050, 2910);
+        /** ISO A9 media size: 37mm x 52mm (1.46" x 2.05") */
+        public static final MediaSize ISO_A9 =
+                new MediaSize("ISO_A9", "android", R.string.mediaSize_iso_a9, 1460, 2050);
+        /** ISO A10 media size: 26mm x 37mm (1.02" x 1.46") */
+        public static final MediaSize ISO_A10 =
+                new MediaSize("ISO_A10", "android", R.string.mediaSize_iso_a10, 1020, 1460);
+
+        /** ISO B0 media size: 1000mm x 1414mm (39.37" x 55.67") */
+        public static final MediaSize ISO_B0 =
+                new MediaSize("ISO_B0", "android", R.string.mediaSize_iso_b0, 39370, 55670);
+        /** ISO B1 media size: 707mm x 1000mm (27.83" x 39.37") */
+        public static final MediaSize ISO_B1 =
+                new MediaSize("ISO_B1", "android", R.string.mediaSize_iso_b1, 27830, 39370);
+        /** ISO B2 media size: 500mm x 707mm (19.69" x 27.83") */
+        public static final MediaSize ISO_B2 =
+                new MediaSize("ISO_B2", "android", R.string.mediaSize_iso_b2, 19690, 27830);
+        /** ISO B3 media size: 353mm x 500mm (13.90" x 19.69") */
+        public static final MediaSize ISO_B3 =
+                new MediaSize("ISO_B3", "android", R.string.mediaSize_iso_b3, 13900, 19690);
+        /** ISO B4 media size: 250mm x 353mm (9.84" x 13.90") */
+        public static final MediaSize ISO_B4 =
+                new MediaSize("ISO_B4", "android", R.string.mediaSize_iso_b4, 9840, 13900);
+        /** ISO B5 media size: 176mm x 250mm (6.93" x 9.84") */
+        public static final MediaSize ISO_B5 =
+                new MediaSize("ISO_B5", "android", R.string.mediaSize_iso_b5, 6930, 9840);
+        /** ISO B6 media size: 125mm x 176mm (4.92" x 6.93") */
+        public static final MediaSize ISO_B6 =
+                new MediaSize("ISO_B6", "android", R.string.mediaSize_iso_b6, 4920, 6930);
+        /** ISO B7 media size: 88mm x 125mm (3.46" x 4.92") */
+        public static final MediaSize ISO_B7 =
+                new MediaSize("ISO_B7", "android", R.string.mediaSize_iso_b7, 3460, 4920);
+        /** ISO B8 media size: 62mm x 88mm (2.44" x 3.46") */
+        public static final MediaSize ISO_B8 =
+                new MediaSize("ISO_B8", "android", R.string.mediaSize_iso_b8, 2440, 3460);
+        /** ISO B9 media size: 44mm x 62mm (1.73" x 2.44") */
+        public static final MediaSize ISO_B9 =
+                new MediaSize("ISO_B9", "android", R.string.mediaSize_iso_b9, 1730, 2440);
+        /** ISO B10 media size: 31mm x 44mm (1.22" x 1.73") */
+        public static final MediaSize ISO_B10 =
+                new MediaSize("ISO_B10", "android", R.string.mediaSize_iso_b10, 1220, 1730);
+
+        /** ISO C0 media size: 917mm x 1297mm (36.10" x 51.06") */
+        public static final MediaSize ISO_C0 =
+                new MediaSize("ISO_C0", "android", R.string.mediaSize_iso_c0, 36100, 51060);
+        /** ISO C1 media size: 648mm x 917mm (25.51" x 36.10") */
+        public static final MediaSize ISO_C1 =
+                new MediaSize("ISO_C1", "android", R.string.mediaSize_iso_c1, 25510, 36100);
+        /** ISO C2 media size: 458mm x 648mm (18.03" x 25.51") */
+        public static final MediaSize ISO_C2 =
+                new MediaSize("ISO_C2", "android", R.string.mediaSize_iso_c2, 18030, 25510);
+        /** ISO C3 media size: 324mm x 458mm (12.76" x 18.03") */
+        public static final MediaSize ISO_C3 =
+                new MediaSize("ISO_C3", "android", R.string.mediaSize_iso_c3, 12760, 18030);
+        /** ISO C4 media size: 229mm x 324mm (9.02" x 12.76") */
+        public static final MediaSize ISO_C4 =
+                new MediaSize("ISO_C4", "android", R.string.mediaSize_iso_c4, 9020, 12760);
+        /** ISO C5 media size: 162mm x 229mm (6.38" x 9.02") */
+        public static final MediaSize ISO_C5 =
+                new MediaSize("ISO_C5", "android", R.string.mediaSize_iso_c5, 6380, 9020);
+        /** ISO C6 media size: 114mm x 162mm (4.49" x 6.38") */
+        public static final MediaSize ISO_C6 =
+                new MediaSize("ISO_C6", "android", R.string.mediaSize_iso_c6, 4490, 6380);
+        /** ISO C7 media size: 81mm x 114mm (3.19" x 4.49") */
+        public static final MediaSize ISO_C7 =
+                new MediaSize("ISO_C7", "android", R.string.mediaSize_iso_c7, 3190, 4490);
+        /** ISO C8 media size: 57mm x 81mm (2.24" x 3.19") */
+        public static final MediaSize ISO_C8 =
+                new MediaSize("ISO_C8", "android", R.string.mediaSize_iso_c8, 2240, 3190);
+        /** ISO C9 media size: 40mm x 57mm (1.57" x 2.24") */
+        public static final MediaSize ISO_C9 =
+                new MediaSize("ISO_C9", "android", R.string.mediaSize_iso_c9, 1570, 2240);
+        /** ISO C10 media size: 28mm x 40mm (1.10" x 1.57") */
+        public static final MediaSize ISO_C10 =
+                new MediaSize("ISO_C10", "android", R.string.mediaSize_iso_c10, 1100, 1570);
+
+        // North America
+
+        /** North America Letter media size: 8.5" x 11" */
+        public static final MediaSize NA_LETTER =
+                new MediaSize("NA_LETTER", "android", R.string.mediaSize_na_letter, 8500, 11000);
+        /** North America Government-Letter media size: 8.0" x 10.5" */
+        public static final MediaSize NA_GOVT_LETTER =
+                new MediaSize("NA_GOVT_LETTER", "android",
+                        R.string.mediaSize_na_gvrnmt_letter, 8000, 10500);
+        /** North America Legal media size: 8.5" x 14" */
+        public static final MediaSize NA_LEGAL =
+                new MediaSize("NA_LEGAL", "android", R.string.mediaSize_na_legal, 8500, 14000);
+        /** North America Junior Legal media size: 8.0" x 5.0" */
+        public static final MediaSize NA_JUNIOR_LEGAL =
+                new MediaSize("NA_JUNIOR_LEGAL", "android",
+                        R.string.mediaSize_na_junior_legal, 8000, 5000);
+        /** North America Ledger media size: 17" x 11" */
+        public static final MediaSize NA_LEDGER =
+                new MediaSize("NA_LEDGER", "android", R.string.mediaSize_na_ledger, 17000, 11000);
+        /** North America Tabloid media size: 11" x 17" */
+        public static final MediaSize NA_TBLOID =
+                new MediaSize("NA_TABLOID", "android",
+                        R.string.mediaSize_na_tabloid, 11000, 17000);
+
+        private final String mId;
+        /**@hide */
+        public final String mLabel;
+        /**@hide */
+        public final String mPackageName;
+        /**@hide */
+        public final int mLabelResId;
+        private final int mWidthMils;
+        private final int mHeightMils;
+
+        /**
+         * Creates a new instance. This is the preferred constructor since
+         * it enables the media size label to be shown in a localized fashion
+         * on a locale change.
+         *
+         * @param id The unique media size id.
+         * @param packageName The name of the creating package.
+         * @param labelResId The resource if of a human readable label.
+         * @param widthMils The width in mils (thousands of an inch).
+         * @param heightMils The height in mils (thousands of an inch).
+         *
+         * @throws IllegalArgumentException If the id is empty.
+         * @throws IllegalArgumentException If the label is empty.
+         * @throws IllegalArgumentException If the widthMils is less than or equal to zero.
+         * @throws IllegalArgumentException If the heightMils is less than or equal to zero.
+         *
+         * @hide
+         */
+        public MediaSize(String id, String packageName, int labelResId,
+                int widthMils, int heightMils) {
+            if (TextUtils.isEmpty(id)) {
+                throw new IllegalArgumentException("id cannot be empty.");
+            }
+            if (TextUtils.isEmpty(packageName)) {
+                throw new IllegalArgumentException("packageName cannot be empty.");
+            }
+            if (labelResId <= 0) {
+                throw new IllegalArgumentException("labelResId must be greater than zero.");
+            }
+            if (widthMils <= 0) {
+                throw new IllegalArgumentException("widthMils "
+                        + "cannot be less than or equal to zero.");
+            }
+            if (heightMils <= 0) {
+                throw new IllegalArgumentException("heightMils "
+                       + "cannot be less than or euqual to zero.");
+            }
+            mPackageName = packageName;
+            mId = id;
+            mLabelResId = labelResId;
+            mWidthMils = widthMils;
+            mHeightMils = heightMils;
+            mLabel = null;
+        }
+
+        /**
+         * Creates a new instance.
+         *
+         * @param id The unique media size id.
+         * @param label The <strong>internationalized</strong> human readable label.
+         * @param widthMils The width in mils (thousands of an inch).
+         * @param heightMils The height in mils (thousands of an inch).
+         *
+         * @throws IllegalArgumentException If the id is empty.
+         * @throws IllegalArgumentException If the label is empty.
+         * @throws IllegalArgumentException If the widthMils is less than or equal to zero.
+         * @throws IllegalArgumentException If the heightMils is less than or equal to zero.
+         */
+        public MediaSize(String id, String label, int widthMils, int heightMils) {
+            if (TextUtils.isEmpty(id)) {
+                throw new IllegalArgumentException("id cannot be empty.");
+            }
+            if (TextUtils.isEmpty(label)) {
+                throw new IllegalArgumentException("label cannot be empty.");
+            }
+            if (widthMils <= 0) {
+                throw new IllegalArgumentException("widthMils "
+                        + "cannot be less than or equal to zero.");
+            }
+            if (heightMils <= 0) {
+                throw new IllegalArgumentException("heightMils "
+                       + "cannot be less than or euqual to zero.");
+            }
+            mId = id;
+            mLabel = label;
+            mWidthMils = widthMils;
+            mHeightMils = heightMils;
+            mLabelResId = 0;
+            mPackageName = null;
+        }
+
+        /** @hide */
+        public MediaSize(String id, String label, String packageName,
+                int widthMils, int heightMils, int labelResId) {
+            mPackageName = packageName;
+            mId = id;
+            mLabelResId = labelResId;
+            mWidthMils = widthMils;
+            mHeightMils = heightMils;
+            mLabel = label;
+        }
+
+        /**
+         * Gets the unique media size id.
+         *
+         * @return The unique media size id.
+         */
+        public String getId() {
+            return mId;
+        }
+
+        /**
+         * Gets the human readable media size label.
+         *
+         * @param packageManager The package manager for loading the label.
+         * @return The human readable label.
+         */
+        public String getLabel(PackageManager packageManager) {
+            if (!TextUtils.isEmpty(mPackageName) && mLabelResId > 0) {
+                try {
+                    return packageManager.getResourcesForApplication(
+                            mPackageName).getString(mLabelResId);
+                } catch (NotFoundException nfe) {
+                    Log.w(LOG_TAG, "Could not load resouce" + mLabelResId
+                            + " from package " + mPackageName);
+                } catch (NameNotFoundException nnfee) {
+                    Log.w(LOG_TAG, "Could not load resouce" + mLabelResId
+                            + " from package " + mPackageName);
+                }
+            }
+            return mLabel;
+        }
+
+        /**
+         * Gets the media width in mils (thousands of an inch).
+         *
+         * @return The media width.
+         */
+        public int getWidthMils() {
+            return mWidthMils;
+        }
+
+        /**
+         * Gets the media height in mils (thousands of an inch).
+         *
+         * @return The media height.
+         */
+        public int getHeightMils() {
+            return mHeightMils;
+        }
+
+        /**
+         * Gets whether this media size is in portrait which is the
+         * height is greater or equal to the width.
+         *
+         * @return True if the media size is in portrait, false if
+         * it is in landscape.
+         */
+        public boolean isPortrait() {
+            return mHeightMils >= mWidthMils;
+        }
+
+        /**
+         * Returns a new media size in a portrait orientation
+         * which is the height is the greater dimension.
+         *
+         * @return New instance in landscape orientation.
+         */
+        public MediaSize asPortrait() {
+            return new MediaSize(mId, mLabel, mPackageName,
+                    Math.min(mWidthMils, mHeightMils),
+                    Math.max(mWidthMils, mHeightMils),
+                    mLabelResId);
+        }
+
+        /**
+         * Returns a new media size in a landscape orientation
+         * which is the height is the lesser dimension.
+         *
+         * @return New instance in landscape orientation.
+         */
+        public MediaSize asLandscape() {
+            return new MediaSize(mId, mLabel, mPackageName,
+                    Math.max(mWidthMils, mHeightMils),
+                    Math.min(mWidthMils, mHeightMils),
+                    mLabelResId);
+        }
+
+        void writeToParcel(Parcel parcel) {
+            parcel.writeString(mId);
+            parcel.writeString(mLabel);
+            parcel.writeString(mPackageName);
+            parcel.writeInt(mWidthMils);
+            parcel.writeInt(mHeightMils);
+            parcel.writeInt(mLabelResId);
+        }
+
+        static MediaSize createFromParcel(Parcel parcel) {
+            return new MediaSize(
+                    parcel.readString(),
+                    parcel.readString(),
+                    parcel.readString(),
+                    parcel.readInt(),
+                    parcel.readInt(),
+                    parcel.readInt());
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + mWidthMils;
+            result = prime * result + mHeightMils;
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj == null) {
+                return false;
+            }
+            if (getClass() != obj.getClass()) {
+                return false;
+            }
+            MediaSize other = (MediaSize) obj;
+            if (mWidthMils != other.mWidthMils) {
+                return false;
+            }
+            if (mHeightMils != other.mHeightMils) {
+                return false;
+            }
+            return true;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder builder = new StringBuilder();
+            builder.append("MediaSize{");
+            builder.append("id: ").append(mId);
+            builder.append(", label: ").append(mLabel);
+            builder.append(", packageName: ").append(mPackageName);
+            builder.append(", heightMils: ").append(mHeightMils);
+            builder.append(", widthMils: ").append(mWidthMils);
+            builder.append(", labelResId: ").append(mLabelResId);
+            builder.append("}");
+            return builder.toString();
+        }
+    }
+
+    /**
+     * This class specifies a supported resolution in dpi (dots per inch).
+     */
+    public static final class Resolution {
+        private final String mId;
+        private final String mLabel;
+        private final int mHorizontalDpi;
+        private final int mVerticalDpi;
+
+        /**
+         * Creates a new instance.
+         *
+         * @param id The unique resolution id.
+         * @param label The <strong>internationalized</strong> human readable label.
+         * @param horizontalDpi The horizontal resolution in dpi.
+         * @param verticalDpi The vertical resolution in dpi.
+         *
+         * @throws IllegalArgumentException If the id is empty.
+         * @throws IllegalArgumentException If the label is empty.
+         * @throws IllegalArgumentException If the horizontalDpi is less than or equal to zero.
+         * @throws IllegalArgumentException If the verticalDpi is less than or equal to zero.
+         */
+        public Resolution(String id, String label, int horizontalDpi, int verticalDpi) {
+            if (TextUtils.isEmpty(id)) {
+                throw new IllegalArgumentException("id cannot be empty.");
+            }
+            if (TextUtils.isEmpty(label)) {
+                throw new IllegalArgumentException("label cannot be empty.");
+            }
+            if (horizontalDpi <= 0) {
+                throw new IllegalArgumentException("horizontalDpi "
+                        + "cannot be less than or equal to zero.");
+            }
+            if (verticalDpi <= 0) {
+                throw new IllegalArgumentException("verticalDpi"
+                       + " cannot be less than or equal to zero.");
+            }
+            mId = id;
+            mLabel = label;
+            mHorizontalDpi = horizontalDpi;
+            mVerticalDpi = verticalDpi;
+        }
+
+        /**
+         * Gets the unique resolution id.
+         *
+         * @return The unique resolution id.
+         */
+        public String getId() {
+            return mId;
+        }
+
+        /**
+         * Gets the resolution human readable label.
+         *
+         * @return The human readable label.
+         */
+        public String getLabel() {
+            return mLabel;
+        }
+
+        /**
+         * Gets the vertical resolution in dpi.
+         *
+         * @return The horizontal resolution.
+         */
+        public int getHorizontalDpi() {
+            return mHorizontalDpi;
+        }
+
+        /**
+         * Gets the vertical resolution in dpi.
+         *
+         * @return The vertical resolution.
+         */
+        public int getVerticalDpi() {
+            return mVerticalDpi;
+        }
+
+        void writeToParcel(Parcel parcel) {
+            parcel.writeString(mId);
+            parcel.writeString(mLabel);
+            parcel.writeInt(mHorizontalDpi);
+            parcel.writeInt(mVerticalDpi);
+        }
+
+        static Resolution createFromParcel(Parcel parcel) {
+            return new Resolution(
+                    parcel.readString(),
+                    parcel.readString(),
+                    parcel.readInt(),
+                    parcel.readInt());
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + mHorizontalDpi;
+            result = prime * result + mVerticalDpi;
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj == null) {
+                return false;
+            }
+            if (getClass() != obj.getClass()) {
+                return false;
+            }
+            Resolution other = (Resolution) obj;
+            if (mHorizontalDpi != other.mHorizontalDpi) {
+                return false;
+            }
+            if (mVerticalDpi != other.mVerticalDpi) {
+                return false;
+            }
+            return true;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder builder = new StringBuilder();
+            builder.append("Resolution{");
+            builder.append("id: ").append(mId);
+            builder.append(", label: ").append(mLabel);
+            builder.append(", horizontalDpi: ").append(mHorizontalDpi);
+            builder.append(", verticalDpi: ").append(mVerticalDpi);
+            builder.append("}");
+            return builder.toString();
+        }
+    }
+
+    /**
+     * This class specifies content margins.
+     */
+    public static final class Margins {
+        public static final Margins NO_MARGINS = new Margins(0,  0,  0,  0);
+
+        private final int mLeftMils;
+        private final int mTopMils;
+        private final int mRightMils;
+        private final int mBottomMils;
+
+        /**
+         * Creates a new instance.
+         *
+         * @param leftMils The left margin in mils (thousands of an inch).
+         * @param topMils The top margin in mils (thousands of an inch).
+         * @param rightMils The right margin in mils (thousands of an inch).
+         * @param bottomMils The bottom margin in mils (thousands of an inch).
+         */
+        public Margins(int leftMils, int topMils, int rightMils, int bottomMils) {
+            mTopMils = topMils;
+            mLeftMils = leftMils;
+            mRightMils = rightMils;
+            mBottomMils = bottomMils;
+        }
+
+        /**
+         * Gets the left margin in mils (thousands of an inch).
+         *
+         * @return The left margin.
+         */
+        public int getLeftMils() {
+            return mLeftMils;
+        }
+
+        /**
+         * Gets the top margin in mils (thousands of an inch).
+         *
+         * @return The top margin.
+         */
+        public int getTopMils() {
+            return mTopMils;
+        }
+
+        /**
+         * Gets the right margin in mils (thousands of an inch).
+         *
+         * @return The right margin.
+         */
+        public int getRightMils() {
+            return mRightMils;
+        }
+
+        /**
+         * Gets the bottom margin in mils (thousands of an inch).
+         *
+         * @return The bottom margin.
+         */
+        public int getBottomMils() {
+            return mBottomMils;
+        }
+
+        void writeToParcel(Parcel parcel) {
+            parcel.writeInt(mLeftMils);
+            parcel.writeInt(mTopMils);
+            parcel.writeInt(mRightMils);
+            parcel.writeInt(mBottomMils);
+        }
+
+        static Margins createFromParcel(Parcel parcel) {
+            return new Margins(
+                    parcel.readInt(),
+                    parcel.readInt(),
+                    parcel.readInt(),
+                    parcel.readInt());
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + mBottomMils;
+            result = prime * result + mLeftMils;
+            result = prime * result + mRightMils;
+            result = prime * result + mTopMils;
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj == null) {
+                return false;
+            }
+            if (getClass() != obj.getClass()) {
+                return false;
+            }
+            Margins other = (Margins) obj;
+            if (mBottomMils != other.mBottomMils) {
+                return false;
+            }
+            if (mLeftMils != other.mLeftMils) {
+                return false;
+            }
+            if (mRightMils != other.mRightMils) {
+                return false;
+            }
+            if (mTopMils != other.mTopMils) {
+                return false;
+            }
+            return true;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder builder = new StringBuilder();
+            builder.append("Margins{");
+            builder.append("leftMils: ").append(mLeftMils);
+            builder.append(", topMils: ").append(mTopMils);
+            builder.append(", rightMils: ").append(mRightMils);
+            builder.append(", bottomMils: ").append(mBottomMils);
+            builder.append("}");
+            return builder.toString();
+        }
+    }
+
+    static String colorModeToString(int colorMode) {
+        switch (colorMode) {
+            case COLOR_MODE_MONOCHROME: {
+                return "COLOR_MODE_MONOCHROME";
+            }
+            case COLOR_MODE_COLOR: {
+                return "COLOR_MODE_COLOR";
+            }
+            default:
+                return "COLOR_MODE_UNKNOWN";
+        }
+    }
+
+    static void enforceValidColorMode(int colorMode) {
+        if ((colorMode & VALID_COLOR_MODES) == 0 && Integer.bitCount(colorMode) == 1) {
+            throw new IllegalArgumentException("invalid color mode: " + colorMode);
+        }
+    }
+
+    /**
+     * Builder for creating {@link PrintAttributes}.
+     */
+    public static final class Builder {
+        private final PrintAttributes mAttributes = new PrintAttributes();
+
+        /**
+         * Sets the media size.
+         *
+         * @param mediaSize The media size.
+         * @return This builder.
+         */
+        public Builder setMediaSize(MediaSize mediaSize) {
+            mAttributes.setMediaSize(mediaSize);
+            return this;
+        }
+
+        /**
+         * Sets the resolution.
+         *
+         * @param resolution The resolution.
+         * @return This builder.
+         */
+        public Builder setResolution(Resolution resolution) {
+            mAttributes.setResolution(resolution);
+            return this;
+        }
+
+        /**
+         * Sets the minimal margins. If the content does not fit
+         * these margins it will be clipped.
+         *
+         * @param margins The margins.
+         * @return This builder.
+         */
+        public Builder setMinMargins(Margins margins) {
+            mAttributes.setMinMargins(margins);
+            return this;
+        }
+
+        /**
+         * Sets the color mode.
+         *
+         * @param colorMode A valid color mode or zero.
+         * @return This builder.
+         *
+         * @see PrintAttributes#COLOR_MODE_MONOCHROME
+         * @see PrintAttributes#COLOR_MODE_COLOR
+         */
+        public Builder setColorMode(int colorMode) {
+            if (Integer.bitCount(colorMode) > 1) {
+                throw new IllegalArgumentException("can specify at most one colorMode bit.");
+            }
+            mAttributes.setColorMode(colorMode);
+            return this;
+        }
+
+        /**
+         * Creates a new {@link PrintAttributes} instance.
+         *
+         * @return The new instance.
+         */
+        public PrintAttributes build() {
+            return mAttributes;
+        }
+    }
+
+    public static final Parcelable.Creator<PrintAttributes> CREATOR =
+            new Creator<PrintAttributes>() {
+        @Override
+        public PrintAttributes createFromParcel(Parcel parcel) {
+            return new PrintAttributes(parcel);
+        }
+
+        @Override
+        public PrintAttributes[] newArray(int size) {
+            return new PrintAttributes[size];
+        }
+    };
+}
diff --git a/core/java/android/print/PrintDocumentAdapter.java b/core/java/android/print/PrintDocumentAdapter.java
new file mode 100644
index 0000000..8ac34c1
--- /dev/null
+++ b/core/java/android/print/PrintDocumentAdapter.java
@@ -0,0 +1,246 @@
+/*
+ * 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.print;
+
+import android.os.Bundle;
+import android.os.CancellationSignal;
+import android.os.ParcelFileDescriptor;
+
+/**
+ * Base class that provides the content of a document to be printed.
+ *
+ * <h3>Lifecycle</h3>
+ * <p>
+ * <ul>
+ * <li>
+ * Initially, you will receive a call to {@link #onStart()}. This callback
+ * can be used to allocate resources.
+ * </li>
+ * <li>
+ * Next, you will get one or more calls to {@link #onLayout(PrintAttributes,
+ * PrintAttributes, CancellationSignal, LayoutResultCallback, Bundle)} to
+ * inform you that the print attributes (page size, density, etc) changed
+ * giving you an opportunity to layout the content to match the new constraints.
+ * </li>
+ * <li>
+ * After every call to {@link #onLayout(PrintAttributes, PrintAttributes,
+ * CancellationSignal, LayoutResultCallback, Bundle)}, you may get a call to
+ * {@link #onWrite(PageRange[], ParcelFileDescriptor, CancellationSignal, WriteResultCallback)}
+ * asking you to write a PDF file with the content for specific pages.
+ * </li>
+ * <li>
+ * Finally, you will receive a call to {@link #onFinish()}. You can use this
+ * callback to release resources allocated in {@link #onStart()}.
+ * </li>
+ * </ul>
+ * </p>
+ * <h3>Implementation</h3>
+ * <p>
+ * The APIs defined in this class are designed to enable doing part or all
+ * of the work on an arbitrary thread. For example, if the printed content
+ * does not depend on the UI state, i.e. on what is shown on the screen, then
+ * you can offload the entire work on a dedicated thread, thus making your
+ * application interactive while the print work is being performed.
+ * </p>
+ * <p>
+ * You can also do work on different threads, for example if you print UI
+ * content, you can handle {@link #onStart()} and {@link #onLayout(PrintAttributes,
+ * PrintAttributes, CancellationSignal, LayoutResultCallback, Bundle)} on
+ * the UI thread (assuming onStart initializes resources needed for layout).
+ * This will ensure that the UI does not change while you are laying out the
+ * printed content. Then you can handle {@link #onWrite(PageRange[], ParcelFileDescriptor,
+ * CancellationSignal, WriteResultCallback)} and {@link #onFinish()} on another
+ * thread. This will ensure that the UI is frozen for the minimal amount of
+ * time. Also this assumes that you will generate the printed content in
+ * {@link #onLayout(PrintAttributes, PrintAttributes, CancellationSignal,
+ * LayoutResultCallback, Bundle)} which is not mandatory. If you use multiple
+ * threads, you are responsible for proper synchronization.
+ * </p>
+ */
+public abstract class PrintDocumentAdapter {
+
+    /**
+     * Meta-data key: mapped to a boolean value that is <code>true</code> if
+     * the current layout is for a print preview, <code>false</code> otherwise.
+     */
+    public static final String METADATA_KEY_PRINT_PREVIEW = "KEY_METADATA_PRINT_PREVIEW";
+
+    /**
+     * Called when printing starts. You can use this callback to allocate
+     * resources. This method is invoked on the main thread.
+     */
+    public void onStart() {
+        /* do nothing - stub */
+    }
+
+    /**
+     * Called when the print attributes (page size, density, etc) changed
+     * giving you a chance to layout the content such that it matches the
+     * new constraints. This method is invoked on the main thread.
+     * <p>
+     * After you are done laying out, you <strong>must</strong> invoke: {@link
+     * LayoutResultCallback#onLayoutFinished(PrintDocumentInfo, boolean)} with
+     * the last argument <code>true</code> or <code>false</code> depending on
+     * whether the layout changed the content or not, respectively; and {@link
+     * LayoutResultCallback#onLayoutFailed(CharSequence)}, if an error occurred.
+     * Note that you must call one of the methods of the given callback.
+     * </p>
+     * <p>
+     * <strong>Note:</strong> If the content is large and a layout will be
+     * performed, it is a good practice to schedule the work on a dedicated
+     * thread and register an observer in the provided {@link
+     * CancellationSignal} upon invocation of which you should stop the
+     * layout. The cancellation callback will not be made on the main
+     * thread.
+     * </p>
+     *
+     * @param oldAttributes The old print attributes.
+     * @param newAttributes The new print attributes.
+     * @param cancellationSignal Signal for observing cancel layout requests.
+     * @param callback Callback to inform the system for the layout result.
+     * @param metadata Additional information about how layout the content.
+     *
+     * @see LayoutResultCallback
+     * @see CancellationSignal
+     * @see #METADATA_KEY_PRINT_PREVIEW
+     */
+    public abstract void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes,
+            CancellationSignal cancellationSignal, LayoutResultCallback callback,
+            Bundle metadata);
+
+    /**
+     * Called when specific pages of the content should be written in the
+     * form of a PDF file to the given file descriptor. This method is invoked
+     * on the main thread.
+     *<p>
+     * After you are done writing, you should close the file descriptor and
+     * invoke {@link WriteResultCallback #onWriteFinished(PageRange[]), if writing
+     * completed successfully; or {@link WriteResultCallback#onWriteFailed(
+     * CharSequence)}, if an error occurred. Note that you must call one of
+     * the methods of the given callback.
+     * </p>
+     * <p>
+     * <strong>Note:</strong> If the printed content is large, it is a good
+     * practice to schedule writing it on a dedicated thread and register an
+     * observer in the provided {@link CancellationSignal} upon invocation of
+     * which you should stop writing. The cancellation callback will not be
+     * made on the main thread.
+     * </p>
+     *
+     * @param pages The pages whose content to print - non-overlapping in ascending order.
+     * @param destination The destination file descriptor to which to write.
+     * @param cancellationSignal Signal for observing cancel writing requests.
+     * @param callback Callback to inform the system for the write result.
+     *
+     * @see WriteResultCallback
+     * @see CancellationSignal
+     */
+    public abstract void onWrite(PageRange[] pages, ParcelFileDescriptor destination,
+            CancellationSignal cancellationSignal, WriteResultCallback callback);
+
+    /**
+     * Called when printing finishes. You can use this callback to release
+     * resources acquired in {@link #onStart()}. This method is invoked on
+     * the main thread.
+     */
+    public void onFinish() {
+        /* do nothing - stub */
+    }
+
+    /**
+     * Base class for implementing a callback for the result of {@link
+     * PrintDocumentAdapter#onWrite(PageRange[], ParcelFileDescriptor, CancellationSignal,
+     * WriteResultCallback)}.
+     */
+    public static abstract class WriteResultCallback {
+
+        /**
+         * @hide
+         */
+        public WriteResultCallback() {
+            /* do nothing - hide constructor */
+        }
+
+        /**
+         * Notifies that all the data was written.
+         *
+         * @param pages The pages that were written. Cannot be null or empty.
+         */
+        public void onWriteFinished(PageRange[] pages) {
+            /* do nothing - stub */
+        }
+
+        /**
+         * Notifies that an error occurred while writing the data.
+         *
+         * @param error Error message. May be null if error is unknown.
+         */
+        public void onWriteFailed(CharSequence error) {
+            /* do nothing - stub */
+        }
+
+        /**
+         * Notifies that write was cancelled as a result of a cancellation request.
+         */
+        public void onWriteCancelled() {
+            /* do nothing - stub */
+        }
+    }
+
+    /**
+     * Base class for implementing a callback for the result of {@link
+     * PrintDocumentAdapter#onLayout(PrintAttributes, PrintAttributes,
+     * CancellationSignal, LayoutResultCallback, Bundle)}.
+     */
+    public static abstract class LayoutResultCallback {
+
+        /**
+         * @hide
+         */
+        public LayoutResultCallback() {
+            /* do nothing - hide constructor */
+        }
+
+        /**
+         * Notifies that the layout finished and whether the content changed.
+         *
+         * @param info An info object describing the document. Cannot be null.
+         * @param changed Whether the layout changed.
+         *
+         * @see PrintDocumentInfo
+         */
+        public void onLayoutFinished(PrintDocumentInfo info, boolean changed) {
+            /* do nothing - stub */
+        }
+
+        /**
+         * Notifies that an error occurred while laying out the document.
+         *
+         * @param error Error message. May be null if error is unknown.
+         */
+        public void onLayoutFailed(CharSequence error) {
+            /* do nothing - stub */
+        }
+
+        /**
+         * Notifies that layout was cancelled as a result of a cancellation request.
+         */
+        public void onLayoutCancelled() {
+            /* do nothing - stub */
+        }
+    }
+}
diff --git a/core/java/android/print/PrintDocumentInfo.aidl b/core/java/android/print/PrintDocumentInfo.aidl
new file mode 100644
index 0000000..831dcb7
--- /dev/null
+++ b/core/java/android/print/PrintDocumentInfo.aidl
@@ -0,0 +1,19 @@
+/**
+ * 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.print;
+
+parcelable PrintDocumentInfo;
diff --git a/core/java/android/print/PrintDocumentInfo.java b/core/java/android/print/PrintDocumentInfo.java
new file mode 100644
index 0000000..f094962
--- /dev/null
+++ b/core/java/android/print/PrintDocumentInfo.java
@@ -0,0 +1,297 @@
+/*
+ * 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.print;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+/**
+ * This class encapsulates information about a printed document.
+ */
+public final class PrintDocumentInfo implements Parcelable {
+
+    /**
+     * Constant for unknown page count..
+     */
+    public static final int PAGE_COUNT_UNKNOWN = -1;
+
+    /**
+     * Content type: unknown.
+     */
+    public static final int CONTENT_TYPE_UNKNOWN = -1;
+
+    /**
+     * Content type: document.
+     */
+    public static final int CONTENT_TYPE_DOCUMENT = 0;
+
+    /**
+     * Content type: photo.
+     */
+    public static final int CONTENT_TYPE_PHOTO = 1;
+
+    private String mName;
+    private int mPageCount;
+    private int mContentType;
+    private long mDataSize;
+
+    /**
+     * Creates a new instance.
+     */
+    private PrintDocumentInfo() {
+        /* do nothing */
+    }
+
+    /**
+     * Creates a new instance.
+     *
+     * @param Prototype from which to clone.
+     */
+    private PrintDocumentInfo(PrintDocumentInfo prototype) {
+        mName = prototype.mName;
+        mPageCount = prototype.mPageCount;
+        mContentType = prototype.mContentType;
+        mDataSize = prototype.mDataSize;
+    }
+
+    /**
+     * Creates a new instance.
+     *
+     * @param parcel Data from which to initialize.
+     */
+    private PrintDocumentInfo(Parcel parcel) {
+        mName = parcel.readString();
+        mPageCount = parcel.readInt();
+        mContentType = parcel.readInt();
+        mDataSize = parcel.readLong();
+    }
+
+    /**
+     * Gets the document name.
+     *
+     * @return The document name.
+     */
+    public String getName() {
+        return mName;
+    }
+
+    /**
+     * Gets the total number of pages.
+     *
+     * @return The number of pages.
+     *
+     * @see #PAGE_COUNT_UNKNOWN
+     */
+    public int getPageCount() {
+        return mPageCount;
+    }
+
+    /**
+     * Gets the content type.
+     *
+     * @return The content type.
+     *
+     * @see #CONTENT_TYPE_UNKNOWN
+     * @see #CONTENT_TYPE_DOCUMENT
+     * @see #CONTENT_TYPE_PHOTO
+     */
+    public int getContentType() {
+        return mContentType;
+    }
+
+    /**
+     * Gets the document data size in bytes.
+     *
+     * @return The data size.
+     */
+    public long getDataSize() {
+        return mDataSize;
+    }
+
+    /**
+     * Sets the document data size in bytes.
+     *
+     * @param dataSize The data size.
+     *
+     * @hide
+     */
+    public void setDataSize(long dataSize) {
+        mDataSize = dataSize;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeString(mName);
+        parcel.writeInt(mPageCount);
+        parcel.writeInt(mContentType);
+        parcel.writeLong(mDataSize);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((mName != null) ? mName.hashCode() : 0);
+        result = prime * result + mContentType;
+        result = prime * result + mPageCount;
+        result = prime * result + (int) mDataSize;
+        result = prime * result + (int) mDataSize >> 32;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        PrintDocumentInfo other = (PrintDocumentInfo) obj;
+        if (!TextUtils.equals(mName, other.mName)) {
+            return false;
+        }
+        if (mContentType != other.mContentType) {
+            return false;
+        }
+        if (mPageCount != other.mPageCount) {
+            return false;
+        }
+        if (mDataSize != other.mDataSize) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("PrintDocumentInfo{");
+        builder.append("name=").append(mName);
+        builder.append(", pageCount=").append(mPageCount);
+        builder.append(", contentType=").append(contentTyepToString(mContentType));
+        builder.append(", size=").append(mDataSize);
+        builder.append("}");
+        return builder.toString();
+    }
+
+    private String contentTyepToString(int contentType) {
+        switch (contentType) {
+            case CONTENT_TYPE_DOCUMENT: {
+                return "CONTENT_TYPE_DOCUMENT";
+            }
+            case CONTENT_TYPE_PHOTO: {
+                return "CONTENT_TYPE_PHOTO";
+            }
+            default: {
+                return "CONTENT_TYPE_UNKNOWN";
+            }
+        }
+    }
+
+    /**
+     * Builder for creating an {@link PrintDocumentInfo}.
+     */
+    public static final class Builder {
+        private final PrintDocumentInfo mPrototype;
+
+        /**
+         * Constructor.
+         * <p>
+         * The values of the relevant properties are initialized with default
+         * values. Please refer to the documentation of the individual setters
+         * for information about the default values.
+         * </p>
+         *
+         * @param name The document name. Cannot be empty. 
+         */
+        public Builder(String name) {
+            if (TextUtils.isEmpty(name)) {
+                throw new IllegalArgumentException("name cannot be empty");
+            }
+            mPrototype = new PrintDocumentInfo();
+            mPrototype.mName = name;
+        }
+
+        /**
+         * Sets the total number of pages.
+         * <p>
+         * <strong>Default: </strong> {@link #PAGE_COUNT_UNKNOWN}
+         * </p>
+         *
+         * @param pageCount The number of pages. Must be greater than
+         * or equal to zero or {@link PrintDocumentInfo#PAGE_COUNT_UNKNOWN}.
+         */
+        public Builder setPageCount(int pageCount) {
+            if (pageCount < 0 && pageCount != PAGE_COUNT_UNKNOWN) {
+                throw new IllegalArgumentException("pageCount"
+                        + " must be greater than or euqal to zero or"
+                        + " DocumentInfo#PAGE_COUNT_UNKNOWN");
+            }
+            mPrototype.mPageCount = pageCount;
+            return this;
+        }
+
+        /**
+         * Sets the content type.
+         * <p>
+         * <strong>Default: </strong> {@link #CONTENT_TYPE_UNKNOWN}
+         * </p>
+         *
+         * @param type The content type.
+         *
+         * @see #CONTENT_TYPE_UNKNOWN
+         * @see #CONTENT_TYPE_DOCUMENT
+         * @see #CONTENT_TYPE_PHOTO
+         */
+        public Builder setContentType(int type) {
+            mPrototype.mContentType = type;
+            return this;
+        }
+
+        /**
+         * Creates a new {@link PrintDocumentInfo} instance.
+         *
+         * @return The new instance.
+         */
+        public PrintDocumentInfo build() {
+            return new PrintDocumentInfo(mPrototype);
+        }
+    }
+
+    public static final Parcelable.Creator<PrintDocumentInfo> CREATOR =
+            new Creator<PrintDocumentInfo>() {
+        @Override
+        public PrintDocumentInfo createFromParcel(Parcel parcel) {
+            return new PrintDocumentInfo(parcel);
+        }
+
+        @Override
+        public PrintDocumentInfo[] newArray(int size) {
+            return new PrintDocumentInfo[size];
+        }
+    };
+}
diff --git a/core/java/android/print/PrintFileDocumentAdapter.java b/core/java/android/print/PrintFileDocumentAdapter.java
new file mode 100644
index 0000000..c3a23a5
--- /dev/null
+++ b/core/java/android/print/PrintFileDocumentAdapter.java
@@ -0,0 +1,153 @@
+/*
+ * 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.print;
+
+import android.content.Context;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.CancellationSignal;
+import android.os.CancellationSignal.OnCancelListener;
+import android.os.ParcelFileDescriptor;
+import android.util.Log;
+
+import com.android.internal.R;
+
+import libcore.io.IoUtils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Adapter for printing PDF files. This class could be useful if you
+ * want to print a file and intercept when the system is ready
+ * spooling the data, so you can delete the file if it is a
+ * temporary one. To achieve this one must override {@link #onFinish()}
+ * and delete the file yourself.
+ */
+public class PrintFileDocumentAdapter extends PrintDocumentAdapter {
+
+    private static final String LOG_TAG = "PrintedFileDocumentAdapter";
+
+    private final Context mContext;
+
+    private final File mFile;
+
+    private final PrintDocumentInfo mDocumentInfo;
+
+    private WriteFileAsyncTask mWriteFileAsyncTask;
+
+    /**
+     * Constructor.
+     *
+     * @param context Context for accessing resources.
+     * @param file The PDF file to print.
+     * @param documentInfo The information about the printed file.
+     */
+    public PrintFileDocumentAdapter(Context context, File file,
+            PrintDocumentInfo documentInfo) {
+        if (file == null) {
+            throw new IllegalArgumentException("File cannot be null!");
+        }
+        if (documentInfo == null) {
+            throw new IllegalArgumentException("documentInfo cannot be null!");
+        }
+        mContext = context;
+        mFile = file;
+        mDocumentInfo = documentInfo;
+    }
+
+    @Override
+    public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes,
+            CancellationSignal cancellationSignal, LayoutResultCallback callback,
+            Bundle metadata) {
+        callback.onLayoutFinished(mDocumentInfo, false);
+    }
+
+    @Override
+    public void onWrite(PageRange[] pages, ParcelFileDescriptor destination,
+            CancellationSignal cancellationSignal, WriteResultCallback callback) {
+        mWriteFileAsyncTask = new WriteFileAsyncTask(destination, cancellationSignal, callback);
+        mWriteFileAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
+                (Void[]) null);
+    }
+
+    private final class WriteFileAsyncTask extends AsyncTask<Void, Void, Void> {
+
+        private final ParcelFileDescriptor mDestination;
+
+        private final WriteResultCallback mResultCallback;
+
+        private final CancellationSignal mCancellationSignal;
+
+        public WriteFileAsyncTask(ParcelFileDescriptor destination,
+                CancellationSignal cancellationSignal, WriteResultCallback callback) {
+            mDestination = destination;
+            mResultCallback = callback;
+            mCancellationSignal = cancellationSignal;
+            mCancellationSignal.setOnCancelListener(new OnCancelListener() {
+                @Override
+                public void onCancel() {
+                    cancel(true);
+                }
+            });
+        }
+
+        @Override
+        protected Void doInBackground(Void... params) {
+            InputStream in = null;
+            OutputStream out = new FileOutputStream(mDestination.getFileDescriptor());
+            final byte[] buffer = new byte[8192];
+            try {
+                in = new FileInputStream(mFile);
+                while (true) {
+                    if (isCancelled()) {
+                        break;
+                    }
+                    final int readByteCount = in.read(buffer);
+                    if (readByteCount < 0) {
+                        break;
+                    }
+                    out.write(buffer, 0, readByteCount);
+                }
+             } catch (IOException ioe) {
+                 Log.e(LOG_TAG, "Error writing data!", ioe);
+                 mResultCallback.onWriteFailed(mContext.getString(
+                         R.string.write_fail_reason_cannot_write));
+             } finally {
+                IoUtils.closeQuietly(in);
+                IoUtils.closeQuietly(out);
+            }
+            return null;
+        }
+
+        @Override
+        protected void onPostExecute(Void result) {
+            mResultCallback.onWriteFinished(new PageRange[] {PageRange.ALL_PAGES});
+        }
+
+        @Override
+        protected void onCancelled(Void result) {
+            mResultCallback.onWriteFailed(mContext.getString(
+                    R.string.write_fail_reason_cancelled));
+        }
+    }
+}
+
diff --git a/core/java/android/print/PrintJob.java b/core/java/android/print/PrintJob.java
new file mode 100644
index 0000000..42bea6d
--- /dev/null
+++ b/core/java/android/print/PrintJob.java
@@ -0,0 +1,101 @@
+/*
+ * 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.print;
+
+/**
+ * This class represents a print job from the perspective of
+ * an application.
+ */
+public final class PrintJob {
+
+    private final int mId;
+
+    private final PrintManager mPrintManager;
+
+    private PrintJobInfo mCachedInfo;
+
+    PrintJob(PrintJobInfo info, PrintManager printManager) {
+        mCachedInfo = info;
+        mPrintManager = printManager;
+        mId = info.getId();
+    }
+
+    /**
+     * Gets the unique print job id.
+     *
+     * @return The id.
+     */
+    public int getId() {
+        return mId;
+    }
+
+    /**
+     * Gets the {@link PrintJobInfo} that describes this job.
+     * <p>
+     * <strong>Node:</strong>The returned info object is a snapshot of the
+     * current print job state. Every call to this method returns a fresh
+     * info object that reflects the current print job state.
+     * </p>
+     *
+     * @return The print job info.
+     */
+    public PrintJobInfo getInfo() {
+        if (isInImmutableState()) {
+            return mCachedInfo;
+        }
+        PrintJobInfo info = mPrintManager.getPrintJobInfo(mId);
+        if (info != null) {
+            mCachedInfo = info;
+        }
+        return mCachedInfo;
+    }
+
+    /**
+     * Cancels this print job.
+     */
+    public void cancel() {
+        if (!isInImmutableState()) {
+            mPrintManager.cancelPrintJob(mId);
+        }
+    }
+
+    private boolean isInImmutableState() {
+        final int state = mCachedInfo.getState();
+        return state == PrintJobInfo.STATE_COMPLETED
+                || state == PrintJobInfo.STATE_CANCELED;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        PrintJob other = (PrintJob) obj;
+        return mId == other.mId;
+    }
+
+    @Override
+    public int hashCode() {
+        return mId;
+    }
+}
diff --git a/core/java/android/print/PrintJobInfo.aidl b/core/java/android/print/PrintJobInfo.aidl
new file mode 100644
index 0000000..fbca99c
--- /dev/null
+++ b/core/java/android/print/PrintJobInfo.aidl
@@ -0,0 +1,19 @@
+/**
+ * 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.print;
+
+parcelable PrintJobInfo;
diff --git a/core/java/android/print/PrintJobInfo.java b/core/java/android/print/PrintJobInfo.java
new file mode 100644
index 0000000..b919ad6
--- /dev/null
+++ b/core/java/android/print/PrintJobInfo.java
@@ -0,0 +1,578 @@
+/*
+ * 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.print;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Arrays;
+
+/**
+ * This class represents the description of a print job.
+ */
+public final class PrintJobInfo implements Parcelable {
+
+    /** Undefined print job id. */
+    public static final int PRINT_JOB_ID_UNDEFINED = -1;
+
+    /**
+     * Constant for matching any print job state.
+     *
+     * @hide
+     */
+    public static final int STATE_ANY = -1;
+
+    /**
+     * Constant for matching any print job state.
+     *
+     * @hide
+     */
+    public static final int STATE_ANY_VISIBLE_TO_CLIENTS = -2;
+
+    /**
+     * Constant for matching any active print job state.
+     *
+     * @hide
+     */
+    public static final int STATE_ANY_ACTIVE = -3;
+
+    /**
+     * Print job state: The print job is being created but not yet
+     * ready to be printed.
+     * <p>
+     * Next valid states: {@link #STATE_QUEUED}
+     * </p>
+     *
+     * @hide
+     */
+    public static final int STATE_CREATED = 1;
+
+    /**
+     * Print job state: The print jobs is created, it is ready
+     * to be printed and should be processed.
+     * <p>
+     * Next valid states: {@link #STATE_STARTED}, {@link #STATE_FAILED},
+     * {@link #STATE_CANCELED}
+     * </p>
+     */
+    public static final int STATE_QUEUED = 2;
+
+    /**
+     * Print job state: The print job is being printed.
+     * <p>
+     * Next valid states: {@link #STATE_COMPLETED}, {@link #STATE_FAILED},
+     * {@link #STATE_CANCELED}, {@link #STATE_BLOCKED}
+     * </p>
+     */
+    public static final int STATE_STARTED = 3;
+
+    /**
+     * Print job state: The print job is blocked.
+     * <p>
+     * Next valid states: {@link #STATE_FAILED}, {@link #STATE_CANCELED},
+     * {@link #STATE_STARTED}
+     * </p>
+     */
+    public static final int STATE_BLOCKED = 4;
+
+    /**
+     * Print job state: The print job was successfully printed.
+     * This is a terminal state.
+     * <p>
+     * Next valid states: None
+     * </p>
+     */
+    public static final int STATE_COMPLETED = 5;
+
+    /**
+     * Print job state: The print job was printing but printing failed.
+     * This is a terminal state.
+     * <p>
+     * Next valid states: None
+     * </p>
+     */
+    public static final int STATE_FAILED = 6;
+
+    /**
+     * Print job state: The print job was canceled.
+     * This is a terminal state.
+     * <p>
+     * Next valid states: None
+     * </p>
+     */
+    public static final int STATE_CANCELED = 7;
+
+    /** The unique print job id. */
+    private int mId;
+
+    /** The human readable print job label. */
+    private String mLabel;
+
+    /** The unique id of the printer. */
+    private PrinterId mPrinterId;
+
+    /** The name of the printer - internally used */
+    private String mPrinterName;
+
+    /** The status of the print job. */
+    private int mState;
+
+    /** The id of the app that created the job. */
+    private int mAppId;
+
+    /** The id of the user that created the job. */
+    private int mUserId;
+
+    /** Optional tag assigned by a print service.*/
+    private String mTag;
+
+    /** How many copies to print. */
+    private int mCopies;
+
+    /** Reason for the print job being in its current state. */
+    private String mStateReason;
+
+    /** The pages to print */
+    private PageRange[] mPageRanges;
+
+    /** The print job attributes size. */
+    private PrintAttributes mAttributes;
+
+    /** Information about the printed document. */
+    private PrintDocumentInfo mDocumentInfo;
+
+    /** @hide*/
+    public PrintJobInfo() {
+        /* do nothing */
+    }
+
+    /** @hide */
+    public PrintJobInfo(PrintJobInfo other) {
+        mId = other.mId;
+        mLabel = other.mLabel;
+        mPrinterId = other.mPrinterId;
+        mPrinterName = other.mPrinterName;
+        mState = other.mState;
+        mAppId = other.mAppId;
+        mUserId = other.mUserId;
+        mTag = other.mTag;
+        mCopies = other.mCopies;
+        mStateReason = other.mStateReason;
+        mPageRanges = other.mPageRanges;
+        mAttributes = other.mAttributes;
+        mDocumentInfo = other.mDocumentInfo;
+    }
+
+    private PrintJobInfo(Parcel parcel) {
+        mId = parcel.readInt();
+        mLabel = parcel.readString();
+        mPrinterId = parcel.readParcelable(null);
+        mPrinterName = parcel.readString();
+        mState = parcel.readInt();
+        mAppId = parcel.readInt();
+        mUserId = parcel.readInt();
+        mTag = parcel.readString();
+        mCopies = parcel.readInt();
+        mStateReason = parcel.readString();
+        if (parcel.readInt() == 1) {
+            Parcelable[] parcelables = parcel.readParcelableArray(null);
+            mPageRanges = new PageRange[parcelables.length];
+            for (int i = 0; i < parcelables.length; i++) {
+                mPageRanges[i] = (PageRange) parcelables[i];
+            }
+        }
+        if (parcel.readInt() == 1) {
+            mAttributes = PrintAttributes.CREATOR.createFromParcel(parcel);
+        }
+        if (parcel.readInt() == 1) {
+            mDocumentInfo = PrintDocumentInfo.CREATOR.createFromParcel(parcel);
+        }
+    }
+
+    /**
+     * Gets the unique print job id.
+     *
+     * @return The id.
+     */
+    public int getId() {
+        return mId;
+    }
+
+    /**
+     * Sets the unique print job id.
+     *
+     * @param The job id.
+     *
+     * @hide
+     */
+    public void setId(int id) {
+        this.mId = id;
+    }
+
+    /**
+     * Gets the human readable job label.
+     *
+     * @return The label.
+     */
+    public String getLabel() {
+        return mLabel;
+    }
+
+    /**
+     * Sets the human readable job label.
+     *
+     * @param label The label.
+     *
+     * @hide
+     */
+    public void setLabel(String label) {
+        mLabel = label;
+    }
+
+    /**
+     * Gets the unique target printer id.
+     *
+     * @return The target printer id.
+     */
+    public PrinterId getPrinterId() {
+        return mPrinterId;
+    }
+
+    /**
+     * Sets the unique target pritner id.
+     *
+     * @param printerId The target printer id.
+     *
+     * @hide
+     */
+    public void setPrinterId(PrinterId printerId) {
+        mPrinterId = printerId;
+    }
+
+    /**
+     * Gets the name of the target printer.
+     *
+     * @return The printer name.
+     *
+     * @hide
+     */
+    public String getPrinterName() {
+        return mPrinterName;
+    }
+
+    /**
+     * Sets the name of the target printer.
+     *
+     * @param printerName The printer name.
+     *
+     * @hide
+     */
+    public void setPrinterName(String printerName) {
+        mPrinterName = printerName;
+    }
+
+    /**
+     * Gets the current job state.
+     *
+     * @return The job state.
+     */
+    public int getState() {
+        return mState;
+    }
+
+    /**
+     * Sets the current job state.
+     *
+     * @param state The job state.
+     *
+     * @hide
+     */
+    public void setState(int state) {
+        mState = state;
+    }
+
+    /**
+     * Sets the owning application id.
+     *
+     * @return The owning app id.
+     *
+     * @hide
+     */
+    public int getAppId() {
+        return mAppId;
+    }
+
+    /**
+     * Sets the owning application id.
+     *
+     * @param appId The owning app id.
+     *
+     * @hide
+     */
+    public void setAppId(int appId) {
+        mAppId = appId;
+    }
+
+    /**
+     * Gets the owning user id.
+     *
+     * @return The user id.
+     *
+     * @hide
+     */
+    public int getUserId() {
+        return mUserId;
+    }
+
+    /**
+     * Sets the owning user id.
+     *
+     * @param userId The user id.
+     *
+     * @hide
+     */
+    public void setUserId(int userId) {
+        mUserId = userId;
+    }
+
+    /**
+     * Gets the optional tag assigned by a print service.
+     *
+     * @return The tag.
+     */
+    public String getTag() {
+        return mTag;
+    }
+
+    /**
+     * Sets the optional tag assigned by a print service.
+     *
+     * @param tag The tag.
+     *
+     * @hide
+     */
+    public void setTag(String tag) {
+        mTag = tag;
+    }
+
+    /**
+     * Gets the number of copies.
+     *
+     * @return The number of copies or zero if not set.
+     */
+    public int getCopies() {
+        return mCopies;
+    }
+
+    /**
+     * Sets the number of copies.
+     *
+     * @param copyCount The number of copies.
+     *
+     * @hide
+     */
+    public void setCopies(int copyCount) {
+        if (copyCount < 1) {
+            throw new IllegalArgumentException("Copies must be more than one.");
+        }
+        mCopies = copyCount;
+    }
+
+    /**
+     * Gets the reason for the print job being in the current state.
+     *
+     * @return The reason, or null if there is no reason or the
+     * reason is unknown.
+     *
+     * @hide
+     */
+    public String getStateReason() {
+        return mStateReason;
+    }
+
+    /**
+     * Sets the reason for the print job being in the current state.
+     *
+     * @param stateReason The reason, or null if there is no reason
+     * or the reason is unknown.
+     *
+     * @hide
+     */
+    public void setStateReason(String stateReason) {
+        mStateReason = stateReason;
+    }
+
+    /**
+     * Gets the included pages.
+     *
+     * @return The included pages or <code>null</code> if not set.
+     */
+    public PageRange[] getPages() {
+        return mPageRanges;
+    }
+
+    /**
+     * Sets the included pages.
+     *
+     * @return The included pages.
+     *
+     * @hide
+     */
+    public void setPages(PageRange[] pageRanges) {
+        mPageRanges = pageRanges;
+    }
+
+    /**
+     * Gets the print job attributes.
+     *
+     * @return The attributes.
+     */
+    public PrintAttributes getAttributes() {
+        return mAttributes;
+    }
+
+    /**
+     * Sets the print job attributes.
+     *
+     * @param attributes The attributes.
+     *
+     * @hide
+     */
+    public void setAttributes(PrintAttributes attributes) {
+        mAttributes = attributes;
+    }
+
+    /**
+     * Gets the info describing the printed document.
+     *
+     * @return The document info.
+     *
+     * @hide
+     */
+    public PrintDocumentInfo getDocumentInfo() {
+        return mDocumentInfo;
+    }
+
+    /**
+     * Sets the info describing the printed document.
+     *
+     * @param info The document info.
+     *
+     * @hide
+     */
+    public void setDocumentInfo(PrintDocumentInfo info) {
+        mDocumentInfo = info;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeInt(mId);
+        parcel.writeString(mLabel);
+        parcel.writeParcelable(mPrinterId, flags);
+        parcel.writeString(mPrinterName);
+        parcel.writeInt(mState);
+        parcel.writeInt(mAppId);
+        parcel.writeInt(mUserId);
+        parcel.writeString(mTag);
+        parcel.writeInt(mCopies);
+        parcel.writeString(mStateReason);
+        if (mPageRanges != null) {
+            parcel.writeInt(1);
+            parcel.writeParcelableArray(mPageRanges, flags);
+        } else {
+            parcel.writeInt(0);
+        }
+        if (mAttributes != null) {
+            parcel.writeInt(1);
+            mAttributes.writeToParcel(parcel, flags);
+        } else {
+            parcel.writeInt(0);
+        }
+        if (mDocumentInfo != null) {
+            parcel.writeInt(1);
+            mDocumentInfo.writeToParcel(parcel, flags);
+        } else {
+            parcel.writeInt(0);
+        }
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("PrintJobInfo{");
+        builder.append("label: ").append(mLabel);
+        builder.append(", id: ").append(mId);
+        builder.append(", status: ").append(stateToString(mState));
+        builder.append(", printer: " + mPrinterId);
+        builder.append(", tag: ").append(mTag);
+        builder.append(", copies: ").append(mCopies);
+        builder.append(", attributes: " + (mAttributes != null
+                ? mAttributes.toString() : null));
+        builder.append(", documentInfo: " + (mDocumentInfo != null
+                ? mDocumentInfo.toString() : null));
+        builder.append(", pages: " + (mPageRanges != null
+                ? Arrays.toString(mPageRanges) : null));
+        builder.append("}");
+        return builder.toString();
+    }
+
+    /** @hide */
+    public static String stateToString(int state) {
+        switch (state) {
+            case STATE_CREATED: {
+                return "STATUS_CREATED";
+            }
+            case STATE_QUEUED: {
+                return "STATE_QUEUED";
+            }
+            case STATE_STARTED: {
+                return "STATE_STARTED";
+            }
+            case STATE_FAILED: {
+                return "STATUS_FAILED";
+            }
+            case STATE_COMPLETED: {
+                return "STATUS_COMPLETED";
+            }
+            case STATE_CANCELED: {
+                return "STATUS_CANCELED";
+            }
+            default: {
+                return "STATUS_UNKNOWN";
+            }
+        }
+    }
+
+
+    public static final Parcelable.Creator<PrintJobInfo> CREATOR =
+            new Creator<PrintJobInfo>() {
+        @Override
+        public PrintJobInfo createFromParcel(Parcel parcel) {
+            return new PrintJobInfo(parcel);
+        }
+
+        @Override
+        public PrintJobInfo[] newArray(int size) {
+            return new PrintJobInfo[size];
+        }
+    };
+}
diff --git a/core/java/android/print/PrintManager.java b/core/java/android/print/PrintManager.java
new file mode 100644
index 0000000..10cc771
--- /dev/null
+++ b/core/java/android/print/PrintManager.java
@@ -0,0 +1,514 @@
+/*
+ * 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.print;
+
+import android.content.Context;
+import android.content.IntentSender;
+import android.content.IntentSender.SendIntentException;
+import android.os.Bundle;
+import android.os.CancellationSignal;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.print.PrintDocumentAdapter.LayoutResultCallback;
+import android.print.PrintDocumentAdapter.WriteResultCallback;
+import android.printservice.PrintServiceInfo;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.os.SomeArgs;
+
+import libcore.io.IoUtils;
+
+import java.io.File;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * System level service for accessing the printing capabilities of the platform.
+ * <p>
+ * To obtain a handle to the print manager do the following:
+ * </p>
+ * <pre>
+ * PrintManager printManager =
+ *         (PrintManager) context.getSystemService(Context.PRINT_SERVICE);
+ * </pre>
+ */
+public final class PrintManager {
+
+    private static final String LOG_TAG = "PrintManager";
+
+    /** @hide */
+    public static final int APP_ID_ANY = -2;
+
+    private final Context mContext;
+
+    private final IPrintManager mService;
+
+    private final int mUserId;
+
+    private final int mAppId;
+
+    private final PrintClient mPrintClient;
+
+    private final Handler mHandler;
+
+    /**
+     * Creates a new instance.
+     *
+     * @param context The current context in which to operate.
+     * @param service The backing system service.
+     *
+     * @hide
+     */
+    public PrintManager(Context context, IPrintManager service, int userId, int appId) {
+        mContext = context;
+        mService = service;
+        mUserId = userId;
+        mAppId = appId;
+        mPrintClient = new PrintClient(this);
+        mHandler = new Handler(context.getMainLooper(), null, false) {
+            @Override
+            public void handleMessage(Message message) {
+                SomeArgs args = (SomeArgs) message.obj;
+                Context context = (Context) args.arg1;
+                IntentSender intent = (IntentSender) args.arg2;
+                args.recycle();
+                try {
+                    context.startIntentSender(intent, null, 0, 0, 0);
+                } catch (SendIntentException sie) {
+                    Log.e(LOG_TAG, "Couldn't start print job config activity.", sie);
+                }
+            }
+        };
+    }
+
+    /**
+     * Creates an instance that can access all print jobs.
+     *
+     * @param userId The user id for which to get all print jobs.
+     * @return An instance if the caller has the permission to access
+     * all print jobs, null otherwise.
+     *
+     * @hide
+     */
+    public PrintManager getGlobalPrintManagerForUser(int userId) {
+        return new PrintManager(mContext, mService, userId, APP_ID_ANY);
+    }
+
+    PrintJobInfo getPrintJobInfo(int printJobId) {
+        try {
+            return mService.getPrintJobInfo(printJobId, mAppId, mUserId);
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error getting a print job info:" + printJobId, re);
+        }
+        return null;
+    }
+
+    /**
+     * Gets the print jobs for this application.
+     *
+     * @return The print job list.
+     *
+     * @see PrintJob
+     */
+    public List<PrintJob> getPrintJobs() {
+        try {
+            List<PrintJobInfo> printJobInfos = mService.getPrintJobInfos(mAppId, mUserId);
+            if (printJobInfos == null) {
+                return Collections.emptyList();
+            }
+            final int printJobCount = printJobInfos.size();
+            List<PrintJob> printJobs = new ArrayList<PrintJob>(printJobCount);
+            for (int i = 0; i < printJobCount; i++) {
+                printJobs.add(new PrintJob(printJobInfos.get(i), this));
+            }
+            return printJobs;
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error getting print jobs", re);
+        }
+        return Collections.emptyList();
+    }
+
+    void cancelPrintJob(int printJobId) {
+        try {
+            mService.cancelPrintJob(printJobId, mAppId, mUserId);
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error cancleing a print job: " + printJobId, re);
+        }
+    }
+
+    /**
+     * Creates a print job for printing a file with default print attributes.
+     *
+     * @param printJobName A name for the new print job.
+     * @param pdfFile The PDF file to print.
+     * @param documentInfo Information about the printed document.
+     * @param attributes The default print job attributes.
+     * @return The created print job on success or null on failure.
+     *
+     * @see PrintJob
+     */
+    public PrintJob print(String printJobName, File pdfFile, PrintDocumentInfo documentInfo,
+            PrintAttributes attributes) {
+        PrintFileDocumentAdapter documentAdapter = new PrintFileDocumentAdapter(
+                mContext, pdfFile, documentInfo);
+        return print(printJobName, documentAdapter, attributes);
+    }
+
+    /**
+     * Creates a print job for printing a {@link PrintDocumentAdapter} with default print
+     * attributes.
+     *
+     * @param printJobName A name for the new print job.
+     * @param documentAdapter An adapter that emits the document to print.
+     * @param attributes The default print job attributes.
+     * @return The created print job on success or null on failure.
+     *
+     * @see PrintJob
+     */
+    public PrintJob print(String printJobName, PrintDocumentAdapter documentAdapter,
+            PrintAttributes attributes) {
+        if (TextUtils.isEmpty(printJobName)) {
+            throw new IllegalArgumentException("priintJobName cannot be empty");
+        }
+        PrintDocumentAdapterDelegate delegate = new PrintDocumentAdapterDelegate(documentAdapter,
+                mContext.getMainLooper());
+        try {
+            PrintJobInfo printJob = mService.print(printJobName, mPrintClient, delegate,
+                    attributes, mAppId, mUserId);
+            if (printJob != null) {
+                return new PrintJob(printJob, this);
+            }
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error creating a print job", re);
+        }
+        return null;
+    }
+
+    /**
+     * Gets the list of enabled print services.
+     *
+     * @return The enabled service list or an empty list.
+     *
+     * @hide
+     */
+    public List<PrintServiceInfo> getEnabledPrintServices() {
+        try {
+            List<PrintServiceInfo> enabledServices = mService.getEnabledPrintServices(mUserId);
+            if (enabledServices != null) {
+                return enabledServices;
+            }
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error getting the enalbed print services", re);
+        }
+        return Collections.emptyList();
+    }
+
+    /**
+     * @hide
+     */
+    public PrinterDiscoverySession createPrinterDiscoverySession() {
+        return new PrinterDiscoverySession(mService, mContext, mUserId);
+    }
+
+    private static final class PrintClient extends IPrintClient.Stub {
+
+        private final WeakReference<PrintManager> mWeakPrintManager;
+
+        public PrintClient(PrintManager manager) {
+            mWeakPrintManager = new WeakReference<PrintManager>(manager);
+        }
+
+        @Override
+        public void startPrintJobConfigActivity(IntentSender intent)  {
+            PrintManager manager = mWeakPrintManager.get();
+            if (manager != null) {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 =  manager.mContext;
+                args.arg2 = intent;
+                manager.mHandler.obtainMessage(0, args).sendToTarget();
+            }
+        }
+    }
+
+    private static final class PrintDocumentAdapterDelegate extends IPrintDocumentAdapter.Stub {
+
+        private final Object mLock = new Object();
+
+        private CancellationSignal mLayoutOrWriteCancellation;
+
+        private PrintDocumentAdapter mDocumentAdapter; // Strong reference OK - cleared in finish()
+
+        private Handler mHandler; // Strong reference OK - cleared in finish()
+
+        public PrintDocumentAdapterDelegate(PrintDocumentAdapter documentAdapter, Looper looper) {
+            mDocumentAdapter = documentAdapter;
+            mHandler = new MyHandler(looper);
+        }
+
+        @Override
+        public void start() {
+            mHandler.sendEmptyMessage(MyHandler.MSG_START);
+        }
+
+        @Override
+        public void layout(PrintAttributes oldAttributes, PrintAttributes newAttributes,
+                ILayoutResultCallback callback, Bundle metadata, int sequence) {
+            synchronized (mLock) {
+                if (mLayoutOrWriteCancellation != null) {
+                    mLayoutOrWriteCancellation.cancel();
+                }
+            }
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = oldAttributes;
+            args.arg2 = newAttributes;
+            args.arg3 = callback;
+            args.arg4 = metadata;
+            args.argi1 = sequence;
+            mHandler.removeMessages(MyHandler.MSG_LAYOUT);
+            mHandler.obtainMessage(MyHandler.MSG_LAYOUT, args).sendToTarget();
+        }
+
+        @Override
+        public void write(PageRange[] pages, ParcelFileDescriptor fd,
+            IWriteResultCallback callback, int sequence) {
+            synchronized (mLock) {
+                if (mLayoutOrWriteCancellation != null) {
+                    mLayoutOrWriteCancellation.cancel();
+                }
+            }
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = pages;
+            args.arg2 = fd;
+            args.arg3 = callback;
+            args.argi1 = sequence;
+            mHandler.removeMessages(MyHandler.MSG_WRITE);
+            mHandler.obtainMessage(MyHandler.MSG_WRITE, args).sendToTarget();
+        }
+
+        @Override
+        public void finish() {
+            mHandler.sendEmptyMessage(MyHandler.MSG_FINISH);
+        }
+
+        private boolean isFinished() {
+            return mDocumentAdapter == null;
+        }
+
+        private void doFinish() {
+            mDocumentAdapter = null;
+            mHandler = null;
+            mLayoutOrWriteCancellation = null;
+        }
+
+        private final class MyHandler extends Handler {
+            public static final int MSG_START = 1;
+            public static final int MSG_LAYOUT = 2;
+            public static final int MSG_WRITE = 3;
+            public static final int MSG_FINISH = 4;
+
+            public MyHandler(Looper looper) {
+                super(looper, null, true);
+            }
+
+            @Override
+            public void handleMessage(Message message) {
+                if (isFinished()) {
+                    return;
+                }
+                switch (message.what) {
+                    case MSG_START: {
+                        mDocumentAdapter.onStart();
+                    } break;
+
+                    case MSG_LAYOUT: {
+                        SomeArgs args = (SomeArgs) message.obj;
+                        PrintAttributes oldAttributes = (PrintAttributes) args.arg1;
+                        PrintAttributes newAttributes = (PrintAttributes) args.arg2;
+                        ILayoutResultCallback callback = (ILayoutResultCallback) args.arg3;
+                        Bundle metadata = (Bundle) args.arg4;
+                        final int sequence = args.argi1;
+                        args.recycle();
+
+                        CancellationSignal cancellation = new CancellationSignal();
+                        synchronized (mLock) {
+                            mLayoutOrWriteCancellation = cancellation;
+                        }
+
+                        mDocumentAdapter.onLayout(oldAttributes, newAttributes, cancellation,
+                                new MyLayoutResultCallback(callback, sequence), metadata);
+                    } break;
+
+                    case MSG_WRITE: {
+                        SomeArgs args = (SomeArgs) message.obj;
+                        PageRange[] pages = (PageRange[]) args.arg1;
+                        ParcelFileDescriptor fd = (ParcelFileDescriptor) args.arg2;
+                        IWriteResultCallback callback = (IWriteResultCallback) args.arg3;
+                        final int sequence = args.argi1;
+                        args.recycle();
+
+                        CancellationSignal cancellation = new CancellationSignal();
+                        synchronized (mLock) {
+                            mLayoutOrWriteCancellation = cancellation;
+                        }
+
+                        mDocumentAdapter.onWrite(pages, fd, cancellation,
+                                new MyWriteResultCallback(callback, fd, sequence));
+                    } break;
+
+                    case MSG_FINISH: {
+                        mDocumentAdapter.onFinish();
+                        doFinish();
+                    } break;
+
+                    default: {
+                        throw new IllegalArgumentException("Unknown message: "
+                                + message.what);
+                    }
+                }
+            }
+        }
+
+        private final class MyLayoutResultCallback extends LayoutResultCallback {
+            private ILayoutResultCallback mCallback;
+            private final int mSequence;
+
+            public MyLayoutResultCallback(ILayoutResultCallback callback,
+                    int sequence) {
+                mCallback = callback;
+                mSequence = sequence;
+            }
+
+            @Override
+            public void onLayoutFinished(PrintDocumentInfo info, boolean changed) {
+                if (info == null) {
+                    throw new NullPointerException("document info cannot be null");
+                }
+                final ILayoutResultCallback callback;
+                synchronized (mLock) {
+                    callback = mCallback;
+                    clearLocked();
+                }
+                if (callback != null) {
+                    try {
+                        callback.onLayoutFinished(info, changed, mSequence);
+                    } catch (RemoteException re) {
+                        Log.e(LOG_TAG, "Error calling onLayoutFinished", re);
+                    }
+                }
+            }
+
+            @Override
+            public void onLayoutFailed(CharSequence error) {
+                final ILayoutResultCallback callback;
+                synchronized (mLock) {
+                    callback = mCallback;
+                    clearLocked();
+                }
+                if (callback != null) {
+                    try {
+                        callback.onLayoutFailed(error, mSequence);
+                    } catch (RemoteException re) {
+                        Log.e(LOG_TAG, "Error calling onLayoutFailed", re);
+                    }
+                }
+            }
+
+            @Override
+            public void onLayoutCancelled() {
+                synchronized (mLock) {
+                    clearLocked();
+                }
+            }
+
+            private void clearLocked() {
+                mLayoutOrWriteCancellation = null;
+                mCallback = null;
+            }
+        }
+
+        private final class MyWriteResultCallback extends WriteResultCallback {
+            private ParcelFileDescriptor mFd;
+            private int mSequence;
+            private IWriteResultCallback mCallback;
+
+            public MyWriteResultCallback(IWriteResultCallback callback,
+                    ParcelFileDescriptor fd, int sequence) {
+                mFd = fd;
+                mSequence = sequence;
+                mCallback = callback;
+            }
+
+            @Override
+            public void onWriteFinished(PageRange[] pages) {
+                final IWriteResultCallback callback;
+                synchronized (mLock) {
+                    callback = mCallback;
+                    clearLocked();
+                }
+                if (pages == null) {
+                    throw new IllegalArgumentException("pages cannot be null");
+                }
+                if (pages.length == 0) {
+                    throw new IllegalArgumentException("pages cannot be empty");
+                }
+                if (callback != null) {
+                    try {
+                        callback.onWriteFinished(pages, mSequence);
+                    } catch (RemoteException re) {
+                        Log.e(LOG_TAG, "Error calling onWriteFinished", re);
+                    }
+                }
+            }
+
+            @Override
+            public void onWriteFailed(CharSequence error) {
+                final IWriteResultCallback callback;
+                synchronized (mLock) {
+                    callback = mCallback;
+                    clearLocked();
+                }
+                if (callback != null) {
+                    try {
+                        callback.onWriteFailed(error, mSequence);
+                    } catch (RemoteException re) {
+                        Log.e(LOG_TAG, "Error calling onWriteFailed", re);
+                    }
+                }
+            }
+
+            @Override
+            public void onWriteCancelled() {
+                synchronized (mLock) {
+                    clearLocked();
+                }
+            }
+
+            private void clearLocked() {
+                mLayoutOrWriteCancellation = null;
+                IoUtils.closeQuietly(mFd);
+                mCallback = null;
+                mFd = null;
+            }
+        }
+    }
+}
diff --git a/core/java/android/print/PrinterCapabilitiesInfo.aidl b/core/java/android/print/PrinterCapabilitiesInfo.aidl
new file mode 100644
index 0000000..0f5fb6b
--- /dev/null
+++ b/core/java/android/print/PrinterCapabilitiesInfo.aidl
@@ -0,0 +1,19 @@
+/**
+ * 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.print;
+
+parcelable PrinterCapabilitiesInfo;
diff --git a/core/java/android/print/PrinterCapabilitiesInfo.java b/core/java/android/print/PrinterCapabilitiesInfo.java
new file mode 100644
index 0000000..df51ec1
--- /dev/null
+++ b/core/java/android/print/PrinterCapabilitiesInfo.java
@@ -0,0 +1,547 @@
+/*
+ * 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.print;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.print.PrintAttributes.Margins;
+import android.print.PrintAttributes.MediaSize;
+import android.print.PrintAttributes.Resolution;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * This class represents the capabilities of a printer.
+ */
+public final class PrinterCapabilitiesInfo implements Parcelable {
+    /**
+     * Undefined default value.
+     *
+     * @hide
+     */
+    public static final int DEFAULT_UNDEFINED = -1;
+
+    private static final int PROPERTY_MEDIA_SIZE = 0;
+    private static final int PROPERTY_RESOLUTION = 1;
+    private static final int PROPERTY_COLOR_MODE = 2;
+    private static final int PROPERTY_COUNT = 3;
+
+    private static final Margins DEFAULT_MARGINS = new Margins(0,  0,  0,  0);
+
+    private Margins mMinMargins = DEFAULT_MARGINS;
+    private List<MediaSize> mMediaSizes;
+    private List<Resolution> mResolutions;
+
+    private int mColorModes;
+
+    private final int[] mDefaults = new int[PROPERTY_COUNT];
+
+    /**
+     * @hide
+     */
+    public PrinterCapabilitiesInfo() {
+        Arrays.fill(mDefaults, DEFAULT_UNDEFINED);
+    }
+
+    /**
+     * @hide
+     */
+    public PrinterCapabilitiesInfo(PrinterCapabilitiesInfo prototype) {
+        copyFrom(prototype);
+    }
+
+    /**
+     * @hide
+     */
+    public void copyFrom(PrinterCapabilitiesInfo other) {
+        if (this == other) {
+            return;
+        }
+
+        mMinMargins = other.mMinMargins;
+
+        if (other.mMediaSizes != null) {
+            if (mMediaSizes != null) {
+                mMediaSizes.clear();
+                mMediaSizes.addAll(other.mMediaSizes);
+            } else {
+                mMediaSizes = new ArrayList<MediaSize>(other.mMediaSizes);
+            }
+        } else {
+            mMediaSizes = null;
+        }
+
+        if (other.mResolutions != null) {
+            if (mResolutions != null) {
+                mResolutions.clear();
+                mResolutions.addAll(other.mResolutions);
+            } else {
+                mResolutions = new ArrayList<Resolution>(other.mResolutions);
+            }
+        } else {
+            mResolutions = null;
+        }
+
+        mColorModes = other.mColorModes;
+
+        final int defaultCount = other.mDefaults.length;
+        for (int i = 0; i < defaultCount; i++) {
+            mDefaults[i] = other.mDefaults[i];
+        }
+    }
+
+    /**
+     * Gets the supported media sizes.
+     *
+     * @return The media sizes.
+     */
+    public List<MediaSize> getMediaSizes() {
+        return mMediaSizes;
+    }
+
+    /**
+     * Gets the supported resolutions.
+     *
+     * @return The resolutions.
+     */
+    public List<Resolution> getResolutions() {
+        return mResolutions;
+    }
+
+    /**
+     * Gets the minimal margins. These are the minimal margins
+     * the printer physically supports.
+     *
+     * @return The minimal margins.
+     */
+    public Margins getMinMargins() {
+        return mMinMargins;
+    }
+
+    /**
+     * Gets the supported color modes.
+     *
+     * @return The color modes.
+     *
+     * @see PrintAttributes#COLOR_MODE_COLOR
+     * @see PrintAttributes#COLOR_MODE_MONOCHROME
+     */
+    public int getColorModes() {
+        return mColorModes;
+    }
+
+    /**
+     * Gets the default print attributes.
+     *
+     * @return The default attributes.
+     */
+    public PrintAttributes getDefaults() {
+        PrintAttributes.Builder builder = new PrintAttributes.Builder();
+
+        builder.setMinMargins(mMinMargins);
+
+        final int mediaSizeIndex = mDefaults[PROPERTY_MEDIA_SIZE];
+        if (mediaSizeIndex >= 0) {
+            builder.setMediaSize(mMediaSizes.get(mediaSizeIndex));
+        }
+
+        final int resolutionIndex = mDefaults[PROPERTY_RESOLUTION];
+        if (resolutionIndex >= 0) {
+            builder.setResolution(mResolutions.get(resolutionIndex));
+        }
+
+        final int colorMode = mDefaults[PROPERTY_COLOR_MODE];
+        if (colorMode > 0) {
+            builder.setColorMode(colorMode);
+        }
+
+        return builder.build();
+    }
+
+    private PrinterCapabilitiesInfo(Parcel parcel) {
+        mMinMargins = readMargins(parcel);
+        readMediaSizes(parcel);
+        readResolutions(parcel);
+
+        mColorModes = parcel.readInt();
+
+        readDefaults(parcel);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        writeMargins(mMinMargins, parcel);
+        writeMediaSizes(parcel);
+        writeResolutions(parcel);
+
+        parcel.writeInt(mColorModes);
+
+        writeDefaults(parcel);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((mMinMargins == null) ? 0 : mMinMargins.hashCode());
+        result = prime * result + ((mMediaSizes == null) ? 0 : mMediaSizes.hashCode());
+        result = prime * result + ((mResolutions == null) ? 0 : mResolutions.hashCode());
+        result = prime * result + mColorModes;
+        result = prime * result + Arrays.hashCode(mDefaults);
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        PrinterCapabilitiesInfo other = (PrinterCapabilitiesInfo) obj;
+        if (mMinMargins == null) {
+            if (other.mMinMargins != null) {
+                return false;
+            }
+        } else if (!mMinMargins.equals(other.mMinMargins)) {
+            return false;
+        }
+        if (mMediaSizes == null) {
+            if (other.mMediaSizes != null) {
+                return false;
+            }
+        } else if (!mMediaSizes.equals(other.mMediaSizes)) {
+            return false;
+        }
+        if (mResolutions == null) {
+            if (other.mResolutions != null) {
+                return false;
+            }
+        } else if (!mResolutions.equals(other.mResolutions)) {
+            return false;
+        }
+        if (mColorModes != other.mColorModes) {
+            return false;
+        }
+        if (!Arrays.equals(mDefaults, other.mDefaults)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("PrinterInfo{");
+        builder.append("minMargins=").append(mMinMargins);
+        builder.append(", mediaSizes=").append(mMediaSizes);
+        builder.append(", resolutions=").append(mResolutions);
+        builder.append(", colorModes=").append(colorModesToString());
+        builder.append("\"}");
+        return builder.toString();
+    }
+
+    private String colorModesToString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append('[');
+        int colorModes = mColorModes;
+        while (colorModes != 0) {
+            final int colorMode = 1 << Integer.numberOfTrailingZeros(colorModes);
+            colorModes &= ~colorMode;
+            if (builder.length() > 1) {
+                builder.append(", ");
+            }
+            builder.append(PrintAttributes.colorModeToString(colorMode));
+        }
+        builder.append(']');
+        return builder.toString();
+    }
+
+    private void writeMediaSizes(Parcel parcel) {
+        if (mMediaSizes == null) {
+            parcel.writeInt(0);
+            return;
+        }
+        final int mediaSizeCount = mMediaSizes.size();
+        parcel.writeInt(mediaSizeCount);
+        for (int i = 0; i < mediaSizeCount; i++) {
+            mMediaSizes.get(i).writeToParcel(parcel);
+        }
+    }
+
+    private void readMediaSizes(Parcel parcel) {
+        final int mediaSizeCount = parcel.readInt();
+        if (mediaSizeCount > 0 && mMediaSizes == null) {
+            mMediaSizes = new ArrayList<MediaSize>();
+        }
+        for (int i = 0; i < mediaSizeCount; i++) {
+            mMediaSizes.add(MediaSize.createFromParcel(parcel));
+        }
+    }
+
+    private void writeResolutions(Parcel parcel) {
+        if (mResolutions == null) {
+            parcel.writeInt(0);
+            return;
+        }
+        final int resolutionCount = mResolutions.size();
+        parcel.writeInt(resolutionCount);
+        for (int i = 0; i < resolutionCount; i++) {
+            mResolutions.get(i).writeToParcel(parcel);
+        }
+    }
+
+    private void readResolutions(Parcel parcel) {
+        final int resolutionCount = parcel.readInt();
+        if (resolutionCount > 0 && mResolutions == null) {
+            mResolutions = new ArrayList<Resolution>();
+        }
+        for (int i = 0; i < resolutionCount; i++) {
+            mResolutions.add(Resolution.createFromParcel(parcel));
+        }
+    }
+
+    private void writeMargins(Margins margins, Parcel parcel) {
+        if (margins == null) {
+            parcel.writeInt(0);
+        } else {
+            parcel.writeInt(1);
+            margins.writeToParcel(parcel);
+        }
+    }
+
+    private Margins readMargins(Parcel parcel) {
+        return (parcel.readInt() == 1) ? Margins.createFromParcel(parcel) : null;
+    }
+
+    private void readDefaults(Parcel parcel) {
+        final int defaultCount = parcel.readInt();
+        for (int i = 0; i < defaultCount; i++) {
+            mDefaults[i] = parcel.readInt();
+        }
+    }
+
+    private void writeDefaults(Parcel parcel) {
+        final int defaultCount = mDefaults.length;
+        parcel.writeInt(defaultCount);
+        for (int i = 0; i < defaultCount; i++) {
+            parcel.writeInt(mDefaults[i]);
+        }
+    }
+
+    /**
+     * Builder for creating of a {@link PrinterInfo}. This class is responsible
+     * to enforce that all required attributes have at least one default value.
+     * In other words, this class creates only well-formed {@link PrinterInfo}s.
+     * <p>
+     * Look at the individual methods for a reference whether a property is
+     * required or if it is optional.
+     * </p>
+     */
+    public static final class Builder {
+        private final PrinterCapabilitiesInfo mPrototype;
+
+        /**
+         * Creates a new instance.
+         *
+         * @param printerId The printer id. Cannot be null.
+         *
+         * @throws IllegalArgumentException If the printer id is null.
+         */
+        public Builder(PrinterId printerId) {
+            if (printerId == null) {
+                throw new IllegalArgumentException("printerId cannot be null.");
+            }
+            mPrototype = new PrinterCapabilitiesInfo();
+        }
+
+        /**
+         * Adds a supported media size.
+         * <p>
+         * <strong>Required:</strong> Yes
+         * </p>
+         *
+         * @param mediaSize A media size.
+         * @param isDefault Whether this is the default.
+         * @return This builder.
+         * @throws IllegalArgumentException If set as default and there
+         *     is already a default.
+         *
+         * @see PrintAttributes.MediaSize
+         */
+        public Builder addMediaSize(MediaSize mediaSize, boolean isDefault) {
+            if (mPrototype.mMediaSizes == null) {
+                mPrototype.mMediaSizes = new ArrayList<MediaSize>();
+            }
+            final int insertionIndex = mPrototype.mMediaSizes.size();
+            mPrototype.mMediaSizes.add(mediaSize);
+            if (isDefault) {
+                throwIfDefaultAlreadySpecified(PROPERTY_MEDIA_SIZE);
+                mPrototype.mDefaults[PROPERTY_MEDIA_SIZE] = insertionIndex;
+            }
+            return this;
+        }
+
+        /**
+         * Adds a supported resolution.
+         * <p>
+         * <strong>Required:</strong> Yes
+         * </p>
+         *
+         * @param resolution A resolution.
+         * @param isDefault Whether this is the default.
+         * @return This builder.
+         *
+         * @throws IllegalArgumentException If set as default and there
+         *     is already a default.
+         *
+         * @see PrintAttributes.Resolution
+         */
+        public Builder addResolution(Resolution resolution, boolean isDefault) {
+            if (mPrototype.mResolutions == null) {
+                mPrototype.mResolutions = new ArrayList<Resolution>();
+            }
+            final int insertionIndex = mPrototype.mResolutions.size();
+            mPrototype.mResolutions.add(resolution);
+            if (isDefault) {
+                throwIfDefaultAlreadySpecified(PROPERTY_RESOLUTION);
+                mPrototype.mDefaults[PROPERTY_RESOLUTION] = insertionIndex;
+            }
+            return this;
+        }
+
+        /**
+         * Sets the minimal margins. These are the minimal margins
+         * the printer physically supports.
+         *
+         * <p>
+         * <strong>Required:</strong> Yes
+         * </p>
+         *
+         * @param margins The margins.
+         * @return This builder.
+         *
+         * @throws IllegalArgumentException If margins are <code>null</code>.
+         *
+         * @see PrintAttributes.Margins
+         */
+        public Builder setMinMargins(Margins margins) {
+            if (margins == null) {
+                throw new IllegalArgumentException("margins cannot be null");
+            }
+            mPrototype.mMinMargins = margins;
+            return this;
+        }
+
+        /**
+         * Sets the color modes.
+         * <p>
+         * <strong>Required:</strong> Yes
+         * </p>
+         *
+         * @param colorModes The color mode bit mask.
+         * @param defaultColorMode The default color mode.
+         * @return This builder.
+         *
+         * @throws IllegalArgumentException If color modes contains an invalid
+         *         mode bit or if the default color mode is invalid.
+         *
+         * @see PrintAttributes#COLOR_MODE_COLOR
+         * @see PrintAttributes#COLOR_MODE_MONOCHROME
+         */
+        public Builder setColorModes(int colorModes, int defaultColorMode) {
+            int currentModes = colorModes;
+            while (currentModes > 0) {
+                final int currentMode = (1 << Integer.numberOfTrailingZeros(currentModes));
+                currentModes &= ~currentMode;
+                PrintAttributes.enforceValidColorMode(currentMode);
+            }
+            if ((colorModes & defaultColorMode) == 0) {
+                throw new IllegalArgumentException("Default color mode not in color modes.");
+            }
+            PrintAttributes.enforceValidColorMode(colorModes);
+            mPrototype.mColorModes = colorModes;
+            mPrototype.mDefaults[PROPERTY_COLOR_MODE] = defaultColorMode;
+            return this;
+        }
+
+        /**
+         * Crates a new {@link PrinterCapabilitiesInfo} enforcing that all
+         * required properties have need specified. See individual methods
+         * in this class for reference about required attributes.
+         *
+         * @return A new {@link PrinterCapabilitiesInfo}.
+         *
+         * @throws IllegalStateException If a required attribute was not specified.
+         */
+        public PrinterCapabilitiesInfo build() {
+            if (mPrototype.mMediaSizes == null || mPrototype.mMediaSizes.isEmpty()) {
+                throw new IllegalStateException("No media size specified.");
+            }
+            if (mPrototype.mDefaults[PROPERTY_MEDIA_SIZE] == DEFAULT_UNDEFINED) {
+                throw new IllegalStateException("No default media size specified.");
+            }
+            if (mPrototype.mResolutions == null || mPrototype.mResolutions.isEmpty()) {
+                throw new IllegalStateException("No resolution specified.");
+            }
+            if (mPrototype.mDefaults[PROPERTY_RESOLUTION] == DEFAULT_UNDEFINED) {
+                throw new IllegalStateException("No default resolution specified.");
+            }
+            if (mPrototype.mColorModes == 0) {
+                throw new IllegalStateException("No color mode specified.");
+            }
+            if (mPrototype.mDefaults[PROPERTY_COLOR_MODE] == DEFAULT_UNDEFINED) {
+                throw new IllegalStateException("No default color mode specified.");
+            }
+            if (mPrototype.mMinMargins == null) {
+                throw new IllegalArgumentException("margins cannot be null");
+            }
+            return new PrinterCapabilitiesInfo(mPrototype);
+        }
+
+        private void throwIfDefaultAlreadySpecified(int propertyIndex) {
+            if (mPrototype.mDefaults[propertyIndex] != DEFAULT_UNDEFINED) {
+                throw new IllegalArgumentException("Default already specified.");
+            }
+        }
+    }
+
+    public static final Parcelable.Creator<PrinterCapabilitiesInfo> CREATOR =
+            new Parcelable.Creator<PrinterCapabilitiesInfo>() {
+        @Override
+        public PrinterCapabilitiesInfo createFromParcel(Parcel parcel) {
+            return new PrinterCapabilitiesInfo(parcel);
+        }
+
+        @Override
+        public PrinterCapabilitiesInfo[] newArray(int size) {
+            return new PrinterCapabilitiesInfo[size];
+        }
+    };
+}
+
diff --git a/core/java/android/print/PrinterDiscoverySession.java b/core/java/android/print/PrinterDiscoverySession.java
new file mode 100644
index 0000000..64249b4
--- /dev/null
+++ b/core/java/android/print/PrinterDiscoverySession.java
@@ -0,0 +1,290 @@
+/*
+ * 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.print;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @hide
+ */
+public final class PrinterDiscoverySession {
+
+    private static final String LOG_TAG ="PrinterDiscoverySession";
+
+    private static final int MSG_PRINTERS_ADDED = 1;
+    private static final int MSG_PRINTERS_REMOVED = 2;
+
+    private final ArrayMap<PrinterId, PrinterInfo> mPrinters =
+            new ArrayMap<PrinterId, PrinterInfo>();
+
+    private final IPrintManager mPrintManager;
+
+    private final int mUserId;
+
+    private final Handler mHandler;
+
+    private IPrinterDiscoveryObserver mObserver;
+
+    private OnPrintersChangeListener mListener;
+
+    private boolean mIsPrinterDiscoveryStarted;
+
+    public static interface OnPrintersChangeListener {
+        public void onPrintersChanged();
+    }
+
+    PrinterDiscoverySession(IPrintManager printManager, Context context, int userId) {
+        mPrintManager = printManager;
+        mUserId = userId;
+        mHandler = new SessionHandler(context.getMainLooper());
+        mObserver = new PrinterDiscoveryObserver(this);
+        try {
+            mPrintManager.createPrinterDiscoverySession(mObserver, mUserId);
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error creating printer discovery session", re);
+        }
+    }
+
+    public final void startPrinterDisovery(List<PrinterId> priorityList) {
+        if (isDestroyed()) {
+            Log.w(LOG_TAG, "Ignoring start printers dsicovery - session destroyed");
+            return;
+        }
+        if (!mIsPrinterDiscoveryStarted) {
+            mIsPrinterDiscoveryStarted = true;
+            try {
+                mPrintManager.startPrinterDiscovery(mObserver, priorityList, mUserId);
+            } catch (RemoteException re) {
+                Log.e(LOG_TAG, "Error starting printer discovery", re);
+            }
+        }
+    }
+
+    public final void stopPrinterDiscovery() {
+        if (isDestroyed()) {
+            Log.w(LOG_TAG, "Ignoring stop printers discovery - session destroyed");
+            return;
+        }
+        if (mIsPrinterDiscoveryStarted) {
+            mIsPrinterDiscoveryStarted = false;
+            try {
+                mPrintManager.stopPrinterDiscovery(mObserver, mUserId);
+            } catch (RemoteException re) {
+                Log.e(LOG_TAG, "Error stopping printer discovery", re);
+            }
+        }
+    }
+
+    public final void startPrinterStateTracking(PrinterId printerId) {
+        if (isDestroyed()) {
+            Log.w(LOG_TAG, "Ignoring start printer state tracking - session destroyed");
+            return;
+        }
+        try {
+            mPrintManager.startPrinterStateTracking(printerId, mUserId);
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error starting printer state tracking", re);
+        }
+    }
+
+    public final void stopPrinterStateTracking(PrinterId printerId) {
+        if (isDestroyed()) {
+            Log.w(LOG_TAG, "Ignoring stop printer state tracking - session destroyed");
+            return;
+        }
+        try {
+            mPrintManager.stopPrinterStateTracking(printerId, mUserId);
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error stoping printer state tracking", re);
+        }
+    }
+
+    public final void validatePrinters(List<PrinterId> printerIds) {
+        if (isDestroyed()) {
+            Log.w(LOG_TAG, "Ignoring validate printers - session destroyed");
+            return;
+        }
+        try {
+            mPrintManager.validatePrinters(printerIds, mUserId);
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error validating printers", re);
+        }
+    }
+
+    public final void destroy() {
+        if (isDestroyed()) {
+            Log.w(LOG_TAG, "Ignoring destroy - session destroyed");
+        }
+        destroyNoCheck();
+    }
+
+    public final List<PrinterInfo> getPrinters() {
+        if (isDestroyed()) {
+            Log.w(LOG_TAG, "Ignoring get printers - session destroyed");
+            return Collections.emptyList();
+        }
+        return new ArrayList<PrinterInfo>(mPrinters.values());
+    }
+
+    public final boolean isDestroyed() {
+        throwIfNotCalledOnMainThread();
+        return isDestroyedNoCheck();
+    }
+
+    public final boolean isPrinterDiscoveryStarted() {
+        throwIfNotCalledOnMainThread();
+        return mIsPrinterDiscoveryStarted;
+    }
+
+    public final void setOnPrintersChangeListener(OnPrintersChangeListener listener) {
+        throwIfNotCalledOnMainThread();
+        mListener = listener;
+    }
+
+    @Override
+    protected final void finalize() throws Throwable {
+        if (!isDestroyedNoCheck()) {
+            Log.e(LOG_TAG, "Destroying leaked printer discovery session");
+            destroyNoCheck();
+        }
+        super.finalize();
+    }
+
+    private boolean isDestroyedNoCheck() {
+        return (mObserver == null);
+    }
+
+    private void destroyNoCheck() {
+        stopPrinterDiscovery();
+        try {
+            mPrintManager.destroyPrinterDiscoverySession(mObserver, mUserId);
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error destroying printer discovery session", re);
+        } finally {
+            mObserver = null;
+            mPrinters.clear();
+        }
+    }
+
+    private void handlePrintersAdded(List<PrinterInfo> printers) {
+        if (isDestroyed()) {
+            return;
+        }
+        boolean printersChanged = false;
+        final int addedPrinterCount = printers.size();
+        for (int i = 0; i < addedPrinterCount; i++) {
+            PrinterInfo addedPrinter = printers.get(i);
+            PrinterInfo oldPrinter = mPrinters.put(addedPrinter.getId(), addedPrinter);
+            if (oldPrinter == null || !oldPrinter.equals(addedPrinter)) {
+                printersChanged = true;
+            }
+        }
+        if (printersChanged) {
+            notifyOnPrintersChanged();
+        }
+    }
+
+    private void handlePrintersRemoved(List<PrinterId> printerIds) {
+        if (isDestroyed()) {
+            return;
+        }
+        boolean printersChanged = false;
+        final int removedPrinterIdCount = printerIds.size();
+        for (int i = 0; i < removedPrinterIdCount; i++) {
+            PrinterId removedPrinterId = printerIds.get(i);
+            if (mPrinters.remove(removedPrinterId) != null) {
+                printersChanged = true;
+            }
+        }
+        if (printersChanged) {
+            notifyOnPrintersChanged();
+        }
+    }
+
+    private void notifyOnPrintersChanged() {
+        if (mListener != null) {
+            mListener.onPrintersChanged();
+        }
+    }
+
+    private static void throwIfNotCalledOnMainThread() {
+        if (!Looper.getMainLooper().isCurrentThread()) {
+            throw new IllegalAccessError("must be called from the main thread");
+        }
+    }
+
+    private final class SessionHandler extends Handler {
+
+        public SessionHandler(Looper looper) {
+            super(looper, null, false);
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public void handleMessage(Message message) {
+            switch (message.what) {
+                case MSG_PRINTERS_ADDED: {
+                    List<PrinterInfo> printers = (List<PrinterInfo>) message.obj;
+                    handlePrintersAdded(printers);
+                } break;
+
+                case MSG_PRINTERS_REMOVED: {
+                    List<PrinterId> printerIds = (List<PrinterId>) message.obj;
+                    handlePrintersRemoved(printerIds);
+                } break;
+            }
+        }
+    }
+
+    private static final class PrinterDiscoveryObserver extends IPrinterDiscoveryObserver.Stub {
+
+        private final WeakReference<PrinterDiscoverySession> mWeakSession;
+
+        public PrinterDiscoveryObserver(PrinterDiscoverySession session) {
+            mWeakSession = new WeakReference<PrinterDiscoverySession>(session);
+        }
+
+        @Override
+        public void onPrintersAdded(List<PrinterInfo> printers) {
+            PrinterDiscoverySession session = mWeakSession.get();
+            if (session != null) {
+                session.mHandler.obtainMessage(MSG_PRINTERS_ADDED,
+                        printers).sendToTarget();
+            }
+        }
+
+        @Override
+        public void onPrintersRemoved(List<PrinterId> printerIds) {
+            PrinterDiscoverySession session = mWeakSession.get();
+            if (session != null) {
+                session.mHandler.obtainMessage(MSG_PRINTERS_REMOVED,
+                        printerIds).sendToTarget();
+            }
+        }
+    }
+}
diff --git a/core/java/android/print/PrinterId.aidl b/core/java/android/print/PrinterId.aidl
new file mode 100644
index 0000000..84f422f
--- /dev/null
+++ b/core/java/android/print/PrinterId.aidl
@@ -0,0 +1,19 @@
+/**
+ * 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.print;
+
+parcelable PrinterId;
diff --git a/core/java/android/print/PrinterId.java b/core/java/android/print/PrinterId.java
new file mode 100644
index 0000000..a3f3b2bf
--- /dev/null
+++ b/core/java/android/print/PrinterId.java
@@ -0,0 +1,140 @@
+/*
+ * 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.print;
+
+import android.content.ComponentName;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+/**
+ * This class represents the unique id of a printer.
+ */
+public final class PrinterId implements Parcelable {
+
+    private final ComponentName mServiceName;
+
+    private final String mLocalId;
+
+    /**
+     * Creates a new instance.
+     *
+     * @param serviceName The managing print service.
+     * @param localId The locally unique id within the managing service.
+     *
+     * @hide
+     */
+    public PrinterId(ComponentName serviceName, String localId) {
+        mServiceName = serviceName;
+        mLocalId = localId;
+    }
+
+    private PrinterId(Parcel parcel) {
+        mServiceName = parcel.readParcelable(null);
+        mLocalId = parcel.readString();
+    }
+
+    /**
+     * The id of the print service this printer is managed by.
+     *
+     * @return The print service component name.
+     *
+     * @hide
+     */
+    public ComponentName getServiceName() {
+        return mServiceName;
+    }
+
+    /**
+     * Gets the id of this printer which is unique in the context
+     * of the print service that manages it.
+     *
+     * @return The printer name.
+     */
+    public String getLocalId() {
+        return mLocalId;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeParcelable(mServiceName, flags);
+        parcel.writeString(mLocalId);
+    }
+
+    @Override
+    public boolean equals(Object object) {
+        if (this == object) {
+            return true;
+        }
+        if (object == null) {
+            return false;
+        }
+        if (getClass() != object.getClass()) {
+            return false;
+        }
+        PrinterId other = (PrinterId) object;
+        if (mServiceName == null) {
+            if (other.mServiceName != null) {
+                return false;
+            }
+        } else if (!mServiceName.equals(other.mServiceName)) {
+            return false;
+        }
+        if (!TextUtils.equals(mLocalId, other.mLocalId)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int hashCode = 1;
+        hashCode = prime * hashCode + ((mServiceName != null)
+                ? mServiceName.hashCode() : 1);
+        hashCode = prime * hashCode + mLocalId.hashCode();
+        return hashCode;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("PrinterId{");
+        builder.append("serviceName=").append(mServiceName.flattenToString());
+        builder.append(", localId=").append(mLocalId);
+        builder.append('}');
+        return builder.toString();
+    }
+
+    public static final Parcelable.Creator<PrinterId> CREATOR =
+            new Creator<PrinterId>() {
+        @Override
+        public PrinterId createFromParcel(Parcel parcel) {
+            return new PrinterId(parcel);
+        }
+
+        @Override
+        public PrinterId[] newArray(int size) {
+            return new PrinterId[size];
+        }
+    };
+}
diff --git a/core/java/android/print/PrinterInfo.aidl b/core/java/android/print/PrinterInfo.aidl
new file mode 100644
index 0000000..6ec5a58
--- /dev/null
+++ b/core/java/android/print/PrinterInfo.aidl
@@ -0,0 +1,19 @@
+/**
+ * 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.print;
+
+parcelable PrinterInfo;
diff --git a/core/java/android/print/PrinterInfo.java b/core/java/android/print/PrinterInfo.java
new file mode 100644
index 0000000..a51e28b
--- /dev/null
+++ b/core/java/android/print/PrinterInfo.java
@@ -0,0 +1,322 @@
+/*
+ * 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.print;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+/**
+ * This class represents the description of a printer.
+ */
+public final class PrinterInfo implements Parcelable {
+
+    /** Printer status: the printer is idle and ready to print. */
+    public static final int STATUS_IDLE = 1;
+
+    /** Printer status: the printer is busy printing. */
+    public static final int STATUS_BUSY = 2;
+
+    /** Printer status: the printer is not available. */
+    public static final int STATUS_UNAVAILABLE = 3;
+
+    private PrinterId mId;
+
+    private String mName;
+
+    private int mStatus;
+
+    private String mDescription;
+
+    private PrinterCapabilitiesInfo mCapabilities;
+
+    private PrinterInfo() {
+        /* do nothing */
+    }
+
+    private PrinterInfo(PrinterInfo prototype) {
+        copyFrom(prototype);
+    }
+
+    /**
+     * @hide
+     */
+    public void copyFrom(PrinterInfo other) {
+        if (this == other) {
+            return;
+        }
+        mId = other.mId;
+        mName = other.mName;
+        mStatus = other.mStatus;
+        mDescription = other.mDescription;
+        if (other.mCapabilities != null) {
+            if (mCapabilities != null) {
+                mCapabilities.copyFrom(other.mCapabilities);
+            } else {
+                mCapabilities = new PrinterCapabilitiesInfo(other.mCapabilities);
+            }
+        } else {
+            mCapabilities = null;
+        }
+    }
+
+    /**
+     * Get the globally unique printer id.
+     *
+     * @return The printer id.
+     */
+    public PrinterId getId() {
+        return mId;
+    }
+
+    /**
+     * Get the printer name.
+     *
+     * @return The printer name.
+     */
+    public String getName() {
+        return mName;
+    }
+
+    /**
+     * Gets the printer status.
+     *
+     * @return The status.
+     */
+    public int getStatus() {
+        return mStatus;
+    }
+
+    /**
+     * Gets the  printer description.
+     *
+     * @return The description.
+     */
+    public String getDescription() {
+        return mDescription;
+    }
+
+    /**
+     * Gets the printer capabilities.
+     *
+     * @return The capabilities.
+     */
+    public PrinterCapabilitiesInfo getCapabilities() {
+        return mCapabilities;
+    }
+
+    private PrinterInfo(Parcel parcel) {
+        mId = parcel.readParcelable(null);
+        mName = parcel.readString();
+        mStatus = parcel.readInt();
+        mDescription = parcel.readString();
+        mCapabilities = parcel.readParcelable(null);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeParcelable(mId, flags);
+        parcel.writeString(mName);
+        parcel.writeInt(mStatus);
+        parcel.writeString(mDescription);
+        parcel.writeParcelable(mCapabilities, flags);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((mId != null) ? mId.hashCode() : 0);
+        result = prime * result + ((mName != null) ? mName.hashCode() : 0);
+        result = prime * result + mStatus;
+        result = prime * result + ((mDescription != null) ? mDescription.hashCode() : 0);
+        result = prime * result + ((mCapabilities != null) ? mCapabilities.hashCode() : 0);
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        PrinterInfo other = (PrinterInfo) obj;
+        if (mId == null) {
+            if (other.mId != null) {
+                return false;
+            }
+        } else if (!mId.equals(other.mId)) {
+            return false;
+        }
+        if (!TextUtils.equals(mName, other.mName)) {
+            return false;
+        }
+        if (mStatus != other.mStatus) {
+            return false;
+        }
+        if (!TextUtils.equals(mDescription, other.mDescription)) {
+            return false;
+        }
+        if (mCapabilities == null) {
+            if (other.mCapabilities != null) {
+                return false;
+            }
+        } else if (!mCapabilities.equals(other.mCapabilities)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("PrinterInfo{");
+        builder.append("id=").append(mId);
+        builder.append(", name=").append(mName);
+        builder.append(", status=").append(mStatus);
+        builder.append(", description=").append(mDescription);
+        builder.append(", capabilities=").append(mCapabilities);
+        builder.append("\"}");
+        return builder.toString();
+    }
+
+    /**
+     * Builder for creating of a {@link PrinterInfo}.
+     */
+    public static final class Builder {
+        private final PrinterInfo mPrototype;
+
+        /**
+         * Constructor.
+         *
+         * @param printerId The printer id. Cannot be null.
+         * @param name The printer name. Cannot be empty.
+         * @param status The printer status. Must be a valid status.
+         */
+        public Builder(PrinterId printerId, String name, int status) {
+            if (printerId == null) {
+                throw new IllegalArgumentException("printerId cannot be null.");
+            }
+            if (TextUtils.isEmpty(name)) {
+                throw new IllegalArgumentException("name cannot be empty.");
+            }
+            if (!isValidStatus(status)) {
+                throw new IllegalArgumentException("status is invalid.");
+            }
+            mPrototype = new PrinterInfo();
+            mPrototype.mId = printerId;
+            mPrototype.mName = name;
+            mPrototype.mStatus = status;
+        }
+
+        /**
+         * Constructor.
+         *
+         * @param other Other info from which to start building.
+         */
+        public Builder(PrinterInfo other) {
+            mPrototype = new PrinterInfo();
+            mPrototype.copyFrom(other);
+        }
+
+        /**
+         * Sets the printer status.
+         *
+         * @param status The status.
+         * @return This builder.
+         *
+         * @see PrinterInfo#STATUS_IDLE
+         * @see PrinterInfo#STATUS_BUSY
+         * @see PrinterInfo#STATUS_UNAVAILABLE
+         */
+        public Builder setStatus(int status) {
+            mPrototype.mStatus = status;
+            return this;
+        }
+
+        /**
+         * Sets the printer name.
+         *
+         * @param name The name.
+         * @return This builder.
+         */
+        public Builder setName(String name) {
+            mPrototype.mName = name;
+            return this;
+        }
+
+        /**
+         * Sets the printer description.
+         *
+         * @param description The description.
+         * @return This builder.
+         */
+        public Builder setDescription(String description) {
+            mPrototype.mDescription = description;
+            return this;
+        }
+
+        /**
+         * Sets the printer capabilities.
+         *
+         * @param capabilities The capabilities.
+         * @return This builder.
+         */
+        public Builder setCapabilities(PrinterCapabilitiesInfo capabilities) {
+            mPrototype.mCapabilities = capabilities;
+            return this;
+        }
+
+        /**
+         * Crates a new {@link PrinterInfo}.
+         *
+         * @return A new {@link PrinterInfo}.
+         */
+        public PrinterInfo build() {
+            return new PrinterInfo(mPrototype);
+        }
+
+        private boolean isValidStatus(int status) {
+            return (status == STATUS_IDLE
+                    || status == STATUS_IDLE
+                    || status == STATUS_UNAVAILABLE);
+        }
+    }
+
+    public static final Parcelable.Creator<PrinterInfo> CREATOR =
+            new Parcelable.Creator<PrinterInfo>() {
+        @Override
+        public PrinterInfo createFromParcel(Parcel parcel) {
+            return new PrinterInfo(parcel);
+        }
+
+        @Override
+        public PrinterInfo[] newArray(int size) {
+            return new PrinterInfo[size];
+        }
+    };
+}
diff --git a/core/java/android/print/pdf/PdfDocument.java b/core/java/android/print/pdf/PdfDocument.java
new file mode 100644
index 0000000..a2883cf
--- /dev/null
+++ b/core/java/android/print/pdf/PdfDocument.java
@@ -0,0 +1,416 @@
+/*
+ * 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.print.pdf;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.Rect;
+
+import dalvik.system.CloseGuard;
+
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * <p>
+ * This class enables generating a PDF document from native Android content. You
+ * open a new document and then for every page you want to add you start a page,
+ * write content to the page, and finish the page. After you are done with all
+ * pages, you write the document to an output stream and close the document.
+ * After a document is closed you should not use it anymore.
+ * </p>
+ * <p>
+ * A typical use of the APIs looks like this:
+ * </p>
+ * <pre>
+ * // open a new document
+ * PdfDocument document = PdfDocument.open();
+ *
+ * // crate a page description
+ * PageInfo pageInfo = new PageInfo.Builder(new Rect(0, 0, 100, 100), 1).create();
+ *
+ * // start a page
+ * Page page = document.startPage(pageInfo);
+ *
+ * // draw something on the page
+ * View content = getContentView();
+ * content.draw(page.getCanvas());
+ *
+ * // finish the page
+ * document.finishPage(page);
+ * . . .
+ * // add more pages
+ * . . .
+ * // write the document content
+ * document.writeTo(getOutputStream());
+ *
+ * //close the document
+ * document.close();
+ * </pre>
+ */
+public final class PdfDocument {
+
+    private final byte[] mChunk = new byte[4096];
+
+    private final CloseGuard mCloseGuard = CloseGuard.get();
+
+    private final List<PageInfo> mPages = new ArrayList<PageInfo>();
+
+    private int mNativeDocument;
+
+    private Page mCurrentPage;
+
+    /**
+     * Opens a new document.
+     * <p>
+     * <strong>Note:</strong> You must close the document after you are
+     * done by calling {@link #close()}
+     * </p>
+     *
+     * @return The document.
+     *
+     * @see #close()
+     */
+    public static PdfDocument open() {
+        return new PdfDocument();
+    }
+
+    /**
+     * Creates a new instance.
+     */
+    private PdfDocument() {
+        mNativeDocument = nativeCreateDocument();
+        mCloseGuard.open("close");
+    }
+
+    /**
+     * Starts a page using the provided {@link PageInfo}. After the page
+     * is created you can draw arbitrary content on the page's canvas which
+     * you can get by calling {@link Page#getCanvas()}. After you are done
+     * drawing the content you should finish the page by calling
+     * {@link #finishPage(Page)}. After the page is finished you should
+     * no longer access the page or its canvas.
+     * <p>
+     * <strong>Note:</strong> Do not call this method after {@link #close()}.
+     * </p>
+     *
+     * @param pageInfo The page info.
+     * @return A blank page.
+     *
+     * @see #finishPage(Page)
+     */
+    public Page startPage(PageInfo pageInfo) {
+        throwIfClosed();
+        if (pageInfo == null) {
+            throw new IllegalArgumentException("page cannot be null!");
+        }
+        if (mCurrentPage != null) {
+            throw new IllegalStateException("Previous page not finished!");
+        }
+        Canvas canvas = new PdfCanvas(nativeCreatePage(pageInfo.mPageSize,
+                pageInfo.mContentSize, pageInfo.mInitialTransform.native_instance));
+        mCurrentPage = new Page(canvas, pageInfo);
+        return mCurrentPage;
+    }
+
+    /**
+     * Finishes a started page. You should always finish the last started page.
+     * <p>
+     * <strong>Note:</strong> Do not call this method after {@link #close()}.
+     * </p>
+     *
+     * @param page The page.
+     *
+     * @see #startPage(PageInfo)
+     */
+    public void finishPage(Page page) {
+        throwIfClosed();
+        if (page == null) {
+            throw new IllegalArgumentException("page cannot be null");
+        }
+        if (page != mCurrentPage) {
+            throw new IllegalStateException("invalid page");
+        }
+        mPages.add(page.getInfo());
+        mCurrentPage = null;
+        nativeAppendPage(mNativeDocument, page.mCanvas.mNativeCanvas);
+        page.finish();
+    }
+
+    /**
+     * Writes the document to an output stream.
+     * <p>
+     * <strong>Note:</strong> Do not call this method after {@link #close()}.
+     * </p>
+     *
+     * @param out The output stream.
+     */
+    public void writeTo(OutputStream out) {
+        throwIfClosed();
+        if (out == null) {
+            throw new IllegalArgumentException("out cannot be null!");
+        }
+        nativeWriteTo(mNativeDocument, out, mChunk);
+    }
+
+    /**
+     * Gets the pages of the document.
+     *
+     * @return The pages.
+     */
+    public List<PageInfo> getPages() {
+        return Collections.unmodifiableList(mPages);
+    }
+
+    /**
+     * Closes this document. This method should be called after you
+     * are done working with the document. After this call the document
+     * is considered closed and none of its methods should be called.
+     */
+    public void close() {
+        dispose();
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            mCloseGuard.warnIfOpen();
+            dispose();
+        } finally {
+            super.finalize();
+        }
+    }
+
+    private void dispose() {
+        if (mNativeDocument != 0) {
+            nativeFinalize(mNativeDocument);
+            mCloseGuard.close();
+            mNativeDocument = 0;
+        }
+    }
+
+    /**
+     * Throws an exception if the document is already closed.
+     */
+    private void throwIfClosed() {
+        if (mNativeDocument == 0) {
+            throw new IllegalStateException("document is closed!");
+        }
+    }
+
+    private native int nativeCreateDocument();
+
+    private native void nativeFinalize(int document);
+
+    private native void nativeAppendPage(int document, int page);
+
+    private native void nativeWriteTo(int document, OutputStream out, byte[] chunk);
+
+    private static native int nativeCreatePage(Rect pageSize,
+            Rect contentSize, int nativeMatrix);
+
+
+    private final class PdfCanvas extends Canvas {
+
+        public PdfCanvas(int nativeCanvas) {
+            super(nativeCanvas);
+        }
+
+        @Override
+        public void setBitmap(Bitmap bitmap) {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    /**
+     * This class represents meta-data that describes a PDF {@link Page}.
+     */
+    public static final class PageInfo {
+        private Rect mPageSize;
+        private Rect mContentSize;
+        private Matrix mInitialTransform;
+        private int mPageNumber;
+
+        /**
+         * Creates a new instance.
+         */
+        private PageInfo() {
+            /* do nothing */
+        }
+
+        /**
+         * Gets the page size in PostScript points (1/72th of an inch).
+         *
+         * @return The page size.
+         */
+        public Rect getPageSize() {
+            return mPageSize;
+        }
+
+        /**
+         * Get the content size in PostScript points (1/72th of an inch).
+         *
+         * @return The content size.
+         */
+        public Rect getContentSize() {
+            return mContentSize;
+        }
+
+        /**
+         * Gets the initial transform which is applied to the page. This may be
+         * useful to move the origin to account for a margin, apply scale, or
+         * apply a rotation.
+         *
+         * @return The initial transform.
+         */
+        public Matrix getInitialTransform() {
+            return mInitialTransform;
+        }
+
+        /**
+         * Gets the page number.
+         *
+         * @return The page number.
+         */
+        public int getPageNumber() {
+            return mPageNumber;
+        }
+
+        /**
+         * Builder for creating a {@link PageInfo}.
+         */
+        public static final class Builder {
+            private final PageInfo mPageInfo = new PageInfo();
+
+            /**
+             * Creates a new builder with the mandatory page info attributes.
+             *
+             * @param pageSize The page size in PostScript (1/72th of an inch).
+             * @param pageNumber The page number.
+             */
+            public Builder(Rect pageSize, int pageNumber) {
+                if (pageSize.width() == 0 || pageSize.height() == 0) {
+                    throw new IllegalArgumentException("page width and height" +
+                            " must be greater than zero!");
+                }
+                if (pageNumber < 0) {
+                    throw new IllegalArgumentException("pageNumber cannot be less than zero!");
+                }
+                mPageInfo.mPageSize = pageSize;
+                mPageInfo.mPageNumber = pageNumber;
+            }
+
+            /**
+             * Sets the content size in PostScript point (1/72th of an inch).
+             *
+             * @param contentSize The content size.
+             */
+            public Builder setContentSize(Rect contentSize) {
+                Rect pageSize = mPageInfo.mPageSize;
+                if (contentSize != null && (pageSize.left > contentSize.left
+                        || pageSize.top > contentSize.top
+                        || pageSize.right < contentSize.right
+                        || pageSize.bottom < contentSize.bottom)) {
+                    throw new IllegalArgumentException("contentSize does not fit the pageSize!");
+                }
+                mPageInfo.mContentSize = contentSize;
+                return this;
+            }
+
+            /**
+             * Sets the initial transform which is applied to the page. This may be
+             * useful to move the origin to account for a margin, apply scale, or
+             * apply a rotation.
+             *
+             * @param transform The initial transform.
+             */
+            public Builder setInitialTransform(Matrix transform) {
+                mPageInfo.mInitialTransform = transform;
+                return this;
+            }
+
+            /**
+             * Creates a new {@link PageInfo}.
+             *
+             * @return The new instance.
+             */
+            public PageInfo create() {
+                if (mPageInfo.mContentSize == null) {
+                    mPageInfo.mContentSize = mPageInfo.mPageSize;
+                }
+                if (mPageInfo.mInitialTransform == null) {
+                    mPageInfo.mInitialTransform = new Matrix();
+                }
+                return mPageInfo;
+            }
+        }
+    }
+
+    /**
+     * This class represents a PDF document page. It has associated
+     * a canvas on which you can draw content and is acquired by a
+     * call to {@link #getCanvas()}. It also has associated a
+     * {@link PageInfo} instance that describes its attributes.
+     */
+    public static final class Page {
+        private final PageInfo mPageInfo;
+        private Canvas mCanvas;
+
+        /**
+         * Creates a new instance.
+         *
+         * @param canvas The canvas of the page.
+         * @param pageInfo The info with meta-data.
+         */
+        private Page(Canvas canvas, PageInfo pageInfo) {
+            mCanvas = canvas;
+            mPageInfo = pageInfo;
+        }
+
+        /**
+         * Gets the {@link Canvas} of the page.
+         *
+         * @return The canvas if the page is not finished, null otherwise.
+         *
+         * @see PdfDocument#finishPage(Page)
+         */
+        public Canvas getCanvas() {
+            return mCanvas;
+        }
+
+        /**
+         * Gets the {@link PageInfo} with meta-data for the page.
+         *
+         * @return The page info.
+         *
+         * @see PdfDocument#finishPage(Page)
+         */
+        public PageInfo getInfo() {
+            return mPageInfo;
+        }
+
+        private void finish() {
+            if (mCanvas != null) {
+                mCanvas.release();
+                mCanvas = null;
+            }
+        }
+    }
+}
diff --git a/core/java/android/print/pdf/PrintedPdfDocument.java b/core/java/android/print/pdf/PrintedPdfDocument.java
new file mode 100644
index 0000000..1fd4646
--- /dev/null
+++ b/core/java/android/print/pdf/PrintedPdfDocument.java
@@ -0,0 +1,165 @@
+/*
+ * 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.print.pdf;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.print.PrintAttributes;
+import android.print.PrintAttributes.Margins;
+import android.print.PrintAttributes.MediaSize;
+import android.print.pdf.PdfDocument;
+import android.print.pdf.PdfDocument.Page;
+import android.print.pdf.PdfDocument.PageInfo;
+
+import java.io.OutputStream;
+import java.util.List;
+
+/**
+ * This class is a helper for printing content to a different media
+ * size. This class is responsible for computing a correct page size
+ * given some print constraints, i.e. {@link PrintAttributes}. It is
+ * an adapter around a {@link PdfDocument}.
+ */
+public final class PrintedPdfDocument {
+    private static final int MILS_PER_INCH = 1000;
+    private static final int POINTS_IN_INCH = 72;
+
+    private final PdfDocument mDocument = PdfDocument.open();
+    private final Rect mPageSize = new Rect();
+    private final Rect mContentSize = new Rect();
+
+    /**
+     * Opens a new document. The document pages are computed based on
+     * the passes in {@link PrintAttributes}.
+     * <p>
+     * <strong>Note:</strong> You must close the document after you are
+     * done by calling {@link #close()}
+     * </p>
+     *
+     * @param context Context instance for accessing resources.
+     * @param attributes The print attributes.
+     * @return The document.
+     *
+     * @see #close()
+     */
+    public static PrintedPdfDocument open(Context context, PrintAttributes attributes) {
+        return new PrintedPdfDocument(context, attributes);
+    }
+
+    /**
+     * Creates a new instance.
+     *
+     * @param context Context instance for accessing resources and services.
+     * @param attributes The {@link PrintAttributes} to user.
+     */
+    private PrintedPdfDocument(Context context, PrintAttributes attributes) {
+        MediaSize mediaSize = attributes.getMediaSize();
+
+        // Compute the size of the target canvas from the attributes.
+        final int pageWidth = (int) (((float) mediaSize.getWidthMils() / MILS_PER_INCH)
+                * POINTS_IN_INCH);
+        final int pageHeight = (int) (((float) mediaSize.getHeightMils() / MILS_PER_INCH)
+                * POINTS_IN_INCH);
+        mPageSize.set(0, 0, pageWidth, pageHeight);
+
+        // Compute the content size from the attributes.
+        Margins minMargins = attributes.getMinMargins();
+        final int marginLeft = (int) (((float) minMargins.getLeftMils() /MILS_PER_INCH)
+                * POINTS_IN_INCH);
+        final int marginTop = (int) (((float) minMargins.getTopMils() / MILS_PER_INCH)
+                * POINTS_IN_INCH);
+        final int marginRight = (int) (((float) minMargins.getRightMils() / MILS_PER_INCH)
+                * POINTS_IN_INCH);
+        final int marginBottom = (int) (((float) minMargins.getBottomMils() / MILS_PER_INCH)
+                * POINTS_IN_INCH);
+        mContentSize.set(mPageSize.left + marginLeft, mPageSize.top + marginTop,
+                mPageSize.right - marginRight, mPageSize.bottom - marginBottom);
+    }
+
+    /**
+     * Starts a page using a page size computed from the print attributes
+     * passed in {@link #open(Context, PrintAttributes)} and the given page
+     * number to create appropriate {@link PageInfo}.
+     * <p>
+     * After the page is created you can draw arbitrary content on the page's
+     * canvas which you can get by calling {@link Page#getCanvas() Page.getCanvas()}.
+     * After you are done drawing the content you should finish the page by calling
+     * {@link #finishPage(Page)}. After the page is finished you should no longer
+     * access the page or its canvas.
+     * </p>
+     * <p>
+     * <strong>Note:</strong> Do not call this method after {@link #close()}.
+     * </p>
+     *
+     * @param pageNumber The page number.
+     * @return A blank page.
+     *
+     * @see #finishPage(Page)
+     */
+    public Page startPage(int pageNumber) {
+        PageInfo pageInfo = new PageInfo
+                .Builder(mPageSize, 0)
+                .setContentSize(mContentSize)
+                .create();
+        Page page = mDocument.startPage(pageInfo);
+        return page;
+    }
+
+    /**
+     * Finishes a started page. You should always finish the last started page.
+     * <p>
+     * <strong>Note:</strong> Do not call this method after {@link #close()}.
+     * </p>
+     *
+     * @param page The page.
+     *
+     * @see #startPage(int)
+     */
+    public void finishPage(Page page) {
+        mDocument.finishPage(page);
+    }
+
+    /**
+     * Writes the document to an output stream.
+     * <p>
+     * <strong>Note:</strong> Do not call this method after {@link #close()}.
+     * </p>
+     *
+     * @param out The output stream.
+     */
+    public void writeTo(OutputStream out) {
+        mDocument.writeTo(out);
+    }
+
+    /**
+     * Gets the pages of the document.
+     *
+     * @return The pages.
+     */
+    public List<PageInfo> getPages() {
+        return mDocument.getPages();
+    }
+
+    /**
+     * Closes this document. This method should be called after you
+     * are done working with the document. After this call the document
+     * is considered closed and none of its methods should be called.
+     */
+    public void close() {
+        mDocument.close();
+    }
+}
diff --git a/core/java/android/printservice/IPrintService.aidl b/core/java/android/printservice/IPrintService.aidl
new file mode 100644
index 0000000..ee36619
--- /dev/null
+++ b/core/java/android/printservice/IPrintService.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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 languagÿe governing permissions and
+ * limitations under the License.
+ */
+
+package android.printservice;
+
+import android.print.PrinterId;
+import android.print.PrintJobInfo;
+import android.printservice.IPrintServiceClient;
+
+/**
+ * Top-level interface to a print service component.
+ *
+ * @hide
+ */
+oneway interface IPrintService {
+    void setClient(IPrintServiceClient client);
+    void requestCancelPrintJob(in PrintJobInfo printJobInfo);
+    void onPrintJobQueued(in PrintJobInfo printJobInfo);
+
+    void createPrinterDiscoverySession();
+    void startPrinterDiscovery(in List<PrinterId> priorityList);
+    void stopPrinterDiscovery();
+    void validatePrinters(in List<PrinterId> printerIds);
+    void startPrinterStateTracking(in PrinterId printerId);
+    void stopPrinterStateTracking(in PrinterId printerId);
+    void destroyPrinterDiscoverySession();
+}
diff --git a/core/java/android/printservice/IPrintServiceClient.aidl b/core/java/android/printservice/IPrintServiceClient.aidl
new file mode 100644
index 0000000..ad3c04f
--- /dev/null
+++ b/core/java/android/printservice/IPrintServiceClient.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.printservice;
+
+import android.os.ParcelFileDescriptor;
+import android.print.PrintJobInfo;
+import android.print.PrinterId;
+import android.print.PrinterInfo;
+
+/**
+ * The top-level interface from a print service to the system.
+ *
+ * @hide
+ */
+interface IPrintServiceClient {
+    List<PrintJobInfo> getPrintJobInfos();
+    PrintJobInfo getPrintJobInfo(int printJobId);
+    boolean setPrintJobState(int printJobId, int state, String error);
+    boolean setPrintJobTag(int printJobId, String tag);
+    oneway void writePrintJobData(in ParcelFileDescriptor fd, int printJobId);
+
+    void onPrintersAdded(in List<PrinterInfo> printers);
+    void onPrintersRemoved(in List<PrinterId> printerIds);
+}
diff --git a/core/java/android/printservice/PrintDocument.java b/core/java/android/printservice/PrintDocument.java
new file mode 100644
index 0000000..8292cfbc
--- /dev/null
+++ b/core/java/android/printservice/PrintDocument.java
@@ -0,0 +1,96 @@
+/*
+ * 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.printservice;
+
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.print.PrintDocumentInfo;
+import android.util.Log;
+
+import java.io.IOException;
+
+/**
+ * This class represents a printed document from the perspective of a print
+ * service. It exposes APIs to query the document and obtain its data.
+ * <p>
+ * <strong>Note: </strong> All methods of this class must be executed on the
+ * main application thread.
+ * </p>
+ */
+public final class PrintDocument {
+
+    private static final String LOG_TAG = "PrintDocument";
+
+    private final int mPrintJobId;
+
+    private final IPrintServiceClient mPrintServiceClient;
+
+    private final PrintDocumentInfo mInfo;
+
+    PrintDocument(int printJobId, IPrintServiceClient printServiceClient,
+            PrintDocumentInfo info) {
+        mPrintJobId = printJobId;
+        mPrintServiceClient = printServiceClient;
+        mInfo = info;
+    }
+
+    /**
+     * Gets the {@link PrintDocumentInfo} that describes this document.
+     *
+     * @return The document info.
+     */
+    public PrintDocumentInfo getInfo() {
+        PrintService.throwIfNotCalledOnMainThread();
+        return mInfo;
+    }
+
+    /**
+     * Gets the data associated with this document.
+     * <p>
+     * <strong>Note: </strong> It is a responsibility of the client to open a
+     * stream to the returned file descriptor, fully read the data, and close
+     * the file descriptor.
+     * </p>
+     *
+     * @return A file descriptor for reading the data.
+     */
+    public ParcelFileDescriptor getData() {
+        PrintService.throwIfNotCalledOnMainThread();
+        ParcelFileDescriptor source = null;
+        ParcelFileDescriptor sink = null;
+        try {
+            ParcelFileDescriptor[] fds = ParcelFileDescriptor.createPipe();
+            source = fds[0];
+            sink = fds[1];
+            mPrintServiceClient.writePrintJobData(sink, mPrintJobId);
+            return source;
+        } catch (IOException ioe) {
+            Log.e(LOG_TAG, "Error calling getting print job data!", ioe);
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error calling getting print job data!", re);
+        } finally {
+            if (sink != null) {
+                try {
+                    sink.close();
+                } catch (IOException ioe) {
+                    /* ignore */
+                }
+            }
+        }
+        return null;
+    }
+}
diff --git a/core/java/android/printservice/PrintJob.java b/core/java/android/printservice/PrintJob.java
new file mode 100644
index 0000000..4ff7f0c
--- /dev/null
+++ b/core/java/android/printservice/PrintJob.java
@@ -0,0 +1,345 @@
+/*
+ * 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.printservice;
+
+import android.os.RemoteException;
+import android.print.PrintJobInfo;
+import android.text.TextUtils;
+import android.util.Log;
+
+/**
+ * This class represents a print job from the perspective of a print
+ * service. It provides APIs for observing the print job state and
+ * performing operations on the print job.
+ * <p>
+ * <strong>Note: </strong> All methods of this class must be invoked on
+ * the main application thread.
+ * </p>
+ */
+public final class PrintJob {
+
+    private static final String LOG_TAG = "PrintJob";
+
+    private final IPrintServiceClient mPrintServiceClient;
+
+    private final PrintDocument mDocument;
+
+    private PrintJobInfo mCachedInfo;
+
+    PrintJob(PrintJobInfo jobInfo, IPrintServiceClient client) {
+        mCachedInfo = jobInfo;
+        mPrintServiceClient = client;
+        mDocument = new PrintDocument(mCachedInfo.getId(), client,
+                jobInfo.getDocumentInfo());
+    }
+
+    /**
+     * Gets the unique print job id.
+     *
+     * @return The id.
+     */
+    public int getId() {
+        PrintService.throwIfNotCalledOnMainThread();
+        return mCachedInfo.getId();
+    }
+
+    /**
+     * Gets the {@link PrintJobInfo} that describes this job.
+     * <p>
+     * <strong>Node:</strong>The returned info object is a snapshot of the
+     * current print job state. Every call to this method returns a fresh
+     * info object that reflects the current print job state.
+     * </p>
+     *
+     * @return The print job info.
+     */
+    public PrintJobInfo getInfo() {
+        PrintService.throwIfNotCalledOnMainThread();
+        if (isInImmutableState()) {
+            return mCachedInfo;
+        }
+        PrintJobInfo info = null;
+        try {
+            info = mPrintServiceClient.getPrintJobInfo(mCachedInfo.getId());
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Couldn't get info for job: " + mCachedInfo.getId(), re);
+        }
+        if (info != null) {
+            mCachedInfo = info;
+        }
+        return mCachedInfo;
+    }
+
+    /**
+     * Gets the printed document.
+     *
+     * @return The document.
+     */
+    public PrintDocument getDocument() {
+        PrintService.throwIfNotCalledOnMainThread();
+        return mDocument;
+    }
+
+    /**
+     * Gets whether this print job is queued. Such a print job is
+     * ready to be printed and can be started or cancelled.
+     *
+     * @return Whether the print job is queued.
+     *
+     * @see #start()
+     * @see #cancel()
+     */
+    public boolean isQueued() {
+        PrintService.throwIfNotCalledOnMainThread();
+        return getInfo().getState() == PrintJobInfo.STATE_QUEUED;
+    }
+
+    /**
+     * Gets whether this print job is started. Such a print job is
+     * being printed and can be completed or canceled or failed.
+     *
+     * @return Whether the print job is started.
+     *
+     * @see #complete()
+     * @see #cancel()
+     * @see #fail(CharSequence)
+     */
+    public boolean isStarted() {
+        PrintService.throwIfNotCalledOnMainThread();
+        return getInfo().getState() == PrintJobInfo.STATE_STARTED;
+    }
+
+    /**
+     * Gets whether this print job is blocked. Such a print job is halted
+     * due to an abnormal condition and can be started or canceled or failed.
+     *
+     * @return Whether the print job is blocked.
+     *
+     * @see #start()
+     * @see #cancel()
+     * @see #fail(CharSequence)
+     */
+    public boolean isBlocked() {
+        PrintService.throwIfNotCalledOnMainThread();
+        return getInfo().getState() == PrintJobInfo.STATE_BLOCKED;
+    }
+
+    /**
+     * Gets whether this print job is completed. Such a print job
+     * is successfully printed. This is a final state.
+     *
+     * @return Whether the print job is completed.
+     *
+     * @see #complete()
+     */
+    public boolean isCompleted() {
+        PrintService.throwIfNotCalledOnMainThread();
+        return getInfo().getState() == PrintJobInfo.STATE_COMPLETED;
+    }
+
+    /**
+     * Gets whether this print job is failed. Such a print job is
+     * not successfully printed due to an error. This is a final state.
+     *
+     * @return Whether the print job is failed.
+     *
+     * @see #fail(CharSequence)
+     */
+    public boolean isFailed() {
+        PrintService.throwIfNotCalledOnMainThread();
+        return getInfo().getState() == PrintJobInfo.STATE_FAILED;
+    }
+
+    /**
+     * Gets whether this print job is cancelled. Such a print job was
+     * cancelled as a result of a user request. This is a final state.
+     *
+     * @return Whether the print job is cancelled.
+     *
+     * @see #cancel()
+     */
+    public boolean isCancelled() {
+        PrintService.throwIfNotCalledOnMainThread();
+        return getInfo().getState() == PrintJobInfo.STATE_FAILED;
+    }
+
+    /**
+     * Starts the print job. You should call this method if {@link
+     * #isQueued()} or {@link #isBlocked()} returns true and you started
+     * resumed printing.
+     *
+     * @return Whether the job was started.
+     *
+     * @see #isQueued()
+     * @see #isBlocked()
+     */
+    public boolean start() {
+        PrintService.throwIfNotCalledOnMainThread();
+        final int state = getInfo().getState();
+        if (state == PrintJobInfo.STATE_QUEUED
+                || state == PrintJobInfo.STATE_BLOCKED) {
+            return setState(PrintJobInfo.STATE_STARTED, null);
+        }
+        return false;
+    }
+
+    /**
+     * Blocks the print job. You should call this method if {@link
+     * #isStarted()} or {@link #isBlocked()} returns true and you need
+     * to block the print job. For example, the user has to add some
+     * paper to continue printing. To resume the print job call {@link
+     * #start()}.
+     *
+     * @return Whether the job was blocked.
+     *
+     * @see #isStarted()
+     * @see #isBlocked()
+     */
+    public boolean block(String reason) {
+        PrintService.throwIfNotCalledOnMainThread();
+        PrintJobInfo info = getInfo();
+        final int state = info.getState();
+        if (state == PrintJobInfo.STATE_STARTED
+                || (state == PrintJobInfo.STATE_BLOCKED
+                        && !TextUtils.equals(info.getStateReason(), reason))) {
+            return setState(PrintJobInfo.STATE_BLOCKED, reason);
+        }
+        return false;
+    }
+
+    /**
+     * Completes the print job. You should call this method if {@link
+     * #isStarted()} returns true and you are done printing.
+     *
+     * @return Whether the job as completed.
+     *
+     * @see #isStarted()
+     */
+    public boolean complete() {
+        PrintService.throwIfNotCalledOnMainThread();
+        if (isStarted()) {
+            return setState(PrintJobInfo.STATE_COMPLETED, null);
+        }
+        return false;
+    }
+
+    /**
+     * Fails the print job. You should call this method if {@link
+     * #isQueued()} or {@link #isStarted()} or {@link #isBlocked()}
+     * returns true you failed while printing.
+     *
+     * @param error The human readable, short, and translated reason
+     * for the failure.
+     * @return Whether the job was failed.
+     *
+     * @see #isQueued()
+     * @see #isStarted()
+     * @see #isBlocked()
+     */
+    public boolean fail(String error) {
+        PrintService.throwIfNotCalledOnMainThread();
+        if (!isInImmutableState()) {
+            return setState(PrintJobInfo.STATE_FAILED, error);
+        }
+        return false;
+    }
+
+    /**
+     * Cancels the print job. You should call this method if {@link
+     * #isQueued()} or {@link #isStarted() or #isBlocked()} returns
+     * true and you canceled the print job as a response to a call to
+     * {@link PrintService#onRequestCancelPrintJob(PrintJob)}.
+     *
+     * @return Whether the job is canceled.
+     *
+     * @see #isStarted()
+     * @see #isQueued()
+     * @see #isBlocked()
+     */
+    public boolean cancel() {
+        PrintService.throwIfNotCalledOnMainThread();
+        if (!isInImmutableState()) {
+            return setState(PrintJobInfo.STATE_CANCELED, null);
+        }
+        return false;
+    }
+
+    /**
+     * Sets a tag that is valid in the context of a {@link PrintService}
+     * and is not interpreted by the system. For example, a print service
+     * may set as a tag the key of the print job returned by a remote
+     * print server, if the printing is off handed to a cloud based service.
+     *
+     * @param tag The tag.
+     * @return True if the tag was set, false otherwise.
+     */
+    public boolean setTag(String tag) {
+        PrintService.throwIfNotCalledOnMainThread();
+        if (isInImmutableState()) {
+            return false;
+        }
+        try {
+            return mPrintServiceClient.setPrintJobTag(mCachedInfo.getId(), tag);
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error setting tag for job: " + mCachedInfo.getId(), re);
+        }
+        return false;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        PrintJob other = (PrintJob) obj;
+        return (mCachedInfo.getId() == other.mCachedInfo.getId());
+    }
+
+    @Override
+    public int hashCode() {
+        return mCachedInfo.getId();
+    }
+
+    private boolean isInImmutableState() {
+        final int state = mCachedInfo.getState();
+        return state == PrintJobInfo.STATE_COMPLETED
+                || state == PrintJobInfo.STATE_CANCELED
+                || state == PrintJobInfo.STATE_FAILED;
+    }
+
+    private boolean setState(int state, String error) {
+        try {
+            if (mPrintServiceClient.setPrintJobState(mCachedInfo.getId(), state, error)) {
+                // Best effort - update the state of the cached info since
+                // we may not be able to re-fetch it later if the job gets
+                // removed from the spooler as a result of the state change.
+                mCachedInfo.setState(state);
+                mCachedInfo.setStateReason(error);
+                return true;
+            }
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error setting the state of job: " + mCachedInfo.getId(), re);
+        }
+        return false;
+    }
+}
diff --git a/core/java/android/printservice/PrintService.java b/core/java/android/printservice/PrintService.java
new file mode 100644
index 0000000..e5ebf77
--- /dev/null
+++ b/core/java/android/printservice/PrintService.java
@@ -0,0 +1,467 @@
+/*
+ * 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.printservice;
+
+import android.app.Service;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.print.PrintJobInfo;
+import android.print.PrinterId;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * <p>
+ * This is the base class for implementing print services. A print service knows
+ * how to discover and interact one or more printers via one or more protocols.
+ * </p>
+ * <h3>Printer discovery</h3>
+ * <p>
+ * A print service is responsible for discovering printers, adding discovered printers,
+ * removing added printers, and updating added printers. When the system is interested
+ * in printers managed by your service it will call {@link
+ * #onCreatePrinterDiscoverySession()} from which you must return a new {@link
+ * PrinterDiscoverySession} instance. The returned session encapsulates the interaction
+ * between the system and your service during printer discovery. For description of this
+ * interaction refer to the documentation for {@link PrinterDiscoverySession}.
+ * </p>
+ * <p>
+ * For every printer discovery session all printers have to be added since system does
+ * not retain printers across sessions. Hence, each printer known to this print service
+ * should be added only once during a discovery session. Only an already added printer
+ * can be removed or updated. Removed printers can be added again.
+ * </p>
+ * <h3>Print jobs</h3>
+ * <p>
+ * When a new print job targeted to a printer managed by this print service is is queued,
+ * i.e. ready for processing by the print service, you will receive a call to {@link
+ * #onPrintJobQueued(PrintJob)}. The print service may handle the print job immediately
+ * or schedule that for an appropriate time in the future. The list of all active print
+ * jobs for this service is obtained by calling {@link #getActivePrintJobs()}. Active
+ * print jobs are ones that are queued or started.
+ * </p>
+ * <p>
+ * A print service is responsible for setting a print job's state as appropriate
+ * while processing it. Initially, a print job is queued, i.e. {@link PrintJob#isQueued()
+ * PrintJob.isQueued()} returns true, which means that the document to be printed is
+ * spooled by the system and the print service can begin processing it. You can obtain
+ * the printed document by calling {@link PrintJob#getDocument() PrintJob.getDocument()}
+ * whose data is accessed via {@link PrintDocument#getData() PrintDocument.getData()}.
+ * After the print service starts printing the data it should set the print job's
+ * state to started by calling {@link PrintJob#start()} after which
+ * {@link PrintJob#isStarted() PrintJob.isStarted()} would return true. Upon successful
+ * completion, the print job should be marked as completed by calling {@link
+ * PrintJob#complete() PrintJob.complete()} after which {@link PrintJob#isCompleted()
+ * PrintJob.isCompleted()} would return true. In case of a failure, the print job should
+ * be marked as failed by calling {@link PrintJob#fail(String) PrintJob.fail(
+ * String)} after which {@link PrintJob#isFailed() PrintJob.isFailed()} would
+ * return true.
+ * </p>
+ * <p>
+ * If a print job is queued or started and the user requests to cancel it, the print
+ * service will receive a call to {@link #onRequestCancelPrintJob(PrintJob)} which
+ * requests from the service to do best effort in canceling the job. In case the job
+ * is successfully canceled, its state has to be marked as cancelled by calling {@link
+ * PrintJob#cancel() PrintJob.cancel()} after which {@link PrintJob#isCancelled()
+ * PrintJob.isCacnelled()} would return true.
+ * </p>
+ * <h3>Lifecycle</h3>
+ * <p>
+ * The lifecycle of a print service is managed exclusively by the system and follows
+ * the established service lifecycle. Additionally, starting or stopping a print service
+ * is triggered exclusively by an explicit user action through enabling or disabling it
+ * in the device settings. After the system binds to a print service, it calls {@link
+ * #onConnected()}. This method can be overriden by clients to perform post binding setup.
+ * Also after the system unbinds from a print service, it calls {@link #onDisconnected()}.
+ * This method can be overriden by clients to perform post unbinding cleanup. Your should
+ * not do any work after the system disconnected from your print service since the
+ * service can be killed at any time to reclaim memory. The system will not disconnect
+ * from a print service if there are active print jobs for the printers managed by it.
+ * </p>
+ * <h3>Declaration</h3>
+ * <p>
+ * A print service is declared as any other service in an AndroidManifest.xml but it must
+ * also specify that it handles the {@link android.content.Intent} with action {@link
+ * #SERVICE_INTERFACE android.printservice.PrintService}. Failure to declare this intent
+ * will cause the system to ignore the print service. Additionally, a print service must
+ * request the {@link android.Manifest.permission#BIND_PRINT_SERVICE
+ * android.permission.BIND_PRINT_SERVICE} permission to ensure that only the system can
+ * bind to it. Failure to declare this intent will cause the system to ignore the print
+ * service. Following is an example declaration:
+ * </p>
+ * <pre>
+ * &lt;service android:name=".MyPrintService"
+ *         android:permission="android.permission.BIND_PRINT_SERVICE"&gt;
+ *     &lt;intent-filter&gt;
+ *         &lt;action android:name="android.printservice.PrintService" /&gt;
+ *     &lt;/intent-filter&gt;
+ *     . . .
+ * &lt;/service&gt;
+ * </pre>
+ * <h3>Configuration</h3>
+ * <p>
+ * A print service can be configured by specifying an optional settings activity which
+ * exposes service specific settings, an optional add printers activity which is used for
+ * manual addition of printers, vendor name ,etc. It is a responsibility of the system
+ * to launch the settings and add printers activities when appropriate.
+ * </p>
+ * <p>
+ * A print service is configured by providing a {@link #SERVICE_META_DATA meta-data}
+ * entry in the manifest when declaring the service. A service declaration with a meta-data
+ * tag is presented below:
+ * <pre> &lt;service android:name=".MyPrintService"
+ *         android:permission="android.permission.BIND_PRINT_SERVICE"&gt;
+ *     &lt;intent-filter&gt;
+ *         &lt;action android:name="android.printservice.PrintService" /&gt;
+ *     &lt;/intent-filter&gt;
+ *     &lt;meta-data android:name="android.printservice" android:resource="@xml/printservice" /&gt;
+ * &lt;/service&gt;</pre>
+ * </p>
+ * <p>
+ * For more details for how to configure your print service via the meta-data refer to
+ * {@link #SERVICE_META_DATA} and <code>&lt;{@link android.R.styleable#PrintService
+ * print-service}&gt;</code>.
+ * </p>
+ * <p>
+ * <strong>Note: </strong> All callbacks in this class are executed on the main
+ * application thread. You should also invoke any method of this class on the main
+ * application thread.
+ * </p>
+ */
+public abstract class PrintService extends Service {
+
+    private static final String LOG_TAG = "PrintService";
+
+    private static final boolean DEBUG = false;
+
+    /**
+     * The {@link Intent} action that must be declared as handled by a service
+     * in its manifest for the system to recognize it as a print service.
+     */
+    public static final String SERVICE_INTERFACE = "android.printservice.PrintService";
+
+    /**
+     * Name under which a {@link PrintService} component publishes additional information
+     * about itself. This meta-data must reference a XML resource containing a <code>
+     * &lt;{@link android.R.styleable#PrintService print-service}&gt;</code> tag. This is
+     * a sample XML file configuring a print service:
+     * <pre> &lt;print-service
+     *     android:vendor="SomeVendor"
+     *     android:settingsActivity="foo.bar.MySettingsActivity"
+     *     andorid:addPrintersActivity="foo.bar.MyAddPrintersActivity."
+     *     . . .
+     * /&gt;</pre>
+     * <p>
+     * For detailed configuration options that can be specified via the meta-data
+     * refer to {@link android.R.styleable#PrintService android.R.styleable.PrintService}.
+     * </p>
+     * <p>
+     * If you declare a settings or add a printers activity, they have to be exported,
+     * by setting the {@link android.R.attr#exported} activity attribute to <code>true
+     * </code>. Also in case you want only the system to be able to start any of these
+     * activities you can specify that they request the android.permission
+     * .START_PRINT_SERVICE_CONFIG_ACTIVITY permission by setting the
+     * {@link android.R.attr#permission} activity attribute.
+     * </p>
+     */
+    public static final String SERVICE_META_DATA = "android.printservice";
+
+    private Handler mHandler;
+
+    private IPrintServiceClient mClient;
+
+    private int mLastSessionId = -1;
+
+    private PrinterDiscoverySession mDiscoverySession;
+
+    @Override
+    protected final void attachBaseContext(Context base) {
+        super.attachBaseContext(base);
+        mHandler = new ServiceHandler(base.getMainLooper());
+    }
+
+    /**
+     * The system has connected to this service.
+     */
+    protected void onConnected() {
+        /* do nothing */
+    }
+
+    /**
+     * The system has disconnected from this service.
+     */
+    protected void onDisconnected() {
+        /* do nothing */
+    }
+
+    /**
+     * Callback asking you to create a new {@link PrinterDiscoverySession}.
+     *
+     * @see PrinterDiscoverySession
+     */
+    protected abstract PrinterDiscoverySession onCreatePrinterDiscoverySession();
+
+    /**
+     * Called when cancellation of a print job is requested. The service
+     * should do best effort to fulfill the request. After the cancellation
+     * is performed, the print job should be marked as cancelled state by
+     * calling {@link PrintJob#cancel()}.
+     *
+     * @param printJob The print job to cancel.
+     *
+     * @see PrintJob#cancel() PrintJob.cancel()
+     * @see PrintJob#isCancelled() PrintJob.isCancelled()
+     */
+    protected abstract void onRequestCancelPrintJob(PrintJob printJob);
+
+    /**
+     * Called when there is a queued print job for one of the printers
+     * managed by this print service.
+     *
+     * @param printJob The new queued print job.
+     *
+     * @see PrintJob#isQueued() PrintJob.isQueued()
+     * @see #getActivePrintJobs()
+     */
+    protected abstract void onPrintJobQueued(PrintJob printJob);
+
+    /**
+     * Gets the active print jobs for the printers managed by this service.
+     * Active print jobs are ones that are not in a final state, i.e. whose
+     * state is queued or started.
+     *
+     * @return The active print jobs.
+     *
+     * @see PrintJob#isQueued() PrintJob.isQueued()
+     * @see PrintJob#isStarted() PrintJob.isStarted()
+     */
+    public final List<PrintJob> getActivePrintJobs() {
+        throwIfNotCalledOnMainThread();
+        if (mClient == null) {
+            return Collections.emptyList();
+        }
+        try {
+            List<PrintJob> printJobs = null;
+            List<PrintJobInfo> printJobInfos = mClient.getPrintJobInfos();
+            if (printJobInfos != null) {
+                final int printJobInfoCount = printJobInfos.size();
+                printJobs = new ArrayList<PrintJob>(printJobInfoCount);
+                for (int i = 0; i < printJobInfoCount; i++) {
+                    printJobs.add(new PrintJob(printJobInfos.get(i), mClient));
+                }
+            }
+            if (printJobs != null) {
+                return printJobs;
+            }
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error calling getPrintJobs()", re);
+        }
+        return Collections.emptyList();
+    }
+
+    /**
+     * Generates a global printer id given the printer's locally unique one.
+     *
+     * @param localId A locally unique id in the context of your print service.
+     * @return Global printer id.
+     */
+    public final PrinterId generatePrinterId(String localId) {
+        throwIfNotCalledOnMainThread();
+        return new PrinterId(new ComponentName(getPackageName(),
+                getClass().getName()), localId);
+    }
+
+    static void throwIfNotCalledOnMainThread() {
+        if (!Looper.getMainLooper().isCurrentThread()) {
+            throw new IllegalAccessError("must be called from the main thread");
+        }
+    }
+
+    @Override
+    public final IBinder onBind(Intent intent) {
+        return new IPrintService.Stub() {
+            @Override
+            public void createPrinterDiscoverySession() {
+                mHandler.sendEmptyMessage(ServiceHandler.MSG_CREATE_PRINTER_DISCOVERY_SESSION);
+            }
+
+            @Override
+            public void destroyPrinterDiscoverySession() {
+                mHandler.sendEmptyMessage(ServiceHandler.MSG_DESTROY_PRINTER_DISCOVERY_SESSION);
+            }
+
+            public void startPrinterDiscovery(List<PrinterId> priorityList) {
+                mHandler.obtainMessage(ServiceHandler.MSG_START_PRINTER_DISCOVERY,
+                        priorityList).sendToTarget();
+            }
+
+            @Override
+            public void stopPrinterDiscovery() {
+                mHandler.sendEmptyMessage(ServiceHandler.MSG_STOP_PRINTER_DISCOVERY);
+            }
+
+            @Override
+            public void validatePrinters(List<PrinterId> printerIds) {
+                mHandler.obtainMessage(ServiceHandler.MSG_VALIDATE_PRINTERS,
+                        printerIds).sendToTarget();
+            }
+
+            @Override
+            public void startPrinterStateTracking(PrinterId printerId) {
+                mHandler.obtainMessage(ServiceHandler.MSG_START_PRINTER_STATE_TRACKING,
+                        printerId).sendToTarget();
+            }
+
+            @Override
+            public void stopPrinterStateTracking(PrinterId printerId) {
+                mHandler.obtainMessage(ServiceHandler.MSG_STOP_PRINTER_STATE_TRACKING,
+                        printerId).sendToTarget();
+            }
+
+            @Override
+            public void setClient(IPrintServiceClient client) {
+                mHandler.obtainMessage(ServiceHandler.MSG_SET_CLEINT, client)
+                        .sendToTarget();
+            }
+
+            @Override
+            public void requestCancelPrintJob(PrintJobInfo printJobInfo) {
+                mHandler.obtainMessage(ServiceHandler.MSG_ON_REQUEST_CANCEL_PRINTJOB,
+                        printJobInfo).sendToTarget();
+            }
+
+            @Override
+            public void onPrintJobQueued(PrintJobInfo printJobInfo) {
+                mHandler.obtainMessage(ServiceHandler.MSG_ON_PRINTJOB_QUEUED,
+                        printJobInfo).sendToTarget();
+            }
+        };
+    }
+
+    private final class ServiceHandler extends Handler {
+        public static final int MSG_CREATE_PRINTER_DISCOVERY_SESSION = 1;
+        public static final int MSG_DESTROY_PRINTER_DISCOVERY_SESSION = 2;
+        public static final int MSG_START_PRINTER_DISCOVERY = 3;
+        public static final int MSG_STOP_PRINTER_DISCOVERY = 4;
+        public static final int MSG_VALIDATE_PRINTERS = 5;
+        public static final int MSG_START_PRINTER_STATE_TRACKING = 6;
+        public static final int MSG_STOP_PRINTER_STATE_TRACKING = 7;
+        public static final int MSG_ON_PRINTJOB_QUEUED = 8;
+        public static final int MSG_ON_REQUEST_CANCEL_PRINTJOB = 9;
+        public static final int MSG_SET_CLEINT = 10;
+
+        public ServiceHandler(Looper looper) {
+            super(looper, null, true);
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public void handleMessage(Message message) {
+            final int action = message.what;
+            switch (action) {
+                case MSG_CREATE_PRINTER_DISCOVERY_SESSION: {
+                    PrinterDiscoverySession session = onCreatePrinterDiscoverySession();
+                    if (session == null) {
+                        throw new NullPointerException("session cannot be null");
+                    }
+                    if (session.getId() == mLastSessionId) {
+                        throw new IllegalStateException("cannot reuse session instances");
+                    }
+                    mDiscoverySession = session;
+                    mLastSessionId = session.getId();
+                    session.setObserver(mClient);
+                } break;
+
+                case MSG_DESTROY_PRINTER_DISCOVERY_SESSION: {
+                    if (mDiscoverySession != null) {
+                        mDiscoverySession.destroy();
+                        mDiscoverySession = null;
+                    }
+                } break;
+
+                case MSG_START_PRINTER_DISCOVERY: {
+                    if (mDiscoverySession != null) {
+                        List<PrinterId> priorityList = (ArrayList<PrinterId>) message.obj;
+                        mDiscoverySession.startPrinterDiscovery(priorityList);
+                    }
+                } break;
+
+                case MSG_STOP_PRINTER_DISCOVERY: {
+                    if (mDiscoverySession != null) {
+                        mDiscoverySession.stopPrinterDiscovery();
+                    }
+                } break;
+
+                case MSG_VALIDATE_PRINTERS: {
+                    if (mDiscoverySession != null) {
+                        List<PrinterId> printerIds = (List<PrinterId>) message.obj;
+                        mDiscoverySession.validatePrinters(printerIds);
+                    }
+                } break;
+
+                case MSG_START_PRINTER_STATE_TRACKING: {
+                    if (mDiscoverySession != null) {
+                        PrinterId printerId = (PrinterId) message.obj;
+                        mDiscoverySession.startPrinterStateTracking(printerId);
+                    }
+                } break;
+
+                case MSG_STOP_PRINTER_STATE_TRACKING: {
+                    if (mDiscoverySession != null) {
+                        PrinterId printerId = (PrinterId) message.obj;
+                        mDiscoverySession.stopPrinterStateTracking(printerId);
+                    }
+                } break;
+
+                case MSG_ON_REQUEST_CANCEL_PRINTJOB: {
+                    PrintJobInfo printJobInfo = (PrintJobInfo) message.obj;
+                    onRequestCancelPrintJob(new PrintJob(printJobInfo, mClient));
+                } break;
+
+                case MSG_ON_PRINTJOB_QUEUED: {
+                    PrintJobInfo printJobInfo = (PrintJobInfo) message.obj;
+                    if (DEBUG) {
+                        Log.i(LOG_TAG, "Queued: " + printJobInfo);
+                    }
+                    onPrintJobQueued(new PrintJob(printJobInfo, mClient));
+                } break;
+
+                case MSG_SET_CLEINT: {
+                    mClient = (IPrintServiceClient) message.obj;
+                    if (mClient != null) {
+                        onConnected();
+                     } else {
+                        onDisconnected();
+                     }
+                } break;
+
+                default: {
+                    throw new IllegalArgumentException("Unknown message: " + action);
+                }
+            }
+        }
+    }
+}
diff --git a/core/java/android/printservice/PrintServiceInfo.aidl b/core/java/android/printservice/PrintServiceInfo.aidl
new file mode 100644
index 0000000..95b67f2
--- /dev/null
+++ b/core/java/android/printservice/PrintServiceInfo.aidl
@@ -0,0 +1,19 @@
+/**
+ * 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.printservice;
+
+parcelable PrintServiceInfo;
diff --git a/core/java/android/printservice/PrintServiceInfo.java b/core/java/android/printservice/PrintServiceInfo.java
new file mode 100644
index 0000000..8e9636c
--- /dev/null
+++ b/core/java/android/printservice/PrintServiceInfo.java
@@ -0,0 +1,260 @@
+/*
+ * 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.printservice;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Xml;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+
+/**
+ * This class describes a {@link PrintService}. A print service knows
+ * how to communicate with one or more printers over one or more protocols
+ * and exposes printers for use by the applications via the platform print
+ * APIs.
+ *
+ * @see PrintService
+ * @see android.print.PrintManager
+ *
+ * @hide
+ */
+public final class PrintServiceInfo implements Parcelable {
+
+    private static final String LOG_TAG = PrintServiceInfo.class.getSimpleName();
+
+    private static final String TAG_PRINT_SERVICE = "print-service";
+
+    private final String mId;
+
+    private final ResolveInfo mResolveInfo;
+
+    private final String mSettingsActivityName;
+
+    private final String mAddPrintersActivityName;
+
+    /**
+     * Creates a new instance.
+     *
+     * @hide
+     */
+    public PrintServiceInfo(Parcel parcel) {
+        mId = parcel.readString();
+        mResolveInfo = parcel.readParcelable(null);
+        mSettingsActivityName = parcel.readString();
+        mAddPrintersActivityName = parcel.readString();
+    }
+
+    /**
+     * Creates a new instance.
+     *
+     * @param resolveInfo The service resolve info.
+     * @param settingsActivityName Optional settings activity name.
+     * @param addPrintersActivityName Optional add printers activity name.
+     */
+    public PrintServiceInfo(ResolveInfo resolveInfo, String settingsActivityName,
+            String addPrintersActivityName) {
+        mId = new ComponentName(resolveInfo.serviceInfo.packageName,
+                resolveInfo.serviceInfo.name).flattenToString();
+        mResolveInfo = resolveInfo;
+        mSettingsActivityName = settingsActivityName;
+        mAddPrintersActivityName = addPrintersActivityName;
+    }
+
+    /**
+     * Creates a new instance.
+     *
+     * @param resolveInfo The service resolve info.
+     * @param context Context for accessing resources.
+     * @throws XmlPullParserException If a XML parsing error occurs.
+     * @throws IOException If a I/O error occurs.
+     */
+    public static PrintServiceInfo create(ResolveInfo resolveInfo, Context context) {
+        String settingsActivityName = null;
+        String addPrintersActivityName = null;
+
+        XmlResourceParser parser = null;
+        PackageManager packageManager = context.getPackageManager();
+        parser = resolveInfo.serviceInfo.loadXmlMetaData(packageManager,
+                PrintService.SERVICE_META_DATA);
+        if (parser != null) {
+            try {
+                int type = 0;
+                while (type != XmlPullParser.END_DOCUMENT && type != XmlPullParser.START_TAG) {
+                    type = parser.next();
+                }
+
+                String nodeName = parser.getName();
+                if (!TAG_PRINT_SERVICE.equals(nodeName)) {
+                    Log.e(LOG_TAG, "Ignoring meta-data that does not start with "
+                            + TAG_PRINT_SERVICE + " tag");
+                } else {
+                    Resources resources = packageManager.getResourcesForApplication(
+                            resolveInfo.serviceInfo.applicationInfo);
+                    AttributeSet allAttributes = Xml.asAttributeSet(parser);
+                    TypedArray attributes = resources.obtainAttributes(allAttributes,
+                            com.android.internal.R.styleable.PrintService);
+
+                    settingsActivityName = attributes.getString(
+                            com.android.internal.R.styleable.PrintService_settingsActivity);
+
+                    addPrintersActivityName = attributes.getString(
+                            com.android.internal.R.styleable.PrintService_addPrintersActivity);
+
+                    attributes.recycle();
+                }
+            } catch (IOException ioe) {
+                Log.w(LOG_TAG, "Error reading meta-data:" + ioe);
+            } catch (XmlPullParserException xppe) {
+                Log.w(LOG_TAG, "Error reading meta-data:" + xppe);
+            } catch (NameNotFoundException e) {
+                Log.e(LOG_TAG, "Unable to load resources for: "
+                        + resolveInfo.serviceInfo.packageName);
+            } finally {
+                if (parser != null) {
+                    parser.close();
+                }
+            }
+        }
+
+        return new PrintServiceInfo(resolveInfo, settingsActivityName, addPrintersActivityName);
+    }
+
+    /**
+     * The accessibility service id.
+     * <p>
+     * <strong>Generated by the system.</strong>
+     * </p>
+     *
+     * @return The id.
+     */
+    public String getId() {
+        return mId;
+    }
+
+    /**
+     * The service {@link ResolveInfo}.
+     *
+     * @return The info.
+     */
+    public ResolveInfo getResolveInfo() {
+        return mResolveInfo;
+    }
+
+    /**
+     * The settings activity name.
+     * <p>
+     * <strong>Statically set from
+     * {@link PrintService#SERVICE_META_DATA meta-data}.</strong>
+     * </p>
+     *
+     * @return The settings activity name.
+     */
+    public String getSettingsActivityName() {
+        return mSettingsActivityName;
+    }
+
+    /**
+     * The add printers activity name.
+     * <p>
+     * <strong>Statically set from
+     * {@link PrintService#SERVICE_META_DATA meta-data}.</strong>
+     * </p>
+     *
+     * @return The add printers activity name.
+     */
+    public String getAddPrintersActivityName() {
+        return mAddPrintersActivityName;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public int describeContents() {
+        return 0;
+    }
+
+    public void writeToParcel(Parcel parcel, int flagz) {
+        parcel.writeString(mId);
+        parcel.writeParcelable(mResolveInfo, 0);
+        parcel.writeString(mSettingsActivityName);
+        parcel.writeString(mAddPrintersActivityName);
+    }
+
+    @Override
+    public int hashCode() {
+        return 31 + ((mId == null) ? 0 : mId.hashCode());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        PrintServiceInfo other = (PrintServiceInfo) obj;
+        if (mId == null) {
+            if (other.mId != null) {
+                return false;
+            }
+        } else if (!mId.equals(other.mId)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("PrintServiceInfo{");
+        builder.append("id=").append(mId);
+        builder.append(", resolveInfo=").append(mResolveInfo);
+        builder.append(", settingsActivityName=").append(mSettingsActivityName);
+        builder.append(", addPrintersActivityName=").append(mAddPrintersActivityName);
+        builder.append("}");
+        return builder.toString();
+    }
+
+    public static final Parcelable.Creator<PrintServiceInfo> CREATOR =
+            new Parcelable.Creator<PrintServiceInfo>() {
+        public PrintServiceInfo createFromParcel(Parcel parcel) {
+            return new PrintServiceInfo(parcel);
+        }
+
+        public PrintServiceInfo[] newArray(int size) {
+            return new PrintServiceInfo[size];
+        }
+    };
+}
diff --git a/core/java/android/printservice/PrinterDiscoverySession.java b/core/java/android/printservice/PrinterDiscoverySession.java
new file mode 100644
index 0000000..b0bf3da
--- /dev/null
+++ b/core/java/android/printservice/PrinterDiscoverySession.java
@@ -0,0 +1,549 @@
+/*
+ * 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.printservice;
+
+import android.os.RemoteException;
+import android.print.PrinterCapabilitiesInfo;
+import android.print.PrinterId;
+import android.print.PrinterInfo;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * This class encapsulates the interaction between a print service and the
+ * system during printer discovery. During printer discovery you are responsible
+ * for adding discovered printers, removing previously added printers that
+ * disappeared, and updating already added printers.
+ * <p>
+ * During the lifetime of this session you may be asked to start and stop
+ * performing printer discovery multiple times. You will receive a call to {@link
+ * PrinterDiscoverySession#onStartPrinterDiscovery(List)} to start printer
+ * discovery and a call to {@link PrinterDiscoverySession#onStopPrinterDiscovery()}
+ * to stop printer discovery. When the system is no longer interested in printers
+ * discovered by this session you will receive a call to {@link #onDestroy()} at
+ * which point the system will no longer call into the session and all the session
+ * methods will do nothing.
+ * </p>
+ * <p>
+ * Discovered printers are added by invoking {@link
+ * PrinterDiscoverySession#addPrinters(List)}. Added printers that disappeared are
+ * removed by invoking {@link PrinterDiscoverySession#removePrinters(List)}. Added
+ * printers whose properties or capabilities changed are updated through a call to
+ * {@link PrinterDiscoverySession#addPrinters(List)}. The printers added in this
+ * session can be acquired via {@link #getPrinters()} where the returned printers
+ * will be an up-to-date snapshot of the printers that you reported during the
+ * session. Printers are <strong>not</strong> persisted across sessions.
+ * </p>
+ * <p>
+ * The system will make a call to {@link #onValidatePrinters(List)} if you
+ * need to update some printers. It is possible that you add a printer without
+ * specifying its capabilities. This enables you to avoid querying all discovered
+ * printers for their capabilities, rather querying the capabilities of a printer
+ * only if necessary. For example, the system will request that you update a printer
+ * if it gets selected by the user. When validating printers you do not need to
+ * provide the printers' capabilities but may do so.
+ * </p>
+ * <p>
+ * If the system is interested in being constantly updated for the state of a
+ * printer you will receive a call to {@link #onStartPrinterStateTracking(PrinterId)}
+ * after which you will have to do a best effort to keep the system updated for
+ * changes in the printer state and capabilities. You also <strong>must</strong>
+ * update the printer capabilities if you did not provide them when adding it, or
+ * the printer will be ignored. When the system is no longer interested in getting
+ * updates for a printer you will receive a call to {@link #onStopPrinterStateTracking(
+ * PrinterId)}.
+ * </p>
+ * <p>
+ * <strong>Note: </strong> All callbacks in this class are executed on the main
+ * application thread. You also have to invoke any method of this class on the main
+ * application thread.
+ * </p>
+ */
+public abstract class PrinterDiscoverySession {
+    private static final String LOG_TAG = "PrinterDiscoverySession";
+
+    private static final int MAX_ITEMS_PER_CALLBACK = 50;
+
+    private static int sIdCounter = 0;
+
+    private final int mId;
+
+    private final ArrayMap<PrinterId, PrinterInfo> mPrinters =
+            new ArrayMap<PrinterId, PrinterInfo>();
+
+    private final List<PrinterId> mTrackedPrinters =
+            new ArrayList<PrinterId>();
+
+    private ArrayMap<PrinterId, PrinterInfo> mLastSentPrinters;
+
+    private IPrintServiceClient mObserver;
+
+    private boolean mIsDestroyed;
+
+    private boolean mIsDiscoveryStarted;
+
+    /**
+     * Constructor.
+     */
+    public PrinterDiscoverySession() {
+        mId = sIdCounter++;
+    }
+
+    void setObserver(IPrintServiceClient observer) {
+        mObserver = observer;
+        // If some printers were added in the method that
+        // created the session, send them over.
+        if (!mPrinters.isEmpty()) {
+            sendAddedPrinters(mObserver, getPrinters());
+        }
+    }
+
+    int getId() {
+        return mId;
+    }
+
+    /**
+     * Gets the printers reported in this session. For example, if you add two
+     * printers and remove one of them, the returned list will contain only
+     * the printer that was added but not removed.
+     * <p>
+     * <strong>Note: </strong> Calls to this method after the session is
+     * destroyed, that is after the {@link #onDestroy()} callback, will be ignored.
+     * </p>
+     *
+     * @return The printers.
+     *
+     * @see #addPrinters(List)
+     * @see #removePrinters(List)
+     * @see #isDestroyed()
+     */
+    public final List<PrinterInfo> getPrinters() {
+        PrintService.throwIfNotCalledOnMainThread();
+        if (mIsDestroyed) {
+            return Collections.emptyList();
+        }
+        return new ArrayList<PrinterInfo>(mPrinters.values());
+    }
+
+    /**
+     * Adds discovered printers. Adding an already added printer updates it.
+     * Removed printers can be added again. You can call this method multiple
+     * times during the life of this session. Duplicates will be ignored.
+     * <p>
+     * <strong>Note: </strong> Calls to this method after the session is
+     * destroyed, that is after the {@link #onDestroy()} callback, will be ignored.
+     * </p>
+     *
+     * @param printers The printers to add.
+     *
+     * @see #removePrinters(List)
+     * @see #getPrinters()
+     * @see #isDestroyed()
+     */
+    public final void addPrinters(List<PrinterInfo> printers) {
+        PrintService.throwIfNotCalledOnMainThread();
+
+        // If the session is destroyed - nothing do to.
+        if (mIsDestroyed) {
+            Log.w(LOG_TAG, "Not adding printers - session destroyed.");
+            return;
+        }
+
+        if (mIsDiscoveryStarted) {
+            // If during discovery, add the new printers and send them.
+            List<PrinterInfo> addedPrinters = null;
+            final int addedPrinterCount = printers.size();
+            for (int i = 0; i < addedPrinterCount; i++) {
+                PrinterInfo addedPrinter = printers.get(i);
+                PrinterInfo oldPrinter = mPrinters.put(addedPrinter.getId(), addedPrinter);
+                if (oldPrinter == null || !oldPrinter.equals(addedPrinter)) {
+                    if (addedPrinters == null) {
+                        addedPrinters = new ArrayList<PrinterInfo>();
+                    }
+                    addedPrinters.add(addedPrinter);
+                }
+            }
+
+            // Send the added printers, if such.
+            if (addedPrinters != null) {
+                sendAddedPrinters(mObserver, addedPrinters);
+            }
+        } else {
+            // Remember the last sent printers if needed.
+            if (mLastSentPrinters == null) {
+                mLastSentPrinters = new ArrayMap<PrinterId, PrinterInfo>(mPrinters);
+            }
+
+            // Update the printers.
+            final int addedPrinterCount = printers.size();
+            for (int i = 0; i < addedPrinterCount; i++) {
+                PrinterInfo addedPrinter = printers.get(i);
+                if (mPrinters.get(addedPrinter.getId()) == null) {
+                    mPrinters.put(addedPrinter.getId(), addedPrinter);
+                }
+            }
+        }
+    }
+
+    private static void sendAddedPrinters(IPrintServiceClient observer,
+        List<PrinterInfo> printers) {
+        try {
+            final int printerCount = printers.size();
+            if (printerCount <= MAX_ITEMS_PER_CALLBACK) {
+                observer.onPrintersAdded(printers);
+            } else {
+                // Send the added printers in chunks avoiding the binder transaction limit.
+                final int transactionCount = (printerCount / MAX_ITEMS_PER_CALLBACK) + 1;
+                for (int i = 0; i < transactionCount; i++) {
+                    final int start = i * MAX_ITEMS_PER_CALLBACK;
+                    final int end = Math.min(start + MAX_ITEMS_PER_CALLBACK, printerCount);
+                    List<PrinterInfo> subPrinters = printers.subList(start, end);
+                    observer.onPrintersAdded(subPrinters);
+                }
+            }
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error sending added printers", re);
+        }
+    }
+
+    /**
+     * Removes added printers. Removing an already removed or never added
+     * printer has no effect. Removed printers can be added again. You can
+     * call this method multiple times during the lifetime of this session.
+     * <p>
+     * <strong>Note: </strong> Calls to this method after the session is
+     * destroyed, that is after the {@link #onDestroy()} callback, will be ignored.
+     * </p>
+     *
+     * @param printerIds The ids of the removed printers.
+     *
+     * @see #addPrinters(List)
+     * @see #getPrinters()
+     * @see #isDestroyed()
+     */
+    public final void removePrinters(List<PrinterId> printerIds) {
+        PrintService.throwIfNotCalledOnMainThread();
+
+        // If the session is destroyed - nothing do to.
+        if (mIsDestroyed) {
+            Log.w(LOG_TAG, "Not removing printers - session destroyed.");
+            return;
+        }
+
+        if (mIsDiscoveryStarted) {
+            // If during discovery, remove existing printers and send them.
+            List<PrinterId> removedPrinterIds = new ArrayList<PrinterId>();
+            final int removedPrinterIdCount = printerIds.size();
+            for (int i = 0; i < removedPrinterIdCount; i++) {
+                PrinterId removedPrinterId = printerIds.get(i);
+                if (mPrinters.remove(removedPrinterId) != null) {
+                    removedPrinterIds.add(removedPrinterId);
+                }
+            }
+
+            // Send the removed printers, if such.
+            if (!removedPrinterIds.isEmpty()) {
+                sendRemovedPrinters(mObserver, removedPrinterIds);
+            }
+        } else {
+            // Remember the last sent printers if needed.
+            if (mLastSentPrinters == null) {
+                mLastSentPrinters = new ArrayMap<PrinterId, PrinterInfo>(mPrinters);
+            }
+
+            // Update the printers.
+            final int removedPrinterIdCount = printerIds.size();
+            for (int i = 0; i < removedPrinterIdCount; i++) {
+                PrinterId removedPrinterId = printerIds.get(i);
+                mPrinters.remove(removedPrinterId);
+            }
+        }
+    }
+
+    private static void sendRemovedPrinters(IPrintServiceClient observer,
+            List<PrinterId> printerIds) {
+        try {
+            final int printerIdCount = printerIds.size();
+            if (printerIdCount <= MAX_ITEMS_PER_CALLBACK) {
+                observer.onPrintersRemoved(printerIds);
+            } else {
+                final int transactionCount = (printerIdCount / MAX_ITEMS_PER_CALLBACK) + 1;
+                for (int i = 0; i < transactionCount; i++) {
+                    final int start = i * MAX_ITEMS_PER_CALLBACK;
+                    final int end = Math.min(start + MAX_ITEMS_PER_CALLBACK, printerIdCount);
+                    List<PrinterId> subPrinterIds = printerIds.subList(start, end);
+                    observer.onPrintersRemoved(subPrinterIds);
+                }
+            }
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error sending removed printers", re);
+        }
+    }
+
+    private void sendOutOfDiscoveryPeriodPrinterChanges() {
+        // Noting changed since the last discovery period - nothing to do.
+        if (mLastSentPrinters == null || mLastSentPrinters.isEmpty()) {
+            mLastSentPrinters = null;
+            return;
+        }
+
+        // Determine the added printers.
+        List<PrinterInfo> addedPrinters = null;
+        for (PrinterInfo printer : mPrinters.values()) {
+            PrinterInfo sentPrinter = mLastSentPrinters.get(printer.getId());
+            if (sentPrinter == null || !sentPrinter.equals(printer)) {
+                if (addedPrinters == null) {
+                    addedPrinters = new ArrayList<PrinterInfo>();
+                }
+                addedPrinters.add(printer);
+            }
+        }
+
+        // Send the added printers, if such.
+        if (addedPrinters != null) {
+            sendAddedPrinters(mObserver, addedPrinters);
+        }
+
+        // Determine the removed printers.
+        List<PrinterId> removedPrinterIds = null;
+        for (PrinterInfo sentPrinter : mLastSentPrinters.values()) {
+            if (!mPrinters.containsKey(sentPrinter.getId())) {
+                if (removedPrinterIds == null) {
+                    removedPrinterIds = new ArrayList<PrinterId>();
+                }
+                removedPrinterIds.add(sentPrinter.getId());
+            }
+        }
+
+        // Send the removed printers, if such.
+        if (removedPrinterIds != null) {
+            sendRemovedPrinters(mObserver, removedPrinterIds);
+        }
+
+        mLastSentPrinters = null;
+    }
+
+    /**
+     * Callback asking you to start printer discovery. Discovered printers should be
+     * added via calling {@link #addPrinters(List)}. Added printers that disappeared
+     * should be removed via calling {@link #removePrinters(List)}. Added printers
+     * whose properties or capabilities changed should be updated via calling {@link
+     * #addPrinters(List)}. You will receive a call to {@link #onStopPrinterDiscovery()}
+     * when you should stop printer discovery.
+     * <p>
+     * During the lifetime of this session all printers that are known to your print
+     * service have to be added. The system does not retain any printers across sessions.
+     * However, if you were asked to start and then stop performing printer discovery
+     * in this session, then a subsequent discovering should not re-discover already
+     * discovered printers. You can get the printers reported during this session by
+     * calling {@link #getPrinters()}.
+     * </p>
+     * <p>
+     * <strong>Note: </strong>You are also given a list of printers whose availability
+     * has to be checked first. For example, these printers could be the user's favorite
+     * ones, therefore they have to be verified first. You do <strong>not need</strong>
+     * to provide the capabilities of the printers, rather verify whether they exist
+     * similarly to {@link #onValidatePrinters(List)}.
+     * </p>
+     *
+     * @param priorityList The list of printers to validate first. Never null.
+     *
+     * @see #onStopPrinterDiscovery()
+     * @see #addPrinters(List)
+     * @see #removePrinters(List)
+     * @see #isPrinterDiscoveryStarted()
+     */
+    public abstract void onStartPrinterDiscovery(List<PrinterId> priorityList);
+
+    /**
+     * Callback notifying you that you should stop printer discovery.
+     *
+     * @see #onStartPrinterDiscovery(List)
+     * @see #isPrinterDiscoveryStarted()
+     */
+    public abstract void onStopPrinterDiscovery();
+
+    /**
+     * Callback asking you to validate that the given printers are valid, that
+     * is they exist. You are responsible for checking whether these printers
+     * exist and for the ones that do exist notify the system via calling
+     * {@link #addPrinters(List)}.
+     * <p>
+     * <strong>Note: </strong> You are <strong>not required</strong> to provide
+     * the printer capabilities when updating the printers that do exist.
+     * <p>
+     *
+     * @param printerIds The printers to validate.
+     *
+     * @see PrinterInfo.Builder#setCapabilities(PrinterCapabilitiesInfo)
+     *      PrinterInfo.Builder.setCapabilities(PrinterCapabilitiesInfo)
+     */
+    public abstract void onValidatePrinters(List<PrinterId> printerIds);
+
+    /**
+     * Callback asking you to start tracking the state of a printer. Tracking
+     * the state means that you should do a best effort to observe the state
+     * of this printer and notify the system if that state changes via calling
+     * {@link #addPrinters(List)}.
+     * <p>
+     * <strong>Note: </strong> A printer can be initially added without its
+     * capabilities to avoid polling printers that the user will not select.
+     * However, after this method is called you are expected to update the
+     * printer <strong>including</strong> its capabilities. Otherwise, the
+     * printer will be ignored.
+     * <p>
+     * <p>
+     * A scenario when you may be requested to track a printer's state is if
+     * the user selects that printer and the system has to present print
+     * options UI based on the printer's capabilities. In this case the user
+     * should be promptly informed if, for example, the printer becomes
+     * unavailable.
+     * </p>
+     *
+     * @param printerId The printer to start tracking.
+     *
+     * @see #onStopPrinterStateTracking(PrinterId)
+     * @see PrinterInfo.Builder#setCapabilities(PrinterCapabilitiesInfo)
+     *      PrinterInfo.Builder.setCapabilities(PrinterCapabilitiesInfo)
+     */
+    public abstract void onStartPrinterStateTracking(PrinterId printerId);
+
+    /**
+     * Callback asking you to stop tracking the state of a printer. The passed
+     * in printer id is the one for which you received a call to {@link
+     * #onStartPrinterStateTracking(PrinterId)}.
+     *
+     * @param printerId The printer to stop tracking.
+     *
+     * @see #onStartPrinterStateTracking(PrinterId)
+     */
+    public abstract void onStopPrinterStateTracking(PrinterId printerId);
+
+    /**
+     * Gets the printers that should be tracked. These are printers that are
+     * important to the user and for which you received a call to {@link
+     * #onStartPrinterStateTracking(PrinterId)} asking you to observer their
+     * state and reporting it to the system via {@link #addPrinters(List)}.
+     * You will receive a call to {@link #onStopPrinterStateTracking(PrinterId)}
+     * if you should stop tracking a printer.
+     * <p>
+     * <strong>Note: </strong> Calls to this method after the session is
+     * destroyed, that is after the {@link #onDestroy()} callback, will be ignored.
+     * </p>
+     *
+     * @return The printers.
+     *
+     * @see #onStartPrinterStateTracking(PrinterId)
+     * @see #onStopPrinterStateTracking(PrinterId)
+     * @see #isDestroyed()
+     */
+    public final List<PrinterId> getTrackedPrinters() {
+        PrintService.throwIfNotCalledOnMainThread();
+        if (mIsDestroyed) {
+            return Collections.emptyList();
+        }
+        return new ArrayList<PrinterId>(mTrackedPrinters);
+    }
+
+    /**
+     * Notifies you that the session is destroyed. After this callback is invoked
+     * any calls to the methods of this class will be ignored, {@link #isDestroyed()}
+     * will return true and you will also no longer receive callbacks.
+     *
+     * @see #isDestroyed()
+     */
+    public abstract void onDestroy();
+
+    /**
+     * Gets whether the session is destroyed.
+     *
+     * @return Whether the session is destroyed.
+     *
+     * @see #onDestroy()
+     */
+    public final boolean isDestroyed() {
+        PrintService.throwIfNotCalledOnMainThread();
+        return mIsDestroyed;
+    }
+
+    /**
+     * Gets whether printer discovery is started.
+     *
+     * @return Whether printer discovery is destroyed.
+     *
+     * @see #onStartPrinterDiscovery(List)
+     * @see #onStopPrinterDiscovery()
+     */
+    public final boolean isPrinterDiscoveryStarted() {
+        PrintService.throwIfNotCalledOnMainThread();
+        return mIsDiscoveryStarted;
+    }
+
+    void startPrinterDiscovery(List<PrinterId> priorityList) {
+        if (!mIsDestroyed) {
+            mIsDiscoveryStarted = true;
+            sendOutOfDiscoveryPeriodPrinterChanges();
+            if (priorityList == null) {
+                priorityList = Collections.emptyList();
+            }
+            onStartPrinterDiscovery(priorityList);
+        }
+    }
+
+    void stopPrinterDiscovery() {
+        if (!mIsDestroyed) {
+            mIsDiscoveryStarted = false;
+            onStopPrinterDiscovery();
+        }
+    }
+
+    void validatePrinters(List<PrinterId> printerIds) {
+        if (!mIsDestroyed && mObserver != null) {
+            onValidatePrinters(printerIds);
+        }
+    }
+
+    void startPrinterStateTracking(PrinterId printerId) {
+        if (!mIsDestroyed && mObserver != null
+                && !mTrackedPrinters.contains(printerId)) {
+            mTrackedPrinters.add(printerId);
+            onStartPrinterStateTracking(printerId);
+        }
+    }
+
+    void stopPrinterStateTracking(PrinterId printerId) {
+        if (!mIsDestroyed && mObserver != null
+                && mTrackedPrinters.remove(printerId)) {
+            onStopPrinterStateTracking(printerId);
+        }
+    }
+
+    void destroy() {
+        if (!mIsDestroyed) {
+            mIsDestroyed = true;
+            mIsDiscoveryStarted = false;
+            mPrinters.clear();
+            mLastSentPrinters = null;
+            mObserver = null;
+            onDestroy();
+        }
+    }
+}
diff --git a/core/java/android/printservice/package.html b/core/java/android/printservice/package.html
new file mode 100644
index 0000000..7410a49
--- /dev/null
+++ b/core/java/android/printservice/package.html
@@ -0,0 +1,23 @@
+<HTML>
+<BODY>
+<p>
+Provides classes for implementing print services. Print services are plug-in components
+that know how to talk to printers via some standard protocols. These services serve as a
+bridge between the system and the printers. Hence, the printer and print protocol specific
+implementation is factored out of the system and can by independently developed and updated.
+</p>
+<p>
+A print service implementation should extend {@link android.printservice.PrintService}
+and implement its abstract methods. Also the print service has to follow the contract for
+managing print {@link android.printservice.PrintJob}s.
+<p/>
+<p>
+The system is responsible for starting and stopping a print service depending on whether
+there are active print jobs for the printers managed by the service. The print service
+should also perform printer discovery in a timely fashion to ensure good user experience.
+The interaction between the system and the print service during printer discovery is
+encapsulated by a {@link android.printservice.PrinterDiscoverySession} instance created
+by the print service when requested by the system.
+</p>
+</BODY>
+</HTML>
diff --git a/core/java/android/provider/AlarmClock.java b/core/java/android/provider/AlarmClock.java
index 3401cb1..724d76d 100644
--- a/core/java/android/provider/AlarmClock.java
+++ b/core/java/android/provider/AlarmClock.java
@@ -21,12 +21,12 @@
 
 /**
  * The AlarmClock provider contains an Intent action and extras that can be used
- * to start an Activity to set a new alarm in an alarm clock application.
+ * to start an Activity to set a new alarm or timer in an alarm clock application.
  *
- * Applications that wish to receive the ACTION_SET_ALARM Intent should create
- * an activity to handle the Intent that requires the permission
+ * Applications that wish to receive the ACTION_SET_ALARM  and ACTION_SET_TIMER Intents
+ * should create an activity to handle the Intent that requires the permission
  * com.android.alarm.permission.SET_ALARM.  Applications that wish to create a
- * new alarm should use
+ * new alarm or timer should use
  * {@link android.content.Context#startActivity Context.startActivity()} so that
  * the user has the option of choosing which alarm clock application to use.
  */
@@ -34,49 +34,203 @@
     /**
      * Activity Action: Set an alarm.
      * <p>
-     * Input: Nothing.
-     * <p>
-     * Output: Nothing.
+     * Activates an existing alarm or creates a new one.
+     * </p><p>
+     * This action requests an alarm to be set for a given time of day. If no time of day is
+     * specified, an implementation should start an activity that is capable of setting an alarm
+     * ({@link #EXTRA_SKIP_UI} is ignored in this case). If a time of day is specified, and
+     * {@link #EXTRA_SKIP_UI} is {@code true}, and the alarm is not repeating, the implementation
+     * should remove this alarm after it has been dismissed. If an identical alarm exists matching
+     * all parameters, the implementation may re-use it instead of creating a new one (in this case,
+     * the alarm should not be removed after dismissal).
+     *
+     * This action always enables the alarm.
+     * </p>
+     * <h3>Request parameters</h3>
+     * <ul>
+     * <li>{@link #EXTRA_HOUR} <em>(optional)</em>: The hour of the alarm being set.
+     * <li>{@link #EXTRA_MINUTES} <em>(optional)</em>: The minutes of the alarm being set.
+     * <li>{@link #EXTRA_DAYS} <em>(optional)</em>: Weekdays for repeating alarm.
+     * <li>{@link #EXTRA_MESSAGE} <em>(optional)</em>: A custom message for the alarm.
+     * <li>{@link #EXTRA_RINGTONE} <em>(optional)</em>: A ringtone to play with this alarm.
+     * <li>{@link #EXTRA_VIBRATE} <em>(optional)</em>: Whether or not to activate the device
+     * vibrator for this alarm.
+     * <li>{@link #EXTRA_SKIP_UI} <em>(optional)</em>: Whether or not to display an activity for
+     * setting this alarm.
+     * </ul>
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_SET_ALARM = "android.intent.action.SET_ALARM";
 
     /**
-     * Activity Extra: Provide a custom message for the alarm.
+     * Activity Action: Set a timer.
      * <p>
-     * This can be passed as an extra field in the Intent created with
-     * ACTION_SET_ALARM.
+     * Activates an existing timer or creates a new one.
+     * </p><p>
+     * This action requests a timer to be started for a specific {@link #EXTRA_LENGTH length} of
+     * time. If no {@link #EXTRA_LENGTH length} is specified, the implementation should start an
+     * activity that is capable of setting a timer ({@link #EXTRA_SKIP_UI} is ignored in this case).
+     * If a {@link #EXTRA_LENGTH length} is specified, and {@link #EXTRA_SKIP_UI} is {@code true},
+     * the implementation should remove this timer after it has been dismissed. If an identical,
+     * unused timer exists matching both parameters, an implementation may re-use it instead of
+     * creating a new one (in this case, the timer should not be removed after dismissal).
+     *
+     * This action always starts the timer.
+     * </p>
+     *
+     * <h3>Request parameters</h3>
+     * <ul>
+     * <li>{@link #EXTRA_LENGTH} <em>(optional)</em>: The length of the timer being set.
+     * <li>{@link #EXTRA_MESSAGE} <em>(optional)</em>: A custom message for the timer.
+     * <li>{@link #EXTRA_SKIP_UI} <em>(optional)</em>: Whether or not to display an activity for
+     * setting this timer.
+     * </ul>
      */
-    public static final String EXTRA_MESSAGE = "android.intent.extra.alarm.MESSAGE";
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_SET_TIMER = "android.intent.action.SET_TIMER";
 
     /**
-     * Activity Extra: The hour of the alarm being set.
+     * Activity Action: Show the alarms.
      * <p>
-     * This value can be passed as an extra field to the Intent created with
-     * ACTION_SET_ALARM.  If it is not provided, the behavior is undefined and
-     * is up to the application.  The value is an integer and ranges from 0 to
-     * 23.
+     * This action opens the alarms page.
+     * </p>
+     */
+     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+     public static final String ACTION_SHOW_ALARMS = "android.intent.action.SHOW_ALARMS";
+
+    /**
+     * Bundle extra: Weekdays for repeating alarm.
+     * <p>
+     * Used by {@link #ACTION_SET_ALARM}.
+     * </p><p>
+     * The value is an {@code ArrayList<Integer>}. Each item can be:
+     * </p>
+     * <ul>
+     * <li> {@link java.util.Calendar#SUNDAY},
+     * <li> {@link java.util.Calendar#MONDAY},
+     * <li> {@link java.util.Calendar#TUESDAY},
+     * <li> {@link java.util.Calendar#WEDNESDAY},
+     * <li> {@link java.util.Calendar#THURSDAY},
+     * <li> {@link java.util.Calendar#FRIDAY},
+     * <li> {@link java.util.Calendar#SATURDAY}
+     * </ul>
+     */
+    public static final String EXTRA_DAYS = "android.intent.extra.alarm.DAYS";
+
+    /**
+     * Bundle extra: The hour of the alarm.
+     * <p>
+     * Used by {@link #ACTION_SET_ALARM}.
+     * </p><p>
+     * This extra is optional. If not provided, an implementation should open an activity
+     * that allows a user to set an alarm with user provided time.
+     * </p><p>
+     * The value is an {@link Integer} and ranges from 0 to 23.
+     * </p>
+     *
+     * @see #ACTION_SET_ALARM
+     * @see #EXTRA_MINUTES
+     * @see #EXTRA_DAYS
      */
     public static final String EXTRA_HOUR = "android.intent.extra.alarm.HOUR";
 
     /**
-     * Activity Extra: The minutes of the alarm being set.
+     * Bundle extra: The length of the timer in seconds.
      * <p>
-     * This value can be passed as an extra field to the Intent created with
-     * ACTION_SET_ALARM.  If it is not provided, the behavior is undefined and
-     * is up to the application.  The value is an integer and ranges from 0 to
-     * 59.
+     * Used by {@link #ACTION_SET_TIMER}.
+     * </p><p>
+     * This extra is optional. If not provided, an implementation should open an activity
+     * that allows a user to set a timer with user provided length.
+     * </p><p>
+     * The value is an {@link Integer} and ranges from 1 to 86400 (24 hours).
+     * </p>
+     *
+     * @see #ACTION_SET_TIMER
+     */
+    public static final String EXTRA_LENGTH = "android.intent.extra.alarm.LENGTH";
+
+    /**
+     * Bundle extra: A custom message for the alarm or timer.
+     * <p>
+     * Used by {@link #ACTION_SET_ALARM} and {@link #ACTION_SET_TIMER}.
+     * </p><p>
+     * The value is a {@link String}.
+     * </p>
+     *
+     * @see #ACTION_SET_ALARM
+     * @see #ACTION_SET_TIMER
+     */
+    public static final String EXTRA_MESSAGE = "android.intent.extra.alarm.MESSAGE";
+
+    /**
+     * Bundle extra: The minutes of the alarm.
+     * <p>
+     * Used by {@link #ACTION_SET_ALARM}.
+     * </p><p>
+     * The value is an {@link Integer} and ranges from 0 to 59. If not provided, it defaults to 0.
+     * </p>
+     *
+     * @see #ACTION_SET_ALARM
+     * @see #EXTRA_HOUR
+     * @see #EXTRA_DAYS
      */
     public static final String EXTRA_MINUTES = "android.intent.extra.alarm.MINUTES";
 
     /**
-     * Activity Extra: Optionally skip the application UI.
+     * Bundle extra: A ringtone to be played with this alarm.
      * <p>
-     * This value can be passed as an extra field to the Intent created with
-     * ACTION_SET_ALARM.  If true, the application is asked to bypass any
-     * intermediate UI and instead pop a toast indicating the result then
-     * finish the Activity.  If false, the application may display intermediate
-     * UI like a confirmation dialog or alarm settings.  The default is false.
+     * Used by {@link #ACTION_SET_ALARM}.
+     * </p><p>
+     * This value is a {@link String} and can either be set to {@link #VALUE_RINGTONE_SILENT} or
+     * to a content URI of the media to be played. If not specified or the URI doesn't exist,
+     * {@code "content://settings/system/alarm_alert} will be used.
+     * </p>
+     *
+     * @see #ACTION_SET_ALARM
+     * @see #VALUE_RINGTONE_SILENT
+     * @see #EXTRA_VIBRATE
+     */
+    public static final String EXTRA_RINGTONE = "android.intent.extra.alarm.RINGTONE";
+
+    /**
+     * Bundle extra: Whether or not to display an activity after performing the action.
+     * <p>
+     * Used by {@link #ACTION_SET_ALARM} and {@link #ACTION_SET_TIMER}.
+     * </p><p>
+     * If true, the application is asked to bypass any intermediate UI. If false, the application
+     * may display intermediate UI like a confirmation dialog or settings.
+     * </p><p>
+     * The value is a {@link Boolean}. The default is {@code false}.
+     * </p>
+     *
+     * @see #ACTION_SET_ALARM
+     * @see #ACTION_SET_TIMER
      */
     public static final String EXTRA_SKIP_UI = "android.intent.extra.alarm.SKIP_UI";
+
+    /**
+     * Bundle extra: Whether or not to activate the device vibrator.
+     * <p>
+     * Used by {@link #ACTION_SET_ALARM}.
+     * </p><p>
+     * The value is a {@link Boolean}. The default is {@code true}.
+     * </p>
+     *
+     * @see #ACTION_SET_ALARM
+     * @see #EXTRA_RINGTONE
+     * @see #VALUE_RINGTONE_SILENT
+     */
+    public static final String EXTRA_VIBRATE = "android.intent.extra.alarm.VIBRATE";
+
+    /**
+     * Bundle extra value: Indicates no ringtone should be played.
+     * <p>
+     * Used by {@link #ACTION_SET_ALARM}, passed in through {@link #EXTRA_RINGTONE}.
+     * </p>
+     *
+     * @see #ACTION_SET_ALARM
+     * @see #EXTRA_RINGTONE
+     * @see #EXTRA_VIBRATE
+     */
+    public static final String VALUE_RINGTONE_SILENT = "silent";
 }
diff --git a/core/java/android/provider/Applications.java b/core/java/android/provider/Applications.java
deleted file mode 100644
index 7aabc50..0000000
--- a/core/java/android/provider/Applications.java
+++ /dev/null
@@ -1,127 +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.provider;
-
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.database.Cursor;
-import android.net.Uri;
-
-import java.util.List;
-
-/**
- * The Applications provider gives information about installed applications.
- *
- * @hide Only used by ApplicationsProvider so far.
- */
-public class Applications {
-
-    /**
-     * The content authority for this provider.
-     */
-    public static final String AUTHORITY = "applications";
-
-    /**
-     * The content:// style URL for this provider
-     */
-    public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
-
-    /**
-     * The content path for application component URIs.
-     */
-    public static final String APPLICATION_PATH = "applications";
-
-    /**
-     * The content path for application search.
-     */
-    public static final String SEARCH_PATH = "search";
-
-    private static final String APPLICATION_SUB_TYPE = "vnd.android.application";
-
-    /**
-     * The MIME type for a single application item.
-     */
-    public static final String APPLICATION_ITEM_TYPE =
-            ContentResolver.CURSOR_ITEM_BASE_TYPE + "/" + APPLICATION_SUB_TYPE;
-
-    /**
-     * The MIME type for a list of application items.
-     */
-    public static final String APPLICATION_DIR_TYPE =
-            ContentResolver.CURSOR_DIR_BASE_TYPE + "/" + APPLICATION_SUB_TYPE;
-
-    /**
-     * no public constructor since this is a utility class
-     */
-    private Applications() {}
-
-    /**
-     * Gets a cursor with application search results.
-     * See {@link ApplicationColumns} for the columns available in the returned cursor.
-     */
-    public static Cursor search(ContentResolver resolver, String query) {
-        Uri searchUri = CONTENT_URI.buildUpon().appendPath(SEARCH_PATH).appendPath(query).build();
-        return resolver.query(searchUri, null, null, null, null);
-    }
-
-    /**
-     * Gets the application component name from an application URI.
-     *
-     * @param appUri A URI of the form
-     * "content://applications/applications/&lt;packageName&gt;/&lt;className&gt;".
-     * @return The component name for the application, or
-     * <code>null</code> if the given URI was <code>null</code>
-     * or malformed.
-     */
-    public static ComponentName uriToComponentName(Uri appUri) {
-        if (appUri == null) return null;
-        if (!ContentResolver.SCHEME_CONTENT.equals(appUri.getScheme())) return null;
-        if (!AUTHORITY.equals(appUri.getAuthority())) return null;
-        List<String> pathSegments = appUri.getPathSegments();
-        if (pathSegments.size() != 3) return null;
-        if (!APPLICATION_PATH.equals(pathSegments.get(0))) return null;
-        String packageName = pathSegments.get(1);
-        String name = pathSegments.get(2);
-        return new ComponentName(packageName, name);
-    }
-
-    /**
-     * Gets the URI for an application component.
-     *
-     * @param packageName The name of the application's package.
-     * @param className The class name of the application.
-     * @return A URI of the form
-     * "content://applications/applications/&lt;packageName&gt;/&lt;className&gt;".
-     */
-    public static Uri componentNameToUri(String packageName, String className) {
-        return Applications.CONTENT_URI.buildUpon()
-                .appendEncodedPath(APPLICATION_PATH)
-                .appendPath(packageName)
-                .appendPath(className)
-                .build();
-    }
-
-    /**
-     * The columns in application cursors, like those returned by
-     * {@link Applications#search(ContentResolver, String)}.
-     */
-    public interface ApplicationColumns extends BaseColumns {
-        public static final String NAME = "name";
-        public static final String ICON = "icon";
-        public static final String URI = "uri";
-    }
-}
diff --git a/core/java/android/provider/CalendarContract.java b/core/java/android/provider/CalendarContract.java
index 25af209..d743484 100644
--- a/core/java/android/provider/CalendarContract.java
+++ b/core/java/android/provider/CalendarContract.java
@@ -2393,7 +2393,7 @@
             intent.setData(ContentUris.withAppendedId(CalendarContract.CONTENT_URI, alarmTime));
             intent.putExtra(ALARM_TIME, alarmTime);
             PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
-            manager.set(AlarmManager.RTC_WAKEUP, alarmTime, pi);
+            manager.setExact(AlarmManager.RTC_WAKEUP, alarmTime, pi);
         }
 
         /**
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 5dca67f..a6f23a8 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -137,6 +137,32 @@
         public static final String NUMBER = "number";
 
         /**
+         * The number presenting rules set by the network.
+         *
+         * <p>
+         * Allowed values:
+         * <ul>
+         * <li>{@link #PRESENTATION_ALLOWED}</li>
+         * <li>{@link #PRESENTATION_RESTRICTED}</li>
+         * <li>{@link #PRESENTATION_UNKNOWN}</li>
+         * <li>{@link #PRESENTATION_PAYPHONE}</li>
+         * </ul>
+         * </p>
+         *
+         * <P>Type: INTEGER</P>
+         */
+        public static final String NUMBER_PRESENTATION = "presentation";
+
+        /** Number is allowed to display for caller id. */
+        public static final int PRESENTATION_ALLOWED = 1;
+        /** Number is blocked by user. */
+        public static final int PRESENTATION_RESTRICTED = 2;
+        /** Number is not specified or unknown by network. */
+        public static final int PRESENTATION_UNKNOWN = 3;
+        /** Number is a pay phone. */
+        public static final int PRESENTATION_PAYPHONE = 4;
+
+        /**
          * The ISO 3166-1 two letters country code of the country where the
          * user received or made the call.
          * <P>
@@ -267,7 +293,8 @@
          * if the contact is unknown.
          * @param context the context used to get the ContentResolver
          * @param number the phone number to be added to the calls db
-         * @param presentation the number presenting rules set by the network for
+         * @param presentation enum value from PhoneConstants.PRESENTATION_xxx, which
+         *        is set by the network and denotes the number presenting rules for
          *        "allowed", "payphone", "restricted" or "unknown"
          * @param callType enumerated values for "incoming", "outgoing", or "missed"
          * @param start time stamp for the call in milliseconds
@@ -278,24 +305,32 @@
         public static Uri addCall(CallerInfo ci, Context context, String number,
                 int presentation, int callType, long start, int duration) {
             final ContentResolver resolver = context.getContentResolver();
+            int numberPresentation = PRESENTATION_ALLOWED;
 
-            // If this is a private number then set the number to Private, otherwise check
-            // if the number field is empty and set the number to Unavailable
+            // Remap network specified number presentation types
+            // PhoneConstants.PRESENTATION_xxx to calllog number presentation types
+            // Calls.PRESENTATION_xxx, in order to insulate the persistent calllog
+            // from any future radio changes.
+            // If the number field is empty set the presentation type to Unknown.
             if (presentation == PhoneConstants.PRESENTATION_RESTRICTED) {
-                number = CallerInfo.PRIVATE_NUMBER;
-                if (ci != null) ci.name = "";
+                numberPresentation = PRESENTATION_RESTRICTED;
             } else if (presentation == PhoneConstants.PRESENTATION_PAYPHONE) {
-                number = CallerInfo.PAYPHONE_NUMBER;
-                if (ci != null) ci.name = "";
+                numberPresentation = PRESENTATION_PAYPHONE;
             } else if (TextUtils.isEmpty(number)
                     || presentation == PhoneConstants.PRESENTATION_UNKNOWN) {
-                number = CallerInfo.UNKNOWN_NUMBER;
-                if (ci != null) ci.name = "";
+                numberPresentation = PRESENTATION_UNKNOWN;
+            }
+            if (numberPresentation != PRESENTATION_ALLOWED) {
+                number = "";
+                if (ci != null) {
+                    ci.name = "";
+                }
             }
 
-            ContentValues values = new ContentValues(5);
+            ContentValues values = new ContentValues(6);
 
             values.put(NUMBER, number);
+            values.put(NUMBER_PRESENTATION, Integer.valueOf(numberPresentation));
             values.put(TYPE, Integer.valueOf(callType));
             values.put(DATE, Long.valueOf(start));
             values.put(DURATION, Long.valueOf(duration));
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 220b997..b16df28 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -825,6 +825,14 @@
         public static final String STARRED = "starred";
 
         /**
+         * The position at which the contact is pinned. If {@link PinnedPositions.UNPINNED},
+         * the contact is not pinned. Also see {@link PinnedPositions}.
+         * <P>Type: INTEGER </P>
+         * @hide
+         */
+        public static final String PINNED = "pinned";
+
+        /**
          * URI for a custom ringtone associated with the contact. If null or missing,
          * the default ringtone is used.
          * <P>Type: TEXT (URI to the ringtone)</P>
@@ -5105,9 +5113,8 @@
          * Value of 1 implies true, 0 implies false when 0 is the default.
          * When a cursor is returned to the client, it should check for an extra with the name
          * {@link ContactsContract#DEFERRED_SNIPPETING} in the cursor. If it exists, the client
-         * should do its own snippeting using {@link ContactsContract#snippetize}. If
-         * it doesn't exist, the snippet column in the cursor should already contain a snippetized
-         * string.
+         * should do its own snippeting. If it doesn't exist, the snippet column in the cursor
+         * should already contain a snippetized string.
          *
          * @hide
          */
@@ -7715,6 +7722,138 @@
     }
 
     /**
+     * <p>
+     * API allowing applications to send pinning information for specified contacts to the
+     * Contacts Provider.
+     * </p>
+     *
+     * <p>
+     * This pinning information can be used by individual applications to customize how
+     * they order particular pinned contacts. For example, a Dialer application could
+     * use pinned information to order user-pinned contacts in a top row of favorites.
+     * </p>
+     *
+     * <p>
+     * It is possible for two or more contacts to occupy the same pinned position (due
+     * to aggregation and sync), so this pinning information should be used on a best-effort
+     * basis to order contacts in-application rather than an absolute guide on where a contact
+     * should be positioned. Contacts returned by the ContactsProvider will not be ordered based
+     * on this information, so it is up to the client application to reorder these contacts within
+     * their own UI adhering to (or ignoring as appropriate) information stored in the pinned
+     * column.
+     * </p>
+     *
+     * <p>
+     * By default, unpinned contacts will have a pinned position of
+     * {@link PinnedPositions#UNPINNED}, or {@link Integer#MAX_VALUE} (2^31 - 1). Client-provided
+     * pinned positions can be positive integers that range anywhere from 0 to
+     * {@link PinnedPositions#UNPINNED}.
+     * </p>
+     *
+     * <p>
+     * When using {@link PinnedPositions#UPDATE_URI} to update the pinned positions of
+     * certain contacts, it may make sense for your application to star any pinned contacts
+     * by default. To specify this behavior, set the boolean query parameter
+     * {@link PinnedPositions#STAR_WHEN_PINNING} to true to force all pinned and unpinned
+     * contacts to be automatically starred and unstarred.
+     * </p>
+     * @hide
+     */
+    public static final class PinnedPositions {
+
+        /**
+         * <p>
+         * This URI allows applications to update pinned positions for a provided set of contacts.
+         * </p>
+         *
+         * <p>
+         * The list of contactIds to pin and their corresponding pinned positions should be
+         * provided in key-value pairs stored in a {@link ContentValues} object where the key
+         * is a valid contactId, while each pinned position is a positive integer.
+         * </p>
+         *
+         * <p>
+         * Example:
+         * <pre>
+         * ContentValues values = new ContentValues();
+         * values.put("10", 20);
+         * values.put("12", 2);
+         * values.put("15", PinnedPositions.UNPINNED);
+         * int count = resolver.update(PinnedPositions.UPDATE_URI, values, null, null);
+         * </pre>
+         *
+         * This pins the contact with id 10 at position 20, the contact with id 12 at position 2,
+         * and unpins the contact with id 15.
+         * </p>
+         */
+        public static final Uri UPDATE_URI = Uri.withAppendedPath(AUTHORITY_URI,
+                "pinned_position_update");
+
+        /**
+         * Default value for the pinned position of an unpinned contact. Also equal to
+         * {@link Integer#MAX_VALUE}.
+         */
+        public static final int UNPINNED = 0x7FFFFFFF;
+
+        /**
+         * Value of pinned position for a contact that a user has indicated should be considered
+         * of the lowest priority. It is up to the client application to determine how to present
+         * such a contact - for example all the way at the bottom of a contact list, or simply
+         * just hidden from view.
+         */
+        public static final int DEMOTED = -1;
+
+        /**
+         * <p> Clients can provide this value as a pinned position to undemote a formerly demoted
+         * contact. If the contact was formerly demoted, it will be restored to an
+         * {@link #UNPINNED} position. If it was otherwise already pinned at another position,
+         * it will not be affected.
+         * </p>
+         *
+         * <p>
+         * Example:
+         * <pre>
+         * ContentValues values = new ContentValues();
+         * values.put("15", PinnedPositions.UNDEMOTE);
+         * int count = resolver.update(ContactsContract.PinnedPositions.UPDATE_URI.buildUpon()
+         *          .build(), values, null, null);
+         * </pre>
+         *
+         * This restores the contact with id 15 to an {@link #UNPINNED} position, meaning that
+         * other apps (e.g. the Dialer) that were formerly hiding this contact from view based on
+         * its {@link #DEMOTED} position will start displaying it again.
+         * </p>
+         */
+        public static final String UNDEMOTE = "undemote";
+
+        /**
+         * <p>
+         * A boolean query parameter that can be used with {@link #UPDATE_URI}.
+         * If "1" or "true", any contact that is pinned or unpinned will be correspondingly
+         * starred or unstarred. Otherwise, starring information will not be affected by pinned
+         * updates. This is false by default.
+         * </p>
+         *
+         * <p>
+         * Example:
+         * <pre>
+         * ContentValues values = new ContentValues();
+         * values.put("10", 20);
+         * values.put("15", PinnedPositions.UNPINNED);
+         * int count = resolver.update(ContactsContract.PinnedPositions.UPDATE_URI.buildUpon()
+         *          .appendQueryParameter(PinnedPositions.FORCE_STAR_WHEN_PINNING, "true").build(),
+         *          values, null, null);
+         * </pre>
+         *
+         * This will pin the contact with id 10 at position 20 and star it automatically if not
+         * already starred, and unpin the contact with id 15, and unstar it automatically if not
+         * already unstarred.
+         * </p>
+         */
+        public static final String STAR_WHEN_PINNING = "star_when_pinning";
+    }
+
+    /**
      * Helper methods to display QuickContact dialogs that allow users to pivot on
      * a specific {@link Contacts} entry.
      */
@@ -8463,138 +8602,4 @@
             public static final String DATA_SET = "com.android.contacts.extra.DATA_SET";
         }
     }
-
-    /**
-     * Creates a snippet out of the given content that matches the given query.
-     * @param content - The content to use to compute the snippet.
-     * @param displayName - Display name for the contact - if this already contains the search
-     *        content, no snippet should be shown.
-     * @param query - String to search for in the content.
-     * @param snippetStartMatch - Marks the start of the matching string in the snippet.
-     * @param snippetEndMatch - Marks the end of the matching string in the snippet.
-     * @param snippetEllipsis - Ellipsis string appended to the end of the snippet (if too long).
-     * @param snippetMaxTokens - Maximum number of words from the snippet that will be displayed.
-     * @return The computed snippet, or null if the snippet could not be computed or should not be
-     *         shown.
-     *
-     *  @hide
-     */
-    public static String snippetize(String content, String displayName, String query,
-            char snippetStartMatch, char snippetEndMatch, String snippetEllipsis,
-            int snippetMaxTokens) {
-
-        String lowerQuery = query != null ? query.toLowerCase() : null;
-        if (TextUtils.isEmpty(content) || TextUtils.isEmpty(query) ||
-                TextUtils.isEmpty(displayName) || !content.toLowerCase().contains(lowerQuery)) {
-            return null;
-        }
-
-        // If the display name already contains the query term, return empty - snippets should
-        // not be needed in that case.
-        String lowerDisplayName = displayName != null ? displayName.toLowerCase() : "";
-        List<String> nameTokens = new ArrayList<String>();
-        List<Integer> nameTokenOffsets = new ArrayList<Integer>();
-        split(lowerDisplayName.trim(), nameTokens, nameTokenOffsets);
-        for (String nameToken : nameTokens) {
-            if (nameToken.startsWith(lowerQuery)) {
-                return null;
-            }
-        }
-
-        String[] contentLines = content.split("\n");
-
-        // Locate the lines of the content that contain the query term.
-        for (String contentLine : contentLines) {
-            if (contentLine.toLowerCase().contains(lowerQuery)) {
-
-                // Line contains the query string - now search for it at the start of tokens.
-                List<String> lineTokens = new ArrayList<String>();
-                List<Integer> tokenOffsets = new ArrayList<Integer>();
-                split(contentLine, lineTokens, tokenOffsets);
-
-                // As we find matches against the query, we'll populate this list with the marked
-                // (or unchanged) tokens.
-                List<String> markedTokens = new ArrayList<String>();
-
-                int firstToken = -1;
-                int lastToken = -1;
-                for (int i = 0; i < lineTokens.size(); i++) {
-                    String token = lineTokens.get(i);
-                    String lowerToken = token.toLowerCase();
-                    if (lowerToken.startsWith(lowerQuery)) {
-
-                        // Query term matched; surround the token with match markers.
-                        markedTokens.add(snippetStartMatch + token + snippetEndMatch);
-
-                        // If this is the first token found with a match, mark the token
-                        // positions to use for assembling the snippet.
-                        if (firstToken == -1) {
-                            firstToken =
-                                    Math.max(0, i - (int) Math.floor(
-                                            Math.abs(snippetMaxTokens)
-                                            / 2.0));
-                            lastToken =
-                                    Math.min(lineTokens.size(), firstToken +
-                                            Math.abs(snippetMaxTokens));
-                        }
-                    } else {
-                        markedTokens.add(token);
-                    }
-                }
-
-                // Assemble the snippet by piecing the tokens back together.
-                if (firstToken > -1) {
-                    StringBuilder sb = new StringBuilder();
-                    if (firstToken > 0) {
-                        sb.append(snippetEllipsis);
-                    }
-                    for (int i = firstToken; i < lastToken; i++) {
-                        String markedToken = markedTokens.get(i);
-                        String originalToken = lineTokens.get(i);
-                        sb.append(markedToken);
-                        if (i < lastToken - 1) {
-                            // Add the characters that appeared between this token and the next.
-                            sb.append(contentLine.substring(
-                                    tokenOffsets.get(i) + originalToken.length(),
-                                    tokenOffsets.get(i + 1)));
-                        }
-                    }
-                    if (lastToken < lineTokens.size()) {
-                        sb.append(snippetEllipsis);
-                    }
-                    return sb.toString();
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Pattern for splitting a line into tokens.  This matches e-mail addresses as a single token,
-     * otherwise splitting on any group of non-alphanumeric characters.
-     *
-     * @hide
-     */
-    private static Pattern SPLIT_PATTERN =
-        Pattern.compile("([\\w-\\.]+)@((?:[\\w]+\\.)+)([a-zA-Z]{2,4})|[\\w]+");
-
-    /**
-     * Helper method for splitting a string into tokens.  The lists passed in are populated with the
-     * tokens and offsets into the content of each token.  The tokenization function parses e-mail
-     * addresses as a single token; otherwise it splits on any non-alphanumeric character.
-     * @param content Content to split.
-     * @param tokens List of token strings to populate.
-     * @param offsets List of offsets into the content for each token returned.
-     *
-     * @hide
-     */
-    private static void split(String content, List<String> tokens, List<Integer> offsets) {
-        Matcher matcher = SPLIT_PATTERN.matcher(content);
-        while (matcher.find()) {
-            tokens.add(matcher.group());
-            offsets.add(matcher.start());
-        }
-    }
-
-
 }
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
new file mode 100644
index 0000000..3f33e80
--- /dev/null
+++ b/core/java/android/provider/DocumentsContract.java
@@ -0,0 +1,811 @@
+/*
+ * 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.provider;
+
+import static android.net.TrafficStats.KB_IN_BYTES;
+import static libcore.io.OsConstants.SEEK_SET;
+
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ProviderInfo;
+import android.content.res.AssetFileDescriptor;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Point;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.CancellationSignal;
+import android.os.ParcelFileDescriptor;
+import android.os.ParcelFileDescriptor.OnCloseListener;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.google.android.collect.Lists;
+
+import libcore.io.ErrnoException;
+import libcore.io.IoUtils;
+import libcore.io.Libcore;
+
+import java.io.BufferedInputStream;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Defines the contract between a documents provider and the platform.
+ * <p>
+ * To create a document provider, extend {@link DocumentsProvider}, which
+ * provides a foundational implementation of this contract.
+ *
+ * @see DocumentsProvider
+ */
+public final class DocumentsContract {
+    private static final String TAG = "Documents";
+
+    // content://com.example/root/
+    // content://com.example/root/sdcard/
+    // content://com.example/root/sdcard/recent/
+    // content://com.example/root/sdcard/search/?query=pony
+    // content://com.example/document/12/
+    // content://com.example/document/12/children/
+
+    private DocumentsContract() {
+    }
+
+    /** {@hide} */
+    public static final String META_DATA_DOCUMENT_PROVIDER = "android.content.DOCUMENT_PROVIDER";
+
+    /** {@hide} */
+    public static final String ACTION_MANAGE_ROOT = "android.provider.action.MANAGE_ROOT";
+    /** {@hide} */
+    public static final String ACTION_MANAGE_DOCUMENT = "android.provider.action.MANAGE_DOCUMENT";
+
+    /**
+     * Buffer is large enough to rewind past any EXIF headers.
+     */
+    private static final int THUMBNAIL_BUFFER_SIZE = (int) (128 * KB_IN_BYTES);
+
+    /**
+     * Constants related to a document, including {@link Cursor} columns names
+     * and flags.
+     * <p>
+     * A document can be either an openable file (with a specific MIME type), or
+     * a directory containing additional documents (with the
+     * {@link #MIME_TYPE_DIR} MIME type).
+     * <p>
+     * All columns are <em>read-only</em> to client applications.
+     */
+    public final static class Document {
+        private Document() {
+        }
+
+        /**
+         * Unique ID of a document. This ID is both provided by and interpreted
+         * by a {@link DocumentsProvider}, and should be treated as an opaque
+         * value by client applications.
+         * <p>
+         * Each document must have a unique ID within a provider, but that
+         * single document may be included as a child of multiple directories.
+         * <p>
+         * A provider must always return durable IDs, since they will be used to
+         * issue long-term Uri permission grants when an application interacts
+         * with {@link Intent#ACTION_OPEN_DOCUMENT} and
+         * {@link Intent#ACTION_CREATE_DOCUMENT}.
+         * <p>
+         * Type: STRING
+         */
+        public static final String COLUMN_DOCUMENT_ID = "document_id";
+
+        /**
+         * Concrete MIME type of a document. For example, "image/png" or
+         * "application/pdf" for openable files. A document can also be a
+         * directory containing additional documents, which is represented with
+         * the {@link #MIME_TYPE_DIR} MIME type.
+         * <p>
+         * Type: STRING
+         *
+         * @see #MIME_TYPE_DIR
+         */
+        public static final String COLUMN_MIME_TYPE = "mime_type";
+
+        /**
+         * Display name of a document, used as the primary title displayed to a
+         * user.
+         * <p>
+         * Type: STRING
+         */
+        public static final String COLUMN_DISPLAY_NAME = OpenableColumns.DISPLAY_NAME;
+
+        /**
+         * Summary of a document, which may be shown to a user. The summary may
+         * be {@code null}.
+         * <p>
+         * Type: STRING
+         */
+        public static final String COLUMN_SUMMARY = "summary";
+
+        /**
+         * Timestamp when a document was last modified, in milliseconds since
+         * January 1, 1970 00:00:00.0 UTC, or {@code null} if unknown. A
+         * {@link DocumentsProvider} can update this field using events from
+         * {@link OnCloseListener} or other reliable
+         * {@link ParcelFileDescriptor} transports.
+         * <p>
+         * Type: INTEGER (long)
+         *
+         * @see System#currentTimeMillis()
+         */
+        public static final String COLUMN_LAST_MODIFIED = "last_modified";
+
+        /**
+         * Specific icon resource ID for a document, or {@code null} to use
+         * platform default icon based on {@link #COLUMN_MIME_TYPE}.
+         * <p>
+         * Type: INTEGER (int)
+         */
+        public static final String COLUMN_ICON = "icon";
+
+        /**
+         * Flags that apply to a document.
+         * <p>
+         * Type: INTEGER (int)
+         *
+         * @see #FLAG_SUPPORTS_WRITE
+         * @see #FLAG_SUPPORTS_DELETE
+         * @see #FLAG_SUPPORTS_THUMBNAIL
+         * @see #FLAG_DIR_PREFERS_GRID
+         * @see #FLAG_DIR_SUPPORTS_CREATE
+         */
+        public static final String COLUMN_FLAGS = "flags";
+
+        /**
+         * Size of a document, in bytes, or {@code null} if unknown.
+         * <p>
+         * Type: INTEGER (long)
+         */
+        public static final String COLUMN_SIZE = OpenableColumns.SIZE;
+
+        /**
+         * MIME type of a document which is a directory that may contain
+         * additional documents.
+         *
+         * @see #COLUMN_MIME_TYPE
+         */
+        public static final String MIME_TYPE_DIR = "vnd.android.document/directory";
+
+        /**
+         * Flag indicating that a document can be represented as a thumbnail.
+         *
+         * @see #COLUMN_FLAGS
+         * @see DocumentsContract#getDocumentThumbnail(ContentResolver, Uri,
+         *      Point, CancellationSignal)
+         * @see DocumentsProvider#openDocumentThumbnail(String, Point,
+         *      android.os.CancellationSignal)
+         */
+        public static final int FLAG_SUPPORTS_THUMBNAIL = 1;
+
+        /**
+         * Flag indicating that a document supports writing.
+         * <p>
+         * When a document is opened with {@link Intent#ACTION_OPEN_DOCUMENT},
+         * the calling application is granted both
+         * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} and
+         * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION}. However, the actual
+         * writability of a document may change over time, for example due to
+         * remote access changes. This flag indicates that a document client can
+         * expect {@link ContentResolver#openOutputStream(Uri)} to succeed.
+         *
+         * @see #COLUMN_FLAGS
+         */
+        public static final int FLAG_SUPPORTS_WRITE = 1 << 1;
+
+        /**
+         * Flag indicating that a document is deletable.
+         *
+         * @see #COLUMN_FLAGS
+         * @see DocumentsContract#deleteDocument(ContentResolver, Uri)
+         * @see DocumentsProvider#deleteDocument(String)
+         */
+        public static final int FLAG_SUPPORTS_DELETE = 1 << 2;
+
+        /**
+         * Flag indicating that a document is a directory that supports creation
+         * of new files within it. Only valid when {@link #COLUMN_MIME_TYPE} is
+         * {@link #MIME_TYPE_DIR}.
+         *
+         * @see #COLUMN_FLAGS
+         * @see DocumentsContract#createDocument(ContentResolver, Uri, String,
+         *      String)
+         * @see DocumentsProvider#createDocument(String, String, String)
+         */
+        public static final int FLAG_DIR_SUPPORTS_CREATE = 1 << 3;
+
+        /**
+         * Flag indicating that a directory prefers its contents be shown in a
+         * larger format grid. Usually suitable when a directory contains mostly
+         * pictures. Only valid when {@link #COLUMN_MIME_TYPE} is
+         * {@link #MIME_TYPE_DIR}.
+         *
+         * @see #COLUMN_FLAGS
+         */
+        public static final int FLAG_DIR_PREFERS_GRID = 1 << 4;
+
+        /**
+         * Flag indicating that a directory prefers its contents be sorted by
+         * {@link #COLUMN_LAST_MODIFIED}. Only valid when
+         * {@link #COLUMN_MIME_TYPE} is {@link #MIME_TYPE_DIR}.
+         *
+         * @see #COLUMN_FLAGS
+         */
+        public static final int FLAG_DIR_PREFERS_LAST_MODIFIED = 1 << 5;
+
+        /**
+         * Flag indicating that document titles should be hidden when viewing
+         * this directory in a larger format grid. For example, a directory
+         * containing only images may want the image thumbnails to speak for
+         * themselves. Only valid when {@link #COLUMN_MIME_TYPE} is
+         * {@link #MIME_TYPE_DIR}.
+         *
+         * @see #COLUMN_FLAGS
+         * @see #FLAG_DIR_PREFERS_GRID
+         */
+        public static final int FLAG_DIR_HIDE_GRID_TITLES = 1 << 6;
+    }
+
+    /**
+     * Constants related to a root of documents, including {@link Cursor}
+     * columns names and flags.
+     * <p>
+     * All columns are <em>read-only</em> to client applications.
+     */
+    public final static class Root {
+        private Root() {
+        }
+
+        /**
+         * Unique ID of a root. This ID is both provided by and interpreted by a
+         * {@link DocumentsProvider}, and should be treated as an opaque value
+         * by client applications.
+         * <p>
+         * Type: STRING
+         */
+        public static final String COLUMN_ROOT_ID = "root_id";
+
+        /**
+         * Type of a root, used for clustering when presenting multiple roots to
+         * a user.
+         * <p>
+         * Type: INTEGER (int)
+         *
+         * @see #ROOT_TYPE_SERVICE
+         * @see #ROOT_TYPE_SHORTCUT
+         * @see #ROOT_TYPE_DEVICE
+         */
+        public static final String COLUMN_ROOT_TYPE = "root_type";
+
+        /**
+         * Flags that apply to a root.
+         * <p>
+         * Type: INTEGER (int)
+         *
+         * @see #FLAG_ADVANCED
+         * @see #FLAG_EMPTY
+         * @see #FLAG_LOCAL_ONLY
+         * @see #FLAG_SUPPORTS_CREATE
+         * @see #FLAG_SUPPORTS_RECENTS
+         * @see #FLAG_SUPPORTS_SEARCH
+         */
+        public static final String COLUMN_FLAGS = "flags";
+
+        /**
+         * Icon resource ID for a root.
+         * <p>
+         * Type: INTEGER (int)
+         */
+        public static final String COLUMN_ICON = "icon";
+
+        /**
+         * Title for a root, which will be shown to a user.
+         * <p>
+         * Type: STRING
+         */
+        public static final String COLUMN_TITLE = "title";
+
+        /**
+         * Summary for this root, which may be shown to a user. The summary may
+         * be {@code null}.
+         * <p>
+         * Type: STRING
+         */
+        public static final String COLUMN_SUMMARY = "summary";
+
+        /**
+         * Document which is a directory that represents the top directory of
+         * this root.
+         * <p>
+         * Type: STRING
+         *
+         * @see Document#COLUMN_DOCUMENT_ID
+         */
+        public static final String COLUMN_DOCUMENT_ID = "document_id";
+
+        /**
+         * Number of bytes available in this root, or {@code null} if unknown or
+         * unbounded.
+         * <p>
+         * Type: INTEGER (long)
+         */
+        public static final String COLUMN_AVAILABLE_BYTES = "available_bytes";
+
+        /**
+         * MIME types supported by this root, or {@code null} if the root
+         * supports all MIME types. Multiple MIME types can be separated by a
+         * newline. For example, a root supporting audio might use
+         * "audio/*\napplication/x-flac".
+         * <p>
+         * Type: String
+         */
+        public static final String COLUMN_MIME_TYPES = "mime_types";
+
+        /** {@hide} */
+        public static final String MIME_TYPE_ITEM = "vnd.android.document/root";
+
+        /**
+         * Type of root that represents a storage service, such as a cloud-based
+         * service.
+         *
+         * @see #COLUMN_ROOT_TYPE
+         */
+        public static final int ROOT_TYPE_SERVICE = 1;
+
+        /**
+         * Type of root that represents a shortcut to content that may be
+         * available elsewhere through another storage root.
+         *
+         * @see #COLUMN_ROOT_TYPE
+         */
+        public static final int ROOT_TYPE_SHORTCUT = 2;
+
+        /**
+         * Type of root that represents a physical storage device.
+         *
+         * @see #COLUMN_ROOT_TYPE
+         */
+        public static final int ROOT_TYPE_DEVICE = 3;
+
+        /**
+         * Flag indicating that at least one directory under this root supports
+         * creating content. Roots with this flag will be shown when an
+         * application interacts with {@link Intent#ACTION_CREATE_DOCUMENT}.
+         *
+         * @see #COLUMN_FLAGS
+         */
+        public static final int FLAG_SUPPORTS_CREATE = 1;
+
+        /**
+         * Flag indicating that this root offers content that is strictly local
+         * on the device. That is, no network requests are made for the content.
+         *
+         * @see #COLUMN_FLAGS
+         * @see Intent#EXTRA_LOCAL_ONLY
+         */
+        public static final int FLAG_LOCAL_ONLY = 1 << 1;
+
+        /**
+         * Flag indicating that this root should only be visible to advanced
+         * users.
+         *
+         * @see #COLUMN_FLAGS
+         */
+        public static final int FLAG_ADVANCED = 1 << 2;
+
+        /**
+         * Flag indicating that this root can report recently modified
+         * documents.
+         *
+         * @see #COLUMN_FLAGS
+         * @see DocumentsContract#buildRecentDocumentsUri(String, String)
+         */
+        public static final int FLAG_SUPPORTS_RECENTS = 1 << 3;
+
+        /**
+         * Flag indicating that this root supports search.
+         *
+         * @see #COLUMN_FLAGS
+         * @see DocumentsProvider#querySearchDocuments(String, String,
+         *      String[])
+         */
+        public static final int FLAG_SUPPORTS_SEARCH = 1 << 4;
+
+        /**
+         * Flag indicating that this root is currently empty. This may be used
+         * to hide the root when opening documents, but the root will still be
+         * shown when creating documents and {@link #FLAG_SUPPORTS_CREATE} is
+         * also set.
+         *
+         * @see #COLUMN_FLAGS
+         * @see DocumentsProvider#querySearchDocuments(String, String,
+         *      String[])
+         */
+        public static final int FLAG_EMPTY = 1 << 5;
+    }
+
+    /**
+     * Optional boolean flag included in a directory {@link Cursor#getExtras()}
+     * indicating that a document provider is still loading data. For example, a
+     * provider has returned some results, but is still waiting on an
+     * outstanding network request. The provider must send a content changed
+     * notification when loading is finished.
+     *
+     * @see ContentResolver#notifyChange(Uri, android.database.ContentObserver,
+     *      boolean)
+     */
+    public static final String EXTRA_LOADING = "loading";
+
+    /**
+     * Optional string included in a directory {@link Cursor#getExtras()}
+     * providing an informational message that should be shown to a user. For
+     * example, a provider may wish to indicate that not all documents are
+     * available.
+     */
+    public static final String EXTRA_INFO = "info";
+
+    /**
+     * Optional string included in a directory {@link Cursor#getExtras()}
+     * providing an error message that should be shown to a user. For example, a
+     * provider may wish to indicate that a network error occurred. The user may
+     * choose to retry, resulting in a new query.
+     */
+    public static final String EXTRA_ERROR = "error";
+
+    /** {@hide} */
+    public static final String METHOD_CREATE_DOCUMENT = "android:createDocument";
+    /** {@hide} */
+    public static final String METHOD_DELETE_DOCUMENT = "android:deleteDocument";
+
+    /** {@hide} */
+    public static final String EXTRA_THUMBNAIL_SIZE = "thumbnail_size";
+
+    private static final String PATH_ROOT = "root";
+    private static final String PATH_RECENT = "recent";
+    private static final String PATH_DOCUMENT = "document";
+    private static final String PATH_CHILDREN = "children";
+    private static final String PATH_SEARCH = "search";
+
+    private static final String PARAM_QUERY = "query";
+    private static final String PARAM_MANAGE = "manage";
+
+    /**
+     * Build Uri representing the roots of a document provider. When queried, a
+     * provider will return one or more rows with columns defined by
+     * {@link Root}.
+     *
+     * @see DocumentsProvider#queryRoots(String[])
+     */
+    public static Uri buildRootsUri(String authority) {
+        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
+                .authority(authority).appendPath(PATH_ROOT).build();
+    }
+
+    /**
+     * Build Uri representing the given {@link Root#COLUMN_ROOT_ID} in a
+     * document provider.
+     *
+     * @see #getRootId(Uri)
+     */
+    public static Uri buildRootUri(String authority, String rootId) {
+        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
+                .authority(authority).appendPath(PATH_ROOT).appendPath(rootId).build();
+    }
+
+    /**
+     * Build Uri representing the recently modified documents of a specific root
+     * in a document provider. When queried, a provider will return zero or more
+     * rows with columns defined by {@link Document}.
+     *
+     * @see DocumentsProvider#queryRecentDocuments(String, String[])
+     * @see #getRootId(Uri)
+     */
+    public static Uri buildRecentDocumentsUri(String authority, String rootId) {
+        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
+                .authority(authority).appendPath(PATH_ROOT).appendPath(rootId)
+                .appendPath(PATH_RECENT).build();
+    }
+
+    /**
+     * Build Uri representing the given {@link Document#COLUMN_DOCUMENT_ID} in a
+     * document provider. When queried, a provider will return a single row with
+     * columns defined by {@link Document}.
+     *
+     * @see DocumentsProvider#queryDocument(String, String[])
+     * @see #getDocumentId(Uri)
+     */
+    public static Uri buildDocumentUri(String authority, String documentId) {
+        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
+                .authority(authority).appendPath(PATH_DOCUMENT).appendPath(documentId).build();
+    }
+
+    /**
+     * Build Uri representing the children of the given directory in a document
+     * provider. When queried, a provider will return zero or more rows with
+     * columns defined by {@link Document}.
+     *
+     * @param parentDocumentId the document to return children for, which must
+     *            be a directory with MIME type of
+     *            {@link Document#MIME_TYPE_DIR}.
+     * @see DocumentsProvider#queryChildDocuments(String, String[], String)
+     * @see #getDocumentId(Uri)
+     */
+    public static Uri buildChildDocumentsUri(String authority, String parentDocumentId) {
+        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(authority)
+                .appendPath(PATH_DOCUMENT).appendPath(parentDocumentId).appendPath(PATH_CHILDREN)
+                .build();
+    }
+
+    /**
+     * Build Uri representing a search for matching documents under a specific
+     * root in a document provider. When queried, a provider will return zero or
+     * more rows with columns defined by {@link Document}.
+     *
+     * @see DocumentsProvider#querySearchDocuments(String, String, String[])
+     * @see #getRootId(Uri)
+     * @see #getSearchDocumentsQuery(Uri)
+     */
+    public static Uri buildSearchDocumentsUri(
+            String authority, String rootId, String query) {
+        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(authority)
+                .appendPath(PATH_ROOT).appendPath(rootId).appendPath(PATH_SEARCH)
+                .appendQueryParameter(PARAM_QUERY, query).build();
+    }
+
+    /**
+     * Extract the {@link Root#COLUMN_ROOT_ID} from the given Uri.
+     */
+    public static String getRootId(Uri rootUri) {
+        final List<String> paths = rootUri.getPathSegments();
+        if (paths.size() < 2) {
+            throw new IllegalArgumentException("Not a root: " + rootUri);
+        }
+        if (!PATH_ROOT.equals(paths.get(0))) {
+            throw new IllegalArgumentException("Not a root: " + rootUri);
+        }
+        return paths.get(1);
+    }
+
+    /**
+     * Extract the {@link Document#COLUMN_DOCUMENT_ID} from the given Uri.
+     */
+    public static String getDocumentId(Uri documentUri) {
+        final List<String> paths = documentUri.getPathSegments();
+        if (paths.size() < 2) {
+            throw new IllegalArgumentException("Not a document: " + documentUri);
+        }
+        if (!PATH_DOCUMENT.equals(paths.get(0))) {
+            throw new IllegalArgumentException("Not a document: " + documentUri);
+        }
+        return paths.get(1);
+    }
+
+    /**
+     * Extract the search query from a Uri built by
+     * {@link #buildSearchDocumentsUri(String, String, String)}.
+     */
+    public static String getSearchDocumentsQuery(Uri searchDocumentsUri) {
+        return searchDocumentsUri.getQueryParameter(PARAM_QUERY);
+    }
+
+    /** {@hide} */
+    public static Uri setManageMode(Uri uri) {
+        return uri.buildUpon().appendQueryParameter(PARAM_MANAGE, "true").build();
+    }
+
+    /** {@hide} */
+    public static boolean isManageMode(Uri uri) {
+        return uri.getBooleanQueryParameter(PARAM_MANAGE, false);
+    }
+
+    /**
+     * Return list of all documents that the calling package has "open." These
+     * are Uris matching {@link DocumentsContract} to which persistent
+     * read/write access has been granted, usually through
+     * {@link Intent#ACTION_OPEN_DOCUMENT} or
+     * {@link Intent#ACTION_CREATE_DOCUMENT}.
+     *
+     * @see Context#grantUriPermission(String, Uri, int)
+     * @see Context#revokeUriPermission(Uri, int)
+     * @see ContentResolver#getIncomingUriPermissionGrants(int, int)
+     */
+    public static Uri[] getOpenDocuments(Context context) {
+        final int openedFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION
+                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_PERSIST_GRANT_URI_PERMISSION;
+        final Uri[] uris = context.getContentResolver()
+                .getIncomingUriPermissionGrants(openedFlags, openedFlags);
+
+        // Filter to only include document providers
+        final PackageManager pm = context.getPackageManager();
+        final List<Uri> result = Lists.newArrayList();
+        for (Uri uri : uris) {
+            final ProviderInfo info = pm.resolveContentProvider(
+                    uri.getAuthority(), PackageManager.GET_META_DATA);
+            if (info.metaData.containsKey(META_DATA_DOCUMENT_PROVIDER)) {
+                result.add(uri);
+            }
+        }
+
+        return result.toArray(new Uri[result.size()]);
+    }
+
+    /**
+     * Return thumbnail representing the document at the given Uri. Callers are
+     * responsible for their own in-memory caching.
+     *
+     * @param documentUri document to return thumbnail for, which must have
+     *            {@link Document#FLAG_SUPPORTS_THUMBNAIL} set.
+     * @param size optimal thumbnail size desired. A provider may return a
+     *            thumbnail of a different size, but never more than double the
+     *            requested size.
+     * @param signal signal used to indicate that caller is no longer interested
+     *            in the thumbnail.
+     * @return decoded thumbnail, or {@code null} if problem was encountered.
+     * @see DocumentsProvider#openDocumentThumbnail(String, Point,
+     *      android.os.CancellationSignal)
+     */
+    public static Bitmap getDocumentThumbnail(
+            ContentResolver resolver, Uri documentUri, Point size, CancellationSignal signal) {
+        final ContentProviderClient client = resolver.acquireUnstableContentProviderClient(
+                documentUri.getAuthority());
+        try {
+            return getDocumentThumbnail(client, documentUri, size, signal);
+        } catch (RemoteException e) {
+            return null;
+        } finally {
+            ContentProviderClient.closeQuietly(client);
+        }
+    }
+
+    /** {@hide} */
+    public static Bitmap getDocumentThumbnail(
+            ContentProviderClient client, Uri documentUri, Point size, CancellationSignal signal)
+            throws RemoteException {
+        final Bundle openOpts = new Bundle();
+        openOpts.putParcelable(DocumentsContract.EXTRA_THUMBNAIL_SIZE, size);
+
+        AssetFileDescriptor afd = null;
+        try {
+            afd = client.openTypedAssetFileDescriptor(documentUri, "image/*", openOpts, signal);
+
+            final FileDescriptor fd = afd.getFileDescriptor();
+            final long offset = afd.getStartOffset();
+
+            // Try seeking on the returned FD, since it gives us the most
+            // optimal decode path; otherwise fall back to buffering.
+            BufferedInputStream is = null;
+            try {
+                Libcore.os.lseek(fd, offset, SEEK_SET);
+            } catch (ErrnoException e) {
+                is = new BufferedInputStream(new FileInputStream(fd), THUMBNAIL_BUFFER_SIZE);
+                is.mark(THUMBNAIL_BUFFER_SIZE);
+            }
+
+            // We requested a rough thumbnail size, but the remote size may have
+            // returned something giant, so defensively scale down as needed.
+            final BitmapFactory.Options opts = new BitmapFactory.Options();
+            opts.inJustDecodeBounds = true;
+            if (is != null) {
+                BitmapFactory.decodeStream(is, null, opts);
+            } else {
+                BitmapFactory.decodeFileDescriptor(fd, null, opts);
+            }
+
+            final int widthSample = opts.outWidth / size.x;
+            final int heightSample = opts.outHeight / size.y;
+
+            opts.inJustDecodeBounds = false;
+            opts.inSampleSize = Math.min(widthSample, heightSample);
+            Log.d(TAG, "Decoding with sample size " + opts.inSampleSize);
+            if (is != null) {
+                is.reset();
+                return BitmapFactory.decodeStream(is, null, opts);
+            } else {
+                try {
+                    Libcore.os.lseek(fd, offset, SEEK_SET);
+                } catch (ErrnoException e) {
+                    e.rethrowAsIOException();
+                }
+                return BitmapFactory.decodeFileDescriptor(fd, null, opts);
+            }
+        } catch (IOException e) {
+            Log.w(TAG, "Failed to load thumbnail for " + documentUri + ": " + e);
+            return null;
+        } finally {
+            IoUtils.closeQuietly(afd);
+        }
+    }
+
+    /**
+     * Create a new document with given MIME type and display name.
+     *
+     * @param parentDocumentUri directory with
+     *            {@link Document#FLAG_DIR_SUPPORTS_CREATE}
+     * @param mimeType MIME type of new document
+     * @param displayName name of new document
+     * @return newly created document, or {@code null} if failed
+     * @hide
+     */
+    public static Uri createDocument(ContentResolver resolver, Uri parentDocumentUri,
+            String mimeType, String displayName) {
+        final ContentProviderClient client = resolver.acquireUnstableContentProviderClient(
+                parentDocumentUri.getAuthority());
+        try {
+            return createDocument(client, parentDocumentUri, mimeType, displayName);
+        } finally {
+            ContentProviderClient.closeQuietly(client);
+        }
+    }
+
+    /** {@hide} */
+    public static Uri createDocument(ContentProviderClient client, Uri parentDocumentUri,
+            String mimeType, String displayName) {
+        final Bundle in = new Bundle();
+        in.putString(Document.COLUMN_DOCUMENT_ID, getDocumentId(parentDocumentUri));
+        in.putString(Document.COLUMN_MIME_TYPE, mimeType);
+        in.putString(Document.COLUMN_DISPLAY_NAME, displayName);
+
+        try {
+            final Bundle out = client.call(METHOD_CREATE_DOCUMENT, null, in);
+            return buildDocumentUri(
+                    parentDocumentUri.getAuthority(), out.getString(Document.COLUMN_DOCUMENT_ID));
+        } catch (Exception e) {
+            Log.w(TAG, "Failed to create document", e);
+            return null;
+        }
+    }
+
+    /**
+     * Delete the given document.
+     *
+     * @param documentUri document with {@link Document#FLAG_SUPPORTS_DELETE}
+     */
+    public static boolean deleteDocument(ContentResolver resolver, Uri documentUri) {
+        final ContentProviderClient client = resolver.acquireUnstableContentProviderClient(
+                documentUri.getAuthority());
+        try {
+            return deleteDocument(client, documentUri);
+        } finally {
+            ContentProviderClient.closeQuietly(client);
+        }
+    }
+
+    /** {@hide} */
+    public static boolean deleteDocument(ContentProviderClient client, Uri documentUri) {
+        final Bundle in = new Bundle();
+        in.putString(Document.COLUMN_DOCUMENT_ID, getDocumentId(documentUri));
+
+        try {
+            final Bundle out = client.call(METHOD_DELETE_DOCUMENT, null, in);
+            return true;
+        } catch (Exception e) {
+            Log.w(TAG, "Failed to delete document", e);
+            return false;
+        }
+    }
+}
diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java
new file mode 100644
index 0000000..bc4e28b
--- /dev/null
+++ b/core/java/android/provider/DocumentsProvider.java
@@ -0,0 +1,463 @@
+/*
+ * 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.provider;
+
+import static android.provider.DocumentsContract.EXTRA_THUMBNAIL_SIZE;
+import static android.provider.DocumentsContract.METHOD_CREATE_DOCUMENT;
+import static android.provider.DocumentsContract.METHOD_DELETE_DOCUMENT;
+import static android.provider.DocumentsContract.getDocumentId;
+import static android.provider.DocumentsContract.getRootId;
+import static android.provider.DocumentsContract.getSearchDocumentsQuery;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.content.UriMatcher;
+import android.content.pm.PackageManager;
+import android.content.pm.ProviderInfo;
+import android.content.res.AssetFileDescriptor;
+import android.database.Cursor;
+import android.graphics.Point;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.CancellationSignal;
+import android.os.ParcelFileDescriptor;
+import android.os.ParcelFileDescriptor.OnCloseListener;
+import android.provider.DocumentsContract.Document;
+import android.util.Log;
+
+import libcore.io.IoUtils;
+
+import java.io.FileNotFoundException;
+
+/**
+ * Base class for a document provider. A document provider should extend this
+ * class and implement the abstract methods.
+ * <p>
+ * Each document provider expresses one or more "roots" which each serve as the
+ * top-level of a tree. For example, a root could represent an account, or a
+ * physical storage device. Under each root, documents are referenced by
+ * {@link Document#COLUMN_DOCUMENT_ID}, which must not change once returned.
+ * <p>
+ * Documents can be either an openable file (with a specific MIME type), or a
+ * directory containing additional documents (with the
+ * {@link Document#MIME_TYPE_DIR} MIME type). Each document can have different
+ * capabilities, as described by {@link Document#COLUMN_FLAGS}. The same
+ * {@link Document#COLUMN_DOCUMENT_ID} can be included in multiple directories.
+ * <p>
+ * Document providers must be protected with the
+ * {@link android.Manifest.permission#MANAGE_DOCUMENTS} permission, which can
+ * only be requested by the system. The system-provided UI then issues narrow
+ * Uri permission grants for individual documents when the user explicitly picks
+ * documents.
+ *
+ * @see Intent#ACTION_OPEN_DOCUMENT
+ * @see Intent#ACTION_CREATE_DOCUMENT
+ */
+public abstract class DocumentsProvider extends ContentProvider {
+    private static final String TAG = "DocumentsProvider";
+
+    private static final int MATCH_ROOTS = 1;
+    private static final int MATCH_ROOT = 2;
+    private static final int MATCH_RECENT = 3;
+    private static final int MATCH_SEARCH = 4;
+    private static final int MATCH_DOCUMENT = 5;
+    private static final int MATCH_CHILDREN = 6;
+
+    private String mAuthority;
+
+    private UriMatcher mMatcher;
+
+    /**
+     * Implementation is provided by the parent class.
+     */
+    @Override
+    public void attachInfo(Context context, ProviderInfo info) {
+        mAuthority = info.authority;
+
+        mMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+        mMatcher.addURI(mAuthority, "root", MATCH_ROOTS);
+        mMatcher.addURI(mAuthority, "root/*", MATCH_ROOT);
+        mMatcher.addURI(mAuthority, "root/*/recent", MATCH_RECENT);
+        mMatcher.addURI(mAuthority, "root/*/search", MATCH_SEARCH);
+        mMatcher.addURI(mAuthority, "document/*", MATCH_DOCUMENT);
+        mMatcher.addURI(mAuthority, "document/*/children", MATCH_CHILDREN);
+
+        // Sanity check our setup
+        if (!info.exported) {
+            throw new SecurityException("Provider must be exported");
+        }
+        if (!info.grantUriPermissions) {
+            throw new SecurityException("Provider must grantUriPermissions");
+        }
+        if (!android.Manifest.permission.MANAGE_DOCUMENTS.equals(info.readPermission)
+                || !android.Manifest.permission.MANAGE_DOCUMENTS.equals(info.writePermission)) {
+            throw new SecurityException("Provider must be protected by MANAGE_DOCUMENTS");
+        }
+
+        super.attachInfo(context, info);
+    }
+
+    /**
+     * Create a new document and return its {@link Document#COLUMN_DOCUMENT_ID}.
+     * A provider must allocate a new {@link Document#COLUMN_DOCUMENT_ID} to
+     * represent the document, which must not change once returned.
+     *
+     * @param documentId the parent directory to create the new document under.
+     * @param mimeType the MIME type associated with the new document.
+     * @param displayName the display name of the new document.
+     */
+    @SuppressWarnings("unused")
+    public String createDocument(String documentId, String mimeType, String displayName)
+            throws FileNotFoundException {
+        throw new UnsupportedOperationException("Create not supported");
+    }
+
+    /**
+     * Delete the given document. Upon returning, any Uri permission grants for
+     * the given document will be revoked. If additional documents were deleted
+     * as a side effect of this call, such as documents inside a directory, the
+     * implementor is responsible for revoking those permissions.
+     *
+     * @param documentId the document to delete.
+     */
+    @SuppressWarnings("unused")
+    public void deleteDocument(String documentId) throws FileNotFoundException {
+        throw new UnsupportedOperationException("Delete not supported");
+    }
+
+    public abstract Cursor queryRoots(String[] projection) throws FileNotFoundException;
+
+    @SuppressWarnings("unused")
+    public Cursor queryRecentDocuments(String rootId, String[] projection)
+            throws FileNotFoundException {
+        throw new UnsupportedOperationException("Recent not supported");
+    }
+
+    /**
+     * Return metadata for the given document. A provider should avoid making
+     * network requests to keep this request fast.
+     *
+     * @param documentId the document to return.
+     */
+    public abstract Cursor queryDocument(String documentId, String[] projection)
+            throws FileNotFoundException;
+
+    /**
+     * Return the children of the given document which is a directory.
+     *
+     * @param parentDocumentId the directory to return children for.
+     */
+    public abstract Cursor queryChildDocuments(
+            String parentDocumentId, String[] projection, String sortOrder)
+            throws FileNotFoundException;
+
+    /** {@hide} */
+    @SuppressWarnings("unused")
+    public Cursor queryChildDocumentsForManage(
+            String parentDocumentId, String[] projection, String sortOrder)
+            throws FileNotFoundException {
+        throw new UnsupportedOperationException("Manage not supported");
+    }
+
+    /**
+     * Return documents that that match the given query.
+     *
+     * @param rootId the root to search under.
+     */
+    @SuppressWarnings("unused")
+    public Cursor querySearchDocuments(String rootId, String query, String[] projection)
+            throws FileNotFoundException {
+        throw new UnsupportedOperationException("Search not supported");
+    }
+
+    /**
+     * Return MIME type for the given document. Must match the value of
+     * {@link Document#COLUMN_MIME_TYPE} for this document.
+     */
+    public String getDocumentType(String documentId) throws FileNotFoundException {
+        final Cursor cursor = queryDocument(documentId, null);
+        try {
+            if (cursor.moveToFirst()) {
+                return cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_MIME_TYPE));
+            } else {
+                return null;
+            }
+        } finally {
+            IoUtils.closeQuietly(cursor);
+        }
+    }
+
+    /**
+     * Open and return the requested document. A provider should return a
+     * reliable {@link ParcelFileDescriptor} to detect when the remote caller
+     * has finished reading or writing the document. A provider may return a
+     * pipe or socket pair if the mode is exclusively
+     * {@link ParcelFileDescriptor#MODE_READ_ONLY} or
+     * {@link ParcelFileDescriptor#MODE_WRITE_ONLY}, but complex modes like
+     * {@link ParcelFileDescriptor#MODE_READ_WRITE} require a normal file on
+     * disk. If a provider blocks while downloading content, it should
+     * periodically check {@link CancellationSignal#isCanceled()} to abort
+     * abandoned open requests.
+     *
+     * @param docId the document to return.
+     * @param mode the mode to open with, such as 'r', 'w', or 'rw'.
+     * @param signal used by the caller to signal if the request should be
+     *            cancelled.
+     * @see ParcelFileDescriptor#open(java.io.File, int, android.os.Handler,
+     *      OnCloseListener)
+     * @see ParcelFileDescriptor#createReliablePipe()
+     * @see ParcelFileDescriptor#createReliableSocketPair()
+     */
+    public abstract ParcelFileDescriptor openDocument(
+            String docId, String mode, CancellationSignal signal) throws FileNotFoundException;
+
+    /**
+     * Open and return a thumbnail of the requested document. A provider should
+     * return a thumbnail closely matching the hinted size, attempting to serve
+     * from a local cache if possible. A provider should never return images
+     * more than double the hinted size. If a provider performs expensive
+     * operations to download or generate a thumbnail, it should periodically
+     * check {@link CancellationSignal#isCanceled()} to abort abandoned
+     * thumbnail requests.
+     *
+     * @param docId the document to return.
+     * @param sizeHint hint of the optimal thumbnail dimensions.
+     * @param signal used by the caller to signal if the request should be
+     *            cancelled.
+     * @see Document#FLAG_SUPPORTS_THUMBNAIL
+     */
+    @SuppressWarnings("unused")
+    public AssetFileDescriptor openDocumentThumbnail(
+            String docId, Point sizeHint, CancellationSignal signal) throws FileNotFoundException {
+        throw new UnsupportedOperationException("Thumbnails not supported");
+    }
+
+    /**
+     * Implementation is provided by the parent class. Cannot be overriden.
+     *
+     * @see #queryRoots(String[])
+     * @see #queryRecentDocuments(String, String[])
+     * @see #queryDocument(String, String[])
+     * @see #queryChildDocuments(String, String[], String)
+     * @see #querySearchDocuments(String, String, String[])
+     */
+    @Override
+    public final Cursor query(Uri uri, String[] projection, String selection,
+            String[] selectionArgs, String sortOrder) {
+        try {
+            switch (mMatcher.match(uri)) {
+                case MATCH_ROOTS:
+                    return queryRoots(projection);
+                case MATCH_RECENT:
+                    return queryRecentDocuments(getRootId(uri), projection);
+                case MATCH_SEARCH:
+                    return querySearchDocuments(
+                            getRootId(uri), getSearchDocumentsQuery(uri), projection);
+                case MATCH_DOCUMENT:
+                    return queryDocument(getDocumentId(uri), projection);
+                case MATCH_CHILDREN:
+                    if (DocumentsContract.isManageMode(uri)) {
+                        return queryChildDocumentsForManage(
+                                getDocumentId(uri), projection, sortOrder);
+                    } else {
+                        return queryChildDocuments(getDocumentId(uri), projection, sortOrder);
+                    }
+                default:
+                    throw new UnsupportedOperationException("Unsupported Uri " + uri);
+            }
+        } catch (FileNotFoundException e) {
+            Log.w(TAG, "Failed during query", e);
+            return null;
+        }
+    }
+
+    /**
+     * Implementation is provided by the parent class. Cannot be overriden.
+     *
+     * @see #getDocumentType(String)
+     */
+    @Override
+    public final String getType(Uri uri) {
+        try {
+            switch (mMatcher.match(uri)) {
+                case MATCH_ROOT:
+                    return DocumentsContract.Root.MIME_TYPE_ITEM;
+                case MATCH_DOCUMENT:
+                    return getDocumentType(getDocumentId(uri));
+                default:
+                    return null;
+            }
+        } catch (FileNotFoundException e) {
+            Log.w(TAG, "Failed during getType", e);
+            return null;
+        }
+    }
+
+    /**
+     * Implementation is provided by the parent class. Throws by default, and
+     * cannot be overriden.
+     *
+     * @see #createDocument(String, String, String)
+     */
+    @Override
+    public final Uri insert(Uri uri, ContentValues values) {
+        throw new UnsupportedOperationException("Insert not supported");
+    }
+
+    /**
+     * Implementation is provided by the parent class. Throws by default, and
+     * cannot be overriden.
+     *
+     * @see #deleteDocument(String)
+     */
+    @Override
+    public final int delete(Uri uri, String selection, String[] selectionArgs) {
+        throw new UnsupportedOperationException("Delete not supported");
+    }
+
+    /**
+     * Implementation is provided by the parent class. Throws by default, and
+     * cannot be overriden.
+     */
+    @Override
+    public final int update(
+            Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        throw new UnsupportedOperationException("Update not supported");
+    }
+
+    /**
+     * Implementation is provided by the parent class. Can be overridden to
+     * provide additional functionality, but subclasses <em>must</em> always
+     * call the superclass. If the superclass returns {@code null}, the subclass
+     * may implement custom behavior.
+     *
+     * @see #openDocument(String, String, CancellationSignal)
+     * @see #deleteDocument(String)
+     */
+    @Override
+    public Bundle call(String method, String arg, Bundle extras) {
+        final Context context = getContext();
+
+        if (!method.startsWith("android:")) {
+            // Let non-platform methods pass through
+            return super.call(method, arg, extras);
+        }
+
+        final String documentId = extras.getString(Document.COLUMN_DOCUMENT_ID);
+        final Uri documentUri = DocumentsContract.buildDocumentUri(mAuthority, documentId);
+
+        // Require that caller can manage given document
+        final boolean callerHasManage =
+                context.checkCallingOrSelfPermission(android.Manifest.permission.MANAGE_DOCUMENTS)
+                == PackageManager.PERMISSION_GRANTED;
+        if (!callerHasManage) {
+            getContext().enforceCallingOrSelfUriPermission(
+                    documentUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, method);
+        }
+
+        final Bundle out = new Bundle();
+        try {
+            if (METHOD_CREATE_DOCUMENT.equals(method)) {
+                final String mimeType = extras.getString(Document.COLUMN_MIME_TYPE);
+                final String displayName = extras.getString(Document.COLUMN_DISPLAY_NAME);
+
+                final String newDocumentId = createDocument(documentId, mimeType, displayName);
+                out.putString(Document.COLUMN_DOCUMENT_ID, newDocumentId);
+
+                // Extend permission grant towards caller if needed
+                if (!callerHasManage) {
+                    final Uri newDocumentUri = DocumentsContract.buildDocumentUri(
+                            mAuthority, newDocumentId);
+                    context.grantUriPermission(getCallingPackage(), newDocumentUri,
+                            Intent.FLAG_GRANT_READ_URI_PERMISSION
+                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+                            | Intent.FLAG_PERSIST_GRANT_URI_PERMISSION);
+                }
+
+            } else if (METHOD_DELETE_DOCUMENT.equals(method)) {
+                deleteDocument(documentId);
+
+                // Document no longer exists, clean up any grants
+                context.revokeUriPermission(documentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION
+                        | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+                        | Intent.FLAG_PERSIST_GRANT_URI_PERMISSION);
+
+            } else {
+                throw new UnsupportedOperationException("Method not supported " + method);
+            }
+        } catch (FileNotFoundException e) {
+            throw new IllegalStateException("Failed call " + method, e);
+        }
+        return out;
+    }
+
+    /**
+     * Implementation is provided by the parent class.
+     *
+     * @see #openDocument(String, String, CancellationSignal)
+     */
+    @Override
+    public final ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
+        return openDocument(getDocumentId(uri), mode, null);
+    }
+
+    /**
+     * Implementation is provided by the parent class.
+     *
+     * @see #openDocument(String, String, CancellationSignal)
+     */
+    @Override
+    public final ParcelFileDescriptor openFile(Uri uri, String mode, CancellationSignal signal)
+            throws FileNotFoundException {
+        return openDocument(getDocumentId(uri), mode, signal);
+    }
+
+    /**
+     * Implementation is provided by the parent class.
+     *
+     * @see #openDocumentThumbnail(String, Point, CancellationSignal)
+     */
+    @Override
+    public final AssetFileDescriptor openTypedAssetFile(Uri uri, String mimeTypeFilter, Bundle opts)
+            throws FileNotFoundException {
+        if (opts != null && opts.containsKey(EXTRA_THUMBNAIL_SIZE)) {
+            final Point sizeHint = opts.getParcelable(EXTRA_THUMBNAIL_SIZE);
+            return openDocumentThumbnail(getDocumentId(uri), sizeHint, null);
+        } else {
+            return super.openTypedAssetFile(uri, mimeTypeFilter, opts);
+        }
+    }
+
+    /**
+     * Implementation is provided by the parent class.
+     *
+     * @see #openDocumentThumbnail(String, Point, CancellationSignal)
+     */
+    @Override
+    public final AssetFileDescriptor openTypedAssetFile(
+            Uri uri, String mimeTypeFilter, Bundle opts, CancellationSignal signal)
+            throws FileNotFoundException {
+        if (opts != null && opts.containsKey(EXTRA_THUMBNAIL_SIZE)) {
+            final Point sizeHint = opts.getParcelable(EXTRA_THUMBNAIL_SIZE);
+            return openDocumentThumbnail(getDocumentId(uri), sizeHint, signal);
+        } else {
+            return super.openTypedAssetFile(uri, mimeTypeFilter, opts, signal);
+        }
+    }
+}
diff --git a/core/java/android/provider/DrmStore.java b/core/java/android/provider/DrmStore.java
deleted file mode 100644
index 34f2f0d..0000000
--- a/core/java/android/provider/DrmStore.java
+++ /dev/null
@@ -1,211 +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.provider;
-
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.drm.mobile1.DrmRawContent;
-import android.drm.mobile1.DrmRights;
-import android.drm.mobile1.DrmRightsManager;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.net.Uri;
-import android.util.Log;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * The DRM provider contains forward locked DRM content.
- *
- * @hide
- */
-public final class DrmStore
-{
-    private static final String TAG = "DrmStore";
-
-    public static final String AUTHORITY = "drm";
-
-    /**
-     * This is in the Manifest class of the drm provider, but that isn't visible
-     * in the framework.
-     */
-    private static final String ACCESS_DRM_PERMISSION = "android.permission.ACCESS_DRM";
-
-    /**
-     * Fields for DRM database
-     */
-
-    public interface Columns extends BaseColumns {
-        /**
-         * The data stream for the file
-         * <P>Type: DATA STREAM</P>
-         */
-        public static final String DATA = "_data";
-
-        /**
-         * The size of the file in bytes
-         * <P>Type: INTEGER (long)</P>
-         */
-        public static final String SIZE = "_size";
-
-        /**
-         * The title of the file content
-         * <P>Type: TEXT</P>
-         */
-        public static final String TITLE = "title";
-
-        /**
-         * The MIME type of the file
-         * <P>Type: TEXT</P>
-         */
-        public static final String MIME_TYPE = "mime_type";
-
-    }
-
-    public interface Images extends Columns {
-
-        public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/images");
-    }
-
-    public interface Audio extends Columns {
-
-        public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/audio");
-    }
-
-    /**
-     * Utility function for inserting a file into the DRM content provider.
-     *
-     * @param cr The content resolver to use
-     * @param file The file to insert
-     * @param title The title for the content (or null)
-     * @return uri to the DRM record or null
-     */
-    public static final Intent addDrmFile(ContentResolver cr, File file, String title) {
-        FileInputStream fis = null;
-        Intent result = null;
-
-        try {
-            fis = new FileInputStream(file);
-            if (title == null) {
-                title = file.getName();
-                int lastDot = title.lastIndexOf('.');
-                if (lastDot > 0) {
-                    title = title.substring(0, lastDot);
-                }
-            }
-            result = addDrmFile(cr, fis, title);
-        } catch (Exception e) {
-            Log.e(TAG, "pushing file failed", e);
-        } finally {
-            try {
-                if (fis != null)
-                    fis.close();
-            } catch (IOException e) {
-                Log.e(TAG, "IOException in DrmStore.addDrmFile()", e);
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * Utility function for inserting a file stream into the DRM content provider.
-     *
-     * @param cr The content resolver to use
-     * @param fis The FileInputStream to insert
-     * @param title The title for the content (or null)
-     * @return uri to the DRM record or null
-     */
-    public static final Intent addDrmFile(ContentResolver cr, FileInputStream fis, String title) {
-        OutputStream os = null;
-        Intent result = null;
-
-        try {
-            DrmRawContent content = new DrmRawContent(fis, (int) fis.available(),
-                    DrmRawContent.DRM_MIMETYPE_MESSAGE_STRING);
-            String mimeType = content.getContentType();
-            long size = fis.getChannel().size();
-
-            DrmRightsManager manager = manager = DrmRightsManager.getInstance();
-            DrmRights rights = manager.queryRights(content);
-            InputStream stream = content.getContentInputStream(rights);
-
-            Uri contentUri = null;
-            if (mimeType.startsWith("audio/")) {
-                contentUri = DrmStore.Audio.CONTENT_URI;
-            } else if (mimeType.startsWith("image/")) {
-                contentUri = DrmStore.Images.CONTENT_URI;
-            } else {
-                Log.w(TAG, "unsupported mime type " + mimeType);
-            }
-
-            if (contentUri != null) {
-                ContentValues values = new ContentValues(3);
-                values.put(DrmStore.Columns.TITLE, title);
-                values.put(DrmStore.Columns.SIZE, size);
-                values.put(DrmStore.Columns.MIME_TYPE, mimeType);
-
-                Uri uri = cr.insert(contentUri, values);
-                if (uri != null) {
-                    os = cr.openOutputStream(uri);
-
-                    byte[] buffer = new byte[1000];
-                    int count;
-
-                    while ((count = stream.read(buffer)) != -1) {
-                        os.write(buffer, 0, count);
-                    }
-                    result = new Intent();
-                    result.setDataAndType(uri, mimeType);
-
-                }
-            }
-        } catch (Exception e) {
-            Log.e(TAG, "pushing file failed", e);
-        } finally {
-            try {
-                if (fis != null)
-                    fis.close();
-                if (os != null)
-                    os.close();
-            } catch (IOException e) {
-                Log.e(TAG, "IOException in DrmStore.addDrmFile()", e);
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * Utility function to enforce any permissions required to access DRM
-     * content.
-     *
-     * @param context A context used for checking calling permission.
-     */
-    public static void enforceAccessDrmPermission(Context context) {
-        if (context.checkCallingOrSelfPermission(ACCESS_DRM_PERMISSION) !=
-                PackageManager.PERMISSION_GRANTED) {
-            throw new SecurityException("Requires DRM permission");
-        }
-    }
-
-}
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index cb6300f..ad6839b 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -19,8 +19,8 @@
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.content.ContentResolver;
-import android.content.ContentValues;
 import android.content.ContentUris;
+import android.content.ContentValues;
 import android.content.Context;
 import android.database.Cursor;
 import android.database.DatabaseUtils;
@@ -532,7 +532,8 @@
         private static final Object sThumbBufLock = new Object();
         private static byte[] sThumbBuf;
 
-        private static Bitmap getMiniThumbFromFile(Cursor c, Uri baseUri, ContentResolver cr, BitmapFactory.Options options) {
+        private static Bitmap getMiniThumbFromFile(
+                Cursor c, Uri baseUri, ContentResolver cr, BitmapFactory.Options options) {
             Bitmap bitmap = null;
             Uri thumbUri = null;
             try {
@@ -577,6 +578,7 @@
                 if (c != null) c.close();
             }
         }
+
         /**
          * This method ensure thumbnails associated with origId are generated and decode the byte
          * stream from database (MICRO_KIND) or file (MINI_KIND).
diff --git a/core/java/android/provider/OpenableColumns.java b/core/java/android/provider/OpenableColumns.java
index f548bae..faf96b7 100644
--- a/core/java/android/provider/OpenableColumns.java
+++ b/core/java/android/provider/OpenableColumns.java
@@ -16,11 +16,17 @@
 
 package android.provider;
 
+import android.content.ContentResolver;
+import android.content.Intent;
+
 /**
- * These are standard columns for openable URIs. (See
- * {@link android.content.Intent#CATEGORY_OPENABLE}.) If possible providers that have openable URIs
- * should support these columns. To find the content type of a URI use
- * {@link android.content.ContentResolver#getType(android.net.Uri)} as normal.
+ * These are standard columns for openable URIs. Providers that serve openable
+ * URIs <em>must</em> support at least these columns when queried.
+ * <p>
+ * To find the content type of a URI, use
+ * {@link ContentResolver#getType(android.net.Uri)}.
+ *
+ * @see Intent#CATEGORY_OPENABLE
  */
 public interface OpenableColumns {
 
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 5e1f27e..c1c826c 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -33,6 +33,7 @@
 import android.content.res.Resources;
 import android.database.Cursor;
 import android.database.SQLException;
+import android.location.LocationManager;
 import android.net.ConnectivityManager;
 import android.net.Uri;
 import android.net.wifi.WifiManager;
@@ -159,6 +160,38 @@
             "android.settings.SECURITY_SETTINGS";
 
     /**
+     * Activity Action: Show trusted credentials settings, opening to the user tab,
+     * to allow management of installed credentials.
+     * <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_TRUSTED_CREDENTIALS_USER =
+            "com.android.settings.TRUSTED_CREDENTIALS_USER";
+
+    /**
+     * Activity Action: Show dialog explaining that an installed CA cert may enable
+     * monitoring of encrypted network traffic.
+     * <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_MONITORING_CERT_INFO =
+            "com.android.settings.MONITORING_CERT_INFO";
+
+    /**
      * Activity Action: Show settings to allow configuration of privacy options.
      * <p>
      * In some cases, a matching Activity may not exist, so ensure you
@@ -342,8 +375,9 @@
     /**
      * Activity Action: Show settings to manage the user input dictionary.
      * <p>
-     * In some cases, a matching Activity may not exist, so ensure you
-     * safeguard against this.
+     * Starting with {@link android.os.Build.VERSION_CODES#KITKAT},
+     * it is guaranteed there will always be an appropriate implementation for this Intent action.
+     * In prior releases of the platform this was optional, so ensure you safeguard against it.
      * <p>
      * Input: Nothing.
      * <p>
@@ -642,6 +676,23 @@
         "android.settings.NFCSHARING_SETTINGS";
 
     /**
+     * Activity Action: Show NFC Tap & Pay settings
+     * <p>
+     * This shows UI that allows the user to configure Tap&Pay
+     * settings.
+     * <p>
+     * In some cases, a matching Activity may not exist, so ensure you
+     * safeguard against this.
+     * <p>
+     * Input: Nothing.
+     * <p>
+     * Output: Nothing
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_NFC_PAYMENT_SETTINGS =
+        "android.settings.NFC_PAYMENT_SETTINGS";
+
+    /**
      * Activity Action: Show Daydream settings.
      * <p>
      * In some cases, a matching Activity may not exist, so ensure you
@@ -671,6 +722,33 @@
     public static final String ACTION_NOTIFICATION_LISTENER_SETTINGS
             = "android.settings.NOTIFICATION_LISTENER_SETTINGS";
 
+    /**
+     * Activity Action: Show settings for video captioning.
+     * <p>
+     * In some cases, a matching Activity may not exist, so ensure you safeguard
+     * against this.
+     * <p>
+     * Input: Nothing.
+     * <p>
+     * Output: Nothing.
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_CAPTIONING_SETTINGS = "android.settings.CAPTIONING_SETTINGS";
+
+    /**
+     * Activity Action: Show the top level print settings.
+     * <p>
+     * In some cases, a matching Activity may not exist, so ensure you
+     * safeguard against this.
+     * <p>
+     * Input: Nothing.
+     * <p>
+     * Output: Nothing.
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_PRINT_SETTINGS =
+            "android.settings.ACTION_PRINT_SETTINGS";
+
     // End of Intent actions for Settings
 
     /**
@@ -736,6 +814,10 @@
     private static final String TAG = "Settings";
     private static final boolean LOCAL_LOGV = false;
 
+    // Lock ensures that when enabling/disabling the master location switch, we don't end up
+    // with a partial enable/disable state in multi-threaded situations.
+    private static final Object mLocationSettingsLock = new Object();
+
     public static class SettingNotFoundException extends AndroidException {
         public SettingNotFoundException(String msg) {
             super(msg);
@@ -1011,6 +1093,14 @@
             MOVED_TO_GLOBAL.add(Settings.Global.WAIT_FOR_DEBUGGER);
             MOVED_TO_GLOBAL.add(Settings.Global.SHOW_PROCESSES);
             MOVED_TO_GLOBAL.add(Settings.Global.ALWAYS_FINISH_ACTIVITIES);
+            MOVED_TO_GLOBAL.add(Settings.Global.TZINFO_UPDATE_CONTENT_URL);
+            MOVED_TO_GLOBAL.add(Settings.Global.TZINFO_UPDATE_METADATA_URL);
+            MOVED_TO_GLOBAL.add(Settings.Global.SELINUX_UPDATE_CONTENT_URL);
+            MOVED_TO_GLOBAL.add(Settings.Global.SELINUX_UPDATE_METADATA_URL);
+            MOVED_TO_GLOBAL.add(Settings.Global.SMS_SHORT_CODES_UPDATE_CONTENT_URL);
+            MOVED_TO_GLOBAL.add(Settings.Global.SMS_SHORT_CODES_UPDATE_METADATA_URL);
+            MOVED_TO_GLOBAL.add(Settings.Global.CERT_PIN_UPDATE_CONTENT_URL);
+            MOVED_TO_GLOBAL.add(Settings.Global.CERT_PIN_UPDATE_METADATA_URL);
         }
 
         /** @hide */
@@ -2381,7 +2471,9 @@
             SIP_CALL_OPTIONS,
             SIP_RECEIVE_CALLS,
             POINTER_SPEED,
-            VIBRATE_WHEN_RINGING
+            VIBRATE_WHEN_RINGING,
+            RINGTONE,
+            NOTIFICATION_SOUND
         };
 
         // Settings moved to Settings.Secure
@@ -2864,6 +2956,11 @@
 
         /** @hide */
         public static int getIntForUser(ContentResolver cr, String name, int def, int userHandle) {
+            if (LOCATION_MODE.equals(name)) {
+                // HACK ALERT: temporary hack to work around b/10491283.
+                // TODO: once b/10491283 fixed, remove this hack
+                return getLocationModeForUser(cr, userHandle);
+            }
             String v = getStringForUser(cr, name, userHandle);
             try {
                 return v != null ? Integer.parseInt(v) : def;
@@ -2898,6 +2995,11 @@
         /** @hide */
         public static int getIntForUser(ContentResolver cr, String name, int userHandle)
                 throws SettingNotFoundException {
+            if (LOCATION_MODE.equals(name)) {
+                // HACK ALERT: temporary hack to work around b/10491283.
+                // TODO: once b/10491283 fixed, remove this hack
+                return getLocationModeForUser(cr, userHandle);
+            }
             String v = getStringForUser(cr, name, userHandle);
             try {
                 return Integer.parseInt(v);
@@ -2926,6 +3028,11 @@
         /** @hide */
         public static boolean putIntForUser(ContentResolver cr, String name, int value,
                 int userHandle) {
+            if (LOCATION_MODE.equals(name)) {
+                // HACK ALERT: temporary hack to work around b/10491283.
+                // TODO: once b/10491283 fixed, remove this hack
+                return setLocationModeForUser(cr, value, userHandle);
+            }
             return putStringForUser(cr, name, Integer.toString(value), userHandle);
         }
 
@@ -3184,6 +3291,13 @@
                 "input_method_selector_visibility";
 
         /**
+         * bluetooth HCI snoop log configuration
+         * @hide
+         */
+        public static final String BLUETOOTH_HCI_LOG =
+                "bluetooth_hci_log";
+
+        /**
          * @deprecated Use {@link android.provider.Settings.Global#DEVICE_PROVISIONED} instead
          */
         @Deprecated
@@ -3227,10 +3341,43 @@
 
         /**
          * Comma-separated list of location providers that activities may access.
+         *
+         * @deprecated use {@link #LOCATION_MODE}
          */
+        @Deprecated
         public static final String LOCATION_PROVIDERS_ALLOWED = "location_providers_allowed";
 
         /**
+         * The degree of location access enabled by the user.
+         * <p/>
+         * When used with {@link #putInt(ContentResolver, String, int)}, must be one of {@link
+         * #LOCATION_MODE_HIGH_ACCURACY}, {@link #LOCATION_MODE_SENSORS_ONLY}, {@link
+         * #LOCATION_MODE_BATTERY_SAVING}, or {@link #LOCATION_MODE_OFF}. When used with {@link
+         * #getInt(ContentResolver, String)}, the caller must gracefully handle additional location
+         * modes that might be added in the future.
+         */
+        public static final String LOCATION_MODE = "location_mode";
+
+        /**
+         * Location access disabled.
+         */
+        public static final int LOCATION_MODE_OFF = 0;
+        /**
+         * Network Location Provider disabled, but GPS and other sensors enabled.
+         */
+        public static final int LOCATION_MODE_SENSORS_ONLY = 1;
+        /**
+         * Reduced power usage, such as limiting the number of GPS updates per hour. Requests
+         * with {@link android.location.Criteria#POWER_HIGH} may be downgraded to
+         * {@link android.location.Criteria#POWER_MEDIUM}.
+         */
+        public static final int LOCATION_MODE_BATTERY_SAVING = 2;
+        /**
+         * Best-effort location computation allowed.
+         */
+        public static final int LOCATION_MODE_HIGH_ACCURACY = 3;
+
+        /**
          * A flag containing settings used for biometric weak
          * @hide
          */
@@ -3494,12 +3641,139 @@
                 "accessibility_display_magnification_auto_update";
 
         /**
+         * Setting that specifies whether timed text (captions) should be
+         * displayed in video content. Text display properties are controlled by
+         * the following settings:
+         * <ul>
+         * <li>{@link #ACCESSIBILITY_CAPTIONING_LOCALE}
+         * <li>{@link #ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR}
+         * <li>{@link #ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR}
+         * <li>{@link #ACCESSIBILITY_CAPTIONING_EDGE_COLOR}
+         * <li>{@link #ACCESSIBILITY_CAPTIONING_EDGE_TYPE}
+         * <li>{@link #ACCESSIBILITY_CAPTIONING_TYPEFACE}
+         * <li>{@link #ACCESSIBILITY_CAPTIONING_FONT_SCALE}
+         * </ul>
+         *
+         * @hide
+         */
+        public static final String ACCESSIBILITY_CAPTIONING_ENABLED =
+                "accessibility_captioning_enabled";
+
+        /**
+         * Setting that specifies the language for captions as a locale string,
+         * e.g. en_US.
+         *
+         * @see java.util.Locale#toString
+         * @hide
+         */
+        public static final String ACCESSIBILITY_CAPTIONING_LOCALE =
+                "accessibility_captioning_locale";
+
+        /**
+         * Integer property that specifies the preset style for captions, one
+         * of:
+         * <ul>
+         * <li>{@link android.view.accessibility.CaptioningManager.CaptionStyle#PRESET_CUSTOM}
+         * <li>a valid index of {@link android.view.accessibility.CaptioningManager.CaptionStyle#PRESETS}
+         * </ul>
+         *
+         * @see java.util.Locale#toString
+         * @hide
+         */
+        public static final String ACCESSIBILITY_CAPTIONING_PRESET =
+                "accessibility_captioning_preset";
+
+        /**
+         * Integer property that specifes the background color for captions as a
+         * packed 32-bit color.
+         *
+         * @see android.graphics.Color#argb
+         * @hide
+         */
+        public static final String ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR =
+                "accessibility_captioning_background_color";
+
+        /**
+         * Integer property that specifes the foreground color for captions as a
+         * packed 32-bit color.
+         *
+         * @see android.graphics.Color#argb
+         * @hide
+         */
+        public static final String ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR =
+                "accessibility_captioning_foreground_color";
+
+        /**
+         * Integer property that specifes the edge type for captions, one of:
+         * <ul>
+         * <li>{@link android.view.accessibility.CaptioningManager.CaptionStyle#EDGE_TYPE_NONE}
+         * <li>{@link android.view.accessibility.CaptioningManager.CaptionStyle#EDGE_TYPE_OUTLINE}
+         * <li>{@link android.view.accessibility.CaptioningManager.CaptionStyle#EDGE_TYPE_DROP_SHADOW}
+         * </ul>
+         *
+         * @see #ACCESSIBILITY_CAPTIONING_EDGE_COLOR
+         * @hide
+         */
+        public static final String ACCESSIBILITY_CAPTIONING_EDGE_TYPE =
+                "accessibility_captioning_edge_type";
+
+        /**
+         * Integer property that specifes the edge color for captions as a
+         * packed 32-bit color.
+         *
+         * @see #ACCESSIBILITY_CAPTIONING_EDGE_TYPE
+         * @see android.graphics.Color#argb
+         * @hide
+         */
+        public static final String ACCESSIBILITY_CAPTIONING_EDGE_COLOR =
+                "accessibility_captioning_edge_color";
+
+        /**
+         * String property that specifies the typeface for captions, one of:
+         * <ul>
+         * <li>DEFAULT
+         * <li>MONOSPACE
+         * <li>SANS_SERIF
+         * <li>SERIF
+         * </ul>
+         *
+         * @see android.graphics.Typeface
+         * @hide
+         */
+        public static final String ACCESSIBILITY_CAPTIONING_TYPEFACE =
+                "accessibility_captioning_typeface";
+
+        /**
+         * Floating point property that specifies font scaling for captions.
+         *
+         * @hide
+         */
+        public static final String ACCESSIBILITY_CAPTIONING_FONT_SCALE =
+                "accessibility_captioning_font_scale";
+
+        /**
          * The timout for considering a press to be a long press in milliseconds.
          * @hide
          */
         public static final String LONG_PRESS_TIMEOUT = "long_press_timeout";
 
         /**
+         * List of the enabled print services.
+         * @hide
+         */
+        public static final String ENABLED_PRINT_SERVICES =
+            "enabled_print_services";
+
+        /**
+         * List of the system print services we enabled on first boot. On
+         * first boot we enable all system, i.e. bundled print services,
+         * once, so they work out-of-the-box.
+         * @hide
+         */
+        public static final String ENABLED_ON_FIRST_BOOT_SYSTEM_PRINT_SERVICES =
+            "enabled_on_first_boot_system_print_services";
+
+        /**
          * Setting to always use the default text-to-speech settings regardless
          * of the application settings.
          * 1 = override application settings,
@@ -3968,6 +4242,14 @@
          */
         public static final String VOICE_RECOGNITION_SERVICE = "voice_recognition_service";
 
+        /**
+         * Stores whether an user has consented to have apps verified through PAM.
+         * The value is boolean (1 or 0).
+         *
+         * @hide
+         */
+        public static final String PACKAGE_VERIFIER_USER_CONSENT =
+            "package_verifier_user_consent";
 
         /**
          * The {@link ComponentName} string of the selected spell checker service which is
@@ -4067,6 +4349,12 @@
         public static final String SCREENSAVER_DEFAULT_COMPONENT = "screensaver_default_component";
 
         /**
+         * The default NFC payment component
+         * @hide
+         */
+        public static final String NFC_PAYMENT_DEFAULT_COMPONENT = "nfc_payment_default_component";
+
+        /**
          * Name of a package that the current user has explicitly allowed to see all of that
          * user's notifications.
          *
@@ -4074,12 +4362,8 @@
          */
         public static final String ENABLED_NOTIFICATION_LISTENERS = "enabled_notification_listeners";
 
-        /**
-         * Whether or not to enable the dial pad autocomplete functionality.
-         *
-         * @hide
-         */
-        public static final String DIALPAD_AUTOCOMPLETE = "dialpad_autocomplete";
+        /** @hide */
+        public static final String BAR_SERVICE_COMPONENT = "bar_service_component";
 
         /**
          * This are the settings to be backed up.
@@ -4106,6 +4390,14 @@
             TOUCH_EXPLORATION_ENABLED,
             ACCESSIBILITY_ENABLED,
             ACCESSIBILITY_SPEAK_PASSWORD,
+            ACCESSIBILITY_CAPTIONING_ENABLED,
+            ACCESSIBILITY_CAPTIONING_LOCALE,
+            ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR,
+            ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR,
+            ACCESSIBILITY_CAPTIONING_EDGE_TYPE,
+            ACCESSIBILITY_CAPTIONING_EDGE_COLOR,
+            ACCESSIBILITY_CAPTIONING_TYPEFACE,
+            ACCESSIBILITY_CAPTIONING_FONT_SCALE,
             TTS_USE_DEFAULTS,
             TTS_DEFAULT_RATE,
             TTS_DEFAULT_PITCH,
@@ -4121,16 +4413,20 @@
             MOUNT_UMS_AUTOSTART,
             MOUNT_UMS_PROMPT,
             MOUNT_UMS_NOTIFY_ENABLED,
-            UI_NIGHT_MODE,
-            DIALPAD_AUTOCOMPLETE
+            UI_NIGHT_MODE
         };
 
         /**
          * Helper method for determining if a location provider is enabled.
+         *
          * @param cr the content resolver to use
          * @param provider the location provider to query
          * @return true if the provider is enabled
+         *
+         * @deprecated use {@link #LOCATION_MODE} or
+         *             {@link LocationManager#isProviderEnabled(String)}
          */
+        @Deprecated
         public static final boolean isLocationProviderEnabled(ContentResolver cr, String provider) {
             return isLocationProviderEnabledForUser(cr, provider, UserHandle.myUserId());
         }
@@ -4141,8 +4437,11 @@
          * @param provider the location provider to query
          * @param userId the userId to query
          * @return true if the provider is enabled
+         * @deprecated use {@link #LOCATION_MODE} or
+         *             {@link LocationManager#isProviderEnabled(String)}
          * @hide
          */
+        @Deprecated
         public static final boolean isLocationProviderEnabledForUser(ContentResolver cr, String provider, int userId) {
             String allowedProviders = Settings.Secure.getStringForUser(cr,
                     LOCATION_PROVIDERS_ALLOWED, userId);
@@ -4154,7 +4453,9 @@
          * @param cr the content resolver to use
          * @param provider the location provider to enable or disable
          * @param enabled true if the provider should be enabled
+         * @deprecated use {@link #putInt(ContentResolver, String, int)} and {@link #LOCATION_MODE}
          */
+        @Deprecated
         public static final void setLocationProviderEnabled(ContentResolver cr,
                 String provider, boolean enabled) {
             setLocationProviderEnabledForUser(cr, provider, enabled, UserHandle.myUserId());
@@ -4162,24 +4463,99 @@
 
         /**
          * Thread-safe method for enabling or disabling a single location provider.
+         *
          * @param cr the content resolver to use
          * @param provider the location provider to enable or disable
          * @param enabled true if the provider should be enabled
          * @param userId the userId for which to enable/disable providers
+         * @return true if the value was set, false on database errors
+         * @deprecated use {@link #putIntForUser(ContentResolver, String, int, int)} and
+         *             {@link #LOCATION_MODE}
          * @hide
          */
-        public static final void setLocationProviderEnabledForUser(ContentResolver cr,
+        @Deprecated
+        public static final boolean setLocationProviderEnabledForUser(ContentResolver cr,
                 String provider, boolean enabled, int userId) {
-            // to ensure thread safety, we write the provider name with a '+' or '-'
-            // and let the SettingsProvider handle it rather than reading and modifying
-            // the list of enabled providers.
-            if (enabled) {
-                provider = "+" + provider;
-            } else {
-                provider = "-" + provider;
+            synchronized (mLocationSettingsLock) {
+                // to ensure thread safety, we write the provider name with a '+' or '-'
+                // and let the SettingsProvider handle it rather than reading and modifying
+                // the list of enabled providers.
+                if (enabled) {
+                    provider = "+" + provider;
+                } else {
+                    provider = "-" + provider;
+                }
+                return putStringForUser(cr, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, provider,
+                        userId);
             }
-            putStringForUser(cr, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, provider,
-                    userId);
+        }
+
+        /**
+         * Thread-safe method for setting the location mode to one of
+         * {@link #LOCATION_MODE_HIGH_ACCURACY}, {@link #LOCATION_MODE_SENSORS_ONLY},
+         * {@link #LOCATION_MODE_BATTERY_SAVING}, or {@link #LOCATION_MODE_OFF}.
+         *
+         * @param cr the content resolver to use
+         * @param mode such as {@link #LOCATION_MODE_HIGH_ACCURACY}
+         * @param userId the userId for which to change mode
+         * @return true if the value was set, false on database errors
+         *
+         * @throws IllegalArgumentException if mode is not one of the supported values
+         */
+        private static final boolean setLocationModeForUser(ContentResolver cr, int mode,
+                int userId) {
+            synchronized (mLocationSettingsLock) {
+                boolean gps = false;
+                boolean network = false;
+                switch (mode) {
+                    case LOCATION_MODE_OFF:
+                        break;
+                    case LOCATION_MODE_SENSORS_ONLY:
+                        gps = true;
+                        break;
+                    case LOCATION_MODE_BATTERY_SAVING:
+                        network = true;
+                        break;
+                    case LOCATION_MODE_HIGH_ACCURACY:
+                        gps = true;
+                        network = true;
+                        break;
+                    default:
+                        throw new IllegalArgumentException("Invalid location mode: " + mode);
+                }
+                boolean gpsSuccess = Settings.Secure.setLocationProviderEnabledForUser(
+                        cr, LocationManager.GPS_PROVIDER, gps, userId);
+                boolean nlpSuccess = Settings.Secure.setLocationProviderEnabledForUser(
+                        cr, LocationManager.NETWORK_PROVIDER, network, userId);
+                return gpsSuccess && nlpSuccess;
+            }
+        }
+
+        /**
+         * Thread-safe method for reading the location mode, returns one of
+         * {@link #LOCATION_MODE_HIGH_ACCURACY}, {@link #LOCATION_MODE_SENSORS_ONLY},
+         * {@link #LOCATION_MODE_BATTERY_SAVING}, or {@link #LOCATION_MODE_OFF}.
+         *
+         * @param cr the content resolver to use
+         * @param userId the userId for which to read the mode
+         * @return the location mode
+         */
+        private static final int getLocationModeForUser(ContentResolver cr, int userId) {
+            synchronized (mLocationSettingsLock) {
+                boolean gpsEnabled = Settings.Secure.isLocationProviderEnabledForUser(
+                        cr, LocationManager.GPS_PROVIDER, userId);
+                boolean networkEnabled = Settings.Secure.isLocationProviderEnabledForUser(
+                        cr, LocationManager.NETWORK_PROVIDER, userId);
+                if (gpsEnabled && networkEnabled) {
+                    return LOCATION_MODE_HIGH_ACCURACY;
+                } else if (gpsEnabled) {
+                    return LOCATION_MODE_SENSORS_ONLY;
+                } else if (networkEnabled) {
+                    return LOCATION_MODE_BATTERY_SAVING;
+                } else {
+                    return LOCATION_MODE_OFF;
+                }
+            }
         }
     }
 
@@ -4776,6 +5152,29 @@
        public static final String WIFI_DISPLAY_ON = "wifi_display_on";
 
        /**
+        * Whether Wifi display certification mode is enabled/disabled
+        * 0=disabled. 1=enabled.
+        * @hide
+        */
+       public static final String WIFI_DISPLAY_CERTIFICATION_ON =
+               "wifi_display_certification_on";
+
+       /**
+        * WPS Configuration method used by Wifi display, this setting only
+        * takes effect when WIFI_DISPLAY_CERTIFICATION_ON is 1 (enabled).
+        *
+        * Possible values are:
+        *
+        * WpsInfo.INVALID: use default WPS method chosen by framework
+        * WpsInfo.PBC    : use Push button
+        * WpsInfo.KEYPAD : use Keypad
+        * WpsInfo.DISPLAY: use Display
+        * @hide
+        */
+       public static final String WIFI_DISPLAY_WPS_CONFIG =
+           "wifi_display_wps_config";
+
+       /**
         * Whether to notify the user of open networks.
         * <p>
         * If not connected and the scan results have an open network, we will
@@ -5131,6 +5530,25 @@
          */
         public static final String CONNECTIVITY_CHANGE_DELAY = "connectivity_change_delay";
 
+
+        /**
+         * Network sampling interval, in seconds. We'll generate link information
+         * about bytes/packets sent and error rates based on data sampled in this interval
+         *
+         * @hide
+         */
+
+        public static final String CONNECTIVITY_SAMPLING_INTERVAL_IN_SECONDS =
+                "connectivity_sampling_interval_in_seconds";
+
+        /**
+         * The series of successively longer delays used in retrying to download PAC file.
+         * Last delay is used between successful PAC downloads.
+         *
+         * @hide
+         */
+        public static final String PAC_CHANGE_DELAY = "pac_change_delay";
+
         /**
          * Setting to turn off captive portal detection. Feature is enabled by
          * default and the setting needs to be set to 0 to disable it.
@@ -5226,6 +5644,13 @@
                 GLOBAL_HTTP_PROXY_EXCLUSION_LIST = "global_http_proxy_exclusion_list";
 
         /**
+         * The location PAC File for the proxy.
+         * @hide
+         */
+        public static final String
+                GLOBAL_HTTP_PROXY_PAC = "global_proxy_pac_url";
+
+        /**
          * Enables the UI setting to allow the user to specify the global HTTP
          * proxy and associated exclusion list.
          *
@@ -5249,6 +5674,9 @@
         /** {@hide} */
         public static final String
                 BLUETOOTH_INPUT_DEVICE_PRIORITY_PREFIX = "bluetooth_input_device_priority_";
+        /** {@hide} */
+        public static final String
+                BLUETOOTH_MAP_PRIORITY_PREFIX = "bluetooth_map_priority_";
 
         /**
          * Get the key that retrieves a bluetooth headset's priority.
@@ -5275,6 +5703,13 @@
         }
 
         /**
+         * Get the key that retrieves a bluetooth map priority.
+         * @hide
+         */
+        public static final String getBluetoothMapPriorityKey(String address) {
+            return BLUETOOTH_MAP_PRIORITY_PREFIX + address.toUpperCase(Locale.ROOT);
+        }
+        /**
          * Scaling factor for normal window animations. Setting to 0 will
          * disable window animations.
          */
@@ -5449,6 +5884,12 @@
         public static final String SELINUX_STATUS = "selinux_status";
 
         /**
+         * Developer setting to force RTL layout.
+         * @hide
+         */
+        public static final String DEVELOPMENT_FORCE_RTL = "debug.force_rtl";
+
+        /**
          * Settings to backup. This is here so that it's in the same place as the settings
          * keys and easy to update.
          *
diff --git a/core/java/android/security/IKeystoreService.java b/core/java/android/security/IKeystoreService.java
index 3d75dc8..f8bf45b 100644
--- a/core/java/android/security/IKeystoreService.java
+++ b/core/java/android/security/IKeystoreService.java
@@ -244,7 +244,8 @@
                 return _result;
             }
 
-            public int generate(String name, int uid, int flags) throws RemoteException {
+            public int generate(String name, int uid, int keyType, int keySize, int flags,
+                    byte[][] args) throws RemoteException {
                 Parcel _data = Parcel.obtain();
                 Parcel _reply = Parcel.obtain();
                 int _result;
@@ -252,7 +253,17 @@
                     _data.writeInterfaceToken(DESCRIPTOR);
                     _data.writeString(name);
                     _data.writeInt(uid);
+                    _data.writeInt(keyType);
+                    _data.writeInt(keySize);
                     _data.writeInt(flags);
+                    if (args == null) {
+                        _data.writeInt(0);
+                    } else {
+                        _data.writeInt(args.length);
+                        for (int i = 0; i < args.length; i++) {
+                            _data.writeByteArray(args[i]);
+                        }
+                    }
                     mRemote.transact(Stub.TRANSACTION_generate, _data, _reply, 0);
                     _reply.readException();
                     _result = _reply.readInt();
@@ -433,12 +444,13 @@
             }
 
             @Override
-            public int is_hardware_backed() throws RemoteException {
+            public int is_hardware_backed(String keyType) throws RemoteException {
                 Parcel _data = Parcel.obtain();
                 Parcel _reply = Parcel.obtain();
                 int _result;
                 try {
                     _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeString(keyType);
                     mRemote.transact(Stub.TRANSACTION_is_hardware_backed, _data, _reply, 0);
                     _reply.readException();
                     _result = _reply.readInt();
@@ -560,7 +572,8 @@
 
     public int zero() throws RemoteException;
 
-    public int generate(String name, int uid, int flags) throws RemoteException;
+    public int generate(String name, int uid, int keyType, int keySize, int flags, byte[][] args)
+            throws RemoteException;
 
     public int import_key(String name, byte[] data, int uid, int flags) throws RemoteException;
 
@@ -581,7 +594,7 @@
     public int duplicate(String srcKey, int srcUid, String destKey, int destUid)
             throws RemoteException;
 
-    public int is_hardware_backed() throws RemoteException;
+    public int is_hardware_backed(String string) throws RemoteException;
 
     public int clear_uid(long uid) throws RemoteException;
 }
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index bfea9ca..2e0e59b 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -164,11 +164,19 @@
     private class INotificationListenerWrapper extends INotificationListener.Stub {
         @Override
         public void onNotificationPosted(StatusBarNotification sbn) {
-            NotificationListenerService.this.onNotificationPosted(sbn);
+            try {
+                NotificationListenerService.this.onNotificationPosted(sbn);
+            } catch (Throwable t) {
+                Log.w(TAG, "Error running onNotificationPosted", t);
+            }
         }
         @Override
         public void onNotificationRemoved(StatusBarNotification sbn) {
-            NotificationListenerService.this.onNotificationRemoved(sbn);
+            try {
+                NotificationListenerService.this.onNotificationRemoved(sbn);
+            } catch (Throwable t) {
+                Log.w(TAG, "Error running onNotificationRemoved", t);
+            }
         }
     }
 }
diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java
index 19f8678..b5b9e14 100644
--- a/core/java/android/service/notification/StatusBarNotification.java
+++ b/core/java/android/service/notification/StatusBarNotification.java
@@ -33,23 +33,12 @@
     private final int uid;
     private final String basePkg;
     private final int initialPid;
-    // TODO: make this field private and move callers to an accessor that
-    // ensures sourceUser is applied.
-
     private final Notification notification;
     private final UserHandle user;
     private final long postTime;
 
     private final int score;
 
-    /** This is temporarily needed for the JB MR1 PDK.
-     * @hide */
-    @Deprecated
-    public StatusBarNotification(String pkg, int id, String tag, int uid, int initialPid, int score,
-            Notification notification) {
-        this(pkg, id, tag, uid, initialPid, score, notification, UserHandle.OWNER);
-    }
-
     /** @hide */
     public StatusBarNotification(String pkg, int id, String tag, int uid, int initialPid, int score,
             Notification notification, UserHandle user) {
diff --git a/core/java/android/speech/tts/SynthesisRequest.java b/core/java/android/speech/tts/SynthesisRequest.java
index 6398d3d..12a026b 100644
--- a/core/java/android/speech/tts/SynthesisRequest.java
+++ b/core/java/android/speech/tts/SynthesisRequest.java
@@ -30,7 +30,7 @@
  * </ul>
  *
  * Any additional parameters sent to the text to speech service are passed in
- * uninterpreted, see the @code{params} argument in {@link TextToSpeech#speak}
+ * uninterpreted, see the {@code params} argument in {@link TextToSpeech#speak}
  * and {@link TextToSpeech#synthesizeToFile}.
  */
 public final class SynthesisRequest {
@@ -41,6 +41,7 @@
     private String mVariant;
     private int mSpeechRate;
     private int mPitch;
+    private int mCallerUid;
 
     public SynthesisRequest(String text, Bundle params) {
         mText = text;
@@ -98,6 +99,13 @@
     }
 
     /**
+     * Gets the request caller Uid.
+     */
+    public int getCallerUid() {
+        return mCallerUid;
+    }
+
+    /**
      * Sets the locale for the request.
      */
     void setLanguage(String language, String country, String variant) {
@@ -119,4 +127,11 @@
     void setPitch(int pitch) {
         mPitch = pitch;
     }
+
+    /**
+     * Sets Caller Uid
+     */
+    void setCallerUid(int uid) {
+        mCallerUid = uid;
+    }
 }
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 578a86e..b808363 100644
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -561,7 +561,8 @@
      *            The context this instance is running in.
      * @param listener
      *            The {@link TextToSpeech.OnInitListener} that will be called when the
-     *            TextToSpeech engine has initialized.
+     *            TextToSpeech engine has initialized. In a case of a failure the listener
+     *            may be called immediately, before TextToSpeech instance is fully constructed.
      */
     public TextToSpeech(Context context, OnInitListener listener) {
         this(context, listener, null);
@@ -575,7 +576,8 @@
      *            The context this instance is running in.
      * @param listener
      *            The {@link TextToSpeech.OnInitListener} that will be called when the
-     *            TextToSpeech engine has initialized.
+     *            TextToSpeech engine has initialized. In a case of a failure the listener
+     *            may be called immediately, before TextToSpeech instance is fully constructed.
      * @param engine Package name of the TTS engine to use.
      */
     public TextToSpeech(Context context, OnInitListener listener, String engine) {
diff --git a/core/java/android/speech/tts/TextToSpeechService.java b/core/java/android/speech/tts/TextToSpeechService.java
index 703dcff..575855c 100644
--- a/core/java/android/speech/tts/TextToSpeechService.java
+++ b/core/java/android/speech/tts/TextToSpeechService.java
@@ -557,11 +557,13 @@
         // guarded by 'this'.
         private AbstractSynthesisCallback mSynthesisCallback;
         private final EventLogger mEventLogger;
+        private final int mCallerUid;
 
         public SynthesisSpeechItem(Object callerIdentity, int callerUid, int callerPid,
                 Bundle params, String text) {
             super(callerIdentity, callerUid, callerPid, params);
             mText = text;
+            mCallerUid = callerUid;
             mSynthesisRequest = new SynthesisRequest(mText, mParams);
             mDefaultLocale = getSettingsLocale();
             setRequestParams(mSynthesisRequest);
@@ -611,7 +613,7 @@
         private void setRequestParams(SynthesisRequest request) {
             request.setLanguage(getLanguage(), getCountry(), getVariant());
             request.setSpeechRate(getSpeechRate());
-
+            request.setCallerUid(mCallerUid);
             request.setPitch(getPitch());
         }
 
diff --git a/core/java/android/speech/tts/TtsEngines.java b/core/java/android/speech/tts/TtsEngines.java
index 2706bc7..5fbd22e 100644
--- a/core/java/android/speech/tts/TtsEngines.java
+++ b/core/java/android/speech/tts/TtsEngines.java
@@ -355,7 +355,18 @@
         return v1Locale;
     }
 
-    private String getDefaultLocale() {
+    /**
+     * Return the default device locale in form of 3 letter codes delimited by
+     * {@link #LOCALE_DELIMITER}:
+     * <ul>
+     *   <li> "ISO 639-2/T language code" if locale have no country entry</li>
+     *   <li> "ISO 639-2/T language code{@link #LOCALE_DELIMITER}ISO 3166 country code "
+     *     if locale have no variant entry</li>
+     *   <li> "ISO 639-2/T language code{@link #LOCALE_DELIMITER}ISO 3166 country code
+     *     {@link #LOCALE_DELIMITER} variant" if locale have variant entry</li>
+     * </ul>
+     */
+    public String getDefaultLocale() {
         final Locale locale = Locale.getDefault();
 
         // Note that the default locale might have an empty variant
diff --git a/core/java/android/text/AndroidBidi.java b/core/java/android/text/AndroidBidi.java
index eacd40d..b1c07f5 100644
--- a/core/java/android/text/AndroidBidi.java
+++ b/core/java/android/text/AndroidBidi.java
@@ -60,6 +60,9 @@
      */
     public static Directions directions(int dir, byte[] levels, int lstart,
             char[] chars, int cstart, int len) {
+        if (len == 0) {
+            return Layout.DIRS_ALL_LEFT_TO_RIGHT;
+        }
 
         int baseLevel = dir == Layout.DIR_LEFT_TO_RIGHT ? 0 : 1;
         int curLevel = levels[lstart];
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 1291279..e7d6fda 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -474,6 +474,8 @@
                 mLineCount < mMaximumVisibleLineCount) {
             // Log.e("text", "output last " + bufEnd);
 
+            measured.setPara(source, bufStart, bufEnd, textDir);
+
             paint.getFontMetricsInt(fm);
 
             v = out(source,
@@ -482,7 +484,7 @@
                     v,
                     spacingmult, spacingadd, null,
                     null, fm, false,
-                    needMultiply, null, DEFAULT_DIR, true, bufEnd,
+                    needMultiply, measured.mLevels, measured.mDir, measured.mEasy, bufEnd,
                     includepad, trackpad, null,
                     null, bufStart, ellipsize,
                     ellipsizedWidth, 0, paint, false);
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index e2035c2..596ca8c 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -19,6 +19,8 @@
 import android.content.res.Resources;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.SystemProperties;
+import android.provider.Settings;
 import android.text.style.AbsoluteSizeSpan;
 import android.text.style.AlignmentSpan;
 import android.text.style.BackgroundColorSpan;
@@ -1743,8 +1745,10 @@
                 return View.LAYOUT_DIRECTION_RTL;
             }
         }
-
-        return View.LAYOUT_DIRECTION_LTR;
+        // If forcing into RTL layout mode, return RTL as default, else LTR
+        return SystemProperties.getBoolean(Settings.Global.DEVELOPMENT_FORCE_RTL, false)
+                ? View.LAYOUT_DIRECTION_RTL
+                : View.LAYOUT_DIRECTION_LTR;
     }
 
     /**
diff --git a/core/java/android/text/format/DateUtils.java b/core/java/android/text/format/DateUtils.java
index cba350f..22675b4 100644
--- a/core/java/android/text/format/DateUtils.java
+++ b/core/java/android/text/format/DateUtils.java
@@ -815,7 +815,14 @@
      * @return the formatter with the formatted date/time range appended to the string buffer.
      */
     public static Formatter formatDateRange(Context context, Formatter formatter, long startMillis,
-            long endMillis, int flags, String timeZone) {
+                                            long endMillis, int flags, String timeZone) {
+        // If we're being asked to format a time without being explicitly told whether to use
+        // the 12- or 24-hour clock, icu4c will fall back to the locale's preferred 12/24 format,
+        // but we want to fall back to the user's preference.
+        if ((flags & (FORMAT_SHOW_TIME | FORMAT_12HOUR | FORMAT_24HOUR)) == FORMAT_SHOW_TIME) {
+            flags |= DateFormat.is24HourFormat(context) ? FORMAT_24HOUR : FORMAT_12HOUR;
+        }
+
         String range = DateIntervalFormat.formatDateRange(startMillis, endMillis, flags, timeZone);
         try {
             formatter.out().append(range);
diff --git a/core/java/android/text/method/ArrowKeyMovementMethod.java b/core/java/android/text/method/ArrowKeyMovementMethod.java
index 30bb447..ba6f1d4 100644
--- a/core/java/android/text/method/ArrowKeyMovementMethod.java
+++ b/core/java/android/text/method/ArrowKeyMovementMethod.java
@@ -56,7 +56,7 @@
                     if (event.getAction() == KeyEvent.ACTION_DOWN
                             && event.getRepeatCount() == 0
                             && MetaKeyKeyListener.getMetaState(buffer,
-                                        MetaKeyKeyListener.META_SELECTING) != 0) {
+                                        MetaKeyKeyListener.META_SELECTING, event) != 0) {
                         return widget.showContextMenu();
                     }
                 }
diff --git a/core/java/android/text/method/BaseKeyListener.java b/core/java/android/text/method/BaseKeyListener.java
index 4fede32..63607fa 100644
--- a/core/java/android/text/method/BaseKeyListener.java
+++ b/core/java/android/text/method/BaseKeyListener.java
@@ -75,7 +75,7 @@
         }
 
         // Alt+Backspace or Alt+ForwardDelete deletes the current line, if possible.
-        if (event.isAltPressed() || getMetaState(content, META_ALT_ON) == 1) {
+        if (getMetaState(content, META_ALT_ON, event) == 1) {
             if (deleteLine(view, content)) {
                 return true;
             }
diff --git a/core/java/android/text/method/BaseMovementMethod.java b/core/java/android/text/method/BaseMovementMethod.java
index 113a4be..155a2c4 100644
--- a/core/java/android/text/method/BaseMovementMethod.java
+++ b/core/java/android/text/method/BaseMovementMethod.java
@@ -135,7 +135,7 @@
      */
     protected int getMovementMetaState(Spannable buffer, KeyEvent event) {
         // We ignore locked modifiers and SHIFT.
-        int metaState = (event.getMetaState() | MetaKeyKeyListener.getMetaState(buffer))
+        int metaState = MetaKeyKeyListener.getMetaState(buffer, event)
                 & ~(MetaKeyKeyListener.META_ALT_LOCKED | MetaKeyKeyListener.META_SYM_LOCKED);
         return KeyEvent.normalizeMetaState(metaState) & ~KeyEvent.META_SHIFT_MASK;
     }
diff --git a/core/java/android/text/method/DialerKeyListener.java b/core/java/android/text/method/DialerKeyListener.java
index ce51fae..bb8b0de 100644
--- a/core/java/android/text/method/DialerKeyListener.java
+++ b/core/java/android/text/method/DialerKeyListener.java
@@ -53,7 +53,7 @@
      * from the KeyEvent.
      */
     protected int lookup(KeyEvent event, Spannable content) {
-        int meta = event.getMetaState() | getMetaState(content);
+        int meta = getMetaState(content, event);
         int number = event.getNumber();
 
         /*
diff --git a/core/java/android/text/method/LinkMovementMethod.java b/core/java/android/text/method/LinkMovementMethod.java
index aff233d..3855ff3 100644
--- a/core/java/android/text/method/LinkMovementMethod.java
+++ b/core/java/android/text/method/LinkMovementMethod.java
@@ -36,6 +36,11 @@
     private static final int DOWN = 3;
 
     @Override
+    public boolean canSelectArbitrarily() {
+        return true;
+    }
+
+    @Override
     protected boolean handleMovementKey(TextView widget, Spannable buffer, int keyCode,
             int movementMetaState, KeyEvent event) {
         switch (keyCode) {
diff --git a/core/java/android/text/method/MetaKeyKeyListener.java b/core/java/android/text/method/MetaKeyKeyListener.java
index 0a097f9..e9db5fd 100644
--- a/core/java/android/text/method/MetaKeyKeyListener.java
+++ b/core/java/android/text/method/MetaKeyKeyListener.java
@@ -135,6 +135,9 @@
     private static final Object SYM = new NoCopySpan.Concrete();
     private static final Object SELECTING = new NoCopySpan.Concrete();
 
+    private static final int PRESSED_RETURN_VALUE = 1;
+    private static final int LOCKED_RETURN_VALUE = 2;
+
     /**
      * Resets all meta state to inactive.
      */
@@ -161,9 +164,34 @@
     }
 
     /**
+     * Gets the state of the meta keys for a specific key event.
+     *
+     * For input devices that use toggled key modifiers, the `toggled' state
+     * is stored into the text buffer. This method retrieves the meta state
+     * for this event, accounting for the stored state. If the event has been
+     * created by a device that does not support toggled key modifiers, like
+     * a virtual device for example, the stored state is ignored.
+     *
+     * @param text the buffer in which the meta key would have been pressed.
+     * @param event the event for which to evaluate the meta state.
+     * @return an integer in which each bit set to one represents a pressed
+     *         or locked meta key.
+     */
+    public static final int getMetaState(final CharSequence text, final KeyEvent event) {
+        int metaState = event.getMetaState();
+        if (event.getKeyCharacterMap().getModifierBehavior()
+                == KeyCharacterMap.MODIFIER_BEHAVIOR_CHORDED_OR_TOGGLED) {
+            metaState |= getMetaState(text);
+        }
+        return metaState;
+    }
+
+    // As META_SELECTING is @hide we should not mention it in public comments, hence the
+    // omission in @param meta
+    /**
      * Gets the state of a particular meta key.
      *
-     * @param meta META_SHIFT_ON, META_ALT_ON, META_SYM_ON, or META_SELECTING
+     * @param meta META_SHIFT_ON, META_ALT_ON, META_SYM_ON
      * @param text the buffer in which the meta key would have been pressed.
      *
      * @return 0 if inactive, 1 if active, 2 if locked.
@@ -171,22 +199,53 @@
     public static final int getMetaState(CharSequence text, int meta) {
         switch (meta) {
             case META_SHIFT_ON:
-                return getActive(text, CAP, 1, 2);
+                return getActive(text, CAP, PRESSED_RETURN_VALUE, LOCKED_RETURN_VALUE);
 
             case META_ALT_ON:
-                return getActive(text, ALT, 1, 2);
+                return getActive(text, ALT, PRESSED_RETURN_VALUE, LOCKED_RETURN_VALUE);
 
             case META_SYM_ON:
-                return getActive(text, SYM, 1, 2);
+                return getActive(text, SYM, PRESSED_RETURN_VALUE, LOCKED_RETURN_VALUE);
 
             case META_SELECTING:
-                return getActive(text, SELECTING, 1, 2);
+                return getActive(text, SELECTING, PRESSED_RETURN_VALUE, LOCKED_RETURN_VALUE);
 
             default:
                 return 0;
         }
     }
 
+    /**
+     * Gets the state of a particular meta key to use with a particular key event.
+     *
+     * If the key event has been created by a device that does not support toggled
+     * key modifiers, like a virtual keyboard for example, only the meta state in
+     * the key event is considered.
+     *
+     * @param meta META_SHIFT_ON, META_ALT_ON, META_SYM_ON
+     * @param text the buffer in which the meta key would have been pressed.
+     * @param event the event for which to evaluate the meta state.
+     * @return 0 if inactive, 1 if active, 2 if locked.
+     */
+    public static final int getMetaState(final CharSequence text, final int meta,
+            final KeyEvent event) {
+        int metaState = event.getMetaState();
+        if (event.getKeyCharacterMap().getModifierBehavior()
+                == KeyCharacterMap.MODIFIER_BEHAVIOR_CHORDED_OR_TOGGLED) {
+            metaState |= getMetaState(text);
+        }
+        if (META_SELECTING == meta) {
+            // #getMetaState(long, int) does not support META_SELECTING, but we want the same
+            // behavior as #getMetaState(CharSequence, int) so we need to do it here
+            if ((metaState & META_SELECTING) != 0) {
+                // META_SELECTING is only ever set to PRESSED and can't be LOCKED, so return 1
+                return 1;
+            }
+            return 0;
+        }
+        return getMetaState(metaState, meta);
+    }
+
     private static int getActive(CharSequence text, Object meta,
                                  int on, int lock) {
         if (!(text instanceof Spanned)) {
@@ -430,18 +489,18 @@
     public static final int getMetaState(long state, int meta) {
         switch (meta) {
             case META_SHIFT_ON:
-                if ((state & META_CAP_LOCKED) != 0) return 2;
-                if ((state & META_SHIFT_ON) != 0) return 1;
+                if ((state & META_CAP_LOCKED) != 0) return LOCKED_RETURN_VALUE;
+                if ((state & META_SHIFT_ON) != 0) return PRESSED_RETURN_VALUE;
                 return 0;
 
             case META_ALT_ON:
-                if ((state & META_ALT_LOCKED) != 0) return 2;
-                if ((state & META_ALT_ON) != 0) return 1;
+                if ((state & META_ALT_LOCKED) != 0) return LOCKED_RETURN_VALUE;
+                if ((state & META_ALT_ON) != 0) return PRESSED_RETURN_VALUE;
                 return 0;
 
             case META_SYM_ON:
-                if ((state & META_SYM_LOCKED) != 0) return 2;
-                if ((state & META_SYM_ON) != 0) return 1;
+                if ((state & META_SYM_LOCKED) != 0) return LOCKED_RETURN_VALUE;
+                if ((state & META_SYM_ON) != 0) return PRESSED_RETURN_VALUE;
                 return 0;
 
             default:
@@ -599,4 +658,3 @@
     private static final int LOCKED = 
         Spannable.SPAN_MARK_MARK | (4 << Spannable.SPAN_USER_SHIFT);
 }
-
diff --git a/core/java/android/text/method/NumberKeyListener.java b/core/java/android/text/method/NumberKeyListener.java
index 5d4c732..988d566 100644
--- a/core/java/android/text/method/NumberKeyListener.java
+++ b/core/java/android/text/method/NumberKeyListener.java
@@ -41,7 +41,7 @@
     protected abstract char[] getAcceptedChars();
 
     protected int lookup(KeyEvent event, Spannable content) {
-        return event.getMatch(getAcceptedChars(), event.getMetaState() | getMetaState(content));
+        return event.getMatch(getAcceptedChars(), getMetaState(content, event));
     }
 
     public CharSequence filter(CharSequence source, int start, int end,
diff --git a/core/java/android/text/method/QwertyKeyListener.java b/core/java/android/text/method/QwertyKeyListener.java
index 98316ae..0bd46bc 100644
--- a/core/java/android/text/method/QwertyKeyListener.java
+++ b/core/java/android/text/method/QwertyKeyListener.java
@@ -108,7 +108,7 @@
 
         // QWERTY keyboard normal case
 
-        int i = event.getUnicodeChar(event.getMetaState() | getMetaState(content));
+        int i = event.getUnicodeChar(getMetaState(content, event));
 
         if (!mFullKeyboard) {
             int count = event.getRepeatCount();
diff --git a/core/java/android/transition/AutoTransition.java b/core/java/android/transition/AutoTransition.java
new file mode 100644
index 0000000..6e46021
--- /dev/null
+++ b/core/java/android/transition/AutoTransition.java
@@ -0,0 +1,41 @@
+/*
+ * 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.transition;
+
+/**
+ * Utility class for creating a default transition that automatically fades,
+ * moves, and resizes views during a scene change.
+ *
+ * <p>An AutoTransition can be described in a resource file by using the
+ * tag <code>autoTransition</code>, along with the other standard
+ * attributes of {@link android.R.styleable#Transition}.</p>
+ */
+public class AutoTransition extends TransitionSet {
+
+    /**
+     * Constructs an AutoTransition object, which is a TransitionSet which
+     * first fades out disappearing targets, then moves and resizes existing
+     * targets, and finally fades in appearing targets.
+     *
+     */
+    public AutoTransition() {
+        setOrdering(ORDERING_SEQUENTIAL);
+        addTransition(new Fade(Fade.OUT)).
+                addTransition(new ChangeBounds()).
+                addTransition(new Fade(Fade.IN));
+    }
+}
diff --git a/core/java/android/transition/ChangeBounds.java b/core/java/android/transition/ChangeBounds.java
new file mode 100644
index 0000000..8053bff
--- /dev/null
+++ b/core/java/android/transition/ChangeBounds.java
@@ -0,0 +1,310 @@
+/*
+ * 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.transition;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.RectEvaluator;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.BitmapDrawable;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.util.Map;
+
+/**
+ * This transition captures the layout bounds of target views before and after
+ * the scene change and animates those changes during the transition.
+ *
+ * <p>A ChangeBounds transition can be described in a resource file by using the
+ * tag <code>changeBounds</code>, along with the other standard
+ * attributes of {@link android.R.styleable#Transition}.</p>
+ */
+public class ChangeBounds extends Transition {
+
+    private static final String PROPNAME_BOUNDS = "android:changeBounds:bounds";
+    private static final String PROPNAME_PARENT = "android:changeBounds:parent";
+    private static final String PROPNAME_WINDOW_X = "android:changeBounds:windowX";
+    private static final String PROPNAME_WINDOW_Y = "android:changeBounds:windowY";
+    private static final String[] sTransitionProperties = {
+            PROPNAME_BOUNDS,
+            PROPNAME_PARENT,
+            PROPNAME_WINDOW_X,
+            PROPNAME_WINDOW_Y
+    };
+
+    int[] tempLocation = new int[2];
+    boolean mResizeClip = false;
+    boolean mReparent = false;
+    private static final String LOG_TAG = "ChangeBounds";
+
+    private static RectEvaluator sRectEvaluator = new RectEvaluator();
+
+    @Override
+    public String[] getTransitionProperties() {
+        return sTransitionProperties;
+    }
+
+    public void setResizeClip(boolean resizeClip) {
+        mResizeClip = resizeClip;
+    }
+
+    /**
+     * Setting this flag tells ChangeBounds to track the before/after parent
+     * of every view using this transition. The flag is not enabled by
+     * default because it requires the parent instances to be the same
+     * in the two scenes or else all parents must use ids to allow
+     * the transition to determine which parents are the same.
+     *
+     * @param reparent true if the transition should track the parent
+     * container of target views and animate parent changes.
+     */
+    public void setReparent(boolean reparent) {
+        mReparent = reparent;
+    }
+
+    private void captureValues(TransitionValues values) {
+        View view = values.view;
+        values.values.put(PROPNAME_BOUNDS, new Rect(view.getLeft(), view.getTop(),
+                view.getRight(), view.getBottom()));
+        values.values.put(PROPNAME_PARENT, values.view.getParent());
+        values.view.getLocationInWindow(tempLocation);
+        values.values.put(PROPNAME_WINDOW_X, tempLocation[0]);
+        values.values.put(PROPNAME_WINDOW_Y, tempLocation[1]);
+    }
+
+    @Override
+    public void captureStartValues(TransitionValues transitionValues) {
+        captureValues(transitionValues);
+    }
+
+    @Override
+    public void captureEndValues(TransitionValues transitionValues) {
+        captureValues(transitionValues);
+    }
+
+    @Override
+    public Animator createAnimator(final ViewGroup sceneRoot, TransitionValues startValues,
+            TransitionValues endValues) {
+        if (startValues == null || endValues == null) {
+            return null;
+        }
+        Map<String, Object> startParentVals = startValues.values;
+        Map<String, Object> endParentVals = endValues.values;
+        ViewGroup startParent = (ViewGroup) startParentVals.get(PROPNAME_PARENT);
+        ViewGroup endParent = (ViewGroup) endParentVals.get(PROPNAME_PARENT);
+        if (startParent == null || endParent == null) {
+            return null;
+        }
+        final View view = endValues.view;
+        boolean parentsEqual = (startParent == endParent) ||
+                (startParent.getId() == endParent.getId());
+        // TODO: Might want reparenting to be separate/subclass transition, or at least
+        // triggered by a property on ChangeBounds. Otherwise, we're forcing the requirement that
+        // all parents in layouts have IDs to avoid layout-inflation resulting in a side-effect
+        // of reparenting the views.
+        if (!mReparent || parentsEqual) {
+            Rect startBounds = (Rect) startValues.values.get(PROPNAME_BOUNDS);
+            Rect endBounds = (Rect) endValues.values.get(PROPNAME_BOUNDS);
+            int startLeft = startBounds.left;
+            int endLeft = endBounds.left;
+            int startTop = startBounds.top;
+            int endTop = endBounds.top;
+            int startRight = startBounds.right;
+            int endRight = endBounds.right;
+            int startBottom = startBounds.bottom;
+            int endBottom = endBounds.bottom;
+            int startWidth = startRight - startLeft;
+            int startHeight = startBottom - startTop;
+            int endWidth = endRight - endLeft;
+            int endHeight = endBottom - endTop;
+            int numChanges = 0;
+            if (startWidth != 0 && startHeight != 0 && endWidth != 0 && endHeight != 0) {
+                if (startLeft != endLeft) ++numChanges;
+                if (startTop != endTop) ++numChanges;
+                if (startRight != endRight) ++numChanges;
+                if (startBottom != endBottom) ++numChanges;
+            }
+            if (numChanges > 0) {
+                if (!mResizeClip) {
+                    PropertyValuesHolder pvh[] = new PropertyValuesHolder[numChanges];
+                    int pvhIndex = 0;
+                    if (startLeft != endLeft) view.setLeft(startLeft);
+                    if (startTop != endTop) view.setTop(startTop);
+                    if (startRight != endRight) view.setRight(startRight);
+                    if (startBottom != endBottom) view.setBottom(startBottom);
+                    if (startLeft != endLeft) {
+                        pvh[pvhIndex++] = PropertyValuesHolder.ofInt("left", startLeft, endLeft);
+                    }
+                    if (startTop != endTop) {
+                        pvh[pvhIndex++] = PropertyValuesHolder.ofInt("top", startTop, endTop);
+                    }
+                    if (startRight != endRight) {
+                        pvh[pvhIndex++] = PropertyValuesHolder.ofInt("right",
+                                startRight, endRight);
+                    }
+                    if (startBottom != endBottom) {
+                        pvh[pvhIndex++] = PropertyValuesHolder.ofInt("bottom",
+                                startBottom, endBottom);
+                    }
+                    ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(view, pvh);
+                    if (view.getParent() instanceof ViewGroup) {
+                        final ViewGroup parent = (ViewGroup) view.getParent();
+                        parent.suppressLayout(true);
+                        TransitionListener transitionListener = new TransitionListenerAdapter() {
+                            boolean mCanceled = false;
+
+                            @Override
+                            public void onTransitionCancel(Transition transition) {
+                                parent.suppressLayout(false);
+                                mCanceled = true;
+                            }
+
+                            @Override
+                            public void onTransitionEnd(Transition transition) {
+                                if (!mCanceled) {
+                                    parent.suppressLayout(false);
+                                }
+                            }
+
+                            @Override
+                            public void onTransitionPause(Transition transition) {
+                                parent.suppressLayout(false);
+                            }
+
+                            @Override
+                            public void onTransitionResume(Transition transition) {
+                                parent.suppressLayout(true);
+                            }
+                        };
+                        addListener(transitionListener);
+                    }
+                    return anim;
+                } else {
+                    if (startWidth != endWidth) view.setRight(endLeft +
+                            Math.max(startWidth, endWidth));
+                    if (startHeight != endHeight) view.setBottom(endTop +
+                            Math.max(startHeight, endHeight));
+                    // TODO: don't clobber TX/TY
+                    if (startLeft != endLeft) view.setTranslationX(startLeft - endLeft);
+                    if (startTop != endTop) view.setTranslationY(startTop - endTop);
+                    // Animate location with translationX/Y and size with clip bounds
+                    float transXDelta = endLeft - startLeft;
+                    float transYDelta = endTop - startTop;
+                    int widthDelta = endWidth - startWidth;
+                    int heightDelta = endHeight - startHeight;
+                    numChanges = 0;
+                    if (transXDelta != 0) numChanges++;
+                    if (transYDelta != 0) numChanges++;
+                    if (widthDelta != 0 || heightDelta != 0) numChanges++;
+                    PropertyValuesHolder pvh[] = new PropertyValuesHolder[numChanges];
+                    int pvhIndex = 0;
+                    if (transXDelta != 0) {
+                        pvh[pvhIndex++] = PropertyValuesHolder.ofFloat("translationX",
+                                view.getTranslationX(), 0);
+                    }
+                    if (transYDelta != 0) {
+                        pvh[pvhIndex++] = PropertyValuesHolder.ofFloat("translationY",
+                                view.getTranslationY(), 0);
+                    }
+                    if (widthDelta != 0 || heightDelta != 0) {
+                        Rect tempStartBounds = new Rect(0, 0, startWidth, startHeight);
+                        Rect tempEndBounds = new Rect(0, 0, endWidth, endHeight);
+                        pvh[pvhIndex++] = PropertyValuesHolder.ofObject("clipBounds",
+                                sRectEvaluator, tempStartBounds, tempEndBounds);
+                    }
+                    ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(view, pvh);
+                    if (view.getParent() instanceof ViewGroup) {
+                        final ViewGroup parent = (ViewGroup) view.getParent();
+                        parent.suppressLayout(true);
+                        TransitionListener transitionListener = new TransitionListenerAdapter() {
+                            boolean mCanceled = false;
+
+                            @Override
+                            public void onTransitionCancel(Transition transition) {
+                                parent.suppressLayout(false);
+                                mCanceled = true;
+                            }
+
+                            @Override
+                            public void onTransitionEnd(Transition transition) {
+                                if (!mCanceled) {
+                                    parent.suppressLayout(false);
+                                }
+                            }
+
+                            @Override
+                            public void onTransitionPause(Transition transition) {
+                                parent.suppressLayout(false);
+                            }
+
+                            @Override
+                            public void onTransitionResume(Transition transition) {
+                                parent.suppressLayout(true);
+                            }
+                        };
+                        addListener(transitionListener);
+                    }
+                    anim.addListener(new AnimatorListenerAdapter() {
+                        @Override
+                        public void onAnimationEnd(Animator animation) {
+                            view.setClipBounds(null);
+                        }
+                    });
+                    return anim;
+                }
+            }
+        } else {
+            int startX = (Integer) startValues.values.get(PROPNAME_WINDOW_X);
+            int startY = (Integer) startValues.values.get(PROPNAME_WINDOW_Y);
+            int endX = (Integer) endValues.values.get(PROPNAME_WINDOW_X);
+            int endY = (Integer) endValues.values.get(PROPNAME_WINDOW_Y);
+            // TODO: also handle size changes: check bounds and animate size changes
+            if (startX != endX || startY != endY) {
+                sceneRoot.getLocationInWindow(tempLocation);
+                Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),
+                        Bitmap.Config.ARGB_8888);
+                Canvas canvas = new Canvas(bitmap);
+                view.draw(canvas);
+                final BitmapDrawable drawable = new BitmapDrawable(bitmap);
+                view.setVisibility(View.INVISIBLE);
+                sceneRoot.getOverlay().add(drawable);
+                Rect startBounds1 = new Rect(startX - tempLocation[0], startY - tempLocation[1],
+                        startX - tempLocation[0] + view.getWidth(),
+                        startY - tempLocation[1] + view.getHeight());
+                Rect endBounds1 = new Rect(endX - tempLocation[0], endY - tempLocation[1],
+                        endX - tempLocation[0] + view.getWidth(),
+                        endY - tempLocation[1] + view.getHeight());
+                ObjectAnimator anim = ObjectAnimator.ofObject(drawable, "bounds",
+                        sRectEvaluator, startBounds1, endBounds1);
+                anim.addListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationEnd(Animator animation) {
+                        sceneRoot.getOverlay().remove(drawable);
+                        view.setVisibility(View.VISIBLE);
+                    }
+                });
+                return anim;
+            }
+        }
+        return null;
+    }
+}
diff --git a/core/java/android/transition/Crossfade.java b/core/java/android/transition/Crossfade.java
new file mode 100644
index 0000000..69ce872
--- /dev/null
+++ b/core/java/android/transition/Crossfade.java
@@ -0,0 +1,296 @@
+/*
+ * 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.transition;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.RectEvaluator;
+import android.animation.ValueAnimator;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.BitmapDrawable;
+import android.util.Log;
+import android.view.SurfaceView;
+import android.view.TextureView;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewOverlay;
+
+import java.util.Map;
+
+/**
+ * This transition captures bitmap representations of target views before and
+ * after the scene change and fades between them.
+ *
+ * <p>Note: This transition is not compatible with {@link TextureView}
+ * or {@link SurfaceView}.</p>
+ *
+ * @hide
+ */
+public class Crossfade extends Transition {
+    // TODO: Add a hook that lets a Transition call user code to query whether it should run on
+    // a given target view. This would save bitmap comparisons in this transition, for example.
+
+    private static final String LOG_TAG = "Crossfade";
+
+    private static final String PROPNAME_BITMAP = "android:crossfade:bitmap";
+    private static final String PROPNAME_DRAWABLE = "android:crossfade:drawable";
+    private static final String PROPNAME_BOUNDS = "android:crossfade:bounds";
+
+    private static RectEvaluator sRectEvaluator = new RectEvaluator();
+
+    private int mFadeBehavior = FADE_BEHAVIOR_REVEAL;
+    private int mResizeBehavior = RESIZE_BEHAVIOR_SCALE;
+
+    /**
+     * Flag specifying that the fading animation should cross-fade
+     * between the old and new representation of all affected target
+     * views. This means that the old representation will fade out
+     * while the new one fades in. This effect may work well on views
+     * without solid backgrounds, such as TextViews.
+     *
+     * @see #setFadeBehavior(int)
+     */
+    public static final int FADE_BEHAVIOR_CROSSFADE = 0;
+    /**
+     * Flag specifying that the fading animation should reveal the
+     * new representation of all affected target views. This means
+     * that the old representation will fade out, gradually
+     * revealing the new representation, which remains opaque
+     * the whole time. This effect may work well on views
+     * with solid backgrounds, such as ImageViews.
+     *
+     * @see #setFadeBehavior(int)
+     */
+    public static final int FADE_BEHAVIOR_REVEAL = 1;
+    /**
+     * Flag specifying that the fading animation should first fade
+     * out the original representation completely and then fade in the
+     * new one. This effect may be more suitable than the other
+     * fade behaviors for views with.
+     *
+     * @see #setFadeBehavior(int)
+     */
+    public static final int FADE_BEHAVIOR_OUT_IN = 2;
+
+    /**
+     * Flag specifying that the transition should not animate any
+     * changes in size between the old and new target views.
+     * This means that no scaling will take place as a result of
+     * this transition
+     *
+     * @see #setResizeBehavior(int)
+     */
+    public static final int RESIZE_BEHAVIOR_NONE = 0;
+    /**
+     * Flag specifying that the transition should animate any
+     * changes in size between the old and new target views.
+     * This means that the animation will scale the start/end
+     * representations of affected views from the starting size
+     * to the ending size over the course of the animation.
+     * This effect may work well on images, but is not recommended
+     * for text.
+     *
+     * @see #setResizeBehavior(int)
+     */
+    public static final int RESIZE_BEHAVIOR_SCALE = 1;
+
+    // TODO: Add fade/resize behaviors to xml resources
+
+    /**
+     * Sets the type of fading animation that will be run, one of
+     * {@link #FADE_BEHAVIOR_CROSSFADE} and {@link #FADE_BEHAVIOR_REVEAL}.
+     *
+     * @param fadeBehavior The type of fading animation to use when this
+     * transition is run.
+     */
+    public Crossfade setFadeBehavior(int fadeBehavior) {
+        if (fadeBehavior >= FADE_BEHAVIOR_CROSSFADE && fadeBehavior <= FADE_BEHAVIOR_OUT_IN) {
+            mFadeBehavior = fadeBehavior;
+        }
+        return this;
+    }
+
+    /**
+     * Returns the fading behavior of the animation.
+     *
+     * @return This crossfade object.
+     * @see #setFadeBehavior(int)
+     */
+    public int getFadeBehavior() {
+        return mFadeBehavior;
+    }
+
+    /**
+     * Sets the type of resizing behavior that will be used during the
+     * transition animation, one of {@link #RESIZE_BEHAVIOR_NONE} and
+     * {@link #RESIZE_BEHAVIOR_SCALE}.
+     *
+     * @param resizeBehavior The type of resizing behavior to use when this
+     * transition is run.
+     */
+    public Crossfade setResizeBehavior(int resizeBehavior) {
+        if (resizeBehavior >= RESIZE_BEHAVIOR_NONE && resizeBehavior <= RESIZE_BEHAVIOR_SCALE) {
+            mResizeBehavior = resizeBehavior;
+        }
+        return this;
+    }
+
+    /**
+     * Returns the resizing behavior of the animation.
+     *
+     * @return This crossfade object.
+     * @see #setResizeBehavior(int)
+     */
+    public int getResizeBehavior() {
+        return mResizeBehavior;
+    }
+
+    @Override
+    public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
+            TransitionValues endValues) {
+        if (startValues == null || endValues == null) {
+            return null;
+        }
+        final boolean useParentOverlay = mFadeBehavior != FADE_BEHAVIOR_REVEAL;
+        final View view = endValues.view;
+        Map<String, Object> startVals = startValues.values;
+        Map<String, Object> endVals = endValues.values;
+        Rect startBounds = (Rect) startVals.get(PROPNAME_BOUNDS);
+        Rect endBounds = (Rect) endVals.get(PROPNAME_BOUNDS);
+        Bitmap startBitmap = (Bitmap) startVals.get(PROPNAME_BITMAP);
+        Bitmap endBitmap = (Bitmap) endVals.get(PROPNAME_BITMAP);
+        final BitmapDrawable startDrawable = (BitmapDrawable) startVals.get(PROPNAME_DRAWABLE);
+        final BitmapDrawable endDrawable = (BitmapDrawable) endVals.get(PROPNAME_DRAWABLE);
+        if (Transition.DBG) {
+            Log.d(LOG_TAG, "StartBitmap.sameAs(endBitmap) = " + startBitmap.sameAs(endBitmap) +
+                    " for start, end: " + startBitmap + ", " + endBitmap);
+        }
+        if (startDrawable != null && endDrawable != null && !startBitmap.sameAs(endBitmap)) {
+            ViewOverlay overlay = useParentOverlay ?
+                    ((ViewGroup) view.getParent()).getOverlay() : view.getOverlay();
+            if (mFadeBehavior == FADE_BEHAVIOR_REVEAL) {
+                overlay.add(endDrawable);
+            }
+            overlay.add(startDrawable);
+            // The transition works by placing the end drawable under the start drawable and
+            // gradually fading out the start drawable. So it's not really a cross-fade, but rather
+            // a reveal of the end scene over time. Also, animate the bounds of both drawables
+            // to mimic the change in the size of the view itself between scenes.
+            ObjectAnimator anim;
+            if (mFadeBehavior == FADE_BEHAVIOR_OUT_IN) {
+                // Fade out completely halfway through the transition
+                anim = ObjectAnimator.ofInt(startDrawable, "alpha", 255, 0, 0);
+            } else {
+                anim = ObjectAnimator.ofInt(startDrawable, "alpha", 0);
+            }
+            anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+                @Override
+                public void onAnimationUpdate(ValueAnimator animation) {
+                    // TODO: some way to auto-invalidate views based on drawable changes? callbacks?
+                    view.invalidate(startDrawable.getBounds());
+                }
+            });
+            ObjectAnimator anim1 = null;
+            if (mFadeBehavior == FADE_BEHAVIOR_OUT_IN) {
+                // start fading in halfway through the transition
+                anim1 = ObjectAnimator.ofFloat(view, View.ALPHA, 0, 0, 1);
+            } else if (mFadeBehavior == FADE_BEHAVIOR_CROSSFADE) {
+                anim1 = ObjectAnimator.ofFloat(view, View.ALPHA, 0, 1);
+            }
+            if (Transition.DBG) {
+                Log.d(LOG_TAG, "Crossfade: created anim " + anim + " for start, end values " +
+                        startValues + ", " + endValues);
+            }
+            anim.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    ViewOverlay overlay = useParentOverlay ?
+                            ((ViewGroup) view.getParent()).getOverlay() : view.getOverlay();
+                    overlay.remove(startDrawable);
+                    if (mFadeBehavior == FADE_BEHAVIOR_REVEAL) {
+                        overlay.remove(endDrawable);
+                    }
+                }
+            });
+            AnimatorSet set = new AnimatorSet();
+            set.playTogether(anim);
+            if (anim1 != null) {
+                set.playTogether(anim1);
+            }
+            if (mResizeBehavior == RESIZE_BEHAVIOR_SCALE && !startBounds.equals(endBounds)) {
+                if (Transition.DBG) {
+                    Log.d(LOG_TAG, "animating from startBounds to endBounds: " +
+                            startBounds + ", " + endBounds);
+                }
+                Animator anim2 = ObjectAnimator.ofObject(startDrawable, "bounds",
+                        sRectEvaluator, startBounds, endBounds);
+                set.playTogether(anim2);
+                if (mResizeBehavior == RESIZE_BEHAVIOR_SCALE) {
+                    // TODO: How to handle resizing with a CROSSFADE (vs. REVEAL) effect
+                    // when we are animating the view directly?
+                    Animator anim3 = ObjectAnimator.ofObject(endDrawable, "bounds",
+                            sRectEvaluator, startBounds, endBounds);
+                    set.playTogether(anim3);
+                }
+            }
+            return set;
+        } else {
+            return null;
+        }
+    }
+
+    private void captureValues(TransitionValues transitionValues) {
+        View view = transitionValues.view;
+        Rect bounds = new Rect(0, 0, view.getWidth(), view.getHeight());
+        if (mFadeBehavior != FADE_BEHAVIOR_REVEAL) {
+            bounds.offset(view.getLeft(), view.getTop());
+        }
+        transitionValues.values.put(PROPNAME_BOUNDS, bounds);
+
+        if (Transition.DBG) {
+            Log.d(LOG_TAG, "Captured bounds " + transitionValues.values.get(PROPNAME_BOUNDS));
+        }
+        Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),
+                Bitmap.Config.ARGB_8888);
+        if (view instanceof TextureView) {
+            bitmap = ((TextureView) view).getBitmap();
+        } else {
+            Canvas c = new Canvas(bitmap);
+            view.draw(c);
+        }
+        transitionValues.values.put(PROPNAME_BITMAP, bitmap);
+        // TODO: I don't have resources, can't call the non-deprecated method?
+        BitmapDrawable drawable = new BitmapDrawable(bitmap);
+        // TODO: lrtb will be wrong if the view has transXY set
+        drawable.setBounds(bounds);
+        transitionValues.values.put(PROPNAME_DRAWABLE, drawable);
+    }
+
+    @Override
+    public void captureStartValues(TransitionValues transitionValues) {
+        captureValues(transitionValues);
+    }
+
+    @Override
+    public void captureEndValues(TransitionValues transitionValues) {
+        captureValues(transitionValues);
+    }
+}
diff --git a/core/java/android/transition/Fade.java b/core/java/android/transition/Fade.java
new file mode 100644
index 0000000..12e0d73
--- /dev/null
+++ b/core/java/android/transition/Fade.java
@@ -0,0 +1,301 @@
+/*
+ * 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.transition;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * This transition tracks changes to the visibility of target views in the
+ * start and end scenes and fades views in or out when they become visible
+ * or non-visible. Visibility is determined by both the
+ * {@link View#setVisibility(int)} state of the view as well as whether it
+ * is parented in the current view hierarchy.
+ *
+ * <p>A Fade transition can be described in a resource file by using the
+ * tag <code>fade</code>, along with the standard
+ * attributes of {@link android.R.styleable#Fade} and
+ * {@link android.R.styleable#Transition}.</p>
+
+ */
+public class Fade extends Visibility {
+
+    private static boolean DBG = Transition.DBG && false;
+
+    private static final String LOG_TAG = "Fade";
+    private static final String PROPNAME_ALPHA = "android:fade:alpha";
+    private static final String PROPNAME_SCREEN_X = "android:fade:screenX";
+    private static final String PROPNAME_SCREEN_Y = "android:fade:screenY";
+
+    /**
+     * Fading mode used in {@link #Fade(int)} to make the transition
+     * operate on targets that are appearing. Maybe be combined with
+     * {@link #OUT} to fade both in and out.
+     */
+    public static final int IN = 0x1;
+    /**
+     * Fading mode used in {@link #Fade(int)} to make the transition
+     * operate on targets that are disappearing. Maybe be combined with
+     * {@link #IN} to fade both in and out.
+     */
+    public static final int OUT = 0x2;
+
+    private int mFadingMode;
+
+    /**
+     * Constructs a Fade transition that will fade targets in and out.
+     */
+    public Fade() {
+        this(IN | OUT);
+    }
+
+    /**
+     * Constructs a Fade transition that will fade targets in
+     * and/or out, according to the value of fadingMode.
+     *
+     * @param fadingMode The behavior of this transition, a combination of
+     * {@link #IN} and {@link #OUT}.
+     */
+    public Fade(int fadingMode) {
+        mFadingMode = fadingMode;
+    }
+
+    /**
+     * Utility method to handle creating and running the Animator.
+     */
+    private Animator createAnimation(View view, float startAlpha, float endAlpha,
+            AnimatorListenerAdapter listener) {
+        if (startAlpha == endAlpha) {
+            // run listener if we're noop'ing the animation, to get the end-state results now
+            if (listener != null) {
+                listener.onAnimationEnd(null);
+            }
+            return null;
+        }
+        final ObjectAnimator anim = ObjectAnimator.ofFloat(view, "alpha", startAlpha, endAlpha);
+        if (listener != null) {
+            anim.addListener(listener);
+            anim.addPauseListener(listener);
+        }
+        return anim;
+    }
+
+    private void captureValues(TransitionValues transitionValues) {
+        float alpha = transitionValues.view.getAlpha();
+        transitionValues.values.put(PROPNAME_ALPHA, alpha);
+        int[] loc = new int[2];
+        transitionValues.view.getLocationOnScreen(loc);
+        transitionValues.values.put(PROPNAME_SCREEN_X, loc[0]);
+        transitionValues.values.put(PROPNAME_SCREEN_Y, loc[1]);
+    }
+
+    @Override
+    public void captureStartValues(TransitionValues transitionValues) {
+        super.captureStartValues(transitionValues);
+        captureValues(transitionValues);
+    }
+
+
+    @Override
+    public void captureEndValues(TransitionValues transitionValues) {
+        super.captureEndValues(transitionValues);
+    }
+
+    @Override
+    public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
+            TransitionValues endValues) {
+        Animator animator = super.createAnimator(sceneRoot, startValues, endValues);
+        if (animator == null && startValues != null && endValues != null) {
+            boolean endVisible = isVisible(endValues);
+            final View endView = endValues.view;
+            float endAlpha = endView.getAlpha();
+            float startAlpha = (Float) startValues.values.get(PROPNAME_ALPHA);
+            if ((endVisible && startAlpha < endAlpha && (mFadingMode & Fade.IN) != 0) ||
+                    (!endVisible && startAlpha > endAlpha && (mFadingMode & Fade.OUT) != 0)) {
+                animator = createAnimation(endView, startAlpha, endAlpha, null);
+            }
+        }
+        return animator;
+    }
+
+    @Override
+    public Animator onAppear(ViewGroup sceneRoot,
+            TransitionValues startValues, int startVisibility,
+            TransitionValues endValues, int endVisibility) {
+        if ((mFadingMode & IN) != IN || endValues == null) {
+            return null;
+        }
+        final View endView = endValues.view;
+        if (DBG) {
+            View startView = (startValues != null) ? startValues.view : null;
+            Log.d(LOG_TAG, "Fade.onDisappear: startView, startVis, endView, endVis = " +
+                    startView + ", " + startVisibility + ", " + endView + ", " + endVisibility);
+        }
+        // if alpha < 1, just fade it in from the current value
+        if (endView.getAlpha() == 1.0f) {
+            endView.setAlpha(0);
+        }
+        return createAnimation(endView, endView.getAlpha(), 1, null);
+    }
+
+    @Override
+    public Animator onDisappear(ViewGroup sceneRoot,
+            TransitionValues startValues, int startVisibility,
+            TransitionValues endValues, int endVisibility) {
+        if ((mFadingMode & OUT) != OUT) {
+            return null;
+        }
+        View view;
+        View startView = (startValues != null) ? startValues.view : null;
+        View endView = (endValues != null) ? endValues.view : null;
+        if (DBG) {
+            Log.d(LOG_TAG, "Fade.onDisappear: startView, startVis, endView, endVis = " +
+                        startView + ", " + startVisibility + ", " + endView + ", " + endVisibility);
+        }
+        View overlayView = null;
+        View viewToKeep = null;
+        if (endView == null || endView.getParent() == null) {
+            // view was removed: add the start view to the Overlay
+            view = startView;
+            overlayView = view;
+        } else {
+            // visibility change
+            if (endVisibility == View.INVISIBLE) {
+                view = endView;
+                viewToKeep = view;
+            } else {
+                // Becoming GONE
+                if (startView == endView) {
+                    view = endView;
+                    viewToKeep = view;
+                } else {
+                    view = startView;
+                    overlayView = view;
+                }
+            }
+        }
+        final int finalVisibility = endVisibility;
+        // TODO: add automatic facility to Visibility superclass for keeping views around
+        if (overlayView != null) {
+            // TODO: Need to do this for general case of adding to overlay
+            int screenX = (Integer) startValues.values.get(PROPNAME_SCREEN_X);
+            int screenY = (Integer) startValues.values.get(PROPNAME_SCREEN_Y);
+            int[] loc = new int[2];
+            sceneRoot.getLocationOnScreen(loc);
+            overlayView.offsetLeftAndRight((screenX - loc[0]) - overlayView.getLeft());
+            overlayView.offsetTopAndBottom((screenY - loc[1]) - overlayView.getTop());
+            sceneRoot.getOverlay().add(overlayView);
+            // TODO: add automatic facility to Visibility superclass for keeping views around
+            final float startAlpha = view.getAlpha();
+            float endAlpha = 0;
+            final View finalView = view;
+            final View finalOverlayView = overlayView;
+            final View finalViewToKeep = viewToKeep;
+            final ViewGroup finalSceneRoot = sceneRoot;
+            final AnimatorListenerAdapter endListener = new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    finalView.setAlpha(startAlpha);
+                    // TODO: restore view offset from overlay repositioning
+                    if (finalViewToKeep != null) {
+                        finalViewToKeep.setVisibility(finalVisibility);
+                    }
+                    if (finalOverlayView != null) {
+                        finalSceneRoot.getOverlay().remove(finalOverlayView);
+                    }
+                }
+
+                @Override
+                public void onAnimationPause(Animator animation) {
+                    if (finalOverlayView != null) {
+                        finalSceneRoot.getOverlay().remove(finalOverlayView);
+                    }
+                }
+
+                @Override
+                public void onAnimationResume(Animator animation) {
+                    if (finalOverlayView != null) {
+                        finalSceneRoot.getOverlay().add(finalOverlayView);
+                    }
+                }
+            };
+            return createAnimation(view, startAlpha, endAlpha, endListener);
+        }
+        if (viewToKeep != null) {
+            // TODO: find a different way to do this, like just changing the view to be
+            // VISIBLE for the duration of the transition
+            viewToKeep.setVisibility((View.VISIBLE));
+            // TODO: add automatic facility to Visibility superclass for keeping views around
+            final float startAlpha = view.getAlpha();
+            float endAlpha = 0;
+            final View finalView = view;
+            final View finalOverlayView = overlayView;
+            final View finalViewToKeep = viewToKeep;
+            final ViewGroup finalSceneRoot = sceneRoot;
+            final AnimatorListenerAdapter endListener = new AnimatorListenerAdapter() {
+                boolean mCanceled = false;
+                float mPausedAlpha = -1;
+
+                @Override
+                public void onAnimationPause(Animator animation) {
+                    if (finalViewToKeep != null && !mCanceled) {
+                        finalViewToKeep.setVisibility(finalVisibility);
+                    }
+                    mPausedAlpha = finalView.getAlpha();
+                    finalView.setAlpha(startAlpha);
+                }
+
+                @Override
+                public void onAnimationResume(Animator animation) {
+                    if (finalViewToKeep != null && !mCanceled) {
+                        finalViewToKeep.setVisibility(View.VISIBLE);
+                    }
+                    finalView.setAlpha(mPausedAlpha);
+                }
+
+                @Override
+                public void onAnimationCancel(Animator animation) {
+                    mCanceled = true;
+                    if (mPausedAlpha >= 0) {
+                        finalView.setAlpha(mPausedAlpha);
+                    }
+                }
+
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    if (!mCanceled) {
+                        finalView.setAlpha(startAlpha);
+                    }
+                    // TODO: restore view offset from overlay repositioning
+                    if (finalViewToKeep != null && !mCanceled) {
+                        finalViewToKeep.setVisibility(finalVisibility);
+                    }
+                    if (finalOverlayView != null) {
+                        finalSceneRoot.getOverlay().remove(finalOverlayView);
+                    }
+                }
+            };
+            return createAnimation(view, startAlpha, endAlpha, endListener);
+        }
+        return null;
+    }
+
+}
\ No newline at end of file
diff --git a/core/java/android/transition/Recolor.java b/core/java/android/transition/Recolor.java
new file mode 100644
index 0000000..70111d1
--- /dev/null
+++ b/core/java/android/transition/Recolor.java
@@ -0,0 +1,95 @@
+/*
+ * 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.transition;
+
+import android.animation.Animator;
+import android.animation.ArgbEvaluator;
+import android.animation.ObjectAnimator;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+/**
+ * This transition tracks changes during scene changes to the
+ * {@link View#setBackground(android.graphics.drawable.Drawable) background}
+ * property of its target views (when the background is a
+ * {@link ColorDrawable}, as well as the
+ * {@link TextView#setTextColor(android.content.res.ColorStateList)
+ * color} of the text for target TextViews. If the color changes between
+ * scenes, the color change is animated.
+ *
+ * @hide
+ */
+public class Recolor extends Transition {
+
+    private static final String PROPNAME_BACKGROUND = "android:recolor:background";
+    private static final String PROPNAME_TEXT_COLOR = "android:recolor:textColor";
+
+    private void captureValues(TransitionValues transitionValues) {
+        transitionValues.values.put(PROPNAME_BACKGROUND, transitionValues.view.getBackground());
+        if (transitionValues.view instanceof TextView) {
+            transitionValues.values.put(PROPNAME_TEXT_COLOR,
+                    ((TextView)transitionValues.view).getCurrentTextColor());
+        }
+    }
+
+    @Override
+    public void captureStartValues(TransitionValues transitionValues) {
+        captureValues(transitionValues);
+    }
+
+    @Override
+    public void captureEndValues(TransitionValues transitionValues) {
+        captureValues(transitionValues);
+    }
+
+    @Override
+    public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
+            TransitionValues endValues) {
+        if (startValues == null || endValues == null) {
+            return null;
+        }
+        final View view = endValues.view;
+        Drawable startBackground = (Drawable) startValues.values.get(PROPNAME_BACKGROUND);
+        Drawable endBackground = (Drawable) endValues.values.get(PROPNAME_BACKGROUND);
+        boolean changed = false;
+        if (startBackground instanceof ColorDrawable && endBackground instanceof ColorDrawable) {
+            ColorDrawable startColor = (ColorDrawable) startBackground;
+            ColorDrawable endColor = (ColorDrawable) endBackground;
+            if (startColor.getColor() != endColor.getColor()) {
+                endColor.setColor(startColor.getColor());
+                changed = true;
+                return ObjectAnimator.ofObject(endBackground, "color",
+                        new ArgbEvaluator(), startColor.getColor(), endColor.getColor());
+            }
+        }
+        if (view instanceof TextView) {
+            TextView textView = (TextView) view;
+            int start = (Integer) startValues.values.get(PROPNAME_TEXT_COLOR);
+            int end = (Integer) endValues.values.get(PROPNAME_TEXT_COLOR);
+            if (start != end) {
+                textView.setTextColor(end);
+                changed = true;
+                return ObjectAnimator.ofObject(textView, "textColor",
+                        new ArgbEvaluator(), start, end);
+            }
+        }
+        return null;
+    }
+}
diff --git a/core/java/android/transition/Rotate.java b/core/java/android/transition/Rotate.java
new file mode 100644
index 0000000..ad1720ca
--- /dev/null
+++ b/core/java/android/transition/Rotate.java
@@ -0,0 +1,60 @@
+/*
+ * 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.transition;
+
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * This transition captures the rotation property of targets before and after
+ * the scene change and animates any changes.
+ *
+ * @hide
+ */
+public class Rotate extends Transition {
+
+    private static final String PROPNAME_ROTATION = "android:rotate:rotation";
+
+    @Override
+    public void captureStartValues(TransitionValues transitionValues) {
+        transitionValues.values.put(PROPNAME_ROTATION, transitionValues.view.getRotation());
+    }
+
+    @Override
+    public void captureEndValues(TransitionValues transitionValues) {
+        transitionValues.values.put(PROPNAME_ROTATION, transitionValues.view.getRotation());
+    }
+
+    @Override
+    public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
+            TransitionValues endValues) {
+        if (startValues == null || endValues == null) {
+            return null;
+        }
+        final View view = endValues.view;
+        float startRotation = (Float) startValues.values.get(PROPNAME_ROTATION);
+        float endRotation = (Float) endValues.values.get(PROPNAME_ROTATION);
+        if (startRotation != endRotation) {
+            view.setRotation(startRotation);
+            return ObjectAnimator.ofFloat(view, View.ROTATION,
+                    startRotation, endRotation);
+        }
+        return null;
+    }
+}
diff --git a/core/java/android/transition/Scene.java b/core/java/android/transition/Scene.java
new file mode 100644
index 0000000..f81eeef
--- /dev/null
+++ b/core/java/android/transition/Scene.java
@@ -0,0 +1,245 @@
+/*
+ * 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.transition;
+
+import android.content.Context;
+import android.util.SparseArray;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * A scene represents the collection of values that various properties in the
+ * View hierarchy will have when the scene is applied. A Scene can be
+ * configured to automatically run a Transition when it is applied, which will
+ * animate the various property changes that take place during the
+ * scene change.
+ */
+public final class Scene {
+
+    private Context mContext;
+    private int mLayoutId = -1;
+    private ViewGroup mSceneRoot;
+    private ViewGroup mLayout; // alternative to layoutId
+    Runnable mEnterAction, mExitAction;
+    private static ThreadLocal<SparseArray<Scene>> sScenes = new ThreadLocal<SparseArray<Scene>>();
+
+    /**
+     * Returns a Scene described by the resource file associated with the given
+     * <code>layoutId</code> parameter. If such a Scene has already been created,
+     * that same Scene will be returned. This caching of layoutId-based scenes enables
+     * sharing of common scenes between those created in code and those referenced
+     * by {@link TransitionManager} XML resource files.
+     *
+     * @param sceneRoot The root of the hierarchy in which scene changes
+     * and transitions will take place.
+     * @param layoutId The id of a standard layout resource file.
+     * @param context The context used in the process of inflating
+     * the layout resource.
+     * @return
+     */
+    public static Scene getSceneForLayout(ViewGroup sceneRoot, int layoutId, Context context) {
+        SparseArray<Scene> scenes = sScenes.get();
+        if (scenes == null) {
+            scenes = new SparseArray<Scene>();
+            sScenes.set(scenes);
+        }
+        Scene scene = scenes.get(layoutId);
+        if (scene != null) {
+            return scene;
+        } else {
+            scene = new Scene(sceneRoot, layoutId, context);
+            scenes.put(layoutId, scene);
+            return scene;
+        }
+    }
+
+    /**
+     * Constructs a Scene with no information about how values will change
+     * when this scene is applied. This constructor might be used when
+     * a Scene is created with the intention of being dynamically configured,
+     * through setting {@link #setEnterAction(Runnable)} and possibly
+     * {@link #setExitAction(Runnable)}.
+     *
+     * @param sceneRoot The root of the hierarchy in which scene changes
+     * and transitions will take place.
+     */
+    public Scene(ViewGroup sceneRoot) {
+        mSceneRoot = sceneRoot;
+    }
+
+    /**
+     * Constructs a Scene which, when entered, will remove any
+     * children from the sceneRoot container and will inflate and add
+     * the hierarchy specified by the layoutId resource file.
+     *
+     * <p>This method is hidden because layoutId-based scenes should be
+     * created by the caching factory method {@link Scene#getCurrentScene(View)}.</p>
+     *
+     * @param sceneRoot The root of the hierarchy in which scene changes
+     * and transitions will take place.
+     * @param layoutId The id of a resource file that defines the view
+     * hierarchy of this scene.
+     * @param context The context used in the process of inflating
+     * the layout resource.
+     */
+    private Scene(ViewGroup sceneRoot, int layoutId, Context context) {
+        mContext = context;
+        mSceneRoot = sceneRoot;
+        mLayoutId = layoutId;
+    }
+
+    /**
+     * Constructs a Scene which, when entered, will remove any
+     * children from the sceneRoot container and add the layout
+     * object as a new child of that container.
+     *
+     * @param sceneRoot The root of the hierarchy in which scene changes
+     * and transitions will take place.
+     * @param layout The view hierarchy of this scene, added as a child
+     * of sceneRoot when this scene is entered.
+     */
+    public Scene(ViewGroup sceneRoot, ViewGroup layout) {
+        mSceneRoot = sceneRoot;
+        mLayout = layout;
+    }
+
+    /**
+     * Gets the root of the scene, which is the root of the view hierarchy
+     * affected by changes due to this scene, and which will be animated
+     * when this scene is entered.
+     *
+     * @return The root of the view hierarchy affected by this scene.
+     */
+    public ViewGroup getSceneRoot() {
+        return mSceneRoot;
+    }
+
+    /**
+     * Exits this scene, if it is the current scene
+     * on the scene's {@link #getSceneRoot() scene root}. The current scene is
+     * set when {@link #enter() entering} a scene.
+     * Exiting a scene runs the {@link #setExitAction(Runnable) exit action}
+     * if there is one.
+     */
+    public void exit() {
+        if (getCurrentScene(mSceneRoot) == this) {
+            if (mExitAction != null) {
+                mExitAction.run();
+            }
+        }
+    }
+
+    /**
+     * Enters this scene, which entails changing all values that
+     * are specified by this scene. These may be values associated
+     * with a layout view group or layout resource file which will
+     * now be added to the scene root, or it may be values changed by
+     * an {@link #setEnterAction(Runnable)} enter action}, or a
+     * combination of the these. No transition will be run when the
+     * scene is entered. To get transition behavior in scene changes,
+     * use one of the methods in {@link TransitionManager} instead.
+     */
+    public void enter() {
+
+        // Apply layout change, if any
+        if (mLayoutId >= 0 || mLayout != null) {
+            // empty out parent container before adding to it
+            getSceneRoot().removeAllViews();
+
+            if (mLayoutId >= 0) {
+                LayoutInflater.from(mContext).inflate(mLayoutId, mSceneRoot);
+            } else {
+                mSceneRoot.addView(mLayout);
+            }
+        }
+
+        // Notify next scene that it is entering. Subclasses may override to configure scene.
+        if (mEnterAction != null) {
+            mEnterAction.run();
+        }
+
+        setCurrentScene(mSceneRoot, this);
+    }
+
+    /**
+     * Set the scene that the given view is in. The current scene is set only
+     * on the root view of a scene, not for every view in that hierarchy. This
+     * information is used by Scene to determine whether there is a previous
+     * scene which should be exited before the new scene is entered.
+     *
+     * @param view The view on which the current scene is being set
+     */
+    static void setCurrentScene(View view, Scene scene) {
+        view.setTagInternal(com.android.internal.R.id.current_scene, scene);
+    }
+
+    /**
+     * Gets the current {@link Scene} set on the given view. A scene is set on a view
+     * only if that view is the scene root.
+     *
+     * @return The current Scene set on this view. A value of null indicates that
+     * no Scene is currently set.
+     */
+    static Scene getCurrentScene(View view) {
+        return (Scene) view.getTag(com.android.internal.R.id.current_scene);
+    }
+
+    /**
+     * Scenes that are not defined with layout resources or
+     * hierarchies, or which need to perform additional steps
+     * after those hierarchies are changed to, should set an enter
+     * action, and possibly an exit action as well. An enter action
+     * will cause Scene to call back into application code to do
+     * anything else the application needs after transitions have
+     * captured pre-change values and after any other scene changes
+     * have been applied, such as the layout (if any) being added to
+     * the view hierarchy. After this method is called, Transitions will
+     * be played.
+     *
+     * @param action The runnable whose {@link Runnable#run() run()} method will
+     * be called when this scene is entered
+     * @see #setExitAction(Runnable)
+     * @see Scene#Scene(ViewGroup, int, Context)
+     * @see Scene#Scene(ViewGroup, ViewGroup)
+     */
+    public void setEnterAction(Runnable action) {
+        mEnterAction = action;
+    }
+
+    /**
+     * Scenes that are not defined with layout resources or
+     * hierarchies, or which need to perform additional steps
+     * after those hierarchies are changed to, should set an enter
+     * action, and possibly an exit action as well. An exit action
+     * will cause Scene to call back into application code to do
+     * anything the application needs to do after applicable transitions have
+     * captured pre-change values, but before any other scene changes
+     * have been applied, such as the new layout (if any) being added to
+     * the view hierarchy. After this method is called, the next scene
+     * will be entered, including a call to {@link #setEnterAction(Runnable)}
+     * if an enter action is set.
+     *
+     * @see #setEnterAction(Runnable)
+     * @see Scene#Scene(ViewGroup, int, Context)
+     * @see Scene#Scene(ViewGroup, ViewGroup)
+     */
+    public void setExitAction(Runnable action) {
+        mExitAction = action;
+    }
+
+}
\ No newline at end of file
diff --git a/core/java/android/transition/Slide.java b/core/java/android/transition/Slide.java
new file mode 100644
index 0000000..b38973c
--- /dev/null
+++ b/core/java/android/transition/Slide.java
@@ -0,0 +1,65 @@
+/*
+ * 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.transition;
+
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.animation.TimeInterpolator;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.DecelerateInterpolator;
+
+/**
+ * This transition captures the visibility of target objects before and
+ * after a scene change and animates any changes by sliding the target
+ * objects into or out of place.
+ *
+ * @hide
+ */
+public class Slide extends Visibility {
+
+    // TODO: Add parameter for sliding factor - it's hard-coded below
+
+    private static final TimeInterpolator sAccelerator = new AccelerateInterpolator();
+    private static final TimeInterpolator sDecelerator = new DecelerateInterpolator();
+
+    @Override
+    public Animator onAppear(ViewGroup sceneRoot,
+            TransitionValues startValues, int startVisibility,
+            TransitionValues endValues, int endVisibility) {
+        View endView = (endValues != null) ? endValues.view : null;
+        endView.setTranslationY(-2 * endView.getHeight());
+        ObjectAnimator anim = ObjectAnimator.ofFloat(endView, View.TRANSLATION_Y,
+                -2 * endView.getHeight(), 0);
+        anim.setInterpolator(sDecelerator);
+        return anim;
+    }
+
+    @Override
+    public Animator onDisappear(ViewGroup sceneRoot,
+            TransitionValues startValues, int startVisibility,
+            TransitionValues endValues, int endVisibility) {
+        View startView = (startValues != null) ? startValues.view : null;
+        startView.setTranslationY(0);
+        ObjectAnimator anim = ObjectAnimator.ofFloat(startView, View.TRANSLATION_Y, 0,
+                -2 * startView.getHeight());
+        anim.setInterpolator(sAccelerator);
+        return anim;
+    }
+
+}
diff --git a/core/java/android/transition/TextChange.java b/core/java/android/transition/TextChange.java
new file mode 100644
index 0000000..0b1e4e1
--- /dev/null
+++ b/core/java/android/transition/TextChange.java
@@ -0,0 +1,231 @@
+/*
+ * 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.transition;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ValueAnimator;
+import android.graphics.Color;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import java.util.Map;
+
+/**
+ * This transition tracks changes to the text in TextView targets. If the text
+ * changes between the start and end scenes, the transition ensures that the
+ * starting text stays until the transition ends, at which point it changes
+ * to the end text.  This is useful in situations where you want to resize a
+ * text view to its new size before displaying the text that goes there.
+ *
+ * @hide
+ */
+public class TextChange extends Transition {
+    private static final String PROPNAME_TEXT = "android:textchange:text";
+    private static final String PROPNAME_TEXT_COLOR = "android:textchange:textColor";
+
+    private int mChangeBehavior = CHANGE_BEHAVIOR_KEEP;
+
+    /**
+     * Flag specifying that the text in affected/changing TextView targets will keep
+     * their original text during the transition, setting it to the final text when
+     * the transition ends. This is the default behavior.
+     *
+     * @see #setChangeBehavior(int)
+     */
+    public static final int CHANGE_BEHAVIOR_KEEP = 0;
+    /**
+     * Flag specifying that the text changing animation should first fade
+     * out the original text completely. The new text is set on the target
+     * view at the end of the fade-out animation. This transition is typically
+     * used with a later {@link #CHANGE_BEHAVIOR_IN} transition, allowing more
+     * flexibility than the {@link #CHANGE_BEHAVIOR_OUT_IN} by allowing other
+     * transitions to be run sequentially or in parallel with these fades.
+     *
+     * @see #setChangeBehavior(int)
+     */
+    public static final int CHANGE_BEHAVIOR_OUT = 1;
+    /**
+     * Flag specifying that the text changing animation should fade in the
+     * end text into the affected target view(s). This transition is typically
+     * used in conjunction with an earlier {@link #CHANGE_BEHAVIOR_OUT}
+     * transition, possibly with other transitions running as well, such as
+     * a sequence to fade out, then resize the view, then fade in.
+     *
+     * @see #setChangeBehavior(int)
+     */
+    public static final int CHANGE_BEHAVIOR_IN = 2;
+    /**
+     * Flag specifying that the text changing animation should first fade
+     * out the original text completely and then fade in the
+     * new text.
+     *
+     * @see #setChangeBehavior(int)
+     */
+    public static final int CHANGE_BEHAVIOR_OUT_IN = 3;
+
+    private static final String[] sTransitionProperties = {
+            PROPNAME_TEXT
+    };
+
+    /**
+     * Sets the type of changing animation that will be run, one of
+     * {@link #CHANGE_BEHAVIOR_KEEP}, {@link #CHANGE_BEHAVIOR_OUT},
+     * {@link #CHANGE_BEHAVIOR_IN}, and {@link #CHANGE_BEHAVIOR_OUT_IN}.
+     *
+     * @param changeBehavior The type of fading animation to use when this
+     * transition is run.
+     * @return this textChange object.
+     */
+    public TextChange setChangeBehavior(int changeBehavior) {
+        if (changeBehavior >= CHANGE_BEHAVIOR_KEEP && changeBehavior <= CHANGE_BEHAVIOR_OUT_IN) {
+            mChangeBehavior = changeBehavior;
+        }
+        return this;
+    }
+
+    @Override
+    public String[] getTransitionProperties() {
+        return sTransitionProperties;
+    }
+
+    /**
+     * Returns the type of changing animation that will be run.
+     *
+     * @return either {@link #CHANGE_BEHAVIOR_KEEP}, {@link #CHANGE_BEHAVIOR_OUT},
+     * {@link #CHANGE_BEHAVIOR_IN}, or {@link #CHANGE_BEHAVIOR_OUT_IN}.
+     */
+    public int getChangeBehavior() {
+        return mChangeBehavior;
+    }
+
+    private void captureValues(TransitionValues transitionValues) {
+        if (transitionValues.view instanceof TextView) {
+            TextView textview = (TextView) transitionValues.view;
+            transitionValues.values.put(PROPNAME_TEXT, textview.getText());
+            if (mChangeBehavior > CHANGE_BEHAVIOR_KEEP) {
+                transitionValues.values.put(PROPNAME_TEXT_COLOR, textview.getCurrentTextColor());
+            }
+        }
+    }
+
+    @Override
+    public void captureStartValues(TransitionValues transitionValues) {
+        captureValues(transitionValues);
+    }
+
+    @Override
+    public void captureEndValues(TransitionValues transitionValues) {
+        captureValues(transitionValues);
+    }
+
+    @Override
+    public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
+            TransitionValues endValues) {
+        if (startValues == null || endValues == null ||
+                !(startValues.view instanceof TextView) || !(endValues.view instanceof TextView)) {
+            return null;
+        }
+        final TextView view = (TextView) endValues.view;
+        Map<String, Object> startVals = startValues.values;
+        Map<String, Object> endVals = endValues.values;
+        final CharSequence startText = startVals.get(PROPNAME_TEXT) != null ?
+                (CharSequence) startVals.get(PROPNAME_TEXT) : "";
+        final CharSequence endText = endVals.get(PROPNAME_TEXT) != null ?
+                (CharSequence) endVals.get(PROPNAME_TEXT) : "";
+        if (!startText.equals(endText)) {
+            view.setText(startText);
+            Animator anim;
+            if (mChangeBehavior == CHANGE_BEHAVIOR_KEEP) {
+                anim = ValueAnimator.ofFloat(0, 1);
+                anim.addListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationEnd(Animator animation) {
+                        if (startText.equals(view.getText())) {
+                            // Only set if it hasn't been changed since anim started
+                            view.setText(endText);
+                        }
+                    }
+                });
+            } else {
+                // Fade out start text
+                final int startColor = (Integer) startVals.get(PROPNAME_TEXT_COLOR);
+                final int endColor = (Integer) endVals.get(PROPNAME_TEXT_COLOR);
+                ValueAnimator outAnim = null, inAnim = null;
+                if (mChangeBehavior == CHANGE_BEHAVIOR_OUT_IN ||
+                        mChangeBehavior == CHANGE_BEHAVIOR_OUT) {
+                    outAnim = ValueAnimator.ofInt(255, 0);
+                    outAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+                        @Override
+                        public void onAnimationUpdate(ValueAnimator animation) {
+                            int currAlpha = (Integer) animation.getAnimatedValue();
+                            view.setTextColor(currAlpha << 24 | Color.red(startColor) << 16 |
+                                    Color.green(startColor) << 8 | Color.red(startColor));
+                        }
+                    });
+                    outAnim.addListener(new AnimatorListenerAdapter() {
+                        @Override
+                        public void onAnimationEnd(Animator animation) {
+                            if (startText.equals(view.getText())) {
+                                // Only set if it hasn't been changed since anim started
+                                view.setText(endText);
+                            }
+                        }
+                    });
+                }
+                if (mChangeBehavior == CHANGE_BEHAVIOR_OUT_IN ||
+                        mChangeBehavior == CHANGE_BEHAVIOR_IN) {
+                    inAnim = ValueAnimator.ofInt(0, 255);
+                    inAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+                        @Override
+                        public void onAnimationUpdate(ValueAnimator animation) {
+                            int currAlpha = (Integer) animation.getAnimatedValue();
+                            view.setTextColor(currAlpha << 24 | Color.red(endColor) << 16 |
+                                    Color.green(endColor) << 8 | Color.red(endColor));
+                        }
+                    });
+                }
+                if (outAnim != null && inAnim != null) {
+                    anim = new AnimatorSet();
+                    ((AnimatorSet) anim).playSequentially(outAnim, inAnim);
+                } else if (outAnim != null) {
+                    anim = outAnim;
+                } else {
+                    // Must be an in-only animation
+                    anim = inAnim;
+                }
+            }
+            TransitionListener transitionListener = new TransitionListenerAdapter() {
+                boolean mCanceled = false;
+
+                @Override
+                public void onTransitionPause(Transition transition) {
+                    view.setText(endText);
+                }
+
+                @Override
+                public void onTransitionResume(Transition transition) {
+                    view.setText(startText);
+                }
+            };
+            addListener(transitionListener);
+            return anim;
+        }
+        return null;
+    }
+}
diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java
new file mode 100644
index 0000000..c588c6b
--- /dev/null
+++ b/core/java/android/transition/Transition.java
@@ -0,0 +1,1662 @@
+/*
+ * 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.transition;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.TimeInterpolator;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.LongSparseArray;
+import android.util.SparseArray;
+import android.view.SurfaceView;
+import android.view.TextureView;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewOverlay;
+import android.widget.ListView;
+import android.widget.Spinner;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A Transition holds information about animations that will be run on its
+ * targets during a scene change. Subclasses of this abstract class may
+ * choreograph several child transitions ({@link TransitionSet} or they may
+ * perform custom animations themselves. Any Transition has two main jobs:
+ * (1) capture property values, and (2) play animations based on changes to
+ * captured property values. A custom transition knows what property values
+ * on View objects are of interest to it, and also knows how to animate
+ * changes to those values. For example, the {@link Fade} transition tracks
+ * changes to visibility-related properties and is able to construct and run
+ * animations that fade items in or out based on changes to those properties.
+ *
+ * <p>Note: Transitions may not work correctly with either {@link SurfaceView}
+ * or {@link TextureView}, due to the way that these views are displayed
+ * on the screen. For SurfaceView, the problem is that the view is updated from
+ * a non-UI thread, so changes to the view due to transitions (such as moving
+ * and resizing the view) may be out of sync with the display inside those bounds.
+ * TextureView is more compatible with transitions in general, but some
+ * specific transitions (such as {@link Fade}) may not be compatible
+ * with TextureView because they rely on {@link ViewOverlay} functionality,
+ * which does not currently work with TextureView.</p>
+ *
+ * <p>Transitions can be declared in XML resource files inside the <code>res/transition</code>
+ * directory. Transition resources consist of a tag name for one of the Transition
+ * subclasses along with attributes to define some of the attributes of that transition.
+ * For example, here is a minimal resource file that declares a {@link ChangeBounds} transition:</p>
+ *
+ * {@sample development/samples/ApiDemos/res/transition/changebounds.xml ChangeBounds}
+ *
+ * <p>Note that attributes for the transition are not required, just as they are
+ * optional when declared in code; Transitions created from XML resources will use
+ * the same defaults as their code-created equivalents. Here is a slightly more
+ * elaborate example which declares a {@link TransitionSet} transition with
+ * {@link ChangeBounds} and {@link Fade} child transitions:</p>
+ *
+ * {@sample
+ * development/samples/ApiDemos/res/transition/changebounds_fadeout_sequential.xml TransitionSet}
+ *
+ * <p>In this example, the transitionOrdering attribute is used on the TransitionSet
+ * object to change from the default {@link TransitionSet#ORDERING_TOGETHER} behavior
+ * to be {@link TransitionSet#ORDERING_SEQUENTIAL} instead. Also, the {@link Fade}
+ * transition uses a fadingMode of {@link Fade#OUT} instead of the default
+ * out-in behavior. Finally, note the use of the <code>targets</code> sub-tag, which
+ * takes a set of {@link android.R.styleable#TransitionTarget target} tags, each
+ * of which lists a specific <code>targetId</code> which this transition acts upon.
+ * Use of targets is optional, but can be used to either limit the time spent checking
+ * attributes on unchanging views, or limiting the types of animations run on specific views.
+ * In this case, we know that only the <code>grayscaleContainer</code> will be
+ * disappearing, so we choose to limit the {@link Fade} transition to only that view.</p>
+ *
+ * Further information on XML resource descriptions for transitions can be found for
+ * {@link android.R.styleable#Transition}, {@link android.R.styleable#TransitionSet},
+ * {@link android.R.styleable#TransitionTarget}, and {@link android.R.styleable#Fade}.
+ *
+ */
+public abstract class Transition implements Cloneable {
+
+    private static final String LOG_TAG = "Transition";
+    static final boolean DBG = false;
+
+    private String mName = getClass().getName();
+
+    long mStartDelay = -1;
+    long mDuration = -1;
+    TimeInterpolator mInterpolator = null;
+    ArrayList<Integer> mTargetIds = new ArrayList<Integer>();
+    ArrayList<View> mTargets = new ArrayList<View>();
+    ArrayList<Integer> mTargetIdExcludes = null;
+    ArrayList<View> mTargetExcludes = null;
+    ArrayList<Class> mTargetTypeExcludes = null;
+    ArrayList<Integer> mTargetIdChildExcludes = null;
+    ArrayList<View> mTargetChildExcludes = null;
+    ArrayList<Class> mTargetTypeChildExcludes = null;
+    private TransitionValuesMaps mStartValues = new TransitionValuesMaps();
+    private TransitionValuesMaps mEndValues = new TransitionValuesMaps();
+    TransitionSet mParent = null;
+
+    // Per-animator information used for later canceling when future transitions overlap
+    private static ThreadLocal<ArrayMap<Animator, AnimationInfo>> sRunningAnimators =
+            new ThreadLocal<ArrayMap<Animator, AnimationInfo>>();
+
+    // Scene Root is set at createAnimator() time in the cloned Transition
+    ViewGroup mSceneRoot = null;
+
+    // Track all animators in use in case the transition gets canceled and needs to
+    // cancel running animators
+    private ArrayList<Animator> mCurrentAnimators = new ArrayList<Animator>();
+
+    // Number of per-target instances of this Transition currently running. This count is
+    // determined by calls to start() and end()
+    int mNumInstances = 0;
+
+    // Whether this transition is currently paused, due to a call to pause()
+    boolean mPaused = false;
+
+    // Whether this transition has ended. Used to avoid pause/resume on transitions
+    // that have completed
+    private boolean mEnded = false;
+
+    // The set of listeners to be sent transition lifecycle events.
+    ArrayList<TransitionListener> mListeners = null;
+
+    // The set of animators collected from calls to createAnimator(),
+    // to be run in runAnimators()
+    ArrayList<Animator> mAnimators = new ArrayList<Animator>();
+
+    /**
+     * Constructs a Transition object with no target objects. A transition with
+     * no targets defaults to running on all target objects in the scene hierarchy
+     * (if the transition is not contained in a TransitionSet), or all target
+     * objects passed down from its parent (if it is in a TransitionSet).
+     */
+    public Transition() {}
+
+    /**
+     * Sets the duration of this transition. By default, there is no duration
+     * (indicated by a negative number), which means that the Animator created by
+     * the transition will have its own specified duration. If the duration of a
+     * Transition is set, that duration will override the Animator duration.
+     *
+     * @param duration The length of the animation, in milliseconds.
+     * @return This transition object.
+     * @attr ref android.R.styleable#Transition_duration
+     */
+    public Transition setDuration(long duration) {
+        mDuration = duration;
+        return this;
+    }
+
+    /**
+     * Returns the duration set on this transition. If no duration has been set,
+     * the returned value will be negative, indicating that resulting animators will
+     * retain their own durations.
+     *
+     * @return The duration set on this transition, in milliseconds, if one has been
+     * set, otherwise returns a negative number.
+     */
+    public long getDuration() {
+        return mDuration;
+    }
+
+    /**
+     * Sets the startDelay of this transition. By default, there is no delay
+     * (indicated by a negative number), which means that the Animator created by
+     * the transition will have its own specified startDelay. If the delay of a
+     * Transition is set, that delay will override the Animator delay.
+     *
+     * @param startDelay The length of the delay, in milliseconds.
+     * @return This transition object.
+     * @attr ref android.R.styleable#Transition_startDelay
+     */
+    public Transition setStartDelay(long startDelay) {
+        mStartDelay = startDelay;
+        return this;
+    }
+
+    /**
+     * Returns the startDelay set on this transition. If no startDelay has been set,
+     * the returned value will be negative, indicating that resulting animators will
+     * retain their own startDelays.
+     *
+     * @return The startDelay set on this transition, in milliseconds, if one has
+     * been set, otherwise returns a negative number.
+     */
+    public long getStartDelay() {
+        return mStartDelay;
+    }
+
+    /**
+     * Sets the interpolator of this transition. By default, the interpolator
+     * is null, which means that the Animator created by the transition
+     * will have its own specified interpolator. If the interpolator of a
+     * Transition is set, that interpolator will override the Animator interpolator.
+     *
+     * @param interpolator The time interpolator used by the transition
+     * @return This transition object.
+     * @attr ref android.R.styleable#Transition_interpolator
+     */
+    public Transition setInterpolator(TimeInterpolator interpolator) {
+        mInterpolator = interpolator;
+        return this;
+    }
+
+    /**
+     * Returns the interpolator set on this transition. If no interpolator has been set,
+     * the returned value will be null, indicating that resulting animators will
+     * retain their own interpolators.
+     *
+     * @return The interpolator set on this transition, if one has been set, otherwise
+     * returns null.
+     */
+    public TimeInterpolator getInterpolator() {
+        return mInterpolator;
+    }
+
+    /**
+     * Returns the set of property names used stored in the {@link TransitionValues}
+     * object passed into {@link #captureStartValues(TransitionValues)} that
+     * this transition cares about for the purposes of canceling overlapping animations.
+     * When any transition is started on a given scene root, all transitions
+     * currently running on that same scene root are checked to see whether the
+     * properties on which they based their animations agree with the end values of
+     * the same properties in the new transition. If the end values are not equal,
+     * then the old animation is canceled since the new transition will start a new
+     * animation to these new values. If the values are equal, the old animation is
+     * allowed to continue and no new animation is started for that transition.
+     *
+     * <p>A transition does not need to override this method. However, not doing so
+     * will mean that the cancellation logic outlined in the previous paragraph
+     * will be skipped for that transition, possibly leading to artifacts as
+     * old transitions and new transitions on the same targets run in parallel,
+     * animating views toward potentially different end values.</p>
+     *
+     * @return An array of property names as described in the class documentation for
+     * {@link TransitionValues}. The default implementation returns <code>null</code>.
+     */
+    public String[] getTransitionProperties() {
+        return null;
+    }
+
+    /**
+     * This method creates an animation that will be run for this transition
+     * given the information in the startValues and endValues structures captured
+     * earlier for the start and end scenes. Subclasses of Transition should override
+     * this method. The method should only be called by the transition system; it is
+     * not intended to be called from external classes.
+     *
+     * <p>This method is called by the transition's parent (all the way up to the
+     * topmost Transition in the hierarchy) with the sceneRoot and start/end
+     * values that the transition may need to set up initial target values
+     * and construct an appropriate animation. For example, if an overall
+     * Transition is a {@link TransitionSet} consisting of several
+     * child transitions in sequence, then some of the child transitions may
+     * want to set initial values on target views prior to the overall
+     * Transition commencing, to put them in an appropriate state for the
+     * delay between that start and the child Transition start time. For
+     * example, a transition that fades an item in may wish to set the starting
+     * alpha value to 0, to avoid it blinking in prior to the transition
+     * actually starting the animation. This is necessary because the scene
+     * change that triggers the Transition will automatically set the end-scene
+     * on all target views, so a Transition that wants to animate from a
+     * different value should set that value prior to returning from this method.</p>
+     *
+     * <p>Additionally, a Transition can perform logic to determine whether
+     * the transition needs to run on the given target and start/end values.
+     * For example, a transition that resizes objects on the screen may wish
+     * to avoid running for views which are not present in either the start
+     * or end scenes.</p>
+     *
+     * <p>If there is an animator created and returned from this method, the
+     * transition mechanism will apply any applicable duration, startDelay,
+     * and interpolator to that animation and start it. A return value of
+     * <code>null</code> indicates that no animation should run. The default
+     * implementation returns null.</p>
+     *
+     * <p>The method is called for every applicable target object, which is
+     * stored in the {@link TransitionValues#view} field.</p>
+     *
+     *
+     * @param sceneRoot The root of the transition hierarchy.
+     * @param startValues The values for a specific target in the start scene.
+     * @param endValues The values for the target in the end scene.
+     * @return A Animator to be started at the appropriate time in the
+     * overall transition for this scene change. A null value means no animation
+     * should be run.
+     */
+    public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
+            TransitionValues endValues) {
+        return null;
+    }
+
+    /**
+     * This method, essentially a wrapper around all calls to createAnimator for all
+     * possible target views, is called with the entire set of start/end
+     * values. The implementation in Transition iterates through these lists
+     * and calls {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)}
+     * with each set of start/end values on this transition. The
+     * TransitionSet subclass overrides this method and delegates it to
+     * each of its children in succession.
+     *
+     * @hide
+     */
+    protected void createAnimators(ViewGroup sceneRoot, TransitionValuesMaps startValues,
+            TransitionValuesMaps endValues) {
+        if (DBG) {
+            Log.d(LOG_TAG, "createAnimators() for " + this);
+        }
+        ArrayMap<View, TransitionValues> endCopy =
+                new ArrayMap<View, TransitionValues>(endValues.viewValues);
+        SparseArray<TransitionValues> endIdCopy =
+                new SparseArray<TransitionValues>(endValues.idValues.size());
+        for (int i = 0; i < endValues.idValues.size(); ++i) {
+            int id = endValues.idValues.keyAt(i);
+            endIdCopy.put(id, endValues.idValues.valueAt(i));
+        }
+        LongSparseArray<TransitionValues> endItemIdCopy =
+                new LongSparseArray<TransitionValues>(endValues.itemIdValues.size());
+        for (int i = 0; i < endValues.itemIdValues.size(); ++i) {
+            long id = endValues.itemIdValues.keyAt(i);
+            endItemIdCopy.put(id, endValues.itemIdValues.valueAt(i));
+        }
+        // Walk through the start values, playing everything we find
+        // Remove from the end set as we go
+        ArrayList<TransitionValues> startValuesList = new ArrayList<TransitionValues>();
+        ArrayList<TransitionValues> endValuesList = new ArrayList<TransitionValues>();
+        for (View view : startValues.viewValues.keySet()) {
+            TransitionValues start = null;
+            TransitionValues end = null;
+            boolean isInListView = false;
+            if (view.getParent() instanceof ListView) {
+                isInListView = true;
+            }
+            if (!isInListView) {
+                int id = view.getId();
+                start = startValues.viewValues.get(view) != null ?
+                        startValues.viewValues.get(view) : startValues.idValues.get(id);
+                if (endValues.viewValues.get(view) != null) {
+                    end = endValues.viewValues.get(view);
+                    endCopy.remove(view);
+                } else {
+                    end = endValues.idValues.get(id);
+                    View removeView = null;
+                    for (View viewToRemove : endCopy.keySet()) {
+                        if (viewToRemove.getId() == id) {
+                            removeView = viewToRemove;
+                        }
+                    }
+                    if (removeView != null) {
+                        endCopy.remove(removeView);
+                    }
+                }
+                endIdCopy.remove(id);
+                if (isValidTarget(view, id)) {
+                    startValuesList.add(start);
+                    endValuesList.add(end);
+                }
+            } else {
+                ListView parent = (ListView) view.getParent();
+                if (parent.getAdapter().hasStableIds()) {
+                    int position = parent.getPositionForView(view);
+                    long itemId = parent.getItemIdAtPosition(position);
+                    start = startValues.itemIdValues.get(itemId);
+                    endItemIdCopy.remove(itemId);
+                    // TODO: deal with targetIDs for itemIDs for ListView items
+                    startValuesList.add(start);
+                    endValuesList.add(end);
+                }
+            }
+        }
+        int startItemIdCopySize = startValues.itemIdValues.size();
+        for (int i = 0; i < startItemIdCopySize; ++i) {
+            long id = startValues.itemIdValues.keyAt(i);
+            if (isValidTarget(null, id)) {
+                TransitionValues start = startValues.itemIdValues.get(id);
+                TransitionValues end = endValues.itemIdValues.get(id);
+                endItemIdCopy.remove(id);
+                startValuesList.add(start);
+                endValuesList.add(end);
+            }
+        }
+        // Now walk through the remains of the end set
+        for (View view : endCopy.keySet()) {
+            int id = view.getId();
+            if (isValidTarget(view, id)) {
+                TransitionValues start = startValues.viewValues.get(view) != null ?
+                        startValues.viewValues.get(view) : startValues.idValues.get(id);
+                TransitionValues end = endCopy.get(view);
+                endIdCopy.remove(id);
+                startValuesList.add(start);
+                endValuesList.add(end);
+            }
+        }
+        int endIdCopySize = endIdCopy.size();
+        for (int i = 0; i < endIdCopySize; ++i) {
+            int id = endIdCopy.keyAt(i);
+            if (isValidTarget(null, id)) {
+                TransitionValues start = startValues.idValues.get(id);
+                TransitionValues end = endIdCopy.get(id);
+                startValuesList.add(start);
+                endValuesList.add(end);
+            }
+        }
+        int endItemIdCopySize = endItemIdCopy.size();
+        for (int i = 0; i < endItemIdCopySize; ++i) {
+            long id = endItemIdCopy.keyAt(i);
+            // TODO: Deal with targetIDs and itemIDs
+            TransitionValues start = startValues.itemIdValues.get(id);
+            TransitionValues end = endItemIdCopy.get(id);
+            startValuesList.add(start);
+            endValuesList.add(end);
+        }
+        ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
+        for (int i = 0; i < startValuesList.size(); ++i) {
+            TransitionValues start = startValuesList.get(i);
+            TransitionValues end = endValuesList.get(i);
+            // Only bother trying to animate with values that differ between start/end
+            if (start != null || end != null) {
+                if (start == null || !start.equals(end)) {
+                    if (DBG) {
+                        View view = (end != null) ? end.view : start.view;
+                        Log.d(LOG_TAG, "  differing start/end values for view " +
+                                view);
+                        if (start == null || end == null) {
+                            Log.d(LOG_TAG, "    " + ((start == null) ?
+                                    "start null, end non-null" : "start non-null, end null"));
+                        } else {
+                            for (String key : start.values.keySet()) {
+                                Object startValue = start.values.get(key);
+                                Object endValue = end.values.get(key);
+                                if (startValue != endValue && !startValue.equals(endValue)) {
+                                    Log.d(LOG_TAG, "    " + key + ": start(" + startValue +
+                                            "), end(" + endValue +")");
+                                }
+                            }
+                        }
+                    }
+                    // TODO: what to do about targetIds and itemIds?
+                    Animator animator = createAnimator(sceneRoot, start, end);
+                    if (animator != null) {
+                        // Save animation info for future cancellation purposes
+                        View view = null;
+                        TransitionValues infoValues = null;
+                        if (end != null) {
+                            view = end.view;
+                            String[] properties = getTransitionProperties();
+                            if (view != null && properties != null && properties.length > 0) {
+                                infoValues = new TransitionValues();
+                                infoValues.view = view;
+                                TransitionValues newValues = endValues.viewValues.get(view);
+                                if (newValues != null) {
+                                    for (int j = 0; j < properties.length; ++j) {
+                                        infoValues.values.put(properties[j],
+                                                newValues.values.get(properties[j]));
+                                    }
+                                }
+                                int numExistingAnims = runningAnimators.size();
+                                for (int j = 0; j < numExistingAnims; ++j) {
+                                    Animator anim = runningAnimators.keyAt(j);
+                                    AnimationInfo info = runningAnimators.get(anim);
+                                    if (info.values != null && info.view == view &&
+                                            ((info.name == null && getName() == null) ||
+                                            info.name.equals(getName()))) {
+                                        if (info.values.equals(infoValues)) {
+                                            // Favor the old animator
+                                            animator = null;
+                                            break;
+                                        }
+                                    }
+                                }
+                            }
+                        } else {
+                            view = (start != null) ? start.view : null;
+                        }
+                        if (animator != null) {
+                            AnimationInfo info = new AnimationInfo(view, getName(), infoValues);
+                            runningAnimators.put(animator, info);
+                            mAnimators.add(animator);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Internal utility method for checking whether a given view/id
+     * is valid for this transition, where "valid" means that either
+     * the Transition has no target/targetId list (the default, in which
+     * cause the transition should act on all views in the hiearchy), or
+     * the given view is in the target list or the view id is in the
+     * targetId list. If the target parameter is null, then the target list
+     * is not checked (this is in the case of ListView items, where the
+     * views are ignored and only the ids are used).
+     */
+    boolean isValidTarget(View target, long targetId) {
+        if (mTargetIdExcludes != null && mTargetIdExcludes.contains(targetId)) {
+            return false;
+        }
+        if (mTargetExcludes != null && mTargetExcludes.contains(target)) {
+            return false;
+        }
+        if (mTargetTypeExcludes != null && target != null) {
+            int numTypes = mTargetTypeExcludes.size();
+            for (int i = 0; i < numTypes; ++i) {
+                Class type = mTargetTypeExcludes.get(i);
+                if (type.isInstance(target)) {
+                    return false;
+                }
+            }
+        }
+        if (mTargetIds.size() == 0 && mTargets.size() == 0) {
+            return true;
+        }
+        if (mTargetIds.size() > 0) {
+            for (int i = 0; i < mTargetIds.size(); ++i) {
+                if (mTargetIds.get(i) == targetId) {
+                    return true;
+                }
+            }
+        }
+        if (target != null && mTargets.size() > 0) {
+            for (int i = 0; i < mTargets.size(); ++i) {
+                if (mTargets.get(i) == target) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private static ArrayMap<Animator, AnimationInfo> getRunningAnimators() {
+        ArrayMap<Animator, AnimationInfo> runningAnimators = sRunningAnimators.get();
+        if (runningAnimators == null) {
+            runningAnimators = new ArrayMap<Animator, AnimationInfo>();
+            sRunningAnimators.set(runningAnimators);
+        }
+        return runningAnimators;
+    }
+
+    /**
+     * This is called internally once all animations have been set up by the
+     * transition hierarchy. \
+     *
+     * @hide
+     */
+    protected void runAnimators() {
+        if (DBG) {
+            Log.d(LOG_TAG, "runAnimators() on " + this);
+        }
+        start();
+        ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
+        // Now start every Animator that was previously created for this transition
+        for (Animator anim : mAnimators) {
+            if (DBG) {
+                Log.d(LOG_TAG, "  anim: " + anim);
+            }
+            if (runningAnimators.containsKey(anim)) {
+                start();
+                runAnimator(anim, runningAnimators);
+            }
+        }
+        mAnimators.clear();
+        end();
+    }
+
+    private void runAnimator(Animator animator,
+            final ArrayMap<Animator, AnimationInfo> runningAnimators) {
+        if (animator != null) {
+            // TODO: could be a single listener instance for all of them since it uses the param
+            animator.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationStart(Animator animation) {
+                    mCurrentAnimators.add(animation);
+                }
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    runningAnimators.remove(animation);
+                    mCurrentAnimators.remove(animation);
+                }
+            });
+            animate(animator);
+        }
+    }
+
+    /**
+     * Captures the values in the start scene for the properties that this
+     * transition monitors. These values are then passed as the startValues
+     * structure in a later call to
+     * {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)}.
+     * The main concern for an implementation is what the
+     * properties are that the transition cares about and what the values are
+     * for all of those properties. The start and end values will be compared
+     * later during the
+     * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues)}
+     * method to determine what, if any, animations, should be run.
+     *
+     * <p>Subclasses must implement this method. The method should only be called by the
+     * transition system; it is not intended to be called from external classes.</p>
+     *
+     * @param transitionValues The holder for any values that the Transition
+     * wishes to store. Values are stored in the <code>values</code> field
+     * of this TransitionValues object and are keyed from
+     * a String value. For example, to store a view's rotation value,
+     * a transition might call
+     * <code>transitionValues.values.put("appname:transitionname:rotation",
+     * view.getRotation())</code>. The target view will already be stored in
+     * the transitionValues structure when this method is called.
+     *
+     * @see #captureEndValues(TransitionValues)
+     * @see #createAnimator(ViewGroup, TransitionValues, TransitionValues)
+     */
+    public abstract void captureStartValues(TransitionValues transitionValues);
+
+    /**
+     * Captures the values in the end scene for the properties that this
+     * transition monitors. These values are then passed as the endValues
+     * structure in a later call to
+     * {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)}.
+     * The main concern for an implementation is what the
+     * properties are that the transition cares about and what the values are
+     * for all of those properties. The start and end values will be compared
+     * later during the
+     * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues)}
+     * method to determine what, if any, animations, should be run.
+     *
+     * <p>Subclasses must implement this method. The method should only be called by the
+     * transition system; it is not intended to be called from external classes.</p>
+     *
+     * @param transitionValues The holder for any values that the Transition
+     * wishes to store. Values are stored in the <code>values</code> field
+     * of this TransitionValues object and are keyed from
+     * a String value. For example, to store a view's rotation value,
+     * a transition might call
+     * <code>transitionValues.values.put("appname:transitionname:rotation",
+     * view.getRotation())</code>. The target view will already be stored in
+     * the transitionValues structure when this method is called.
+     *
+     * @see #captureStartValues(TransitionValues)
+     * @see #createAnimator(ViewGroup, TransitionValues, TransitionValues)
+     */
+    public abstract void captureEndValues(TransitionValues transitionValues);
+
+    /**
+     * Adds the id of a target view that this Transition is interested in
+     * animating. By default, there are no targetIds, and a Transition will
+     * listen for changes on every view in the hierarchy below the sceneRoot
+     * of the Scene being transitioned into. Setting targetIds constrains
+     * the Transition to only listen for, and act on, views with these IDs.
+     * Views with different IDs, or no IDs whatsoever, will be ignored.
+     *
+     * <p>Note that using ids to specify targets implies that ids should be unique
+     * within the view hierarchy underneat the scene root.</p>
+     *
+     * @see View#getId()
+     * @param targetId The id of a target view, must be a positive number.
+     * @return The Transition to which the targetId is added.
+     * Returning the same object makes it easier to chain calls during
+     * construction, such as
+     * <code>transitionSet.addTransitions(new Fade()).addTarget(someId);</code>
+     */
+    public Transition addTarget(int targetId) {
+        if (targetId > 0) {
+            mTargetIds.add(targetId);
+        }
+        return this;
+    }
+
+    /**
+     * Removes the given targetId from the list of ids that this Transition
+     * is interested in animating.
+     *
+     * @param targetId The id of a target view, must be a positive number.
+     * @return The Transition from which the targetId is removed.
+     * Returning the same object makes it easier to chain calls during
+     * construction, such as
+     * <code>transitionSet.addTransitions(new Fade()).removeTargetId(someId);</code>
+     */
+    public Transition removeTarget(int targetId) {
+        if (targetId > 0) {
+            mTargetIds.remove(targetId);
+        }
+        return this;
+    }
+
+    /**
+     * Whether to add the given id to the list of target ids to exclude from this
+     * transition. The <code>exclude</code> parameter specifies whether the target
+     * should be added to or removed from the excluded list.
+     *
+     * <p>Excluding targets is a general mechanism for allowing transitions to run on
+     * a view hierarchy while skipping target views that should not be part of
+     * the transition. For example, you may want to avoid animating children
+     * of a specific ListView or Spinner. Views can be excluded either by their
+     * id, or by their instance reference, or by the Class of that view
+     * (eg, {@link Spinner}).</p>
+     *
+     * @see #excludeChildren(int, boolean)
+     * @see #excludeTarget(View, boolean)
+     * @see #excludeTarget(Class, boolean)
+     *
+     * @param targetId The id of a target to ignore when running this transition.
+     * @param exclude Whether to add the target to or remove the target from the
+     * current list of excluded targets.
+     * @return This transition object.
+     */
+    public Transition excludeTarget(int targetId, boolean exclude) {
+        mTargetIdExcludes = excludeId(mTargetIdExcludes, targetId, exclude);
+        return this;
+    }
+
+    /**
+     * Whether to add the children of the given id to the list of targets to exclude
+     * from this transition. The <code>exclude</code> parameter specifies whether
+     * the children of the target should be added to or removed from the excluded list.
+     * Excluding children in this way provides a simple mechanism for excluding all
+     * children of specific targets, rather than individually excluding each
+     * child individually.
+     *
+     * <p>Excluding targets is a general mechanism for allowing transitions to run on
+     * a view hierarchy while skipping target views that should not be part of
+     * the transition. For example, you may want to avoid animating children
+     * of a specific ListView or Spinner. Views can be excluded either by their
+     * id, or by their instance reference, or by the Class of that view
+     * (eg, {@link Spinner}).</p>
+     *
+     * @see #excludeTarget(int, boolean)
+     * @see #excludeChildren(View, boolean)
+     * @see #excludeChildren(Class, boolean)
+     *
+     * @param targetId The id of a target whose children should be ignored when running
+     * this transition.
+     * @param exclude Whether to add the target to or remove the target from the
+     * current list of excluded-child targets.
+     * @return This transition object.
+     */
+    public Transition excludeChildren(int targetId, boolean exclude) {
+        mTargetIdChildExcludes = excludeId(mTargetIdChildExcludes, targetId, exclude);
+        return this;
+    }
+
+    /**
+     * Utility method to manage the boilerplate code that is the same whether we
+     * are excluding targets or their children.
+     */
+    private ArrayList<Integer> excludeId(ArrayList<Integer> list, int targetId, boolean exclude) {
+        if (targetId > 0) {
+            if (exclude) {
+                list = ArrayListManager.add(list, targetId);
+            } else {
+                list = ArrayListManager.remove(list, targetId);
+            }
+        }
+        return list;
+    }
+
+    /**
+     * Whether to add the given target to the list of targets to exclude from this
+     * transition. The <code>exclude</code> parameter specifies whether the target
+     * should be added to or removed from the excluded list.
+     *
+     * <p>Excluding targets is a general mechanism for allowing transitions to run on
+     * a view hierarchy while skipping target views that should not be part of
+     * the transition. For example, you may want to avoid animating children
+     * of a specific ListView or Spinner. Views can be excluded either by their
+     * id, or by their instance reference, or by the Class of that view
+     * (eg, {@link Spinner}).</p>
+     *
+     * @see #excludeChildren(View, boolean)
+     * @see #excludeTarget(int, boolean)
+     * @see #excludeTarget(Class, boolean)
+     *
+     * @param target The target to ignore when running this transition.
+     * @param exclude Whether to add the target to or remove the target from the
+     * current list of excluded targets.
+     * @return This transition object.
+     */
+    public Transition excludeTarget(View target, boolean exclude) {
+        mTargetExcludes = excludeView(mTargetExcludes, target, exclude);
+        return this;
+    }
+
+    /**
+     * Whether to add the children of given target to the list of target children
+     * to exclude from this transition. The <code>exclude</code> parameter specifies
+     * whether the target should be added to or removed from the excluded list.
+     *
+     * <p>Excluding targets is a general mechanism for allowing transitions to run on
+     * a view hierarchy while skipping target views that should not be part of
+     * the transition. For example, you may want to avoid animating children
+     * of a specific ListView or Spinner. Views can be excluded either by their
+     * id, or by their instance reference, or by the Class of that view
+     * (eg, {@link Spinner}).</p>
+     *
+     * @see #excludeTarget(View, boolean)
+     * @see #excludeChildren(int, boolean)
+     * @see #excludeChildren(Class, boolean)
+     *
+     * @param target The target to ignore when running this transition.
+     * @param exclude Whether to add the target to or remove the target from the
+     * current list of excluded targets.
+     * @return This transition object.
+     */
+    public Transition excludeChildren(View target, boolean exclude) {
+        mTargetChildExcludes = excludeView(mTargetChildExcludes, target, exclude);
+        return this;
+    }
+
+    /**
+     * Utility method to manage the boilerplate code that is the same whether we
+     * are excluding targets or their children.
+     */
+    private ArrayList<View> excludeView(ArrayList<View> list, View target, boolean exclude) {
+        if (target != null) {
+            if (exclude) {
+                list = ArrayListManager.add(list, target);
+            } else {
+                list = ArrayListManager.remove(list, target);
+            }
+        }
+        return list;
+    }
+
+    /**
+     * Whether to add the given type to the list of types to exclude from this
+     * transition. The <code>exclude</code> parameter specifies whether the target
+     * type should be added to or removed from the excluded list.
+     *
+     * <p>Excluding targets is a general mechanism for allowing transitions to run on
+     * a view hierarchy while skipping target views that should not be part of
+     * the transition. For example, you may want to avoid animating children
+     * of a specific ListView or Spinner. Views can be excluded either by their
+     * id, or by their instance reference, or by the Class of that view
+     * (eg, {@link Spinner}).</p>
+     *
+     * @see #excludeChildren(Class, boolean)
+     * @see #excludeTarget(int, boolean)
+     * @see #excludeTarget(View, boolean)
+     *
+     * @param type The type to ignore when running this transition.
+     * @param exclude Whether to add the target type to or remove it from the
+     * current list of excluded target types.
+     * @return This transition object.
+     */
+    public Transition excludeTarget(Class type, boolean exclude) {
+        mTargetTypeExcludes = excludeType(mTargetTypeExcludes, type, exclude);
+        return this;
+    }
+
+    /**
+     * Whether to add the given type to the list of types whose children should
+     * be excluded from this transition. The <code>exclude</code> parameter
+     * specifies whether the target type should be added to or removed from
+     * the excluded list.
+     *
+     * <p>Excluding targets is a general mechanism for allowing transitions to run on
+     * a view hierarchy while skipping target views that should not be part of
+     * the transition. For example, you may want to avoid animating children
+     * of a specific ListView or Spinner. Views can be excluded either by their
+     * id, or by their instance reference, or by the Class of that view
+     * (eg, {@link Spinner}).</p>
+     *
+     * @see #excludeTarget(Class, boolean)
+     * @see #excludeChildren(int, boolean)
+     * @see #excludeChildren(View, boolean)
+     *
+     * @param type The type to ignore when running this transition.
+     * @param exclude Whether to add the target type to or remove it from the
+     * current list of excluded target types.
+     * @return This transition object.
+     */
+    public Transition excludeChildren(Class type, boolean exclude) {
+        mTargetTypeChildExcludes = excludeType(mTargetTypeChildExcludes, type, exclude);
+        return this;
+    }
+
+    /**
+     * Utility method to manage the boilerplate code that is the same whether we
+     * are excluding targets or their children.
+     */
+    private ArrayList<Class> excludeType(ArrayList<Class> list, Class type, boolean exclude) {
+        if (type != null) {
+            if (exclude) {
+                list = ArrayListManager.add(list, type);
+            } else {
+                list = ArrayListManager.remove(list, type);
+            }
+        }
+        return list;
+    }
+
+    /**
+     * Sets the target view instances that this Transition is interested in
+     * animating. By default, there are no targets, and a Transition will
+     * listen for changes on every view in the hierarchy below the sceneRoot
+     * of the Scene being transitioned into. Setting targets constrains
+     * the Transition to only listen for, and act on, these views.
+     * All other views will be ignored.
+     *
+     * <p>The target list is like the {@link #addTarget(int) targetId}
+     * list except this list specifies the actual View instances, not the ids
+     * of the views. This is an important distinction when scene changes involve
+     * view hierarchies which have been inflated separately; different views may
+     * share the same id but not actually be the same instance. If the transition
+     * should treat those views as the same, then {@link #addTarget(int)} should be used
+     * instead of {@link #addTarget(View)}. If, on the other hand, scene changes involve
+     * changes all within the same view hierarchy, among views which do not
+     * necessarily have ids set on them, then the target list of views may be more
+     * convenient.</p>
+     *
+     * @see #addTarget(int)
+     * @param target A View on which the Transition will act, must be non-null.
+     * @return The Transition to which the target is added.
+     * Returning the same object makes it easier to chain calls during
+     * construction, such as
+     * <code>transitionSet.addTransitions(new Fade()).addTarget(someView);</code>
+     */
+    public Transition addTarget(View target) {
+        mTargets.add(target);
+        return this;
+    }
+
+    /**
+     * Removes the given target from the list of targets that this Transition
+     * is interested in animating.
+     *
+     * @param target The target view, must be non-null.
+     * @return Transition The Transition from which the target is removed.
+     * Returning the same object makes it easier to chain calls during
+     * construction, such as
+     * <code>transitionSet.addTransitions(new Fade()).removeTarget(someView);</code>
+     */
+    public Transition removeTarget(View target) {
+        if (target != null) {
+            mTargets.remove(target);
+        }
+        return this;
+    }
+
+    /**
+     * Returns the array of target IDs that this transition limits itself to
+     * tracking and animating. If the array is null for both this method and
+     * {@link #getTargets()}, then this transition is
+     * not limited to specific views, and will handle changes to any views
+     * in the hierarchy of a scene change.
+     *
+     * @return the list of target IDs
+     */
+    public List<Integer> getTargetIds() {
+        return mTargetIds;
+    }
+
+    /**
+     * Returns the array of target views that this transition limits itself to
+     * tracking and animating. If the array is null for both this method and
+     * {@link #getTargetIds()}, then this transition is
+     * not limited to specific views, and will handle changes to any views
+     * in the hierarchy of a scene change.
+     *
+     * @return the list of target views
+     */
+    public List<View> getTargets() {
+        return mTargets;
+    }
+
+    /**
+     * Recursive method that captures values for the given view and the
+     * hierarchy underneath it.
+     * @param sceneRoot The root of the view hierarchy being captured
+     * @param start true if this capture is happening before the scene change,
+     * false otherwise
+     */
+    void captureValues(ViewGroup sceneRoot, boolean start) {
+        if (start) {
+            mStartValues.viewValues.clear();
+            mStartValues.idValues.clear();
+            mStartValues.itemIdValues.clear();
+        } else {
+            mEndValues.viewValues.clear();
+            mEndValues.idValues.clear();
+            mEndValues.itemIdValues.clear();
+        }
+        if (mTargetIds.size() > 0 || mTargets.size() > 0) {
+            if (mTargetIds.size() > 0) {
+                for (int i = 0; i < mTargetIds.size(); ++i) {
+                    int id = mTargetIds.get(i);
+                    View view = sceneRoot.findViewById(id);
+                    if (view != null) {
+                        TransitionValues values = new TransitionValues();
+                        values.view = view;
+                        if (start) {
+                            captureStartValues(values);
+                        } else {
+                            captureEndValues(values);
+                        }
+                        if (start) {
+                            mStartValues.viewValues.put(view, values);
+                            if (id >= 0) {
+                                mStartValues.idValues.put(id, values);
+                            }
+                        } else {
+                            mEndValues.viewValues.put(view, values);
+                            if (id >= 0) {
+                                mEndValues.idValues.put(id, values);
+                            }
+                        }
+                    }
+                }
+            }
+            if (mTargets.size() > 0) {
+                for (int i = 0; i < mTargets.size(); ++i) {
+                    View view = mTargets.get(i);
+                    if (view != null) {
+                        TransitionValues values = new TransitionValues();
+                        values.view = view;
+                        if (start) {
+                            captureStartValues(values);
+                        } else {
+                            captureEndValues(values);
+                        }
+                        if (start) {
+                            mStartValues.viewValues.put(view, values);
+                        } else {
+                            mEndValues.viewValues.put(view, values);
+                        }
+                    }
+                }
+            }
+        } else {
+            captureHierarchy(sceneRoot, start);
+        }
+    }
+
+    /**
+     * Recursive method which captures values for an entire view hierarchy,
+     * starting at some root view. Transitions without targetIDs will use this
+     * method to capture values for all possible views.
+     *
+     * @param view The view for which to capture values. Children of this View
+     * will also be captured, recursively down to the leaf nodes.
+     * @param start true if values are being captured in the start scene, false
+     * otherwise.
+     */
+    private void captureHierarchy(View view, boolean start) {
+        if (view == null) {
+            return;
+        }
+        boolean isListViewItem = false;
+        if (view.getParent() instanceof ListView) {
+            isListViewItem = true;
+        }
+        if (isListViewItem && !((ListView) view.getParent()).getAdapter().hasStableIds()) {
+            // ignore listview children unless we can track them with stable IDs
+            return;
+        }
+        int id = View.NO_ID;
+        long itemId = View.NO_ID;
+        if (!isListViewItem) {
+            id = view.getId();
+        } else {
+            ListView listview = (ListView) view.getParent();
+            int position = listview.getPositionForView(view);
+            itemId = listview.getItemIdAtPosition(position);
+            view.setHasTransientState(true);
+        }
+        if (mTargetIdExcludes != null && mTargetIdExcludes.contains(id)) {
+            return;
+        }
+        if (mTargetExcludes != null && mTargetExcludes.contains(view)) {
+            return;
+        }
+        if (mTargetTypeExcludes != null && view != null) {
+            int numTypes = mTargetTypeExcludes.size();
+            for (int i = 0; i < numTypes; ++i) {
+                if (mTargetTypeExcludes.get(i).isInstance(view)) {
+                    return;
+                }
+            }
+        }
+        TransitionValues values = new TransitionValues();
+        values.view = view;
+        captureStartValues(values);
+        if (start) {
+            if (!isListViewItem) {
+                mStartValues.viewValues.put(view, values);
+                if (id >= 0) {
+                    mStartValues.idValues.put((int) id, values);
+                }
+            } else {
+                mStartValues.itemIdValues.put(itemId, values);
+            }
+        } else {
+            if (!isListViewItem) {
+                mEndValues.viewValues.put(view, values);
+                if (id >= 0) {
+                    mEndValues.idValues.put((int) id, values);
+                }
+            } else {
+                mEndValues.itemIdValues.put(itemId, values);
+            }
+        }
+        if (view instanceof ViewGroup) {
+            // Don't traverse child hierarchy if there are any child-excludes on this view
+            if (mTargetIdChildExcludes != null && mTargetIdChildExcludes.contains(id)) {
+                return;
+            }
+            if (mTargetChildExcludes != null && mTargetChildExcludes.contains(view)) {
+                return;
+            }
+            if (mTargetTypeChildExcludes != null && view != null) {
+                int numTypes = mTargetTypeChildExcludes.size();
+                for (int i = 0; i < numTypes; ++i) {
+                    if (mTargetTypeChildExcludes.get(i).isInstance(view)) {
+                        return;
+                    }
+                }
+            }
+            ViewGroup parent = (ViewGroup) view;
+            for (int i = 0; i < parent.getChildCount(); ++i) {
+                captureHierarchy(parent.getChildAt(i), start);
+            }
+        }
+    }
+
+    /**
+     * This method can be called by transitions to get the TransitionValues for
+     * any particular view during the transition-playing process. This might be
+     * necessary, for example, to query the before/after state of related views
+     * for a given transition.
+     */
+    public TransitionValues getTransitionValues(View view, boolean start) {
+        if (mParent != null) {
+            return mParent.getTransitionValues(view, start);
+        }
+        TransitionValuesMaps valuesMaps = start ? mStartValues : mEndValues;
+        TransitionValues values = valuesMaps.viewValues.get(view);
+        if (values == null) {
+            int id = view.getId();
+            if (id >= 0) {
+                values = valuesMaps.idValues.get(id);
+            }
+            if (values == null && view.getParent() instanceof ListView) {
+                ListView listview = (ListView) view.getParent();
+                int position = listview.getPositionForView(view);
+                long itemId = listview.getItemIdAtPosition(position);
+                values = valuesMaps.itemIdValues.get(itemId);
+            }
+            // TODO: Doesn't handle the case where a view was parented to a
+            // ListView (with an itemId), but no longer is
+        }
+        return values;
+    }
+
+    /**
+     * Pauses this transition, sending out calls to {@link
+     * TransitionListener#onTransitionPause(Transition)} to all listeners
+     * and pausing all running animators started by this transition.
+     *
+     * @hide
+     */
+    public void pause() {
+        if (!mEnded) {
+            ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
+            int numOldAnims = runningAnimators.size();
+            for (int i = numOldAnims - 1; i >= 0; i--) {
+                Animator anim = runningAnimators.keyAt(i);
+                anim.pause();
+            }
+            if (mListeners != null && mListeners.size() > 0) {
+                ArrayList<TransitionListener> tmpListeners =
+                        (ArrayList<TransitionListener>) mListeners.clone();
+                int numListeners = tmpListeners.size();
+                for (int i = 0; i < numListeners; ++i) {
+                    tmpListeners.get(i).onTransitionPause(this);
+                }
+            }
+            mPaused = true;
+        }
+    }
+
+    /**
+     * Resumes this transition, sending out calls to {@link
+     * TransitionListener#onTransitionPause(Transition)} to all listeners
+     * and pausing all running animators started by this transition.
+     *
+     * @hide
+     */
+    public void resume() {
+        if (mPaused) {
+            if (!mEnded) {
+                ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
+                int numOldAnims = runningAnimators.size();
+                for (int i = numOldAnims - 1; i >= 0; i--) {
+                    Animator anim = runningAnimators.keyAt(i);
+                    anim.resume();
+                }
+                if (mListeners != null && mListeners.size() > 0) {
+                    ArrayList<TransitionListener> tmpListeners =
+                            (ArrayList<TransitionListener>) mListeners.clone();
+                    int numListeners = tmpListeners.size();
+                    for (int i = 0; i < numListeners; ++i) {
+                        tmpListeners.get(i).onTransitionResume(this);
+                    }
+                }
+            }
+            mPaused = false;
+        }
+    }
+
+    /**
+     * Called by TransitionManager to play the transition. This calls
+     * createAnimators() to set things up and create all of the animations and then
+     * runAnimations() to actually start the animations.
+     */
+    void playTransition(ViewGroup sceneRoot) {
+        ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
+        int numOldAnims = runningAnimators.size();
+        for (int i = numOldAnims - 1; i >= 0; i--) {
+            Animator anim = runningAnimators.keyAt(i);
+            if (anim != null) {
+                AnimationInfo oldInfo = runningAnimators.get(anim);
+                if (oldInfo != null) {
+                    boolean cancel = false;
+                    TransitionValues oldValues = oldInfo.values;
+                    View oldView = oldInfo.view;
+                    TransitionValues newValues = mEndValues.viewValues != null ?
+                            mEndValues.viewValues.get(oldView) : null;
+                    if (oldValues != null) {
+                        // if oldValues null, then transition didn't care to stash values,
+                        // and won't get canceled
+                        if (newValues == null) {
+                            cancel = true;
+                        } else {
+                            for (String key : oldValues.values.keySet()) {
+                                Object oldValue = oldValues.values.get(key);
+                                Object newValue = newValues.values.get(key);
+                                if (oldValue != null && newValue != null &&
+                                        !oldValue.equals(newValue)) {
+                                    cancel = true;
+                                    if (DBG) {
+                                        Log.d(LOG_TAG, "Transition.playTransition: " +
+                                                "oldValue != newValue for " + key +
+                                                ": old, new = " + oldValue + ", " + newValue);
+                                    }
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                    if (cancel) {
+                        if (anim.isRunning() || anim.isStarted()) {
+                            if (DBG) {
+                                Log.d(LOG_TAG, "Canceling anim " + anim);
+                            }
+                            anim.cancel();
+                        } else {
+                            if (DBG) {
+                                Log.d(LOG_TAG, "removing anim from info list: " + anim);
+                            }
+                            runningAnimators.remove(anim);
+                        }
+                    }
+                }
+            }
+        }
+
+        createAnimators(sceneRoot, mStartValues, mEndValues);
+        runAnimators();
+    }
+
+    /**
+     * This is a utility method used by subclasses to handle standard parts of
+     * setting up and running an Animator: it sets the {@link #getDuration()
+     * duration} and the {@link #getStartDelay() startDelay}, starts the
+     * animation, and, when the animator ends, calls {@link #end()}.
+     *
+     * @param animator The Animator to be run during this transition.
+     *
+     * @hide
+     */
+    protected void animate(Animator animator) {
+        // TODO: maybe pass auto-end as a boolean parameter?
+        if (animator == null) {
+            end();
+        } else {
+            if (getDuration() >= 0) {
+                animator.setDuration(getDuration());
+            }
+            if (getStartDelay() >= 0) {
+                animator.setStartDelay(getStartDelay());
+            }
+            if (getInterpolator() != null) {
+                animator.setInterpolator(getInterpolator());
+            }
+            animator.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    end();
+                    animation.removeListener(this);
+                }
+            });
+            animator.start();
+        }
+    }
+
+    /**
+     * This method is called automatically by the transition and
+     * TransitionSet classes prior to a Transition subclass starting;
+     * subclasses should not need to call it directly.
+     *
+     * @hide
+     */
+    protected void start() {
+        if (mNumInstances == 0) {
+            if (mListeners != null && mListeners.size() > 0) {
+                ArrayList<TransitionListener> tmpListeners =
+                        (ArrayList<TransitionListener>) mListeners.clone();
+                int numListeners = tmpListeners.size();
+                for (int i = 0; i < numListeners; ++i) {
+                    tmpListeners.get(i).onTransitionStart(this);
+                }
+            }
+            mEnded = false;
+        }
+        mNumInstances++;
+    }
+
+    /**
+     * This method is called automatically by the Transition and
+     * TransitionSet classes when a transition finishes, either because
+     * a transition did nothing (returned a null Animator from
+     * {@link Transition#createAnimator(ViewGroup, TransitionValues,
+     * TransitionValues)}) or because the transition returned a valid
+     * Animator and end() was called in the onAnimationEnd()
+     * callback of the AnimatorListener.
+     *
+     * @hide
+     */
+    protected void end() {
+        --mNumInstances;
+        if (mNumInstances == 0) {
+            if (mListeners != null && mListeners.size() > 0) {
+                ArrayList<TransitionListener> tmpListeners =
+                        (ArrayList<TransitionListener>) mListeners.clone();
+                int numListeners = tmpListeners.size();
+                for (int i = 0; i < numListeners; ++i) {
+                    tmpListeners.get(i).onTransitionEnd(this);
+                }
+            }
+            for (int i = 0; i < mStartValues.itemIdValues.size(); ++i) {
+                TransitionValues tv = mStartValues.itemIdValues.valueAt(i);
+                View v = tv.view;
+                if (v.hasTransientState()) {
+                    v.setHasTransientState(false);
+                }
+            }
+            for (int i = 0; i < mEndValues.itemIdValues.size(); ++i) {
+                TransitionValues tv = mEndValues.itemIdValues.valueAt(i);
+                View v = tv.view;
+                if (v.hasTransientState()) {
+                    v.setHasTransientState(false);
+                }
+            }
+            mEnded = true;
+        }
+    }
+
+    /**
+     * This method cancels a transition that is currently running.
+     *
+     * @hide
+     */
+    protected void cancel() {
+        int numAnimators = mCurrentAnimators.size();
+        for (int i = numAnimators - 1; i >= 0; i--) {
+            Animator animator = mCurrentAnimators.get(i);
+            animator.cancel();
+        }
+        if (mListeners != null && mListeners.size() > 0) {
+            ArrayList<TransitionListener> tmpListeners =
+                    (ArrayList<TransitionListener>) mListeners.clone();
+            int numListeners = tmpListeners.size();
+            for (int i = 0; i < numListeners; ++i) {
+                tmpListeners.get(i).onTransitionCancel(this);
+            }
+        }
+    }
+
+    /**
+     * Adds a listener to the set of listeners that are sent events through the
+     * life of an animation, such as start, repeat, and end.
+     *
+     * @param listener the listener to be added to the current set of listeners
+     * for this animation.
+     * @return This transition object.
+     */
+    public Transition addListener(TransitionListener listener) {
+        if (mListeners == null) {
+            mListeners = new ArrayList<TransitionListener>();
+        }
+        mListeners.add(listener);
+        return this;
+    }
+
+    /**
+     * Removes a listener from the set listening to this animation.
+     *
+     * @param listener the listener to be removed from the current set of
+     * listeners for this transition.
+     * @return This transition object.
+     */
+    public Transition removeListener(TransitionListener listener) {
+        if (mListeners == null) {
+            return this;
+        }
+        mListeners.remove(listener);
+        if (mListeners.size() == 0) {
+            mListeners = null;
+        }
+        return this;
+    }
+
+    Transition setSceneRoot(ViewGroup sceneRoot) {
+        mSceneRoot = sceneRoot;
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return toString("");
+    }
+
+    @Override
+    public Transition clone() {
+        Transition clone = null;
+        try {
+            clone = (Transition) super.clone();
+            clone.mAnimators = new ArrayList<Animator>();
+        } catch (CloneNotSupportedException e) {}
+
+        return clone;
+    }
+
+    /**
+     * Returns the name of this Transition. This name is used internally to distinguish
+     * between different transitions to determine when interrupting transitions overlap.
+     * For example, a ChangeBounds running on the same target view as another ChangeBounds
+     * should determine whether the old transition is animating to different end values
+     * and should be canceled in favor of the new transition.
+     *
+     * <p>By default, a Transition's name is simply the value of {@link Class#getName()},
+     * but subclasses are free to override and return something different.</p>
+     *
+     * @return The name of this transition.
+     */
+    public String getName() {
+        return mName;
+    }
+
+    String toString(String indent) {
+        String result = indent + getClass().getSimpleName() + "@" +
+                Integer.toHexString(hashCode()) + ": ";
+        if (mDuration != -1) {
+            result += "dur(" + mDuration + ") ";
+        }
+        if (mStartDelay != -1) {
+            result += "dly(" + mStartDelay + ") ";
+        }
+        if (mInterpolator != null) {
+            result += "interp(" + mInterpolator + ") ";
+        }
+        if (mTargetIds.size() > 0 || mTargets.size() > 0) {
+            result += "tgts(";
+            if (mTargetIds.size() > 0) {
+                for (int i = 0; i < mTargetIds.size(); ++i) {
+                    if (i > 0) {
+                        result += ", ";
+                    }
+                    result += mTargetIds.get(i);
+                }
+            }
+            if (mTargets.size() > 0) {
+                for (int i = 0; i < mTargets.size(); ++i) {
+                    if (i > 0) {
+                        result += ", ";
+                    }
+                    result += mTargets.get(i);
+                }
+            }
+            result += ")";
+        }
+        return result;
+    }
+
+    /**
+     * A transition listener receives notifications from a transition.
+     * Notifications indicate transition lifecycle events.
+     */
+    public static interface TransitionListener {
+        /**
+         * Notification about the start of the transition.
+         *
+         * @param transition The started transition.
+         */
+        void onTransitionStart(Transition transition);
+
+        /**
+         * Notification about the end of the transition. Canceled transitions
+         * will always notify listeners of both the cancellation and end
+         * events. That is, {@link #onTransitionEnd(Transition)} is always called,
+         * regardless of whether the transition was canceled or played
+         * through to completion.
+         *
+         * @param transition The transition which reached its end.
+         */
+        void onTransitionEnd(Transition transition);
+
+        /**
+         * Notification about the cancellation of the transition.
+         * Note that cancel may be called by a parent {@link TransitionSet} on
+         * a child transition which has not yet started. This allows the child
+         * transition to restore state on target objects which was set at
+         * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues)
+         * createAnimator()} time.
+         *
+         * @param transition The transition which was canceled.
+         */
+        void onTransitionCancel(Transition transition);
+
+        /**
+         * Notification when a transition is paused.
+         * Note that createAnimator() may be called by a parent {@link TransitionSet} on
+         * a child transition which has not yet started. This allows the child
+         * transition to restore state on target objects which was set at
+         * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues)
+         * createAnimator()} time.
+         *
+         * @param transition The transition which was paused.
+         */
+        void onTransitionPause(Transition transition);
+
+        /**
+         * Notification when a transition is resumed.
+         * Note that resume() may be called by a parent {@link TransitionSet} on
+         * a child transition which has not yet started. This allows the child
+         * transition to restore state which may have changed in an earlier call
+         * to {@link #onTransitionPause(Transition)}.
+         *
+         * @param transition The transition which was resumed.
+         */
+        void onTransitionResume(Transition transition);
+    }
+
+    /**
+     * Utility adapter class to avoid having to override all three methods
+     * whenever someone just wants to listen for a single event.
+     *
+     * @hide
+     * */
+    public static class TransitionListenerAdapter implements TransitionListener {
+        @Override
+        public void onTransitionStart(Transition transition) {
+        }
+
+        @Override
+        public void onTransitionEnd(Transition transition) {
+        }
+
+        @Override
+        public void onTransitionCancel(Transition transition) {
+        }
+
+        @Override
+        public void onTransitionPause(Transition transition) {
+        }
+
+        @Override
+        public void onTransitionResume(Transition transition) {
+        }
+    }
+
+    /**
+     * Holds information about each animator used when a new transition starts
+     * while other transitions are still running to determine whether a running
+     * animation should be canceled or a new animation noop'd. The structure holds
+     * information about the state that an animation is going to, to be compared to
+     * end state of a new animation.
+     */
+    private static class AnimationInfo {
+        View view;
+        String name;
+        TransitionValues values;
+
+        AnimationInfo(View view, String name, TransitionValues values) {
+            this.view = view;
+            this.name = name;
+            this.values = values;
+        }
+    }
+
+    /**
+     * Utility class for managing typed ArrayLists efficiently. In particular, this
+     * can be useful for lists that we don't expect to be used often (eg, the exclude
+     * lists), so we'd like to keep them nulled out by default. This causes the code to
+     * become tedious, with constant null checks, code to allocate when necessary,
+     * and code to null out the reference when the list is empty. This class encapsulates
+     * all of that functionality into simple add()/remove() methods which perform the
+     * necessary checks, allocation/null-out as appropriate, and return the
+     * resulting list.
+     */
+    private static class ArrayListManager {
+
+        /**
+         * Add the specified item to the list, returning the resulting list.
+         * The returned list can either the be same list passed in or, if that
+         * list was null, the new list that was created.
+         *
+         * Note that the list holds unique items; if the item already exists in the
+         * list, the list is not modified.
+         */
+        static <T> ArrayList<T> add(ArrayList<T> list, T item) {
+            if (list == null) {
+                list = new ArrayList<T>();
+            }
+            if (!list.contains(item)) {
+                list.add(item);
+            }
+            return list;
+        }
+
+        /**
+         * Remove the specified item from the list, returning the resulting list.
+         * The returned list can either the be same list passed in or, if that
+         * list becomes empty as a result of the remove(), the new list was created.
+         */
+        static <T> ArrayList<T> remove(ArrayList<T> list, T item) {
+            if (list != null) {
+                list.remove(item);
+                if (list.isEmpty()) {
+                    list = null;
+                }
+            }
+            return list;
+        }
+    }
+
+}
diff --git a/core/java/android/transition/TransitionInflater.java b/core/java/android/transition/TransitionInflater.java
new file mode 100644
index 0000000..eeb6cba
--- /dev/null
+++ b/core/java/android/transition/TransitionInflater.java
@@ -0,0 +1,327 @@
+/*
+ * 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.transition;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.util.ArrayMap;
+import android.util.AttributeSet;
+import android.util.SparseArray;
+import android.util.Xml;
+import android.view.InflateException;
+import android.view.ViewGroup;
+import android.view.animation.AnimationUtils;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+/**
+ * This class inflates scenes and transitions from resource files.
+ *
+ * Information on XML resource descriptions for transitions can be found for
+ * {@link android.R.styleable#Transition}, {@link android.R.styleable#TransitionSet},
+ * {@link android.R.styleable#TransitionTarget}, {@link android.R.styleable#Fade},
+ * and {@link android.R.styleable#TransitionManager}.
+ */
+public class TransitionInflater {
+
+    // We only need one inflater for any given context. Also, this allows us to associate
+    // ids with unique instances per-Context, used to avoid re-inflating
+    // already-inflated resources into new/different instances
+    private static final ArrayMap<Context, TransitionInflater> sInflaterMap =
+            new ArrayMap<Context, TransitionInflater>();
+
+    private Context mContext;
+    // TODO: do we need id maps for transitions and transitionMgrs as well?
+    SparseArray<Scene> mScenes = new SparseArray<Scene>();
+
+    private TransitionInflater(Context context) {
+        mContext = context;
+    }
+
+    /**
+     * Obtains the TransitionInflater from the given context.
+     */
+    public static TransitionInflater from(Context context) {
+        TransitionInflater inflater = sInflaterMap.get(context);
+        if (inflater != null) {
+            return inflater;
+        }
+        inflater = new TransitionInflater(context);
+        sInflaterMap.put(context, inflater);
+        return inflater;
+    }
+
+    /**
+     * Loads a {@link Transition} object from a resource
+     *
+     * @param resource The resource id of the transition to load
+     * @return The loaded Transition object
+     * @throws android.content.res.Resources.NotFoundException when the
+     * transition cannot be loaded
+     */
+    public Transition inflateTransition(int resource) {
+        XmlResourceParser parser =  mContext.getResources().getXml(resource);
+        try {
+            return createTransitionFromXml(parser, Xml.asAttributeSet(parser), null);
+        } catch (XmlPullParserException e) {
+            InflateException ex = new InflateException(e.getMessage());
+            ex.initCause(e);
+            throw ex;
+        } catch (IOException e) {
+            InflateException ex = new InflateException(
+                    parser.getPositionDescription()
+                            + ": " + e.getMessage());
+            ex.initCause(e);
+            throw ex;
+        } finally {
+            parser.close();
+        }
+    }
+
+    /**
+     * Loads a {@link TransitionManager} object from a resource
+     *
+     *
+     *
+     * @param resource The resource id of the transition manager to load
+     * @return The loaded TransitionManager object
+     * @throws android.content.res.Resources.NotFoundException when the
+     * transition manager cannot be loaded
+     */
+    public TransitionManager inflateTransitionManager(int resource, ViewGroup sceneRoot) {
+        XmlResourceParser parser =  mContext.getResources().getXml(resource);
+        try {
+            return createTransitionManagerFromXml(parser, Xml.asAttributeSet(parser), sceneRoot);
+        } catch (XmlPullParserException e) {
+            InflateException ex = new InflateException(e.getMessage());
+            ex.initCause(e);
+            throw ex;
+        } catch (IOException e) {
+            InflateException ex = new InflateException(
+                    parser.getPositionDescription()
+                            + ": " + e.getMessage());
+            ex.initCause(e);
+            throw ex;
+        } finally {
+            parser.close();
+        }
+    }
+
+    //
+    // Transition loading
+    //
+
+    private Transition createTransitionFromXml(XmlPullParser parser,
+            AttributeSet attrs, TransitionSet transitionSet)
+            throws XmlPullParserException, IOException {
+
+        Transition transition = null;
+
+        // Make sure we are on a start tag.
+        int type;
+        int depth = parser.getDepth();
+
+        while (((type=parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
+                && type != XmlPullParser.END_DOCUMENT) {
+
+            boolean newTransition = false;
+
+            if (type != XmlPullParser.START_TAG) {
+                continue;
+            }
+
+            String  name = parser.getName();
+            if ("fade".equals(name)) {
+                TypedArray a = mContext.obtainStyledAttributes(attrs,
+                        com.android.internal.R.styleable.Fade);
+                int fadingMode = a.getInt(com.android.internal.R.styleable.Fade_fadingMode,
+                        Fade.IN | Fade.OUT);
+                transition = new Fade(fadingMode);
+                newTransition = true;
+            } else if ("changeBounds".equals(name)) {
+                transition = new ChangeBounds();
+                newTransition = true;
+            } else if ("slide".equals(name)) {
+                transition = new Slide();
+                newTransition = true;
+            } else if ("autoTransition".equals(name)) {
+                transition = new AutoTransition();
+                newTransition = true;
+            } else if ("recolor".equals(name)) {
+                transition = new Recolor();
+                newTransition = true;
+            } else if ("set".equals(name)) {
+                transition = new TransitionSet();
+                TypedArray a = mContext.obtainStyledAttributes(attrs,
+                        com.android.internal.R.styleable.TransitionSet);
+                int ordering = a.getInt(
+                        com.android.internal.R.styleable.TransitionSet_transitionOrdering,
+                        TransitionSet.ORDERING_TOGETHER);
+                ((TransitionSet) transition).setOrdering(ordering);
+                createTransitionFromXml(parser, attrs, ((TransitionSet) transition));
+                a.recycle();
+                newTransition = true;
+            } else if ("targets".equals(name)) {
+                if (parser.getDepth() - 1 > depth && transition != null) {
+                    // We're inside the child tag - add targets to the child
+                    getTargetIds(parser, attrs, transition);
+                } else if (parser.getDepth() - 1 == depth && transitionSet != null) {
+                    // add targets to the set
+                    getTargetIds(parser, attrs, transitionSet);
+                }
+            }
+            if (transition != null || "targets".equals(name)) {
+                if (newTransition) {
+                    loadTransition(transition, attrs);
+                    if (transitionSet != null) {
+                        transitionSet.addTransition(transition);
+                    }
+                }
+            } else {
+                throw new RuntimeException("Unknown scene name: " + parser.getName());
+            }
+        }
+
+        return transition;
+    }
+
+    private void getTargetIds(XmlPullParser parser,
+            AttributeSet attrs, Transition transition) throws XmlPullParserException, IOException {
+
+        // Make sure we are on a start tag.
+        int type;
+        int depth = parser.getDepth();
+
+        ArrayList<Integer> targetIds = new ArrayList<Integer>();
+        while (((type=parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
+                && type != XmlPullParser.END_DOCUMENT) {
+
+            if (type != XmlPullParser.START_TAG) {
+                continue;
+            }
+
+            String  name = parser.getName();
+            if (name.equals("target")) {
+                TypedArray a = mContext.obtainStyledAttributes(attrs,
+                        com.android.internal.R.styleable.TransitionTarget);
+                int id = a.getResourceId(
+                        com.android.internal.R.styleable.TransitionTarget_targetId, -1);
+                if (id >= 0) {
+                    targetIds.add(id);
+                }
+            } else {
+                throw new RuntimeException("Unknown scene name: " + parser.getName());
+            }
+        }
+        int numTargets = targetIds.size();
+        if (numTargets > 0) {
+            for (int i = 0; i < numTargets; ++i) {
+                transition.addTarget(targetIds.get(i));
+            }
+        }
+    }
+
+    private Transition loadTransition(Transition transition, AttributeSet attrs)
+            throws Resources.NotFoundException {
+
+        TypedArray a =
+                mContext.obtainStyledAttributes(attrs, com.android.internal.R.styleable.Transition);
+        long duration = a.getInt(com.android.internal.R.styleable.Transition_duration, -1);
+        if (duration >= 0) {
+            transition.setDuration(duration);
+        }
+        long startDelay = a.getInt(com.android.internal.R.styleable.Transition_startDelay, -1);
+        if (startDelay > 0) {
+            transition.setStartDelay(startDelay);
+        }
+        final int resID =
+                a.getResourceId(com.android.internal.R.styleable.Animator_interpolator, 0);
+        if (resID > 0) {
+            transition.setInterpolator(AnimationUtils.loadInterpolator(mContext, resID));
+        }
+        a.recycle();
+        return transition;
+    }
+
+    //
+    // TransitionManager loading
+    //
+
+    private TransitionManager createTransitionManagerFromXml(XmlPullParser parser,
+            AttributeSet attrs, ViewGroup sceneRoot) throws XmlPullParserException, IOException {
+
+        // Make sure we are on a start tag.
+        int type;
+        int depth = parser.getDepth();
+        TransitionManager transitionManager = null;
+
+        while (((type=parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
+                && type != XmlPullParser.END_DOCUMENT) {
+
+            if (type != XmlPullParser.START_TAG) {
+                continue;
+            }
+
+            String  name = parser.getName();
+            if (name.equals("transitionManager")) {
+                transitionManager = new TransitionManager();
+            } else if (name.equals("transition") && (transitionManager != null)) {
+                loadTransition(attrs, sceneRoot, transitionManager);
+            } else {
+                throw new RuntimeException("Unknown scene name: " + parser.getName());
+            }
+        }
+        return transitionManager;
+    }
+
+    private void loadTransition(AttributeSet attrs, ViewGroup sceneRoot,
+            TransitionManager transitionManager) throws Resources.NotFoundException {
+
+        TypedArray a = mContext.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.TransitionManager);
+        int transitionId = a.getResourceId(
+                com.android.internal.R.styleable.TransitionManager_transition, -1);
+        Scene fromScene = null, toScene = null;
+        int fromId = a.getResourceId(
+                com.android.internal.R.styleable.TransitionManager_fromScene, -1);
+        if (fromId >= 0) fromScene = Scene.getSceneForLayout(sceneRoot, fromId, mContext);
+        int toId = a.getResourceId(
+                com.android.internal.R.styleable.TransitionManager_toScene, -1);
+        if (toId >= 0) toScene = Scene.getSceneForLayout(sceneRoot, toId, mContext);
+        if (transitionId >= 0) {
+            Transition transition = inflateTransition(transitionId);
+            if (transition != null) {
+                if (fromScene != null) {
+                    if (toScene == null){
+                        throw new RuntimeException("No matching toScene for given fromScene " +
+                                "for transition ID " + transitionId);
+                    } else {
+                        transitionManager.setTransition(fromScene, toScene, transition);
+                    }
+                } else if (toId >= 0) {
+                    transitionManager.setTransition(toScene, transition);
+                }
+            }
+        }
+        a.recycle();
+    }
+}
diff --git a/core/java/android/transition/TransitionManager.java b/core/java/android/transition/TransitionManager.java
new file mode 100644
index 0000000..54d801e
--- /dev/null
+++ b/core/java/android/transition/TransitionManager.java
@@ -0,0 +1,364 @@
+/*
+ * 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.transition;
+
+import android.content.Context;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+
+import java.util.ArrayList;
+
+/**
+ * This class manages the set of transitions that fire when there is a
+ * change of {@link Scene}. To use the manager, add scenes along with
+ * transition objects with calls to {@link #setTransition(Scene, Transition)}
+ * or {@link #setTransition(Scene, Scene, Transition)}. Setting specific
+ * transitions for scene changes is not required; by default, a Scene change
+ * will use {@link AutoTransition} to do something reasonable for most
+ * situations. Specifying other transitions for particular scene changes is
+ * only necessary if the application wants different transition behavior
+ * in these situations.
+ *
+ * <p>TransitionManagers can be declared in XML resource files inside the
+ * <code>res/transition</code> directory. TransitionManager resources consist of
+ * the <code>transitionManager</code>tag name, containing one or more
+ * <code>transition</code> tags, each of which describe the relationship of
+ * that transition to the from/to scene information in that tag.
+ * For example, here is a resource file that declares several scene
+ * transitions:</p>
+ *
+ * {@sample development/samples/ApiDemos/res/transition/transitions_mgr.xml TransitionManager}
+ *
+ * <p>For each of the <code>fromScene</code> and <code>toScene</code> attributes,
+ * there is a reference to a standard XML layout file. This is equivalent to
+ * creating a scene from a layout in code by calling
+ * {@link Scene#getSceneForLayout(ViewGroup, int, Context)}. For the
+ * <code>transition</code> attribute, there is a reference to a resource
+ * file in the <code>res/transition</code> directory which describes that
+ * transition.</p>
+ *
+ * Information on XML resource descriptions for transitions can be found for
+ * {@link android.R.styleable#Transition}, {@link android.R.styleable#TransitionSet},
+ * {@link android.R.styleable#TransitionTarget}, {@link android.R.styleable#Fade},
+ * and {@link android.R.styleable#TransitionManager}.
+ */
+public class TransitionManager {
+    // TODO: how to handle enter/exit?
+
+    private static String LOG_TAG = "TransitionManager";
+
+    private static Transition sDefaultTransition = new AutoTransition();
+
+    ArrayMap<Scene, Transition> mSceneTransitions = new ArrayMap<Scene, Transition>();
+    ArrayMap<Scene, ArrayMap<Scene, Transition>> mScenePairTransitions =
+            new ArrayMap<Scene, ArrayMap<Scene, Transition>>();
+    private static ThreadLocal<ArrayMap<ViewGroup, ArrayList<Transition>>> sRunningTransitions =
+            new ThreadLocal<ArrayMap<ViewGroup, ArrayList<Transition>>>();
+    private static ArrayList<ViewGroup> sPendingTransitions = new ArrayList<ViewGroup>();
+
+
+    /**
+     * Sets the transition to be used for any scene change for which no
+     * other transition is explicitly set. The initial value is
+     * an {@link AutoTransition} instance.
+     *
+     * @param transition The default transition to be used for scene changes.
+     */
+    public void setDefaultTransition(Transition transition) {
+        sDefaultTransition = transition;
+    }
+
+    /**
+     * Gets the current default transition. The initial value is an {@link
+     * AutoTransition} instance.
+     *
+     * @return The current default transition.
+     * @see #setDefaultTransition(Transition)
+     */
+    public static Transition getDefaultTransition() {
+        return sDefaultTransition;
+    }
+
+    /**
+     * Sets a specific transition to occur when the given scene is entered.
+     *
+     * @param scene The scene which, when applied, will cause the given
+     * transition to run.
+     * @param transition The transition that will play when the given scene is
+     * entered. A value of null will result in the default behavior of
+     * using the {@link #getDefaultTransition() default transition} instead.
+     */
+    public void setTransition(Scene scene, Transition transition) {
+        mSceneTransitions.put(scene, transition);
+    }
+
+    /**
+     * Sets a specific transition to occur when the given pair of scenes is
+     * exited/entered.
+     *
+     * @param fromScene The scene being exited when the given transition will
+     * be run
+     * @param toScene The scene being entered when the given transition will
+     * be run
+     * @param transition The transition that will play when the given scene is
+     * entered. A value of null will result in the default behavior of
+     * using the {@link #getDefaultTransition() default transition} instead.
+     */
+    public void setTransition(Scene fromScene, Scene toScene, Transition transition) {
+        ArrayMap<Scene, Transition> sceneTransitionMap = mScenePairTransitions.get(toScene);
+        if (sceneTransitionMap == null) {
+            sceneTransitionMap = new ArrayMap<Scene, Transition>();
+            mScenePairTransitions.put(toScene, sceneTransitionMap);
+        }
+        sceneTransitionMap.put(fromScene, transition);
+    }
+
+    /**
+     * Returns the Transition for the given scene being entered. The result
+     * depends not only on the given scene, but also the scene which the
+     * {@link Scene#getSceneRoot() sceneRoot} of the Scene is currently in.
+     *
+     * @param scene The scene being entered
+     * @return The Transition to be used for the given scene change. If no
+     * Transition was specified for this scene change, the {@link #getDefaultTransition()
+     * default transition} will be used instead.
+     */
+    private Transition getTransition(Scene scene) {
+        Transition transition = null;
+        ViewGroup sceneRoot = scene.getSceneRoot();
+        if (sceneRoot != null) {
+            // TODO: cached in Scene instead? long-term, cache in View itself
+            Scene currScene = Scene.getCurrentScene(sceneRoot);
+            if (currScene != null) {
+                ArrayMap<Scene, Transition> sceneTransitionMap = mScenePairTransitions.get(scene);
+                if (sceneTransitionMap != null) {
+                    transition = sceneTransitionMap.get(currScene);
+                    if (transition != null) {
+                        return transition;
+                    }
+                }
+            }
+        }
+        transition = mSceneTransitions.get(scene);
+        return (transition != null) ? transition : sDefaultTransition;
+    }
+
+    /**
+     * This is where all of the work of a transition/scene-change is
+     * orchestrated. This method captures the start values for the given
+     * transition, exits the current Scene, enters the new scene, captures
+     * the end values for the transition, and finally plays the
+     * resulting values-populated transition.
+     *
+     * @param scene The scene being entered
+     * @param transition The transition to play for this scene change
+     */
+    private static void changeScene(Scene scene, Transition transition) {
+
+        final ViewGroup sceneRoot = scene.getSceneRoot();
+
+        Transition transitionClone = transition.clone();
+        transitionClone.setSceneRoot(sceneRoot);
+
+        sceneChangeSetup(sceneRoot, transitionClone);
+
+        scene.enter();
+
+        sceneChangeRunTransition(sceneRoot, transitionClone);
+    }
+
+    private static ArrayMap<ViewGroup, ArrayList<Transition>> getRunningTransitions() {
+        ArrayMap<ViewGroup, ArrayList<Transition>> runningTransitions =
+                sRunningTransitions.get();
+        if (runningTransitions == null) {
+            runningTransitions = new ArrayMap<ViewGroup, ArrayList<Transition>>();
+            sRunningTransitions.set(runningTransitions);
+        }
+        return runningTransitions;
+    }
+
+    private static void sceneChangeRunTransition(final ViewGroup sceneRoot,
+            final Transition transition) {
+        if (transition != null) {
+            final ViewTreeObserver observer = sceneRoot.getViewTreeObserver();
+            observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+                public boolean onPreDraw() {
+                    sceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
+                    sPendingTransitions.remove(sceneRoot);
+                    // Add to running list, handle end to remove it
+                    final ArrayMap<ViewGroup, ArrayList<Transition>> runningTransitions =
+                            getRunningTransitions();
+                    ArrayList<Transition> currentTransitions = runningTransitions.get(sceneRoot);
+                    ArrayList<Transition> previousRunningTransitions = null;
+                    if (currentTransitions == null) {
+                        currentTransitions = new ArrayList<Transition>();
+                        runningTransitions.put(sceneRoot, currentTransitions);
+                    } else if (currentTransitions.size() > 0) {
+                        previousRunningTransitions = new ArrayList<Transition>(currentTransitions);
+                    }
+                    currentTransitions.add(transition);
+                    transition.addListener(new Transition.TransitionListenerAdapter() {
+                        @Override
+                        public void onTransitionEnd(Transition transition) {
+                            ArrayList<Transition> currentTransitions =
+                                    runningTransitions.get(sceneRoot);
+                            currentTransitions.remove(transition);
+                        }
+                    });
+                    transition.captureValues(sceneRoot, false);
+                    if (previousRunningTransitions != null) {
+                        for (Transition runningTransition : previousRunningTransitions) {
+                            runningTransition.resume();
+                        }
+                    }
+                    transition.playTransition(sceneRoot);
+
+                    // Returning false from onPreDraw() skips the current frame. This is
+                    // necessary to avoid artifacts caused by resetting target views
+                    // to their proper end states for capturing. Waiting until the next
+                    // frame to draw allows these views to have their mid-transition
+                    // values set on them again and avoid artifacts.
+                    return false;
+                }
+            });
+        }
+    }
+
+    private static void sceneChangeSetup(ViewGroup sceneRoot, Transition transition) {
+
+        // Capture current values
+        ArrayList<Transition> runningTransitions = getRunningTransitions().get(sceneRoot);
+
+        if (runningTransitions != null && runningTransitions.size() > 0) {
+            for (Transition runningTransition : runningTransitions) {
+                runningTransition.pause();
+            }
+        }
+
+        if (transition != null) {
+            transition.captureValues(sceneRoot, true);
+        }
+
+        // Notify previous scene that it is being exited
+        Scene previousScene = Scene.getCurrentScene(sceneRoot);
+        if (previousScene != null) {
+            previousScene.exit();
+        }
+    }
+
+    /**
+     * Change to the given scene, using the
+     * appropriate transition for this particular scene change
+     * (as specified to the TransitionManager, or the default
+     * if no such transition exists).
+     *
+     * @param scene The Scene to change to
+     */
+    public void transitionTo(Scene scene) {
+        // Auto transition if there is no transition declared for the Scene, but there is
+        // a root or parent view
+        changeScene(scene, getTransition(scene));
+
+    }
+
+    /**
+     * Convenience method to simply change to the given scene using
+     * the default transition for TransitionManager.
+     *
+     * @param scene The Scene to change to
+     */
+    public static void go(Scene scene) {
+        changeScene(scene, sDefaultTransition);
+    }
+
+    /**
+     * Convenience method to simply change to the given scene using
+     * the given transition.
+     *
+     * <p>Passing in <code>null</code> for the transition parameter will
+     * result in the scene changing without any transition running, and is
+     * equivalent to calling {@link Scene#exit()} on the scene root's
+     * current scene, followed by {@link Scene#enter()} on the scene
+     * specified by the <code>scene</code> parameter.</p>
+     *
+     * @param scene The Scene to change to
+     * @param transition The transition to use for this scene change. A
+     * value of null causes the scene change to happen with no transition.
+     */
+    public static void go(Scene scene, Transition transition) {
+        changeScene(scene, transition);
+    }
+
+    /**
+     * Convenience method to animate, using the default transition,
+     * to a new scene defined by all changes within the given scene root between
+     * calling this method and the next rendering frame.
+     * Equivalent to calling {@link #beginDelayedTransition(ViewGroup, Transition)}
+     * with a value of <code>null</code> for the <code>transition</code> parameter.
+     *
+     * @param sceneRoot The root of the View hierarchy to run the transition on.
+     */
+    public static void beginDelayedTransition(final ViewGroup sceneRoot) {
+        beginDelayedTransition(sceneRoot, null);
+    }
+
+    /**
+     * Convenience method to animate to a new scene defined by all changes within
+     * the given scene root between calling this method and the next rendering frame.
+     * Calling this method causes TransitionManager to capture current values in the
+     * scene root and then post a request to run a transition on the next frame.
+     * At that time, the new values in the scene root will be captured and changes
+     * will be animated. There is no need to create a Scene; it is implied by
+     * changes which take place between calling this method and the next frame when
+     * the transition begins.
+     *
+     * <p>Calling this method several times before the next frame (for example, if
+     * unrelated code also wants to make dynamic changes and run a transition on
+     * the same scene root), only the first call will trigger capturing values
+     * and exiting the current scene. Subsequent calls to the method with the
+     * same scene root during the same frame will be ignored.</p>
+     *
+     * <p>Passing in <code>null</code> for the transition parameter will
+     * cause the TransitionManager to use its default transition.</p>
+     *
+     * @param sceneRoot The root of the View hierarchy to run the transition on.
+     * @param transition The transition to use for this change. A
+     * value of null causes the TransitionManager to use the default transition.
+     */
+    public static void beginDelayedTransition(final ViewGroup sceneRoot, Transition transition) {
+
+        // TEMPORARY: disabling delayed transitions until a fix for the various ActionBar-
+        // triggered artifacts is found
+
+//        if (!sPendingTransitions.contains(sceneRoot) && sceneRoot.isLaidOut()) {
+//            if (Transition.DBG) {
+//                Log.d(LOG_TAG, "beginDelayedTransition: root, transition = " +
+//                        sceneRoot + ", " + transition);
+//            }
+//            sPendingTransitions.add(sceneRoot);
+//            if (transition == null) {
+//                transition = sDefaultTransition;
+//            }
+//            final Transition finalTransition = transition.clone();
+//            sceneChangeSetup(sceneRoot, transition);
+//            Scene.setCurrentScene(sceneRoot, null);
+//            sceneChangeRunTransition(sceneRoot, finalTransition);
+//        }
+    }
+}
diff --git a/core/java/android/transition/TransitionSet.java b/core/java/android/transition/TransitionSet.java
new file mode 100644
index 0000000..f72b36e
--- /dev/null
+++ b/core/java/android/transition/TransitionSet.java
@@ -0,0 +1,362 @@
+/*
+ * 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.transition;
+
+import android.animation.TimeInterpolator;
+import android.util.AndroidRuntimeException;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.util.ArrayList;
+
+/**
+ * A TransitionSet is a parent of child transitions (including other
+ * TransitionSets). Using TransitionSets enables more complex
+ * choreography of transitions, where some sets play {@link #ORDERING_TOGETHER} and
+ * others play {@link #ORDERING_SEQUENTIAL}. For example, {@link AutoTransition}
+ * uses a TransitionSet to sequentially play a Fade(Fade.OUT), followed by
+ * a {@link ChangeBounds}, followed by a Fade(Fade.OUT) transition.
+ */
+public class TransitionSet extends Transition {
+
+    ArrayList<Transition> mTransitions = new ArrayList<Transition>();
+    private boolean mPlayTogether = true;
+    int mCurrentListeners;
+    boolean mStarted = false;
+
+    /**
+     * A flag used to indicate that the child transitions of this set
+     * should all start at the same time.
+     */
+    public static final int ORDERING_TOGETHER = 0;
+    /**
+     * A flag used to indicate that the child transitions of this set should
+     * play in sequence; when one child transition ends, the next child
+     * transition begins. Note that a transition does not end until all
+     * instances of it (which are playing on all applicable targets of the
+     * transition) end.
+     */
+    public static final int ORDERING_SEQUENTIAL = 1;
+
+    /**
+     * Constructs an empty transition set. Add child transitions to the
+     * set by calling {@link #addTransition(Transition)} )}. By default,
+     * child transitions will play {@link #ORDERING_TOGETHER together}.
+     */
+    public TransitionSet() {
+    }
+
+    /**
+     * Sets the play order of this set's child transitions.
+     *
+     * @param ordering {@link #ORDERING_TOGETHER} to play this set's child
+     * transitions together, {@link #ORDERING_SEQUENTIAL} to play the child
+     * transitions in sequence.
+     * @return This transitionSet object.
+     */
+    public TransitionSet setOrdering(int ordering) {
+        switch (ordering) {
+            case ORDERING_SEQUENTIAL:
+                mPlayTogether = false;
+                break;
+            case ORDERING_TOGETHER:
+                mPlayTogether = true;
+                break;
+            default:
+                throw new AndroidRuntimeException("Invalid parameter for TransitionSet " +
+                        "ordering: " + ordering);
+        }
+        return this;
+    }
+
+    /**
+     * Returns the ordering of this TransitionSet. By default, the value is
+     * {@link #ORDERING_TOGETHER}.
+     *
+     * @return {@link #ORDERING_TOGETHER} if child transitions will play at the same
+     * time, {@link #ORDERING_SEQUENTIAL} if they will play in sequence.
+     *
+     * @see #setOrdering(int)
+     */
+    public int getOrdering() {
+        return mPlayTogether ? ORDERING_TOGETHER : ORDERING_SEQUENTIAL;
+    }
+
+    /**
+     * Adds child transition to this set. The order in which this child transition
+     * is added relative to other child transitions that are added, in addition to
+     * the {@link #getOrdering() ordering} property, determines the
+     * order in which the transitions are started.
+     *
+     * <p>If this transitionSet has a {@link #getDuration() duration} set on it, the
+     * child transition will inherit that duration. Transitions are assumed to have
+     * a maximum of one transitionSet parent.</p>
+     *
+     * @param transition A non-null child transition to be added to this set.
+     * @return This transitionSet object.
+     */
+    public TransitionSet addTransition(Transition transition) {
+        if (transition != null) {
+            mTransitions.add(transition);
+            transition.mParent = this;
+            if (mDuration >= 0) {
+                transition.setDuration(mDuration);
+            }
+        }
+        return this;
+    }
+
+    /**
+     * Setting a non-negative duration on a TransitionSet causes all of the child
+     * transitions (current and future) to inherit this duration.
+     *
+     * @param duration The length of the animation, in milliseconds.
+     * @return This transitionSet object.
+     */
+    @Override
+    public TransitionSet setDuration(long duration) {
+        super.setDuration(duration);
+        if (mDuration >= 0) {
+            int numTransitions = mTransitions.size();
+            for (int i = 0; i < numTransitions; ++i) {
+                mTransitions.get(i).setDuration(duration);
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public TransitionSet setStartDelay(long startDelay) {
+        return (TransitionSet) super.setStartDelay(startDelay);
+    }
+
+    @Override
+    public TransitionSet setInterpolator(TimeInterpolator interpolator) {
+        return (TransitionSet) super.setInterpolator(interpolator);
+    }
+
+    @Override
+    public TransitionSet addTarget(View target) {
+        return (TransitionSet) super.addTarget(target);
+    }
+
+    @Override
+    public TransitionSet addTarget(int targetId) {
+        return (TransitionSet) super.addTarget(targetId);
+    }
+
+    @Override
+    public TransitionSet addListener(TransitionListener listener) {
+        return (TransitionSet) super.addListener(listener);
+    }
+
+    @Override
+    public TransitionSet removeTarget(int targetId) {
+        return (TransitionSet) super.removeTarget(targetId);
+    }
+
+    @Override
+    public TransitionSet removeTarget(View target) {
+        return (TransitionSet) super.removeTarget(target);
+    }
+
+    @Override
+    public TransitionSet removeListener(TransitionListener listener) {
+        return (TransitionSet) super.removeListener(listener);
+    }
+
+    /**
+     * Removes the specified child transition from this set.
+     *
+     * @param transition The transition to be removed.
+     * @return This transitionSet object.
+     */
+    public TransitionSet removeTransition(Transition transition) {
+        mTransitions.remove(transition);
+        transition.mParent = null;
+        return this;
+    }
+
+    /**
+     * Sets up listeners for each of the child transitions. This is used to
+     * determine when this transition set is finished (all child transitions
+     * must finish first).
+     */
+    private void setupStartEndListeners() {
+        TransitionSetListener listener = new TransitionSetListener(this);
+        for (Transition childTransition : mTransitions) {
+            childTransition.addListener(listener);
+        }
+        mCurrentListeners = mTransitions.size();
+    }
+
+    /**
+     * This listener is used to detect when all child transitions are done, at
+     * which point this transition set is also done.
+     */
+    static class TransitionSetListener extends TransitionListenerAdapter {
+        TransitionSet mTransitionSet;
+        TransitionSetListener(TransitionSet transitionSet) {
+            mTransitionSet = transitionSet;
+        }
+        @Override
+        public void onTransitionStart(Transition transition) {
+            if (!mTransitionSet.mStarted) {
+                mTransitionSet.start();
+                mTransitionSet.mStarted = true;
+            }
+        }
+
+        @Override
+        public void onTransitionEnd(Transition transition) {
+            --mTransitionSet.mCurrentListeners;
+            if (mTransitionSet.mCurrentListeners == 0) {
+                // All child trans
+                mTransitionSet.mStarted = false;
+                mTransitionSet.end();
+            }
+            transition.removeListener(this);
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    protected void createAnimators(ViewGroup sceneRoot, TransitionValuesMaps startValues,
+            TransitionValuesMaps endValues) {
+        for (Transition childTransition : mTransitions) {
+            childTransition.createAnimators(sceneRoot, startValues, endValues);
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    protected void runAnimators() {
+        setupStartEndListeners();
+        if (!mPlayTogether) {
+            // Setup sequence with listeners
+            // TODO: Need to add listeners in such a way that we can remove them later if canceled
+            for (int i = 1; i < mTransitions.size(); ++i) {
+                Transition previousTransition = mTransitions.get(i - 1);
+                final Transition nextTransition = mTransitions.get(i);
+                previousTransition.addListener(new TransitionListenerAdapter() {
+                    @Override
+                    public void onTransitionEnd(Transition transition) {
+                        nextTransition.runAnimators();
+                        transition.removeListener(this);
+                    }
+                });
+            }
+            Transition firstTransition = mTransitions.get(0);
+            if (firstTransition != null) {
+                firstTransition.runAnimators();
+            }
+        } else {
+            for (Transition childTransition : mTransitions) {
+                childTransition.runAnimators();
+            }
+        }
+    }
+
+    @Override
+    public void captureStartValues(TransitionValues transitionValues) {
+        int targetId = transitionValues.view.getId();
+        if (isValidTarget(transitionValues.view, targetId)) {
+            for (Transition childTransition : mTransitions) {
+                if (childTransition.isValidTarget(transitionValues.view, targetId)) {
+                    childTransition.captureStartValues(transitionValues);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void captureEndValues(TransitionValues transitionValues) {
+        int targetId = transitionValues.view.getId();
+        if (isValidTarget(transitionValues.view, targetId)) {
+            for (Transition childTransition : mTransitions) {
+                if (childTransition.isValidTarget(transitionValues.view, targetId)) {
+                    childTransition.captureEndValues(transitionValues);
+                }
+            }
+        }
+    }
+
+    /** @hide */
+    @Override
+    public void pause() {
+        super.pause();
+        int numTransitions = mTransitions.size();
+        for (int i = 0; i < numTransitions; ++i) {
+            mTransitions.get(i).pause();
+        }
+    }
+
+    /** @hide */
+    @Override
+    public void resume() {
+        super.resume();
+        int numTransitions = mTransitions.size();
+        for (int i = 0; i < numTransitions; ++i) {
+            mTransitions.get(i).resume();
+        }
+    }
+
+    /** @hide */
+    @Override
+    protected void cancel() {
+        super.cancel();
+        int numTransitions = mTransitions.size();
+        for (int i = 0; i < numTransitions; ++i) {
+            mTransitions.get(i).cancel();
+        }
+    }
+
+    @Override
+    TransitionSet setSceneRoot(ViewGroup sceneRoot) {
+        super.setSceneRoot(sceneRoot);
+        int numTransitions = mTransitions.size();
+        for (int i = 0; i < numTransitions; ++i) {
+            mTransitions.get(i).setSceneRoot(sceneRoot);
+        }
+        return (TransitionSet) this;
+    }
+
+    @Override
+    String toString(String indent) {
+        String result = super.toString(indent);
+        for (int i = 0; i < mTransitions.size(); ++i) {
+            result += "\n" + mTransitions.get(i).toString(indent + "  ");
+        }
+        return result;
+    }
+
+    @Override
+    public TransitionSet clone() {
+        TransitionSet clone = (TransitionSet) super.clone();
+        clone.mTransitions = new ArrayList<Transition>();
+        int numTransitions = mTransitions.size();
+        for (int i = 0; i < numTransitions; ++i) {
+            clone.mTransitions.add((Transition) mTransitions.get(i).clone());
+        }
+        return clone;
+    }
+
+}
diff --git a/core/java/android/transition/TransitionValues.java b/core/java/android/transition/TransitionValues.java
new file mode 100644
index 0000000..8989f89
--- /dev/null
+++ b/core/java/android/transition/TransitionValues.java
@@ -0,0 +1,82 @@
+/*
+ * 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.transition;
+
+import android.util.ArrayMap;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.util.Map;
+
+/**
+ * Data structure which holds cached values for the transition.
+ * The view field is the target which all of the values pertain to.
+ * The values field is a map which holds information for fields
+ * according to names selected by the transitions. These names should
+ * be unique to avoid clobbering values stored by other transitions,
+ * such as the convention project:transition_name:property_name. For
+ * example, the platform might store a property "alpha" in a transition
+ * "Fader" as "android:fader:alpha".
+ *
+ * <p>These values are cached during the
+ * {@link Transition#captureStartValues(TransitionValues)}
+ * capture} phases of a scene change, once when the start values are captured
+ * and again when the end values are captured. These start/end values are then
+ * passed into the transitions via the
+ * for {@link Transition#createAnimator(ViewGroup, TransitionValues, TransitionValues)}
+ * method.</p>
+ */
+public class TransitionValues {
+
+    /**
+     * The View with these values
+     */
+    public View view;
+
+    /**
+     * The set of values tracked by transitions for this scene
+     */
+    public final Map<String, Object> values = new ArrayMap<String, Object>();
+
+    @Override
+    public boolean equals(Object other) {
+        if (other instanceof TransitionValues) {
+            if (view == ((TransitionValues) other).view) {
+                if (values.equals(((TransitionValues) other).values)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return 31*view.hashCode() + values.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        String returnValue = "TransitionValues@" + Integer.toHexString(hashCode()) + ":\n";
+        returnValue += "    view = " + view + "\n";
+        returnValue += "    values:";
+        for (String s : values.keySet()) {
+            returnValue += "    " + s + ": " + values.get(s) + "\n";
+        }
+        return returnValue;
+    }
+}
\ No newline at end of file
diff --git a/core/java/android/transition/TransitionValuesMaps.java b/core/java/android/transition/TransitionValuesMaps.java
new file mode 100644
index 0000000..131596b
--- /dev/null
+++ b/core/java/android/transition/TransitionValuesMaps.java
@@ -0,0 +1,30 @@
+/*
+ * 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.transition;
+
+import android.util.ArrayMap;
+import android.util.LongSparseArray;
+import android.util.SparseArray;
+import android.view.View;
+
+class TransitionValuesMaps {
+    ArrayMap<View, TransitionValues> viewValues =
+            new ArrayMap<View, TransitionValues>();
+    SparseArray<TransitionValues> idValues = new SparseArray<TransitionValues>();
+    LongSparseArray<TransitionValues> itemIdValues =
+            new LongSparseArray<TransitionValues>();
+}
diff --git a/core/java/android/transition/Visibility.java b/core/java/android/transition/Visibility.java
new file mode 100644
index 0000000..75d3e7c
--- /dev/null
+++ b/core/java/android/transition/Visibility.java
@@ -0,0 +1,289 @@
+/*
+ * 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.transition;
+
+import android.animation.Animator;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * This transition tracks changes to the visibility of target views in the
+ * start and end scenes. Visibility is determined not just by the
+ * {@link View#setVisibility(int)} state of views, but also whether
+ * views exist in the current view hierarchy. The class is intended to be a
+ * utility for subclasses such as {@link Fade}, which use this visibility
+ * information to determine the specific animations to run when visibility
+ * changes occur. Subclasses should implement one or both of the methods
+ * {@link #onAppear(ViewGroup, TransitionValues, int, TransitionValues, int)},
+ * {@link #onDisappear(ViewGroup, TransitionValues, int, TransitionValues, int)},
+ *
+ * <p>Note that a view's visibility change is determined by both whether the view
+ * itself is changing and whether its parent hierarchy's visibility is changing.
+ * That is, a view that appears in the end scene will only trigger a call to
+ * {@link #onAppear(android.view.ViewGroup, TransitionValues, int, TransitionValues, int)
+ * appear()} if its parent hierarchy was stable between the start and end scenes.
+ * This is done to avoid causing a visibility transition on every node in a hierarchy
+ * when only the top-most node is the one that should be transitioned in/out.
+ * Stability is determined by either the parent hierarchy views being the same
+ * between scenes or, if scenes are inflated from layout resource files and thus
+ * have result in different view instances, if the views represented by
+ * the ids of those parents are stable. This means that visibility determination
+ * is more effective with inflated view hierarchies if ids are used.
+ * The exception to this is when the visibility subclass transition is
+ * targeted at specific views, in which case the visibility of parent views
+ * is ignored.</p>
+ */
+public abstract class Visibility extends Transition {
+
+    private static final String PROPNAME_VISIBILITY = "android:visibility:visibility";
+    private static final String PROPNAME_PARENT = "android:visibility:parent";
+    private static final String[] sTransitionProperties = {
+            PROPNAME_VISIBILITY,
+            PROPNAME_PARENT,
+    };
+
+    private static class VisibilityInfo {
+        boolean visibilityChange;
+        boolean fadeIn;
+        int startVisibility;
+        int endVisibility;
+        ViewGroup startParent;
+        ViewGroup endParent;
+    }
+
+    // Temporary structure, used in calculating state in setup() and play()
+    private VisibilityInfo mTmpVisibilityInfo = new VisibilityInfo();
+
+    @Override
+    public String[] getTransitionProperties() {
+        return sTransitionProperties;
+    }
+
+    private void captureValues(TransitionValues transitionValues) {
+        int visibility = transitionValues.view.getVisibility();
+        transitionValues.values.put(PROPNAME_VISIBILITY, visibility);
+        transitionValues.values.put(PROPNAME_PARENT, transitionValues.view.getParent());
+    }
+
+    @Override
+    public void captureStartValues(TransitionValues transitionValues) {
+        captureValues(transitionValues);
+    }
+
+    @Override
+    public void captureEndValues(TransitionValues transitionValues) {
+        captureValues(transitionValues);
+    }
+
+    /**
+     * Returns whether the view is 'visible' according to the given values
+     * object. This is determined by testing the same properties in the values
+     * object that are used to determine whether the object is appearing or
+     * disappearing in the {@link
+     * Transition#createAnimator(ViewGroup, TransitionValues, TransitionValues)}
+     * method. This method can be called by, for example, subclasses that want
+     * to know whether the object is visible in the same way that Visibility
+     * determines it for the actual animation.
+     *
+     * @param values The TransitionValues object that holds the information by
+     * which visibility is determined.
+     * @return True if the view reference by <code>values</code> is visible,
+     * false otherwise.
+     */
+    public boolean isVisible(TransitionValues values) {
+        if (values == null) {
+            return false;
+        }
+        int visibility = (Integer) values.values.get(PROPNAME_VISIBILITY);
+        View parent = (View) values.values.get(PROPNAME_PARENT);
+
+        return visibility == View.VISIBLE && parent != null;
+    }
+
+    /**
+     * Tests whether the hierarchy, up to the scene root, changes visibility between
+     * start and end scenes. This is done to ensure that a view that changes visibility
+     * is only animated if that view's parent was stable between scenes; we should not
+     * fade an entire hierarchy, but rather just the top-most node in the hierarchy that
+     * changed visibility. Note that both the start and end parents are passed in
+     * because the instances may differ for the same view due to layout inflation
+     * between scenes.
+     *
+     * @param sceneRoot The root of the scene hierarchy
+     * @param startView The container view in the start scene
+     * @param endView The container view in the end scene
+     * @return true if the parent hierarchy experienced a visibility change, false
+     * otherwise
+     */
+    private boolean isHierarchyVisibilityChanging(ViewGroup sceneRoot, ViewGroup startView,
+            ViewGroup endView) {
+
+        if (startView == sceneRoot || endView == sceneRoot) {
+            return false;
+        }
+        TransitionValues startValues = startView != null ?
+                getTransitionValues(startView, true) : getTransitionValues(endView, true);
+        TransitionValues endValues = endView != null ?
+                getTransitionValues(endView, false) : getTransitionValues(startView, false);
+
+        if (startValues == null || endValues == null) {
+            return true;
+        }
+        Integer visibility = (Integer) startValues.values.get(PROPNAME_VISIBILITY);
+        int startVisibility = (visibility != null) ? visibility : -1;
+        ViewGroup startParent = (ViewGroup) startValues.values.get(PROPNAME_PARENT);
+        visibility = (Integer) endValues.values.get(PROPNAME_VISIBILITY);
+        int endVisibility = (visibility != null) ? visibility : -1;
+        ViewGroup endParent = (ViewGroup) endValues.values.get(PROPNAME_PARENT);
+        if (startVisibility != endVisibility || startParent != endParent) {
+            return true;
+        }
+
+        if (startParent != null || endParent != null) {
+            return isHierarchyVisibilityChanging(sceneRoot, startParent, endParent);
+        }
+        return false;
+    }
+
+    private VisibilityInfo getVisibilityChangeInfo(TransitionValues startValues,
+            TransitionValues endValues) {
+        final VisibilityInfo visInfo = mTmpVisibilityInfo;
+        visInfo.visibilityChange = false;
+        visInfo.fadeIn = false;
+        if (startValues != null) {
+            visInfo.startVisibility = (Integer) startValues.values.get(PROPNAME_VISIBILITY);
+            visInfo.startParent = (ViewGroup) startValues.values.get(PROPNAME_PARENT);
+        } else {
+            visInfo.startVisibility = -1;
+            visInfo.startParent = null;
+        }
+        if (endValues != null) {
+            visInfo.endVisibility = (Integer) endValues.values.get(PROPNAME_VISIBILITY);
+            visInfo.endParent = (ViewGroup) endValues.values.get(PROPNAME_PARENT);
+        } else {
+            visInfo.endVisibility = -1;
+            visInfo.endParent = null;
+        }
+        if (startValues != null && endValues != null) {
+            if (visInfo.startVisibility == visInfo.endVisibility &&
+                    visInfo.startParent == visInfo.endParent) {
+                return visInfo;
+            } else {
+                if (visInfo.startVisibility != visInfo.endVisibility) {
+                    if (visInfo.startVisibility == View.VISIBLE) {
+                        visInfo.fadeIn = false;
+                        visInfo.visibilityChange = true;
+                    } else if (visInfo.endVisibility == View.VISIBLE) {
+                        visInfo.fadeIn = true;
+                        visInfo.visibilityChange = true;
+                    }
+                    // no visibilityChange if going between INVISIBLE and GONE
+                } else if (visInfo.startParent != visInfo.endParent) {
+                    if (visInfo.endParent == null) {
+                        visInfo.fadeIn = false;
+                        visInfo.visibilityChange = true;
+                    } else if (visInfo.startParent == null) {
+                        visInfo.fadeIn = true;
+                        visInfo.visibilityChange = true;
+                    }
+                }
+            }
+        }
+        if (startValues == null) {
+            visInfo.fadeIn = true;
+            visInfo.visibilityChange = true;
+        } else if (endValues == null) {
+            visInfo.fadeIn = false;
+            visInfo.visibilityChange = true;
+        }
+        return visInfo;
+    }
+
+    @Override
+    public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
+            TransitionValues endValues) {
+        VisibilityInfo visInfo = getVisibilityChangeInfo(startValues, endValues);
+        if (visInfo.visibilityChange) {
+            // Only transition views that are either targets of this transition
+            // or whose parent hierarchies remain stable between scenes
+            boolean isTarget = false;
+            if (mTargets.size() > 0 || mTargetIds.size() > 0) {
+                View startView = startValues != null ? startValues.view : null;
+                View endView = endValues != null ? endValues.view : null;
+                int startId = startView != null ? startView.getId() : -1;
+                int endId = endView != null ? endView.getId() : -1;
+                isTarget = isValidTarget(startView, startId) || isValidTarget(endView, endId);
+            }
+            if (isTarget || ((visInfo.startParent != null || visInfo.endParent != null) &&
+                    !isHierarchyVisibilityChanging(sceneRoot,
+                            visInfo.startParent, visInfo.endParent))) {
+                if (visInfo.fadeIn) {
+                    return onAppear(sceneRoot, startValues, visInfo.startVisibility,
+                            endValues, visInfo.endVisibility);
+                } else {
+                    return onDisappear(sceneRoot, startValues, visInfo.startVisibility,
+                            endValues, visInfo.endVisibility
+                    );
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * The default implementation of this method does nothing. Subclasses
+     * should override if they need to create an Animator when targets appear.
+     * The method should only be called by the Visibility class; it is
+     * not intended to be called from external classes.
+     *
+     * @param sceneRoot The root of the transition hierarchy
+     * @param startValues The target values in the start scene
+     * @param startVisibility The target visibility in the start scene
+     * @param endValues The target values in the end scene
+     * @param endVisibility The target visibility in the end scene
+     * @return An Animator to be started at the appropriate time in the
+     * overall transition for this scene change. A null value means no animation
+     * should be run.
+     */
+    public Animator onAppear(ViewGroup sceneRoot,
+            TransitionValues startValues, int startVisibility,
+            TransitionValues endValues, int endVisibility) {
+        return null;
+    }
+
+    /**
+     * The default implementation of this method does nothing. Subclasses
+     * should override if they need to create an Animator when targets disappear.
+     * The method should only be called by the Visibility class; it is
+     * not intended to be called from external classes.
+     *
+     *
+     * @param sceneRoot The root of the transition hierarchy
+     * @param startValues The target values in the start scene
+     * @param startVisibility The target visibility in the start scene
+     * @param endValues The target values in the end scene
+     * @param endVisibility The target visibility in the end scene
+     * @return An Animator to be started at the appropriate time in the
+     * overall transition for this scene change. A null value means no animation
+     * should be run.
+     */
+    public Animator onDisappear(ViewGroup sceneRoot,
+            TransitionValues startValues, int startVisibility,
+            TransitionValues endValues, int endVisibility) {
+        return null;
+    }
+}
diff --git a/core/java/android/transition/package.html b/core/java/android/transition/package.html
new file mode 100644
index 0000000..f357d34
--- /dev/null
+++ b/core/java/android/transition/package.html
@@ -0,0 +1,26 @@
+<html>
+<body>
+<p>The classes in this package enable "scenes & transitions" functionality for
+view hiearchies.</p>
+
+<p>A <b>Scene</b> is an encapsulation of the state of a view hierarchy,
+including the views in that hierarchy and the various values (layout-related
+and otherwise) that those views have. A scene can be defined by a layout hierarchy
+directly or by code which sets up the scene dynamically as it is entered.</p>
+
+<p>A <b>Transition</b> is a mechanism to automatically animate changes that occur
+when a new scene is entered. Some transition capabilities are automatic. That
+is, entering a scene may cause animations to run which fade out views that
+go away, changeBounds and resize existing views that change, and fade in views that
+become visible. There are additional transitions that can animate other
+attributes, such as color changes, and which can optionally be specified
+to take place during particular scene changes. Finally, developers can
+define their own Transition subclasses which monitor particular property
+changes and which run custom animations when those properties change values.</p>
+
+<p><b>TransitionManager</b> is used to specify custom transitions for particular
+scene changes, and to cause scene changes with specific transitions to
+take place.</p>
+
+</body>
+</html>
diff --git a/core/java/android/util/ArrayMap.java b/core/java/android/util/ArrayMap.java
new file mode 100644
index 0000000..fa534cc
--- /dev/null
+++ b/core/java/android/util/ArrayMap.java
@@ -0,0 +1,828 @@
+/*
+ * 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.util;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * ArrayMap is a generic key->value mapping data structure that is
+ * designed to be more memory efficient than a traditional {@link java.util.HashMap}.
+ * It keeps its mappings in an array data structure -- an integer array of hash
+ * codes for each item, and an Object array of the key/value pairs.  This allows it to
+ * avoid having to create an extra object for every entry put in to the map, and it
+ * also tries to control the growth of the size of these arrays more aggressively
+ * (since growing them only requires copying the entries in the array, not rebuilding
+ * a hash map).
+ *
+ * <p>Note that this implementation is not intended to be appropriate for data structures
+ * that may contain large numbers of items.  It is generally slower than a traditional
+ * HashMap, since lookups require a binary search and adds and removes require inserting
+ * and deleting entries in the array.  For containers holding up to hundreds of items,
+ * the performance difference is not significant, less than 50%.</p>
+ *
+ * <p>Because this container is intended to better balance memory use, unlike most other
+ * standard Java containers it will shrink its array as items are removed from it.  Currently
+ * you have no control over this shrinking -- if you set a capacity and then remove an
+ * item, it may reduce the capacity to better match the current size.  In the future an
+ * explicit call to set the capacity should turn off this aggressive shrinking behavior.</p>
+ */
+public final class ArrayMap<K, V> implements Map<K, V> {
+    private static final boolean DEBUG = false;
+    private static final String TAG = "ArrayMap";
+
+    /**
+     * The minimum amount by which the capacity of a ArrayMap will increase.
+     * This is tuned to be relatively space-efficient.
+     */
+    private static final int BASE_SIZE = 4;
+
+    /**
+     * Maximum number of entries to have in array caches.
+     */
+    private static final int CACHE_SIZE = 10;
+
+    /**
+     * @hide Special immutable empty ArrayMap.
+     */
+    public static final ArrayMap EMPTY = new ArrayMap(true);
+
+    /**
+     * Caches of small array objects to avoid spamming garbage.  The cache
+     * Object[] variable is a pointer to a linked list of array objects.
+     * The first entry in the array is a pointer to the next array in the
+     * list; the second entry is a pointer to the int[] hash code array for it.
+     */
+    static Object[] mBaseCache;
+    static int mBaseCacheSize;
+    static Object[] mTwiceBaseCache;
+    static int mTwiceBaseCacheSize;
+
+    /**
+     * Special hash array value that indicates the container is immutable.
+     */
+    static final int[] EMPTY_IMMUTABLE_INTS = new int[0];
+
+    int[] mHashes;
+    Object[] mArray;
+    int mSize;
+    MapCollections<K, V> mCollections;
+
+    int indexOf(Object key, int hash) {
+        final int N = mSize;
+
+        // Important fast case: if nothing is in here, nothing to look for.
+        if (N == 0) {
+            return ~0;
+        }
+
+        int index = ContainerHelpers.binarySearch(mHashes, N, hash);
+
+        // If the hash code wasn't found, then we have no entry for this key.
+        if (index < 0) {
+            return index;
+        }
+
+        // If the key at the returned index matches, that's what we want.
+        if (key.equals(mArray[index<<1])) {
+            return index;
+        }
+
+        // Search for a matching key after the index.
+        int end;
+        for (end = index + 1; end < N && mHashes[end] == hash; end++) {
+            if (key.equals(mArray[end << 1])) return end;
+        }
+
+        // Search for a matching key before the index.
+        for (int i = index - 1; i >= 0 && mHashes[i] == hash; i--) {
+            if (key.equals(mArray[i << 1])) return i;
+        }
+
+        // Key not found -- return negative value indicating where a
+        // new entry for this key should go.  We use the end of the
+        // hash chain to reduce the number of array entries that will
+        // need to be copied when inserting.
+        return ~end;
+    }
+
+    int indexOfNull() {
+        final int N = mSize;
+
+        // Important fast case: if nothing is in here, nothing to look for.
+        if (N == 0) {
+            return ~0;
+        }
+
+        int index = ContainerHelpers.binarySearch(mHashes, N, 0);
+
+        // If the hash code wasn't found, then we have no entry for this key.
+        if (index < 0) {
+            return index;
+        }
+
+        // If the key at the returned index matches, that's what we want.
+        if (null == mArray[index<<1]) {
+            return index;
+        }
+
+        // Search for a matching key after the index.
+        int end;
+        for (end = index + 1; end < N && mHashes[end] == 0; end++) {
+            if (null == mArray[end << 1]) return end;
+        }
+
+        // Search for a matching key before the index.
+        for (int i = index - 1; i >= 0 && mHashes[i] == 0; i--) {
+            if (null == mArray[i << 1]) return i;
+        }
+
+        // Key not found -- return negative value indicating where a
+        // new entry for this key should go.  We use the end of the
+        // hash chain to reduce the number of array entries that will
+        // need to be copied when inserting.
+        return ~end;
+    }
+
+    private void allocArrays(final int size) {
+        if (mHashes == EMPTY_IMMUTABLE_INTS) {
+            throw new UnsupportedOperationException("ArrayMap is immutable");
+        }
+        if (size == (BASE_SIZE*2)) {
+            synchronized (ArrayMap.class) {
+                if (mTwiceBaseCache != null) {
+                    final Object[] array = mTwiceBaseCache;
+                    mArray = array;
+                    mTwiceBaseCache = (Object[])array[0];
+                    mHashes = (int[])array[1];
+                    array[0] = array[1] = null;
+                    mTwiceBaseCacheSize--;
+                    if (DEBUG) Log.d(TAG, "Retrieving 2x cache " + mHashes
+                            + " now have " + mTwiceBaseCacheSize + " entries");
+                    return;
+                }
+            }
+        } else if (size == BASE_SIZE) {
+            synchronized (ArrayMap.class) {
+                if (mBaseCache != null) {
+                    final Object[] array = mBaseCache;
+                    mArray = array;
+                    mBaseCache = (Object[])array[0];
+                    mHashes = (int[])array[1];
+                    array[0] = array[1] = null;
+                    mBaseCacheSize--;
+                    if (DEBUG) Log.d(TAG, "Retrieving 1x cache " + mHashes
+                            + " now have " + mBaseCacheSize + " entries");
+                    return;
+                }
+            }
+        }
+
+        mHashes = new int[size];
+        mArray = new Object[size<<1];
+    }
+
+    private static void freeArrays(final int[] hashes, final Object[] array, final int size) {
+        if (hashes.length == (BASE_SIZE*2)) {
+            synchronized (ArrayMap.class) {
+                if (mTwiceBaseCacheSize < CACHE_SIZE) {
+                    array[0] = mTwiceBaseCache;
+                    array[1] = hashes;
+                    for (int i=(size<<1)-1; i>=2; i--) {
+                        array[i] = null;
+                    }
+                    mTwiceBaseCache = array;
+                    mTwiceBaseCacheSize++;
+                    if (DEBUG) Log.d(TAG, "Storing 2x cache " + array
+                            + " now have " + mTwiceBaseCacheSize + " entries");
+                }
+            }
+        } else if (hashes.length == BASE_SIZE) {
+            synchronized (ArrayMap.class) {
+                if (mBaseCacheSize < CACHE_SIZE) {
+                    array[0] = mBaseCache;
+                    array[1] = hashes;
+                    for (int i=(size<<1)-1; i>=2; i--) {
+                        array[i] = null;
+                    }
+                    mBaseCache = array;
+                    mBaseCacheSize++;
+                    if (DEBUG) Log.d(TAG, "Storing 1x cache " + array
+                            + " now have " + mBaseCacheSize + " entries");
+                }
+            }
+        }
+    }
+
+    /**
+     * Create a new empty ArrayMap.  The default capacity of an array map is 0, and
+     * will grow once items are added to it.
+     */
+    public ArrayMap() {
+        mHashes = ContainerHelpers.EMPTY_INTS;
+        mArray = ContainerHelpers.EMPTY_OBJECTS;
+        mSize = 0;
+    }
+
+    /**
+     * Create a new ArrayMap with a given initial capacity.
+     */
+    public ArrayMap(int capacity) {
+        if (capacity == 0) {
+            mHashes = ContainerHelpers.EMPTY_INTS;
+            mArray = ContainerHelpers.EMPTY_OBJECTS;
+        } else {
+            allocArrays(capacity);
+        }
+        mSize = 0;
+    }
+
+    private ArrayMap(boolean immutable) {
+        mHashes = EMPTY_IMMUTABLE_INTS;
+        mArray = ContainerHelpers.EMPTY_OBJECTS;
+        mSize = 0;
+    }
+
+    /**
+     * Create a new ArrayMap with the mappings from the given ArrayMap.
+     */
+    public ArrayMap(ArrayMap map) {
+        this();
+        if (map != null) {
+            putAll(map);
+        }
+    }
+
+    /**
+     * Make the array map empty.  All storage is released.
+     */
+    @Override
+    public void clear() {
+        if (mSize > 0) {
+            freeArrays(mHashes, mArray, mSize);
+            mHashes = ContainerHelpers.EMPTY_INTS;
+            mArray = ContainerHelpers.EMPTY_OBJECTS;
+            mSize = 0;
+        }
+    }
+
+    /**
+     * @hide
+     * Like {@link #clear}, but doesn't reduce the capacity of the ArrayMap.
+     */
+    public void erase() {
+        if (mSize > 0) {
+            final int N = mSize<<1;
+            final Object[] array = mArray;
+            for (int i=0; i<N; i++) {
+                array[i] = null;
+            }
+        }
+    }
+
+    /**
+     * Ensure the array map can hold at least <var>minimumCapacity</var>
+     * items.
+     */
+    public void ensureCapacity(int minimumCapacity) {
+        if (mHashes.length < minimumCapacity) {
+            final int[] ohashes = mHashes;
+            final Object[] oarray = mArray;
+            allocArrays(minimumCapacity);
+            if (mSize > 0) {
+                System.arraycopy(ohashes, 0, mHashes, 0, mSize);
+                System.arraycopy(oarray, 0, mArray, 0, mSize<<1);
+            }
+            freeArrays(ohashes, oarray, mSize);
+        }
+    }
+
+    /**
+     * Check whether a key exists in the array.
+     *
+     * @param key The key to search for.
+     * @return Returns true if the key exists, else false.
+     */
+    @Override
+    public boolean containsKey(Object key) {
+        return key == null ? (indexOfNull() >= 0) : (indexOf(key, key.hashCode()) >= 0);
+    }
+
+    int indexOfValue(Object value) {
+        final int N = mSize*2;
+        final Object[] array = mArray;
+        if (value == null) {
+            for (int i=1; i<N; i+=2) {
+                if (array[i] == null) {
+                    return i>>1;
+                }
+            }
+        } else {
+            for (int i=1; i<N; i+=2) {
+                if (value.equals(array[i])) {
+                    return i>>1;
+                }
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Check whether a value exists in the array.  This requires a linear search
+     * through the entire array.
+     *
+     * @param value The value to search for.
+     * @return Returns true if the value exists, else false.
+     */
+    @Override
+    public boolean containsValue(Object value) {
+        return indexOfValue(value) >= 0;
+    }
+
+    /**
+     * Retrieve a value from the array.
+     * @param key The key of the value to retrieve.
+     * @return Returns the value associated with the given key,
+     * or null if there is no such key.
+     */
+    @Override
+    public V get(Object key) {
+        final int index = key == null ? indexOfNull() : indexOf(key, key.hashCode());
+        return index >= 0 ? (V)mArray[(index<<1)+1] : null;
+    }
+
+    /**
+     * Return the key at the given index in the array.
+     * @param index The desired index, must be between 0 and {@link #size()}-1.
+     * @return Returns the key stored at the given index.
+     */
+    public K keyAt(int index) {
+        return (K)mArray[index << 1];
+    }
+
+    /**
+     * Return the value at the given index in the array.
+     * @param index The desired index, must be between 0 and {@link #size()}-1.
+     * @return Returns the value stored at the given index.
+     */
+    public V valueAt(int index) {
+        return (V)mArray[(index << 1) + 1];
+    }
+
+    /**
+     * Set the value at a given index in the array.
+     * @param index The desired index, must be between 0 and {@link #size()}-1.
+     * @param value The new value to store at this index.
+     * @return Returns the previous value at the given index.
+     */
+    public V setValueAt(int index, V value) {
+        index = (index << 1) + 1;
+        V old = (V)mArray[index];
+        mArray[index] = value;
+        return old;
+    }
+
+    /**
+     * Return true if the array map contains no items.
+     */
+    @Override
+    public boolean isEmpty() {
+        return mSize <= 0;
+    }
+
+    /**
+     * Add a new value to the array map.
+     * @param key The key under which to store the value.  <b>Must not be null.</b>  If
+     * this key already exists in the array, its value will be replaced.
+     * @param value The value to store for the given key.
+     * @return Returns the old value that was stored for the given key, or null if there
+     * was no such key.
+     */
+    @Override
+    public V put(K key, V value) {
+        final int hash;
+        int index;
+        if (key == null) {
+            hash = 0;
+            index = indexOfNull();
+        } else {
+            hash = key.hashCode();
+            index = indexOf(key, hash);
+        }
+        if (index >= 0) {
+            index = (index<<1) + 1;
+            final V old = (V)mArray[index];
+            mArray[index] = value;
+            return old;
+        }
+
+        index = ~index;
+        if (mSize >= mHashes.length) {
+            final int n = mSize >= (BASE_SIZE*2) ? (mSize+(mSize>>1))
+                    : (mSize >= BASE_SIZE ? (BASE_SIZE*2) : BASE_SIZE);
+
+            if (DEBUG) Log.d(TAG, "put: grow from " + mHashes.length + " to " + n);
+
+            final int[] ohashes = mHashes;
+            final Object[] oarray = mArray;
+            allocArrays(n);
+
+            if (mHashes.length > 0) {
+                if (DEBUG) Log.d(TAG, "put: copy 0-" + mSize + " to 0");
+                System.arraycopy(ohashes, 0, mHashes, 0, ohashes.length);
+                System.arraycopy(oarray, 0, mArray, 0, oarray.length);
+            }
+
+            freeArrays(ohashes, oarray, mSize);
+        }
+
+        if (index < mSize) {
+            if (DEBUG) Log.d(TAG, "put: move " + index + "-" + (mSize-index)
+                    + " to " + (index+1));
+            System.arraycopy(mHashes, index, mHashes, index + 1, mSize - index);
+            System.arraycopy(mArray, index << 1, mArray, (index + 1) << 1, (mSize - index) << 1);
+        }
+
+        mHashes[index] = hash;
+        mArray[index<<1] = key;
+        mArray[(index<<1)+1] = value;
+        mSize++;
+        return null;
+    }
+
+    /**
+     * Special fast path for appending items to the end of the array without validation.
+     * The array must already be large enough to contain the item.
+     * @hide
+     */
+    public void append(K key, V value) {
+        int index = mSize;
+        final int hash = key == null ? 0 : key.hashCode();
+        if (index >= mHashes.length) {
+            throw new IllegalStateException("Array is full");
+        }
+        if (index > 0 && mHashes[index-1] > hash) {
+            RuntimeException e = new RuntimeException("here");
+            e.fillInStackTrace();
+            Log.w(TAG, "New hash " + hash
+                    + " is before end of array hash " + mHashes[index-1]
+                    + " at index " + index + " key " + key, e);
+            put(key, value);
+            return;
+        }
+        mSize = index+1;
+        mHashes[index] = hash;
+        index <<= 1;
+        mArray[index] = key;
+        mArray[index+1] = value;
+    }
+
+    /**
+     * Perform a {@link #put(Object, Object)} of all key/value pairs in <var>array</var>
+     * @param array The array whose contents are to be retrieved.
+     */
+    public void putAll(ArrayMap<? extends K, ? extends V> array) {
+        final int N = array.mSize;
+        ensureCapacity(mSize + N);
+        if (mSize == 0) {
+            if (N > 0) {
+                System.arraycopy(array.mHashes, 0, mHashes, 0, N);
+                System.arraycopy(array.mArray, 0, mArray, 0, N<<1);
+                mSize = N;
+            }
+        } else {
+            for (int i=0; i<N; i++) {
+                put(array.keyAt(i), array.valueAt(i));
+            }
+        }
+    }
+
+    /**
+     * Remove an existing key from the array map.
+     * @param key The key of the mapping to remove.
+     * @return Returns the value that was stored under the key, or null if there
+     * was no such key.
+     */
+    @Override
+    public V remove(Object key) {
+        int index = key == null ? indexOfNull() : indexOf(key, key.hashCode());
+        if (index >= 0) {
+            return removeAt(index);
+        }
+
+        return null;
+    }
+
+    /**
+     * Remove the key/value mapping at the given index.
+     * @param index The desired index, must be between 0 and {@link #size()}-1.
+     * @return Returns the value that was stored at this index.
+     */
+    public V removeAt(int index) {
+        final Object old = mArray[(index << 1) + 1];
+        if (mSize <= 1) {
+            // Now empty.
+            if (DEBUG) Log.d(TAG, "remove: shrink from " + mHashes.length + " to 0");
+            freeArrays(mHashes, mArray, mSize);
+            mHashes = ContainerHelpers.EMPTY_INTS;
+            mArray = ContainerHelpers.EMPTY_OBJECTS;
+            mSize = 0;
+        } else {
+            if (mHashes.length > (BASE_SIZE*2) && mSize < mHashes.length/3) {
+                // Shrunk enough to reduce size of arrays.  We don't allow it to
+                // shrink smaller than (BASE_SIZE*2) to avoid flapping between
+                // that and BASE_SIZE.
+                final int n = mSize > (BASE_SIZE*2) ? (mSize + (mSize>>1)) : (BASE_SIZE*2);
+
+                if (DEBUG) Log.d(TAG, "remove: shrink from " + mHashes.length + " to " + n);
+
+                final int[] ohashes = mHashes;
+                final Object[] oarray = mArray;
+                allocArrays(n);
+
+                mSize--;
+                if (index > 0) {
+                    if (DEBUG) Log.d(TAG, "remove: copy from 0-" + index + " to 0");
+                    System.arraycopy(ohashes, 0, mHashes, 0, index);
+                    System.arraycopy(oarray, 0, mArray, 0, index << 1);
+                }
+                if (index < mSize) {
+                    if (DEBUG) Log.d(TAG, "remove: copy from " + (index+1) + "-" + mSize
+                            + " to " + index);
+                    System.arraycopy(ohashes, index + 1, mHashes, index, mSize - index);
+                    System.arraycopy(oarray, (index + 1) << 1, mArray, index << 1,
+                            (mSize - index) << 1);
+                }
+            } else {
+                mSize--;
+                if (index < mSize) {
+                    if (DEBUG) Log.d(TAG, "remove: move " + (index+1) + "-" + mSize
+                            + " to " + index);
+                    System.arraycopy(mHashes, index + 1, mHashes, index, mSize - index);
+                    System.arraycopy(mArray, (index + 1) << 1, mArray, index << 1,
+                            (mSize - index) << 1);
+                }
+                mArray[mSize << 1] = null;
+                mArray[(mSize << 1) + 1] = null;
+            }
+        }
+        return (V)old;
+    }
+
+    /**
+     * Return the number of items in this array map.
+     */
+    @Override
+    public int size() {
+        return mSize;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * <p>This implementation returns false if the object is not a map, or
+     * if the maps have different sizes. Otherwise, for each key in this map,
+     * values of both maps are compared. If the values for any key are not
+     * equal, the method returns false, otherwise it returns true.
+     */
+    @Override
+    public boolean equals(Object object) {
+        if (this == object) {
+            return true;
+        }
+        if (object instanceof Map) {
+            Map<?, ?> map = (Map<?, ?>) object;
+            if (size() != map.size()) {
+                return false;
+            }
+
+            try {
+                for (int i=0; i<mSize; i++) {
+                    K key = keyAt(i);
+                    V mine = valueAt(i);
+                    Object theirs = map.get(key);
+                    if (mine == null) {
+                        if (theirs != null || !map.containsKey(key)) {
+                            return false;
+                        }
+                    } else if (!mine.equals(theirs)) {
+                        return false;
+                    }
+                }
+            } catch (NullPointerException ignored) {
+                return false;
+            } catch (ClassCastException ignored) {
+                return false;
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode() {
+        final int[] hashes = mHashes;
+        final Object[] array = mArray;
+        int result = 0;
+        for (int i = 0, v = 1, s = mSize; i < s; i++, v+=2) {
+            Object value = array[v];
+            result += hashes[i] ^ (value == null ? 0 : value.hashCode());
+        }
+        return result;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * <p>This implementation composes a string by iterating over its mappings. If
+     * this map contains itself as a key or a value, the string "(this Map)"
+     * will appear in its place.
+     */
+    @Override
+    public String toString() {
+        if (isEmpty()) {
+            return "{}";
+        }
+
+        StringBuilder buffer = new StringBuilder(mSize * 28);
+        buffer.append('{');
+        for (int i=0; i<mSize; i++) {
+            if (i > 0) {
+                buffer.append(", ");
+            }
+            Object key = keyAt(i);
+            if (key != this) {
+                buffer.append(key);
+            } else {
+                buffer.append("(this Map)");
+            }
+            buffer.append('=');
+            Object value = valueAt(i);
+            if (value != this) {
+                buffer.append(value);
+            } else {
+                buffer.append("(this Map)");
+            }
+        }
+        buffer.append('}');
+        return buffer.toString();
+    }
+
+    // ------------------------------------------------------------------------
+    // Interop with traditional Java containers.  Not as efficient as using
+    // specialized collection APIs.
+    // ------------------------------------------------------------------------
+
+    private MapCollections<K, V> getCollection() {
+        if (mCollections == null) {
+            mCollections = new MapCollections<K, V>() {
+                @Override
+                protected int colGetSize() {
+                    return mSize;
+                }
+
+                @Override
+                protected Object colGetEntry(int index, int offset) {
+                    return mArray[(index<<1) + offset];
+                }
+
+                @Override
+                protected int colIndexOfKey(Object key) {
+                    return key == null ? indexOfNull() : indexOf(key, key.hashCode());
+                }
+
+                @Override
+                protected int colIndexOfValue(Object value) {
+                    return indexOfValue(value);
+                }
+
+                @Override
+                protected Map<K, V> colGetMap() {
+                    return ArrayMap.this;
+                }
+
+                @Override
+                protected void colPut(K key, V value) {
+                    put(key, value);
+                }
+
+                @Override
+                protected V colSetValue(int index, V value) {
+                    return setValueAt(index, value);
+                }
+
+                @Override
+                protected void colRemoveAt(int index) {
+                    removeAt(index);
+                }
+
+                @Override
+                protected void colClear() {
+                    clear();
+                }
+            };
+        }
+        return mCollections;
+    }
+
+    /**
+     * Determine if the array map contains all of the keys in the given collection.
+     * @param collection The collection whose contents are to be checked against.
+     * @return Returns true if this array map contains a key for every entry
+     * in <var>collection</var>, else returns false.
+     */
+    public boolean containsAll(Collection<?> collection) {
+        return MapCollections.containsAllHelper(this, collection);
+    }
+
+    /**
+     * Perform a {@link #put(Object, Object)} of all key/value pairs in <var>map</var>
+     * @param map The map whose contents are to be retrieved.
+     */
+    @Override
+    public void putAll(Map<? extends K, ? extends V> map) {
+        ensureCapacity(mSize + map.size());
+        for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) {
+            put(entry.getKey(), entry.getValue());
+        }
+    }
+
+    /**
+     * Remove all keys in the array map that exist in the given collection.
+     * @param collection The collection whose contents are to be used to remove keys.
+     * @return Returns true if any keys were removed from the array map, else false.
+     */
+    public boolean removeAll(Collection<?> collection) {
+        return MapCollections.removeAllHelper(this, collection);
+    }
+
+    /**
+     * Remove all keys in the array map that do <b>not</b> exist in the given collection.
+     * @param collection The collection whose contents are to be used to determine which
+     * keys to keep.
+     * @return Returns true if any keys were removed from the array map, else false.
+     */
+    public boolean retainAll(Collection<?> collection) {
+        return MapCollections.retainAllHelper(this, collection);
+    }
+
+    /**
+     * Return a {@link java.util.Set} for iterating over and interacting with all mappings
+     * in the array map.
+     *
+     * <p><b>Note:</b> this is a very inefficient way to access the array contents, it
+     * requires generating a number of temporary objects.</p>
+     *
+     * <p><b>Note:</b></p> the semantics of this
+     * Set are subtly different than that of a {@link java.util.HashMap}: most important,
+     * the {@link java.util.Map.Entry Map.Entry} object returned by its iterator is a single
+     * object that exists for the entire iterator, so you can <b>not</b> hold on to it
+     * after calling {@link java.util.Iterator#next() Iterator.next}.</p>
+     */
+    @Override
+    public Set<Map.Entry<K, V>> entrySet() {
+        return getCollection().getEntrySet();
+    }
+
+    /**
+     * Return a {@link java.util.Set} for iterating over and interacting with all keys
+     * in the array map.
+     *
+     * <p><b>Note:</b> this is a fairly inefficient way to access the array contents, it
+     * requires generating a number of temporary objects.</p>
+     */
+    @Override
+    public Set<K> keySet() {
+        return getCollection().getKeySet();
+    }
+
+    /**
+     * Return a {@link java.util.Collection} for iterating over and interacting with all values
+     * in the array map.
+     *
+     * <p><b>Note:</b> this is a fairly inefficient way to access the array contents, it
+     * requires generating a number of temporary objects.</p>
+     */
+    @Override
+    public Collection<V> values() {
+        return getCollection().getValues();
+    }
+}
diff --git a/core/java/android/util/ArraySet.java b/core/java/android/util/ArraySet.java
new file mode 100644
index 0000000..3c695e9
--- /dev/null
+++ b/core/java/android/util/ArraySet.java
@@ -0,0 +1,670 @@
+/*
+ * 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.util;
+
+import java.lang.reflect.Array;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * ArraySet is a generic set data structure that is designed to be more memory efficient than a
+ * traditional {@link java.util.HashSet}.  The design is very similar to
+ * {@link ArrayMap}, with all of the caveats described there.  This implementation is
+ * separate from ArrayMap, however, so the Object array contains only one item for each
+ * entry in the set (instead of a pair for a mapping).
+ *
+ * <p>Note that this implementation is not intended to be appropriate for data structures
+ * that may contain large numbers of items.  It is generally slower than a traditional
+ * HashSet, since lookups require a binary search and adds and removes require inserting
+ * and deleting entries in the array.  For containers holding up to hundreds of items,
+ * the performance difference is not significant, less than 50%.</p>
+ *
+ * <p>Because this container is intended to better balance memory use, unlike most other
+ * standard Java containers it will shrink its array as items are removed from it.  Currently
+ * you have no control over this shrinking -- if you set a capacity and then remove an
+ * item, it may reduce the capacity to better match the current size.  In the future an
+ * explicit call to set the capacity should turn off this aggressive shrinking behavior.</p>
+ *
+ * @hide
+ */
+public final class ArraySet<E> implements Collection<E>, Set<E> {
+    private static final boolean DEBUG = false;
+    private static final String TAG = "ArraySet";
+
+    /**
+     * The minimum amount by which the capacity of a ArraySet will increase.
+     * This is tuned to be relatively space-efficient.
+     */
+    private static final int BASE_SIZE = 4;
+
+    /**
+     * Maximum number of entries to have in array caches.
+     */
+    private static final int CACHE_SIZE = 10;
+
+    /**
+     * Caches of small array objects to avoid spamming garbage.  The cache
+     * Object[] variable is a pointer to a linked list of array objects.
+     * The first entry in the array is a pointer to the next array in the
+     * list; the second entry is a pointer to the int[] hash code array for it.
+     */
+    static Object[] mBaseCache;
+    static int mBaseCacheSize;
+    static Object[] mTwiceBaseCache;
+    static int mTwiceBaseCacheSize;
+
+    int[] mHashes;
+    Object[] mArray;
+    int mSize;
+    MapCollections<E, E> mCollections;
+
+    private int indexOf(Object key, int hash) {
+        final int N = mSize;
+
+        // Important fast case: if nothing is in here, nothing to look for.
+        if (N == 0) {
+            return ~0;
+        }
+
+        int index = ContainerHelpers.binarySearch(mHashes, N, hash);
+
+        // If the hash code wasn't found, then we have no entry for this key.
+        if (index < 0) {
+            return index;
+        }
+
+        // If the key at the returned index matches, that's what we want.
+        if (key.equals(mArray[index])) {
+            return index;
+        }
+
+        // Search for a matching key after the index.
+        int end;
+        for (end = index + 1; end < N && mHashes[end] == hash; end++) {
+            if (key.equals(mArray[end])) return end;
+        }
+
+        // Search for a matching key before the index.
+        for (int i = index - 1; i >= 0 && mHashes[i] == hash; i--) {
+            if (key.equals(mArray[i])) return i;
+        }
+
+        // Key not found -- return negative value indicating where a
+        // new entry for this key should go.  We use the end of the
+        // hash chain to reduce the number of array entries that will
+        // need to be copied when inserting.
+        return ~end;
+    }
+
+    private int indexOfNull() {
+        final int N = mSize;
+
+        // Important fast case: if nothing is in here, nothing to look for.
+        if (N == 0) {
+            return ~0;
+        }
+
+        int index = ContainerHelpers.binarySearch(mHashes, N, 0);
+
+        // If the hash code wasn't found, then we have no entry for this key.
+        if (index < 0) {
+            return index;
+        }
+
+        // If the key at the returned index matches, that's what we want.
+        if (null == mArray[index]) {
+            return index;
+        }
+
+        // Search for a matching key after the index.
+        int end;
+        for (end = index + 1; end < N && mHashes[end] == 0; end++) {
+            if (null == mArray[end]) return end;
+        }
+
+        // Search for a matching key before the index.
+        for (int i = index - 1; i >= 0 && mHashes[i] == 0; i--) {
+            if (null == mArray[i]) return i;
+        }
+
+        // Key not found -- return negative value indicating where a
+        // new entry for this key should go.  We use the end of the
+        // hash chain to reduce the number of array entries that will
+        // need to be copied when inserting.
+        return ~end;
+    }
+
+    private void allocArrays(final int size) {
+        if (size == (BASE_SIZE*2)) {
+            synchronized (ArraySet.class) {
+                if (mTwiceBaseCache != null) {
+                    final Object[] array = mTwiceBaseCache;
+                    mArray = array;
+                    mTwiceBaseCache = (Object[])array[0];
+                    mHashes = (int[])array[1];
+                    array[0] = array[1] = null;
+                    mTwiceBaseCacheSize--;
+                    if (DEBUG) Log.d(TAG, "Retrieving 2x cache " + mHashes
+                            + " now have " + mTwiceBaseCacheSize + " entries");
+                    return;
+                }
+            }
+        } else if (size == BASE_SIZE) {
+            synchronized (ArraySet.class) {
+                if (mBaseCache != null) {
+                    final Object[] array = mBaseCache;
+                    mArray = array;
+                    mBaseCache = (Object[])array[0];
+                    mHashes = (int[])array[1];
+                    array[0] = array[1] = null;
+                    mBaseCacheSize--;
+                    if (DEBUG) Log.d(TAG, "Retrieving 1x cache " + mHashes
+                            + " now have " + mBaseCacheSize + " entries");
+                    return;
+                }
+            }
+        }
+
+        mHashes = new int[size];
+        mArray = new Object[size];
+    }
+
+    private static void freeArrays(final int[] hashes, final Object[] array, final int size) {
+        if (hashes.length == (BASE_SIZE*2)) {
+            synchronized (ArraySet.class) {
+                if (mTwiceBaseCacheSize < CACHE_SIZE) {
+                    array[0] = mTwiceBaseCache;
+                    array[1] = hashes;
+                    for (int i=size-1; i>=2; i--) {
+                        array[i] = null;
+                    }
+                    mTwiceBaseCache = array;
+                    mTwiceBaseCacheSize++;
+                    if (DEBUG) Log.d(TAG, "Storing 2x cache " + array
+                            + " now have " + mTwiceBaseCacheSize + " entries");
+                }
+            }
+        } else if (hashes.length == BASE_SIZE) {
+            synchronized (ArraySet.class) {
+                if (mBaseCacheSize < CACHE_SIZE) {
+                    array[0] = mBaseCache;
+                    array[1] = hashes;
+                    for (int i=size-1; i>=2; i--) {
+                        array[i] = null;
+                    }
+                    mBaseCache = array;
+                    mBaseCacheSize++;
+                    if (DEBUG) Log.d(TAG, "Storing 1x cache " + array
+                            + " now have " + mBaseCacheSize + " entries");
+                }
+            }
+        }
+    }
+
+    /**
+     * Create a new empty ArraySet.  The default capacity of an array map is 0, and
+     * will grow once items are added to it.
+     */
+    public ArraySet() {
+        mHashes = ContainerHelpers.EMPTY_INTS;
+        mArray = ContainerHelpers.EMPTY_OBJECTS;
+        mSize = 0;
+    }
+
+    /**
+     * Create a new ArraySet with a given initial capacity.
+     */
+    public ArraySet(int capacity) {
+        if (capacity == 0) {
+            mHashes = ContainerHelpers.EMPTY_INTS;
+            mArray = ContainerHelpers.EMPTY_OBJECTS;
+        } else {
+            allocArrays(capacity);
+        }
+        mSize = 0;
+    }
+
+    /**
+     * Create a new ArraySet with the mappings from the given ArraySet.
+     */
+    public ArraySet(ArraySet set) {
+        this();
+        if (set != null) {
+            addAll(set);
+        }
+    }
+
+
+    /**
+     * Make the array map empty.  All storage is released.
+     */
+    @Override
+    public void clear() {
+        if (mSize != 0) {
+            freeArrays(mHashes, mArray, mSize);
+            mHashes = ContainerHelpers.EMPTY_INTS;
+            mArray = ContainerHelpers.EMPTY_OBJECTS;
+            mSize = 0;
+        }
+    }
+
+    /**
+     * Ensure the array map can hold at least <var>minimumCapacity</var>
+     * items.
+     */
+    public void ensureCapacity(int minimumCapacity) {
+        if (mHashes.length < minimumCapacity) {
+            final int[] ohashes = mHashes;
+            final Object[] oarray = mArray;
+            allocArrays(minimumCapacity);
+            if (mSize > 0) {
+                System.arraycopy(ohashes, 0, mHashes, 0, mSize);
+                System.arraycopy(oarray, 0, mArray, 0, mSize);
+            }
+            freeArrays(ohashes, oarray, mSize);
+        }
+    }
+
+    /**
+     * Check whether a value exists in the set.
+     *
+     * @param key The value to search for.
+     * @return Returns true if the value exists, else false.
+     */
+    @Override
+    public boolean contains(Object key) {
+        return key == null ? (indexOfNull() >= 0) : (indexOf(key, key.hashCode()) >= 0);
+    }
+
+    /**
+     * Return the value at the given index in the array.
+     * @param index The desired index, must be between 0 and {@link #size()}-1.
+     * @return Returns the value stored at the given index.
+     */
+    public E valueAt(int index) {
+        return (E)mArray[index];
+    }
+
+    /**
+     * Return true if the array map contains no items.
+     */
+    @Override
+    public boolean isEmpty() {
+        return mSize <= 0;
+    }
+
+    /**
+     * Adds the specified object to this set. The set is not modified if it
+     * already contains the object.
+     *
+     * @param value the object to add.
+     * @return {@code true} if this set is modified, {@code false} otherwise.
+     * @throws ClassCastException
+     *             when the class of the object is inappropriate for this set.
+     */
+    @Override
+    public boolean add(E value) {
+        final int hash;
+        int index;
+        if (value == null) {
+            hash = 0;
+            index = indexOfNull();
+        } else {
+            hash = value.hashCode();
+            index = indexOf(value, hash);
+        }
+        if (index >= 0) {
+            return false;
+        }
+
+        index = ~index;
+        if (mSize >= mHashes.length) {
+            final int n = mSize >= (BASE_SIZE*2) ? (mSize+(mSize>>1))
+                    : (mSize >= BASE_SIZE ? (BASE_SIZE*2) : BASE_SIZE);
+
+            if (DEBUG) Log.d(TAG, "add: grow from " + mHashes.length + " to " + n);
+
+            final int[] ohashes = mHashes;
+            final Object[] oarray = mArray;
+            allocArrays(n);
+
+            if (mHashes.length > 0) {
+                if (DEBUG) Log.d(TAG, "add: copy 0-" + mSize + " to 0");
+                System.arraycopy(ohashes, 0, mHashes, 0, ohashes.length);
+                System.arraycopy(oarray, 0, mArray, 0, oarray.length);
+            }
+
+            freeArrays(ohashes, oarray, mSize);
+        }
+
+        if (index < mSize) {
+            if (DEBUG) Log.d(TAG, "add: move " + index + "-" + (mSize-index)
+                    + " to " + (index+1));
+            System.arraycopy(mHashes, index, mHashes, index + 1, mSize - index);
+            System.arraycopy(mArray, index, mArray, index + 1, mSize - index);
+        }
+
+        mHashes[index] = hash;
+        mArray[index] = value;
+        mSize++;
+        return true;
+    }
+
+    /**
+     * Perform a {@link #add(Object)} of all values in <var>array</var>
+     * @param array The array whose contents are to be retrieved.
+     */
+    public void putAll(ArraySet<? extends E> array) {
+        final int N = array.mSize;
+        ensureCapacity(mSize + N);
+        if (mSize == 0) {
+            if (N > 0) {
+                System.arraycopy(array.mHashes, 0, mHashes, 0, N);
+                System.arraycopy(array.mArray, 0, mArray, 0, N);
+                mSize = N;
+            }
+        } else {
+            for (int i=0; i<N; i++) {
+                add(array.valueAt(i));
+            }
+        }
+    }
+
+    /**
+     * Removes the specified object from this set.
+     *
+     * @param object the object to remove.
+     * @return {@code true} if this set was modified, {@code false} otherwise.
+     */
+    @Override
+    public boolean remove(Object object) {
+        int index = object == null ? indexOfNull() : indexOf(object, object.hashCode());
+        if (index >= 0) {
+            removeAt(index);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Remove the key/value mapping at the given index.
+     * @param index The desired index, must be between 0 and {@link #size()}-1.
+     * @return Returns the value that was stored at this index.
+     */
+    public E removeAt(int index) {
+        final Object old = mArray[index];
+        if (mSize <= 1) {
+            // Now empty.
+            if (DEBUG) Log.d(TAG, "remove: shrink from " + mHashes.length + " to 0");
+            freeArrays(mHashes, mArray, mSize);
+            mHashes = ContainerHelpers.EMPTY_INTS;
+            mArray = ContainerHelpers.EMPTY_OBJECTS;
+            mSize = 0;
+        } else {
+            if (mHashes.length > (BASE_SIZE*2) && mSize < mHashes.length/3) {
+                // Shrunk enough to reduce size of arrays.  We don't allow it to
+                // shrink smaller than (BASE_SIZE*2) to avoid flapping between
+                // that and BASE_SIZE.
+                final int n = mSize > (BASE_SIZE*2) ? (mSize + (mSize>>1)) : (BASE_SIZE*2);
+
+                if (DEBUG) Log.d(TAG, "remove: shrink from " + mHashes.length + " to " + n);
+
+                final int[] ohashes = mHashes;
+                final Object[] oarray = mArray;
+                allocArrays(n);
+
+                mSize--;
+                if (index > 0) {
+                    if (DEBUG) Log.d(TAG, "remove: copy from 0-" + index + " to 0");
+                    System.arraycopy(ohashes, 0, mHashes, 0, index);
+                    System.arraycopy(oarray, 0, mArray, 0, index);
+                }
+                if (index < mSize) {
+                    if (DEBUG) Log.d(TAG, "remove: copy from " + (index+1) + "-" + mSize
+                            + " to " + index);
+                    System.arraycopy(ohashes, index + 1, mHashes, index, mSize - index);
+                    System.arraycopy(oarray, index + 1, mArray, index, mSize - index);
+                }
+            } else {
+                mSize--;
+                if (index < mSize) {
+                    if (DEBUG) Log.d(TAG, "remove: move " + (index+1) + "-" + mSize
+                            + " to " + index);
+                    System.arraycopy(mHashes, index + 1, mHashes, index, mSize - index);
+                    System.arraycopy(mArray, index + 1, mArray, index, mSize - index);
+                }
+                mArray[mSize] = null;
+            }
+        }
+        return (E)old;
+    }
+
+    /**
+     * Return the number of items in this array map.
+     */
+    @Override
+    public int size() {
+        return mSize;
+    }
+
+    @Override
+    public Object[] toArray() {
+        Object[] result = new Object[mSize];
+        System.arraycopy(mArray, 0, result, 0, mSize);
+        return result;
+    }
+
+    @Override
+    public <T> T[] toArray(T[] array) {
+        if (array.length < mSize) {
+            @SuppressWarnings("unchecked") T[] newArray
+                = (T[]) Array.newInstance(array.getClass().getComponentType(), mSize);
+            array = newArray;
+        }
+        System.arraycopy(mArray, 0, array, 0, mSize);
+        if (array.length > mSize) {
+            array[mSize] = null;
+        }
+        return array;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * <p>This implementation returns false if the object is not a set, or
+     * if the sets have different sizes.  Otherwise, for each value in this
+     * set, it checks to make sure the value also exists in the other set.
+     * If any value doesn't exist, the method returns false; otherwise, it
+     * returns true.
+     */
+    @Override
+    public boolean equals(Object object) {
+        if (this == object) {
+            return true;
+        }
+        if (object instanceof Set) {
+            Set<?> set = (Set<?>) object;
+            if (size() != set.size()) {
+                return false;
+            }
+
+            try {
+                for (int i=0; i<mSize; i++) {
+                    E mine = valueAt(i);
+                    if (!set.contains(mine)) {
+                        return false;
+                    }
+                }
+            } catch (NullPointerException ignored) {
+                return false;
+            } catch (ClassCastException ignored) {
+                return false;
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode() {
+        final int[] hashes = mHashes;
+        int result = 0;
+        for (int i = 0, s = mSize; i < s; i++) {
+            result += hashes[i];
+        }
+        return result;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * <p>This implementation composes a string by iterating over its values. If
+     * this set contains itself as a value, the string "(this Set)"
+     * will appear in its place.
+     */
+    @Override
+    public String toString() {
+        if (isEmpty()) {
+            return "{}";
+        }
+
+        StringBuilder buffer = new StringBuilder(mSize * 14);
+        buffer.append('{');
+        for (int i=0; i<mSize; i++) {
+            if (i > 0) {
+                buffer.append(", ");
+            }
+            Object value = valueAt(i);
+            if (value != this) {
+                buffer.append(value);
+            } else {
+                buffer.append("(this Set)");
+            }
+        }
+        buffer.append('}');
+        return buffer.toString();
+    }
+
+    // ------------------------------------------------------------------------
+    // Interop with traditional Java containers.  Not as efficient as using
+    // specialized collection APIs.
+    // ------------------------------------------------------------------------
+
+    private MapCollections<E, E> getCollection() {
+        if (mCollections == null) {
+            mCollections = new MapCollections<E, E>() {
+                @Override
+                protected int colGetSize() {
+                    return mSize;
+                }
+
+                @Override
+                protected Object colGetEntry(int index, int offset) {
+                    return mArray[index];
+                }
+
+                @Override
+                protected int colIndexOfKey(Object key) {
+                    return key == null ? indexOfNull() : indexOf(key, key.hashCode());
+                }
+
+                @Override
+                protected int colIndexOfValue(Object value) {
+                    return value == null ? indexOfNull() : indexOf(value, value.hashCode());
+                }
+
+                @Override
+                protected Map<E, E> colGetMap() {
+                    throw new UnsupportedOperationException("not a map");
+                }
+
+                @Override
+                protected void colPut(E key, E value) {
+                    add(key);
+                }
+
+                @Override
+                protected E colSetValue(int index, E value) {
+                    throw new UnsupportedOperationException("not a map");
+                }
+
+                @Override
+                protected void colRemoveAt(int index) {
+                    removeAt(index);
+                }
+
+                @Override
+                protected void colClear() {
+                    clear();
+                }
+            };
+        }
+        return mCollections;
+    }
+
+    @Override
+    public Iterator<E> iterator() {
+        return getCollection().getKeySet().iterator();
+    }
+
+    @Override
+    public boolean containsAll(Collection<?> collection) {
+        Iterator<?> it = collection.iterator();
+        while (it.hasNext()) {
+            if (!contains(it.next())) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public boolean addAll(Collection<? extends E> collection) {
+        ensureCapacity(mSize + collection.size());
+        boolean added = false;
+        for (E value : collection) {
+            added |= add(value);
+        }
+        return added;
+    }
+
+    @Override
+    public boolean removeAll(Collection<?> collection) {
+        boolean removed = false;
+        for (Object value : collection) {
+            removed |= remove(value);
+        }
+        return removed;
+    }
+
+    @Override
+    public boolean retainAll(Collection<?> collection) {
+        boolean removed = false;
+        for (int i=mSize-1; i>=0; i--) {
+            if (!collection.contains(mArray[i])) {
+                removeAt(i);
+                removed = true;
+            }
+        }
+        return removed;
+    }
+}
diff --git a/core/java/android/util/ContainerHelpers.java b/core/java/android/util/ContainerHelpers.java
new file mode 100644
index 0000000..624c4bd
--- /dev/null
+++ b/core/java/android/util/ContainerHelpers.java
@@ -0,0 +1,63 @@
+/*
+ * 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.util;
+
+class ContainerHelpers {
+    static final boolean[] EMPTY_BOOLEANS = new boolean[0];
+    static final int[] EMPTY_INTS = new int[0];
+    static final long[] EMPTY_LONGS = new long[0];
+    static final Object[] EMPTY_OBJECTS = new Object[0];
+
+    // This is Arrays.binarySearch(), but doesn't do any argument validation.
+    static int binarySearch(int[] array, int size, int value) {
+        int lo = 0;
+        int hi = size - 1;
+
+        while (lo <= hi) {
+            final int mid = (lo + hi) >>> 1;
+            final int midVal = array[mid];
+
+            if (midVal < value) {
+                lo = mid + 1;
+            } else if (midVal > value) {
+                hi = mid - 1;
+            } else {
+                return mid;  // value found
+            }
+        }
+        return ~lo;  // value not present
+    }
+
+    static int binarySearch(long[] array, int size, long value) {
+        int lo = 0;
+        int hi = size - 1;
+
+        while (lo <= hi) {
+            final int mid = (lo + hi) >>> 1;
+            final long midVal = array[mid];
+
+            if (midVal < value) {
+                lo = mid + 1;
+            } else if (midVal > value) {
+                hi = mid - 1;
+            } else {
+                return mid;  // value found
+            }
+        }
+        return ~lo;  // value not present
+    }
+}
diff --git a/core/java/android/util/LayoutDirection.java b/core/java/android/util/LayoutDirection.java
new file mode 100644
index 0000000..20af20b
--- /dev/null
+++ b/core/java/android/util/LayoutDirection.java
@@ -0,0 +1,48 @@
+/*
+ * 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.util;
+
+/**
+ * A class for defining layout directions. A layout direction can be left-to-right (LTR)
+ * or right-to-left (RTL). It can also be inherited (from a parent) or deduced from the default
+ * language script of a locale.
+ */
+public final class LayoutDirection {
+
+    // No instantiation
+    private LayoutDirection() {}
+
+    /**
+     * Horizontal layout direction is from Left to Right.
+     */
+    public static final int LTR = 0;
+
+    /**
+     * Horizontal layout direction is from Right to Left.
+     */
+    public static final int RTL = 1;
+
+    /**
+     * Horizontal layout direction is inherited.
+     */
+    public static final int INHERIT = 2;
+
+    /**
+     * Horizontal layout direction is deduced from the default language script for the locale.
+     */
+    public static final int LOCALE = 3;
+}
diff --git a/core/java/android/util/Log.java b/core/java/android/util/Log.java
index 1c3709f..6a6f027 100644
--- a/core/java/android/util/Log.java
+++ b/core/java/android/util/Log.java
@@ -17,6 +17,7 @@
 package android.util;
 
 import com.android.internal.os.RuntimeInit;
+import com.android.internal.util.FastPrintWriter;
 
 import java.io.PrintWriter;
 import java.io.StringWriter;
@@ -315,8 +316,9 @@
         }
 
         StringWriter sw = new StringWriter();
-        PrintWriter pw = new PrintWriter(sw);
+        PrintWriter pw = new FastPrintWriter(sw, false, 256);
         tr.printStackTrace(pw);
+        pw.flush();
         return sw.toString();
     }
 
diff --git a/core/java/android/util/LongSparseArray.java b/core/java/android/util/LongSparseArray.java
index 630e5f3..d6e116f 100644
--- a/core/java/android/util/LongSparseArray.java
+++ b/core/java/android/util/LongSparseArray.java
@@ -20,8 +20,31 @@
 
 /**
  * SparseArray mapping longs 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 Longs to Objects.
+ * there can be gaps in the indices.  It is intended to be more memory efficient
+ * than using a HashMap to map Longs to Objects, both because it avoids
+ * auto-boxing keys and its data structure doesn't rely on an extra entry object
+ * for each mapping.
+ *
+ * <p>Note that this container keeps its mappings in an array data structure,
+ * using a binary search to find keys.  The implementation is not intended to be appropriate for
+ * data structures
+ * that may contain large numbers of items.  It is generally slower than a traditional
+ * HashMap, since lookups require a binary search and adds and removes require inserting
+ * and deleting entries in the array.  For containers holding up to hundreds of items,
+ * the performance difference is not significant, less than 50%.</p>
+ *
+ * <p>To help with performance, the container includes an optimization when removing
+ * keys: instead of compacting its array immediately, it leaves the removed entry marked
+ * as deleted.  The entry can then be re-used for the same key, or compacted later in
+ * a single garbage collection step of all removed entries.  This garbage collection will
+ * need to be performed at any time the array needs to be grown or the the map size or
+ * entry values are retrieved.</p>
+ *
+ * <p>It is possible to iterate over the items in this container using
+ * {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
+ * <code>keyAt(int)</code> with ascending values of the index will return the
+ * keys in ascending order, or the values corresponding to the keys in ascending
+ * order in the case of <code>valueAt(int)<code>.</p>
  */
 public class LongSparseArray<E> implements Cloneable {
     private static final Object DELETED = new Object();
@@ -41,13 +64,19 @@
     /**
      * Creates a new LongSparseArray containing no mappings that will not
      * require any additional memory allocation to store the specified
-     * number of mappings.
+     * number of mappings.  If you supply an initial capacity of 0, the
+     * sparse array will be initialized with a light-weight representation
+     * not requiring any additional array allocations.
      */
     public LongSparseArray(int initialCapacity) {
-        initialCapacity = ArrayUtils.idealLongArraySize(initialCapacity);
-
-        mKeys = new long[initialCapacity];
-        mValues = new Object[initialCapacity];
+        if (initialCapacity == 0) {
+            mKeys = ContainerHelpers.EMPTY_LONGS;
+            mValues = ContainerHelpers.EMPTY_OBJECTS;
+        } else {
+            initialCapacity = ArrayUtils.idealLongArraySize(initialCapacity);
+            mKeys = new long[initialCapacity];
+            mValues = new Object[initialCapacity];
+        }
         mSize = 0;
     }
 
@@ -79,7 +108,7 @@
      */
     @SuppressWarnings("unchecked")
     public E get(long key, E valueIfKeyNotFound) {
-        int i = binarySearch(mKeys, 0, mSize, key);
+        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
 
         if (i < 0 || mValues[i] == DELETED) {
             return valueIfKeyNotFound;
@@ -92,7 +121,7 @@
      * Removes the mapping from the specified key, if there was any.
      */
     public void delete(long key) {
-        int i = binarySearch(mKeys, 0, mSize, key);
+        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
 
         if (i >= 0) {
             if (mValues[i] != DELETED) {
@@ -153,7 +182,7 @@
      * was one.
      */
     public void put(long key, E value) {
-        int i = binarySearch(mKeys, 0, mSize, key);
+        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
 
         if (i >= 0) {
             mValues[i] = value;
@@ -170,7 +199,7 @@
                 gc();
 
                 // Search again because indices may have changed.
-                i = ~binarySearch(mKeys, 0, mSize, key);
+                i = ~ContainerHelpers.binarySearch(mKeys, mSize, key);
             }
 
             if (mSize >= mKeys.length) {
@@ -215,6 +244,11 @@
      * 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
      * LongSparseArray stores.
+     *
+     * <p>The keys corresponding to indices in ascending order are guaranteed to
+     * be in ascending order, e.g., <code>keyAt(0)</code> will return the
+     * smallest key and <code>keyAt(size()-1)</code> will return the largest
+     * key.</p>
      */
     public long keyAt(int index) {
         if (mGarbage) {
@@ -228,6 +262,12 @@
      * 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
      * LongSparseArray stores.
+     *
+     * <p>The values corresponding to indices in ascending order are guaranteed
+     * to be associated with keys in ascending order, e.g.,
+     * <code>valueAt(0)</code> will return the value associated with the
+     * smallest key and <code>valueAt(size()-1)</code> will return the value
+     * associated with the largest key.</p>
      */
     @SuppressWarnings("unchecked")
     public E valueAt(int index) {
@@ -261,7 +301,7 @@
             gc();
         }
 
-        return binarySearch(mKeys, 0, mSize, key);
+        return ContainerHelpers.binarySearch(mKeys, mSize, key);
     }
 
     /**
@@ -333,23 +373,36 @@
         mSize = pos + 1;
     }
 
-    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;
+    /**
+     * {@inheritDoc}
+     *
+     * <p>This implementation composes a string by iterating over its mappings. If
+     * this map contains itself as a value, the string "(this Map)"
+     * will appear in its place.
+     */
+    @Override
+    public String toString() {
+        if (size() <= 0) {
+            return "{}";
         }
 
-        if (high == start + len)
-            return ~(start + len);
-        else if (a[high] == key)
-            return high;
-        else
-            return ~high;
+        StringBuilder buffer = new StringBuilder(mSize * 28);
+        buffer.append('{');
+        for (int i=0; i<mSize; i++) {
+            if (i > 0) {
+                buffer.append(", ");
+            }
+            long key = keyAt(i);
+            buffer.append(key);
+            buffer.append('=');
+            Object value = valueAt(i);
+            if (value != this) {
+                buffer.append(value);
+            } else {
+                buffer.append("(this Map)");
+            }
+        }
+        buffer.append('}');
+        return buffer.toString();
     }
 }
diff --git a/core/java/android/util/LongSparseLongArray.java b/core/java/android/util/LongSparseLongArray.java
index 34b6126..87d868b 100644
--- a/core/java/android/util/LongSparseLongArray.java
+++ b/core/java/android/util/LongSparseLongArray.java
@@ -22,8 +22,24 @@
 
 /**
  * Map of {@code long} to {@code long}. Unlike a normal array of longs, there
- * can be gaps in the indices. It is intended to be more efficient than using a
- * {@code HashMap}.
+ * can be gaps in the indices. It is intended to be more memory efficient than using a
+ * {@code HashMap}, both because it avoids
+ * auto-boxing keys and values and its data structure doesn't rely on an extra entry object
+ * for each mapping.
+ *
+ * <p>Note that this container keeps its mappings in an array data structure,
+ * using a binary search to find keys.  The implementation is not intended to be appropriate for
+ * data structures
+ * that may contain large numbers of items.  It is generally slower than a traditional
+ * HashMap, since lookups require a binary search and adds and removes require inserting
+ * and deleting entries in the array.  For containers holding up to hundreds of items,
+ * the performance difference is not significant, less than 50%.</p>
+ *
+ * <p>It is possible to iterate over the items in this container using
+ * {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
+ * <code>keyAt(int)</code> with ascending values of the index will return the
+ * keys in ascending order, or the values corresponding to the keys in ascending
+ * order in the case of <code>valueAt(int)<code>.</p>
  *
  * @hide
  */
@@ -42,13 +58,19 @@
     /**
      * Creates a new SparseLongArray containing no mappings that will not
      * require any additional memory allocation to store the specified
-     * number of mappings.
+     * number of mappings.  If you supply an initial capacity of 0, the
+     * sparse array will be initialized with a light-weight representation
+     * not requiring any additional array allocations.
      */
     public LongSparseLongArray(int initialCapacity) {
-        initialCapacity = ArrayUtils.idealLongArraySize(initialCapacity);
-
-        mKeys = new long[initialCapacity];
-        mValues = new long[initialCapacity];
+        if (initialCapacity == 0) {
+            mKeys = ContainerHelpers.EMPTY_LONGS;
+            mValues = ContainerHelpers.EMPTY_LONGS;
+        } else {
+            initialCapacity = ArrayUtils.idealLongArraySize(initialCapacity);
+            mKeys = new long[initialCapacity];
+            mValues = new long[initialCapacity];
+        }
         mSize = 0;
     }
 
@@ -78,7 +100,7 @@
      * if no such mapping has been made.
      */
     public long get(long key, long valueIfKeyNotFound) {
-        int i = Arrays.binarySearch(mKeys, 0, mSize, key);
+        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
 
         if (i < 0) {
             return valueIfKeyNotFound;
@@ -91,7 +113,7 @@
      * Removes the mapping from the specified key, if there was any.
      */
     public void delete(long key) {
-        int i = Arrays.binarySearch(mKeys, 0, mSize, key);
+        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
 
         if (i >= 0) {
             removeAt(i);
@@ -113,7 +135,7 @@
      * was one.
      */
     public void put(long key, long value) {
-        int i = Arrays.binarySearch(mKeys, 0, mSize, key);
+        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
 
         if (i >= 0) {
             mValues[i] = value;
@@ -147,6 +169,11 @@
      * 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
      * SparseLongArray stores.
+     *
+     * <p>The keys corresponding to indices in ascending order are guaranteed to
+     * be in ascending order, e.g., <code>keyAt(0)</code> will return the
+     * smallest key and <code>keyAt(size()-1)</code> will return the largest
+     * key.</p>
      */
     public long keyAt(int index) {
         return mKeys[index];
@@ -156,6 +183,12 @@
      * 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
      * SparseLongArray stores.
+     *
+     * <p>The values corresponding to indices in ascending order are guaranteed
+     * to be associated with keys in ascending order, e.g.,
+     * <code>valueAt(0)</code> will return the value associated with the
+     * smallest key and <code>valueAt(size()-1)</code> will return the value
+     * associated with the largest key.</p>
      */
     public long valueAt(int index) {
         return mValues[index];
@@ -167,7 +200,7 @@
      * key is not mapped.
      */
     public int indexOfKey(long key) {
-        return Arrays.binarySearch(mKeys, 0, mSize, key);
+        return ContainerHelpers.binarySearch(mKeys, mSize, key);
     }
 
     /**
@@ -225,4 +258,31 @@
         mKeys = nkeys;
         mValues = nvalues;
     }
+
+    /**
+     * {@inheritDoc}
+     *
+     * <p>This implementation composes a string by iterating over its mappings.
+     */
+    @Override
+    public String toString() {
+        if (size() <= 0) {
+            return "{}";
+        }
+
+        StringBuilder buffer = new StringBuilder(mSize * 28);
+        buffer.append('{');
+        for (int i=0; i<mSize; i++) {
+            if (i > 0) {
+                buffer.append(", ");
+            }
+            long key = keyAt(i);
+            buffer.append(key);
+            buffer.append('=');
+            long value = valueAt(i);
+            buffer.append(value);
+        }
+        buffer.append('}');
+        return buffer.toString();
+    }
 }
diff --git a/core/java/android/util/MapCollections.java b/core/java/android/util/MapCollections.java
new file mode 100644
index 0000000..f4a9b0b
--- /dev/null
+++ b/core/java/android/util/MapCollections.java
@@ -0,0 +1,559 @@
+/*
+ * 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.util;
+
+import libcore.util.Objects;
+
+import java.lang.reflect.Array;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Helper for writing standard Java collection interfaces to a data
+ * structure like {@link ArrayMap}.
+ * @hide
+ */
+abstract class MapCollections<K, V> {
+    EntrySet mEntrySet;
+    KeySet mKeySet;
+    ValuesCollection mValues;
+
+    final class ArrayIterator<T> implements Iterator<T> {
+        final int mOffset;
+        int mSize;
+        int mIndex;
+        boolean mCanRemove = false;
+
+        ArrayIterator(int offset) {
+            mOffset = offset;
+            mSize = colGetSize();
+        }
+
+        @Override
+        public boolean hasNext() {
+            return mIndex < mSize;
+        }
+
+        @Override
+        public T next() {
+            Object res = colGetEntry(mIndex, mOffset);
+            mIndex++;
+            mCanRemove = true;
+            return (T)res;
+        }
+
+        @Override
+        public void remove() {
+            if (!mCanRemove) {
+                throw new IllegalStateException();
+            }
+            mIndex--;
+            mSize--;
+            mCanRemove = false;
+            colRemoveAt(mIndex);
+        }
+    }
+
+    final class MapIterator implements Iterator<Map.Entry<K, V>>, Map.Entry<K, V> {
+        int mEnd;
+        int mIndex;
+        boolean mEntryValid = false;
+
+        MapIterator() {
+            mEnd = colGetSize() - 1;
+            mIndex = -1;
+        }
+
+        @Override
+        public boolean hasNext() {
+            return mIndex < mEnd;
+        }
+
+        @Override
+        public Map.Entry<K, V> next() {
+            mIndex++;
+            mEntryValid = true;
+            return this;
+        }
+
+        @Override
+        public void remove() {
+            if (!mEntryValid) {
+                throw new IllegalStateException();
+            }
+            mIndex--;
+            mEnd--;
+            mEntryValid = false;
+            colRemoveAt(mIndex);
+        }
+
+        @Override
+        public K getKey() {
+            if (!mEntryValid) {
+                throw new IllegalStateException(
+                        "This container does not support retaining Map.Entry objects");
+            }
+            return (K)colGetEntry(mIndex, 0);
+        }
+
+        @Override
+        public V getValue() {
+            if (!mEntryValid) {
+                throw new IllegalStateException(
+                        "This container does not support retaining Map.Entry objects");
+            }
+            return (V)colGetEntry(mIndex, 1);
+        }
+
+        @Override
+        public V setValue(V object) {
+            if (!mEntryValid) {
+                throw new IllegalStateException(
+                        "This container does not support retaining Map.Entry objects");
+            }
+            return colSetValue(mIndex, object);
+        }
+
+        @Override
+        public final boolean equals(Object o) {
+            if (!mEntryValid) {
+                throw new IllegalStateException(
+                        "This container does not support retaining Map.Entry objects");
+            }
+            if (!(o instanceof Map.Entry)) {
+                return false;
+            }
+            Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
+            return Objects.equal(e.getKey(), colGetEntry(mIndex, 0))
+                    && Objects.equal(e.getValue(), colGetEntry(mIndex, 1));
+        }
+
+        @Override
+        public final int hashCode() {
+            if (!mEntryValid) {
+                throw new IllegalStateException(
+                        "This container does not support retaining Map.Entry objects");
+            }
+            final Object key = colGetEntry(mIndex, 0);
+            final Object value = colGetEntry(mIndex, 1);
+            return (key == null ? 0 : key.hashCode()) ^
+                    (value == null ? 0 : value.hashCode());
+        }
+
+        @Override
+        public final String toString() {
+            return getKey() + "=" + getValue();
+        }
+    }
+
+    final class EntrySet implements Set<Map.Entry<K, V>> {
+        @Override
+        public boolean add(Map.Entry<K, V> object) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean addAll(Collection<? extends Map.Entry<K, V>> collection) {
+            int oldSize = colGetSize();
+            for (Map.Entry<K, V> entry : collection) {
+                colPut(entry.getKey(), entry.getValue());
+            }
+            return oldSize != colGetSize();
+        }
+
+        @Override
+        public void clear() {
+            colClear();
+        }
+
+        @Override
+        public boolean contains(Object o) {
+            if (!(o instanceof Map.Entry))
+                return false;
+            Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
+            int index = colIndexOfKey(e.getKey());
+            if (index < 0) {
+                return false;
+            }
+            Object foundVal = colGetEntry(index, 1);
+            return Objects.equal(foundVal, e.getValue());
+        }
+
+        @Override
+        public boolean containsAll(Collection<?> collection) {
+            Iterator<?> it = collection.iterator();
+            while (it.hasNext()) {
+                if (!contains(it.next())) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return colGetSize() == 0;
+        }
+
+        @Override
+        public Iterator<Map.Entry<K, V>> iterator() {
+            return new MapIterator();
+        }
+
+        @Override
+        public boolean remove(Object object) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean removeAll(Collection<?> collection) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean retainAll(Collection<?> collection) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public int size() {
+            return colGetSize();
+        }
+
+        @Override
+        public Object[] toArray() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public <T> T[] toArray(T[] array) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean equals(Object object) {
+            return equalsSetHelper(this, object);
+        }
+
+        @Override
+        public int hashCode() {
+            int result = 0;
+            for (int i=colGetSize()-1; i>=0; i--) {
+                final Object key = colGetEntry(i, 0);
+                final Object value = colGetEntry(i, 1);
+                result += ( (key == null ? 0 : key.hashCode()) ^
+                        (value == null ? 0 : value.hashCode()) );
+            }
+            return result;
+        }
+    };
+
+    final class KeySet implements Set<K> {
+
+        @Override
+        public boolean add(K object) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean addAll(Collection<? extends K> collection) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void clear() {
+            colClear();
+        }
+
+        @Override
+        public boolean contains(Object object) {
+            return colIndexOfKey(object) >= 0;
+        }
+
+        @Override
+        public boolean containsAll(Collection<?> collection) {
+            return containsAllHelper(colGetMap(), collection);
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return colGetSize() == 0;
+        }
+
+        @Override
+        public Iterator<K> iterator() {
+            return new ArrayIterator<K>(0);
+        }
+
+        @Override
+        public boolean remove(Object object) {
+            int index = colIndexOfKey(object);
+            if (index >= 0) {
+                colRemoveAt(index);
+                return true;
+            }
+            return false;
+        }
+
+        @Override
+        public boolean removeAll(Collection<?> collection) {
+            return removeAllHelper(colGetMap(), collection);
+        }
+
+        @Override
+        public boolean retainAll(Collection<?> collection) {
+            return retainAllHelper(colGetMap(), collection);
+        }
+
+        @Override
+        public int size() {
+            return colGetSize();
+        }
+
+        @Override
+        public Object[] toArray() {
+            return toArrayHelper(0);
+        }
+
+        @Override
+        public <T> T[] toArray(T[] array) {
+            return toArrayHelper(array, 0);
+        }
+
+        @Override
+        public boolean equals(Object object) {
+            return equalsSetHelper(this, object);
+        }
+
+        @Override
+        public int hashCode() {
+            int result = 0;
+            for (int i=colGetSize()-1; i>=0; i--) {
+                Object obj = colGetEntry(i, 0);
+                result += obj == null ? 0 : obj.hashCode();
+            }
+            return result;
+        }
+    };
+
+    final class ValuesCollection implements Collection<V> {
+
+        @Override
+        public boolean add(V object) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean addAll(Collection<? extends V> collection) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void clear() {
+            colClear();
+        }
+
+        @Override
+        public boolean contains(Object object) {
+            return colIndexOfValue(object) >= 0;
+        }
+
+        @Override
+        public boolean containsAll(Collection<?> collection) {
+            Iterator<?> it = collection.iterator();
+            while (it.hasNext()) {
+                if (!contains(it.next())) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return colGetSize() == 0;
+        }
+
+        @Override
+        public Iterator<V> iterator() {
+            return new ArrayIterator<V>(1);
+        }
+
+        @Override
+        public boolean remove(Object object) {
+            int index = colIndexOfValue(object);
+            if (index >= 0) {
+                colRemoveAt(index);
+                return true;
+            }
+            return false;
+        }
+
+        @Override
+        public boolean removeAll(Collection<?> collection) {
+            int N = colGetSize();
+            boolean changed = false;
+            for (int i=0; i<N; i++) {
+                Object cur = colGetEntry(i, 1);
+                if (collection.contains(cur)) {
+                    colRemoveAt(i);
+                    i--;
+                    N--;
+                    changed = true;
+                }
+            }
+            return changed;
+        }
+
+        @Override
+        public boolean retainAll(Collection<?> collection) {
+            int N = colGetSize();
+            boolean changed = false;
+            for (int i=0; i<N; i++) {
+                Object cur = colGetEntry(i, 1);
+                if (!collection.contains(cur)) {
+                    colRemoveAt(i);
+                    i--;
+                    N--;
+                    changed = true;
+                }
+            }
+            return changed;
+        }
+
+        @Override
+        public int size() {
+            return colGetSize();
+        }
+
+        @Override
+        public Object[] toArray() {
+            return toArrayHelper(1);
+        }
+
+        @Override
+        public <T> T[] toArray(T[] array) {
+            return toArrayHelper(array, 1);
+        }
+    };
+
+    public static <K, V> boolean containsAllHelper(Map<K, V> map, Collection<?> collection) {
+        Iterator<?> it = collection.iterator();
+        while (it.hasNext()) {
+            if (!map.containsKey(it.next())) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public static <K, V> boolean removeAllHelper(Map<K, V> map, Collection<?> collection) {
+        int oldSize = map.size();
+        Iterator<?> it = collection.iterator();
+        while (it.hasNext()) {
+            map.remove(it.next());
+        }
+        return oldSize != map.size();
+    }
+
+    public static <K, V> boolean retainAllHelper(Map<K, V> map, Collection<?> collection) {
+        int oldSize = map.size();
+        Iterator<K> it = map.keySet().iterator();
+        while (it.hasNext()) {
+            if (!collection.contains(it.next())) {
+                it.remove();
+            }
+        }
+        return oldSize != map.size();
+    }
+
+    public Object[] toArrayHelper(int offset) {
+        final int N = colGetSize();
+        Object[] result = new Object[N];
+        for (int i=0; i<N; i++) {
+            result[i] = colGetEntry(i, offset);
+        }
+        return result;
+    }
+
+    public <T> T[] toArrayHelper(T[] array, int offset) {
+        final int N  = colGetSize();
+        if (array.length < N) {
+            @SuppressWarnings("unchecked") T[] newArray
+                = (T[]) Array.newInstance(array.getClass().getComponentType(), N);
+            array = newArray;
+        }
+        for (int i=0; i<N; i++) {
+            array[i] = (T)colGetEntry(i, offset);
+        }
+        if (array.length > N) {
+            array[N] = null;
+        }
+        return array;
+    }
+
+    public static <T> boolean equalsSetHelper(Set<T> set, Object object) {
+        if (set == object) {
+            return true;
+        }
+        if (object instanceof Set) {
+            Set<?> s = (Set<?>) object;
+
+            try {
+                return set.size() == s.size() && set.containsAll(s);
+            } catch (NullPointerException ignored) {
+                return false;
+            } catch (ClassCastException ignored) {
+                return false;
+            }
+        }
+        return false;
+    }
+
+    public Set<Map.Entry<K, V>> getEntrySet() {
+        if (mEntrySet == null) {
+            mEntrySet = new EntrySet();
+        }
+        return mEntrySet;
+    }
+
+    public Set<K> getKeySet() {
+        if (mKeySet == null) {
+            mKeySet = new KeySet();
+        }
+        return mKeySet;
+    }
+
+    public Collection<V> getValues() {
+        if (mValues == null) {
+            mValues = new ValuesCollection();
+        }
+        return mValues;
+    }
+
+    protected abstract int colGetSize();
+    protected abstract Object colGetEntry(int index, int offset);
+    protected abstract int colIndexOfKey(Object key);
+    protected abstract int colIndexOfValue(Object key);
+    protected abstract Map<K, V> colGetMap();
+    protected abstract void colPut(K key, V value);
+    protected abstract V colSetValue(int index, V value);
+    protected abstract void colRemoveAt(int index);
+    protected abstract void colClear();
+}
diff --git a/core/java/android/util/SparseArray.java b/core/java/android/util/SparseArray.java
index 7e8fee5..6e168a8 100644
--- a/core/java/android/util/SparseArray.java
+++ b/core/java/android/util/SparseArray.java
@@ -20,8 +20,31 @@
 
 /**
  * SparseArrays map integers 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 to Objects.
+ * there can be gaps in the indices.  It is intended to be more memory efficient
+ * than using a HashMap to map Integers to Objects, both because it avoids
+ * auto-boxing keys and its data structure doesn't rely on an extra entry object
+ * for each mapping.
+ *
+ * <p>Note that this container keeps its mappings in an array data structure,
+ * using a binary search to find keys.  The implementation is not intended to be appropriate for
+ * data structures
+ * that may contain large numbers of items.  It is generally slower than a traditional
+ * HashMap, since lookups require a binary search and adds and removes require inserting
+ * and deleting entries in the array.  For containers holding up to hundreds of items,
+ * the performance difference is not significant, less than 50%.</p>
+ *
+ * <p>To help with performance, the container includes an optimization when removing
+ * keys: instead of compacting its array immediately, it leaves the removed entry marked
+ * as deleted.  The entry can then be re-used for the same key, or compacted later in
+ * a single garbage collection step of all removed entries.  This garbage collection will
+ * need to be performed at any time the array needs to be grown or the the map size or
+ * entry values are retrieved.</p>
+ *
+ * <p>It is possible to iterate over the items in this container using
+ * {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
+ * <code>keyAt(int)</code> with ascending values of the index will return the
+ * keys in ascending order, or the values corresponding to the keys in ascending
+ * order in the case of <code>valueAt(int)<code>.</p>
  */
 public class SparseArray<E> implements Cloneable {
     private static final Object DELETED = new Object();
@@ -41,13 +64,19 @@
     /**
      * Creates a new SparseArray containing no mappings that will not
      * require any additional memory allocation to store the specified
-     * number of mappings.
+     * number of mappings.  If you supply an initial capacity of 0, the
+     * sparse array will be initialized with a light-weight representation
+     * not requiring any additional array allocations.
      */
     public SparseArray(int initialCapacity) {
-        initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity);
-
-        mKeys = new int[initialCapacity];
-        mValues = new Object[initialCapacity];
+        if (initialCapacity == 0) {
+            mKeys = ContainerHelpers.EMPTY_INTS;
+            mValues = ContainerHelpers.EMPTY_OBJECTS;
+        } else {
+            initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity);
+            mKeys = new int[initialCapacity];
+            mValues = new Object[initialCapacity];
+        }
         mSize = 0;
     }
 
@@ -79,7 +108,7 @@
      */
     @SuppressWarnings("unchecked")
     public E get(int key, E valueIfKeyNotFound) {
-        int i = binarySearch(mKeys, 0, mSize, key);
+        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
 
         if (i < 0 || mValues[i] == DELETED) {
             return valueIfKeyNotFound;
@@ -92,7 +121,7 @@
      * Removes the mapping from the specified key, if there was any.
      */
     public void delete(int key) {
-        int i = binarySearch(mKeys, 0, mSize, key);
+        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
 
         if (i >= 0) {
             if (mValues[i] != DELETED) {
@@ -119,6 +148,19 @@
         }
     }
 
+    /**
+     * Remove a range of mappings as a batch.
+     *
+     * @param index Index to begin at
+     * @param size Number of mappings to remove
+     */
+    public void removeAtRange(int index, int size) {
+        final int end = Math.min(mSize, index + size);
+        for (int i = index; i < end; i++) {
+            removeAt(i);
+        }
+    }
+
     private void gc() {
         // Log.e("SparseArray", "gc start with " + mSize);
 
@@ -153,7 +195,7 @@
      * was one.
      */
     public void put(int key, E value) {
-        int i = binarySearch(mKeys, 0, mSize, key);
+        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
 
         if (i >= 0) {
             mValues[i] = value;
@@ -170,7 +212,7 @@
                 gc();
 
                 // Search again because indices may have changed.
-                i = ~binarySearch(mKeys, 0, mSize, key);
+                i = ~ContainerHelpers.binarySearch(mKeys, mSize, key);
             }
 
             if (mSize >= mKeys.length) {
@@ -215,6 +257,11 @@
      * 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.
+     *
+     * <p>The keys corresponding to indices in ascending order are guaranteed to
+     * be in ascending order, e.g., <code>keyAt(0)</code> will return the
+     * smallest key and <code>keyAt(size()-1)</code> will return the largest
+     * key.</p>
      */
     public int keyAt(int index) {
         if (mGarbage) {
@@ -228,6 +275,12 @@
      * 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.
+     *
+     * <p>The values corresponding to indices in ascending order are guaranteed
+     * to be associated with keys in ascending order, e.g.,
+     * <code>valueAt(0)</code> will return the value associated with the
+     * smallest key and <code>valueAt(size()-1)</code> will return the value
+     * associated with the largest key.</p>
      */
     @SuppressWarnings("unchecked")
     public E valueAt(int index) {
@@ -261,7 +314,7 @@
             gc();
         }
 
-        return binarySearch(mKeys, 0, mSize, key);
+        return ContainerHelpers.binarySearch(mKeys, mSize, key);
     }
 
     /**
@@ -335,23 +388,36 @@
         mSize = pos + 1;
     }
 
-    private static int binarySearch(int[] a, int start, int len, int 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;
+    /**
+     * {@inheritDoc}
+     *
+     * <p>This implementation composes a string by iterating over its mappings. If
+     * this map contains itself as a value, the string "(this Map)"
+     * will appear in its place.
+     */
+    @Override
+    public String toString() {
+        if (size() <= 0) {
+            return "{}";
         }
 
-        if (high == start + len)
-            return ~(start + len);
-        else if (a[high] == key)
-            return high;
-        else
-            return ~high;
+        StringBuilder buffer = new StringBuilder(mSize * 28);
+        buffer.append('{');
+        for (int i=0; i<mSize; i++) {
+            if (i > 0) {
+                buffer.append(", ");
+            }
+            int key = keyAt(i);
+            buffer.append(key);
+            buffer.append('=');
+            Object value = valueAt(i);
+            if (value != this) {
+                buffer.append(value);
+            } else {
+                buffer.append("(this Map)");
+            }
+        }
+        buffer.append('}');
+        return buffer.toString();
     }
 }
diff --git a/core/java/android/util/SparseBooleanArray.java b/core/java/android/util/SparseBooleanArray.java
index 76c47c6..68487e3 100644
--- a/core/java/android/util/SparseBooleanArray.java
+++ b/core/java/android/util/SparseBooleanArray.java
@@ -21,8 +21,24 @@
 /**
  * SparseBooleanArrays map integers to booleans.
  * Unlike a normal array of booleans
- * there can be gaps in the indices.  It is intended to be more efficient
- * than using a HashMap to map Integers to Booleans.
+ * there can be gaps in the indices.  It is intended to be more memory efficient
+ * than using a HashMap to map Integers to Booleans, both because it avoids
+ * auto-boxing keys and values and its data structure doesn't rely on an extra entry object
+ * for each mapping.
+ *
+ * <p>Note that this container keeps its mappings in an array data structure,
+ * using a binary search to find keys.  The implementation is not intended to be appropriate for
+ * data structures
+ * that may contain large numbers of items.  It is generally slower than a traditional
+ * HashMap, since lookups require a binary search and adds and removes require inserting
+ * and deleting entries in the array.  For containers holding up to hundreds of items,
+ * the performance difference is not significant, less than 50%.</p>
+ *
+ * <p>It is possible to iterate over the items in this container using
+ * {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
+ * <code>keyAt(int)</code> with ascending values of the index will return the
+ * keys in ascending order, or the values corresponding to the keys in ascending
+ * order in the case of <code>valueAt(int)<code>.</p>
  */
 public class SparseBooleanArray implements Cloneable {
     /**
@@ -35,13 +51,19 @@
     /**
      * Creates a new SparseBooleanArray containing no mappings that will not
      * require any additional memory allocation to store the specified
-     * number of mappings.
+     * number of mappings.  If you supply an initial capacity of 0, the
+     * sparse array will be initialized with a light-weight representation
+     * not requiring any additional array allocations.
      */
     public SparseBooleanArray(int initialCapacity) {
-        initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity);
-
-        mKeys = new int[initialCapacity];
-        mValues = new boolean[initialCapacity];
+        if (initialCapacity == 0) {
+            mKeys = ContainerHelpers.EMPTY_INTS;
+            mValues = ContainerHelpers.EMPTY_BOOLEANS;
+        } else {
+            initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity);
+            mKeys = new int[initialCapacity];
+            mValues = new boolean[initialCapacity];
+        }
         mSize = 0;
     }
 
@@ -71,7 +93,7 @@
      * if no such mapping has been made.
      */
     public boolean get(int key, boolean valueIfKeyNotFound) {
-        int i = binarySearch(mKeys, 0, mSize, key);
+        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
 
         if (i < 0) {
             return valueIfKeyNotFound;
@@ -84,7 +106,7 @@
      * Removes the mapping from the specified key, if there was any.
      */
     public void delete(int key) {
-        int i = binarySearch(mKeys, 0, mSize, key);
+        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
 
         if (i >= 0) {
             System.arraycopy(mKeys, i + 1, mKeys, i, mSize - (i + 1));
@@ -99,7 +121,7 @@
      * was one.
      */
     public void put(int key, boolean value) {
-        int i = binarySearch(mKeys, 0, mSize, key);
+        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
 
         if (i >= 0) {
             mValues[i] = value;
@@ -143,16 +165,27 @@
     /**
      * 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
-     * SparseBooleanArray stores.  
+     * SparseBooleanArray stores.
+     *
+     * <p>The keys corresponding to indices in ascending order are guaranteed to
+     * be in ascending order, e.g., <code>keyAt(0)</code> will return the
+     * smallest key and <code>keyAt(size()-1)</code> will return the largest
+     * key.</p>
      */
     public int keyAt(int index) {
         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
-     * SparseBooleanArray stores.  
+     * SparseBooleanArray stores.
+     *
+     * <p>The values corresponding to indices in ascending order are guaranteed
+     * to be associated with keys in ascending order, e.g.,
+     * <code>valueAt(0)</code> will return the value associated with the
+     * smallest key and <code>valueAt(size()-1)</code> will return the value
+     * associated with the largest key.</p>
      */
     public boolean valueAt(int index) {
         return mValues[index];
@@ -164,7 +197,7 @@
      * key is not mapped.
      */
     public int indexOfKey(int key) {
-        return binarySearch(mKeys, 0, mSize, key);
+        return ContainerHelpers.binarySearch(mKeys, mSize, key);
     }
 
     /**
@@ -219,25 +252,32 @@
         mValues[pos] = value;
         mSize = pos + 1;
     }
-    
-    private static int binarySearch(int[] a, int start, int len, int 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;
+    /**
+     * {@inheritDoc}
+     *
+     * <p>This implementation composes a string by iterating over its mappings.
+     */
+    @Override
+    public String toString() {
+        if (size() <= 0) {
+            return "{}";
         }
 
-        if (high == start + len)
-            return ~(start + len);
-        else if (a[high] == key)
-            return high;
-        else
-            return ~high;
+        StringBuilder buffer = new StringBuilder(mSize * 28);
+        buffer.append('{');
+        for (int i=0; i<mSize; i++) {
+            if (i > 0) {
+                buffer.append(", ");
+            }
+            int key = keyAt(i);
+            buffer.append(key);
+            buffer.append('=');
+            boolean value = valueAt(i);
+            buffer.append(value);
+        }
+        buffer.append('}');
+        return buffer.toString();
     }
 
     private int[] mKeys;
diff --git a/core/java/android/util/SparseIntArray.java b/core/java/android/util/SparseIntArray.java
index 8d11177..0835cb0 100644
--- a/core/java/android/util/SparseIntArray.java
+++ b/core/java/android/util/SparseIntArray.java
@@ -20,11 +20,26 @@
 
 /**
  * SparseIntArrays map integers to integers.  Unlike a normal array of integers,
- * there can be gaps in the indices.  It is intended to be more efficient
- * than using a HashMap to map Integers to Integers.
+ * there can be gaps in the indices.  It is intended to be more memory efficient
+ * than using a HashMap to map Integers to Integers, both because it avoids
+ * auto-boxing keys and values and its data structure doesn't rely on an extra entry object
+ * for each mapping.
+ *
+ * <p>Note that this container keeps its mappings in an array data structure,
+ * using a binary search to find keys.  The implementation is not intended to be appropriate for
+ * data structures
+ * that may contain large numbers of items.  It is generally slower than a traditional
+ * HashMap, since lookups require a binary search and adds and removes require inserting
+ * and deleting entries in the array.  For containers holding up to hundreds of items,
+ * the performance difference is not significant, less than 50%.</p>
+ *
+ * <p>It is possible to iterate over the items in this container using
+ * {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
+ * <code>keyAt(int)</code> with ascending values of the index will return the
+ * keys in ascending order, or the values corresponding to the keys in ascending
+ * order in the case of <code>valueAt(int)<code>.</p>
  */
 public class SparseIntArray implements Cloneable {
-
     private int[] mKeys;
     private int[] mValues;
     private int mSize;
@@ -39,13 +54,19 @@
     /**
      * Creates a new SparseIntArray containing no mappings that will not
      * require any additional memory allocation to store the specified
-     * number of mappings.
+     * number of mappings.  If you supply an initial capacity of 0, the
+     * sparse array will be initialized with a light-weight representation
+     * not requiring any additional array allocations.
      */
     public SparseIntArray(int initialCapacity) {
-        initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity);
-
-        mKeys = new int[initialCapacity];
-        mValues = new int[initialCapacity];
+        if (initialCapacity == 0) {
+            mKeys = ContainerHelpers.EMPTY_INTS;
+            mValues = ContainerHelpers.EMPTY_INTS;
+        } else {
+            initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity);
+            mKeys = new int[initialCapacity];
+            mValues = new int[initialCapacity];
+        }
         mSize = 0;
     }
 
@@ -75,7 +96,7 @@
      * if no such mapping has been made.
      */
     public int get(int key, int valueIfKeyNotFound) {
-        int i = binarySearch(mKeys, 0, mSize, key);
+        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
 
         if (i < 0) {
             return valueIfKeyNotFound;
@@ -88,7 +109,7 @@
      * Removes the mapping from the specified key, if there was any.
      */
     public void delete(int key) {
-        int i = binarySearch(mKeys, 0, mSize, key);
+        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
 
         if (i >= 0) {
             removeAt(i);
@@ -110,7 +131,7 @@
      * was one.
      */
     public void put(int key, int value) {
-        int i = binarySearch(mKeys, 0, mSize, key);
+        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
 
         if (i >= 0) {
             mValues[i] = value;
@@ -154,16 +175,27 @@
     /**
      * 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
-     * SparseIntArray stores.  
+     * SparseIntArray stores.
+     *
+     * <p>The keys corresponding to indices in ascending order are guaranteed to
+     * be in ascending order, e.g., <code>keyAt(0)</code> will return the
+     * smallest key and <code>keyAt(size()-1)</code> will return the largest
+     * key.</p>
      */
     public int keyAt(int index) {
         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
-     * SparseIntArray stores.  
+     * SparseIntArray stores.
+     *
+     * <p>The values corresponding to indices in ascending order are guaranteed
+     * to be associated with keys in ascending order, e.g.,
+     * <code>valueAt(0)</code> will return the value associated with the
+     * smallest key and <code>valueAt(size()-1)</code> will return the value
+     * associated with the largest key.</p>
      */
     public int valueAt(int index) {
         return mValues[index];
@@ -175,7 +207,7 @@
      * key is not mapped.
      */
     public int indexOfKey(int key) {
-        return binarySearch(mKeys, 0, mSize, key);
+        return ContainerHelpers.binarySearch(mKeys, mSize, key);
     }
 
     /**
@@ -230,24 +262,31 @@
         mValues[pos] = value;
         mSize = pos + 1;
     }
-    
-    private static int binarySearch(int[] a, int start, int len, int 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;
+    /**
+     * {@inheritDoc}
+     *
+     * <p>This implementation composes a string by iterating over its mappings.
+     */
+    @Override
+    public String toString() {
+        if (size() <= 0) {
+            return "{}";
         }
 
-        if (high == start + len)
-            return ~(start + len);
-        else if (a[high] == key)
-            return high;
-        else
-            return ~high;
+        StringBuilder buffer = new StringBuilder(mSize * 28);
+        buffer.append('{');
+        for (int i=0; i<mSize; i++) {
+            if (i > 0) {
+                buffer.append(", ");
+            }
+            int key = keyAt(i);
+            buffer.append(key);
+            buffer.append('=');
+            int value = valueAt(i);
+            buffer.append(value);
+        }
+        buffer.append('}');
+        return buffer.toString();
     }
 }
diff --git a/core/java/android/util/SparseLongArray.java b/core/java/android/util/SparseLongArray.java
index 2f7a6fe..62c1c0d 100644
--- a/core/java/android/util/SparseLongArray.java
+++ b/core/java/android/util/SparseLongArray.java
@@ -20,11 +20,26 @@
 
 /**
  * SparseLongArrays map integers to longs.  Unlike a normal array of longs,
- * there can be gaps in the indices.  It is intended to be more efficient
- * than using a HashMap to map Integers to Longs.
+ * there can be gaps in the indices.  It is intended to be more memory efficient
+ * than using a HashMap to map Integers to Longs, both because it avoids
+ * auto-boxing keys and values and its data structure doesn't rely on an extra entry object
+ * for each mapping.
+ *
+ * <p>Note that this container keeps its mappings in an array data structure,
+ * using a binary search to find keys.  The implementation is not intended to be appropriate for
+ * data structures
+ * that may contain large numbers of items.  It is generally slower than a traditional
+ * HashMap, since lookups require a binary search and adds and removes require inserting
+ * and deleting entries in the array.  For containers holding up to hundreds of items,
+ * the performance difference is not significant, less than 50%.</p>
+ *
+ * <p>It is possible to iterate over the items in this container using
+ * {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
+ * <code>keyAt(int)</code> with ascending values of the index will return the
+ * keys in ascending order, or the values corresponding to the keys in ascending
+ * order in the case of <code>valueAt(int)<code>.</p>
  */
 public class SparseLongArray implements Cloneable {
-
     private int[] mKeys;
     private long[] mValues;
     private int mSize;
@@ -39,13 +54,19 @@
     /**
      * Creates a new SparseLongArray containing no mappings that will not
      * require any additional memory allocation to store the specified
-     * number of mappings.
+     * number of mappings.  If you supply an initial capacity of 0, the
+     * sparse array will be initialized with a light-weight representation
+     * not requiring any additional array allocations.
      */
     public SparseLongArray(int initialCapacity) {
-        initialCapacity = ArrayUtils.idealLongArraySize(initialCapacity);
-
-        mKeys = new int[initialCapacity];
-        mValues = new long[initialCapacity];
+        if (initialCapacity == 0) {
+            mKeys = ContainerHelpers.EMPTY_INTS;
+            mValues = ContainerHelpers.EMPTY_LONGS;
+        } else {
+            initialCapacity = ArrayUtils.idealLongArraySize(initialCapacity);
+            mKeys = new int[initialCapacity];
+            mValues = new long[initialCapacity];
+        }
         mSize = 0;
     }
 
@@ -75,7 +96,7 @@
      * if no such mapping has been made.
      */
     public long get(int key, long valueIfKeyNotFound) {
-        int i = binarySearch(mKeys, 0, mSize, key);
+        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
 
         if (i < 0) {
             return valueIfKeyNotFound;
@@ -88,7 +109,7 @@
      * Removes the mapping from the specified key, if there was any.
      */
     public void delete(int key) {
-        int i = binarySearch(mKeys, 0, mSize, key);
+        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
 
         if (i >= 0) {
             removeAt(i);
@@ -110,7 +131,7 @@
      * was one.
      */
     public void put(int key, long value) {
-        int i = binarySearch(mKeys, 0, mSize, key);
+        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
 
         if (i >= 0) {
             mValues[i] = value;
@@ -144,6 +165,11 @@
      * 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
      * SparseLongArray stores.
+     *
+     * <p>The keys corresponding to indices in ascending order are guaranteed to
+     * be in ascending order, e.g., <code>keyAt(0)</code> will return the
+     * smallest key and <code>keyAt(size()-1)</code> will return the largest
+     * key.</p>
      */
     public int keyAt(int index) {
         return mKeys[index];
@@ -153,6 +179,12 @@
      * 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
      * SparseLongArray stores.
+     *
+     * <p>The values corresponding to indices in ascending order are guaranteed
+     * to be associated with keys in ascending order, e.g.,
+     * <code>valueAt(0)</code> will return the value associated with the
+     * smallest key and <code>valueAt(size()-1)</code> will return the value
+     * associated with the largest key.</p>
      */
     public long valueAt(int index) {
         return mValues[index];
@@ -164,7 +196,7 @@
      * key is not mapped.
      */
     public int indexOfKey(int key) {
-        return binarySearch(mKeys, 0, mSize, key);
+        return ContainerHelpers.binarySearch(mKeys, mSize, key);
     }
 
     /**
@@ -223,23 +255,30 @@
         mValues = nvalues;
     }
 
-    private static int binarySearch(int[] 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;
+    /**
+     * {@inheritDoc}
+     *
+     * <p>This implementation composes a string by iterating over its mappings.
+     */
+    @Override
+    public String toString() {
+        if (size() <= 0) {
+            return "{}";
         }
 
-        if (high == start + len)
-            return ~(start + len);
-        else if (a[high] == key)
-            return high;
-        else
-            return ~high;
+        StringBuilder buffer = new StringBuilder(mSize * 28);
+        buffer.append('{');
+        for (int i=0; i<mSize; i++) {
+            if (i > 0) {
+                buffer.append(", ");
+            }
+            int key = keyAt(i);
+            buffer.append(key);
+            buffer.append('=');
+            long value = valueAt(i);
+            buffer.append(value);
+        }
+        buffer.append('}');
+        return buffer.toString();
     }
 }
diff --git a/core/java/android/util/SuperNotCalledException.java b/core/java/android/util/SuperNotCalledException.java
new file mode 100644
index 0000000..1836142
--- /dev/null
+++ b/core/java/android/util/SuperNotCalledException.java
@@ -0,0 +1,27 @@
+/*
+ * 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.util;
+
+/**
+ * @hide
+ */
+public final class SuperNotCalledException extends AndroidRuntimeException {
+    public SuperNotCalledException(String msg) {
+        super(msg);
+    }
+}
diff --git a/core/java/android/util/TimedRemoteCaller.java b/core/java/android/util/TimedRemoteCaller.java
new file mode 100644
index 0000000..abb2b64
--- /dev/null
+++ b/core/java/android/util/TimedRemoteCaller.java
@@ -0,0 +1,134 @@
+/*
+ * 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.util;
+
+import android.os.SystemClock;
+
+import java.util.concurrent.TimeoutException;
+
+/**
+ * This is a helper class for making an async one way call and
+ * its async one way response response in a sync fashion within
+ * a timeout. The key idea is to call the remote method with a
+ * sequence number and a callback and then starting to wait for
+ * the response. The remote method calls back with the result and
+ * the sequence number. If the response comes within the timeout
+ * and its sequence number is the one sent in the method invocation,
+ * then the call succeeded. If the response does not come within
+ * the timeout then the call failed. Older result received when
+ * waiting for the result are ignored.
+ * <p>
+ * Typical usage is:
+ * </p>
+ * <p><pre><code>
+ * public class MyMethodCaller extends TimeoutRemoteCallHelper<Object> {
+ *     // The one way remote method to call.
+ *     private final IRemoteInterface mTarget;
+ *
+ *     // One way callback invoked when the remote method is done.
+ *     private final IRemoteCallback mCallback = new IRemoteCallback.Stub() {
+ *         public void onCompleted(Object result, int sequence) {
+ *             onRemoteMethodResult(result, sequence);
+ *         }
+ *     };
+ *
+ *     public MyMethodCaller(IRemoteInterface target) {
+ *         mTarget = target;
+ *     }
+ *
+ *     public Object onCallMyMethod(Object arg) throws RemoteException {
+ *         final int sequence = onBeforeRemoteCall();
+ *         mTarget.myMethod(arg, sequence);
+ *         return getResultTimed(sequence);
+ *     }
+ * }
+ * </code></pre></p>
+ *
+ * @param <T> The type of the expected result.
+ *
+ * @hide
+ */
+public abstract class TimedRemoteCaller<T> {
+
+    public static final long DEFAULT_CALL_TIMEOUT_MILLIS = 5000;
+
+    private static final int UNDEFINED_SEQUENCE = -1;
+
+    private final Object mLock = new Object();
+
+    private final long mCallTimeoutMillis;
+
+    private int mSequenceCounter;
+
+    private int mReceivedSequence = UNDEFINED_SEQUENCE;
+
+    private int mAwaitedSequence = UNDEFINED_SEQUENCE;
+
+    private T mResult;
+
+    public TimedRemoteCaller(long callTimeoutMillis) {
+        mCallTimeoutMillis = callTimeoutMillis;
+    }
+
+    public final int onBeforeRemoteCall() {
+        synchronized (mLock) {
+            mAwaitedSequence = mSequenceCounter++;
+            return mAwaitedSequence;
+        }
+    }
+
+    public final T getResultTimed(int sequence) throws TimeoutException {
+        synchronized (mLock) {
+            final boolean success = waitForResultTimedLocked(sequence);
+            if (!success) {
+                throw new TimeoutException("No reponse for sequence: " + sequence);
+            }
+            T result = mResult;
+            mResult = null;
+            return result;
+        }
+    }
+
+    public final void onRemoteMethodResult(T result, int sequence) {
+        synchronized (mLock) {
+            if (sequence == mAwaitedSequence) {
+                mReceivedSequence = sequence;
+                mResult = result;
+                mLock.notifyAll();
+            }
+        }
+    }
+
+    private boolean waitForResultTimedLocked(int sequence) {
+        final long startMillis = SystemClock.uptimeMillis();
+        while (true) {
+            try {
+                if (mReceivedSequence == sequence) {
+                    return true;
+                }
+                final long elapsedMillis = SystemClock.uptimeMillis() - startMillis;
+                final long waitMillis = mCallTimeoutMillis - elapsedMillis;
+                if (waitMillis <= 0) {
+                    return false;
+                }
+                mLock.wait(waitMillis);
+            } catch (InterruptedException ie) {
+                /* ignore */
+            }
+        }
+    }
+}
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 2d6453e..e835a97 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -406,6 +406,10 @@
                         if (host == null || !ViewRootImpl.isViewDescendantOf(host, root)) {
                             break;
                         }
+                        // The focused view not shown, we failed.
+                        if (!isShown(host)) {
+                            break;
+                        }
                         // If the host has a provider ask this provider to search for the
                         // focus instead fetching all provider nodes to do the search here.
                         AccessibilityNodeProvider provider = host.getAccessibilityNodeProvider();
diff --git a/core/java/android/view/CompatibilityInfoHolder.java b/core/java/android/view/CompatibilityInfoHolder.java
deleted file mode 100644
index fc8d684..0000000
--- a/core/java/android/view/CompatibilityInfoHolder.java
+++ /dev/null
@@ -1,45 +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.CompatibilityInfo;
-
-/** @hide */
-public class CompatibilityInfoHolder {
-    private volatile CompatibilityInfo mCompatInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
-
-    public void set(CompatibilityInfo compatInfo) {
-        if (compatInfo != null && (compatInfo.isScalingRequired()
-                || !compatInfo.supportsScreen())) {
-            mCompatInfo = compatInfo;
-        } else {
-            mCompatInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
-        }
-    }
-
-    public CompatibilityInfo get() {
-        return mCompatInfo;
-    }
-
-    public CompatibilityInfo getIfNeeded() {
-        CompatibilityInfo ci = mCompatInfo;
-        if (ci == null || ci  == CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO) {
-            return null;
-        }
-        return ci;
-    }
-}
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index e6a7950..354ea66 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -16,10 +16,12 @@
 
 package android.view;
 
+import android.content.res.CompatibilityInfo;
 import android.graphics.PixelFormat;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.hardware.display.DisplayManagerGlobal;
+import android.os.Process;
 import android.os.SystemClock;
 import android.util.DisplayMetrics;
 import android.util.Log;
@@ -57,7 +59,9 @@
     private final int mFlags;
     private final int mType;
     private final String mAddress;
-    private final CompatibilityInfoHolder mCompatibilityInfo;
+    private final int mOwnerUid;
+    private final String mOwnerPackageName;
+    private final DisplayAdjustments mDisplayAdjustments;
 
     private DisplayInfo mDisplayInfo; // never null
     private boolean mIsValid;
@@ -143,6 +147,27 @@
     public static final int FLAG_SECURE = 1 << 1;
 
     /**
+     * Display flag: Indicates that the display is private.  Only the application that
+     * owns the display can create windows on it.
+     *
+     * @see #getFlags
+     */
+    public static final int FLAG_PRIVATE = 1 << 2;
+
+    /**
+     * Display flag: Indicates that the display is a presentation display.
+     * <p>
+     * This flag identifies secondary displays that are suitable for
+     * use as presentation displays such as HDMI or Wireless displays.  Applications
+     * may automatically project their content to presentation displays to provide
+     * richer second screen experiences.
+     * </p>
+     *
+     * @see #getFlags
+     */
+    public static final int FLAG_PRESENTATION = 1 << 3;
+
+    /**
      * Display type: Unknown display type.
      * @hide
      */
@@ -173,6 +198,12 @@
     public static final int TYPE_OVERLAY = 4;
 
     /**
+     * Display type: Virtual display.
+     * @hide
+     */
+    public static final int TYPE_VIRTUAL = 5;
+
+    /**
      * Internal method to create a display.
      * Applications should use {@link android.view.WindowManager#getDefaultDisplay()}
      * or {@link android.hardware.display.DisplayManager#getDisplay}
@@ -182,11 +213,11 @@
      */
     public Display(DisplayManagerGlobal global,
             int displayId, DisplayInfo displayInfo /*not null*/,
-            CompatibilityInfoHolder compatibilityInfo) {
+            DisplayAdjustments daj) {
         mGlobal = global;
         mDisplayId = displayId;
         mDisplayInfo = displayInfo;
-        mCompatibilityInfo = compatibilityInfo;
+        mDisplayAdjustments = new DisplayAdjustments(daj);
         mIsValid = true;
 
         // Cache properties that cannot change as long as the display is valid.
@@ -194,6 +225,8 @@
         mFlags = displayInfo.flags;
         mType = displayInfo.type;
         mAddress = displayInfo.address;
+        mOwnerUid = displayInfo.ownerUid;
+        mOwnerPackageName = displayInfo.ownerPackageName;
     }
 
     /**
@@ -262,6 +295,7 @@
      *
      * @see #FLAG_SUPPORTS_PROTECTED_BUFFERS
      * @see #FLAG_SECURE
+     * @see #FLAG_PRIVATE
      */
     public int getFlags() {
         return mFlags;
@@ -277,6 +311,7 @@
      * @see #TYPE_HDMI
      * @see #TYPE_WIFI
      * @see #TYPE_OVERLAY
+     * @see #TYPE_VIRTUAL
      * @hide
      */
     public int getType() {
@@ -295,13 +330,39 @@
     }
 
     /**
-     * Gets the compatibility info used by this display instance.
+     * Gets the UID of the application that owns this display, or zero if it is
+     * owned by the system.
+     * <p>
+     * If the display is private, then only the owner can use it.
+     * </p>
      *
-     * @return The compatibility info holder, or null if none is required.
      * @hide
      */
-    public CompatibilityInfoHolder getCompatibilityInfo() {
-        return mCompatibilityInfo;
+    public int getOwnerUid() {
+        return mOwnerUid;
+    }
+
+    /**
+     * Gets the package name of the application that owns this display, or null if it is
+     * owned by the system.
+     * <p>
+     * If the display is private, then only the owner can use it.
+     * </p>
+     *
+     * @hide
+     */
+    public String getOwnerPackageName() {
+        return mOwnerPackageName;
+    }
+
+    /**
+     * Gets the compatibility info used by this display instance.
+     *
+     * @return The display adjustments holder, or null if none is required.
+     * @hide
+     */
+    public DisplayAdjustments getDisplayAdjustments() {
+        return mDisplayAdjustments;
     }
 
     /**
@@ -342,7 +403,7 @@
     public void getSize(Point outSize) {
         synchronized (this) {
             updateDisplayInfoLocked();
-            mDisplayInfo.getAppMetrics(mTempMetrics, mCompatibilityInfo);
+            mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments);
             outSize.x = mTempMetrics.widthPixels;
             outSize.y = mTempMetrics.heightPixels;
         }
@@ -357,7 +418,7 @@
     public void getRectSize(Rect outSize) {
         synchronized (this) {
             updateDisplayInfoLocked();
-            mDisplayInfo.getAppMetrics(mTempMetrics, mCompatibilityInfo);
+            mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments);
             outSize.set(0, 0, mTempMetrics.widthPixels, mTempMetrics.heightPixels);
         }
     }
@@ -522,7 +583,7 @@
     public void getMetrics(DisplayMetrics outMetrics) {
         synchronized (this) {
             updateDisplayInfoLocked();
-            mDisplayInfo.getAppMetrics(outMetrics, mCompatibilityInfo);
+            mDisplayInfo.getAppMetrics(outMetrics, mDisplayAdjustments);
         }
     }
 
@@ -560,10 +621,28 @@
     public void getRealMetrics(DisplayMetrics outMetrics) {
         synchronized (this) {
             updateDisplayInfoLocked();
-            mDisplayInfo.getLogicalMetrics(outMetrics, null);
+            mDisplayInfo.getLogicalMetrics(outMetrics,
+                    CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO,
+                    mDisplayAdjustments.getActivityToken());
         }
     }
 
+    /**
+     * Returns true if the specified UID has access to this display.
+     * @hide
+     */
+    public boolean hasAccess(int uid) {
+        return Display.hasAccess(uid, mFlags, mOwnerUid);
+    }
+
+    /** @hide */
+    public static boolean hasAccess(int uid, int flags, int ownerUid) {
+        return (flags & Display.FLAG_PRIVATE) == 0
+                || uid == ownerUid
+                || uid == Process.SYSTEM_UID
+                || uid == 0;
+    }
+
     private void updateDisplayInfoLocked() {
         // Note: The display manager caches display info objects on our behalf.
         DisplayInfo newInfo = mGlobal.getDisplayInfo(mDisplayId);
@@ -591,7 +670,7 @@
         long now = SystemClock.uptimeMillis();
         if (now > mLastCachedAppSizeUpdate + CACHED_APP_SIZE_DURATION_MILLIS) {
             updateDisplayInfoLocked();
-            mDisplayInfo.getAppMetrics(mTempMetrics, mCompatibilityInfo);
+            mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments);
             mCachedAppWidthCompat = mTempMetrics.widthPixels;
             mCachedAppHeightCompat = mTempMetrics.heightPixels;
             mLastCachedAppSizeUpdate = now;
@@ -603,7 +682,7 @@
     public String toString() {
         synchronized (this) {
             updateDisplayInfoLocked();
-            mDisplayInfo.getAppMetrics(mTempMetrics, mCompatibilityInfo);
+            mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments);
             return "Display id " + mDisplayId + ": " + mDisplayInfo
                     + ", " + mTempMetrics + ", isValid=" + mIsValid;
         }
@@ -624,6 +703,8 @@
                 return "WIFI";
             case TYPE_OVERLAY:
                 return "OVERLAY";
+            case TYPE_VIRTUAL:
+                return "VIRTUAL";
             default:
                 return Integer.toString(type);
         }
diff --git a/core/java/android/view/DisplayAdjustments.java b/core/java/android/view/DisplayAdjustments.java
new file mode 100644
index 0000000..041d9e0
--- /dev/null
+++ b/core/java/android/view/DisplayAdjustments.java
@@ -0,0 +1,97 @@
+/*
+ * 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.CompatibilityInfo;
+import android.os.IBinder;
+
+import com.android.internal.util.Objects;
+
+/** @hide */
+public class DisplayAdjustments {
+    public static final boolean DEVELOPMENT_RESOURCES_DEPEND_ON_ACTIVITY_TOKEN = false;
+
+    public static final DisplayAdjustments DEFAULT_DISPLAY_ADJUSTMENTS = new DisplayAdjustments();
+
+    private volatile CompatibilityInfo mCompatInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
+    private volatile IBinder mActivityToken;
+
+    public DisplayAdjustments() {
+    }
+
+    public DisplayAdjustments(IBinder token) {
+        mActivityToken = token;
+    }
+
+    public DisplayAdjustments(DisplayAdjustments daj) {
+        this (daj.getCompatibilityInfo(), daj.getActivityToken());
+    }
+
+    public DisplayAdjustments(CompatibilityInfo compatInfo, IBinder token) {
+        setCompatibilityInfo(compatInfo);
+        mActivityToken = token;
+    }
+
+    public void setCompatibilityInfo(CompatibilityInfo compatInfo) {
+        if (this == DEFAULT_DISPLAY_ADJUSTMENTS) {
+            throw new IllegalArgumentException(
+                    "setCompatbilityInfo: Cannot modify DEFAULT_DISPLAY_ADJUSTMENTS");
+        }
+        if (compatInfo != null && (compatInfo.isScalingRequired()
+                || !compatInfo.supportsScreen())) {
+            mCompatInfo = compatInfo;
+        } else {
+            mCompatInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
+        }
+    }
+
+    public CompatibilityInfo getCompatibilityInfo() {
+        return mCompatInfo;
+    }
+
+    public void setActivityToken(IBinder token) {
+        if (this == DEFAULT_DISPLAY_ADJUSTMENTS) {
+            throw new IllegalArgumentException(
+                    "setActivityToken: Cannot modify DEFAULT_DISPLAY_ADJUSTMENTS");
+        }
+        mActivityToken = token;
+    }
+
+    public IBinder getActivityToken() {
+        return mActivityToken;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 17;
+        hash = hash * 31 + mCompatInfo.hashCode();
+        if (DEVELOPMENT_RESOURCES_DEPEND_ON_ACTIVITY_TOKEN) {
+            hash = hash * 31 + (mActivityToken == null ? 0 : mActivityToken.hashCode());
+        }
+        return hash;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof DisplayAdjustments)) {
+            return false;
+        }
+        DisplayAdjustments daj = (DisplayAdjustments)o;
+        return Objects.equal(daj.mCompatInfo, mCompatInfo) &&
+                Objects.equal(daj.mActivityToken, mActivityToken);
+    }
+}
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index 9fcd9b1..8944207 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -17,8 +17,10 @@
 package android.view;
 
 import android.content.res.CompatibilityInfo;
+import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.Process;
 import android.util.DisplayMetrics;
 
 import libcore.util.Objects;
@@ -177,6 +179,23 @@
      */
     public float physicalYDpi;
 
+    /**
+     * The UID of the application that owns this display, or zero if it is owned by the system.
+     * <p>
+     * If the display is private, then only the owner can use it.
+     * </p>
+     */
+    public int ownerUid;
+
+    /**
+     * The package name of the application that owns this display, or null if it is
+     * owned by the system.
+     * <p>
+     * If the display is private, then only the owner can use it.
+     * </p>
+     */
+    public String ownerPackageName;
+
     public static final Creator<DisplayInfo> CREATOR = new Creator<DisplayInfo>() {
         @Override
         public DisplayInfo createFromParcel(Parcel source) {
@@ -228,7 +247,9 @@
                 && refreshRate == other.refreshRate
                 && logicalDensityDpi == other.logicalDensityDpi
                 && physicalXDpi == other.physicalXDpi
-                && physicalYDpi == other.physicalYDpi;
+                && physicalYDpi == other.physicalYDpi
+                && ownerUid == other.ownerUid
+                && Objects.equal(ownerPackageName, other.ownerPackageName);
     }
 
     @Override
@@ -259,6 +280,8 @@
         logicalDensityDpi = other.logicalDensityDpi;
         physicalXDpi = other.physicalXDpi;
         physicalYDpi = other.physicalYDpi;
+        ownerUid = other.ownerUid;
+        ownerPackageName = other.ownerPackageName;
     }
 
     public void readFromParcel(Parcel source) {
@@ -284,6 +307,8 @@
         logicalDensityDpi = source.readInt();
         physicalXDpi = source.readFloat();
         physicalYDpi = source.readFloat();
+        ownerUid = source.readInt();
+        ownerPackageName = source.readString();
     }
 
     @Override
@@ -310,6 +335,8 @@
         dest.writeInt(logicalDensityDpi);
         dest.writeFloat(physicalXDpi);
         dest.writeFloat(physicalYDpi);
+        dest.writeInt(ownerUid);
+        dest.writeString(ownerPackageName);
     }
 
     @Override
@@ -317,12 +344,22 @@
         return 0;
     }
 
-    public void getAppMetrics(DisplayMetrics outMetrics, CompatibilityInfoHolder cih) {
-        getMetricsWithSize(outMetrics, cih, appWidth, appHeight);
+    public void getAppMetrics(DisplayMetrics outMetrics) {
+        getAppMetrics(outMetrics, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
     }
 
-    public void getLogicalMetrics(DisplayMetrics outMetrics, CompatibilityInfoHolder cih) {
-        getMetricsWithSize(outMetrics, cih, logicalWidth, logicalHeight);
+    public void getAppMetrics(DisplayMetrics outMetrics, DisplayAdjustments displayAdjustments) {
+        getMetricsWithSize(outMetrics, displayAdjustments.getCompatibilityInfo(),
+                displayAdjustments.getActivityToken(), appWidth, appHeight);
+    }
+
+    public void getAppMetrics(DisplayMetrics outMetrics, CompatibilityInfo ci, IBinder token) {
+        getMetricsWithSize(outMetrics, ci, token, appWidth, appHeight);
+    }
+
+    public void getLogicalMetrics(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
+            IBinder token) {
+        getMetricsWithSize(outMetrics, compatInfo, token, logicalWidth, logicalHeight);
     }
 
     public int getNaturalWidth() {
@@ -335,8 +372,15 @@
                 logicalHeight : logicalWidth;
     }
 
-    private void getMetricsWithSize(DisplayMetrics outMetrics, CompatibilityInfoHolder cih,
-            int width, int height) {
+    /**
+     * Returns true if the specified UID has access to this display.
+     */
+    public boolean hasAccess(int uid) {
+        return Display.hasAccess(uid, flags, ownerUid);
+    }
+
+    private void getMetricsWithSize(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
+            IBinder token, int width, int height) {
         outMetrics.densityDpi = outMetrics.noncompatDensityDpi = logicalDensityDpi;
         outMetrics.noncompatWidthPixels  = outMetrics.widthPixels = width;
         outMetrics.noncompatHeightPixels = outMetrics.heightPixels = height;
@@ -347,11 +391,8 @@
         outMetrics.xdpi = outMetrics.noncompatXdpi = physicalXDpi;
         outMetrics.ydpi = outMetrics.noncompatYdpi = physicalYDpi;
 
-        if (cih != null) {
-            CompatibilityInfo ci = cih.getIfNeeded();
-            if (ci != null) {
-                ci.applyToDisplayMetrics(outMetrics);
-            }
+        if (!compatInfo.equals(CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO)) {
+            compatInfo.applyToDisplayMetrics(outMetrics);
         }
     }
 
@@ -402,8 +443,13 @@
         sb.append(layerStack);
         sb.append(", type ");
         sb.append(Display.typeToString(type));
-        sb.append(", address ");
-        sb.append(address);
+        if (address != null) {
+            sb.append(", address ").append(address);
+        }
+        if (ownerUid != 0 || ownerPackageName != null) {
+            sb.append(", owner ").append(ownerPackageName);
+            sb.append(" (uid ").append(ownerUid).append(")");
+        }
         sb.append(flagsToString(flags));
         sb.append("}");
         return sb.toString();
@@ -417,6 +463,12 @@
         if ((flags & Display.FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) {
             result.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS");
         }
+        if ((flags & Display.FLAG_PRIVATE) != 0) {
+            result.append(", FLAG_PRIVATE");
+        }
+        if ((flags & Display.FLAG_PRESENTATION) != 0) {
+            result.append(", FLAG_PRESENTATION");
+        }
         return result.toString();
     }
 }
diff --git a/core/java/android/view/DisplayList.java b/core/java/android/view/DisplayList.java
index 2d24c1e..43fd628 100644
--- a/core/java/android/view/DisplayList.java
+++ b/core/java/android/view/DisplayList.java
@@ -208,9 +208,22 @@
      * {@link #isValid()} will return false.
      *
      * @see #isValid()
+     * @see #reset()
      */
     public abstract void clear();
 
+
+    /**
+     * Reset native resources. This is called when cleaning up the state of display lists
+     * during destruction of hardware resources, to ensure that we do not hold onto
+     * obsolete resources after related resources are gone.
+     *
+     * @see #clear()
+     *
+     * @hide
+     */
+    public abstract void reset();
+
     /**
      * Sets the dirty flag. When a display list is dirty, {@link #clear()} should
      * be invoked whenever possible.
@@ -670,13 +683,4 @@
      * @see View#offsetTopAndBottom(int)
      */
     public abstract void offsetTopAndBottom(float offset);
-
-    /**
-     * Reset native resources. This is called when cleaning up the state of display lists
-     * during destruction of hardware resources, to ensure that we do not hold onto
-     * obsolete resources after related resources are gone.
-     *
-     * @hide
-     */
-    public abstract void reset();
 }
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 2ec9a7d..beefc21 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -21,6 +21,7 @@
 import android.graphics.ColorFilter;
 import android.graphics.DrawFilter;
 import android.graphics.Matrix;
+import android.graphics.NinePatch;
 import android.graphics.Paint;
 import android.graphics.PaintFlagsDrawFilter;
 import android.graphics.Path;
@@ -58,11 +59,11 @@
     private int mWidth;
     private int mHeight;
     
-    private final float[] mPoint = new float[2];
-    private final float[] mLine = new float[4];
+    private float[] mPoint;
+    private float[] mLine;
     
-    private final Rect mClipBounds = new Rect();
-    private final RectF mPathBounds = new RectF();
+    private Rect mClipBounds;
+    private RectF mPathBounds;
 
     private DrawFilter mFilter;
 
@@ -162,6 +163,16 @@
     }
 
     @Override
+    void cancelLayerUpdate(HardwareLayer layer) {
+        nCancelLayerUpdate(mRenderer, ((GLES20RenderLayer) layer).mLayer);
+    }
+
+    @Override
+    void flushLayerUpdates() {
+        nFlushLayerUpdates(mRenderer);
+    }
+
+    @Override
     void clearLayerUpdates() {
         nClearLayerUpdates(mRenderer);
     }
@@ -183,7 +194,9 @@
     static native boolean nCopyLayer(int layerId, int bitmap);
 
     private static native void nClearLayerUpdates(int renderer);
+    private static native void nFlushLayerUpdates(int renderer);
     private static native void nPushLayerUpdate(int renderer, int layer);
+    private static native void nCancelLayerUpdate(int renderer, int layer);
 
     ///////////////////////////////////////////////////////////////////////////
     // Canvas management
@@ -273,6 +286,18 @@
 
     private static native int nGetStencilSize();
 
+    void setCountOverdrawEnabled(boolean enabled) {
+        nSetCountOverdrawEnabled(mRenderer, enabled);
+    }
+
+    static native void nSetCountOverdrawEnabled(int renderer, boolean enabled);
+
+    float getOverdraw() {
+        return nGetOverdraw(mRenderer);
+    }
+
+    static native float nGetOverdraw(int renderer);
+
     ///////////////////////////////////////////////////////////////////////////
     // Functor
     ///////////////////////////////////////////////////////////////////////////
@@ -314,21 +339,21 @@
      * 
      * @see #flushCaches(int) 
      */
-    public static final int FLUSH_CACHES_LAYERS = 0;
+    static final int FLUSH_CACHES_LAYERS = 0;
     
     /**
      * Must match Caches::FlushMode values
      * 
      * @see #flushCaches(int) 
      */
-    public static final int FLUSH_CACHES_MODERATE = 1;
+    static final int FLUSH_CACHES_MODERATE = 1;
 
     /**
      * Must match Caches::FlushMode values
      * 
      * @see #flushCaches(int) 
      */
-    public static final int FLUSH_CACHES_FULL = 2;
+    static final int FLUSH_CACHES_FULL = 2;
 
     /**
      * Flush caches to reclaim as much memory as possible. The amount of memory
@@ -338,10 +363,8 @@
      * {@link #FLUSH_CACHES_FULL}.
      * 
      * @param level Hint about the amount of memory to reclaim
-     * 
-     * @hide
      */
-    public static void flushCaches(int level) {
+    static void flushCaches(int level) {
         nFlushCaches(level);
     }
 
@@ -353,21 +376,28 @@
      * 
      * @hide
      */
-    public static void terminateCaches() {
+    static void terminateCaches() {
         nTerminateCaches();
     }
 
     private static native void nTerminateCaches();
 
-    /**
-     * @hide
-     */
-    public static void initCaches() {
-        nInitCaches();
+    static boolean initCaches() {
+        return nInitCaches();
     }
 
-    private static native void nInitCaches();
-    
+    private static native boolean nInitCaches();
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Atlas
+    ///////////////////////////////////////////////////////////////////////////
+
+    static void initAtlas(GraphicBuffer buffer, int[] map) {
+        nInitAtlas(buffer, map, map.length);
+    }
+
+    private static native void nInitAtlas(GraphicBuffer buffer, int[] map, int count);
+
     ///////////////////////////////////////////////////////////////////////////
     // Display list
     ///////////////////////////////////////////////////////////////////////////
@@ -419,6 +449,31 @@
     private static native void nResume(int renderer);
 
     ///////////////////////////////////////////////////////////////////////////
+    // Support
+    ///////////////////////////////////////////////////////////////////////////
+
+    private Rect getInternalClipBounds() {
+        if (mClipBounds == null) mClipBounds = new Rect();
+        return mClipBounds;
+    }
+
+
+    private RectF getPathBounds() {
+        if (mPathBounds == null) mPathBounds = new RectF();
+        return mPathBounds;
+    }
+
+    private float[] getPointStorage() {
+        if (mPoint == null) mPoint = new float[2];
+        return mPoint;
+    }
+
+    private float[] getLineStorage() {
+        if (mLine == null) mLine = new float[4];
+        return mLine;
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
     // Clipping
     ///////////////////////////////////////////////////////////////////////////
 
@@ -506,9 +561,10 @@
 
     @Override
     public boolean quickReject(Path path, EdgeType type) {
-        path.computeBounds(mPathBounds, true);
-        return nQuickReject(mRenderer, mPathBounds.left, mPathBounds.top,
-                mPathBounds.right, mPathBounds.bottom);
+        RectF pathBounds = getPathBounds();
+        path.computeBounds(pathBounds, true);
+        return nQuickReject(mRenderer, pathBounds.left, pathBounds.top,
+                pathBounds.right, pathBounds.bottom);
     }
 
     @Override
@@ -565,7 +621,7 @@
 
     @Override
     public void concat(Matrix matrix) {
-        nConcatMatrix(mRenderer, matrix.native_instance);
+        if (matrix != null) nConcatMatrix(mRenderer, matrix.native_instance);
     }
     
     private static native void nConcatMatrix(int renderer, int matrix);
@@ -718,25 +774,41 @@
     }
 
     @Override
-    public void drawPatch(Bitmap bitmap, byte[] chunks, RectF dst, Paint paint) {
-        if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps");
+    public void drawPatch(NinePatch patch, Rect dst, Paint paint) {
+        Bitmap bitmap = patch.getBitmap();
+        throwIfCannotDraw(bitmap);
         // Shaders are ignored when drawing patches
         int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
         try {
             final int nativePaint = paint == null ? 0 : paint.mNativePaint;
-            nDrawPatch(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, chunks,
+            nDrawPatch(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, patch.mNativeChunk,
                     dst.left, dst.top, dst.right, dst.bottom, nativePaint);
         } finally {
             if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
         }
     }
 
-    private static native void nDrawPatch(int renderer, int bitmap, byte[] buffer, byte[] chunks,
+    @Override
+    public void drawPatch(NinePatch patch, RectF dst, Paint paint) {
+        Bitmap bitmap = patch.getBitmap();
+        throwIfCannotDraw(bitmap);
+        // Shaders are ignored when drawing patches
+        int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
+        try {
+            final int nativePaint = paint == null ? 0 : paint.mNativePaint;
+            nDrawPatch(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, patch.mNativeChunk,
+                    dst.left, dst.top, dst.right, dst.bottom, nativePaint);
+        } finally {
+            if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
+        }
+    }
+
+    private static native void nDrawPatch(int renderer, int bitmap, byte[] buffer, int chunk,
             float left, float top, float right, float bottom, int paint);
 
     @Override
     public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) {
-        if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps");
+        throwIfCannotDraw(bitmap);
         // Shaders are ignored when drawing bitmaps
         int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
         try {
@@ -747,12 +819,12 @@
         }
     }
 
-    private static native void nDrawBitmap(
-            int renderer, int bitmap, byte[] buffer, float left, float top, int paint);
+    private static native void nDrawBitmap(int renderer, int bitmap, byte[] buffer,
+            float left, float top, int paint);
 
     @Override
     public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) {
-        if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps");
+        throwIfCannotDraw(bitmap);
         // Shaders are ignored when drawing bitmaps
         int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
         try {
@@ -764,12 +836,12 @@
         }
     }
 
-    private static native void nDrawBitmap(int renderer, int bitmap, byte[] buff,
+    private static native void nDrawBitmap(int renderer, int bitmap, byte[] buffer,
             int matrix, int paint);
 
     @Override
     public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) {
-        if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps");
+        throwIfCannotDraw(bitmap);
         // Shaders are ignored when drawing bitmaps
         int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
         try {
@@ -796,7 +868,7 @@
 
     @Override
     public void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) {
-        if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps");
+        throwIfCannotDraw(bitmap);
         // Shaders are ignored when drawing bitmaps
         int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
         try {
@@ -872,7 +944,7 @@
     @Override
     public void drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts,
             int vertOffset, int[] colors, int colorOffset, Paint paint) {
-        if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps");
+        throwIfCannotDraw(bitmap);
         if (meshWidth < 0 || meshHeight < 0 || vertOffset < 0 || colorOffset < 0) {
             throw new ArrayIndexOutOfBoundsException();
         }
@@ -890,7 +962,7 @@
 
         int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
         try {
-            final int nativePaint = paint == null ? 0 : paint.mNativePaint;        
+            final int nativePaint = paint == null ? 0 : paint.mNativePaint;
             nDrawBitmapMesh(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, meshWidth, meshHeight,
                     verts, vertOffset, colors, colorOffset, nativePaint);
         } finally {
@@ -929,11 +1001,12 @@
 
     @Override
     public void drawLine(float startX, float startY, float stopX, float stopY, Paint paint) {
-        mLine[0] = startX;
-        mLine[1] = startY;
-        mLine[2] = stopX;
-        mLine[3] = stopY;
-        drawLines(mLine, 0, 4, paint);
+        float[] line = getLineStorage();
+        line[0] = startX;
+        line[1] = startY;
+        line[2] = stopX;
+        line[3] = stopY;
+        drawLines(line, 0, 4, paint);
     }
 
     @Override
@@ -974,7 +1047,7 @@
 
     @Override
     public void drawPaint(Paint paint) {
-        final Rect r = mClipBounds;
+        final Rect r = getInternalClipBounds();
         nGetClipBounds(mRenderer, r);
         drawRect(r.left, r.top, r.right, r.bottom, paint);
     }
@@ -1051,9 +1124,10 @@
 
     @Override
     public void drawPoint(float x, float y, Paint paint) {
-        mPoint[0] = x;
-        mPoint[1] = y;
-        drawPoints(mPoint, 0, 2, paint);
+        float[] point = getPointStorage();
+        point[0] = x;
+        point[1] = y;
+        drawPoints(point, 0, 2, paint);
     }
 
     @Override
diff --git a/core/java/android/view/GLES20DisplayList.java b/core/java/android/view/GLES20DisplayList.java
index 3272504..c652bac 100644
--- a/core/java/android/view/GLES20DisplayList.java
+++ b/core/java/android/view/GLES20DisplayList.java
@@ -16,7 +16,6 @@
 
 package android.view;
 
-import android.graphics.Bitmap;
 import android.graphics.Matrix;
 
 import java.util.ArrayList;
@@ -25,12 +24,7 @@
  * An implementation of display list for OpenGL ES 2.0.
  */
 class GLES20DisplayList extends DisplayList {
-    // These lists ensure that any Bitmaps and DisplayLists recorded by a DisplayList are kept
-    // alive as long as the DisplayList is alive.  The Bitmap and DisplayList lists
-    // are populated by the GLES20RecordingCanvas during appropriate drawing calls and are
-    // cleared at the start of a new drawing frame or when the view is detached from the window.
-    final ArrayList<Bitmap> mBitmaps = new ArrayList<Bitmap>(5);
-    final ArrayList<DisplayList> mChildDisplayLists = new ArrayList<DisplayList>();
+    private ArrayList<DisplayList> mChildDisplayLists;
 
     private GLES20RecordingCanvas mCanvas;
     private boolean mValid;
@@ -83,8 +77,16 @@
         }
         mValid = false;
 
-        mBitmaps.clear();
-        mChildDisplayLists.clear();
+        clearReferences();
+    }
+
+    void clearReferences() {
+        if (mChildDisplayLists != null) mChildDisplayLists.clear();
+    }
+
+    ArrayList<DisplayList> getChildDisplayLists() {
+        if (mChildDisplayLists == null) mChildDisplayLists = new ArrayList<DisplayList>();
+        return mChildDisplayLists;
     }
 
     @Override
@@ -92,6 +94,7 @@
         if (hasNativeDisplayList()) {
             nReset(mFinalizer.mNativeDisplayList);
         }
+        clear();
     }
 
     @Override
diff --git a/core/java/android/view/GLES20Layer.java b/core/java/android/view/GLES20Layer.java
index 7ee628b..0e3311c 100644
--- a/core/java/android/view/GLES20Layer.java
+++ b/core/java/android/view/GLES20Layer.java
@@ -59,6 +59,9 @@
 
     @Override
     public void destroy() {
+        if (mDisplayList != null) {
+            mDisplayList.reset();
+        }
         if (mFinalizer != null) {
             mFinalizer.destroy();
             mFinalizer = null;
diff --git a/core/java/android/view/GLES20RecordingCanvas.java b/core/java/android/view/GLES20RecordingCanvas.java
index 7da2451..b6fc38d 100644
--- a/core/java/android/view/GLES20RecordingCanvas.java
+++ b/core/java/android/view/GLES20RecordingCanvas.java
@@ -16,14 +16,7 @@
 
 package android.view;
 
-import android.graphics.Bitmap;
-import android.graphics.BitmapShader;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.Path;
 import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.Shader;
 import android.util.Pools.SynchronizedPool;
 
 /**
@@ -62,229 +55,17 @@
     }
 
     void start() {
-        mDisplayList.mBitmaps.clear();
-        mDisplayList.mChildDisplayLists.clear();
+        mDisplayList.clearReferences();
     }
 
     int end(int nativeDisplayList) {
         return getDisplayList(nativeDisplayList);
     }
 
-    private void recordShaderBitmap(Paint paint) {
-        if (paint != null) {
-            final Shader shader = paint.getShader();
-            if (shader instanceof BitmapShader) {
-                mDisplayList.mBitmaps.add(((BitmapShader) shader).mBitmap);
-            }
-        }
-    }
-
-    @Override
-    public void drawPatch(Bitmap bitmap, byte[] chunks, RectF dst, Paint paint) {
-        super.drawPatch(bitmap, chunks, dst, paint);
-        mDisplayList.mBitmaps.add(bitmap);
-        // Shaders in the Paint are ignored when drawing a Bitmap
-    }
-
-    @Override
-    public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) {
-        super.drawBitmap(bitmap, left, top, paint);
-        mDisplayList.mBitmaps.add(bitmap);
-        // Shaders in the Paint are ignored when drawing a Bitmap
-    }
-
-    @Override
-    public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) {
-        super.drawBitmap(bitmap, matrix, paint);
-        mDisplayList.mBitmaps.add(bitmap);
-        // Shaders in the Paint are ignored when drawing a Bitmap
-    }
-
-    @Override
-    public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) {
-        super.drawBitmap(bitmap, src, dst, paint);
-        mDisplayList.mBitmaps.add(bitmap);
-        // Shaders in the Paint are ignored when drawing a Bitmap
-    }
-
-    @Override
-    public void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) {
-        super.drawBitmap(bitmap, src, dst, paint);
-        mDisplayList.mBitmaps.add(bitmap);
-        // Shaders in the Paint are ignored when drawing a Bitmap
-    }
-
-    @Override
-    public void drawBitmap(int[] colors, int offset, int stride, float x, float y, int width,
-            int height, boolean hasAlpha, Paint paint) {
-        super.drawBitmap(colors, offset, stride, x, y, width, height, hasAlpha, paint);
-        // Shaders in the Paint are ignored when drawing a Bitmap
-    }
-
-    @Override
-    public void drawBitmap(int[] colors, int offset, int stride, int x, int y, int width,
-            int height, boolean hasAlpha, Paint paint) {
-        super.drawBitmap(colors, offset, stride, x, y, width, height, hasAlpha, paint);
-        // Shaders in the Paint are ignored when drawing a Bitmap
-    }
-
-    @Override
-    public void drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts,
-            int vertOffset, int[] colors, int colorOffset, Paint paint) {
-        super.drawBitmapMesh(bitmap, meshWidth, meshHeight, verts, vertOffset,
-                colors, colorOffset, paint);
-        mDisplayList.mBitmaps.add(bitmap);
-        // Shaders in the Paint are ignored when drawing a Bitmap
-    }
-
-    @Override
-    public void drawCircle(float cx, float cy, float radius, Paint paint) {
-        super.drawCircle(cx, cy, radius, paint);
-        recordShaderBitmap(paint);
-    }
-
     @Override
     public int drawDisplayList(DisplayList displayList, Rect dirty, int flags) {
         int status = super.drawDisplayList(displayList, dirty, flags);
-        mDisplayList.mChildDisplayLists.add(displayList);
+        mDisplayList.getChildDisplayLists().add(displayList);
         return status;
     }
-
-    @Override
-    public void drawLine(float startX, float startY, float stopX, float stopY, Paint paint) {
-        super.drawLine(startX, startY, stopX, stopY, paint);
-        recordShaderBitmap(paint);
-    }
-
-    @Override
-    public void drawLines(float[] pts, int offset, int count, Paint paint) {
-        super.drawLines(pts, offset, count, paint);
-        recordShaderBitmap(paint);
-    }
-
-    @Override
-    public void drawLines(float[] pts, Paint paint) {
-        super.drawLines(pts, paint);
-        recordShaderBitmap(paint);
-    }
-
-    @Override
-    public void drawOval(RectF oval, Paint paint) {
-        super.drawOval(oval, paint);
-        recordShaderBitmap(paint);
-    }
-
-    @Override
-    public void drawPaint(Paint paint) {
-        super.drawPaint(paint);
-        recordShaderBitmap(paint);
-    }
-
-    @Override
-    public void drawPath(Path path, Paint paint) {
-        super.drawPath(path, paint);
-        recordShaderBitmap(paint);
-    }
-
-    @Override
-    public void drawPoint(float x, float y, Paint paint) {
-        super.drawPoint(x, y, paint);
-        recordShaderBitmap(paint);
-    }
-
-    @Override
-    public void drawPoints(float[] pts, int offset, int count, Paint paint) {
-        super.drawPoints(pts, offset, count, paint);
-        recordShaderBitmap(paint);
-    }
-
-    @Override
-    public void drawPoints(float[] pts, Paint paint) {
-        super.drawPoints(pts, paint);
-        recordShaderBitmap(paint);
-    }
-
-    @Override
-    public void drawPosText(char[] text, int index, int count, float[] pos, Paint paint) {
-        super.drawPosText(text, index, count, pos, paint);
-        recordShaderBitmap(paint);
-    }
-
-    @Override
-    public void drawPosText(String text, float[] pos, Paint paint) {
-        super.drawPosText(text, pos, paint);
-        recordShaderBitmap(paint);
-    }
-
-    @Override
-    public void drawRect(float left, float top, float right, float bottom, Paint paint) {
-        super.drawRect(left, top, right, bottom, paint);
-        recordShaderBitmap(paint);
-    }
-
-    @Override
-    public void drawRoundRect(RectF rect, float rx, float ry, Paint paint) {
-        super.drawRoundRect(rect, rx, ry, paint);
-        recordShaderBitmap(paint);
-    }
-
-    @Override
-    public void drawText(char[] text, int index, int count, float x, float y, Paint paint) {
-        super.drawText(text, index, count, x, y, paint);
-        recordShaderBitmap(paint);
-    }
-
-    @Override
-    public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) {
-        super.drawText(text, start, end, x, y, paint);
-        recordShaderBitmap(paint);
-    }
-
-    @Override
-    public void drawText(String text, int start, int end, float x, float y, Paint paint) {
-        super.drawText(text, start, end, x, y, paint);
-        recordShaderBitmap(paint);
-    }
-
-    @Override
-    public void drawText(String text, float x, float y, Paint paint) {
-        super.drawText(text, x, y, paint);
-        recordShaderBitmap(paint);
-    }
-
-    @Override
-    public void drawTextOnPath(char[] text, int index, int count, Path path, float hOffset,
-            float vOffset, Paint paint) {
-        super.drawTextOnPath(text, index, count, path, hOffset, vOffset, paint);
-        recordShaderBitmap(paint);
-    }
-
-    @Override
-    public void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) {
-        super.drawTextOnPath(text, path, hOffset, vOffset, paint);
-        recordShaderBitmap(paint);
-    }
-
-    @Override
-    public void drawTextRun(char[] text, int index, int count, int contextIndex, int contextCount,
-            float x, float y, int dir, Paint paint) {
-        super.drawTextRun(text, index, count, contextIndex, contextCount, x, y, dir, paint);
-        recordShaderBitmap(paint);
-    }
-
-    @Override
-    public void drawTextRun(CharSequence text, int start, int end, int contextStart,
-            int contextEnd, float x, float y, int dir, Paint paint) {
-        super.drawTextRun(text, start, end, contextStart, contextEnd, x, y, dir, paint);
-        recordShaderBitmap(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) {
-        super.drawVertices(mode, vertexCount, verts, vertOffset, texs, texOffset, colors,
-                colorOffset, indices, indexOffset, indexCount, paint);
-        recordShaderBitmap(paint);
-    }
 }
diff --git a/core/java/android/view/GLES20RenderLayer.java b/core/java/android/view/GLES20RenderLayer.java
index 685dc70..68ba77c 100644
--- a/core/java/android/view/GLES20RenderLayer.java
+++ b/core/java/android/view/GLES20RenderLayer.java
@@ -100,12 +100,17 @@
 
     @Override
     HardwareCanvas start(Canvas currentCanvas) {
+        return start(currentCanvas, null);
+    }
+
+    @Override
+    HardwareCanvas start(Canvas currentCanvas, Rect dirty) {
         if (currentCanvas instanceof GLES20Canvas) {
             ((GLES20Canvas) currentCanvas).interrupt();
         }
         HardwareCanvas canvas = getCanvas();
         canvas.setViewport(mWidth, mHeight);
-        canvas.onPreDraw(null);
+        canvas.onPreDraw(dirty);
         return canvas;
     }
 
diff --git a/core/java/android/view/GLES20TextureLayer.java b/core/java/android/view/GLES20TextureLayer.java
index e863e49..bb5a6eb 100644
--- a/core/java/android/view/GLES20TextureLayer.java
+++ b/core/java/android/view/GLES20TextureLayer.java
@@ -63,12 +63,17 @@
     }
 
     @Override
+    HardwareCanvas start(Canvas currentCanvas, Rect dirty) {
+        return null;
+    }
+
+    @Override
     void end(Canvas currentCanvas) {
     }
 
     SurfaceTexture getSurfaceTexture() {
         if (mSurface == null) {
-            mSurface = new SurfaceTexture(mTexture, false);
+            mSurface = new SurfaceTexture(mTexture);
         }
         return mSurface;
     }
diff --git a/core/java/android/view/GestureDetector.java b/core/java/android/view/GestureDetector.java
index 6bbfe0f..2351548 100644
--- a/core/java/android/view/GestureDetector.java
+++ b/core/java/android/view/GestureDetector.java
@@ -17,7 +17,6 @@
 package android.view;
 
 import android.content.Context;
-import android.os.Build;
 import android.os.Handler;
 import android.os.Message;
 
@@ -202,6 +201,7 @@
     private static final int LONGPRESS_TIMEOUT = ViewConfiguration.getLongPressTimeout();
     private static final int TAP_TIMEOUT = ViewConfiguration.getTapTimeout();
     private static final int DOUBLE_TAP_TIMEOUT = ViewConfiguration.getDoubleTapTimeout();
+    private static final int DOUBLE_TAP_MIN_TIME = ViewConfiguration.getDoubleTapMinTime();
 
     // constants for Message.what used by GestureHandler below
     private static final int SHOW_PRESS = 1;
@@ -673,7 +673,8 @@
             return false;
         }
 
-        if (secondDown.getEventTime() - firstUp.getEventTime() > DOUBLE_TAP_TIMEOUT) {
+        final long deltaTime = secondDown.getEventTime() - firstUp.getEventTime();
+        if (deltaTime > DOUBLE_TAP_TIMEOUT || deltaTime < DOUBLE_TAP_MIN_TIME) {
             return false;
         }
 
diff --git a/core/java/android/view/GraphicBuffer.aidl b/core/java/android/view/GraphicBuffer.aidl
new file mode 100644
index 0000000..6dc6bed
--- /dev/null
+++ b/core/java/android/view/GraphicBuffer.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.view;
+
+parcelable GraphicBuffer;
diff --git a/core/java/android/view/GraphicBuffer.java b/core/java/android/view/GraphicBuffer.java
new file mode 100644
index 0000000..30c077c
--- /dev/null
+++ b/core/java/android/view/GraphicBuffer.java
@@ -0,0 +1,292 @@
+/*
+ * 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.view;
+
+import android.graphics.Canvas;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Simple wrapper for the native GraphicBuffer class.
+ *
+ * @hide
+ */
+@SuppressWarnings("UnusedDeclaration")
+public class GraphicBuffer implements Parcelable {
+    // Note: keep usage flags in sync with GraphicBuffer.h and gralloc.h
+    public static final int USAGE_SW_READ_NEVER = 0x0;
+    public static final int USAGE_SW_READ_RARELY = 0x2;
+    public static final int USAGE_SW_READ_OFTEN = 0x3;
+    public static final int USAGE_SW_READ_MASK = 0xF;
+
+    public static final int USAGE_SW_WRITE_NEVER = 0x0;
+    public static final int USAGE_SW_WRITE_RARELY = 0x20;
+    public static final int USAGE_SW_WRITE_OFTEN = 0x30;
+    public static final int USAGE_SW_WRITE_MASK = 0xF0;
+
+    public static final int USAGE_SOFTWARE_MASK = USAGE_SW_READ_MASK | USAGE_SW_WRITE_MASK;
+
+    public static final int USAGE_PROTECTED = 0x4000;
+
+    public static final int USAGE_HW_TEXTURE = 0x100;
+    public static final int USAGE_HW_RENDER = 0x200;
+    public static final int USAGE_HW_2D = 0x400;
+    public static final int USAGE_HW_COMPOSER = 0x800;
+    public static final int USAGE_HW_VIDEO_ENCODER = 0x10000;
+    public static final int USAGE_HW_MASK = 0x71F00;
+
+    private final int mWidth;
+    private final int mHeight;
+    private final int mFormat;
+    private final int mUsage;
+    // Note: do not rename, this field is used by native code
+    private final int mNativeObject;
+
+    // These two fields are only used by lock/unlockCanvas()
+    private Canvas mCanvas;
+    private int mSaveCount;
+
+    // If set to true, this GraphicBuffer instance cannot be used anymore
+    private boolean mDestroyed;
+
+    /**
+     * Creates new <code>GraphicBuffer</code> instance. This method will return null
+     * if the buffer cannot be created.
+     *
+     * @param width The width in pixels of the buffer
+     * @param height The height in pixels of the buffer
+     * @param format The format of each pixel as specified in {@link PixelFormat}
+     * @param usage Hint indicating how the buffer will be used
+     *
+     * @return A <code>GraphicBuffer</code> instance or null
+     */
+    public static GraphicBuffer create(int width, int height, int format, int usage) {
+        int nativeObject = nCreateGraphicBuffer(width, height, format, usage);
+        if (nativeObject != 0) {
+            return new GraphicBuffer(width, height, format, usage, nativeObject);
+        }
+        return null;
+    }
+
+    /**
+     * Private use only. See {@link #create(int, int, int, int)}.
+     */
+    private GraphicBuffer(int width, int height, int format, int usage, int nativeObject) {
+        mWidth = width;
+        mHeight = height;
+        mFormat = format;
+        mUsage = usage;
+        mNativeObject = nativeObject;
+    }
+
+    /**
+     * Returns the width of this buffer in pixels.
+     */
+    public int getWidth() {
+        return mWidth;
+    }
+
+    /**
+     * Returns the height of this buffer in pixels.
+     */
+    public int getHeight() {
+        return mHeight;
+    }
+
+    /**
+     * Returns the pixel format of this buffer. The pixel format must be one of
+     * the formats defined in {@link PixelFormat}.
+     */
+    public int getFormat() {
+        return mFormat;
+    }
+
+    /**
+     * Returns the usage hint set on this buffer.
+     */
+    public int getUsage() {
+        return mUsage;
+    }
+
+    /**
+     * <p>Start editing the pixels in the buffer. A null is returned if the buffer
+     * cannot be locked for editing.</p>
+     *
+     * <p>The content of the buffer is preserved between unlockCanvas()
+     * and lockCanvas().</p>
+     *
+     * <p>If this method is called after {@link #destroy()}, the return value will
+     * always be null.</p>
+     *
+     * @return A Canvas used to draw into the buffer, or null.
+     *
+     * @see #lockCanvas(android.graphics.Rect)
+     * @see #unlockCanvasAndPost(android.graphics.Canvas)
+     * @see #isDestroyed()
+     */
+    public Canvas lockCanvas() {
+        return lockCanvas(null);
+    }
+
+    /**
+     * Just like {@link #lockCanvas()} but allows specification of a dirty
+     * rectangle.
+     *
+     * <p>If this method is called after {@link #destroy()}, the return value will
+     * always be null.</p>
+     *
+     * @param dirty Area of the buffer that may be modified.
+
+     * @return A Canvas used to draw into the surface, or null.
+     *
+     * @see #lockCanvas()
+     * @see #unlockCanvasAndPost(android.graphics.Canvas)
+     * @see #isDestroyed()
+     */
+    public Canvas lockCanvas(Rect dirty) {
+        if (mDestroyed) {
+            return null;
+        }
+
+        if (mCanvas == null) {
+            mCanvas = new Canvas();
+        }
+
+        if (nLockCanvas(mNativeObject, mCanvas, dirty)) {
+            mSaveCount = mCanvas.save();
+            return mCanvas;
+        }
+
+        return null;
+    }
+
+    /**
+     * Finish editing pixels in the buffer.
+     *
+     * <p>This method doesn't do anything if {@link #destroy()} was
+     * previously called.</p>
+     *
+     * @param canvas The Canvas previously returned by lockCanvas()
+     *
+     * @see #lockCanvas()
+     * @see #lockCanvas(android.graphics.Rect)
+     * @see #isDestroyed()
+     */
+    public void unlockCanvasAndPost(Canvas canvas) {
+        if (!mDestroyed && mCanvas != null && canvas == mCanvas) {
+            canvas.restoreToCount(mSaveCount);
+            mSaveCount = 0;
+
+            nUnlockCanvasAndPost(mNativeObject, mCanvas);
+        }
+    }
+
+    /**
+     * Destroyes this buffer immediately. Calling this method frees up any
+     * underlying native resources. After calling this method, this buffer
+     * must not be used in any way ({@link #lockCanvas()} must not be called,
+     * etc.)
+     *
+     * @see #isDestroyed()
+     */
+    public void destroy() {
+        if (!mDestroyed) {
+            mDestroyed = true;
+            nDestroyGraphicBuffer(mNativeObject);
+        }
+    }
+
+    /**
+     * Indicates whether this buffer has been destroyed. A destroyed buffer
+     * cannot be used in any way: locking a Canvas will return null, the buffer
+     * cannot be written to a parcel, etc.
+     *
+     * @return True if this <code>GraphicBuffer</code> is in a destroyed state,
+     *         false otherwise.
+     *
+     * @see #destroy()
+     */
+    public boolean isDestroyed() {
+        return mDestroyed;
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            if (!mDestroyed) nDestroyGraphicBuffer(mNativeObject);
+        } finally {
+            super.finalize();
+        }
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * Flatten this object in to a Parcel.
+     *
+     * <p>Calling this method will throw an <code>IllegalStateException</code> if
+     * {@link #destroy()} has been previously called.</p>
+     *
+     * @param dest The Parcel in which the object should be written.
+     * @param flags Additional flags about how the object should be written.
+     *              May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
+     */
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        if (mDestroyed) {
+            throw new IllegalStateException("This GraphicBuffer has been destroyed and cannot be "
+                    + "written to a parcel.");
+        }
+
+        dest.writeInt(mWidth);
+        dest.writeInt(mHeight);
+        dest.writeInt(mFormat);
+        dest.writeInt(mUsage);
+        nWriteGraphicBufferToParcel(mNativeObject, dest);
+    }
+
+    public static final Parcelable.Creator<GraphicBuffer> CREATOR =
+            new Parcelable.Creator<GraphicBuffer>() {
+        public GraphicBuffer createFromParcel(Parcel in) {
+            int width = in.readInt();
+            int height = in.readInt();
+            int format = in.readInt();
+            int usage = in.readInt();
+            int nativeObject = nReadGraphicBufferFromParcel(in);
+            if (nativeObject != 0) {
+                return new GraphicBuffer(width, height, format, usage, nativeObject);
+            }
+            return null;
+        }
+
+        public GraphicBuffer[] newArray(int size) {
+            return new GraphicBuffer[size];
+        }
+    };
+
+    private static native int nCreateGraphicBuffer(int width, int height, int format, int usage);
+    private static native void nDestroyGraphicBuffer(int nativeObject);
+    private static native void nWriteGraphicBufferToParcel(int nativeObject, Parcel dest);
+    private static native int nReadGraphicBufferFromParcel(Parcel in);
+    private static native boolean nLockCanvas(int nativeObject, Canvas canvas, Rect dirty);
+    private static native boolean nUnlockCanvasAndPost(int nativeObject, Canvas canvas);
+}
diff --git a/core/java/android/view/HardwareCanvas.java b/core/java/android/view/HardwareCanvas.java
index 0dfed69..259e1cd 100644
--- a/core/java/android/view/HardwareCanvas.java
+++ b/core/java/android/view/HardwareCanvas.java
@@ -202,6 +202,28 @@
     abstract void pushLayerUpdate(HardwareLayer layer);
 
     /**
+     * Cancels a queued layer update. If the specified layer was not
+     * queued for update, this method has no effect.
+     *
+     * @param layer The layer whose update to cancel
+     *
+     * @see #pushLayerUpdate(HardwareLayer)
+     * @see #clearLayerUpdates()
+     *
+     * @hide
+     */
+    abstract void cancelLayerUpdate(HardwareLayer layer);
+
+    /**
+     * Immediately executes all enqueued layer updates.
+     *
+     * @see #pushLayerUpdate(HardwareLayer)
+     *
+     * @hide
+     */
+    abstract void flushLayerUpdates();
+
+    /**
      * Removes all enqueued layer updates.
      * 
      * @see #pushLayerUpdate(HardwareLayer)
diff --git a/core/java/android/view/HardwareLayer.java b/core/java/android/view/HardwareLayer.java
index 18b838b..23383d9 100644
--- a/core/java/android/view/HardwareLayer.java
+++ b/core/java/android/view/HardwareLayer.java
@@ -158,14 +158,22 @@
     /**
      * This must be invoked before drawing onto this layer.
      *
-     * @param currentCanvas
+     * @param currentCanvas The canvas whose rendering needs to be interrupted
      */
     abstract HardwareCanvas start(Canvas currentCanvas);
 
     /**
+     * This must be invoked before drawing onto this layer.
+     *
+     * @param dirty The dirty area to repaint
+     * @param currentCanvas The canvas whose rendering needs to be interrupted
+     */
+    abstract HardwareCanvas start(Canvas currentCanvas, Rect dirty);
+
+    /**
      * This must be invoked after drawing onto this layer.
      *
-     * @param currentCanvas
+     * @param currentCanvas The canvas whose rendering needs to be resumed
      */
     abstract void end(Canvas currentCanvas);
 
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 8308459..f215189 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -17,6 +17,7 @@
 package android.view;
 
 import android.content.ComponentCallbacks2;
+import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.Rect;
 import android.graphics.SurfaceTexture;
@@ -24,12 +25,17 @@
 import android.opengl.GLUtils;
 import android.opengl.ManagedEGLContext;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.Looper;
+import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.Trace;
 import android.util.DisplayMetrics;
 import android.util.Log;
+import android.view.Surface.OutOfResourcesException;
+
 import com.google.android.gles_jni.EGLImpl;
 
 import javax.microedition.khronos.egl.EGL10;
@@ -42,7 +48,6 @@
 
 import java.io.File;
 import java.io.PrintWriter;
-import java.util.Arrays;
 import java.util.concurrent.locks.ReentrantLock;
 
 import static javax.microedition.khronos.egl.EGL10.*;
@@ -71,7 +76,7 @@
      * System property used to enable or disable dirty regions invalidation.
      * This property is only queried if {@link #RENDER_DIRTY_REGIONS} is true.
      * The default value of this property is assumed to be true.
-     * 
+     *
      * Possible values:
      * "true", to enable partial invalidates
      * "false", to disable partial invalidates
@@ -131,7 +136,7 @@
 
     /**
      * System property used to debug EGL configuration choice.
-     * 
+     *
      * Possible values:
      * "choice", print the chosen configuration only
      * "all", print all possible configurations
@@ -144,7 +149,7 @@
      * Possible values:
      * "true", to enable dirty regions debugging
      * "false", to disable dirty regions debugging
-     * 
+     *
      * @hide
      */
     public static final String DEBUG_DIRTY_REGIONS_PROPERTY = "debug.hwui.show_dirty_regions";
@@ -162,15 +167,32 @@
             "debug.hwui.show_layers_updates";
 
     /**
-     * Turn on to show overdraw level.
+     * Controls overdraw debugging.
      *
      * Possible values:
-     * "true", to enable overdraw debugging
      * "false", to disable overdraw debugging
+     * "show", to show overdraw areas on screen
+     * "count", to display an overdraw counter
      *
      * @hide
      */
-    public static final String DEBUG_SHOW_OVERDRAW_PROPERTY = "debug.hwui.show_overdraw";
+    public static final String DEBUG_OVERDRAW_PROPERTY = "debug.hwui.overdraw";
+
+    /**
+     * Value for {@link #DEBUG_OVERDRAW_PROPERTY}. When the property is set to this
+     * value, overdraw will be shown on screen by coloring pixels.
+     *
+     * @hide
+     */
+    public static final String OVERDRAW_PROPERTY_SHOW = "show";
+
+    /**
+     * Value for {@link #DEBUG_OVERDRAW_PROPERTY}. When the property is set to this
+     * value, an overdraw counter will be shown on screen.
+     *
+     * @hide
+     */
+    public static final String OVERDRAW_PROPERTY_COUNT = "count";
 
     /**
      * Turn on to debug non-rectangular clip operations.
@@ -188,14 +210,14 @@
     /**
      * A process can set this flag to false to prevent the use of hardware
      * rendering.
-     * 
+     *
      * @hide
      */
     public static boolean sRendererDisabled = false;
 
     /**
      * Further hardware renderer disabling for the system process.
-     * 
+     *
      * @hide
      */
     public static boolean sSystemRendererDisabled = false;
@@ -215,7 +237,7 @@
 
     /**
      * Invoke this method to disable hardware rendering in the current process.
-     * 
+     *
      * @hide
      */
     public static void disable(boolean system) {
@@ -228,7 +250,7 @@
     /**
      * Indicates whether hardware acceleration is available under any form for
      * the view hierarchy.
-     * 
+     *
      * @return True if the view hierarchy can potentially be hardware accelerated,
      *         false otherwise
      */
@@ -238,30 +260,30 @@
 
     /**
      * Destroys the hardware rendering context.
-     * 
+     *
      * @param full If true, destroys all associated resources.
      */
     abstract void destroy(boolean full);
 
     /**
      * Initializes the hardware renderer for the specified surface.
-     * 
+     *
      * @param surface The surface to hardware accelerate
-     * 
+     *
      * @return True if the initialization was successful, false otherwise.
      */
-    abstract boolean initialize(Surface surface) throws Surface.OutOfResourcesException;
-    
+    abstract boolean initialize(Surface surface) throws OutOfResourcesException;
+
     /**
      * Updates the hardware renderer for the specified surface.
      *
      * @param surface The surface to hardware accelerate
      */
-    abstract void updateSurface(Surface surface) throws Surface.OutOfResourcesException;
+    abstract void updateSurface(Surface surface) throws OutOfResourcesException;
 
     /**
      * Destroys the layers used by the specified view hierarchy.
-     * 
+     *
      * @param view The root of the view hierarchy
      */
     abstract void destroyLayers(View view);
@@ -269,11 +291,11 @@
     /**
      * Destroys all hardware rendering resources associated with the specified
      * view hierarchy.
-     * 
+     *
      * @param view The root of the view hierarchy
      */
     abstract void destroyHardwareResources(View view);
-    
+
     /**
      * This method should be invoked whenever the current hardware renderer
      * context should be reset.
@@ -286,7 +308,7 @@
      * This method should be invoked to ensure the hardware renderer is in
      * valid state (for instance, to ensure the correct EGL context is bound
      * to the current thread.)
-     * 
+     *
      * @return true if the renderer is now valid, false otherwise
      */
     abstract boolean validate();
@@ -294,7 +316,7 @@
     /**
      * This method ensures the hardware renderer is in a valid state
      * before executing the specified action.
-     * 
+     *
      * This method will attempt to set a valid state even if the window
      * the renderer is attached to was destroyed.
      *
@@ -305,7 +327,7 @@
     /**
      * Setup the hardware renderer for drawing. This is called whenever the
      * size of the target surface changes or when the surface is first created.
-     * 
+     *
      * @param width Width of the drawing surface.
      * @param height Height of the drawing surface.
      */
@@ -364,7 +386,7 @@
     /**
      * Sets the directory to use as a persistent storage for hardware rendering
      * resources.
-     * 
+     *
      * @param cacheDir A directory the current process can write to
      *
      * @hide
@@ -386,6 +408,17 @@
     private static native void nBeginFrame(int[] size);
 
     /**
+     * Returns the current system time according to the renderer.
+     * This method is used for debugging only and should not be used
+     * as a clock.
+     */
+    static long getSystemTime() {
+        return nGetSystemTime();
+    }
+
+    private static native long nGetSystemTime();
+
+    /**
      * Preserves the back buffer of the current surface after a buffer swap.
      * Calling this method sets the EGL_SWAP_BEHAVIOR attribute of the current
      * surface to EGL_BUFFER_PRESERVED. Calling this method requires an EGL
@@ -416,12 +449,32 @@
     /**
      * Indicates that the specified hardware layer needs to be updated
      * as soon as possible.
-     * 
+     *
      * @param layer The hardware layer that needs an update
+     *
+     * @see #flushLayerUpdates()
+     * @see #cancelLayerUpdate(HardwareLayer)
      */
     abstract void pushLayerUpdate(HardwareLayer layer);
 
     /**
+     * Cancels a queued layer update. If the specified layer was not
+     * queued for update, this method has no effect.
+     *
+     * @param layer The layer whose update to cancel
+     *
+     * @see #pushLayerUpdate(HardwareLayer)
+     */
+    abstract void cancelLayerUpdate(HardwareLayer layer);
+
+    /**
+     * Forces all enqueued layer updates to be executed immediately.
+     *
+     * @see #pushLayerUpdate(HardwareLayer)
+     */
+    abstract void flushLayerUpdates();
+
+    /**
      * Interface used to receive callbacks whenever a view is drawn by
      * a hardware renderer instance.
      */
@@ -430,7 +483,7 @@
          * Invoked before a view is drawn by a hardware renderer.
          * This method can be used to apply transformations to the
          * canvas but no drawing command should be issued.
-         * 
+         *
          * @param canvas The Canvas used to render the view.
          */
         void onHardwarePreDraw(HardwareCanvas canvas);
@@ -438,7 +491,7 @@
         /**
          * Invoked after a view is drawn by a hardware renderer.
          * It is safe to invoke drawing commands from this method.
-         * 
+         *
          * @param canvas The Canvas used to render the view.
          */
         void onHardwarePostDraw(HardwareCanvas canvas);
@@ -458,9 +511,9 @@
     /**
      * Creates a new display list that can be used to record batches of
      * drawing operations.
-     * 
+     *
      * @param name The name of the display list, used for debugging purpose. May be null.
-     * 
+     *
      * @return A new display list.
      *
      * @hide
@@ -470,20 +523,20 @@
     /**
      * Creates a new hardware layer. A hardware layer built by calling this
      * method will be treated as a texture layer, instead of as a render target.
-     * 
+     *
      * @param isOpaque Whether the layer should be opaque or not
-     * 
+     *
      * @return A hardware layer
      */
     abstract HardwareLayer createHardwareLayer(boolean isOpaque);
 
     /**
      * Creates a new hardware layer.
-     * 
+     *
      * @param width The minimum width of the layer
      * @param height The minimum height of the layer
      * @param isOpaque Whether the layer should be opaque or not
-     * 
+     *
      * @return A hardware layer
      */
     abstract HardwareLayer createHardwareLayer(int width, int height, boolean isOpaque);
@@ -493,7 +546,7 @@
      * specified hardware layer.
      *
      * @param layer The layer to render into using a {@link android.graphics.SurfaceTexture}
-     * 
+     *
      * @return A {@link SurfaceTexture}
      */
     abstract SurfaceTexture createSurfaceTexture(HardwareLayer layer);
@@ -509,11 +562,11 @@
 
     /**
      * Detaches the specified functor from the current functor execution queue.
-     * 
+     *
      * @param functor The native functor to remove from the execution queue.
-     *                
-     * @see HardwareCanvas#callDrawGLFunction(int) 
-     * @see #attachFunctor(android.view.View.AttachInfo, int) 
+     *
+     * @see HardwareCanvas#callDrawGLFunction(int)
+     * @see #attachFunctor(android.view.View.AttachInfo, int)
      */
     abstract void detachFunctor(int functor);
 
@@ -540,12 +593,12 @@
      * @param width The width of the drawing surface.
      * @param height The height of the drawing surface.
      * @param surface The surface to hardware accelerate
-     *                
+     *
      * @return true if the surface was initialized, false otherwise. Returning
      *         false might mean that the surface was already initialized.
      */
     boolean initializeIfNeeded(int width, int height, Surface surface)
-            throws Surface.OutOfResourcesException {
+            throws OutOfResourcesException {
         if (isRequested()) {
             // We lost the gl context, so recreate it.
             if (!isEnabled()) {
@@ -567,10 +620,10 @@
 
     /**
      * Creates a hardware renderer using OpenGL.
-     * 
+     *
      * @param glVersion The version of OpenGL to use (1 for OpenGL 1, 11 for OpenGL 1.1, etc.)
      * @param translucent True if the surface is translucent, false otherwise
-     * 
+     *
      * @return A hardware renderer backed by OpenGL.
      */
     static HardwareRenderer createGlRenderer(int glVersion, boolean translucent) {
@@ -585,7 +638,7 @@
      * Invoke this method when the system is running out of memory. This
      * method will attempt to recover as much memory as possible, based on
      * the specified hint.
-     * 
+     *
      * @param level Hint about the amount of memory that should be trimmed,
      *              see {@link android.content.ComponentCallbacks}
      */
@@ -598,7 +651,7 @@
      * Starts the process of trimming memory. Usually this call will setup
      * hardware rendering context and reclaim memory.Extra cleanup might
      * be required by calling {@link #endTrimMemory()}.
-     * 
+     *
      * @param level Hint about the amount of memory that should be trimmed,
      *              see {@link android.content.ComponentCallbacks}
      */
@@ -616,7 +669,7 @@
 
     /**
      * Indicates whether hardware acceleration is currently enabled.
-     * 
+     *
      * @return True if hardware acceleration is in use, false otherwise.
      */
     boolean isEnabled() {
@@ -625,7 +678,7 @@
 
     /**
      * Indicates whether hardware acceleration is currently enabled.
-     * 
+     *
      * @param enabled True if the hardware renderer is in use, false otherwise.
      */
     void setEnabled(boolean enabled) {
@@ -635,7 +688,7 @@
     /**
      * Indicates whether hardware acceleration is currently request but not
      * necessarily enabled yet.
-     * 
+     *
      * @return True if requested, false otherwise.
      */
     boolean isRequested() {
@@ -645,7 +698,7 @@
     /**
      * Indicates whether hardware acceleration is currently requested but not
      * necessarily enabled yet.
-     * 
+     *
      * @return True to request hardware acceleration, false otherwise.
      */
     void setRequested(boolean requested) {
@@ -762,6 +815,17 @@
         private static final int PROFILE_DRAW_THRESHOLD_STROKE_WIDTH = 2;
         private static final int PROFILE_DRAW_DP_PER_MS = 7;
 
+        private static final String[] VISUALIZERS = {
+                PROFILE_PROPERTY_VISUALIZE_BARS,
+                PROFILE_PROPERTY_VISUALIZE_LINES
+        };
+
+        private static final String[] OVERDRAW = {
+                OVERDRAW_PROPERTY_SHOW,
+                OVERDRAW_PROPERTY_COUNT
+        };
+        private static final int OVERDRAW_TYPE_COUNT = 1;
+
         static EGL10 sEgl;
         static EGLDisplay sEglDisplay;
         static EGLConfig sEglConfig;
@@ -775,7 +839,7 @@
         Thread mEglThread;
 
         EGLSurface mEglSurface;
-        
+
         GL mGl;
         HardwareCanvas mCanvas;
 
@@ -807,7 +871,9 @@
         Paint mProfilePaint;
 
         boolean mDebugDirtyRegions;
-        boolean mShowOverdraw;
+        int mDebugOverdraw = -1;
+        HardwareLayer mDebugOverdrawLayer;
+        Paint mDebugOverdrawPaint;
 
         final int mGlVersion;
         final boolean mTranslucent;
@@ -819,6 +885,8 @@
         private final int[] mSurfaceSize = new int[2];
         private final FunctorsRunnable mFunctorsRunnable = new FunctorsRunnable();
 
+        private long mDrawDelta = Long.MAX_VALUE;
+
         GlRenderer(int glVersion, boolean translucent) {
             mGlVersion = glVersion;
             mTranslucent = translucent;
@@ -826,18 +894,13 @@
             loadSystemProperties(null);
         }
 
-        private static final String[] VISUALIZERS = {
-                PROFILE_PROPERTY_VISUALIZE_BARS,
-                PROFILE_PROPERTY_VISUALIZE_LINES
-        };
-
         @Override
         boolean loadSystemProperties(Surface surface) {
             boolean value;
             boolean changed = false;
 
             String profiling = SystemProperties.get(PROFILE_PROPERTY);
-            int graphType = Arrays.binarySearch(VISUALIZERS, profiling);
+            int graphType = search(VISUALIZERS, profiling);
             value = graphType >= 0;
 
             if (graphType != mProfileVisualizerType) {
@@ -894,11 +957,19 @@
                 }
             }
 
-            value = SystemProperties.getBoolean(
-                    HardwareRenderer.DEBUG_SHOW_OVERDRAW_PROPERTY, false);
-            if (value != mShowOverdraw) {
+            String overdraw = SystemProperties.get(HardwareRenderer.DEBUG_OVERDRAW_PROPERTY);
+            int debugOverdraw = search(OVERDRAW, overdraw);
+            if (debugOverdraw != mDebugOverdraw) {
                 changed = true;
-                mShowOverdraw = value;
+                mDebugOverdraw = debugOverdraw;
+
+                if (mDebugOverdraw != OVERDRAW_TYPE_COUNT) {
+                    if (mDebugOverdrawLayer != null) {
+                        mDebugOverdrawLayer.destroy();
+                        mDebugOverdrawLayer = null;
+                        mDebugOverdrawPaint = null;
+                    }
+                }
             }
 
             if (nLoadProperties()) {
@@ -908,6 +979,13 @@
             return changed;
         }
 
+        private static int search(String[] values, String value) {
+            for (int i = 0; i < values.length; i++) {
+                if (values[i].equals(value)) return i;
+            }
+            return -1;
+        }
+
         @Override
         void dumpGfxInfo(PrintWriter pw) {
             if (mProfileEnabled) {
@@ -968,15 +1046,15 @@
             if (fallback) {
                 // we'll try again if it was context lost
                 setRequested(false);
-                Log.w(LOG_TAG, "Mountain View, we've had a problem here. " 
+                Log.w(LOG_TAG, "Mountain View, we've had a problem here. "
                         + "Switching back to software rendering.");
             }
         }
 
         @Override
-        boolean initialize(Surface surface) throws Surface.OutOfResourcesException {
+        boolean initialize(Surface surface) throws OutOfResourcesException {
             if (isRequested() && !isEnabled()) {
-                initializeEgl();
+                boolean contextCreated = initializeEgl();
                 mGl = createEglSurface(surface);
                 mDestroyed = false;
 
@@ -991,6 +1069,10 @@
                             mCanvas.setName(mName);
                         }
                         setEnabled(true);
+
+                        if (contextCreated) {
+                            initAtlas();
+                        }
                     }
 
                     return mCanvas != null;
@@ -998,9 +1080,9 @@
             }
             return false;
         }
-        
+
         @Override
-        void updateSurface(Surface surface) throws Surface.OutOfResourcesException {
+        void updateSurface(Surface surface) throws OutOfResourcesException {
             if (isRequested() && isEnabled()) {
                 createEglSurface(surface);
             }
@@ -1010,19 +1092,19 @@
 
         abstract int[] getConfig(boolean dirtyRegions);
 
-        void initializeEgl() {
+        boolean initializeEgl() {
             synchronized (sEglLock) {
                 if (sEgl == null && sEglConfig == null) {
                     sEgl = (EGL10) EGLContext.getEGL();
-                    
+
                     // Get to the default display.
                     sEglDisplay = sEgl.eglGetDisplay(EGL_DEFAULT_DISPLAY);
-                    
+
                     if (sEglDisplay == EGL_NO_DISPLAY) {
                         throw new RuntimeException("eglGetDisplay failed "
                                 + GLUtils.getEGLErrorString(sEgl.eglGetError()));
                     }
-                    
+
                     // We can now initialize EGL for that display
                     int[] version = new int[2];
                     if (!sEgl.eglInitialize(sEglDisplay, version)) {
@@ -1043,7 +1125,10 @@
             if (mEglContext == null) {
                 mEglContext = createContext(sEgl, sEglDisplay, sEglConfig);
                 sEglContextStorage.set(createManagedContext(mEglContext));
+                return true;
             }
+
+            return false;
         }
 
         private EGLConfig loadEglConfig() {
@@ -1133,7 +1218,7 @@
             Log.d(LOG_TAG, "  CONFIG_CAVEAT = 0x" + Integer.toHexString(value[0]));
         }
 
-        GL createEglSurface(Surface surface) throws Surface.OutOfResourcesException {
+        GL createEglSurface(Surface surface) throws OutOfResourcesException {
             // Check preconditions.
             if (sEgl == null) {
                 throw new RuntimeException("egl not initialized");
@@ -1145,7 +1230,7 @@
                 throw new RuntimeException("eglConfig not initialized");
             }
             if (Thread.currentThread() != mEglThread) {
-                throw new IllegalStateException("HardwareRenderer cannot be used " 
+                throw new IllegalStateException("HardwareRenderer cannot be used "
                         + "from multiple threads");
             }
 
@@ -1181,6 +1266,7 @@
         }
 
         abstract void initCaches();
+        abstract void initAtlas();
 
         EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) {
             int[] attribs = { EGL14.EGL_CONTEXT_CLIENT_VERSION, mGlVersion, EGL_NONE };
@@ -1193,6 +1279,7 @@
                         "Could not create an EGL context. eglCreateContext failed with error: " +
                         GLUtils.getEGLErrorString(sEgl.eglGetError()));
             }
+
             return context;
         }
 
@@ -1216,7 +1303,10 @@
 
         void destroySurface() {
             if (mEglSurface != null && mEglSurface != EGL_NO_SURFACE) {
-                sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+                if (mEglSurface.equals(sEgl.eglGetCurrentSurface(EGL_DRAW))) {
+                    sEgl.eglMakeCurrent(sEglDisplay,
+                            EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+                }
                 sEgl.eglDestroySurface(sEglDisplay, mEglSurface);
                 mEglSurface = null;
             }
@@ -1272,7 +1362,7 @@
 
         @Override
         boolean validate() {
-            return checkCurrent() != SURFACE_STATE_ERROR;
+            return checkRenderContext() != SURFACE_STATE_ERROR;
         }
 
         @Override
@@ -1306,8 +1396,8 @@
 
         boolean canDraw() {
             return mGl != null && mCanvas != null;
-        }        
-        
+        }
+
         int onPreDraw(Rect dirty) {
             return DisplayList.STATUS_DONE;
         }
@@ -1325,8 +1415,7 @@
                     return;
                 }
 
-                final int surfaceState = checkCurrent();
-                if (surfaceState != SURFACE_STATE_ERROR) {
+                if (checkRenderContext() != SURFACE_STATE_ERROR) {
                     int status = mCanvas.invokeFunctors(mRedrawClip);
                     handleFunctorStatus(attachInfo, status);
                 }
@@ -1345,7 +1434,8 @@
 
                 view.mPrivateFlags |= View.PFLAG_DRAWN;
 
-                final int surfaceState = checkCurrent();
+                // We are already on the correct thread
+                final int surfaceState = checkRenderContextUnsafe();
                 if (surfaceState != SURFACE_STATE_ERROR) {
                     HardwareCanvas canvas = mCanvas;
                     attachInfo.mHardwareCanvas = canvas;
@@ -1358,9 +1448,17 @@
 
                     DisplayList displayList = buildDisplayList(view, canvas);
 
+                    // buildDisplayList() calls into user code which can cause
+                    // an eglMakeCurrent to happen with a different surface/context.
+                    // We must therefore check again here.
+                    if (checkRenderContextUnsafe() == SURFACE_STATE_ERROR) {
+                        return;
+                    }
+
                     int saveCount = 0;
                     int status = DisplayList.STATUS_DONE;
 
+                    long start = getSystemTime();
                     try {
                         status = prepareFrame(dirty);
 
@@ -1380,10 +1478,15 @@
                         canvas.restoreToCount(saveCount);
                         view.mRecreateDisplayList = false;
 
-                        mFrameCount++;
+                        mDrawDelta = getSystemTime() - start;
 
-                        debugDirtyRegions(dirty, canvas);
-                        drawProfileData(attachInfo);
+                        if (mDrawDelta > 0) {
+                            mFrameCount++;
+
+                            debugOverdraw(attachInfo, dirty, canvas, displayList);
+                            debugDirtyRegions(dirty, canvas);
+                            drawProfileData(attachInfo);
+                        }
                     }
 
                     onPostDraw();
@@ -1399,7 +1502,63 @@
             }
         }
 
+        abstract void countOverdraw(HardwareCanvas canvas);
+        abstract float getOverdraw(HardwareCanvas canvas);
+
+        private void debugOverdraw(View.AttachInfo attachInfo, Rect dirty,
+                HardwareCanvas canvas, DisplayList displayList) {
+
+            if (mDebugOverdraw == OVERDRAW_TYPE_COUNT) {
+                if (mDebugOverdrawLayer == null) {
+                    mDebugOverdrawLayer = createHardwareLayer(mWidth, mHeight, true);
+                } else if (mDebugOverdrawLayer.getWidth() != mWidth ||
+                        mDebugOverdrawLayer.getHeight() != mHeight) {
+                    mDebugOverdrawLayer.resize(mWidth, mHeight);
+                }
+
+                if (!mDebugOverdrawLayer.isValid()) {
+                    mDebugOverdraw = -1;
+                    return;
+                }
+
+                HardwareCanvas layerCanvas = mDebugOverdrawLayer.start(canvas, dirty);
+                countOverdraw(layerCanvas);
+                final int restoreCount = layerCanvas.save();
+                layerCanvas.drawDisplayList(displayList, null, DisplayList.FLAG_CLIP_CHILDREN);
+                layerCanvas.restoreToCount(restoreCount);
+                mDebugOverdrawLayer.end(canvas);
+
+                float overdraw = getOverdraw(layerCanvas);
+                DisplayMetrics metrics = attachInfo.mRootView.getResources().getDisplayMetrics();
+
+                drawOverdrawCounter(canvas, overdraw, metrics.density);
+            }
+        }
+
+        private void drawOverdrawCounter(HardwareCanvas canvas, float overdraw, float density) {
+            final String text = String.format("%.2fx", overdraw);
+            final Paint paint = setupPaint(density);
+            // HSBtoColor will clamp the values in the 0..1 range
+            paint.setColor(Color.HSBtoColor(0.28f - 0.28f * overdraw / 3.5f, 0.8f, 1.0f));
+
+            canvas.drawText(text, density * 4.0f, mHeight - paint.getFontMetrics().bottom, paint);
+        }
+
+        private Paint setupPaint(float density) {
+            if (mDebugOverdrawPaint == null) {
+                mDebugOverdrawPaint = new Paint();
+                mDebugOverdrawPaint.setAntiAlias(true);
+                mDebugOverdrawPaint.setShadowLayer(density * 3.0f, 0.0f, 0.0f, 0xff000000);
+                mDebugOverdrawPaint.setTextSize(density * 20.0f);
+            }
+            return mDebugOverdrawPaint;
+        }
+
         private DisplayList buildDisplayList(View view, HardwareCanvas canvas) {
+            if (mDrawDelta <= 0) {
+                return view.mDisplayList;
+            }
+
             view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED)
                     == View.PFLAG_INVALIDATED;
             view.mPrivateFlags &= ~View.PFLAG_INVALIDATED;
@@ -1572,21 +1731,39 @@
         }
 
         /**
-         * Ensures the current EGL context is the one we expect.
-         * 
+         * Ensures the current EGL context and surface are the ones we expect.
+         * This method throws an IllegalStateException if invoked from a thread
+         * that did not initialize EGL.
+         *
          * @return {@link #SURFACE_STATE_ERROR} if the correct EGL context cannot be made current,
          *         {@link #SURFACE_STATE_UPDATED} if the EGL context was changed or
          *         {@link #SURFACE_STATE_SUCCESS} if the EGL context was the correct one
+         *
+         * @see #checkRenderContextUnsafe()
          */
-        int checkCurrent() {
+        int checkRenderContext() {
             if (mEglThread != Thread.currentThread()) {
                 throw new IllegalStateException("Hardware acceleration can only be used with a " +
                         "single UI thread.\nOriginal thread: " + mEglThread + "\n" +
                         "Current thread: " + Thread.currentThread());
             }
 
-            if (!mEglContext.equals(sEgl.eglGetCurrentContext()) ||
-                    !mEglSurface.equals(sEgl.eglGetCurrentSurface(EGL_DRAW))) {
+            return checkRenderContextUnsafe();
+        }
+
+        /**
+         * Ensures the current EGL context and surface are the ones we expect.
+         * This method does not check the current thread.
+         *
+         * @return {@link #SURFACE_STATE_ERROR} if the correct EGL context cannot be made current,
+         *         {@link #SURFACE_STATE_UPDATED} if the EGL context was changed or
+         *         {@link #SURFACE_STATE_SUCCESS} if the EGL context was the correct one
+         *
+         * @see #checkRenderContext()
+         */
+        private int checkRenderContextUnsafe() {
+            if (!mEglSurface.equals(sEgl.eglGetCurrentSurface(EGL_DRAW)) ||
+                    !mEglContext.equals(sEgl.eglGetCurrentContext())) {
                 if (!sEgl.eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
                     Log.e(LOG_TAG, "eglMakeCurrent failed " +
                             GLUtils.getEGLErrorString(sEgl.eglGetError()));
@@ -1788,13 +1965,43 @@
 
         @Override
         void initCaches() {
-            GLES20Canvas.initCaches();
+            if (GLES20Canvas.initCaches()) {
+                // Caches were (re)initialized, rebind atlas
+                initAtlas();
+            }
+        }
+
+        @Override
+        void initAtlas() {
+            IBinder binder = ServiceManager.getService("assetatlas");
+            if (binder == null) return;
+
+            IAssetAtlas atlas = IAssetAtlas.Stub.asInterface(binder);
+            try {
+                if (atlas.isCompatible(android.os.Process.myPpid())) {
+                    GraphicBuffer buffer = atlas.getBuffer();
+                    if (buffer != null) {
+                        int[] map = atlas.getMap();
+                        if (map != null) {
+                            GLES20Canvas.initAtlas(buffer, map);
+                        }
+                        // If IAssetAtlas is not the same class as the IBinder
+                        // we are using a remote service and we can safely
+                        // destroy the graphic buffer
+                        if (atlas.getClass() != binder.getClass()) {
+                            buffer.destroy();
+                        }
+                    }
+                }
+            } catch (RemoteException e) {
+                Log.w(LOG_TAG, "Could not acquire atlas", e);
+            }
         }
 
         @Override
         boolean canDraw() {
             return super.canDraw() && mGlCanvas != null;
-        }                
+        }
 
         @Override
         int onPreDraw(Rect dirty) {
@@ -1970,6 +2177,16 @@
         }
 
         @Override
+        void cancelLayerUpdate(HardwareLayer layer) {
+            mGlCanvas.cancelLayerUpdate(layer);
+        }
+
+        @Override
+        void flushLayerUpdates() {
+            mGlCanvas.flushLayerUpdates();
+        }
+
+        @Override
         public DisplayList createDisplayList(String name) {
             return new GLES20DisplayList(name);
         }
@@ -1985,6 +2202,16 @@
         }
 
         @Override
+        void countOverdraw(HardwareCanvas canvas) {
+            ((GLES20Canvas) canvas).setCountOverdrawEnabled(true);
+        }
+
+        @Override
+        float getOverdraw(HardwareCanvas canvas) {
+            return ((GLES20Canvas) canvas).getOverdraw();
+        }
+
+        @Override
         public SurfaceTexture createSurfaceTexture(HardwareLayer layer) {
             return ((GLES20TextureLayer) layer).getSurfaceTexture();
         }
@@ -1996,8 +2223,7 @@
 
         @Override
         boolean safelyRun(Runnable action) {
-            boolean needsContext = true;
-            if (isEnabled() && checkCurrent() != SURFACE_STATE_ERROR) needsContext = false;
+            boolean needsContext = !isEnabled() || checkRenderContext() == SURFACE_STATE_ERROR;
 
             if (needsContext) {
                 Gl20RendererEglContext managedContext =
diff --git a/core/java/android/view/IApplicationToken.aidl b/core/java/android/view/IApplicationToken.aidl
index 5f0600f..633b40f 100644
--- a/core/java/android/view/IApplicationToken.aidl
+++ b/core/java/android/view/IApplicationToken.aidl
@@ -23,7 +23,7 @@
     void windowsDrawn();
     void windowsVisible();
     void windowsGone();
-    boolean keyDispatchingTimedOut();
+    boolean keyDispatchingTimedOut(String reason);
     long getKeyDispatchingTimeout();
 }
 
diff --git a/core/java/android/view/IAssetAtlas.aidl b/core/java/android/view/IAssetAtlas.aidl
new file mode 100644
index 0000000..5f1e238
--- /dev/null
+++ b/core/java/android/view/IAssetAtlas.aidl
@@ -0,0 +1,54 @@
+/**
+ * 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.view;
+
+import android.view.GraphicBuffer;
+
+/**
+ * Programming interface to the system assets atlas. This atlas, when
+ * present, holds preloaded drawable in a single, shareable graphics
+ * buffer. This allows multiple processes to share the same data to
+ * save up on memory.
+ *
+ * @hide
+ */
+interface IAssetAtlas {
+    /**
+     * Indicates whether the atlas is compatible with the specified
+     * parent process id. If the atlas' ppid does not match, this
+     * method will return false.
+     */
+    boolean isCompatible(int ppid);
+
+    /**
+     * Returns the atlas buffer (texture) or null if the atlas is
+     * not available yet.
+     */
+    GraphicBuffer getBuffer();
+
+    /**
+     * Returns the map of the bitmaps stored in the atlas or null
+     * if the atlas is not available yet.
+     *
+     * Each bitmap is represented by several entries in the array:
+     * int0: SkBitmap*, the native bitmap object
+     * int1: x position
+     * int2: y position
+     * int3: rotated, 1 if the bitmap must be rotated, 0 otherwise
+     */
+    int[] getMap();
+}
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 8ed4a86..aea2799c 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -71,17 +71,14 @@
 
     void setOverscan(int displayId, int left, int top, int right, int bottom);
 
-    // Is the device configured to have a full system bar for larger screens?
-    boolean hasSystemNavBar();
-
     // These can only be called when holding the MANAGE_APP_TOKENS permission.
     void pauseKeyDispatching(IBinder token);
     void resumeKeyDispatching(IBinder token);
     void setEventDispatching(boolean enabled);
     void addWindowToken(IBinder token, int type);
     void removeWindowToken(IBinder token);
-    void addAppToken(int addPos, IApplicationToken token,
-            int groupId, int requestedOrientation, boolean fullscreen, boolean showWhenLocked);
+    void addAppToken(int addPos, IApplicationToken token, int groupId, int stackId,
+            int requestedOrientation, boolean fullscreen, boolean showWhenLocked, int userId);
     void setAppGroupId(IBinder token, int groupId);
     void setAppOrientation(IApplicationToken token, int requestedOrientation);
     int getAppOrientation(IApplicationToken token);
@@ -97,15 +94,12 @@
     void executeAppTransition();
     void setAppStartingWindow(IBinder token, String pkg, int theme,
             in CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes,
-            int icon, int windowFlags, IBinder transferFrom, boolean createIfNeeded);
+            int icon, int logo, int windowFlags, IBinder transferFrom, boolean createIfNeeded);
     void setAppWillBeHidden(IBinder token);
     void setAppVisibility(IBinder token, boolean visible);
     void startAppFreezingScreen(IBinder token, int configChanges);
     void stopAppFreezingScreen(IBinder token, boolean force);
     void removeAppToken(IBinder token);
-    void moveAppToken(int index, IBinder token);
-    void moveAppTokensToTop(in List<IBinder> tokens);
-    void moveAppTokensToBottom(in List<IBinder> tokens);
 
     // Re-evaluate the current orientation from the caller's state.
     // If there is a change, the new Configuration is returned and the
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index 2a761c1..e829116 100644
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -44,13 +44,17 @@
 public final class InputDevice implements Parcelable {
     private final int mId;
     private final int mGeneration;
+    private final int mControllerNumber;
     private final String mName;
+    private final int mVendorId;
+    private final int mProductId;
     private final String mDescriptor;
     private final boolean mIsExternal;
     private final int mSources;
     private final int mKeyboardType;
     private final KeyCharacterMap mKeyCharacterMap;
     private final boolean mHasVibrator;
+    private final boolean mHasButtonUnderPad;
     private final ArrayList<MotionRange> mMotionRanges = new ArrayList<MotionRange>();
 
     private Vibrator mVibrator; // guarded by mMotionRanges during initialization
@@ -341,30 +345,38 @@
     };
 
     // Called by native code.
-    private InputDevice(int id, int generation, String name, String descriptor,
-            boolean isExternal, int sources,
-            int keyboardType, KeyCharacterMap keyCharacterMap, boolean hasVibrator) {
+    private InputDevice(int id, int generation, int controllerNumber, String name, int vendorId,
+            int productId, String descriptor, boolean isExternal, int sources, int keyboardType,
+            KeyCharacterMap keyCharacterMap, boolean hasVibrator, boolean hasButtonUnderPad) {
         mId = id;
         mGeneration = generation;
+        mControllerNumber = controllerNumber;
         mName = name;
+        mVendorId = vendorId;
+        mProductId = productId;
         mDescriptor = descriptor;
         mIsExternal = isExternal;
         mSources = sources;
         mKeyboardType = keyboardType;
         mKeyCharacterMap = keyCharacterMap;
         mHasVibrator = hasVibrator;
+        mHasButtonUnderPad = hasButtonUnderPad;
     }
 
     private InputDevice(Parcel in) {
         mId = in.readInt();
         mGeneration = in.readInt();
+        mControllerNumber = in.readInt();
         mName = in.readString();
+        mVendorId = in.readInt();
+        mProductId = in.readInt();
         mDescriptor = in.readString();
         mIsExternal = in.readInt() != 0;
         mSources = in.readInt();
         mKeyboardType = in.readInt();
         mKeyCharacterMap = KeyCharacterMap.CREATOR.createFromParcel(in);
         mHasVibrator = in.readInt() != 0;
+        mHasButtonUnderPad = in.readInt() != 0;
 
         for (;;) {
             int axis = in.readInt();
@@ -410,6 +422,25 @@
     }
 
     /**
+     * The controller number for a given input device.
+     * <p>
+     * Each gamepad or joystick is given a unique, positive controller number when initially
+     * configured by the system. This number may change due to events such as device disconnects /
+     * reconnects or user initiated reassignment. Any change in number will trigger an event that
+     * can be observed by registering an {@link InputManager.InputDeviceListener}.
+     * </p>
+     * <p>
+     * All input devices which are not gamepads or joysticks will be assigned a controller number
+     * of 0.
+     * </p>
+     *
+     * @return The controller number of the device.
+     */
+    public int getControllerNumber() {
+        return mControllerNumber;
+    }
+
+    /**
      * Gets a generation number for this input device.
      * The generation number is incremented whenever the device is reconfigured and its
      * properties may have changed.
@@ -423,6 +454,33 @@
     }
 
     /**
+     * Gets the vendor id for the given device, if available.
+     * <p>
+     * A vendor id uniquely identifies the company who manufactured the device. A value of 0 will
+     * be assigned where a vendor id is not available.
+     * </p>
+     *
+     * @return The vendor id of a given device
+     */
+    public int getVendorId() {
+        return mVendorId;
+    }
+
+    /**
+     * Gets the product id for the given device, if available.
+     * <p>
+     * A product id uniquely identifies which product within the address space of a given vendor,
+     * identified by the device's vendor id. A value of 0 will be assigned where a product id is
+     * not available.
+     * </p>
+     *
+     * @return The product id of a given device
+     */
+    public int getProductId() {
+        return mProductId;
+    }
+
+    /**
      * Gets the input device descriptor, which is a stable identifier for an input device.
      * <p>
      * An input device descriptor uniquely identifies an input device.  Its value
@@ -521,6 +579,16 @@
     }
 
     /**
+     * Gets whether the device is capable of producing the list of keycodes.
+     * @param keys The list of android keycodes to check for.
+     * @return An array of booleans where each member specifies whether the device is capable of
+     * generating the keycode given by the corresponding value at the same index in the keys array.
+     */
+    public boolean[] hasKeys(int... keys) {
+        return InputManager.getInstance().deviceHasKeys(mId, keys);
+    }
+
+    /**
      * Gets information about the range of values for a particular {@link MotionEvent} axis.
      * If the device supports multiple sources, the same axis may have different meanings
      * for each source.  Returns information about the first axis found for any source.
@@ -612,6 +680,15 @@
     }
 
     /**
+     * Reports whether the device has a button under its touchpad
+     * @return Whether the device has a button under its touchpad
+     * @hide
+     */
+    public boolean hasButtonUnderPad() {
+        return mHasButtonUnderPad;
+    }
+
+    /**
      * Provides information about the range of values for a particular {@link MotionEvent} axis.
      *
      * @see InputDevice#getMotionRange(int)
@@ -726,13 +803,17 @@
     public void writeToParcel(Parcel out, int flags) {
         out.writeInt(mId);
         out.writeInt(mGeneration);
+        out.writeInt(mControllerNumber);
         out.writeString(mName);
+        out.writeInt(mVendorId);
+        out.writeInt(mProductId);
         out.writeString(mDescriptor);
         out.writeInt(mIsExternal ? 1 : 0);
         out.writeInt(mSources);
         out.writeInt(mKeyboardType);
         mKeyCharacterMap.writeToParcel(out, flags);
         out.writeInt(mHasVibrator ? 1 : 0);
+        out.writeInt(mHasButtonUnderPad ? 1 : 0);
 
         final int numRanges = mMotionRanges.size();
         for (int i = 0; i < numRanges; i++) {
diff --git a/core/java/android/view/InputEvent.java b/core/java/android/view/InputEvent.java
index 07a937c..1ecdf30 100644
--- a/core/java/android/view/InputEvent.java
+++ b/core/java/android/view/InputEvent.java
@@ -70,6 +70,7 @@
      * Gets the source of the event.
      * 
      * @return The event source or {@link InputDevice#SOURCE_UNKNOWN} if unknown.
+     * @see InputDevice#getSources
      */
     public abstract int getSource();
 
diff --git a/core/java/android/view/InputFilter.java b/core/java/android/view/InputFilter.java
index c25b87b..4aba30c 100644
--- a/core/java/android/view/InputFilter.java
+++ b/core/java/android/view/InputFilter.java
@@ -40,7 +40,7 @@
  * <li>Input events are then asynchronously delivered to the input filter's
  * {@link #onInputEvent(InputEvent)} method instead of being enqueued for dispatch to
  * applications as usual.  The input filter only receives input events that were
- * generated by input device; the input filter will not receive input events that were
+ * generated by an input device; the input filter will not receive input events that were
  * injected into the system by other means, such as by instrumentation.</li>
  * <li>The input filter processes and optionally transforms the stream of events.  For example,
  * it may transform a sequence of motion events representing an accessibility gesture into
@@ -68,7 +68,7 @@
  * The input filter must take into account the fact that the input events coming from different
  * devices or even different sources all consist of distinct streams of input.
  * Use {@link InputEvent#getDeviceId()} and {@link InputEvent#getSource()} to identify
- * the source of the event and its semantics.  There are be multiple sources of keys,
+ * the source of the event and its semantics.  There may be multiple sources of keys,
  * touches and other input: they must be kept separate.
  * </p>
  * <h3>Policy flags</h3>
@@ -88,7 +88,7 @@
  * The input filter should clear its internal state about the gesture and then send key or
  * motion events to the dispatcher to cancel any keys or pointers that are down.
  * </p><p>
- * Corollary: Events that set sent to the dispatcher should usually include the
+ * Corollary: Events that get sent to the dispatcher should usually include the
  * {@link WindowManagerPolicy#FLAG_PASS_TO_USER} flag.  Otherwise, they will be dropped!
  * </p><p>
  * It may be prudent to disable automatic key repeating for synthetic key events
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 5db3909..5a5fc10 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -629,8 +629,11 @@
     /** Key code constant: Brightness Up key.
      * Adjusts the screen brightness up. */
     public static final int KEYCODE_BRIGHTNESS_UP   = 221;
+    /** Key code constant: Audio Track key
+     * Switches the audio tracks. */
+    public static final int KEYCODE_MEDIA_AUDIO_TRACK = 222;
 
-    private static final int LAST_KEYCODE           = KEYCODE_BRIGHTNESS_UP;
+    private static final int LAST_KEYCODE           = KEYCODE_MEDIA_AUDIO_TRACK;
 
     // NOTE: If you add a new keycode here you must also add it to:
     //  isSystem()
@@ -874,6 +877,7 @@
         names.append(KEYCODE_ASSIST, "KEYCODE_ASSIST");
         names.append(KEYCODE_BRIGHTNESS_DOWN, "KEYCODE_BRIGHTNESS_DOWN");
         names.append(KEYCODE_BRIGHTNESS_UP, "KEYCODE_BRIGHTNESS_UP");
+        names.append(KEYCODE_MEDIA_AUDIO_TRACK, "KEYCODE_MEDIA_AUDIO_TRACK");
     };
 
     // Symbolic names of all metakeys in bit order from least significant to most significant.
@@ -1833,6 +1837,19 @@
         }
     }
 
+    /** Whether key will, by default, trigger a click on the focused view.
+     * @hide
+     */
+    public static final boolean isConfirmKey(int keyCode) {
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_DPAD_CENTER:
+            case KeyEvent.KEYCODE_ENTER:
+                return true;
+            default:
+                return false;
+        }
+    }
+
     /** {@inheritDoc} */
     @Override
     public final int getDeviceId() {
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index ee36097..db577f3 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -3003,13 +3003,13 @@
     }
 
     /**
-     * Returns a string that represents the symbolic name of the specified action
+     * Returns a string that represents the symbolic name of the specified unmasked action
      * such as "ACTION_DOWN", "ACTION_POINTER_DOWN(3)" or an equivalent numeric constant
      * such as "35" if unknown.
      *
-     * @param action The action.
+     * @param action The unmasked action.
      * @return The symbolic name of the specified action.
-     * @hide
+     * @see #getAction()
      */
     public static String actionToString(int action) {
         switch (action) {
@@ -3047,7 +3047,7 @@
      * Returns a string that represents the symbolic name of the specified axis
      * such as "AXIS_X" or an equivalent numeric constant such as "42" if unknown.
      *
-     * @param axis The axis
+     * @param axis The axis.
      * @return The symbolic name of the specified axis.
      */
     public static String axisToString(int axis) {
@@ -3061,7 +3061,7 @@
      *
      * @param symbolicName The symbolic name of the axis.
      * @return The axis or -1 if not found.
-     * @see KeyEvent#keycodeToString(int)
+     * @see KeyEvent#keyCodeToString(int)
      */
     public static int axisFromString(String symbolicName) {
         if (symbolicName == null) {
diff --git a/core/java/android/view/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java
index 51c5c7b..a0d39ca 100644
--- a/core/java/android/view/ScaleGestureDetector.java
+++ b/core/java/android/view/ScaleGestureDetector.java
@@ -18,6 +18,8 @@
 
 import android.content.Context;
 import android.content.res.Resources;
+import android.os.Build;
+import android.os.Handler;
 import android.os.SystemClock;
 import android.util.FloatMath;
 
@@ -128,6 +130,8 @@
     private float mFocusX;
     private float mFocusY;
 
+    private boolean mDoubleTapScales;
+
     private float mCurrSpan;
     private float mPrevSpan;
     private float mInitialSpan;
@@ -148,9 +152,15 @@
     private int mTouchHistoryDirection;
     private long mTouchHistoryLastAcceptedTime;
     private int mTouchMinMajor;
+    private MotionEvent mDoubleTapEvent;
+    private int mDoubleTapMode = DOUBLE_TAP_MODE_NONE;
+    private final Handler mHandler;
 
     private static final long TOUCH_STABILIZE_TIME = 128; // ms
-    private static final int TOUCH_MIN_MAJOR = 48; // dp
+    private static final int DOUBLE_TAP_MODE_NONE = 0;
+    private static final int DOUBLE_TAP_MODE_IN_PROGRESS = 1;
+    private static final float SCALE_FACTOR = .5f;
+
 
     /**
      * Consistency verifier for debugging purposes.
@@ -158,8 +168,37 @@
     private final InputEventConsistencyVerifier mInputEventConsistencyVerifier =
             InputEventConsistencyVerifier.isInstrumentationEnabled() ?
                     new InputEventConsistencyVerifier(this, 0) : null;
+    private GestureDetector mGestureDetector;
 
+    private boolean mEventBeforeOrAboveStartingGestureEvent;
+
+    /**
+     * Creates a ScaleGestureDetector with the supplied listener.
+     * You may only use this constructor from a {@link android.os.Looper Looper} thread.
+     *
+     * @param context the application's context
+     * @param listener the listener invoked for all the callbacks, this must
+     * not be null.
+     *
+     * @throws NullPointerException if {@code listener} is null.
+     */
     public ScaleGestureDetector(Context context, OnScaleGestureListener listener) {
+        this(context, listener, null);
+    }
+
+    /**
+     * Creates a ScaleGestureDetector with the supplied listener.
+     * @see android.os.Handler#Handler()
+     *
+     * @param context the application's context
+     * @param listener the listener invoked for all the callbacks, this must
+     * not be null.
+     * @param handler the handler to use for running deferred listener events.
+     *
+     * @throws NullPointerException if {@code listener} is null.
+     */
+    public ScaleGestureDetector(Context context, OnScaleGestureListener listener,
+                                Handler handler) {
         mContext = context;
         mListener = listener;
         mSpanSlop = ViewConfiguration.get(context).getScaledTouchSlop() * 2;
@@ -167,8 +206,12 @@
         final Resources res = context.getResources();
         mTouchMinMajor = res.getDimensionPixelSize(
                 com.android.internal.R.dimen.config_minScalingTouchMajor);
-        mMinSpan = res.getDimensionPixelSize(
-                com.android.internal.R.dimen.config_minScalingSpan);
+        mMinSpan = res.getDimensionPixelSize(com.android.internal.R.dimen.config_minScalingSpan);
+        mHandler = handler;
+        // Quick scale is enabled by default after JB_MR2
+        if (context.getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.JELLY_BEAN_MR2) {
+            setQuickScaleEnabled(true);
+        }
     }
 
     /**
@@ -263,8 +306,14 @@
 
         final int action = event.getActionMasked();
 
+        // Forward the event to check for double tap gesture
+        if (mDoubleTapScales) {
+            mGestureDetector.onTouchEvent(event);
+        }
+
         final boolean streamComplete = action == MotionEvent.ACTION_UP ||
                 action == MotionEvent.ACTION_CANCEL;
+
         if (action == MotionEvent.ACTION_DOWN || streamComplete) {
             // Reset any scale in progress with the listener.
             // If it's an ACTION_DOWN we're beginning a new event stream.
@@ -273,6 +322,7 @@
                 mListener.onScaleEnd(this);
                 mInProgress = false;
                 mInitialSpan = 0;
+                mDoubleTapMode = DOUBLE_TAP_MODE_NONE;
             }
 
             if (streamComplete) {
@@ -284,21 +334,37 @@
         final boolean configChanged = action == MotionEvent.ACTION_DOWN ||
                 action == MotionEvent.ACTION_POINTER_UP ||
                 action == MotionEvent.ACTION_POINTER_DOWN;
+
+
         final boolean pointerUp = action == MotionEvent.ACTION_POINTER_UP;
         final int skipIndex = pointerUp ? event.getActionIndex() : -1;
 
         // Determine focal point
         float sumX = 0, sumY = 0;
         final int count = event.getPointerCount();
-        for (int i = 0; i < count; i++) {
-            if (skipIndex == i) continue;
-            sumX += event.getX(i);
-            sumY += event.getY(i);
-        }
         final int div = pointerUp ? count - 1 : count;
-        final float focusX = sumX / div;
-        final float focusY = sumY / div;
+        final float focusX;
+        final float focusY;
+        if (mDoubleTapMode == DOUBLE_TAP_MODE_IN_PROGRESS) {
+            // In double tap mode, the focal pt is always where the double tap
+            // gesture started
+            focusX = mDoubleTapEvent.getX();
+            focusY = mDoubleTapEvent.getY();
+            if (event.getY() < focusY) {
+                mEventBeforeOrAboveStartingGestureEvent = true;
+            } else {
+                mEventBeforeOrAboveStartingGestureEvent = false;
+            }
+        } else {
+            for (int i = 0; i < count; i++) {
+                if (skipIndex == i) continue;
+                sumX += event.getX(i);
+                sumY += event.getY(i);
+            }
 
+            focusX = sumX / div;
+            focusY = sumY / div;
+        }
 
         addTouchHistory(event);
 
@@ -320,7 +386,12 @@
         // the focal point.
         final float spanX = devX * 2;
         final float spanY = devY * 2;
-        final float span = FloatMath.sqrt(spanX * spanX + spanY * spanY);
+        final float span;
+        if (inDoubleTapMode()) {
+            span = spanY;
+        } else {
+            span = FloatMath.sqrt(spanX * spanX + spanY * spanY);
+        }
 
         // Dispatch begin/end events as needed.
         // If the configuration changes, notify the app to reset its current state by beginning
@@ -328,17 +399,20 @@
         final boolean wasInProgress = mInProgress;
         mFocusX = focusX;
         mFocusY = focusY;
-        if (mInProgress && (span < mMinSpan || configChanged)) {
+        if (!inDoubleTapMode() && mInProgress && (span < mMinSpan || configChanged)) {
             mListener.onScaleEnd(this);
             mInProgress = false;
             mInitialSpan = span;
+            mDoubleTapMode = DOUBLE_TAP_MODE_NONE;
         }
         if (configChanged) {
             mPrevSpanX = mCurrSpanX = spanX;
             mPrevSpanY = mCurrSpanY = spanY;
             mInitialSpan = mPrevSpan = mCurrSpan = span;
         }
-        if (!mInProgress && span >= mMinSpan &&
+
+        final int minSpan = inDoubleTapMode() ? mSpanSlop : mMinSpan;
+        if (!mInProgress && span >=  minSpan &&
                 (wasInProgress || Math.abs(span - mInitialSpan) > mSpanSlop)) {
             mPrevSpanX = mCurrSpanX = spanX;
             mPrevSpanY = mCurrSpanY = spanY;
@@ -354,6 +428,7 @@
             mCurrSpan = span;
 
             boolean updatePrev = true;
+
             if (mInProgress) {
                 updatePrev = mListener.onScale(this);
             }
@@ -369,6 +444,34 @@
         return true;
     }
 
+
+    private boolean inDoubleTapMode() {
+        return mDoubleTapMode == DOUBLE_TAP_MODE_IN_PROGRESS;
+    }
+
+    /**
+     * Set whether the associated {@link OnScaleGestureListener} should receive onScale callbacks
+     * when the user performs a doubleTap followed by a swipe. Note that this is enabled by default
+     * if the app targets API 19 and newer.
+     * @param scales true to enable quick scaling, false to disable
+     */
+    public void setQuickScaleEnabled(boolean scales) {
+        mDoubleTapScales = scales;
+        if (mDoubleTapScales && mGestureDetector == null) {
+            GestureDetector.SimpleOnGestureListener gestureListener =
+                    new GestureDetector.SimpleOnGestureListener() {
+                        @Override
+                        public boolean onDoubleTap(MotionEvent e) {
+                            // Double tap: start watching for a swipe
+                            mDoubleTapEvent = e;
+                            mDoubleTapMode = DOUBLE_TAP_MODE_IN_PROGRESS;
+                            return true;
+                        }
+                    };
+            mGestureDetector = new GestureDetector(mContext, gestureListener, mHandler);
+        }
+    }
+
     /**
      * Returns {@code true} if a scale gesture is in progress.
      */
@@ -472,6 +575,16 @@
      * @return The current scaling factor.
      */
     public float getScaleFactor() {
+        if (inDoubleTapMode()) {
+            // Drag is moving up; the further away from the gesture
+            // start, the smaller the span should be, the closer,
+            // the larger the span, and therefore the larger the scale
+            final boolean scaleUp =
+                    (mEventBeforeOrAboveStartingGestureEvent && (mCurrSpan < mPrevSpan)) ||
+                    (!mEventBeforeOrAboveStartingGestureEvent && (mCurrSpan > mPrevSpan));
+            final float spanDiff = (Math.abs(1 - (mCurrSpan / mPrevSpan)) * SCALE_FACTOR);
+            return mPrevSpan <= 0 ? 1 : scaleUp ? (1 + spanDiff) : (1 - spanDiff);
+        }
         return mPrevSpan > 0 ? mCurrSpan / mPrevSpan : 1;
     }
 
@@ -493,4 +606,4 @@
     public long getEventTime() {
         return mCurrTime;
     }
-}
+}
\ No newline at end of file
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index ae4005b..1bfda2d 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -36,7 +36,7 @@
             throws OutOfResourcesException;
     private static native int nativeCreateFromSurfaceControl(int surfaceControlNativeObject);
 
-    private static native void nativeLockCanvas(int nativeObject, Canvas canvas, Rect dirty)
+    private static native int nativeLockCanvas(int nativeObject, Canvas canvas, Rect dirty)
             throws OutOfResourcesException;
     private static native void nativeUnlockCanvasAndPost(int nativeObject, Canvas canvas);
 
@@ -71,8 +71,9 @@
     // Guarded state.
     final Object mLock = new Object(); // protects the native state
     private String mName;
-    int mNativeSurface; // package scope only for SurfaceControl access
-    private int mGenerationId; // incremented each time mNativeSurface changes
+    int mNativeObject; // package scope only for SurfaceControl access
+    private int mLockedObject;
+    private int mGenerationId; // incremented each time mNativeObject changes
     private final Canvas mCanvas = new CompatibleCanvas();
 
     // A matrix to scale the matrix set by application. This is set to null for
@@ -115,6 +116,7 @@
      *
      * @param surfaceTexture The {@link SurfaceTexture} that is updated by this
      * Surface.
+     * @throws OutOfResourcesException if the surface could not be created.
      */
     public Surface(SurfaceTexture surfaceTexture) {
         if (surfaceTexture == null) {
@@ -123,12 +125,7 @@
 
         synchronized (mLock) {
             mName = surfaceTexture.toString();
-            try {
-                setNativeObjectLocked(nativeCreateFromSurfaceTexture(surfaceTexture));
-            } catch (OutOfResourcesException ex) {
-                // We can't throw OutOfResourcesException because it would be an API change.
-                throw new RuntimeException(ex);
-            }
+            setNativeObjectLocked(nativeCreateFromSurfaceTexture(surfaceTexture));
         }
     }
 
@@ -158,8 +155,8 @@
      */
     public void release() {
         synchronized (mLock) {
-            if (mNativeSurface != 0) {
-                nativeRelease(mNativeSurface);
+            if (mNativeObject != 0) {
+                nativeRelease(mNativeObject);
                 setNativeObjectLocked(0);
             }
         }
@@ -183,8 +180,8 @@
      */
     public boolean isValid() {
         synchronized (mLock) {
-            if (mNativeSurface == 0) return false;
-            return nativeIsValid(mNativeSurface);
+            if (mNativeObject == 0) return false;
+            return nativeIsValid(mNativeObject);
         }
     }
 
@@ -210,7 +207,7 @@
     public boolean isConsumerRunningBehind() {
         synchronized (mLock) {
             checkNotReleasedLocked();
-            return nativeIsConsumerRunningBehind(mNativeSurface);
+            return nativeIsConsumerRunningBehind(mNativeObject);
         }
     }
 
@@ -228,12 +225,22 @@
      * The caller may also pass <code>null</code> instead, in the case where the
      * entire surface should be redrawn.
      * @return A canvas for drawing into the surface.
+     *
+     * @throws IllegalArgumentException If the inOutDirty rectangle is not valid.
+     * @throws OutOfResourcesException If the canvas cannot be locked.
      */
     public Canvas lockCanvas(Rect inOutDirty)
-            throws OutOfResourcesException, IllegalArgumentException {
+            throws Surface.OutOfResourcesException, IllegalArgumentException {
         synchronized (mLock) {
             checkNotReleasedLocked();
-            nativeLockCanvas(mNativeSurface, mCanvas, inOutDirty);
+            if (mLockedObject != 0) {
+                // Ideally, nativeLockCanvas() would throw in this situation and prevent the
+                // double-lock, but that won't happen if mNativeObject was updated.  We can't
+                // abandon the old mLockedObject because it might still be in use, so instead
+                // we just refuse to re-lock the Surface.
+                throw new IllegalStateException("Surface was already locked");
+            }
+            mLockedObject = nativeLockCanvas(mNativeObject, mCanvas, inOutDirty);
             return mCanvas;
         }
     }
@@ -252,11 +259,21 @@
 
         synchronized (mLock) {
             checkNotReleasedLocked();
-            nativeUnlockCanvasAndPost(mNativeSurface, canvas);
+            if (mNativeObject != mLockedObject) {
+                Log.w(TAG, "WARNING: Surface's mNativeObject (0x" +
+                        Integer.toHexString(mNativeObject) + ") != mLockedObject (0x" +
+                        Integer.toHexString(mLockedObject) +")");
+            }
+            if (mLockedObject == 0) {
+                throw new IllegalStateException("Surface was not locked");
+            }
+            nativeUnlockCanvasAndPost(mLockedObject, canvas);
+            nativeRelease(mLockedObject);
+            mLockedObject = 0;
         }
     }
 
-    /** 
+    /**
      * @deprecated This API has been removed and is not supported.  Do not use.
      */
     @Deprecated
@@ -298,8 +315,8 @@
         int newNativeObject = nativeCreateFromSurfaceControl(surfaceControlPtr);
 
         synchronized (mLock) {
-            if (mNativeSurface != 0) {
-                nativeRelease(mNativeSurface);
+            if (mNativeObject != 0) {
+                nativeRelease(mNativeObject);
             }
             setNativeObjectLocked(newNativeObject);
         }
@@ -319,13 +336,13 @@
         if (other != this) {
             final int newPtr;
             synchronized (other.mLock) {
-                newPtr = other.mNativeSurface;
+                newPtr = other.mNativeObject;
                 other.setNativeObjectLocked(0);
             }
 
             synchronized (mLock) {
-                if (mNativeSurface != 0) {
-                    nativeRelease(mNativeSurface);
+                if (mNativeObject != 0) {
+                    nativeRelease(mNativeObject);
                 }
                 setNativeObjectLocked(newPtr);
             }
@@ -343,8 +360,12 @@
         }
 
         synchronized (mLock) {
+            // nativeReadFromParcel() will either return mNativeObject, or
+            // create a new native Surface and return it after reducing
+            // the reference count on mNativeObject.  Either way, it is
+            // not necessary to call nativeRelease() here.
             mName = source.readString();
-            setNativeObjectLocked(nativeReadFromParcel(mNativeSurface, source));
+            setNativeObjectLocked(nativeReadFromParcel(mNativeObject, source));
         }
     }
 
@@ -355,7 +376,7 @@
         }
         synchronized (mLock) {
             dest.writeString(mName);
-            nativeWriteToParcel(mNativeSurface, dest);
+            nativeWriteToParcel(mNativeObject, dest);
         }
         if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) {
             release();
@@ -365,32 +386,35 @@
     @Override
     public String toString() {
         synchronized (mLock) {
-            return "Surface(name=" + mName + ")";
+            return "Surface(name=" + mName + ")/@0x" +
+                    Integer.toHexString(System.identityHashCode(this));
         }
     }
 
     private void setNativeObjectLocked(int ptr) {
-        if (mNativeSurface != ptr) {
-            if (mNativeSurface == 0 && ptr != 0) {
+        if (mNativeObject != ptr) {
+            if (mNativeObject == 0 && ptr != 0) {
                 mCloseGuard.open("release");
-            } else if (mNativeSurface != 0 && ptr == 0) {
+            } else if (mNativeObject != 0 && ptr == 0) {
                 mCloseGuard.close();
             }
-            mNativeSurface = ptr;
+            mNativeObject = ptr;
             mGenerationId += 1;
         }
     }
 
     private void checkNotReleasedLocked() {
-        if (mNativeSurface == 0) {
+        if (mNativeObject == 0) {
             throw new IllegalStateException("Surface has already been released.");
         }
     }
 
     /**
-     * Exception thrown when a surface couldn't be created or resized.
+     * Exception thrown when a Canvas couldn't be locked with {@link Surface#lockCanvas}, or
+     * when a SurfaceTexture could not successfully be allocated.
      */
-    public static class OutOfResourcesException extends Exception {
+    @SuppressWarnings("serial")
+    public static class OutOfResourcesException extends RuntimeException {
         public OutOfResourcesException() {
         }
         public OutOfResourcesException(String name) {
@@ -463,7 +487,7 @@
         public void getMatrix(Matrix m) {
             super.getMatrix(m);
             if (mOrigMatrix == null) {
-                mOrigMatrix = new Matrix(); 
+                mOrigMatrix = new Matrix();
             }
             mOrigMatrix.set(m);
         }
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index c6da84f..b22d5cf 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -24,6 +24,7 @@
 import android.os.IBinder;
 import android.os.SystemProperties;
 import android.util.Log;
+import android.view.Surface.OutOfResourcesException;
 
 /**
  * SurfaceControl
@@ -59,13 +60,14 @@
 
     private static native IBinder nativeGetBuiltInDisplay(int physicalDisplayId);
     private static native IBinder nativeCreateDisplay(String name, boolean secure);
+    private static native void nativeDestroyDisplay(IBinder displayToken);
     private static native void nativeSetDisplaySurface(
             IBinder displayToken, int nativeSurfaceObject);
     private static native void nativeSetDisplayLayerStack(
             IBinder displayToken, int layerStack);
     private static native void nativeSetDisplayProjection(
             IBinder displayToken, int orientation,
-            int l, int t, int r, int b, 
+            int l, int t, int r, int b,
             int L, int T, int R, int B);
     private static native boolean nativeGetDisplayInfo(
             IBinder displayToken, SurfaceControl.PhysicalDisplayInfo outInfo);
@@ -74,23 +76,12 @@
 
 
     private final CloseGuard mCloseGuard = CloseGuard.get();
-    private String mName;
+    private final String mName;
     int mNativeObject; // package visibility only for Surface.java access
 
     private static final boolean HEADLESS = "1".equals(
         SystemProperties.get("ro.config.headless", "0"));
 
-    /**
-     * Exception thrown when a surface couldn't be created or resized.
-     */
-    public static class OutOfResourcesException extends Exception {
-        public OutOfResourcesException() {
-        }
-        public OutOfResourcesException(String name) {
-            super(name);
-        }
-    }
-
     /* flags used in constructor (keep in sync with ISurfaceComposerClient.h) */
 
     /**
@@ -103,7 +94,7 @@
      * measures will be taken to disallow the surface's content to be copied
      * from another process. In particular, screenshots and VNC servers will
      * be disabled, but other measures can take place, for instance the
-     * surface might not be hardware accelerated. 
+     * surface might not be hardware accelerated.
      *
      */
     public static final int SECURE = 0x00000080;
@@ -219,6 +210,8 @@
      * @param h The surface initial height.
      * @param flags The surface creation flags.  Should always include {@link #HIDDEN}
      * in the creation flags.
+     *
+     * @throws throws OutOfResourcesException If the SurfaceControl cannot be created.
      */
     public SurfaceControl(SurfaceSession session,
             String name, int w, int h, int format, int flags)
@@ -247,10 +240,10 @@
             throw new OutOfResourcesException(
                     "Couldn't allocate SurfaceControl native object");
         }
-        
+
         mCloseGuard.open("release");
     }
-    
+
     @Override
     protected void finalize() throws Throwable {
         try {
@@ -300,7 +293,7 @@
         if (mNativeObject == 0) throw new NullPointerException(
                 "mNativeObject is null. Have you called release() already?");
     }
-    
+
     /*
      * set surface parameters.
      * needs to be inside open/closeTransaction block
@@ -369,7 +362,7 @@
     public void setWindowCrop(Rect crop) {
         checkNotReleased();
         if (crop != null) {
-            nativeSetWindowCrop(mNativeObject, 
+            nativeSetWindowCrop(mNativeObject,
                 crop.left, crop.top, crop.right, crop.bottom);
         } else {
             nativeSetWindowCrop(mNativeObject, 0, 0, 0, 0);
@@ -397,19 +390,19 @@
         public float xDpi;
         public float yDpi;
         public boolean secure;
-    
+
         public PhysicalDisplayInfo() {
         }
-    
+
         public PhysicalDisplayInfo(PhysicalDisplayInfo other) {
             copyFrom(other);
         }
-    
+
         @Override
         public boolean equals(Object o) {
             return o instanceof PhysicalDisplayInfo && equals((PhysicalDisplayInfo)o);
         }
-    
+
         public boolean equals(PhysicalDisplayInfo other) {
             return other != null
                     && width == other.width
@@ -420,12 +413,12 @@
                     && yDpi == other.yDpi
                     && secure == other.secure;
         }
-    
+
         @Override
         public int hashCode() {
             return 0; // don't care
         }
-    
+
         public void copyFrom(PhysicalDisplayInfo other) {
             width = other.width;
             height = other.height;
@@ -435,7 +428,7 @@
             yDpi = other.yDpi;
             secure = other.secure;
         }
-    
+
         // For debugging purposes
         @Override
         public String toString() {
@@ -481,7 +474,7 @@
             throw new IllegalArgumentException("displayRect must not be null");
         }
         nativeSetDisplayProjection(displayToken, orientation,
-                layerStackRect.left, layerStackRect.top, layerStackRect.right, layerStackRect.bottom, 
+                layerStackRect.left, layerStackRect.top, layerStackRect.right, layerStackRect.bottom,
                 displayRect.left, displayRect.top, displayRect.right, displayRect.bottom);
     }
 
@@ -499,7 +492,7 @@
 
         if (surface != null) {
             synchronized (surface.mLock) {
-                nativeSetDisplaySurface(displayToken, surface.mNativeSurface);
+                nativeSetDisplaySurface(displayToken, surface.mNativeObject);
             }
         } else {
             nativeSetDisplaySurface(displayToken, 0);
@@ -513,6 +506,13 @@
         return nativeCreateDisplay(name, secure);
     }
 
+    public static void destroyDisplay(IBinder displayToken) {
+        if (displayToken == null) {
+            throw new IllegalArgumentException("displayToken must not be null");
+        }
+        nativeDestroyDisplay(displayToken);
+    }
+
     public static IBinder getBuiltInDisplay(int builtInDisplayId) {
         return nativeGetBuiltInDisplay(builtInDisplayId);
     }
@@ -608,7 +608,7 @@
                 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
         return nativeScreenshot(displayToken, width, height, 0, 0, true);
     }
-    
+
     private static void screenshot(IBinder display, Surface consumer,
             int width, int height, int minLayer, int maxLayer, boolean allLayers) {
         if (display == null) {
diff --git a/core/java/android/view/SurfaceHolder.java b/core/java/android/view/SurfaceHolder.java
index 015a78e..99fa2a4 100644
--- a/core/java/android/view/SurfaceHolder.java
+++ b/core/java/android/view/SurfaceHolder.java
@@ -277,9 +277,6 @@
      * 
      * <p>This method is intended to be used by frameworks which often need
      * direct access to the Surface object (usually to pass it to native code).
-     * When designing APIs always use SurfaceHolder to pass surfaces around
-     * as opposed to the Surface object itself. A rule of thumb is that
-     * application code should never have to call this method.
      * 
      * @return Surface The surface.
      */
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 793fb5e..1e4b29f 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -43,7 +43,7 @@
  * You can control the format of this surface and, if you like, its size; the
  * SurfaceView takes care of placing the surface at the correct location on the
  * screen
- * 
+ *
  * <p>The surface is Z ordered so that it is behind the window holding its
  * SurfaceView; the SurfaceView punches a hole in its window to allow its
  * surface to be displayed. The view hierarchy will take care of correctly
@@ -52,7 +52,7 @@
  * buttons on top of the Surface, though note however that it can have an
  * impact on performance since a full alpha-blended composite will be performed
  * each time the Surface changes.
- * 
+ *
  * <p> The transparent region that makes the surface visible is based on the
  * layout positions in the view hierarchy. If the post-layout transform
  * properties are used to draw a sibling view on top of the SurfaceView, the
@@ -60,16 +60,16 @@
  *
  * <p>Access to the underlying surface is provided via the SurfaceHolder interface,
  * which can be retrieved by calling {@link #getHolder}.
- * 
+ *
  * <p>The Surface will be created for you while the SurfaceView's window is
  * visible; you should implement {@link SurfaceHolder.Callback#surfaceCreated}
  * and {@link SurfaceHolder.Callback#surfaceDestroyed} to discover when the
  * Surface is created and destroyed as the window is shown and hidden.
- * 
+ *
  * <p>One of the purposes of this class is to provide a surface in which a
  * secondary thread can render into the screen. If you are going to use it
  * this way, you need to be aware of some threading semantics:
- * 
+ *
  * <ul>
  * <li> All SurfaceView and
  * {@link SurfaceHolder.Callback SurfaceHolder.Callback} methods will be called
@@ -91,7 +91,7 @@
             = new ArrayList<SurfaceHolder.Callback>();
 
     final int[] mLocation = new int[2];
-    
+
     final ReentrantLock mSurfaceLock = new ReentrantLock();
     final Surface mSurface = new Surface();       // Current surface in use
     final Surface mNewSurface = new Surface();    // New surface we are switching to
@@ -106,13 +106,13 @@
     final Rect mOverscanInsets = new Rect();
     final Rect mContentInsets = new Rect();
     final Configuration mConfiguration = new Configuration();
-    
+
     static final int KEEP_SCREEN_ON_MSG = 1;
     static final int GET_NEW_SURFACE_MSG = 2;
     static final int UPDATE_WINDOW_MSG = 3;
-    
+
     int mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
-    
+
     boolean mIsCreating = false;
 
     final Handler mHandler = new Handler() {
@@ -131,14 +131,15 @@
             }
         }
     };
-    
+
     final ViewTreeObserver.OnScrollChangedListener mScrollChangedListener
             = new ViewTreeObserver.OnScrollChangedListener() {
+                    @Override
                     public void onScrollChanged() {
                         updateWindow(false, false);
                     }
             };
-            
+
     boolean mRequestedVisible = false;
     boolean mWindowVisibility = false;
     boolean mViewVisibility = false;
@@ -152,7 +153,7 @@
     boolean mHaveFrame = false;
     boolean mSurfaceCreated = false;
     long mLastLockTime = 0;
-    
+
     boolean mVisible = false;
     int mLeft = -1;
     int mTop = -1;
@@ -160,7 +161,6 @@
     int mHeight = -1;
     int mFormat = -1;
     final Rect mSurfaceFrame = new Rect();
-    Rect mTmpDirty;
     int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1;
     boolean mUpdateWindowNeeded;
     boolean mReportDrawNeeded;
@@ -170,7 +170,7 @@
             new ViewTreeObserver.OnPreDrawListener() {
                 @Override
                 public boolean onPreDraw() {
-                    // reposition ourselves where the surface is 
+                    // reposition ourselves where the surface is
                     mHaveFrame = getWidth() > 0 && getHeight() > 0;
                     updateWindow(false, false);
                     return true;
@@ -182,7 +182,7 @@
         super(context);
         init();
     }
-    
+
     public SurfaceView(Context context, AttributeSet attrs) {
         super(context, attrs);
         init();
@@ -196,11 +196,11 @@
     private void init() {
         setWillNotDraw(true);
     }
-    
+
     /**
      * Return the SurfaceHolder providing access and control over this
      * SurfaceView's underlying surface.
-     * 
+     *
      * @return SurfaceHolder The holder of the surface.
      */
     public SurfaceHolder getHolder() {
@@ -286,7 +286,7 @@
                 : getDefaultSize(0, heightMeasureSpec);
         setMeasuredDimension(width, height);
     }
-    
+
     /** @hide */
     @Override
     protected boolean setFrame(int left, int top, int right, int bottom) {
@@ -300,7 +300,7 @@
         if (mWindowType == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
             return super.gatherTransparentRegion(region);
         }
-        
+
         boolean opaque = true;
         if ((mPrivateFlags & PFLAG_SKIP_DRAW) == 0) {
             // this view draws, remove it from the transparent region
@@ -351,10 +351,10 @@
      * regular surface view in the window (but still behind the window itself).
      * This is typically used to place overlays on top of an underlying media
      * surface view.
-     * 
+     *
      * <p>Note that this must be set before the surface view's containing
      * window is attached to the window manager.
-     * 
+     *
      * <p>Calling this overrides any previous call to {@link #setZOrderOnTop}.
      */
     public void setZOrderMediaOverlay(boolean isMediaOverlay) {
@@ -362,7 +362,7 @@
                 ? WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY
                 : WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
     }
-    
+
     /**
      * Control whether the surface view's surface is placed on top of its
      * window.  Normally it is placed behind the window, to allow it to
@@ -370,10 +370,10 @@
      * hierarchy.  By setting this, you cause it to be placed above the
      * window.  This means that none of the contents of the window this
      * SurfaceView is in will be visible on top of its surface.
-     * 
+     *
      * <p>Note that this must be set before the surface view's containing
      * window is attached to the window manager.
-     * 
+     *
      * <p>Calling this overrides any previous call to {@link #setZOrderMediaOverlay}.
      */
     public void setZOrderOnTop(boolean onTop) {
@@ -428,7 +428,7 @@
         if (mTranslator != null) {
             mSurface.setCompatibilityTranslator(mTranslator);
         }
-        
+
         int myWidth = mRequestedWidth;
         if (myWidth <= 0) myWidth = getWidth();
         int myHeight = mRequestedHeight;
@@ -459,7 +459,7 @@
                 mFormat = mRequestedFormat;
 
                 // Scaling/Translate window's layout here because mLayout is not used elsewhere.
-                
+
                 // Places the window relative
                 mLayout.x = mLeft;
                 mLayout.y = mTop;
@@ -468,7 +468,7 @@
                 if (mTranslator != null) {
                     mTranslator.translateLayoutParamsInAppWindowToScreen(mLayout);
                 }
-                
+
                 mLayout.format = mRequestedFormat;
                 mLayout.flags |=WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                               | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
@@ -490,7 +490,7 @@
                     mSession.addToDisplayWithoutInputChannel(mWindow, mWindow.mSeq, mLayout,
                             mVisible ? VISIBLE : GONE, display.getDisplayId(), mContentInsets);
                 }
-                
+
                 boolean realSizeChanged;
                 boolean reportDrawNeeded;
 
@@ -502,7 +502,7 @@
                     reportDrawNeeded = mReportDrawNeeded;
                     mReportDrawNeeded = false;
                     mDrawingStopped = !visible;
-    
+
                     if (DEBUG) Log.i(TAG, "Cur surface: " + mSurface);
 
                     relayoutResult = mSession.relayout(
@@ -528,7 +528,7 @@
                         mSurfaceFrame.right = (int) (mWinFrame.width() * appInvertedScale + 0.5f);
                         mSurfaceFrame.bottom = (int) (mWinFrame.height() * appInvertedScale + 0.5f);
                     }
-                    
+
                     final int surfaceWidth = mSurfaceFrame.right;
                     final int surfaceHeight = mSurfaceFrame.bottom;
                     realSizeChanged = mLastSurfaceWidth != surfaceWidth
@@ -668,10 +668,12 @@
             }
         }
 
+        @Override
         public void dispatchAppVisibility(boolean visible) {
             // The point of SurfaceView is to let the app control the surface.
         }
 
+        @Override
         public void dispatchGetNewSurface() {
             SurfaceView surfaceView = mSurfaceView.get();
             if (surfaceView != null) {
@@ -680,10 +682,12 @@
             }
         }
 
+        @Override
         public void windowFocusChanged(boolean hasFocus, boolean touchEnabled) {
             Log.w("SurfaceView", "Unexpected focus in surface: focus=" + hasFocus + ", touchEnabled=" + touchEnabled);
         }
 
+        @Override
         public void executeCommand(String command, String parameters, ParcelFileDescriptor out) {
         }
 
@@ -691,30 +695,34 @@
         int mCurHeight = -1;
     }
 
-    private SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
-        
+    private final SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
+
         private static final String LOG_TAG = "SurfaceHolder";
-        
+
+        @Override
         public boolean isCreating() {
             return mIsCreating;
         }
 
+        @Override
         public void addCallback(Callback callback) {
             synchronized (mCallbacks) {
-                // This is a linear search, but in practice we'll 
+                // This is a linear search, but in practice we'll
                 // have only a couple callbacks, so it doesn't matter.
-                if (mCallbacks.contains(callback) == false) {      
+                if (mCallbacks.contains(callback) == false) {
                     mCallbacks.add(callback);
                 }
             }
         }
 
+        @Override
         public void removeCallback(Callback callback) {
             synchronized (mCallbacks) {
                 mCallbacks.remove(callback);
             }
         }
-        
+
+        @Override
         public void setFixedSize(int width, int height) {
             if (mRequestedWidth != width || mRequestedHeight != height) {
                 mRequestedWidth = width;
@@ -723,6 +731,7 @@
             }
         }
 
+        @Override
         public void setSizeFromLayout() {
             if (mRequestedWidth != -1 || mRequestedHeight != -1) {
                 mRequestedWidth = mRequestedHeight = -1;
@@ -730,6 +739,7 @@
             }
         }
 
+        @Override
         public void setFormat(int format) {
 
             // for backward compatibility reason, OPAQUE always
@@ -746,15 +756,17 @@
         /**
          * @deprecated setType is now ignored.
          */
+        @Override
         @Deprecated
         public void setType(int type) { }
 
+        @Override
         public void setKeepScreenOn(boolean screenOn) {
             Message msg = mHandler.obtainMessage(KEEP_SCREEN_ON_MSG);
             msg.arg1 = screenOn ? 1 : 0;
             mHandler.sendMessage(msg);
         }
-        
+
         /**
          * Gets a {@link Canvas} for drawing into the SurfaceView's Surface
          *
@@ -764,6 +776,7 @@
          * The caller must redraw the entire surface.
          * @return A canvas for drawing into the surface.
          */
+        @Override
         public Canvas lockCanvas() {
             return internalLockCanvas(null);
         }
@@ -783,6 +796,7 @@
          * entire surface should be redrawn.
          * @return A canvas for drawing into the surface.
          */
+        @Override
         public Canvas lockCanvas(Rect inOutDirty) {
             return internalLockCanvas(inOutDirty);
         }
@@ -795,14 +809,6 @@
 
             Canvas c = null;
             if (!mDrawingStopped && mWindow != null) {
-                if (dirty == null) {
-                    if (mTmpDirty == null) {
-                        mTmpDirty = new Rect();
-                    }
-                    mTmpDirty.set(mSurfaceFrame);
-                    dirty = mTmpDirty;
-                }
-
                 try {
                     c = mSurface.lockCanvas(dirty);
                 } catch (Exception e) {
@@ -815,7 +821,7 @@
                 mLastLockTime = SystemClock.uptimeMillis();
                 return c;
             }
-            
+
             // If the Surface is not ready to be drawn, then return null,
             // but throttle calls to this function so it isn't called more
             // than every 100ms.
@@ -830,7 +836,7 @@
             }
             mLastLockTime = now;
             mSurfaceLock.unlock();
-            
+
             return null;
         }
 
@@ -840,15 +846,18 @@
          *
          * @param canvas The canvas previously obtained from {@link #lockCanvas}.
          */
+        @Override
         public void unlockCanvasAndPost(Canvas canvas) {
             mSurface.unlockCanvasAndPost(canvas);
             mSurfaceLock.unlock();
         }
 
+        @Override
         public Surface getSurface() {
             return mSurface;
         }
 
+        @Override
         public Rect getSurfaceFrame() {
             return mSurfaceFrame;
         }
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index 244dc33..b2c9f8c 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -322,7 +322,7 @@
     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
         super.onSizeChanged(w, h, oldw, oldh);
         if (mSurface != null) {
-            nSetDefaultBufferSize(mSurface, getWidth(), getHeight());
+            mSurface.setDefaultBufferSize(getWidth(), getHeight());
             updateLayer();
             if (mListener != null) {
                 mListener.onSurfaceTextureSizeChanged(mSurface, getWidth(), getHeight());
@@ -362,7 +362,7 @@
                 // Create a new SurfaceTexture for the layer.
                 mSurface = mAttachInfo.mHardwareRenderer.createSurfaceTexture(mLayer);
             }
-            nSetDefaultBufferSize(mSurface, getWidth(), getHeight());
+            mSurface.setDefaultBufferSize(getWidth(), getHeight());
             nCreateNativeWindow(mSurface);
 
             mUpdateListener = new SurfaceTexture.OnFrameAvailableListener() {
@@ -399,7 +399,7 @@
             mMatrixChanged = true;
 
             mAttachInfo.mHardwareRenderer.setSurfaceTexture(mLayer, mSurface);
-            nSetDefaultBufferSize(mSurface, getWidth(), getHeight());
+            mSurface.setDefaultBufferSize(getWidth(), getHeight());
         }
 
         applyUpdate();
@@ -656,13 +656,19 @@
      * rectangle. Every pixel within that rectangle must be written; however
      * pixels outside the dirty rectangle will be preserved by the next call
      * to lockCanvas().
+     *
+     * This method can return null if the underlying surface texture is not
+     * available (see {@link #isAvailable()} or if the surface texture is
+     * already connected to an image producer (for instance: the camera,
+     * OpenGL, a media player, etc.)
      * 
      * @param dirty Area of the surface that will be modified.
 
      * @return A Canvas used to draw into the surface.
      * 
      * @see #lockCanvas() 
-     * @see #unlockCanvasAndPost(android.graphics.Canvas) 
+     * @see #unlockCanvasAndPost(android.graphics.Canvas)
+     * @see #isAvailable()
      */
     public Canvas lockCanvas(Rect dirty) {
         if (!isAvailable()) return null;
@@ -672,7 +678,9 @@
         }
 
         synchronized (mNativeWindowLock) {
-            nLockCanvas(mNativeWindow, mCanvas, dirty);
+            if (!nLockCanvas(mNativeWindow, mCanvas, dirty)) {
+                return null;
+            }
         }
         mSaveCount = mCanvas.save();
 
@@ -808,9 +816,6 @@
     private native void nCreateNativeWindow(SurfaceTexture surface);
     private native void nDestroyNativeWindow();
 
-    private static native void nSetDefaultBufferSize(SurfaceTexture surfaceTexture,
-            int width, int height);
-
-    private static native void nLockCanvas(int nativeWindow, Canvas canvas, Rect dirty);
+    private static native boolean nLockCanvas(int nativeWindow, Canvas canvas, Rect dirty);
     private static native void nUnlockCanvasAndPost(int nativeWindow, Canvas canvas);
 }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 50638aa..a5db6ee 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -40,7 +40,6 @@
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.hardware.display.DisplayManagerGlobal;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -52,10 +51,13 @@
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.FloatProperty;
+import android.util.LayoutDirection;
 import android.util.Log;
+import android.util.LongSparseLongArray;
 import android.util.Pools.SynchronizedPool;
 import android.util.Property;
 import android.util.SparseArray;
+import android.util.SuperNotCalledException;
 import android.util.TypedValue;
 import android.view.ContextMenu.ContextMenuInfo;
 import android.view.AccessibilityIterators.TextSegmentIterator;
@@ -1122,7 +1124,6 @@
      *
      * @see android.graphics.drawable.Drawable
      * @see #getDrawableState()
-     * @hide
      */
     protected static final int[] PRESSED_STATE_SET;
     /**
@@ -1563,6 +1564,8 @@
 
     private int mAccessibilityCursorPosition = ACCESSIBILITY_CURSOR_POSITION_UNDEFINED;
 
+    SendViewStateChangedAccessibilityEvent mSendViewStateChangedAccessibilityEvent;
+
     /**
      * The view's tag.
      * {@hide}
@@ -1797,25 +1800,25 @@
      * Horizontal layout direction of this view is from Left to Right.
      * Use with {@link #setLayoutDirection}.
      */
-    public static final int LAYOUT_DIRECTION_LTR = 0;
+    public static final int LAYOUT_DIRECTION_LTR = LayoutDirection.LTR;
 
     /**
      * Horizontal layout direction of this view is from Right to Left.
      * Use with {@link #setLayoutDirection}.
      */
-    public static final int LAYOUT_DIRECTION_RTL = 1;
+    public static final int LAYOUT_DIRECTION_RTL = LayoutDirection.RTL;
 
     /**
      * Horizontal layout direction of this view is inherited from its parent.
      * Use with {@link #setLayoutDirection}.
      */
-    public static final int LAYOUT_DIRECTION_INHERIT = 2;
+    public static final int LAYOUT_DIRECTION_INHERIT = LayoutDirection.INHERIT;
 
     /**
      * Horizontal layout direction of this view is from deduced from the default language
      * script for the locale. Use with {@link #setLayoutDirection}.
      */
-    public static final int LAYOUT_DIRECTION_LOCALE = 3;
+    public static final int LAYOUT_DIRECTION_LOCALE = LayoutDirection.LOCALE;
 
     /**
      * Bit shift to get the horizontal layout direction. (bits after DRAG_HOVERED)
@@ -2131,15 +2134,58 @@
         << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
 
     /**
-     * Flag indicating whether a view has accessibility focus.
+     * Shift for the bits in {@link #mPrivateFlags2} related to the
+     * "accessibilityLiveRegion" attribute.
      */
-    static final int PFLAG2_ACCESSIBILITY_FOCUSED = 0x00000040 << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
+    static final int PFLAG2_ACCESSIBILITY_LIVE_REGION_SHIFT = 22;
 
     /**
-     * Flag indicating whether a view state for accessibility has changed.
+     * Live region mode specifying that accessibility services should not
+     * automatically announce changes to this view. This is the default live
+     * region mode for most views.
+     * <p>
+     * Use with {@link #setAccessibilityLiveRegion(int)}.
      */
-    static final int PFLAG2_ACCESSIBILITY_STATE_CHANGED = 0x00000080
-            << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
+    public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0x00000000;
+
+    /**
+     * Live region mode specifying that accessibility services should announce
+     * changes to this view.
+     * <p>
+     * Use with {@link #setAccessibilityLiveRegion(int)}.
+     */
+    public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 0x00000001;
+
+    /**
+     * Live region mode specifying that accessibility services should interrupt
+     * ongoing speech to immediately announce changes to this view.
+     * <p>
+     * Use with {@link #setAccessibilityLiveRegion(int)}.
+     */
+    public static final int ACCESSIBILITY_LIVE_REGION_ASSERTIVE = 0x00000002;
+
+    /**
+     * The default whether the view is important for accessibility.
+     */
+    static final int ACCESSIBILITY_LIVE_REGION_DEFAULT = ACCESSIBILITY_LIVE_REGION_NONE;
+
+    /**
+     * Mask for obtaining the bits which specify a view's accessibility live
+     * region mode.
+     */
+    static final int PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK = (ACCESSIBILITY_LIVE_REGION_NONE
+            | ACCESSIBILITY_LIVE_REGION_POLITE | ACCESSIBILITY_LIVE_REGION_ASSERTIVE)
+            << PFLAG2_ACCESSIBILITY_LIVE_REGION_SHIFT;
+
+    /**
+     * Flag indicating whether a view has accessibility focus.
+     */
+    static final int PFLAG2_ACCESSIBILITY_FOCUSED = 0x04000000;
+
+    /**
+     * Flag whether the accessibility state of the subtree rooted at this view changed.
+     */
+    static final int PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED = 0x08000000;
 
     /**
      * Flag indicating whether a view failed the quickReject() check in draw(). This condition
@@ -2191,6 +2237,24 @@
      */
     static final int PFLAG3_VIEW_IS_ANIMATING_ALPHA = 0x2;
 
+    /**
+     * Flag indicating that the view has been through at least one layout since it
+     * was last attached to a window.
+     */
+    static final int PFLAG3_IS_LAID_OUT = 0x4;
+
+    /**
+     * Flag indicating that a call to measure() was skipped and should be done
+     * instead when layout() is invoked.
+     */
+    static final int PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT = 0x8;
+
+    /**
+     * Flag indicating that an overridden method correctly  called down to
+     * the superclass implementation as required by the API spec.
+     */
+    static final int PFLAG3_CALLED_SUPER = 0x10;
+
 
     /* End of masks for mPrivateFlags3 */
 
@@ -2341,7 +2405,7 @@
      * allows it to avoid artifacts when switching in and out of that mode, at
      * the expense that some of its user interface may be covered by screen
      * decorations when they are shown.  You can perform layout of your inner
-     * UI elements to account for the navagation system UI through the
+     * UI elements to account for the navigation system UI through the
      * {@link #fitSystemWindows(Rect)} method.
      */
     public static final int SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION = 0x00000200;
@@ -2359,6 +2423,42 @@
     public static final int SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN = 0x00000400;
 
     /**
+     * Flag for {@link #setSystemUiVisibility(int)}: View would like to remain interactive when
+     * hiding the status bar with {@link #SYSTEM_UI_FLAG_FULLSCREEN} and/or hiding the navigation
+     * bar with {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}.  Use this flag to create an immersive
+     * experience while also hiding the system bars.  If this flag is not set,
+     * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION} will be force cleared by the system on any user
+     * interaction, and {@link #SYSTEM_UI_FLAG_FULLSCREEN} will be force-cleared by the system
+     * if the user swipes from the top of the screen.
+     * <p>When system bars are hidden in immersive mode, they can be revealed temporarily with
+     * system gestures, such as swiping from the top of the screen.  These transient system bars
+     * will overlay app’s content, may have some degree of transparency, and will automatically
+     * hide after a short timeout.
+     * </p><p>Since this flag is a modifier for {@link #SYSTEM_UI_FLAG_FULLSCREEN} and
+     * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, it only has an effect when used in combination
+     * with one or both of those flags.</p>
+     */
+    public static final int SYSTEM_UI_FLAG_IMMERSIVE = 0x00000800;
+
+    /**
+     * Flag for {@link #setSystemUiVisibility(int)}: View would like the status bar to have
+     * transparency.
+     *
+     * <p>The transparency request may be denied if the bar is in another mode with a specific
+     * style, like {@link #SYSTEM_UI_FLAG_IMMERSIVE immersive mode}.
+     */
+    public static final int SYSTEM_UI_FLAG_TRANSPARENT_STATUS = 0x00001000;
+
+    /**
+     * Flag for {@link #setSystemUiVisibility(int)}: View would like the navigation bar to have
+     * transparency.
+     *
+     * <p>The transparency request may be denied if the bar is in another mode with a specific
+     * style, like {@link #SYSTEM_UI_FLAG_IMMERSIVE immersive mode}.
+     */
+    public static final int SYSTEM_UI_FLAG_TRANSPARENT_NAVIGATION = 0x00002000;
+
+    /**
      * @deprecated Use {@link #SYSTEM_UI_FLAG_LOW_PROFILE} instead.
      */
     public static final int STATUS_BAR_HIDDEN = SYSTEM_UI_FLAG_LOW_PROFILE;
@@ -2479,6 +2579,46 @@
 
     /**
      * @hide
+     *
+     * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
+     * out of the public fields to keep the undefined bits out of the developer's way.
+     *
+     * Flag to specify that the status bar is displayed in transient mode.
+     */
+    public static final int STATUS_BAR_TRANSIENT = 0x04000000;
+
+    /**
+     * @hide
+     *
+     * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
+     * out of the public fields to keep the undefined bits out of the developer's way.
+     *
+     * Flag to specify that the navigation bar is displayed in transient mode.
+     */
+    public static final int NAVIGATION_BAR_TRANSIENT = 0x08000000;
+
+    /**
+     * @hide
+     *
+     * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
+     * out of the public fields to keep the undefined bits out of the developer's way.
+     *
+     * Flag to specify that the hidden status bar would like to be shown.
+     */
+    public static final int STATUS_BAR_UNHIDE = 0x10000000;
+
+    /**
+     * @hide
+     *
+     * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
+     * out of the public fields to keep the undefined bits out of the developer's way.
+     *
+     * Flag to specify that the hidden navigation bar would like to be shown.
+     */
+    public static final int NAVIGATION_BAR_UNHIDE = 0x20000000;
+
+    /**
+     * @hide
      */
     public static final int PUBLIC_STATUS_BAR_VISIBILITY_MASK = 0x0000FFFF;
 
@@ -2938,6 +3078,8 @@
      */
     int mOldHeightMeasureSpec = Integer.MIN_VALUE;
 
+    private LongSparseLongArray mMeasureCache;
+
     @ViewDebug.ExportedProperty(deepExport = true, prefix = "bg_")
     private Drawable mBackground;
 
@@ -3012,18 +3154,6 @@
     private int[] mDrawableState = null;
 
     /**
-     * Set to true when drawing cache is enabled and cannot be created.
-     *
-     * @hide
-     */
-    public boolean mCachingFailed;
-
-    private Bitmap mDrawingCache;
-    private Bitmap mUnscaledDrawingCache;
-    private HardwareLayer mHardwareLayer;
-    DisplayList mDisplayList;
-
-    /**
      * When this view has focus and the next focus is {@link #FOCUS_LEFT},
      * the user may specify which view to go to next.
      */
@@ -3215,6 +3345,18 @@
     int mLayerType = LAYER_TYPE_NONE;
     Paint mLayerPaint;
     Rect mLocalDirtyRect;
+    private HardwareLayer mHardwareLayer;
+
+    /**
+     * Set to true when drawing cache is enabled and cannot be created.
+     *
+     * @hide
+     */
+    public boolean mCachingFailed;
+    private Bitmap mDrawingCache;
+    private Bitmap mUnscaledDrawingCache;
+
+    DisplayList mDisplayList;
 
     /**
      * Set to true when the view is sending hover accessibility events because it
@@ -3266,8 +3408,8 @@
         mUserPaddingStart = UNDEFINED_PADDING;
         mUserPaddingEnd = UNDEFINED_PADDING;
 
-        if (!sUseBrokenMakeMeasureSpec && context.getApplicationInfo().targetSdkVersion <=
-                Build.VERSION_CODES.JELLY_BEAN_MR1 ) {
+        if (!sUseBrokenMakeMeasureSpec && context != null &&
+                context.getApplicationInfo().targetSdkVersion <= JELLY_BEAN_MR1) {
             // Older apps may need this compatibility hack for measurement.
             sUseBrokenMakeMeasureSpec = true;
         }
@@ -3305,17 +3447,16 @@
      * @param context The Context the view is running in, through which it can
      *        access the current theme, resources, etc.
      * @param attrs The attributes of the XML tag that is inflating the view.
-     * @param defStyle The default style to apply to this view. If 0, no style
-     *        will be applied (beyond what is included in the theme). This may
-     *        either be an attribute resource, whose value will be retrieved
-     *        from the current theme, or an explicit style resource.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource to apply to this view. If 0, no
+     *        default style will be applied.
      * @see #View(Context, AttributeSet)
      */
-    public View(Context context, AttributeSet attrs, int defStyle) {
+    public View(Context context, AttributeSet attrs, int defStyleAttr) {
         this(context);
 
         TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.View,
-                defStyle, 0);
+                defStyleAttr, 0);
 
         Drawable background = null;
 
@@ -3666,6 +3807,9 @@
                     setImportantForAccessibility(a.getInt(attr,
                             IMPORTANT_FOR_ACCESSIBILITY_DEFAULT));
                     break;
+                case R.styleable.View_accessibilityLiveRegion:
+                    setAccessibilityLiveRegion(a.getInt(attr, ACCESSIBILITY_LIVE_REGION_DEFAULT));
+                    break;
             }
         }
 
@@ -4418,10 +4562,6 @@
 
             onFocusChanged(true, direction, previouslyFocusedRect);
             refreshDrawableState();
-
-            if (AccessibilityManager.getInstance(mContext).isEnabled()) {
-                notifyAccessibilityStateChanged();
-            }
         }
     }
 
@@ -4511,10 +4651,23 @@
             System.out.println(this + " clearFocus()");
         }
 
+        clearFocusInternal(true, true);
+    }
+
+    /**
+     * Clears focus from the view, optionally propagating the change up through
+     * the parent hierarchy and requesting that the root view place new focus.
+     *
+     * @param propagate whether to propagate the change up through the parent
+     *            hierarchy
+     * @param refocus when propagate is true, specifies whether to request the
+     *            root view place new focus
+     */
+    void clearFocusInternal(boolean propagate, boolean refocus) {
         if ((mPrivateFlags & PFLAG_FOCUSED) != 0) {
             mPrivateFlags &= ~PFLAG_FOCUSED;
 
-            if (mParent != null) {
+            if (propagate && mParent != null) {
                 mParent.clearChildFocus(this);
             }
 
@@ -4522,13 +4675,9 @@
 
             refreshDrawableState();
 
-            if (!rootViewRequestFocus()) {
+            if (propagate && (!refocus || !rootViewRequestFocus())) {
                 notifyGlobalFocusCleared(this);
             }
-
-            if (AccessibilityManager.getInstance(mContext).isEnabled()) {
-                notifyAccessibilityStateChanged();
-            }
         }
     }
 
@@ -4539,32 +4688,24 @@
     }
 
     boolean rootViewRequestFocus() {
-        View root = getRootView();
-        if (root != null) {
-            return root.requestFocus();
-        }
-        return false;
+        final View root = getRootView();
+        return root != null && root.requestFocus();
     }
 
     /**
      * Called internally by the view system when a new view is getting focus.
      * This is what clears the old focus.
+     * <p>
+     * <b>NOTE:</b> The parent view's focused child must be updated manually
+     * after calling this method. Otherwise, the view hierarchy may be left in
+     * an inconstent state.
      */
     void unFocus() {
         if (DBG) {
             System.out.println(this + " unFocus()");
         }
 
-        if ((mPrivateFlags & PFLAG_FOCUSED) != 0) {
-            mPrivateFlags &= ~PFLAG_FOCUSED;
-
-            onFocusChanged(false, 0, null);
-            refreshDrawableState();
-
-            if (AccessibilityManager.getInstance(mContext).isEnabled()) {
-                notifyAccessibilityStateChanged();
-            }
-        }
+        clearFocusInternal(false, false);
     }
 
     /**
@@ -4614,9 +4755,10 @@
      */
     protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
         if (gainFocus) {
-            if (AccessibilityManager.getInstance(mContext).isEnabled()) {
-                sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
-            }
+            sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
+        } else {
+            notifyViewAccessibilityStateChangedIfNeeded(
+                    AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
         }
 
         InputMethodManager imm = InputMethodManager.peekInstance();
@@ -4673,6 +4815,10 @@
      * @see AccessibilityDelegate
      */
     public void sendAccessibilityEvent(int eventType) {
+        // Excluded views do not send accessibility events.
+        if (!includeForAccessibility()) {
+            return;
+        }
         if (mAccessibilityDelegate != null) {
             mAccessibilityDelegate.sendAccessibilityEvent(this, eventType);
         } else {
@@ -4840,7 +4986,6 @@
      * Note: Called from the default {@link AccessibilityDelegate}.
      */
     void onPopulateAccessibilityEventInternal(AccessibilityEvent event) {
-
     }
 
     /**
@@ -5331,9 +5476,12 @@
         mContentDescription = contentDescription;
         final boolean nonEmptyDesc = contentDescription != null && contentDescription.length() > 0;
         if (nonEmptyDesc && getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
-             setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
+            setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
+            notifySubtreeAccessibilityStateChangedIfNeeded();
+        } else {
+            notifyViewAccessibilityStateChangedIfNeeded(
+                    AccessibilityEvent.CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION);
         }
-        notifyAccessibilityStateChanged();
     }
 
     /**
@@ -5657,7 +5805,7 @@
      * which you would like to ensure are not being covered.
      *
      * <p>The default implementation of this method simply applies the content
-     * inset's to the view's padding, consuming that content (modifying the
+     * insets to the view's padding, consuming that content (modifying the
      * insets to be 0), and returning true.  This behavior is off by default, but can
      * be enabled through {@link #setFitsSystemWindows(boolean)}.
      *
@@ -5694,8 +5842,8 @@
      * {@link android.os.Build.VERSION_CODES#JELLY_BEAN} you must not modify
      * the insets or else you and Android will be unhappy.
      *
-     * @return Return true if this view applied the insets and it should not
-     * continue propagating further down the hierarchy, false otherwise.
+     * @return {@code true} if this view applied the insets and it should not
+     * continue propagating further down the hierarchy, {@code false} otherwise.
      * @see #getFitsSystemWindows()
      * @see #setFitsSystemWindows(boolean) 
      * @see #setSystemUiVisibility(int)
@@ -5766,15 +5914,15 @@
     }
 
     /**
-     * Check for state of {@link #setFitsSystemWindows(boolean). If this method
-     * returns true, the default implementation of {@link #fitSystemWindows(Rect)}
+     * Check for state of {@link #setFitsSystemWindows(boolean)}. If this method
+     * returns {@code true}, the default implementation of {@link #fitSystemWindows(Rect)}
      * will be executed.
      *
-     * @return Returns true if the default implementation of
+     * @return {@code true} if the default implementation of
      * {@link #fitSystemWindows(Rect)} will be executed.
      *
      * @attr ref android.R.styleable#View_fitsSystemWindows
-     * @see #setFitsSystemWindows()
+     * @see #setFitsSystemWindows(boolean)
      * @see #fitSystemWindows(Rect)
      * @see #setSystemUiVisibility(int)
      */
@@ -5863,6 +6011,10 @@
         // Invalidate too, since the default behavior for views is to be
         // be drawn at 50% alpha rather than to change the drawable.
         invalidate(true);
+
+        if (!enabled) {
+            cancelPendingInputEvents();
+        }
     }
 
     /**
@@ -6110,6 +6262,21 @@
     }
 
     /**
+     * Returns true if this view is currently attached to a window.
+     */
+    public boolean isAttachedToWindow() {
+        return mAttachInfo != null;
+    }
+
+    /**
+     * Returns true if this view has been through at least one layout since it
+     * was last attached to or detached from a window.
+     */
+    public boolean isLaidOut() {
+        return (mPrivateFlags3 & PFLAG3_IS_LAID_OUT) == PFLAG3_IS_LAID_OUT;
+    }
+
+    /**
      * If this view doesn't do any drawing on its own, set this flag to
      * allow further optimizations. By default, this flag is not set on
      * View, but could be set on some View subclasses such as ViewGroup.
@@ -6578,8 +6745,9 @@
      * Returns whether this View is accessibility focused.
      *
      * @return True if this View is accessibility focused.
+     * @hide
      */
-    boolean isAccessibilityFocused() {
+    public boolean isAccessibilityFocused() {
         return (mPrivateFlags2 & PFLAG2_ACCESSIBILITY_FOCUSED) != 0;
     }
 
@@ -6613,7 +6781,6 @@
             }
             invalidate();
             sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
-            notifyAccessibilityStateChanged();
             return true;
         }
         return false;
@@ -6676,7 +6843,6 @@
             mPrivateFlags2 &= ~PFLAG2_ACCESSIBILITY_FOCUSED;
             invalidate();
             sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
-            notifyAccessibilityStateChanged();
         }
     }
 
@@ -6837,6 +7003,58 @@
     }
 
     /**
+     * Sets the live region mode for this view. This indicates to accessibility
+     * services whether they should automatically notify the user about changes
+     * to the view's content description or text, or to the content descriptions
+     * or text of the view's children (where applicable).
+     * <p>
+     * For example, in a login screen with a TextView that displays an "incorrect
+     * password" notification, that view should be marked as a live region with
+     * mode {@link #ACCESSIBILITY_LIVE_REGION_POLITE}.
+     * <p>
+     * To disable change notifications for this view, use
+     * {@link #ACCESSIBILITY_LIVE_REGION_NONE}. This is the default live region
+     * mode for most views.
+     * <p>
+     * To indicate that the user should be notified of changes, use
+     * {@link #ACCESSIBILITY_LIVE_REGION_POLITE}.
+     * <p>
+     * If the view's changes should interrupt ongoing speech and notify the user
+     * immediately, use {@link #ACCESSIBILITY_LIVE_REGION_ASSERTIVE}.
+     *
+     * @param mode The live region mode for this view, one of:
+     *        <ul>
+     *        <li>{@link #ACCESSIBILITY_LIVE_REGION_NONE}
+     *        <li>{@link #ACCESSIBILITY_LIVE_REGION_POLITE}
+     *        <li>{@link #ACCESSIBILITY_LIVE_REGION_ASSERTIVE}
+     *        </ul>
+     * @attr ref android.R.styleable#View_accessibilityLiveRegion
+     */
+    public void setAccessibilityLiveRegion(int mode) {
+        if (mode != getAccessibilityLiveRegion()) {
+            mPrivateFlags2 &= ~PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK;
+            mPrivateFlags2 |= (mode << PFLAG2_ACCESSIBILITY_LIVE_REGION_SHIFT)
+                    & PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK;
+            notifyViewAccessibilityStateChangedIfNeeded(
+                    AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
+        }
+    }
+
+    /**
+     * Gets the live region mode for this View.
+     *
+     * @return The live region mode for the view.
+     *
+     * @attr ref android.R.styleable#View_accessibilityLiveRegion
+     *
+     * @see #setAccessibilityLiveRegion(int)
+     */
+    public int getAccessibilityLiveRegion() {
+        return (mPrivateFlags2 & PFLAG2_ACCESSIBILITY_LIVE_REGION_MASK)
+                >> PFLAG2_ACCESSIBILITY_LIVE_REGION_SHIFT;
+    }
+
+    /**
      * Sets how to determine whether this view is important for accessibility
      * which is if it fires accessibility events and if it is reported to
      * accessibility services that query the screen.
@@ -6850,11 +7068,17 @@
      * @see #IMPORTANT_FOR_ACCESSIBILITY_AUTO
      */
     public void setImportantForAccessibility(int mode) {
+        final boolean oldIncludeForAccessibility = includeForAccessibility();
         if (mode != getImportantForAccessibility()) {
             mPrivateFlags2 &= ~PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK;
             mPrivateFlags2 |= (mode << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT)
                     & PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK;
-            notifyAccessibilityStateChanged();
+            if (oldIncludeForAccessibility != includeForAccessibility()) {
+                notifySubtreeAccessibilityStateChangedIfNeeded();
+            } else {
+                notifyViewAccessibilityStateChangedIfNeeded(
+                        AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
+            }
         }
     }
 
@@ -6875,7 +7099,8 @@
                 return false;
             case IMPORTANT_FOR_ACCESSIBILITY_AUTO:
                 return isActionableForAccessibility() || hasListenersForAccessibility()
-                        || getAccessibilityNodeProvider() != null;
+                        || getAccessibilityNodeProvider() != null
+                        || getAccessibilityLiveRegion() != ACCESSIBILITY_LIVE_REGION_NONE;
             default:
                 throw new IllegalArgumentException("Unknow important for accessibility mode: "
                         + mode);
@@ -6926,6 +7151,7 @@
      * @hide
      */
     public boolean includeForAccessibility() {
+        //noinspection SimplifiableIfStatement
         if (mAttachInfo != null) {
             return (mAttachInfo.mAccessibilityFetchFlags
                     & AccessibilityNodeInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS) != 0
@@ -6961,39 +7187,62 @@
     }
 
     /**
-     * Notifies accessibility services that some view's important for
-     * accessibility state has changed. Note that such notifications
-     * are made at most once every
+     * Notifies that the accessibility state of this view changed. The change
+     * is local to this view and does not represent structural changes such
+     * as children and parent. For example, the view became focusable. The
+     * notification is at at most once every
      * {@link ViewConfiguration#getSendRecurringAccessibilityEventsInterval()}
-     * to avoid unnecessary load to the system. Also once a view has
-     * made a notifucation this method is a NOP until the notification has
-     * been sent to clients.
+     * to avoid unnecessary load to the system. Also once a view has a pending
+     * notifucation this method is a NOP until the notification has been sent.
      *
      * @hide
-     *
-     * TODO: Makse sure this method is called for any view state change
-     *       that is interesting for accessilility purposes.
      */
-    public void notifyAccessibilityStateChanged() {
+    public void notifyViewAccessibilityStateChangedIfNeeded(int changeType) {
         if (!AccessibilityManager.getInstance(mContext).isEnabled()) {
             return;
         }
-        if ((mPrivateFlags2 & PFLAG2_ACCESSIBILITY_STATE_CHANGED) == 0) {
-            mPrivateFlags2 |= PFLAG2_ACCESSIBILITY_STATE_CHANGED;
+        if (mSendViewStateChangedAccessibilityEvent == null) {
+            mSendViewStateChangedAccessibilityEvent =
+                    new SendViewStateChangedAccessibilityEvent();
+        }
+        mSendViewStateChangedAccessibilityEvent.runOrPost(changeType);
+    }
+
+    /**
+     * Notifies that the accessibility state of this view changed. The change
+     * is *not* local to this view and does represent structural changes such
+     * as children and parent. For example, the view size changed. The
+     * notification is at at most once every
+     * {@link ViewConfiguration#getSendRecurringAccessibilityEventsInterval()}
+     * to avoid unnecessary load to the system. Also once a view has a pending
+     * notifucation this method is a NOP until the notification has been sent.
+     *
+     * @hide
+     */
+    public void notifySubtreeAccessibilityStateChangedIfNeeded() {
+        if (!AccessibilityManager.getInstance(mContext).isEnabled()) {
+            return;
+        }
+        if ((mPrivateFlags2 & PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED) == 0) {
+            mPrivateFlags2 |= PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED;
             if (mParent != null) {
-                mParent.childAccessibilityStateChanged(this);
+                try {
+                    mParent.notifySubtreeAccessibilityStateChanged(
+                            this, this, AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE);
+                } catch (AbstractMethodError e) {
+                    Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
+                            " does not fully implement ViewParent", e);
+                }
             }
         }
     }
 
     /**
-     * Reset the state indicating the this view has requested clients
-     * interested in its accessibility state to be notified.
-     *
-     * @hide
+     * Reset the flag indicating the accessibility state of the subtree rooted
+     * at this view changed.
      */
-    public void resetAccessibilityStateChanged() {
-        mPrivateFlags2 &= ~PFLAG2_ACCESSIBILITY_STATE_CHANGED;
+    void resetSubtreeAccessibilityStateChanged() {
+        mPrivateFlags2 &= ~PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED;
     }
 
     /**
@@ -7106,7 +7355,8 @@
                         || getAccessibilitySelectionEnd() != end)
                         && (start == end)) {
                     setAccessibilitySelection(start, end);
-                    notifyAccessibilityStateChanged();
+                    notifyViewAccessibilityStateChangedIfNeeded(
+                            AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
                     return true;
                 }
             } break;
@@ -7261,7 +7511,6 @@
      * @hide
      */
     public void dispatchStartTemporaryDetach() {
-        clearAccessibilityFocus();
         clearDisplayList();
 
         onStartTemporaryDetach();
@@ -7497,8 +7746,8 @@
      * @return True if the event was handled by the view, false otherwise.
      */
     protected boolean dispatchHoverEvent(MotionEvent event) {
-        //noinspection SimplifiableIfStatement
         ListenerInfo li = mListenerInfo;
+        //noinspection SimplifiableIfStatement
         if (li != null && li.mOnHoverListener != null
                 && (mViewFlags & ENABLED_MASK) == ENABLED
                 && li.mOnHoverListener.onHover(this, event)) {
@@ -7864,21 +8113,17 @@
     public boolean onKeyDown(int keyCode, KeyEvent event) {
         boolean result = false;
 
-        switch (keyCode) {
-            case KeyEvent.KEYCODE_DPAD_CENTER:
-            case KeyEvent.KEYCODE_ENTER: {
-                if ((mViewFlags & ENABLED_MASK) == DISABLED) {
-                    return true;
-                }
-                // Long clickable items don't necessarily have to be clickable
-                if (((mViewFlags & CLICKABLE) == CLICKABLE ||
-                        (mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) &&
-                        (event.getRepeatCount() == 0)) {
-                    setPressed(true);
-                    checkForLongClick(0);
-                    return true;
-                }
-                break;
+        if (KeyEvent.isConfirmKey(keyCode)) {
+            if ((mViewFlags & ENABLED_MASK) == DISABLED) {
+                return true;
+            }
+            // Long clickable items don't necessarily have to be clickable
+            if (((mViewFlags & CLICKABLE) == CLICKABLE ||
+                    (mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) &&
+                    (event.getRepeatCount() == 0)) {
+                setPressed(true);
+                checkForLongClick(0);
+                return true;
             }
         }
         return result;
@@ -7910,28 +8155,21 @@
      * @param event   The KeyEvent object that defines the button action.
      */
     public boolean onKeyUp(int keyCode, KeyEvent event) {
-        boolean result = false;
+        if (KeyEvent.isConfirmKey(keyCode)) {
+            if ((mViewFlags & ENABLED_MASK) == DISABLED) {
+                return true;
+            }
+            if ((mViewFlags & CLICKABLE) == CLICKABLE && isPressed()) {
+                setPressed(false);
 
-        switch (keyCode) {
-            case KeyEvent.KEYCODE_DPAD_CENTER:
-            case KeyEvent.KEYCODE_ENTER: {
-                if ((mViewFlags & ENABLED_MASK) == DISABLED) {
-                    return true;
+                if (!mHasPerformedLongPress) {
+                    // This is a tap, so remove the longpress check
+                    removeLongPressCallback();
+                    return performClick();
                 }
-                if ((mViewFlags & CLICKABLE) == CLICKABLE && isPressed()) {
-                    setPressed(false);
-
-                    if (!mHasPerformedLongPress) {
-                        // This is a tap, so remove the longpress check
-                        removeLongPressCallback();
-
-                        result = performClick();
-                    }
-                }
-                break;
             }
         }
-        return result;
+        return false;
     }
 
     /**
@@ -8295,6 +8533,17 @@
 
     /**
      * Implement this method to handle touch screen motion events.
+     * <p>
+     * If this method is used to detect click actions, it is recommended that
+     * the actions be performed by implementing and calling
+     * {@link #performClick()}. This will ensure consistent system behavior,
+     * including:
+     * <ul>
+     * <li>obeying click sound preferences
+     * <li>dispatching OnClickListener calls
+     * <li>handling {@link AccessibilityNodeInfo#ACTION_CLICK ACTION_CLICK} when
+     * accessibility features are enabled
+     * </ul>
      *
      * @param event The motion event.
      * @return True if the event was handled, false otherwise.
@@ -8527,6 +8776,10 @@
      * @param mask Constant indicating the bit range that should be changed
      */
     void setFlags(int flags, int mask) {
+        final boolean accessibilityEnabled =
+                AccessibilityManager.getInstance(mContext).isEnabled();
+        final boolean oldIncludeForAccessibility = accessibilityEnabled && includeForAccessibility();
+
         int old = mViewFlags;
         mViewFlags = (mViewFlags & ~mask) | (flags & mask);
 
@@ -8551,12 +8804,10 @@
                  */
                 if (mParent != null) mParent.focusableViewAvailable(this);
             }
-            if (AccessibilityManager.getInstance(mContext).isEnabled()) {
-                notifyAccessibilityStateChanged();
-            }
         }
 
-        if ((flags & VISIBILITY_MASK) == VISIBLE) {
+        final int newVisibility = flags & VISIBILITY_MASK;
+        if (newVisibility == VISIBLE) {
             if ((changed & VISIBILITY_MASK) != 0) {
                 /*
                  * If this view is becoming visible, invalidate it in case it changed while
@@ -8622,14 +8873,19 @@
         }
 
         if ((changed & VISIBILITY_MASK) != 0) {
+            // If the view is invisible, cleanup its display list to free up resources
+            if (newVisibility != VISIBLE) {
+                cleanupDraw();
+            }
+
             if (mParent instanceof ViewGroup) {
                 ((ViewGroup) mParent).onChildVisibilityChanged(this,
-                        (changed & VISIBILITY_MASK), (flags & VISIBILITY_MASK));
+                        (changed & VISIBILITY_MASK), newVisibility);
                 ((View) mParent).invalidate(true);
             } else if (mParent != null) {
                 mParent.invalidateChild(this, null);
             }
-            dispatchVisibilityChanged(this, (flags & VISIBILITY_MASK));
+            dispatchVisibilityChanged(this, newVisibility);
         }
 
         if ((changed & WILL_NOT_CACHE_DRAWING) != 0) {
@@ -8668,19 +8924,30 @@
             }
         }
 
-        if (AccessibilityManager.getInstance(mContext).isEnabled()
-                && ((changed & FOCUSABLE) != 0 || (changed & CLICKABLE) != 0
-                        || (changed & LONG_CLICKABLE) != 0 || (changed & ENABLED) != 0)) {
-            notifyAccessibilityStateChanged();
+        if (accessibilityEnabled) {
+            if ((changed & FOCUSABLE_MASK) != 0 || (changed & VISIBILITY_MASK) != 0
+                    || (changed & CLICKABLE) != 0 || (changed & LONG_CLICKABLE) != 0) {
+                if (oldIncludeForAccessibility != includeForAccessibility()) {
+                    notifySubtreeAccessibilityStateChangedIfNeeded();
+                } else {
+                    notifyViewAccessibilityStateChangedIfNeeded(
+                            AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
+                }
+            } else if ((changed & ENABLED_MASK) != 0) {
+                notifyViewAccessibilityStateChangedIfNeeded(
+                        AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
+            }
         }
     }
 
     /**
      * Change the view's z order in the tree, so it's on top of other sibling
      * views. This ordering change may affect layout, if the parent container
-     * uses an order-dependent layout scheme (e.g., LinearLayout). This
+     * uses an order-dependent layout scheme (e.g., LinearLayout). Prior
+     * to {@link android.os.Build.VERSION_CODES#KITKAT} this
      * method should be followed by calls to {@link #requestLayout()} and
-     * {@link View#invalidate()} on the parent.
+     * {@link View#invalidate()} on the view's parent to force the parent to redraw
+     * with the new child ordering.
      *
      * @see ViewGroup#bringChildToFront(View)
      */
@@ -9378,9 +9645,11 @@
      */
     public void setPivotX(float pivotX) {
         ensureTransformationInfo();
-        mPrivateFlags |= PFLAG_PIVOT_EXPLICITLY_SET;
         final TransformationInfo info = mTransformationInfo;
-        if (info.mPivotX != pivotX) {
+        boolean pivotSet = (mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) ==
+                PFLAG_PIVOT_EXPLICITLY_SET;
+        if (info.mPivotX != pivotX || !pivotSet) {
+            mPrivateFlags |= PFLAG_PIVOT_EXPLICITLY_SET;
             invalidateViewProperty(true, false);
             info.mPivotX = pivotX;
             info.mMatrixDirty = true;
@@ -9428,9 +9697,11 @@
      */
     public void setPivotY(float pivotY) {
         ensureTransformationInfo();
-        mPrivateFlags |= PFLAG_PIVOT_EXPLICITLY_SET;
         final TransformationInfo info = mTransformationInfo;
-        if (info.mPivotY != pivotY) {
+        boolean pivotSet = (mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) ==
+                PFLAG_PIVOT_EXPLICITLY_SET;
+        if (info.mPivotY != pivotY || !pivotSet) {
+            mPrivateFlags |= PFLAG_PIVOT_EXPLICITLY_SET;
             invalidateViewProperty(true, false);
             info.mPivotY = pivotY;
             info.mMatrixDirty = true;
@@ -9981,8 +10252,10 @@
      * is inside the view, where the area of the view is expanded by the slop factor.
      * This method is called while processing touch-move events to determine if the event
      * is still within the view.
+     *
+     * @hide
      */
-    private boolean pointInView(float localX, float localY, float slop) {
+    public boolean pointInView(float localX, float localY, float slop) {
         return localX >= -slop && localY >= -slop && localX < ((mRight - mLeft) + slop) &&
                 localY < ((mBottom - mTop) + slop);
     }
@@ -11715,9 +11988,12 @@
             mPrivateFlags &= ~PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH;
         }
 
+        mPrivateFlags3 &= ~PFLAG3_IS_LAID_OUT;
+
         jumpDrawablesToCurrentState();
 
-        clearAccessibilityFocus();
+        resetSubtreeAccessibilityStateChanged();
+
         if (isFocused()) {
             InputMethodManager imm = InputMethodManager.peekInstance();
             imm.focusIn(this);
@@ -11855,10 +12131,15 @@
                     if (!canResolveLayoutDirection()) return false;
 
                     // Parent has not yet resolved, LTR is still the default
-                    if (!mParent.isLayoutDirectionResolved()) return false;
+                    try {
+                        if (!mParent.isLayoutDirectionResolved()) return false;
 
-                    if (mParent.getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
-                        mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL;
+                        if (mParent.getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
+                            mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL;
+                        }
+                    } catch (AbstractMethodError e) {
+                        Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
+                                " does not fully implement ViewParent", e);
                     }
                     break;
                 case LAYOUT_DIRECTION_RTL:
@@ -11884,13 +12165,20 @@
      * Check if layout direction resolution can be done.
      *
      * @return true if layout direction resolution can be done otherwise return false.
-     *
-     * @hide
      */
     public boolean canResolveLayoutDirection() {
         switch (getRawLayoutDirection()) {
             case LAYOUT_DIRECTION_INHERIT:
-                return (mParent != null) && mParent.canResolveLayoutDirection();
+                if (mParent != null) {
+                    try {
+                        return mParent.canResolveLayoutDirection();
+                    } catch (AbstractMethodError e) {
+                        Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
+                                " does not fully implement ViewParent", e);
+                    }
+                }
+                return false;
+
             default:
                 return true;
         }
@@ -11918,7 +12206,6 @@
 
     /**
      * @return true if layout direction has been resolved.
-     * @hide
      */
     public boolean isLayoutDirectionResolved() {
         return (mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_RESOLVED) == PFLAG2_LAYOUT_DIRECTION_RESOLVED;
@@ -11934,17 +12221,19 @@
     }
 
     /**
-     * Resolve padding depending on layout direction.
+     * Resolves padding depending on layout direction, if applicable, and
+     * recomputes internal padding values to adjust for scroll bars.
      *
      * @hide
      */
     public void resolvePadding() {
+        final int resolvedLayoutDirection = getLayoutDirection();
+
         if (!isRtlCompatibilityMode()) {
             // Post Jelly Bean MR1 case: we need to take the resolved layout direction into account.
             // If start / end padding are defined, they will be resolved (hence overriding) to
             // left / right or right / left depending on the resolved layout direction.
             // If start / end padding are not defined, use the left / right ones.
-            int resolvedLayoutDirection = getLayoutDirection();
             switch (resolvedLayoutDirection) {
                 case LAYOUT_DIRECTION_RTL:
                     if (mUserPaddingStart != UNDEFINED_PADDING) {
@@ -11973,12 +12262,11 @@
             }
 
             mUserPaddingBottom = (mUserPaddingBottom >= 0) ? mUserPaddingBottom : mPaddingBottom;
-
-            internalSetPadding(mUserPaddingLeft, mPaddingTop, mUserPaddingRight,
-                    mUserPaddingBottom);
-            onRtlPropertiesChanged(resolvedLayoutDirection);
         }
 
+        internalSetPadding(mUserPaddingLeft, mPaddingTop, mUserPaddingRight, mUserPaddingBottom);
+        onRtlPropertiesChanged(resolvedLayoutDirection);
+
         mPrivateFlags2 |= PFLAG2_PADDING_RESOLVED;
     }
 
@@ -11999,6 +12287,7 @@
      */
     protected void onDetachedFromWindow() {
         mPrivateFlags &= ~PFLAG_CANCEL_NEXT_UP_EVENT;
+        mPrivateFlags3 &= ~PFLAG3_IS_LAID_OUT;
 
         removeUnsetPressCallback();
         removeLongPressCallback();
@@ -12006,9 +12295,14 @@
         removeSendViewScrolledAccessibilityEventCallback();
 
         destroyDrawingCache();
-
         destroyLayer(false);
 
+        cleanupDraw();
+
+        mCurrentAnimation = null;
+    }
+
+    private void cleanupDraw() {
         if (mAttachInfo != null) {
             if (mDisplayList != null) {
                 mDisplayList.markDirty();
@@ -12017,12 +12311,11 @@
             mAttachInfo.mViewRootImpl.cancelInvalidate(this);
         } else {
             // Should never happen
-            clearDisplayList();
+            resetDisplayList();
         }
+    }
 
-        mCurrentAnimation = null;
-
-        resetAccessibilityStateChanged();
+    void invalidateInheritedLayoutMode(int layoutModeOfRoot) {
     }
 
     /**
@@ -12185,6 +12478,61 @@
     }
 
     /**
+     * Cancel any deferred high-level input events that were previously posted to the event queue.
+     *
+     * <p>Many views post high-level events such as click handlers to the event queue
+     * to run deferred in order to preserve a desired user experience - clearing visible
+     * pressed states before executing, etc. This method will abort any events of this nature
+     * that are currently in flight.</p>
+     *
+     * <p>Custom views that generate their own high-level deferred input events should override
+     * {@link #onCancelPendingInputEvents()} and remove those pending events from the queue.</p>
+     *
+     * <p>This will also cancel pending input events for any child views.</p>
+     *
+     * <p>Note that this may not be sufficient as a debouncing strategy for clicks in all cases.
+     * This will not impact newer events posted after this call that may occur as a result of
+     * lower-level input events still waiting in the queue. If you are trying to prevent
+     * double-submitted  events for the duration of some sort of asynchronous transaction
+     * you should also take other steps to protect against unexpected double inputs e.g. calling
+     * {@link #setEnabled(boolean) setEnabled(false)} and re-enabling the view when
+     * the transaction completes, tracking already submitted transaction IDs, etc.</p>
+     */
+    public final void cancelPendingInputEvents() {
+        dispatchCancelPendingInputEvents();
+    }
+
+    /**
+     * Called by {@link #cancelPendingInputEvents()} to cancel input events in flight.
+     * Overridden by ViewGroup to dispatch. Package scoped to prevent app-side meddling.
+     */
+    void dispatchCancelPendingInputEvents() {
+        mPrivateFlags3 &= ~PFLAG3_CALLED_SUPER;
+        onCancelPendingInputEvents();
+        if ((mPrivateFlags3 & PFLAG3_CALLED_SUPER) != PFLAG3_CALLED_SUPER) {
+            throw new SuperNotCalledException("View " + getClass().getSimpleName() +
+                    " did not call through to super.onCancelPendingInputEvents()");
+        }
+    }
+
+    /**
+     * Called as the result of a call to {@link #cancelPendingInputEvents()} on this view or
+     * a parent view.
+     *
+     * <p>This method is responsible for removing any pending high-level input events that were
+     * posted to the event queue to run later. Custom view classes that post their own deferred
+     * high-level events via {@link #post(Runnable)}, {@link #postDelayed(Runnable, long)} or
+     * {@link android.os.Handler} should override this method, call
+     * <code>super.onCancelPendingInputEvents()</code> and remove those callbacks as appropriate.
+     * </p>
+     */
+    public void onCancelPendingInputEvents() {
+        removePerformClickCallback();
+        cancelLongPress();
+        mPrivateFlags3 |= PFLAG3_CALLED_SUPER;
+    }
+
+    /**
      * Store this view hierarchy's frozen state into the given container.
      *
      * @param container The SparseArray in which to save the view's state.
@@ -12519,16 +12867,26 @@
     public void buildLayer() {
         if (mLayerType == LAYER_TYPE_NONE) return;
 
-        if (mAttachInfo == null) {
+        final AttachInfo attachInfo = mAttachInfo;
+        if (attachInfo == null) {
             throw new IllegalStateException("This view must be attached to a window first");
         }
 
         switch (mLayerType) {
             case LAYER_TYPE_HARDWARE:
-                if (mAttachInfo.mHardwareRenderer != null &&
-                        mAttachInfo.mHardwareRenderer.isEnabled() &&
-                        mAttachInfo.mHardwareRenderer.validate()) {
+                if (attachInfo.mHardwareRenderer != null &&
+                        attachInfo.mHardwareRenderer.isEnabled() &&
+                        attachInfo.mHardwareRenderer.validate()) {
                     getHardwareLayer();
+                    // TODO: We need a better way to handle this case
+                    // If views have registered pre-draw listeners they need
+                    // to be notified before we build the layer. Those listeners
+                    // may however rely on other events to happen first so we
+                    // cannot just invoke them here until they don't cancel the
+                    // current frame
+                    if (!attachInfo.mTreeObserver.hasOnPreDrawListeners()) {
+                        attachInfo.mViewRootImpl.dispatchFlushHardwareLayerUpdates();
+                    }
                 }
                 break;
             case LAYER_TYPE_SOFTWARE:
@@ -12614,12 +12972,11 @@
             if (info != null && info.mHardwareRenderer != null &&
                     info.mHardwareRenderer.isEnabled() &&
                     (valid || info.mHardwareRenderer.validate())) {
+
+                info.mHardwareRenderer.cancelLayerUpdate(mHardwareLayer);
                 mHardwareLayer.destroy();
                 mHardwareLayer = null;
 
-                if (mDisplayList != null) {
-                    mDisplayList.reset();
-                }
                 invalidate(true);
                 invalidateParentCaches();
             }
@@ -12640,6 +12997,7 @@
      * @hide
      */
     protected void destroyHardwareResources() {
+        resetDisplayList();
         destroyLayer(true);
     }
 
@@ -12784,8 +13142,7 @@
                 mRecreateDisplayList = true;
             }
             if (displayList == null) {
-                final String name = getClass().getSimpleName();
-                displayList = mAttachInfo.mHardwareRenderer.createDisplayList(name);
+                displayList = mAttachInfo.mHardwareRenderer.createDisplayList(getClass().getName());
                 // If we're creating a new display list, make sure our parent gets invalidated
                 // since they will need to recreate their display list to account for this
                 // new child display list.
@@ -12888,6 +13245,12 @@
         }
     }
 
+    private void resetDisplayList() {
+        if (mDisplayList != null) {
+            mDisplayList.reset();
+        }
+    }
+
     /**
      * <p>Calling this method is equivalent to calling <code>getDrawingCache(false)</code>.</p>
      *
@@ -13060,14 +13423,8 @@
                     // Keep the DRAWING_CACHE_QUALITY_LOW flag just in case
                     switch (mViewFlags & DRAWING_CACHE_QUALITY_MASK) {
                         case DRAWING_CACHE_QUALITY_AUTO:
-                            quality = Bitmap.Config.ARGB_8888;
-                            break;
                         case DRAWING_CACHE_QUALITY_LOW:
-                            quality = Bitmap.Config.ARGB_8888;
-                            break;
                         case DRAWING_CACHE_QUALITY_HIGH:
-                            quality = Bitmap.Config.ARGB_8888;
-                            break;
                         default:
                             quality = Bitmap.Config.ARGB_8888;
                             break;
@@ -13222,6 +13579,9 @@
         // Fast path for layouts with no backgrounds
         if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
             dispatchDraw(canvas);
+            if (mOverlay != null && !mOverlay.isEmpty()) {
+                mOverlay.getOverlayView().draw(canvas);
+            }
         } else {
             draw(canvas);
         }
@@ -13432,7 +13792,8 @@
             onAnimationStart();
         }
 
-        boolean more = a.getTransformation(drawingTime, parent.mChildTransformation, 1f);
+        final Transformation t = parent.getChildTransformation();
+        boolean more = a.getTransformation(drawingTime, t, 1f);
         if (scalingRequired && mAttachInfo.mApplicationScale != 1f) {
             if (parent.mInvalidationTransformation == null) {
                 parent.mInvalidationTransformation = new Transformation();
@@ -13440,7 +13801,7 @@
             invalidationTransform = parent.mInvalidationTransformation;
             a.getTransformation(drawingTime, invalidationTransform, 1f);
         } else {
-            invalidationTransform = parent.mChildTransformation;
+            invalidationTransform = t;
         }
 
         if (more) {
@@ -13493,17 +13854,15 @@
             if (mParent instanceof ViewGroup && (((ViewGroup) mParent).mGroupFlags &
                     ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
                 ViewGroup parentVG = (ViewGroup) mParent;
-                final boolean hasTransform =
-                        parentVG.getChildStaticTransformation(this, parentVG.mChildTransformation);
-                if (hasTransform) {
-                    Transformation transform = parentVG.mChildTransformation;
-                    final int transformType = parentVG.mChildTransformation.getTransformationType();
+                final Transformation t = parentVG.getChildTransformation();
+                if (parentVG.getChildStaticTransformation(this, t)) {
+                    final int transformType = t.getTransformationType();
                     if (transformType != Transformation.TYPE_IDENTITY) {
                         if ((transformType & Transformation.TYPE_ALPHA) != 0) {
-                            alpha = transform.getAlpha();
+                            alpha = t.getAlpha();
                         }
                         if ((transformType & Transformation.TYPE_MATRIX) != 0) {
-                            displayList.setMatrix(transform.getMatrix());
+                            displayList.setMatrix(t.getMatrix());
                         }
                     }
                 }
@@ -13548,7 +13907,7 @@
         final int flags = parent.mGroupFlags;
 
         if ((flags & ViewGroup.FLAG_CLEAR_TRANSFORMATION) == ViewGroup.FLAG_CLEAR_TRANSFORMATION) {
-            parent.mChildTransformation.clear();
+            parent.getChildTransformation().clear();
             parent.mGroupFlags &= ~ViewGroup.FLAG_CLEAR_TRANSFORMATION;
         }
 
@@ -13576,7 +13935,7 @@
             if (concatMatrix) {
                 mPrivateFlags3 |= PFLAG3_VIEW_IS_ANIMATING_TRANSFORM;
             }
-            transformToApply = parent.mChildTransformation;
+            transformToApply = parent.getChildTransformation();
         } else {
             if ((mPrivateFlags3 & PFLAG3_VIEW_IS_ANIMATING_TRANSFORM) ==
                     PFLAG3_VIEW_IS_ANIMATING_TRANSFORM && mDisplayList != null) {
@@ -13586,12 +13945,11 @@
             }
             if (!useDisplayListProperties &&
                     (flags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
-                final boolean hasTransform =
-                        parent.getChildStaticTransformation(this, parent.mChildTransformation);
+                final Transformation t = parent.getChildTransformation();
+                final boolean hasTransform = parent.getChildStaticTransformation(this, t);
                 if (hasTransform) {
-                    final int transformType = parent.mChildTransformation.getTransformationType();
-                    transformToApply = transformType != Transformation.TYPE_IDENTITY ?
-                            parent.mChildTransformation : null;
+                    final int transformType = t.getTransformationType();
+                    transformToApply = transformType != Transformation.TYPE_IDENTITY ? t : null;
                     concatMatrix = (transformType & Transformation.TYPE_MATRIX) != 0;
                 }
             }
@@ -13867,10 +14225,6 @@
         }
 
         if (more && hardwareAccelerated) {
-            // invalidation is the trigger to recreate display lists, so if we're using
-            // display lists to render, force an invalidate to allow the animation to
-            // continue drawing another frame
-            parent.invalidate(true);
             if (a.hasAlpha() && (mPrivateFlags & PFLAG_ALPHA_SET) == PFLAG_ALPHA_SET) {
                 // alpha animations should cause the child to recreate its display list
                 invalidate(true);
@@ -14280,12 +14634,19 @@
      */
     @SuppressWarnings({"unchecked"})
     public void layout(int l, int t, int r, int b) {
+        if ((mPrivateFlags3 & PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT) != 0) {
+            onMeasure(mOldWidthMeasureSpec, mOldHeightMeasureSpec);
+            mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
+        }
+
         int oldL = mLeft;
         int oldT = mTop;
         int oldB = mBottom;
         int oldR = mRight;
+
         boolean changed = isLayoutModeOptical(mParent) ?
                 setOpticalFrame(l, t, r, b) : setFrame(l, t, r, b);
+
         if (changed || (mPrivateFlags & PFLAG_LAYOUT_REQUIRED) == PFLAG_LAYOUT_REQUIRED) {
             onLayout(changed, l, t, r, b);
             mPrivateFlags &= ~PFLAG_LAYOUT_REQUIRED;
@@ -14300,7 +14661,9 @@
                 }
             }
         }
+
         mPrivateFlags &= ~PFLAG_FORCE_LAYOUT;
+        mPrivateFlags3 |= PFLAG3_IS_LAID_OUT;
     }
 
     /**
@@ -14393,6 +14756,8 @@
             mPrivateFlags |= drawn;
 
             mBackgroundSizeChanged = true;
+
+            notifySubtreeAccessibilityStateChangedIfNeeded();
         }
         return changed;
     }
@@ -14503,13 +14868,26 @@
      * @hide
      */
     protected void resolveDrawables() {
-        if (canResolveLayoutDirection()) {
-            if (mBackground != null) {
-                mBackground.setLayoutDirection(getLayoutDirection());
-            }
-            mPrivateFlags2 |= PFLAG2_DRAWABLE_RESOLVED;
-            onResolveDrawables(getLayoutDirection());
+        // Drawables resolution may need to happen before resolving the layout direction (which is
+        // done only during the measure() call).
+        // If the layout direction is not resolved yet, we cannot resolve the Drawables except in
+        // one case: when the raw layout direction has not been defined as LAYOUT_DIRECTION_INHERIT.
+        // So, if the raw layout direction is LAYOUT_DIRECTION_LTR or LAYOUT_DIRECTION_RTL or
+        // LAYOUT_DIRECTION_LOCALE, we can "cheat" and we don't need to wait for the layout
+        // direction to be resolved as its resolved value will be the same as its raw value.
+        if (!isLayoutDirectionResolved() &&
+                getRawLayoutDirection() == View.LAYOUT_DIRECTION_INHERIT) {
+            return;
         }
+
+        final int layoutDirection = isLayoutDirectionResolved() ?
+                getLayoutDirection() : getRawLayoutDirection();
+
+        if (mBackground != null) {
+            mBackground.setLayoutDirection(layoutDirection);
+        }
+        mPrivateFlags2 |= PFLAG2_DRAWABLE_RESOLVED;
+        onResolveDrawables(layoutDirection);
     }
 
     /**
@@ -15151,15 +15529,15 @@
      * @param selected true if the view must be selected, false otherwise
      */
     public void setSelected(boolean selected) {
+        //noinspection DoubleNegation
         if (((mPrivateFlags & PFLAG_SELECTED) != 0) != selected) {
             mPrivateFlags = (mPrivateFlags & ~PFLAG_SELECTED) | (selected ? PFLAG_SELECTED : 0);
             if (!selected) resetPressedState();
             invalidate(true);
             refreshDrawableState();
             dispatchSetSelected(selected);
-            if (AccessibilityManager.getInstance(mContext).isEnabled()) {
-                notifyAccessibilityStateChanged();
-            }
+            notifyViewAccessibilityStateChangedIfNeeded(
+                    AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
         }
     }
 
@@ -15197,6 +15575,7 @@
      * @param activated true if the view must be activated, false otherwise
      */
     public void setActivated(boolean activated) {
+        //noinspection DoubleNegation
         if (((mPrivateFlags & PFLAG_ACTIVATED) != 0) != activated) {
             mPrivateFlags = (mPrivateFlags & ~PFLAG_ACTIVATED) | (activated ? PFLAG_ACTIVATED : 0);
             invalidate(true);
@@ -15270,6 +15649,90 @@
     }
 
     /**
+     * Transforms a motion event from view-local coordinates to on-screen
+     * coordinates.
+     *
+     * @param ev the view-local motion event
+     * @return false if the transformation could not be applied
+     * @hide
+     */
+    public boolean toGlobalMotionEvent(MotionEvent ev) {
+        final AttachInfo info = mAttachInfo;
+        if (info == null) {
+            return false;
+        }
+
+        transformMotionEventToGlobal(ev);
+        ev.offsetLocation(info.mWindowLeft, info.mWindowTop);
+        return true;
+    }
+
+    /**
+     * Transforms a motion event from on-screen coordinates to view-local
+     * coordinates.
+     *
+     * @param ev the on-screen motion event
+     * @return false if the transformation could not be applied
+     * @hide
+     */
+    public boolean toLocalMotionEvent(MotionEvent ev) {
+        final AttachInfo info = mAttachInfo;
+        if (info == null) {
+            return false;
+        }
+
+        ev.offsetLocation(-info.mWindowLeft, -info.mWindowTop);
+        transformMotionEventToLocal(ev);
+        return true;
+    }
+
+    /**
+     * Recursive helper method that applies transformations in post-order.
+     *
+     * @param ev the on-screen motion event
+     */
+    private void transformMotionEventToLocal(MotionEvent ev) {
+        final ViewParent parent = mParent;
+        if (parent instanceof View) {
+            final View vp = (View) parent;
+            vp.transformMotionEventToLocal(ev);
+            ev.offsetLocation(vp.mScrollX, vp.mScrollY);
+        } else if (parent instanceof ViewRootImpl) {
+            final ViewRootImpl vr = (ViewRootImpl) parent;
+            ev.offsetLocation(0, vr.mCurScrollY);
+        }
+
+        ev.offsetLocation(-mLeft, -mTop);
+
+        if (!hasIdentityMatrix()) {
+            ev.transform(getInverseMatrix());
+        }
+    }
+
+    /**
+     * Recursive helper method that applies transformations in pre-order.
+     *
+     * @param ev the on-screen motion event
+     */
+    private void transformMotionEventToGlobal(MotionEvent ev) {
+        if (!hasIdentityMatrix()) {
+            ev.transform(getMatrix());
+        }
+
+        ev.offsetLocation(mLeft, mTop);
+
+        final ViewParent parent = mParent;
+        if (parent instanceof View) {
+            final View vp = (View) parent;
+            ev.offsetLocation(-vp.mScrollX, -vp.mScrollY);
+            vp.transformMotionEventToGlobal(ev);
+        } else if (parent instanceof ViewRootImpl) {
+            final ViewRootImpl vr = (ViewRootImpl) parent;
+            ev.offsetLocation(0, -vr.mCurScrollY);
+        }
+    }
+
+    /**
      * <p>Computes the coordinates of this view on the screen. The argument
      * must be an array of two integers. After the method returns, the array
      * contains the x and y location in that order.</p>
@@ -15637,7 +16100,7 @@
 
     private void setKeyedTag(int key, Object tag) {
         if (mKeyedTags == null) {
-            mKeyedTags = new SparseArray<Object>();
+            mKeyedTags = new SparseArray<Object>(2);
         }
 
         mKeyedTags.put(key, tag);
@@ -15774,6 +16237,8 @@
      * handle possible request-during-layout errors correctly.</p>
      */
     public void requestLayout() {
+        if (mMeasureCache != null) mMeasureCache.clear();
+
         if (mAttachInfo != null && mAttachInfo.mViewRequestingLayout == null) {
             // Only trigger request-during-layout logic if this is the view requesting it,
             // not the views in its parent hierarchy
@@ -15803,6 +16268,8 @@
      * on the parent.
      */
     public void forceLayout() {
+        if (mMeasureCache != null) mMeasureCache.clear();
+
         mPrivateFlags |= PFLAG_FORCE_LAYOUT;
         mPrivateFlags |= PFLAG_INVALIDATED;
     }
@@ -15836,6 +16303,11 @@
             widthMeasureSpec  = MeasureSpec.adjust(widthMeasureSpec,  optical ? -oWidth  : oWidth);
             heightMeasureSpec = MeasureSpec.adjust(heightMeasureSpec, optical ? -oHeight : oHeight);
         }
+
+        // Suppress sign extension for the low bytes
+        long key = (long) widthMeasureSpec << 32 | (long) heightMeasureSpec & 0xffffffffL;
+        if (mMeasureCache == null) mMeasureCache = new LongSparseLongArray(2);
+
         if ((mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT ||
                 widthMeasureSpec != mOldWidthMeasureSpec ||
                 heightMeasureSpec != mOldHeightMeasureSpec) {
@@ -15845,8 +16317,18 @@
 
             resolveRtlPropertiesIfNeeded();
 
-            // measure ourselves, this should set the measured dimension flag back
-            onMeasure(widthMeasureSpec, heightMeasureSpec);
+            int cacheIndex = (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT ? -1 :
+                    mMeasureCache.indexOfKey(key);
+            if (cacheIndex < 0) {
+                // measure ourselves, this should set the measured dimension flag back
+                onMeasure(widthMeasureSpec, heightMeasureSpec);
+                mPrivateFlags3 &= ~PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
+            } else {
+                long value = mMeasureCache.valueAt(cacheIndex);
+                // Casting a long to int drops the high 32 bits, no mask needed
+                setMeasuredDimension((int) (value >> 32), (int) value);
+                mPrivateFlags3 |= PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
+            }
 
             // flag not set, setMeasuredDimension() was not invoked, we raise
             // an exception to warn the developer
@@ -15861,6 +16343,9 @@
 
         mOldWidthMeasureSpec = widthMeasureSpec;
         mOldHeightMeasureSpec = heightMeasureSpec;
+
+        mMeasureCache.put(key, ((long) mMeasuredWidth) << 32 |
+                (long) mMeasuredHeight & 0xffffffffL); // suppress sign extension
     }
 
     /**
@@ -16352,7 +16837,9 @@
      * @param visibility  Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE},
      * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, {@link #SYSTEM_UI_FLAG_FULLSCREEN},
      * {@link #SYSTEM_UI_FLAG_LAYOUT_STABLE}, {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION},
-     * and {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}.
+     * {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}, {@link #SYSTEM_UI_FLAG_IMMERSIVE},
+     * {@link #SYSTEM_UI_FLAG_TRANSPARENT_STATUS},
+     * and {@link #SYSTEM_UI_FLAG_TRANSPARENT_NAVIGATION}.
      */
     public void setSystemUiVisibility(int visibility) {
         if (visibility != mSystemUiVisibility) {
@@ -16364,11 +16851,13 @@
     }
 
     /**
-     * Returns the last {@link #setSystemUiVisibility(int) that this view has requested.
+     * Returns the last {@link #setSystemUiVisibility(int)} that this view has requested.
      * @return  Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE},
      * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}, {@link #SYSTEM_UI_FLAG_FULLSCREEN},
      * {@link #SYSTEM_UI_FLAG_LAYOUT_STABLE}, {@link #SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION},
-     * and {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}.
+     * {@link #SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}, {@link #SYSTEM_UI_FLAG_IMMERSIVE},
+     * {@link #SYSTEM_UI_FLAG_TRANSPARENT_STATUS},
+     * and {@link #SYSTEM_UI_FLAG_TRANSPARENT_NAVIGATION}.
      */
     public int getSystemUiVisibility() {
         return mSystemUiVisibility;
@@ -16387,7 +16876,7 @@
     /**
      * Override to find out when the window's requested system UI visibility
      * has changed, that is the value returned by {@link #getWindowSystemUiVisibility()}.
-     * This is different from the callbacks recieved through
+     * This is different from the callbacks received through
      * {@link #setOnSystemUiVisibilityChangeListener(OnSystemUiVisibilityChangeListener)}
      * in that this is only telling you about the local request of the window,
      * not the actual values applied by the system.
@@ -16706,8 +17195,8 @@
      * </p>
      */
     public boolean dispatchDragEvent(DragEvent event) {
-        //noinspection SimplifiableIfStatement
         ListenerInfo li = mListenerInfo;
+        //noinspection SimplifiableIfStatement
         if (li != null && li.mOnDragListener != null && (mViewFlags & ENABLED_MASK) == ENABLED
                 && li.mOnDragListener.onDrag(this, event)) {
             return true;
@@ -17072,14 +17561,29 @@
                     }
 
                     // Parent has not yet resolved, so we still return the default
-                    if (!mParent.isTextDirectionResolved()) {
-                        mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
-                        // Resolution will need to happen again later
-                        return false;
+                    try {
+                        if (!mParent.isTextDirectionResolved()) {
+                            mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
+                            // Resolution will need to happen again later
+                            return false;
+                        }
+                    } catch (AbstractMethodError e) {
+                        Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
+                                " does not fully implement ViewParent", e);
+                        mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED |
+                                PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
+                        return true;
                     }
 
                     // Set current resolved direction to the same value as the parent's one
-                    final int parentResolvedDirection = mParent.getTextDirection();
+                    int parentResolvedDirection;
+                    try {
+                        parentResolvedDirection = mParent.getTextDirection();
+                    } catch (AbstractMethodError e) {
+                        Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
+                                " does not fully implement ViewParent", e);
+                        parentResolvedDirection = TEXT_DIRECTION_LTR;
+                    }
                     switch (parentResolvedDirection) {
                         case TEXT_DIRECTION_FIRST_STRONG:
                         case TEXT_DIRECTION_ANY_RTL:
@@ -17120,13 +17624,20 @@
      * Check if text direction resolution can be done.
      *
      * @return true if text direction resolution can be done otherwise return false.
-     *
-     * @hide
      */
     public boolean canResolveTextDirection() {
         switch (getRawTextDirection()) {
             case TEXT_DIRECTION_INHERIT:
-                return (mParent != null) && mParent.canResolveTextDirection();
+                if (mParent != null) {
+                    try {
+                        return mParent.canResolveTextDirection();
+                    } catch (AbstractMethodError e) {
+                        Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
+                                " does not fully implement ViewParent", e);
+                    }
+                }
+                return false;
+
             default:
                 return true;
         }
@@ -17156,8 +17667,6 @@
 
     /**
      * @return true if text direction is resolved.
-     *
-     * @hide
      */
     public boolean isTextDirectionResolved() {
         return (mPrivateFlags2 & PFLAG2_TEXT_DIRECTION_RESOLVED) == PFLAG2_TEXT_DIRECTION_RESOLVED;
@@ -17284,13 +17793,28 @@
                     }
 
                     // Parent has not yet resolved, so we still return the default
-                    if (!mParent.isTextAlignmentResolved()) {
-                        mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
-                        // Resolution will need to happen again later
-                        return false;
+                    try {
+                        if (!mParent.isTextAlignmentResolved()) {
+                            mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
+                            // Resolution will need to happen again later
+                            return false;
+                        }
+                    } catch (AbstractMethodError e) {
+                        Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
+                                " does not fully implement ViewParent", e);
+                        mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED |
+                                PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
+                        return true;
                     }
 
-                    final int parentResolvedTextAlignment = mParent.getTextAlignment();
+                    int parentResolvedTextAlignment;
+                    try {
+                        parentResolvedTextAlignment = mParent.getTextAlignment();
+                    } catch (AbstractMethodError e) {
+                        Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
+                                " does not fully implement ViewParent", e);
+                        parentResolvedTextAlignment = TEXT_ALIGNMENT_GRAVITY;
+                    }
                     switch (parentResolvedTextAlignment) {
                         case TEXT_ALIGNMENT_GRAVITY:
                         case TEXT_ALIGNMENT_TEXT_START:
@@ -17335,13 +17859,20 @@
      * Check if text alignment resolution can be done.
      *
      * @return true if text alignment resolution can be done otherwise return false.
-     *
-     * @hide
      */
     public boolean canResolveTextAlignment() {
         switch (getRawTextAlignment()) {
             case TEXT_DIRECTION_INHERIT:
-                return (mParent != null) && mParent.canResolveTextAlignment();
+                if (mParent != null) {
+                    try {
+                        return mParent.canResolveTextAlignment();
+                    } catch (AbstractMethodError e) {
+                        Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
+                                " does not fully implement ViewParent", e);
+                    }
+                }
+                return false;
+
             default:
                 return true;
         }
@@ -17371,8 +17902,6 @@
 
     /**
      * @return true if text alignment is resolved.
-     *
-     * @hide
      */
     public boolean isTextAlignmentResolved() {
         return (mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_RESOLVED) == PFLAG2_TEXT_ALIGNMENT_RESOLVED;
@@ -18749,6 +19278,79 @@
         }
     }
 
+    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);
+                mPosted = true;
+                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/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index 499075e..c3f064f 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -97,6 +97,13 @@
     private static final int DOUBLE_TAP_TIMEOUT = 300;
 
     /**
+     * Defines the minimum duration in milliseconds between the first tap's up event and
+     * the second tap's down event for an interaction to be considered a
+     * double-tap.
+     */
+    private static final int DOUBLE_TAP_MIN_TIME = 40;
+
+    /**
      * Defines the maximum duration in milliseconds between a touch pad
      * touch and release for a given touch to be considered a tap (click) as
      * opposed to a hover movement gesture.
@@ -291,7 +298,7 @@
         if (!sHasPermanentMenuKeySet) {
             IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
             try {
-                sHasPermanentMenuKey = !wm.hasSystemNavBar() && !wm.hasNavigationBar();
+                sHasPermanentMenuKey = !wm.hasNavigationBar();
                 sHasPermanentMenuKeySet = true;
             } catch (RemoteException ex) {
                 sHasPermanentMenuKey = false;
@@ -436,6 +443,17 @@
     }
 
     /**
+     * @return the minimum duration in milliseconds between the first tap's
+     * up event and the second tap's down event for an interaction to be considered a
+     * double-tap.
+     *
+     * @hide
+     */
+    public static int getDoubleTapMinTime() {
+        return DOUBLE_TAP_MIN_TIME;
+    }
+
+    /**
      * @return the maximum duration in milliseconds between a touch pad
      * touch and release for a given touch to be considered a tap (click) as
      * opposed to a hover movement gesture.
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index ed128b0..92e5e96 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -698,6 +698,11 @@
                 captureViewLayer(group.getChildAt(i), clientStream, localVisible);
             }
         }
+
+        if (view.mOverlay != null) {
+            ViewGroup overlayContainer = view.getOverlay().mOverlayViewGroup;
+            captureViewLayer(overlayContainer, clientStream, localVisible);
+        }
     }
 
     private static void outputDisplayList(View root, String parameter) throws IOException {
@@ -743,7 +748,7 @@
         }
     }
 
-    private static Bitmap performViewCapture(final View captureView, final boolean skpiChildren) {
+    private static Bitmap performViewCapture(final View captureView, final boolean skipChildren) {
         if (captureView != null) {
             final CountDownLatch latch = new CountDownLatch(1);
             final Bitmap[] cache = new Bitmap[1];
@@ -752,7 +757,7 @@
                 public void run() {
                     try {
                         cache[0] = captureView.createSnapshot(
-                                Bitmap.Config.ARGB_8888, 0, skpiChildren);
+                                Bitmap.Config.ARGB_8888, 0, skipChildren);
                     } catch (OutOfMemoryError e) {
                         Log.w("View", "Out of memory for bitmap");
                     } finally {
@@ -815,6 +820,13 @@
             } else if (isRequestedView(view, className, hashCode)) {
                 return view;
             }
+            if (view.mOverlay != null) {
+                final View found = findView((ViewGroup) view.mOverlay.mOverlayViewGroup,
+                        className, hashCode);
+                if (found != null) {
+                    return found;
+                }
+            }
             if (view instanceof HierarchyHandler) {
                 final View found = ((HierarchyHandler)view)
                         .findHierarchyView(className, hashCode);
@@ -823,12 +835,19 @@
                 }
             }
         }
-
         return null;
     }
 
     private static boolean isRequestedView(View view, String className, int hashCode) {
-        return view.getClass().getName().equals(className) && view.hashCode() == hashCode;
+        if (view.hashCode() == hashCode) {
+            String viewClassName = view.getClass().getName();
+            if (className.equals("ViewOverlay")) {
+                return viewClassName.equals("android.view.ViewOverlay$OverlayViewGroup");
+            } else {
+                return className.equals(viewClassName);
+            }
+        }
+        return false;
     }
 
     private static void dumpViewHierarchy(Context context, ViewGroup group,
@@ -850,6 +869,12 @@
             } else {
                 dumpView(context, view, out, level + 1, includeProperties);
             }
+            if (view.mOverlay != null) {
+                ViewOverlay overlay = view.getOverlay();
+                ViewGroup overlayContainer = overlay.mOverlayViewGroup;
+                dumpViewHierarchy(context, overlayContainer, out, level + 2, skipChildren,
+                        includeProperties);
+            }
         }
         if (group instanceof HierarchyHandler) {
             ((HierarchyHandler)group).dumpViewHierarchyWithProperties(out, level + 1);
@@ -863,7 +888,11 @@
             for (int i = 0; i < level; i++) {
                 out.write(' ');
             }
-            out.write(view.getClass().getName());
+            String className = view.getClass().getName();
+            if (className.equals("android.view.ViewOverlay$OverlayViewGroup")) {
+                className = "ViewOverlay";
+            }
+            out.write(className);
             out.write('@');
             out.write(Integer.toHexString(view.hashCode()));
             out.write(' ');
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 3aa4cfb..9414237 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -38,6 +38,7 @@
 import android.util.Pools.SynchronizedPool;
 import android.util.SparseArray;
 import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
@@ -130,7 +131,7 @@
      * A Transformation used when drawing children, to
      * apply on the child being drawn.
      */
-    final Transformation mChildTransformation = new Transformation();
+    private Transformation mChildTransformation;
 
     /**
      * Used to track the current invalidation region.
@@ -154,7 +155,7 @@
     private boolean mChildAcceptsDrag;
 
     // Used during drag dispatch
-    private final PointF mLocalPoint = new PointF();
+    private PointF mLocalPoint;
 
     // Layout animation
     private LayoutAnimationController mLayoutAnimationController;
@@ -206,7 +207,7 @@
     /**
      * Either {@link #LAYOUT_MODE_CLIP_BOUNDS} or {@link #LAYOUT_MODE_OPTICAL_BOUNDS}.
      */
-    private int mLayoutMode = DEFAULT_LAYOUT_MODE;
+    private int mLayoutMode = LAYOUT_MODE_UNDEFINED;
 
     /**
      * NOTE: If you change the flags below make sure to reflect the changes
@@ -347,6 +348,14 @@
     private static final int FLAG_PREVENT_DISPATCH_ATTACHED_TO_WINDOW = 0x400000;
 
     /**
+     * When true, indicates that a layoutMode has been explicitly set, either with
+     * an explicit call to {@link #setLayoutMode(int)} in code or from an XML resource.
+     * This distinguishes the situation in which a layout mode was inherited from
+     * one of the ViewGroup's ancestors and cached locally.
+     */
+    private static final int FLAG_LAYOUT_MODE_WAS_EXPLICITLY_SET = 0x800000;
+
+    /**
      * Indicates which types of drawing caches are to be kept in memory.
      * This field should be made private, so it is hidden from the SDK.
      * {@hide}
@@ -375,6 +384,8 @@
 
     // Layout Modes
 
+    private static final int LAYOUT_MODE_UNDEFINED = -1;
+
     /**
      * This constant is a {@link #setLayoutMode(int) layoutMode}.
      * Clip bounds are the raw values of {@link #getLeft() left}, {@link #getTop() top},
@@ -391,7 +402,7 @@
     public static final int LAYOUT_MODE_OPTICAL_BOUNDS = 1;
 
     /** @hide */
-    public static int DEFAULT_LAYOUT_MODE = LAYOUT_MODE_CLIP_BOUNDS;
+    public static int LAYOUT_MODE_DEFAULT = LAYOUT_MODE_CLIP_BOUNDS;
 
     /**
      * We clip to padding when FLAG_CLIP_TO_PADDING and FLAG_PADDING_NOT_NULL
@@ -533,7 +544,7 @@
                     }
                     break;
                 case R.styleable.ViewGroup_layoutMode:
-                    setLayoutMode(a.getInt(attr, DEFAULT_LAYOUT_MODE));
+                    setLayoutMode(a.getInt(attr, LAYOUT_MODE_UNDEFINED));
                     break;
             }
         }
@@ -732,8 +743,6 @@
 
     /**
      * Called when a child view has changed whether or not it is tracking transient state.
-     *
-     * @hide
      */
     public void childHasTransientStateChanged(View child, boolean childHasTransientState) {
         final boolean oldHasTransientState = hasTransientState();
@@ -754,9 +763,6 @@
         }
     }
 
-    /**
-     * @hide
-     */
     @Override
     public boolean hasTransientState() {
         return mChildCountWithTransientState > 0 || super.hasTransientState();
@@ -1118,9 +1124,16 @@
             removeFromArray(index);
             addInArray(child, mChildrenCount);
             child.mParent = this;
+            requestLayout();
+            invalidate();
         }
     }
 
+    private PointF getLocalPoint() {
+        if (mLocalPoint == null) mLocalPoint = new PointF();
+        return mLocalPoint;
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -1134,6 +1147,8 @@
         ViewRootImpl root = getViewRootImpl();
 
         // Dispatch down the view hierarchy
+        final PointF localPoint = getLocalPoint();
+
         switch (event.mAction) {
         case DragEvent.ACTION_DRAG_STARTED: {
             // clear state to recalculate which views we drag over
@@ -1194,7 +1209,7 @@
 
         case DragEvent.ACTION_DRAG_LOCATION: {
             // Find the [possibly new] drag target
-            final View target = findFrontmostDroppableChildAt(event.mX, event.mY, mLocalPoint);
+            final View target = findFrontmostDroppableChildAt(event.mX, event.mY, localPoint);
 
             // If we've changed apparent drag target, tell the view root which view
             // we're over now [for purposes of the eventual drag-recipient-changed
@@ -1228,8 +1243,8 @@
 
             // Dispatch the actual drag location notice, localized into its coordinates
             if (target != null) {
-                event.mX = mLocalPoint.x;
-                event.mY = mLocalPoint.y;
+                event.mX = localPoint.x;
+                event.mY = localPoint.y;
 
                 retval = target.dispatchDragEvent(event);
 
@@ -1263,11 +1278,11 @@
 
         case DragEvent.ACTION_DROP: {
             if (ViewDebug.DEBUG_DRAG) Log.d(View.VIEW_LOG_TAG, "Drop event: " + event);
-            View target = findFrontmostDroppableChildAt(event.mX, event.mY, mLocalPoint);
+            View target = findFrontmostDroppableChildAt(event.mX, event.mY, localPoint);
             if (target != null) {
                 if (ViewDebug.DEBUG_DRAG) Log.d(View.VIEW_LOG_TAG, "   dispatch drop to " + target);
-                event.mX = mLocalPoint.x;
-                event.mY = mLocalPoint.y;
+                event.mX = localPoint.x;
+                event.mY = localPoint.y;
                 retval = target.dispatchDragEvent(event);
                 event.mX = tx;
                 event.mY = ty;
@@ -1690,16 +1705,6 @@
     }
 
     /**
-     * @hide
-     */
-    @Override
-    public void childAccessibilityStateChanged(View child) {
-        if (mParent != null) {
-            mParent.childAccessibilityStateChanged(child);
-        }
-    }
-
-    /**
      * Implement this method to intercept hover events before they are handled
      * by child views.
      * <p>
@@ -2523,17 +2528,29 @@
         event.setClassName(ViewGroup.class.getName());
     }
 
-    /**
-     * @hide
-     */
     @Override
-    public void resetAccessibilityStateChanged() {
-        super.resetAccessibilityStateChanged();
+    public void notifySubtreeAccessibilityStateChanged(View child, View source, int changeType) {
+        // 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);
+        } else if (mParent != null) {
+            try {
+                mParent.notifySubtreeAccessibilityStateChanged(this, source, changeType);
+            } catch (AbstractMethodError e) {
+                Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
+                        " does not fully implement ViewParent", e);
+            }
+        }
+    }
+
+    @Override
+    void resetSubtreeAccessibilityStateChanged() {
+        super.resetSubtreeAccessibilityStateChanged();
         View[] children = mChildren;
         final int childCount = mChildrenCount;
         for (int i = 0; i < childCount; i++) {
-            View child = children[i];
-            child.resetAccessibilityStateChanged();
+            children[i].resetSubtreeAccessibilityStateChanged();
         }
     }
 
@@ -2773,8 +2790,8 @@
         return (int) (dips * scale + 0.5f);
     }
 
-    private void drawRectCorners(Canvas canvas, int x1, int y1, int x2, int y2, Paint paint,
-                                 int lineLength, int lineWidth) {
+    private static void drawRectCorners(Canvas canvas, int x1, int y1, int x2, int y2, Paint paint,
+            int lineLength, int lineWidth) {
         drawCorner(canvas, paint, x1, y1, lineLength, lineLength, lineWidth);
         drawCorner(canvas, paint, x1, y2, lineLength, -lineLength, lineWidth);
         drawCorner(canvas, paint, x2, y1, -lineLength, lineLength, lineWidth);
@@ -3170,6 +3187,17 @@
         }
     }
 
+    @Override
+    void dispatchCancelPendingInputEvents() {
+        super.dispatchCancelPendingInputEvents();
+
+        final View[] children = mChildren;
+        final int count = mChildrenCount;
+        for (int i = 0; i < count; i++) {
+            children[i].dispatchCancelPendingInputEvents();
+        }
+    }
+
     /**
      * When this property is set to true, this ViewGroup supports static transformations on
      * children; this causes
@@ -3204,6 +3232,13 @@
         return false;
     }
 
+    Transformation getChildTransformation() {
+        if (mChildTransformation == null) {
+            mChildTransformation = new Transformation();
+        }
+        return mChildTransformation;
+    }
+
     /**
      * {@hide}
      */
@@ -3451,6 +3486,24 @@
         }
     }
 
+    private void clearCachedLayoutMode() {
+        if (!hasBooleanFlag(FLAG_LAYOUT_MODE_WAS_EXPLICITLY_SET)) {
+           mLayoutMode = LAYOUT_MODE_UNDEFINED;
+        }
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        clearCachedLayoutMode();
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        clearCachedLayoutMode();
+    }
+
     /**
      * Adds a view during layout. This is useful if in your onLayout() method,
      * you need to add more views (as does the list view for example).
@@ -3565,6 +3618,10 @@
         if (child.hasTransientState()) {
             childHasTransientStateChanged(child, true);
         }
+
+        if (child.isImportantForAccessibility() && child.getVisibility() != View.GONE) {
+            notifySubtreeAccessibilityStateChangedIfNeeded();
+        }
     }
 
     private void addInArray(View child, int index) {
@@ -3804,6 +3861,10 @@
         }
 
         onViewRemoved(view);
+
+        if (view.isImportantForAccessibility() && view.getVisibility() != View.GONE) {
+            notifySubtreeAccessibilityStateChangedIfNeeded();
+        }
     }
 
     /**
@@ -3812,13 +3873,19 @@
      * the ViewGroup will be animated according to the animations defined in that LayoutTransition
      * object. By default, the transition object is null (so layout changes are not animated).
      *
+     * <p>Replacing a non-null transition will cause that previous transition to be
+     * canceled, if it is currently running, to restore this container to
+     * its correct post-transition state.</p>
+     *
      * @param transition The LayoutTransition object that will animated changes in layout. A value
      * of <code>null</code> means no transition will run on layout changes.
      * @attr ref android.R.styleable#ViewGroup_animateLayoutChanges
      */
     public void setLayoutTransition(LayoutTransition transition) {
         if (mTransition != null) {
-            mTransition.removeTransitionListener(mLayoutTransitionListener);
+            LayoutTransition previousTransition = mTransition;
+            previousTransition.cancel();
+            previousTransition.removeTransitionListener(mLayoutTransitionListener);
         }
         mTransition = transition;
         if (mTransition != null) {
@@ -4380,8 +4447,10 @@
     /**
      * Quick invalidation method that simply transforms the dirty rect into the parent's
      * coordinate system, pruning the invalidation if the parent has already been invalidated.
+     *
+     * @hide
      */
-    private ViewParent invalidateChildInParentFast(int left, int top, final Rect dirty) {
+    protected ViewParent invalidateChildInParentFast(int left, int top, final Rect dirty) {
         if ((mPrivateFlags & PFLAG_DRAWN) == PFLAG_DRAWN ||
                 (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID) {
             dirty.offset(left - mScrollX, top - mScrollY);
@@ -4754,6 +4823,10 @@
         setBooleanFlag(FLAG_USE_CHILD_DRAWING_ORDER, enabled);
     }
 
+    private boolean hasBooleanFlag(int flag) {
+        return (mGroupFlags & flag) == flag;
+    }
+
     private void setBooleanFlag(int flag, boolean value) {
         if (value) {
             mGroupFlags |= flag;
@@ -4797,24 +4870,63 @@
         mPersistentDrawingCache = drawingCacheToKeep & PERSISTENT_ALL_CACHES;
     }
 
+    private void setLayoutMode(int layoutMode, boolean explicitly) {
+        mLayoutMode = layoutMode;
+        setBooleanFlag(FLAG_LAYOUT_MODE_WAS_EXPLICITLY_SET, explicitly);
+    }
+
     /**
-     * Returns the basis of alignment during layout operations on this view group:
+     * Recursively traverse the view hierarchy, resetting the layoutMode of any
+     * descendants that had inherited a different layoutMode from a previous parent.
+     * Recursion terminates when a descendant's mode is:
+     * <ul>
+     *     <li>Undefined</li>
+     *     <li>The same as the root node's</li>
+     *     <li>A mode that had been explicitly set</li>
+     * <ul/>
+     * The first two clauses are optimizations.
+     * @param layoutModeOfRoot
+     */
+    @Override
+    void invalidateInheritedLayoutMode(int layoutModeOfRoot) {
+        if (mLayoutMode == LAYOUT_MODE_UNDEFINED ||
+            mLayoutMode == layoutModeOfRoot ||
+            hasBooleanFlag(FLAG_LAYOUT_MODE_WAS_EXPLICITLY_SET)) {
+            return;
+        }
+        setLayoutMode(LAYOUT_MODE_UNDEFINED, false);
+
+        // apply recursively
+        for (int i = 0, N = getChildCount(); i < N; i++) {
+            getChildAt(i).invalidateInheritedLayoutMode(layoutModeOfRoot);
+        }
+    }
+
+    /**
+     * Returns the basis of alignment during layout operations on this ViewGroup:
      * either {@link #LAYOUT_MODE_CLIP_BOUNDS} or {@link #LAYOUT_MODE_OPTICAL_BOUNDS}.
+     * <p>
+     * If no layoutMode was explicitly set, either programmatically or in an XML resource,
+     * the method returns the layoutMode of the view's parent ViewGroup if such a parent exists,
+     * otherwise the method returns a default value of {@link #LAYOUT_MODE_CLIP_BOUNDS}.
      *
      * @return the layout mode to use during layout operations
      *
      * @see #setLayoutMode(int)
      */
     public int getLayoutMode() {
+        if (mLayoutMode == LAYOUT_MODE_UNDEFINED) {
+            int inheritedLayoutMode = (mParent instanceof ViewGroup) ?
+                    ((ViewGroup) mParent).getLayoutMode() : LAYOUT_MODE_DEFAULT;
+            setLayoutMode(inheritedLayoutMode, false);
+        }
         return mLayoutMode;
     }
 
     /**
-     * Sets the basis of alignment during the layout of this view group.
+     * Sets the basis of alignment during the layout of this ViewGroup.
      * Valid values are either {@link #LAYOUT_MODE_CLIP_BOUNDS} or
      * {@link #LAYOUT_MODE_OPTICAL_BOUNDS}.
-     * <p>
-     * The default is {@link #LAYOUT_MODE_CLIP_BOUNDS}.
      *
      * @param layoutMode the layout mode to use during layout operations
      *
@@ -4823,7 +4935,8 @@
      */
     public void setLayoutMode(int layoutMode) {
         if (mLayoutMode != layoutMode) {
-            mLayoutMode = layoutMode;
+            invalidateInheritedLayoutMode(layoutMode);
+            setLayoutMode(layoutMode, layoutMode != LAYOUT_MODE_UNDEFINED);
             requestLayout();
         }
     }
@@ -5268,6 +5381,18 @@
     }
 
     /**
+     * Returns whether layout calls on this container are currently being
+     * suppressed, due to an earlier call to {@link #suppressLayout(boolean)}.
+     *
+     * @return true if layout calls are currently suppressed, false otherwise.
+     *
+     * @hide
+     */
+    public boolean isLayoutSuppressed() {
+        return mSuppressLayout;
+    }
+
+    /**
      * {@inheritDoc}
      */
     @Override
@@ -6343,7 +6468,7 @@
      */
     private static final class TouchTarget {
         private static final int MAX_RECYCLED = 32;
-        private static final Object sRecycleLock = new Object();
+        private static final Object sRecycleLock = new Object[0];
         private static TouchTarget sRecycleBin;
         private static int sRecycledCount;
 
@@ -6395,7 +6520,7 @@
     /* Describes a hovered view. */
     private static final class HoverTarget {
         private static final int MAX_RECYCLED = 32;
-        private static final Object sRecycleLock = new Object();
+        private static final Object sRecycleLock = new Object[0];
         private static HoverTarget sRecycleBin;
         private static int sRecycledCount;
 
@@ -6614,8 +6739,9 @@
         return sDebugPaint;
     }
 
-    private void drawRect(Canvas canvas, Paint paint, int x1, int y1, int x2, int y2) {
+    private static void drawRect(Canvas canvas, Paint paint, int x1, int y1, int x2, int y2) {
         if (sDebugLines== null) {
+            // TODO: This won't work with multiple UI threads in a single process
             sDebugLines = new float[16];
         }
 
diff --git a/core/java/android/view/ViewOverlay.java b/core/java/android/view/ViewOverlay.java
index 5510939..975931a 100644
--- a/core/java/android/view/ViewOverlay.java
+++ b/core/java/android/view/ViewOverlay.java
@@ -15,6 +15,7 @@
  */
 package android.view;
 
+import android.animation.LayoutTransition;
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Rect;
@@ -169,6 +170,14 @@
                     child.offsetTopAndBottom(parentLocation[1] - hostViewLocation[1]);
                 }
                 parent.removeView(child);
+                if (parent.getLayoutTransition() != null) {
+                    // LayoutTransition will cause the child to delay removal - cancel it
+                    parent.getLayoutTransition().cancel(LayoutTransition.DISAPPEARING);
+                }
+                // fail-safe if view is still attached for any reason
+                if (child.getParent() != null) {
+                    child.mParent = null;
+                }
             }
             super.addView(child);
         }
@@ -291,6 +300,17 @@
             }
         }
 
+        /**
+         * @hide
+         */
+        @Override
+        protected ViewParent invalidateChildInParentFast(int left, int top, Rect dirty) {
+            if (mHostView instanceof ViewGroup) {
+                return ((ViewGroup) mHostView).invalidateChildInParentFast(left, top, dirty);
+            }
+            return null;
+        }
+
         @Override
         public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
             if (mHostView != null) {
diff --git a/core/java/android/view/ViewParent.java b/core/java/android/view/ViewParent.java
index d79aa7e..01376934 100644
--- a/core/java/android/view/ViewParent.java
+++ b/core/java/android/view/ViewParent.java
@@ -148,9 +148,11 @@
     /**
      * Change the z order of the child so it's on top of all other children.
      * This ordering change may affect layout, if this container
-     * uses an order-dependent layout scheme (e.g., LinearLayout). This
+     * uses an order-dependent layout scheme (e.g., LinearLayout). Prior
+     * to {@link android.os.Build.VERSION_CODES#KITKAT} this
      * method should be followed by calls to {@link #requestLayout()} and
-     * {@link View#invalidate()} on this parent.
+     * {@link View#invalidate()} on this parent to force the parent to redraw
+     * with the new child ordering.
      * 
      * @param child The child to bring to the top of the z order
      */
@@ -269,10 +271,25 @@
     /**
      * Called when a child view now has or no longer is tracking transient state.
      *
+     * <p>"Transient state" is any state that a View might hold that is not expected to
+     * be reflected in the data model that the View currently presents. This state only
+     * affects the presentation to the user within the View itself, such as the current
+     * state of animations in progress or the state of a text selection operation.</p>
+     *
+     * <p>Transient state is useful for hinting to other components of the View system
+     * that a particular view is tracking something complex but encapsulated.
+     * A <code>ListView</code> for example may acknowledge that list item Views
+     * with transient state should be preserved within their position or stable item ID
+     * instead of treating that view as trivially replaceable by the backing adapter.
+     * This allows adapter implementations to be simpler instead of needing to track
+     * the state of item view animations in progress such that they could be restored
+     * in the event of an unexpected recycling and rebinding of attached item views.</p>
+     *
+     * <p>This method is called on a parent view when a child view or a view within
+     * its subtree begins or ends tracking of internal transient state.</p>
+     *
      * @param child Child view whose state has changed
      * @param hasTransientState true if this child has transient state
-     *
-     * @hide
      */
     public void childHasTransientStateChanged(View child, boolean hasTransientState);
 
@@ -292,21 +309,27 @@
     public ViewParent getParentForAccessibility();
 
     /**
-     * A child notifies its parent that its state for accessibility has changed.
-     * That is some of the child properties reported to accessibility services has
-     * changed, hence the interested services have to be notified for the new state.
-     *
-     * @hide
+     * Notifies a view parent that the accessibility state of one of its
+     * descendants has changed and that the structure of the subtree is
+     * different.
+     * @param child The direct child whose subtree has changed.
+     * @param source The descendant view that changed.
+     * @param changeType A bit mask of the types of changes that occurred. One
+     *            or more of:
+     *            <ul>
+     *            <li>{@link AccessibilityEvent#CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION}
+     *            <li>{@link AccessibilityEvent#CONTENT_CHANGE_TYPE_SUBTREE}
+     *            <li>{@link AccessibilityEvent#CONTENT_CHANGE_TYPE_TEXT}
+     *            <li>{@link AccessibilityEvent#CONTENT_CHANGE_TYPE_UNDEFINED}
+     *            </ul>
      */
-    public void childAccessibilityStateChanged(View child);
+    public void notifySubtreeAccessibilityStateChanged(View child, View source, int changeType);
 
     /**
      * Tells if this view parent can resolve the layout direction.
      * See {@link View#setLayoutDirection(int)}
      *
      * @return True if this view parent can resolve the layout direction.
-     *
-     * @hide
      */
     public boolean canResolveLayoutDirection();
 
@@ -315,8 +338,6 @@
      * See {@link View#setLayoutDirection(int)}
      *
      * @return True if this view parent layout direction is resolved.
-     *
-     * @hide
      */
     public boolean isLayoutDirectionResolved();
 
@@ -325,8 +346,6 @@
      *
      * @return {@link View#LAYOUT_DIRECTION_RTL} if the layout direction is RTL or returns
      * {@link View#LAYOUT_DIRECTION_LTR} if the layout direction is not RTL.
-     *
-     * @hide
      */
     public int getLayoutDirection();
 
@@ -335,8 +354,6 @@
      * See {@link View#setTextDirection(int)}
      *
      * @return True if this view parent can resolve the text direction.
-     *
-     * @hide
      */
     public boolean canResolveTextDirection();
 
@@ -345,8 +362,6 @@
      * See {@link View#setTextDirection(int)}
      *
      * @return True if this view parent text direction is resolved.
-     *
-     * @hide
      */
     public boolean isTextDirectionResolved();
 
@@ -360,8 +375,6 @@
      * {@link View#TEXT_DIRECTION_LTR},
      * {@link View#TEXT_DIRECTION_RTL},
      * {@link View#TEXT_DIRECTION_LOCALE}
-     *
-     * @hide
      */
     public int getTextDirection();
 
@@ -370,8 +383,6 @@
      * See {@link View#setTextAlignment(int)}
      *
      * @return True if this view parent can resolve the text alignment.
-     *
-     * @hide
      */
     public boolean canResolveTextAlignment();
 
@@ -380,8 +391,6 @@
      * See {@link View#setTextAlignment(int)}
      *
      * @return True if this view parent text alignment is resolved.
-     *
-     * @hide
      */
     public boolean isTextAlignmentResolved();
 
@@ -396,8 +405,6 @@
      * {@link View#TEXT_ALIGNMENT_TEXT_END},
      * {@link View#TEXT_ALIGNMENT_VIEW_START},
      * {@link View#TEXT_ALIGNMENT_VIEW_END}
-     *
-     * @hide
      */
     public int getTextAlignment();
 }
diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java
index e6bf420..67a94be 100644
--- a/core/java/android/view/ViewPropertyAnimator.java
+++ b/core/java/android/view/ViewPropertyAnimator.java
@@ -93,11 +93,16 @@
     private boolean mInterpolatorSet = false;
 
     /**
-     * Listener for the lifecycle events of the underlying 
+     * Listener for the lifecycle events of the underlying ValueAnimator object.
      */
     private Animator.AnimatorListener mListener = null;
 
     /**
+     * Listener for the update events of the underlying ValueAnimator object.
+     */
+    private ValueAnimator.AnimatorUpdateListener mUpdateListener = null;
+
+    /**
      * A lazily-created ValueAnimator used in order to get some default animator properties
      * (duration, start delay, interpolator, etc.).
      */
@@ -353,7 +358,10 @@
      * Sets a listener for events in the underlying Animators that run the property
      * animations.
      *
-     * @param listener The listener to be called with AnimatorListener events.
+     * @see Animator.AnimatorListener
+     *
+     * @param listener The listener to be called with AnimatorListener events. A value of
+     * <code>null</code> removes any existing listener.
      * @return This object, allowing calls to methods in this class to be chained.
      */
     public ViewPropertyAnimator setListener(Animator.AnimatorListener listener) {
@@ -362,6 +370,25 @@
     }
 
     /**
+     * Sets a listener for update events in the underlying ValueAnimator that runs
+     * the property animations. Note that the underlying animator is animating between
+     * 0 and 1 (these values are then turned into the actual property values internally
+     * by ViewPropertyAnimator). So the animator cannot give information on the current
+     * values of the properties being animated by this ViewPropertyAnimator, although
+     * the view object itself can be queried to get the current values.
+     *
+     * @see android.animation.ValueAnimator.AnimatorUpdateListener
+     *
+     * @param listener The listener to be called with update events. A value of
+     * <code>null</code> removes any existing listener.
+     * @return This object, allowing calls to methods in this class to be chained.
+     */
+    public ViewPropertyAnimator setUpdateListener(ValueAnimator.AnimatorUpdateListener listener) {
+        mUpdateListener = listener;
+        return this;
+    }
+
+    /**
      * Starts the currently pending property animations immediately. Calling <code>start()</code>
      * is optional because all animations start automatically at the next opportunity. However,
      * if the animations are needed to start immediately and synchronously (not at the time when
@@ -675,6 +702,9 @@
             @Override
             public void run() {
                 mView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+                if (mView.isAttachedToWindow()) {
+                    mView.buildLayer();
+                }
             }
         };
         final int currentLayerType = mView.getLayerType();
@@ -1073,6 +1103,9 @@
             } else {
                 mView.invalidateViewProperty(false, false);
             }
+            if (mUpdateListener != null) {
+                mUpdateListener.onAnimationUpdate(animation);
+            }
         }
     }
 }
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 6b2ed91..38f28ae 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -23,7 +23,6 @@
 import android.content.ComponentCallbacks;
 import android.content.ComponentCallbacks2;
 import android.content.Context;
-import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
@@ -69,6 +68,7 @@
 import android.view.animation.Interpolator;
 import android.view.inputmethod.InputConnection;
 import android.view.inputmethod.InputMethodManager;
+import android.view.Surface.OutOfResourcesException;
 import android.widget.Scroller;
 
 import com.android.internal.R;
@@ -82,6 +82,7 @@
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.Locale;
 
 /**
  * The top of a view hierarchy, implementing the needed protocol between View
@@ -108,13 +109,12 @@
     private static final boolean DEBUG_FPS = false;
     private static final boolean DEBUG_INPUT_PROCESSING = false || LOCAL_LOGV;
 
-    private static final boolean USE_RENDER_THREAD = false;
-
     /**
      * Set this system property to true to force the view hierarchy to render
      * at 60 Hz. This can be used to measure the potential framerate.
      */
-    private static final String PROPERTY_PROFILE_RENDERING = "viewancestor.profile_rendering";
+    private static final String PROPERTY_PROFILE_RENDERING = "viewroot.profile_rendering";
+    private static final String PROPERTY_MEDIA_DISABLED = "config.disable_media";
 
     /**
      * Maximum time we allow the user to roll the trackball enough to generate
@@ -126,14 +126,10 @@
 
     static final ArrayList<Runnable> sFirstDrawHandlers = new ArrayList<Runnable>();
     static boolean sFirstDrawComplete = false;
-    
+
     static final ArrayList<ComponentCallbacks> sConfigCallbacks
             = new ArrayList<ComponentCallbacks>();
 
-    private static boolean sUseRenderThread = false;
-    private static boolean sRenderThreadQueried = false;
-    private static final Object[] sRenderThreadQueryLock = new Object[0];
-
     final Context mContext;
     final IWindowSession mWindowSession;
     final Display mDisplay;
@@ -167,14 +163,14 @@
     // Set to true if the owner of this window is in the stopped state,
     // so the window should no longer be active.
     boolean mStopped = false;
-    
+
     boolean mLastInCompatMode = false;
 
     SurfaceHolder.Callback2 mSurfaceHolderCallback;
     BaseSurfaceHolder mSurfaceHolder;
     boolean mIsCreating;
     boolean mDrawingAllowed;
-    
+
     final Region mTransparentRegion;
     final Region mPreviousTransparentRegion;
 
@@ -192,7 +188,7 @@
     InputQueue mInputQueue;
     FallbackEventHandler mFallbackEventHandler;
     Choreographer mChoreographer;
-    
+
     final Rect mTempRect; // used in the transaction to not thrash the heap.
     final Rect mVisRect; // used to retrieve visible rect of focused view.
 
@@ -235,6 +231,8 @@
     InputStage mFirstInputStage;
     InputStage mFirstPostImeInputStage;
 
+    boolean mFlipControllerFallbackKeys;
+
     boolean mWindowAttributesChanged = false;
     int mWindowAttributesChangesFlag = 0;
 
@@ -245,7 +243,7 @@
     boolean mAdded;
     boolean mAddedTouchMode;
 
-    final CompatibilityInfoHolder mCompatibilityInfo;
+    final DisplayAdjustments mDisplayAdjustments;
 
     // These are accessed by multiple threads.
     final Rect mWinFrame; // frame given by window manager.
@@ -281,18 +279,20 @@
     volatile Object mLocalDragState;
     final PointF mDragPoint = new PointF();
     final PointF mLastTouchPoint = new PointF();
-    
-    private boolean mProfileRendering;    
+
+    private boolean mProfileRendering;
     private Choreographer.FrameCallback mRenderProfiler;
     private boolean mRenderProfilingEnabled;
 
+    private boolean mMediaDisabled;
+
     // Variables to track frames per second, enabled via DEBUG_FPS flag
     private long mFpsStartTime = -1;
     private long mFpsPrevTime = -1;
     private int mFpsNumFrames;
 
     private final ArrayList<DisplayList> mDisplayLists = new ArrayList<DisplayList>();
-    
+
     /**
      * see {@link #playSoundEffect(int)}
      */
@@ -317,6 +317,9 @@
 
     private int mViewLayoutDirectionInitial;
 
+    /** Set to true once doDie() has been called. */
+    private boolean mRemoved;
+
     /**
      * Consistency verifier for debugging purposes.
      */
@@ -330,15 +333,14 @@
         int localValue;
         int localChanges;
     }
-    
+
     public ViewRootImpl(Context context, Display display) {
         mContext = context;
         mWindowSession = WindowManagerGlobal.getWindowSession();
         mDisplay = display;
         mBasePackageName = context.getBasePackageName();
 
-        CompatibilityInfoHolder cih = display.getCompatibilityInfo();
-        mCompatibilityInfo = cih != null ? cih : new CompatibilityInfoHolder();
+        mDisplayAdjustments = display.getDisplayAdjustments();
 
         mThread = Thread.currentThread();
         mLocation = new WindowLeaked(null);
@@ -367,41 +369,14 @@
         mNoncompatDensity = context.getResources().getDisplayMetrics().noncompatDensityDpi;
         mFallbackEventHandler = PolicyManager.makeNewFallbackEventHandler(context);
         mChoreographer = Choreographer.getInstance();
+        mFlipControllerFallbackKeys =
+            context.getResources().getBoolean(R.bool.flip_controller_fallback_keys);
 
         PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
         mAttachInfo.mScreenOn = powerManager.isScreenOn();
         loadSystemProperties();
     }
 
-    /**
-     * @return True if the application requests the use of a separate render thread,
-     *         false otherwise
-     */
-    private static boolean isRenderThreadRequested(Context context) {
-        if (USE_RENDER_THREAD) {
-            synchronized (sRenderThreadQueryLock) {
-                if (!sRenderThreadQueried) {
-                    final PackageManager packageManager = context.getPackageManager();
-                    final String packageName = context.getApplicationInfo().packageName;
-                    try {
-                        ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packageName,
-                                PackageManager.GET_META_DATA);
-                        if (applicationInfo.metaData != null) {
-                            sUseRenderThread = applicationInfo.metaData.getBoolean(
-                                    "android.graphics.renderThread", false);
-                        }
-                    } catch (PackageManager.NameNotFoundException e) {
-                    } finally {
-                        sRenderThreadQueried = true;
-                    }
-                }
-                return sUseRenderThread;
-            }
-        } else {
-            return false;
-        }
-    }
-
     public static void addFirstDrawHandler(Runnable callback) {
         synchronized (sFirstDrawHandlers) {
             if (!sFirstDrawComplete) {
@@ -409,13 +384,13 @@
             }
         }
     }
-    
+
     public static void addConfigCallback(ComponentCallbacks callback) {
         synchronized (sConfigCallbacks) {
             sConfigCallbacks.add(callback);
         }
     }
-    
+
     // FIXME for perf testing only
     private boolean mProfile = false;
 
@@ -474,12 +449,13 @@
                     }
                 }
 
-                CompatibilityInfo compatibilityInfo = mCompatibilityInfo.get();
+                CompatibilityInfo compatibilityInfo = mDisplayAdjustments.getCompatibilityInfo();
                 mTranslator = compatibilityInfo.getTranslator();
+                mDisplayAdjustments.setActivityToken(attrs.token);
 
                 // If the application owns the surface, don't enable hardware acceleration
                 if (mSurfaceHolder == null) {
-                    enableHardwareAcceleration(mView.getContext(), attrs);
+                    enableHardwareAcceleration(attrs);
                 }
 
                 boolean restore = false;
@@ -539,7 +515,7 @@
                         attrs.restore();
                     }
                 }
-                
+
                 if (mTranslator != null) {
                     mTranslator.translateRectInScreenToAppWindow(mAttachInfo.mContentInsets);
                 }
@@ -619,8 +595,8 @@
 
                 // Set up the input pipeline.
                 CharSequence counterSuffix = attrs.getTitle();
-                InputStage syntheticStage = new SyntheticInputStage();
-                InputStage viewPostImeStage = new ViewPostImeInputStage(syntheticStage);
+                InputStage syntheticInputStage = new SyntheticInputStage();
+                InputStage viewPostImeStage = new ViewPostImeInputStage(syntheticInputStage);
                 InputStage nativePostImeStage = new NativePostImeInputStage(viewPostImeStage,
                         "aq:native-post-ime:" + counterSuffix);
                 InputStage earlyPostImeStage = new EarlyPostImeInputStage(nativePostImeStage);
@@ -637,16 +613,13 @@
         }
     }
 
-    void destroyHardwareResources() {
-        if (mAttachInfo.mHardwareRenderer != null) {
-            if (mAttachInfo.mHardwareRenderer.isEnabled()) {
-                mAttachInfo.mHardwareRenderer.destroyLayers(mView);
-            }
-            mAttachInfo.mHardwareRenderer.destroy(false);
-        }
+    /** Whether the window is in local focus mode or not */
+    private boolean isInLocalFocusMode() {
+        return (mWindowAttributes.flags & WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE) != 0;
     }
 
-    void terminateHardwareResources() {
+    void destroyHardwareResources() {
+        invalidateDisplayLists();
         if (mAttachInfo.mHardwareRenderer != null) {
             mAttachInfo.mHardwareRenderer.destroyHardwareResources(mView);
             mAttachInfo.mHardwareRenderer.destroy(false);
@@ -660,6 +633,7 @@
                 HardwareRenderer.trimMemory(ComponentCallbacks2.TRIM_MEMORY_MODERATE);
             }
         } else {
+            invalidateDisplayLists();
             if (mAttachInfo.mHardwareRenderer != null &&
                     mAttachInfo.mHardwareRenderer.isEnabled()) {
                 mAttachInfo.mHardwareRenderer.destroyLayers(mView);
@@ -673,6 +647,18 @@
         }
     }
 
+    void flushHardwareLayerUpdates() {
+        if (mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled() &&
+                mAttachInfo.mHardwareRenderer.validate()) {
+            mAttachInfo.mHardwareRenderer.flushLayerUpdates();
+        }
+    }
+
+    void dispatchFlushHardwareLayerUpdates() {
+        mHandler.removeMessages(MSG_FLUSH_LAYER_UPDATES);
+        mHandler.sendMessageAtFrontOfQueue(mHandler.obtainMessage(MSG_FLUSH_LAYER_UPDATES));
+    }
+
     public boolean attachFunctor(int functor) {
         //noinspection SimplifiableIfStatement
         if (mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled()) {
@@ -687,7 +673,7 @@
         }
     }
 
-    private void enableHardwareAcceleration(Context context, WindowManager.LayoutParams attrs) {
+    private void enableHardwareAcceleration(WindowManager.LayoutParams attrs) {
         mAttachInfo.mHardwareAccelerated = false;
         mAttachInfo.mHardwareAccelerationRequested = false;
 
@@ -695,7 +681,7 @@
         if (mTranslator != null) return;
 
         // Try to enable hardware acceleration if requested
-        final boolean hardwareAccelerated = 
+        final boolean hardwareAccelerated =
                 (attrs.flags & WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
 
         if (hardwareAccelerated) {
@@ -722,16 +708,11 @@
                 // Don't enable hardware acceleration when we're not on the main thread
                 if (!HardwareRenderer.sSystemRendererDisabled &&
                         Looper.getMainLooper() != Looper.myLooper()) {
-                    Log.w(HardwareRenderer.LOG_TAG, "Attempting to initialize hardware " 
+                    Log.w(HardwareRenderer.LOG_TAG, "Attempting to initialize hardware "
                             + "acceleration outside of the main thread, aborting");
                     return;
                 }
 
-                final boolean renderThread = isRenderThreadRequested(context);
-                if (renderThread) {
-                    Log.i(HardwareRenderer.LOG_TAG, "Render threat initiated");
-                }
-
                 if (mAttachInfo.mHardwareRenderer != null) {
                     mAttachInfo.mHardwareRenderer.destroy(true);
                 }
@@ -865,6 +846,7 @@
         invalidateChildInParent(null, dirty);
     }
 
+    @Override
     public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
         checkThread();
         if (DEBUG_DRAW) Log.v(TAG, "Invalidate child: " + dirty);
@@ -922,10 +904,12 @@
         }
     }
 
+    @Override
     public ViewParent getParent() {
         return null;
     }
 
+    @Override
     public boolean getChildVisibleRect(View child, Rect r, android.graphics.Point offset) {
         if (child != mView) {
             throw new RuntimeException("child is not mine, honest!");
@@ -935,6 +919,7 @@
         return r.intersect(0, 0, mWidth, mHeight);
     }
 
+    @Override
     public void bringChildToFront(View child) {
     }
 
@@ -943,9 +928,14 @@
     }
 
     void disposeResizeBuffer() {
-        if (mResizeBuffer != null) {
-            mResizeBuffer.destroy();
-            mResizeBuffer = null;
+        if (mResizeBuffer != null && mAttachInfo.mHardwareRenderer != null) {
+            mAttachInfo.mHardwareRenderer.safelyRun(new Runnable() {
+                @Override
+                public void run() {
+                    mResizeBuffer.destroy();
+                    mResizeBuffer = null;
+                }
+            });
         }
     }
 
@@ -1151,7 +1141,7 @@
             surfaceChanged = true;
             params = lp;
         }
-        CompatibilityInfo compatibilityInfo = mCompatibilityInfo.get();
+        CompatibilityInfo compatibilityInfo = mDisplayAdjustments.getCompatibilityInfo();
         if (compatibilityInfo.supportsScreen() == mLastInCompatMode) {
             params = lp;
             mFullRedrawNeeded = true;
@@ -1164,9 +1154,9 @@
                 mLastInCompatMode = true;
             }
         }
-        
+
         mWindowAttributesChangesFlag = 0;
-        
+
         Rect frame = mWinFrame;
         if (mFirst) {
             mFullRedrawNeeded = true;
@@ -1465,7 +1455,7 @@
                             }
 
                             DisplayList displayList = mView.mDisplayList;
-                            if (displayList != null) {
+                            if (displayList != null && displayList.isValid()) {
                                 layerCanvas.drawDisplayList(displayList, null,
                                         DisplayList.FLAG_CLIP_CHILDREN);
                             } else {
@@ -1486,8 +1476,7 @@
                             if (mResizeBuffer != null) {
                                 mResizeBuffer.end(hwRendererCanvas);
                                 if (!completed) {
-                                    mResizeBuffer.destroy();
-                                    mResizeBuffer = null;
+                                    disposeResizeBuffer();
                                 }
                             }
                         }
@@ -1535,7 +1524,7 @@
                             try {
                                 hwInitialized = mAttachInfo.mHardwareRenderer.initialize(
                                         mHolder.getSurface());
-                            } catch (Surface.OutOfResourcesException e) {
+                            } catch (OutOfResourcesException e) {
                                 handleOutOfResourcesException(e);
                                 return;
                             }
@@ -1562,7 +1551,7 @@
                     mFullRedrawNeeded = true;
                     try {
                         mAttachInfo.mHardwareRenderer.updateSurface(mHolder.getSurface());
-                    } catch (Surface.OutOfResourcesException e) {
+                    } catch (OutOfResourcesException e) {
                         handleOutOfResourcesException(e);
                         return;
                     }
@@ -1657,23 +1646,23 @@
                         || mHeight != host.getMeasuredHeight() || contentInsetsChanged) {
                     int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
                     int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height);
-    
+
                     if (DEBUG_LAYOUT) Log.v(TAG, "Ooops, something changed!  mWidth="
                             + mWidth + " measuredWidth=" + host.getMeasuredWidth()
                             + " mHeight=" + mHeight
                             + " measuredHeight=" + host.getMeasuredHeight()
                             + " coveredInsetsChanged=" + contentInsetsChanged);
-    
+
                      // Ask host how big it wants to be
                     performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
-    
+
                     // Implementation of weights from WindowManager.LayoutParams
                     // We just grow the dimensions as needed and re-measure if
                     // needs be
                     int width = host.getMeasuredWidth();
                     int height = host.getMeasuredHeight();
                     boolean measureAgain = false;
-    
+
                     if (lp.horizontalWeight > 0.0f) {
                         width += (int) ((mWidth - width) * lp.horizontalWeight);
                         childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(width,
@@ -1686,14 +1675,14 @@
                                 MeasureSpec.EXACTLY);
                         measureAgain = true;
                     }
-    
+
                     if (measureAgain) {
                         if (DEBUG_LAYOUT) Log.v(TAG,
                                 "And hey let's measure once more: width=" + width
                                 + " height=" + height);
                         performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
                     }
-    
+
                     layoutRequested = true;
                 }
             }
@@ -1766,10 +1755,6 @@
         if (triggerGlobalLayoutListener) {
             attachInfo.mRecomputeGlobalAttributes = false;
             attachInfo.mTreeObserver.dispatchOnGlobalLayout();
-
-            if (AccessibilityManager.getInstance(host.mContext).isEnabled()) {
-                postSendWindowContentChangedCallback(mView);
-            }
         }
 
         if (computesInternalInsets) {
@@ -1837,7 +1822,7 @@
         mNewSurfaceNeeded = false;
         mViewVisibility = viewVisibility;
 
-        if (mAttachInfo.mHasWindowFocus) {
+        if (mAttachInfo.mHasWindowFocus && !isInLocalFocusMode()) {
             final boolean imTarget = WindowManager.LayoutParams
                     .mayUseInputMethod(mWindowAttributes.flags);
             if (imTarget != mLastWasImTarget) {
@@ -1868,7 +1853,7 @@
                     }
                     mPendingTransitions.clear();
                 }
-    
+
                 performDraw();
             }
         } else {
@@ -2095,6 +2080,7 @@
         return validLayoutRequesters;
     }
 
+    @Override
     public void requestTransparentRegion(View child) {
         // the test below should not fail unless someone is messing with us
         checkThread();
@@ -2145,10 +2131,12 @@
     int mResizeAlpha;
     final Paint mResizePaint = new Paint();
 
+    @Override
     public void onHardwarePreDraw(HardwareCanvas canvas) {
         canvas.translate(0, -mHardwareYOffset);
     }
 
+    @Override
     public void onHardwarePostDraw(HardwareCanvas canvas) {
         if (mResizeBuffer != null) {
             mResizePaint.setAlpha(mResizeAlpha);
@@ -2382,7 +2370,7 @@
                     try {
                         attachInfo.mHardwareRenderer.initializeIfNeeded(mWidth, mHeight,
                                 mHolder.getSurface());
-                    } catch (Surface.OutOfResourcesException e) {
+                    } catch (OutOfResourcesException e) {
                         handleOutOfResourcesException(e);
                         return;
                     }
@@ -2568,7 +2556,7 @@
         for (int i = 0; i < count; i++) {
             final DisplayList displayList = displayLists.get(i);
             if (displayList.isDirty()) {
-                displayList.clear();
+                displayList.reset();
             }
         }
 
@@ -2758,6 +2746,7 @@
         mAccessibilityFocusedVirtualView = node;
     }
 
+    @Override
     public void requestChildFocus(View child, View focused) {
         if (DEBUG_INPUT_RESIZE) {
             Log.v(TAG, "Request child focus: focus now " + focused);
@@ -2766,6 +2755,7 @@
         scheduleTraversals();
     }
 
+    @Override
     public void clearChildFocus(View child) {
         if (DEBUG_INPUT_RESIZE) {
             Log.v(TAG, "Clearing child focus");
@@ -2779,6 +2769,7 @@
         return null;
     }
 
+    @Override
     public void focusableViewAvailable(View v) {
         checkThread();
         if (mView != null) {
@@ -2800,6 +2791,7 @@
         }
     }
 
+    @Override
     public void recomputeViewAttributes(View child) {
         checkThread();
         if (mView == child) {
@@ -2867,8 +2859,8 @@
                 + mWindowAttributes.getTitle()
                 + ": " + config);
 
-        CompatibilityInfo ci = mCompatibilityInfo.getIfNeeded();
-        if (ci != null) {
+        CompatibilityInfo ci = mDisplayAdjustments.getCompatibilityInfo();
+        if (!ci.equals(CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO)) {
             config = new Configuration(config);
             ci.applyToConfiguration(mNoncompatDensity, config);
         }
@@ -2894,8 +2886,11 @@
                 mView.dispatchConfigurationChanged(config);
             }
         }
+
+        mFlipControllerFallbackKeys =
+            mContext.getResources().getBoolean(R.bool.flip_controller_fallback_keys);
     }
-    
+
     /**
      * Return true if child is an ancestor of parent, (or equal to the parent).
      */
@@ -2925,7 +2920,7 @@
     private final static int MSG_RESIZED = 4;
     private final static int MSG_RESIZED_REPORT = 5;
     private final static int MSG_WINDOW_FOCUS_CHANGED = 6;
-    private final static int MSG_DISPATCH_KEY = 7;
+    private final static int MSG_DISPATCH_INPUT_EVENT = 7;
     private final static int MSG_DISPATCH_APP_VISIBILITY = 8;
     private final static int MSG_DISPATCH_GET_NEW_SURFACE = 9;
     private final static int MSG_DISPATCH_KEY_FROM_IME = 11;
@@ -2942,6 +2937,7 @@
     private final static int MSG_DISPATCH_DONE_ANIMATING = 22;
     private final static int MSG_INVALIDATE_WORLD = 23;
     private final static int MSG_WINDOW_MOVED = 24;
+    private final static int MSG_FLUSH_LAYER_UPDATES = 25;
 
     final class ViewRootHandler extends Handler {
         @Override
@@ -2959,8 +2955,8 @@
                     return "MSG_RESIZED_REPORT";
                 case MSG_WINDOW_FOCUS_CHANGED:
                     return "MSG_WINDOW_FOCUS_CHANGED";
-                case MSG_DISPATCH_KEY:
-                    return "MSG_DISPATCH_KEY";
+                case MSG_DISPATCH_INPUT_EVENT:
+                    return "MSG_DISPATCH_INPUT_EVENT";
                 case MSG_DISPATCH_APP_VISIBILITY:
                     return "MSG_DISPATCH_APP_VISIBILITY";
                 case MSG_DISPATCH_GET_NEW_SURFACE:
@@ -2991,6 +2987,8 @@
                     return "MSG_DISPATCH_DONE_ANIMATING";
                 case MSG_WINDOW_MOVED:
                     return "MSG_WINDOW_MOVED";
+                case MSG_FLUSH_LAYER_UPDATES:
+                    return "MSG_FLUSH_LAYER_UPDATES";
             }
             return super.getMessageName(message);
         }
@@ -3087,7 +3085,7 @@
                             try {
                                 mAttachInfo.mHardwareRenderer.initializeIfNeeded(
                                         mWidth, mHeight, mHolder.getSurface());
-                            } catch (Surface.OutOfResourcesException e) {
+                            } catch (OutOfResourcesException e) {
                                 Log.e(TAG, "OutOfResourcesException locking surface", e);
                                 try {
                                     if (!mWindowSession.outOfMemory(mWindow)) {
@@ -3108,7 +3106,8 @@
 
                     InputMethodManager imm = InputMethodManager.peekInstance();
                     if (mView != null) {
-                        if (hasWindowFocus && imm != null && mLastWasImTarget) {
+                        if (hasWindowFocus && imm != null && mLastWasImTarget &&
+                                !isInLocalFocusMode()) {
                             imm.startGettingWindowFocus(mView);
                         }
                         mAttachInfo.mKeyDispatchState.reset();
@@ -3119,7 +3118,7 @@
                     // Note: must be done after the focus change callbacks,
                     // so all of the view state is set up correctly.
                     if (hasWindowFocus) {
-                        if (imm != null && mLastWasImTarget) {
+                        if (imm != null && mLastWasImTarget && !isInLocalFocusMode()) {
                             imm.onWindowFocus(mView, mView.findFocus(),
                                     mWindowAttributes.softInputMode,
                                     !mHasHadWindowFocus, mWindowAttributes.flags);
@@ -3147,8 +3146,8 @@
             case MSG_DIE:
                 doDie();
                 break;
-            case MSG_DISPATCH_KEY: {
-                KeyEvent event = (KeyEvent)msg.obj;
+            case MSG_DISPATCH_INPUT_EVENT: {
+                InputEvent event = (InputEvent)msg.obj;
                 enqueueInputEvent(event, null, 0, true);
             } break;
             case MSG_DISPATCH_KEY_FROM_IME: {
@@ -3213,6 +3212,9 @@
                     invalidateWorld(mView);
                 }
             } break;
+            case MSG_FLUSH_LAYER_UPDATES: {
+                flushHardwareLayerUpdates();
+            } break;
             }
         }
     }
@@ -3235,7 +3237,9 @@
 
         // tell the window manager
         try {
-            mWindowSession.setInTouchMode(inTouchMode);
+            if (!isInLocalFocusMode()) {
+                mWindowSession.setInTouchMode(inTouchMode);
+            }
         } catch (RemoteException e) {
             throw new RuntimeException(e);
         }
@@ -3263,24 +3267,23 @@
     }
 
     private boolean enterTouchMode() {
-        if (mView != null) {
-            if (mView.hasFocus()) {
-                // note: not relying on mFocusedView here because this could
-                // be when the window is first being added, and mFocused isn't
-                // set yet.
-                final View focused = mView.findFocus();
-                if (focused != null && !focused.isFocusableInTouchMode()) {
-                    final ViewGroup ancestorToTakeFocus =
-                            findAncestorToTakeFocusInTouchMode(focused);
-                    if (ancestorToTakeFocus != null) {
-                        // there is an ancestor that wants focus after its descendants that
-                        // is focusable in touch mode.. give it focus
-                        return ancestorToTakeFocus.requestFocus();
-                    } else {
-                        // nothing appropriate to have focus in touch mode, clear it out
-                        focused.unFocus();
-                        return true;
-                    }
+        if (mView != null && mView.hasFocus()) {
+            // note: not relying on mFocusedView here because this could
+            // be when the window is first being added, and mFocused isn't
+            // set yet.
+            final View focused = mView.findFocus();
+            if (focused != null && !focused.isFocusableInTouchMode()) {
+                final ViewGroup ancestorToTakeFocus = findAncestorToTakeFocusInTouchMode(focused);
+                if (ancestorToTakeFocus != null) {
+                    // there is an ancestor that wants focus after its
+                    // descendants that is focusable in touch mode.. give it
+                    // focus
+                    return ancestorToTakeFocus.requestFocus();
+                } else {
+                    // There's nothing to focus. Clear and propagate through the
+                    // hierarchy, but don't attempt to place new focus.
+                    focused.clearFocusInternal(true, false);
+                    return true;
                 }
             }
         }
@@ -3638,7 +3641,7 @@
 
         @Override
         protected int onProcess(QueuedInputEvent q) {
-            if (mLastWasImTarget) {
+            if (mLastWasImTarget && !isInLocalFocusMode()) {
                 InputMethodManager imm = InputMethodManager.peekInstance();
                 if (imm != null) {
                     final InputEvent event = q.mEvent;
@@ -3914,6 +3917,7 @@
         private final SyntheticJoystickHandler mJoystick = new SyntheticJoystickHandler();
         private final SyntheticTouchNavigationHandler mTouchNavigation =
                 new SyntheticTouchNavigationHandler();
+        private final SyntheticKeyHandler mKeys = new SyntheticKeyHandler();
 
         public SyntheticInputStage() {
             super(null);
@@ -3936,7 +3940,12 @@
                     mTouchNavigation.process(event);
                     return FINISH_HANDLED;
                 }
+            } else if (q.mEvent instanceof KeyEvent) {
+                if (mKeys.process((KeyEvent) q.mEvent)) {
+                    return FINISH_HANDLED;
+                }
             }
+
             return FORWARD;
         }
 
@@ -4386,12 +4395,6 @@
 
         /* TODO: These constants should eventually be moved to ViewConfiguration. */
 
-        // Tap timeout in milliseconds.
-        private static final int TAP_TIMEOUT = 250;
-
-        // The maximum distance traveled for a gesture to be considered a tap in millimeters.
-        private static final int TAP_SLOP_MILLIMETERS = 5;
-
         // The nominal distance traveled to move by one unit.
         private static final int TICK_DISTANCE_MILLIMETERS = 12;
 
@@ -4419,10 +4422,6 @@
 
         /* Configuration for the current input device. */
 
-        // The tap timeout and scaled slop.
-        private int mConfigTapTimeout;
-        private float mConfigTapSlop;
-
         // The scaled tick distance.  A movement of this amount should generally translate
         // into a single dpad event in a given direction.
         private float mConfigTickDistance;
@@ -4468,6 +4467,9 @@
         private boolean mFlinging;
         private float mFlingVelocity;
 
+        // The last time a confirm key was pressed on the touch nav device
+        private long mLastConfirmKeyTime = Long.MAX_VALUE;
+
         public SyntheticTouchNavigationHandler() {
             super(true);
         }
@@ -4504,8 +4506,6 @@
                         float nominalRes = (xRes + yRes) * 0.5f;
 
                         // Precompute all of the configuration thresholds we will need.
-                        mConfigTapTimeout = TAP_TIMEOUT;
-                        mConfigTapSlop = TAP_SLOP_MILLIMETERS * nominalRes;
                         mConfigTickDistance = TICK_DISTANCE_MILLIMETERS * nominalRes;
                         mConfigMinFlingVelocity =
                                 MIN_FLING_VELOCITY_TICKS_PER_SECOND * mConfigTickDistance;
@@ -4515,8 +4515,6 @@
                         if (LOCAL_DEBUG) {
                             Log.d(LOCAL_TAG, "Configured device " + mCurrentDeviceId
                                     + " (" + Integer.toHexString(mCurrentSource) + "): "
-                                    + "mConfigTapTimeout=" + mConfigTapTimeout
-                                    + ", mConfigTapSlop=" + mConfigTapSlop
                                     + ", mConfigTickDistance=" + mConfigTickDistance
                                     + ", mConfigMinFlingVelocity=" + mConfigMinFlingVelocity
                                     + ", mConfigMaxFlingVelocity=" + mConfigMaxFlingVelocity);
@@ -4578,15 +4576,7 @@
 
                     // Detect taps and flings.
                     if (action == MotionEvent.ACTION_UP) {
-                        if (!mConsumedMovement
-                                && Math.hypot(mLastX - mStartX, mLastY - mStartY) < mConfigTapSlop
-                                && time <= mStartTime + mConfigTapTimeout) {
-                            // It's a tap!
-                            finishKeys(time);
-                            sendKeyDownOrRepeat(time, KeyEvent.KEYCODE_DPAD_CENTER, metaState);
-                            sendKeyUp(time);
-                        } else if (mConsumedMovement
-                                && mPendingKeyCode != KeyEvent.KEYCODE_UNKNOWN) {
+                        if (mConsumedMovement && mPendingKeyCode != KeyEvent.KEYCODE_UNKNOWN) {
                             // It might be a fling.
                             mVelocityTracker.computeCurrentVelocity(1000, mConfigMaxFlingVelocity);
                             final float vx = mVelocityTracker.getXVelocity(mActivePointerId);
@@ -4785,6 +4775,63 @@
         };
     }
 
+    final class SyntheticKeyHandler {
+
+        public boolean process(KeyEvent event) {
+            // In some locales (like Japan) controllers use B for confirm and A for back, rather
+            // than vice versa, so we need to special case this here since the input system itself
+            // is not locale-aware.
+            int keyCode;
+            switch(event.getKeyCode()) {
+                case KeyEvent.KEYCODE_BUTTON_A:
+                case KeyEvent.KEYCODE_BUTTON_C:
+                case KeyEvent.KEYCODE_BUTTON_X:
+                case KeyEvent.KEYCODE_BUTTON_Z:
+                    keyCode = mFlipControllerFallbackKeys ?
+                        KeyEvent.KEYCODE_BACK : KeyEvent.KEYCODE_DPAD_CENTER;
+                    break;
+                case KeyEvent.KEYCODE_BUTTON_B:
+                case KeyEvent.KEYCODE_BUTTON_Y:
+                    keyCode = mFlipControllerFallbackKeys ?
+                        KeyEvent.KEYCODE_DPAD_CENTER : KeyEvent.KEYCODE_BACK;
+                    break;
+                case KeyEvent.KEYCODE_BUTTON_THUMBL:
+                case KeyEvent.KEYCODE_BUTTON_THUMBR:
+                case KeyEvent.KEYCODE_BUTTON_START:
+                case KeyEvent.KEYCODE_BUTTON_1:
+                case KeyEvent.KEYCODE_BUTTON_2:
+                case KeyEvent.KEYCODE_BUTTON_3:
+                case KeyEvent.KEYCODE_BUTTON_4:
+                case KeyEvent.KEYCODE_BUTTON_5:
+                case KeyEvent.KEYCODE_BUTTON_6:
+                case KeyEvent.KEYCODE_BUTTON_7:
+                case KeyEvent.KEYCODE_BUTTON_8:
+                case KeyEvent.KEYCODE_BUTTON_9:
+                case KeyEvent.KEYCODE_BUTTON_10:
+                case KeyEvent.KEYCODE_BUTTON_11:
+                case KeyEvent.KEYCODE_BUTTON_12:
+                case KeyEvent.KEYCODE_BUTTON_13:
+                case KeyEvent.KEYCODE_BUTTON_14:
+                case KeyEvent.KEYCODE_BUTTON_15:
+                case KeyEvent.KEYCODE_BUTTON_16:
+                    keyCode = KeyEvent.KEYCODE_DPAD_CENTER;
+                    break;
+                case KeyEvent.KEYCODE_BUTTON_SELECT:
+                case KeyEvent.KEYCODE_BUTTON_MODE:
+                    keyCode = KeyEvent.KEYCODE_MENU;
+                default:
+                    return false;
+            }
+
+            enqueueInputEvent(new KeyEvent(event.getDownTime(), event.getEventTime(),
+                        event.getAction(), keyCode, event.getRepeatCount(), event.getMetaState(),
+                        event.getScanCode(), event.getFlags() | KeyEvent.FLAG_FALLBACK,
+                        event.getSource()));
+            return true;
+        }
+
+    }
+
     /**
      * Returns true if the key is used for keyboard navigation.
      * @param keyEvent The key event.
@@ -4952,7 +4999,7 @@
             // most recent data.
             mSeq = args.seq;
             mAttachInfo.mForceReportNewAttributes = true;
-            scheduleTraversals();            
+            scheduleTraversals();
         }
         if (mView == null) return;
         if (args.localChanges != 0) {
@@ -5042,7 +5089,7 @@
         if (restore) {
             params.restore();
         }
-        
+
         if (mTranslator != null) {
             mTranslator.translateRectInScreenToAppWinFrame(mWinFrame);
             mTranslator.translateRectInScreenToAppWindow(mPendingOverscanInsets);
@@ -5055,9 +5102,14 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public void playSoundEffect(int effectId) {
         checkThread();
 
+        if (mMediaDisabled) {
+            return;
+        }
+
         try {
             final AudioManager audioManager = getAudioManager();
 
@@ -5091,6 +5143,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public boolean performHapticFeedback(int effectId, boolean always) {
         try {
             return mWindowSession.performHapticFeedback(mWindow, effectId, always);
@@ -5102,6 +5155,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public View focusSearch(View focused, int direction) {
         checkThread();
         if (!(mView instanceof ViewGroup)) {
@@ -5113,7 +5167,7 @@
     public void debug() {
         mView.debug();
     }
-    
+
     public void dumpGfxInfo(int[] info) {
         info[0] = info[1] = 0;
         if (mView != null) {
@@ -5138,26 +5192,36 @@
         }
     }
 
-    public void die(boolean immediate) {
+    /**
+     * @param immediate True, do now if not in traversal. False, put on queue and do later.
+     * @return True, request has been queued. False, request has been completed.
+     */
+    boolean die(boolean immediate) {
         // Make sure we do execute immediately if we are in the middle of a traversal or the damage
         // done by dispatchDetachedFromWindow will cause havoc on return.
         if (immediate && !mIsInTraversal) {
             doDie();
-        } else {
-            if (!mIsDrawing) {
-                destroyHardwareRenderer();
-            } else {
-                Log.e(TAG, "Attempting to destroy the window while drawing!\n" +
-                        "  window=" + this + ", title=" + mWindowAttributes.getTitle());
-            }
-            mHandler.sendEmptyMessage(MSG_DIE);
+            return false;
         }
+
+        if (!mIsDrawing) {
+            destroyHardwareRenderer();
+        } else {
+            Log.e(TAG, "Attempting to destroy the window while drawing!\n" +
+                    "  window=" + this + ", title=" + mWindowAttributes.getTitle());
+        }
+        mHandler.sendEmptyMessage(MSG_DIE);
+        return true;
     }
 
     void doDie() {
         checkThread();
         if (LOCAL_LOGV) Log.v(TAG, "DIE in " + this + " of " + mSurface);
         synchronized (this) {
+            if (mRemoved) {
+                return;
+            }
+            mRemoved = true;
             if (mAdded) {
                 dispatchDetachedFromWindow();
             }
@@ -5181,13 +5245,14 @@
                         } catch (RemoteException e) {
                         }
                     }
-    
+
                     mSurface.release();
                 }
             }
 
             mAdded = false;
         }
+        WindowManagerGlobal.getInstance().doRemoveView(this);
     }
 
     public void requestUpdateConfiguration(Configuration config) {
@@ -5203,6 +5268,9 @@
                 mProfileRendering = SystemProperties.getBoolean(PROPERTY_PROFILE_RENDERING, false);
                 profileRendering(mAttachInfo.mHasWindowFocus);
 
+                // Media (used by sound effects)
+                mMediaDisabled = SystemProperties.getBoolean(PROPERTY_MEDIA_DISABLED, false);
+
                 // Hardware rendering
                 if (mAttachInfo.mHardwareRenderer != null) {
                     if (mAttachInfo.mHardwareRenderer.loadSystemProperties(mHolder.getSurface())) {
@@ -5518,8 +5586,8 @@
 
     final class InvalidateOnAnimationRunnable implements Runnable {
         private boolean mPosted;
-        private ArrayList<View> mViews = new ArrayList<View>();
-        private ArrayList<AttachInfo.InvalidateInfo> mViewRects =
+        private final ArrayList<View> mViews = new ArrayList<View>();
+        private final ArrayList<AttachInfo.InvalidateInfo> mViewRects =
                 new ArrayList<AttachInfo.InvalidateInfo>();
         private View[] mTempViews;
         private AttachInfo.InvalidateInfo[] mTempViewRects;
@@ -5632,8 +5700,8 @@
         mInvalidateOnAnimationRunnable.removeView(view);
     }
 
-    public void dispatchKey(KeyEvent event) {
-        Message msg = mHandler.obtainMessage(MSG_DISPATCH_KEY, event);
+    public void dispatchInputEvent(InputEvent event) {
+        Message msg = mHandler.obtainMessage(MSG_DISPATCH_INPUT_EVENT, event);
         msg.setAsynchronous(true);
         mHandler.sendMessage(msg);
     }
@@ -5663,7 +5731,7 @@
                         flags, event.getSource(), null);
                 fallbackAction.recycle();
 
-                dispatchKey(fallbackEvent);
+                dispatchInputEvent(fallbackEvent);
             }
         }
     }
@@ -5739,20 +5807,12 @@
      * This event is send at most once every
      * {@link ViewConfiguration#getSendRecurringAccessibilityEventsInterval()}.
      */
-    private void postSendWindowContentChangedCallback(View source) {
+    private void postSendWindowContentChangedCallback(View source, int changeType) {
         if (mSendWindowContentChangedAccessibilityEvent == null) {
             mSendWindowContentChangedAccessibilityEvent =
                 new SendWindowContentChangedAccessibilityEvent();
         }
-        View oldSource = mSendWindowContentChangedAccessibilityEvent.mSource;
-        if (oldSource == null) {
-            mSendWindowContentChangedAccessibilityEvent.mSource = source;
-            mHandler.postDelayed(mSendWindowContentChangedAccessibilityEvent,
-                    ViewConfiguration.getSendRecurringAccessibilityEventsInterval());
-        } else {
-            mSendWindowContentChangedAccessibilityEvent.mSource =
-                    getCommonPredecessor(oldSource, source);
-        }
+        mSendWindowContentChangedAccessibilityEvent.runOrPost(source, changeType);
     }
 
     /**
@@ -5765,20 +5825,25 @@
         }
     }
 
+    @Override
     public boolean showContextMenuForChild(View originalView) {
         return false;
     }
 
+    @Override
     public ActionMode startActionModeForChild(View originalView, ActionMode.Callback callback) {
         return null;
     }
 
+    @Override
     public void createContextMenu(ContextMenu menu) {
     }
 
+    @Override
     public void childDrawableStateChanged(View child) {
     }
 
+    @Override
     public boolean requestSendAccessibilityEvent(View child, AccessibilityEvent event) {
         if (mView == null) {
             return false;
@@ -5819,8 +5884,8 @@
     }
 
     @Override
-    public void childAccessibilityStateChanged(View child) {
-        postSendWindowContentChangedCallback(child);
+    public void notifySubtreeAccessibilityStateChanged(View child, View source, int changeType) {
+        postSendWindowContentChangedCallback(source, changeType);
     }
 
     @Override
@@ -5910,10 +5975,12 @@
         }
     }
 
+    @Override
     public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
         // ViewAncestor never intercepts touch event, so this can be a no-op
     }
 
+    @Override
     public boolean requestChildRectangleOnScreen(View child, Rect rectangle, boolean immediate) {
         final boolean scrolled = scrollToRectOrFocus(rectangle, immediate);
         if (rectangle != null) {
@@ -5929,10 +5996,16 @@
         return scrolled;
     }
 
+    @Override
     public void childHasTransientStateChanged(View child, boolean hasTransientState) {
         // Do nothing.
     }
 
+    void changeCanvasOpacity(boolean opaque) {
+        // TODO(romainguy): recreate Canvas (software or hardware) to reflect the opacity change.
+        Log.d(TAG, "changeCanvasOpacity: opaque=" + opaque);
+    }
+
     class TakenSurfaceHolder extends BaseSurfaceHolder {
         @Override
         public boolean onAllowLockCanvas() {
@@ -5944,20 +6017,23 @@
             // Not currently interesting -- from changing between fixed and layout size.
         }
 
+        @Override
         public void setFormat(int format) {
             ((RootViewSurfaceTaker)mView).setSurfaceFormat(format);
         }
 
+        @Override
         public void setType(int type) {
             ((RootViewSurfaceTaker)mView).setSurfaceType(type);
         }
-        
+
         @Override
         public void onUpdateSurface() {
             // We take care of format and type changes on our own.
             throw new IllegalStateException("Shouldn't be here");
         }
 
+        @Override
         public boolean isCreating() {
             return mIsCreating;
         }
@@ -5967,7 +6043,8 @@
             throw new UnsupportedOperationException(
                     "Currently only support sizing from layout");
         }
-        
+
+        @Override
         public void setKeepScreenOn(boolean screenOn) {
             ((RootViewSurfaceTaker)mView).setSurfaceKeepScreenOn(screenOn);
         }
@@ -5982,6 +6059,7 @@
             mWindowSession = viewAncestor.mWindowSession;
         }
 
+        @Override
         public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
                 Rect visibleInsets, boolean reportDraw, Configuration newConfig) {
             final ViewRootImpl viewAncestor = mViewAncestor.get();
@@ -5999,6 +6077,7 @@
             }
         }
 
+        @Override
         public void dispatchAppVisibility(boolean visible) {
             final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
@@ -6006,6 +6085,7 @@
             }
         }
 
+        @Override
         public void dispatchScreenState(boolean on) {
             final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
@@ -6013,6 +6093,7 @@
             }
         }
 
+        @Override
         public void dispatchGetNewSurface() {
             final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
@@ -6020,6 +6101,7 @@
             }
         }
 
+        @Override
         public void windowFocusChanged(boolean hasFocus, boolean inTouchMode) {
             final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
@@ -6036,6 +6118,7 @@
             }
         }
 
+        @Override
         public void executeCommand(String command, String parameters, ParcelFileDescriptor out) {
             final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
@@ -6066,14 +6149,16 @@
                 }
             }
         }
-        
+
+        @Override
         public void closeSystemDialogs(String reason) {
             final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
                 viewAncestor.dispatchCloseSystemDialogs(reason);
             }
         }
-        
+
+        @Override
         public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep,
                 boolean sync) {
             if (sync) {
@@ -6084,6 +6169,7 @@
             }
         }
 
+        @Override
         public void dispatchWallpaperCommand(String action, int x, int y,
                 int z, Bundle extras, boolean sync) {
             if (sync) {
@@ -6095,6 +6181,7 @@
         }
 
         /* Drag/drop */
+        @Override
         public void dispatchDragEvent(DragEvent event) {
             final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
@@ -6102,6 +6189,7 @@
             }
         }
 
+        @Override
         public void dispatchSystemUiVisibilityChanged(int seq, int globalVisibility,
                 int localValue, int localChanges) {
             final ViewRootImpl viewAncestor = mViewAncestor.get();
@@ -6111,6 +6199,7 @@
             }
         }
 
+        @Override
         public void doneAnimating() {
             final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
@@ -6125,50 +6214,63 @@
         }
     }
 
-    private SurfaceHolder mHolder = new SurfaceHolder() {
+    private final SurfaceHolder mHolder = new SurfaceHolder() {
         // we only need a SurfaceHolder for opengl. it would be nice
         // to implement everything else though, especially the callback
         // support (opengl doesn't make use of it right now, but eventually
         // will).
+        @Override
         public Surface getSurface() {
             return mSurface;
         }
 
+        @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 Rect getSurfaceFrame() {
             return null;
         }
@@ -6263,6 +6365,7 @@
      */
     final class AccessibilityInteractionConnectionManager
             implements AccessibilityStateChangeListener {
+        @Override
         public void onAccessibilityStateChanged(boolean enabled) {
             if (enabled) {
                 ensureConnection();
@@ -6435,13 +6538,48 @@
     }
 
     private class SendWindowContentChangedAccessibilityEvent implements Runnable {
-        public View mSource;
+        private int mChangeTypes = 0;
 
+        public View mSource;
+        public long mLastEventTimeMillis;
+
+        @Override
         public void run() {
+            // 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);
+            } else {
+                mLastEventTimeMillis = 0;
+            }
+            // In any case reset to initial state.
+            mSource.resetSubtreeAccessibilityStateChanged();
+            mSource = null;
+            mChangeTypes = 0;
+        }
+
+        public void runOrPost(View source, int changeType) {
             if (mSource != null) {
-                mSource.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
-                mSource.resetAccessibilityStateChanged();
-                mSource = null;
+                // If there is no common predecessor, then mSource points to
+                // a removed view, hence in this case always prefer the source.
+                View predecessor = getCommonPredecessor(mSource, source);
+                mSource = (predecessor != null) ? predecessor : source;
+                mChangeTypes |= changeType;
+                return;
+            }
+            mSource = source;
+            mChangeTypes = changeType;
+            final long timeSinceLastMillis = SystemClock.uptimeMillis() - mLastEventTimeMillis;
+            final long minEventIntevalMillis =
+                    ViewConfiguration.getSendRecurringAccessibilityEventsInterval();
+            if (timeSinceLastMillis >= minEventIntevalMillis) {
+                mSource.removeCallbacks(this);
+                run();
+            } else {
+                mSource.postDelayed(this, minEventIntevalMillis - timeSinceLastMillis);
             }
         }
     }
diff --git a/core/java/android/view/ViewTreeObserver.java b/core/java/android/view/ViewTreeObserver.java
index 072c95f..730c4eb 100644
--- a/core/java/android/view/ViewTreeObserver.java
+++ b/core/java/android/view/ViewTreeObserver.java
@@ -243,9 +243,9 @@
 
         @Override
         public int hashCode() {
-            int result = contentInsets != null ? contentInsets.hashCode() : 0;
-            result = 31 * result + (visibleInsets != null ? visibleInsets.hashCode() : 0);
-            result = 31 * result + (touchableRegion != null ? touchableRegion.hashCode() : 0);
+            int result = contentInsets.hashCode();
+            result = 31 * result + visibleInsets.hashCode();
+            result = 31 * result + touchableRegion.hashCode();
             result = 31 * result + mTouchableInsets;
             return result;
         }
@@ -814,6 +814,13 @@
     }
 
     /**
+     * Returns whether there are listeners for on pre-draw events.
+     */
+    final boolean hasOnPreDrawListeners() {
+        return mOnPreDrawListeners != null && mOnPreDrawListeners.size() > 0;
+    }
+
+    /**
      * Notifies registered listeners that the drawing pass is about to start. If a
      * listener returns true, then the drawing pass is canceled and rescheduled. This can
      * be called manually if you are forcing the drawing on a View or a hierarchy of Views
diff --git a/core/java/android/view/VolumePanel.java b/core/java/android/view/VolumePanel.java
index 9c00b7f..f0e6677 100644
--- a/core/java/android/view/VolumePanel.java
+++ b/core/java/android/view/VolumePanel.java
@@ -32,6 +32,7 @@
 import android.media.AudioSystem;
 import android.media.RingtoneManager;
 import android.media.ToneGenerator;
+import android.media.VolumeController;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.Message;
@@ -55,7 +56,8 @@
  *
  * @hide
  */
-public class VolumePanel extends Handler implements OnSeekBarChangeListener, View.OnClickListener
+public class VolumePanel extends Handler implements OnSeekBarChangeListener, View.OnClickListener,
+        VolumeController
 {
     private static final String TAG = "VolumePanel";
     private static boolean LOGD = false;
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 06974d3..7a24243 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -1256,4 +1256,52 @@
      * @param mask Flags specifying which options should be modified. Others will remain unchanged.
      */
     public void setUiOptions(int uiOptions, int mask) { }
+
+    /**
+     * Set the primary icon for this window.
+     *
+     * @param resId resource ID of a drawable to set
+     */
+    public void setIcon(int resId) { }
+
+    /**
+     * Set the default icon for this window.
+     * This will be overridden by any other icon set operation which could come from the
+     * theme or another explicit set.
+     *
+     * @hide
+     */
+    public void setDefaultIcon(int resId) { }
+
+    /**
+     * Set the logo for this window. A logo is often shown in place of an
+     * {@link #setIcon(int) icon} but is generally wider and communicates window title information
+     * as well.
+     *
+     * @param resId resource ID of a drawable to set
+     */
+    public void setLogo(int resId) { }
+
+    /**
+     * Set the default logo for this window.
+     * This will be overridden by any other logo set operation which could come from the
+     * theme or another explicit set.
+     *
+     * @hide
+     */
+    public void setDefaultLogo(int resId) { }
+
+    /**
+     * Set focus locally. The window should have the
+     * {@link WindowManager.LayoutParams#FLAG_LOCAL_FOCUS_MODE} flag set already.
+     * @param hasFocus Whether this window has focus or not.
+     * @param inTouchMode Whether this window is in touch mode or not.
+     */
+    public void setLocalFocus(boolean hasFocus, boolean inTouchMode) { }
+
+    /**
+     * Inject an event to window locally.
+     * @param event A key or touch event to inject to this window.
+     */
+    public void injectInputEvent(InputEvent event) { }
 }
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 541c503..c9c74e7 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -219,7 +219,8 @@
             @ViewDebug.IntToString(from = TYPE_DREAM, to = "TYPE_DREAM"),
             @ViewDebug.IntToString(from = TYPE_NAVIGATION_BAR_PANEL, to = "TYPE_NAVIGATION_BAR_PANEL"),
             @ViewDebug.IntToString(from = TYPE_DISPLAY_OVERLAY, to = "TYPE_DISPLAY_OVERLAY"),
-            @ViewDebug.IntToString(from = TYPE_MAGNIFICATION_OVERLAY, to = "TYPE_MAGNIFICATION_OVERLAY")
+            @ViewDebug.IntToString(from = TYPE_MAGNIFICATION_OVERLAY, to = "TYPE_MAGNIFICATION_OVERLAY"),
+            @ViewDebug.IntToString(from = TYPE_PRIVATE_PRESENTATION, to = "TYPE_PRIVATE_PRESENTATION")
         })
         public int type;
     
@@ -527,6 +528,20 @@
          */
         public static final int TYPE_RECENTS_OVERLAY = FIRST_SYSTEM_WINDOW+28;
 
+
+        /**
+         * Window type: keyguard scrim window. Shows if keyguard needs to be restarted.
+         * In multiuser systems shows on all users' windows.
+         * @hide
+         */
+        public static final int TYPE_KEYGUARD_SCRIM           = FIRST_SYSTEM_WINDOW+29;
+
+        /**
+         * Window type: Window for Presentation on top of private
+         * virtual display.
+         */
+        public static final int TYPE_PRIVATE_PRESENTATION = FIRST_SYSTEM_WINDOW+30;
+
         /**
          * End of types of system windows.
          */
@@ -851,6 +866,15 @@
          */
         public static final int FLAG_NEEDS_MENU_KEY = 0x08000000;
 
+        /**
+         * Flag for a window in local focus mode.
+         * Window in local focus mode can control focus independent of window manager using
+         * {@link Window#setLocalFocus(boolean, boolean)}.
+         * Usually window in this mode will not get touch/key events from window manager, but will
+         * get events only via local injection using {@link Window#injectInputEvent(InputEvent)}.
+         */
+        public static final int FLAG_LOCAL_FOCUS_MODE = 0x10000000;
+
         /** Window flag: special flag to limit the size of the window to be
          * original size ([320x480] x density). Used to create window for applications
          * running under compatibility mode.
@@ -890,6 +914,7 @@
          * @see #FLAG_DISMISS_KEYGUARD
          * @see #FLAG_SPLIT_TOUCH
          * @see #FLAG_HARDWARE_ACCELERATED
+         * @see #FLAG_LOCAL_FOCUS_MODE
          */
         @ViewDebug.ExportedProperty(flagMapping = {
             @ViewDebug.FlagToString(mask = FLAG_ALLOW_LOCK_WHILE_SCREEN_ON, equals = FLAG_ALLOW_LOCK_WHILE_SCREEN_ON,
@@ -941,7 +966,9 @@
             @ViewDebug.FlagToString(mask = FLAG_SPLIT_TOUCH, equals = FLAG_SPLIT_TOUCH,
                     name = "FLAG_SPLIT_TOUCH"),
             @ViewDebug.FlagToString(mask = FLAG_HARDWARE_ACCELERATED, equals = FLAG_HARDWARE_ACCELERATED,
-                    name = "FLAG_HARDWARE_ACCELERATED")
+                    name = "FLAG_HARDWARE_ACCELERATED"),
+            @ViewDebug.FlagToString(mask = FLAG_LOCAL_FOCUS_MODE, equals = FLAG_LOCAL_FOCUS_MODE,
+                    name = "FLAG_LOCAL_FOCUS_MODE")
         })
         public int flags;
 
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index 0ff46e9..96c0ed2 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -22,17 +22,19 @@
 import android.content.res.Configuration;
 import android.opengl.ManagedEGLContext;
 import android.os.IBinder;
-import android.os.Looper;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemProperties;
 import android.util.AndroidRuntimeException;
+import android.util.ArraySet;
 import android.util.Log;
 import android.view.inputmethod.InputMethodManager;
+import com.android.internal.util.FastPrintWriter;
 
 import java.io.FileDescriptor;
 import java.io.FileOutputStream;
 import java.io.PrintWriter;
+import java.util.ArrayList;
 
 /**
  * Provides low-level communication with the system window manager for
@@ -107,9 +109,11 @@
 
     private final Object mLock = new Object();
 
-    private View[] mViews;
-    private ViewRootImpl[] mRoots;
-    private WindowManager.LayoutParams[] mParams;
+    private final ArrayList<View> mViews = new ArrayList<View>();
+    private final ArrayList<ViewRootImpl> mRoots = new ArrayList<ViewRootImpl>();
+    private final ArrayList<WindowManager.LayoutParams> mParams =
+            new ArrayList<WindowManager.LayoutParams>();
+    private final ArraySet<View> mDyingViews = new ArraySet<View>();
     private boolean mNeedsEglTerminate;
 
     private Runnable mSystemPropertyUpdater;
@@ -162,11 +166,10 @@
 
     public String[] getViewRootNames() {
         synchronized (mLock) {
-            if (mRoots == null) return new String[0];
-            String[] mViewRoots = new String[mRoots.length];
-            int i = 0;
-            for (ViewRootImpl root : mRoots) {
-                mViewRoots[i++] = getWindowName(root);
+            final int numRoots = mRoots.size();
+            String[] mViewRoots = new String[numRoots];
+            for (int i = 0; i < numRoots; ++i) {
+                mViewRoots[i] = getWindowName(mRoots.get(i));
             }
             return mViewRoots;
         }
@@ -174,8 +177,8 @@
 
     public View getRootView(String name) {
         synchronized (mLock) {
-            if (mRoots == null) return null;
-            for (ViewRootImpl root : mRoots) {
+            for (int i = mRoots.size() - 1; i >= 0; --i) {
+                final ViewRootImpl root = mRoots.get(i);
                 if (name.equals(getWindowName(root))) return root.getView();
             }
         }
@@ -209,8 +212,8 @@
                 mSystemPropertyUpdater = new Runnable() {
                     @Override public void run() {
                         synchronized (mLock) {
-                            for (ViewRootImpl viewRoot : mRoots) {
-                                viewRoot.loadSystemProperties();
+                            for (int i = mRoots.size() - 1; i >= 0; --i) {
+                                mRoots.get(i).loadSystemProperties();
                             }
                         }
                     }
@@ -220,18 +223,24 @@
 
             int index = findViewLocked(view, false);
             if (index >= 0) {
-                throw new IllegalStateException("View " + view
-                        + " has already been added to the window manager.");
+                if (mDyingViews.contains(view)) {
+                    // Don't wait for MSG_DIE to make it's way through root's queue.
+                    mRoots.get(index).doDie();
+                } else {
+                    throw new IllegalStateException("View " + view
+                            + " has already been added to the window manager.");
+                }
+                // The previous removeView() had not completed executing. Now it has.
             }
 
             // If this is a panel window, then find the window it is being
             // attached to for future reference.
             if (wparams.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW &&
                     wparams.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
-                final int count = mViews != null ? mViews.length : 0;
-                for (int i=0; i<count; i++) {
-                    if (mRoots[i].mWindow.asBinder() == wparams.token) {
-                        panelParentView = mViews[i];
+                final int count = mViews.size();
+                for (int i = 0; i < count; i++) {
+                    if (mRoots.get(i).mWindow.asBinder() == wparams.token) {
+                        panelParentView = mViews.get(i);
                     }
                 }
             }
@@ -240,28 +249,9 @@
 
             view.setLayoutParams(wparams);
 
-            if (mViews == null) {
-                index = 1;
-                mViews = new View[1];
-                mRoots = new ViewRootImpl[1];
-                mParams = new WindowManager.LayoutParams[1];
-            } else {
-                index = mViews.length + 1;
-                Object[] old = mViews;
-                mViews = new View[index];
-                System.arraycopy(old, 0, mViews, 0, index-1);
-                old = mRoots;
-                mRoots = new ViewRootImpl[index];
-                System.arraycopy(old, 0, mRoots, 0, index-1);
-                old = mParams;
-                mParams = new WindowManager.LayoutParams[index];
-                System.arraycopy(old, 0, mParams, 0, index-1);
-            }
-            index--;
-
-            mViews[index] = view;
-            mRoots[index] = root;
-            mParams[index] = wparams;
+            mViews.add(view);
+            mRoots.add(root);
+            mParams.add(wparams);
         }
 
         // do this last because it fires off messages to start doing things
@@ -293,8 +283,9 @@
 
         synchronized (mLock) {
             int index = findViewLocked(view, true);
-            ViewRootImpl root = mRoots[index];
-            mParams[index] = wparams;
+            ViewRootImpl root = mRoots.get(index);
+            mParams.remove(index);
+            mParams.add(index, wparams);
             root.setLayoutParams(wparams, false);
         }
     }
@@ -306,7 +297,8 @@
 
         synchronized (mLock) {
             int index = findViewLocked(view, true);
-            View curView = removeViewLocked(index, immediate);
+            View curView = mRoots.get(index).getView();
+            removeViewLocked(index, immediate);
             if (curView == view) {
                 return;
             }
@@ -318,16 +310,13 @@
 
     public void closeAll(IBinder token, String who, String what) {
         synchronized (mLock) {
-            if (mViews == null)
-                return;
-
-            int count = mViews.length;
+            int count = mViews.size();
             //Log.i("foo", "Closing all windows of " + token);
-            for (int i=0; i<count; i++) {
+            for (int i = 0; i < count; i++) {
                 //Log.i("foo", "@ " + i + " token " + mParams[i].token
                 //        + " view " + mRoots[i].getView());
-                if (token == null || mParams[i].token == token) {
-                    ViewRootImpl root = mRoots[i];
+                if (token == null || mParams.get(i).token == token) {
+                    ViewRootImpl root = mRoots.get(i);
 
                     //Log.i("foo", "Force closing " + root);
                     if (who != null) {
@@ -335,77 +324,52 @@
                                 what + " " + who + " has leaked window "
                                 + root.getView() + " that was originally added here");
                         leak.setStackTrace(root.getLocation().getStackTrace());
-                        Log.e(TAG, leak.getMessage(), leak);
+                        Log.e(TAG, "", leak);
                     }
 
                     removeViewLocked(i, false);
-                    i--;
-                    count--;
                 }
             }
         }
     }
 
-    private View removeViewLocked(int index, boolean immediate) {
-        ViewRootImpl root = mRoots[index];
+    private void removeViewLocked(int index, boolean immediate) {
+        ViewRootImpl root = mRoots.get(index);
         View view = root.getView();
 
         if (view != null) {
             InputMethodManager imm = InputMethodManager.getInstance();
             if (imm != null) {
-                imm.windowDismissed(mViews[index].getWindowToken());
+                imm.windowDismissed(mViews.get(index).getWindowToken());
             }
         }
-        root.die(immediate);
-
-        final int count = mViews.length;
-
-        // remove it from the list
-        View[] tmpViews = new View[count-1];
-        removeItem(tmpViews, mViews, index);
-        mViews = tmpViews;
-
-        ViewRootImpl[] tmpRoots = new ViewRootImpl[count-1];
-        removeItem(tmpRoots, mRoots, index);
-        mRoots = tmpRoots;
-
-        WindowManager.LayoutParams[] tmpParams
-                = new WindowManager.LayoutParams[count-1];
-        removeItem(tmpParams, mParams, index);
-        mParams = tmpParams;
-
+        boolean deferred = root.die(immediate);
         if (view != null) {
             view.assignParent(null);
-            // func doesn't allow null...  does it matter if we clear them?
-            //view.setLayoutParams(null);
+            if (deferred) {
+                mDyingViews.add(view);
+            }
         }
-        return view;
     }
 
-    private static void removeItem(Object[] dst, Object[] src, int index) {
-        if (dst.length > 0) {
-            if (index > 0) {
-                System.arraycopy(src, 0, dst, 0, index);
-            }
-            if (index < dst.length) {
-                System.arraycopy(src, index+1, dst, index, src.length-index-1);
+    void doRemoveView(ViewRootImpl root) {
+        synchronized (mLock) {
+            final int index = mRoots.indexOf(root);
+            if (index >= 0) {
+                mRoots.remove(index);
+                mParams.remove(index);
+                final View view = mViews.remove(index);
+                mDyingViews.remove(view);
             }
         }
     }
 
     private int findViewLocked(View view, boolean required) {
-        if (mViews != null) {
-            final int count = mViews.length;
-            for (int i = 0; i < count; i++) {
-                if (mViews[i] == view) {
-                    return i;
-                }
-            }
+        final int index = mViews.indexOf(view);
+        if (required && index < 0) {
+            throw new IllegalArgumentException("View=" + view + " not attached to window manager");
         }
-        if (required) {
-            throw new IllegalArgumentException("View not attached to window manager");
-        }
-        return -1;
+        return index;
     }
 
     public void startTrimMemory(int level) {
@@ -418,10 +382,8 @@
                 // Destroy all hardware surfaces and resources associated to
                 // known windows
                 synchronized (mLock) {
-                    if (mViews == null) return;
-                    int count = mViews.length;
-                    for (int i = 0; i < count; i++) {
-                        mRoots[i].terminateHardwareResources();
+                    for (int i = mRoots.size() - 1; i >= 0; --i) {
+                        mRoots.get(i).destroyHardwareResources();
                     }
                 }
                 // Force a full memory flush
@@ -445,64 +407,60 @@
 
     public void trimLocalMemory() {
         synchronized (mLock) {
-            if (mViews == null) return;
-            int count = mViews.length;
-            for (int i = 0; i < count; i++) {
-                mRoots[i].destroyHardwareLayers();
+            for (int i = mRoots.size() - 1; i >= 0; --i) {
+                mRoots.get(i).destroyHardwareLayers();
             }
         }
     }
 
     public void dumpGfxInfo(FileDescriptor fd) {
         FileOutputStream fout = new FileOutputStream(fd);
-        PrintWriter pw = new PrintWriter(fout);
+        PrintWriter pw = new FastPrintWriter(fout);
         try {
             synchronized (mLock) {
-                if (mViews != null) {
-                    final int count = mViews.length;
+                final int count = mViews.size();
 
-                    pw.println("Profile data in ms:");
+                pw.println("Profile data in ms:");
 
-                    for (int i = 0; i < count; i++) {
-                        ViewRootImpl root = mRoots[i];
-                        String name = getWindowName(root);
-                        pw.printf("\n\t%s", name);
+                for (int i = 0; i < count; i++) {
+                    ViewRootImpl root = mRoots.get(i);
+                    String name = getWindowName(root);
+                    pw.printf("\n\t%s", name);
 
-                        HardwareRenderer renderer =
-                                root.getView().mAttachInfo.mHardwareRenderer;
-                        if (renderer != null) {
-                            renderer.dumpGfxInfo(pw);
-                        }
+                    HardwareRenderer renderer =
+                            root.getView().mAttachInfo.mHardwareRenderer;
+                    if (renderer != null) {
+                        renderer.dumpGfxInfo(pw);
                     }
-
-                    pw.println("\nView hierarchy:\n");
-
-                    int viewsCount = 0;
-                    int displayListsSize = 0;
-                    int[] info = new int[2];
-
-                    for (int i = 0; i < count; i++) {
-                        ViewRootImpl root = mRoots[i];
-                        root.dumpGfxInfo(info);
-
-                        String name = getWindowName(root);
-                        pw.printf("  %s\n  %d views, %.2f kB of display lists",
-                                name, info[0], info[1] / 1024.0f);
-                        HardwareRenderer renderer =
-                                root.getView().mAttachInfo.mHardwareRenderer;
-                        if (renderer != null) {
-                            pw.printf(", %d frames rendered", renderer.getFrameCount());
-                        }
-                        pw.printf("\n\n");
-
-                        viewsCount += info[0];
-                        displayListsSize += info[1];
-                    }
-
-                    pw.printf("\nTotal ViewRootImpl: %d\n", count);
-                    pw.printf("Total Views:        %d\n", viewsCount);
-                    pw.printf("Total DisplayList:  %.2f kB\n\n", displayListsSize / 1024.0f);
                 }
+
+                pw.println("\nView hierarchy:\n");
+
+                int viewsCount = 0;
+                int displayListsSize = 0;
+                int[] info = new int[2];
+
+                for (int i = 0; i < count; i++) {
+                    ViewRootImpl root = mRoots.get(i);
+                    root.dumpGfxInfo(info);
+
+                    String name = getWindowName(root);
+                    pw.printf("  %s\n  %d views, %.2f kB of display lists",
+                            name, info[0], info[1] / 1024.0f);
+                    HardwareRenderer renderer =
+                            root.getView().mAttachInfo.mHardwareRenderer;
+                    if (renderer != null) {
+                        pw.printf(", %d frames rendered", renderer.getFrameCount());
+                    }
+                    pw.printf("\n\n");
+
+                    viewsCount += info[0];
+                    displayListsSize += info[1];
+                }
+
+                pw.printf("\nTotal ViewRootImpl: %d\n", count);
+                pw.printf("Total Views:        %d\n", viewsCount);
+                pw.printf("Total DisplayList:  %.2f kB\n\n", displayListsSize / 1024.0f);
             }
         } finally {
             pw.flush();
@@ -516,13 +474,11 @@
 
     public void setStoppedState(IBinder token, boolean stopped) {
         synchronized (mLock) {
-            if (mViews != null) {
-                int count = mViews.length;
-                for (int i=0; i < count; i++) {
-                    if (token == null || mParams[i].token == token) {
-                        ViewRootImpl root = mRoots[i];
-                        root.setStopped(stopped);
-                    }
+            int count = mViews.size();
+            for (int i = 0; i < count; i++) {
+                if (token == null || mParams.get(i).token == token) {
+                    ViewRootImpl root = mRoots.get(i);
+                    root.setStopped(stopped);
                 }
             }
         }
@@ -530,12 +486,25 @@
 
     public void reportNewConfiguration(Configuration config) {
         synchronized (mLock) {
-            if (mViews != null) {
-                int count = mViews.length;
-                config = new Configuration(config);
-                for (int i=0; i < count; i++) {
-                    ViewRootImpl root = mRoots[i];
-                    root.requestUpdateConfiguration(config);
+            int count = mViews.size();
+            config = new Configuration(config);
+            for (int i=0; i < count; i++) {
+                ViewRootImpl root = mRoots.get(i);
+                root.requestUpdateConfiguration(config);
+            }
+        }
+    }
+
+    /** @hide */
+    public void changeCanvasOpacity(IBinder token, boolean opaque) {
+        if (token == null) {
+            return;
+        }
+        synchronized (mLock) {
+            for (int i = mParams.size() - 1; i >= 0; --i) {
+                if (mParams.get(i).token == token) {
+                    mRoots.get(i).changeCanvasOpacity(opaque);
+                    return;
                 }
             }
         }
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index c0044b6..e116662 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -408,11 +408,6 @@
         public int getLidState();
 
         /**
-         * Creates an input channel that will receive all input from the input dispatcher.
-         */
-        public InputChannel monitorInput(String name);
-
-        /**
          * Switch the keyboard layout for the given device.
          * Direction should be +1 or -1 to go to the next or previous keyboard layout.
          */
@@ -420,6 +415,26 @@
 
         public void shutdown(boolean confirm);
         public void rebootSafeMode(boolean confirm);
+
+        /**
+         * Return the window manager lock needed to correctly call "Lw" methods.
+         */
+        public Object getWindowManagerLock();
+
+        /** Register a system listener for touch events */
+        void registerPointerEventListener(PointerEventListener listener);
+
+        /** Unregister a system listener for touch events */
+        void unregisterPointerEventListener(PointerEventListener listener);
+    }
+
+    public interface PointerEventListener {
+        /**
+         * 1. onPointerEvent will be called on the service.UiThread.
+         * 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);
     }
 
     /** Window has been added to the screen. */
@@ -463,6 +478,11 @@
             WindowManagerFuncs windowManagerFuncs);
 
     /**
+     * @return true if com.android.internal.R.bool#config_forceDefaultOrientation is true.
+     */
+    public boolean isDefaultOrientationForced();
+
+    /**
      * Called by window manager once it has the initial, default native
      * display dimensions.
      */
@@ -563,12 +583,6 @@
     public int getAboveUniverseLayer();
 
     /**
-     * Return true if the policy desires a full unified system nav bar.  Otherwise,
-     * it is a phone-style status bar with optional nav bar.
-     */
-    public boolean hasSystemNavBar();
-
-    /**
      * Return the display width available after excluding any screen
      * decorations that can never be removed.  That is, system bar or
      * button bar.
@@ -637,7 +651,7 @@
      */
     public View addStartingWindow(IBinder appToken, String packageName,
             int theme, CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel,
-            int labelRes, int icon, int windowFlags);
+            int labelRes, int icon, int logo, int windowFlags);
 
     /**
      * Called when the first window of an application has been displayed, while
@@ -816,6 +830,14 @@
     public int getSystemDecorRectLw(Rect systemRect);
 
     /**
+     * Return the rectangle of the screen that is available for applications to run in.
+     * This will be called immediately after {@link #beginLayoutLw}.
+     *
+     * @param r The rectangle to be filled with the boundaries available to applications.
+     */
+    public void getContentRectLw(Rect r);
+
+    /**
      * Called for each window attached to the window manager as layout is
      * proceeding.  The implementation of this function must take care of
      * setting the window's frame, either here or in finishLayout().
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index dbeca1f..7e2bffa 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -326,6 +326,7 @@
  * <em>Properties:</em></br>
  * <ul>
  *   <li>{@link #getEventType()} - The type of the event.</li>
+ *   <li>{@link #getContentChangeTypes()} - The type of content changes.</li>
  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
  *   <li>{@link #getClassName()} - The class name of the source.</li>
  *   <li>{@link #getPackageName()} - The package name of the source.</li>
@@ -661,6 +662,30 @@
     public static final int TYPE_TOUCH_INTERACTION_END = 0x00200000;
 
     /**
+     * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
+     * The type of change is not defined.
+     */
+    public static final int CONTENT_CHANGE_TYPE_UNDEFINED = 0x00000000;
+
+    /**
+     * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
+     * A node in the subtree rooted at the source node was added or removed.
+     */
+    public static final int CONTENT_CHANGE_TYPE_SUBTREE = 0x00000001;
+
+    /**
+     * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
+     * The node's text changed.
+     */
+    public static final int CONTENT_CHANGE_TYPE_TEXT = 0x00000002;
+
+    /**
+     * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
+     * The node's content description changed.
+     */
+    public static final int CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION = 0x00000004;
+
+    /**
      * Mask for {@link AccessibilityEvent} all types.
      *
      * @see #TYPE_VIEW_CLICKED
@@ -695,6 +720,7 @@
     private long mEventTime;
     int mMovementGranularity;
     int mAction;
+    int mContentChangeTypes;
 
     private final ArrayList<AccessibilityRecord> mRecords = new ArrayList<AccessibilityRecord>();
 
@@ -714,6 +740,7 @@
         mEventType = event.mEventType;
         mMovementGranularity = event.mMovementGranularity;
         mAction = event.mAction;
+        mContentChangeTypes = event.mContentChangeTypes;
         mEventTime = event.mEventTime;
         mPackageName = event.mPackageName;
     }
@@ -777,6 +804,36 @@
     }
 
     /**
+     * Gets the bit mask of change types signaled by an
+     * {@link #TYPE_WINDOW_CONTENT_CHANGED} event. A single event may represent
+     * multiple change types.
+     *
+     * @return The bit mask of change types. One or more of:
+     *         <ul>
+     *         <li>{@link AccessibilityEvent#CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION}
+     *         <li>{@link AccessibilityEvent#CONTENT_CHANGE_TYPE_SUBTREE}
+     *         <li>{@link AccessibilityEvent#CONTENT_CHANGE_TYPE_TEXT}
+     *         <li>{@link AccessibilityEvent#CONTENT_CHANGE_TYPE_UNDEFINED}
+     *         </ul>
+     */
+    public int getContentChangeTypes() {
+        return mContentChangeTypes;
+    }
+
+    /**
+     * Sets the bit mask of node tree changes signaled by an
+     * {@link #TYPE_WINDOW_CONTENT_CHANGED} event.
+     *
+     * @param changeTypes The bit mask of change types.
+     * @throws IllegalStateException If called from an AccessibilityService.
+     * @see #getContentChangeTypes()
+     */
+    public void setContentChangeTypes(int changeTypes) {
+        enforceNotSealed();
+        mContentChangeTypes = changeTypes;
+    }
+
+    /**
      * Sets the event type.
      *
      * @param eventType The event type.
@@ -943,6 +1000,7 @@
         mEventType = 0;
         mMovementGranularity = 0;
         mAction = 0;
+        mContentChangeTypes = 0;
         mPackageName = null;
         mEventTime = 0;
         while (!mRecords.isEmpty()) {
@@ -961,6 +1019,7 @@
         mEventType = parcel.readInt();
         mMovementGranularity = parcel.readInt();
         mAction = parcel.readInt();
+        mContentChangeTypes = parcel.readInt();
         mPackageName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
         mEventTime = parcel.readLong();
         mConnectionId = parcel.readInt();
@@ -1013,6 +1072,7 @@
         parcel.writeInt(mEventType);
         parcel.writeInt(mMovementGranularity);
         parcel.writeInt(mAction);
+        parcel.writeInt(mContentChangeTypes);
         TextUtils.writeToParcel(mPackageName, parcel, 0);
         parcel.writeLong(mEventTime);
         parcel.writeInt(mConnectionId);
@@ -1074,6 +1134,7 @@
         builder.append(super.toString());
         if (DEBUG) {
             builder.append("\n");
+            builder.append("; ContentChangeTypes: ").append(mContentChangeTypes);
             builder.append("; sourceWindowId: ").append(mSourceWindowId);
             builder.append("; mSourceNodeId: ").append(mSourceNodeId);
             for (int i = 0; i < mRecords.size(); i++) {
diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
index 84d7e72..139df3e 100644
--- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java
+++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
@@ -163,7 +163,7 @@
     public AccessibilityNodeInfo getRootInActiveWindow(int connectionId) {
         return findAccessibilityNodeInfoByAccessibilityId(connectionId,
                 AccessibilityNodeInfo.ACTIVE_WINDOW_ID, AccessibilityNodeInfo.ROOT_NODE_ID,
-                AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS);
+                false, AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS);
     }
 
     /**
@@ -177,18 +177,22 @@
      *     where to start the search. Use
      *     {@link android.view.accessibility.AccessibilityNodeInfo#ROOT_NODE_ID}
      *     to start from the root.
+     * @param bypassCache Whether to bypass the cache while looking for the node.
      * @param prefetchFlags flags to guide prefetching.
      * @return An {@link AccessibilityNodeInfo} if found, null otherwise.
      */
     public AccessibilityNodeInfo findAccessibilityNodeInfoByAccessibilityId(int connectionId,
-            int accessibilityWindowId, long accessibilityNodeId, int prefetchFlags) {
+            int accessibilityWindowId, long accessibilityNodeId, boolean bypassCache,
+            int prefetchFlags) {
         try {
             IAccessibilityServiceConnection connection = getConnection(connectionId);
             if (connection != null) {
-                AccessibilityNodeInfo cachedInfo = sAccessibilityNodeInfoCache.get(
-                        accessibilityNodeId);
-                if (cachedInfo != null) {
-                    return cachedInfo;
+                if (!bypassCache) {
+                    AccessibilityNodeInfo cachedInfo = sAccessibilityNodeInfoCache.get(
+                            accessibilityNodeId);
+                    if (cachedInfo != null) {
+                        return cachedInfo;
+                    }
                 }
                 final int interactionId = mInteractionIdCounter.getAndIncrement();
                 final boolean success = connection.findAccessibilityNodeInfoByAccessibilityId(
@@ -350,7 +354,7 @@
             }
         } catch (RemoteException re) {
             if (DEBUG) {
-                Log.w(LOG_TAG, "Error while calling remote findAccessibilityFocus", re);
+                Log.w(LOG_TAG, "Error while calling remote findFocus", re);
             }
         }
         return null;
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index 732699b..04ce7e2 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -16,14 +16,17 @@
 
 package android.view.accessibility;
 
+import android.Manifest;
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
@@ -132,29 +135,6 @@
     }
 
     /**
-     * Creates the singleton AccessibilityManager to be shared across users. This
-     * has to be called before the local AccessibilityManager is created to ensure
-     * it registers itself in the system correctly.
-     * <p>
-     * Note: Calling this method requires INTERACT_ACROSS_USERS_FULL or
-     *       INTERACT_ACROSS_USERS permission.
-     * </p>
-     * @param context Context in which this manager operates.
-     * @throws IllegalStateException if not called before the local
-     *     AccessibilityManager is instantiated.
-     *
-     * @hide
-     */
-    public static void createAsSharedAcrossUsers(Context context) {
-        synchronized (sInstanceSync) {
-            if (sInstance != null) {
-                throw new IllegalStateException("AccessibilityManager already created.");
-            }
-            createSingletonInstance(context, UserHandle.USER_CURRENT);
-        }
-    }
-
-    /**
      * Get an AccessibilityManager instance (create one if necessary).
      *
      * @param context Context in which this manager operates.
@@ -164,25 +144,27 @@
     public static AccessibilityManager getInstance(Context context) {
         synchronized (sInstanceSync) {
             if (sInstance == null) {
-                createSingletonInstance(context, UserHandle.myUserId());
+                final int userId;
+                if (Binder.getCallingUid() == Process.SYSTEM_UID
+                        || context.checkCallingOrSelfPermission(
+                                Manifest.permission.INTERACT_ACROSS_USERS)
+                                        == PackageManager.PERMISSION_GRANTED
+                        || context.checkCallingOrSelfPermission(
+                                Manifest.permission.INTERACT_ACROSS_USERS_FULL)
+                                        == PackageManager.PERMISSION_GRANTED) {
+                    userId = UserHandle.USER_CURRENT;
+                } else {
+                    userId = UserHandle.myUserId();
+                }
+                IBinder iBinder = ServiceManager.getService(Context.ACCESSIBILITY_SERVICE);
+                IAccessibilityManager service = IAccessibilityManager.Stub.asInterface(iBinder);
+                sInstance = new AccessibilityManager(context, service, userId);
             }
         }
         return sInstance;
     }
 
     /**
-     * Creates the singleton instance.
-     *
-     * @param context Context in which this manager operates.
-     * @param userId The user id under which to operate.
-     */
-    private static void createSingletonInstance(Context context, int userId) {
-        IBinder iBinder = ServiceManager.getService(Context.ACCESSIBILITY_SERVICE);
-        IAccessibilityManager service = IAccessibilityManager.Stub.asInterface(iBinder);
-        sInstance = new AccessibilityManager(context, service, userId);
-    }
-
-    /**
      * Create an instance.
      *
      * @param context A {@link Context}.
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index d9c9b69..9fc37cf 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -21,6 +21,7 @@
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.text.InputType;
 import android.util.Pools.SynchronizedPool;
 import android.util.SparseLongArray;
 import android.view.View;
@@ -267,6 +268,23 @@
     public static final int ACTION_SET_SELECTION = 0x00020000;
 
     /**
+     * Action to expand an expandable node.
+     */
+    public static final int ACTION_EXPAND = 0x00040000;
+
+    /**
+     * Action to collapse an expandable node.
+     */
+    public static final int ACTION_COLLAPSE = 0x00080000;
+
+    /**
+     * Action to dismiss a dismissable node.
+     */
+    public static final int ACTION_DISMISS = 0x00100000;
+
+    // Action arguments
+
+    /**
      * Argument for which movement granularity to be used when traversing the node text.
      * <p>
      * <strong>Type:</strong> int<br>
@@ -333,6 +351,8 @@
     public static final String ACTION_ARGUMENT_SELECTION_END_INT =
             "ACTION_ARGUMENT_SELECTION_END_INT";
 
+    // Focus types
+
     /**
      * The input focus.
      */
@@ -398,6 +418,14 @@
 
     private static final int BOOLEAN_PROPERTY_EDITABLE = 0x00001000;
 
+    private static final int BOOLEAN_PROPERTY_OPENS_POPUP = 0x00002000;
+
+    private static final int BOOLEAN_PROPERTY_DISMISSABLE = 0x00004000;
+
+    private static final int BOOLEAN_PROPERTY_MULTI_LINE = 0x00008000;
+
+    private static final int BOOLEAN_PROPERTY_CONTENT_INVALID = 0x00010000;
+
     /**
      * Bits that provide the id of a virtual descendant of a view.
      */
@@ -482,9 +510,17 @@
 
     private int mTextSelectionStart = UNDEFINED;
     private int mTextSelectionEnd = UNDEFINED;
+    private int mInputType = InputType.TYPE_NULL;
+    private int mLiveRegion = View.ACCESSIBILITY_LIVE_REGION_NONE;
+
+    private Bundle mExtras;
 
     private int mConnectionId = UNDEFINED;
 
+    private RangeInfo mRangeInfo;
+    private CollectionInfo mCollectionInfo;
+    private CollectionItemInfo mCollectionItemInfo;
+
     /**
      * Hide constructor from clients.
      */
@@ -594,16 +630,20 @@
      * since it represents a view that is no longer in the view tree and should
      * be recycled.
      * </p>
+     *
+     * @param bypassCache Whether to bypass the cache.
      * @return Whether the refresh succeeded.
+     *
+     * @hide
      */
-    public boolean refresh() {
+    public boolean refresh(boolean bypassCache) {
         enforceSealed();
         if (!canPerformRequestOverConnection(mSourceNodeId)) {
             return false;
         }
         AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
         AccessibilityNodeInfo refreshedInfo = client.findAccessibilityNodeInfoByAccessibilityId(
-                mConnectionId, mWindowId, mSourceNodeId, 0);
+                mConnectionId, mWindowId, mSourceNodeId, bypassCache, 0);
         if (refreshedInfo == null) {
             return false;
         }
@@ -613,6 +653,19 @@
     }
 
     /**
+     * Refreshes this info with the latest state of the view it represents.
+     * <p>
+     * <strong>Note:</strong> If this method returns false this info is obsolete
+     * since it represents a view that is no longer in the view tree and should
+     * be recycled.
+     * </p>
+     * @return Whether the refresh succeeded.
+     */
+    public boolean refresh() {
+        return refresh(false);
+    }
+
+    /**
      * @return The ids of the children.
      *
      * @hide
@@ -652,7 +705,7 @@
         final long childId = mChildNodeIds.get(index);
         AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
         return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId, mWindowId,
-                childId, FLAG_PREFETCH_DESCENDANTS);
+                childId, false, FLAG_PREFETCH_DESCENDANTS);
     }
 
     /**
@@ -878,7 +931,7 @@
         }
         AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
         return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId,
-                mWindowId, mParentNodeId, FLAG_PREFETCH_DESCENDANTS | FLAG_PREFETCH_SIBLINGS);
+                mWindowId, mParentNodeId, false, FLAG_PREFETCH_DESCENDANTS | FLAG_PREFETCH_SIBLINGS);
     }
 
     /**
@@ -1283,7 +1336,6 @@
      * @throws IllegalStateException If called from an AccessibilityService.
      */
     public void setScrollable(boolean scrollable) {
-        enforceNotSealed();
         setBooleanProperty(BOOLEAN_PROPERTY_SCROLLABLE, scrollable);
     }
 
@@ -1313,6 +1365,216 @@
     }
 
     /**
+     * Gets the collection info if the node is a collection. A collection
+     * child is always a collection item.
+     *
+     * @return The collection info.
+     */
+    public CollectionInfo getCollectionInfo() {
+        return mCollectionInfo;
+    }
+
+    /**
+     * Sets the collection info if the node is a collection. A collection
+     * child is always a collection item.
+     * <p>
+     *   <strong>Note:</strong> Cannot be called from an
+     *   {@link android.accessibilityservice.AccessibilityService}.
+     *   This class is made immutable before being delivered to an AccessibilityService.
+     * </p>
+     *
+     * @param collectionInfo The collection info.
+     */
+    public void setCollectionInfo(CollectionInfo collectionInfo) {
+        enforceNotSealed();
+        mCollectionInfo = collectionInfo;
+    }
+
+    /**
+     * Gets the collection item info if the node is a collection item. A collection
+     * item is always a child of a collection.
+     *
+     * @return The collection item info.
+     */
+    public CollectionItemInfo getCollectionItemInfo() {
+        return mCollectionItemInfo;
+    }
+
+    /**
+     * Sets the collection item info if the node is a collection item. A collection
+     * item is always a child of a collection.
+     * <p>
+     *   <strong>Note:</strong> Cannot be called from an
+     *   {@link android.accessibilityservice.AccessibilityService}.
+     *   This class is made immutable before being delivered to an AccessibilityService.
+     * </p>
+     *
+     * @return collectionItem True if the node is an item.
+     */
+    public void setCollectionItemInfo(CollectionItemInfo collectionItemInfo) {
+        enforceNotSealed();
+        mCollectionItemInfo = collectionItemInfo;
+    }
+
+    /**
+     * Gets the range info if this node is a range.
+     *
+     * @return The range.
+     */
+    public RangeInfo getRangeInfo() {
+        return mRangeInfo;
+    }
+
+    /**
+     * Sets the range info if this node is a range.
+     * <p>
+     *   <strong>Note:</strong> Cannot be called from an
+     *   {@link android.accessibilityservice.AccessibilityService}.
+     *   This class is made immutable before being delivered to an AccessibilityService.
+     * </p>
+     *
+     * @param rangeInfo The range info.
+     */
+    public void setRangeInfo(RangeInfo rangeInfo) {
+        enforceNotSealed();
+        mRangeInfo = rangeInfo;
+    }
+
+    /**
+     * Gets if the content of this node is invalid. For example,
+     * a date is not well-formed.
+     *
+     * @return If the node content is invalid.
+     */
+    public boolean isContentInvalid() {
+        return getBooleanProperty(BOOLEAN_PROPERTY_CONTENT_INVALID);
+    }
+
+    /**
+     * Sets if the content of this node is invalid. For example,
+     * a date is not well-formed.
+     * <p>
+     *   <strong>Note:</strong> Cannot be called from an
+     *   {@link android.accessibilityservice.AccessibilityService}.
+     *   This class is made immutable before being delivered to an AccessibilityService.
+     * </p>
+     *
+     * @param contentInvalid If the node content is invalid.
+     */
+    public void setContentInvalid(boolean contentInvalid) {
+        setBooleanProperty(BOOLEAN_PROPERTY_CONTENT_INVALID, contentInvalid);
+    }
+
+    /**
+     * Gets the node's live region mode.
+     * <p>
+     * A live region is a node that contains information that is important for
+     * the user and when it changes the user should be notified. For example,
+     * in a login screen with a TextView that displays an "incorrect password"
+     * notification, that view should be marked as a live region with mode
+     * {@link View#ACCESSIBILITY_LIVE_REGION_POLITE}.
+     * <p>
+     * It is the responsibility of the accessibility service to monitor
+     * {@link AccessibilityEvent#TYPE_WINDOW_CONTENT_CHANGED} events indicating
+     * changes to live region nodes and their children.
+     *
+     * @return The live region mode, or
+     *         {@link View#ACCESSIBILITY_LIVE_REGION_NONE} if the view is not a
+     *         live region.
+     * @see android.view.View#getAccessibilityLiveRegion()
+     */
+    public int getLiveRegion() {
+        return mLiveRegion;
+    }
+
+    /**
+     * Sets the node's live region mode.
+     * <p>
+     * <strong>Note:</strong> Cannot be called from an
+     * {@link android.accessibilityservice.AccessibilityService}. This class is
+     * made immutable before being delivered to an AccessibilityService.
+     *
+     * @param mode The live region mode, or
+     *        {@link View#ACCESSIBILITY_LIVE_REGION_NONE} if the view is not a
+     *        live region.
+     * @see android.view.View#setAccessibilityLiveRegion(int)
+     */
+    public void setLiveRegion(int mode) {
+        enforceNotSealed();
+        mLiveRegion = mode;
+    }
+
+    /**
+     * Gets if the node is a multi line editable text.
+     *
+     * @return True if the node is multi line.
+     */
+    public boolean isMultiLine() {
+        return getBooleanProperty(BOOLEAN_PROPERTY_MULTI_LINE);
+    }
+
+    /**
+     * Sets if the node is a multi line editable text.
+     * <p>
+     *   <strong>Note:</strong> Cannot be called from an
+     *   {@link android.accessibilityservice.AccessibilityService}.
+     *   This class is made immutable before being delivered to an AccessibilityService.
+     * </p>
+     *
+     * @param multiLine True if the node is multi line.
+     */
+    public void setMultiLine(boolean multiLine) {
+        setBooleanProperty(BOOLEAN_PROPERTY_MULTI_LINE, multiLine);
+    }
+
+    /**
+     * Gets if this node opens a popup or a dialog.
+     *
+     * @return If the the node opens a popup.
+     */
+    public boolean canOpenPopup() {
+        return getBooleanProperty(BOOLEAN_PROPERTY_OPENS_POPUP);
+    }
+
+    /**
+     * Sets if this node opens a popup or a dialog.
+     * <p>
+     *   <strong>Note:</strong> Cannot be called from an
+     *   {@link android.accessibilityservice.AccessibilityService}.
+     *   This class is made immutable before being delivered to an AccessibilityService.
+     * </p>
+     *
+     * @param opensPopup If the the node opens a popup.
+     */
+    public void setCanOpenPopup(boolean opensPopup) {
+        enforceNotSealed();
+        setBooleanProperty(BOOLEAN_PROPERTY_OPENS_POPUP, opensPopup);
+    }
+
+    /**
+     * Gets if the node can be dismissed.
+     *
+     * @return If the node can be dismissed.
+     */
+    public boolean isDismissable() {
+        return getBooleanProperty(BOOLEAN_PROPERTY_DISMISSABLE);
+    }
+
+    /**
+     * Sets if the node can be dismissed.
+     * <p>
+     *   <strong>Note:</strong> Cannot be called from an
+     *   {@link android.accessibilityservice.AccessibilityService}.
+     *   This class is made immutable before being delivered to an AccessibilityService.
+     * </p>
+     *
+     * @param dismissable If the node can be dismissed.
+     */
+    public void setDismissable(boolean dismissable) {
+        setBooleanProperty(BOOLEAN_PROPERTY_DISMISSABLE, dismissable);
+    }
+
+    /**
      * Gets the package this node comes from.
      *
      * @return The package name.
@@ -1470,7 +1732,7 @@
         }
         AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
         return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId,
-                mWindowId, mLabelForId, FLAG_PREFETCH_DESCENDANTS | FLAG_PREFETCH_SIBLINGS);
+                mWindowId, mLabelForId, false, FLAG_PREFETCH_DESCENDANTS | FLAG_PREFETCH_SIBLINGS);
     }
 
     /**
@@ -1527,7 +1789,7 @@
         }
         AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
         return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId,
-                mWindowId, mLabeledById, FLAG_PREFETCH_DESCENDANTS | FLAG_PREFETCH_SIBLINGS);
+                mWindowId, mLabeledById, false, FLAG_PREFETCH_DESCENDANTS | FLAG_PREFETCH_SIBLINGS);
     }
 
     /**
@@ -1600,6 +1862,53 @@
     }
 
     /**
+     * Gets the input type of the source as defined by {@link InputType}.
+     *
+     * @return The input type.
+     */
+    public int getInputType() {
+        return mInputType;
+    }
+
+    /**
+     * Sets the input type of the source as defined by {@link InputType}.
+     * <p>
+     *   <strong>Note:</strong> Cannot be called from an
+     *   {@link android.accessibilityservice.AccessibilityService}.
+     *   This class is made immutable before being delivered to an
+     *   AccessibilityService.
+     * </p>
+     *
+     * @param inputType The input type.
+     *
+     * @throws IllegalStateException If called from an AccessibilityService.
+     */
+    public void setInputType(int inputType) {
+        enforceNotSealed();
+        mInputType = inputType;
+    }
+
+    /**
+     * Gets an optional bundle with extra data. The bundle
+     * is lazily created and never <code>null</code>.
+     * <p>
+     * <strong>Note:</strong> It is recommended to use the package
+     * name of your application as a prefix for the keys to avoid
+     * collisions which may confuse an accessibility service if the
+     * same key has different meaning when emitted from different
+     * applications.
+     * </p>
+     *
+     * @return The bundle.
+     */
+    public Bundle getExtras() {
+        if (mExtras == null) {
+            mExtras = new Bundle();
+        }
+        return mExtras;
+    }
+
+    /**
      * Gets the value of a boolean property.
      *
      * @param property The property.
@@ -1845,6 +2154,45 @@
 
         parcel.writeInt(mTextSelectionStart);
         parcel.writeInt(mTextSelectionEnd);
+        parcel.writeInt(mInputType);
+        parcel.writeInt(mLiveRegion);
+
+        if (mExtras != null) {
+            parcel.writeInt(1);
+            parcel.writeBundle(mExtras);
+        } else {
+            parcel.writeInt(0);
+        }
+
+        if (mRangeInfo != null) {
+            parcel.writeInt(1);
+            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);
+            parcel.writeInt(mCollectionInfo.getRowCount());
+            parcel.writeInt(mCollectionInfo.getColumnCount());
+            parcel.writeInt(mCollectionInfo.isHierarchical() ? 1 : 0);
+        } else {
+            parcel.writeInt(0);
+        }
+
+        if (mCollectionItemInfo != null) {
+            parcel.writeInt(1);
+            parcel.writeInt(mCollectionItemInfo.getColumnIndex());
+            parcel.writeInt(mCollectionItemInfo.getColumnSpan());
+            parcel.writeInt(mCollectionItemInfo.getRowIndex());
+            parcel.writeInt(mCollectionItemInfo.getRowSpan());
+            parcel.writeInt(mCollectionItemInfo.isHeading() ? 1 : 0);
+        } else {
+            parcel.writeInt(0);
+        }
 
         // Since instances of this class are fetched via synchronous i.e. blocking
         // calls in IPCs we always recycle as soon as the instance is marshaled.
@@ -1876,10 +2224,21 @@
         mMovementGranularities = other.mMovementGranularities;
         final int otherChildIdCount = other.mChildNodeIds.size();
         for (int i = 0; i < otherChildIdCount; i++) {
-            mChildNodeIds.put(i, other.mChildNodeIds.valueAt(i));    
+            mChildNodeIds.put(i, other.mChildNodeIds.valueAt(i));
         }
         mTextSelectionStart = other.mTextSelectionStart;
         mTextSelectionEnd = other.mTextSelectionEnd;
+        mInputType = other.mInputType;
+        mLiveRegion = other.mLiveRegion;
+        if (other.mExtras != null && !other.mExtras.isEmpty()) {
+            getExtras().putAll(other.mExtras);
+        }
+        mRangeInfo = (other.mRangeInfo != null)
+                ? RangeInfo.obtain(other.mRangeInfo) : null;
+        mCollectionInfo = (other.mCollectionInfo != null)
+                ? CollectionInfo.obtain(other.mCollectionInfo) : null;
+        mCollectionItemInfo =  (other.mCollectionItemInfo != null)
+                ? CollectionItemInfo.obtain(other.mCollectionItemInfo) : null;
     }
 
     /**
@@ -1927,6 +2286,37 @@
 
         mTextSelectionStart = parcel.readInt();
         mTextSelectionEnd = parcel.readInt();
+
+        mInputType = parcel.readInt();
+        mLiveRegion = parcel.readInt();
+
+        if (parcel.readInt() == 1) {
+            getExtras().putAll(parcel.readBundle());
+        }
+
+        if (parcel.readInt() == 1) {
+            mRangeInfo = RangeInfo.obtain(
+                    parcel.readInt(),
+                    parcel.readFloat(),
+                    parcel.readFloat(),
+                    parcel.readFloat());
+        }
+
+        if (parcel.readInt() == 1) {
+            mCollectionInfo = CollectionInfo.obtain(
+                    parcel.readInt(),
+                    parcel.readInt(),
+                    parcel.readInt() == 1);
+        }
+
+        if (parcel.readInt() == 1) {
+            mCollectionItemInfo = CollectionItemInfo.obtain(
+                    parcel.readInt(),
+                    parcel.readInt(),
+                    parcel.readInt(),
+                    parcel.readInt(),
+                    parcel.readInt() == 1);
+        }
     }
 
     /**
@@ -1953,6 +2343,23 @@
         mActions = 0;
         mTextSelectionStart = UNDEFINED;
         mTextSelectionEnd = UNDEFINED;
+        mInputType = InputType.TYPE_NULL;
+        mLiveRegion = View.ACCESSIBILITY_LIVE_REGION_NONE;
+        if (mExtras != null) {
+            mExtras.clear();
+        }
+        if (mRangeInfo != null) {
+            mRangeInfo.recycle();
+            mRangeInfo = null;
+        }
+        if (mCollectionInfo != null) {
+            mCollectionInfo.recycle();
+            mCollectionInfo = null;
+        }
+        if (mCollectionItemInfo != null) {
+            mCollectionItemInfo.recycle();
+            mCollectionItemInfo = null;
+        }
     }
 
     /**
@@ -2132,6 +2539,360 @@
     }
 
     /**
+     * Class with information if a node is a range. Use
+     * {@link RangeInfo#obtain(int, float, float, float) to get an instance.
+     */
+    public static final class RangeInfo {
+        private static final int MAX_POOL_SIZE = 10;
+
+        /** Range type: integer. */
+        public static final int RANGE_TYPE_INT = 0;
+        /** Range type: float. */
+        public static final int RANGE_TYPE_FLOAT = 1;
+        /** Range type: percent with values from zero to one.*/
+        public static final int RANGE_TYPE_PERCENT = 2;
+
+        private static final SynchronizedPool<RangeInfo> sPool =
+                new SynchronizedPool<AccessibilityNodeInfo.RangeInfo>(MAX_POOL_SIZE);
+
+        private int mType;
+        private float mMin;
+        private float mMax;
+        private float mCurrent;
+
+        /**
+         * Obtains a pooled instance that is a clone of another one.
+         *
+         * @param other The instance to clone.
+         *
+         * @hide
+         */
+        public static RangeInfo obtain(RangeInfo other) {
+            return obtain(other.mType, other.mMin, other.mMax, other.mCurrent);
+        }
+
+        /**
+         * Obtains a pooled instance.
+         *
+         * @param type The type of the range.
+         * @param min The min value.
+         * @param max The max value.
+         * @param current The current value.
+         */
+        public static RangeInfo obtain(int type, float min, float max, float current) {
+            RangeInfo info = sPool.acquire();
+            return (info != null) ? info : new RangeInfo(type, min, max, current);
+        }
+
+        /**
+         * Creates a new range.
+         *
+         * @param type The type of the range.
+         * @param min The min value.
+         * @param max The max value.
+         * @param current The current value.
+         */
+        private RangeInfo(int type, float min, float max, float current) {
+            mType = type;
+            mMin = min;
+            mMax = max;
+            mCurrent = current;
+        }
+
+        /**
+         * Gets the range type.
+         *
+         * @return The range type.
+         *
+         * @see #RANGE_TYPE_INT
+         * @see #RANGE_TYPE_FLOAT
+         * @see #RANGE_TYPE_PERCENT
+         */
+        public int getType() {
+            return mType;
+        }
+
+        /**
+         * Gets the min value.
+         *
+         * @return The min value.
+         */
+        public float getMin() {
+            return mMin;
+        }
+
+        /**
+         * Gets the max value.
+         *
+         * @return The max value.
+         */
+        public float getMax() {
+            return mMax;
+        }
+
+        /**
+         * Gets the current value.
+         *
+         * @return The current value.
+         */
+        public float getCurrent() {
+            return mCurrent;
+        }
+
+        /**
+         * Recycles this instance.
+         */
+        void recycle() {
+            clear();
+            sPool.release(this);
+        }
+
+        private void clear() {
+            mType = 0;
+            mMin = 0;
+            mMax = 0;
+            mCurrent = 0;
+        }
+    }
+
+    /**
+     * Class with information if a node is a collection. Use
+     * {@link CollectionInfo#obtain(int, int, boolean)} to get an instance.
+     * <p>
+     * A collection of items has rows and columns and may be hierarchical.
+     * For example, a horizontal list is a collection with one column, as
+     * many rows as the list items, and is not hierarchical; A table is a
+     * collection with several rows, several columns, and is not hierarchical;
+     * A vertical tree is a hierarchical collection with one column and
+     * as many rows as the first level children.
+     * </p>
+     */
+    public static final class CollectionInfo {
+        private static final int MAX_POOL_SIZE = 20;
+
+        private static final SynchronizedPool<CollectionInfo> sPool =
+                new SynchronizedPool<CollectionInfo>(MAX_POOL_SIZE);
+
+        private int mRowCount;
+        private int mColumnCount;
+        private boolean mHierarchical;
+
+        /**
+         * Obtains a pooled instance that is a clone of another one.
+         *
+         * @param other The instance to clone.
+         *
+         * @hide
+         */
+        public static CollectionInfo obtain(CollectionInfo other) {
+            return CollectionInfo.obtain(other.mRowCount, other.mColumnCount,
+                    other.mHierarchical);
+        }
+
+        /**
+         * Obtains a pooled instance.
+         *
+         * @param rowCount The number of rows.
+         * @param columnCount The number of columns.
+         * @param hierarchical Whether the collection is hierarchical.
+         */
+        public static CollectionInfo obtain(int rowCount, int columnCount,
+                boolean hierarchical) {
+            CollectionInfo info = sPool.acquire();
+            return (info != null) ? info : new CollectionInfo(rowCount,
+                    columnCount, hierarchical);
+        }
+
+        /**
+         * Creates a new instance.
+         *
+         * @param rowCount The number of rows.
+         * @param columnCount The number of columns.
+         * @param hierarchical Whether the collection is hierarchical.
+         */
+        private CollectionInfo(int rowCount, int columnCount,
+                boolean hierarchical) {
+            mRowCount = rowCount;
+            mColumnCount = columnCount;
+            mHierarchical = hierarchical;
+        }
+
+        /**
+         * Gets the number of rows.
+         *
+         * @return The row count.
+         */
+        public int getRowCount() {
+            return mRowCount;
+        }
+
+        /**
+         * Gets the number of columns.
+         *
+         * @return The column count.
+         */
+        public int getColumnCount() {
+            return mColumnCount;
+        }
+
+        /**
+         * Gets if the collection is a hierarchically ordered.
+         *
+         * @return Whether the collection is hierarchical.
+         */
+        public boolean isHierarchical() {
+            return mHierarchical;
+        }
+
+        /**
+         * Recycles this instance.
+         */
+        void recycle() {
+            clear();
+            sPool.release(this);
+        }
+
+        private void clear() {
+            mRowCount = 0;
+            mColumnCount = 0;
+            mHierarchical = false;
+        }
+    }
+
+    /**
+     * Class with information if a node is a collection item. Use
+     * {@link CollectionItemInfo#obtain(int, int, int, int, boolean)}
+     * to get an instance.
+     * <p>
+     * A collection item is contained in a collection, it starts at
+     * a given row and column in the collection, and spans one or
+     * more rows and columns. For example, a header of two related
+     * table columns starts at the first row and the first column,
+     * spans one row and two columns.
+     * </p>
+     */
+    public static final class CollectionItemInfo {
+        private static final int MAX_POOL_SIZE = 20;
+
+        private static final SynchronizedPool<CollectionItemInfo> sPool =
+                new SynchronizedPool<CollectionItemInfo>(MAX_POOL_SIZE);
+
+        /**
+         * Obtains a pooled instance that is a clone of another one.
+         *
+         * @param other The instance to clone.
+         *
+         * @hide
+         */
+        public static CollectionItemInfo obtain(CollectionItemInfo other) {
+            return CollectionItemInfo.obtain(other.mRowIndex, other.mRowSpan,
+                    other.mColumnIndex, other.mColumnSpan, other.mHeading);
+        }
+
+        /**
+         * Obtains a pooled instance.
+         *
+         * @param rowIndex The row index at which the item is located.
+         * @param rowSpan The number of rows the item spans.
+         * @param columnIndex The column index at which the item is located.
+         * @param columnSpan The number of columns the item spans.
+         * @param heading Whether the item is a heading.
+         */
+        public static CollectionItemInfo obtain(int rowIndex, int rowSpan,
+                int columnIndex, int columnSpan, boolean heading) {
+            CollectionItemInfo info = sPool.acquire();
+            return (info != null) ? info : new CollectionItemInfo(rowIndex,
+                    rowSpan, columnIndex, columnSpan, heading);
+        }
+
+        private boolean mHeading;
+        private int mColumnIndex;
+        private int mRowIndex;
+        private int mColumnSpan;
+        private int mRowSpan;
+
+        /**
+         * Creates a new instance.
+         *
+         * @param rowIndex The row index at which the item is located.
+         * @param rowSpan The number of rows the item spans.
+         * @param columnIndex The column index at which the item is located.
+         * @param columnSpan The number of columns the item spans.
+         * @param heading Whether the item is a heading.
+         */
+        private CollectionItemInfo(int rowIndex, int rowSpan,
+                int columnIndex, int columnSpan, boolean heading) {
+            mRowIndex = rowIndex;
+            mRowSpan = rowSpan;
+            mColumnIndex = columnIndex;
+            mColumnSpan = columnSpan;
+            mHeading = heading;
+        }
+
+        /**
+         * Gets the column index at which the item is located.
+         *
+         * @return The column index.
+         */
+        public int getColumnIndex() {
+            return mColumnIndex;
+        }
+
+        /**
+         * Gets the row index at which the item is located.
+         *
+         * @return The row index.
+         */
+        public int getRowIndex() {
+            return mRowIndex;
+        }
+
+        /**
+         * Gets the number of columns the item spans.
+         *
+         * @return The column span.
+         */
+        public int getColumnSpan() {
+            return mColumnSpan;
+        }
+
+        /**
+         * Gets the number of rows the item spans.
+         *
+         * @return The row span.
+         */
+        public int getRowSpan() {
+            return mRowSpan;
+        }
+
+        /**
+         * Gets if the collection item is a heading. For example, section
+         * heading, table header, etc.
+         *
+         * @return If the item is a heading.
+         */
+        public boolean isHeading() {
+            return mHeading;
+        }
+
+        /**
+         * Recycles this instance.
+         */
+        void recycle() {
+            clear();
+            sPool.release(this);
+        }
+
+        private void clear() {
+            mColumnIndex = 0;
+            mColumnSpan = 0;
+            mRowIndex = 0;
+            mRowSpan = 0;
+            mHeading = false;
+        }
+    }
+
+    /**
      * @see Parcelable.Creator
      */
     public static final Parcelable.Creator<AccessibilityNodeInfo> CREATOR =
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
index 28518aa..6bef78e 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
@@ -41,7 +41,7 @@
 
     private static final boolean DEBUG = false;
 
-    private static final boolean CHECK_INTEGRITY = true;
+    private static final boolean CHECK_INTEGRITY_IF_DEBUGGABLE_BUILD = true;
 
     private final Object mLock = new Object();
 
@@ -67,16 +67,12 @@
         if (ENABLED) {
             final int eventType = event.getEventType();
             switch (eventType) {
-                case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: {
-                    // New window so we clear the cache.
-                    mWindowId = event.getWindowId();
-                    clear();
-                } break;
+                case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
                 case AccessibilityEvent.TYPE_VIEW_HOVER_ENTER:
                 case AccessibilityEvent.TYPE_VIEW_HOVER_EXIT: {
                     final int windowId = event.getWindowId();
+                    // If a new window, we clear the cache.
                     if (mWindowId != windowId) {
-                        // New window so we clear the cache.
                         mWindowId = windowId;
                         clear();
                     }
@@ -87,34 +83,48 @@
                 case AccessibilityEvent.TYPE_VIEW_SELECTED:
                 case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED:
                 case AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED: {
-                    // Since we prefetch the descendants of a node we
-                    // just remove the entire subtree since when the node
-                    // is fetched we will gets its descendant anyway.
+                    refreshCachedNode(event.getSourceNodeId());
+                } break;
+                case AccessibilityEvent.TYPE_VIEW_SCROLLED: {
+                    clearSubTreeLocked(event.getSourceNodeId());
+                } break;
+                case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED: {
                     synchronized (mLock) {
                         final long sourceId = event.getSourceNodeId();
-                        clearSubTreeLocked(sourceId);
-                        if (eventType == AccessibilityEvent.TYPE_VIEW_FOCUSED) {
-                            clearSubtreeWithOldInputFocusLocked(sourceId);
+                        if ((event.getContentChangeTypes()
+                                & AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE) != 0) {
+                            clearSubTreeLocked(sourceId);
+                        } else {
+                            refreshCachedNode(sourceId);
                         }
-                        if (eventType == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED) {
-                            clearSubtreeWithOldAccessibilityFocusLocked(sourceId);
-                        }
-                    }
-                } break;
-                case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED:
-                case AccessibilityEvent.TYPE_VIEW_SCROLLED: {
-                    synchronized (mLock) {
-                        final long accessibilityNodeId = event.getSourceNodeId();
-                        clearSubTreeLocked(accessibilityNodeId);
                     }
                 } break;
             }
-            if (Build.IS_DEBUGGABLE && CHECK_INTEGRITY) {
+            if (CHECK_INTEGRITY_IF_DEBUGGABLE_BUILD && Build.IS_DEBUGGABLE) {
                 checkIntegrity();
             }
         }
     }
 
+    private void refreshCachedNode(long sourceId) {
+        if (DEBUG) {
+            Log.i(LOG_TAG, "Refreshing cached node.");
+        }
+        synchronized (mLock) {
+            AccessibilityNodeInfo cachedInfo = mCacheImpl.get(sourceId);
+            // If the source is not in the cache - nothing to do.
+            if (cachedInfo == null) {
+                return;
+            }
+            // The node changed so we will just refresh it right now.
+            if (cachedInfo.refresh(true)) {
+                return;
+            }
+            // Weird, we could not refresh. Just evict the entire sub-tree.
+            clearSubTreeLocked(sourceId);
+        }
+    }
+
     /**
      * Gets a cached {@link AccessibilityNodeInfo} given its accessibility node id.
      *
@@ -212,6 +222,13 @@
      * @param rootNodeId The root id.
      */
     private void clearSubTreeLocked(long rootNodeId) {
+        if (DEBUG) {
+            Log.i(LOG_TAG, "Clearing cached subtree.");
+        }
+        clearSubTreeRecursiveLocked(rootNodeId);
+    }
+
+    private void clearSubTreeRecursiveLocked(long rootNodeId) {
         AccessibilityNodeInfo current = mCacheImpl.get(rootNodeId);
         if (current == null) {
             return;
@@ -221,41 +238,7 @@
         final int childCount = childNodeIds.size();
         for (int i = 0; i < childCount; i++) {
             final long childNodeId = childNodeIds.valueAt(i);
-            clearSubTreeLocked(childNodeId);
-        }
-    }
-
-    /**
-     * We are enforcing the invariant for a single input focus.
-     *
-     * @param currentInputFocusId The current input focused node.
-     */
-    private void clearSubtreeWithOldInputFocusLocked(long currentInputFocusId) {
-        final int cacheSize = mCacheImpl.size();
-        for (int i = 0; i < cacheSize; i++) {
-            AccessibilityNodeInfo info = mCacheImpl.valueAt(i);
-            final long infoSourceId = info.getSourceNodeId();
-            if (infoSourceId != currentInputFocusId && info.isFocused()) {
-                clearSubTreeLocked(infoSourceId);
-                return;
-            }
-        }
-    }
-
-    /**
-     * We are enforcing the invariant for a single accessibility focus.
-     *
-     * @param currentAccessibilityFocusId The current input focused node.
-     */
-    private void clearSubtreeWithOldAccessibilityFocusLocked(long currentAccessibilityFocusId) {
-        final int cacheSize = mCacheImpl.size();
-        for (int i = 0; i < cacheSize; i++) {
-            AccessibilityNodeInfo info = mCacheImpl.valueAt(i);
-            final long infoSourceId = info.getSourceNodeId();
-            if (infoSourceId != currentAccessibilityFocusId && info.isAccessibilityFocused()) {
-                clearSubTreeLocked(infoSourceId);
-                return;
-            }
+            clearSubTreeRecursiveLocked(childNodeId);
         }
     }
 
@@ -327,12 +310,11 @@
             }
 
             // Check for disconnected nodes or ones from another window.
-            final int cacheSize = mCacheImpl.size();
-            for (int i = 0; i < cacheSize; i++) {
+            for (int i = 0; i < mCacheImpl.size(); i++) {
                 AccessibilityNodeInfo info = mCacheImpl.valueAt(i);
                 if (!seen.contains(info)) {
                     if (info.getWindowId() == windowId) {
-                        Log.e(LOG_TAG, "Disconneced node: ");
+                        Log.e(LOG_TAG, "Disconneced node: " + info);
                     } else {
                         Log.e(LOG_TAG, "Node from: " + info.getWindowId() + " not from:"
                                 + windowId + " " + info);
diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java
index 7147c57..3fcd218 100644
--- a/core/java/android/view/accessibility/AccessibilityRecord.java
+++ b/core/java/android/view/accessibility/AccessibilityRecord.java
@@ -164,7 +164,7 @@
         }
         AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
         return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId, mSourceWindowId,
-                mSourceNodeId, GET_SOURCE_PREFETCH_FLAGS);
+                mSourceNodeId, false, GET_SOURCE_PREFETCH_FLAGS);
     }
 
     /**
diff --git a/core/java/android/view/accessibility/CaptioningManager.java b/core/java/android/view/accessibility/CaptioningManager.java
new file mode 100644
index 0000000..557239f
--- /dev/null
+++ b/core/java/android/view/accessibility/CaptioningManager.java
@@ -0,0 +1,405 @@
+/*
+ * 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.view.accessibility;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.graphics.Color;
+import android.graphics.Typeface;
+import android.net.Uri;
+import android.os.Handler;
+import android.provider.Settings.Secure;
+import android.text.TextUtils;
+
+import java.util.ArrayList;
+import java.util.Locale;
+
+/**
+ * Contains methods for accessing and monitoring preferred video captioning state and visual
+ * properties.
+ * <p>
+ * To obtain a handle to the captioning manager, do the following:
+ * <p>
+ * <code>
+ * <pre>CaptioningManager captioningManager =
+ *        (CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE);</pre>
+ * </code>
+ */
+public class CaptioningManager {
+    /** Default captioning enabled value. */
+    private static final int DEFAULT_ENABLED = 0;
+
+    /** Default style preset as an index into {@link CaptionStyle#PRESETS}. */
+    private static final int DEFAULT_PRESET = 0;
+
+    /** Default scaling value for caption fonts. */
+    private static final float DEFAULT_FONT_SCALE = 1;
+
+    private final ArrayList<CaptioningChangeListener>
+            mListeners = new ArrayList<CaptioningChangeListener>();
+    private final Handler mHandler = new Handler();
+
+    private final ContentResolver mContentResolver;
+
+    /**
+     * Creates a new captioning manager for the specified context.
+     *
+     * @hide
+     */
+    public CaptioningManager(Context context) {
+        mContentResolver = context.getContentResolver();
+    }
+
+    /**
+     * @return the user's preferred captioning enabled state
+     */
+    public final boolean isEnabled() {
+        return Secure.getInt(
+                mContentResolver, Secure.ACCESSIBILITY_CAPTIONING_ENABLED, DEFAULT_ENABLED) == 1;
+    }
+
+    /**
+     * @return the raw locale string for the user's preferred captioning
+     *         language
+     * @hide
+     */
+    public final String getRawLocale() {
+        return Secure.getString(mContentResolver, Secure.ACCESSIBILITY_CAPTIONING_LOCALE);
+    }
+
+    /**
+     * @return the locale for the user's preferred captioning language, or null
+     *         if not specified
+     */
+    public final Locale getLocale() {
+        final String rawLocale = getRawLocale();
+        if (!TextUtils.isEmpty(rawLocale)) {
+            final String[] splitLocale = rawLocale.split("_");
+            switch (splitLocale.length) {
+                case 3:
+                    return new Locale(splitLocale[0], splitLocale[1], splitLocale[2]);
+                case 2:
+                    return new Locale(splitLocale[0], splitLocale[1]);
+                case 1:
+                    return new Locale(splitLocale[0]);
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * @return the user's preferred font scaling factor for video captions, or 1 if not
+     *         specified
+     */
+    public final float getFontScale() {
+        return Secure.getFloat(
+                mContentResolver, Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE, DEFAULT_FONT_SCALE);
+    }
+
+    /**
+     * @return the raw preset number, or the first preset if not specified
+     * @hide
+     */
+    public int getRawUserStyle() {
+        return Secure.getInt(
+                mContentResolver, Secure.ACCESSIBILITY_CAPTIONING_PRESET, DEFAULT_PRESET);
+    }
+
+    /**
+     * @return the user's preferred visual properties for captions as a
+     *         {@link CaptionStyle}, or the default style if not specified
+     */
+    public CaptionStyle getUserStyle() {
+        final int preset = getRawUserStyle();
+        if (preset == CaptionStyle.PRESET_CUSTOM) {
+            return CaptionStyle.getCustomStyle(mContentResolver);
+        }
+
+        return CaptionStyle.PRESETS[preset];
+    }
+
+    /**
+     * Adds a listener for changes in the user's preferred captioning enabled
+     * state and visual properties.
+     *
+     * @param listener the listener to add
+     */
+    public void addCaptioningChangeListener(CaptioningChangeListener listener) {
+        synchronized (mListeners) {
+            if (mListeners.isEmpty()) {
+                registerObserver(Secure.ACCESSIBILITY_CAPTIONING_ENABLED);
+                registerObserver(Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR);
+                registerObserver(Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR);
+                registerObserver(Secure.ACCESSIBILITY_CAPTIONING_EDGE_TYPE);
+                registerObserver(Secure.ACCESSIBILITY_CAPTIONING_EDGE_COLOR);
+                registerObserver(Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE);
+                registerObserver(Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE);
+                registerObserver(Secure.ACCESSIBILITY_CAPTIONING_LOCALE);
+            }
+
+            mListeners.add(listener);
+        }
+    }
+
+    private void registerObserver(String key) {
+        mContentResolver.registerContentObserver(Secure.getUriFor(key), false, mContentObserver);
+    }
+
+    /**
+     * Removes a listener previously added using
+     * {@link #addCaptioningChangeListener}.
+     *
+     * @param listener the listener to remove
+     */
+    public void removeCaptioningChangeListener(CaptioningChangeListener listener) {
+        synchronized (mListeners) {
+            mListeners.remove(listener);
+
+            if (mListeners.isEmpty()) {
+                mContentResolver.unregisterContentObserver(mContentObserver);
+            }
+        }
+    }
+
+    private void notifyEnabledChanged() {
+        final boolean enabled = isEnabled();
+        synchronized (mListeners) {
+            for (CaptioningChangeListener listener : mListeners) {
+                listener.onEnabledChanged(enabled);
+            }
+        }
+    }
+
+    private void notifyUserStyleChanged() {
+        final CaptionStyle userStyle = getUserStyle();
+        synchronized (mListeners) {
+            for (CaptioningChangeListener listener : mListeners) {
+                listener.onUserStyleChanged(userStyle);
+            }
+        }
+    }
+
+    private void notifyLocaleChanged() {
+        final Locale locale = getLocale();
+        synchronized (mListeners) {
+            for (CaptioningChangeListener listener : mListeners) {
+                listener.onLocaleChanged(locale);
+            }
+        }
+    }
+
+    private void notifyFontScaleChanged() {
+        final float fontScale = getFontScale();
+        synchronized (mListeners) {
+            for (CaptioningChangeListener listener : mListeners) {
+                listener.onFontScaleChanged(fontScale);
+            }
+        }
+    }
+
+    private final ContentObserver mContentObserver = new ContentObserver(mHandler) {
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            final String uriPath = uri.getPath();
+            final String name = uriPath.substring(uriPath.lastIndexOf('/') + 1);
+            if (Secure.ACCESSIBILITY_CAPTIONING_ENABLED.equals(name)) {
+                notifyEnabledChanged();
+            } else if (Secure.ACCESSIBILITY_CAPTIONING_LOCALE.equals(name)) {
+                notifyLocaleChanged();
+            } else if (Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE.equals(name)) {
+                notifyFontScaleChanged();
+            } else {
+                // We only need a single callback when multiple style properties
+                // change in rapid succession.
+                mHandler.removeCallbacks(mStyleChangedRunnable);
+                mHandler.post(mStyleChangedRunnable);
+            }
+        }
+    };
+
+    /**
+     * Runnable posted when user style properties change. This is used to
+     * prevent unnecessary change notifications when multiple properties change
+     * in rapid succession.
+     */
+    private final Runnable mStyleChangedRunnable = new Runnable() {
+        @Override
+        public void run() {
+            notifyUserStyleChanged();
+        }
+    };
+
+    /**
+     * Specifies visual properties for video captions, including foreground and
+     * background colors, edge properties, and typeface.
+     */
+    public static final class CaptionStyle {
+        private static final CaptionStyle WHITE_ON_BLACK;
+        private static final CaptionStyle BLACK_ON_WHITE;
+        private static final CaptionStyle YELLOW_ON_BLACK;
+        private static final CaptionStyle YELLOW_ON_BLUE;
+        private static final CaptionStyle DEFAULT_CUSTOM;
+
+        /** @hide */
+        public static final CaptionStyle[] PRESETS;
+
+        /** @hide */
+        public static final int PRESET_CUSTOM = -1;
+
+        /** Edge type value specifying no character edges. */
+        public static final int EDGE_TYPE_NONE = 0;
+
+        /** Edge type value specifying uniformly outlined character edges. */
+        public static final int EDGE_TYPE_OUTLINE = 1;
+
+        /** Edge type value specifying drop-shadowed character edges. */
+        public static final int EDGE_TYPE_DROP_SHADOW = 2;
+
+        /** The preferred foreground color for video captions. */
+        public final int foregroundColor;
+
+        /** The preferred background color for video captions. */
+        public final int backgroundColor;
+
+        /**
+         * The preferred edge type for video captions, one of:
+         * <ul>
+         * <li>{@link #EDGE_TYPE_NONE}
+         * <li>{@link #EDGE_TYPE_OUTLINE}
+         * <li>{@link #EDGE_TYPE_DROP_SHADOW}
+         * </ul>
+         */
+        public final int edgeType;
+
+        /**
+         * The preferred edge color for video captions, if using an edge type
+         * other than {@link #EDGE_TYPE_NONE}.
+         */
+        public final int edgeColor;
+
+        /**
+         * @hide
+         */
+        public final String mRawTypeface;
+
+        private Typeface mParsedTypeface;
+
+        private CaptionStyle(int foregroundColor, int backgroundColor, int edgeType, int edgeColor,
+                String rawTypeface) {
+            this.foregroundColor = foregroundColor;
+            this.backgroundColor = backgroundColor;
+            this.edgeType = edgeType;
+            this.edgeColor = edgeColor;
+
+            mRawTypeface = rawTypeface;
+        }
+
+        /**
+         * @return the preferred {@link Typeface} for video captions, or null if
+         *         not specified
+         */
+        public Typeface getTypeface() {
+            if (mParsedTypeface == null && !TextUtils.isEmpty(mRawTypeface)) {
+                mParsedTypeface = Typeface.create(mRawTypeface, Typeface.NORMAL);
+            }
+            return mParsedTypeface;
+        }
+
+        /**
+         * @hide
+         */
+        public static CaptionStyle getCustomStyle(ContentResolver cr) {
+            final CaptionStyle defStyle = CaptionStyle.DEFAULT_CUSTOM;
+            final int foregroundColor = Secure.getInt(
+                    cr, Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR, defStyle.foregroundColor);
+            final int backgroundColor = Secure.getInt(
+                    cr, Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR, defStyle.backgroundColor);
+            final int edgeType = Secure.getInt(
+                    cr, Secure.ACCESSIBILITY_CAPTIONING_EDGE_TYPE, defStyle.edgeType);
+            final int edgeColor = Secure.getInt(
+                    cr, Secure.ACCESSIBILITY_CAPTIONING_EDGE_COLOR, defStyle.edgeColor);
+
+            String rawTypeface = Secure.getString(cr, Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE);
+            if (rawTypeface == null) {
+                rawTypeface = defStyle.mRawTypeface;
+            }
+
+            return new CaptionStyle(
+                    foregroundColor, backgroundColor, edgeType, edgeColor, rawTypeface);
+        }
+
+        static {
+            WHITE_ON_BLACK = new CaptionStyle(
+                    Color.WHITE, Color.BLACK, EDGE_TYPE_NONE, Color.BLACK, null);
+            BLACK_ON_WHITE = new CaptionStyle(
+                    Color.BLACK, Color.WHITE, EDGE_TYPE_NONE, Color.BLACK, null);
+            YELLOW_ON_BLACK = new CaptionStyle(
+                    Color.YELLOW, Color.BLACK, EDGE_TYPE_NONE, Color.BLACK, null);
+            YELLOW_ON_BLUE = new CaptionStyle(
+                    Color.YELLOW, Color.BLUE, EDGE_TYPE_NONE, Color.BLACK, null);
+
+            PRESETS = new CaptionStyle[] {
+                    WHITE_ON_BLACK, BLACK_ON_WHITE, YELLOW_ON_BLACK, YELLOW_ON_BLUE
+            };
+
+            DEFAULT_CUSTOM = WHITE_ON_BLACK;
+        }
+    }
+
+    /**
+     * Listener for changes in captioning properties, including enabled state
+     * and user style preferences.
+     */
+    public static abstract class CaptioningChangeListener {
+        /**
+         * Called when the captioning enabled state changes.
+         *
+         * @param enabled the user's new preferred captioning enabled state
+         */
+        public void onEnabledChanged(boolean enabled) {
+        }
+
+        /**
+         * Called when the captioning user style changes.
+         *
+         * @param userStyle the user's new preferred style
+         * @see CaptioningManager#getUserStyle()
+         */
+        public void onUserStyleChanged(CaptionStyle userStyle) {
+        }
+
+        /**
+         * Called when the captioning locale changes.
+         *
+         * @param locale the preferred captioning locale
+         * @see CaptioningManager#getLocale()
+         */
+        public void onLocaleChanged(Locale locale) {
+        }
+
+        /**
+         * Called when the captioning font scaling factor changes.
+         *
+         * @param fontScale the preferred font scaling factor
+         * @see CaptioningManager#getFontScale()
+         */
+        public void onFontScaleChanged(float fontScale) {
+        }
+    }
+}
diff --git a/core/java/android/view/animation/AnimationSet.java b/core/java/android/view/animation/AnimationSet.java
index 14d3d19..71c7450 100644
--- a/core/java/android/view/animation/AnimationSet.java
+++ b/core/java/android/view/animation/AnimationSet.java
@@ -114,7 +114,7 @@
      * Constructor to use when building an AnimationSet from code
      * 
      * @param shareInterpolator Pass true if all of the animations in this set
-     *        should use the interpolator assocciated with this AnimationSet.
+     *        should use the interpolator associated with this AnimationSet.
      *        Pass false if each animation should use its own interpolator.
      */
     public AnimationSet(boolean shareInterpolator) {
diff --git a/core/java/android/view/animation/Transformation.java b/core/java/android/view/animation/Transformation.java
index e8c1d23..890909b 100644
--- a/core/java/android/view/animation/Transformation.java
+++ b/core/java/android/view/animation/Transformation.java
@@ -29,19 +29,19 @@
     /**
      * Indicates a transformation that has no effect (alpha = 1 and identity matrix.)
      */
-    public static int TYPE_IDENTITY = 0x0;
+    public static final int TYPE_IDENTITY = 0x0;
     /**
      * Indicates a transformation that applies an alpha only (uses an identity matrix.)
      */
-    public static int TYPE_ALPHA = 0x1;
+    public static final int TYPE_ALPHA = 0x1;
     /**
      * Indicates a transformation that applies a matrix only (alpha = 1.)
      */
-    public static int TYPE_MATRIX = 0x2;
+    public static final int TYPE_MATRIX = 0x2;
     /**
      * Indicates a transformation that applies an alpha and a matrix.
      */
-    public static int TYPE_BOTH = TYPE_ALPHA | TYPE_MATRIX;
+    public static final int TYPE_BOTH = TYPE_ALPHA | TYPE_MATRIX;
 
     protected Matrix mMatrix;
     protected float mAlpha;
diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java
index d6b973e..f730cf7 100644
--- a/core/java/android/view/inputmethod/BaseInputConnection.java
+++ b/core/java/android/view/inputmethod/BaseInputConnection.java
@@ -269,8 +269,9 @@
         if (content != null) {
             beginBatchEdit();
             removeComposingSpans(content);
-            endBatchEdit();
+            // Note: sendCurrentText does nothing unless mDummyMode is set
             sendCurrentText();
+            endBatchEdit();
         }
         return true;
     }
@@ -467,8 +468,9 @@
             content.setSpan(COMPOSING, a, b,
                     Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_COMPOSING);
 
-            endBatchEdit();
+            // Note: sendCurrentText does nothing unless mDummyMode is set
             sendCurrentText();
+            endBatchEdit();
         }
         return true;
     }
diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java
index 54c2ba5..c440c7b 100644
--- a/core/java/android/view/inputmethod/InputMethodInfo.java
+++ b/core/java/android/view/inputmethod/InputMethodInfo.java
@@ -36,6 +36,7 @@
 import android.util.Printer;
 import android.util.Slog;
 import android.util.Xml;
+import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -78,14 +79,19 @@
      */
     private final ArrayList<InputMethodSubtype> mSubtypes = new ArrayList<InputMethodSubtype>();
 
-    private boolean mIsAuxIme;
+    private final boolean mIsAuxIme;
 
     /**
-     * Cavert: mForceDefault must be false for production. This flag is only for test.
+     * Caveat: mForceDefault must be false for production. This flag is only for test.
      */
     private final boolean mForceDefault;
 
     /**
+     * The flag whether this IME supports ways to switch to a next input method (e.g. globe key.)
+     */
+    private final boolean mSupportsSwitchingToNextInputMethod;
+
+    /**
      * Constructor.
      *
      * @param context The Context in which we are parsing the input method.
@@ -112,7 +118,8 @@
         mService = service;
         ServiceInfo si = service.serviceInfo;
         mId = new ComponentName(si.packageName, si.name).flattenToShortString();
-        mIsAuxIme = true;
+        boolean isAuxIme = true;
+        boolean supportsSwitchingToNextInputMethod = false; // false as default
         mForceDefault = false;
 
         PackageManager pm = context.getPackageManager();
@@ -148,6 +155,9 @@
                     com.android.internal.R.styleable.InputMethod_settingsActivity);
             isDefaultResId = sa.getResourceId(
                     com.android.internal.R.styleable.InputMethod_isDefault, 0);
+            supportsSwitchingToNextInputMethod = sa.getBoolean(
+                    com.android.internal.R.styleable.InputMethod_supportsSwitchingToNextInputMethod,
+                    false);
             sa.recycle();
 
             final int depth = parser.getDepth();
@@ -162,26 +172,28 @@
                     }
                     final TypedArray a = res.obtainAttributes(
                             attrs, com.android.internal.R.styleable.InputMethod_Subtype);
-                    InputMethodSubtype subtype = new InputMethodSubtype(
-                            a.getResourceId(com.android.internal.R.styleable
-                                    .InputMethod_Subtype_label, 0),
-                            a.getResourceId(com.android.internal.R.styleable
-                                    .InputMethod_Subtype_icon, 0),
-                            a.getString(com.android.internal.R.styleable
-                                    .InputMethod_Subtype_imeSubtypeLocale),
-                            a.getString(com.android.internal.R.styleable
-                                    .InputMethod_Subtype_imeSubtypeMode),
-                            a.getString(com.android.internal.R.styleable
-                                    .InputMethod_Subtype_imeSubtypeExtraValue),
-                            a.getBoolean(com.android.internal.R.styleable
-                                    .InputMethod_Subtype_isAuxiliary, false),
-                            a.getBoolean(com.android.internal.R.styleable
-                                    .InputMethod_Subtype_overridesImplicitlyEnabledSubtype, false),
-                            a.getInt(com.android.internal.R.styleable
-                                    .InputMethod_Subtype_subtypeId, 0 /* use Arrays.hashCode */)
-                            );
+                    final InputMethodSubtype subtype = new InputMethodSubtypeBuilder()
+                            .setSubtypeNameResId(a.getResourceId(com.android.internal.R.styleable
+                                    .InputMethod_Subtype_label, 0))
+                            .setSubtypeIconResId(a.getResourceId(com.android.internal.R.styleable
+                                    .InputMethod_Subtype_icon, 0))
+                            .setSubtypeLocale(a.getString(com.android.internal.R.styleable
+                                    .InputMethod_Subtype_imeSubtypeLocale))
+                            .setSubtypeMode(a.getString(com.android.internal.R.styleable
+                                    .InputMethod_Subtype_imeSubtypeMode))
+                            .setSubtypeExtraValue(a.getString(com.android.internal.R.styleable
+                                    .InputMethod_Subtype_imeSubtypeExtraValue))
+                            .setIsAuxiliary(a.getBoolean(com.android.internal.R.styleable
+                                    .InputMethod_Subtype_isAuxiliary, false))
+                            .setOverridesImplicitlyEnabledSubtype(a.getBoolean(
+                                    com.android.internal.R.styleable
+                                    .InputMethod_Subtype_overridesImplicitlyEnabledSubtype, false))
+                            .setSubtypeId(a.getInt(com.android.internal.R.styleable
+                                    .InputMethod_Subtype_subtypeId, 0 /* use Arrays.hashCode */))
+                            .setIsAsciiCapable(a.getBoolean(com.android.internal.R.styleable
+                                    .InputMethod_Subtype_isAsciiCapable, false)).build();
                     if (!subtype.isAuxiliary()) {
-                        mIsAuxIme = false;
+                        isAuxIme = false;
                     }
                     mSubtypes.add(subtype);
                 }
@@ -194,7 +206,7 @@
         }
 
         if (mSubtypes.size() == 0) {
-            mIsAuxIme = false;
+            isAuxIme = false;
         }
 
         if (additionalSubtypesMap != null && additionalSubtypesMap.containsKey(mId)) {
@@ -212,6 +224,8 @@
         }
         mSettingsActivityName = settingsActivityComponent;
         mIsDefaultResId = isDefaultResId;
+        mIsAuxIme = isAuxIme;
+        mSupportsSwitchingToNextInputMethod = supportsSwitchingToNextInputMethod;
     }
 
     InputMethodInfo(Parcel source) {
@@ -219,6 +233,7 @@
         mSettingsActivityName = source.readString();
         mIsDefaultResId = source.readInt();
         mIsAuxIme = source.readInt() == 1;
+        mSupportsSwitchingToNextInputMethod = source.readInt() == 1;
         mService = ResolveInfo.CREATOR.createFromParcel(source);
         source.readTypedList(mSubtypes, InputMethodSubtype.CREATOR);
         mForceDefault = false;
@@ -250,6 +265,7 @@
             mSubtypes.addAll(subtypes);
         }
         mForceDefault = forceDefault;
+        mSupportsSwitchingToNextInputMethod = true;
     }
 
     private static ResolveInfo buildDummyResolveInfo(String packageName, String className,
@@ -431,6 +447,14 @@
     }
 
     /**
+     * @return true if this input method supports ways to switch to a next input method.
+     * @hide
+     */
+    public boolean supportsSwitchingToNextInputMethod() {
+        return mSupportsSwitchingToNextInputMethod;
+    }
+
+    /**
      * Used to package this object into a {@link Parcel}.
      * 
      * @param dest The {@link Parcel} to be written.
@@ -442,6 +466,7 @@
         dest.writeString(mSettingsActivityName);
         dest.writeInt(mIsDefaultResId);
         dest.writeInt(mIsAuxIme ? 1 : 0);
+        dest.writeInt(mSupportsSwitchingToNextInputMethod ? 1 : 0);
         mService.writeToParcel(dest, flags);
         dest.writeTypedList(mSubtypes);
     }
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 4df4734..53f7c79 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -613,7 +613,8 @@
     public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(InputMethodInfo imi,
             boolean allowsImplicitlySelectedSubtypes) {
         try {
-            return mService.getEnabledInputMethodSubtypeList(imi, allowsImplicitlySelectedSubtypes);
+            return mService.getEnabledInputMethodSubtypeList(
+                    imi == null ? null : imi.getId(), allowsImplicitlySelectedSubtypes);
         } catch (RemoteException e) {
             throw new RuntimeException(e);
         }
@@ -1411,12 +1412,17 @@
 
                 try {
                     if (DEBUG) Log.v(TAG, "SELECTION CHANGE: " + mCurMethod);
-                    mCurMethod.updateSelection(mCursorSelStart, mCursorSelEnd,
-                            selStart, selEnd, candidatesStart, candidatesEnd);
+                    final int oldSelStart = mCursorSelStart;
+                    final int oldSelEnd = mCursorSelEnd;
+                    // Update internal values before sending updateSelection to the IME, because
+                    // if it changes the text within its onUpdateSelection handler in a way that
+                    // does not move the cursor we don't want to call it again with the same values.
                     mCursorSelStart = selStart;
                     mCursorSelEnd = selEnd;
                     mCursorCandStart = candidatesStart;
                     mCursorCandEnd = candidatesEnd;
+                    mCurMethod.updateSelection(oldSelStart, oldSelEnd,
+                            selStart, selEnd, candidatesStart, candidatesEnd);
                 } catch (RemoteException e) {
                     Log.w(TAG, "IME died: " + mCurId, e);
                 }
@@ -1875,6 +1881,28 @@
     }
 
     /**
+     * Returns true if the current IME needs to offer the users ways to switch to a next input
+     * method (e.g. a globe key.).
+     * When an IME sets supportsSwitchingToNextInputMethod and this method returns true,
+     * the IME has to offer ways to to invoke {@link #switchToNextInputMethod} accordingly.
+     * <p> Note that the system determines the most appropriate next input method
+     * and subtype in order to provide the consistent user experience in switching
+     * between IMEs and subtypes.
+     * @param imeToken Supplies the identifying token given to an input method when it was started,
+     * which allows it to perform this operation on itself.
+     */
+    public boolean shouldOfferSwitchingToNextInputMethod(IBinder imeToken) {
+        synchronized (mH) {
+            try {
+                return mService.shouldOfferSwitchingToNextInputMethod(imeToken);
+            } catch (RemoteException e) {
+                Log.w(TAG, "IME died: " + mCurId, e);
+                return false;
+            }
+        }
+    }
+
+    /**
      * Set additional input method subtypes. Only a process which shares the same uid with the IME
      * can add additional input method subtypes to the IME.
      * Please note that a subtype's status is stored in the system.
diff --git a/core/java/android/view/inputmethod/InputMethodSubtype.java b/core/java/android/view/inputmethod/InputMethodSubtype.java
index 7895e6f..88b2977 100644
--- a/core/java/android/view/inputmethod/InputMethodSubtype.java
+++ b/core/java/android/view/inputmethod/InputMethodSubtype.java
@@ -52,6 +52,7 @@
 
     private final boolean mIsAuxiliary;
     private final boolean mOverridesImplicitlyEnabledSubtype;
+    private final boolean mIsAsciiCapable;
     private final int mSubtypeHashCode;
     private final int mSubtypeIconResId;
     private final int mSubtypeNameResId;
@@ -62,24 +63,145 @@
     private volatile HashMap<String, String> mExtraValueHashMapCache;
 
     /**
+     * InputMethodSubtypeBuilder is a builder class of InputMethodSubtype.
+     * This class is designed to be used with
+     * {@link android.view.inputmethod.InputMethodManager#setAdditionalInputMethodSubtypes}.
+     * The developer needs to be aware of what each parameter means.
+     */
+    public static class InputMethodSubtypeBuilder {
+        /**
+         * @param isAuxiliary should true when this subtype is auxiliary, false otherwise.
+         * An auxiliary subtype has the following differences with a regular subtype:
+         * - An auxiliary subtype cannot be chosen as the default IME in Settings.
+         * - The framework will never switch to this subtype through
+         *   {@link android.view.inputmethod.InputMethodManager#switchToLastInputMethod}.
+         * Note that the subtype will still be available in the IME switcher.
+         * The intent is to allow for IMEs to specify they are meant to be invoked temporarily
+         * in a one-shot way, and to return to the previous IME once finished (e.g. voice input).
+         */
+        public InputMethodSubtypeBuilder setIsAuxiliary(boolean isAuxiliary) {
+            mIsAuxiliary = isAuxiliary;
+            return this;
+        }
+        private boolean mIsAuxiliary = false;
+
+        /**
+         * @param overridesImplicitlyEnabledSubtype should be true if this subtype should be
+         * enabled by default if no other subtypes in the IME are enabled explicitly. Note that a
+         * subtype with this parameter set will not be shown in the list of subtypes in each IME's
+         * subtype enabler. A canonical use of this would be for an IME to supply an "automatic"
+         * subtype that adapts to the current system language.
+         */
+        public InputMethodSubtypeBuilder setOverridesImplicitlyEnabledSubtype(
+                boolean overridesImplicitlyEnabledSubtype) {
+            mOverridesImplicitlyEnabledSubtype = overridesImplicitlyEnabledSubtype;
+            return this;
+        }
+        private boolean mOverridesImplicitlyEnabledSubtype = false;
+
+        /**
+         * @param isAsciiCapable should be true if this subtype is ASCII capable. If the subtype
+         * is ASCII capable, it should guarantee that the user can input ASCII characters with
+         * this subtype. This is important because many password fields only allow
+         * ASCII-characters.
+         */
+        public InputMethodSubtypeBuilder setIsAsciiCapable(boolean isAsciiCapable) {
+            mIsAsciiCapable = isAsciiCapable;
+            return this;
+        }
+        private boolean mIsAsciiCapable = false;
+
+        /**
+         * @param subtypeIconResId is a resource ID of the subtype icon drawable.
+         */
+        public InputMethodSubtypeBuilder setSubtypeIconResId(int subtypeIconResId) {
+            mSubtypeIconResId = subtypeIconResId;
+            return this;
+        }
+        private int mSubtypeIconResId = 0;
+
+        /**
+         * @param subtypeNameResId is the resource ID of the subtype name string.
+         * The string resource may have exactly one %s in it. If present,
+         * the %s part will be replaced with the locale's display name by
+         * the formatter. Please refer to {@link #getDisplayName} for details.
+         */
+        public InputMethodSubtypeBuilder setSubtypeNameResId(int subtypeNameResId) {
+            mSubtypeNameResId = subtypeNameResId;
+            return this;
+        }
+        private int mSubtypeNameResId = 0;
+
+        /**
+         * @param subtypeId is the unique ID for this subtype. The input method framework keeps
+         * track of enabled subtypes by ID. When the IME package gets upgraded, enabled IDs will
+         * stay enabled even if other attributes are different. If the ID is unspecified or 0,
+         * Arrays.hashCode(new Object[] {locale, mode, extraValue,
+         * isAuxiliary, overridesImplicitlyEnabledSubtype}) will be used instead.
+         */
+        public InputMethodSubtypeBuilder setSubtypeId(int subtypeId) {
+            mSubtypeId = subtypeId;
+            return this;
+        }
+        private int mSubtypeId = 0;
+
+        /**
+         * @param subtypeLocale is the locale supported by this subtype.
+         */
+        public InputMethodSubtypeBuilder setSubtypeLocale(String subtypeLocale) {
+            mSubtypeLocale = subtypeLocale == null ? "" : subtypeLocale;
+            return this;
+        }
+        private String mSubtypeLocale = "";
+
+        /**
+         * @param subtypeMode is the mode supported by this subtype.
+         */
+        public InputMethodSubtypeBuilder setSubtypeMode(String subtypeMode) {
+            mSubtypeMode = subtypeMode == null ? "" : subtypeMode;
+            return this;
+        }
+        private String mSubtypeMode = "";
+        /**
+         * @param subtypeExtraValue is the extra value of the subtype. This string is free-form,
+         * but the API supplies tools to deal with a key-value comma-separated list; see
+         * {@link #containsExtraValueKey} and {@link #getExtraValueOf}.
+         */
+        public InputMethodSubtypeBuilder setSubtypeExtraValue(String subtypeExtraValue) {
+            mSubtypeExtraValue = subtypeExtraValue == null ? "" : subtypeExtraValue;
+            return this;
+        }
+        private String mSubtypeExtraValue = "";
+
+        /**
+         * @return InputMethodSubtype using parameters in this InputMethodSubtypeBuilder.
+         */
+        public InputMethodSubtype build() {
+            return new InputMethodSubtype(this);
+        }
+     }
+
+     private static InputMethodSubtypeBuilder getBuilder(int nameId, int iconId, String locale,
+             String mode, String extraValue, boolean isAuxiliary,
+             boolean overridesImplicitlyEnabledSubtype, int id, boolean isAsciiCapable) {
+         final InputMethodSubtypeBuilder builder = new InputMethodSubtypeBuilder();
+         builder.mSubtypeNameResId = nameId;
+         builder.mSubtypeIconResId = iconId;
+         builder.mSubtypeLocale = locale;
+         builder.mSubtypeMode = mode;
+         builder.mSubtypeExtraValue = extraValue;
+         builder.mIsAuxiliary = isAuxiliary;
+         builder.mOverridesImplicitlyEnabledSubtype = overridesImplicitlyEnabledSubtype;
+         builder.mSubtypeId = id;
+         builder.mIsAsciiCapable = isAsciiCapable;
+         return builder;
+     }
+
+    /**
      * Constructor with no subtype ID specified, overridesImplicitlyEnabledSubtype not specified.
-     * @param nameId Resource ID of the subtype name string. The string resource may have exactly
-     * one %s in it. If there is, the %s part will be replaced with the locale's display name by
-     * the formatter. Please refer to {@link #getDisplayName} for details.
-     * @param iconId Resource ID of the subtype icon drawable.
-     * @param locale The locale supported by the subtype
-     * @param mode The mode supported by the subtype
-     * @param extraValue The extra value of the subtype. This string is free-form, but the API
-     * supplies tools to deal with a key-value comma-separated list; see
-     * {@link #containsExtraValueKey} and {@link #getExtraValueOf}.
-     * @param isAuxiliary true when this subtype is auxiliary, false otherwise. An auxiliary
-     * subtype will not be shown in the list of enabled IMEs for choosing the current IME in
-     * the Settings even when this subtype is enabled. Please note that this subtype will still
-     * be shown in the list of IMEs in the IME switcher to allow the user to tentatively switch
-     * to this subtype while an IME is shown. The framework will never switch the current IME to
-     * this subtype by {@link android.view.inputmethod.InputMethodManager#switchToLastInputMethod}.
-     * The intent of having this flag is to allow for IMEs that are invoked in a one-shot way as
-     * auxiliary input mode, and return to the previous IME once it is finished (e.g. voice input).
+     * Arguments for this constructor have the same meanings as
+     * {@link InputMethodSubtype#InputMethodSubtype(int, int, String, String, String, boolean,
+     * boolean, int)} except "id" and "overridesImplicitlyEnabledSubtype".
      * @hide
      */
     public InputMethodSubtype(int nameId, int iconId, String locale, String mode, String extraValue,
@@ -89,27 +211,10 @@
 
     /**
      * Constructor with no subtype ID specified.
-     * @param nameId Resource ID of the subtype name string. The string resource may have exactly
-     * one %s in it. If there is, the %s part will be replaced with the locale's display name by
-     * the formatter. Please refer to {@link #getDisplayName} for details.
-     * @param iconId Resource ID of the subtype icon drawable.
-     * @param locale The locale supported by the subtype
-     * @param mode The mode supported by the subtype
-     * @param extraValue The extra value of the subtype. This string is free-form, but the API
-     * supplies tools to deal with a key-value comma-separated list; see
-     * {@link #containsExtraValueKey} and {@link #getExtraValueOf}.
-     * @param isAuxiliary true when this subtype is auxiliary, false otherwise. An auxiliary
-     * subtype will not be shown in the list of enabled IMEs for choosing the current IME in
-     * the Settings even when this subtype is enabled. Please note that this subtype will still
-     * be shown in the list of IMEs in the IME switcher to allow the user to tentatively switch
-     * to this subtype while an IME is shown. The framework will never switch the current IME to
-     * this subtype by {@link android.view.inputmethod.InputMethodManager#switchToLastInputMethod}.
-     * The intent of having this flag is to allow for IMEs that are invoked in a one-shot way as
-     * auxiliary input mode, and return to the previous IME once it is finished (e.g. voice input).
-     * @param overridesImplicitlyEnabledSubtype true when this subtype should be enabled by default
-     * if no other subtypes in the IME are enabled explicitly. Note that a subtype with this
-     * parameter being true will not be shown in the list of subtypes in each IME's subtype enabler.
-     * Having an "automatic" subtype is an example use of this flag.
+     * @deprecated use {@link InputMethodSubtypeBuilder} instead.
+     * Arguments for this constructor have the same meanings as
+     * {@link InputMethodSubtype#InputMethodSubtype(int, int, String, String, String, boolean,
+     * boolean, int)} except "id".
      */
     public InputMethodSubtype(int nameId, int iconId, String locale, String mode, String extraValue,
             boolean isAuxiliary, boolean overridesImplicitlyEnabledSubtype) {
@@ -119,6 +224,8 @@
 
     /**
      * Constructor.
+     * @deprecated use {@link InputMethodSubtypeBuilder} instead.
+     * "isAsciiCapable" is "false" in this constructor.
      * @param nameId Resource ID of the subtype name string. The string resource may have exactly
      * one %s in it. If there is, the %s part will be replaced with the locale's display name by
      * the formatter. Please refer to {@link #getDisplayName} for details.
@@ -148,18 +255,29 @@
      */
     public InputMethodSubtype(int nameId, int iconId, String locale, String mode, String extraValue,
             boolean isAuxiliary, boolean overridesImplicitlyEnabledSubtype, int id) {
-        mSubtypeNameResId = nameId;
-        mSubtypeIconResId = iconId;
-        mSubtypeLocale = locale != null ? locale : "";
-        mSubtypeMode = mode != null ? mode : "";
-        mSubtypeExtraValue = extraValue != null ? extraValue : "";
-        mIsAuxiliary = isAuxiliary;
-        mOverridesImplicitlyEnabledSubtype = overridesImplicitlyEnabledSubtype;
+        this(getBuilder(nameId, iconId, locale, mode, extraValue, isAuxiliary,
+                overridesImplicitlyEnabledSubtype, id, false));
+    }
+
+    /**
+     * Constructor.
+     * @param builder Builder for InputMethodSubtype
+     */
+    private InputMethodSubtype(InputMethodSubtypeBuilder builder) {
+        mSubtypeNameResId = builder.mSubtypeNameResId;
+        mSubtypeIconResId = builder.mSubtypeIconResId;
+        mSubtypeLocale = builder.mSubtypeLocale;
+        mSubtypeMode = builder.mSubtypeMode;
+        mSubtypeExtraValue = builder.mSubtypeExtraValue;
+        mIsAuxiliary = builder.mIsAuxiliary;
+        mOverridesImplicitlyEnabledSubtype = builder.mOverridesImplicitlyEnabledSubtype;
+        mSubtypeId = builder.mSubtypeId;
+        mIsAsciiCapable = builder.mIsAsciiCapable;
         // If hashCode() of this subtype is 0 and you want to specify it as an id of this subtype,
         // just specify 0 as this subtype's id. Then, this subtype's id is treated as 0.
-        mSubtypeHashCode = id != 0 ? id : hashCodeInternal(mSubtypeLocale, mSubtypeMode,
-                mSubtypeExtraValue, mIsAuxiliary, mOverridesImplicitlyEnabledSubtype);
-        mSubtypeId = id;
+        mSubtypeHashCode = mSubtypeId != 0 ? mSubtypeId : hashCodeInternal(mSubtypeLocale,
+                mSubtypeMode, mSubtypeExtraValue, mIsAuxiliary, mOverridesImplicitlyEnabledSubtype,
+                mIsAsciiCapable);
     }
 
     InputMethodSubtype(Parcel source) {
@@ -176,6 +294,7 @@
         mOverridesImplicitlyEnabledSubtype = (source.readInt() == 1);
         mSubtypeHashCode = source.readInt();
         mSubtypeId = source.readInt();
+        mIsAsciiCapable = (source.readInt() == 1);
     }
 
     /**
@@ -239,6 +358,15 @@
     }
 
     /**
+     * @return true if this subtype is Ascii capable, false otherwise. If the subtype is ASCII
+     * capable, it should guarantee that the user can input ASCII characters with this subtype.
+     * This is important because many password fields only allow ASCII-characters.
+     */
+    public boolean isAsciiCapable() {
+        return mIsAsciiCapable;
+    }
+
+    /**
      * @param context Context will be used for getting Locale and PackageManager.
      * @param packageName The package name of the IME
      * @param appInfo The application info of the IME
@@ -336,7 +464,8 @@
                 && (subtype.getIconResId() == getIconResId())
                 && (subtype.getLocale().equals(getLocale()))
                 && (subtype.getExtraValue().equals(getExtraValue()))
-                && (subtype.isAuxiliary() == isAuxiliary());
+                && (subtype.isAuxiliary() == isAuxiliary())
+                && (subtype.isAsciiCapable() == isAsciiCapable());
         }
         return false;
     }
@@ -357,6 +486,7 @@
         dest.writeInt(mOverridesImplicitlyEnabledSubtype ? 1 : 0);
         dest.writeInt(mSubtypeHashCode);
         dest.writeInt(mSubtypeId);
+        dest.writeInt(mIsAsciiCapable ? 1 : 0);
     }
 
     public static final Parcelable.Creator<InputMethodSubtype> CREATOR
@@ -389,9 +519,10 @@
     }
 
     private static int hashCodeInternal(String locale, String mode, String extraValue,
-            boolean isAuxiliary, boolean overridesImplicitlyEnabledSubtype) {
+            boolean isAuxiliary, boolean overridesImplicitlyEnabledSubtype,
+            boolean isAsciiCapable) {
         return Arrays.hashCode(new Object[] {locale, mode, extraValue, isAuxiliary,
-                overridesImplicitlyEnabledSubtype});
+                overridesImplicitlyEnabledSubtype, isAsciiCapable});
     }
 
     /**
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index fea6be6..7707392 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -50,7 +50,9 @@
  */
 class CallbackProxy extends Handler {
     // Logging tag
-    private static final String LOGTAG = "CallbackProxy";
+    static final String LOGTAG = "WebViewCallback";
+    // Enables API callback tracing
+    private static final boolean TRACE = DebugFlags.TRACE_CALLBACK;
     // Instance of WebViewClient that is the client callback.
     private volatile WebViewClient mWebViewClient;
     // Instance of WebChromeClient for handling all chrome functions.
@@ -258,6 +260,7 @@
         }
         boolean override = false;
         if (mWebViewClient != null) {
+            if (TRACE) Log.d(LOGTAG, "shouldOverrideUrlLoading=" + overrideUrl);
             override = mWebViewClient.shouldOverrideUrlLoading(mWebView.getWebView(),
                     overrideUrl);
         } else {
@@ -307,6 +310,7 @@
                 String startedUrl = msg.getData().getString("url");
                 mWebView.onPageStarted(startedUrl);
                 if (mWebViewClient != null) {
+                    if (TRACE) Log.d(LOGTAG, "onPageStarted=" + startedUrl);
                     mWebViewClient.onPageStarted(mWebView.getWebView(), startedUrl,
                             (Bitmap) msg.obj);
                 }
@@ -316,18 +320,21 @@
                 String finishedUrl = (String) msg.obj;
                 mWebView.onPageFinished(finishedUrl);
                 if (mWebViewClient != null) {
+                    if (TRACE) Log.d(LOGTAG, "onPageFinished=" + finishedUrl);
                     mWebViewClient.onPageFinished(mWebView.getWebView(), finishedUrl);
                 }
                 break;
 
             case RECEIVED_ICON:
                 if (mWebChromeClient != null) {
+                    if (TRACE) Log.d(LOGTAG, "onReceivedIcon");
                     mWebChromeClient.onReceivedIcon(mWebView.getWebView(), (Bitmap) msg.obj);
                 }
                 break;
 
             case RECEIVED_TOUCH_ICON_URL:
                 if (mWebChromeClient != null) {
+                    if (TRACE) Log.d(LOGTAG, "onReceivedTouchIconUrl");
                     mWebChromeClient.onReceivedTouchIconUrl(mWebView.getWebView(),
                             (String) msg.obj, msg.arg1 == 1);
                 }
@@ -335,6 +342,7 @@
 
             case RECEIVED_TITLE:
                 if (mWebChromeClient != null) {
+                    if (TRACE) Log.d(LOGTAG, "onReceivedTitle");
                     mWebChromeClient.onReceivedTitle(mWebView.getWebView(),
                             (String) msg.obj);
                 }
@@ -345,6 +353,7 @@
                     int reasonCode = msg.arg1;
                     final String description  = msg.getData().getString("description");
                     final String failUrl  = msg.getData().getString("failingUrl");
+                    if (TRACE) Log.d(LOGTAG, "onReceivedError=" + failUrl);
                     mWebViewClient.onReceivedError(mWebView.getWebView(), reasonCode,
                             description, failUrl);
                 }
@@ -356,6 +365,7 @@
                 Message dontResend =
                         (Message) msg.getData().getParcelable("dontResend");
                 if (mWebViewClient != null) {
+                    if (TRACE) Log.d(LOGTAG, "onFormResubmission");
                     mWebViewClient.onFormResubmission(mWebView.getWebView(), dontResend,
                             resend);
                 } else {
@@ -379,6 +389,7 @@
                     HttpAuthHandler handler = (HttpAuthHandler) msg.obj;
                     String host = msg.getData().getString("host");
                     String realm = msg.getData().getString("realm");
+                    if (TRACE) Log.d(LOGTAG, "onReceivedHttpAuthRequest");
                     mWebViewClient.onReceivedHttpAuthRequest(mWebView.getWebView(), handler,
                             host, realm);
                 }
@@ -388,6 +399,7 @@
                 if (mWebViewClient != null) {
                     HashMap<String, Object> map =
                         (HashMap<String, Object>) msg.obj;
+                    if (TRACE) Log.d(LOGTAG, "onReceivedSslError");
                     mWebViewClient.onReceivedSslError(mWebView.getWebView(),
                             (SslErrorHandler) map.get("handler"),
                             (SslError) map.get("error"));
@@ -396,6 +408,7 @@
 
             case PROCEEDED_AFTER_SSL_ERROR:
                 if (mWebViewClient != null && mWebViewClient instanceof WebViewClientClassicExt) {
+                    if (TRACE) Log.d(LOGTAG, "onProceededAfterSslError");
                     ((WebViewClientClassicExt) mWebViewClient).onProceededAfterSslError(
                             mWebView.getWebView(),
                             (SslError) msg.obj);
@@ -404,6 +417,7 @@
 
             case CLIENT_CERT_REQUEST:
                 if (mWebViewClient != null  && mWebViewClient instanceof WebViewClientClassicExt) {
+                    if (TRACE) Log.d(LOGTAG, "onReceivedClientCertRequest");
                     HashMap<String, Object> map = (HashMap<String, Object>) msg.obj;
                     ((WebViewClientClassicExt) mWebViewClient).onReceivedClientCertRequest(
                             mWebView.getWebView(),
@@ -418,6 +432,7 @@
                 // changed.
                 synchronized (this) {
                     if (mWebChromeClient != null) {
+                        if (TRACE) Log.d(LOGTAG, "onProgressChanged=" + mLatestProgress);
                         mWebChromeClient.onProgressChanged(mWebView.getWebView(),
                                 mLatestProgress);
                     }
@@ -427,14 +442,18 @@
 
             case UPDATE_VISITED:
                 if (mWebViewClient != null) {
+                    String url = (String) msg.obj;
+                    if (TRACE) Log.d(LOGTAG, "doUpdateVisitedHistory=" + url);
                     mWebViewClient.doUpdateVisitedHistory(mWebView.getWebView(),
-                            (String) msg.obj, msg.arg1 != 0);
+                            url, msg.arg1 != 0);
                 }
                 break;
 
             case LOAD_RESOURCE:
                 if (mWebViewClient != null) {
-                    mWebViewClient.onLoadResource(mWebView.getWebView(), (String) msg.obj);
+                    String url = (String) msg.obj;
+                    if (TRACE) Log.d(LOGTAG, "onLoadResource=" + url);
+                    mWebViewClient.onLoadResource(mWebView.getWebView(), url);
                 }
                 break;
 
@@ -448,6 +467,7 @@
                     String referer = msg.getData().getString("referer");
                     Long contentLength = msg.getData().getLong("contentLength");
 
+                    if (TRACE) Log.d(LOGTAG, "onDownloadStart");
                     if (mDownloadListener instanceof BrowserDownloadListener) {
                         ((BrowserDownloadListener) mDownloadListener).onDownloadStart(url,
                              userAgent, contentDisposition, mimetype, referer, contentLength);
@@ -460,6 +480,7 @@
 
             case CREATE_WINDOW:
                 if (mWebChromeClient != null) {
+                    if (TRACE) Log.d(LOGTAG, "onCreateWindow");
                     if (!mWebChromeClient.onCreateWindow(mWebView.getWebView(),
                                 msg.arg1 == 1, msg.arg2 == 1,
                                 (Message) msg.obj)) {
@@ -473,12 +494,14 @@
 
             case REQUEST_FOCUS:
                 if (mWebChromeClient != null) {
+                    if (TRACE) Log.d(LOGTAG, "onRequestFocus");
                     mWebChromeClient.onRequestFocus(mWebView.getWebView());
                 }
                 break;
 
             case CLOSE_WINDOW:
                 if (mWebChromeClient != null) {
+                    if (TRACE) Log.d(LOGTAG, "onCloseWindow");
                     mWebChromeClient.onCloseWindow(((WebViewClassic) msg.obj).getWebView());
                 }
                 break;
@@ -500,6 +523,7 @@
 
             case ASYNC_KEYEVENTS:
                 if (mWebViewClient != null) {
+                    if (TRACE) Log.d(LOGTAG, "onUnhandledKeyEvent");
                     mWebViewClient.onUnhandledKeyEvent(mWebView.getWebView(),
                             (KeyEvent) msg.obj);
                 }
@@ -521,6 +545,7 @@
                     WebStorage.QuotaUpdater quotaUpdater =
                         (WebStorage.QuotaUpdater) map.get("quotaUpdater");
 
+                    if (TRACE) Log.d(LOGTAG, "onExceededDatabaseQuota");
                     mWebChromeClient.onExceededDatabaseQuota(url,
                             databaseIdentifier, quota, estimatedDatabaseSize,
                             totalQuota, quotaUpdater);
@@ -538,6 +563,7 @@
                     WebStorage.QuotaUpdater quotaUpdater =
                         (WebStorage.QuotaUpdater) map.get("quotaUpdater");
 
+                    if (TRACE) Log.d(LOGTAG, "onReachedMaxAppCacheSize");
                     mWebChromeClient.onReachedMaxAppCacheSize(requiredStorage,
                             quota, quotaUpdater);
                 }
@@ -551,6 +577,7 @@
                     GeolocationPermissions.Callback callback =
                             (GeolocationPermissions.Callback)
                             map.get("callback");
+                    if (TRACE) Log.d(LOGTAG, "onGeolocationPermissionsShowPrompt");
                     mWebChromeClient.onGeolocationPermissionsShowPrompt(origin,
                             callback);
                 }
@@ -558,6 +585,7 @@
 
             case GEOLOCATION_PERMISSIONS_HIDE_PROMPT:
                 if (mWebChromeClient != null) {
+                    if (TRACE) Log.d(LOGTAG, "onGeolocationPermissionsHidePrompt");
                     mWebChromeClient.onGeolocationPermissionsHidePrompt();
                 }
                 break;
@@ -566,6 +594,7 @@
                 if (mWebChromeClient != null) {
                     final JsResultReceiver receiver = (JsResultReceiver) msg.obj;
                     JsDialogHelper helper = new JsDialogHelper(receiver.mJsResult, msg);
+                    if (TRACE) Log.d(LOGTAG, "onJsAlert");
                     if (!helper.invokeCallback(mWebChromeClient, mWebView.getWebView())) {
                         helper.showDialog(mContext);
                     }
@@ -577,6 +606,7 @@
                 if(mWebChromeClient != null) {
                     final JsResultReceiver receiver = (JsResultReceiver) msg.obj;
                     final JsResult res = receiver.mJsResult;
+                    if (TRACE) Log.d(LOGTAG, "onJsTimeout");
                     if (mWebChromeClient.onJsTimeout()) {
                         res.confirm();
                     } else {
@@ -598,6 +628,7 @@
 
             case SCALE_CHANGED:
                 if (mWebViewClient != null) {
+                    if (TRACE) Log.d(LOGTAG, "onScaleChanged");
                     mWebViewClient.onScaleChanged(mWebView.getWebView(), msg.getData()
                             .getFloat("old"), msg.getData().getFloat("new"));
                 }
@@ -624,6 +655,7 @@
                 ConsoleMessage.MessageLevel messageLevel =
                         ConsoleMessage.MessageLevel.values()[msgLevel];
 
+                if (TRACE) Log.d(LOGTAG, "onConsoleMessage");
                 if (!mWebChromeClient.onConsoleMessage(new ConsoleMessage(message, sourceID,
                         lineNumber, messageLevel))) {
                     // If false was returned the user did not provide their own console function so
@@ -654,12 +686,14 @@
 
             case GET_VISITED_HISTORY:
                 if (mWebChromeClient != null) {
+                    if (TRACE) Log.d(LOGTAG, "getVisitedHistory");
                     mWebChromeClient.getVisitedHistory((ValueCallback<String[]>)msg.obj);
                 }
                 break;
 
             case OPEN_FILE_CHOOSER:
                 if (mWebChromeClient != null) {
+                    if (TRACE) Log.d(LOGTAG, "openFileChooser");
                     UploadFileMessageData data = (UploadFileMessageData)msg.obj;
                     mWebChromeClient.openFileChooser(data.getUploadFile(), data.getAcceptType(),
                             data.getCapture());
@@ -668,6 +702,7 @@
 
             case ADD_HISTORY_ITEM:
                 if (mWebBackForwardListClient != null) {
+                    if (TRACE) Log.d(LOGTAG, "onNewHistoryItem");
                     mWebBackForwardListClient.onNewHistoryItem(
                             (WebHistoryItem) msg.obj);
                 }
@@ -693,6 +728,7 @@
                     String realm = msg.getData().getString("realm");
                     String account = msg.getData().getString("account");
                     String args = msg.getData().getString("args");
+                    if (TRACE) Log.d(LOGTAG, "onReceivedLoginRequest");
                     mWebViewClient.onReceivedLoginRequest(mWebView.getWebView(), realm,
                             account, args);
                 }
@@ -910,6 +946,7 @@
             return null;
         }
         // Note: This method does _not_ send a message.
+        if (TRACE) Log.d(LOGTAG, "shouldInterceptRequest=" + url);
         WebResourceResponse r =
                 mWebViewClient.shouldInterceptRequest(mWebView.getWebView(), url);
         if (r == null) {
diff --git a/core/java/android/webkit/DebugFlags.java b/core/java/android/webkit/DebugFlags.java
index 349113e..524f610 100644
--- a/core/java/android/webkit/DebugFlags.java
+++ b/core/java/android/webkit/DebugFlags.java
@@ -24,25 +24,33 @@
  * The name of each flags maps directly to the name of the class in which that
  * flag is used.
  *
+ * @hide Only used by WebView implementations.
  */
-class DebugFlags {
+public class DebugFlags {
 
+    public static final boolean COOKIE_SYNC_MANAGER = false;
+    public static final boolean TRACE_API = false;
+    public static final boolean TRACE_CALLBACK = false;
+    public static final boolean TRACE_JAVASCRIPT_BRIDGE = false;
+    public static final boolean URL_UTIL = false;
+    public static final boolean WEB_SYNC_MANAGER = false;
+
+    // TODO: Delete these when WebViewClassic is moved
     public static final boolean BROWSER_FRAME = false;
     public static final boolean CACHE_MANAGER = false;
     public static final boolean CALLBACK_PROXY = false;
     public static final boolean COOKIE_MANAGER = false;
-    public static final boolean COOKIE_SYNC_MANAGER = false;
     public static final boolean FRAME_LOADER = false;
     public static final boolean J_WEB_CORE_JAVA_BRIDGE = false;// HIGHLY VERBOSE
     public static final boolean LOAD_LISTENER = false;
+    public static final boolean MEASURE_PAGE_SWAP_FPS = false;
     public static final boolean NETWORK = false;
     public static final boolean SSL_ERROR_HANDLER = false;
     public static final boolean STREAM_LOADER = false;
-    public static final boolean URL_UTIL = false;
     public static final boolean WEB_BACK_FORWARD_LIST = false;
     public static final boolean WEB_SETTINGS = false;
-    public static final boolean WEB_SYNC_MANAGER = false;
     public static final boolean WEB_VIEW = false;
     public static final boolean WEB_VIEW_CORE = false;
-    public static final boolean MEASURE_PAGE_SWAP_FPS = false;
+
+
 }
diff --git a/core/java/android/webkit/HTML5VideoFullScreen.java b/core/java/android/webkit/HTML5VideoFullScreen.java
index b52218d..6fb32c8 100644
--- a/core/java/android/webkit/HTML5VideoFullScreen.java
+++ b/core/java/android/webkit/HTML5VideoFullScreen.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.media.MediaPlayer;
 import android.media.Metadata;
+import android.util.Log;
 import android.view.Gravity;
 import android.view.MotionEvent;
 import android.view.SurfaceHolder;
@@ -293,12 +294,16 @@
         mLayout.setVisibility(View.VISIBLE);
         WebChromeClient client = webView.getWebChromeClient();
         if (client != null) {
+            if (DebugFlags.TRACE_CALLBACK) Log.d(CallbackProxy.LOGTAG, "onShowCustomView");
             client.onShowCustomView(mLayout, mCallback);
             // Plugins like Flash will draw over the video so hide
             // them while we're playing.
             if (webView.getViewManager() != null)
                 webView.getViewManager().hideAll();
 
+            if (DebugFlags.TRACE_CALLBACK) {
+                Log.d(CallbackProxy.LOGTAG, "getVideoLoadingProgressView");
+            }
             mProgressView = client.getVideoLoadingProgressView();
             if (mProgressView != null) {
                 mLayout.addView(mProgressView, layoutParams);
diff --git a/core/java/android/webkit/HTML5VideoViewProxy.java b/core/java/android/webkit/HTML5VideoViewProxy.java
index a3d62ae..e8538f6 100644
--- a/core/java/android/webkit/HTML5VideoViewProxy.java
+++ b/core/java/android/webkit/HTML5VideoViewProxy.java
@@ -180,6 +180,7 @@
             if (!mHTML5VideoView.fullScreenExited() && mHTML5VideoView.isFullScreenMode()) {
                 WebChromeClient client = webView.getWebChromeClient();
                 if (client != null) {
+                    if (DebugFlags.TRACE_CALLBACK) Log.d(CallbackProxy.LOGTAG, "onHideCustomView");
                     client.onHideCustomView();
                 }
             }
@@ -405,6 +406,7 @@
             case ERROR: {
                 WebChromeClient client = mWebView.getWebChromeClient();
                 if (client != null) {
+                    if (DebugFlags.TRACE_CALLBACK) Log.d(CallbackProxy.LOGTAG, "onHideCustomView");
                     client.onHideCustomView();
                 }
                 break;
@@ -412,6 +414,9 @@
             case LOAD_DEFAULT_POSTER: {
                 WebChromeClient client = mWebView.getWebChromeClient();
                 if (client != null) {
+                    if (DebugFlags.TRACE_CALLBACK) {
+                        Log.d(CallbackProxy.LOGTAG, "getDefaultVideoPoster");
+                    }
                     doSetPoster(client.getDefaultVideoPoster());
                 }
                 break;
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 8ae0021..7a38a16 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -333,8 +333,11 @@
     }
 
     /**
-     * Sets whether the WebView loads pages in overview mode. The default is
-     * false.
+     * Sets whether the WebView loads pages in overview mode, that is,
+     * zooms out the content to fit on screen by width. This setting is
+     * taken into account when the content width is greater than the width
+     * of the WebView control, for example, when {@link #getUseWideViewPort}
+     * is enabled. The default is false.
      */
     public void setLoadWithOverviewMode(boolean overview) {
         throw new MustOverrideException();
@@ -500,6 +503,12 @@
      * Sets the default zoom density of the page. This must be called from the UI
      * thread. The default is {@link ZoomDensity#MEDIUM}.
      *
+     * This setting is not recommended for use in new applications.  If the WebView
+     * is utilized to display mobile-oriented pages, the desired effect can be achieved by
+     * adjusting 'width' and 'initial-scale' attributes of page's 'meta viewport'
+     * tag. For pages lacking the tag, {@link android.webkit.WebView#setInitialScale}
+     * and {@link #setUseWideViewPort} can be used.
+     *
      * @param zoom the zoom density
      */
     public void setDefaultZoom(ZoomDensity zoom) {
@@ -510,6 +519,8 @@
      * Gets the default zoom density of the page. This should be called from
      * the UI thread.
      *
+     * This setting is not recommended for use in new applications.
+     *
      * @return the zoom density
      * @see #setDefaultZoom
      */
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 4998742..15331dc 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -28,9 +28,11 @@
 import android.net.http.SslCertificate;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.CancellationSignal;
 import android.os.Looper;
 import android.os.Message;
 import android.os.StrictMode;
+import android.print.PrintDocumentAdapter;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.KeyEvent;
@@ -41,6 +43,7 @@
 import android.view.ViewTreeObserver;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeProvider;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
 import android.widget.AbsoluteLayout;
@@ -240,7 +243,7 @@
         implements ViewTreeObserver.OnGlobalFocusChangeListener,
         ViewGroup.OnHierarchyChangeListener, ViewDebug.HierarchyHandler {
 
-    private static final String LOGTAG = "webview_proxy";
+    private static final String LOGTAG = "WebView";
 
     // Throwing an exception for incorrect thread usage if the
     // build target is JB MR2 or newer. Defaults to false, and is
@@ -492,9 +495,12 @@
         sEnforceThreadChecking = context.getApplicationInfo().targetSdkVersion >=
                 Build.VERSION_CODES.JELLY_BEAN_MR2;
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "WebView<init>");
 
         ensureProviderCreated();
         mProvider.init(javaScriptInterfaces, privateBrowsing);
+        // Post condition of creating a webview is the CookieSyncManager instance exists.
+        CookieSyncManager.createInstance(getContext());
     }
 
     /**
@@ -504,6 +510,7 @@
      */
     public void setHorizontalScrollbarOverlay(boolean overlay) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setHorizontalScrollbarOverlay=" + overlay);
         mProvider.setHorizontalScrollbarOverlay(overlay);
     }
 
@@ -514,6 +521,7 @@
      */
     public void setVerticalScrollbarOverlay(boolean overlay) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setVerticalScrollbarOverlay=" + overlay);
         mProvider.setVerticalScrollbarOverlay(overlay);
     }
 
@@ -568,6 +576,7 @@
     @Deprecated
     public void setCertificate(SslCertificate certificate) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setCertificate=" + certificate);
         mProvider.setCertificate(certificate);
     }
 
@@ -591,6 +600,7 @@
     @Deprecated
     public void savePassword(String host, String username, String password) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "savePassword=" + host);
         mProvider.savePassword(host, username, password);
     }
 
@@ -610,6 +620,7 @@
     public void setHttpAuthUsernamePassword(String host, String realm,
             String username, String password) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setHttpAuthUsernamePassword=" + host);
         mProvider.setHttpAuthUsernamePassword(host, realm, username, password);
     }
 
@@ -639,6 +650,7 @@
      */
     public void destroy() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "destroy");
         mProvider.destroy();
     }
 
@@ -677,6 +689,7 @@
      */
     public void setNetworkAvailable(boolean networkUp) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setNetworkAvailable=" + networkUp);
         mProvider.setNetworkAvailable(networkUp);
     }
 
@@ -693,6 +706,7 @@
      */
     public WebBackForwardList saveState(Bundle outState) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "saveState");
         return mProvider.saveState(outState);
     }
 
@@ -709,6 +723,7 @@
     @Deprecated
     public boolean savePicture(Bundle b, final File dest) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "savePicture=" + dest.getName());
         return mProvider.savePicture(b, dest);
     }
 
@@ -726,6 +741,7 @@
     @Deprecated
     public boolean restorePicture(Bundle b, File src) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "restorePicture=" + src.getName());
         return mProvider.restorePicture(b, src);
     }
 
@@ -743,6 +759,7 @@
      */
     public WebBackForwardList restoreState(Bundle inState) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "restoreState");
         return mProvider.restoreState(inState);
     }
 
@@ -759,6 +776,7 @@
      */
     public void loadUrl(String url, Map<String, String> additionalHttpHeaders) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "loadUrl(extra headers)=" + url);
         mProvider.loadUrl(url, additionalHttpHeaders);
     }
 
@@ -769,6 +787,7 @@
      */
     public void loadUrl(String url) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "loadUrl=" + url);
         mProvider.loadUrl(url);
     }
 
@@ -778,10 +797,12 @@
      * {@link #loadUrl(String)} instead.
      *
      * @param url the URL of the resource to load
-     * @param postData the data will be passed to "POST" request
+     * @param postData the data will be passed to "POST" request, which must be
+     *     be "application/x-www-form-urlencoded" encoded.
      */
     public void postUrl(String url, byte[] postData) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "postUrl=" + url);
         mProvider.postUrl(url, postData);
     }
 
@@ -816,6 +837,7 @@
      */
     public void loadData(String data, String mimeType, String encoding) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "loadData");
         mProvider.loadData(data, mimeType, encoding);
     }
 
@@ -831,7 +853,10 @@
      * <p>
      * If the base URL uses the data scheme, this method is equivalent to
      * calling {@link #loadData(String,String,String) loadData()} and the
-     * historyUrl is ignored.
+     * historyUrl is ignored, and the data will be treated as part of a data: URL.
+     * If the base URL uses any other scheme, then the data will be loaded into
+     * the WebView as a plain string (i.e. not part of a data URL) and any URL-encoded
+     * entities in the string will not be decoded.
      *
      * @param baseUrl the URL to use as the page's base URL. If null defaults to
      *                'about:blank'.
@@ -845,16 +870,35 @@
     public void loadDataWithBaseURL(String baseUrl, String data,
             String mimeType, String encoding, String historyUrl) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "loadDataWithBaseURL=" + baseUrl);
         mProvider.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl);
     }
 
     /**
+     * Asynchronously evaluates JavaScript in the context of the currently displayed page.
+     * If non-null, |resultCallback| will be invoked with any result returned from that
+     * execution. This method must be called on the UI thread and the callback will
+     * be made on the UI thread.
+     *
+     * @param script the JavaScript to execute.
+     * @param resultCallback A callback to be invoked when the script execution
+     *                       completes with the result of the execution (if any).
+     *                       May be null if no notificaion of the result is required.
+     */
+    public void evaluateJavascript(String script, ValueCallback<String> resultCallback) {
+        checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "evaluateJavascript=" + script);
+        mProvider.evaluateJavaScript(script, resultCallback);
+    }
+
+    /**
      * Saves the current view as a web archive.
      *
      * @param filename the filename where the archive should be placed
      */
     public void saveWebArchive(String filename) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "saveWebArchive=" + filename);
         mProvider.saveWebArchive(filename);
     }
 
@@ -872,6 +916,7 @@
      */
     public void saveWebArchive(String basename, boolean autoname, ValueCallback<String> callback) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "saveWebArchive(auto)=" + basename);
         mProvider.saveWebArchive(basename, autoname, callback);
     }
 
@@ -880,6 +925,7 @@
      */
     public void stopLoading() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "stopLoading");
         mProvider.stopLoading();
     }
 
@@ -888,6 +934,7 @@
      */
     public void reload() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "reload");
         mProvider.reload();
     }
 
@@ -906,6 +953,7 @@
      */
     public void goBack() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "goBack");
         mProvider.goBack();
     }
 
@@ -924,6 +972,7 @@
      */
     public void goForward() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "goForward");
         mProvider.goForward();
     }
 
@@ -949,6 +998,7 @@
      */
     public void goBackOrForward(int steps) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "goBackOrForwad=" + steps);
         mProvider.goBackOrForward(steps);
     }
 
@@ -968,6 +1018,7 @@
      */
     public boolean pageUp(boolean top) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "pageUp");
         return mProvider.pageUp(top);
     }
 
@@ -979,6 +1030,7 @@
      */
     public boolean pageDown(boolean bottom) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "pageDown");
         return mProvider.pageDown(bottom);
     }
 
@@ -991,6 +1043,7 @@
     @Deprecated
     public void clearView() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearView");
         mProvider.clearView();
     }
 
@@ -1010,10 +1063,29 @@
      */
     public Picture capturePicture() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "capturePicture");
         return mProvider.capturePicture();
     }
 
     /**
+     * Creates a PrintDocumentAdapter that provides the content of this Webview for printing.
+     * Only supported for API levels
+     * {@link android.os.Build.VERSION_CODES#KITKAT} and above.
+     *
+     * The adapter works by converting the Webview contents to a PDF stream. The Webview cannot
+     * be drawn during the conversion process - any such draws are undefined. It is recommended
+     * to use a dedicated off screen Webview for the printing. If necessary, an application may
+     * temporarily hide a visible WebView by using a custom PrintDocumentAdapter instance
+     * wrapped around the object returned and observing the onStart and onFinish methods. See
+     * {@link android.print.PrintDocumentAdapter} for more information.
+     */
+    public PrintDocumentAdapter createPrintDocumentAdapter() {
+        checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "createPrintDocumentAdapter");
+        return mProvider.createPrintDocumentAdapter();
+    }
+
+    /**
      * Gets the current scale of this WebView.
      *
      * @return the current scale
@@ -1030,10 +1102,18 @@
     }
 
     /**
-     * Sets the initial scale for this WebView. 0 means default. If
-     * {@link WebSettings#getUseWideViewPort()} is true, it zooms out all the
-     * way. Otherwise it starts with 100%. If initial scale is greater than 0,
-     * WebView starts with this value as initial scale.
+     * Sets the initial scale for this WebView. 0 means default.
+     * The behavior for the default scale depends on the state of
+     * {@link WebSettings#getUseWideViewPort()} and
+     * {@link WebSettings#getLoadWithOverviewMode()}.
+     * If the content fits into the WebView control by width, then
+     * the zoom is set to 100%. For wide content, the behavor
+     * depends on the state of {@link WebSettings#getLoadWithOverviewMode()}.
+     * If its value is true, the content will be zoomed out to be fit
+     * by width into the WebView control, otherwise not.
+     *
+     * If initial scale is greater than 0, WebView starts with this value
+     * as initial scale.
      * Please note that unlike the scale properties in the viewport meta tag,
      * this method doesn't take the screen density into account.
      *
@@ -1041,6 +1121,7 @@
      */
     public void setInitialScale(int scaleInPercent) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setInitialScale=" + scaleInPercent);
         mProvider.setInitialScale(scaleInPercent);
     }
 
@@ -1051,6 +1132,7 @@
      */
     public void invokeZoomPicker() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "invokeZoomPicker");
         mProvider.invokeZoomPicker();
     }
 
@@ -1074,6 +1156,7 @@
      */
     public HitTestResult getHitTestResult() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "getHitTestResult");
         return mProvider.getHitTestResult();
     }
 
@@ -1092,6 +1175,7 @@
      */
     public void requestFocusNodeHref(Message hrefMsg) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "requestFocusNodeHref");
         mProvider.requestFocusNodeHref(hrefMsg);
     }
 
@@ -1104,6 +1188,7 @@
      */
     public void requestImageRef(Message msg) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "requestImageRef");
         mProvider.requestImageRef(msg);
     }
 
@@ -1208,6 +1293,7 @@
      */
     public void pauseTimers() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "pauseTimers");
         mProvider.pauseTimers();
     }
 
@@ -1217,6 +1303,7 @@
      */
     public void resumeTimers() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "resumeTimers");
         mProvider.resumeTimers();
     }
 
@@ -1229,6 +1316,7 @@
      */
     public void onPause() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "onPause");
         mProvider.onPause();
     }
 
@@ -1237,6 +1325,7 @@
      */
     public void onResume() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "onResume");
         mProvider.onResume();
     }
 
@@ -1256,6 +1345,7 @@
      */
     public void freeMemory() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "freeMemory");
         mProvider.freeMemory();
     }
 
@@ -1267,6 +1357,7 @@
      */
     public void clearCache(boolean includeDiskFiles) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearCache");
         mProvider.clearCache(includeDiskFiles);
     }
 
@@ -1278,6 +1369,7 @@
      */
     public void clearFormData() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearFormData");
         mProvider.clearFormData();
     }
 
@@ -1286,6 +1378,7 @@
      */
     public void clearHistory() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearHistory");
         mProvider.clearHistory();
     }
 
@@ -1295,6 +1388,7 @@
      */
     public void clearSslPreferences() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearSslPreferences");
         mProvider.clearSslPreferences();
     }
 
@@ -1336,6 +1430,7 @@
      */
     public void findNext(boolean forward) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "findNext");
         mProvider.findNext(forward);
     }
 
@@ -1351,6 +1446,7 @@
     @Deprecated
     public int findAll(String find) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "findAll");
         StrictMode.noteSlowCall("findAll blocks UI: prefer findAllAsync");
         return mProvider.findAll(find);
     }
@@ -1365,6 +1461,7 @@
      */
     public void findAllAsync(String find) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "findAllAsync");
         mProvider.findAllAsync(find);
     }
 
@@ -1385,6 +1482,7 @@
     @Deprecated
     public boolean showFindDialog(String text, boolean showIme) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "showFindDialog");
         return mProvider.showFindDialog(text, showIme);
     }
 
@@ -1420,6 +1518,7 @@
      */
     public void clearMatches() {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearMatches");
         mProvider.clearMatches();
     }
 
@@ -1480,6 +1579,7 @@
     @Deprecated
     public void setPictureListener(PictureListener listener) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setPictureListener=" + listener);
         mProvider.setPictureListener(listener);
     }
 
@@ -1529,6 +1629,7 @@
      */
     public void addJavascriptInterface(Object object, String name) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "addJavascriptInterface=" + name);
         mProvider.addJavascriptInterface(object, name);
     }
 
@@ -1541,6 +1642,7 @@
      */
     public void removeJavascriptInterface(String name) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "removeJavascriptInterface=" + name);
         mProvider.removeJavascriptInterface(name);
     }
 
@@ -1630,6 +1732,7 @@
 
     public void flingScroll(int vx, int vy) {
         checkThread();
+        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "flingScroll");
         mProvider.flingScroll(vx, vy);
     }
 
@@ -1832,6 +1935,11 @@
             return WebView.this.getHorizontalScrollbarHeight();
         }
 
+        public void super_onDrawVerticalScrollBar(Canvas canvas, Drawable scrollBar,
+                int l, int t, int r, int b) {
+            WebView.super.onDrawVerticalScrollBar(canvas, scrollBar, l, t, r, b);
+        }
+
         // ---- Access to (non-public) fields ----
         /** Raw setter for the scroll X value, without invoking onScrollChanged handlers etc. */
         public void setScrollXRaw(int scrollX) {
@@ -2051,6 +2159,13 @@
     }
     */
 
+    @Override
+    public AccessibilityNodeProvider getAccessibilityNodeProvider() {
+        AccessibilityNodeProvider provider =
+                mProvider.getViewDelegate().getAccessibilityNodeProvider();
+        return provider == null ? super.getAccessibilityNodeProvider() : provider;
+    }
+
     @Deprecated
     @Override
     public boolean shouldDelayChildPressedState() {
@@ -2163,7 +2278,6 @@
         return mProvider.getViewDelegate().requestFocus(direction, previouslyFocusedRect);
     }
 
-    @Deprecated
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index a324502..e82ce30 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -57,15 +57,18 @@
 import android.os.AsyncTask;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.CancellationSignal;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
 import android.os.SystemClock;
+import android.print.PrintDocumentAdapter;
 import android.security.KeyChain;
 import android.text.Editable;
 import android.text.InputType;
 import android.text.Selection;
 import android.text.TextUtils;
+import android.util.AndroidRuntimeException;
 import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.Log;
@@ -89,6 +92,7 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeProvider;
 import android.view.inputmethod.BaseInputConnection;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
@@ -1293,6 +1297,19 @@
     // WebViewProvider bindings
 
     static class Factory implements WebViewFactoryProvider,  WebViewFactoryProvider.Statics {
+        Factory() {
+            // Touch JniUtil and WebViewCore in case this is being called from
+            // WebViewFactory.Preloader, to ensure that the JNI libraries that they use are
+            // preloaded in the zygote.
+            try {
+                Class.forName("android.webkit.JniUtil");
+                Class.forName("android.webkit.WebViewCore");
+            } catch (ClassNotFoundException e) {
+                Log.e(LOGTAG, "failed to load JNI libraries");
+                throw new AndroidRuntimeException(e);
+            }
+        }
+
         @Override
         public String findAddress(String addr) {
             return WebViewClassic.findAddress(addr);
@@ -1755,6 +1772,11 @@
     }
 
     @Override
+    public AccessibilityNodeProvider getAccessibilityNodeProvider() {
+      return null;
+    }
+
+    @Override
     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
         if (!mWebView.isEnabled()) {
             // Only default actions are supported while disabled.
@@ -2636,6 +2658,12 @@
         clearHelpers();
     }
 
+    @Override
+    public void evaluateJavaScript(String script, ValueCallback<String> resultCallback) {
+        // K-only API not implemented in WebViewClassic.
+        throw new IllegalStateException("This API not supported on Android 4.3 and earlier");
+    }
+
     /**
      * See {@link WebView#saveWebArchive(String)}
      */
@@ -2866,6 +2894,15 @@
     }
 
     /**
+     * See {@link WebView#createPrintDocumentAdapter()}
+     */
+    @Override
+    public PrintDocumentAdapter createPrintDocumentAdapter() {
+        // K-only API not implemented in WebViewClassic.
+        throw new IllegalStateException("This API not supported on Android 4.3 and earlier");
+    }
+
+    /**
      * See {@link WebView#getScale()}
      */
     @Override
@@ -7912,6 +7949,7 @@
             // triggered in setNewPicture
             Picture picture = mContext.getApplicationInfo().targetSdkVersion <
                     Build.VERSION_CODES.JELLY_BEAN_MR2 ? capturePicture() : null;
+            if (DebugFlags.TRACE_CALLBACK) Log.d(CallbackProxy.LOGTAG, "onNewPicture");
             mPictureListener.onNewPicture(getWebView(), picture);
         }
     }
@@ -7999,6 +8037,7 @@
                 // triggered in pageSwapCallback
                 Picture picture = mContext.getApplicationInfo().targetSdkVersion <
                         Build.VERSION_CODES.JELLY_BEAN_MR2 ? capturePicture() : null;
+                if (DebugFlags.TRACE_CALLBACK) Log.d(CallbackProxy.LOGTAG, "onNewPicture");
                 mPictureListener.onNewPicture(getWebView(), picture);
             }
         }
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index 00d87bd..0fd4e33 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -19,37 +19,86 @@
 import android.os.Build;
 import android.os.StrictMode;
 import android.os.SystemProperties;
+import android.util.AndroidRuntimeException;
 import android.util.Log;
 
-import dalvik.system.PathClassLoader;
-
 /**
  * Top level factory, used creating all the main WebView implementation classes.
  *
  * @hide
  */
 public final class WebViewFactory {
-    public static final String WEBVIEW_EXPERIMENTAL_PROPERTY = "persist.sys.webview.exp";
-    private static final String DEPRECATED_CHROMIUM_PROPERTY = "webview.use_chromium";
+    private static final boolean DEFAULT_TO_EXPERIMENTAL_WEBVIEW = true;
+    // REMEMBER: property names must be <= 31 chars total.
+    private static final String EXPERIMENTAL_PROPERTY_DEFAULT_OFF = "persist.sys.webview.exp";
+    private static final String EXPERIMENTAL_PROPERTY_DEFAULT_ON =
+            "persist.sys.webview." + Build.ID;
+
+    // Modify the persisted property name when the new webview is on-by-default, so that any user
+    // setting override only lives as long as that build.
+    private static final String LONG_PROPERTY_NAME = DEFAULT_TO_EXPERIMENTAL_WEBVIEW ?
+            EXPERIMENTAL_PROPERTY_DEFAULT_ON : EXPERIMENTAL_PROPERTY_DEFAULT_OFF;
+    private static final String WEBVIEW_EXPERIMENTAL_PROPERTY =
+            LONG_PROPERTY_NAME.length() > SystemProperties.PROP_NAME_MAX ?
+            LONG_PROPERTY_NAME.substring(0, SystemProperties.PROP_NAME_MAX) : LONG_PROPERTY_NAME;
+
+    private static final String FORCE_PROVIDER_PROPERTY = "webview.force_provider";
+    private static final String FORCE_PROVIDER_PROPERTY_VALUE_CHROMIUM = "chromium";
+    private static final String FORCE_PROVIDER_PROPERTY_VALUE_CLASSIC = "classic";
 
     // Default Provider factory class name.
     // TODO: When the Chromium powered WebView is ready, it should be the default factory class.
     private static final String DEFAULT_WEBVIEW_FACTORY = "android.webkit.WebViewClassic$Factory";
     private static final String CHROMIUM_WEBVIEW_FACTORY =
             "com.android.webview.chromium.WebViewChromiumFactoryProvider";
-    private static final String CHROMIUM_WEBVIEW_JAR = "/system/framework/webviewchromium.jar";
 
     private static final String LOGTAG = "WebViewFactory";
 
     private static final boolean DEBUG = false;
 
+    private static class Preloader {
+        static WebViewFactoryProvider sPreloadedProvider;
+        static {
+            try {
+                sPreloadedProvider = getFactoryClass().newInstance();
+            } catch (Exception e) {
+                Log.w(LOGTAG, "error preloading provider", e);
+            }
+        }
+    }
+
     // Cache the factory both for efficiency, and ensure any one process gets all webviews from the
     // same provider.
     private static WebViewFactoryProvider sProviderInstance;
     private static final Object sProviderLock = new Object();
 
     public static boolean isExperimentalWebViewAvailable() {
-        return Build.IS_DEBUGGABLE && (new java.io.File(CHROMIUM_WEBVIEW_JAR).exists());
+        try {
+            // Pass false so we don't initialize the class at this point, as this will be wasted if
+            // it's not enabled.
+            Class.forName(CHROMIUM_WEBVIEW_FACTORY, false, WebViewFactory.class.getClassLoader());
+            return true;
+        } catch (ClassNotFoundException e) {
+            return false;
+        }
+    }
+
+    /** @hide */
+    public static void setUseExperimentalWebView(boolean enable) {
+        SystemProperties.set(WEBVIEW_EXPERIMENTAL_PROPERTY, enable ? "true" : "false");
+        Log.i(LOGTAG, "Use Experimental WebView changed: "
+                + SystemProperties.get(WebViewFactory.WEBVIEW_EXPERIMENTAL_PROPERTY, ""));
+    }
+
+    /** @hide */
+    public static boolean useExperimentalWebView() {
+        return SystemProperties.getBoolean(WEBVIEW_EXPERIMENTAL_PROPERTY,
+            DEFAULT_TO_EXPERIMENTAL_WEBVIEW);
+    }
+
+    /** @hide */
+    public static boolean isUseExperimentalWebViewSet() {
+        return !SystemProperties.get(WEBVIEW_EXPERIMENTAL_PROPERTY).isEmpty();
     }
 
     static WebViewFactoryProvider getProvider() {
@@ -58,66 +107,57 @@
             // us honest and minimize usage of WebViewClassic internals when binding the proxy.
             if (sProviderInstance != null) return sProviderInstance;
 
-            if (isExperimentalWebViewEnabled()) {
-                StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
-                try {
-                    sProviderInstance = loadChromiumProvider();
-                    if (DEBUG) Log.v(LOGTAG, "Loaded Chromium provider: " + sProviderInstance);
-                } finally {
-                    StrictMode.setThreadPolicy(oldPolicy);
-                }
+            Class<WebViewFactoryProvider> providerClass;
+            try {
+                providerClass = getFactoryClass();
+            } catch (ClassNotFoundException e) {
+                Log.e(LOGTAG, "error loading provider", e);
+                throw new AndroidRuntimeException(e);
             }
 
-            if (sProviderInstance == null) {
-                if (DEBUG) Log.v(LOGTAG, "Falling back to default provider: "
-                        + DEFAULT_WEBVIEW_FACTORY);
-                sProviderInstance = getFactoryByName(DEFAULT_WEBVIEW_FACTORY,
-                        WebViewFactory.class.getClassLoader());
-                if (sProviderInstance == null) {
-                    if (DEBUG) Log.v(LOGTAG, "Falling back to explicit linkage");
-                    sProviderInstance = new WebViewClassic.Factory();
-                }
+            // This implicitly loads Preloader even if it wasn't preloaded at boot.
+            if (Preloader.sPreloadedProvider != null &&
+                Preloader.sPreloadedProvider.getClass() == providerClass) {
+                sProviderInstance = Preloader.sPreloadedProvider;
+                if (DEBUG) Log.v(LOGTAG, "Using preloaded provider: " + sProviderInstance);
+                return sProviderInstance;
             }
-            return sProviderInstance;
+
+            // The preloaded provider isn't the one we wanted; construct our own.
+            StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
+            try {
+                sProviderInstance = providerClass.newInstance();
+                if (DEBUG) Log.v(LOGTAG, "Loaded provider: " + sProviderInstance);
+                return sProviderInstance;
+            } catch (Exception e) {
+                Log.e(LOGTAG, "error instantiating provider", e);
+                throw new AndroidRuntimeException(e);
+            } finally {
+                StrictMode.setThreadPolicy(oldPolicy);
+            }
         }
     }
 
-    // For debug builds, we allow a system property to specify that we should use the
-    // experimtanl Chromium powered WebView. This enables us to switch between
-    // implementations at runtime. For user (release) builds, don't allow this.
+    // We allow a system property to specify that we should use the experimental Chromium powered
+    // WebView. This enables us to switch between implementations at runtime.
     private static boolean isExperimentalWebViewEnabled() {
-        if (!isExperimentalWebViewAvailable())
-            return false;
-        if (SystemProperties.getBoolean(DEPRECATED_CHROMIUM_PROPERTY, false)) {
-            Log.w(LOGTAG, String.format("The property %s has been deprecated. Please use %s.",
-                    DEPRECATED_CHROMIUM_PROPERTY, WEBVIEW_EXPERIMENTAL_PROPERTY));
-            return true;
-        }
-        return SystemProperties.getBoolean(WEBVIEW_EXPERIMENTAL_PROPERTY, false);
+        if (!isExperimentalWebViewAvailable()) return false;
+        String forceProviderName = SystemProperties.get(FORCE_PROVIDER_PROPERTY);
+        if (forceProviderName.isEmpty()) return useExperimentalWebView();
+
+        Log.i(LOGTAG, String.format("Provider overridden by property: %s=%s",
+                FORCE_PROVIDER_PROPERTY, forceProviderName));
+        if (forceProviderName.equals(FORCE_PROVIDER_PROPERTY_VALUE_CHROMIUM)) return true;
+        if (forceProviderName.equals(FORCE_PROVIDER_PROPERTY_VALUE_CLASSIC)) return false;
+        Log.e(LOGTAG, String.format("Unrecognized provider: %s", forceProviderName));
+        return useExperimentalWebView();
     }
 
-    // TODO: This allows us to have the legacy and Chromium WebView coexist for development
-    // and side-by-side testing. After transition, remove this when no longer required.
-    private static WebViewFactoryProvider loadChromiumProvider() {
-        ClassLoader clazzLoader = new PathClassLoader(CHROMIUM_WEBVIEW_JAR, null,
-                WebViewFactory.class.getClassLoader());
-        return getFactoryByName(CHROMIUM_WEBVIEW_FACTORY, clazzLoader);
-    }
-
-    private static WebViewFactoryProvider getFactoryByName(String providerName,
-            ClassLoader loader) {
-        try {
-            if (DEBUG) Log.v(LOGTAG, "attempt to load class " + providerName);
-            Class<?> c = Class.forName(providerName, true, loader);
-            if (DEBUG) Log.v(LOGTAG, "instantiating factory");
-            return (WebViewFactoryProvider) c.newInstance();
-        } catch (ClassNotFoundException e) {
-            Log.e(LOGTAG, "error loading " + providerName, e);
-        } catch (IllegalAccessException e) {
-            Log.e(LOGTAG, "error loading " + providerName, e);
-        } catch (InstantiationException e) {
-            Log.e(LOGTAG, "error loading " + providerName, e);
+    private static Class<WebViewFactoryProvider> getFactoryClass() throws ClassNotFoundException {
+        if (isExperimentalWebViewEnabled()) {
+            return (Class<WebViewFactoryProvider>) Class.forName(CHROMIUM_WEBVIEW_FACTORY);
+        } else  {
+            return (Class<WebViewFactoryProvider>) Class.forName(DEFAULT_WEBVIEW_FACTORY);
         }
-        return null;
     }
 }
diff --git a/core/java/android/webkit/WebViewProvider.java b/core/java/android/webkit/WebViewProvider.java
index fa17ab9..696aad4 100644
--- a/core/java/android/webkit/WebViewProvider.java
+++ b/core/java/android/webkit/WebViewProvider.java
@@ -26,12 +26,14 @@
 import android.net.http.SslCertificate;
 import android.os.Bundle;
 import android.os.Message;
+import android.print.PrintDocumentAdapter;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup.LayoutParams;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeProvider;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
 import android.webkit.WebView.HitTestResult;
@@ -113,6 +115,8 @@
     public void loadDataWithBaseURL(String baseUrl, String data,
             String mimeType, String encoding, String historyUrl);
 
+    public void evaluateJavaScript(String script, ValueCallback<String> resultCallback);
+
     public void saveWebArchive(String filename);
 
     public void saveWebArchive(String basename, boolean autoname, ValueCallback<String> callback);
@@ -143,6 +147,8 @@
 
     public Picture capturePicture();
 
+    public PrintDocumentAdapter createPrintDocumentAdapter();
+
     public float getScale();
 
     public void setInitialScale(int scaleInPercent);
@@ -279,6 +285,8 @@
     interface ViewDelegate {
         public boolean shouldDelayChildPressedState();
 
+        public AccessibilityNodeProvider getAccessibilityNodeProvider();
+
         public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info);
 
         public void onInitializeAccessibilityEvent(AccessibilityEvent event);
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index c36ecc8..7378d74 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -25,11 +25,12 @@
 import android.graphics.drawable.TransitionDrawable;
 import android.os.Bundle;
 import android.os.Debug;
-import android.os.Handler;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.StrictMode;
+import android.os.Trace;
 import android.text.Editable;
+import android.text.InputType;
 import android.text.TextUtils;
 import android.text.TextWatcher;
 import android.util.AttributeSet;
@@ -61,9 +62,12 @@
 import android.view.animation.Interpolator;
 import android.view.animation.LinearInterpolator;
 import android.view.inputmethod.BaseInputConnection;
+import android.view.inputmethod.CompletionInfo;
+import android.view.inputmethod.CorrectionInfo;
 import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.ExtractedText;
+import android.view.inputmethod.ExtractedTextRequest;
 import android.view.inputmethod.InputConnection;
-import android.view.inputmethod.InputConnectionWrapper;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.RemoteViews.OnClickHandler;
 
@@ -219,6 +223,11 @@
     public static final int CHOICE_MODE_MULTIPLE_MODAL = 3;
 
     /**
+     * The thread that created this view.
+     */
+    private final Thread mOwnerThread;
+
+    /**
      * Controls if/how the user may choose/check items in the list
      */
     int mChoiceMode = CHOICE_MODE_NONE;
@@ -434,6 +443,11 @@
     boolean mFastScrollEnabled;
 
     /**
+     * Whether or not to always show the fast scroll feature on this list
+     */
+    boolean mFastScrollAlwaysVisible;
+
+    /**
      * Optional callback to notify client when scroll position has changed
      */
     private OnScrollListener mOnScrollListener;
@@ -752,6 +766,8 @@
         super(context);
         initAbsListView();
 
+        mOwnerThread = Thread.currentThread();
+
         setVerticalScrollBarEnabled(true);
         TypedArray a = context.obtainStyledAttributes(R.styleable.View);
         initializeScrollbars(a);
@@ -766,6 +782,8 @@
         super(context, attrs, defStyle);
         initAbsListView();
 
+        mOwnerThread = Thread.currentThread();
+
         TypedArray a = context.obtainStyledAttributes(attrs,
                 com.android.internal.R.styleable.AbsListView, defStyle, 0);
 
@@ -1151,10 +1169,10 @@
         }
         if (mChoiceMode != CHOICE_MODE_NONE) {
             if (mCheckStates == null) {
-                mCheckStates = new SparseBooleanArray();
+                mCheckStates = new SparseBooleanArray(0);
             }
             if (mCheckedIdStates == null && mAdapter != null && mAdapter.hasStableIds()) {
-                mCheckedIdStates = new LongSparseArray<Integer>();
+                mCheckedIdStates = new LongSparseArray<Integer>(0);
             }
             // Modal multi-choice mode only has choices when the mode is active. Clear them.
             if (mChoiceMode == CHOICE_MODE_MULTIPLE_MODAL) {
@@ -1193,79 +1211,135 @@
     }
 
     /**
-     * Enables fast scrolling by letting the user quickly scroll through lists by
-     * dragging the fast scroll thumb. The adapter attached to the list may want
-     * to implement {@link SectionIndexer} if it wishes to display alphabet preview and
-     * jump between sections of the list.
+     * Specifies whether fast scrolling is enabled or disabled.
+     * <p>
+     * When fast scrolling is enabled, the user can quickly scroll through lists
+     * by dragging the fast scroll thumb.
+     * <p>
+     * If the adapter backing this list implements {@link SectionIndexer}, the
+     * fast scroller will display section header previews as the user scrolls.
+     * Additionally, the user will be able to quickly jump between sections by
+     * tapping along the length of the scroll bar.
+     *
      * @see SectionIndexer
      * @see #isFastScrollEnabled()
-     * @param enabled whether or not to enable fast scrolling
+     * @param enabled true to enable fast scrolling, false otherwise
      */
-    public void setFastScrollEnabled(boolean enabled) {
-        mFastScrollEnabled = enabled;
-        if (enabled) {
-            if (mFastScroller == null) {
-                mFastScroller = new FastScroller(getContext(), this);
-            }
-        } else {
-            if (mFastScroller != null) {
-                mFastScroller.stop();
-                mFastScroller = null;
+    public void setFastScrollEnabled(final boolean enabled) {
+        if (mFastScrollEnabled != enabled) {
+            mFastScrollEnabled = enabled;
+
+            if (isOwnerThread()) {
+                setFastScrollerEnabledUiThread(enabled);
+            } else {
+                post(new Runnable() {
+                    @Override
+                    public void run() {
+                        setFastScrollerEnabledUiThread(enabled);
+                    }
+                });
             }
         }
     }
 
+    private void setFastScrollerEnabledUiThread(boolean enabled) {
+        if (mFastScroller != null) {
+            mFastScroller.setEnabled(enabled);
+        } else if (enabled) {
+            mFastScroller = new FastScroller(this);
+            mFastScroller.setEnabled(true);
+        }
+
+        resolvePadding();
+
+        if (mFastScroller != null) {
+            mFastScroller.updateLayout();
+        }
+    }
+
     /**
-     * Set whether or not the fast scroller should always be shown in place of the
-     * standard scrollbars. Fast scrollers shown in this way will not fade out and will
-     * be a permanent fixture within the list. Best combined with an inset scroll bar style
-     * that will ensure enough padding. This will enable fast scrolling if it is not
+     * Set whether or not the fast scroller should always be shown in place of
+     * the standard scroll bars. This will enable fast scrolling if it is not
      * already enabled.
+     * <p>
+     * Fast scrollers shown in this way will not fade out and will be a
+     * permanent fixture within the list. This is best combined with an inset
+     * scroll bar style to ensure the scroll bar does not overlap content.
      *
-     * @param alwaysShow true if the fast scroller should always be displayed.
+     * @param alwaysShow true if the fast scroller should always be displayed,
+     *            false otherwise
      * @see #setScrollBarStyle(int)
      * @see #setFastScrollEnabled(boolean)
      */
-    public void setFastScrollAlwaysVisible(boolean alwaysShow) {
-        if (alwaysShow && !mFastScrollEnabled) {
-            setFastScrollEnabled(true);
-        }
+    public void setFastScrollAlwaysVisible(final boolean alwaysShow) {
+        if (mFastScrollAlwaysVisible != alwaysShow) {
+            if (alwaysShow && !mFastScrollEnabled) {
+                setFastScrollEnabled(true);
+            }
 
+            mFastScrollAlwaysVisible = alwaysShow;
+
+            if (isOwnerThread()) {
+                setFastScrollerAlwaysVisibleUiThread(alwaysShow);
+            } else {
+                post(new Runnable() {
+                    @Override
+                    public void run() {
+                        setFastScrollerAlwaysVisibleUiThread(alwaysShow);
+                    }
+                });
+            }
+        }
+    }
+
+    private void setFastScrollerAlwaysVisibleUiThread(boolean alwaysShow) {
         if (mFastScroller != null) {
             mFastScroller.setAlwaysShow(alwaysShow);
         }
-
-        computeOpaqueFlags();
-        recomputePadding();
     }
 
     /**
-     * Returns true if the fast scroller is set to always show on this view rather than
-     * fade out when not in use.
+     * @return whether the current thread is the one that created the view
+     */
+    private boolean isOwnerThread() {
+        return mOwnerThread == Thread.currentThread();
+    }
+
+    /**
+     * Returns true if the fast scroller is set to always show on this view.
      *
-     * @return true if the fast scroller will always show.
+     * @return true if the fast scroller will always show
      * @see #setFastScrollAlwaysVisible(boolean)
      */
     public boolean isFastScrollAlwaysVisible() {
-        return mFastScrollEnabled && mFastScroller.isAlwaysShowEnabled();
+        if (mFastScroller == null) {
+            return mFastScrollEnabled && mFastScrollAlwaysVisible;
+        } else {
+            return mFastScroller.isEnabled() && mFastScroller.isAlwaysShowEnabled();
+        }
     }
 
     @Override
     public int getVerticalScrollbarWidth() {
-        if (isFastScrollAlwaysVisible()) {
+        if (mFastScroller != null && mFastScroller.isEnabled()) {
             return Math.max(super.getVerticalScrollbarWidth(), mFastScroller.getWidth());
         }
         return super.getVerticalScrollbarWidth();
     }
 
     /**
-     * Returns the current state of the fast scroll feature.
+     * Returns true if the fast scroller is enabled.
+     *
      * @see #setFastScrollEnabled(boolean)
      * @return true if fast scroll is enabled, false otherwise
      */
     @ViewDebug.ExportedProperty
     public boolean isFastScrollEnabled() {
-        return mFastScrollEnabled;
+        if (mFastScroller == null) {
+            return mFastScrollEnabled;
+        } else {
+            return mFastScroller.isEnabled();
+        }
     }
 
     @Override
@@ -1276,13 +1350,21 @@
         }
     }
 
+    @Override
+    public void setScrollBarStyle(int style) {
+        super.setScrollBarStyle(style);
+        if (mFastScroller != null) {
+            mFastScroller.setScrollBarStyle(style);
+        }
+    }
+
     /**
-     * If fast scroll is visible, then don't draw the vertical scrollbar.
+     * If fast scroll is enabled, then don't draw the vertical scrollbar.
      * @hide
      */
     @Override
     protected boolean isVerticalScrollBarHidden() {
-        return mFastScroller != null && mFastScroller.isVisible();
+        return isFastScrollEnabled();
     }
 
     /**
@@ -1334,7 +1416,7 @@
      */
     void invokeOnItemScrollListener() {
         if (mFastScroller != null) {
-            mFastScroller.onScroll(this, mFirstPosition, getChildCount(), mItemCount);
+            mFastScroller.onScroll(mFirstPosition, getChildCount(), mItemCount);
         }
         if (mOnScrollListener != null) {
             mOnScrollListener.onScroll(this, mFirstPosition, getChildCount(), mItemCount);
@@ -1615,10 +1697,12 @@
 
         public static final Parcelable.Creator<SavedState> CREATOR
                 = new Parcelable.Creator<SavedState>() {
+            @Override
             public SavedState createFromParcel(Parcel in) {
                 return new SavedState(in);
             }
 
+            @Override
             public SavedState[] newArray(int size) {
                 return new SavedState[size];
             }
@@ -1943,8 +2027,8 @@
             }
 
             final int top = getChildAt(0).getTop();
-            final float fadeLength = (float) getVerticalFadingEdgeLength();
-            return top < mPaddingTop ? (float) -(top - mPaddingTop) / fadeLength : fadeEdge;
+            final float fadeLength = getVerticalFadingEdgeLength();
+            return top < mPaddingTop ? -(top - mPaddingTop) / fadeLength : fadeEdge;
         }
     }
 
@@ -1961,9 +2045,9 @@
 
             final int bottom = getChildAt(count - 1).getBottom();
             final int height = getHeight();
-            final float fadeLength = (float) getVerticalFadingEdgeLength();
+            final float fadeLength = getVerticalFadingEdgeLength();
             return bottom > height - mPaddingBottom ?
-                    (float) (bottom - height + mPaddingBottom) / fadeLength : fadeEdge;
+                    (bottom - height + mPaddingBottom) / fadeLength : fadeEdge;
         }
     }
 
@@ -2004,7 +2088,7 @@
             }
             mRecycler.markChildrenDirty();
         }
-        
+
         if (mFastScroller != null && mItemCount != mOldItemCount) {
             mFastScroller.onItemCountChanged(mOldItemCount, mItemCount);
         }
@@ -2146,6 +2230,8 @@
      * @return A view displaying the data associated with the specified position
      */
     View obtainView(int position, boolean[] isScrap) {
+        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "obtainView");
+
         isScrap[0] = false;
         View scrapView;
 
@@ -2208,6 +2294,8 @@
             }
         }
 
+        Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+
         return child;
     }
 
@@ -2229,33 +2317,7 @@
             super.onInitializeAccessibilityNodeInfo(host, info);
 
             final int position = getPositionForView(host);
-            final ListAdapter adapter = getAdapter();
-
-            if ((position == INVALID_POSITION) || (adapter == null)) {
-                return;
-            }
-
-            if (!isEnabled() || !adapter.isEnabled(position)) {
-                return;
-            }
-
-            if (position == getSelectedItemPosition()) {
-                info.setSelected(true);
-                info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_SELECTION);
-            } else {
-                info.addAction(AccessibilityNodeInfo.ACTION_SELECT);
-            }
-
-            if (isClickable()) {
-                info.addAction(AccessibilityNodeInfo.ACTION_CLICK);
-                info.setClickable(true);
-            }
-
-            if (isLongClickable()) {
-                info.addAction(AccessibilityNodeInfo.ACTION_LONG_CLICK);
-                info.setLongClickable(true);
-            }
-
+            onInitializeAccessibilityNodeInfoForItem(host, position, info);
         }
 
         @Override
@@ -2308,6 +2370,45 @@
         }
     }
 
+    /**
+     * Initializes an {@link AccessibilityNodeInfo} with information about a
+     * particular item in the list.
+     *
+     * @param view View representing the list item.
+     * @param position Position of the list item within the adapter.
+     * @param info Node info to populate.
+     */
+    public void onInitializeAccessibilityNodeInfoForItem(
+            View view, int position, AccessibilityNodeInfo info) {
+        final ListAdapter adapter = getAdapter();
+        if (position == INVALID_POSITION || adapter == null) {
+            // The item doesn't exist, so there's not much we can do here.
+            return;
+        }
+
+        if (!isEnabled() || !adapter.isEnabled(position)) {
+            info.setEnabled(false);
+            return;
+        }
+
+        if (position == getSelectedItemPosition()) {
+            info.setSelected(true);
+            info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_SELECTION);
+        } else {
+            info.addAction(AccessibilityNodeInfo.ACTION_SELECT);
+        }
+
+        if (isClickable()) {
+            info.addAction(AccessibilityNodeInfo.ACTION_CLICK);
+            info.setClickable(true);
+        }
+
+        if (isLongClickable()) {
+            info.addAction(AccessibilityNodeInfo.ACTION_LONG_CLICK);
+            info.setLongClickable(true);
+        }
+    }
+
     void positionSelector(int position, View sel) {
         if (position != INVALID_POSITION) {
             mSelectorPosition = position;
@@ -2426,7 +2527,7 @@
      * @return True if the selector should be shown
      */
     boolean shouldShowSelector() {
-        return (hasFocus() && !isInTouchMode()) || touchModeDrawsInPressedState();
+        return (!isInTouchMode()) || (touchModeDrawsInPressedState() && isPressed());
     }
 
     private void drawSelector(Canvas canvas) {
@@ -2730,7 +2831,6 @@
     @Override
     public void onRtlPropertiesChanged(int layoutDirection) {
         super.onRtlPropertiesChanged(layoutDirection);
-
         if (mFastScroller != null) {
            mFastScroller.setScrollbarPosition(getVerticalScrollbarPosition());
         }
@@ -2751,6 +2851,23 @@
         return new AdapterContextMenuInfo(view, position, id);
     }
 
+    @Override
+    public void onCancelPendingInputEvents() {
+        super.onCancelPendingInputEvents();
+        if (mPerformClick != null) {
+            removeCallbacks(mPerformClick);
+        }
+        if (mPendingCheckForTap != null) {
+            removeCallbacks(mPendingCheckForTap);
+        }
+        if (mPendingCheckForLongPress != null) {
+            removeCallbacks(mPendingCheckForLongPress);
+        }
+        if (mPendingCheckForKeyLongPress != null) {
+            removeCallbacks(mPendingCheckForKeyLongPress);
+        }
+    }
+
     /**
      * A base class for Runnables that will check that their view is still attached to
      * the original window as when the Runnable was created.
@@ -2764,13 +2881,14 @@
         }
 
         public boolean sameWindow() {
-            return hasWindowFocus() && getWindowAttachCount() == mOriginalAttachCount;
+            return getWindowAttachCount() == mOriginalAttachCount;
         }
     }
 
     private class PerformClick extends WindowRunnnable implements Runnable {
         int mClickMotionPosition;
 
+        @Override
         public void run() {
             // The data has changed since we posted this action in the event queue,
             // bail out before bad things happen
@@ -2792,6 +2910,7 @@
     }
 
     private class CheckForLongPress extends WindowRunnnable implements Runnable {
+        @Override
         public void run() {
             final int motionPosition = mMotionPosition;
             final View child = getChildAt(motionPosition - mFirstPosition);
@@ -2815,6 +2934,7 @@
     }
 
     private class CheckForKeyLongPress extends WindowRunnnable implements Runnable {
+        @Override
         public void run() {
             if (isPressed() && mSelectedPosition >= 0) {
                 int index = mSelectedPosition - mFirstPosition;
@@ -2914,9 +3034,7 @@
 
     @Override
     public boolean onKeyUp(int keyCode, KeyEvent event) {
-        switch (keyCode) {
-        case KeyEvent.KEYCODE_DPAD_CENTER:
-        case KeyEvent.KEYCODE_ENTER:
+        if (KeyEvent.isConfirmKey(keyCode)) {
             if (!isEnabled()) {
                 return true;
             }
@@ -2932,7 +3050,6 @@
                 setPressed(false);
                 return true;
             }
-            break;
         }
         return super.onKeyUp(keyCode, event);
     }
@@ -2989,6 +3106,7 @@
     }
 
     final class CheckForTap implements Runnable {
+        @Override
         public void run() {
             if (mTouchMode == TOUCH_MODE_DOWN) {
                 mTouchMode = TOUCH_MODE_TAP;
@@ -3049,15 +3167,9 @@
                 mTouchMode = TOUCH_MODE_SCROLL;
                 mMotionCorrection = deltaY > 0 ? mTouchSlop : -mTouchSlop;
             }
-            final Handler handler = getHandler();
-            // Handler should not be null unless the AbsListView is not attached to a
-            // window, which would make it very hard to scroll it... but the monkeys
-            // say it's possible.
-            if (handler != null) {
-                handler.removeCallbacks(mPendingCheckForLongPress);
-            }
+            removeCallbacks(mPendingCheckForLongPress);
             setPressed(false);
-            View motionView = getChildAt(mMotionPosition - mFirstPosition);
+            final View motionView = getChildAt(mMotionPosition - mFirstPosition);
             if (motionView != null) {
                 motionView.setPressed(false);
             }
@@ -3239,6 +3351,7 @@
         }
     }
 
+    @Override
     public void onTouchModeChanged(boolean isInTouchMode) {
         if (isInTouchMode) {
             // Get rid of the selection when we enter touch mode
@@ -3299,126 +3412,193 @@
             }
         }
 
-        final int action = ev.getAction();
-
-        View v;
-
         initVelocityTrackerIfNotExists();
         mVelocityTracker.addMovement(ev);
 
-        switch (action & MotionEvent.ACTION_MASK) {
-        case MotionEvent.ACTION_DOWN: {
-            switch (mTouchMode) {
-            case TOUCH_MODE_OVERFLING: {
-                mFlingRunnable.endFling();
-                if (mPositionScroller != null) {
-                    mPositionScroller.stop();
-                }
-                mTouchMode = TOUCH_MODE_OVERSCROLL;
-                mMotionX = (int) ev.getX();
-                mMotionY = mLastY = (int) ev.getY();
-                mMotionCorrection = 0;
-                mActivePointerId = ev.getPointerId(0);
-                mDirection = 0;
+        final int actionMasked = ev.getActionMasked();
+        switch (actionMasked) {
+            case MotionEvent.ACTION_DOWN: {
+                onTouchDown(ev);
                 break;
             }
 
-            default: {
-                mActivePointerId = ev.getPointerId(0);
-                final int x = (int) ev.getX();
-                final int y = (int) ev.getY();
-                int motionPosition = pointToPosition(x, y);
-                if (!mDataChanged) {
-                    if ((mTouchMode != TOUCH_MODE_FLING) && (motionPosition >= 0)
-                            && (getAdapter().isEnabled(motionPosition))) {
-                        // User clicked on an actual view (and was not stopping a fling).
-                        // It might be a click or a scroll. Assume it is a click until
-                        // proven otherwise
-                        mTouchMode = TOUCH_MODE_DOWN;
-                        // FIXME Debounce
-                        if (mPendingCheckForTap == null) {
-                            mPendingCheckForTap = new CheckForTap();
-                        }
-                        postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());
-                    } else {
-                        if (mTouchMode == TOUCH_MODE_FLING) {
-                            // Stopped a fling. It is a scroll.
-                            createScrollingCache();
-                            mTouchMode = TOUCH_MODE_SCROLL;
-                            mMotionCorrection = 0;
-                            motionPosition = findMotionRow(y);
-                            mFlingRunnable.flywheelTouch();
-                        }
-                    }
-                }
+            case MotionEvent.ACTION_MOVE: {
+                onTouchMove(ev);
+                break;
+            }
 
+            case MotionEvent.ACTION_UP: {
+                onTouchUp(ev);
+                break;
+            }
+
+            case MotionEvent.ACTION_CANCEL: {
+                onTouchCancel();
+                break;
+            }
+
+            case MotionEvent.ACTION_POINTER_UP: {
+                onSecondaryPointerUp(ev);
+                final int x = mMotionX;
+                final int y = mMotionY;
+                final int motionPosition = pointToPosition(x, y);
                 if (motionPosition >= 0) {
                     // Remember where the motion event started
-                    v = getChildAt(motionPosition - mFirstPosition);
-                    mMotionViewOriginalTop = v.getTop();
+                    final View child = getChildAt(motionPosition - mFirstPosition);
+                    mMotionViewOriginalTop = child.getTop();
+                    mMotionPosition = motionPosition;
                 }
-                mMotionX = x;
-                mMotionY = y;
-                mMotionPosition = motionPosition;
-                mLastY = Integer.MIN_VALUE;
+                mLastY = y;
                 break;
             }
-            }
 
-            if (performButtonActionOnTouchDown(ev)) {
-                if (mTouchMode == TOUCH_MODE_DOWN) {
-                    removeCallbacks(mPendingCheckForTap);
+            case MotionEvent.ACTION_POINTER_DOWN: {
+                // New pointers take over dragging duties
+                final int index = ev.getActionIndex();
+                final int id = ev.getPointerId(index);
+                final int x = (int) ev.getX(index);
+                final int y = (int) ev.getY(index);
+                mMotionCorrection = 0;
+                mActivePointerId = id;
+                mMotionX = x;
+                mMotionY = y;
+                final int motionPosition = pointToPosition(x, y);
+                if (motionPosition >= 0) {
+                    // Remember where the motion event started
+                    final View child = getChildAt(motionPosition - mFirstPosition);
+                    mMotionViewOriginalTop = child.getTop();
+                    mMotionPosition = motionPosition;
                 }
+                mLastY = y;
+                break;
             }
-            break;
         }
 
-        case MotionEvent.ACTION_MOVE: {
-            int pointerIndex = ev.findPointerIndex(mActivePointerId);
-            if (pointerIndex == -1) {
-                pointerIndex = 0;
-                mActivePointerId = ev.getPointerId(pointerIndex);
-            }
-            final int y = (int) ev.getY(pointerIndex);
+        return true;
+    }
 
-            if (mDataChanged) {
-                // Re-sync everything if data has been changed
-                // since the scroll operation can query the adapter.
-                layoutChildren();
+    private void onTouchDown(MotionEvent ev) {
+        mActivePointerId = ev.getPointerId(0);
+
+        if (mTouchMode == TOUCH_MODE_OVERFLING) {
+            // Stopped the fling. It is a scroll.
+            mFlingRunnable.endFling();
+            if (mPositionScroller != null) {
+                mPositionScroller.stop();
+            }
+            mTouchMode = TOUCH_MODE_OVERSCROLL;
+            mMotionX = (int) ev.getX();
+            mMotionY = (int) ev.getY();
+            mLastY = mMotionY;
+            mMotionCorrection = 0;
+            mDirection = 0;
+        } else {
+            final int x = (int) ev.getX();
+            final int y = (int) ev.getY();
+            int motionPosition = pointToPosition(x, y);
+
+            if (!mDataChanged) {
+                if (mTouchMode == TOUCH_MODE_FLING) {
+                    // Stopped a fling. It is a scroll.
+                    createScrollingCache();
+                    mTouchMode = TOUCH_MODE_SCROLL;
+                    mMotionCorrection = 0;
+                    motionPosition = findMotionRow(y);
+                    mFlingRunnable.flywheelTouch();
+                } else if ((motionPosition >= 0) && getAdapter().isEnabled(motionPosition)) {
+                    // User clicked on an actual view (and was not stopping a
+                    // fling). It might be a click or a scroll. Assume it is a
+                    // click until proven otherwise.
+                    mTouchMode = TOUCH_MODE_DOWN;
+
+                    // FIXME Debounce
+                    if (mPendingCheckForTap == null) {
+                        mPendingCheckForTap = new CheckForTap();
+                    }
+
+                    postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());
+                }
             }
 
-            switch (mTouchMode) {
+            if (motionPosition >= 0) {
+                // Remember where the motion event started
+                final View v = getChildAt(motionPosition - mFirstPosition);
+                mMotionViewOriginalTop = v.getTop();
+            }
+
+            mMotionX = x;
+            mMotionY = y;
+            mMotionPosition = motionPosition;
+            mLastY = Integer.MIN_VALUE;
+        }
+
+        if (mTouchMode == TOUCH_MODE_DOWN && mMotionPosition != INVALID_POSITION
+                && performButtonActionOnTouchDown(ev)) {
+            removeCallbacks(mPendingCheckForTap);
+        }
+    }
+
+    private void onTouchMove(MotionEvent ev) {
+        int pointerIndex = ev.findPointerIndex(mActivePointerId);
+        if (pointerIndex == -1) {
+            pointerIndex = 0;
+            mActivePointerId = ev.getPointerId(pointerIndex);
+        }
+
+        if (mDataChanged) {
+            // Re-sync everything if data has been changed
+            // since the scroll operation can query the adapter.
+            layoutChildren();
+        }
+
+        final int y = (int) ev.getY(pointerIndex);
+
+        switch (mTouchMode) {
             case TOUCH_MODE_DOWN:
             case TOUCH_MODE_TAP:
             case TOUCH_MODE_DONE_WAITING:
                 // Check if we have moved far enough that it looks more like a
-                // scroll than a tap
-                startScrollIfNeeded(y);
+                // scroll than a tap. If so, we'll enter scrolling mode.
+                if (startScrollIfNeeded(y)) {
+                    break;
+                }
+                // Otherwise, check containment within list bounds. If we're
+                // outside bounds, cancel any active presses.
+                final float x = ev.getX(pointerIndex);
+                if (!pointInView(x, y, mTouchSlop)) {
+                    setPressed(false);
+                    final View motionView = getChildAt(mMotionPosition - mFirstPosition);
+                    if (motionView != null) {
+                        motionView.setPressed(false);
+                    }
+                    removeCallbacks(mTouchMode == TOUCH_MODE_DOWN ?
+                            mPendingCheckForTap : mPendingCheckForLongPress);
+                    mTouchMode = TOUCH_MODE_DONE_WAITING;
+                    updateSelectorState();
+                }
                 break;
             case TOUCH_MODE_SCROLL:
             case TOUCH_MODE_OVERSCROLL:
                 scrollIfNeeded(y);
                 break;
-            }
-            break;
         }
+    }
 
-        case MotionEvent.ACTION_UP: {
-            switch (mTouchMode) {
-            case TOUCH_MODE_DOWN:
-            case TOUCH_MODE_TAP:
-            case TOUCH_MODE_DONE_WAITING:
-                final int motionPosition = mMotionPosition;
-                final View child = getChildAt(motionPosition - mFirstPosition);
+    private void onTouchUp(MotionEvent ev) {
+        switch (mTouchMode) {
+        case TOUCH_MODE_DOWN:
+        case TOUCH_MODE_TAP:
+        case TOUCH_MODE_DONE_WAITING:
+            final int motionPosition = mMotionPosition;
+            final View child = getChildAt(motionPosition - mFirstPosition);
+            if (child != null) {
+                if (mTouchMode != TOUCH_MODE_DOWN) {
+                    child.setPressed(false);
+                }
 
                 final float x = ev.getX();
                 final boolean inList = x > mListPadding.left && x < getWidth() - mListPadding.right;
-
-                if (child != null && !child.hasFocusable() && inList) {
-                    if (mTouchMode != TOUCH_MODE_DOWN) {
-                        child.setPressed(false);
-                    }
-
+                if (inList && !child.hasFocusable()) {
                     if (mPerformClick == null) {
                         mPerformClick = new PerformClick();
                     }
@@ -3430,11 +3610,8 @@
                     mResurrectToPosition = motionPosition;
 
                     if (mTouchMode == TOUCH_MODE_DOWN || mTouchMode == TOUCH_MODE_TAP) {
-                        final Handler handler = getHandler();
-                        if (handler != null) {
-                            handler.removeCallbacks(mTouchMode == TOUCH_MODE_DOWN ?
-                                    mPendingCheckForTap : mPendingCheckForLongPress);
-                        }
+                        removeCallbacks(mTouchMode == TOUCH_MODE_DOWN ?
+                                mPendingCheckForTap : mPendingCheckForLongPress);
                         mLayoutMode = LAYOUT_NORMAL;
                         if (!mDataChanged && mAdapter.isEnabled(motionPosition)) {
                             mTouchMode = TOUCH_MODE_TAP;
@@ -3470,191 +3647,140 @@
                             mTouchMode = TOUCH_MODE_REST;
                             updateSelectorState();
                         }
-                        return true;
+                        return;
                     } else if (!mDataChanged && mAdapter.isEnabled(motionPosition)) {
                         performClick.run();
                     }
                 }
-                mTouchMode = TOUCH_MODE_REST;
-                updateSelectorState();
-                break;
-            case TOUCH_MODE_SCROLL:
-                final int childCount = getChildCount();
-                if (childCount > 0) {
-                    final int firstChildTop = getChildAt(0).getTop();
-                    final int lastChildBottom = getChildAt(childCount - 1).getBottom();
-                    final int contentTop = mListPadding.top;
-                    final int contentBottom = getHeight() - mListPadding.bottom;
-                    if (mFirstPosition == 0 && firstChildTop >= contentTop &&
-                            mFirstPosition + childCount < mItemCount &&
-                            lastChildBottom <= getHeight() - contentBottom) {
-                        mTouchMode = TOUCH_MODE_REST;
-                        reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
-                    } else {
-                        final VelocityTracker velocityTracker = mVelocityTracker;
-                        velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
-
-                        final int initialVelocity = (int)
-                                (velocityTracker.getYVelocity(mActivePointerId) * mVelocityScale);
-                        // Fling if we have enough velocity and we aren't at a boundary.
-                        // Since we can potentially overfling more than we can overscroll, don't
-                        // allow the weird behavior where you can scroll to a boundary then
-                        // fling further.
-                        if (Math.abs(initialVelocity) > mMinimumVelocity &&
-                                !((mFirstPosition == 0 &&
-                                        firstChildTop == contentTop - mOverscrollDistance) ||
-                                  (mFirstPosition + childCount == mItemCount &&
-                                        lastChildBottom == contentBottom + mOverscrollDistance))) {
-                            if (mFlingRunnable == null) {
-                                mFlingRunnable = new FlingRunnable();
-                            }
-                            reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
-
-                            mFlingRunnable.start(-initialVelocity);
-                        } else {
-                            mTouchMode = TOUCH_MODE_REST;
-                            reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
-                            if (mFlingRunnable != null) {
-                                mFlingRunnable.endFling();
-                            }
-                            if (mPositionScroller != null) {
-                                mPositionScroller.stop();
-                            }
-                        }
-                    }
-                } else {
+            }
+            mTouchMode = TOUCH_MODE_REST;
+            updateSelectorState();
+            break;
+        case TOUCH_MODE_SCROLL:
+            final int childCount = getChildCount();
+            if (childCount > 0) {
+                final int firstChildTop = getChildAt(0).getTop();
+                final int lastChildBottom = getChildAt(childCount - 1).getBottom();
+                final int contentTop = mListPadding.top;
+                final int contentBottom = getHeight() - mListPadding.bottom;
+                if (mFirstPosition == 0 && firstChildTop >= contentTop &&
+                        mFirstPosition + childCount < mItemCount &&
+                        lastChildBottom <= getHeight() - contentBottom) {
                     mTouchMode = TOUCH_MODE_REST;
                     reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
-                }
-                break;
-
-            case TOUCH_MODE_OVERSCROLL:
-                if (mFlingRunnable == null) {
-                    mFlingRunnable = new FlingRunnable();
-                }
-                final VelocityTracker velocityTracker = mVelocityTracker;
-                velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
-                final int initialVelocity = (int) velocityTracker.getYVelocity(mActivePointerId);
-
-                reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
-                if (Math.abs(initialVelocity) > mMinimumVelocity) {
-                    mFlingRunnable.startOverfling(-initialVelocity);
                 } else {
-                    mFlingRunnable.startSpringback();
+                    final VelocityTracker velocityTracker = mVelocityTracker;
+                    velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
+
+                    final int initialVelocity = (int)
+                            (velocityTracker.getYVelocity(mActivePointerId) * mVelocityScale);
+                    // Fling if we have enough velocity and we aren't at a boundary.
+                    // Since we can potentially overfling more than we can overscroll, don't
+                    // allow the weird behavior where you can scroll to a boundary then
+                    // fling further.
+                    if (Math.abs(initialVelocity) > mMinimumVelocity &&
+                            !((mFirstPosition == 0 &&
+                                    firstChildTop == contentTop - mOverscrollDistance) ||
+                              (mFirstPosition + childCount == mItemCount &&
+                                    lastChildBottom == contentBottom + mOverscrollDistance))) {
+                        if (mFlingRunnable == null) {
+                            mFlingRunnable = new FlingRunnable();
+                        }
+                        reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
+
+                        mFlingRunnable.start(-initialVelocity);
+                    } else {
+                        mTouchMode = TOUCH_MODE_REST;
+                        reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
+                        if (mFlingRunnable != null) {
+                            mFlingRunnable.endFling();
+                        }
+                        if (mPositionScroller != null) {
+                            mPositionScroller.stop();
+                        }
+                    }
                 }
-
-                break;
-            }
-
-            setPressed(false);
-
-            if (mEdgeGlowTop != null) {
-                mEdgeGlowTop.onRelease();
-                mEdgeGlowBottom.onRelease();
-            }
-
-            // Need to redraw since we probably aren't drawing the selector anymore
-            invalidate();
-
-            final Handler handler = getHandler();
-            if (handler != null) {
-                handler.removeCallbacks(mPendingCheckForLongPress);
-            }
-
-            recycleVelocityTracker();
-
-            mActivePointerId = INVALID_POINTER;
-
-            if (PROFILE_SCROLLING) {
-                if (mScrollProfilingStarted) {
-                    Debug.stopMethodTracing();
-                    mScrollProfilingStarted = false;
-                }
-            }
-
-            if (mScrollStrictSpan != null) {
-                mScrollStrictSpan.finish();
-                mScrollStrictSpan = null;
-            }
-            break;
-        }
-
-        case MotionEvent.ACTION_CANCEL: {
-            switch (mTouchMode) {
-            case TOUCH_MODE_OVERSCROLL:
-                if (mFlingRunnable == null) {
-                    mFlingRunnable = new FlingRunnable();
-                }
-                mFlingRunnable.startSpringback();
-                break;
-
-            case TOUCH_MODE_OVERFLING:
-                // Do nothing - let it play out.
-                break;
-
-            default:
+            } else {
                 mTouchMode = TOUCH_MODE_REST;
-                setPressed(false);
-                View motionView = this.getChildAt(mMotionPosition - mFirstPosition);
-                if (motionView != null) {
-                    motionView.setPressed(false);
-                }
-                clearScrollingCache();
+                reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
+            }
+            break;
 
-                final Handler handler = getHandler();
-                if (handler != null) {
-                    handler.removeCallbacks(mPendingCheckForLongPress);
-                }
+        case TOUCH_MODE_OVERSCROLL:
+            if (mFlingRunnable == null) {
+                mFlingRunnable = new FlingRunnable();
+            }
+            final VelocityTracker velocityTracker = mVelocityTracker;
+            velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
+            final int initialVelocity = (int) velocityTracker.getYVelocity(mActivePointerId);
 
-                recycleVelocityTracker();
+            reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
+            if (Math.abs(initialVelocity) > mMinimumVelocity) {
+                mFlingRunnable.startOverfling(-initialVelocity);
+            } else {
+                mFlingRunnable.startSpringback();
             }
 
-            if (mEdgeGlowTop != null) {
-                mEdgeGlowTop.onRelease();
-                mEdgeGlowBottom.onRelease();
-            }
-            mActivePointerId = INVALID_POINTER;
             break;
         }
 
-        case MotionEvent.ACTION_POINTER_UP: {
-            onSecondaryPointerUp(ev);
-            final int x = mMotionX;
-            final int y = mMotionY;
-            final int motionPosition = pointToPosition(x, y);
-            if (motionPosition >= 0) {
-                // Remember where the motion event started
-                v = getChildAt(motionPosition - mFirstPosition);
-                mMotionViewOriginalTop = v.getTop();
-                mMotionPosition = motionPosition;
-            }
-            mLastY = y;
-            break;
+        setPressed(false);
+
+        if (mEdgeGlowTop != null) {
+            mEdgeGlowTop.onRelease();
+            mEdgeGlowBottom.onRelease();
         }
 
-        case MotionEvent.ACTION_POINTER_DOWN: {
-            // New pointers take over dragging duties
-            final int index = ev.getActionIndex();
-            final int id = ev.getPointerId(index);
-            final int x = (int) ev.getX(index);
-            final int y = (int) ev.getY(index);
-            mMotionCorrection = 0;
-            mActivePointerId = id;
-            mMotionX = x;
-            mMotionY = y;
-            final int motionPosition = pointToPosition(x, y);
-            if (motionPosition >= 0) {
-                // Remember where the motion event started
-                v = getChildAt(motionPosition - mFirstPosition);
-                mMotionViewOriginalTop = v.getTop();
-                mMotionPosition = motionPosition;
+        // Need to redraw since we probably aren't drawing the selector anymore
+        invalidate();
+        removeCallbacks(mPendingCheckForLongPress);
+        recycleVelocityTracker();
+
+        mActivePointerId = INVALID_POINTER;
+
+        if (PROFILE_SCROLLING) {
+            if (mScrollProfilingStarted) {
+                Debug.stopMethodTracing();
+                mScrollProfilingStarted = false;
             }
-            mLastY = y;
-            break;
-        }
         }
 
-        return true;
+        if (mScrollStrictSpan != null) {
+            mScrollStrictSpan.finish();
+            mScrollStrictSpan = null;
+        }
+    }
+
+    private void onTouchCancel() {
+        switch (mTouchMode) {
+        case TOUCH_MODE_OVERSCROLL:
+            if (mFlingRunnable == null) {
+                mFlingRunnable = new FlingRunnable();
+            }
+            mFlingRunnable.startSpringback();
+            break;
+
+        case TOUCH_MODE_OVERFLING:
+            // Do nothing - let it play out.
+            break;
+
+        default:
+            mTouchMode = TOUCH_MODE_REST;
+            setPressed(false);
+            final View motionView = this.getChildAt(mMotionPosition - mFirstPosition);
+            if (motionView != null) {
+                motionView.setPressed(false);
+            }
+            clearScrollingCache();
+            removeCallbacks(mPendingCheckForLongPress);
+            recycleVelocityTracker();
+        }
+
+        if (mEdgeGlowTop != null) {
+            mEdgeGlowTop.onRelease();
+            mEdgeGlowBottom.onRelease();
+        }
+        mActivePointerId = INVALID_POINTER;
     }
 
     @Override
@@ -3728,18 +3854,6 @@
                 canvas.restoreToCount(restoreCount);
             }
         }
-        if (mFastScroller != null) {
-            final int scrollY = mScrollY;
-            if (scrollY != 0) {
-                // Pin to the top/bottom during overscroll
-                int restoreCount = canvas.save();
-                canvas.translate(0, (float) scrollY);
-                mFastScroller.draw(canvas);
-                canvas.restoreToCount(restoreCount);
-            } else {
-                mFastScroller.draw(canvas);
-            }
-        }
     }
 
     /**
@@ -3780,6 +3894,15 @@
     }
 
     @Override
+    public boolean onInterceptHoverEvent(MotionEvent event) {
+        if (mFastScroller != null && mFastScroller.onInterceptHoverEvent(event)) {
+            return true;
+        }
+
+        return super.onInterceptHoverEvent(event);
+    }
+
+    @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
         int action = ev.getAction();
         View v;
@@ -3796,11 +3919,8 @@
             return false;
         }
 
-        if (mFastScroller != null) {
-            boolean intercepted = mFastScroller.onInterceptTouchEvent(ev);
-            if (intercepted) {
-                return true;
-            }
+        if (mFastScroller != null && mFastScroller.onInterceptTouchEvent(ev)) {
+            return true;
         }
 
         switch (action & MotionEvent.ACTION_MASK) {
@@ -3945,6 +4065,7 @@
         private int mLastFlingY;
 
         private final Runnable mCheckFlywheel = new Runnable() {
+            @Override
             public void run() {
                 final int activeId = mActivePointerId;
                 final VelocityTracker vt = mVelocityTracker;
@@ -4066,6 +4187,7 @@
             postDelayed(mCheckFlywheel, FLYWHEEL_TIMEOUT);
         }
 
+        @Override
         public void run() {
             switch (mTouchMode) {
             default:
@@ -4455,6 +4577,7 @@
             removeCallbacks(this);
         }
 
+        @Override
         public void run() {
             final int listHeight = getHeight();
             final int firstPos = mFirstPosition;
@@ -4637,9 +4760,6 @@
     /**
      * The amount of friction applied to flings. The default value
      * is {@link ViewConfiguration#getScrollFriction}.
-     *
-     * @return A scalar dimensionless value representing the coefficient of
-     *         friction.
      */
     public void setFriction(float friction) {
         if (mFlingRunnable == null) {
@@ -4806,6 +4926,7 @@
         if (!isHardwareAccelerated()) {
             if (mClearScrollingCache == null) {
                 mClearScrollingCache = new Runnable() {
+                    @Override
                     public void run() {
                         if (mCachingStarted) {
                             mCachingStarted = mCachingActive = false;
@@ -4825,6 +4946,43 @@
     }
 
     /**
+     * Scrolls the list items within the view by a specified number of pixels.
+     *
+     * @param y the amount of pixels to scroll by vertically
+     * @see #canScrollList(int)
+     */
+    public void scrollListBy(int y) {
+        trackMotionScroll(-y, -y);
+    }
+
+    /**
+     * Check if the items in the list can be scrolled in a certain direction.
+     *
+     * @param direction Negative to check scrolling up, positive to check
+     *            scrolling down.
+     * @return true if the list can be scrolled in the specified direction,
+     *         false otherwise.
+     * @see #scrollListBy(int)
+     */
+    public boolean canScrollList(int direction) {
+        final int childCount = getChildCount();
+        if (childCount == 0) {
+            return false;
+        }
+
+        final int firstPosition = mFirstPosition;
+        final Rect listPadding = mListPadding;
+        if (direction > 0) {
+            final int lastBottom = getChildAt(childCount - 1).getBottom();
+            final int lastPosition = firstPosition + childCount;
+            return lastPosition < mItemCount || lastBottom > getHeight() - listPadding.bottom;
+        } else {
+            final int firstTop = getChildAt(0).getTop();
+            return firstPosition > 0 || firstTop < listPadding.top;
+        }
+    }
+
+    /**
      * Track a motion scroll
      *
      * @param deltaY Amount to offset mMotionView. This is the accumulated delta since the motion
@@ -5083,7 +5241,7 @@
         requestLayout();
         invalidate();
     }
-    
+
     /**
      * If there is a selection returns false.
      * Otherwise resurrects the selection and returns true if resurrected.
@@ -5591,54 +5749,157 @@
     @Override
     public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
         if (isTextFilterEnabled()) {
-            // XXX we need to have the text filter created, so we can get an
-            // InputConnection to proxy to.  Unfortunately this means we pretty
-            // much need to make it as soon as a list view gets focus.
-            createTextFilter(false);
             if (mPublicInputConnection == null) {
                 mDefInputConnection = new BaseInputConnection(this, false);
-                mPublicInputConnection = new InputConnectionWrapper(
-                        mTextFilter.onCreateInputConnection(outAttrs), true) {
-                    @Override
-                    public boolean reportFullscreenMode(boolean enabled) {
-                        // Use our own input connection, since it is
-                        // the "real" one the IME is talking with.
-                        return mDefInputConnection.reportFullscreenMode(enabled);
-                    }
-
-                    @Override
-                    public boolean performEditorAction(int editorAction) {
-                        // The editor is off in its own window; we need to be
-                        // the one that does this.
-                        if (editorAction == EditorInfo.IME_ACTION_DONE) {
-                            InputMethodManager imm = (InputMethodManager)
-                                    getContext().getSystemService(
-                                            Context.INPUT_METHOD_SERVICE);
-                            if (imm != null) {
-                                imm.hideSoftInputFromWindow(getWindowToken(), 0);
-                            }
-                            return true;
-                        }
-                        return false;
-                    }
-
-                    @Override
-                    public boolean sendKeyEvent(KeyEvent event) {
-                        // Use our own input connection, since the filter
-                        // text view may not be shown in a window so has
-                        // no ViewAncestor to dispatch events with.
-                        return mDefInputConnection.sendKeyEvent(event);
-                    }
-                };
+                mPublicInputConnection = new InputConnectionWrapper(outAttrs);
             }
-            outAttrs.inputType = EditorInfo.TYPE_CLASS_TEXT
-                    | EditorInfo.TYPE_TEXT_VARIATION_FILTER;
+            outAttrs.inputType = EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_VARIATION_FILTER;
             outAttrs.imeOptions = EditorInfo.IME_ACTION_DONE;
             return mPublicInputConnection;
         }
         return null;
     }
 
+    private class InputConnectionWrapper implements InputConnection {
+        private final EditorInfo mOutAttrs;
+        private InputConnection mTarget;
+
+        public InputConnectionWrapper(EditorInfo outAttrs) {
+            mOutAttrs = outAttrs;
+        }
+
+        private InputConnection getTarget() {
+            if (mTarget == null) {
+                mTarget = getTextFilterInput().onCreateInputConnection(mOutAttrs);
+            }
+            return mTarget;
+        }
+
+        @Override
+        public boolean reportFullscreenMode(boolean enabled) {
+            // Use our own input connection, since it is
+            // the "real" one the IME is talking with.
+            return mDefInputConnection.reportFullscreenMode(enabled);
+        }
+
+        @Override
+        public boolean performEditorAction(int editorAction) {
+            // The editor is off in its own window; we need to be
+            // the one that does this.
+            if (editorAction == EditorInfo.IME_ACTION_DONE) {
+                InputMethodManager imm = (InputMethodManager)
+                        getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+                if (imm != null) {
+                    imm.hideSoftInputFromWindow(getWindowToken(), 0);
+                }
+                return true;
+            }
+            return false;
+        }
+
+        @Override
+        public boolean sendKeyEvent(KeyEvent event) {
+            // Use our own input connection, since the filter
+            // text view may not be shown in a window so has
+            // no ViewAncestor to dispatch events with.
+            return mDefInputConnection.sendKeyEvent(event);
+        }
+
+        @Override
+        public CharSequence getTextBeforeCursor(int n, int flags) {
+            if (mTarget == null) return "";
+            return mTarget.getTextBeforeCursor(n, flags);
+        }
+
+        @Override
+        public CharSequence getTextAfterCursor(int n, int flags) {
+            if (mTarget == null) return "";
+            return mTarget.getTextAfterCursor(n, flags);
+        }
+
+        @Override
+        public CharSequence getSelectedText(int flags) {
+            if (mTarget == null) return "";
+            return mTarget.getSelectedText(flags);
+        }
+
+        @Override
+        public int getCursorCapsMode(int reqModes) {
+            if (mTarget == null) return InputType.TYPE_TEXT_FLAG_CAP_SENTENCES;
+            return mTarget.getCursorCapsMode(reqModes);
+        }
+
+        @Override
+        public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) {
+            return getTarget().getExtractedText(request, flags);
+        }
+
+        @Override
+        public boolean deleteSurroundingText(int beforeLength, int afterLength) {
+            return getTarget().deleteSurroundingText(beforeLength, afterLength);
+        }
+
+        @Override
+        public boolean setComposingText(CharSequence text, int newCursorPosition) {
+            return getTarget().setComposingText(text, newCursorPosition);
+        }
+
+        @Override
+        public boolean setComposingRegion(int start, int end) {
+            return getTarget().setComposingRegion(start, end);
+        }
+
+        @Override
+        public boolean finishComposingText() {
+            return mTarget == null || mTarget.finishComposingText();
+        }
+
+        @Override
+        public boolean commitText(CharSequence text, int newCursorPosition) {
+            return getTarget().commitText(text, newCursorPosition);
+        }
+
+        @Override
+        public boolean commitCompletion(CompletionInfo text) {
+            return getTarget().commitCompletion(text);
+        }
+
+        @Override
+        public boolean commitCorrection(CorrectionInfo correctionInfo) {
+            return getTarget().commitCorrection(correctionInfo);
+        }
+
+        @Override
+        public boolean setSelection(int start, int end) {
+            return getTarget().setSelection(start, end);
+        }
+
+        @Override
+        public boolean performContextMenuAction(int id) {
+            return getTarget().performContextMenuAction(id);
+        }
+
+        @Override
+        public boolean beginBatchEdit() {
+            return getTarget().beginBatchEdit();
+        }
+
+        @Override
+        public boolean endBatchEdit() {
+            return getTarget().endBatchEdit();
+        }
+
+        @Override
+        public boolean clearMetaKeyStates(int states) {
+            return getTarget().clearMetaKeyStates(states);
+        }
+
+        @Override
+        public boolean performPrivateCommand(String action, Bundle data) {
+            return getTarget().performPrivateCommand(action, data);
+        }
+    }
+
     /**
      * For filtering we proxy an input connection to an internal text editor,
      * and this allows the proxying to happen.
@@ -5655,23 +5916,11 @@
      */
     private void createTextFilter(boolean animateEntrance) {
         if (mPopup == null) {
-            Context c = getContext();
-            PopupWindow p = new PopupWindow(c);
-            LayoutInflater layoutInflater = (LayoutInflater)
-                    c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-            mTextFilter = (EditText) layoutInflater.inflate(
-                    com.android.internal.R.layout.typing_filter, null);
-            // For some reason setting this as the "real" input type changes
-            // the text view in some way that it doesn't work, and I don't
-            // want to figure out why this is.
-            mTextFilter.setRawInputType(EditorInfo.TYPE_CLASS_TEXT
-                    | EditorInfo.TYPE_TEXT_VARIATION_FILTER);
-            mTextFilter.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI);
-            mTextFilter.addTextChangedListener(this);
+            PopupWindow p = new PopupWindow(getContext());
             p.setFocusable(false);
             p.setTouchable(false);
             p.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
-            p.setContentView(mTextFilter);
+            p.setContentView(getTextFilterInput());
             p.setWidth(LayoutParams.WRAP_CONTENT);
             p.setHeight(LayoutParams.WRAP_CONTENT);
             p.setBackgroundDrawable(null);
@@ -5686,12 +5935,28 @@
         }
     }
 
+    private EditText getTextFilterInput() {
+        if (mTextFilter == null) {
+            final LayoutInflater layoutInflater = LayoutInflater.from(getContext());
+            mTextFilter = (EditText) layoutInflater.inflate(
+                    com.android.internal.R.layout.typing_filter, null);
+            // For some reason setting this as the "real" input type changes
+            // the text view in some way that it doesn't work, and I don't
+            // want to figure out why this is.
+            mTextFilter.setRawInputType(EditorInfo.TYPE_CLASS_TEXT
+                    | EditorInfo.TYPE_TEXT_VARIATION_FILTER);
+            mTextFilter.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI);
+            mTextFilter.addTextChangedListener(this);
+        }
+        return mTextFilter;
+    }
+
     /**
      * Clear the text filter.
      */
     public void clearTextFilter() {
         if (mFiltered) {
-            mTextFilter.setText("");
+            getTextFilterInput().setText("");
             mFiltered = false;
             if (mPopup != null && mPopup.isShowing()) {
                 dismissPopup();
@@ -5706,6 +5971,7 @@
         return mFiltered;
     }
 
+    @Override
     public void onGlobalLayout() {
         if (isShown()) {
             // Show the popup if we are filtered
@@ -5725,6 +5991,7 @@
      * For our text watcher that is associated with the text filter.  Does
      * nothing.
      */
+    @Override
     public void beforeTextChanged(CharSequence s, int start, int count, int after) {
     }
 
@@ -5733,8 +6000,10 @@
      * the actual filtering as the text changes, and takes care of hiding and
      * showing the popup displaying the currently entered filter text.
      */
+    @Override
     public void onTextChanged(CharSequence s, int start, int before, int count) {
-        if (mPopup != null && isTextFilterEnabled()) {
+        if (isTextFilterEnabled()) {
+            createTextFilter(true);
             int length = s.length();
             boolean showing = mPopup.isShowing();
             if (!showing && length > 0) {
@@ -5763,9 +6032,11 @@
      * For our text watcher that is associated with the text filter.  Does
      * nothing.
      */
+    @Override
     public void afterTextChanged(Editable s) {
     }
 
+    @Override
     public void onFilterComplete(int count) {
         if (mSelectedPosition < 0 && count > 0) {
             mResurrectToPosition = INVALID_POSITION;
@@ -5917,9 +6188,9 @@
 
     /**
      * Sets up the onClickHandler to be used by the RemoteViewsAdapter when inflating RemoteViews
-     * 
+     *
      * @param handler The OnClickHandler to use when inflating RemoteViews.
-     * 
+     *
      * @hide
      */
     public void setRemoteViewsOnClickHandler(OnClickHandler handler) {
@@ -5934,6 +6205,7 @@
      * This defers a notifyDataSetChanged on the pending RemoteViewsAdapter if it has not
      * connected yet.
      */
+    @Override
     public void deferNotifyDataSetChanged() {
         mDeferNotifyDataSetChanged = true;
     }
@@ -5941,6 +6213,7 @@
     /**
      * Called back when the adapter connects to the RemoteViewsService.
      */
+    @Override
     public boolean onRemoteAdapterConnected() {
         if (mRemoteAdapter != mAdapter) {
             setAdapter(mRemoteAdapter);
@@ -5959,6 +6232,7 @@
     /**
      * Called back when the adapter disconnects from the RemoteViewsService.
      */
+    @Override
     public void onRemoteAdapterDisconnected() {
         // If the remote adapter disconnects, we keep it around
         // since the currently displayed items are still cached.
@@ -6041,6 +6315,7 @@
             return mWrapped != null;
         }
 
+        @Override
         public boolean onCreateActionMode(ActionMode mode, Menu menu) {
             if (mWrapped.onCreateActionMode(mode, menu)) {
                 // Initialize checked graphic state?
@@ -6050,14 +6325,17 @@
             return false;
         }
 
+        @Override
         public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
             return mWrapped.onPrepareActionMode(mode, menu);
         }
 
+        @Override
         public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
             return mWrapped.onActionItemClicked(mode, item);
         }
 
+        @Override
         public void onDestroyActionMode(ActionMode mode) {
             mWrapped.onDestroyActionMode(mode);
             mChoiceActionMode = null;
@@ -6072,6 +6350,7 @@
             setLongClickable(true);
         }
 
+        @Override
         public void onItemCheckedStateChanged(ActionMode mode,
                 int position, long id, boolean checked) {
             mWrapped.onItemCheckedStateChanged(mode, position, id, checked);
@@ -6296,6 +6575,7 @@
             }
             mFirstActivePosition = firstActivePosition;
 
+            //noinspection MismatchedReadAndWriteOfArray
             final View[] activeViews = mActiveViews;
             for (int i = 0; i < childCount; i++) {
                 View child = getChildAt(i);
@@ -6373,58 +6653,67 @@
         }
 
         /**
-         * Put a view into the ScrapViews list. These views are unordered.
+         * Puts a view into the list of scrap views.
+         * <p>
+         * If the list data hasn't changed or the adapter has stable IDs, views
+         * with transient state will be preserved for later retrieval.
          *
          * @param scrap The view to add
+         * @param position The view's position within its parent
          */
         void addScrapView(View scrap, int position) {
-            AbsListView.LayoutParams lp = (AbsListView.LayoutParams) scrap.getLayoutParams();
+            final AbsListView.LayoutParams lp = (AbsListView.LayoutParams) scrap.getLayoutParams();
             if (lp == null) {
                 return;
             }
 
             lp.scrappedFromPosition = position;
 
-            // Don't put header or footer views or views that should be ignored
-            // into the scrap heap
-            int viewType = lp.viewType;
+            // Don't scrap header or footer views, or views that should
+            // otherwise not be recycled.
+            final int viewType = lp.viewType;
+            if (!shouldRecycleViewType(viewType)) {
+                return;
+            }
+
+            scrap.dispatchStartTemporaryDetach();
+
+            // Don't scrap views that have transient state.
             final boolean scrapHasTransientState = scrap.hasTransientState();
-            if (!shouldRecycleViewType(viewType) || scrapHasTransientState) {
-                if (viewType != ITEM_VIEW_TYPE_HEADER_OR_FOOTER && scrapHasTransientState) {
+            if (scrapHasTransientState) {
+                if (mAdapter != null && mAdapterHasStableIds) {
+                    // If the adapter has stable IDs, we can reuse the view for
+                    // the same data.
+                    if (mTransientStateViewsById == null) {
+                        mTransientStateViewsById = new LongSparseArray<View>();
+                    }
+                    mTransientStateViewsById.put(lp.itemId, scrap);
+                } else if (!mDataChanged) {
+                    // If the data hasn't changed, we can reuse the views at
+                    // their old positions.
+                    if (mTransientStateViews == null) {
+                        mTransientStateViews = new SparseArray<View>();
+                    }
+                    mTransientStateViews.put(position, scrap);
+                } else {
+                    // Otherwise, we'll have to remove the view and start over.
                     if (mSkippedScrap == null) {
                         mSkippedScrap = new ArrayList<View>();
                     }
                     mSkippedScrap.add(scrap);
                 }
-                if (scrapHasTransientState) {
-                    scrap.dispatchStartTemporaryDetach();
-                    if (mAdapter != null && mAdapterHasStableIds) {
-                        if (mTransientStateViewsById == null) {
-                            mTransientStateViewsById = new LongSparseArray<View>();
-                        }
-                        mTransientStateViewsById.put(lp.itemId, scrap);
-                    } else if (!mDataChanged) {
-                        // avoid putting views on transient state list during a data change;
-                        // the layout positions may be out of sync with the adapter positions
-                        if (mTransientStateViews == null) {
-                            mTransientStateViews = new SparseArray<View>();
-                        }
-                        mTransientStateViews.put(position, scrap);
-                    }
-                }
-                return;
-            }
-
-            scrap.dispatchStartTemporaryDetach();
-            if (mViewTypeCount == 1) {
-                mCurrentScrap.add(scrap);
             } else {
-                mScrapViews[viewType].add(scrap);
-            }
+                if (mViewTypeCount == 1) {
+                    mCurrentScrap.add(scrap);
+                } else {
+                    mScrapViews[viewType].add(scrap);
+                }
 
-            scrap.setAccessibilityDelegate(null);
-            if (mRecyclerListener != null) {
-                mRecyclerListener.onMovedToScrapHeap(scrap);
+                scrap.setAccessibilityDelegate(null);
+
+                if (mRecyclerListener != null) {
+                    mRecyclerListener.onMovedToScrapHeap(scrap);
+                }
             }
         }
 
diff --git a/core/java/android/widget/ActivityChooserView.java b/core/java/android/widget/ActivityChooserView.java
index 2037c3a..dff1531 100644
--- a/core/java/android/widget/ActivityChooserView.java
+++ b/core/java/android/widget/ActivityChooserView.java
@@ -29,11 +29,14 @@
 import android.util.AttributeSet;
 import android.view.ActionProvider;
 import android.view.LayoutInflater;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.view.ViewTreeObserver.OnGlobalLayoutListener;
+import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.ActivityChooserModel.ActivityChooserModelClient;
+import android.widget.ListPopupWindow.ForwardingListener;
 
 /**
  * This class is a view for choosing an activity for handling a given {@link Intent}.
@@ -227,10 +230,37 @@
         mDefaultActivityButton.setOnLongClickListener(mCallbacks);
         mDefaultActivityButtonImage = (ImageView) mDefaultActivityButton.findViewById(R.id.image);
 
-        mExpandActivityOverflowButton = (FrameLayout) findViewById(R.id.expand_activities_button);
-        mExpandActivityOverflowButton.setOnClickListener(mCallbacks);
+        final FrameLayout expandButton = (FrameLayout) findViewById(R.id.expand_activities_button);
+        expandButton.setOnClickListener(mCallbacks);
+        expandButton.setAccessibilityDelegate(new AccessibilityDelegate() {
+            @Override
+            public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
+                super.onInitializeAccessibilityNodeInfo(host, info);
+                info.setCanOpenPopup(true);
+            }
+        });
+        expandButton.setOnTouchListener(new ForwardingListener(expandButton) {
+            @Override
+            public ListPopupWindow getPopup() {
+                return getListPopupWindow();
+            }
+
+            @Override
+            protected boolean onForwardingStarted() {
+                showPopup();
+                return true;
+            }
+
+            @Override
+            protected boolean onForwardingStopped() {
+                dismissPopup();
+                return true;
+            }
+        });
+        mExpandActivityOverflowButton = expandButton;
+
         mExpandActivityOverflowButtonImage =
-            (ImageView) mExpandActivityOverflowButton.findViewById(R.id.image);
+            (ImageView) expandButton.findViewById(R.id.image);
         mExpandActivityOverflowButtonImage.setImageDrawable(expandActivityOverflowButtonDrawable);
 
         mAdapter = new ActivityChooserViewAdapter();
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index 502de31..31ab0af 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -31,7 +31,6 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
-import android.view.accessibility.AccessibilityNodeProvider;
 
 /**
  * An AdapterView is a view whose children are determined by an {@link Adapter}.
@@ -1034,8 +1033,7 @@
             checkSelectionChanged();
         }
 
-        //TODO: Hmm, we do not know the old state so this is sub-optimal
-        notifyAccessibilityStateChanged();
+        notifySubtreeAccessibilityStateChangedIfNeeded();
     }
 
     void checkSelectionChanged() {
diff --git a/core/java/android/widget/CalendarView.java b/core/java/android/widget/CalendarView.java
index 6970cde..de2be75 100644
--- a/core/java/android/widget/CalendarView.java
+++ b/core/java/android/widget/CalendarView.java
@@ -1028,26 +1028,29 @@
      * Sets up the strings to be used by the header.
      */
     private void setUpHeader() {
+        final String[] tinyWeekdayNames = LocaleData.get(Locale.getDefault()).tinyWeekdayNames;
         mDayLabels = new String[mDaysPerWeek];
-        for (int i = mFirstDayOfWeek, count = mFirstDayOfWeek + mDaysPerWeek; i < count; i++) {
-            int calendarDay = (i > Calendar.SATURDAY) ? i - Calendar.SATURDAY : i;
-            mDayLabels[i - mFirstDayOfWeek] = DateUtils.getDayOfWeekString(calendarDay,
-                    DateUtils.LENGTH_SHORTEST);
+        for (int i = 0; i < mDaysPerWeek; i++) {
+            final int j = i + mFirstDayOfWeek;
+            final int calendarDay = (j > Calendar.SATURDAY) ? j - Calendar.SATURDAY : j;
+            mDayLabels[i] = tinyWeekdayNames[calendarDay];
         }
-
+        // Deal with week number
         TextView label = (TextView) mDayNamesHeader.getChildAt(0);
         if (mShowWeekNumber) {
             label.setVisibility(View.VISIBLE);
         } else {
             label.setVisibility(View.GONE);
         }
-        for (int i = 1, count = mDayNamesHeader.getChildCount(); i < count; i++) {
-            label = (TextView) mDayNamesHeader.getChildAt(i);
+        // Deal with day labels
+        final int count = mDayNamesHeader.getChildCount();
+        for (int i = 0; i < count - 1; i++) {
+            label = (TextView) mDayNamesHeader.getChildAt(i + 1);
             if (mWeekDayTextAppearanceResId > -1) {
                 label.setTextAppearance(mContext, mWeekDayTextAppearanceResId);
             }
-            if (i < mDaysPerWeek + 1) {
-                label.setText(mDayLabels[i - 1]);
+            if (i < mDaysPerWeek) {
+                label.setText(mDayLabels[i]);
                 label.setVisibility(View.VISIBLE);
             } else {
                 label.setVisibility(View.GONE);
diff --git a/core/java/android/widget/CheckedTextView.java b/core/java/android/widget/CheckedTextView.java
index 3f080d6..5c10a77 100644
--- a/core/java/android/widget/CheckedTextView.java
+++ b/core/java/android/widget/CheckedTextView.java
@@ -93,7 +93,8 @@
         if (mChecked != checked) {
             mChecked = checked;
             refreshDrawableState();
-            notifyAccessibilityStateChanged();
+            notifyViewAccessibilityStateChangedIfNeeded(
+                    AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
         }
     }
 
diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java
index 452ad1b..082ff3d 100644
--- a/core/java/android/widget/CompoundButton.java
+++ b/core/java/android/widget/CompoundButton.java
@@ -114,7 +114,8 @@
         if (mChecked != checked) {
             mChecked = checked;
             refreshDrawableState();
-            notifyAccessibilityStateChanged();
+            notifyViewAccessibilityStateChangedIfNeeded(
+                    AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
 
             // Avoid infinite recursions if setChecked() is called from a listener
             if (mBroadcasting) {
@@ -199,10 +200,8 @@
                 unscheduleDrawable(mButtonDrawable);
             }
             d.setCallback(this);
-            d.setState(getDrawableState());
             d.setVisible(getVisibility() == VISIBLE, false);
             mButtonDrawable = d;
-            mButtonDrawable.setState(null);
             setMinHeight(mButtonDrawable.getIntrinsicHeight());
         }
 
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index f57f333..50d28ab 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -16,6 +16,13 @@
 
 package android.widget;
 
+import android.content.UndoManager;
+import android.content.UndoOperation;
+import android.content.UndoOwner;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.InputFilter;
+import android.text.SpannableString;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.widget.EditableInputConnection;
 
@@ -107,11 +114,16 @@
  */
 public class Editor {
     private static final String TAG = "Editor";
+    static final boolean DEBUG_UNDO = false;
 
     static final int BLINK = 500;
     private static final float[] TEMP_POSITION = new float[2];
     private static int DRAG_SHADOW_MAX_TEXT_LENGTH = 20;
 
+    UndoManager mUndoManager;
+    UndoOwner mUndoOwner;
+    InputFilter mUndoInputFilter;
+
     // Cursor Controllers.
     InsertionPointCursorController mInsertionPointCursorController;
     SelectionModifierCursorController mSelectionModifierCursorController;
@@ -181,7 +193,10 @@
     // Set when this TextView gained focus with some text selected. Will start selection mode.
     boolean mCreatedWithASelection;
 
-    private EasyEditSpanController mEasyEditSpanController;
+    // The span controller helps monitoring the changes to which the Editor needs to react:
+    // - EasyEditSpans, for which we have some UI to display on attach and on hide
+    // - SelectionSpans, for which we need to call updateSelection if an IME is attached
+    private SpanController mSpanController;
 
     WordIterator mWordIterator;
     SpellChecker mSpellChecker;
@@ -466,8 +481,8 @@
     }
 
     private void hideSpanControllers() {
-        if (mEasyEditSpanController != null) {
-            mEasyEditSpanController.hide();
+        if (mSpanController != null) {
+            mSpanController.hide();
         }
     }
 
@@ -484,6 +499,10 @@
      * Create new SpellCheckSpans on the modified region.
      */
     private void updateSpellCheckSpans(int start, int end, boolean createSpellChecker) {
+        // Remove spans whose adjacent characters are text not punctuation
+        mTextView.removeAdjacentSuggestionSpans(start);
+        mTextView.removeAdjacentSuggestionSpans(end);
+
         if (mTextView.isTextEditable() && mTextView.isSuggestionsEnabled() &&
                 !(mTextView instanceof ExtractEditText)) {
             if (mSpellChecker == null && createSpellChecker) {
@@ -1082,9 +1101,12 @@
             mTextView.updateAfterEdit();
             reportExtractedText();
         } else if (ims.mCursorChanged) {
-            // Cheezy way to get us to report the current cursor location.
+            // Cheesy way to get us to report the current cursor location.
             mTextView.invalidateCursor();
         }
+        // sendUpdateSelection knows to avoid sending if the selection did
+        // not actually change.
+        sendUpdateSelection();
     }
 
     static final int EXTRACT_NOTHING = -2;
@@ -1205,6 +1227,27 @@
         return false;
     }
 
+    private void sendUpdateSelection() {
+        if (null != mInputMethodState && mInputMethodState.mBatchEditNesting <= 0) {
+            final InputMethodManager imm = InputMethodManager.peekInstance();
+            if (null != imm) {
+                final int selectionStart = mTextView.getSelectionStart();
+                final int selectionEnd = mTextView.getSelectionEnd();
+                int candStart = -1;
+                int candEnd = -1;
+                if (mTextView.getText() instanceof Spannable) {
+                    final Spannable sp = (Spannable) mTextView.getText();
+                    candStart = EditableInputConnection.getComposingSpanStart(sp);
+                    candEnd = EditableInputConnection.getComposingSpanEnd(sp);
+                }
+                // InputMethodManager#updateSelection skips sending the message if
+                // none of the parameters have changed since the last time we called it.
+                imm.updateSelection(mTextView,
+                        selectionStart, selectionEnd, candStart, candEnd);
+            }
+        }
+    }
+
     void onDraw(Canvas canvas, Layout layout, Path highlight, Paint highlightPaint,
             int cursorOffsetVertical) {
         final int selectionStart = mTextView.getSelectionStart();
@@ -1222,17 +1265,6 @@
                         // input method.
                         reported = reportExtractedText();
                     }
-                    if (!reported && highlight != null) {
-                        int candStart = -1;
-                        int candEnd = -1;
-                        if (mTextView.getText() instanceof Spannable) {
-                            Spannable sp = (Spannable) mTextView.getText();
-                            candStart = EditableInputConnection.getComposingSpanStart(sp);
-                            candEnd = EditableInputConnection.getComposingSpanEnd(sp);
-                        }
-                        imm.updateSelection(mTextView,
-                                selectionStart, selectionEnd, candStart, candEnd);
-                    }
                 }
 
                 if (imm.isWatchingCursor(mTextView) && highlight != null) {
@@ -1859,17 +1891,18 @@
             text.setSpan(mKeyListener, 0, textLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
         }
 
-        if (mEasyEditSpanController == null) {
-            mEasyEditSpanController = new EasyEditSpanController();
+        if (mSpanController == null) {
+            mSpanController = new SpanController();
         }
-        text.setSpan(mEasyEditSpanController, 0, textLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+        text.setSpan(mSpanController, 0, textLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
     }
 
     /**
      * Controls the {@link EasyEditSpan} monitoring when it is added, and when the related
      * pop-up should be displayed.
+     * Also monitors {@link Selection} to call back to the attached input method.
      */
-    class EasyEditSpanController implements SpanWatcher {
+    class SpanController implements SpanWatcher {
 
         private static final int DISPLAY_TIMEOUT_MS = 3000; // 3 secs
 
@@ -1877,9 +1910,18 @@
 
         private Runnable mHidePopup;
 
+        // This function is pure but inner classes can't have static functions
+        private boolean isNonIntermediateSelectionSpan(final Spannable text,
+                final Object span) {
+            return (Selection.SELECTION_START == span || Selection.SELECTION_END == span)
+                    && (text.getSpanFlags(span) & Spanned.SPAN_INTERMEDIATE) == 0;
+        }
+
         @Override
         public void onSpanAdded(Spannable text, Object span, int start, int end) {
-            if (span instanceof EasyEditSpan) {
+            if (isNonIntermediateSelectionSpan(text, span)) {
+                sendUpdateSelection();
+            } else if (span instanceof EasyEditSpan) {
                 if (mPopupWindow == null) {
                     mPopupWindow = new EasyEditPopupWindow();
                     mHidePopup = new Runnable() {
@@ -1903,7 +1945,7 @@
                         int start = editable.getSpanStart(span);
                         int end = editable.getSpanEnd(span);
                         if (start >= 0 && end >= 0) {
-                            sendNotification(EasyEditSpan.TEXT_DELETED, span);
+                            sendEasySpanNotification(EasyEditSpan.TEXT_DELETED, span);
                             mTextView.deleteText_internal(start, end);
                         }
                         editable.removeSpan(span);
@@ -1934,7 +1976,9 @@
 
         @Override
         public void onSpanRemoved(Spannable text, Object span, int start, int end) {
-            if (mPopupWindow != null && span == mPopupWindow.mEasyEditSpan) {
+            if (isNonIntermediateSelectionSpan(text, span)) {
+                sendUpdateSelection();
+            } else if (mPopupWindow != null && span == mPopupWindow.mEasyEditSpan) {
                 hide();
             }
         }
@@ -1942,9 +1986,11 @@
         @Override
         public void onSpanChanged(Spannable text, Object span, int previousStart, int previousEnd,
                 int newStart, int newEnd) {
-            if (mPopupWindow != null && span instanceof EasyEditSpan) {
+            if (isNonIntermediateSelectionSpan(text, span)) {
+                sendUpdateSelection();
+            } else if (mPopupWindow != null && span instanceof EasyEditSpan) {
                 EasyEditSpan easyEditSpan = (EasyEditSpan) span;
-                sendNotification(EasyEditSpan.TEXT_MODIFIED, easyEditSpan);
+                sendEasySpanNotification(EasyEditSpan.TEXT_MODIFIED, easyEditSpan);
                 text.removeSpan(easyEditSpan);
             }
         }
@@ -1956,7 +2002,7 @@
             }
         }
 
-        private void sendNotification(int textChangedType, EasyEditSpan span) {
+        private void sendEasySpanNotification(int textChangedType, EasyEditSpan span) {
             try {
                 PendingIntent pendingIntent = span.getPendingIntent();
                 if (pendingIntent != null) {
@@ -1984,7 +2030,7 @@
 
     /**
      * Displays the actions associated to an {@link EasyEditSpan}. The pop-up is controlled
-     * by {@link EasyEditSpanController}.
+     * by {@link SpanController}.
      */
     private class EasyEditPopupWindow extends PinnedPopupWindow
             implements OnClickListener {
@@ -3929,4 +3975,166 @@
             mTextView.setCursorPosition_internal(newCursorPosition, newCursorPosition);
         }
     }
+
+    public static class UndoInputFilter implements InputFilter {
+        final Editor mEditor;
+
+        public UndoInputFilter(Editor editor) {
+            mEditor = editor;
+        }
+
+        @Override
+        public CharSequence filter(CharSequence source, int start, int end,
+                Spanned dest, int dstart, int dend) {
+            if (DEBUG_UNDO) {
+                Log.d(TAG, "filter: source=" + source + " (" + start + "-" + end + ")");
+                Log.d(TAG, "filter: dest=" + dest + " (" + dstart + "-" + dend + ")");
+            }
+            final UndoManager um = mEditor.mUndoManager;
+            if (um.isInUndo()) {
+                if (DEBUG_UNDO) Log.d(TAG, "*** skipping, currently performing undo/redo");
+                return null;
+            }
+
+            um.beginUpdate("Edit text");
+            TextModifyOperation op = um.getLastOperation(
+                    TextModifyOperation.class, mEditor.mUndoOwner, UndoManager.MERGE_MODE_UNIQUE);
+            if (op != null) {
+                if (DEBUG_UNDO) Log.d(TAG, "Last op: range=(" + op.mRangeStart + "-" + op.mRangeEnd
+                        + "), oldText=" + op.mOldText);
+                // See if we can continue modifying this operation.
+                if (op.mOldText == null) {
+                    // The current operation is an add...  are we adding more?  We are adding
+                    // more if we are either appending new text to the end of the last edit or
+                    // completely replacing some or all of the last edit.
+                    if (start < end && ((dstart >= op.mRangeStart && dend <= op.mRangeEnd)
+                            || (dstart == op.mRangeEnd && dend == op.mRangeEnd))) {
+                        op.mRangeEnd = dstart + (end-start);
+                        um.endUpdate();
+                        if (DEBUG_UNDO) Log.d(TAG, "*** merging with last op, mRangeEnd="
+                                + op.mRangeEnd);
+                        return null;
+                    }
+                } else {
+                    // The current operation is a delete...  can we delete more?
+                    if (start == end && dend == op.mRangeStart-1) {
+                        SpannableStringBuilder str;
+                        if (op.mOldText instanceof SpannableString) {
+                            str = (SpannableStringBuilder)op.mOldText;
+                        } else {
+                            str = new SpannableStringBuilder(op.mOldText);
+                        }
+                        str.insert(0, dest, dstart, dend);
+                        op.mRangeStart = dstart;
+                        op.mOldText = str;
+                        um.endUpdate();
+                        if (DEBUG_UNDO) Log.d(TAG, "*** merging with last op, range=("
+                                + op.mRangeStart + "-" + op.mRangeEnd
+                                + "), oldText=" + op.mOldText);
+                        return null;
+                    }
+                }
+
+                // Couldn't add to the current undo operation, need to start a new
+                // undo state for a new undo operation.
+                um.commitState(null);
+                um.setUndoLabel("Edit text");
+            }
+
+            // Create a new undo state reflecting the operation being performed.
+            op = new TextModifyOperation(mEditor.mUndoOwner);
+            op.mRangeStart = dstart;
+            if (start < end) {
+                op.mRangeEnd = dstart + (end-start);
+            } else {
+                op.mRangeEnd = dstart;
+            }
+            if (dstart < dend) {
+                op.mOldText = dest.subSequence(dstart, dend);
+            }
+            if (DEBUG_UNDO) Log.d(TAG, "*** adding new op, range=(" + op.mRangeStart
+                    + "-" + op.mRangeEnd + "), oldText=" + op.mOldText);
+            um.addOperation(op, UndoManager.MERGE_MODE_NONE);
+            um.endUpdate();
+            return null;
+        }
+    }
+
+    public static class TextModifyOperation extends UndoOperation<TextView> {
+        int mRangeStart, mRangeEnd;
+        CharSequence mOldText;
+
+        public TextModifyOperation(UndoOwner owner) {
+            super(owner);
+        }
+
+        public TextModifyOperation(Parcel src, ClassLoader loader) {
+            super(src, loader);
+            mRangeStart = src.readInt();
+            mRangeEnd = src.readInt();
+            mOldText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(src);
+        }
+
+        @Override
+        public void commit() {
+        }
+
+        @Override
+        public void undo() {
+            swapText();
+        }
+
+        @Override
+        public void redo() {
+            swapText();
+        }
+
+        private void swapText() {
+            // Both undo and redo involves swapping the contents of the range
+            // in the text view with our local text.
+            TextView tv = getOwnerData();
+            Editable editable = (Editable)tv.getText();
+            CharSequence curText;
+            if (mRangeStart >= mRangeEnd) {
+                curText = null;
+            } else {
+                curText = editable.subSequence(mRangeStart, mRangeEnd);
+            }
+            if (DEBUG_UNDO) {
+                Log.d(TAG, "Swap: range=(" + mRangeStart + "-" + mRangeEnd
+                        + "), oldText=" + mOldText);
+                Log.d(TAG, "Swap: curText=" + curText);
+            }
+            if (mOldText == null) {
+                editable.delete(mRangeStart, mRangeEnd);
+                mRangeEnd = mRangeStart;
+            } else {
+                editable.replace(mRangeStart, mRangeEnd, mOldText);
+                mRangeEnd = mRangeStart + mOldText.length();
+            }
+            mOldText = curText;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeInt(mRangeStart);
+            dest.writeInt(mRangeEnd);
+            TextUtils.writeToParcel(mOldText, dest, flags);
+        }
+
+        public static final Parcelable.ClassLoaderCreator<TextModifyOperation> CREATOR
+                = new Parcelable.ClassLoaderCreator<TextModifyOperation>() {
+            public TextModifyOperation createFromParcel(Parcel in) {
+                return new TextModifyOperation(in, null);
+            }
+
+            public TextModifyOperation createFromParcel(Parcel in, ClassLoader loader) {
+                return new TextModifyOperation(in, loader);
+            }
+
+            public TextModifyOperation[] newArray(int size) {
+                return new TextModifyOperation[size];
+            }
+        };
+    }
 }
diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java
index 10b8cbe..006b96e 100644
--- a/core/java/android/widget/FastScroller.java
+++ b/core/java/android/widget/FastScroller.java
@@ -16,47 +16,66 @@
 
 package android.widget;
 
+import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
 import android.content.Context;
 import android.content.res.ColorStateList;
+import android.content.res.Resources;
 import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.Paint;
 import android.graphics.Rect;
-import android.graphics.RectF;
 import android.graphics.drawable.Drawable;
-import android.graphics.drawable.NinePatchDrawable;
-import android.os.Handler;
-import android.os.SystemClock;
+import android.os.Build;
+import android.text.TextUtils.TruncateAt;
+import android.util.IntProperty;
+import android.util.MathUtils;
+import android.util.Property;
+import android.view.Gravity;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.View.MeasureSpec;
 import android.view.ViewConfiguration;
+import android.view.ViewGroup.LayoutParams;
+import android.view.ViewGroupOverlay;
 import android.widget.AbsListView.OnScrollListener;
 
+import com.android.internal.R;
+
 /**
  * Helper class for AbsListView to draw and control the Fast Scroll thumb
  */
 class FastScroller {
-    private static final String TAG = "FastScroller";
-   
-    // Minimum number of pages to justify showing a fast scroll thumb
-    private static int MIN_PAGES = 4;
-    // Scroll thumb not showing
+    /** Duration of fade-out animation. */
+    private static final int DURATION_FADE_OUT = 300;
+
+    /** Duration of fade-in animation. */
+    private static final int DURATION_FADE_IN = 150;
+
+    /** Duration of transition cross-fade animation. */
+    private static final int DURATION_CROSS_FADE = 50;
+
+    /** Duration of transition resize animation. */
+    private static final int DURATION_RESIZE = 100;
+
+    /** Inactivity timeout before fading controls. */
+    private static final long FADE_TIMEOUT = 1500;
+
+    /** Minimum number of pages to justify showing a fast scroll thumb. */
+    private static final int MIN_PAGES = 4;
+
+    /** Scroll thumb and preview not showing. */
     private static final int STATE_NONE = 0;
-    // Not implemented yet - fade-in transition
-    private static final int STATE_ENTER = 1;
-    // Scroll thumb visible and moving along with the scrollbar
-    private static final int STATE_VISIBLE = 2;
-    // Scroll thumb being dragged by user
-    private static final int STATE_DRAGGING = 3;
-    // Scroll thumb fading out due to inactivity timeout
-    private static final int STATE_EXIT = 4;
 
-    private static final int[] PRESSED_STATES = new int[] {
-        android.R.attr.state_pressed
-    };
+    /** Scroll thumb visible and moving along with the scrollbar. */
+    private static final int STATE_VISIBLE = 1;
 
-    private static final int[] DEFAULT_STATES = new int[0];
+    /** Scroll thumb and preview being dragged by user. */
+    private static final int STATE_DRAGGING = 2;
 
+    /** Styleable attributes. */
     private static final int[] ATTRS = new int[] {
         android.R.attr.fastScrollTextColor,
         android.R.attr.fastScrollThumbDrawable,
@@ -66,6 +85,7 @@
         android.R.attr.fastScrollOverlayPosition
     };
 
+    // Styleable attribute indices.
     private static final int TEXT_COLOR = 0;
     private static final int THUMB_DRAWABLE = 1;
     private static final int TRACK_DRAWABLE = 2;
@@ -73,111 +93,317 @@
     private static final int PREVIEW_BACKGROUND_RIGHT = 4;
     private static final int OVERLAY_POSITION = 5;
 
+    // Positions for preview image and text.
     private static final int OVERLAY_FLOATING = 0;
     private static final int OVERLAY_AT_THUMB = 1;
-    
-    private Drawable mThumbDrawable;
-    private Drawable mOverlayDrawable;
-    private Drawable mTrackDrawable;
 
-    private Drawable mOverlayDrawableLeft;
-    private Drawable mOverlayDrawableRight;
+    // Indices for mPreviewResId.
+    private static final int PREVIEW_LEFT = 0;
+    private static final int PREVIEW_RIGHT = 1;
 
-    int mThumbH;
-    int mThumbW;
-    int mThumbY;
+    /** Delay before considering a tap in the thumb area to be a drag. */
+    private static final long TAP_TIMEOUT = ViewConfiguration.getTapTimeout();
 
-    private RectF mOverlayPos;
-    private int mOverlaySize;
+    private final Rect mTempBounds = new Rect();
+    private final Rect mTempMargins = new Rect();
+    private final Rect mContainerRect = new Rect();
 
-    AbsListView mList;
-    boolean mScrollCompleted;
-    private int mVisibleItem;
-    private Paint mPaint;
-    private int mListOffset;
-    private int mItemCount = -1;
+    private final AbsListView mList;
+    private final ViewGroupOverlay mOverlay;
+    private final TextView mPrimaryText;
+    private final TextView mSecondaryText;
+    private final ImageView mThumbImage;
+    private final ImageView mTrackImage;
+    private final ImageView mPreviewImage;
+
+    /**
+     * Preview image resource IDs for left- and right-aligned layouts. See
+     * {@link #PREVIEW_LEFT} and {@link #PREVIEW_RIGHT}.
+     */
+    private final int[] mPreviewResId = new int[2];
+
+    /**
+     * Padding in pixels around the preview text. Applied as layout margins to
+     * the preview text and padding to the preview image.
+     */
+    private final int mPreviewPadding;
+
+    /** Whether there is a track image to display. */
+    private final boolean mHasTrackImage;
+
+    /** Total width of decorations. */
+    private final int mWidth;
+
+    /** Set containing decoration transition animations. */
+    private AnimatorSet mDecorAnimation;
+
+    /** Set containing preview text transition animations. */
+    private AnimatorSet mPreviewAnimation;
+
+    /** Whether the primary text is showing. */
+    private boolean mShowingPrimary;
+
+    /** Whether we're waiting for completion of scrollTo(). */
+    private boolean mScrollCompleted;
+
+    /** The position of the first visible item in the list. */
+    private int mFirstVisibleItem;
+
+    /** The number of headers at the top of the view. */
+    private int mHeaderCount;
+
+    /** The index of the current section. */
+    private int mCurrentSection = -1;
+
+    /** The current scrollbar position. */
+    private int mScrollbarPosition = -1;
+
+    /** Whether the list is long enough to need a fast scroller. */
     private boolean mLongList;
-    
-    private Object [] mSections;
-    private String mSectionText;
-    private boolean mDrawOverlay;
-    private ScrollFade mScrollFade;
-    
+
+    private Object[] mSections;
+
+    /** Whether this view is currently performing layout. */
+    private boolean mUpdatingLayout;
+
+    /**
+     * Current decoration state, one of:
+     * <ul>
+     * <li>{@link #STATE_NONE}, nothing visible
+     * <li>{@link #STATE_VISIBLE}, showing track and thumb
+     * <li>{@link #STATE_DRAGGING}, visible and showing preview
+     * </ul>
+     */
     private int mState;
-    
-    private Handler mHandler = new Handler();
-    
-    BaseAdapter mListAdapter;
+
+    private BaseAdapter mListAdapter;
     private SectionIndexer mSectionIndexer;
 
-    private boolean mChangedBounds;
-    
-    private int mPosition;
+    /** Whether decorations should be laid out from right to left. */
+    private boolean mLayoutFromRight;
 
+    /** Whether the fast scroller is enabled. */
+    private boolean mEnabled;
+
+    /** Whether the scrollbar and decorations should always be shown. */
     private boolean mAlwaysShow;
 
+    /**
+     * Position for the preview image and text. One of:
+     * <ul>
+     * <li>{@link #OVERLAY_AT_THUMB}
+     * <li>{@link #OVERLAY_FLOATING}
+     * </ul>
+     */
     private int mOverlayPosition;
 
+    /** Current scrollbar style, including inset and overlay properties. */
+    private int mScrollBarStyle;
+
+    /** Whether to precisely match the thumb position to the list. */
     private boolean mMatchDragPosition;
 
-    float mInitialTouchY;
-    boolean mPendingDrag;
+    private float mInitialTouchY;
+    private boolean mHasPendingDrag;
     private int mScaledTouchSlop;
 
-    private static final int FADE_TIMEOUT = 1500;
-    private static final int PENDING_DRAG_DELAY = 180;
-
-    private final Rect mTmpRect = new Rect();
-
     private final Runnable mDeferStartDrag = new Runnable() {
+        @Override
         public void run() {
             if (mList.mIsAttached) {
                 beginDrag();
 
-                final int viewHeight = mList.getHeight();
-                // Jitter
-                int newThumbY = (int) mInitialTouchY - mThumbH + 10;
-                if (newThumbY < 0) {
-                    newThumbY = 0;
-                } else if (newThumbY + mThumbH > viewHeight) {
-                    newThumbY = viewHeight - mThumbH;
-                }
-                mThumbY = newThumbY;
-                scrollTo((float) mThumbY / (viewHeight - mThumbH));
+                final float pos = getPosFromMotionEvent(mInitialTouchY);
+                scrollTo(pos);
             }
 
-            mPendingDrag = false;
+            mHasPendingDrag = false;
         }
     };
 
-    public FastScroller(Context context, AbsListView listView) {
+    /**
+     * Used to delay hiding fast scroll decorations.
+     */
+    private final Runnable mDeferHide = new Runnable() {
+        @Override
+        public void run() {
+            setState(STATE_NONE);
+        }
+    };
+
+    /**
+     * Used to effect a transition from primary to secondary text.
+     */
+    private final AnimatorListener mSwitchPrimaryListener = new AnimatorListenerAdapter() {
+        @Override
+        public void onAnimationEnd(Animator animation) {
+            mShowingPrimary = !mShowingPrimary;
+        }
+    };
+
+    public FastScroller(AbsListView listView) {
         mList = listView;
-        init(context);
+        mOverlay = listView.getOverlay();
+
+        final Context context = listView.getContext();
+        mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
+
+        final Resources res = context.getResources();
+        final TypedArray ta = context.getTheme().obtainStyledAttributes(ATTRS);
+
+        final ImageView trackImage = new ImageView(context);
+        mTrackImage = trackImage;
+
+        int width = 0;
+
+        // Add track to overlay if it has an image.
+        final Drawable trackDrawable = ta.getDrawable(TRACK_DRAWABLE);
+        if (trackDrawable != null) {
+            mHasTrackImage = true;
+            trackImage.setBackground(trackDrawable);
+            mOverlay.add(trackImage);
+            width = Math.max(width, trackDrawable.getIntrinsicWidth());
+        } else {
+            mHasTrackImage = false;
+        }
+
+        final ImageView thumbImage = new ImageView(context);
+        mThumbImage = thumbImage;
+
+        // Add thumb to overlay if it has an image.
+        final Drawable thumbDrawable = ta.getDrawable(THUMB_DRAWABLE);
+        if (thumbDrawable != null) {
+            thumbImage.setImageDrawable(thumbDrawable);
+            mOverlay.add(thumbImage);
+            width = Math.max(width, thumbDrawable.getIntrinsicWidth());
+        }
+
+        // If necessary, apply minimum thumb width and height.
+        if (thumbDrawable.getIntrinsicWidth() <= 0 || thumbDrawable.getIntrinsicHeight() <= 0) {
+            final int minWidth = res.getDimensionPixelSize(R.dimen.fastscroll_thumb_width);
+            thumbImage.setMinimumWidth(minWidth);
+            thumbImage.setMinimumHeight(
+                    res.getDimensionPixelSize(R.dimen.fastscroll_thumb_height));
+            width = Math.max(width, minWidth);
+        }
+
+        mWidth = width;
+
+        final int previewSize = res.getDimensionPixelSize(R.dimen.fastscroll_overlay_size);
+        mPreviewImage = new ImageView(context);
+        mPreviewImage.setMinimumWidth(previewSize);
+        mPreviewImage.setMinimumHeight(previewSize);
+        mPreviewImage.setAlpha(0f);
+        mOverlay.add(mPreviewImage);
+
+        mPreviewPadding = res.getDimensionPixelSize(R.dimen.fastscroll_overlay_padding);
+
+        final int textMinSize = Math.max(0, previewSize - mPreviewPadding);
+        mPrimaryText = createPreviewTextView(context, ta);
+        mPrimaryText.setMinimumWidth(textMinSize);
+        mPrimaryText.setMinimumHeight(textMinSize);
+        mOverlay.add(mPrimaryText);
+        mSecondaryText = createPreviewTextView(context, ta);
+        mSecondaryText.setMinimumWidth(textMinSize);
+        mSecondaryText.setMinimumHeight(textMinSize);
+        mOverlay.add(mSecondaryText);
+
+        mPreviewResId[PREVIEW_LEFT] = ta.getResourceId(PREVIEW_BACKGROUND_LEFT, 0);
+        mPreviewResId[PREVIEW_RIGHT] = ta.getResourceId(PREVIEW_BACKGROUND_RIGHT, 0);
+        mOverlayPosition = ta.getInt(OVERLAY_POSITION, OVERLAY_FLOATING);
+        ta.recycle();
+
+        mScrollBarStyle = listView.getScrollBarStyle();
+        mScrollCompleted = true;
+        mState = STATE_VISIBLE;
+        mMatchDragPosition = context.getApplicationInfo().targetSdkVersion
+                >= Build.VERSION_CODES.HONEYCOMB;
+
+        getSectionsFromIndexer();
+        refreshDrawablePressedState();
+        updateLongList(listView.getChildCount(), listView.getCount());
+        setScrollbarPosition(mList.getVerticalScrollbarPosition());
+        postAutoHide();
     }
 
-    public void setAlwaysShow(boolean alwaysShow) {
-        mAlwaysShow = alwaysShow;
-        if (alwaysShow) {
-            mHandler.removeCallbacks(mScrollFade);
-            setState(STATE_VISIBLE);
-        } else if (mState == STATE_VISIBLE) {
-            mHandler.postDelayed(mScrollFade, FADE_TIMEOUT);
+    /**
+     * Removes this FastScroller overlay from the host view.
+     */
+    public void remove() {
+        mOverlay.remove(mTrackImage);
+        mOverlay.remove(mThumbImage);
+        mOverlay.remove(mPreviewImage);
+        mOverlay.remove(mPrimaryText);
+        mOverlay.remove(mSecondaryText);
+    }
+
+    /**
+     * @param enabled Whether the fast scroll thumb is enabled.
+     */
+    public void setEnabled(boolean enabled) {
+        if (mEnabled != enabled) {
+            mEnabled = enabled;
+
+            onStateDependencyChanged();
         }
     }
 
+    /**
+     * @return Whether the fast scroll thumb is enabled.
+     */
+    public boolean isEnabled() {
+        return mEnabled && (mLongList || mAlwaysShow);
+    }
+
+    /**
+     * @param alwaysShow Whether the fast scroll thumb should always be shown
+     */
+    public void setAlwaysShow(boolean alwaysShow) {
+        if (mAlwaysShow != alwaysShow) {
+            mAlwaysShow = alwaysShow;
+
+            onStateDependencyChanged();
+        }
+    }
+
+    /**
+     * @return Whether the fast scroll thumb will always be shown
+     * @see #setAlwaysShow(boolean)
+     */
     public boolean isAlwaysShowEnabled() {
         return mAlwaysShow;
     }
 
-    private void refreshDrawableState() {
-        int[] state = mState == STATE_DRAGGING ? PRESSED_STATES : DEFAULT_STATES;
+    /**
+     * Called when one of the variables affecting enabled state changes.
+     */
+    private void onStateDependencyChanged() {
+        if (isEnabled()) {
+            if (isAlwaysShowEnabled()) {
+                setState(STATE_VISIBLE);
+            } else if (mState == STATE_VISIBLE) {
+                postAutoHide();
+            }
+        } else {
+            stop();
+        }
 
-        if (mThumbDrawable != null && mThumbDrawable.isStateful()) {
-            mThumbDrawable.setState(state);
+        mList.resolvePadding();
+    }
+
+    public void setScrollBarStyle(int style) {
+        if (mScrollBarStyle != style) {
+            mScrollBarStyle = style;
+
+            updateLayout();
         }
-        if (mTrackDrawable != null && mTrackDrawable.isStateful()) {
-            mTrackDrawable.setState(state);
-        }
+    }
+
+    /**
+     * Immediately transitions the fast scroller decorations to a hidden state.
+     */
+    public void stop() {
+        setState(STATE_NONE);
     }
 
     public void setScrollbarPosition(int position) {
@@ -185,362 +411,459 @@
             position = mList.isLayoutRtl() ?
                     View.SCROLLBAR_POSITION_LEFT : View.SCROLLBAR_POSITION_RIGHT;
         }
-        mPosition = position;
-        switch (position) {
-            default:
-            case View.SCROLLBAR_POSITION_RIGHT:
-                mOverlayDrawable = mOverlayDrawableRight;
-                break;
-            case View.SCROLLBAR_POSITION_LEFT:
-                mOverlayDrawable = mOverlayDrawableLeft;
-                break;
+
+        if (mScrollbarPosition != position) {
+            mScrollbarPosition = position;
+            mLayoutFromRight = position != View.SCROLLBAR_POSITION_LEFT;
+
+            final int previewResId = mPreviewResId[mLayoutFromRight ? PREVIEW_RIGHT : PREVIEW_LEFT];
+            mPreviewImage.setBackgroundResource(previewResId);
+
+            // Add extra padding for text.
+            final Drawable background = mPreviewImage.getBackground();
+            if (background != null) {
+                final Rect padding = mTempBounds;
+                background.getPadding(padding);
+                padding.offset(mPreviewPadding, mPreviewPadding);
+                mPreviewImage.setPadding(padding.left, padding.top, padding.right, padding.bottom);
+            }
+
+            // Requires re-layout.
+            updateLayout();
         }
     }
 
     public int getWidth() {
-        return mThumbW;
+        return mWidth;
     }
 
-    public void setState(int state) {
+    public void onSizeChanged(int w, int h, int oldw, int oldh) {
+        updateLayout();
+    }
+
+    public void onItemCountChanged(int oldTotalItemCount, int totalItemCount) {
+        final int visibleItemCount = mList.getChildCount();
+        final boolean hasMoreItems = totalItemCount - visibleItemCount > 0;
+        if (hasMoreItems && mState != STATE_DRAGGING) {
+            final int firstVisibleItem = mList.getFirstVisiblePosition();
+            setThumbPos(getPosFromItemCount(firstVisibleItem, visibleItemCount, totalItemCount));
+        }
+
+        updateLongList(visibleItemCount, totalItemCount);
+    }
+
+    private void updateLongList(int visibleItemCount, int totalItemCount) {
+        final boolean longList = visibleItemCount > 0
+                && totalItemCount / visibleItemCount >= MIN_PAGES;
+        if (mLongList != longList) {
+            mLongList = longList;
+
+            onStateDependencyChanged();
+        }
+    }
+
+    /**
+     * Creates a view into which preview text can be placed.
+     */
+    private TextView createPreviewTextView(Context context, TypedArray ta) {
+        final LayoutParams params = new LayoutParams(
+                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+        final Resources res = context.getResources();
+        final int minSize = res.getDimensionPixelSize(R.dimen.fastscroll_overlay_size);
+        final ColorStateList textColor = ta.getColorStateList(TEXT_COLOR);
+        final float textSize = res.getDimension(R.dimen.fastscroll_overlay_text_size);
+        final TextView textView = new TextView(context);
+        textView.setLayoutParams(params);
+        textView.setTextColor(textColor);
+        textView.setTextSize(textSize);
+        textView.setSingleLine(true);
+        textView.setEllipsize(TruncateAt.MIDDLE);
+        textView.setGravity(Gravity.CENTER);
+        textView.setAlpha(0f);
+
+        // Manually propagate inherited layout direction.
+        textView.setLayoutDirection(mList.getLayoutDirection());
+
+        return textView;
+    }
+
+    /**
+     * Measures and layouts the scrollbar and decorations.
+     */
+    public void updateLayout() {
+        // Prevent re-entry when RTL properties change as a side-effect of
+        // resolving padding.
+        if (mUpdatingLayout) {
+            return;
+        }
+
+        mUpdatingLayout = true;
+
+        updateContainerRect();
+
+        layoutThumb();
+        layoutTrack();
+
+        final Rect bounds = mTempBounds;
+        measurePreview(mPrimaryText, bounds);
+        applyLayout(mPrimaryText, bounds);
+        measurePreview(mSecondaryText, bounds);
+        applyLayout(mSecondaryText, bounds);
+
+        if (mPreviewImage != null) {
+            // Apply preview image padding.
+            bounds.left -= mPreviewImage.getPaddingLeft();
+            bounds.top -= mPreviewImage.getPaddingTop();
+            bounds.right += mPreviewImage.getPaddingRight();
+            bounds.bottom += mPreviewImage.getPaddingBottom();
+            applyLayout(mPreviewImage, bounds);
+        }
+
+        mUpdatingLayout = false;
+    }
+
+    /**
+     * Layouts a view within the specified bounds and pins the pivot point to
+     * the appropriate edge.
+     *
+     * @param view The view to layout.
+     * @param bounds Bounds at which to layout the view.
+     */
+    private void applyLayout(View view, Rect bounds) {
+        view.layout(bounds.left, bounds.top, bounds.right, bounds.bottom);
+        view.setPivotX(mLayoutFromRight ? bounds.right - bounds.left : 0);
+    }
+
+    /**
+     * Measures the preview text bounds, taking preview image padding into
+     * account. This method should only be called after {@link #layoutThumb()}
+     * and {@link #layoutTrack()} have both been called at least once.
+     *
+     * @param v The preview text view to measure.
+     * @param out Rectangle into which measured bounds are placed.
+     */
+    private void measurePreview(View v, Rect out) {
+        // Apply the preview image's padding as layout margins.
+        final Rect margins = mTempMargins;
+        margins.left = mPreviewImage.getPaddingLeft();
+        margins.top = mPreviewImage.getPaddingTop();
+        margins.right = mPreviewImage.getPaddingRight();
+        margins.bottom = mPreviewImage.getPaddingBottom();
+
+        if (mOverlayPosition == OVERLAY_AT_THUMB) {
+            measureViewToSide(v, mThumbImage, margins, out);
+        } else {
+            measureFloating(v, margins, out);
+        }
+    }
+
+    /**
+     * Measures the bounds for a view that should be laid out against the edge
+     * of an adjacent view. If no adjacent view is provided, lays out against
+     * the list edge.
+     *
+     * @param view The view to measure for layout.
+     * @param adjacent (Optional) The adjacent view, may be null to align to the
+     *            list edge.
+     * @param margins Layout margins to apply to the view.
+     * @param out Rectangle into which measured bounds are placed.
+     */
+    private void measureViewToSide(View view, View adjacent, Rect margins, Rect out) {
+        final int marginLeft;
+        final int marginTop;
+        final int marginRight;
+        if (margins == null) {
+            marginLeft = 0;
+            marginTop = 0;
+            marginRight = 0;
+        } else {
+            marginLeft = margins.left;
+            marginTop = margins.top;
+            marginRight = margins.right;
+        }
+
+        final Rect container = mContainerRect;
+        final int containerWidth = container.width();
+        final int maxWidth;
+        if (adjacent == null) {
+            maxWidth = containerWidth;
+        } else if (mLayoutFromRight) {
+            maxWidth = adjacent.getLeft();
+        } else {
+            maxWidth = containerWidth - adjacent.getRight();
+        }
+
+        final int adjMaxWidth = maxWidth - marginLeft - marginRight;
+        final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(adjMaxWidth, MeasureSpec.AT_MOST);
+        final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+        view.measure(widthMeasureSpec, heightMeasureSpec);
+
+        // Align to the left or right.
+        final int width = view.getMeasuredWidth();
+        final int left;
+        final int right;
+        if (mLayoutFromRight) {
+            right = (adjacent == null ? container.right : adjacent.getLeft()) - marginRight;
+            left = right - width;
+        } else {
+            left = (adjacent == null ? container.left : adjacent.getRight()) + marginLeft;
+            right = left + width;
+        }
+
+        // Don't adjust the vertical position.
+        final int top = marginTop;
+        final int bottom = top + view.getMeasuredHeight();
+        out.set(left, top, right, bottom);
+    }
+
+    private void measureFloating(View preview, Rect margins, Rect out) {
+        final int marginLeft;
+        final int marginTop;
+        final int marginRight;
+        if (margins == null) {
+            marginLeft = 0;
+            marginTop = 0;
+            marginRight = 0;
+        } else {
+            marginLeft = margins.left;
+            marginTop = margins.top;
+            marginRight = margins.right;
+        }
+
+        final Rect container = mContainerRect;
+        final int containerWidth = container.width();
+        final int adjMaxWidth = containerWidth - marginLeft - marginRight;
+        final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(adjMaxWidth, MeasureSpec.AT_MOST);
+        final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+        preview.measure(widthMeasureSpec, heightMeasureSpec);
+
+        // Align at the vertical center, 10% from the top.
+        final int containerHeight = container.height();
+        final int width = preview.getMeasuredWidth();
+        final int top = containerHeight / 10 + marginTop + container.top;
+        final int bottom = top + preview.getMeasuredHeight();
+        final int left = (containerWidth - width) / 2 + container.left;
+        final int right = left + width;
+        out.set(left, top, right, bottom);
+    }
+
+    /**
+     * Updates the container rectangle used for layout.
+     */
+    private void updateContainerRect() {
+        final AbsListView list = mList;
+        list.resolvePadding();
+
+        final Rect container = mContainerRect;
+        container.left = 0;
+        container.top = 0;
+        container.right = list.getWidth();
+        container.bottom = list.getHeight();
+
+        final int scrollbarStyle = mScrollBarStyle;
+        if (scrollbarStyle == View.SCROLLBARS_INSIDE_INSET
+                || scrollbarStyle == View.SCROLLBARS_INSIDE_OVERLAY) {
+            container.left += list.getPaddingLeft();
+            container.top += list.getPaddingTop();
+            container.right -= list.getPaddingRight();
+            container.bottom -= list.getPaddingBottom();
+
+            // In inset mode, we need to adjust for padded scrollbar width.
+            if (scrollbarStyle == View.SCROLLBARS_INSIDE_INSET) {
+                final int width = getWidth();
+                if (mScrollbarPosition == View.SCROLLBAR_POSITION_RIGHT) {
+                    container.right += width;
+                } else {
+                    container.left -= width;
+                }
+            }
+        }
+    }
+
+    /**
+     * Lays out the thumb according to the current scrollbar position.
+     */
+    private void layoutThumb() {
+        final Rect bounds = mTempBounds;
+        measureViewToSide(mThumbImage, null, null, bounds);
+        applyLayout(mThumbImage, bounds);
+    }
+
+    /**
+     * Lays out the track centered on the thumb. Must be called after
+     * {@link #layoutThumb}.
+     */
+    private void layoutTrack() {
+        final View track = mTrackImage;
+        final View thumb = mThumbImage;
+        final Rect container = mContainerRect;
+        final int containerWidth = container.width();
+        final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(containerWidth, MeasureSpec.AT_MOST);
+        final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+        track.measure(widthMeasureSpec, heightMeasureSpec);
+
+        final int trackWidth = track.getMeasuredWidth();
+        final int thumbHalfHeight = thumb == null ? 0 : thumb.getHeight() / 2;
+        final int left = thumb.getLeft() + (thumb.getWidth() - trackWidth) / 2;
+        final int right = left + trackWidth;
+        final int top = container.top + thumbHalfHeight;
+        final int bottom = container.bottom - thumbHalfHeight;
+        track.layout(left, top, right, bottom);
+    }
+
+    private void setState(int state) {
+        mList.removeCallbacks(mDeferHide);
+
+        if (mAlwaysShow && state == STATE_NONE) {
+            state = STATE_VISIBLE;
+        }
+
+        if (state == mState) {
+            return;
+        }
+
         switch (state) {
             case STATE_NONE:
-                mHandler.removeCallbacks(mScrollFade);
-                mList.invalidate();
+                transitionToHidden();
                 break;
             case STATE_VISIBLE:
-                if (mState != STATE_VISIBLE) { // Optimization
-                    resetThumbPos();
-                }
-                // Fall through
+                transitionToVisible();
+                break;
             case STATE_DRAGGING:
-                mHandler.removeCallbacks(mScrollFade);
-                break;
-            case STATE_EXIT:
-                final int viewWidth = mList.getWidth();
-                final int top = mThumbY;
-                final int bottom = mThumbY + mThumbH;
-                final int left;
-                final int right;
-                switch (mList.getLayoutDirection()) {
-                    case View.LAYOUT_DIRECTION_RTL:
-                        left = 0;
-                        right = mThumbW;
-                        break;
-                    case View.LAYOUT_DIRECTION_LTR:
-                    default:
-                        left = viewWidth - mThumbW;
-                        right = viewWidth;
-                }
-                mList.invalidate(left, top, right, bottom);
-                break;
-        }
-        mState = state;
-        refreshDrawableState();
-    }
-    
-    public int getState() {
-        return mState;
-    }
-    
-    private void resetThumbPos() {
-        final int viewWidth = mList.getWidth();
-        // Bounds are always top right. Y coordinate get's translated during draw
-        switch (mPosition) {
-            case View.SCROLLBAR_POSITION_RIGHT:
-                mThumbDrawable.setBounds(viewWidth - mThumbW, 0, viewWidth, mThumbH);
-                break;
-            case View.SCROLLBAR_POSITION_LEFT:
-                mThumbDrawable.setBounds(0, 0, mThumbW, mThumbH);
-                break;
-        }
-        mThumbDrawable.setAlpha(ScrollFade.ALPHA_MAX);
-    }
-    
-    private void useThumbDrawable(Context context, Drawable drawable) {
-        mThumbDrawable = drawable;
-        if (drawable instanceof NinePatchDrawable) {
-            mThumbW = context.getResources().getDimensionPixelSize(
-                    com.android.internal.R.dimen.fastscroll_thumb_width);
-            mThumbH = context.getResources().getDimensionPixelSize(
-                    com.android.internal.R.dimen.fastscroll_thumb_height);
-        } else {
-            mThumbW = drawable.getIntrinsicWidth();
-            mThumbH = drawable.getIntrinsicHeight();
-        }
-        mChangedBounds = true;
-    }
-
-    private void init(Context context) {
-        // Get both the scrollbar states drawables
-        TypedArray ta = context.getTheme().obtainStyledAttributes(ATTRS);
-        useThumbDrawable(context, ta.getDrawable(THUMB_DRAWABLE));
-        mTrackDrawable = ta.getDrawable(TRACK_DRAWABLE);
-        
-        mOverlayDrawableLeft = ta.getDrawable(PREVIEW_BACKGROUND_LEFT);
-        mOverlayDrawableRight = ta.getDrawable(PREVIEW_BACKGROUND_RIGHT);
-        mOverlayPosition = ta.getInt(OVERLAY_POSITION, OVERLAY_FLOATING);
-        
-        mScrollCompleted = true;
-
-        getSectionsFromIndexer();
-
-        mOverlaySize = context.getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.fastscroll_overlay_size);
-        mOverlayPos = new RectF();
-        mScrollFade = new ScrollFade();
-        mPaint = new Paint();
-        mPaint.setAntiAlias(true);
-        mPaint.setTextAlign(Paint.Align.CENTER);
-        mPaint.setTextSize(mOverlaySize / 2);
-
-        ColorStateList textColor = ta.getColorStateList(TEXT_COLOR);
-        int textColorNormal = textColor.getDefaultColor();
-        mPaint.setColor(textColorNormal);
-        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
-
-        // to show mOverlayDrawable properly
-        if (mList.getWidth() > 0 && mList.getHeight() > 0) {
-            onSizeChanged(mList.getWidth(), mList.getHeight(), 0, 0);
-        }
-        
-        mState = STATE_NONE;
-        refreshDrawableState();
-
-        ta.recycle();
-
-        mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
-
-        mMatchDragPosition = context.getApplicationInfo().targetSdkVersion >=
-                android.os.Build.VERSION_CODES.HONEYCOMB;
-
-        setScrollbarPosition(mList.getVerticalScrollbarPosition());
-    }
-    
-    void stop() {
-        setState(STATE_NONE);
-    }
-    
-    boolean isVisible() {
-        return !(mState == STATE_NONE);
-    }
-    
-    public void draw(Canvas canvas) {
-        
-        if (mState == STATE_NONE) {
-            // No need to draw anything
-            return;
-        }
-
-        final int y = mThumbY;
-        final int viewWidth = mList.getWidth();
-        final FastScroller.ScrollFade scrollFade = mScrollFade;
-
-        int alpha = -1;
-        if (mState == STATE_EXIT) {
-            alpha = scrollFade.getAlpha();
-            if (alpha < ScrollFade.ALPHA_MAX / 2) {
-                mThumbDrawable.setAlpha(alpha * 2);
-            }
-            int left = 0;
-            switch (mPosition) {
-                case View.SCROLLBAR_POSITION_RIGHT:
-                    left = viewWidth - (mThumbW * alpha) / ScrollFade.ALPHA_MAX;
-                    break;
-                case View.SCROLLBAR_POSITION_LEFT:
-                    left = -mThumbW + (mThumbW * alpha) / ScrollFade.ALPHA_MAX;
-                    break;
-            }
-            mThumbDrawable.setBounds(left, 0, left + mThumbW, mThumbH);
-            mChangedBounds = true;
-        }
-
-        if (mTrackDrawable != null) {
-            final Rect thumbBounds = mThumbDrawable.getBounds();
-            final int left = thumbBounds.left;
-            final int halfThumbHeight = (thumbBounds.bottom - thumbBounds.top) / 2;
-            final int trackWidth = mTrackDrawable.getIntrinsicWidth();
-            final int trackLeft = (left + mThumbW / 2) - trackWidth / 2;
-            mTrackDrawable.setBounds(trackLeft, halfThumbHeight,
-                    trackLeft + trackWidth, mList.getHeight() - halfThumbHeight);
-            mTrackDrawable.draw(canvas);
-        }
-
-        canvas.translate(0, y);
-        mThumbDrawable.draw(canvas);
-        canvas.translate(0, -y);
-
-        // If user is dragging the scroll bar, draw the alphabet overlay
-        if (mState == STATE_DRAGGING && mDrawOverlay) {
-            if (mOverlayPosition == OVERLAY_AT_THUMB) {
-                int left = 0;
-                switch (mPosition) {
-                    default:
-                    case View.SCROLLBAR_POSITION_RIGHT:
-                        left = Math.max(0,
-                                mThumbDrawable.getBounds().left - mThumbW - mOverlaySize);
-                        break;
-                    case View.SCROLLBAR_POSITION_LEFT:
-                        left = Math.min(mThumbDrawable.getBounds().right + mThumbW,
-                                mList.getWidth() - mOverlaySize);
-                        break;
-                }
-
-                int top = Math.max(0,
-                        Math.min(y + (mThumbH - mOverlaySize) / 2, mList.getHeight() - mOverlaySize));
-
-                final RectF pos = mOverlayPos;
-                pos.left = left;
-                pos.right = pos.left + mOverlaySize;
-                pos.top = top;
-                pos.bottom = pos.top + mOverlaySize;
-                if (mOverlayDrawable != null) {
-                    mOverlayDrawable.setBounds((int) pos.left, (int) pos.top,
-                            (int) pos.right, (int) pos.bottom);
-                }
-            }
-            mOverlayDrawable.draw(canvas);
-            final Paint paint = mPaint;
-            float descent = paint.descent();
-            final RectF rectF = mOverlayPos;
-            final Rect tmpRect = mTmpRect;
-            mOverlayDrawable.getPadding(tmpRect);
-            final int hOff = (tmpRect.right - tmpRect.left) / 2;
-            final int vOff = (tmpRect.bottom - tmpRect.top) / 2;
-            canvas.drawText(mSectionText, (int) (rectF.left + rectF.right) / 2 - hOff,
-                    (int) (rectF.bottom + rectF.top) / 2 + mOverlaySize / 4 - descent - vOff,
-                    paint);
-        } else if (mState == STATE_EXIT) {
-            if (alpha == 0) { // Done with exit
-                setState(STATE_NONE);
-            } else {
-                final int left, right, top, bottom;
-                if (mTrackDrawable != null) {
-                    top = 0;
-                    bottom = mList.getHeight();
+                if (transitionPreviewLayout(mCurrentSection)) {
+                    transitionToDragging();
                 } else {
-                    top = y;
-                    bottom = y + mThumbH;
+                    transitionToVisible();
                 }
-                switch (mList.getLayoutDirection()) {
-                    case View.LAYOUT_DIRECTION_RTL:
-                        left = 0;
-                        right = mThumbW;
-                        break;
-                    case View.LAYOUT_DIRECTION_LTR:
-                    default:
-                        left = viewWidth - mThumbW;
-                        right = viewWidth;
-                }
-                mList.invalidate(left, top, right, bottom);
-            }
+                break;
         }
+
+        mState = state;
+
+        refreshDrawablePressedState();
     }
 
-    void onSizeChanged(int w, int h, int oldw, int oldh) {
-        if (mThumbDrawable != null) {
-            switch (mPosition) {
-                default:
-                case View.SCROLLBAR_POSITION_RIGHT:
-                    mThumbDrawable.setBounds(w - mThumbW, 0, w, mThumbH);
-                    break;
-                case View.SCROLLBAR_POSITION_LEFT:
-                    mThumbDrawable.setBounds(0, 0, mThumbW, mThumbH);
-                    break;
-            }
-        }
-        if (mOverlayPosition == OVERLAY_FLOATING) {
-            final RectF pos = mOverlayPos;
-            pos.left = (w - mOverlaySize) / 2;
-            pos.right = pos.left + mOverlaySize;
-            pos.top = h / 10; // 10% from top
-            pos.bottom = pos.top + mOverlaySize;
-            if (mOverlayDrawable != null) {
-                mOverlayDrawable.setBounds((int) pos.left, (int) pos.top,
-                        (int) pos.right, (int) pos.bottom);
-            }
-        }
+    private void refreshDrawablePressedState() {
+        final boolean isPressed = mState == STATE_DRAGGING;
+        mThumbImage.setPressed(isPressed);
+        mTrackImage.setPressed(isPressed);
     }
 
-    void onItemCountChanged(int oldCount, int newCount) {
-        if (mAlwaysShow) {
-            mLongList = true;
+    /**
+     * Shows nothing.
+     */
+    private void transitionToHidden() {
+        if (mDecorAnimation != null) {
+            mDecorAnimation.cancel();
         }
+
+        final Animator fadeOut = groupAnimatorOfFloat(View.ALPHA, 0f, mThumbImage, mTrackImage,
+                mPreviewImage, mPrimaryText, mSecondaryText).setDuration(DURATION_FADE_OUT);
+
+        // Push the thumb and track outside the list bounds.
+        final float offset = mLayoutFromRight ? mThumbImage.getWidth() : -mThumbImage.getWidth();
+        final Animator slideOut = groupAnimatorOfFloat(
+                View.TRANSLATION_X, offset, mThumbImage, mTrackImage)
+                .setDuration(DURATION_FADE_OUT);
+
+        mDecorAnimation = new AnimatorSet();
+        mDecorAnimation.playTogether(fadeOut, slideOut);
+        mDecorAnimation.start();
     }
 
-    void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, 
-            int totalItemCount) {
-        // Are there enough pages to require fast scroll? Recompute only if total count changes
-        if (mItemCount != totalItemCount && visibleItemCount > 0) {
-            mItemCount = totalItemCount;
-            mLongList = mItemCount / visibleItemCount >= MIN_PAGES;
+    /**
+     * Shows the thumb and track.
+     */
+    private void transitionToVisible() {
+        if (mDecorAnimation != null) {
+            mDecorAnimation.cancel();
         }
-        if (mAlwaysShow) {
-            mLongList = true;
+
+        final Animator fadeIn = groupAnimatorOfFloat(View.ALPHA, 1f, mThumbImage, mTrackImage)
+                .setDuration(DURATION_FADE_IN);
+        final Animator fadeOut = groupAnimatorOfFloat(
+                View.ALPHA, 0f, mPreviewImage, mPrimaryText, mSecondaryText)
+                .setDuration(DURATION_FADE_OUT);
+        final Animator slideIn = groupAnimatorOfFloat(
+                View.TRANSLATION_X, 0f, mThumbImage, mTrackImage).setDuration(DURATION_FADE_IN);
+
+        mDecorAnimation = new AnimatorSet();
+        mDecorAnimation.playTogether(fadeIn, fadeOut, slideIn);
+        mDecorAnimation.start();
+    }
+
+    /**
+     * Shows the thumb, preview, and track.
+     */
+    private void transitionToDragging() {
+        if (mDecorAnimation != null) {
+            mDecorAnimation.cancel();
         }
-        if (!mLongList) {
-            if (mState != STATE_NONE) {
-                setState(STATE_NONE);
-            }
+
+        final Animator fadeIn = groupAnimatorOfFloat(
+                View.ALPHA, 1f, mThumbImage, mTrackImage, mPreviewImage)
+                .setDuration(DURATION_FADE_IN);
+        final Animator slideIn = groupAnimatorOfFloat(
+                View.TRANSLATION_X, 0f, mThumbImage, mTrackImage).setDuration(DURATION_FADE_IN);
+
+        mDecorAnimation = new AnimatorSet();
+        mDecorAnimation.playTogether(fadeIn, slideIn);
+        mDecorAnimation.start();
+    }
+
+    private void postAutoHide() {
+        mList.removeCallbacks(mDeferHide);
+        mList.postDelayed(mDeferHide, FADE_TIMEOUT);
+    }
+
+    public void onScroll(int firstVisibleItem, int visibleItemCount, int totalItemCount) {
+        if (!isEnabled()) {
+            setState(STATE_NONE);
             return;
         }
-        if (totalItemCount - visibleItemCount > 0 && mState != STATE_DRAGGING) {
-            mThumbY = getThumbPositionForListPosition(firstVisibleItem, visibleItemCount,
-                    totalItemCount);
-            if (mChangedBounds) {
-                resetThumbPos();
-                mChangedBounds = false;
-            }
+
+        final boolean hasMoreItems = totalItemCount - visibleItemCount > 0;
+        if (hasMoreItems && mState != STATE_DRAGGING) {
+            setThumbPos(getPosFromItemCount(firstVisibleItem, visibleItemCount, totalItemCount));
         }
+
         mScrollCompleted = true;
-        if (firstVisibleItem == mVisibleItem) {
-            return;
-        }
-        mVisibleItem = firstVisibleItem;
-        if (mState != STATE_DRAGGING) {
-            setState(STATE_VISIBLE);
-            if (!mAlwaysShow) {
-                mHandler.postDelayed(mScrollFade, FADE_TIMEOUT);
+
+        if (mFirstVisibleItem != firstVisibleItem) {
+            mFirstVisibleItem = firstVisibleItem;
+
+            // Show the thumb, if necessary, and set up auto-fade.
+            if (mState != STATE_DRAGGING) {
+                setState(STATE_VISIBLE);
+                postAutoHide();
             }
         }
     }
 
-    SectionIndexer getSectionIndexer() {
-        return mSectionIndexer;
-    }
-
-    Object[] getSections() {
-        if (mListAdapter == null && mList != null) {
-            getSectionsFromIndexer();
-        }
-        return mSections;
-    }
-
-    void getSectionsFromIndexer() {
-        Adapter adapter = mList.getAdapter();
+    private void getSectionsFromIndexer() {
         mSectionIndexer = null;
+
+        Adapter adapter = mList.getAdapter();
         if (adapter instanceof HeaderViewListAdapter) {
-            mListOffset = ((HeaderViewListAdapter)adapter).getHeadersCount();
-            adapter = ((HeaderViewListAdapter)adapter).getWrappedAdapter();
+            mHeaderCount = ((HeaderViewListAdapter) adapter).getHeadersCount();
+            adapter = ((HeaderViewListAdapter) adapter).getWrappedAdapter();
         }
+
         if (adapter instanceof ExpandableListConnector) {
-            ExpandableListAdapter expAdapter = ((ExpandableListConnector)adapter).getAdapter();
+            final ExpandableListAdapter expAdapter = ((ExpandableListConnector) adapter)
+                    .getAdapter();
             if (expAdapter instanceof SectionIndexer) {
                 mSectionIndexer = (SectionIndexer) expAdapter;
                 mListAdapter = (BaseAdapter) adapter;
                 mSections = mSectionIndexer.getSections();
             }
+        } else if (adapter instanceof SectionIndexer) {
+            mListAdapter = (BaseAdapter) adapter;
+            mSectionIndexer = (SectionIndexer) adapter;
+            mSections = mSectionIndexer.getSections();
         } else {
-            if (adapter instanceof SectionIndexer) {
-                mListAdapter = (BaseAdapter) adapter;
-                mSectionIndexer = (SectionIndexer) adapter;
-                mSections = mSectionIndexer.getSections();
-                if (mSections == null) {
-                    mSections = new String[] { " " };
-                }
-            } else {
-                mListAdapter = (BaseAdapter) adapter;
-                mSections = new String[] { " " };
-            }
+            mListAdapter = (BaseAdapter) adapter;
+            mSections = null;
         }
     }
 
@@ -548,21 +871,24 @@
         mListAdapter = null;
     }
 
-    void scrollTo(float position) {
-        int count = mList.getCount();
+    /**
+     * Scrolls to a specific position within the section
+     * @param position
+     */
+    private void scrollTo(float position) {
         mScrollCompleted = false;
-        float fThreshold = (1.0f / count) / 8;
+
+        final int count = mList.getCount();
         final Object[] sections = mSections;
+        final int sectionCount = sections == null ? 0 : sections.length;
         int sectionIndex;
-        if (sections != null && sections.length > 1) {
-            final int nSections = sections.length;
-            int section = (int) (position * nSections);
-            if (section >= nSections) {
-                section = nSections - 1;
-            }
-            int exactSection = section;
-            sectionIndex = section;
-            int index = mSectionIndexer.getPositionForSection(section);
+        if (sections != null && sectionCount > 1) {
+            final int exactSection = MathUtils.constrain(
+                    (int) (position * sectionCount), 0, sectionCount - 1);
+            int targetSection = exactSection;
+            int targetIndex = mSectionIndexer.getPositionForSection(targetSection);
+            sectionIndex = targetSection;
+
             // Given the expected section and index, the following code will
             // try to account for missing sections (no names starting with..)
             // It will compute the scroll space of surrounding empty sections
@@ -570,25 +896,26 @@
             // available space, so that there is always some list movement while
             // the user moves the thumb.
             int nextIndex = count;
-            int prevIndex = index;
-            int prevSection = section;
-            int nextSection = section + 1;
+            int prevIndex = targetIndex;
+            int prevSection = targetSection;
+            int nextSection = targetSection + 1;
+
             // Assume the next section is unique
-            if (section < nSections - 1) {
-                nextIndex = mSectionIndexer.getPositionForSection(section + 1);
+            if (targetSection < sectionCount - 1) {
+                nextIndex = mSectionIndexer.getPositionForSection(targetSection + 1);
             }
-            
+
             // Find the previous index if we're slicing the previous section
-            if (nextIndex == index) {
+            if (nextIndex == targetIndex) {
                 // Non-existent letter
-                while (section > 0) {
-                    section--;
-                    prevIndex = mSectionIndexer.getPositionForSection(section);
-                    if (prevIndex != index) {
-                        prevSection = section;
-                        sectionIndex = section;
+                while (targetSection > 0) {
+                    targetSection--;
+                    prevIndex = mSectionIndexer.getPositionForSection(targetSection);
+                    if (prevIndex != targetIndex) {
+                        prevSection = targetSection;
+                        sectionIndex = targetSection;
                         break;
-                    } else if (section == 0) {
+                    } else if (targetSection == 0) {
                         // When section reaches 0 here, sectionIndex must follow it.
                         // Assuming mSectionIndexer.getPositionForSection(0) == 0.
                         sectionIndex = 0;
@@ -596,136 +923,305 @@
                     }
                 }
             }
+
             // Find the next index, in case the assumed next index is not
-            // unique. For instance, if there is no P, then request for P's 
+            // unique. For instance, if there is no P, then request for P's
             // position actually returns Q's. So we need to look ahead to make
-            // sure that there is really a Q at Q's position. If not, move 
+            // sure that there is really a Q at Q's position. If not, move
             // further down...
             int nextNextSection = nextSection + 1;
-            while (nextNextSection < nSections &&
+            while (nextNextSection < sectionCount &&
                     mSectionIndexer.getPositionForSection(nextNextSection) == nextIndex) {
                 nextNextSection++;
                 nextSection++;
             }
+
             // Compute the beginning and ending scroll range percentage of the
-            // currently visible letter. This could be equal to or greater than
-            // (1 / nSections). 
-            float fPrev = (float) prevSection / nSections;
-            float fNext = (float) nextSection / nSections;
-            if (prevSection == exactSection && position - fPrev < fThreshold) {
-                index = prevIndex;
+            // currently visible section. This could be equal to or greater than
+            // (1 / nSections). If the target position is near the previous
+            // position, snap to the previous position.
+            final float prevPosition = (float) prevSection / sectionCount;
+            final float nextPosition = (float) nextSection / sectionCount;
+            final float snapThreshold = (count == 0) ? Float.MAX_VALUE : .125f / count;
+            if (prevSection == exactSection && position - prevPosition < snapThreshold) {
+                targetIndex = prevIndex;
             } else {
-                index = prevIndex + (int) ((nextIndex - prevIndex) * (position - fPrev) 
-                    / (fNext - fPrev));
+                targetIndex = prevIndex + (int) ((nextIndex - prevIndex) * (position - prevPosition)
+                    / (nextPosition - prevPosition));
             }
-            // Don't overflow
-            if (index > count - 1) index = count - 1;
-            
+
+            // Clamp to valid positions.
+            targetIndex = MathUtils.constrain(targetIndex, 0, count - 1);
+
             if (mList instanceof ExpandableListView) {
-                ExpandableListView expList = (ExpandableListView) mList;
+                final ExpandableListView expList = (ExpandableListView) mList;
                 expList.setSelectionFromTop(expList.getFlatListPosition(
-                        ExpandableListView.getPackedPositionForGroup(index + mListOffset)), 0);
+                        ExpandableListView.getPackedPositionForGroup(targetIndex + mHeaderCount)),
+                        0);
             } else if (mList instanceof ListView) {
-                ((ListView)mList).setSelectionFromTop(index + mListOffset, 0);
+                ((ListView) mList).setSelectionFromTop(targetIndex + mHeaderCount, 0);
             } else {
-                mList.setSelection(index + mListOffset);
+                mList.setSelection(targetIndex + mHeaderCount);
             }
         } else {
-            int index = (int) (position * count);
-            // Don't overflow
-            if (index > count - 1) index = count - 1;
+            final int index = MathUtils.constrain((int) (position * count), 0, count - 1);
 
             if (mList instanceof ExpandableListView) {
                 ExpandableListView expList = (ExpandableListView) mList;
                 expList.setSelectionFromTop(expList.getFlatListPosition(
-                        ExpandableListView.getPackedPositionForGroup(index + mListOffset)), 0);
+                        ExpandableListView.getPackedPositionForGroup(index + mHeaderCount)), 0);
             } else if (mList instanceof ListView) {
-                ((ListView)mList).setSelectionFromTop(index + mListOffset, 0);
+                ((ListView)mList).setSelectionFromTop(index + mHeaderCount, 0);
             } else {
-                mList.setSelection(index + mListOffset);
+                mList.setSelection(index + mHeaderCount);
             }
+
             sectionIndex = -1;
         }
 
-        if (sectionIndex >= 0) {
-            String text = mSectionText = sections[sectionIndex].toString();
-            mDrawOverlay = (text.length() != 1 || text.charAt(0) != ' ') &&
-                    sectionIndex < sections.length;
-        } else {
-            mDrawOverlay = false;
+        if (mCurrentSection != sectionIndex) {
+            mCurrentSection = sectionIndex;
+
+            if (transitionPreviewLayout(sectionIndex)) {
+                transitionToDragging();
+            } else {
+                transitionToVisible();
+            }
         }
     }
 
-    private int getThumbPositionForListPosition(int firstVisibleItem, int visibleItemCount,
-            int totalItemCount) {
+    /**
+     * Transitions the preview text to a new section. Handles animation,
+     * measurement, and layout. If the new preview text is empty, returns false.
+     *
+     * @param sectionIndex The section index to which the preview should
+     *            transition.
+     * @return False if the new preview text is empty.
+     */
+    private boolean transitionPreviewLayout(int sectionIndex) {
+        final Object[] sections = mSections;
+        String text = null;
+        if (sections != null && sectionIndex >= 0 && sectionIndex < sections.length) {
+            final Object section = sections[sectionIndex];
+            if (section != null) {
+                text = section.toString();
+            }
+        }
+
+        final Rect bounds = mTempBounds;
+        final ImageView preview = mPreviewImage;
+        final TextView showing;
+        final TextView target;
+        if (mShowingPrimary) {
+            showing = mPrimaryText;
+            target = mSecondaryText;
+        } else {
+            showing = mSecondaryText;
+            target = mPrimaryText;
+        }
+
+        // Set and layout target immediately.
+        target.setText(text);
+        measurePreview(target, bounds);
+        applyLayout(target, bounds);
+
+        if (mPreviewAnimation != null) {
+            mPreviewAnimation.cancel();
+        }
+
+        // Cross-fade preview text.
+        final Animator showTarget = animateAlpha(target, 1f).setDuration(DURATION_CROSS_FADE);
+        final Animator hideShowing = animateAlpha(showing, 0f).setDuration(DURATION_CROSS_FADE);
+        hideShowing.addListener(mSwitchPrimaryListener);
+
+        // Apply preview image padding and animate bounds, if necessary.
+        bounds.left -= mPreviewImage.getPaddingLeft();
+        bounds.top -= mPreviewImage.getPaddingTop();
+        bounds.right += mPreviewImage.getPaddingRight();
+        bounds.bottom += mPreviewImage.getPaddingBottom();
+        final Animator resizePreview = animateBounds(preview, bounds);
+        resizePreview.setDuration(DURATION_RESIZE);
+
+        mPreviewAnimation = new AnimatorSet();
+        final AnimatorSet.Builder builder = mPreviewAnimation.play(hideShowing).with(showTarget);
+        builder.with(resizePreview);
+
+        // The current preview size is unaffected by hidden or showing. It's
+        // used to set starting scales for things that need to be scaled down.
+        final int previewWidth = preview.getWidth() - preview.getPaddingLeft()
+                - preview.getPaddingRight();
+
+        // If target is too large, shrink it immediately to fit and expand to
+        // target size. Otherwise, start at target size.
+        final int targetWidth = target.getWidth();
+        if (targetWidth > previewWidth) {
+            target.setScaleX((float) previewWidth / targetWidth);
+            final Animator scaleAnim = animateScaleX(target, 1f).setDuration(DURATION_RESIZE);
+            builder.with(scaleAnim);
+        } else {
+            target.setScaleX(1f);
+        }
+
+        // If showing is larger than target, shrink to target size.
+        final int showingWidth = showing.getWidth();
+        if (showingWidth > targetWidth) {
+            final float scale = (float) targetWidth / showingWidth;
+            final Animator scaleAnim = animateScaleX(showing, scale).setDuration(DURATION_RESIZE);
+            builder.with(scaleAnim);
+        }
+
+        mPreviewAnimation.start();
+
+        return (text != null && text.length() > 0);
+    }
+
+    /**
+     * Positions the thumb and preview widgets.
+     *
+     * @param position The position, between 0 and 1, along the track at which
+     *            to place the thumb.
+     */
+    private void setThumbPos(float position) {
+        final Rect container = mContainerRect;
+        final int top = container.top;
+        final int bottom = container.bottom;
+
+        final ImageView trackImage = mTrackImage;
+        final ImageView thumbImage = mThumbImage;
+        final float min = trackImage.getTop();
+        final float max = trackImage.getBottom();
+        final float offset = min;
+        final float range = max - min;
+        final float thumbMiddle = position * range + offset;
+        thumbImage.setTranslationY(thumbMiddle - thumbImage.getHeight() / 2);
+
+        // Center the preview on the thumb, constrained to the list bounds.
+        final ImageView previewImage = mPreviewImage;
+        final float previewHalfHeight = previewImage.getHeight() / 2f;
+        final float minP = top + previewHalfHeight;
+        final float maxP = bottom - previewHalfHeight;
+        final float previewMiddle = MathUtils.constrain(thumbMiddle, minP, maxP);
+        final float previewTop = previewMiddle - previewHalfHeight;
+        previewImage.setTranslationY(previewTop);
+
+        mPrimaryText.setTranslationY(previewTop);
+        mSecondaryText.setTranslationY(previewTop);
+    }
+
+    private float getPosFromMotionEvent(float y) {
+        final Rect container = mContainerRect;
+        final int top = container.top;
+        final int bottom = container.bottom;
+
+        final ImageView trackImage = mTrackImage;
+        final float min = trackImage.getTop();
+        final float max = trackImage.getBottom();
+        final float offset = min;
+        final float range = max - min;
+
+        // If the list is the same height as the thumbnail or shorter,
+        // effectively disable scrolling.
+        if (range <= 0) {
+            return 0f;
+        }
+
+        return MathUtils.constrain((y - offset) / range, 0f, 1f);
+    }
+
+    private float getPosFromItemCount(
+            int firstVisibleItem, int visibleItemCount, int totalItemCount) {
         if (mSectionIndexer == null || mListAdapter == null) {
             getSectionsFromIndexer();
         }
-        if (mSectionIndexer == null || !mMatchDragPosition) {
-            return ((mList.getHeight() - mThumbH) * firstVisibleItem)
-                    / (totalItemCount - visibleItemCount);
+
+        final boolean hasSections = mSectionIndexer != null && mSections != null
+                && mSections.length > 0;
+        if (!hasSections || !mMatchDragPosition) {
+            return (float) firstVisibleItem / (totalItemCount - visibleItemCount);
         }
 
-        firstVisibleItem -= mListOffset;
+        // Ignore headers.
+        firstVisibleItem -= mHeaderCount;
         if (firstVisibleItem < 0) {
             return 0;
         }
-        totalItemCount -= mListOffset;
+        totalItemCount -= mHeaderCount;
 
-        final int trackHeight = mList.getHeight() - mThumbH;
+        // Hidden portion of the first visible row.
+        final View child = mList.getChildAt(0);
+        final float incrementalPos;
+        if (child == null || child.getHeight() == 0) {
+            incrementalPos = 0;
+        } else {
+            incrementalPos = (float) (mList.getPaddingTop() - child.getTop()) / child.getHeight();
+        }
 
+        // Number of rows in this section.
         final int section = mSectionIndexer.getSectionForPosition(firstVisibleItem);
         final int sectionPos = mSectionIndexer.getPositionForSection(section);
-        final int nextSectionPos;
         final int sectionCount = mSections.length;
-        if (section + 1 < sectionCount) {
-            nextSectionPos = mSectionIndexer.getPositionForSection(section + 1);
+        final int positionsInSection;
+        if (section < sectionCount - 1) {
+            final int nextSectionPos;
+            if (section + 1 < sectionCount) {
+                nextSectionPos = mSectionIndexer.getPositionForSection(section + 1);
+            } else {
+                nextSectionPos = totalItemCount - 1;
+            }
+            positionsInSection = nextSectionPos - sectionPos;
         } else {
-            nextSectionPos = totalItemCount - 1;
-        }
-        final int positionsInSection = nextSectionPos - sectionPos;
-
-        final View child = mList.getChildAt(0);
-        final float incrementalPos = child == null ? 0 : firstVisibleItem +
-                (float) (mList.getPaddingTop() - child.getTop()) / child.getHeight();
-        final float posWithinSection = (incrementalPos - sectionPos) / positionsInSection;
-        int result = (int) ((section + posWithinSection) / sectionCount * trackHeight);
-
-        // Fake out the scrollbar for the last item. Since the section indexer won't
-        // ever actually move the list in this end space, make scrolling across the last item
-        // account for whatever space is remaining.
-        if (firstVisibleItem > 0 && firstVisibleItem + visibleItemCount == totalItemCount) {
-            final View lastChild = mList.getChildAt(visibleItemCount - 1);
-            final float lastItemVisible = (float) (mList.getHeight() - mList.getPaddingBottom()
-                    - lastChild.getTop()) / lastChild.getHeight();
-            result += (trackHeight - result) * lastItemVisible;
+            positionsInSection = totalItemCount - sectionPos;
         }
 
-        return result;
+        // Position within this section.
+        final float posWithinSection;
+        if (positionsInSection == 0) {
+            posWithinSection = 0;
+        } else {
+            posWithinSection = (firstVisibleItem + incrementalPos - sectionPos)
+                    / positionsInSection;
+        }
+
+        return (section + posWithinSection) / sectionCount;
     }
 
+    /**
+     * Cancels an ongoing fling event by injecting a
+     * {@link MotionEvent#ACTION_CANCEL} into the host view.
+     */
     private void cancelFling() {
-        // Cancel the list fling
-        MotionEvent cancelFling = MotionEvent.obtain(0, 0, MotionEvent.ACTION_CANCEL, 0, 0, 0);
+        final MotionEvent cancelFling = MotionEvent.obtain(
+                0, 0, MotionEvent.ACTION_CANCEL, 0, 0, 0);
         mList.onTouchEvent(cancelFling);
         cancelFling.recycle();
     }
-    
-    void cancelPendingDrag() {
+
+    /**
+     * Cancels a pending drag.
+     *
+     * @see #startPendingDrag()
+     */
+    private void cancelPendingDrag() {
         mList.removeCallbacks(mDeferStartDrag);
-        mPendingDrag = false;
+        mHasPendingDrag = false;
     }
 
-    void startPendingDrag() {
-        mPendingDrag = true;
-        mList.postDelayed(mDeferStartDrag, PENDING_DRAG_DELAY);
+    /**
+     * Delays dragging until after the framework has determined that the user is
+     * scrolling, rather than tapping.
+     */
+    private void startPendingDrag() {
+        mHasPendingDrag = true;
+        mList.postDelayed(mDeferStartDrag, TAP_TIMEOUT);
     }
 
-    void beginDrag() {
+    private void beginDrag() {
         setState(STATE_DRAGGING);
+
         if (mListAdapter == null && mList != null) {
             getSectionsFromIndexer();
         }
+
         if (mList != null) {
             mList.requestDisallowInterceptTouchEvent(true);
             mList.reportScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
@@ -734,87 +1230,101 @@
         cancelFling();
     }
 
-    boolean onInterceptTouchEvent(MotionEvent ev) {
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        if (!isEnabled()) {
+            return false;
+        }
+
         switch (ev.getActionMasked()) {
             case MotionEvent.ACTION_DOWN:
-                if (mState > STATE_NONE && isPointInside(ev.getX(), ev.getY())) {
+                if (isPointInside(ev.getX(), ev.getY())) {
+                    // If the parent has requested that its children delay
+                    // pressed state (e.g. is a scrolling container) then we
+                    // need to allow the parent time to decide whether it wants
+                    // to intercept events. If it does, we will receive a CANCEL
+                    // event.
                     if (!mList.isInScrollingContainer()) {
                         beginDrag();
                         return true;
                     }
+
                     mInitialTouchY = ev.getY();
                     startPendingDrag();
                 }
                 break;
+            case MotionEvent.ACTION_MOVE:
+                if (!isPointInside(ev.getX(), ev.getY())) {
+                    cancelPendingDrag();
+                }
+                break;
             case MotionEvent.ACTION_UP:
             case MotionEvent.ACTION_CANCEL:
                 cancelPendingDrag();
                 break;
         }
+
         return false;
     }
 
-    boolean onTouchEvent(MotionEvent me) {
-        if (mState == STATE_NONE) {
+    public boolean onInterceptHoverEvent(MotionEvent ev) {
+        if (!isEnabled()) {
             return false;
         }
 
-        final int action = me.getAction();
+        final int actionMasked = ev.getActionMasked();
+        if ((actionMasked == MotionEvent.ACTION_HOVER_ENTER
+                || actionMasked == MotionEvent.ACTION_HOVER_MOVE) && mState == STATE_NONE
+                && isPointInside(ev.getX(), ev.getY())) {
+            setState(STATE_VISIBLE);
+            postAutoHide();
+        }
 
-        if (action == MotionEvent.ACTION_DOWN) {
-            if (isPointInside(me.getX(), me.getY())) {
-                if (!mList.isInScrollingContainer()) {
+        return false;
+    }
+
+    public boolean onTouchEvent(MotionEvent me) {
+        if (!isEnabled()) {
+            return false;
+        }
+
+        switch (me.getActionMasked()) {
+            case MotionEvent.ACTION_UP: {
+                if (mHasPendingDrag) {
+                    // Allow a tap to scroll.
                     beginDrag();
+
+                    final float pos = getPosFromMotionEvent(me.getY());
+                    setThumbPos(pos);
+                    scrollTo(pos);
+
+                    cancelPendingDrag();
+                    // Will hit the STATE_DRAGGING check below
+                }
+
+                if (mState == STATE_DRAGGING) {
+                    if (mList != null) {
+                        // ViewGroup does the right thing already, but there might
+                        // be other classes that don't properly reset on touch-up,
+                        // so do this explicitly just in case.
+                        mList.requestDisallowInterceptTouchEvent(false);
+                        mList.reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
+                    }
+
+                    setState(STATE_VISIBLE);
+                    postAutoHide();
+
                     return true;
                 }
-                mInitialTouchY = me.getY();
-                startPendingDrag();
-            }
-        } else if (action == MotionEvent.ACTION_UP) { // don't add ACTION_CANCEL here
-            if (mPendingDrag) {
-                // Allow a tap to scroll.
-                beginDrag();
+            } break;
 
-                final int viewHeight = mList.getHeight();
-                // Jitter
-                int newThumbY = (int) me.getY() - mThumbH + 10;
-                if (newThumbY < 0) {
-                    newThumbY = 0;
-                } else if (newThumbY + mThumbH > viewHeight) {
-                    newThumbY = viewHeight - mThumbH;
-                }
-                mThumbY = newThumbY;
-                scrollTo((float) mThumbY / (viewHeight - mThumbH));
-
-                cancelPendingDrag();
-                // Will hit the STATE_DRAGGING check below
-            }
-            if (mState == STATE_DRAGGING) {
-                if (mList != null) {
-                    // ViewGroup does the right thing already, but there might
-                    // be other classes that don't properly reset on touch-up,
-                    // so do this explicitly just in case.
-                    mList.requestDisallowInterceptTouchEvent(false);
-                    mList.reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
-                }
-                setState(STATE_VISIBLE);
-                final Handler handler = mHandler;
-                handler.removeCallbacks(mScrollFade);
-                if (!mAlwaysShow) {
-                    handler.postDelayed(mScrollFade, 1000);
-                }
-
-                mList.invalidate();
-                return true;
-            }
-        } else if (action == MotionEvent.ACTION_MOVE) {
-            if (mPendingDrag) {
-                final float y = me.getY();
-                if (Math.abs(y - mInitialTouchY) > mScaledTouchSlop) {
+            case MotionEvent.ACTION_MOVE: {
+                if (mHasPendingDrag && Math.abs(me.getY() - mInitialTouchY) > mScaledTouchSlop) {
                     setState(STATE_DRAGGING);
+
                     if (mListAdapter == null && mList != null) {
                         getSectionsFromIndexer();
                     }
+
                     if (mList != null) {
                         mList.requestDisallowInterceptTouchEvent(true);
                         mList.reportScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
@@ -824,86 +1334,168 @@
                     cancelPendingDrag();
                     // Will hit the STATE_DRAGGING check below
                 }
-            }
-            if (mState == STATE_DRAGGING) {
-                final int viewHeight = mList.getHeight();
-                // Jitter
-                int newThumbY = (int) me.getY() - mThumbH + 10;
-                if (newThumbY < 0) {
-                    newThumbY = 0;
-                } else if (newThumbY + mThumbH > viewHeight) {
-                    newThumbY = viewHeight - mThumbH;
-                }
-                if (Math.abs(mThumbY - newThumbY) < 2) {
+
+                if (mState == STATE_DRAGGING) {
+                    // TODO: Ignore jitter.
+                    final float pos = getPosFromMotionEvent(me.getY());
+                    setThumbPos(pos);
+
+                    // If the previous scrollTo is still pending
+                    if (mScrollCompleted) {
+                        scrollTo(pos);
+                    }
+
                     return true;
                 }
-                mThumbY = newThumbY;
-                // If the previous scrollTo is still pending
-                if (mScrollCompleted) {
-                    scrollTo((float) mThumbY / (viewHeight - mThumbH));
-                }
-                return true;
-            }
-        } else if (action == MotionEvent.ACTION_CANCEL) {
-            cancelPendingDrag();
+            } break;
+
+            case MotionEvent.ACTION_CANCEL: {
+                cancelPendingDrag();
+            } break;
         }
+
         return false;
     }
 
-    boolean isPointInside(float x, float y) {
-        boolean inTrack = false;
-        switch (mPosition) {
-            default:
-            case View.SCROLLBAR_POSITION_RIGHT:
-                inTrack = x > mList.getWidth() - mThumbW;
-                break;
-            case View.SCROLLBAR_POSITION_LEFT:
-                inTrack = x < mThumbW;
-                break;
-        }
-
-        // Allow taps in the track to start moving.
-        return inTrack && (mTrackDrawable != null || y >= mThumbY && y <= mThumbY + mThumbH);
+    /**
+     * Returns whether a coordinate is inside the scroller's activation area. If
+     * there is a track image, touching anywhere within the thumb-width of the
+     * track activates scrolling. Otherwise, the user has to touch inside thumb
+     * itself.
+     *
+     * @param x The x-coordinate.
+     * @param y The y-coordinate.
+     * @return Whether the coordinate is inside the scroller's activation area.
+     */
+    private boolean isPointInside(float x, float y) {
+        return isPointInsideX(x) && (mHasTrackImage || isPointInsideY(y));
     }
 
-    public class ScrollFade implements Runnable {
-        
-        long mStartTime;
-        long mFadeDuration;
-        static final int ALPHA_MAX = 208;
-        static final long FADE_DURATION = 200;
-        
-        void startFade() {
-            mFadeDuration = FADE_DURATION;
-            mStartTime = SystemClock.uptimeMillis();
-            setState(STATE_EXIT);
+    private boolean isPointInsideX(float x) {
+        if (mLayoutFromRight) {
+            return x >= mThumbImage.getLeft();
+        } else {
+            return x <= mThumbImage.getRight();
         }
-        
-        int getAlpha() {
-            if (getState() != STATE_EXIT) {
-                return ALPHA_MAX;
-            }
-            int alpha;
-            long now = SystemClock.uptimeMillis();
-            if (now > mStartTime + mFadeDuration) {
-                alpha = 0;
+    }
+
+    private boolean isPointInsideY(float y) {
+        return y >= mThumbImage.getTop() && y <= mThumbImage.getBottom();
+    }
+
+    /**
+     * Constructs an animator for the specified property on a group of views.
+     * See {@link ObjectAnimator#ofFloat(Object, String, float...)} for
+     * implementation details.
+     *
+     * @param property The property being animated.
+     * @param value The value to which that property should animate.
+     * @param views The target views to animate.
+     * @return An animator for all the specified views.
+     */
+    private static Animator groupAnimatorOfFloat(
+            Property<View, Float> property, float value, View... views) {
+        AnimatorSet animSet = new AnimatorSet();
+        AnimatorSet.Builder builder = null;
+
+        for (int i = views.length - 1; i >= 0; i--) {
+            final Animator anim = ObjectAnimator.ofFloat(views[i], property, value);
+            if (builder == null) {
+                builder = animSet.play(anim);
             } else {
-                alpha = (int) (ALPHA_MAX - ((now - mStartTime) * ALPHA_MAX) / mFadeDuration); 
-            }
-            return alpha;
-        }
-        
-        public void run() {
-            if (getState() != STATE_EXIT) {
-                startFade();
-                return;
-            }
-            
-            if (getAlpha() > 0) {
-                mList.invalidate();
-            } else {
-                setState(STATE_NONE);
+                builder.with(anim);
             }
         }
+
+        return animSet;
+    }
+
+    /**
+     * Returns an animator for the view's scaleX value.
+     */
+    private static Animator animateScaleX(View v, float target) {
+        return ObjectAnimator.ofFloat(v, View.SCALE_X, target);
+    }
+
+    /**
+     * Returns an animator for the view's alpha value.
+     */
+    private static Animator animateAlpha(View v, float alpha) {
+        return ObjectAnimator.ofFloat(v, View.ALPHA, alpha);
+    }
+
+    /**
+     * A Property wrapper around the <code>left</code> functionality handled by the
+     * {@link View#setLeft(int)} and {@link View#getLeft()} methods.
+     */
+    private static Property<View, Integer> LEFT = new IntProperty<View>("left") {
+        @Override
+        public void setValue(View object, int value) {
+            object.setLeft(value);
+        }
+
+        @Override
+        public Integer get(View object) {
+            return object.getLeft();
+        }
+    };
+
+    /**
+     * A Property wrapper around the <code>top</code> functionality handled by the
+     * {@link View#setTop(int)} and {@link View#getTop()} methods.
+     */
+    private static Property<View, Integer> TOP = new IntProperty<View>("top") {
+        @Override
+        public void setValue(View object, int value) {
+            object.setTop(value);
+        }
+
+        @Override
+        public Integer get(View object) {
+            return object.getTop();
+        }
+    };
+
+    /**
+     * A Property wrapper around the <code>right</code> functionality handled by the
+     * {@link View#setRight(int)} and {@link View#getRight()} methods.
+     */
+    private static Property<View, Integer> RIGHT = new IntProperty<View>("right") {
+        @Override
+        public void setValue(View object, int value) {
+            object.setRight(value);
+        }
+
+        @Override
+        public Integer get(View object) {
+            return object.getRight();
+        }
+    };
+
+    /**
+     * A Property wrapper around the <code>bottom</code> functionality handled by the
+     * {@link View#setBottom(int)} and {@link View#getBottom()} methods.
+     */
+    private static Property<View, Integer> BOTTOM = new IntProperty<View>("bottom") {
+        @Override
+        public void setValue(View object, int value) {
+            object.setBottom(value);
+        }
+
+        @Override
+        public Integer get(View object) {
+            return object.getBottom();
+        }
+    };
+
+    /**
+     * Returns an animator for the view's bounds.
+     */
+    private static Animator animateBounds(View v, Rect bounds) {
+        final PropertyValuesHolder left = PropertyValuesHolder.ofInt(LEFT, bounds.left);
+        final PropertyValuesHolder top = PropertyValuesHolder.ofInt(TOP, bounds.top);
+        final PropertyValuesHolder right = PropertyValuesHolder.ofInt(RIGHT, bounds.right);
+        final PropertyValuesHolder bottom = PropertyValuesHolder.ofInt(BOTTOM, bounds.bottom);
+        return ObjectAnimator.ofPropertyValuesHolder(v, left, top, right, bottom);
     }
 }
diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java
index 738f63b..d9d4ad7 100644
--- a/core/java/android/widget/FrameLayout.java
+++ b/core/java/android/widget/FrameLayout.java
@@ -267,12 +267,12 @@
         return mForeground;
     }
 
-    private int getPaddingLeftWithForeground() {
+    int getPaddingLeftWithForeground() {
         return mForegroundInPadding ? Math.max(mPaddingLeft, mForegroundPaddingLeft) :
             mPaddingLeft + mForegroundPaddingLeft;
     }
 
-    private int getPaddingRightWithForeground() {
+    int getPaddingRightWithForeground() {
         return mForegroundInPadding ? Math.max(mPaddingRight, mForegroundPaddingRight) :
             mPaddingRight + mForegroundPaddingRight;
     }
@@ -385,6 +385,11 @@
      */
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        layoutChildren(left, top, right, bottom, false /* no force left gravity */);
+    }
+
+    void layoutChildren(int left, int top, int right, int bottom,
+                                  boolean forceLeftGravity) {
         final int count = getChildCount();
 
         final int parentLeft = getPaddingLeftWithForeground();
@@ -416,16 +421,16 @@
                 final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
 
                 switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
-                    case Gravity.LEFT:
-                        childLeft = parentLeft + lp.leftMargin;
-                        break;
                     case Gravity.CENTER_HORIZONTAL:
                         childLeft = parentLeft + (parentRight - parentLeft - width) / 2 +
                         lp.leftMargin - lp.rightMargin;
                         break;
                     case Gravity.RIGHT:
-                        childLeft = parentRight - width - lp.rightMargin;
-                        break;
+                        if (!forceLeftGravity) {
+                            childLeft = parentRight - width - lp.rightMargin;
+                            break;
+                        }
+                    case Gravity.LEFT:
                     default:
                         childLeft = parentLeft + lp.leftMargin;
                 }
@@ -651,5 +656,17 @@
         public LayoutParams(ViewGroup.MarginLayoutParams source) {
             super(source);
         }
+
+        /**
+         * Copy constructor. Clones the width, height, margin values, and
+         * gravity of the source.
+         *
+         * @param source The layout params to copy from.
+         */
+        public LayoutParams(LayoutParams source) {
+            super(source);
+
+            this.gravity = source.gravity;
+        }
     }
 }
diff --git a/core/java/android/widget/Gallery.java b/core/java/android/widget/Gallery.java
index c4ef11c..78ba6e0 100644
--- a/core/java/android/widget/Gallery.java
+++ b/core/java/android/widget/Gallery.java
@@ -1228,13 +1228,9 @@
 
     @Override
     public boolean onKeyUp(int keyCode, KeyEvent event) {
-        switch (keyCode) {
-        case KeyEvent.KEYCODE_DPAD_CENTER:
-        case KeyEvent.KEYCODE_ENTER: {
-            
+        if (KeyEvent.isConfirmKey(keyCode)) {
             if (mReceivedInvokeKeyDown) {
                 if (mItemCount > 0) {
-    
                     dispatchPress(mSelectedChild);
                     postDelayed(new Runnable() {
                         @Override
@@ -1242,20 +1238,17 @@
                             dispatchUnpress();
                         }
                     }, ViewConfiguration.getPressedStateDuration());
-    
+
                     int selectedIndex = mSelectedPosition - mFirstPosition;
                     performItemClick(getChildAt(selectedIndex), mSelectedPosition, mAdapter
                             .getItemId(mSelectedPosition));
                 }
             }
-            
+
             // Clear the flag
             mReceivedInvokeKeyDown = false;
-            
             return true;
         }
-        }
-
         return super.onKeyUp(keyCode, event);
     }
     
diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java
index 2309001..54cc3f4 100644
--- a/core/java/android/widget/GridLayout.java
+++ b/core/java/android/widget/GridLayout.java
@@ -24,7 +24,9 @@
 import android.graphics.Paint;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.util.LogPrinter;
 import android.util.Pair;
+import android.util.Printer;
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
@@ -124,6 +126,17 @@
  * GridLayout's algorithms favour rows and columns that are closer to its <em>right</em>
  * and <em>bottom</em> edges.
  *
+ * <h4>Interpretation of GONE</h4>
+ *
+ * For layout purposes, GridLayout treats views whose visibility status is
+ * {@link View#GONE GONE}, as having zero width and height. This is subtly different from
+ * the policy of ignoring views that are marked as GONE outright. If, for example, a gone-marked
+ * view was alone in a column, that column would itself collapse to zero width if and only if
+ * no gravity was defined on the view. If gravity was defined, then the gone-marked
+ * view has no effect on the layout and the container should be laid out as if the view
+ * had never been added to it.
+ * These statements apply equally to rows as well as columns, and to groups of rows or columns.
+ *
  * <h5>Limitations</h5>
  *
  * GridLayout does not provide support for the principle of <em>weight</em>, as defined in
@@ -208,10 +221,15 @@
 
     // Misc constants
 
-    static final String TAG = GridLayout.class.getName();
     static final int MAX_SIZE = 100000;
     static final int DEFAULT_CONTAINER_MARGIN = 0;
     static final int UNINITIALIZED_HASH = 0;
+    static final Printer LOG_PRINTER = new LogPrinter(Log.DEBUG, GridLayout.class.getName());
+    static final Printer NO_PRINTER = new Printer() {
+        @Override
+        public void println(String x) {
+        }
+    };
 
     // Defaults
 
@@ -233,13 +251,14 @@
 
     // Instance variables
 
-    final Axis horizontalAxis = new Axis(true);
-    final Axis verticalAxis = new Axis(false);
-    int orientation = DEFAULT_ORIENTATION;
-    boolean useDefaultMargins = DEFAULT_USE_DEFAULT_MARGINS;
-    int alignmentMode = DEFAULT_ALIGNMENT_MODE;
-    int defaultGap;
-    int lastLayoutParamsHashCode = UNINITIALIZED_HASH;
+    final Axis mHorizontalAxis = new Axis(true);
+    final Axis mVerticalAxis = new Axis(false);
+    int mOrientation = DEFAULT_ORIENTATION;
+    boolean mUseDefaultMargins = DEFAULT_USE_DEFAULT_MARGINS;
+    int mAlignmentMode = DEFAULT_ALIGNMENT_MODE;
+    int mDefaultGap;
+    int mLastLayoutParamsHashCode = UNINITIALIZED_HASH;
+    Printer mPrinter = LOG_PRINTER;
 
     // Constructors
 
@@ -248,7 +267,7 @@
      */
     public GridLayout(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
-        defaultGap = context.getResources().getDimensionPixelOffset(R.dimen.default_gap);
+        mDefaultGap = context.getResources().getDimensionPixelOffset(R.dimen.default_gap);
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.GridLayout);
         try {
             setRowCount(a.getInt(ROW_COUNT, DEFAULT_COUNT));
@@ -290,7 +309,7 @@
      * @attr ref android.R.styleable#GridLayout_orientation
      */
     public int getOrientation() {
-        return orientation;
+        return mOrientation;
     }
 
     /**
@@ -330,8 +349,8 @@
      * @attr ref android.R.styleable#GridLayout_orientation
      */
     public void setOrientation(int orientation) {
-        if (this.orientation != orientation) {
-            this.orientation = orientation;
+        if (this.mOrientation != orientation) {
+            this.mOrientation = orientation;
             invalidateStructure();
             requestLayout();
         }
@@ -350,7 +369,7 @@
      * @attr ref android.R.styleable#GridLayout_rowCount
      */
     public int getRowCount() {
-        return verticalAxis.getCount();
+        return mVerticalAxis.getCount();
     }
 
     /**
@@ -365,7 +384,7 @@
      * @attr ref android.R.styleable#GridLayout_rowCount
      */
     public void setRowCount(int rowCount) {
-        verticalAxis.setCount(rowCount);
+        mVerticalAxis.setCount(rowCount);
         invalidateStructure();
         requestLayout();
     }
@@ -383,7 +402,7 @@
      * @attr ref android.R.styleable#GridLayout_columnCount
      */
     public int getColumnCount() {
-        return horizontalAxis.getCount();
+        return mHorizontalAxis.getCount();
     }
 
     /**
@@ -398,7 +417,7 @@
      * @attr ref android.R.styleable#GridLayout_columnCount
      */
     public void setColumnCount(int columnCount) {
-        horizontalAxis.setCount(columnCount);
+        mHorizontalAxis.setCount(columnCount);
         invalidateStructure();
         requestLayout();
     }
@@ -414,7 +433,7 @@
      * @attr ref android.R.styleable#GridLayout_useDefaultMargins
      */
     public boolean getUseDefaultMargins() {
-        return useDefaultMargins;
+        return mUseDefaultMargins;
     }
 
     /**
@@ -444,7 +463,7 @@
      * @attr ref android.R.styleable#GridLayout_useDefaultMargins
      */
     public void setUseDefaultMargins(boolean useDefaultMargins) {
-        this.useDefaultMargins = useDefaultMargins;
+        this.mUseDefaultMargins = useDefaultMargins;
         requestLayout();
     }
 
@@ -461,7 +480,7 @@
      * @attr ref android.R.styleable#GridLayout_alignmentMode
      */
     public int getAlignmentMode() {
-        return alignmentMode;
+        return mAlignmentMode;
     }
 
     /**
@@ -480,7 +499,7 @@
      * @attr ref android.R.styleable#GridLayout_alignmentMode
      */
     public void setAlignmentMode(int alignmentMode) {
-        this.alignmentMode = alignmentMode;
+        this.mAlignmentMode = alignmentMode;
         requestLayout();
     }
 
@@ -495,7 +514,7 @@
      * @attr ref android.R.styleable#GridLayout_rowOrderPreserved
      */
     public boolean isRowOrderPreserved() {
-        return verticalAxis.isOrderPreserved();
+        return mVerticalAxis.isOrderPreserved();
     }
 
     /**
@@ -515,7 +534,7 @@
      * @attr ref android.R.styleable#GridLayout_rowOrderPreserved
      */
     public void setRowOrderPreserved(boolean rowOrderPreserved) {
-        verticalAxis.setOrderPreserved(rowOrderPreserved);
+        mVerticalAxis.setOrderPreserved(rowOrderPreserved);
         invalidateStructure();
         requestLayout();
     }
@@ -531,7 +550,7 @@
      * @attr ref android.R.styleable#GridLayout_columnOrderPreserved
      */
     public boolean isColumnOrderPreserved() {
-        return horizontalAxis.isOrderPreserved();
+        return mHorizontalAxis.isOrderPreserved();
     }
 
     /**
@@ -551,11 +570,38 @@
      * @attr ref android.R.styleable#GridLayout_columnOrderPreserved
      */
     public void setColumnOrderPreserved(boolean columnOrderPreserved) {
-        horizontalAxis.setOrderPreserved(columnOrderPreserved);
+        mHorizontalAxis.setOrderPreserved(columnOrderPreserved);
         invalidateStructure();
         requestLayout();
     }
 
+    /**
+     * Return the printer that will log diagnostics from this layout.
+     *
+     * @see #setPrinter(android.util.Printer)
+     *
+     * @return the printer associated with this view
+     *
+     * @hide
+     */
+    public Printer getPrinter() {
+        return mPrinter;
+    }
+
+    /**
+     * Set the printer that will log diagnostics from this layout.
+     * The default value is created by {@link android.util.LogPrinter}.
+     *
+     * @param printer the printer associated with this layout
+     *
+     * @see #getPrinter()
+     *
+     * @hide
+     */
+    public void setPrinter(Printer printer) {
+        this.mPrinter = (printer == null) ? NO_PRINTER : printer;
+    }
+
     // Static utility methods
 
     static int max2(int[] a, int valueIfEmpty) {
@@ -601,7 +647,7 @@
         if (c.getClass() == Space.class) {
             return 0;
         }
-        return defaultGap / 2;
+        return mDefaultGap / 2;
     }
 
     private int getDefaultMargin(View c, boolean isAtEdge, boolean horizontal, boolean leading) {
@@ -609,11 +655,11 @@
     }
 
     private int getDefaultMargin(View c, LayoutParams p, boolean horizontal, boolean leading) {
-        if (!useDefaultMargins) {
+        if (!mUseDefaultMargins) {
             return 0;
         }
         Spec spec = horizontal ? p.columnSpec : p.rowSpec;
-        Axis axis = horizontal ? horizontalAxis : verticalAxis;
+        Axis axis = horizontal ? mHorizontalAxis : mVerticalAxis;
         Interval span = spec.span;
         boolean leading1 = (horizontal && isLayoutRtl()) ? !leading : leading;
         boolean isAtEdge = leading1 ? (span.min == 0) : (span.max == axis.getCount());
@@ -630,10 +676,10 @@
     }
 
     private int getMargin(View view, boolean horizontal, boolean leading) {
-        if (alignmentMode == ALIGN_MARGINS) {
+        if (mAlignmentMode == ALIGN_MARGINS) {
             return getMargin1(view, horizontal, leading);
         } else {
-            Axis axis = horizontal ? horizontalAxis : verticalAxis;
+            Axis axis = horizontal ? mHorizontalAxis : mVerticalAxis;
             int[] margins = leading ? axis.getLeadingMargins() : axis.getTrailingMargins();
             LayoutParams lp = getLayoutParams(view);
             Spec spec = horizontal ? lp.columnSpec : lp.rowSpec;
@@ -680,8 +726,8 @@
 
     // install default indices for cells that don't define them
     private void validateLayoutParams() {
-        final boolean horizontal = (orientation == HORIZONTAL);
-        final Axis axis = horizontal ? horizontalAxis : verticalAxis;
+        final boolean horizontal = (mOrientation == HORIZONTAL);
+        final Axis axis = horizontal ? mHorizontalAxis : mVerticalAxis;
         final int count = (axis.definedCount != UNDEFINED) ? axis.definedCount : 0;
 
         int major = 0;
@@ -737,9 +783,9 @@
     }
 
     private void invalidateStructure() {
-        lastLayoutParamsHashCode = UNINITIALIZED_HASH;
-        horizontalAxis.invalidateStructure();
-        verticalAxis.invalidateStructure();
+        mLastLayoutParamsHashCode = UNINITIALIZED_HASH;
+        mHorizontalAxis.invalidateStructure();
+        mVerticalAxis.invalidateStructure();
         // This can end up being done twice. Better twice than not at all.
         invalidateValues();
     }
@@ -747,9 +793,9 @@
     private void invalidateValues() {
         // Need null check because requestLayout() is called in View's initializer,
         // before we are set up.
-        if (horizontalAxis != null && verticalAxis != null) {
-            horizontalAxis.invalidateValues();
-            verticalAxis.invalidateValues();
+        if (mHorizontalAxis != null && mVerticalAxis != null) {
+            mHorizontalAxis.invalidateValues();
+            mVerticalAxis.invalidateValues();
         }
     }
 
@@ -780,7 +826,7 @@
         if (span.min != UNDEFINED && span.min < 0) {
             handleInvalidParams(groupName + " indices must be positive");
         }
-        Axis axis = horizontal ? horizontalAxis : verticalAxis;
+        Axis axis = horizontal ? mHorizontalAxis : mVerticalAxis;
         int count = axis.definedCount;
         if (count != UNDEFINED) {
             if (span.max > count) {
@@ -866,7 +912,7 @@
         int right  = getWidth()  - getPaddingRight()  - insets.right;
         int bottom = getHeight() - getPaddingBottom() - insets.bottom;
 
-        int[] xs = horizontalAxis.locations;
+        int[] xs = mHorizontalAxis.locations;
         if (xs != null) {
             for (int i = 0, length = xs.length; i < length; i++) {
                 int x = left + xs[i];
@@ -874,7 +920,7 @@
             }
         }
 
-        int[] ys = verticalAxis.locations;
+        int[] ys = mVerticalAxis.locations;
         if (ys != null) {
             for (int i = 0, length = ys.length; i < length; i++) {
                 int y = top + ys[i];
@@ -915,7 +961,7 @@
     protected void onChildVisibilityChanged(View child, int oldVisibility, int newVisibility) {
         super.onChildVisibilityChanged(child, oldVisibility, newVisibility);
         if (oldVisibility == GONE || newVisibility == GONE) {
-            invalidateStructure();
+        invalidateStructure();
         }
     }
 
@@ -931,12 +977,12 @@
     }
 
     private void consistencyCheck() {
-        if (lastLayoutParamsHashCode == UNINITIALIZED_HASH) {
+        if (mLastLayoutParamsHashCode == UNINITIALIZED_HASH) {
             validateLayoutParams();
-            lastLayoutParamsHashCode = computeLayoutParamsHashCode();
-        } else if (lastLayoutParamsHashCode != computeLayoutParamsHashCode()) {
-            Log.w(TAG, "The fields of some layout parameters were modified in between layout " +
-                    "operations. Check the javadoc for GridLayout.LayoutParams#rowSpec.");
+            mLastLayoutParamsHashCode = computeLayoutParamsHashCode();
+        } else if (mLastLayoutParamsHashCode != computeLayoutParamsHashCode()) {
+            mPrinter.println("The fields of some layout parameters were modified in between "
+                    + "layout operations. Check the javadoc for GridLayout.LayoutParams#rowSpec.");
             invalidateStructure();
             consistencyCheck();
         }
@@ -963,11 +1009,11 @@
             if (firstPass) {
                 measureChildWithMargins2(c, widthSpec, heightSpec, lp.width, lp.height);
             } else {
-                boolean horizontal = (orientation == HORIZONTAL);
+                boolean horizontal = (mOrientation == HORIZONTAL);
                 Spec spec = horizontal ? lp.columnSpec : lp.rowSpec;
                 if (spec.alignment == FILL) {
                     Interval span = spec.span;
-                    Axis axis = horizontal ? horizontalAxis : verticalAxis;
+                    Axis axis = horizontal ? mHorizontalAxis : mVerticalAxis;
                     int[] locations = axis.getLocations();
                     int cellSize = locations[span.max] - locations[span.min];
                     int viewSize = cellSize - getTotalMargin(c, horizontal);
@@ -1006,14 +1052,14 @@
         int heightSansPadding;
 
         // Use the orientation property to decide which axis should be laid out first.
-        if (orientation == HORIZONTAL) {
-            widthSansPadding = horizontalAxis.getMeasure(widthSpecSansPadding);
+        if (mOrientation == HORIZONTAL) {
+            widthSansPadding = mHorizontalAxis.getMeasure(widthSpecSansPadding);
             measureChildrenWithMargins(widthSpecSansPadding, heightSpecSansPadding, false);
-            heightSansPadding = verticalAxis.getMeasure(heightSpecSansPadding);
+            heightSansPadding = mVerticalAxis.getMeasure(heightSpecSansPadding);
         } else {
-            heightSansPadding = verticalAxis.getMeasure(heightSpecSansPadding);
+            heightSansPadding = mVerticalAxis.getMeasure(heightSpecSansPadding);
             measureChildrenWithMargins(widthSpecSansPadding, heightSpecSansPadding, false);
-            widthSansPadding = horizontalAxis.getMeasure(widthSpecSansPadding);
+            widthSansPadding = mHorizontalAxis.getMeasure(widthSpecSansPadding);
         }
 
         int measuredWidth  = Math.max(widthSansPadding  + hPadding, getSuggestedMinimumWidth());
@@ -1072,11 +1118,11 @@
         int paddingRight = getPaddingRight();
         int paddingBottom = getPaddingBottom();
 
-        horizontalAxis.layout(targetWidth - paddingLeft - paddingRight);
-        verticalAxis.layout(targetHeight - paddingTop - paddingBottom);
+        mHorizontalAxis.layout(targetWidth - paddingLeft - paddingRight);
+        mVerticalAxis.layout(targetHeight - paddingTop - paddingBottom);
 
-        int[] hLocations = horizontalAxis.getLocations();
-        int[] vLocations = verticalAxis.getLocations();
+        int[] hLocations = mHorizontalAxis.getLocations();
+        int[] vLocations = mVerticalAxis.getLocations();
 
         for (int i = 0, N = getChildCount(); i < N; i++) {
             View c = getChildAt(i);
@@ -1103,8 +1149,8 @@
             Alignment hAlign = getAlignment(columnSpec.alignment, true);
             Alignment vAlign = getAlignment(rowSpec.alignment, false);
 
-            Bounds boundsX = horizontalAxis.getGroupBounds().getValue(i);
-            Bounds boundsY = verticalAxis.getGroupBounds().getValue(i);
+            Bounds boundsX = mHorizontalAxis.getGroupBounds().getValue(i);
+            Bounds boundsY = mVerticalAxis.getGroupBounds().getValue(i);
 
             // Gravity offsets: the location of the alignment group relative to its cell group.
             int gravityOffsetX = hAlign.getGravityOffset(c, cellWidth - boundsX.size(true));
@@ -1246,6 +1292,7 @@
             Assoc<Spec, Bounds> assoc = Assoc.of(Spec.class, Bounds.class);
             for (int i = 0, N = getChildCount(); i < N; i++) {
                 View c = getChildAt(i);
+                // we must include views that are GONE here, see introductory javadoc
                 LayoutParams lp = getLayoutParams(c);
                 Spec spec = horizontal ? lp.columnSpec : lp.rowSpec;
                 Bounds bounds = getAlignment(spec.alignment, horizontal).getBounds();
@@ -1261,6 +1308,7 @@
             }
             for (int i = 0, N = getChildCount(); i < N; i++) {
                 View c = getChildAt(i);
+                // we must include views that are GONE here, see introductory javadoc
                 LayoutParams lp = getLayoutParams(c);
                 Spec spec = horizontal ? lp.columnSpec : lp.rowSpec;
                 groupBounds.getValue(i).include(GridLayout.this, c, spec, this);
@@ -1527,8 +1575,8 @@
                     removed.add(arc);
                 }
             }
-            Log.d(TAG, axisName + " constraints: " + arcsToString(culprits) + " are inconsistent; "
-                    + "permanently removing: " + arcsToString(removed) + ". ");
+            mPrinter.println(axisName + " constraints: " + arcsToString(culprits) +
+                    " are inconsistent; permanently removing: " + arcsToString(removed) + ". ");
         }
 
         /*
@@ -1917,12 +1965,16 @@
         }
 
         /**
-         * {@inheritDoc}
+         * Copy constructor. Clones the width, height, margin values, row spec,
+         * and column spec of the source.
+         *
+         * @param source The layout params to copy from.
          */
-        public LayoutParams(LayoutParams that) {
-            super(that);
-            this.rowSpec = that.rowSpec;
-            this.columnSpec = that.columnSpec;
+        public LayoutParams(LayoutParams source) {
+            super(source);
+
+            this.rowSpec = source.rowSpec;
+            this.columnSpec = source.columnSpec;
         }
 
         // AttributeSet constructors
@@ -2666,6 +2718,9 @@
 
         @Override
         public int getAlignmentValue(View view, int viewSize, int mode) {
+            if (view.getVisibility() == GONE) {
+                return 0;
+            }
             int baseline = view.getBaseline();
             return baseline == -1 ? UNDEFINED : baseline;
         }
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index 63147dd..15daf83 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -20,6 +20,7 @@
 import android.content.Intent;
 import android.content.res.TypedArray;
 import android.graphics.Rect;
+import android.os.Trace;
 import android.util.AttributeSet;
 import android.view.Gravity;
 import android.view.KeyEvent;
@@ -29,7 +30,10 @@
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.CollectionInfo;
+import android.view.accessibility.AccessibilityNodeInfo.CollectionItemInfo;
 import android.view.animation.GridLayoutAnimationController;
+import android.widget.AbsListView.LayoutParams;
 import android.widget.RemoteViews.RemoteView;
 
 
@@ -1364,6 +1368,8 @@
      */
     private void setupChild(View child, int position, int y, boolean flow, int childrenLeft,
             boolean selected, boolean recycled, int where) {
+        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "setupGridItem");
+
         boolean isSelected = selected && shouldShowSelector();
         final boolean updateChildSelected = isSelected != child.isSelected();
         final int mode = mTouchMode;
@@ -1459,6 +1465,8 @@
                 != position) {
             child.jumpDrawablesToCurrentState();
         }
+
+        Trace.traceEnd(Trace.TRACE_TAG_VIEW);
     }
 
     /**
@@ -2254,5 +2262,37 @@
     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfo(info);
         info.setClassName(GridView.class.getName());
+
+        final int columnsCount = getNumColumns();
+        final int rowsCount = getCount() / columnsCount;
+        final CollectionInfo collectionInfo = CollectionInfo.obtain(columnsCount, rowsCount, false);
+        info.setCollectionInfo(collectionInfo);
+    }
+
+    @Override
+    public void onInitializeAccessibilityNodeInfoForItem(
+            View view, int position, AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfoForItem(view, position, info);
+
+        final int count = getCount();
+        final int columnsCount = getNumColumns();
+        final int rowsCount = count / columnsCount;
+
+        final int row;
+        final int column;
+        if (!mStackFromBottom) {
+            column = position % columnsCount;
+            row = position / columnsCount;
+        } else {
+            final int invertedIndex = count - 1 - position;
+
+            column = columnsCount - 1 - (invertedIndex % columnsCount);
+            row = rowsCount - 1 - invertedIndex / columnsCount;
+        }
+
+        final LayoutParams lp = (LayoutParams) view.getLayoutParams();
+        final boolean isHeading = lp != null && lp.viewType != ITEM_VIEW_TYPE_HEADER_OR_FOOTER;
+        final CollectionItemInfo itemInfo = CollectionItemInfo.obtain(column, 1, row, 1, isHeading);
+        info.setCollectionItemInfo(itemInfo);
     }
 }
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index ff0579c..dab0962 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -20,7 +20,10 @@
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.graphics.Rect;
+import android.os.Build;
 import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.FocusFinder;
@@ -133,6 +136,8 @@
      */
     private static final int INVALID_POINTER = -1;
 
+    private SavedState mSavedState;
+
     public HorizontalScrollView(Context context) {
         this(context, null);
     }
@@ -595,12 +600,13 @@
                     final boolean canOverscroll = overscrollMode == OVER_SCROLL_ALWAYS ||
                             (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0);
 
+                    // Calling overScrollBy will call onOverScrolled, which
+                    // calls onScrollChanged if applicable.
                     if (overScrollBy(deltaX, 0, mScrollX, 0, range, 0,
                             mOverscrollDistance, 0, true)) {
                         // Break our velocity if we hit a scroll barrier.
                         mVelocityTracker.clear();
                     }
-                    onScrollChanged(mScrollX, mScrollY, oldX, oldY);
 
                     if (canOverscroll) {
                         final int pulledToX = oldX + deltaX;
@@ -732,9 +738,12 @@
             boolean clampedX, boolean clampedY) {
         // Treat animating scrolls differently; see #computeScroll() for why.
         if (!mScroller.isFinished()) {
+            final int oldX = mScrollX;
+            final int oldY = mScrollY;
             mScrollX = scrollX;
             mScrollY = scrollY;
             invalidateParentIfNeeded();
+            onScrollChanged(mScrollX, mScrollY, oldX, oldY);
             if (clampedX) {
                 mScroller.springBack(mScrollX, mScrollY, 0, getScrollRange(), 0, 0);
             }
@@ -1448,14 +1457,52 @@
 
     @Override
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
-        super.onLayout(changed, l, t, r, b);
+        int childWidth = 0;
+        int childMargins = 0;
+
+        if (getChildCount() > 0) {
+            childWidth = getChildAt(0).getMeasuredWidth();
+            LayoutParams childParams = (LayoutParams) getChildAt(0).getLayoutParams();
+            childMargins = childParams.leftMargin + childParams.rightMargin;
+        }
+
+        final int available = r - l - getPaddingLeftWithForeground() -
+                getPaddingRightWithForeground() - childMargins;
+
+        final boolean forceLeftGravity = (childWidth > available);
+
+        layoutChildren(l, t, r, b, forceLeftGravity);
+
         mIsLayoutDirty = false;
         // Give a child focus if it needs it
         if (mChildToScrollTo != null && isViewDescendantOf(mChildToScrollTo, this)) {
-                scrollToChild(mChildToScrollTo);
+            scrollToChild(mChildToScrollTo);
         }
         mChildToScrollTo = null;
 
+        if (!isLaidOut()) {
+            final int scrollRange = Math.max(0,
+                    childWidth - (r - l - mPaddingLeft - mPaddingRight));
+            if (mSavedState != null) {
+                if (isLayoutRtl() == mSavedState.isLayoutRtl) {
+                    mScrollX = mSavedState.scrollPosition;
+                } else {
+                    mScrollX = scrollRange - mSavedState.scrollPosition;
+                }
+                mSavedState = null;
+            } else {
+                if (isLayoutRtl()) {
+                    mScrollX = scrollRange - mScrollX;
+                } // mScrollX default value is "0" for LTR
+            }
+            // Don't forget to clamp
+            if (mScrollX > scrollRange) {
+                mScrollX = scrollRange;
+            } else if (mScrollX < 0) {
+                mScrollX = 0;
+            }
+        }
+
         // Calling this with the present values causes it to re-claim them
         scrollTo(mScrollX, mScrollY);
     }
@@ -1600,4 +1647,73 @@
         }
         return n;
     }
+
+    @Override
+    protected void onRestoreInstanceState(Parcelable state) {
+        if (mContext.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.JELLY_BEAN_MR2) {
+            // Some old apps reused IDs in ways they shouldn't have.
+            // Don't break them, but they don't get scroll state restoration.
+            super.onRestoreInstanceState(state);
+            return;
+        }
+        SavedState ss = (SavedState) state;
+        super.onRestoreInstanceState(ss.getSuperState());
+        mSavedState = ss;
+        requestLayout();
+    }
+
+    @Override
+    protected Parcelable onSaveInstanceState() {
+        if (mContext.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.JELLY_BEAN_MR2) {
+            // Some old apps reused IDs in ways they shouldn't have.
+            // Don't break them, but they don't get scroll state restoration.
+            return super.onSaveInstanceState();
+        }
+        Parcelable superState = super.onSaveInstanceState();
+        SavedState ss = new SavedState(superState);
+        ss.scrollPosition = mScrollX;
+        ss.isLayoutRtl = isLayoutRtl();
+        return ss;
+    }
+
+    static class SavedState extends BaseSavedState {
+        public int scrollPosition;
+        public boolean isLayoutRtl;
+
+        SavedState(Parcelable superState) {
+            super(superState);
+        }
+
+        public SavedState(Parcel source) {
+            super(source);
+            scrollPosition = source.readInt();
+            isLayoutRtl = (source.readInt() == 0) ? true : false;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            super.writeToParcel(dest, flags);
+            dest.writeInt(scrollPosition);
+            dest.writeInt(isLayoutRtl ? 1 : 0);
+        }
+
+        @Override
+        public String toString() {
+            return "HorizontalScrollView.SavedState{"
+                    + Integer.toHexString(System.identityHashCode(this))
+                    + " scrollPosition=" + scrollPosition
+                    + " isLayoutRtl=" + isLayoutRtl + "}";
+        }
+
+        public static final Parcelable.Creator<SavedState> CREATOR
+                = new Parcelable.Creator<SavedState>() {
+            public SavedState createFromParcel(Parcel in) {
+                return new SavedState(in);
+            }
+
+            public SavedState[] newArray(int size) {
+                return new SavedState[size];
+            }
+        };
+    }
 }
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 33fd8ce..3e53b91 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -732,6 +732,15 @@
         }
     }
 
+    @Override
+    public void onRtlPropertiesChanged(int layoutDirection) {
+        super.onRtlPropertiesChanged(layoutDirection);
+
+        if (mDrawable != null) {
+            mDrawable.setLayoutDirection(layoutDirection);
+        }
+    }
+
     private static final Matrix.ScaleToFit[] sS2FArray = {
         Matrix.ScaleToFit.FILL,
         Matrix.ScaleToFit.START,
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index bc57c36e..ad60a95 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -1871,10 +1871,23 @@
         /**
          * {@inheritDoc}
          */
-        public LayoutParams(MarginLayoutParams source) {
+        public LayoutParams(ViewGroup.MarginLayoutParams source) {
             super(source);
         }
 
+        /**
+         * Copy constructor. Clones the width, height, margin values, weight,
+         * and gravity of the source.
+         *
+         * @param source The layout params to copy from.
+         */
+        public LayoutParams(LayoutParams source) {
+            super(source);
+
+            this.weight = source.weight;
+            this.gravity = source.gravity;
+        }
+
         @Override
         public String debug(String output) {
             return output + "LinearLayout.LayoutParams={width=" + sizeToString(width) +
diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java
index 3d6b69e..b7e1fdd 100644
--- a/core/java/android/widget/ListPopupWindow.java
+++ b/core/java/android/widget/ListPopupWindow.java
@@ -16,6 +16,9 @@
 
 package android.widget;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.database.DataSetObserver;
 import android.graphics.Rect;
@@ -23,14 +26,20 @@
 import android.os.Handler;
 import android.text.TextUtils;
 import android.util.AttributeSet;
+import android.util.IntProperty;
 import android.util.Log;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.View.MeasureSpec;
+import android.view.View.OnAttachStateChangeListener;
 import android.view.View.OnTouchListener;
+import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.view.ViewParent;
+import android.view.animation.AccelerateDecelerateInterpolator;
+
+import com.android.internal.widget.AutoScrollHelper.AbsListViewAutoScroller;
 
 import java.util.Locale;
 
@@ -821,8 +830,7 @@
             // to select one of its items
             if (keyCode != KeyEvent.KEYCODE_SPACE
                     && (mDropDownList.getSelectedItemPosition() >= 0
-                            || (keyCode != KeyEvent.KEYCODE_ENTER
-                                    && keyCode != KeyEvent.KEYCODE_DPAD_CENTER))) {
+                            || !KeyEvent.isConfirmKey(keyCode))) {
                 int curIndex = mDropDownList.getSelectedItemPosition();
                 boolean consumed;
 
@@ -910,16 +918,10 @@
     public boolean onKeyUp(int keyCode, KeyEvent event) {
         if (isShowing() && mDropDownList.getSelectedItemPosition() >= 0) {
             boolean consumed = mDropDownList.onKeyUp(keyCode, event);
-            if (consumed) {
-                switch (keyCode) {
-                    // if the list accepts the key events and the key event
-                    // was a click, the text view gets the selected item
-                    // from the drop down as its content
-                    case KeyEvent.KEYCODE_ENTER:
-                    case KeyEvent.KEYCODE_DPAD_CENTER:
-                        dismiss();
-                        break;
-                }
+            if (consumed && KeyEvent.isConfirmKey(keyCode)) {
+                // if the list accepts the key events and the key event was a click, the text view
+                // gets the selected item from the drop down as its content
+                dismiss();
             }
             return consumed;
         }
@@ -963,6 +965,35 @@
     }
 
     /**
+     * Returns an {@link OnTouchListener} that can be added to the source view
+     * to implement drag-to-open behavior. Generally, the source view should be
+     * the same view that was passed to {@link #setAnchorView}.
+     * <p>
+     * When the listener is set on a view, touching that view and dragging
+     * outside of its bounds will open the popup window. Lifting will select the
+     * currently touched list item.
+     * <p>
+     * Example usage:
+     * <pre>
+     * ListPopupWindow myPopup = new ListPopupWindow(context);
+     * myPopup.setAnchor(myAnchor);
+     * OnTouchListener dragListener = myPopup.createDragToOpenListener(myAnchor);
+     * myAnchor.setOnTouchListener(dragListener);
+     * </pre>
+     *
+     * @param src the view on which the resulting listener will be set
+     * @return a touch listener that controls drag-to-open behavior
+     */
+    public OnTouchListener createDragToOpenListener(View src) {
+        return new ForwardingListener(src) {
+            @Override
+            public ListPopupWindow getPopup() {
+                return ListPopupWindow.this;
+            }
+        };
+    }
+
+    /**
      * <p>Builds the popup window's content and returns the height the popup
      * should have. Returns -1 when the content already exists.</p>
      *
@@ -1130,13 +1161,225 @@
     }
 
     /**
+     * Abstract class that forwards touch events to a {@link ListPopupWindow}.
+     *
+     * @hide
+     */
+    public static abstract class ForwardingListener
+            implements View.OnTouchListener, View.OnAttachStateChangeListener {
+        /** Scaled touch slop, used for detecting movement outside bounds. */
+        private final float mScaledTouchSlop;
+
+        /** Timeout before disallowing intercept on the source's parent. */
+        private final int mTapTimeout;
+
+        /** Source view from which events are forwarded. */
+        private final View mSrc;
+
+        /** Runnable used to prevent conflicts with scrolling parents. */
+        private Runnable mDisallowIntercept;
+
+        /** Whether this listener is currently forwarding touch events. */
+        private boolean mForwarding;
+
+        /** The id of the first pointer down in the current event stream. */
+        private int mActivePointerId;
+
+        public ForwardingListener(View src) {
+            mSrc = src;
+            mScaledTouchSlop = ViewConfiguration.get(src.getContext()).getScaledTouchSlop();
+            mTapTimeout = ViewConfiguration.getTapTimeout();
+
+            src.addOnAttachStateChangeListener(this);
+        }
+
+        /**
+         * Returns the popup to which this listener is forwarding events.
+         * <p>
+         * Override this to return the correct popup. If the popup is displayed
+         * asynchronously, you may also need to override
+         * {@link #onForwardingStopped} to prevent premature cancelation of
+         * forwarding.
+         *
+         * @return the popup to which this listener is forwarding events
+         */
+        public abstract ListPopupWindow getPopup();
+
+        @Override
+        public boolean onTouch(View v, MotionEvent event) {
+            final boolean wasForwarding = mForwarding;
+            final boolean forwarding;
+            if (wasForwarding) {
+                forwarding = onTouchForwarded(event) || !onForwardingStopped();
+            } else {
+                forwarding = onTouchObserved(event) && onForwardingStarted();
+            }
+
+            mForwarding = forwarding;
+            return forwarding || wasForwarding;
+        }
+
+        @Override
+        public void onViewAttachedToWindow(View v) {
+        }
+
+        @Override
+        public void onViewDetachedFromWindow(View v) {
+            mForwarding = false;
+            mActivePointerId = MotionEvent.INVALID_POINTER_ID;
+
+            if (mDisallowIntercept != null) {
+                mSrc.removeCallbacks(mDisallowIntercept);
+            }
+        }
+
+        /**
+         * Called when forwarding would like to start.
+         * <p>
+         * By default, this will show the popup returned by {@link #getPopup()}.
+         * It may be overridden to perform another action, like clicking the
+         * source view or preparing the popup before showing it.
+         *
+         * @return true to start forwarding, false otherwise
+         */
+        protected boolean onForwardingStarted() {
+            final ListPopupWindow popup = getPopup();
+            if (popup != null && !popup.isShowing()) {
+                popup.show();
+            }
+            return true;
+        }
+
+        /**
+         * Called when forwarding would like to stop.
+         * <p>
+         * By default, this will dismiss the popup returned by
+         * {@link #getPopup()}. It may be overridden to perform some other
+         * action.
+         *
+         * @return true to stop forwarding, false otherwise
+         */
+        protected boolean onForwardingStopped() {
+            final ListPopupWindow popup = getPopup();
+            if (popup != null && popup.isShowing()) {
+                popup.dismiss();
+            }
+            return true;
+        }
+
+        /**
+         * Observes motion events and determines when to start forwarding.
+         *
+         * @param srcEvent motion event in source view coordinates
+         * @return true to start forwarding motion events, false otherwise
+         */
+        private boolean onTouchObserved(MotionEvent srcEvent) {
+            final View src = mSrc;
+            if (!src.isEnabled()) {
+                return false;
+            }
+
+            final int actionMasked = srcEvent.getActionMasked();
+            switch (actionMasked) {
+                case MotionEvent.ACTION_DOWN:
+                    mActivePointerId = srcEvent.getPointerId(0);
+                    if (mDisallowIntercept == null) {
+                        mDisallowIntercept = new DisallowIntercept();
+                    }
+                    src.postDelayed(mDisallowIntercept, mTapTimeout);
+                    break;
+                case MotionEvent.ACTION_MOVE:
+                    final int activePointerIndex = srcEvent.findPointerIndex(mActivePointerId);
+                    if (activePointerIndex >= 0) {
+                        final float x = srcEvent.getX(activePointerIndex);
+                        final float y = srcEvent.getY(activePointerIndex);
+                        if (!src.pointInView(x, y, mScaledTouchSlop)) {
+                            // The pointer has moved outside of the view.
+                            if (mDisallowIntercept != null) {
+                                src.removeCallbacks(mDisallowIntercept);
+                            }
+                            src.getParent().requestDisallowInterceptTouchEvent(true);
+                            return true;
+                        }
+                    }
+                    break;
+                case MotionEvent.ACTION_CANCEL:
+                case MotionEvent.ACTION_UP:
+                    if (mDisallowIntercept != null) {
+                        src.removeCallbacks(mDisallowIntercept);
+                    }
+                    break;
+            }
+
+            return false;
+        }
+
+        /**
+         * Handled forwarded motion events and determines when to stop
+         * forwarding.
+         *
+         * @param srcEvent motion event in source view coordinates
+         * @return true to continue forwarding motion events, false to cancel
+         */
+        private boolean onTouchForwarded(MotionEvent srcEvent) {
+            final View src = mSrc;
+            final ListPopupWindow popup = getPopup();
+            if (popup == null || !popup.isShowing()) {
+                return false;
+            }
+
+            final DropDownListView dst = popup.mDropDownList;
+            if (dst == null || !dst.isShown()) {
+                return false;
+            }
+
+            // Convert event to destination-local coordinates.
+            final MotionEvent dstEvent = MotionEvent.obtainNoHistory(srcEvent);
+            src.toGlobalMotionEvent(dstEvent);
+            dst.toLocalMotionEvent(dstEvent);
+
+            // Forward converted event to destination view, then recycle it.
+            final boolean handled = dst.onForwardedEvent(dstEvent, mActivePointerId);
+            dstEvent.recycle();
+            return handled;
+        }
+
+        private class DisallowIntercept implements Runnable {
+            @Override
+            public void run() {
+                final ViewParent parent = mSrc.getParent();
+                parent.requestDisallowInterceptTouchEvent(true);
+            }
+        }
+    }
+
+    /**
      * <p>Wrapper class for a ListView. This wrapper can hijack the focus to
      * make sure the list uses the appropriate drawables and states when
      * displayed on screen within a drop down. The focus is never actually
      * passed to the drop down in this mode; the list only looks focused.</p>
      */
     private static class DropDownListView extends ListView {
-        private static final String TAG = ListPopupWindow.TAG + ".DropDownListView";
+        /** Duration in milliseconds of the drag-to-open click animation. */
+        private static final long CLICK_ANIM_DURATION = 150;
+
+        /** Target alpha value for drag-to-open click animation. */
+        private static final int CLICK_ANIM_ALPHA = 0x80;
+
+        /** Wrapper around Drawable's <code>alpha</code> property. */
+        private static final IntProperty<Drawable> DRAWABLE_ALPHA =
+                new IntProperty<Drawable>("alpha") {
+                    @Override
+                    public void setValue(Drawable object, int value) {
+                        object.setAlpha(value);
+                    }
+
+                    @Override
+                    public Integer get(Drawable object) {
+                        return object.getAlpha();
+                    }
+                };
+
         /*
          * WARNING: This is a workaround for a touch mode issue.
          *
@@ -1172,6 +1415,15 @@
          */
         private boolean mHijackFocus;
 
+        /** Whether to force drawing of the pressed state selector. */
+        private boolean mDrawsInPressedState;
+
+        /** Current drag-to-open click animation, if any. */
+        private Animator mClickAnimation;
+
+        /** Helper for drag-to-open auto scrolling. */
+        private AbsListViewAutoScroller mScrollHelper;
+
         /**
          * <p>Creates a new list view wrapper.</p>
          *
@@ -1185,6 +1437,130 @@
         }
 
         /**
+         * Handles forwarded events.
+         *
+         * @param activePointerId id of the pointer that activated forwarding
+         * @return whether the event was handled
+         */
+        public boolean onForwardedEvent(MotionEvent event, int activePointerId) {
+            boolean handledEvent = true;
+            boolean clearPressedItem = false;
+
+            final int actionMasked = event.getActionMasked();
+            switch (actionMasked) {
+                case MotionEvent.ACTION_CANCEL:
+                    handledEvent = false;
+                    break;
+                case MotionEvent.ACTION_UP:
+                    handledEvent = false;
+                    // $FALL-THROUGH$
+                case MotionEvent.ACTION_MOVE:
+                    final int activeIndex = event.findPointerIndex(activePointerId);
+                    if (activeIndex < 0) {
+                        handledEvent = false;
+                        break;
+                    }
+
+                    final int x = (int) event.getX(activeIndex);
+                    final int y = (int) event.getY(activeIndex);
+                    final int position = pointToPosition(x, y);
+                    if (position == INVALID_POSITION) {
+                        clearPressedItem = true;
+                        break;
+                    }
+
+                    final View child = getChildAt(position - getFirstVisiblePosition());
+                    setPressedItem(child, position);
+                    handledEvent = true;
+
+                    if (actionMasked == MotionEvent.ACTION_UP) {
+                        clickPressedItem(child, position);
+                    }
+                    break;
+            }
+
+            // Failure to handle the event cancels forwarding.
+            if (!handledEvent || clearPressedItem) {
+                clearPressedItem();
+            }
+
+            // Manage automatic scrolling.
+            if (handledEvent) {
+                if (mScrollHelper == null) {
+                    mScrollHelper = new AbsListViewAutoScroller(this);
+                }
+                mScrollHelper.setEnabled(true);
+                mScrollHelper.onTouch(this, event);
+            } else if (mScrollHelper != null) {
+                mScrollHelper.setEnabled(false);
+            }
+
+            return handledEvent;
+        }
+
+        /**
+         * Starts an alpha animation on the selector. When the animation ends,
+         * the list performs a click on the item.
+         */
+        private void clickPressedItem(final View child, final int position) {
+            final long id = getItemIdAtPosition(position);
+            final Animator anim = ObjectAnimator.ofInt(
+                    mSelector, DRAWABLE_ALPHA, 0xFF, CLICK_ANIM_ALPHA, 0xFF);
+            anim.setDuration(CLICK_ANIM_DURATION);
+            anim.setInterpolator(new AccelerateDecelerateInterpolator());
+            anim.addListener(new AnimatorListenerAdapter() {
+                    @Override
+                public void onAnimationEnd(Animator animation) {
+                    performItemClick(child, position, id);
+                }
+            });
+            anim.start();
+
+            if (mClickAnimation != null) {
+                mClickAnimation.cancel();
+            }
+            mClickAnimation = anim;
+        }
+
+        private void clearPressedItem() {
+            mDrawsInPressedState = false;
+            setPressed(false);
+            updateSelectorState();
+
+            if (mClickAnimation != null) {
+                mClickAnimation.cancel();
+                mClickAnimation = null;
+            }
+        }
+
+        private void setPressedItem(View child, int position) {
+            mDrawsInPressedState = true;
+
+            // Ordering is essential. First update the pressed state and layout
+            // the children. This will ensure the selector actually gets drawn.
+            setPressed(true);
+            layoutChildren();
+
+            // Ensure that keyboard focus starts from the last touched position.
+            setSelectedPositionInt(position);
+            positionSelector(position, child);
+
+            // Refresh the drawable state to reflect the new pressed state,
+            // which will also update the selector state.
+            refreshDrawableState();
+
+            if (mClickAnimation != null) {
+                mClickAnimation.cancel();
+                mClickAnimation = null;
+            }
+        }
+
+        @Override
+        boolean touchModeDrawsInPressedState() {
+            return mDrawsInPressedState || super.touchModeDrawsInPressedState();
+        }
+
+        /**
          * <p>Avoids jarring scrolling effect by ensuring that list elements
          * made of a text view fit on a single line.</p>
          *
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index f42999d..b239fbd 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -16,6 +16,7 @@
 
 package android.widget;
 
+import android.os.Trace;
 import com.android.internal.R;
 import com.android.internal.util.Predicate;
 import com.google.android.collect.Lists;
@@ -41,7 +42,8 @@
 import android.view.ViewRootImpl;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
-import android.view.accessibility.AccessibilityNodeProvider;
+import android.view.accessibility.AccessibilityNodeInfo.CollectionInfo;
+import android.view.accessibility.AccessibilityNodeInfo.CollectionItemInfo;
 import android.widget.RemoteViews.RemoteView;
 
 import java.util.ArrayList;
@@ -240,35 +242,39 @@
     }
 
     /**
-     * Add a fixed view to appear at the top of the list. If addHeaderView is
+     * Add a fixed view to appear at the top of the list. If this method is
      * called more than once, the views will appear in the order they were
      * added. Views added using this call can take focus if they want.
      * <p>
-     * NOTE: Call this before calling setAdapter. This is so ListView can wrap
-     * the supplied cursor with one that will also account for header and footer
-     * views.
+     * Note: When first introduced, this method could only be called before
+     * setting the adapter with {@link #setAdapter(ListAdapter)}. Starting with
+     * {@link android.os.Build.VERSION_CODES#KITKAT}, this method may be
+     * called at any time. If the ListView's adapter does not extend
+     * {@link HeaderViewListAdapter}, it will be wrapped with a supporting
+     * instance of {@link WrapperListAdapter}.
      *
      * @param v The view to add.
      * @param data Data to associate with this view
      * @param isSelectable whether the item is selectable
      */
     public void addHeaderView(View v, Object data, boolean isSelectable) {
-
-        if (mAdapter != null && ! (mAdapter instanceof HeaderViewListAdapter)) {
-            throw new IllegalStateException(
-                    "Cannot add header view to list -- setAdapter has already been called.");
-        }
-
-        FixedViewInfo info = new FixedViewInfo();
+        final FixedViewInfo info = new FixedViewInfo();
         info.view = v;
         info.data = data;
         info.isSelectable = isSelectable;
         mHeaderViewInfos.add(info);
 
-        // in the case of re-adding a header view, or adding one later on,
-        // we need to notify the observer
-        if (mAdapter != null && mDataSetObserver != null) {
-            mDataSetObserver.onChanged();
+        // Wrap the adapter if it wasn't already wrapped.
+        if (mAdapter != null) {
+            if (!(mAdapter instanceof HeaderViewListAdapter)) {
+                mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, mAdapter);
+            }
+
+            // In the case of re-adding a header view, or adding one later on,
+            // we need to notify the observer.
+            if (mDataSetObserver != null) {
+                mDataSetObserver.onChanged();
+            }
         }
     }
 
@@ -277,9 +283,12 @@
      * called more than once, the views will appear in the order they were
      * added. Views added using this call can take focus if they want.
      * <p>
-     * NOTE: Call this before calling setAdapter. This is so ListView can wrap
-     * the supplied cursor with one that will also account for header and footer
-     * views.
+     * Note: When first introduced, this method could only be called before
+     * setting the adapter with {@link #setAdapter(ListAdapter)}. Starting with
+     * {@link android.os.Build.VERSION_CODES#KITKAT}, this method may be
+     * called at any time. If the ListView's adapter does not extend
+     * {@link HeaderViewListAdapter}, it will be wrapped with a supporting
+     * instance of {@link WrapperListAdapter}.
      *
      * @param v The view to add.
      */
@@ -330,41 +339,49 @@
      * called more than once, the views will appear in the order they were
      * added. Views added using this call can take focus if they want.
      * <p>
-     * NOTE: Call this before calling setAdapter. This is so ListView can wrap
-     * the supplied cursor with one that will also account for header and footer
-     * views.
+     * Note: When first introduced, this method could only be called before
+     * setting the adapter with {@link #setAdapter(ListAdapter)}. Starting with
+     * {@link android.os.Build.VERSION_CODES#KITKAT}, this method may be
+     * called at any time. If the ListView's adapter does not extend
+     * {@link HeaderViewListAdapter}, it will be wrapped with a supporting
+     * instance of {@link WrapperListAdapter}.
      *
      * @param v The view to add.
      * @param data Data to associate with this view
      * @param isSelectable true if the footer view can be selected
      */
     public void addFooterView(View v, Object data, boolean isSelectable) {
-
-        // NOTE: do not enforce the adapter being null here, since unlike in
-        // addHeaderView, it was never enforced here, and so existing apps are
-        // relying on being able to add a footer and then calling setAdapter to
-        // force creation of the HeaderViewListAdapter wrapper
-
-        FixedViewInfo info = new FixedViewInfo();
+        final FixedViewInfo info = new FixedViewInfo();
         info.view = v;
         info.data = data;
         info.isSelectable = isSelectable;
         mFooterViewInfos.add(info);
 
-        // in the case of re-adding a footer view, or adding one later on,
-        // we need to notify the observer
-        if (mAdapter != null && mDataSetObserver != null) {
-            mDataSetObserver.onChanged();
+        // Wrap the adapter if it wasn't already wrapped.
+        if (mAdapter != null) {
+            if (!(mAdapter instanceof HeaderViewListAdapter)) {
+                mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, mAdapter);
+            }
+
+            // In the case of re-adding a footer view, or adding one later on,
+            // we need to notify the observer.
+            if (mDataSetObserver != null) {
+                mDataSetObserver.onChanged();
+            }
         }
     }
 
     /**
-     * Add a fixed view to appear at the bottom of the list. If addFooterView is called more
-     * than once, the views will appear in the order they were added. Views added using
-     * this call can take focus if they want.
-     * <p>NOTE: Call this before calling setAdapter. This is so ListView can wrap the supplied
-     * cursor with one that will also account for header and footer views.
-     *
+     * Add a fixed view to appear at the bottom of the list. If addFooterView is
+     * called more than once, the views will appear in the order they were
+     * added. Views added using this call can take focus if they want.
+     * <p>
+     * Note: When first introduced, this method could only be called before
+     * setting the adapter with {@link #setAdapter(ListAdapter)}. Starting with
+     * {@link android.os.Build.VERSION_CODES#KITKAT}, this method may be
+     * called at any time. If the ListView's adapter does not extend
+     * {@link HeaderViewListAdapter}, it will be wrapped with a supporting
+     * instance of {@link WrapperListAdapter}.
      *
      * @param v The view to add.
      */
@@ -1462,12 +1479,12 @@
     @Override
     protected void layoutChildren() {
         final boolean blockLayoutRequests = mBlockLayoutRequests;
-        if (!blockLayoutRequests) {
-            mBlockLayoutRequests = true;
-        } else {
+        if (blockLayoutRequests) {
             return;
         }
 
+        mBlockLayoutRequests = true;
+
         try {
             super.layoutChildren();
 
@@ -1479,10 +1496,10 @@
                 return;
             }
 
-            int childrenTop = mListPadding.top;
-            int childrenBottom = mBottom - mTop - mListPadding.bottom;
+            final int childrenTop = mListPadding.top;
+            final int childrenBottom = mBottom - mTop - mListPadding.bottom;
+            final int childCount = getChildCount();
 
-            int childCount = getChildCount();
             int index = 0;
             int delta = 0;
 
@@ -1491,12 +1508,6 @@
             View oldFirst = null;
             View newSel = null;
 
-            View focusLayoutRestoreView = null;
-
-            AccessibilityNodeInfo accessibilityFocusLayoutRestoreNode = null;
-            View accessibilityFocusLayoutRestoreView = null;
-            int accessibilityFocusPosition = INVALID_POSITION;
-
             // Remember stuff we will need down below
             switch (mLayoutMode) {
             case LAYOUT_SET_SELECTION:
@@ -1544,49 +1555,36 @@
             } else if (mItemCount != mAdapter.getCount()) {
                 throw new IllegalStateException("The content of the adapter has changed but "
                         + "ListView did not receive a notification. Make sure the content of "
-                        + "your adapter is not modified from a background thread, but only "
-                        + "from the UI thread. [in ListView(" + getId() + ", " + getClass() 
+                        + "your adapter is not modified from a background thread, but only from "
+                        + "the UI thread. Make sure your adapter calls notifyDataSetChanged() "
+                        + "when its content changes. [in ListView(" + getId() + ", " + getClass()
                         + ") with Adapter(" + mAdapter.getClass() + ")]");
             }
 
             setSelectedPositionInt(mNextSelectedPosition);
 
-            // Remember which child, if any, had accessibility focus. This must
-            // occur before recycling any views, since that will clear
-            // accessibility focus.
-            final ViewRootImpl viewRootImpl = getViewRootImpl();
-            if (viewRootImpl != null) {
-                final View accessFocusedView = viewRootImpl.getAccessibilityFocusedHost();
-                if (accessFocusedView != null) {
-                    final View accessFocusedChild = findAccessibilityFocusedChild(
-                            accessFocusedView);
-                    if (accessFocusedChild != null) {
-                        if (!dataChanged || isDirectChildHeaderOrFooter(accessFocusedChild)) {
-                            // If the views won't be changing, try to maintain
-                            // focus on the current view host and (if
-                            // applicable) its virtual view.
-                            accessibilityFocusLayoutRestoreView = accessFocusedView;
-                            accessibilityFocusLayoutRestoreNode = viewRootImpl
-                                    .getAccessibilityFocusedVirtualView();
-                        } else {
-                            // Otherwise, try to maintain focus at the same
-                            // position.
-                            accessibilityFocusPosition = getPositionForView(accessFocusedChild);
-                        }
-                    }
-                }
+            // Remember which child, if any, had accessibility focus.
+            final int accessibilityFocusPosition;
+            final View accessFocusedChild = getAccessibilityFocusedChild();
+            if (accessFocusedChild != null) {
+                accessibilityFocusPosition = getPositionForView(accessFocusedChild);
+                accessFocusedChild.setHasTransientState(true);
+            } else {
+                accessibilityFocusPosition = INVALID_POSITION;
+            }
+
+            // Ensure the child containing focus, if any, has transient state.
+            // If the list data hasn't changed, or if the adapter has stable
+            // IDs, this will maintain focus.
+            final View focusedChild = getFocusedChild();
+            if (focusedChild != null) {
+                focusedChild.setHasTransientState(true);
             }
 
             // Pull all children into the RecycleBin.
             // These views will be reused if possible
             final int firstPosition = mFirstPosition;
             final RecycleBin recycleBin = mRecycler;
-
-            // reset the focus restoration
-            View focusLayoutRestoreDirectChild = null;
-
-            // Don't put header or footer views into the Recycler. Those are
-            // already cached in mHeaderViews;
             if (dataChanged) {
                 for (int i = 0; i < childCount; i++) {
                     recycleBin.addScrapView(getChildAt(i), firstPosition+i);
@@ -1595,28 +1593,6 @@
                 recycleBin.fillActiveViews(childCount, firstPosition);
             }
 
-            // take focus back to us temporarily to avoid the eventual
-            // call to clear focus when removing the focused child below
-            // from messing things up when ViewAncestor assigns focus back
-            // to someone else
-            final View focusedChild = getFocusedChild();
-            if (focusedChild != null) {
-                // TODO: in some cases focusedChild.getParent() == null
-
-                // we can remember the focused view to restore after relayout if the
-                // data hasn't changed, or if the focused position is a header or footer
-                if (!dataChanged || isDirectChildHeaderOrFooter(focusedChild)) {
-                    focusLayoutRestoreDirectChild = focusedChild;
-                    // remember the specific view that had focus
-                    focusLayoutRestoreView = findFocus();
-                    if (focusLayoutRestoreView != null) {
-                        // tell it we are going to mess with it
-                        focusLayoutRestoreView.onStartTemporaryDetach();
-                    }
-                }
-                requestFocus();
-            }
-
             // Clear out old views
             detachAllViewsFromParent();
             recycleBin.removeSkippedScrap();
@@ -1676,72 +1652,58 @@
             recycleBin.scrapActiveViews();
 
             if (sel != null) {
-                // the current selected item should get focus if items
-                // are focusable
-                if (mItemsCanFocus && hasFocus() && !sel.hasFocus()) {
-                    final boolean focusWasTaken = (sel == focusLayoutRestoreDirectChild &&
-                            focusLayoutRestoreView != null &&
-                            focusLayoutRestoreView.requestFocus()) || sel.requestFocus();
-                    if (!focusWasTaken) {
-                        // selected item didn't take focus, fine, but still want
-                        // to make sure something else outside of the selected view
-                        // has focus
+                final boolean shouldPlaceFocus = mItemsCanFocus && hasFocus();
+                final boolean maintainedFocus = focusedChild != null && focusedChild.hasFocus();
+                if (shouldPlaceFocus && !maintainedFocus && !sel.hasFocus()) {
+                    if (sel.requestFocus()) {
+                        // Successfully placed focus, clear selection.
+                        sel.setSelected(false);
+                        mSelectorRect.setEmpty();
+                    } else {
+                        // Failed to place focus, clear current (invalid) focus.
                         final View focused = getFocusedChild();
                         if (focused != null) {
                             focused.clearFocus();
                         }
                         positionSelector(INVALID_POSITION, sel);
-                    } else {
-                        sel.setSelected(false);
-                        mSelectorRect.setEmpty();
                     }
                 } else {
                     positionSelector(INVALID_POSITION, sel);
                 }
                 mSelectedTop = sel.getTop();
             } else {
-                if (mTouchMode > TOUCH_MODE_DOWN && mTouchMode < TOUCH_MODE_SCROLL) {
-                    View child = getChildAt(mMotionPosition - mFirstPosition);
-                    if (child != null) positionSelector(mMotionPosition, child);
+                // If the user's finger is down, select the motion position.
+                // Otherwise, clear selection.
+                if (mTouchMode == TOUCH_MODE_TAP || mTouchMode == TOUCH_MODE_DONE_WAITING) {
+                    final View child = getChildAt(mMotionPosition - mFirstPosition);
+                    if (child != null)  {
+                        positionSelector(mMotionPosition, child);
+                    }
                 } else {
                     mSelectedTop = 0;
                     mSelectorRect.setEmpty();
                 }
+            }
 
-                // even if there is not selected position, we may need to restore
-                // focus (i.e. something focusable in touch mode)
-                if (hasFocus() && focusLayoutRestoreView != null) {
-                    focusLayoutRestoreView.requestFocus();
+            if (accessFocusedChild != null) {
+                accessFocusedChild.setHasTransientState(false);
+
+                // If we failed to maintain accessibility focus on the previous
+                // view, attempt to restore it to the previous position.
+                if (!accessFocusedChild.isAccessibilityFocused()
+                    && accessibilityFocusPosition != INVALID_POSITION) {
+                    // Bound the position within the visible children.
+                    final int position = MathUtils.constrain(
+                            accessibilityFocusPosition - mFirstPosition, 0, getChildCount() - 1);
+                    final View restoreView = getChildAt(position);
+                    if (restoreView != null) {
+                        restoreView.requestAccessibilityFocus();
+                    }
                 }
             }
 
-            // Attempt to restore accessibility focus.
-            if (accessibilityFocusLayoutRestoreView != null) {
-                final AccessibilityNodeProvider provider =
-                        accessibilityFocusLayoutRestoreView.getAccessibilityNodeProvider();
-                if ((accessibilityFocusLayoutRestoreNode != null) && (provider != null)) {
-                    final int virtualViewId = AccessibilityNodeInfo.getVirtualDescendantId(
-                            accessibilityFocusLayoutRestoreNode.getSourceNodeId());
-                    provider.performAction(virtualViewId,
-                            AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
-                } else {
-                    accessibilityFocusLayoutRestoreView.requestAccessibilityFocus();
-                }
-            } else if (accessibilityFocusPosition != INVALID_POSITION) {
-                // Bound the position within the visible children.
-                final int position = MathUtils.constrain(
-                        (accessibilityFocusPosition - mFirstPosition), 0, (getChildCount() - 1));
-                final View restoreView = getChildAt(position);
-                if (restoreView != null) {
-                    restoreView.requestAccessibilityFocus();
-                }
-            }
-
-            // tell focus view we are done mucking with it, if it is still in
-            // our view hierarchy.
-            if (focusLayoutRestoreView != null
-                    && focusLayoutRestoreView.getWindowToken() != null) {
-                focusLayoutRestoreView.onFinishTemporaryDetach();
+            if (focusedChild != null) {
+                focusedChild.setHasTransientState(false);
             }
             
             mLayoutMode = LAYOUT_NORMAL;
@@ -1768,45 +1730,34 @@
     }
 
     /**
-     * @param focusedView the view that has accessibility focus.
-     * @return the direct child that contains accessibility focus.
+     * @return the direct child that contains accessibility focus, or null if no
+     *         child contains accessibility focus
      */
-    private View findAccessibilityFocusedChild(View focusedView) {
+    private View getAccessibilityFocusedChild() {
+        final ViewRootImpl viewRootImpl = getViewRootImpl();
+        if (viewRootImpl == null) {
+            return null;
+        }
+
+        View focusedView = viewRootImpl.getAccessibilityFocusedHost();
+        if (focusedView == null) {
+            return null;
+        }
+
         ViewParent viewParent = focusedView.getParent();
         while ((viewParent instanceof View) && (viewParent != this)) {
             focusedView = (View) viewParent;
             viewParent = viewParent.getParent();
         }
+
         if (!(viewParent instanceof View)) {
             return null;
         }
+
         return focusedView;
     }
 
     /**
-     * @param child a direct child of this list.
-     * @return Whether child is a header or footer view.
-     */
-    private boolean isDirectChildHeaderOrFooter(View child) {
-
-        final ArrayList<FixedViewInfo> headers = mHeaderViewInfos;
-        final int numHeaders = headers.size();
-        for (int i = 0; i < numHeaders; i++) {
-            if (child == headers.get(i).view) {
-                return true;
-            }
-        }
-        final ArrayList<FixedViewInfo> footers = mFooterViewInfos;
-        final int numFooters = footers.size();
-        for (int i = 0; i < numFooters; i++) {
-            if (child == footers.get(i).view) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
      * Obtain the view and add it to our list of children. The view can be made
      * fresh, converted from an unused view, or used as is if it was in the
      * recycle bin.
@@ -1861,6 +1812,8 @@
      */
     private void setupChild(View child, int position, int y, boolean flowDown, int childrenLeft,
             boolean selected, boolean recycled) {
+        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "setupListItem");
+
         final boolean isSelected = selected && shouldShowSelector();
         final boolean updateChildSelected = isSelected != child.isSelected();
         final int mode = mTouchMode;
@@ -1941,6 +1894,8 @@
                 != position) {
             child.jumpDrawablesToCurrentState();
         }
+
+        Trace.traceEnd(Trace.TRACE_TAG_VIEW);
     }
 
     @Override
@@ -2058,17 +2013,61 @@
                     position--;
                 }
             }
-
-            if (position < 0 || position >= count) {
-                return INVALID_POSITION;
-            }
-            return position;
-        } else {
-            if (position < 0 || position >= count) {
-                return INVALID_POSITION;
-            }
-            return position;
         }
+
+        if (position < 0 || position >= count) {
+            return INVALID_POSITION;
+        }
+
+        return position;
+    }
+
+    /**
+     * Find a position that can be selected (i.e., is not a separator). If there
+     * are no selectable positions in the specified direction from the starting
+     * position, searches in the opposite direction from the starting position
+     * to the current position.
+     *
+     * @param current the current position
+     * @param position the starting position
+     * @param lookDown whether to look down for other positions
+     * @return the next selectable position, or {@link #INVALID_POSITION} if
+     *         nothing can be found
+     */
+    int lookForSelectablePositionAfter(int current, int position, boolean lookDown) {
+        final ListAdapter adapter = mAdapter;
+        if (adapter == null || isInTouchMode()) {
+            return INVALID_POSITION;
+        }
+
+        // First check after the starting position in the specified direction.
+        final int after = lookForSelectablePosition(position, lookDown);
+        if (after != INVALID_POSITION) {
+            return after;
+        }
+
+        // Then check between the starting position and the current position.
+        final int count = adapter.getCount();
+        current = MathUtils.constrain(current, -1, count - 1);
+        if (lookDown) {
+            position = Math.min(position - 1, count - 1);
+            while ((position > current) && !adapter.isEnabled(position)) {
+                position--;
+            }
+            if (position <= current) {
+                return INVALID_POSITION;
+            }
+        } else {
+            position = Math.max(0, position + 1);
+            while ((position < current) && !adapter.isEnabled(position)) {
+                position++;
+            }
+            if (position >= current) {
+                return INVALID_POSITION;
+            }
+        }
+
+        return position;
     }
 
     /**
@@ -2281,27 +2280,30 @@
      * @return whether selection was moved
      */
     boolean pageScroll(int direction) {
-        int nextPage = -1;
-        boolean down = false;
+        final int nextPage;
+        final boolean down;
 
         if (direction == FOCUS_UP) {
             nextPage = Math.max(0, mSelectedPosition - getChildCount() - 1);
+            down = false;
         } else if (direction == FOCUS_DOWN) {
             nextPage = Math.min(mItemCount - 1, mSelectedPosition + getChildCount() - 1);
             down = true;
+        } else {
+            return false;
         }
 
         if (nextPage >= 0) {
-            int position = lookForSelectablePosition(nextPage, down);
+            final int position = lookForSelectablePositionAfter(mSelectedPosition, nextPage, down);
             if (position >= 0) {
                 mLayoutMode = LAYOUT_SPECIFIC;
                 mSpecificTop = mPaddingTop + getVerticalFadingEdgeLength();
 
-                if (down && position > mItemCount - getChildCount()) {
+                if (down && (position > (mItemCount - getChildCount()))) {
                     mLayoutMode = LAYOUT_FORCE_BOTTOM;
                 }
 
-                if (!down && position < getChildCount()) {
+                if (!down && (position < getChildCount())) {
                     mLayoutMode = LAYOUT_FORCE_TOP;
                 }
 
@@ -2319,18 +2321,18 @@
     }
 
     /**
-     * Go to the last or first item if possible (not worrying about panning across or navigating
-     * within the internal focus of the currently selected item.)
+     * Go to the last or first item if possible (not worrying about panning
+     * across or navigating within the internal focus of the currently selected
+     * item.)
      *
      * @param direction either {@link View#FOCUS_UP} or {@link View#FOCUS_DOWN}
-     *
      * @return whether selection was moved
      */
     boolean fullScroll(int direction) {
         boolean moved = false;
         if (direction == FOCUS_UP) {
             if (mSelectedPosition != 0) {
-                int position = lookForSelectablePosition(0, true);
+                final int position = lookForSelectablePositionAfter(mSelectedPosition, 0, true);
                 if (position >= 0) {
                     mLayoutMode = LAYOUT_FORCE_TOP;
                     setSelectionInt(position);
@@ -2339,8 +2341,10 @@
                 moved = true;
             }
         } else if (direction == FOCUS_DOWN) {
-            if (mSelectedPosition < mItemCount - 1) {
-                int position = lookForSelectablePosition(mItemCount - 1, true);
+            final int lastItem = (mItemCount - 1);
+            if (mSelectedPosition < lastItem) {
+                final int position = lookForSelectablePositionAfter(
+                        mSelectedPosition, lastItem, false);
                 if (position >= 0) {
                     mLayoutMode = LAYOUT_FORCE_BOTTOM;
                     setSelectionInt(position);
@@ -2425,24 +2429,37 @@
 
     /**
      * Used by {@link #arrowScrollImpl(int)} to help determine the next selected position
-     * to move to. This can return a position currently not represented by a view on screen
-     * but only in the direction given.
+     * to move to. This return a position in the direction given if the selected item
+     * is fully visible.
      *
+     * @param selectedView Current selected view to move from
      * @param selectedPos Current selected position to move from
      * @param direction Direction to move in
      * @return Desired selected position after moving in the given direction
      */
-    private final int nextSelectedPositionForDirection(int selectedPos, int direction) {
+    private final int nextSelectedPositionForDirection(
+            View selectedView, int selectedPos, int direction) {
         int nextSelected;
+
         if (direction == View.FOCUS_DOWN) {
-            nextSelected = selectedPos != INVALID_POSITION && selectedPos >= mFirstPosition ?
-                    selectedPos + 1 :
-                    mFirstPosition;
+            final int listBottom = getHeight() - mListPadding.bottom;
+            if (selectedView != null && selectedView.getBottom() <= listBottom) {
+                nextSelected = selectedPos != INVALID_POSITION && selectedPos >= mFirstPosition ?
+                        selectedPos + 1 :
+                        mFirstPosition;
+            } else {
+                return INVALID_POSITION;
+            }
         } else {
-            final int lastPos = mFirstPosition + getChildCount() - 1;
-            nextSelected = selectedPos != INVALID_POSITION && selectedPos <= lastPos ?
-                    selectedPos - 1 :
-                    lastPos;
+            final int listTop = mListPadding.top;
+            if (selectedView != null && selectedView.getTop() >= listTop) {
+                final int lastPos = mFirstPosition + getChildCount() - 1;
+                nextSelected = selectedPos != INVALID_POSITION && selectedPos <= lastPos ?
+                        selectedPos - 1 :
+                        lastPos;
+            } else {
+                return INVALID_POSITION;
+            }
         }
 
         if (nextSelected < 0 || nextSelected >= mAdapter.getCount()) {
@@ -2466,7 +2483,7 @@
         View selectedView = getSelectedView();
         int selectedPos = mSelectedPosition;
 
-        int nextSelectedPosition = nextSelectedPositionForDirection(selectedPos, direction);
+        int nextSelectedPosition = nextSelectedPositionForDirection(selectedView, selectedPos, direction);
         int amountToScroll = amountToScroll(direction, nextSelectedPosition);
 
         // if we are moving focus, we may OVERRIDE the default behavior
@@ -3195,7 +3212,7 @@
             final int count = getChildCount();
             final int headerCount = mHeaderViewInfos.size();
             final int itemCount = mItemCount;
-            final int footerLimit = itemCount - mFooterViewInfos.size() - 1;
+            final int footerLimit = (itemCount - mFooterViewInfos.size());
             final boolean headerDividers = mHeaderDividersEnabled;
             final boolean footerDividers = mFooterDividersEnabled;
             final int first = mFirstPosition;
@@ -3239,17 +3256,25 @@
                 }
 
                 for (int i = 0; i < count; i++) {
-                    if ((headerDividers || first + i >= headerCount) &&
-                            (footerDividers || first + i < footerLimit)) {
-                        View child = getChildAt(i);
+                    final int itemIndex = (first + i);
+                    final boolean isHeader = (itemIndex < headerCount);
+                    final boolean isFooter = (itemIndex >= footerLimit);
+                    if ((headerDividers || !isHeader) && (footerDividers || !isFooter)) {
+                        final View child = getChildAt(i);
                         bottom = child.getBottom();
-                        // Don't draw dividers next to items that are not enabled
+                        final boolean isLastItem = (i == (count - 1));
 
-                        if (drawDividers &&
-                                (bottom < listBottom && !(drawOverscrollFooter && i == count - 1))) {
-                            if ((areAllItemsSelectable ||
-                                    (adapter.isEnabled(first + i) && (i == count - 1 ||
-                                            adapter.isEnabled(first + i + 1))))) {
+                        if (drawDividers && (bottom < listBottom)
+                                && !(drawOverscrollFooter && isLastItem)) {
+                            final int nextIndex = (itemIndex + 1);
+                            // Draw dividers between enabled items, headers and/or
+                            // footers when enabled, and the end of the list.
+                            if (areAllItemsSelectable || ((adapter.isEnabled(itemIndex)
+                                    || (headerDividers && isHeader)
+                                    || (footerDividers && isFooter)) && (isLastItem
+                                    || adapter.isEnabled(nextIndex)
+                                    || (headerDividers && (nextIndex < headerCount))
+                                    || (footerDividers && (nextIndex >= footerLimit))))) {
                                 bounds.top = bottom;
                                 bounds.bottom = bottom + dividerHeight;
                                 drawDivider(canvas, bounds, i);
@@ -3282,20 +3307,28 @@
 
                 final int start = drawOverscrollHeader ? 1 : 0;
                 for (int i = start; i < count; i++) {
-                    if ((headerDividers || first + i >= headerCount) &&
-                            (footerDividers || first + i < footerLimit)) {
-                        View child = getChildAt(i);
+                    final int itemIndex = (first + i);
+                    final boolean isHeader = (itemIndex < headerCount);
+                    final boolean isFooter = (itemIndex >= footerLimit);
+                    if ((headerDividers || !isHeader) && (footerDividers || !isFooter)) {
+                        final View child = getChildAt(i);
                         top = child.getTop();
-                        // Don't draw dividers next to items that are not enabled
-                        if (top > effectivePaddingTop) {
-                            if ((areAllItemsSelectable ||
-                                    (adapter.isEnabled(first + i) && (i == count - 1 ||
-                                            adapter.isEnabled(first + i + 1))))) {
+                        if (drawDividers && (top > effectivePaddingTop)) {
+                            final boolean isFirstItem = (i == start);
+                            final int previousIndex = (itemIndex - 1);
+                            // Draw dividers between enabled items, headers and/or
+                            // footers when enabled, and the end of the list.
+                            if (areAllItemsSelectable || ((adapter.isEnabled(itemIndex)
+                                    || (headerDividers && isHeader)
+                                    || (footerDividers && isFooter)) && (isFirstItem
+                                    || adapter.isEnabled(previousIndex)
+                                    || (headerDividers && (previousIndex < headerCount))
+                                    || (footerDividers && (previousIndex >= footerLimit))))) {
                                 bounds.top = top - dividerHeight;
                                 bounds.bottom = top;
-                                // Give the method the child ABOVE the divider, so we
-                                // subtract one from our child
-                                // position. Give -1 when there is no child above the
+                                // Give the method the child ABOVE the divider,
+                                // so we subtract one from our child position.
+                                // Give -1 when there is no child above the
                                 // divider.
                                 drawDivider(canvas, bounds, i - 1);
                             } else if (fillForMissingDividers) {
@@ -3404,6 +3437,7 @@
      * @param headerDividersEnabled True to draw the headers, false otherwise.
      *
      * @see #setFooterDividersEnabled(boolean)
+     * @see #areHeaderDividersEnabled()
      * @see #addHeaderView(android.view.View)
      */
     public void setHeaderDividersEnabled(boolean headerDividersEnabled) {
@@ -3412,17 +3446,36 @@
     }
 
     /**
+     * @return Whether the drawing of the divider for header views is enabled
+     *
+     * @see #setHeaderDividersEnabled(boolean)
+     */
+    public boolean areHeaderDividersEnabled() {
+        return mHeaderDividersEnabled;
+    }
+
+    /**
      * Enables or disables the drawing of the divider for footer views.
      *
      * @param footerDividersEnabled True to draw the footers, false otherwise.
      *
      * @see #setHeaderDividersEnabled(boolean)
+     * @see #areFooterDividersEnabled()
      * @see #addFooterView(android.view.View)
      */
     public void setFooterDividersEnabled(boolean footerDividersEnabled) {
         mFooterDividersEnabled = footerDividersEnabled;
         invalidate();
     }
+
+    /**
+     * @return Whether the drawing of the divider for footer views is enabled
+     *
+     * @see #setFooterDividersEnabled(boolean)
+     */
+    public boolean areFooterDividersEnabled() {
+        return mFooterDividersEnabled;
+    }
     
     /**
      * Sets the drawable that will be drawn above all other list content.
@@ -3728,5 +3781,20 @@
     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfo(info);
         info.setClassName(ListView.class.getName());
+
+        final int count = getCount();
+        final CollectionInfo collectionInfo = CollectionInfo.obtain(1, count, false);
+        info.setCollectionInfo(collectionInfo);
+    }
+
+    @Override
+    public void onInitializeAccessibilityNodeInfoForItem(
+            View view, int position, AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfoForItem(view, position, info);
+
+        final LayoutParams lp = (LayoutParams) view.getLayoutParams();
+        final boolean isHeading = lp != null && lp.viewType != ITEM_VIEW_TYPE_HEADER_OR_FOOTER;
+        final CollectionItemInfo itemInfo = CollectionItemInfo.obtain(0, 1, position, 1, isHeading);
+        info.setCollectionItemInfo(itemInfo);
     }
 }
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 4a98f66..19cc3c2 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -1425,6 +1425,7 @@
 
     @Override
     protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
         removeAllCallbacks();
     }
 
diff --git a/core/java/android/widget/PopupMenu.java b/core/java/android/widget/PopupMenu.java
index 6a6d767..603db70 100644
--- a/core/java/android/widget/PopupMenu.java
+++ b/core/java/android/widget/PopupMenu.java
@@ -26,6 +26,8 @@
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
+import android.view.View.OnTouchListener;
+import android.widget.ListPopupWindow.ForwardingListener;
 
 /**
  * A PopupMenu displays a {@link Menu} in a modal popup window anchored to a {@link View}.
@@ -40,6 +42,7 @@
     private MenuPopupHelper mPopup;
     private OnMenuItemClickListener mMenuItemClickListener;
     private OnDismissListener mDismissListener;
+    private OnTouchListener mDragListener;
 
     /**
      * Callback interface used to notify the application that the menu has closed.
@@ -71,6 +74,35 @@
     }
 
     /**
+     * Returns an {@link OnTouchListener} that can be added to the anchor view
+     * to implement drag-to-open behavior.
+     * <p>
+     * When the listener is set on a view, touching that view and dragging
+     * outside of its bounds will open the popup window. Lifting will select the
+     * currently touched list item.
+     * <p>
+     * Example usage:
+     * <pre>
+     * PopupMenu myPopup = new PopupMenu(context, myAnchor);
+     * myAnchor.setOnTouchListener(myPopup.getDragToOpenListener());
+     * </pre>
+     *
+     * @return a touch listener that controls drag-to-open behavior
+     */
+    public OnTouchListener getDragToOpenListener() {
+        if (mDragListener == null) {
+            mDragListener = new ForwardingListener(mAnchor) {
+                @Override
+                public ListPopupWindow getPopup() {
+                    return mPopup.getPopup();
+                }
+            };
+        }
+
+        return mDragListener;
+    }
+
+    /**
      * @return the {@link Menu} associated with this popup. Populate the returned Menu with
      * items before calling {@link #show()}.
      *
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index f940226..e03e83d 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -16,22 +16,21 @@
 
 package android.widget;
 
+import android.util.ArrayMap;
 import com.android.internal.R;
 
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Comparator;
-import java.util.HashMap;
 import java.util.SortedSet;
 import java.util.TreeSet;
 
 import android.content.Context;
-import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Rect;
 import android.os.Build;
 import android.util.AttributeSet;
-import android.util.Pools.SimplePool;
+import android.util.Pools.SynchronizedPool;
 import android.util.SparseArray;
 import android.view.Gravity;
 import android.view.View;
@@ -42,7 +41,6 @@
 import android.widget.RemoteViews.RemoteView;
 
 import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
-import static android.util.Log.d;
 
 /**
  * A Layout where the positions of the children can be described in relation to each other or to the
@@ -83,10 +81,6 @@
  */
 @RemoteView
 public class RelativeLayout extends ViewGroup {
-    private static final String LOG_TAG = "RelativeLayout";
-
-    private static final boolean DEBUG_GRAPH = false;
-
     public static final int TRUE = -1;
 
     /**
@@ -212,8 +206,8 @@
     private SortedSet<View> mTopToBottomLeftToRightSet = null;
     
     private boolean mDirtyHierarchy;
-    private View[] mSortedHorizontalChildren = new View[0];
-    private View[] mSortedVerticalChildren = new View[0];
+    private View[] mSortedHorizontalChildren;
+    private View[] mSortedVerticalChildren;
     private final DependencyGraph mGraph = new DependencyGraph();
 
     // Compatibility hack. Old versions of the platform had problems
@@ -360,42 +354,26 @@
     }
 
     private void sortChildren() {
-        int count = getChildCount();
-        if (mSortedVerticalChildren.length != count) mSortedVerticalChildren = new View[count];
-        if (mSortedHorizontalChildren.length != count) mSortedHorizontalChildren = new View[count];
+        final int count = getChildCount();
+        if (mSortedVerticalChildren == null || mSortedVerticalChildren.length != count) {
+            mSortedVerticalChildren = new View[count];
+        }
+
+        if (mSortedHorizontalChildren == null || mSortedHorizontalChildren.length != count) {
+            mSortedHorizontalChildren = new View[count];
+        }
 
         final DependencyGraph graph = mGraph;
         graph.clear();
 
         for (int i = 0; i < count; i++) {
-            final View child = getChildAt(i);
-            graph.add(child);
-        }
-
-        if (DEBUG_GRAPH) {
-            d(LOG_TAG, "=== Sorted vertical children");
-            graph.log(getResources(), RULES_VERTICAL);
-            d(LOG_TAG, "=== Sorted horizontal children");
-            graph.log(getResources(), RULES_HORIZONTAL);
+            graph.add(getChildAt(i));
         }
 
         graph.getSortedViews(mSortedVerticalChildren, RULES_VERTICAL);
         graph.getSortedViews(mSortedHorizontalChildren, RULES_HORIZONTAL);
-
-        if (DEBUG_GRAPH) {
-            d(LOG_TAG, "=== Ordered list of vertical children");
-            for (View view : mSortedVerticalChildren) {
-                DependencyGraph.printViewId(getResources(), view);
-            }
-            d(LOG_TAG, "=== Ordered list of horizontal children");
-            for (View view : mSortedHorizontalChildren) {
-                DependencyGraph.printViewId(getResources(), view);
-            }
-        }        
     }
 
-    // TODO: we need to find another way to implement RelativeLayout
-    // This implementation cannot handle every case
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         if (mDirtyHierarchy) {
@@ -484,6 +462,7 @@
 
         views = mSortedVerticalChildren;
         count = views.length;
+        final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
 
         for (int i = 0; i < count; i++) {
             View child = views[i];
@@ -498,14 +477,26 @@
 
                 if (isWrapContentWidth) {
                     if (isLayoutRtl()) {
-                        width = Math.max(width, myWidth - params.mLeft);
+                        if (targetSdkVersion < Build.VERSION_CODES.KITKAT) {
+                            width = Math.max(width, myWidth - params.mLeft);
+                        } else {
+                            width = Math.max(width, myWidth - params.mLeft - params.leftMargin);
+                        }
                     } else {
-                        width = Math.max(width, params.mRight);
+                        if (targetSdkVersion < Build.VERSION_CODES.KITKAT) {
+                            width = Math.max(width, params.mRight);
+                        } else {
+                            width = Math.max(width, params.mRight + params.rightMargin);
+                        }
                     }
                 }
 
                 if (isWrapContentHeight) {
-                    height = Math.max(height, params.mBottom);
+                    if (targetSdkVersion < Build.VERSION_CODES.KITKAT) {
+                        height = Math.max(height, params.mBottom);
+                    } else {
+                        height = Math.max(height, params.mBottom + params.bottomMargin);
+                    }
                 }
 
                 if (child != ignore || verticalGravity) {
@@ -545,7 +536,7 @@
             // the right of each child view
             width += mPaddingRight;
 
-            if (mLayoutParams.width >= 0) {
+            if (mLayoutParams != null && mLayoutParams.width >= 0) {
                 width = Math.max(width, mLayoutParams.width);
             }
 
@@ -575,7 +566,7 @@
             // the bottom of each child view
             height += mPaddingBottom;
 
-            if (mLayoutParams.height >= 0) {
+            if (mLayoutParams != null && mLayoutParams.height >= 0) {
                 height = Math.max(height, mLayoutParams.height);
             }
 
@@ -900,8 +891,6 @@
         } else if (childParams.alignWithParent && rules[LEFT_OF] != 0) {
             if (myWidth >= 0) {
                 childParams.mRight = myWidth - mPaddingRight - childParams.rightMargin;
-            } else {
-                // FIXME uh oh...
             }
         }
 
@@ -926,8 +915,6 @@
         } else if (childParams.alignWithParent && rules[ALIGN_RIGHT] != 0) {
             if (myWidth >= 0) {
                 childParams.mRight = myWidth - mPaddingRight - childParams.rightMargin;
-            } else {
-                // FIXME uh oh...
             }
         }
 
@@ -938,8 +925,6 @@
         if (0 != rules[ALIGN_PARENT_RIGHT]) {
             if (myWidth >= 0) {
                 childParams.mRight = myWidth - mPaddingRight - childParams.rightMargin;
-            } else {
-                // FIXME uh oh...
             }
         }
     }
@@ -958,8 +943,6 @@
         } else if (childParams.alignWithParent && rules[ABOVE] != 0) {
             if (myHeight >= 0) {
                 childParams.mBottom = myHeight - mPaddingBottom - childParams.bottomMargin;
-            } else {
-                // FIXME uh oh...
             }
         }
 
@@ -984,8 +967,6 @@
         } else if (childParams.alignWithParent && rules[ALIGN_BOTTOM] != 0) {
             if (myHeight >= 0) {
                 childParams.mBottom = myHeight - mPaddingBottom - childParams.bottomMargin;
-            } else {
-                // FIXME uh oh...
             }
         }
 
@@ -996,8 +977,6 @@
         if (0 != rules[ALIGN_PARENT_BOTTOM]) {
             if (myHeight >= 0) {
                 childParams.mBottom = myHeight - mPaddingBottom - childParams.bottomMargin;
-            } else {
-                // FIXME uh oh...
             }
         }
 
@@ -1355,6 +1334,24 @@
             super(source);
         }
 
+        /**
+         * Copy constructor. Clones the width, height, margin values, and rules
+         * of the source.
+         *
+         * @param source The layout params to copy from.
+         */
+        public LayoutParams(LayoutParams source) {
+            super(source);
+
+            this.mIsRtlCompatibilityMode = source.mIsRtlCompatibilityMode;
+            this.mRulesChanged = source.mRulesChanged;
+            this.alignWithParent = source.alignWithParent;
+
+            System.arraycopy(source.mRules, LEFT_OF, this.mRules, LEFT_OF, VERB_COUNT);
+            System.arraycopy(
+                    source.mInitialRules, LEFT_OF, this.mInitialRules, LEFT_OF, VERB_COUNT);
+        }
+
         @Override
         public String debug(String output) {
             return output + "ViewGroup.LayoutParams={ width=" + sizeToString(width) +
@@ -1677,8 +1674,10 @@
 
                 sorted[index++] = view;
 
-                final HashMap<Node, DependencyGraph> dependents = node.dependents;
-                for (Node dependent : dependents.keySet()) {
+                final ArrayMap<Node, DependencyGraph> dependents = node.dependents;
+                final int count = dependents.size();
+                for (int i = 0; i < count; i++) {
+                    final Node dependent = dependents.keyAt(i);
                     final SparseArray<Node> dependencies = dependent.dependencies;
 
                     dependencies.remove(key);
@@ -1756,61 +1755,6 @@
         }
 
         /**
-         * Prints the dependency graph for the specified rules.
-         *
-         * @param resources The context's resources to print the ids.
-         * @param rules The list of rules to take into account.
-         */
-        void log(Resources resources, int... rules) {
-            final ArrayDeque<Node> roots = findRoots(rules);
-            for (Node node : roots) {
-                printNode(resources, node);
-            }
-        }
-
-        static void printViewId(Resources resources, View view) {
-            if (view.getId() != View.NO_ID) {
-                d(LOG_TAG, resources.getResourceEntryName(view.getId()));
-            } else {
-                d(LOG_TAG, "NO_ID");
-            }
-        }
-
-        private static void appendViewId(Resources resources, Node node, StringBuilder buffer) {
-            if (node.view.getId() != View.NO_ID) {
-                buffer.append(resources.getResourceEntryName(node.view.getId()));
-            } else {
-                buffer.append("NO_ID");
-            }
-        }
-
-        private static void printNode(Resources resources, Node node) {
-            if (node.dependents.size() == 0) {
-                printViewId(resources, node.view);
-            } else {
-                for (Node dependent : node.dependents.keySet()) {
-                    StringBuilder buffer = new StringBuilder();
-                    appendViewId(resources, node, buffer);
-                    printdependents(resources, dependent, buffer);
-                }
-            }
-        }
-
-        private static void printdependents(Resources resources, Node node, StringBuilder buffer) {
-            buffer.append(" -> ");
-            appendViewId(resources, node, buffer);
-
-            if (node.dependents.size() == 0) {
-                d(LOG_TAG, buffer.toString());
-            } else {
-                for (Node dependent : node.dependents.keySet()) {
-                    StringBuilder subBuffer = new StringBuilder(buffer);
-                    printdependents(resources, dependent, subBuffer);
-                }
-            }
-        }
-
-        /**
          * A node in the dependency graph. A node is a view, its list of dependencies
          * and its list of dependents.
          *
@@ -1826,7 +1770,8 @@
              * The list of dependents for this node; a dependent is a node
              * that needs this node to be processed first.
              */
-            final HashMap<Node, DependencyGraph> dependents = new HashMap<Node, DependencyGraph>();
+            final ArrayMap<Node, DependencyGraph> dependents =
+                    new ArrayMap<Node, DependencyGraph>();
 
             /**
              * The list of dependencies for this node.
@@ -1839,7 +1784,8 @@
             // The pool is static, so all nodes instances are shared across
             // activities, that's why we give it a rather high limit
             private static final int POOL_LIMIT = 100;
-            private static final SimplePool<Node> sPool = new SimplePool<Node>(POOL_LIMIT);
+            private static final SynchronizedPool<Node> sPool =
+                    new SynchronizedPool<Node>(POOL_LIMIT);
 
             static Node acquire(View view) {
                 Node node = sPool.acquire();
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 07e66b7..0d3df51 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -37,6 +37,7 @@
 import android.os.StrictMode;
 import android.os.UserHandle;
 import android.text.TextUtils;
+import android.util.ArrayMap;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.LayoutInflater.Filter;
@@ -45,6 +46,7 @@
 import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.widget.AdapterView.OnItemClickListener;
+import libcore.util.Objects;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
@@ -136,6 +138,49 @@
 
     private static final OnClickHandler DEFAULT_ON_CLICK_HANDLER = new OnClickHandler();
 
+    private static final Object[] sMethodsLock = new Object[0];
+    private static final ArrayMap<Class<? extends View>, ArrayMap<MutablePair<String, Class<?>>, Method>> sMethods =
+            new ArrayMap<Class<? extends View>, ArrayMap<MutablePair<String, Class<?>>, Method>>();
+    private static final ThreadLocal<Object[]> sInvokeArgsTls = new ThreadLocal<Object[]>() {
+        @Override
+        protected Object[] initialValue() {
+            return new Object[1];
+        }
+    };
+
+    /**
+     * Handle with care!
+     */
+    static class MutablePair<F, S> {
+        F first;
+        S second;
+
+        MutablePair(F first, S second) {
+            this.first = first;
+            this.second = second;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (!(o instanceof MutablePair)) {
+                return false;
+            }
+            MutablePair<?, ?> p = (MutablePair<?, ?>) o;
+            return Objects.equal(p.first, first) && Objects.equal(p.second, second);
+        }
+
+        @Override
+        public int hashCode() {
+            return (first == null ? 0 : first.hashCode()) ^ (second == null ? 0 : second.hashCode());
+        }
+    }
+
+    /**
+     * This pair is used to perform lookups in sMethods without causing allocations.
+     */
+    private final MutablePair<String, Class<?>> mPair =
+            new MutablePair<String, Class<?>>(null, null);
+
     /**
      * This annotation indicates that a subclass of View is alllowed to be used
      * with the {@link RemoteViews} mechanism.
@@ -206,9 +251,8 @@
          * Overridden by each class to report on it's own memory usage
          */
         public void updateMemoryUsageEstimate(MemoryUsageCounter counter) {
-            // We currently only calculate Bitmap memory usage, so by default, don't do anything
-            // here
-            return;
+            // We currently only calculate Bitmap memory usage, so by default,
+            // don't do anything here
         }
 
         public void setBitmapCache(BitmapCache bitmapCache) {
@@ -346,7 +390,7 @@
             }
             if (target == root) {
                 target.setTagInternal(com.android.internal.R.id.fillInIntent, fillInIntent);
-            } else if (target != null && fillInIntent != null) {
+            } else if (fillInIntent != null) {
                 OnClickListener listener = new OnClickListener() {
                     public void onClick(View v) {
                         // Insure that this view is a child of an AdapterView
@@ -372,16 +416,7 @@
 
                         PendingIntent pendingIntent = (PendingIntent) parent.getTag();
 
-                        final float appScale = v.getContext().getResources()
-                                .getCompatibilityInfo().applicationScale;
-                        final int[] pos = new int[2];
-                        v.getLocationOnScreen(pos);
-
-                        final Rect rect = new Rect();
-                        rect.left = (int) (pos[0] * appScale + 0.5f);
-                        rect.top = (int) (pos[1] * appScale + 0.5f);
-                        rect.right = (int) ((pos[0] + v.getWidth()) * appScale + 0.5f);
-                        rect.bottom = (int) ((pos[1] + v.getHeight()) * appScale + 0.5f);
+                        final Rect rect = getSourceBounds(v);
 
                         fillInIntent.setSourceBounds(rect);
                         handler.onClickHandler(v, pendingIntent, fillInIntent);
@@ -452,16 +487,7 @@
                             }
                             if (fillInIntent == null) return;
 
-                            final float appScale = view.getContext().getResources()
-                                    .getCompatibilityInfo().applicationScale;
-                            final int[] pos = new int[2];
-                            view.getLocationOnScreen(pos);
-
-                            final Rect rect = new Rect();
-                            rect.left = (int) (pos[0] * appScale + 0.5f);
-                            rect.top = (int) (pos[1] * appScale + 0.5f);
-                            rect.right = (int) ((pos[0] + view.getWidth()) * appScale + 0.5f);
-                            rect.bottom = (int) ((pos[1] + view.getHeight()) * appScale + 0.5f);
+                            final Rect rect = getSourceBounds(view);
 
                             final Intent intent = new Intent();
                             intent.setSourceBounds(rect);
@@ -679,33 +705,22 @@
                 }
             }
 
-            if (target != null) {
-                // If the pendingIntent is null, we clear the onClickListener
-                OnClickListener listener = null;
-                if (pendingIntent != null) {
-                    listener = new OnClickListener() {
-                        public void onClick(View v) {
-                            // Find target view location in screen coordinates and
-                            // fill into PendingIntent before sending.
-                            final float appScale = v.getContext().getResources()
-                                    .getCompatibilityInfo().applicationScale;
-                            final int[] pos = new int[2];
-                            v.getLocationOnScreen(pos);
+            // If the pendingIntent is null, we clear the onClickListener
+            OnClickListener listener = null;
+            if (pendingIntent != null) {
+                listener = new OnClickListener() {
+                    public void onClick(View v) {
+                        // Find target view location in screen coordinates and
+                        // fill into PendingIntent before sending.
+                        final Rect rect = getSourceBounds(v);
 
-                            final Rect rect = new Rect();
-                            rect.left = (int) (pos[0] * appScale + 0.5f);
-                            rect.top = (int) (pos[1] * appScale + 0.5f);
-                            rect.right = (int) ((pos[0] + v.getWidth()) * appScale + 0.5f);
-                            rect.bottom = (int) ((pos[1] + v.getHeight()) * appScale + 0.5f);
-
-                            final Intent intent = new Intent();
-                            intent.setSourceBounds(rect);
-                            handler.onClickHandler(v, pendingIntent, intent);
-                        }
-                    };
-                }
-                target.setOnClickListener(listener);
+                        final Intent intent = new Intent();
+                        intent.setSourceBounds(rect);
+                        handler.onClickHandler(v, pendingIntent, intent);
+                    }
+                };
             }
+            target.setOnClickListener(listener);
         }
 
         public String getActionName() {
@@ -717,6 +732,71 @@
         public final static int TAG = 1;
     }
 
+    private static Rect getSourceBounds(View v) {
+        final float appScale = v.getContext().getResources()
+                .getCompatibilityInfo().applicationScale;
+        final int[] pos = new int[2];
+        v.getLocationOnScreen(pos);
+
+        final Rect rect = new Rect();
+        rect.left = (int) (pos[0] * appScale + 0.5f);
+        rect.top = (int) (pos[1] * appScale + 0.5f);
+        rect.right = (int) ((pos[0] + v.getWidth()) * appScale + 0.5f);
+        rect.bottom = (int) ((pos[1] + v.getHeight()) * appScale + 0.5f);
+        return rect;
+    }
+
+    private Method getMethod(View view, String methodName, Class<?> paramType) {
+        Method method;
+        Class<? extends View> klass = view.getClass();
+
+        synchronized (sMethodsLock) {
+            ArrayMap<MutablePair<String, Class<?>>, Method> methods = sMethods.get(klass);
+            if (methods == null) {
+                methods = new ArrayMap<MutablePair<String, Class<?>>, Method>();
+                sMethods.put(klass, methods);
+            }
+
+            mPair.first = methodName;
+            mPair.second = paramType;
+
+            method = methods.get(mPair);
+            if (method == null) {
+                try {
+                    if (paramType == null) {
+                        method = klass.getMethod(methodName);
+                    } else {
+                        method = klass.getMethod(methodName, paramType);
+                    }
+                } catch (NoSuchMethodException ex) {
+                    throw new ActionException("view: " + klass.getName() + " doesn't have method: "
+                            + methodName + getParameters(paramType));
+                }
+
+                if (!method.isAnnotationPresent(RemotableViewMethod.class)) {
+                    throw new ActionException("view: " + klass.getName()
+                            + " can't use method with RemoteViews: "
+                            + methodName + getParameters(paramType));
+                }
+
+                methods.put(new MutablePair<String, Class<?>>(methodName, paramType), method);
+            }
+        }
+
+        return method;
+    }
+
+    private static String getParameters(Class<?> paramType) {
+        if (paramType == null) return "()";
+        return "(" + paramType + ")";
+    }
+
+    private static Object[] wrapArg(Object value) {
+        Object[] args = sInvokeArgsTls.get();
+        args[0] = value;
+        return args;
+    }
+
     /**
      * Equivalent to calling a combination of {@link Drawable#setAlpha(int)},
      * {@link Drawable#setColorFilter(int, android.graphics.PorterDuff.Mode)},
@@ -810,8 +890,8 @@
         public final static int TAG = 3;
     }
 
-    private class ReflectionActionWithoutParams extends Action {
-        String methodName;
+    private final class ReflectionActionWithoutParams extends Action {
+        final String methodName;
 
         public final static int TAG = 5;
 
@@ -836,28 +916,10 @@
             final View view = root.findViewById(viewId);
             if (view == null) return;
 
-            Class klass = view.getClass();
-            Method method;
             try {
-                method = klass.getMethod(this.methodName);
-            } catch (NoSuchMethodException ex) {
-                throw new ActionException("view: " + klass.getName() + " doesn't have method: "
-                        + this.methodName + "()");
-            }
-
-            if (!method.isAnnotationPresent(RemotableViewMethod.class)) {
-                throw new ActionException("view: " + klass.getName()
-                        + " can't use method with RemoteViews: "
-                        + this.methodName + "()");
-            }
-
-            try {
-                //noinspection ConstantIfStatement
-                if (false) {
-                    Log.d(LOG_TAG, "view: " + klass.getName() + " calling method: "
-                        + this.methodName + "()");
-                }
-                method.invoke(view);
+                getMethod(view, this.methodName, null).invoke(view);
+            } catch (ActionException e) {
+                throw e;
             } catch (Exception ex) {
                 throw new ActionException(ex);
             }
@@ -990,7 +1052,7 @@
     /**
      * Base class for the reflection actions.
      */
-    private class ReflectionAction extends Action {
+    private final class ReflectionAction extends Action {
         static final int TAG = 2;
 
         static final int BOOLEAN = 1;
@@ -1157,7 +1219,7 @@
             }
         }
 
-        private Class getParameterType() {
+        private Class<?> getParameterType() {
             switch (this.type) {
                 case BOOLEAN:
                     return boolean.class;
@@ -1197,37 +1259,16 @@
             final View view = root.findViewById(viewId);
             if (view == null) return;
 
-            Class param = getParameterType();
+            Class<?> param = getParameterType();
             if (param == null) {
                 throw new ActionException("bad type: " + this.type);
             }
 
-            Class klass = view.getClass();
-            Method method;
             try {
-                method = klass.getMethod(this.methodName, getParameterType());
-            }
-            catch (NoSuchMethodException ex) {
-                throw new ActionException("view: " + klass.getName() + " doesn't have method: "
-                        + this.methodName + "(" + param.getName() + ")");
-            }
-
-            if (!method.isAnnotationPresent(RemotableViewMethod.class)) {
-                throw new ActionException("view: " + klass.getName()
-                        + " can't use method with RemoteViews: "
-                        + this.methodName + "(" + param.getName() + ")");
-            }
-
-            try {
-                //noinspection ConstantIfStatement
-                if (false) {
-                    Log.d(LOG_TAG, "view: " + klass.getName() + " calling method: "
-                        + this.methodName + "(" + param.getName() + ") with "
-                        + (this.value == null ? "null" : this.value.getClass().getName()));
-                }
-                method.invoke(view, this.value);
-            }
-            catch (Exception ex) {
+                getMethod(view, this.methodName, param).invoke(view, wrapArg(this.value));
+            } catch (ActionException e) {
+                throw e;
+            } catch (Exception ex) {
                 throw new ActionException(ex);
             }
         }
@@ -1323,7 +1364,7 @@
         }
 
         public String getActionName() {
-            return "ViewGroupAction" + this.nestedViews == null ? "Remove" : "Add";
+            return "ViewGroupAction" + (nestedViews == null ? "Remove" : "Add");
         }
 
         public int mergeBehavior() {
@@ -1370,7 +1411,6 @@
 
         @Override
         public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
-            final Context context = root.getContext();
             final TextView target = (TextView) root.findViewById(viewId);
             if (target == null) return;
             if (isRelative) {
@@ -1415,7 +1455,6 @@
 
         @Override
         public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
-            final Context context = root.getContext();
             final TextView target = (TextView) root.findViewById(viewId);
             if (target == null) return;
             target.setTextSize(units, size);
@@ -1462,7 +1501,6 @@
 
         @Override
         public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
-            final Context context = root.getContext();
             final View target = root.findViewById(viewId);
             if (target == null) return;
             target.setPadding(left, top, right, bottom);
@@ -1494,6 +1532,7 @@
             return mMemoryUsage;
         }
 
+        @SuppressWarnings("deprecation")
         public void addBitmapMemory(Bitmap b) {
             final Bitmap.Config c = b.getConfig();
             // If we don't know, be pessimistic and assume 4
@@ -1597,7 +1636,7 @@
         if (mode == MODE_NORMAL) {
             mPackage = parcel.readString();
             mLayoutId = parcel.readInt();
-            mIsWidgetCollectionChild = parcel.readInt() == 1 ? true : false;
+            mIsWidgetCollectionChild = parcel.readInt() == 1;
 
             int count = parcel.readInt();
             if (count > 0) {
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index aeee111..3ff0cee 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -22,9 +22,11 @@
 import java.util.HashSet;
 import java.util.LinkedList;
 
+import android.Manifest;
 import android.appwidget.AppWidgetManager;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IBinder;
@@ -34,6 +36,7 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.Log;
+import android.util.Slog;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.View.MeasureSpec;
@@ -50,9 +53,11 @@
  */
 /** @hide */
 public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback {
+    private static final String MULTI_USER_PERM = Manifest.permission.INTERACT_ACROSS_USERS_FULL;
+
     private static final String TAG = "RemoteViewsAdapter";
 
-    // The max number of items in the cache 
+    // The max number of items in the cache
     private static final int sDefaultCacheSize = 40;
     // The delay (in millis) to wait until attempting to unbind from a service after a request.
     // This ensures that we don't stay continually bound to the service and that it can be destroyed
@@ -63,7 +68,7 @@
     private static final int sDefaultLoadingViewHeight = 50;
 
     // Type defs for controlling different messages across the main and worker message queues
-    private static final int sDefaultMessageType = 0; 
+    private static final int sDefaultMessageType = 0;
     private static final int sUnbindServiceMessageType = 1;
 
     private final Context mContext;
@@ -90,7 +95,7 @@
     private Handler mMainQueue;
 
     // We cache the FixedSizeRemoteViewsCaches across orientation. These are the related data
-    // structures; 
+    // structures;
     private static final HashMap<RemoteViewsCacheKey,
             FixedSizeRemoteViewsCache> sCachedRemoteViewsCaches
             = new HashMap<RemoteViewsCacheKey,
@@ -155,13 +160,12 @@
                 try {
                     RemoteViewsAdapter adapter;
                     final AppWidgetManager mgr = AppWidgetManager.getInstance(context);
-                    if (Process.myUid() == Process.SYSTEM_UID
-                            && (adapter = mAdapter.get()) != null) {
+                    if ((adapter = mAdapter.get()) != null) {
+                        checkInteractAcrossUsersPermission(context, adapter.mUserId);
                         mgr.bindRemoteViewsService(appWidgetId, intent, asBinder(),
                                 new UserHandle(adapter.mUserId));
                     } else {
-                        mgr.bindRemoteViewsService(appWidgetId, intent, asBinder(),
-                                Process.myUserHandle());
+                        Slog.w(TAG, "bind: adapter was null");
                     }
                     mIsConnecting = true;
                 } catch (Exception e) {
@@ -176,12 +180,12 @@
             try {
                 RemoteViewsAdapter adapter;
                 final AppWidgetManager mgr = AppWidgetManager.getInstance(context);
-                if (Process.myUid() == Process.SYSTEM_UID
-                        && (adapter = mAdapter.get()) != null) {
+                if ((adapter = mAdapter.get()) != null) {
+                    checkInteractAcrossUsersPermission(context, adapter.mUserId);
                     mgr.unbindRemoteViewsService(appWidgetId, intent,
                             new UserHandle(adapter.mUserId));
                 } else {
-                    mgr.unbindRemoteViewsService(appWidgetId, intent, Process.myUserHandle());
+                    Slog.w(TAG, "unbind: adapter was null");
                 }
                 mIsConnecting = false;
             } catch (Exception e) {
@@ -263,7 +267,7 @@
             // Clear the main/worker queues
             final RemoteViewsAdapter adapter = mAdapter.get();
             if (adapter == null) return;
-            
+
             adapter.mMainQueue.post(new Runnable() {
                 @Override
                 public void run() {
@@ -828,11 +832,9 @@
         }
         mRequestedViews = new RemoteViewsFrameLayoutRefSet();
 
-        if (Process.myUid() == Process.SYSTEM_UID) {
-            mUserId = new LockPatternUtils(context).getCurrentUser();
-        } else {
-            mUserId = UserHandle.myUserId();
-        }
+        checkInteractAcrossUsersPermission(context, UserHandle.myUserId());
+        mUserId = context.getUserId();
+
         // Strip the previously injected app widget id from service intent
         if (intent.hasExtra(RemoteViews.EXTRA_REMOTEADAPTER_APPWIDGET_ID)) {
             intent.removeExtra(RemoteViews.EXTRA_REMOTEADAPTER_APPWIDGET_ID);
@@ -876,6 +878,15 @@
         }
     }
 
+    private static void checkInteractAcrossUsersPermission(Context context, int userId) {
+        if (context.getUserId() != userId
+                && context.checkCallingOrSelfPermission(MULTI_USER_PERM)
+                != PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException("Must have permission " + MULTI_USER_PERM
+                    + " to inflate another user's widget");
+        }
+    }
+
     @Override
     protected void finalize() throws Throwable {
         try {
diff --git a/core/java/android/widget/ScrollBarDrawable.java b/core/java/android/widget/ScrollBarDrawable.java
index 93a1179..9886bc3 100644
--- a/core/java/android/widget/ScrollBarDrawable.java
+++ b/core/java/android/widget/ScrollBarDrawable.java
@@ -226,6 +226,12 @@
     }
 
     @Override
+    public int getAlpha() {
+        // All elements should have same alpha, just return one of them
+        return mVerticalThumb.getAlpha();
+    }
+
+    @Override
     public void setColorFilter(ColorFilter cf) {
         if (mVerticalTrack != null) {
             mVerticalTrack.setColorFilter(cf);
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index bc41931..6680393 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -16,6 +16,9 @@
 
 package android.widget;
 
+import android.os.Build;
+import android.os.Parcel;
+import android.os.Parcelable;
 import com.android.internal.R;
 
 import android.content.Context;
@@ -149,6 +152,8 @@
      */
     private static final int INVALID_POINTER = -1;
 
+    private SavedState mSavedState;
+
     public ScrollView(Context context) {
         this(context, null);
     }
@@ -631,12 +636,13 @@
                     final boolean canOverscroll = overscrollMode == OVER_SCROLL_ALWAYS ||
                             (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0);
 
+                    // Calling overScrollBy will call onOverScrolled, which
+                    // calls onScrollChanged if applicable.
                     if (overScrollBy(0, deltaY, 0, mScrollY,
                             0, range, 0, mOverscrollDistance, true)) {
                         // Break our velocity if we hit a scroll barrier.
                         mVelocityTracker.clear();
                     }
-                    onScrollChanged(mScrollX, mScrollY, oldX, oldY);
 
                     if (canOverscroll) {
                         final int pulledToY = oldY + deltaY;
@@ -753,9 +759,12 @@
             boolean clampedX, boolean clampedY) {
         // Treat animating scrolls differently; see #computeScroll() for why.
         if (!mScroller.isFinished()) {
+            final int oldX = mScrollX;
+            final int oldY = mScrollY;
             mScrollX = scrollX;
             mScrollY = scrollY;
             invalidateParentIfNeeded();
+            onScrollChanged(mScrollX, mScrollY, oldX, oldY);
             if (clampedY) {
                 mScroller.springBack(mScrollX, mScrollY, 0, 0, 0, getScrollRange());
             }
@@ -1464,6 +1473,24 @@
         }
         mChildToScrollTo = null;
 
+        if (!isLaidOut()) {
+            if (mSavedState != null) {
+                mScrollY = mSavedState.scrollPosition;
+                mSavedState = null;
+            } // mScrollY default value is "0"
+
+            final int childHeight = (getChildCount() > 0) ? getChildAt(0).getMeasuredHeight() : 0;
+            final int scrollRange = Math.max(0,
+                    childHeight - (b - t - mPaddingBottom - mPaddingTop));
+
+            // Don't forget to clamp
+            if (mScrollY > scrollRange) {
+                mScrollY = scrollRange;
+            } else if (mScrollY < 0) {
+                mScrollY = 0;
+            }
+        }
+
         // Calling this with the present values causes it to re-claim them
         scrollTo(mScrollX, mScrollY);
     }
@@ -1633,4 +1660,69 @@
         }
         return n;
     }
+
+    @Override
+    protected void onRestoreInstanceState(Parcelable state) {
+        if (mContext.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.JELLY_BEAN_MR2) {
+            // Some old apps reused IDs in ways they shouldn't have.
+            // Don't break them, but they don't get scroll state restoration.
+            super.onRestoreInstanceState(state);
+            return;
+        }
+        SavedState ss = (SavedState) state;
+        super.onRestoreInstanceState(ss.getSuperState());
+        mSavedState = ss;
+        requestLayout();
+    }
+
+    @Override
+    protected Parcelable onSaveInstanceState() {
+        if (mContext.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.JELLY_BEAN_MR2) {
+            // Some old apps reused IDs in ways they shouldn't have.
+            // Don't break them, but they don't get scroll state restoration.
+            return super.onSaveInstanceState();
+        }
+        Parcelable superState = super.onSaveInstanceState();
+        SavedState ss = new SavedState(superState);
+        ss.scrollPosition = mScrollY;
+        return ss;
+    }
+
+    static class SavedState extends BaseSavedState {
+        public int scrollPosition;
+
+        SavedState(Parcelable superState) {
+            super(superState);
+        }
+
+        public SavedState(Parcel source) {
+            super(source);
+            scrollPosition = source.readInt();
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            super.writeToParcel(dest, flags);
+            dest.writeInt(scrollPosition);
+        }
+
+        @Override
+        public String toString() {
+            return "HorizontalScrollView.SavedState{"
+                    + Integer.toHexString(System.identityHashCode(this))
+                    + " scrollPosition=" + scrollPosition + "}";
+        }
+
+        public static final Parcelable.Creator<SavedState> CREATOR
+                = new Parcelable.Creator<SavedState>() {
+            public SavedState createFromParcel(Parcel in) {
+                return new SavedState(in);
+            }
+
+            public SavedState[] newArray(int size) {
+                return new SavedState[size];
+            }
+        };
+    }
+
 }
diff --git a/core/java/android/widget/SectionIndexer.java b/core/java/android/widget/SectionIndexer.java
index a1c71f4..f6333d1 100644
--- a/core/java/android/widget/SectionIndexer.java
+++ b/core/java/android/widget/SectionIndexer.java
@@ -17,38 +17,62 @@
 package android.widget;
 
 /**
- * Interface that should be implemented on Adapters to enable fast scrolling 
- * in an {@link AbsListView} between sections of the list. A section is a group of list items
- * to jump to that have something in common. For example, they may begin with the
- * same letter or they may be songs from the same artist. ExpandableListAdapters that
- * consider groups and sections as synonymous should account for collapsed groups and return
- * an appropriate section/position.
+ * Interface that may implemented on {@link Adapter}s to enable fast scrolling
+ * between sections of an {@link AbsListView}.
+ * <p>
+ * A section is a group of list items that have something in common. For
+ * example, they may begin with the same letter or they may be songs from the
+ * same artist.
+ * <p>
+ * {@link ExpandableListAdapter}s that consider groups and sections as
+ * synonymous should account for collapsed groups and return an appropriate
+ * section/position.
+ *
+ * @see AbsListView#setFastScrollEnabled(boolean)
  */
 public interface SectionIndexer {
     /**
-     * This provides the list view with an array of section objects. In the simplest
-     * case these are Strings, each containing one letter of the alphabet.
-     * They could be more complex objects that indicate the grouping for the adapter's
-     * consumption. The list view will call toString() on the objects to get the
-     * preview letter to display while scrolling.
-     * @return the array of objects that indicate the different sections of the list.
+     * Returns an array of objects representing sections of the list. The
+     * returned array and its contents should be non-null.
+     * <p>
+     * The list view will call toString() on the objects to get the preview text
+     * to display while scrolling. For example, an adapter may return an array
+     * of Strings representing letters of the alphabet. Or, it may return an
+     * array of objects whose toString() methods return their section titles.
+     *
+     * @return the array of section objects
      */
     Object[] getSections();
-    
+
     /**
-     * Provides the starting index in the list for a given section.
-     * @param section the index of the section to jump to.
-     * @return the starting position of that section. If the section is out of bounds, the
-     * position must be clipped to fall within the size of the list.
+     * Given the index of a section within the array of section objects, returns
+     * the starting position of that section within the adapter.
+     * <p>
+     * If the section's starting position is outside of the adapter bounds, the
+     * position must be clipped to fall within the size of the adapter.
+     *
+     * @param sectionIndex the index of the section within the array of section
+     *            objects
+     * @return the starting position of that section within the adapter,
+     *         constrained to fall within the adapter bounds
      */
-    int getPositionForSection(int section);
-    
+    int getPositionForSection(int sectionIndex);
+
     /**
-     * This is a reverse mapping to fetch the section index for a given position
-     * in the list.
-     * @param position the position for which to return the section
-     * @return the section index. If the position is out of bounds, the section index
+     * Given a position within the adapter, returns the index of the
+     * corresponding section within the array of section objects.
+     * <p>
+     * If the section index is outside of the section array bounds, the index
      * must be clipped to fall within the size of the section array.
+     * <p>
+     * For example, consider an indexer where the section at array index 0
+     * starts at adapter position 100. Calling this method with position 10,
+     * which is before the first section, must return index 0.
+     *
+     * @param position the position within the adapter for which to return the
+     *            corresponding section index
+     * @return the index of the corresponding section within the array of
+     *         section objects, constrained to fall within the array bounds
      */
-    int getSectionForPosition(int position);    
+    int getSectionForPosition(int position);
 }
diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java
index 9e7f97e..b204dfd 100644
--- a/core/java/android/widget/SpellChecker.java
+++ b/core/java/android/widget/SpellChecker.java
@@ -753,4 +753,39 @@
             }
         }
     }
+
+    public static boolean haveWordBoundariesChanged(final Editable editable, final int start,
+            final int end, final int spanStart, final int spanEnd) {
+        final boolean haveWordBoundariesChanged;
+        if (spanEnd != start && spanStart != end) {
+            haveWordBoundariesChanged = true;
+            if (DBG) {
+                Log.d(TAG, "(1) Text inside the span has been modified. Remove.");
+            }
+        } else if (spanEnd == start && start < editable.length()) {
+            final int codePoint = Character.codePointAt(editable, start);
+            haveWordBoundariesChanged = Character.isLetterOrDigit(codePoint);
+            if (DBG) {
+                Log.d(TAG, "(2) Characters have been appended to the spanned text. "
+                        + (haveWordBoundariesChanged ? "Remove.<" : "Keep. <") + (char)(codePoint)
+                        + ">, " + editable + ", " + editable.subSequence(spanStart, spanEnd) + ", "
+                        + start);
+            }
+        } else if (spanStart == end && end > 0) {
+            final int codePoint = Character.codePointBefore(editable, end);
+            haveWordBoundariesChanged = Character.isLetterOrDigit(codePoint);
+            if (DBG) {
+                Log.d(TAG, "(3) Characters have been prepended to the spanned text. "
+                        + (haveWordBoundariesChanged ? "Remove.<" : "Keep.<") + (char)(codePoint)
+                        + ">, " + editable + ", " + editable.subSequence(spanStart, spanEnd) + ", "
+                        + end);
+            }
+        } else {
+            if (DBG) {
+                Log.d(TAG, "(4) Characters adjacent to the spanned text were deleted. Keep.");
+            }
+            haveWordBoundariesChanged = false;
+        }
+        return haveWordBoundariesChanged;
+    }
 }
diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java
index e3de0b9..b75d36f 100644
--- a/core/java/android/widget/Spinner.java
+++ b/core/java/android/widget/Spinner.java
@@ -30,12 +30,14 @@
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.Gravity;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.view.ViewTreeObserver.OnGlobalLayoutListener;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.widget.ListPopupWindow.ForwardingListener;
 import android.widget.PopupWindow.OnDismissListener;
 
 
@@ -76,7 +78,10 @@
      * Use the theme-supplied value to select the dropdown mode.
      */
     private static final int MODE_THEME = -1;
-    
+
+    /** Forwarding listener used to implement drag-to-open. */
+    private ForwardingListener mForwardingListener;
+
     private SpinnerPopup mPopup;
     private DropDownAdapter mTempAdapter;
     int mDropDownWidth;
@@ -173,7 +178,7 @@
         }
 
         case MODE_DROPDOWN: {
-            DropdownPopup popup = new DropdownPopup(context, attrs, defStyle);
+            final DropdownPopup popup = new DropdownPopup(context, attrs, defStyle);
 
             mDropDownWidth = a.getLayoutDimension(
                     com.android.internal.R.styleable.Spinner_dropDownWidth,
@@ -193,6 +198,20 @@
             }
 
             mPopup = popup;
+            mForwardingListener = new ForwardingListener(this) {
+                @Override
+                public ListPopupWindow getPopup() {
+                    return popup;
+                }
+
+                @Override
+                public boolean onForwardingStarted() {
+                    if (!mPopup.isShowing()) {
+                        mPopup.show(getTextDirection(), getTextAlignment());
+                    }
+                    return true;
+                }
+            };
             break;
         }
         }
@@ -377,10 +396,24 @@
         return mGravity;
     }
 
+    /**
+     * Sets the Adapter used to provide the data which backs this Spinner.
+     * <p>
+     * Note that Spinner overrides {@link Adapter#getViewTypeCount()} on the
+     * Adapter associated with this view. Calling
+     * {@link Adapter#getItemViewType(int) getItemViewType(int)} on the object
+     * returned from {@link #getAdapter()} will always return 0. Calling
+     * {@link Adapter#getViewTypeCount() getViewTypeCount()} will always return
+     * 1.
+     *
+     * @see AbsSpinner#setAdapter(SpinnerAdapter)
+     */
     @Override
     public void setAdapter(SpinnerAdapter adapter) {
         super.setAdapter(adapter);
 
+        mRecycler.clear();
+
         if (mPopup != null) {
             mPopup.setAdapter(new DropDownAdapter(adapter));
         } else {
@@ -395,9 +428,8 @@
         if (getChildCount() > 0) {
             child = getChildAt(0);
         } else if (mAdapter != null && mAdapter.getCount() > 0) {
-            child = makeAndAddView(0);
+            child = makeView(0, false);
             mRecycler.put(0, child);
-            removeAllViewsInLayout();
         }
 
         if (child != null) {
@@ -437,6 +469,15 @@
     }
 
     @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        if (mForwardingListener != null && mForwardingListener.onTouch(this, event)) {
+            return true;
+        }
+
+        return super.onTouchEvent(event);
+    }
+
+    @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
         if (mPopup != null && MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.AT_MOST) {
@@ -496,7 +537,7 @@
         mFirstPosition = mSelectedPosition;
 
         if (mAdapter != null) {
-            View sel = makeAndAddView(mSelectedPosition);
+            View sel = makeView(mSelectedPosition, true);
             int width = sel.getMeasuredWidth();
             int selectedOffset = childrenLeft;
             final int layoutDirection = getLayoutDirection();
@@ -531,17 +572,17 @@
      * from the old to new positions.
      *
      * @param position Position in the spinner for the view to obtain
-     * @return A view that has been added to the spinner
+     * @param addChild true to add the child to the spinner, false to obtain and configure only.
+     * @return A view for the given position
      */
-    private View makeAndAddView(int position) {
-
+    private View makeView(int position, boolean addChild) {
         View child;
 
         if (!mDataChanged) {
             child = mRecycler.get(position);
             if (child != null) {
                 // Position the view
-                setUpChild(child);
+                setUpChild(child, addChild);
 
                 return child;
             }
@@ -551,7 +592,7 @@
         child = mAdapter.getView(position, null, this);
 
         // Position the view
-        setUpChild(child);
+        setUpChild(child, addChild);
 
         return child;
     }
@@ -561,8 +602,9 @@
      * and fill out its layout paramters.
      *
      * @param child The view to position
+     * @param addChild true if the child should be added to the Spinner during setup
      */
-    private void setUpChild(View child) {
+    private void setUpChild(View child, boolean addChild) {
 
         // Respect layout params that are already in the view. Otherwise
         // make some up...
@@ -571,7 +613,9 @@
             lp = generateDefaultLayoutParams();
         }
 
-        addViewInLayout(child, 0, lp);
+        if (addChild) {
+            addViewInLayout(child, 0, lp);
+        }
 
         child.setSelected(hasFocus());
         if (mDisableChildrenWhenDisabled) {
@@ -633,6 +677,10 @@
     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfo(info);
         info.setClassName(Spinner.class.getName());
+
+        if (mAdapter != null) {
+            info.setCanOpenPopup(true);
+        }
     }
 
     /**
@@ -925,6 +973,9 @@
         }
 
         public void show(int textDirection, int textAlignment) {
+            if (mListAdapter == null) {
+                return;
+            }
             AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
             if (mPrompt != null) {
                 builder.setTitle(mPrompt);
diff --git a/core/java/android/widget/TextClock.java b/core/java/android/widget/TextClock.java
index a564c96..b3b95d9 100644
--- a/core/java/android/widget/TextClock.java
+++ b/core/java/android/widget/TextClock.java
@@ -95,6 +95,7 @@
      *
      * @see #setFormat12Hour(CharSequence)
      * @see #getFormat12Hour()
+     *
      * @deprecated Let the system use locale-appropriate defaults instead.
      */
     public static final CharSequence DEFAULT_FORMAT_12_HOUR = "h:mm a";
@@ -108,6 +109,7 @@
      *
      * @see #setFormat24Hour(CharSequence)
      * @see #getFormat24Hour()
+     *
      * @deprecated Let the system use locale-appropriate defaults instead.
      */
     public static final CharSequence DEFAULT_FORMAT_24_HOUR = "H:mm";
@@ -162,9 +164,7 @@
     };
 
     /**
-     * Creates a new clock using the default patterns
-     * {@link #DEFAULT_FORMAT_24_HOUR} and {@link #DEFAULT_FORMAT_12_HOUR}
-     * respectively for the 24-hour and 12-hour modes.
+     * Creates a new clock using the default patterns for the current locale.
      *
      * @param context The Context the view is running in, through which it can
      *        access the current theme, resources, etc.
@@ -258,20 +258,26 @@
     }
 
     /**
-     * Specifies the formatting pattern used to display the date and/or time
+     * <p>Specifies the formatting pattern used to display the date and/or time
      * in 12-hour mode. The formatting pattern syntax is described in
-     * {@link DateFormat}.
+     * {@link DateFormat}.</p>
      *
-     * If this pattern is set to null, {@link #getFormat24Hour()} will be used
+     * <p>If this pattern is set to null, {@link #getFormat24Hour()} will be used
      * even in 12-hour mode. If both 24-hour and 12-hour formatting patterns
-     * are set to null, {@link #DEFAULT_FORMAT_24_HOUR} and
-     * {@link #DEFAULT_FORMAT_12_HOUR} will be used instead.
+     * are set to null, the default pattern for the current locale will be used
+     * instead.</p>
+     *
+     * <p><strong>Note:</strong> if styling is not needed, it is highly recommended
+     * you supply a format string generated by
+     * {@link DateFormat#getBestDateTimePattern(java.util.Locale, String)}. This method
+     * takes care of generating a format string adapted to the desired locale.</p>
+     *
      *
      * @param format A date/time formatting pattern as described in {@link DateFormat}
      *
      * @see #getFormat12Hour()
      * @see #is24HourModeEnabled()
-     * @see #DEFAULT_FORMAT_12_HOUR
+     * @see DateFormat#getBestDateTimePattern(java.util.Locale, String)
      * @see DateFormat
      *
      * @attr ref android.R.styleable#TextClock_format12Hour
@@ -300,20 +306,25 @@
     }
 
     /**
-     * Specifies the formatting pattern used to display the date and/or time
+     * <p>Specifies the formatting pattern used to display the date and/or time
      * in 24-hour mode. The formatting pattern syntax is described in
-     * {@link DateFormat}.
+     * {@link DateFormat}.</p>
      *
-     * If this pattern is set to null, {@link #getFormat12Hour()} will be used
-     * even in 24-hour mode. If both 24-hour and 12-hour formatting patterns
-     * are set to null, {@link #DEFAULT_FORMAT_24_HOUR} and
-     * {@link #DEFAULT_FORMAT_12_HOUR} will be used instead.
+     * <p>If this pattern is set to null, {@link #getFormat24Hour()} will be used
+     * even in 12-hour mode. If both 24-hour and 12-hour formatting patterns
+     * are set to null, the default pattern for the current locale will be used
+     * instead.</p>
+     *
+     * <p><strong>Note:</strong> if styling is not needed, it is highly recommended
+     * you supply a format string generated by
+     * {@link DateFormat#getBestDateTimePattern(java.util.Locale, String)}. This method
+     * takes care of generating a format string adapted to the desired locale.</p>
      *
      * @param format A date/time formatting pattern as described in {@link DateFormat}
      *
      * @see #getFormat24Hour()
      * @see #is24HourModeEnabled()
-     * @see #DEFAULT_FORMAT_24_HOUR
+     * @see DateFormat#getBestDateTimePattern(java.util.Locale, String)
      * @see DateFormat
      *
      * @attr ref android.R.styleable#TextClock_format24Hour
@@ -334,8 +345,7 @@
      * returned by {@link #getFormat12Hour()} is used instead.
      *
      * If either one of the formats is null, the other format is used. If
-     * both formats are null, the default values {@link #DEFAULT_FORMAT_12_HOUR}
-     * and {@link #DEFAULT_FORMAT_24_HOUR} are used instead.
+     * both formats are null, the default formats for the current locale are used.
      *
      * @return true if time should be displayed in 24-hour format, false if it
      *         should be displayed in 12-hour format.
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 04c4070..ae1b627 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -20,6 +20,7 @@
 import android.content.ClipData;
 import android.content.ClipboardManager;
 import android.content.Context;
+import android.content.UndoManager;
 import android.content.res.ColorStateList;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Resources;
@@ -291,6 +292,13 @@
 
     private boolean mPreDrawRegistered;
 
+    // A flag to prevent repeated movements from escaping the enclosing text view. The idea here is
+    // that if a user is holding down a movement key to traverse text, we shouldn't also traverse
+    // the view hierarchy. On the other hand, if the user is using the movement key to traverse views
+    // (i.e. the first movement was to traverse out of this view, or this view was traversed into by
+    // the user holding the movement key down) then we shouldn't prevent the focus from changing.
+    private boolean mPreventDefaultMovement;
+
     private TextUtils.TruncateAt mEllipsize;
 
     static class Drawables {
@@ -351,9 +359,7 @@
                             mDrawableRight = mDrawableStart;
                             mDrawableSizeRight = mDrawableSizeStart;
                             mDrawableHeightRight = mDrawableHeightStart;
-                        }
 
-                        if (mOverride) {
                             mDrawableLeft = mDrawableEnd;
                             mDrawableSizeLeft = mDrawableSizeEnd;
                             mDrawableHeightLeft = mDrawableHeightEnd;
@@ -366,9 +372,7 @@
                             mDrawableLeft = mDrawableStart;
                             mDrawableSizeLeft = mDrawableSizeStart;
                             mDrawableHeightLeft = mDrawableHeightStart;
-                        }
 
-                        if (mOverride) {
                             mDrawableRight = mDrawableEnd;
                             mDrawableSizeRight = mDrawableSizeEnd;
                             mDrawableHeightRight = mDrawableHeightEnd;
@@ -547,7 +551,6 @@
     private InputFilter[] mFilters = NO_FILTERS;
 
     private volatile Locale mCurrentSpellCheckerLocaleCache;
-    private final ReentrantLock mCurrentTextServicesLocaleLock = new ReentrantLock();
 
     // It is possible to have a selection even when mEditor is null (programmatically set, like when
     // a link is pressed). These highlight-related fields do not go in mEditor.
@@ -1371,6 +1374,8 @@
             } else {
                 dr.mDrawableSizeEnd = dr.mDrawableHeightEnd = 0;
             }
+            resetResolvedDrawables();
+            resolveDrawables();
         }
     }
 
@@ -1510,6 +1515,51 @@
     }
 
     /**
+     * Retrieve the {@link android.content.UndoManager} that is currently associated
+     * with this TextView.  By default there is no associated UndoManager, so null
+     * is returned.  One can be associated with the TextView through
+     * {@link #setUndoManager(android.content.UndoManager, String)}
+     *
+     * @hide
+     */
+    public final UndoManager getUndoManager() {
+        return mEditor == null ? null : mEditor.mUndoManager;
+    }
+
+    /**
+     * Associate an {@link android.content.UndoManager} with this TextView.  Once
+     * done, all edit operations on the TextView will result in appropriate
+     * {@link android.content.UndoOperation} objects pushed on the given UndoManager's
+     * stack.
+     *
+     * @param undoManager The {@link android.content.UndoManager} to associate with
+     * this TextView, or null to clear any existing association.
+     * @param tag String tag identifying this particular TextView owner in the
+     * UndoManager.  This is used to keep the correct association with the
+     * {@link android.content.UndoOwner} of any operations inside of the UndoManager.
+     *
+     * @hide
+     */
+    public final void setUndoManager(UndoManager undoManager, String tag) {
+        if (undoManager != null) {
+            createEditorIfNeeded();
+            mEditor.mUndoManager = undoManager;
+            mEditor.mUndoOwner = undoManager.getOwner(tag, this);
+            mEditor.mUndoInputFilter = new Editor.UndoInputFilter(mEditor);
+            if (!(mText instanceof Editable)) {
+                setText(mText, BufferType.EDITABLE);
+            }
+
+            setFilters((Editable) mText, mFilters);
+        } else if (mEditor != null) {
+            // XXX need to destroy all associated state.
+            mEditor.mUndoManager = null;
+            mEditor.mUndoOwner = null;
+            mEditor.mUndoInputFilter = null;
+        }
+    }
+
+    /**
      * @return the current key listener for this TextView.
      * This will frequently be null for non-EditText TextViews.
      *
@@ -1673,7 +1723,8 @@
         setText(mText);
 
         if (hasPasswordTransformationMethod()) {
-            notifyAccessibilityStateChanged();
+            notifyViewAccessibilityStateChangedIfNeeded(
+                    AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
         }
     }
 
@@ -1994,6 +2045,8 @@
             dr.mDrawableRightInitial = right;
         }
 
+        resetResolvedDrawables();
+        resolveDrawables();
         invalidate();
         requestLayout();
     }
@@ -3774,6 +3827,8 @@
         sendOnTextChanged(text, 0, oldlen, textLength);
         onTextChanged(text, 0, oldlen, textLength);
 
+        notifyViewAccessibilityStateChangedIfNeeded(AccessibilityEvent.CONTENT_CHANGE_TYPE_TEXT);
+
         if (needEditableForNotification) {
             sendAfterTextChanged((Editable) text);
         }
@@ -4358,6 +4413,8 @@
     public void setError(CharSequence error, Drawable icon) {
         createEditorIfNeeded();
         mEditor.setError(error, icon);
+        notifyViewAccessibilityStateChangedIfNeeded(
+                AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
     }
 
     @Override
@@ -4401,16 +4458,30 @@
      * and includes mInput in the list if it is an InputFilter.
      */
     private void setFilters(Editable e, InputFilter[] filters) {
-        if (mEditor != null && mEditor.mKeyListener instanceof InputFilter) {
-            InputFilter[] nf = new InputFilter[filters.length + 1];
+        if (mEditor != null) {
+            final boolean undoFilter = mEditor.mUndoInputFilter != null;
+            final boolean keyFilter = mEditor.mKeyListener instanceof InputFilter;
+            int num = 0;
+            if (undoFilter) num++;
+            if (keyFilter) num++;
+            if (num > 0) {
+                InputFilter[] nf = new InputFilter[filters.length + num];
 
-            System.arraycopy(filters, 0, nf, 0, filters.length);
-            nf[filters.length] = (InputFilter) mEditor.mKeyListener;
+                System.arraycopy(filters, 0, nf, 0, filters.length);
+                num = 0;
+                if (undoFilter) {
+                    nf[filters.length] = mEditor.mUndoInputFilter;
+                    num++;
+                }
+                if (keyFilter) {
+                    nf[filters.length + num] = (InputFilter) mEditor.mKeyListener;
+                }
 
-            e.setFilters(nf);
-        } else {
-            e.setFilters(filters);
+                e.setFilters(nf);
+                return;
+            }
         }
+        e.setFilters(filters);
     }
 
     /**
@@ -5282,7 +5353,6 @@
     public boolean onKeyDown(int keyCode, KeyEvent event) {
         int which = doKeyDown(keyCode, event, null);
         if (which == 0) {
-            // Go through default dispatching.
             return super.onKeyDown(keyCode, event);
         }
 
@@ -5380,6 +5450,15 @@
             return 0;
         }
 
+        // If this is the initial keydown, we don't want to prevent a movement away from this view.
+        // While this shouldn't be necessary because any time we're preventing default movement we
+        // should be restricting the focus to remain within this view, thus we'll also receive
+        // the key up event, occasionally key up events will get dropped and we don't want to
+        // prevent the user from traversing out of this on the next key down.
+        if (event.getRepeatCount() == 0 && !KeyEvent.isModifierKey(keyCode)) {
+            mPreventDefaultMovement = false;
+        }
+
         switch (keyCode) {
             case KeyEvent.KEYCODE_ENTER:
                 if (event.hasNoModifiers()) {
@@ -5488,12 +5567,16 @@
                 }
             }
             if (doDown) {
-                if (mMovement.onKeyDown(this, (Spannable)mText, keyCode, event))
+                if (mMovement.onKeyDown(this, (Spannable)mText, keyCode, event)) {
+                    if (event.getRepeatCount() == 0 && !KeyEvent.isModifierKey(keyCode)) {
+                        mPreventDefaultMovement = true;
+                    }
                     return 2;
+                }
             }
         }
 
-        return 0;
+        return mPreventDefaultMovement && !KeyEvent.isModifierKey(keyCode) ? -1 : 0;
     }
 
     /**
@@ -5526,6 +5609,10 @@
             return super.onKeyUp(keyCode, event);
         }
 
+        if (!KeyEvent.isModifierKey(keyCode)) {
+            mPreventDefaultMovement = false;
+        }
+
         switch (keyCode) {
             case KeyEvent.KEYCODE_DPAD_CENTER:
                 if (event.hasNoModifiers()) {
@@ -7240,7 +7327,6 @@
      */
     protected void onSelectionChanged(int selStart, int selEnd) {
         sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED);
-        notifyAccessibilityStateChanged();
     }
 
     /**
@@ -7285,27 +7371,42 @@
         }
 
         // The spans that are inside or intersect the modified region no longer make sense
-        removeIntersectingSpans(start, start + before, SpellCheckSpan.class);
-        removeIntersectingSpans(start, start + before, SuggestionSpan.class);
+        removeIntersectingNonAdjacentSpans(start, start + before, SpellCheckSpan.class);
+        removeIntersectingNonAdjacentSpans(start, start + before, SuggestionSpan.class);
     }
 
     // Removes all spans that are inside or actually overlap the start..end range
-    private <T> void removeIntersectingSpans(int start, int end, Class<T> type) {
+    private <T> void removeIntersectingNonAdjacentSpans(int start, int end, Class<T> type) {
         if (!(mText instanceof Editable)) return;
         Editable text = (Editable) mText;
 
         T[] spans = text.getSpans(start, end, type);
         final int length = spans.length;
         for (int i = 0; i < length; i++) {
-            final int s = text.getSpanStart(spans[i]);
-            final int e = text.getSpanEnd(spans[i]);
-            // Spans that are adjacent to the edited region will be handled in
-            // updateSpellCheckSpans. Result depends on what will be added (space or text)
-            if (e == start || s == end) break;
+            final int spanStart = text.getSpanStart(spans[i]);
+            final int spanEnd = text.getSpanEnd(spans[i]);
+            if (spanEnd == start || spanStart == end) break;
             text.removeSpan(spans[i]);
         }
     }
 
+    void removeAdjacentSuggestionSpans(final int pos) {
+        if (!(mText instanceof Editable)) return;
+        final Editable text = (Editable) mText;
+
+        final SuggestionSpan[] spans = text.getSpans(pos, pos, SuggestionSpan.class);
+        final int length = spans.length;
+        for (int i = 0; i < length; i++) {
+            final int spanStart = text.getSpanStart(spans[i]);
+            final int spanEnd = text.getSpanEnd(spans[i]);
+            if (spanEnd == pos || spanStart == pos) {
+                if (SpellChecker.haveWordBoundariesChanged(text, pos, pos, spanStart, spanEnd)) {
+                    text.removeSpan(spans[i]);
+                }
+            }
+        }
+    }
+
     /**
      * Not private so it can be called from an inner class without going
      * through a thunk.
@@ -7958,16 +8059,13 @@
     }
 
     private void updateTextServicesLocaleAsync() {
+        // AsyncTask.execute() uses a serial executor which means we don't have
+        // to lock around updateTextServicesLocaleLocked() to prevent it from
+        // being executed n times in parallel.
         AsyncTask.execute(new Runnable() {
             @Override
             public void run() {
-                if (mCurrentTextServicesLocaleLock.tryLock()) {
-                    try {
-                        updateTextServicesLocaleLocked();
-                    } finally {
-                        mCurrentTextServicesLocaleLock.unlock();
-                    }
-                }
+                updateTextServicesLocaleLocked();
             }
         });
     }
@@ -8056,6 +8154,14 @@
             info.setEditable(true);
         }
 
+        if (mEditor != null) {
+            info.setInputType(mEditor.mInputType);
+
+            if (mEditor.mError != null) {
+                info.setContentInvalid(true);
+            }
+        }
+
         if (!TextUtils.isEmpty(mText)) {
             info.addAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY);
             info.addAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY);
@@ -8080,6 +8186,10 @@
                 info.addAction(AccessibilityNodeInfo.ACTION_CUT);
             }
         }
+
+        if (!isSingleLine()) {
+            info.setMultiLine(true);
+        }
     }
 
     @Override
@@ -8088,7 +8198,6 @@
             case AccessibilityNodeInfo.ACTION_COPY: {
                 if (isFocused() && canCopy()) {
                     if (onTextContextMenuItem(ID_COPY)) {
-                        notifyAccessibilityStateChanged();
                         return true;
                     }
                 }
@@ -8096,7 +8205,6 @@
             case AccessibilityNodeInfo.ACTION_PASTE: {
                 if (isFocused() && canPaste()) {
                     if (onTextContextMenuItem(ID_PASTE)) {
-                        notifyAccessibilityStateChanged();
                         return true;
                     }
                 }
@@ -8104,7 +8212,6 @@
             case AccessibilityNodeInfo.ACTION_CUT: {
                 if (isFocused() && canCut()) {
                     if (onTextContextMenuItem(ID_CUT)) {
-                        notifyAccessibilityStateChanged();
                         return true;
                     }
                 }
@@ -8123,7 +8230,6 @@
                         // No arguments clears the selection.
                         if (start == end && end == -1) {
                             Selection.removeSelection((Spannable) text);
-                            notifyAccessibilityStateChanged();
                             return true;
                         }
                         if (start >= 0 && start <= end && end <= text.length()) {
@@ -8132,7 +8238,6 @@
                             if (mEditor != null) {
                                 mEditor.startSelectionActionMode();
                             }
-                            notifyAccessibilityStateChanged();
                             return true;
                         }
                     }
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index e33c4d4..c26cb24 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -22,10 +22,12 @@
 import android.content.res.TypedArray;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.text.format.DateFormat;
 import android.text.format.DateUtils;
 import android.util.AttributeSet;
 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.inputmethod.EditorInfo;
@@ -105,6 +107,9 @@
 
     private Locale mCurrentLocale;
 
+    private boolean mHourWithTwoDigit;
+    private char mHourFormat;
+
     /**
      * The callback interface used to indicate the time has been adjusted.
      */
@@ -164,7 +169,7 @@
         // divider (only for the new widget style)
         mDivider = (TextView) findViewById(R.id.divider);
         if (mDivider != null) {
-            mDivider.setText(R.string.time_picker_separator);
+            setDividerText();
         }
 
         // minute
@@ -235,6 +240,24 @@
             mAmPmSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_DONE);
         }
 
+        if (isAmPmAtStart()) {
+            // Move the am/pm view to the beginning
+            ViewGroup amPmParent = (ViewGroup) findViewById(R.id.timePickerLayout);
+            amPmParent.removeView(amPmView);
+            amPmParent.addView(amPmView, 0);
+            // Swap layout margins if needed. They may be not symmetrical (Old Standard Theme for
+            // example and not for Holo Theme)
+            ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) amPmView.getLayoutParams();
+            final int startMargin = lp.getMarginStart();
+            final int endMargin = lp.getMarginEnd();
+            if (startMargin != endMargin) {
+                lp.setMarginStart(endMargin);
+                lp.setMarginEnd(startMargin);
+            }
+        }
+
+        getHourFormatData();
+
         // update controls to initial state
         updateHourControl();
         updateMinuteControl();
@@ -259,6 +282,35 @@
         }
     }
 
+    private void getHourFormatData() {
+        final Locale defaultLocale = Locale.getDefault();
+        final String bestDateTimePattern = DateFormat.getBestDateTimePattern(defaultLocale,
+                (mIs24HourView) ? "Hm" : "hm");
+        final int lengthPattern = bestDateTimePattern.length();
+        mHourWithTwoDigit = false;
+        char hourFormat = '\0';
+        // Check if the returned pattern is single or double 'H', 'h', 'K', 'k'. We also save
+        // the hour format that we found.
+        for (int i = 0; i < lengthPattern; i++) {
+            final char c = bestDateTimePattern.charAt(i);
+            if (c == 'H' || c == 'h' || c == 'K' || c == 'k') {
+                mHourFormat = c;
+                if (i + 1 < lengthPattern && c == bestDateTimePattern.charAt(i + 1)) {
+                    mHourWithTwoDigit = true;
+                }
+                break;
+            }
+        }
+    }
+
+    private boolean isAmPmAtStart() {
+        final Locale defaultLocale = Locale.getDefault();
+        final String bestDateTimePattern = DateFormat.getBestDateTimePattern(defaultLocale,
+                "hm" /* skeleton */);
+
+        return bestDateTimePattern.startsWith("a");
+    }
+
     @Override
     public void setEnabled(boolean enabled) {
         if (mIsEnabled == enabled) {
@@ -391,6 +443,10 @@
      * Set the current hour.
      */
     public void setCurrentHour(Integer currentHour) {
+        setCurrentHour(currentHour, true);
+    }
+
+    private void setCurrentHour(Integer currentHour, boolean notifyTimeChanged) {
         // why was Integer used in the first place?
         if (currentHour == null || currentHour == getCurrentHour()) {
             return;
@@ -411,7 +467,9 @@
             updateAmPmControl();
         }
         mHourSpinner.setValue(currentHour);
-        onTimeChanged();
+        if (notifyTimeChanged) {
+            onTimeChanged();
+        }
     }
 
     /**
@@ -423,12 +481,16 @@
         if (mIs24HourView == is24HourView) {
             return;
         }
-        mIs24HourView = is24HourView;
-        // cache the current hour since spinner range changes
+        // cache the current hour since spinner range changes and BEFORE changing mIs24HourView!!
         int currentHour = getCurrentHour();
+        // Order is important here.
+        mIs24HourView = is24HourView;
+        getHourFormatData();
         updateHourControl();
-        // set value after spinner range is updated
-        setCurrentHour(currentHour);
+        // set value after spinner range is updated - be aware that because mIs24HourView has
+        // changed then getCurrentHour() is not equal to the currentHour we cached before so
+        // explicitly ask for *not* propagating any onTimeChanged()
+        setCurrentHour(currentHour, false /* no onTimeChanged() */);
         updateMinuteControl();
         updateAmPmControl();
     }
@@ -458,6 +520,38 @@
         onTimeChanged();
     }
 
+    /**
+     * The time separator is defined in the Unicode CLDR and cannot be supposed to be ":".
+     *
+     * See http://unicode.org/cldr/trac/browser/trunk/common/main
+     *
+     * We pass the correct "skeleton" depending on 12 or 24 hours view and then extract the
+     * separator as the character which is just after the hour marker in the returned pattern.
+     */
+    private void setDividerText() {
+        final Locale defaultLocale = Locale.getDefault();
+        final String skeleton = (mIs24HourView) ? "Hm" : "hm";
+        final String bestDateTimePattern = DateFormat.getBestDateTimePattern(defaultLocale,
+                skeleton);
+        final String separatorText;
+        int hourIndex = bestDateTimePattern.lastIndexOf('H');
+        if (hourIndex == -1) {
+            hourIndex = bestDateTimePattern.lastIndexOf('h');
+        }
+        if (hourIndex == -1) {
+            // Default case
+            separatorText = ":";
+        } else {
+            int minuteIndex = bestDateTimePattern.indexOf('m', hourIndex + 1);
+            if  (minuteIndex == -1) {
+                separatorText = Character.toString(bestDateTimePattern.charAt(hourIndex + 1));
+            } else {
+                separatorText = bestDateTimePattern.substring(hourIndex + 1, minuteIndex);
+            }
+        }
+        mDivider.setText(separatorText);
+    }
+
     @Override
     public int getBaseline() {
         return mHourSpinner.getBaseline();
@@ -500,14 +594,25 @@
 
     private void updateHourControl() {
         if (is24HourView()) {
-            mHourSpinner.setMinValue(0);
-            mHourSpinner.setMaxValue(23);
-            mHourSpinner.setFormatter(NumberPicker.getTwoDigitFormatter());
+            // 'k' means 1-24 hour
+            if (mHourFormat == 'k') {
+                mHourSpinner.setMinValue(1);
+                mHourSpinner.setMaxValue(24);
+            } else {
+                mHourSpinner.setMinValue(0);
+                mHourSpinner.setMaxValue(23);
+            }
         } else {
-            mHourSpinner.setMinValue(1);
-            mHourSpinner.setMaxValue(12);
-            mHourSpinner.setFormatter(null);
+            // 'K' means 0-11 hour
+            if (mHourFormat == 'K') {
+                mHourSpinner.setMinValue(0);
+                mHourSpinner.setMaxValue(11);
+            } else {
+                mHourSpinner.setMinValue(1);
+                mHourSpinner.setMaxValue(12);
+            }
         }
+        mHourSpinner.setFormatter(mHourWithTwoDigit ? NumberPicker.getTwoDigitFormatter() : null);
     }
 
     private void updateMinuteControl() {
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index 1d85126..4b71e36 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -29,6 +29,7 @@
 import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.View.OnClickListener;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
@@ -74,6 +75,9 @@
      */
     public static final int LENGTH_LONG = 1;
 
+    /** @hide */
+    public static final int LENGTH_INFINITE = 2;
+
     final Context mContext;
     final TN mTN;
     int mDuration;
@@ -91,6 +95,8 @@
         mTN = new TN();
         mTN.mY = context.getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.toast_y_offset);
+        mTN.mGravity = context.getResources().getInteger(
+                com.android.internal.R.integer.config_toastDefaultGravity);
     }
     
     /**
@@ -288,6 +294,61 @@
         tv.setText(s);
     }
 
+    /** @hide */
+    public static Toast makeBar(Context context, int resId, int duration) {
+        return makeBar(context, context.getResources().getText(resId), duration);
+    }
+
+    /** @hide */
+    public static Toast makeBar(Context context, CharSequence text, int duration) {
+        Toast result = new Toast(context);
+
+        LayoutInflater inflate = (LayoutInflater)
+                context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        View v = inflate.inflate(com.android.internal.R.layout.toast_bar, null);
+        ((TextView)v.findViewById(android.R.id.message)).setText(text);
+        v.findViewById(android.R.id.button1).setVisibility(View.GONE);
+
+        result.mNextView = v;
+        result.mDuration = duration;
+        result.mTN.mParams.alpha = 0.9f;
+        result.mTN.mParams.windowAnimations = com.android.internal.R.style.Animation_ToastBar;
+
+        return result;
+    }
+
+    /** @hide */
+    public Toast setAction(int resId, Runnable action) {
+        return setAction(mContext.getResources().getText(resId), action);
+    }
+
+    /** @hide */
+    public Toast setAction(CharSequence actionText, final Runnable action) {
+        if (mNextView != null) {
+            TextView text1 = (TextView)mNextView.findViewById(android.R.id.text1);
+            View button1 =  mNextView.findViewById(android.R.id.button1);
+            if (text1 != null && button1 != null) {
+                text1.setText(actionText);
+                button1.setVisibility(View.VISIBLE);
+                button1.setOnClickListener(new OnClickListener() {
+                    @Override
+                    public void onClick(View v) {
+                        if (action != null) {
+                            action.run();
+                        }
+                    }});
+                return setInteractive(true);
+            }
+        }
+        throw new RuntimeException("This Toast was not created with Toast.makeBar()");
+    }
+
+    /** @hide */
+    public Toast setInteractive(boolean interactive) {
+        mTN.setInteractive(interactive);
+        return this;
+    }
+
     // =======================================================================================
     // All the gunk below is the interaction with the Notification Service, which handles
     // the proper ordering of these system-wide.
@@ -323,12 +384,12 @@
         private final WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();
         final Handler mHandler = new Handler();    
 
-        int mGravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
+        int mGravity;
         int mX, mY;
         float mHorizontalMargin;
         float mVerticalMargin;
 
-       
+
         View mView;
         View mNextView;
 
@@ -340,13 +401,20 @@
             final WindowManager.LayoutParams params = mParams;
             params.height = WindowManager.LayoutParams.WRAP_CONTENT;
             params.width = WindowManager.LayoutParams.WRAP_CONTENT;
-            params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                    | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
-                    | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
             params.format = PixelFormat.TRANSLUCENT;
             params.windowAnimations = com.android.internal.R.style.Animation_Toast;
             params.type = WindowManager.LayoutParams.TYPE_TOAST;
             params.setTitle("Toast");
+            setInteractive(false);
+        }
+
+        private void setInteractive(boolean interactive) {
+            mParams.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
+                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                    | (interactive
+                            ? (WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+                                    | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH)
+                            : WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
         }
 
         /**
diff --git a/core/java/android/widget/VideoView.java b/core/java/android/widget/VideoView.java
index ebf9fe0..009b729 100644
--- a/core/java/android/widget/VideoView.java
+++ b/core/java/android/widget/VideoView.java
@@ -21,15 +21,21 @@
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.res.Resources;
+import android.graphics.Canvas;
 import android.media.AudioManager;
+import android.media.MediaFormat;
 import android.media.MediaPlayer;
-import android.media.Metadata;
 import android.media.MediaPlayer.OnCompletionListener;
 import android.media.MediaPlayer.OnErrorListener;
 import android.media.MediaPlayer.OnInfoListener;
+import android.media.Metadata;
+import android.media.SubtitleController;
+import android.media.SubtitleTrack.RenderingWidget;
+import android.media.WebVttRenderer;
 import android.net.Uri;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.util.Pair;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.SurfaceHolder;
@@ -40,7 +46,9 @@
 import android.widget.MediaController.MediaPlayerControl;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.util.Map;
+import java.util.Vector;
 
 /**
  * Displays a video file.  The VideoView class
@@ -49,7 +57,8 @@
  * it can be used in any layout manager, and provides various display options
  * such as scaling and tinting.
  */
-public class VideoView extends SurfaceView implements MediaPlayerControl {
+public class VideoView extends SurfaceView
+        implements MediaPlayerControl, SubtitleController.Anchor {
     private String TAG = "VideoView";
     // settable by the client
     private Uri         mUri;
@@ -91,6 +100,12 @@
     private boolean     mCanSeekBack;
     private boolean     mCanSeekForward;
 
+    /** Subtitle rendering widget overlaid on top of the video. */
+    private RenderingWidget mSubtitleWidget;
+
+    /** Listener for changes to subtitle data, used to redraw when needed. */
+    private RenderingWidget.OnChangedListener mSubtitlesChangedListener;
+
     public VideoView(Context context) {
         super(context);
         initVideoView();
@@ -194,6 +209,7 @@
         setFocusable(true);
         setFocusableInTouchMode(true);
         requestFocus();
+        mPendingSubtitleTracks = new Vector<Pair<InputStream, MediaFormat>>();
         mCurrentState = STATE_IDLE;
         mTargetState  = STATE_IDLE;
     }
@@ -218,6 +234,43 @@
         invalidate();
     }
 
+    /**
+     * Adds an external subtitle source file (from the provided input stream.)
+     *
+     * Note that a single external subtitle source may contain multiple or no
+     * supported tracks in it. If the source contained at least one track in
+     * it, one will receive an {@link MediaPlayer#MEDIA_INFO_METADATA_UPDATE}
+     * info message. Otherwise, if reading the source takes excessive time,
+     * one will receive a {@link MediaPlayer#MEDIA_INFO_SUBTITLE_TIMED_OUT}
+     * message. If the source contained no supported track (including an empty
+     * source file or null input stream), one will receive a {@link
+     * MediaPlayer#MEDIA_INFO_UNSUPPORTED_SUBTITLE} message. One can find the
+     * total number of available tracks using {@link MediaPlayer#getTrackInfo()}
+     * to see what additional tracks become available after this method call.
+     *
+     * @param is     input stream containing the subtitle data.  It will be
+     *               closed by the media framework.
+     * @param format the format of the subtitle track(s).  Must contain at least
+     *               the mime type ({@link MediaFormat#KEY_MIME}) and the
+     *               language ({@link MediaFormat#KEY_LANGUAGE}) of the file.
+     *               If the file itself contains the language information,
+     *               specify "und" for the language.
+     */
+    public void addSubtitleSource(InputStream is, MediaFormat format) {
+        if (mMediaPlayer == null) {
+            mPendingSubtitleTracks.add(Pair.create(is, format));
+        } else {
+            try {
+                mMediaPlayer.addSubtitleSource(is, format);
+            } catch (IllegalStateException e) {
+                mInfoListener.onInfo(
+                        mMediaPlayer, MediaPlayer.MEDIA_INFO_UNSUPPORTED_SUBTITLE, 0);
+            }
+        }
+    }
+
+    private Vector<Pair<InputStream, MediaFormat>> mPendingSubtitleTracks;
+
     public void stopPlayback() {
         if (mMediaPlayer != null) {
             mMediaPlayer.stop();
@@ -244,6 +297,14 @@
         release(false);
         try {
             mMediaPlayer = new MediaPlayer();
+            // TODO: create SubtitleController in MediaPlayer, but we need
+            // a context for the subtitle renderers
+            final Context context = getContext();
+            final SubtitleController controller = new SubtitleController(
+                    context, mMediaPlayer.getMediaTimeProvider(), mMediaPlayer);
+            controller.registerRenderer(new WebVttRenderer(context));
+            mMediaPlayer.setSubtitleAnchor(controller, this);
+
             if (mAudioSession != 0) {
                 mMediaPlayer.setAudioSessionId(mAudioSession);
             } else {
@@ -253,7 +314,7 @@
             mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);
             mMediaPlayer.setOnCompletionListener(mCompletionListener);
             mMediaPlayer.setOnErrorListener(mErrorListener);
-            mMediaPlayer.setOnInfoListener(mOnInfoListener);
+            mMediaPlayer.setOnInfoListener(mInfoListener);
             mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
             mCurrentBufferPercentage = 0;
             mMediaPlayer.setDataSource(mContext, mUri, mHeaders);
@@ -261,6 +322,16 @@
             mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
             mMediaPlayer.setScreenOnWhilePlaying(true);
             mMediaPlayer.prepareAsync();
+
+            for (Pair<InputStream, MediaFormat> pending: mPendingSubtitleTracks) {
+                try {
+                    mMediaPlayer.addSubtitleSource(pending.first, pending.second);
+                } catch (IllegalStateException e) {
+                    mInfoListener.onInfo(
+                            mMediaPlayer, MediaPlayer.MEDIA_INFO_UNSUPPORTED_SUBTITLE, 0);
+                }
+            }
+
             // we don't set the target state here either, but preserve the
             // target state that was there before.
             mCurrentState = STATE_PREPARING;
@@ -277,6 +348,8 @@
             mTargetState = STATE_ERROR;
             mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
             return;
+        } finally {
+            mPendingSubtitleTracks.clear();
         }
     }
 
@@ -386,6 +459,16 @@
         }
     };
 
+    private MediaPlayer.OnInfoListener mInfoListener =
+        new MediaPlayer.OnInfoListener() {
+        public  boolean onInfo(MediaPlayer mp, int arg1, int arg2) {
+            if (mOnInfoListener != null) {
+                mOnInfoListener.onInfo(mp, arg1, arg2);
+            }
+            return true;
+        }
+    };
+
     private MediaPlayer.OnErrorListener mErrorListener =
         new MediaPlayer.OnErrorListener() {
         public boolean onError(MediaPlayer mp, int framework_err, int impl_err) {
@@ -530,6 +613,7 @@
             mMediaPlayer.reset();
             mMediaPlayer.release();
             mMediaPlayer = null;
+            mPendingSubtitleTracks.clear();
             mCurrentState = STATE_IDLE;
             if (cleartargetstate) {
                 mTargetState  = STATE_IDLE;
@@ -702,4 +786,97 @@
         }
         return mAudioSession;
     }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+
+        if (mSubtitleWidget != null) {
+            mSubtitleWidget.onAttachedToWindow();
+        }
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+
+        if (mSubtitleWidget != null) {
+            mSubtitleWidget.onDetachedFromWindow();
+        }
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+
+        if (mSubtitleWidget != null) {
+            measureAndLayoutSubtitleWidget();
+        }
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        super.draw(canvas);
+
+        if (mSubtitleWidget != null) {
+            final int saveCount = canvas.save();
+            canvas.translate(getPaddingLeft(), getPaddingTop());
+            mSubtitleWidget.draw(canvas);
+            canvas.restoreToCount(saveCount);
+        }
+    }
+
+    /**
+     * Forces a measurement and layout pass for all overlaid views.
+     *
+     * @see #setSubtitleWidget(RenderingWidget)
+     */
+    private void measureAndLayoutSubtitleWidget() {
+        final int width = getWidth() - getPaddingLeft() - getPaddingRight();
+        final int height = getHeight() - getPaddingTop() - getPaddingBottom();
+
+        mSubtitleWidget.setSize(width, height);
+    }
+
+    /** @hide */
+    @Override
+    public void setSubtitleWidget(RenderingWidget subtitleWidget) {
+        if (mSubtitleWidget == subtitleWidget) {
+            return;
+        }
+
+        final boolean attachedToWindow = isAttachedToWindow();
+        if (mSubtitleWidget != null) {
+            if (attachedToWindow) {
+                mSubtitleWidget.onDetachedFromWindow();
+            }
+
+            mSubtitleWidget.setOnChangedListener(null);
+        }
+
+        mSubtitleWidget = subtitleWidget;
+
+        if (subtitleWidget != null) {
+            if (mSubtitlesChangedListener == null) {
+                mSubtitlesChangedListener = new RenderingWidget.OnChangedListener() {
+                    @Override
+                    public void onChanged(RenderingWidget renderingWidget) {
+                        invalidate();
+                    }
+                };
+            }
+
+            setWillNotDraw(false);
+            subtitleWidget.setOnChangedListener(mSubtitlesChangedListener);
+
+            if (attachedToWindow) {
+                subtitleWidget.onAttachedToWindow();
+                requestLayout();
+            }
+        } else {
+            setWillNotDraw(true);
+        }
+
+        invalidate();
+    }
 }
diff --git a/core/java/android/widget/ZoomButtonsController.java b/core/java/android/widget/ZoomButtonsController.java
index a89c9c1..50c803b 100644
--- a/core/java/android/widget/ZoomButtonsController.java
+++ b/core/java/android/widget/ZoomButtonsController.java
@@ -503,7 +503,7 @@
 
             ViewRootImpl viewRoot = mOwnerView.getViewRootImpl();
             if (viewRoot != null) {
-                viewRoot.dispatchKey(event);
+                viewRoot.dispatchInputEvent(event);
             }
 
             // We gave the key to the owner, don't let the container handle this key
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index acbb2b1..066d6c3 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.app;
 
+import android.animation.ValueAnimator;
+import android.view.ViewParent;
 import com.android.internal.view.ActionBarPolicy;
 import com.android.internal.view.menu.MenuBuilder;
 import com.android.internal.view.menu.MenuPopupHelper;
@@ -75,7 +77,6 @@
 
     private ActionBarOverlayLayout mOverlayLayout;
     private ActionBarContainer mContainerView;
-    private ViewGroup mTopVisibilityView;
     private ActionBarView mActionView;
     private ActionBarContextView mContextView;
     private ActionBarContainer mSplitView;
@@ -125,12 +126,12 @@
         public void onAnimationEnd(Animator animation) {
             if (mContentAnimations && mContentView != null) {
                 mContentView.setTranslationY(0);
-                mTopVisibilityView.setTranslationY(0);
+                mContainerView.setTranslationY(0);
             }
             if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) {
                 mSplitView.setVisibility(View.GONE);
             }
-            mTopVisibilityView.setVisibility(View.GONE);
+            mContainerView.setVisibility(View.GONE);
             mContainerView.setTransitioning(false);
             mCurrentShowAnim = null;
             completeDeferredDestroyActionMode();
@@ -144,7 +145,16 @@
         @Override
         public void onAnimationEnd(Animator animation) {
             mCurrentShowAnim = null;
-            mTopVisibilityView.requestLayout();
+            mContainerView.requestLayout();
+        }
+    };
+
+    final ValueAnimator.AnimatorUpdateListener mUpdateListener =
+            new ValueAnimator.AnimatorUpdateListener() {
+        @Override
+        public void onAnimationUpdate(ValueAnimator animation) {
+            final ViewParent parent = mContainerView.getParent();
+            ((View) parent).invalidate();
         }
     };
 
@@ -153,7 +163,7 @@
         Window window = activity.getWindow();
         View decor = window.getDecorView();
         boolean overlayMode = mActivity.getWindow().hasFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
-        init(decor, overlayMode);
+        init(decor);
         if (!overlayMode) {
             mContentView = decor.findViewById(android.R.id.content);
         }
@@ -161,26 +171,21 @@
 
     public ActionBarImpl(Dialog dialog) {
         mDialog = dialog;
-        init(dialog.getWindow().getDecorView(), false);
+        init(dialog.getWindow().getDecorView());
     }
 
-    private void init(View decor, boolean overlayMode) {
+    private void init(View decor) {
         mContext = decor.getContext();
         mOverlayLayout = (ActionBarOverlayLayout) decor.findViewById(
                 com.android.internal.R.id.action_bar_overlay_layout);
         if (mOverlayLayout != null) {
-            mOverlayLayout.setActionBar(this, overlayMode);
+            mOverlayLayout.setActionBar(this);
         }
         mActionView = (ActionBarView) decor.findViewById(com.android.internal.R.id.action_bar);
         mContextView = (ActionBarContextView) decor.findViewById(
                 com.android.internal.R.id.action_context_bar);
         mContainerView = (ActionBarContainer) decor.findViewById(
                 com.android.internal.R.id.action_bar_container);
-        mTopVisibilityView = (ViewGroup)decor.findViewById(
-                com.android.internal.R.id.top_action_bar);
-        if (mTopVisibilityView == null) {
-            mTopVisibilityView = mContainerView;
-        }
         mSplitView = (ActionBarContainer) decor.findViewById(
                 com.android.internal.R.id.split_action_bar);
 
@@ -675,29 +680,30 @@
         if (mCurrentShowAnim != null) {
             mCurrentShowAnim.end();
         }
-        mTopVisibilityView.setVisibility(View.VISIBLE);
+        mContainerView.setVisibility(View.VISIBLE);
 
         if (mCurWindowVisibility == View.VISIBLE && (mShowHideAnimationEnabled
                 || fromSystem)) {
-            mTopVisibilityView.setTranslationY(0); // because we're about to ask its window loc
-            float startingY = -mTopVisibilityView.getHeight();
+            mContainerView.setTranslationY(0); // because we're about to ask its window loc
+            float startingY = -mContainerView.getHeight();
             if (fromSystem) {
                 int topLeft[] = {0, 0};
-                mTopVisibilityView.getLocationInWindow(topLeft);
+                mContainerView.getLocationInWindow(topLeft);
                 startingY -= topLeft[1];
             }
-            mTopVisibilityView.setTranslationY(startingY);
+            mContainerView.setTranslationY(startingY);
             AnimatorSet anim = new AnimatorSet();
-            AnimatorSet.Builder b = anim.play(ObjectAnimator.ofFloat(mTopVisibilityView,
-                    "translationY", 0));
+            ObjectAnimator a = ObjectAnimator.ofFloat(mContainerView, View.TRANSLATION_Y, 0);
+            a.addUpdateListener(mUpdateListener);
+            AnimatorSet.Builder b = anim.play(a);
             if (mContentAnimations && mContentView != null) {
-                b.with(ObjectAnimator.ofFloat(mContentView, "translationY",
+                b.with(ObjectAnimator.ofFloat(mContentView, View.TRANSLATION_Y,
                         startingY, 0));
             }
             if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) {
                 mSplitView.setTranslationY(mSplitView.getHeight());
                 mSplitView.setVisibility(View.VISIBLE);
-                b.with(ObjectAnimator.ofFloat(mSplitView, "translationY", 0));
+                b.with(ObjectAnimator.ofFloat(mSplitView, View.TRANSLATION_Y, 0));
             }
             anim.setInterpolator(AnimationUtils.loadInterpolator(mContext,
                     com.android.internal.R.interpolator.decelerate_cubic));
@@ -713,8 +719,8 @@
             mCurrentShowAnim = anim;
             anim.start();
         } else {
-            mTopVisibilityView.setAlpha(1);
-            mTopVisibilityView.setTranslationY(0);
+            mContainerView.setAlpha(1);
+            mContainerView.setTranslationY(0);
             if (mContentAnimations && mContentView != null) {
                 mContentView.setTranslationY(0);
             }
@@ -737,24 +743,25 @@
 
         if (mCurWindowVisibility == View.VISIBLE && (mShowHideAnimationEnabled
                 || fromSystem)) {
-            mTopVisibilityView.setAlpha(1);
+            mContainerView.setAlpha(1);
             mContainerView.setTransitioning(true);
             AnimatorSet anim = new AnimatorSet();
-            float endingY = -mTopVisibilityView.getHeight();
+            float endingY = -mContainerView.getHeight();
             if (fromSystem) {
                 int topLeft[] = {0, 0};
-                mTopVisibilityView.getLocationInWindow(topLeft);
+                mContainerView.getLocationInWindow(topLeft);
                 endingY -= topLeft[1];
             }
-            AnimatorSet.Builder b = anim.play(ObjectAnimator.ofFloat(mTopVisibilityView,
-                    "translationY", endingY));
+            ObjectAnimator a = ObjectAnimator.ofFloat(mContainerView, View.TRANSLATION_Y, endingY);
+            a.addUpdateListener(mUpdateListener);
+            AnimatorSet.Builder b = anim.play(a);
             if (mContentAnimations && mContentView != null) {
-                b.with(ObjectAnimator.ofFloat(mContentView, "translationY",
+                b.with(ObjectAnimator.ofFloat(mContentView, View.TRANSLATION_Y,
                         0, endingY));
             }
             if (mSplitView != null && mSplitView.getVisibility() == View.VISIBLE) {
                 mSplitView.setAlpha(1);
-                b.with(ObjectAnimator.ofFloat(mSplitView, "translationY",
+                b.with(ObjectAnimator.ofFloat(mSplitView, View.TRANSLATION_Y,
                         mSplitView.getHeight()));
             }
             anim.setInterpolator(AnimationUtils.loadInterpolator(mContext,
@@ -1210,6 +1217,10 @@
         mActionView.setIcon(icon);
     }
 
+    public boolean hasIcon() {
+        return mActionView.hasIcon();
+    }
+
     @Override
     public void setLogo(int resId) {
         mActionView.setLogo(resId);
@@ -1220,6 +1231,10 @@
         mActionView.setLogo(logo);
     }
 
+    public boolean hasLogo() {
+        return mActionView.hasLogo();
+    }
+
     public void setDefaultDisplayHomeAsUpEnabled(boolean enable) {
         if (!mDisplayHomeAsUpSet) {
             setDisplayHomeAsUpEnabled(enable);
diff --git a/core/java/com/android/internal/app/AlertActivity.java b/core/java/com/android/internal/app/AlertActivity.java
index 7251256..7456def 100644
--- a/core/java/com/android/internal/app/AlertActivity.java
+++ b/core/java/com/android/internal/app/AlertActivity.java
@@ -36,18 +36,18 @@
      * @see #mAlertParams
      */
     protected AlertController mAlert;
-    
+
     /**
      * The parameters for the alert.
      */
     protected AlertController.AlertParams mAlertParams;
-    
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        
+
         mAlert = new AlertController(this, this, getWindow());
-        mAlertParams = new AlertController.AlertParams(this);        
+        mAlertParams = new AlertController.AlertParams(this);
     }
 
     public void cancel() {
@@ -65,7 +65,7 @@
     /**
      * Sets up the alert, including applying the parameters to the alert model,
      * and installing the alert's content.
-     * 
+     *
      * @see #mAlert
      * @see #mAlertParams
      */
@@ -73,7 +73,7 @@
         mAlertParams.apply(mAlert);
         mAlert.installContent();
     }
-    
+
     @Override
     public boolean onKeyDown(int keyCode, KeyEvent event) {
         if (mAlert.onKeyDown(keyCode, event)) return true;
@@ -85,6 +85,4 @@
         if (mAlert.onKeyUp(keyCode, event)) return true;
         return super.onKeyUp(keyCode, event);
     }
-    
-    
 }
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index cfd9cc7..16c41f3 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -24,12 +24,14 @@
     // be kept in sync with frameworks/native/include/binder/IAppOpsService.h
     int checkOperation(int code, int uid, String packageName);
     int noteOperation(int code, int uid, String packageName);
-    int startOperation(int code, int uid, String packageName);
-    void finishOperation(int code, int uid, String packageName);
+    int startOperation(IBinder token, int code, int uid, String packageName);
+    void finishOperation(IBinder token, int code, int uid, String packageName);
     void startWatchingMode(int op, String packageName, IAppOpsCallback callback);
     void stopWatchingMode(IAppOpsCallback callback);
+    IBinder getToken(IBinder clientToken);
 
     // Remaining methods are only used in Java.
+    int checkPackage(int uid, String packageName);
     List<AppOpsManager.PackageOps> getPackagesForOps(in int[] ops);
     List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, in int[] ops);
     void setMode(int code, int uid, String packageName, int mode);
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 823e19f..525517c 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -71,6 +71,7 @@
     void noteWifiMulticastEnabledFromSource(in WorkSource ws);
     void noteWifiMulticastDisabledFromSource(in WorkSource ws);
     void noteNetworkInterfaceType(String iface, int type);
+    void noteNetworkStatsEnabled();
     void setBatteryState(int status, int health, int plugType, int level, int temp, int volt);
     long getAwakeTimeBattery();
     long getAwakeTimePlugged();
diff --git a/core/java/com/android/internal/app/IProcessStats.aidl b/core/java/com/android/internal/app/IProcessStats.aidl
new file mode 100644
index 0000000..047424d
--- /dev/null
+++ b/core/java/com/android/internal/app/IProcessStats.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app;
+
+import android.content.ComponentName;
+import android.os.ParcelFileDescriptor;
+import com.android.internal.app.ProcessStats;
+
+interface IProcessStats {
+    byte[] getCurrentStats(out List<ParcelFileDescriptor> historic);
+    int getCurrentMemoryState();
+}
diff --git a/core/java/com/android/internal/app/PlatLogoActivity.java b/core/java/com/android/internal/app/PlatLogoActivity.java
index 3a2b647..f2eee45 100644
--- a/core/java/com/android/internal/app/PlatLogoActivity.java
+++ b/core/java/com/android/internal/app/PlatLogoActivity.java
@@ -18,91 +18,94 @@
 
 import android.app.Activity;
 import android.content.ActivityNotFoundException;
+import android.content.Context;
 import android.content.Intent;
 import android.graphics.Typeface;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
+import android.text.method.AllCapsTransformationMethod;
+import android.text.method.TransformationMethod;
 import android.util.DisplayMetrics;
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.animation.DecelerateInterpolator;
+import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 import android.widget.Toast;
 
 public class PlatLogoActivity extends Activity {
-    Toast mToast;
-    ImageView mContent;
+    FrameLayout mContent;
     int mCount;
     final Handler mHandler = new Handler();
 
-    private View makeView() {
-        DisplayMetrics metrics = new DisplayMetrics();
-        getWindowManager().getDefaultDisplay().getMetrics(metrics);
-
-        LinearLayout view = new LinearLayout(this);
-        view.setOrientation(LinearLayout.VERTICAL);
-        view.setLayoutParams(
-                new ViewGroup.LayoutParams(
-                    ViewGroup.LayoutParams.WRAP_CONTENT,
-                    ViewGroup.LayoutParams.WRAP_CONTENT
-                ));
-        final int p = (int)(8 * metrics.density);
-        view.setPadding(p, p, p, p);
-
-        Typeface light = Typeface.create("sans-serif-light", Typeface.NORMAL);
-        Typeface normal = Typeface.create("sans-serif", Typeface.BOLD);
-
-        final float size = 14 * metrics.density;
-        final LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
-                LinearLayout.LayoutParams.WRAP_CONTENT,
-                LinearLayout.LayoutParams.WRAP_CONTENT);
-        lp.gravity = Gravity.CENTER_HORIZONTAL;
-        lp.bottomMargin = (int) (-4*metrics.density);
-
-        TextView tv = new TextView(this);
-        if (light != null) tv.setTypeface(light);
-        tv.setTextSize(1.25f*size);
-        tv.setTextColor(0xFFFFFFFF);
-        tv.setShadowLayer(4*metrics.density, 0, 2*metrics.density, 0x66000000);
-        tv.setText("Android " + Build.VERSION.RELEASE);
-        view.addView(tv, lp);
-   
-        tv = new TextView(this);
-        if (normal != null) tv.setTypeface(normal);
-        tv.setTextSize(size);
-        tv.setTextColor(0xFFFFFFFF);
-        tv.setShadowLayer(4*metrics.density, 0, 2*metrics.density, 0x66000000);
-        tv.setText("JELLY BEAN");
-        view.addView(tv, lp);
-
-        return view;
-    }
-
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        mToast = Toast.makeText(this, "", Toast.LENGTH_LONG);
-        mToast.setView(makeView());
-
         DisplayMetrics metrics = new DisplayMetrics();
         getWindowManager().getDefaultDisplay().getMetrics(metrics);
 
-        mContent = new ImageView(this);
-        mContent.setImageResource(com.android.internal.R.drawable.platlogo_alt);
-        mContent.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
+        Typeface bold = Typeface.create("sans-serif", Typeface.BOLD);
+        Typeface light = Typeface.create("sans-serif-light", Typeface.NORMAL);
+
+        mContent = new FrameLayout(this);
         
-        final int p = (int)(32 * metrics.density);
-        mContent.setPadding(p, p, p, p);
+        final FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
+                FrameLayout.LayoutParams.WRAP_CONTENT,
+                FrameLayout.LayoutParams.WRAP_CONTENT);
+        lp.gravity = Gravity.CENTER;
+
+        final ImageView logo = new ImageView(this);
+        logo.setImageResource(com.android.internal.R.drawable.platlogo);
+        logo.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
+        logo.setVisibility(View.INVISIBLE);
+
+        final TextView letter = new TextView(this);
+
+        letter.setTypeface(bold);
+        letter.setTextSize(300);
+        letter.setTextColor(0xFFFFFFFF);
+        letter.setGravity(Gravity.CENTER);
+        letter.setText(String.valueOf(Build.VERSION.RELEASE).substring(0, 1));
+
+        final int p = (int)(4 * metrics.density);
+
+        final TextView tv = new TextView(this);
+        if (light != null) tv.setTypeface(light);
+        tv.setTextSize(30);
+        tv.setPadding(p, p, p, p);
+        tv.setTextColor(0xFFFFFFFF);
+        tv.setGravity(Gravity.CENTER);
+        tv.setTransformationMethod(new AllCapsTransformationMethod(this));
+        tv.setText("Android " + Build.VERSION.RELEASE);
+        tv.setVisibility(View.INVISIBLE);
+
+        mContent.addView(letter, lp);
+        mContent.addView(logo, lp);
+
+        final FrameLayout.LayoutParams lp2 = new FrameLayout.LayoutParams(lp);
+        lp2.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
+        lp2.bottomMargin = 10*p;
+
+        mContent.addView(tv, lp2);
 
         mContent.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                mToast.show();
-                mContent.setImageResource(com.android.internal.R.drawable.platlogo);
+                if (logo.getVisibility() != View.VISIBLE) {
+                    letter.animate().alpha(0.25f).scaleY(0.75f).scaleX(0.75f).setDuration(2000)
+                            .start();
+                    logo.setAlpha(0f);
+                    logo.setVisibility(View.VISIBLE);
+                    logo.animate().alpha(1f).setDuration(1000).setStartDelay(500).start();
+                    tv.setAlpha(0f);
+                    tv.setVisibility(View.VISIBLE);
+                    tv.animate().alpha(1f).setDuration(1000).setStartDelay(1000).start();
+                }
             }
         });
 
@@ -115,9 +118,8 @@
                             | Intent.FLAG_ACTIVITY_CLEAR_TASK
                             | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
                         .addCategory("com.android.internal.category.PLATLOGO"));
-                        //.setClassName("com.android.systemui","com.android.systemui.BeanBag"));
                 } catch (ActivityNotFoundException ex) {
-                    android.util.Log.e("PlatLogoActivity", "Couldn't find a bag of beans.");
+                    android.util.Log.e("PlatLogoActivity", "Couldn't find a piece of pie.");
                 }
                 finish();
                 return true;
diff --git a/core/java/com/android/internal/app/ProcessMap.java b/core/java/com/android/internal/app/ProcessMap.java
new file mode 100644
index 0000000..6ff0304
--- /dev/null
+++ b/core/java/com/android/internal/app/ProcessMap.java
@@ -0,0 +1,55 @@
+/*
+ * 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 com.android.internal.app;
+
+import android.util.ArrayMap;
+import android.util.SparseArray;
+
+public class ProcessMap<E> {
+    final ArrayMap<String, SparseArray<E>> mMap
+            = new ArrayMap<String, SparseArray<E>>();
+    
+    public E get(String name, int uid) {
+        SparseArray<E> uids = mMap.get(name);
+        if (uids == null) return null;
+        return uids.get(uid);
+    }
+    
+    public E put(String name, int uid, E value) {
+        SparseArray<E> uids = mMap.get(name);
+        if (uids == null) {
+            uids = new SparseArray<E>(2);
+            mMap.put(name, uids);
+        }
+        uids.put(uid, value);
+        return value;
+    }
+    
+    public void remove(String name, int uid) {
+        SparseArray<E> uids = mMap.get(name);
+        if (uids != null) {
+            uids.remove(uid);
+            if (uids.size() == 0) {
+                mMap.remove(name);
+            }
+        }
+    }
+    
+    public ArrayMap<String, SparseArray<E>> getMap() {
+        return mMap;
+    }
+}
diff --git a/core/java/com/android/internal/app/ProcessStats.aidl b/core/java/com/android/internal/app/ProcessStats.aidl
new file mode 100644
index 0000000..48b1f85
--- /dev/null
+++ b/core/java/com/android/internal/app/ProcessStats.aidl
@@ -0,0 +1,19 @@
+/*
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package com.android.internal.app;
+
+parcelable ProcessStats;
diff --git a/core/java/com/android/internal/app/ProcessStats.java b/core/java/com/android/internal/app/ProcessStats.java
new file mode 100644
index 0000000..07854e2
--- /dev/null
+++ b/core/java/com/android/internal/app/ProcessStats.java
@@ -0,0 +1,2855 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.text.format.DateFormat;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.util.TimeUtils;
+import android.webkit.WebViewFactory;
+import com.android.internal.util.ArrayUtils;
+import dalvik.system.VMRuntime;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Objects;
+
+public final class ProcessStats implements Parcelable {
+    static final String TAG = "ProcessStats";
+    static final boolean DEBUG = false;
+
+    public static final String SERVICE_NAME = "procstats";
+
+    public static final int STATE_NOTHING = -1;
+    public static final int STATE_PERSISTENT = 0;
+    public static final int STATE_TOP = 1;
+    public static final int STATE_IMPORTANT_FOREGROUND = 2;
+    public static final int STATE_IMPORTANT_BACKGROUND = 3;
+    public static final int STATE_BACKUP = 4;
+    public static final int STATE_HEAVY_WEIGHT = 5;
+    public static final int STATE_SERVICE = 6;
+    public static final int STATE_SERVICE_RESTARTING = 7;
+    public static final int STATE_RECEIVER = 8;
+    public static final int STATE_HOME = 9;
+    public static final int STATE_LAST_ACTIVITY = 10;
+    public static final int STATE_CACHED_ACTIVITY = 11;
+    public static final int STATE_CACHED_ACTIVITY_CLIENT = 12;
+    public static final int STATE_CACHED_EMPTY = 13;
+    public static final int STATE_COUNT = STATE_CACHED_EMPTY+1;
+
+    public static final int PSS_SAMPLE_COUNT = 0;
+    public static final int PSS_MINIMUM = 1;
+    public static final int PSS_AVERAGE = 2;
+    public static final int PSS_MAXIMUM = 3;
+    public static final int PSS_USS_MINIMUM = 4;
+    public static final int PSS_USS_AVERAGE = 5;
+    public static final int PSS_USS_MAXIMUM = 6;
+    public static final int PSS_COUNT = PSS_USS_MAXIMUM+1;
+
+    public static final int ADJ_NOTHING = -1;
+    public static final int ADJ_MEM_FACTOR_NORMAL = 0;
+    public static final int ADJ_MEM_FACTOR_MODERATE = 1;
+    public static final int ADJ_MEM_FACTOR_LOW = 2;
+    public static final int ADJ_MEM_FACTOR_CRITICAL = 3;
+    public static final int ADJ_MEM_FACTOR_COUNT = ADJ_MEM_FACTOR_CRITICAL+1;
+    public static final int ADJ_SCREEN_MOD = ADJ_MEM_FACTOR_COUNT;
+    public static final int ADJ_SCREEN_OFF = 0;
+    public static final int ADJ_SCREEN_ON = ADJ_SCREEN_MOD;
+    public static final int ADJ_COUNT = ADJ_SCREEN_ON*2;
+
+    public static final int FLAG_COMPLETE = 1<<0;
+    public static final int FLAG_SHUTDOWN = 1<<1;
+    public static final int FLAG_SYSPROPS = 1<<2;
+
+    public static final int[] ALL_MEM_ADJ = new int[] { ADJ_MEM_FACTOR_NORMAL,
+            ADJ_MEM_FACTOR_MODERATE, ADJ_MEM_FACTOR_LOW, ADJ_MEM_FACTOR_CRITICAL };
+
+    public static final int[] ALL_SCREEN_ADJ = new int[] { ADJ_SCREEN_OFF, ADJ_SCREEN_ON };
+
+    public static final int[] NON_CACHED_PROC_STATES = new int[] {
+            STATE_PERSISTENT, STATE_TOP, STATE_IMPORTANT_FOREGROUND,
+            STATE_IMPORTANT_BACKGROUND, STATE_BACKUP, STATE_HEAVY_WEIGHT,
+            STATE_SERVICE, STATE_SERVICE_RESTARTING, STATE_RECEIVER
+    };
+
+    public static final int[] BACKGROUND_PROC_STATES = new int[] {
+            STATE_IMPORTANT_FOREGROUND, STATE_IMPORTANT_BACKGROUND, STATE_BACKUP,
+            STATE_HEAVY_WEIGHT, STATE_SERVICE, STATE_SERVICE_RESTARTING, STATE_RECEIVER
+    };
+
+    // Map from process states to the states we track.
+    static final int[] PROCESS_STATE_TO_STATE = new int[] {
+            STATE_PERSISTENT,               // ActivityManager.PROCESS_STATE_PERSISTENT
+            STATE_PERSISTENT,               // ActivityManager.PROCESS_STATE_PERSISTENT_UI
+            STATE_TOP,                      // ActivityManager.PROCESS_STATE_TOP
+            STATE_IMPORTANT_FOREGROUND,     // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
+            STATE_IMPORTANT_BACKGROUND,     // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
+            STATE_BACKUP,                   // ActivityManager.PROCESS_STATE_BACKUP
+            STATE_HEAVY_WEIGHT,             // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
+            STATE_SERVICE,                  // ActivityManager.PROCESS_STATE_SERVICE
+            STATE_RECEIVER,                 // ActivityManager.PROCESS_STATE_RECEIVER
+            STATE_HOME,                     // ActivityManager.PROCESS_STATE_HOME
+            STATE_LAST_ACTIVITY,            // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
+            STATE_CACHED_ACTIVITY,          // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
+            STATE_CACHED_ACTIVITY_CLIENT,   // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
+            STATE_CACHED_EMPTY,             // ActivityManager.PROCESS_STATE_CACHED_EMPTY
+    };
+
+    public static final int[] ALL_PROC_STATES = new int[] { STATE_PERSISTENT,
+            STATE_TOP, STATE_IMPORTANT_FOREGROUND, STATE_IMPORTANT_BACKGROUND, STATE_BACKUP,
+            STATE_HEAVY_WEIGHT, STATE_SERVICE, STATE_SERVICE_RESTARTING, STATE_RECEIVER,
+            STATE_HOME, STATE_LAST_ACTIVITY, STATE_CACHED_ACTIVITY,
+            STATE_CACHED_ACTIVITY_CLIENT, STATE_CACHED_EMPTY
+    };
+
+    static final String[] STATE_NAMES = new String[] {
+            "Persistent", "Top       ", "Imp Fg    ", "Imp Bg    ",
+            "Backup    ", "Heavy Wght", "Service   ", "Service Rs",
+            "Receiver  ", "Home      ",
+            "Last Act  ", "Cch Act   ", "Cch CliAct", "Cch Empty "
+    };
+
+    public static final String[] ADJ_SCREEN_NAMES_CSV = new String[] {
+            "off", "on"
+    };
+
+    public static final String[] ADJ_MEM_NAMES_CSV = new String[] {
+            "norm", "mod",  "low", "crit"
+    };
+
+    public static final String[] STATE_NAMES_CSV = new String[] {
+            "pers", "top", "impfg", "impbg", "backup", "heavy",
+            "service", "service-rs", "receiver", "home", "lastact",
+            "cch-activity", "cch-aclient", "cch-empty"
+    };
+
+    static final String[] ADJ_SCREEN_TAGS = new String[] {
+            "0", "1"
+    };
+
+    static final String[] ADJ_MEM_TAGS = new String[] {
+            "n", "m",  "l", "c"
+    };
+
+    static final String[] STATE_TAGS = new String[] {
+            "p", "t", "f", "b", "u", "w",
+            "s", "x", "r", "h", "l", "a", "c", "e"
+    };
+
+    static final String CSV_SEP = "\t";
+
+    // Current version of the parcel format.
+    private static final int PARCEL_VERSION = 11;
+    // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
+    private static final int MAGIC = 0x50535453;
+
+    // Where the "type"/"state" part of the data appears in an offset integer.
+    static int OFFSET_TYPE_SHIFT = 0;
+    static int OFFSET_TYPE_MASK = 0xff;
+    // Where the "which array" part of the data appears in an offset integer.
+    static int OFFSET_ARRAY_SHIFT = 8;
+    static int OFFSET_ARRAY_MASK = 0xff;
+    // Where the "index into array" part of the data appears in an offset integer.
+    static int OFFSET_INDEX_SHIFT = 16;
+    static int OFFSET_INDEX_MASK = 0xffff;
+
+    public String mReadError;
+    public String mTimePeriodStartClockStr;
+    public int mFlags;
+
+    public final ProcessMap<PackageState> mPackages = new ProcessMap<PackageState>();
+    public final ProcessMap<ProcessState> mProcesses = new ProcessMap<ProcessState>();
+
+    public final long[] mMemFactorDurations = new long[ADJ_COUNT];
+    public int mMemFactor = STATE_NOTHING;
+    public long mStartTime;
+
+    public long mTimePeriodStartClock;
+    public long mTimePeriodStartRealtime;
+    public long mTimePeriodEndRealtime;
+    String mRuntime;
+    String mWebView;
+    boolean mRunning;
+
+    static final int LONGS_SIZE = 4096;
+    final ArrayList<long[]> mLongs = new ArrayList<long[]>();
+    int mNextLong;
+
+    int[] mAddLongTable;
+    int mAddLongTableSize;
+
+    // For writing parcels.
+    ArrayMap<String, Integer> mCommonStringToIndex;
+
+    // For reading parcels.
+    ArrayList<String> mIndexToCommonString;
+
+    public ProcessStats(boolean running) {
+        mRunning = running;
+        reset();
+    }
+
+    public ProcessStats(Parcel in) {
+        reset();
+        readFromParcel(in);
+    }
+
+    public void add(ProcessStats other) {
+        ArrayMap<String, SparseArray<PackageState>> pkgMap = other.mPackages.getMap();
+        for (int ip=0; ip<pkgMap.size(); ip++) {
+            String pkgName = pkgMap.keyAt(ip);
+            SparseArray<PackageState> uids = pkgMap.valueAt(ip);
+            for (int iu=0; iu<uids.size(); iu++) {
+                int uid = uids.keyAt(iu);
+                PackageState otherState = uids.valueAt(iu);
+                final int NPROCS = otherState.mProcesses.size();
+                final int NSRVS = otherState.mServices.size();
+                for (int iproc=0; iproc<NPROCS; iproc++) {
+                    ProcessState otherProc = otherState.mProcesses.valueAt(iproc);
+                    if (otherProc.mCommonProcess != otherProc) {
+                        if (DEBUG) Slog.d(TAG, "Adding pkg " + pkgName + " uid " + uid
+                                + " proc " + otherProc.mName);
+                        ProcessState thisProc = getProcessStateLocked(pkgName, uid,
+                                otherProc.mName);
+                        if (thisProc.mCommonProcess == thisProc) {
+                            if (DEBUG) Slog.d(TAG, "Existing process is single-package, splitting");
+                            thisProc.mMultiPackage = true;
+                            long now = SystemClock.uptimeMillis();
+                            final PackageState pkgState = getPackageStateLocked(pkgName, uid);
+                            thisProc = thisProc.clone(thisProc.mPackage, now);
+                            pkgState.mProcesses.put(thisProc.mName, thisProc);
+                        }
+                        thisProc.add(otherProc);
+                    }
+                }
+                for (int isvc=0; isvc<NSRVS; isvc++) {
+                    ServiceState otherSvc = otherState.mServices.valueAt(isvc);
+                    if (DEBUG) Slog.d(TAG, "Adding pkg " + pkgName + " uid " + uid
+                            + " service " + otherSvc.mName);
+                    ServiceState thisSvc = getServiceStateLocked(pkgName, uid,
+                            otherSvc.mProcessName, otherSvc.mName);
+                    thisSvc.add(otherSvc);
+                }
+            }
+        }
+
+        ArrayMap<String, SparseArray<ProcessState>> procMap = other.mProcesses.getMap();
+        for (int ip=0; ip<procMap.size(); ip++) {
+            SparseArray<ProcessState> uids = procMap.valueAt(ip);
+            for (int iu=0; iu<uids.size(); iu++) {
+                int uid = uids.keyAt(iu);
+                ProcessState otherProc = uids.valueAt(iu);
+                ProcessState thisProc = mProcesses.get(otherProc.mName, uid);
+                if (DEBUG) Slog.d(TAG, "Adding uid " + uid + " proc " + otherProc.mName);
+                if (thisProc == null) {
+                    if (DEBUG) Slog.d(TAG, "Creating new process!");
+                    thisProc = new ProcessState(this, otherProc.mPackage, uid, otherProc.mName);
+                    mProcesses.put(otherProc.mName, uid, thisProc);
+                    PackageState thisState = getPackageStateLocked(otherProc.mPackage, uid);
+                    if (!thisState.mProcesses.containsKey(otherProc.mName)) {
+                        thisState.mProcesses.put(otherProc.mName, thisProc);
+                    }
+                }
+                thisProc.add(otherProc);
+            }
+        }
+
+        for (int i=0; i<ADJ_COUNT; i++) {
+            if (DEBUG) Slog.d(TAG, "Total duration #" + i + " inc by "
+                    + other.mMemFactorDurations[i] + " from "
+                    + mMemFactorDurations[i]);
+            mMemFactorDurations[i] += other.mMemFactorDurations[i];
+        }
+
+        if (other.mTimePeriodStartClock < mTimePeriodStartClock) {
+            mTimePeriodStartClock = other.mTimePeriodStartClock;
+            mTimePeriodStartClockStr = other.mTimePeriodStartClockStr;
+        }
+        mTimePeriodEndRealtime += other.mTimePeriodEndRealtime - other.mTimePeriodStartRealtime;
+    }
+
+    public static final Parcelable.Creator<ProcessStats> CREATOR
+            = new Parcelable.Creator<ProcessStats>() {
+        public ProcessStats createFromParcel(Parcel in) {
+            return new ProcessStats(in);
+        }
+
+        public ProcessStats[] newArray(int size) {
+            return new ProcessStats[size];
+        }
+    };
+
+    private static void printScreenLabel(PrintWriter pw, int offset) {
+        switch (offset) {
+            case ADJ_NOTHING:
+                pw.print("             ");
+                break;
+            case ADJ_SCREEN_OFF:
+                pw.print("Screen Off / ");
+                break;
+            case ADJ_SCREEN_ON:
+                pw.print("Screen On  / ");
+                break;
+            default:
+                pw.print("?????????? / ");
+                break;
+        }
+    }
+
+    public static void printScreenLabelCsv(PrintWriter pw, int offset) {
+        switch (offset) {
+            case ADJ_NOTHING:
+                break;
+            case ADJ_SCREEN_OFF:
+                pw.print(ADJ_SCREEN_NAMES_CSV[0]);
+                break;
+            case ADJ_SCREEN_ON:
+                pw.print(ADJ_SCREEN_NAMES_CSV[1]);
+                break;
+            default:
+                pw.print("???");
+                break;
+        }
+    }
+
+    private static void printMemLabel(PrintWriter pw, int offset) {
+        switch (offset) {
+            case ADJ_NOTHING:
+                pw.print("       ");
+                break;
+            case ADJ_MEM_FACTOR_NORMAL:
+                pw.print("Norm / ");
+                break;
+            case ADJ_MEM_FACTOR_MODERATE:
+                pw.print("Mod  / ");
+                break;
+            case ADJ_MEM_FACTOR_LOW:
+                pw.print("Low  / ");
+                break;
+            case ADJ_MEM_FACTOR_CRITICAL:
+                pw.print("Crit / ");
+                break;
+            default:
+                pw.print("???? / ");
+                break;
+        }
+    }
+
+    public static void printMemLabelCsv(PrintWriter pw, int offset) {
+        if (offset >= ADJ_MEM_FACTOR_NORMAL) {
+            if (offset <= ADJ_MEM_FACTOR_CRITICAL) {
+                pw.print(ADJ_MEM_NAMES_CSV[offset]);
+            } else {
+                pw.print("???");
+            }
+        }
+    }
+
+    public static long dumpSingleTime(PrintWriter pw, String prefix, long[] durations,
+            int curState, long curStartTime, long now) {
+        long totalTime = 0;
+        int printedScreen = -1;
+        for (int iscreen=0; iscreen<ADJ_COUNT; iscreen+=ADJ_SCREEN_MOD) {
+            int printedMem = -1;
+            for (int imem=0; imem<ADJ_MEM_FACTOR_COUNT; imem++) {
+                int state = imem+iscreen;
+                long time = durations[state];
+                String running = "";
+                if (curState == state) {
+                    time += now - curStartTime;
+                    if (pw != null) {
+                        running = " (running)";
+                    }
+                }
+                if (time != 0) {
+                    if (pw != null) {
+                        pw.print(prefix);
+                        printScreenLabel(pw, printedScreen != iscreen
+                                ? iscreen : STATE_NOTHING);
+                        printedScreen = iscreen;
+                        printMemLabel(pw, printedMem != imem ? imem : STATE_NOTHING);
+                        printedMem = imem;
+                        TimeUtils.formatDuration(time, pw); pw.println(running);
+                    }
+                    totalTime += time;
+                }
+            }
+        }
+        if (totalTime != 0 && pw != null) {
+            pw.print(prefix);
+            printScreenLabel(pw, STATE_NOTHING);
+            pw.print("TOTAL: ");
+            TimeUtils.formatDuration(totalTime, pw);
+            pw.println();
+        }
+        return totalTime;
+    }
+
+    static void dumpAdjTimesCheckin(PrintWriter pw, String sep, long[] durations,
+            int curState, long curStartTime, long now) {
+        for (int iscreen=0; iscreen<ADJ_COUNT; iscreen+=ADJ_SCREEN_MOD) {
+            for (int imem=0; imem<ADJ_MEM_FACTOR_COUNT; imem++) {
+                int state = imem+iscreen;
+                long time = durations[state];
+                if (curState == state) {
+                    time += now - curStartTime;
+                }
+                if (time != 0) {
+                    printAdjTagAndValue(pw, state, time);
+                }
+            }
+        }
+    }
+
+    static void dumpServiceTimeCheckin(PrintWriter pw, String label, String packageName,
+            int uid, String serviceName, ServiceState svc, int serviceType, int opCount,
+            int curState, long curStartTime, long now) {
+        if (opCount <= 0) {
+            return;
+        }
+        pw.print(label);
+        pw.print(",");
+        pw.print(packageName);
+        pw.print(",");
+        pw.print(uid);
+        pw.print(",");
+        pw.print(serviceName);
+        pw.print(",");
+        pw.print(opCount);
+        boolean didCurState = false;
+        for (int i=0; i<svc.mDurationsTableSize; i++) {
+            int off = svc.mDurationsTable[i];
+            int type = (off>>OFFSET_TYPE_SHIFT)&OFFSET_TYPE_MASK;
+            int memFactor = type / ServiceState.SERVICE_COUNT;
+            type %= ServiceState.SERVICE_COUNT;
+            if (type != serviceType) {
+                continue;
+            }
+            long time = svc.mStats.getLong(off, 0);
+            if (curState == memFactor) {
+                didCurState = true;
+                time += now - curStartTime;
+            }
+            printAdjTagAndValue(pw, memFactor, time);
+        }
+        if (!didCurState && curState != STATE_NOTHING) {
+            printAdjTagAndValue(pw, curState, now - curStartTime);
+        }
+        pw.println();
+    }
+
+    public static void computeProcessData(ProcessState proc, ProcessDataCollection data, long now) {
+        data.totalTime = 0;
+        data.numPss = data.minPss = data.avgPss = data.maxPss =
+                data.minUss = data.avgUss = data.maxUss = 0;
+        for (int is=0; is<data.screenStates.length; is++) {
+            for (int im=0; im<data.memStates.length; im++) {
+                for (int ip=0; ip<data.procStates.length; ip++) {
+                    int bucket = ((data.screenStates[is] + data.memStates[im]) * STATE_COUNT)
+                            + data.procStates[ip];
+                    data.totalTime += proc.getDuration(bucket, now);
+                    long samples = proc.getPssSampleCount(bucket);
+                    if (samples > 0) {
+                        long minPss = proc.getPssMinimum(bucket);
+                        long avgPss = proc.getPssAverage(bucket);
+                        long maxPss = proc.getPssMaximum(bucket);
+                        long minUss = proc.getPssUssMinimum(bucket);
+                        long avgUss = proc.getPssUssAverage(bucket);
+                        long maxUss = proc.getPssUssMaximum(bucket);
+                        if (data.numPss == 0) {
+                            data.minPss = minPss;
+                            data.avgPss = avgPss;
+                            data.maxPss = maxPss;
+                            data.minUss = minUss;
+                            data.avgUss = avgUss;
+                            data.maxUss = maxUss;
+                        } else {
+                            if (minPss < data.minPss) {
+                                data.minPss = minPss;
+                            }
+                            data.avgPss = (long)( ((data.avgPss*(double)data.numPss)
+                                    + (avgPss*(double)samples)) / (data.numPss+samples) );
+                            if (maxPss > data.maxPss) {
+                                data.maxPss = maxPss;
+                            }
+                            if (minUss < data.minUss) {
+                                data.minUss = minUss;
+                            }
+                            data.avgUss = (long)( ((data.avgUss*(double)data.numPss)
+                                    + (avgUss*(double)samples)) / (data.numPss+samples) );
+                            if (maxUss > data.maxUss) {
+                                data.maxUss = maxUss;
+                            }
+                        }
+                        data.numPss += samples;
+                    }
+                }
+            }
+        }
+    }
+
+    static long computeProcessTimeLocked(ProcessState proc, int[] screenStates, int[] memStates,
+                int[] procStates, long now) {
+        long totalTime = 0;
+        /*
+        for (int i=0; i<proc.mDurationsTableSize; i++) {
+            int val = proc.mDurationsTable[i];
+            totalTime += proc.mState.getLong(val, 0);
+            if ((val&0xff) == proc.mCurState) {
+                totalTime += now - proc.mStartTime;
+            }
+        }
+        */
+        for (int is=0; is<screenStates.length; is++) {
+            for (int im=0; im<memStates.length; im++) {
+                for (int ip=0; ip<procStates.length; ip++) {
+                    int bucket = ((screenStates[is] + memStates[im]) * STATE_COUNT)
+                            + procStates[ip];
+                    totalTime += proc.getDuration(bucket, now);
+                }
+            }
+        }
+        proc.mTmpTotalTime = totalTime;
+        return totalTime;
+    }
+
+    static void dumpProcessState(PrintWriter pw, String prefix, ProcessState proc,
+            int[] screenStates, int[] memStates, int[] procStates, long now) {
+        long totalTime = 0;
+        int printedScreen = -1;
+        for (int is=0; is<screenStates.length; is++) {
+            int printedMem = -1;
+            for (int im=0; im<memStates.length; im++) {
+                for (int ip=0; ip<procStates.length; ip++) {
+                    final int iscreen = screenStates[is];
+                    final int imem = memStates[im];
+                    final int bucket = ((iscreen + imem) * STATE_COUNT) + procStates[ip];
+                    long time = proc.getDuration(bucket, now);
+                    String running = "";
+                    if (proc.mCurState == bucket) {
+                        running = " (running)";
+                    }
+                    if (time != 0) {
+                        pw.print(prefix);
+                        if (screenStates.length > 1) {
+                            printScreenLabel(pw, printedScreen != iscreen
+                                    ? iscreen : STATE_NOTHING);
+                            printedScreen = iscreen;
+                        }
+                        if (memStates.length > 1) {
+                            printMemLabel(pw, printedMem != imem ? imem : STATE_NOTHING);
+                            printedMem = imem;
+                        }
+                        pw.print(STATE_NAMES[procStates[ip]]); pw.print(": ");
+                        TimeUtils.formatDuration(time, pw); pw.println(running);
+                        totalTime += time;
+                    }
+                }
+            }
+        }
+        if (totalTime != 0) {
+            pw.print(prefix);
+            if (screenStates.length > 1) {
+                printScreenLabel(pw, STATE_NOTHING);
+            }
+            if (memStates.length > 1) {
+                printMemLabel(pw, STATE_NOTHING);
+            }
+            pw.print("TOTAL     : ");
+            TimeUtils.formatDuration(totalTime, pw);
+            pw.println();
+        }
+    }
+
+    static void dumpProcessPss(PrintWriter pw, String prefix, ProcessState proc, int[] screenStates,
+            int[] memStates, int[] procStates) {
+        boolean printedHeader = false;
+        int printedScreen = -1;
+        for (int is=0; is<screenStates.length; is++) {
+            int printedMem = -1;
+            for (int im=0; im<memStates.length; im++) {
+                for (int ip=0; ip<procStates.length; ip++) {
+                    final int iscreen = screenStates[is];
+                    final int imem = memStates[im];
+                    final int bucket = ((iscreen + imem) * STATE_COUNT) + procStates[ip];
+                    long count = proc.getPssSampleCount(bucket);
+                    if (count > 0) {
+                        if (!printedHeader) {
+                            pw.print(prefix);
+                            pw.print("PSS/USS (");
+                            pw.print(proc.mPssTableSize);
+                            pw.println(" entries):");
+                            printedHeader = true;
+                        }
+                        pw.print(prefix);
+                        pw.print("  ");
+                        if (screenStates.length > 1) {
+                            printScreenLabel(pw, printedScreen != iscreen
+                                    ? iscreen : STATE_NOTHING);
+                            printedScreen = iscreen;
+                        }
+                        if (memStates.length > 1) {
+                            printMemLabel(pw, printedMem != imem ? imem : STATE_NOTHING);
+                            printedMem = imem;
+                        }
+                        pw.print(STATE_NAMES[procStates[ip]]); pw.print(": ");
+                        pw.print(count);
+                        pw.print(" samples ");
+                        printSizeValue(pw, proc.getPssMinimum(bucket) * 1024);
+                        pw.print(" ");
+                        printSizeValue(pw, proc.getPssAverage(bucket) * 1024);
+                        pw.print(" ");
+                        printSizeValue(pw, proc.getPssMaximum(bucket) * 1024);
+                        pw.print(" / ");
+                        printSizeValue(pw, proc.getPssUssMinimum(bucket) * 1024);
+                        pw.print(" ");
+                        printSizeValue(pw, proc.getPssUssAverage(bucket) * 1024);
+                        pw.print(" ");
+                        printSizeValue(pw, proc.getPssUssMaximum(bucket) * 1024);
+                        pw.println();
+                    }
+                }
+            }
+        }
+        if (proc.mNumExcessiveWake != 0) {
+            pw.print(prefix); pw.print("Killed for excessive wake locks: ");
+                    pw.print(proc.mNumExcessiveWake); pw.println(" times");
+        }
+        if (proc.mNumExcessiveCpu != 0) {
+            pw.print(prefix); pw.print("Killed for excessive CPU use: ");
+                    pw.print(proc.mNumExcessiveCpu); pw.println(" times");
+        }
+    }
+
+    static void dumpStateHeadersCsv(PrintWriter pw, String sep, int[] screenStates,
+            int[] memStates, int[] procStates) {
+        final int NS = screenStates != null ? screenStates.length : 1;
+        final int NM = memStates != null ? memStates.length : 1;
+        final int NP = procStates != null ? procStates.length : 1;
+        for (int is=0; is<NS; is++) {
+            for (int im=0; im<NM; im++) {
+                for (int ip=0; ip<NP; ip++) {
+                    pw.print(sep);
+                    boolean printed = false;
+                    if (screenStates != null && screenStates.length > 1) {
+                        printScreenLabelCsv(pw, screenStates[is]);
+                        printed = true;
+                    }
+                    if (memStates != null && memStates.length > 1) {
+                        if (printed) {
+                            pw.print("-");
+                        }
+                        printMemLabelCsv(pw, memStates[im]);
+                        printed = true;
+                    }
+                    if (procStates != null && procStates.length > 1) {
+                        if (printed) {
+                            pw.print("-");
+                        }
+                        pw.print(STATE_NAMES_CSV[procStates[ip]]);
+                    }
+                }
+            }
+        }
+    }
+
+    static void dumpProcessStateCsv(PrintWriter pw, ProcessState proc,
+            boolean sepScreenStates, int[] screenStates, boolean sepMemStates, int[] memStates,
+            boolean sepProcStates, int[] procStates, long now) {
+        final int NSS = sepScreenStates ? screenStates.length : 1;
+        final int NMS = sepMemStates ? memStates.length : 1;
+        final int NPS = sepProcStates ? procStates.length : 1;
+        for (int iss=0; iss<NSS; iss++) {
+            for (int ims=0; ims<NMS; ims++) {
+                for (int ips=0; ips<NPS; ips++) {
+                    final int vsscreen = sepScreenStates ? screenStates[iss] : 0;
+                    final int vsmem = sepMemStates ? memStates[ims] : 0;
+                    final int vsproc = sepProcStates ? procStates[ips] : 0;
+                    final int NSA = sepScreenStates ? 1 : screenStates.length;
+                    final int NMA = sepMemStates ? 1 : memStates.length;
+                    final int NPA = sepProcStates ? 1 : procStates.length;
+                    long totalTime = 0;
+                    for (int isa=0; isa<NSA; isa++) {
+                        for (int ima=0; ima<NMA; ima++) {
+                            for (int ipa=0; ipa<NPA; ipa++) {
+                                final int vascreen = sepScreenStates ? 0 : screenStates[isa];
+                                final int vamem = sepMemStates ? 0 : memStates[ima];
+                                final int vaproc = sepProcStates ? 0 : procStates[ipa];
+                                final int bucket = ((vsscreen + vascreen + vsmem + vamem)
+                                        * STATE_COUNT) + vsproc + vaproc;
+                                totalTime += proc.getDuration(bucket, now);
+                            }
+                        }
+                    }
+                    pw.print(CSV_SEP);
+                    pw.print(totalTime);
+                }
+            }
+        }
+    }
+
+    static void dumpProcessList(PrintWriter pw, String prefix, ArrayList<ProcessState> procs,
+            int[] screenStates, int[] memStates, int[] procStates, long now) {
+        String innerPrefix = prefix + "  ";
+        for (int i=procs.size()-1; i>=0; i--) {
+            ProcessState proc = procs.get(i);
+            pw.print(prefix);
+            pw.print(proc.mName);
+            pw.print(" / ");
+            UserHandle.formatUid(pw, proc.mUid);
+            pw.print(" (");
+            pw.print(proc.mDurationsTableSize);
+            pw.print(" entries)");
+            pw.println(":");
+            dumpProcessState(pw, innerPrefix, proc, screenStates, memStates, procStates, now);
+            if (proc.mPssTableSize > 0) {
+                dumpProcessPss(pw, innerPrefix, proc, screenStates, memStates, procStates);
+            }
+        }
+    }
+
+    static void dumpProcessSummaryDetails(PrintWriter pw, ProcessState proc, String prefix,
+            String label, int[] screenStates, int[] memStates, int[] procStates,
+            long now, long totalTime, boolean full) {
+        ProcessDataCollection totals = new ProcessDataCollection(screenStates,
+                memStates, procStates);
+        computeProcessData(proc, totals, now);
+        if (totals.totalTime != 0 || totals.numPss != 0) {
+            if (prefix != null) {
+                pw.print(prefix);
+            }
+            if (label != null) {
+                pw.print(label);
+            }
+            totals.print(pw, totalTime, full);
+            if (prefix != null) {
+                pw.println();
+            }
+        }
+    }
+
+    static void dumpProcessSummaryLocked(PrintWriter pw, String prefix,
+            ArrayList<ProcessState> procs, int[] screenStates, int[] memStates, int[] procStates,
+            long now, long totalTime) {
+        for (int i=procs.size()-1; i>=0; i--) {
+            ProcessState proc = procs.get(i);
+            pw.print(prefix);
+            pw.print("* ");
+            pw.print(proc.mName);
+            pw.print(" / ");
+            UserHandle.formatUid(pw, proc.mUid);
+            pw.println(":");
+            dumpProcessSummaryDetails(pw, proc, prefix, "         TOTAL: ", screenStates, memStates,
+                    procStates, now, totalTime, true);
+            dumpProcessSummaryDetails(pw, proc, prefix, "    Persistent: ", screenStates, memStates,
+                    new int[] { STATE_PERSISTENT }, now, totalTime, true);
+            dumpProcessSummaryDetails(pw, proc, prefix, "           Top: ", screenStates, memStates,
+                    new int[] {STATE_TOP}, now, totalTime, true);
+            dumpProcessSummaryDetails(pw, proc, prefix, "        Imp Fg: ", screenStates, memStates,
+                    new int[] { STATE_IMPORTANT_FOREGROUND }, now, totalTime, true);
+            dumpProcessSummaryDetails(pw, proc, prefix, "        Imp Bg: ", screenStates, memStates,
+                    new int[] {STATE_IMPORTANT_BACKGROUND}, now, totalTime, true);
+            dumpProcessSummaryDetails(pw, proc, prefix, "        Backup: ", screenStates, memStates,
+                    new int[] {STATE_BACKUP}, now, totalTime, true);
+            dumpProcessSummaryDetails(pw, proc, prefix, "     Heavy Wgt: ", screenStates, memStates,
+                    new int[] {STATE_HEAVY_WEIGHT}, now, totalTime, true);
+            dumpProcessSummaryDetails(pw, proc, prefix, "       Service: ", screenStates, memStates,
+                    new int[] {STATE_SERVICE}, now, totalTime, true);
+            dumpProcessSummaryDetails(pw, proc, prefix, "    Service Rs: ", screenStates, memStates,
+                    new int[] {STATE_SERVICE_RESTARTING}, now, totalTime, true);
+            dumpProcessSummaryDetails(pw, proc, prefix, "      Receiver: ", screenStates, memStates,
+                    new int[] {STATE_RECEIVER}, now, totalTime, true);
+            dumpProcessSummaryDetails(pw, proc, prefix, "          Home: ", screenStates, memStates,
+                    new int[] {STATE_HOME}, now, totalTime, true);
+            dumpProcessSummaryDetails(pw, proc, prefix, "    (Last Act): ", screenStates, memStates,
+                    new int[] {STATE_LAST_ACTIVITY}, now, totalTime, true);
+            dumpProcessSummaryDetails(pw, proc, prefix, "      (Cached): ", screenStates, memStates,
+                    new int[] {STATE_CACHED_ACTIVITY, STATE_CACHED_ACTIVITY_CLIENT,
+                            STATE_CACHED_EMPTY}, now, totalTime, true);
+        }
+    }
+
+    static void printPercent(PrintWriter pw, double fraction) {
+        fraction *= 100;
+        if (fraction < 1) {
+            pw.print(String.format("%.2f", fraction));
+        } else if (fraction < 10) {
+            pw.print(String.format("%.1f", fraction));
+        } else {
+            pw.print(String.format("%.0f", fraction));
+        }
+        pw.print("%");
+    }
+
+    static void printSizeValue(PrintWriter pw, long number) {
+        float result = number;
+        String suffix = "";
+        if (result > 900) {
+            suffix = "KB";
+            result = result / 1024;
+        }
+        if (result > 900) {
+            suffix = "MB";
+            result = result / 1024;
+        }
+        if (result > 900) {
+            suffix = "GB";
+            result = result / 1024;
+        }
+        if (result > 900) {
+            suffix = "TB";
+            result = result / 1024;
+        }
+        if (result > 900) {
+            suffix = "PB";
+            result = result / 1024;
+        }
+        String value;
+        if (result < 1) {
+            value = String.format("%.2f", result);
+        } else if (result < 10) {
+            value = String.format("%.1f", result);
+        } else if (result < 100) {
+            value = String.format("%.0f", result);
+        } else {
+            value = String.format("%.0f", result);
+        }
+        pw.print(value);
+        pw.print(suffix);
+    }
+
+    public static void dumpProcessListCsv(PrintWriter pw, ArrayList<ProcessState> procs,
+            boolean sepScreenStates, int[] screenStates, boolean sepMemStates, int[] memStates,
+            boolean sepProcStates, int[] procStates, long now) {
+        pw.print("process");
+        pw.print(CSV_SEP);
+        pw.print("uid");
+        dumpStateHeadersCsv(pw, CSV_SEP, sepScreenStates ? screenStates : null,
+                sepMemStates ? memStates : null,
+                sepProcStates ? procStates : null);
+        pw.println();
+        for (int i=procs.size()-1; i>=0; i--) {
+            ProcessState proc = procs.get(i);
+            pw.print(proc.mName);
+            pw.print(CSV_SEP);
+            UserHandle.formatUid(pw, proc.mUid);
+            dumpProcessStateCsv(pw, proc, sepScreenStates, screenStates,
+                    sepMemStates, memStates, sepProcStates, procStates, now);
+            pw.println();
+        }
+    }
+
+    static int printArrayEntry(PrintWriter pw, String[] array, int value, int mod) {
+        int index = value/mod;
+        if (index >= 0 && index < array.length) {
+            pw.print(array[index]);
+        } else {
+            pw.print('?');
+        }
+        return value - index*mod;
+    }
+
+    static void printProcStateTag(PrintWriter pw, int state) {
+        state = printArrayEntry(pw, ADJ_SCREEN_TAGS,  state, ADJ_SCREEN_MOD*STATE_COUNT);
+        state = printArrayEntry(pw, ADJ_MEM_TAGS,  state, STATE_COUNT);
+        printArrayEntry(pw, STATE_TAGS,  state, 1);
+    }
+
+    static void printAdjTag(PrintWriter pw, int state) {
+        state = printArrayEntry(pw, ADJ_SCREEN_TAGS,  state, ADJ_SCREEN_MOD);
+        printArrayEntry(pw, ADJ_MEM_TAGS, state, 1);
+    }
+
+    static void printProcStateTagAndValue(PrintWriter pw, int state, long value) {
+        pw.print(',');
+        printProcStateTag(pw, state);
+        pw.print(':');
+        pw.print(value);
+    }
+
+    static void printAdjTagAndValue(PrintWriter pw, int state, long value) {
+        pw.print(',');
+        printAdjTag(pw, state);
+        pw.print(':');
+        pw.print(value);
+    }
+
+    static void dumpAllProcessStateCheckin(PrintWriter pw, ProcessState proc, long now) {
+        boolean didCurState = false;
+        for (int i=0; i<proc.mDurationsTableSize; i++) {
+            int off = proc.mDurationsTable[i];
+            int type = (off>>OFFSET_TYPE_SHIFT)&OFFSET_TYPE_MASK;
+            long time = proc.mStats.getLong(off, 0);
+            if (proc.mCurState == type) {
+                didCurState = true;
+                time += now - proc.mStartTime;
+            }
+            printProcStateTagAndValue(pw, type, time);
+        }
+        if (!didCurState && proc.mCurState != STATE_NOTHING) {
+            printProcStateTagAndValue(pw, proc.mCurState, now - proc.mStartTime);
+        }
+    }
+
+    static void dumpAllProcessPssCheckin(PrintWriter pw, ProcessState proc) {
+        for (int i=0; i<proc.mPssTableSize; i++) {
+            int off = proc.mPssTable[i];
+            int type = (off>>OFFSET_TYPE_SHIFT)&OFFSET_TYPE_MASK;
+            long count = proc.mStats.getLong(off, PSS_SAMPLE_COUNT);
+            long min = proc.mStats.getLong(off, PSS_MINIMUM);
+            long avg = proc.mStats.getLong(off, PSS_AVERAGE);
+            long max = proc.mStats.getLong(off, PSS_MAXIMUM);
+            long umin = proc.mStats.getLong(off, PSS_USS_MINIMUM);
+            long uavg = proc.mStats.getLong(off, PSS_USS_AVERAGE);
+            long umax = proc.mStats.getLong(off, PSS_USS_MAXIMUM);
+            pw.print(',');
+            printProcStateTag(pw, type);
+            pw.print(':');
+            pw.print(count);
+            pw.print(':');
+            pw.print(min);
+            pw.print(':');
+            pw.print(avg);
+            pw.print(':');
+            pw.print(max);
+            pw.print(':');
+            pw.print(umin);
+            pw.print(':');
+            pw.print(uavg);
+            pw.print(':');
+            pw.print(umax);
+        }
+    }
+
+    public void reset() {
+        if (DEBUG) Slog.d(TAG, "Resetting state of " + mTimePeriodStartClockStr);
+        resetCommon();
+        mPackages.getMap().clear();
+        mProcesses.getMap().clear();
+        mMemFactor = STATE_NOTHING;
+        mStartTime = 0;
+        if (DEBUG) Slog.d(TAG, "State reset; now " + mTimePeriodStartClockStr);
+    }
+
+    public void resetSafely() {
+        if (DEBUG) Slog.d(TAG, "Safely resetting state of " + mTimePeriodStartClockStr);
+        resetCommon();
+        long now = SystemClock.uptimeMillis();
+        ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
+        for (int ip=procMap.size()-1; ip>=0; ip--) {
+            SparseArray<ProcessState> uids = procMap.valueAt(ip);
+            for (int iu=uids.size()-1; iu>=0; iu--) {
+                ProcessState ps = uids.valueAt(iu);
+                if (ps.isInUse()) {
+                    uids.valueAt(iu).resetSafely(now);
+                } else {
+                    uids.removeAt(iu);
+                }
+            }
+            if (uids.size() <= 0) {
+                procMap.removeAt(ip);
+            }
+        }
+        ArrayMap<String, SparseArray<PackageState>> pkgMap = mPackages.getMap();
+        for (int ip=pkgMap.size()-1; ip>=0; ip--) {
+            SparseArray<PackageState> uids = pkgMap.valueAt(ip);
+            for (int iu=uids.size()-1; iu>=0; iu--) {
+                PackageState pkgState = uids.valueAt(iu);
+                for (int iproc=pkgState.mProcesses.size()-1; iproc>=0; iproc--) {
+                    ProcessState ps = pkgState.mProcesses.valueAt(iproc);
+                    if (ps.isInUse() || ps.mCommonProcess.isInUse()) {
+                        pkgState.mProcesses.valueAt(iproc).resetSafely(now);
+                    } else {
+                        pkgState.mProcesses.removeAt(iproc);
+                    }
+                }
+                for (int isvc=pkgState.mServices.size()-1; isvc>=0; isvc--) {
+                    ServiceState ss = pkgState.mServices.valueAt(isvc);
+                    if (ss.isInUse()) {
+                        pkgState.mServices.valueAt(isvc).resetSafely(now);
+                    } else {
+                        pkgState.mServices.removeAt(isvc);
+                    }
+                }
+                if (pkgState.mProcesses.size() <= 0 && pkgState.mServices.size() <= 0) {
+                    uids.removeAt(iu);
+                }
+            }
+            if (uids.size() <= 0) {
+                pkgMap.removeAt(ip);
+            }
+        }
+        mStartTime = SystemClock.uptimeMillis();
+        if (DEBUG) Slog.d(TAG, "State reset; now " + mTimePeriodStartClockStr);
+    }
+
+    private void resetCommon() {
+        mTimePeriodStartClock = System.currentTimeMillis();
+        buildTimePeriodStartClockStr();
+        mTimePeriodStartRealtime = mTimePeriodEndRealtime = SystemClock.elapsedRealtime();
+        mLongs.clear();
+        mLongs.add(new long[LONGS_SIZE]);
+        mNextLong = 0;
+        Arrays.fill(mMemFactorDurations, 0);
+        mStartTime = 0;
+        mReadError = null;
+        mFlags = 0;
+        evaluateSystemProperties(true);
+    }
+
+    public boolean evaluateSystemProperties(boolean update) {
+        boolean changed = false;
+        String runtime = SystemProperties.get("persist.sys.dalvik.vm.lib",
+                VMRuntime.getRuntime().vmLibrary());
+        if (!Objects.equals(runtime, mRuntime)) {
+            changed = true;
+            if (update) {
+                mRuntime = runtime;
+            }
+        }
+        String webview = WebViewFactory.useExperimentalWebView() ? "chromeview" : "webview";
+        if (!Objects.equals(webview, mWebView)) {
+            changed = true;
+            if (update) {
+                mWebView = webview;
+            }
+        }
+        return changed;
+    }
+
+    private void buildTimePeriodStartClockStr() {
+        mTimePeriodStartClockStr = DateFormat.format("yyyy-MM-dd-HH-mm-ss",
+                mTimePeriodStartClock).toString();
+    }
+
+    static final int[] BAD_TABLE = new int[0];
+
+    private int[] readTableFromParcel(Parcel in, String name, String what) {
+        final int size = in.readInt();
+        if (size < 0) {
+            Slog.w(TAG, "Ignoring existing stats; bad " + what + " table size: " + size);
+            return BAD_TABLE;
+        }
+        if (size == 0) {
+            return null;
+        }
+        final int[] table = new int[size];
+        for (int i=0; i<size; i++) {
+            table[i] = in.readInt();
+            if (DEBUG) Slog.i(TAG, "Reading in " + name + " table #" + i + ": "
+                    + ProcessStats.printLongOffset(table[i]));
+            if (!validateLongOffset(table[i])) {
+                Slog.w(TAG, "Ignoring existing stats; bad " + what + " table entry: "
+                        + ProcessStats.printLongOffset(table[i]));
+                return null;
+            }
+        }
+        return table;
+    }
+
+    private void writeCompactedLongArray(Parcel out, long[] array) {
+        final int N = array.length;
+        out.writeInt(N);
+        for (int i=0; i<N; i++) {
+            long val = array[i];
+            if (val < 0) {
+                Slog.w(TAG, "Time val negative: " + val);
+                val = 0;
+            }
+            if (val <= Integer.MAX_VALUE) {
+                out.writeInt((int)val);
+            } else {
+                int top = ~((int)((val>>32)&0x7fffffff));
+                int bottom = (int)(val&0xfffffff);
+                out.writeInt(top);
+                out.writeInt(bottom);
+            }
+        }
+    }
+
+    private void readCompactedLongArray(Parcel in, int version, long[] array) {
+        if (version <= 10) {
+            in.readLongArray(array);
+            return;
+        }
+        final int N = in.readInt();
+        if (N != array.length) {
+            throw new RuntimeException("bad array lengths");
+        }
+        for (int i=0; i<N; i++) {
+            int val = in.readInt();
+            if (val >= 0) {
+                array[i] = val;
+            } else {
+                int bottom = in.readInt();
+                array[i] = (((long)~val)<<32) | bottom;
+            }
+        }
+    }
+
+    private void writeCommonString(Parcel out, String name) {
+        Integer index = mCommonStringToIndex.get(name);
+        if (index != null) {
+            out.writeInt(index);
+            return;
+        }
+        index = mCommonStringToIndex.size();
+        mCommonStringToIndex.put(name, index);
+        out.writeInt(~index);
+        out.writeString(name);
+    }
+
+    private String readCommonString(Parcel in, int version) {
+        if (version <= 9) {
+            return in.readString();
+        }
+        int index = in.readInt();
+        if (index >= 0) {
+            return mIndexToCommonString.get(index);
+        }
+        index = ~index;
+        String name = in.readString();
+        while (mIndexToCommonString.size() <= index) {
+            mIndexToCommonString.add(null);
+        }
+        mIndexToCommonString.set(index, name);
+        return name;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        long now = SystemClock.uptimeMillis();
+        out.writeInt(MAGIC);
+        out.writeInt(PARCEL_VERSION);
+        out.writeInt(STATE_COUNT);
+        out.writeInt(ADJ_COUNT);
+        out.writeInt(PSS_COUNT);
+        out.writeInt(LONGS_SIZE);
+
+        mCommonStringToIndex = new ArrayMap<String, Integer>(mProcesses.mMap.size());
+
+        // First commit all running times.
+        ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
+        final int NPROC = procMap.size();
+        for (int ip=0; ip<NPROC; ip++) {
+            SparseArray<ProcessState> uids = procMap.valueAt(ip);
+            final int NUID = uids.size();
+            for (int iu=0; iu<NUID; iu++) {
+                uids.valueAt(iu).commitStateTime(now);
+            }
+        }
+        ArrayMap<String, SparseArray<PackageState>> pkgMap = mPackages.getMap();
+        final int NPKG = pkgMap.size();
+        for (int ip=0; ip<NPKG; ip++) {
+            SparseArray<PackageState> uids = pkgMap.valueAt(ip);
+            final int NUID = uids.size();
+            for (int iu=0; iu<NUID; iu++) {
+                PackageState pkgState = uids.valueAt(iu);
+                final int NPROCS = pkgState.mProcesses.size();
+                for (int iproc=0; iproc<NPROCS; iproc++) {
+                    ProcessState proc = pkgState.mProcesses.valueAt(iproc);
+                    if (proc.mCommonProcess != proc) {
+                        proc.commitStateTime(now);
+                    }
+                }
+                final int NSRVS = pkgState.mServices.size();
+                for (int isvc=0; isvc<NSRVS; isvc++) {
+                    pkgState.mServices.valueAt(isvc).commitStateTime(now);
+                }
+            }
+        }
+
+        out.writeLong(mTimePeriodStartClock);
+        out.writeLong(mTimePeriodStartRealtime);
+        out.writeLong(mTimePeriodEndRealtime);
+        out.writeString(mRuntime);
+        out.writeString(mWebView);
+        out.writeInt(mFlags);
+
+        out.writeInt(mLongs.size());
+        out.writeInt(mNextLong);
+        for (int i=0; i<(mLongs.size()-1); i++) {
+            writeCompactedLongArray(out, mLongs.get(i));
+        }
+        long[] lastLongs = mLongs.get(mLongs.size() - 1);
+        for (int i=0; i<mNextLong; i++) {
+            out.writeLong(lastLongs[i]);
+            if (DEBUG) Slog.d(TAG, "Writing last long #" + i + ": " + lastLongs[i]);
+        }
+
+        if (mMemFactor != STATE_NOTHING) {
+            mMemFactorDurations[mMemFactor] += now - mStartTime;
+            mStartTime = now;
+        }
+        writeCompactedLongArray(out, mMemFactorDurations);
+
+        out.writeInt(NPROC);
+        for (int ip=0; ip<NPROC; ip++) {
+            writeCommonString(out, procMap.keyAt(ip));
+            SparseArray<ProcessState> uids = procMap.valueAt(ip);
+            final int NUID = uids.size();
+            out.writeInt(NUID);
+            for (int iu=0; iu<NUID; iu++) {
+                out.writeInt(uids.keyAt(iu));
+                ProcessState proc = uids.valueAt(iu);
+                writeCommonString(out, proc.mPackage);
+                proc.writeToParcel(out, now);
+            }
+        }
+        out.writeInt(NPKG);
+        for (int ip=0; ip<NPKG; ip++) {
+            writeCommonString(out, pkgMap.keyAt(ip));
+            SparseArray<PackageState> uids = pkgMap.valueAt(ip);
+            final int NUID = uids.size();
+            out.writeInt(NUID);
+            for (int iu=0; iu<NUID; iu++) {
+                out.writeInt(uids.keyAt(iu));
+                PackageState pkgState = uids.valueAt(iu);
+                final int NPROCS = pkgState.mProcesses.size();
+                out.writeInt(NPROCS);
+                for (int iproc=0; iproc<NPROCS; iproc++) {
+                    writeCommonString(out, pkgState.mProcesses.keyAt(iproc));
+                    ProcessState proc = pkgState.mProcesses.valueAt(iproc);
+                    if (proc.mCommonProcess == proc) {
+                        // This is the same as the common process we wrote above.
+                        out.writeInt(0);
+                    } else {
+                        // There is separate data for this package's process.
+                        out.writeInt(1);
+                        proc.writeToParcel(out, now);
+                    }
+                }
+                final int NSRVS = pkgState.mServices.size();
+                out.writeInt(NSRVS);
+                for (int isvc=0; isvc<NSRVS; isvc++) {
+                    out.writeString(pkgState.mServices.keyAt(isvc));
+                    ServiceState svc = pkgState.mServices.valueAt(isvc);
+                    writeCommonString(out, svc.mProcessName);
+                    svc.writeToParcel(out, now);
+                }
+            }
+        }
+
+        mCommonStringToIndex = null;
+    }
+
+    private boolean readCheckedInt(Parcel in, int val, String what) {
+        int got;
+        if ((got=in.readInt()) != val) {
+            mReadError = "bad " + what + ": " + got;
+            return false;
+        }
+        return true;
+    }
+
+    static byte[] readFully(InputStream stream) throws IOException {
+        int pos = 0;
+        int avail = stream.available();
+        byte[] data = new byte[avail];
+        while (true) {
+            int amt = stream.read(data, pos, data.length-pos);
+            //Log.i("foo", "Read " + amt + " bytes at " + pos
+            //        + " of avail " + data.length);
+            if (amt <= 0) {
+                //Log.i("foo", "**** FINISHED READING: pos=" + pos
+                //        + " len=" + data.length);
+                return data;
+            }
+            pos += amt;
+            avail = stream.available();
+            if (avail > data.length-pos) {
+                byte[] newData = new byte[pos+avail];
+                System.arraycopy(data, 0, newData, 0, pos);
+                data = newData;
+            }
+        }
+    }
+
+    public void read(InputStream stream) {
+        try {
+            byte[] raw = readFully(stream);
+            Parcel in = Parcel.obtain();
+            in.unmarshall(raw, 0, raw.length);
+            in.setDataPosition(0);
+            stream.close();
+
+            readFromParcel(in);
+        } catch (IOException e) {
+            mReadError = "caught exception: " + e;
+        }
+    }
+
+    public void readFromParcel(Parcel in) {
+        final boolean hadData = mPackages.getMap().size() > 0
+                || mProcesses.getMap().size() > 0;
+        if (hadData) {
+            resetSafely();
+        }
+
+        if (!readCheckedInt(in, MAGIC, "magic number")) {
+            return;
+        }
+        int version = in.readInt();
+        if (version != PARCEL_VERSION) {
+            mReadError = "bad version: " + version;
+            return;
+        }
+        if (!readCheckedInt(in, STATE_COUNT, "state count")) {
+            return;
+        }
+        if (!readCheckedInt(in, ADJ_COUNT, "adj count")) {
+            return;
+        }
+        if (!readCheckedInt(in, PSS_COUNT, "pss count")) {
+            return;
+        }
+        if (!readCheckedInt(in, LONGS_SIZE, "longs size")) {
+            return;
+        }
+
+        mIndexToCommonString = new ArrayList<String>();
+
+        mTimePeriodStartClock = in.readLong();
+        buildTimePeriodStartClockStr();
+        mTimePeriodStartRealtime = in.readLong();
+        mTimePeriodEndRealtime = in.readLong();
+        mRuntime = in.readString();
+        mWebView = in.readString();
+        mFlags = in.readInt();
+
+        final int NLONGS = in.readInt();
+        final int NEXTLONG = in.readInt();
+        mLongs.clear();
+        for (int i=0; i<(NLONGS-1); i++) {
+            while (i >= mLongs.size()) {
+                mLongs.add(new long[LONGS_SIZE]);
+            }
+            readCompactedLongArray(in, version, mLongs.get(i));
+        }
+        long[] longs = new long[LONGS_SIZE];
+        mNextLong = NEXTLONG;
+        for (int i=0; i<NEXTLONG; i++) {
+            longs[i] = in.readLong();
+            if (DEBUG) Slog.d(TAG, "Reading last long #" + i + ": " + longs[i]);
+        }
+        mLongs.add(longs);
+
+        readCompactedLongArray(in, version, mMemFactorDurations);
+
+        int NPROC = in.readInt();
+        if (NPROC < 0) {
+            mReadError = "bad process count: " + NPROC;
+            return;
+        }
+        while (NPROC > 0) {
+            NPROC--;
+            String procName = readCommonString(in, version);
+            if (procName == null) {
+                mReadError = "bad process name";
+                return;
+            }
+            int NUID = in.readInt();
+            if (NUID < 0) {
+                mReadError = "bad uid count: " + NUID;
+                return;
+            }
+            while (NUID > 0) {
+                NUID--;
+                int uid = in.readInt();
+                if (uid < 0) {
+                    mReadError = "bad uid: " + uid;
+                    return;
+                }
+                String pkgName = readCommonString(in, version);
+                if (pkgName == null) {
+                    mReadError = "bad process package name";
+                    return;
+                }
+                ProcessState proc = hadData ? mProcesses.get(procName, uid) : null;
+                if (proc != null) {
+                    if (!proc.readFromParcel(in, false)) {
+                        return;
+                    }
+                } else {
+                    proc = new ProcessState(this, pkgName, uid, procName);
+                    if (!proc.readFromParcel(in, true)) {
+                        return;
+                    }
+                }
+                if (DEBUG) Slog.d(TAG, "Adding process: " + procName + " " + uid + " " + proc);
+                mProcesses.put(procName, uid, proc);
+            }
+        }
+
+        if (DEBUG) Slog.d(TAG, "Read " + mProcesses.getMap().size() + " processes");
+
+        int NPKG = in.readInt();
+        if (NPKG < 0) {
+            mReadError = "bad package count: " + NPKG;
+            return;
+        }
+        while (NPKG > 0) {
+            NPKG--;
+            String pkgName = readCommonString(in, version);
+            if (pkgName == null) {
+                mReadError = "bad package name";
+                return;
+            }
+            int NUID = in.readInt();
+            if (NUID < 0) {
+                mReadError = "bad uid count: " + NUID;
+                return;
+            }
+            while (NUID > 0) {
+                NUID--;
+                int uid = in.readInt();
+                if (uid < 0) {
+                    mReadError = "bad uid: " + uid;
+                    return;
+                }
+                PackageState pkgState = new PackageState(uid);
+                mPackages.put(pkgName, uid, pkgState);
+                int NPROCS = in.readInt();
+                if (NPROCS < 0) {
+                    mReadError = "bad package process count: " + NPROCS;
+                    return;
+                }
+                while (NPROCS > 0) {
+                    NPROCS--;
+                    String procName = readCommonString(in, version);
+                    if (procName == null) {
+                        mReadError = "bad package process name";
+                        return;
+                    }
+                    int hasProc = in.readInt();
+                    if (DEBUG) Slog.d(TAG, "Reading package " + pkgName + " " + uid
+                            + " process " + procName + " hasProc=" + hasProc);
+                    ProcessState commonProc = mProcesses.get(procName, uid);
+                    if (DEBUG) Slog.d(TAG, "Got common proc " + procName + " " + uid
+                            + ": " + commonProc);
+                    if (commonProc == null) {
+                        mReadError = "no common proc: " + procName;
+                        return;
+                    }
+                    if (hasProc != 0) {
+                        // The process for this package is unique to the package; we
+                        // need to load it.  We don't need to do anything about it if
+                        // it is not unique because if someone later looks for it
+                        // they will find and use it from the global procs.
+                        ProcessState proc = hadData ? pkgState.mProcesses.get(procName) : null;
+                        if (proc != null) {
+                            if (!proc.readFromParcel(in, false)) {
+                                return;
+                            }
+                        } else {
+                            proc = new ProcessState(commonProc, pkgName, uid, procName, 0);
+                            if (!proc.readFromParcel(in, true)) {
+                                return;
+                            }
+                        }
+                        if (DEBUG) Slog.d(TAG, "Adding package " + pkgName + " process: "
+                                + procName + " " + uid + " " + proc);
+                        pkgState.mProcesses.put(procName, proc);
+                    } else {
+                        if (DEBUG) Slog.d(TAG, "Adding package " + pkgName + " process: "
+                                + procName + " " + uid + " " + commonProc);
+                        pkgState.mProcesses.put(procName, commonProc);
+                    }
+                }
+                int NSRVS = in.readInt();
+                if (NSRVS < 0) {
+                    mReadError = "bad package service count: " + NSRVS;
+                    return;
+                }
+                while (NSRVS > 0) {
+                    NSRVS--;
+                    String serviceName = in.readString();
+                    if (serviceName == null) {
+                        mReadError = "bad package service name";
+                        return;
+                    }
+                    String processName = version > 9 ? readCommonString(in, version) : null;
+                    ServiceState serv = hadData ? pkgState.mServices.get(serviceName) : null;
+                    if (serv == null) {
+                        serv = new ServiceState(this, pkgName, serviceName, processName, null);
+                    }
+                    if (!serv.readFromParcel(in)) {
+                        return;
+                    }
+                    if (DEBUG) Slog.d(TAG, "Adding package " + pkgName + " service: "
+                            + serviceName + " " + uid + " " + serv);
+                    pkgState.mServices.put(serviceName, serv);
+                }
+            }
+        }
+
+        mIndexToCommonString = null;
+
+        if (DEBUG) Slog.d(TAG, "Successfully read procstats!");
+    }
+
+    int addLongData(int index, int type, int num) {
+        int tableLen = mAddLongTable != null ? mAddLongTable.length : 0;
+        if (mAddLongTableSize >= tableLen) {
+            int newSize = ArrayUtils.idealIntArraySize(tableLen + 1);
+            int[] newTable = new int[newSize];
+            if (tableLen > 0) {
+                System.arraycopy(mAddLongTable, 0, newTable, 0, tableLen);
+            }
+            mAddLongTable = newTable;
+        }
+        if (mAddLongTableSize > 0 && mAddLongTableSize - index != 0) {
+            System.arraycopy(mAddLongTable, index, mAddLongTable, index + 1,
+                    mAddLongTableSize - index);
+        }
+        int off = allocLongData(num);
+        mAddLongTable[index] = type | off;
+        mAddLongTableSize++;
+        return off;
+    }
+
+    int allocLongData(int num) {
+        int whichLongs = mLongs.size()-1;
+        long[] longs = mLongs.get(whichLongs);
+        if (mNextLong + num > longs.length) {
+            longs = new long[LONGS_SIZE];
+            mLongs.add(longs);
+            whichLongs++;
+            mNextLong = 0;
+        }
+        int off = (whichLongs<<OFFSET_ARRAY_SHIFT) | (mNextLong<<OFFSET_INDEX_SHIFT);
+        mNextLong += num;
+        return off;
+    }
+
+    boolean validateLongOffset(int off) {
+        int arr = (off>>OFFSET_ARRAY_SHIFT)&OFFSET_ARRAY_MASK;
+        if (arr >= mLongs.size()) {
+            return false;
+        }
+        int idx = (off>>OFFSET_INDEX_SHIFT)&OFFSET_INDEX_MASK;
+        if (idx >= LONGS_SIZE) {
+            return false;
+        }
+        if (DEBUG) Slog.d(TAG, "Validated long " + printLongOffset(off)
+                + ": " + getLong(off, 0));
+        return true;
+    }
+
+    static String printLongOffset(int off) {
+        StringBuilder sb = new StringBuilder(16);
+        sb.append("a"); sb.append((off>>OFFSET_ARRAY_SHIFT)&OFFSET_ARRAY_MASK);
+        sb.append("i"); sb.append((off>>OFFSET_INDEX_SHIFT)&OFFSET_INDEX_MASK);
+        sb.append("t"); sb.append((off>>OFFSET_TYPE_SHIFT)&OFFSET_TYPE_MASK);
+        return sb.toString();
+    }
+
+    void setLong(int off, int index, long value) {
+        long[] longs = mLongs.get((off>>OFFSET_ARRAY_SHIFT)&OFFSET_ARRAY_MASK);
+        longs[index + ((off>>OFFSET_INDEX_SHIFT)&OFFSET_INDEX_MASK)] = value;
+    }
+
+    long getLong(int off, int index) {
+        long[] longs = mLongs.get((off>>OFFSET_ARRAY_SHIFT)&OFFSET_ARRAY_MASK);
+        return longs[index + ((off>>OFFSET_INDEX_SHIFT)&OFFSET_INDEX_MASK)];
+    }
+
+    static int binarySearch(int[] array, int size, int value) {
+        int lo = 0;
+        int hi = size - 1;
+
+        while (lo <= hi) {
+            int mid = (lo + hi) >>> 1;
+            int midVal = (array[mid] >> OFFSET_TYPE_SHIFT) & OFFSET_TYPE_MASK;
+
+            if (midVal < value) {
+                lo = mid + 1;
+            } else if (midVal > value) {
+                hi = mid - 1;
+            } else {
+                return mid;  // value found
+            }
+        }
+        return ~lo;  // value not present
+    }
+
+    public PackageState getPackageStateLocked(String packageName, int uid) {
+        PackageState as = mPackages.get(packageName, uid);
+        if (as != null) {
+            return as;
+        }
+        as = new PackageState(uid);
+        mPackages.put(packageName, uid, as);
+        return as;
+    }
+
+    public ProcessState getProcessStateLocked(String packageName, int uid, String processName) {
+        final PackageState pkgState = getPackageStateLocked(packageName, uid);
+        ProcessState ps = pkgState.mProcesses.get(processName);
+        if (ps != null) {
+            return ps;
+        }
+        ProcessState commonProc = mProcesses.get(processName, uid);
+        if (commonProc == null) {
+            commonProc = new ProcessState(this, packageName, uid, processName);
+            mProcesses.put(processName, uid, commonProc);
+        }
+        if (!commonProc.mMultiPackage) {
+            if (packageName.equals(commonProc.mPackage)) {
+                // This common process is not in use by multiple packages, and
+                // is for the calling package, so we can just use it directly.
+                ps = commonProc;
+            } else {
+                // This common process has not been in use by multiple packages,
+                // but it was created for a different package than the caller.
+                // We need to convert it to a multi-package process.
+                commonProc.mMultiPackage = true;
+                // The original package it was created for now needs to point
+                // to its own copy.
+                long now = SystemClock.uptimeMillis();
+                pkgState.mProcesses.put(commonProc.mName, commonProc.clone(
+                        commonProc.mPackage, now));
+                ps = new ProcessState(commonProc, packageName, uid, processName, now);
+            }
+        } else {
+            // The common process is for multiple packages, we need to create a
+            // separate object for the per-package data.
+            ps = new ProcessState(commonProc, packageName, uid, processName,
+                    SystemClock.uptimeMillis());
+        }
+        pkgState.mProcesses.put(processName, ps);
+        return ps;
+    }
+
+    public ProcessStats.ServiceState getServiceStateLocked(String packageName, int uid,
+            String processName, String className) {
+        final ProcessStats.PackageState as = getPackageStateLocked(packageName, uid);
+        ProcessStats.ServiceState ss = as.mServices.get(className);
+        if (ss != null) {
+            return ss;
+        }
+        final ProcessStats.ProcessState ps = processName != null
+                ? getProcessStateLocked(packageName, uid, processName) : null;
+        ss = new ProcessStats.ServiceState(this, packageName, className, processName, ps);
+        as.mServices.put(className, ss);
+        return ss;
+    }
+
+    public void dumpLocked(PrintWriter pw, String reqPackage, long now, boolean dumpAll) {
+        long totalTime = dumpSingleTime(null, null, mMemFactorDurations, mMemFactor,
+                mStartTime, now);
+        ArrayMap<String, SparseArray<PackageState>> pkgMap = mPackages.getMap();
+        boolean printedHeader = false;
+        for (int ip=0; ip<pkgMap.size(); ip++) {
+            String pkgName = pkgMap.keyAt(ip);
+            if (reqPackage != null && !reqPackage.equals(pkgName)) {
+                continue;
+            }
+            SparseArray<PackageState> uids = pkgMap.valueAt(ip);
+            for (int iu=0; iu<uids.size(); iu++) {
+                int uid = uids.keyAt(iu);
+                PackageState pkgState = uids.valueAt(iu);
+                final int NPROCS = pkgState.mProcesses.size();
+                final int NSRVS = pkgState.mServices.size();
+                if (NPROCS > 0 || NSRVS > 0) {
+                    if (!printedHeader) {
+                        pw.println("Per-Package Stats:");
+                        printedHeader = true;
+                    }
+                    pw.print("  * "); pw.print(pkgName); pw.print(" / ");
+                            UserHandle.formatUid(pw, uid); pw.println(":");
+                }
+                if (dumpAll) {
+                    for (int iproc=0; iproc<NPROCS; iproc++) {
+                        ProcessState proc = pkgState.mProcesses.valueAt(iproc);
+                        pw.print("      Process ");
+                        pw.print(pkgState.mProcesses.keyAt(iproc));
+                        pw.print(" (");
+                        pw.print(proc.mDurationsTableSize);
+                        pw.print(" entries)");
+                        pw.println(":");
+                        dumpProcessState(pw, "        ", proc, ALL_SCREEN_ADJ, ALL_MEM_ADJ,
+                                ALL_PROC_STATES, now);
+                        dumpProcessPss(pw, "        ", proc, ALL_SCREEN_ADJ, ALL_MEM_ADJ,
+                                ALL_PROC_STATES);
+                        pw.print("        mActive="); pw.println(proc.mActive);
+                        pw.print("        mNumActiveServices="); pw.print(proc.mNumActiveServices);
+                                pw.print(" mNumStartedServices=");
+                                pw.println(proc.mNumStartedServices);
+                    }
+                } else {
+                    ArrayList<ProcessState> procs = new ArrayList<ProcessState>();
+                    for (int iproc=0; iproc<NPROCS; iproc++) {
+                        procs.add(pkgState.mProcesses.valueAt(iproc));
+                    }
+                    dumpProcessSummaryLocked(pw, "      ", procs, ALL_SCREEN_ADJ, ALL_MEM_ADJ,
+                            NON_CACHED_PROC_STATES, now, totalTime);
+                }
+                for (int isvc=0; isvc<NSRVS; isvc++) {
+                    if (dumpAll) {
+                        pw.print("      Service ");
+                    } else {
+                        pw.print("      * ");
+                    }
+                    pw.print(pkgState.mServices.keyAt(isvc));
+                    pw.println(":");
+                    ServiceState svc = pkgState.mServices.valueAt(isvc);
+                    dumpServiceStats(pw, "        ", "          ", "    ", "Running", svc,
+                            svc.mRunCount, ServiceState.SERVICE_RUN, svc.mRunState,
+                            svc.mRunStartTime, now, totalTime, dumpAll);
+                    dumpServiceStats(pw, "        ", "          ", "    ", "Started", svc,
+                            svc.mStartedCount, ServiceState.SERVICE_STARTED, svc.mStartedState,
+                            svc.mStartedStartTime, now, totalTime, dumpAll);
+                    dumpServiceStats(pw, "        ", "          ", "      ", "Bound", svc,
+                            svc.mBoundCount, ServiceState.SERVICE_BOUND, svc.mBoundState,
+                            svc.mBoundStartTime, now, totalTime, dumpAll);
+                    dumpServiceStats(pw, "        ", "          ", "  ", "Executing", svc,
+                            svc.mExecCount, ServiceState.SERVICE_EXEC, svc.mExecState,
+                            svc.mExecStartTime, now, totalTime, dumpAll);
+                    if (dumpAll) {
+                        pw.print("        mActive="); pw.println(svc.mActive);
+                    }
+                }
+            }
+        }
+
+        if (reqPackage == null) {
+            ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
+            printedHeader = false;
+            for (int ip=0; ip<procMap.size(); ip++) {
+                String procName = procMap.keyAt(ip);
+                SparseArray<ProcessState> uids = procMap.valueAt(ip);
+                for (int iu=0; iu<uids.size(); iu++) {
+                    int uid = uids.keyAt(iu);
+                    ProcessState proc = uids.valueAt(iu);
+                    if (proc.mDurationsTableSize == 0 && proc.mCurState == STATE_NOTHING
+                            && proc.mPssTableSize == 0) {
+                        continue;
+                    }
+                    if (!printedHeader) {
+                        pw.println();
+                        pw.println("Per-Process Stats:");
+                        printedHeader = true;
+                    }
+                    pw.print("  * "); pw.print(procName); pw.print(" / ");
+                            UserHandle.formatUid(pw, uid);
+                            pw.print(" ("); pw.print(proc.mDurationsTableSize);
+                            pw.print(" entries)"); pw.println(":");
+                    dumpProcessState(pw, "        ", proc, ALL_SCREEN_ADJ, ALL_MEM_ADJ,
+                            ALL_PROC_STATES, now);
+                    dumpProcessPss(pw, "        ", proc, ALL_SCREEN_ADJ, ALL_MEM_ADJ,
+                            ALL_PROC_STATES);
+                    if (dumpAll) {
+                        pw.print("        mActive="); pw.println(proc.mActive);
+                        pw.print("        mNumActiveServices="); pw.print(proc.mNumActiveServices);
+                                pw.print(" mNumStartedServices=");
+                                pw.println(proc.mNumStartedServices);
+                    }
+                }
+            }
+
+            pw.println();
+            pw.println("Summary:");
+            dumpSummaryLocked(pw, reqPackage, now);
+        } else {
+            pw.println();
+            dumpTotalsLocked(pw, now);
+        }
+
+        if (dumpAll) {
+            pw.println();
+            pw.println("Internal state:");
+            pw.print("  Num long arrays: "); pw.println(mLongs.size());
+            pw.print("  Next long entry: "); pw.println(mNextLong);
+            pw.print("  mRunning="); pw.println(mRunning);
+        }
+    }
+
+    public static long dumpSingleServiceTime(PrintWriter pw, String prefix, ServiceState service,
+            int serviceType, int curState, long curStartTime, long now) {
+        long totalTime = 0;
+        int printedScreen = -1;
+        for (int iscreen=0; iscreen<ADJ_COUNT; iscreen+=ADJ_SCREEN_MOD) {
+            int printedMem = -1;
+            for (int imem=0; imem<ADJ_MEM_FACTOR_COUNT; imem++) {
+                int state = imem+iscreen;
+                long time = service.getDuration(serviceType, curState, curStartTime,
+                        state, now);
+                String running = "";
+                if (curState == state && pw != null) {
+                    running = " (running)";
+                }
+                if (time != 0) {
+                    if (pw != null) {
+                        pw.print(prefix);
+                        printScreenLabel(pw, printedScreen != iscreen
+                                ? iscreen : STATE_NOTHING);
+                        printedScreen = iscreen;
+                        printMemLabel(pw, printedMem != imem ? imem : STATE_NOTHING);
+                        printedMem = imem;
+                        TimeUtils.formatDuration(time, pw); pw.println(running);
+                    }
+                    totalTime += time;
+                }
+            }
+        }
+        if (totalTime != 0 && pw != null) {
+            pw.print(prefix);
+            printScreenLabel(pw, STATE_NOTHING);
+            pw.print("TOTAL: ");
+            TimeUtils.formatDuration(totalTime, pw);
+            pw.println();
+        }
+        return totalTime;
+    }
+
+    void dumpServiceStats(PrintWriter pw, String prefix, String prefixInner,
+            String headerPrefix, String header, ServiceState service,
+            int count, int serviceType, int state, long startTime, long now, long totalTime,
+            boolean dumpAll) {
+        if (count != 0) {
+            if (dumpAll) {
+                pw.print(prefix); pw.print(header);
+                pw.print(" op count "); pw.print(count); pw.println(":");
+                dumpSingleServiceTime(pw, prefixInner, service, serviceType, state, startTime,
+                        now);
+            } else {
+                long myTime = dumpSingleServiceTime(null, null, service, serviceType, state,
+                        startTime, now);
+                pw.print(prefix); pw.print(headerPrefix); pw.print(header);
+                pw.print(" count "); pw.print(count);
+                pw.print(" / time ");
+                printPercent(pw, (double)myTime/(double)totalTime);
+                pw.println();
+            }
+        }
+    }
+
+    public void dumpSummaryLocked(PrintWriter pw, String reqPackage, long now) {
+        long totalTime = dumpSingleTime(null, null, mMemFactorDurations, mMemFactor,
+                mStartTime, now);
+        dumpFilteredSummaryLocked(pw, null, "  ", ALL_SCREEN_ADJ, ALL_MEM_ADJ,
+                NON_CACHED_PROC_STATES, now, totalTime, reqPackage);
+        pw.println();
+        dumpTotalsLocked(pw, now);
+    }
+
+    void dumpTotalsLocked(PrintWriter pw, long now) {
+        pw.println("Run time Stats:");
+        dumpSingleTime(pw, "  ", mMemFactorDurations, mMemFactor, mStartTime, now);
+        pw.println();
+        pw.print("          Start time: ");
+        pw.print(DateFormat.format("yyyy-MM-dd HH:mm:ss", mTimePeriodStartClock));
+        pw.println();
+        pw.print("  Total elapsed time: ");
+        TimeUtils.formatDuration(
+                (mRunning ? SystemClock.elapsedRealtime() : mTimePeriodEndRealtime)
+                        - mTimePeriodStartRealtime, pw);
+        boolean partial = true;
+        if ((mFlags&FLAG_SHUTDOWN) != 0) {
+            pw.print(" (shutdown)");
+            partial = false;
+        }
+        if ((mFlags&FLAG_SYSPROPS) != 0) {
+            pw.print(" (sysprops)");
+            partial = false;
+        }
+        if ((mFlags&FLAG_COMPLETE) != 0) {
+            pw.print(" (complete)");
+            partial = false;
+        }
+        if (partial) {
+            pw.print(" (partial)");
+        }
+        pw.print(' ');
+        pw.print(mRuntime);
+        pw.print(' ');
+        pw.print(mWebView);
+        pw.println();
+    }
+
+    void dumpFilteredSummaryLocked(PrintWriter pw, String header, String prefix,
+            int[] screenStates, int[] memStates, int[] procStates, long now, long totalTime,
+            String reqPackage) {
+        ArrayList<ProcessState> procs = collectProcessesLocked(screenStates, memStates,
+                procStates, now, reqPackage);
+        if (procs.size() > 0) {
+            if (header != null) {
+                pw.println();
+                pw.println(header);
+            }
+            dumpProcessSummaryLocked(pw, prefix, procs, screenStates, memStates, procStates,
+                    now, totalTime);
+        }
+    }
+
+    public ArrayList<ProcessState> collectProcessesLocked(int[] screenStates, int[] memStates,
+            int[] procStates, long now, String reqPackage) {
+        ArraySet<ProcessState> foundProcs = new ArraySet<ProcessState>();
+        ArrayMap<String, SparseArray<PackageState>> pkgMap = mPackages.getMap();
+        for (int ip=0; ip<pkgMap.size(); ip++) {
+            if (reqPackage != null && !reqPackage.equals(pkgMap.keyAt(ip))) {
+                continue;
+            }
+            SparseArray<PackageState> procs = pkgMap.valueAt(ip);
+            for (int iu=0; iu<procs.size(); iu++) {
+                PackageState state = procs.valueAt(iu);
+                for (int iproc=0; iproc<state.mProcesses.size(); iproc++) {
+                    ProcessState proc = state.mProcesses.valueAt(iproc);
+                    foundProcs.add(proc.mCommonProcess);
+                }
+            }
+        }
+        ArrayList<ProcessState> outProcs = new ArrayList<ProcessState>(foundProcs.size());
+        for (int i=0; i<foundProcs.size(); i++) {
+            ProcessState proc = foundProcs.valueAt(i);
+            if (computeProcessTimeLocked(proc, screenStates, memStates,
+                    procStates, now) > 0) {
+                outProcs.add(proc);
+            }
+        }
+        Collections.sort(outProcs, new Comparator<ProcessState>() {
+            @Override
+            public int compare(ProcessState lhs, ProcessState rhs) {
+                if (lhs.mTmpTotalTime < rhs.mTmpTotalTime) {
+                    return -1;
+                } else if (lhs.mTmpTotalTime > rhs.mTmpTotalTime) {
+                    return 1;
+                }
+                return 0;
+            }
+        });
+        return outProcs;
+    }
+
+    String collapseString(String pkgName, String itemName) {
+        if (itemName.startsWith(pkgName)) {
+            final int ITEMLEN = itemName.length();
+            final int PKGLEN = pkgName.length();
+            if (ITEMLEN == PKGLEN) {
+                return "";
+            } else if (ITEMLEN >= PKGLEN) {
+                if (itemName.charAt(PKGLEN) == '.') {
+                    return itemName.substring(PKGLEN);
+                }
+            }
+        }
+        return itemName;
+    }
+
+    public void dumpCheckinLocked(PrintWriter pw, String reqPackage) {
+        final long now = SystemClock.uptimeMillis();
+        ArrayMap<String, SparseArray<PackageState>> pkgMap = mPackages.getMap();
+        pw.println("vers,3");
+        pw.print("period,"); pw.print(mTimePeriodStartClockStr);
+        pw.print(","); pw.print(mTimePeriodStartRealtime); pw.print(",");
+        pw.print(mRunning ? SystemClock.elapsedRealtime() : mTimePeriodEndRealtime);
+        boolean partial = true;
+        if ((mFlags&FLAG_SHUTDOWN) != 0) {
+            pw.print(",shutdown");
+            partial = false;
+        }
+        if ((mFlags&FLAG_SYSPROPS) != 0) {
+            pw.print(",sysprops");
+            partial = false;
+        }
+        if ((mFlags&FLAG_COMPLETE) != 0) {
+            pw.print(",complete");
+            partial = false;
+        }
+        if (partial) {
+            pw.print(",partial");
+        }
+        pw.println();
+        pw.print("config,"); pw.print(mRuntime); pw.print(','); pw.println(mWebView);
+        for (int ip=0; ip<pkgMap.size(); ip++) {
+            String pkgName = pkgMap.keyAt(ip);
+            if (reqPackage != null && !reqPackage.equals(pkgName)) {
+                continue;
+            }
+            SparseArray<PackageState> uids = pkgMap.valueAt(ip);
+            for (int iu=0; iu<uids.size(); iu++) {
+                int uid = uids.keyAt(iu);
+                PackageState pkgState = uids.valueAt(iu);
+                final int NPROCS = pkgState.mProcesses.size();
+                final int NSRVS = pkgState.mServices.size();
+                for (int iproc=0; iproc<NPROCS; iproc++) {
+                    ProcessState proc = pkgState.mProcesses.valueAt(iproc);
+                    pw.print("pkgproc,");
+                    pw.print(pkgName);
+                    pw.print(",");
+                    pw.print(uid);
+                    pw.print(",");
+                    pw.print(collapseString(pkgName, pkgState.mProcesses.keyAt(iproc)));
+                    dumpAllProcessStateCheckin(pw, proc, now);
+                    pw.println();
+                    if (proc.mPssTableSize > 0) {
+                        pw.print("pkgpss,");
+                        pw.print(pkgName);
+                        pw.print(",");
+                        pw.print(uid);
+                        pw.print(",");
+                        pw.print(collapseString(pkgName, pkgState.mProcesses.keyAt(iproc)));
+                        dumpAllProcessPssCheckin(pw, proc);
+                        pw.println();
+                    }
+                    if (proc.mNumExcessiveWake > 0 || proc.mNumExcessiveCpu > 0) {
+                        pw.print("pkgkills,");
+                        pw.print(pkgName);
+                        pw.print(",");
+                        pw.print(uid);
+                        pw.print(",");
+                        pw.print(collapseString(pkgName, pkgState.mProcesses.keyAt(iproc)));
+                        pw.print(",");
+                        pw.print(proc.mNumExcessiveWake);
+                        pw.print(",");
+                        pw.print(proc.mNumExcessiveCpu);
+                        pw.println();
+                    }
+                }
+                for (int isvc=0; isvc<NSRVS; isvc++) {
+                    String serviceName = collapseString(pkgName,
+                            pkgState.mServices.keyAt(isvc));
+                    ServiceState svc = pkgState.mServices.valueAt(isvc);
+                    dumpServiceTimeCheckin(pw, "pkgsvc-run", pkgName, uid, serviceName,
+                            svc, ServiceState.SERVICE_RUN, svc.mRunCount,
+                            svc.mRunState, svc.mRunStartTime, now);
+                    dumpServiceTimeCheckin(pw, "pkgsvc-start", pkgName, uid, serviceName,
+                            svc, ServiceState.SERVICE_STARTED, svc.mStartedCount,
+                            svc.mStartedState, svc.mStartedStartTime, now);
+                    dumpServiceTimeCheckin(pw, "pkgsvc-bound", pkgName, uid, serviceName,
+                            svc, ServiceState.SERVICE_BOUND, svc.mBoundCount,
+                            svc.mBoundState, svc.mBoundStartTime, now);
+                    dumpServiceTimeCheckin(pw, "pkgsvc-exec", pkgName, uid, serviceName,
+                            svc, ServiceState.SERVICE_EXEC, svc.mExecCount,
+                            svc.mExecState, svc.mExecStartTime, now);
+                }
+            }
+        }
+
+        ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
+        for (int ip=0; ip<procMap.size(); ip++) {
+            String procName = procMap.keyAt(ip);
+            SparseArray<ProcessState> uids = procMap.valueAt(ip);
+            for (int iu=0; iu<uids.size(); iu++) {
+                int uid = uids.keyAt(iu);
+                ProcessState procState = uids.valueAt(iu);
+                if (procState.mDurationsTableSize > 0) {
+                    pw.print("proc,");
+                    pw.print(procName);
+                    pw.print(",");
+                    pw.print(uid);
+                    dumpAllProcessStateCheckin(pw, procState, now);
+                    pw.println();
+                }
+                if (procState.mPssTableSize > 0) {
+                    pw.print("pss,");
+                    pw.print(procName);
+                    pw.print(",");
+                    pw.print(uid);
+                    dumpAllProcessPssCheckin(pw, procState);
+                    pw.println();
+                }
+                if (procState.mNumExcessiveWake > 0 || procState.mNumExcessiveCpu > 0) {
+                    pw.print("kills,");
+                    pw.print(procName);
+                    pw.print(",");
+                    pw.print(uid);
+                    pw.print(",");
+                    pw.print(procState.mNumExcessiveWake);
+                    pw.print(",");
+                    pw.print(procState.mNumExcessiveCpu);
+                    pw.println();
+                }
+            }
+        }
+        pw.print("total");
+        dumpAdjTimesCheckin(pw, ",", mMemFactorDurations, mMemFactor,
+                mStartTime, now);
+        pw.println();
+    }
+
+    public static final class ProcessState {
+        public final ProcessStats mStats;
+        public final ProcessState mCommonProcess;
+        public final String mPackage;
+        public final int mUid;
+        public final String mName;
+
+        int[] mDurationsTable;
+        int mDurationsTableSize;
+
+        //final long[] mDurations = new long[STATE_COUNT*ADJ_COUNT];
+        int mCurState = STATE_NOTHING;
+        long mStartTime;
+
+        int mLastPssState = STATE_NOTHING;
+        long mLastPssTime;
+        int[] mPssTable;
+        int mPssTableSize;
+
+        boolean mActive;
+        int mNumActiveServices;
+        int mNumStartedServices;
+
+        int mNumExcessiveWake;
+        int mNumExcessiveCpu;
+
+        boolean mMultiPackage;
+
+        public long mTmpTotalTime;
+
+        /**
+         * Create a new top-level process state, for the initial case where there is only
+         * a single package running in a process.  The initial state is not running.
+         */
+        public ProcessState(ProcessStats processStats, String pkg, int uid, String name) {
+            mStats = processStats;
+            mCommonProcess = this;
+            mPackage = pkg;
+            mUid = uid;
+            mName = name;
+        }
+
+        /**
+         * Create a new per-package process state for an existing top-level process
+         * state.  The current running state of the top-level process is also copied,
+         * marked as started running at 'now'.
+         */
+        public ProcessState(ProcessState commonProcess, String pkg, int uid, String name,
+                long now) {
+            mStats = commonProcess.mStats;
+            mCommonProcess = commonProcess;
+            mPackage = pkg;
+            mUid = uid;
+            mName = name;
+            mCurState = commonProcess.mCurState;
+            mStartTime = now;
+        }
+
+        ProcessState clone(String pkg, long now) {
+            ProcessState pnew = new ProcessState(this, pkg, mUid, mName, now);
+            if (mDurationsTable != null) {
+                mStats.mAddLongTable = new int[mDurationsTable.length];
+                mStats.mAddLongTableSize = 0;
+                for (int i=0; i<mDurationsTableSize; i++) {
+                    int origEnt = mDurationsTable[i];
+                    int type = (origEnt>>OFFSET_TYPE_SHIFT)&OFFSET_TYPE_MASK;
+                    int newOff = mStats.addLongData(i, type, 1);
+                    mStats.mAddLongTable[i] = newOff | type;
+                    mStats.setLong(newOff, 0, mStats.getLong(origEnt, 0));
+                }
+                pnew.mDurationsTable = mStats.mAddLongTable;
+                pnew.mDurationsTableSize = mStats.mAddLongTableSize;
+            }
+            if (mPssTable != null) {
+                mStats.mAddLongTable = new int[mPssTable.length];
+                mStats.mAddLongTableSize = 0;
+                for (int i=0; i<mPssTableSize; i++) {
+                    int origEnt = mPssTable[i];
+                    int type = (origEnt>>OFFSET_TYPE_SHIFT)&OFFSET_TYPE_MASK;
+                    int newOff = mStats.addLongData(i, type, PSS_COUNT);
+                    mStats.mAddLongTable[i] = newOff | type;
+                    for (int j=0; j<PSS_COUNT; j++) {
+                        mStats.setLong(newOff, j, mStats.getLong(origEnt, j));
+                    }
+                }
+                pnew.mPssTable = mStats.mAddLongTable;
+                pnew.mPssTableSize = mStats.mAddLongTableSize;
+            }
+            pnew.mNumExcessiveWake = mNumExcessiveWake;
+            pnew.mNumExcessiveCpu = mNumExcessiveCpu;
+            pnew.mActive = mActive;
+            pnew.mNumStartedServices = mNumStartedServices;
+            return pnew;
+        }
+
+        void add(ProcessState other) {
+            for (int i=0; i<other.mDurationsTableSize; i++) {
+                int ent = other.mDurationsTable[i];
+                int state = (ent>>OFFSET_TYPE_SHIFT)&OFFSET_TYPE_MASK;
+                if (DEBUG) Slog.d(TAG, "Adding state " + state + " duration "
+                        + other.mStats.getLong(ent, 0));
+                addDuration(state, other.mStats.getLong(ent, 0));
+            }
+            for (int i=0; i<other.mPssTableSize; i++) {
+                int ent = other.mPssTable[i];
+                int state = (ent>>OFFSET_TYPE_SHIFT)&OFFSET_TYPE_MASK;
+                addPss(state, (int) other.mStats.getLong(ent, PSS_SAMPLE_COUNT),
+                        other.mStats.getLong(ent, PSS_MINIMUM),
+                        other.mStats.getLong(ent, PSS_AVERAGE),
+                        other.mStats.getLong(ent, PSS_MAXIMUM),
+                        other.mStats.getLong(ent, PSS_USS_MINIMUM),
+                        other.mStats.getLong(ent, PSS_USS_AVERAGE),
+                        other.mStats.getLong(ent, PSS_USS_MAXIMUM));
+            }
+            mNumExcessiveWake += other.mNumExcessiveWake;
+            mNumExcessiveCpu += other.mNumExcessiveCpu;
+        }
+
+        void resetSafely(long now) {
+            mDurationsTable = null;
+            mDurationsTableSize = 0;
+            mStartTime = now;
+            mLastPssState = STATE_NOTHING;
+            mLastPssTime = 0;
+            mPssTable = null;
+            mPssTableSize = 0;
+            mNumExcessiveWake = 0;
+            mNumExcessiveCpu = 0;
+        }
+
+        void writeToParcel(Parcel out, long now) {
+            out.writeInt(mMultiPackage ? 1 : 0);
+            out.writeInt(mDurationsTableSize);
+            for (int i=0; i<mDurationsTableSize; i++) {
+                if (DEBUG) Slog.i(TAG, "Writing in " + mName + " dur #" + i + ": "
+                        + printLongOffset(mDurationsTable[i]));
+                out.writeInt(mDurationsTable[i]);
+            }
+            out.writeInt(mPssTableSize);
+            for (int i=0; i<mPssTableSize; i++) {
+                if (DEBUG) Slog.i(TAG, "Writing in " + mName + " pss #" + i + ": "
+                        + printLongOffset(mPssTable[i]));
+                out.writeInt(mPssTable[i]);
+            }
+            out.writeInt(mNumExcessiveWake);
+            out.writeInt(mNumExcessiveCpu);
+        }
+
+        boolean readFromParcel(Parcel in, boolean fully) {
+            boolean multiPackage = in.readInt() != 0;
+            if (fully) {
+                mMultiPackage = multiPackage;
+            }
+            if (DEBUG) Slog.d(TAG, "Reading durations table...");
+            mDurationsTable = mStats.readTableFromParcel(in, mName, "durations");
+            if (mDurationsTable == BAD_TABLE) {
+                return false;
+            }
+            mDurationsTableSize = mDurationsTable != null ? mDurationsTable.length : 0;
+            if (DEBUG) Slog.d(TAG, "Reading pss table...");
+            mPssTable = mStats.readTableFromParcel(in, mName, "pss");
+            if (mPssTable == BAD_TABLE) {
+                return false;
+            }
+            mPssTableSize = mPssTable != null ? mPssTable.length : 0;
+            mNumExcessiveWake = in.readInt();
+            mNumExcessiveCpu = in.readInt();
+            return true;
+        }
+
+        public void makeActive() {
+            mActive = true;
+        }
+
+        public void makeInactive() {
+            mActive = false;
+        }
+
+        public boolean isInUse() {
+            return mActive || mNumActiveServices > 0 || mNumStartedServices > 0;
+        }
+
+        /**
+         * Update the current state of the given list of processes.
+         *
+         * @param state Current ActivityManager.PROCESS_STATE_*
+         * @param memFactor Current mem factor constant.
+         * @param now Current time.
+         * @param pkgList Processes to update.
+         */
+        public void setState(int state, int memFactor, long now,
+                ArrayMap<String, ProcessState> pkgList) {
+            if (state < 0) {
+                state = mNumStartedServices > 0
+                        ? (STATE_SERVICE_RESTARTING+(memFactor*STATE_COUNT)) : STATE_NOTHING;
+            } else {
+                state = PROCESS_STATE_TO_STATE[state] + (memFactor*STATE_COUNT);
+            }
+
+            // First update the common process.
+            mCommonProcess.setState(state, now);
+
+            // If the common process is not multi-package, there is nothing else to do.
+            if (!mCommonProcess.mMultiPackage) {
+                return;
+            }
+
+            if (pkgList != null) {
+                for (int ip=pkgList.size()-1; ip>=0; ip--) {
+                    pullFixedProc(pkgList, ip).setState(state, now);
+                }
+            }
+        }
+
+        void setState(int state, long now) {
+            if (mCurState != state) {
+                //Slog.i(TAG, "Setting state in " + mName + "/" + mPackage + ": " + state);
+                commitStateTime(now);
+                mCurState = state;
+            }
+        }
+
+        void commitStateTime(long now) {
+            if (mCurState != STATE_NOTHING) {
+                long dur = now - mStartTime;
+                if (dur > 0) {
+                    addDuration(mCurState, dur);
+                }
+            }
+            mStartTime = now;
+        }
+
+        void addDuration(int state, long dur) {
+            int idx = binarySearch(mDurationsTable, mDurationsTableSize, state);
+            int off;
+            if (idx >= 0) {
+                off = mDurationsTable[idx];
+            } else {
+                mStats.mAddLongTable = mDurationsTable;
+                mStats.mAddLongTableSize = mDurationsTableSize;
+                off = mStats.addLongData(~idx, state, 1);
+                mDurationsTable = mStats.mAddLongTable;
+                mDurationsTableSize = mStats.mAddLongTableSize;
+            }
+            long[] longs = mStats.mLongs.get((off>>OFFSET_ARRAY_SHIFT)&OFFSET_ARRAY_MASK);
+            if (DEBUG) Slog.d(TAG, "Duration of " + mName + " state " + state + " inc by " + dur
+                    + " from " + longs[(off>>OFFSET_INDEX_SHIFT)&OFFSET_INDEX_MASK]);
+            longs[(off>>OFFSET_INDEX_SHIFT)&OFFSET_INDEX_MASK] += dur;
+        }
+
+        void incActiveServices() {
+            if (mCommonProcess != this) {
+                mCommonProcess.incActiveServices();
+            }
+            mNumActiveServices++;
+        }
+
+        void decActiveServices() {
+            if (mCommonProcess != this) {
+                mCommonProcess.decActiveServices();
+            }
+            mNumActiveServices--;
+            if (mNumActiveServices < 0) {
+                throw new IllegalStateException("Proc active services underrun: pkg="
+                        + mPackage + " uid=" + mUid + " name=" + mName);
+            }
+        }
+
+        void incStartedServices(int memFactor, long now) {
+            if (mCommonProcess != this) {
+                mCommonProcess.incStartedServices(memFactor, now);
+            }
+            mNumStartedServices++;
+            if (mNumStartedServices == 1 && mCurState == STATE_NOTHING) {
+                setState(STATE_NOTHING, memFactor, now, null);
+            }
+        }
+
+        void decStartedServices(int memFactor, long now) {
+            if (mCommonProcess != this) {
+                mCommonProcess.decStartedServices(memFactor, now);
+            }
+            mNumStartedServices--;
+            if (mNumStartedServices == 0 && mCurState == STATE_SERVICE_RESTARTING) {
+                setState(STATE_NOTHING, memFactor, now, null);
+            } else if (mNumStartedServices < 0) {
+                throw new IllegalStateException("Proc started services underrun: pkg="
+                        + mPackage + " uid=" + mUid + " name=" + mName);
+            }
+        }
+
+        public void addPss(long pss, long uss, boolean always) {
+            if (!always) {
+                if (mLastPssState == mCurState && SystemClock.uptimeMillis()
+                        < (mLastPssTime+(30*1000))) {
+                    return;
+                }
+            }
+            mLastPssState = mCurState;
+            mLastPssTime = SystemClock.uptimeMillis();
+            if (mCurState != STATE_NOTHING) {
+                addPss(mCurState, 1, pss, pss, pss, uss, uss, uss);
+            }
+        }
+
+        void addPss(int state, int inCount, long minPss, long avgPss, long maxPss, long minUss,
+                long avgUss, long maxUss) {
+            int idx = binarySearch(mPssTable, mPssTableSize, state);
+            int off;
+            if (idx >= 0) {
+                off = mPssTable[idx];
+            } else {
+                mStats.mAddLongTable = mPssTable;
+                mStats.mAddLongTableSize = mPssTableSize;
+                off = mStats.addLongData(~idx, state, PSS_COUNT);
+                mPssTable = mStats.mAddLongTable;
+                mPssTableSize = mStats.mAddLongTableSize;
+            }
+            long[] longs = mStats.mLongs.get((off>>OFFSET_ARRAY_SHIFT)&OFFSET_ARRAY_MASK);
+            idx = (off>>OFFSET_INDEX_SHIFT)&OFFSET_INDEX_MASK;
+            long count = longs[idx+PSS_SAMPLE_COUNT];
+            if (count == 0) {
+                longs[idx+PSS_SAMPLE_COUNT] = inCount;
+                longs[idx+PSS_MINIMUM] = minPss;
+                longs[idx+PSS_AVERAGE] = avgPss;
+                longs[idx+PSS_MAXIMUM] = maxPss;
+                longs[idx+PSS_USS_MINIMUM] = minUss;
+                longs[idx+PSS_USS_AVERAGE] = avgUss;
+                longs[idx+PSS_USS_MAXIMUM] = maxUss;
+            } else {
+                longs[idx+PSS_SAMPLE_COUNT] = count+inCount;
+                if (longs[idx+PSS_MINIMUM] > minPss) {
+                    longs[idx+PSS_MINIMUM] = minPss;
+                }
+                longs[idx+PSS_AVERAGE] = (long)(
+                        ((longs[idx+PSS_AVERAGE]*(double)count)+(avgPss*(double)inCount))
+                                / (count+inCount) );
+                if (longs[idx+PSS_MAXIMUM] < maxPss) {
+                    longs[idx+PSS_MAXIMUM] = maxPss;
+                }
+                if (longs[idx+PSS_USS_MINIMUM] > minUss) {
+                    longs[idx+PSS_USS_MINIMUM] = minUss;
+                }
+                longs[idx+PSS_USS_AVERAGE] = (long)(
+                        ((longs[idx+PSS_USS_AVERAGE]*(double)count)+(avgUss*(double)inCount))
+                                / (count+inCount) );
+                if (longs[idx+PSS_USS_MAXIMUM] < maxUss) {
+                    longs[idx+PSS_USS_MAXIMUM] = maxUss;
+                }
+            }
+        }
+
+        public void reportExcessiveWake(ArrayMap<String, ProcessState> pkgList) {
+            mCommonProcess.mNumExcessiveWake++;
+            if (!mCommonProcess.mMultiPackage) {
+                return;
+            }
+
+            for (int ip=pkgList.size()-1; ip>=0; ip--) {
+                pullFixedProc(pkgList, ip).mNumExcessiveWake++;
+            }
+        }
+
+        public void reportExcessiveCpu(ArrayMap<String, ProcessState> pkgList) {
+            mCommonProcess.mNumExcessiveCpu++;
+            if (!mCommonProcess.mMultiPackage) {
+                return;
+            }
+
+            for (int ip=pkgList.size()-1; ip>=0; ip--) {
+                pullFixedProc(pkgList, ip).mNumExcessiveCpu++;
+            }
+        }
+
+        ProcessState pullFixedProc(String pkgName) {
+            if (mMultiPackage) {
+                // The array map is still pointing to a common process state
+                // that is now shared across packages.  Update it to point to
+                // the new per-package state.
+                ProcessState proc = mStats.mPackages.get(pkgName,
+                        mUid).mProcesses.get(mName);
+                if (proc == null) {
+                    throw new IllegalStateException("Didn't create per-package process");
+                }
+                return proc;
+            }
+            return this;
+        }
+
+        private ProcessState pullFixedProc(ArrayMap<String, ProcessState> pkgList,
+                int index) {
+            ProcessState proc = pkgList.valueAt(index);
+            if (proc.mMultiPackage) {
+                // The array map is still pointing to a common process state
+                // that is now shared across packages.  Update it to point to
+                // the new per-package state.
+                PackageState pkg = mStats.mPackages.get(pkgList.keyAt(index), proc.mUid);
+                if (pkg == null) {
+                    throw new IllegalStateException("No existing package "
+                            + pkgList.keyAt(index) + " for multi-proc" + proc.mName);
+                }
+                proc = pkg.mProcesses.get(proc.mName);
+                if (proc == null) {
+                    throw new IllegalStateException("Didn't create per-package process");
+                }
+                pkgList.setValueAt(index, proc);
+            }
+            return proc;
+        }
+
+        long getDuration(int state, long now) {
+            int idx = binarySearch(mDurationsTable, mDurationsTableSize, state);
+            long time = idx >= 0 ? mStats.getLong(mDurationsTable[idx], 0) : 0;
+            if (mCurState == state) {
+                time += now - mStartTime;
+            }
+            return time;
+        }
+
+        long getPssSampleCount(int state) {
+            int idx = binarySearch(mPssTable, mPssTableSize, state);
+            return idx >= 0 ? mStats.getLong(mPssTable[idx], PSS_SAMPLE_COUNT) : 0;
+        }
+
+        long getPssMinimum(int state) {
+            int idx = binarySearch(mPssTable, mPssTableSize, state);
+            return idx >= 0 ? mStats.getLong(mPssTable[idx], PSS_MINIMUM) : 0;
+        }
+
+        long getPssAverage(int state) {
+            int idx = binarySearch(mPssTable, mPssTableSize, state);
+            return idx >= 0 ? mStats.getLong(mPssTable[idx], PSS_AVERAGE) : 0;
+        }
+
+        long getPssMaximum(int state) {
+            int idx = binarySearch(mPssTable, mPssTableSize, state);
+            return idx >= 0 ? mStats.getLong(mPssTable[idx], PSS_MAXIMUM) : 0;
+        }
+
+        long getPssUssMinimum(int state) {
+            int idx = binarySearch(mPssTable, mPssTableSize, state);
+            return idx >= 0 ? mStats.getLong(mPssTable[idx], PSS_USS_MINIMUM) : 0;
+        }
+
+        long getPssUssAverage(int state) {
+            int idx = binarySearch(mPssTable, mPssTableSize, state);
+            return idx >= 0 ? mStats.getLong(mPssTable[idx], PSS_USS_AVERAGE) : 0;
+        }
+
+        long getPssUssMaximum(int state) {
+            int idx = binarySearch(mPssTable, mPssTableSize, state);
+            return idx >= 0 ? mStats.getLong(mPssTable[idx], PSS_USS_MAXIMUM) : 0;
+        }
+    }
+
+    public static final class ServiceState {
+        final ProcessStats mStats;
+        public final String mPackage;
+        public final String mName;
+        public final String mProcessName;
+        ProcessState mProc;
+
+        int mActive = 0;
+
+        public static final int SERVICE_RUN = 0;
+        public static final int SERVICE_STARTED = 1;
+        public static final int SERVICE_BOUND = 2;
+        public static final int SERVICE_EXEC = 3;
+        static final int SERVICE_COUNT = 4;
+
+        int[] mDurationsTable;
+        int mDurationsTableSize;
+
+        int mRunCount;
+        public int mRunState = STATE_NOTHING;
+        long mRunStartTime;
+
+        int mStartedCount;
+        public int mStartedState = STATE_NOTHING;
+        long mStartedStartTime;
+
+        int mBoundCount;
+        public int mBoundState = STATE_NOTHING;
+        long mBoundStartTime;
+
+        int mExecCount;
+        public int mExecState = STATE_NOTHING;
+        long mExecStartTime;
+
+        public ServiceState(ProcessStats processStats, String pkg, String name,
+                String processName, ProcessState proc) {
+            mStats = processStats;
+            mPackage = pkg;
+            mName = name;
+            mProcessName = processName;
+            mProc = proc;
+        }
+
+        public void makeActive() {
+            if (mActive == 0) {
+                mProc.incActiveServices();
+            }
+            mActive++;
+        }
+
+        public void makeInactive() {
+            /*
+            RuntimeException here = new RuntimeException("here");
+            here.fillInStackTrace();
+            Slog.i(TAG, "Making " + this + " inactive", here);
+            */
+            mActive--;
+            if (mActive == 0) {
+                mProc.decActiveServices();
+            }
+        }
+
+        public boolean isInUse() {
+            return mActive > 0;
+        }
+
+        void add(ServiceState other) {
+            for (int i=0; i<other.mDurationsTableSize; i++) {
+                int ent = other.mDurationsTable[i];
+                int state = (ent>>OFFSET_TYPE_SHIFT)&OFFSET_TYPE_MASK;
+                addStateTime(state, other.mStats.getLong(ent, 0));
+            }
+            mRunCount += other.mRunCount;
+            mStartedCount += other.mStartedCount;
+            mBoundCount += other.mBoundCount;
+            mExecCount += other.mExecCount;
+        }
+
+        void resetSafely(long now) {
+            mDurationsTable = null;
+            mDurationsTableSize = 0;
+            mRunCount = mRunState != STATE_NOTHING ? 1 : 0;
+            mStartedCount = mStartedState != STATE_NOTHING ? 1 : 0;
+            mBoundCount = mBoundState != STATE_NOTHING ? 1 : 0;
+            mExecCount = mExecState != STATE_NOTHING ? 1 : 0;
+            mStartedStartTime = mBoundStartTime = mExecStartTime = now;
+        }
+
+        void writeToParcel(Parcel out, long now) {
+            out.writeInt(mDurationsTableSize);
+            for (int i=0; i<mDurationsTableSize; i++) {
+                if (DEBUG) Slog.i(TAG, "Writing service in " + mPackage + " dur #" + i + ": "
+                        + printLongOffset(mDurationsTable[i]));
+                out.writeInt(mDurationsTable[i]);
+            }
+            out.writeInt(mRunCount);
+            out.writeInt(mStartedCount);
+            out.writeInt(mBoundCount);
+            out.writeInt(mExecCount);
+        }
+
+        boolean readFromParcel(Parcel in) {
+            if (DEBUG) Slog.d(TAG, "Reading durations table...");
+            mDurationsTable = mStats.readTableFromParcel(in, mPackage, "service");
+            if (mDurationsTable == BAD_TABLE) {
+                return false;
+            }
+            mDurationsTableSize = mDurationsTable != null ? mDurationsTable.length : 0;
+            mRunCount = in.readInt();
+            mStartedCount = in.readInt();
+            mBoundCount = in.readInt();
+            mExecCount = in.readInt();
+            return true;
+        }
+
+        void addStateTime(int state, long time) {
+            if (time > 0) {
+                int idx = binarySearch(mDurationsTable, mDurationsTableSize, state);
+                int off;
+                if (idx >= 0) {
+                    off = mDurationsTable[idx];
+                } else {
+                    mStats.mAddLongTable = mDurationsTable;
+                    mStats.mAddLongTableSize = mDurationsTableSize;
+                    off = mStats.addLongData(~idx, state, 1);
+                    mDurationsTable = mStats.mAddLongTable;
+                    mDurationsTableSize = mStats.mAddLongTableSize;
+                }
+                long[] longs = mStats.mLongs.get((off>>OFFSET_ARRAY_SHIFT)&OFFSET_ARRAY_MASK);
+                longs[(off>>OFFSET_INDEX_SHIFT)&OFFSET_INDEX_MASK] += time;
+            }
+        }
+
+        void commitStateTime(long now) {
+            if (mRunState != STATE_NOTHING) {
+                addStateTime(SERVICE_RUN + (mRunState*SERVICE_COUNT), now - mRunStartTime);
+                mRunStartTime = now;
+            }
+            if (mStartedState != STATE_NOTHING) {
+                addStateTime(SERVICE_STARTED + (mStartedState*SERVICE_COUNT),
+                        now - mStartedStartTime);
+                mStartedStartTime = now;
+            }
+            if (mBoundState != STATE_NOTHING) {
+                addStateTime(SERVICE_BOUND + (mBoundState*SERVICE_COUNT), now - mBoundStartTime);
+                mBoundStartTime = now;
+            }
+            if (mExecState != STATE_NOTHING) {
+                addStateTime(SERVICE_EXEC + (mExecState*SERVICE_COUNT), now - mExecStartTime);
+                mExecStartTime = now;
+            }
+        }
+
+        private void updateRunning(int memFactor, long now) {
+            final int state = (mStartedState != STATE_NOTHING || mBoundState != STATE_NOTHING
+                    || mExecState != STATE_NOTHING) ? memFactor : STATE_NOTHING;
+            if (mRunState != state) {
+                if (mRunState != STATE_NOTHING) {
+                    addStateTime(SERVICE_RUN + (mRunState*SERVICE_COUNT),
+                            now - mRunStartTime);
+                } else if (state != STATE_NOTHING) {
+                    mRunCount++;
+                }
+                mRunState = state;
+                mRunStartTime = now;
+            }
+        }
+
+        public void setStarted(boolean started, int memFactor, long now) {
+            if (mActive <= 0) {
+                throw new IllegalStateException("Service " + this + " has mActive=" + mActive);
+            }
+            final boolean wasStarted = mStartedState != STATE_NOTHING;
+            final int state = started ? memFactor : STATE_NOTHING;
+            if (mStartedState != state) {
+                if (mStartedState != STATE_NOTHING) {
+                    addStateTime(SERVICE_STARTED + (mStartedState*SERVICE_COUNT),
+                            now - mStartedStartTime);
+                } else if (started) {
+                    mStartedCount++;
+                }
+                mStartedState = state;
+                mStartedStartTime = now;
+                mProc = mProc.pullFixedProc(mPackage);
+                if (wasStarted != started) {
+                    if (started) {
+                        mProc.incStartedServices(memFactor, now);
+                    } else {
+                        mProc.decStartedServices(memFactor, now);
+                    }
+                }
+                updateRunning(memFactor, now);
+            }
+        }
+
+        public void setBound(boolean bound, int memFactor, long now) {
+            if (mActive <= 0) {
+                throw new IllegalStateException("Service " + this + " has mActive=" + mActive);
+            }
+            final int state = bound ? memFactor : STATE_NOTHING;
+            if (mBoundState != state) {
+                if (mBoundState != STATE_NOTHING) {
+                    addStateTime(SERVICE_BOUND + (mBoundState*SERVICE_COUNT),
+                            now - mBoundStartTime);
+                } else if (bound) {
+                    mBoundCount++;
+                }
+                mBoundState = state;
+                mBoundStartTime = now;
+                updateRunning(memFactor, now);
+            }
+        }
+
+        public void setExecuting(boolean executing, int memFactor, long now) {
+            if (mActive <= 0) {
+                throw new IllegalStateException("Service " + this + " has mActive=" + mActive);
+            }
+            final int state = executing ? memFactor : STATE_NOTHING;
+            if (mExecState != state) {
+                if (mExecState != STATE_NOTHING) {
+                    addStateTime(SERVICE_EXEC + (mExecState*SERVICE_COUNT), now - mExecStartTime);
+                } else if (executing) {
+                    mExecCount++;
+                }
+                mExecState = state;
+                mExecStartTime = now;
+                updateRunning(memFactor, now);
+            }
+        }
+
+        private long getDuration(int opType, int curState, long startTime, int memFactor,
+                long now) {
+            int state = opType + (memFactor*SERVICE_COUNT);
+            int idx = binarySearch(mDurationsTable, mDurationsTableSize, state);
+            long time = idx >= 0 ? mStats.getLong(mDurationsTable[idx], 0) : 0;
+            if (curState == memFactor) {
+                time += now - startTime;
+            }
+            return time;
+        }
+    }
+
+    public static final class PackageState {
+        public final ArrayMap<String, ProcessState> mProcesses
+                = new ArrayMap<String, ProcessState>();
+        public final ArrayMap<String, ServiceState> mServices
+                = new ArrayMap<String, ServiceState>();
+        final int mUid;
+
+        public PackageState(int uid) {
+            mUid = uid;
+        }
+    }
+
+    public static final class ProcessDataCollection {
+        final int[] screenStates;
+        final int[] memStates;
+        final int[] procStates;
+
+        public long totalTime;
+        public long numPss;
+        public long minPss;
+        public long avgPss;
+        public long maxPss;
+        public long minUss;
+        public long avgUss;
+        public long maxUss;
+
+        public ProcessDataCollection(int[] _screenStates, int[] _memStates, int[] _procStates) {
+            screenStates = _screenStates;
+            memStates = _memStates;
+            procStates = _procStates;
+        }
+
+        void print(PrintWriter pw, long overallTime, boolean full) {
+            printPercent(pw, (double) totalTime / (double) overallTime);
+            if (numPss > 0) {
+                pw.print(" (");
+                printSizeValue(pw, minPss * 1024);
+                pw.print("-");
+                printSizeValue(pw, avgPss * 1024);
+                pw.print("-");
+                printSizeValue(pw, maxPss * 1024);
+                pw.print("/");
+                printSizeValue(pw, minUss * 1024);
+                pw.print("-");
+                printSizeValue(pw, avgUss * 1024);
+                pw.print("-");
+                printSizeValue(pw, maxUss * 1024);
+                if (full) {
+                    pw.print(" over ");
+                    pw.print(numPss);
+                }
+                pw.print(")");
+            }
+        }
+    }
+}
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index c22cd26..8819237 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -16,16 +16,19 @@
 
 package com.android.internal.app;
 
+import android.os.AsyncTask;
 import com.android.internal.R;
 import com.android.internal.content.PackageMonitor;
 
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
+import android.app.AppGlobals;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.ActivityInfo;
+import android.content.pm.IPackageManager;
 import android.content.pm.LabeledIntent;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -44,7 +47,6 @@
 import android.widget.AdapterView;
 import android.widget.BaseAdapter;
 import android.widget.Button;
-import android.widget.GridView;
 import android.widget.ImageView;
 import android.widget.ListView;
 import android.widget.TextView;
@@ -70,13 +72,13 @@
     private PackageManager mPm;
     private boolean mAlwaysUseOption;
     private boolean mShowExtended;
-    private GridView mGrid;
+    private ListView mListView;
     private Button mAlwaysButton;
     private Button mOnceButton;
     private int mIconDpi;
     private int mIconSize;
     private int mMaxColumns;
-    private int mLastSelected = GridView.INVALID_POSITION;
+    private int mLastSelected = ListView.INVALID_POSITION;
 
     private boolean mRegistered;
     private final PackageMonitor mPackageMonitor = new PackageMonitor() {
@@ -138,17 +140,15 @@
             finish();
             return;
         } else if (count > 1) {
-            ap.mView = getLayoutInflater().inflate(R.layout.resolver_grid, null);
-            mGrid = (GridView) ap.mView.findViewById(R.id.resolver_grid);
-            mGrid.setAdapter(mAdapter);
-            mGrid.setOnItemClickListener(this);
-            mGrid.setOnItemLongClickListener(new ItemLongClickListener());
+            ap.mView = getLayoutInflater().inflate(R.layout.resolver_list, null);
+            mListView = (ListView) ap.mView.findViewById(R.id.resolver_list);
+            mListView.setAdapter(mAdapter);
+            mListView.setOnItemClickListener(this);
+            mListView.setOnItemLongClickListener(new ItemLongClickListener());
 
             if (alwaysUseOption) {
-                mGrid.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+                mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
             }
-
-            resizeGrid();
         } else if (count == 1) {
             startActivity(mAdapter.intentForPosition(0));
             mPackageMonitor.unregister();
@@ -171,11 +171,11 @@
                 mAlwaysUseOption = false;
             }
         }
-    }
-
-    void resizeGrid() {
-        final int itemCount = mAdapter.getCount();
-        mGrid.setNumColumns(Math.min(itemCount, mMaxColumns));
+        final int initialHighlight = mAdapter.getInitialHighlight();
+        if (initialHighlight >= 0) {
+            mListView.setItemChecked(initialHighlight, true);
+            onItemClick(null, null, initialHighlight, 0); // Other entries are not used
+        }
     }
 
     Drawable getIcon(Resources res, int resId) {
@@ -246,26 +246,26 @@
     protected void onRestoreInstanceState(Bundle savedInstanceState) {
         super.onRestoreInstanceState(savedInstanceState);
         if (mAlwaysUseOption) {
-            final int checkedPos = mGrid.getCheckedItemPosition();
-            final boolean enabled = checkedPos != GridView.INVALID_POSITION;
+            final int checkedPos = mListView.getCheckedItemPosition();
+            final boolean enabled = checkedPos != ListView.INVALID_POSITION;
             mLastSelected = checkedPos;
             mAlwaysButton.setEnabled(enabled);
             mOnceButton.setEnabled(enabled);
             if (enabled) {
-                mGrid.setSelection(checkedPos);
+                mListView.setSelection(checkedPos);
             }
         }
     }
 
     @Override
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-        final int checkedPos = mGrid.getCheckedItemPosition();
-        final boolean hasValidSelection = checkedPos != GridView.INVALID_POSITION;
+        final int checkedPos = mListView.getCheckedItemPosition();
+        final boolean hasValidSelection = checkedPos != ListView.INVALID_POSITION;
         if (mAlwaysUseOption && (!hasValidSelection || mLastSelected != checkedPos)) {
             mAlwaysButton.setEnabled(hasValidSelection);
             mOnceButton.setEnabled(hasValidSelection);
             if (hasValidSelection) {
-                mGrid.smoothScrollToPosition(checkedPos);
+                mListView.smoothScrollToPosition(checkedPos);
             }
             mLastSelected = checkedPos;
         } else {
@@ -275,7 +275,7 @@
 
     public void onButtonClick(View v) {
         final int id = v.getId();
-        startSelected(mGrid.getCheckedItemPosition(), id == R.id.button_always);
+        startSelected(mListView.getCheckedItemPosition(), id == R.id.button_always);
         dismiss();
     }
 
@@ -287,7 +287,7 @@
     }
 
     protected void onIntentSelected(ResolveInfo ri, Intent intent, boolean alwaysCheck) {
-        if (alwaysCheck) {
+        if (mAlwaysUseOption) {
             // Build a reasonable intent filter, based on what matched.
             IntentFilter filter = new IntentFilter();
 
@@ -326,6 +326,17 @@
 
                     // Look through the resolved filter to determine which part
                     // of it matched the original Intent.
+                    Iterator<PatternMatcher> pIt = ri.filter.schemeSpecificPartsIterator();
+                    if (pIt != null) {
+                        String ssp = data.getSchemeSpecificPart();
+                        while (ssp != null && pIt.hasNext()) {
+                            PatternMatcher p = pIt.next();
+                            if (p.match(ssp)) {
+                                filter.addDataSchemeSpecificPart(p.getPath(), p.getType());
+                                break;
+                            }
+                        }
+                    }
                     Iterator<IntentFilter.AuthorityEntry> aIt = ri.filter.authoritiesIterator();
                     if (aIt != null) {
                         while (aIt.hasNext()) {
@@ -338,7 +349,7 @@
                             }
                         }
                     }
-                    Iterator<PatternMatcher> pIt = ri.filter.pathsIterator();
+                    pIt = ri.filter.pathsIterator();
                     if (pIt != null) {
                         String path = data.getPath();
                         while (path != null && pIt.hasNext()) {
@@ -362,8 +373,19 @@
                             r.activityInfo.name);
                     if (r.match > bestMatch) bestMatch = r.match;
                 }
-                getPackageManager().addPreferredActivity(filter, bestMatch, set,
-                        intent.getComponent());
+                if (alwaysCheck) {
+                    getPackageManager().addPreferredActivity(filter, bestMatch, set,
+                            intent.getComponent());
+                } else {
+                    try {
+                        AppGlobals.getPackageManager().setLastChosenActivity(intent,
+                                intent.resolveTypeIfNeeded(getContentResolver()),
+                                PackageManager.MATCH_DEFAULT_ONLY,
+                                filter, bestMatch, intent.getComponent());
+                    } catch (RemoteException re) {
+                        Log.d(TAG, "Error calling setLastChosenActivity\n" + re);
+                    }
+                }
             }
         }
 
@@ -398,11 +420,13 @@
     private final class ResolveListAdapter extends BaseAdapter {
         private final Intent[] mInitialIntents;
         private final List<ResolveInfo> mBaseResolveList;
+        private ResolveInfo mLastChosen;
         private final Intent mIntent;
         private final int mLaunchedFromUid;
         private final LayoutInflater mInflater;
 
         private List<DisplayResolveInfo> mList;
+        private int mInitialHighlight = -1;
 
         public ResolveListAdapter(Context context, Intent intent,
                 Intent[] initialIntents, List<ResolveInfo> rList, int launchedFromUid) {
@@ -424,14 +448,24 @@
             if (newItemCount == 0) {
                 // We no longer have any items...  just finish the activity.
                 finish();
-            } else if (newItemCount != oldItemCount) {
-                resizeGrid();
             }
         }
 
+        public int getInitialHighlight() {
+            return mInitialHighlight;
+        }
+
         private void rebuildList() {
             List<ResolveInfo> currentResolveList;
 
+            try {
+                mLastChosen = AppGlobals.getPackageManager().getLastChosenActivity(
+                        mIntent, mIntent.resolveTypeIfNeeded(getContentResolver()),
+                        PackageManager.MATCH_DEFAULT_ONLY);
+            } catch (RemoteException re) {
+                Log.d(TAG, "Error calling setLastChosenActivity\n" + re);
+            }
+
             mList.clear();
             if (mBaseResolveList != null) {
                 currentResolveList = mBaseResolveList;
@@ -544,6 +578,12 @@
             // Process labels from start to i
             int num = end - start+1;
             if (num == 1) {
+                if (mLastChosen != null
+                        && mLastChosen.activityInfo.packageName.equals(
+                                ro.activityInfo.packageName)
+                        && mLastChosen.activityInfo.name.equals(ro.activityInfo.name)) {
+                    mInitialHighlight = mList.size();
+                }
                 // No duplicate labels. Use label for entry at start
                 mList.add(new DisplayResolveInfo(ro, roLabel, null, null));
             } else {
@@ -573,6 +613,12 @@
                 }
                 for (int k = start; k <= end; k++) {
                     ResolveInfo add = rList.get(k);
+                    if (mLastChosen != null
+                            && mLastChosen.activityInfo.packageName.equals(
+                                    add.activityInfo.packageName)
+                            && mLastChosen.activityInfo.name.equals(add.activityInfo.name)) {
+                        mInitialHighlight = mList.size();
+                    }
                     if (usePkg) {
                         // Use application name for all entries from start to end-1
                         mList.add(new DisplayResolveInfo(add, roLabel,
@@ -621,9 +667,11 @@
                 view = mInflater.inflate(
                         com.android.internal.R.layout.resolve_list_item, parent, false);
 
+                final ViewHolder holder = new ViewHolder(view);
+                view.setTag(holder);
+
                 // Fix the icon size even if we have different sized resources
-                ImageView icon = (ImageView)view.findViewById(R.id.icon);
-                ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) icon.getLayoutParams();
+                ViewGroup.LayoutParams lp = holder.icon.getLayoutParams();
                 lp.width = lp.height = mIconSize;
             } else {
                 view = convertView;
@@ -633,20 +681,30 @@
         }
 
         private final void bindView(View view, DisplayResolveInfo info) {
-            TextView text = (TextView)view.findViewById(com.android.internal.R.id.text1);
-            TextView text2 = (TextView)view.findViewById(com.android.internal.R.id.text2);
-            ImageView icon = (ImageView)view.findViewById(R.id.icon);
-            text.setText(info.displayLabel);
+            final ViewHolder holder = (ViewHolder) view.getTag();
+            holder.text.setText(info.displayLabel);
             if (mShowExtended) {
-                text2.setVisibility(View.VISIBLE);
-                text2.setText(info.extendedInfo);
+                holder.text2.setVisibility(View.VISIBLE);
+                holder.text2.setText(info.extendedInfo);
             } else {
-                text2.setVisibility(View.GONE);
+                holder.text2.setVisibility(View.GONE);
             }
             if (info.displayIcon == null) {
-                info.displayIcon = loadIconForResolveInfo(info.ri);
+                new LoadIconTask().execute(info);
             }
-            icon.setImageDrawable(info.displayIcon);
+            holder.icon.setImageDrawable(info.displayIcon);
+        }
+    }
+
+    static class ViewHolder {
+        public TextView text;
+        public TextView text2;
+        public ImageView icon;
+
+        public ViewHolder(View view) {
+            text = (TextView) view.findViewById(com.android.internal.R.id.text1);
+            text2 = (TextView) view.findViewById(com.android.internal.R.id.text2);
+            icon = (ImageView) view.findViewById(R.id.icon);
         }
     }
 
@@ -660,5 +718,21 @@
         }
 
     }
+
+    class LoadIconTask extends AsyncTask<DisplayResolveInfo, Void, DisplayResolveInfo> {
+        @Override
+        protected DisplayResolveInfo doInBackground(DisplayResolveInfo... params) {
+            final DisplayResolveInfo info = params[0];
+            if (info.displayIcon == null) {
+                info.displayIcon = loadIconForResolveInfo(info.ri);
+            }
+            return info;
+        }
+
+        @Override
+        protected void onPostExecute(DisplayResolveInfo info) {
+            mAdapter.notifyDataSetChanged();
+        }
+    }
 }
 
diff --git a/core/java/com/android/internal/app/RestrictionsPinActivity.java b/core/java/com/android/internal/app/RestrictionsPinActivity.java
new file mode 100644
index 0000000..66585c6
--- /dev/null
+++ b/core/java/com/android/internal/app/RestrictionsPinActivity.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.os.UserManager;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.TextView.OnEditorActionListener;
+
+import com.android.internal.R;
+
+/**
+ * This activity is launched by Settings and other apps to either create a new PIN or
+ * challenge for an existing PIN. The PIN is maintained by UserManager.
+ */
+public class RestrictionsPinActivity extends AlertActivity
+        implements OnClickListener, TextWatcher, OnEditorActionListener {
+
+    protected UserManager mUserManager;
+    protected boolean mHasRestrictionsPin;
+
+    protected EditText mPinText;
+    protected TextView mPinErrorMessage;
+    private Button mOkButton;
+    private Button mCancelButton;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        mUserManager = (UserManager) getSystemService(Context.USER_SERVICE);
+        mHasRestrictionsPin = mUserManager.hasRestrictionsChallenge();
+        initUi();
+        setupAlert();
+    }
+
+    protected void initUi() {
+        AlertController.AlertParams ap = mAlertParams;
+        ap.mTitle = getString(R.string.restr_pin_enter_admin_pin);
+        LayoutInflater inflater =
+                (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        ap.mView = inflater.inflate(R.layout.restrictions_pin_challenge, null);
+
+        mPinErrorMessage = (TextView) ap.mView.findViewById(R.id.pin_error_message);
+        mPinText = (EditText) ap.mView.findViewById(R.id.pin_text);
+        mOkButton = (Button) ap.mView.findViewById(R.id.pin_ok_button);
+        mCancelButton = (Button) ap.mView.findViewById(R.id.pin_cancel_button);
+
+        mPinText.addTextChangedListener(this);
+
+        mOkButton.setOnClickListener(this);
+        mCancelButton.setOnClickListener(this);
+    }
+
+    protected boolean verifyingPin() {
+        return true;
+    }
+
+    public void onResume() {
+        super.onResume();
+
+        setPositiveButtonState(false);
+        boolean hasPin = mUserManager.hasRestrictionsChallenge();
+        if (hasPin) {
+            mPinErrorMessage.setVisibility(View.INVISIBLE);
+            mPinText.setOnEditorActionListener(this);
+            updatePinTimer(-1);
+        } else if (verifyingPin()) {
+            setResult(RESULT_OK);
+            finish();
+        }
+    }
+
+    protected void setPositiveButtonState(boolean enabled) {
+        mOkButton.setEnabled(enabled);
+    }
+
+    private boolean updatePinTimer(int pinTimerMs) {
+        if (pinTimerMs < 0) {
+            pinTimerMs = mUserManager.checkRestrictionsChallenge(null);
+        }
+        boolean enableInput;
+        if (pinTimerMs >= 200) {
+            // Do the count down timer for less than a minute, otherwise just say try again later.
+            if (pinTimerMs <= 60000) {
+                final int seconds = (pinTimerMs + 200) / 1000;
+                final String formatString = getResources().getQuantityString(
+                        R.plurals.restr_pin_countdown,
+                        seconds);
+                mPinErrorMessage.setText(String.format(formatString, seconds));
+            } else {
+                mPinErrorMessage.setText(R.string.restr_pin_try_later);
+            }
+            enableInput = false;
+            mPinErrorMessage.setVisibility(View.VISIBLE);
+            mPinText.setText("");
+            mPinText.postDelayed(mCountdownRunnable, Math.min(1000, pinTimerMs));
+        } else {
+            enableInput = true;
+            mPinErrorMessage.setText(R.string.restr_pin_incorrect);
+        }
+        mPinText.setEnabled(enableInput);
+        setPositiveButtonState(enableInput);
+        return enableInput;
+    }
+
+    protected void performPositiveButtonAction() {
+        int result = mUserManager.checkRestrictionsChallenge(mPinText.getText().toString());
+        if (result == UserManager.PIN_VERIFICATION_SUCCESS) {
+            setResult(RESULT_OK);
+            finish();
+        } else if (result >= 0) {
+            mPinErrorMessage.setText(R.string.restr_pin_incorrect);
+            mPinErrorMessage.setVisibility(View.VISIBLE);
+            updatePinTimer(result);
+            mPinText.setText("");
+        }
+    }
+
+    @Override
+    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+    }
+
+    @Override
+    public void onTextChanged(CharSequence s, int start, int before, int count) {
+        CharSequence pin = mPinText.getText();
+        setPositiveButtonState(pin != null && pin.length() >= 4);
+    }
+
+    @Override
+    public void afterTextChanged(Editable s) {
+    }
+
+    @Override
+    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+        performPositiveButtonAction();
+        return true;
+    }
+
+    private Runnable mCountdownRunnable = new Runnable() {
+        public void run() {
+            if (updatePinTimer(-1)) {
+                // If we are no longer counting down, clear the message.
+                mPinErrorMessage.setVisibility(View.INVISIBLE);
+            }
+        }
+    };
+
+    @Override
+    public void onClick(View v) {
+        if (v == mOkButton) {
+            performPositiveButtonAction();
+        } else if (v == mCancelButton) {
+            setResult(RESULT_CANCELED);
+            finish();
+        }
+    }
+}
diff --git a/core/java/com/android/internal/content/PackageMonitor.java b/core/java/com/android/internal/content/PackageMonitor.java
index 424c19b..ab871fb 100644
--- a/core/java/com/android/internal/content/PackageMonitor.java
+++ b/core/java/com/android/internal/content/PackageMonitor.java
@@ -25,6 +25,7 @@
 import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.UserHandle;
+import com.android.internal.os.BackgroundThread;
 
 import java.util.HashSet;
 
@@ -37,10 +38,6 @@
     static final IntentFilter sNonDataFilt = new IntentFilter();
     static final IntentFilter sExternalFilt = new IntentFilter();
 
-    static final Object sLock = new Object();
-    static HandlerThread sBackgroundThread;
-    static Handler sBackgroundHandler;
-
     static {
         sPackageFilt.addAction(Intent.ACTION_PACKAGE_ADDED);
         sPackageFilt.addAction(Intent.ACTION_PACKAGE_REMOVED);
@@ -79,15 +76,7 @@
         }
         mRegisteredContext = context;
         if (thread == null) {
-            synchronized (sLock) {
-                if (sBackgroundThread == null) {
-                    sBackgroundThread = new HandlerThread("PackageMonitor",
-                            android.os.Process.THREAD_PRIORITY_BACKGROUND);
-                    sBackgroundThread.start();
-                    sBackgroundHandler = new Handler(sBackgroundThread.getLooper());
-                }
-                mRegisteredHandler = sBackgroundHandler;
-            }
+            mRegisteredHandler = BackgroundThread.getHandler();
         } else {
             mRegisteredHandler = new Handler(thread);
         }
diff --git a/core/java/com/android/internal/inputmethod/InputMethodUtils.java b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
index 4e21324..63d018f 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodUtils.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
@@ -57,6 +57,45 @@
         // This utility class is not publicly instantiable.
     }
 
+    // ----------------------------------------------------------------------
+    // Utilities for debug
+    public static String getStackTrace() {
+        final StringBuilder sb = new StringBuilder();
+        try {
+            throw new RuntimeException();
+        } catch (RuntimeException e) {
+            final StackTraceElement[] frames = e.getStackTrace();
+            // Start at 1 because the first frame is here and we don't care about it
+            for (int j = 1; j < frames.length; ++j) {
+                sb.append(frames[j].toString() + "\n");
+            }
+        }
+        return sb.toString();
+    }
+
+    public static String getApiCallStack() {
+        String apiCallStack = "";
+        try {
+            throw new RuntimeException();
+        } catch (RuntimeException e) {
+            final StackTraceElement[] frames = e.getStackTrace();
+            for (int j = 1; j < frames.length; ++j) {
+                final String tempCallStack = frames[j].toString();
+                if (TextUtils.isEmpty(apiCallStack)) {
+                    // Overwrite apiCallStack if it's empty
+                    apiCallStack = tempCallStack;
+                } else if (tempCallStack.indexOf("Transact(") < 0) {
+                    // Overwrite apiCallStack if it's not a binder call
+                    apiCallStack = tempCallStack;
+                } else {
+                    break;
+                }
+            }
+        }
+        return apiCallStack;
+    }
+    // ----------------------------------------------------------------------
+
     public static boolean isSystemIme(InputMethodInfo inputMethod) {
         return (inputMethod.getServiceInfo().applicationInfo.flags
                 & ApplicationInfo.FLAG_SYSTEM) != 0;
@@ -142,7 +181,7 @@
                 || isSystemImeThatHasEnglishKeyboardSubtype(imi);
     }
 
-    private static boolean containsSubtypeOf(InputMethodInfo imi, String language, String mode) {
+    public static boolean containsSubtypeOf(InputMethodInfo imi, String language, String mode) {
         final int N = imi.getSubtypeCount();
         for (int i = 0; i < N; ++i) {
             if (!imi.getSubtypeAt(i).getLocale().startsWith(language)) {
@@ -432,6 +471,17 @@
         }
     }
 
+    public static CharSequence getImeAndSubtypeDisplayName(Context context, InputMethodInfo imi,
+            InputMethodSubtype subtype) {
+        final CharSequence imiLabel = imi.loadLabel(context.getPackageManager());
+        return subtype != null
+                ? TextUtils.concat(subtype.getDisplayName(context,
+                        imi.getPackageName(), imi.getServiceInfo().applicationInfo),
+                                (TextUtils.isEmpty(imiLabel) ?
+                                        "" : " - " + imiLabel))
+                : imiLabel;
+    }
+
     /**
      * Utility class for putting and getting settings for InputMethod
      * TODO: Move all putters and getters of settings to this class.
@@ -508,7 +558,7 @@
             return InputMethodSubtype.sort(context, 0, imi, enabledSubtypes);
         }
 
-        private List<InputMethodSubtype> getEnabledInputMethodSubtypeListLocked(
+        public List<InputMethodSubtype> getEnabledInputMethodSubtypeListLocked(
                 InputMethodInfo imi) {
             List<Pair<String, ArrayList<String>>> imsList =
                     getEnabledInputMethodsAndSubtypeListLocked();
diff --git a/core/java/com/android/internal/logging/AndroidHandler.java b/core/java/com/android/internal/logging/AndroidHandler.java
index 12f6a4f..f55a31f 100644
--- a/core/java/com/android/internal/logging/AndroidHandler.java
+++ b/core/java/com/android/internal/logging/AndroidHandler.java
@@ -17,6 +17,7 @@
 package com.android.internal.logging;
 
 import android.util.Log;
+import com.android.internal.util.FastPrintWriter;
 import dalvik.system.DalvikLogging;
 import dalvik.system.DalvikLogHandler;
 
@@ -91,7 +92,7 @@
             Throwable thrown = r.getThrown();
             if (thrown != null) {
                 StringWriter sw = new StringWriter();
-                PrintWriter pw = new PrintWriter(sw);
+                PrintWriter pw = new FastPrintWriter(sw, false, 256);
                 sw.write(r.getMessage());
                 sw.write("\n");
                 thrown.printStackTrace(pw);
diff --git a/core/java/com/android/internal/net/VpnConfig.java b/core/java/com/android/internal/net/VpnConfig.java
index 956653b..98599d0 100644
--- a/core/java/com/android/internal/net/VpnConfig.java
+++ b/core/java/com/android/internal/net/VpnConfig.java
@@ -21,10 +21,15 @@
 import android.content.Intent;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.UserHandle;
+import android.net.RouteInfo;
+import android.net.LinkAddress;
 
 import com.android.internal.util.Preconditions;
 
+import java.net.InetAddress;
 import java.util.List;
+import java.util.ArrayList;
 
 /**
  * A simple container used to carry information in VpnBuilder, VpnDialogs,
@@ -46,29 +51,54 @@
         return intent;
     }
 
-    public static PendingIntent getIntentForStatusPanel(Context context, VpnConfig config) {
-        Preconditions.checkNotNull(config);
-
+    public static PendingIntent getIntentForStatusPanel(Context context) {
         Intent intent = new Intent();
         intent.setClassName(DIALOGS_PACKAGE, DIALOGS_PACKAGE + ".ManageDialog");
-        intent.putExtra("config", config);
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY |
                 Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-        return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
+        return PendingIntent.getActivityAsUser(context, 0, intent, 0, null, UserHandle.CURRENT);
     }
 
     public String user;
     public String interfaze;
     public String session;
     public int mtu = -1;
-    public String addresses;
-    public String routes;
+    public List<LinkAddress> addresses = new ArrayList<LinkAddress>();
+    public List<RouteInfo> routes = new ArrayList<RouteInfo>();
     public List<String> dnsServers;
     public List<String> searchDomains;
     public PendingIntent configureIntent;
     public long startTime = -1;
     public boolean legacy;
 
+    public void addLegacyRoutes(String routesStr) {
+        if (routesStr.trim().equals("")) {
+            return;
+        }
+        String[] routes = routesStr.trim().split(" ");
+        for (String route : routes) {
+            //each route is ip/prefix
+            String[] split = route.split("/");
+            RouteInfo info = new RouteInfo(new LinkAddress
+                    (InetAddress.parseNumericAddress(split[0]), Integer.parseInt(split[1])), null);
+            this.routes.add(info);
+        }
+    }
+
+    public void addLegacyAddresses(String addressesStr) {
+        if (addressesStr.trim().equals("")) {
+            return;
+        }
+        String[] addresses = addressesStr.trim().split(" ");
+        for (String address : addresses) {
+            //each address is ip/prefix
+            String[] split = address.split("/");
+            LinkAddress addr = new LinkAddress(InetAddress.parseNumericAddress(split[0]),
+                    Integer.parseInt(split[1]));
+            this.addresses.add(addr);
+        }
+    }
+
     @Override
     public int describeContents() {
         return 0;
@@ -80,8 +110,8 @@
         out.writeString(interfaze);
         out.writeString(session);
         out.writeInt(mtu);
-        out.writeString(addresses);
-        out.writeString(routes);
+        out.writeTypedList(addresses);
+        out.writeTypedList(routes);
         out.writeStringList(dnsServers);
         out.writeStringList(searchDomains);
         out.writeParcelable(configureIntent, flags);
@@ -98,8 +128,8 @@
             config.interfaze = in.readString();
             config.session = in.readString();
             config.mtu = in.readInt();
-            config.addresses = in.readString();
-            config.routes = in.readString();
+            in.readTypedList(config.addresses, LinkAddress.CREATOR);
+            in.readTypedList(config.routes, RouteInfo.CREATOR);
             config.dnsServers = in.createStringArrayList();
             config.searchDomains = in.createStringArrayList();
             config.configureIntent = in.readParcelable(null);
diff --git a/core/java/com/android/internal/notification/DemoContactNotificationScorer.java b/core/java/com/android/internal/notification/DemoContactNotificationScorer.java
new file mode 100644
index 0000000..f484724
--- /dev/null
+++ b/core/java/com/android/internal/notification/DemoContactNotificationScorer.java
@@ -0,0 +1,188 @@
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package com.android.internal.notification;
+
+import android.app.Notification;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.ContactsContract;
+import android.provider.Settings;
+import android.text.SpannableString;
+import android.util.Slog;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * This NotificationScorer bumps up the priority of notifications that contain references to the
+ * display names of starred contacts. The references it picks up are spannable strings which, in
+ * their entirety, match the display name of some starred contact. The magnitude of the bump ranges
+ * from 0 to 15 (assuming NOTIFICATION_PRIORITY_MULTIPLIER = 10) depending on the initial score, and
+ * the mapping is defined by priorityBumpMap. In a production version of this scorer, a notification
+ * extra will be used to specify contact identifiers.
+ */
+
+public class DemoContactNotificationScorer implements NotificationScorer {
+    private static final String TAG = "DemoContactNotificationScorer";
+    private static final boolean DBG = false;
+
+    protected static final boolean ENABLE_CONTACT_SCORER = true;
+    private static final String SETTING_ENABLE_SCORER = "contact_scorer_enabled";
+    protected boolean mEnabled;
+
+    // see NotificationManagerService
+    private static final int NOTIFICATION_PRIORITY_MULTIPLIER = 10;
+
+    private Context mContext;
+
+    private static final List<String> RELEVANT_KEYS_LIST = Arrays.asList(
+            Notification.EXTRA_INFO_TEXT, Notification.EXTRA_TEXT, Notification.EXTRA_TEXT_LINES,
+            Notification.EXTRA_SUB_TEXT, Notification.EXTRA_TITLE
+    );
+
+    private static final String[] PROJECTION = new String[] {
+            ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME
+    };
+
+    private static final Uri CONTACTS_URI = ContactsContract.Contacts.CONTENT_URI;
+
+    private static List<String> extractSpannedStrings(CharSequence charSequence) {
+        if (charSequence == null) return Collections.emptyList();
+        if (!(charSequence instanceof SpannableString)) {
+            return Arrays.asList(charSequence.toString());
+        }
+        SpannableString spannableString = (SpannableString)charSequence;
+        // get all spans
+        Object[] ssArr = spannableString.getSpans(0, spannableString.length(), Object.class);
+        // spanned string sequences
+        ArrayList<String> sss = new ArrayList<String>();
+        for (Object spanObj : ssArr) {
+            try {
+                sss.add(spannableString.subSequence(spannableString.getSpanStart(spanObj),
+                        spannableString.getSpanEnd(spanObj)).toString());
+            } catch(StringIndexOutOfBoundsException e) {
+                Slog.e(TAG, "Bad indices when extracting spanned subsequence", e);
+            }
+        }
+        return sss;
+    };
+
+    private static String getQuestionMarksInParens(int n) {
+        StringBuilder sb = new StringBuilder("(");
+        for (int i = 0; i < n; i++) {
+            if (sb.length() > 1) sb.append(',');
+            sb.append('?');
+        }
+        sb.append(")");
+        return sb.toString();
+    }
+
+    private boolean hasStarredContact(Bundle extras) {
+        if (extras == null) return false;
+        ArrayList<String> qStrings = new ArrayList<String>();
+        // build list to query against the database for display names.
+        for (String rk: RELEVANT_KEYS_LIST) {
+            if (extras.get(rk) == null) {
+                continue;
+            } else if (extras.get(rk) instanceof CharSequence) {
+                qStrings.addAll(extractSpannedStrings((CharSequence) extras.get(rk)));
+            } else if (extras.get(rk) instanceof CharSequence[]) {
+                // this is intended for Notification.EXTRA_TEXT_LINES
+                for (CharSequence line: (CharSequence[]) extras.get(rk)){
+                    qStrings.addAll(extractSpannedStrings(line));
+                }
+            } else {
+                Slog.w(TAG, "Strange, the extra " + rk + " is of unexpected type.");
+            }
+        }
+        if (qStrings.isEmpty()) return false;
+        String[] qStringsArr = qStrings.toArray(new String[qStrings.size()]);
+
+        String selection = ContactsContract.Contacts.DISPLAY_NAME + " IN "
+                + getQuestionMarksInParens(qStringsArr.length) + " AND "
+                + ContactsContract.Contacts.STARRED+" ='1'";
+
+        Cursor c = null;
+        try {
+            c = mContext.getContentResolver().query(
+                    CONTACTS_URI, PROJECTION, selection, qStringsArr, null);
+            if (c != null) return c.getCount() > 0;
+        } catch(Throwable t) {
+            Slog.w(TAG, "Problem getting content resolver or performing contacts query.", t);
+        } finally {
+            if (c != null) {
+                c.close();
+            }
+        }
+        return false;
+    }
+
+    private final static int clamp(int x, int low, int high) {
+        return (x < low) ? low : ((x > high) ? high : x);
+    }
+
+    private static int priorityBumpMap(int incomingScore) {
+        //assumption is that scale runs from [-2*pm, 2*pm]
+        int pm = NOTIFICATION_PRIORITY_MULTIPLIER;
+        int theScore = incomingScore;
+        // enforce input in range
+        theScore = clamp(theScore, -2 * pm, 2 * pm);
+        if (theScore != incomingScore) return incomingScore;
+        // map -20 -> -20 and -10 -> 5 (when pm = 10)
+        if (theScore <= -pm) {
+            theScore += 1.5 * (theScore + 2 * pm);
+        } else {
+            // map 0 -> 10, 10 -> 15, 20 -> 20;
+            theScore += 0.5 * (2 * pm - theScore);
+        }
+        if (DBG) Slog.v(TAG, "priorityBumpMap: score before: " + incomingScore
+                + ", score after " + theScore + ".");
+        return theScore;
+    }
+
+    @Override
+    public void initialize(Context context) {
+        if (DBG) Slog.v(TAG, "Initializing  " + getClass().getSimpleName() + ".");
+        mContext = context;
+        mEnabled = ENABLE_CONTACT_SCORER && 1 == Settings.Global.getInt(
+                mContext.getContentResolver(), SETTING_ENABLE_SCORER, 0);
+    }
+
+    @Override
+    public int getScore(Notification notification, int score) {
+        if (notification == null || !mEnabled) {
+            if (DBG) Slog.w(TAG, "empty notification? scorer disabled?");
+            return score;
+        }
+        boolean hasStarredPriority = hasStarredContact(notification.extras);
+
+        if (DBG) {
+            if (hasStarredPriority) {
+                Slog.v(TAG, "Notification references starred contact. Promoted!");
+            } else {
+                Slog.v(TAG, "Notification lacks any starred contact reference. Not promoted!");
+            }
+        }
+        if (hasStarredPriority) score = priorityBumpMap(score);
+        return score;
+    }
+}
+
diff --git a/core/java/com/android/internal/notification/NotificationScorer.java b/core/java/com/android/internal/notification/NotificationScorer.java
new file mode 100644
index 0000000..863c08c
--- /dev/null
+++ b/core/java/com/android/internal/notification/NotificationScorer.java
@@ -0,0 +1,27 @@
+/*
+* Copyright (C) 2013 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package com.android.internal.notification;
+
+import android.app.Notification;
+import android.content.Context;
+
+public interface NotificationScorer {
+
+    public void initialize(Context context);
+    public int getScore(Notification notification, int score);
+
+}
diff --git a/core/java/com/android/internal/os/BackgroundThread.java b/core/java/com/android/internal/os/BackgroundThread.java
new file mode 100644
index 0000000..d6f7b20
--- /dev/null
+++ b/core/java/com/android/internal/os/BackgroundThread.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.os;
+
+import android.os.Handler;
+import android.os.HandlerThread;
+
+/**
+ * Shared singleton background thread for each process.
+ */
+public final class BackgroundThread extends HandlerThread {
+    private static BackgroundThread sInstance;
+    private static Handler sHandler;
+
+    private BackgroundThread() {
+        super("android.bg", android.os.Process.THREAD_PRIORITY_BACKGROUND);
+    }
+
+    private static void ensureThreadLocked() {
+        if (sInstance == null) {
+            sInstance = new BackgroundThread();
+            sInstance.start();
+            sHandler = new Handler(sInstance.getLooper());
+        }
+    }
+
+    public static BackgroundThread get() {
+        synchronized (BackgroundThread.class) {
+            ensureThreadLocked();
+            return sInstance;
+        }
+    }
+
+    public static Handler getHandler() {
+        synchronized (BackgroundThread.class) {
+            ensureThreadLocked();
+            return sHandler;
+        }
+    }
+}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 6375dbe..e0a154c 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -16,7 +16,6 @@
 
 package com.android.internal.os;
 
-import static android.text.format.DateUtils.SECOND_IN_MILLIS;
 import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
 
 import android.bluetooth.BluetoothDevice;
@@ -46,7 +45,9 @@
 import android.util.SparseArray;
 import android.util.TimeUtils;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.net.NetworkStatsFactory;
+import com.android.internal.util.FastPrintWriter;
 import com.android.internal.util.JournaledFile;
 import com.google.android.collect.Sets;
 
@@ -83,7 +84,7 @@
     private static final int MAGIC = 0xBA757475; // 'BATSTATS'
 
     // Current on-disk Parcel version
-    private static final int VERSION = 64 + (USE_OLD_HISTORY ? 1000 : 0);
+    private static final int VERSION = 66 + (USE_OLD_HISTORY ? 1000 : 0);
 
     // Maximum number of items we will record in the history.
     private static final int MAX_HISTORY_ITEMS = 2000;
@@ -231,6 +232,9 @@
     final StopwatchTimer[] mPhoneDataConnectionsTimer =
             new StopwatchTimer[NUM_DATA_CONNECTION_TYPES];
 
+    final LongSamplingCounter[] mNetworkActivityCounters =
+            new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
+
     boolean mWifiOn;
     StopwatchTimer mWifiOnTimer;
     int mWifiOnUid = -1;
@@ -275,12 +279,6 @@
 
     long mLastWriteTime = 0; // Milliseconds
 
-    // Mobile data transferred while on battery
-    private long[] mMobileDataTx = new long[4];
-    private long[] mMobileDataRx = new long[4];
-    private long[] mTotalDataTx = new long[4];
-    private long[] mTotalDataRx = new long[4];
-
     private long mRadioDataUptime;
     private long mRadioDataStart;
 
@@ -304,7 +302,8 @@
     private static int sKernelWakelockUpdateVersion = 0;
 
     private static final int[] PROC_WAKELOCKS_FORMAT = new int[] {
-        Process.PROC_TAB_TERM|Process.PROC_OUT_STRING,                // 0: name
+        Process.PROC_TAB_TERM|Process.PROC_OUT_STRING|                // 0: name
+                              Process.PROC_QUOTES,
         Process.PROC_TAB_TERM|Process.PROC_OUT_LONG,                  // 1: count
         Process.PROC_TAB_TERM,
         Process.PROC_TAB_TERM,
@@ -337,9 +336,12 @@
     private HashMap<String, Integer> mUidCache = new HashMap<String, Integer>();
 
     private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory();
+    private NetworkStats mLastSnapshot;
 
-    /** Network ifaces that {@link ConnectivityManager} has claimed as mobile. */
+    @GuardedBy("this")
     private HashSet<String> mMobileIfaces = Sets.newHashSet();
+    @GuardedBy("this")
+    private HashSet<String> mWifiIfaces = Sets.newHashSet();
 
     // For debugging
     public BatteryStatsImpl() {
@@ -466,7 +468,6 @@
     }
 
     public static class SamplingCounter extends Counter {
-
         SamplingCounter(ArrayList<Unpluggable> unpluggables, Parcel in) {
             super(unpluggables, in);
         }
@@ -480,6 +481,93 @@
         }
     }
 
+    public static class LongSamplingCounter implements Unpluggable {
+        final ArrayList<Unpluggable> mUnpluggables;
+        long mCount;
+        long mLoadedCount;
+        long mLastCount;
+        long mUnpluggedCount;
+        long mPluggedCount;
+
+        LongSamplingCounter(ArrayList<Unpluggable> unpluggables, Parcel in) {
+            mUnpluggables = unpluggables;
+            mPluggedCount = in.readLong();
+            mCount = mPluggedCount;
+            mLoadedCount = in.readLong();
+            mLastCount = 0;
+            mUnpluggedCount = in.readLong();
+            unpluggables.add(this);
+        }
+
+        LongSamplingCounter(ArrayList<Unpluggable> unpluggables) {
+            mUnpluggables = unpluggables;
+            unpluggables.add(this);
+        }
+
+        public void writeToParcel(Parcel out) {
+            out.writeLong(mCount);
+            out.writeLong(mLoadedCount);
+            out.writeLong(mUnpluggedCount);
+        }
+
+        @Override
+        public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
+            mUnpluggedCount = mPluggedCount;
+            mCount = mPluggedCount;
+        }
+
+        @Override
+        public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
+            mPluggedCount = mCount;
+        }
+
+        public long getCountLocked(int which) {
+            long val;
+            if (which == STATS_LAST) {
+                val = mLastCount;
+            } else {
+                val = mCount;
+                if (which == STATS_SINCE_UNPLUGGED) {
+                    val -= mUnpluggedCount;
+                } else if (which != STATS_SINCE_CHARGED) {
+                    val -= mLoadedCount;
+                }
+            }
+
+            return val;
+        }
+
+        void addCountLocked(long count) {
+            mCount += count;
+        }
+
+        /**
+         * Clear state of this counter.
+         */
+        void reset(boolean detachIfReset) {
+            mCount = 0;
+            mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0;
+            if (detachIfReset) {
+                detach();
+            }
+        }
+
+        void detach() {
+            mUnpluggables.remove(this);
+        }
+
+        void writeSummaryFromParcelLocked(Parcel out) {
+            out.writeLong(mCount);
+        }
+
+        void readSummaryFromParcelLocked(Parcel in) {
+            mLoadedCount = in.readLong();
+            mCount = mLoadedCount;
+            mLastCount = 0;
+            mUnpluggedCount = mPluggedCount = mLoadedCount;
+        }
+    }
+
     /**
      * State for keeping track of timing information.
      */
@@ -525,7 +613,6 @@
          * Constructs from a parcel.
          * @param type
          * @param unpluggables
-         * @param powerType
          * @param in
          */
         Timer(int type, ArrayList<Unpluggable> unpluggables, Parcel in) {
@@ -659,7 +746,7 @@
         }
 
         public void logState(Printer pw, String prefix) {
-            pw.println(prefix + " mCount=" + mCount
+            pw.println(prefix + "mCount=" + mCount
                     + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
                     + " mUnpluggedCount=" + mUnpluggedCount);
             pw.println(prefix + "mTotalTime=" + mTotalTime
@@ -1044,7 +1131,7 @@
 
         public void logState(Printer pw, String prefix) {
             super.logState(pw, prefix);
-            pw.println(prefix + "mNesting=" + mNesting + "mUpdateTime=" + mUpdateTime
+            pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTime
                     + " mAcquireTime=" + mAcquireTime);
         }
 
@@ -1316,15 +1403,6 @@
         return kwlt;
     }
 
-    private void doDataPlug(long[] dataTransfer, long currentBytes) {
-        dataTransfer[STATS_LAST] = dataTransfer[STATS_SINCE_UNPLUGGED];
-        dataTransfer[STATS_SINCE_UNPLUGGED] = -1;
-    }
-
-    private void doDataUnplug(long[] dataTransfer, long currentBytes) {
-        dataTransfer[STATS_SINCE_UNPLUGGED] = currentBytes;
-    }
-
     /**
      * Radio uptime in microseconds when transferring data. This value is very approximate.
      * @return
@@ -1571,34 +1649,10 @@
     }
 
     public void doUnplugLocked(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
-        NetworkStats.Entry entry = null;
-
-        // Track UID data usage
-        final NetworkStats uidStats = getNetworkStatsDetailGroupedByUid();
-        final int size = uidStats.size();
-        for (int i = 0; i < size; i++) {
-            entry = uidStats.getValues(i, entry);
-
-            final Uid u = getUidStatsLocked(entry.uid);
-            u.mStartedTcpBytesReceived = entry.rxBytes;
-            u.mStartedTcpBytesSent = entry.txBytes;
-            u.mTcpBytesReceivedAtLastUnplug = u.mCurrentTcpBytesReceived;
-            u.mTcpBytesSentAtLastUnplug = u.mCurrentTcpBytesSent;
-        }
-
         for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
             mUnpluggables.get(i).unplug(elapsedRealtime, batteryUptime, batteryRealtime);
         }
 
-        // Track both mobile and total overall data
-        final NetworkStats ifaceStats = getNetworkStatsSummary();
-        entry = ifaceStats.getTotal(entry, mMobileIfaces);
-        doDataUnplug(mMobileDataRx, entry.rxBytes);
-        doDataUnplug(mMobileDataTx, entry.txBytes);
-        entry = ifaceStats.getTotal(entry);
-        doDataUnplug(mTotalDataRx, entry.rxBytes);
-        doDataUnplug(mTotalDataTx, entry.txBytes);
-
         // Track radio awake time
         mRadioDataStart = getCurrentRadioDataUptime();
         mRadioDataUptime = 0;
@@ -1609,32 +1663,10 @@
     }
 
     public void doPlugLocked(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
-        NetworkStats.Entry entry = null;
-
-        for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
-            Uid u = mUidStats.valueAt(iu);
-            if (u.mStartedTcpBytesReceived >= 0) {
-                u.mCurrentTcpBytesReceived = u.computeCurrentTcpBytesReceived();
-                u.mStartedTcpBytesReceived = -1;
-            }
-            if (u.mStartedTcpBytesSent >= 0) {
-                u.mCurrentTcpBytesSent = u.computeCurrentTcpBytesSent();
-                u.mStartedTcpBytesSent = -1;
-            }
-        }
         for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
             mUnpluggables.get(i).plug(elapsedRealtime, batteryUptime, batteryRealtime);
         }
 
-        // Track both mobile and total overall data
-        final NetworkStats ifaceStats = getNetworkStatsSummary();
-        entry = ifaceStats.getTotal(entry, mMobileIfaces);
-        doDataPlug(mMobileDataRx, entry.rxBytes);
-        doDataPlug(mMobileDataTx, entry.txBytes);
-        entry = ifaceStats.getTotal(entry);
-        doDataPlug(mTotalDataRx, entry.rxBytes);
-        doDataPlug(mTotalDataTx, entry.txBytes);
-
         // Track radio awake time
         mRadioDataUptime = getRadioDataUptime();
         mRadioDataStart = -1;
@@ -2234,6 +2266,14 @@
         getUidStatsLocked(uid).noteVideoTurnedOffLocked();
     }
 
+    public void noteActivityResumedLocked(int uid) {
+        getUidStatsLocked(uid).noteActivityResumedLocked();
+    }
+
+    public void noteActivityPausedLocked(int uid) {
+        getUidStatsLocked(uid).noteActivityPausedLocked();
+    }
+
     public void noteVibratorOnLocked(int uid, long durationMillis) {
         getUidStatsLocked(uid).noteVibratorOnLocked(durationMillis);
     }
@@ -2433,6 +2473,18 @@
         } else {
             mMobileIfaces.remove(iface);
         }
+        if (ConnectivityManager.isNetworkTypeWifi(networkType)) {
+            mWifiIfaces.add(iface);
+        } else {
+            mWifiIfaces.remove(iface);
+        }
+    }
+
+    public void noteNetworkStatsEnabledLocked() {
+        // During device boot, qtaguid isn't enabled until after the inital
+        // loading of battery stats. Now that they're enabled, take our initial
+        // snapshot for future delta calculation.
+        updateNetworkActivityLocked();
     }
 
     @Override public long getScreenOnTime(long batteryRealtime, int which) {
@@ -2491,6 +2543,15 @@
         return mBluetoothOnTimer.getTotalTimeLocked(batteryRealtime, which);
     }
 
+    @Override
+    public long getNetworkActivityCount(int type, int which) {
+        if (type >= 0 && type < mNetworkActivityCounters.length) {
+            return mNetworkActivityCounters[type].getCountLocked(which);
+        } else {
+            return 0;
+        }
+    }
+
     @Override public boolean getIsOnBattery() {
         return mOnBattery;
     }
@@ -2505,17 +2566,6 @@
     public final class Uid extends BatteryStats.Uid {
 
         final int mUid;
-        long mLoadedTcpBytesReceived;
-        long mLoadedTcpBytesSent;
-        long mCurrentTcpBytesReceived;
-        long mCurrentTcpBytesSent;
-        long mTcpBytesReceivedAtLastUnplug;
-        long mTcpBytesSentAtLastUnplug;
-
-        // These are not saved/restored when parcelling, since we want
-        // to return from the parcel with a snapshot of the state.
-        long mStartedTcpBytesReceived = -1;
-        long mStartedTcpBytesSent = -1;
 
         boolean mWifiRunning;
         StopwatchTimer mWifiRunningTimer;
@@ -2535,10 +2585,14 @@
         boolean mVideoTurnedOn;
         StopwatchTimer mVideoTurnedOnTimer;
 
+        StopwatchTimer mForegroundActivityTimer;
+
         BatchTimer mVibratorOnTimer;
 
         Counter[] mUserActivityCounters;
 
+        LongSamplingCounter[] mNetworkActivityCounters;
+
         /**
          * The statistics we have collected for this uid's wake locks.
          */
@@ -2602,43 +2656,6 @@
         }
 
         @Override
-        public long getTcpBytesReceived(int which) {
-            if (which == STATS_LAST) {
-                return mLoadedTcpBytesReceived;
-            } else {
-                long current = computeCurrentTcpBytesReceived();
-                if (which == STATS_SINCE_UNPLUGGED) {
-                    current -= mTcpBytesReceivedAtLastUnplug;
-                } else if (which == STATS_SINCE_CHARGED) {
-                    current += mLoadedTcpBytesReceived;
-                }
-                return current;
-            }
-        }
-
-        public long computeCurrentTcpBytesReceived() {
-            final long uidRxBytes = getNetworkStatsDetailGroupedByUid().getTotal(
-                    null, mUid).rxBytes;
-            return mCurrentTcpBytesReceived + (mStartedTcpBytesReceived >= 0
-                    ? (uidRxBytes - mStartedTcpBytesReceived) : 0);
-        }
-
-        @Override
-        public long getTcpBytesSent(int which) {
-            if (which == STATS_LAST) {
-                return mLoadedTcpBytesSent;
-            } else {
-                long current = computeCurrentTcpBytesSent();
-                if (which == STATS_SINCE_UNPLUGGED) {
-                    current -= mTcpBytesSentAtLastUnplug;
-                } else if (which == STATS_SINCE_CHARGED) {
-                    current += mLoadedTcpBytesSent;
-                }
-                return current;
-            }
-        }
-
-        @Override
         public void noteWifiRunningLocked() {
             if (!mWifiRunning) {
                 mWifiRunning = true;
@@ -2770,6 +2787,27 @@
             }
         }
 
+        public StopwatchTimer createForegroundActivityTimerLocked() {
+            if (mForegroundActivityTimer == null) {
+                mForegroundActivityTimer = new StopwatchTimer(
+                        Uid.this, FOREGROUND_ACTIVITY, null, mUnpluggables);
+            }
+            return mForegroundActivityTimer;
+        }
+
+        @Override
+        public void noteActivityResumedLocked() {
+            // We always start, since we want multiple foreground PIDs to nest
+            createForegroundActivityTimerLocked().startRunningLocked(BatteryStatsImpl.this);
+        }
+
+        @Override
+        public void noteActivityPausedLocked() {
+            if (mForegroundActivityTimer != null) {
+                mForegroundActivityTimer.stopRunningLocked(BatteryStatsImpl.this);
+            }
+        }
+
         public BatchTimer createVibratorOnTimerLocked() {
             if (mVibratorOnTimer == null) {
                 mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON,
@@ -2838,6 +2876,11 @@
         }
 
         @Override
+        public Timer getForegroundActivityTimer() {
+            return mForegroundActivityTimer;
+        }
+
+        @Override
         public Timer getVibratorOnTimer() {
             return mVibratorOnTimer;
         }
@@ -2875,11 +2918,38 @@
             }
         }
 
-        public long computeCurrentTcpBytesSent() {
-            final long uidTxBytes = getNetworkStatsDetailGroupedByUid().getTotal(
-                    null, mUid).txBytes;
-            return mCurrentTcpBytesSent + (mStartedTcpBytesSent >= 0
-                    ? (uidTxBytes - mStartedTcpBytesSent) : 0);
+        void noteNetworkActivityLocked(int type, long delta) {
+            if (mNetworkActivityCounters == null) {
+                initNetworkActivityLocked();
+            }
+            if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) {
+                mNetworkActivityCounters[type].addCountLocked(delta);
+            } else {
+                Slog.w(TAG, "Unknown network activity type " + type + " was specified.",
+                        new Throwable());
+            }
+        }
+
+        @Override
+        public boolean hasNetworkActivity() {
+            return mNetworkActivityCounters != null;
+        }
+
+        @Override
+        public long getNetworkActivityCount(int type, int which) {
+            if (mNetworkActivityCounters != null && type >= 0
+                    && type < mNetworkActivityCounters.length) {
+                return mNetworkActivityCounters[type].getCountLocked(which);
+            } else {
+                return 0;
+            }
+        }
+
+        void initNetworkActivityLocked() {
+            mNetworkActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
+            for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
+                mNetworkActivityCounters[i] = new LongSamplingCounter(mUnpluggables);
+            }
         }
 
         /**
@@ -2913,6 +2983,9 @@
                 active |= !mVideoTurnedOnTimer.reset(BatteryStatsImpl.this, false);
                 active |= mVideoTurnedOn;
             }
+            if (mForegroundActivityTimer != null) {
+                active |= !mForegroundActivityTimer.reset(BatteryStatsImpl.this, false);
+            }
             if (mVibratorOnTimer != null) {
                 if (mVibratorOnTimer.reset(BatteryStatsImpl.this, false)) {
                     mVibratorOnTimer.detach();
@@ -2922,15 +2995,18 @@
                 }
             }
 
-            mLoadedTcpBytesReceived = mLoadedTcpBytesSent = 0;
-            mCurrentTcpBytesReceived = mCurrentTcpBytesSent = 0;
-
             if (mUserActivityCounters != null) {
                 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
                     mUserActivityCounters[i].reset(false);
                 }
             }
 
+            if (mNetworkActivityCounters != null) {
+                for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
+                    mNetworkActivityCounters[i].reset(false);
+                }
+            }
+
             if (mWakelockStats.size() > 0) {
                 Iterator<Map.Entry<String, Wakelock>> it = mWakelockStats.entrySet().iterator();
                 while (it.hasNext()) {
@@ -3012,11 +3088,20 @@
                     mVideoTurnedOnTimer.detach();
                     mVideoTurnedOnTimer = null;
                 }
+                if (mForegroundActivityTimer != null) {
+                    mForegroundActivityTimer.detach();
+                    mForegroundActivityTimer = null;
+                }
                 if (mUserActivityCounters != null) {
                     for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
                         mUserActivityCounters[i].detach();
                     }
                 }
+                if (mNetworkActivityCounters != null) {
+                    for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
+                        mNetworkActivityCounters[i].detach();
+                    }
+                }
             }
 
             return !active;
@@ -3051,12 +3136,6 @@
                 pkg.writeToParcelLocked(out);
             }
 
-            out.writeLong(mLoadedTcpBytesReceived);
-            out.writeLong(mLoadedTcpBytesSent);
-            out.writeLong(computeCurrentTcpBytesReceived());
-            out.writeLong(computeCurrentTcpBytesSent());
-            out.writeLong(mTcpBytesReceivedAtLastUnplug);
-            out.writeLong(mTcpBytesSentAtLastUnplug);
             if (mWifiRunningTimer != null) {
                 out.writeInt(1);
                 mWifiRunningTimer.writeToParcel(out, batteryRealtime);
@@ -3093,6 +3172,12 @@
             } else {
                 out.writeInt(0);
             }
+            if (mForegroundActivityTimer != null) {
+                out.writeInt(1);
+                mForegroundActivityTimer.writeToParcel(out, batteryRealtime);
+            } else {
+                out.writeInt(0);
+            }
             if (mVibratorOnTimer != null) {
                 out.writeInt(1);
                 mVibratorOnTimer.writeToParcel(out, batteryRealtime);
@@ -3107,6 +3192,14 @@
             } else {
                 out.writeInt(0);
             }
+            if (mNetworkActivityCounters != null) {
+                out.writeInt(1);
+                for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
+                    mNetworkActivityCounters[i].writeToParcel(out);
+                }
+            } else {
+                out.writeInt(0);
+            }
         }
 
         void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
@@ -3149,12 +3242,6 @@
                 mPackageStats.put(packageName, pkg);
             }
 
-            mLoadedTcpBytesReceived = in.readLong();
-            mLoadedTcpBytesSent = in.readLong();
-            mCurrentTcpBytesReceived = in.readLong();
-            mCurrentTcpBytesSent = in.readLong();
-            mTcpBytesReceivedAtLastUnplug = in.readLong();
-            mTcpBytesSentAtLastUnplug = in.readLong();
             mWifiRunning = false;
             if (in.readInt() != 0) {
                 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
@@ -3198,6 +3285,12 @@
                 mVideoTurnedOnTimer = null;
             }
             if (in.readInt() != 0) {
+                mForegroundActivityTimer = new StopwatchTimer(
+                        Uid.this, FOREGROUND_ACTIVITY, null, mUnpluggables, in);
+            } else {
+                mForegroundActivityTimer = null;
+            }
+            if (in.readInt() != 0) {
                 mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON,
                         mUnpluggables, BatteryStatsImpl.this.mOnBatteryInternal, in);
             } else {
@@ -3211,6 +3304,14 @@
             } else {
                 mUserActivityCounters = null;
             }
+            if (in.readInt() != 0) {
+                mNetworkActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
+                for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
+                    mNetworkActivityCounters[i] = new LongSamplingCounter(mUnpluggables, in);
+                }
+            } else {
+                mNetworkActivityCounters = null;
+            }
         }
 
         /**
@@ -3366,16 +3467,16 @@
             long mSystemTime;
 
             /**
-             * Number of times the process has been started.
-             */
-            int mStarts;
-
-            /**
              * Amount of time the process was running in the foreground.
              */
             long mForegroundTime;
 
             /**
+             * Number of times the process has been started.
+             */
+            int mStarts;
+
+            /**
              * The amount of user time loaded from a previous save.
              */
             long mLoadedUserTime;
@@ -3386,16 +3487,16 @@
             long mLoadedSystemTime;
 
             /**
-             * The number of times the process has started from a previous save.
-             */
-            int mLoadedStarts;
-
-            /**
              * The amount of foreground time loaded from a previous save.
              */
             long mLoadedForegroundTime;
 
             /**
+             * The number of times the process has started from a previous save.
+             */
+            int mLoadedStarts;
+
+            /**
              * The amount of user time loaded from the previous run.
              */
             long mLastUserTime;
@@ -3406,16 +3507,16 @@
             long mLastSystemTime;
 
             /**
-             * The number of times the process has started from the previous run.
-             */
-            int mLastStarts;
-
-            /**
              * The amount of foreground time loaded from the previous run
              */
             long mLastForegroundTime;
 
             /**
+             * The number of times the process has started from the previous run.
+             */
+            int mLastStarts;
+
+            /**
              * The amount of user time when last unplugged.
              */
             long mUnpluggedUserTime;
@@ -3426,15 +3527,15 @@
             long mUnpluggedSystemTime;
 
             /**
-             * The number of times the process has started before unplugged.
-             */
-            int mUnpluggedStarts;
-
-            /**
              * The amount of foreground time since unplugged.
              */
             long mUnpluggedForegroundTime;
 
+            /**
+             * The number of times the process has started before unplugged.
+             */
+            int mUnpluggedStarts;
+
             SamplingCounter[] mSpeedBins;
 
             ArrayList<ExcessivePower> mExcessivePower;
@@ -3447,8 +3548,8 @@
             public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
                 mUnpluggedUserTime = mUserTime;
                 mUnpluggedSystemTime = mSystemTime;
-                mUnpluggedStarts = mStarts;
                 mUnpluggedForegroundTime = mForegroundTime;
+                mUnpluggedStarts = mStarts;
             }
 
             public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
@@ -4285,6 +4386,9 @@
         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
             mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i, null, mUnpluggables);
         }
+        for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
+            mNetworkActivityCounters[i] = new LongSamplingCounter(mUnpluggables);
+        }
         mWifiOnTimer = new StopwatchTimer(null, -3, null, mUnpluggables);
         mGlobalWifiRunningTimer = new StopwatchTimer(null, -4, null, mUnpluggables);
         mBluetoothOnTimer = new StopwatchTimer(null, -5, null, mUnpluggables);
@@ -4358,12 +4462,13 @@
                 Slog.w(TAG, "New history ends before old history!");
             } else if (!out.same(mHistoryReadTmp)) {
                 long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
-                PrintWriter pw = new PrintWriter(new LogWriter(android.util.Log.WARN, TAG));
+                PrintWriter pw = new FastPrintWriter(new LogWriter(android.util.Log.WARN, TAG));
                 pw.println("Histories differ!");
                 pw.println("Old history:");
                 (new HistoryPrinter()).printNextItem(pw, out, now);
                 pw.println("New history:");
                 (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, now);
+                pw.flush();
             }
         }
         return true;
@@ -4460,6 +4565,9 @@
         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
             mPhoneDataConnectionsTimer[i].reset(this, false);
         }
+        for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
+            mNetworkActivityCounters[i].reset(false);
+        }
         mWifiOnTimer.reset(this, false);
         mGlobalWifiRunningTimer.reset(this, false);
         mBluetoothOnTimer.reset(this, false);
@@ -4535,6 +4643,7 @@
                 mDischargeStartLevel = level;
             }
             updateKernelWakelocksLocked();
+            updateNetworkActivityLocked();
             mHistoryCur.batteryLevel = (byte)level;
             mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: "
@@ -4557,6 +4666,7 @@
             doUnplugLocked(realtime, mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime);
         } else {
             updateKernelWakelocksLocked();
+            updateNetworkActivityLocked();
             mHistoryCur.batteryLevel = (byte)level;
             mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: "
@@ -4689,6 +4799,52 @@
         }
     }
 
+    private void updateNetworkActivityLocked() {
+        if (!SystemProperties.getBoolean(PROP_QTAGUID_ENABLED, false)) return;
+
+        final NetworkStats snapshot;
+        try {
+            snapshot = mNetworkStatsFactory.readNetworkStatsDetail();
+        } catch (IOException e) {
+            Log.wtf(TAG, "Failed to read network stats", e);
+            return;
+        }
+
+        if (mLastSnapshot == null) {
+            mLastSnapshot = snapshot;
+            return;
+        }
+
+        final NetworkStats delta = snapshot.subtract(mLastSnapshot);
+        mLastSnapshot = snapshot;
+
+        NetworkStats.Entry entry = null;
+        final int size = delta.size();
+        for (int i = 0; i < size; i++) {
+            entry = delta.getValues(i, entry);
+
+            if (entry.rxBytes == 0 || entry.txBytes == 0) continue;
+            if (entry.tag != NetworkStats.TAG_NONE) continue;
+
+            final Uid u = getUidStatsLocked(entry.uid);
+
+            if (mMobileIfaces.contains(entry.iface)) {
+                u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_BYTES, entry.rxBytes);
+                u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_BYTES, entry.txBytes);
+
+                mNetworkActivityCounters[NETWORK_MOBILE_RX_BYTES].addCountLocked(entry.rxBytes);
+                mNetworkActivityCounters[NETWORK_MOBILE_TX_BYTES].addCountLocked(entry.txBytes);
+
+            } else if (mWifiIfaces.contains(entry.iface)) {
+                u.noteNetworkActivityLocked(NETWORK_WIFI_RX_BYTES, entry.rxBytes);
+                u.noteNetworkActivityLocked(NETWORK_WIFI_TX_BYTES, entry.txBytes);
+
+                mNetworkActivityCounters[NETWORK_WIFI_RX_BYTES].addCountLocked(entry.rxBytes);
+                mNetworkActivityCounters[NETWORK_WIFI_TX_BYTES].addCountLocked(entry.txBytes);
+            }
+        }
+    }
+
     public long getAwakeTimeBattery() {
         return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT);
     }
@@ -4779,47 +4935,6 @@
         return getBatteryRealtimeLocked(curTime);
     }
 
-    private long getTcpBytes(long current, long[] dataBytes, int which) {
-        if (which == STATS_LAST) {
-            return dataBytes[STATS_LAST];
-        } else {
-            if (which == STATS_SINCE_UNPLUGGED) {
-                if (dataBytes[STATS_SINCE_UNPLUGGED] < 0) {
-                    return dataBytes[STATS_LAST];
-                } else {
-                    return current - dataBytes[STATS_SINCE_UNPLUGGED];
-                }
-            } else if (which == STATS_SINCE_CHARGED) {
-                return (current - dataBytes[STATS_CURRENT]) + dataBytes[STATS_SINCE_CHARGED];
-            }
-            return current - dataBytes[STATS_CURRENT];
-        }
-    }
-
-    /** Only STATS_UNPLUGGED works properly */
-    public long getMobileTcpBytesSent(int which) {
-        final long mobileTxBytes = getNetworkStatsSummary().getTotal(null, mMobileIfaces).txBytes;
-        return getTcpBytes(mobileTxBytes, mMobileDataTx, which);
-    }
-
-    /** Only STATS_UNPLUGGED works properly */
-    public long getMobileTcpBytesReceived(int which) {
-        final long mobileRxBytes = getNetworkStatsSummary().getTotal(null, mMobileIfaces).rxBytes;
-        return getTcpBytes(mobileRxBytes, mMobileDataRx, which);
-    }
-
-    /** Only STATS_UNPLUGGED works properly */
-    public long getTotalTcpBytesSent(int which) {
-        final long totalTxBytes = getNetworkStatsSummary().getTotal(null).txBytes;
-        return getTcpBytes(totalTxBytes, mTotalDataTx, which);
-    }
-
-    /** Only STATS_UNPLUGGED works properly */
-    public long getTotalTcpBytesReceived(int which) {
-        final long totalRxBytes = getNetworkStatsSummary().getTotal(null).rxBytes;
-        return getTcpBytes(totalRxBytes, mTotalDataRx, which);
-    }
-
     @Override
     public int getDischargeStartLevel() {
         synchronized(this) {
@@ -5299,6 +5414,9 @@
         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
             mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in);
         }
+        for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
+            mNetworkActivityCounters[i].readSummaryFromParcelLocked(in);
+        }
         mWifiOn = false;
         mWifiOnTimer.readSummaryFromParcelLocked(in);
         mGlobalWifiRunning = false;
@@ -5355,6 +5473,9 @@
                 u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
             }
             if (in.readInt() != 0) {
+                u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in);
+            }
+            if (in.readInt() != 0) {
                 u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in);
             }
 
@@ -5367,6 +5488,15 @@
                 }
             }
 
+            if (in.readInt() != 0) {
+                if (u.mNetworkActivityCounters == null) {
+                    u.initNetworkActivityLocked();
+                }
+                for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
+                    u.mNetworkActivityCounters[i].readSummaryFromParcelLocked(in);
+                }
+            }
+
             int NW = in.readInt();
             if (NW > 100) {
                 Slog.w(TAG, "File corrupt: too many wake locks " + NW);
@@ -5408,6 +5538,7 @@
                 Uid.Proc p = u.getProcessStatsLocked(procName);
                 p.mUserTime = p.mLoadedUserTime = in.readLong();
                 p.mSystemTime = p.mLoadedSystemTime = in.readLong();
+                p.mForegroundTime = p.mLoadedForegroundTime = in.readLong();
                 p.mStarts = p.mLoadedStarts = in.readInt();
                 int NSB = in.readInt();
                 if (NSB > 100) {
@@ -5448,9 +5579,6 @@
                     s.mLaunches = s.mLoadedLaunches = in.readInt();
                 }
             }
-
-            u.mLoadedTcpBytesReceived = in.readLong();
-            u.mLoadedTcpBytesSent = in.readLong();
         }
     }
 
@@ -5463,6 +5591,7 @@
     public void writeSummaryToParcel(Parcel out) {
         // Need to update with current kernel wake lock counts.
         updateKernelWakelocksLocked();
+        updateNetworkActivityLocked();
 
         final long NOW_SYS = SystemClock.uptimeMillis() * 1000;
         final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000;
@@ -5498,6 +5627,9 @@
         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
             mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
         }
+        for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
+            mNetworkActivityCounters[i].writeSummaryFromParcelLocked(out);
+        }
         mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
         mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
         mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
@@ -5557,6 +5689,12 @@
             } else {
                 out.writeInt(0);
             }
+            if (u.mForegroundActivityTimer != null) {
+                out.writeInt(1);
+                u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, NOWREAL);
+            } else {
+                out.writeInt(0);
+            }
             if (u.mVibratorOnTimer != null) {
                 out.writeInt(1);
                 u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
@@ -5573,6 +5711,15 @@
                 }
             }
 
+            if (u.mNetworkActivityCounters == null) {
+                out.writeInt(0);
+            } else {
+                out.writeInt(1);
+                for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
+                    u.mNetworkActivityCounters[i].writeSummaryFromParcelLocked(out);
+                }
+            }
+
             int NW = u.mWakelockStats.size();
             out.writeInt(NW);
             if (NW > 0) {
@@ -5626,6 +5773,7 @@
                     Uid.Proc ps = ent.getValue();
                     out.writeLong(ps.mUserTime);
                     out.writeLong(ps.mSystemTime);
+                    out.writeLong(ps.mForegroundTime);
                     out.writeInt(ps.mStarts);
                     final int N = ps.mSpeedBins.length;
                     out.writeInt(N);
@@ -5664,9 +5812,6 @@
                     }
                 }
             }
-
-            out.writeLong(u.getTcpBytesReceived(STATS_SINCE_CHARGED));
-            out.writeLong(u.getTcpBytesSent(STATS_SINCE_CHARGED));
         }
     }
 
@@ -5705,6 +5850,9 @@
             mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i,
                     null, mUnpluggables, in);
         }
+        for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
+            mNetworkActivityCounters[i] = new LongSamplingCounter(mUnpluggables, in);
+        }
         mWifiOn = false;
         mWifiOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
         mGlobalWifiRunning = false;
@@ -5735,15 +5883,6 @@
         mDischargeAmountScreenOffSinceCharge = in.readInt();
         mLastWriteTime = in.readLong();
 
-        mMobileDataRx[STATS_LAST] = in.readLong();
-        mMobileDataRx[STATS_SINCE_UNPLUGGED] = -1;
-        mMobileDataTx[STATS_LAST] = in.readLong();
-        mMobileDataTx[STATS_SINCE_UNPLUGGED] = -1;
-        mTotalDataRx[STATS_LAST] = in.readLong();
-        mTotalDataRx[STATS_SINCE_UNPLUGGED] = -1;
-        mTotalDataTx[STATS_LAST] = in.readLong();
-        mTotalDataTx[STATS_SINCE_UNPLUGGED] = -1;
-
         mRadioDataUptime = in.readLong();
         mRadioDataStart = -1;
 
@@ -5793,6 +5932,7 @@
     void writeToParcelLocked(Parcel out, boolean inclUids, int flags) {
         // Need to update with current kernel wake lock counts.
         updateKernelWakelocksLocked();
+        updateNetworkActivityLocked();
 
         final long uSecUptime = SystemClock.uptimeMillis() * 1000;
         final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
@@ -5819,6 +5959,9 @@
         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
             mPhoneDataConnectionsTimer[i].writeToParcel(out, batteryRealtime);
         }
+        for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
+            mNetworkActivityCounters[i].writeToParcel(out);
+        }
         mWifiOnTimer.writeToParcel(out, batteryRealtime);
         mGlobalWifiRunningTimer.writeToParcel(out, batteryRealtime);
         mBluetoothOnTimer.writeToParcel(out, batteryRealtime);
@@ -5843,11 +5986,6 @@
         out.writeInt(mDischargeAmountScreenOffSinceCharge);
         out.writeLong(mLastWriteTime);
 
-        out.writeLong(getMobileTcpBytesReceived(STATS_SINCE_UNPLUGGED));
-        out.writeLong(getMobileTcpBytesSent(STATS_SINCE_UNPLUGGED));
-        out.writeLong(getTotalTcpBytesReceived(STATS_SINCE_UNPLUGGED));
-        out.writeLong(getTotalTcpBytesSent(STATS_SINCE_UNPLUGGED));
-
         // Write radio uptime for data
         out.writeLong(getRadioDataUptime());
 
@@ -5899,9 +6037,10 @@
     public void prepareForDumpLocked() {
         // Need to retrieve current kernel wake lock stats before printing.
         updateKernelWakelocksLocked();
+        updateNetworkActivityLocked();
     }
 
-    public void dumpLocked(PrintWriter pw) {
+    public void dumpLocked(PrintWriter pw, boolean isUnpluggedOnly, int reqUid) {
         if (DEBUG) {
             Printer pr = new PrintWriterPrinter(pw);
             pr.println("*** Screen timer:");
@@ -5930,59 +6069,7 @@
             mGlobalWifiRunningTimer.logState(pr, "  ");
             pr.println("*** Bluetooth timer:");
             mBluetoothOnTimer.logState(pr, "  ");
-            pr.println("*** Mobile ifaces:");
-            pr.println(mMobileIfaces.toString());
         }
-        super.dumpLocked(pw);
-    }
-
-    private NetworkStats mNetworkSummaryCache;
-    private NetworkStats mNetworkDetailCache;
-
-    private NetworkStats getNetworkStatsSummary() {
-        // NOTE: calls from BatteryStatsService already hold this lock
-        synchronized (this) {
-            if (mNetworkSummaryCache == null
-                    || mNetworkSummaryCache.getElapsedRealtimeAge() > SECOND_IN_MILLIS) {
-                mNetworkSummaryCache = null;
-
-                if (SystemProperties.getBoolean(PROP_QTAGUID_ENABLED, false)) {
-                    try {
-                        mNetworkSummaryCache = mNetworkStatsFactory.readNetworkStatsSummaryDev();
-                    } catch (IOException e) {
-                        Log.wtf(TAG, "problem reading network stats", e);
-                    }
-                }
-
-                if (mNetworkSummaryCache == null) {
-                    mNetworkSummaryCache = new NetworkStats(SystemClock.elapsedRealtime(), 0);
-                }
-            }
-            return mNetworkSummaryCache;
-        }
-    }
-
-    private NetworkStats getNetworkStatsDetailGroupedByUid() {
-        // NOTE: calls from BatteryStatsService already hold this lock
-        synchronized (this) {
-            if (mNetworkDetailCache == null
-                    || mNetworkDetailCache.getElapsedRealtimeAge() > SECOND_IN_MILLIS) {
-                mNetworkDetailCache = null;
-
-                if (SystemProperties.getBoolean(PROP_QTAGUID_ENABLED, false)) {
-                    try {
-                        mNetworkDetailCache = mNetworkStatsFactory
-                                .readNetworkStatsDetail().groupedByUid();
-                    } catch (IOException e) {
-                        Log.wtf(TAG, "problem reading network stats", e);
-                    }
-                }
-
-                if (mNetworkDetailCache == null) {
-                    mNetworkDetailCache = new NetworkStats(SystemClock.elapsedRealtime(), 0);
-                }
-            }
-            return mNetworkDetailCache;
-        }
+        super.dumpLocked(pw, isUnpluggedOnly, reqUid);
     }
 }
diff --git a/core/java/com/android/internal/os/HandlerCaller.java b/core/java/com/android/internal/os/HandlerCaller.java
index b442ff5..d9e3ef6 100644
--- a/core/java/com/android/internal/os/HandlerCaller.java
+++ b/core/java/com/android/internal/os/HandlerCaller.java
@@ -65,7 +65,11 @@
         
         mH.sendMessage(msg);
     }
-    
+
+    public void sendMessageDelayed(Message msg, long delayMillis) {
+        mH.sendMessageDelayed(msg, delayMillis);
+    }
+
     public boolean hasMessages(int what) {
         return mH.hasMessages(what);
     }
diff --git a/core/java/com/android/internal/os/ProcessCpuTracker.java b/core/java/com/android/internal/os/ProcessCpuTracker.java
new file mode 100644
index 0000000..58cd60d
--- /dev/null
+++ b/core/java/com/android/internal/os/ProcessCpuTracker.java
@@ -0,0 +1,877 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.os;
+
+import static android.os.Process.*;
+
+import android.os.FileUtils;
+import android.os.Process;
+import android.os.StrictMode;
+import android.os.SystemClock;
+import android.util.Slog;
+import com.android.internal.util.FastPrintWriter;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.StringTokenizer;
+
+public class ProcessCpuTracker {
+    private static final String TAG = "ProcessCpuTracker";
+    private static final boolean DEBUG = false;
+    private static final boolean localLOGV = DEBUG || false;
+
+    private static final int[] PROCESS_STATS_FORMAT = new int[] {
+        PROC_SPACE_TERM,
+        PROC_SPACE_TERM|PROC_PARENS,
+        PROC_SPACE_TERM,
+        PROC_SPACE_TERM,
+        PROC_SPACE_TERM,
+        PROC_SPACE_TERM,
+        PROC_SPACE_TERM,
+        PROC_SPACE_TERM,
+        PROC_SPACE_TERM,
+        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 10: minor faults
+        PROC_SPACE_TERM,
+        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 12: major faults
+        PROC_SPACE_TERM,
+        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 14: utime
+        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 15: stime
+    };
+
+    static final int PROCESS_STAT_MINOR_FAULTS = 0;
+    static final int PROCESS_STAT_MAJOR_FAULTS = 1;
+    static final int PROCESS_STAT_UTIME = 2;
+    static final int PROCESS_STAT_STIME = 3;
+
+    /** Stores user time and system time in 100ths of a second. */
+    private final long[] mProcessStatsData = new long[4];
+    /** Stores user time and system time in 100ths of a second. */
+    private final long[] mSinglePidStatsData = new long[4];
+
+    private static final int[] PROCESS_FULL_STATS_FORMAT = new int[] {
+        PROC_SPACE_TERM,
+        PROC_SPACE_TERM|PROC_PARENS|PROC_OUT_STRING,    // 2: name
+        PROC_SPACE_TERM,
+        PROC_SPACE_TERM,
+        PROC_SPACE_TERM,
+        PROC_SPACE_TERM,
+        PROC_SPACE_TERM,
+        PROC_SPACE_TERM,
+        PROC_SPACE_TERM,
+        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 10: minor faults
+        PROC_SPACE_TERM,
+        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 12: major faults
+        PROC_SPACE_TERM,
+        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 14: utime
+        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 15: stime
+        PROC_SPACE_TERM,
+        PROC_SPACE_TERM,
+        PROC_SPACE_TERM,
+        PROC_SPACE_TERM,
+        PROC_SPACE_TERM,
+        PROC_SPACE_TERM,
+        PROC_SPACE_TERM,
+        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 23: vsize
+    };
+
+    static final int PROCESS_FULL_STAT_MINOR_FAULTS = 1;
+    static final int PROCESS_FULL_STAT_MAJOR_FAULTS = 2;
+    static final int PROCESS_FULL_STAT_UTIME = 3;
+    static final int PROCESS_FULL_STAT_STIME = 4;
+    static final int PROCESS_FULL_STAT_VSIZE = 5;
+
+    private final String[] mProcessFullStatsStringData = new String[6];
+    private final long[] mProcessFullStatsData = new long[6];
+
+    private static final int[] SYSTEM_CPU_FORMAT = new int[] {
+        PROC_SPACE_TERM|PROC_COMBINE,
+        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 1: user time
+        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 2: nice time
+        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 3: sys time
+        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 4: idle time
+        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 5: iowait time
+        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 6: irq time
+        PROC_SPACE_TERM|PROC_OUT_LONG                   // 7: softirq time
+    };
+
+    private final long[] mSystemCpuData = new long[7];
+
+    private static final int[] LOAD_AVERAGE_FORMAT = new int[] {
+        PROC_SPACE_TERM|PROC_OUT_FLOAT,                 // 0: 1 min
+        PROC_SPACE_TERM|PROC_OUT_FLOAT,                 // 1: 5 mins
+        PROC_SPACE_TERM|PROC_OUT_FLOAT                  // 2: 15 mins
+    };
+
+    private final float[] mLoadAverageData = new float[3];
+
+    private final boolean mIncludeThreads;
+
+    private float mLoad1 = 0;
+    private float mLoad5 = 0;
+    private float mLoad15 = 0;
+
+    private long mCurrentSampleTime;
+    private long mLastSampleTime;
+
+    private long mCurrentSampleRealTime;
+    private long mLastSampleRealTime;
+
+    private long mBaseUserTime;
+    private long mBaseSystemTime;
+    private long mBaseIoWaitTime;
+    private long mBaseIrqTime;
+    private long mBaseSoftIrqTime;
+    private long mBaseIdleTime;
+    private int mRelUserTime;
+    private int mRelSystemTime;
+    private int mRelIoWaitTime;
+    private int mRelIrqTime;
+    private int mRelSoftIrqTime;
+    private int mRelIdleTime;
+
+    private int[] mCurPids;
+    private int[] mCurThreadPids;
+
+    private final ArrayList<Stats> mProcStats = new ArrayList<Stats>();
+    private final ArrayList<Stats> mWorkingProcs = new ArrayList<Stats>();
+    private boolean mWorkingProcsSorted;
+
+    private boolean mFirst = true;
+
+    private byte[] mBuffer = new byte[4096];
+
+    /**
+     * The time in microseconds that the CPU has been running at each speed.
+     */
+    private long[] mCpuSpeedTimes;
+
+    /**
+     * The relative time in microseconds that the CPU has been running at each speed.
+     */
+    private long[] mRelCpuSpeedTimes;
+
+    /**
+     * The different speeds that the CPU can be running at.
+     */
+    private long[] mCpuSpeeds;
+
+    public static class Stats {
+        public final int pid;
+        public final int uid;
+        final String statFile;
+        final String cmdlineFile;
+        final String threadsDir;
+        final ArrayList<Stats> threadStats;
+        final ArrayList<Stats> workingThreads;
+
+        public BatteryStatsImpl.Uid.Proc batteryStats;
+
+        public boolean interesting;
+
+        public String baseName;
+        public String name;
+        public int nameWidth;
+
+        // vsize capture when process first detected; can be used to
+        // filter out kernel processes.
+        public long vsize;
+
+        public long base_uptime;
+        public long rel_uptime;
+
+        public long base_utime;
+        public long base_stime;
+        public int rel_utime;
+        public int rel_stime;
+
+        public long base_minfaults;
+        public long base_majfaults;
+        public int rel_minfaults;
+        public int rel_majfaults;
+
+        public boolean active;
+        public boolean working;
+        public boolean added;
+        public boolean removed;
+
+        Stats(int _pid, int parentPid, boolean includeThreads) {
+            pid = _pid;
+            if (parentPid < 0) {
+                final File procDir = new File("/proc", Integer.toString(pid));
+                statFile = new File(procDir, "stat").toString();
+                cmdlineFile = new File(procDir, "cmdline").toString();
+                threadsDir = (new File(procDir, "task")).toString();
+                if (includeThreads) {
+                    threadStats = new ArrayList<Stats>();
+                    workingThreads = new ArrayList<Stats>();
+                } else {
+                    threadStats = null;
+                    workingThreads = null;
+                }
+            } else {
+                final File procDir = new File("/proc", Integer.toString(
+                        parentPid));
+                final File taskDir = new File(
+                        new File(procDir, "task"), Integer.toString(pid));
+                statFile = new File(taskDir, "stat").toString();
+                cmdlineFile = null;
+                threadsDir = null;
+                threadStats = null;
+                workingThreads = null;
+            }
+            uid = FileUtils.getUid(statFile.toString());
+        }
+    }
+
+    private final static Comparator<Stats> sLoadComparator = new Comparator<Stats>() {
+        public final int
+        compare(Stats sta, Stats stb) {
+            int ta = sta.rel_utime + sta.rel_stime;
+            int tb = stb.rel_utime + stb.rel_stime;
+            if (ta != tb) {
+                return ta > tb ? -1 : 1;
+            }
+            if (sta.added != stb.added) {
+                return sta.added ? -1 : 1;
+            }
+            if (sta.removed != stb.removed) {
+                return sta.added ? -1 : 1;
+            }
+            return 0;
+        }
+    };
+
+
+    public ProcessCpuTracker(boolean includeThreads) {
+        mIncludeThreads = includeThreads;
+    }
+
+    public void onLoadChanged(float load1, float load5, float load15) {
+    }
+
+    public int onMeasureProcessName(String name) {
+        return 0;
+    }
+
+    public void init() {
+        if (DEBUG) Slog.v(TAG, "Init: " + this);
+        mFirst = true;
+        update();
+    }
+
+    public void update() {
+        if (DEBUG) Slog.v(TAG, "Update: " + this);
+        mLastSampleTime = mCurrentSampleTime;
+        mCurrentSampleTime = SystemClock.uptimeMillis();
+        mLastSampleRealTime = mCurrentSampleRealTime;
+        mCurrentSampleRealTime = SystemClock.elapsedRealtime();
+
+        final long[] sysCpu = mSystemCpuData;
+        if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT,
+                null, sysCpu, null)) {
+            // Total user time is user + nice time.
+            final long usertime = sysCpu[0]+sysCpu[1];
+            // Total system time is simply system time.
+            final long systemtime = sysCpu[2];
+            // Total idle time is simply idle time.
+            final long idletime = sysCpu[3];
+            // Total irq time is iowait + irq + softirq time.
+            final long iowaittime = sysCpu[4];
+            final long irqtime = sysCpu[5];
+            final long softirqtime = sysCpu[6];
+
+            mRelUserTime = (int)(usertime - mBaseUserTime);
+            mRelSystemTime = (int)(systemtime - mBaseSystemTime);
+            mRelIoWaitTime = (int)(iowaittime - mBaseIoWaitTime);
+            mRelIrqTime = (int)(irqtime - mBaseIrqTime);
+            mRelSoftIrqTime = (int)(softirqtime - mBaseSoftIrqTime);
+            mRelIdleTime = (int)(idletime - mBaseIdleTime);
+
+            if (DEBUG) {
+                Slog.i("Load", "Total U:" + sysCpu[0] + " N:" + sysCpu[1]
+                      + " S:" + sysCpu[2] + " I:" + sysCpu[3]
+                      + " W:" + sysCpu[4] + " Q:" + sysCpu[5]
+                      + " O:" + sysCpu[6]);
+                Slog.i("Load", "Rel U:" + mRelUserTime + " S:" + mRelSystemTime
+                      + " I:" + mRelIdleTime + " Q:" + mRelIrqTime);
+            }
+
+            mBaseUserTime = usertime;
+            mBaseSystemTime = systemtime;
+            mBaseIoWaitTime = iowaittime;
+            mBaseIrqTime = irqtime;
+            mBaseSoftIrqTime = softirqtime;
+            mBaseIdleTime = idletime;
+        }
+
+        mCurPids = collectStats("/proc", -1, mFirst, mCurPids, mProcStats);
+
+        final float[] loadAverages = mLoadAverageData;
+        if (Process.readProcFile("/proc/loadavg", LOAD_AVERAGE_FORMAT,
+                null, null, loadAverages)) {
+            float load1 = loadAverages[0];
+            float load5 = loadAverages[1];
+            float load15 = loadAverages[2];
+            if (load1 != mLoad1 || load5 != mLoad5 || load15 != mLoad15) {
+                mLoad1 = load1;
+                mLoad5 = load5;
+                mLoad15 = load15;
+                onLoadChanged(load1, load5, load15);
+            }
+        }
+
+        if (DEBUG) Slog.i(TAG, "*** TIME TO COLLECT STATS: "
+                + (SystemClock.uptimeMillis()-mCurrentSampleTime));
+
+        mWorkingProcsSorted = false;
+        mFirst = false;
+    }
+
+    private int[] collectStats(String statsFile, int parentPid, boolean first,
+            int[] curPids, ArrayList<Stats> allProcs) {
+
+        int[] pids = Process.getPids(statsFile, curPids);
+        int NP = (pids == null) ? 0 : pids.length;
+        int NS = allProcs.size();
+        int curStatsIndex = 0;
+        for (int i=0; i<NP; i++) {
+            int pid = pids[i];
+            if (pid < 0) {
+                NP = pid;
+                break;
+            }
+            Stats st = curStatsIndex < NS ? allProcs.get(curStatsIndex) : null;
+
+            if (st != null && st.pid == pid) {
+                // Update an existing process...
+                st.added = false;
+                st.working = false;
+                curStatsIndex++;
+                if (DEBUG) Slog.v(TAG, "Existing "
+                        + (parentPid < 0 ? "process" : "thread")
+                        + " pid " + pid + ": " + st);
+
+                if (st.interesting) {
+                    final long uptime = SystemClock.uptimeMillis();
+
+                    final long[] procStats = mProcessStatsData;
+                    if (!Process.readProcFile(st.statFile.toString(),
+                            PROCESS_STATS_FORMAT, null, procStats, null)) {
+                        continue;
+                    }
+
+                    final long minfaults = procStats[PROCESS_STAT_MINOR_FAULTS];
+                    final long majfaults = procStats[PROCESS_STAT_MAJOR_FAULTS];
+                    final long utime = procStats[PROCESS_STAT_UTIME];
+                    final long stime = procStats[PROCESS_STAT_STIME];
+
+                    if (utime == st.base_utime && stime == st.base_stime) {
+                        st.rel_utime = 0;
+                        st.rel_stime = 0;
+                        st.rel_minfaults = 0;
+                        st.rel_majfaults = 0;
+                        if (st.active) {
+                            st.active = false;
+                        }
+                        continue;
+                    }
+
+                    if (!st.active) {
+                        st.active = true;
+                    }
+
+                    if (parentPid < 0) {
+                        getName(st, st.cmdlineFile);
+                        if (st.threadStats != null) {
+                            mCurThreadPids = collectStats(st.threadsDir, pid, false,
+                                    mCurThreadPids, st.threadStats);
+                        }
+                    }
+
+                    if (DEBUG) Slog.v("Load", "Stats changed " + st.name + " pid=" + st.pid
+                            + " utime=" + utime + "-" + st.base_utime
+                            + " stime=" + stime + "-" + st.base_stime
+                            + " minfaults=" + minfaults + "-" + st.base_minfaults
+                            + " majfaults=" + majfaults + "-" + st.base_majfaults);
+
+                    st.rel_uptime = uptime - st.base_uptime;
+                    st.base_uptime = uptime;
+                    st.rel_utime = (int)(utime - st.base_utime);
+                    st.rel_stime = (int)(stime - st.base_stime);
+                    st.base_utime = utime;
+                    st.base_stime = stime;
+                    st.rel_minfaults = (int)(minfaults - st.base_minfaults);
+                    st.rel_majfaults = (int)(majfaults - st.base_majfaults);
+                    st.base_minfaults = minfaults;
+                    st.base_majfaults = majfaults;
+                    st.working = true;
+                }
+
+                continue;
+            }
+
+            if (st == null || st.pid > pid) {
+                // We have a new process!
+                st = new Stats(pid, parentPid, mIncludeThreads);
+                allProcs.add(curStatsIndex, st);
+                curStatsIndex++;
+                NS++;
+                if (DEBUG) Slog.v(TAG, "New "
+                        + (parentPid < 0 ? "process" : "thread")
+                        + " pid " + pid + ": " + st);
+
+                final String[] procStatsString = mProcessFullStatsStringData;
+                final long[] procStats = mProcessFullStatsData;
+                st.base_uptime = SystemClock.uptimeMillis();
+                if (Process.readProcFile(st.statFile.toString(),
+                        PROCESS_FULL_STATS_FORMAT, procStatsString,
+                        procStats, null)) {
+                    // This is a possible way to filter out processes that
+                    // are actually kernel threads...  do we want to?  Some
+                    // of them do use CPU, but there can be a *lot* that are
+                    // not doing anything.
+                    st.vsize = procStats[PROCESS_FULL_STAT_VSIZE];
+                    if (true || procStats[PROCESS_FULL_STAT_VSIZE] != 0) {
+                        st.interesting = true;
+                        st.baseName = procStatsString[0];
+                        st.base_minfaults = procStats[PROCESS_FULL_STAT_MINOR_FAULTS];
+                        st.base_majfaults = procStats[PROCESS_FULL_STAT_MAJOR_FAULTS];
+                        st.base_utime = procStats[PROCESS_FULL_STAT_UTIME];
+                        st.base_stime = procStats[PROCESS_FULL_STAT_STIME];
+                    } else {
+                        Slog.i(TAG, "Skipping kernel process pid " + pid
+                                + " name " + procStatsString[0]);
+                        st.baseName = procStatsString[0];
+                    }
+                } else {
+                    Slog.w(TAG, "Skipping unknown process pid " + pid);
+                    st.baseName = "<unknown>";
+                    st.base_utime = st.base_stime = 0;
+                    st.base_minfaults = st.base_majfaults = 0;
+                }
+
+                if (parentPid < 0) {
+                    getName(st, st.cmdlineFile);
+                    if (st.threadStats != null) {
+                        mCurThreadPids = collectStats(st.threadsDir, pid, true,
+                                mCurThreadPids, st.threadStats);
+                    }
+                } else if (st.interesting) {
+                    st.name = st.baseName;
+                    st.nameWidth = onMeasureProcessName(st.name);
+                }
+
+                if (DEBUG) Slog.v("Load", "Stats added " + st.name + " pid=" + st.pid
+                        + " utime=" + st.base_utime + " stime=" + st.base_stime
+                        + " minfaults=" + st.base_minfaults + " majfaults=" + st.base_majfaults);
+
+                st.rel_utime = 0;
+                st.rel_stime = 0;
+                st.rel_minfaults = 0;
+                st.rel_majfaults = 0;
+                st.added = true;
+                if (!first && st.interesting) {
+                    st.working = true;
+                }
+                continue;
+            }
+
+            // This process has gone away!
+            st.rel_utime = 0;
+            st.rel_stime = 0;
+            st.rel_minfaults = 0;
+            st.rel_majfaults = 0;
+            st.removed = true;
+            st.working = true;
+            allProcs.remove(curStatsIndex);
+            NS--;
+            if (DEBUG) Slog.v(TAG, "Removed "
+                    + (parentPid < 0 ? "process" : "thread")
+                    + " pid " + pid + ": " + st);
+            // Decrement the loop counter so that we process the current pid
+            // again the next time through the loop.
+            i--;
+            continue;
+        }
+
+        while (curStatsIndex < NS) {
+            // This process has gone away!
+            final Stats st = allProcs.get(curStatsIndex);
+            st.rel_utime = 0;
+            st.rel_stime = 0;
+            st.rel_minfaults = 0;
+            st.rel_majfaults = 0;
+            st.removed = true;
+            st.working = true;
+            allProcs.remove(curStatsIndex);
+            NS--;
+            if (localLOGV) Slog.v(TAG, "Removed pid " + st.pid + ": " + st);
+        }
+
+        return pids;
+    }
+
+    /**
+     * Returns the total time (in clock ticks, or 1/100 sec) spent executing in
+     * both user and system code.
+     */
+    public long getCpuTimeForPid(int pid) {
+        final String statFile = "/proc/" + pid + "/stat";
+        final long[] statsData = mSinglePidStatsData;
+        if (Process.readProcFile(statFile, PROCESS_STATS_FORMAT,
+                null, statsData, null)) {
+            long time = statsData[PROCESS_STAT_UTIME]
+                    + statsData[PROCESS_STAT_STIME];
+            return time;
+        }
+        return 0;
+    }
+
+    /**
+     * Returns the delta time (in clock ticks, or 1/100 sec) spent at each CPU
+     * speed, since the last call to this method. If this is the first call, it
+     * will return 1 for each value.
+     */
+    public long[] getLastCpuSpeedTimes() {
+        if (mCpuSpeedTimes == null) {
+            mCpuSpeedTimes = getCpuSpeedTimes(null);
+            mRelCpuSpeedTimes = new long[mCpuSpeedTimes.length];
+            for (int i = 0; i < mCpuSpeedTimes.length; i++) {
+                mRelCpuSpeedTimes[i] = 1; // Initialize
+            }
+        } else {
+            getCpuSpeedTimes(mRelCpuSpeedTimes);
+            for (int i = 0; i < mCpuSpeedTimes.length; i++) {
+                long temp = mRelCpuSpeedTimes[i];
+                mRelCpuSpeedTimes[i] -= mCpuSpeedTimes[i];
+                mCpuSpeedTimes[i] = temp;
+            }
+        }
+        return mRelCpuSpeedTimes;
+    }
+
+    private long[] getCpuSpeedTimes(long[] out) {
+        long[] tempTimes = out;
+        long[] tempSpeeds = mCpuSpeeds;
+        final int MAX_SPEEDS = 60;
+        if (out == null) {
+            tempTimes = new long[MAX_SPEEDS]; // Hopefully no more than that
+            tempSpeeds = new long[MAX_SPEEDS];
+        }
+        int speed = 0;
+        String file = readFile("/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state", '\0');
+        // Note: file may be null on kernels without cpufreq (i.e. the emulator's)
+        if (file != null) {
+            StringTokenizer st = new StringTokenizer(file, "\n ");
+            while (st.hasMoreElements()) {
+                String token = st.nextToken();
+                try {
+                    long val = Long.parseLong(token);
+                    tempSpeeds[speed] = val;
+                    token = st.nextToken();
+                    val = Long.parseLong(token);
+                    tempTimes[speed] = val;
+                    speed++;
+                    if (speed == MAX_SPEEDS) break; // No more
+                    if (localLOGV && out == null) {
+                        Slog.v(TAG, "First time : Speed/Time = " + tempSpeeds[speed - 1]
+                              + "\t" + tempTimes[speed - 1]);
+                    }
+                } catch (NumberFormatException nfe) {
+                    Slog.i(TAG, "Unable to parse time_in_state");
+                }
+            }
+        }
+        if (out == null) {
+            out = new long[speed];
+            mCpuSpeeds = new long[speed];
+            System.arraycopy(tempSpeeds, 0, mCpuSpeeds, 0, speed);
+            System.arraycopy(tempTimes, 0, out, 0, speed);
+        }
+        return out;
+    }
+
+    final public int getLastUserTime() {
+        return mRelUserTime;
+    }
+
+    final public int getLastSystemTime() {
+        return mRelSystemTime;
+    }
+
+    final public int getLastIoWaitTime() {
+        return mRelIoWaitTime;
+    }
+
+    final public int getLastIrqTime() {
+        return mRelIrqTime;
+    }
+
+    final public int getLastSoftIrqTime() {
+        return mRelSoftIrqTime;
+    }
+
+    final public int getLastIdleTime() {
+        return mRelIdleTime;
+    }
+
+    final public float getTotalCpuPercent() {
+        int denom = mRelUserTime+mRelSystemTime+mRelIrqTime+mRelIdleTime;
+        if (denom <= 0) {
+            return 0;
+        }
+        return ((float)(mRelUserTime+mRelSystemTime+mRelIrqTime)*100) / denom;
+    }
+
+    final void buildWorkingProcs() {
+        if (!mWorkingProcsSorted) {
+            mWorkingProcs.clear();
+            final int N = mProcStats.size();
+            for (int i=0; i<N; i++) {
+                Stats stats = mProcStats.get(i);
+                if (stats.working) {
+                    mWorkingProcs.add(stats);
+                    if (stats.threadStats != null && stats.threadStats.size() > 1) {
+                        stats.workingThreads.clear();
+                        final int M = stats.threadStats.size();
+                        for (int j=0; j<M; j++) {
+                            Stats tstats = stats.threadStats.get(j);
+                            if (tstats.working) {
+                                stats.workingThreads.add(tstats);
+                            }
+                        }
+                        Collections.sort(stats.workingThreads, sLoadComparator);
+                    }
+                }
+            }
+            Collections.sort(mWorkingProcs, sLoadComparator);
+            mWorkingProcsSorted = true;
+        }
+    }
+
+    final public int countStats() {
+        return mProcStats.size();
+    }
+
+    final public Stats getStats(int index) {
+        return mProcStats.get(index);
+    }
+
+    final public int countWorkingStats() {
+        buildWorkingProcs();
+        return mWorkingProcs.size();
+    }
+
+    final public Stats getWorkingStats(int index) {
+        return mWorkingProcs.get(index);
+    }
+
+    final public String printCurrentLoad() {
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new FastPrintWriter(sw, false, 128);
+        pw.print("Load: ");
+        pw.print(mLoad1);
+        pw.print(" / ");
+        pw.print(mLoad5);
+        pw.print(" / ");
+        pw.println(mLoad15);
+        pw.flush();
+        return sw.toString();
+    }
+
+    final public String printCurrentState(long now) {
+        buildWorkingProcs();
+
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new FastPrintWriter(sw, false, 1024);
+
+        pw.print("CPU usage from ");
+        if (now > mLastSampleTime) {
+            pw.print(now-mLastSampleTime);
+            pw.print("ms to ");
+            pw.print(now-mCurrentSampleTime);
+            pw.print("ms ago");
+        } else {
+            pw.print(mLastSampleTime-now);
+            pw.print("ms to ");
+            pw.print(mCurrentSampleTime-now);
+            pw.print("ms later");
+        }
+
+        long sampleTime = mCurrentSampleTime - mLastSampleTime;
+        long sampleRealTime = mCurrentSampleRealTime - mLastSampleRealTime;
+        long percAwake = sampleRealTime > 0 ? ((sampleTime*100) / sampleRealTime) : 0;
+        if (percAwake != 100) {
+            pw.print(" with ");
+            pw.print(percAwake);
+            pw.print("% awake");
+        }
+        pw.println(":");
+
+        final int totalTime = mRelUserTime + mRelSystemTime + mRelIoWaitTime
+                + mRelIrqTime + mRelSoftIrqTime + mRelIdleTime;
+
+        if (DEBUG) Slog.i(TAG, "totalTime " + totalTime + " over sample time "
+                + (mCurrentSampleTime-mLastSampleTime));
+
+        int N = mWorkingProcs.size();
+        for (int i=0; i<N; i++) {
+            Stats st = mWorkingProcs.get(i);
+            printProcessCPU(pw, st.added ? " +" : (st.removed ? " -": "  "),
+                    st.pid, st.name, (int)(st.rel_uptime+5)/10,
+                    st.rel_utime, st.rel_stime, 0, 0, 0, st.rel_minfaults, st.rel_majfaults);
+            if (!st.removed && st.workingThreads != null) {
+                int M = st.workingThreads.size();
+                for (int j=0; j<M; j++) {
+                    Stats tst = st.workingThreads.get(j);
+                    printProcessCPU(pw,
+                            tst.added ? "   +" : (tst.removed ? "   -": "    "),
+                            tst.pid, tst.name, (int)(st.rel_uptime+5)/10,
+                            tst.rel_utime, tst.rel_stime, 0, 0, 0, 0, 0);
+                }
+            }
+        }
+
+        printProcessCPU(pw, "", -1, "TOTAL", totalTime, mRelUserTime, mRelSystemTime,
+                mRelIoWaitTime, mRelIrqTime, mRelSoftIrqTime, 0, 0);
+
+        pw.flush();
+        return sw.toString();
+    }
+
+    private void printRatio(PrintWriter pw, long numerator, long denominator) {
+        long thousands = (numerator*1000)/denominator;
+        long hundreds = thousands/10;
+        pw.print(hundreds);
+        if (hundreds < 10) {
+            long remainder = thousands - (hundreds*10);
+            if (remainder != 0) {
+                pw.print('.');
+                pw.print(remainder);
+            }
+        }
+    }
+
+    private void printProcessCPU(PrintWriter pw, String prefix, int pid, String label,
+            int totalTime, int user, int system, int iowait, int irq, int softIrq,
+            int minFaults, int majFaults) {
+        pw.print(prefix);
+        if (totalTime == 0) totalTime = 1;
+        printRatio(pw, user+system+iowait+irq+softIrq, totalTime);
+        pw.print("% ");
+        if (pid >= 0) {
+            pw.print(pid);
+            pw.print("/");
+        }
+        pw.print(label);
+        pw.print(": ");
+        printRatio(pw, user, totalTime);
+        pw.print("% user + ");
+        printRatio(pw, system, totalTime);
+        pw.print("% kernel");
+        if (iowait > 0) {
+            pw.print(" + ");
+            printRatio(pw, iowait, totalTime);
+            pw.print("% iowait");
+        }
+        if (irq > 0) {
+            pw.print(" + ");
+            printRatio(pw, irq, totalTime);
+            pw.print("% irq");
+        }
+        if (softIrq > 0) {
+            pw.print(" + ");
+            printRatio(pw, softIrq, totalTime);
+            pw.print("% softirq");
+        }
+        if (minFaults > 0 || majFaults > 0) {
+            pw.print(" / faults:");
+            if (minFaults > 0) {
+                pw.print(" ");
+                pw.print(minFaults);
+                pw.print(" minor");
+            }
+            if (majFaults > 0) {
+                pw.print(" ");
+                pw.print(majFaults);
+                pw.print(" major");
+            }
+        }
+        pw.println();
+    }
+
+    private String readFile(String file, char endChar) {
+        // Permit disk reads here, as /proc/meminfo isn't really "on
+        // disk" and should be fast.  TODO: make BlockGuard ignore
+        // /proc/ and /sys/ files perhaps?
+        StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
+        FileInputStream is = null;
+        try {
+            is = new FileInputStream(file);
+            int len = is.read(mBuffer);
+            is.close();
+
+            if (len > 0) {
+                int i;
+                for (i=0; i<len; i++) {
+                    if (mBuffer[i] == endChar) {
+                        break;
+                    }
+                }
+                return new String(mBuffer, 0, i);
+            }
+        } catch (java.io.FileNotFoundException e) {
+        } catch (java.io.IOException e) {
+        } finally {
+            if (is != null) {
+                try {
+                    is.close();
+                } catch (java.io.IOException e) {
+                }
+            }
+            StrictMode.setThreadPolicy(savedPolicy);
+        }
+        return null;
+    }
+
+    private void getName(Stats st, String cmdlineFile) {
+        String newName = st.name;
+        if (st.name == null || st.name.equals("app_process")
+                || st.name.equals("<pre-initialized>")) {
+            String cmdName = readFile(cmdlineFile, '\0');
+            if (cmdName != null && cmdName.length() > 1) {
+                newName = cmdName;
+                int i = newName.lastIndexOf("/");
+                if (i > 0 && i < newName.length()-1) {
+                    newName = newName.substring(i+1);
+                }
+            }
+            if (newName == null) {
+                newName = st.baseName;
+            }
+        }
+        if (st.name == null || !newName.equals(st.name)) {
+            st.name = newName;
+            st.nameWidth = onMeasureProcessName(st.name);
+        }
+    }
+}
diff --git a/core/java/com/android/internal/os/ProcessStats.java b/core/java/com/android/internal/os/ProcessStats.java
deleted file mode 100644
index b1bb8c1..0000000
--- a/core/java/com/android/internal/os/ProcessStats.java
+++ /dev/null
@@ -1,859 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.os;
-
-import static android.os.Process.*;
-
-import android.os.Process;
-import android.os.StrictMode;
-import android.os.SystemClock;
-import android.util.Slog;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.StringTokenizer;
-
-public class ProcessStats {
-    private static final String TAG = "ProcessStats";
-    private static final boolean DEBUG = false;
-    private static final boolean localLOGV = DEBUG || false;
-    
-    private static final int[] PROCESS_STATS_FORMAT = new int[] {
-        PROC_SPACE_TERM,
-        PROC_SPACE_TERM|PROC_PARENS,
-        PROC_SPACE_TERM,
-        PROC_SPACE_TERM,
-        PROC_SPACE_TERM,
-        PROC_SPACE_TERM,
-        PROC_SPACE_TERM,
-        PROC_SPACE_TERM,
-        PROC_SPACE_TERM,
-        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 9: minor faults
-        PROC_SPACE_TERM,
-        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 11: major faults
-        PROC_SPACE_TERM,
-        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 13: utime
-        PROC_SPACE_TERM|PROC_OUT_LONG                   // 14: stime
-    };
-
-    static final int PROCESS_STAT_MINOR_FAULTS = 0;
-    static final int PROCESS_STAT_MAJOR_FAULTS = 1;
-    static final int PROCESS_STAT_UTIME = 2;
-    static final int PROCESS_STAT_STIME = 3;
-    
-    /** Stores user time and system time in 100ths of a second. */
-    private final long[] mProcessStatsData = new long[4];
-    /** Stores user time and system time in 100ths of a second. */
-    private final long[] mSinglePidStatsData = new long[4];
-
-    private static final int[] PROCESS_FULL_STATS_FORMAT = new int[] {
-        PROC_SPACE_TERM,
-        PROC_SPACE_TERM|PROC_PARENS|PROC_OUT_STRING,    // 1: name
-        PROC_SPACE_TERM,
-        PROC_SPACE_TERM,
-        PROC_SPACE_TERM,
-        PROC_SPACE_TERM,
-        PROC_SPACE_TERM,
-        PROC_SPACE_TERM,
-        PROC_SPACE_TERM,
-        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 9: minor faults
-        PROC_SPACE_TERM,
-        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 11: major faults
-        PROC_SPACE_TERM,
-        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 13: utime
-        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 14: stime
-        PROC_SPACE_TERM,
-        PROC_SPACE_TERM,
-        PROC_SPACE_TERM,
-        PROC_SPACE_TERM,
-        PROC_SPACE_TERM,
-        PROC_SPACE_TERM,
-        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 21: vsize
-    };
-
-    static final int PROCESS_FULL_STAT_MINOR_FAULTS = 1;
-    static final int PROCESS_FULL_STAT_MAJOR_FAULTS = 2;
-    static final int PROCESS_FULL_STAT_UTIME = 3;
-    static final int PROCESS_FULL_STAT_STIME = 4;
-    static final int PROCESS_FULL_STAT_VSIZE = 5;
-
-    private final String[] mProcessFullStatsStringData = new String[6];
-    private final long[] mProcessFullStatsData = new long[6];
-
-    private static final int[] SYSTEM_CPU_FORMAT = new int[] {
-        PROC_SPACE_TERM|PROC_COMBINE,
-        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 1: user time
-        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 2: nice time
-        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 3: sys time
-        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 4: idle time
-        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 5: iowait time
-        PROC_SPACE_TERM|PROC_OUT_LONG,                  // 6: irq time
-        PROC_SPACE_TERM|PROC_OUT_LONG                   // 7: softirq time
-    };
-
-    private final long[] mSystemCpuData = new long[7];
-
-    private static final int[] LOAD_AVERAGE_FORMAT = new int[] {
-        PROC_SPACE_TERM|PROC_OUT_FLOAT,                 // 0: 1 min
-        PROC_SPACE_TERM|PROC_OUT_FLOAT,                 // 1: 5 mins
-        PROC_SPACE_TERM|PROC_OUT_FLOAT                  // 2: 15 mins
-    };
-
-    private final float[] mLoadAverageData = new float[3];
-
-    private final boolean mIncludeThreads;
-    
-    private float mLoad1 = 0;
-    private float mLoad5 = 0;
-    private float mLoad15 = 0;
-    
-    private long mCurrentSampleTime;
-    private long mLastSampleTime;
-    
-    private long mCurrentSampleRealTime;
-    private long mLastSampleRealTime;
-
-    private long mBaseUserTime;
-    private long mBaseSystemTime;
-    private long mBaseIoWaitTime;
-    private long mBaseIrqTime;
-    private long mBaseSoftIrqTime;
-    private long mBaseIdleTime;
-    private int mRelUserTime;
-    private int mRelSystemTime;
-    private int mRelIoWaitTime;
-    private int mRelIrqTime;
-    private int mRelSoftIrqTime;
-    private int mRelIdleTime;
-
-    private int[] mCurPids;
-    private int[] mCurThreadPids;
-    
-    private final ArrayList<Stats> mProcStats = new ArrayList<Stats>();
-    private final ArrayList<Stats> mWorkingProcs = new ArrayList<Stats>();
-    private boolean mWorkingProcsSorted;
-
-    private boolean mFirst = true;
-
-    private byte[] mBuffer = new byte[4096];
-
-    /**
-     * The time in microseconds that the CPU has been running at each speed.
-     */
-    private long[] mCpuSpeedTimes;
-
-    /**
-     * The relative time in microseconds that the CPU has been running at each speed.
-     */
-    private long[] mRelCpuSpeedTimes;
-
-    /**
-     * The different speeds that the CPU can be running at.
-     */
-    private long[] mCpuSpeeds;
-
-    public static class Stats {
-        public final int pid;
-        final String statFile;
-        final String cmdlineFile;
-        final String threadsDir;
-        final ArrayList<Stats> threadStats;
-        final ArrayList<Stats> workingThreads;
-        
-        public boolean interesting;
-
-        public String baseName;
-        public String name;
-        public int nameWidth;
-
-        public long base_uptime;
-        public long rel_uptime;
-
-        public long base_utime;
-        public long base_stime;
-        public int rel_utime;
-        public int rel_stime;
-
-        public long base_minfaults;
-        public long base_majfaults;
-        public int rel_minfaults;
-        public int rel_majfaults;
-        
-        public boolean active;
-        public boolean working;
-        public boolean added;
-        public boolean removed;
-        
-        Stats(int _pid, int parentPid, boolean includeThreads) {
-            pid = _pid;
-            if (parentPid < 0) {
-                final File procDir = new File("/proc", Integer.toString(pid));
-                statFile = new File(procDir, "stat").toString();
-                cmdlineFile = new File(procDir, "cmdline").toString();
-                threadsDir = (new File(procDir, "task")).toString();
-                if (includeThreads) {
-                    threadStats = new ArrayList<Stats>();
-                    workingThreads = new ArrayList<Stats>();
-                } else {
-                    threadStats = null;
-                    workingThreads = null;
-                }
-            } else {
-                final File procDir = new File("/proc", Integer.toString(
-                        parentPid));
-                final File taskDir = new File(
-                        new File(procDir, "task"), Integer.toString(pid));
-                statFile = new File(taskDir, "stat").toString();
-                cmdlineFile = null;
-                threadsDir = null;
-                threadStats = null;
-                workingThreads = null;
-            }
-        }
-    }
-
-    private final static Comparator<Stats> sLoadComparator = new Comparator<Stats>() {
-        public final int
-        compare(Stats sta, Stats stb) {
-            int ta = sta.rel_utime + sta.rel_stime;
-            int tb = stb.rel_utime + stb.rel_stime;
-            if (ta != tb) {
-                return ta > tb ? -1 : 1;
-            }
-            if (sta.added != stb.added) {
-                return sta.added ? -1 : 1;
-            }
-            if (sta.removed != stb.removed) {
-                return sta.added ? -1 : 1;
-            }
-            return 0;
-        }
-    };
-
-
-    public ProcessStats(boolean includeThreads) {
-        mIncludeThreads = includeThreads;
-    }
-    
-    public void onLoadChanged(float load1, float load5, float load15) {
-    }
-    
-    public int onMeasureProcessName(String name) {
-        return 0;
-    }
-    
-    public void init() {
-        if (DEBUG) Slog.v(TAG, "Init: " + this);
-        mFirst = true;
-        update();
-    }
-    
-    public void update() {
-        if (DEBUG) Slog.v(TAG, "Update: " + this);
-        mLastSampleTime = mCurrentSampleTime;
-        mCurrentSampleTime = SystemClock.uptimeMillis();
-        mLastSampleRealTime = mCurrentSampleRealTime;
-        mCurrentSampleRealTime = SystemClock.elapsedRealtime();
-        
-        final long[] sysCpu = mSystemCpuData;
-        if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT,
-                null, sysCpu, null)) {
-            // Total user time is user + nice time.
-            final long usertime = sysCpu[0]+sysCpu[1];
-            // Total system time is simply system time.
-            final long systemtime = sysCpu[2];
-            // Total idle time is simply idle time.
-            final long idletime = sysCpu[3];
-            // Total irq time is iowait + irq + softirq time.
-            final long iowaittime = sysCpu[4];
-            final long irqtime = sysCpu[5];
-            final long softirqtime = sysCpu[6];
-
-            mRelUserTime = (int)(usertime - mBaseUserTime);
-            mRelSystemTime = (int)(systemtime - mBaseSystemTime);
-            mRelIoWaitTime = (int)(iowaittime - mBaseIoWaitTime);
-            mRelIrqTime = (int)(irqtime - mBaseIrqTime);
-            mRelSoftIrqTime = (int)(softirqtime - mBaseSoftIrqTime);
-            mRelIdleTime = (int)(idletime - mBaseIdleTime);
-
-            if (DEBUG) {
-                Slog.i("Load", "Total U:" + sysCpu[0] + " N:" + sysCpu[1]
-                      + " S:" + sysCpu[2] + " I:" + sysCpu[3]
-                      + " W:" + sysCpu[4] + " Q:" + sysCpu[5]
-                      + " O:" + sysCpu[6]);
-                Slog.i("Load", "Rel U:" + mRelUserTime + " S:" + mRelSystemTime
-                      + " I:" + mRelIdleTime + " Q:" + mRelIrqTime);
-            }
-
-            mBaseUserTime = usertime;
-            mBaseSystemTime = systemtime;
-            mBaseIoWaitTime = iowaittime;
-            mBaseIrqTime = irqtime;
-            mBaseSoftIrqTime = softirqtime;
-            mBaseIdleTime = idletime;
-        }
-
-        mCurPids = collectStats("/proc", -1, mFirst, mCurPids, mProcStats);
-
-        final float[] loadAverages = mLoadAverageData;
-        if (Process.readProcFile("/proc/loadavg", LOAD_AVERAGE_FORMAT,
-                null, null, loadAverages)) {
-            float load1 = loadAverages[0];
-            float load5 = loadAverages[1];
-            float load15 = loadAverages[2];
-            if (load1 != mLoad1 || load5 != mLoad5 || load15 != mLoad15) {
-                mLoad1 = load1;
-                mLoad5 = load5;
-                mLoad15 = load15;
-                onLoadChanged(load1, load5, load15);
-            }
-        }
-
-        if (DEBUG) Slog.i(TAG, "*** TIME TO COLLECT STATS: "
-                + (SystemClock.uptimeMillis()-mCurrentSampleTime));
-
-        mWorkingProcsSorted = false;
-        mFirst = false;
-    }    
-    
-    private int[] collectStats(String statsFile, int parentPid, boolean first,
-            int[] curPids, ArrayList<Stats> allProcs) {
-        
-        int[] pids = Process.getPids(statsFile, curPids);
-        int NP = (pids == null) ? 0 : pids.length;
-        int NS = allProcs.size();
-        int curStatsIndex = 0;
-        for (int i=0; i<NP; i++) {
-            int pid = pids[i];
-            if (pid < 0) {
-                NP = pid;
-                break;
-            }
-            Stats st = curStatsIndex < NS ? allProcs.get(curStatsIndex) : null;
-            
-            if (st != null && st.pid == pid) {
-                // Update an existing process...
-                st.added = false;
-                st.working = false;
-                curStatsIndex++;
-                if (DEBUG) Slog.v(TAG, "Existing "
-                        + (parentPid < 0 ? "process" : "thread")
-                        + " pid " + pid + ": " + st);
-
-                if (st.interesting) {
-                    final long uptime = SystemClock.uptimeMillis();
-
-                    final long[] procStats = mProcessStatsData;
-                    if (!Process.readProcFile(st.statFile.toString(),
-                            PROCESS_STATS_FORMAT, null, procStats, null)) {
-                        continue;
-                    }
-                    
-                    final long minfaults = procStats[PROCESS_STAT_MINOR_FAULTS];
-                    final long majfaults = procStats[PROCESS_STAT_MAJOR_FAULTS];
-                    final long utime = procStats[PROCESS_STAT_UTIME];
-                    final long stime = procStats[PROCESS_STAT_STIME];
-
-                    if (utime == st.base_utime && stime == st.base_stime) {
-                        st.rel_utime = 0;
-                        st.rel_stime = 0;
-                        st.rel_minfaults = 0;
-                        st.rel_majfaults = 0;
-                        if (st.active) {
-                            st.active = false;
-                        }
-                        continue;
-                    }
-
-                    if (!st.active) {
-                        st.active = true;
-                    }
-
-                    if (parentPid < 0) {
-                        getName(st, st.cmdlineFile);
-                        if (st.threadStats != null) {
-                            mCurThreadPids = collectStats(st.threadsDir, pid, false,
-                                    mCurThreadPids, st.threadStats);
-                        }
-                    }
-
-                    if (DEBUG) Slog.v("Load", "Stats changed " + st.name + " pid=" + st.pid
-                            + " utime=" + utime + "-" + st.base_utime
-                            + " stime=" + stime + "-" + st.base_stime
-                            + " minfaults=" + minfaults + "-" + st.base_minfaults
-                            + " majfaults=" + majfaults + "-" + st.base_majfaults);
-
-                    st.rel_uptime = uptime - st.base_uptime;
-                    st.base_uptime = uptime;
-                    st.rel_utime = (int)(utime - st.base_utime);
-                    st.rel_stime = (int)(stime - st.base_stime);
-                    st.base_utime = utime;
-                    st.base_stime = stime;
-                    st.rel_minfaults = (int)(minfaults - st.base_minfaults);
-                    st.rel_majfaults = (int)(majfaults - st.base_majfaults);
-                    st.base_minfaults = minfaults;
-                    st.base_majfaults = majfaults;
-                    st.working = true;
-                }
-
-                continue;
-            }
-            
-            if (st == null || st.pid > pid) {
-                // We have a new process!
-                st = new Stats(pid, parentPid, mIncludeThreads);
-                allProcs.add(curStatsIndex, st);
-                curStatsIndex++;
-                NS++;
-                if (DEBUG) Slog.v(TAG, "New "
-                        + (parentPid < 0 ? "process" : "thread")
-                        + " pid " + pid + ": " + st);
-
-                final String[] procStatsString = mProcessFullStatsStringData;
-                final long[] procStats = mProcessFullStatsData;
-                st.base_uptime = SystemClock.uptimeMillis();
-                if (Process.readProcFile(st.statFile.toString(),
-                        PROCESS_FULL_STATS_FORMAT, procStatsString,
-                        procStats, null)) {
-                    // This is a possible way to filter out processes that
-                    // are actually kernel threads...  do we want to?  Some
-                    // of them do use CPU, but there can be a *lot* that are
-                    // not doing anything.
-                    if (true || procStats[PROCESS_FULL_STAT_VSIZE] != 0) {
-                        st.interesting = true;
-                        st.baseName = procStatsString[0];
-                        st.base_minfaults = procStats[PROCESS_FULL_STAT_MINOR_FAULTS];
-                        st.base_majfaults = procStats[PROCESS_FULL_STAT_MAJOR_FAULTS];
-                        st.base_utime = procStats[PROCESS_FULL_STAT_UTIME];
-                        st.base_stime = procStats[PROCESS_FULL_STAT_STIME];
-                    } else {
-                        Slog.i(TAG, "Skipping kernel process pid " + pid
-                                + " name " + procStatsString[0]);
-                        st.baseName = procStatsString[0];
-                    }
-                } else {
-                    Slog.w(TAG, "Skipping unknown process pid " + pid);
-                    st.baseName = "<unknown>";
-                    st.base_utime = st.base_stime = 0;
-                    st.base_minfaults = st.base_majfaults = 0;
-                }
-
-                if (parentPid < 0) {
-                    getName(st, st.cmdlineFile);
-                    if (st.threadStats != null) {
-                        mCurThreadPids = collectStats(st.threadsDir, pid, true,
-                                mCurThreadPids, st.threadStats);
-                    }
-                } else if (st.interesting) {
-                    st.name = st.baseName;
-                    st.nameWidth = onMeasureProcessName(st.name);
-                }
-
-                if (DEBUG) Slog.v("Load", "Stats added " + st.name + " pid=" + st.pid
-                        + " utime=" + st.base_utime + " stime=" + st.base_stime
-                        + " minfaults=" + st.base_minfaults + " majfaults=" + st.base_majfaults);
-                
-                st.rel_utime = 0;
-                st.rel_stime = 0;
-                st.rel_minfaults = 0;
-                st.rel_majfaults = 0;
-                st.added = true;
-                if (!first && st.interesting) {
-                    st.working = true;
-                }
-                continue;
-            }
-                
-            // This process has gone away!
-            st.rel_utime = 0;
-            st.rel_stime = 0;
-            st.rel_minfaults = 0;
-            st.rel_majfaults = 0;
-            st.removed = true;
-            st.working = true;
-            allProcs.remove(curStatsIndex);
-            NS--;
-            if (DEBUG) Slog.v(TAG, "Removed "
-                    + (parentPid < 0 ? "process" : "thread")
-                    + " pid " + pid + ": " + st);
-            // Decrement the loop counter so that we process the current pid
-            // again the next time through the loop.
-            i--;
-            continue;
-        }
-
-        while (curStatsIndex < NS) {
-            // This process has gone away!
-            final Stats st = allProcs.get(curStatsIndex);
-            st.rel_utime = 0;
-            st.rel_stime = 0;
-            st.rel_minfaults = 0;
-            st.rel_majfaults = 0;
-            st.removed = true;
-            st.working = true;
-            allProcs.remove(curStatsIndex);
-            NS--;
-            if (localLOGV) Slog.v(TAG, "Removed pid " + st.pid + ": " + st);
-        }
-        
-        return pids;
-    }
-
-    public long getCpuTimeForPid(int pid) {
-        final String statFile = "/proc/" + pid + "/stat";
-        final long[] statsData = mSinglePidStatsData;
-        if (Process.readProcFile(statFile, PROCESS_STATS_FORMAT,
-                null, statsData, null)) {
-            long time = statsData[PROCESS_STAT_UTIME]
-                    + statsData[PROCESS_STAT_STIME];
-            return time;
-        }
-        return 0;
-    }
-
-    /**
-     * Returns the times spent at each CPU speed, since the last call to this method. If this
-     * is the first time, it will return 1 for each value.
-     * @return relative times spent at different speed steps.
-     */
-    public long[] getLastCpuSpeedTimes() {
-        if (mCpuSpeedTimes == null) {
-            mCpuSpeedTimes = getCpuSpeedTimes(null);
-            mRelCpuSpeedTimes = new long[mCpuSpeedTimes.length];
-            for (int i = 0; i < mCpuSpeedTimes.length; i++) {
-                mRelCpuSpeedTimes[i] = 1; // Initialize
-            }
-        } else {
-            getCpuSpeedTimes(mRelCpuSpeedTimes);
-            for (int i = 0; i < mCpuSpeedTimes.length; i++) {
-                long temp = mRelCpuSpeedTimes[i];
-                mRelCpuSpeedTimes[i] -= mCpuSpeedTimes[i];
-                mCpuSpeedTimes[i] = temp;
-            }
-        }
-        return mRelCpuSpeedTimes;
-    }
-
-    private long[] getCpuSpeedTimes(long[] out) {
-        long[] tempTimes = out;
-        long[] tempSpeeds = mCpuSpeeds;
-        final int MAX_SPEEDS = 60;
-        if (out == null) {
-            tempTimes = new long[MAX_SPEEDS]; // Hopefully no more than that
-            tempSpeeds = new long[MAX_SPEEDS];
-        }
-        int speed = 0;
-        String file = readFile("/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state", '\0');
-        // Note: file may be null on kernels without cpufreq (i.e. the emulator's)
-        if (file != null) {
-            StringTokenizer st = new StringTokenizer(file, "\n ");
-            while (st.hasMoreElements()) {
-                String token = st.nextToken();
-                try {
-                    long val = Long.parseLong(token);
-                    tempSpeeds[speed] = val;
-                    token = st.nextToken();
-                    val = Long.parseLong(token);
-                    tempTimes[speed] = val;
-                    speed++;
-                    if (speed == MAX_SPEEDS) break; // No more
-                    if (localLOGV && out == null) {
-                        Slog.v(TAG, "First time : Speed/Time = " + tempSpeeds[speed - 1]
-                              + "\t" + tempTimes[speed - 1]);
-                    }
-                } catch (NumberFormatException nfe) {
-                    Slog.i(TAG, "Unable to parse time_in_state");
-                }
-            }
-        }
-        if (out == null) {
-            out = new long[speed];
-            mCpuSpeeds = new long[speed];
-            System.arraycopy(tempSpeeds, 0, mCpuSpeeds, 0, speed);
-            System.arraycopy(tempTimes, 0, out, 0, speed);
-        }
-        return out;
-    }
-
-    final public int getLastUserTime() {
-        return mRelUserTime;
-    }
-    
-    final public int getLastSystemTime() {
-        return mRelSystemTime;
-    }
-    
-    final public int getLastIoWaitTime() {
-        return mRelIoWaitTime;
-    }
-    
-    final public int getLastIrqTime() {
-        return mRelIrqTime;
-    }
-    
-    final public int getLastSoftIrqTime() {
-        return mRelSoftIrqTime;
-    }
-    
-    final public int getLastIdleTime() {
-        return mRelIdleTime;
-    }
-    
-    final public float getTotalCpuPercent() {
-        int denom = mRelUserTime+mRelSystemTime+mRelIrqTime+mRelIdleTime;
-        if (denom <= 0) {
-            return 0;
-        }
-        return ((float)(mRelUserTime+mRelSystemTime+mRelIrqTime)*100) / denom;
-    }
-    
-    final void buildWorkingProcs() {
-        if (!mWorkingProcsSorted) {
-            mWorkingProcs.clear();
-            final int N = mProcStats.size();
-            for (int i=0; i<N; i++) {
-                Stats stats = mProcStats.get(i);
-                if (stats.working) {
-                    mWorkingProcs.add(stats);
-                    if (stats.threadStats != null && stats.threadStats.size() > 1) {
-                        stats.workingThreads.clear();
-                        final int M = stats.threadStats.size();
-                        for (int j=0; j<M; j++) {
-                            Stats tstats = stats.threadStats.get(j);
-                            if (tstats.working) {
-                                stats.workingThreads.add(tstats);
-                            }
-                        }
-                        Collections.sort(stats.workingThreads, sLoadComparator);
-                    }
-                }
-            }
-            Collections.sort(mWorkingProcs, sLoadComparator);
-            mWorkingProcsSorted = true;
-        }
-    }
-
-    final public int countStats() {
-        return mProcStats.size();
-    }
-
-    final public Stats getStats(int index) {
-        return mProcStats.get(index);
-    }
-
-    final public int countWorkingStats() {
-        buildWorkingProcs();
-        return mWorkingProcs.size();
-    }
-
-    final public Stats getWorkingStats(int index) {
-        return mWorkingProcs.get(index);
-    }
-    
-    final public String printCurrentLoad() {
-        StringWriter sw = new StringWriter();
-        PrintWriter pw = new PrintWriter(sw);
-        pw.print("Load: ");
-        pw.print(mLoad1);
-        pw.print(" / ");
-        pw.print(mLoad5);
-        pw.print(" / ");
-        pw.println(mLoad15);
-        return sw.toString();
-    }
-
-    final public String printCurrentState(long now) {
-        buildWorkingProcs();
-        
-        StringWriter sw = new StringWriter();
-        PrintWriter pw = new PrintWriter(sw);
-        
-        pw.print("CPU usage from ");
-        if (now > mLastSampleTime) {
-            pw.print(now-mLastSampleTime);
-            pw.print("ms to ");
-            pw.print(now-mCurrentSampleTime);
-            pw.print("ms ago");
-        } else {
-            pw.print(mLastSampleTime-now);
-            pw.print("ms to ");
-            pw.print(mCurrentSampleTime-now);
-            pw.print("ms later");
-        }
-
-        long sampleTime = mCurrentSampleTime - mLastSampleTime;
-        long sampleRealTime = mCurrentSampleRealTime - mLastSampleRealTime;
-        long percAwake = sampleRealTime > 0 ? ((sampleTime*100) / sampleRealTime) : 0;
-        if (percAwake != 100) {
-            pw.print(" with ");
-            pw.print(percAwake);
-            pw.print("% awake");
-        }
-        pw.println(":");
-        
-        final int totalTime = mRelUserTime + mRelSystemTime + mRelIoWaitTime
-                + mRelIrqTime + mRelSoftIrqTime + mRelIdleTime;
-        
-        if (DEBUG) Slog.i(TAG, "totalTime " + totalTime + " over sample time "
-                + (mCurrentSampleTime-mLastSampleTime));
-
-        int N = mWorkingProcs.size();
-        for (int i=0; i<N; i++) {
-            Stats st = mWorkingProcs.get(i);
-            printProcessCPU(pw, st.added ? " +" : (st.removed ? " -": "  "),
-                    st.pid, st.name, (int)(st.rel_uptime+5)/10,
-                    st.rel_utime, st.rel_stime, 0, 0, 0, st.rel_minfaults, st.rel_majfaults);
-            if (!st.removed && st.workingThreads != null) {
-                int M = st.workingThreads.size();
-                for (int j=0; j<M; j++) {
-                    Stats tst = st.workingThreads.get(j);
-                    printProcessCPU(pw,
-                            tst.added ? "   +" : (tst.removed ? "   -": "    "),
-                            tst.pid, tst.name, (int)(st.rel_uptime+5)/10,
-                            tst.rel_utime, tst.rel_stime, 0, 0, 0, 0, 0);
-                }
-            }
-        }
-        
-        printProcessCPU(pw, "", -1, "TOTAL", totalTime, mRelUserTime, mRelSystemTime,
-                mRelIoWaitTime, mRelIrqTime, mRelSoftIrqTime, 0, 0);
-        
-        return sw.toString();
-    }
-    
-    private void printRatio(PrintWriter pw, long numerator, long denominator) {
-        long thousands = (numerator*1000)/denominator;
-        long hundreds = thousands/10;
-        pw.print(hundreds);
-        if (hundreds < 10) {
-            long remainder = thousands - (hundreds*10);
-            if (remainder != 0) {
-                pw.print('.');
-                pw.print(remainder);
-            }
-        }
-    }
-
-    private void printProcessCPU(PrintWriter pw, String prefix, int pid, String label,
-            int totalTime, int user, int system, int iowait, int irq, int softIrq,
-            int minFaults, int majFaults) {
-        pw.print(prefix);
-        if (totalTime == 0) totalTime = 1;
-        printRatio(pw, user+system+iowait+irq+softIrq, totalTime);
-        pw.print("% ");
-        if (pid >= 0) {
-            pw.print(pid);
-            pw.print("/");
-        }
-        pw.print(label);
-        pw.print(": ");
-        printRatio(pw, user, totalTime);
-        pw.print("% user + ");
-        printRatio(pw, system, totalTime);
-        pw.print("% kernel");
-        if (iowait > 0) {
-            pw.print(" + ");
-            printRatio(pw, iowait, totalTime);
-            pw.print("% iowait");
-        }
-        if (irq > 0) {
-            pw.print(" + ");
-            printRatio(pw, irq, totalTime);
-            pw.print("% irq");
-        }
-        if (softIrq > 0) {
-            pw.print(" + ");
-            printRatio(pw, softIrq, totalTime);
-            pw.print("% softirq");
-        }
-        if (minFaults > 0 || majFaults > 0) {
-            pw.print(" / faults:");
-            if (minFaults > 0) {
-                pw.print(" ");
-                pw.print(minFaults);
-                pw.print(" minor");
-            }
-            if (majFaults > 0) {
-                pw.print(" ");
-                pw.print(majFaults);
-                pw.print(" major");
-            }
-        }
-        pw.println();
-    }
-    
-    private String readFile(String file, char endChar) {
-        // Permit disk reads here, as /proc/meminfo isn't really "on
-        // disk" and should be fast.  TODO: make BlockGuard ignore
-        // /proc/ and /sys/ files perhaps?
-        StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
-        FileInputStream is = null;
-        try {
-            is = new FileInputStream(file);
-            int len = is.read(mBuffer);
-            is.close();
-
-            if (len > 0) {
-                int i;
-                for (i=0; i<len; i++) {
-                    if (mBuffer[i] == endChar) {
-                        break;
-                    }
-                }
-                return new String(mBuffer, 0, i);
-            }
-        } catch (java.io.FileNotFoundException e) {
-        } catch (java.io.IOException e) {
-        } finally {
-            if (is != null) {
-                try {
-                    is.close();
-                } catch (java.io.IOException e) {
-                }
-            }
-            StrictMode.setThreadPolicy(savedPolicy);
-        }
-        return null;
-    }
-
-    private void getName(Stats st, String cmdlineFile) {
-        String newName = st.name;
-        if (st.name == null || st.name.equals("app_process")
-                || st.name.equals("<pre-initialized>")) {
-            String cmdName = readFile(cmdlineFile, '\0');
-            if (cmdName != null && cmdName.length() > 1) {
-                newName = cmdName;
-                int i = newName.lastIndexOf("/");
-                if (i > 0 && i < newName.length()-1) {
-                    newName = newName.substring(i+1);
-                }
-            }
-            if (newName == null) {
-                newName = st.baseName;
-            }
-        }
-        if (st.name == null || !newName.equals(st.name)) {
-            st.name = newName;
-            st.nameWidth = onMeasureProcessName(st.name);
-        }
-    }
-}
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index cdd2ad1..5538dca 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -17,6 +17,7 @@
 package com.android.internal.os;
 
 import android.app.ActivityManagerNative;
+import android.app.ActivityThread;
 import android.app.ApplicationErrorReport;
 import android.os.Build;
 import android.os.Debug;
@@ -69,7 +70,14 @@
                 if (mApplicationObject == null) {
                     Slog.e(TAG, "*** FATAL EXCEPTION IN SYSTEM PROCESS: " + t.getName(), e);
                 } else {
-                    Slog.e(TAG, "FATAL EXCEPTION: " + t.getName(), e);
+                    StringBuilder message = new StringBuilder();
+                    message.append("FATAL EXCEPTION: ").append(t.getName()).append("\n");
+                    final String processName = ActivityThread.currentProcessName();
+                    if (processName != null) {
+                        message.append("Process: ").append(processName).append(", ");
+                    }
+                    message.append("PID: ").append(Process.myPid());
+                    Slog.e(TAG, message.toString(), e);
                 }
 
                 // Bring up crash dialog, wait for it to be dismissed
@@ -334,6 +342,7 @@
             }
         } catch (Throwable t2) {
             Slog.e(TAG, "Error reporting WTF", t2);
+            Slog.e(TAG, "Original WTF:", t);
         }
     }
 
diff --git a/core/java/com/android/internal/os/TransferPipe.java b/core/java/com/android/internal/os/TransferPipe.java
new file mode 100644
index 0000000..068d914
--- /dev/null
+++ b/core/java/com/android/internal/os/TransferPipe.java
@@ -0,0 +1,242 @@
+/*
+ * 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.os;
+
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.IInterface;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.util.Slog;
+
+/**
+ * Helper for transferring data through a pipe from a client app.
+ */
+public final class TransferPipe implements Runnable {
+    static final String TAG = "TransferPipe";
+    static final boolean DEBUG = false;
+
+    static final long DEFAULT_TIMEOUT = 5000;  // 5 seconds
+
+    final Thread mThread;;
+    final ParcelFileDescriptor[] mFds;
+
+    FileDescriptor mOutFd;
+    long mEndTime;
+    String mFailure;
+    boolean mComplete;
+
+    String mBufferPrefix;
+
+    interface Caller {
+        void go(IInterface iface, FileDescriptor fd, String prefix,
+                String[] args) throws RemoteException;
+    }
+
+    public TransferPipe() throws IOException {
+        mThread = new Thread(this, "TransferPipe");
+        mFds = ParcelFileDescriptor.createPipe();
+    }
+
+    ParcelFileDescriptor getReadFd() {
+        return mFds[0];
+    }
+
+    public ParcelFileDescriptor getWriteFd() {
+        return mFds[1];
+    }
+
+    public void setBufferPrefix(String prefix) {
+        mBufferPrefix = prefix;
+    }
+
+    static void go(Caller caller, IInterface iface, FileDescriptor out,
+            String prefix, String[] args) throws IOException, RemoteException {
+        go(caller, iface, out, prefix, args, DEFAULT_TIMEOUT);
+    }
+
+    static void go(Caller caller, IInterface iface, FileDescriptor out,
+            String prefix, String[] args, long timeout) throws IOException, RemoteException {
+        if ((iface.asBinder()) instanceof Binder) {
+            // This is a local object...  just call it directly.
+            try {
+                caller.go(iface, out, prefix, args);
+            } catch (RemoteException e) {
+            }
+            return;
+        }
+
+        TransferPipe tp = new TransferPipe();
+        try {
+            caller.go(iface, tp.getWriteFd().getFileDescriptor(), prefix, args);
+            tp.go(out, timeout);
+        } finally {
+            tp.kill();
+        }
+    }
+
+    static void goDump(IBinder binder, FileDescriptor out,
+            String[] args) throws IOException, RemoteException {
+        goDump(binder, out, args, DEFAULT_TIMEOUT);
+    }
+
+    static void goDump(IBinder binder, FileDescriptor out,
+            String[] args, long timeout) throws IOException, RemoteException {
+        if (binder instanceof Binder) {
+            // This is a local object...  just call it directly.
+            try {
+                binder.dump(out, args);
+            } catch (RemoteException e) {
+            }
+            return;
+        }
+
+        TransferPipe tp = new TransferPipe();
+        try {
+            binder.dumpAsync(tp.getWriteFd().getFileDescriptor(), args);
+            tp.go(out, timeout);
+        } finally {
+            tp.kill();
+        }
+    }
+
+    public void go(FileDescriptor out) throws IOException {
+        go(out, DEFAULT_TIMEOUT);
+    }
+
+    public void go(FileDescriptor out, long timeout) throws IOException {
+        try {
+            synchronized (this) {
+                mOutFd = out;
+                mEndTime = SystemClock.uptimeMillis() + timeout;
+
+                if (DEBUG) Slog.i(TAG, "read=" + getReadFd() + " write=" + getWriteFd()
+                        + " out=" + out);
+
+                // Close the write fd, so we know when the other side is done.
+                closeFd(1);
+
+                mThread.start();
+
+                while (mFailure == null && !mComplete) {
+                    long waitTime = mEndTime - SystemClock.uptimeMillis();
+                    if (waitTime <= 0) {
+                        if (DEBUG) Slog.i(TAG, "TIMEOUT!");
+                        mThread.interrupt();
+                        throw new IOException("Timeout");
+                    }
+
+                    try {
+                        wait(waitTime);
+                    } catch (InterruptedException e) {
+                    }
+                }
+
+                if (DEBUG) Slog.i(TAG, "Finished: " + mFailure);
+                if (mFailure != null) {
+                    throw new IOException(mFailure);
+                }
+            }
+        } finally {
+            kill();
+        }
+    }
+
+    void closeFd(int num) {
+        if (mFds[num] != null) {
+            if (DEBUG) Slog.i(TAG, "Closing: " + mFds[num]);
+            try {
+                mFds[num].close();
+            } catch (IOException e) {
+            }
+            mFds[num] = null;
+        }
+    }
+
+    public void kill() {
+        closeFd(0);
+        closeFd(1);
+    }
+
+    @Override
+    public void run() {
+        final byte[] buffer = new byte[1024];
+        final FileInputStream fis = new FileInputStream(getReadFd().getFileDescriptor());
+        final FileOutputStream fos = new FileOutputStream(mOutFd);
+
+        if (DEBUG) Slog.i(TAG, "Ready to read pipe...");
+        byte[] bufferPrefix = null;
+        boolean needPrefix = true;
+        if (mBufferPrefix != null) {
+            bufferPrefix = mBufferPrefix.getBytes();
+        }
+
+        int size;
+        try {
+            while ((size=fis.read(buffer)) > 0) {
+                if (DEBUG) Slog.i(TAG, "Got " + size + " bytes");
+                if (bufferPrefix == null) {
+                    fos.write(buffer, 0, size);
+                } else {
+                    int start = 0;
+                    for (int i=0; i<size; i++) {
+                        if (buffer[i] != '\n') {
+                            if (i > start) {
+                                fos.write(buffer, start, i-start);
+                            }
+                            start = i;
+                            if (needPrefix) {
+                                fos.write(bufferPrefix);
+                                needPrefix = false;
+                            }
+                            do {
+                                i++;
+                            } while (i<size && buffer[i] != '\n');
+                            if (i < size) {
+                                needPrefix = true;
+                            }
+                        }
+                    }
+                    if (size > start) {
+                        fos.write(buffer, start, size-start);
+                    }
+                }
+            }
+            if (DEBUG) Slog.i(TAG, "End of pipe: size=" + size);
+            if (mThread.isInterrupted()) {
+                if (DEBUG) Slog.i(TAG, "Interrupted!");
+            }
+        } catch (IOException e) {
+            synchronized (this) {
+                mFailure = e.toString();
+                notifyAll();
+                return;
+            }
+        }
+
+        synchronized (this) {
+            mComplete = true;
+            notifyAll();
+        }
+    }
+}
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index fb22df7..04351da 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -22,9 +22,11 @@
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.net.LocalServerSocket;
+import android.opengl.EGL14;
 import android.os.Debug;
 import android.os.Process;
 import android.os.SystemClock;
+import android.os.SystemProperties;
 import android.os.Trace;
 import android.util.EventLog;
 import android.util.Log;
@@ -59,9 +61,10 @@
  * @hide
  */
 public class ZygoteInit {
-
     private static final String TAG = "Zygote";
 
+    private static final String PROPERTY_DISABLE_OPENGL_PRELOADING = "ro.zygote.disable_gl_preload";
+
     private static final String ANDROID_SOCKET_ENV = "ANDROID_SOCKET_zygote";
 
     private static final int LOG_BOOT_PROGRESS_PRELOAD_START = 3020;
@@ -227,6 +230,13 @@
     static void preload() {
         preloadClasses();
         preloadResources();
+        preloadOpenGL();
+    }
+
+    private static void preloadOpenGL() {
+        if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false)) {
+            EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
+        }
     }
 
     /**
@@ -479,7 +489,6 @@
             OsConstants.CAP_NET_BIND_SERVICE,
             OsConstants.CAP_NET_BROADCAST,
             OsConstants.CAP_NET_RAW,
-            OsConstants.CAP_SYS_BOOT,
             OsConstants.CAP_SYS_MODULE,
             OsConstants.CAP_SYS_NICE,
             OsConstants.CAP_SYS_RESOURCE,
@@ -490,7 +499,7 @@
         String args[] = {
             "--setuid=1000",
             "--setgid=1000",
-            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006,3007",
+            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1032,3001,3002,3003,3006,3007",
             "--capabilities=" + capabilities + "," + capabilities,
             "--runtime-init",
             "--nice-name=system_server",
diff --git a/core/java/com/android/internal/policy/IKeyguardExitCallback.aidl b/core/java/com/android/internal/policy/IKeyguardExitCallback.aidl
new file mode 100644
index 0000000..3702712
--- /dev/null
+++ b/core/java/com/android/internal/policy/IKeyguardExitCallback.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.policy;
+
+oneway interface IKeyguardExitCallback {
+    void onKeyguardExitResult(boolean success);
+}
diff --git a/core/java/com/android/internal/policy/IKeyguardService.aidl b/core/java/com/android/internal/policy/IKeyguardService.aidl
new file mode 100644
index 0000000..d1f7fa3
--- /dev/null
+++ b/core/java/com/android/internal/policy/IKeyguardService.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.policy;
+
+import com.android.internal.policy.IKeyguardShowCallback;
+import com.android.internal.policy.IKeyguardExitCallback;
+
+import android.os.Bundle;
+
+interface IKeyguardService {
+    boolean isShowing();
+    boolean isSecure();
+    boolean isShowingAndNotHidden();
+    boolean isInputRestricted();
+    boolean isDismissable();
+    oneway void verifyUnlock(IKeyguardExitCallback callback);
+    oneway void keyguardDone(boolean authenticated, boolean wakeup);
+    oneway void setHidden(boolean isHidden);
+    oneway void dismiss();
+    oneway void onDreamingStarted();
+    oneway void onDreamingStopped();
+    oneway void onScreenTurnedOff(int reason);
+    oneway void onScreenTurnedOn(IKeyguardShowCallback callback);
+    oneway void setKeyguardEnabled(boolean enabled);
+    oneway void onSystemReady();
+    oneway void doKeyguardTimeout(in Bundle options);
+    oneway void setCurrentUser(int userId);
+    oneway void showAssistant();
+}
diff --git a/core/java/com/android/internal/policy/IKeyguardShowCallback.aidl b/core/java/com/android/internal/policy/IKeyguardShowCallback.aidl
new file mode 100644
index 0000000..a2784d9
--- /dev/null
+++ b/core/java/com/android/internal/policy/IKeyguardShowCallback.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.policy;
+
+oneway interface IKeyguardShowCallback {
+    void onShown(IBinder windowToken);
+}
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index 58b15e2..d1d1a52 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -38,5 +38,6 @@
     void toggleRecentApps();
     void preloadRecentApps();
     void cancelPreloadRecentApps();
+    void setWindowState(int window, int state);
 }
 
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index c98ba8d..97ea7d8 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -51,4 +51,5 @@
     void toggleRecentApps();
     void preloadRecentApps();
     void cancelPreloadRecentApps();
+    void setWindowState(int window, int state);
 }
diff --git a/core/java/com/android/internal/transition/ActionBarTransition.java b/core/java/com/android/internal/transition/ActionBarTransition.java
new file mode 100644
index 0000000..de59728
--- /dev/null
+++ b/core/java/com/android/internal/transition/ActionBarTransition.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.internal.transition;
+
+import android.transition.ChangeBounds;
+import android.transition.Fade;
+import android.transition.TextChange;
+import android.transition.Transition;
+import android.transition.TransitionSet;
+
+public class ActionBarTransition {
+
+    private static final int TRANSITION_DURATION = 120; // ms
+
+    private static final Transition sTransition;
+
+    static {
+        final TextChange tc = new TextChange();
+        tc.setChangeBehavior(TextChange.CHANGE_BEHAVIOR_OUT_IN);
+        final TransitionSet inner = new TransitionSet();
+        inner.addTransition(tc).addTransition(new ChangeBounds());
+        final TransitionSet tg = new TransitionSet();
+        tg.addTransition(new Fade(Fade.OUT)).addTransition(inner).addTransition(new Fade(Fade.IN));
+        tg.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+        tg.setDuration(TRANSITION_DURATION);
+        sTransition = tg;
+    }
+
+    public static Transition getActionBarTransition() {
+        return sTransition;
+    }
+}
diff --git a/core/java/com/android/internal/util/DumpUtils.java b/core/java/com/android/internal/util/DumpUtils.java
index 7b8c582..65b56ec 100644
--- a/core/java/com/android/internal/util/DumpUtils.java
+++ b/core/java/com/android/internal/util/DumpUtils.java
@@ -40,7 +40,7 @@
         if (handler.runWithScissors(new Runnable() {
             @Override
             public void run() {
-                PrintWriter lpw = new PrintWriter(sw);
+                PrintWriter lpw = new FastPrintWriter(sw);
                 dump.dump(lpw);
                 lpw.close();
             }
diff --git a/core/java/com/android/internal/util/FastPrintWriter.java b/core/java/com/android/internal/util/FastPrintWriter.java
new file mode 100644
index 0000000..9bec10e
--- /dev/null
+++ b/core/java/com/android/internal/util/FastPrintWriter.java
@@ -0,0 +1,600 @@
+package com.android.internal.util;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CoderResult;
+import java.nio.charset.CodingErrorAction;
+
+public class FastPrintWriter extends PrintWriter {
+    private static Writer sDummyWriter = new Writer() {
+        @Override
+        public void close() throws IOException {
+            UnsupportedOperationException ex
+                    = new UnsupportedOperationException("Shouldn't be here");
+            throw ex;
+        }
+
+        @Override
+        public void flush() throws IOException {
+            close();
+        }
+
+        @Override
+        public void write(char[] buf, int offset, int count) throws IOException {
+            close();
+        }
+    };
+
+    private final int mBufferLen;
+    private final char[] mText;
+    private int mPos;
+
+    final private OutputStream mOutputStream;
+    final private boolean mAutoFlush;
+    final private String mSeparator;
+
+    final private Writer mWriter;
+
+    private CharsetEncoder mCharset;
+    final private ByteBuffer mBytes;
+
+    private boolean mIoError;
+
+    /**
+     * Constructs a new {@code PrintWriter} with {@code out} as its target
+     * stream. By default, the new print writer does not automatically flush its
+     * contents to the target stream when a newline is encountered.
+     *
+     * @param out
+     *            the target output stream.
+     * @throws NullPointerException
+     *             if {@code out} is {@code null}.
+     */
+    public FastPrintWriter(OutputStream out) {
+        this(out, false, 8192);
+    }
+
+    /**
+     * Constructs a new {@code PrintWriter} with {@code out} as its target
+     * stream. The parameter {@code autoFlush} determines if the print writer
+     * automatically flushes its contents to the target stream when a newline is
+     * encountered.
+     *
+     * @param out
+     *            the target output stream.
+     * @param autoFlush
+     *            indicates whether contents are flushed upon encountering a
+     *            newline sequence.
+     * @throws NullPointerException
+     *             if {@code out} is {@code null}.
+     */
+    public FastPrintWriter(OutputStream out, boolean autoFlush) {
+        this(out, autoFlush, 8192);
+    }
+
+    /**
+     * Constructs a new {@code PrintWriter} with {@code out} as its target
+     * stream and a custom buffer size. The parameter {@code autoFlush} determines
+     * if the print writer automatically flushes its contents to the target stream
+     * when a newline is encountered.
+     *
+     * @param out
+     *            the target output stream.
+     * @param autoFlush
+     *            indicates whether contents are flushed upon encountering a
+     *            newline sequence.
+     * @param bufferLen
+     *            specifies the size of the FastPrintWriter's internal buffer; the
+     *            default is 8192.
+     * @throws NullPointerException
+     *             if {@code out} is {@code null}.
+     */
+    public FastPrintWriter(OutputStream out, boolean autoFlush, int bufferLen) {
+        super(sDummyWriter, autoFlush);
+        if (out == null) {
+            throw new NullPointerException("out is null");
+        }
+        mBufferLen = bufferLen;
+        mText = new char[bufferLen];
+        mBytes = ByteBuffer.allocate(mBufferLen);
+        mOutputStream = out;
+        mWriter = null;
+        mAutoFlush = autoFlush;
+        mSeparator = System.lineSeparator();
+        initDefaultEncoder();
+    }
+
+    /**
+     * Constructs a new {@code PrintWriter} with {@code wr} as its target
+     * writer. By default, the new print writer does not automatically flush its
+     * contents to the target writer when a newline is encountered.
+     *
+     * <p>NOTE: Unlike PrintWriter, this version will still do buffering inside of
+     * FastPrintWriter before sending data to the Writer.  This means you must call
+     * flush() before retrieving any data from the Writer.</p>
+     *
+     * @param wr
+     *            the target writer.
+     * @throws NullPointerException
+     *             if {@code wr} is {@code null}.
+     */
+    public FastPrintWriter(Writer wr) {
+        this(wr, false, 8192);
+    }
+
+    /**
+     * Constructs a new {@code PrintWriter} with {@code out} as its target
+     * writer. The parameter {@code autoFlush} determines if the print writer
+     * automatically flushes its contents to the target writer when a newline is
+     * encountered.
+     *
+     * @param wr
+     *            the target writer.
+     * @param autoFlush
+     *            indicates whether to flush contents upon encountering a
+     *            newline sequence.
+     * @throws NullPointerException
+     *             if {@code out} is {@code null}.
+     */
+    public FastPrintWriter(Writer wr, boolean autoFlush) {
+        this(wr, autoFlush, 8192);
+    }
+
+    /**
+     * Constructs a new {@code PrintWriter} with {@code out} as its target
+     * writer and a custom buffer size. The parameter {@code autoFlush} determines
+     * if the print writer automatically flushes its contents to the target writer
+     * when a newline is encountered.
+     *
+     * @param wr
+     *            the target writer.
+     * @param autoFlush
+     *            indicates whether to flush contents upon encountering a
+     *            newline sequence.
+     * @param bufferLen
+     *            specifies the size of the FastPrintWriter's internal buffer; the
+     *            default is 8192.
+     * @throws NullPointerException
+     *             if {@code wr} is {@code null}.
+     */
+    public FastPrintWriter(Writer wr, boolean autoFlush, int bufferLen) {
+        super(sDummyWriter, autoFlush);
+        if (wr == null) {
+            throw new NullPointerException("wr is null");
+        }
+        mBufferLen = bufferLen;
+        mText = new char[bufferLen];
+        mBytes = null;
+        mOutputStream = null;
+        mWriter = wr;
+        mAutoFlush = autoFlush;
+        mSeparator = System.lineSeparator();
+        initDefaultEncoder();
+    }
+
+    private final void initEncoder(String csn) throws UnsupportedEncodingException {
+        try {
+            mCharset = Charset.forName(csn).newEncoder();
+        } catch (Exception e) {
+            throw new UnsupportedEncodingException(csn);
+        }
+        mCharset.onMalformedInput(CodingErrorAction.REPLACE);
+        mCharset.onUnmappableCharacter(CodingErrorAction.REPLACE);
+    }
+
+    /**
+     * Flushes this writer and returns the value of the error flag.
+     *
+     * @return {@code true} if either an {@code IOException} has been thrown
+     *         previously or if {@code setError()} has been called;
+     *         {@code false} otherwise.
+     * @see #setError()
+     */
+    public boolean checkError() {
+        flush();
+        synchronized (lock) {
+            return mIoError;
+        }
+    }
+
+    /**
+     * Sets the error state of the stream to false.
+     * @since 1.6
+     */
+    protected void clearError() {
+        synchronized (lock) {
+            mIoError = false;
+        }
+    }
+
+    /**
+     * Sets the error flag of this writer to true.
+     */
+    protected void setError() {
+        synchronized (lock) {
+            mIoError = true;
+        }
+    }
+
+    private final void initDefaultEncoder() {
+        mCharset = Charset.defaultCharset().newEncoder();
+        mCharset.onMalformedInput(CodingErrorAction.REPLACE);
+        mCharset.onUnmappableCharacter(CodingErrorAction.REPLACE);
+    }
+
+    private void appendLocked(char c) throws IOException {
+        int pos = mPos;
+        if (pos >= (mBufferLen-1)) {
+            flushLocked();
+            pos = mPos;
+        }
+        mText[pos] = c;
+        mPos = pos+1;
+    }
+
+    private void appendLocked(String str, int i, final int length) throws IOException {
+        final int BUFFER_LEN = mBufferLen;
+        if (length > BUFFER_LEN) {
+            final int end = i + length;
+            while (i < end) {
+                int next = i + BUFFER_LEN;
+                appendLocked(str, i, next < end ? BUFFER_LEN : (end - i));
+                i = next;
+            }
+            return;
+        }
+        int pos = mPos;
+        if ((pos+length) > BUFFER_LEN) {
+            flushLocked();
+            pos = mPos;
+        }
+        str.getChars(i, i + length, mText, pos);
+        mPos = pos + length;
+    }
+
+    private void appendLocked(char[] buf, int i, final int length) throws IOException {
+        final int BUFFER_LEN = mBufferLen;
+        if (length > BUFFER_LEN) {
+            final int end = i + length;
+            while (i < end) {
+                int next = i + BUFFER_LEN;
+                appendLocked(buf, i, next < end ? BUFFER_LEN : (end - i));
+                i = next;
+            }
+            return;
+        }
+        int pos = mPos;
+        if ((pos+length) > BUFFER_LEN) {
+            flushLocked();
+            pos = mPos;
+        }
+        System.arraycopy(buf, i, mText, pos, length);
+        mPos = pos + length;
+    }
+
+    private void flushBytesLocked() throws IOException {
+        int position;
+        if ((position = mBytes.position()) > 0) {
+            mBytes.flip();
+            mOutputStream.write(mBytes.array(), 0, position);
+            mBytes.clear();
+        }
+    }
+
+    private void flushLocked() throws IOException {
+        //Log.i("PackageManager", "flush mPos=" + mPos);
+        if (mPos > 0) {
+            if (mOutputStream != null) {
+                CharBuffer charBuffer = CharBuffer.wrap(mText, 0, mPos);
+                CoderResult result = mCharset.encode(charBuffer, mBytes, true);
+                while (true) {
+                    if (result.isError()) {
+                        throw new IOException(result.toString());
+                    } else if (result.isOverflow()) {
+                        flushBytesLocked();
+                        result = mCharset.encode(charBuffer, mBytes, true);
+                        continue;
+                    }
+                    break;
+                }
+                flushBytesLocked();
+                mOutputStream.flush();
+            } else {
+                mWriter.write(mText, 0, mPos);
+                mWriter.flush();
+            }
+            mPos = 0;
+        }
+    }
+
+    /**
+     * Ensures that all pending data is sent out to the target. It also
+     * flushes the target. If an I/O error occurs, this writer's error
+     * state is set to {@code true}.
+     */
+    @Override
+    public void flush() {
+        synchronized (lock) {
+            try {
+                flushLocked();
+                if (mOutputStream != null) {
+                    mOutputStream.flush();
+                } else {
+                    mWriter.flush();
+                }
+            } catch (IOException e) {
+                setError();
+            }
+        }
+    }
+
+    @Override
+    public void close() {
+        synchronized (lock) {
+            try {
+                flushLocked();
+                if (mOutputStream != null) {
+                    mOutputStream.close();
+                } else {
+                    mWriter.close();
+                }
+            } catch (IOException e) {
+                setError();
+            }
+        }
+    }
+
+    /**
+     * Prints the string representation of the specified character array
+     * to the target.
+     *
+     * @param charArray
+     *            the character array to print to the target.
+     * @see #print(String)
+     */
+    public void print(char[] charArray) {
+        synchronized (lock) {
+            try {
+                appendLocked(charArray, 0, charArray.length);
+            } catch (IOException e) {
+            }
+        }
+    }
+
+    /**
+     * Prints the string representation of the specified character to the
+     * target.
+     *
+     * @param ch
+     *            the character to print to the target.
+     * @see #print(String)
+     */
+    public void print(char ch) {
+        synchronized (lock) {
+            try {
+                appendLocked(ch);
+            } catch (IOException e) {
+            }
+        }
+    }
+
+    /**
+     * Prints a string to the target. The string is converted to an array of
+     * bytes using the encoding chosen during the construction of this writer.
+     * The bytes are then written to the target with {@code write(int)}.
+     * <p>
+     * If an I/O error occurs, this writer's error flag is set to {@code true}.
+     *
+     * @param str
+     *            the string to print to the target.
+     * @see #write(int)
+     */
+    public void print(String str) {
+        if (str == null) {
+            str = String.valueOf((Object) null);
+        }
+        synchronized (lock) {
+            try {
+                appendLocked(str, 0, str.length());
+            } catch (IOException e) {
+                setError();
+            }
+        }
+    }
+
+
+    @Override
+    public void print(int inum) {
+        if (inum == 0) {
+            print("0");
+        } else {
+            super.print(inum);
+        }
+    }
+
+    @Override
+    public void print(long lnum) {
+        if (lnum == 0) {
+            print("0");
+        } else {
+            super.print(lnum);
+        }
+    }
+
+    /**
+     * Prints a newline. Flushes this writer if the autoFlush flag is set to {@code true}.
+     */
+    public void println() {
+        synchronized (lock) {
+            try {
+                appendLocked(mSeparator, 0, mSeparator.length());
+                if (mAutoFlush) {
+                    flushLocked();
+                }
+            } catch (IOException e) {
+                setError();
+            }
+        }
+    }
+
+    @Override
+    public void println(int inum) {
+        if (inum == 0) {
+            println("0");
+        } else {
+            super.println(inum);
+        }
+    }
+
+    @Override
+    public void println(long lnum) {
+        if (lnum == 0) {
+            println("0");
+        } else {
+            super.println(lnum);
+        }
+    }
+
+    /**
+     * Prints the string representation of the character array {@code chars} followed by a newline.
+     * Flushes this writer if the autoFlush flag is set to {@code true}.
+     */
+    public void println(char[] chars) {
+        print(chars);
+        println();
+    }
+
+    /**
+     * Prints the string representation of the char {@code c} followed by a newline.
+     * Flushes this writer if the autoFlush flag is set to {@code true}.
+     */
+    public void println(char c) {
+        print(c);
+        println();
+    }
+
+    /**
+     * Writes {@code count} characters from {@code buffer} starting at {@code
+     * offset} to the target.
+     * <p>
+     * This writer's error flag is set to {@code true} if this writer is closed
+     * or an I/O error occurs.
+     *
+     * @param buf
+     *            the buffer to write to the target.
+     * @param offset
+     *            the index of the first character in {@code buffer} to write.
+     * @param count
+     *            the number of characters in {@code buffer} to write.
+     * @throws IndexOutOfBoundsException
+     *             if {@code offset < 0} or {@code count < 0}, or if {@code
+     *             offset + count} is greater than the length of {@code buf}.
+     */
+    @Override
+    public void write(char[] buf, int offset, int count) {
+        synchronized (lock) {
+            try {
+                appendLocked(buf, offset, count);
+            } catch (IOException e) {
+            }
+        }
+    }
+
+    /**
+     * Writes one character to the target. Only the two least significant bytes
+     * of the integer {@code oneChar} are written.
+     * <p>
+     * This writer's error flag is set to {@code true} if this writer is closed
+     * or an I/O error occurs.
+     *
+     * @param oneChar
+     *            the character to write to the target.
+     */
+    @Override
+    public void write(int oneChar) {
+        synchronized (lock) {
+            try {
+                appendLocked((char) oneChar);
+            } catch (IOException e) {
+            }
+        }
+    }
+
+    /**
+     * Writes the characters from the specified string to the target.
+     *
+     * @param str
+     *            the non-null string containing the characters to write.
+     */
+    @Override
+    public void write(String str) {
+        synchronized (lock) {
+            try {
+                appendLocked(str, 0, str.length());
+            } catch (IOException e) {
+            }
+        }
+    }
+
+    /**
+     * Writes {@code count} characters from {@code str} starting at {@code
+     * offset} to the target.
+     *
+     * @param str
+     *            the non-null string containing the characters to write.
+     * @param offset
+     *            the index of the first character in {@code str} to write.
+     * @param count
+     *            the number of characters from {@code str} to write.
+     * @throws IndexOutOfBoundsException
+     *             if {@code offset < 0} or {@code count < 0}, or if {@code
+     *             offset + count} is greater than the length of {@code str}.
+     */
+    @Override
+    public void write(String str, int offset, int count) {
+        synchronized (lock) {
+            try {
+                appendLocked(str, offset, count);
+            } catch (IOException e) {
+            }
+        }
+    }
+
+    /**
+     * Appends a subsequence of the character sequence {@code csq} to the
+     * target. This method works the same way as {@code
+     * PrintWriter.print(csq.subsequence(start, end).toString())}. If {@code
+     * csq} is {@code null}, then the specified subsequence of the string "null"
+     * will be written to the target.
+     *
+     * @param csq
+     *            the character sequence appended to the target.
+     * @param start
+     *            the index of the first char in the character sequence appended
+     *            to the target.
+     * @param end
+     *            the index of the character following the last character of the
+     *            subsequence appended to the target.
+     * @return this writer.
+     * @throws StringIndexOutOfBoundsException
+     *             if {@code start > end}, {@code start < 0}, {@code end < 0} or
+     *             either {@code start} or {@code end} are greater or equal than
+     *             the length of {@code csq}.
+     */
+    @Override
+    public PrintWriter append(CharSequence csq, int start, int end) {
+        if (csq == null) {
+            csq = "null";
+        }
+        String output = csq.subSequence(start, end).toString();
+        write(output, 0, output.length());
+        return this;
+    }
+}
diff --git a/core/java/com/android/internal/util/IndentingPrintWriter.java b/core/java/com/android/internal/util/IndentingPrintWriter.java
index d01a817..6fddd09 100644
--- a/core/java/com/android/internal/util/IndentingPrintWriter.java
+++ b/core/java/com/android/internal/util/IndentingPrintWriter.java
@@ -68,6 +68,10 @@
         print(key + "=" + String.valueOf(value) + " ");
     }
 
+    public void printHexPair(String key, int value) {
+        print(key + "=0x" + Integer.toHexString(value) + " ");
+    }
+
     @Override
     public void write(char[] buf, int offset, int count) {
         final int indentLength = mIndentBuilder.length();
diff --git a/core/java/com/android/internal/util/MemInfoReader.java b/core/java/com/android/internal/util/MemInfoReader.java
index 850e1f0..ad65433 100644
--- a/core/java/com/android/internal/util/MemInfoReader.java
+++ b/core/java/com/android/internal/util/MemInfoReader.java
@@ -18,6 +18,7 @@
 
 import java.io.FileInputStream;
 
+import android.os.Debug;
 import android.os.StrictMode;
 
 public class MemInfoReader {
@@ -63,34 +64,11 @@
         // /proc/ and /sys/ files perhaps?
         StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
         try {
-            mTotalSize = 0;
-            mFreeSize = 0;
-            mCachedSize = 0;
-            FileInputStream is = new FileInputStream("/proc/meminfo");
-            int len = is.read(mBuffer);
-            is.close();
-            final int BUFLEN = mBuffer.length;
-            int count = 0;
-            for (int i=0; i<len && count < 3; i++) {
-                if (matchText(mBuffer, i, "MemTotal")) {
-                    i += 8;
-                    mTotalSize = extractMemValue(mBuffer, i);
-                    count++;
-                } else if (matchText(mBuffer, i, "MemFree")) {
-                    i += 7;
-                    mFreeSize = extractMemValue(mBuffer, i);
-                    count++;
-                } else if (matchText(mBuffer, i, "Cached")) {
-                    i += 6;
-                    mCachedSize = extractMemValue(mBuffer, i);
-                    count++;
-                }
-                while (i < BUFLEN && mBuffer[i] != '\n') {
-                    i++;
-                }
-            }
-        } catch (java.io.FileNotFoundException e) {
-        } catch (java.io.IOException e) {
+            long[] infos = new long[Debug.MEMINFO_COUNT];
+            Debug.getMemInfo(infos);
+            mTotalSize = infos[Debug.MEMINFO_TOTAL] * 1024;
+            mFreeSize = infos[Debug.MEMINFO_FREE] * 1024;
+            mCachedSize = infos[Debug.MEMINFO_CACHED] * 1024;
         } finally {
             StrictMode.setThreadPolicy(savedPolicy);
         }
diff --git a/core/java/com/android/internal/view/ActionBarPolicy.java b/core/java/com/android/internal/view/ActionBarPolicy.java
index cf69a9d..25086c5 100644
--- a/core/java/com/android/internal/view/ActionBarPolicy.java
+++ b/core/java/com/android/internal/view/ActionBarPolicy.java
@@ -45,10 +45,7 @@
     }
 
     public boolean showsOverflowMenuButton() {
-        return !ViewConfiguration.get(mContext).hasPermanentMenuKey() ||
-                ((mContext.getResources().getConfiguration().uiMode &
-                        Configuration.UI_MODE_TYPE_TELEVISION) ==
-                        Configuration.UI_MODE_TYPE_TELEVISION);
+        return true;
     }
 
     public int getEmbeddedMenuWidthLimit() {
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 82b2654..12ced68 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -28,11 +28,13 @@
 /**
  * Public interface to the global input method manager, used by all client
  * applications.
+ * You need to update BridgeIInputMethodManager.java as well when changing
+ * this file.
  */
 interface IInputMethodManager {
     List<InputMethodInfo> getInputMethodList();
     List<InputMethodInfo> getEnabledInputMethodList();
-    List<InputMethodSubtype> getEnabledInputMethodSubtypeList(in InputMethodInfo imi,
+    List<InputMethodSubtype> getEnabledInputMethodSubtypeList(in String imiId,
             boolean allowsImplicitlySelectedSubtypes);
     InputMethodSubtype getLastInputMethodSubtype();
     // TODO: We should change the return type from List to List<Parcelable>
@@ -54,7 +56,7 @@
     InputBindResult windowGainedFocus(in IInputMethodClient client, in IBinder windowToken,
             int controlFlags, int softInputMode, int windowFlags,
             in EditorInfo attribute, IInputContext inputContext);
-            
+
     void showInputMethodPickerFromClient(in IInputMethodClient client);
     void showInputMethodAndSubtypeEnablerFromClient(in IInputMethodClient client, String topId);
     void setInputMethod(in IBinder token, String id);
@@ -69,6 +71,7 @@
     boolean setCurrentInputMethodSubtype(in InputMethodSubtype subtype);
     boolean switchToLastInputMethod(in IBinder token);
     boolean switchToNextInputMethod(in IBinder token, boolean onlyCurrentIme);
+    boolean shouldOfferSwitchingToNextInputMethod(in IBinder token);
     boolean setInputMethodEnabled(String id, boolean enabled);
     oneway void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes);
 }
diff --git a/core/java/com/android/internal/view/RotationPolicy.java b/core/java/com/android/internal/view/RotationPolicy.java
index 95130c8..70e2bfc 100644
--- a/core/java/com/android/internal/view/RotationPolicy.java
+++ b/core/java/com/android/internal/view/RotationPolicy.java
@@ -17,12 +17,13 @@
 package com.android.internal.view;
 
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.AsyncTask;
+import android.os.Build;
 import android.os.Handler;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.Log;
@@ -40,6 +41,21 @@
     }
 
     /**
+     * Gets whether the device supports rotation. In general such a
+     * device has an accelerometer and has the portrait and landscape
+     * features.
+     *
+     * @param context Context for accessing system resources.
+     * @return Whether the device supports rotation.
+     */
+    public static boolean isRotationSupported(Context context) {
+        PackageManager pm = context.getPackageManager();
+        return pm.hasSystemFeature(PackageManager.FEATURE_SENSOR_ACCELEROMETER)
+                && pm.hasSystemFeature(PackageManager.FEATURE_SCREEN_PORTRAIT)
+                && pm.hasSystemFeature(PackageManager.FEATURE_SCREEN_LANDSCAPE);
+    }
+
+    /**
      * Returns true if the device supports the rotation-lock toggle feature
      * in the system UI or system bar.
      *
@@ -48,7 +64,8 @@
      * settings.
      */
     public static boolean isRotationLockToggleSupported(Context context) {
-        return context.getResources().getConfiguration().smallestScreenWidthDp >= 600;
+        return isRotationSupported(context)
+                && context.getResources().getConfiguration().smallestScreenWidthDp >= 600;
     }
 
     /**
diff --git a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
index 4bb6d06..d5ab0f2 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
@@ -16,14 +16,13 @@
 
 package com.android.internal.view.menu;
 
-import com.android.internal.view.ActionBarPolicy;
-import com.android.internal.view.menu.ActionMenuView.ActionMenuChildView;
-
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.transition.Transition;
+import android.transition.TransitionManager;
 import android.util.SparseBooleanArray;
 import android.view.ActionProvider;
 import android.view.MenuItem;
@@ -31,7 +30,13 @@
 import android.view.View;
 import android.view.View.MeasureSpec;
 import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.ImageButton;
+import android.widget.ListPopupWindow;
+import android.widget.ListPopupWindow.ForwardingListener;
+import com.android.internal.transition.ActionBarTransition;
+import com.android.internal.view.ActionBarPolicy;
+import com.android.internal.view.menu.ActionMenuView.ActionMenuChildView;
 
 import java.util.ArrayList;
 
@@ -68,6 +73,8 @@
     final PopupPresenterCallback mPopupPresenterCallback = new PopupPresenterCallback();
     int mOpenSubMenuId;
 
+    private static final Transition sTransition = ActionBarTransition.getActionBarTransition();
+
     public ActionMenuPresenter(Context context) {
         super(context, com.android.internal.R.layout.action_menu_layout,
                 com.android.internal.R.layout.action_menu_item_layout);
@@ -151,16 +158,35 @@
     }
 
     @Override
-    public View getItemView(MenuItemImpl item, View convertView, ViewGroup parent) {
+    public View getItemView(final MenuItemImpl item, View convertView, ViewGroup parent) {
         View actionView = item.getActionView();
         if (actionView == null || item.hasCollapsibleActionView()) {
-            if (!(convertView instanceof ActionMenuItemView)) {
-                convertView = null;
-            }
-            actionView = super.getItemView(item, convertView, parent);
+            // Don't recycle existing item views for action buttons; it interferes with transitions.
+            actionView = super.getItemView(item, null, parent);
         }
         actionView.setVisibility(item.isActionViewExpanded() ? View.GONE : View.VISIBLE);
 
+        if (item.hasSubMenu()) {
+            actionView.setOnTouchListener(new ForwardingListener(actionView) {
+                @Override
+                public ListPopupWindow getPopup() {
+                    return mActionButtonPopup != null ? mActionButtonPopup.getPopup() : null;
+                }
+
+                @Override
+                protected boolean onForwardingStarted() {
+                    return onSubMenuSelected((SubMenuBuilder) item.getSubMenu());
+                }
+
+                @Override
+                protected boolean onForwardingStopped() {
+                    return dismissPopupMenus();
+                }
+            });
+        } else {
+            actionView.setOnTouchListener(null);
+        }
+
         final ActionMenuView menuParent = (ActionMenuView) parent;
         final ViewGroup.LayoutParams lp = actionView.getLayoutParams();
         if (!menuParent.checkLayoutParams(lp)) {
@@ -185,6 +211,10 @@
 
     @Override
     public void updateMenuView(boolean cleared) {
+        final ViewGroup menuViewParent = (ViewGroup) ((View) mMenuView).getParent();
+        if (menuViewParent != null) {
+            TransitionManager.beginDelayedTransition(menuViewParent, sTransition);
+        }
         super.updateMenuView(cleared);
 
         if (mMenu != null) {
@@ -343,6 +373,10 @@
         return mOverflowPopup != null && mOverflowPopup.isShowing();
     }
 
+    public boolean isOverflowMenuShowPending() {
+        return mPostedOpenRunnable != null || isOverflowMenuShowing();
+    }
+
     /**
      * @return true if space has been reserved in the action menu for an overflow item.
      */
@@ -559,6 +593,36 @@
             setFocusable(true);
             setVisibility(VISIBLE);
             setEnabled(true);
+
+            setOnTouchListener(new ForwardingListener(this) {
+                @Override
+                public ListPopupWindow getPopup() {
+                    if (mOverflowPopup == null) {
+                        return null;
+                    }
+
+                    return mOverflowPopup.getPopup();
+                }
+
+                @Override
+                public boolean onForwardingStarted() {
+                    showOverflowMenu();
+                    return true;
+                }
+
+                @Override
+                public boolean onForwardingStopped() {
+                    // Displaying the popup occurs asynchronously, so wait for
+                    // the runnable to finish before deciding whether to stop
+                    // forwarding.
+                    if (mPostedOpenRunnable != null) {
+                        return false;
+                    }
+
+                    hideOverflowMenu();
+                    return true;
+                }
+            });
         }
 
         @Override
@@ -572,10 +636,12 @@
             return true;
         }
 
+        @Override
         public boolean needsDividerBefore() {
             return false;
         }
 
+        @Override
         public boolean needsDividerAfter() {
             return false;
         }
@@ -589,6 +655,12 @@
             }
             super.onMeasure(widthMeasureSpec, heightMeasureSpec);
         }
+
+        @Override
+        public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+            super.onInitializeAccessibilityNodeInfo(info);
+            info.setCanOpenPopup(true);
+        }
     }
 
     private class OverflowPopup extends MenuPopupHelper {
diff --git a/core/java/com/android/internal/view/menu/ListMenuItemView.java b/core/java/com/android/internal/view/menu/ListMenuItemView.java
index df579c6..a2a4acc 100644
--- a/core/java/com/android/internal/view/menu/ListMenuItemView.java
+++ b/core/java/com/android/internal/view/menu/ListMenuItemView.java
@@ -23,6 +23,7 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.CheckBox;
 import android.widget.CompoundButton;
 import android.widget.ImageView;
@@ -269,4 +270,13 @@
         }
         return mInflater;
     }
+
+    @Override
+    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfo(info);
+
+        if (mItemData != null && mItemData.hasSubMenu()) {
+            info.setCanOpenPopup(true);
+        }
+    }
 }
diff --git a/core/java/com/android/internal/view/menu/MenuItemImpl.java b/core/java/com/android/internal/view/menu/MenuItemImpl.java
index 39078ca..4d0a326 100644
--- a/core/java/com/android/internal/view/menu/MenuItemImpl.java
+++ b/core/java/com/android/internal/view/menu/MenuItemImpl.java
@@ -616,7 +616,7 @@
 
     @Override
     public boolean expandActionView() {
-        if ((mShowAsAction & SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW) == 0 || mActionView == null) {
+        if (!hasCollapsibleActionView()) {
             return false;
         }
 
@@ -653,7 +653,13 @@
     }
 
     public boolean hasCollapsibleActionView() {
-        return (mShowAsAction & SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW) != 0 && mActionView != null;
+        if ((mShowAsAction & SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW) != 0) {
+            if (mActionView == null && mActionProvider != null) {
+                mActionView = mActionProvider.onCreateActionView(this);
+            }
+            return mActionView != null;
+        }
+        return false;
     }
 
     public void setActionViewExpanded(boolean isExpanded) {
diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
index cacc86b..dbb78c2 100644
--- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
@@ -18,11 +18,11 @@
 
 import android.content.Context;
 import android.content.res.Resources;
-import android.database.DataSetObserver;
 import android.os.Parcelable;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.MenuItem;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.View.MeasureSpec;
 import android.view.ViewGroup;
@@ -47,23 +47,28 @@
 
     static final int ITEM_LAYOUT = com.android.internal.R.layout.popup_menu_item_layout;
 
-    private Context mContext;
-    private LayoutInflater mInflater;
-    private ListPopupWindow mPopup;
-    private MenuBuilder mMenu;
-    private int mPopupMaxWidth;
+    private final Context mContext;
+    private final LayoutInflater mInflater;
+    private final MenuBuilder mMenu;
+    private final MenuAdapter mAdapter;
+    private final boolean mOverflowOnly;
+    private final int mPopupMaxWidth;
+
     private View mAnchorView;
-    private boolean mOverflowOnly;
+    private ListPopupWindow mPopup;
     private ViewTreeObserver mTreeObserver;
-
-    private MenuAdapter mAdapter;
-
     private Callback mPresenterCallback;
 
     boolean mForceShowIcon;
 
     private ViewGroup mMeasureParent;
 
+    /** Whether the cached content width value is valid. */
+    private boolean mHasContentWidth;
+
+    /** Cached content width from {@link #measureContentWidth}. */
+    private int mContentWidth;
+
     public MenuPopupHelper(Context context, MenuBuilder menu) {
         this(context, menu, null, false);
     }
@@ -77,6 +82,7 @@
         mContext = context;
         mInflater = LayoutInflater.from(context);
         mMenu = menu;
+        mAdapter = new MenuAdapter(mMenu);
         mOverflowOnly = overflowOnly;
 
         final Resources res = context.getResources();
@@ -102,12 +108,14 @@
         }
     }
 
+    public ListPopupWindow getPopup() {
+        return mPopup;
+    }
+
     public boolean tryShow() {
         mPopup = new ListPopupWindow(mContext, null, com.android.internal.R.attr.popupMenuStyle);
         mPopup.setOnDismissListener(this);
         mPopup.setOnItemClickListener(this);
-
-        mAdapter = new MenuAdapter(mMenu);
         mPopup.setAdapter(mAdapter);
         mPopup.setModal(true);
 
@@ -122,7 +130,12 @@
             return false;
         }
 
-        mPopup.setContentWidth(Math.min(measureContentWidth(mAdapter), mPopupMaxWidth));
+        if (!mHasContentWidth) {
+            mContentWidth = measureContentWidth();
+            mHasContentWidth = true;
+        }
+
+        mPopup.setContentWidth(mContentWidth);
         mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
         mPopup.show();
         mPopup.getListView().setOnKeyListener(this);
@@ -164,15 +177,15 @@
         return false;
     }
 
-    private int measureContentWidth(ListAdapter adapter) {
+    private int measureContentWidth() {
         // Menus don't tend to be long, so this is more sane than it looks.
-        int width = 0;
+        int maxWidth = 0;
         View itemView = null;
         int itemType = 0;
-        final int widthMeasureSpec =
-            MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-        final int heightMeasureSpec =
-            MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+
+        final ListAdapter adapter = mAdapter;
+        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);
@@ -180,14 +193,23 @@
                 itemType = positionType;
                 itemView = null;
             }
+
             if (mMeasureParent == null) {
                 mMeasureParent = new FrameLayout(mContext);
             }
+
             itemView = adapter.getView(i, itemView, mMeasureParent);
             itemView.measure(widthMeasureSpec, heightMeasureSpec);
-            width = Math.max(width, itemView.getMeasuredWidth());
+
+            final int itemWidth = itemView.getMeasuredWidth();
+            if (itemWidth >= mPopupMaxWidth) {
+                return mPopupMaxWidth;
+            } else if (itemWidth > maxWidth) {
+                maxWidth = itemWidth;
+            }
         }
-        return width;
+
+        return maxWidth;
     }
 
     @Override
@@ -228,7 +250,11 @@
 
     @Override
     public void updateMenuView(boolean cleared) {
-        if (mAdapter != null) mAdapter.notifyDataSetChanged();
+        mHasContentWidth = false;
+
+        if (mAdapter != null) {
+            mAdapter.notifyDataSetChanged();
+        }
     }
 
     @Override
diff --git a/core/java/com/android/internal/widget/AbsActionBarView.java b/core/java/com/android/internal/widget/AbsActionBarView.java
index ca7f5d0..f3891c7 100644
--- a/core/java/com/android/internal/widget/AbsActionBarView.java
+++ b/core/java/com/android/internal/widget/AbsActionBarView.java
@@ -201,6 +201,13 @@
         return false;
     }
 
+    public boolean isOverflowMenuShowPending() {
+        if (mActionMenuPresenter != null) {
+            return mActionMenuPresenter.isOverflowMenuShowPending();
+        }
+        return false;
+    }
+
     public boolean isOverflowReserved() {
         return mActionMenuPresenter != null && mActionMenuPresenter.isOverflowReserved();
     }
diff --git a/core/java/com/android/internal/widget/ActionBarContainer.java b/core/java/com/android/internal/widget/ActionBarContainer.java
index 6120a09..8a49899 100644
--- a/core/java/com/android/internal/widget/ActionBarContainer.java
+++ b/core/java/com/android/internal/widget/ActionBarContainer.java
@@ -296,23 +296,7 @@
         if (mTabContainer != null && mTabContainer.getVisibility() != GONE) {
             final int containerHeight = getMeasuredHeight();
             final int tabHeight = mTabContainer.getMeasuredHeight();
-
-            if ((mActionBarView.getDisplayOptions() & ActionBar.DISPLAY_SHOW_HOME) == 0) {
-                // Not showing home, put tabs on top.
-                final int count = getChildCount();
-                for (int i = 0; i < count; i++) {
-                    final View child = getChildAt(i);
-
-                    if (child == mTabContainer) continue;
-
-                    if (!mActionBarView.isCollapsed()) {
-                        child.offsetTopAndBottom(tabHeight);
-                    }
-                }
-                mTabContainer.layout(l, 0, r, tabHeight);
-            } else {
-                mTabContainer.layout(l, containerHeight - tabHeight, r, containerHeight);
-            }
+            mTabContainer.layout(l, containerHeight - tabHeight, r, containerHeight);
         }
 
         boolean needsInvalidate = false;
diff --git a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
index f359146..5469b63 100644
--- a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
+++ b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
@@ -16,6 +16,9 @@
 
 package com.android.internal.widget;
 
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
 import android.view.ViewGroup;
 import com.android.internal.app.ActionBarImpl;
 
@@ -31,18 +34,23 @@
  * has request that its layout ignore them.
  */
 public class ActionBarOverlayLayout extends ViewGroup {
+    private static final String TAG = "ActionBarOverlayLayout";
+
     private int mActionBarHeight;
     private ActionBarImpl mActionBar;
     private int mWindowVisibility = View.VISIBLE;
 
     // The main UI elements that we handle the layout of.
     private View mContent;
-    private View mActionBarTop;
     private View mActionBarBottom;
+    private ActionBarContainer mActionBarTop;
 
     // Some interior UI elements.
-    private ActionBarContainer mContainerView;
-    private ActionBarView mActionView;
+    private ActionBarView mActionBarView;
+
+    // Content overlay drawable - generally the action bar's shadow
+    private Drawable mWindowContentOverlay;
+    private boolean mIgnoreWindowContentOverlay;
 
     private boolean mOverlayMode;
     private int mLastSystemUiVisibility;
@@ -53,8 +61,9 @@
     private final Rect mInnerInsets = new Rect();
     private final Rect mLastInnerInsets = new Rect();
 
-    static final int[] mActionBarSizeAttr = new int [] {
-            com.android.internal.R.attr.actionBarSize
+    static final int[] ATTRS = new int [] {
+            com.android.internal.R.attr.actionBarSize,
+            com.android.internal.R.attr.windowContentOverlay
     };
 
     public ActionBarOverlayLayout(Context context) {
@@ -68,14 +77,18 @@
     }
 
     private void init(Context context) {
-        TypedArray ta = getContext().getTheme().obtainStyledAttributes(mActionBarSizeAttr);
+        TypedArray ta = getContext().getTheme().obtainStyledAttributes(ATTRS);
         mActionBarHeight = ta.getDimensionPixelSize(0, 0);
+        mWindowContentOverlay = ta.getDrawable(1);
+        setWillNotDraw(mWindowContentOverlay == null);
         ta.recycle();
+
+        mIgnoreWindowContentOverlay = context.getApplicationInfo().targetSdkVersion <
+                Build.VERSION_CODES.KITKAT;
     }
 
-    public void setActionBar(ActionBarImpl impl, boolean overlayMode) {
+    public void setActionBar(ActionBarImpl impl) {
         mActionBar = impl;
-        mOverlayMode = overlayMode;
         if (getWindowToken() != null) {
             // This is being initialized after being added to a window;
             // make sure to update all state now.
@@ -88,6 +101,18 @@
         }
     }
 
+    public void setOverlayMode(boolean overlayMode) {
+        mOverlayMode = overlayMode;
+
+        /*
+         * Drawing the window content overlay was broken before K so starting to draw it
+         * again unexpectedly will cause artifacts in some apps. They should fix it.
+         */
+        mIgnoreWindowContentOverlay = overlayMode &&
+                getContext().getApplicationInfo().targetSdkVersion <
+                        Build.VERSION_CODES.KITKAT;
+    }
+
     public void setShowingForActionMode(boolean showing) {
         if (showing) {
             // Here's a fun hack: if the status bar is currently being hidden,
@@ -253,7 +278,7 @@
             // we can't depend on the size currently reported by it -- this must remain constant.
             topInset = mActionBarHeight;
             if (mActionBar != null && mActionBar.hasNonEmbeddedTabs()) {
-                View tabs = mContainerView.getTabContainer();
+                View tabs = mActionBarTop.getTabContainer();
                 if (tabs != null) {
                     // If tabs are not embedded, increase space on top to account for them.
                     topInset += mActionBarHeight;
@@ -265,7 +290,7 @@
             topInset = mActionBarTop.getMeasuredHeight();
         }
 
-        if (mActionView.isSplitActionBar()) {
+        if (mActionBarView.isSplitActionBar()) {
             // If action bar is split, adjust bottom insets for it.
             if (mActionBarBottom != null) {
                 if (stable) {
@@ -352,6 +377,18 @@
     }
 
     @Override
+    public void draw(Canvas c) {
+        super.draw(c);
+        if (mWindowContentOverlay != null && !mIgnoreWindowContentOverlay) {
+            final int top = mActionBarTop.getVisibility() == VISIBLE ?
+                    (int) (mActionBarTop.getBottom() + mActionBarTop.getTranslationY() + 0.5f) : 0;
+            mWindowContentOverlay.setBounds(0, top, getWidth(),
+                    top + mWindowContentOverlay.getIntrinsicHeight());
+            mWindowContentOverlay.draw(c);
+        }
+    }
+
+    @Override
     public boolean shouldDelayChildPressedState() {
         return false;
     }
@@ -359,10 +396,9 @@
     void pullChildren() {
         if (mContent == null) {
             mContent = findViewById(com.android.internal.R.id.content);
-            mActionBarTop = findViewById(com.android.internal.R.id.top_action_bar);
-            mContainerView = (ActionBarContainer)findViewById(
+            mActionBarTop = (ActionBarContainer)findViewById(
                     com.android.internal.R.id.action_bar_container);
-            mActionView = (ActionBarView) findViewById(com.android.internal.R.id.action_bar);
+            mActionBarView = (ActionBarView) findViewById(com.android.internal.R.id.action_bar);
             mActionBarBottom = findViewById(com.android.internal.R.id.split_action_bar);
         }
     }
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index dda1a10..969c94ba 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -16,24 +16,12 @@
 
 package com.android.internal.widget;
 
-import com.android.internal.R;
-import com.android.internal.view.menu.ActionMenuItem;
-import com.android.internal.view.menu.ActionMenuPresenter;
-import com.android.internal.view.menu.ActionMenuView;
-import com.android.internal.view.menu.MenuBuilder;
-import com.android.internal.view.menu.MenuItemImpl;
-import com.android.internal.view.menu.MenuPresenter;
-import com.android.internal.view.menu.MenuView;
-import com.android.internal.view.menu.SubMenuBuilder;
-
 import android.animation.LayoutTransition;
 import android.app.ActionBar;
 import android.app.ActionBar.OnNavigationListener;
-import android.app.Activity;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Configuration;
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
@@ -41,8 +29,13 @@
 import android.os.Parcelable;
 import android.text.Layout;
 import android.text.TextUtils;
+import android.transition.ChangeBounds;
+import android.transition.Fade;
+import android.transition.TextChange;
+import android.transition.Transition;
+import android.transition.TransitionManager;
+import android.transition.TransitionSet;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.CollapsibleActionView;
 import android.view.Gravity;
 import android.view.LayoutInflater;
@@ -62,6 +55,16 @@
 import android.widget.Spinner;
 import android.widget.SpinnerAdapter;
 import android.widget.TextView;
+import com.android.internal.R;
+import com.android.internal.transition.ActionBarTransition;
+import com.android.internal.view.menu.ActionMenuItem;
+import com.android.internal.view.menu.ActionMenuPresenter;
+import com.android.internal.view.menu.ActionMenuView;
+import com.android.internal.view.menu.MenuBuilder;
+import com.android.internal.view.menu.MenuItemImpl;
+import com.android.internal.view.menu.MenuPresenter;
+import com.android.internal.view.menu.MenuView;
+import com.android.internal.view.menu.SubMenuBuilder;
 
 /**
  * @hide
@@ -101,7 +104,6 @@
     private LinearLayout mTitleLayout;
     private TextView mTitleView;
     private TextView mSubtitleView;
-    private View mTitleUpView;
     private ViewGroup mUpGoerFive;
 
     private Spinner mSpinner;
@@ -142,6 +144,8 @@
 
     Window.Callback mWindowCallback;
 
+    private final static Transition sTransition = ActionBarTransition.getActionBarTransition();
+
     private final AdapterView.OnItemSelectedListener mNavItemSelectedListener =
             new AdapterView.OnItemSelectedListener() {
         public void onItemSelected(AdapterView parent, View view, int position, long id) {
@@ -188,34 +192,8 @@
                 ActionBar.NAVIGATION_MODE_STANDARD);
         mTitle = a.getText(R.styleable.ActionBar_title);
         mSubtitle = a.getText(R.styleable.ActionBar_subtitle);
-
         mLogo = a.getDrawable(R.styleable.ActionBar_logo);
-        if (mLogo == null) {
-            if (context instanceof Activity) {
-                try {
-                    mLogo = pm.getActivityLogo(((Activity) context).getComponentName());
-                } catch (NameNotFoundException e) {
-                    Log.e(TAG, "Activity component name not found!", e);
-                }
-            }
-            if (mLogo == null) {
-                mLogo = appInfo.loadLogo(pm);
-            }
-        }
-
         mIcon = a.getDrawable(R.styleable.ActionBar_icon);
-        if (mIcon == null) {
-            if (context instanceof Activity) {
-                try {
-                    mIcon = pm.getActivityIcon(((Activity) context).getComponentName());
-                } catch (NameNotFoundException e) {
-                    Log.e(TAG, "Activity component name not found!", e);
-                }
-            }
-            if (mIcon == null) {
-                mIcon = appInfo.loadIcon(pm);
-            }
-        }
 
         final LayoutInflater inflater = LayoutInflater.from(context);
 
@@ -228,7 +206,7 @@
         mHomeLayout = (HomeView) inflater.inflate(homeResId, mUpGoerFive, false);
 
         mExpandedHomeLayout = (HomeView) inflater.inflate(homeResId, mUpGoerFive, false);
-        mExpandedHomeLayout.setUp(true);
+        mExpandedHomeLayout.setShowUp(true);
         mExpandedHomeLayout.setOnClickListener(mExpandedActionViewUpListener);
         mExpandedHomeLayout.setContentDescription(getResources().getText(
                 R.string.action_bar_up_description));
@@ -281,7 +259,6 @@
 
         mTitleView = null;
         mSubtitleView = null;
-        mTitleUpView = null;
         if (mTitleLayout != null && mTitleLayout.getParent() == mUpGoerFive) {
             mUpGoerFive.removeView(mTitleLayout);
         }
@@ -505,6 +482,9 @@
 
     public void setCustomNavigationView(View view) {
         final boolean showCustom = (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0;
+        if (showCustom) {
+            TransitionManager.beginDelayedTransition(this, sTransition);
+        }
         if (mCustomNavView != null && showCustom) {
             removeView(mCustomNavView);
         }
@@ -542,6 +522,7 @@
     }
 
     private void setTitleImpl(CharSequence title) {
+        TransitionManager.beginDelayedTransition(this, sTransition);
         mTitle = title;
         if (mTitleView != null) {
             mTitleView.setText(title);
@@ -561,6 +542,7 @@
     }
 
     public void setSubtitle(CharSequence subtitle) {
+        TransitionManager.beginDelayedTransition(this, sTransition);
         mSubtitle = subtitle;
         if (mSubtitleView != null) {
             mSubtitleView.setText(subtitle);
@@ -641,13 +623,11 @@
         mDisplayOptions = options;
 
         if ((flagsChanged & DISPLAY_RELAYOUT_MASK) != 0) {
-            final boolean showHome = (options & ActionBar.DISPLAY_SHOW_HOME) != 0;
-            final int vis = showHome && mExpandedActionView == null ? VISIBLE : GONE;
-            mHomeLayout.setVisibility(vis);
+            TransitionManager.beginDelayedTransition(this, sTransition);
 
             if ((flagsChanged & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
                 final boolean setUp = (options & ActionBar.DISPLAY_HOME_AS_UP) != 0;
-                mHomeLayout.setUp(setUp);
+                mHomeLayout.setShowUp(setUp);
 
                 // Showing home as up implicitly enables interaction with it.
                 // In honeycomb it was always enabled, so make this transition
@@ -671,11 +651,14 @@
                 }
             }
 
-            if (mTitleLayout != null && (flagsChanged &
-                    (ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_HOME)) != 0) {
-                final boolean homeAsUp = (mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0;
-                mTitleUpView.setVisibility(!showHome ? (homeAsUp ? VISIBLE : INVISIBLE) : GONE);
-            }
+            final boolean showHome = (options & ActionBar.DISPLAY_SHOW_HOME) != 0;
+            final boolean homeAsUp = (mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0;
+            final boolean titleUp = !showHome && homeAsUp;
+            mHomeLayout.setShowIcon(showHome);
+
+            final int homeVis = (showHome || titleUp) && mExpandedActionView == null ?
+                    VISIBLE : GONE;
+            mHomeLayout.setVisibility(homeVis);
 
             if ((flagsChanged & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && mCustomNavView != null) {
                 if ((options & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) {
@@ -729,7 +712,11 @@
     }
 
     public void setIcon(int resId) {
-        setIcon(mContext.getResources().getDrawable(resId));
+        setIcon(resId != 0 ? mContext.getResources().getDrawable(resId) : null);
+    }
+
+    public boolean hasIcon() {
+        return mIcon != null;
     }
 
     public void setLogo(Drawable logo) {
@@ -740,12 +727,17 @@
     }
 
     public void setLogo(int resId) {
-        setLogo(mContext.getResources().getDrawable(resId));
+        setLogo(resId != 0 ? mContext.getResources().getDrawable(resId) : null);
+    }
+
+    public boolean hasLogo() {
+        return mLogo != null;
     }
 
     public void setNavigationMode(int mode) {
         final int oldMode = mNavigationMode;
         if (mode != oldMode) {
+            TransitionManager.beginDelayedTransition(this, sTransition);
             switch (oldMode) {
             case ActionBar.NAVIGATION_MODE_LIST:
                 if (mListNavLayout != null) {
@@ -851,7 +843,6 @@
                     this, false);
             mTitleView = (TextView) mTitleLayout.findViewById(R.id.action_bar_title);
             mSubtitleView = (TextView) mTitleLayout.findViewById(R.id.action_bar_subtitle);
-            mTitleUpView = (View) mTitleLayout.findViewById(R.id.up);
 
             if (mTitleStyleRes != 0) {
                 mTitleView.setTextAppearance(mContext, mTitleStyleRes);
@@ -867,13 +858,9 @@
                 mSubtitleView.setText(mSubtitle);
                 mSubtitleView.setVisibility(VISIBLE);
             }
-
-            final boolean homeAsUp = (mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0;
-            final boolean showHome = (mDisplayOptions & ActionBar.DISPLAY_SHOW_HOME) != 0;
-            final boolean showTitleUp = !showHome;
-            mTitleUpView.setVisibility(showTitleUp ? (homeAsUp ? VISIBLE : INVISIBLE) : GONE);
         }
 
+        TransitionManager.beginDelayedTransition(this, sTransition);
         mUpGoerFive.addView(mTitleLayout);
         if (mExpandedActionView != null ||
                 (TextUtils.isEmpty(mTitle) && TextUtils.isEmpty(mSubtitle))) {
@@ -977,25 +964,32 @@
         int leftOfCenter = availableWidth / 2;
         int rightOfCenter = leftOfCenter;
 
+        final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE &&
+                (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0;
+
         HomeView homeLayout = mExpandedActionView != null ? mExpandedHomeLayout : mHomeLayout;
 
-        int homeWidth = 0;
-        if (homeLayout.getVisibility() != GONE && homeLayout.getParent() == mUpGoerFive) {
-            final ViewGroup.LayoutParams lp = homeLayout.getLayoutParams();
-            int homeWidthSpec;
-            if (lp.width < 0) {
-                homeWidthSpec = MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST);
-            } else {
-                homeWidthSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY);
-            }
+        final ViewGroup.LayoutParams homeLp = homeLayout.getLayoutParams();
+        int homeWidthSpec;
+        if (homeLp.width < 0) {
+            homeWidthSpec = MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST);
+        } else {
+            homeWidthSpec = MeasureSpec.makeMeasureSpec(homeLp.width, MeasureSpec.EXACTLY);
+        }
 
-            /*
-             * This is a little weird.
-             * We're only measuring the *home* affordance within the Up container here
-             * on purpose, because we want to give the available space to all other views before
-             * the title text. We'll remeasure the whole up container again later.
-             */
-            homeLayout.measure(homeWidthSpec, exactHeightSpec);
+        /*
+         * This is a little weird.
+         * We're only measuring the *home* affordance within the Up container here
+         * on purpose, because we want to give the available space to all other views before
+         * the title text. We'll remeasure the whole up container again later.
+         * We need to measure this container so we know the right offset for the up affordance
+         * no matter what.
+         */
+        homeLayout.measure(homeWidthSpec, exactHeightSpec);
+
+        int homeWidth = 0;
+        if ((homeLayout.getVisibility() != GONE && homeLayout.getParent() == mUpGoerFive)
+                || showTitle) {
             homeWidth = homeLayout.getMeasuredWidth();
             final int homeOffsetWidth = homeWidth + homeLayout.getStartOffset();
             availableWidth = Math.max(0, availableWidth - homeOffsetWidth);
@@ -1015,9 +1009,6 @@
                     rightOfCenter - mIndeterminateProgressView.getMeasuredWidth());
         }
 
-        final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE &&
-                (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0;
-
         if (mExpandedActionView == null) {
             switch (mNavigationMode) {
                 case ActionBar.NAVIGATION_MODE_LIST:
@@ -1146,7 +1137,7 @@
         }
 
         final boolean isLayoutRtl = isLayoutRtl();
-        final int direction = isLayoutRtl ? +1 : -1;
+        final int direction = isLayoutRtl ? 1 : -1;
         int menuStart = isLayoutRtl ? getPaddingLeft() : r - l - getPaddingRight();
         // In LTR mode, we start from left padding and go to the right; in RTL mode, we start
         // from the padding right and go to the left (in reverse way)
@@ -1154,8 +1145,16 @@
         final int y = getPaddingTop();
 
         HomeView homeLayout = mExpandedActionView != null ? mExpandedHomeLayout : mHomeLayout;
-        final int startOffset = homeLayout.getVisibility() != GONE &&
-                homeLayout.getParent() == mUpGoerFive ? homeLayout.getStartOffset() : 0;
+        final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE &&
+                (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0;
+        int startOffset = 0;
+        if (homeLayout.getParent() == mUpGoerFive) {
+            if (homeLayout.getVisibility() != GONE) {
+                startOffset = homeLayout.getStartOffset();
+            } else if (showTitle) {
+                startOffset = homeLayout.getUpWidth();
+            }
+        }
 
         // Position the up container based on where the edge of the home layout should go.
         x += positionChild(mUpGoerFive,
@@ -1163,9 +1162,6 @@
         x = next(x, startOffset, isLayoutRtl);
 
         if (mExpandedActionView == null) {
-            final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE &&
-                    (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0;
-
             switch (mNavigationMode) {
                 case ActionBar.NAVIGATION_MODE_STANDARD:
                     break;
@@ -1396,6 +1392,7 @@
         private ImageView mUpView;
         private ImageView mIconView;
         private int mUpWidth;
+        private int mStartOffset;
         private int mUpIndicatorRes;
         private Drawable mDefaultUpIndicator;
 
@@ -1414,10 +1411,14 @@
             }
         }
 
-        public void setUp(boolean isUp) {
+        public void setShowUp(boolean isUp) {
             mUpView.setVisibility(isUp ? VISIBLE : GONE);
         }
 
+        public void setShowIcon(boolean showIcon) {
+            mIconView.setVisibility(showIcon ? VISIBLE : GONE);
+        }
+
         public void setIcon(Drawable icon) {
             mIconView.setImageDrawable(icon);
         }
@@ -1470,21 +1471,33 @@
         }
 
         public int getStartOffset() {
-            return mUpView.getVisibility() == GONE ? mUpWidth : 0;
+            return mUpView.getVisibility() == GONE ? mStartOffset : 0;
+        }
+
+        public int getUpWidth() {
+            return mUpWidth;
         }
 
         @Override
         protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
             measureChildWithMargins(mUpView, widthMeasureSpec, 0, heightMeasureSpec, 0);
             final LayoutParams upLp = (LayoutParams) mUpView.getLayoutParams();
-            mUpWidth = upLp.leftMargin + mUpView.getMeasuredWidth() + upLp.rightMargin;
-            int width = mUpView.getVisibility() == GONE ? 0 : mUpWidth;
+            final int upMargins = upLp.leftMargin + upLp.rightMargin;
+            mUpWidth = mUpView.getMeasuredWidth();
+            mStartOffset = mUpWidth + upMargins;
+            int width = mUpView.getVisibility() == GONE ? 0 : mStartOffset;
             int height = upLp.topMargin + mUpView.getMeasuredHeight() + upLp.bottomMargin;
-            measureChildWithMargins(mIconView, widthMeasureSpec, width, heightMeasureSpec, 0);
-            final LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams();
-            width += iconLp.leftMargin + mIconView.getMeasuredWidth() + iconLp.rightMargin;
-            height = Math.max(height,
-                    iconLp.topMargin + mIconView.getMeasuredHeight() + iconLp.bottomMargin);
+
+            if (mIconView.getVisibility() != GONE) {
+                measureChildWithMargins(mIconView, widthMeasureSpec, width, heightMeasureSpec, 0);
+                final LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams();
+                width += iconLp.leftMargin + mIconView.getMeasuredWidth() + iconLp.rightMargin;
+                height = Math.max(height,
+                        iconLp.topMargin + mIconView.getMeasuredHeight() + iconLp.bottomMargin);
+            } else if (upMargins < 0) {
+                // Remove the measurement effects of negative margins used for offsets
+                width -= upMargins;
+            }
 
             final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
             final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
diff --git a/core/java/com/android/internal/widget/AutoScrollHelper.java b/core/java/com/android/internal/widget/AutoScrollHelper.java
new file mode 100644
index 0000000..7a294aa
--- /dev/null
+++ b/core/java/com/android/internal/widget/AutoScrollHelper.java
@@ -0,0 +1,924 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget;
+
+import android.content.res.Resources;
+import android.os.SystemClock;
+import android.util.DisplayMetrics;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
+import android.widget.AbsListView;
+
+/**
+ * AutoScrollHelper is a utility class for adding automatic edge-triggered
+ * scrolling to Views.
+ * <p>
+ * <b>Note:</b> Implementing classes are responsible for overriding the
+ * {@link #scrollTargetBy}, {@link #canTargetScrollHorizontally}, and
+ * {@link #canTargetScrollVertically} methods. See
+ * {@link AbsListViewAutoScroller} for an {@link android.widget.AbsListView}
+ * -specific implementation.
+ * <p>
+ * <h1>Activation</h1> Automatic scrolling starts when the user touches within
+ * an activation area. By default, activation areas are defined as the top,
+ * left, right, and bottom 20% of the host view's total area. Touching within
+ * the top activation area scrolls up, left scrolls to the left, and so on.
+ * <p>
+ * As the user touches closer to the extreme edge of the activation area,
+ * scrolling accelerates up to a maximum velocity. When using the default edge
+ * type, {@link #EDGE_TYPE_INSIDE_EXTEND}, moving outside of the view bounds
+ * will scroll at the maximum velocity.
+ * <p>
+ * The following activation properties may be configured:
+ * <ul>
+ * <li>Delay after entering activation area before auto-scrolling begins, see
+ * {@link #setActivationDelay}. Default value is
+ * {@link ViewConfiguration#getTapTimeout()} to avoid conflicting with taps.
+ * <li>Location of activation areas, see {@link #setEdgeType}. Default value is
+ * {@link #EDGE_TYPE_INSIDE_EXTEND}.
+ * <li>Size of activation areas relative to view size, see
+ * {@link #setRelativeEdges}. Default value is 20% for both vertical and
+ * horizontal edges.
+ * <li>Maximum size used to constrain relative size, see
+ * {@link #setMaximumEdges}. Default value is {@link #NO_MAX}.
+ * </ul>
+ * <h1>Scrolling</h1> When automatic scrolling is active, the helper will
+ * repeatedly call {@link #scrollTargetBy} to apply new scrolling offsets.
+ * <p>
+ * The following scrolling properties may be configured:
+ * <ul>
+ * <li>Acceleration ramp-up duration, see {@link #setRampUpDuration}. Default
+ * value is 500 milliseconds.
+ * <li>Acceleration ramp-down duration, see {@link #setRampDownDuration}.
+ * Default value is 500 milliseconds.
+ * <li>Target velocity relative to view size, see {@link #setRelativeVelocity}.
+ * Default value is 100% per second for both vertical and horizontal.
+ * <li>Minimum velocity used to constrain relative velocity, see
+ * {@link #setMinimumVelocity}. When set, scrolling will accelerate to the
+ * larger of either this value or the relative target value. Default value is
+ * approximately 5 centimeters or 315 dips per second.
+ * <li>Maximum velocity used to constrain relative velocity, see
+ * {@link #setMaximumVelocity}. Default value is approximately 25 centimeters or
+ * 1575 dips per second.
+ * </ul>
+ */
+public abstract class AutoScrollHelper implements View.OnTouchListener {
+    /**
+     * Constant passed to {@link #setRelativeEdges} or
+     * {@link #setRelativeVelocity}. Using this value ensures that the computed
+     * relative value is ignored and the absolute maximum value is always used.
+     */
+    public static final float RELATIVE_UNSPECIFIED = 0;
+
+    /**
+     * Constant passed to {@link #setMaximumEdges}, {@link #setMaximumVelocity},
+     * or {@link #setMinimumVelocity}. Using this value ensures that the
+     * computed relative value is always used without constraining to a
+     * particular minimum or maximum value.
+     */
+    public static final float NO_MAX = Float.MAX_VALUE;
+
+    /**
+     * Constant passed to {@link #setMaximumEdges}, or
+     * {@link #setMaximumVelocity}, or {@link #setMinimumVelocity}. Using this
+     * value ensures that the computed relative value is always used without
+     * constraining to a particular minimum or maximum value.
+     */
+    public static final float NO_MIN = 0;
+
+    /**
+     * Edge type that specifies an activation area starting at the view bounds
+     * and extending inward. Moving outside the view bounds will stop scrolling.
+     *
+     * @see #setEdgeType
+     */
+    public static final int EDGE_TYPE_INSIDE = 0;
+
+    /**
+     * Edge type that specifies an activation area starting at the view bounds
+     * and extending inward. After activation begins, moving outside the view
+     * bounds will continue scrolling.
+     *
+     * @see #setEdgeType
+     */
+    public static final int EDGE_TYPE_INSIDE_EXTEND = 1;
+
+    /**
+     * Edge type that specifies an activation area starting at the view bounds
+     * and extending outward. Moving inside the view bounds will stop scrolling.
+     *
+     * @see #setEdgeType
+     */
+    public static final int EDGE_TYPE_OUTSIDE = 2;
+
+    private static final int HORIZONTAL = 0;
+    private static final int VERTICAL = 1;
+
+    /** Scroller used to control acceleration toward maximum velocity. */
+    private final ClampedScroller mScroller = new ClampedScroller();
+
+    /** Interpolator used to scale velocity with touch position. */
+    private final Interpolator mEdgeInterpolator = new AccelerateInterpolator();
+
+    /** The view to auto-scroll. Might not be the source of touch events. */
+    private final View mTarget;
+
+    /** Runnable used to animate scrolling. */
+    private Runnable mRunnable;
+
+    /** Edge insets used to activate auto-scrolling. */
+    private float[] mRelativeEdges = new float[] { RELATIVE_UNSPECIFIED, RELATIVE_UNSPECIFIED };
+
+    /** Clamping values for edge insets used to activate auto-scrolling. */
+    private float[] mMaximumEdges = new float[] { NO_MAX, NO_MAX };
+
+    /** The type of edge being used. */
+    private int mEdgeType;
+
+    /** Delay after entering an activation edge before auto-scrolling begins. */
+    private int mActivationDelay;
+
+    /** Relative scrolling velocity at maximum edge distance. */
+    private float[] mRelativeVelocity = new float[] { RELATIVE_UNSPECIFIED, RELATIVE_UNSPECIFIED };
+
+    /** Clamping values used for scrolling velocity. */
+    private float[] mMinimumVelocity = new float[] { NO_MIN, NO_MIN };
+
+    /** Clamping values used for scrolling velocity. */
+    private float[] mMaximumVelocity = new float[] { NO_MAX, NO_MAX };
+
+    /** Whether to start activation immediately. */
+    private boolean mAlreadyDelayed;
+
+    /** Whether to reset the scroller start time on the next animation. */
+    private boolean mNeedsReset;
+
+    /** Whether to send a cancel motion event to the target view. */
+    private boolean mNeedsCancel;
+
+    /** Whether the auto-scroller is actively scrolling. */
+    private boolean mAnimating;
+
+    /** Whether the auto-scroller is enabled. */
+    private boolean mEnabled;
+
+    /** Whether the auto-scroller consumes events when scrolling. */
+    private boolean mExclusive;
+
+    // Default values.
+    private static final int DEFAULT_EDGE_TYPE = EDGE_TYPE_INSIDE_EXTEND;
+    private static final int DEFAULT_MINIMUM_VELOCITY_DIPS = 315;
+    private static final int DEFAULT_MAXIMUM_VELOCITY_DIPS = 1575;
+    private static final float DEFAULT_MAXIMUM_EDGE = NO_MAX;
+    private static final float DEFAULT_RELATIVE_EDGE = 0.2f;
+    private static final float DEFAULT_RELATIVE_VELOCITY = 1f;
+    private static final int DEFAULT_ACTIVATION_DELAY = ViewConfiguration.getTapTimeout();
+    private static final int DEFAULT_RAMP_UP_DURATION = 500;
+    private static final int DEFAULT_RAMP_DOWN_DURATION = 500;
+
+    /**
+     * Creates a new helper for scrolling the specified target view.
+     * <p>
+     * The resulting helper may be configured by chaining setter calls and
+     * should be set as a touch listener on the target view.
+     * <p>
+     * By default, the helper is disabled and will not respond to touch events
+     * until it is enabled using {@link #setEnabled}.
+     *
+     * @param target The view to automatically scroll.
+     */
+    public AutoScrollHelper(View target) {
+        mTarget = target;
+
+        final DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
+        final int maxVelocity = (int) (DEFAULT_MAXIMUM_VELOCITY_DIPS * metrics.density + 0.5f);
+        final int minVelocity = (int) (DEFAULT_MINIMUM_VELOCITY_DIPS * metrics.density + 0.5f);
+        setMaximumVelocity(maxVelocity, maxVelocity);
+        setMinimumVelocity(minVelocity, minVelocity);
+
+        setEdgeType(DEFAULT_EDGE_TYPE);
+        setMaximumEdges(DEFAULT_MAXIMUM_EDGE, DEFAULT_MAXIMUM_EDGE);
+        setRelativeEdges(DEFAULT_RELATIVE_EDGE, DEFAULT_RELATIVE_EDGE);
+        setRelativeVelocity(DEFAULT_RELATIVE_VELOCITY, DEFAULT_RELATIVE_VELOCITY);
+        setActivationDelay(DEFAULT_ACTIVATION_DELAY);
+        setRampUpDuration(DEFAULT_RAMP_UP_DURATION);
+        setRampDownDuration(DEFAULT_RAMP_DOWN_DURATION);
+    }
+
+    /**
+     * Sets whether the scroll helper is enabled and should respond to touch
+     * events.
+     *
+     * @param enabled Whether the scroll helper is enabled.
+     * @return The scroll helper, which may used to chain setter calls.
+     */
+    public AutoScrollHelper setEnabled(boolean enabled) {
+        if (mEnabled && !enabled) {
+            requestStop();
+        }
+
+        mEnabled = enabled;
+        return this;
+    }
+
+    /**
+     * @return True if this helper is enabled and responding to touch events.
+     */
+    public boolean isEnabled() {
+        return mEnabled;
+    }
+
+    /**
+     * Enables or disables exclusive handling of touch events during scrolling.
+     * By default, exclusive handling is disabled and the target view receives
+     * all touch events.
+     * <p>
+     * When enabled, {@link #onTouch} will return true if the helper is
+     * currently scrolling and false otherwise.
+     *
+     * @param exclusive True to exclusively handle touch events during scrolling,
+     *            false to allow the target view to receive all touch events.
+     * @return The scroll helper, which may used to chain setter calls.
+     */
+    public AutoScrollHelper setExclusive(boolean exclusive) {
+        mExclusive = exclusive;
+        return this;
+    }
+
+    /**
+     * Indicates whether the scroll helper handles touch events exclusively
+     * during scrolling.
+     *
+     * @return True if exclusive handling of touch events during scrolling is
+     *         enabled, false otherwise.
+     * @see #setExclusive(boolean)
+     */
+    public boolean isExclusive() {
+        return mExclusive;
+    }
+
+    /**
+     * Sets the absolute maximum scrolling velocity.
+     * <p>
+     * If relative velocity is not specified, scrolling will always reach the
+     * same maximum velocity. If both relative and maximum velocities are
+     * specified, the maximum velocity will be used to clamp the calculated
+     * relative velocity.
+     *
+     * @param horizontalMax The maximum horizontal scrolling velocity, or
+     *            {@link #NO_MAX} to leave the relative value unconstrained.
+     * @param verticalMax The maximum vertical scrolling velocity, or
+     *            {@link #NO_MAX} to leave the relative value unconstrained.
+     * @return The scroll helper, which may used to chain setter calls.
+     */
+    public AutoScrollHelper setMaximumVelocity(float horizontalMax, float verticalMax) {
+        mMaximumVelocity[HORIZONTAL] = horizontalMax / 1000f;
+        mMaximumVelocity[VERTICAL] = verticalMax / 1000f;
+        return this;
+    }
+
+    /**
+     * Sets the absolute minimum scrolling velocity.
+     * <p>
+     * If both relative and minimum velocities are specified, the minimum
+     * velocity will be used to clamp the calculated relative velocity.
+     *
+     * @param horizontalMin The minimum horizontal scrolling velocity, or
+     *            {@link #NO_MIN} to leave the relative value unconstrained.
+     * @param verticalMin The minimum vertical scrolling velocity, or
+     *            {@link #NO_MIN} to leave the relative value unconstrained.
+     * @return The scroll helper, which may used to chain setter calls.
+     */
+    public AutoScrollHelper setMinimumVelocity(float horizontalMin, float verticalMin) {
+        mMinimumVelocity[HORIZONTAL] = horizontalMin / 1000f;
+        mMinimumVelocity[VERTICAL] = verticalMin / 1000f;
+        return this;
+    }
+
+    /**
+     * Sets the target scrolling velocity relative to the host view's
+     * dimensions.
+     * <p>
+     * If both relative and maximum velocities are specified, the maximum
+     * velocity will be used to clamp the calculated relative velocity.
+     *
+     * @param horizontal The target horizontal velocity as a fraction of the
+     *            host view width per second, or {@link #RELATIVE_UNSPECIFIED}
+     *            to ignore.
+     * @param vertical The target vertical velocity as a fraction of the host
+     *            view height per second, or {@link #RELATIVE_UNSPECIFIED} to
+     *            ignore.
+     * @return The scroll helper, which may used to chain setter calls.
+     */
+    public AutoScrollHelper setRelativeVelocity(float horizontal, float vertical) {
+        mRelativeVelocity[HORIZONTAL] = horizontal / 1000f;
+        mRelativeVelocity[VERTICAL] = vertical / 1000f;
+        return this;
+    }
+
+    /**
+     * Sets the activation edge type, one of:
+     * <ul>
+     * <li>{@link #EDGE_TYPE_INSIDE} for edges that respond to touches inside
+     * the bounds of the host view. If touch moves outside the bounds, scrolling
+     * will stop.
+     * <li>{@link #EDGE_TYPE_INSIDE_EXTEND} for inside edges that continued to
+     * scroll when touch moves outside the bounds of the host view.
+     * <li>{@link #EDGE_TYPE_OUTSIDE} for edges that only respond to touches
+     * that move outside the bounds of the host view.
+     * </ul>
+     *
+     * @param type The type of edge to use.
+     * @return The scroll helper, which may used to chain setter calls.
+     */
+    public AutoScrollHelper setEdgeType(int type) {
+        mEdgeType = type;
+        return this;
+    }
+
+    /**
+     * Sets the activation edge size relative to the host view's dimensions.
+     * <p>
+     * If both relative and maximum edges are specified, the maximum edge will
+     * be used to constrain the calculated relative edge size.
+     *
+     * @param horizontal The horizontal edge size as a fraction of the host view
+     *            width, or {@link #RELATIVE_UNSPECIFIED} to always use the
+     *            maximum value.
+     * @param vertical The vertical edge size as a fraction of the host view
+     *            height, or {@link #RELATIVE_UNSPECIFIED} to always use the
+     *            maximum value.
+     * @return The scroll helper, which may used to chain setter calls.
+     */
+    public AutoScrollHelper setRelativeEdges(float horizontal, float vertical) {
+        mRelativeEdges[HORIZONTAL] = horizontal;
+        mRelativeEdges[VERTICAL] = vertical;
+        return this;
+    }
+
+    /**
+     * Sets the absolute maximum edge size.
+     * <p>
+     * If relative edge size is not specified, activation edges will always be
+     * the maximum edge size. If both relative and maximum edges are specified,
+     * the maximum edge will be used to constrain the calculated relative edge
+     * size.
+     *
+     * @param horizontalMax The maximum horizontal edge size in pixels, or
+     *            {@link #NO_MAX} to use the unconstrained calculated relative
+     *            value.
+     * @param verticalMax The maximum vertical edge size in pixels, or
+     *            {@link #NO_MAX} to use the unconstrained calculated relative
+     *            value.
+     * @return The scroll helper, which may used to chain setter calls.
+     */
+    public AutoScrollHelper setMaximumEdges(float horizontalMax, float verticalMax) {
+        mMaximumEdges[HORIZONTAL] = horizontalMax;
+        mMaximumEdges[VERTICAL] = verticalMax;
+        return this;
+    }
+
+    /**
+     * Sets the delay after entering an activation edge before activation of
+     * auto-scrolling. By default, the activation delay is set to
+     * {@link ViewConfiguration#getTapTimeout()}.
+     * <p>
+     * Specifying a delay of zero will start auto-scrolling immediately after
+     * the touch position enters an activation edge.
+     *
+     * @param delayMillis The activation delay in milliseconds.
+     * @return The scroll helper, which may used to chain setter calls.
+     */
+    public AutoScrollHelper setActivationDelay(int delayMillis) {
+        mActivationDelay = delayMillis;
+        return this;
+    }
+
+    /**
+     * Sets the amount of time after activation of auto-scrolling that is takes
+     * to reach target velocity for the current touch position.
+     * <p>
+     * Specifying a duration greater than zero prevents sudden jumps in
+     * velocity.
+     *
+     * @param durationMillis The ramp-up duration in milliseconds.
+     * @return The scroll helper, which may used to chain setter calls.
+     */
+    public AutoScrollHelper setRampUpDuration(int durationMillis) {
+        mScroller.setRampUpDuration(durationMillis);
+        return this;
+    }
+
+    /**
+     * Sets the amount of time after de-activation of auto-scrolling that is
+     * takes to slow to a stop.
+     * <p>
+     * Specifying a duration greater than zero prevents sudden jumps in
+     * velocity.
+     *
+     * @param durationMillis The ramp-down duration in milliseconds.
+     * @return The scroll helper, which may used to chain setter calls.
+     */
+    public AutoScrollHelper setRampDownDuration(int durationMillis) {
+        mScroller.setRampDownDuration(durationMillis);
+        return this;
+    }
+
+    /**
+     * Handles touch events by activating automatic scrolling, adjusting scroll
+     * velocity, or stopping.
+     * <p>
+     * If {@link #isExclusive()} is false, always returns false so that
+     * the host view may handle touch events. Otherwise, returns true when
+     * automatic scrolling is active and false otherwise.
+     */
+    @Override
+    public boolean onTouch(View v, MotionEvent event) {
+        if (!mEnabled) {
+            return false;
+        }
+
+        final int action = event.getActionMasked();
+        switch (action) {
+            case MotionEvent.ACTION_DOWN:
+                mNeedsCancel = true;
+                mAlreadyDelayed = false;
+                // $FALL-THROUGH$
+            case MotionEvent.ACTION_MOVE:
+                final float xTargetVelocity = computeTargetVelocity(
+                        HORIZONTAL, event.getX(), v.getWidth(), mTarget.getWidth());
+                final float yTargetVelocity = computeTargetVelocity(
+                        VERTICAL, event.getY(), v.getHeight(), mTarget.getHeight());
+                mScroller.setTargetVelocity(xTargetVelocity, yTargetVelocity);
+
+                // If the auto scroller was not previously active, but it should
+                // be, then update the state and start animations.
+                if (!mAnimating && shouldAnimate()) {
+                    startAnimating();
+                }
+                break;
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_CANCEL:
+                requestStop();
+                break;
+        }
+
+        return mExclusive && mAnimating;
+    }
+
+    /**
+     * @return whether the target is able to scroll in the requested direction
+     */
+    private boolean shouldAnimate() {
+        final ClampedScroller scroller = mScroller;
+        final int verticalDirection = scroller.getVerticalDirection();
+        final int horizontalDirection = scroller.getHorizontalDirection();
+
+        return verticalDirection != 0 && canTargetScrollVertically(verticalDirection)
+                || horizontalDirection != 0 && canTargetScrollHorizontally(horizontalDirection);
+    }
+
+    /**
+     * Starts the scroll animation.
+     */
+    private void startAnimating() {
+        if (mRunnable == null) {
+            mRunnable = new ScrollAnimationRunnable();
+        }
+
+        mAnimating = true;
+        mNeedsReset = true;
+
+        if (!mAlreadyDelayed && mActivationDelay > 0) {
+            mTarget.postOnAnimationDelayed(mRunnable, mActivationDelay);
+        } else {
+            mRunnable.run();
+        }
+
+        // If we start animating again before the user lifts their finger, we
+        // already know it's not a tap and don't need an activation delay.
+        mAlreadyDelayed = true;
+    }
+
+    /**
+     * Requests that the scroll animation slow to a stop. If there is an
+     * activation delay, this may occur between posting the animation and
+     * actually running it.
+     */
+    private void requestStop() {
+        if (mNeedsReset) {
+            // The animation has been posted, but hasn't run yet. Manually
+            // stopping animation will prevent it from running.
+            mAnimating = false;
+        } else {
+            mScroller.requestStop();
+        }
+    }
+
+    private float computeTargetVelocity(
+            int direction, float coordinate, float srcSize, float dstSize) {
+        final float relativeEdge = mRelativeEdges[direction];
+        final float maximumEdge = mMaximumEdges[direction];
+        final float value = getEdgeValue(relativeEdge, srcSize, maximumEdge, coordinate);
+        if (value == 0) {
+            // The edge in this direction is not activated.
+            return 0;
+        }
+
+        final float relativeVelocity = mRelativeVelocity[direction];
+        final float minimumVelocity = mMinimumVelocity[direction];
+        final float maximumVelocity = mMaximumVelocity[direction];
+        final float targetVelocity = relativeVelocity * dstSize;
+
+        // Target velocity is adjusted for interpolated edge position, then
+        // clamped to the minimum and maximum values. Later, this value will be
+        // adjusted for time-based acceleration.
+        if (value > 0) {
+            return constrain(value * targetVelocity, minimumVelocity, maximumVelocity);
+        } else {
+            return -constrain(-value * targetVelocity, minimumVelocity, maximumVelocity);
+        }
+    }
+
+    /**
+     * Override this method to scroll the target view by the specified number of
+     * pixels.
+     *
+     * @param deltaX The number of pixels to scroll by horizontally.
+     * @param deltaY The number of pixels to scroll by vertically.
+     */
+    public abstract void scrollTargetBy(int deltaX, int deltaY);
+
+    /**
+     * Override this method to return whether the target view can be scrolled
+     * horizontally in a certain direction.
+     *
+     * @param direction Negative to check scrolling left, positive to check
+     *            scrolling right.
+     * @return true if the target view is able to horizontally scroll in the
+     *         specified direction.
+     */
+    public abstract boolean canTargetScrollHorizontally(int direction);
+
+    /**
+     * Override this method to return whether the target view can be scrolled
+     * vertically in a certain direction.
+     *
+     * @param direction Negative to check scrolling up, positive to check
+     *            scrolling down.
+     * @return true if the target view is able to vertically scroll in the
+     *         specified direction.
+     */
+    public abstract boolean canTargetScrollVertically(int direction);
+
+    /**
+     * Returns the interpolated position of a touch point relative to an edge
+     * defined by its relative inset, its maximum absolute inset, and the edge
+     * interpolator.
+     *
+     * @param relativeValue The size of the inset relative to the total size.
+     * @param size Total size.
+     * @param maxValue The maximum size of the inset, used to clamp (relative *
+     *            total).
+     * @param current Touch position within within the total size.
+     * @return Interpolated value of the touch position within the edge.
+     */
+    private float getEdgeValue(float relativeValue, float size, float maxValue, float current) {
+        // For now, leading and trailing edges are always the same size.
+        final float edgeSize = constrain(relativeValue * size, NO_MIN, maxValue);
+        final float valueLeading = constrainEdgeValue(current, edgeSize);
+        final float valueTrailing = constrainEdgeValue(size - current, edgeSize);
+        final float value = (valueTrailing - valueLeading);
+        final float interpolated;
+        if (value < 0) {
+            interpolated = -mEdgeInterpolator.getInterpolation(-value);
+        } else if (value > 0) {
+            interpolated = mEdgeInterpolator.getInterpolation(value);
+        } else {
+            return 0;
+        }
+
+        return constrain(interpolated, -1, 1);
+    }
+
+    private float constrainEdgeValue(float current, float leading) {
+        if (leading == 0) {
+            return 0;
+        }
+
+        switch (mEdgeType) {
+            case EDGE_TYPE_INSIDE:
+            case EDGE_TYPE_INSIDE_EXTEND:
+                if (current < leading) {
+                    if (current >= 0) {
+                        // Movement up to the edge is scaled.
+                        return 1f - current / leading;
+                    } else if (mAnimating && (mEdgeType == EDGE_TYPE_INSIDE_EXTEND)) {
+                        // Movement beyond the edge is always maximum.
+                        return 1f;
+                    }
+                }
+                break;
+            case EDGE_TYPE_OUTSIDE:
+                if (current < 0) {
+                    // Movement beyond the edge is scaled.
+                    return current / -leading;
+                }
+                break;
+        }
+
+        return 0;
+    }
+
+    private static int constrain(int value, int min, int max) {
+        if (value > max) {
+            return max;
+        } else if (value < min) {
+            return min;
+        } else {
+            return value;
+        }
+    }
+
+    private static float constrain(float value, float min, float max) {
+        if (value > max) {
+            return max;
+        } else if (value < min) {
+            return min;
+        } else {
+            return value;
+        }
+    }
+
+    /**
+     * Sends a {@link MotionEvent#ACTION_CANCEL} event to the target view,
+     * canceling any ongoing touch events.
+     */
+    private void cancelTargetTouch() {
+        final long eventTime = SystemClock.uptimeMillis();
+        final MotionEvent cancel = MotionEvent.obtain(
+                eventTime, eventTime, MotionEvent.ACTION_CANCEL, 0, 0, 0);
+        mTarget.onTouchEvent(cancel);
+        cancel.recycle();
+    }
+
+    private class ScrollAnimationRunnable implements Runnable {
+        @Override
+        public void run() {
+            if (!mAnimating) {
+                return;
+            }
+
+            if (mNeedsReset) {
+                mNeedsReset = false;
+                mScroller.start();
+            }
+
+            final ClampedScroller scroller = mScroller;
+            if (scroller.isFinished() || !shouldAnimate()) {
+                mAnimating = false;
+                return;
+            }
+
+            if (mNeedsCancel) {
+                mNeedsCancel = false;
+                cancelTargetTouch();
+            }
+
+            scroller.computeScrollDelta();
+
+            final int deltaX = scroller.getDeltaX();
+            final int deltaY = scroller.getDeltaY();
+            scrollTargetBy(deltaX,  deltaY);
+
+            // Keep going until the scroller has permanently stopped.
+            mTarget.postOnAnimation(this);
+        }
+    }
+
+    /**
+     * Scroller whose velocity follows the curve of an {@link Interpolator} and
+     * is clamped to the interpolated 0f value before starting and the
+     * interpolated 1f value after a specified duration.
+     */
+    private static class ClampedScroller {
+        private int mRampUpDuration;
+        private int mRampDownDuration;
+        private float mTargetVelocityX;
+        private float mTargetVelocityY;
+
+        private long mStartTime;
+
+        private long mDeltaTime;
+        private int mDeltaX;
+        private int mDeltaY;
+
+        private long mStopTime;
+        private float mStopValue;
+        private int mEffectiveRampDown;
+
+        /**
+         * Creates a new ramp-up scroller that reaches full velocity after a
+         * specified duration.
+         */
+        public ClampedScroller() {
+            mStartTime = Long.MIN_VALUE;
+            mStopTime = -1;
+            mDeltaTime = 0;
+            mDeltaX = 0;
+            mDeltaY = 0;
+        }
+
+        public void setRampUpDuration(int durationMillis) {
+            mRampUpDuration = durationMillis;
+        }
+
+        public void setRampDownDuration(int durationMillis) {
+            mRampDownDuration = durationMillis;
+        }
+
+        /**
+         * Starts the scroller at the current animation time.
+         */
+        public void start() {
+            mStartTime = AnimationUtils.currentAnimationTimeMillis();
+            mStopTime = -1;
+            mDeltaTime = mStartTime;
+            mStopValue = 0.5f;
+            mDeltaX = 0;
+            mDeltaY = 0;
+        }
+
+        /**
+         * Stops the scroller at the current animation time.
+         */
+        public void requestStop() {
+            final long currentTime = AnimationUtils.currentAnimationTimeMillis();
+            mEffectiveRampDown = constrain((int) (currentTime - mStartTime), 0, mRampDownDuration);
+            mStopValue = getValueAt(currentTime);
+            mStopTime = currentTime;
+        }
+
+        public boolean isFinished() {
+            return mStopTime > 0
+                    && AnimationUtils.currentAnimationTimeMillis() > mStopTime + mEffectiveRampDown;
+        }
+
+        private float getValueAt(long currentTime) {
+            if (currentTime < mStartTime) {
+                return 0f;
+            } else if (mStopTime < 0 || currentTime < mStopTime) {
+                final long elapsedSinceStart = currentTime - mStartTime;
+                return 0.5f * constrain(elapsedSinceStart / (float) mRampUpDuration, 0, 1);
+            } else {
+                final long elapsedSinceEnd = currentTime - mStopTime;
+                return (1 - mStopValue) + mStopValue
+                        * constrain(elapsedSinceEnd / (float) mEffectiveRampDown, 0, 1);
+            }
+        }
+
+        /**
+         * Interpolates the value along a parabolic curve corresponding to the equation
+         * <code>y = -4x * (x-1)</code>.
+         *
+         * @param value The value to interpolate, between 0 and 1.
+         * @return the interpolated value, between 0 and 1.
+         */
+        private float interpolateValue(float value) {
+            return -4 * value * value + 4 * value;
+        }
+
+        /**
+         * Computes the current scroll deltas. This usually only be called after
+         * starting the scroller with {@link #start()}.
+         *
+         * @see #getDeltaX()
+         * @see #getDeltaY()
+         */
+        public void computeScrollDelta() {
+            if (mDeltaTime == 0) {
+                throw new RuntimeException("Cannot compute scroll delta before calling start()");
+            }
+
+            final long currentTime = AnimationUtils.currentAnimationTimeMillis();
+            final float value = getValueAt(currentTime);
+            final float scale = interpolateValue(value);
+            final long elapsedSinceDelta = currentTime - mDeltaTime;
+
+            mDeltaTime = currentTime;
+            mDeltaX = (int) (elapsedSinceDelta * scale * mTargetVelocityX);
+            mDeltaY = (int) (elapsedSinceDelta * scale * mTargetVelocityY);
+        }
+
+        /**
+         * Sets the target velocity for this scroller.
+         *
+         * @param x The target X velocity in pixels per millisecond.
+         * @param y The target Y velocity in pixels per millisecond.
+         */
+        public void setTargetVelocity(float x, float y) {
+            mTargetVelocityX = x;
+            mTargetVelocityY = y;
+        }
+
+        public int getHorizontalDirection() {
+            return (int) (mTargetVelocityX / Math.abs(mTargetVelocityX));
+        }
+
+        public int getVerticalDirection() {
+            return (int) (mTargetVelocityY / Math.abs(mTargetVelocityY));
+        }
+
+        /**
+         * The distance traveled in the X-coordinate computed by the last call
+         * to {@link #computeScrollDelta()}.
+         */
+        public int getDeltaX() {
+            return mDeltaX;
+        }
+
+        /**
+         * The distance traveled in the Y-coordinate computed by the last call
+         * to {@link #computeScrollDelta()}.
+         */
+        public int getDeltaY() {
+            return mDeltaY;
+        }
+    }
+
+    /**
+     * An implementation of {@link AutoScrollHelper} that knows how to scroll
+     * through an {@link AbsListView}.
+     */
+    public static class AbsListViewAutoScroller extends AutoScrollHelper {
+        private final AbsListView mTarget;
+
+        public AbsListViewAutoScroller(AbsListView target) {
+            super(target);
+
+            mTarget = target;
+        }
+
+        @Override
+        public void scrollTargetBy(int deltaX, int deltaY) {
+            mTarget.scrollListBy(deltaY);
+        }
+
+        @Override
+        public boolean canTargetScrollHorizontally(int direction) {
+            // List do not scroll horizontally.
+            return false;
+        }
+
+        @Override
+        public boolean canTargetScrollVertically(int direction) {
+            final AbsListView target = mTarget;
+            final int itemCount = target.getCount();
+            final int childCount = target.getChildCount();
+            final int firstPosition = target.getFirstVisiblePosition();
+            final int lastPosition = firstPosition + childCount;
+
+            if (direction > 0) {
+                // Are we already showing the entire last item?
+                if (lastPosition >= itemCount) {
+                    final View lastView = target.getChildAt(childCount - 1);
+                    if (lastView.getBottom() <= target.getHeight()) {
+                        return false;
+                    }
+                }
+            } else if (direction < 0) {
+                // Are we already showing the entire first item?
+                if (firstPosition <= 0) {
+                    final View firstView = target.getChildAt(0);
+                    if (firstView.getTop() >= 0) {
+                        return false;
+                    }
+                }
+            } else {
+                // The behavior for direction 0 is undefined and we can return
+                // whatever we want.
+                return false;
+            }
+
+            return true;
+        }
+    }
+}
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index d3ead26..1f2ab93 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.widget;
 
+import android.Manifest;
 import android.app.ActivityManagerNative;
 import android.app.admin.DevicePolicyManager;
 import android.appwidget.AppWidgetManager;
@@ -137,6 +138,7 @@
             = "lockscreen.biometricweakeverchosen";
     public final static String LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS
             = "lockscreen.power_button_instantly_locks";
+    public final static String LOCKSCREEN_WIDGETS_ENABLED = "lockscreen.widgets_enabled";
 
     public final static String PASSWORD_HISTORY_KEY = "lockscreen.passwordhistory";
 
@@ -149,6 +151,8 @@
     private DevicePolicyManager mDevicePolicyManager;
     private ILockSettings mLockSettingsService;
 
+    private final boolean mMultiUserMode;
+
     // The current user is set by KeyguardViewMediator and shared by all LockPatternUtils.
     private static volatile int sCurrentUserId = UserHandle.USER_NULL;
 
@@ -170,6 +174,12 @@
     public LockPatternUtils(Context context) {
         mContext = context;
         mContentResolver = context.getContentResolver();
+
+        // If this is being called by the system or by an application like keyguard that
+        // has permision INTERACT_ACROSS_USERS, then LockPatternUtils will operate in multi-user
+        // mode where calls are for the current user rather than the user of the calling process.
+        mMultiUserMode = context.checkCallingOrSelfPermission(
+            Manifest.permission.INTERACT_ACROSS_USERS_FULL) == PackageManager.PERMISSION_GRANTED;
     }
 
     private ILockSettings getLockSettings() {
@@ -264,13 +274,12 @@
     }
 
     private int getCurrentOrCallingUserId() {
-        int callingUid = Binder.getCallingUid();
-        if (callingUid == android.os.Process.SYSTEM_UID) {
+        if (mMultiUserMode) {
             // TODO: This is a little inefficient. See if all users of this are able to
             // handle USER_CURRENT and pass that instead.
             return getCurrentUser();
         } else {
-            return UserHandle.getUserId(callingUid);
+            return UserHandle.getCallingUserId();
         }
     }
 
@@ -1045,28 +1054,38 @@
         return nextAlarm;
     }
 
-    private boolean getBoolean(String secureSettingKey, boolean defaultValue) {
+    private boolean getBoolean(String secureSettingKey, boolean defaultValue, int userId) {
         try {
-            return getLockSettings().getBoolean(secureSettingKey, defaultValue,
-                    getCurrentOrCallingUserId());
+            return getLockSettings().getBoolean(secureSettingKey, defaultValue, userId);
         } catch (RemoteException re) {
             return defaultValue;
         }
     }
 
-    private void setBoolean(String secureSettingKey, boolean enabled) {
+    private boolean getBoolean(String secureSettingKey, boolean defaultValue) {
+        return getBoolean(secureSettingKey, defaultValue, getCurrentOrCallingUserId());
+    }
+
+    private void setBoolean(String secureSettingKey, boolean enabled, int userId) {
         try {
-            getLockSettings().setBoolean(secureSettingKey, enabled, getCurrentOrCallingUserId());
+            getLockSettings().setBoolean(secureSettingKey, enabled, userId);
         } catch (RemoteException re) {
             // What can we do?
             Log.e(TAG, "Couldn't write boolean " + secureSettingKey + re);
         }
     }
 
+    private void setBoolean(String secureSettingKey, boolean enabled) {
+        setBoolean(secureSettingKey, enabled, getCurrentOrCallingUserId());
+    }
+
     public int[] getAppWidgets() {
+        return getAppWidgets(UserHandle.USER_CURRENT);
+    }
+
+    private int[] getAppWidgets(int userId) {
         String appWidgetIdString = Settings.Secure.getStringForUser(
-                mContentResolver, Settings.Secure.LOCK_SCREEN_APPWIDGET_IDS,
-                UserHandle.USER_CURRENT);
+                mContentResolver, Settings.Secure.LOCK_SCREEN_APPWIDGET_IDS, userId);
         String delims = ",";
         if (appWidgetIdString != null && appWidgetIdString.length() > 0) {
             String[] appWidgetStringIds = appWidgetIdString.split(delims);
@@ -1353,4 +1372,35 @@
         return false;
     }
 
+    /**
+     * Determine whether the user has selected any non-system widgets in keyguard
+     *
+     * @return true if widgets have been selected
+     */
+    public boolean hasWidgetsEnabledInKeyguard(int userid) {
+        int widgets[] = getAppWidgets(userid);
+        for (int i = 0; i < widgets.length; i++) {
+            if (widgets[i] > 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public boolean getWidgetsEnabled() {
+        return getWidgetsEnabled(getCurrentOrCallingUserId());
+    }
+
+    public boolean getWidgetsEnabled(int userId) {
+        return getBoolean(LOCKSCREEN_WIDGETS_ENABLED, false, userId);
+    }
+
+    public void setWidgetsEnabled(boolean enabled) {
+        setWidgetsEnabled(enabled, getCurrentOrCallingUserId());
+    }
+
+    public void setWidgetsEnabled(boolean enabled, int userId) {
+        setBoolean(LOCKSCREEN_WIDGETS_ENABLED, enabled, userId);
+    }
+
 }
diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
index f8332c4..a3df291 100644
--- a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
+++ b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
@@ -184,7 +184,7 @@
                 KeyEvent event = events[i];
                 event = KeyEvent.changeFlags(event, event.getFlags()
                         | KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE);
-                viewRootImpl.dispatchKey(event);
+                viewRootImpl.dispatchInputEvent(event);
             }
         }
     }
diff --git a/core/java/com/android/internal/widget/PointerLocationView.java b/core/java/com/android/internal/widget/PointerLocationView.java
index f10a2e8..d82831f 100644
--- a/core/java/com/android/internal/widget/PointerLocationView.java
+++ b/core/java/com/android/internal/widget/PointerLocationView.java
@@ -46,6 +46,7 @@
         // Trace of previous points.
         private float[] mTraceX = new float[32];
         private float[] mTraceY = new float[32];
+        private boolean[] mTraceCurrent = new boolean[32];
         private int mTraceCount;
         
         // True if the pointer is down.
@@ -76,7 +77,7 @@
             mTraceCount = 0;
         }
         
-        public void addTrace(float x, float y) {
+        public void addTrace(float x, float y, boolean current) {
             int traceCapacity = mTraceX.length;
             if (mTraceCount == traceCapacity) {
                 traceCapacity *= 2;
@@ -87,10 +88,15 @@
                 float[] newTraceY = new float[traceCapacity];
                 System.arraycopy(mTraceY, 0, newTraceY, 0, mTraceCount);
                 mTraceY = newTraceY;
+
+                boolean[] newTraceCurrent = new boolean[traceCapacity];
+                System.arraycopy(mTraceCurrent, 0, newTraceCurrent, 0, mTraceCount);
+                mTraceCurrent= newTraceCurrent;
             }
             
             mTraceX[mTraceCount] = x;
             mTraceY[mTraceCount] = y;
+            mTraceCurrent[mTraceCount] = current;
             mTraceCount += 1;
         }
     }
@@ -106,6 +112,7 @@
     private final Paint mTextBackgroundPaint;
     private final Paint mTextLevelPaint;
     private final Paint mPaint;
+    private final Paint mCurrentPointPaint;
     private final Paint mTargetPaint;
     private final Paint mPathPaint;
     private final FontMetricsInt mTextMetrics = new FontMetricsInt();
@@ -147,6 +154,11 @@
         mPaint.setARGB(255, 255, 255, 255);
         mPaint.setStyle(Paint.Style.STROKE);
         mPaint.setStrokeWidth(2);
+        mCurrentPointPaint = new Paint();
+        mCurrentPointPaint.setAntiAlias(true);
+        mCurrentPointPaint.setARGB(255, 255, 0, 0);
+        mCurrentPointPaint.setStyle(Paint.Style.STROKE);
+        mCurrentPointPaint.setStrokeWidth(2);
         mTargetPaint = new Paint();
         mTargetPaint.setAntiAlias(false);
         mTargetPaint.setARGB(255, 0, 0, 192);
@@ -294,7 +306,8 @@
                 }
                 if (haveLast) {
                     canvas.drawLine(lastX, lastY, x, y, mPathPaint);
-                    canvas.drawPoint(lastX, lastY, mPaint);
+                    final Paint paint = ps.mTraceCurrent[i] ? mCurrentPointPaint : mPaint;
+                    canvas.drawPoint(lastX, lastY, paint);
                     drawn = true;
                 }
                 lastX = x;
@@ -549,8 +562,9 @@
 
             final PointerState ps = mPointers.get(id);
             ps.mCurDown = true;
-            ps.mHasBoundingBox = (InputDevice.getDevice(event.getDeviceId()).
-                    getMotionRange(MotionEvent.AXIS_GENERIC_1) != null);
+            InputDevice device = InputDevice.getDevice(event.getDeviceId());
+            ps.mHasBoundingBox = device != null &&
+                    device.getMotionRange(MotionEvent.AXIS_GENERIC_1) != null;
         }
 
         final int NI = event.getPointerCount();
@@ -573,7 +587,7 @@
                     logCoords("Pointer", action, i, coords, id, event);
                 }
                 if (ps != null) {
-                    ps.addTrace(coords.x, coords.y);
+                    ps.addTrace(coords.x, coords.y, false);
                 }
             }
         }
@@ -586,7 +600,7 @@
                 logCoords("Pointer", action, i, coords, id, event);
             }
             if (ps != null) {
-                ps.addTrace(coords.x, coords.y);
+                ps.addTrace(coords.x, coords.y, true);
                 ps.mXVelocity = mVelocity.getXVelocity(id);
                 ps.mYVelocity = mVelocity.getYVelocity(id);
                 mVelocity.getEstimator(id, ps.mEstimator);
@@ -625,7 +639,7 @@
                 if (mActivePointerId == id) {
                     mActivePointerId = event.getPointerId(index == 0 ? 1 : 0);
                 }
-                ps.addTrace(Float.NaN, Float.NaN);
+                ps.addTrace(Float.NaN, Float.NaN, false);
             }
         }
 
diff --git a/core/java/com/android/internal/widget/SubtitleView.java b/core/java/com/android/internal/widget/SubtitleView.java
new file mode 100644
index 0000000..356401c
--- /dev/null
+++ b/core/java/com/android/internal/widget/SubtitleView.java
@@ -0,0 +1,369 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.res.Resources.Theme;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Paint.Join;
+import android.graphics.Paint.Style;
+import android.graphics.RectF;
+import android.graphics.Typeface;
+import android.text.Layout.Alignment;
+import android.text.StaticLayout;
+import android.text.TextPaint;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+import android.view.View;
+import android.view.accessibility.CaptioningManager.CaptionStyle;
+
+public class SubtitleView extends View {
+    // Ratio of inner padding to font size.
+    private static final float INNER_PADDING_RATIO = 0.125f;
+
+    // Styled dimensions.
+    private final float mCornerRadius;
+    private final float mOutlineWidth;
+    private final float mShadowRadius;
+    private final float mShadowOffsetX;
+    private final float mShadowOffsetY;
+
+    /** Temporary rectangle used for computing line bounds. */
+    private final RectF mLineBounds = new RectF();
+
+    /** Temporary array used for computing line wrapping. */
+    private float[] mTextWidths;
+
+    /** Reusable string builder used for holding text. */
+    private final StringBuilder mText = new StringBuilder();
+    private final StringBuilder mBreakText = new StringBuilder();
+
+    private TextPaint mPaint;
+
+    private int mForegroundColor;
+    private int mBackgroundColor;
+    private int mEdgeColor;
+    private int mEdgeType;
+
+    private boolean mHasMeasurements;
+    private int mLastMeasuredWidth;
+    private StaticLayout mLayout;
+
+    private float mSpacingMult = 1;
+    private float mSpacingAdd = 0;
+    private int mInnerPaddingX = 0;
+
+    public SubtitleView(Context context) {
+        this(context, null);
+    }
+
+    public SubtitleView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public SubtitleView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs);
+
+        final Theme theme = context.getTheme();
+        final TypedArray a = theme.obtainStyledAttributes(
+                    attrs, android.R.styleable.TextView, defStyle, 0);
+
+        CharSequence text = "";
+        int textSize = 15;
+
+        final int n = a.getIndexCount();
+        for (int i = 0; i < n; i++) {
+            int attr = a.getIndex(i);
+
+            switch (attr) {
+                case android.R.styleable.TextView_text:
+                    text = a.getText(attr);
+                    break;
+                case android.R.styleable.TextView_lineSpacingExtra:
+                    mSpacingAdd = a.getDimensionPixelSize(attr, (int) mSpacingAdd);
+                    break;
+                case android.R.styleable.TextView_lineSpacingMultiplier:
+                    mSpacingMult = a.getFloat(attr, mSpacingMult);
+                    break;
+                case android.R.styleable.TextAppearance_textSize:
+                    textSize = a.getDimensionPixelSize(attr, textSize);
+                    break;
+            }
+        }
+
+        // Set up density-dependent properties.
+        // TODO: Move these to a default style.
+        final Resources res = getContext().getResources();
+        final DisplayMetrics m = res.getDisplayMetrics();
+        mCornerRadius = res.getDimension(com.android.internal.R.dimen.subtitle_corner_radius);
+        mOutlineWidth = res.getDimension(com.android.internal.R.dimen.subtitle_outline_width);
+        mShadowRadius = res.getDimension(com.android.internal.R.dimen.subtitle_shadow_radius);
+        mShadowOffsetX = res.getDimension(com.android.internal.R.dimen.subtitle_shadow_offset);
+        mShadowOffsetY = mShadowOffsetX;
+
+        final TextPaint paint = new TextPaint();
+        paint.setAntiAlias(true);
+        paint.setSubpixelText(true);
+
+        mPaint = paint;
+
+        setText(text);
+        setTextSize(textSize);
+    }
+
+    public void setText(int resId) {
+        final CharSequence text = getContext().getText(resId);
+        setText(text);
+    }
+
+    public void setText(CharSequence text) {
+        mText.setLength(0);
+        mText.append(text);
+
+        mHasMeasurements = false;
+
+        requestLayout();
+    }
+
+    public void setForegroundColor(int color) {
+        mForegroundColor = color;
+
+        invalidate();
+    }
+
+    @Override
+    public void setBackgroundColor(int color) {
+        mBackgroundColor = color;
+
+        invalidate();
+    }
+
+    public void setEdgeType(int edgeType) {
+        mEdgeType = edgeType;
+
+        invalidate();
+    }
+
+    public void setEdgeColor(int color) {
+        mEdgeColor = color;
+
+        invalidate();
+    }
+
+    public void setTextSize(float size) {
+        final DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
+        final float pixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, size, metrics);
+        if (mPaint.getTextSize() != size) {
+            mHasMeasurements = false;
+            mInnerPaddingX = (int) (size * INNER_PADDING_RATIO + 0.5f);
+            mPaint.setTextSize(size);
+
+            requestLayout();
+        }
+    }
+
+    public void setTypeface(Typeface typeface) {
+        if (mPaint.getTypeface() != typeface) {
+            mHasMeasurements = false;
+            mPaint.setTypeface(typeface);
+
+            requestLayout();
+        }
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        final int widthSpec = MeasureSpec.getSize(widthMeasureSpec);
+
+        if (computeMeasurements(widthSpec)) {
+            final StaticLayout layout = mLayout;
+
+            // Account for padding.
+            final int paddingX = mPaddingLeft + mPaddingRight + mInnerPaddingX * 2;
+            final int width = layout.getWidth() + paddingX;
+            final int height = layout.getHeight() + mPaddingTop + mPaddingBottom;
+            setMeasuredDimension(width, height);
+        } else {
+            setMeasuredDimension(MEASURED_STATE_TOO_SMALL, MEASURED_STATE_TOO_SMALL);
+        }
+    }
+
+    @Override
+    public void onLayout(boolean changed, int l, int t, int r, int b) {
+        final int width = r - l;
+
+        computeMeasurements(width);
+    }
+
+    private boolean computeMeasurements(int maxWidth) {
+        if (mHasMeasurements && maxWidth == mLastMeasuredWidth) {
+            return true;
+        }
+
+        // Account for padding.
+        final int paddingX = mPaddingLeft + mPaddingRight + mInnerPaddingX;
+        maxWidth -= paddingX;
+
+        if (maxWidth <= 0) {
+            return false;
+        }
+
+        final TextPaint paint = mPaint;
+        final CharSequence text = mText;
+        final int textLength = text.length();
+        if (mTextWidths == null || mTextWidths.length < textLength) {
+            mTextWidths = new float[textLength];
+        }
+
+        final float[] textWidths = mTextWidths;
+        paint.getTextWidths(text, 0, textLength, textWidths);
+
+        // Compute total length.
+        float runLength = 0;
+        for (int i = 0; i < textLength; i++) {
+            runLength += textWidths[i];
+        }
+
+        final int lineCount = (int) (runLength / maxWidth) + 1;
+        final int lineLength = (int) (runLength / lineCount);
+
+        // Build line break buffer.
+        final StringBuilder breakText = mBreakText;
+        breakText.setLength(0);
+
+        int line = 0;
+        int lastBreak = 0;
+        int maxRunLength = 0;
+        runLength = 0;
+        for (int i = 0; i < textLength; i++) {
+            if (runLength > lineLength) {
+                final CharSequence sequence = text.subSequence(lastBreak, i);
+                final int trimmedLength = TextUtils.getTrimmedLength(sequence);
+                breakText.append(sequence, 0, trimmedLength);
+                breakText.append('\n');
+                lastBreak = i;
+                runLength = 0;
+            }
+
+            runLength += textWidths[i];
+
+            if (runLength > maxRunLength) {
+                maxRunLength = (int) Math.ceil(runLength);
+            }
+        }
+        breakText.append(text.subSequence(lastBreak, textLength));
+
+        mHasMeasurements = true;
+        mLastMeasuredWidth = maxWidth;
+
+        mLayout = new StaticLayout(breakText, paint, maxRunLength, Alignment.ALIGN_LEFT,
+                mSpacingMult, mSpacingAdd, true);
+
+        return true;
+    }
+
+    public void setStyle(int styleId) {
+        final Context context = mContext;
+        final ContentResolver cr = context.getContentResolver();
+        final CaptionStyle style;
+        if (styleId == CaptionStyle.PRESET_CUSTOM) {
+            style = CaptionStyle.getCustomStyle(cr);
+        } else {
+            style = CaptionStyle.PRESETS[styleId];
+        }
+
+        mForegroundColor = style.foregroundColor;
+        mBackgroundColor = style.backgroundColor;
+        mEdgeType = style.edgeType;
+        mEdgeColor = style.edgeColor;
+        mHasMeasurements = false;
+
+        final Typeface typeface = style.getTypeface();
+        setTypeface(typeface);
+
+        requestLayout();
+    }
+
+    @Override
+    protected void onDraw(Canvas c) {
+        final StaticLayout layout = mLayout;
+        if (layout == null) {
+            return;
+        }
+
+        final int saveCount = c.save();
+        final int innerPaddingX = mInnerPaddingX;
+        c.translate(mPaddingLeft + innerPaddingX, mPaddingTop);
+
+        final RectF bounds = mLineBounds;
+        final int lineCount = layout.getLineCount();
+        final Paint paint = layout.getPaint();
+        paint.setShadowLayer(0, 0, 0, 0);
+
+        final int backgroundColor = mBackgroundColor;
+        if (Color.alpha(backgroundColor) > 0) {
+            paint.setColor(backgroundColor);
+            paint.setStyle(Style.FILL);
+
+            final float cornerRadius = mCornerRadius;
+            float previousBottom = layout.getLineTop(0);
+
+            for (int i = 0; i < lineCount; i++) {
+                bounds.left = layout.getLineLeft(i) - innerPaddingX;
+                bounds.right = layout.getLineRight(i) + innerPaddingX;
+                bounds.top = previousBottom;
+                bounds.bottom = layout.getLineBottom(i);
+
+                previousBottom = bounds.bottom;
+
+                c.drawRoundRect(bounds, cornerRadius, cornerRadius, paint);
+            }
+        }
+
+        final int edgeType = mEdgeType;
+        if (edgeType == CaptionStyle.EDGE_TYPE_OUTLINE) {
+            paint.setColor(mEdgeColor);
+            paint.setStyle(Style.FILL_AND_STROKE);
+            paint.setStrokeJoin(Join.ROUND);
+            paint.setStrokeWidth(mOutlineWidth);
+
+            for (int i = 0; i < lineCount; i++) {
+                layout.drawText(c, i, i);
+            }
+        }
+
+        if (edgeType == CaptionStyle.EDGE_TYPE_DROP_SHADOW) {
+            paint.setShadowLayer(mShadowRadius, mShadowOffsetX, mShadowOffsetY, mEdgeColor);
+        }
+
+        paint.setColor(mForegroundColor);
+        paint.setStyle(Style.FILL);
+
+        for (int i = 0; i < lineCount; i++) {
+            layout.drawText(c, i, i);
+        }
+
+        c.restoreToCount(saveCount);
+    }
+}
diff --git a/core/java/com/android/internal/widget/TransportControlView.java b/core/java/com/android/internal/widget/TransportControlView.java
deleted file mode 100644
index ca797eb..0000000
--- a/core/java/com/android/internal/widget/TransportControlView.java
+++ /dev/null
@@ -1,515 +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.widget;
-
-import java.lang.ref.WeakReference;
-
-import com.android.internal.widget.LockScreenWidgetCallback;
-import com.android.internal.widget.LockScreenWidgetInterface;
-
-import android.app.PendingIntent;
-import android.app.PendingIntent.CanceledException;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.media.AudioManager;
-import android.media.MediaMetadataRetriever;
-import android.media.RemoteControlClient;
-import android.media.IRemoteControlDisplay;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.text.Spannable;
-import android.text.TextUtils;
-import android.text.style.ForegroundColorSpan;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-
-import com.android.internal.R;
-
-public class TransportControlView extends FrameLayout implements OnClickListener,
-        LockScreenWidgetInterface {
-
-    private static final int MSG_UPDATE_STATE = 100;
-    private static final int MSG_SET_METADATA = 101;
-    private static final int MSG_SET_TRANSPORT_CONTROLS = 102;
-    private static final int MSG_SET_ARTWORK = 103;
-    private static final int MSG_SET_GENERATION_ID = 104;
-    private static final int MAXDIM = 512;
-    private static final int DISPLAY_TIMEOUT_MS = 5000; // 5s
-    protected static final boolean DEBUG = false;
-    protected static final String TAG = "TransportControlView";
-
-    private ImageView mAlbumArt;
-    private TextView mTrackTitle;
-    private ImageView mBtnPrev;
-    private ImageView mBtnPlay;
-    private ImageView mBtnNext;
-    private int mClientGeneration;
-    private Metadata mMetadata = new Metadata();
-    private boolean mAttached;
-    private PendingIntent mClientIntent;
-    private int mTransportControlFlags;
-    private int mCurrentPlayState;
-    private AudioManager mAudioManager;
-    private LockScreenWidgetCallback mWidgetCallbacks;
-    private IRemoteControlDisplayWeak mIRCD;
-
-    /**
-     * The metadata which should be populated into the view once we've been attached
-     */
-    private Bundle mPopulateMetadataWhenAttached = null;
-
-    // This handler is required to ensure messages from IRCD are handled in sequence and on
-    // the UI thread.
-    private Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-            case MSG_UPDATE_STATE:
-                if (mClientGeneration == msg.arg1) updatePlayPauseState(msg.arg2);
-                break;
-
-            case MSG_SET_METADATA:
-                if (mClientGeneration == msg.arg1) updateMetadata((Bundle) msg.obj);
-                break;
-
-            case MSG_SET_TRANSPORT_CONTROLS:
-                if (mClientGeneration == msg.arg1) updateTransportControls(msg.arg2);
-                break;
-
-            case MSG_SET_ARTWORK:
-                if (mClientGeneration == msg.arg1) {
-                    if (mMetadata.bitmap != null) {
-                        mMetadata.bitmap.recycle();
-                    }
-                    mMetadata.bitmap = (Bitmap) msg.obj;
-                    mAlbumArt.setImageBitmap(mMetadata.bitmap);
-                }
-                break;
-
-            case MSG_SET_GENERATION_ID:
-                if (msg.arg2 != 0) {
-                    // This means nobody is currently registered. Hide the view.
-                    if (mWidgetCallbacks != null) {
-                        mWidgetCallbacks.requestHide(TransportControlView.this);
-                    }
-                }
-                if (DEBUG) Log.v(TAG, "New genId = " + msg.arg1 + ", clearing = " + msg.arg2);
-                mClientGeneration = msg.arg1;
-                mClientIntent = (PendingIntent) msg.obj;
-                break;
-
-            }
-        }
-    };
-
-    /**
-     * This class is required to have weak linkage to the current TransportControlView
-     * because the remote process can hold a strong reference to this binder object and
-     * we can't predict when it will be GC'd in the remote process. Without this code, it
-     * would allow a heavyweight object to be held on this side of the binder when there's
-     * no requirement to run a GC on the other side.
-     */
-    private static class IRemoteControlDisplayWeak extends IRemoteControlDisplay.Stub {
-        private WeakReference<Handler> mLocalHandler;
-
-        IRemoteControlDisplayWeak(Handler handler) {
-            mLocalHandler = new WeakReference<Handler>(handler);
-        }
-
-        public void setPlaybackState(int generationId, int state, long stateChangeTimeMs,
-                long currentPosMs, float speed) {
-            Handler handler = mLocalHandler.get();
-            if (handler != null) {
-                handler.obtainMessage(MSG_UPDATE_STATE, generationId, state).sendToTarget();
-            }
-        }
-
-        public void setMetadata(int generationId, Bundle metadata) {
-            Handler handler = mLocalHandler.get();
-            if (handler != null) {
-                handler.obtainMessage(MSG_SET_METADATA, generationId, 0, metadata).sendToTarget();
-            }
-        }
-
-        public void setTransportControlInfo(int generationId, int flags, int posCapabilities) {
-            Handler handler = mLocalHandler.get();
-            if (handler != null) {
-                handler.obtainMessage(MSG_SET_TRANSPORT_CONTROLS, generationId, flags)
-                        .sendToTarget();
-            }
-        }
-
-        public void setArtwork(int generationId, Bitmap bitmap) {
-            Handler handler = mLocalHandler.get();
-            if (handler != null) {
-                handler.obtainMessage(MSG_SET_ARTWORK, generationId, 0, bitmap).sendToTarget();
-            }
-        }
-
-        public void setAllMetadata(int generationId, Bundle metadata, Bitmap bitmap) {
-            Handler handler = mLocalHandler.get();
-            if (handler != null) {
-                handler.obtainMessage(MSG_SET_METADATA, generationId, 0, metadata).sendToTarget();
-                handler.obtainMessage(MSG_SET_ARTWORK, generationId, 0, bitmap).sendToTarget();
-            }
-        }
-
-        public void setCurrentClientId(int clientGeneration, PendingIntent mediaIntent,
-                boolean clearing) throws RemoteException {
-            Handler handler = mLocalHandler.get();
-            if (handler != null) {
-                handler.obtainMessage(MSG_SET_GENERATION_ID,
-                    clientGeneration, (clearing ? 1 : 0), mediaIntent).sendToTarget();
-            }
-        }
-    };
-
-    public TransportControlView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        if (DEBUG) Log.v(TAG, "Create TCV " + this);
-        mAudioManager = new AudioManager(mContext);
-        mCurrentPlayState = RemoteControlClient.PLAYSTATE_NONE; // until we get a callback
-        mIRCD = new IRemoteControlDisplayWeak(mHandler);
-    }
-
-    private void updateTransportControls(int transportControlFlags) {
-        mTransportControlFlags = transportControlFlags;
-    }
-
-    @Override
-    public void onFinishInflate() {
-        super.onFinishInflate();
-        mTrackTitle = (TextView) findViewById(R.id.title);
-        mTrackTitle.setSelected(true); // enable marquee
-        mAlbumArt = (ImageView) findViewById(R.id.albumart);
-        mBtnPrev = (ImageView) findViewById(R.id.btn_prev);
-        mBtnPlay = (ImageView) findViewById(R.id.btn_play);
-        mBtnNext = (ImageView) findViewById(R.id.btn_next);
-        final View buttons[] = { mBtnPrev, mBtnPlay, mBtnNext };
-        for (View view : buttons) {
-            view.setOnClickListener(this);
-        }
-    }
-
-    @Override
-    public void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        if (mPopulateMetadataWhenAttached != null) {
-            updateMetadata(mPopulateMetadataWhenAttached);
-            mPopulateMetadataWhenAttached = null;
-        }
-        if (!mAttached) {
-            if (DEBUG) Log.v(TAG, "Registering TCV " + this);
-            mAudioManager.registerRemoteControlDisplay(mIRCD);
-        }
-        mAttached = true;
-    }
-
-    @Override
-    public void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        if (mAttached) {
-            if (DEBUG) Log.v(TAG, "Unregistering TCV " + this);
-            mAudioManager.unregisterRemoteControlDisplay(mIRCD);
-        }
-        mAttached = false;
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        int dim = Math.min(MAXDIM, Math.max(getWidth(), getHeight()));
-//        Log.v(TAG, "setting max bitmap size: " + dim + "x" + dim);
-//        mAudioManager.remoteControlDisplayUsesBitmapSize(mIRCD, dim, dim);
-    }
-
-    class Metadata {
-        private String artist;
-        private String trackTitle;
-        private String albumTitle;
-        private Bitmap bitmap;
-
-        public String toString() {
-            return "Metadata[artist=" + artist + " trackTitle=" + trackTitle + " albumTitle=" + albumTitle + "]";
-        }
-    }
-
-    private String getMdString(Bundle data, int id) {
-        return data.getString(Integer.toString(id));
-    }
-
-    private void updateMetadata(Bundle data) {
-        if (mAttached) {
-            mMetadata.artist = getMdString(data, MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST);
-            mMetadata.trackTitle = getMdString(data, MediaMetadataRetriever.METADATA_KEY_TITLE);
-            mMetadata.albumTitle = getMdString(data, MediaMetadataRetriever.METADATA_KEY_ALBUM);
-            populateMetadata();
-        } else {
-            mPopulateMetadataWhenAttached = data;
-        }
-    }
-
-    /**
-     * Populates the given metadata into the view
-     */
-    private void populateMetadata() {
-        StringBuilder sb = new StringBuilder();
-        int trackTitleLength = 0;
-        if (!TextUtils.isEmpty(mMetadata.trackTitle)) {
-            sb.append(mMetadata.trackTitle);
-            trackTitleLength = mMetadata.trackTitle.length();
-        }
-        if (!TextUtils.isEmpty(mMetadata.artist)) {
-            if (sb.length() != 0) {
-                sb.append(" - ");
-            }
-            sb.append(mMetadata.artist);
-        }
-        if (!TextUtils.isEmpty(mMetadata.albumTitle)) {
-            if (sb.length() != 0) {
-                sb.append(" - ");
-            }
-            sb.append(mMetadata.albumTitle);
-        }
-        mTrackTitle.setText(sb.toString(), TextView.BufferType.SPANNABLE);
-        Spannable str = (Spannable) mTrackTitle.getText();
-        if (trackTitleLength != 0) {
-            str.setSpan(new ForegroundColorSpan(0xffffffff), 0, trackTitleLength,
-                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
-            trackTitleLength++;
-        }
-        if (sb.length() > trackTitleLength) {
-            str.setSpan(new ForegroundColorSpan(0x7fffffff), trackTitleLength, sb.length(),
-                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
-        }
-
-        mAlbumArt.setImageBitmap(mMetadata.bitmap);
-        final int flags = mTransportControlFlags;
-        setVisibilityBasedOnFlag(mBtnPrev, flags, RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS);
-        setVisibilityBasedOnFlag(mBtnNext, flags, RemoteControlClient.FLAG_KEY_MEDIA_NEXT);
-        setVisibilityBasedOnFlag(mBtnPlay, flags,
-                RemoteControlClient.FLAG_KEY_MEDIA_PLAY
-                | RemoteControlClient.FLAG_KEY_MEDIA_PAUSE
-                | RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE
-                | RemoteControlClient.FLAG_KEY_MEDIA_STOP);
-
-        updatePlayPauseState(mCurrentPlayState);
-    }
-
-    private static void setVisibilityBasedOnFlag(View view, int flags, int flag) {
-        if ((flags & flag) != 0) {
-            view.setVisibility(View.VISIBLE);
-        } else {
-            view.setVisibility(View.GONE);
-        }
-    }
-
-    private void updatePlayPauseState(int state) {
-        if (DEBUG) Log.v(TAG,
-                "updatePlayPauseState(), old=" + mCurrentPlayState + ", state=" + state);
-        if (state == mCurrentPlayState) {
-            return;
-        }
-        final int imageResId;
-        final int imageDescId;
-        boolean showIfHidden = false;
-        switch (state) {
-            case RemoteControlClient.PLAYSTATE_ERROR:
-                imageResId = com.android.internal.R.drawable.stat_sys_warning;
-                // TODO use more specific image description string for warning, but here the "play"
-                //      message is still valid because this button triggers a play command.
-                imageDescId = com.android.internal.R.string.lockscreen_transport_play_description;
-                break;
-
-            case RemoteControlClient.PLAYSTATE_PLAYING:
-                imageResId = com.android.internal.R.drawable.ic_media_pause;
-                imageDescId = com.android.internal.R.string.lockscreen_transport_pause_description;
-                showIfHidden = true;
-                break;
-
-            case RemoteControlClient.PLAYSTATE_BUFFERING:
-                imageResId = com.android.internal.R.drawable.ic_media_stop;
-                imageDescId = com.android.internal.R.string.lockscreen_transport_stop_description;
-                showIfHidden = true;
-                break;
-
-            case RemoteControlClient.PLAYSTATE_PAUSED:
-            default:
-                imageResId = com.android.internal.R.drawable.ic_media_play;
-                imageDescId = com.android.internal.R.string.lockscreen_transport_play_description;
-                showIfHidden = false;
-                break;
-        }
-        mBtnPlay.setImageResource(imageResId);
-        mBtnPlay.setContentDescription(getResources().getString(imageDescId));
-        if (showIfHidden && mWidgetCallbacks != null && !mWidgetCallbacks.isVisible(this)) {
-            mWidgetCallbacks.requestShow(this);
-        }
-        mCurrentPlayState = state;
-    }
-
-    static class SavedState extends BaseSavedState {
-        boolean wasShowing;
-
-        SavedState(Parcelable superState) {
-            super(superState);
-        }
-
-        private SavedState(Parcel in) {
-            super(in);
-            this.wasShowing = in.readInt() != 0;
-        }
-
-        @Override
-        public void writeToParcel(Parcel out, int flags) {
-            super.writeToParcel(out, flags);
-            out.writeInt(this.wasShowing ? 1 : 0);
-        }
-
-        public static final Parcelable.Creator<SavedState> CREATOR
-                = new Parcelable.Creator<SavedState>() {
-            public SavedState createFromParcel(Parcel in) {
-                return new SavedState(in);
-            }
-
-            public SavedState[] newArray(int size) {
-                return new SavedState[size];
-            }
-        };
-    }
-
-    @Override
-    public Parcelable onSaveInstanceState() {
-        if (DEBUG) Log.v(TAG, "onSaveInstanceState()");
-        Parcelable superState = super.onSaveInstanceState();
-        SavedState ss = new SavedState(superState);
-        ss.wasShowing = mWidgetCallbacks != null && mWidgetCallbacks.isVisible(this);
-        return ss;
-    }
-
-    @Override
-    public void onRestoreInstanceState(Parcelable state) {
-        if (DEBUG) Log.v(TAG, "onRestoreInstanceState()");
-        if (!(state instanceof SavedState)) {
-            super.onRestoreInstanceState(state);
-            return;
-        }
-        SavedState ss = (SavedState) state;
-        super.onRestoreInstanceState(ss.getSuperState());
-        if (ss.wasShowing && mWidgetCallbacks != null) {
-            mWidgetCallbacks.requestShow(this);
-        }
-    }
-
-    public void onClick(View v) {
-        int keyCode = -1;
-        if (v == mBtnPrev) {
-            keyCode = KeyEvent.KEYCODE_MEDIA_PREVIOUS;
-        } else if (v == mBtnNext) {
-            keyCode = KeyEvent.KEYCODE_MEDIA_NEXT;
-        } else if (v == mBtnPlay) {
-            keyCode = KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE;
-
-        }
-        if (keyCode != -1) {
-            sendMediaButtonClick(keyCode);
-            if (mWidgetCallbacks != null) {
-                mWidgetCallbacks.userActivity(this);
-            }
-        }
-    }
-
-    private void sendMediaButtonClick(int keyCode) {
-        if (mClientIntent == null) {
-            // Shouldn't be possible because this view should be hidden in this case.
-            Log.e(TAG, "sendMediaButtonClick(): No client is currently registered");
-            return;
-        }
-        // use the registered PendingIntent that will be processed by the registered
-        //    media button event receiver, which is the component of mClientIntent
-        KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
-        Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
-        intent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
-        try {
-            mClientIntent.send(getContext(), 0, intent);
-        } catch (CanceledException e) {
-            Log.e(TAG, "Error sending intent for media button down: "+e);
-            e.printStackTrace();
-        }
-
-        keyEvent = new KeyEvent(KeyEvent.ACTION_UP, keyCode);
-        intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
-        intent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
-        try {
-            mClientIntent.send(getContext(), 0, intent);
-        } catch (CanceledException e) {
-            Log.e(TAG, "Error sending intent for media button up: "+e);
-            e.printStackTrace();
-        }
-    }
-
-    public void setCallback(LockScreenWidgetCallback callback) {
-        mWidgetCallbacks = callback;
-    }
-
-    public boolean providesClock() {
-        return false;
-    }
-
-    private boolean wasPlayingRecently(int state, long stateChangeTimeMs) {
-        switch (state) {
-            case RemoteControlClient.PLAYSTATE_PLAYING:
-            case RemoteControlClient.PLAYSTATE_FAST_FORWARDING:
-            case RemoteControlClient.PLAYSTATE_REWINDING:
-            case RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS:
-            case RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS:
-            case RemoteControlClient.PLAYSTATE_BUFFERING:
-                // actively playing or about to play
-                return true;
-            case RemoteControlClient.PLAYSTATE_NONE:
-                return false;
-            case RemoteControlClient.PLAYSTATE_STOPPED:
-            case RemoteControlClient.PLAYSTATE_PAUSED:
-            case RemoteControlClient.PLAYSTATE_ERROR:
-                // we have stopped playing, check how long ago
-                if (DEBUG) {
-                    if ((SystemClock.elapsedRealtime() - stateChangeTimeMs) < DISPLAY_TIMEOUT_MS) {
-                        Log.v(TAG, "wasPlayingRecently: time < TIMEOUT was playing recently");
-                    } else {
-                        Log.v(TAG, "wasPlayingRecently: time > TIMEOUT");
-                    }
-                }
-                return ((SystemClock.elapsedRealtime() - stateChangeTimeMs) < DISPLAY_TIMEOUT_MS);
-            default:
-                Log.e(TAG, "Unknown playback state " + state + " in wasPlayingRecently()");
-                return false;
-        }
-    }
-}
diff --git a/core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java b/core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java
index 30f5f2f..16bec16 100644
--- a/core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java
+++ b/core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java
@@ -46,36 +46,6 @@
     private boolean mEnabled = true;
     private final int mResourceId;
 
-    /* package */ static class DrawableWithAlpha extends Drawable {
-        private float mAlpha = 1.0f;
-        private Drawable mRealDrawable;
-        public DrawableWithAlpha(Drawable realDrawable) {
-            mRealDrawable = realDrawable;
-        }
-        public void setAlpha(float alpha) {
-            mAlpha = alpha;
-        }
-        public float getAlpha() {
-            return mAlpha;
-        }
-        public void draw(Canvas canvas) {
-            mRealDrawable.setAlpha((int) Math.round(mAlpha * 255f));
-            mRealDrawable.draw(canvas);
-        }
-        @Override
-        public void setAlpha(int alpha) {
-            mRealDrawable.setAlpha(alpha);
-        }
-        @Override
-        public void setColorFilter(ColorFilter cf) {
-            mRealDrawable.setColorFilter(cf);
-        }
-        @Override
-        public int getOpacity() {
-            return mRealDrawable.getOpacity();
-        }
-    }
-
     public TargetDrawable(Resources res, int resId) {
         mResourceId = resId;
         setDrawable(res, resId);
diff --git a/core/java/com/android/server/net/BaseNetworkObserver.java b/core/java/com/android/server/net/BaseNetworkObserver.java
new file mode 100644
index 0000000..fa54c5f
--- /dev/null
+++ b/core/java/com/android/server/net/BaseNetworkObserver.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.net;
+
+import android.net.INetworkManagementEventObserver;
+
+/**
+ * Base {@link INetworkManagementEventObserver} that provides no-op
+ * implementations which can be overridden.
+ *
+ * @hide
+ */
+public class BaseNetworkObserver extends INetworkManagementEventObserver.Stub {
+    @Override
+    public void interfaceStatusChanged(String iface, boolean up) {
+        // default no-op
+    }
+
+    @Override
+    public void interfaceRemoved(String iface) {
+        // default no-op
+    }
+
+    @Override
+    public void addressUpdated(String address, String iface, int flags, int scope) {
+        // default no-op
+    }
+
+    @Override
+    public void addressRemoved(String address, String iface, int flags, int scope) {
+        // default no-op
+    }
+
+    @Override
+    public void interfaceLinkStateChanged(String iface, boolean up) {
+        // default no-op
+    }
+
+    @Override
+    public void interfaceAdded(String iface) {
+        // default no-op
+    }
+
+    @Override
+    public void interfaceClassDataActivityChanged(String label, boolean active) {
+        // default no-op
+    }
+
+    @Override
+    public void limitReached(String limitName, String iface) {
+        // default no-op
+    }
+}
diff --git a/core/java/com/google/android/collect/Maps.java b/core/java/com/google/android/collect/Maps.java
index d537e0c..fc2c9fe 100644
--- a/core/java/com/google/android/collect/Maps.java
+++ b/core/java/com/google/android/collect/Maps.java
@@ -16,6 +16,8 @@
 
 package com.google.android.collect;
 
+import android.util.ArrayMap;
+
 import java.util.HashMap;
 
 /**
@@ -30,4 +32,11 @@
     public static <K, V> HashMap<K, V> newHashMap() {
         return new HashMap<K, V>();
     }
+
+    /**
+     * Creates a {@code ArrayMap} instance.
+     */
+    public static <K, V> ArrayMap<K, V> newArrayMap() {
+        return new ArrayMap<K, V>();
+    }
 }
diff --git a/core/java/com/google/android/collect/Sets.java b/core/java/com/google/android/collect/Sets.java
index fbfbe50..dd3cab1 100644
--- a/core/java/com/google/android/collect/Sets.java
+++ b/core/java/com/google/android/collect/Sets.java
@@ -16,6 +16,8 @@
 
 package com.google.android.collect;
 
+import android.util.ArraySet;
+
 import java.util.Collections;
 import java.util.EnumSet;
 import java.util.HashSet;
@@ -90,4 +92,20 @@
         return set;
     }
 
+    /**
+     * Creates a {@code ArraySet} instance.
+     */
+    public static <E> ArraySet<E> newArraySet() {
+        return new ArraySet<E>();
+    }
+
+    /**
+     * Creates a {@code ArraySet} instance containing the given elements.
+     */
+    public static <E> ArraySet<E> newArraySet(E... elements) {
+        int capacity = elements.length * 4 / 3 + 1;
+        ArraySet<E> set = new ArraySet<E>(capacity);
+        Collections.addAll(set, elements);
+        return set;
+    }
 }
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 337c1ec..d5d746a 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -51,6 +51,7 @@
 	android_view_KeyEvent.cpp \
 	android_view_KeyCharacterMap.cpp \
 	android_view_HardwareRenderer.cpp \
+	android_view_GraphicBuffer.cpp \
 	android_view_GLES20DisplayList.cpp \
 	android_view_GLES20Canvas.cpp \
 	android_view_MotionEvent.cpp \
@@ -62,7 +63,6 @@
 	android_os_FileUtils.cpp \
 	android_os_MemoryFile.cpp \
 	android_os_MessageQueue.cpp \
-	android_os_ParcelFileDescriptor.cpp \
 	android_os_Parcel.cpp \
 	android_os_SELinux.cpp \
 	android_os_SystemClock.cpp \
@@ -72,7 +72,7 @@
 	android_net_LocalSocketImpl.cpp \
 	android_net_NetUtils.cpp \
 	android_net_TrafficStats.cpp \
-	android_net_wifi_Wifi.cpp \
+	android_net_wifi_WifiNative.cpp \
 	android_nio_utils.cpp \
 	android_text_format_Time.cpp \
 	android_util_AssetManager.cpp \
@@ -105,7 +105,6 @@
 	android/graphics/Path.cpp \
 	android/graphics/PathMeasure.cpp \
 	android/graphics/PathEffect.cpp \
-	android_graphics_PixelFormat.cpp \
 	android/graphics/Picture.cpp \
 	android/graphics/PorterDuff.cpp \
 	android/graphics/BitmapRegionDecoder.cpp \
@@ -126,6 +125,7 @@
 	android_media_RemoteDisplay.cpp \
 	android_media_ToneGenerator.cpp \
 	android_hardware_Camera.cpp \
+	android_hardware_camera2_CameraMetadata.cpp \
 	android_hardware_SensorManager.cpp \
 	android_hardware_SerialPort.cpp \
 	android_hardware_UsbDevice.cpp \
@@ -135,6 +135,7 @@
 	android_util_FileObserver.cpp \
 	android/opengl/poly_clip.cpp.arm \
 	android/opengl/util.cpp.arm \
+	android/print/android_print_pdf_PdfDocument.cpp \
 	android_server_NetworkManagementSocketTagger.cpp \
 	android_server_Watchdog.cpp \
 	android_ddm_DdmHandleNativeHeap.cpp \
@@ -158,11 +159,9 @@
 	$(call include-path-for, libhardware)/hardware \
 	$(call include-path-for, libhardware_legacy)/hardware_legacy \
 	$(TOP)/frameworks/av/include \
-	external/skia/include/core \
-	external/skia/include/effects \
-	external/skia/include/images \
-	external/skia/include/ports \
+	$(TOP)/system/media/camera/include \
 	external/skia/src/core \
+	external/skia/src/pdf \
 	external/skia/src/images \
 	external/skia/include/utils \
 	external/sqlite/dist \
@@ -189,10 +188,11 @@
 	libnetutils \
 	libui \
 	libgui \
+	libinput \
 	libcamera_client \
+	libcamera_metadata \
 	libskia \
 	libsqlite \
-	libdvm \
 	libEGL \
 	libGLESv1_CM \
 	libGLESv2 \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index ca658da..490d85c 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -24,7 +24,6 @@
 #include <utils/Log.h>
 #include <utils/misc.h>
 #include <binder/Parcel.h>
-#include <utils/StringArray.h>
 #include <utils/threads.h>
 #include <cutils/properties.h>
 
@@ -34,6 +33,7 @@
 
 #include "jni.h"
 #include "JNIHelp.h"
+#include "JniInvocation.h"
 #include "android_util_Binder.h"
 
 #include <stdio.h>
@@ -53,6 +53,7 @@
 extern int register_android_graphics_BitmapFactory(JNIEnv*);
 extern int register_android_graphics_BitmapRegionDecoder(JNIEnv*);
 extern int register_android_graphics_Camera(JNIEnv* env);
+extern int register_android_graphics_CreateJavaOutputStreamAdaptor(JNIEnv* env);
 extern int register_android_graphics_Graphics(JNIEnv* env);
 extern int register_android_graphics_Interpolator(JNIEnv* env);
 extern int register_android_graphics_LayerRasterizer(JNIEnv*);
@@ -76,6 +77,7 @@
 extern int register_android_opengl_jni_GLES30(JNIEnv* env);
 
 extern int register_android_hardware_Camera(JNIEnv *env);
+extern int register_android_hardware_camera2_CameraMetadata(JNIEnv *env);
 extern int register_android_hardware_SensorManager(JNIEnv *env);
 extern int register_android_hardware_SerialPort(JNIEnv *env);
 extern int register_android_hardware_UsbDevice(JNIEnv *env);
@@ -115,8 +117,8 @@
 extern int register_android_graphics_Region(JNIEnv* env);
 extern int register_android_graphics_SurfaceTexture(JNIEnv* env);
 extern int register_android_graphics_Xfermode(JNIEnv* env);
-extern int register_android_graphics_PixelFormat(JNIEnv* env);
 extern int register_android_view_DisplayEventReceiver(JNIEnv* env);
+extern int register_android_view_GraphicBuffer(JNIEnv* env);
 extern int register_android_view_GLES20DisplayList(JNIEnv* env);
 extern int register_android_view_GLES20Canvas(JNIEnv* env);
 extern int register_android_view_HardwareRenderer(JNIEnv* env);
@@ -134,7 +136,6 @@
 extern int register_android_os_Debug(JNIEnv* env);
 extern int register_android_os_MessageQueue(JNIEnv* env);
 extern int register_android_os_Parcel(JNIEnv* env);
-extern int register_android_os_ParcelFileDescriptor(JNIEnv *env);
 extern int register_android_os_SELinux(JNIEnv* env);
 extern int register_android_os_SystemProperties(JNIEnv *env);
 extern int register_android_os_SystemClock(JNIEnv* env);
@@ -143,10 +144,11 @@
 extern int register_android_os_FileUtils(JNIEnv *env);
 extern int register_android_os_UEventObserver(JNIEnv* env);
 extern int register_android_os_MemoryFile(JNIEnv* env);
+extern int register_android_print_pdf_PdfDocument(JNIEnv* env);
 extern int register_android_net_LocalSocketImpl(JNIEnv* env);
 extern int register_android_net_NetworkUtils(JNIEnv* env);
 extern int register_android_net_TrafficStats(JNIEnv* env);
-extern int register_android_net_wifi_WifiManager(JNIEnv* env);
+extern int register_android_net_wifi_WifiNative(JNIEnv* env);
 extern int register_android_text_AndroidCharacter(JNIEnv *env);
 extern int register_android_text_AndroidBidi(JNIEnv *env);
 extern int register_android_opengl_classes(JNIEnv *env);
@@ -371,19 +373,6 @@
 }
 
 /*
- * We just want failed write() calls to just return with an error.
- */
-static void blockSigpipe()
-{
-    sigset_t mask;
-
-    sigemptyset(&mask);
-    sigaddset(&mask, SIGPIPE);
-    if (sigprocmask(SIG_BLOCK, &mask, NULL) != 0)
-        ALOGW("WARNING: SIGPIPE not blocked\n");
-}
-
-/*
  * Read the persistent locale.
  */
 static void readLocale(char* language, char* region)
@@ -460,6 +449,7 @@
     char heapminfreeOptsBuf[sizeof("-XX:HeapMinFree=")-1 + PROPERTY_VALUE_MAX];
     char heapmaxfreeOptsBuf[sizeof("-XX:HeapMaxFree=")-1 + PROPERTY_VALUE_MAX];
     char heaptargetutilizationOptsBuf[sizeof("-XX:HeapTargetUtilization=")-1 + PROPERTY_VALUE_MAX];
+    char jitcodecachesizeOptsBuf[sizeof("-Xjitcodecachesize:")-1 + PROPERTY_VALUE_MAX];
     char extraOptsBuf[PROPERTY_VALUE_MAX];
     char* stackTraceFile = NULL;
     bool checkJni = false;
@@ -551,6 +541,14 @@
     opt.optionString = "-XX:mainThreadStackSize=24K";
     mOptions.add(opt);
 
+    // Set the max jit code cache size.  Note: size of 0 will disable the JIT.
+    strcpy(jitcodecachesizeOptsBuf, "-Xjitcodecachesize:");
+    property_get("dalvik.vm.jit.codecachesize", jitcodecachesizeOptsBuf+19,  NULL);
+    if (jitcodecachesizeOptsBuf[19] != '\0') {
+      opt.optionString = jitcodecachesizeOptsBuf;
+      mOptions.add(opt);
+    }
+
     strcpy(heapgrowthlimitOptsBuf, "-XX:HeapGrowthLimit=");
     property_get("dalvik.vm.heapgrowthlimit", heapgrowthlimitOptsBuf+20, "");
     if (heapgrowthlimitOptsBuf[20] != '\0') {
@@ -579,6 +577,12 @@
         mOptions.add(opt);
     }
 
+    property_get("ro.config.low_ram", propBuf, "");
+    if (strcmp(propBuf, "true") == 0) {
+      opt.optionString = "-XX:LowMemoryMode";
+      mOptions.add(opt);
+    }
+
     /*
      * Enable or disable dexopt features, such as bytecode verification and
      * calculation of register maps for precise GC.
@@ -804,8 +808,6 @@
     ALOGD("\n>>>>>> AndroidRuntime START %s <<<<<<\n",
             className != NULL ? className : "(unknown)");
 
-    blockSigpipe();
-
     /*
      * 'startSystemServer == true' means runtime is obsolete and not run from
      * init.rc anymore, so we print out the boot start event here.
@@ -831,6 +833,8 @@
     //ALOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);
 
     /* start the virtual machine */
+    JniInvocation jni_invocation;
+    jni_invocation.Init(NULL);
     JNIEnv* env;
     if (startVm(&mJavaVM, &env) != 0) {
         return;
@@ -1110,8 +1114,8 @@
     REG_JNI(register_android_os_Parcel),
     REG_JNI(register_android_view_DisplayEventReceiver),
     REG_JNI(register_android_nio_utils),
-    REG_JNI(register_android_graphics_PixelFormat),
     REG_JNI(register_android_graphics_Graphics),
+    REG_JNI(register_android_view_GraphicBuffer),
     REG_JNI(register_android_view_GLES20DisplayList),
     REG_JNI(register_android_view_GLES20Canvas),
     REG_JNI(register_android_view_HardwareRenderer),
@@ -1134,6 +1138,7 @@
     REG_JNI(register_android_graphics_BitmapFactory),
     REG_JNI(register_android_graphics_BitmapRegionDecoder),
     REG_JNI(register_android_graphics_Camera),
+    REG_JNI(register_android_graphics_CreateJavaOutputStreamAdaptor),
     REG_JNI(register_android_graphics_Canvas),
     REG_JNI(register_android_graphics_ColorFilter),
     REG_JNI(register_android_graphics_DrawFilter),
@@ -1165,17 +1170,18 @@
     REG_JNI(register_android_os_FileObserver),
     REG_JNI(register_android_os_FileUtils),
     REG_JNI(register_android_os_MessageQueue),
-    REG_JNI(register_android_os_ParcelFileDescriptor),
     REG_JNI(register_android_os_SELinux),
     REG_JNI(register_android_os_Trace),
     REG_JNI(register_android_os_UEventObserver),
+    REG_JNI(register_android_print_pdf_PdfDocument),
     REG_JNI(register_android_net_LocalSocketImpl),
     REG_JNI(register_android_net_NetworkUtils),
     REG_JNI(register_android_net_TrafficStats),
-    REG_JNI(register_android_net_wifi_WifiManager),
+    REG_JNI(register_android_net_wifi_WifiNative),
     REG_JNI(register_android_os_MemoryFile),
     REG_JNI(register_com_android_internal_os_ZygoteInit),
     REG_JNI(register_android_hardware_Camera),
+    REG_JNI(register_android_hardware_camera2_CameraMetadata),
     REG_JNI(register_android_hardware_SensorManager),
     REG_JNI(register_android_hardware_SerialPort),
     REG_JNI(register_android_hardware_UsbDevice),
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 63683b4..eea9ee1 100644
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -5,6 +5,7 @@
 #include "GraphicsJNI.h"

 #include "SkDither.h"

 #include "SkUnPreMultiply.h"

+#include "SkStream.h"

 

 #include <binder/Parcel.h>

 #include "android_os_Parcel.h"

@@ -38,6 +39,23 @@
     }

 }

 

+static void FromColor_D32_Raw(void* dst, const SkColor src[], int width,

+                          int, int) {

+    // SkColor's ordering may be different from SkPMColor

+    if (SK_COLOR_MATCHES_PMCOLOR_BYTE_ORDER) {

+        memcpy(dst, src, width * sizeof(SkColor));

+        return;

+    }

+

+    // order isn't same, repack each pixel manually

+    SkPMColor* d = (SkPMColor*)dst;

+    for (int i = 0; i < width; i++) {

+        SkColor c = *src++;

+        *d++ = SkPackARGB32NoCheck(SkColorGetA(c), SkColorGetR(c),

+                                   SkColorGetG(c), SkColorGetB(c));

+    }

+}

+

 static void FromColor_D565(void* dst, const SkColor src[], int width,

                            int x, int y) {

     uint16_t* d = (uint16_t*)dst;

@@ -56,19 +74,35 @@
 

     DITHER_4444_SCAN(y);

     for (int stop = x + width; x < stop; x++) {

-        SkPMColor c = SkPreMultiplyColor(*src++);

-        *d++ = SkDitherARGB32To4444(c, DITHER_VALUE(x));

-//        *d++ = SkPixel32ToPixel4444(c);

+        SkPMColor pmc = SkPreMultiplyColor(*src++);

+        *d++ = SkDitherARGB32To4444(pmc, DITHER_VALUE(x));

+//        *d++ = SkPixel32ToPixel4444(pmc);

+    }

+}

+

+static void FromColor_D4444_Raw(void* dst, const SkColor src[], int width,

+                            int x, int y) {

+    SkPMColor16* d = (SkPMColor16*)dst;

+

+    DITHER_4444_SCAN(y);

+    for (int stop = x + width; x < stop; x++) {

+        SkColor c = *src++;

+

+        // SkPMColor is used because the ordering is ARGB32, even though the target actually premultiplied

+        SkPMColor pmc = SkPackARGB32NoCheck(SkColorGetA(c), SkColorGetR(c),

+                                            SkColorGetG(c), SkColorGetB(c));

+        *d++ = SkDitherARGB32To4444(pmc, DITHER_VALUE(x));

+//        *d++ = SkPixel32ToPixel4444(pmc);

     }

 }

 

 // can return NULL

-static FromColorProc ChooseFromColorProc(SkBitmap::Config config) {

+static FromColorProc ChooseFromColorProc(SkBitmap::Config config, bool isPremultiplied) {

     switch (config) {

         case SkBitmap::kARGB_8888_Config:

-            return FromColor_D32;

+            return isPremultiplied ? FromColor_D32 : FromColor_D32_Raw;

         case SkBitmap::kARGB_4444_Config:

-            return FromColor_D4444;

+            return isPremultiplied ? FromColor_D4444 : FromColor_D4444_Raw;

         case SkBitmap::kRGB_565_Config:

             return FromColor_D565;

         default:

@@ -77,13 +111,12 @@
     return NULL;

 }

 

-bool GraphicsJNI::SetPixels(JNIEnv* env, jintArray srcColors,

-                            int srcOffset, int srcStride,

-                            int x, int y, int width, int height,

-                            const SkBitmap& dstBitmap) {

+bool GraphicsJNI::SetPixels(JNIEnv* env, jintArray srcColors, int srcOffset, int srcStride,

+        int x, int y, int width, int height,

+        const SkBitmap& dstBitmap, bool isPremultiplied) {

     SkAutoLockPixels alp(dstBitmap);

     void* dst = dstBitmap.getPixels();

-    FromColorProc proc = ChooseFromColorProc(dstBitmap.config());

+    FromColorProc proc = ChooseFromColorProc(dstBitmap.config(), isPremultiplied);

 

     if (NULL == dst || NULL == proc) {

         return false;

@@ -122,6 +155,17 @@
     } while (--width != 0);

 }

 

+static void ToColor_S32_Raw(SkColor dst[], const void* src, int width,

+                              SkColorTable*) {

+    SkASSERT(width > 0);

+    const SkPMColor* s = (const SkPMColor*)src;

+    do {

+        SkPMColor c = *s++;

+        *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c),

+                                SkGetPackedG32(c), SkGetPackedB32(c));

+    } while (--width != 0);

+}

+

 static void ToColor_S32_Opaque(SkColor dst[], const void* src, int width,

                                SkColorTable*) {

     SkASSERT(width > 0);

@@ -142,6 +186,17 @@
     } while (--width != 0);

 }

 

+static void ToColor_S4444_Raw(SkColor dst[], const void* src, int width,

+                                SkColorTable*) {

+    SkASSERT(width > 0);

+    const SkPMColor16* s = (const SkPMColor16*)src;

+    do {

+        SkPMColor c = SkPixel4444ToPixel32(*s++);

+        *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c),

+                                SkGetPackedG32(c), SkGetPackedB32(c));

+    } while (--width != 0);

+}

+

 static void ToColor_S4444_Opaque(SkColor dst[], const void* src, int width,

                                  SkColorTable*) {

     SkASSERT(width > 0);

@@ -175,6 +230,19 @@
     ctable->unlockColors(false);

 }

 

+static void ToColor_SI8_Raw(SkColor dst[], const void* src, int width,

+                              SkColorTable* ctable) {

+    SkASSERT(width > 0);

+    const uint8_t* s = (const uint8_t*)src;

+    const SkPMColor* colors = ctable->lockColors();

+    do {

+        SkPMColor c = colors[*s++];

+        *dst++ = SkColorSetARGB(SkGetPackedA32(c), SkGetPackedR32(c),

+                                SkGetPackedG32(c), SkGetPackedB32(c));

+    } while (--width != 0);

+    ctable->unlockColors(false);

+}

+

 static void ToColor_SI8_Opaque(SkColor dst[], const void* src, int width,

                                SkColorTable* ctable) {

     SkASSERT(width > 0);

@@ -189,19 +257,22 @@
 }

 

 // can return NULL

-static ToColorProc ChooseToColorProc(const SkBitmap& src) {

+static ToColorProc ChooseToColorProc(const SkBitmap& src, bool isPremultiplied) {

     switch (src.config()) {

         case SkBitmap::kARGB_8888_Config:

-            return src.isOpaque() ? ToColor_S32_Opaque : ToColor_S32_Alpha;

+            if (src.isOpaque()) return ToColor_S32_Opaque;

+            return isPremultiplied ? ToColor_S32_Alpha : ToColor_S32_Raw;

         case SkBitmap::kARGB_4444_Config:

-            return src.isOpaque() ? ToColor_S4444_Opaque : ToColor_S4444_Alpha;

+            if (src.isOpaque()) return ToColor_S4444_Opaque;

+            return isPremultiplied ? ToColor_S4444_Alpha : ToColor_S4444_Raw;

         case SkBitmap::kRGB_565_Config:

             return ToColor_S565;

         case SkBitmap::kIndex8_Config:

             if (src.getColorTable() == NULL) {

                 return NULL;

             }

-            return src.isOpaque() ? ToColor_SI8_Opaque : ToColor_SI8_Alpha;

+            if (src.isOpaque()) return ToColor_SI8_Opaque;

+            return isPremultiplied ? ToColor_SI8_Raw : ToColor_SI8_Alpha;

         default:

             break;

     }

@@ -211,6 +282,12 @@
 ///////////////////////////////////////////////////////////////////////////////

 ///////////////////////////////////////////////////////////////////////////////

 

+static int getPremulBitmapCreateFlags(bool isMutable) {

+    int flags = GraphicsJNI::kBitmapCreateFlag_Premultiplied;

+    if (isMutable) flags |= GraphicsJNI::kBitmapCreateFlag_Mutable;

+    return flags;

+}

+

 static jobject Bitmap_creator(JNIEnv* env, jobject, jintArray jColors,

                               int offset, int stride, int width, int height,

                               SkBitmap::Config config, jboolean isMutable) {

@@ -222,8 +299,12 @@
         }

     }

 

-    SkBitmap bitmap;

+    // ARGB_4444 is a deprecated format, convert automatically to 8888

+    if (config == SkBitmap::kARGB_4444_Config) {

+        config = SkBitmap::kARGB_8888_Config;

+    }

 

+    SkBitmap bitmap;

     bitmap.setConfig(config, width, height);

 

     jbyteArray buff = GraphicsJNI::allocateJavaPixelRef(env, &bitmap, NULL);

@@ -233,10 +314,11 @@
 

     if (jColors != NULL) {

         GraphicsJNI::SetPixels(env, jColors, offset, stride,

-                               0, 0, width, height, bitmap);

+                0, 0, width, height, bitmap, true);

     }

 

-    return GraphicsJNI::createBitmap(env, new SkBitmap(bitmap), buff, isMutable, NULL, NULL);

+    return GraphicsJNI::createBitmap(env, new SkBitmap(bitmap), buff,

+            getPremulBitmapCreateFlags(isMutable), NULL, NULL);

 }

 

 static jobject Bitmap_copy(JNIEnv* env, jobject, const SkBitmap* src,

@@ -247,8 +329,8 @@
     if (!src->copyTo(&result, dstConfig, &allocator)) {

         return NULL;

     }

-

-    return GraphicsJNI::createBitmap(env, new SkBitmap(result), allocator.getStorageObj(), isMutable, NULL, NULL);

+    return GraphicsJNI::createBitmap(env, new SkBitmap(result), allocator.getStorageObj(),

+            getPremulBitmapCreateFlags(isMutable), NULL, NULL);

 }

 

 static void Bitmap_destructor(JNIEnv* env, jobject, SkBitmap* bitmap) {

@@ -271,6 +353,26 @@
     return true;

 }

 

+static void Bitmap_reconfigure(JNIEnv* env, jobject clazz, jint bitmapInt,

+        int width, int height, SkBitmap::Config config, int allocSize) {

+    if (width * height * SkBitmap::ComputeBytesPerPixel(config) > allocSize) {

+        // done in native as there's no way to get BytesPerPixel in Java

+        doThrowIAE(env, "Bitmap not large enough to support new configuration");

+        return;

+    }

+    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapInt);

+    SkPixelRef* ref = bitmap->pixelRef();

+    SkSafeRef(ref);

+    bitmap->setConfig(config, width, height);

+    bitmap->setPixelRef(ref);

+

+    // notifyPixelsChanged will increment the generation ID even though the actual pixel data

+    // hasn't been touched. This signals the renderer that the bitmap (including width, height,

+    // and config) has changed.

+    ref->notifyPixelsChanged();

+    SkSafeUnref(ref);

+}

+

 // These must match the int values in Bitmap.java

 enum JavaEncodeFormat {

     kJPEG_JavaEncodeFormat = 0,

@@ -324,14 +426,6 @@
     bitmap->eraseColor(color);

 }

 

-static int Bitmap_width(JNIEnv* env, jobject, SkBitmap* bitmap) {

-    return bitmap->width();

-}

-

-static int Bitmap_height(JNIEnv* env, jobject, SkBitmap* bitmap) {

-    return bitmap->height();

-}

-

 static int Bitmap_rowBytes(JNIEnv* env, jobject, SkBitmap* bitmap) {

     return bitmap->rowBytes();

 }

@@ -426,7 +520,9 @@
     bitmap->unlockPixels();

 

     blob.release();

-    return GraphicsJNI::createBitmap(env, bitmap, buffer, isMutable, NULL, NULL, density);

+

+    return GraphicsJNI::createBitmap(env, bitmap, buffer, getPremulBitmapCreateFlags(isMutable),

+            NULL, NULL, density);

 }

 

 static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject,

@@ -504,16 +600,17 @@
         env->ReleaseIntArrayElements(offsetXY, array, 0);

     }

 

-    return GraphicsJNI::createBitmap(env, dst, allocator.getStorageObj(), true, NULL, NULL);

+    return GraphicsJNI::createBitmap(env, dst, allocator.getStorageObj(),

+            GraphicsJNI::kBitmapCreateFlag_Mutable, NULL, NULL);

 }

 

 ///////////////////////////////////////////////////////////////////////////////

 

 static int Bitmap_getPixel(JNIEnv* env, jobject, const SkBitmap* bitmap,

-                           int x, int y) {

+        int x, int y, bool isPremultiplied) {

     SkAutoLockPixels alp(*bitmap);

 

-    ToColorProc proc = ChooseToColorProc(*bitmap);

+    ToColorProc proc = ChooseToColorProc(*bitmap, isPremultiplied);

     if (NULL == proc) {

         return 0;

     }

@@ -528,11 +625,11 @@
 }

 

 static void Bitmap_getPixels(JNIEnv* env, jobject, const SkBitmap* bitmap,

-                             jintArray pixelArray, int offset, int stride,

-                             int x, int y, int width, int height) {

+        jintArray pixelArray, int offset, int stride,

+        int x, int y, int width, int height, bool isPremultiplied) {

     SkAutoLockPixels alp(*bitmap);

 

-    ToColorProc proc = ChooseToColorProc(*bitmap);

+    ToColorProc proc = ChooseToColorProc(*bitmap, isPremultiplied);

     if (NULL == proc) {

         return;

     }

@@ -555,13 +652,13 @@
 ///////////////////////////////////////////////////////////////////////////////

 

 static void Bitmap_setPixel(JNIEnv* env, jobject, const SkBitmap* bitmap,

-                            int x, int y, SkColor color) {

+        int x, int y, SkColor color, bool isPremultiplied) {

     SkAutoLockPixels alp(*bitmap);

     if (NULL == bitmap->getPixels()) {

         return;

     }

 

-    FromColorProc proc = ChooseFromColorProc(bitmap->config());

+    FromColorProc proc = ChooseFromColorProc(bitmap->config(), isPremultiplied);

     if (NULL == proc) {

         return;

     }

@@ -571,10 +668,10 @@
 }

 

 static void Bitmap_setPixels(JNIEnv* env, jobject, const SkBitmap* bitmap,

-                             jintArray pixelArray, int offset, int stride,

-                             int x, int y, int width, int height) {

+        jintArray pixelArray, int offset, int stride,

+        int x, int y, int width, int height, bool isPremultiplied) {

     GraphicsJNI::SetPixels(env, pixelArray, offset, stride,

-                           x, y, width, height, *bitmap);

+            x, y, width, height, *bitmap, isPremultiplied);

 }

 

 static void Bitmap_copyPixelsToBuffer(JNIEnv* env, jobject,

@@ -666,11 +763,10 @@
         (void*)Bitmap_copy },

     {   "nativeDestructor",         "(I)V", (void*)Bitmap_destructor },

     {   "nativeRecycle",            "(I)Z", (void*)Bitmap_recycle },

+    {   "nativeReconfigure",        "(IIIII)V", (void*)Bitmap_reconfigure },

     {   "nativeCompress",           "(IIILjava/io/OutputStream;[B)Z",

         (void*)Bitmap_compress },

     {   "nativeErase",              "(II)V", (void*)Bitmap_erase },

-    {   "nativeWidth",              "(I)I", (void*)Bitmap_width },

-    {   "nativeHeight",             "(I)I", (void*)Bitmap_height },

     {   "nativeRowBytes",           "(I)I", (void*)Bitmap_rowBytes },

     {   "nativeConfig",             "(I)I", (void*)Bitmap_config },

     {   "nativeHasAlpha",           "(I)Z", (void*)Bitmap_hasAlpha },

@@ -685,10 +781,10 @@
     {   "nativeExtractAlpha",       "(II[I)Landroid/graphics/Bitmap;",

         (void*)Bitmap_extractAlpha },

     {   "nativeGenerationId",       "(I)I", (void*)Bitmap_getGenerationId },

-    {   "nativeGetPixel",           "(III)I", (void*)Bitmap_getPixel },

-    {   "nativeGetPixels",          "(I[IIIIIII)V", (void*)Bitmap_getPixels },

-    {   "nativeSetPixel",           "(IIII)V", (void*)Bitmap_setPixel },

-    {   "nativeSetPixels",          "(I[IIIIIII)V", (void*)Bitmap_setPixels },

+    {   "nativeGetPixel",           "(IIIZ)I", (void*)Bitmap_getPixel },

+    {   "nativeGetPixels",          "(I[IIIIIIIZ)V", (void*)Bitmap_getPixels },

+    {   "nativeSetPixel",           "(IIIIZ)V", (void*)Bitmap_setPixel },

+    {   "nativeSetPixels",          "(I[IIIIIIIZ)V", (void*)Bitmap_setPixels },

     {   "nativeCopyPixelsToBuffer", "(ILjava/nio/Buffer;)V",

                                             (void*)Bitmap_copyPixelsToBuffer },

     {   "nativeCopyPixelsFromBuffer", "(ILjava/nio/Buffer;)V",

diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index daabce3..f9bb233 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -2,6 +2,7 @@
 
 #include "BitmapFactory.h"
 #include "NinePatchPeeker.h"
+#include "SkData.h"
 #include "SkImageDecoder.h"
 #include "SkImageRef_ashmem.h"
 #include "SkImageRef_GlobalPool.h"
@@ -13,6 +14,7 @@
 #include "AutoDecodeCancel.h"
 #include "Utils.h"
 #include "JNIHelp.h"
+#include "GraphicsJNI.h"
 
 #include <android_runtime/AndroidRuntime.h>
 #include <androidfw/Asset.h>
@@ -24,11 +26,16 @@
 jfieldID gOptions_justBoundsFieldID;
 jfieldID gOptions_sampleSizeFieldID;
 jfieldID gOptions_configFieldID;
+jfieldID gOptions_premultipliedFieldID;
 jfieldID gOptions_mutableFieldID;
 jfieldID gOptions_ditherFieldID;
 jfieldID gOptions_purgeableFieldID;
 jfieldID gOptions_shareableFieldID;
 jfieldID gOptions_preferQualityOverSpeedFieldID;
+jfieldID gOptions_scaledFieldID;
+jfieldID gOptions_densityFieldID;
+jfieldID gOptions_screenDensityFieldID;
+jfieldID gOptions_targetDensityFieldID;
 jfieldID gOptions_widthFieldID;
 jfieldID gOptions_heightFieldID;
 jfieldID gOptions_mimeFieldID;
@@ -61,6 +68,7 @@
         { SkImageDecoder::kICO_Format,  "image/x-ico" },
         { SkImageDecoder::kJPEG_Format, "image/jpeg" },
         { SkImageDecoder::kPNG_Format,  "image/png" },
+        { SkImageDecoder::kWEBP_Format, "image/webp" },
         { SkImageDecoder::kWBMP_Format, "image/vnd.wap.wbmp" }
     };
 
@@ -112,30 +120,6 @@
     }
 }
 
-static jbyteArray nativeScaleNinePatch(JNIEnv* env, jobject, jbyteArray chunkObject, jfloat scale,
-        jobject padding) {
-
-    jbyte* array = env->GetByteArrayElements(chunkObject, 0);
-    if (array != NULL) {
-        size_t chunkSize = env->GetArrayLength(chunkObject);
-        void* storage = alloca(chunkSize);
-        android::Res_png_9patch* chunk = static_cast<android::Res_png_9patch*>(storage);
-        memcpy(chunk, array, chunkSize);
-        android::Res_png_9patch::deserialize(chunk);
-
-        scaleNinePatchChunk(chunk, scale);
-        memcpy(array, chunk, chunkSize);
-
-        if (padding) {
-            GraphicsJNI::set_jrect(env, padding, chunk->paddingLeft, chunk->paddingTop,
-                    chunk->paddingRight, chunk->paddingBottom);
-        }
-
-        env->ReleaseByteArrayElements(chunkObject, array, 0);
-    }
-    return chunkObject;
-}
-
 static SkPixelRef* installPixelRef(SkBitmap* bitmap, SkStream* stream,
         int sampleSize, bool ditherImage) {
 
@@ -152,12 +136,80 @@
     return pr;
 }
 
+static SkBitmap::Config configForScaledOutput(SkBitmap::Config config) {
+    switch (config) {
+        case SkBitmap::kNo_Config:
+        case SkBitmap::kIndex8_Config:
+            return SkBitmap::kARGB_8888_Config;
+        default:
+            break;
+    }
+    return config;
+}
+
+class ScaleCheckingAllocator : public SkBitmap::HeapAllocator {
+public:
+    ScaleCheckingAllocator(float scale, int size)
+            : mScale(scale), mSize(size) {
+    }
+
+    virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
+        // accounts for scale in final allocation, using eventual size and config
+        const int bytesPerPixel = SkBitmap::ComputeBytesPerPixel(
+                configForScaledOutput(bitmap->getConfig()));
+        const int requestedSize = bytesPerPixel *
+                int(bitmap->width() * mScale + 0.5f) *
+                int(bitmap->height() * mScale + 0.5f);
+        if (requestedSize > mSize) {
+            ALOGW("bitmap for alloc reuse (%d bytes) can't fit scaled bitmap (%d bytes)",
+                    mSize, requestedSize);
+            return false;
+        }
+        return SkBitmap::HeapAllocator::allocPixelRef(bitmap, ctable);
+    }
+private:
+    const float mScale;
+    const int mSize;
+};
+
+class RecyclingPixelAllocator : public SkBitmap::Allocator {
+public:
+    RecyclingPixelAllocator(SkPixelRef* pixelRef, unsigned int size)
+            : mPixelRef(pixelRef), mSize(size) {
+        SkSafeRef(mPixelRef);
+    }
+
+    ~RecyclingPixelAllocator() {
+        SkSafeUnref(mPixelRef);
+    }
+
+    virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
+        if (!bitmap->getSize64().is32() || bitmap->getSize() > mSize) {
+            ALOGW("bitmap marked for reuse (%d bytes) can't fit new bitmap (%d bytes)",
+                    mSize, bitmap->getSize());
+            return false;
+        }
+
+        // Create a new pixelref with the new ctable that wraps the previous pixelref
+        SkPixelRef* pr = new AndroidPixelRef(*static_cast<AndroidPixelRef*>(mPixelRef), ctable);
+
+        bitmap->setPixelRef(pr)->unref();
+        // since we're already allocated, we lockPixels right away
+        // HeapAllocator/JavaPixelAllocator behaves this way too
+        bitmap->lockPixels();
+        return true;
+    }
+
+private:
+    SkPixelRef* const mPixelRef;
+    const unsigned int mSize;
+};
+
 // since we "may" create a purgeable imageref, we require the stream be ref'able
 // i.e. dynamically allocated, since its lifetime may exceed the current stack
 // frame.
-static jobject doDecode(JNIEnv* env, SkStream* stream, jobject padding,
-        jobject options, bool allowPurgeable, bool forcePurgeable = false,
-        bool applyScale = false, float scale = 1.0f) {
+static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding,
+        jobject options, bool allowPurgeable, bool forcePurgeable = false) {
 
     int sampleSize = 1;
 
@@ -166,10 +218,10 @@
 
     bool doDither = true;
     bool isMutable = false;
-    bool willScale = applyScale && scale != 1.0f;
-    bool isPurgeable = !willScale &&
-            (forcePurgeable || (allowPurgeable && optionsPurgeable(env, options)));
+    float scale = 1.0f;
+    bool isPurgeable = forcePurgeable || (allowPurgeable && optionsPurgeable(env, options));
     bool preferQualityOverSpeed = false;
+    bool requireUnpremultiplied = false;
 
     jobject javaBitmap = NULL;
 
@@ -190,12 +242,21 @@
         doDither = env->GetBooleanField(options, gOptions_ditherFieldID);
         preferQualityOverSpeed = env->GetBooleanField(options,
                 gOptions_preferQualityOverSpeedFieldID);
+        requireUnpremultiplied = !env->GetBooleanField(options, gOptions_premultipliedFieldID);
         javaBitmap = env->GetObjectField(options, gOptions_bitmapFieldID);
+
+        if (env->GetBooleanField(options, gOptions_scaledFieldID)) {
+            const int density = env->GetIntField(options, gOptions_densityFieldID);
+            const int targetDensity = env->GetIntField(options, gOptions_targetDensityFieldID);
+            const int screenDensity = env->GetIntField(options, gOptions_screenDensityFieldID);
+            if (density != 0 && targetDensity != 0 && density != screenDensity) {
+                scale = (float) targetDensity / density;
+            }
+        }
     }
 
-    if (willScale && javaBitmap != NULL) {
-        return nullObjectReturn("Cannot pre-scale a reused bitmap");
-    }
+    const bool willScale = scale != 1.0f;
+    isPurgeable &= !willScale;
 
     SkImageDecoder* decoder = SkImageDecoder::Factory(stream);
     if (decoder == NULL) {
@@ -205,39 +266,49 @@
     decoder->setSampleSize(sampleSize);
     decoder->setDitherImage(doDither);
     decoder->setPreferQualityOverSpeed(preferQualityOverSpeed);
+    decoder->setRequireUnpremultipliedColors(requireUnpremultiplied);
+
+    SkBitmap* outputBitmap = NULL;
+    unsigned int existingBufferSize = 0;
+    if (javaBitmap != NULL) {
+        outputBitmap = (SkBitmap*) env->GetIntField(javaBitmap, gBitmap_nativeBitmapFieldID);
+        if (outputBitmap->isImmutable()) {
+            ALOGW("Unable to reuse an immutable bitmap as an image decoder target.");
+            javaBitmap = NULL;
+            outputBitmap = NULL;
+        } else {
+            existingBufferSize = GraphicsJNI::getBitmapAllocationByteCount(env, javaBitmap);
+        }
+    }
+
+    SkAutoTDelete<SkBitmap> adb(outputBitmap == NULL ? new SkBitmap : NULL);
+    if (outputBitmap == NULL) outputBitmap = adb.get();
 
     NinePatchPeeker peeker(decoder);
-    JavaPixelAllocator javaAllocator(env);
-
-    SkBitmap* bitmap;
-    bool useExistingBitmap = false;
-    if (javaBitmap == NULL) {
-        bitmap = new SkBitmap;
-    } else {
-        if (sampleSize != 1) {
-            return nullObjectReturn("SkImageDecoder: Cannot reuse bitmap with sampleSize != 1");
-        }
-
-        bitmap = (SkBitmap*) env->GetIntField(javaBitmap, gBitmap_nativeBitmapFieldID);
-        // only reuse the provided bitmap if it is immutable
-        if (!bitmap->isImmutable()) {
-            useExistingBitmap = true;
-            // config of supplied bitmap overrules config set in options
-            prefConfig = bitmap->getConfig();
-        } else {
-            ALOGW("Unable to reuse an immutable bitmap as an image decoder target.");
-            bitmap = new SkBitmap;
-        }
-    }
-
-    SkAutoTDelete<SkImageDecoder> add(decoder);
-    SkAutoTDelete<SkBitmap> adb(!useExistingBitmap ? bitmap : NULL);
-
     decoder->setPeeker(&peeker);
-    if (!isPurgeable) {
-        decoder->setAllocator(&javaAllocator);
+
+    SkImageDecoder::Mode decodeMode = isPurgeable ? SkImageDecoder::kDecodeBounds_Mode : mode;
+
+    JavaPixelAllocator javaAllocator(env);
+    RecyclingPixelAllocator recyclingAllocator(outputBitmap->pixelRef(), existingBufferSize);
+    ScaleCheckingAllocator scaleCheckingAllocator(scale, existingBufferSize);
+    SkBitmap::Allocator* outputAllocator = (javaBitmap != NULL) ?
+            (SkBitmap::Allocator*)&recyclingAllocator : (SkBitmap::Allocator*)&javaAllocator;
+    if (decodeMode != SkImageDecoder::kDecodeBounds_Mode) {
+        if (!willScale) {
+            decoder->setAllocator(outputAllocator);
+        } else if (javaBitmap != NULL) {
+            // check for eventual scaled bounds at allocation time, so we don't decode the bitmap
+            // only to find the scaled result too large to fit in the allocation
+            decoder->setAllocator(&scaleCheckingAllocator);
+        }
     }
 
+    // Only setup the decoder to be deleted after its stack-based, refcounted
+    // components (allocators, peekers, etc) are declared. This prevents RefCnt
+    // asserts from firing due to the order objects are deleted from the stack.
+    SkAutoTDelete<SkImageDecoder> add(decoder);
+
     AutoDecoderCancel adc(options, decoder);
 
     // To fix the race condition in case "requestCancelDecode"
@@ -247,25 +318,13 @@
         return nullObjectReturn("gOptions_mCancelID");
     }
 
-    SkImageDecoder::Mode decodeMode = mode;
-    if (isPurgeable) {
-        decodeMode = SkImageDecoder::kDecodeBounds_Mode;
-    }
-
-    SkBitmap* decoded;
-    if (willScale) {
-        decoded = new SkBitmap;
-    } else {
-        decoded = bitmap;
-    }
-    SkAutoTDelete<SkBitmap> adb2(willScale ? decoded : NULL);
-
-    if (!decoder->decode(stream, decoded, prefConfig, decodeMode, javaBitmap != NULL)) {
+    SkBitmap decodingBitmap;
+    if (!decoder->decode(stream, &decodingBitmap, prefConfig, decodeMode)) {
         return nullObjectReturn("decoder->decode returned false");
     }
 
-    int scaledWidth = decoded->width();
-    int scaledHeight = decoded->height();
+    int scaledWidth = decodingBitmap.width();
+    int scaledHeight = decodingBitmap.height();
 
     if (willScale && mode != SkImageDecoder::kDecodeBounds_Mode) {
         scaledWidth = int(scaledWidth * scale + 0.5f);
@@ -333,33 +392,26 @@
         // Dalvik code has always behaved. We simply recreate the behavior here.
         // The result is slightly different from simply using scale because of
         // the 0.5f rounding bias applied when computing the target image size
-        const float sx = scaledWidth / float(decoded->width());
-        const float sy = scaledHeight / float(decoded->height());
+        const float sx = scaledWidth / float(decodingBitmap.width());
+        const float sy = scaledHeight / float(decodingBitmap.height());
 
-        SkBitmap::Config config = decoded->config();
-        switch (config) {
-            case SkBitmap::kNo_Config:
-            case SkBitmap::kIndex8_Config:
-            case SkBitmap::kRLE_Index8_Config:
-                config = SkBitmap::kARGB_8888_Config;
-                break;
-            default:
-                break;
-        }
-
-        bitmap->setConfig(config, scaledWidth, scaledHeight);
-        bitmap->setIsOpaque(decoded->isOpaque());
-        if (!bitmap->allocPixels(&javaAllocator, NULL)) {
+        // TODO: avoid copying when scaled size equals decodingBitmap size
+        SkBitmap::Config config = configForScaledOutput(decodingBitmap.config());
+        outputBitmap->setConfig(config, scaledWidth, scaledHeight);
+        outputBitmap->setIsOpaque(decodingBitmap.isOpaque());
+        if (!outputBitmap->allocPixels(outputAllocator, NULL)) {
             return nullObjectReturn("allocation failed for scaled bitmap");
         }
-        bitmap->eraseColor(0);
+        outputBitmap->eraseColor(0);
 
         SkPaint paint;
         paint.setFilterBitmap(true);
 
-        SkCanvas canvas(*bitmap);
+        SkCanvas canvas(*outputBitmap);
         canvas.scale(sx, sy);
-        canvas.drawBitmap(*decoded, 0.0f, 0.0f, &paint);
+        canvas.drawBitmap(decodingBitmap, 0.0f, 0.0f, &paint);
+    } else {
+        outputBitmap->swap(decodingBitmap);
     }
 
     if (padding) {
@@ -374,17 +426,17 @@
 
     SkPixelRef* pr;
     if (isPurgeable) {
-        pr = installPixelRef(bitmap, stream, sampleSize, doDither);
+        pr = installPixelRef(outputBitmap, stream, sampleSize, doDither);
     } else {
         // if we get here, we're in kDecodePixels_Mode and will therefore
         // already have a pixelref installed.
-        pr = bitmap->pixelRef();
+        pr = outputBitmap->pixelRef();
     }
     if (pr == NULL) {
         return nullObjectReturn("Got null SkPixelRef");
     }
 
-    if (!isMutable && !useExistingBitmap) {
+    if (!isMutable && javaBitmap == NULL) {
         // promise we will never change our pixels (great for sharing and pictures)
         pr->setImmutable();
     }
@@ -392,43 +444,36 @@
     // detach bitmap from its autodeleter, since we want to own it now
     adb.detach();
 
-    if (useExistingBitmap) {
+    if (javaBitmap != NULL) {
+        bool isPremultiplied = !requireUnpremultiplied;
+        GraphicsJNI::reinitBitmap(env, javaBitmap, outputBitmap, isPremultiplied);
+        outputBitmap->notifyPixelsChanged();
         // If a java bitmap was passed in for reuse, pass it back
         return javaBitmap;
     }
+
+    int bitmapCreateFlags = 0x0;
+    if (isMutable) bitmapCreateFlags |= GraphicsJNI::kBitmapCreateFlag_Mutable;
+    if (!requireUnpremultiplied) bitmapCreateFlags |= GraphicsJNI::kBitmapCreateFlag_Premultiplied;
+
     // now create the java bitmap
-    return GraphicsJNI::createBitmap(env, bitmap, javaAllocator.getStorageObj(),
-            isMutable, ninePatchChunk, layoutBounds, -1);
-}
-
-static jobject nativeDecodeStreamScaled(JNIEnv* env, jobject clazz, jobject is, jbyteArray storage,
-        jobject padding, jobject options, jboolean applyScale, jfloat scale) {
-
-    jobject bitmap = NULL;
-    SkStream* stream = CreateJavaInputStreamAdaptor(env, is, storage, 0);
-
-    if (stream) {
-        // for now we don't allow purgeable with java inputstreams
-        bitmap = doDecode(env, stream, padding, options, false, false, applyScale, scale);
-        stream->unref();
-    }
-    return bitmap;
+    return GraphicsJNI::createBitmap(env, outputBitmap, javaAllocator.getStorageObj(),
+            bitmapCreateFlags, ninePatchChunk, layoutBounds, -1);
 }
 
 static jobject nativeDecodeStream(JNIEnv* env, jobject clazz, jobject is, jbyteArray storage,
         jobject padding, jobject options) {
 
-    return nativeDecodeStreamScaled(env, clazz, is, storage, padding, options, false, 1.0f);
-}
+    jobject bitmap = NULL;
+    SkAutoTUnref<SkStreamRewindable> stream(GetRewindableStream(env, is, storage));
 
-static ssize_t getFDSize(int fd) {
-    off64_t curr = ::lseek64(fd, 0, SEEK_CUR);
-    if (curr < 0) {
-        return 0;
+    if (stream.get()) {
+        // for now we don't allow purgeable with java inputstreams
+        // FIXME: GetRewindableStream may have made a copy, in which case
+        // purgeable should be allowed.
+        bitmap = doDecode(env, stream, padding, options, false, false);
     }
-    size_t size = ::lseek(fd, 0, SEEK_END);
-    ::lseek64(fd, curr, SEEK_SET);
-    return size;
+    return bitmap;
 }
 
 static jobject nativeDecodeFileDescriptor(JNIEnv* env, jobject clazz, jobject fileDescriptor,
@@ -438,6 +483,12 @@
 
     jint descriptor = jniGetFDFromFileDescriptor(env, fileDescriptor);
 
+    struct stat fdStat;
+    if (fstat(descriptor, &fdStat) == -1) {
+        doThrowIOE(env, "broken file descriptor");
+        return nullObjectReturn("fstat return -1");
+    }
+
     bool isPurgeable = optionsPurgeable(env, bitmapFactoryOptions);
     bool isShareable = optionsShareable(env, bitmapFactoryOptions);
     bool weOwnTheFD = false;
@@ -449,17 +500,8 @@
         }
     }
 
-    SkFDStream* stream = new SkFDStream(descriptor, weOwnTheFD);
-    SkAutoUnref aur(stream);
-    if (!stream->isValid()) {
-        return NULL;
-    }
-
-    /* Restore our offset when we leave, so we can be called more than once
-       with the same descriptor. This is only required if we didn't dup the
-       file descriptor, but it is OK to do it all the time.
-    */
-    AutoFDSeek as(descriptor);
+    SkAutoTUnref<SkData> data(SkData::NewFromFD(descriptor));
+    SkAutoTUnref<SkMemoryStream> stream(new SkMemoryStream(data));
 
     /* Allow purgeable iff we own the FD, i.e., in the puregeable and
        shareable case.
@@ -467,44 +509,16 @@
     return doDecode(env, stream, padding, bitmapFactoryOptions, weOwnTheFD);
 }
 
-/*  make a deep copy of the asset, and return it as a stream, or NULL if there
-    was an error.
- */
-static SkStream* copyAssetToStream(Asset* asset) {
-    // if we could "ref/reopen" the asset, we may not need to copy it here
-    off64_t size = asset->seek(0, SEEK_SET);
-    if ((off64_t)-1 == size) {
-        SkDebugf("---- copyAsset: asset rewind failed\n");
-        return NULL;
-    }
+static jobject nativeDecodeAsset(JNIEnv* env, jobject clazz, jint native_asset,
+        jobject padding, jobject options) {
 
-    size = asset->getLength();
-    if (size <= 0) {
-        SkDebugf("---- copyAsset: asset->getLength() returned %d\n", size);
-        return NULL;
-    }
-
-    SkStream* stream = new SkMemoryStream(size);
-    void* data = const_cast<void*>(stream->getMemoryBase());
-    off64_t len = asset->read(data, size);
-    if (len != size) {
-        SkDebugf("---- copyAsset: asset->read(%d) returned %d\n", size, len);
-        delete stream;
-        stream = NULL;
-    }
-    return stream;
-}
-
-static jobject nativeDecodeAssetScaled(JNIEnv* env, jobject clazz, jint native_asset,
-        jobject padding, jobject options, jboolean applyScale, jfloat scale) {
-
-    SkStream* stream;
+    SkStreamRewindable* stream;
     Asset* asset = reinterpret_cast<Asset*>(native_asset);
     bool forcePurgeable = optionsPurgeable(env, options);
     if (forcePurgeable) {
         // if we could "ref/reopen" the asset, we may not need to copy it here
         // and we could assume optionsShareable, since assets are always RO
-        stream = copyAssetToStream(asset);
+        stream = CopyAssetToStream(asset);
         if (stream == NULL) {
             return NULL;
         }
@@ -514,13 +528,7 @@
         stream = new AssetStreamAdaptor(asset);
     }
     SkAutoUnref aur(stream);
-    return doDecode(env, stream, padding, options, true, forcePurgeable, applyScale, scale);
-}
-
-static jobject nativeDecodeAsset(JNIEnv* env, jobject clazz, jint native_asset,
-        jobject padding, jobject options) {
-
-    return nativeDecodeAssetScaled(env, clazz, native_asset, padding, options, false, 1.0f);
+    return doDecode(env, stream, padding, options, forcePurgeable, forcePurgeable);
 }
 
 static jobject nativeDecodeByteArray(JNIEnv* env, jobject, jbyteArray byteArray,
@@ -533,7 +541,7 @@
      */
     bool purgeable = optionsPurgeable(env, options) && !optionsJustBounds(env, options);
     AutoJavaByteArray ar(env, byteArray);
-    SkStream* stream = new SkMemoryStream(ar.ptr() + offset, length, purgeable);
+    SkMemoryStream* stream = new SkMemoryStream(ar.ptr() + offset, length, purgeable);
     SkAutoUnref aur(stream);
     return doDecode(env, stream, NULL, options, purgeable);
 }
@@ -554,10 +562,6 @@
         "(Ljava/io/InputStream;[BLandroid/graphics/Rect;Landroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap;",
         (void*)nativeDecodeStream
     },
-    {   "nativeDecodeStream",
-        "(Ljava/io/InputStream;[BLandroid/graphics/Rect;Landroid/graphics/BitmapFactory$Options;ZF)Landroid/graphics/Bitmap;",
-        (void*)nativeDecodeStreamScaled
-    },
 
     {   "nativeDecodeFileDescriptor",
         "(Ljava/io/FileDescriptor;Landroid/graphics/Rect;Landroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap;",
@@ -569,21 +573,11 @@
         (void*)nativeDecodeAsset
     },
 
-    {   "nativeDecodeAsset",
-        "(ILandroid/graphics/Rect;Landroid/graphics/BitmapFactory$Options;ZF)Landroid/graphics/Bitmap;",
-        (void*)nativeDecodeAssetScaled
-    },
-
     {   "nativeDecodeByteArray",
         "([BIILandroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap;",
         (void*)nativeDecodeByteArray
     },
 
-    {   "nativeScaleNinePatch",
-        "([BFLandroid/graphics/Rect;)[B",
-        (void*)nativeScaleNinePatch
-    },
-
     {   "nativeIsSeekable",
         "(Ljava/io/FileDescriptor;)Z",
         (void*)nativeIsSeekable
@@ -610,12 +604,17 @@
     gOptions_sampleSizeFieldID = getFieldIDCheck(env, options_class, "inSampleSize", "I");
     gOptions_configFieldID = getFieldIDCheck(env, options_class, "inPreferredConfig",
             "Landroid/graphics/Bitmap$Config;");
+    gOptions_premultipliedFieldID = getFieldIDCheck(env, options_class, "inPremultiplied", "Z");
     gOptions_mutableFieldID = getFieldIDCheck(env, options_class, "inMutable", "Z");
     gOptions_ditherFieldID = getFieldIDCheck(env, options_class, "inDither", "Z");
     gOptions_purgeableFieldID = getFieldIDCheck(env, options_class, "inPurgeable", "Z");
     gOptions_shareableFieldID = getFieldIDCheck(env, options_class, "inInputShareable", "Z");
     gOptions_preferQualityOverSpeedFieldID = getFieldIDCheck(env, options_class,
             "inPreferQualityOverSpeed", "Z");
+    gOptions_scaledFieldID = getFieldIDCheck(env, options_class, "inScaled", "Z");
+    gOptions_densityFieldID = getFieldIDCheck(env, options_class, "inDensity", "I");
+    gOptions_screenDensityFieldID = getFieldIDCheck(env, options_class, "inScreenDensity", "I");
+    gOptions_targetDensityFieldID = getFieldIDCheck(env, options_class, "inTargetDensity", "I");
     gOptions_widthFieldID = getFieldIDCheck(env, options_class, "outWidth", "I");
     gOptions_heightFieldID = getFieldIDCheck(env, options_class, "outHeight", "I");
     gOptions_mimeFieldID = getFieldIDCheck(env, options_class, "outMimeType", "Ljava/lang/String;");
diff --git a/core/jni/android/graphics/BitmapFactory.h b/core/jni/android/graphics/BitmapFactory.h
index f2aaab7..97dcc6d 100644
--- a/core/jni/android/graphics/BitmapFactory.h
+++ b/core/jni/android/graphics/BitmapFactory.h
@@ -7,6 +7,7 @@
 extern jfieldID gOptions_justBoundsFieldID;
 extern jfieldID gOptions_sampleSizeFieldID;
 extern jfieldID gOptions_configFieldID;
+extern jfieldID gOptions_premultipliedFieldID;
 extern jfieldID gOptions_ditherFieldID;
 extern jfieldID gOptions_purgeableFieldID;
 extern jfieldID gOptions_shareableFieldID;
diff --git a/core/jni/android/graphics/BitmapRegionDecoder.cpp b/core/jni/android/graphics/BitmapRegionDecoder.cpp
index b218bcd..ee47ac4 100644
--- a/core/jni/android/graphics/BitmapRegionDecoder.cpp
+++ b/core/jni/android/graphics/BitmapRegionDecoder.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "BitmapRegionDecoder"
 
 #include "SkBitmap.h"
+#include "SkData.h"
 #include "SkImageEncoder.h"
 #include "GraphicsJNI.h"
 #include "SkUtils.h"
@@ -25,7 +26,6 @@
 #include "SkStream.h"
 #include "BitmapFactory.h"
 #include "AutoDecodeCancel.h"
-#include "SkBitmapRegionDecoder.h"
 #include "CreateJavaOutputStreamAdaptor.h"
 #include "Utils.h"
 #include "JNIHelp.h"
@@ -49,28 +49,34 @@
 
 using namespace android;
 
-static SkMemoryStream* buildSkMemoryStream(SkStream *stream) {
-    size_t bufferSize = 4096;
-    size_t streamLen = 0;
-    size_t len;
-    char* data = (char*)sk_malloc_throw(bufferSize);
-
-    while ((len = stream->read(data + streamLen,
-                    bufferSize - streamLen)) != 0) {
-        streamLen += len;
-        if (streamLen == bufferSize) {
-            bufferSize *= 2;
-            data = (char*)sk_realloc_throw(data, bufferSize);
-        }
+class SkBitmapRegionDecoder {
+public:
+    SkBitmapRegionDecoder(SkImageDecoder* decoder, int width, int height) {
+        fDecoder = decoder;
+        fWidth = width;
+        fHeight = height;
     }
-    data = (char*)sk_realloc_throw(data, streamLen);
+    ~SkBitmapRegionDecoder() {
+        SkDELETE(fDecoder);
+    }
 
-    SkMemoryStream* streamMem = new SkMemoryStream();
-    streamMem->setMemoryOwned(data, streamLen);
-    return streamMem;
-}
+    bool decodeRegion(SkBitmap* bitmap, const SkIRect& rect,
+                      SkBitmap::Config pref, int sampleSize) {
+        fDecoder->setSampleSize(sampleSize);
+        return fDecoder->decodeRegion(bitmap, rect, pref);
+    }
 
-static jobject doBuildTileIndex(JNIEnv* env, SkStream* stream) {
+    SkImageDecoder* getDecoder() const { return fDecoder; }
+    int getWidth() const { return fWidth; }
+    int getHeight() const { return fHeight; }
+
+private:
+    SkImageDecoder* fDecoder;
+    int fWidth;
+    int fHeight;
+};
+
+static jobject createBitmapRegionDecoder(JNIEnv* env, SkStream* stream) {
     SkImageDecoder* decoder = SkImageDecoder::Factory(stream);
     int width, height;
     if (NULL == decoder) {
@@ -87,11 +93,11 @@
         snprintf(msg, sizeof(msg), "Image failed to decode using %s decoder",
                 decoder->getFormatName());
         doThrowIOE(env, msg);
+        SkDELETE(decoder);
         return nullObjectReturn("decoder->buildTileIndex returned false");
     }
 
-    SkBitmapRegionDecoder *bm = new SkBitmapRegionDecoder(decoder, stream, width, height);
-
+    SkBitmapRegionDecoder *bm = new SkBitmapRegionDecoder(decoder, width, height);
     return GraphicsJNI::createBitmapRegionDecoder(env, bm);
 }
 
@@ -103,7 +109,10 @@
      */
     AutoJavaByteArray ar(env, byteArray);
     SkStream* stream = new SkMemoryStream(ar.ptr() + offset, length, true);
-    return doBuildTileIndex(env, stream);
+
+    jobject brd = createBitmapRegionDecoder(env, stream);
+    SkSafeUnref(stream); // the decoder now holds a reference
+    return brd;
 }
 
 static jobject nativeNewInstanceFromFileDescriptor(JNIEnv* env, jobject clazz,
@@ -111,67 +120,48 @@
     NPE_CHECK_RETURN_ZERO(env, fileDescriptor);
 
     jint descriptor = jniGetFDFromFileDescriptor(env, fileDescriptor);
-    SkStream *stream = NULL;
+
     struct stat fdStat;
-    int newFD;
     if (fstat(descriptor, &fdStat) == -1) {
         doThrowIOE(env, "broken file descriptor");
         return nullObjectReturn("fstat return -1");
     }
 
-    if (isShareable &&
-            S_ISREG(fdStat.st_mode) &&
-            (newFD = ::dup(descriptor)) != -1) {
-        SkFDStream* fdStream = new SkFDStream(newFD, true);
-        if (!fdStream->isValid()) {
-            fdStream->unref();
-            return NULL;
-        }
-        stream = fdStream;
-    } else {
-        /* Restore our offset when we leave, so we can be called more than once
-           with the same descriptor. This is only required if we didn't dup the
-           file descriptor, but it is OK to do it all the time.
-        */
-        AutoFDSeek as(descriptor);
+    SkAutoTUnref<SkData> data(SkData::NewFromFD(descriptor));
+    SkMemoryStream* stream = new SkMemoryStream(data);
 
-        SkFDStream* fdStream = new SkFDStream(descriptor, false);
-        if (!fdStream->isValid()) {
-            fdStream->unref();
-            return NULL;
-        }
-        stream = buildSkMemoryStream(fdStream);
-        fdStream->unref();
-    }
-
-    return doBuildTileIndex(env, stream);
+    jobject brd = createBitmapRegionDecoder(env, stream);
+    SkSafeUnref(stream); // the decoder now holds a reference
+    return brd;
 }
 
 static jobject nativeNewInstanceFromStream(JNIEnv* env, jobject clazz,
                                   jobject is,       // InputStream
                                   jbyteArray storage, // byte[]
                                   jboolean isShareable) {
-    jobject largeBitmap = NULL;
-    SkStream* stream = CreateJavaInputStreamAdaptor(env, is, storage, 1024);
+    jobject brd = NULL;
+    // for now we don't allow shareable with java inputstreams
+    SkStreamRewindable* stream = CopyJavaInputStream(env, is, storage);
 
     if (stream) {
-        // for now we don't allow shareable with java inputstreams
-        SkMemoryStream *mStream = buildSkMemoryStream(stream);
-        largeBitmap = doBuildTileIndex(env, mStream);
-        stream->unref();
+        brd = createBitmapRegionDecoder(env, stream);
+        stream->unref(); // the decoder now holds a reference
     }
-    return largeBitmap;
+    return brd;
 }
 
 static jobject nativeNewInstanceFromAsset(JNIEnv* env, jobject clazz,
                                  jint native_asset, // Asset
                                  jboolean isShareable) {
-    SkStream* stream, *assStream;
     Asset* asset = reinterpret_cast<Asset*>(native_asset);
-    assStream = new AssetStreamAdaptor(asset);
-    stream = buildSkMemoryStream(assStream);
-    assStream->unref();
-    return doBuildTileIndex(env, stream);
+    SkAutoTUnref<SkMemoryStream> stream(CopyAssetToStream(asset));
+    if (NULL == stream.get()) {
+        return NULL;
+    }
+
+    jobject brd = createBitmapRegionDecoder(env, stream.get());
+    // The decoder now holds a reference to stream.
+    return brd;
 }
 
 /*
@@ -188,6 +178,7 @@
     SkBitmap::Config prefConfig = SkBitmap::kNo_Config;
     bool doDither = true;
     bool preferQualityOverSpeed = false;
+    bool requireUnpremultiplied = false;
 
     if (NULL != options) {
         sampleSize = env->GetIntField(options, gOptions_sampleSizeFieldID);
@@ -203,11 +194,13 @@
                 gOptions_preferQualityOverSpeedFieldID);
         // Get the bitmap for re-use if it exists.
         tileBitmap = env->GetObjectField(options, gOptions_bitmapFieldID);
+        requireUnpremultiplied = !env->GetBooleanField(options, gOptions_premultipliedFieldID);
     }
 
     decoder->setDitherImage(doDither);
     decoder->setPreferQualityOverSpeed(preferQualityOverSpeed);
-    AutoDecoderCancel   adc(options, decoder);
+    decoder->setRequireUnpremultipliedColors(requireUnpremultiplied);
+    AutoDecoderCancel adc(options, decoder);
 
     // To fix the race condition in case "requestCancelDecode"
     // happens earlier than AutoDecoderCancel object is added
@@ -257,7 +250,10 @@
 
     JavaPixelAllocator* allocator = (JavaPixelAllocator*) decoder->getAllocator();
     jbyteArray buff = allocator->getStorageObjAndReset();
-    return GraphicsJNI::createBitmap(env, bitmap, buff, false, NULL, NULL, -1);
+
+    int bitmapCreateFlags = 0;
+    if (!requireUnpremultiplied) bitmapCreateFlags |= GraphicsJNI::kBitmapCreateFlag_Premultiplied;
+    return GraphicsJNI::createBitmap(env, bitmap, buff, bitmapCreateFlags, NULL, NULL, -1);
 }
 
 static int nativeGetHeight(JNIEnv* env, jobject, SkBitmapRegionDecoder *brd) {
diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp
index 3308064..813dd5a 100644
--- a/core/jni/android/graphics/Canvas.cpp
+++ b/core/jni/android/graphics/Canvas.cpp
@@ -35,8 +35,6 @@
 
 #include <utils/Log.h>
 
-#define TIME_DRAWx
-
 static uint32_t get_thread_msec() {
 #if defined(HAVE_POSIX_CLOCKS)
     struct timespec tm;
@@ -463,20 +461,6 @@
         canvas->drawPath(*path, *paint);
     }
  
-    static void drawPicture(JNIEnv* env, jobject, SkCanvas* canvas,
-                            SkPicture* picture) {
-        SkASSERT(canvas);
-        SkASSERT(picture);
-        
-#ifdef TIME_DRAW
-        SkMSec now = get_thread_msec(); //SkTime::GetMSecs();
-#endif
-        canvas->drawPicture(*picture);
-#ifdef TIME_DRAW
-        ALOGD("---- picture playback %d ms\n", get_thread_msec() - now);
-#endif
-    }
-
     static void drawBitmap__BitmapFFPaint(JNIEnv* env, jobject jcanvas,
                                           SkCanvas* canvas, SkBitmap* bitmap,
                                           jfloat left, jfloat top,
@@ -563,18 +547,17 @@
                                 jboolean hasAlpha, SkPaint* paint)
     {
         SkBitmap    bitmap;
-        
         bitmap.setConfig(hasAlpha ? SkBitmap::kARGB_8888_Config :
                          SkBitmap::kRGB_565_Config, width, height);
         if (!bitmap.allocPixels()) {
             return;
         }
-        
+
         if (!GraphicsJNI::SetPixels(env, jcolors, offset, stride,
-                                    0, 0, width, height, bitmap)) {
+                0, 0, width, height, bitmap, true)) {
             return;
         }
-        
+
         canvas->drawBitmap(bitmap, SkFloatToScalar(x), SkFloatToScalar(y),
                            paint);
     }
@@ -1103,7 +1086,6 @@
         (void*) SkCanvasGlue::drawTextOnPath___CIIPathFFPaint},
     {"native_drawTextOnPath","(ILjava/lang/String;IFFII)V",
         (void*) SkCanvasGlue::drawTextOnPath__StringPathFFPaint},
-    {"native_drawPicture", "(II)V", (void*) SkCanvasGlue::drawPicture},
 
     {"freeCaches", "()V", (void*) SkCanvasGlue::freeCaches},
 
diff --git a/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp b/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp
index aa4cbde..2d06b68 100644
--- a/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp
+++ b/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp
@@ -1,28 +1,77 @@
 #include "CreateJavaOutputStreamAdaptor.h"
-
-#define RETURN_NULL_IF_NULL(value) \
-    do { if (!(value)) { SkASSERT(0); return NULL; } } while (false)
+#include "JNIHelp.h"
+#include "SkData.h"
+#include "SkRefCnt.h"
+#include "SkStream.h"
+#include "SkTypes.h"
+#include "Utils.h"
+#include <androidfw/Asset.h>
 
 static jmethodID    gInputStream_resetMethodID;
 static jmethodID    gInputStream_markMethodID;
-static jmethodID    gInputStream_availableMethodID;
+static jmethodID    gInputStream_markSupportedMethodID;
 static jmethodID    gInputStream_readMethodID;
 static jmethodID    gInputStream_skipMethodID;
 
+class RewindableJavaStream;
+
+/**
+ *  Non-rewindable wrapper for a Java InputStream.
+ */
 class JavaInputStreamAdaptor : public SkStream {
 public:
     JavaInputStreamAdaptor(JNIEnv* env, jobject js, jbyteArray ar)
         : fEnv(env), fJavaInputStream(js), fJavaByteArray(ar) {
         SkASSERT(ar);
-        fCapacity   = env->GetArrayLength(ar);
+        fCapacity = env->GetArrayLength(ar);
         SkASSERT(fCapacity > 0);
-        fBytesRead  = 0;
+        fBytesRead = 0;
+        fIsAtEnd = false;
     }
 
-	virtual bool rewind() {
+    virtual size_t read(void* buffer, size_t size) {
+        JNIEnv* env = fEnv;
+        if (NULL == buffer) {
+            if (0 == size) {
+                return 0;
+            } else {
+                /*  InputStream.skip(n) can return <=0 but still not be at EOF
+                    If we see that value, we need to call read(), which will
+                    block if waiting for more data, or return -1 at EOF
+                 */
+                size_t amountSkipped = 0;
+                do {
+                    size_t amount = this->doSkip(size - amountSkipped);
+                    if (0 == amount) {
+                        char tmp;
+                        amount = this->doRead(&tmp, 1);
+                        if (0 == amount) {
+                            // if read returned 0, we're at EOF
+                            fIsAtEnd = true;
+                            break;
+                        }
+                    }
+                    amountSkipped += amount;
+                } while (amountSkipped < size);
+                return amountSkipped;
+            }
+        }
+        return this->doRead(buffer, size);
+    }
+
+    virtual bool isAtEnd() const {
+        return fIsAtEnd;
+    }
+
+private:
+    // Does not override rewind, since a JavaInputStreamAdaptor's interface
+    // does not support rewinding. RewindableJavaStream, which is a friend,
+    // will be able to call this method to rewind.
+    bool doRewind() {
         JNIEnv* env = fEnv;
 
         fBytesRead = 0;
+        fIsAtEnd = false;
 
         env->CallVoidMethod(fJavaInputStream, gInputStream_resetMethodID);
         if (env->ExceptionCheck()) {
@@ -53,6 +102,7 @@
             }
 
             if (n < 0) { // n == 0 should not be possible, see InputStream read() specifications.
+                fIsAtEnd = true;
                 break;  // eof
             }
 
@@ -92,91 +142,162 @@
         return (size_t)skipped;
     }
 
-    size_t doSize() {
-        JNIEnv* env = fEnv;
-        jint avail = env->CallIntMethod(fJavaInputStream,
-                                        gInputStream_availableMethodID);
-        if (env->ExceptionCheck()) {
-            env->ExceptionDescribe();
-            env->ExceptionClear();
-            SkDebugf("------- available threw an exception\n");
-            avail = 0;
-        }
-        return avail;
-    }
-
-	virtual size_t read(void* buffer, size_t size) {
-        JNIEnv* env = fEnv;
-        if (NULL == buffer) {
-            if (0 == size) {
-                return this->doSize();
-            } else {
-                /*  InputStream.skip(n) can return <=0 but still not be at EOF
-                    If we see that value, we need to call read(), which will
-                    block if waiting for more data, or return -1 at EOF
-                 */
-                size_t amountSkipped = 0;
-                do {
-                    size_t amount = this->doSkip(size - amountSkipped);
-                    if (0 == amount) {
-                        char tmp;
-                        amount = this->doRead(&tmp, 1);
-                        if (0 == amount) {
-                            // if read returned 0, we're at EOF
-                            break;
-                        }
-                    }
-                    amountSkipped += amount;
-                } while (amountSkipped < size);
-                return amountSkipped;
-            }
-        }
-        return this->doRead(buffer, size);
-    }
-
-private:
     JNIEnv*     fEnv;
     jobject     fJavaInputStream;   // the caller owns this object
     jbyteArray  fJavaByteArray;     // the caller owns this object
     size_t      fCapacity;
     size_t      fBytesRead;
+    bool        fIsAtEnd;
+
+    // Allows access to doRewind and fBytesRead.
+    friend class RewindableJavaStream;
 };
 
 SkStream* CreateJavaInputStreamAdaptor(JNIEnv* env, jobject stream,
-                                       jbyteArray storage, int markSize) {
-    static bool gInited;
-
-    if (!gInited) {
-        jclass inputStream_Clazz = env->FindClass("java/io/InputStream");
-        RETURN_NULL_IF_NULL(inputStream_Clazz);
-
-        gInputStream_resetMethodID      = env->GetMethodID(inputStream_Clazz,
-                                                           "reset", "()V");
-        gInputStream_markMethodID       = env->GetMethodID(inputStream_Clazz,
-                                                           "mark", "(I)V");
-        gInputStream_availableMethodID  = env->GetMethodID(inputStream_Clazz,
-                                                           "available", "()I");
-        gInputStream_readMethodID       = env->GetMethodID(inputStream_Clazz,
-                                                           "read", "([BII)I");
-        gInputStream_skipMethodID       = env->GetMethodID(inputStream_Clazz,
-                                                           "skip", "(J)J");
-
-        RETURN_NULL_IF_NULL(gInputStream_resetMethodID);
-        RETURN_NULL_IF_NULL(gInputStream_markMethodID);
-        RETURN_NULL_IF_NULL(gInputStream_availableMethodID);
-        RETURN_NULL_IF_NULL(gInputStream_readMethodID);
-        RETURN_NULL_IF_NULL(gInputStream_skipMethodID);
-
-        gInited = true;
-    }
-
-    if (markSize) {
-        env->CallVoidMethod(stream, gInputStream_markMethodID, markSize);
-    }
-
+                                       jbyteArray storage) {
     return new JavaInputStreamAdaptor(env, stream, storage);
 }
 
+
+static SkMemoryStream* adaptor_to_mem_stream(SkStream* adaptor) {
+    SkASSERT(adaptor != NULL);
+    SkDynamicMemoryWStream wStream;
+    const int bufferSize = 256 * 1024; // 256 KB, same as ViewStateSerializer.
+    uint8_t buffer[bufferSize];
+    do {
+        size_t bytesRead = adaptor->read(buffer, bufferSize);
+        wStream.write(buffer, bytesRead);
+    } while (!adaptor->isAtEnd());
+    SkAutoTUnref<SkData> data(wStream.copyToData());
+    return new SkMemoryStream(data.get());
+}
+
+SkStreamRewindable* CopyJavaInputStream(JNIEnv* env, jobject stream,
+                                        jbyteArray storage) {
+    SkAutoTUnref<SkStream> adaptor(CreateJavaInputStreamAdaptor(env, stream, storage));
+    if (NULL == adaptor.get()) {
+        return NULL;
+    }
+    return adaptor_to_mem_stream(adaptor.get());
+}
+
+/**
+ *  Wrapper for a Java InputStream which is rewindable and
+ *  has a length.
+ */
+class RewindableJavaStream : public SkStreamRewindable {
+public:
+    // RewindableJavaStream takes ownership of adaptor.
+    RewindableJavaStream(JavaInputStreamAdaptor* adaptor, size_t length)
+        : fAdaptor(adaptor)
+        , fLength(length) {
+        SkASSERT(fAdaptor != NULL);
+    }
+
+    virtual ~RewindableJavaStream() {
+        fAdaptor->unref();
+    }
+
+    virtual bool rewind() {
+        return fAdaptor->doRewind();
+    }
+
+    virtual size_t read(void* buffer, size_t size) {
+        return fAdaptor->read(buffer, size);
+    }
+
+    virtual bool isAtEnd() const {
+        return fAdaptor->isAtEnd();
+    }
+
+    virtual size_t getLength() const {
+        return fLength;
+    }
+
+    virtual bool hasLength() const {
+        return true;
+    }
+
+    virtual SkStreamRewindable* duplicate() const {
+        // Duplicating this stream requires rewinding and
+        // reading, which modify this Stream (and could
+        // fail, leaving this one invalid).
+        SkASSERT(false);
+        return NULL;
+    }
+
+private:
+    JavaInputStreamAdaptor* fAdaptor;
+    const size_t            fLength;
+};
+
+static jclass   gByteArrayInputStream_Clazz;
+static jfieldID gCountField;
+static jfieldID gPosField;
+
+/**
+ *  If jstream is a ByteArrayInputStream, return its remaining length. Otherwise
+ *  return 0.
+ */
+static size_t get_length_from_byte_array_stream(JNIEnv* env, jobject jstream) {
+    if (env->IsInstanceOf(jstream, gByteArrayInputStream_Clazz)) {
+        // Return the remaining length, to keep the same behavior of using the rest of the
+        // stream.
+        return env->GetIntField(jstream, gCountField) - env->GetIntField(jstream, gPosField);
+    }
+    return 0;
+}
+
+/**
+ *  If jstream is a class that has a length, return it. Otherwise
+ *  return 0.
+ *  Only checks for a set of subclasses.
+ */
+static size_t get_length_if_supported(JNIEnv* env, jobject jstream) {
+    size_t len = get_length_from_byte_array_stream(env, jstream);
+    if (len > 0) {
+        return len;
+    }
+    return 0;
+}
+
+SkStreamRewindable* GetRewindableStream(JNIEnv* env, jobject stream,
+                                        jbyteArray storage) {
+    SkAutoTUnref<SkStream> adaptor(CreateJavaInputStreamAdaptor(env, stream, storage));
+    if (NULL == adaptor.get()) {
+        return NULL;
+    }
+
+    const size_t length = get_length_if_supported(env, stream);
+    if (length > 0 && env->CallBooleanMethod(stream, gInputStream_markSupportedMethodID)) {
+        // Set the readLimit for mark to the end of the stream, so it can
+        // be rewound regardless of how much has been read.
+        env->CallVoidMethod(stream, gInputStream_markMethodID, length);
+        // RewindableJavaStream will unref adaptor when it is destroyed.
+        return new RewindableJavaStream(static_cast<JavaInputStreamAdaptor*>(adaptor.detach()),
+                                        length);
+    }
+
+    return adaptor_to_mem_stream(adaptor.get());
+}
+
+static jclass       gAssetInputStream_Clazz;
+static jmethodID    gGetAssetIntMethodID;
+
+android::AssetStreamAdaptor* CheckForAssetStream(JNIEnv* env, jobject jstream) {
+    if (!env->IsInstanceOf(jstream, gAssetInputStream_Clazz)) {
+        return NULL;
+    }
+
+    jint jasset = env->CallIntMethod(jstream, gGetAssetIntMethodID);
+    android::Asset* a = reinterpret_cast<android::Asset*>(jasset);
+    if (NULL == a) {
+        jniThrowNullPointerException(env, "NULL native asset");
+        return NULL;
+    }
+    return new android::AssetStreamAdaptor(a);
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 static jmethodID    gOutputStream_writeMethodID;
@@ -239,18 +360,57 @@
     static bool gInited;
 
     if (!gInited) {
-        jclass outputStream_Clazz = env->FindClass("java/io/OutputStream");
-        RETURN_NULL_IF_NULL(outputStream_Clazz);
-
-        gOutputStream_writeMethodID = env->GetMethodID(outputStream_Clazz,
-                                                       "write", "([BII)V");
-        RETURN_NULL_IF_NULL(gOutputStream_writeMethodID);
-        gOutputStream_flushMethodID = env->GetMethodID(outputStream_Clazz,
-                                                       "flush", "()V");
-        RETURN_NULL_IF_NULL(gOutputStream_flushMethodID);
 
         gInited = true;
     }
 
     return new SkJavaOutputStream(env, stream, storage);
 }
+
+static jclass findClassCheck(JNIEnv* env, const char classname[]) {
+    jclass clazz = env->FindClass(classname);
+    SkASSERT(!env->ExceptionCheck());
+    return clazz;
+}
+
+static jfieldID getFieldIDCheck(JNIEnv* env, jclass clazz,
+                                const char fieldname[], const char type[]) {
+    jfieldID id = env->GetFieldID(clazz, fieldname, type);
+    SkASSERT(!env->ExceptionCheck());
+    return id;
+}
+
+static jmethodID getMethodIDCheck(JNIEnv* env, jclass clazz,
+                                  const char methodname[], const char type[]) {
+    jmethodID id = env->GetMethodID(clazz, methodname, type);
+    SkASSERT(!env->ExceptionCheck());
+    return id;
+}
+
+int register_android_graphics_CreateJavaOutputStreamAdaptor(JNIEnv* env) {
+    jclass inputStream_Clazz = findClassCheck(env, "java/io/InputStream");
+    gInputStream_resetMethodID = getMethodIDCheck(env, inputStream_Clazz, "reset", "()V");
+    gInputStream_markMethodID = getMethodIDCheck(env, inputStream_Clazz, "mark", "(I)V");
+    gInputStream_markSupportedMethodID = getMethodIDCheck(env, inputStream_Clazz, "markSupported", "()Z");
+    gInputStream_readMethodID = getMethodIDCheck(env, inputStream_Clazz, "read", "([BII)I");
+    gInputStream_skipMethodID = getMethodIDCheck(env, inputStream_Clazz, "skip", "(J)J");
+
+    gByteArrayInputStream_Clazz = findClassCheck(env, "java/io/ByteArrayInputStream");
+    // Ref gByteArrayInputStream_Clazz so we can continue to refer to it when
+    // calling IsInstance.
+    gByteArrayInputStream_Clazz = (jclass) env->NewGlobalRef(gByteArrayInputStream_Clazz);
+    gCountField = getFieldIDCheck(env, gByteArrayInputStream_Clazz, "count", "I");
+    gPosField = getFieldIDCheck(env, gByteArrayInputStream_Clazz, "pos", "I");
+
+    gAssetInputStream_Clazz = findClassCheck(env, "android/content/res/AssetManager$AssetInputStream");
+    // Ref gAssetInputStream_Clazz so we can continue to refer to it when
+    // calling IsInstance.
+    gAssetInputStream_Clazz = (jclass) env->NewGlobalRef(gAssetInputStream_Clazz);
+    gGetAssetIntMethodID = getMethodIDCheck(env, gAssetInputStream_Clazz, "getAssetInt", "()I");
+
+    jclass outputStream_Clazz = findClassCheck(env, "java/io/OutputStream");
+    gOutputStream_writeMethodID = getMethodIDCheck(env, outputStream_Clazz, "write", "([BII)V");
+    gOutputStream_flushMethodID = getMethodIDCheck(env, outputStream_Clazz, "flush", "()V");
+
+    return 0;
+}
diff --git a/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.h b/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.h
index c34c96a..fcc0c9a 100644
--- a/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.h
+++ b/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.h
@@ -3,11 +3,68 @@
 
 //#include <android_runtime/AndroidRuntime.h>
 #include "jni.h"
-#include "SkStream.h"
 
+namespace android {
+    class AssetStreamAdaptor;
+}
+
+class SkMemoryStream;
+class SkStream;
+class SkStreamRewindable;
+class SkWStream;
+
+/**
+ *  Return an adaptor from a Java InputStream to an SkStream.
+ *  @param env JNIEnv object.
+ *  @param stream Pointer to Java InputStream.
+ *  @param storage Java byte array for retrieving data from the
+ *      Java InputStream.
+ *  @return SkStream Simple subclass of SkStream which supports its
+ *      basic methods like reading. Only valid until the calling
+ *      function returns, since the Java InputStream is not managed
+ *      by the SkStream.
+ */
 SkStream* CreateJavaInputStreamAdaptor(JNIEnv* env, jobject stream,
-                                       jbyteArray storage, int markSize = 0);
+                                       jbyteArray storage);
+
+/**
+ *  Copy a Java InputStream.
+ *  @param env JNIEnv object.
+ *  @param stream Pointer to Java InputStream.
+ *  @param storage Java byte array for retrieving data from the
+ *      Java InputStream.
+ *  @return SkStreamRewindable The data in stream will be copied
+ *      to a new SkStreamRewindable.
+ */
+SkStreamRewindable* CopyJavaInputStream(JNIEnv* env, jobject stream,
+                                        jbyteArray storage);
+
+/**
+ *  Get a rewindable stream from a Java InputStream.
+ *  @param env JNIEnv object.
+ *  @param stream Pointer to Java InputStream.
+ *  @param storage Java byte array for retrieving data from the
+ *      Java InputStream.
+ *  @return SkStreamRewindable Either a wrapper around the Java
+ *      InputStream, if possible, or a copy which is rewindable.
+ *      Since it may be a wrapper, must not be used after the
+ *      caller returns, like the result of CreateJavaInputStreamAdaptor.
+ */
+SkStreamRewindable* GetRewindableStream(JNIEnv* env, jobject stream,
+                                        jbyteArray storage);
+
+/**
+ *  If the Java InputStream is an AssetInputStream, return an adaptor.
+ *  This should not be used after the calling function returns, since
+ *  the caller may close the asset. Returns NULL if the stream is
+ *  not an AssetInputStream.
+ *  @param env JNIEnv object.
+ *  @param stream Pointer to Java InputStream.
+ *  @return AssetStreamAdaptor representing the InputStream, or NULL.
+ *      Must not be held onto.
+ */
+android::AssetStreamAdaptor* CheckForAssetStream(JNIEnv* env, jobject stream);
+
 SkWStream* CreateJavaOutputStreamAdaptor(JNIEnv* env, jobject stream,
                                          jbyteArray storage);
-
 #endif
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index d4c7600..8cb152d 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -152,6 +152,8 @@
 static jclass   gBitmap_class;
 static jfieldID gBitmap_nativeInstanceID;
 static jmethodID gBitmap_constructorMethodID;
+static jmethodID gBitmap_reinitMethodID;
+static jmethodID gBitmap_getAllocationByteCountMethodID;
 
 static jclass   gBitmapConfig_class;
 static jfieldID gBitmapConfig_nativeInstanceID;
@@ -345,24 +347,38 @@
 ///////////////////////////////////////////////////////////////////////////////////////////
 
 jobject GraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buffer,
-                                  bool isMutable, jbyteArray ninepatch, jintArray layoutbounds,
-                                  int density)
+        int bitmapCreateFlags, jbyteArray ninepatch, jintArray layoutbounds, int density)
 {
     SkASSERT(bitmap);
     SkASSERT(bitmap->pixelRef());
+    bool isMutable = bitmapCreateFlags & kBitmapCreateFlag_Mutable;
+    bool isPremultiplied = bitmapCreateFlags & kBitmapCreateFlag_Premultiplied;
+
     jobject obj = env->NewObject(gBitmap_class, gBitmap_constructorMethodID,
-            static_cast<jint>(reinterpret_cast<uintptr_t>(bitmap)),
-            buffer, isMutable, ninepatch, layoutbounds, density);
+            static_cast<jint>(reinterpret_cast<uintptr_t>(bitmap)), buffer,
+            bitmap->width(), bitmap->height(), density, isMutable, isPremultiplied,
+            ninepatch, layoutbounds);
     hasException(env); // For the side effect of logging.
     return obj;
 }
 
-jobject GraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, bool isMutable,
-                            jbyteArray ninepatch, int density)
+jobject GraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, int bitmapCreateFlags,
+        jbyteArray ninepatch, int density)
 {
-    return createBitmap(env, bitmap, NULL, isMutable, ninepatch, NULL, density);
+    return createBitmap(env, bitmap, NULL, bitmapCreateFlags, ninepatch, NULL, density);
 }
 
+void GraphicsJNI::reinitBitmap(JNIEnv* env, jobject javaBitmap, SkBitmap* bitmap,
+        bool isPremultiplied)
+{
+    env->CallVoidMethod(javaBitmap, gBitmap_reinitMethodID,
+            bitmap->width(), bitmap->height(), isPremultiplied);
+}
+
+int GraphicsJNI::getBitmapAllocationByteCount(JNIEnv* env, jobject javaBitmap)
+{
+    return env->CallIntMethod(javaBitmap, gBitmap_getAllocationByteCountMethodID);
+}
 
 jobject GraphicsJNI::createBitmapRegionDecoder(JNIEnv* env, SkBitmapRegionDecoder* bitmap)
 {
@@ -398,7 +414,8 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 AndroidPixelRef::AndroidPixelRef(JNIEnv* env, void* storage, size_t size, jbyteArray storageObj,
-        SkColorTable* ctable) : SkMallocPixelRef(storage, size, ctable) {
+        SkColorTable* ctable) : SkMallocPixelRef(storage, size, ctable, (storageObj == NULL)),
+        fWrappedPixelRef(NULL) {
     SkASSERT(storage);
     SkASSERT(env);
 
@@ -415,28 +432,59 @@
 
 }
 
+AndroidPixelRef::AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, SkColorTable* ctable) :
+        SkMallocPixelRef(wrappedPixelRef.getAddr(), wrappedPixelRef.getSize(), ctable, false),
+        fWrappedPixelRef(wrappedPixelRef.fWrappedPixelRef ?
+            wrappedPixelRef.fWrappedPixelRef : &wrappedPixelRef)
+{
+    SkASSERT(fWrappedPixelRef);
+    SkSafeRef(fWrappedPixelRef);
+
+    // don't need to initialize these, as all the relevant logic delegates to the wrapped ref
+    fStorageObj = NULL;
+    fHasGlobalRef = false;
+    fGlobalRefCnt = 0;
+    fOnJavaHeap = false;
+}
+
 AndroidPixelRef::~AndroidPixelRef() {
-    if (fOnJavaHeap) {
+    if (fWrappedPixelRef) {
+        SkSafeUnref(fWrappedPixelRef);
+    } else if (fOnJavaHeap) {
         JNIEnv* env = vm2env(fVM);
 
         if (fStorageObj && fHasGlobalRef) {
             env->DeleteGlobalRef(fStorageObj);
         }
         fStorageObj = NULL;
-
-        // Set this to NULL to prevent the SkMallocPixelRef destructor
-        // from freeing the memory.
-        fStorage = NULL;
     }
 }
+jbyteArray AndroidPixelRef::getStorageObj() {
+    if (fWrappedPixelRef) {
+        return fWrappedPixelRef->fStorageObj;
+    }
+    return fStorageObj;
+}
 
 void AndroidPixelRef::setLocalJNIRef(jbyteArray arr) {
-    if (!fHasGlobalRef) {
+    if (fWrappedPixelRef) {
+        // delegate java obj management to the wrapped ref
+        fWrappedPixelRef->setLocalJNIRef(arr);
+    } else if (!fHasGlobalRef) {
         fStorageObj = arr;
     }
 }
 
 void AndroidPixelRef::globalRef(void* localref) {
+    if (fWrappedPixelRef) {
+        // delegate java obj management to the wrapped ref
+        fWrappedPixelRef->globalRef(localref);
+
+        // Note: we only ref and unref the wrapped AndroidPixelRef so that
+        // bitmap->pixelRef()->globalRef() and globalUnref() can be used in a pair, even if
+        // the bitmap has its underlying AndroidPixelRef swapped out/wrapped
+        return;
+    }
     if (fOnJavaHeap && sk_atomic_inc(&fGlobalRefCnt) == 0) {
         JNIEnv *env = vm2env(fVM);
 
@@ -461,6 +509,11 @@
 }
 
 void AndroidPixelRef::globalUnref() {
+    if (fWrappedPixelRef) {
+        // delegate java obj management to the wrapped ref
+        fWrappedPixelRef->globalUnref();
+        return;
+    }
     if (fOnJavaHeap && sk_atomic_dec(&fGlobalRefCnt) == 1) {
         JNIEnv *env = vm2env(fVM);
         if (!fHasGlobalRef) {
@@ -586,8 +639,9 @@
 
     gBitmap_class = make_globalref(env, "android/graphics/Bitmap");
     gBitmap_nativeInstanceID = getFieldIDCheck(env, gBitmap_class, "mNativeBitmap", "I");
-    gBitmap_constructorMethodID = env->GetMethodID(gBitmap_class, "<init>",
-                                            "(I[BZ[B[II)V");
+    gBitmap_constructorMethodID = env->GetMethodID(gBitmap_class, "<init>", "(I[BIIIZZ[B[I)V");
+    gBitmap_reinitMethodID = env->GetMethodID(gBitmap_class, "reinit", "(IIZ)V");
+    gBitmap_getAllocationByteCountMethodID = env->GetMethodID(gBitmap_class, "getAllocationByteCount", "()I");
     gBitmapRegionDecoder_class = make_globalref(env, "android/graphics/BitmapRegionDecoder");
     gBitmapRegionDecoder_constructorMethodID = env->GetMethodID(gBitmapRegionDecoder_class, "<init>", "(I)V");
 
diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h
index c5b06f5..f4590b9 100644
--- a/core/jni/android/graphics/GraphicsJNI.h
+++ b/core/jni/android/graphics/GraphicsJNI.h
@@ -7,16 +7,22 @@
 #include "SkMallocPixelRef.h"
 #include "SkPoint.h"
 #include "SkRect.h"
-#include "../images/SkBitmapRegionDecoder.h"
-#include "../images/SkImageDecoder.h"
+#include "SkImageDecoder.h"
 #include <jni.h>
 
+class SkBitmapRegionDecoder;
 class SkCanvas;
 class SkPaint;
 class SkPicture;
 
 class GraphicsJNI {
 public:
+    enum BitmapCreateFlags {
+        kBitmapCreateFlag_None = 0x0,
+        kBitmapCreateFlag_Mutable = 0x1,
+        kBitmapCreateFlag_Premultiplied = 0x2,
+    };
+
     // returns true if an exception is set (and dumps it out to the Log)
     static bool hasException(JNIEnv*);
 
@@ -53,25 +59,29 @@
         storage array (may be null).
     */
     static jobject createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buffer,
-                                bool isMutable, jbyteArray ninepatch, jintArray layoutbounds,
-                                int density = -1);
+            int bitmapCreateFlags, jbyteArray ninepatch, jintArray layoutbounds, int density = -1);
 
-    static jobject createBitmap(JNIEnv* env, SkBitmap* bitmap, bool isMutable,
-                                jbyteArray ninepatch, int density = -1);
+    static jobject createBitmap(JNIEnv* env, SkBitmap* bitmap, int bitmapCreateFlags,
+            jbyteArray ninepatch, int density = -1);
+
+    static void reinitBitmap(JNIEnv* env, jobject javaBitmap, SkBitmap* bitmap,
+            bool isPremultiplied);
+
+    static int getBitmapAllocationByteCount(JNIEnv* env, jobject javaBitmap);
 
     static jobject createRegion(JNIEnv* env, SkRegion* region);
 
     static jobject createBitmapRegionDecoder(JNIEnv* env, SkBitmapRegionDecoder* bitmap);
 
     static jbyteArray allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap,
-                                     SkColorTable* ctable);
+            SkColorTable* ctable);
 
     /** Copy the colors in colors[] to the bitmap, convert to the correct
         format along the way.
     */
     static bool SetPixels(JNIEnv* env, jintArray colors, int srcOffset,
-                          int srcStride, int x, int y, int width, int height,
-                          const SkBitmap& dstBitmap);
+            int srcStride, int x, int y, int width, int height,
+            const SkBitmap& dstBitmap, bool isPremultiplied);
 
     static jbyteArray getBitmapStorageObj(SkPixelRef *pixref);
 };
@@ -81,9 +91,16 @@
     AndroidPixelRef(JNIEnv* env, void* storage, size_t size, jbyteArray storageObj,
                     SkColorTable* ctable);
 
+    /**
+     * Creates an AndroidPixelRef that wraps (and refs) another to reuse/share
+     * the same storage and java byte array refcounting, yet have a different
+     * color table.
+     */
+    AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, SkColorTable* ctable);
+
     virtual ~AndroidPixelRef();
 
-    jbyteArray getStorageObj() { return fStorageObj; }
+    jbyteArray getStorageObj();
 
     void setLocalJNIRef(jbyteArray arr);
 
@@ -100,6 +117,8 @@
     virtual void globalUnref();
 
 private:
+    AndroidPixelRef* const fWrappedPixelRef; // if set, delegate memory management calls to this
+
     JavaVM* fVM;
     bool fOnJavaHeap; // If true, the memory was allocated on the Java heap
 
diff --git a/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp b/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp
index ce31c5b..a75efcf 100644
--- a/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp
+++ b/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp
@@ -138,16 +138,15 @@
 hb_blob_t* harfbuzzSkiaReferenceTable(hb_face_t* face, hb_tag_t tag, void* userData)
 {
     SkTypeface* typeface = reinterpret_cast<SkTypeface*>(userData);
-    SkFontID uniqueID = typeface->uniqueID();
 
-    const size_t tableSize = SkFontHost::GetTableSize(uniqueID, tag);
+    const size_t tableSize = typeface->getTableSize(tag);
     if (!tableSize)
         return 0;
 
     char* buffer = reinterpret_cast<char*>(malloc(tableSize));
     if (!buffer)
         return 0;
-    size_t actualSize = SkFontHost::GetTableData(uniqueID, tag, 0, tableSize, buffer);
+    size_t actualSize = typeface->getTableData(tag, 0, tableSize, buffer);
     if (tableSize != actualSize) {
         free(buffer);
         return 0;
diff --git a/core/jni/android/graphics/Movie.cpp b/core/jni/android/graphics/Movie.cpp
index 4f64ff8..2eae841 100644
--- a/core/jni/android/graphics/Movie.cpp
+++ b/core/jni/android/graphics/Movie.cpp
@@ -1,8 +1,10 @@
+#include "ScopedLocalRef.h"
 #include "SkMovie.h"
 #include "SkStream.h"
 #include "GraphicsJNI.h"
 #include "SkTemplates.h"
 #include "SkUtils.h"
+#include "Utils.h"
 #include "CreateJavaOutputStreamAdaptor.h"
 
 #include <androidfw/Asset.h>
@@ -83,9 +85,14 @@
 
     NPE_CHECK_RETURN_ZERO(env, istream);
 
-    // what is the lifetime of the array? Can the skstream hold onto it?
-    jbyteArray byteArray = env->NewByteArray(16*1024);
-    SkStream* strm = CreateJavaInputStreamAdaptor(env, istream, byteArray);
+    SkStreamRewindable* strm = CheckForAssetStream(env, istream);
+    jbyteArray byteArray = NULL;
+    ScopedLocalRef<jbyteArray> scoper(env, NULL);
+    if (NULL == strm) {
+        byteArray = env->NewByteArray(16*1024);
+        scoper.reset(byteArray);
+        strm = GetRewindableStream(env, istream, byteArray);
+    }
     if (NULL == strm) {
         return 0;
     }
diff --git a/core/jni/android/graphics/NinePatch.cpp b/core/jni/android/graphics/NinePatch.cpp
index 684b1c1..7e6aeae 100644
--- a/core/jni/android/graphics/NinePatch.cpp
+++ b/core/jni/android/graphics/NinePatch.cpp
@@ -21,22 +21,30 @@
 #include <androidfw/ResourceTypes.h>
 #include <utils/Log.h>
 
+#include <Caches.h>
+
 #include "SkCanvas.h"
 #include "SkRegion.h"
 #include "GraphicsJNI.h"
 
 #include "JNIHelp.h"
 
-extern void NinePatch_Draw(SkCanvas* canvas, const SkRect& bounds,
-                const SkBitmap& bitmap, const android::Res_png_9patch& chunk,
-                           const SkPaint* paint, SkRegion** outRegion);
+extern void NinePatch_Draw(SkCanvas* canvas, const SkRect& bounds, const SkBitmap& bitmap,
+        const android::Res_png_9patch& chunk, const SkPaint* paint, SkRegion** outRegion);
 
 using namespace android;
 
+/**
+ * IMPORTANT NOTE: 9patch chunks can be manipuated either as an array of bytes
+ * or as a Res_png_9patch instance. It is important to note that the size of the
+ * array required to hold a 9patch chunk is greater than sizeof(Res_png_9patch).
+ * The code below manipulates chunks as Res_png_9patch* types to draw and as
+ * int8_t* to allocate and free the backing storage.
+ */
+
 class SkNinePatchGlue {
 public:
-    static jboolean isNinePatchChunk(JNIEnv* env, jobject, jbyteArray obj)
-    {
+    static jboolean isNinePatchChunk(JNIEnv* env, jobject, jbyteArray obj) {
         if (NULL == obj) {
             return false;
         }
@@ -45,126 +53,110 @@
         }
         const jbyte* array = env->GetByteArrayElements(obj, 0);
         if (array != NULL) {
-            const Res_png_9patch* chunk =
-                                reinterpret_cast<const Res_png_9patch*>(array);
+            const Res_png_9patch* chunk = reinterpret_cast<const Res_png_9patch*>(array);
             int8_t wasDeserialized = chunk->wasDeserialized;
-            env->ReleaseByteArrayElements(obj, const_cast<jbyte*>(array),
-                                          JNI_ABORT);
+            env->ReleaseByteArrayElements(obj, const_cast<jbyte*>(array), JNI_ABORT);
             return wasDeserialized != -1;
         }
         return false;
     }
 
-    static void validateNinePatchChunk(JNIEnv* env, jobject, jint, jbyteArray obj)
-    {
-        if (env->GetArrayLength(obj) < (int) (sizeof(Res_png_9patch))) {
+    static int8_t* validateNinePatchChunk(JNIEnv* env, jobject, jint, jbyteArray obj) {
+        size_t chunkSize = env->GetArrayLength(obj);
+        if (chunkSize < (int) (sizeof(Res_png_9patch))) {
             jniThrowRuntimeException(env, "Array too small for chunk.");
-            return;
+            return NULL;
         }
 
-        // XXX Also check that dimensions are correct.
+        int8_t* storage = new int8_t[chunkSize];
+        // This call copies the content of the jbyteArray
+        env->GetByteArrayRegion(obj, 0, chunkSize, reinterpret_cast<jbyte*>(storage));
+        // Deserialize in place, return the array we just allocated
+        return (int8_t*) Res_png_9patch::deserialize(storage);
     }
 
-    static void draw(JNIEnv* env, SkCanvas* canvas, SkRect& bounds,
-                      const SkBitmap* bitmap, jbyteArray chunkObj, const SkPaint* paint,
-                      jint destDensity, jint srcDensity)
-    {
-        size_t chunkSize = env->GetArrayLength(chunkObj);
-        void* storage = alloca(chunkSize);
-        env->GetByteArrayRegion(chunkObj, 0, chunkSize,
-                                reinterpret_cast<jbyte*>(storage));
-        if (!env->ExceptionCheck()) {
-            // need to deserialize the chunk
-            Res_png_9patch* chunk = static_cast<Res_png_9patch*>(storage);
-            assert(chunkSize == chunk->serializedSize());
-            // this relies on deserialization being done in place
-            Res_png_9patch::deserialize(chunk);
+    static void finalize(JNIEnv* env, jobject, int8_t* patch) {
+#ifdef USE_OPENGL_RENDERER
+        if (android::uirenderer::Caches::hasInstance()) {
+            Res_png_9patch* p = (Res_png_9patch*) patch;
+            android::uirenderer::Caches::getInstance().resourceCache.destructor(p);
+            return;
+        }
+#endif // USE_OPENGL_RENDERER
+        delete[] patch;
+    }
 
-            if (destDensity == srcDensity || destDensity == 0
-                    || srcDensity == 0) {
-                ALOGV("Drawing unscaled 9-patch: (%g,%g)-(%g,%g)",
-                        SkScalarToFloat(bounds.fLeft), SkScalarToFloat(bounds.fTop),
-                        SkScalarToFloat(bounds.fRight), SkScalarToFloat(bounds.fBottom));
-                NinePatch_Draw(canvas, bounds, *bitmap, *chunk, paint, NULL);
-            } else {
-                canvas->save();
+    static void draw(JNIEnv* env, SkCanvas* canvas, SkRect& bounds, const SkBitmap* bitmap,
+            Res_png_9patch* chunk, const SkPaint* paint, jint destDensity, jint srcDensity) {
+        if (destDensity == srcDensity || destDensity == 0 || srcDensity == 0) {
+            ALOGV("Drawing unscaled 9-patch: (%g,%g)-(%g,%g)",
+                    SkScalarToFloat(bounds.fLeft), SkScalarToFloat(bounds.fTop),
+                    SkScalarToFloat(bounds.fRight), SkScalarToFloat(bounds.fBottom));
+            NinePatch_Draw(canvas, bounds, *bitmap, *chunk, paint, NULL);
+        } else {
+            canvas->save();
 
-                SkScalar scale = SkFloatToScalar(destDensity / (float)srcDensity);
-                canvas->translate(bounds.fLeft, bounds.fTop);
-                canvas->scale(scale, scale);
+            SkScalar scale = SkFloatToScalar(destDensity / (float)srcDensity);
+            canvas->translate(bounds.fLeft, bounds.fTop);
+            canvas->scale(scale, scale);
 
-                bounds.fRight = SkScalarDiv(bounds.fRight-bounds.fLeft, scale);
-                bounds.fBottom = SkScalarDiv(bounds.fBottom-bounds.fTop, scale);
-                bounds.fLeft = bounds.fTop = 0;
+            bounds.fRight = SkScalarDiv(bounds.fRight-bounds.fLeft, scale);
+            bounds.fBottom = SkScalarDiv(bounds.fBottom-bounds.fTop, scale);
+            bounds.fLeft = bounds.fTop = 0;
 
-                ALOGV("Drawing scaled 9-patch: (%g,%g)-(%g,%g) srcDensity=%d destDensity=%d",
-                        SkScalarToFloat(bounds.fLeft), SkScalarToFloat(bounds.fTop),
-                        SkScalarToFloat(bounds.fRight), SkScalarToFloat(bounds.fBottom),
-                        srcDensity, destDensity);
+            ALOGV("Drawing scaled 9-patch: (%g,%g)-(%g,%g) srcDensity=%d destDensity=%d",
+                    SkScalarToFloat(bounds.fLeft), SkScalarToFloat(bounds.fTop),
+                    SkScalarToFloat(bounds.fRight), SkScalarToFloat(bounds.fBottom),
+                    srcDensity, destDensity);
 
-                NinePatch_Draw(canvas, bounds, *bitmap, *chunk, paint, NULL);
+            NinePatch_Draw(canvas, bounds, *bitmap, *chunk, paint, NULL);
 
-                canvas->restore();
-            }
+            canvas->restore();
         }
     }
 
     static void drawF(JNIEnv* env, jobject, SkCanvas* canvas, jobject boundsRectF,
-                      const SkBitmap* bitmap, jbyteArray chunkObj, const SkPaint* paint,
-                      jint destDensity, jint srcDensity)
-    {
+            const SkBitmap* bitmap, Res_png_9patch* chunk, const SkPaint* paint,
+            jint destDensity, jint srcDensity) {
         SkASSERT(canvas);
         SkASSERT(boundsRectF);
         SkASSERT(bitmap);
-        SkASSERT(chunkObj);
+        SkASSERT(chunk);
         // paint is optional
 
-        SkRect      bounds;
+        SkRect bounds;
         GraphicsJNI::jrectf_to_rect(env, boundsRectF, &bounds);
 
-        draw(env, canvas, bounds, bitmap, chunkObj, paint, destDensity, srcDensity);
+        draw(env, canvas, bounds, bitmap, chunk, paint, destDensity, srcDensity);
     }
 
     static void drawI(JNIEnv* env, jobject, SkCanvas* canvas, jobject boundsRect,
-                      const SkBitmap* bitmap, jbyteArray chunkObj, const SkPaint* paint,
-                      jint destDensity, jint srcDensity)
-    {
+            const SkBitmap* bitmap, Res_png_9patch* chunk, const SkPaint* paint,
+            jint destDensity, jint srcDensity) {
         SkASSERT(canvas);
         SkASSERT(boundsRect);
         SkASSERT(bitmap);
-        SkASSERT(chunkObj);
+        SkASSERT(chunk);
         // paint is optional
 
-        SkRect      bounds;
+        SkRect bounds;
         GraphicsJNI::jrect_to_rect(env, boundsRect, &bounds);
-        draw(env, canvas, bounds, bitmap, chunkObj, paint, destDensity, srcDensity);
+        draw(env, canvas, bounds, bitmap, chunk, paint, destDensity, srcDensity);
     }
 
-    static jint getTransparentRegion(JNIEnv* env, jobject,
-                    const SkBitmap* bitmap, jbyteArray chunkObj,
-                    jobject boundsRect)
-    {
+    static jint getTransparentRegion(JNIEnv* env, jobject, const SkBitmap* bitmap,
+            Res_png_9patch* chunk, jobject boundsRect) {
         SkASSERT(bitmap);
-        SkASSERT(chunkObj);
+        SkASSERT(chunk);
         SkASSERT(boundsRect);
 
-        SkRect      bounds;
+        SkRect bounds;
         GraphicsJNI::jrect_to_rect(env, boundsRect, &bounds);
-        size_t chunkSize = env->GetArrayLength(chunkObj);
-        void* storage = alloca(chunkSize);
-        env->GetByteArrayRegion(chunkObj, 0, chunkSize,
-                                reinterpret_cast<jbyte*>(storage));
-        if (!env->ExceptionCheck()) {
-            // need to deserialize the chunk
-            Res_png_9patch* chunk = static_cast<Res_png_9patch*>(storage);
-            assert(chunkSize == chunk->serializedSize());
-            // this relies on deserialization being done in place
-            Res_png_9patch::deserialize(chunk);
-            SkRegion* region = NULL;
-            NinePatch_Draw(NULL, bounds, *bitmap, *chunk, NULL, &region);
-            return (jint)region;
-        }
-        return 0;
+
+        SkRegion* region = NULL;
+        NinePatch_Draw(NULL, bounds, *bitmap, *chunk, NULL, &region);
+
+        return (jint) region;
     }
 
 };
@@ -174,18 +166,16 @@
 #include <android_runtime/AndroidRuntime.h>
 
 static JNINativeMethod gNinePatchMethods[] = {
-    { "isNinePatchChunk", "([B)Z",                      (void*)SkNinePatchGlue::isNinePatchChunk   },
-    { "validateNinePatchChunk", "(I[B)V",               (void*)SkNinePatchGlue::validateNinePatchChunk   },
-    { "nativeDraw", "(ILandroid/graphics/RectF;I[BIII)V", (void*)SkNinePatchGlue::drawF   },
-    { "nativeDraw", "(ILandroid/graphics/Rect;I[BIII)V",  (void*)SkNinePatchGlue::drawI   },
-    { "nativeGetTransparentRegion", "(I[BLandroid/graphics/Rect;)I",
-                                                        (void*)SkNinePatchGlue::getTransparentRegion   }
+    { "isNinePatchChunk", "([B)Z",                        (void*) SkNinePatchGlue::isNinePatchChunk },
+    { "validateNinePatchChunk", "(I[B)I",                 (void*) SkNinePatchGlue::validateNinePatchChunk },
+    { "nativeFinalize", "(I)V",                           (void*) SkNinePatchGlue::finalize },
+    { "nativeDraw", "(ILandroid/graphics/RectF;IIIII)V",  (void*) SkNinePatchGlue::drawF },
+    { "nativeDraw", "(ILandroid/graphics/Rect;IIIII)V",   (void*) SkNinePatchGlue::drawI },
+    { "nativeGetTransparentRegion", "(IILandroid/graphics/Rect;)I",
+                                                          (void*) SkNinePatchGlue::getTransparentRegion }
 };
 
-int register_android_graphics_NinePatch(JNIEnv* env)
-{
+int register_android_graphics_NinePatch(JNIEnv* env) {
     return android::AndroidRuntime::registerNativeMethods(env,
-                                                       "android/graphics/NinePatch",
-                                                       gNinePatchMethods,
-                                                       SK_ARRAY_COUNT(gNinePatchMethods));
+            "android/graphics/NinePatch", gNinePatchMethods, SK_ARRAY_COUNT(gNinePatchMethods));
 }
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 5454c08..40e0731 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -58,6 +58,10 @@
 static void defaultSettingsForAndroid(SkPaint* paint) {
     // GlyphID encoding is required because we are using Harfbuzz shaping
     paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+
+    SkPaintOptionsAndroid paintOpts = paint->getPaintOptionsAndroid();
+    paintOpts.setUseFontFallbacks(true);
+    paint->setPaintOptionsAndroid(paintOpts);
 }
 
 class SkPaintGlue {
@@ -109,7 +113,7 @@
     static void setHinting(JNIEnv* env, jobject paint, jint mode) {
         NPE_CHECK_RETURN_VOID(env, paint);
         GraphicsJNI::getNativePaint(env, paint)->setHinting(
-                mode == 0 ? SkPaint::kNo_Hinting : SkPaint::kSlight_Hinting);
+                mode == 0 ? SkPaint::kNo_Hinting : SkPaint::kNormal_Hinting);
     }
 
     static void setAntiAlias(JNIEnv* env, jobject paint, jboolean aa) {
@@ -300,7 +304,10 @@
         ScopedUtfChars localeChars(env, locale);
         char langTag[ULOC_FULLNAME_CAPACITY];
         toLanguageTag(langTag, ULOC_FULLNAME_CAPACITY, localeChars.c_str());
-        obj->setLanguage(SkLanguage(langTag));
+
+        SkPaintOptionsAndroid paintOpts = obj->getPaintOptionsAndroid();
+        paintOpts.setLanguage(langTag);
+        obj->setPaintOptionsAndroid(paintOpts);
     }
 
     static jfloat getTextSize(JNIEnv* env, jobject paint) {
@@ -757,8 +764,6 @@
     static void doTextBounds(JNIEnv* env, const jchar* text, int count,
                              jobject bounds, const SkPaint& paint, jint bidiFlags) {
         SkRect  r;
-        r.set(0,0,0,0);
-
         SkIRect ir;
 
         sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(&paint,
diff --git a/core/jni/android/graphics/Path.cpp b/core/jni/android/graphics/Path.cpp
index eb9e004..ab7f1dc 100644
--- a/core/jni/android/graphics/Path.cpp
+++ b/core/jni/android/graphics/Path.cpp
@@ -25,6 +25,7 @@
 #include <android_runtime/AndroidRuntime.h>
 
 #include "SkPath.h"
+#include "pathops/SkPathOps.h"
 
 #include <Caches.h>
 
@@ -67,8 +68,7 @@
         return obj->getFillType();
     }
  
-    static void setFillType(JNIEnv* env, jobject clazz, SkPath* path,
-                            SkPath::FillType ft) {
+    static void setFillType(JNIEnv* env, jobject clazz, SkPath* path, SkPath::FillType ft) {
         path->setFillType(ft);
     }
  
@@ -200,7 +200,7 @@
     }
  
     static void addRoundRectXY(JNIEnv* env, jobject clazz, SkPath* obj, jobject rect,
-                               jfloat rx, jfloat ry, SkPath::Direction dir) {
+            jfloat rx, jfloat ry, SkPath::Direction dir) {
         SkRect rect_;
         GraphicsJNI::jrectf_to_rect(env, rect, &rect_);
         SkScalar rx_ = SkFloatToScalar(rx);
@@ -209,7 +209,7 @@
     }
     
     static void addRoundRect8(JNIEnv* env, jobject, SkPath* obj, jobject rect,
-                              jfloatArray array, SkPath::Direction dir) {
+            jfloatArray array, SkPath::Direction dir) {
         SkRect rect_;
         GraphicsJNI::jrectf_to_rect(env, rect, &rect_);
         AutoJavaFloatArray  afa(env, array, 8);
@@ -261,7 +261,10 @@
     static void transform__Matrix(JNIEnv* env, jobject clazz, SkPath* obj, SkMatrix* matrix) {
         obj->transform(*matrix);
     }
- 
+
+    static jboolean op(JNIEnv* env, jobject clazz, SkPath* p1, SkPath* p2, SkPathOp op, SkPath* r) {
+         return Op(*p1, *p2, op, r);
+     }
 };
 
 static JNINativeMethod methods[] = {
@@ -301,7 +304,8 @@
     {"native_offset","(IFF)V", (void*) SkPathGlue::offset__FF},
     {"native_setLastPoint","(IFF)V", (void*) SkPathGlue::setLastPoint},
     {"native_transform","(III)V", (void*) SkPathGlue::transform__MatrixPath},
-    {"native_transform","(II)V", (void*) SkPathGlue::transform__Matrix}
+    {"native_transform","(II)V", (void*) SkPathGlue::transform__Matrix},
+    {"native_op","(IIII)Z", (void*) SkPathGlue::op}
 };
 
 int register_android_graphics_Path(JNIEnv* env) {
diff --git a/core/jni/android/graphics/Picture.cpp b/core/jni/android/graphics/Picture.cpp
index f28fc26..fcf22b8 100644
--- a/core/jni/android/graphics/Picture.cpp
+++ b/core/jni/android/graphics/Picture.cpp
@@ -20,6 +20,7 @@
 
 #include "SkCanvas.h"
 #include "SkPicture.h"
+#include "SkStream.h"
 #include "SkTemplates.h"
 #include "CreateJavaOutputStreamAdaptor.h"
 
@@ -40,7 +41,7 @@
         SkPicture* picture = NULL;
         SkStream* strm = CreateJavaInputStreamAdaptor(env, jstream, jstorage);
         if (strm) {
-            picture = new SkPicture(strm);
+            picture = SkPicture::CreateFromStream(strm);
             delete strm;
         }
         return picture;
diff --git a/core/jni/android/graphics/SurfaceTexture.cpp b/core/jni/android/graphics/SurfaceTexture.cpp
index 753f5dc..0c9b3bc 100644
--- a/core/jni/android/graphics/SurfaceTexture.cpp
+++ b/core/jni/android/graphics/SurfaceTexture.cpp
@@ -18,6 +18,9 @@
 
 #include <stdio.h>
 
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
 #include <gui/GLConsumer.h>
 #include <gui/Surface.h>
 
@@ -34,12 +37,13 @@
 namespace android {
 
 static const char* const OutOfResourcesException =
-    "android/graphics/SurfaceTexture$OutOfResourcesException";
+    "android/view/Surface$OutOfResourcesException";
 static const char* const IllegalStateException = "java/lang/IllegalStateException";
 const char* const kSurfaceTextureClassPathName = "android/graphics/SurfaceTexture";
 
 struct fields_t {
     jfieldID  surfaceTexture;
+    jfieldID  bufferQueue;
     jfieldID  frameAvailableListener;
     jmethodID postEvent;
 };
@@ -61,6 +65,20 @@
     env->SetIntField(thiz, fields.surfaceTexture, (int)surfaceTexture.get());
 }
 
+static void SurfaceTexture_setBufferQueue(JNIEnv* env, jobject thiz,
+        const sp<BufferQueue>& bq)
+{
+    BufferQueue* const p =
+        (BufferQueue*)env->GetIntField(thiz, fields.bufferQueue);
+    if (bq.get()) {
+        bq->incStrong((void*)SurfaceTexture_setBufferQueue);
+    }
+    if (p) {
+        p->decStrong((void*)SurfaceTexture_setBufferQueue);
+    }
+    env->SetIntField(thiz, fields.bufferQueue, (int)bq.get());
+}
+
 static void SurfaceTexture_setFrameAvailableListener(JNIEnv* env,
         jobject thiz, sp<GLConsumer::FrameAvailableListener> listener)
 {
@@ -76,23 +94,22 @@
     env->SetIntField(thiz, fields.frameAvailableListener, (int)listener.get());
 }
 
-sp<GLConsumer> SurfaceTexture_getSurfaceTexture(JNIEnv* env,
-        jobject thiz)
-{
+sp<GLConsumer> SurfaceTexture_getSurfaceTexture(JNIEnv* env, jobject thiz) {
     return (GLConsumer*)env->GetIntField(thiz, fields.surfaceTexture);
 }
 
-sp<ANativeWindow> android_SurfaceTexture_getNativeWindow(
-        JNIEnv* env, jobject thiz)
-{
+sp<IGraphicBufferProducer> SurfaceTexture_getProducer(JNIEnv* env, jobject thiz) {
+    return (BufferQueue*)env->GetIntField(thiz, fields.bufferQueue);
+}
+
+sp<ANativeWindow> android_SurfaceTexture_getNativeWindow(JNIEnv* env, jobject thiz) {
     sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
-    sp<Surface> surfaceTextureClient(surfaceTexture != NULL ?
-            new Surface(surfaceTexture->getBufferQueue()) : NULL);
+    sp<IGraphicBufferProducer> producer(SurfaceTexture_getProducer(env, thiz));
+    sp<Surface> surfaceTextureClient(surfaceTexture != NULL ? new Surface(producer) : NULL);
     return surfaceTextureClient;
 }
 
-bool android_SurfaceTexture_isInstanceOf(JNIEnv* env, jobject thiz)
-{
+bool android_SurfaceTexture_isInstanceOf(JNIEnv* env, jobject thiz) {
     jclass surfaceTextureClass = env->FindClass(kSurfaceTextureClassPathName);
     return env->IsInstanceOf(thiz, surfaceTextureClass);
 }
@@ -175,6 +192,12 @@
 
 // ----------------------------------------------------------------------------
 
+
+#define ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID "mSurfaceTexture"
+#define ANDROID_GRAPHICS_BUFFERQUEUE_JNI_ID "mBufferQueue"
+#define ANDROID_GRAPHICS_FRAMEAVAILABLELISTENER_JNI_ID \
+                                         "mFrameAvailableListener"
+
 static void SurfaceTexture_classInit(JNIEnv* env, jclass clazz)
 {
     fields.surfaceTexture = env->GetFieldID(clazz,
@@ -183,6 +206,12 @@
         ALOGE("can't find android/graphics/SurfaceTexture.%s",
                 ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID);
     }
+    fields.bufferQueue = env->GetFieldID(clazz,
+            ANDROID_GRAPHICS_BUFFERQUEUE_JNI_ID, "I");
+    if (fields.bufferQueue == NULL) {
+        ALOGE("can't find android/graphics/SurfaceTexture.%s",
+                ANDROID_GRAPHICS_BUFFERQUEUE_JNI_ID);
+    }
     fields.frameAvailableListener = env->GetFieldID(clazz,
             ANDROID_GRAPHICS_FRAMEAVAILABLELISTENER_JNI_ID, "I");
     if (fields.frameAvailableListener == NULL) {
@@ -197,16 +226,24 @@
     }
 }
 
-static void SurfaceTexture_init(JNIEnv* env, jobject thiz, jint texName,
-        jobject weakThiz, jboolean allowSynchronous)
+static void SurfaceTexture_init(JNIEnv* env, jobject thiz,
+        jint texName, jboolean singleBufferMode, jobject weakThiz)
 {
-    sp<GLConsumer> surfaceTexture(new GLConsumer(texName, allowSynchronous));
+    sp<BufferQueue> bq = new BufferQueue();
+
+    if (singleBufferMode) {
+        bq->disableAsyncBuffer();
+        bq->setDefaultMaxBufferCount(1);
+    }
+
+    sp<GLConsumer> surfaceTexture(new GLConsumer(bq, texName, GL_TEXTURE_EXTERNAL_OES, true, true));
     if (surfaceTexture == 0) {
         jniThrowException(env, OutOfResourcesException,
                 "Unable to create native SurfaceTexture");
         return;
     }
     SurfaceTexture_setSurfaceTexture(env, thiz, surfaceTexture);
+    SurfaceTexture_setBufferQueue(env, thiz, bq);
 
     jclass clazz = env->GetObjectClass(thiz);
     if (clazz == NULL) {
@@ -227,11 +264,11 @@
     surfaceTexture->setFrameAvailableListener(0);
     SurfaceTexture_setFrameAvailableListener(env, thiz, 0);
     SurfaceTexture_setSurfaceTexture(env, thiz, 0);
+    SurfaceTexture_setBufferQueue(env, thiz, 0);
 }
 
 static void SurfaceTexture_setDefaultBufferSize(
-        JNIEnv* env, jobject thiz, jint width, jint height)
-{
+        JNIEnv* env, jobject thiz, jint width, jint height) {
     sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
     surfaceTexture->setDefaultBufferSize(width, height);
 }
@@ -248,6 +285,18 @@
     }
 }
 
+static void SurfaceTexture_releaseTexImage(JNIEnv* env, jobject thiz)
+{
+    sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
+    status_t err = surfaceTexture->releaseTexImage();
+    if (err == INVALID_OPERATION) {
+        jniThrowException(env, IllegalStateException, "Unable to release texture contents (see "
+                "logcat for details)");
+    } else if (err < 0) {
+        jniThrowRuntimeException(env, "Error during updateTexImage (see logcat for details)");
+    }
+}
+
 static jint SurfaceTexture_detachFromGLContext(JNIEnv* env, jobject thiz)
 {
     sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
@@ -285,10 +334,11 @@
 
 static JNINativeMethod gSurfaceTextureMethods[] = {
     {"nativeClassInit",            "()V",   (void*)SurfaceTexture_classInit },
-    {"nativeInit",                 "(ILjava/lang/Object;Z)V", (void*)SurfaceTexture_init },
+    {"nativeInit",                 "(IZLjava/lang/Object;)V", (void*)SurfaceTexture_init },
     {"nativeFinalize",             "()V",   (void*)SurfaceTexture_finalize },
     {"nativeSetDefaultBufferSize", "(II)V", (void*)SurfaceTexture_setDefaultBufferSize },
     {"nativeUpdateTexImage",       "()V",   (void*)SurfaceTexture_updateTexImage },
+    {"nativeReleaseTexImage",      "()V",   (void*)SurfaceTexture_releaseTexImage },
     {"nativeDetachFromGLContext",  "()I",   (void*)SurfaceTexture_detachFromGLContext },
     {"nativeAttachToGLContext",    "(I)I",   (void*)SurfaceTexture_attachToGLContext },
     {"nativeGetTransformMatrix",   "([F)V", (void*)SurfaceTexture_getTransformMatrix },
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index b2cf9c1..73f3639 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -20,7 +20,6 @@
 
 #include "TextLayoutCache.h"
 #include "TextLayout.h"
-#include "SkFontHost.h"
 #include "SkTypeface_android.h"
 #include "HarfBuzzNGFaceSkia.h"
 #include <unicode/unistr.h>
@@ -219,7 +218,8 @@
  */
 TextLayoutCacheKey::TextLayoutCacheKey(): start(0), count(0), contextCount(0),
         dirFlags(0), typeface(NULL), textSize(0), textSkewX(0), textScaleX(0), flags(0),
-        hinting(SkPaint::kNo_Hinting), variant(SkPaint::kDefault_Variant), language()  {
+        hinting(SkPaint::kNo_Hinting) {
+    paintOpts.setUseFontFallbacks(true);
 }
 
 TextLayoutCacheKey::TextLayoutCacheKey(const SkPaint* paint, const UChar* text,
@@ -233,8 +233,7 @@
     textScaleX = paint->getTextScaleX();
     flags = paint->getFlags();
     hinting = paint->getHinting();
-    variant = paint->getFontVariant();
-    language = paint->getLanguage();
+    paintOpts = paint->getPaintOptionsAndroid();
 }
 
 TextLayoutCacheKey::TextLayoutCacheKey(const TextLayoutCacheKey& other) :
@@ -249,8 +248,7 @@
         textScaleX(other.textScaleX),
         flags(other.flags),
         hinting(other.hinting),
-        variant(other.variant),
-        language(other.language) {
+        paintOpts(other.paintOpts) {
 }
 
 int TextLayoutCacheKey::compare(const TextLayoutCacheKey& lhs, const TextLayoutCacheKey& rhs) {
@@ -284,11 +282,8 @@
     deltaInt = lhs.dirFlags - rhs.dirFlags;
     if (deltaInt) return (deltaInt);
 
-    deltaInt = lhs.variant - rhs.variant;
-    if (deltaInt) return (deltaInt);
-
-    if (lhs.language < rhs.language) return -1;
-    if (lhs.language > rhs.language) return +1;
+    if (lhs.paintOpts != rhs.paintOpts)
+        return memcmp(&lhs.paintOpts, &rhs.paintOpts, sizeof(SkPaintOptionsAndroid));
 
     return memcmp(lhs.getText(), rhs.getText(), lhs.contextCount * sizeof(UChar));
 }
@@ -307,7 +302,7 @@
     hash = JenkinsHashMix(hash, hash_type(textScaleX));
     hash = JenkinsHashMix(hash, flags);
     hash = JenkinsHashMix(hash, hinting);
-    hash = JenkinsHashMix(hash, variant);
+    hash = JenkinsHashMix(hash, paintOpts.getFontVariant());
     // Note: leaving out language is not problematic, as equality comparisons
     // are still valid - the only bad thing that could happen is collisions.
     hash = JenkinsHashMixShorts(hash, getText(), contextCount);
@@ -319,6 +314,7 @@
  */
 TextLayoutValue::TextLayoutValue(size_t contextCount) :
         mTotalAdvance(0), mElapsedTime(0) {
+    mBounds.setEmpty();
     // Give a hint for advances and glyphs vectors size
     mAdvances.setCapacity(contextCount);
     mGlyphs.setCapacity(contextCount);
@@ -346,11 +342,11 @@
     hb_buffer_destroy(mBuffer);
 }
 
-void TextLayoutShaper::computeValues(TextLayoutValue* value, const SkPaint* paint, const UChar* chars,
-        size_t start, size_t count, size_t contextCount, int dirFlags) {
-
+void TextLayoutShaper::computeValues(TextLayoutValue* value, const SkPaint* paint,
+        const UChar* chars, size_t start, size_t count, size_t contextCount, int dirFlags) {
     computeValues(paint, chars, start, count, contextCount, dirFlags,
-            &value->mAdvances, &value->mTotalAdvance, &value->mGlyphs, &value->mPos);
+            &value->mAdvances, &value->mTotalAdvance, &value->mBounds,
+            &value->mGlyphs, &value->mPos);
 #if DEBUG_ADVANCES
     ALOGD("Advances - start = %d, count = %d, contextCount = %d, totalAdvance = %f", start, count,
             contextCount, value->mTotalAdvance);
@@ -359,7 +355,7 @@
 
 void TextLayoutShaper::computeValues(const SkPaint* paint, const UChar* chars,
         size_t start, size_t count, size_t contextCount, int dirFlags,
-        Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
+        Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance, SkRect* outBounds,
         Vector<jchar>* const outGlyphs, Vector<jfloat>* const outPos) {
         *outTotalAdvance = 0;
         if (!count) {
@@ -455,7 +451,7 @@
                                     i, startRun, lengthRun, isRTL);
 #endif
                             computeRunValues(paint, chars, startRun, lengthRun, contextCount, isRTL,
-                                    outAdvances, outTotalAdvance, outGlyphs, outPos);
+                                    outAdvances, outTotalAdvance, outBounds, outGlyphs, outPos);
 
                         }
                     }
@@ -479,7 +475,7 @@
                     "-- run-start = %d, run-len = %d, isRTL = %d", start, count, isRTL);
 #endif
             computeRunValues(paint, chars, start, count, contextCount, isRTL,
-                    outAdvances, outTotalAdvance, outGlyphs, outPos);
+                    outAdvances, outTotalAdvance, outBounds, outGlyphs, outPos);
         }
 
 #if DEBUG_GLYPHS
@@ -676,7 +672,7 @@
 
 void TextLayoutShaper::computeRunValues(const SkPaint* paint, const UChar* contextChars,
         size_t start, size_t count, size_t contextCount, bool isRTL,
-        Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
+        Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance, SkRect* outBounds,
         Vector<jchar>* const outGlyphs, Vector<jfloat>* const outPos) {
     if (!count) {
         // We cannot shape an empty run.
@@ -698,8 +694,7 @@
     mShapingPaint.setTextScaleX(paint->getTextScaleX());
     mShapingPaint.setFlags(paint->getFlags());
     mShapingPaint.setHinting(paint->getHinting());
-    mShapingPaint.setFontVariant(paint->getFontVariant());
-    mShapingPaint.setLanguage(paint->getLanguage());
+    mShapingPaint.setPaintOptionsAndroid(paint->getPaintOptionsAndroid());
 
     // Split the BiDi run into Script runs. Harfbuzz will populate the pos, length and script
     // into the shaperItem
@@ -750,12 +745,22 @@
             size_t cluster = info[i].cluster - start;
             float xAdvance = HBFixedToFloat(positions[i].x_advance);
             outAdvances->replaceAt(outAdvances->itemAt(cluster) + xAdvance, cluster);
-            outGlyphs->add(info[i].codepoint + glyphBaseCount);
+            jchar glyphId = info[i].codepoint + glyphBaseCount;
+            outGlyphs->add(glyphId);
             float xo = HBFixedToFloat(positions[i].x_offset);
             float yo = -HBFixedToFloat(positions[i].y_offset);
-            outPos->add(totalAdvance + xo + yo * skewX);
-            outPos->add(yo);
+
+            float xpos = totalAdvance + xo + yo * skewX;
+            float ypos = yo;
+            outPos->add(xpos);
+            outPos->add(ypos);
             totalAdvance += xAdvance;
+
+            // TODO: consider using glyph cache
+            const SkGlyph& metrics = mShapingPaint.getGlyphMetrics(glyphId, NULL);
+            outBounds->join(xpos + metrics.fLeft, ypos + metrics.fTop,
+                    xpos + metrics.fLeft + metrics.fWidth, ypos + metrics.fTop + metrics.fHeight);
+
         }
     }
 
@@ -839,7 +844,7 @@
         if (typeface) {
             SkSafeRef(typeface);
         } else {
-            typeface = SkFontHost::CreateTypeface(NULL, NULL, SkTypeface::kNormal);
+            typeface = SkTypeface::CreateFromName(NULL, SkTypeface::kNormal);
 #if DEBUG_GLYPHS
             ALOGD("Using Default Typeface (normal style)");
 #endif
diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h
index 5414a11..54704ec 100644
--- a/core/jni/android/graphics/TextLayoutCache.h
+++ b/core/jni/android/graphics/TextLayoutCache.h
@@ -28,7 +28,6 @@
 #include <utils/Singleton.h>
 
 #include <SkAutoKern.h>
-#include <SkLanguage.h>
 #include <SkPaint.h>
 #include <SkTemplates.h>
 #include <SkTypeface.h>
@@ -104,8 +103,7 @@
     SkScalar textScaleX;
     uint32_t flags;
     SkPaint::Hinting hinting;
-    SkPaint::FontVariant variant;
-    SkLanguage language;
+    SkPaintOptionsAndroid paintOpts;
 
 }; // TextLayoutCacheKey
 
@@ -134,6 +132,7 @@
     inline const jfloat* getAdvances() const { return mAdvances.array(); }
     inline size_t getAdvancesCount() const { return mAdvances.size(); }
     inline jfloat getTotalAdvance() const { return mTotalAdvance; }
+    inline const SkRect& getBounds() const { return mBounds; }
     inline const jchar* getGlyphs() const { return mGlyphs.array(); }
     inline size_t getGlyphsCount() const { return mGlyphs.size(); }
     inline const jfloat* getPos() const { return mPos.array(); }
@@ -150,6 +149,11 @@
     jfloat mTotalAdvance;
 
     /**
+     * Bounds containing all glyphs
+     */
+    SkRect mBounds;
+
+    /**
      * Glyphs vector
      */
     Vector<jchar> mGlyphs;
@@ -208,12 +212,12 @@
 
     void computeValues(const SkPaint* paint, const UChar* chars,
             size_t start, size_t count, size_t contextCount, int dirFlags,
-            Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
+            Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance, SkRect* outBounds,
             Vector<jchar>* const outGlyphs, Vector<jfloat>* const outPos);
 
     void computeRunValues(const SkPaint* paint, const UChar* chars,
             size_t start, size_t count, size_t contextCount, bool isRTL,
-            Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
+            Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance, SkRect* outBounds,
             Vector<jchar>* const outGlyphs, Vector<jfloat>* const outPos);
 
     SkTypeface* setCachedTypeface(SkTypeface** typeface, hb_script_t script, SkTypeface::Style style);
diff --git a/core/jni/android/graphics/Utils.cpp b/core/jni/android/graphics/Utils.cpp
index cf6977e..b7d1f3a 100644
--- a/core/jni/android/graphics/Utils.cpp
+++ b/core/jni/android/graphics/Utils.cpp
@@ -28,12 +28,28 @@
     return true;
 }
 
+size_t AssetStreamAdaptor::getLength() const {
+    return fAsset->getLength();
+}
+
+bool AssetStreamAdaptor::isAtEnd() const {
+    return fAsset->getRemainingLength() == 0;
+}
+
+SkStreamRewindable* AssetStreamAdaptor::duplicate() const {
+    SkASSERT(false);
+    // Cannot create a duplicate, since each AssetStreamAdaptor
+    // would be modifying the Asset.
+    //return new AssetStreamAdaptor(fAsset);
+    return NULL;
+}
+
 size_t AssetStreamAdaptor::read(void* buffer, size_t size) {
     ssize_t amount;
 
     if (NULL == buffer) {
-        if (0 == size) {  // caller is asking us for our total length
-            return fAsset->getLength();
+        if (0 == size) {
+            return 0;
         }
         // asset->seek returns new total offset
         // we want to return amount that was skipped
@@ -62,6 +78,34 @@
     return amount;
 }
 
+SkMemoryStream* android::CopyAssetToStream(Asset* asset) {
+    if (NULL == asset) {
+        return NULL;
+    }
+
+    off64_t size = asset->seek(0, SEEK_SET);
+    if ((off64_t)-1 == size) {
+        SkDebugf("---- copyAsset: asset rewind failed\n");
+        return NULL;
+    }
+
+    size = asset->getLength();
+    if (size <= 0) {
+        SkDebugf("---- copyAsset: asset->getLength() returned %d\n", size);
+        return NULL;
+    }
+
+    SkMemoryStream* stream = new SkMemoryStream(size);
+    void* data = const_cast<void*>(stream->getMemoryBase());
+    off64_t len = asset->read(data, size);
+    if (len != size) {
+        SkDebugf("---- copyAsset: asset->read(%d) returned %d\n", size, len);
+        delete stream;
+        stream = NULL;
+    }
+    return stream;
+}
+
 jobject android::nullObjectReturn(const char msg[]) {
     if (msg) {
         SkDebugf("--- %s\n", msg);
diff --git a/core/jni/android/graphics/Utils.h b/core/jni/android/graphics/Utils.h
index 75ceaa2..a1ac72a 100644
--- a/core/jni/android/graphics/Utils.h
+++ b/core/jni/android/graphics/Utils.h
@@ -26,16 +26,27 @@
 
 namespace android {
 
-class AssetStreamAdaptor : public SkStream {
+class AssetStreamAdaptor : public SkStreamRewindable {
 public:
     AssetStreamAdaptor(Asset* a) : fAsset(a) {}
     virtual bool rewind();
     virtual size_t read(void* buffer, size_t size);
+    virtual bool hasLength() const { return true; }
+    virtual size_t getLength() const;
+    virtual bool isAtEnd() const;
 
+    virtual SkStreamRewindable* duplicate() const;
 private:
     Asset*  fAsset;
 };
 
+/**
+ *  Make a deep copy of the asset, and return it as a stream, or NULL if there
+ *  was an error.
+ *  FIXME: If we could "ref/reopen" the asset, we may not need to copy it here.
+ */
+
+SkMemoryStream* CopyAssetToStream(Asset*);
 
 /** Restore the file descriptor's offset in our destructor
  */
diff --git a/core/jni/android/print/android_print_pdf_PdfDocument.cpp b/core/jni/android/print/android_print_pdf_PdfDocument.cpp
new file mode 100644
index 0000000..3daad5c
--- /dev/null
+++ b/core/jni/android/print/android_print_pdf_PdfDocument.cpp
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+
+#include "jni.h"
+#include "GraphicsJNI.h"
+#include <android_runtime/AndroidRuntime.h>
+
+#include "SkCanvas.h"
+#include "SkPDFDevice.h"
+#include "SkPDFDocument.h"
+#include "SkRect.h"
+#include "SkSize.h"
+#include "CreateJavaOutputStreamAdaptor.h"
+#include "JNIHelp.h"
+
+namespace android {
+
+static jint nativeCreateDocument(JNIEnv* env, jobject clazz) {
+    return reinterpret_cast<jint>(new SkPDFDocument());
+}
+
+static void nativeFinalize(JNIEnv* env, jobject thiz, jint documentPtr) {
+    delete reinterpret_cast<SkPDFDocument*>(documentPtr);
+}
+
+static jint nativeCreatePage(JNIEnv* env, jobject thiz,
+        jobject pageSize, jobject contentSize, jint initialTransformation) {
+    SkIRect skPageSizeRect;
+    GraphicsJNI::jrect_to_irect(env, pageSize, &skPageSizeRect);
+    SkISize skPageSize = SkISize::Make(skPageSizeRect.width(),
+            skPageSizeRect.height());
+
+    SkIRect skContentRect;
+    GraphicsJNI::jrect_to_irect(env, contentSize, &skContentRect);
+    SkISize skContentSize = SkISize::Make(skContentRect.width(),
+            skContentRect.height());
+
+    SkMatrix* transformation = reinterpret_cast<SkMatrix*>(initialTransformation);
+    SkPDFDevice* skPdfDevice = new SkPDFDevice(skPageSize, skContentSize, *transformation);
+
+    return reinterpret_cast<jint>(new SkCanvas(skPdfDevice));
+}
+
+static void nativeAppendPage(JNIEnv* env, jobject thiz, jint documentPtr, jint pagePtr) {
+    SkCanvas* page = reinterpret_cast<SkCanvas*>(pagePtr);
+    SkPDFDocument* document = reinterpret_cast<SkPDFDocument*>(documentPtr);
+    SkPDFDevice* device = static_cast<SkPDFDevice*>(page->getDevice());
+    document->appendPage(device);
+}
+
+static void nativeWriteTo(JNIEnv* env, jobject clazz, jint documentPtr,
+        jobject out, jbyteArray chunk) {
+    SkWStream* skWStream = CreateJavaOutputStreamAdaptor(env, out, chunk);
+    SkPDFDocument* document = reinterpret_cast<SkPDFDocument*>(documentPtr);
+    document->emitPDF(skWStream);
+    delete skWStream;
+}
+
+static JNINativeMethod gPdfDocument_Methods[] = {
+    {"nativeCreateDocument", "()I", (void*) nativeCreateDocument},
+    {"nativeFinalize", "(I)V", (void*) nativeFinalize},
+    {"nativeCreatePage", "(Landroid/graphics/Rect;Landroid/graphics/Rect;I)I",
+            (void*) nativeCreatePage},
+    {"nativeAppendPage", "(II)V", (void*) nativeAppendPage},
+    {"nativeWriteTo", "(ILjava/io/OutputStream;[B)V", (void*) nativeWriteTo}
+};
+
+int register_android_print_pdf_PdfDocument(JNIEnv* env) {
+    int result = android::AndroidRuntime::registerNativeMethods(
+            env, "android/print/pdf/PdfDocument", gPdfDocument_Methods,
+            NELEM(gPdfDocument_Methods));
+    return result;
+}
+
+};
diff --git a/core/jni/android_app_NativeActivity.cpp b/core/jni/android_app_NativeActivity.cpp
index 9fc01e1..5418006 100644
--- a/core/jni/android_app_NativeActivity.cpp
+++ b/core/jni/android_app_NativeActivity.cpp
@@ -25,7 +25,7 @@
 #include <android_runtime/android_util_AssetManager.h>
 #include <android_runtime/android_view_Surface.h>
 #include <android_runtime/AndroidRuntime.h>
-#include <androidfw/InputTransport.h>
+#include <input/InputTransport.h>
 
 #include <gui/Surface.h>
 
@@ -306,19 +306,23 @@
         code->internalDataPath = code->internalDataPathObj.string();
         env->ReleaseStringUTFChars(internalDataDir, dirStr);
     
-        dirStr = env->GetStringUTFChars(externalDataDir, NULL);
-        code->externalDataPathObj = dirStr;
+        if (externalDataDir != NULL) {
+            dirStr = env->GetStringUTFChars(externalDataDir, NULL);
+            code->externalDataPathObj = dirStr;
+            env->ReleaseStringUTFChars(externalDataDir, dirStr);
+        }
         code->externalDataPath = code->externalDataPathObj.string();
-        env->ReleaseStringUTFChars(externalDataDir, dirStr);
 
         code->sdkVersion = sdkVersion;
         
         code->assetManager = assetManagerForJavaObject(env, jAssetMgr);
 
-        dirStr = env->GetStringUTFChars(obbDir, NULL);
-        code->obbPathObj = dirStr;
+        if (obbDir != NULL) {
+            dirStr = env->GetStringUTFChars(obbDir, NULL);
+            code->obbPathObj = dirStr;
+            env->ReleaseStringUTFChars(obbDir, dirStr);
+        }
         code->obbPath = code->obbPathObj.string();
-        env->ReleaseStringUTFChars(obbDir, dirStr);
 
         jbyte* rawSavedState = NULL;
         jsize rawSavedSize = 0;
diff --git a/core/jni/android_database_SQLiteConnection.cpp b/core/jni/android_database_SQLiteConnection.cpp
index f70f0d1..6e496fd 100644
--- a/core/jni/android_database_SQLiteConnection.cpp
+++ b/core/jni/android_database_SQLiteConnection.cpp
@@ -19,6 +19,7 @@
 #include <jni.h>
 #include <JNIHelp.h>
 #include <android_runtime/AndroidRuntime.h>
+#include <android_runtime/Log.h>
 
 #include <utils/Log.h>
 #include <utils/String8.h>
diff --git a/core/jni/android_emoji_EmojiFactory.cpp b/core/jni/android_emoji_EmojiFactory.cpp
index 4383997..5276934 100644
--- a/core/jni/android_emoji_EmojiFactory.cpp
+++ b/core/jni/android_emoji_EmojiFactory.cpp
@@ -6,6 +6,7 @@
 #include <ScopedUtfChars.h>
 
 #include "EmojiFactory.h"
+#include "GraphicsJNI.h"
 #include <nativehelper/JNIHelp.h>
 
 #include <dlfcn.h>
@@ -92,9 +93,6 @@
 static pthread_once_t g_once = PTHREAD_ONCE_INIT;
 static bool lib_emoji_factory_is_ready;
 
-static jclass    gBitmap_class;
-static jmethodID gBitmap_constructorMethodID;
-
 static jclass    gEmojiFactory_class;
 static jmethodID gEmojiFactory_constructorMethodID;
 
@@ -172,13 +170,8 @@
     return NULL;
   }
 
-  jobject obj = env->NewObject(gBitmap_class, gBitmap_constructorMethodID,
-      static_cast<jint>(reinterpret_cast<uintptr_t>(bitmap)), NULL, false, NULL, -1);
-  if (env->ExceptionCheck() != 0) {
-    ALOGE("*** Uncaught exception returned from Java call!\n");
-    env->ExceptionDescribe();
-  }
-  return obj;
+  return GraphicsJNI::createBitmap(env, bitmap,
+      GraphicsJNI::kBitmapCreateFlag_Premultiplied, NULL);
 }
 
 static void android_emoji_EmojiFactory_destructor(
@@ -281,9 +274,6 @@
 }
 
 int register_android_emoji_EmojiFactory(JNIEnv* env) {
-  gBitmap_class = make_globalref(env, "android/graphics/Bitmap");
-  gBitmap_constructorMethodID = env->GetMethodID(gBitmap_class, "<init>",
-                                                 "(I[BZ[BI)V");
   gEmojiFactory_class = make_globalref(env, "android/emoji/EmojiFactory");
   gEmojiFactory_constructorMethodID = env->GetMethodID(
       gEmojiFactory_class, "<init>", "(ILjava/lang/String;)V");
diff --git a/core/jni/android_graphics_PixelFormat.cpp b/core/jni/android_graphics_PixelFormat.cpp
deleted file mode 100644
index 1fc363b..0000000
--- a/core/jni/android_graphics_PixelFormat.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <assert.h>
-
-#include <ui/PixelFormat.h>
-
-#include "jni.h"
-#include "JNIHelp.h"
-#include <android_runtime/AndroidRuntime.h>
-#include <utils/misc.h>
-
-// ----------------------------------------------------------------------------
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-struct offsets_t {
-    jfieldID bytesPerPixel;
-    jfieldID bitsPerPixel;
-};
-
-static offsets_t offsets;
-
-// ----------------------------------------------------------------------------
-
-static void android_graphics_getPixelFormatInfo(
-        JNIEnv* env, jobject clazz, jint format, jobject pixelFormatObject)
-{
-    PixelFormatInfo info;
-    status_t err;
-
-    // we need this for backward compatibility with PixelFormat's
-    // deprecated constants
-    switch (format) {
-    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
-        // defined as the bytes per pixel of the Y plane
-        info.bytesPerPixel = 1;
-        info.bitsPerPixel = 16;
-        goto done;
-    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
-        // defined as the bytes per pixel of the Y plane
-        info.bytesPerPixel = 1;
-        info.bitsPerPixel = 12;
-        goto done;
-    case HAL_PIXEL_FORMAT_YCbCr_422_I:
-        // defined as the bytes per pixel of the Y plane
-        info.bytesPerPixel = 1;
-        info.bitsPerPixel = 16;
-        goto done;
-    }
-
-    err = getPixelFormatInfo(format, &info);
-    if (err < 0) {
-        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
-        return;
-    }
-
-done:
-    env->SetIntField(pixelFormatObject, offsets.bytesPerPixel, info.bytesPerPixel);
-    env->SetIntField(pixelFormatObject, offsets.bitsPerPixel,  info.bitsPerPixel);
-}
-// ----------------------------------------------------------------------------
-
-const char* const kClassPathName = "android/graphics/PixelFormat";
-
-static void nativeClassInit(JNIEnv* env, jclass clazz);
-
-static JNINativeMethod gMethods[] = {
-    {   "nativeClassInit", "()V",
-        (void*)nativeClassInit },
-	{   "getPixelFormatInfo", "(ILandroid/graphics/PixelFormat;)V",
-        (void*)android_graphics_getPixelFormatInfo
-    }
-};
-
-void nativeClassInit(JNIEnv* env, jclass clazz)
-{
-    offsets.bytesPerPixel = env->GetFieldID(clazz, "bytesPerPixel", "I");
-    offsets.bitsPerPixel  = env->GetFieldID(clazz, "bitsPerPixel", "I");
-}
-
-int register_android_graphics_PixelFormat(JNIEnv* env)
-{
-    return AndroidRuntime::registerNativeMethods(env,
-            kClassPathName, gMethods, NELEM(gMethods));
-}
-
-};
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index 686e4e3..09d8d0f 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -553,7 +553,7 @@
         }
     }
 
-    if (camera->setPreviewTexture(gbp) != NO_ERROR) {
+    if (camera->setPreviewTarget(gbp) != NO_ERROR) {
         jniThrowException(env, "java/io/IOException", "setPreviewTexture failed");
     }
 }
@@ -565,14 +565,10 @@
     sp<Camera> camera = get_native_camera(env, thiz, NULL);
     if (camera == 0) return;
 
-    sp<BufferQueue> bufferQueue = NULL;
+    sp<IGraphicBufferProducer> producer = NULL;
     if (jSurfaceTexture != NULL) {
-        sp<GLConsumer> surfaceTexture =
-            SurfaceTexture_getSurfaceTexture(env, jSurfaceTexture);
-        if (surfaceTexture != NULL) {
-            bufferQueue = surfaceTexture->getBufferQueue();
-        }
-        else {
+        producer = SurfaceTexture_getProducer(env, jSurfaceTexture);
+        if (producer == NULL) {
             jniThrowException(env, "java/lang/IllegalArgumentException",
                     "SurfaceTexture already released in setPreviewTexture");
             return;
@@ -580,12 +576,36 @@
 
     }
 
-    if (camera->setPreviewTexture(bufferQueue) != NO_ERROR) {
+    if (camera->setPreviewTarget(producer) != NO_ERROR) {
         jniThrowException(env, "java/io/IOException",
                 "setPreviewTexture failed");
     }
 }
 
+static void android_hardware_Camera_setPreviewCallbackSurface(JNIEnv *env,
+        jobject thiz, jobject jSurface)
+{
+    ALOGV("setPreviewCallbackSurface");
+    JNICameraContext* context;
+    sp<Camera> camera = get_native_camera(env, thiz, &context);
+    if (camera == 0) return;
+
+    sp<IGraphicBufferProducer> gbp;
+    sp<Surface> surface;
+    if (jSurface) {
+        surface = android_view_Surface_getSurface(env, jSurface);
+        if (surface != NULL) {
+            gbp = surface->getIGraphicBufferProducer();
+        }
+    }
+    // Clear out normal preview callbacks
+    context->setCallbackMode(env, false, false);
+    // Then set up callback surface
+    if (camera->setPreviewCallbackTarget(gbp) != NO_ERROR) {
+        jniThrowException(env, "java/io/IOException", "setPreviewCallbackTarget failed");
+    }
+}
+
 static void android_hardware_Camera_startPreview(JNIEnv *env, jobject thiz)
 {
     ALOGV("startPreview");
@@ -881,6 +901,9 @@
   { "setPreviewTexture",
     "(Landroid/graphics/SurfaceTexture;)V",
     (void *)android_hardware_Camera_setPreviewTexture },
+  { "setPreviewCallbackSurface",
+    "(Landroid/view/Surface;)V",
+    (void *)android_hardware_Camera_setPreviewCallbackSurface },
   { "startPreview",
     "()V",
     (void *)android_hardware_Camera_startPreview },
diff --git a/core/jni/android_hardware_SensorManager.cpp b/core/jni/android_hardware_SensorManager.cpp
index 6374494..4290a6e 100644
--- a/core/jni/android_hardware_SensorManager.cpp
+++ b/core/jni/android_hardware_SensorManager.cpp
@@ -31,6 +31,7 @@
 static struct {
     jclass clazz;
     jmethodID dispatchSensorEvent;
+    jmethodID dispatchFlushCompleteEvent;
 } gBaseEventQueueClassInfo;
 
 namespace android {
@@ -46,6 +47,8 @@
     jfieldID    resolution;
     jfieldID    power;
     jfieldID    minDelay;
+    jfieldID    fifoReservedEventCount;
+    jfieldID    fifoMaxEventCount;
 } gSensorOffsets;
 
 
@@ -67,6 +70,9 @@
     sensorOffsets.resolution  = _env->GetFieldID(sensorClass, "mResolution","F");
     sensorOffsets.power       = _env->GetFieldID(sensorClass, "mPower",     "F");
     sensorOffsets.minDelay    = _env->GetFieldID(sensorClass, "mMinDelay",  "I");
+    sensorOffsets.fifoReservedEventCount =
+            _env->GetFieldID(sensorClass, "mFifoReservedEventCount",  "I");
+    sensorOffsets.fifoMaxEventCount = _env->GetFieldID(sensorClass, "mFifoMaxEventCount",  "I");
 }
 
 static jint
@@ -78,7 +84,7 @@
     size_t count = mgr.getSensorList(&sensorList);
     if (size_t(next) >= count)
         return -1;
-    
+
     Sensor const* const list = sensorList[next];
     const SensorOffsets& sensorOffsets(gSensorOffsets);
     jstring name = env->NewStringUTF(list->getName().string());
@@ -92,7 +98,9 @@
     env->SetFloatField(sensor, sensorOffsets.resolution, list->getResolution());
     env->SetFloatField(sensor, sensorOffsets.power,      list->getPowerUsage());
     env->SetIntField(sensor, sensorOffsets.minDelay,     list->getMinDelay());
-    
+    env->SetIntField(sensor, sensorOffsets.fifoReservedEventCount,
+                     list->getFifoReservedEventCount());
+    env->SetIntField(sensor, sensorOffsets.fifoMaxEventCount, list->getFifoMaxEventCount());
     next++;
     return size_t(next) < count ? next : 0;
 }
@@ -142,14 +150,28 @@
         while ((n = q->read(buffer, 16)) > 0) {
             for (int i=0 ; i<n ; i++) {
 
-                env->SetFloatArrayRegion(mScratch, 0, 16, buffer[i].data);
+                if (buffer[i].type == SENSOR_TYPE_STEP_COUNTER) {
+                    // step-counter returns a uint64, but the java API only deals with floats
+                    float value = float(buffer[i].u64.step_counter);
+                    env->SetFloatArrayRegion(mScratch, 0, 1, &value);
+                } else {
+                    env->SetFloatArrayRegion(mScratch, 0, 16, buffer[i].data);
+                }
 
-                env->CallVoidMethod(mReceiverObject,
-                        gBaseEventQueueClassInfo.dispatchSensorEvent,
-                        buffer[i].sensor,
-                        mScratch,
-                        buffer[i].vector.status,
-                        buffer[i].timestamp);
+                if (buffer[i].type == SENSOR_TYPE_META_DATA) {
+                    // This is a flush complete sensor event. Call dispatchFlushCompleteEvent
+                    // method.
+                    env->CallVoidMethod(mReceiverObject,
+                                        gBaseEventQueueClassInfo.dispatchFlushCompleteEvent,
+                                        buffer[i].meta_data.sensor);
+                } else {
+                    env->CallVoidMethod(mReceiverObject,
+                                        gBaseEventQueueClassInfo.dispatchSensorEvent,
+                                        buffer[i].sensor,
+                                        mScratch,
+                                        buffer[i].vector.status,
+                                        buffer[i].timestamp);
+                }
 
                 if (env->ExceptionCheck()) {
                     ALOGE("Exception dispatching input event.");
@@ -180,9 +202,11 @@
     return jint(receiver.get());
 }
 
-static jint nativeEnableSensor(JNIEnv *env, jclass clazz, jint eventQ, jint handle, jint us) {
+static jint nativeEnableSensor(JNIEnv *env, jclass clazz, jint eventQ, jint handle, jint rate_us,
+                               jint maxBatchReportLatency, jint reservedFlags) {
     sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));
-    return receiver->getSensorEventQueue()->enableSensor(handle, us);
+    return receiver->getSensorEventQueue()->enableSensor(handle, rate_us, maxBatchReportLatency,
+                                                         reservedFlags);
 }
 
 static jint nativeDisableSensor(JNIEnv *env, jclass clazz, jint eventQ, jint handle) {
@@ -196,6 +220,10 @@
     receiver->decStrong((void*)nativeInitSensorEventQueue);
 }
 
+static jint nativeFlushSensor(JNIEnv *env, jclass clazz, jint eventQ, jint handle) {
+    sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));
+    return receiver->getSensorEventQueue()->flushSensor(handle);
+}
 
 //----------------------------------------------------------------------------
 
@@ -215,7 +243,7 @@
             (void*)nativeInitSensorEventQueue },
 
     {"nativeEnableSensor",
-            "(III)I",
+            "(IIIII)I",
             (void*)nativeEnableSensor },
 
     {"nativeDisableSensor",
@@ -225,6 +253,10 @@
     {"nativeDestroySensorEventQueue",
             "(I)V",
             (void*)nativeDestroySensorEventQueue },
+
+    {"nativeFlushSensor",
+            "(II)I",
+            (void*)nativeFlushSensor },
 };
 
 }; // namespace android
@@ -254,5 +286,9 @@
             gBaseEventQueueClassInfo.clazz,
             "dispatchSensorEvent", "(I[FIJ)V");
 
+    GET_METHOD_ID(gBaseEventQueueClassInfo.dispatchFlushCompleteEvent,
+                  gBaseEventQueueClassInfo.clazz,
+                  "dispatchFlushCompleteEvent", "(I)V");
+
     return 0;
 }
diff --git a/core/jni/android_hardware_camera2_CameraMetadata.cpp b/core/jni/android_hardware_camera2_CameraMetadata.cpp
new file mode 100644
index 0000000..3c7da1e
--- /dev/null
+++ b/core/jni/android_hardware_camera2_CameraMetadata.cpp
@@ -0,0 +1,559 @@
+/*
+**
+** Copyright 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.
+*/
+
+// #define LOG_NDEBUG 0
+// #define LOG_NNDEBUG 0
+#define LOG_TAG "CameraMetadata-JNI"
+#include <utils/Log.h>
+
+#include "jni.h"
+#include "JNIHelp.h"
+#include "android_os_Parcel.h"
+#include "android_runtime/AndroidRuntime.h"
+
+#include <camera/CameraMetadata.h>
+#include <nativehelper/ScopedUtfChars.h>
+#include <nativehelper/ScopedPrimitiveArray.h>
+
+#if defined(LOG_NNDEBUG)
+#if !LOG_NNDEBUG
+#define ALOGVV ALOGV
+#endif
+#else
+#define ALOGVV(...)
+#endif
+
+// fully-qualified class name
+#define CAMERA_METADATA_CLASS_NAME "android/hardware/camera2/impl/CameraMetadataNative"
+
+using namespace android;
+
+struct fields_t {
+    jfieldID    metadata_ptr;
+};
+
+static fields_t fields;
+
+namespace {
+struct Helpers {
+    static size_t getTypeSize(uint8_t type) {
+        if (type >= NUM_TYPES) {
+            ALOGE("%s: Invalid type specified (%ud)", __FUNCTION__, type);
+            return static_cast<size_t>(-1);
+        }
+
+        return camera_metadata_type_size[type];
+    }
+
+    static status_t updateAny(CameraMetadata *metadata,
+                          uint32_t tag,
+                          uint32_t type,
+                          const void *data,
+                          size_t dataBytes) {
+
+        if (type >= NUM_TYPES) {
+            ALOGE("%s: Invalid type specified (%ud)", __FUNCTION__, type);
+            return INVALID_OPERATION;
+        }
+
+        size_t typeSize = getTypeSize(type);
+
+        if (dataBytes % typeSize != 0) {
+            ALOGE("%s: Expected dataBytes (%ud) to be divisible by typeSize "
+                  "(%ud)", __FUNCTION__, dataBytes, typeSize);
+            return BAD_VALUE;
+        }
+
+        size_t dataCount = dataBytes / typeSize;
+
+        switch(type) {
+#define METADATA_UPDATE(runtime_type, compile_type)                            \
+            case runtime_type: {                                               \
+                const compile_type *dataPtr =                                  \
+                        static_cast<const compile_type*>(data);                \
+                return metadata->update(tag, dataPtr, dataCount);              \
+            }                                                                  \
+
+            METADATA_UPDATE(TYPE_BYTE,     uint8_t);
+            METADATA_UPDATE(TYPE_INT32,    int32_t);
+            METADATA_UPDATE(TYPE_FLOAT,    float);
+            METADATA_UPDATE(TYPE_INT64,    int64_t);
+            METADATA_UPDATE(TYPE_DOUBLE,   double);
+            METADATA_UPDATE(TYPE_RATIONAL, camera_metadata_rational_t);
+
+            default: {
+                // unreachable
+                ALOGE("%s: Unreachable", __FUNCTION__);
+                return INVALID_OPERATION;
+            }
+        }
+
+#undef METADATA_UPDATE
+    }
+};
+} // namespace {}
+
+extern "C" {
+
+static void CameraMetadata_classInit(JNIEnv *env, jobject thiz);
+static jint CameraMetadata_getTagFromKey(JNIEnv *env, jobject thiz, jstring keyName);
+static jint CameraMetadata_getTypeFromTag(JNIEnv *env, jobject thiz, jint tag);
+
+// Less safe access to native pointer. Does NOT throw any Java exceptions if NULL.
+static CameraMetadata* CameraMetadata_getPointerNoThrow(JNIEnv *env, jobject thiz) {
+
+    if (thiz == NULL) {
+        return NULL;
+    }
+
+    return reinterpret_cast<CameraMetadata*>(env->GetLongField(thiz, fields.metadata_ptr));
+}
+
+// Safe access to native pointer from object. Throws if not possible to access.
+static CameraMetadata* CameraMetadata_getPointerThrow(JNIEnv *env, jobject thiz,
+                                                 const char* argName = "this") {
+
+    if (thiz == NULL) {
+        ALOGV("%s: Throwing java.lang.NullPointerException for null reference",
+              __FUNCTION__);
+        jniThrowNullPointerException(env, argName);
+        return NULL;
+    }
+
+    CameraMetadata* metadata = CameraMetadata_getPointerNoThrow(env, thiz);
+    if (metadata == NULL) {
+        ALOGV("%s: Throwing java.lang.IllegalStateException for closed object",
+              __FUNCTION__);
+        jniThrowException(env, "java/lang/IllegalStateException",
+                            "Metadata object was already closed");
+        return NULL;
+    }
+
+    return metadata;
+}
+
+static jlong CameraMetadata_allocate(JNIEnv *env, jobject thiz) {
+    ALOGV("%s", __FUNCTION__);
+
+    return reinterpret_cast<jlong>(new CameraMetadata());
+}
+
+static jlong CameraMetadata_allocateCopy(JNIEnv *env, jobject thiz,
+        jobject other) {
+    ALOGV("%s", __FUNCTION__);
+
+    CameraMetadata* otherMetadata =
+            CameraMetadata_getPointerThrow(env, other, "other");
+
+    // In case of exception, return
+    if (otherMetadata == NULL) return NULL;
+
+    // Clone native metadata and return new pointer
+    return reinterpret_cast<jlong>(new CameraMetadata(*otherMetadata));
+}
+
+
+static jboolean CameraMetadata_isEmpty(JNIEnv *env, jobject thiz) {
+    ALOGV("%s", __FUNCTION__);
+
+    CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz);
+
+    if (metadata == NULL) {
+        ALOGW("%s: Returning early due to exception being thrown",
+               __FUNCTION__);
+        return JNI_TRUE; // actually throws java exc.
+    }
+
+    jboolean empty = metadata->isEmpty();
+
+    ALOGV("%s: Empty returned %d, entry count was %d",
+          __FUNCTION__, empty, metadata->entryCount());
+
+    return empty;
+}
+
+static jint CameraMetadata_getEntryCount(JNIEnv *env, jobject thiz) {
+    ALOGV("%s", __FUNCTION__);
+
+    CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz);
+
+    if (metadata == NULL) return 0; // actually throws java exc.
+
+    return metadata->entryCount();
+}
+
+// idempotent. calling more than once has no effect.
+static void CameraMetadata_close(JNIEnv *env, jobject thiz) {
+    ALOGV("%s", __FUNCTION__);
+
+    CameraMetadata* metadata = CameraMetadata_getPointerNoThrow(env, thiz);
+
+    if (metadata != NULL) {
+        delete metadata;
+        env->SetLongField(thiz, fields.metadata_ptr, 0);
+    }
+
+    LOG_ALWAYS_FATAL_IF(CameraMetadata_getPointerNoThrow(env, thiz) != NULL,
+                        "Expected the native ptr to be 0 after #close");
+}
+
+static void CameraMetadata_swap(JNIEnv *env, jobject thiz, jobject other) {
+    ALOGV("%s", __FUNCTION__);
+
+    CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz);
+
+    // order is important: we can't call another JNI method
+    // if there is an exception pending
+    if (metadata == NULL) return;
+
+    CameraMetadata* otherMetadata = CameraMetadata_getPointerThrow(env, other, "other");
+
+    if (otherMetadata == NULL) return;
+
+    metadata->swap(*otherMetadata);
+}
+
+static jbyteArray CameraMetadata_readValues(JNIEnv *env, jobject thiz, jint tag) {
+    ALOGV("%s (tag = %d)", __FUNCTION__, tag);
+
+    CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz);
+    if (metadata == NULL) return NULL;
+
+    int tagType = get_camera_metadata_tag_type(tag);
+    if (tagType == -1) {
+        jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
+                             "Tag (%d) did not have a type", tag);
+        return NULL;
+    }
+    size_t tagSize = Helpers::getTypeSize(tagType);
+
+    camera_metadata_entry entry = metadata->find(tag);
+    if (entry.count == 0) {
+         if (!metadata->exists(tag)) {
+             ALOGV("%s: Tag %d does not have any entries", __FUNCTION__, tag);
+             return NULL;
+         } else {
+             // OK: we will return a 0-sized array.
+             ALOGV("%s: Tag %d had an entry, but it had 0 data", __FUNCTION__,
+                   tag);
+         }
+    }
+
+    jsize byteCount = entry.count * tagSize;
+    jbyteArray byteArray = env->NewByteArray(byteCount);
+    if (env->ExceptionCheck()) return NULL;
+
+    // Copy into java array from native array
+    ScopedByteArrayRW arrayWriter(env, byteArray);
+    memcpy(arrayWriter.get(), entry.data.u8, byteCount);
+
+    return byteArray;
+}
+
+static void CameraMetadata_writeValues(JNIEnv *env, jobject thiz, jint tag, jbyteArray src) {
+    ALOGV("%s (tag = %d)", __FUNCTION__, tag);
+
+    CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz);
+    if (metadata == NULL) return;
+
+    int tagType = get_camera_metadata_tag_type(tag);
+    if (tagType == -1) {
+        jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
+                             "Tag (%d) did not have a type", tag);
+        return;
+    }
+    size_t tagSize = Helpers::getTypeSize(tagType);
+
+    status_t res;
+
+    if (src == NULL) {
+        // If array is NULL, delete the entry
+        if (metadata->exists(tag)) {
+            res = metadata->erase(tag);
+            ALOGV("%s: Erase values (res = %d)", __FUNCTION__, res);
+        } else {
+            res = OK;
+            ALOGV("%s: Don't need to erase", __FUNCTION__);
+        }
+    } else {
+        // Copy from java array into native array
+        ScopedByteArrayRO arrayReader(env, src);
+        if (arrayReader.get() == NULL) return;
+
+        res = Helpers::updateAny(metadata, static_cast<uint32_t>(tag),
+                                 tagType, arrayReader.get(), arrayReader.size());
+
+        ALOGV("%s: Update values (res = %d)", __FUNCTION__, res);
+    }
+
+    if (res == OK) {
+        return;
+    } else if (res == BAD_VALUE) {
+        jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
+                             "Src byte array was poorly formed");
+    } else if (res == INVALID_OPERATION) {
+        jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
+                             "Internal error while trying to update metadata");
+    } else {
+        jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
+                             "Unknown error (%d) while trying to update "
+                            "metadata", res);
+    }
+}
+
+static void CameraMetadata_readFromParcel(JNIEnv *env, jobject thiz, jobject parcel) {
+    ALOGV("%s", __FUNCTION__);
+    CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz);
+    if (metadata == NULL) {
+        return;
+    }
+
+    Parcel* parcelNative = parcelForJavaObject(env, parcel);
+    if (parcelNative == NULL) {
+        jniThrowNullPointerException(env, "parcel");
+        return;
+    }
+
+    status_t err;
+    if ((err = metadata->readFromParcel(parcelNative)) != OK) {
+        jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
+                             "Failed to read from parcel (error code %d)", err);
+        return;
+    }
+}
+
+static void CameraMetadata_writeToParcel(JNIEnv *env, jobject thiz, jobject parcel) {
+    ALOGV("%s", __FUNCTION__);
+    CameraMetadata* metadata = CameraMetadata_getPointerThrow(env, thiz);
+    if (metadata == NULL) {
+        return;
+    }
+
+    Parcel* parcelNative = parcelForJavaObject(env, parcel);
+    if (parcelNative == NULL) {
+        jniThrowNullPointerException(env, "parcel");
+        return;
+    }
+
+    status_t err;
+    if ((err = metadata->writeToParcel(parcelNative)) != OK) {
+        jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
+                                  "Failed to write to parcel (error code %d)", err);
+        return;
+    }
+}
+
+} // extern "C"
+
+//-------------------------------------------------
+
+static JNINativeMethod gCameraMetadataMethods[] = {
+// static methods
+  { "nativeClassInit",
+    "()V",
+    (void *)CameraMetadata_classInit },
+  { "nativeGetTagFromKey",
+    "(Ljava/lang/String;)I",
+    (void *)CameraMetadata_getTagFromKey },
+  { "nativeGetTypeFromTag",
+    "(I)I",
+    (void *)CameraMetadata_getTypeFromTag },
+// instance methods
+  { "nativeAllocate",
+    "()J",
+    (void*)CameraMetadata_allocate },
+  { "nativeAllocateCopy",
+    "(L" CAMERA_METADATA_CLASS_NAME ";)J",
+    (void *)CameraMetadata_allocateCopy },
+  { "nativeIsEmpty",
+    "()Z",
+    (void*)CameraMetadata_isEmpty },
+  { "nativeGetEntryCount",
+    "()I",
+    (void*)CameraMetadata_getEntryCount },
+  { "nativeClose",
+    "()V",
+    (void*)CameraMetadata_close },
+  { "nativeSwap",
+    "(L" CAMERA_METADATA_CLASS_NAME ";)V",
+    (void *)CameraMetadata_swap },
+  { "nativeReadValues",
+    "(I)[B",
+    (void *)CameraMetadata_readValues },
+  { "nativeWriteValues",
+    "(I[B)V",
+    (void *)CameraMetadata_writeValues },
+// Parcelable interface
+  { "nativeReadFromParcel",
+    "(Landroid/os/Parcel;)V",
+    (void *)CameraMetadata_readFromParcel },
+  { "nativeWriteToParcel",
+    "(Landroid/os/Parcel;)V",
+    (void *)CameraMetadata_writeToParcel },
+};
+
+struct field {
+    const char *class_name;
+    const char *field_name;
+    const char *field_type;
+    jfieldID   *jfield;
+};
+
+static int find_fields(JNIEnv *env, field *fields, int count)
+{
+    for (int i = 0; i < count; i++) {
+        field *f = &fields[i];
+        jclass clazz = env->FindClass(f->class_name);
+        if (clazz == NULL) {
+            ALOGE("Can't find %s", f->class_name);
+            return -1;
+        }
+
+        jfieldID field = env->GetFieldID(clazz, f->field_name, f->field_type);
+        if (field == NULL) {
+            ALOGE("Can't find %s.%s", f->class_name, f->field_name);
+            return -1;
+        }
+
+        *(f->jfield) = field;
+    }
+
+    return 0;
+}
+
+// Get all the required offsets in java class and register native functions
+int register_android_hardware_camera2_CameraMetadata(JNIEnv *env)
+{
+    // Register native functions
+    return AndroidRuntime::registerNativeMethods(env,
+            CAMERA_METADATA_CLASS_NAME,
+            gCameraMetadataMethods,
+            NELEM(gCameraMetadataMethods));
+}
+
+extern "C" {
+static void CameraMetadata_classInit(JNIEnv *env, jobject thiz) {
+    // XX: Why do this separately instead of doing it in the register function?
+    ALOGV("%s", __FUNCTION__);
+
+    field fields_to_find[] = {
+        { CAMERA_METADATA_CLASS_NAME, "mMetadataPtr", "J", &fields.metadata_ptr },
+    };
+
+    // Do this here instead of in register_native_methods,
+    // since otherwise it will fail to find the fields.
+    if (find_fields(env, fields_to_find, NELEM(fields_to_find)) < 0)
+        return;
+
+    jclass clazz = env->FindClass(CAMERA_METADATA_CLASS_NAME);
+}
+
+static jint CameraMetadata_getTagFromKey(JNIEnv *env, jobject thiz, jstring keyName) {
+
+    ScopedUtfChars keyScoped(env, keyName);
+    const char *key = keyScoped.c_str();
+    if (key == NULL) {
+        // exception thrown by ScopedUtfChars
+        return 0;
+    }
+    size_t keyLength = strlen(key);
+
+    ALOGV("%s (key = '%s')", __FUNCTION__, key);
+
+    // First, find the section by the longest string match
+    const char *section = NULL;
+    size_t sectionIndex = 0;
+    size_t sectionLength = 0;
+    for (size_t i = 0; i < ANDROID_SECTION_COUNT; ++i) {
+        const char *str = camera_metadata_section_names[i];
+        ALOGVV("%s: Trying to match against section '%s'",
+               __FUNCTION__, str);
+        if (strstr(key, str) == key) { // key begins with the section name
+            size_t strLength = strlen(str);
+
+            ALOGVV("%s: Key begins with section name", __FUNCTION__);
+
+            // section name is the longest we've found so far
+            if (section == NULL || sectionLength < strLength) {
+                section = str;
+                sectionIndex = i;
+                sectionLength = strLength;
+
+                ALOGVV("%s: Found new best section (idx %d)", __FUNCTION__, sectionIndex);
+            }
+        }
+    }
+
+    // TODO: vendor ext
+    // TODO: Make above get_camera_metadata_section_from_name ?
+
+    if (section == NULL) {
+        jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
+                             "Could not find section name for key '%s')", key);
+        return 0;
+    } else {
+        ALOGV("%s: Found matched section '%s' (%d)",
+              __FUNCTION__, section, sectionIndex);
+    }
+
+    // Get the tag name component of the key
+    const char *keyTagName = key + sectionLength + 1; // x.y.z -> z
+    if (sectionLength + 1 >= keyLength) {
+        jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
+                             "Key length too short for key '%s')", key);
+    }
+
+    // Match rest of name against the tag names in that section only
+    uint32_t tagBegin, tagEnd; // [tagBegin, tagEnd)
+    tagBegin = camera_metadata_section_bounds[sectionIndex][0];
+    tagEnd = camera_metadata_section_bounds[sectionIndex][1];
+
+    uint32_t tag;
+    for (tag = tagBegin; tag < tagEnd; ++tag) {
+        const char *tagName = get_camera_metadata_tag_name(tag);
+
+        if (strcmp(keyTagName, tagName) == 0) {
+            ALOGV("%s: Found matched tag '%s' (%d)",
+                  __FUNCTION__, tagName, tag);
+            break;
+        }
+    }
+
+    // TODO: vendor ext
+    // TODO: Make above get_camera_metadata_tag_from_name ?
+
+    if (tag == tagEnd) {
+        jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
+                             "Could not find tag name for key '%s')", key);
+        return 0;
+    }
+
+    return tag;
+}
+
+static jint CameraMetadata_getTypeFromTag(JNIEnv *env, jobject thiz, jint tag) {
+    int tagType = get_camera_metadata_tag_type(tag);
+    if (tagType == -1) {
+        jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
+                             "Tag (%d) did not have a type", tag);
+        return -1;
+    }
+
+    return tagType;
+}
+
+} // extern "C"
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index 197d240..1c43cc5 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -18,22 +18,12 @@
 
 #define LOG_TAG "AudioRecord-JNI"
 
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <math.h>
-
 #include <jni.h>
 #include <JNIHelp.h>
 #include <android_runtime/AndroidRuntime.h>
 
 #include <utils/Log.h>
-#include <utils/SortedVector.h>
-#include <utils/threads.h>
 #include <media/AudioRecord.h>
-#include <media/mediarecorder.h>
-
-#include <cutils/bitops.h>
 
 #include <system/audio.h>
 
@@ -47,8 +37,6 @@
 struct fields_t {
     // these fields provide access from C++ to the...
     jmethodID postNativeEventInJava; //... event post callback method
-    int       PCM16;                 //...  format constants
-    int       PCM8;                  //...  format constants
     jfieldID  nativeRecorderInJavaObj; // provides access to the C++ AudioRecord object
     jfieldID  nativeCallbackCookie;    // provides access to the AudioRecord callback data
 };
@@ -61,6 +49,10 @@
     Condition   cond;
 };
 
+// keep these values in sync with AudioFormat.java
+#define ENCODING_PCM_16BIT 2
+#define ENCODING_PCM_8BIT  3
+
 static Mutex sLock;
 static SortedVector <audiorecord_callback_cookie *> sAudioRecordCallBackCookies;
 
@@ -101,14 +93,11 @@
         }
         callbackInfo->busy = true;
     }
-    if (event == AudioRecord::EVENT_MORE_DATA) {
-        // set size to 0 to signal we're not using the callback to read more data
-        AudioRecord::Buffer* pBuff = (AudioRecord::Buffer*)info;
-        pBuff->size = 0;
 
-    } else if (event == AudioRecord::EVENT_MARKER) {
+    switch (event) {
+    case AudioRecord::EVENT_MARKER: {
         JNIEnv *env = AndroidRuntime::getJNIEnv();
-        if (user && env) {
+        if (user != NULL && env != NULL) {
             env->CallStaticVoidMethod(
                 callbackInfo->audioRecord_class,
                 javaAudioRecordFields.postNativeEventInJava,
@@ -118,10 +107,11 @@
                 env->ExceptionClear();
             }
         }
+        } break;
 
-    } else if (event == AudioRecord::EVENT_NEW_POS) {
+    case AudioRecord::EVENT_NEW_POS: {
         JNIEnv *env = AndroidRuntime::getJNIEnv();
-        if (user && env) {
+        if (user != NULL && env != NULL) {
             env->CallStaticVoidMethod(
                 callbackInfo->audioRecord_class,
                 javaAudioRecordFields.postNativeEventInJava,
@@ -131,7 +121,9 @@
                 env->ExceptionClear();
             }
         }
+        } break;
     }
+
     {
         Mutex::Autolock l(sLock);
         callbackInfo->busy = false;
@@ -166,28 +158,29 @@
 // ----------------------------------------------------------------------------
 static int
 android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this,
-        jint source, jint sampleRateInHertz, jint channels,
+        jint source, jint sampleRateInHertz, jint channelMask,
+                // Java channel masks map directly to the native definition
         jint audioFormat, jint buffSizeInBytes, jintArray jSession)
 {
     //ALOGV(">> Entering android_media_AudioRecord_setup");
-    //ALOGV("sampleRate=%d, audioFormat=%d, channels=%x, buffSizeInBytes=%d",
-    //     sampleRateInHertz, audioFormat, channels,     buffSizeInBytes);
+    //ALOGV("sampleRate=%d, audioFormat=%d, channel mask=%x, buffSizeInBytes=%d",
+    //     sampleRateInHertz, audioFormat, channelMask, buffSizeInBytes);
 
-    if (!audio_is_input_channel(channels)) {
-        ALOGE("Error creating AudioRecord: channel count is not 1 or 2.");
+    if (!audio_is_input_channel(channelMask)) {
+        ALOGE("Error creating AudioRecord: channel mask %#x is not valid.", channelMask);
         return AUDIORECORD_ERROR_SETUP_INVALIDCHANNELMASK;
     }
-    uint32_t nbChannels = popcount(channels);
+    uint32_t nbChannels = popcount(channelMask);
 
     // compare the format against the Java constants
-    if ((audioFormat != javaAudioRecordFields.PCM16)
-        && (audioFormat != javaAudioRecordFields.PCM8)) {
+    if ((audioFormat != ENCODING_PCM_16BIT)
+        && (audioFormat != ENCODING_PCM_8BIT)) {
         ALOGE("Error creating AudioRecord: unsupported audio format.");
         return AUDIORECORD_ERROR_SETUP_INVALIDFORMAT;
     }
 
-    int bytesPerSample = audioFormat==javaAudioRecordFields.PCM16 ? 2 : 1;
-    audio_format_t format = audioFormat==javaAudioRecordFields.PCM16 ?
+    int bytesPerSample = audioFormat == ENCODING_PCM_16BIT ? 2 : 1;
+    audio_format_t format = audioFormat == ENCODING_PCM_16BIT ?
             AUDIO_FORMAT_PCM_16_BIT : AUDIO_FORMAT_PCM_8_BIT;
 
     if (buffSizeInBytes == 0) {
@@ -197,7 +190,7 @@
     int frameSize = nbChannels * bytesPerSample;
     size_t frameCount = buffSizeInBytes / frameSize;
 
-    if (uint32_t(source) >= AUDIO_SOURCE_CNT) {
+    if ((uint32_t(source) >= AUDIO_SOURCE_CNT) && (uint32_t(source) != AUDIO_SOURCE_HOTWORD)) {
         ALOGE("Error creating AudioRecord: unknown source.");
         return AUDIORECORD_ERROR_SETUP_INVALIDSOURCE;
     }
@@ -236,12 +229,12 @@
     lpRecorder->set((audio_source_t) source,
         sampleRateInHertz,
         format,        // word length, PCM
-        channels,
+        channelMask,
         frameCount,
         recorderCallback,// callback_t
         lpCallbackData,// void* user
         0,             // notificationFrames,
-        true,          // threadCanCallJava)
+        true,          // threadCanCallJava
         sessionId);
 
     if (lpRecorder->initCheck() != NO_ERROR) {
@@ -394,6 +387,9 @@
                                             (jint)recorderBuffSize : sizeInBytes );
     env->ReleaseByteArrayElements(javaAudioData, recordBuff, 0);
 
+    if (readSize < 0) {
+        readSize = AUDIORECORD_ERROR_INVALID_OPERATION;
+    }
     return (jint) readSize;
 }
 
@@ -402,10 +398,13 @@
                                                         jshortArray javaAudioData,
                                                         jint offsetInShorts, jint sizeInShorts) {
 
-    return (android_media_AudioRecord_readInByteArray(env, thiz,
+    jint read = android_media_AudioRecord_readInByteArray(env, thiz,
                                                         (jbyteArray) javaAudioData,
-                                                        offsetInShorts*2, sizeInShorts*2)
-            / 2);
+                                                        offsetInShorts*2, sizeInShorts*2);
+    if (read > 0) {
+        read /= 2;
+    }
+    return read;
 }
 
 // ----------------------------------------------------------------------------
@@ -431,8 +430,12 @@
     }
 
     // read new data from the recorder
-    return (jint) lpRecorder->read(nativeFromJavaBuf,
+    ssize_t readSize = lpRecorder->read(nativeFromJavaBuf,
                                    capacity < sizeInBytes ? capacity : sizeInBytes);
+    if (readSize < 0) {
+        readSize = AUDIORECORD_ERROR_INVALID_OPERATION;
+    }
+    return (jint)readSize;
 }
 
 
@@ -510,7 +513,7 @@
     size_t frameCount = 0;
     status_t result = AudioRecord::getMinFrameCount(&frameCount,
             sampleRateInHertz,
-            (audioFormat == javaAudioRecordFields.PCM16 ?
+            (audioFormat == ENCODING_PCM_16BIT ?
                 AUDIO_FORMAT_PCM_16_BIT : AUDIO_FORMAT_PCM_8_BIT),
             audio_channel_in_mask_from_count(nbChannels));
 
@@ -520,7 +523,7 @@
     if (result != NO_ERROR) {
         return -1;
     }
-    return frameCount * nbChannels * (audioFormat == javaAudioRecordFields.PCM16 ? 2 : 1);
+    return frameCount * nbChannels * (audioFormat == ENCODING_PCM_16BIT ? 2 : 1);
 }
 
 
@@ -552,18 +555,9 @@
 
 // field names found in android/media/AudioRecord.java
 #define JAVA_POSTEVENT_CALLBACK_NAME  "postEventFromNative"
-#define JAVA_CONST_PCM16_NAME         "ENCODING_PCM_16BIT"
-#define JAVA_CONST_PCM8_NAME          "ENCODING_PCM_8BIT"
 #define JAVA_NATIVERECORDERINJAVAOBJ_FIELD_NAME  "mNativeRecorderInJavaObj"
 #define JAVA_NATIVECALLBACKINFO_FIELD_NAME       "mNativeCallbackCookie"
 
-#define JAVA_AUDIOFORMAT_CLASS_NAME "android/media/AudioFormat"
-
-// ----------------------------------------------------------------------------
-
-extern bool android_media_getIntConstantFromClass(JNIEnv* pEnv,
-                jclass theClass, const char* className, const char* constName, int* constVal);
-
 // ----------------------------------------------------------------------------
 int register_android_media_AudioRecord(JNIEnv *env)
 {
@@ -605,23 +599,6 @@
         return -1;
     }
 
-    // Get the format constants from the AudioFormat class
-    jclass audioFormatClass = NULL;
-    audioFormatClass = env->FindClass(JAVA_AUDIOFORMAT_CLASS_NAME);
-    if (audioFormatClass == NULL) {
-        ALOGE("Can't find %s", JAVA_AUDIOFORMAT_CLASS_NAME);
-        return -1;
-    }
-    if ( !android_media_getIntConstantFromClass(env, audioFormatClass,
-                JAVA_AUDIOFORMAT_CLASS_NAME,
-                JAVA_CONST_PCM16_NAME, &(javaAudioRecordFields.PCM16))
-           || !android_media_getIntConstantFromClass(env, audioFormatClass,
-                JAVA_AUDIOFORMAT_CLASS_NAME,
-                JAVA_CONST_PCM8_NAME, &(javaAudioRecordFields.PCM8)) ) {
-        // error log performed in getIntConstantFromClass()
-        return -1;
-    }
-
     return AndroidRuntime::registerNativeMethods(env,
             kClassPathName, gMethods, NELEM(gMethods));
 }
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 67c2cfd..7d99464 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -18,11 +18,6 @@
 #define LOG_TAG "AudioSystem"
 #include <utils/Log.h>
 
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <math.h>
-
 #include <jni.h>
 #include <JNIHelp.h>
 #include <android_runtime/AndroidRuntime.h>
@@ -46,11 +41,15 @@
 
 static int check_AudioSystem_Command(status_t status)
 {
-    if (status == NO_ERROR) {
+    switch (status) {
+    case DEAD_OBJECT:
+        return kAudioStatusMediaServerDied;
+    case NO_ERROR:
         return kAudioStatusOk;
-    } else {
-        return kAudioStatusError;
+    default:
+        break;
     }
+    return kAudioStatusError;
 }
 
 static int
@@ -127,21 +126,9 @@
 
     jclass clazz = env->FindClass(kClassPathName);
 
-    int error;
-
-    switch (err) {
-    case DEAD_OBJECT:
-        error = kAudioStatusMediaServerDied;
-        break;
-    case NO_ERROR:
-        error = kAudioStatusOk;
-        break;
-    default:
-        error = kAudioStatusError;
-        break;
-    }
-
-    env->CallStaticVoidMethod(clazz, env->GetStaticMethodID(clazz, "errorCallbackFromNative","(I)V"), error);
+    env->CallStaticVoidMethod(clazz, env->GetStaticMethodID(clazz,
+                              "errorCallbackFromNative","(I)V"),
+                              check_AudioSystem_Command(err));
 }
 
 static int
@@ -282,6 +269,18 @@
     return (jint) afLatency;
 }
 
+static jint
+android_media_AudioSystem_setLowRamDevice(JNIEnv *env, jobject clazz, jboolean isLowRamDevice)
+{
+    return (jint) AudioSystem::setLowRamDevice((bool) isLowRamDevice);
+}
+
+static int
+android_media_AudioSystem_checkAudioFlinger(JNIEnv *env, jobject clazz)
+{
+    return check_AudioSystem_Command(AudioSystem::checkAudioFlinger());
+}
+
 // ----------------------------------------------------------------------------
 
 static JNINativeMethod gMethods[] = {
@@ -308,6 +307,8 @@
     {"getPrimaryOutputSamplingRate", "()I", (void *)android_media_AudioSystem_getPrimaryOutputSamplingRate},
     {"getPrimaryOutputFrameCount",   "()I", (void *)android_media_AudioSystem_getPrimaryOutputFrameCount},
     {"getOutputLatency",    "(I)I",     (void *)android_media_AudioSystem_getOutputLatency},
+    {"setLowRamDevice",     "(Z)I",     (void *)android_media_AudioSystem_setLowRamDevice},
+    {"checkAudioFlinger",    "()I",     (void *)android_media_AudioSystem_checkAudioFlinger},
 };
 
 int register_android_media_AudioSystem(JNIEnv *env)
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 3ff9dda..225bf06 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -17,11 +17,6 @@
 
 #define LOG_TAG "AudioTrack-JNI"
 
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <math.h>
-
 #include <jni.h>
 #include <JNIHelp.h>
 #include <android_runtime/AndroidRuntime.h>
@@ -33,8 +28,6 @@
 #include <binder/MemoryHeapBase.h>
 #include <binder/MemoryBase.h>
 
-#include <cutils/bitops.h>
-
 #include <system/audio.h>
 
 // ----------------------------------------------------------------------------
@@ -47,8 +40,6 @@
 struct fields_t {
     // these fields provide access from C++ to the...
     jmethodID postNativeEventInJava; //... event post callback method
-    int       PCM16;                 //...  format constants
-    int       PCM8;                  //...  format constants
     jfieldID  nativeTrackInJavaObj;  // stores in Java the native AudioTrack object
     jfieldID  jniData;      // stores in Java additional resources used by the native AudioTrack
 };
@@ -64,6 +55,9 @@
 // keep these values in sync with AudioTrack.java
 #define MODE_STATIC 0
 #define MODE_STREAM 1
+// keep these values in sync with AudioFormat.java
+#define ENCODING_PCM_16BIT 2
+#define ENCODING_PCM_8BIT  3
 
 // ----------------------------------------------------------------------------
 class AudioTrackJniStorage {
@@ -137,14 +131,10 @@
         callbackInfo->busy = true;
     }
 
-    if (event == AudioTrack::EVENT_MORE_DATA) {
-        // set size to 0 to signal we're not using the callback to write more data
-        AudioTrack::Buffer* pBuff = (AudioTrack::Buffer*)info;
-        pBuff->size = 0;
-
-    } else if (event == AudioTrack::EVENT_MARKER) {
+    switch (event) {
+    case AudioTrack::EVENT_MARKER: {
         JNIEnv *env = AndroidRuntime::getJNIEnv();
-        if (user && env) {
+        if (user != NULL && env != NULL) {
             env->CallStaticVoidMethod(
                 callbackInfo->audioTrack_class,
                 javaAudioTrackFields.postNativeEventInJava,
@@ -154,10 +144,11 @@
                 env->ExceptionClear();
             }
         }
+        } break;
 
-    } else if (event == AudioTrack::EVENT_NEW_POS) {
+    case AudioTrack::EVENT_NEW_POS: {
         JNIEnv *env = AndroidRuntime::getJNIEnv();
-        if (user && env) {
+        if (user != NULL && env != NULL) {
             env->CallStaticVoidMethod(
                 callbackInfo->audioTrack_class,
                 javaAudioTrackFields.postNativeEventInJava,
@@ -167,7 +158,9 @@
                 env->ExceptionClear();
             }
         }
+        } break;
     }
+
     {
         Mutex::Autolock l(sLock);
         callbackInfo->busy = false;
@@ -225,7 +218,7 @@
     uint32_t nativeChannelMask = ((uint32_t)javaChannelMask) >> 2;
 
     if (!audio_is_output_channel(nativeChannelMask)) {
-        ALOGE("Error creating AudioTrack: invalid channel mask.");
+        ALOGE("Error creating AudioTrack: invalid channel mask %#x.", javaChannelMask);
         return AUDIOTRACK_ERROR_SETUP_INVALIDCHANNELMASK;
     }
 
@@ -251,7 +244,8 @@
 
     // check the format.
     // This function was called from Java, so we compare the format against the Java constants
-    if ((audioFormat != javaAudioTrackFields.PCM16) && (audioFormat != javaAudioTrackFields.PCM8)) {
+    if ((audioFormat != ENCODING_PCM_16BIT) && (audioFormat != ENCODING_PCM_8BIT)) {
+
         ALOGE("Error creating AudioTrack: unsupported audio format.");
         return AUDIOTRACK_ERROR_SETUP_INVALIDFORMAT;
     }
@@ -259,19 +253,19 @@
     // for the moment 8bitPCM in MODE_STATIC is not supported natively in the AudioTrack C++ class
     // so we declare everything as 16bitPCM, the 8->16bit conversion for MODE_STATIC will be handled
     // in android_media_AudioTrack_native_write_byte()
-    if ((audioFormat == javaAudioTrackFields.PCM8)
+    if ((audioFormat == ENCODING_PCM_8BIT)
         && (memoryMode == MODE_STATIC)) {
         ALOGV("android_media_AudioTrack_native_setup(): requesting MODE_STATIC for 8bit \
             buff size of %dbytes, switching to 16bit, buff size of %dbytes",
             buffSizeInBytes, 2*buffSizeInBytes);
-        audioFormat = javaAudioTrackFields.PCM16;
+        audioFormat = ENCODING_PCM_16BIT;
         // we will need twice the memory to store the data
         buffSizeInBytes *= 2;
     }
 
     // compute the frame count
-    int bytesPerSample = audioFormat == javaAudioTrackFields.PCM16 ? 2 : 1;
-    audio_format_t format = audioFormat == javaAudioTrackFields.PCM16 ?
+    int bytesPerSample = audioFormat == ENCODING_PCM_16BIT ? 2 : 1;
+    audio_format_t format = audioFormat == ENCODING_PCM_16BIT ?
             AUDIO_FORMAT_PCM_16_BIT : AUDIO_FORMAT_PCM_8_BIT;
     int frameCount = buffSizeInBytes / (nbChannels * bytesPerSample);
 
@@ -520,15 +514,19 @@
     // regular write() or copy the data to the AudioTrack's shared memory?
     if (track->sharedBuffer() == 0) {
         written = track->write(data + offsetInBytes, sizeInBytes);
+        // for compatibility with earlier behavior of write(), return 0 in this case
+        if (written == (ssize_t) WOULD_BLOCK) {
+            written = 0;
+        }
     } else {
-        if (audioFormat == javaAudioTrackFields.PCM16) {
+        if (audioFormat == ENCODING_PCM_16BIT) {
             // writing to shared memory, check for capacity
             if ((size_t)sizeInBytes > track->sharedBuffer()->size()) {
                 sizeInBytes = track->sharedBuffer()->size();
             }
             memcpy(track->sharedBuffer()->pointer(), data + offsetInBytes, sizeInBytes);
             written = sizeInBytes;
-        } else if (audioFormat == javaAudioTrackFields.PCM8) {
+        } else if (audioFormat == ENCODING_PCM_8BIT) {
             // data contains 8bit data we need to expand to 16bit before copying
             // to the shared memory
             // writing to shared memory, check for capacity,
@@ -597,11 +595,14 @@
                                                   jshortArray javaAudioData,
                                                   jint offsetInShorts, jint sizeInShorts,
                                                   jint javaAudioFormat) {
-    return (android_media_AudioTrack_native_write_byte(env, thiz,
+    jint written = android_media_AudioTrack_native_write_byte(env, thiz,
                                                  (jbyteArray) javaAudioData,
                                                  offsetInShorts*2, sizeInShorts*2,
-                                                 javaAudioFormat)
-            / 2);
+                                                 javaAudioFormat);
+    if (written > 0) {
+        written /= 2;
+    }
+    return written;
 }
 
 
@@ -741,6 +742,30 @@
 
 
 // ----------------------------------------------------------------------------
+static jint android_media_AudioTrack_get_timestamp(JNIEnv *env,  jobject thiz, jlongArray jTimestamp) {
+    sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
+
+    if (lpTrack == NULL) {
+        ALOGE("Unable to retrieve AudioTrack pointer for getTimestamp()");
+        return AUDIOTRACK_ERROR;
+    }
+    AudioTimestamp timestamp;
+    status_t status = lpTrack->getTimestamp(timestamp);
+    if (status == OK) {
+        jlong* nTimestamp = (jlong *) env->GetPrimitiveArrayCritical(jTimestamp, NULL);
+        if (nTimestamp == NULL) {
+            ALOGE("Unable to get array for getTimestamp()");
+            return AUDIOTRACK_ERROR;
+        }
+        nTimestamp[0] = (jlong) timestamp.mPosition;
+        nTimestamp[1] = (jlong) ((timestamp.mTime.tv_sec * 1000000000LL) + timestamp.mTime.tv_nsec);
+        env->ReleasePrimitiveArrayCritical(jTimestamp, nTimestamp, 0);
+    }
+    return (jint) android_media_translateErrorCode(status);
+}
+
+
+// ----------------------------------------------------------------------------
 static jint android_media_AudioTrack_set_loop(JNIEnv *env,  jobject thiz,
         jint loopStart, jint loopEnd, jint loopCount) {
     sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
@@ -809,7 +834,7 @@
             sampleRateInHertz) != NO_ERROR) {
         return -1;
     }
-    return frameCount * nbChannels * (audioFormat == javaAudioTrackFields.PCM16 ? 2 : 1);
+    return frameCount * nbChannels * (audioFormat == ENCODING_PCM_16BIT ? 2 : 1);
 }
 
 // ----------------------------------------------------------------------------
@@ -868,6 +893,7 @@
     {"native_set_position",  "(I)I",     (void *)android_media_AudioTrack_set_position},
     {"native_get_position",  "()I",      (void *)android_media_AudioTrack_get_position},
     {"native_get_latency",   "()I",      (void *)android_media_AudioTrack_get_latency},
+    {"native_get_timestamp", "([J)I",    (void *)android_media_AudioTrack_get_timestamp},
     {"native_set_loop",      "(III)I",   (void *)android_media_AudioTrack_set_loop},
     {"native_reload_static", "()I",      (void *)android_media_AudioTrack_reload},
     {"native_get_output_sample_rate",
@@ -883,23 +909,9 @@
 
 // field names found in android/media/AudioTrack.java
 #define JAVA_POSTEVENT_CALLBACK_NAME                    "postEventFromNative"
-#define JAVA_CONST_PCM16_NAME                           "ENCODING_PCM_16BIT"
-#define JAVA_CONST_PCM8_NAME                            "ENCODING_PCM_8BIT"
-#define JAVA_CONST_BUFFER_COUNT_NAME                    "BUFFER_COUNT"
-#define JAVA_CONST_STREAM_VOICE_CALL_NAME               "STREAM_VOICE_CALL"
-#define JAVA_CONST_STREAM_SYSTEM_NAME                   "STREAM_SYSTEM"
-#define JAVA_CONST_STREAM_RING_NAME                     "STREAM_RING"
-#define JAVA_CONST_STREAM_MUSIC_NAME                    "STREAM_MUSIC"
-#define JAVA_CONST_STREAM_ALARM_NAME                    "STREAM_ALARM"
-#define JAVA_CONST_STREAM_NOTIFICATION_NAME             "STREAM_NOTIFICATION"
-#define JAVA_CONST_STREAM_BLUETOOTH_SCO_NAME            "STREAM_BLUETOOTH_SCO"
-#define JAVA_CONST_STREAM_DTMF_NAME                     "STREAM_DTMF"
 #define JAVA_NATIVETRACKINJAVAOBJ_FIELD_NAME            "mNativeTrackInJavaObj"
 #define JAVA_JNIDATA_FIELD_NAME                         "mJniData"
 
-#define JAVA_AUDIOFORMAT_CLASS_NAME             "android/media/AudioFormat"
-#define JAVA_AUDIOMANAGER_CLASS_NAME            "android/media/AudioManager"
-
 // ----------------------------------------------------------------------------
 // preconditions:
 //    theClass is valid
@@ -957,23 +969,6 @@
         return -1;
     }
 
-    // Get the format constants from the AudioFormat class
-    jclass audioFormatClass = NULL;
-    audioFormatClass = env->FindClass(JAVA_AUDIOFORMAT_CLASS_NAME);
-    if (audioFormatClass == NULL) {
-        ALOGE("Can't find %s", JAVA_AUDIOFORMAT_CLASS_NAME);
-        return -1;
-    }
-    if ( !android_media_getIntConstantFromClass(env, audioFormatClass,
-                JAVA_AUDIOFORMAT_CLASS_NAME,
-                JAVA_CONST_PCM16_NAME, &(javaAudioTrackFields.PCM16))
-           || !android_media_getIntConstantFromClass(env, audioFormatClass,
-                JAVA_AUDIOFORMAT_CLASS_NAME,
-                JAVA_CONST_PCM8_NAME, &(javaAudioTrackFields.PCM8)) ) {
-        // error log performed in android_media_getIntConstantFromClass()
-        return -1;
-    }
-
     return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
 }
 
diff --git a/core/jni/android_media_RemoteDisplay.cpp b/core/jni/android_media_RemoteDisplay.cpp
index 80d13be..463be5e 100644
--- a/core/jni/android_media_RemoteDisplay.cpp
+++ b/core/jni/android_media_RemoteDisplay.cpp
@@ -24,6 +24,7 @@
 
 #include <android_runtime/AndroidRuntime.h>
 #include <android_runtime/android_view_Surface.h>
+#include <android_runtime/Log.h>
 
 #include <binder/IServiceManager.h>
 
@@ -61,7 +62,7 @@
 
 public:
     virtual void onDisplayConnected(const sp<IGraphicBufferProducer>& bufferProducer,
-            uint32_t width, uint32_t height, uint32_t flags) {
+            uint32_t width, uint32_t height, uint32_t flags, uint32_t session) {
         JNIEnv* env = AndroidRuntime::getJNIEnv();
 
         jobject surfaceObj = android_view_Surface_createFromIGraphicBufferProducer(env, bufferProducer);
@@ -73,7 +74,7 @@
 
         env->CallVoidMethod(mRemoteDisplayObjGlobal,
                 gRemoteDisplayClassInfo.notifyDisplayConnected,
-                surfaceObj, width, height, flags);
+                surfaceObj, width, height, flags, session);
         env->DeleteLocalRef(surfaceObj);
         checkAndClearExceptionFromCallback(env, "notifyDisplayConnected");
     }
@@ -117,6 +118,14 @@
         mDisplay->dispose();
     }
 
+    void pause() {
+        mDisplay->pause();
+    }
+
+    void resume() {
+        mDisplay->resume();
+    }
+
 private:
     sp<IRemoteDisplay> mDisplay;
     sp<NativeRemoteDisplayClient> mClient;
@@ -149,6 +158,16 @@
     return reinterpret_cast<jint>(wrapper);
 }
 
+static void nativePause(JNIEnv* env, jobject remoteDisplayObj, jint ptr) {
+    NativeRemoteDisplay* wrapper = reinterpret_cast<NativeRemoteDisplay*>(ptr);
+    wrapper->pause();
+}
+
+static void nativeResume(JNIEnv* env, jobject remoteDisplayObj, jint ptr) {
+    NativeRemoteDisplay* wrapper = reinterpret_cast<NativeRemoteDisplay*>(ptr);
+    wrapper->resume();
+}
+
 static void nativeDispose(JNIEnv* env, jobject remoteDisplayObj, jint ptr) {
     NativeRemoteDisplay* wrapper = reinterpret_cast<NativeRemoteDisplay*>(ptr);
     delete wrapper;
@@ -161,6 +180,10 @@
             (void*)nativeListen },
     {"nativeDispose", "(I)V",
             (void*)nativeDispose },
+    {"nativePause", "(I)V",
+            (void*)nativePause },
+    {"nativeResume", "(I)V",
+            (void*)nativeResume },
 };
 
 int register_android_media_RemoteDisplay(JNIEnv* env)
@@ -171,7 +194,7 @@
     jclass clazz = env->FindClass("android/media/RemoteDisplay");
     gRemoteDisplayClassInfo.notifyDisplayConnected =
             env->GetMethodID(clazz, "notifyDisplayConnected",
-                    "(Landroid/view/Surface;III)V");
+                    "(Landroid/view/Surface;IIII)V");
     gRemoteDisplayClassInfo.notifyDisplayDisconnected =
             env->GetMethodID(clazz, "notifyDisplayDisconnected", "()V");
     gRemoteDisplayClassInfo.notifyDisplayError =
diff --git a/core/jni/android_net_LocalSocketImpl.cpp b/core/jni/android_net_LocalSocketImpl.cpp
index f2b69c6..b9ed28e 100644
--- a/core/jni/android_net_LocalSocketImpl.cpp
+++ b/core/jni/android_net_LocalSocketImpl.cpp
@@ -44,26 +44,6 @@
 static jclass class_FileDescriptor;
 static jmethodID method_CredentialsInit;
 
-/*
- * private native FileDescriptor
- * create_native(boolean stream)
- *               throws IOException;
- */
-static jobject
-socket_create (JNIEnv *env, jobject object, jboolean stream)
-{
-    int ret;
-
-    ret = socket(PF_LOCAL, stream ? SOCK_STREAM : SOCK_DGRAM, 0);
-
-    if (ret < 0) {
-        jniThrowIOException(env, errno);
-        return NULL;
-    }
-
-    return jniCreateFileDescriptor(env,ret);
-}
-
 /* private native void connectLocal(FileDescriptor fd,
  * String name, int namespace) throws IOException
  */
@@ -445,32 +425,6 @@
 #endif
 }
 
-static void socket_close (JNIEnv *env, jobject object, jobject fileDescriptor)
-{
-    int fd;
-    int err;
-
-    if (fileDescriptor == NULL) {
-        jniThrowNullPointerException(env, NULL);
-        return;
-    }
-
-    fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
-
-    if (env->ExceptionOccurred() != NULL) {
-        return;
-    }
-
-    do {
-        err = close(fd);
-    } while (err < 0 && errno == EINTR);
-
-    if (err < 0) {
-        jniThrowIOException(env, errno);
-        return;
-    }
-}
-
 /**
  * Processes ancillary data, handling only
  * SCM_RIGHTS. Creates appropriate objects and sets appropriate
@@ -909,7 +863,6 @@
      /* name, signature, funcPtr */
     {"getOption_native", "(Ljava/io/FileDescriptor;I)I", (void*)socket_getOption},
     {"setOption_native", "(Ljava/io/FileDescriptor;III)V", (void*)socket_setOption},
-    {"create_native", "(Z)Ljava/io/FileDescriptor;", (void*)socket_create},
     {"connectLocal", "(Ljava/io/FileDescriptor;Ljava/lang/String;I)V",
                                                 (void*)socket_connect_local},
     {"bindLocal", "(Ljava/io/FileDescriptor;Ljava/lang/String;I)V", (void*)socket_bind_local},
@@ -918,7 +871,6 @@
     {"shutdown", "(Ljava/io/FileDescriptor;Z)V", (void*)socket_shutdown},
     {"available_native", "(Ljava/io/FileDescriptor;)I", (void*) socket_available},
     {"pending_native", "(Ljava/io/FileDescriptor;)I", (void*) socket_pending},
-    {"close_native", "(Ljava/io/FileDescriptor;)V", (void*) socket_close},
     {"read_native", "(Ljava/io/FileDescriptor;)I", (void*) socket_read},
     {"readba_native", "([BIILjava/io/FileDescriptor;)I", (void*) socket_readba},
     {"writeba_native", "([BIILjava/io/FileDescriptor;)V", (void*) socket_writeba},
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index faae11e..6d23c32 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "NetUtils"
 
 #include "jni.h"
+#include "JNIHelp.h"
 #include <utils/misc.h>
 #include <android_runtime/AndroidRuntime.h>
 #include <utils/Log.h>
@@ -36,7 +37,8 @@
                     const char *server,
                     uint32_t *lease,
                     const char *vendorInfo,
-                    const char *domains);
+                    const char *domains,
+                    const char *mtu);
 
 int dhcp_do_request_renew(const char * const ifname,
                     const char *ipaddr,
@@ -46,7 +48,8 @@
                     const char *server,
                     uint32_t *lease,
                     const char *vendorInfo,
-                    const char *domains);
+                    const char *domains,
+                    const char *mtu);
 
 int dhcp_stop(const char *ifname);
 int dhcp_release_lease(const char *ifname);
@@ -125,19 +128,20 @@
     uint32_t lease;
     char vendorInfo[PROPERTY_VALUE_MAX];
     char domains[PROPERTY_VALUE_MAX];
+    char mtu[PROPERTY_VALUE_MAX];
 
     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
     if (nameStr == NULL) return (jboolean)false;
 
     if (renew) {
         result = ::dhcp_do_request_renew(nameStr, ipaddr, gateway, &prefixLength,
-                dns, server, &lease, vendorInfo, domains);
+                dns, server, &lease, vendorInfo, domains, mtu);
     } else {
         result = ::dhcp_do_request(nameStr, ipaddr, gateway, &prefixLength,
-                dns, server, &lease, vendorInfo, domains);
+                dns, server, &lease, vendorInfo, domains, mtu);
     }
     if (result != 0) {
-        ALOGD("dhcp_do_request failed");
+        ALOGD("dhcp_do_request failed : %s (%s)", nameStr, renew ? "renew" : "new");
     }
 
     env->ReleaseStringUTFChars(ifname, nameStr);
@@ -239,6 +243,13 @@
     return env->NewStringUTF(::dhcp_get_errmsg());
 }
 
+static void android_net_utils_markSocket(JNIEnv *env, jobject thiz, jint socket, jint mark)
+{
+    if (setsockopt(socket, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0) {
+        jniThrowException(env, "java/lang/IllegalStateException", "Error marking socket");
+    }
+}
+
 // ----------------------------------------------------------------------------
 
 /*
@@ -255,6 +266,7 @@
     { "stopDhcp", "(Ljava/lang/String;)Z",  (void *)android_net_utils_stopDhcp },
     { "releaseDhcpLease", "(Ljava/lang/String;)Z",  (void *)android_net_utils_releaseDhcpLease },
     { "getDhcpError", "()Ljava/lang/String;", (void*) android_net_utils_getDhcpError },
+    { "markSocket", "(II)V", (void*) android_net_utils_markSocket },
 };
 
 int register_android_net_NetworkUtils(JNIEnv* env)
diff --git a/core/jni/android_net_TrafficStats.cpp b/core/jni/android_net_TrafficStats.cpp
index b4c4a1b..f904b62 100644
--- a/core/jni/android_net_TrafficStats.cpp
+++ b/core/jni/android_net_TrafficStats.cpp
@@ -23,7 +23,6 @@
 #include <sys/types.h>
 
 #include <android_runtime/AndroidRuntime.h>
-#include <cutils/logger.h>
 #include <jni.h>
 #include <ScopedUtfChars.h>
 #include <utils/misc.h>
diff --git a/core/jni/android_net_wifi_Wifi.cpp b/core/jni/android_net_wifi_Wifi.cpp
deleted file mode 100644
index 9537ac4..0000000
--- a/core/jni/android_net_wifi_Wifi.cpp
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright 2008, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "wifi"
-
-#include "jni.h"
-#include <ScopedUtfChars.h>
-#include <utils/misc.h>
-#include <android_runtime/AndroidRuntime.h>
-#include <utils/Log.h>
-#include <utils/String16.h>
-
-#include "wifi.h"
-
-#define WIFI_PKG_NAME "android/net/wifi/WifiNative"
-#define BUF_SIZE 256
-#define EVENT_BUF_SIZE 2048
-
-namespace android {
-
-static jint DBG = false;
-
-static int doCommand(const char *ifname, const char *cmd, char *replybuf, int replybuflen)
-{
-    size_t reply_len = replybuflen - 1;
-
-    if (::wifi_command(ifname, cmd, replybuf, &reply_len) != 0)
-        return -1;
-    else {
-        // Strip off trailing newline
-        if (reply_len > 0 && replybuf[reply_len-1] == '\n')
-            replybuf[reply_len-1] = '\0';
-        else
-            replybuf[reply_len] = '\0';
-        return 0;
-    }
-}
-
-static jint doIntCommand(const char *ifname, const char* fmt, ...)
-{
-    char buf[BUF_SIZE];
-    va_list args;
-    va_start(args, fmt);
-    int byteCount = vsnprintf(buf, sizeof(buf), fmt, args);
-    va_end(args);
-    if (byteCount < 0 || byteCount >= BUF_SIZE) {
-        return -1;
-    }
-    char reply[BUF_SIZE];
-    if (doCommand(ifname, buf, reply, sizeof(reply)) != 0) {
-        return -1;
-    }
-    return static_cast<jint>(atoi(reply));
-}
-
-static jboolean doBooleanCommand(const char *ifname, const char* expect, const char* fmt, ...)
-{
-    char buf[BUF_SIZE];
-    va_list args;
-    va_start(args, fmt);
-    int byteCount = vsnprintf(buf, sizeof(buf), fmt, args);
-    va_end(args);
-    if (byteCount < 0 || byteCount >= BUF_SIZE) {
-        return JNI_FALSE;
-    }
-    char reply[BUF_SIZE];
-    if (doCommand(ifname, buf, reply, sizeof(reply)) != 0) {
-        return JNI_FALSE;
-    }
-    return (strcmp(reply, expect) == 0);
-}
-
-// Send a command to the supplicant, and return the reply as a String
-static jstring doStringCommand(JNIEnv* env, const char *ifname, const char* fmt, ...) {
-    char buf[BUF_SIZE];
-    va_list args;
-    va_start(args, fmt);
-    int byteCount = vsnprintf(buf, sizeof(buf), fmt, args);
-    va_end(args);
-    if (byteCount < 0 || byteCount >= BUF_SIZE) {
-        return NULL;
-    }
-    char reply[4096];
-    if (doCommand(ifname, buf, reply, sizeof(reply)) != 0) {
-        return NULL;
-    }
-    // TODO: why not just NewStringUTF?
-    String16 str((char *)reply);
-    return env->NewString((const jchar *)str.string(), str.size());
-}
-
-static jboolean android_net_wifi_isDriverLoaded(JNIEnv* env, jobject)
-{
-    return (jboolean)(::is_wifi_driver_loaded() == 1);
-}
-
-static jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject)
-{
-    return (jboolean)(::wifi_load_driver() == 0);
-}
-
-static jboolean android_net_wifi_unloadDriver(JNIEnv* env, jobject)
-{
-    return (jboolean)(::wifi_unload_driver() == 0);
-}
-
-static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject, jboolean p2pSupported)
-{
-    return (jboolean)(::wifi_start_supplicant(p2pSupported) == 0);
-}
-
-static jboolean android_net_wifi_killSupplicant(JNIEnv* env, jobject, jboolean p2pSupported)
-{
-    return (jboolean)(::wifi_stop_supplicant(p2pSupported) == 0);
-}
-
-static jboolean android_net_wifi_connectToSupplicant(JNIEnv* env, jobject, jstring jIface)
-{
-    ScopedUtfChars ifname(env, jIface);
-    return (jboolean)(::wifi_connect_to_supplicant(ifname.c_str()) == 0);
-}
-
-static void android_net_wifi_closeSupplicantConnection(JNIEnv* env, jobject, jstring jIface)
-{
-    ScopedUtfChars ifname(env, jIface);
-    ::wifi_close_supplicant_connection(ifname.c_str());
-}
-
-static jstring android_net_wifi_waitForEvent(JNIEnv* env, jobject, jstring jIface)
-{
-    char buf[EVENT_BUF_SIZE];
-    ScopedUtfChars ifname(env, jIface);
-    int nread = ::wifi_wait_for_event(ifname.c_str(), buf, sizeof buf);
-    if (nread > 0) {
-        return env->NewStringUTF(buf);
-    } else {
-        return NULL;
-    }
-}
-
-static jboolean android_net_wifi_doBooleanCommand(JNIEnv* env, jobject, jstring jIface,
-        jstring jCommand)
-{
-    ScopedUtfChars ifname(env, jIface);
-    ScopedUtfChars command(env, jCommand);
-
-    if (command.c_str() == NULL) {
-        return JNI_FALSE;
-    }
-    if (DBG) ALOGD("doBoolean: %s", command.c_str());
-    return doBooleanCommand(ifname.c_str(), "OK", "%s", command.c_str());
-}
-
-static jint android_net_wifi_doIntCommand(JNIEnv* env, jobject, jstring jIface,
-        jstring jCommand)
-{
-    ScopedUtfChars ifname(env, jIface);
-    ScopedUtfChars command(env, jCommand);
-
-    if (command.c_str() == NULL) {
-        return -1;
-    }
-    if (DBG) ALOGD("doInt: %s", command.c_str());
-    return doIntCommand(ifname.c_str(), "%s", command.c_str());
-}
-
-static jstring android_net_wifi_doStringCommand(JNIEnv* env, jobject, jstring jIface,
-        jstring jCommand)
-{
-    ScopedUtfChars ifname(env, jIface);
-
-    ScopedUtfChars command(env, jCommand);
-    if (command.c_str() == NULL) {
-        return NULL;
-    }
-    if (DBG) ALOGD("doString: %s", command.c_str());
-    return doStringCommand(env, ifname.c_str(), "%s", command.c_str());
-}
-
-
-
-// ----------------------------------------------------------------------------
-
-/*
- * JNI registration.
- */
-static JNINativeMethod gWifiMethods[] = {
-    /* name, signature, funcPtr */
-
-    { "loadDriver", "()Z",  (void *)android_net_wifi_loadDriver },
-    { "isDriverLoaded", "()Z",  (void *)android_net_wifi_isDriverLoaded },
-    { "unloadDriver", "()Z",  (void *)android_net_wifi_unloadDriver },
-    { "startSupplicant", "(Z)Z",  (void *)android_net_wifi_startSupplicant },
-    { "killSupplicant", "(Z)Z",  (void *)android_net_wifi_killSupplicant },
-    { "connectToSupplicant", "(Ljava/lang/String;)Z",
-            (void *)android_net_wifi_connectToSupplicant },
-    { "closeSupplicantConnection", "(Ljava/lang/String;)V",
-            (void *)android_net_wifi_closeSupplicantConnection },
-    { "waitForEvent", "(Ljava/lang/String;)Ljava/lang/String;",
-            (void*) android_net_wifi_waitForEvent },
-    { "doBooleanCommand", "(Ljava/lang/String;Ljava/lang/String;)Z",
-            (void*) android_net_wifi_doBooleanCommand },
-    { "doIntCommand", "(Ljava/lang/String;Ljava/lang/String;)I",
-            (void*) android_net_wifi_doIntCommand },
-    { "doStringCommand", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
-            (void*) android_net_wifi_doStringCommand },
-};
-
-int register_android_net_wifi_WifiManager(JNIEnv* env)
-{
-    return AndroidRuntime::registerNativeMethods(env,
-            WIFI_PKG_NAME, gWifiMethods, NELEM(gWifiMethods));
-}
-
-}; // namespace android
diff --git a/core/jni/android_net_wifi_WifiNative.cpp b/core/jni/android_net_wifi_WifiNative.cpp
new file mode 100644
index 0000000..6e11192
--- /dev/null
+++ b/core/jni/android_net_wifi_WifiNative.cpp
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2008, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "wifi"
+
+#include "jni.h"
+#include <ScopedUtfChars.h>
+#include <utils/misc.h>
+#include <android_runtime/AndroidRuntime.h>
+#include <utils/Log.h>
+#include <utils/String16.h>
+
+#include "wifi.h"
+
+#define REPLY_BUF_SIZE 4096 // wpa_supplicant's maximum size.
+#define EVENT_BUF_SIZE 2048
+
+namespace android {
+
+static jint DBG = false;
+
+static bool doCommand(JNIEnv* env, jstring javaCommand,
+                      char* reply, size_t reply_len) {
+    ScopedUtfChars command(env, javaCommand);
+    if (command.c_str() == NULL) {
+        return false; // ScopedUtfChars already threw on error.
+    }
+
+    if (DBG) {
+        ALOGD("doCommand: %s", command.c_str());
+    }
+
+    --reply_len; // Ensure we have room to add NUL termination.
+    if (::wifi_command(command.c_str(), reply, &reply_len) != 0) {
+        return false;
+    }
+
+    // Strip off trailing newline.
+    if (reply_len > 0 && reply[reply_len-1] == '\n') {
+        reply[reply_len-1] = '\0';
+    } else {
+        reply[reply_len] = '\0';
+    }
+    return true;
+}
+
+static jint doIntCommand(JNIEnv* env, jstring javaCommand) {
+    char reply[REPLY_BUF_SIZE];
+    if (!doCommand(env, javaCommand, reply, sizeof(reply))) {
+        return -1;
+    }
+    return static_cast<jint>(atoi(reply));
+}
+
+static jboolean doBooleanCommand(JNIEnv* env, jstring javaCommand) {
+    char reply[REPLY_BUF_SIZE];
+    if (!doCommand(env, javaCommand, reply, sizeof(reply))) {
+        return JNI_FALSE;
+    }
+    return (strcmp(reply, "OK") == 0);
+}
+
+// Send a command to the supplicant, and return the reply as a String.
+static jstring doStringCommand(JNIEnv* env, jstring javaCommand) {
+    char reply[REPLY_BUF_SIZE];
+    if (!doCommand(env, javaCommand, reply, sizeof(reply))) {
+        return NULL;
+    }
+    return env->NewStringUTF(reply);
+}
+
+static jboolean android_net_wifi_isDriverLoaded(JNIEnv* env, jobject)
+{
+    return (::is_wifi_driver_loaded() == 1);
+}
+
+static jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject)
+{
+    return (::wifi_load_driver() == 0);
+}
+
+static jboolean android_net_wifi_unloadDriver(JNIEnv* env, jobject)
+{
+    return (::wifi_unload_driver() == 0);
+}
+
+static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject, jboolean p2pSupported)
+{
+    return (::wifi_start_supplicant(p2pSupported) == 0);
+}
+
+static jboolean android_net_wifi_killSupplicant(JNIEnv* env, jobject, jboolean p2pSupported)
+{
+    return (::wifi_stop_supplicant(p2pSupported) == 0);
+}
+
+static jboolean android_net_wifi_connectToSupplicant(JNIEnv* env, jobject)
+{
+    return (::wifi_connect_to_supplicant() == 0);
+}
+
+static void android_net_wifi_closeSupplicantConnection(JNIEnv* env, jobject)
+{
+    ::wifi_close_supplicant_connection();
+}
+
+static jstring android_net_wifi_waitForEvent(JNIEnv* env, jobject)
+{
+    char buf[EVENT_BUF_SIZE];
+    int nread = ::wifi_wait_for_event(buf, sizeof buf);
+    if (nread > 0) {
+        return env->NewStringUTF(buf);
+    } else {
+        return NULL;
+    }
+}
+
+static jboolean android_net_wifi_doBooleanCommand(JNIEnv* env, jobject, jstring javaCommand) {
+    return doBooleanCommand(env, javaCommand);
+}
+
+static jint android_net_wifi_doIntCommand(JNIEnv* env, jobject, jstring javaCommand) {
+    return doIntCommand(env, javaCommand);
+}
+
+static jstring android_net_wifi_doStringCommand(JNIEnv* env, jobject, jstring javaCommand) {
+    return doStringCommand(env,javaCommand);
+}
+
+
+
+// ----------------------------------------------------------------------------
+
+/*
+ * JNI registration.
+ */
+static JNINativeMethod gWifiMethods[] = {
+    /* name, signature, funcPtr */
+
+    { "loadDriver", "()Z",  (void *)android_net_wifi_loadDriver },
+    { "isDriverLoaded", "()Z",  (void *)android_net_wifi_isDriverLoaded },
+    { "unloadDriver", "()Z",  (void *)android_net_wifi_unloadDriver },
+    { "startSupplicant", "(Z)Z",  (void *)android_net_wifi_startSupplicant },
+    { "killSupplicant", "(Z)Z",  (void *)android_net_wifi_killSupplicant },
+    { "connectToSupplicantNative", "()Z", (void *)android_net_wifi_connectToSupplicant },
+    { "closeSupplicantConnectionNative", "()V",
+            (void *)android_net_wifi_closeSupplicantConnection },
+    { "waitForEventNative", "()Ljava/lang/String;", (void*)android_net_wifi_waitForEvent },
+    { "doBooleanCommandNative", "(Ljava/lang/String;)Z", (void*)android_net_wifi_doBooleanCommand },
+    { "doIntCommandNative", "(Ljava/lang/String;)I", (void*)android_net_wifi_doIntCommand },
+    { "doStringCommandNative", "(Ljava/lang/String;)Ljava/lang/String;",
+            (void*) android_net_wifi_doStringCommand },
+};
+
+int register_android_net_wifi_WifiNative(JNIEnv* env) {
+    return AndroidRuntime::registerNativeMethods(env,
+            "android/net/wifi/WifiNative", gWifiMethods, NELEM(gWifiMethods));
+}
+
+}; // namespace android
diff --git a/core/jni/android_opengl_EGL14.cpp b/core/jni/android_opengl_EGL14.cpp
index 664af07..1fe4b08 100644
--- a/core/jni/android_opengl_EGL14.cpp
+++ b/core/jni/android_opengl_EGL14.cpp
@@ -136,7 +136,7 @@
   (JNIEnv *_env, jobject _this) {
     EGLint _returnValue = (EGLint) 0;
     _returnValue = eglGetError();
-    return _returnValue;
+    return (jint)_returnValue;
 }
 
 /* EGLDisplay eglGetDisplay ( EGLNativeDisplayType display_id ) */
@@ -230,7 +230,7 @@
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
     }
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* EGLBoolean eglTerminate ( EGLDisplay dpy ) */
@@ -243,7 +243,7 @@
     _returnValue = eglTerminate(
         (EGLDisplay)dpy_native
     );
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* const char * eglQueryString ( EGLDisplay dpy, EGLint name ) */
@@ -331,7 +331,7 @@
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
     }
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* EGLBoolean eglChooseConfig ( EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config ) */
@@ -454,7 +454,7 @@
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
     }
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* EGLBoolean eglGetConfigAttrib ( EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value ) */
@@ -509,7 +509,7 @@
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
     }
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* EGLSurface eglCreateWindowSurface ( EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list ) */
@@ -604,7 +604,7 @@
     jint _remaining;
     EGLint *attrib_list = (EGLint *) 0;
     android::sp<ANativeWindow> window;
-    android::sp<android::GLConsumer> glConsumer;
+    android::sp<android::IGraphicBufferProducer> producer;
 
     if (!attrib_list_ref) {
         _exception = 1;
@@ -625,12 +625,12 @@
         _exceptionMessage = "Make sure the SurfaceView or associated SurfaceHolder has a valid Surface";
         goto exit;
     }
-    glConsumer = android::SurfaceTexture_getSurfaceTexture(_env, win);
+    producer = android::SurfaceTexture_getProducer(_env, win);
 
-    if (glConsumer == NULL)
+    if (producer == NULL)
         goto not_valid_surface;
 
-    window = new android::Surface(glConsumer->getBufferQueue());
+    window = new android::Surface(producer);
 
     if (window == NULL)
         goto not_valid_surface;
@@ -753,7 +753,7 @@
         (EGLDisplay)dpy_native,
         (EGLSurface)surface_native
     );
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* EGLBoolean eglQuerySurface ( EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value ) */
@@ -808,7 +808,7 @@
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
     }
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* EGLBoolean eglBindAPI ( EGLenum api ) */
@@ -819,7 +819,7 @@
     _returnValue = eglBindAPI(
         (EGLenum)api
     );
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* EGLenum eglQueryAPI ( void ) */
@@ -828,7 +828,7 @@
   (JNIEnv *_env, jobject _this) {
     EGLenum _returnValue = (EGLenum) 0;
     _returnValue = eglQueryAPI();
-    return _returnValue;
+    return (jint)_returnValue;
 }
 
 /* EGLBoolean eglWaitClient ( void ) */
@@ -837,7 +837,7 @@
   (JNIEnv *_env, jobject _this) {
     EGLBoolean _returnValue = (EGLBoolean) 0;
     _returnValue = eglWaitClient();
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* EGLBoolean eglReleaseThread ( void ) */
@@ -846,7 +846,7 @@
   (JNIEnv *_env, jobject _this) {
     EGLBoolean _returnValue = (EGLBoolean) 0;
     _returnValue = eglReleaseThread();
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* EGLSurface eglCreatePbufferFromClientBuffer ( EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list ) */
@@ -927,7 +927,7 @@
         (EGLint)attribute,
         (EGLint)value
     );
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* EGLBoolean eglBindTexImage ( EGLDisplay dpy, EGLSurface surface, EGLint buffer ) */
@@ -943,7 +943,7 @@
         (EGLSurface)surface_native,
         (EGLint)buffer
     );
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* EGLBoolean eglReleaseTexImage ( EGLDisplay dpy, EGLSurface surface, EGLint buffer ) */
@@ -959,7 +959,7 @@
         (EGLSurface)surface_native,
         (EGLint)buffer
     );
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* EGLBoolean eglSwapInterval ( EGLDisplay dpy, EGLint interval ) */
@@ -973,7 +973,7 @@
         (EGLDisplay)dpy_native,
         (EGLint)interval
     );
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* EGLContext eglCreateContext ( EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list ) */
@@ -1052,7 +1052,7 @@
         (EGLDisplay)dpy_native,
         (EGLContext)ctx_native
     );
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* EGLBoolean eglMakeCurrent ( EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx ) */
@@ -1071,7 +1071,7 @@
         (EGLSurface)read_native,
         (EGLContext)ctx_native
     );
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* EGLContext eglGetCurrentContext ( void ) */
@@ -1155,7 +1155,7 @@
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
     }
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* EGLBoolean eglWaitGL ( void ) */
@@ -1164,7 +1164,7 @@
   (JNIEnv *_env, jobject _this) {
     EGLBoolean _returnValue = (EGLBoolean) 0;
     _returnValue = eglWaitGL();
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* EGLBoolean eglWaitNative ( EGLint engine ) */
@@ -1175,7 +1175,7 @@
     _returnValue = eglWaitNative(
         (EGLint)engine
     );
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* EGLBoolean eglSwapBuffers ( EGLDisplay dpy, EGLSurface surface ) */
@@ -1190,7 +1190,7 @@
         (EGLDisplay)dpy_native,
         (EGLSurface)surface_native
     );
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* EGLBoolean eglCopyBuffers ( EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target ) */
diff --git a/core/jni/android_opengl_GLES10.cpp b/core/jni/android_opengl_GLES10.cpp
index 336c0ec..cc34e99 100644
--- a/core/jni/android_opengl_GLES10.cpp
+++ b/core/jni/android_opengl_GLES10.cpp
@@ -63,6 +63,12 @@
     glVertexAttribPointer(indx, size, type, normalized, stride, pointer);
 }
 #endif
+#ifdef GL_ES_VERSION_3_0
+static void glVertexAttribIPointerBounds(GLuint indx, GLint size, GLenum type,
+        GLsizei stride, const GLvoid *pointer, GLsizei count) {
+    glVertexAttribIPointer(indx, size, type, stride, pointer);
+}
+#endif
 }
 
 /* Cache method IDs each time the class is loaded. */
@@ -288,6 +294,7 @@
     int _needed = 0;
 
     params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    _remaining /= sizeof(CTYPE);    // convert from bytes to item count
     _needed = getNeededCount(pname);
     // if we didn't find this pname, we just assume the user passed
     // an array of the right size -- this might happen with extensions
@@ -1184,7 +1191,7 @@
   (JNIEnv *_env, jobject _this) {
     GLenum _returnValue;
     _returnValue = glGetError();
-    return _returnValue;
+    return (jint)_returnValue;
 }
 
 /* void glGetIntegerv ( GLenum pname, GLint *params ) */
diff --git a/core/jni/android_opengl_GLES10Ext.cpp b/core/jni/android_opengl_GLES10Ext.cpp
index 59e63e1..9284384 100644
--- a/core/jni/android_opengl_GLES10Ext.cpp
+++ b/core/jni/android_opengl_GLES10Ext.cpp
@@ -63,6 +63,12 @@
     glVertexAttribPointer(indx, size, type, normalized, stride, pointer);
 }
 #endif
+#ifdef GL_ES_VERSION_3_0
+static void glVertexAttribIPointerBounds(GLuint indx, GLint size, GLenum type,
+        GLsizei stride, const GLvoid *pointer, GLsizei count) {
+    glVertexAttribIPointer(indx, size, type, stride, pointer);
+}
+#endif
 }
 
 /* Cache method IDs each time the class is loaded. */
@@ -288,6 +294,7 @@
     int _needed = 0;
 
     params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    _remaining /= sizeof(CTYPE);    // convert from bytes to item count
     _needed = getNeededCount(pname);
     // if we didn't find this pname, we just assume the user passed
     // an array of the right size -- this might happen with extensions
@@ -395,7 +402,7 @@
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
     }
-    return _returnValue;
+    return (jint)_returnValue;
 }
 
 /* GLbitfield glQueryMatrixxOES ( GLfixed *mantissa, GLint *exponent ) */
@@ -452,7 +459,7 @@
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
     }
-    return _returnValue;
+    return (jint)_returnValue;
 }
 
 static const char *classPathName = "android/opengl/GLES10Ext";
diff --git a/core/jni/android_opengl_GLES11.cpp b/core/jni/android_opengl_GLES11.cpp
index 352f5bf..871e84d 100644
--- a/core/jni/android_opengl_GLES11.cpp
+++ b/core/jni/android_opengl_GLES11.cpp
@@ -63,6 +63,12 @@
     glVertexAttribPointer(indx, size, type, normalized, stride, pointer);
 }
 #endif
+#ifdef GL_ES_VERSION_3_0
+static void glVertexAttribIPointerBounds(GLuint indx, GLint size, GLenum type,
+        GLsizei stride, const GLvoid *pointer, GLsizei count) {
+    glVertexAttribIPointer(indx, size, type, stride, pointer);
+}
+#endif
 }
 
 /* Cache method IDs each time the class is loaded. */
@@ -288,6 +294,7 @@
     int _needed = 0;
 
     params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    _remaining /= sizeof(CTYPE);    // convert from bytes to item count
     _needed = getNeededCount(pname);
     // if we didn't find this pname, we just assume the user passed
     // an array of the right size -- this might happen with extensions
@@ -571,7 +578,7 @@
         (GLint)size,
         (GLenum)type,
         (GLsizei)stride,
-        (const GLvoid *)offset
+        (GLvoid *)offset
     );
 }
 
@@ -672,7 +679,7 @@
         (GLenum)mode,
         (GLsizei)count,
         (GLenum)type,
-        (const GLvoid *)offset
+        (GLvoid *)offset
     );
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2263,7 +2270,7 @@
     _returnValue = glIsBuffer(
         (GLuint)buffer
     );
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* GLboolean glIsEnabled ( GLenum cap ) */
@@ -2274,7 +2281,7 @@
     _returnValue = glIsEnabled(
         (GLenum)cap
     );
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* GLboolean glIsTexture ( GLuint texture ) */
@@ -2285,7 +2292,7 @@
     _returnValue = glIsTexture(
         (GLuint)texture
     );
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* void glNormalPointer ( GLenum type, GLsizei stride, GLint offset ) */
@@ -2295,7 +2302,7 @@
     glNormalPointer(
         (GLenum)type,
         (GLsizei)stride,
-        (const GLvoid *)offset
+        (GLvoid *)offset
     );
 }
 
@@ -2522,7 +2529,7 @@
         (GLint)size,
         (GLenum)type,
         (GLsizei)stride,
-        (const GLvoid *)offset
+        (GLvoid *)offset
     );
 }
 
@@ -2930,7 +2937,7 @@
         (GLint)size,
         (GLenum)type,
         (GLsizei)stride,
-        (const GLvoid *)offset
+        (GLvoid *)offset
     );
 }
 
diff --git a/core/jni/android_opengl_GLES11Ext.cpp b/core/jni/android_opengl_GLES11Ext.cpp
index c91baa2..3e038ad 100644
--- a/core/jni/android_opengl_GLES11Ext.cpp
+++ b/core/jni/android_opengl_GLES11Ext.cpp
@@ -63,6 +63,12 @@
     glVertexAttribPointer(indx, size, type, normalized, stride, pointer);
 }
 #endif
+#ifdef GL_ES_VERSION_3_0
+static void glVertexAttribIPointerBounds(GLuint indx, GLint size, GLenum type,
+        GLsizei stride, const GLvoid *pointer, GLsizei count) {
+    glVertexAttribIPointer(indx, size, type, stride, pointer);
+}
+#endif
 }
 
 /* Cache method IDs each time the class is loaded. */
@@ -288,6 +294,7 @@
     int _needed = 0;
 
     params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    _remaining /= sizeof(CTYPE);    // convert from bytes to item count
     _needed = getNeededCount(pname);
     // if we didn't find this pname, we just assume the user passed
     // an array of the right size -- this might happen with extensions
@@ -2129,7 +2136,7 @@
     _returnValue = glIsRenderbufferOES(
         (GLuint)renderbuffer
     );
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* void glBindRenderbufferOES ( GLenum target, GLuint renderbuffer ) */
@@ -2422,7 +2429,7 @@
     _returnValue = glIsFramebufferOES(
         (GLuint)framebuffer
     );
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* void glBindFramebufferOES ( GLenum target, GLuint framebuffer ) */
@@ -2615,7 +2622,7 @@
     _returnValue = glCheckFramebufferStatusOES(
         (GLenum)target
     );
-    return _returnValue;
+    return (jint)_returnValue;
 }
 
 /* void glFramebufferRenderbufferOES ( GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer ) */
diff --git a/core/jni/android_opengl_GLES20.cpp b/core/jni/android_opengl_GLES20.cpp
index 4179785..9bc69ae 100644
--- a/core/jni/android_opengl_GLES20.cpp
+++ b/core/jni/android_opengl_GLES20.cpp
@@ -63,6 +63,12 @@
     glVertexAttribPointer(indx, size, type, normalized, stride, pointer);
 }
 #endif
+#ifdef GL_ES_VERSION_3_0
+static void glVertexAttribIPointerBounds(GLuint indx, GLint size, GLenum type,
+        GLsizei stride, const GLvoid *pointer, GLsizei count) {
+    glVertexAttribIPointer(indx, size, type, stride, pointer);
+}
+#endif
 }
 
 /* Cache method IDs each time the class is loaded. */
@@ -288,6 +294,7 @@
     int _needed = 0;
 
     params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    _remaining /= sizeof(CTYPE);    // convert from bytes to item count
     _needed = getNeededCount(pname);
     // if we didn't find this pname, we just assume the user passed
     // an array of the right size -- this might happen with extensions
@@ -549,7 +556,7 @@
     _returnValue = glCheckFramebufferStatus(
         (GLenum)target
     );
-    return _returnValue;
+    return (jint)_returnValue;
 }
 
 /* void glClear ( GLbitfield mask ) */
@@ -709,7 +716,7 @@
   (JNIEnv *_env, jobject _this) {
     GLuint _returnValue;
     _returnValue = glCreateProgram();
-    return _returnValue;
+    return (jint)_returnValue;
 }
 
 /* GLuint glCreateShader ( GLenum type ) */
@@ -720,7 +727,7 @@
     _returnValue = glCreateShader(
         (GLenum)type
     );
-    return _returnValue;
+    return (jint)_returnValue;
 }
 
 /* void glCullFace ( GLenum mode ) */
@@ -1172,7 +1179,7 @@
         (GLenum)mode,
         (GLsizei)count,
         (GLenum)type,
-        (const GLvoid *)offset
+        (GLvoid *)offset
     );
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2466,7 +2473,7 @@
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
     }
-    return _returnValue;
+    return (jint)_returnValue;
 }
 
 /* void glGetBooleanv ( GLenum pname, GLboolean *params ) */
@@ -2576,7 +2583,7 @@
   (JNIEnv *_env, jobject _this) {
     GLenum _returnValue;
     _returnValue = glGetError();
-    return _returnValue;
+    return (jint)_returnValue;
 }
 
 /* void glGetFloatv ( GLenum pname, GLfloat *params ) */
@@ -3614,7 +3621,7 @@
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
     }
-    return _returnValue;
+    return (jint)_returnValue;
 }
 
 /* void glGetVertexAttribfv ( GLuint index, GLenum pname, GLfloat *params ) */
@@ -3855,7 +3862,7 @@
     _returnValue = glIsBuffer(
         (GLuint)buffer
     );
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* GLboolean glIsEnabled ( GLenum cap ) */
@@ -3866,7 +3873,7 @@
     _returnValue = glIsEnabled(
         (GLenum)cap
     );
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* GLboolean glIsFramebuffer ( GLuint framebuffer ) */
@@ -3877,7 +3884,7 @@
     _returnValue = glIsFramebuffer(
         (GLuint)framebuffer
     );
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* GLboolean glIsProgram ( GLuint program ) */
@@ -3888,7 +3895,7 @@
     _returnValue = glIsProgram(
         (GLuint)program
     );
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* GLboolean glIsRenderbuffer ( GLuint renderbuffer ) */
@@ -3899,7 +3906,7 @@
     _returnValue = glIsRenderbuffer(
         (GLuint)renderbuffer
     );
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* GLboolean glIsShader ( GLuint shader ) */
@@ -3910,7 +3917,7 @@
     _returnValue = glIsShader(
         (GLuint)shader
     );
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* GLboolean glIsTexture ( GLuint texture ) */
@@ -3921,7 +3928,7 @@
     _returnValue = glIsTexture(
         (GLuint)texture
     );
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* void glLineWidth ( GLfloat width ) */
@@ -5975,7 +5982,7 @@
         (GLenum)type,
         (GLboolean)normalized,
         (GLsizei)stride,
-        (const GLvoid *)offset
+        (GLvoid *)offset
     );
 }
 
diff --git a/core/jni/android_opengl_GLES30.cpp b/core/jni/android_opengl_GLES30.cpp
index 3c50aa0..832d643 100644
--- a/core/jni/android_opengl_GLES30.cpp
+++ b/core/jni/android_opengl_GLES30.cpp
@@ -294,6 +294,7 @@
     int _needed = 0;
 
     params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+    _remaining /= sizeof(CTYPE);    // convert from bytes to item count
     _needed = getNeededCount(pname);
     // if we didn't find this pname, we just assume the user passed
     // an array of the right size -- this might happen with extensions
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index 2883c10..60540f4 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -21,6 +21,7 @@
 #include "utils/misc.h"
 #include "cutils/debugger.h"
 
+#include <cutils/log.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -43,6 +44,7 @@
     HEAP_UNKNOWN,
     HEAP_DALVIK,
     HEAP_NATIVE,
+    HEAP_DALVIK_OTHER,
     HEAP_STACK,
     HEAP_CURSOR,
     HEAP_ASHMEM,
@@ -52,38 +54,57 @@
     HEAP_APK,
     HEAP_TTF,
     HEAP_DEX,
+    HEAP_OAT,
+    HEAP_ART,
     HEAP_UNKNOWN_MAP,
+    HEAP_GPU,
+
+    HEAP_DALVIK_NORMAL,
+    HEAP_DALVIK_LARGE,
+    HEAP_DALVIK_LINEARALLOC,
+    HEAP_DALVIK_ACCOUNTING,
+    HEAP_DALVIK_CODE_CACHE,
 
     _NUM_HEAP,
+    _NUM_EXCLUSIVE_HEAP = HEAP_GPU+1,
     _NUM_CORE_HEAP = HEAP_NATIVE+1
 };
 
 struct stat_fields {
     jfieldID pss_field;
+    jfieldID pssSwappable_field;
     jfieldID privateDirty_field;
     jfieldID sharedDirty_field;
+    jfieldID privateClean_field;
+    jfieldID sharedClean_field;
 };
 
 struct stat_field_names {
     const char* pss_name;
+    const char* pssSwappable_name;
     const char* privateDirty_name;
     const char* sharedDirty_name;
+    const char* privateClean_name;
+    const char* sharedClean_name;
 };
 
 static stat_fields stat_fields[_NUM_CORE_HEAP];
 
 static stat_field_names stat_field_names[_NUM_CORE_HEAP] = {
-    { "otherPss", "otherPrivateDirty", "otherSharedDirty" },
-    { "dalvikPss", "dalvikPrivateDirty", "dalvikSharedDirty" },
-    { "nativePss", "nativePrivateDirty", "nativeSharedDirty" }
+    { "otherPss", "otherSwappablePss", "otherPrivateDirty", "otherSharedDirty", "otherPrivateClean", "otherSharedClean" },
+    { "dalvikPss", "dalvikSwappablePss", "dalvikPrivateDirty", "dalvikSharedDirty", "dalvikPrivateClean", "dalvikSharedClean" },
+    { "nativePss", "nativeSwappablePss", "nativePrivateDirty", "nativeSharedDirty", "nativePrivateClean", "nativeSharedClean" }
 };
 
 jfieldID otherStats_field;
 
 struct stats_t {
     int pss;
+    int swappablePss;
     int privateDirty;
     int sharedDirty;
+    int privateClean;
+    int sharedClean;
 };
 
 #define BINDER_STATS "/proc/binder/stats"
@@ -118,15 +139,83 @@
 #endif
 }
 
+// XXX Qualcom-specific!
+static jlong read_gpu_mem(int pid)
+{
+    char line[1024];
+    jlong uss = 0;
+    unsigned temp;
+
+    char tmp[128];
+    FILE *fp;
+
+    sprintf(tmp, "/d/kgsl/proc/%d/mem", pid);
+    fp = fopen(tmp, "r");
+    if (fp == 0) {
+        //ALOGI("Unable to open: %s", tmp);
+        return 0;
+    }
+
+    while (true) {
+        if (fgets(line, 1024, fp) == NULL) {
+            break;
+        }
+
+        //ALOGI("Read: %s", line);
+
+        // Format is:
+        //  gpuaddr useraddr     size    id flags       type            usage sglen
+        // 54676000 54676000     4096     1 ----p     gpumem      arraybuffer     1
+        //
+        // If useraddr is 0, this is gpu mem not otherwise accounted
+        // against the process.
+
+        // Make sure line is long enough.
+        int i = 0;
+        while (i < 9) {
+            if (line[i] == 0) {
+                break;
+            }
+            i++;
+        }
+        if (i < 9) {
+            //ALOGI("Early line term!");
+            continue;
+        }
+
+        // Look to see if useraddr is 00000000.
+        while (i < 17) {
+            if (line[i] != '0') {
+                break;
+            }
+            i++;
+        }
+        if (i < 17) {
+            //ALOGI("useraddr not 0!");
+            continue;
+        }
+
+        uss += atoi(line + i);
+        //ALOGI("Uss now: %ld", uss);
+    }
+
+    fclose(fp);
+
+    // Convert from bytes to KB.
+    return uss / 1024;
+}
+
 static void read_mapinfo(FILE *fp, stats_t* stats)
 {
     char line[1024];
     int len, nameLen;
     bool skip, done = false;
 
-    unsigned size = 0, resident = 0, pss = 0;
+    unsigned size = 0, resident = 0, pss = 0, swappable_pss = 0;
+    float sharing_proportion = 0.0;
     unsigned shared_clean = 0, shared_dirty = 0;
     unsigned private_clean = 0, private_dirty = 0;
+    bool is_swappable = false;
     unsigned referenced = 0;
     unsigned temp;
 
@@ -137,6 +226,7 @@
     int name_pos;
 
     int whichHeap = HEAP_UNKNOWN;
+    int subHeap = HEAP_UNKNOWN;
     int prevHeap = HEAP_UNKNOWN;
 
     if(fgets(line, sizeof(line), fp) == 0) return;
@@ -145,7 +235,9 @@
         prevHeap = whichHeap;
         prevEnd = end;
         whichHeap = HEAP_UNKNOWN;
+        subHeap = HEAP_UNKNOWN;
         skip = false;
+        is_swappable = false;
 
         len = strlen(line);
         if (len < 1) return;
@@ -160,30 +252,72 @@
             name = line + name_pos;
             nameLen = strlen(name);
 
-            if ((strstr(name, "[heap]") == name) ||
-                (strstr(name, "/dev/ashmem/libc malloc") == name)) {
+            if ((strstr(name, "[heap]") == name)) {
                 whichHeap = HEAP_NATIVE;
-            } else if (strstr(name, "/dev/ashmem/dalvik-") == name) {
-                whichHeap = HEAP_DALVIK;
-            } else if (strstr(name, "[stack") == name) {
+            } else if (strncmp(name, "/dev/ashmem", 11) == 0) {
+                if (strncmp(name, "/dev/ashmem/dalvik-", 19) == 0) {
+                    whichHeap = HEAP_DALVIK_OTHER;
+                    if (strstr(name, "/dev/ashmem/dalvik-LinearAlloc") == name) {
+                        subHeap = HEAP_DALVIK_LINEARALLOC;
+                    } else if ((strstr(name, "/dev/ashmem/dalvik-mark") == name) ||
+                               (strstr(name, "/dev/ashmem/dalvik-allocspace alloc space live-bitmap") == name) ||
+                               (strstr(name, "/dev/ashmem/dalvik-allocspace alloc space mark-bitmap") == name) ||
+                               (strstr(name, "/dev/ashmem/dalvik-card table") == name) ||
+                               (strstr(name, "/dev/ashmem/dalvik-allocation stack") == name) ||
+                               (strstr(name, "/dev/ashmem/dalvik-live stack") == name) ||
+                               (strstr(name, "/dev/ashmem/dalvik-imagespace") == name) ||
+                               (strstr(name, "/dev/ashmem/dalvik-bitmap") == name) ||
+                               (strstr(name, "/dev/ashmem/dalvik-card-table") == name) ||
+                               (strstr(name, "/dev/ashmem/dalvik-mark-stack") == name) ||
+                               (strstr(name, "/dev/ashmem/dalvik-aux-structure") == name)) {
+                        subHeap = HEAP_DALVIK_ACCOUNTING;
+                    } else if (strstr(name, "/dev/ashmem/dalvik-large") == name) {
+                        whichHeap = HEAP_DALVIK;
+                        subHeap = HEAP_DALVIK_LARGE;
+                    } else if (strstr(name, "/dev/ashmem/dalvik-jit-code-cache") == name) {
+                        subHeap = HEAP_DALVIK_CODE_CACHE;
+                    } else {
+                        // This is the regular Dalvik heap.
+                        whichHeap = HEAP_DALVIK;
+                        subHeap = HEAP_DALVIK_NORMAL;
+                    }
+                } else if (strncmp(name, "/dev/ashmem/CursorWindow", 24) == 0) {
+                    whichHeap = HEAP_CURSOR;
+                } else if (strncmp(name, "/dev/ashmem/libc malloc", 23) == 0) {
+                    whichHeap = HEAP_NATIVE;
+                } else {
+                    whichHeap = HEAP_ASHMEM;
+                }
+            } else if (strncmp(name, "[anon:libc_malloc]", 18) == 0) {
+                whichHeap = HEAP_NATIVE;
+            } else if (strncmp(name, "[stack", 6) == 0) {
                 whichHeap = HEAP_STACK;
-            } else if (strstr(name, "/dev/ashmem/CursorWindow") == name) {
-                whichHeap = HEAP_CURSOR;
-            } else if (strstr(name, "/dev/ashmem/") == name) {
-                whichHeap = HEAP_ASHMEM;
-            } else if (strstr(name, "/dev/") == name) {
+            } else if (strncmp(name, "/dev/", 5) == 0) {
                 whichHeap = HEAP_UNKNOWN_DEV;
             } else if (nameLen > 3 && strcmp(name+nameLen-3, ".so") == 0) {
                 whichHeap = HEAP_SO;
+                is_swappable = true;
             } else if (nameLen > 4 && strcmp(name+nameLen-4, ".jar") == 0) {
                 whichHeap = HEAP_JAR;
+                is_swappable = true;
             } else if (nameLen > 4 && strcmp(name+nameLen-4, ".apk") == 0) {
                 whichHeap = HEAP_APK;
+                is_swappable = true;
             } else if (nameLen > 4 && strcmp(name+nameLen-4, ".ttf") == 0) {
                 whichHeap = HEAP_TTF;
+                is_swappable = true;
             } else if ((nameLen > 4 && strcmp(name+nameLen-4, ".dex") == 0) ||
                        (nameLen > 5 && strcmp(name+nameLen-5, ".odex") == 0)) {
                 whichHeap = HEAP_DEX;
+                is_swappable = true;
+            } else if (nameLen > 4 && strcmp(name+nameLen-4, ".oat") == 0) {
+                whichHeap = HEAP_OAT;
+                is_swappable = true;
+            } else if (nameLen > 4 && strcmp(name+nameLen-4, ".art") == 0) {
+                whichHeap = HEAP_ART;
+                is_swappable = true;
+            } else if (strncmp(name, "[anon:", 6) == 0) {
+                whichHeap = HEAP_UNKNOWN;
             } else if (nameLen > 0) {
                 whichHeap = HEAP_UNKNOWN_MAP;
             } else if (start == prevEnd && prevHeap == HEAP_SO) {
@@ -225,9 +359,29 @@
         }
 
         if (!skip) {
+            if (is_swappable && (pss > 0)) {
+                sharing_proportion = 0.0;
+                if ((shared_clean > 0) || (shared_dirty > 0)) {
+                    sharing_proportion = (pss - private_clean - private_dirty)/(shared_clean+shared_dirty);
+                }
+                swappable_pss = (sharing_proportion*shared_clean) + private_clean;
+            } else
+                swappable_pss = 0;
+
             stats[whichHeap].pss += pss;
+            stats[whichHeap].swappablePss += swappable_pss;
             stats[whichHeap].privateDirty += private_dirty;
             stats[whichHeap].sharedDirty += shared_dirty;
+            stats[whichHeap].privateClean += private_clean;
+            stats[whichHeap].sharedClean += shared_clean;
+            if (whichHeap == HEAP_DALVIK || whichHeap == HEAP_DALVIK_OTHER) {
+                stats[subHeap].pss += pss;
+                stats[subHeap].swappablePss += swappable_pss;
+                stats[subHeap].privateDirty += private_dirty;
+                stats[subHeap].sharedDirty += shared_dirty;
+                stats[subHeap].privateClean += private_clean;
+                stats[subHeap].sharedClean += shared_clean;
+            }
         }
     }
 }
@@ -251,20 +405,32 @@
     stats_t stats[_NUM_HEAP];
     memset(&stats, 0, sizeof(stats));
 
+
     load_maps(pid, stats);
 
-    for (int i=_NUM_CORE_HEAP; i<_NUM_HEAP; i++) {
+    jlong gpu = read_gpu_mem(pid);
+    stats[HEAP_GPU].pss += gpu;
+    stats[HEAP_GPU].privateDirty += gpu;
+
+    for (int i=_NUM_CORE_HEAP; i<_NUM_EXCLUSIVE_HEAP; i++) {
         stats[HEAP_UNKNOWN].pss += stats[i].pss;
+        stats[HEAP_UNKNOWN].swappablePss += stats[i].swappablePss;
         stats[HEAP_UNKNOWN].privateDirty += stats[i].privateDirty;
         stats[HEAP_UNKNOWN].sharedDirty += stats[i].sharedDirty;
+        stats[HEAP_UNKNOWN].privateClean += stats[i].privateClean;
+        stats[HEAP_UNKNOWN].sharedClean += stats[i].sharedClean;
     }
 
     for (int i=0; i<_NUM_CORE_HEAP; i++) {
         env->SetIntField(object, stat_fields[i].pss_field, stats[i].pss);
+        env->SetIntField(object, stat_fields[i].pssSwappable_field, stats[i].swappablePss);
         env->SetIntField(object, stat_fields[i].privateDirty_field, stats[i].privateDirty);
         env->SetIntField(object, stat_fields[i].sharedDirty_field, stats[i].sharedDirty);
+        env->SetIntField(object, stat_fields[i].privateClean_field, stats[i].privateClean);
+        env->SetIntField(object, stat_fields[i].sharedClean_field, stats[i].sharedClean);
     }
 
+
     jintArray otherIntArray = (jintArray)env->GetObjectField(object, otherStats_field);
 
     jint* otherArray = (jint*)env->GetPrimitiveArrayCritical(otherIntArray, 0);
@@ -275,8 +441,11 @@
     int j=0;
     for (int i=_NUM_CORE_HEAP; i<_NUM_HEAP; i++) {
         otherArray[j++] = stats[i].pss;
+        otherArray[j++] = stats[i].swappablePss;
         otherArray[j++] = stats[i].privateDirty;
         otherArray[j++] = stats[i].sharedDirty;
+        otherArray[j++] = stats[i].privateClean;
+        otherArray[j++] = stats[i].sharedClean;
     }
 
     env->ReleasePrimitiveArrayCritical(otherIntArray, otherArray, 0);
@@ -287,37 +456,145 @@
     android_os_Debug_getDirtyPagesPid(env, clazz, getpid(), object);
 }
 
-static jlong android_os_Debug_getPssPid(JNIEnv *env, jobject clazz, jint pid)
+static jlong android_os_Debug_getPssPid(JNIEnv *env, jobject clazz, jint pid, jlongArray outUss)
 {
     char line[1024];
     jlong pss = 0;
+    jlong uss = 0;
     unsigned temp;
 
     char tmp[128];
     FILE *fp;
 
+    pss = uss = read_gpu_mem(pid);
+
     sprintf(tmp, "/proc/%d/smaps", pid);
     fp = fopen(tmp, "r");
-    if (fp == 0) return 0;
 
-    while (true) {
-        if (fgets(line, 1024, fp) == 0) {
-            break;
+    if (fp != 0) {
+        while (true) {
+            if (fgets(line, 1024, fp) == NULL) {
+                break;
+            }
+
+            if (line[0] == 'P') {
+                if (strncmp(line, "Pss:", 4) == 0) {
+                    char* c = line + 4;
+                    while (*c != 0 && (*c < '0' || *c > '9')) {
+                        c++;
+                    }
+                    pss += atoi(c);
+                } else if (strncmp(line, "Private_Clean:", 14)
+                        || strncmp(line, "Private_Dirty:", 14)) {
+                    char* c = line + 14;
+                    while (*c != 0 && (*c < '0' || *c > '9')) {
+                        c++;
+                    }
+                    uss += atoi(c);
+                }
+            }
         }
 
-        if (sscanf(line, "Pss: %d kB", &temp) == 1) {
-            pss += temp;
-        }
+        fclose(fp);
     }
 
-    fclose(fp);
+    if (outUss != NULL) {
+        if (env->GetArrayLength(outUss) >= 1) {
+            jlong* outUssArray = env->GetLongArrayElements(outUss, 0);
+            if (outUssArray != NULL) {
+                outUssArray[0] = uss;
+            }
+            env->ReleaseLongArrayElements(outUss, outUssArray, 0);
+        }
+    }
 
     return pss;
 }
 
 static jlong android_os_Debug_getPss(JNIEnv *env, jobject clazz)
 {
-    return android_os_Debug_getPssPid(env, clazz, getpid());
+    return android_os_Debug_getPssPid(env, clazz, getpid(), NULL);
+}
+
+static void android_os_Debug_getMemInfo(JNIEnv *env, jobject clazz, jlongArray out)
+{
+    char buffer[1024];
+    int numFound = 0;
+
+    if (out == NULL) {
+        jniThrowNullPointerException(env, "out == null");
+        return;
+    }
+
+    int fd = open("/proc/meminfo", O_RDONLY);
+
+    if (fd < 0) {
+        printf("Unable to open /proc/meminfo: %s\n", strerror(errno));
+        return;
+    }
+
+    const int len = read(fd, buffer, sizeof(buffer)-1);
+    close(fd);
+
+    if (len < 0) {
+        printf("Empty /proc/meminfo");
+        return;
+    }
+    buffer[len] = 0;
+
+    static const char* const tags[] = {
+            "MemTotal:",
+            "MemFree:",
+            "Buffers:",
+            "Cached:",
+            "Shmem:",
+            "Slab:",
+            NULL
+    };
+    static const int tagsLen[] = {
+            9,
+            8,
+            8,
+            7,
+            6,
+            5,
+            0
+    };
+    long mem[] = { 0, 0, 0, 0, 0, 0 };
+
+    char* p = buffer;
+    while (*p && numFound < 6) {
+        int i = 0;
+        while (tags[i]) {
+            if (strncmp(p, tags[i], tagsLen[i]) == 0) {
+                p += tagsLen[i];
+                while (*p == ' ') p++;
+                char* num = p;
+                while (*p >= '0' && *p <= '9') p++;
+                if (*p != 0) {
+                    *p = 0;
+                    p++;
+                }
+                mem[i] = atoll(num);
+                numFound++;
+                break;
+            }
+            i++;
+        }
+        while (*p && *p != '\n') {
+            p++;
+        }
+        if (*p) p++;
+    }
+
+    int maxNum = env->GetArrayLength(out);
+    jlong* outArray = env->GetLongArrayElements(out, 0);
+    if (outArray != NULL) {
+        for (int i=0; i<maxNum && tags[i]; i++) {
+            outArray[i] = mem[i];
+        }
+    }
+    env->ReleaseLongArrayElements(out, outArray, 0);
 }
 
 static jint read_binder_stat(const char* stat)
@@ -592,8 +869,10 @@
             (void*) android_os_Debug_getDirtyPagesPid },
     { "getPss",                 "()J",
             (void*) android_os_Debug_getPss },
-    { "getPss",                 "(I)J",
+    { "getPss",                 "(I[J)J",
             (void*) android_os_Debug_getPssPid },
+    { "getMemInfo",             "([J)V",
+            (void*) android_os_Debug_getMemInfo },
     { "dumpNativeHeap",         "(Ljava/io/FileDescriptor;)V",
             (void*) android_os_Debug_dumpNativeHeap },
     { "getBinderSentTransactions", "()I",
@@ -617,11 +896,13 @@
     // Sanity check the number of other statistics expected in Java matches here.
     jfieldID numOtherStats_field = env->GetStaticFieldID(clazz, "NUM_OTHER_STATS", "I");
     jint numOtherStats = env->GetStaticIntField(clazz, numOtherStats_field);
+    jfieldID numDvkStats_field = env->GetStaticFieldID(clazz, "NUM_DVK_STATS", "I");
+    jint numDvkStats = env->GetStaticIntField(clazz, numDvkStats_field);
     int expectedNumOtherStats = _NUM_HEAP - _NUM_CORE_HEAP;
-    if (numOtherStats != expectedNumOtherStats) {
+    if ((numOtherStats + numDvkStats) != expectedNumOtherStats) {
         jniThrowExceptionFmt(env, "java/lang/RuntimeException",
-                             "android.os.Debug.Meminfo.NUM_OTHER_STATS=%d expected %d",
-                             numOtherStats, expectedNumOtherStats);
+                             "android.os.Debug.Meminfo.NUM_OTHER_STATS+android.os.Debug.Meminfo.NUM_DVK_STATS=%d expected %d",
+                             numOtherStats+numDvkStats, expectedNumOtherStats);
         return JNI_ERR;
     }
 
@@ -630,10 +911,16 @@
     for (int i=0; i<_NUM_CORE_HEAP; i++) {
         stat_fields[i].pss_field =
                 env->GetFieldID(clazz, stat_field_names[i].pss_name, "I");
+        stat_fields[i].pssSwappable_field =
+                env->GetFieldID(clazz, stat_field_names[i].pssSwappable_name, "I");
         stat_fields[i].privateDirty_field =
                 env->GetFieldID(clazz, stat_field_names[i].privateDirty_name, "I");
         stat_fields[i].sharedDirty_field =
                 env->GetFieldID(clazz, stat_field_names[i].sharedDirty_name, "I");
+        stat_fields[i].privateClean_field =
+                env->GetFieldID(clazz, stat_field_names[i].privateClean_name, "I");
+        stat_fields[i].sharedClean_field =
+                env->GetFieldID(clazz, stat_field_names[i].sharedClean_name, "I");
     }
 
     return jniRegisterNativeMethods(env, "android/os/Debug", gMethods, NELEM(gMethods));
diff --git a/core/jni/android_os_FileUtils.cpp b/core/jni/android_os_FileUtils.cpp
index a07f5b7..d1245da 100644
--- a/core/jni/android_os_FileUtils.cpp
+++ b/core/jni/android_os_FileUtils.cpp
@@ -33,28 +33,6 @@
 
 namespace android {
 
-jint android_os_FileUtils_setPermissions(JNIEnv* env, jobject clazz,
-                                         jstring file, jint mode,
-                                         jint uid, jint gid)
-{
-    const jchar* str = env->GetStringCritical(file, 0);
-    String8 file8;
-    if (str) {
-        file8 = String8(str, env->GetStringLength(file));
-        env->ReleaseStringCritical(file, str);
-    }
-    if (file8.size() <= 0) {
-        return ENOENT;
-    }
-    if (uid >= 0 || gid >= 0) {
-        int res = chown(file8.string(), uid, gid);
-        if (res != 0) {
-            return errno;
-        }
-    }
-    return chmod(file8.string(), mode) == 0 ? 0 : errno;
-}
-
 jint android_os_FileUtils_getFatVolumeId(JNIEnv* env, jobject clazz, jstring path)
 {
     if (path == NULL) {
@@ -77,7 +55,6 @@
 }
 
 static const JNINativeMethod methods[] = {
-    {"setPermissions",  "(Ljava/lang/String;III)I", (void*)android_os_FileUtils_setPermissions},
     {"getFatVolumeId",  "(Ljava/lang/String;)I", (void*)android_os_FileUtils_getFatVolumeId},
 };
 
diff --git a/core/jni/android_os_MessageQueue.cpp b/core/jni/android_os_MessageQueue.cpp
index 7540645..c9c3720 100644
--- a/core/jni/android_os_MessageQueue.cpp
+++ b/core/jni/android_os_MessageQueue.cpp
@@ -141,6 +141,11 @@
     return nativeMessageQueue->wake();
 }
 
+static jboolean android_os_MessageQueue_nativeIsIdling(JNIEnv* env, jclass clazz, jint ptr) {
+    NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
+    return nativeMessageQueue->getLooper()->isIdling();
+}
+
 // ----------------------------------------------------------------------------
 
 static JNINativeMethod gMessageQueueMethods[] = {
@@ -148,7 +153,8 @@
     { "nativeInit", "()I", (void*)android_os_MessageQueue_nativeInit },
     { "nativeDestroy", "(I)V", (void*)android_os_MessageQueue_nativeDestroy },
     { "nativePollOnce", "(II)V", (void*)android_os_MessageQueue_nativePollOnce },
-    { "nativeWake", "(I)V", (void*)android_os_MessageQueue_nativeWake }
+    { "nativeWake", "(I)V", (void*)android_os_MessageQueue_nativeWake },
+    { "nativeIsIdling", "(I)Z", (void*)android_os_MessageQueue_nativeIsIdling }
 };
 
 #define FIND_CLASS(var, className) \
diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp
index 858ec79..aa451e3 100644
--- a/core/jni/android_os_Parcel.cpp
+++ b/core/jni/android_os_Parcel.cpp
@@ -35,7 +35,6 @@
 #include <utils/SystemClock.h>
 #include <utils/List.h>
 #include <utils/KeyedVector.h>
-#include <cutils/logger.h>
 #include <binder/Parcel.h>
 #include <binder/ProcessState.h>
 #include <binder/IServiceManager.h>
diff --git a/core/jni/android_os_ParcelFileDescriptor.cpp b/core/jni/android_os_ParcelFileDescriptor.cpp
deleted file mode 100644
index 99a2d04..0000000
--- a/core/jni/android_os_ParcelFileDescriptor.cpp
+++ /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.
- */
-
-//#define LOG_NDEBUG 0
-
-#include "JNIHelp.h"
-
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <stdio.h>
-
-#include <utils/Log.h>
-
-#include <android_runtime/AndroidRuntime.h>
-
-namespace android
-{
-
-static struct parcel_file_descriptor_offsets_t
-{
-    jfieldID mFileDescriptor;
-} gParcelFileDescriptorOffsets;
-
-static jobject android_os_ParcelFileDescriptor_getFileDescriptorFromFd(JNIEnv* env,
-    jobject clazz, jint origfd)
-{
-    int fd = dup(origfd);
-    if (fd < 0) {
-        jniThrowException(env, "java/io/IOException", strerror(errno));
-        return NULL;
-    }
-    return jniCreateFileDescriptor(env, fd);
-}
-
-static jobject android_os_ParcelFileDescriptor_getFileDescriptorFromFdNoDup(JNIEnv* env,
-    jobject clazz, jint fd)
-{
-    return jniCreateFileDescriptor(env, fd);
-}
-
-static void android_os_ParcelFileDescriptor_createPipeNative(JNIEnv* env,
-    jobject clazz, jobjectArray outFds)
-{
-    int fds[2];
-    if (pipe(fds) < 0) {
-        int therr = errno;
-        jniThrowException(env, "java/io/IOException", strerror(therr));
-        return;
-    }
-
-    for (int i=0; i<2; i++) {
-        jobject fdObj = jniCreateFileDescriptor(env, fds[i]);
-        env->SetObjectArrayElement(outFds, i, fdObj);
-    }
-}
-
-static jint getFd(JNIEnv* env, jobject clazz)
-{
-    jobject descriptor = env->GetObjectField(clazz, gParcelFileDescriptorOffsets.mFileDescriptor);
-    if (descriptor == NULL) return -1;
-    return jniGetFDFromFileDescriptor(env, descriptor);
-}
-
-static jlong android_os_ParcelFileDescriptor_getStatSize(JNIEnv* env,
-    jobject clazz)
-{
-    jint fd = getFd(env, clazz);
-    if (fd < 0) {
-        jniThrowException(env, "java/lang/IllegalArgumentException", "bad file descriptor");
-        return -1;
-    }
-
-    struct stat st;
-    if (fstat(fd, &st) != 0) {
-        return -1;
-    }
-
-    if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
-        return st.st_size;
-    }
-
-    return -1;
-}
-
-static jlong android_os_ParcelFileDescriptor_seekTo(JNIEnv* env,
-    jobject clazz, jlong pos)
-{
-    jint fd = getFd(env, clazz);
-    if (fd < 0) {
-        jniThrowException(env, "java/lang/IllegalArgumentException", "bad file descriptor");
-        return -1;
-    }
-
-    return lseek(fd, pos, SEEK_SET);
-}
-
-static jlong android_os_ParcelFileDescriptor_getFdNative(JNIEnv* env, jobject clazz)
-{
-    jint fd = getFd(env, clazz);
-    if (fd < 0) {
-        jniThrowException(env, "java/lang/IllegalArgumentException", "bad file descriptor");
-        return -1;
-    }
-
-    return fd;
-}
-
-static const JNINativeMethod gParcelFileDescriptorMethods[] = {
-    {"getFileDescriptorFromFd", "(I)Ljava/io/FileDescriptor;",
-        (void*)android_os_ParcelFileDescriptor_getFileDescriptorFromFd},
-    {"getFileDescriptorFromFdNoDup", "(I)Ljava/io/FileDescriptor;",
-        (void*)android_os_ParcelFileDescriptor_getFileDescriptorFromFdNoDup},
-    {"createPipeNative", "([Ljava/io/FileDescriptor;)V",
-        (void*)android_os_ParcelFileDescriptor_createPipeNative},
-    {"getStatSize", "()J",
-        (void*)android_os_ParcelFileDescriptor_getStatSize},
-    {"seekTo", "(J)J",
-        (void*)android_os_ParcelFileDescriptor_seekTo},
-    {"getFdNative", "()I",
-        (void*)android_os_ParcelFileDescriptor_getFdNative}
-};
-
-const char* const kParcelFileDescriptorPathName = "android/os/ParcelFileDescriptor";
-
-int register_android_os_ParcelFileDescriptor(JNIEnv* env)
-{
-    jclass clazz = env->FindClass(kParcelFileDescriptorPathName);
-    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.ParcelFileDescriptor");
-    gParcelFileDescriptorOffsets.mFileDescriptor = env->GetFieldID(clazz, "mFileDescriptor", "Ljava/io/FileDescriptor;");
-    LOG_FATAL_IF(gParcelFileDescriptorOffsets.mFileDescriptor == NULL,
-                 "Unable to find mFileDescriptor field in android.os.ParcelFileDescriptor");
-
-    return AndroidRuntime::registerNativeMethods(
-        env, kParcelFileDescriptorPathName,
-        gParcelFileDescriptorMethods, NELEM(gParcelFileDescriptorMethods));
-}
-
-}
diff --git a/core/jni/android_os_SystemClock.cpp b/core/jni/android_os_SystemClock.cpp
index 5c135ee..d20b800 100644
--- a/core/jni/android_os_SystemClock.cpp
+++ b/core/jni/android_os_SystemClock.cpp
@@ -19,18 +19,67 @@
  * System clock functions.
  */
 
+#ifdef HAVE_ANDROID_OS
+#include <linux/ioctl.h>
+#include <linux/rtc.h>
+#include <utils/Atomic.h>
+#include <linux/android_alarm.h>
+#endif
+
+#include <sys/time.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+
 #include "JNIHelp.h"
 #include "jni.h"
 #include "android_runtime/AndroidRuntime.h"
 
-#include "utils/SystemClock.h"
-
 #include <sys/time.h>
 #include <time.h>
 
+#include <utils/SystemClock.h>
+
 namespace android {
 
 /*
+ * Set the current time.  This only works when running as root.
+ */
+static int setCurrentTimeMillis(int64_t millis)
+{
+    struct timeval tv;
+    struct timespec ts;
+    int fd;
+    int res;
+    int ret = 0;
+
+    if (millis <= 0 || millis / 1000LL >= INT_MAX) {
+        return -1;
+    }
+
+    tv.tv_sec = (time_t) (millis / 1000LL);
+    tv.tv_usec = (suseconds_t) ((millis % 1000LL) * 1000LL);
+
+    ALOGD("Setting time of day to sec=%d\n", (int) tv.tv_sec);
+
+    fd = open("/dev/alarm", O_RDWR);
+    if(fd < 0) {
+        ALOGW("Unable to open alarm driver: %s\n", strerror(errno));
+        return -1;
+    }
+    ts.tv_sec = tv.tv_sec;
+    ts.tv_nsec = tv.tv_usec * 1000;
+    res = ioctl(fd, ANDROID_ALARM_SET_RTC, &ts);
+    if(res < 0) {
+        ALOGW("Unable to set rtc to %ld: %s\n", tv.tv_sec, strerror(errno));
+        ret = -1;
+    }
+    close(fd);
+    return ret;
+}
+
+/*
  * native public static void setCurrentTimeMillis(long millis)
  *
  * Set the current time.  This only works when running as root.
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index 32f6ecf..2c23f9d 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -586,7 +586,7 @@
     }
 
     ResTable::resource_name name;
-    if (!am->getResources().getResourceName(resid, &name)) {
+    if (!am->getResources().getResourceName(resid, true, &name)) {
         return NULL;
     }
 
@@ -594,19 +594,27 @@
     if (name.package != NULL) {
         str.setTo(name.package, name.packageLen);
     }
-    if (name.type != NULL) {
+    if (name.type8 != NULL || name.type != NULL) {
         if (str.size() > 0) {
             char16_t div = ':';
             str.append(&div, 1);
         }
-        str.append(name.type, name.typeLen);
+        if (name.type8 != NULL) {
+            str.append(String16(name.type8, name.typeLen));
+        } else {
+            str.append(name.type, name.typeLen);
+        }
     }
-    if (name.name != NULL) {
+    if (name.name8 != NULL || name.name != NULL) {
         if (str.size() > 0) {
             char16_t div = '/';
             str.append(&div, 1);
         }
-        str.append(name.name, name.nameLen);
+        if (name.name8 != NULL) {
+            str.append(String16(name.name8, name.nameLen));
+        } else {
+            str.append(name.name, name.nameLen);
+        }
     }
 
     return env->NewString((const jchar*)str.string(), str.size());
@@ -621,7 +629,7 @@
     }
 
     ResTable::resource_name name;
-    if (!am->getResources().getResourceName(resid, &name)) {
+    if (!am->getResources().getResourceName(resid, true, &name)) {
         return NULL;
     }
 
@@ -641,10 +649,14 @@
     }
 
     ResTable::resource_name name;
-    if (!am->getResources().getResourceName(resid, &name)) {
+    if (!am->getResources().getResourceName(resid, true, &name)) {
         return NULL;
     }
 
+    if (name.type8 != NULL) {
+        return env->NewStringUTF(name.type8);
+    }
+
     if (name.type != NULL) {
         return env->NewString((const jchar*)name.type, name.typeLen);
     }
@@ -661,10 +673,14 @@
     }
 
     ResTable::resource_name name;
-    if (!am->getResources().getResourceName(resid, &name)) {
+    if (!am->getResources().getResourceName(resid, true, &name)) {
         return NULL;
     }
 
+    if (name.name8 != NULL) {
+        return env->NewStringUTF(name.name8);
+    }
+
     if (name.name != NULL) {
         return env->NewString((const jchar*)name.name, name.nameLen);
     }
@@ -680,7 +696,7 @@
 {
     if (outValue == NULL) {
          jniThrowNullPointerException(env, "outValue");
-         return NULL;
+         return 0;
     }
     AssetManager* am = assetManagerForJavaObject(env, clazz);
     if (am == NULL) {
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 8766cf9..3ac2225 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -35,7 +35,7 @@
 #include <utils/SystemClock.h>
 #include <utils/List.h>
 #include <utils/KeyedVector.h>
-#include <cutils/logger.h>
+#include <log/logger.h>
 #include <binder/Parcel.h>
 #include <binder/ProcessState.h>
 #include <binder/IServiceManager.h>
@@ -986,6 +986,7 @@
 }
 
 // From frameworks/base/core/java/android/content/EventLogTags.logtags:
+#define ENABLE_BINDER_SAMPLE 0
 #define LOGTAG_BINDER_OPERATION 52004
 
 static void conditionally_log_binder_call(int64_t start_millis,
@@ -1063,6 +1064,7 @@
     ALOGV("Java code calling transact on %p in Java object %p with code %d\n",
             target, obj, code);
 
+#if ENABLE_BINDER_SAMPLE
     // Only log the binder call duration for things on the Java-level main thread.
     // But if we don't
     const bool time_binder_calls = should_time_binder_calls();
@@ -1071,12 +1073,15 @@
     if (time_binder_calls) {
         start_millis = uptimeMillis();
     }
+#endif
     //printf("Transact from Java code to %p sending: ", target); data->print();
     status_t err = target->transact(code, *data, reply, flags);
     //if (reply) printf("Transact from Java code to %p received: ", target); reply->print();
+#if ENABLE_BINDER_SAMPLE
     if (time_binder_calls) {
         conditionally_log_binder_call(start_millis, target, code);
     }
+#endif
 
     if (err == NO_ERROR) {
         return JNI_TRUE;
diff --git a/core/jni/android_util_EventLog.cpp b/core/jni/android_util_EventLog.cpp
index 6ee504d..83d8aa2 100644
--- a/core/jni/android_util_EventLog.cpp
+++ b/core/jni/android_util_EventLog.cpp
@@ -19,7 +19,7 @@
 #include "JNIHelp.h"
 #include "android_runtime/AndroidRuntime.h"
 #include "jni.h"
-#include "cutils/logger.h"
+#include "log/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))
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 607c429..8325217 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -33,6 +33,7 @@
 #include <sys/errno.h>
 #include <sys/resource.h>
 #include <sys/types.h>
+#include <sys/stat.h>
 #include <dirent.h>
 #include <fcntl.h>
 #include <grp.h>
@@ -360,6 +361,32 @@
     return false;
 }
 
+jboolean android_os_Process_setSwappiness(JNIEnv *env, jobject clazz,
+                                          jint pid, jboolean is_increased)
+{
+    char text[64];
+
+    if (is_increased) {
+        strcpy(text, "/sys/fs/cgroup/memory/sw/tasks");
+    } else {
+        strcpy(text, "/sys/fs/cgroup/memory/tasks");
+    }
+
+    struct stat st;
+    if (stat(text, &st) || !S_ISREG(st.st_mode)) {
+        return false;
+    }
+
+    int fd = open(text, O_WRONLY);
+    if (fd >= 0) {
+        sprintf(text, "%d", pid);
+        write(fd, text, strlen(text));
+        close(fd);
+    }
+
+    return true;
+}
+
 void android_os_Process_setArgV0(JNIEnv* env, jobject clazz, jstring name)
 {
     if (name == NULL) {
@@ -657,6 +684,7 @@
     PROC_SPACE_TERM = ' ',
     PROC_COMBINE = 0x100,
     PROC_PARENS = 0x200,
+    PROC_QUOTES = 0x400,
     PROC_OUT_STRING = 0x1000,
     PROC_OUT_LONG = 0x2000,
     PROC_OUT_FLOAT = 0x4000,
@@ -698,9 +726,15 @@
     jboolean res = JNI_TRUE;
 
     for (jsize fi=0; fi<NF; fi++) {
-        const jint mode = formatData[fi];
+        jint mode = formatData[fi];
         if ((mode&PROC_PARENS) != 0) {
             i++;
+        } else if ((mode&PROC_QUOTES != 0)) {
+            if (buffer[i] == '"') {
+                i++;
+            } else {
+                mode &= ~PROC_QUOTES;
+            }
         }
         const char term = (char)(mode&PROC_TERM_MASK);
         const jsize start = i;
@@ -716,6 +750,12 @@
             }
             end = i;
             i++;
+        } else if ((mode&PROC_QUOTES) != 0) {
+            while (buffer[i] != '"' && i < endIndex) {
+                i++;
+            }
+            end = i;
+            i++;
         }
         while (buffer[i] != term && i < endIndex) {
             i++;
@@ -984,6 +1024,7 @@
     {"setProcessGroup",     "(II)V", (void*)android_os_Process_setProcessGroup},
     {"getProcessGroup",     "(I)I", (void*)android_os_Process_getProcessGroup},
     {"setOomAdj",   "(II)Z", (void*)android_os_Process_setOomAdj},
+    {"setSwappiness",   "(IZ)Z", (void*)android_os_Process_setSwappiness},
     {"setArgV0",    "(Ljava/lang/String;)V", (void*)android_os_Process_setArgV0},
     {"setUid", "(I)I", (void*)android_os_Process_setUid},
     {"setGid", "(I)I", (void*)android_os_Process_setGid},
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index b87fe27..dc90da7 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -16,18 +16,19 @@
 
 #define LOG_TAG "OpenGLRenderer"
 
-#include <EGL/egl.h>
-
 #include "jni.h"
 #include "GraphicsJNI.h"
 #include <nativehelper/JNIHelp.h>
 
+#include "android_view_GraphicBuffer.h"
+
 #include <android_runtime/AndroidRuntime.h>
 #include <android_runtime/android_graphics_SurfaceTexture.h>
-#include <gui/GLConsumer.h>
 
 #include <androidfw/ResourceTypes.h>
 
+#include <gui/GLConsumer.h>
+
 #include <private/hwui/DrawGlInfo.h>
 
 #include <cutils/properties.h>
@@ -99,10 +100,11 @@
     }
 }
 
-static void android_view_GLES20Canvas_initCaches(JNIEnv* env, jobject clazz) {
+static bool android_view_GLES20Canvas_initCaches(JNIEnv* env, jobject clazz) {
     if (Caches::hasInstance()) {
-        Caches::getInstance().init();
+        return Caches::getInstance().init();
     }
+    return false;
 }
 
 static void android_view_GLES20Canvas_terminateCaches(JNIEnv* env, jobject clazz) {
@@ -112,6 +114,21 @@
 }
 
 // ----------------------------------------------------------------------------
+// Caching
+// ----------------------------------------------------------------------------
+
+static void android_view_GLES20Canvas_initAtlas(JNIEnv* env, jobject clazz,
+        jobject graphicBuffer, jintArray atlasMapArray, jint count) {
+
+    sp<GraphicBuffer> buffer = graphicBufferForJavaObject(env, graphicBuffer);
+    jint* atlasMap = env->GetIntArrayElements(atlasMapArray, NULL);
+
+    Caches::getInstance().assetAtlas.init(buffer, atlasMap, count);
+
+    env->ReleaseIntArrayElements(atlasMapArray, atlasMap, 0);
+}
+
+// ----------------------------------------------------------------------------
 // Constructors
 // ----------------------------------------------------------------------------
 
@@ -168,6 +185,16 @@
     }
 }
 
+static void android_view_GLES20Canvas_setCountOverdrawEnabled(JNIEnv* env, jobject clazz,
+        OpenGLRenderer* renderer, jboolean enabled) {
+    renderer->setCountOverdrawEnabled(enabled);
+}
+
+static jfloat android_view_GLES20Canvas_getOverdraw(JNIEnv* env, jobject clazz,
+        OpenGLRenderer* renderer) {
+    return renderer->getOverdraw();
+}
+
 // ----------------------------------------------------------------------------
 // Functor
 // ----------------------------------------------------------------------------
@@ -271,7 +298,7 @@
 
 static bool android_view_GLES20Canvas_quickReject(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom) {
-    return renderer->quickReject(left, top, right, bottom);
+    return renderer->quickRejectNoScissor(left, top, right, bottom);
 }
 
 static bool android_view_GLES20Canvas_clipRectF(JNIEnv* env, jobject clazz,
@@ -370,8 +397,8 @@
 }
 
 static void android_view_GLES20Canvas_drawBitmapMatrix(JNIEnv* env, jobject clazz,
-        OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer, SkMatrix* matrix,
-        SkPaint* paint) {
+        OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer,
+        SkMatrix* matrix, SkPaint* paint) {
     // This object allows the renderer to allocate a global JNI ref to the buffer object.
     JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
 
@@ -390,7 +417,7 @@
         return;
     }
 
-    if (!GraphicsJNI::SetPixels(env, colors, offset, stride, 0, 0, width, height, *bitmap)) {
+    if (!GraphicsJNI::SetPixels(env, colors, offset, stride, 0, 0, width, height, *bitmap, true)) {
         delete bitmap;
         return;
     }
@@ -405,8 +432,8 @@
 
 static void android_view_GLES20Canvas_drawBitmapMesh(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer,
-        jint meshWidth, jint meshHeight, jfloatArray vertices, jint offset,
-        jintArray colors, jint colorOffset, SkPaint* paint) {
+        jint meshWidth, jint meshHeight, jfloatArray vertices, jint offset, jintArray colors,
+        jint colorOffset, SkPaint* paint) {
     // This object allows the renderer to allocate a global JNI ref to the buffer object.
     JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
 
@@ -420,20 +447,12 @@
 }
 
 static void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject clazz,
-        OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer, jbyteArray chunks,
+        OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer, Res_png_9patch* patch,
         float left, float top, float right, float bottom, SkPaint* paint) {
     // This object allows the renderer to allocate a global JNI ref to the buffer object.
     JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
 
-    jbyte* storage = env->GetByteArrayElements(chunks, NULL);
-    Res_png_9patch* patch = reinterpret_cast<Res_png_9patch*>(storage);
-    Res_png_9patch::deserialize(patch);
-
-    renderer->drawPatch(bitmap, &patch->xDivs[0], &patch->yDivs[0],
-            &patch->colors[0], patch->numXDivs, patch->numYDivs, patch->numColors,
-            left, top, right, bottom, paint);
-
-    env->ReleaseByteArrayElements(chunks, storage, 0);
+    renderer->drawPatch(bitmap, patch, left, top, right, bottom, paint);
 }
 
 static void android_view_GLES20Canvas_drawColor(JNIEnv* env, jobject clazz,
@@ -567,6 +586,20 @@
 // Text
 // ----------------------------------------------------------------------------
 
+static float xOffsetForTextAlign(SkPaint* paint, float totalAdvance) {
+    switch (paint->getTextAlign()) {
+        case SkPaint::kCenter_Align:
+            return -totalAdvance / 2.0f;
+            break;
+        case SkPaint::kRight_Align:
+            return -totalAdvance;
+            break;
+        default:
+            break;
+    }
+    return 0;
+}
+
 static void renderText(OpenGLRenderer* renderer, const jchar* text, int count,
         jfloat x, jfloat y, int flags, SkPaint* paint) {
     sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
@@ -577,10 +610,15 @@
     const jchar* glyphs = value->getGlyphs();
     size_t glyphsCount = value->getGlyphsCount();
     jfloat totalAdvance = value->getTotalAdvance();
+    x += xOffsetForTextAlign(paint, totalAdvance);
     const float* positions = value->getPos();
     int bytesCount = glyphsCount * sizeof(jchar);
-    renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, x, y,
-            positions, paint, totalAdvance);
+    const SkRect& r = value->getBounds();
+    android::uirenderer::Rect bounds(r.fLeft, r.fTop, r.fRight, r.fBottom);
+    bounds.translate(x, y);
+
+    renderer->drawText((const char*) glyphs, bytesCount, glyphsCount,
+            x, y, positions, paint, totalAdvance, bounds);
 }
 
 static void renderTextOnPath(OpenGLRenderer* renderer, const jchar* text, int count,
@@ -608,10 +646,15 @@
     const jchar* glyphs = value->getGlyphs();
     size_t glyphsCount = value->getGlyphsCount();
     jfloat totalAdvance = value->getTotalAdvance();
+    x += xOffsetForTextAlign(paint, totalAdvance);
     const float* positions = value->getPos();
     int bytesCount = glyphsCount * sizeof(jchar);
-    renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, x, y,
-            positions, paint, totalAdvance);
+    const SkRect& r = value->getBounds();
+    android::uirenderer::Rect bounds(r.fLeft, r.fTop, r.fRight, r.fBottom);
+    bounds.translate(x, y);
+
+    renderer->drawText((const char*) glyphs, bytesCount, glyphsCount,
+            x, y, positions, paint, totalAdvance, bounds);
 }
 
 static void android_view_GLES20Canvas_drawTextArray(JNIEnv* env, jobject clazz,
@@ -882,11 +925,21 @@
     renderer->pushLayerUpdate(layer);
 }
 
+static void android_view_GLES20Canvas_cancelLayerUpdate(JNIEnv* env, jobject clazz,
+        OpenGLRenderer* renderer, Layer* layer) {
+    renderer->cancelLayerUpdate(layer);
+}
+
 static void android_view_GLES20Canvas_clearLayerUpdates(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer) {
     renderer->clearLayerUpdates();
 }
 
+static void android_view_GLES20Canvas_flushLayerUpdates(JNIEnv* env, jobject clazz,
+        OpenGLRenderer* renderer) {
+    renderer->flushLayerUpdates();
+}
+
 #endif // USE_OPENGL_RENDERER
 
 // ----------------------------------------------------------------------------
@@ -932,9 +985,12 @@
 
 #ifdef USE_OPENGL_RENDERER
     { "nFlushCaches",       "(I)V",            (void*) android_view_GLES20Canvas_flushCaches },
-    { "nInitCaches",        "()V",             (void*) android_view_GLES20Canvas_initCaches },
+    { "nInitCaches",        "()Z",             (void*) android_view_GLES20Canvas_initCaches },
     { "nTerminateCaches",   "()V",             (void*) android_view_GLES20Canvas_terminateCaches },
 
+    { "nInitAtlas",         "(Landroid/view/GraphicBuffer;[II)V",
+            (void*) android_view_GLES20Canvas_initAtlas },
+
     { "nCreateRenderer",    "()I",             (void*) android_view_GLES20Canvas_createRenderer },
     { "nDestroyRenderer",   "(I)V",            (void*) android_view_GLES20Canvas_destroyRenderer },
     { "nSetViewport",       "(III)V",          (void*) android_view_GLES20Canvas_setViewport },
@@ -944,6 +1000,9 @@
     { "nSetName",           "(ILjava/lang/String;)V",
             (void*) android_view_GLES20Canvas_setName },
 
+    { "nSetCountOverdrawEnabled", "(IZ)V",     (void*) android_view_GLES20Canvas_setCountOverdrawEnabled },
+    { "nGetOverdraw",             "(I)F",      (void*) android_view_GLES20Canvas_getOverdraw },
+
     { "nGetStencilSize",    "()I",             (void*) android_view_GLES20Canvas_getStencilSize },
 
     { "nCallDrawGLFunction", "(II)I",          (void*) android_view_GLES20Canvas_callDrawGLFunction },
@@ -984,7 +1043,7 @@
 
     { "nDrawBitmapMesh",    "(II[BII[FI[III)V",(void*) android_view_GLES20Canvas_drawBitmapMesh },
 
-    { "nDrawPatch",         "(II[B[BFFFFI)V",  (void*) android_view_GLES20Canvas_drawPatch },
+    { "nDrawPatch",         "(II[BIFFFFI)V",   (void*) android_view_GLES20Canvas_drawPatch },
 
     { "nDrawColor",         "(III)V",          (void*) android_view_GLES20Canvas_drawColor },
     { "nDrawRect",          "(IFFFFI)V",       (void*) android_view_GLES20Canvas_drawRect },
@@ -1053,7 +1112,9 @@
     { "nDrawLayer",              "(IIFF)V",    (void*) android_view_GLES20Canvas_drawLayer },
     { "nCopyLayer",              "(II)Z",      (void*) android_view_GLES20Canvas_copyLayer },
     { "nClearLayerUpdates",      "(I)V",       (void*) android_view_GLES20Canvas_clearLayerUpdates },
+    { "nFlushLayerUpdates",      "(I)V",       (void*) android_view_GLES20Canvas_flushLayerUpdates },
     { "nPushLayerUpdate",        "(II)V",      (void*) android_view_GLES20Canvas_pushLayerUpdate },
+    { "nCancelLayerUpdate",      "(II)V",      (void*) android_view_GLES20Canvas_cancelLayerUpdate },
 
     { "nSetTextureLayerTransform", "(II)V",    (void*) android_view_GLES20Canvas_setTextureLayerTransform },
 
diff --git a/core/jni/android_view_GraphicBuffer.cpp b/core/jni/android_view_GraphicBuffer.cpp
new file mode 100644
index 0000000..d68c0b2
--- /dev/null
+++ b/core/jni/android_view_GraphicBuffer.cpp
@@ -0,0 +1,331 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "GraphicBuffer"
+
+#include "jni.h"
+#include "JNIHelp.h"
+
+#include "android_os_Parcel.h"
+#include "android_view_GraphicBuffer.h"
+
+#include <android_runtime/AndroidRuntime.h>
+
+#include <binder/Parcel.h>
+
+#include <ui/GraphicBuffer.h>
+#include <ui/PixelFormat.h>
+
+#include <gui/IGraphicBufferAlloc.h>
+#include <gui/ISurfaceComposer.h>
+
+#include <SkCanvas.h>
+#include <SkBitmap.h>
+
+#include <private/gui/ComposerService.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+// Defines
+// ----------------------------------------------------------------------------
+
+// Debug
+#define DEBUG_GRAPHIC_BUFFER 0
+
+// Debug
+#if DEBUG_GRAPHIC_BUFFER
+    #define GB_LOGD(...) ALOGD(__VA_ARGS__)
+    #define GB_LOGW(...) ALOGW(__VA_ARGS__)
+#else
+    #define GB_LOGD(...)
+    #define GB_LOGW(...)
+#endif
+
+#define LOCK_CANVAS_USAGE GraphicBuffer::USAGE_SW_READ_OFTEN | GraphicBuffer::USAGE_SW_WRITE_OFTEN
+
+// ----------------------------------------------------------------------------
+// JNI Helpers
+// ----------------------------------------------------------------------------
+
+static struct {
+    jfieldID mNativeObject;
+} gGraphicBufferClassInfo;
+
+static struct {
+    jmethodID set;
+    jfieldID left;
+    jfieldID top;
+    jfieldID right;
+    jfieldID bottom;
+} gRectClassInfo;
+
+static struct {
+    jfieldID mFinalizer;
+    jfieldID mNativeCanvas;
+    jfieldID mSurfaceFormat;
+} gCanvasClassInfo;
+
+static struct {
+    jfieldID mNativeCanvas;
+} gCanvasFinalizerClassInfo;
+
+#define GET_INT(object, field) \
+    env->GetIntField(object, field)
+
+#define SET_INT(object, field, value) \
+    env->SetIntField(object, field, value)
+
+#define INVOKEV(object, method, ...) \
+    env->CallVoidMethod(object, method, __VA_ARGS__)
+
+// ----------------------------------------------------------------------------
+// Types
+// ----------------------------------------------------------------------------
+
+class GraphicBufferWrapper {
+public:
+    GraphicBufferWrapper(const sp<GraphicBuffer>& buffer): buffer(buffer) {
+    }
+
+    sp<GraphicBuffer> buffer;
+};
+
+// ----------------------------------------------------------------------------
+// GraphicBuffer lifecycle
+// ----------------------------------------------------------------------------
+
+static GraphicBufferWrapper* android_view_GraphiceBuffer_create(JNIEnv* env, jobject clazz,
+        jint width, jint height, jint format, jint usage) {
+
+    sp<ISurfaceComposer> composer(ComposerService::getComposerService());
+    sp<IGraphicBufferAlloc> alloc(composer->createGraphicBufferAlloc());
+    if (alloc == NULL) {
+        GB_LOGW("createGraphicBufferAlloc() failed in GraphicBuffer.create()");
+        return NULL;
+    }
+
+    status_t error;
+    sp<GraphicBuffer> buffer(alloc->createGraphicBuffer(width, height, format, usage, &error));
+    if (buffer == NULL) {
+        GB_LOGW("createGraphicBuffer() failed in GraphicBuffer.create()");
+        return NULL;
+    }
+
+    return new GraphicBufferWrapper(buffer);
+}
+
+static void android_view_GraphiceBuffer_destroy(JNIEnv* env, jobject clazz,
+        GraphicBufferWrapper* wrapper) {
+    delete wrapper;
+}
+
+// ----------------------------------------------------------------------------
+// Canvas management
+// ----------------------------------------------------------------------------
+
+static inline void swapCanvasPtr(JNIEnv* env, jobject canvasObj, SkCanvas* newCanvas) {
+    jobject canvasFinalizerObj = env->GetObjectField(canvasObj, gCanvasClassInfo.mFinalizer);
+    SkCanvas* previousCanvas = reinterpret_cast<SkCanvas*>(
+            GET_INT(canvasObj, gCanvasClassInfo.mNativeCanvas));
+    SET_INT(canvasObj, gCanvasClassInfo.mNativeCanvas, (int) newCanvas);
+    SET_INT(canvasFinalizerObj, gCanvasFinalizerClassInfo.mNativeCanvas, (int) newCanvas);
+    SkSafeUnref(previousCanvas);
+}
+
+static inline SkBitmap::Config convertPixelFormat(int32_t format) {
+    switch (format) {
+        case PIXEL_FORMAT_RGBA_8888:
+            return SkBitmap::kARGB_8888_Config;
+        case PIXEL_FORMAT_RGBX_8888:
+            return SkBitmap::kARGB_8888_Config;
+        case PIXEL_FORMAT_RGB_565:
+            return SkBitmap::kRGB_565_Config;
+        default:
+            return SkBitmap::kNo_Config;
+    }
+}
+
+static jboolean android_view_GraphicBuffer_lockCanvas(JNIEnv* env, jobject,
+        GraphicBufferWrapper* wrapper, jobject canvas, jobject dirtyRect) {
+
+    if (!wrapper) {
+        return false;
+    }
+
+    sp<GraphicBuffer> buffer(wrapper->buffer);
+
+    Rect rect;
+    if (dirtyRect) {
+        rect.left = GET_INT(dirtyRect, gRectClassInfo.left);
+        rect.top = GET_INT(dirtyRect, gRectClassInfo.top);
+        rect.right = GET_INT(dirtyRect, gRectClassInfo.right);
+        rect.bottom = GET_INT(dirtyRect, gRectClassInfo.bottom);
+    } else {
+        rect.set(Rect(buffer->getWidth(), buffer->getHeight()));
+    }
+
+    void* bits = NULL;
+    status_t status = buffer->lock(LOCK_CANVAS_USAGE, rect, &bits);
+
+    if (status) return false;
+    if (!bits) {
+        buffer->unlock();
+        return false;
+    }
+
+    ssize_t bytesCount = buffer->getStride() * bytesPerPixel(buffer->getPixelFormat());
+
+    SkBitmap bitmap;
+    bitmap.setConfig(convertPixelFormat(buffer->getPixelFormat()),
+            buffer->getWidth(), buffer->getHeight(), bytesCount);
+
+    if (buffer->getWidth() > 0 && buffer->getHeight() > 0) {
+        bitmap.setPixels(bits);
+    } else {
+        bitmap.setPixels(NULL);
+    }
+
+    SET_INT(canvas, gCanvasClassInfo.mSurfaceFormat, buffer->getPixelFormat());
+
+    SkCanvas* nativeCanvas = SkNEW_ARGS(SkCanvas, (bitmap));
+    swapCanvasPtr(env, canvas, nativeCanvas);
+
+    SkRect clipRect;
+    clipRect.set(rect.left, rect.top, rect.right, rect.bottom);
+    nativeCanvas->clipRect(clipRect);
+
+    if (dirtyRect) {
+        INVOKEV(dirtyRect, gRectClassInfo.set,
+                int(rect.left), int(rect.top), int(rect.right), int(rect.bottom));
+    }
+
+    return true;
+}
+
+static jboolean android_view_GraphicBuffer_unlockCanvasAndPost(JNIEnv* env, jobject,
+        GraphicBufferWrapper* wrapper, jobject canvas) {
+
+    SkCanvas* nativeCanvas = SkNEW(SkCanvas);
+    swapCanvasPtr(env, canvas, nativeCanvas);
+
+    if (wrapper) {
+        status_t status = wrapper->buffer->unlock();
+        return status == 0;
+    }
+
+    return false;
+}
+
+// ----------------------------------------------------------------------------
+// Serialization
+// ----------------------------------------------------------------------------
+
+static void android_view_GraphiceBuffer_write(JNIEnv* env, jobject clazz,
+        GraphicBufferWrapper* wrapper, jobject dest) {
+    Parcel* parcel = parcelForJavaObject(env, dest);
+    if (parcel) {
+        parcel->write(*wrapper->buffer);
+    }
+}
+
+static GraphicBufferWrapper* android_view_GraphiceBuffer_read(JNIEnv* env, jobject clazz,
+        jobject in) {
+
+    Parcel* parcel = parcelForJavaObject(env, in);
+    if (parcel) {
+        sp<GraphicBuffer> buffer = new GraphicBuffer();
+        parcel->read(*buffer);
+        return new GraphicBufferWrapper(buffer);
+    }
+
+    return NULL;
+}
+
+// ----------------------------------------------------------------------------
+// External helpers
+// ----------------------------------------------------------------------------
+
+sp<GraphicBuffer> graphicBufferForJavaObject(JNIEnv* env, jobject obj) {
+    if (obj) {
+        jint nativeObject = env->GetIntField(obj, gGraphicBufferClassInfo.mNativeObject);
+        GraphicBufferWrapper* wrapper = (GraphicBufferWrapper*) nativeObject;
+        if (wrapper != NULL) {
+            sp<GraphicBuffer> buffer(wrapper->buffer);
+            return buffer;
+        }
+    }
+    return NULL;
+}
+
+// ----------------------------------------------------------------------------
+// JNI Glue
+// ----------------------------------------------------------------------------
+
+#define FIND_CLASS(var, className) \
+        var = env->FindClass(className); \
+        LOG_FATAL_IF(! var, "Unable to find class " className);
+
+#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
+        var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
+        LOG_FATAL_IF(! var, "Unable to find field " fieldName);
+
+#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
+        var = env->GetMethodID(clazz, methodName, methodDescriptor); \
+        LOG_FATAL_IF(!var, "Unable to find method " methodName);
+
+const char* const kClassPathName = "android/view/GraphicBuffer";
+
+static JNINativeMethod gMethods[] = {
+    { "nCreateGraphicBuffer",  "(IIII)I", (void*) android_view_GraphiceBuffer_create },
+    { "nDestroyGraphicBuffer", "(I)V",    (void*) android_view_GraphiceBuffer_destroy },
+
+    { "nWriteGraphicBufferToParcel",  "(ILandroid/os/Parcel;)V",
+            (void*) android_view_GraphiceBuffer_write },
+    { "nReadGraphicBufferFromParcel", "(Landroid/os/Parcel;)I",
+            (void*) android_view_GraphiceBuffer_read },
+
+    { "nLockCanvas", "(ILandroid/graphics/Canvas;Landroid/graphics/Rect;)Z",
+            (void*) android_view_GraphicBuffer_lockCanvas },
+    { "nUnlockCanvasAndPost", "(ILandroid/graphics/Canvas;)Z",
+            (void*) android_view_GraphicBuffer_unlockCanvasAndPost },
+};
+
+int register_android_view_GraphicBuffer(JNIEnv* env) {
+    jclass clazz;
+    FIND_CLASS(clazz, "android/view/GraphicBuffer");
+    GET_FIELD_ID(gGraphicBufferClassInfo.mNativeObject, clazz, "mNativeObject", "I");
+
+    FIND_CLASS(clazz, "android/graphics/Rect");
+    GET_METHOD_ID(gRectClassInfo.set, clazz, "set", "(IIII)V");
+    GET_FIELD_ID(gRectClassInfo.left, clazz, "left", "I");
+    GET_FIELD_ID(gRectClassInfo.top, clazz, "top", "I");
+    GET_FIELD_ID(gRectClassInfo.right, clazz, "right", "I");
+    GET_FIELD_ID(gRectClassInfo.bottom, clazz, "bottom", "I");
+
+    FIND_CLASS(clazz, "android/graphics/Canvas");
+    GET_FIELD_ID(gCanvasClassInfo.mFinalizer, clazz, "mFinalizer",
+            "Landroid/graphics/Canvas$CanvasFinalizer;");
+    GET_FIELD_ID(gCanvasClassInfo.mNativeCanvas, clazz, "mNativeCanvas", "I");
+    GET_FIELD_ID(gCanvasClassInfo.mSurfaceFormat, clazz, "mSurfaceFormat", "I");
+
+    FIND_CLASS(clazz, "android/graphics/Canvas$CanvasFinalizer");
+    GET_FIELD_ID(gCanvasFinalizerClassInfo.mNativeCanvas, clazz, "mNativeCanvas", "I");
+
+    return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
+}
+
+};
diff --git a/core/jni/android_view_GraphicBuffer.h b/core/jni/android_view_GraphicBuffer.h
new file mode 100644
index 0000000..509587c
--- /dev/null
+++ b/core/jni/android_view_GraphicBuffer.h
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+#include <ui/GraphicBuffer.h>
+
+#include "jni.h"
+
+namespace android {
+
+// This function does not perform any type checking, the specified
+// object must be an instance of android.view.GraphicBuffer
+extern sp<GraphicBuffer> graphicBufferForJavaObject(JNIEnv* env, jobject obj);
+
+}
diff --git a/core/jni/android_view_HardwareRenderer.cpp b/core/jni/android_view_HardwareRenderer.cpp
index 948a966..479fbe2 100644
--- a/core/jni/android_view_HardwareRenderer.cpp
+++ b/core/jni/android_view_HardwareRenderer.cpp
@@ -20,9 +20,14 @@
 #include <nativehelper/JNIHelp.h>
 #include <android_runtime/AndroidRuntime.h>
 
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
 #include <EGL/egl_cache.h>
 
+#include <utils/Timers.h>
+
 #include <Caches.h>
+#include <Extensions.h>
 
 #ifdef USE_OPENGL_RENDERER
     EGLAPI void EGLAPIENTRY eglBeginFrame(EGLDisplay dpy, EGLSurface surface);
@@ -119,6 +124,13 @@
     eglBeginFrame(display, surface);
 }
 
+static jlong android_view_HardwareRenderer_getSystemTime(JNIEnv* env, jobject clazz) {
+    if (uirenderer::Extensions::getInstance().hasNvSystemTime()) {
+        return eglGetSystemTimeNV();
+    }
+    return systemTime(SYSTEM_TIME_MONOTONIC);
+}
+
 #endif // USE_OPENGL_RENDERER
 
 // ----------------------------------------------------------------------------
@@ -146,6 +158,8 @@
     { "nLoadProperties",        "()Z",   (void*) android_view_HardwareRenderer_loadProperties },
 
     { "nBeginFrame",            "([I)V", (void*) android_view_HardwareRenderer_beginFrame },
+
+    { "nGetSystemTime",         "()J",   (void*) android_view_HardwareRenderer_getSystemTime },
 #endif
 
     { "nSetupShadersDiskCache", "(Ljava/lang/String;)V",
diff --git a/core/jni/android_view_InputChannel.cpp b/core/jni/android_view_InputChannel.cpp
index 9fa9fe4..ce475e0 100644
--- a/core/jni/android_view_InputChannel.cpp
+++ b/core/jni/android_view_InputChannel.cpp
@@ -21,7 +21,7 @@
 #include <android_runtime/AndroidRuntime.h>
 #include <binder/Parcel.h>
 #include <utils/Log.h>
-#include <androidfw/InputTransport.h>
+#include <input/InputTransport.h>
 #include "android_view_InputChannel.h"
 #include "android_os_Parcel.h"
 #include "android_util_Binder.h"
diff --git a/core/jni/android_view_InputChannel.h b/core/jni/android_view_InputChannel.h
index 0967021..2ba2dc0 100644
--- a/core/jni/android_view_InputChannel.h
+++ b/core/jni/android_view_InputChannel.h
@@ -19,7 +19,7 @@
 
 #include "jni.h"
 
-#include <androidfw/InputTransport.h>
+#include <input/InputTransport.h>
 
 namespace android {
 
diff --git a/core/jni/android_view_InputDevice.cpp b/core/jni/android_view_InputDevice.cpp
index e3a54a8..bef0f84 100644
--- a/core/jni/android_view_InputDevice.cpp
+++ b/core/jni/android_view_InputDevice.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include <androidfw/Input.h>
+#include <input/Input.h>
 
 #include <android_runtime/AndroidRuntime.h>
 #include <nativehelper/jni.h>
@@ -53,11 +53,15 @@
         return NULL;
     }
 
+    const InputDeviceIdentifier& ident = deviceInfo.getIdentifier();
+
     ScopedLocalRef<jobject> inputDeviceObj(env, env->NewObject(gInputDeviceClassInfo.clazz,
-            gInputDeviceClassInfo.ctor, deviceInfo.getId(), deviceInfo.getGeneration(),
-            nameObj.get(), descriptorObj.get(), deviceInfo.isExternal(),
-            deviceInfo.getSources(), deviceInfo.getKeyboardType(),
-            kcmObj.get(), deviceInfo.hasVibrator()));
+                gInputDeviceClassInfo.ctor, deviceInfo.getId(), deviceInfo.getGeneration(),
+                deviceInfo.getControllerNumber(), nameObj.get(),
+                static_cast<int32_t>(ident.vendor), static_cast<int32_t>(ident.product),
+                descriptorObj.get(), deviceInfo.isExternal(), deviceInfo.getSources(),
+                deviceInfo.getKeyboardType(), kcmObj.get(), deviceInfo.hasVibrator(),
+                deviceInfo.hasButtonUnderPad()));
 
     const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
     for (size_t i = 0; i < ranges.size(); i++) {
@@ -87,7 +91,8 @@
     gInputDeviceClassInfo.clazz = jclass(env->NewGlobalRef(gInputDeviceClassInfo.clazz));
 
     GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
-            "<init>", "(IILjava/lang/String;Ljava/lang/String;ZIILandroid/view/KeyCharacterMap;Z)V");
+            "<init>",
+            "(IIILjava/lang/String;IILjava/lang/String;ZIILandroid/view/KeyCharacterMap;ZZ)V");
 
     GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
             "addMotionRange", "(IIFFFFF)V");
diff --git a/core/jni/android_view_InputDevice.h b/core/jni/android_view_InputDevice.h
index 78651ba..ac38eb1 100644
--- a/core/jni/android_view_InputDevice.h
+++ b/core/jni/android_view_InputDevice.h
@@ -19,7 +19,7 @@
 
 #include "jni.h"
 
-#include <androidfw/InputDevice.h>
+#include <input/InputDevice.h>
 
 namespace android {
 
diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp
index 8e1e04a..b254de7 100644
--- a/core/jni/android_view_InputEventReceiver.cpp
+++ b/core/jni/android_view_InputEventReceiver.cpp
@@ -29,7 +29,7 @@
 #include <utils/Looper.h>
 #include <utils/Vector.h>
 #include <utils/threads.h>
-#include <androidfw/InputTransport.h>
+#include <input/InputTransport.h>
 #include "android_os_MessageQueue.h"
 #include "android_view_InputChannel.h"
 #include "android_view_KeyEvent.h"
diff --git a/core/jni/android_view_InputEventSender.cpp b/core/jni/android_view_InputEventSender.cpp
index b46eb4b..e4b65a1 100644
--- a/core/jni/android_view_InputEventSender.cpp
+++ b/core/jni/android_view_InputEventSender.cpp
@@ -29,7 +29,7 @@
 #include <utils/Looper.h>
 #include <utils/threads.h>
 #include <utils/KeyedVector.h>
-#include <androidfw/InputTransport.h>
+#include <input/InputTransport.h>
 #include "android_os_MessageQueue.h"
 #include "android_view_InputChannel.h"
 #include "android_view_KeyEvent.h"
diff --git a/core/jni/android_view_InputQueue.cpp b/core/jni/android_view_InputQueue.cpp
index ec56afa..7532c9d 100644
--- a/core/jni/android_view_InputQueue.cpp
+++ b/core/jni/android_view_InputQueue.cpp
@@ -23,7 +23,7 @@
 #include <android/input.h>
 #include <android_runtime/AndroidRuntime.h>
 #include <android_runtime/android_view_InputQueue.h>
-#include <androidfw/Input.h>
+#include <input/Input.h>
 #include <utils/Looper.h>
 #include <utils/TypeHelpers.h>
 #include <ScopedLocalRef.h>
diff --git a/core/jni/android_view_KeyCharacterMap.cpp b/core/jni/android_view_KeyCharacterMap.cpp
index 3e56a89..ffe2dea 100644
--- a/core/jni/android_view_KeyCharacterMap.cpp
+++ b/core/jni/android_view_KeyCharacterMap.cpp
@@ -16,8 +16,8 @@
 
 #include <android_runtime/AndroidRuntime.h>
 
-#include <androidfw/KeyCharacterMap.h>
-#include <androidfw/Input.h>
+#include <input/KeyCharacterMap.h>
+#include <input/Input.h>
 #include <binder/Parcel.h>
 
 #include <nativehelper/jni.h>
diff --git a/core/jni/android_view_KeyCharacterMap.h b/core/jni/android_view_KeyCharacterMap.h
index 04024f6..e8465c2 100644
--- a/core/jni/android_view_KeyCharacterMap.h
+++ b/core/jni/android_view_KeyCharacterMap.h
@@ -19,7 +19,7 @@
 
 #include "jni.h"
 
-#include <androidfw/KeyCharacterMap.h>
+#include <input/KeyCharacterMap.h>
 
 namespace android {
 
diff --git a/core/jni/android_view_KeyEvent.cpp b/core/jni/android_view_KeyEvent.cpp
index 36a98f9..c83541d 100644
--- a/core/jni/android_view_KeyEvent.cpp
+++ b/core/jni/android_view_KeyEvent.cpp
@@ -19,8 +19,9 @@
 #include "JNIHelp.h"
 
 #include <android_runtime/AndroidRuntime.h>
+#include <android_runtime/Log.h>
 #include <utils/Log.h>
-#include <androidfw/Input.h>
+#include <input/Input.h>
 #include "android_view_KeyEvent.h"
 
 namespace android {
diff --git a/core/jni/android_view_MotionEvent.cpp b/core/jni/android_view_MotionEvent.cpp
index e69fb74..f1b90e1 100644
--- a/core/jni/android_view_MotionEvent.cpp
+++ b/core/jni/android_view_MotionEvent.cpp
@@ -18,17 +18,16 @@
 
 #include "JNIHelp.h"
 
+#include <SkMatrix.h>
 #include <android_runtime/AndroidRuntime.h>
+#include <android_runtime/Log.h>
 #include <utils/Log.h>
-#include <androidfw/Input.h>
+#include <input/Input.h>
 #include "android_os_Parcel.h"
 #include "android_view_MotionEvent.h"
 #include "android_util_Binder.h"
 #include "android/graphics/Matrix.h"
 
-#include "SkMatrix.h"
-
-
 namespace android {
 
 // ----------------------------------------------------------------------------
@@ -680,7 +679,18 @@
         jint nativePtr, jobject matrixObj) {
     SkMatrix* matrix = android_graphics_Matrix_getSkMatrix(env, matrixObj);
     MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
-    event->transform(matrix);
+
+    float m[9];
+    m[0] = SkScalarToFloat(matrix->get(SkMatrix::kMScaleX));
+    m[1] = SkScalarToFloat(matrix->get(SkMatrix::kMSkewX));
+    m[2] = SkScalarToFloat(matrix->get(SkMatrix::kMTransX));
+    m[3] = SkScalarToFloat(matrix->get(SkMatrix::kMSkewY));
+    m[4] = SkScalarToFloat(matrix->get(SkMatrix::kMScaleY));
+    m[5] = SkScalarToFloat(matrix->get(SkMatrix::kMTransY));
+    m[6] = SkScalarToFloat(matrix->get(SkMatrix::kMPersp0));
+    m[7] = SkScalarToFloat(matrix->get(SkMatrix::kMPersp1));
+    m[8] = SkScalarToFloat(matrix->get(SkMatrix::kMPersp2));
+    event->transform(m);
 }
 
 static jint android_view_MotionEvent_nativeReadFromParcel(JNIEnv* env, jclass clazz,
diff --git a/core/jni/android_view_PointerIcon.cpp b/core/jni/android_view_PointerIcon.cpp
index 8b6dc60..5e29213 100644
--- a/core/jni/android_view_PointerIcon.cpp
+++ b/core/jni/android_view_PointerIcon.cpp
@@ -21,6 +21,7 @@
 #include "android_view_PointerIcon.h"
 
 #include <android_runtime/AndroidRuntime.h>
+#include <android_runtime/Log.h>
 #include <utils/Log.h>
 #include <android/graphics/GraphicsJNI.h>
 
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index d9f6be9..1868469 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -26,6 +26,7 @@
 #include <android_runtime/AndroidRuntime.h>
 #include <android_runtime/android_view_Surface.h>
 #include <android_runtime/android_graphics_SurfaceTexture.h>
+#include <android_runtime/Log.h>
 
 #include <binder/Parcel.h>
 
@@ -107,7 +108,7 @@
         return NULL;
     }
 
-    sp<Surface> surface(new Surface(bufferProducer));
+    sp<Surface> surface(new Surface(bufferProducer, true));
     if (surface == NULL) {
         return NULL;
     }
@@ -135,15 +136,14 @@
 
 static jint nativeCreateFromSurfaceTexture(JNIEnv* env, jclass clazz,
         jobject surfaceTextureObj) {
-    sp<GLConsumer> st(SurfaceTexture_getSurfaceTexture(env, surfaceTextureObj));
-    if (st == NULL) {
+    sp<IGraphicBufferProducer> producer(SurfaceTexture_getProducer(env, surfaceTextureObj));
+    if (producer == NULL) {
         jniThrowException(env, "java/lang/IllegalArgumentException",
                 "SurfaceTexture has already been released");
         return 0;
     }
 
-    sp<IGraphicBufferProducer> bq = st->getBufferQueue();
-    sp<Surface> surface(new Surface(bq));
+    sp<Surface> surface(new Surface(producer, true));
     if (surface == NULL) {
         jniThrowException(env, OutOfResourcesException, NULL);
         return 0;
@@ -183,9 +183,7 @@
     switch (format) {
     case PIXEL_FORMAT_RGBX_8888:    return SkBitmap::kARGB_8888_Config;
     case PIXEL_FORMAT_RGBA_8888:    return SkBitmap::kARGB_8888_Config;
-    case PIXEL_FORMAT_RGBA_4444:    return SkBitmap::kARGB_4444_Config;
     case PIXEL_FORMAT_RGB_565:      return SkBitmap::kRGB_565_Config;
-    case PIXEL_FORMAT_A_8:          return SkBitmap::kA8_Config;
     default:                        return SkBitmap::kNo_Config;
     }
 }
@@ -199,40 +197,34 @@
   SkSafeUnref(previousCanvas);
 }
 
-static void nativeLockCanvas(JNIEnv* env, jclass clazz,
+static jint nativeLockCanvas(JNIEnv* env, jclass clazz,
         jint nativeObject, jobject canvasObj, jobject dirtyRectObj) {
     sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject));
 
     if (!isSurfaceValid(surface)) {
         doThrowIAE(env);
-        return;
+        return 0;
     }
 
-    // get dirty region
-    Region dirtyRegion;
+    Rect dirtyRect;
+    Rect* dirtyRectPtr = NULL;
+
     if (dirtyRectObj) {
-        Rect dirty;
-        dirty.left = env->GetIntField(dirtyRectObj, gRectClassInfo.left);
-        dirty.top = env->GetIntField(dirtyRectObj, gRectClassInfo.top);
-        dirty.right = env->GetIntField(dirtyRectObj, gRectClassInfo.right);
-        dirty.bottom = env->GetIntField(dirtyRectObj, gRectClassInfo.bottom);
-        if (!dirty.isEmpty()) {
-            dirtyRegion.set(dirty);
-        }
-    } else {
-        dirtyRegion.set(Rect(0x3FFF, 0x3FFF));
+        dirtyRect.left   = env->GetIntField(dirtyRectObj, gRectClassInfo.left);
+        dirtyRect.top    = env->GetIntField(dirtyRectObj, gRectClassInfo.top);
+        dirtyRect.right  = env->GetIntField(dirtyRectObj, gRectClassInfo.right);
+        dirtyRect.bottom = env->GetIntField(dirtyRectObj, gRectClassInfo.bottom);
+        dirtyRectPtr = &dirtyRect;
     }
 
     ANativeWindow_Buffer outBuffer;
-    Rect dirtyBounds(dirtyRegion.getBounds());
-    status_t err = surface->lock(&outBuffer, &dirtyBounds);
-    dirtyRegion.set(dirtyBounds);
+    status_t err = surface->lock(&outBuffer, dirtyRectPtr);
     if (err < 0) {
         const char* const exception = (err == NO_MEMORY) ?
                 OutOfResourcesException :
                 "java/lang/IllegalArgumentException";
         jniThrowException(env, exception, NULL);
-        return;
+        return 0;
     }
 
     // Associate a SkCanvas object to this surface
@@ -254,28 +246,23 @@
     SkCanvas* nativeCanvas = SkNEW_ARGS(SkCanvas, (bitmap));
     swapCanvasPtr(env, canvasObj, nativeCanvas);
 
-    SkRegion clipReg;
-    if (dirtyRegion.isRect()) { // very common case
-        const Rect b(dirtyRegion.getBounds());
-        clipReg.setRect(b.left, b.top, b.right, b.bottom);
-    } else {
-        size_t count;
-        Rect const* r = dirtyRegion.getArray(&count);
-        while (count) {
-            clipReg.op(r->left, r->top, r->right, r->bottom, SkRegion::kUnion_Op);
-            r++, count--;
-        }
+    if (dirtyRectPtr) {
+        nativeCanvas->clipRect( SkRect::Make(reinterpret_cast<const SkIRect&>(dirtyRect)) );
     }
 
-    nativeCanvas->clipRegion(clipReg);
-
     if (dirtyRectObj) {
-        const Rect& bounds(dirtyRegion.getBounds());
-        env->SetIntField(dirtyRectObj, gRectClassInfo.left, bounds.left);
-        env->SetIntField(dirtyRectObj, gRectClassInfo.top, bounds.top);
-        env->SetIntField(dirtyRectObj, gRectClassInfo.right, bounds.right);
-        env->SetIntField(dirtyRectObj, gRectClassInfo.bottom, bounds.bottom);
+        env->SetIntField(dirtyRectObj, gRectClassInfo.left,   dirtyRect.left);
+        env->SetIntField(dirtyRectObj, gRectClassInfo.top,    dirtyRect.top);
+        env->SetIntField(dirtyRectObj, gRectClassInfo.right,  dirtyRect.right);
+        env->SetIntField(dirtyRectObj, gRectClassInfo.bottom, dirtyRect.bottom);
     }
+
+    // Create another reference to the surface and return it.  This reference
+    // should be passed to nativeUnlockCanvasAndPost in place of mNativeObject,
+    // because the latter could be replaced while the surface is locked.
+    sp<Surface> lockedSurface(surface);
+    lockedSurface->incStrong(&sRefBaseOwner);
+    return (int) lockedSurface.get();
 }
 
 static void nativeUnlockCanvasAndPost(JNIEnv* env, jclass clazz,
@@ -337,7 +324,7 @@
     sp<IGraphicBufferProducer> gbp(interface_cast<IGraphicBufferProducer>(binder));
     if (gbp != NULL) {
         // we have a new IGraphicBufferProducer, create a new Surface for it
-        sur = new Surface(gbp);
+        sur = new Surface(gbp, true);
         // and keep a reference before passing to java
         sur->incStrong(&sRefBaseOwner);
     }
@@ -372,7 +359,7 @@
             (void*)nativeIsValid },
     {"nativeIsConsumerRunningBehind", "(I)Z",
             (void*)nativeIsConsumerRunningBehind },
-    {"nativeLockCanvas", "(ILandroid/graphics/Canvas;Landroid/graphics/Rect;)V",
+    {"nativeLockCanvas", "(ILandroid/graphics/Canvas;Landroid/graphics/Rect;)I",
             (void*)nativeLockCanvas },
     {"nativeUnlockCanvasAndPost", "(ILandroid/graphics/Canvas;)V",
             (void*)nativeUnlockCanvasAndPost },
@@ -392,7 +379,7 @@
     jclass clazz = env->FindClass("android/view/Surface");
     gSurfaceClassInfo.clazz = jclass(env->NewGlobalRef(clazz));
     gSurfaceClassInfo.mNativeObject =
-            env->GetFieldID(gSurfaceClassInfo.clazz, "mNativeSurface", "I");
+            env->GetFieldID(gSurfaceClassInfo.clazz, "mNativeObject", "I");
     gSurfaceClassInfo.mLock =
             env->GetFieldID(gSurfaceClassInfo.clazz, "mLock", "Ljava/lang/Object;");
     gSurfaceClassInfo.ctor = env->GetMethodID(gSurfaceClassInfo.clazz, "<init>", "(I)V");
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index ec10536..67eade8 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -155,9 +155,7 @@
     switch (format) {
     case PIXEL_FORMAT_RGBX_8888:    return SkBitmap::kARGB_8888_Config;
     case PIXEL_FORMAT_RGBA_8888:    return SkBitmap::kARGB_8888_Config;
-    case PIXEL_FORMAT_RGBA_4444:    return SkBitmap::kARGB_4444_Config;
     case PIXEL_FORMAT_RGB_565:      return SkBitmap::kRGB_565_Config;
-    case PIXEL_FORMAT_A_8:          return SkBitmap::kA8_Config;
     default:                        return SkBitmap::kNo_Config;
     }
 }
@@ -197,7 +195,8 @@
         bitmap->setPixels(NULL);
     }
 
-    return GraphicsJNI::createBitmap(env, bitmap, false, NULL);
+    return GraphicsJNI::createBitmap(env, bitmap,
+            GraphicsJNI::kBitmapCreateFlag_Premultiplied, NULL);
 }
 
 static void nativeScreenshot(JNIEnv* env, jclass clazz,
@@ -335,6 +334,12 @@
     return javaObjectForIBinder(env, token);
 }
 
+static void nativeDestroyDisplay(JNIEnv* env, jclass clazz, jobject tokenObj) {
+    sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
+    if (token == NULL) return;
+    SurfaceComposerClient::destroyDisplay(token);
+}
+
 static void nativeSetDisplaySurface(JNIEnv* env, jclass clazz,
         jobject tokenObj, jint nativeSurfaceObject) {
     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
@@ -443,6 +448,8 @@
             (void*)nativeGetBuiltInDisplay },
     {"nativeCreateDisplay", "(Ljava/lang/String;Z)Landroid/os/IBinder;",
             (void*)nativeCreateDisplay },
+    {"nativeDestroyDisplay", "(Landroid/os/IBinder;)V",
+            (void*)nativeDestroyDisplay },
     {"nativeSetDisplaySurface", "(Landroid/os/IBinder;I)V",
             (void*)nativeSetDisplaySurface },
     {"nativeSetDisplayLayerStack", "(Landroid/os/IBinder;I)V",
diff --git a/core/jni/android_view_TextureView.cpp b/core/jni/android_view_TextureView.cpp
index 5baae84..0f429005 100644
--- a/core/jni/android_view_TextureView.cpp
+++ b/core/jni/android_view_TextureView.cpp
@@ -69,13 +69,6 @@
 // Native layer
 // ----------------------------------------------------------------------------
 
-static void android_view_TextureView_setDefaultBufferSize(JNIEnv* env, jobject,
-    jobject surface, jint width, jint height) {
-
-    sp<GLConsumer> glConsumer(SurfaceTexture_getSurfaceTexture(env, surface));
-    glConsumer->setDefaultBufferSize(width, height);
-}
-
 static inline SkBitmap::Config convertPixelFormat(int32_t format) {
     switch (format) {
         case WINDOW_FORMAT_RGBA_8888:
@@ -106,8 +99,8 @@
 static void android_view_TextureView_createNativeWindow(JNIEnv* env, jobject textureView,
         jobject surface) {
 
-    sp<GLConsumer> glConsumer(SurfaceTexture_getSurfaceTexture(env, surface));
-    sp<ANativeWindow> window = new Surface(glConsumer->getBufferQueue());
+    sp<IGraphicBufferProducer> producer(SurfaceTexture_getProducer(env, surface));
+    sp<ANativeWindow> window = new Surface(producer, true);
 
     window->incStrong((void*)android_view_TextureView_createNativeWindow);
     SET_INT(textureView, gTextureViewClassInfo.nativeWindow, jint(window.get()));
@@ -126,19 +119,19 @@
 }
 
 static inline void swapCanvasPtr(JNIEnv* env, jobject canvasObj, SkCanvas* newCanvas) {
-  jobject canvasFinalizerObj = env->GetObjectField(canvasObj, gCanvasClassInfo.mFinalizer);
-  SkCanvas* previousCanvas = reinterpret_cast<SkCanvas*>(
+    jobject canvasFinalizerObj = env->GetObjectField(canvasObj, gCanvasClassInfo.mFinalizer);
+    SkCanvas* previousCanvas = reinterpret_cast<SkCanvas*>(
           env->GetIntField(canvasObj, gCanvasClassInfo.mNativeCanvas));
-  env->SetIntField(canvasObj, gCanvasClassInfo.mNativeCanvas, (int)newCanvas);
-  env->SetIntField(canvasFinalizerObj, gCanvasFinalizerClassInfo.mNativeCanvas, (int)newCanvas);
-  SkSafeUnref(previousCanvas);
+    env->SetIntField(canvasObj, gCanvasClassInfo.mNativeCanvas, (int)newCanvas);
+    env->SetIntField(canvasFinalizerObj, gCanvasFinalizerClassInfo.mNativeCanvas, (int)newCanvas);
+    SkSafeUnref(previousCanvas);
 }
 
-static void android_view_TextureView_lockCanvas(JNIEnv* env, jobject,
+static jboolean android_view_TextureView_lockCanvas(JNIEnv* env, jobject,
         jint nativeWindow, jobject canvas, jobject dirtyRect) {
 
     if (!nativeWindow) {
-        return;
+        return false;
     }
 
     ANativeWindow_Buffer buffer;
@@ -154,7 +147,8 @@
     }
 
     sp<ANativeWindow> window((ANativeWindow*) nativeWindow);
-    native_window_lock(window.get(), &buffer, &rect);
+    int32_t status = native_window_lock(window.get(), &buffer, &rect);
+    if (status) return false;
 
     ssize_t bytesCount = buffer.stride * bytesPerPixel(buffer.format);
 
@@ -184,6 +178,8 @@
         INVOKEV(dirtyRect, gRectClassInfo.set,
                 int(rect.left), int(rect.top), int(rect.right), int(rect.bottom));
     }
+
+    return true;
 }
 
 static void android_view_TextureView_unlockCanvasAndPost(JNIEnv* env, jobject,
@@ -205,15 +201,12 @@
 const char* const kClassPathName = "android/view/TextureView";
 
 static JNINativeMethod gMethods[] = {
-    {   "nSetDefaultBufferSize", "(Landroid/graphics/SurfaceTexture;II)V",
-            (void*) android_view_TextureView_setDefaultBufferSize },
-
     {   "nCreateNativeWindow", "(Landroid/graphics/SurfaceTexture;)V",
             (void*) android_view_TextureView_createNativeWindow },
     {   "nDestroyNativeWindow", "()V",
             (void*) android_view_TextureView_destroyNativeWindow },
 
-    {   "nLockCanvas", "(ILandroid/graphics/Canvas;Landroid/graphics/Rect;)V",
+    {   "nLockCanvas", "(ILandroid/graphics/Canvas;Landroid/graphics/Rect;)Z",
             (void*) android_view_TextureView_lockCanvas },
     {   "nUnlockCanvasAndPost", "(ILandroid/graphics/Canvas;)V",
             (void*) android_view_TextureView_unlockCanvasAndPost },
@@ -241,7 +234,8 @@
     GET_FIELD_ID(gRectClassInfo.bottom, clazz, "bottom", "I");
 
     FIND_CLASS(clazz, "android/graphics/Canvas");
-    GET_FIELD_ID(gCanvasClassInfo.mFinalizer, clazz, "mFinalizer", "Landroid/graphics/Canvas$CanvasFinalizer;");
+    GET_FIELD_ID(gCanvasClassInfo.mFinalizer, clazz, "mFinalizer",
+            "Landroid/graphics/Canvas$CanvasFinalizer;");
     GET_FIELD_ID(gCanvasClassInfo.mNativeCanvas, clazz, "mNativeCanvas", "I");
     GET_FIELD_ID(gCanvasClassInfo.mSurfaceFormat, clazz, "mSurfaceFormat", "I");
 
diff --git a/core/jni/android_view_VelocityTracker.cpp b/core/jni/android_view_VelocityTracker.cpp
index c2fa3be..90ba2ba 100644
--- a/core/jni/android_view_VelocityTracker.cpp
+++ b/core/jni/android_view_VelocityTracker.cpp
@@ -20,8 +20,8 @@
 
 #include <android_runtime/AndroidRuntime.h>
 #include <utils/Log.h>
-#include <androidfw/Input.h>
-#include <androidfw/VelocityTracker.h>
+#include <input/Input.h>
+#include <input/VelocityTracker.h>
 #include "android_view_MotionEvent.h"
 
 #include <ScopedUtfChars.h>
diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
index 8d6fab4..bf5accd 100644
--- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
+++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
@@ -20,7 +20,7 @@
 #include <android_runtime/AndroidRuntime.h>
 
 #include <utils/Log.h>
-#include <utils/ZipFileRO.h>
+#include <androidfw/ZipFileRO.h>
 #include <ScopedUtfChars.h>
 
 #include <zlib.h>
diff --git a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
index 0906593..ec19f0a 100644
--- a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
+++ b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
@@ -21,7 +21,6 @@
 #include <sys/types.h>
 
 #include <android_runtime/AndroidRuntime.h>
-#include <cutils/logger.h>
 #include <jni.h>
 
 #include <ScopedUtfChars.h>
diff --git a/core/jni/com_google_android_gles_jni_EGLImpl.cpp b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
index 37330ec..50b3302 100644
--- a/core/jni/com_google_android_gles_jni_EGLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
@@ -258,7 +258,6 @@
     case SkBitmap::kARGB_8888_Config:   return PIXEL_FORMAT_RGBA_8888;
     case SkBitmap::kARGB_4444_Config:   return PIXEL_FORMAT_RGBA_4444;
     case SkBitmap::kRGB_565_Config:     return PIXEL_FORMAT_RGB_565;
-    case SkBitmap::kA8_Config:          return PIXEL_FORMAT_A_8;
     default:                            return PIXEL_FORMAT_NONE;
     }
 }
@@ -352,10 +351,9 @@
                 "Make sure the SurfaceTexture is valid");
         return 0;
     }
-    
-    sp<GLConsumer> glConsumer(SurfaceTexture_getSurfaceTexture(_env, native_window));
 
-    window = new Surface(glConsumer->getBufferQueue());
+    sp<IGraphicBufferProducer> producer(SurfaceTexture_getProducer(_env, native_window));
+    window = new Surface(producer, true);
     if (window == NULL)
         goto not_valid_surface;
 
diff --git a/core/jni/com_google_android_gles_jni_GLImpl.cpp b/core/jni/com_google_android_gles_jni_GLImpl.cpp
index badd697..b0c26c51 100644
--- a/core/jni/com_google_android_gles_jni_GLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_GLImpl.cpp
@@ -1181,7 +1181,7 @@
   (JNIEnv *_env, jobject _this) {
     GLenum _returnValue;
     _returnValue = glGetError();
-    return _returnValue;
+    return (jint)_returnValue;
 }
 
 /* void glGetIntegerv ( GLenum pname, GLint *params ) */
@@ -4017,7 +4017,7 @@
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
     }
-    return _returnValue;
+    return (jint)_returnValue;
 }
 
 /* GLbitfield glQueryMatrixxOES ( GLfixed *mantissa, GLint *exponent ) */
@@ -4074,7 +4074,7 @@
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
     }
-    return _returnValue;
+    return (jint)_returnValue;
 }
 
 /* void glBindBuffer ( GLenum target, GLuint buffer ) */
@@ -4359,7 +4359,7 @@
         (GLint)size,
         (GLenum)type,
         (GLsizei)stride,
-        (const GLvoid *)offset
+        (GLvoid *)offset
     );
 }
 
@@ -4460,7 +4460,7 @@
         (GLenum)mode,
         (GLsizei)count,
         (GLenum)type,
-        (const GLvoid *)offset
+        (GLvoid *)offset
     );
     if (_exception) {
         jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -6067,7 +6067,7 @@
     _returnValue = glIsBuffer(
         (GLuint)buffer
     );
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* GLboolean glIsEnabled ( GLenum cap ) */
@@ -6078,7 +6078,7 @@
     _returnValue = glIsEnabled(
         (GLenum)cap
     );
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* GLboolean glIsTexture ( GLuint texture ) */
@@ -6089,7 +6089,7 @@
     _returnValue = glIsTexture(
         (GLuint)texture
     );
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* void glNormalPointer ( GLenum type, GLsizei stride, GLint offset ) */
@@ -6099,7 +6099,7 @@
     glNormalPointer(
         (GLenum)type,
         (GLsizei)stride,
-        (const GLvoid *)offset
+        (GLvoid *)offset
     );
 }
 
@@ -6326,7 +6326,7 @@
         (GLint)size,
         (GLenum)type,
         (GLsizei)stride,
-        (const GLvoid *)offset
+        (GLvoid *)offset
     );
 }
 
@@ -6756,7 +6756,7 @@
         (GLint)size,
         (GLenum)type,
         (GLsizei)stride,
-        (const GLvoid *)offset
+        (GLvoid *)offset
     );
 }
 
@@ -7196,7 +7196,7 @@
         (GLint)size,
         (GLenum)type,
         (GLsizei)stride,
-        (const GLvoid *)offset
+        (GLvoid *)offset
     );
 }
 
@@ -7232,7 +7232,7 @@
         (GLint)size,
         (GLenum)type,
         (GLsizei)stride,
-        (const GLvoid *)offset
+        (GLvoid *)offset
     );
 }
 
@@ -7325,7 +7325,7 @@
     _returnValue = glCheckFramebufferStatusOES(
         (GLint)target
     );
-    return _returnValue;
+    return (jint)_returnValue;
 }
 
 /* void glDeleteFramebuffersOES ( GLint n, GLuint *framebuffers ) */
@@ -8166,7 +8166,7 @@
     _returnValue = glIsFramebufferOES(
         (GLint)framebuffer
     );
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* GLboolean glIsRenderbufferOES ( GLint renderbuffer ) */
@@ -8182,7 +8182,7 @@
     _returnValue = glIsRenderbufferOES(
         (GLint)renderbuffer
     );
-    return _returnValue;
+    return (jboolean)_returnValue;
 }
 
 /* void glRenderbufferStorageOES ( GLint target, GLint internalformat, GLint width, GLint height ) */
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index c23012a..499a930 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -29,8 +29,10 @@
     <protected-broadcast android:name="android.intent.action.SCREEN_OFF" />
     <protected-broadcast android:name="android.intent.action.SCREEN_ON" />
     <protected-broadcast android:name="android.intent.action.USER_PRESENT" />
+    <protected-broadcast android:name="android.intent.action.TIME_SET" />
     <protected-broadcast android:name="android.intent.action.TIME_TICK" />
     <protected-broadcast android:name="android.intent.action.TIMEZONE_CHANGED" />
+    <protected-broadcast android:name="android.intent.action.DATE_CHANGED" />
     <protected-broadcast android:name="android.intent.action.BOOT_COMPLETED" />
     <protected-broadcast android:name="android.intent.action.PACKAGE_INSTALL" />
     <protected-broadcast android:name="android.intent.action.PACKAGE_ADDED" />
@@ -64,6 +66,9 @@
     <protected-broadcast android:name="android.intent.action.MASTER_CLEAR_NOTIFICATION" />
     <protected-broadcast android:name="android.intent.action.USER_ADDED" />
     <protected-broadcast android:name="android.intent.action.USER_REMOVED" />
+    <protected-broadcast android:name="android.intent.action.USER_STARTING" />
+    <protected-broadcast android:name="android.intent.action.USER_STARTED" />
+    <protected-broadcast android:name="android.intent.action.USER_STOPPING" />
     <protected-broadcast android:name="android.intent.action.USER_STOPPED" />
     <protected-broadcast android:name="android.intent.action.USER_BACKGROUND" />
     <protected-broadcast android:name="android.intent.action.USER_FOREGROUND" />
@@ -89,6 +94,8 @@
     <protected-broadcast android:name="android.bluetooth.adapter.action.DISCOVERY_FINISHED" />
     <protected-broadcast android:name="android.bluetooth.adapter.action.LOCAL_NAME_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED" />
+    <protected-broadcast android:name="android.bluetooth.device.action.UUID" />
+    <protected-broadcast android:name="android.bluetooth.device.action.ALIAS_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.device.action.FOUND" />
     <protected-broadcast android:name="android.bluetooth.device.action.DISAPPEARED" />
     <protected-broadcast android:name="android.bluetooth.device.action.CLASS_CHANGED" />
@@ -101,6 +108,10 @@
     <protected-broadcast android:name="android.bluetooth.device.action.PAIRING_REQUEST" />
     <protected-broadcast android:name="android.bluetooth.device.action.PAIRING_CANCEL" />
     <protected-broadcast android:name="android.bluetooth.device.action.CONNECTION_ACCESS_REPLY" />
+    <protected-broadcast android:name="android.bluetooth.device.action.CONNECTION_ACCESS_CANCEL" />
+    <protected-broadcast android:name="android.bluetooth.device.action.CONNECTION_ACCESS_REQUEST" />
+    <protected-broadcast android:name="android.bluetooth.devicepicker.action.LAUNCH" />
+    <protected-broadcast android:name="android.bluetooth.devicepicker.action.DEVICE_SELECTED" />
     <protected-broadcast
         android:name="android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED" />
     <protected-broadcast
@@ -114,7 +125,30 @@
     <protected-broadcast
         android:name="android.bluetooth.input.profile.action.CONNECTION_STATE_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.pan.profile.action.CONNECTION_STATE_CHANGED" />
+    <protected-broadcast android:name="android.bluetooth.pbap.intent.action.PBAP_STATE_CHANGED" />
+    <protected-broadcast android:name="android.btopp.intent.action.INCOMING_FILE_NOTIFICATION" />
+    <protected-broadcast android:name="android.btopp.intent.action.BT_OPP_HANDOVER_STARTED" />
+    <protected-broadcast android:name="android.btopp.intent.action.TRANSFER_COMPLETE" />
+    <protected-broadcast android:name="android.btopp.intent.action.USER_CONFIRMATION_TIMEOUT" />
+    <protected-broadcast android:name="android.btopp.intent.action.BT_OPP_TRANSFER_PROGRESS" />
+    <protected-broadcast android:name="android.btopp.intent.action.LIST" />
+    <protected-broadcast android:name="android.btopp.intent.action.OPEN_OUTBOUND" />
+    <protected-broadcast android:name="android.btopp.intent.action.HIDE_COMPLETE" />
+    <protected-broadcast android:name="android.btopp.intent.action.CONFIRM" />
+    <protected-broadcast android:name="android.btopp.intent.action.HIDE" />
+    <protected-broadcast android:name="android.btopp.intent.action.BT_OPP_TRANSFER_DONE" />
+    <protected-broadcast android:name="android.btopp.intent.action.RETRY" />
+    <protected-broadcast android:name="android.btopp.intent.action.OPEN" />
+    <protected-broadcast android:name="android.btopp.intent.action.OPEN_INBOUND" />
+    <protected-broadcast android:name="com.android.bluetooth.pbap.authchall" />
+    <protected-broadcast android:name="com.android.bluetooth.pbap.userconfirmtimeout" />
+    <protected-broadcast android:name="com.android.bluetooth.pbap.authresponse" />
+    <protected-broadcast android:name="com.android.bluetooth.pbap.authcancelled" />
 
     <protected-broadcast android:name="android.hardware.display.action.WIFI_DISPLAY_STATUS_CHANGED" />
 
@@ -131,12 +165,34 @@
     <protected-broadcast android:name="android.intent.action.USB_AUDIO_ACCESSORY_PLUG" />
     <protected-broadcast android:name="android.intent.action.USB_AUDIO_DEVICE_PLUG" />
 
+    <protected-broadcast android:name="android.media.AUDIO_BECOMING_NOISY" />
+    <protected-broadcast android:name="android.media.RINGER_MODE_CHANGED" />
+    <protected-broadcast android:name="android.media.VIBRATE_SETTING_CHANGED" />
+    <protected-broadcast android:name="android.media.VOLUME_CHANGED_ACTION" />
+    <protected-broadcast android:name="android.media.MASTER_VOLUME_CHANGED_ACTION" />
+    <protected-broadcast android:name="android.media.MASTER_MUTE_CHANGED_ACTION" />
+    <protected-broadcast android:name="android.media.SCO_AUDIO_STATE_CHANGED" />
+    <protected-broadcast android:name="android.media.ACTION_SCO_AUDIO_STATE_UPDATED" />
+
+    <protected-broadcast android:name="android.intent.action.MEDIA_REMOVED" />
+    <protected-broadcast android:name="android.intent.action.MEDIA_UNMOUNTED" />
+    <protected-broadcast android:name="android.intent.action.MEDIA_CHECKING" />
+    <protected-broadcast android:name="android.intent.action.MEDIA_NOFS" />
+    <protected-broadcast android:name="android.intent.action.MEDIA_MOUNTED" />
+    <protected-broadcast android:name="android.intent.action.MEDIA_SHARED" />
+    <protected-broadcast android:name="android.intent.action.MEDIA_UNSHARED" />
+    <protected-broadcast android:name="android.intent.action.MEDIA_BAD_REMOVAL" />
+    <protected-broadcast android:name="android.intent.action.MEDIA_UNMOUNTABLE" />
+    <protected-broadcast android:name="android.intent.action.MEDIA_EJECT" />
+
     <protected-broadcast android:name="android.net.conn.CONNECTIVITY_CHANGE" />
     <protected-broadcast android:name="android.net.conn.CONNECTIVITY_CHANGE_IMMEDIATE" />
     <protected-broadcast android:name="android.net.conn.DATA_ACTIVITY_CHANGE" />
     <protected-broadcast android:name="android.net.conn.BACKGROUND_DATA_SETTING_CHANGED" />
     <protected-broadcast android:name="android.net.conn.CAPTIVE_PORTAL_TEST_COMPLETED" />
 
+    <protected-broadcast android:name="android.net.nsd.STATE_CHANGED" />
+
     <protected-broadcast android:name="android.nfc.action.LLCP_LINK_STATE_CHANGED" />
     <protected-broadcast android:name="com.android.nfc_extras.action.RF_FIELD_ON_DETECTED" />
     <protected-broadcast android:name="com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED" />
@@ -173,6 +229,9 @@
     <protected-broadcast android:name="android.net.wifi.p2p.PERSISTENT_GROUPS_CHANGED" />
     <protected-broadcast android:name="android.net.conn.TETHER_STATE_CHANGED" />
     <protected-broadcast android:name="android.net.conn.INET_CONDITION_ACTION" />
+    <protected-broadcast android:name="android.net.conn.NETWORK_CONDITIONS_MEASURED" />
+    <protected-brodcast
+            android:name="android.net.ConnectivityService.action.PKT_CNT_SAMPLE_INTERVAL_ELAPSED" />
     <protected-broadcast android:name="android.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE" />
     <protected-broadcast android:name="android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE" />
     <protected-broadcast android:name="android.intent.action.AIRPLANE_MODE" />
@@ -182,6 +241,16 @@
     <protected-broadcast android:name="android.intent.action.ACTION_IDLE_MAINTENANCE_START" />
     <protected-broadcast android:name="android.intent.action.ACTION_IDLE_MAINTENANCE_END" />
 
+    <protected-broadcast android:name="android.intent.action.HDMI_PLUGGED" />
+
+    <protected-broadcast android:name="android.intent.action.PHONE_STATE" />
+
+    <protected-broadcast android:name="android.location.GPS_ENABLED_CHANGE" />
+    <protected-broadcast android:name="android.location.PROVIDERS_CHANGED" />
+    <protected-broadcast android:name="android.location.MODE_CHANGED" />
+    <protected-broadcast android:name="android.location.GPS_FIX_CHANGE" />
+    <protected-broadcast android:name="android.net.proxy.PAC_REFRESH" />
+
     <protected-broadcast
         android:name="com.android.server.connectivityservice.CONNECTED_TO_PROVISIONING_NETWORK_ACTION" />
 
@@ -830,6 +899,13 @@
         android:label="@string/permlab_wakeLock"
         android:description="@string/permdesc_wakeLock" />
 
+    <!-- Allows using the device's IR transmitter, if available -->
+    <permission android:name="android.permission.TRANSMIT_IR"
+        android:permissionGroup="android.permission-group.AFFECTS_BATTERY"
+        android:protectionLevel="normal"
+        android:label="@string/permlab_transmitIr"
+        android:description="@string/permdesc_transmitIr" />
+
     <!-- ==================================================== -->
     <!-- Permissions related to changing audio settings   -->
     <!-- ==================================================== -->
@@ -1043,15 +1119,15 @@
     <!-- Allows an application to read from external storage.
          <p>Any app that declares the {@link #WRITE_EXTERNAL_STORAGE} permission is implicitly
          granted this permission.</p>
-         <p>Currently, this permission is not enforced and all apps still have access to read from
-         external storage without this permission. That will change in a future release and apps
-         will require this permission to read from external storage. So if your
-         app reads from the external storage, you should add this permission to your app now
-         to ensure that it continues to work on future versions of Android.</p>
-         <p>You can test your app with the permission enforced by either running your app on the
-         Android Emulator when running Android 4.1 or higher, or enabling <em>Protect USB
+         <p>This permission is enforced starting in API level 19.  Before API level 19, this
+         permission is not enforced and all apps still have access to read from external storage.
+         You can test your app with the permission enforced by enabling <em>Protect USB
          storage</em> under Developer options in the Settings app on a device running Android 4.1 or
          higher.</p>
+         <p>Also starting in API level 19, this permission is <em>not</em> required to
+         read/write files in your application-specific directories returned by
+         {@link android.content.Context#getExternalFilesDir} and
+         {@link android.content.Context#getExternalCacheDir}.
          <p class="note"><strong>Note:</strong> If <em>both</em> your <a
          href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
          minSdkVersion}</a> and <a
@@ -1074,7 +1150,11 @@
          targetSdkVersion}</a> values are set to 3 or lower, the system implicitly
          grants your app this permission. If you don't need this permission, be sure your <a
          href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
-         targetSdkVersion}</a> is 4 or higher. -->
+         targetSdkVersion}</a> is 4 or higher.
+         <p>Starting in API level 19, this permission is <em>not</em> required to
+         read/write files in your application-specific directories returned by
+         {@link android.content.Context#getExternalFilesDir} and
+         {@link android.content.Context#getExternalCacheDir}. -->
     <permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
         android:permissionGroup="android.permission-group.STORAGE"
         android:label="@string/permlab_sdcardWrite"
@@ -1089,6 +1169,14 @@
         android:description="@string/permdesc_mediaStorageWrite"
         android:protectionLevel="signature|system" />
 
+    <!-- Allows an application to manage access to documents, usually as part
+         of a document picker. -->
+    <permission android:name="android.permission.MANAGE_DOCUMENTS"
+        android:permissionGroup="android.permission-group.STORAGE"
+        android:label="@string/permlab_manageDocs"
+        android:description="@string/permdesc_manageDocs"
+        android:protectionLevel="signature|system" />
+
     <!-- ================================== -->
     <!-- Permissions for screenlock         -->
     <!-- ================================== -->
@@ -1181,6 +1269,13 @@
         android:label="@string/permlab_removeTasks"
         android:description="@string/permdesc_removeTasks" />
 
+    <!-- @hide Allows an application to create/manage/remove stacks -->
+    <permission android:name="android.permission.MANAGE_ACTIVITY_STACKS"
+        android:permissionGroup="android.permission-group.APP_INFO"
+        android:protectionLevel="signature"
+        android:label="@string/permlab_manageActivityStacks"
+        android:description="@string/permdesc_manageActivityStacks" />
+
     <!-- Allows an application to start any activity, regardless of permission
          protection or exported state. @hide -->
     <permission android:name="android.permission.START_ANY_ACTIVITY"
@@ -1564,6 +1659,14 @@
         android:label="@string/permlab_anyCodecForPlayback"
         android:description="@string/permdesc_anyCodecForPlayback" />
 
+    <!-- Allows an application to install and/or uninstall CA certificates on
+         behalf of the user.
+         @hide -->
+    <permission android:name="android.permission.MANAGE_CA_CERTIFICATES"
+        android:protectionLevel="signature|system"
+        android:label="@string/permlab_manageCaCertificates"
+        android:description="@string/permdesc_manageCaCertificates" />
+
     <!-- ========================================= -->
     <!-- Permissions for special development tools -->
     <!-- ========================================= -->
@@ -1809,6 +1912,27 @@
         android:description="@string/permdesc_bindAccessibilityService"
         android:protectionLevel="signature" />
 
+    <!-- Must be required by a {@link android.printservice.PrintService},
+         to ensure that only the system can bind to it. -->
+    <permission android:name="android.permission.BIND_PRINT_SERVICE"
+        android:label="@string/permlab_bindPrintService"
+        android:description="@string/permdesc_bindPrintService"
+        android:protectionLevel="signature" />
+
+    <!-- Must be required by a {@link android.nfc.cardemulation.HostApduService}
+         or {@link android.nfc.cardemulation.OffHostApduService} to ensure that only
+         the system can bind to it. -->
+    <permission android:name="android.permission.BIND_NFC_SERVICE"
+        android:label="@string/permlab_bindNfcService"
+        android:description="@string/permdesc_bindNfcService"
+        android:protectionLevel="signature" />
+
+    <!-- Must be required by the PrintSpooler to ensure that only the system can bind to it. -->
+    <permission android:name="android.permission.BIND_PRINT_SPOOLER_SERVICE"
+        android:label="@string/permlab_bindPrintSpoolerService"
+        android:description="@string/permdesc_bindPrintSpoolerService"
+        android:protectionLevel="signature" />
+
     <!-- Must be required by a TextService (e.g. SpellCheckerService)
          to ensure that only the system can bind to it. -->
     <permission android:name="android.permission.BIND_TEXT_SERVICE"
@@ -1816,7 +1940,7 @@
         android:description="@string/permdesc_bindTextService"
         android:protectionLevel="signature" />
 
-    <!-- Must be required by an {@link android.net.VpnService},
+    <!-- Must be required by a {@link android.net.VpnService},
          to ensure that only the system can bind to it. -->
     <permission android:name="android.permission.BIND_VPN_SERVICE"
         android:label="@string/permlab_bindVpnService"
@@ -1837,6 +1961,13 @@
         android:description="@string/permdesc_bindDeviceAdmin"
         android:protectionLevel="signature" />
 
+    <!-- Required to add or remove another application as a device admin.
+         <p/>Not for use by third-party applications. -->
+    <permission android:name="android.permission.MANAGE_DEVICE_ADMINS"
+        android:label="@string/permlab_manageDeviceAdmins"
+        android:description="@string/permdesc_manageDeviceAdmins"
+        android:protectionLevel="signature|system" />
+
     <!-- Allows low-level access to setting the orientation (actually
          rotation) of the screen.
          <p>Not for use by third-party applications. -->
@@ -1940,6 +2071,35 @@
         android:description="@string/permdesc_controlWifiDisplay"
         android:protectionLevel="signature" />
 
+    <!-- Allows an application to capture audio output.
+         <p>Not for use by third-party applications.</p> -->
+    <permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT"
+        android:label="@string/permlab_captureAudioOutput"
+        android:description="@string/permdesc_captureAudioOutput"
+        android:protectionLevel="signature|system" />
+
+    <!-- Allows an application to capture audio for hotword detection.
+         <p>Not for use by third-party applications.</p>
+         @hide -->
+    <permission android:name="android.permission.CAPTURE_AUDIO_HOTWORD"
+        android:label="@string/permlab_captureAudioHotword"
+        android:description="@string/permdesc_captureAudioHotword"
+        android:protectionLevel="signature|system" />
+
+    <!-- Allows an application to capture video output.
+         <p>Not for use by third-party applications.</p> -->
+    <permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT"
+        android:label="@string/permlab_captureVideoOutput"
+        android:description="@string/permdesc_captureVideoOutput"
+        android:protectionLevel="signature|system" />
+
+    <!-- Allows an application to capture secure video output.
+         <p>Not for use by third-party applications.</p> -->
+    <permission android:name="android.permission.CAPTURE_SECURE_VIDEO_OUTPUT"
+        android:label="@string/permlab_captureSecureVideoOutput"
+        android:description="@string/permdesc_captureSecureVideoOutput"
+        android:protectionLevel="signature|system" />
+
     <!-- Required to be able to disable the device (very dangerous!).
     <p>Not for use by third-party applications.. -->
     <permission android:name="android.permission.BRICK"
@@ -2195,6 +2355,16 @@
         android:description="@string/permdesc_modifyNetworkAccounting"
         android:protectionLevel="signature|system" />
 
+    <!-- Allows an application to mark traffic as from another user for per user routing.
+         Used by system wide services like media server that execute delegated network connections
+         for users.
+         @hide
+    -->
+    <permission android:name="android.permission.MARK_NETWORK_SOCKET"
+        android:label="@string/permlab_markNetworkSocket"
+        android:description="@string/permdesc_markNetworkSocket"
+        android:protectionLevel="signature|system" />
+
     <!-- C2DM permission.
          @hide Used internally.
      -->
@@ -2252,6 +2422,20 @@
         android:description="@string/permdesc_accessNotifications"
         android:protectionLevel="signature|system" />
 
+    <!-- Allows access to keyguard secure storage.  Only allowed for system processes.
+        @hide -->
+    <permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE"
+        android:protectionLevel="signature"
+        android:label="@string/permlab_access_keyguard_secure_storage"
+        android:description="@string/permdesc_access_keyguard_secure_storage" />
+
+    <!-- Allows an application to control keyguard.  Only allowed for system processes.
+        @hide -->
+    <permission android:name="android.permission.CONTROL_KEYGUARD"
+        android:protectionLevel="signature"
+        android:label="@string/permlab_control_keyguard"
+        android:description="@string/permdesc_control_keyguard" />
+
     <!-- Must be required by an {@link
          android.service.notification.NotificationListenerService},
          to ensure that only the system can bind to it. -->
@@ -2260,6 +2444,21 @@
         android:description="@string/permdesc_bindNotificationListenerService"
         android:protectionLevel="signature" />
 
+    <!-- Allows an application to call into a carrier setup flow. It is up to the
+         carrier setup application to enforce that this permission is required
+         @hide This is not a third-party API (intended for OEMs and system apps). -->
+    <permission android:name="android.permission.INVOKE_CARRIER_SETUP"
+        android:label="@string/permlab_invokeCarrierSetup"
+        android:description="@string/permdesc_invokeCarrierSetup"
+        android:protectionLevel="signature|system" />
+
+    <!-- Allows an application to listen for network condition observations.
+         @hide This is not a third-party API (intended for system apps). -->
+    <permission android:name="android.permission.ACCESS_NETWORK_CONDITIONS"
+        android:label="@string/permlab_accessNetworkConditions"
+        android:description="@string/permdesc_accessNetworkConditions"
+        android:protectionLevel="signature|system" />
+
     <!-- The system process is explicitly the only one allowed to launch the
          confirmation UI for full backup/restore -->
     <uses-permission android:name="android.permission.CONFIRM_FULL_BACKUP"/>
@@ -2326,8 +2525,7 @@
         <activity android:name="android.accounts.CantAddAccountActivity"
                 android:excludeFromRecents="true"
                 android:exported="true"
-                android:theme="@android:style/Theme.Holo.Dialog"
-                android:label="@string/error_message_title"
+                android:theme="@android:style/Theme.Holo.Dialog.NoActionBar"
                 android:process=":ui">
         </activity>
 
@@ -2363,6 +2561,17 @@
                 android:process=":ui">
         </activity>
 
+        <activity android:name="com.android.internal.app.RestrictionsPinActivity"
+                android:theme="@style/Theme.Holo.Dialog.Alert"
+                android:excludeFromRecents="true"
+                android:windowSoftInputMode="adjustPan"
+                android:process=":ui">
+            <intent-filter android:priority="100">
+                <action android:name="android.intent.action.RESTRICTIONS_CHALLENGE" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
         <receiver android:name="com.android.server.BootReceiver"
                 android:primaryUserOnly="true">
             <intent-filter>
@@ -2407,9 +2616,9 @@
         </receiver>
 
         <receiver android:name="com.android.server.MasterClearReceiver"
-            android:permission="android.permission.MASTER_CLEAR"
-            android:priority="100" >
-            <intent-filter>
+            android:permission="android.permission.MASTER_CLEAR">
+            <intent-filter
+                    android:priority="100" >
                 <!-- For Checkin, Settings, etc.: action=MASTER_CLEAR -->
                 <action android:name="android.intent.action.MASTER_CLEAR" />
 
diff --git a/core/res/res/anim/keyguard_security_fade_in.xml b/core/res/res/anim/keyguard_security_fade_in.xml
deleted file mode 100644
index 6293432..0000000
--- a/core/res/res/anim/keyguard_security_fade_in.xml
+++ /dev/null
@@ -1,22 +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.
--->
-
-<alpha xmlns:android="http://schemas.android.com/apk/res/android"
-    android:interpolator="@android:interpolator/decelerate_quad"
-    android:fromAlpha="0.0" android:toAlpha="1.0"
-    android:duration="@*android:integer/kg_security_fade_duration" />
-
-
diff --git a/core/res/res/anim/keyguard_security_fade_out.xml b/core/res/res/anim/keyguard_security_fade_out.xml
deleted file mode 100644
index 4ab0229..0000000
--- a/core/res/res/anim/keyguard_security_fade_out.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.
--->
-<alpha xmlns:android="http://schemas.android.com/apk/res/android"
-    android:interpolator="@android:interpolator/accelerate_quad"
-    android:fromAlpha="1.0"
-    android:toAlpha="0.0"
-    android:duration="@*android:integer/kg_security_fade_duration"
-/>
diff --git a/core/res/res/anim/toast_bar_enter.xml b/core/res/res/anim/toast_bar_enter.xml
new file mode 100644
index 0000000..5c0dfcf
--- /dev/null
+++ b/core/res/res/anim/toast_bar_enter.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+** Copyright 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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:shareInterpolator="false">
+    <translate android:fromYDelta="10%" android:toYDelta="0"
+            android:interpolator="@interpolator/decelerate_quint"
+            android:duration="@android:integer/config_shortAnimTime"/>
+    <alpha android:fromAlpha="0.5" android:toAlpha="1.0"
+            android:interpolator="@interpolator/decelerate_cubic"
+            android:duration="@android:integer/config_shortAnimTime" />
+</set>
diff --git a/core/res/res/anim/toast_bar_exit.xml b/core/res/res/anim/toast_bar_exit.xml
new file mode 100644
index 0000000..4e3b7da
--- /dev/null
+++ b/core/res/res/anim/toast_bar_exit.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+** Copyright 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.
+*/
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shareInterpolator="false">
+    <translate android:fromYDelta="0" android:toYDelta="10%"
+            android:interpolator="@interpolator/accelerate_quint"
+            android:duration="@android:integer/config_shortAnimTime"/>
+    <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+            android:interpolator="@interpolator/accelerate_cubic"
+            android:duration="@android:integer/config_shortAnimTime"/>
+</set>
diff --git a/core/res/res/drawable-hdpi/activity_picker_bg_activated.9.png b/core/res/res/drawable-hdpi/activity_picker_bg_activated.9.png
deleted file mode 100644
index e591a7b..0000000
--- a/core/res/res/drawable-hdpi/activity_picker_bg_activated.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/activity_picker_bg_focused.9.png b/core/res/res/drawable-hdpi/activity_picker_bg_focused.9.png
deleted file mode 100644
index ea27290d..0000000
--- a/core/res/res/drawable-hdpi/activity_picker_bg_focused.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_ab_back_holo_dark.png b/core/res/res/drawable-hdpi/ic_ab_back_holo_dark_am.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_ab_back_holo_dark.png
rename to core/res/res/drawable-hdpi/ic_ab_back_holo_dark_am.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_ab_back_holo_light.png b/core/res/res/drawable-hdpi/ic_ab_back_holo_light_am.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_ab_back_holo_light.png
rename to core/res/res/drawable-hdpi/ic_ab_back_holo_light_am.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_audio_notification.png b/core/res/res/drawable-hdpi/ic_audio_notification_am.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_audio_notification.png
rename to core/res/res/drawable-hdpi/ic_audio_notification_am.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_audio_notification_mute.png b/core/res/res/drawable-hdpi/ic_audio_notification_mute_am.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_audio_notification_mute.png
rename to core/res/res/drawable-hdpi/ic_audio_notification_mute_am.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_audio_phone.png b/core/res/res/drawable-hdpi/ic_audio_phone_am.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_audio_phone.png
rename to core/res/res/drawable-hdpi/ic_audio_phone_am.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_audio_ring_notif.png b/core/res/res/drawable-hdpi/ic_audio_ring_notif_am.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_audio_ring_notif.png
rename to core/res/res/drawable-hdpi/ic_audio_ring_notif_am.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_audio_ring_notif_mute.png b/core/res/res/drawable-hdpi/ic_audio_ring_notif_mute_am.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_audio_ring_notif_mute.png
rename to core/res/res/drawable-hdpi/ic_audio_ring_notif_mute_am.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_audio_ring_notif_vibrate.png b/core/res/res/drawable-hdpi/ic_audio_ring_notif_vibrate_am.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_audio_ring_notif_vibrate.png
rename to core/res/res/drawable-hdpi/ic_audio_ring_notif_vibrate_am.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_audio_vol.png b/core/res/res/drawable-hdpi/ic_audio_vol_am.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_audio_vol.png
rename to core/res/res/drawable-hdpi/ic_audio_vol_am.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_audio_vol_mute.png b/core/res/res/drawable-hdpi/ic_audio_vol_mute_am.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_audio_vol_mute.png
rename to core/res/res/drawable-hdpi/ic_audio_vol_mute_am.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lock_airplane_mode_off.png b/core/res/res/drawable-hdpi/ic_lock_airplane_mode_off_am.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_lock_airplane_mode_off.png
rename to core/res/res/drawable-hdpi/ic_lock_airplane_mode_off_am.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_cc.png b/core/res/res/drawable-hdpi/ic_menu_cc_am.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_menu_cc.png
rename to core/res/res/drawable-hdpi/ic_menu_cc_am.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/kg_add_widget.png b/core/res/res/drawable-hdpi/kg_add_widget.png
deleted file mode 100644
index 68971a5..0000000
--- a/core/res/res/drawable-hdpi/kg_add_widget.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/kg_security_lock_focused.png b/core/res/res/drawable-hdpi/kg_security_lock_focused.png
deleted file mode 100644
index abcf683..0000000
--- a/core/res/res/drawable-hdpi/kg_security_lock_focused.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/kg_security_lock_normal.png b/core/res/res/drawable-hdpi/kg_security_lock_normal.png
deleted file mode 100644
index e8cff24..0000000
--- a/core/res/res/drawable-hdpi/kg_security_lock_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/kg_security_lock_pressed.png b/core/res/res/drawable-hdpi/kg_security_lock_pressed.png
deleted file mode 100644
index 3214dcb..0000000
--- a/core/res/res/drawable-hdpi/kg_security_lock_pressed.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/popup_inline_error_above.9.png b/core/res/res/drawable-hdpi/popup_inline_error_above_am.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/popup_inline_error_above.9.png
rename to core/res/res/drawable-hdpi/popup_inline_error_above_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/popup_inline_error_above_holo_dark.9.png b/core/res/res/drawable-hdpi/popup_inline_error_above_holo_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/popup_inline_error_above_holo_dark.9.png
rename to core/res/res/drawable-hdpi/popup_inline_error_above_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/popup_inline_error_above_holo_light.9.png b/core/res/res/drawable-hdpi/popup_inline_error_above_holo_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/popup_inline_error_above_holo_light.9.png
rename to core/res/res/drawable-hdpi/popup_inline_error_above_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/popup_inline_error.9.png b/core/res/res/drawable-hdpi/popup_inline_error_am.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/popup_inline_error.9.png
rename to core/res/res/drawable-hdpi/popup_inline_error_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/popup_inline_error_holo_dark.9.png b/core/res/res/drawable-hdpi/popup_inline_error_holo_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/popup_inline_error_holo_dark.9.png
rename to core/res/res/drawable-hdpi/popup_inline_error_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/popup_inline_error_holo_light.9.png b/core/res/res/drawable-hdpi/popup_inline_error_holo_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/popup_inline_error_holo_light.9.png
rename to core/res/res/drawable-hdpi/popup_inline_error_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_focused_dark.9.png b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_focused_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/quickcontact_badge_overlay_focused_dark.9.png
rename to core/res/res/drawable-hdpi/quickcontact_badge_overlay_focused_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_focused_light.9.png b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_focused_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/quickcontact_badge_overlay_focused_light.9.png
rename to core/res/res/drawable-hdpi/quickcontact_badge_overlay_focused_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_dark.9.png b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_dark.9.png
rename to core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_light.9.png b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_light.9.png
rename to core/res/res/drawable-hdpi/quickcontact_badge_overlay_normal_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_dark.9.png b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_dark.9.png
rename to core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_light.9.png b/core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_light.9.png
rename to core/res/res/drawable-hdpi/quickcontact_badge_overlay_pressed_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_default_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_ab_default_holo_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/spinner_ab_default_holo_dark.9.png
rename to core/res/res/drawable-hdpi/spinner_ab_default_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_default_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_ab_default_holo_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/spinner_ab_default_holo_light.9.png
rename to core/res/res/drawable-hdpi/spinner_ab_default_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/spinner_ab_disabled_holo_dark.9.png
rename to core/res/res/drawable-hdpi/spinner_ab_disabled_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_ab_disabled_holo_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/spinner_ab_disabled_holo_light.9.png
rename to core/res/res/drawable-hdpi/spinner_ab_disabled_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_ab_focused_holo_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/spinner_ab_focused_holo_dark.9.png
rename to core/res/res/drawable-hdpi/spinner_ab_focused_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_focused_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_ab_focused_holo_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/spinner_ab_focused_holo_light.9.png
rename to core/res/res/drawable-hdpi/spinner_ab_focused_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/spinner_ab_pressed_holo_dark.9.png
rename to core/res/res/drawable-hdpi/spinner_ab_pressed_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_ab_pressed_holo_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/spinner_ab_pressed_holo_light.9.png
rename to core/res/res/drawable-hdpi/spinner_ab_pressed_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_default_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_default_holo_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/spinner_default_holo_dark.9.png
rename to core/res/res/drawable-hdpi/spinner_default_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_default_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_default_holo_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/spinner_default_holo_light.9.png
rename to core/res/res/drawable-hdpi/spinner_default_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_disabled_holo_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/spinner_disabled_holo_dark.9.png
rename to core/res/res/drawable-hdpi/spinner_disabled_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_disabled_holo_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/spinner_disabled_holo_light.9.png
rename to core/res/res/drawable-hdpi/spinner_disabled_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_focused_holo_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/spinner_focused_holo_dark.9.png
rename to core/res/res/drawable-hdpi/spinner_focused_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_focused_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_focused_holo_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/spinner_focused_holo_light.9.png
rename to core/res/res/drawable-hdpi/spinner_focused_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_pressed_holo_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/spinner_pressed_holo_dark.9.png
rename to core/res/res/drawable-hdpi/spinner_pressed_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_pressed_holo_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/spinner_pressed_holo_light.9.png
rename to core/res/res/drawable-hdpi/spinner_pressed_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_notify_call_mute.png b/core/res/res/drawable-hdpi/stat_notify_call_mute.png
index 7f87ee7..f8f9503 100644
--- a/core/res/res/drawable-hdpi/stat_notify_call_mute.png
+++ b/core/res/res/drawable-hdpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_adb.png b/core/res/res/drawable-hdpi/stat_sys_adb.png
deleted file mode 100644
index cfbbd8d..0000000
--- a/core/res/res/drawable-hdpi/stat_sys_adb.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_adb_am.png b/core/res/res/drawable-hdpi/stat_sys_adb_am.png
new file mode 100644
index 0000000..382557e
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_adb_am.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_certificate_info.png b/core/res/res/drawable-hdpi/stat_sys_certificate_info.png
new file mode 100644
index 0000000..3be426c
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_certificate_info.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_secure.png b/core/res/res/drawable-hdpi/stat_sys_secure.png
deleted file mode 100644
index 5e979db..0000000
--- a/core/res/res/drawable-hdpi/stat_sys_secure.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_speakerphone.png b/core/res/res/drawable-hdpi/stat_sys_speakerphone.png
index 765be61..d5bb37f 100644
--- a/core/res/res/drawable-hdpi/stat_sys_speakerphone.png
+++ b/core/res/res/drawable-hdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/toast_bar_bg.9.png b/core/res/res/drawable-hdpi/toast_bar_bg.9.png
new file mode 100644
index 0000000..2396b26
--- /dev/null
+++ b/core/res/res/drawable-hdpi/toast_bar_bg.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_lock_airplane_mode_off.png b/core/res/res/drawable-ldpi/ic_lock_airplane_mode_off_am.png
similarity index 100%
rename from core/res/res/drawable-ldpi/ic_lock_airplane_mode_off.png
rename to core/res/res/drawable-ldpi/ic_lock_airplane_mode_off_am.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_cc.png b/core/res/res/drawable-ldpi/ic_menu_cc_am.png
similarity index 100%
rename from core/res/res/drawable-ldpi/ic_menu_cc.png
rename to core/res/res/drawable-ldpi/ic_menu_cc_am.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/popup_inline_error_above.9.png b/core/res/res/drawable-ldpi/popup_inline_error_above_am.9.png
similarity index 100%
rename from core/res/res/drawable-ldpi/popup_inline_error_above.9.png
rename to core/res/res/drawable-ldpi/popup_inline_error_above_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/popup_inline_error.9.png b/core/res/res/drawable-ldpi/popup_inline_error_am.9.png
similarity index 100%
rename from core/res/res/drawable-ldpi/popup_inline_error.9.png
rename to core/res/res/drawable-ldpi/popup_inline_error_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_notify_call_mute.png b/core/res/res/drawable-ldpi/stat_notify_call_mute.png
index d160009..353ecf2 100644
--- a/core/res/res/drawable-ldpi/stat_notify_call_mute.png
+++ b/core/res/res/drawable-ldpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_adb.png b/core/res/res/drawable-ldpi/stat_sys_adb_am.png
similarity index 100%
rename from core/res/res/drawable-ldpi/stat_sys_adb.png
rename to core/res/res/drawable-ldpi/stat_sys_adb_am.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_secure.png b/core/res/res/drawable-ldpi/stat_sys_secure.png
deleted file mode 100644
index 096aa95..0000000
--- a/core/res/res/drawable-ldpi/stat_sys_secure.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_speakerphone.png b/core/res/res/drawable-ldpi/stat_sys_speakerphone.png
index 7fc67a0..22ecd30 100644
--- a/core/res/res/drawable-ldpi/stat_sys_speakerphone.png
+++ b/core/res/res/drawable-ldpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/btn_cab_done_default_holo_dark.9.png b/core/res/res/drawable-ldrtl-hdpi/btn_cab_done_default_holo_dark.9.png
deleted file mode 100644
index 45450e4..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/btn_cab_done_default_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/btn_cab_done_default_holo_light.9.png b/core/res/res/drawable-ldrtl-hdpi/btn_cab_done_default_holo_light.9.png
deleted file mode 100644
index b568989..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/btn_cab_done_default_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/btn_cab_done_focused_holo_dark.9.png b/core/res/res/drawable-ldrtl-hdpi/btn_cab_done_focused_holo_dark.9.png
deleted file mode 100644
index e0434584..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/btn_cab_done_focused_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/btn_cab_done_focused_holo_light.9.png b/core/res/res/drawable-ldrtl-hdpi/btn_cab_done_focused_holo_light.9.png
deleted file mode 100644
index f208c99..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/btn_cab_done_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/btn_cab_done_pressed_holo_dark.9.png b/core/res/res/drawable-ldrtl-hdpi/btn_cab_done_pressed_holo_dark.9.png
deleted file mode 100644
index 94eb994..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/btn_cab_done_pressed_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/btn_cab_done_pressed_holo_light.9.png b/core/res/res/drawable-ldrtl-hdpi/btn_cab_done_pressed_holo_light.9.png
deleted file mode 100644
index 1fee149..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/btn_cab_done_pressed_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/ic_ab_back_holo_dark.png b/core/res/res/drawable-ldrtl-hdpi/ic_ab_back_holo_dark.png
deleted file mode 100644
index 9beeb0f..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/ic_ab_back_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/ic_ab_back_holo_light.png b/core/res/res/drawable-ldrtl-hdpi/ic_ab_back_holo_light.png
deleted file mode 100644
index 844e38b..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/ic_ab_back_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/ic_audio_notification.png b/core/res/res/drawable-ldrtl-hdpi/ic_audio_notification.png
deleted file mode 100644
index 62ef692..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/ic_audio_notification.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/ic_audio_notification_mute.png b/core/res/res/drawable-ldrtl-hdpi/ic_audio_notification_mute.png
deleted file mode 100644
index 40123e3..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/ic_audio_notification_mute.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/ic_audio_phone.png b/core/res/res/drawable-ldrtl-hdpi/ic_audio_phone.png
deleted file mode 100644
index 968f5ee..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/ic_audio_phone.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/ic_audio_ring_notif.png b/core/res/res/drawable-ldrtl-hdpi/ic_audio_ring_notif.png
deleted file mode 100644
index e5f0dcf..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/ic_audio_ring_notif.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/ic_audio_ring_notif_mute.png b/core/res/res/drawable-ldrtl-hdpi/ic_audio_ring_notif_mute.png
deleted file mode 100644
index 371e32f..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/ic_audio_ring_notif_mute.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/ic_audio_ring_notif_vibrate.png b/core/res/res/drawable-ldrtl-hdpi/ic_audio_ring_notif_vibrate.png
deleted file mode 100644
index e05e8f5..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/ic_audio_ring_notif_vibrate.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/ic_audio_vol.png b/core/res/res/drawable-ldrtl-hdpi/ic_audio_vol.png
deleted file mode 100644
index 81a8422..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/ic_audio_vol.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/ic_audio_vol_mute.png b/core/res/res/drawable-ldrtl-hdpi/ic_audio_vol_mute.png
deleted file mode 100644
index 371e32f..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/ic_audio_vol_mute.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/ic_lock_airplane_mode_off.png b/core/res/res/drawable-ldrtl-hdpi/ic_lock_airplane_mode_off.png
deleted file mode 100644
index 7b1eee6..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/ic_lock_airplane_mode_off.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/ic_menu_cc.png b/core/res/res/drawable-ldrtl-hdpi/ic_menu_cc.png
deleted file mode 100644
index aedf9b1..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/ic_menu_cc.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/popup_inline_error.9.png b/core/res/res/drawable-ldrtl-hdpi/popup_inline_error.9.png
deleted file mode 100644
index 8b43f4e..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/popup_inline_error.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/popup_inline_error_above.9.png b/core/res/res/drawable-ldrtl-hdpi/popup_inline_error_above.9.png
deleted file mode 100644
index 20e9002..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/popup_inline_error_above.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/popup_inline_error_above_holo_dark.9.png b/core/res/res/drawable-ldrtl-hdpi/popup_inline_error_above_holo_dark.9.png
deleted file mode 100644
index b5f397c..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/popup_inline_error_above_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/popup_inline_error_above_holo_light.9.png b/core/res/res/drawable-ldrtl-hdpi/popup_inline_error_above_holo_light.9.png
deleted file mode 100644
index a04d695..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/popup_inline_error_above_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/popup_inline_error_holo_dark.9.png b/core/res/res/drawable-ldrtl-hdpi/popup_inline_error_holo_dark.9.png
deleted file mode 100644
index 8567b1f..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/popup_inline_error_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/popup_inline_error_holo_light.9.png b/core/res/res/drawable-ldrtl-hdpi/popup_inline_error_holo_light.9.png
deleted file mode 100644
index 7d1754c..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/popup_inline_error_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/quickcontact_badge_overlay_focused_dark.9.png b/core/res/res/drawable-ldrtl-hdpi/quickcontact_badge_overlay_focused_dark.9.png
deleted file mode 100644
index 7c5826f..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/quickcontact_badge_overlay_focused_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/quickcontact_badge_overlay_focused_light.9.png b/core/res/res/drawable-ldrtl-hdpi/quickcontact_badge_overlay_focused_light.9.png
deleted file mode 100644
index 974a292..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/quickcontact_badge_overlay_focused_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/quickcontact_badge_overlay_normal_dark.9.png b/core/res/res/drawable-ldrtl-hdpi/quickcontact_badge_overlay_normal_dark.9.png
deleted file mode 100644
index b3196c9..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/quickcontact_badge_overlay_normal_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/quickcontact_badge_overlay_normal_light.9.png b/core/res/res/drawable-ldrtl-hdpi/quickcontact_badge_overlay_normal_light.9.png
deleted file mode 100644
index 1f833d3..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/quickcontact_badge_overlay_normal_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/quickcontact_badge_overlay_pressed_dark.9.png b/core/res/res/drawable-ldrtl-hdpi/quickcontact_badge_overlay_pressed_dark.9.png
deleted file mode 100644
index e969abc..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/quickcontact_badge_overlay_pressed_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/quickcontact_badge_overlay_pressed_light.9.png b/core/res/res/drawable-ldrtl-hdpi/quickcontact_badge_overlay_pressed_light.9.png
deleted file mode 100644
index 3adbc84..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/quickcontact_badge_overlay_pressed_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/spinner_ab_default_holo_dark.9.png b/core/res/res/drawable-ldrtl-hdpi/spinner_ab_default_holo_dark.9.png
deleted file mode 100644
index 57141d5..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/spinner_ab_default_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/spinner_ab_default_holo_light.9.png b/core/res/res/drawable-ldrtl-hdpi/spinner_ab_default_holo_light.9.png
deleted file mode 100644
index 8e28906..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/spinner_ab_default_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/spinner_ab_disabled_holo_dark.9.png b/core/res/res/drawable-ldrtl-hdpi/spinner_ab_disabled_holo_dark.9.png
deleted file mode 100644
index efdab73..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/spinner_ab_disabled_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/spinner_ab_disabled_holo_light.9.png b/core/res/res/drawable-ldrtl-hdpi/spinner_ab_disabled_holo_light.9.png
deleted file mode 100644
index 307b86d..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/spinner_ab_disabled_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/spinner_ab_focused_holo_dark.9.png b/core/res/res/drawable-ldrtl-hdpi/spinner_ab_focused_holo_dark.9.png
deleted file mode 100644
index 2e28431..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/spinner_ab_focused_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/spinner_ab_focused_holo_light.9.png b/core/res/res/drawable-ldrtl-hdpi/spinner_ab_focused_holo_light.9.png
deleted file mode 100644
index 7a83451..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/spinner_ab_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/spinner_ab_pressed_holo_dark.9.png b/core/res/res/drawable-ldrtl-hdpi/spinner_ab_pressed_holo_dark.9.png
deleted file mode 100644
index 9afc912..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/spinner_ab_pressed_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/spinner_ab_pressed_holo_light.9.png b/core/res/res/drawable-ldrtl-hdpi/spinner_ab_pressed_holo_light.9.png
deleted file mode 100644
index 7d03855..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/spinner_ab_pressed_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/spinner_default_holo_dark.9.png b/core/res/res/drawable-ldrtl-hdpi/spinner_default_holo_dark.9.png
deleted file mode 100644
index 21f1e2c..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/spinner_default_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/spinner_default_holo_light.9.png b/core/res/res/drawable-ldrtl-hdpi/spinner_default_holo_light.9.png
deleted file mode 100644
index 600b861..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/spinner_default_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/spinner_disabled_holo_dark.9.png b/core/res/res/drawable-ldrtl-hdpi/spinner_disabled_holo_dark.9.png
deleted file mode 100644
index c11619c..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/spinner_disabled_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/spinner_disabled_holo_light.9.png b/core/res/res/drawable-ldrtl-hdpi/spinner_disabled_holo_light.9.png
deleted file mode 100644
index 91be10f..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/spinner_disabled_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/spinner_focused_holo_dark.9.png b/core/res/res/drawable-ldrtl-hdpi/spinner_focused_holo_dark.9.png
deleted file mode 100644
index c921487..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/spinner_focused_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/spinner_focused_holo_light.9.png b/core/res/res/drawable-ldrtl-hdpi/spinner_focused_holo_light.9.png
deleted file mode 100644
index 4da6c6e..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/spinner_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/spinner_pressed_holo_dark.9.png b/core/res/res/drawable-ldrtl-hdpi/spinner_pressed_holo_dark.9.png
deleted file mode 100644
index 9c7d294..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/spinner_pressed_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/spinner_pressed_holo_light.9.png b/core/res/res/drawable-ldrtl-hdpi/spinner_pressed_holo_light.9.png
deleted file mode 100644
index c9f493a..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/spinner_pressed_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-hdpi/stat_sys_adb.png b/core/res/res/drawable-ldrtl-hdpi/stat_sys_adb.png
deleted file mode 100644
index a7dc29d..0000000
--- a/core/res/res/drawable-ldrtl-hdpi/stat_sys_adb.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-ldpi/ic_lock_airplane_mode_off.png b/core/res/res/drawable-ldrtl-ldpi/ic_lock_airplane_mode_off.png
deleted file mode 100644
index c093420..0000000
--- a/core/res/res/drawable-ldrtl-ldpi/ic_lock_airplane_mode_off.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-ldpi/ic_menu_cc.png b/core/res/res/drawable-ldrtl-ldpi/ic_menu_cc.png
deleted file mode 100644
index 1f21884..0000000
--- a/core/res/res/drawable-ldrtl-ldpi/ic_menu_cc.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-ldpi/popup_inline_error.9.png b/core/res/res/drawable-ldrtl-ldpi/popup_inline_error.9.png
deleted file mode 100644
index d2efb62..0000000
--- a/core/res/res/drawable-ldrtl-ldpi/popup_inline_error.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-ldpi/popup_inline_error_above.9.png b/core/res/res/drawable-ldrtl-ldpi/popup_inline_error_above.9.png
deleted file mode 100644
index 04d200d..0000000
--- a/core/res/res/drawable-ldrtl-ldpi/popup_inline_error_above.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-ldpi/stat_sys_adb.png b/core/res/res/drawable-ldrtl-ldpi/stat_sys_adb.png
deleted file mode 100644
index d726b7a..0000000
--- a/core/res/res/drawable-ldrtl-ldpi/stat_sys_adb.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/btn_cab_done_default_holo_dark.9.png b/core/res/res/drawable-ldrtl-mdpi/btn_cab_done_default_holo_dark.9.png
deleted file mode 100644
index abffc49..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/btn_cab_done_default_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/btn_cab_done_default_holo_light.9.png b/core/res/res/drawable-ldrtl-mdpi/btn_cab_done_default_holo_light.9.png
deleted file mode 100644
index a369081..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/btn_cab_done_default_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/btn_cab_done_focused_holo_dark.9.png b/core/res/res/drawable-ldrtl-mdpi/btn_cab_done_focused_holo_dark.9.png
deleted file mode 100644
index e33e964..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/btn_cab_done_focused_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/btn_cab_done_focused_holo_light.9.png b/core/res/res/drawable-ldrtl-mdpi/btn_cab_done_focused_holo_light.9.png
deleted file mode 100644
index 0a845dd..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/btn_cab_done_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/btn_cab_done_pressed_holo_dark.9.png b/core/res/res/drawable-ldrtl-mdpi/btn_cab_done_pressed_holo_dark.9.png
deleted file mode 100644
index 74b0352..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/btn_cab_done_pressed_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/btn_cab_done_pressed_holo_light.9.png b/core/res/res/drawable-ldrtl-mdpi/btn_cab_done_pressed_holo_light.9.png
deleted file mode 100644
index bfb4972..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/btn_cab_done_pressed_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/ic_ab_back_holo_dark.png b/core/res/res/drawable-ldrtl-mdpi/ic_ab_back_holo_dark.png
deleted file mode 100644
index c22dc90..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/ic_ab_back_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/ic_ab_back_holo_light.png b/core/res/res/drawable-ldrtl-mdpi/ic_ab_back_holo_light.png
deleted file mode 100644
index f49b715..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/ic_ab_back_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/ic_audio_notification.png b/core/res/res/drawable-ldrtl-mdpi/ic_audio_notification.png
deleted file mode 100644
index d9843e0..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/ic_audio_notification.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/ic_audio_notification_mute.png b/core/res/res/drawable-ldrtl-mdpi/ic_audio_notification_mute.png
deleted file mode 100644
index 2159cab..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/ic_audio_notification_mute.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/ic_audio_phone.png b/core/res/res/drawable-ldrtl-mdpi/ic_audio_phone.png
deleted file mode 100644
index b5af351..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/ic_audio_phone.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/ic_audio_ring_notif.png b/core/res/res/drawable-ldrtl-mdpi/ic_audio_ring_notif.png
deleted file mode 100644
index 6341be6..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/ic_audio_ring_notif.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/ic_audio_ring_notif_mute.png b/core/res/res/drawable-ldrtl-mdpi/ic_audio_ring_notif_mute.png
deleted file mode 100644
index b4c3a54..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/ic_audio_ring_notif_mute.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/ic_audio_ring_notif_vibrate.png b/core/res/res/drawable-ldrtl-mdpi/ic_audio_ring_notif_vibrate.png
deleted file mode 100644
index 835773e..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/ic_audio_ring_notif_vibrate.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/ic_audio_vol.png b/core/res/res/drawable-ldrtl-mdpi/ic_audio_vol.png
deleted file mode 100644
index 947d1f9..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/ic_audio_vol.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/ic_audio_vol_mute.png b/core/res/res/drawable-ldrtl-mdpi/ic_audio_vol_mute.png
deleted file mode 100644
index b4c3a54..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/ic_audio_vol_mute.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/ic_lock_airplane_mode_off.png b/core/res/res/drawable-ldrtl-mdpi/ic_lock_airplane_mode_off.png
deleted file mode 100644
index cba5500..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/ic_lock_airplane_mode_off.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/ic_menu_cc.png b/core/res/res/drawable-ldrtl-mdpi/ic_menu_cc.png
deleted file mode 100644
index 0335dec..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/ic_menu_cc.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/popup_inline_error.9.png b/core/res/res/drawable-ldrtl-mdpi/popup_inline_error.9.png
deleted file mode 100644
index 27e8d4f..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/popup_inline_error.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/popup_inline_error_above.9.png b/core/res/res/drawable-ldrtl-mdpi/popup_inline_error_above.9.png
deleted file mode 100644
index 4ae2b91..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/popup_inline_error_above.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/popup_inline_error_above_holo_dark.9.png b/core/res/res/drawable-ldrtl-mdpi/popup_inline_error_above_holo_dark.9.png
deleted file mode 100644
index 8cc3b69..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/popup_inline_error_above_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/popup_inline_error_above_holo_light.9.png b/core/res/res/drawable-ldrtl-mdpi/popup_inline_error_above_holo_light.9.png
deleted file mode 100644
index 7a84200..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/popup_inline_error_above_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/popup_inline_error_holo_dark.9.png b/core/res/res/drawable-ldrtl-mdpi/popup_inline_error_holo_dark.9.png
deleted file mode 100644
index 8fc2e2e..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/popup_inline_error_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/popup_inline_error_holo_light.9.png b/core/res/res/drawable-ldrtl-mdpi/popup_inline_error_holo_light.9.png
deleted file mode 100644
index 687a691..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/popup_inline_error_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/quickcontact_badge_overlay_focused_dark.9.png b/core/res/res/drawable-ldrtl-mdpi/quickcontact_badge_overlay_focused_dark.9.png
deleted file mode 100644
index a321836..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/quickcontact_badge_overlay_focused_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/quickcontact_badge_overlay_focused_light.9.png b/core/res/res/drawable-ldrtl-mdpi/quickcontact_badge_overlay_focused_light.9.png
deleted file mode 100644
index 4c5d692..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/quickcontact_badge_overlay_focused_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/quickcontact_badge_overlay_normal_dark.9.png b/core/res/res/drawable-ldrtl-mdpi/quickcontact_badge_overlay_normal_dark.9.png
deleted file mode 100644
index 6199dc5..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/quickcontact_badge_overlay_normal_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/quickcontact_badge_overlay_normal_light.9.png b/core/res/res/drawable-ldrtl-mdpi/quickcontact_badge_overlay_normal_light.9.png
deleted file mode 100644
index 1b0905a..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/quickcontact_badge_overlay_normal_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/quickcontact_badge_overlay_pressed_dark.9.png b/core/res/res/drawable-ldrtl-mdpi/quickcontact_badge_overlay_pressed_dark.9.png
deleted file mode 100644
index c6d7868..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/quickcontact_badge_overlay_pressed_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/quickcontact_badge_overlay_pressed_light.9.png b/core/res/res/drawable-ldrtl-mdpi/quickcontact_badge_overlay_pressed_light.9.png
deleted file mode 100644
index 179644c..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/quickcontact_badge_overlay_pressed_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/spinner_ab_default_holo_dark.9.png b/core/res/res/drawable-ldrtl-mdpi/spinner_ab_default_holo_dark.9.png
deleted file mode 100644
index 02c799e..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/spinner_ab_default_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/spinner_ab_default_holo_light.9.png b/core/res/res/drawable-ldrtl-mdpi/spinner_ab_default_holo_light.9.png
deleted file mode 100644
index 286157c..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/spinner_ab_default_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/spinner_ab_disabled_holo_dark.9.png b/core/res/res/drawable-ldrtl-mdpi/spinner_ab_disabled_holo_dark.9.png
deleted file mode 100644
index 030f723..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/spinner_ab_disabled_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/spinner_ab_disabled_holo_light.9.png b/core/res/res/drawable-ldrtl-mdpi/spinner_ab_disabled_holo_light.9.png
deleted file mode 100644
index a5b10d2..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/spinner_ab_disabled_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/spinner_ab_focused_holo_dark.9.png b/core/res/res/drawable-ldrtl-mdpi/spinner_ab_focused_holo_dark.9.png
deleted file mode 100644
index 10faec10..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/spinner_ab_focused_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/spinner_ab_focused_holo_light.9.png b/core/res/res/drawable-ldrtl-mdpi/spinner_ab_focused_holo_light.9.png
deleted file mode 100644
index 62a70ed..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/spinner_ab_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/spinner_ab_pressed_holo_dark.9.png b/core/res/res/drawable-ldrtl-mdpi/spinner_ab_pressed_holo_dark.9.png
deleted file mode 100644
index 633b8d2..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/spinner_ab_pressed_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/spinner_ab_pressed_holo_light.9.png b/core/res/res/drawable-ldrtl-mdpi/spinner_ab_pressed_holo_light.9.png
deleted file mode 100644
index 59ff556..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/spinner_ab_pressed_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/spinner_default_holo_dark.9.png b/core/res/res/drawable-ldrtl-mdpi/spinner_default_holo_dark.9.png
deleted file mode 100644
index 09d5aa4..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/spinner_default_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/spinner_default_holo_light.9.png b/core/res/res/drawable-ldrtl-mdpi/spinner_default_holo_light.9.png
deleted file mode 100644
index c320ea0..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/spinner_default_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/spinner_disabled_holo_dark.9.png b/core/res/res/drawable-ldrtl-mdpi/spinner_disabled_holo_dark.9.png
deleted file mode 100644
index a5f28fd..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/spinner_disabled_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/spinner_disabled_holo_light.9.png b/core/res/res/drawable-ldrtl-mdpi/spinner_disabled_holo_light.9.png
deleted file mode 100644
index 9e0d39c..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/spinner_disabled_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/spinner_focused_holo_dark.9.png b/core/res/res/drawable-ldrtl-mdpi/spinner_focused_holo_dark.9.png
deleted file mode 100644
index 24d928f..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/spinner_focused_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/spinner_focused_holo_light.9.png b/core/res/res/drawable-ldrtl-mdpi/spinner_focused_holo_light.9.png
deleted file mode 100644
index 596ba2d..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/spinner_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/spinner_pressed_holo_dark.9.png b/core/res/res/drawable-ldrtl-mdpi/spinner_pressed_holo_dark.9.png
deleted file mode 100644
index 55b1af7..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/spinner_pressed_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/spinner_pressed_holo_light.9.png b/core/res/res/drawable-ldrtl-mdpi/spinner_pressed_holo_light.9.png
deleted file mode 100644
index bb0486a..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/spinner_pressed_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-mdpi/stat_sys_adb.png b/core/res/res/drawable-ldrtl-mdpi/stat_sys_adb.png
deleted file mode 100644
index 265c421..0000000
--- a/core/res/res/drawable-ldrtl-mdpi/stat_sys_adb.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/btn_cab_done_default_holo_dark.9.png b/core/res/res/drawable-ldrtl-xhdpi/btn_cab_done_default_holo_dark.9.png
deleted file mode 100644
index d253dd4..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/btn_cab_done_default_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/btn_cab_done_default_holo_light.9.png b/core/res/res/drawable-ldrtl-xhdpi/btn_cab_done_default_holo_light.9.png
deleted file mode 100644
index 65f9ec1..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/btn_cab_done_default_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/btn_cab_done_focused_holo_dark.9.png b/core/res/res/drawable-ldrtl-xhdpi/btn_cab_done_focused_holo_dark.9.png
deleted file mode 100644
index 105da60..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/btn_cab_done_focused_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/btn_cab_done_focused_holo_light.9.png b/core/res/res/drawable-ldrtl-xhdpi/btn_cab_done_focused_holo_light.9.png
deleted file mode 100644
index de53be7..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/btn_cab_done_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/btn_cab_done_pressed_holo_dark.9.png b/core/res/res/drawable-ldrtl-xhdpi/btn_cab_done_pressed_holo_dark.9.png
deleted file mode 100644
index 3be0b0c..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/btn_cab_done_pressed_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/btn_cab_done_pressed_holo_light.9.png b/core/res/res/drawable-ldrtl-xhdpi/btn_cab_done_pressed_holo_light.9.png
deleted file mode 100644
index 878c702..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/btn_cab_done_pressed_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/ic_ab_back_holo_dark.png b/core/res/res/drawable-ldrtl-xhdpi/ic_ab_back_holo_dark.png
deleted file mode 100644
index 8dfb7d8..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/ic_ab_back_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/ic_ab_back_holo_light.png b/core/res/res/drawable-ldrtl-xhdpi/ic_ab_back_holo_light.png
deleted file mode 100644
index 29852ad..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/ic_ab_back_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/ic_audio_notification.png b/core/res/res/drawable-ldrtl-xhdpi/ic_audio_notification.png
deleted file mode 100644
index 43aedea..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/ic_audio_notification.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/ic_audio_notification_mute.png b/core/res/res/drawable-ldrtl-xhdpi/ic_audio_notification_mute.png
deleted file mode 100644
index 4e87f77..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/ic_audio_notification_mute.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/ic_audio_phone.png b/core/res/res/drawable-ldrtl-xhdpi/ic_audio_phone.png
deleted file mode 100644
index 1066d03..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/ic_audio_phone.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/ic_audio_ring_notif.png b/core/res/res/drawable-ldrtl-xhdpi/ic_audio_ring_notif.png
deleted file mode 100644
index daf9213..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/ic_audio_ring_notif.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/ic_audio_ring_notif_mute.png b/core/res/res/drawable-ldrtl-xhdpi/ic_audio_ring_notif_mute.png
deleted file mode 100644
index 83d3bdd..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/ic_audio_ring_notif_mute.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/ic_audio_ring_notif_vibrate.png b/core/res/res/drawable-ldrtl-xhdpi/ic_audio_ring_notif_vibrate.png
deleted file mode 100644
index 4de95aa..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/ic_audio_ring_notif_vibrate.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/ic_audio_vol.png b/core/res/res/drawable-ldrtl-xhdpi/ic_audio_vol.png
deleted file mode 100644
index 8132926..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/ic_audio_vol.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/ic_audio_vol_mute.png b/core/res/res/drawable-ldrtl-xhdpi/ic_audio_vol_mute.png
deleted file mode 100644
index 83d3bdd..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/ic_audio_vol_mute.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/ic_lock_airplane_mode_off.png b/core/res/res/drawable-ldrtl-xhdpi/ic_lock_airplane_mode_off.png
deleted file mode 100644
index 6820a23..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/ic_lock_airplane_mode_off.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/ic_menu_cc.png b/core/res/res/drawable-ldrtl-xhdpi/ic_menu_cc.png
deleted file mode 100644
index c8690bd..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/ic_menu_cc.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/popup_inline_error.9.png b/core/res/res/drawable-ldrtl-xhdpi/popup_inline_error.9.png
deleted file mode 100644
index db91a56..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/popup_inline_error.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/popup_inline_error_above.9.png b/core/res/res/drawable-ldrtl-xhdpi/popup_inline_error_above.9.png
deleted file mode 100644
index 90820b5..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/popup_inline_error_above.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/popup_inline_error_above_holo_dark.9.png b/core/res/res/drawable-ldrtl-xhdpi/popup_inline_error_above_holo_dark.9.png
deleted file mode 100644
index 5989975..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/popup_inline_error_above_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/popup_inline_error_above_holo_light.9.png b/core/res/res/drawable-ldrtl-xhdpi/popup_inline_error_above_holo_light.9.png
deleted file mode 100644
index 3b3f87d3..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/popup_inline_error_above_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/popup_inline_error_holo_dark.9.png b/core/res/res/drawable-ldrtl-xhdpi/popup_inline_error_holo_dark.9.png
deleted file mode 100644
index 75baba2..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/popup_inline_error_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/popup_inline_error_holo_light.9.png b/core/res/res/drawable-ldrtl-xhdpi/popup_inline_error_holo_light.9.png
deleted file mode 100644
index 6c0203d..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/popup_inline_error_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/quickcontact_badge_overlay_focused_dark.9.png b/core/res/res/drawable-ldrtl-xhdpi/quickcontact_badge_overlay_focused_dark.9.png
deleted file mode 100644
index 039a056..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/quickcontact_badge_overlay_focused_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/quickcontact_badge_overlay_focused_light.9.png b/core/res/res/drawable-ldrtl-xhdpi/quickcontact_badge_overlay_focused_light.9.png
deleted file mode 100644
index c8d68c5..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/quickcontact_badge_overlay_focused_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/quickcontact_badge_overlay_normal_dark.9.png b/core/res/res/drawable-ldrtl-xhdpi/quickcontact_badge_overlay_normal_dark.9.png
deleted file mode 100644
index 1fef1ad..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/quickcontact_badge_overlay_normal_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/quickcontact_badge_overlay_normal_light.9.png b/core/res/res/drawable-ldrtl-xhdpi/quickcontact_badge_overlay_normal_light.9.png
deleted file mode 100644
index 6b22d44..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/quickcontact_badge_overlay_normal_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/quickcontact_badge_overlay_pressed_dark.9.png b/core/res/res/drawable-ldrtl-xhdpi/quickcontact_badge_overlay_pressed_dark.9.png
deleted file mode 100644
index c219527..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/quickcontact_badge_overlay_pressed_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/quickcontact_badge_overlay_pressed_light.9.png b/core/res/res/drawable-ldrtl-xhdpi/quickcontact_badge_overlay_pressed_light.9.png
deleted file mode 100644
index 2a1d508..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/quickcontact_badge_overlay_pressed_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/spinner_ab_default_holo_dark.9.png b/core/res/res/drawable-ldrtl-xhdpi/spinner_ab_default_holo_dark.9.png
deleted file mode 100644
index 6f41b24..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/spinner_ab_default_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/spinner_ab_default_holo_light.9.png b/core/res/res/drawable-ldrtl-xhdpi/spinner_ab_default_holo_light.9.png
deleted file mode 100644
index 5a96fc1..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/spinner_ab_default_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/spinner_ab_disabled_holo_dark.9.png b/core/res/res/drawable-ldrtl-xhdpi/spinner_ab_disabled_holo_dark.9.png
deleted file mode 100644
index 96a6da5..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/spinner_ab_disabled_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/spinner_ab_disabled_holo_light.9.png b/core/res/res/drawable-ldrtl-xhdpi/spinner_ab_disabled_holo_light.9.png
deleted file mode 100644
index 849d795..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/spinner_ab_disabled_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/spinner_ab_focused_holo_dark.9.png b/core/res/res/drawable-ldrtl-xhdpi/spinner_ab_focused_holo_dark.9.png
deleted file mode 100644
index 3d6d0f9..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/spinner_ab_focused_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/spinner_ab_focused_holo_light.9.png b/core/res/res/drawable-ldrtl-xhdpi/spinner_ab_focused_holo_light.9.png
deleted file mode 100644
index 1cbaf6c..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/spinner_ab_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/spinner_ab_pressed_holo_dark.9.png b/core/res/res/drawable-ldrtl-xhdpi/spinner_ab_pressed_holo_dark.9.png
deleted file mode 100644
index 878e90d..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/spinner_ab_pressed_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/spinner_ab_pressed_holo_light.9.png b/core/res/res/drawable-ldrtl-xhdpi/spinner_ab_pressed_holo_light.9.png
deleted file mode 100644
index f25acc2..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/spinner_ab_pressed_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/spinner_default_holo_dark.9.png b/core/res/res/drawable-ldrtl-xhdpi/spinner_default_holo_dark.9.png
deleted file mode 100644
index 8d89c86..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/spinner_default_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/spinner_default_holo_light.9.png b/core/res/res/drawable-ldrtl-xhdpi/spinner_default_holo_light.9.png
deleted file mode 100644
index 6e3ca08..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/spinner_default_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/spinner_disabled_holo_dark.9.png b/core/res/res/drawable-ldrtl-xhdpi/spinner_disabled_holo_dark.9.png
deleted file mode 100644
index 2204091..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/spinner_disabled_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/spinner_disabled_holo_light.9.png b/core/res/res/drawable-ldrtl-xhdpi/spinner_disabled_holo_light.9.png
deleted file mode 100644
index 3e6684e..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/spinner_disabled_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/spinner_focused_holo_dark.9.png b/core/res/res/drawable-ldrtl-xhdpi/spinner_focused_holo_dark.9.png
deleted file mode 100644
index 5129dee..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/spinner_focused_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/spinner_focused_holo_light.9.png b/core/res/res/drawable-ldrtl-xhdpi/spinner_focused_holo_light.9.png
deleted file mode 100644
index 0f0289b..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/spinner_focused_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/spinner_pressed_holo_dark.9.png b/core/res/res/drawable-ldrtl-xhdpi/spinner_pressed_holo_dark.9.png
deleted file mode 100644
index 795820b..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/spinner_pressed_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/spinner_pressed_holo_light.9.png b/core/res/res/drawable-ldrtl-xhdpi/spinner_pressed_holo_light.9.png
deleted file mode 100644
index 830edfd..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/spinner_pressed_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldrtl-xhdpi/stat_sys_adb.png b/core/res/res/drawable-ldrtl-xhdpi/stat_sys_adb.png
deleted file mode 100644
index e342556..0000000
--- a/core/res/res/drawable-ldrtl-xhdpi/stat_sys_adb.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/activity_picker_bg_activated.9.png b/core/res/res/drawable-mdpi/activity_picker_bg_activated.9.png
deleted file mode 100644
index 7dfea4c..0000000
--- a/core/res/res/drawable-mdpi/activity_picker_bg_activated.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/activity_picker_bg_focused.9.png b/core/res/res/drawable-mdpi/activity_picker_bg_focused.9.png
deleted file mode 100644
index 99b0279..0000000
--- a/core/res/res/drawable-mdpi/activity_picker_bg_focused.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_ab_back_holo_dark.png b/core/res/res/drawable-mdpi/ic_ab_back_holo_dark_am.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_ab_back_holo_dark.png
rename to core/res/res/drawable-mdpi/ic_ab_back_holo_dark_am.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_ab_back_holo_light.png b/core/res/res/drawable-mdpi/ic_ab_back_holo_light_am.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_ab_back_holo_light.png
rename to core/res/res/drawable-mdpi/ic_ab_back_holo_light_am.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_audio_notification.png b/core/res/res/drawable-mdpi/ic_audio_notification_am.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_audio_notification.png
rename to core/res/res/drawable-mdpi/ic_audio_notification_am.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_audio_notification_mute.png b/core/res/res/drawable-mdpi/ic_audio_notification_mute_am.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_audio_notification_mute.png
rename to core/res/res/drawable-mdpi/ic_audio_notification_mute_am.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_audio_phone.png b/core/res/res/drawable-mdpi/ic_audio_phone_am.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_audio_phone.png
rename to core/res/res/drawable-mdpi/ic_audio_phone_am.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_audio_ring_notif.png b/core/res/res/drawable-mdpi/ic_audio_ring_notif_am.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_audio_ring_notif.png
rename to core/res/res/drawable-mdpi/ic_audio_ring_notif_am.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_audio_ring_notif_mute.png b/core/res/res/drawable-mdpi/ic_audio_ring_notif_mute_am.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_audio_ring_notif_mute.png
rename to core/res/res/drawable-mdpi/ic_audio_ring_notif_mute_am.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_audio_ring_notif_vibrate.png b/core/res/res/drawable-mdpi/ic_audio_ring_notif_vibrate_am.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_audio_ring_notif_vibrate.png
rename to core/res/res/drawable-mdpi/ic_audio_ring_notif_vibrate_am.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_audio_vol.png b/core/res/res/drawable-mdpi/ic_audio_vol_am.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_audio_vol.png
rename to core/res/res/drawable-mdpi/ic_audio_vol_am.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_audio_vol_mute.png b/core/res/res/drawable-mdpi/ic_audio_vol_mute_am.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_audio_vol_mute.png
rename to core/res/res/drawable-mdpi/ic_audio_vol_mute_am.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lock_airplane_mode_off.png b/core/res/res/drawable-mdpi/ic_lock_airplane_mode_off_am.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_lock_airplane_mode_off.png
rename to core/res/res/drawable-mdpi/ic_lock_airplane_mode_off_am.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_cc.png b/core/res/res/drawable-mdpi/ic_menu_cc_am.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_menu_cc.png
rename to core/res/res/drawable-mdpi/ic_menu_cc_am.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_add_widget.png b/core/res/res/drawable-mdpi/kg_add_widget.png
deleted file mode 100644
index 136ae17..0000000
--- a/core/res/res/drawable-mdpi/kg_add_widget.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_security_lock_focused.png b/core/res/res/drawable-mdpi/kg_security_lock_focused.png
deleted file mode 100644
index c567a82..0000000
--- a/core/res/res/drawable-mdpi/kg_security_lock_focused.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_security_lock_normal.png b/core/res/res/drawable-mdpi/kg_security_lock_normal.png
deleted file mode 100644
index 6fbecc1..0000000
--- a/core/res/res/drawable-mdpi/kg_security_lock_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_security_lock_pressed.png b/core/res/res/drawable-mdpi/kg_security_lock_pressed.png
deleted file mode 100644
index a883258..0000000
--- a/core/res/res/drawable-mdpi/kg_security_lock_pressed.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/popup_inline_error_above.9.png b/core/res/res/drawable-mdpi/popup_inline_error_above_am.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/popup_inline_error_above.9.png
rename to core/res/res/drawable-mdpi/popup_inline_error_above_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/popup_inline_error_above_holo_dark.9.png b/core/res/res/drawable-mdpi/popup_inline_error_above_holo_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/popup_inline_error_above_holo_dark.9.png
rename to core/res/res/drawable-mdpi/popup_inline_error_above_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/popup_inline_error_above_holo_light.9.png b/core/res/res/drawable-mdpi/popup_inline_error_above_holo_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/popup_inline_error_above_holo_light.9.png
rename to core/res/res/drawable-mdpi/popup_inline_error_above_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/popup_inline_error.9.png b/core/res/res/drawable-mdpi/popup_inline_error_am.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/popup_inline_error.9.png
rename to core/res/res/drawable-mdpi/popup_inline_error_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/popup_inline_error_holo_dark.9.png b/core/res/res/drawable-mdpi/popup_inline_error_holo_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/popup_inline_error_holo_dark.9.png
rename to core/res/res/drawable-mdpi/popup_inline_error_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/popup_inline_error_holo_light.9.png b/core/res/res/drawable-mdpi/popup_inline_error_holo_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/popup_inline_error_holo_light.9.png
rename to core/res/res/drawable-mdpi/popup_inline_error_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_focused_dark.9.png b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_focused_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/quickcontact_badge_overlay_focused_dark.9.png
rename to core/res/res/drawable-mdpi/quickcontact_badge_overlay_focused_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_focused_light.9.png b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_focused_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/quickcontact_badge_overlay_focused_light.9.png
rename to core/res/res/drawable-mdpi/quickcontact_badge_overlay_focused_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_dark.9.png b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_dark.9.png
rename to core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_light.9.png b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_light.9.png
rename to core/res/res/drawable-mdpi/quickcontact_badge_overlay_normal_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_dark.9.png b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_dark.9.png
rename to core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_light.9.png b/core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_light.9.png
rename to core/res/res/drawable-mdpi/quickcontact_badge_overlay_pressed_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_default_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_ab_default_holo_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/spinner_ab_default_holo_dark.9.png
rename to core/res/res/drawable-mdpi/spinner_ab_default_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_default_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_ab_default_holo_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/spinner_ab_default_holo_light.9.png
rename to core/res/res/drawable-mdpi/spinner_ab_default_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/spinner_ab_disabled_holo_dark.9.png
rename to core/res/res/drawable-mdpi/spinner_ab_disabled_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_ab_disabled_holo_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/spinner_ab_disabled_holo_light.9.png
rename to core/res/res/drawable-mdpi/spinner_ab_disabled_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_ab_focused_holo_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/spinner_ab_focused_holo_dark.9.png
rename to core/res/res/drawable-mdpi/spinner_ab_focused_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_focused_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_ab_focused_holo_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/spinner_ab_focused_holo_light.9.png
rename to core/res/res/drawable-mdpi/spinner_ab_focused_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/spinner_ab_pressed_holo_dark.9.png
rename to core/res/res/drawable-mdpi/spinner_ab_pressed_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_ab_pressed_holo_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/spinner_ab_pressed_holo_light.9.png
rename to core/res/res/drawable-mdpi/spinner_ab_pressed_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_default_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_default_holo_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/spinner_default_holo_dark.9.png
rename to core/res/res/drawable-mdpi/spinner_default_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_default_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_default_holo_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/spinner_default_holo_light.9.png
rename to core/res/res/drawable-mdpi/spinner_default_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_disabled_holo_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/spinner_disabled_holo_dark.9.png
rename to core/res/res/drawable-mdpi/spinner_disabled_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_disabled_holo_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/spinner_disabled_holo_light.9.png
rename to core/res/res/drawable-mdpi/spinner_disabled_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_focused_holo_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/spinner_focused_holo_dark.9.png
rename to core/res/res/drawable-mdpi/spinner_focused_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_focused_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_focused_holo_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/spinner_focused_holo_light.9.png
rename to core/res/res/drawable-mdpi/spinner_focused_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_pressed_holo_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/spinner_pressed_holo_dark.9.png
rename to core/res/res/drawable-mdpi/spinner_pressed_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_pressed_holo_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/spinner_pressed_holo_light.9.png
rename to core/res/res/drawable-mdpi/spinner_pressed_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_call_mute.png b/core/res/res/drawable-mdpi/stat_notify_call_mute.png
index 58e0cbc..79683c7 100644
--- a/core/res/res/drawable-mdpi/stat_notify_call_mute.png
+++ b/core/res/res/drawable-mdpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_adb.png b/core/res/res/drawable-mdpi/stat_sys_adb.png
deleted file mode 100644
index 4862919..0000000
--- a/core/res/res/drawable-mdpi/stat_sys_adb.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_adb_am.png b/core/res/res/drawable-mdpi/stat_sys_adb_am.png
new file mode 100644
index 0000000..4380035
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_adb_am.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_certificate_info.png b/core/res/res/drawable-mdpi/stat_sys_certificate_info.png
new file mode 100644
index 0000000..e15cf38
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_certificate_info.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_secure.png b/core/res/res/drawable-mdpi/stat_sys_secure.png
deleted file mode 100644
index da3e318..0000000
--- a/core/res/res/drawable-mdpi/stat_sys_secure.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_speakerphone.png b/core/res/res/drawable-mdpi/stat_sys_speakerphone.png
index d82704e..df0597f 100644
--- a/core/res/res/drawable-mdpi/stat_sys_speakerphone.png
+++ b/core/res/res/drawable-mdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/toast_bar_bg.9.png b/core/res/res/drawable-mdpi/toast_bar_bg.9.png
new file mode 100644
index 0000000..291a936
--- /dev/null
+++ b/core/res/res/drawable-mdpi/toast_bar_bg.9.png
Binary files differ
diff --git a/core/res/res/drawable-nodpi/platlogo.png b/core/res/res/drawable-nodpi/platlogo.png
index 63b53b8..4fd0e3c 100644
--- a/core/res/res/drawable-nodpi/platlogo.png
+++ b/core/res/res/drawable-nodpi/platlogo.png
Binary files differ
diff --git a/core/res/res/drawable-nodpi/platlogo_alt.png b/core/res/res/drawable-nodpi/platlogo_alt.png
deleted file mode 100644
index f46c6c6..0000000
--- a/core/res/res/drawable-nodpi/platlogo_alt.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-nodpi/view_accessibility_focused.9.png b/core/res/res/drawable-nodpi/view_accessibility_focused.9.png
deleted file mode 100644
index f03f575..0000000
--- a/core/res/res/drawable-nodpi/view_accessibility_focused.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-hdpi/stat_notify_call_mute.png b/core/res/res/drawable-sw600dp-hdpi/stat_notify_call_mute.png
index b753764..996aadc 100644
--- a/core/res/res/drawable-sw600dp-hdpi/stat_notify_call_mute.png
+++ b/core/res/res/drawable-sw600dp-hdpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-hdpi/stat_sys_speakerphone.png b/core/res/res/drawable-sw600dp-hdpi/stat_sys_speakerphone.png
index b47a9f6..e440805 100644
--- a/core/res/res/drawable-sw600dp-hdpi/stat_sys_speakerphone.png
+++ b/core/res/res/drawable-sw600dp-hdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-mdpi/stat_notify_call_mute.png b/core/res/res/drawable-sw600dp-mdpi/stat_notify_call_mute.png
index 951197c..5ebf23a 100644
--- a/core/res/res/drawable-sw600dp-mdpi/stat_notify_call_mute.png
+++ b/core/res/res/drawable-sw600dp-mdpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-mdpi/stat_sys_speakerphone.png b/core/res/res/drawable-sw600dp-mdpi/stat_sys_speakerphone.png
index 5893db9..0228134 100644
--- a/core/res/res/drawable-sw600dp-mdpi/stat_sys_speakerphone.png
+++ b/core/res/res/drawable-sw600dp-mdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-xhdpi/stat_notify_call_mute.png b/core/res/res/drawable-sw600dp-xhdpi/stat_notify_call_mute.png
index 1d72243..142080a 100644
--- a/core/res/res/drawable-sw600dp-xhdpi/stat_notify_call_mute.png
+++ b/core/res/res/drawable-sw600dp-xhdpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-xhdpi/stat_sys_speakerphone.png b/core/res/res/drawable-sw600dp-xhdpi/stat_sys_speakerphone.png
index 76dee9e..f9563b2 100644
--- a/core/res/res/drawable-sw600dp-xhdpi/stat_sys_speakerphone.png
+++ b/core/res/res/drawable-sw600dp-xhdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-xxhdpi/stat_notify_call_mute.png b/core/res/res/drawable-sw600dp-xxhdpi/stat_notify_call_mute.png
new file mode 100644
index 0000000..dd1b5be
--- /dev/null
+++ b/core/res/res/drawable-sw600dp-xxhdpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-xxhdpi/stat_sys_speakerphone.png b/core/res/res/drawable-sw600dp-xxhdpi/stat_sys_speakerphone.png
new file mode 100644
index 0000000..df9bff1
--- /dev/null
+++ b/core/res/res/drawable-sw600dp-xxhdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/activity_picker_bg_activated.9.png b/core/res/res/drawable-xhdpi/activity_picker_bg_activated.9.png
deleted file mode 100644
index f01a79e..0000000
--- a/core/res/res/drawable-xhdpi/activity_picker_bg_activated.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/activity_picker_bg_focused.9.png b/core/res/res/drawable-xhdpi/activity_picker_bg_focused.9.png
deleted file mode 100644
index 7bea197..0000000
--- a/core/res/res/drawable-xhdpi/activity_picker_bg_focused.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/default_wallpaper.jpg b/core/res/res/drawable-xhdpi/default_wallpaper.jpg
deleted file mode 100644
index da9fa91..0000000
--- a/core/res/res/drawable-xhdpi/default_wallpaper.jpg
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_ab_back_holo_dark.png b/core/res/res/drawable-xhdpi/ic_ab_back_holo_dark_am.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_ab_back_holo_dark.png
rename to core/res/res/drawable-xhdpi/ic_ab_back_holo_dark_am.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_ab_back_holo_light.png b/core/res/res/drawable-xhdpi/ic_ab_back_holo_light_am.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_ab_back_holo_light.png
rename to core/res/res/drawable-xhdpi/ic_ab_back_holo_light_am.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_audio_notification.png b/core/res/res/drawable-xhdpi/ic_audio_notification_am.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_audio_notification.png
rename to core/res/res/drawable-xhdpi/ic_audio_notification_am.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_audio_notification_mute.png b/core/res/res/drawable-xhdpi/ic_audio_notification_mute_am.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_audio_notification_mute.png
rename to core/res/res/drawable-xhdpi/ic_audio_notification_mute_am.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_audio_phone.png b/core/res/res/drawable-xhdpi/ic_audio_phone_am.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_audio_phone.png
rename to core/res/res/drawable-xhdpi/ic_audio_phone_am.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_audio_ring_notif.png b/core/res/res/drawable-xhdpi/ic_audio_ring_notif_am.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_audio_ring_notif.png
rename to core/res/res/drawable-xhdpi/ic_audio_ring_notif_am.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_audio_ring_notif_mute.png b/core/res/res/drawable-xhdpi/ic_audio_ring_notif_mute_am.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_audio_ring_notif_mute.png
rename to core/res/res/drawable-xhdpi/ic_audio_ring_notif_mute_am.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_audio_ring_notif_vibrate.png b/core/res/res/drawable-xhdpi/ic_audio_ring_notif_vibrate_am.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_audio_ring_notif_vibrate.png
rename to core/res/res/drawable-xhdpi/ic_audio_ring_notif_vibrate_am.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_audio_vol.png b/core/res/res/drawable-xhdpi/ic_audio_vol_am.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_audio_vol.png
rename to core/res/res/drawable-xhdpi/ic_audio_vol_am.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_audio_vol_mute.png b/core/res/res/drawable-xhdpi/ic_audio_vol_mute_am.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_audio_vol_mute.png
rename to core/res/res/drawable-xhdpi/ic_audio_vol_mute_am.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lock_airplane_mode_off.png b/core/res/res/drawable-xhdpi/ic_lock_airplane_mode_off_am.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_lock_airplane_mode_off.png
rename to core/res/res/drawable-xhdpi/ic_lock_airplane_mode_off_am.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_cc.png b/core/res/res/drawable-xhdpi/ic_menu_cc_am.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_menu_cc.png
rename to core/res/res/drawable-xhdpi/ic_menu_cc_am.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_add_widget.png b/core/res/res/drawable-xhdpi/kg_add_widget.png
deleted file mode 100644
index ca48be2..0000000
--- a/core/res/res/drawable-xhdpi/kg_add_widget.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_security_lock_focused.png b/core/res/res/drawable-xhdpi/kg_security_lock_focused.png
deleted file mode 100644
index ee21647..0000000
--- a/core/res/res/drawable-xhdpi/kg_security_lock_focused.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_security_lock_normal.png b/core/res/res/drawable-xhdpi/kg_security_lock_normal.png
deleted file mode 100644
index eae7d8c..0000000
--- a/core/res/res/drawable-xhdpi/kg_security_lock_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_security_lock_pressed.png b/core/res/res/drawable-xhdpi/kg_security_lock_pressed.png
deleted file mode 100644
index 5e9a52b..0000000
--- a/core/res/res/drawable-xhdpi/kg_security_lock_pressed.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/popup_inline_error_above.9.png b/core/res/res/drawable-xhdpi/popup_inline_error_above_am.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/popup_inline_error_above.9.png
rename to core/res/res/drawable-xhdpi/popup_inline_error_above_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/popup_inline_error_above_holo_dark.9.png b/core/res/res/drawable-xhdpi/popup_inline_error_above_holo_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/popup_inline_error_above_holo_dark.9.png
rename to core/res/res/drawable-xhdpi/popup_inline_error_above_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/popup_inline_error_above_holo_light.9.png b/core/res/res/drawable-xhdpi/popup_inline_error_above_holo_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/popup_inline_error_above_holo_light.9.png
rename to core/res/res/drawable-xhdpi/popup_inline_error_above_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/popup_inline_error.9.png b/core/res/res/drawable-xhdpi/popup_inline_error_am.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/popup_inline_error.9.png
rename to core/res/res/drawable-xhdpi/popup_inline_error_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/popup_inline_error_holo_dark.9.png b/core/res/res/drawable-xhdpi/popup_inline_error_holo_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/popup_inline_error_holo_dark.9.png
rename to core/res/res/drawable-xhdpi/popup_inline_error_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/popup_inline_error_holo_light.9.png b/core/res/res/drawable-xhdpi/popup_inline_error_holo_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/popup_inline_error_holo_light.9.png
rename to core/res/res/drawable-xhdpi/popup_inline_error_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_focused_dark.9.png b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_focused_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/quickcontact_badge_overlay_focused_dark.9.png
rename to core/res/res/drawable-xhdpi/quickcontact_badge_overlay_focused_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_focused_light.9.png b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_focused_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/quickcontact_badge_overlay_focused_light.9.png
rename to core/res/res/drawable-xhdpi/quickcontact_badge_overlay_focused_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_dark.9.png b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_dark.9.png
rename to core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_light.9.png b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_light.9.png
rename to core/res/res/drawable-xhdpi/quickcontact_badge_overlay_normal_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_dark.9.png b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_dark.9.png
rename to core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_light.9.png b/core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_light.9.png
rename to core/res/res/drawable-xhdpi/quickcontact_badge_overlay_pressed_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_default_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_ab_default_holo_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/spinner_ab_default_holo_dark.9.png
rename to core/res/res/drawable-xhdpi/spinner_ab_default_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_default_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_ab_default_holo_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/spinner_ab_default_holo_light.9.png
rename to core/res/res/drawable-xhdpi/spinner_ab_default_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_dark.9.png
rename to core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_light.9.png
rename to core/res/res/drawable-xhdpi/spinner_ab_disabled_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/spinner_ab_focused_holo_dark.9.png
rename to core/res/res/drawable-xhdpi/spinner_ab_focused_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_ab_focused_holo_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/spinner_ab_focused_holo_light.9.png
rename to core/res/res/drawable-xhdpi/spinner_ab_focused_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_dark.9.png
rename to core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_light.9.png
rename to core/res/res/drawable-xhdpi/spinner_ab_pressed_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_default_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_default_holo_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/spinner_default_holo_dark.9.png
rename to core/res/res/drawable-xhdpi/spinner_default_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_default_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_default_holo_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/spinner_default_holo_light.9.png
rename to core/res/res/drawable-xhdpi/spinner_default_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_disabled_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_disabled_holo_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/spinner_disabled_holo_dark.9.png
rename to core/res/res/drawable-xhdpi/spinner_disabled_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_disabled_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_disabled_holo_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/spinner_disabled_holo_light.9.png
rename to core/res/res/drawable-xhdpi/spinner_disabled_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_focused_holo_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/spinner_focused_holo_dark.9.png
rename to core/res/res/drawable-xhdpi/spinner_focused_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_focused_holo_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/spinner_focused_holo_light.9.png
rename to core/res/res/drawable-xhdpi/spinner_focused_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_pressed_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_pressed_holo_dark_am.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/spinner_pressed_holo_dark.9.png
rename to core/res/res/drawable-xhdpi/spinner_pressed_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_pressed_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_pressed_holo_light_am.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/spinner_pressed_holo_light.9.png
rename to core/res/res/drawable-xhdpi/spinner_pressed_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_notify_call_mute.png b/core/res/res/drawable-xhdpi/stat_notify_call_mute.png
index adbd7b1..e143366 100644
--- a/core/res/res/drawable-xhdpi/stat_notify_call_mute.png
+++ b/core/res/res/drawable-xhdpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_sys_adb.png b/core/res/res/drawable-xhdpi/stat_sys_adb.png
deleted file mode 100644
index 576ae24..0000000
--- a/core/res/res/drawable-xhdpi/stat_sys_adb.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_sys_adb_am.png b/core/res/res/drawable-xhdpi/stat_sys_adb_am.png
new file mode 100644
index 0000000..3222a76
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/stat_sys_adb_am.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_sys_certificate_info.png b/core/res/res/drawable-xhdpi/stat_sys_certificate_info.png
new file mode 100644
index 0000000..3c93ea0
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/stat_sys_certificate_info.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_sys_secure.png b/core/res/res/drawable-xhdpi/stat_sys_secure.png
deleted file mode 100644
index bef2fd7..0000000
--- a/core/res/res/drawable-xhdpi/stat_sys_secure.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_sys_speakerphone.png b/core/res/res/drawable-xhdpi/stat_sys_speakerphone.png
index 51e648c..f7f7871 100644
--- a/core/res/res/drawable-xhdpi/stat_sys_speakerphone.png
+++ b/core/res/res/drawable-xhdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/toast_bar_bg.9.png b/core/res/res/drawable-xhdpi/toast_bar_bg.9.png
new file mode 100644
index 0000000..1dc4927
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/toast_bar_bg.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ab_bottom_solid_dark_holo.9.png b/core/res/res/drawable-xxhdpi/ab_bottom_solid_dark_holo.9.png
new file mode 100644
index 0000000..8358392
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ab_bottom_solid_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ab_bottom_solid_inverse_holo.9.png b/core/res/res/drawable-xxhdpi/ab_bottom_solid_inverse_holo.9.png
new file mode 100644
index 0000000..8c6e40c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ab_bottom_solid_inverse_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ab_bottom_solid_light_holo.9.png b/core/res/res/drawable-xxhdpi/ab_bottom_solid_light_holo.9.png
new file mode 100644
index 0000000..f6c33dc
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ab_bottom_solid_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ab_bottom_transparent_dark_holo.9.png b/core/res/res/drawable-xxhdpi/ab_bottom_transparent_dark_holo.9.png
new file mode 100644
index 0000000..f32ca94
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ab_bottom_transparent_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ab_bottom_transparent_light_holo.9.png b/core/res/res/drawable-xxhdpi/ab_bottom_transparent_light_holo.9.png
new file mode 100644
index 0000000..da69ea5
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ab_bottom_transparent_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ab_share_pack_holo_dark.9.png b/core/res/res/drawable-xxhdpi/ab_share_pack_holo_dark.9.png
new file mode 100644
index 0000000..18269a9
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ab_share_pack_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ab_share_pack_holo_light.9.png b/core/res/res/drawable-xxhdpi/ab_share_pack_holo_light.9.png
new file mode 100644
index 0000000..469f736
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ab_share_pack_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ab_solid_dark_holo.9.png b/core/res/res/drawable-xxhdpi/ab_solid_dark_holo.9.png
new file mode 100644
index 0000000..48be5cc
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ab_solid_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ab_solid_light_holo.9.png b/core/res/res/drawable-xxhdpi/ab_solid_light_holo.9.png
new file mode 100644
index 0000000..2e49b8d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ab_solid_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ab_solid_shadow_holo.9.png b/core/res/res/drawable-xxhdpi/ab_solid_shadow_holo.9.png
new file mode 100644
index 0000000..8071886
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ab_solid_shadow_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ab_stacked_solid_dark_holo.9.png b/core/res/res/drawable-xxhdpi/ab_stacked_solid_dark_holo.9.png
new file mode 100644
index 0000000..086069b
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ab_stacked_solid_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ab_stacked_solid_inverse_holo.9.png b/core/res/res/drawable-xxhdpi/ab_stacked_solid_inverse_holo.9.png
new file mode 100644
index 0000000..4074d81
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ab_stacked_solid_inverse_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ab_stacked_solid_light_holo.9.png b/core/res/res/drawable-xxhdpi/ab_stacked_solid_light_holo.9.png
new file mode 100644
index 0000000..8ce58b3
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ab_stacked_solid_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ab_stacked_transparent_dark_holo.9.png b/core/res/res/drawable-xxhdpi/ab_stacked_transparent_dark_holo.9.png
new file mode 100644
index 0000000..fd92764
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ab_stacked_transparent_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ab_stacked_transparent_light_holo.9.png b/core/res/res/drawable-xxhdpi/ab_stacked_transparent_light_holo.9.png
new file mode 100644
index 0000000..8d64aa7
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ab_stacked_transparent_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ab_transparent_dark_holo.9.png b/core/res/res/drawable-xxhdpi/ab_transparent_dark_holo.9.png
new file mode 100644
index 0000000..84155ccf
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ab_transparent_dark_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ab_transparent_light_holo.9.png b/core/res/res/drawable-xxhdpi/ab_transparent_light_holo.9.png
new file mode 100644
index 0000000..d48e27f
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ab_transparent_light_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_cab_done_default_holo_dark.9.png b/core/res/res/drawable-xxhdpi/btn_cab_done_default_holo_dark.9.png
new file mode 100644
index 0000000..95475ee
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_cab_done_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_cab_done_default_holo_light.9.png b/core/res/res/drawable-xxhdpi/btn_cab_done_default_holo_light.9.png
new file mode 100644
index 0000000..e1c55ad
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_cab_done_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_cab_done_focused_holo_dark.9.png b/core/res/res/drawable-xxhdpi/btn_cab_done_focused_holo_dark.9.png
new file mode 100644
index 0000000..6c49fe7
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_cab_done_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_cab_done_focused_holo_light.9.png b/core/res/res/drawable-xxhdpi/btn_cab_done_focused_holo_light.9.png
new file mode 100644
index 0000000..35a557e
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_cab_done_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_cab_done_pressed_holo_dark.9.png b/core/res/res/drawable-xxhdpi/btn_cab_done_pressed_holo_dark.9.png
new file mode 100644
index 0000000..7af87c8
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_cab_done_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_cab_done_pressed_holo_light.9.png b/core/res/res/drawable-xxhdpi/btn_cab_done_pressed_holo_light.9.png
new file mode 100644
index 0000000..0afe002
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_cab_done_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_off_disabled_focused_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_check_off_disabled_focused_holo_dark.png
new file mode 100644
index 0000000..0707776
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_check_off_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_off_disabled_focused_holo_light.png b/core/res/res/drawable-xxhdpi/btn_check_off_disabled_focused_holo_light.png
new file mode 100644
index 0000000..e1553b7
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_check_off_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_off_disabled_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_check_off_disabled_holo_dark.png
new file mode 100644
index 0000000..e74b8b7
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_check_off_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_off_disabled_holo_light.png b/core/res/res/drawable-xxhdpi/btn_check_off_disabled_holo_light.png
new file mode 100644
index 0000000..47a6373
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_check_off_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_off_focused_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_check_off_focused_holo_dark.png
new file mode 100644
index 0000000..b0353feb
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_check_off_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_off_focused_holo_light.png b/core/res/res/drawable-xxhdpi/btn_check_off_focused_holo_light.png
new file mode 100644
index 0000000..889a67c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_check_off_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_off_holo.png b/core/res/res/drawable-xxhdpi/btn_check_off_holo.png
new file mode 100644
index 0000000..cdcfdef
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_check_off_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_off_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_check_off_holo_dark.png
new file mode 100644
index 0000000..ecfc08c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_check_off_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_off_holo_light.png b/core/res/res/drawable-xxhdpi/btn_check_off_holo_light.png
new file mode 100644
index 0000000..b067b58
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_check_off_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_off_pressed_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_check_off_pressed_holo_dark.png
new file mode 100644
index 0000000..a54cfbf3
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_check_off_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_off_pressed_holo_light.png b/core/res/res/drawable-xxhdpi/btn_check_off_pressed_holo_light.png
new file mode 100644
index 0000000..5afea71
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_check_off_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_on_disabled_focused_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_check_on_disabled_focused_holo_dark.png
new file mode 100644
index 0000000..d249372
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_check_on_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_on_disabled_focused_holo_light.png b/core/res/res/drawable-xxhdpi/btn_check_on_disabled_focused_holo_light.png
new file mode 100644
index 0000000..b544001
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_check_on_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_on_disabled_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_check_on_disabled_holo_dark.png
new file mode 100644
index 0000000..eff125b
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_check_on_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_on_disabled_holo_light.png b/core/res/res/drawable-xxhdpi/btn_check_on_disabled_holo_light.png
new file mode 100644
index 0000000..013c1f6
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_check_on_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_on_focused_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_check_on_focused_holo_dark.png
new file mode 100644
index 0000000..e0d942a
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_check_on_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_on_focused_holo_light.png b/core/res/res/drawable-xxhdpi/btn_check_on_focused_holo_light.png
new file mode 100644
index 0000000..83f8dfd
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_check_on_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_on_holo.png b/core/res/res/drawable-xxhdpi/btn_check_on_holo.png
new file mode 100644
index 0000000..6193147
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_check_on_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_on_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_check_on_holo_dark.png
new file mode 100644
index 0000000..1aafc83
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_check_on_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_on_holo_light.png b/core/res/res/drawable-xxhdpi/btn_check_on_holo_light.png
new file mode 100644
index 0000000..11598dd
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_check_on_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_on_pressed_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_check_on_pressed_holo_dark.png
new file mode 100644
index 0000000..f4f58b7
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_check_on_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_on_pressed_holo_light.png b/core/res/res/drawable-xxhdpi/btn_check_on_pressed_holo_light.png
new file mode 100644
index 0000000..c270562
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_check_on_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_code_lock_default_holo.png b/core/res/res/drawable-xxhdpi/btn_code_lock_default_holo.png
new file mode 100755
index 0000000..1b6c9b5
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_code_lock_default_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_code_lock_touched_holo.png b/core/res/res/drawable-xxhdpi/btn_code_lock_touched_holo.png
new file mode 100755
index 0000000..dd13af8
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_code_lock_touched_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_default_disabled_focused_holo_dark.9.png b/core/res/res/drawable-xxhdpi/btn_default_disabled_focused_holo_dark.9.png
new file mode 100644
index 0000000..aea519c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_default_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_default_disabled_focused_holo_light.9.png b/core/res/res/drawable-xxhdpi/btn_default_disabled_focused_holo_light.9.png
new file mode 100644
index 0000000..8ec4bf5
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_default_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_default_disabled_holo.9.png b/core/res/res/drawable-xxhdpi/btn_default_disabled_holo.9.png
new file mode 100644
index 0000000..60732b3
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_default_disabled_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_default_disabled_holo_dark.9.png b/core/res/res/drawable-xxhdpi/btn_default_disabled_holo_dark.9.png
new file mode 100644
index 0000000..12bac53
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_default_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_default_disabled_holo_light.9.png b/core/res/res/drawable-xxhdpi/btn_default_disabled_holo_light.9.png
new file mode 100644
index 0000000..b4c90d4
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_default_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_default_focused_holo.9.png b/core/res/res/drawable-xxhdpi/btn_default_focused_holo.9.png
new file mode 100644
index 0000000..33c3ebb
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_default_focused_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_default_focused_holo_dark.9.png b/core/res/res/drawable-xxhdpi/btn_default_focused_holo_dark.9.png
new file mode 100644
index 0000000..f7bfd78
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_default_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_default_focused_holo_light.9.png b/core/res/res/drawable-xxhdpi/btn_default_focused_holo_light.9.png
new file mode 100644
index 0000000..7f5432f
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_default_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_default_normal_holo.9.png b/core/res/res/drawable-xxhdpi/btn_default_normal_holo.9.png
new file mode 100644
index 0000000..c1632c8
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_default_normal_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_default_normal_holo_dark.9.png b/core/res/res/drawable-xxhdpi/btn_default_normal_holo_dark.9.png
new file mode 100644
index 0000000..6449593
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_default_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_default_normal_holo_light.9.png b/core/res/res/drawable-xxhdpi/btn_default_normal_holo_light.9.png
new file mode 100644
index 0000000..68be3c5
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_default_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_default_pressed_holo.9.png b/core/res/res/drawable-xxhdpi/btn_default_pressed_holo.9.png
new file mode 100644
index 0000000..e3d3eb1
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_default_pressed_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_default_pressed_holo_dark.9.png b/core/res/res/drawable-xxhdpi/btn_default_pressed_holo_dark.9.png
new file mode 100644
index 0000000..19706e0
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_default_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_default_pressed_holo_light.9.png b/core/res/res/drawable-xxhdpi/btn_default_pressed_holo_light.9.png
new file mode 100644
index 0000000..af8eebb
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_default_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_group_disabled_holo_dark.9.png b/core/res/res/drawable-xxhdpi/btn_group_disabled_holo_dark.9.png
new file mode 100644
index 0000000..54ff2c0
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_group_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_group_disabled_holo_light.9.png b/core/res/res/drawable-xxhdpi/btn_group_disabled_holo_light.9.png
new file mode 100644
index 0000000..e3c4945
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_group_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_group_focused_holo_dark.9.png b/core/res/res/drawable-xxhdpi/btn_group_focused_holo_dark.9.png
new file mode 100644
index 0000000..bd04226
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_group_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_group_focused_holo_light.9.png b/core/res/res/drawable-xxhdpi/btn_group_focused_holo_light.9.png
new file mode 100644
index 0000000..f7aa79e
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_group_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_group_normal_holo_dark.9.png b/core/res/res/drawable-xxhdpi/btn_group_normal_holo_dark.9.png
new file mode 100644
index 0000000..26f98fc
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_group_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_group_normal_holo_light.9.png b/core/res/res/drawable-xxhdpi/btn_group_normal_holo_light.9.png
new file mode 100644
index 0000000..1ba39f2
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_group_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_group_pressed_holo_dark.9.png b/core/res/res/drawable-xxhdpi/btn_group_pressed_holo_dark.9.png
new file mode 100644
index 0000000..531acc4
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_group_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_group_pressed_holo_light.9.png b/core/res/res/drawable-xxhdpi/btn_group_pressed_holo_light.9.png
new file mode 100644
index 0000000..358f546
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_group_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_off_disabled_focused_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_radio_off_disabled_focused_holo_dark.png
new file mode 100644
index 0000000..6c0f6f3
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_radio_off_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_off_disabled_focused_holo_light.png b/core/res/res/drawable-xxhdpi/btn_radio_off_disabled_focused_holo_light.png
new file mode 100644
index 0000000..63ac52b
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_radio_off_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_off_disabled_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_radio_off_disabled_holo_dark.png
new file mode 100644
index 0000000..946936e
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_radio_off_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_off_disabled_holo_light.png b/core/res/res/drawable-xxhdpi/btn_radio_off_disabled_holo_light.png
new file mode 100644
index 0000000..06f0cc7
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_radio_off_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_off_focused_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_radio_off_focused_holo_dark.png
new file mode 100644
index 0000000..abbf1ae
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_radio_off_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_off_focused_holo_light.png b/core/res/res/drawable-xxhdpi/btn_radio_off_focused_holo_light.png
new file mode 100644
index 0000000..28f5843
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_radio_off_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_off_holo.png b/core/res/res/drawable-xxhdpi/btn_radio_off_holo.png
new file mode 100644
index 0000000..c8ac939
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_radio_off_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_off_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_radio_off_holo_dark.png
new file mode 100644
index 0000000..a7afd00
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_radio_off_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_off_holo_light.png b/core/res/res/drawable-xxhdpi/btn_radio_off_holo_light.png
new file mode 100644
index 0000000..43fac43
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_radio_off_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_off_pressed_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_radio_off_pressed_holo_dark.png
new file mode 100644
index 0000000..9bc460f
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_radio_off_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_off_pressed_holo_light.png b/core/res/res/drawable-xxhdpi/btn_radio_off_pressed_holo_light.png
new file mode 100644
index 0000000..96c63b1
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_radio_off_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_on_disabled_focused_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_radio_on_disabled_focused_holo_dark.png
new file mode 100644
index 0000000..16b2023
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_radio_on_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_on_disabled_focused_holo_light.png b/core/res/res/drawable-xxhdpi/btn_radio_on_disabled_focused_holo_light.png
new file mode 100644
index 0000000..f03d07f
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_radio_on_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_on_disabled_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_radio_on_disabled_holo_dark.png
new file mode 100644
index 0000000..66b833d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_radio_on_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_on_disabled_holo_light.png b/core/res/res/drawable-xxhdpi/btn_radio_on_disabled_holo_light.png
new file mode 100644
index 0000000..adb7304
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_radio_on_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_on_focused_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_radio_on_focused_holo_dark.png
new file mode 100644
index 0000000..cb7d6c8
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_radio_on_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_on_focused_holo_light.png b/core/res/res/drawable-xxhdpi/btn_radio_on_focused_holo_light.png
new file mode 100644
index 0000000..12a0601
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_radio_on_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_on_holo.png b/core/res/res/drawable-xxhdpi/btn_radio_on_holo.png
new file mode 100644
index 0000000..2a11733
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_radio_on_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_on_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_radio_on_holo_dark.png
new file mode 100644
index 0000000..f3ce811
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_radio_on_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_on_holo_light.png b/core/res/res/drawable-xxhdpi/btn_radio_on_holo_light.png
new file mode 100644
index 0000000..43142b6
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_radio_on_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_on_pressed_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_radio_on_pressed_holo_dark.png
new file mode 100644
index 0000000..de76d56
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_radio_on_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_on_pressed_holo_light.png b/core/res/res/drawable-xxhdpi/btn_radio_on_pressed_holo_light.png
new file mode 100644
index 0000000..d7eee84
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_radio_on_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_rating_star_off_disabled_focused_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_rating_star_off_disabled_focused_holo_dark.png
new file mode 100644
index 0000000..292c752
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_rating_star_off_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_rating_star_off_disabled_focused_holo_light.png b/core/res/res/drawable-xxhdpi/btn_rating_star_off_disabled_focused_holo_light.png
new file mode 100644
index 0000000..635c009
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_rating_star_off_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_rating_star_off_disabled_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_rating_star_off_disabled_holo_dark.png
new file mode 100644
index 0000000..fef0797
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_rating_star_off_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_rating_star_off_disabled_holo_light.png b/core/res/res/drawable-xxhdpi/btn_rating_star_off_disabled_holo_light.png
new file mode 100644
index 0000000..c43977dd
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_rating_star_off_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_rating_star_off_focused_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_rating_star_off_focused_holo_dark.png
new file mode 100644
index 0000000..521dc80
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_rating_star_off_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_rating_star_off_focused_holo_light.png b/core/res/res/drawable-xxhdpi/btn_rating_star_off_focused_holo_light.png
new file mode 100644
index 0000000..71a367b
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_rating_star_off_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_rating_star_off_normal_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_rating_star_off_normal_holo_dark.png
new file mode 100644
index 0000000..35f72fa
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_rating_star_off_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_rating_star_off_normal_holo_light.png b/core/res/res/drawable-xxhdpi/btn_rating_star_off_normal_holo_light.png
new file mode 100644
index 0000000..c8541c3
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_rating_star_off_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_rating_star_off_pressed_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_rating_star_off_pressed_holo_dark.png
new file mode 100644
index 0000000..899e577
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_rating_star_off_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_rating_star_off_pressed_holo_light.png b/core/res/res/drawable-xxhdpi/btn_rating_star_off_pressed_holo_light.png
new file mode 100644
index 0000000..aaa6826
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_rating_star_off_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_rating_star_on_disabled_focused_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_rating_star_on_disabled_focused_holo_dark.png
new file mode 100644
index 0000000..e699edc
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_rating_star_on_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_rating_star_on_disabled_focused_holo_light.png b/core/res/res/drawable-xxhdpi/btn_rating_star_on_disabled_focused_holo_light.png
new file mode 100644
index 0000000..a59c23c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_rating_star_on_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_rating_star_on_disabled_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_rating_star_on_disabled_holo_dark.png
new file mode 100644
index 0000000..d2504fb
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_rating_star_on_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_rating_star_on_disabled_holo_light.png b/core/res/res/drawable-xxhdpi/btn_rating_star_on_disabled_holo_light.png
new file mode 100644
index 0000000..d514bdd
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_rating_star_on_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_rating_star_on_focused_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_rating_star_on_focused_holo_dark.png
new file mode 100644
index 0000000..53c7a53
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_rating_star_on_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_rating_star_on_focused_holo_light.png b/core/res/res/drawable-xxhdpi/btn_rating_star_on_focused_holo_light.png
new file mode 100644
index 0000000..f942490
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_rating_star_on_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_rating_star_on_normal_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_rating_star_on_normal_holo_dark.png
new file mode 100644
index 0000000..11bae7c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_rating_star_on_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_rating_star_on_normal_holo_light.png b/core/res/res/drawable-xxhdpi/btn_rating_star_on_normal_holo_light.png
new file mode 100644
index 0000000..08804b5
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_rating_star_on_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_rating_star_on_pressed_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_rating_star_on_pressed_holo_dark.png
new file mode 100644
index 0000000..e15fc63
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_rating_star_on_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_rating_star_on_pressed_holo_light.png b/core/res/res/drawable-xxhdpi/btn_rating_star_on_pressed_holo_light.png
new file mode 100644
index 0000000..cc82a54
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_rating_star_on_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_star_off_disabled_focused_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_star_off_disabled_focused_holo_dark.png
new file mode 100644
index 0000000..853243d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_star_off_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_star_off_disabled_focused_holo_light.png b/core/res/res/drawable-xxhdpi/btn_star_off_disabled_focused_holo_light.png
new file mode 100644
index 0000000..b5cd0bb
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_star_off_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_star_off_disabled_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_star_off_disabled_holo_dark.png
new file mode 100644
index 0000000..bb16a5f7
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_star_off_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_star_off_disabled_holo_light.png b/core/res/res/drawable-xxhdpi/btn_star_off_disabled_holo_light.png
new file mode 100644
index 0000000..c178a9b
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_star_off_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_star_off_focused_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_star_off_focused_holo_dark.png
new file mode 100644
index 0000000..886f395
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_star_off_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_star_off_focused_holo_light.png b/core/res/res/drawable-xxhdpi/btn_star_off_focused_holo_light.png
new file mode 100644
index 0000000..ab2b334
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_star_off_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_star_off_normal_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_star_off_normal_holo_dark.png
new file mode 100644
index 0000000..59a8547
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_star_off_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_star_off_normal_holo_light.png b/core/res/res/drawable-xxhdpi/btn_star_off_normal_holo_light.png
new file mode 100644
index 0000000..14cac81
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_star_off_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_star_off_pressed_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_star_off_pressed_holo_dark.png
new file mode 100644
index 0000000..b756e79
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_star_off_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_star_off_pressed_holo_light.png b/core/res/res/drawable-xxhdpi/btn_star_off_pressed_holo_light.png
new file mode 100644
index 0000000..89bf5b4
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_star_off_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_star_on_disabled_focused_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_star_on_disabled_focused_holo_dark.png
new file mode 100644
index 0000000..7027cc2
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_star_on_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_star_on_disabled_focused_holo_light.png b/core/res/res/drawable-xxhdpi/btn_star_on_disabled_focused_holo_light.png
new file mode 100644
index 0000000..d491c5b
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_star_on_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_star_on_disabled_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_star_on_disabled_holo_dark.png
new file mode 100644
index 0000000..f968b1a
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_star_on_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_star_on_disabled_holo_light.png b/core/res/res/drawable-xxhdpi/btn_star_on_disabled_holo_light.png
new file mode 100644
index 0000000..1999f68
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_star_on_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_star_on_focused_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_star_on_focused_holo_dark.png
new file mode 100644
index 0000000..ab4b58c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_star_on_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_star_on_focused_holo_light.png b/core/res/res/drawable-xxhdpi/btn_star_on_focused_holo_light.png
new file mode 100644
index 0000000..cd44fa6
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_star_on_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_star_on_normal_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_star_on_normal_holo_dark.png
new file mode 100644
index 0000000..8847d78
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_star_on_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_star_on_normal_holo_light.png b/core/res/res/drawable-xxhdpi/btn_star_on_normal_holo_light.png
new file mode 100644
index 0000000..3ef0498
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_star_on_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_star_on_pressed_holo_dark.png b/core/res/res/drawable-xxhdpi/btn_star_on_pressed_holo_dark.png
new file mode 100644
index 0000000..50e4940
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_star_on_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_star_on_pressed_holo_light.png b/core/res/res/drawable-xxhdpi/btn_star_on_pressed_holo_light.png
new file mode 100644
index 0000000..0b77905
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_star_on_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_toggle_off_disabled_focused_holo_dark.9.png b/core/res/res/drawable-xxhdpi/btn_toggle_off_disabled_focused_holo_dark.9.png
new file mode 100644
index 0000000..e5ec283
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_toggle_off_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_toggle_off_disabled_focused_holo_light.9.png b/core/res/res/drawable-xxhdpi/btn_toggle_off_disabled_focused_holo_light.9.png
new file mode 100644
index 0000000..5cd267d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_toggle_off_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_toggle_off_disabled_holo_dark.9.png b/core/res/res/drawable-xxhdpi/btn_toggle_off_disabled_holo_dark.9.png
new file mode 100644
index 0000000..c34c7af
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_toggle_off_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_toggle_off_disabled_holo_light.9.png b/core/res/res/drawable-xxhdpi/btn_toggle_off_disabled_holo_light.9.png
new file mode 100644
index 0000000..9b3900a
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_toggle_off_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_toggle_off_focused_holo_dark.9.png b/core/res/res/drawable-xxhdpi/btn_toggle_off_focused_holo_dark.9.png
new file mode 100644
index 0000000..345fe9c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_toggle_off_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_toggle_off_focused_holo_light.9.png b/core/res/res/drawable-xxhdpi/btn_toggle_off_focused_holo_light.9.png
new file mode 100644
index 0000000..b338843
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_toggle_off_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_toggle_off_normal_holo_dark.9.png b/core/res/res/drawable-xxhdpi/btn_toggle_off_normal_holo_dark.9.png
new file mode 100644
index 0000000..3f6ab80
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_toggle_off_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_toggle_off_normal_holo_light.9.png b/core/res/res/drawable-xxhdpi/btn_toggle_off_normal_holo_light.9.png
new file mode 100644
index 0000000..df71589
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_toggle_off_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_toggle_off_pressed_holo_dark.9.png b/core/res/res/drawable-xxhdpi/btn_toggle_off_pressed_holo_dark.9.png
new file mode 100644
index 0000000..2e21a6f
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_toggle_off_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_toggle_off_pressed_holo_light.9.png b/core/res/res/drawable-xxhdpi/btn_toggle_off_pressed_holo_light.9.png
new file mode 100644
index 0000000..1a346c9
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_toggle_off_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_toggle_on_disabled_focused_holo_dark.9.png b/core/res/res/drawable-xxhdpi/btn_toggle_on_disabled_focused_holo_dark.9.png
new file mode 100644
index 0000000..ea15883
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_toggle_on_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_toggle_on_disabled_focused_holo_light.9.png b/core/res/res/drawable-xxhdpi/btn_toggle_on_disabled_focused_holo_light.9.png
new file mode 100644
index 0000000..b403039
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_toggle_on_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_toggle_on_disabled_holo_dark.9.png b/core/res/res/drawable-xxhdpi/btn_toggle_on_disabled_holo_dark.9.png
new file mode 100644
index 0000000..f12643e
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_toggle_on_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_toggle_on_disabled_holo_light.9.png b/core/res/res/drawable-xxhdpi/btn_toggle_on_disabled_holo_light.9.png
new file mode 100644
index 0000000..3090c9a
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_toggle_on_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_toggle_on_focused_holo_dark.9.png b/core/res/res/drawable-xxhdpi/btn_toggle_on_focused_holo_dark.9.png
new file mode 100644
index 0000000..2fb4d91
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_toggle_on_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_toggle_on_focused_holo_light.9.png b/core/res/res/drawable-xxhdpi/btn_toggle_on_focused_holo_light.9.png
new file mode 100644
index 0000000..5e17dd5
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_toggle_on_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_toggle_on_normal_holo_dark.9.png b/core/res/res/drawable-xxhdpi/btn_toggle_on_normal_holo_dark.9.png
new file mode 100644
index 0000000..bf9b997
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_toggle_on_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_toggle_on_normal_holo_light.9.png b/core/res/res/drawable-xxhdpi/btn_toggle_on_normal_holo_light.9.png
new file mode 100644
index 0000000..b36f670c6
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_toggle_on_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_toggle_on_pressed_holo_dark.9.png b/core/res/res/drawable-xxhdpi/btn_toggle_on_pressed_holo_dark.9.png
new file mode 100644
index 0000000..d0c2151
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_toggle_on_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_toggle_on_pressed_holo_light.9.png b/core/res/res/drawable-xxhdpi/btn_toggle_on_pressed_holo_light.9.png
new file mode 100644
index 0000000..fab8dc1
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_toggle_on_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/cab_background_bottom_holo_dark.9.png b/core/res/res/drawable-xxhdpi/cab_background_bottom_holo_dark.9.png
new file mode 100644
index 0000000..8666113
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/cab_background_bottom_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/cab_background_bottom_holo_light.9.png b/core/res/res/drawable-xxhdpi/cab_background_bottom_holo_light.9.png
new file mode 100644
index 0000000..805927b
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/cab_background_bottom_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/cab_background_top_holo_dark.9.png b/core/res/res/drawable-xxhdpi/cab_background_top_holo_dark.9.png
new file mode 100644
index 0000000..418f322
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/cab_background_top_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/cab_background_top_holo_light.9.png b/core/res/res/drawable-xxhdpi/cab_background_top_holo_light.9.png
new file mode 100644
index 0000000..a5a59d4
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/cab_background_top_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/combobox_disabled.png b/core/res/res/drawable-xxhdpi/combobox_disabled.png
new file mode 100644
index 0000000..d342344
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/combobox_disabled.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/combobox_nohighlight.png b/core/res/res/drawable-xxhdpi/combobox_nohighlight.png
new file mode 100644
index 0000000..377fbd3
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/combobox_nohighlight.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/create_contact.png b/core/res/res/drawable-xxhdpi/create_contact.png
new file mode 100644
index 0000000..9baf195
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/create_contact.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/day_picker_week_view_dayline_holo.9.png b/core/res/res/drawable-xxhdpi/day_picker_week_view_dayline_holo.9.png
new file mode 100644
index 0000000..6b22972
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/day_picker_week_view_dayline_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/dialog_bottom_holo_dark.9.png b/core/res/res/drawable-xxhdpi/dialog_bottom_holo_dark.9.png
new file mode 100644
index 0000000..0d2ba50
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/dialog_bottom_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/dialog_bottom_holo_light.9.png b/core/res/res/drawable-xxhdpi/dialog_bottom_holo_light.9.png
new file mode 100644
index 0000000..13462d1
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/dialog_bottom_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/dialog_full_holo_dark.9.png b/core/res/res/drawable-xxhdpi/dialog_full_holo_dark.9.png
new file mode 100644
index 0000000..b029809
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/dialog_full_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/dialog_full_holo_light.9.png b/core/res/res/drawable-xxhdpi/dialog_full_holo_light.9.png
new file mode 100644
index 0000000..63dd192
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/dialog_full_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/dialog_ic_close_focused_holo_dark.png b/core/res/res/drawable-xxhdpi/dialog_ic_close_focused_holo_dark.png
new file mode 100644
index 0000000..ffe7cbf
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/dialog_ic_close_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/dialog_ic_close_focused_holo_light.png b/core/res/res/drawable-xxhdpi/dialog_ic_close_focused_holo_light.png
new file mode 100644
index 0000000..f21e320
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/dialog_ic_close_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/dialog_ic_close_normal_holo_dark.png b/core/res/res/drawable-xxhdpi/dialog_ic_close_normal_holo_dark.png
new file mode 100644
index 0000000..87cf4d5
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/dialog_ic_close_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/dialog_ic_close_normal_holo_light.png b/core/res/res/drawable-xxhdpi/dialog_ic_close_normal_holo_light.png
new file mode 100644
index 0000000..8d185f4
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/dialog_ic_close_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/dialog_ic_close_pressed_holo_dark.png b/core/res/res/drawable-xxhdpi/dialog_ic_close_pressed_holo_dark.png
new file mode 100644
index 0000000..cb2ec6a
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/dialog_ic_close_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/dialog_ic_close_pressed_holo_light.png b/core/res/res/drawable-xxhdpi/dialog_ic_close_pressed_holo_light.png
new file mode 100644
index 0000000..776dbfd
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/dialog_ic_close_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/dialog_middle_holo_dark.9.png b/core/res/res/drawable-xxhdpi/dialog_middle_holo_dark.9.png
new file mode 100644
index 0000000..d922fd6
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/dialog_middle_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/dialog_middle_holo_light.9.png b/core/res/res/drawable-xxhdpi/dialog_middle_holo_light.9.png
new file mode 100644
index 0000000..1298194
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/dialog_middle_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/dialog_top_holo_dark.9.png b/core/res/res/drawable-xxhdpi/dialog_top_holo_dark.9.png
new file mode 100644
index 0000000..baf7be3
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/dialog_top_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/dialog_top_holo_light.9.png b/core/res/res/drawable-xxhdpi/dialog_top_holo_light.9.png
new file mode 100644
index 0000000..f35251f
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/dialog_top_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/emo_im_angel.png b/core/res/res/drawable-xxhdpi/emo_im_angel.png
new file mode 100644
index 0000000..7d317e2
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/emo_im_angel.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/emo_im_cool.png b/core/res/res/drawable-xxhdpi/emo_im_cool.png
new file mode 100644
index 0000000..a05fabe
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/emo_im_cool.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/emo_im_crying.png b/core/res/res/drawable-xxhdpi/emo_im_crying.png
new file mode 100644
index 0000000..102800d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/emo_im_crying.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/emo_im_embarrassed.png b/core/res/res/drawable-xxhdpi/emo_im_embarrassed.png
new file mode 100644
index 0000000..6e5d226
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/emo_im_embarrassed.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/emo_im_foot_in_mouth.png b/core/res/res/drawable-xxhdpi/emo_im_foot_in_mouth.png
new file mode 100644
index 0000000..c328f8c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/emo_im_foot_in_mouth.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/emo_im_happy.png b/core/res/res/drawable-xxhdpi/emo_im_happy.png
new file mode 100644
index 0000000..11e0163
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/emo_im_happy.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/emo_im_kissing.png b/core/res/res/drawable-xxhdpi/emo_im_kissing.png
new file mode 100644
index 0000000..b929861
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/emo_im_kissing.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/emo_im_laughing.png b/core/res/res/drawable-xxhdpi/emo_im_laughing.png
new file mode 100644
index 0000000..4ed90bc
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/emo_im_laughing.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/emo_im_lips_are_sealed.png b/core/res/res/drawable-xxhdpi/emo_im_lips_are_sealed.png
new file mode 100644
index 0000000..bcbcf8d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/emo_im_lips_are_sealed.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/emo_im_money_mouth.png b/core/res/res/drawable-xxhdpi/emo_im_money_mouth.png
new file mode 100644
index 0000000..e17cf77
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/emo_im_money_mouth.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/emo_im_sad.png b/core/res/res/drawable-xxhdpi/emo_im_sad.png
new file mode 100644
index 0000000..0696d99
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/emo_im_sad.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/emo_im_surprised.png b/core/res/res/drawable-xxhdpi/emo_im_surprised.png
new file mode 100644
index 0000000..bd821d7
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/emo_im_surprised.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/emo_im_tongue_sticking_out.png b/core/res/res/drawable-xxhdpi/emo_im_tongue_sticking_out.png
new file mode 100644
index 0000000..af21474
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/emo_im_tongue_sticking_out.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/emo_im_undecided.png b/core/res/res/drawable-xxhdpi/emo_im_undecided.png
new file mode 100644
index 0000000..c43aa0b
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/emo_im_undecided.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/emo_im_winking.png b/core/res/res/drawable-xxhdpi/emo_im_winking.png
new file mode 100644
index 0000000..41cdd23
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/emo_im_winking.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/emo_im_wtf.png b/core/res/res/drawable-xxhdpi/emo_im_wtf.png
new file mode 100644
index 0000000..36f0b32
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/emo_im_wtf.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/emo_im_yelling.png b/core/res/res/drawable-xxhdpi/emo_im_yelling.png
new file mode 100644
index 0000000..db210eb
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/emo_im_yelling.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/expander_close_holo_dark.9.png b/core/res/res/drawable-xxhdpi/expander_close_holo_dark.9.png
new file mode 100644
index 0000000..fb41e44
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/expander_close_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/expander_close_holo_light.9.png b/core/res/res/drawable-xxhdpi/expander_close_holo_light.9.png
new file mode 100644
index 0000000..f3042a7
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/expander_close_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/expander_open_holo_dark.9.png b/core/res/res/drawable-xxhdpi/expander_open_holo_dark.9.png
new file mode 100644
index 0000000..b1f006a
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/expander_open_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/expander_open_holo_light.9.png b/core/res/res/drawable-xxhdpi/expander_open_holo_light.9.png
new file mode 100644
index 0000000..bac07f6
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/expander_open_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/fastscroll_label_left_holo_dark.9.png b/core/res/res/drawable-xxhdpi/fastscroll_label_left_holo_dark.9.png
new file mode 100644
index 0000000..c9b5893
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/fastscroll_label_left_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/fastscroll_label_left_holo_light.9.png b/core/res/res/drawable-xxhdpi/fastscroll_label_left_holo_light.9.png
new file mode 100644
index 0000000..a1326ed
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/fastscroll_label_left_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/fastscroll_label_right_holo_dark.9.png b/core/res/res/drawable-xxhdpi/fastscroll_label_right_holo_dark.9.png
new file mode 100644
index 0000000..91152ea
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/fastscroll_label_right_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/fastscroll_label_right_holo_light.9.png b/core/res/res/drawable-xxhdpi/fastscroll_label_right_holo_light.9.png
new file mode 100644
index 0000000..1541e97
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/fastscroll_label_right_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/fastscroll_thumb_default_holo.png b/core/res/res/drawable-xxhdpi/fastscroll_thumb_default_holo.png
new file mode 100644
index 0000000..d8335d5
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/fastscroll_thumb_default_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/fastscroll_thumb_pressed_holo.png b/core/res/res/drawable-xxhdpi/fastscroll_thumb_pressed_holo.png
new file mode 100644
index 0000000..cdc13e1
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/fastscroll_thumb_pressed_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/fastscroll_track_default_holo_dark.9.png b/core/res/res/drawable-xxhdpi/fastscroll_track_default_holo_dark.9.png
new file mode 100644
index 0000000..b9455ff
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/fastscroll_track_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/fastscroll_track_default_holo_light.9.png b/core/res/res/drawable-xxhdpi/fastscroll_track_default_holo_light.9.png
new file mode 100644
index 0000000..a5c54dc
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/fastscroll_track_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/fastscroll_track_pressed_holo_dark.9.png b/core/res/res/drawable-xxhdpi/fastscroll_track_pressed_holo_dark.9.png
new file mode 100644
index 0000000..eaf0969
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/fastscroll_track_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/fastscroll_track_pressed_holo_light.9.png b/core/res/res/drawable-xxhdpi/fastscroll_track_pressed_holo_light.9.png
new file mode 100644
index 0000000..9db45c0
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/fastscroll_track_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_ab_back_holo_dark_am.png b/core/res/res/drawable-xxhdpi/ic_ab_back_holo_dark_am.png
new file mode 100644
index 0000000..04d1348
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_ab_back_holo_dark_am.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_ab_back_holo_light_am.png b/core/res/res/drawable-xxhdpi/ic_ab_back_holo_light_am.png
new file mode 100644
index 0000000..962dba3
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_ab_back_holo_light_am.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_action_assist_generic_activated.png b/core/res/res/drawable-xxhdpi/ic_action_assist_generic_activated.png
new file mode 100644
index 0000000..cc38e83
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_action_assist_generic_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_action_assist_generic_normal.png b/core/res/res/drawable-xxhdpi/ic_action_assist_generic_normal.png
new file mode 100644
index 0000000..42f96eb
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_action_assist_generic_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_audio_alarm.png b/core/res/res/drawable-xxhdpi/ic_audio_alarm.png
new file mode 100755
index 0000000..c1c3d35
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_audio_alarm.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_audio_alarm_mute.png b/core/res/res/drawable-xxhdpi/ic_audio_alarm_mute.png
new file mode 100644
index 0000000..4bcee68
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_audio_alarm_mute.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_audio_bt.png b/core/res/res/drawable-xxhdpi/ic_audio_bt.png
new file mode 100755
index 0000000..140edac
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_audio_bt.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_audio_bt_mute.png b/core/res/res/drawable-xxhdpi/ic_audio_bt_mute.png
new file mode 100644
index 0000000..97829b4
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_audio_bt_mute.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_audio_notification_am.png b/core/res/res/drawable-xxhdpi/ic_audio_notification_am.png
new file mode 100755
index 0000000..fb0e96e
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_audio_notification_am.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_audio_notification_mute_am.png b/core/res/res/drawable-xxhdpi/ic_audio_notification_mute_am.png
new file mode 100644
index 0000000..3aa7b53
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_audio_notification_mute_am.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_audio_phone_am.png b/core/res/res/drawable-xxhdpi/ic_audio_phone_am.png
new file mode 100644
index 0000000..1fd54a1
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_audio_phone_am.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_audio_ring_notif_am.png b/core/res/res/drawable-xxhdpi/ic_audio_ring_notif_am.png
new file mode 100644
index 0000000..699711c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_audio_ring_notif_am.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_audio_ring_notif_mute_am.png b/core/res/res/drawable-xxhdpi/ic_audio_ring_notif_mute_am.png
new file mode 100644
index 0000000..19d92ba
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_audio_ring_notif_mute_am.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_audio_ring_notif_vibrate_am.png b/core/res/res/drawable-xxhdpi/ic_audio_ring_notif_vibrate_am.png
new file mode 100644
index 0000000..fdcfd56
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_audio_ring_notif_vibrate_am.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_audio_vol_am.png b/core/res/res/drawable-xxhdpi/ic_audio_vol_am.png
new file mode 100755
index 0000000..15b6311
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_audio_vol_am.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_audio_vol_mute_am.png b/core/res/res/drawable-xxhdpi/ic_audio_vol_mute_am.png
new file mode 100644
index 0000000..b8f4111
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_audio_vol_mute_am.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_btn_search_go.png b/core/res/res/drawable-xxhdpi/ic_btn_search_go.png
new file mode 100644
index 0000000..1f4301d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_btn_search_go.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_btn_speak_now.png b/core/res/res/drawable-xxhdpi/ic_btn_speak_now.png
new file mode 100644
index 0000000..b15f385
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_btn_speak_now.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_bullet_key_permission.png b/core/res/res/drawable-xxhdpi/ic_bullet_key_permission.png
new file mode 100644
index 0000000..a74c286
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_bullet_key_permission.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_cab_done_holo.png b/core/res/res/drawable-xxhdpi/ic_cab_done_holo.png
new file mode 100644
index 0000000..a23a3ae
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_cab_done_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_cab_done_holo_dark.png b/core/res/res/drawable-xxhdpi/ic_cab_done_holo_dark.png
new file mode 100644
index 0000000..fdecbe1
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_cab_done_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_cab_done_holo_light.png b/core/res/res/drawable-xxhdpi/ic_cab_done_holo_light.png
new file mode 100644
index 0000000..ca93e70
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_cab_done_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_commit_search_api_holo_dark.png b/core/res/res/drawable-xxhdpi/ic_commit_search_api_holo_dark.png
new file mode 100644
index 0000000..6e48dc6
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_commit_search_api_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_commit_search_api_holo_light.png b/core/res/res/drawable-xxhdpi/ic_commit_search_api_holo_light.png
new file mode 100644
index 0000000..d26f75e
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_commit_search_api_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_contact_picture.png b/core/res/res/drawable-xxhdpi/ic_contact_picture.png
new file mode 100644
index 0000000..b36ec17
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_contact_picture.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_contact_picture_180_holo_dark.png b/core/res/res/drawable-xxhdpi/ic_contact_picture_180_holo_dark.png
new file mode 100644
index 0000000..6e057ac
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_contact_picture_180_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_contact_picture_180_holo_light.png b/core/res/res/drawable-xxhdpi/ic_contact_picture_180_holo_light.png
new file mode 100644
index 0000000..4111bc5
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_contact_picture_180_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_contact_picture_holo_dark.png b/core/res/res/drawable-xxhdpi/ic_contact_picture_holo_dark.png
new file mode 100644
index 0000000..52a69c3
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_contact_picture_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_contact_picture_holo_light.png b/core/res/res/drawable-xxhdpi/ic_contact_picture_holo_light.png
new file mode 100644
index 0000000..5a41c23
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_contact_picture_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_dialog_alert_holo_dark.png b/core/res/res/drawable-xxhdpi/ic_dialog_alert_holo_dark.png
new file mode 100644
index 0000000..cdd6fd8
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_dialog_alert_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_dialog_alert_holo_light.png b/core/res/res/drawable-xxhdpi/ic_dialog_alert_holo_light.png
new file mode 100644
index 0000000..24ec28c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_dialog_alert_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_emergency.png b/core/res/res/drawable-xxhdpi/ic_emergency.png
new file mode 100644
index 0000000..d070311d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_emergency.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_input_delete.png b/core/res/res/drawable-xxhdpi/ic_input_delete.png
new file mode 100644
index 0000000..ea047dd
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_input_delete.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lock_airplane_mode.png b/core/res/res/drawable-xxhdpi/ic_lock_airplane_mode.png
new file mode 100644
index 0000000..116b891
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lock_airplane_mode.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lock_airplane_mode_off_am.png b/core/res/res/drawable-xxhdpi/ic_lock_airplane_mode_off_am.png
new file mode 100644
index 0000000..5ca72ed
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lock_airplane_mode_off_am.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lock_idle_alarm.png b/core/res/res/drawable-xxhdpi/ic_lock_idle_alarm.png
new file mode 100644
index 0000000..ed2d3c5
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lock_idle_alarm.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lock_lock.png b/core/res/res/drawable-xxhdpi/ic_lock_lock.png
new file mode 100644
index 0000000..1b8882c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lock_lock.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lock_power_off.png b/core/res/res/drawable-xxhdpi/ic_lock_power_off.png
new file mode 100644
index 0000000..061dc78
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lock_power_off.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lock_silent_mode_off.png b/core/res/res/drawable-xxhdpi/ic_lock_silent_mode_off.png
new file mode 100644
index 0000000..2cca958
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lock_silent_mode_off.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_alarm.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_alarm.png
new file mode 100644
index 0000000..f53fa8f
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_alarm.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_answer_active.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_answer_active.png
new file mode 100644
index 0000000..78a560f
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_answer_active.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_answer_focused.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_answer_focused.png
new file mode 100644
index 0000000..9c21761
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_answer_focused.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_answer_normal.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_answer_normal.png
new file mode 100644
index 0000000..9298b61
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_answer_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_camera_activated.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_camera_activated.png
new file mode 100644
index 0000000..c41fe84
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_camera_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_camera_normal.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_camera_normal.png
new file mode 100644
index 0000000..3c29157
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_camera_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_chevron_down.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_chevron_down.png
new file mode 100644
index 0000000..8b3458b
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_chevron_down.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_chevron_left.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_chevron_left.png
new file mode 100644
index 0000000..10cad65
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_chevron_left.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_chevron_right.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_chevron_right.png
new file mode 100644
index 0000000..9fe0601
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_chevron_right.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_chevron_up.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_chevron_up.png
new file mode 100644
index 0000000..8e9d6d0
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_chevron_up.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_decline_activated.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_decline_activated.png
new file mode 100644
index 0000000..1d114b1
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_decline_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_decline_focused.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_decline_focused.png
new file mode 100644
index 0000000..4db7876
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_decline_focused.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_decline_normal.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_decline_normal.png
new file mode 100644
index 0000000..89aece4
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_decline_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_emergencycall_normal.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_emergencycall_normal.png
new file mode 100644
index 0000000..4b99bad
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_emergencycall_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_emergencycall_pressed.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_emergencycall_pressed.png
new file mode 100644
index 0000000..d1bd72e
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_emergencycall_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_forgotpassword_normal.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_forgotpassword_normal.png
new file mode 100644
index 0000000..ece563c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_forgotpassword_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_forgotpassword_pressed.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_forgotpassword_pressed.png
new file mode 100644
index 0000000..ff3dfa1
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_forgotpassword_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_glowdot.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_glowdot.png
new file mode 100644
index 0000000..c0edd91
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_glowdot.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_google_activated.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_google_activated.png
new file mode 100644
index 0000000..d03fc06
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_google_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_google_focused.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_google_focused.png
new file mode 100644
index 0000000..76124a9
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_google_focused.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_google_normal.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_google_normal.png
new file mode 100644
index 0000000..d0680dc
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_google_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_handle_normal.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_handle_normal.png
new file mode 100644
index 0000000..a5418d8
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_handle_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_handle_pressed.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_handle_pressed.png
new file mode 100644
index 0000000..7528064
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_handle_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_ime.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_ime.png
new file mode 100644
index 0000000..cb5d2fa
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_ime.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_player_background.9.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_player_background.9.png
new file mode 100644
index 0000000..6dacccf
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_player_background.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_puk.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_puk.png
new file mode 100644
index 0000000..61db8cd
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_puk.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_silent_activated.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_silent_activated.png
new file mode 100644
index 0000000..fd295ec
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_silent_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_silent_focused.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_silent_focused.png
new file mode 100644
index 0000000..a2e1b69
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_silent_focused.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_silent_normal.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_silent_normal.png
new file mode 100644
index 0000000..d791ffa
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_silent_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_sim.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_sim.png
new file mode 100644
index 0000000..3ba4331a
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_sim.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_soundon_activated.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_soundon_activated.png
new file mode 100644
index 0000000..e469bf4
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_soundon_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_soundon_focused.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_soundon_focused.png
new file mode 100644
index 0000000..89b3213
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_soundon_focused.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_soundon_normal.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_soundon_normal.png
new file mode 100644
index 0000000..72bc5ee
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_soundon_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_text_activated.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_text_activated.png
new file mode 100644
index 0000000..10cbb7e
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_text_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_text_focusde.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_text_focusde.png
new file mode 100644
index 0000000..0cf7307
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_text_focusde.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_text_normal.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_text_normal.png
new file mode 100644
index 0000000..304996d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_text_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_unlock_activated.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_unlock_activated.png
new file mode 100644
index 0000000..dbd5d48
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_unlock_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_unlock_normal.png b/core/res/res/drawable-xxhdpi/ic_lockscreen_unlock_normal.png
new file mode 100644
index 0000000..153bfa9
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreen_unlock_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreens_now_button.png b/core/res/res/drawable-xxhdpi/ic_lockscreens_now_button.png
new file mode 100644
index 0000000..74ad3c8
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_lockscreens_now_button.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_embed_play.png b/core/res/res/drawable-xxhdpi/ic_media_embed_play.png
new file mode 100644
index 0000000..3bf5a82
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_embed_play.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_ff.png b/core/res/res/drawable-xxhdpi/ic_media_ff.png
new file mode 100644
index 0000000..ab9e022
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_ff.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_fullscreen.png b/core/res/res/drawable-xxhdpi/ic_media_fullscreen.png
new file mode 100644
index 0000000..5734f16
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_fullscreen.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_next.png b/core/res/res/drawable-xxhdpi/ic_media_next.png
new file mode 100644
index 0000000..ce0a143
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_next.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_pause.png b/core/res/res/drawable-xxhdpi/ic_media_pause.png
new file mode 100644
index 0000000..9a36b17
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_pause.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_play.png b/core/res/res/drawable-xxhdpi/ic_media_play.png
new file mode 100644
index 0000000..41f76bb
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_play.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_previous.png b/core/res/res/drawable-xxhdpi/ic_media_previous.png
new file mode 100644
index 0000000..d468874
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_previous.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_rew.png b/core/res/res/drawable-xxhdpi/ic_media_rew.png
new file mode 100644
index 0000000..8ebb2cc
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_rew.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_disabled_holo_dark.png b/core/res/res/drawable-xxhdpi/ic_media_route_disabled_holo_dark.png
new file mode 100644
index 0000000..7b0c383
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_disabled_holo_light.png b/core/res/res/drawable-xxhdpi/ic_media_route_disabled_holo_light.png
new file mode 100644
index 0000000..efb624e
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_off_holo_dark.png b/core/res/res/drawable-xxhdpi/ic_media_route_off_holo_dark.png
new file mode 100644
index 0000000..5ee57e4
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_off_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_off_holo_light.png b/core/res/res/drawable-xxhdpi/ic_media_route_off_holo_light.png
new file mode 100644
index 0000000..6bc2e4a
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_off_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_0_holo_dark.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_0_holo_dark.png
new file mode 100644
index 0000000..c13af9c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_0_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_0_holo_light.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_0_holo_light.png
new file mode 100644
index 0000000..744fb42
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_0_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_1_holo_dark.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_1_holo_dark.png
new file mode 100644
index 0000000..ca4d59c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_1_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_1_holo_light.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_1_holo_light.png
new file mode 100644
index 0000000..fde5688
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_1_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_2_holo_dark.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_2_holo_dark.png
new file mode 100644
index 0000000..b8715c3
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_2_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_2_holo_light.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_2_holo_light.png
new file mode 100644
index 0000000..668bb25
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_2_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_holo_dark.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_holo_dark.png
new file mode 100644
index 0000000..7f54a62
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_route_on_holo_light.png b/core/res/res/drawable-xxhdpi/ic_media_route_on_holo_light.png
new file mode 100644
index 0000000..2df924d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_route_on_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_media_stop.png b/core/res/res/drawable-xxhdpi/ic_media_stop.png
new file mode 100644
index 0000000..c09989a
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_media_stop.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_account_list.png b/core/res/res/drawable-xxhdpi/ic_menu_account_list.png
new file mode 100644
index 0000000..e072523
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_account_list.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_add.png b/core/res/res/drawable-xxhdpi/ic_menu_add.png
new file mode 100644
index 0000000..18a83a1
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_add.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_agenda.png b/core/res/res/drawable-xxhdpi/ic_menu_agenda.png
new file mode 100644
index 0000000..20f350b
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_agenda.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_allfriends.png b/core/res/res/drawable-xxhdpi/ic_menu_allfriends.png
new file mode 100644
index 0000000..c07a7c7
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_allfriends.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_always_landscape_portrait.png b/core/res/res/drawable-xxhdpi/ic_menu_always_landscape_portrait.png
new file mode 100644
index 0000000..2decf65
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_always_landscape_portrait.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_archive.png b/core/res/res/drawable-xxhdpi/ic_menu_archive.png
new file mode 100644
index 0000000..a2d93b9
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_archive.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_attachment.png b/core/res/res/drawable-xxhdpi/ic_menu_attachment.png
new file mode 100644
index 0000000..a92f66b
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_attachment.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_back.png b/core/res/res/drawable-xxhdpi/ic_menu_back.png
new file mode 100644
index 0000000..d3191ca
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_back.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_block.png b/core/res/res/drawable-xxhdpi/ic_menu_block.png
new file mode 100644
index 0000000..6b8f78d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_block.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_blocked_user.png b/core/res/res/drawable-xxhdpi/ic_menu_blocked_user.png
new file mode 100644
index 0000000..096bfe4
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_blocked_user.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_btn_add.png b/core/res/res/drawable-xxhdpi/ic_menu_btn_add.png
new file mode 100644
index 0000000..18a83a1
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_btn_add.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_call.png b/core/res/res/drawable-xxhdpi/ic_menu_call.png
new file mode 100644
index 0000000..3b99ebb
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_call.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_camera.png b/core/res/res/drawable-xxhdpi/ic_menu_camera.png
new file mode 100644
index 0000000..e09d050
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_camera.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_cc_am.png b/core/res/res/drawable-xxhdpi/ic_menu_cc_am.png
new file mode 100644
index 0000000..5f1b341
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_cc_am.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_chat_dashboard.png b/core/res/res/drawable-xxhdpi/ic_menu_chat_dashboard.png
new file mode 100644
index 0000000..92fdd99
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_chat_dashboard.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_clear_playlist.png b/core/res/res/drawable-xxhdpi/ic_menu_clear_playlist.png
new file mode 100644
index 0000000..819e839
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_clear_playlist.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_compass.png b/core/res/res/drawable-xxhdpi/ic_menu_compass.png
new file mode 100644
index 0000000..068678d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_compass.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_compose.png b/core/res/res/drawable-xxhdpi/ic_menu_compose.png
new file mode 100644
index 0000000..f4ccc2d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_compose.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_copy.png b/core/res/res/drawable-xxhdpi/ic_menu_copy.png
new file mode 100644
index 0000000..222e083
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_copy.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_copy_holo_dark.png b/core/res/res/drawable-xxhdpi/ic_menu_copy_holo_dark.png
new file mode 100644
index 0000000..9dd56ef
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_copy_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_copy_holo_light.png b/core/res/res/drawable-xxhdpi/ic_menu_copy_holo_light.png
new file mode 100644
index 0000000..91043c9
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_copy_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_crop.png b/core/res/res/drawable-xxhdpi/ic_menu_crop.png
new file mode 100644
index 0000000..4cc11ca
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_crop.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_cut.png b/core/res/res/drawable-xxhdpi/ic_menu_cut.png
new file mode 100644
index 0000000..81f45c6
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_cut.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_cut_holo_dark.png b/core/res/res/drawable-xxhdpi/ic_menu_cut_holo_dark.png
new file mode 100644
index 0000000..1bec21c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_cut_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_cut_holo_light.png b/core/res/res/drawable-xxhdpi/ic_menu_cut_holo_light.png
new file mode 100644
index 0000000..0dfab90
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_cut_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_day.png b/core/res/res/drawable-xxhdpi/ic_menu_day.png
new file mode 100644
index 0000000..6b92894
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_day.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_delete.png b/core/res/res/drawable-xxhdpi/ic_menu_delete.png
new file mode 100644
index 0000000..8e9e78d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_delete.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_directions.png b/core/res/res/drawable-xxhdpi/ic_menu_directions.png
new file mode 100644
index 0000000..f8a50c5
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_directions.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_edit.png b/core/res/res/drawable-xxhdpi/ic_menu_edit.png
new file mode 100644
index 0000000..2b6e967
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_edit.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_emoticons.png b/core/res/res/drawable-xxhdpi/ic_menu_emoticons.png
new file mode 100644
index 0000000..eae564f
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_emoticons.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_end_conversation.png b/core/res/res/drawable-xxhdpi/ic_menu_end_conversation.png
new file mode 100644
index 0000000..dd94956
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_end_conversation.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_find.png b/core/res/res/drawable-xxhdpi/ic_menu_find.png
new file mode 100644
index 0000000..32fad0a
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_find.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_find_holo_dark.png b/core/res/res/drawable-xxhdpi/ic_menu_find_holo_dark.png
new file mode 100644
index 0000000..f15e47a
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_find_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_find_holo_light.png b/core/res/res/drawable-xxhdpi/ic_menu_find_holo_light.png
new file mode 100644
index 0000000..61f6128
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_find_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_forward.png b/core/res/res/drawable-xxhdpi/ic_menu_forward.png
new file mode 100644
index 0000000..ca7eff9
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_forward.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_friendslist.png b/core/res/res/drawable-xxhdpi/ic_menu_friendslist.png
new file mode 100644
index 0000000..920d687
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_friendslist.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_gallery.png b/core/res/res/drawable-xxhdpi/ic_menu_gallery.png
new file mode 100644
index 0000000..3140ba9
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_gallery.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_goto.png b/core/res/res/drawable-xxhdpi/ic_menu_goto.png
new file mode 100644
index 0000000..0d2109c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_goto.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_help.png b/core/res/res/drawable-xxhdpi/ic_menu_help.png
new file mode 100644
index 0000000..a16ad70
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_help.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_help_holo_light.png b/core/res/res/drawable-xxhdpi/ic_menu_help_holo_light.png
new file mode 100644
index 0000000..62c9eda
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_help_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_home.png b/core/res/res/drawable-xxhdpi/ic_menu_home.png
new file mode 100644
index 0000000..23c67d0
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_home.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_info_details.png b/core/res/res/drawable-xxhdpi/ic_menu_info_details.png
new file mode 100644
index 0000000..4414bea
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_info_details.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_invite.png b/core/res/res/drawable-xxhdpi/ic_menu_invite.png
new file mode 100644
index 0000000..8020fd8
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_invite.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_login.png b/core/res/res/drawable-xxhdpi/ic_menu_login.png
new file mode 100644
index 0000000..2ac01e9
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_login.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_manage.png b/core/res/res/drawable-xxhdpi/ic_menu_manage.png
new file mode 100644
index 0000000..733b759
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_manage.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_mapmode.png b/core/res/res/drawable-xxhdpi/ic_menu_mapmode.png
new file mode 100644
index 0000000..4d8c185
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_mapmode.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_mark.png b/core/res/res/drawable-xxhdpi/ic_menu_mark.png
new file mode 100644
index 0000000..768aeb3
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_mark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_month.png b/core/res/res/drawable-xxhdpi/ic_menu_month.png
new file mode 100644
index 0000000..b591a23
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_month.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_more.png b/core/res/res/drawable-xxhdpi/ic_menu_more.png
new file mode 100644
index 0000000..7e0bb5e
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_more.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_moreoverflow.png b/core/res/res/drawable-xxhdpi/ic_menu_moreoverflow.png
new file mode 100644
index 0000000..c3a1390
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_moreoverflow.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_moreoverflow_focused_holo_dark.png b/core/res/res/drawable-xxhdpi/ic_menu_moreoverflow_focused_holo_dark.png
new file mode 100644
index 0000000..9cddee4
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_moreoverflow_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_moreoverflow_focused_holo_light.png b/core/res/res/drawable-xxhdpi/ic_menu_moreoverflow_focused_holo_light.png
new file mode 100644
index 0000000..826e724
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_moreoverflow_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_moreoverflow_normal_holo_dark.png b/core/res/res/drawable-xxhdpi/ic_menu_moreoverflow_normal_holo_dark.png
new file mode 100644
index 0000000..498a9ff
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_moreoverflow_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_moreoverflow_normal_holo_light.png b/core/res/res/drawable-xxhdpi/ic_menu_moreoverflow_normal_holo_light.png
new file mode 100644
index 0000000..d3d3f1a
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_moreoverflow_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_my_calendar.png b/core/res/res/drawable-xxhdpi/ic_menu_my_calendar.png
new file mode 100644
index 0000000..a9285fe
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_my_calendar.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_mylocation.png b/core/res/res/drawable-xxhdpi/ic_menu_mylocation.png
new file mode 100644
index 0000000..8ea61e1
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_mylocation.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_myplaces.png b/core/res/res/drawable-xxhdpi/ic_menu_myplaces.png
new file mode 100644
index 0000000..85b3f20
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_myplaces.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_notifications.png b/core/res/res/drawable-xxhdpi/ic_menu_notifications.png
new file mode 100644
index 0000000..d72a365
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_notifications.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_paste.png b/core/res/res/drawable-xxhdpi/ic_menu_paste.png
new file mode 100644
index 0000000..11f560c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_paste.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_paste_holo_dark.png b/core/res/res/drawable-xxhdpi/ic_menu_paste_holo_dark.png
new file mode 100644
index 0000000..d0b1fdb
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_paste_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_paste_holo_light.png b/core/res/res/drawable-xxhdpi/ic_menu_paste_holo_light.png
new file mode 100644
index 0000000..27d01a69
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_paste_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_play_clip.png b/core/res/res/drawable-xxhdpi/ic_menu_play_clip.png
new file mode 100644
index 0000000..5c3b1e3
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_play_clip.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_preferences.png b/core/res/res/drawable-xxhdpi/ic_menu_preferences.png
new file mode 100644
index 0000000..b039537
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_preferences.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_recent_history.png b/core/res/res/drawable-xxhdpi/ic_menu_recent_history.png
new file mode 100644
index 0000000..a3640a6
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_recent_history.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_refresh.png b/core/res/res/drawable-xxhdpi/ic_menu_refresh.png
new file mode 100644
index 0000000..580f4cf
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_refresh.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_report_image.png b/core/res/res/drawable-xxhdpi/ic_menu_report_image.png
new file mode 100644
index 0000000..b8cf01e
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_report_image.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_revert.png b/core/res/res/drawable-xxhdpi/ic_menu_revert.png
new file mode 100644
index 0000000..009cb91
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_revert.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_rotate.png b/core/res/res/drawable-xxhdpi/ic_menu_rotate.png
new file mode 100644
index 0000000..fd6781f
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_rotate.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_save.png b/core/res/res/drawable-xxhdpi/ic_menu_save.png
new file mode 100644
index 0000000..800da9a
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_save.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_search.png b/core/res/res/drawable-xxhdpi/ic_menu_search.png
new file mode 100644
index 0000000..22bb4c8
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_search.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_search_holo_dark.png b/core/res/res/drawable-xxhdpi/ic_menu_search_holo_dark.png
new file mode 100644
index 0000000..4ba4314
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_search_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_search_holo_light.png b/core/res/res/drawable-xxhdpi/ic_menu_search_holo_light.png
new file mode 100644
index 0000000..c69d526
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_search_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_selectall_holo_dark.png b/core/res/res/drawable-xxhdpi/ic_menu_selectall_holo_dark.png
new file mode 100644
index 0000000..9608411
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_selectall_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_selectall_holo_light.png b/core/res/res/drawable-xxhdpi/ic_menu_selectall_holo_light.png
new file mode 100644
index 0000000..f66ab27
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_selectall_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_send.png b/core/res/res/drawable-xxhdpi/ic_menu_send.png
new file mode 100644
index 0000000..7674d24
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_send.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_set_as.png b/core/res/res/drawable-xxhdpi/ic_menu_set_as.png
new file mode 100644
index 0000000..667d723
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_set_as.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_settings_holo_light.png b/core/res/res/drawable-xxhdpi/ic_menu_settings_holo_light.png
new file mode 100644
index 0000000..5df7a55
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_settings_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_share.png b/core/res/res/drawable-xxhdpi/ic_menu_share.png
new file mode 100644
index 0000000..7b90639
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_share.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_share_holo_dark.png b/core/res/res/drawable-xxhdpi/ic_menu_share_holo_dark.png
new file mode 100644
index 0000000..cc0cdda
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_share_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_share_holo_light.png b/core/res/res/drawable-xxhdpi/ic_menu_share_holo_light.png
new file mode 100644
index 0000000..1e21d9d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_share_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_slideshow.png b/core/res/res/drawable-xxhdpi/ic_menu_slideshow.png
new file mode 100644
index 0000000..5db7bc7
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_slideshow.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_sort_alphabetically.png b/core/res/res/drawable-xxhdpi/ic_menu_sort_alphabetically.png
new file mode 100644
index 0000000..bb925f2
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_sort_alphabetically.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_sort_by_size.png b/core/res/res/drawable-xxhdpi/ic_menu_sort_by_size.png
new file mode 100644
index 0000000..da3b4a7
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_sort_by_size.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_star.png b/core/res/res/drawable-xxhdpi/ic_menu_star.png
new file mode 100644
index 0000000..63ce68d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_star.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_start_conversation.png b/core/res/res/drawable-xxhdpi/ic_menu_start_conversation.png
new file mode 100644
index 0000000..bb26e49
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_start_conversation.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_stop.png b/core/res/res/drawable-xxhdpi/ic_menu_stop.png
new file mode 100644
index 0000000..992738d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_stop.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_today.png b/core/res/res/drawable-xxhdpi/ic_menu_today.png
new file mode 100644
index 0000000..b5d58d80
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_today.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_upload.png b/core/res/res/drawable-xxhdpi/ic_menu_upload.png
new file mode 100644
index 0000000..931e6ed
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_upload.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_upload_you_tube.png b/core/res/res/drawable-xxhdpi/ic_menu_upload_you_tube.png
new file mode 100644
index 0000000..fd8f409
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_upload_you_tube.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_view.png b/core/res/res/drawable-xxhdpi/ic_menu_view.png
new file mode 100644
index 0000000..aff6c86
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_view.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_week.png b/core/res/res/drawable-xxhdpi/ic_menu_week.png
new file mode 100644
index 0000000..8da6b1e
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_week.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_zoom.png b/core/res/res/drawable-xxhdpi/ic_menu_zoom.png
new file mode 100644
index 0000000..f6a5c30
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_zoom.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_notification_ime_default.png b/core/res/res/drawable-xxhdpi/ic_notification_ime_default.png
new file mode 100644
index 0000000..6c8222e
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_notification_ime_default.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_notification_media_route.png b/core/res/res/drawable-xxhdpi/ic_notification_media_route.png
new file mode 100644
index 0000000..da1a627
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_notification_media_route.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_notify_wifidisplay.png b/core/res/res/drawable-xxhdpi/ic_notify_wifidisplay.png
new file mode 100644
index 0000000..fea4774
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_notify_wifidisplay.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_accounts.png b/core/res/res/drawable-xxhdpi/ic_perm_group_accounts.png
new file mode 100644
index 0000000..f30fcd4c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_perm_group_accounts.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_app_info.png b/core/res/res/drawable-xxhdpi/ic_perm_group_app_info.png
new file mode 100644
index 0000000..11f2638
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_perm_group_app_info.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_audio_settings.png b/core/res/res/drawable-xxhdpi/ic_perm_group_audio_settings.png
new file mode 100644
index 0000000..aaf8f76
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_perm_group_audio_settings.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_bluetooth.png b/core/res/res/drawable-xxhdpi/ic_perm_group_bluetooth.png
new file mode 100644
index 0000000..b302cc7
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_perm_group_bluetooth.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_bookmarks.png b/core/res/res/drawable-xxhdpi/ic_perm_group_bookmarks.png
new file mode 100644
index 0000000..75aee05
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_perm_group_bookmarks.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_calendar.png b/core/res/res/drawable-xxhdpi/ic_perm_group_calendar.png
new file mode 100644
index 0000000..ad3629c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_perm_group_calendar.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_camera.png b/core/res/res/drawable-xxhdpi/ic_perm_group_camera.png
new file mode 100644
index 0000000..e22ffb8
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_perm_group_camera.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_device_alarms.png b/core/res/res/drawable-xxhdpi/ic_perm_group_device_alarms.png
new file mode 100644
index 0000000..0b48a24
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_perm_group_device_alarms.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_display.png b/core/res/res/drawable-xxhdpi/ic_perm_group_display.png
new file mode 100644
index 0000000..29e6332
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_perm_group_display.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_effects_battery.png b/core/res/res/drawable-xxhdpi/ic_perm_group_effects_battery.png
new file mode 100644
index 0000000..afe137a
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_perm_group_effects_battery.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_location.png b/core/res/res/drawable-xxhdpi/ic_perm_group_location.png
new file mode 100644
index 0000000..7124634
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_perm_group_location.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_messages.png b/core/res/res/drawable-xxhdpi/ic_perm_group_messages.png
new file mode 100644
index 0000000..9534dcb
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_perm_group_messages.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_microphone.png b/core/res/res/drawable-xxhdpi/ic_perm_group_microphone.png
new file mode 100644
index 0000000..723a2cf
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_perm_group_microphone.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_network.png b/core/res/res/drawable-xxhdpi/ic_perm_group_network.png
new file mode 100644
index 0000000..703b25b
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_perm_group_network.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_personal_info.png b/core/res/res/drawable-xxhdpi/ic_perm_group_personal_info.png
new file mode 100644
index 0000000..2428976
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_perm_group_personal_info.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_phone_calls.png b/core/res/res/drawable-xxhdpi/ic_perm_group_phone_calls.png
new file mode 100644
index 0000000..67e523c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_perm_group_phone_calls.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_screenlock.png b/core/res/res/drawable-xxhdpi/ic_perm_group_screenlock.png
new file mode 100644
index 0000000..d660740
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_perm_group_screenlock.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_shortrange_network.png b/core/res/res/drawable-xxhdpi/ic_perm_group_shortrange_network.png
new file mode 100644
index 0000000..3aae345
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_perm_group_shortrange_network.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_social_info.png b/core/res/res/drawable-xxhdpi/ic_perm_group_social_info.png
new file mode 100644
index 0000000..a3d7b26
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_perm_group_social_info.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_status_bar.png b/core/res/res/drawable-xxhdpi/ic_perm_group_status_bar.png
new file mode 100644
index 0000000..e260acf
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_perm_group_status_bar.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_storage.png b/core/res/res/drawable-xxhdpi/ic_perm_group_storage.png
new file mode 100644
index 0000000..d3937db
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_perm_group_storage.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_sync_settings.png b/core/res/res/drawable-xxhdpi/ic_perm_group_sync_settings.png
new file mode 100644
index 0000000..41ef06b
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_perm_group_sync_settings.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_system_clock.png b/core/res/res/drawable-xxhdpi/ic_perm_group_system_clock.png
new file mode 100644
index 0000000..5a89628
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_perm_group_system_clock.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_system_tools.png b/core/res/res/drawable-xxhdpi/ic_perm_group_system_tools.png
new file mode 100644
index 0000000..cee2b05
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_perm_group_system_tools.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_user_dictionary.png b/core/res/res/drawable-xxhdpi/ic_perm_group_user_dictionary.png
new file mode 100644
index 0000000..8c2cd17
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_perm_group_user_dictionary.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_user_dictionary_write.png b/core/res/res/drawable-xxhdpi/ic_perm_group_user_dictionary_write.png
new file mode 100644
index 0000000..121d6cf
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_perm_group_user_dictionary_write.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_voicemail.png b/core/res/res/drawable-xxhdpi/ic_perm_group_voicemail.png
new file mode 100644
index 0000000..118c140
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_perm_group_voicemail.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_wallpapewr.png b/core/res/res/drawable-xxhdpi/ic_perm_group_wallpapewr.png
new file mode 100644
index 0000000..f95cd9d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_perm_group_wallpapewr.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_suggestions_add.png b/core/res/res/drawable-xxhdpi/ic_suggestions_add.png
new file mode 100644
index 0000000..b880d40
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_suggestions_add.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_suggestions_delete.png b/core/res/res/drawable-xxhdpi/ic_suggestions_delete.png
new file mode 100644
index 0000000..f9e2702
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_suggestions_delete.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_text_dot.png b/core/res/res/drawable-xxhdpi/ic_text_dot.png
new file mode 100644
index 0000000..a74c286
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_text_dot.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/indicator_code_lock_point_area_default_holo.png b/core/res/res/drawable-xxhdpi/indicator_code_lock_point_area_default_holo.png
new file mode 100644
index 0000000..a11b6dd
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/indicator_code_lock_point_area_default_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/indicator_code_lock_point_area_green_holo.png b/core/res/res/drawable-xxhdpi/indicator_code_lock_point_area_green_holo.png
new file mode 100644
index 0000000..eae7ea8
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/indicator_code_lock_point_area_green_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/indicator_code_lock_point_area_red_holo.png b/core/res/res/drawable-xxhdpi/indicator_code_lock_point_area_red_holo.png
new file mode 100644
index 0000000..f6c3e27
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/indicator_code_lock_point_area_red_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/indicator_input_error.png b/core/res/res/drawable-xxhdpi/indicator_input_error.png
new file mode 100644
index 0000000..b5a6eaf
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/indicator_input_error.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/kg_add_widget.png b/core/res/res/drawable-xxhdpi/kg_add_widget.png
new file mode 100644
index 0000000..33d839e
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/kg_add_widget.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/kg_add_widget_disabled.png b/core/res/res/drawable-xxhdpi/kg_add_widget_disabled.png
new file mode 100644
index 0000000..405ab30
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/kg_add_widget_disabled.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/kg_add_widget_pressed.png b/core/res/res/drawable-xxhdpi/kg_add_widget_pressed.png
new file mode 100644
index 0000000..f23fad5
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/kg_add_widget_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/kg_bouncer_bg_focused.9.png b/core/res/res/drawable-xxhdpi/kg_bouncer_bg_focused.9.png
new file mode 100644
index 0000000..67e5900
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/kg_bouncer_bg_focused.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/kg_bouncer_bg_normal.9.png b/core/res/res/drawable-xxhdpi/kg_bouncer_bg_normal.9.png
new file mode 100644
index 0000000..b474e7d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/kg_bouncer_bg_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/kg_bouncer_bg_pressed.9.png b/core/res/res/drawable-xxhdpi/kg_bouncer_bg_pressed.9.png
new file mode 100644
index 0000000..5edf225
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/kg_bouncer_bg_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/kg_dot_pattern.png b/core/res/res/drawable-xxhdpi/kg_dot_pattern.png
new file mode 100644
index 0000000..2ce3ba2
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/kg_dot_pattern.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/kg_security_grip.9.png b/core/res/res/drawable-xxhdpi/kg_security_grip.9.png
new file mode 100644
index 0000000..47fd407
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/kg_security_grip.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/kg_security_lock_focused.png b/core/res/res/drawable-xxhdpi/kg_security_lock_focused.png
new file mode 100644
index 0000000..e0a2e2a
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/kg_security_lock_focused.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/kg_security_lock_normal.png b/core/res/res/drawable-xxhdpi/kg_security_lock_normal.png
new file mode 100644
index 0000000..2d62c45
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/kg_security_lock_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/kg_security_lock_pressed.png b/core/res/res/drawable-xxhdpi/kg_security_lock_pressed.png
new file mode 100644
index 0000000..97900d5
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/kg_security_lock_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/kg_widget_bg_padded.9.png b/core/res/res/drawable-xxhdpi/kg_widget_bg_padded.9.png
new file mode 100644
index 0000000..a22bc8e
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/kg_widget_bg_padded.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/list_activated_holo.9.png b/core/res/res/drawable-xxhdpi/list_activated_holo.9.png
new file mode 100644
index 0000000..9f08bb0
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/list_activated_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/list_divider_holo_dark.9.png b/core/res/res/drawable-xxhdpi/list_divider_holo_dark.9.png
new file mode 100644
index 0000000..9678825
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/list_divider_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/list_divider_holo_light.9.png b/core/res/res/drawable-xxhdpi/list_divider_holo_light.9.png
new file mode 100644
index 0000000..c69a6a3
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/list_divider_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/list_focused_holo.9.png b/core/res/res/drawable-xxhdpi/list_focused_holo.9.png
new file mode 100644
index 0000000..76cad17
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/list_focused_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/list_longpressed_holo.9.png b/core/res/res/drawable-xxhdpi/list_longpressed_holo.9.png
new file mode 100644
index 0000000..8f436ea
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/list_longpressed_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/list_pressed_holo_dark.9.png b/core/res/res/drawable-xxhdpi/list_pressed_holo_dark.9.png
new file mode 100644
index 0000000..7bfdd34
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/list_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/list_pressed_holo_light.9.png b/core/res/res/drawable-xxhdpi/list_pressed_holo_light.9.png
new file mode 100644
index 0000000..13f76de
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/list_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/list_section_divider_holo_dark.9.png b/core/res/res/drawable-xxhdpi/list_section_divider_holo_dark.9.png
new file mode 100644
index 0000000..61f8915
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/list_section_divider_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/list_section_divider_holo_light.9.png b/core/res/res/drawable-xxhdpi/list_section_divider_holo_light.9.png
new file mode 100644
index 0000000..5ae4882
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/list_section_divider_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/list_selected_holo_dark.9.png b/core/res/res/drawable-xxhdpi/list_selected_holo_dark.9.png
new file mode 100644
index 0000000..a1b5ed2
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/list_selected_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/list_selected_holo_light.9.png b/core/res/res/drawable-xxhdpi/list_selected_holo_light.9.png
new file mode 100644
index 0000000..7cfb33d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/list_selected_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/list_selector_background_disabled.9.png b/core/res/res/drawable-xxhdpi/list_selector_background_disabled.9.png
new file mode 100644
index 0000000..e662b69
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/list_selector_background_disabled.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/list_selector_background_focus.9.png b/core/res/res/drawable-xxhdpi/list_selector_background_focus.9.png
new file mode 100644
index 0000000..5167387
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/list_selector_background_focus.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/list_selector_background_longpress.9.png b/core/res/res/drawable-xxhdpi/list_selector_background_longpress.9.png
new file mode 100644
index 0000000..4d83885
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/list_selector_background_longpress.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/list_selector_background_pressed.9.png b/core/res/res/drawable-xxhdpi/list_selector_background_pressed.9.png
new file mode 100644
index 0000000..2f93cbf
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/list_selector_background_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/lockscreen_protection_pattern.png b/core/res/res/drawable-xxhdpi/lockscreen_protection_pattern.png
new file mode 100644
index 0000000..5521eb6
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/lockscreen_protection_pattern.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/magnified_region_frame.9.png b/core/res/res/drawable-xxhdpi/magnified_region_frame.9.png
new file mode 100644
index 0000000..09ee1c3
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/magnified_region_frame.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/menu_dropdown_panel_holo_dark.9.png b/core/res/res/drawable-xxhdpi/menu_dropdown_panel_holo_dark.9.png
new file mode 100644
index 0000000..e87e372
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/menu_dropdown_panel_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/menu_dropdown_panel_holo_light.9.png b/core/res/res/drawable-xxhdpi/menu_dropdown_panel_holo_light.9.png
new file mode 100644
index 0000000..6ca7814
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/menu_dropdown_panel_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/menu_hardkey_panel_holo_dark.9.png b/core/res/res/drawable-xxhdpi/menu_hardkey_panel_holo_dark.9.png
new file mode 100644
index 0000000..c933eab
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/menu_hardkey_panel_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/menu_hardkey_panel_holo_light.9.png b/core/res/res/drawable-xxhdpi/menu_hardkey_panel_holo_light.9.png
new file mode 100644
index 0000000..112f939
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/menu_hardkey_panel_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/menu_popup_panel_holo_dark.9.png b/core/res/res/drawable-xxhdpi/menu_popup_panel_holo_dark.9.png
new file mode 100644
index 0000000..90489bc
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/menu_popup_panel_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/menu_popup_panel_holo_light.9.png b/core/res/res/drawable-xxhdpi/menu_popup_panel_holo_light.9.png
new file mode 100644
index 0000000..472c3d3
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/menu_popup_panel_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/numberpicker_down_disabled_focused_holo_dark.png b/core/res/res/drawable-xxhdpi/numberpicker_down_disabled_focused_holo_dark.png
new file mode 100644
index 0000000..6f0a88c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/numberpicker_down_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/numberpicker_down_disabled_focused_holo_light.png b/core/res/res/drawable-xxhdpi/numberpicker_down_disabled_focused_holo_light.png
new file mode 100644
index 0000000..ea965c5
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/numberpicker_down_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/numberpicker_down_disabled_holo_dark.png b/core/res/res/drawable-xxhdpi/numberpicker_down_disabled_holo_dark.png
new file mode 100644
index 0000000..822df62
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/numberpicker_down_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/numberpicker_down_disabled_holo_light.png b/core/res/res/drawable-xxhdpi/numberpicker_down_disabled_holo_light.png
new file mode 100644
index 0000000..b17dd91
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/numberpicker_down_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/numberpicker_down_focused_holo_dark.png b/core/res/res/drawable-xxhdpi/numberpicker_down_focused_holo_dark.png
new file mode 100644
index 0000000..b558db7
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/numberpicker_down_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/numberpicker_down_focused_holo_light.png b/core/res/res/drawable-xxhdpi/numberpicker_down_focused_holo_light.png
new file mode 100644
index 0000000..5121bc0
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/numberpicker_down_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/numberpicker_down_longpressed_holo_dark.png b/core/res/res/drawable-xxhdpi/numberpicker_down_longpressed_holo_dark.png
new file mode 100644
index 0000000..166e08c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/numberpicker_down_longpressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/numberpicker_down_longpressed_holo_light.png b/core/res/res/drawable-xxhdpi/numberpicker_down_longpressed_holo_light.png
new file mode 100644
index 0000000..166e08c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/numberpicker_down_longpressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/numberpicker_down_normal_holo_dark.png b/core/res/res/drawable-xxhdpi/numberpicker_down_normal_holo_dark.png
new file mode 100644
index 0000000..3f2e813
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/numberpicker_down_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/numberpicker_down_normal_holo_light.png b/core/res/res/drawable-xxhdpi/numberpicker_down_normal_holo_light.png
new file mode 100644
index 0000000..9026c12
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/numberpicker_down_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/numberpicker_down_pressed_holo_dark.png b/core/res/res/drawable-xxhdpi/numberpicker_down_pressed_holo_dark.png
new file mode 100644
index 0000000..2a24398
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/numberpicker_down_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/numberpicker_down_pressed_holo_light.png b/core/res/res/drawable-xxhdpi/numberpicker_down_pressed_holo_light.png
new file mode 100644
index 0000000..2a24398
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/numberpicker_down_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/numberpicker_selection_divider.9.png b/core/res/res/drawable-xxhdpi/numberpicker_selection_divider.9.png
new file mode 100644
index 0000000..b7a9940
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/numberpicker_selection_divider.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/numberpicker_up_disabled_focused_holo_dark.png b/core/res/res/drawable-xxhdpi/numberpicker_up_disabled_focused_holo_dark.png
new file mode 100644
index 0000000..a4eb1a5
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/numberpicker_up_disabled_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/numberpicker_up_disabled_focused_holo_light.png b/core/res/res/drawable-xxhdpi/numberpicker_up_disabled_focused_holo_light.png
new file mode 100644
index 0000000..b43b0c2
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/numberpicker_up_disabled_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/numberpicker_up_disabled_holo_dark.png b/core/res/res/drawable-xxhdpi/numberpicker_up_disabled_holo_dark.png
new file mode 100644
index 0000000..81b68fc
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/numberpicker_up_disabled_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/numberpicker_up_disabled_holo_light.png b/core/res/res/drawable-xxhdpi/numberpicker_up_disabled_holo_light.png
new file mode 100644
index 0000000..91b2f2f
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/numberpicker_up_disabled_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/numberpicker_up_focused_holo_dark.png b/core/res/res/drawable-xxhdpi/numberpicker_up_focused_holo_dark.png
new file mode 100644
index 0000000..82da07e
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/numberpicker_up_focused_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/numberpicker_up_focused_holo_light.png b/core/res/res/drawable-xxhdpi/numberpicker_up_focused_holo_light.png
new file mode 100644
index 0000000..d7c2f34
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/numberpicker_up_focused_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/numberpicker_up_longpressed_holo_dark.png b/core/res/res/drawable-xxhdpi/numberpicker_up_longpressed_holo_dark.png
new file mode 100644
index 0000000..1bc2bf1
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/numberpicker_up_longpressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/numberpicker_up_longpressed_holo_light.png b/core/res/res/drawable-xxhdpi/numberpicker_up_longpressed_holo_light.png
new file mode 100644
index 0000000..1bc2bf1
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/numberpicker_up_longpressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/numberpicker_up_normal_holo_dark.png b/core/res/res/drawable-xxhdpi/numberpicker_up_normal_holo_dark.png
new file mode 100644
index 0000000..0fd9b05
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/numberpicker_up_normal_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/numberpicker_up_normal_holo_light.png b/core/res/res/drawable-xxhdpi/numberpicker_up_normal_holo_light.png
new file mode 100644
index 0000000..9f6a470
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/numberpicker_up_normal_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/numberpicker_up_pressed_holo_dark.png b/core/res/res/drawable-xxhdpi/numberpicker_up_pressed_holo_dark.png
new file mode 100644
index 0000000..35905ea
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/numberpicker_up_pressed_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/numberpicker_up_pressed_holo_light.png b/core/res/res/drawable-xxhdpi/numberpicker_up_pressed_holo_light.png
new file mode 100644
index 0000000..35905ea
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/numberpicker_up_pressed_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/overscroll_edge.png b/core/res/res/drawable-xxhdpi/overscroll_edge.png
new file mode 100644
index 0000000..1a92737
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/overscroll_edge.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/overscroll_glow.png b/core/res/res/drawable-xxhdpi/overscroll_glow.png
new file mode 100644
index 0000000..c187e95
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/overscroll_glow.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/panel_bg_holo_dark.9.png b/core/res/res/drawable-xxhdpi/panel_bg_holo_dark.9.png
new file mode 100644
index 0000000..8993469
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/panel_bg_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/panel_bg_holo_light.9.png b/core/res/res/drawable-xxhdpi/panel_bg_holo_light.9.png
new file mode 100644
index 0000000..38ec76c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/panel_bg_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/pointer_arrow.png b/core/res/res/drawable-xxhdpi/pointer_arrow.png
new file mode 100644
index 0000000..65e0320
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/pointer_arrow.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/popup_inline_error_above_holo_dark_am.9.png b/core/res/res/drawable-xxhdpi/popup_inline_error_above_holo_dark_am.9.png
new file mode 100644
index 0000000..251660a
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/popup_inline_error_above_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/popup_inline_error_above_holo_light_am.9.png b/core/res/res/drawable-xxhdpi/popup_inline_error_above_holo_light_am.9.png
new file mode 100644
index 0000000..12b1e64
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/popup_inline_error_above_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/popup_inline_error_holo_dark_am.9.png b/core/res/res/drawable-xxhdpi/popup_inline_error_holo_dark_am.9.png
new file mode 100644
index 0000000..5d389af
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/popup_inline_error_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/popup_inline_error_holo_light_am.9.png b/core/res/res/drawable-xxhdpi/popup_inline_error_holo_light_am.9.png
new file mode 100644
index 0000000..5e3c01b
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/popup_inline_error_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/presence_audio_away.png b/core/res/res/drawable-xxhdpi/presence_audio_away.png
new file mode 100644
index 0000000..e8e2b1a
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/presence_audio_away.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/presence_audio_busy.png b/core/res/res/drawable-xxhdpi/presence_audio_busy.png
new file mode 100644
index 0000000..824b5be
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/presence_audio_busy.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/presence_audio_online.png b/core/res/res/drawable-xxhdpi/presence_audio_online.png
new file mode 100644
index 0000000..6b3cd2d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/presence_audio_online.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/presence_away.png b/core/res/res/drawable-xxhdpi/presence_away.png
new file mode 100644
index 0000000..217f4e9
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/presence_away.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/presence_busy.png b/core/res/res/drawable-xxhdpi/presence_busy.png
new file mode 100644
index 0000000..9416720
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/presence_busy.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/presence_invisible.png b/core/res/res/drawable-xxhdpi/presence_invisible.png
new file mode 100644
index 0000000..72ada9c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/presence_invisible.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/presence_offline.png b/core/res/res/drawable-xxhdpi/presence_offline.png
new file mode 100644
index 0000000..bc71d3a
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/presence_offline.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/presence_online.png b/core/res/res/drawable-xxhdpi/presence_online.png
new file mode 100644
index 0000000..501a75d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/presence_online.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/presence_video_away.png b/core/res/res/drawable-xxhdpi/presence_video_away.png
new file mode 100644
index 0000000..1379bc0
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/presence_video_away.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/presence_video_busy.png b/core/res/res/drawable-xxhdpi/presence_video_busy.png
new file mode 100644
index 0000000..d90297c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/presence_video_busy.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/presence_video_online.png b/core/res/res/drawable-xxhdpi/presence_video_online.png
new file mode 100644
index 0000000..4186408
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/presence_video_online.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/progress_bg_holo_dark.9.png b/core/res/res/drawable-xxhdpi/progress_bg_holo_dark.9.png
new file mode 100644
index 0000000..2e8c2e5
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/progress_bg_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/progress_bg_holo_light.9.png b/core/res/res/drawable-xxhdpi/progress_bg_holo_light.9.png
new file mode 100644
index 0000000..fb146c3
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/progress_bg_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/progress_primary_holo_dark.9.png b/core/res/res/drawable-xxhdpi/progress_primary_holo_dark.9.png
new file mode 100644
index 0000000..36078f9
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/progress_primary_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/progress_primary_holo_light.9.png b/core/res/res/drawable-xxhdpi/progress_primary_holo_light.9.png
new file mode 100644
index 0000000..add4d38
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/progress_primary_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/progress_secondary_holo_dark.9.png b/core/res/res/drawable-xxhdpi/progress_secondary_holo_dark.9.png
new file mode 100644
index 0000000..90b56fc
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/progress_secondary_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/progress_secondary_holo_light.9.png b/core/res/res/drawable-xxhdpi/progress_secondary_holo_light.9.png
new file mode 100644
index 0000000..28b53dd
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/progress_secondary_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/progressbar_indeterminate_holo1.png b/core/res/res/drawable-xxhdpi/progressbar_indeterminate_holo1.png
new file mode 100644
index 0000000..e751345
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/progressbar_indeterminate_holo1.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/progressbar_indeterminate_holo2.png b/core/res/res/drawable-xxhdpi/progressbar_indeterminate_holo2.png
new file mode 100644
index 0000000..663965f
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/progressbar_indeterminate_holo2.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/progressbar_indeterminate_holo3.png b/core/res/res/drawable-xxhdpi/progressbar_indeterminate_holo3.png
new file mode 100644
index 0000000..3574c9a
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/progressbar_indeterminate_holo3.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/progressbar_indeterminate_holo4.png b/core/res/res/drawable-xxhdpi/progressbar_indeterminate_holo4.png
new file mode 100644
index 0000000..a289d33
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/progressbar_indeterminate_holo4.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/progressbar_indeterminate_holo5.png b/core/res/res/drawable-xxhdpi/progressbar_indeterminate_holo5.png
new file mode 100644
index 0000000..6fa2fbb
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/progressbar_indeterminate_holo5.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/progressbar_indeterminate_holo6.png b/core/res/res/drawable-xxhdpi/progressbar_indeterminate_holo6.png
new file mode 100644
index 0000000..0117543
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/progressbar_indeterminate_holo6.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/progressbar_indeterminate_holo7.png b/core/res/res/drawable-xxhdpi/progressbar_indeterminate_holo7.png
new file mode 100644
index 0000000..681fe1d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/progressbar_indeterminate_holo7.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/progressbar_indeterminate_holo8.png b/core/res/res/drawable-xxhdpi/progressbar_indeterminate_holo8.png
new file mode 100644
index 0000000..bbc3999
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/progressbar_indeterminate_holo8.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/quickcontact_badge_overlay_focused_dark_am.9.png b/core/res/res/drawable-xxhdpi/quickcontact_badge_overlay_focused_dark_am.9.png
new file mode 100644
index 0000000..8eda0f1
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/quickcontact_badge_overlay_focused_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/quickcontact_badge_overlay_focused_light_am.9.png b/core/res/res/drawable-xxhdpi/quickcontact_badge_overlay_focused_light_am.9.png
new file mode 100644
index 0000000..c7cd27a
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/quickcontact_badge_overlay_focused_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/quickcontact_badge_overlay_normal_dark_am.9.png b/core/res/res/drawable-xxhdpi/quickcontact_badge_overlay_normal_dark_am.9.png
new file mode 100644
index 0000000..09c8cbd
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/quickcontact_badge_overlay_normal_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/quickcontact_badge_overlay_normal_light_am.9.png b/core/res/res/drawable-xxhdpi/quickcontact_badge_overlay_normal_light_am.9.png
new file mode 100644
index 0000000..d0a5a71
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/quickcontact_badge_overlay_normal_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/quickcontact_badge_overlay_pressed_dark_am.9.png b/core/res/res/drawable-xxhdpi/quickcontact_badge_overlay_pressed_dark_am.9.png
new file mode 100644
index 0000000..8a67108
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/quickcontact_badge_overlay_pressed_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/quickcontact_badge_overlay_pressed_light_am.9.png b/core/res/res/drawable-xxhdpi/quickcontact_badge_overlay_pressed_light_am.9.png
new file mode 100644
index 0000000..f84557f
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/quickcontact_badge_overlay_pressed_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/rate_star_big_half_holo_dark.png b/core/res/res/drawable-xxhdpi/rate_star_big_half_holo_dark.png
new file mode 100644
index 0000000..ede3db5
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/rate_star_big_half_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/rate_star_big_half_holo_light.png b/core/res/res/drawable-xxhdpi/rate_star_big_half_holo_light.png
new file mode 100644
index 0000000..906dbe1
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/rate_star_big_half_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/rate_star_big_off_holo_dark.png b/core/res/res/drawable-xxhdpi/rate_star_big_off_holo_dark.png
new file mode 100644
index 0000000..cff58d3
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/rate_star_big_off_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/rate_star_big_off_holo_light.png b/core/res/res/drawable-xxhdpi/rate_star_big_off_holo_light.png
new file mode 100644
index 0000000..7e1a770
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/rate_star_big_off_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/rate_star_big_on_holo_dark.png b/core/res/res/drawable-xxhdpi/rate_star_big_on_holo_dark.png
new file mode 100644
index 0000000..ab3f4d3
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/rate_star_big_on_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/rate_star_big_on_holo_light.png b/core/res/res/drawable-xxhdpi/rate_star_big_on_holo_light.png
new file mode 100644
index 0000000..ab7a496
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/rate_star_big_on_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/rate_star_med_half_holo_dark.png b/core/res/res/drawable-xxhdpi/rate_star_med_half_holo_dark.png
new file mode 100644
index 0000000..8bb8aa0
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/rate_star_med_half_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/rate_star_med_half_holo_light.png b/core/res/res/drawable-xxhdpi/rate_star_med_half_holo_light.png
new file mode 100644
index 0000000..44e6696
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/rate_star_med_half_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/rate_star_med_off_holo_dark.png b/core/res/res/drawable-xxhdpi/rate_star_med_off_holo_dark.png
new file mode 100644
index 0000000..94ec824
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/rate_star_med_off_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/rate_star_med_off_holo_light.png b/core/res/res/drawable-xxhdpi/rate_star_med_off_holo_light.png
new file mode 100644
index 0000000..0a12fc9
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/rate_star_med_off_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/rate_star_med_on_holo_dark.png b/core/res/res/drawable-xxhdpi/rate_star_med_on_holo_dark.png
new file mode 100644
index 0000000..4894658
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/rate_star_med_on_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/rate_star_med_on_holo_light.png b/core/res/res/drawable-xxhdpi/rate_star_med_on_holo_light.png
new file mode 100644
index 0000000..4bb8a73
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/rate_star_med_on_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/rate_star_small_half_holo_dark.png b/core/res/res/drawable-xxhdpi/rate_star_small_half_holo_dark.png
new file mode 100644
index 0000000..9e215d7
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/rate_star_small_half_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/rate_star_small_half_holo_light.png b/core/res/res/drawable-xxhdpi/rate_star_small_half_holo_light.png
new file mode 100644
index 0000000..e6ce596
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/rate_star_small_half_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/rate_star_small_off_holo_dark.png b/core/res/res/drawable-xxhdpi/rate_star_small_off_holo_dark.png
new file mode 100644
index 0000000..2a9fc21
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/rate_star_small_off_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/rate_star_small_off_holo_light.png b/core/res/res/drawable-xxhdpi/rate_star_small_off_holo_light.png
new file mode 100644
index 0000000..42cad5e
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/rate_star_small_off_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/rate_star_small_on_holo_dark.png b/core/res/res/drawable-xxhdpi/rate_star_small_on_holo_dark.png
new file mode 100644
index 0000000..0612b25
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/rate_star_small_on_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/rate_star_small_on_holo_light.png b/core/res/res/drawable-xxhdpi/rate_star_small_on_holo_light.png
new file mode 100644
index 0000000..aaa3d0f
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/rate_star_small_on_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrollbar_handle_holo_dark.9.png b/core/res/res/drawable-xxhdpi/scrollbar_handle_holo_dark.9.png
new file mode 100644
index 0000000..66b3e9d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/scrollbar_handle_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrollbar_handle_holo_light.9.png b/core/res/res/drawable-xxhdpi/scrollbar_handle_holo_light.9.png
new file mode 100644
index 0000000..5fbd723
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/scrollbar_handle_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_disabled_holo.png b/core/res/res/drawable-xxhdpi/scrubber_control_disabled_holo.png
new file mode 100644
index 0000000..74b7431
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/scrubber_control_disabled_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_focused_holo.png b/core/res/res/drawable-xxhdpi/scrubber_control_focused_holo.png
new file mode 100644
index 0000000..2945fbd
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/scrubber_control_focused_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_normal_holo.png b/core/res/res/drawable-xxhdpi/scrubber_control_normal_holo.png
new file mode 100644
index 0000000..9dde7da
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/scrubber_control_normal_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_pressed_holo.png b/core/res/res/drawable-xxhdpi/scrubber_control_pressed_holo.png
new file mode 100644
index 0000000..8afbb6d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/scrubber_control_pressed_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_primary_holo.9.png b/core/res/res/drawable-xxhdpi/scrubber_primary_holo.9.png
new file mode 100644
index 0000000..209df49
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/scrubber_primary_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_secondary_holo.9.png b/core/res/res/drawable-xxhdpi/scrubber_secondary_holo.9.png
new file mode 100644
index 0000000..3dbcc48
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/scrubber_secondary_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_track_holo_dark.9.png b/core/res/res/drawable-xxhdpi/scrubber_track_holo_dark.9.png
new file mode 100644
index 0000000..4014860
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/scrubber_track_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_track_holo_light.9.png b/core/res/res/drawable-xxhdpi/scrubber_track_holo_light.9.png
new file mode 100644
index 0000000..1a6f577
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/scrubber_track_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_16_inner_holo.png b/core/res/res/drawable-xxhdpi/spinner_16_inner_holo.png
new file mode 100644
index 0000000..30f0db3
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_16_inner_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_16_outer_holo.png b/core/res/res/drawable-xxhdpi/spinner_16_outer_holo.png
new file mode 100644
index 0000000..d0729da
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_16_outer_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_20_inner_holo.png b/core/res/res/drawable-xxhdpi/spinner_20_inner_holo.png
new file mode 100644
index 0000000..6cbd1f4
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_20_inner_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_20_outer_holo.png b/core/res/res/drawable-xxhdpi/spinner_20_outer_holo.png
new file mode 100644
index 0000000..b6af5e7
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_20_outer_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_48_inner_holo.png b/core/res/res/drawable-xxhdpi/spinner_48_inner_holo.png
new file mode 100644
index 0000000..eca7a46
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_48_inner_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_48_outer_holo.png b/core/res/res/drawable-xxhdpi/spinner_48_outer_holo.png
new file mode 100644
index 0000000..3511d52
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_48_outer_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_76_inner_holo.png b/core/res/res/drawable-xxhdpi/spinner_76_inner_holo.png
new file mode 100644
index 0000000..21ad59f
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_76_inner_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_76_outer_holo.png b/core/res/res/drawable-xxhdpi/spinner_76_outer_holo.png
new file mode 100644
index 0000000..471d78c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_76_outer_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_ab_activated_holo_dark.9.png b/core/res/res/drawable-xxhdpi/spinner_ab_activated_holo_dark.9.png
new file mode 100644
index 0000000..6be9e6b
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_ab_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_ab_activated_holo_light.9.png b/core/res/res/drawable-xxhdpi/spinner_ab_activated_holo_light.9.png
new file mode 100644
index 0000000..0b9a077
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_ab_activated_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_ab_default_holo_dark_am.9.png b/core/res/res/drawable-xxhdpi/spinner_ab_default_holo_dark_am.9.png
new file mode 100644
index 0000000..71075a7
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_ab_default_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_ab_default_holo_light_am.9.png b/core/res/res/drawable-xxhdpi/spinner_ab_default_holo_light_am.9.png
new file mode 100644
index 0000000..6aabc3c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_ab_default_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_ab_disabled_holo_dark_am.9.png b/core/res/res/drawable-xxhdpi/spinner_ab_disabled_holo_dark_am.9.png
new file mode 100644
index 0000000..a2045e1
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_ab_disabled_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_ab_disabled_holo_light_am.9.png b/core/res/res/drawable-xxhdpi/spinner_ab_disabled_holo_light_am.9.png
new file mode 100644
index 0000000..1f4d161
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_ab_disabled_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_ab_focused_holo_dark_am.9.png b/core/res/res/drawable-xxhdpi/spinner_ab_focused_holo_dark_am.9.png
new file mode 100644
index 0000000..85b0634
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_ab_focused_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_ab_focused_holo_light_am.9.png b/core/res/res/drawable-xxhdpi/spinner_ab_focused_holo_light_am.9.png
new file mode 100644
index 0000000..52e29fc
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_ab_focused_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_ab_pressed_holo_dark_am.9.png b/core/res/res/drawable-xxhdpi/spinner_ab_pressed_holo_dark_am.9.png
new file mode 100644
index 0000000..103a2c3
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_ab_pressed_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_ab_pressed_holo_light_am.9.png b/core/res/res/drawable-xxhdpi/spinner_ab_pressed_holo_light_am.9.png
new file mode 100644
index 0000000..4e76add
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_ab_pressed_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_activated_holo_dark.9.png b/core/res/res/drawable-xxhdpi/spinner_activated_holo_dark.9.png
new file mode 100644
index 0000000..b1a39e1
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_activated_holo_light.9.png b/core/res/res/drawable-xxhdpi/spinner_activated_holo_light.9.png
new file mode 100644
index 0000000..052f551
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_activated_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_default_holo_dark_am.9.png b/core/res/res/drawable-xxhdpi/spinner_default_holo_dark_am.9.png
new file mode 100644
index 0000000..b0020f2
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_default_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_default_holo_light_am.9.png b/core/res/res/drawable-xxhdpi/spinner_default_holo_light_am.9.png
new file mode 100644
index 0000000..32139ce
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_default_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_disabled_holo.9.png b/core/res/res/drawable-xxhdpi/spinner_disabled_holo.9.png
new file mode 100644
index 0000000..f666309
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_disabled_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_disabled_holo_dark_am.9.png b/core/res/res/drawable-xxhdpi/spinner_disabled_holo_dark_am.9.png
new file mode 100644
index 0000000..7c12096
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_disabled_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_disabled_holo_light_am.9.png b/core/res/res/drawable-xxhdpi/spinner_disabled_holo_light_am.9.png
new file mode 100644
index 0000000..4cef095
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_disabled_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_focused_holo_dark_am.9.png b/core/res/res/drawable-xxhdpi/spinner_focused_holo_dark_am.9.png
new file mode 100644
index 0000000..5ab38fd
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_focused_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_focused_holo_light_am.9.png b/core/res/res/drawable-xxhdpi/spinner_focused_holo_light_am.9.png
new file mode 100644
index 0000000..c40ce17
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_focused_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_normal_holo.9.png b/core/res/res/drawable-xxhdpi/spinner_normal_holo.9.png
new file mode 100644
index 0000000..48a23f6
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_normal_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_pressed_holo_dark_am.9.png b/core/res/res/drawable-xxhdpi/spinner_pressed_holo_dark_am.9.png
new file mode 100644
index 0000000..d8b02e0
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_pressed_holo_dark_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_pressed_holo_light_am.9.png b/core/res/res/drawable-xxhdpi/spinner_pressed_holo_light_am.9.png
new file mode 100644
index 0000000..807f2c1
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_pressed_holo_light_am.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_notify_call_mute.png b/core/res/res/drawable-xxhdpi/stat_notify_call_mute.png
new file mode 100644
index 0000000..8c6176c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_notify_car_mode.png b/core/res/res/drawable-xxhdpi/stat_notify_car_mode.png
new file mode 100755
index 0000000..b01e00f
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_notify_car_mode.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_notify_chat.png b/core/res/res/drawable-xxhdpi/stat_notify_chat.png
new file mode 100644
index 0000000..960fdd4
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_notify_chat.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_notify_disabled.png b/core/res/res/drawable-xxhdpi/stat_notify_disabled.png
new file mode 100644
index 0000000..06d7677b
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_notify_disabled.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_notify_disk_full.png b/core/res/res/drawable-xxhdpi/stat_notify_disk_full.png
new file mode 100755
index 0000000..cd790a6
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_notify_disk_full.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_notify_email_generic.png b/core/res/res/drawable-xxhdpi/stat_notify_email_generic.png
new file mode 100755
index 0000000..ba98c67
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_notify_email_generic.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_notify_error.png b/core/res/res/drawable-xxhdpi/stat_notify_error.png
new file mode 100644
index 0000000..fa5f7a3
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_notify_error.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_notify_gmail.png b/core/res/res/drawable-xxhdpi/stat_notify_gmail.png
new file mode 100755
index 0000000..4640e88
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_notify_gmail.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_notify_missed_call.png b/core/res/res/drawable-xxhdpi/stat_notify_missed_call.png
new file mode 100644
index 0000000..904df3b
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_notify_missed_call.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_notify_more.png b/core/res/res/drawable-xxhdpi/stat_notify_more.png
new file mode 100755
index 0000000..f3a46ec
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_notify_more.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_notify_rssi_in_range.png b/core/res/res/drawable-xxhdpi/stat_notify_rssi_in_range.png
new file mode 100644
index 0000000..86c34ed
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_notify_rssi_in_range.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_notify_sdcard.png b/core/res/res/drawable-xxhdpi/stat_notify_sdcard.png
new file mode 100755
index 0000000..87e9d20
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_notify_sdcard.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_notify_sdcard_prepare.png b/core/res/res/drawable-xxhdpi/stat_notify_sdcard_prepare.png
new file mode 100755
index 0000000..735ccc9
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_notify_sdcard_prepare.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_notify_sdcard_usb.png b/core/res/res/drawable-xxhdpi/stat_notify_sdcard_usb.png
new file mode 100755
index 0000000..e7512ed
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_notify_sdcard_usb.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_notify_sim_toolkit.png b/core/res/res/drawable-xxhdpi/stat_notify_sim_toolkit.png
new file mode 100755
index 0000000..d1cf3d7
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_notify_sim_toolkit.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_notify_sync.png b/core/res/res/drawable-xxhdpi/stat_notify_sync.png
new file mode 100755
index 0000000..2a36702
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_notify_sync.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_notify_sync_anim0.png b/core/res/res/drawable-xxhdpi/stat_notify_sync_anim0.png
new file mode 100755
index 0000000..2a36702
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_notify_sync_anim0.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_notify_sync_error.png b/core/res/res/drawable-xxhdpi/stat_notify_sync_error.png
new file mode 100755
index 0000000..db2f0e2
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_notify_sync_error.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_notify_voicemail.png b/core/res/res/drawable-xxhdpi/stat_notify_voicemail.png
new file mode 100755
index 0000000..71dfe68
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_notify_voicemail.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_notify_wifi_in_range.png b/core/res/res/drawable-xxhdpi/stat_notify_wifi_in_range.png
new file mode 100644
index 0000000..47e74fb
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_notify_wifi_in_range.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_adb_am.png b/core/res/res/drawable-xxhdpi/stat_sys_adb_am.png
new file mode 100644
index 0000000..e01ad386
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_sys_adb_am.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_certificate_info.png b/core/res/res/drawable-xxhdpi/stat_sys_certificate_info.png
new file mode 100644
index 0000000..d96ef64
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_sys_certificate_info.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_data_bluetooth.png b/core/res/res/drawable-xxhdpi/stat_sys_data_bluetooth.png
new file mode 100755
index 0000000..6dd4d7f
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_sys_data_bluetooth.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_data_usb.png b/core/res/res/drawable-xxhdpi/stat_sys_data_usb.png
new file mode 100755
index 0000000..7fcf5cd
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_sys_data_usb.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_data_wimax_signal_3_fully.png b/core/res/res/drawable-xxhdpi/stat_sys_data_wimax_signal_3_fully.png
new file mode 100644
index 0000000..aeccbd6
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_sys_data_wimax_signal_3_fully.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_data_wimax_signal_disconnected.png b/core/res/res/drawable-xxhdpi/stat_sys_data_wimax_signal_disconnected.png
new file mode 100644
index 0000000..3cdc45d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_sys_data_wimax_signal_disconnected.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_download_anim0.png b/core/res/res/drawable-xxhdpi/stat_sys_download_anim0.png
new file mode 100755
index 0000000..836db12
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_sys_download_anim0.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_download_anim1.png b/core/res/res/drawable-xxhdpi/stat_sys_download_anim1.png
new file mode 100755
index 0000000..5bc3add4
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_sys_download_anim1.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_download_anim2.png b/core/res/res/drawable-xxhdpi/stat_sys_download_anim2.png
new file mode 100755
index 0000000..962c450
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_sys_download_anim2.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_download_anim3.png b/core/res/res/drawable-xxhdpi/stat_sys_download_anim3.png
new file mode 100755
index 0000000..e1d0d55
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_sys_download_anim3.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_download_anim4.png b/core/res/res/drawable-xxhdpi/stat_sys_download_anim4.png
new file mode 100755
index 0000000..84420de
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_sys_download_anim4.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_download_anim5.png b/core/res/res/drawable-xxhdpi/stat_sys_download_anim5.png
new file mode 100755
index 0000000..b495943
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_sys_download_anim5.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_gps_on.png b/core/res/res/drawable-xxhdpi/stat_sys_gps_on.png
new file mode 100755
index 0000000..81fb04a
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_sys_gps_on.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_phone_call.png b/core/res/res/drawable-xxhdpi/stat_sys_phone_call.png
new file mode 100644
index 0000000..9348384
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_sys_phone_call.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_speakerphone.png b/core/res/res/drawable-xxhdpi/stat_sys_speakerphone.png
new file mode 100644
index 0000000..a53913f
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_tether_bluetooth.png b/core/res/res/drawable-xxhdpi/stat_sys_tether_bluetooth.png
new file mode 100644
index 0000000..25acfbb
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_sys_tether_bluetooth.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_tether_general.png b/core/res/res/drawable-xxhdpi/stat_sys_tether_general.png
new file mode 100644
index 0000000..5c65601
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_sys_tether_general.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_tether_usb.png b/core/res/res/drawable-xxhdpi/stat_sys_tether_usb.png
new file mode 100644
index 0000000..28b4b54
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_sys_tether_usb.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_tether_wifi.png b/core/res/res/drawable-xxhdpi/stat_sys_tether_wifi.png
new file mode 100644
index 0000000..da44e6a
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_sys_tether_wifi.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_throttled.png b/core/res/res/drawable-xxhdpi/stat_sys_throttled.png
new file mode 100755
index 0000000..c2189e4
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_sys_throttled.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_upload_anim0.png b/core/res/res/drawable-xxhdpi/stat_sys_upload_anim0.png
new file mode 100755
index 0000000..9e63fca
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_sys_upload_anim0.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_upload_anim1.png b/core/res/res/drawable-xxhdpi/stat_sys_upload_anim1.png
new file mode 100755
index 0000000..39dd3b8
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_sys_upload_anim1.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_upload_anim2.png b/core/res/res/drawable-xxhdpi/stat_sys_upload_anim2.png
new file mode 100755
index 0000000..b828430
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_sys_upload_anim2.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_upload_anim3.png b/core/res/res/drawable-xxhdpi/stat_sys_upload_anim3.png
new file mode 100755
index 0000000..7834460
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_sys_upload_anim3.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_upload_anim4.png b/core/res/res/drawable-xxhdpi/stat_sys_upload_anim4.png
new file mode 100755
index 0000000..34c6f27
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_sys_upload_anim4.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_upload_anim5.png b/core/res/res/drawable-xxhdpi/stat_sys_upload_anim5.png
new file mode 100755
index 0000000..1270acf
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_sys_upload_anim5.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_warning.png b/core/res/res/drawable-xxhdpi/stat_sys_warning.png
new file mode 100755
index 0000000..907de0f
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_sys_warning.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/switch_bg_disabled_holo_dark.9.png b/core/res/res/drawable-xxhdpi/switch_bg_disabled_holo_dark.9.png
new file mode 100644
index 0000000..e80453e
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/switch_bg_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/switch_bg_disabled_holo_light.9.png b/core/res/res/drawable-xxhdpi/switch_bg_disabled_holo_light.9.png
new file mode 100644
index 0000000..0ec08ee
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/switch_bg_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/switch_bg_focused_holo_dark.9.png b/core/res/res/drawable-xxhdpi/switch_bg_focused_holo_dark.9.png
new file mode 100644
index 0000000..13f852d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/switch_bg_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/switch_bg_focused_holo_light.9.png b/core/res/res/drawable-xxhdpi/switch_bg_focused_holo_light.9.png
new file mode 100644
index 0000000..e7767b8
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/switch_bg_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/switch_bg_holo_dark.9.png b/core/res/res/drawable-xxhdpi/switch_bg_holo_dark.9.png
new file mode 100644
index 0000000..d1133bf
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/switch_bg_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/switch_bg_holo_light.9.png b/core/res/res/drawable-xxhdpi/switch_bg_holo_light.9.png
new file mode 100644
index 0000000..4532035
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/switch_bg_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/switch_thumb_activated_holo_dark.9.png b/core/res/res/drawable-xxhdpi/switch_thumb_activated_holo_dark.9.png
new file mode 100644
index 0000000..2b3e151
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/switch_thumb_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/switch_thumb_activated_holo_light.9.png b/core/res/res/drawable-xxhdpi/switch_thumb_activated_holo_light.9.png
new file mode 100644
index 0000000..77c08a5
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/switch_thumb_activated_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/switch_thumb_disabled_holo_dark.9.png b/core/res/res/drawable-xxhdpi/switch_thumb_disabled_holo_dark.9.png
new file mode 100644
index 0000000..5f36c04
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/switch_thumb_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/switch_thumb_disabled_holo_light.9.png b/core/res/res/drawable-xxhdpi/switch_thumb_disabled_holo_light.9.png
new file mode 100644
index 0000000..7c16463
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/switch_thumb_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/switch_thumb_holo_dark.9.png b/core/res/res/drawable-xxhdpi/switch_thumb_holo_dark.9.png
new file mode 100644
index 0000000..f14f0d6
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/switch_thumb_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/switch_thumb_holo_light.9.png b/core/res/res/drawable-xxhdpi/switch_thumb_holo_light.9.png
new file mode 100644
index 0000000..9920f54
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/switch_thumb_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/switch_thumb_holo_light_v2.9.png b/core/res/res/drawable-xxhdpi/switch_thumb_holo_light_v2.9.png
new file mode 100644
index 0000000..00518ad
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/switch_thumb_holo_light_v2.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/switch_thumb_pressed_holo_dark.9.png b/core/res/res/drawable-xxhdpi/switch_thumb_pressed_holo_dark.9.png
new file mode 100644
index 0000000..bdcfc74
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/switch_thumb_pressed_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/switch_thumb_pressed_holo_light.9.png b/core/res/res/drawable-xxhdpi/switch_thumb_pressed_holo_light.9.png
new file mode 100644
index 0000000..302b4e2
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/switch_thumb_pressed_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/sym_def_app_icon.png b/core/res/res/drawable-xxhdpi/sym_def_app_icon.png
new file mode 100644
index 0000000..20a47a0
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/sym_def_app_icon.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/sym_keyboard_delete.png b/core/res/res/drawable-xxhdpi/sym_keyboard_delete.png
new file mode 100644
index 0000000..9230135
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/sym_keyboard_delete.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/sym_keyboard_enter.png b/core/res/res/drawable-xxhdpi/sym_keyboard_enter.png
new file mode 100644
index 0000000..a234cde
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/sym_keyboard_enter.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/sym_keyboard_num0_no_plus.png b/core/res/res/drawable-xxhdpi/sym_keyboard_num0_no_plus.png
new file mode 100644
index 0000000..da434a4
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/sym_keyboard_num0_no_plus.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/sym_keyboard_num1.png b/core/res/res/drawable-xxhdpi/sym_keyboard_num1.png
new file mode 100644
index 0000000..715e9aee
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/sym_keyboard_num1.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/sym_keyboard_num2.png b/core/res/res/drawable-xxhdpi/sym_keyboard_num2.png
new file mode 100644
index 0000000..d0cbce2
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/sym_keyboard_num2.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/sym_keyboard_num3.png b/core/res/res/drawable-xxhdpi/sym_keyboard_num3.png
new file mode 100644
index 0000000..d152442
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/sym_keyboard_num3.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/sym_keyboard_num4.png b/core/res/res/drawable-xxhdpi/sym_keyboard_num4.png
new file mode 100644
index 0000000..9438f47
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/sym_keyboard_num4.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/sym_keyboard_num5.png b/core/res/res/drawable-xxhdpi/sym_keyboard_num5.png
new file mode 100644
index 0000000..0104cfe
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/sym_keyboard_num5.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/sym_keyboard_num6.png b/core/res/res/drawable-xxhdpi/sym_keyboard_num6.png
new file mode 100644
index 0000000..852d0a22
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/sym_keyboard_num6.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/sym_keyboard_num7.png b/core/res/res/drawable-xxhdpi/sym_keyboard_num7.png
new file mode 100644
index 0000000..bdd1e22
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/sym_keyboard_num7.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/sym_keyboard_num8.png b/core/res/res/drawable-xxhdpi/sym_keyboard_num8.png
new file mode 100644
index 0000000..0d9a0f3
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/sym_keyboard_num8.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/sym_keyboard_num9.png b/core/res/res/drawable-xxhdpi/sym_keyboard_num9.png
new file mode 100644
index 0000000..ab87892
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/sym_keyboard_num9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/sym_keyboard_return_holo.png b/core/res/res/drawable-xxhdpi/sym_keyboard_return_holo.png
new file mode 100644
index 0000000..7d95807
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/sym_keyboard_return_holo.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/tab_selected_focused_holo.9.png b/core/res/res/drawable-xxhdpi/tab_selected_focused_holo.9.png
new file mode 100644
index 0000000..619efa4
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/tab_selected_focused_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/tab_selected_holo.9.png b/core/res/res/drawable-xxhdpi/tab_selected_holo.9.png
new file mode 100644
index 0000000..bee35ca
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/tab_selected_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/tab_selected_pressed_holo.9.png b/core/res/res/drawable-xxhdpi/tab_selected_pressed_holo.9.png
new file mode 100644
index 0000000..8987d993d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/tab_selected_pressed_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/tab_unselected_focused_holo.9.png b/core/res/res/drawable-xxhdpi/tab_unselected_focused_holo.9.png
new file mode 100644
index 0000000..e9a5bf5
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/tab_unselected_focused_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/tab_unselected_holo.9.png b/core/res/res/drawable-xxhdpi/tab_unselected_holo.9.png
new file mode 100644
index 0000000..8fcecf7
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/tab_unselected_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/tab_unselected_pressed_holo.9.png b/core/res/res/drawable-xxhdpi/tab_unselected_pressed_holo.9.png
new file mode 100644
index 0000000..92419c4
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/tab_unselected_pressed_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/text_edit_paste_window.9.png b/core/res/res/drawable-xxhdpi/text_edit_paste_window.9.png
new file mode 100644
index 0000000..9e247e6
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/text_edit_paste_window.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/text_edit_suggestions_window.9.png b/core/res/res/drawable-xxhdpi/text_edit_suggestions_window.9.png
new file mode 100644
index 0000000..9e247e6
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/text_edit_suggestions_window.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/text_select_handle_left.png b/core/res/res/drawable-xxhdpi/text_select_handle_left.png
new file mode 100644
index 0000000..8497601
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/text_select_handle_left.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/text_select_handle_middle.png b/core/res/res/drawable-xxhdpi/text_select_handle_middle.png
new file mode 100644
index 0000000..7b74f66
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/text_select_handle_middle.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/text_select_handle_right.png b/core/res/res/drawable-xxhdpi/text_select_handle_right.png
new file mode 100644
index 0000000..25e0780
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/text_select_handle_right.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_activated_holo_dark.9.png b/core/res/res/drawable-xxhdpi/textfield_activated_holo_dark.9.png
new file mode 100644
index 0000000..a4c891e
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_activated_holo_light.9.png b/core/res/res/drawable-xxhdpi/textfield_activated_holo_light.9.png
new file mode 100644
index 0000000..a4c891e
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_activated_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_default_holo_dark.9.png b/core/res/res/drawable-xxhdpi/textfield_default_holo_dark.9.png
new file mode 100644
index 0000000..1e8dafa
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_default_holo_light.9.png b/core/res/res/drawable-xxhdpi/textfield_default_holo_light.9.png
new file mode 100644
index 0000000..9ece814
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_disabled_focused_holo_dark.9.png b/core/res/res/drawable-xxhdpi/textfield_disabled_focused_holo_dark.9.png
new file mode 100644
index 0000000..e21548e
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_disabled_focused_holo_light.9.png b/core/res/res/drawable-xxhdpi/textfield_disabled_focused_holo_light.9.png
new file mode 100644
index 0000000..5bc20f9
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_disabled_holo_dark.9.png b/core/res/res/drawable-xxhdpi/textfield_disabled_holo_dark.9.png
new file mode 100644
index 0000000..5592f76
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_disabled_holo_light.9.png b/core/res/res/drawable-xxhdpi/textfield_disabled_holo_light.9.png
new file mode 100644
index 0000000..8fda94d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_focused_holo_dark.9.png b/core/res/res/drawable-xxhdpi/textfield_focused_holo_dark.9.png
new file mode 100644
index 0000000..d557164
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_focused_holo_light.9.png b/core/res/res/drawable-xxhdpi/textfield_focused_holo_light.9.png
new file mode 100644
index 0000000..d557164
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_multiline_activated_holo_dark.9.png b/core/res/res/drawable-xxhdpi/textfield_multiline_activated_holo_dark.9.png
new file mode 100644
index 0000000..a4c891e
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_multiline_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_multiline_activated_holo_light.9.png b/core/res/res/drawable-xxhdpi/textfield_multiline_activated_holo_light.9.png
new file mode 100644
index 0000000..a4c891e
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_multiline_activated_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_multiline_default_holo_dark.9.png b/core/res/res/drawable-xxhdpi/textfield_multiline_default_holo_dark.9.png
new file mode 100644
index 0000000..1e8dafa
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_multiline_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_multiline_default_holo_light.9.png b/core/res/res/drawable-xxhdpi/textfield_multiline_default_holo_light.9.png
new file mode 100644
index 0000000..9ece814
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_multiline_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_multiline_disabled_focused_holo_dark.9.png b/core/res/res/drawable-xxhdpi/textfield_multiline_disabled_focused_holo_dark.9.png
new file mode 100644
index 0000000..e21548e
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_multiline_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_multiline_disabled_focused_holo_light.9.png b/core/res/res/drawable-xxhdpi/textfield_multiline_disabled_focused_holo_light.9.png
new file mode 100644
index 0000000..5bc20f9
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_multiline_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_multiline_disabled_holo_dark.9.png b/core/res/res/drawable-xxhdpi/textfield_multiline_disabled_holo_dark.9.png
new file mode 100644
index 0000000..5592f76
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_multiline_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_multiline_disabled_holo_light.9.png b/core/res/res/drawable-xxhdpi/textfield_multiline_disabled_holo_light.9.png
new file mode 100644
index 0000000..8fda94d
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_multiline_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_multiline_focused_holo_dark.9.png b/core/res/res/drawable-xxhdpi/textfield_multiline_focused_holo_dark.9.png
new file mode 100644
index 0000000..d557164
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_multiline_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_multiline_focused_holo_light.9.png b/core/res/res/drawable-xxhdpi/textfield_multiline_focused_holo_light.9.png
new file mode 100644
index 0000000..d557164
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_multiline_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_search_default_holo_dark.9.png b/core/res/res/drawable-xxhdpi/textfield_search_default_holo_dark.9.png
new file mode 100644
index 0000000..e634c75
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_search_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_search_default_holo_light.9.png b/core/res/res/drawable-xxhdpi/textfield_search_default_holo_light.9.png
new file mode 100644
index 0000000..ea9dd89
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_search_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_search_right_default_holo_dark.9.png b/core/res/res/drawable-xxhdpi/textfield_search_right_default_holo_dark.9.png
new file mode 100644
index 0000000..6042bcf
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_search_right_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_search_right_default_holo_light.9.png b/core/res/res/drawable-xxhdpi/textfield_search_right_default_holo_light.9.png
new file mode 100644
index 0000000..b34b536
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_search_right_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_search_right_selected_holo_dark.9.png b/core/res/res/drawable-xxhdpi/textfield_search_right_selected_holo_dark.9.png
new file mode 100644
index 0000000..114acf4
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_search_right_selected_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_search_right_selected_holo_light.9.png b/core/res/res/drawable-xxhdpi/textfield_search_right_selected_holo_light.9.png
new file mode 100644
index 0000000..098475b
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_search_right_selected_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_search_selected_holo_dark.9.png b/core/res/res/drawable-xxhdpi/textfield_search_selected_holo_dark.9.png
new file mode 100644
index 0000000..8fcaadc
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_search_selected_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_search_selected_holo_light.9.png b/core/res/res/drawable-xxhdpi/textfield_search_selected_holo_light.9.png
new file mode 100644
index 0000000..df5c730
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_search_selected_holo_light.9.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
new file mode 100644
index 0000000..882b9c6
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/toast_frame.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/toast_frame_holo.9.png b/core/res/res/drawable-xxhdpi/toast_frame_holo.9.png
new file mode 100644
index 0000000..882b9c6
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/toast_frame_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/transportcontrol_bg.9.png b/core/res/res/drawable-xxhdpi/transportcontrol_bg.9.png
new file mode 100644
index 0000000..a5dc6cb
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/transportcontrol_bg.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/vpn_connected.png b/core/res/res/drawable-xxhdpi/vpn_connected.png
new file mode 100644
index 0000000..ea4930c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/vpn_connected.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/vpn_disconnected.png b/core/res/res/drawable-xxhdpi/vpn_disconnected.png
new file mode 100644
index 0000000..4cd0dd4
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/vpn_disconnected.png
Binary files differ
diff --git a/core/res/res/drawable/activity_picker_bg.xml b/core/res/res/drawable/activity_picker_bg.xml
deleted file mode 100644
index a471c94..0000000
--- a/core/res/res/drawable/activity_picker_bg.xml
+++ /dev/null
@@ -1,30 +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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <item android:state_window_focused="false" android:drawable="@color/transparent" />
-
-    <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. -->
-    <item android:state_focused="true"  android:state_enabled="false" android:state_pressed="true" android:drawable="@drawable/list_selector_disabled_holo_light" />
-    <item android:state_focused="true"  android:state_enabled="false"                              android:drawable="@drawable/list_selector_disabled_holo_light" />
-    <item android:state_focused="true"                                android:state_pressed="true" android:drawable="@drawable/list_selector_background_transition_holo_light" />
-    <item android:state_focused="false"                               android:state_pressed="true" android:drawable="@drawable/list_selector_background_transition_holo_light" />
-    <item android:state_focused="true"                                                             android:drawable="@drawable/activity_picker_bg_focused" />
-    <item android:state_activated="true"                                                             android:drawable="@drawable/activity_picker_bg_activated" />
-    <item android:drawable="@color/transparent" />
-
-</selector>
diff --git a/core/res/res/drawable/btn_cab_done_holo_dark.xml b/core/res/res/drawable/btn_cab_done_holo_dark.xml
index fe42951..14f5777 100644
--- a/core/res/res/drawable/btn_cab_done_holo_dark.xml
+++ b/core/res/res/drawable/btn_cab_done_holo_dark.xml
@@ -14,7 +14,8 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+          android:autoMirrored="true">
     <item android:state_pressed="true"
         android:drawable="@drawable/btn_cab_done_pressed_holo_dark" />
     <item android:state_focused="true" android:state_enabled="true"
diff --git a/core/res/res/drawable/btn_cab_done_holo_light.xml b/core/res/res/drawable/btn_cab_done_holo_light.xml
index f362774..a9a634f 100644
--- a/core/res/res/drawable/btn_cab_done_holo_light.xml
+++ b/core/res/res/drawable/btn_cab_done_holo_light.xml
@@ -14,7 +14,8 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+          android:autoMirrored="true">
     <item android:state_pressed="true"
         android:drawable="@drawable/btn_cab_done_pressed_holo_light" />
     <item android:state_focused="true" android:state_enabled="true"
diff --git a/core/res/res/drawable/ic_ab_back_holo_dark.xml b/core/res/res/drawable/ic_ab_back_holo_dark.xml
new file mode 100644
index 0000000..740d3e8
--- /dev/null
+++ b/core/res/res/drawable/ic_ab_back_holo_dark.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/ic_ab_back_holo_dark_am"
+        android:autoMirrored="true">
+</bitmap>
diff --git a/core/res/res/drawable/ic_ab_back_holo_light.xml b/core/res/res/drawable/ic_ab_back_holo_light.xml
new file mode 100644
index 0000000..7639f94
--- /dev/null
+++ b/core/res/res/drawable/ic_ab_back_holo_light.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/ic_ab_back_holo_light_am"
+        android:autoMirrored="true">
+</bitmap>
diff --git a/core/res/res/drawable/ic_audio_notification.xml b/core/res/res/drawable/ic_audio_notification.xml
new file mode 100644
index 0000000..b87e4c8
--- /dev/null
+++ b/core/res/res/drawable/ic_audio_notification.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/ic_audio_notification_am"
+        android:autoMirrored="true">
+</bitmap>
diff --git a/core/res/res/drawable/ic_audio_notification_mute.xml b/core/res/res/drawable/ic_audio_notification_mute.xml
new file mode 100644
index 0000000..1caf27c
--- /dev/null
+++ b/core/res/res/drawable/ic_audio_notification_mute.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/ic_audio_notification_mute_am"
+        android:autoMirrored="true">
+</bitmap>
diff --git a/core/res/res/drawable/ic_audio_phone.xml b/core/res/res/drawable/ic_audio_phone.xml
new file mode 100644
index 0000000..e6869fd
--- /dev/null
+++ b/core/res/res/drawable/ic_audio_phone.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/ic_audio_phone_am"
+        android:autoMirrored="true">
+</bitmap>
diff --git a/core/res/res/drawable/ic_audio_ring_notif.xml b/core/res/res/drawable/ic_audio_ring_notif.xml
new file mode 100644
index 0000000..2f48741
--- /dev/null
+++ b/core/res/res/drawable/ic_audio_ring_notif.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/ic_audio_ring_notif_am"
+        android:autoMirrored="true">
+</bitmap>
diff --git a/core/res/res/drawable/ic_audio_ring_notif_mute.xml b/core/res/res/drawable/ic_audio_ring_notif_mute.xml
new file mode 100644
index 0000000..7549f6d
--- /dev/null
+++ b/core/res/res/drawable/ic_audio_ring_notif_mute.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/ic_audio_ring_notif_mute_am"
+        android:autoMirrored="true">
+</bitmap>
diff --git a/core/res/res/drawable/ic_audio_ring_notif_vibrate.xml b/core/res/res/drawable/ic_audio_ring_notif_vibrate.xml
new file mode 100644
index 0000000..3481e27
--- /dev/null
+++ b/core/res/res/drawable/ic_audio_ring_notif_vibrate.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/ic_audio_ring_notif_vibrate_am"
+        android:autoMirrored="true">
+</bitmap>
diff --git a/core/res/res/drawable/ic_audio_vol.xml b/core/res/res/drawable/ic_audio_vol.xml
new file mode 100644
index 0000000..6dd249b
--- /dev/null
+++ b/core/res/res/drawable/ic_audio_vol.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/ic_audio_vol_am"
+        android:autoMirrored="true">
+</bitmap>
diff --git a/core/res/res/drawable/ic_audio_vol_mute.xml b/core/res/res/drawable/ic_audio_vol_mute.xml
new file mode 100644
index 0000000..b093f59
--- /dev/null
+++ b/core/res/res/drawable/ic_audio_vol_mute.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/ic_audio_vol_mute_am"
+        android:autoMirrored="true">
+</bitmap>
diff --git a/core/res/res/drawable/ic_lock_airplane_mode_off.xml b/core/res/res/drawable/ic_lock_airplane_mode_off.xml
new file mode 100644
index 0000000..b344e28
--- /dev/null
+++ b/core/res/res/drawable/ic_lock_airplane_mode_off.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/ic_lock_airplane_mode_off_am"
+        android:autoMirrored="true">
+</bitmap>
diff --git a/core/res/res/drawable/ic_menu_cc.xml b/core/res/res/drawable/ic_menu_cc.xml
new file mode 100644
index 0000000..2bb4ff7
--- /dev/null
+++ b/core/res/res/drawable/ic_menu_cc.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/ic_menu_cc_am"
+        android:autoMirrored="true">
+</bitmap>
diff --git a/core/res/res/drawable/lockscreen_password_field_dark.xml b/core/res/res/drawable/lockscreen_password_field_dark.xml
deleted file mode 100644
index 92ceb79..0000000
--- a/core/res/res/drawable/lockscreen_password_field_dark.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_window_focused="false" android:state_enabled="true" android:drawable="@drawable/textfield_bg_default_holo_dark" />
-    <item android:state_window_focused="false" android:state_enabled="false" android:drawable="@drawable/textfield_bg_disabled_holo_dark" />
-    <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/textfield_bg_activated_holo_dark" />
-    <iten android:state_enabled="true" android:state_activated="true" android:drawable="@drawable/textfield_bg_focused_holo_dark" />
-    <item android:state_enabled="true" android:drawable="@drawable/textfield_bg_default_holo_dark" />
-    <item android:state_focused="true" android:drawable="@drawable/textfield_bg_disabled_focused_holo_dark" />
-    <item android:drawable="@drawable/textfield_bg_disabled_holo_dark" />
-</selector>
-
diff --git a/core/res/res/drawable/popup_inline_error.xml b/core/res/res/drawable/popup_inline_error.xml
new file mode 100644
index 0000000..d74678b
--- /dev/null
+++ b/core/res/res/drawable/popup_inline_error.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/popup_inline_error_am"
+        android:autoMirrored="true">
+</nine-patch>
diff --git a/core/res/res/drawable/popup_inline_error_above.xml b/core/res/res/drawable/popup_inline_error_above.xml
new file mode 100644
index 0000000..4be5a3e
--- /dev/null
+++ b/core/res/res/drawable/popup_inline_error_above.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/popup_inline_error_above_am"
+        android:autoMirrored="true">
+</nine-patch>
diff --git a/core/res/res/drawable/popup_inline_error_above_holo_dark.xml b/core/res/res/drawable/popup_inline_error_above_holo_dark.xml
new file mode 100644
index 0000000..70511b8
--- /dev/null
+++ b/core/res/res/drawable/popup_inline_error_above_holo_dark.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/popup_inline_error_above_holo_dark_am"
+        android:autoMirrored="true">
+</nine-patch>
diff --git a/core/res/res/drawable/popup_inline_error_above_holo_light.xml b/core/res/res/drawable/popup_inline_error_above_holo_light.xml
new file mode 100644
index 0000000..0cf8974
--- /dev/null
+++ b/core/res/res/drawable/popup_inline_error_above_holo_light.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/popup_inline_error_above_holo_light_am"
+        android:autoMirrored="true">
+</nine-patch>
diff --git a/core/res/res/drawable/popup_inline_error_holo_dark.xml b/core/res/res/drawable/popup_inline_error_holo_dark.xml
new file mode 100644
index 0000000..16cfe79
--- /dev/null
+++ b/core/res/res/drawable/popup_inline_error_holo_dark.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/popup_inline_error_holo_dark_am"
+        android:autoMirrored="true">
+</nine-patch>
diff --git a/core/res/res/drawable/popup_inline_error_holo_light.xml b/core/res/res/drawable/popup_inline_error_holo_light.xml
new file mode 100644
index 0000000..1725a22
--- /dev/null
+++ b/core/res/res/drawable/popup_inline_error_holo_light.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/popup_inline_error_holo_light_am"
+        android:autoMirrored="true">
+</nine-patch>
diff --git a/core/res/res/drawable/quickcontact_badge_overlay_focused_dark.xml b/core/res/res/drawable/quickcontact_badge_overlay_focused_dark.xml
new file mode 100644
index 0000000..21fb932
--- /dev/null
+++ b/core/res/res/drawable/quickcontact_badge_overlay_focused_dark.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/quickcontact_badge_overlay_focused_dark_am"
+        android:autoMirrored="true">
+</nine-patch>
diff --git a/core/res/res/drawable/quickcontact_badge_overlay_focused_light.xml b/core/res/res/drawable/quickcontact_badge_overlay_focused_light.xml
new file mode 100644
index 0000000..04f97cd
--- /dev/null
+++ b/core/res/res/drawable/quickcontact_badge_overlay_focused_light.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/quickcontact_badge_overlay_focused_light_am"
+        android:autoMirrored="true">
+</nine-patch>
diff --git a/core/res/res/drawable/quickcontact_badge_overlay_normal_dark.xml b/core/res/res/drawable/quickcontact_badge_overlay_normal_dark.xml
new file mode 100644
index 0000000..ff17781
--- /dev/null
+++ b/core/res/res/drawable/quickcontact_badge_overlay_normal_dark.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/quickcontact_badge_overlay_normal_dark_am"
+        android:autoMirrored="true">
+</nine-patch>
diff --git a/core/res/res/drawable/quickcontact_badge_overlay_normal_light.xml b/core/res/res/drawable/quickcontact_badge_overlay_normal_light.xml
new file mode 100644
index 0000000..148354d
--- /dev/null
+++ b/core/res/res/drawable/quickcontact_badge_overlay_normal_light.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/quickcontact_badge_overlay_normal_light_am"
+        android:autoMirrored="true">
+</nine-patch>
diff --git a/core/res/res/drawable/quickcontact_badge_overlay_pressed_dark.xml b/core/res/res/drawable/quickcontact_badge_overlay_pressed_dark.xml
new file mode 100644
index 0000000..9ca8a88
--- /dev/null
+++ b/core/res/res/drawable/quickcontact_badge_overlay_pressed_dark.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/quickcontact_badge_overlay_pressed_dark_am"
+        android:autoMirrored="true">
+</nine-patch>
diff --git a/core/res/res/drawable/quickcontact_badge_overlay_pressed_light.xml b/core/res/res/drawable/quickcontact_badge_overlay_pressed_light.xml
new file mode 100644
index 0000000..d2236e2
--- /dev/null
+++ b/core/res/res/drawable/quickcontact_badge_overlay_pressed_light.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/quickcontact_badge_overlay_pressed_light_am"
+        android:autoMirrored="true">
+</nine-patch>
diff --git a/core/res/res/drawable/spinner_ab_default_holo_dark.xml b/core/res/res/drawable/spinner_ab_default_holo_dark.xml
new file mode 100644
index 0000000..b0cc006
--- /dev/null
+++ b/core/res/res/drawable/spinner_ab_default_holo_dark.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/spinner_ab_default_holo_dark_am"
+        android:autoMirrored="true">
+</nine-patch>
diff --git a/core/res/res/drawable/spinner_ab_default_holo_light.xml b/core/res/res/drawable/spinner_ab_default_holo_light.xml
new file mode 100644
index 0000000..48d1fcb
--- /dev/null
+++ b/core/res/res/drawable/spinner_ab_default_holo_light.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/spinner_ab_default_holo_light_am"
+        android:autoMirrored="true">
+</nine-patch>
diff --git a/core/res/res/drawable/spinner_ab_disabled_holo_dark.xml b/core/res/res/drawable/spinner_ab_disabled_holo_dark.xml
new file mode 100644
index 0000000..60926a7
--- /dev/null
+++ b/core/res/res/drawable/spinner_ab_disabled_holo_dark.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/spinner_ab_disabled_holo_dark_am"
+        android:autoMirrored="true">
+</nine-patch>
diff --git a/core/res/res/drawable/spinner_ab_disabled_holo_light.xml b/core/res/res/drawable/spinner_ab_disabled_holo_light.xml
new file mode 100644
index 0000000..668212c
--- /dev/null
+++ b/core/res/res/drawable/spinner_ab_disabled_holo_light.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/spinner_ab_disabled_holo_light_am"
+        android:autoMirrored="true">
+</nine-patch>
diff --git a/core/res/res/drawable/spinner_ab_focused_holo_dark.xml b/core/res/res/drawable/spinner_ab_focused_holo_dark.xml
new file mode 100644
index 0000000..ff82bce
--- /dev/null
+++ b/core/res/res/drawable/spinner_ab_focused_holo_dark.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/spinner_ab_focused_holo_dark_am"
+        android:autoMirrored="true">
+</nine-patch>
diff --git a/core/res/res/drawable/spinner_ab_focused_holo_light.xml b/core/res/res/drawable/spinner_ab_focused_holo_light.xml
new file mode 100644
index 0000000..19ac864
--- /dev/null
+++ b/core/res/res/drawable/spinner_ab_focused_holo_light.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/spinner_ab_focused_holo_light_am"
+        android:autoMirrored="true">
+</nine-patch>
diff --git a/core/res/res/drawable/spinner_ab_holo_dark.xml b/core/res/res/drawable/spinner_ab_holo_dark.xml
index 0932eff..9b8967c 100644
--- a/core/res/res/drawable/spinner_ab_holo_dark.xml
+++ b/core/res/res/drawable/spinner_ab_holo_dark.xml
@@ -14,7 +14,8 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+          android:autoMirrored="true">
     <item android:state_enabled="false"
           android:drawable="@drawable/spinner_ab_disabled_holo_dark" />
     <item android:state_pressed="true"
diff --git a/core/res/res/drawable/spinner_ab_holo_light.xml b/core/res/res/drawable/spinner_ab_holo_light.xml
index e785cf4..a324c08 100644
--- a/core/res/res/drawable/spinner_ab_holo_light.xml
+++ b/core/res/res/drawable/spinner_ab_holo_light.xml
@@ -14,7 +14,8 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+          android:autoMirrored="true">
     <item android:state_enabled="false"
           android:drawable="@drawable/spinner_ab_disabled_holo_light" />
     <item android:state_pressed="true"
diff --git a/core/res/res/drawable/spinner_ab_pressed_holo_dark.xml b/core/res/res/drawable/spinner_ab_pressed_holo_dark.xml
new file mode 100644
index 0000000..baad9f0
--- /dev/null
+++ b/core/res/res/drawable/spinner_ab_pressed_holo_dark.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/spinner_ab_pressed_holo_dark_am"
+        android:autoMirrored="true">
+</nine-patch>
diff --git a/core/res/res/drawable/spinner_ab_pressed_holo_light.xml b/core/res/res/drawable/spinner_ab_pressed_holo_light.xml
new file mode 100644
index 0000000..b58ee1d
--- /dev/null
+++ b/core/res/res/drawable/spinner_ab_pressed_holo_light.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/spinner_ab_pressed_holo_light_am"
+        android:autoMirrored="true">
+</nine-patch>
diff --git a/core/res/res/drawable/spinner_background_holo_dark.xml b/core/res/res/drawable/spinner_background_holo_dark.xml
index eb6b18b..a57f720 100644
--- a/core/res/res/drawable/spinner_background_holo_dark.xml
+++ b/core/res/res/drawable/spinner_background_holo_dark.xml
@@ -14,7 +14,8 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+          android:autoMirrored="true">
     <item android:state_enabled="false"
           android:drawable="@drawable/spinner_disabled_holo_dark" />
     <item android:state_pressed="true"
diff --git a/core/res/res/drawable/spinner_background_holo_light.xml b/core/res/res/drawable/spinner_background_holo_light.xml
index 9d17ed0c..899633c 100644
--- a/core/res/res/drawable/spinner_background_holo_light.xml
+++ b/core/res/res/drawable/spinner_background_holo_light.xml
@@ -14,7 +14,8 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+          android:autoMirrored="true">
     <item android:state_enabled="false"
           android:drawable="@drawable/spinner_disabled_holo_light" />
     <item android:state_pressed="true"
diff --git a/core/res/res/drawable/spinner_default_holo_dark.xml b/core/res/res/drawable/spinner_default_holo_dark.xml
new file mode 100644
index 0000000..8d0d020
--- /dev/null
+++ b/core/res/res/drawable/spinner_default_holo_dark.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/spinner_default_holo_dark_am"
+        android:autoMirrored="true">
+</nine-patch>
diff --git a/core/res/res/drawable/spinner_default_holo_light.xml b/core/res/res/drawable/spinner_default_holo_light.xml
new file mode 100644
index 0000000..250f2eb
--- /dev/null
+++ b/core/res/res/drawable/spinner_default_holo_light.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/spinner_default_holo_light_am"
+        android:autoMirrored="true">
+</nine-patch>
diff --git a/core/res/res/drawable/spinner_disabled_holo_dark.xml b/core/res/res/drawable/spinner_disabled_holo_dark.xml
new file mode 100644
index 0000000..c7efa8b
--- /dev/null
+++ b/core/res/res/drawable/spinner_disabled_holo_dark.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/spinner_disabled_holo_dark_am"
+        android:autoMirrored="true">
+</nine-patch>
diff --git a/core/res/res/drawable/spinner_disabled_holo_light.xml b/core/res/res/drawable/spinner_disabled_holo_light.xml
new file mode 100644
index 0000000..772154b
--- /dev/null
+++ b/core/res/res/drawable/spinner_disabled_holo_light.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/spinner_disabled_holo_light_am"
+        android:autoMirrored="true">
+</nine-patch>
diff --git a/core/res/res/drawable/spinner_focused_holo_dark.xml b/core/res/res/drawable/spinner_focused_holo_dark.xml
new file mode 100644
index 0000000..9758fa3
--- /dev/null
+++ b/core/res/res/drawable/spinner_focused_holo_dark.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/spinner_focused_holo_dark_am"
+        android:autoMirrored="true">
+</nine-patch>
diff --git a/core/res/res/drawable/spinner_focused_holo_light.xml b/core/res/res/drawable/spinner_focused_holo_light.xml
new file mode 100644
index 0000000..e3f7108
--- /dev/null
+++ b/core/res/res/drawable/spinner_focused_holo_light.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/spinner_focused_holo_light_am"
+        android:autoMirrored="true">
+</nine-patch>
diff --git a/core/res/res/drawable/spinner_pressed_holo_dark.xml b/core/res/res/drawable/spinner_pressed_holo_dark.xml
new file mode 100644
index 0000000..ab98514
--- /dev/null
+++ b/core/res/res/drawable/spinner_pressed_holo_dark.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/spinner_pressed_holo_dark_am"
+        android:autoMirrored="true">
+</nine-patch>
diff --git a/core/res/res/drawable/spinner_pressed_holo_light.xml b/core/res/res/drawable/spinner_pressed_holo_light.xml
new file mode 100644
index 0000000..6be4785
--- /dev/null
+++ b/core/res/res/drawable/spinner_pressed_holo_light.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/spinner_pressed_holo_light_am"
+        android:autoMirrored="true">
+</nine-patch>
diff --git a/core/res/res/drawable/stat_sys_adb.xml b/core/res/res/drawable/stat_sys_adb.xml
new file mode 100644
index 0000000..dfc8563
--- /dev/null
+++ b/core/res/res/drawable/stat_sys_adb.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+        android:src="@drawable/stat_sys_adb_am"
+        android:autoMirrored="true">
+</bitmap>
diff --git a/core/res/res/drawable/view_accessibility_focused.xml b/core/res/res/drawable/view_accessibility_focused.xml
new file mode 100644
index 0000000..0da9a81
--- /dev/null
+++ b/core/res/res/drawable/view_accessibility_focused.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <stroke
+        android:width="2dp"
+        android:color="@color/accessibility_focus_highlight" />
+
+    <corners android:radius="2dp"/>
+
+</shape>
diff --git a/core/res/res/layout-land/keyguard_glow_pad_container.xml b/core/res/res/layout-land/keyguard_glow_pad_container.xml
deleted file mode 100644
index f8364f1..0000000
--- a/core/res/res/layout-land/keyguard_glow_pad_container.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?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.
-*/
--->
-
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-    <include layout="@layout/keyguard_glow_pad_view"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center" />
-</merge>
\ No newline at end of file
diff --git a/core/res/res/layout-land/keyguard_host_view.xml b/core/res/res/layout-land/keyguard_host_view.xml
deleted file mode 100644
index 6b36235..0000000
--- a/core/res/res/layout-land/keyguard_host_view.xml
+++ /dev/null
@@ -1,80 +0,0 @@
-<?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.
-*/
--->
-
-<!-- This is the host view that generally contains two sub views: the widget view
-    and the security view. -->
-<com.android.internal.policy.impl.keyguard.KeyguardHostView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/res/android"
-    android:id="@+id/keyguard_host_view"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="horizontal">
-
-    <com.android.internal.policy.impl.keyguard.MultiPaneChallengeLayout
-        android:id="@+id/multi_pane_challenge"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:clipChildren="false">
-
-        <include layout="@layout/keyguard_widget_remove_drop_target"
-            android:id="@+id/keyguard_widget_pager_delete_target"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="top|center_horizontal"
-            androidprv:layout_childType="pageDeleteDropTarget" />
-
-        <include layout="@layout/keyguard_widget_pager"
-            android:id="@+id/app_widget_container"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            androidprv:layout_centerWithinArea="0.55"
-            androidprv:layout_childType="widget"
-            androidprv:layout_maxWidth="480dp"
-            androidprv:layout_maxHeight="480dp" />
-        <include layout="@layout/keyguard_multi_user_selector"/>
-
-        <View android:layout_width="match_parent"
-              android:layout_height="match_parent"
-              androidprv:layout_childType="scrim"
-              android:background="#99000000" />
-
-        <com.android.internal.policy.impl.keyguard.KeyguardSecurityContainer
-            android:id="@+id/keyguard_security_container"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            androidprv:layout_childType="challenge"
-            androidprv:layout_centerWithinArea="0.55">
-            <com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper
-                android:id="@+id/view_flipper"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:clipChildren="false"
-                android:clipToPadding="false"
-                android:paddingLeft="@dimen/keyguard_security_view_margin"
-                android:paddingTop="@dimen/keyguard_security_view_margin"
-                android:paddingRight="@dimen/keyguard_security_view_margin"
-                android:paddingBottom="@dimen/keyguard_security_view_margin"
-                android:gravity="center">
-            </com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper>
-        </com.android.internal.policy.impl.keyguard.KeyguardSecurityContainer>
-
-    </com.android.internal.policy.impl.keyguard.MultiPaneChallengeLayout>
-</com.android.internal.policy.impl.keyguard.KeyguardHostView>
-
diff --git a/core/res/res/layout-land/keyguard_widget_pager.xml b/core/res/res/layout-land/keyguard_widget_pager.xml
deleted file mode 100644
index 02c6d0e..0000000
--- a/core/res/res/layout-land/keyguard_widget_pager.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?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.
-*/
--->
-
-<!-- This is the selector widget that allows the user to select an action. -->
-<com.android.internal.policy.impl.keyguard.KeyguardWidgetCarousel
-    xmlns:androidprv="http://schemas.android.com/apk/res/android"
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:paddingLeft="25dp"
-    android:paddingRight="25dp"
-    android:paddingTop="25dp"
-    android:paddingBottom="25dp"
-    android:clipToPadding="false"
-    androidprv:pageSpacing="10dp">
-</com.android.internal.policy.impl.keyguard.KeyguardWidgetCarousel>
\ No newline at end of file
diff --git a/core/res/res/layout-port/keyguard_host_view.xml b/core/res/res/layout-port/keyguard_host_view.xml
deleted file mode 100644
index fb25f9c..0000000
--- a/core/res/res/layout-port/keyguard_host_view.xml
+++ /dev/null
@@ -1,94 +0,0 @@
-<?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.
-*/
--->
-
-<!-- This is the host view that generally contains two sub views: the widget view
-    and the security view. -->
-<com.android.internal.policy.impl.keyguard.KeyguardHostView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/res/android"
-    android:id="@+id/keyguard_host_view"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:gravity="center_horizontal"
-    android:orientation="vertical">
-
-    <com.android.internal.policy.impl.keyguard.SlidingChallengeLayout
-        android:id="@+id/sliding_layout"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent">
-
-        <FrameLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            androidprv:layout_childType="pageDeleteDropTarget">
-            <include layout="@layout/keyguard_widget_remove_drop_target"
-                android:id="@+id/keyguard_widget_pager_delete_target"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="top|center_horizontal" />
-        </FrameLayout>
-
-        <FrameLayout
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            androidprv:layout_childType="widgets">
-            <include layout="@layout/keyguard_widget_pager"
-                android:id="@+id/app_widget_container"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:layout_gravity="center"/>
-        </FrameLayout>
-
-        <View android:layout_width="match_parent"
-              android:layout_height="match_parent"
-              androidprv:layout_childType="scrim"
-              android:background="#99000000" />
-
-        <com.android.internal.policy.impl.keyguard.KeyguardSecurityContainer
-            android:id="@+id/keyguard_security_container"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_maxHeight="@dimen/keyguard_security_height"
-            androidprv:layout_childType="challenge"
-            android:padding="0dp"
-            android:gravity="bottom|center_horizontal">
-            <com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper
-                android:id="@+id/view_flipper"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:clipChildren="false"
-                android:clipToPadding="false"
-                android:paddingTop="@dimen/keyguard_security_view_margin"
-                android:gravity="center">
-            </com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper>
-        </com.android.internal.policy.impl.keyguard.KeyguardSecurityContainer>
-
-        <ImageButton
-              android:layout_width="match_parent"
-              android:layout_height="@dimen/kg_widget_pager_bottom_padding"
-              androidprv:layout_childType="expandChallengeHandle"
-              android:focusable="true"
-              android:background="@null"
-              android:src="@drawable/keyguard_expand_challenge_handle"
-              android:scaleType="center"
-              android:contentDescription="@string/keyguard_accessibility_expand_lock_area" />
-
-    </com.android.internal.policy.impl.keyguard.SlidingChallengeLayout>
-</com.android.internal.policy.impl.keyguard.KeyguardHostView>
-
diff --git a/core/res/res/layout-port/keyguard_widget_pager.xml b/core/res/res/layout-port/keyguard_widget_pager.xml
deleted file mode 100644
index 7f22709..0000000
--- a/core/res/res/layout-port/keyguard_widget_pager.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?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.
-*/
--->
-
-<!-- This is the selector widget that allows the user to select an action. -->
-<com.android.internal.policy.impl.keyguard.KeyguardWidgetPager
-    xmlns:androidprv="http://schemas.android.com/apk/res/android"
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/app_widget_container"
-    android:paddingLeft="25dp"
-    android:paddingRight="25dp"
-    android:paddingTop="25dp"
-    android:paddingBottom="@dimen/kg_widget_pager_bottom_padding"
-    android:clipToPadding="false"
-    androidprv:pageSpacing="10dp">
-</com.android.internal.policy.impl.keyguard.KeyguardWidgetPager>
diff --git a/core/res/res/layout-sw600dp-port/keyguard_host_view.xml b/core/res/res/layout-sw600dp-port/keyguard_host_view.xml
deleted file mode 100644
index e3d577d..0000000
--- a/core/res/res/layout-sw600dp-port/keyguard_host_view.xml
+++ /dev/null
@@ -1,82 +0,0 @@
-<?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.
-*/
--->
-
-<!-- This is the host view that generally contains two sub views: the widget view
-    and the security view. -->
-<com.android.internal.policy.impl.keyguard.KeyguardHostView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/res/android"
-    android:id="@+id/keyguard_host_view"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="horizontal">
-
-    <com.android.internal.policy.impl.keyguard.MultiPaneChallengeLayout
-        android:id="@+id/multi_pane_challenge"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:clipChildren="false"
-        android:orientation="vertical">
-
-        <include layout="@layout/keyguard_widget_remove_drop_target"
-            android:id="@+id/keyguard_widget_pager_delete_target"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="top|center_horizontal"
-            androidprv:layout_childType="pageDeleteDropTarget" />
-
-        <include layout="@layout/keyguard_widget_pager"
-            android:id="@+id/app_widget_container"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            androidprv:layout_centerWithinArea="0.5"
-            androidprv:layout_childType="widget"
-            androidprv:layout_maxWidth="480dp"
-            androidprv:layout_maxHeight="480dp" />
-
-        <include layout="@layout/keyguard_multi_user_selector"/>
-
-        <View android:layout_width="match_parent"
-              android:layout_height="match_parent"
-              androidprv:layout_childType="scrim"
-              android:background="#99000000" />
-
-        <com.android.internal.policy.impl.keyguard.KeyguardSecurityContainer
-            android:id="@+id/keyguard_security_container"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            androidprv:layout_centerWithinArea="0.5"
-            androidprv:layout_childType="challenge"
-            android:layout_gravity="center_horizontal|bottom">
-            <com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper
-                android:id="@+id/view_flipper"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:clipChildren="false"
-                android:clipToPadding="false"
-                android:paddingLeft="@dimen/keyguard_security_view_margin"
-                android:paddingTop="@dimen/keyguard_security_view_margin"
-                android:paddingRight="@dimen/keyguard_security_view_margin"
-                android:paddingBottom="@dimen/keyguard_security_view_margin"
-                android:gravity="center">
-            </com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper>
-        </com.android.internal.policy.impl.keyguard.KeyguardSecurityContainer>
-
-    </com.android.internal.policy.impl.keyguard.MultiPaneChallengeLayout>
-</com.android.internal.policy.impl.keyguard.KeyguardHostView>
diff --git a/core/res/res/layout-sw600dp-port/keyguard_status_area.xml b/core/res/res/layout-sw600dp-port/keyguard_status_area.xml
deleted file mode 100644
index 88dd760..0000000
--- a/core/res/res/layout-sw600dp-port/keyguard_status_area.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License")
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<!-- This is a view that shows general status information in Keyguard. -->
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/keyguard_status_area"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:layout_gravity="end"
-    android:layout_marginTop="-16dp"
-    android:orientation="vertical">
-
-    <TextView
-        android:id="@+id/date"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="end"
-        android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
-        android:singleLine="true"
-        android:ellipsize="marquee"
-        android:textAppearance="?android:attr/textAppearanceMedium"
-        android:textSize="@dimen/kg_status_date_font_size"
-        />
-
-    <TextView
-        android:id="@+id/alarm_status"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="end"
-        android:layout_marginTop="28dp"
-        android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
-        android:singleLine="true"
-        android:ellipsize="marquee"
-        android:textAppearance="?android:attr/textAppearance"
-        android:textSize="@dimen/kg_status_line_font_size"
-        android:drawablePadding="4dip"
-        />
-
-</LinearLayout>
diff --git a/core/res/res/layout-sw600dp/keyguard_navigation.xml b/core/res/res/layout-sw600dp/keyguard_navigation.xml
deleted file mode 100644
index 2e6fa37..0000000
--- a/core/res/res/layout-sw600dp/keyguard_navigation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
-*/
--->
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-    <include layout="@layout/default_navigation" />
-</merge>
diff --git a/core/res/res/layout-sw600dp/keyguard_sim_puk_pin_navigation.xml b/core/res/res/layout-sw600dp/keyguard_sim_puk_pin_navigation.xml
deleted file mode 100644
index 2e6fa37..0000000
--- a/core/res/res/layout-sw600dp/keyguard_sim_puk_pin_navigation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
-*/
--->
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-    <include layout="@layout/default_navigation" />
-</merge>
diff --git a/core/res/res/layout-sw600dp/keyguard_transport_control.xml b/core/res/res/layout-sw600dp/keyguard_transport_control.xml
deleted file mode 100644
index f864339..0000000
--- a/core/res/res/layout-sw600dp/keyguard_transport_control.xml
+++ /dev/null
@@ -1,111 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<!-- *** Note *** This should mirror the file in layout/ with the exception of the background set
-     here for adding a drop shadow on tablets. -->
-
-<com.android.internal.widget.TransportControlView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/transport_controls"
-    android:background="@drawable/transportcontrol_bg">
-
-    <!-- FrameLayout used as scrim to show between album art and buttons -->
-    <FrameLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:foreground="@drawable/ic_lockscreen_player_background">
-        <!-- We use ImageView for its cropping features, otherwise could be android:background -->
-        <ImageView
-            android:id="@+id/albumart"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layout_gravity="fill"
-            android:scaleType="centerCrop"
-            android:adjustViewBounds="false"
-        />
-    </FrameLayout>
-
-    <LinearLayout
-        android:orientation="vertical"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_gravity="bottom">
-        <TextView
-            android:id="@+id/title"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="8dip"
-            android:layout_marginStart="16dip"
-            android:layout_marginEnd="16dip"
-            android:gravity="center_horizontal"
-            android:singleLine="true"
-            android:ellipsize="end"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-        />
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="horizontal"
-            android:layout_marginTop="5dip">
-            <FrameLayout
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_weight="1">
-                <ImageView
-                    android:id="@+id/btn_prev"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_gravity="center"
-                    android:src="@drawable/ic_media_previous"
-                    android:clickable="true"
-                    android:background="?android:attr/selectableItemBackground"
-                    android:padding="10dip"
-                    android:contentDescription="@string/lockscreen_transport_prev_description"/>
-            </FrameLayout>
-            <FrameLayout
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_weight="1">
-                <ImageView
-                    android:id="@+id/btn_play"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_gravity="center"
-                    android:clickable="true"
-                    android:src="@drawable/ic_media_play"
-                    android:background="?android:attr/selectableItemBackground"
-                    android:padding="10dip"
-                    android:contentDescription="@string/lockscreen_transport_play_description"/>
-            </FrameLayout>
-            <FrameLayout
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_weight="1">
-                <ImageView
-                    android:id="@+id/btn_next"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_gravity="center"
-                    android:clickable="true"
-                    android:src="@drawable/ic_media_next"
-                    android:background="?android:attr/selectableItemBackground"
-                    android:padding="10dip"
-                    android:contentDescription="@string/lockscreen_transport_next_description"/>
-            </FrameLayout>
-        </LinearLayout>
-    </LinearLayout>
-
-</com.android.internal.widget.TransportControlView>
diff --git a/core/res/res/layout-xlarge/screen_action_bar.xml b/core/res/res/layout-xlarge/screen_action_bar.xml
index 4f286780..e495e53 100644
--- a/core/res/res/layout-xlarge/screen_action_bar.xml
+++ b/core/res/res/layout-xlarge/screen_action_bar.xml
@@ -28,30 +28,23 @@
     <FrameLayout android:id="@android:id/content"
         android:layout_width="match_parent"
         android:layout_height="match_parent" />
-    <LinearLayout android:id="@+id/top_action_bar"
-                  android:layout_width="match_parent"
-                  android:layout_height="wrap_content">
-        <com.android.internal.widget.ActionBarContainer android:id="@+id/action_bar_container"
+    <com.android.internal.widget.ActionBarContainer
+        android:id="@+id/action_bar_container"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentTop="true"
+        style="?android:attr/actionBarStyle"
+        android:gravity="top">
+        <com.android.internal.widget.ActionBarView
+            android:id="@+id/action_bar"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_alignParentTop="true"
-            style="?android:attr/actionBarStyle"
-            android:gravity="top">
-            <com.android.internal.widget.ActionBarView
-                android:id="@+id/action_bar"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                style="?android:attr/actionBarStyle" />
-            <com.android.internal.widget.ActionBarContextView
-                android:id="@+id/action_context_bar"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:visibility="gone"
-                style="?android:attr/actionModeStyle" />
-        </com.android.internal.widget.ActionBarContainer>
-        <ImageView android:src="?android:attr/windowContentOverlay"
-                   android:scaleType="fitXY"
-                   android:layout_width="match_parent"
-                   android:layout_height="wrap_content" />
-    </LinearLayout>
+            style="?android:attr/actionBarStyle" />
+        <com.android.internal.widget.ActionBarContextView
+            android:id="@+id/action_context_bar"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:visibility="gone"
+            style="?android:attr/actionModeStyle" />
+    </com.android.internal.widget.ActionBarContainer>
 </com.android.internal.widget.ActionBarOverlayLayout>
diff --git a/core/res/res/layout/action_bar_title_item.xml b/core/res/res/layout/action_bar_title_item.xml
index ccc5b07..fecfded 100644
--- a/core/res/res/layout/action_bar_title_item.xml
+++ b/core/res/res/layout/action_bar_title_item.xml
@@ -16,33 +16,20 @@
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
               android:layout_width="wrap_content"
-              android:layout_height="match_parent"
-              android:orientation="horizontal"
-              android:paddingEnd="8dip"
-              android:enabled="false">
-
-    <ImageView android:id="@android:id/up"
-               android:src="?android:attr/homeAsUpIndicator"
-               android:layout_gravity="center_vertical|start"
-               android:visibility="gone"
-               android:layout_width="wrap_content"
-               android:layout_height="wrap_content" />
-
-    <LinearLayout android:layout_width="wrap_content"
-                  android:layout_height="wrap_content"
-                  android:layout_gravity="center_vertical|start"
-                  android:orientation="vertical">
-        <TextView android:id="@+id/action_bar_title"
-                  android:layout_width="wrap_content"
-                  android:layout_height="wrap_content"
-                  android:singleLine="true"
-                  android:ellipsize="end" />
-        <TextView android:id="@+id/action_bar_subtitle"
-                  android:layout_width="wrap_content"
-                  android:layout_height="wrap_content"
-                  android:layout_marginTop="@dimen/action_bar_subtitle_top_margin"
-                  android:singleLine="true"
-                  android:ellipsize="end"
-                  android:visibility="gone" />
-    </LinearLayout>
+              android:layout_height="wrap_content"
+              android:layout_gravity="center_vertical|start"
+              android:orientation="vertical"
+              android:paddingEnd="8dp">
+    <TextView android:id="@+id/action_bar_title"
+              android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:singleLine="true"
+              android:ellipsize="end" />
+    <TextView android:id="@+id/action_bar_subtitle"
+              android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:layout_marginTop="@dimen/action_bar_subtitle_top_margin"
+              android:singleLine="true"
+              android:ellipsize="end"
+              android:visibility="gone" />
 </LinearLayout>
diff --git a/core/res/res/layout/keyguard_account_view.xml b/core/res/res/layout/keyguard_account_view.xml
deleted file mode 100644
index fa36371..0000000
--- a/core/res/res/layout/keyguard_account_view.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?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.
-*/
--->
-<com.android.internal.policy.impl.keyguard.KeyguardAccountView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/keyguard_account_view"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_maxWidth="@dimen/keyguard_security_width"
-    android:layout_maxHeight="@dimen/keyguard_security_height"
-    android:orientation="vertical">
-
-    <include layout="@layout/keyguard_message_area"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content" />
-
-    <RelativeLayout
-        android:layout_width="match_parent"
-        android:layout_height="0dip"
-        android:layout_weight="1">
-
-        <EditText
-            android:id="@+id/login"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="8dip"
-            android:layout_marginStart="7dip"
-            android:layout_marginEnd="7dip"
-            android:layout_alignParentTop="true"
-            android:hint="@string/kg_login_username_hint"
-            android:inputType="textEmailAddress"
-            />
-
-        <EditText
-            android:id="@+id/password"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_below="@id/login"
-            android:layout_toLeftOf="@+id/ok"
-            android:layout_marginTop="15dip"
-            android:layout_marginStart="7dip"
-            android:layout_marginEnd="7dip"
-            android:inputType="textPassword"
-            android:hint="@string/kg_login_password_hint"
-            android:nextFocusRight="@+id/ok"
-            android:nextFocusDown="@+id/ok"
-            />
-
-        <!-- ok below password, aligned to right of screen -->
-        <Button
-            android:id="@+id/ok"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_margin="7dip"
-            android:layout_alignParentEnd="true"
-            android:layout_below="@id/login"
-            android:text="@string/kg_login_submit_button"
-            />
-
-    </RelativeLayout>
-
-    <!--  no room for ECA on this screen right now
-    <include layout="@layout/keyguard_eca"
-        android:id="@+id/keyguard_selector_fade_container"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="vertical"
-        android:layout_gravity="bottom|center_horizontal"
-        android:gravity="center_horizontal" />
-    -->
-
-</com.android.internal.policy.impl.keyguard.KeyguardAccountView>
diff --git a/core/res/res/layout/keyguard_add_widget.xml b/core/res/res/layout/keyguard_add_widget.xml
deleted file mode 100644
index d043fdb..0000000
--- a/core/res/res/layout/keyguard_add_widget.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License")
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<!-- This is a view that shows general status information in Keyguard. -->
-<com.android.internal.policy.impl.keyguard.KeyguardWidgetFrame
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/keyguard_add_widget"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    >
-    <FrameLayout
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:contentDescription="@string/keyguard_accessibility_widget_empty_slot"
-            >
-        <ImageView
-            android:id="@+id/keyguard_add_widget_view"
-            android:clickable="true"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center"
-            android:padding="24dp"
-            android:src="@drawable/keyguard_add_widget_button"
-            android:contentDescription="@string/keyguard_accessibility_add_widget"/>
-    </FrameLayout>
-</com.android.internal.policy.impl.keyguard.KeyguardWidgetFrame>
diff --git a/core/res/res/layout/keyguard_emergency_carrier_area.xml b/core/res/res/layout/keyguard_emergency_carrier_area.xml
deleted file mode 100644
index b8a7654..0000000
--- a/core/res/res/layout/keyguard_emergency_carrier_area.xml
+++ /dev/null
@@ -1,76 +0,0 @@
-<?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.
-*/
--->
-
-<!-- This contains emergency call button and carrier as shared by pin/pattern/password screens -->
-<com.android.internal.policy.impl.keyguard.EmergencyCarrierArea
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:orientation="vertical"
-    android:gravity="center"
-    android:layout_gravity="center_horizontal"
-    android:layout_alignParentBottom="true"
-    android:clickable="true">
-
-    <com.android.internal.policy.impl.keyguard.CarrierText
-        android:id="@+id/carrier_text"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:singleLine="true"
-        android:ellipsize="marquee"
-        android:textAppearance="?android:attr/textAppearanceMedium"
-        android:textSize="@dimen/kg_status_line_font_size"
-        android:textColor="?android:attr/textColorSecondary"/>
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="-10dip"
-        style="?android:attr/buttonBarStyle"
-        android:orientation="horizontal"
-        android:gravity="center"
-        android:weightSum="2">
-
-        <com.android.internal.policy.impl.keyguard.EmergencyButton
-            android:id="@+id/emergency_call_button"
-            android:layout_width="0dip"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:drawableLeft="@*android:drawable/lockscreen_emergency_button"
-            android:text="@string/kg_emergency_call_label"
-            style="?android:attr/buttonBarButtonStyle"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:textSize="@dimen/kg_status_line_font_size"
-            android:textColor="?android:attr/textColorSecondary"
-            android:drawablePadding="8dip" />
-
-        <Button android:id="@+id/forgot_password_button"
-            android:layout_width="0dip"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:drawableLeft="@*android:drawable/lockscreen_forgot_password_button"
-            style="?android:attr/buttonBarButtonStyle"
-            android:textSize="@dimen/kg_status_line_font_size"
-            android:textColor="?android:attr/textColorSecondary"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:drawablePadding="8dip"
-            android:visibility="gone"/>
-    </LinearLayout>
-
-</com.android.internal.policy.impl.keyguard.EmergencyCarrierArea>
diff --git a/core/res/res/layout/keyguard_face_unlock_view.xml b/core/res/res/layout/keyguard_face_unlock_view.xml
deleted file mode 100644
index c9f1176..0000000
--- a/core/res/res/layout/keyguard_face_unlock_view.xml
+++ /dev/null
@@ -1,78 +0,0 @@
-<?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.
-*/
--->
-
-<!-- This is the screen that allows the user to unlock by showing their face.  -->
-<com.android.internal.policy.impl.keyguard.KeyguardFaceUnlockView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/keyguard_face_unlock_view"
-    android:orientation="vertical"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_maxWidth="@dimen/keyguard_security_width"
-    android:layout_maxHeight="@dimen/keyguard_security_height"
-    android:contentDescription="@string/keyguard_accessibility_face_unlock">
-
-    <include layout="@layout/keyguard_message_area"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        />
-
-    <FrameLayout
-       android:id="@+id/keyguard_bouncer_frame"
-       android:background="@*android:drawable/kg_bouncer_bg_white"
-       android:layout_width="match_parent"
-       android:layout_height="0dp"
-       android:layout_weight="1"
-       >
-       <com.android.internal.widget.FaceUnlockView
-           android:id="@+id/face_unlock_area_view"
-           android:layout_width="match_parent"
-           android:layout_height="match_parent"
-           android:layout_gravity="center_horizontal"
-           android:background="@*android:drawable/intro_bg"
-           android:gravity="center">
-
-           <View
-               android:id="@+id/spotlightMask"
-               android:layout_width="match_parent"
-               android:layout_height="match_parent"
-               android:background="@*android:color/facelock_spotlight_mask"
-           />
-
-           <ImageButton
-               android:id="@+id/face_unlock_cancel_button"
-               android:layout_width="wrap_content"
-               android:layout_height="wrap_content"
-               android:padding="5dip"
-               android:layout_alignParentTop="true"
-               android:layout_alignParentEnd="true"
-               android:background="#00000000"
-               android:src="@*android:drawable/ic_facial_backup"
-           />
-       </com.android.internal.widget.FaceUnlockView>
-    </FrameLayout>
-
-    <include layout="@layout/keyguard_eca"
-        android:id="@+id/keyguard_selector_fade_container"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="vertical"
-        android:layout_gravity="bottom|center_horizontal"
-        android:gravity="center_horizontal" />
-</com.android.internal.policy.impl.keyguard.KeyguardFaceUnlockView>
diff --git a/core/res/res/layout/keyguard_glow_pad_container.xml b/core/res/res/layout/keyguard_glow_pad_container.xml
deleted file mode 100644
index d86707f..0000000
--- a/core/res/res/layout/keyguard_glow_pad_container.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?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.
-*/
--->
-
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-    <include layout="@layout/keyguard_glow_pad_view"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="bottom|center_horizontal"
-        android:layout_marginBottom="-60dp"/>
-</merge>
\ No newline at end of file
diff --git a/core/res/res/layout/keyguard_glow_pad_view.xml b/core/res/res/layout/keyguard_glow_pad_view.xml
deleted file mode 100644
index cfd8160..0000000
--- a/core/res/res/layout/keyguard_glow_pad_view.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?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.
-*/
--->
-
-<!-- This is the selector widget that allows the user to select an action. -->
-<com.android.internal.widget.multiwaveview.GlowPadView
-    xmlns:prvandroid="http://schemas.android.com/apk/prv/res/android"
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/glow_pad_view"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:layout_gravity="center"
-    android:orientation="horizontal"
-    android:gravity="@integer/kg_selector_gravity"
-    android:contentDescription="@string/keyguard_accessibility_slide_area"
-
-    prvandroid:targetDrawables="@array/lockscreen_targets_unlock_only"
-    prvandroid:targetDescriptions="@array/lockscreen_target_descriptions_unlock_only"
-    prvandroid:directionDescriptions="@*android:array/lockscreen_direction_descriptions"
-    prvandroid:handleDrawable="@*android:drawable/ic_lockscreen_handle"
-    prvandroid:outerRingDrawable="@*android:drawable/ic_lockscreen_outerring"
-    prvandroid:outerRadius="@*android:dimen/glowpadview_target_placement_radius"
-    prvandroid:innerRadius="@*android:dimen/glowpadview_inner_radius"
-    prvandroid:snapMargin="@*android:dimen/glowpadview_snap_margin"
-    prvandroid:firstItemOffset="@integer/kg_glowpad_rotation_offset"
-    prvandroid:magneticTargets="true"
-    prvandroid:feedbackCount="1"
-    prvandroid:vibrationDuration="20"
-    prvandroid:glowRadius="@*android:dimen/glowpadview_glow_radius"
-    prvandroid:pointDrawable="@*android:drawable/ic_lockscreen_glowdot"
-    prvandroid:allowScaling="true" />
diff --git a/core/res/res/layout/keyguard_message_area.xml b/core/res/res/layout/keyguard_message_area.xml
deleted file mode 100644
index 37463cf..0000000
--- a/core/res/res/layout/keyguard_message_area.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?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.
-*/
--->
-
-<!-- This contains emergency call button and carrier as shared by pin/pattern/password screens -->
-<com.android.internal.policy.impl.keyguard.KeyguardMessageArea
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:gravity="center"
-    android:id="@+id/keyguard_message_area"
-    android:singleLine="true"
-    android:ellipsize="marquee"
-    android:textAppearance="?android:attr/textAppearance"
-    android:textSize="@dimen/kg_status_line_font_size"
-    android:textColor="?android:attr/textColorSecondary"
-    android:clickable="true" />
-
diff --git a/core/res/res/layout/keyguard_message_area_large.xml b/core/res/res/layout/keyguard_message_area_large.xml
deleted file mode 100644
index 584cec4..0000000
--- a/core/res/res/layout/keyguard_message_area_large.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?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.
-*/
--->
-
-<!-- This contains emergency call button and carrier as shared by pin/pattern/password screens -->
-<com.android.internal.policy.impl.keyguard.KeyguardMessageArea
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:gravity="center"
-    android:id="@+id/keyguard_message_area"
-    android:maxLines="4"
-    android:textAppearance="?android:attr/textAppearance"
-    android:textSize="@dimen/kg_status_line_font_size"
-    android:textColor="?android:attr/textColorSecondary" />
-
diff --git a/core/res/res/layout/keyguard_multi_user_avatar.xml b/core/res/res/layout/keyguard_multi_user_avatar.xml
deleted file mode 100644
index 2d8f02d..0000000
--- a/core/res/res/layout/keyguard_multi_user_avatar.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License")
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<!-- This is a view that shows general status information in Keyguard. -->
-<com.android.internal.policy.impl.keyguard.KeyguardMultiUserAvatar
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="@dimen/keyguard_avatar_size"
-    android:layout_height="@dimen/keyguard_avatar_size"
-    android:background="#00000000"
-    android:gravity="center_horizontal">
-    <ImageView
-        android:id="@+id/keyguard_user_avatar"
-        android:scaleType="center"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_gravity="center"/>
-    <TextView
-       android:id="@+id/keyguard_user_name"
-       android:layout_width="match_parent"
-       android:layout_height="wrap_content"
-       android:layout_gravity="bottom"
-       android:gravity="center"
-       android:textSize="@dimen/keyguard_avatar_name_size"
-       android:textColor="#ffffff"
-       android:singleLine="true"
-       android:ellipsize="end"
-       android:paddingLeft="2dp"
-       android:paddingRight="2dp" />
-</com.android.internal.policy.impl.keyguard.KeyguardMultiUserAvatar>
diff --git a/core/res/res/layout/keyguard_multi_user_selector.xml b/core/res/res/layout/keyguard_multi_user_selector.xml
deleted file mode 100644
index ee01285..0000000
--- a/core/res/res/layout/keyguard_multi_user_selector.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License")
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<com.android.internal.policy.impl.keyguard.KeyguardMultiUserSelectorView
-    xmlns:androidprv="http://schemas.android.com/apk/res/android"
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    androidprv:layout_childType="userSwitcher"
-    android:id="@+id/keyguard_user_selector"
-    android:orientation="horizontal"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:layout_gravity="bottom"
-    android:contentDescription="@*android:string/keyguard_accessibility_user_selector"
-    android:visibility="gone">
-
-    <com.android.internal.policy.impl.keyguard.KeyguardLinearLayout
-        android:id="@+id/keyguard_users_grid"
-        android:orientation="horizontal"
-        android:layout_width="wrap_content"
-        android:layout_marginBottom="@dimen/keyguard_muliuser_selector_margin"
-        android:layout_height="@dimen/keyguard_avatar_size"
-        android:layout_gravity="center|bottom" />
-
-</com.android.internal.policy.impl.keyguard.KeyguardMultiUserSelectorView>
diff --git a/core/res/res/layout/keyguard_multi_user_selector_widget.xml b/core/res/res/layout/keyguard_multi_user_selector_widget.xml
deleted file mode 100644
index fc126fe..0000000
--- a/core/res/res/layout/keyguard_multi_user_selector_widget.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License")
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<!-- This is a view that shows general status information in Keyguard. -->
-<com.android.internal.policy.impl.keyguard.KeyguardWidgetFrame
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/keyguard_multi_user_selector"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
-</com.android.internal.policy.impl.keyguard.KeyguardWidgetFrame>
\ No newline at end of file
diff --git a/core/res/res/layout/keyguard_password_view.xml b/core/res/res/layout/keyguard_password_view.xml
deleted file mode 100644
index aab54c3..0000000
--- a/core/res/res/layout/keyguard_password_view.xml
+++ /dev/null
@@ -1,104 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2008, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License")
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<com.android.internal.policy.impl.keyguard.KeyguardPasswordView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/keyguard_password_view"
-    android:orientation="vertical"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_maxWidth="@dimen/keyguard_security_width"
-    android:layout_maxHeight="@dimen/keyguard_security_height"
-    android:gravity="bottom"
-    android:contentDescription="@string/keyguard_accessibility_password_unlock"
-    >
-
-    <Space
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="1"
-        />
-
-    <include layout="@layout/keyguard_message_area"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content" />
-
-    <!-- Password entry field -->
-    <!-- Note: the entire container is styled to look like the edit field,
-         since the backspace/IME switcher looks better inside -->
-      <FrameLayout
-         android:id="@+id/keyguard_bouncer_frame"
-         android:background="@*android:drawable/kg_bouncer_bg_white"
-         android:layout_height="wrap_content"
-         android:layout_width="match_parent"
-         >
-         <LinearLayout
-             android:layout_height="wrap_content"
-             android:layout_width="match_parent"
-             android:orientation="horizontal"
-             android:background="#70000000"
-             android:layout_marginTop="8dp"
-             android:layout_marginBottom="8dp"
-             >
-
-             <EditText android:id="@+id/passwordEntry"
-                 android:layout_width="0dip"
-                 android:layout_height="wrap_content"
-                 android:layout_weight="1"
-                 android:gravity="center_horizontal"
-                 android:layout_gravity="center_vertical"
-                 android:layout_marginStart="@*android:dimen/keyguard_lockscreen_pin_margin_left"
-                 android:singleLine="true"
-                 android:textStyle="normal"
-                 android:inputType="textPassword"
-                 android:textSize="36sp"
-                 android:background="@null"
-                 android:textAppearance="?android:attr/textAppearanceMedium"
-                 android:textColor="#ffffffff"
-                 android:imeOptions="flagForceAscii|actionDone"
-                 />
-
-             <ImageView android:id="@+id/switch_ime_button"
-                 android:layout_width="wrap_content"
-                 android:layout_height="wrap_content"
-                 android:src="@*android:drawable/ic_lockscreen_ime"
-                 android:clickable="true"
-                 android:padding="8dip"
-                 android:layout_gravity="center"
-                 android:background="?android:attr/selectableItemBackground"
-                 android:visibility="gone"
-                 />
-
-            </LinearLayout>
-       </FrameLayout>
-
-    <Space
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="1"
-        />
-
-    <include layout="@layout/keyguard_eca"
-             android:id="@+id/keyguard_selector_fade_container"
-             android:layout_width="match_parent"
-             android:layout_height="wrap_content"
-             android:orientation="vertical"
-             android:layout_gravity="bottom|center_horizontal"
-             android:gravity="center_horizontal" />
-
-</com.android.internal.policy.impl.keyguard.KeyguardPasswordView>
diff --git a/core/res/res/layout/keyguard_pattern_view.xml b/core/res/res/layout/keyguard_pattern_view.xml
deleted file mode 100644
index 1bd3e4e..0000000
--- a/core/res/res/layout/keyguard_pattern_view.xml
+++ /dev/null
@@ -1,78 +0,0 @@
-<?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.
-*/
--->
-
-<!-- This is the screen that shows the 9 circle unlock widget and instructs
-     the user how to unlock their device, or make an emergency call.  This
-     is the portrait layout.  -->
-<com.android.internal.policy.impl.keyguard.KeyguardPatternView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/keyguard_pattern_view"
-    android:orientation="vertical"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_maxWidth="@dimen/keyguard_security_width"
-    android:layout_maxHeight="@dimen/keyguard_security_height"
-    android:gravity="center_horizontal"
-    android:contentDescription="@string/keyguard_accessibility_pattern_unlock">
-
-    <FrameLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent">
-
-        <LinearLayout
-            android:layout_height="wrap_content"
-            android:layout_width="wrap_content"
-            android:orientation="vertical"
-            android:layout_gravity="center">
-
-            <include layout="@layout/keyguard_message_area"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-               />
-
-          <FrameLayout
-             android:id="@+id/keyguard_bouncer_frame"
-             android:background="@*android:drawable/kg_bouncer_bg_white"
-             android:layout_width="match_parent"
-             android:layout_height="0dp"
-             android:layout_weight="1"
-             >
-            <com.android.internal.widget.LockPatternView
-                android:id="@+id/lockPatternView"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:layout_weight="1"
-                android:layout_marginEnd="8dip"
-                android:layout_marginBottom="4dip"
-                android:layout_marginStart="8dip"
-                android:layout_gravity="center_horizontal"
-                android:gravity="center"
-                android:contentDescription="@string/keyguard_accessibility_pattern_area" />
-          </FrameLayout>
-          <include layout="@layout/keyguard_eca"
-              android:id="@+id/keyguard_selector_fade_container"
-              android:layout_width="match_parent"
-              android:layout_height="wrap_content"
-              android:orientation="vertical"
-              android:layout_gravity="bottom|center_horizontal"
-              android:gravity="center_horizontal" />
-        </LinearLayout>
-    </FrameLayout>
-
-</com.android.internal.policy.impl.keyguard.KeyguardPatternView>
diff --git a/core/res/res/layout/keyguard_pin_view.xml b/core/res/res/layout/keyguard_pin_view.xml
deleted file mode 100644
index 6a3b9e6..0000000
--- a/core/res/res/layout/keyguard_pin_view.xml
+++ /dev/null
@@ -1,224 +0,0 @@
-<?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.
-*/
--->
-
-<com.android.internal.policy.impl.keyguard.KeyguardPINView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/res/android"
-    android:id="@+id/keyguard_pin_view"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_maxWidth="@dimen/keyguard_security_width"
-    android:layout_maxHeight="@dimen/keyguard_security_height"
-    android:orientation="vertical"
-    android:contentDescription="@string/keyguard_accessibility_pin_unlock"
-    >
-    <include layout="@layout/keyguard_message_area"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        />
-    <LinearLayout
-       android:id="@+id/keyguard_bouncer_frame"
-       android:background="@*android:drawable/kg_bouncer_bg_white"
-       android:layout_width="match_parent"
-       android:layout_height="0dp"
-       android:orientation="vertical"
-       android:layout_weight="1"
-       android:layoutDirection="ltr"
-       >
-       <LinearLayout
-          android:layout_width="match_parent"
-          android:layout_height="0dp"
-          android:orientation="horizontal"
-          android:layout_weight="1"
-          >
-          <TextView android:id="@+id/pinEntry"
-               android:editable="true"
-               android:layout_width="0dip"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               android:gravity="center"
-               android:layout_marginStart="@*android:dimen/keyguard_lockscreen_pin_margin_left"
-               android:singleLine="true"
-               android:cursorVisible="false"
-               android:background="@null"
-               android:textAppearance="@style/TextAppearance.NumPadKey"
-               android:imeOptions="flagForceAscii|actionDone"
-               />
-           <ImageButton android:id="@+id/delete_button"
-               android:layout_width="wrap_content"
-               android:layout_height="match_parent"
-               android:gravity="center_vertical"
-               android:src="@*android:drawable/ic_input_delete"
-               android:clickable="true"
-               android:paddingTop="8dip"
-               android:paddingBottom="8dip"
-               android:paddingLeft="24dp"
-               android:paddingRight="24dp"
-               android:background="?android:attr/selectableItemBackground"
-               android:contentDescription="@string/keyboardview_keycode_delete"
-               />
-       </LinearLayout>
-       <View
-           android:layout_width="wrap_content"
-           android:layout_height="1dp"
-           android:background="#55FFFFFF"
-           />
-       <LinearLayout
-           android:layout_width="match_parent"
-           android:layout_height="0dp"
-           android:layout_weight="1"
-           android:orientation="horizontal"
-           >
-           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-               android:id="@+id/key1"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pinEntry"
-               androidprv:digit="1"
-               />
-           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-               android:id="@+id/key2"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pinEntry"
-               androidprv:digit="2"
-               />
-           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-               android:id="@+id/key3"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pinEntry"
-               androidprv:digit="3"
-               />
-       </LinearLayout>
-       <LinearLayout
-           android:layout_width="match_parent"
-           android:layout_height="0dp"
-           android:layout_weight="1"
-           android:orientation="horizontal"
-           >
-           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-               android:id="@+id/key4"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pinEntry"
-               androidprv:digit="4"
-               />
-           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-               android:id="@+id/key5"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pinEntry"
-               androidprv:digit="5"
-               />
-           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-               android:id="@+id/key6"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pinEntry"
-               androidprv:digit="6"
-               />
-       </LinearLayout>
-       <LinearLayout
-           android:layout_width="match_parent"
-           android:layout_height="0dp"
-           android:orientation="horizontal"
-           android:layout_weight="1"
-           >
-           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-               android:id="@+id/key7"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pinEntry"
-               androidprv:digit="7"
-               />
-           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-               android:id="@+id/key8"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pinEntry"
-               androidprv:digit="8"
-               />
-           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-               android:id="@+id/key9"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pinEntry"
-               androidprv:digit="9"
-               />
-       </LinearLayout>
-       <LinearLayout
-           android:layout_width="match_parent"
-           android:layout_height="0dp"
-           android:layout_weight="1"
-           android:orientation="horizontal"
-           >
-           <Space
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               />
-           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-               android:id="@+id/key0"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pinEntry"
-               androidprv:digit="0"
-               />
-           <ImageButton
-               android:id="@+id/key_enter"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               android:paddingRight="30dp"
-               android:src="@drawable/sym_keyboard_return_holo"
-               android:contentDescription="@string/keyboardview_keycode_enter"
-               />
-       </LinearLayout>
-    </LinearLayout>
-    <include layout="@layout/keyguard_eca"
-                   android:id="@+id/keyguard_selector_fade_container"
-                   android:layout_width="match_parent"
-                   android:layout_height="wrap_content"
-                   android:orientation="vertical"
-                   android:layout_gravity="bottom|center_horizontal"
-                   android:gravity="center_horizontal" />
-
-</com.android.internal.policy.impl.keyguard.KeyguardPINView>
diff --git a/core/res/res/layout/keyguard_selector_view.xml b/core/res/res/layout/keyguard_selector_view.xml
deleted file mode 100644
index dfacb6a..0000000
--- a/core/res/res/layout/keyguard_selector_view.xml
+++ /dev/null
@@ -1,64 +0,0 @@
-<?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.
-*/
--->
-
-<!-- This is the selector widget that allows the user to select an action. -->
-<com.android.internal.policy.impl.keyguard.KeyguardSelectorView
-    xmlns:prvandroid="http://schemas.android.com/apk/prv/res/android"
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/keyguard_selector_view"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_maxWidth="420dp"
-    android:layout_maxHeight="@dimen/keyguard_security_height"
-    android:clipChildren="false"
-    android:clipToPadding="false"
-    android:orientation="vertical"
-    android:contentDescription="@string/keyguard_accessibility_slide_unlock">
-
-    <FrameLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_gravity="center"
-        android:clipChildren="false"
-        android:clipToPadding="false"
-        android:gravity="center">
-
-        <include layout="@layout/keyguard_message_area"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content" />
-
-        <View
-            android:id="@+id/keyguard_selector_view_frame"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layout_marginLeft="16dp"
-            android:layout_marginRight="16dp"
-            android:background="@*android:drawable/kg_bouncer_bg_white"/>
-
-        <include layout="@layout/keyguard_glow_pad_container" />
-
-        <include layout="@layout/keyguard_eca"
-            android:id="@+id/keyguard_selector_fade_container"
-            android:layout_width="match_parent"
-            android:layout_height="48dp"
-            android:layout_gravity="bottom|center_horizontal" />
-    </FrameLayout>
-
-</com.android.internal.policy.impl.keyguard.KeyguardSelectorView>
-
diff --git a/core/res/res/layout/keyguard_sim_pin_view.xml b/core/res/res/layout/keyguard_sim_pin_view.xml
deleted file mode 100644
index 6e6fe08..0000000
--- a/core/res/res/layout/keyguard_sim_pin_view.xml
+++ /dev/null
@@ -1,230 +0,0 @@
-<?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.
-*/
--->
-<!-- This is the SIM PIN view that allows the user to enter a SIM PIN to unlock the device. -->
-<com.android.internal.policy.impl.keyguard.KeyguardSimPinView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/res/android"
-    android:id="@+id/keyguard_sim_pin_view"
-    android:orientation="vertical"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_maxWidth="@dimen/keyguard_security_width"
-    android:layout_maxHeight="@dimen/keyguard_security_height"
-    android:gravity="center_horizontal">
-
-    <ImageView
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:src="@drawable/ic_lockscreen_sim"/>
-
-    <include layout="@layout/keyguard_message_area"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        />
-    <LinearLayout
-       android:id="@+id/keyguard_bouncer_frame"
-       android:background="@*android:drawable/kg_bouncer_bg_white"
-       android:layout_width="match_parent"
-       android:layout_height="0dp"
-       android:orientation="vertical"
-       android:layout_weight="1"
-       android:layoutDirection="ltr"
-       >
-       <LinearLayout
-           android:layout_width="match_parent"
-           android:layout_height="0dp"
-           android:orientation="horizontal"
-           android:layout_weight="1"
-           >
-           <TextView android:id="@+id/pinEntry"
-               android:editable="true"
-               android:layout_width="0dip"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               android:gravity="center"
-               android:layout_marginStart="@*android:dimen/keyguard_lockscreen_pin_margin_left"
-               android:singleLine="true"
-               android:cursorVisible="false"
-               android:background="@null"
-               android:textAppearance="@style/TextAppearance.NumPadKey"
-               android:imeOptions="flagForceAscii|actionDone"
-               />
-           <ImageButton android:id="@+id/delete_button"
-               android:layout_width="wrap_content"
-               android:layout_height="match_parent"
-               android:gravity="center_vertical"
-               android:src="@*android:drawable/ic_input_delete"
-               android:clickable="true"
-               android:paddingTop="8dip"
-               android:paddingBottom="8dip"
-               android:paddingLeft="24dp"
-               android:paddingRight="24dp"
-               android:background="?android:attr/selectableItemBackground"
-               android:contentDescription="@string/keyboardview_keycode_delete"
-               />
-       </LinearLayout>
-       <View
-           android:layout_width="wrap_content"
-           android:layout_height="1dp"
-           android:background="#55FFFFFF"
-           />
-       <LinearLayout
-           android:layout_width="match_parent"
-           android:layout_height="0dp"
-           android:layout_weight="1"
-           android:orientation="horizontal"
-           >
-           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-               android:id="@+id/key1"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pinEntry"
-               androidprv:digit="1"
-               />
-           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-               android:id="@+id/key2"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pinEntry"
-               androidprv:digit="2"
-               />
-           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-               android:id="@+id/key3"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pinEntry"
-               androidprv:digit="3"
-               />
-       </LinearLayout>
-       <LinearLayout
-           android:layout_width="match_parent"
-           android:layout_height="0dp"
-           android:layout_weight="1"
-           android:orientation="horizontal"
-           >
-           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-               android:id="@+id/key4"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pinEntry"
-               androidprv:digit="4"
-               />
-           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-               android:id="@+id/key5"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pinEntry"
-               androidprv:digit="5"
-               />
-           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-               android:id="@+id/key6"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pinEntry"
-               androidprv:digit="6"
-               />
-       </LinearLayout>
-       <LinearLayout
-           android:layout_width="match_parent"
-           android:layout_height="0dp"
-           android:orientation="horizontal"
-           android:layout_weight="1"
-           >
-           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-               android:id="@+id/key7"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pinEntry"
-               androidprv:digit="7"
-               />
-           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-               android:id="@+id/key8"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pinEntry"
-               androidprv:digit="8"
-               />
-           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-               android:id="@+id/key9"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pinEntry"
-               androidprv:digit="9"
-               />
-       </LinearLayout>
-       <LinearLayout
-           android:layout_width="match_parent"
-           android:layout_height="0dp"
-           android:layout_weight="1"
-           android:orientation="horizontal"
-           >
-           <Space
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               />
-           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-               android:id="@+id/key0"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pinEntry"
-               androidprv:digit="0"
-               />
-           <ImageButton
-               android:id="@+id/key_enter"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               android:paddingRight="30dp"
-               android:src="@drawable/sym_keyboard_return_holo"
-               android:contentDescription="@string/keyboardview_keycode_enter"
-               />
-       </LinearLayout>
-    </LinearLayout>
-
-    <include layout="@layout/keyguard_eca"
-                   android:id="@+id/keyguard_selector_fade_container"
-                   android:layout_width="match_parent"
-                   android:layout_height="wrap_content"
-                   android:orientation="vertical"
-                   android:layout_gravity="bottom|center_horizontal"
-                   android:gravity="center_horizontal" />
-
-</com.android.internal.policy.impl.keyguard.KeyguardSimPinView>
diff --git a/core/res/res/layout/keyguard_sim_puk_pin_account_navigation.xml b/core/res/res/layout/keyguard_sim_puk_pin_account_navigation.xml
deleted file mode 100644
index 2e6fa37..0000000
--- a/core/res/res/layout/keyguard_sim_puk_pin_account_navigation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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.
-*/
--->
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-    <include layout="@layout/default_navigation" />
-</merge>
diff --git a/core/res/res/layout/keyguard_sim_puk_view.xml b/core/res/res/layout/keyguard_sim_puk_view.xml
deleted file mode 100644
index 0412fdc..0000000
--- a/core/res/res/layout/keyguard_sim_puk_view.xml
+++ /dev/null
@@ -1,230 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2008, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License")
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<!-- This is the SIM PUK view that allows the user to recover their device by entering the
-    carrier-provided PUK code and entering a new SIM PIN for it. -->
-<com.android.internal.policy.impl.keyguard.KeyguardSimPukView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/res/android"
-    android:id="@+id/keyguard_sim_puk_view"
-    android:orientation="vertical"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_maxWidth="@dimen/keyguard_security_width"
-    android:layout_maxHeight="@dimen/keyguard_security_height"
-    android:gravity="center_horizontal">
-
-    <ImageView
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:src="@drawable/ic_lockscreen_sim"/>
-
-    <include layout="@layout/keyguard_message_area"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        />
-    <LinearLayout
-       android:id="@+id/keyguard_bouncer_frame"
-       android:background="@*android:drawable/kg_bouncer_bg_white"
-       android:layout_width="match_parent"
-       android:layout_height="0dp"
-       android:orientation="vertical"
-       android:layout_weight="1"
-       android:layoutDirection="ltr"
-       >
-       <LinearLayout
-           android:layout_width="match_parent"
-           android:layout_height="0dp"
-           android:orientation="horizontal"
-           android:layout_weight="1"
-           >
-           <TextView android:id="@+id/pinEntry"
-               android:editable="true"
-               android:layout_width="0dip"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               android:gravity="center"
-               android:layout_marginStart="@*android:dimen/keyguard_lockscreen_pin_margin_left"
-               android:singleLine="true"
-               android:cursorVisible="false"
-               android:background="@null"
-               android:textAppearance="@style/TextAppearance.NumPadKey"
-               android:imeOptions="flagForceAscii|actionDone"
-               />
-           <ImageButton android:id="@+id/delete_button"
-               android:layout_width="wrap_content"
-               android:layout_height="match_parent"
-               android:gravity="center_vertical"
-               android:src="@*android:drawable/ic_input_delete"
-               android:clickable="true"
-               android:paddingTop="8dip"
-               android:paddingBottom="8dip"
-               android:paddingLeft="24dp"
-               android:paddingRight="24dp"
-               android:background="?android:attr/selectableItemBackground"
-               android:contentDescription="@string/keyboardview_keycode_delete"
-               />
-       </LinearLayout>
-       <View
-           android:layout_width="wrap_content"
-           android:layout_height="1dp"
-           android:background="#55FFFFFF"
-           />
-       <LinearLayout
-           android:layout_width="match_parent"
-           android:layout_height="0dp"
-           android:layout_weight="1"
-           android:orientation="horizontal"
-           >
-           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-               android:id="@+id/key1"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pinEntry"
-               androidprv:digit="1"
-               />
-           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-               android:id="@+id/key2"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pinEntry"
-               androidprv:digit="2"
-               />
-           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-               android:id="@+id/key3"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pinEntry"
-               androidprv:digit="3"
-               />
-       </LinearLayout>
-       <LinearLayout
-           android:layout_width="match_parent"
-           android:layout_height="0dp"
-           android:layout_weight="1"
-           android:orientation="horizontal"
-           >
-           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-               android:id="@+id/key4"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pinEntry"
-               androidprv:digit="4"
-               />
-           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-               android:id="@+id/key5"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pinEntry"
-               androidprv:digit="5"
-               />
-           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-               android:id="@+id/key6"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pinEntry"
-               androidprv:digit="6"
-               />
-       </LinearLayout>
-       <LinearLayout
-           android:layout_width="match_parent"
-           android:layout_height="0dp"
-           android:orientation="horizontal"
-           android:layout_weight="1"
-           >
-           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-               android:id="@+id/key7"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pinEntry"
-               androidprv:digit="7"
-               />
-           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-               android:id="@+id/key8"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pinEntry"
-               androidprv:digit="8"
-               />
-           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-               android:id="@+id/key9"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pinEntry"
-               androidprv:digit="9"
-               />
-       </LinearLayout>
-       <LinearLayout
-           android:layout_width="match_parent"
-           android:layout_height="0dp"
-           android:layout_weight="1"
-           android:orientation="horizontal"
-           >
-           <Space
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               />
-           <view class="com.android.internal.policy.impl.keyguard.NumPadKey"
-               android:id="@+id/key0"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               androidprv:textView="@+id/pinEntry"
-               androidprv:digit="0"
-               />
-           <ImageButton
-               android:id="@+id/key_enter"
-               style="@style/Widget.Button.NumPadKey"
-               android:layout_width="0px"
-               android:layout_height="match_parent"
-               android:layout_weight="1"
-               android:paddingRight="30dp"
-               android:src="@drawable/sym_keyboard_return_holo"
-               android:contentDescription="@string/keyboardview_keycode_enter"
-               />
-       </LinearLayout>
-    </LinearLayout>
-
-    <include layout="@layout/keyguard_eca"
-                   android:id="@+id/keyguard_selector_fade_container"
-                   android:layout_width="match_parent"
-                   android:layout_height="wrap_content"
-                   android:orientation="vertical"
-                   android:layout_gravity="bottom|center_horizontal"
-                   android:gravity="center_horizontal" />
-</com.android.internal.policy.impl.keyguard.KeyguardSimPukView>
diff --git a/core/res/res/layout/keyguard_status_view.xml b/core/res/res/layout/keyguard_status_view.xml
deleted file mode 100644
index 9e36df3..0000000
--- a/core/res/res/layout/keyguard_status_view.xml
+++ /dev/null
@@ -1,67 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License")
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<!-- This is a view that shows general status information in Keyguard. -->
-<com.android.internal.policy.impl.keyguard.KeyguardWidgetFrame
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/keyguard_status_view"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_maxWidth="@dimen/keyguard_security_width"
-    android:layout_maxHeight="@dimen/keyguard_security_height"
-    android:gravity="center_horizontal">
-
-    <com.android.internal.policy.impl.keyguard.KeyguardStatusView
-        android:id="@+id/keyguard_status_view_face_palm"
-        android:orientation="vertical"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:gravity="center_horizontal|top"
-        android:contentDescription="@android:string/keyguard_accessibility_status">
-
-        <LinearLayout android:layout_width="match_parent"
-                      android:layout_height="wrap_content"
-                      android:layout_gravity="center_horizontal|top"
-                      android:orientation="vertical"
-                      android:focusable="true">
-            <com.android.internal.policy.impl.keyguard.ClockView
-                android:id="@+id/clock_view"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
-                android:layout_gravity="right">
-
-                <TextView android:id="@+id/clock_text"
-                          android:layout_width="wrap_content"
-                          android:layout_height="wrap_content"
-                          android:singleLine="true"
-                          android:ellipsize="none"
-                          android:textSize="@dimen/kg_status_clock_font_size"
-                          android:textAppearance="?android:attr/textAppearanceMedium"
-                          android:textColor="#ffffffff"
-                          android:drawablePadding="2dip"
-                          />
-
-            </com.android.internal.policy.impl.keyguard.ClockView>
-
-            <include layout="@layout/keyguard_status_area" />
-        </LinearLayout>
-
-    </com.android.internal.policy.impl.keyguard.KeyguardStatusView>
-</com.android.internal.policy.impl.keyguard.KeyguardWidgetFrame>
diff --git a/core/res/res/layout/keyguard_transport_control_view.xml b/core/res/res/layout/keyguard_transport_control_view.xml
deleted file mode 100644
index 532322c..0000000
--- a/core/res/res/layout/keyguard_transport_control_view.xml
+++ /dev/null
@@ -1,112 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<!-- This is a view to control music playback in keyguard. -->
-<com.android.internal.policy.impl.keyguard.KeyguardTransportControlView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:gravity="center_horizontal"
-    android:id="@+id/keyguard_transport_control">
-
-    <!-- FrameLayout used as scrim to show between album art and buttons -->
-    <FrameLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:foreground="@*android:drawable/ic_lockscreen_player_background"
-        android:contentDescription="@*android:string/keygaurd_accessibility_media_controls">
-        <!-- Use ImageView for its cropping features; otherwise could be android:background -->
-        <ImageView
-            android:id="@+id/albumart"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layout_gravity="fill"
-            android:scaleType="centerCrop"
-            android:adjustViewBounds="false"
-        />
-    </FrameLayout>
-
-    <LinearLayout
-        android:orientation="vertical"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_gravity="bottom">
-        <TextView
-            android:id="@+id/title"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="8dip"
-            android:layout_marginStart="16dip"
-            android:layout_marginEnd="16dip"
-            android:gravity="center_horizontal"
-            android:singleLine="true"
-            android:ellipsize="end"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-        />
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="horizontal"
-            android:layout_marginTop="5dip">
-            <FrameLayout
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_weight="1">
-                <ImageView
-                    android:id="@+id/btn_prev"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_gravity="center"
-                    android:src="@*android:drawable/ic_media_previous"
-                    android:clickable="true"
-                    android:background="?android:attr/selectableItemBackground"
-                    android:padding="10dip"
-                    android:contentDescription="@*android:string/lockscreen_transport_prev_description"/>
-            </FrameLayout>
-            <FrameLayout
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_weight="1">
-                <ImageView
-                    android:id="@+id/btn_play"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_gravity="center"
-                    android:clickable="true"
-                    android:src="@*android:drawable/ic_media_play"
-                    android:background="?android:attr/selectableItemBackground"
-                    android:padding="10dip"
-                    android:contentDescription="@*android:string/lockscreen_transport_play_description"/>
-            </FrameLayout>
-            <FrameLayout
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_weight="1">
-                <ImageView
-                    android:id="@+id/btn_next"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_gravity="center"
-                    android:clickable="true"
-                    android:src="@*android:drawable/ic_media_next"
-                    android:background="?android:attr/selectableItemBackground"
-                    android:padding="10dip"
-                    android:contentDescription="@*android:string/lockscreen_transport_next_description"/>
-            </FrameLayout>
-        </LinearLayout>
-    </LinearLayout>
-
-</com.android.internal.policy.impl.keyguard.KeyguardTransportControlView>
\ No newline at end of file
diff --git a/core/res/res/layout/preference_list_content.xml b/core/res/res/layout/preference_list_content.xml
index 5812053..02cd8cd 100644
--- a/core/res/res/layout/preference_list_content.xml
+++ b/core/res/res/layout/preference_list_content.xml
@@ -30,24 +30,19 @@
         android:layout_weight="1">
 
         <LinearLayout
+            style="?attr/preferenceHeaderPanelStyle"
             android:id="@+id/headers"
             android:orientation="vertical"
             android:layout_width="0px"
             android:layout_height="match_parent"
-            android:layout_marginEnd="@dimen/preference_screen_side_margin_negative"
-            android:layout_marginStart="@dimen/preference_screen_side_margin"
             android:layout_weight="@integer/preferences_left_pane_weight">
 
             <ListView android:id="@android:id/list"
+                style="?attr/preferenceListStyle"
                 android:layout_width="match_parent"
                 android:layout_height="0px"
                 android:layout_weight="1"
-                android:paddingStart="@dimen/preference_screen_header_padding_side"
-                android:paddingEnd="@dimen/preference_screen_header_padding_side"
-                android:paddingTop="@dimen/preference_screen_header_vertical_padding"
-                android:paddingBottom="@dimen/preference_screen_header_vertical_padding"
                 android:clipToPadding="false"
-                android:scrollbarStyle="@integer/preference_screen_header_scrollbarStyle"
                 android:drawSelectorOnTop="false"
                 android:cacheColorHint="@android:color/transparent"
                 android:listPreferredItemHeight="48dp"
diff --git a/core/res/res/layout/preference_list_fragment.xml b/core/res/res/layout/preference_list_fragment.xml
index abfb1f2..4e895b0 100644
--- a/core/res/res/layout/preference_list_fragment.xml
+++ b/core/res/res/layout/preference_list_fragment.xml
@@ -25,13 +25,12 @@
     android:layout_removeBorders="true">
 
     <ListView android:id="@android:id/list"
+        style="?attr/preferenceFragmentListStyle"
         android:layout_width="match_parent"
         android:layout_height="0px"
         android:layout_weight="1"
         android:paddingTop="0dip"
         android:paddingBottom="@dimen/preference_fragment_padding_bottom"
-        android:paddingStart="@dimen/preference_fragment_padding_side"
-        android:paddingEnd="@dimen/preference_fragment_padding_side"
         android:scrollbarStyle="@integer/preference_fragment_scrollbarStyle"
         android:clipToPadding="false"
         android:drawSelectorOnTop="false"
diff --git a/core/res/res/layout/resolve_list_item.xml b/core/res/res/layout/resolve_list_item.xml
index 61cecae..281541b 100644
--- a/core/res/res/layout/resolve_list_item.xml
+++ b/core/res/res/layout/resolve_list_item.xml
@@ -18,40 +18,40 @@
 */
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:gravity="center"
-              android:orientation="vertical"
+              android:orientation="horizontal"
               android:layout_height="wrap_content"
               android:layout_width="match_parent"
-              android:background="@android:drawable/activity_picker_bg"
-              android:padding="16dp">
-
-    <!-- Extended activity info to distinguish between duplicate activity names -->
-    <TextView android:id="@android:id/text2"
-              android:textAppearance="?android:attr/textAppearance"
-              android:layout_width="wrap_content"
-              android:layout_height="wrap_content"
-              android:gravity="center"
-              android:minLines="2"
-              android:maxLines="2"
-              android:paddingStart="4dip"
-              android:paddingEnd="4dip" />
+              android:background="?attr/activatedBackgroundIndicator">
 
     <!-- Activity icon when presenting dialog
          Size will be filled in by ResolverActivity -->
     <ImageView android:id="@+id/icon"
                android:layout_width="0dp"
                android:layout_height="0dp"
+               android:layout_marginStart="12dp"
+               android:padding="4dp"
                android:scaleType="fitCenter" />
 
-    <!-- Activity name -->
-    <TextView android:id="@android:id/text1"
-              android:textAppearance="?android:attr/textAppearanceSmall"
-              android:layout_width="wrap_content"
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:gravity="start|center_vertical"
+              android:orientation="vertical"
               android:layout_height="wrap_content"
-              android:gravity="center"
-              android:minLines="2"
-              android:maxLines="2"
-              android:paddingStart="4dip"
-              android:paddingEnd="4dip" />
+              android:layout_width="wrap_content"
+              android:layout_gravity="start|center_vertical"
+              android:layout_marginStart="12dp">
+        <!-- Activity name -->
+        <TextView android:id="@android:id/text1"
+                  android:textAppearance="?android:attr/textAppearanceMedium"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:maxLines="2" />
+        <!-- Extended activity info to distinguish between duplicate activity names -->
+        <TextView android:id="@android:id/text2"
+                  android:textAppearance="?android:attr/textAppearanceSmall"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:maxLines="2"
+                  android:paddingTop="4dip" />
+    </LinearLayout>
 </LinearLayout>
 
diff --git a/core/res/res/layout/resolver_grid.xml b/core/res/res/layout/resolver_grid.xml
deleted file mode 100644
index d271c1a..0000000
--- a/core/res/res/layout/resolver_grid.xml
+++ /dev/null
@@ -1,74 +0,0 @@
-<?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.
-*/
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:layout_width="match_parent"
-              android:layout_height="match_parent"
-              android:orientation="vertical"
-              android:divider="?android:attr/dividerHorizontal"
-              android:showDividers="middle"
-              android:dividerPadding="0dip">
-    <FrameLayout android:layout_width="match_parent"
-                 android:layout_height="wrap_content"
-                 android:layout_weight="1">
-        <GridView
-            android:layout_gravity="center"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:id="@+id/resolver_grid"
-            android:numColumns="4"
-            android:columnWidth="128dp"
-            android:padding="16dp"
-            android:clipToPadding="false"
-            android:scrollbarStyle="outsideOverlay" />
-    </FrameLayout>
-    <LinearLayout
-        android:id="@+id/button_bar"
-        android:visibility="gone"
-        style="?android:attr/buttonBarStyle"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:layoutDirection="locale"
-        android:measureWithLargestChild="true">
-        <Button android:id="@+id/button_always"
-                android:layout_width="wrap_content"
-                android:layout_gravity="end"
-                android:layout_weight="1"
-                android:maxLines="2"
-                android:minHeight="@dimen/alert_dialog_button_bar_height"
-                style="?android:attr/buttonBarButtonStyle"
-                android:textSize="14sp"
-                android:layout_height="wrap_content"
-                android:enabled="false"
-                android:text="@string/activity_resolver_use_always"
-                android:onClick="onButtonClick" />
-        <Button android:id="@+id/button_once"
-                android:layout_width="wrap_content"
-                android:layout_gravity="start"
-                android:layout_weight="1"
-                android:maxLines="2"
-                style="?android:attr/buttonBarButtonStyle"
-                android:textSize="14sp"
-                android:minHeight="@dimen/alert_dialog_button_bar_height"
-                android:layout_height="wrap_content"
-                android:enabled="false"
-                android:text="@string/activity_resolver_use_once"
-                android:onClick="onButtonClick" />
-    </LinearLayout>
-</LinearLayout>
\ No newline at end of file
diff --git a/core/res/res/layout/resolver_list.xml b/core/res/res/layout/resolver_list.xml
new file mode 100644
index 0000000..f88ced1
--- /dev/null
+++ b/core/res/res/layout/resolver_list.xml
@@ -0,0 +1,72 @@
+<?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.
+*/
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="vertical"
+              android:divider="?android:attr/dividerHorizontal"
+              android:showDividers="middle"
+              android:dividerPadding="0dip">
+
+    <FrameLayout android:layout_width="match_parent"
+                 android:layout_height="wrap_content"
+                 android:layout_weight="1">
+
+        <ListView
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:id="@+id/resolver_list" />
+
+    </FrameLayout>
+
+    <LinearLayout
+        android:id="@+id/button_bar"
+        android:visibility="gone"
+        style="?android:attr/buttonBarStyle"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:layoutDirection="locale"
+        android:measureWithLargestChild="true">
+        <Button android:id="@+id/button_always"
+                android:layout_width="wrap_content"
+                android:layout_gravity="end"
+                android:layout_weight="1"
+                android:maxLines="2"
+                android:minHeight="@dimen/alert_dialog_button_bar_height"
+                style="?android:attr/buttonBarButtonStyle"
+                android:textSize="14sp"
+                android:layout_height="wrap_content"
+                android:enabled="false"
+                android:text="@string/activity_resolver_use_always"
+                android:onClick="onButtonClick" />
+        <Button android:id="@+id/button_once"
+                android:layout_width="wrap_content"
+                android:layout_gravity="start"
+                android:layout_weight="1"
+                android:maxLines="2"
+                style="?android:attr/buttonBarButtonStyle"
+                android:textSize="14sp"
+                android:minHeight="@dimen/alert_dialog_button_bar_height"
+                android:layout_height="wrap_content"
+                android:enabled="false"
+                android:text="@string/activity_resolver_use_once"
+                android:onClick="onButtonClick" />
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/core/res/res/layout/restrictions_pin_challenge.xml b/core/res/res/layout/restrictions_pin_challenge.xml
new file mode 100644
index 0000000..f41924c
--- /dev/null
+++ b/core/res/res/layout/restrictions_pin_challenge.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Layout used as the dialog's content View for EditTextPreference. -->
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:overScrollMode="ifContentScrolls">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:padding="8dip"
+            android:orientation="vertical">
+
+            <EditText android:id="@+id/pin_text"
+                android:layout_marginLeft="8dip"
+                android:layout_marginStart="8dip"
+                android:layout_marginRight="8dip"
+                android:layout_marginEnd="8dip"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:inputType="numberPassword"
+                android:textColor="?android:attr/textColorPrimary" />
+
+            <TextView android:id="@+id/pin_error_message"
+                android:layout_marginTop="8dp"
+                android:layout_marginBottom="8dp"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/restr_pin_incorrect"
+                android:gravity="center"/>
+        </LinearLayout>
+
+        <LinearLayout android:id="@+id/buttonPanel"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:minHeight="@dimen/alert_dialog_button_bar_height"
+            android:orientation="vertical"
+            android:divider="?android:attr/dividerHorizontal"
+            android:showDividers="beginning"
+            android:dividerPadding="0dip">
+            <LinearLayout
+                style="?android:attr/buttonBarStyle"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal"
+                android:layoutDirection="locale"
+                android:measureWithLargestChild="true">
+                <Button android:id="@+id/pin_cancel_button"
+                    android:layout_width="wrap_content"
+                    android:layout_gravity="start"
+                    android:layout_weight="1"
+                    android:maxLines="2"
+                    android:minHeight="@dimen/alert_dialog_button_bar_height"
+                    style="?android:attr/buttonBarButtonStyle"
+                    android:textSize="14sp"
+                    android:layout_height="wrap_content"
+                    android:text="@string/cancel" />
+                <Button android:id="@+id/pin_ok_button"
+                    android:layout_width="wrap_content"
+                    android:layout_gravity="end"
+                    android:layout_weight="1"
+                    android:maxLines="2"
+                    style="?android:attr/buttonBarButtonStyle"
+                    android:textSize="14sp"
+                    android:minHeight="@dimen/alert_dialog_button_bar_height"
+                    android:layout_height="wrap_content"
+                    android:text="@string/ok" />
+            </LinearLayout>
+        </LinearLayout>
+    </LinearLayout>
+</ScrollView>
diff --git a/core/res/res/layout/restrictions_pin_setup.xml b/core/res/res/layout/restrictions_pin_setup.xml
new file mode 100644
index 0000000..03ed696
--- /dev/null
+++ b/core/res/res/layout/restrictions_pin_setup.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Layout used as the dialog's content View for EditTextPreference. -->
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:layout_marginTop="48dp"
+    android:layout_marginBottom="48dp"
+    android:overScrollMode="ifContentScrolls">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:padding="8dip"
+        android:orientation="vertical">
+
+        <TextView android:id="@+id/pin_message"
+            style="?android:attr/textAppearanceMedium"
+            android:layout_marginTop="16dp"
+            android:layout_marginBottom="16dp"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/restr_pin_create_pin"
+            android:textColor="?android:attr/textColorSecondary" />
+
+        <EditText android:id="@+id/pin_text"
+            style="?android:attr/textAppearanceMedium"
+            android:layout_marginBottom="16dp"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:hint="@string/restr_pin_enter_old_pin"
+            android:inputType="numberPassword"
+            android:textColor="?android:attr/textColorPrimary" />
+
+        <EditText android:id="@+id/pin_new_text"
+            style="?android:attr/textAppearanceMedium"
+            android:layout_marginBottom="16dp"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:hint="@string/restr_pin_enter_new_pin"
+            android:inputType="numberPassword"
+            android:textColor="?android:attr/textColorPrimary" />
+
+        <EditText android:id="@+id/pin_confirm_text"
+            style="?android:attr/textAppearanceMedium"
+            android:layout_marginBottom="16dp"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:hint="@string/restr_pin_confirm_pin"
+            android:inputType="numberPassword"
+            android:textColor="?android:attr/textColorPrimary" />
+
+        <TextView android:id="@+id/pin_error_message"
+            style="?android:attr/textAppearanceSmall"
+            android:layout_marginBottom="16dp"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/restr_pin_error_doesnt_match"
+            android:textColor="#FFFF0000" />
+
+    </LinearLayout>
+
+</ScrollView>
diff --git a/core/res/res/layout/screen_action_bar.xml b/core/res/res/layout/screen_action_bar.xml
index e310bf5..b1889a2 100644
--- a/core/res/res/layout/screen_action_bar.xml
+++ b/core/res/res/layout/screen_action_bar.xml
@@ -25,34 +25,27 @@
     android:layout_height="match_parent"
     android:splitMotionEvents="false">
     <FrameLayout android:id="@android:id/content"
+                 android:layout_width="match_parent"
+                 android:layout_height="match_parent" />
+    <com.android.internal.widget.ActionBarContainer
+        android:id="@+id/action_bar_container"
         android:layout_width="match_parent"
-        android:layout_height="match_parent" />
-    <LinearLayout android:id="@+id/top_action_bar"
-                  android:layout_width="match_parent"
-                  android:layout_height="wrap_content">
-        <com.android.internal.widget.ActionBarContainer android:id="@+id/action_bar_container"
+        android:layout_height="wrap_content"
+        android:layout_alignParentTop="true"
+        style="?android:attr/actionBarStyle"
+        android:gravity="top">
+        <com.android.internal.widget.ActionBarView
+            android:id="@+id/action_bar"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_alignParentTop="true"
-            style="?android:attr/actionBarStyle"
-            android:gravity="top">
-            <com.android.internal.widget.ActionBarView
-                android:id="@+id/action_bar"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                style="?android:attr/actionBarStyle" />
-            <com.android.internal.widget.ActionBarContextView
-                android:id="@+id/action_context_bar"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:visibility="gone"
-                style="?android:attr/actionModeStyle" />
-        </com.android.internal.widget.ActionBarContainer>
-        <ImageView android:src="?android:attr/windowContentOverlay"
-                   android:scaleType="fitXY"
-                   android:layout_width="match_parent"
-                   android:layout_height="wrap_content" />
-    </LinearLayout>
+            style="?android:attr/actionBarStyle" />
+        <com.android.internal.widget.ActionBarContextView
+            android:id="@+id/action_context_bar"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:visibility="gone"
+            style="?android:attr/actionModeStyle" />
+    </com.android.internal.widget.ActionBarContainer>
     <com.android.internal.widget.ActionBarContainer android:id="@+id/split_action_bar"
                   android:layout_width="match_parent"
                   android:layout_height="wrap_content"
diff --git a/core/res/res/layout/simple_list_item_2.xml b/core/res/res/layout/simple_list_item_2.xml
index 8c6c9d3..63c542b 100644
--- a/core/res/res/layout/simple_list_item_2.xml
+++ b/core/res/res/layout/simple_list_item_2.xml
@@ -19,12 +19,13 @@
     android:layout_height="wrap_content"
     android:minHeight="?android:attr/listPreferredItemHeight"
     android:mode="twoLine"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
 >
     
 	<TextView android:id="@android:id/text1"
 		android:layout_width="match_parent"
 		android:layout_height="wrap_content"
-    android:layout_marginStart="?android:attr/listPreferredItemPaddingStart"
     android:layout_marginTop="8dip"
 		android:textAppearance="?android:attr/textAppearanceListItem"
 	/>
diff --git a/core/res/res/layout/time_picker.xml b/core/res/res/layout/time_picker.xml
index a78cd85..4fa94f3 100644
--- a/core/res/res/layout/time_picker.xml
+++ b/core/res/res/layout/time_picker.xml
@@ -20,6 +20,7 @@
 <!-- Layout of time picker-->
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/timePickerLayout"
     android:orientation="horizontal"
     android:layout_gravity="center_horizontal"
     android:layout_width="wrap_content"
diff --git a/core/res/res/layout/time_picker_holo.xml b/core/res/res/layout/time_picker_holo.xml
index 7d8900e..c6b7d3a 100644
--- a/core/res/res/layout/time_picker_holo.xml
+++ b/core/res/res/layout/time_picker_holo.xml
@@ -20,14 +20,19 @@
 <!-- Layout of time picker -->
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/timePickerLayout"
     android:orientation="horizontal"
     android:layout_gravity="center_horizontal"
     android:layout_width="wrap_content"
-    android:layout_height="wrap_content">
+    android:layout_height="wrap_content"
+    android:paddingStart="8dip"
+    android:paddingEnd="8dip">
 
     <LinearLayout android:orientation="horizontal"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:paddingStart="8dip"
+        android:paddingEnd="8dip"
         android:layoutDirection="ltr">
 
         <!-- hour -->
@@ -37,8 +42,6 @@
             android:layout_height="wrap_content"
             android:layout_marginTop="16dip"
             android:layout_marginBottom="16dip"
-            android:layout_marginStart="16dip"
-            android:layout_marginEnd="6dip"
             android:focusable="true"
             android:focusableInTouchMode="true"
             />
@@ -48,6 +51,8 @@
             android:id="@+id/divider"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:layout_marginStart="6dip"
+            android:layout_marginEnd="6dip"
             android:layout_gravity="center_vertical"
             android:importantForAccessibility="no"
             />
@@ -59,8 +64,6 @@
             android:layout_height="wrap_content"
             android:layout_marginTop="16dip"
             android:layout_marginBottom="16dip"
-            android:layout_marginStart="6dip"
-            android:layout_marginEnd="8dip"
             android:focusable="true"
             android:focusableInTouchMode="true"
             />
@@ -75,7 +78,7 @@
         android:layout_marginTop="16dip"
         android:layout_marginBottom="16dip"
         android:layout_marginStart="8dip"
-        android:layout_marginEnd="16dip"
+        android:layout_marginEnd="8dip"
         android:focusable="true"
         android:focusableInTouchMode="true"
         />
diff --git a/core/res/res/layout/toast_bar.xml b/core/res/res/layout/toast_bar.xml
new file mode 100644
index 0000000..b7443d5
--- /dev/null
+++ b/core/res/res/layout/toast_bar.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <LinearLayout
+        android:background="@drawable/toast_bar_bg"
+        android:layout_height="50dp"
+        android:layout_width="match_parent">
+
+        <TextView
+            android:id="@android:id/message"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:ellipsize="end"
+            android:gravity="center_vertical"
+            android:paddingLeft="16dp"
+            android:paddingRight="16dp"
+            android:singleLine="true"
+            android:textColor="@android:color/white"
+            android:textSize="16sp" />
+
+        <LinearLayout
+            android:id="@android:id/button1"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:background="?android:attr/selectableItemBackground"
+            android:clickable="true">
+
+            <View
+                android:layout_width="1dp"
+                android:layout_height="match_parent"
+                android:layout_marginBottom="10dp"
+                android:layout_marginRight="12dp"
+                android:layout_marginTop="10dp"
+                android:background="#aaaaaa" />
+
+            <TextView
+                android:id="@android:id/text1"
+                android:textSize="12sp"
+                android:textColor="#aaaaaa"
+                android:textStyle="bold"
+                android:layout_width="wrap_content"
+                android:layout_height="match_parent"
+                android:gravity="center_vertical"
+                android:paddingLeft="8dp"
+                android:paddingRight="20dp"
+                android:textAllCaps="true" />
+        </LinearLayout>
+
+    </LinearLayout>
+
+</FrameLayout>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 405a978..839f3e3 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -131,6 +131,11 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Te veel <xliff:g id="CONTENT_TYPE">%s</xliff:g> uitgevee."</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Tablet se berging is vol. Vee \'n aantal lêers uit om spasie vry te maak."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Foon se berging is vol. Vee \'n aantal lêers uit om spasie vry te maak."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Netwerk kan dalk gemonitor word"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Ek"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Tablet-opsies"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Foonopsies"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Laat die program toe om take na die voorgrond of agtergrond te skuif. Die program kan dit moontlik sonder jou insette doen."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"stop lopende programme"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Laat die program toe om take te verwyder en hul programme te dood. Kwaadwillige programme kan die gedrag van ander programme ontwrig."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"bestuur aktiwiteitstapels"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Laat die program toe om by te voeg by die aktiwiteitstapels waarbinne ander programme loop, of dit te verwyder of te wysig. Kwaadwillige programme kan dalk die gedrag van ander programme ontwrig."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"begin enige aktiwiteit"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Laat die program toe om \'n aktiwiteit te begin, ongeag toestemming-beskerming of uitgevoerde status."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"stel skermversoenbaarheid"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Dit laat die houer toe om aan die topvlak-koppelvlak van \'n invoermetode te bind. Dit moet nooit vir normale programme nodig wees nie."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"verbind aan \'n toeganklikheidsdiens"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Dit laat die houer toe om aan die top-koppelvlak van \'n toeganklikheidsdiens te verbind. Behoort nooit vir gewone programme nodig te wees nie."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"verbind aan \'n drukdiens"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Laat die houer toe om aan die top-koppelvlak van \'n drukdiens te verbind. Behoort nooit vir gewone programme nodig te wees nie."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"verbind aan \'n drukdatabufferdiens"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Laat die houer toe om aan die top-koppelvlak van \'n drukdatabufferdiens te verbind. Behoort nooit vir gewone programme nodig te wees nie."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"verbind aan NFC-diens"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Laat die houer toe om te verbind aan programme wat NFC-kaarte nastrewe. Behoort nooit vir normale programme nodig te wees nie."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"bind aan \'n teksdiens"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Dit laat die houer toe om aan die topvlak-koppelvlak van \'n teksdiens (bv SpellCheckerService) te bind. Dit moet nooit vir normale programme nodig wees nie."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"bind aan \'n VPN-diens"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Dit laat die houer toe om aan die topvlak-koppelvlak van \'n legstuk-diens te bind. Dit moet nooit vir normale programme nodig wees nie."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"skakel met \'n toestel-admin"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Laat die houer toe om bedoelings na \'n toesteladministrateur te stuur. Dit moet nooit vir normale programme nodig wees nie."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"voeg \'n toesteladministrateur by of verwyder een"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Laat die houer aktiewe toesteladministrateurs byvoeg of verwyder. Behoort nooit nodig te wees vir normale programme nie."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"verander skermoriëntasie"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Laat die program toe om die skerm se rotasie te eniger tyd te verander. Dit moet nooit vir normale programme nodig wees nie."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"verander wyserspoed"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Laat die program toe om uit die stelsel se verskeie loglêers te lees. Dit laat \'n program toe om algemene inligting te ontdek oor wat jy met die foon doen, wat moontlik persoonlike of private inligting kan insluit."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"gebruik enige mediadekodeerder vir terugspeel"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Laat die program toe om enige geïnstalleer mediadekodeerder te gebruik om te kan dekodeer vir terugspeel."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"bestuur vertroude eiebewyse"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Laat die program CA-sertifikate as vertroude eiebewyse installeer en deïnstalleer."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"lees/skryf na bronne wat diag besit"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Laat die program toe om na enige hulpbron wat deur die diag-groep besit word, te skryf, byvoorbeeld lêers in /dev. Dit kan potensieel stelselstabiliteit en sekuriteit affekteer. Dit moet NET gebruik word vir hardewarespesifieke diagnose deur die vervaardiger of operateur."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"aktiveer of deaktiveer programkomponente"</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Laat die program toe om Wi-Fi-skerms op te stel en daaraan te koppel."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"beheer Wi-Fi-skerms"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Laat die program toe om laevlak-kenmerke van Wi-Fi-skerms te beheer."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"vang oudio-uitset vas"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Laat die program oudio-uitset vasvang en herlei."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"vang video-uitset vas"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Laat die program video-uitset vasvang en herlei."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"vang veilige video-uitset vas"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Laat die program veilige video-uitset vasvang en herlei."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"verander jou klankinstellings"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Laat die program toe om globale klankinstellings soos volume en watter luidspreker vir uitvoer gebruik word, te verander."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"neem klank op"</string>
@@ -525,6 +552,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"verhoed foon om te slaap"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Laat die program toe om die tablet te keer om te slaap."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Laat die program toe om die foon te keer om te slaap."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"skakel tablet aan of af"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"Sit foon aan of af"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Laat die program toe om die tablet aan en af te skakel."</string>
@@ -613,6 +646,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Laat die program toe om na die SD-kaart te skryf."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"verander/vee uit interne mediabergingsinhoud"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Laat die program toe om die inhoud van die interne mediaberging te verander."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"bestuur dokumentberging"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Laat die program toe om dokumentberging te bestuur."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"verkry toegang tot alle gebruikers se eksterne berging"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Laat die program toe om toegang tot eksterne berging vir alle gebruikers te verkry."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"lees die kaslêerstelsel"</string>
@@ -625,10 +660,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Laat die program toe om netwerkbeleide te bestuur en program-spesifieke reëls te definieer."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"verander verrekening van netwerkgebruik"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Laat die program toe om te verander hoe netwerkgebruik teenoor programme gemeet word. Nie vir gebruik deur normale programme nie."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"wysig sokmerke"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Laat die program toe om sokmerke vir roetering te wysig"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"kry toegang tot kennisgewings"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Laat die program toe om kennisgewings op te haal, te bestudeer en te verwyder, insluitende die kennisgewings wat deur ander programme geplaas is."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"bind aan \'n kennisgewingluisteraardiens"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Laat die houer toe om aan die top-koppelvlak van \'n kennisgewingluisteraardiens te bind. Behoort nooit vir gewone programme nodig te wees nie."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"roep die opstellingprogram op wat deur die diensverskaffer voorsien is"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Laat die houer toe om die opstellingsprogram wat deur die diensverskaffer voorsien word, op te roep. Behoort nooit vir gewone programme nodig te wees nie."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"luister vir waarnemings oor netwerktoestande"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Laat \'n program luister vir waarnemings oor netwerktoestande. Behoort nooit nodig te wees vir normale programme nie."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Stel wagwoordreëls"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Beheer lengte en watter karakters wat in die skermontsluit-wagwoorde gebruik word."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitor pogings om skerm te ontsluit"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +836,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Steek \'n SIM-kaart in."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Die SIM-kaart is weg of nie leesbaar nie. Steek \'n SIM-kaart in."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Onbruikbare SIM-kaart."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Jou SIM-kaart is permanent gedeaktiveer."\n" Kontak jou draadlose diensverskaffer vir \'n ander SIM-kaart."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Jou SIM-kaart is permanent gedeaktiveer.\n Kontak jou draadlose diensverskaffer vir \'n ander SIM-kaart."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Vorigesnit-knoppie"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Volgendesnit-knoppie"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Laatwag-knoppie"</string>
@@ -808,11 +848,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Sien die handleiding of kontak kliëntediens."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM-kaart is gesluit."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Ontsluit tans SIM-kaart…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerd geteken. "\n\n"Probeer weer oor <xliff:g id="NUMBER_1">%d</xliff:g> sekondes."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Jy het jou wagwoord <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerd ingevoer. "\n\n"Probeer weer oor <xliff:g id="NUMBER_1">%d</xliff:g> sekondes."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Jy het jou wagwoord <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerd ingevoer. "\n\n"Probeer weer oor <xliff:g id="NUMBER_1">%d</xliff:g> sekondes."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerd geteken. Na <xliff:g id="NUMBER_1">%d</xliff:g> nóg onsuksesvolle pogings sal jy gevra word om jou tablet te ontsluit met gebruik van jou Google-aanmelddetails."\n\n" Probeer weer oor <xliff:g id="NUMBER_2">%d</xliff:g> sekondes."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerd geteken. Na nóg <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings sal jy gevra word om jou foon te ontsluit met gebruik van jou Google-aanmelddetails."\n\n" Probeer weer oor <xliff:g id="NUMBER_2">%d</xliff:g> sekondes."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerd geteken. \n\nProbeer weer oor <xliff:g id="NUMBER_1">%d</xliff:g> sekondes."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Jy het jou wagwoord <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerd ingevoer. \n\nProbeer weer oor <xliff:g id="NUMBER_1">%d</xliff:g> sekondes."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Jy het jou wagwoord <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerd ingevoer. \n\nProbeer weer oor <xliff:g id="NUMBER_1">%d</xliff:g> sekondes."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerd geteken. Na <xliff:g id="NUMBER_1">%d</xliff:g> nóg onsuksesvolle pogings sal jy gevra word om jou tablet te ontsluit met gebruik van jou Google-aanmelddetails.\n\n Probeer weer oor <xliff:g id="NUMBER_2">%d</xliff:g> sekondes."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerd geteken. Na nóg <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings sal jy gevra word om jou foon te ontsluit met gebruik van jou Google-aanmelddetails.\n\n Probeer weer oor <xliff:g id="NUMBER_2">%d</xliff:g> sekondes."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Jy het <xliff:g id="NUMBER_0">%d</xliff:g> keer probeer om die tablet verkeerde te ontsluit. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle poging, sal die tablet terug gestel word nia die fabrieksverstek en alle gebruikerdata sal verlore wees."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Jy het <xliff:g id="NUMBER_0">%d</xliff:g> keer probeer om die foon verkeerde te ontsluit. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle poging sal die foon terug gestel word na die fabrieksverstek en alle gebruikerdata sal verlore wees."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Jy het die tablet <xliff:g id="NUMBER">%d</xliff:g> keer verkeerd probeer ontsluit. Die tablet sal nou terug gestel word na die fabrieksverstek."</string>
@@ -826,7 +866,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Wagwoord"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Meld aan"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Ongeldige gebruikernaam of wagwoord."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Jou gebruikernaam of wagwoord vergeet?"\n"Besoek "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Jou gebruikernaam of wagwoord vergeet?\nBesoek "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Kontroleer tans..."</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Ontsluit"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Klank aan"</string>
@@ -874,7 +914,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Bevestig navigasie"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Verlaat hierdie bladsy"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Bly op hierdie bladsy"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Is jy seker dat jy weg van hierdie bladsy af wil navigeer?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nIs jy seker dat jy weg van hierdie bladsy af wil navigeer?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Bevestig"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Wenk: Dubbeltik om in en uit te zoem."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Outovul"</string>
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"Ongelukkig het <xliff:g id="APPLICATION">%1$s</xliff:g> gestop."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Ongelukkig het die proses <xliff:g id="PROCESS">%1$s</xliff:g> gestop."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> reageer nie."\n\n"Wil jy dit sluit?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Aktiwiteit <xliff:g id="ACTIVITY">%1$s</xliff:g> reageer nie."\n\n"Wil jy dit afsluit?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> reageer nie.\n\nWil jy dit sluit?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Aktiwiteit <xliff:g id="ACTIVITY">%1$s</xliff:g> reageer nie.\n\nWil jy dit afsluit?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> reageer nie. Wil jy dit sluit?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Proses <xliff:g id="PROCESS">%1$s</xliff:g> reageer nie."\n\n"Wil jy dit afsluit?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Proses <xliff:g id="PROCESS">%1$s</xliff:g> reageer nie.\n\nWil jy dit afsluit?"</string>
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"Verslag"</string>
     <string name="wait" msgid="7147118217226317732">"Wag"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"Die bladsy reageer nie meer nie."\n\n"Wil jy dit toemaak?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Die bladsy reageer nie meer nie.\n\nWil jy dit toemaak?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Program herlei"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> loop nou."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> is oorspronklik laat loop."</string>
@@ -1256,6 +1296,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Laat die program toe om die verstek houerdiens in te roep om inhoud te kopieer. Nie vir gebruik deur normale programme nie."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Roeteer media-uitvoer"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Laat \'n program toe om media-uitvoere na ander eksterne toestelle te roeteer."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Kry toegang tot keyguard se veilige berging"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Laat \'n program toe om toegang tot keyguard se veilige berging te kry."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Beheer wys en versteek van keyguard"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Laat \'n program toe om keyguard te beheer."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Raak twee keer vir zoembeheer"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Kon nie legstuk byvoeg nie."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Gaan"</string>
@@ -1265,15 +1309,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Klaar"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Vorige"</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Voer uit"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Skakel nommer"\n"met <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Skep kontak"\n"met <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Skakel nommer\nmet <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Skep kontak\nmet <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Die volgende een of meer programme versoek toestemming om jou rekening gebruik (nou én in die toekoms)."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Wil jy hierdie versoek toestaan?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Toegangsversoek"</string>
     <string name="allow" msgid="7225948811296386551">"Laat toe"</string>
     <string name="deny" msgid="2081879885755434506">"Weier"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Toestemming versoek"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Toestemming versoek"\n"vir rekening <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Toestemming versoek\nvir rekening <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Invoermetode"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Sinkroniseer"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Toeganklikheid"</string>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Sien alle"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Kies aktiwiteit"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Deel met"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Toestel gesluit."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Stuur tans…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Begin webblaaier?"</string>
@@ -1441,10 +1484,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Koppel tans..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Beskikbaar"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"Nie beskikbaar nie"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"In gebruik"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Ingeboude skerm"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"HDMI-skerm"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Oorlegger #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", veilig"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Draadlose skerm is gekoppel"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Hierdie skerm word op \'n ander toestel gewys"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Ontkoppel"</string>
@@ -1453,7 +1498,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Verkeerde patroon"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Verkeerde wagwoord"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"Verkeerde PIN"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Probeer weer oor <xliff:g id="NUMBER">%d</xliff:g> sekondes."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Probeer weer oor <xliff:g id="NUMBER">%1$d</xliff:g> sekondes."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Teken jou patroon"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Voer SIM-PIN in"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Voer PIN in"</string>
@@ -1473,27 +1518,85 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Wagwoord"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Meld aan"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Ongeldige gebruikernaam of wagwoord."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Het jy jou gebruikernaam of wagwoord vergeet?"\n"Besoek "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Het jy jou gebruikernaam of wagwoord vergeet?\nBesoek "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Kontroleer tans rekening..."</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Jy het jou PIN <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerd ingetik. "\n\n"Probeer weer oor <xliff:g id="NUMBER_1">%d</xliff:g> sekondes."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Jy het <xliff:g id="NUMBER_0">%d</xliff:g> keer jou wagwoord verkeerdelik getik. "\n\n"Probeer weer oor <xliff:g id="NUMBER_1">%d</xliff:g> sekondes."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerdelik geteken. "\n\n"Probeer weer oor <xliff:g id="NUMBER_1">%d</xliff:g> sekondes."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Jy het jou PIN <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerd ingetik. \n\nProbeer weer oor <xliff:g id="NUMBER_1">%d</xliff:g> sekondes."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Jy het <xliff:g id="NUMBER_0">%d</xliff:g> keer jou wagwoord verkeerdelik getik. \n\nProbeer weer oor <xliff:g id="NUMBER_1">%d</xliff:g> sekondes."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerdelik geteken. \n\nProbeer weer oor <xliff:g id="NUMBER_1">%d</xliff:g> sekondes."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Jy het <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerdelik gepoog om die tablet te ontsluit. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings, sal die tablet na die fabrieksverstek teruggestel word en al die gebruikerdata sal verlore wees."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Jy het <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerdelik gepoog om die foon te ontsluit. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings, sal die foon na die fabrieksverstek teruggestel word en al die gebruikerdata sal verlore wees."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Jy het <xliff:g id="NUMBER">%d</xliff:g> keer verkeerdelik gepoog om die tablet te ontsluit. Die tablet sal nou na fabrieksverstek teruggestel word."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Jy het <xliff:g id="NUMBER">%d</xliff:g> keer verkeerdelik gepoog om die foon te ontsluit. Die foon sal nou na fabrieksverstek teruggestel word."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerdelik geteken. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings, sal jy gevra word om jou tablet te ontsluit deur middel van \'n e-posrekening."\n\n" Probeer weer oor <xliff:g id="NUMBER_2">%d</xliff:g> sekondes."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerdelik geteken. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings, sal jy gevra word om jou foon te ontsluit deur middel van \'n e-posrekening."\n\n" Probeer weer oor <xliff:g id="NUMBER_2">%d</xliff:g> sekondes."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerdelik geteken. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings, sal jy gevra word om jou tablet te ontsluit deur middel van \'n e-posrekening.\n\n Probeer weer oor <xliff:g id="NUMBER_2">%d</xliff:g> sekondes."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerdelik geteken. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings, sal jy gevra word om jou foon te ontsluit deur middel van \'n e-posrekening.\n\n Probeer weer oor <xliff:g id="NUMBER_2">%d</xliff:g> sekondes."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Verwyder"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Verhoog volume bo aanbevole vlak?"\n"Deur vir lang tydperke teen hoë volume te luister, kan jou gehoor beskadig word."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Verhoog volume bo aanbevole vlak?\nDeur vir lang tydperke teen hoë volume te luister, kan jou gehoor beskadig word."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Hou aan met twee vingers inhou om toeganklikheid te aktiveer."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Toeganklikheid geaktiveer."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Toeganklikheid gekanselleer."</string>
     <string name="user_switched" msgid="3768006783166984410">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g> ."</string>
     <string name="owner_name" msgid="2716755460376028154">"Eienaar"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Fout"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Hierdie program werk nie met rekeninge vir beperkte profiele nie"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Hierdie program werk nie met rekeninge vir beperkte profiele nie"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Geen program gevind om hierdie handeling te hanteer nie"</string>
     <string name="revoke" msgid="5404479185228271586">"Herroep"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Gekanselleer"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Kon nie inhoud skryf nie"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"onbekend"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Voer administrateur-PIN in"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Voer PIN in"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Verkeerd"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Huidige PIN"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Nuwe PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Bevestig nuwe PIN"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Skep \'n PIN vir wysigingbeperkings"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PIN\'e kom nie ooreen nie. Probeer weer."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"PIN is te kort. Moet ten minste 4 syfers wees."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Probeer weer oor 1 sekonde"</item>
+    <item quantity="other" msgid="4730868920742952817">"Probeer weer oor <xliff:g id="COUNT">%d</xliff:g> sekondes"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Probeer later weer"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Sleep rand van skerm om balk te wys"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Sleep van rand van skerm af om stelselbalk te wys"</string>
 </resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index c84c0e2..6c8c0c6 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -131,6 +131,11 @@
     <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="default" msgid="3475999286680000541">"የስልክ ማከማቻ ሙሉ ነው! ቦታ ነፃ ለማድረግ አንዳንድ ፋይሎች ሰርዝ።"</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"አውታረ መረብ በክትትል ውስጥ ሊሆን ይችላል"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"እኔ"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"የጡባዊ አማራጮች"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"የስልክ አማራጮች"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"መተግበሪያው ተግባሮችን ወደ ቅድመ ገጹ እና ወደ ዳራው እንዲያንቀሳቅስ ይፈቅድለታል። መተግበሪያው ይህንን ያላንተ ግብዓት ሊያደርግ ይችላል።"</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"የአሂድ ትግበራዎች አቁም"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"ተግባሮችን ለማስወገድ እና መተግበሪያዎቻቸውን ለመግደል ለመተግበሪያ ይፈቅዳል። ጎጂ የሆኑ መተግበሪያዎች የሌሎችን መተግበሪያዎችን ባህሪ ሊያውኩ ይችላሉ።"</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"የእንቅስቃሴ ቁልሎችን ማቀናበር"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"መተግበሪያው ሌሎች መተግበሪያዎች በሚያሄዱበት የእንቅስቃሴዎች ቁልሎችን እንዲያክል፣ እንዲያስወግድ እና እንዲቀይር ያስችለዋል። ተንኮል-አዘል መተግበሪያዎች የሌሎች መተግበሪያዎች ባህሪን ሊበጠብጡ ይችላሉ።"</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"ማንኛውም እንቅስቃሴ ጀምር"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"መተግበሪያው ማንኛውም እንቅስቃሴ፣ የፍቃድ ጥበቃም ሆነ ወደ ውጭ የተላከበት ሁኔታ ሳይታይ፣ እንዲጀምር ይፈቅድለታል።"</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"የማያ ገጽ ተኳኋኝነት መድብ"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"ያዡ ግቤት ስልቱን ወደ ከፍተኛ-ደረጃ በይነገጽ ለመጠረዝ ይፈቅዳሉ። ለመደበኛ ትግበራዎች በፍፁም አያስፈልግም።"</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"ከአንድ የተደራሽነት አገልግሎት ጋር እሰር"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"ያዢው ወደ የአንድ ተደራሽነት አገልግሎት ከፍተኛ-ደረጃ በይነገጽ እንዲያስር ይፈቅድለታል። ለመደበኛ መተግበሪያዎች መቼም ቢሆን ሊያስፈልግ አይገባም።"</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"ከአንድ የህትመት አገልግሎት ጋር ማያያዝ"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"ያዢው የህትመት አገልግሎቱን ወደ ከፍተኛ-ደረጃ በይነገጽ እንዲጠርዝ ይፈቅድለታል። ለመደበኛ መተግበሪያዎች በጭራሽ አያስፈልግም።"</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"ከአንድ የህትመት አስተላላፊ አገልግሎት ጋር ይሰሩ"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"ያዢው የህትመት አስተላላፊ አገልግሎቱን ከከፍተኛ-ደረጃ በይነገጽ ጋር እንዲያስር ያስችለዋል። ለመደበኛ መተግበሪያዎች በጭራሽ አያስፈልግም።"</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"ከNFC አገልግሎት ጋር ይሰሩ"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"ያዢው የNFC ካርዶችን የሚያስመስሉ መተግበሪያዎችን እንዲያስር ያስችለዋል። ለመደበኛ መተግበሪያዎች በጭራሽ ሊያስፈልግ አይገባም።"</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"ለፅሁፍ አገልግሎት አሰረ"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"ያዡ ግቤት ለከፍተኛ-ደረጃ የፅሁፍ አገልግሎት ገፅታ ለመጠረዝ ይፈቅዳል። ለመደበኛ ትግበራዎች በፍፁም አያስፈልግም።"</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"ለVPN አገልግሎት ተገዛ"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"ያዡ ግቤት ስልቱን ወደ ከፍተኛ-ደረጃ ፍርግም አገልግሎት ለመጠረዝ  ይፈቅዳሉ። ለመደበኛ ትግበራዎች በፍፁም አያስፈልግም።"</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"ከመሣሪያ አስተዳደር ጋር ተገናኝ"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"ያዡ በይነመረብን ለመሣሪያ አስተዳዳሪ ለመላክ ይፈቅዳሉ። ለመደበኛ መተግበሪያዎች በፍፁም አያስፈልግም።"</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"የመሣሪያ አስተዳዳሪ ያክሉ ወይም ያስወግዱ"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"ያዢው ንቁ የመሣሪያ አስተዳዳሪዎች እንዲያክል ወይም እንዲያስወግድ ያስችለዋል። ለመደበኛ መተግበሪያዎች ጭራሽ ሊያስፈልግ አይገባም።"</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"የማያ ገፀ አቀማመጥን ለውጥ"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"በማንኛውም ጊዜ  የማሳያውን መሽከርከር ለመለወጥ ለመተግበሪያው ይፈቅዳሉ፡፡ ለተለመዱ መተግበሪያዎች አያስፈልግም፡፡"</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"የጠቋሚ ፍጥነት ለውጥ"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">" ከስርዓቱ የተለያዩ የማስታወሻ ፋይሎች ውስጥ ለማንበብ ለመተግበሪያይፈቅዳሉ። ይህ ስለ ስልክህ ምን እያደረክበት እንደሆነ የግላዊ  ወይም የግል መረጃን ጨምሮ ጠቅላላ መረጃ ለማግኘት ይፈቅዳል።"</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"ለመልሰህ አጫውት ማንኛውምንም የማህደረ መረጃ ዲኮደር ተጠቀም"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"ለመልሰህ አጫውት ፍታን በማንኛውም የተጫኑ በማህደረ መረጃ ዲኮደር ለመጠቀም  ለመተግበሪያ ይፈቅዳል።"</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"የታመኑ ምስክርነቶችን ያስተዳድሩ"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"መተግበሪያው CA የምስክር ወረቀቶችን እንደሚታመኑ ምስክርነቶች አንዲጭን እና እንዲያራግፍ ይፍቀዱ።"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"በdiag ባለቤትነት ያሉ ንብረቶችን አንብብ/ፃፍ"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"በዲያግ ቡድን ባለቤትነት ወደ አለ ማንኛውም ንብረት ለምሳሌ በ/dev ያሉ ፋይሎች ለማንበብ እና ለመፃፍ ለመተግበሪያው ይፈቅዳሉ። ይህ በመሰረቱ የስርዓት መረጋጋትን እና ደህንነትን ሊጎዳ ይችላል። ይህ ውስን የሀርድዌር-ተኮር ዲያግኖስቲክስ በአምራቹ ወይም ከዋኙ ብቻ መሆን አለበት።"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"የመተግበሪያ ምንዝሮችን አንቃ ወይም አቦዝን"</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"መተግበሪያው የWifi ማሳያዎችን እንዲያዋቅርና ከእነሱ ጋር እንዲገናኝ ይፈቅድለታል።"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"የWifi ማሳያዎችን ተቆጣጠር"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"መተግበሪያው በዝቅተኛ ደረጃ ላይ ያሉ የWifi ማሳያዎችን እንዲቆጣጠር ይፈቅድለታል።"</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"የድምጽ ውጽዓት ይቅረጹ"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"መተግበሪያው የድምጽ ውጽዓት እንዲቀርጽ እና አቅጣጫውን እንዲያዞር ያስችለዋል።"</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"የቪዲዮ ውጽዓት ይቅረጹ"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"መተግበሪያው የቪዲዮ ውጽዓት እንዲቀርጽ እና አቅጣጫውን እንዲያዞር ያስችለዋል።"</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"ደህንነቱ የተጠበቀ የቪዲዮ ውጽዓት ይቅረጹ"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"መተግበሪያው ደህንነቱ የተጠበቀ የቪዲዮ ውጽዓት እንዲቀርጽ እና አቅጣጫውን እንዲያዞር ያስችለዋል።"</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"የድምፅ ቅንብሮችን ለውጥ"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"መተግበሪያው አንደ የድምጽ መጠን እና ለውጽአት የትኛውን የድምጽ ማጉያ ጥቅም ላይ እንደዋለ የመሳሰሉ ሁለንተናዊ የድምጽ ቅንብሮችን እንዲያስተካክል ይፈቅድለታል።"</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"ኦዲዮ ቅዳ"</string>
@@ -525,6 +552,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"ስልክ ከማንቀላፋት ተከላከል"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"ጡባዊውን ከመተኛት መከልከል ለመተግበሪያው ይፈቅዳሉ።"</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"ስልኩን ከመተኛት መከልከል ለመተግበሪያው ይፈቅዳሉ።"</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"ጡባዊ አብራ ወይም አጥፋ"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"ስልክ አብራ ወይም አጥፋ"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"ጡባዊ ተኮውን ለማብራት እና ለማጥፋት ለመተግበሪያው ይፈቅዳሉ።"</string>
@@ -613,6 +646,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"መተግበሪያውን ወደ SD ካርድ ለመፃፍ ይፈቅዳል።"</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"የውስጥ ማህደረ መረጃ ማከማቻ ይዘቶችን ቀይር/ሰርዝ"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"የውስጥ ማህደረ መረጃ ማከማቻ ይዘትን ለመቀየር ለመተግበሪያው ይፈቅዳሉ፡፡"</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"የሰነድ ማከማቻን ያስተዳድሩ"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"መተግበሪያው የሰነድ ማከማቻን እንዲያስተዳድር ይፈቅድለታል።"</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"የሁሉም ተጠቃሚዎች ውጫዊ ማከማቻውን ይደርስበታል"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"መተግበሪያውን የሁሉም ተጠቃሚዎች ውጫዊ ማከማቻውን እንዲደርስ ይፈቅድለታል።"</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"የመሸጎጫ ስርዓተ ፋይል ድረስ"</string>
@@ -625,11 +660,17 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"የአውታረመረብ ቋሚ መመሪያዎችን እና ትግበራ ተኮር ደንቦችን ለማደራጀት ለመተግበሪያው ይፈቅዳሉ፡፡"</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"የአውታረ መረብ አጠቃቀም"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"ከመተግበሪያዎች በተለየ መልኩ እንዴት የአውታረ መረብ አጠቃቀም እንደተመዘገበ ለመቀየር ለመተግበሪያው ይፈቅዳሉ።ለመደበኛ መተግበሪያዎች አገልግሎት አይውልም።"</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"የሶኬት ምልክቶችን መቀየር"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"መተግበሪያው መንገድ እንዲፈልግ የሶኬት ምልክቶቹን እንዲቀይር ያስችለዋል"</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="policylab_limitPassword" msgid="4497420728857585791">"የይለፍ ቃል ድንቦች አዘጋጅ"</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"በድምጸ-ተያያዥ ሞደም የቀረበው የውቅር መተግበሪያውን መጥራት"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"ያዢው በድምጸ-ተያያዥ ሞደም የቀረበው የውቅር መተግበሪያውን እንዲጠራው ያስችለዋል። ለመደበኛ መተግበሪያዎች በጭራሽ አያስፈልግም።"</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"በአውታረ መረብ ሁኔታዎች ላይ የተስተዋሉ ነገሮችን ያዳምጣል"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"አንድ መተግበሪያ በአውታረ መረብ ሁኔታዎች ላይ የተስተዋሉ ነገሮችን እንዲያዳምጥ ያስችለዋል። ለመደበኛ መተግበሪያዎች በጭራሽ አስፈላጊ ሊሆን አይገባም።"</string>
+    <string name="policylab_limitPassword" msgid="4497420728857585791">"የይለፍ ቃል ደንቦች አዘጋጅ"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"በማያ-መክፈት የተፈቀዱ የይለፍ ቃል ርዝመት እና ቁምፊዎች ተቆጣጠር።"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"የማሳያ-ክፈት ሙከራዎችን አሳይ"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"ማሳያውን በምትከፍትበት ጊዜ በስህተት የተተየቡ የይለፍ ቃሎችን ቁጥር ተቆጣጠር፤ እና ጡባዊ ተኮውን ቆልፍ  ወይም በጣም ብዙ የተሳሳቱ የይለፍ ቃሎች ከተተየቡ የጡባዊ ተኮን ውሂብ አጥፋ፡፡"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -776,7 +816,7 @@
     <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="8963839242565653192">"ከአገልግሎት መስጫ ክልል ውጪ"</string>
-    <string name="lockscreen_screen_locked" msgid="7288443074806832904">"ማሳያ ተቆልፏል።"</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>
@@ -796,7 +836,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"ሲም ካርድ አስገባ፡፡"</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM ካርዱ ጠፍቷል ወይም መነበብ አይችልም።እባክህ SIM ካርድ አስገባ።"</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"የማይሰራ ሲም ካርድ።"</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"SIM ካርድህ በቋሚነት ቦዝኗል።"\n"  ለሌላ SIM ካርድ  የገመድ አልባ አገልግሎት አቅራቢህ ጋር ተገናኝ።"</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"SIM ካርድህ በቋሚነት ቦዝኗል።\n  ለሌላ SIM ካርድ  የገመድ አልባ አገልግሎት አቅራቢህ ጋር ተገናኝ።"</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"የቀድሞ ዝርዝር አዝራር"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"ቀጣይ ዝርዝር አዝራር"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"ለአፍታ አቁም አዝራር"</string>
@@ -808,11 +848,11 @@
     <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">%d</xliff:g>ጊዜ በስህተት ስለውታል።"\n\n"እባክህ እንደገና ከ<xliff:g id="NUMBER_1">%d</xliff:g>ሰከንዶች በኋላ ሞክር።"</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"<xliff:g id="NUMBER_0">%d</xliff:g>ጊዚያቶች የይለፍ ቃልህን በስህተት ተይበኻል፡፡በ<xliff:g id="NUMBER_1">%d</xliff:g> ሰኮንዶች ውስጥ "\n\n"እንደገና ሞክር፡፡"</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"<xliff:g id="NUMBER_0">%d</xliff:g>ጊዚያቶች ፒንህን በስህተት ተይበኻል፡፡በ"\n"ሰኮንዶች ውስጥ "\n"<xliff:g id="NUMBER_1">%d</xliff:g>እንደገና ሞክር፡፡"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"የመክፈቻ ስርዓተ ጥለቱን <xliff:g id="NUMBER_0">%d</xliff:g>ጊዜ በስህተት ስለውታል።ከ<xliff:g id="NUMBER_1">%d</xliff:g>የበለጠ ያልተሳካ ሙከራ በኋላ፣ የGoogle መግቢያዎን ተጠቅመው ስልኩን እንዲከከፍቱ ይጠየቃሉ።"\n\n"እባክዎ እንደገና <xliff:g id="NUMBER_2">%d</xliff:g>ከሰከንዶች በኋላ ይሞክሩ።"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"የመክፈቻ ስርዓተ ጥለቱን<xliff:g id="NUMBER_0">%d</xliff:g>ጊዜ በስህተት ስለውታል።ከ<xliff:g id="NUMBER_1">%d</xliff:g> የበለጠ ያልተሳካ ሙከራ በኋላ፣ የGoogle መግቢያዎን ተጠቅመው ስልኩን እንዲከፍቱ ይጠየቃሉ።"\n\n"እባክዎ እንደገና ከ<xliff:g id="NUMBER_2">%d</xliff:g> ሰከንዶች በኋላ ይሞክሩ።"</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"የመክፈቻ ስርዓተ ጥለቱን <xliff:g id="NUMBER_0">%d</xliff:g>ጊዜ በስህተት ስለውታል።\n\nእባክህ እንደገና ከ<xliff:g id="NUMBER_1">%d</xliff:g>ሰከንዶች በኋላ ሞክር።"</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"<xliff:g id="NUMBER_0">%d</xliff:g>ጊዚያቶች የይለፍ ቃልህን በስህተት ተይበኻል፡፡በ<xliff:g id="NUMBER_1">%d</xliff:g> ሰኮንዶች ውስጥ \n\nእንደገና ሞክር፡፡"</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"<xliff:g id="NUMBER_0">%d</xliff:g>ጊዚያቶች ፒንህን በስህተት ተይበኻል፡፡በ\nሰኮንዶች ውስጥ \n<xliff:g id="NUMBER_1">%d</xliff:g>እንደገና ሞክር፡፡"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"የመክፈቻ ስርዓተ ጥለቱን <xliff:g id="NUMBER_0">%d</xliff:g>ጊዜ በስህተት ስለውታል።ከ<xliff:g id="NUMBER_1">%d</xliff:g>የበለጠ ያልተሳካ ሙከራ በኋላ፣ የGoogle መግቢያዎን ተጠቅመው ስልኩን እንዲከከፍቱ ይጠየቃሉ።\n\nእባክዎ እንደገና <xliff:g id="NUMBER_2">%d</xliff:g>ከሰከንዶች በኋላ ይሞክሩ።"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"የመክፈቻ ስርዓተ ጥለቱን<xliff:g id="NUMBER_0">%d</xliff:g>ጊዜ በስህተት ስለውታል።ከ<xliff:g id="NUMBER_1">%d</xliff:g> የበለጠ ያልተሳካ ሙከራ በኋላ፣ የGoogle መግቢያዎን ተጠቅመው ስልኩን እንዲከፍቱ ይጠየቃሉ።\n\nእባክዎ እንደገና ከ<xliff:g id="NUMBER_2">%d</xliff:g> ሰከንዶች በኋላ ይሞክሩ።"</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"ይህን tablet <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ ያህል በስህተት ለማስከፈት ሞክረሃል፡፡ ከ <xliff:g id="NUMBER_1">%d</xliff:g> በላይ ያልተሳኩ ሙከራዎች በኋላ፣ ይህ tablet አሁን በፋብሪካ ነባሪ ቅንጅት ዳግም ይቀናበርና ሁሉም የተጠቃሚው ውሂብ ይጠፋል፡፡"</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"ይህን ስልክ <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ ያህል በስህተት ለማስከፈት ሞክረሃል፡፡ ከ <xliff:g id="NUMBER_1">%d</xliff:g> በላይ ያልተሳኩ ሙከራዎች በኋላ፣ ይህ ስልክ በፋብሪካ ነባሪ ቅንጅት ዳግም ይቀናበርና ሁሉም የተጠቃሚው ውሂብ ይጠፋል፡፡"</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"ይህን tablet <xliff:g id="NUMBER">%d</xliff:g> ጊዜ ያህል በስህተት ለማስከፈት ሞክረሃል፡፡ ይህ tablet አሁን በፋብሪካ ነባሪ ቅንጅት ዳግም ይቀናበራል፡፡"</string>
@@ -826,7 +866,7 @@
     <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_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>
@@ -874,7 +914,7 @@
     <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="autofill_this_form" msgid="4616758841157816676">"ራስ ሙላ"</string>
@@ -927,8 +967,8 @@
     <string name="menu_space_shortcut_label" msgid="2410328639272162537">"ቦታ"</string>
     <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"አሰገባ"</string>
     <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"ሰርዝ"</string>
-    <string name="search_go" msgid="8298016669822141719">" ፈልግ"</string>
-    <string name="searchview_description_search" msgid="6749826639098512120">"ፈልግ"</string>
+    <string name="search_go" msgid="8298016669822141719">"ፍለጋ"</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>
@@ -939,7 +979,7 @@
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"ከ1 ወር በፊት"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"ከ1 ወር በፊት"</string>
   <plurals name="num_seconds_ago">
-    <item quantity="one" msgid="4869870056547896011">"ከ1 ሰከንድ በፊት"</item>
+    <item quantity="one" msgid="4869870056547896011">"ከ1 ሴኮንድ በፊት"</item>
     <item quantity="other" msgid="3903706804349556379">"<xliff:g id="COUNT">%d</xliff:g> ሰኮንዶች በፊት"</item>
   </plurals>
   <plurals name="num_minutes_ago">
@@ -960,7 +1000,7 @@
     <item quantity="other" msgid="2479586466153314633">"ከ <xliff:g id="COUNT">%d</xliff:g>ቀን በፊት"</item>
   </plurals>
   <plurals name="in_num_seconds">
-    <item quantity="one" msgid="2729745560954905102">"በ1 ሰከንድ"</item>
+    <item quantity="one" msgid="2729745560954905102">"በ1 ሴኮንድ"</item>
     <item quantity="other" msgid="1241926116443974687">"በ<xliff:g id="COUNT">%d</xliff:g> ሰከንዶች ውስጥ"</item>
   </plurals>
   <plurals name="in_num_minutes">
@@ -976,7 +1016,7 @@
     <item quantity="other" msgid="5109449375100953247">"በ<xliff:g id="COUNT">%d</xliff:g> ቀናት"</item>
   </plurals>
   <plurals name="abbrev_num_seconds_ago">
-    <item quantity="one" msgid="1849036840200069118">"1 ሰከንድ በፊት"</item>
+    <item quantity="one" msgid="1849036840200069118">"1 ሴኮንድ በፊት"</item>
     <item quantity="other" msgid="3699169366650930415">"<xliff:g id="COUNT">%d</xliff:g> ሰከንዶች በፊት"</item>
   </plurals>
   <plurals name="abbrev_num_minutes_ago">
@@ -992,7 +1032,7 @@
     <item quantity="other" msgid="3453342639616481191">"ከ <xliff:g id="COUNT">%d</xliff:g>ቀን በፊት"</item>
   </plurals>
   <plurals name="abbrev_in_num_seconds">
-    <item quantity="one" msgid="5842225370795066299">"በ1 ሰከንድ"</item>
+    <item quantity="one" msgid="5842225370795066299">"በ1 ሴኮንድ"</item>
     <item quantity="other" msgid="5495880108825805108">"በ<xliff:g id="COUNT">%d</xliff:g> ሰከንዶች ውስጥ"</item>
   </plurals>
   <plurals name="abbrev_in_num_minutes">
@@ -1016,14 +1056,14 @@
     <string name="hours" msgid="894424005266852993">"ሰዓቶች"</string>
     <string name="minute" msgid="9148878657703769868">"ደቂቃ"</string>
     <string name="minutes" msgid="5646001005827034509">" ደቂቃዎች"</string>
-    <string name="second" msgid="3184235808021478">"ሰከንድ"</string>
+    <string name="second" msgid="3184235808021478">"ሴኮንድ"</string>
     <string name="seconds" msgid="3161515347216589235">"ሰከንዶች"</string>
     <string name="week" msgid="5617961537173061583">"ሳምንት"</string>
     <string name="weeks" msgid="6509623834583944518">"ሳምንቶች"</string>
     <string name="year" msgid="4001118221013892076">"ዓመት"</string>
     <string name="years" msgid="6881577717993213522">"ዓመታት"</string>
   <plurals name="duration_seconds">
-    <item quantity="one" msgid="6962015528372969481">"1 ሰከንድ"</item>
+    <item quantity="one" msgid="6962015528372969481">"1 ሴኮንድ"</item>
     <item quantity="other" msgid="1886107766577166786">"<xliff:g id="COUNT">%d</xliff:g> ሰከንዶች"</item>
   </plurals>
   <plurals name="duration_minutes">
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"መጥፎ ዕድል ሆኖ፣ <xliff:g id="APPLICATION">%1$s</xliff:g> አቁሞዋል፡፡"</string>
     <string name="aerr_process" msgid="4507058997035697579">"መጥፎ ዕድል ሆኖ፣ ይሄ ሂደት <xliff:g id="PROCESS">%1$s</xliff:g> ቆሞዋል፡፡"</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g>ምላሽ እየሰጠ አይደለም።"\n\n"መዝጋት ትፈልጋለህ?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"እንቅስቃሴ <xliff:g id="ACTIVITY">%1$s</xliff:g>ምላሽ እየሰጠ አይደለም።"\n\n"መዝጋት ትፈልጋለህ?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g>ምላሽ እየሰጠ አይደለም።\n\nመዝጋት ትፈልጋለህ?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"እንቅስቃሴ <xliff:g id="ACTIVITY">%1$s</xliff:g>ምላሽ እየሰጠ አይደለም።\n\nመዝጋት ትፈልጋለህ?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g>ምላሽ እየሰጠ አይደለም።መዝጋት ትፈልጋለህ?"</string>
-    <string name="anr_process" msgid="6513209874880517125">" ሂደት<xliff:g id="PROCESS">%1$s</xliff:g> ምላሽ እየሰጠ አይደለም።"\n\n"መዝጋት ትፈልጋለህ?"</string>
+    <string name="anr_process" msgid="6513209874880517125">" ሂደት<xliff:g id="PROCESS">%1$s</xliff:g> ምላሽ እየሰጠ አይደለም።\n\nመዝጋት ትፈልጋለህ?"</string>
     <string name="force_close" msgid="8346072094521265605">"ይሁን"</string>
     <string name="report" msgid="4060218260984795706">"ሪፖርት"</string>
     <string name="wait" msgid="7147118217226317732">"ቆይ"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"ገጹ ምላሽ የማይሰጥ ሆኗል።"\n\n"ልትዘጋው ትፈልጋለህ?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"ገጹ ምላሽ የማይሰጥ ሆኗል።\n\nልትዘጋው ትፈልጋለህ?"</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>
@@ -1256,6 +1296,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"ይዘትን ለመቅዳት ነባሪ መያዣ አገልግሎት እንዲያስነሳ ለመተግበሪው ይፈቅዳሉ፡፡ ለመደበኛ መተግበሪያዎች ለመጠቀም አይሆንም፡፡"</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"የሚዲያ ውፅአት መንገድ"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"አንድ መተግበሪያ የሚዲያ ውፅአትን ወደ ሌላ ውጫዊ መሳሪያ እንዲመራ ይፈቅድለታል።"</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"ደህንነቱ በቁልፍ የተጠበቀ ማከማቻን ይድረሱ"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"አንድ መተግበሪያ ደህንነቱ በቁልፍ የተጠበቀ ማከማቻ እንዲደርስ ያስችለዋል።"</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"የቁልፍ መጠበቂያውን ማሳየት እና መደበቅ ይቆጣጠሩ"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"አንድ መተግበሪያ የቁልፍ መጠበቂያውን እንዲቆጣጠር ያስችለዋል።"</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"ለአጉላ መቆጣጠሪያ ሁለት ጊዜ ነካ አድርግ"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"ምግብር ማከል አልተቻለም።"</string>
     <string name="ime_action_go" msgid="8320845651737369027">"ሂድ"</string>
@@ -1265,8 +1309,8 @@
     <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="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>
@@ -1376,7 +1420,7 @@
     <string name="description_target_camera" msgid="969071997552486814">"ካሜራ"</string>
     <string name="description_target_silent" msgid="893551287746522182">"ፀጥታ"</string>
     <string name="description_target_soundon" msgid="30052466675500172">"ድምፅ አብራ"</string>
-    <string name="description_target_search" msgid="3091587249776033139">"ፈልግ"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"ፍለጋ"</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"ላለመቆለፍ አንሸራት፡፡"</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"የይለፍ ቃል ቁልፎች  ሲነገሩ ለመስማት የጆሮ ማዳመጫ ሰካ።"</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"ነጥብ."</string>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"ሁሉንም ተመልከት"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"እንቅስቃሴ ምረጥ"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"ተጋራ ከ"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"መሣሪያ ተቆልፏል።"</string>
     <string name="list_delimeter" msgid="3975117572185494152">"፣ "</string>
     <string name="sending" msgid="3245653681008218030">"በመላክ ላይ…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"ማሰሺያን አስነሳ?"</string>
@@ -1441,10 +1484,12 @@
     <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>
+    <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_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="wifi_display_notification_title" msgid="2223050649240326557">"ገመድ አልባ ማሳያ ተገናኝቷል"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"ይህ ማያ ገጽ በሌላ መሣሪያ ላይ እያሳየ ነው"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"ግንኙነት አቋርጥ"</string>
@@ -1453,7 +1498,7 @@
     <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_too_many_failed_attempts_countdown" msgid="6358110221603297548">"በ<xliff:g id="NUMBER">%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">"የሲም ፒን ያስገቡ"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"ፒን ያስገቡ"</string>
@@ -1473,27 +1518,85 @@
     <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_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">%d</xliff:g> ጊዜ በትክክል አልተየቡም። "\n\n"በ<xliff:g id="NUMBER_1">%d</xliff:g> ሰኮንዶች ውስጥ እንደገና ይሞክሩ።"</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"የይለፍ ቃልዎን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ ትክክል ባልሆነ መንገድ ተይበዋል።"\n\n"በ<xliff:g id="NUMBER_1">%d</xliff:g> ሰኮንዶች ውስጥ እንደገና ይሞክሩ።"</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"የመክፈቻ ስርዓተ ጥለትዎን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ በትክክል አልሳሉትም። "\n\n" ከ<xliff:g id="NUMBER_1">%d</xliff:g> ሰከንዶች በኋላ እንደገና ይሞክሩ።"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"ፒንዎን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ በትክክል አልተየቡም። \n\nበ<xliff:g id="NUMBER_1">%d</xliff:g> ሰኮንዶች ውስጥ እንደገና ይሞክሩ።"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"የይለፍ ቃልዎን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ ትክክል ባልሆነ መንገድ ተይበዋል።\n\nበ<xliff:g id="NUMBER_1">%d</xliff:g> ሰኮንዶች ውስጥ እንደገና ይሞክሩ።"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"የመክፈቻ ስርዓተ ጥለትዎን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ በትክክል አልሳሉትም። \n\n ከ<xliff:g id="NUMBER_1">%d</xliff:g> ሰከንዶች በኋላ እንደገና ይሞክሩ።"</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"ጡባዊ ቱኮውን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ ትክክል ባልሆነ መንገድ ለመክፈት ሞክረዋል። ከ<xliff:g id="NUMBER_1">%d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ ጡባዊ ቱኮው በፋብሪካ ነባሪ ቅንብር ዳግም ይጀመርና ሁሉም የተጠቃሚ ውሂብ ይጠፋል።"</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"ስልኩን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ ትክክል ባልሆነ መንገድ ለመክፈት ሞክረዋል። ከ<xliff:g id="NUMBER_1">%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="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">%d</xliff:g> ጊዜ በትክክል አልሳሉትም። ከ<xliff:g id="NUMBER_1">%d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ የኢሜይል መለያ ተጠቅመው ጡባዊ ቱኮዎን እንዲከፍቱ ይጠየቃሉ።"\n\n" ከ<xliff:g id="NUMBER_2">%d</xliff:g> ከሰከንዶች በኋላ እንደገና ይሞክሩ።"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"የመክፈቻ ስርዓተ ጥለቱን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ በትክክል አልሳሉትም። ከ<xliff:g id="NUMBER_1">%d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ የኢሜይል መለያ ተጠቅመው ስልክዎን እንዲከፍቱ ይጠየቃሉ።"\n\n"እባክዎ ከ<xliff:g id="NUMBER_2">%d</xliff:g> ሰከንዶች በኋላ እንደገና ይሞክሩ።"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"የመክፈቻ ስርዓተ ጥለቱን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ በትክክል አልሳሉትም። ከ<xliff:g id="NUMBER_1">%d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ የኢሜይል መለያ ተጠቅመው ጡባዊ ቱኮዎን እንዲከፍቱ ይጠየቃሉ።\n\n ከ<xliff:g id="NUMBER_2">%d</xliff:g> ከሰከንዶች በኋላ እንደገና ይሞክሩ።"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"የመክፈቻ ስርዓተ ጥለቱን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ በትክክል አልሳሉትም። ከ<xliff:g id="NUMBER_1">%d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ የኢሜይል መለያ ተጠቅመው ስልክዎን እንዲከፍቱ ይጠየቃሉ።\n\nእባክዎ ከ<xliff:g id="NUMBER_2">%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="7324161939475478066">"ድምጽ ከሚመከረው መጠን በላይ ይጨመር?"\n"ለረጅም ጊዜ በከፍተኛ ድምጽ መስማት የመስማት ችሎታዎን ሊጎዳ ይችላል።"</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"ድምጽ ከሚመከረው መጠን በላይ ይጨመር?\nለረጅም ጊዜ በከፍተኛ ድምጽ መስማት የመስማት ችሎታዎን ሊጎዳ ይችላል።"</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"ተደራሽነትን ለማንቃት ሁለት ጣቶችዎን ባሉበት ያቆዩዋቸው።"</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"ተደራሽነት ነቅቷል።"</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"ተደራሽነት ተሰርዟል።"</string>
     <string name="user_switched" msgid="3768006783166984410">"የአሁኑ ተጠቃሚ <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="app_no_restricted_accounts" msgid="4011285085817350390">"ይህ መተግበሪያ የተገደቡ መገለጫዎች መለያዎችን አይደግፍም"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"ይህ መተግበሪያ የተገደቡ መገለጫዎች መለያዎችን አይደግፍም"</string>
     <string name="app_not_found" msgid="3429141853498927379">"ይህን እርምጃ የሚያከናውን ምንም መተግበሪያ አልተገኘም"</string>
     <string name="revoke" msgid="5404479185228271586">"ሻር"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"አይ ኤስ ኦ ኤ0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"አይ ኤስ ኦ ኤ1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"አይ ኤስ ኦ ኤ2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"አይ ኤስ ኦ ኤ3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"አይ ኤስ ኦ ኤ4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"አይ ኤስ ኦ ኤ5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"አይ ኤስ ኦ ኤ6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"አይ ኤስ ኦ ኤ7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"አይ ኤስ ኦ ኤ8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"አይ ኤስ ኦ ኤ9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"አይ ኤስ ኦ ኤ10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"አይ ኤስ ኦ ቢ0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"አይ ኤስ ኦ ቢ1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"አይ ኤስ ኦ ቢ2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"አይ ኤስ ኦ ቢ3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"አይ ኤስ ኦ ቢ4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"አይ ኤስ ኦ ቢ5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"አይ ኤስ ኦ ቢ6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"አይ ኤስ ኦ ቢ7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"አይ ኤስ ኦ ቢ8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"አይ ኤስ ኦ ቢ9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"አይ ኤስ ኦ ቢ10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"አይ ኤስ ኦ ሲ0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"አይ ኤስ ኦ ሲ1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"አይ ኤስ ኦ ሲ2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"አይ ኤስ ኦ ሲ3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"አይ ኤስ ኦ ሲ4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"አይ ኤስ ኦ ሲ5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"አይ ኤስ ኦ ሲ6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"አይ ኤስ ኦ ሲ7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"አይ ኤስ ኦ ሲ8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"አይ ኤስ ኦ ሲ9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"አይ ኤስ ኦ ሲ10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"ደብዳቤ"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"የመንግስት ደብዳቤ"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"ሕግ"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"ጁኒየር ህጋዊ"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"የሒሳብ መዝገብ"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"ታብሎይድ"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"ተትቷል"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"ይዘት መጻፍ ላይ ስህተት"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"አይታወቅም"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"የአስተዳዳሪ ፒን ያስገቡ"</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>
+    <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">"ገደቦችን ለመቀየር ፒን ይፍጠሩ"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"ፒኖች አይዛመዱም። እንደገና ይሞክሩ።"</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"ፒን በጣም አጭር ነው። ቢያንስ 4 አኃዝ መሆን አለበት።"</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"በ1 ሰከንድ ውስጥ እንደገና ይሞክሩ"</item>
+    <item quantity="other" msgid="4730868920742952817">"በ<xliff:g id="COUNT">%d</xliff:g> ሰከንዶች ውስጥ እንደገና ይሞክሩ"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"ቆይተው እንደገና ይሞክሩ"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"አሞሌውን ለማሳየት የማያ ገጹ ጠርዝ ላይ ያንሸራትቱ"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"አሞሌውን ለማሳየት ከማያ ገጹ ጠርዝ ጀምረው ያንሸራትቱ"</string>
 </resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index d694917..bd394d1 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -131,6 +131,11 @@
     <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="default" msgid="3475999286680000541">"سعة تخزين الهاتف ممتلئة. احذف بعض الملفات لإخلاء مساحة."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"قد تكون الشبكة مراقبة"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"أنا"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"خيارات الجهاز اللوحي"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"خيارات الهاتف"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"للسماح للتطبيق بنقل المهام إلى المقدمة والخلفية. وقد يجري التطبيق ذلك بدون إذنك."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"إيقاف التطبيقات التي قيد التشغيل"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"للسماح للتطبيق بإزالة المهام وإنهاء تطبيقاتها. قد تعطل التطبيقات الضارة عمل التطبيقات الأخرى."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"إدارة حزم الأنشطة"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"للسماح للتطبيق بإضافة حزم الأنشطة التي تعمل بها التطبيقات الأخرى وإزالتها وتعديلها. فقد تعطل التطبيقات الضارة سلوك عمل التطبيقات الأخرى."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"بدء أي نشاط"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"للسماح للتطبيق ببدء أي نشاط، بغض النظر عن حماية الإذن أو حالة التصدير."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"تعيين توافق الشاشة"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"للسماح للمالك بالالتزام بواجهة المستوى العلوي لأسلوب الإدخال. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"الالتزام بخدمة إمكانية الدخول"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"للسماح للمالك بالالتزام بواجهة المستوى العلوي لخدمة إمكانية الدخول. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"الالتزام بخدمة طباعة"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"للسماح للمالك بالالتزام بواجهة المستوى العلوي لخدمة الطباعة. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"الالتزام بخدمة التخزين المؤقت للطباعة"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"للسماح للمالك بالالتزام بواجهة المستوى العلوي لخدمة التخزين المؤقت للطباعة. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"الربط بخدمة NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"للسماح لحامل البطاقة بالربط بالتطبيقات التي تحاكي بطاقات NFC. لا يتوجب استخدامه على الإطلاق للتطبيقات العادية."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"الالتزام بخدمة إدخال النصوص"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"للسماح للمالك بالالتزام بواجهة المستوى العلوي لخدمة إدخال النصوص (على سبيل المثال، SpellCheckerService). لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"الالتزام بخدمة VPN"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"للسماح للمالك بالالتزام بواجهة المستوى العلوي لخدمة الأداة. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"التفاعل مع مشرف الجهاز"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"للسماح للمالك بإرسال الأهداف إلى أحد مشرفي الجهاز. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"إضافة مشرف جهاز أو إزالته"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"للسماح بحامل البطاقة بإضافة مشرفي أجهزة نشطين أو إزالتهم. لا يلزم ذلك أبدًا للتطبيقات العادية."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"تغيير اتجاه الشاشة"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"للسماح للتطبيق بتغيير تدوير الشاشة في أي وقت. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"تغيير سرعة المؤشر"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"للسماح للتطبيق بالقراءة من ملفات سجلات النظام المتنوعة. ويسمح ذلك للتطبيق باكتشاف المعلومات العامة حول ما تفعله بالهاتف، ومن المحتمل أن يتضمن معلومات شخصية أو خاصة."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"استخدام أي برنامج فك تشفير وسائط من أجل التشغيل"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"السماح للتطبيق باستخدام أي برنامج فك تشفير وسائط مثبت لفك التشفير من أجل التشغيل."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"إدارة بيانات الاعتماد الموثوقة"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"السماح للتطبيق بتثبيت شهادات CA وإلغاء تثبيتها باعتبارها بيانات اعتماد محل ثقة."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"قراءة/كتابة إلى الموارد المملوكة بواسطة التشخيص"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"للسماح للتطبيق بالقراءة والكتابة إلى أي مورد مملوك بواسطة مجموعة التشخيصات؛ على سبيل المثال، الملفات في /dev. من المحتمل أن يؤثر ذلك في استقرار النظام وأمانه. يجب ألا يستخدم ذلك سوى للتشخيصات الخاصة بالنظام من قِبل المصنِّع أو المشغِّل."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"تمكين مكونات التطبيق أو تعطيلها"</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"للسماح للتطبيق بتهيئة شاشات Wi-Fi والاتصال بها."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"التحكم في شاشات Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"للسماح للتطبيق بالتحكم في الميزات ذات المستوى المنخفض في شاشات Wi-Fi."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"التقاط إخراج الصوت"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"السماح للتطبيق بالتقاط إخراج الصوت وإعادة توجيهه."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"التقاط إخراج الفيديو"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"السماح للتطبيق بالتقاط إخراج الفيديو وإعادة توجيهه."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"التقاط إخراج الفيديو الآمن"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"السماح للتطبيق بالتقاط إخراج الفيديو الآمن وإعادة توجيهه."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"تغيير إعداداتك الصوتية"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"للسماح للتطبيق بتعديل إعدادات الصوت العامة مثل مستوى الصوت وأي السماعات يتم استخدامها للاستماع."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"تسجيل الصوت"</string>
@@ -525,6 +552,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"منع الهاتف من الدخول في وضع السكون"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"للسماح للتطبيق بمنع الجهاز اللوحي من الانتقال إلى وضع السكون."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"للسماح للتطبيق بمنع الهاتف من الانتقال إلى وضع السكون."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"تشغيل الجهاز اللوحي أو إيقاف تشغيله"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"تشغيل الهاتف أو إيقاف تشغيله"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"للسماح للتطبيق بتشغيل الجهاز اللوحي أو إيقاف تشغيله."</string>
@@ -613,6 +646,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"للسماح للتطبيق بالكتابة إلى بطاقة SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"تعديل/حذف محتويات وحدة تخزين الوسائط الداخلية"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"للسماح للتطبيق بتعديل محتويات وحدة تخزين الوسائط الداخلية."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"إدارة السعة التخزينية للمستند"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"السماح للتطبيق بإدارة السعة التخزينية للمستند."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"الوصول إلى سعة التخزين الخارجية لجميع المستخدمين"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"للسماح للتطبيق بالدخول إلى سعة التخزين الخارجية لجميع المستخدمين."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"الدخول إلى نظام ملفات ذاكرة التخزين المؤقت"</string>
@@ -625,10 +660,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"للسماح لتطبيق بإدارة سياسات الشبكة وتحديد قواعد متعلقة بالتطبيق."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"تعديل حساب استخدام الشبكة"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"للسماح للتطبيق بتعديل كيفية حساب استخدام الشبكة في التطبيقات. ليس للاستخدام بواسطة التطبيقات العادية."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"تعديل علامات المقابس"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"للسماح للتطبيق بتعديل علامات المقابس لإعادة التوجيه."</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_invokeCarrierSetup" msgid="3699600833975117478">"استدعاء تطبيق التهيئة الذي يوفره مشغل شبكة الجوال"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"للسماح للمالك باستدعاء تطبيق التهيئة الذي يوفره مشغل شبكة الجوال. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"الاستماع إلى ملاحظات حول أحوال الشبكة"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"للسماح للتطبيق بالاستماع إلى ملاحظات حول أحوال الشبكة. لا حاجة إلى هذا مع التطبيقات العادية."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"تعيين قواعد كلمة المرور"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"يمكنك التحكم في الطول والأحرف المسموح بها في كلمات مرور إلغاء تأمين الشاشة."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"مراقبة محاولات إلغاء قفل الشاشة"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +836,7 @@
     <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">"تم تعطيل بطاقة SIM بشكل دائم.\n اتصل بمقدم خدمة اللاسلكي للحصول على بطاقة SIM أخرى."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"زر المقطع الصوتي السابق"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"زر المقطع الصوتي التالي"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"زر الإيقاف المؤقت"</string>
@@ -808,11 +848,11 @@
     <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">%d</xliff:g> مرة."\n\n"الرجاء إعادة المحاولة خلال <xliff:g id="NUMBER_1">%d</xliff:g> ثانية."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"لقد كتبت كلمة المرور <xliff:g id="NUMBER_0">%d</xliff:g> مرة بشكل غير صحيح. "\n\n"أعد المحاولة خلال <xliff:g id="NUMBER_1">%d</xliff:g> ثانية."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"لقد كتبت رقم التعريف الشخصي <xliff:g id="NUMBER_0">%d</xliff:g> مرة بشكل غير صحيح. "\n\n"أعد المحاولة خلال <xliff:g id="NUMBER_1">%d</xliff:g> ثانية."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"لقد رسمت نقش إلغاء التأمين بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. بعد <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة الأخرى، ستُطالب بإلغاء تأمين الجهاز اللوحي باستخدام معلومات تسجيل الدخول إلى Google."\n\n" أعد المحاولة خلال <xliff:g id="NUMBER_2">%d</xliff:g> ثانية."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"لقد رسمت نقش إلغاء التأمين بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. بعد <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة الأخرى، ستُطالب بإلغاء تأمين الهاتف باستخدام معلومات تسجيل الدخول إلى Google."\n\n" أعد المحاولة خلال <xliff:g id="NUMBER_2">%d</xliff:g> ثانية."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"لقد رسمت نقش إلغاء التأمين بطريقة غير صحيحة <xliff:g id="NUMBER_0">%d</xliff:g> مرة.\n\nالرجاء إعادة المحاولة خلال <xliff:g id="NUMBER_1">%d</xliff:g> ثانية."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"لقد كتبت كلمة المرور <xliff:g id="NUMBER_0">%d</xliff:g> مرة بشكل غير صحيح. \n\nأعد المحاولة خلال <xliff:g id="NUMBER_1">%d</xliff:g> ثانية."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"لقد كتبت رقم التعريف الشخصي <xliff:g id="NUMBER_0">%d</xliff:g> مرة بشكل غير صحيح. \n\nأعد المحاولة خلال <xliff:g id="NUMBER_1">%d</xliff:g> ثانية."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"لقد رسمت نقش إلغاء التأمين بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. بعد <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة الأخرى، ستُطالب بإلغاء تأمين الجهاز اللوحي باستخدام معلومات تسجيل الدخول إلى Google.\n\n أعد المحاولة خلال <xliff:g id="NUMBER_2">%d</xliff:g> ثانية."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"لقد رسمت نقش إلغاء التأمين بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. بعد <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة الأخرى، ستُطالب بإلغاء تأمين الهاتف باستخدام معلومات تسجيل الدخول إلى Google.\n\n أعد المحاولة خلال <xliff:g id="NUMBER_2">%d</xliff:g> ثانية."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"لقد حاولت إلغاء تأمين الجهاز اللوحي <xliff:g id="NUMBER_0">%d</xliff:g> من المرات. بعد <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة، ستتم إعادة تعيين الجهاز اللوحي إلى الإعدادات الافتراضية للمصنع وسيتم فقد جميع بيانات المستخدم."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"لقد حاولت إلغاء تأمين الهاتف <xliff:g id="NUMBER_0">%d</xliff:g> من المرات. بعد <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة، ستتم إعادة تعيين الهاتف إلى الإعدادات الافتراضية للمصنع وسيتم فقد جميع بيانات المستخدم."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"لقد حاولت إلغاء تأمين الجهاز اللوحي <xliff:g id="NUMBER">%d</xliff:g> من المرات بشكل غير صحيح. سيتم الآن إعادة تعيين الجهاز اللوحي إلى الإعدادات الافتراضية للمصنع."</string>
@@ -826,7 +866,7 @@
     <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_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>
@@ -874,7 +914,7 @@
     <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="autofill_this_form" msgid="4616758841157816676">"ملء تلقائي"</string>
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"للأسف، توقف <xliff:g id="APPLICATION">%1$s</xliff:g>."</string>
     <string name="aerr_process" msgid="4507058997035697579">"للأسف، توقفت العملية <xliff:g id="PROCESS">%1$s</xliff:g>."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> لا يستجيب."\n\n"هل تريد إغلاقه؟"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"النشاط <xliff:g id="ACTIVITY">%1$s</xliff:g> لا يستجيب."\n\n"هل تريد إغلاقه؟"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> لا يستجيب.\n\nهل تريد إغلاقه؟"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"النشاط <xliff:g id="ACTIVITY">%1$s</xliff:g> لا يستجيب.\n\nهل تريد إغلاقه؟"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> لا يستجيب. هل تريد إغلاقه؟"</string>
-    <string name="anr_process" msgid="6513209874880517125">"العملية <xliff:g id="PROCESS">%1$s</xliff:g> لا تستجيب."\n\n"هل تريد إغلاقها؟"</string>
+    <string name="anr_process" msgid="6513209874880517125">"العملية <xliff:g id="PROCESS">%1$s</xliff:g> لا تستجيب.\n\nهل تريد إغلاقها؟"</string>
     <string name="force_close" msgid="8346072094521265605">"موافق"</string>
     <string name="report" msgid="4060218260984795706">"إرسال تقرير"</string>
     <string name="wait" msgid="7147118217226317732">"انتظار"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"أصبحت الصفحة لا تستجيب."\n\n"هل تريد إغلاقها؟"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"أصبحت الصفحة لا تستجيب.\n\nهل تريد إغلاقها؟"</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>
@@ -1256,6 +1296,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"للسماح باستدعاء خدمة الحاوية الافتراضية لنسخ المحتوى. ليس للاستخدام بواسطة التطبيقات العادية."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"توجيه إخراج الوسائط"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"للسماح للتطبيق بتوجيه إخراج الوسائط إلى أجهزة خارجية أخرى."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"الدخول إلى التخزين المحمي بقفل المفاتيح"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"السماح لأحد التطبيقات بالدخول إلى التخزين المحمي بقفل المفاتيح."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"التحكم في عرض وإخفاء قفل المفاتيح"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"للسماح لأحد التطبيقات بالتحكم في قفل المفاتيح."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"المس مرتين للتحكم في التكبير/التصغير"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"تعذرت إضافة أداة."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"تنفيذ"</string>
@@ -1265,15 +1309,15 @@
     <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">"طلب رقم"\n"باستخدام <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"إنشاء جهة اتصال"\n"باستخدام <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"طلب رقم\nباستخدام <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"إنشاء جهة اتصال\nباستخدام <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"يطلب التطبيق أو التطبيقات التالية الإذن للدخول إلى حسابك، الآن وفي المستقبل."</string>
     <string name="grant_credentials_permission_message_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">"الإذن مطلوب"\n"للحساب <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"الإذن مطلوب\nللحساب <xliff:g id="ACCOUNT">%s</xliff:g>."</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>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"عرض الكل"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"اختيار نشاط"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"مشاركة مع"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"تم تأمين الجهاز."</string>
     <string name="list_delimeter" msgid="3975117572185494152">"، "</string>
     <string name="sending" msgid="3245653681008218030">"جارٍ الإرسال..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"تشغيل المتصفح؟"</string>
@@ -1441,10 +1484,12 @@
     <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>
+    <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_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>، <xliff:g id="DPI">%4$d</xliff:g> نقطة لكل بوصة"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">"آمن"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"تم التوصيل بشاشة لاسلكية"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"يتم عرض هذه الشاشة على جهاز آخر"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"قطع الاتصال"</string>
@@ -1453,7 +1498,7 @@
     <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_too_many_failed_attempts_countdown" msgid="6358110221603297548">"حاول مرة أخرى خلال <xliff:g id="NUMBER">%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">"أدخل رقم التعريف الشخصي لبطاقة SIM"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"أدخل رقم التعريف الشخصي"</string>
@@ -1473,27 +1518,85 @@
     <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_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">%d</xliff:g> مرة. "\n\n"أعد المحاولة خلال <xliff:g id="NUMBER_1">%d</xliff:g> ثانية."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"لقد كتبت كلمة المرور بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. "\n\n"أعد المحاولة خلال <xliff:g id="NUMBER_1">%d</xliff:g> ثانية."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"لقد رسمت نقش إلغاء التأمين بطريقة غير صحيحة <xliff:g id="NUMBER_0">%d</xliff:g> مرة. "\n\n"أعد المحاولة خلال <xliff:g id="NUMBER_1">%d</xliff:g> ثانية."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"لقد كتبت رقم التعريف الشخصي بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. \n\nأعد المحاولة خلال <xliff:g id="NUMBER_1">%d</xliff:g> ثانية."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"لقد كتبت كلمة المرور بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. \n\nأعد المحاولة خلال <xliff:g id="NUMBER_1">%d</xliff:g> ثانية."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"لقد رسمت نقش إلغاء التأمين بطريقة غير صحيحة <xliff:g id="NUMBER_0">%d</xliff:g> مرة. \n\nأعد المحاولة خلال <xliff:g id="NUMBER_1">%d</xliff:g> ثانية."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"لقد حاولت إلغاء تأمين الجهاز اللوحي بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة الأخرى، ستتم إعادة تعيين الجهاز اللوحي على الإعدادات الافتراضية للمصنع وسيتم فقد جميع بيانات المستخدم."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"لقد حاولت إلغاء تأمين الهاتف بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة الأخرى، ستطالَب بإلغاء تأمين الجهاز اللوحي باستخدام معلومات حساب بريد إلكتروني."\n\n" أعد المحاولة خلال <xliff:g id="NUMBER_2">%d</xliff:g> ثانية."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"لقد رسمت نقش إلغاء التأمين بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة الأخرى، ستُطالب بإلغاء تأمين الهاتف باستخدام حساب بريد إلكتروني لإلغاء تأمين الهاتف."\n\n" أعد المحاولة خلال <xliff:g id="NUMBER_2">%d</xliff:g> ثانية."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"لقد رسمت نقش إلغاء التأمين بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة الأخرى، ستطالَب بإلغاء تأمين الجهاز اللوحي باستخدام معلومات حساب بريد إلكتروني.\n\n أعد المحاولة خلال <xliff:g id="NUMBER_2">%d</xliff:g> ثانية."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"لقد رسمت نقش إلغاء التأمين بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة الأخرى، ستُطالب بإلغاء تأمين الهاتف باستخدام حساب بريد إلكتروني لإلغاء تأمين الهاتف.\n\n أعد المحاولة خلال <xliff:g id="NUMBER_2">%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="7324161939475478066">"هل تريد رفع مستوى الصوت فوق المستوى الموصى به؟"\n"قد يضر سماع صوت عالٍ لفترات طويلة بسمعك."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"هل تريد رفع مستوى الصوت فوق المستوى الموصى به؟\nقد يضر سماع صوت عالٍ لفترات طويلة بسمعك."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"اضغط بإصبعين لأسفل مع الاستمرار لتمكين تسهيل الدخول."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"تم تمكين إمكانية الدخول."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"تم إلغاء تسهيل الدخول."</string>
     <string name="user_switched" msgid="3768006783166984410">"المستخدم الحالي <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="app_no_restricted_accounts" msgid="4011285085817350390">"هذا التطبيق لا يتوافق مع حسابات الملفات الشخصية المقيدة"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"لا يتوافق هذا التطبيق مع حسابات الملفات الشخصية المقيدة"</string>
     <string name="app_not_found" msgid="3429141853498927379">"لم يتم العثور على تطبيق يمكنه التعامل مع هذا الإجراء."</string>
     <string name="revoke" msgid="5404479185228271586">"إلغاء"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"ملغاة"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"حدث خطأ أثناء كتابة المحتوى"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"غير معروف"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"أدخل رقم التعريف الشخصي للمشرف"</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>
+    <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">"إنشاء رقم تعريف شخصي لتعديل القيود"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"أرقام التعريف الشخصية لا تتطابق، أعد المحاولة."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"رقم التعريف الشخصي أقصر مما يلزم، يجب ألا يقل عن 4 أرقام. "</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"أعد المحاولة خلال ثانية واحدة."</item>
+    <item quantity="other" msgid="4730868920742952817">"أعد المحاولة خلال <xliff:g id="COUNT">%d</xliff:g> ثانية"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"أعد المحاولة لاحقًا"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"مرر سريعًا لحافة الشاشة لإظهار الشريط"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"مرر سريعًا من حافة الشاشة لإظهار شريط النظام"</string>
 </resources>
diff --git a/core/res/res/values-az-rAZ/strings.xml b/core/res/res/values-az-rAZ/strings.xml
new file mode 100644
index 0000000..2f0781c
--- /dev/null
+++ b/core/res/res/values-az-rAZ/strings.xml
@@ -0,0 +1,1589 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<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="5973789783504771878">"KB"</string>
+    <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
+    <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
+    <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
+    <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
+    <string name="untitled" msgid="4638956954852782576">"Başlıqsız"</string>
+    <string name="ellipsis" msgid="7899829516048813237">"..."</string>
+    <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
+    <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Telefon nömrəsi yoxdur)"</string>
+    <string name="unknownName" msgid="2277556546742746522">"(Naməlum)"</string>
+    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Səsli poçt"</string>
+    <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
+    <string name="mmiError" msgid="5154499457739052907">"Bağlantı problemi və ya yalnış MM kodu."</string>
+    <string name="mmiFdnError" msgid="5224398216385316471">"Əməliyyat yalnız sabit nömrələrə yığımla məhdudlaşıb."</string>
+    <string name="serviceEnabled" msgid="8147278346414714315">"Servis işə salındı."</string>
+    <string name="serviceEnabledFor" msgid="6856228140453471041">"Xidmət aktiv edilmişdir:"</string>
+    <string name="serviceDisabled" msgid="1937553226592516411">"Xidmət deaktiv edilib."</string>
+    <string name="serviceRegistered" msgid="6275019082598102493">"Qeydiyyat uğurlu oldu."</string>
+    <string name="serviceErased" msgid="1288584695297200972">"Silinmə uğurlu olmuşdur."</string>
+    <string name="passwordIncorrect" msgid="7612208839450128715">"Yanlış parol"</string>
+    <string name="mmiComplete" msgid="8232527495411698359">"MMI tamamdır."</string>
+    <string name="badPin" msgid="9015277645546710014">"Daxil etdiyiniz köhnə PİN düzgün deyil."</string>
+    <string name="badPuk" msgid="5487257647081132201">"Daxil etdiyiniz PUK düzgün deyil."</string>
+    <string name="mismatchPin" msgid="609379054496863419">"Daxil etdiyiniz PİN kodlar uyğun gəlmir."</string>
+    <string name="invalidPin" msgid="3850018445187475377">"4-dən 8-ə qədər rəqəmi olan PIN yazın."</string>
+    <string name="invalidPuk" msgid="8761456210898036513">"8 və daha çox rəqəmi olan PUK yazın."</string>
+    <string name="needPuk" msgid="919668385956251611">"Sizin SİM kart PUK ilə kilidlənib. Onu açmaq üçün PUK kodu yazın."</string>
+    <string name="needPuk2" msgid="4526033371987193070">"SIM kartın kilidini açmaq üçün PUK2 yazın"</string>
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
+    <string name="ClipMmi" msgid="6952821216480289285">"Daxil olan zəng edənin ID\'si"</string>
+    <string name="ClirMmi" msgid="7784673673446833091">"Gedən Zəng ID"</string>
+    <string name="CfMmi" msgid="5123218989141573515">"Zəng yönləndirmə"</string>
+    <string name="CwMmi" msgid="9129678056795016867">"Zəng gözləyir"</string>
+    <string name="BaMmi" msgid="455193067926770581">"Zəng qadağası"</string>
+    <string name="PwdMmi" msgid="7043715687905254199">"Parolu dəyiş"</string>
+    <string name="PinMmi" msgid="3113117780361190304">"PİN dəyişmək"</string>
+    <string name="CnipMmi" msgid="3110534680557857162">"Hazırdakı nömrəyə zəng edilir"</string>
+    <string name="CnirMmi" msgid="3062102121430548731">"Zənglərin sayı məhdudlaşdırılıb"</string>
+    <string name="ThreeWCMmi" msgid="9051047170321190368">"Üç yollu zəng"</string>
+    <string name="RuacMmi" msgid="7827887459138308886">"Xoşagəlməz zənglərdən imtina"</string>
+    <string name="CndMmi" msgid="3116446237081575808">"Çatdırılma zəngi"</string>
+    <string name="DndMmi" msgid="1265478932418334331">"Narahat etməyin"</string>
+    <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"Adətən zəng edənin ID\'si məhdudlaşdırılır. Növbəti zəng: Məhdudlaşdırılıb"</string>
+    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"Adətən zəng edənin ID\'si məhdudlaşdırılır. Növbəti zəng: Məhdudlaşdırılmayıb"</string>
+    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"Adətən zəng edənin ID\'si məhdudlaşdırılmır. Növbəti zəng: Məhdudlaşdırılıb"</string>
+    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"Adətən zəng edənin ID\'si məhdudlaşdırılmır. Növbəti zəng: Məhdudlaşdırılmayıb"</string>
+    <string name="serviceNotProvisioned" msgid="8614830180508686666">"Xidmət təmin edilməyib."</string>
+    <string name="CLIRPermanent" msgid="3377371145926835671">"Siz zəng edənin ID nizamlarını dəyişə bilməzsiz."</string>
+    <string name="RestrictedChangedTitle" msgid="5592189398956187498">"Məhdudlaşdırılmış keçid dəyişdi"</string>
+    <string name="RestrictedOnData" msgid="8653794784690065540">"Data xidmət bağlıdır."</string>
+    <string name="RestrictedOnEmergency" msgid="6581163779072833665">"Təcili xidmət bağlıdır."</string>
+    <string name="RestrictedOnNormal" msgid="4953867011389750673">"Səs xidməti bağlıdır."</string>
+    <string name="RestrictedOnAllVoice" msgid="3396963652108151260">"Bütün Səs xidmətləri bağlıdır"</string>
+    <string name="RestrictedOnSms" msgid="8314352327461638897">"SMS xidməti bloklanıb."</string>
+    <string name="RestrictedOnVoiceData" msgid="996636487106171320">"Səs/data xidmətləri bloklanıb."</string>
+    <string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Səs/SMS xidmətləri bloklanıb."</string>
+    <string name="RestrictedOnAll" msgid="5643028264466092821">"Bütün səs/data/SMS xidmətləri bağlıdır."</string>
+    <string name="serviceClassVoice" msgid="1258393812335258019">"Səs"</string>
+    <string name="serviceClassData" msgid="872456782077937893">"Məlumat"</string>
+    <string name="serviceClassFAX" msgid="5566624998840486475">"FAKS"</string>
+    <string name="serviceClassSMS" msgid="2015460373701527489">"SMS"</string>
+    <string name="serviceClassDataAsync" msgid="4523454783498551468">"Async"</string>
+    <string name="serviceClassDataSync" msgid="7530000519646054776">"Sinx"</string>
+    <string name="serviceClassPacket" msgid="6991006557993423453">"Paket"</string>
+    <string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
+    <string name="roamingText0" msgid="7170335472198694945">"Rominq göstəricisi işləkdir"</string>
+    <string name="roamingText1" msgid="5314861519752538922">"Rominq göstəricisi işlək deyil"</string>
+    <string name="roamingText2" msgid="8969929049081268115">"Rominq göstəricisi yanır"</string>
+    <string name="roamingText3" msgid="5148255027043943317">"Qonşuluqdan Kənar"</string>
+    <string name="roamingText4" msgid="8808456682550796530">"Binadan kənar"</string>
+    <string name="roamingText5" msgid="7604063252850354350">"Rominq - Arzuolunan sistem"</string>
+    <string name="roamingText6" msgid="2059440825782871513">"Rominq - Mümkün sistem"</string>
+    <string name="roamingText7" msgid="7112078724097233605">"Rominq - Alyans partnyoru"</string>
+    <string name="roamingText8" msgid="5989569778604089291">"Rominq - Premium partnyor"</string>
+    <string name="roamingText9" msgid="7969296811355152491">"Rouminq - Tam Xidmət Funksionallığı"</string>
+    <string name="roamingText10" msgid="3992906999815316417">"Rouminq - Qismən Xidmət Funksionallığı"</string>
+    <string name="roamingText11" msgid="4154476854426920970">"Rouminq Banneri Açıqdır"</string>
+    <string name="roamingText12" msgid="1189071119992726320">"Roaming Banner Off"</string>
+    <string name="roamingTextSearching" msgid="8360141885972279963">"Xidmət axtarılır"</string>
+    <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Yönləndirilmədi"</string>
+    <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
+    <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> saniyə sonra"</string>
+    <string name="cfTemplateRegistered" msgid="5073237827620166285">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Yönləndirilmədi"</string>
+    <string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Yönləndirilmədi"</string>
+    <string name="fcComplete" msgid="3118848230966886575">"Özəllik kodu tamamlandı."</string>
+    <string name="fcError" msgid="3327560126588500777">"Əlaqə problemi və ya yanlış funksiya kodu."</string>
+    <string name="httpErrorOk" msgid="1191919378083472204">"OK"</string>
+    <string name="httpError" msgid="7956392511146698522">"Şəbəkə xətası var idi."</string>
+    <string name="httpErrorLookup" msgid="4711687456111963163">"URL tapıla bilmədi."</string>
+    <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"Sayt autentifikasiya sxemi dəstəklənmir."</string>
+    <string name="httpErrorAuth" msgid="1435065629438044534">"Təsdiq edilə bilmədi."</string>
+    <string name="httpErrorProxyAuth" msgid="1788207010559081331">"Proksi server vasitəsilə təsdiqlənmə uğursuz oldu."</string>
+    <string name="httpErrorConnect" msgid="8714273236364640549">"Serverə qoşula bilmədi."</string>
+    <string name="httpErrorIO" msgid="2340558197489302188">"Serverlə əlaqə alınmadı. Sonra cəhd edin."</string>
+    <string name="httpErrorTimeout" msgid="4743403703762883954">"Server ilə olan əlaqə zaman aşımına məruz qaldı."</string>
+    <string name="httpErrorRedirectLoop" msgid="8679596090392779516">"Bu səhifədə həddindən çox server yönləndirilmələri var."</string>
+    <string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"Protokol dəstəklənmir."</string>
+    <string name="httpErrorFailedSslHandshake" msgid="96549606000658641">"Güvənli bağlantı yaradıla bilmədi."</string>
+    <string name="httpErrorBadUrl" msgid="3636929722728881972">"URL yanlış olduğu üçün səhifəni açmaq mümkün olmadı."</string>
+    <string name="httpErrorFile" msgid="2170788515052558676">"Fayla giriş baş tutmadı."</string>
+    <string name="httpErrorFileNotFound" msgid="6203856612042655084">"Tələb olunan fayl tapılmadı."</string>
+    <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Həddindən çox sorğu işlənilir. Daha sonra yoxlayın."</string>
+    <string name="notification_title" msgid="8967710025036163822">"<xliff:g id="ACCOUNT">%1$s</xliff:g> üçün giriş xətası"</string>
+    <string name="contentServiceSync" msgid="8353523060269335667">"Sinxronlaşdırma"</string>
+    <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Sinxronlaşdırma"</string>
+    <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Həddindən çox <xliff:g id="CONTENT_TYPE">%s</xliff:g> silinmələri var."</string>
+    <string name="low_memory" product="tablet" msgid="6494019234102154896">"Planşetin yaddaşı doludur. Boş yer üçün bəzi faylları silin."</string>
+    <string name="low_memory" product="default" msgid="3475999286680000541">"Telefonun yaddaşı doludur. Boş yer üçün bəzi faylları silin."</string>
+    <string name="me" msgid="6545696007631404292">"Mən"</string>
+    <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Planşet seçimləri"</string>
+    <string name="power_dialog" product="default" msgid="1319919075463988638">"Telefon seçimləri"</string>
+    <string name="silent_mode" msgid="7167703389802618663">"Səssiz rejim"</string>
+    <string name="turn_on_radio" msgid="3912793092339962371">"Simsizi işə salın"</string>
+    <string name="turn_off_radio" msgid="8198784949987062346">"Simsiz rabitəni söndürün"</string>
+    <string name="screen_lock" msgid="799094655496098153">"Ekran kilidi"</string>
+    <string name="power_off" msgid="4266614107412865048">"Söndür"</string>
+    <string name="silent_mode_silent" msgid="319298163018473078">"Zəng deaktivdir"</string>
+    <string name="silent_mode_vibrate" msgid="7072043388581551395">"Zəng vibrasiyadadır"</string>
+    <string name="silent_mode_ring" msgid="8592241816194074353">"Zəngvuran açıqdır"</string>
+    <string name="shutdown_progress" msgid="2281079257329981203">"Söndürülür..."</string>
+    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Planşetiniz sönəcək."</string>
+    <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Telefonunuz sönəcək."</string>
+    <string name="shutdown_confirm_question" msgid="2906544768881136183">"Söndürmək istəyirsiz?"</string>
+    <string name="reboot_safemode_title" msgid="7054509914500140361">"Təhlükəsiz rejimdə yenidən başlayın"</string>
+    <string name="reboot_safemode_confirm" msgid="55293944502784668">"Təhlükəsiz rejimdə yenidən başlamaq istəyirsiniz mi? Bu, quraşdırdığınız bütün üçüncü tərəf tətbiqlərini deaktiv edəcək."</string>
+    <string name="recent_tasks_title" msgid="3691764623638127888">"Son"</string>
+    <string name="no_recent_tasks" msgid="8794906658732193473">"Heç bir son tətbiq yoxdur."</string>
+    <string name="global_actions" product="tablet" msgid="408477140088053665">"Planşet seçimləri"</string>
+    <string name="global_actions" product="default" msgid="2406416831541615258">"Telefon seçimləri"</string>
+    <string name="global_action_lock" msgid="2844945191792119712">"Ekran kilidi"</string>
+    <string name="global_action_power_off" msgid="4471879440839879722">"Söndür"</string>
+    <string name="global_action_bug_report" msgid="7934010578922304799">"Baq hesabatı"</string>
+    <string name="bugreport_title" msgid="2667494803742548533">"Baqı xəbər verin"</string>
+    <string name="bugreport_message" msgid="398447048750350456">"Bu, sizin hazırkı cihaz durumu haqqında məlumat toplayacaq ki, elektron məktub şəklində göndərsin. Baq raportuna başlamaq üçün bir az vaxt lazım ola bilər, bir az səbr edin."</string>
+    <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Səssiz rejim"</string>
+    <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Səs qapalıdır"</string>
+    <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Səs Aktivdir"</string>
+    <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Təyyarə rejimi"</string>
+    <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Uçuş rejimi açıqdır"</string>
+    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Təyyarə rejimi qapalıdır"</string>
+    <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
+    <string name="safeMode" msgid="2788228061547930246">"Təhlükəsiz rejim"</string>
+    <string name="android_system_label" msgid="6577375335728551336">"Android sistemi"</string>
+    <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Ödənişli xidmətlər"</string>
+    <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Xərc tutulacaq əməliyyatlar edir"</string>
+    <string name="permgrouplab_messages" msgid="7521249148445456662">"Sizin mesajlarınız"</string>
+    <string name="permgroupdesc_messages" msgid="7821999071003699236">"SMS, elektron poçt və digər mesajları oxuyur və yazır."</string>
+    <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Şəxsi məlumatınız"</string>
+    <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"Kontakt kartınızda saxlanılan məlumatlarınıza birbaşa giriş."</string>
+    <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Sosial məlumatınız"</string>
+    <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Kontaktlarınız və sosial əlaqələriniz haqqında məlumata birbaşa giriş."</string>
+    <string name="permgrouplab_location" msgid="635149742436692049">"Yerləşməniz"</string>
+    <string name="permgroupdesc_location" msgid="5704679763124170100">"Fiziki adresinizi monitorinq edir."</string>
+    <string name="permgrouplab_network" msgid="5808983377727109831">"Şəbəkə kommunikasiyası"</string>
+    <string name="permgroupdesc_network" msgid="4478299413241861987">"Müxtəlif şəbəkə xüsusiyyətlərinə daxil ol."</string>
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"Bluetooth"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"Bluetooth üzərindən cihazlara və şəbəkələrə daxil ol."</string>
+    <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"Audio Ayarlar"</string>
+    <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"Audio ayarları dəyişin."</string>
+    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Batareyaya təsir edir"</string>
+    <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Batareyanızın tez qurtarmasına səbəb olan funksiyalar istifadə edir"</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"Təqvim"</string>
+    <string name="permgroupdesc_calendar" msgid="5777534316982184416">"Təqvimə və tədbirlərə birbaşa giriş."</string>
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"İstifadəçi Lüğətini Oxu"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"İstifadəçi lüğətindəki sözləri oxuyur."</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"İstifadəçi Lüğətini Yaz"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"İstifadəçi lüğətinə sözlər əlavə edin."</string>
+    <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Əlfəcinlər və Tarixçə"</string>
+    <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Əlfəcinlərə və brauzer tarixinə birbaşa icazə."</string>
+    <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"Zəng"</string>
+    <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"Alarm qur."</string>
+    <string name="permgrouplab_voicemail" msgid="4162237145027592133">"Səsli poçt"</string>
+    <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"Səs poçtuna birbaşa çıxış."</string>
+    <string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
+    <string name="permgroupdesc_microphone" msgid="7106618286905738408">"Audio yazmaq üçün mikrofona birbaşa giriş."</string>
+    <string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
+    <string name="permgroupdesc_camera" msgid="2933667372289567714">"Şəkil və ya video çəkmək üçün kameraya birbaşa çıxış."</string>
+    <string name="permgrouplab_screenlock" msgid="8275500173330718168">"Ekran kilidi"</string>
+    <string name="permgroupdesc_screenlock" msgid="7067497128925499401">"Cihazınızdakı kilid ekranının hərəkətinə təsir etmə bacarığı"</string>
+    <string name="permgrouplab_appInfo" msgid="8028789762634147725">"Tətbiq məlumatlarınız"</string>
+    <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"Cihazınızdakı digər tətbiqlərin davranışına təsir etmək bacarığı."</string>
+    <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"Divar kağızı"</string>
+    <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"Cihazın divar kağızı ayarlarını dəyişin."</string>
+    <string name="permgrouplab_systemClock" msgid="406535759236612992">"Saat"</string>
+    <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"Cihazın vaxt və zaman zolağını dəyişir."</string>
+    <string name="permgrouplab_statusBar" msgid="2095862568113945398">"Status paneli"</string>
+    <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"Cihazın status paneli ayarlarınızı dəyişir."</string>
+    <string name="permgrouplab_syncSettings" msgid="3341990986147826541">"Sinx Ayarları"</string>
+    <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"Sinxronizasiya nizamlarına çıxış."</string>
+    <string name="permgrouplab_accounts" msgid="3359646291125325519">"Hesablarınız"</string>
+    <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Əlçatımlı hesablara daxil olun."</string>
+    <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Hardware kontrolları"</string>
+    <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Dəstəkdəki avadanlığa birbaşa giriş."</string>
+    <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Telefon zəngləri"</string>
+    <string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"Telefon zənglərinə nəzarət edin, qeydə alın və idarə edin."</string>
+    <string name="permgrouplab_systemTools" msgid="4652191644082714048">"Sistem alətləri"</string>
+    <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"Aşağı səviyyəli çıxış və sistem idarəetməsi."</string>
+    <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"İnkişaf alətləri"</string>
+    <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"Özəlliklər yalnız tətbiq developerləri üçün lazımdır."</string>
+    <string name="permgrouplab_display" msgid="4279909676036402636">"Digər tətbiq İstifadəçi İnterfeysi"</string>
+    <string name="permgroupdesc_display" msgid="6051002031933013714">"Digər tətbiqlərin İstifadəçi İnterfeysinə təsir edir."</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"Yaddaş"</string>
+    <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"USB yaddaşa daxil ol."</string>
+    <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"SD karta daxil ol."</string>
+    <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"Əlçatımlılıq funksiyaları"</string>
+    <string name="permgroupdesc_accessibilityFeatures" msgid="4205196881678144335">"Yardımçı texnologiya tələb edə biləcəyi funksiyalar."</string>
+    <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Pəncərənin məzmununu əldə edin"</string>
+    <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Əlaqədə olduğunuz pəncərənin məzmununu nəzərdən keçirin."</string>
+    <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Toxunaraq Kəşf et funksiyasını yandırın"</string>
+    <string name="capability_desc_canRequestTouchExploration" msgid="5800552516779249356">"Toxunulan hissələr səsləndiriləcək və ekran jestlərlə idarə oluna biləcək."</string>
+    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"İnkişaf etmiş veb əlçatımlılığı yandırın"</string>
+    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Skriptlər tətbiq məzmununun daha əlçatımlı olması üçün quraşdırıla bilər."</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Yazdığınız mətni izləyin"</string>
+    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Kredit kartı nömrələri və parollar kimi şəxsi məlumatlar daxildir."</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"status panelini deaktivləşdir və ya dəyişdir"</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"Tətbiqə status panelini deaktiv etməyə və ya sistem ikonalarını əlavə etmək və ya silmək imkanı verir."</string>
+    <string name="permlab_statusBarService" msgid="7247281911387931485">"status paneli"</string>
+    <string name="permdesc_statusBarService" msgid="716113660795976060">"Tətbiqə status paneli olmağa imkan verir."</string>
+    <string name="permlab_expandStatusBar" msgid="1148198785937489264">"status panelini genişlətmək və ya yığmaq"</string>
+    <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"Tətbiqə status panelini genişləndirməyə və ya yox etməyə imkan verir."</string>
+    <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"gedən zənglərin marşrutunu dəyişmək"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Tətbiqə zəng etməyə və zəng edilən nömrəni dəyişməyə imkan verir. Zərərli tətbiqlər bundan istifadə edərək gedən zəngləri izləyə, yönləndirə və ya qarşısını ala bilər."</string>
+    <string name="permlab_receiveSms" msgid="8673471768947895082">"SMS qəbul etmək"</string>
+    <string name="permdesc_receiveSms" msgid="6424387754228766939">"Tətbiqə MMS mesajlarını almaq və emal etmək icazəsi verir. Bu o deməkdir ki, tətbiq sizin mesajlarınızı sizə göstərmədən monitorinq edə və ya silə bilər."</string>
+    <string name="permlab_receiveMms" msgid="1821317344668257098">"mətn mesajlarını qəbul edir (MMS)"</string>
+    <string name="permdesc_receiveMms" msgid="533019437263212260">"Tətbiqə MMS mesajlarını qəbul və emal üçün imkan verir. Bu o deməkdir ki, bu tətbiq sizə göstərmədən cihazınıza göndərilən mesajları silə bilər."</string>
+    <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"təcili yayımları qəbul edir"</string>
+    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Tətbiqə təcili yayım mesajlarını qəbul və emal etmək icazəsi verir. Bu icazə ancaq sistem tətbiqləri üçün mümkündür."</string>
+    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"mobil yayım mesajlarını oxuyur"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Tətbiqə sizin telefonunuz tərəfindən alınmış yayım mesajlarını oxuma icazəsi verir. Telefon yayımı bəzi məkanlarda olan fövqəladə hadisələrlə bağlı sizi xəbərdar etmək üçün qəbul edilir. Zərərli tətbiqlər fövqəladə mobil yayım qəbul edildiyi zaman telefonunun performansına və əməliyyatına müdaxilə edə bilər."</string>
+    <string name="permlab_sendSms" msgid="5600830612147671529">"SMS mesajlarını göndərir"</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"Tətbiqə SMS mesajı göndərmə icazəsi verir. Bu gözlənilməyən ödənişlərə səbəb ola bilər. Zərərli tətbiqlər sizin təsdiqiniz olmadan mesaj göndərməklə sizə ödənişə səbəb ola bilərlər."</string>
+    <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"mesajla cavab verilməli tədbirlər göndərmək"</string>
+    <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"Tətbiqə zənglər üçün \"mesajla cavabla\" hadisələrini idarə etmək üçün digər mesajlaşma tətbiqlərinə sorğuların göndərilməsi icazəsi verir."</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"tekst mesajlarınızı oxuyur (SMS və ya MMS)"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Tətbiqə planşetinizdə və ya SIM kartınızda saxlanan SMS mesajları oxumağa imkan verir. Bu bütün SMS mesajların, onların məzmunundan və konfidensiallığından asılı olmadan oxunması imkanı deməkdir."</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Tətbiqə telefonunuzda və ya SIM kartınızda saxlanan SMS mesajları oxumağa imkan verir. Bu bütün SMS mesajların, onların məzmunundan və konfidensiallığından asılı olmadan oxunması imkanı deməkdir."</string>
+    <string name="permlab_writeSms" msgid="3216950472636214774">"mətn mesajlarınızı redaktə edir (SMS və ya MMS)"</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Tətbiqə telefonunuzda və ya SİM kartınızda yerləşən SMS mesajlara yazma icazəsi verir. Zərərli tətbiqlər sizin mesajlarınızı silə bilər."</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Tətbiqə telefonunuzda və ya SİM kartınızda yerləşən SMS mesajlara yazma icazəsi verir. Zərərli tətbiqlər sizin mesajlarınızı silə bilər."</string>
+    <string name="permlab_receiveWapPush" msgid="5991398711936590410">"mətn mesajları qəbul etmək (WAP)"</string>
+    <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Tətbiqə WAP mesajlar göndərmək və ya qəbul etmək imkanı verir. Buna mesajları izləmək və Sizə xəbər vermədən silmək imkanları da daxildir."</string>
+    <string name="permlab_getTasks" msgid="6466095396623933906">"işlənən tətbiqlər əldə etmək"</string>
+    <string name="permdesc_getTasks" msgid="7454215995847658102">"Tətbiqə hazırda və az öncə işləyən tapşırıqlar haqqında ətraflı məlumat əldə etməyə imkan verir. Bu da cihazda hansı tətbiqlərin istifadə olunması haqqında məlumatların əldə edilməsinə imkan verir."</string>
+    <string name="permlab_interactAcrossUsers" msgid="7114255281944211682">"istifadəçilər arasında əlaqə qurur"</string>
+    <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Tətbiqə bu cihazdakı digər istifadəçilərlə müxtəlif işləri görməyə icazə verir. Zərərli tətbiqlər bundan istifadəçilər arasındakı qorunmanı pozmaq üçün istifadə edə bilər."</string>
+    <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"bütün istifadəçilər ilə əlaqə saxlamaq üçün tam hüquq"</string>
+    <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"İstifadəçilər arasında bütün mümkün əlaqələrə imkan verir."</string>
+    <string name="permlab_manageUsers" msgid="1676150911672282428">"istifadəçiləri idarə edir"</string>
+    <string name="permdesc_manageUsers" msgid="8409306667645355638">"Tətbiqlərə cihazda olan istifadəçiləri, habelə sorğu göndərmə, yaratma və silmə izni verir."</string>
+    <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"işlənən tətbiqlərin detallarını əldə etmək"</string>
+    <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Tətbiqə hazırda və az öncə işləyən tapşırıqlar haqqında ətraflı məlumat əldə etməyə imkan verir. Zərərli tətbiqlər bundan istifadə edərək şəxsi məlumatları oğurlaya bilər."</string>
+    <string name="permlab_reorderTasks" msgid="2018575526934422779">"işlənən tətbiqlərin sırasını dəyişmək"</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Tətbiqə tapşırıqları ön plandan arxa plana keçirməyə imkan verir. Tətbiq bunu Sizin daxiletməniz olmadan da edə bilər."</string>
+    <string name="permlab_removeTasks" msgid="6821513401870377403">"işlək tətbiqləri dayandırır"</string>
+    <string name="permdesc_removeTasks" msgid="1394714352062635493">"Tətbiqə tapşırıqları silməyə və onların tətbiqlərini məhv etməyə imkan verir. Zərərli tətbiqlər bundan istifadə edərək digər tətbiqlərin işlərini dayandıra bilər."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"fəaliyyət toplularını idarə edin"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Tətbiqə digər tətbiqlərin fəaliyyəti daxilində fəaliyyət toplularını əlavə etmək, silmək və dəyişmək imkanı verir."</string>
+    <string name="permlab_startAnyActivity" msgid="2918768238045206456">"hər hansı bir fəaliyyət başlat"</string>
+    <string name="permdesc_startAnyActivity" msgid="997823695343584001">"İcazə qorunması və ya eksport edilmiş statusdan asılı olmayaraq, tətbiqə hər hansı fəaliyyəti başlatmağa imkan verir."</string>
+    <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"ekran uyğunluğunu yerləşdirir"</string>
+    <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Tətbiqə digər tətbiqlərin ekran uyğunluğunu yoxlamaq imkanı verir. Zərərli tətbiqlər digər tətbiqlərin fəaliyyətini poza bilər."</string>
+    <string name="permlab_setDebugApp" msgid="3022107198686584052">"tətbiq sazlanmasını aktiv edir"</string>
+    <string name="permdesc_setDebugApp" msgid="4474512416299013256">"Tətbiqə digər bir tətbiq üçün sazlamanı açmaq üçün imkan verir. Zərərli tətbiqlər bunu digər tətbiqləri yox etmək üçün istifadə edə bilər."</string>
+    <string name="permlab_changeConfiguration" msgid="4162092185124234480">"sistem ekran nizamlarını dəyiş"</string>
+    <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"Tətbiqə yerli parametrlər və ya şriftin ölçüsü kimi cari konfiqurasiyanı dəyişməyə imkan verir."</string>
+    <string name="permlab_enableCarMode" msgid="5684504058192921098">"avtomobil rejimini aktivləşdirir"</string>
+    <string name="permdesc_enableCarMode" msgid="4853187425751419467">"Tətbiqə avtomobil rejimini aktivləşdirməyə imkan verir."</string>
+    <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"digər tətbiqləri qapatmaq"</string>
+    <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"Tətbiqə başqa tətbiqlərin arxafon proseslərini dayandırmaq icazəsi verir. Bu digər tətbiqlərin dayanmasına səbəb ola bilər."</string>
+    <string name="permlab_forceStopPackages" msgid="2329627428832067700">"Digər tətbiqləri dayanmağa məcbur et"</string>
+    <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"Tətbiqə digər tətbiqləri məcburi şəkildə dayandırmağa imkan verir."</string>
+    <string name="permlab_forceBack" msgid="652935204072584616">"tətbiqi qapanmağa məcbur etmək"</string>
+    <string name="permdesc_forceBack" msgid="3892295830419513623">"Tətbiqə ön planda olan istənilən tətbiqi bağlayaraq geriyə dönməyə imkan verir. Normal tətbiqlər tərəfindən heç vaxt istifadə olunmamalıdır."</string>
+    <string name="permlab_dump" msgid="1681799862438954752">"sistemin daxili durumunu bərpa et"</string>
+    <string name="permdesc_dump" msgid="1778299088692290329">"Tətbiqə sistemin daxili statusunu bərpa etməyə imkan verir. Zərərli tətbiqlər lazım olmadığı halda müxtəlif şəxsi və güvənli məlumatları bərpa edə bilər."</string>
+    <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"ekran kontentini bərpa edir"</string>
+    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Tətbiqə aktiv pəncərənin məzmununu əldə etməyə imkan verir. Zərərli tətbiqlər bundan istifadə edərək pəncərə məzmununu ələ keçirib parollları oxuya bilər."</string>
+    <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"giriş imkanını müvəqqəti açmaq"</string>
+    <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"Tətbiqə cihaza girişi müvəqqəti olaraq aktivləşdirməyə imkan verir. Zərərli tətbiqlər istifadəçi razılığı olmadan girişi aktivləşdirə bilər."</string>
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"pəncərə infosunu bərpa edir"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Tətbiqə pəncərə idarəçisindən gələn windows haqqında olan məlumatı bərpa etməyə imkan verir. Zərərli tətbiqlər daxili sistem istifadəsi üçün nəzərdə tutulan məlumatı bərpa edə bilər."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"tədbirləri filtr edir"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Tətbiqə daxiletmə filtrini qeydiyyat etdirməyə imkan verir, bu filtr bütün istifadəçi tədbirlərini göndərilməmişdən əvvəl filtrdən keçirir. Zərərli tətbiq istifadəçi müdaxiləsi olmadan İstifadəçi İnterfeysi sisteminə nəzarət edə bilər."</string>
+    <string name="permlab_magnify_display" msgid="5973626738170618775">"ekranı böyüdür"</string>
+    <string name="permdesc_magnify_display" msgid="7121235684515003792">"Tətbiqə ekran kontentini böyütmək icazəsi verir. Zərərli tətbiqlər bundan istifadə edərək ekranda kontenti böyüdərək cihazın qeyri-stabilliyinə səbəb ola bilər."</string>
+    <string name="permlab_shutdown" msgid="7185747824038909016">"qismən söndürür"</string>
+    <string name="permdesc_shutdown" msgid="7046500838746291775">"Aktivlik idarəçiliyini qapanmış hala gətirir. Tam qapanmanı həyata keçirmir."</string>
+    <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"tətbiqdən tətbiqə keçidin qarşısını almaq"</string>
+    <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"İstifadəçinin başqa tətbiqə keçməsinin qarşısını alır."</string>
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"cari tətbiq informasiyası əldə etmək"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Sahibinə ekranda öndə olan cari tətbiq haqda gizli məlumatı almaq icazəsi verir."</string>
+    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"işə salınan bütün tətbiqləri izləyir və idarə edir"</string>
+    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Tətbiqə sistemin fəaliyyətləri necə başlatdığını nəzarət və kontrol etməyə imkan verir. Zərərli tətbiqlər sistemi tamamilə kompromis edə bilər. Bu icazə yalnız inkişaf üçündür, heç vaxt normal istifadə üçün deyil."</string>
+    <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"qaldırılmış yayım paketini göndər"</string>
+    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"Tətbiqə tətbiq paketinin silinməsi haqqında bildiriş translasiya etmə icazəsi verir. Zərərli tətbiqlər bundan digər işlək tətbiqləri dayandırmaq üçün istifadə edə bilər."</string>
+    <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"SMS tərəfindən qəbul edilən yayım göndər"</string>
+    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"Tətbiqə mesaj gəlməsi haqqında bildirişi yayımlamaq imkanı verir. Zərərli tətbiqlər bundan gələn SMS mesajlarını saxtalaşdırmaq üçün istifadə edə bilər."</string>
+    <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"WAP-PUSH tərəfindən qəbul edilən yayım göndər"</string>
+    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"Tətbiqə WAP PUSH mesajın alındığı haqda bildiriş translasiya etməyə icazə verir. Zərərli tətbiqlər bundan istifadə edərək saxta MMS mesaj alışı və ya səssizcə istənilən veb səhifəni zərərverici variantlarla dəyişmək üçün istifadə edə bilər."</string>
+    <string name="permlab_setProcessLimit" msgid="2451873664363662666">"çalışan proseslərin sayını məhdudlaşdırır"</string>
+    <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"Tətbiqə işlədiləcək maksimum proses sayını idarə etmə izni verir. Normal tətbiqlər tərəfindən tələb olunmur."</string>
+    <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"arxafon tətbiqlərini dayanmağa məcbur edir"</string>
+    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"Tətbiqə aktivitilərin arxa fona getdiyi zaman bitməsini yoxlayır. Normal tətbiqlər tərəfindən tələn olunmur."</string>
+    <string name="permlab_batteryStats" msgid="2789610673514103364">"batareya statistikalarını oxumaq"</string>
+    <string name="permdesc_batteryStats" msgid="5897346582882915114">"Tətbiqə cari aşağı səviyyəli data sitifadəsini oxumaq imkanı verir. Tətbiqə hansı tətbiqi istifadə etdiyiniz haqqında ətraflı məlumat tapmağa imkan verə bilər."</string>
+    <string name="permlab_updateBatteryStats" msgid="3719689764536379557">"batareya statistikalarını dəyişmək"</string>
+    <string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"Tətbiqə yığılmış batareya statistikasını redaktə etmə icazəsi verir. Normal tətbiqlər tərəfindən istifadə edilmir."</string>
+    <string name="permlab_getAppOpsStats" msgid="1508779687436585744">"tətbiq əməliyyat statistikalarını əldə etmək"</string>
+    <string name="permdesc_getAppOpsStats" msgid="6243887041577912877">"Toplanmış tətbiq əməliyyat statistikalarının bərpa edilməsinə imkan verir. Normal tətbiqlər tərəfindən istifadə üçün deyil."</string>
+    <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"tətbiq əməliyyat statistikasını dəyişmək"</string>
+    <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"Tətbiqə toplanmış tətbiq əməliyyat statistikasını dəyişməyə imkan verir. Normal tətbiqlər tərəfindən istifadə olunmur."</string>
+    <string name="permlab_backup" msgid="470013022865453920">"sistem yedəkləməsi və bərpasını idarə edir"</string>
+    <string name="permdesc_backup" msgid="6912230525140589891">"Tətbiqə sistemi rezerv etməyə və mexanizmi bərpa etməyə imkan verir. Normal tətbiqlər tərəfindən istifadə edilmək üçün nəzərdə tutulmayıb.."</string>
+    <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"tam rezervi təsdiq etmək və ya əməliyyatı bərpa etmək"</string>
+    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"Tətbiqə İstifadəçi İnterfeysi tam rezerv təsdiqini işə salmağa imkan verir. Heç bir tətbiq tərəfindən istifadə olunmamalıdır."</string>
+    <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"icazəsiz pəncərələri görüntüləyir"</string>
+    <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"Tətbiqə daxili sistem interfeysi tərəfindən istifadə edilməsi üçün nəzərdə tutulmuş pəncərələri yaratmağa icazə verir. Normal tətbiqlər tərəfindən istifadə edilmir."</string>
+    <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"digər tətbiqlər üzərində çəkmək"</string>
+    <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"Tətbiqə digər tətbiqlərin və ya onların hissələrinin yuxarısında şəkil çəkməyə imkan verir. Onlar istənilən tətbiqin interfeysinin istifadəsinə müdaxilə edə və ya digər tətbiqlərdə axtardıqlarınızı dəyişə bilər."</string>
+    <string name="permlab_setAnimationScale" msgid="2805103241153907174">"qlobal animasiya sürətini dəyişir"</string>
+    <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"Tətbiqə istənilən vaxt qlobal animasiya sürətini (sürətli və ya yavaş animasiyalar) dəyişdirmək imkanı verir."</string>
+    <string name="permlab_manageAppTokens" msgid="1286505717050121370">"tətbiq nişanlarını idarə etmək"</string>
+    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"Tətbiqlərə onların normal Z-orderinqi keçərək markerlərini yaratma və idarəetmə icazəsi verir. Normal tətbiqlər tərəfindən istifadə olunmur."</string>
+    <string name="permlab_freezeScreen" msgid="4708181184441880175">"ekranı dondurur"</string>
+    <string name="permdesc_freezeScreen" msgid="8558923789222670064">"Tətbiqə tam ekranlı yayım üçün ekranı müvəqqəti olaraq dondurma icazəsi verir."</string>
+    <string name="permlab_injectEvents" msgid="1378746584023586600">"düymələri və idarəetmə düymələrini basır"</string>
+    <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"Tətbiqə özünün daxiletmə tədbirlərini digər tətbiqlərə çatdırmağa imkan verir. Zərərli tətbiqlər planşeti ələ keçirmək üçün bundan istifadə edə bilər."</string>
+    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"Tətbiqə özünün daxiletmə tədbirlərini digər tətbiqlərə çatdırmağa imkan verir. Zərərli tətbiqlər telefonu ələ keçirmək üçün bundan istifadə edə bilər."</string>
+    <string name="permlab_readInputState" msgid="469428900041249234">"yazdıqlarınızı və etdiklərinizi izləyir"</string>
+    <string name="permdesc_readInputState" msgid="8387754901688728043">"Tətbiqə basdığınız düymələri izləmək imkanı verilir. Buna parolların və kredit kartı nömrələrinin yazılması da aiddir. Normal tətbiqlər tərəfindən istifadə olunmur."</string>
+    <string name="permlab_bindInputMethod" msgid="3360064620230515776">"daxiletmə metoduna bağlanır"</string>
+    <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Sahibinə daxiletmə metodunun ən üst səviyyə interfeysinə bağlamaq imkanı verir. Normal tətbiqlər üçün heç vaxt lazım olmamalıdır."</string>
+    <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"giriş xidmətinə bağlı qal"</string>
+    <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Sahibə giriş xidmətin ən üst səviyyə interfeysi bağlamağa imkan verir. Normal tətbiqlər üçün heç vaxt lazım olmamalıdır."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"çap servisini qoşma"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Sahibinə bir çap xidmətinin ən üst səviyə araüzünü bağlamağa imkan verir. Normal tətbiqlər üçün heç vaxt lazım olmamalıdır."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"çap spuler servisinə qoş"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Sahibinə çap spuler xidmətinin ən üst səviyyə interfeysinə bağlamağa imkan verir. Normal tətbiqlər üçün heç vaxt lazım olmamalıdır."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC xidmətlərinə qoşun"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Sahibinə NFC kartlarını emulyasiya edən tətbiqləri bir-birinə qoşmağa icazə verin. Normal tətbiqlər üçün lazım deyil."</string>
+    <string name="permlab_bindTextService" msgid="7358378401915287938">"mətn servisini qoşma"</string>
+    <string name="permdesc_bindTextService" msgid="8151968910973998670">"Sahibinə bir mətn xidmətinin ən üst səviyyə araüzünü bağlamağa imkan verir(məsələn, SpellCheckerService). Normal tətbiqlər üçün heç vaxt lazım olmamalıdır."</string>
+    <string name="permlab_bindVpnService" msgid="4708596021161473255">"VPN xidmətə əlaqələndirmək"</string>
+    <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Sahibinə bir Vpn xidmətinin ən üst səviyyə araüzünü bağlamağa imkan verir. Normal tətbiqlər üçün heç vaxt lazım olmamalıdır."</string>
+    <string name="permlab_bindWallpaper" msgid="8716400279937856462">"divar kağızına bağlanır"</string>
+    <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Cihaz sahibinə yuxarı səviyyəli divar kağızı interfeysini cildləməyə imkan verir. Normal tətbiqlər tərəfindən istifadə olunmamalıdır."</string>
+    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"widget servisini qoşma"</string>
+    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Sahibinə vidcet servisin yüksək səviyyəli interfeysi ilə əlaqə saxlamaq icazəsi verir. Normal tətbiqlər tərəfindən heç vaxt istənilməməlidir."</string>
+    <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"cihaz admini ilə ünsiyyət qurmaq"</string>
+    <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Sahibinə bir cihaz idarəçisinə planlar göndərmək üçün imkan verir. Normal tətbiqlər üçün heç vaxt lazım olmamalıdır."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"cihaz admini əlavə edin və ya silin"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Sahibinə aktiv cihaz administratorlarını əlavə etməyə və ya silməyə icazə verir. Normal tətbiqlər üçün tələb olunmamalıdır."</string>
+    <string name="permlab_setOrientation" msgid="3365947717163866844">"ekran oriyentasiyasını dəyişir"</string>
+    <string name="permdesc_setOrientation" msgid="3046126619316671476">"Tətbiqə istənilən zaman ekranın vəziyyətini dəyişmə icazəsi verir. Normal tətbiqlər tərəfindən tələb olunmur."</string>
+    <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"kursor sürətini dəyişmək"</string>
+    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Tətbiqə mausun və ya trekpedin kursor sürətini istənilən zaman dəyişməyə imkan verir. Normal tətbiqlər tərəfindən istifadə olunmamalıdır."</string>
+    <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"klaviatura sxemini dəyişir"</string>
+    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Tətbiqə klaviatura sxemini dəyişmək imkanı verir. Normal tətbiqlər tərəfindən tələb olunmur."</string>
+    <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"tətbiqlərə Linux siqnalları göndərir"</string>
+    <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Tətbiqə bütün davamlı proseslərə siqnal soğrusu göndərməyə imkan verir."</string>
+    <string name="permlab_persistentActivity" msgid="8841113627955563938">"təbiqi həmişə çalışdır"</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Tətbiqə öz komponentlərini yaddaşda saxlama icazəsi verir. Bu planşetin sürətini zəiflətməklə, digər tətbiqlər üçün mövcud olan yaddaşı limitləyə bilər."</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"Tətbiqə öz komponentlərini yaddaşda saxlama icazəsi verir. Bu digər tətbiqlər üçün mövcud olan yaddaşı limitləyə bilər."</string>
+    <string name="permlab_deletePackages" msgid="184385129537705938">"tətbiqləri sil"</string>
+    <string name="permdesc_deletePackages" msgid="7411480275167205081">"Tətbiqə Android paketləri silmə icazəsi verir. Zərərli tətbiqlər bundan digər vacib tətbiqləri silmək üçün istifadə edə bilər."</string>
+    <string name="permlab_clearAppUserData" msgid="274109191845842756">"digər tətbiqlərin məlumatını silir"</string>
+    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"Tətbiqə istifadəçi datasını təmizləməyə imkan verir."</string>
+    <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"digər tətbiqlərin keşini sil"</string>
+    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"Tətbiqə keş faylları silmə icazəsi verir."</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"tətbiq saxlama yaddaşını ölçmək"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Tətbiqə özünün kodunu, məlumatını və keş ölçüsünü alma icazəsi verir."</string>
+    <string name="permlab_installPackages" msgid="2199128482820306924">"birbaşa tətbiqlər quraşdırmaq"</string>
+    <string name="permdesc_installPackages" msgid="5628530972548071284">"Tətbiqə yeni və ya güncəllənmiş Android paketlərini quraşdırmağa imkan verir. Zərərli tətbiqlər bundan istifadə edərək güclü səlahiyyətlərə malik tətbiqləri endirə bilər."</string>
+    <string name="permlab_clearAppCache" msgid="7487279391723526815">"bütün tətbiq keş datasını silir"</string>
+    <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"Tətbiqə planşetin yaddaşını boşaltmaq üçün digər tətbiqlərin keş fayllarını silmək imkanı verir. Bu da digər tətbiqlərin dataları yenidən əldə etmələri səbəbindən daha yavaş işləmələrinə səbəb ola bilər."</string>
+    <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"Tətbiqə digər tətbiqlərin keş qovluğunu təmizləyərək telefonun yaddaşını boşaltmaq icazəsi verir. Bu digər tətbiqlərin məlumatlarını yenidən əldə etməli olduqlarına görə daha yavaş başlamasına səbəb olur."</string>
+    <string name="permlab_movePackage" msgid="3289890271645921411">"tətbiq resurslarının yerini dəyişir"</string>
+    <string name="permdesc_movePackage" msgid="319562217778244524">"Tətbiqə tətbiq resurslarını daxili mediadan xarici mediaya və əksinə daşımağa imkan verir."</string>
+    <string name="permlab_readLogs" msgid="6615778543198967614">"məxfi loq datasını oxuyur"</string>
+    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Tətbiqə sistemin müxtəlif jurnal fayllarını oxumağa imkan verir. Bu da Sizin planşetdə etdikləriniz haqqında məlumatlar, həmçinin şəxsi və konfidensial məlumatlar ola bilər."</string>
+    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Tətbiqə sistemin müxtəlif jurnal fayllarını oxumağa imkan verir. Bu da Sizin planşetdə etdikləriniz haqqında məlumatlar, həmçinin şəxsi və konfidensial məlumatlar ola bilər."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"oxutmaq üçün istənilən media dekoderi istifadə edir"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Tətbiqə playback\'i deşifrə etmək üçün hər hansı bir quraşdırılmış media deşifrələyicisini istifadə etmık imkanı verir."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"etibarlı etimadnamələri idarə et"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Tətbiqə etibarlı etimadnamələr kimi CA sertifikatlarını quraşdırmaq və sistemdən silməyə icazə verir."</string>
+    <string name="permlab_diagnostic" msgid="8076743953908000342">"diaga məxsus olan mənbələri yaz/oxu"</string>
+    <string name="permdesc_diagnostic" msgid="6608295692002452283">"Tətbiqə diag qrupa məsus olan resursları yazmaq və oxumaq icazəsi verir; məsələn  /dev qovluğundakı fayllar. Bu sistemin stabilliyinə və təhlükəsizliyinə təsir edə bilər. Bu ancaq istehsalçı və ya operator tərəfindən avadanlığa xas diaqnostika üçün olmalıdır."</string>
+    <string name="permlab_changeComponentState" msgid="6335576775711095931">"tətbiq komponentlərini aktivləşdirmə və ya deaktivləşdirmə"</string>
+    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Tətbiqə digər tətbiq komponentinin aktiv olub-olmadığını dəyişmək imkanı verir. Zərərli tətbiqlər bundan əhəmiyyətli planşet imkanlarını deaktiv etmək üçün istifadə edə bilər. Bu icazə ilə ehtiyatlı olmaq lazımdır, çünki tətbiq komponentləri yararsız, ziddiyyətli, və ya qeyri-sabit statusa çevrilə bilər."</string>
+    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Tətbiqə digər tətbiq komponentinin aktiv olub-olmadığını dəyişmək imkanı verir. Zərərli tətbiqlər bundan əhəmiyyətli telefon imkanlarını deaktiv etmək üçün istifadə edə bilər. Bu icazə ilə ehtiyatlı olmaq lazımdır, çünki tətbiq komponentləri yararsız, ziddiyyətli, və ya qeyri-sabit statusa çevrilə bilər."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"icazələr vermək və ya ləğv etmək"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Tətbiqə bu və ya digər tətbiqlərə xüsusi iznlər verməyə icazə verir. Zərərli tətbiqlər  bundan izin vermədiyiniz özəllikləri özlərinə vermək üçün istifadə edə bilər."</string>
+    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"tərcih edilən tətbiqlər qur"</string>
+    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Tətbiqə tərcih etdiyiniz tətbiqləri dəyişmək imkanı verir. Zərərli tətbiqlər şəxsi məlumatlarınızı toplamaq üçün cari tətbiqlərinizi aldadaraq işləyən tətbiqləri xəbərsiz dəyişə bilər."</string>
+    <string name="permlab_writeSettings" msgid="2226195290955224730">"sistem ayarlarında dəyişiklik etmək"</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"Tətbiqə sistem ayarları datasını redaktə etmə icazəsi verir. Zərərli tətbiqlər sistem ayarlarını korlaya bilər."</string>
+    <string name="permlab_writeSecureSettings" msgid="204676251876718288">"təhlükəsiz sistem nizamlarını dəyişir"</string>
+    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"Tətbiqə sistemin təhlükəsiz ayarlar datasını dəyişməyə imkan verir. Normal tətbiqlər tərəfindən istifadə üçün deyil."</string>
+    <string name="permlab_writeGservices" msgid="2149426664226152185">"Google xidmətlər xəritəsini dəyişdir"</string>
+    <string name="permdesc_writeGservices" msgid="1287309437638380229">"Tətbiqə Google xidmətlər xəritəsini dəyişdirmək imkanı verir. Normal tətbiqlərin istifadəsi üçün deyil."</string>
+    <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"başlanğıcda işləyir"</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Tətbiqə sistem yükləməni bitirdiyi zaman dərhal özünü başlatmağa imkan verir. Bu planşeti başlatmağın uzun çəkməsinə səbəb ola bilər və tətbiqə həmişə çalışdıraraq bütün planşeti yavaşlatmağa imkan verir."</string>
+    <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Tətbiqə sistem bootinqi bitirdikdən dərhal sonra özünü başlatmaq icazəsi verir. Bu telefonun açılmasını ləngidə və daima işlək qalaraq telefonun sürətini aşağı sala bilər."</string>
+    <string name="permlab_broadcastSticky" msgid="7919126372606881614">"daimi siqnal göndərmək"</string>
+    <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Tətbiqə yayım bitdikdən sonra da qalan çətin yayımlar göndərməyə imkan verir. Hədsiz istifadə çox yaddaş istifadəsinə səbəb olmaqla planşeti yavaş və qeyri-stabil edə bilər."</string>
+    <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Tətbiqə yayım bitdikdən sonra da qalan çətin yayımlar göndərməyə imkan verir. Hədsiz istifadə çox yaddaş istifadəsinə səbəb olmaqla telefonu yavaş və qeyri-stabil edə bilər."</string>
+    <string name="permlab_readContacts" msgid="8348481131899886131">"kontakrlatınızı oxumaq"</string>
+    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Tətbiqə planşetinizdə yerləşən kontaktları oxumaq icazəsi verir, tez-tez zəng elədiyiniz, emailləşdiyiniz və ya əlaqə saxladığınız xüsusi individuallar daxil olmaqla. Bu icazə tətbiqlərə kontakt məlumatlarınızı saxlamağa və zərərli tətbiqlərə kontakt məlumatlarını sizin bilginiz olmada paylaşma imkanı yaradır."</string>
+    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Tətbiqə tez-tez zəng elədiyiniz, e-məktub göndərdiyiniz və ya əlaqə saxladığınız xüsusi individuallar daxil olmaqla telefonunuzda yerləşən kontaktları oxumaq icazəsi verir. Bu icazə tətbiqlərə kontakt məlumatlarınızı saxlamağa və zərərli tətbiqlərə kontakt məlumatlarını sizin xəbəriniz olmada paylaşma imkanı yaradır."</string>
+    <string name="permlab_writeContacts" msgid="5107492086416793544">"kontaktlarınızı dəyişdirir"</string>
+    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Tətbiqə planşetinizdəki zəng etmək tezliyiniz, elektron poçtlarınız, ünsiyyətləriniz haqqında məlumatları dəyişməyə imkan verir. Bu icazə kontakt məlumatlarının silinməsinə də imkan verir."</string>
+    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Tətbiqə Sizin zəng etmək tezliyiniz, elektron poçtlarınız, ünsiyyətləriniz haqqında məlumatları dəyişməyə imkan verir. Buna kontaktların silinməsi imkanı də daxildir."</string>
+    <string name="permlab_readCallLog" msgid="3478133184624102739">"zəng qeydiyyatını oxu"</string>
+    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Tətbiqə gələn və gedən zənglər haqqında olan data daxil olmaqla bərabər planşetinizin zəng qeydiyyatını oxumağa imkan verir. Bu icazə tətbiqlərə zəng qeydiyyatınızı saxlamağa imkan verir və zərərli tətbiqlər zəng qeydiyyat datasını sizdən xəbərsiz paylaşa bilər."</string>
+    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Tətbiqə telefon jurnalınızı oxumağa imkan verir, buna gələn və gedən zənglər haqqında məlumatlar da daxildir. Bu icazə tətbiqə zəng jurnalı datasını saxlamağa imkan verir ki, Zərərli tətbiqlər bundan istifadə edərək Sizdən xəbərsiz bütün məlumatlarnızı paylaşa bilər."</string>
+    <string name="permlab_writeCallLog" msgid="8552045664743499354">"zəng loqu yazır"</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Tətbiqə planşetinizdəki zəng jurnalını, həmçinin gedən və gələn zənglərin siyahısını dəyişməyə imkan verir. Zərərli tətbiqlər bundan istifadə edərək, zəng jurnalınıza dəyişiklik edə bilər."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Tətbiqə sizin daxil olan və gedən zənglər daxil olmaqla telefon zəngi loqlarınızı redaktə etmək icazəsi verir. Zərərli tətbiqlər bundan telefon loqlarınızı silmək və ya redaktə etmək üçün istifadə edə bilər."</string>
+    <string name="permlab_readProfile" msgid="4701889852612716678">"öz kontakt kartınızı oxuyun"</string>
+    <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Tətbiqə cihazınızda yerləşən adınız və kontakt məlumatlarınız kimi şəxsi profil məlumatlarını oxuma icazəsi verir. Bu o deməkdir ki, tətbiq sizi tanıya və sizin profil məlumatlarınızı başqalarına göndərə bilər."</string>
+    <string name="permlab_writeProfile" msgid="907793628777397643">"sizin kontakt kartınızda dəyişiklik etmək"</string>
+    <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Tətbiqə cihazınızda yerləşən adınız və kontakt məlumatlarınız kimi şəxsi profil məlumatlarını dəyişmək və ya əlavə etmək icazəsi verir. Bu o deməkdir ki, tətbiq sizi tanıya və sizin profil məlumatlarınızı başqalarına göndərə bilər."</string>
+    <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"sosial lentinizi oxuyur"</string>
+    <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Tətbiqə Sizin və dostlarınızın sosial güncəllərini əldə etmək və sinxronizə etmək icazəsi verir. Məlumat paylaşarkən diqqətli olun - konfidensiallıqdan asılı olmayaraq bu, Siz və dostlarınız arasında sosial şəbəkələrdəki danışığı oxumaq imkanı verir. Qeyd: bu icazə bütün sosial şəbəkələrdə icra edilə bilməz."</string>
+    <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"sosial axınınıza yazır"</string>
+    <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Tətbiqə dostlarınızdan sosial yenilənmələri göstərmə icazəsi verir. Məlumat paylaşarkən diqqətli olun - bu dostlarınızdan gələn mesajı emal etməyə izn verir. Qeyd: bu icazə bütün sosial şəbəkələrə şamil olunmaya bilər."</string>
+    <string name="permlab_readCalendar" msgid="5972727560257612398">"təqvim tədbirlərini və konfidensial məlumatları oxuyur"</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Tətbiqə dostlarınızın və əməkdaşlarınızın planşetinizdə yerləşən kalendar tədbirlərini oxumağa icazə verir. Bu tətbiqə konfidensiallıq və ya həssaslıqdan asılı olmayaraq sizin kalendar məlumatlarınızı paylaşmaq və ya saxlamağa imkan yaradır."</string>
+    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Tətbiqə dost və əməkdaşlara məxsus olanlar daxil olmaqla planşetdə yerləşən bütün kalendar tətbiqlərini oxumaq icazəsi verir. Bu tətbiqə konfidensiallıq və ya həssaslıqdan asılı olmayaraq, Sizin kalendar məlumatlarınızı paylaşmaq və ya saxlamaq imkanı yaradır."</string>
+    <string name="permlab_writeCalendar" msgid="8438874755193825647">"cihaz sahibinin icazəsi olmadan təqvim tədbirləri əlavə etmək və ya dəyişmək, bunun haqqında bildirişlər göndərmək"</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Tətbiqə planşetinizdəki tədbirləri dəyişməyə, tədbir əlavə etməyə və ya silməyə imkan verir. Buna Sizin dostlarınızla və həmkarlarınızla birlikdə hazırladığınız tədbirlər də daxildir. Bu, tədbirə Sizin adınızdan və Sizdən xəbərsiz, təqvim sahibi kimi mesaj göndərmək imkanını verir."</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Dostlarınız və həmkarlarınıza məxsus olanlar da daxil olmaqla, tətbiqə telefonunuzdakı tədbirləri dəyişməyə, tədbir əlavə etməyə və ya silməyə imkan verir. Bu, tədbirə Sizin adınızdan və Sizdən xəbərsiz, təqvim sahibi kimi mesaj göndərmək imkanı verir."</string>
+    <string name="permlab_accessMockLocation" msgid="8688334974036823330">"test üçün saxta məkan mənbələri"</string>
+    <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Test üçün saxta məkan mənbələri yaradın və ya yeni məkan provayderi quraşdırın. Bu tətbiqlərə GPS və məkan provayderləri kimi məkan mənbələrindən alınan məkan və/ya statusları yenidən yazmağa icazə verir."</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"əlavə məkan provayderi əmrlərinə çıxış"</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"Tətbiqə əlavə məkan provayderi əmrlərinə daxil olmaq imkanı verir. Bu tətbiqə GPS əməliyyatına və ya digər məkan mənbələrinə mane olmaq imkanı verə bilər."</string>
+    <string name="permlab_installLocationProvider" msgid="6578101199825193873">"Məkan provayderini quraşdırmaq icazəsi"</string>
+    <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"Yeni yerləşmə təchizatçısını test etmək və ya quraşdırmaq üçün mock yerləşmə mənbələri yarat. Bu tətbiqə yerləşmənin və/ya digər yerləşmə mənbələrindən GPS və ya yerləşmə təchizatçıları qayıtmış statusların ləğv etməsinə imkan verir."</string>
+    <string name="permlab_accessFineLocation" msgid="1191898061965273372">"dəqiq yeri (GPS və şəbəkə-əsaslı)"</string>
+    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Qlobal Pozisiya Sistemini və ya şəbəkə qüllələri və Wi-Fi kimi şəbəkə məkanını istifadə edərək tətbiqə Sizin dəqiq yerinizi təyin etməyə imkan verir. Bu məkan xidmətləri aktivləşdirilməlidirlər ki, Siz tətbiqi istifadə edən zaman tətbiq onları istifadə edə bilsin. Tətbiqlər Sizin harada olmağınızı bunun vasitəsilə təyin edəcək, eyni zamanda, bu xidmət əlavə batareya enerjisi apara bilər."</string>
+    <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"təxmini məkan (şəbəkə əsaslı)"</string>
+    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Tətbiqə təxmini yerinizi almaq üçün imkan verir. Bu yer, yerləşmə xidmətləri tərəfindən mobil qüllələr və Wi-Fi kimi şəbəkə yerləşmə mənbələrdən istifadə etməklə əldə edilir. Bu yerləşmə xidmətləri tətbiqin onlardan istifadəsi üçün açıq və cihazınızın onları istifadəsi üçün mövcud olmalıdır. Tətbiqlər bundan sizin təxminən harada olduğunuzu müəyyənləşdirmək üçün istifadə edə bilər."</string>
+    <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"SurfaceFlinger\'ə daxil olmaq"</string>
+    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Tətbiqə aşağı səviyyəli SurfaceFnger özəlliklərini istifadə etməyə icazə verir."</string>
+    <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"freym buferi oxuyur"</string>
+    <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Tətbiqə freym buferinin kontentini oxumaq icazəsi verir."</string>
+    <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Wifi görüntülərini quraşdır"</string>
+    <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Tətbiqə Wifi görüntülərini quraşdırmağa və onlara qoşulmağa imkan verir."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"WiFi görüntülərini dəyişir"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Tətbiqə Wifi displeylərinin aşağı səviyyəli funksiyalarını idarə etmək imkanı verir."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"audio çıxışı alın"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Tətbiqə audio çıxışı almaq və yenidən yönləndirmək imkanı verir."</string>
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"video çıxışı alın"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Tətbiqə video çıxışı almaq və yenidən yönləndirmək imkanı verir."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"təhlükəsiz video çıxışı alın"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Tətbiqə güvənli video çıxışı almaq və yenidən yönləndirmək imkanı verir."</string>
+    <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"audio ayarlarınızı dəyişir"</string>
+    <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Tətbiqə səs və hansı spikerin çıxış üçün istifadə olunduğu kimi qlobal səs ayarlarını dəyişdirməyə imkan verir."</string>
+    <string name="permlab_recordAudio" msgid="3876049771427466323">"səs yaz"</string>
+    <string name="permdesc_recordAudio" msgid="4906839301087980680">"Tətbiqə mikrofonla audio yazmaq icazəsi verir. İcazə tətbiqə sizin təsdiqiniz olmadan istənilən zaman səs yazma izni verir."</string>
+    <string name="permlab_camera" msgid="3616391919559751192">"şəkil və video çəkmək"</string>
+    <string name="permdesc_camera" msgid="8497216524735535009">"Tətbiqə kamera ilə şəkil və video çəkməyə imkan yaradır. Bu icazə tətbiqə sizin təsdiqiniz olmadan kameradan istifadə icazəsi verir."</string>
+    <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"kamera istifadə edildikdə LED göstərici ötürülməsini deaktiv edir"</string>
+    <string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"Öncədən quraşdırılmış sistem tətbiqinə kamera tərəfindən istifadə edilən LED indikatorunu söndürmək icazəsi verir."</string>
+    <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"planşeti daimi olaraq aradan qaldır"</string>
+    <string name="permlab_brick" product="default" msgid="8337817093326370537">"telefonu həmişəlik deaktiv etmək"</string>
+    <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"Tətbiqə planşeti birdəfəlik deaktiv etməyə imkan verir. Bu da çox təhlükəlidir."</string>
+    <string name="permdesc_brick" product="default" msgid="5788903297627283099">"Tətbiqə bütün telefonu birdəfəlik deaktivləşdirməyə imkan verir. Bu çox təhlükəlidir."</string>
+    <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"planşeti yenidən yüklənməyə məcbur edir"</string>
+    <string name="permlab_reboot" product="default" msgid="2898560872462638242">"telefonu yenidən yüklənməyə məcbur edir"</string>
+    <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"Tətbiqə planşeti yenidən yükləməyə məcbur etmək imkanı verir."</string>
+    <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"Tətbiqə telefonu yenidən yükləməyə məcbur etmək üçün imkan verir."</string>
+    <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"USB yaddaş fayl sisteminə daxil olmaq"</string>
+    <string name="permlab_mount_unmount_filesystems" product="default" msgid="4402305049890953810">"SD Kart fayl sisteminə daxil olmaq"</string>
+    <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"Tətbiqə silinəbilən yaddaşları və ya fayl sistemini quraşdırma və ayırma icazəsi verir."</string>
+    <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"USB yaddaşı silir"</string>
+    <string name="permlab_mount_format_filesystems" product="default" msgid="262582698639274056">"SD kartı silir"</string>
+    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"Tətbiqə çıxarıla bilən yaddaşı format etməyə imkan verir."</string>
+    <string name="permlab_asec_access" msgid="3411338632002193846">"daxili yaddaşınız haqqında məlumat əldə etmək"</string>
+    <string name="permdesc_asec_access" msgid="3094563844593878548">"Tətbiqə daxili yaddaş haqqında məlumat almağa imkan verir."</string>
+    <string name="permlab_asec_create" msgid="6414757234789336327">"daxili yaddaş yaratmaq"</string>
+    <string name="permdesc_asec_create" msgid="4558869273585856876">"Tətbiqə daxili yaddaş yaratmaq üçün imkan verir."</string>
+    <string name="permlab_asec_destroy" msgid="526928328301618022">"daxili yaddaşı məhv etmə"</string>
+    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"Tətbiqə daxili yaddaşı məhv etmə icazəsi verir."</string>
+    <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"daxili yaddaşı montaj və ya demontaj etmək"</string>
+    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"Tətbiqə daxili yaddaşı quraşdırma/ayırma icazəsi verir."</string>
+    <string name="permlab_asec_rename" msgid="7496633954080472417">"daxili yaddaşın adını dəyiş"</string>
+    <string name="permdesc_asec_rename" msgid="1794757588472127675">"Tətbiqə daxili yaddaşın adını dəyişmək imkanı verir."</string>
+    <string name="permlab_vibrate" msgid="7696427026057705834">"vibrasiyaya nəzarət edir"</string>
+    <string name="permdesc_vibrate" msgid="6284989245902300945">"Tətbiqə vibratoru idarə etmə icazəsi verir."</string>
+    <string name="permlab_flashlight" msgid="2155920810121984215">"Flash işığını idarə edir"</string>
+    <string name="permdesc_flashlight" msgid="6522284794568368310">"Tətbiqə siqnal işığı na nəzarət etməyə imkan verir."</string>
+    <string name="permlab_manageUsb" msgid="1113453430645402723">"USB cihazlar üçün tərcihləri və icazələri idarə etmək"</string>
+    <string name="permdesc_manageUsb" msgid="7776155430218239833">"Tətbiqə USB cihazlar üçün olan tərcihləri və icazələri idarə etməyə imkan verir."</string>
+    <string name="permlab_accessMtp" msgid="4953468676795917042">"MTP protokol həyata keçirmək"</string>
+    <string name="permdesc_accessMtp" msgid="6532961200486791570">"Kernel MTP drayverə girişə imkan verir ki, MTP USB protokolunu həyata keçirsin."</string>
+    <string name="permlab_hardware_test" msgid="4148290860400659146">"avadanlığı sınaq edir"</string>
+    <string name="permdesc_hardware_test" msgid="6597964191208016605">"Tətbiqə avadanlığı yoxlamaq üçün müxtəlif periferiyaları kontrol etməyə imkan verir."</string>
+    <string name="permlab_callPhone" msgid="3925836347681847954">"telefon nömrələrinə birbaşa zəng edir"</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"Tətbiqə Sizin müdaxiləniz olmadan telefon zəngləri etməyə imkan verir. Zərərli tətbiqlər Sizdən xəbərsiz şəkildə müxtəlif zənglər edərək, Sizə maddi ziyan vura bilər. Qeyd: Bu, tətbiqlərə təcili nömrələrə zəng etməyə icazə vermir."</string>
+    <string name="permlab_callPrivileged" msgid="4198349211108497879">"istənilən nömrəyə birbaşa zəng edir"</string>
+    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"Tətbiqə Sizin müdaxiləniz olmadan, təcili zənglər də daxil olmaqla, istənilən telefon zəngini etməyə imkan verir. Zərərli tətbiqlər bundan istifadə edərək, təcili nömrələrə qanunsuz zəng vurmaqla Sizin üçün hüquqi problemlər yarada bilər."</string>
+    <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"CDMA planşet ayarlarına birbaşa başlamaq"</string>
+    <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"CDMA telefon quraşdırmalarına birbaşa başlamaq"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"Tətbiqə CDMA hazırlığını başlatma icazəsi verir. Zərərli tətbiqlər ehtiyac olmadıqda CDMA hazırlığını başlada bilərlər."</string>
+    <string name="permlab_locationUpdates" msgid="7785408253364335740">"məkan güncəlləmə bildirişlərini idarə edir"</string>
+    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Tətbiqə radiodan gələn məkan güncəllənmələrini aktiv və ya deaktiv etməyə imkan verir. Normal tətbiqlər tərəfindən istifadə olunmur."</string>
+    <string name="permlab_checkinProperties" msgid="7855259461268734914">"qeydiyyat xüsusiyyətlərini əldə edir"</string>
+    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Tətbiqə giriş qeydi servisi tərəfindən yüklənmiş mülkiyyətə girişi oxumaq/yazmaq imkanl verir. Normal tətbiqlər üçün nəzərdə tutulmayıb."</string>
+    <string name="permlab_bindGadget" msgid="776905339015863471">"vidcetlər seç"</string>
+    <string name="permdesc_bindGadget" msgid="8261326938599049290">"Tətbiqə sistemə hansı vidcetin hansı tətbiq tərəfindən istifadə edilə bilməsini deməyə icazə verir. Bu icazəli tətbiqlər şəxsi məlumatlara və digər tətbiqlərə çıxış verə bilər. Normal tətbiqlər tərəfindən istifadə üçün deyil."</string>
+    <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"telefon statusunu dəyişmək"</string>
+    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Tətbiqə cihazın telefon funksiyalarını idarə etmək imkanı verir. Belə icazəli tətbiq Sizi xəbərdar etmədən şəbəkələri qoşa, telefon radiosunu yandırıb-söndürə bilər."</string>
+    <string name="permlab_readPhoneState" msgid="9178228524507610486">"telefon statusunu və identifikasiyanı oxuyur"</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Tətbiqə cihazın telefon funksiyalarına giriş icazəsi verir. Belə icazəli tətbiq bu telefonun nömrəsini və cihaz İD\'ni, zəngin aktiv olub-olmadığını və zəng edilən nömrəni müəyyən edə bilər."</string>
+    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"planşetin yuxu rejiminin qarşısını almaq"</string>
+    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"telefonun yuxu rejiminə keçməsini əngəllə"</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Tətbiqə planşetin yuxu rejimini qadağan etməyə imkan verir."</string>
+    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Tətbiqə telefonun yuxu rejimini qadağan etmək imkanı verir."</string>
+    <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"planşeti yandırma və ya söndürmə"</string>
+    <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"telefonu yandırmaq və ya söndürmək"</string>
+    <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Tətbiqə planşeti yandırmağa və söndürməyə imkan verir."</string>
+    <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"Tətbiqə telefonu yandırıb söndürmə icazəsi verir."</string>
+    <string name="permlab_factoryTest" msgid="3715225492696416187">"zavod test rejimində işləyir"</string>
+    <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"Planşet avadanlığına tam girişə imkan verməklə aşağı səviyyəli istehsalçı sınağı kimi işləyir. Yalnız planşet istehsalçı sınaq rejimində olduqda işləyir."</string>
+    <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"Bir aşağı səviyyəli istehsalçı testi kimi çalışdırın, telefon hardware üçün tam giriş imkanı verir. Ancaq telefon, istehsalçı test rejimində çalışdığı zaman aktivdir."</string>
+    <string name="permlab_setWallpaper" msgid="6627192333373465143">"divar kağızı yerləşdirir"</string>
+    <string name="permdesc_setWallpaper" msgid="7373447920977624745">"Tətbiqə sistemə divar kağızı yerləşdirmək icazəsi verir."</string>
+    <string name="permlab_setWallpaperHints" msgid="3278608165977736538">"divar kağızı ölçüsünü verir"</string>
+    <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Tətbiqə sistem divar kağızı ölçüsü göstərişlərini müəyyən etməyə imkan verir."</string>
+    <string name="permlab_masterClear" msgid="2315750423139697397">"fabrik defoltuna sıfırlamaq"</string>
+    <string name="permdesc_masterClear" msgid="3665380492633910226">"Tətbiqə bütün məlumatları, nizamları və quraşdırılmış tətbiqləri silərək sistemi fabrik nizamlarına qaytarmaq imkanı verir."</string>
+    <string name="permlab_setTime" msgid="2021614829591775646">"vaxtı təyin edir"</string>
+    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"Tətbiqə planşetin saat vaxtını dəyişməyə imkan verir."</string>
+    <string name="permdesc_setTime" product="default" msgid="1855702730738020">"Tətbiqə telefonun saat vaxtını dəyişməyə imkan verir."</string>
+    <string name="permlab_setTimeZone" msgid="2945079801013077340">"vaxt zonasını quraşdırır"</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Tətbiqə planşetin vaxt zonasını dəyişmə icazəsi verir."</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Tətbiqə telefon saat zolağını dəyişmək üçün imkan verir."</string>
+    <string name="permlab_accountManagerService" msgid="4829262349691386986">"AccountManagerService kimi davranır"</string>
+    <string name="permdesc_accountManagerService" msgid="1948455552333615954">"Tətbiqə AccountAuthenticators\'ə zəng etməyə imkan verir."</string>
+    <string name="permlab_getAccounts" msgid="1086795467760122114">"cihazda hesabları tapır"</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Tətbiqə planşet tərəfindən bilinən hesabların siyahısını alma icazəsi verir. Bu quraşdırdığınız tətbiqlər tərəfindən yaradılmış istənilən hesab ola bilər."</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Tətbiqə telefonda olan hesabların siyahısını əldə etməyə imkan verir. Buna quraşdırdığınız istənilən tətbiq tərəfindən yaradılan hesablar da aiddir."</string>
+    <string name="permlab_authenticateAccounts" msgid="5265908481172736933">"hesablar yaradır və parollar təyin edir"</string>
+    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"Tətbiqə AccountManager\'in hesab yaratmaq və parol almaq və açmaq daxil olmaqla bərabər, hesab təsdiqləyici imkanlarını istifadə etməyə icazə verir."</string>
+    <string name="permlab_manageAccounts" msgid="4983126304757177305">"hesabları əlavə edir və ya silir"</string>
+    <string name="permdesc_manageAccounts" msgid="8698295625488292506">"Tətbiqə hesabların əlavə olunması və ya silinməsi, həmçinin onların parollarının silinməsi kimi əməliyyatları icra etməyə imkan verir."</string>
+    <string name="permlab_useCredentials" msgid="235481396163877642">"cihazda hesablar istifadə etmək"</string>
+    <string name="permdesc_useCredentials" msgid="7984227147403346422">"Tətbiqə autentifikasiya tokenləri sorğularını göndərməyə icazə verir."</string>
+    <string name="permlab_accessNetworkState" msgid="4951027964348974773">"şəbəkə bağlantılarına baxmaq"</string>
+    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Tətbiqə mövcud olan və qoşulan şəbəkələr kimi qoşulmalar haqqında məlumatı görməyə icazə verir."</string>
+    <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"tam şəbəkə girişi"</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Tətbiqə şəbəkə soketlərini yaratmağa və fərdi şəbəkə protokollarını istifadə etməyə imkan verir. Brauzer və digər tətbiqlər datanın internetə ötürülməsini təmin edən vəsaitlər verir, ona görə də datanın internetə gönrədilməsi üçün bu icazə tələb olunmur."</string>
+    <string name="permlab_writeApnSettings" msgid="505660159675751896">"şəbəkə nizamlarını və trafiki dəyişdirir/qarşısını alır"</string>
+    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Tətbiqə şəbəkə trafikinin qarşısını almaq üçün şəbəkə nizamlarını dəyişmə icazəsi verir, məsələn proksini və ya istənilən APN-in portunu. Zərərli tətbiqlər şəbəkə paketlərini sizin bilginiz olmadan monitorinq edə, yönləndirə və ya redaktə edə bilər."</string>
+    <string name="permlab_changeNetworkState" msgid="958884291454327309">"şəbəkə bağlantısını dəyişir"</string>
+    <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Tətbiqə şəbəkə vəziyyətini dəyişməyə icazə verir."</string>
+    <string name="permlab_changeTetherState" msgid="5952584964373017960">"Sərhədli bağlantını dəyişir"</string>
+    <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Tətbiqə birləşilmiş şəbəkə bağlantısının statusunu dəyişməyə imkan verir."</string>
+    <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"arxafon data istifadəsi ayarını dəyişir"</string>
+    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Tətbiqə fon rejimi nizamlarını dəyişməyə icazə verir."</string>
+    <string name="permlab_accessWifiState" msgid="5202012949247040011">"Wi-Fi bağlantılarına baxmaq"</string>
+    <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Tətbiqə Wi-Fi şəbəkələri haqqında məlumatı görməyə icazə verir, məsələn, Wi-Fi mövcudluğu və qoşulmuş Wi-Fi cihazlarının adları."</string>
+    <string name="permlab_changeWifiState" msgid="6550641188749128035">"Wi-Fi şəbəkəsinə qoşulmaq və ya ayrılmaq"</string>
+    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Tətbiqə Wi-Fi çıxış nöqtəsinə qoşulmaq və ondan ayrılmaq və cihazın Wi-Fi şəbəkə nizamlarını dəyişməyə icazə verir."</string>
+    <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"Wi-Fi Multicast qəbuluna icazə ver"</string>
+    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Tətbiqə Wi-Fi şəbəkədə sizin planşetdən başqa digər multikast adreslərə yönləndirilmiş paketləri almaq icazəsi verir. Bu qeyri-çoxadresli rejimdən fəqli olaraq daha çox enerji işlədir."</string>
+    <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Tətbiqə qrup ünvanlar istifadə etməklə, Wi-Fi şəbəkəsində olan bütün cihazlara göndərilmiş paketləri qəbul etməyə imkan verir. Buna daha çox enerji sərf olunur."</string>
+    <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"Bluetooth ayarlarını əldə edir"</string>
+    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Tətbiqə yerli Bluetooth planşetinin konfiqurasiyasını görməyə və məsafədən cihazları tapmağa və cütləməyə imkan verir."</string>
+    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Tətbiqə lokal Bluetooth telefonunu konfiqurə etməyə və uzaq cihazları kəşf etmək və onlara qoşulmaq icazəsi verir."</string>
+    <string name="permlab_accessWimaxState" msgid="4195907010610205703">"WiMAX\'a qoşul və bağlantını kəs"</string>
+    <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"Tətbiqə WiMAX mövcudluğu və qoşulmuş WiMAX şəbəkələrini təyin etməyə icazə verir."</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"WiMAX vəziyyətini dəyişir"</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Tətbiqə planşeti WiMAX şəbəkələrinə qoşmaq və onlardan ayırmaq icazəsi verir."</string>
+    <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"Tətbiqə telefonu WiMAX şəbəkəsinə qoşmağa və ya WiMAX şəbəkəsindən ayırmağa imkan verir."</string>
+    <string name="permlab_bluetooth" msgid="6127769336339276828">"Bluetooth cihazları ilə cütləndirmək"</string>
+    <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Tətbiqə yerli Bluetooth planşetinin konfiqurasiyasını görməyə və cütlənmiş cihazlarla bağlantılar etməyə və qəbul etməyə imkan verir."</string>
+    <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Tətbiqə Bluetooth və ya telefon konfiqurasiyalarını görməyə və qoşulmuş cihazlarla əlaqə qurmağa və qəbul etməyə icazə verir."</string>
+    <string name="permlab_nfc" msgid="4423351274757876953">"Near Field Communication\'ı kontrol et"</string>
+    <string name="permdesc_nfc" msgid="7120611819401789907">"Tətbiqə Yaxın Məsafə Kommunikasiyası (NFC) teqləri, kartları və oxuyucuları ilə əlaqə qurmağa icazə verir."</string>
+    <string name="permlab_disableKeyguard" msgid="3598496301486439258">"Ekran kilidini deaktiv edir"</string>
+    <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Tətbiqə kilid açarını və təhlükəsizlik parolunu deaktiv etməyə imkan verir. Qanuni misal budur ki, telefon zəng qəbul edən zaman kilidi açır və zəng qurtarandan sonra kilidi bağlayır."</string>
+    <string name="permlab_readSyncSettings" msgid="6201810008230503052">"sinx ayarlarını oxu"</string>
+    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Tətbiqə hesablar üçün sinxronizasiya nizamlarını oxuma icazəsi verir. Məsələn, bu Şəxslər tətbiqinin sinxronizə olunub-olunmadığını təyin edə bilər."</string>
+    <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"sinxronizasiyaya davam edir və onu söndürür"</string>
+    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Tətbiqə hesab üçün sinxronizasiya nizamlarını dəyişməyə icazə verir. Məsələn, bu istifadəçi hesablı Şəxslər tətbiqinin sinxronizasiyasını başlamaq üçün istifadə edilə bilər."</string>
+    <string name="permlab_readSyncStats" msgid="7396577451360202448">"sinxronizasiya statistikasını oxumaq"</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Tətbiqə sync tədbirlərinin tarixçəsi və nə qədər datanın sinx olduğu da daxil olmaqla bərabər, hər hansı bir hesab üçün olan sinx statlarını oxumağa imkan verir."</string>
+    <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"abunə olunmuş xəbərləri oxuyur"</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Tətbiqə hazırda sinxron lentlər haqqında ətraflı məlumat almaq üçün imkan verir."</string>
+    <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"abunə olunmuş xəbərləri yazır"</string>
+    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"Tətbiqə cari sinxronlaşmış lentlərinizə dəyişiklik etmək imkanı verir. Zərərli tətbiqlər sixronlaşmış lentlərinizi dəyişə bilər."</string>
+    <string name="permlab_readDictionary" msgid="4107101525746035718">"lüğətə əlavə etdiyiniz şərtləri oxumaq"</string>
+    <string name="permdesc_readDictionary" msgid="659614600338904243">"Tətbiqə istifadəçinin lüğətdə saxladığı bütün sözləri, adları və frazaları oxumaq icazəsi verir."</string>
+    <string name="permlab_writeDictionary" msgid="2183110402314441106">"istifadəçi lüğətinə sözlər əlavə etmək"</string>
+    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Tətbiqə istifadəçi lüğətinə yeni sözlər yazmağa imkan verir."</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"qorunmuş yaddaşa daxil olmağa cəhd etmək"</string>
+    <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"qorunmuş yaddaşa daxil olmağa cəhd etmək"</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"Tətbiqə gələcək cihazlarda əlçatımlı olacaq USB yaddaş üçün icazə testi etməyə imkan verir."</string>
+    <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"Tətbiqə gələcək cihazlarda mövcud olacaq SD kart üçün icazəni test etmək üçün imkan verir."</string>
+    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"USB yaddaşınızın məzmununu dəyişmək və ya silmək"</string>
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"SD kart kontentlərini dəyişir və ya silir"</string>
+    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Tətbiqə USB yaddaşa yazmağa imkan verir."</string>
+    <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Tətbiqə SD karta yazma icazəsi verir."</string>
+    <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"daxili media yaddaşı kontentini dəyişir/silir"</string>
+    <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Tətbiqə daxili media yaddaşdakı kontenti redaktə etmək icazəsi verir."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"sənəd yaddaşını nizamlayır"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Tətbiqə sənəd yaddaşını idarə etməyə imkan verir."</string>
+    <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"bütün istifadəçilərin xarici yaddaşına daxil ol"</string>
+    <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Tətbiqə bütün istifadəçilər üçün olan xarici yaddaşa giriş imkanı verir."</string>
+    <string name="permlab_cache_filesystem" msgid="5656487264819669824">"keş fayl sisteminə girmək"</string>
+    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Tətbiqə keş fayl sistemini oxumağa və yazmağa icazə verir."</string>
+    <string name="permlab_use_sip" msgid="5986952362795870502">"İnternet zəngləri etmək və ya qəbul etmək"</string>
+    <string name="permdesc_use_sip" msgid="4717632000062674294">"Tətbiqə internet zənglərinin göndərilməsi və qəbul edilməsi üçün SIP servisindən istifadə icazəsi verir."</string>
+    <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"tarixi şəbəkə istifadəsini oxu"</string>
+    <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"Tətbiqə xüsusi şəbəkələr və tətbiqlər üçün tarixi şəbəkə istifadəsini oxumağa icazə verir."</string>
+    <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"şəbəkə siyasətini idarə etmək"</string>
+    <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Tətbiqə şəbəkə qanunlarını və tətbiqin xüsusi qaydalarını idarə etmək imkanı verir."</string>
+    <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"şəbəkə istifadə hesabını dəyişmək"</string>
+    <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Tətbiqə şəbəkə istifadəsinin tətbiqlərə qarşı nizamlarını redaktə etməyə icazə verir. Normal tətbiqlər tərəfindən istifadə edilmir."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"soket işarələrini dəyişin"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Tətbiqə araşdırma üçün soket işarələrini dəyişmək imkanı verir"</string>
+    <string name="permlab_accessNotifications" msgid="7673416487873432268">"bildirişlərə daxil ol"</string>
+    <string name="permdesc_accessNotifications" msgid="458457742683431387">"Tətbiqə bildirişləri əldə etməyə, sınamağa və təmizləməyə imkan verir, buna digər tətbiqlər tərəfindən verilmiş bildirişlər də daxildir."</string>
+    <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"bildiriş dinləmə xidmətinə bağlanır"</string>
+    <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Sahibinə yüksək səviyyəli bildiriş dinləmə servisi ilə əlaqə saxlamağa icazə verir. Normal tətbiqlər tərəfindən heç vaxt istənilməməlidir."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"operator xidmətli konfiurasiya tətbiqinə müraciət edin"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Sahibinə operator xidmətli tətbiq konfiqurasiyasına  müraciət imkanı verir. Normal tətbiqlər üçün tələb olunmamalıdır."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"şəbəkə şəraiti haqqında müşahidələr üçün qulaq asmaq"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Tətbiqə şəbəkə şəraiti üzrə müşahidələr üçün qulaq asmaq imkanı verir. Normal tətbiqlər üçün heç vaxt lazım olmamalıdır."</string>
+    <string name="permlab_hotwordRecognition" msgid="3225080408746361313">"isti söz tanınması tələb et"</string>
+    <string name="permdesc_hotwordRecognition" msgid="3716741260195364252">"Tətbiqə isti söz tanınması tələb etməyə imkan verir. Normal tətbiq üçün lazım ola bilməz."</string>
+    <string name="policylab_limitPassword" msgid="4497420728857585791">"Parol qaydalarını təyin edin"</string>
+    <string name="policydesc_limitPassword" msgid="3252114203919510394">"Ekran kilidini açan şifrələrin uzunluğunu və onlardakı icazə verilən işarələrə nəzarət edir."</string>
+    <string name="policylab_watchLogin" msgid="914130646942199503">"Ekran kilidi cəhdlərini monitorinq et"</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Ekan kilidini açarkən daxil edilmiş yanlış parollara baxın və əgər həddindən çox yanlış parollar daxil edilibsə, planşeti kilidləyin və ya bütün planşet datasını silin."</string>
+    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Ekan kilidini açarkən daxil edilmiş yanlış parollara baxın və əgər həddindən çox yanlış parollar daxil edilibsə, telefonu kilidləyin və ya bütün telefon datasını silin."</string>
+    <string name="policylab_resetPassword" msgid="2620077191242688955">"Ekran kilid parolunu dəyişin"</string>
+    <string name="policydesc_resetPassword" msgid="605963962301904458">"Ekran kilidini açan şifrəni dəyişdirin."</string>
+    <string name="policylab_forceLock" msgid="2274085384704248431">"Ekranı kilidləyin"</string>
+    <string name="policydesc_forceLock" msgid="1141797588403827138">"Ekranın nə vaxt və necə kilidlənməsinə nəzarət edir."</string>
+    <string name="policylab_wipeData" msgid="3910545446758639713">"Bütün məlumatları silin"</string>
+    <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Planşetin datasını xəbərdarlıq olmadan, zavod data sıfırlaması ilə silin."</string>
+    <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Telefonun datasını xəbərdarlıq olmadan, zavod data sıfırlaması ilə silin"</string>
+    <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Cihazın qlobal proksisini ayarlayın"</string>
+    <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Siyasət aktiv olarkən cihazın qlobal proksisini istifadə üçün qurun. Yalnız ilk cihaz admini effektiv qlobal proksini təyin edir."</string>
+    <string name="policylab_expirePassword" msgid="885279151847254056">"Ekran kilidi şifrəsinə son zaman seç"</string>
+    <string name="policydesc_expirePassword" msgid="1729725226314691591">"Ekran kilidi parolunun nə qədər tez-tez dəyişməsini kontrol edin."</string>
+    <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Yaddaş şifrələnməsini ayarlayın"</string>
+    <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"Tətbiq məlumatlarının şifrələnməsini tələb edir."</string>
+    <string name="policylab_disableCamera" msgid="6395301023152297826">"Kameraları dekativ edin"</string>
+    <string name="policydesc_disableCamera" msgid="2306349042834754597">"Bütün cihaz kameralarının istifadəsini əngəllə."</string>
+    <string name="policylab_disableKeyguardFeatures" msgid="266329104542638802">"Klaviatura kilidində funksiyaları deaktiv edin"</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="3467082272186534614">"Klaviatura kilidində bəzi funksiyaların qarşısını alın."</string>
+  <string-array name="phoneTypes">
+    <item msgid="8901098336658710359">"Əsas səhifə"</item>
+    <item msgid="869923650527136615">"Mobil"</item>
+    <item msgid="7897544654242874543">"İş"</item>
+    <item msgid="1103601433382158155">"İş Faksı"</item>
+    <item msgid="1735177144948329370">"Ev Faksı"</item>
+    <item msgid="603878674477207394">"Peycer"</item>
+    <item msgid="1650824275177931637">"Digər"</item>
+    <item msgid="9192514806975898961">"Şəxsi"</item>
+  </string-array>
+  <string-array name="emailAddressTypes">
+    <item msgid="8073994352956129127">"Ana səhifə"</item>
+    <item msgid="7084237356602625604">"İş"</item>
+    <item msgid="1112044410659011023">"Digər"</item>
+    <item msgid="2374913952870110618">"Fərdi"</item>
+  </string-array>
+  <string-array name="postalAddressTypes">
+    <item msgid="6880257626740047286">"Əsas səhifə"</item>
+    <item msgid="5629153956045109251">"İş"</item>
+    <item msgid="4966604264500343469">"Digər"</item>
+    <item msgid="4932682847595299369">"Düzənləyin"</item>
+  </string-array>
+  <string-array name="imAddressTypes">
+    <item msgid="1738585194601476694">"Əsas səhifə"</item>
+    <item msgid="1359644565647383708">"İş"</item>
+    <item msgid="7868549401053615677">"Digər"</item>
+    <item msgid="3145118944639869809">"Fərdi"</item>
+  </string-array>
+  <string-array name="organizationTypes">
+    <item msgid="7546335612189115615">"İş"</item>
+    <item msgid="4378074129049520373">"Digər"</item>
+    <item msgid="3455047468583965104">"Fərdi"</item>
+  </string-array>
+  <string-array name="imProtocols">
+    <item msgid="8595261363518459565">"AIM"</item>
+    <item msgid="7390473628275490700">"Windows Live"</item>
+    <item msgid="7882877134931458217">"Yahoo"</item>
+    <item msgid="5035376313200585242">"Skype"</item>
+    <item msgid="7532363178459444943">"QQ"</item>
+    <item msgid="3713441034299660749">"Google Söhbət"</item>
+    <item msgid="2506857312718630823">"ICQ"</item>
+    <item msgid="1648797903785279353">"Jabber"</item>
+  </string-array>
+    <string name="phoneTypeCustom" msgid="1644738059053355820">"Şəxsi"</string>
+    <string name="phoneTypeHome" msgid="2570923463033985887">"Ev"</string>
+    <string name="phoneTypeMobile" msgid="6501463557754751037">"Mobil"</string>
+    <string name="phoneTypeWork" msgid="8863939667059911633">"İş"</string>
+    <string name="phoneTypeFaxWork" msgid="3517792160008890912">"İş Faksı"</string>
+    <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Ev Faksı"</string>
+    <string name="phoneTypePager" msgid="7582359955394921732">"Peycer"</string>
+    <string name="phoneTypeOther" msgid="1544425847868765990">"Digər"</string>
+    <string name="phoneTypeCallback" msgid="2712175203065678206">"Geriyə zəng"</string>
+    <string name="phoneTypeCar" msgid="8738360689616716982">"Avtomobil"</string>
+    <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Şirkət"</string>
+    <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string>
+    <string name="phoneTypeMain" msgid="6766137010628326916">"Əsas"</string>
+    <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Digər faks"</string>
+    <string name="phoneTypeRadio" msgid="4093738079908667513">"Radio"</string>
+    <string name="phoneTypeTelex" msgid="3367879952476250512">"Teleks"</string>
+    <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY TDD"</string>
+    <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Mobil iş telefonu"</string>
+    <string name="phoneTypeWorkPager" msgid="649938731231157056">"İş Peyceri"</string>
+    <string name="phoneTypeAssistant" msgid="5596772636128562884">"Köməkçi"</string>
+    <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string>
+    <string name="eventTypeCustom" msgid="7837586198458073404">"Fərdi"</string>
+    <string name="eventTypeBirthday" msgid="2813379844211390740">"Doğum günü"</string>
+    <string name="eventTypeAnniversary" msgid="3876779744518284000">"İldönümü"</string>
+    <string name="eventTypeOther" msgid="7388178939010143077">"Digər"</string>
+    <string name="emailTypeCustom" msgid="8525960257804213846">"Fərdi"</string>
+    <string name="emailTypeHome" msgid="449227236140433919">"Əsas səhifə"</string>
+    <string name="emailTypeWork" msgid="3548058059601149973">"İş"</string>
+    <string name="emailTypeOther" msgid="2923008695272639549">"Digər"</string>
+    <string name="emailTypeMobile" msgid="119919005321166205">"Mobil"</string>
+    <string name="postalTypeCustom" msgid="8903206903060479902">"Fərdi"</string>
+    <string name="postalTypeHome" msgid="8165756977184483097">"Əsas səhifə"</string>
+    <string name="postalTypeWork" msgid="5268172772387694495">"İş"</string>
+    <string name="postalTypeOther" msgid="2726111966623584341">"Digər"</string>
+    <string name="imTypeCustom" msgid="2074028755527826046">"Fərdi"</string>
+    <string name="imTypeHome" msgid="6241181032954263892">"Ana səhifə"</string>
+    <string name="imTypeWork" msgid="1371489290242433090">"İş"</string>
+    <string name="imTypeOther" msgid="5377007495735915478">"Digər"</string>
+    <string name="imProtocolCustom" msgid="6919453836618749992">"Şəxsi"</string>
+    <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string>
+    <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string>
+    <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">"Görüşlər"</string>
+    <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">"İş"</string>
+    <string name="orgTypeOther" msgid="3951781131570124082">"Digər"</string>
+    <string name="orgTypeCustom" msgid="225523415372088322">"Fərdi"</string>
+    <string name="relationTypeCustom" msgid="3542403679827297300">"Şəxsi"</string>
+    <string name="relationTypeAssistant" msgid="6274334825195379076">"Köməkçi"</string>
+    <string name="relationTypeBrother" msgid="8757913506784067713">"Qardaş"</string>
+    <string name="relationTypeChild" msgid="1890746277276881626">"Uşaq"</string>
+    <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"Ev yoldaşı"</string>
+    <string name="relationTypeFather" msgid="5228034687082050725">"Ata"</string>
+    <string name="relationTypeFriend" msgid="7313106762483391262">"Dost"</string>
+    <string name="relationTypeManager" msgid="6365677861610137895">"Müdir"</string>
+    <string name="relationTypeMother" msgid="4578571352962758304">"Ana"</string>
+    <string name="relationTypeParent" msgid="4755635567562925226">"Valideyn"</string>
+    <string name="relationTypePartner" msgid="7266490285120262781">"Ortaq"</string>
+    <string name="relationTypeReferredBy" msgid="101573059844135524">"Dəvət edən"</string>
+    <string name="relationTypeRelative" msgid="1799819930085610271">"Qohum"</string>
+    <string name="relationTypeSister" msgid="1735983554479076481">"Bacı"</string>
+    <string name="relationTypeSpouse" msgid="394136939428698117">"Həyat yoldaşı"</string>
+    <string name="sipAddressTypeCustom" msgid="2473580593111590945">"Fərdi"</string>
+    <string name="sipAddressTypeHome" msgid="6093598181069359295">"Əsas səhifə"</string>
+    <string name="sipAddressTypeWork" msgid="6920725730797099047">"İş"</string>
+    <string name="sipAddressTypeOther" msgid="4408436162950119849">"Digər"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PİN kodu daxil edin"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK və yeni PİN kod daxil edin"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK kod"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Yeni PIN kodu"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Şifrə daxil etmək üçün toxunun"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Kilidi açmaq üçün parol yazın"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Kilidi açmaq üçün PIN daxil edin"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Yanlış PIN kodu."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Kilidi açmaq üçün Menyu, sonra 0 basın."</string>
+    <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"Təcili nömrə"</string>
+    <string name="lockscreen_carrier_default" msgid="8963839242565653192">"Xidmət yoxdur."</string>
+    <string name="lockscreen_screen_locked" msgid="7288443074806832904">"Ekran kilidlənib."</string>
+    <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Təcili zəng kilidini açmaq və ya yerləşdirmək üçün Menyu düyməsinə basın."</string>
+    <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Kilidi açmaq üçün Menyu düyməsinə basın."</string>
+    <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Kilidi açmaq üçün model çəkin"</string>
+    <string name="lockscreen_emergency_call" msgid="5347633784401285225">"Təcili zəng"</string>
+    <string name="lockscreen_return_to_call" msgid="5244259785500040021">"Zəngə qayıt"</string>
+    <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Düzdür!"</string>
+    <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Bir də cəhd edin"</string>
+    <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Bir daha cəhd et"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Sifət kilidi cəhdləriniz bitdi"</string>
+    <string name="lockscreen_plugged_in" msgid="8057762828355572315">"Batareya yığılır, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_charged" msgid="321635745684060624">"Dolub"</string>
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_low_battery" msgid="1482873981919249740">"Elektrikə qoşun."</string>
+    <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"SIM kart yoxdur."</string>
+    <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Planşetdə SIM kart yoxdur."</string>
+    <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"Telefonda SİM kart yoxdur."</string>
+    <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"SİM kart daxil edin."</string>
+    <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SİM kart yoxdur və ya oxuna bilinmir. SİM kart daxil edin."</string>
+    <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Yararsız SIM kart."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Sizin SİM kartınız daimi olaraq deaktivləşib.\n Başqa SİM kart üçün simsiz xidmət provayderinizə müraciət edin."</string>
+    <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Əvvəlki trek düyməsi"</string>
+    <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Növbəti trek düyməsi"</string>
+    <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Pauza düyməsi"</string>
+    <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Oxutma düyməsi"</string>
+    <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Dayandırma düyməsi"</string>
+    <string name="emergency_calls_only" msgid="6733978304386365407">"Yalnız təcili zənglər"</string>
+    <string name="lockscreen_network_locked_message" msgid="143389224986028501">"Şəbəkə kilidlidir"</string>
+    <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM kart PUK ilə kilidlənib."</string>
+    <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"İstifadəçi Təlimatlarına baxın və ya Müştəri Xidmətlərinə müraciət edin."</string>
+    <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM kart kilidlənib."</string>
+    <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SİM kartın kilidi açılır..."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Siz kilid modelini <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış çəkdiniz. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> saniyə içində yenidən sınayın."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Şifrənizi <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış daxil etdiniz.\n\n <xliff:g id="NUMBER_1">%d</xliff:g> saniyə ərzində yenidən yoxlayın"</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Siz PIN nömrənizi <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış daxil etdiniz. \n \n <xliff:g id="NUMBER_1">%d</xliff:g> saniyə içində təkrar sınayın."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Siz kilidi açmaq üçün şablonu <xliff:g id="NUMBER_0">%d</xliff:g> dəfə səhv çəkdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> daha uğursuz cəhddən sonra planşetin kilidini Google hesabınıza daxil olmaqla açmağınız istəniləcək.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> saniyə ərzində bir daha yoxlayın."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Siz kilidi açmaq üçün şablonu <xliff:g id="NUMBER_0">%d</xliff:g> dəfə səhv çəkdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> daha uğursuz cəhddən sonra planşetin kilidini Google hesabınıza daxil olmaqla açmağınız tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> saniyə ərzində bir daha yoxlayın."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Siz planşet kilidini açmaq üçün <xliff:g id="NUMBER_0">%d</xliff:g> dəfə uğursuz cəhd etmisiniz. <xliff:g id="NUMBER_1">%d</xliff:g> dəfə də uğursuz cəhd etsəniz, planşet fabrik ayarlarına sıfırlanacaq və bütün məlumatlarınız itəcək."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Siz telefon kilidini açmaq üçün <xliff:g id="NUMBER_0">%d</xliff:g> dəfə uğursuz cəhd etmisiniz. <xliff:g id="NUMBER_1">%d</xliff:g> dəfə də uğursuz cəhd etsəniz, telefon zavod ayarlarına sıfırlanacaq və bütün məlumatlarınız itəcək."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Siz planşetin kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> yanlış cəhd etmisiniz. Planşet artıq defolt zavod halına sıfırlanacaq."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Siz telefonun kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> dəfə səhv cəhd etdiniz. Telefonunuz indi zavod nizamlarına yenilənəcək."</string>
+    <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"<xliff:g id="NUMBER">%d</xliff:g> saniyə ərzində bir daha cəhd edin."</string>
+    <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Şablonu unutdunuz?"</string>
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Hesab kilid açma"</string>
+    <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"Həddindən çox cəhd edildi!"</string>
+    <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"Kilidi açmaq üçün Google hesabınız ilə daxil olun."</string>
+    <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"İstifadəçi adı (e-poçt)"</string>
+    <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Şifrə"</string>
+    <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Daxil olun"</string>
+    <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Yanlış istifadəçi adı və parol."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"İstifadəçi adınızı və ya parolunuzu unutmusunuz?\n "<b>"google.com/accounts/recovery"</b>" linkinə daxil olun."</string>
+    <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Yoxlanır..."</string>
+    <string name="lockscreen_unlock_label" msgid="737440483220667054">"Kilidi aç"</string>
+    <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Səs açıqdır"</string>
+    <string name="lockscreen_sound_off_label" msgid="996822825154319026">"Səs sönülüdür"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Model başlandı"</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Model təmizləndi"</string>
+    <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Xana əlavə edildi"</string>
+    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Model tamamlandı"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d of %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Widget əlavə edin."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Boş"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Kilidi açma sahəsi genişləndi."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Kilidi açma sahəsi çökdü."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> vidcet."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"İstifadəçi selektoru"</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">"Media kontrolları"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Yenidən sıralama vidceti başladıldı."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Vidcetin təkrar sifarişi sona çatdı."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Vidcet <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> silindi."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Kilidi açma sahəsini genişləndir."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Sürüşdürmə kilidi."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Kild açma modeli."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Sifət Kilidi"</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Pin kilid açması."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Şifrə kilidi."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Model sahəsi."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Sürüşdürmə sahəsi."</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="granularity_label_character" msgid="7336470535385009523">"simvol"</string>
+    <string name="granularity_label_word" msgid="7075570328374918660">"söz"</string>
+    <string name="granularity_label_link" msgid="5815508880782488267">"link"</string>
+    <string name="granularity_label_line" msgid="5764267235026120888">"xətt"</string>
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
+    <string name="factorytest_failed" msgid="5410270329114212041">"Zavod testi alınmadı"</string>
+    <string name="factorytest_not_system" msgid="4435201656767276723">"Bu FACTORY_TEST fəaliyyəti yalnızca/sistemdə/tətbiqdə quraşdırılmış paketlər üçün dəstəklənir."</string>
+    <string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST əməliyyatını təsdiqləyən heç bir paket tapılmadı."</string>
+    <string name="factorytest_reboot" msgid="6320168203050791643">"Yenidən yükləyin"</string>
+    <string name="js_dialog_title" msgid="1987483977834603872">"\"<xliff:g id="TITLE">%s</xliff:g>\"dakı səhifədə deyilir:"</string>
+    <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
+    <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Naviqasiyanı Təsdiq edin"</string>
+    <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Bu Səhifəni Tərk edin"</string>
+    <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Bu səhifədə qalın"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nBu səhifədən kənara naviqasiya etmək istədiyinizə əminsiniz mi?"</string>
+    <string name="save_password_label" msgid="6860261758665825069">"Təsdiqlə"</string>
+    <string name="double_tap_toast" msgid="4595046515400268881">"Məsləhət: Böyütmək və kiçiltmək üçün iki dəfə tıklayın."</string>
+    <string name="autofill_this_form" msgid="4616758841157816676">"Avtodoldurma"</string>
+    <string name="setup_autofill" msgid="7103495070180590814">"AvtoDoldurmanı ayarla"</string>
+    <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
+    <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
+    <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
+    <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
+    <string name="autofill_province" msgid="2231806553863422300">"Vilayət"</string>
+    <string name="autofill_postal_code" msgid="4696430407689377108">"Poçt kodu"</string>
+    <string name="autofill_state" msgid="6988894195520044613">"Dövlət"</string>
+    <string name="autofill_zip_code" msgid="8697544592627322946">"Poçt indeksi"</string>
+    <string name="autofill_county" msgid="237073771020362891">"Ölkə"</string>
+    <string name="autofill_island" msgid="4020100875984667025">"Ada"</string>
+    <string name="autofill_district" msgid="8400735073392267672">"Sahə"</string>
+    <string name="autofill_department" msgid="5343279462564453309">"Departament"</string>
+    <string name="autofill_prefecture" msgid="2028499485065800419">"Prefektura"</string>
+    <string name="autofill_parish" msgid="8202206105468820057">"Pariş"</string>
+    <string name="autofill_area" msgid="3547409050889952423">"Sahə"</string>
+    <string name="autofill_emirate" msgid="2893880978835698818">"Əmirlik"</string>
+    <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"Veb əlfəcinlərinizi və tarixçələrinizi oxumaq"</string>
+    <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Tətbiqə Brauzerin daxil olduğu bütün linkləri və bütün Brauzer əlfəcinlərini oxumaq imkanı verir. Qeyd: bu icazə veb brauzer imkanları olan üçüncü tərəf brazuerləri və digər tətbiqlər tərəfindən yerinə yetirilə bilməz."</string>
+    <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"veb əlfəcinləri və tarixçəsi yazmaq"</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Tətbiqə planşetinizdəki brauzer tarixini və əlfəcinləri redaktə etmək icazəsi verir. Bu tətbizə brauzer məlumatlarını silmək və ya redaktə etmək imkanı verə bilər. Qeyd: Bu icazə 3-cü partiya brauzerlərə və ya veb brauzing xüsusiyyətli digər tətbiqlərə şamil olunmaya bilər."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Tətbiqə Brauzer tarixçəsi və telefonunuzda saxlanılan əlfəcinlərə dəyişiklik etmək imkanı verir. Bununla tətbiqlə Brauzer datanızı silə və ya dəyişdirə bilər. Qeyd: bu icazə veb brauzer imkanları olan üçüncü tərəf brazuerləri və digər tətbiqlər tərəfindən yerinə yetirilə bilməz."</string>
+    <string name="permlab_setAlarm" msgid="1379294556362091814">"siqnal qurur"</string>
+    <string name="permdesc_setAlarm" msgid="316392039157473848">"Tətbiqə quraşdırlmış zəngli saata alarm ayarlamağa imkan verir. Bəzi zəngli saat tətbiqləri bu özəlliyi dəstəkləməyə bilər."</string>
+    <string name="permlab_addVoicemail" msgid="5525660026090959044">"Səsli poçt əlavə et"</string>
+    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Tətbiqə səsli poçt qutunuza mesaj əlavə etməyə imkan verir."</string>
+    <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"Brauzerin geolokasiya icazələrini dəyişir"</string>
+    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Tətbiqə Brauzerin geolokasiya icazələrini dəyişməyə imkan verir. Zərərli tətbiqlər bundan istifadə edərək məkan məlumatlarını təsadüfi saytlara göndərə bilər."</string>
+    <string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"paketləri təsdiqlə"</string>
+    <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"Tətbiqə paketin quraşdırılabilən olmasını yoxlamağa imkan verir."</string>
+    <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"paket doğrulayıcıya bağlanır"</string>
+    <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Sahibinə paket yoxlayıcılarına sorğu göndərmək icazəsi verir. Normal tətbiqlər tərəfindən heç vaxt istənilməməlidir."</string>
+    <string name="permlab_serialPort" msgid="546083327654631076">"serial porta çıxır"</string>
+    <string name="permdesc_serialPort" msgid="2991639985224598193">"Sahibinə SerialManager API vasitəsilə serial portlara icazə izni verir."</string>
+    <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"xarici kontent provayderlərinə giriş"</string>
+    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Məzmun provayderlərinə örtükdən daxil olmaq üçün cihaz sahibinə imkan verir. Normal tətbiqlər üçün lazım deyil."</string>
+    <string name="permlab_updateLock" msgid="3527558366616680889">"avtomatik cihaz yenilənmələrini pozur"</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"Sahibinə yeni versiyaya yenilənmək üçün nə vaxt qeyri-interaktiv reboot məlumatını sistemə təklif etmə icazəsi verir."</string>
+    <string name="save_password_message" msgid="767344687139195790">"Brauzerin bu şifrəni yadda saxlamasını istəyirsiz?"</string>
+    <string name="save_password_notnow" msgid="6389675316706699758">"İndi yox"</string>
+    <string name="save_password_remember" msgid="6491879678996749466">"Yadda saxla"</string>
+    <string name="save_password_never" msgid="8274330296785855105">"Heç vaxt"</string>
+    <string name="open_permission_deny" msgid="7374036708316629800">"Bu səhifəni açmaq üçün icazəniz yoxdur."</string>
+    <string name="text_copied" msgid="4985729524670131385">"Mətn panoya kopyalandı."</string>
+    <string name="more_item_label" msgid="4650918923083320495">"Daha çox"</string>
+    <string name="prepend_shortcut_label" msgid="2572214461676015642">"Menyu+"</string>
+    <string name="menu_space_shortcut_label" msgid="2410328639272162537">"boşluq"</string>
+    <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"daxil olun"</string>
+    <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"sil"</string>
+    <string name="search_go" msgid="8298016669822141719">"Axtar"</string>
+    <string name="searchview_description_search" msgid="6749826639098512120">"Axtarış"</string>
+    <string name="searchview_description_query" msgid="5911778593125355124">"Axtarış sorğusu"</string>
+    <string name="searchview_description_clear" msgid="1330281990951833033">"Sorğunu təmizlə"</string>
+    <string name="searchview_description_submit" msgid="2688450133297983542">"Sorğunu göndərin"</string>
+    <string name="searchview_description_voice" msgid="2453203695674994440">"Səsli axtarış"</string>
+    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Toxunaraq Kəşf et funksiyası aktiv edilsin?"</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> Toxunaraq Kəşf Et rejimini aktivləşdirmək istəyir. Toxunaraq Kəşf Et açıldığı zaman, barmağınızın altında nə olduğu haqda olan təsvirləri eşidə və ya görə bilərsiniz və yaplanşetdə insanlarla əlaqəyə keçmək üçün jestlər həyata keçirə bilərsiniz."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> Toxunaraq Kəşf Et rejimini aktivləşdirmək istəyir. Toxunaraq Kəşf Et açıldığı zaman, barmağınızın altında nə olduğu haqda olan təsvirləri eşidə və ya görə bilərsiniz və ya telefonda insanlarla əlaqəyə keçmək üçün jestlər həyata keçirə bilərsiniz"</string>
+    <string name="oneMonthDurationPast" msgid="7396384508953779925">"1 ay öncə"</string>
+    <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"1 ay əvvəl"</string>
+  <plurals name="num_seconds_ago">
+    <item quantity="one" msgid="4869870056547896011">"1 saniyə əvvəl"</item>
+    <item quantity="other" msgid="3903706804349556379">"<xliff:g id="COUNT">%d</xliff:g> saniyə əvvəl"</item>
+  </plurals>
+  <plurals name="num_minutes_ago">
+    <item quantity="one" msgid="3306787433088810191">"1 dəqiqə əvvəl"</item>
+    <item quantity="other" msgid="2176942008915455116">"<xliff:g id="COUNT">%d</xliff:g> dəqiqə əvvəl"</item>
+  </plurals>
+  <plurals name="num_hours_ago">
+    <item quantity="one" msgid="9150797944610821849">"1 saat əvvəl"</item>
+    <item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> saat əvvəl"</item>
+  </plurals>
+  <plurals name="last_num_days">
+    <item quantity="other" msgid="3069992808164318268">"Son <xliff:g id="COUNT">%d</xliff:g> gün"</item>
+  </plurals>
+    <string name="last_month" msgid="3959346739979055432">"Keçən ay"</string>
+    <string name="older" msgid="5211975022815554840">"Köhnə"</string>
+  <plurals name="num_days_ago">
+    <item quantity="one" msgid="861358534398115820">"dünən"</item>
+    <item quantity="other" msgid="2479586466153314633">"<xliff:g id="COUNT">%d</xliff:g> gün əvvəl"</item>
+  </plurals>
+  <plurals name="in_num_seconds">
+    <item quantity="one" msgid="2729745560954905102">"1 saniyə ərzində"</item>
+    <item quantity="other" msgid="1241926116443974687">"<xliff:g id="COUNT">%d</xliff:g> saniyə içində"</item>
+  </plurals>
+  <plurals name="in_num_minutes">
+    <item quantity="one" msgid="8793095251325200395">"1 dəqiqə içində"</item>
+    <item quantity="other" msgid="3330713936399448749">"<xliff:g id="COUNT">%d</xliff:g> dəqiqə ərzində"</item>
+  </plurals>
+  <plurals name="in_num_hours">
+    <item quantity="one" msgid="7164353342477769999">"1 saata"</item>
+    <item quantity="other" msgid="547290677353727389">"<xliff:g id="COUNT">%d</xliff:g> saata"</item>
+  </plurals>
+  <plurals name="in_num_days">
+    <item quantity="one" msgid="5413088743009839518">"sabah"</item>
+    <item quantity="other" msgid="5109449375100953247">"<xliff:g id="COUNT">%d</xliff:g> gün ərzində"</item>
+  </plurals>
+  <plurals name="abbrev_num_seconds_ago">
+    <item quantity="one" msgid="1849036840200069118">"1 saniyə əvvəl"</item>
+    <item quantity="other" msgid="3699169366650930415">"<xliff:g id="COUNT">%d</xliff:g> san əvvəl"</item>
+  </plurals>
+  <plurals name="abbrev_num_minutes_ago">
+    <item quantity="one" msgid="6361490147113871545">"1 dəqiqə əvvəl"</item>
+    <item quantity="other" msgid="851164968597150710">"<xliff:g id="COUNT">%d</xliff:g> dəqiqə əvvəl"</item>
+  </plurals>
+  <plurals name="abbrev_num_hours_ago">
+    <item quantity="one" msgid="4796212039724722116">"1 saat əvvəl"</item>
+    <item quantity="other" msgid="6889970745748538901">"<xliff:g id="COUNT">%d</xliff:g> saat əvvəl"</item>
+  </plurals>
+  <plurals name="abbrev_num_days_ago">
+    <item quantity="one" msgid="8463161711492680309">"dünən"</item>
+    <item quantity="other" msgid="3453342639616481191">"<xliff:g id="COUNT">%d</xliff:g> gün əvvəl"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_seconds">
+    <item quantity="one" msgid="5842225370795066299">"1 san ərzində"</item>
+    <item quantity="other" msgid="5495880108825805108">"<xliff:g id="COUNT">%d</xliff:g> san ərzində"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_minutes">
+    <item quantity="one" msgid="562786149928284878">"1 dəq ərzində"</item>
+    <item quantity="other" msgid="4216113292706568726">"<xliff:g id="COUNT">%d</xliff:g> dəqiqəyə"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_hours">
+    <item quantity="one" msgid="3274708118124045246">"1 saat ərzində"</item>
+    <item quantity="other" msgid="3705373766798013406">"<xliff:g id="COUNT">%d</xliff:g> saata"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_days">
+    <item quantity="one" msgid="2178576254385739855">"sabah"</item>
+    <item quantity="other" msgid="2973062968038355991">"<xliff:g id="COUNT">%d</xliff:g> günə"</item>
+  </plurals>
+    <string name="preposition_for_date" msgid="9093949757757445117">"<xliff:g id="DATE">%s</xliff:g> tarixində"</string>
+    <string name="preposition_for_time" msgid="5506831244263083793">"saat <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="preposition_for_year" msgid="5040395640711867177">"<xliff:g id="YEAR">%s</xliff:g> ilində"</string>
+    <string name="day" msgid="8144195776058119424">"gün"</string>
+    <string name="days" msgid="4774547661021344602">"günlər"</string>
+    <string name="hour" msgid="2126771916426189481">"saat"</string>
+    <string name="hours" msgid="894424005266852993">"saatlar"</string>
+    <string name="minute" msgid="9148878657703769868">"dəq."</string>
+    <string name="minutes" msgid="5646001005827034509">"dəqiqə"</string>
+    <string name="second" msgid="3184235808021478">"sn"</string>
+    <string name="seconds" msgid="3161515347216589235">"san"</string>
+    <string name="week" msgid="5617961537173061583">"həftə"</string>
+    <string name="weeks" msgid="6509623834583944518">"həftə"</string>
+    <string name="year" msgid="4001118221013892076">"il"</string>
+    <string name="years" msgid="6881577717993213522">"il"</string>
+  <plurals name="duration_seconds">
+    <item quantity="one" msgid="6962015528372969481">"1 saniyə"</item>
+    <item quantity="other" msgid="1886107766577166786">"<xliff:g id="COUNT">%d</xliff:g> saniyə"</item>
+  </plurals>
+  <plurals name="duration_minutes">
+    <item quantity="one" msgid="4915414002546085617">"1 dəqiqə"</item>
+    <item quantity="other" msgid="3165187169224908775">"<xliff:g id="COUNT">%d</xliff:g> dəqiqə"</item>
+  </plurals>
+  <plurals name="duration_hours">
+    <item quantity="one" msgid="8917467491248809972">"1 saat"</item>
+    <item quantity="other" msgid="3863962854246773930">"<xliff:g id="COUNT">%d</xliff:g> saat"</item>
+  </plurals>
+    <string name="VideoView_error_title" msgid="3534509135438353077">"Video problemi"</string>
+    <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Bu video bu cihaza strim olunmaq üçün uyğun deyil."</string>
+    <string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Bu video oxumur"</string>
+    <string name="VideoView_error_button" msgid="2822238215100679592">"OK"</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">"günorta"</string>
+    <string name="Noon" msgid="3342127745230013127">"Günorta"</string>
+    <string name="midnight" msgid="7166259508850457595">"gecəyarı"</string>
+    <string name="Midnight" msgid="5630806906897892201">"Gecəyarı"</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">"Hamısını seç"</string>
+    <string name="cut" msgid="3092569408438626261">"Kəs"</string>
+    <string name="copy" msgid="2681946229533511987">"Kopyala"</string>
+    <string name="paste" msgid="5629880836805036433">"Yerləşdir"</string>
+    <string name="replace" msgid="5781686059063148930">"Əvəz et..."</string>
+    <string name="delete" msgid="6098684844021697789">"Sil"</string>
+    <string name="copyUrl" msgid="2538211579596067402">"URL kopyala"</string>
+    <string name="selectTextMode" msgid="1018691815143165326">"Mətn seçin"</string>
+    <string name="textSelectionCABTitle" msgid="5236850394370820357">"Mətn seçimi"</string>
+    <string name="addToDictionary" msgid="4352161534510057874">"Lüğətə əlavə et"</string>
+    <string name="deleteText" msgid="6979668428458199034">"Sil"</string>
+    <string name="inputMethod" msgid="1653630062304567879">"Daxiletmə metodu"</string>
+    <string name="editTextMenuTitle" msgid="4909135564941815494">"Mətn əməliyyatları"</string>
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Yaddaş yeri bitir"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Bəzi sistem funksiyaları işləməyə bilər"</string>
+    <string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> işlənir"</string>
+    <string name="app_running_notification_text" msgid="4653586947747330058">"Daha çox məlumat üçün və ya tətbiqi dayandırmaq üçün toxunun."</string>
+    <string name="ok" msgid="5970060430562524910">"OK"</string>
+    <string name="cancel" msgid="6442560571259935130">"Ləğv et"</string>
+    <string name="yes" msgid="5362982303337969312">"OK"</string>
+    <string name="no" msgid="5141531044935541497">"Ləğv et"</string>
+    <string name="dialog_alert_title" msgid="2049658708609043103">"Diqqət"</string>
+    <string name="loading" msgid="7933681260296021180">"Yüklənir…"</string>
+    <string name="capital_on" msgid="1544682755514494298">"AÇIQ"</string>
+    <string name="capital_off" msgid="6815870386972805832">"QAPALI"</string>
+    <string name="whichApplication" msgid="4533185947064773386">"Əməliyyatı tamamlayın:"</string>
+    <string name="alwaysUse" msgid="4583018368000610438">"Bu fəaliyyət üçün defolt istifadə edin"</string>
+    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Sistem ayarlarında, Tətbiqlərdə və Endirilmişlərdə defoltu təmizləyin."</string>
+    <string name="chooseActivity" msgid="7486876147751803333">"Fəaliyyət seçin"</string>
+    <string name="chooseUsbActivity" msgid="6894748416073583509">"USB cihaz üçün tətbiq seçin"</string>
+    <string name="noApplications" msgid="2991814273936504689">"Heç bir tətbiq bu əməliyyatı apara bilmir."</string>
+    <string name="aerr_title" msgid="1905800560317137752"></string>
+    <string name="aerr_application" msgid="932628488013092776">"Təəssüf ki, <xliff:g id="APPLICATION">%1$s</xliff:g> dayandı."</string>
+    <string name="aerr_process" msgid="4507058997035697579">"Təəssüf ki, <xliff:g id="PROCESS">%1$s</xliff:g> prosesi dayandı."</string>
+    <string name="anr_title" msgid="4351948481459135709"></string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> cavab vermir.\n\nOnu bağlamaq istəyirsiniz?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"<xliff:g id="ACTIVITY">%1$s</xliff:g> aktivitisi cavab vermir. \n\nOnu bağlamaq istəyirsiniz?"</string>
+    <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> cavab vermir. Onu bağlamaq istəyirsiniz?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Proses <xliff:g id="PROCESS">%1$s</xliff:g> cavab vermir. \n \n Onu bağlamaq istəyirsiniz?"</string>
+    <string name="force_close" msgid="8346072094521265605">"OK"</string>
+    <string name="report" msgid="4060218260984795706">"Şikayət edin"</string>
+    <string name="wait" msgid="7147118217226317732">"Gözlə"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Bu səhifə yararsızlaşıb.\n\nBağlamaq istəyirsiz?"</string>
+    <string name="launch_warning_title" msgid="1547997780506713581">"Tətbiq yönləndirildi"</string>
+    <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> indi çalışır."</string>
+    <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilk başladıldı."</string>
+    <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Miqyas"</string>
+    <string name="screen_compat_mode_show" msgid="4013878876486655892">"Həmişə göstər"</string>
+    <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Bunları Sistem ayarlarında yenidən aktivləşdir Yüklənmiş &gt; Tətbiqlər &gt;."</string>
+    <string name="smv_application" msgid="3307209192155442829">"Tətbiq <xliff:g id="APPLICATION">%1$s</xliff:g> (proses <xliff:g id="PROCESS">%2$s</xliff:g>) StrictMode siyasətini pozdu."</string>
+    <string name="smv_process" msgid="5120397012047462446">"<xliff:g id="PROCESS">%1$s</xliff:g> prosesi StrictMode siyasətini pozdu."</string>
+    <string name="android_upgrading_title" msgid="1584192285441405746">"Android təkmilləşdirilir..."</string>
+    <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g> əddədən <xliff:g id="NUMBER_0">%1$d</xliff:g> tətbiq optimallaşır."</string>
+    <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Tətbiqlər başladılır."</string>
+    <string name="android_upgrading_complete" msgid="1405954754112999229">"Yükləmə başa çatır."</string>
+    <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> çalışır"</string>
+    <string name="heavy_weight_notification_detail" msgid="1721681741617898865">"Tətbiqə keçmək üçün toxunun"</string>
+    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Tətbiqlərə keçilsin?"</string>
+    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Bir tətbiq artıq işləyir. Digərini başlatmaq üçün onu dayandırmalısınız."</string>
+    <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g> bölməsinə qayıdın"</string>
+    <string name="old_app_description" msgid="2082094275580358049">"Yeni tətbiqi başlatmayın."</string>
+    <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> tətbiqini başladın"</string>
+    <string name="new_app_description" msgid="1932143598371537340">"Köhnə tətbiqi yadda saxlamadan dayandırın."</string>
+    <string name="sendText" msgid="5209874571959469142">"Mətn üçün əməliyyat seçin"</string>
+    <string name="volume_ringtone" msgid="6885421406845734650">"Zəngin səs gücü"</string>
+    <string name="volume_music" msgid="5421651157138628171">"Media həcmi"</string>
+    <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"Bluetooth vasitəsilə oynadılır"</string>
+    <string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"Səssiz zəng"</string>
+    <string name="volume_call" msgid="3941680041282788711">"Daxili zəng səsi"</string>
+    <string name="volume_bluetooth_call" msgid="2002891926351151534">"Bluetooth zəng həcmi"</string>
+    <string name="volume_alarm" msgid="1985191616042689100">"Siqnal səsi"</string>
+    <string name="volume_notification" msgid="2422265656744276715">"Bildiriş səsi"</string>
+    <string name="volume_unknown" msgid="1400219669770445902">"Həcm"</string>
+    <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"Bluetooth həcmi"</string>
+    <string name="volume_icon_description_ringer" msgid="3326003847006162496">"Zəng səsi gücü"</string>
+    <string name="volume_icon_description_incall" msgid="8890073218154543397">"Zəng həcmi"</string>
+    <string name="volume_icon_description_media" msgid="4217311719665194215">"Media həcmi"</string>
+    <string name="volume_icon_description_notification" msgid="7044986546477282274">"Bildiriş səsi"</string>
+    <string name="ringtone_default" msgid="3789758980357696936">"Defolt rinqton"</string>
+    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Defolt rinqton (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <string name="ringtone_silent" msgid="7937634392408977062">"Heç biri"</string>
+    <string name="ringtone_picker_title" msgid="3515143939175119094">"Zəng səsləri"</string>
+    <string name="ringtone_unknown" msgid="5477919988701784788">"Naməlum rinqton"</string>
+  <plurals name="wifi_available">
+    <item quantity="one" msgid="6654123987418168693">"Wi-Fi şəbəkəsi mövcuddur"</item>
+    <item quantity="other" msgid="4192424489168397386">"Wi-Fi şəbəkələri mövcuddur"</item>
+  </plurals>
+  <plurals name="wifi_available_detailed">
+    <item quantity="one" msgid="1634101450343277345">"Wi-Fi şəbəkəni açın"</item>
+    <item quantity="other" msgid="7915895323644292768">"Açıq Wi-Fi şəbəkələri mövcuddur"</item>
+  </plurals>
+    <string name="wifi_available_sign_in" msgid="4029489716605255386">"Wi-Fi şəbəkəsinə daxil ol"</string>
+    <string name="network_available_sign_in" msgid="8495155593358054676">"Şəbəkəyə daxil olun"</string>
+    <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
+    <skip />
+    <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi\'a qoşulmaq alınmadı"</string>
+    <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" internet bağlantısı keyfiyyətsizdir."</string>
+    <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+    <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wi-Fi Direct əməliyyatını başlat. Bu Wi-Fi müştəri/hotspotu bağlayacaq."</string>
+    <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi Direct başladıla bilmədi."</string>
+    <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct aktivdir"</string>
+    <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Ayarlar üçün toxunun"</string>
+    <string name="accept" msgid="1645267259272829559">"Qəbul edin"</string>
+    <string name="decline" msgid="2112225451706137894">"İmtina edin"</string>
+    <string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Dəvətnamə göndərildi"</string>
+    <string name="wifi_p2p_invitation_to_connect_title" msgid="4958803948658533637">"Qoşulmaq üçün dəvət"</string>
+    <string name="wifi_p2p_from_message" msgid="570389174731951769">"Kimdən:"</string>
+    <string name="wifi_p2p_to_message" msgid="248968974522044099">"Kimə:"</string>
+    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"Tələb olunan PİN kodu daxil edin:"</string>
+    <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PİN:"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"Bu planşet <xliff:g id="DEVICE_NAME">%1$s</xliff:g> cihazına qoşulan zaman Wi-Fi şəbəkəsindən müvəqqəti ayrılmış olacaq"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"Bu telefon <xliff:g id="DEVICE_NAME">%1$s</xliff:g> cihazına qoşulan zaman Wi-Fi şəbəkəsindən müvəqqəti ayrılmış olacaq"</string>
+    <string name="select_character" msgid="3365550120617701745">"Simvol daxil edin"</string>
+    <string name="sms_control_title" msgid="7296612781128917719">"SMS mesaj göndərilir"</string>
+    <string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; çox sayda SMS mesaj göndərir. Bu tətbiqin mesaj göndərməyə davam etməsinə icazə verirsiniz?"</string>
+    <string name="sms_control_yes" msgid="3663725993855816807">"İcazə verin"</string>
+    <string name="sms_control_no" msgid="625438561395534982">"Rədd edin"</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; ünvanına mesaj göndərmək istəyir."</string>
+    <string name="sms_short_code_details" msgid="3492025719868078457">"Bu, mobil hesabınıza "<font fgcolor="#ffffb060">"əlavə tariflərin tətbiq olunması"</font>" ilə nəticələnə bilər."</string>
+    <string name="sms_premium_short_code_details" msgid="5523826349105123687"><font fgcolor="#ffffb060">"Bu mobil hesabınızda ödənişlərə səbəb olacaq."</font></string>
+    <string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"Göndər"</string>
+    <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"Ləğv et"</string>
+    <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"Mənim seçimimi yadda saxla"</string>
+    <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"Bunu sonra Ayarlarda dəyişə bilərsiniz &gt; Tətbiqlər"</string>
+    <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Həmişə icazə ver"</string>
+    <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Heç vaxt icazə verməyin"</string>
+    <string name="sim_removed_title" msgid="6227712319223226185">"SIM kart çıxarıldı"</string>
+    <string name="sim_removed_message" msgid="2333164559970958645">"Cihazınızı etibarlı SIM kart ilə başladana kimi mobil şəbəkə əlçatmaz olacaq."</string>
+    <string name="sim_done_button" msgid="827949989369963775">"Bitdi"</string>
+    <string name="sim_added_title" msgid="3719670512889674693">"SİM kart əlavə edildi"</string>
+    <string name="sim_added_message" msgid="6599945301141050216">"Mobil şəbəkəyə qoşulmaq üçün cihazınızı yenidən başladın."</string>
+    <string name="sim_restart_button" msgid="4722407842815232347">"Yenidən başlat"</string>
+    <string name="time_picker_dialog_title" msgid="8349362623068819295">"Vaxt ayarlayın"</string>
+    <string name="date_picker_dialog_title" msgid="5879450659453782278">"Tarixi quraşdır"</string>
+    <string name="date_time_set" msgid="5777075614321087758">"Ayarlayın"</string>
+    <string name="date_time_done" msgid="2507683751759308828">"Hazırdır"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff33b5e5">"YENİ: "</font></string>
+    <string name="perms_description_app" msgid="5139836143293299417">"<xliff:g id="APP_NAME">%1$s</xliff:g> tərəfindən təmin edilib."</string>
+    <string name="no_permissions" msgid="7283357728219338112">"Heç bir icazə tələb olunmur"</string>
+    <string name="perm_costs_money" msgid="4902470324142151116">"bununla sizdən xərc tutula bilər"</string>
+    <string name="usb_storage_activity_title" msgid="4465055157209648641">"USB toplu yaddaş"</string>
+    <string name="usb_storage_title" msgid="5901459041398751495">"USB qoşuludur"</string>
+    <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"Siz USB vasitəsilə kompütere bağlandınız. Kompüter və Androidinizin USB yaddaşı arasında faylları kopyalamaq istəyirsinizsə, aşağıdakı düyməyə toxunun."</string>
+    <string name="usb_storage_message" product="default" msgid="805351000446037811">"Kompüterinizə USB ilə qoşulmusunuz. Faylları Androidinizin SD kartı ilə kompüteriniz arasında kopyalamaq istəyirsinizsə aşağıdakı düyməyə toxunun."</string>
+    <string name="usb_storage_button_mount" msgid="1052259930369508235">"USB yaddaşı aktivləşdirin"</string>
+    <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"USB yaddaşınızı USB kütləvi yaddaşı üçün istifadə edən zaman problem yarandı."</string>
+    <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"SD kartınızı USB kütləvi yaddaşı üçün istifadə edən zaman problem yarandı."</string>
+    <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB qoşuludur"</string>
+    <string name="usb_storage_notification_message" msgid="939822783828183763">"Faylları kompüterinizə kopyalamaq və ya kompüterinizdən kopyalamaq üçün toxunun."</string>
+    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"USB yaddaşı söndürün"</string>
+    <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"USB yaddaşı söndürmək üçün toxunun."</string>
+    <string name="usb_storage_stop_title" msgid="660129851708775853">"USB yaddaş istifadə olunur"</string>
+    <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"USB yaddaşı söndürmədən öncə Android\'in USB yaddaşını kompüterdən demontaj etdiyinizə (çıxardığınıza) əmin olun."</string>
+    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"USB yaddaşı söndürmədən öncə Android\'in USB yaddaşını kompüterdən demontaj etdiyinizə (çıxardığınıza) əmin olun."</string>
+    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"USB yaddaşını söndür"</string>
+    <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"USB yaddaşı söndürən zaman problem oldu. USB hostu demontaj etmənizi yoxlayın və yenidən cəhd edin."</string>
+    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"USB yaddaşı aktivləşdirin"</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"USB yaddaşı aktivləşdirsəniz, istifadə etdiyiniz bəzi tətbiqlər dayana bilər və USB yaddaş deaktiv edilənə qədər işləməyə bilər."</string>
+    <string name="dlg_error_title" msgid="7323658469626514207">"USB əməliyyatı uğursuzdur"</string>
+    <string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
+    <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Media cihazı kimi qoşuldu"</string>
+    <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Kamera kimi bağlanıldı"</string>
+    <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Quraşdırıcı kimi qoşulub"</string>
+    <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB aksesuara qoşuldu"</string>
+    <string name="usb_notification_message" msgid="2290859399983720271">"Digər USB seçimləri üçün toxunun."</string>
+    <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB yaddaşına format atılsın?"</string>
+    <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD kart format edilsin?"</string>
+    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"USB yaddaşınızda yerləşdirilmiş bütün fayllar silinəcək. Bu addım geri dönülməzdir."</string>
+    <string name="extmedia_format_message" product="default" msgid="14131895027543830">"Kartınızdakı bütün məlumatlar itəcək."</string>
+    <string name="extmedia_format_button_format" msgid="4131064560127478695">"Format"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"USB sazlama qoşuludur"</string>
+    <string name="adb_active_notification_message" msgid="1016654627626476142">"USB debaqı deaktivasiya etmək üçün toxunun."</string>
+    <string name="select_input_method" msgid="4653387336791222978">"Daxiletmə metodunu seçin"</string>
+    <string name="configure_input_methods" msgid="9091652157722495116">"Daxiletmə üsullarını ayarlayın"</string>
+    <string name="use_physical_keyboard" msgid="6203112478095117625">"Fiziki klaviatura"</string>
+    <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Klaviatura sxemi seçin"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Klaviatura tərtibatı seçmək üçün toxunun."</string>
+    <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCÇDEƏFGĞHXIİJKQLMNOÖPRSŞTUÜVYZ"</string>
+    <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCÇDEƏFGĞHİIJKLMNOÖPQRSŞTUÜVWXYZ"</string>
+    <string name="candidates_style" msgid="4333913089637062257"><u>"namizədlər"</u></string>
+    <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"USB yaddaş hazırlanır"</string>
+    <string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"SD kart hazırlanır"</string>
+    <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"Səhvlər yoxlanılır."</string>
+    <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"Boş USB yaddaşı"</string>
+    <string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"Boş SD kart"</string>
+    <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"USB yaddaş boşdur və ya sistem tərəfindən dəstəklənməyən fayl sisteminə malikdir."</string>
+    <string name="ext_media_nofs_notification_message" product="default" msgid="8641065641786923604">"SD kart boşdur və ya sistem tərəfindən dəstəklənməyən fayl sisteminə malikdir."</string>
+    <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"Zədəli USB yaddaş"</string>
+    <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"Zədəli SD kart"</string>
+    <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="1795917578395333280">"SD yaddaş zədələnib. Onu format etməyə çalışın."</string>
+    <string name="ext_media_unmountable_notification_message" product="default" msgid="1753898567525568253">"SD kart zədələnib. Onu format etməyə çalışın."</string>
+    <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"USB yaddaşı gözlənilmədən çıxarıldı"</string>
+    <string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"SD kart gözlənilmədən çıxarıldı"</string>
+    <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"Məlumat itkisinin qarşısını almaq üçün USB yaddaşı çıxarmazdan əvvəl onu demontaj edin."</string>
+    <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"Data itkisinin qarşısını almaq üçün SD kartı çıxarmadan öncə demontaj edin."</string>
+    <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"USB yaddaş çıxarmaq üçün təhlükəsizdir"</string>
+    <string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"SD kart təhlükəsiz çıxarıla bilər"</string>
+    <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"Siz USB yaddaşı təhlükəsiz çıxara bilərsiniz."</string>
+    <string name="ext_media_safe_unmount_notification_message" product="default" msgid="568841278138377604">"Siz SD kartı təhlükəsiz çıxara bilərsiniz."</string>
+    <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"Silinmiş USB yaddaş"</string>
+    <string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"SD kart çıxarıldı"</string>
+    <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"USB yaddaş çıxarıldı. Yeni media əlavə edin."</string>
+    <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"SD kart çıxarıldı. Yenisini daxil edin."</string>
+    <string name="activity_list_empty" msgid="1675388330786841066">"Uyğun gələn fəaliyyət tapılmadı."</string>
+    <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"komponent istifadəsi statistikasını güncəlləyir"</string>
+    <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"Tətbiqə toplanmış istifadə statistikasını dəyişməyə imkan verir. Normal tətbiqlər tərəfindən istifadə olunmur."</string>
+    <string name="permlab_copyProtectedData" msgid="4341036311211406692">"məzmunu kopyala"</string>
+    <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Tətbiqə kontenti kopyalamaq üçün defolt konteyner servisini çağırmaq icazəsi verir. Normal tətbiqlər tərəfindən istifadə edilmir."</string>
+    <string name="permlab_route_media_output" msgid="1642024455750414694">"Media çıxışını yönləndirir"</string>
+    <string name="permdesc_route_media_output" msgid="4932818749547244346">"Tətbiqə media çıxışını digər xarici cihazlara yönləndirmək imkanı verir."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Keyguard təhlükəsiz yaddaşa çıxış"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Tətbiqə keguard təhlükəsiz yaddaşa çatmağa icazə verir."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Klaviatura kilidinin görülməsini və gizlədilməsini idarə edir"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Tətbiqə keguardı idarə etmək icazəsi verir."</string>
+    <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Zoom nəzarəti üçün iki dəfə toxunun"</string>
+    <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Widget əlavə edilə bilmədi."</string>
+    <string name="ime_action_go" msgid="8320845651737369027">"Get"</string>
+    <string name="ime_action_search" msgid="658110271822807811">"Axtar"</string>
+    <string name="ime_action_send" msgid="2316166556349314424">"Göndər"</string>
+    <string name="ime_action_next" msgid="3138843904009813834">"Növbəti"</string>
+    <string name="ime_action_done" msgid="8971516117910934605">"Tamam"</string>
+    <string name="ime_action_previous" msgid="1443550039250105948">"Əvvəlki"</string>
+    <string name="ime_action_default" msgid="2840921885558045721">"İcra edin"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"<xliff:g id="NUMBER">%s</xliff:g> istifadə etməklə\nnömrə yığın"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"<xliff:g id="NUMBER">%s</xliff:g>istifadə edərək kontakt yaradın\n"</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Aşağıdakı bir və ya daha çox tətbiqlər indi və gələcəkdə hesabınıza daxil olmaq üçün icazə istəyir."</string>
+    <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Bu istəyə izn vermək istəyirsiniz?"</string>
+    <string name="grant_permissions_header_text" msgid="6874497408201826708">"Giriş sorğusu"</string>
+    <string name="allow" msgid="7225948811296386551">"İcazə verin"</string>
+    <string name="deny" msgid="2081879885755434506">"Rədd et"</string>
+    <string name="permission_request_notification_title" msgid="6486759795926237907">"İcazə tələb olunur"</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">\n" hesabı üçün<xliff:g id="ACCOUNT">%s</xliff:g> icazə sorğusu göndərildi."</string>
+    <string name="input_method_binding_label" msgid="1283557179944992649">"Daxiletmə metodu"</string>
+    <string name="sync_binding_label" msgid="3687969138375092423">"Sinxronizasiya"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"Əlçatımlılıq"</string>
+    <string name="wallpaper_binding_label" msgid="1240087844304687662">"Divar kağızı"</string>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"Divar kağızını dəyişin"</string>
+    <string name="notification_listener_binding_label" msgid="2014162835481906429">"Bildiriş dinləyən"</string>
+    <string name="vpn_title" msgid="19615213552042827">"VPN aktivləşdirildi"</string>
+    <string name="vpn_title_long" msgid="6400714798049252294">"VPN <xliff:g id="APP">%s</xliff:g> tərəfindən aktivləşdirilib"</string>
+    <string name="vpn_text" msgid="3011306607126450322">"Şəbəkəni idarə etmək üçün toxunun."</string>
+    <string name="vpn_text_long" msgid="6407351006249174473">"<xliff:g id="SESSION">%s</xliff:g> sessiyaya qoşuludur. Şəbəkəni idarə etmək üçün toxunun."</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_error" msgid="6009249814034708175">"Həmişə aktiv VPN xətası"</string>
+    <string name="vpn_lockdown_config" msgid="6415899150671537970">"Konfiqurə etmək üçün toxun"</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>
+    <string name="submit" msgid="1602335572089911941">"Göndər"</string>
+    <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Avtomobil rejimi aktivdir"</string>
+    <string name="car_mode_disable_notification_message" msgid="8035230537563503262">"Avtomobil rejimindən çıxmaq üçün toxunun."</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"Tezerinq və ya hotspot aktivdir"</string>
+    <string name="tethered_notification_message" msgid="6857031760103062982">"Quraşdırmaq üçün toxunun."</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>
+    <string name="throttle_warning_notification_title" msgid="4890894267454867276">"Yüksək mobil data istifadəsi"</string>
+    <string name="throttle_warning_notification_message" msgid="3340822228599337743">"Mobil data istifadəsi haqqında daha çox öyrənmək üçün toxunun."</string>
+    <string name="throttled_notification_title" msgid="6269541897729781332">"Mobil data limiti keçildi"</string>
+    <string name="throttled_notification_message" msgid="5443457321354907181">"Mobil data istifadəsi haqqında daha çox öyrənmək üçün toxunun."</string>
+    <string name="no_matches" msgid="8129421908915840737">"Uyğunluq yoxdur"</string>
+    <string name="find_on_page" msgid="1946799233822820384">"Səhifədə tap"</string>
+  <plurals name="matches_found">
+    <item quantity="one" msgid="8167147081136579439">"1 uyğunluq"</item>
+    <item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> ədəddən <xliff:g id="TOTAL">%d</xliff:g>"</item>
+  </plurals>
+    <string name="action_mode_done" msgid="7217581640461922289">"Hazırdır"</string>
+    <string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"USB yaddaşı qaldırılır..."</string>
+    <string name="progress_unmounting" product="default" msgid="1327894998409537190">"SD kart demontaj edilir..."</string>
+    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"USB yaddaş silinir..."</string>
+    <string name="progress_erasing" product="default" msgid="6596988875507043042">"SD kart silinir..."</string>
+    <string name="format_error" product="nosdcard" msgid="6299769563624776948">"USB yaddaşı silinə bilmədi."</string>
+    <string name="format_error" product="default" msgid="7315248696644510935">"SD kartı silmək mümkün olmadı."</string>
+    <string name="media_bad_removal" msgid="7960864061016603281">"SD kart demontaj edilmədən öncə çıxarıldı."</string>
+    <string name="media_checking" product="nosdcard" msgid="418188720009569693">"USB yaddaş hazırda yoxlanılır."</string>
+    <string name="media_checking" product="default" msgid="7334762503904827481">"SD kart hazırda yoxlanılır."</string>
+    <string name="media_removed" msgid="7001526905057952097">"SD kart çıxarılıb."</string>
+    <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"SD kart hazırda kompüter tərəfindən istifadə edilir."</string>
+    <string name="media_shared" product="default" msgid="5706130568133540435">"SD kart hal-hazırda kompüter tərəfindən istifadə edilir."</string>
+    <string name="media_unknown_state" msgid="729192782197290385">"Naməlum vəziyyətdə xarici media."</string>
+    <string name="share" msgid="1778686618230011964">"Paylaşın"</string>
+    <string name="find" msgid="4808270900322985960">"Tapın"</string>
+    <string name="websearch" msgid="4337157977400211589">"Veb Axtarış"</string>
+    <string name="find_next" msgid="5742124618942193978">"Sonrakını tap"</string>
+    <string name="find_previous" msgid="2196723669388360506">"Əvvəlkini tap"</string>
+    <string name="gpsNotifTicker" msgid="5622683912616496172">"<xliff:g id="NAME">%s</xliff:g> tərəfindən məkan sorğusu"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Məkan sorğusu"</string>
+    <string name="gpsNotifMessage" msgid="1374718023224000702">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>) tərəfindən tələb edilib"</string>
+    <string name="gpsVerifYes" msgid="2346566072867213563">"Bəli"</string>
+    <string name="gpsVerifNo" msgid="1146564937346454865">"Xeyr"</string>
+    <string name="sync_too_many_deletes" msgid="5296321850662746890">"Limiti keçəni silin"</string>
+    <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> üçün <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> silinmiş fayl var, <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> hesabı. Nə etmək istəyirsiniz?"</string>
+    <string name="sync_really_delete" msgid="2572600103122596243">"Elementləri sil"</string>
+    <string name="sync_undo_deletes" msgid="2941317360600338602">"Silinənləri geri qaytar"</string>
+    <string name="sync_do_nothing" msgid="3743764740430821845">"İndilik heç nə etmə"</string>
+    <string name="choose_account_label" msgid="5655203089746423927">"Hesab seçin"</string>
+    <string name="add_account_label" msgid="2935267344849993553">"Hesab əlavə et"</string>
+    <string name="add_account_button_label" msgid="3611982894853435874">"Hesab əlavə edin"</string>
+    <string name="number_picker_increment_button" msgid="2412072272832284313">"Artır"</string>
+    <string name="number_picker_decrement_button" msgid="476050778386779067">"Azaldın"</string>
+    <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> toxunun və basaraq saxlayın."</string>
+    <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Artırmaq üçün yuxarı, azaltmaq üçün aşağı sürüşdürün."</string>
+    <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Dəqiqə artırın"</string>
+    <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Dəqiqəni azalt"</string>
+    <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Saatı artırın"</string>
+    <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Saatı azaldın"</string>
+    <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"PM qurun"</string>
+    <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"AM qurun"</string>
+    <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Artma ayı"</string>
+    <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Ayı azaldın"</string>
+    <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Artma günü"</string>
+    <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Azalma günü"</string>
+    <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Artım ili"</string>
+    <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Azalma ili"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Ləğv et"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Sil"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Hazırdır"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Rejim dəyişikliyi"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Daxil olun"</string>
+    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Tətbiq seçin"</string>
+    <string name="shareactionprovider_share_with" msgid="806688056141131819">"Bununla paylaşın"</string>
+    <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> ilə paylaşın"</string>
+    <string name="content_description_sliding_handle" msgid="415975056159262248">"Sürüşən qulp. Toxunaraq basılı tutun."</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> üçün yuxarı sürüşdürün."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> üçün aşağı sürüşdürün."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> üçün sola sürüşdür."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> üçün sağa sürüşdür."</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Kilidi aç"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Səssiz"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Səs açıqdır"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Axtar"</string>
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Kilidi açmaq üçün vurun."</string>
+    <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Parolların səsləndirilməsi üçün qulaqlıqları taxın."</string>
+    <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Nöqtə."</string>
+    <string name="action_bar_home_description" msgid="5293600496601490216">"Evə gedin"</string>
+    <string name="action_bar_up_description" msgid="2237496562952152589">"Yuxarı gedin"</string>
+    <string name="action_menu_overflow_description" msgid="2295659037509008453">"Əlavə seçimlər"</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="4891916833657929263">"Daxili yaddaş"</string>
+    <string name="storage_sd_card" msgid="3282948861378286745">"SD kart"</string>
+    <string name="storage_usb" msgid="3017954059538517278">"USB yaddaş"</string>
+    <string name="extract_edit_menu_button" msgid="8940478730496610137">"Redaktə et"</string>
+    <string name="data_usage_warning_title" msgid="1955638862122232342">"Data istifadə xəbərdarlığı"</string>
+    <string name="data_usage_warning_body" msgid="2814673551471969954">"İstifadə və ayarları görmək üçün toxunun"</string>
+    <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-3G data deaktivdir"</string>
+    <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G data deaktiv edildi"</string>
+    <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobil data deaktivdir"</string>
+    <string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"Wi-Fi data deaktiv edildi"</string>
+    <string name="data_usage_limit_body" msgid="3317964706973601386">"Aktivləşdirmək üçün toxunun."</string>
+    <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"2G-3G data limiti aşılıb"</string>
+    <string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"4G data limiti keçildi"</string>
+    <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"Mobil data limiti keçildi"</string>
+    <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Wi-Fi data limiti keçildi"</string>
+    <string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> müəyyən edilmiş limit aşır."</string>
+    <string name="data_usage_restricted_title" msgid="5965157361036321914">"Arxaplan datası məhdudlaşdırıldı"</string>
+    <string name="data_usage_restricted_body" msgid="6741521330997452990">"Məhdudiyyəti aradan qaldırmaq üçün toxunun"</string>
+    <string name="ssl_certificate" msgid="6510040486049237639">"Təhlükəsizlik sertifikatı"</string>
+    <string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Bu sertifikat etibarlıdır."</string>
+    <string name="issued_to" msgid="454239480274921032">"Verilib:"</string>
+    <string name="common_name" msgid="2233209299434172646">"Ümumi ad:"</string>
+    <string name="org_name" msgid="6973561190762085236">"Təşkilat:"</string>
+    <string name="org_unit" msgid="7265981890422070383">"Təşkilati vahid:"</string>
+    <string name="issued_by" msgid="2647584988057481566">"Tərəfindən verilib:"</string>
+    <string name="validity_period" msgid="8818886137545983110">"Keçərlilik:"</string>
+    <string name="issued_on" msgid="5895017404361397232">"Dərc olunub:"</string>
+    <string name="expires_on" msgid="3676242949915959821">"Bitmə vaxtı:"</string>
+    <string name="serial_number" msgid="758814067660862493">"Seriya nömrəsi:"</string>
+    <string name="fingerprints" msgid="4516019619850763049">"Barmaq izləri:"</string>
+    <string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 barmaq izi:"</string>
+    <string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 barmaq izi:"</string>
+    <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Hamısını seçın"</string>
+    <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Fəaliyyəti seçin"</string>
+    <string name="share_action_provider_share_with" msgid="5247684435979149216">"Bununla paylaşın"</string>
+    <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="3245653681008218030">"Göndərilir..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Brauzer işə salınsın?"</string>
+    <string name="SetupCallDefault" msgid="5834948469253758575">"Zəngi qəbul edək?"</string>
+    <string name="activity_resolver_use_always" msgid="8017770747801494933">"Həmişə"</string>
+    <string name="activity_resolver_use_once" msgid="2404644797149173758">"Sadəcə bir dəfə"</string>
+    <string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"Planşet"</string>
+    <string name="default_audio_route_name" product="default" msgid="4239291273420140123">"Telefon"</string>
+    <string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Qulaqlıq"</string>
+    <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Dok spikerlər"</string>
+    <string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string>
+    <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">"Simsiz ekran"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Hazırdır"</string>
+    <string name="media_route_button_content_description" msgid="5758553567065145276">"Media çıxışı"</string>
+    <string name="media_route_status_scanning" msgid="7279908761758293783">"Skan edilir..."</string>
+    <string name="media_route_status_connecting" msgid="6422571716007825440">"Qoşulur..."</string>
+    <string name="media_route_status_available" msgid="6983258067194649391">"Əlçatımlı"</string>
+    <string name="media_route_status_not_available" msgid="6739899962681886401">"Əlçatımlı deyil"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"İstifadə olunur"</string>
+    <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Daxili ekran"</string>
+    <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"HDMI Ekran"</string>
+    <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Örtük #<xliff:g id="ID">%1$d</xliff:g>"</string>
+    <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", təhlükəsiz"</string>
+    <string name="wifi_display_notification_title" msgid="2223050649240326557">"Simsiz ekran qoşulub"</string>
+    <string name="wifi_display_notification_message" msgid="4498802012464170685">"Bu ekran digər cihazda göstərir"</string>
+    <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Bağlantını kəsin"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Təcili zəng"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Şablonu unutmuşam"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Yanlış Model"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Yanlış Şifrə"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN səhvdir"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%1$d</xliff:g> saniyə sonra yenidən cəhd edin."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Şablonunuzu çəkin"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM PIN kodu daxil edin"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"PİN kodu daxil edin"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Parol daxil edin"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM indi deaktivdir. Davam etmək üçün PUK kodu daxil edin. Əlavə məlumat üçün operatora müraciət edin."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"İstədiyiniz PİN kodu daxil edin"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"İstədiyiniz PIN kodu təsdiqləyin"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SİM kartın kilidi açılır..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Yanlış PİN kod."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4-dən 8-ə qədər rəqəmi olan PIN yazın."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK kod 8 rəqəm və ya daha çox olmalıdır."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Düzgün PUK kodu yenidən daxil edin. Təkrarlanan cəhdlər SIM\'i birdəfəlik sıradan çıxaracaq."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN kodları uyğun deyil"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Həddindən çox cəhd edildi!"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Kilidi açmaq üçün Google hesabınız ilə daxil olun."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"İstifadəçi adı (e-poçt)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Şifrə"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Daxil ol"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Yanlış istifadəçi adı və ya parol."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"İstifadəçi adınızı və ya parolunuzu unutmusunuz?\n "<b>"google.com/accounts/recovery"</b>" linkinə daxil olun."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Hesab yoxlanılır..."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN kodunuzu <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış daxil etdiniz.\n\n <xliff:g id="NUMBER_1">%d</xliff:g> saniyə ərzində yenidən yoxlayın"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Şifrənizi <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış daxil etdiniz. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> saniyə ərzində yenidən yoxlayın."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Modelinizi <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış çəkmisiniz.\n\n <xliff:g id="NUMBER_1">%d</xliff:g> saniyə ərzində yenidən yoxlayın"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Siz planşet kilidini açmaq üçün <xliff:g id="NUMBER_0">%d</xliff:g> dəfə uğursuz cəhd etmisiniz. <xliff:g id="NUMBER_1">%d</xliff:g> dəfə də uğursuz cəhd etsəniz, planşet fabrik ayarlarına sıfırlanacaq və bütün məlumatlarınız itəcək."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Siz telefon kilidini açmaq üçün <xliff:g id="NUMBER_0">%d</xliff:g> dəfə uğursuz cəhd etmisiniz. <xliff:g id="NUMBER_1">%d</xliff:g> dəfə də uğursuz cəhd etsəniz, telefon fabrik ayarlarına sıfırlanacaq və bütün məlumatlarınız itəcək."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Siz planşet kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> dəfə uğursuz cəhd etmisiniz. Planşet fabrik ayarlarına sıfırlanacaq."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Siz telefonun kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> yanlış cəhd etmisiniz. Telefon artıq defolt zavod halına sıfırlanacaq."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Siz kilidi açmaq üçün şablonu <xliff:g id="NUMBER_0">%d</xliff:g> dəfə səhv çəkdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> daha uğursuz cəhddən sonra planşetinizin kilidini e-poçt hesabınızla açmaq tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> saniyə ərzində bir daha yoxlayın."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Siz artıq modeli <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış daxil etmisiniz.<xliff:g id="NUMBER_1">%d</xliff:g> dəfə də yanlış daxil etsəniz, telefonun kilidinin açılması üçün elektron poçt ünvanınız tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> saniyə ərzində yenidən cəhd edin."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" - "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Yığışdır"</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Səs gücü tövsiyə edilən səviyyədən artırılsın?\nUzun müddət yüksək səs gücü ilə dinləmə Sizin eşitmə qabiliyyətinizə mənfi təsir edə bilər."</string>
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Əlçatımlığı aktivləşdirmək üçün iki barmağınızı basılı saxlayın."</string>
+    <string name="accessibility_enabled" msgid="1381972048564547685">"Əlçatımlılıq aktivləşdirildi"</string>
+    <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Giriş imkanı ləğv edilib."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Cari istifadəçi <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="owner_name" msgid="2716755460376028154">"Sahib"</string>
+    <string name="error_message_title" msgid="4510373083082500195">"Xəta"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Bu tətbiq məhdud profillər üçün hesabları dəstəkləmir."</string>
+    <string name="app_not_found" msgid="3429141853498927379">"Bu əməliyyatı idarə etmək üçün heç bir tətbiq tapılmadı."</string>
+    <string name="revoke" msgid="5404479185228271586">"Ləğv edin"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"B4 ISO"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Məktub"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Hökumət Məktubu"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Hüquqi"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Kiçik Hüquq"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Qovluq"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Qısa"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Ləğv edildi"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Kontent yazmna xətası"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"naməlum"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Administrator PIN kodunu daxil edin"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN daxil edin"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Səhv"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Cari PIN"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Yeni PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Yeni PIN\'i təsdiq edin"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Dəyişmə məhdudiyyətləri üçün PİN yaradın"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PİN uyğun gəlmir. Yenidən cəhd edin."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"PİN çox qısadır. Ən azı 4 rəqəm olmalıdır."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"1 saniyə sonra təkrar yoxlayın"</item>
+    <item quantity="other" msgid="4730868920742952817">"<xliff:g id="COUNT">%d</xliff:g> saniyə sonra təkrar yoxlayın"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Daha sonra yenidən yoxlayın."</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Paneli göstərmək üçün ekranın küncünü sürüşdürün"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Sistem panelini göstərmək üçün ekranın küncündən sürüşdürün"</string>
+</resources>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
new file mode 100644
index 0000000..0ae4dda
--- /dev/null
+++ b/core/res/res/values-az/strings.xml
@@ -0,0 +1,1584 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<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="5973789783504771878">"KB"</string>
+    <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
+    <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
+    <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
+    <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
+    <string name="untitled" msgid="4638956954852782576">"Başlıqsız"</string>
+    <string name="ellipsis" msgid="7899829516048813237">"..."</string>
+    <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
+    <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Telefon nömrəsi yoxdur)"</string>
+    <string name="unknownName" msgid="2277556546742746522">"(Naməlum)"</string>
+    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Səsli poçt"</string>
+    <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
+    <string name="mmiError" msgid="5154499457739052907">"Bağlantı problemi və ya yalnış MM kodu."</string>
+    <string name="mmiFdnError" msgid="5224398216385316471">"Əməliyyat yalnız sabit nömrələrə yığımla məhdudlaşıb."</string>
+    <string name="serviceEnabled" msgid="8147278346414714315">"Servis işə salındı."</string>
+    <string name="serviceEnabledFor" msgid="6856228140453471041">"Xidmət aktiv edilmişdir:"</string>
+    <string name="serviceDisabled" msgid="1937553226592516411">"Xidmət deaktiv edilib."</string>
+    <string name="serviceRegistered" msgid="6275019082598102493">"Qeydiyyat uğurlu oldu."</string>
+    <string name="serviceErased" msgid="1288584695297200972">"Silinmə uğurlu olmuşdur."</string>
+    <string name="passwordIncorrect" msgid="7612208839450128715">"Yanlış parol"</string>
+    <string name="mmiComplete" msgid="8232527495411698359">"MMI tamamdır."</string>
+    <string name="badPin" msgid="9015277645546710014">"Daxil etdiyiniz köhnə PİN düzgün deyil."</string>
+    <string name="badPuk" msgid="5487257647081132201">"Daxil etdiyiniz PUK düzgün deyil."</string>
+    <string name="mismatchPin" msgid="609379054496863419">"Daxil etdiyiniz PİN kodlar uyğun gəlmir."</string>
+    <string name="invalidPin" msgid="3850018445187475377">"4-dən 8-ə qədər rəqəmi olan PIN yazın."</string>
+    <string name="invalidPuk" msgid="8761456210898036513">"8 və daha çox rəqəmi olan PUK yazın."</string>
+    <string name="needPuk" msgid="919668385956251611">"Sizin SİM kart PUK ilə kilidlənib. Onu açmaq üçün PUK kodu yazın."</string>
+    <string name="needPuk2" msgid="4526033371987193070">"SIM kartın kilidini açmaq üçün PUK2 yazın"</string>
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
+    <string name="ClipMmi" msgid="6952821216480289285">"Daxil olan zəng edənin ID\'si"</string>
+    <string name="ClirMmi" msgid="7784673673446833091">"Gedən Zəng ID"</string>
+    <string name="CfMmi" msgid="5123218989141573515">"Zəng yönləndirmə"</string>
+    <string name="CwMmi" msgid="9129678056795016867">"Zəng gözləyir"</string>
+    <string name="BaMmi" msgid="455193067926770581">"Zəng qadağası"</string>
+    <string name="PwdMmi" msgid="7043715687905254199">"Parolu dəyiş"</string>
+    <string name="PinMmi" msgid="3113117780361190304">"PİN dəyişmək"</string>
+    <string name="CnipMmi" msgid="3110534680557857162">"Hazırdakı nömrəyə zəng edilir"</string>
+    <string name="CnirMmi" msgid="3062102121430548731">"Zənglərin sayı məhdudlaşdırılıb"</string>
+    <string name="ThreeWCMmi" msgid="9051047170321190368">"Üç yollu zəng"</string>
+    <string name="RuacMmi" msgid="7827887459138308886">"Xoşagəlməz zənglərdən imtina"</string>
+    <string name="CndMmi" msgid="3116446237081575808">"Çatdırılma zəngi"</string>
+    <string name="DndMmi" msgid="1265478932418334331">"Narahat etməyin"</string>
+    <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"Adətən zəng edənin ID\'si məhdudlaşdırılır. Növbəti zəng: Məhdudlaşdırılıb"</string>
+    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"Adətən zəng edənin ID\'si məhdudlaşdırılır. Növbəti zəng: Məhdudlaşdırılmayıb"</string>
+    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"Adətən zəng edənin ID\'si məhdudlaşdırılmır. Növbəti zəng: Məhdudlaşdırılıb"</string>
+    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"Adətən zəng edənin ID\'si məhdudlaşdırılmır. Növbəti zəng: Məhdudlaşdırılmayıb"</string>
+    <string name="serviceNotProvisioned" msgid="8614830180508686666">"Xidmət təmin edilməyib."</string>
+    <string name="CLIRPermanent" msgid="3377371145926835671">"Siz zəng edənin ID nizamlarını dəyişə bilməzsiz."</string>
+    <string name="RestrictedChangedTitle" msgid="5592189398956187498">"Məhdudlaşdırılmış keçid dəyişdi"</string>
+    <string name="RestrictedOnData" msgid="8653794784690065540">"Data xidmət bağlıdır."</string>
+    <string name="RestrictedOnEmergency" msgid="6581163779072833665">"Təcili xidmət bağlıdır."</string>
+    <string name="RestrictedOnNormal" msgid="4953867011389750673">"Səs xidməti bağlıdır."</string>
+    <string name="RestrictedOnAllVoice" msgid="3396963652108151260">"Bütün Səs xidmətləri bağlıdır"</string>
+    <string name="RestrictedOnSms" msgid="8314352327461638897">"SMS xidməti bloklanıb."</string>
+    <string name="RestrictedOnVoiceData" msgid="996636487106171320">"Səs/data xidmətləri bloklanıb."</string>
+    <string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Səs/SMS xidmətləri bloklanıb."</string>
+    <string name="RestrictedOnAll" msgid="5643028264466092821">"Bütün səs/data/SMS xidmətləri bağlıdır."</string>
+    <string name="serviceClassVoice" msgid="1258393812335258019">"Səs"</string>
+    <string name="serviceClassData" msgid="872456782077937893">"Məlumat"</string>
+    <string name="serviceClassFAX" msgid="5566624998840486475">"FAKS"</string>
+    <string name="serviceClassSMS" msgid="2015460373701527489">"SMS"</string>
+    <string name="serviceClassDataAsync" msgid="4523454783498551468">"Async"</string>
+    <string name="serviceClassDataSync" msgid="7530000519646054776">"Sinx"</string>
+    <string name="serviceClassPacket" msgid="6991006557993423453">"Paket"</string>
+    <string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
+    <string name="roamingText0" msgid="7170335472198694945">"Rominq göstəricisi işləkdir"</string>
+    <string name="roamingText1" msgid="5314861519752538922">"Rominq göstəricisi işlək deyil"</string>
+    <string name="roamingText2" msgid="8969929049081268115">"Rominq göstəricisi yanır"</string>
+    <string name="roamingText3" msgid="5148255027043943317">"Qonşuluqdan Kənar"</string>
+    <string name="roamingText4" msgid="8808456682550796530">"Binadan kənar"</string>
+    <string name="roamingText5" msgid="7604063252850354350">"Rominq - Arzuolunan sistem"</string>
+    <string name="roamingText6" msgid="2059440825782871513">"Rominq - Mümkün sistem"</string>
+    <string name="roamingText7" msgid="7112078724097233605">"Rominq - Alyans partnyoru"</string>
+    <string name="roamingText8" msgid="5989569778604089291">"Rominq - Premium partnyor"</string>
+    <string name="roamingText9" msgid="7969296811355152491">"Rouminq - Tam Xidmət Funksionallığı"</string>
+    <string name="roamingText10" msgid="3992906999815316417">"Rouminq - Qismən Xidmət Funksionallığı"</string>
+    <string name="roamingText11" msgid="4154476854426920970">"Rouminq Banneri Açıqdır"</string>
+    <string name="roamingText12" msgid="1189071119992726320">"Roaming Banner Off"</string>
+    <string name="roamingTextSearching" msgid="8360141885972279963">"Xidmət axtarılır"</string>
+    <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Yönləndirilmədi"</string>
+    <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
+    <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> saniyə sonra"</string>
+    <string name="cfTemplateRegistered" msgid="5073237827620166285">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Yönləndirilmədi"</string>
+    <string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Yönləndirilmədi"</string>
+    <string name="fcComplete" msgid="3118848230966886575">"Özəllik kodu tamamlandı."</string>
+    <string name="fcError" msgid="3327560126588500777">"Əlaqə problemi və ya yanlış funksiya kodu."</string>
+    <string name="httpErrorOk" msgid="1191919378083472204">"OK"</string>
+    <string name="httpError" msgid="7956392511146698522">"Şəbəkə xətası var idi."</string>
+    <string name="httpErrorLookup" msgid="4711687456111963163">"URL tapıla bilmədi."</string>
+    <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"Sayt autentifikasiya sxemi dəstəklənmir."</string>
+    <string name="httpErrorAuth" msgid="1435065629438044534">"Təsdiq edilə bilmədi."</string>
+    <string name="httpErrorProxyAuth" msgid="1788207010559081331">"Proksi server vasitəsilə təsdiqlənmə uğursuz oldu."</string>
+    <string name="httpErrorConnect" msgid="8714273236364640549">"Serverə qoşula bilmədi."</string>
+    <string name="httpErrorIO" msgid="2340558197489302188">"Serverlə əlaqə alınmadı. Sonra cəhd edin."</string>
+    <string name="httpErrorTimeout" msgid="4743403703762883954">"Server ilə olan əlaqə zaman aşımına məruz qaldı."</string>
+    <string name="httpErrorRedirectLoop" msgid="8679596090392779516">"Bu səhifədə həddindən çox server yönləndirilmələri var."</string>
+    <string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"Protokol dəstəklənmir."</string>
+    <string name="httpErrorFailedSslHandshake" msgid="96549606000658641">"Güvənli bağlantı yaradıla bilmədi."</string>
+    <string name="httpErrorBadUrl" msgid="3636929722728881972">"URL yanlış olduğu üçün səhifəni açmaq mümkün olmadı."</string>
+    <string name="httpErrorFile" msgid="2170788515052558676">"Fayla giriş baş tutmadı."</string>
+    <string name="httpErrorFileNotFound" msgid="6203856612042655084">"Tələb olunan fayl tapılmadı."</string>
+    <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Həddindən çox sorğu işlənilir. Daha sonra yoxlayın."</string>
+    <string name="notification_title" msgid="8967710025036163822">"<xliff:g id="ACCOUNT">%1$s</xliff:g> üçün giriş xətası"</string>
+    <string name="contentServiceSync" msgid="8353523060269335667">"Sinxronlaşdırma"</string>
+    <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Sinxronlaşdırma"</string>
+    <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Həddindən çox <xliff:g id="CONTENT_TYPE">%s</xliff:g> silinmələri var."</string>
+    <string name="low_memory" product="tablet" msgid="6494019234102154896">"Planşetin yaddaşı doludur. Boş yer üçün bəzi faylları silin."</string>
+    <string name="low_memory" product="default" msgid="3475999286680000541">"Telefonun yaddaşı doludur. Boş yer üçün bəzi faylları silin."</string>
+    <string name="me" msgid="6545696007631404292">"Mən"</string>
+    <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Planşet seçimləri"</string>
+    <string name="power_dialog" product="default" msgid="1319919075463988638">"Telefon seçimləri"</string>
+    <string name="silent_mode" msgid="7167703389802618663">"Səssiz rejim"</string>
+    <string name="turn_on_radio" msgid="3912793092339962371">"Simsizi işə salın"</string>
+    <string name="turn_off_radio" msgid="8198784949987062346">"Simsiz rabitəni söndürün"</string>
+    <string name="screen_lock" msgid="799094655496098153">"Ekran kilidi"</string>
+    <string name="power_off" msgid="4266614107412865048">"Söndür"</string>
+    <string name="silent_mode_silent" msgid="319298163018473078">"Zəng deaktivdir"</string>
+    <string name="silent_mode_vibrate" msgid="7072043388581551395">"Zəng vibrasiyadadır"</string>
+    <string name="silent_mode_ring" msgid="8592241816194074353">"Zəngvuran açıqdır"</string>
+    <string name="shutdown_progress" msgid="2281079257329981203">"Söndürülür..."</string>
+    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Planşetiniz sönəcək."</string>
+    <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Telefonunuz sönəcək."</string>
+    <string name="shutdown_confirm_question" msgid="2906544768881136183">"Söndürmək istəyirsiz?"</string>
+    <string name="reboot_safemode_title" msgid="7054509914500140361">"Təhlükəsiz rejimdə yenidən başlayın"</string>
+    <string name="reboot_safemode_confirm" msgid="55293944502784668">"Təhlükəsiz rejimdə yenidən başlamaq istəyirsiniz mi? Bu, quraşdırdığınız bütün üçüncü tərəf tətbiqlərini deaktiv edəcək."</string>
+    <string name="recent_tasks_title" msgid="3691764623638127888">"Son"</string>
+    <string name="no_recent_tasks" msgid="8794906658732193473">"Heç bir son tətbiq yoxdur."</string>
+    <string name="global_actions" product="tablet" msgid="408477140088053665">"Planşet seçimləri"</string>
+    <string name="global_actions" product="default" msgid="2406416831541615258">"Telefon seçimləri"</string>
+    <string name="global_action_lock" msgid="2844945191792119712">"Ekran kilidi"</string>
+    <string name="global_action_power_off" msgid="4471879440839879722">"Söndür"</string>
+    <string name="global_action_bug_report" msgid="7934010578922304799">"Baq hesabatı"</string>
+    <string name="bugreport_title" msgid="2667494803742548533">"Baqı xəbər verin"</string>
+    <string name="bugreport_message" msgid="398447048750350456">"Bu, sizin hazırkı cihaz durumu haqqında məlumat toplayacaq ki, elektron məktub şəklində göndərsin. Baq raportuna başlamaq üçün bir az vaxt lazım ola bilər, bir az səbr edin."</string>
+    <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Səssiz rejim"</string>
+    <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Səs qapalıdır"</string>
+    <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Səs Aktivdir"</string>
+    <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Təyyarə rejimi"</string>
+    <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Uçuş rejimi açıqdır"</string>
+    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Təyyarə rejimi qapalıdır"</string>
+    <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
+    <string name="safeMode" msgid="2788228061547930246">"Təhlükəsiz rejim"</string>
+    <string name="android_system_label" msgid="6577375335728551336">"Android sistemi"</string>
+    <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Ödənişli xidmətlər"</string>
+    <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Xərc tutulacaq əməliyyatlar edir"</string>
+    <string name="permgrouplab_messages" msgid="7521249148445456662">"Sizin mesajlarınız"</string>
+    <string name="permgroupdesc_messages" msgid="7821999071003699236">"SMS, elektron poçt və digər mesajları oxuyur və yazır."</string>
+    <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Şəxsi məlumatınız"</string>
+    <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"Kontakt kartınızda saxlanılan məlumatlarınıza birbaşa giriş."</string>
+    <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Sosial məlumatınız"</string>
+    <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Kontaktlarınız və sosial əlaqələriniz haqqında məlumata birbaşa giriş."</string>
+    <string name="permgrouplab_location" msgid="635149742436692049">"Yerləşməniz"</string>
+    <string name="permgroupdesc_location" msgid="5704679763124170100">"Fiziki adresinizi monitorinq edir."</string>
+    <string name="permgrouplab_network" msgid="5808983377727109831">"Şəbəkə kommunikasiyası"</string>
+    <string name="permgroupdesc_network" msgid="4478299413241861987">"Müxtəlif şəbəkə xüsusiyyətlərinə daxil ol."</string>
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"Bluetooth"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"Bluetooth üzərindən cihazlara və şəbəkələrə daxil ol."</string>
+    <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"Audio Ayarlar"</string>
+    <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"Audio ayarları dəyişin."</string>
+    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Batareyaya təsir edir"</string>
+    <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Batareyanızın tez qurtarmasına səbəb olan funksiyalar istifadə edir"</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"Təqvim"</string>
+    <string name="permgroupdesc_calendar" msgid="5777534316982184416">"Təqvimə və tədbirlərə birbaşa giriş."</string>
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"İstifadəçi Lüğətini Oxu"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"İstifadəçi lüğətindəki sözləri oxuyur."</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"İstifadəçi Lüğətini Yaz"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"İstifadəçi lüğətinə sözlər əlavə edin."</string>
+    <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Əlfəcinlər və Tarixçə"</string>
+    <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Əlfəcinlərə və brauzer tarixinə birbaşa icazə."</string>
+    <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"Zəng"</string>
+    <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"Alarm qur."</string>
+    <string name="permgrouplab_voicemail" msgid="4162237145027592133">"Səsli poçt"</string>
+    <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"Səs poçtuna birbaşa çıxış."</string>
+    <string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
+    <string name="permgroupdesc_microphone" msgid="7106618286905738408">"Audio yazmaq üçün mikrofona birbaşa giriş."</string>
+    <string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
+    <string name="permgroupdesc_camera" msgid="2933667372289567714">"Şəkil və ya video çəkmək üçün kameraya birbaşa çıxış."</string>
+    <string name="permgrouplab_screenlock" msgid="8275500173330718168">"Ekran kilidi"</string>
+    <string name="permgroupdesc_screenlock" msgid="7067497128925499401">"Cihazınızdakı kilid ekranının hərəkətinə təsir etmə bacarığı"</string>
+    <string name="permgrouplab_appInfo" msgid="8028789762634147725">"Tətbiq məlumatlarınız"</string>
+    <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"Cihazınızdakı digər tətbiqlərin davranışına təsir etmək bacarığı."</string>
+    <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"Divar kağızı"</string>
+    <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"Cihazın divar kağızı ayarlarını dəyişin."</string>
+    <string name="permgrouplab_systemClock" msgid="406535759236612992">"Saat"</string>
+    <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"Cihazın vaxt və zaman zolağını dəyişir."</string>
+    <string name="permgrouplab_statusBar" msgid="2095862568113945398">"Status paneli"</string>
+    <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"Cihazın status paneli ayarlarınızı dəyişir."</string>
+    <string name="permgrouplab_syncSettings" msgid="3341990986147826541">"Sinx Ayarları"</string>
+    <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"Sinxronizasiya nizamlarına çıxış."</string>
+    <string name="permgrouplab_accounts" msgid="3359646291125325519">"Hesablarınız"</string>
+    <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Əlçatımlı hesablara daxil olun."</string>
+    <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Hardware kontrolları"</string>
+    <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Dəstəkdəki avadanlığa birbaşa giriş."</string>
+    <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Telefon zəngləri"</string>
+    <string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"Telefon zənglərinə nəzarət edin, qeydə alın və idarə edin."</string>
+    <string name="permgrouplab_systemTools" msgid="4652191644082714048">"Sistem alətləri"</string>
+    <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"Aşağı səviyyəli çıxış və sistem idarəetməsi."</string>
+    <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"İnkişaf alətləri"</string>
+    <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"Özəlliklər yalnız tətbiq developerləri üçün lazımdır."</string>
+    <string name="permgrouplab_display" msgid="4279909676036402636">"Digər tətbiq İstifadəçi İnterfeysi"</string>
+    <string name="permgroupdesc_display" msgid="6051002031933013714">"Digər tətbiqlərin İstifadəçi İnterfeysinə təsir edir."</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"Yaddaş"</string>
+    <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"USB yaddaşa daxil ol."</string>
+    <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"SD karta daxil ol."</string>
+    <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"Əlçatımlılıq funksiyaları"</string>
+    <string name="permgroupdesc_accessibilityFeatures" msgid="4205196881678144335">"Yardımçı texnologiya tələb edə biləcəyi funksiyalar."</string>
+    <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Pəncərənin məzmununu əldə edin"</string>
+    <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Əlaqədə olduğunuz pəncərənin məzmununu nəzərdən keçirin."</string>
+    <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Toxunaraq Kəşf et funksiyasını yandırın"</string>
+    <string name="capability_desc_canRequestTouchExploration" msgid="5800552516779249356">"Toxunulan hissələr səsləndiriləcək və ekran jestlərlə idarə oluna biləcək."</string>
+    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"İnkişaf etmiş veb əlçatımlılığı yandırın"</string>
+    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Skriptlər tətbiq məzmununun daha əlçatımlı olması üçün quraşdırıla bilər."</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Yazdığınız mətni izləyin"</string>
+    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Kredit kartı nömrələri və parollar kimi şəxsi məlumatlar daxildir."</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"status panelini deaktivləşdir və ya dəyişdir"</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"Tətbiqə status panelini deaktiv etməyə və ya sistem ikonalarını əlavə etmək və ya silmək imkanı verir."</string>
+    <string name="permlab_statusBarService" msgid="7247281911387931485">"status paneli"</string>
+    <string name="permdesc_statusBarService" msgid="716113660795976060">"Tətbiqə status paneli olmağa imkan verir."</string>
+    <string name="permlab_expandStatusBar" msgid="1148198785937489264">"status panelini genişlətmək və ya yığmaq"</string>
+    <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"Tətbiqə status panelini genişləndirməyə və ya yox etməyə imkan verir."</string>
+    <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"gedən zənglərin marşrutunu dəyişmək"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Tətbiqə zəng etməyə və zəng edilən nömrəni dəyişməyə imkan verir. Zərərli tətbiqlər bundan istifadə edərək gedən zəngləri izləyə, yönləndirə və ya qarşısını ala bilər."</string>
+    <string name="permlab_receiveSms" msgid="8673471768947895082">"SMS qəbul etmək"</string>
+    <string name="permdesc_receiveSms" msgid="6424387754228766939">"Tətbiqə MMS mesajlarını almaq və emal etmək icazəsi verir. Bu o deməkdir ki, tətbiq sizin mesajlarınızı sizə göstərmədən monitorinq edə və ya silə bilər."</string>
+    <string name="permlab_receiveMms" msgid="1821317344668257098">"mətn mesajlarını qəbul edir (MMS)"</string>
+    <string name="permdesc_receiveMms" msgid="533019437263212260">"Tətbiqə MMS mesajlarını qəbul və emal üçün imkan verir. Bu o deməkdir ki, bu tətbiq sizə göstərmədən cihazınıza göndərilən mesajları silə bilər."</string>
+    <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"təcili yayımları qəbul edir"</string>
+    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Tətbiqə təcili yayım mesajlarını qəbul və emal etmək icazəsi verir. Bu icazə ancaq sistem tətbiqləri üçün mümkündür."</string>
+    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"mobil yayım mesajlarını oxuyur"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Tətbiqə sizin telefonunuz tərəfindən alınmış yayım mesajlarını oxuma icazəsi verir. Telefon yayımı bəzi məkanlarda olan fövqəladə hadisələrlə bağlı sizi xəbərdar etmək üçün qəbul edilir. Zərərli tətbiqlər fövqəladə mobil yayım qəbul edildiyi zaman telefonunun performansına və əməliyyatına müdaxilə edə bilər."</string>
+    <string name="permlab_sendSms" msgid="5600830612147671529">"SMS mesajlarını göndərir"</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"Tətbiqə SMS mesajı göndərmə icazəsi verir. Bu gözlənilməyən ödənişlərə səbəb ola bilər. Zərərli tətbiqlər sizin təsdiqiniz olmadan mesaj göndərməklə sizə ödənişə səbəb ola bilərlər."</string>
+    <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"mesajla cavab verilməli tədbirlər göndərmək"</string>
+    <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"Tətbiqə zənglər üçün \"mesajla cavabla\" hadisələrini idarə etmək üçün digər mesajlaşma tətbiqlərinə sorğuların göndərilməsi icazəsi verir."</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"tekst mesajlarınızı oxuyur (SMS və ya MMS)"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Tətbiqə planşetinizdə və ya SIM kartınızda saxlanan SMS mesajları oxumağa imkan verir. Bu bütün SMS mesajların, onların məzmunundan və konfidensiallığından asılı olmadan oxunması imkanı deməkdir."</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Tətbiqə telefonunuzda və ya SIM kartınızda saxlanan SMS mesajları oxumağa imkan verir. Bu bütün SMS mesajların, onların məzmunundan və konfidensiallığından asılı olmadan oxunması imkanı deməkdir."</string>
+    <string name="permlab_writeSms" msgid="3216950472636214774">"mətn mesajlarınızı redaktə edir (SMS və ya MMS)"</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Tətbiqə telefonunuzda və ya SİM kartınızda yerləşən SMS mesajlara yazma icazəsi verir. Zərərli tətbiqlər sizin mesajlarınızı silə bilər."</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Tətbiqə telefonunuzda və ya SİM kartınızda yerləşən SMS mesajlara yazma icazəsi verir. Zərərli tətbiqlər sizin mesajlarınızı silə bilər."</string>
+    <string name="permlab_receiveWapPush" msgid="5991398711936590410">"mətn mesajları qəbul etmək (WAP)"</string>
+    <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Tətbiqə WAP mesajlar göndərmək və ya qəbul etmək imkanı verir. Buna mesajları izləmək və Sizə xəbər vermədən silmək imkanları da daxildir."</string>
+    <string name="permlab_getTasks" msgid="6466095396623933906">"işlənən tətbiqlər əldə etmək"</string>
+    <string name="permdesc_getTasks" msgid="7454215995847658102">"Tətbiqə hazırda və az öncə işləyən tapşırıqlar haqqında ətraflı məlumat əldə etməyə imkan verir. Bu da cihazda hansı tətbiqlərin istifadə olunması haqqında məlumatların əldə edilməsinə imkan verir."</string>
+    <string name="permlab_interactAcrossUsers" msgid="7114255281944211682">"istifadəçilər arasında əlaqə qurur"</string>
+    <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Tətbiqə bu cihazdakı digər istifadəçilərlə müxtəlif işləri görməyə icazə verir. Zərərli tətbiqlər bundan istifadəçilər arasındakı qorunmanı pozmaq üçün istifadə edə bilər."</string>
+    <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"bütün istifadəçilər ilə əlaqə saxlamaq üçün tam hüquq"</string>
+    <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"İstifadəçilər arasında bütün mümkün əlaqələrə imkan verir."</string>
+    <string name="permlab_manageUsers" msgid="1676150911672282428">"istifadəçiləri idarə edir"</string>
+    <string name="permdesc_manageUsers" msgid="8409306667645355638">"Tətbiqlərə cihazda olan istifadəçiləri, habelə sorğu göndərmə, yaratma və silmə izni verir."</string>
+    <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"işlənən tətbiqlərin detallarını əldə etmək"</string>
+    <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Tətbiqə hazırda və az öncə işləyən tapşırıqlar haqqında ətraflı məlumat əldə etməyə imkan verir. Zərərli tətbiqlər bundan istifadə edərək şəxsi məlumatları oğurlaya bilər."</string>
+    <string name="permlab_reorderTasks" msgid="2018575526934422779">"işlənən tətbiqlərin sırasını dəyişmək"</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Tətbiqə tapşırıqları ön plandan arxa plana keçirməyə imkan verir. Tətbiq bunu Sizin daxiletməniz olmadan da edə bilər."</string>
+    <string name="permlab_removeTasks" msgid="6821513401870377403">"işlək tətbiqləri dayandırır"</string>
+    <string name="permdesc_removeTasks" msgid="1394714352062635493">"Tətbiqə tapşırıqları silməyə və onların tətbiqlərini məhv etməyə imkan verir. Zərərli tətbiqlər bundan istifadə edərək digər tətbiqlərin işlərini dayandıra bilər."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"fəaliyyət toplularını idarə edin"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Tətbiqə digər tətbiqlərin fəaliyyəti daxilində fəaliyyət toplularını əlavə etmək, silmək və dəyişmək imkanı verir."</string>
+    <string name="permlab_startAnyActivity" msgid="2918768238045206456">"hər hansı bir fəaliyyət başlat"</string>
+    <string name="permdesc_startAnyActivity" msgid="997823695343584001">"İcazə qorunması və ya eksport edilmiş statusdan asılı olmayaraq, tətbiqə hər hansı fəaliyyəti başlatmağa imkan verir."</string>
+    <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"ekran uyğunluğunu yerləşdirir"</string>
+    <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Tətbiqə digər tətbiqlərin ekran uyğunluğunu yoxlamaq imkanı verir. Zərərli tətbiqlər digər tətbiqlərin fəaliyyətini poza bilər."</string>
+    <string name="permlab_setDebugApp" msgid="3022107198686584052">"tətbiq sazlanmasını aktiv edir"</string>
+    <string name="permdesc_setDebugApp" msgid="4474512416299013256">"Tətbiqə digər bir tətbiq üçün sazlamanı açmaq üçün imkan verir. Zərərli tətbiqlər bunu digər tətbiqləri yox etmək üçün istifadə edə bilər."</string>
+    <string name="permlab_changeConfiguration" msgid="4162092185124234480">"sistem ekran nizamlarını dəyiş"</string>
+    <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"Tətbiqə yerli parametrlər və ya şriftin ölçüsü kimi cari konfiqurasiyanı dəyişməyə imkan verir."</string>
+    <string name="permlab_enableCarMode" msgid="5684504058192921098">"avtomobil rejimini aktivləşdirir"</string>
+    <string name="permdesc_enableCarMode" msgid="4853187425751419467">"Tətbiqə avtomobil rejimini aktivləşdirməyə imkan verir."</string>
+    <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"digər tətbiqləri qapatmaq"</string>
+    <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"Tətbiqə başqa tətbiqlərin arxafon proseslərini dayandırmaq icazəsi verir. Bu digər tətbiqlərin dayanmasına səbəb ola bilər."</string>
+    <string name="permlab_forceStopPackages" msgid="2329627428832067700">"Digər tətbiqləri dayanmağa məcbur et"</string>
+    <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"Tətbiqə digər tətbiqləri məcburi şəkildə dayandırmağa imkan verir."</string>
+    <string name="permlab_forceBack" msgid="652935204072584616">"tətbiqi qapanmağa məcbur etmək"</string>
+    <string name="permdesc_forceBack" msgid="3892295830419513623">"Tətbiqə ön planda olan istənilən tətbiqi bağlayaraq geriyə dönməyə imkan verir. Normal tətbiqlər tərəfindən heç vaxt istifadə olunmamalıdır."</string>
+    <string name="permlab_dump" msgid="1681799862438954752">"sistemin daxili durumunu bərpa et"</string>
+    <string name="permdesc_dump" msgid="1778299088692290329">"Tətbiqə sistemin daxili statusunu bərpa etməyə imkan verir. Zərərli tətbiqlər lazım olmadığı halda müxtəlif şəxsi və güvənli məlumatları bərpa edə bilər."</string>
+    <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"ekran kontentini bərpa edir"</string>
+    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Tətbiqə aktiv pəncərənin məzmununu əldə etməyə imkan verir. Zərərli tətbiqlər bundan istifadə edərək pəncərə məzmununu ələ keçirib parollları oxuya bilər."</string>
+    <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"giriş imkanını müvəqqəti açmaq"</string>
+    <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"Tətbiqə cihaza girişi müvəqqəti olaraq aktivləşdirməyə imkan verir. Zərərli tətbiqlər istifadəçi razılığı olmadan girişi aktivləşdirə bilər."</string>
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"pəncərə infosunu bərpa edir"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Tətbiqə pəncərə idarəçisindən gələn windows haqqında olan məlumatı bərpa etməyə imkan verir. Zərərli tətbiqlər daxili sistem istifadəsi üçün nəzərdə tutulan məlumatı bərpa edə bilər."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"tədbirləri filtr edir"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Tətbiqə daxiletmə filtrini qeydiyyat etdirməyə imkan verir, bu filtr bütün istifadəçi tədbirlərini göndərilməmişdən əvvəl filtrdən keçirir. Zərərli tətbiq istifadəçi müdaxiləsi olmadan İstifadəçi İnterfeysi sisteminə nəzarət edə bilər."</string>
+    <string name="permlab_magnify_display" msgid="5973626738170618775">"ekranı böyüdür"</string>
+    <string name="permdesc_magnify_display" msgid="7121235684515003792">"Tətbiqə ekran kontentini böyütmək icazəsi verir. Zərərli tətbiqlər bundan istifadə edərək ekranda kontenti böyüdərək cihazın qeyri-stabilliyinə səbəb ola bilər."</string>
+    <string name="permlab_shutdown" msgid="7185747824038909016">"qismən söndürür"</string>
+    <string name="permdesc_shutdown" msgid="7046500838746291775">"Aktivlik idarəçiliyini qapanmış hala gətirir. Tam qapanmanı həyata keçirmir."</string>
+    <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"tətbiqdən tətbiqə keçidin qarşısını almaq"</string>
+    <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"İstifadəçinin başqa tətbiqə keçməsinin qarşısını alır."</string>
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"cari tətbiq informasiyası əldə etmək"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="8153651434145132505">"Sahibə ekran önündə cari tətbiq və xidmətlər haqqında şəxsi məlumat əldə etməyə imkan verir."</string>
+    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"işə salınan bütün tətbiqləri izləyir və idarə edir"</string>
+    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Tətbiqə sistemin fəaliyyətləri necə başlatdığını nəzarət və kontrol etməyə imkan verir. Zərərli tətbiqlər sistemi tamamilə kompromis edə bilər. Bu icazə yalnız inkişaf üçündür, heç vaxt normal istifadə üçün deyil."</string>
+    <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"qaldırılmış yayım paketini göndər"</string>
+    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"Tətbiqə tətbiq paketinin silinməsi haqqında bildiriş translasiya etmə icazəsi verir. Zərərli tətbiqlər bundan digər işlək tətbiqləri dayandırmaq üçün istifadə edə bilər."</string>
+    <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"SMS tərəfindən qəbul edilən yayım göndər"</string>
+    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"Tətbiqə mesaj gəlməsi haqqında bildirişi yayımlamaq imkanı verir. Zərərli tətbiqlər bundan gələn SMS mesajlarını saxtalaşdırmaq üçün istifadə edə bilər."</string>
+    <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"WAP-PUSH tərəfindən qəbul edilən yayım göndər"</string>
+    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"Tətbiqə WAP PUSH mesajın alındığı haqda bildiriş translasiya etməyə icazə verir. Zərərli tətbiqlər bundan istifadə edərək saxta MMS mesaj alışı və ya səssizcə istənilən veb səhifəni zərərverici variantlarla dəyişmək üçün istifadə edə bilər."</string>
+    <string name="permlab_setProcessLimit" msgid="2451873664363662666">"çalışan proseslərin sayını məhdudlaşdırır"</string>
+    <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"Tətbiqə işlədiləcək maksimum proses sayını idarə etmə izni verir. Normal tətbiqlər tərəfindən tələb olunmur."</string>
+    <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"arxafon tətbiqlərini dayanmağa məcbur edir"</string>
+    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"Tətbiqə aktivitilərin arxa fona getdiyi zaman bitməsini yoxlayır. Normal tətbiqlər tərəfindən tələn olunmur."</string>
+    <string name="permlab_batteryStats" msgid="2789610673514103364">"batareya statistikalarını oxumaq"</string>
+    <string name="permdesc_batteryStats" msgid="5897346582882915114">"Tətbiqə cari aşağı səviyyəli data sitifadəsini oxumaq imkanı verir. Tətbiqə hansı tətbiqi istifadə etdiyiniz haqqında ətraflı məlumat tapmağa imkan verə bilər."</string>
+    <string name="permlab_updateBatteryStats" msgid="3719689764536379557">"batareya statistikalarını dəyişmək"</string>
+    <string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"Tətbiqə yığılmış batareya statistikasını redaktə etmə icazəsi verir. Normal tətbiqlər tərəfindən istifadə edilmir."</string>
+    <string name="permlab_getAppOpsStats" msgid="1508779687436585744">"tətbiq əməliyyat statistikalarını əldə etmək"</string>
+    <string name="permdesc_getAppOpsStats" msgid="6243887041577912877">"Toplanmış tətbiq əməliyyat statistikalarının bərpa edilməsinə imkan verir. Normal tətbiqlər tərəfindən istifadə üçün deyil."</string>
+    <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"tətbiq əməliyyat statistikasını dəyişmək"</string>
+    <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"Tətbiqə toplanmış tətbiq əməliyyat statistikasını dəyişməyə imkan verir. Normal tətbiqlər tərəfindən istifadə olunmur."</string>
+    <string name="permlab_backup" msgid="470013022865453920">"sistem yedəkləməsi və bərpasını idarə edir"</string>
+    <string name="permdesc_backup" msgid="6912230525140589891">"Tətbiqə sistemi rezerv etməyə və mexanizmi bərpa etməyə imkan verir. Normal tətbiqlər tərəfindən istifadə edilmək üçün nəzərdə tutulmayıb.."</string>
+    <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"tam rezervi təsdiq etmək və ya əməliyyatı bərpa etmək"</string>
+    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"Tətbiqə İstifadəçi İnterfeysi tam rezerv təsdiqini işə salmağa imkan verir. Heç bir tətbiq tərəfindən istifadə olunmamalıdır."</string>
+    <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"icazəsiz pəncərələri görüntüləyir"</string>
+    <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"Tətbiqə daxili sistem interfeysi tərəfindən istifadə edilməsi üçün nəzərdə tutulmuş pəncərələri yaratmağa icazə verir. Normal tətbiqlər tərəfindən istifadə edilmir."</string>
+    <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"digər tətbiqlər üzərində çəkmək"</string>
+    <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"Tətbiqə digər tətbiqlərin və ya onların hissələrinin yuxarısında şəkil çəkməyə imkan verir. Onlar istənilən tətbiqin interfeysinin istifadəsinə müdaxilə edə və ya digər tətbiqlərdə axtardıqlarınızı dəyişə bilər."</string>
+    <string name="permlab_setAnimationScale" msgid="2805103241153907174">"qlobal animasiya sürətini dəyişir"</string>
+    <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"Tətbiqə istənilən vaxt qlobal animasiya sürətini (sürətli və ya yavaş animasiyalar) dəyişdirmək imkanı verir."</string>
+    <string name="permlab_manageAppTokens" msgid="1286505717050121370">"tətbiq nişanlarını idarə etmək"</string>
+    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"Tətbiqlərə onların normal Z-orderinqi keçərək markerlərini yaratma və idarəetmə icazəsi verir. Normal tətbiqlər tərəfindən istifadə olunmur."</string>
+    <string name="permlab_freezeScreen" msgid="4708181184441880175">"ekranı dondurur"</string>
+    <string name="permdesc_freezeScreen" msgid="8558923789222670064">"Tətbiqə tam ekranlı yayım üçün ekranı müvəqqəti olaraq dondurma icazəsi verir."</string>
+    <string name="permlab_injectEvents" msgid="1378746584023586600">"düymələri və idarəetmə düymələrini basır"</string>
+    <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"Tətbiqə özünün daxiletmə tədbirlərini digər tətbiqlərə çatdırmağa imkan verir. Zərərli tətbiqlər planşeti ələ keçirmək üçün bundan istifadə edə bilər."</string>
+    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"Tətbiqə özünün daxiletmə tədbirlərini digər tətbiqlərə çatdırmağa imkan verir. Zərərli tətbiqlər telefonu ələ keçirmək üçün bundan istifadə edə bilər."</string>
+    <string name="permlab_readInputState" msgid="469428900041249234">"yazdıqlarınızı və etdiklərinizi izləyir"</string>
+    <string name="permdesc_readInputState" msgid="8387754901688728043">"Tətbiqə basdığınız düymələri izləmək imkanı verilir. Buna parolların və kredit kartı nömrələrinin yazılması da aiddir. Normal tətbiqlər tərəfindən istifadə olunmur."</string>
+    <string name="permlab_bindInputMethod" msgid="3360064620230515776">"daxiletmə metoduna bağlanır"</string>
+    <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Sahibinə daxiletmə metodunun ən üst səviyyə interfeysinə bağlamaq imkanı verir. Normal tətbiqlər üçün heç vaxt lazım olmamalıdır."</string>
+    <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"giriş xidmətinə bağlı qal"</string>
+    <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Sahibə giriş xidmətin ən üst səviyyə interfeysi bağlamağa imkan verir. Normal tətbiqlər üçün heç vaxt lazım olmamalıdır."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"çap servisini qoşma"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Sahibinə bir çap xidmətinin ən üst səviyə araüzünü bağlamağa imkan verir. Normal tətbiqlər üçün heç vaxt lazım olmamalıdır."</string>
+    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"bütün çap işlərinə giriş əldə et"</string>
+    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Sahibinə digər tətbiqlər tərəfindən yaradılan çap işlərinə giriş hüququ verir. Normal tətbiqlər üçün tələb olunmamalıdır."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC xidmətlərinə qoşun"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Sahibinə NFC kartlarını emulyasiya edən tətbiqləri bir-birinə qoşmağa icazə verin. Normal tətbiqlər üçün lazım deyil."</string>
+    <string name="permlab_bindTextService" msgid="7358378401915287938">"mətn servisini qoşma"</string>
+    <string name="permdesc_bindTextService" msgid="8151968910973998670">"Sahibinə bir mətn xidmətinin ən üst səviyyə araüzünü bağlamağa imkan verir(məsələn, SpellCheckerService). Normal tətbiqlər üçün heç vaxt lazım olmamalıdır."</string>
+    <string name="permlab_bindVpnService" msgid="4708596021161473255">"VPN xidmətə əlaqələndirmək"</string>
+    <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Sahibinə bir Vpn xidmətinin ən üst səviyyə araüzünü bağlamağa imkan verir. Normal tətbiqlər üçün heç vaxt lazım olmamalıdır."</string>
+    <string name="permlab_bindWallpaper" msgid="8716400279937856462">"divar kağızına bağlanır"</string>
+    <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Cihaz sahibinə yuxarı səviyyəli divar kağızı interfeysini cildləməyə imkan verir. Normal tətbiqlər tərəfindən istifadə olunmamalıdır."</string>
+    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"widget servisini qoşma"</string>
+    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Sahibinə vidcet servisin yüksək səviyyəli interfeysi ilə əlaqə saxlamaq icazəsi verir. Normal tətbiqlər tərəfindən heç vaxt istənilməməlidir."</string>
+    <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"cihaz admini ilə ünsiyyət qurmaq"</string>
+    <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Sahibinə bir cihaz idarəçisinə planlar göndərmək üçün imkan verir. Normal tətbiqlər üçün heç vaxt lazım olmamalıdır."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"cihaz admini əlavə edin və ya silin"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Sahibinə aktiv cihaz administratorlarını əlavə etməyə və ya silməyə icazə verir. Normal tətbiqlər üçün tələb olunmamalıdır."</string>
+    <string name="permlab_setOrientation" msgid="3365947717163866844">"ekran oriyentasiyasını dəyişir"</string>
+    <string name="permdesc_setOrientation" msgid="3046126619316671476">"Tətbiqə istənilən zaman ekranın vəziyyətini dəyişmə icazəsi verir. Normal tətbiqlər tərəfindən tələb olunmur."</string>
+    <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"kursor sürətini dəyişmək"</string>
+    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Tətbiqə mausun və ya trekpedin kursor sürətini istənilən zaman dəyişməyə imkan verir. Normal tətbiqlər tərəfindən istifadə olunmamalıdır."</string>
+    <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"klaviatura sxemini dəyişir"</string>
+    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Tətbiqə klaviatura sxemini dəyişmək imkanı verir. Normal tətbiqlər tərəfindən tələb olunmur."</string>
+    <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"tətbiqlərə Linux siqnalları göndərir"</string>
+    <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Tətbiqə bütün davamlı proseslərə siqnal soğrusu göndərməyə imkan verir."</string>
+    <string name="permlab_persistentActivity" msgid="8841113627955563938">"təbiqi həmişə çalışdır"</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Tətbiqə öz komponentlərini yaddaşda saxlama icazəsi verir. Bu planşetin sürətini zəiflətməklə, digər tətbiqlər üçün mövcud olan yaddaşı limitləyə bilər."</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"Tətbiqə öz komponentlərini yaddaşda saxlama icazəsi verir. Bu digər tətbiqlər üçün mövcud olan yaddaşı limitləyə bilər."</string>
+    <string name="permlab_deletePackages" msgid="184385129537705938">"tətbiqləri sil"</string>
+    <string name="permdesc_deletePackages" msgid="7411480275167205081">"Tətbiqə Android paketləri silmə icazəsi verir. Zərərli tətbiqlər bundan digər vacib tətbiqləri silmək üçün istifadə edə bilər."</string>
+    <string name="permlab_clearAppUserData" msgid="274109191845842756">"digər tətbiqlərin məlumatını silir"</string>
+    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"Tətbiqə istifadəçi datasını təmizləməyə imkan verir."</string>
+    <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"digər tətbiqlərin keşini sil"</string>
+    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"Tətbiqə keş faylları silmə icazəsi verir."</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"tətbiq saxlama yaddaşını ölçmək"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Tətbiqə özünün kodunu, məlumatını və keş ölçüsünü alma icazəsi verir."</string>
+    <string name="permlab_installPackages" msgid="2199128482820306924">"birbaşa tətbiqlər quraşdırmaq"</string>
+    <string name="permdesc_installPackages" msgid="5628530972548071284">"Tətbiqə yeni və ya güncəllənmiş Android paketlərini quraşdırmağa imkan verir. Zərərli tətbiqlər bundan istifadə edərək güclü səlahiyyətlərə malik tətbiqləri endirə bilər."</string>
+    <string name="permlab_clearAppCache" msgid="7487279391723526815">"bütün tətbiq keş datasını silir"</string>
+    <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"Tətbiqə planşetin yaddaşını boşaltmaq üçün digər tətbiqlərin keş fayllarını silmək imkanı verir. Bu da digər tətbiqlərin dataları yenidən əldə etmələri səbəbindən daha yavaş işləmələrinə səbəb ola bilər."</string>
+    <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"Tətbiqə digər tətbiqlərin keş qovluğunu təmizləyərək telefonun yaddaşını boşaltmaq icazəsi verir. Bu digər tətbiqlərin məlumatlarını yenidən əldə etməli olduqlarına görə daha yavaş başlamasına səbəb olur."</string>
+    <string name="permlab_movePackage" msgid="3289890271645921411">"tətbiq resurslarının yerini dəyişir"</string>
+    <string name="permdesc_movePackage" msgid="319562217778244524">"Tətbiqə tətbiq resurslarını daxili mediadan xarici mediaya və əksinə daşımağa imkan verir."</string>
+    <string name="permlab_readLogs" msgid="6615778543198967614">"məxfi loq datasını oxuyur"</string>
+    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Tətbiqə sistemin müxtəlif jurnal fayllarını oxumağa imkan verir. Bu da Sizin planşetdə etdikləriniz haqqında məlumatlar, həmçinin şəxsi və konfidensial məlumatlar ola bilər."</string>
+    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Tətbiqə sistemin müxtəlif jurnal fayllarını oxumağa imkan verir. Bu da Sizin planşetdə etdikləriniz haqqında məlumatlar, həmçinin şəxsi və konfidensial məlumatlar ola bilər."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"oxutmaq üçün istənilən media dekoderi istifadə edir"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Tətbiqə playback\'i deşifrə etmək üçün hər hansı bir quraşdırılmış media deşifrələyicisini istifadə etmık imkanı verir."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"etibarlı etimadnamələri idarə et"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Tətbiqə etibarlı etimadnamələr kimi CA sertifikatlarını quraşdırmaq və sistemdən silməyə icazə verir."</string>
+    <string name="permlab_diagnostic" msgid="8076743953908000342">"diaga məxsus olan mənbələri yaz/oxu"</string>
+    <string name="permdesc_diagnostic" msgid="6608295692002452283">"Tətbiqə diag qrupa məsus olan resursları yazmaq və oxumaq icazəsi verir; məsələn  /dev qovluğundakı fayllar. Bu sistemin stabilliyinə və təhlükəsizliyinə təsir edə bilər. Bu ancaq istehsalçı və ya operator tərəfindən avadanlığa xas diaqnostika üçün olmalıdır."</string>
+    <string name="permlab_changeComponentState" msgid="6335576775711095931">"tətbiq komponentlərini aktivləşdirmə və ya deaktivləşdirmə"</string>
+    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Tətbiqə digər tətbiq komponentinin aktiv olub-olmadığını dəyişmək imkanı verir. Zərərli tətbiqlər bundan əhəmiyyətli planşet imkanlarını deaktiv etmək üçün istifadə edə bilər. Bu icazə ilə ehtiyatlı olmaq lazımdır, çünki tətbiq komponentləri yararsız, ziddiyyətli, və ya qeyri-sabit statusa çevrilə bilər."</string>
+    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Tətbiqə digər tətbiq komponentinin aktiv olub-olmadığını dəyişmək imkanı verir. Zərərli tətbiqlər bundan əhəmiyyətli telefon imkanlarını deaktiv etmək üçün istifadə edə bilər. Bu icazə ilə ehtiyatlı olmaq lazımdır, çünki tətbiq komponentləri yararsız, ziddiyyətli, və ya qeyri-sabit statusa çevrilə bilər."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"icazələr vermək və ya ləğv etmək"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Tətbiqə bu və ya digər tətbiqlərə xüsusi iznlər verməyə icazə verir. Zərərli tətbiqlər  bundan izin vermədiyiniz özəllikləri özlərinə vermək üçün istifadə edə bilər."</string>
+    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"tərcih edilən tətbiqlər qur"</string>
+    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Tətbiqə tərcih etdiyiniz tətbiqləri dəyişmək imkanı verir. Zərərli tətbiqlər şəxsi məlumatlarınızı toplamaq üçün cari tətbiqlərinizi aldadaraq işləyən tətbiqləri xəbərsiz dəyişə bilər."</string>
+    <string name="permlab_writeSettings" msgid="2226195290955224730">"sistem ayarlarında dəyişiklik etmək"</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"Tətbiqə sistem ayarları datasını redaktə etmə icazəsi verir. Zərərli tətbiqlər sistem ayarlarını korlaya bilər."</string>
+    <string name="permlab_writeSecureSettings" msgid="204676251876718288">"təhlükəsiz sistem nizamlarını dəyişir"</string>
+    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"Tətbiqə sistemin təhlükəsiz ayarlar datasını dəyişməyə imkan verir. Normal tətbiqlər tərəfindən istifadə üçün deyil."</string>
+    <string name="permlab_writeGservices" msgid="2149426664226152185">"Google xidmətlər xəritəsini dəyişdir"</string>
+    <string name="permdesc_writeGservices" msgid="1287309437638380229">"Tətbiqə Google xidmətlər xəritəsini dəyişdirmək imkanı verir. Normal tətbiqlərin istifadəsi üçün deyil."</string>
+    <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"başlanğıcda işləyir"</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Tətbiqə sistem yükləməni bitirdiyi zaman dərhal özünü başlatmağa imkan verir. Bu planşeti başlatmağın uzun çəkməsinə səbəb ola bilər və tətbiqə həmişə çalışdıraraq bütün planşeti yavaşlatmağa imkan verir."</string>
+    <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Tətbiqə sistem bootinqi bitirdikdən dərhal sonra özünü başlatmaq icazəsi verir. Bu telefonun açılmasını ləngidə və daima işlək qalaraq telefonun sürətini aşağı sala bilər."</string>
+    <string name="permlab_broadcastSticky" msgid="7919126372606881614">"daimi siqnal göndərmək"</string>
+    <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Tətbiqə yayım bitdikdən sonra da qalan çətin yayımlar göndərməyə imkan verir. Hədsiz istifadə çox yaddaş istifadəsinə səbəb olmaqla planşeti yavaş və qeyri-stabil edə bilər."</string>
+    <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Tətbiqə yayım bitdikdən sonra da qalan çətin yayımlar göndərməyə imkan verir. Hədsiz istifadə çox yaddaş istifadəsinə səbəb olmaqla telefonu yavaş və qeyri-stabil edə bilər."</string>
+    <string name="permlab_readContacts" msgid="8348481131899886131">"kontakrlatınızı oxumaq"</string>
+    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Tətbiqə planşetinizdə yerləşən kontaktları oxumaq icazəsi verir, tez-tez zəng elədiyiniz, emailləşdiyiniz və ya əlaqə saxladığınız xüsusi individuallar daxil olmaqla. Bu icazə tətbiqlərə kontakt məlumatlarınızı saxlamağa və zərərli tətbiqlərə kontakt məlumatlarını sizin bilginiz olmada paylaşma imkanı yaradır."</string>
+    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Tətbiqə tez-tez zəng elədiyiniz, e-məktub göndərdiyiniz və ya əlaqə saxladığınız xüsusi individuallar daxil olmaqla telefonunuzda yerləşən kontaktları oxumaq icazəsi verir. Bu icazə tətbiqlərə kontakt məlumatlarınızı saxlamağa və zərərli tətbiqlərə kontakt məlumatlarını sizin xəbəriniz olmada paylaşma imkanı yaradır."</string>
+    <string name="permlab_writeContacts" msgid="5107492086416793544">"kontaktlarınızı dəyişdirir"</string>
+    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Tətbiqə planşetinizdəki zəng etmək tezliyiniz, elektron poçtlarınız, ünsiyyətləriniz haqqında məlumatları dəyişməyə imkan verir. Bu icazə kontakt məlumatlarının silinməsinə də imkan verir."</string>
+    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Tətbiqə Sizin zəng etmək tezliyiniz, elektron poçtlarınız, ünsiyyətləriniz haqqında məlumatları dəyişməyə imkan verir. Buna kontaktların silinməsi imkanı də daxildir."</string>
+    <string name="permlab_readCallLog" msgid="3478133184624102739">"zəng qeydiyyatını oxu"</string>
+    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Tətbiqə gələn və gedən zənglər haqqında olan data daxil olmaqla bərabər planşetinizin zəng qeydiyyatını oxumağa imkan verir. Bu icazə tətbiqlərə zəng qeydiyyatınızı saxlamağa imkan verir və zərərli tətbiqlər zəng qeydiyyat datasını sizdən xəbərsiz paylaşa bilər."</string>
+    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Tətbiqə telefon jurnalınızı oxumağa imkan verir, buna gələn və gedən zənglər haqqında məlumatlar da daxildir. Bu icazə tətbiqə zəng jurnalı datasını saxlamağa imkan verir ki, Zərərli tətbiqlər bundan istifadə edərək Sizdən xəbərsiz bütün məlumatlarnızı paylaşa bilər."</string>
+    <string name="permlab_writeCallLog" msgid="8552045664743499354">"zəng loqu yazır"</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Tətbiqə planşetinizdəki zəng jurnalını, həmçinin gedən və gələn zənglərin siyahısını dəyişməyə imkan verir. Zərərli tətbiqlər bundan istifadə edərək, zəng jurnalınıza dəyişiklik edə bilər."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Tətbiqə sizin daxil olan və gedən zənglər daxil olmaqla telefon zəngi loqlarınızı redaktə etmək icazəsi verir. Zərərli tətbiqlər bundan telefon loqlarınızı silmək və ya redaktə etmək üçün istifadə edə bilər."</string>
+    <string name="permlab_readProfile" msgid="4701889852612716678">"öz kontakt kartınızı oxuyun"</string>
+    <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Tətbiqə cihazınızda yerləşən adınız və kontakt məlumatlarınız kimi şəxsi profil məlumatlarını oxuma icazəsi verir. Bu o deməkdir ki, tətbiq sizi tanıya və sizin profil məlumatlarınızı başqalarına göndərə bilər."</string>
+    <string name="permlab_writeProfile" msgid="907793628777397643">"sizin kontakt kartınızda dəyişiklik etmək"</string>
+    <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Tətbiqə cihazınızda yerləşən adınız və kontakt məlumatlarınız kimi şəxsi profil məlumatlarını dəyişmək və ya əlavə etmək icazəsi verir. Bu o deməkdir ki, tətbiq sizi tanıya və sizin profil məlumatlarınızı başqalarına göndərə bilər."</string>
+    <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"sosial lentinizi oxuyur"</string>
+    <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Tətbiqə Sizin və dostlarınızın sosial güncəllərini əldə etmək və sinxronizə etmək icazəsi verir. Məlumat paylaşarkən diqqətli olun - konfidensiallıqdan asılı olmayaraq bu, Siz və dostlarınız arasında sosial şəbəkələrdəki danışığı oxumaq imkanı verir. Qeyd: bu icazə bütün sosial şəbəkələrdə icra edilə bilməz."</string>
+    <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"sosial axınınıza yazır"</string>
+    <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Tətbiqə dostlarınızdan sosial yenilənmələri göstərmə icazəsi verir. Məlumat paylaşarkən diqqətli olun - bu dostlarınızdan gələn mesajı emal etməyə izn verir. Qeyd: bu icazə bütün sosial şəbəkələrə şamil olunmaya bilər."</string>
+    <string name="permlab_readCalendar" msgid="5972727560257612398">"təqvim tədbirlərini və konfidensial məlumatları oxuyur"</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Tətbiqə dostlarınızın və əməkdaşlarınızın planşetinizdə yerləşən kalendar tədbirlərini oxumağa icazə verir. Bu tətbiqə konfidensiallıq və ya həssaslıqdan asılı olmayaraq sizin kalendar məlumatlarınızı paylaşmaq və ya saxlamağa imkan yaradır."</string>
+    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Tətbiqə dost və əməkdaşlara məxsus olanlar daxil olmaqla planşetdə yerləşən bütün kalendar tətbiqlərini oxumaq icazəsi verir. Bu tətbiqə konfidensiallıq və ya həssaslıqdan asılı olmayaraq, Sizin kalendar məlumatlarınızı paylaşmaq və ya saxlamaq imkanı yaradır."</string>
+    <string name="permlab_writeCalendar" msgid="8438874755193825647">"cihaz sahibinin icazəsi olmadan təqvim tədbirləri əlavə etmək və ya dəyişmək, bunun haqqında bildirişlər göndərmək"</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Tətbiqə planşetinizdəki tədbirləri dəyişməyə, tədbir əlavə etməyə və ya silməyə imkan verir. Buna Sizin dostlarınızla və həmkarlarınızla birlikdə hazırladığınız tədbirlər də daxildir. Bu, tədbirə Sizin adınızdan və Sizdən xəbərsiz, təqvim sahibi kimi mesaj göndərmək imkanını verir."</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Dostlarınız və həmkarlarınıza məxsus olanlar da daxil olmaqla, tətbiqə telefonunuzdakı tədbirləri dəyişməyə, tədbir əlavə etməyə və ya silməyə imkan verir. Bu, tədbirə Sizin adınızdan və Sizdən xəbərsiz, təqvim sahibi kimi mesaj göndərmək imkanı verir."</string>
+    <string name="permlab_accessMockLocation" msgid="8688334974036823330">"test üçün saxta məkan mənbələri"</string>
+    <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Test üçün saxta məkan mənbələri yaradın və ya yeni məkan provayderi quraşdırın. Bu tətbiqlərə GPS və məkan provayderləri kimi məkan mənbələrindən alınan məkan və/ya statusları yenidən yazmağa icazə verir."</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"əlavə məkan provayderi əmrlərinə çıxış"</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"Tətbiqə əlavə məkan provayderi əmrlərinə daxil olmaq imkanı verir. Bu tətbiqə GPS əməliyyatına və ya digər məkan mənbələrinə mane olmaq imkanı verə bilər."</string>
+    <string name="permlab_installLocationProvider" msgid="6578101199825193873">"Məkan provayderini quraşdırmaq icazəsi"</string>
+    <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"Yeni yerləşmə təchizatçısını test etmək və ya quraşdırmaq üçün mock yerləşmə mənbələri yarat. Bu tətbiqə yerləşmənin və/ya digər yerləşmə mənbələrindən GPS və ya yerləşmə təchizatçıları qayıtmış statusların ləğv etməsinə imkan verir."</string>
+    <string name="permlab_accessFineLocation" msgid="1191898061965273372">"dəqiq yeri (GPS və şəbəkə-əsaslı)"</string>
+    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Qlobal Pozisiya Sistemini və ya şəbəkə qüllələri və Wi-Fi kimi şəbəkə məkanını istifadə edərək tətbiqə Sizin dəqiq yerinizi təyin etməyə imkan verir. Bu məkan xidmətləri aktivləşdirilməlidirlər ki, Siz tətbiqi istifadə edən zaman tətbiq onları istifadə edə bilsin. Tətbiqlər Sizin harada olmağınızı bunun vasitəsilə təyin edəcək, eyni zamanda, bu xidmət əlavə batareya enerjisi apara bilər."</string>
+    <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"təxmini məkan (şəbəkə əsaslı)"</string>
+    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Tətbiqə təxmini yerinizi almaq üçün imkan verir. Bu yer, yerləşmə xidmətləri tərəfindən mobil qüllələr və Wi-Fi kimi şəbəkə yerləşmə mənbələrdən istifadə etməklə əldə edilir. Bu yerləşmə xidmətləri tətbiqin onlardan istifadəsi üçün açıq və cihazınızın onları istifadəsi üçün mövcud olmalıdır. Tətbiqlər bundan sizin təxminən harada olduğunuzu müəyyənləşdirmək üçün istifadə edə bilər."</string>
+    <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"SurfaceFlinger\'ə daxil olmaq"</string>
+    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Tətbiqə aşağı səviyyəli SurfaceFnger özəlliklərini istifadə etməyə icazə verir."</string>
+    <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"freym buferi oxuyur"</string>
+    <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Tətbiqə freym buferinin kontentini oxumaq icazəsi verir."</string>
+    <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Wifi görüntülərini quraşdır"</string>
+    <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Tətbiqə Wifi görüntülərini quraşdırmağa və onlara qoşulmağa imkan verir."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"WiFi görüntülərini dəyişir"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Tətbiqə Wifi displeylərinin aşağı səviyyəli funksiyalarını idarə etmək imkanı verir."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"audio çıxışı alın"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Tətbiqə audio çıxışı almaq və yenidən yönləndirmək imkanı verir."</string>
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"video çıxışı alın"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Tətbiqə video çıxışı almaq və yenidən yönləndirmək imkanı verir."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"təhlükəsiz video çıxışı alın"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Tətbiqə güvənli video çıxışı almaq və yenidən yönləndirmək imkanı verir."</string>
+    <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"audio ayarlarınızı dəyişir"</string>
+    <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Tətbiqə səs və hansı spikerin çıxış üçün istifadə olunduğu kimi qlobal səs ayarlarını dəyişdirməyə imkan verir."</string>
+    <string name="permlab_recordAudio" msgid="3876049771427466323">"səs yaz"</string>
+    <string name="permdesc_recordAudio" msgid="4906839301087980680">"Tətbiqə mikrofonla audio yazmaq icazəsi verir. İcazə tətbiqə sizin təsdiqiniz olmadan istənilən zaman səs yazma izni verir."</string>
+    <string name="permlab_camera" msgid="3616391919559751192">"şəkil və video çəkmək"</string>
+    <string name="permdesc_camera" msgid="8497216524735535009">"Tətbiqə kamera ilə şəkil və video çəkməyə imkan yaradır. Bu icazə tətbiqə sizin təsdiqiniz olmadan kameradan istifadə icazəsi verir."</string>
+    <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"kamera istifadə edildikdə LED göstərici ötürülməsini deaktiv edir"</string>
+    <string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"Öncədən quraşdırılmış sistem tətbiqinə kamera tərəfindən istifadə edilən LED indikatorunu söndürmək icazəsi verir."</string>
+    <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"planşeti daimi olaraq aradan qaldır"</string>
+    <string name="permlab_brick" product="default" msgid="8337817093326370537">"telefonu həmişəlik deaktiv etmək"</string>
+    <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"Tətbiqə planşeti birdəfəlik deaktiv etməyə imkan verir. Bu da çox təhlükəlidir."</string>
+    <string name="permdesc_brick" product="default" msgid="5788903297627283099">"Tətbiqə bütün telefonu birdəfəlik deaktivləşdirməyə imkan verir. Bu çox təhlükəlidir."</string>
+    <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"planşeti yenidən yüklənməyə məcbur edir"</string>
+    <string name="permlab_reboot" product="default" msgid="2898560872462638242">"telefonu yenidən yüklənməyə məcbur edir"</string>
+    <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"Tətbiqə planşeti yenidən yükləməyə məcbur etmək imkanı verir."</string>
+    <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"Tətbiqə telefonu yenidən yükləməyə məcbur etmək üçün imkan verir."</string>
+    <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"USB yaddaş fayl sisteminə daxil olmaq"</string>
+    <string name="permlab_mount_unmount_filesystems" product="default" msgid="4402305049890953810">"SD Kart fayl sisteminə daxil olmaq"</string>
+    <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"Tətbiqə silinəbilən yaddaşları və ya fayl sistemini quraşdırma və ayırma icazəsi verir."</string>
+    <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"USB yaddaşı silir"</string>
+    <string name="permlab_mount_format_filesystems" product="default" msgid="262582698639274056">"SD kartı silir"</string>
+    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"Tətbiqə çıxarıla bilən yaddaşı format etməyə imkan verir."</string>
+    <string name="permlab_asec_access" msgid="3411338632002193846">"daxili yaddaşınız haqqında məlumat əldə etmək"</string>
+    <string name="permdesc_asec_access" msgid="3094563844593878548">"Tətbiqə daxili yaddaş haqqında məlumat almağa imkan verir."</string>
+    <string name="permlab_asec_create" msgid="6414757234789336327">"daxili yaddaş yaratmaq"</string>
+    <string name="permdesc_asec_create" msgid="4558869273585856876">"Tətbiqə daxili yaddaş yaratmaq üçün imkan verir."</string>
+    <string name="permlab_asec_destroy" msgid="526928328301618022">"daxili yaddaşı məhv etmə"</string>
+    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"Tətbiqə daxili yaddaşı məhv etmə icazəsi verir."</string>
+    <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"daxili yaddaşı montaj və ya demontaj etmək"</string>
+    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"Tətbiqə daxili yaddaşı quraşdırma/ayırma icazəsi verir."</string>
+    <string name="permlab_asec_rename" msgid="7496633954080472417">"daxili yaddaşın adını dəyiş"</string>
+    <string name="permdesc_asec_rename" msgid="1794757588472127675">"Tətbiqə daxili yaddaşın adını dəyişmək imkanı verir."</string>
+    <string name="permlab_vibrate" msgid="7696427026057705834">"vibrasiyaya nəzarət edir"</string>
+    <string name="permdesc_vibrate" msgid="6284989245902300945">"Tətbiqə vibratoru idarə etmə icazəsi verir."</string>
+    <string name="permlab_flashlight" msgid="2155920810121984215">"Flash işığını idarə edir"</string>
+    <string name="permdesc_flashlight" msgid="6522284794568368310">"Tətbiqə siqnal işığı na nəzarət etməyə imkan verir."</string>
+    <string name="permlab_manageUsb" msgid="1113453430645402723">"USB cihazlar üçün tərcihləri və icazələri idarə etmək"</string>
+    <string name="permdesc_manageUsb" msgid="7776155430218239833">"Tətbiqə USB cihazlar üçün olan tərcihləri və icazələri idarə etməyə imkan verir."</string>
+    <string name="permlab_accessMtp" msgid="4953468676795917042">"MTP protokol həyata keçirmək"</string>
+    <string name="permdesc_accessMtp" msgid="6532961200486791570">"Kernel MTP drayverə girişə imkan verir ki, MTP USB protokolunu həyata keçirsin."</string>
+    <string name="permlab_hardware_test" msgid="4148290860400659146">"avadanlığı sınaq edir"</string>
+    <string name="permdesc_hardware_test" msgid="6597964191208016605">"Tətbiqə avadanlığı yoxlamaq üçün müxtəlif periferiyaları kontrol etməyə imkan verir."</string>
+    <string name="permlab_callPhone" msgid="3925836347681847954">"telefon nömrələrinə birbaşa zəng edir"</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"Tətbiqə Sizin müdaxiləniz olmadan telefon zəngləri etməyə imkan verir. Zərərli tətbiqlər Sizdən xəbərsiz şəkildə müxtəlif zənglər edərək, Sizə maddi ziyan vura bilər. Qeyd: Bu, tətbiqlərə təcili nömrələrə zəng etməyə icazə vermir."</string>
+    <string name="permlab_callPrivileged" msgid="4198349211108497879">"istənilən nömrəyə birbaşa zəng edir"</string>
+    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"Tətbiqə Sizin müdaxiləniz olmadan, təcili zənglər də daxil olmaqla, istənilən telefon zəngini etməyə imkan verir. Zərərli tətbiqlər bundan istifadə edərək, təcili nömrələrə qanunsuz zəng vurmaqla Sizin üçün hüquqi problemlər yarada bilər."</string>
+    <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"CDMA planşet ayarlarına birbaşa başlamaq"</string>
+    <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"CDMA telefon quraşdırmalarına birbaşa başlamaq"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"Tətbiqə CDMA hazırlığını başlatma icazəsi verir. Zərərli tətbiqlər ehtiyac olmadıqda CDMA hazırlığını başlada bilərlər."</string>
+    <string name="permlab_locationUpdates" msgid="7785408253364335740">"məkan güncəlləmə bildirişlərini idarə edir"</string>
+    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Tətbiqə radiodan gələn məkan güncəllənmələrini aktiv və ya deaktiv etməyə imkan verir. Normal tətbiqlər tərəfindən istifadə olunmur."</string>
+    <string name="permlab_checkinProperties" msgid="7855259461268734914">"qeydiyyat xüsusiyyətlərini əldə edir"</string>
+    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Tətbiqə giriş qeydi servisi tərəfindən yüklənmiş mülkiyyətə girişi oxumaq/yazmaq imkanl verir. Normal tətbiqlər üçün nəzərdə tutulmayıb."</string>
+    <string name="permlab_bindGadget" msgid="776905339015863471">"vidcetlər seç"</string>
+    <string name="permdesc_bindGadget" msgid="8261326938599049290">"Tətbiqə sistemə hansı vidcetin hansı tətbiq tərəfindən istifadə edilə bilməsini deməyə icazə verir. Bu icazəli tətbiqlər şəxsi məlumatlara və digər tətbiqlərə çıxış verə bilər. Normal tətbiqlər tərəfindən istifadə üçün deyil."</string>
+    <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"telefon statusunu dəyişmək"</string>
+    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Tətbiqə cihazın telefon funksiyalarını idarə etmək imkanı verir. Belə icazəli tətbiq Sizi xəbərdar etmədən şəbəkələri qoşa, telefon radiosunu yandırıb-söndürə bilər."</string>
+    <string name="permlab_readPhoneState" msgid="9178228524507610486">"telefon statusunu və identifikasiyanı oxuyur"</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Tətbiqə cihazın telefon funksiyalarına giriş icazəsi verir. Belə icazəli tətbiq bu telefonun nömrəsini və cihaz İD\'ni, zəngin aktiv olub-olmadığını və zəng edilən nömrəni müəyyən edə bilər."</string>
+    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"planşetin yuxu rejiminin qarşısını almaq"</string>
+    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"telefonun yuxu rejiminə keçməsini əngəllə"</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Tətbiqə planşetin yuxu rejimini qadağan etməyə imkan verir."</string>
+    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Tətbiqə telefonun yuxu rejimini qadağan etmək imkanı verir."</string>
+    <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"planşeti yandırma və ya söndürmə"</string>
+    <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"telefonu yandırmaq və ya söndürmək"</string>
+    <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Tətbiqə planşeti yandırmağa və söndürməyə imkan verir."</string>
+    <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"Tətbiqə telefonu yandırıb söndürmə icazəsi verir."</string>
+    <string name="permlab_factoryTest" msgid="3715225492696416187">"zavod test rejimində işləyir"</string>
+    <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"Planşet avadanlığına tam girişə imkan verməklə aşağı səviyyəli istehsalçı sınağı kimi işləyir. Yalnız planşet istehsalçı sınaq rejimində olduqda işləyir."</string>
+    <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"Bir aşağı səviyyəli istehsalçı testi kimi çalışdırın, telefon hardware üçün tam giriş imkanı verir. Ancaq telefon, istehsalçı test rejimində çalışdığı zaman aktivdir."</string>
+    <string name="permlab_setWallpaper" msgid="6627192333373465143">"divar kağızı yerləşdirir"</string>
+    <string name="permdesc_setWallpaper" msgid="7373447920977624745">"Tətbiqə sistemə divar kağızı yerləşdirmək icazəsi verir."</string>
+    <string name="permlab_setWallpaperHints" msgid="3278608165977736538">"divar kağızı ölçüsünü verir"</string>
+    <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Tətbiqə sistem divar kağızı ölçüsü göstərişlərini müəyyən etməyə imkan verir."</string>
+    <string name="permlab_masterClear" msgid="2315750423139697397">"fabrik defoltuna sıfırlamaq"</string>
+    <string name="permdesc_masterClear" msgid="3665380492633910226">"Tətbiqə bütün məlumatları, nizamları və quraşdırılmış tətbiqləri silərək sistemi fabrik nizamlarına qaytarmaq imkanı verir."</string>
+    <string name="permlab_setTime" msgid="2021614829591775646">"vaxtı təyin edir"</string>
+    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"Tətbiqə planşetin saat vaxtını dəyişməyə imkan verir."</string>
+    <string name="permdesc_setTime" product="default" msgid="1855702730738020">"Tətbiqə telefonun saat vaxtını dəyişməyə imkan verir."</string>
+    <string name="permlab_setTimeZone" msgid="2945079801013077340">"vaxt zonasını quraşdırır"</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Tətbiqə planşetin vaxt zonasını dəyişmə icazəsi verir."</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Tətbiqə telefon saat zolağını dəyişmək üçün imkan verir."</string>
+    <string name="permlab_accountManagerService" msgid="4829262349691386986">"AccountManagerService kimi davranır"</string>
+    <string name="permdesc_accountManagerService" msgid="1948455552333615954">"Tətbiqə AccountAuthenticators\'ə zəng etməyə imkan verir."</string>
+    <string name="permlab_getAccounts" msgid="1086795467760122114">"cihazda hesabları tapır"</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Tətbiqə planşet tərəfindən bilinən hesabların siyahısını alma icazəsi verir. Bu quraşdırdığınız tətbiqlər tərəfindən yaradılmış istənilən hesab ola bilər."</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Tətbiqə telefonda olan hesabların siyahısını əldə etməyə imkan verir. Buna quraşdırdığınız istənilən tətbiq tərəfindən yaradılan hesablar da aiddir."</string>
+    <string name="permlab_authenticateAccounts" msgid="5265908481172736933">"hesablar yaradır və parollar təyin edir"</string>
+    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"Tətbiqə AccountManager\'in hesab yaratmaq və parol almaq və açmaq daxil olmaqla bərabər, hesab təsdiqləyici imkanlarını istifadə etməyə icazə verir."</string>
+    <string name="permlab_manageAccounts" msgid="4983126304757177305">"hesabları əlavə edir və ya silir"</string>
+    <string name="permdesc_manageAccounts" msgid="8698295625488292506">"Tətbiqə hesabların əlavə olunması və ya silinməsi, həmçinin onların parollarının silinməsi kimi əməliyyatları icra etməyə imkan verir."</string>
+    <string name="permlab_useCredentials" msgid="235481396163877642">"cihazda hesablar istifadə etmək"</string>
+    <string name="permdesc_useCredentials" msgid="7984227147403346422">"Tətbiqə autentifikasiya tokenləri sorğularını göndərməyə icazə verir."</string>
+    <string name="permlab_accessNetworkState" msgid="4951027964348974773">"şəbəkə bağlantılarına baxmaq"</string>
+    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Tətbiqə mövcud olan və qoşulan şəbəkələr kimi qoşulmalar haqqında məlumatı görməyə icazə verir."</string>
+    <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"tam şəbəkə girişi"</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Tətbiqə şəbəkə soketlərini yaratmağa və fərdi şəbəkə protokollarını istifadə etməyə imkan verir. Brauzer və digər tətbiqlər datanın internetə ötürülməsini təmin edən vəsaitlər verir, ona görə də datanın internetə gönrədilməsi üçün bu icazə tələb olunmur."</string>
+    <string name="permlab_writeApnSettings" msgid="505660159675751896">"şəbəkə nizamlarını və trafiki dəyişdirir/qarşısını alır"</string>
+    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Tətbiqə şəbəkə trafikinin qarşısını almaq üçün şəbəkə nizamlarını dəyişmə icazəsi verir, məsələn proksini və ya istənilən APN-in portunu. Zərərli tətbiqlər şəbəkə paketlərini sizin bilginiz olmadan monitorinq edə, yönləndirə və ya redaktə edə bilər."</string>
+    <string name="permlab_changeNetworkState" msgid="958884291454327309">"şəbəkə bağlantısını dəyişir"</string>
+    <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Tətbiqə şəbəkə vəziyyətini dəyişməyə icazə verir."</string>
+    <string name="permlab_changeTetherState" msgid="5952584964373017960">"Sərhədli bağlantını dəyişir"</string>
+    <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Tətbiqə birləşilmiş şəbəkə bağlantısının statusunu dəyişməyə imkan verir."</string>
+    <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"arxafon data istifadəsi ayarını dəyişir"</string>
+    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Tətbiqə fon rejimi nizamlarını dəyişməyə icazə verir."</string>
+    <string name="permlab_accessWifiState" msgid="5202012949247040011">"Wi-Fi bağlantılarına baxmaq"</string>
+    <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Tətbiqə Wi-Fi şəbəkələri haqqında məlumatı görməyə icazə verir, məsələn, Wi-Fi mövcudluğu və qoşulmuş Wi-Fi cihazlarının adları."</string>
+    <string name="permlab_changeWifiState" msgid="6550641188749128035">"Wi-Fi şəbəkəsinə qoşulmaq və ya ayrılmaq"</string>
+    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Tətbiqə Wi-Fi çıxış nöqtəsinə qoşulmaq və ondan ayrılmaq və cihazın Wi-Fi şəbəkə nizamlarını dəyişməyə icazə verir."</string>
+    <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"Wi-Fi Multicast qəbuluna icazə ver"</string>
+    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Tətbiqə Wi-Fi şəbəkədə sizin planşetdən başqa digər multikast adreslərə yönləndirilmiş paketləri almaq icazəsi verir. Bu qeyri-çoxadresli rejimdən fəqli olaraq daha çox enerji işlədir."</string>
+    <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Tətbiqə qrup ünvanlar istifadə etməklə, Wi-Fi şəbəkəsində olan bütün cihazlara göndərilmiş paketləri qəbul etməyə imkan verir. Buna daha çox enerji sərf olunur."</string>
+    <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"Bluetooth ayarlarını əldə edir"</string>
+    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Tətbiqə yerli Bluetooth planşetinin konfiqurasiyasını görməyə və məsafədən cihazları tapmağa və cütləməyə imkan verir."</string>
+    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Tətbiqə lokal Bluetooth telefonunu konfiqurə etməyə və uzaq cihazları kəşf etmək və onlara qoşulmaq icazəsi verir."</string>
+    <string name="permlab_accessWimaxState" msgid="4195907010610205703">"WiMAX\'a qoşul və bağlantını kəs"</string>
+    <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"Tətbiqə WiMAX mövcudluğu və qoşulmuş WiMAX şəbəkələrini təyin etməyə icazə verir."</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"WiMAX vəziyyətini dəyişir"</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Tətbiqə planşeti WiMAX şəbəkələrinə qoşmaq və onlardan ayırmaq icazəsi verir."</string>
+    <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"Tətbiqə telefonu WiMAX şəbəkəsinə qoşmağa və ya WiMAX şəbəkəsindən ayırmağa imkan verir."</string>
+    <string name="permlab_bluetooth" msgid="6127769336339276828">"Bluetooth cihazları ilə cütləndirmək"</string>
+    <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Tətbiqə yerli Bluetooth planşetinin konfiqurasiyasını görməyə və cütlənmiş cihazlarla bağlantılar etməyə və qəbul etməyə imkan verir."</string>
+    <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Tətbiqə Bluetooth və ya telefon konfiqurasiyalarını görməyə və qoşulmuş cihazlarla əlaqə qurmağa və qəbul etməyə icazə verir."</string>
+    <string name="permlab_nfc" msgid="4423351274757876953">"Near Field Communication\'ı kontrol et"</string>
+    <string name="permdesc_nfc" msgid="7120611819401789907">"Tətbiqə Yaxın Məsafə Kommunikasiyası (NFC) teqləri, kartları və oxuyucuları ilə əlaqə qurmağa icazə verir."</string>
+    <string name="permlab_disableKeyguard" msgid="3598496301486439258">"Ekran kilidini deaktiv edir"</string>
+    <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Tətbiqə kilid açarını və təhlükəsizlik parolunu deaktiv etməyə imkan verir. Qanuni misal budur ki, telefon zəng qəbul edən zaman kilidi açır və zəng qurtarandan sonra kilidi bağlayır."</string>
+    <string name="permlab_readSyncSettings" msgid="6201810008230503052">"sinx ayarlarını oxu"</string>
+    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Tətbiqə hesablar üçün sinxronizasiya nizamlarını oxuma icazəsi verir. Məsələn, bu Şəxslər tətbiqinin sinxronizə olunub-olunmadığını təyin edə bilər."</string>
+    <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"sinxronizasiyaya davam edir və onu söndürür"</string>
+    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Tətbiqə hesab üçün sinxronizasiya nizamlarını dəyişməyə icazə verir. Məsələn, bu istifadəçi hesablı Şəxslər tətbiqinin sinxronizasiyasını başlamaq üçün istifadə edilə bilər."</string>
+    <string name="permlab_readSyncStats" msgid="7396577451360202448">"sinxronizasiya statistikasını oxumaq"</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Tətbiqə sync tədbirlərinin tarixçəsi və nə qədər datanın sinx olduğu da daxil olmaqla bərabər, hər hansı bir hesab üçün olan sinx statlarını oxumağa imkan verir."</string>
+    <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"abunə olunmuş xəbərləri oxuyur"</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Tətbiqə hazırda sinxron lentlər haqqında ətraflı məlumat almaq üçün imkan verir."</string>
+    <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"abunə olunmuş xəbərləri yazır"</string>
+    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"Tətbiqə cari sinxronlaşmış lentlərinizə dəyişiklik etmək imkanı verir. Zərərli tətbiqlər sixronlaşmış lentlərinizi dəyişə bilər."</string>
+    <string name="permlab_readDictionary" msgid="4107101525746035718">"lüğətə əlavə etdiyiniz şərtləri oxumaq"</string>
+    <string name="permdesc_readDictionary" msgid="659614600338904243">"Tətbiqə istifadəçinin lüğətdə saxladığı bütün sözləri, adları və frazaları oxumaq icazəsi verir."</string>
+    <string name="permlab_writeDictionary" msgid="2183110402314441106">"istifadəçi lüğətinə sözlər əlavə etmək"</string>
+    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Tətbiqə istifadəçi lüğətinə yeni sözlər yazmağa imkan verir."</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"qorunmuş yaddaşa daxil olmağa cəhd etmək"</string>
+    <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"qorunmuş yaddaşa daxil olmağa cəhd etmək"</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"Tətbiqə gələcək cihazlarda əlçatımlı olacaq USB yaddaş üçün icazə testi etməyə imkan verir."</string>
+    <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"Tətbiqə gələcək cihazlarda mövcud olacaq SD kart üçün icazəni test etmək üçün imkan verir."</string>
+    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"USB yaddaşınızın məzmununu dəyişmək və ya silmək"</string>
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"SD kart kontentlərini dəyişir və ya silir"</string>
+    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Tətbiqə USB yaddaşa yazmağa imkan verir."</string>
+    <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Tətbiqə SD karta yazma icazəsi verir."</string>
+    <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"daxili media yaddaşı kontentini dəyişir/silir"</string>
+    <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Tətbiqə daxili media yaddaşdakı kontenti redaktə etmək icazəsi verir."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"sənəd yaddaşını nizamlayır"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Tətbiqə sənəd yaddaşını idarə etməyə imkan verir."</string>
+    <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"bütün istifadəçilərin xarici yaddaşına daxil ol"</string>
+    <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Tətbiqə bütün istifadəçilər üçün olan xarici yaddaşa giriş imkanı verir."</string>
+    <string name="permlab_cache_filesystem" msgid="5656487264819669824">"keş fayl sisteminə girmək"</string>
+    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Tətbiqə keş fayl sistemini oxumağa və yazmağa icazə verir."</string>
+    <string name="permlab_use_sip" msgid="5986952362795870502">"İnternet zəngləri etmək və ya qəbul etmək"</string>
+    <string name="permdesc_use_sip" msgid="4717632000062674294">"Tətbiqə internet zənglərinin göndərilməsi və qəbul edilməsi üçün SIP servisindən istifadə icazəsi verir."</string>
+    <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"tarixi şəbəkə istifadəsini oxu"</string>
+    <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"Tətbiqə xüsusi şəbəkələr və tətbiqlər üçün tarixi şəbəkə istifadəsini oxumağa icazə verir."</string>
+    <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"şəbəkə siyasətini idarə etmək"</string>
+    <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Tətbiqə şəbəkə qanunlarını və tətbiqin xüsusi qaydalarını idarə etmək imkanı verir."</string>
+    <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"şəbəkə istifadə hesabını dəyişmək"</string>
+    <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Tətbiqə şəbəkə istifadəsinin tətbiqlərə qarşı nizamlarını redaktə etməyə icazə verir. Normal tətbiqlər tərəfindən istifadə edilmir."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"soket işarələrini dəyişin"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Tətbiqə araşdırma üçün soket işarələrini dəyişmək imkanı verir"</string>
+    <string name="permlab_accessNotifications" msgid="7673416487873432268">"bildirişlərə daxil ol"</string>
+    <string name="permdesc_accessNotifications" msgid="458457742683431387">"Tətbiqə bildirişləri əldə etməyə, sınamağa və təmizləməyə imkan verir, buna digər tətbiqlər tərəfindən verilmiş bildirişlər də daxildir."</string>
+    <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"bildiriş dinləmə xidmətinə bağlanır"</string>
+    <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Sahibinə yüksək səviyyəli bildiriş dinləmə servisi ilə əlaqə saxlamağa icazə verir. Normal tətbiqlər tərəfindən heç vaxt istənilməməlidir."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"operator xidmətli konfiurasiya tətbiqinə müraciət edin"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Sahibinə operator xidmətli tətbiq konfiqurasiyasına  müraciət imkanı verir. Normal tətbiqlər üçün tələb olunmamalıdır."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"şəbəkə şəraiti haqqında müşahidələr üçün qulaq asmaq"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Tətbiqə şəbəkə şəraiti üzrə müşahidələr üçün qulaq asmaq imkanı verir. Normal tətbiqlər üçün heç vaxt lazım olmamalıdır."</string>
+    <string name="policylab_limitPassword" msgid="4497420728857585791">"Parol qaydalarını təyin edin"</string>
+    <string name="policydesc_limitPassword" msgid="3252114203919510394">"Ekran kilidini açan şifrələrin uzunluğunu və onlardakı icazə verilən işarələrə nəzarət edir."</string>
+    <string name="policylab_watchLogin" msgid="914130646942199503">"Ekran kilidi cəhdlərini monitorinq et"</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Ekan kilidini açarkən daxil edilmiş yanlış parollara baxın və əgər həddindən çox yanlış parollar daxil edilibsə, planşeti kilidləyin və ya bütün planşet datasını silin."</string>
+    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Ekan kilidini açarkən daxil edilmiş yanlış parollara baxın və əgər həddindən çox yanlış parollar daxil edilibsə, telefonu kilidləyin və ya bütün telefon datasını silin."</string>
+    <string name="policylab_resetPassword" msgid="2620077191242688955">"Ekran kilid parolunu dəyişin"</string>
+    <string name="policydesc_resetPassword" msgid="605963962301904458">"Ekran kilidini açan şifrəni dəyişdirin."</string>
+    <string name="policylab_forceLock" msgid="2274085384704248431">"Ekranı kilidləyin"</string>
+    <string name="policydesc_forceLock" msgid="1141797588403827138">"Ekranın nə vaxt və necə kilidlənməsinə nəzarət edir."</string>
+    <string name="policylab_wipeData" msgid="3910545446758639713">"Bütün məlumatları silin"</string>
+    <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Planşetin datasını xəbərdarlıq olmadan, zavod data sıfırlaması ilə silin."</string>
+    <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Telefonun datasını xəbərdarlıq olmadan, zavod data sıfırlaması ilə silin"</string>
+    <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Cihazın qlobal proksisini ayarlayın"</string>
+    <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Siyasət aktiv olarkən cihazın qlobal proksisini istifadə üçün qurun. Yalnız ilk cihaz admini effektiv qlobal proksini təyin edir."</string>
+    <string name="policylab_expirePassword" msgid="885279151847254056">"Ekran kilidi şifrəsinə son zaman seç"</string>
+    <string name="policydesc_expirePassword" msgid="1729725226314691591">"Ekran kilidi parolunun nə qədər tez-tez dəyişməsini kontrol edin."</string>
+    <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Yaddaş şifrələnməsini ayarlayın"</string>
+    <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"Tətbiq məlumatlarının şifrələnməsini tələb edir."</string>
+    <string name="policylab_disableCamera" msgid="6395301023152297826">"Kameraları dekativ edin"</string>
+    <string name="policydesc_disableCamera" msgid="2306349042834754597">"Bütün cihaz kameralarının istifadəsini əngəllə."</string>
+    <string name="policylab_disableKeyguardFeatures" msgid="266329104542638802">"Klaviatura kilidində funksiyaları deaktiv edin"</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="3467082272186534614">"Klaviatura kilidində bəzi funksiyaların qarşısını alın."</string>
+  <string-array name="phoneTypes">
+    <item msgid="8901098336658710359">"Əsas səhifə"</item>
+    <item msgid="869923650527136615">"Mobil"</item>
+    <item msgid="7897544654242874543">"İş"</item>
+    <item msgid="1103601433382158155">"İş Faksı"</item>
+    <item msgid="1735177144948329370">"Ev Faksı"</item>
+    <item msgid="603878674477207394">"Peycer"</item>
+    <item msgid="1650824275177931637">"Digər"</item>
+    <item msgid="9192514806975898961">"Şəxsi"</item>
+  </string-array>
+  <string-array name="emailAddressTypes">
+    <item msgid="8073994352956129127">"Ana səhifə"</item>
+    <item msgid="7084237356602625604">"İş"</item>
+    <item msgid="1112044410659011023">"Digər"</item>
+    <item msgid="2374913952870110618">"Fərdi"</item>
+  </string-array>
+  <string-array name="postalAddressTypes">
+    <item msgid="6880257626740047286">"Əsas səhifə"</item>
+    <item msgid="5629153956045109251">"İş"</item>
+    <item msgid="4966604264500343469">"Digər"</item>
+    <item msgid="4932682847595299369">"Düzənləyin"</item>
+  </string-array>
+  <string-array name="imAddressTypes">
+    <item msgid="1738585194601476694">"Əsas səhifə"</item>
+    <item msgid="1359644565647383708">"İş"</item>
+    <item msgid="7868549401053615677">"Digər"</item>
+    <item msgid="3145118944639869809">"Fərdi"</item>
+  </string-array>
+  <string-array name="organizationTypes">
+    <item msgid="7546335612189115615">"İş"</item>
+    <item msgid="4378074129049520373">"Digər"</item>
+    <item msgid="3455047468583965104">"Fərdi"</item>
+  </string-array>
+  <string-array name="imProtocols">
+    <item msgid="8595261363518459565">"AIM"</item>
+    <item msgid="7390473628275490700">"Windows Live"</item>
+    <item msgid="7882877134931458217">"Yahoo"</item>
+    <item msgid="5035376313200585242">"Skype"</item>
+    <item msgid="7532363178459444943">"QQ"</item>
+    <item msgid="3713441034299660749">"Google Söhbət"</item>
+    <item msgid="2506857312718630823">"ICQ"</item>
+    <item msgid="1648797903785279353">"Jabber"</item>
+  </string-array>
+    <string name="phoneTypeCustom" msgid="1644738059053355820">"Şəxsi"</string>
+    <string name="phoneTypeHome" msgid="2570923463033985887">"Ev"</string>
+    <string name="phoneTypeMobile" msgid="6501463557754751037">"Mobil"</string>
+    <string name="phoneTypeWork" msgid="8863939667059911633">"İş"</string>
+    <string name="phoneTypeFaxWork" msgid="3517792160008890912">"İş Faksı"</string>
+    <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Ev Faksı"</string>
+    <string name="phoneTypePager" msgid="7582359955394921732">"Peycer"</string>
+    <string name="phoneTypeOther" msgid="1544425847868765990">"Digər"</string>
+    <string name="phoneTypeCallback" msgid="2712175203065678206">"Geriyə zəng"</string>
+    <string name="phoneTypeCar" msgid="8738360689616716982">"Avtomobil"</string>
+    <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Şirkət"</string>
+    <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string>
+    <string name="phoneTypeMain" msgid="6766137010628326916">"Əsas"</string>
+    <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Digər faks"</string>
+    <string name="phoneTypeRadio" msgid="4093738079908667513">"Radio"</string>
+    <string name="phoneTypeTelex" msgid="3367879952476250512">"Teleks"</string>
+    <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY TDD"</string>
+    <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Mobil iş telefonu"</string>
+    <string name="phoneTypeWorkPager" msgid="649938731231157056">"İş Peyceri"</string>
+    <string name="phoneTypeAssistant" msgid="5596772636128562884">"Köməkçi"</string>
+    <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string>
+    <string name="eventTypeCustom" msgid="7837586198458073404">"Fərdi"</string>
+    <string name="eventTypeBirthday" msgid="2813379844211390740">"Doğum günü"</string>
+    <string name="eventTypeAnniversary" msgid="3876779744518284000">"İldönümü"</string>
+    <string name="eventTypeOther" msgid="7388178939010143077">"Digər"</string>
+    <string name="emailTypeCustom" msgid="8525960257804213846">"Fərdi"</string>
+    <string name="emailTypeHome" msgid="449227236140433919">"Əsas səhifə"</string>
+    <string name="emailTypeWork" msgid="3548058059601149973">"İş"</string>
+    <string name="emailTypeOther" msgid="2923008695272639549">"Digər"</string>
+    <string name="emailTypeMobile" msgid="119919005321166205">"Mobil"</string>
+    <string name="postalTypeCustom" msgid="8903206903060479902">"Fərdi"</string>
+    <string name="postalTypeHome" msgid="8165756977184483097">"Əsas səhifə"</string>
+    <string name="postalTypeWork" msgid="5268172772387694495">"İş"</string>
+    <string name="postalTypeOther" msgid="2726111966623584341">"Digər"</string>
+    <string name="imTypeCustom" msgid="2074028755527826046">"Fərdi"</string>
+    <string name="imTypeHome" msgid="6241181032954263892">"Ana səhifə"</string>
+    <string name="imTypeWork" msgid="1371489290242433090">"İş"</string>
+    <string name="imTypeOther" msgid="5377007495735915478">"Digər"</string>
+    <string name="imProtocolCustom" msgid="6919453836618749992">"Şəxsi"</string>
+    <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string>
+    <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string>
+    <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">"Görüşlər"</string>
+    <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">"İş"</string>
+    <string name="orgTypeOther" msgid="3951781131570124082">"Digər"</string>
+    <string name="orgTypeCustom" msgid="225523415372088322">"Fərdi"</string>
+    <string name="relationTypeCustom" msgid="3542403679827297300">"Şəxsi"</string>
+    <string name="relationTypeAssistant" msgid="6274334825195379076">"Köməkçi"</string>
+    <string name="relationTypeBrother" msgid="8757913506784067713">"Qardaş"</string>
+    <string name="relationTypeChild" msgid="1890746277276881626">"Uşaq"</string>
+    <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"Ev yoldaşı"</string>
+    <string name="relationTypeFather" msgid="5228034687082050725">"Ata"</string>
+    <string name="relationTypeFriend" msgid="7313106762483391262">"Dost"</string>
+    <string name="relationTypeManager" msgid="6365677861610137895">"Müdir"</string>
+    <string name="relationTypeMother" msgid="4578571352962758304">"Ana"</string>
+    <string name="relationTypeParent" msgid="4755635567562925226">"Valideyn"</string>
+    <string name="relationTypePartner" msgid="7266490285120262781">"Ortaq"</string>
+    <string name="relationTypeReferredBy" msgid="101573059844135524">"Dəvət edən"</string>
+    <string name="relationTypeRelative" msgid="1799819930085610271">"Qohum"</string>
+    <string name="relationTypeSister" msgid="1735983554479076481">"Bacı"</string>
+    <string name="relationTypeSpouse" msgid="394136939428698117">"Həyat yoldaşı"</string>
+    <string name="sipAddressTypeCustom" msgid="2473580593111590945">"Fərdi"</string>
+    <string name="sipAddressTypeHome" msgid="6093598181069359295">"Əsas səhifə"</string>
+    <string name="sipAddressTypeWork" msgid="6920725730797099047">"İş"</string>
+    <string name="sipAddressTypeOther" msgid="4408436162950119849">"Digər"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PİN kodu daxil edin"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK və yeni PİN kod daxil edin"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK kod"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Yeni PIN kodu"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Şifrə daxil etmək üçün toxunun"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Kilidi açmaq üçün parol yazın"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Kilidi açmaq üçün PIN daxil edin"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Yanlış PIN kodu."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Kilidi açmaq üçün Menyu, sonra 0 basın."</string>
+    <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"Təcili nömrə"</string>
+    <string name="lockscreen_carrier_default" msgid="8963839242565653192">"Xidmət yoxdur."</string>
+    <string name="lockscreen_screen_locked" msgid="7288443074806832904">"Ekran kilidlənib."</string>
+    <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Təcili zəng kilidini açmaq və ya yerləşdirmək üçün Menyu düyməsinə basın."</string>
+    <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Kilidi açmaq üçün Menyu düyməsinə basın."</string>
+    <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Kilidi açmaq üçün model çəkin"</string>
+    <string name="lockscreen_emergency_call" msgid="5347633784401285225">"Təcili zəng"</string>
+    <string name="lockscreen_return_to_call" msgid="5244259785500040021">"Zəngə qayıt"</string>
+    <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Düzdür!"</string>
+    <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Bir də cəhd edin"</string>
+    <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Bir daha cəhd et"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Sifət kilidi cəhdləriniz bitdi"</string>
+    <string name="lockscreen_plugged_in" msgid="8057762828355572315">"Batareya yığılır, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_charged" msgid="321635745684060624">"Dolub"</string>
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_low_battery" msgid="1482873981919249740">"Elektrikə qoşun."</string>
+    <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"SIM kart yoxdur."</string>
+    <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Planşetdə SIM kart yoxdur."</string>
+    <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"Telefonda SİM kart yoxdur."</string>
+    <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"SİM kart daxil edin."</string>
+    <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SİM kart yoxdur və ya oxuna bilinmir. SİM kart daxil edin."</string>
+    <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Yararsız SIM kart."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Sizin SİM kartınız daimi olaraq deaktivləşib.\n Başqa SİM kart üçün simsiz xidmət provayderinizə müraciət edin."</string>
+    <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Əvvəlki trek düyməsi"</string>
+    <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Növbəti trek düyməsi"</string>
+    <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Pauza düyməsi"</string>
+    <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Oxutma düyməsi"</string>
+    <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Dayandırma düyməsi"</string>
+    <string name="emergency_calls_only" msgid="6733978304386365407">"Yalnız təcili zənglər"</string>
+    <string name="lockscreen_network_locked_message" msgid="143389224986028501">"Şəbəkə kilidlidir"</string>
+    <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM kart PUK ilə kilidlənib."</string>
+    <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"İstifadəçi Təlimatlarına baxın və ya Müştəri Xidmətlərinə müraciət edin."</string>
+    <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM kart kilidlənib."</string>
+    <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SİM kartın kilidi açılır..."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Siz kilid modelini <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış çəkdiniz. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> saniyə içində yenidən sınayın."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Şifrənizi <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış daxil etdiniz.\n\n <xliff:g id="NUMBER_1">%d</xliff:g> saniyə ərzində yenidən yoxlayın"</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Siz PIN nömrənizi <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış daxil etdiniz. \n \n <xliff:g id="NUMBER_1">%d</xliff:g> saniyə içində təkrar sınayın."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Siz kilidi açmaq üçün şablonu <xliff:g id="NUMBER_0">%d</xliff:g> dəfə səhv çəkdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> daha uğursuz cəhddən sonra planşetin kilidini Google hesabınıza daxil olmaqla açmağınız istəniləcək.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> saniyə ərzində bir daha yoxlayın."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Siz kilidi açmaq üçün şablonu <xliff:g id="NUMBER_0">%d</xliff:g> dəfə səhv çəkdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> daha uğursuz cəhddən sonra planşetin kilidini Google hesabınıza daxil olmaqla açmağınız tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> saniyə ərzində bir daha yoxlayın."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Siz planşet kilidini açmaq üçün <xliff:g id="NUMBER_0">%d</xliff:g> dəfə uğursuz cəhd etmisiniz. <xliff:g id="NUMBER_1">%d</xliff:g> dəfə də uğursuz cəhd etsəniz, planşet fabrik ayarlarına sıfırlanacaq və bütün məlumatlarınız itəcək."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Siz telefon kilidini açmaq üçün <xliff:g id="NUMBER_0">%d</xliff:g> dəfə uğursuz cəhd etmisiniz. <xliff:g id="NUMBER_1">%d</xliff:g> dəfə də uğursuz cəhd etsəniz, telefon zavod ayarlarına sıfırlanacaq və bütün məlumatlarınız itəcək."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Siz planşetin kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> yanlış cəhd etmisiniz. Planşet artıq defolt zavod halına sıfırlanacaq."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Siz telefonun kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> dəfə səhv cəhd etdiniz. Telefonunuz indi zavod nizamlarına yenilənəcək."</string>
+    <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"<xliff:g id="NUMBER">%d</xliff:g> saniyə ərzində bir daha cəhd edin."</string>
+    <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Şablonu unutdunuz?"</string>
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Hesab kilid açma"</string>
+    <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"Həddindən çox cəhd edildi!"</string>
+    <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"Kilidi açmaq üçün Google hesabınız ilə daxil olun."</string>
+    <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"İstifadəçi adı (e-poçt)"</string>
+    <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Şifrə"</string>
+    <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Daxil olun"</string>
+    <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Yanlış istifadəçi adı və parol."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"İstifadəçi adınızı və ya parolunuzu unutmusunuz?\n "<b>"google.com/accounts/recovery"</b>" linkinə daxil olun."</string>
+    <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Yoxlanır..."</string>
+    <string name="lockscreen_unlock_label" msgid="737440483220667054">"Kilidi aç"</string>
+    <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Səs açıqdır"</string>
+    <string name="lockscreen_sound_off_label" msgid="996822825154319026">"Səs sönülüdür"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Model başlandı"</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Model təmizləndi"</string>
+    <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Xana əlavə edildi"</string>
+    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Model tamamlandı"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d of %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Widget əlavə edin."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Boş"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Kilidi açma sahəsi genişləndi."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Kilidi açma sahəsi çökdü."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> vidcet."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"İstifadəçi selektoru"</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">"Media kontrolları"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Yenidən sıralama vidceti başladıldı."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Vidcetin təkrar sifarişi sona çatdı."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Vidcet <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> silindi."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Kilidi açma sahəsini genişləndir."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Sürüşdürmə kilidi."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Kild açma modeli."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Sifət Kilidi"</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Pin kilid açması."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Şifrə kilidi."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Model sahəsi."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Sürüşdürmə sahəsi."</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="granularity_label_character" msgid="7336470535385009523">"simvol"</string>
+    <string name="granularity_label_word" msgid="7075570328374918660">"söz"</string>
+    <string name="granularity_label_link" msgid="5815508880782488267">"link"</string>
+    <string name="granularity_label_line" msgid="5764267235026120888">"xətt"</string>
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
+    <string name="factorytest_failed" msgid="5410270329114212041">"Zavod testi alınmadı"</string>
+    <string name="factorytest_not_system" msgid="4435201656767276723">"Bu FACTORY_TEST fəaliyyəti yalnızca/sistemdə/tətbiqdə quraşdırılmış paketlər üçün dəstəklənir."</string>
+    <string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST əməliyyatını təsdiqləyən heç bir paket tapılmadı."</string>
+    <string name="factorytest_reboot" msgid="6320168203050791643">"Yenidən yükləyin"</string>
+    <string name="js_dialog_title" msgid="1987483977834603872">"\"<xliff:g id="TITLE">%s</xliff:g>\"dakı səhifədə deyilir:"</string>
+    <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
+    <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Naviqasiyanı Təsdiq edin"</string>
+    <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Bu Səhifəni Tərk edin"</string>
+    <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Bu səhifədə qalın"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nBu səhifədən kənara naviqasiya etmək istədiyinizə əminsiniz mi?"</string>
+    <string name="save_password_label" msgid="6860261758665825069">"Təsdiqlə"</string>
+    <string name="double_tap_toast" msgid="4595046515400268881">"Məsləhət: Böyütmək və kiçiltmək üçün iki dəfə tıklayın."</string>
+    <string name="autofill_this_form" msgid="4616758841157816676">"Avtodoldurma"</string>
+    <string name="setup_autofill" msgid="7103495070180590814">"AvtoDoldurmanı ayarla"</string>
+    <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
+    <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
+    <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
+    <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
+    <string name="autofill_province" msgid="2231806553863422300">"Vilayət"</string>
+    <string name="autofill_postal_code" msgid="4696430407689377108">"Poçt kodu"</string>
+    <string name="autofill_state" msgid="6988894195520044613">"Dövlət"</string>
+    <string name="autofill_zip_code" msgid="8697544592627322946">"Poçt indeksi"</string>
+    <string name="autofill_county" msgid="237073771020362891">"Ölkə"</string>
+    <string name="autofill_island" msgid="4020100875984667025">"Ada"</string>
+    <string name="autofill_district" msgid="8400735073392267672">"Sahə"</string>
+    <string name="autofill_department" msgid="5343279462564453309">"Departament"</string>
+    <string name="autofill_prefecture" msgid="2028499485065800419">"Prefektura"</string>
+    <string name="autofill_parish" msgid="8202206105468820057">"Pariş"</string>
+    <string name="autofill_area" msgid="3547409050889952423">"Sahə"</string>
+    <string name="autofill_emirate" msgid="2893880978835698818">"Əmirlik"</string>
+    <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"Veb əlfəcinlərinizi və tarixçələrinizi oxumaq"</string>
+    <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Tətbiqə Brauzerin daxil olduğu bütün linkləri və bütün Brauzer əlfəcinlərini oxumaq imkanı verir. Qeyd: bu icazə veb brauzer imkanları olan üçüncü tərəf brazuerləri və digər tətbiqlər tərəfindən yerinə yetirilə bilməz."</string>
+    <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"veb əlfəcinləri və tarixçəsi yazmaq"</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Tətbiqə planşetinizdəki brauzer tarixini və əlfəcinləri redaktə etmək icazəsi verir. Bu tətbizə brauzer məlumatlarını silmək və ya redaktə etmək imkanı verə bilər. Qeyd: Bu icazə 3-cü partiya brauzerlərə və ya veb brauzing xüsusiyyətli digər tətbiqlərə şamil olunmaya bilər."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Tətbiqə Brauzer tarixçəsi və telefonunuzda saxlanılan əlfəcinlərə dəyişiklik etmək imkanı verir. Bununla tətbiqlə Brauzer datanızı silə və ya dəyişdirə bilər. Qeyd: bu icazə veb brauzer imkanları olan üçüncü tərəf brazuerləri və digər tətbiqlər tərəfindən yerinə yetirilə bilməz."</string>
+    <string name="permlab_setAlarm" msgid="1379294556362091814">"siqnal qurur"</string>
+    <string name="permdesc_setAlarm" msgid="316392039157473848">"Tətbiqə quraşdırlmış zəngli saata alarm ayarlamağa imkan verir. Bəzi zəngli saat tətbiqləri bu özəlliyi dəstəkləməyə bilər."</string>
+    <string name="permlab_addVoicemail" msgid="5525660026090959044">"Səsli poçt əlavə et"</string>
+    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Tətbiqə səsli poçt qutunuza mesaj əlavə etməyə imkan verir."</string>
+    <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"Brauzerin geolokasiya icazələrini dəyişir"</string>
+    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Tətbiqə Brauzerin geolokasiya icazələrini dəyişməyə imkan verir. Zərərli tətbiqlər bundan istifadə edərək məkan məlumatlarını təsadüfi saytlara göndərə bilər."</string>
+    <string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"paketləri təsdiqlə"</string>
+    <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"Tətbiqə paketin quraşdırılabilən olmasını yoxlamağa imkan verir."</string>
+    <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"paket doğrulayıcıya bağlanır"</string>
+    <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Sahibinə paket yoxlayıcılarına sorğu göndərmək icazəsi verir. Normal tətbiqlər tərəfindən heç vaxt istənilməməlidir."</string>
+    <string name="permlab_serialPort" msgid="546083327654631076">"serial porta çıxır"</string>
+    <string name="permdesc_serialPort" msgid="2991639985224598193">"Sahibinə SerialManager API vasitəsilə serial portlara icazə izni verir."</string>
+    <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"xarici kontent provayderlərinə giriş"</string>
+    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Məzmun provayderlərinə örtükdən daxil olmaq üçün cihaz sahibinə imkan verir. Normal tətbiqlər üçün lazım deyil."</string>
+    <string name="permlab_updateLock" msgid="3527558366616680889">"avtomatik cihaz yenilənmələrini pozur"</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"Sahibinə yeni versiyaya yenilənmək üçün nə vaxt qeyri-interaktiv reboot məlumatını sistemə təklif etmə icazəsi verir."</string>
+    <string name="save_password_message" msgid="767344687139195790">"Brauzerin bu şifrəni yadda saxlamasını istəyirsiz?"</string>
+    <string name="save_password_notnow" msgid="6389675316706699758">"İndi yox"</string>
+    <string name="save_password_remember" msgid="6491879678996749466">"Yadda saxla"</string>
+    <string name="save_password_never" msgid="8274330296785855105">"Heç vaxt"</string>
+    <string name="open_permission_deny" msgid="7374036708316629800">"Bu səhifəni açmaq üçün icazəniz yoxdur."</string>
+    <string name="text_copied" msgid="4985729524670131385">"Mətn panoya kopyalandı."</string>
+    <string name="more_item_label" msgid="4650918923083320495">"Daha çox"</string>
+    <string name="prepend_shortcut_label" msgid="2572214461676015642">"Menyu+"</string>
+    <string name="menu_space_shortcut_label" msgid="2410328639272162537">"boşluq"</string>
+    <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"daxil olun"</string>
+    <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"sil"</string>
+    <string name="search_go" msgid="8298016669822141719">"Axtar"</string>
+    <string name="searchview_description_search" msgid="6749826639098512120">"Axtarış"</string>
+    <string name="searchview_description_query" msgid="5911778593125355124">"Axtarış sorğusu"</string>
+    <string name="searchview_description_clear" msgid="1330281990951833033">"Sorğunu təmizlə"</string>
+    <string name="searchview_description_submit" msgid="2688450133297983542">"Sorğunu göndərin"</string>
+    <string name="searchview_description_voice" msgid="2453203695674994440">"Səsli axtarış"</string>
+    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Toxunaraq Kəşf et funksiyası aktiv edilsin?"</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> Toxunaraq Kəşf Et rejimini aktivləşdirmək istəyir. Toxunaraq Kəşf Et açıldığı zaman, barmağınızın altında nə olduğu haqda olan təsvirləri eşidə və ya görə bilərsiniz və yaplanşetdə insanlarla əlaqəyə keçmək üçün jestlər həyata keçirə bilərsiniz."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> Toxunaraq Kəşf Et rejimini aktivləşdirmək istəyir. Toxunaraq Kəşf Et açıldığı zaman, barmağınızın altında nə olduğu haqda olan təsvirləri eşidə və ya görə bilərsiniz və ya telefonda insanlarla əlaqəyə keçmək üçün jestlər həyata keçirə bilərsiniz"</string>
+    <string name="oneMonthDurationPast" msgid="7396384508953779925">"1 ay öncə"</string>
+    <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"1 ay əvvəl"</string>
+  <plurals name="num_seconds_ago">
+    <item quantity="one" msgid="4869870056547896011">"1 saniyə əvvəl"</item>
+    <item quantity="other" msgid="3903706804349556379">"<xliff:g id="COUNT">%d</xliff:g> saniyə əvvəl"</item>
+  </plurals>
+  <plurals name="num_minutes_ago">
+    <item quantity="one" msgid="3306787433088810191">"1 dəqiqə əvvəl"</item>
+    <item quantity="other" msgid="2176942008915455116">"<xliff:g id="COUNT">%d</xliff:g> dəqiqə əvvəl"</item>
+  </plurals>
+  <plurals name="num_hours_ago">
+    <item quantity="one" msgid="9150797944610821849">"1 saat əvvəl"</item>
+    <item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> saat əvvəl"</item>
+  </plurals>
+  <plurals name="last_num_days">
+    <item quantity="other" msgid="3069992808164318268">"Son <xliff:g id="COUNT">%d</xliff:g> gün"</item>
+  </plurals>
+    <string name="last_month" msgid="3959346739979055432">"Keçən ay"</string>
+    <string name="older" msgid="5211975022815554840">"Köhnə"</string>
+  <plurals name="num_days_ago">
+    <item quantity="one" msgid="861358534398115820">"dünən"</item>
+    <item quantity="other" msgid="2479586466153314633">"<xliff:g id="COUNT">%d</xliff:g> gün əvvəl"</item>
+  </plurals>
+  <plurals name="in_num_seconds">
+    <item quantity="one" msgid="2729745560954905102">"1 saniyə ərzində"</item>
+    <item quantity="other" msgid="1241926116443974687">"<xliff:g id="COUNT">%d</xliff:g> saniyə içində"</item>
+  </plurals>
+  <plurals name="in_num_minutes">
+    <item quantity="one" msgid="8793095251325200395">"1 dəqiqə içində"</item>
+    <item quantity="other" msgid="3330713936399448749">"<xliff:g id="COUNT">%d</xliff:g> dəqiqə ərzində"</item>
+  </plurals>
+  <plurals name="in_num_hours">
+    <item quantity="one" msgid="7164353342477769999">"1 saata"</item>
+    <item quantity="other" msgid="547290677353727389">"<xliff:g id="COUNT">%d</xliff:g> saata"</item>
+  </plurals>
+  <plurals name="in_num_days">
+    <item quantity="one" msgid="5413088743009839518">"sabah"</item>
+    <item quantity="other" msgid="5109449375100953247">"<xliff:g id="COUNT">%d</xliff:g> gün ərzində"</item>
+  </plurals>
+  <plurals name="abbrev_num_seconds_ago">
+    <item quantity="one" msgid="1849036840200069118">"1 saniyə əvvəl"</item>
+    <item quantity="other" msgid="3699169366650930415">"<xliff:g id="COUNT">%d</xliff:g> san əvvəl"</item>
+  </plurals>
+  <plurals name="abbrev_num_minutes_ago">
+    <item quantity="one" msgid="6361490147113871545">"1 dəqiqə əvvəl"</item>
+    <item quantity="other" msgid="851164968597150710">"<xliff:g id="COUNT">%d</xliff:g> dəqiqə əvvəl"</item>
+  </plurals>
+  <plurals name="abbrev_num_hours_ago">
+    <item quantity="one" msgid="4796212039724722116">"1 saat əvvəl"</item>
+    <item quantity="other" msgid="6889970745748538901">"<xliff:g id="COUNT">%d</xliff:g> saat əvvəl"</item>
+  </plurals>
+  <plurals name="abbrev_num_days_ago">
+    <item quantity="one" msgid="8463161711492680309">"dünən"</item>
+    <item quantity="other" msgid="3453342639616481191">"<xliff:g id="COUNT">%d</xliff:g> gün əvvəl"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_seconds">
+    <item quantity="one" msgid="5842225370795066299">"1 san ərzində"</item>
+    <item quantity="other" msgid="5495880108825805108">"<xliff:g id="COUNT">%d</xliff:g> san ərzində"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_minutes">
+    <item quantity="one" msgid="562786149928284878">"1 dəq ərzində"</item>
+    <item quantity="other" msgid="4216113292706568726">"<xliff:g id="COUNT">%d</xliff:g> dəqiqəyə"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_hours">
+    <item quantity="one" msgid="3274708118124045246">"1 saat ərzində"</item>
+    <item quantity="other" msgid="3705373766798013406">"<xliff:g id="COUNT">%d</xliff:g> saata"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_days">
+    <item quantity="one" msgid="2178576254385739855">"sabah"</item>
+    <item quantity="other" msgid="2973062968038355991">"<xliff:g id="COUNT">%d</xliff:g> günə"</item>
+  </plurals>
+    <string name="preposition_for_date" msgid="9093949757757445117">"<xliff:g id="DATE">%s</xliff:g> tarixində"</string>
+    <string name="preposition_for_time" msgid="5506831244263083793">"saat <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="preposition_for_year" msgid="5040395640711867177">"<xliff:g id="YEAR">%s</xliff:g> ilində"</string>
+    <string name="day" msgid="8144195776058119424">"gün"</string>
+    <string name="days" msgid="4774547661021344602">"günlər"</string>
+    <string name="hour" msgid="2126771916426189481">"saat"</string>
+    <string name="hours" msgid="894424005266852993">"saatlar"</string>
+    <string name="minute" msgid="9148878657703769868">"dəq."</string>
+    <string name="minutes" msgid="5646001005827034509">"dəqiqə"</string>
+    <string name="second" msgid="3184235808021478">"sn"</string>
+    <string name="seconds" msgid="3161515347216589235">"san"</string>
+    <string name="week" msgid="5617961537173061583">"həftə"</string>
+    <string name="weeks" msgid="6509623834583944518">"həftə"</string>
+    <string name="year" msgid="4001118221013892076">"il"</string>
+    <string name="years" msgid="6881577717993213522">"il"</string>
+  <plurals name="duration_seconds">
+    <item quantity="one" msgid="6962015528372969481">"1 saniyə"</item>
+    <item quantity="other" msgid="1886107766577166786">"<xliff:g id="COUNT">%d</xliff:g> saniyə"</item>
+  </plurals>
+  <plurals name="duration_minutes">
+    <item quantity="one" msgid="4915414002546085617">"1 dəqiqə"</item>
+    <item quantity="other" msgid="3165187169224908775">"<xliff:g id="COUNT">%d</xliff:g> dəqiqə"</item>
+  </plurals>
+  <plurals name="duration_hours">
+    <item quantity="one" msgid="8917467491248809972">"1 saat"</item>
+    <item quantity="other" msgid="3863962854246773930">"<xliff:g id="COUNT">%d</xliff:g> saat"</item>
+  </plurals>
+    <string name="VideoView_error_title" msgid="3534509135438353077">"Video problemi"</string>
+    <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Bu video bu cihaza strim olunmaq üçün uyğun deyil."</string>
+    <string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Bu video oxumur"</string>
+    <string name="VideoView_error_button" msgid="2822238215100679592">"OK"</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">"günorta"</string>
+    <string name="Noon" msgid="3342127745230013127">"Günorta"</string>
+    <string name="midnight" msgid="7166259508850457595">"gecəyarı"</string>
+    <string name="Midnight" msgid="5630806906897892201">"Gecəyarı"</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">"Hamısını seç"</string>
+    <string name="cut" msgid="3092569408438626261">"Kəs"</string>
+    <string name="copy" msgid="2681946229533511987">"Kopyala"</string>
+    <string name="paste" msgid="5629880836805036433">"Yerləşdir"</string>
+    <string name="replace" msgid="5781686059063148930">"Əvəz et..."</string>
+    <string name="delete" msgid="6098684844021697789">"Sil"</string>
+    <string name="copyUrl" msgid="2538211579596067402">"URL kopyala"</string>
+    <string name="selectTextMode" msgid="1018691815143165326">"Mətn seçin"</string>
+    <string name="textSelectionCABTitle" msgid="5236850394370820357">"Mətn seçimi"</string>
+    <string name="addToDictionary" msgid="4352161534510057874">"Lüğətə əlavə et"</string>
+    <string name="deleteText" msgid="6979668428458199034">"Sil"</string>
+    <string name="inputMethod" msgid="1653630062304567879">"Daxiletmə metodu"</string>
+    <string name="editTextMenuTitle" msgid="4909135564941815494">"Mətn əməliyyatları"</string>
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Yaddaş yeri bitir"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Bəzi sistem funksiyaları işləməyə bilər"</string>
+    <string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> işlənir"</string>
+    <string name="app_running_notification_text" msgid="4653586947747330058">"Daha çox məlumat üçün və ya tətbiqi dayandırmaq üçün toxunun."</string>
+    <string name="ok" msgid="5970060430562524910">"OK"</string>
+    <string name="cancel" msgid="6442560571259935130">"Ləğv et"</string>
+    <string name="yes" msgid="5362982303337969312">"OK"</string>
+    <string name="no" msgid="5141531044935541497">"Ləğv et"</string>
+    <string name="dialog_alert_title" msgid="2049658708609043103">"Diqqət"</string>
+    <string name="loading" msgid="7933681260296021180">"Yüklənir…"</string>
+    <string name="capital_on" msgid="1544682755514494298">"AÇIQ"</string>
+    <string name="capital_off" msgid="6815870386972805832">"QAPALI"</string>
+    <string name="whichApplication" msgid="4533185947064773386">"Əməliyyatı tamamlayın:"</string>
+    <string name="alwaysUse" msgid="4583018368000610438">"Bu fəaliyyət üçün defolt istifadə edin"</string>
+    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Sistem ayarlarında, Tətbiqlərdə və Endirilmişlərdə defoltu təmizləyin."</string>
+    <string name="chooseActivity" msgid="7486876147751803333">"Fəaliyyət seçin"</string>
+    <string name="chooseUsbActivity" msgid="6894748416073583509">"USB cihaz üçün tətbiq seçin"</string>
+    <string name="noApplications" msgid="2991814273936504689">"Heç bir tətbiq bu əməliyyatı apara bilmir."</string>
+    <string name="aerr_title" msgid="1905800560317137752"></string>
+    <string name="aerr_application" msgid="932628488013092776">"Təəssüf ki, <xliff:g id="APPLICATION">%1$s</xliff:g> dayandı."</string>
+    <string name="aerr_process" msgid="4507058997035697579">"Təəssüf ki, <xliff:g id="PROCESS">%1$s</xliff:g> prosesi dayandı."</string>
+    <string name="anr_title" msgid="4351948481459135709"></string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> cavab vermir.\n\nOnu bağlamaq istəyirsiniz?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"<xliff:g id="ACTIVITY">%1$s</xliff:g> aktivitisi cavab vermir. \n\nOnu bağlamaq istəyirsiniz?"</string>
+    <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> cavab vermir. Onu bağlamaq istəyirsiniz?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Proses <xliff:g id="PROCESS">%1$s</xliff:g> cavab vermir. \n \n Onu bağlamaq istəyirsiniz?"</string>
+    <string name="force_close" msgid="8346072094521265605">"OK"</string>
+    <string name="report" msgid="4060218260984795706">"Şikayət edin"</string>
+    <string name="wait" msgid="7147118217226317732">"Gözlə"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Bu səhifə yararsızlaşıb.\n\nBağlamaq istəyirsiz?"</string>
+    <string name="launch_warning_title" msgid="1547997780506713581">"Tətbiq yönləndirildi"</string>
+    <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> indi çalışır."</string>
+    <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilk başladıldı."</string>
+    <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Miqyas"</string>
+    <string name="screen_compat_mode_show" msgid="4013878876486655892">"Həmişə göstər"</string>
+    <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Bunları Sistem ayarlarında yenidən aktivləşdir Yüklənmiş &gt; Tətbiqlər &gt;."</string>
+    <string name="smv_application" msgid="3307209192155442829">"Tətbiq <xliff:g id="APPLICATION">%1$s</xliff:g> (proses <xliff:g id="PROCESS">%2$s</xliff:g>) StrictMode siyasətini pozdu."</string>
+    <string name="smv_process" msgid="5120397012047462446">"<xliff:g id="PROCESS">%1$s</xliff:g> prosesi StrictMode siyasətini pozdu."</string>
+    <string name="android_upgrading_title" msgid="1584192285441405746">"Android təkmilləşdirilir..."</string>
+    <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g> əddədən <xliff:g id="NUMBER_0">%1$d</xliff:g> tətbiq optimallaşır."</string>
+    <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Tətbiqlər başladılır."</string>
+    <string name="android_upgrading_complete" msgid="1405954754112999229">"Yükləmə başa çatır."</string>
+    <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> çalışır"</string>
+    <string name="heavy_weight_notification_detail" msgid="1721681741617898865">"Tətbiqə keçmək üçün toxunun"</string>
+    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Tətbiqlərə keçilsin?"</string>
+    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Bir tətbiq artıq işləyir. Digərini başlatmaq üçün onu dayandırmalısınız."</string>
+    <string name="old_app_action" msgid="493129172238566282">"<xliff:g id="OLD_APP">%1$s</xliff:g> bölməsinə qayıdın"</string>
+    <string name="old_app_description" msgid="2082094275580358049">"Yeni tətbiqi başlatmayın."</string>
+    <string name="new_app_action" msgid="5472756926945440706">"<xliff:g id="OLD_APP">%1$s</xliff:g> tətbiqini başladın"</string>
+    <string name="new_app_description" msgid="1932143598371537340">"Köhnə tətbiqi yadda saxlamadan dayandırın."</string>
+    <string name="sendText" msgid="5209874571959469142">"Mətn üçün əməliyyat seçin"</string>
+    <string name="volume_ringtone" msgid="6885421406845734650">"Zəngin səs gücü"</string>
+    <string name="volume_music" msgid="5421651157138628171">"Media həcmi"</string>
+    <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"Bluetooth vasitəsilə oynadılır"</string>
+    <string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"Səssiz zəng"</string>
+    <string name="volume_call" msgid="3941680041282788711">"Daxili zəng səsi"</string>
+    <string name="volume_bluetooth_call" msgid="2002891926351151534">"Bluetooth zəng həcmi"</string>
+    <string name="volume_alarm" msgid="1985191616042689100">"Siqnal səsi"</string>
+    <string name="volume_notification" msgid="2422265656744276715">"Bildiriş səsi"</string>
+    <string name="volume_unknown" msgid="1400219669770445902">"Həcm"</string>
+    <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"Bluetooth həcmi"</string>
+    <string name="volume_icon_description_ringer" msgid="3326003847006162496">"Zəng səsi gücü"</string>
+    <string name="volume_icon_description_incall" msgid="8890073218154543397">"Zəng həcmi"</string>
+    <string name="volume_icon_description_media" msgid="4217311719665194215">"Media həcmi"</string>
+    <string name="volume_icon_description_notification" msgid="7044986546477282274">"Bildiriş səsi"</string>
+    <string name="ringtone_default" msgid="3789758980357696936">"Defolt rinqton"</string>
+    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Defolt rinqton (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <string name="ringtone_silent" msgid="7937634392408977062">"Heç biri"</string>
+    <string name="ringtone_picker_title" msgid="3515143939175119094">"Zəng səsləri"</string>
+    <string name="ringtone_unknown" msgid="5477919988701784788">"Naməlum rinqton"</string>
+  <plurals name="wifi_available">
+    <item quantity="one" msgid="6654123987418168693">"Wi-Fi şəbəkəsi mövcuddur"</item>
+    <item quantity="other" msgid="4192424489168397386">"Wi-Fi şəbəkələri mövcuddur"</item>
+  </plurals>
+  <plurals name="wifi_available_detailed">
+    <item quantity="one" msgid="1634101450343277345">"Wi-Fi şəbəkəni açın"</item>
+    <item quantity="other" msgid="7915895323644292768">"Açıq Wi-Fi şəbəkələri mövcuddur"</item>
+  </plurals>
+    <string name="wifi_available_sign_in" msgid="4029489716605255386">"Wi-Fi şəbəkəsinə daxil ol"</string>
+    <string name="network_available_sign_in" msgid="8495155593358054676">"Şəbəkəyə daxil olun"</string>
+    <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
+    <skip />
+    <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi\'a qoşulmaq alınmadı"</string>
+    <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" internet bağlantısı keyfiyyətsizdir."</string>
+    <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+    <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wi-Fi Direct əməliyyatını başlat. Bu Wi-Fi müştəri/hotspotu bağlayacaq."</string>
+    <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi Direct başladıla bilmədi."</string>
+    <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct aktivdir"</string>
+    <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Ayarlar üçün toxunun"</string>
+    <string name="accept" msgid="1645267259272829559">"Qəbul edin"</string>
+    <string name="decline" msgid="2112225451706137894">"İmtina edin"</string>
+    <string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Dəvətnamə göndərildi"</string>
+    <string name="wifi_p2p_invitation_to_connect_title" msgid="4958803948658533637">"Qoşulmaq üçün dəvət"</string>
+    <string name="wifi_p2p_from_message" msgid="570389174731951769">"Kimdən:"</string>
+    <string name="wifi_p2p_to_message" msgid="248968974522044099">"Kimə:"</string>
+    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"Tələb olunan PİN kodu daxil edin:"</string>
+    <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PİN:"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"Bu planşet <xliff:g id="DEVICE_NAME">%1$s</xliff:g> cihazına qoşulan zaman Wi-Fi şəbəkəsindən müvəqqəti ayrılmış olacaq"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"Bu telefon <xliff:g id="DEVICE_NAME">%1$s</xliff:g> cihazına qoşulan zaman Wi-Fi şəbəkəsindən müvəqqəti ayrılmış olacaq"</string>
+    <string name="select_character" msgid="3365550120617701745">"Simvol daxil edin"</string>
+    <string name="sms_control_title" msgid="7296612781128917719">"SMS mesaj göndərilir"</string>
+    <string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; çox sayda SMS mesaj göndərir. Bu tətbiqin mesaj göndərməyə davam etməsinə icazə verirsiniz?"</string>
+    <string name="sms_control_yes" msgid="3663725993855816807">"İcazə verin"</string>
+    <string name="sms_control_no" msgid="625438561395534982">"Rədd edin"</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; ünvanına mesaj göndərmək istəyir."</string>
+    <string name="sms_short_code_details" msgid="3492025719868078457">"Bu, mobil hesabınıza "<font fgcolor="#ffffb060">"əlavə tariflərin tətbiq olunması"</font>" ilə nəticələnə bilər."</string>
+    <string name="sms_premium_short_code_details" msgid="5523826349105123687"><font fgcolor="#ffffb060">"Bu mobil hesabınızda ödənişlərə səbəb olacaq."</font></string>
+    <string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"Göndər"</string>
+    <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"Ləğv et"</string>
+    <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"Mənim seçimimi yadda saxla"</string>
+    <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"Bunu sonra Ayarlarda dəyişə bilərsiniz &gt; Tətbiqlər"</string>
+    <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Həmişə icazə ver"</string>
+    <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Heç vaxt icazə verməyin"</string>
+    <string name="sim_removed_title" msgid="6227712319223226185">"SIM kart çıxarıldı"</string>
+    <string name="sim_removed_message" msgid="2333164559970958645">"Cihazınızı etibarlı SIM kart ilə başladana kimi mobil şəbəkə əlçatmaz olacaq."</string>
+    <string name="sim_done_button" msgid="827949989369963775">"Bitdi"</string>
+    <string name="sim_added_title" msgid="3719670512889674693">"SİM kart əlavə edildi"</string>
+    <string name="sim_added_message" msgid="6599945301141050216">"Mobil şəbəkəyə qoşulmaq üçün cihazınızı yenidən başladın."</string>
+    <string name="sim_restart_button" msgid="4722407842815232347">"Yenidən başlat"</string>
+    <string name="time_picker_dialog_title" msgid="8349362623068819295">"Vaxt ayarlayın"</string>
+    <string name="date_picker_dialog_title" msgid="5879450659453782278">"Tarixi quraşdır"</string>
+    <string name="date_time_set" msgid="5777075614321087758">"Ayarlayın"</string>
+    <string name="date_time_done" msgid="2507683751759308828">"Hazırdır"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff33b5e5">"YENİ: "</font></string>
+    <string name="perms_description_app" msgid="5139836143293299417">"<xliff:g id="APP_NAME">%1$s</xliff:g> tərəfindən təmin edilib."</string>
+    <string name="no_permissions" msgid="7283357728219338112">"Heç bir icazə tələb olunmur"</string>
+    <string name="perm_costs_money" msgid="4902470324142151116">"bununla sizdən xərc tutula bilər"</string>
+    <string name="usb_storage_activity_title" msgid="4465055157209648641">"USB toplu yaddaş"</string>
+    <string name="usb_storage_title" msgid="5901459041398751495">"USB qoşuludur"</string>
+    <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"Siz USB vasitəsilə kompütere bağlandınız. Kompüter və Androidinizin USB yaddaşı arasında faylları kopyalamaq istəyirsinizsə, aşağıdakı düyməyə toxunun."</string>
+    <string name="usb_storage_message" product="default" msgid="805351000446037811">"Kompüterinizə USB ilə qoşulmusunuz. Faylları Androidinizin SD kartı ilə kompüteriniz arasında kopyalamaq istəyirsinizsə aşağıdakı düyməyə toxunun."</string>
+    <string name="usb_storage_button_mount" msgid="1052259930369508235">"USB yaddaşı aktivləşdirin"</string>
+    <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"USB yaddaşınızı USB kütləvi yaddaşı üçün istifadə edən zaman problem yarandı."</string>
+    <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"SD kartınızı USB kütləvi yaddaşı üçün istifadə edən zaman problem yarandı."</string>
+    <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB qoşuludur"</string>
+    <string name="usb_storage_notification_message" msgid="939822783828183763">"Faylları kompüterinizə kopyalamaq və ya kompüterinizdən kopyalamaq üçün toxunun."</string>
+    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"USB yaddaşı söndürün"</string>
+    <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"USB yaddaşı söndürmək üçün toxunun."</string>
+    <string name="usb_storage_stop_title" msgid="660129851708775853">"USB yaddaş istifadə olunur"</string>
+    <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"USB yaddaşı söndürmədən öncə Android\'in USB yaddaşını kompüterdən demontaj etdiyinizə (çıxardığınıza) əmin olun."</string>
+    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"USB yaddaşı söndürmədən öncə Android\'in USB yaddaşını kompüterdən demontaj etdiyinizə (çıxardığınıza) əmin olun."</string>
+    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"USB yaddaşını söndür"</string>
+    <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"USB yaddaşı söndürən zaman problem oldu. USB hostu demontaj etmənizi yoxlayın və yenidən cəhd edin."</string>
+    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"USB yaddaşı aktivləşdirin"</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"USB yaddaşı aktivləşdirsəniz, istifadə etdiyiniz bəzi tətbiqlər dayana bilər və USB yaddaş deaktiv edilənə qədər işləməyə bilər."</string>
+    <string name="dlg_error_title" msgid="7323658469626514207">"USB əməliyyatı uğursuzdur"</string>
+    <string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
+    <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Media cihazı kimi qoşuldu"</string>
+    <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Kamera kimi bağlanıldı"</string>
+    <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Quraşdırıcı kimi qoşulub"</string>
+    <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB aksesuara qoşuldu"</string>
+    <string name="usb_notification_message" msgid="2290859399983720271">"Digər USB seçimləri üçün toxunun."</string>
+    <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB yaddaşına format atılsın?"</string>
+    <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD kart format edilsin?"</string>
+    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"USB yaddaşınızda yerləşdirilmiş bütün fayllar silinəcək. Bu addım geri dönülməzdir."</string>
+    <string name="extmedia_format_message" product="default" msgid="14131895027543830">"Kartınızdakı bütün məlumatlar itəcək."</string>
+    <string name="extmedia_format_button_format" msgid="4131064560127478695">"Format"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"USB sazlama qoşuludur"</string>
+    <string name="adb_active_notification_message" msgid="1016654627626476142">"USB debaqı deaktivasiya etmək üçün toxunun."</string>
+    <string name="select_input_method" msgid="4653387336791222978">"Daxiletmə metodunu seçin"</string>
+    <string name="configure_input_methods" msgid="9091652157722495116">"Daxiletmə üsullarını ayarlayın"</string>
+    <string name="use_physical_keyboard" msgid="6203112478095117625">"Fiziki klaviatura"</string>
+    <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Klaviatura sxemi seçin"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Klaviatura tərtibatı seçmək üçün toxunun."</string>
+    <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCÇDEƏFGĞHXIİJKQLMNOÖPRSŞTUÜVYZ"</string>
+    <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCÇDEƏFGĞHİIJKLMNOÖPQRSŞTUÜVWXYZ"</string>
+    <string name="candidates_style" msgid="4333913089637062257"><u>"namizədlər"</u></string>
+    <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"USB yaddaş hazırlanır"</string>
+    <string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"SD kart hazırlanır"</string>
+    <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"Səhvlər yoxlanılır."</string>
+    <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"Boş USB yaddaşı"</string>
+    <string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"Boş SD kart"</string>
+    <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"USB yaddaş boşdur və ya sistem tərəfindən dəstəklənməyən fayl sisteminə malikdir."</string>
+    <string name="ext_media_nofs_notification_message" product="default" msgid="8641065641786923604">"SD kart boşdur və ya sistem tərəfindən dəstəklənməyən fayl sisteminə malikdir."</string>
+    <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"Zədəli USB yaddaş"</string>
+    <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"Zədəli SD kart"</string>
+    <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="1795917578395333280">"SD yaddaş zədələnib. Onu format etməyə çalışın."</string>
+    <string name="ext_media_unmountable_notification_message" product="default" msgid="1753898567525568253">"SD kart zədələnib. Onu format etməyə çalışın."</string>
+    <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"USB yaddaşı gözlənilmədən çıxarıldı"</string>
+    <string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"SD kart gözlənilmədən çıxarıldı"</string>
+    <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"Məlumat itkisinin qarşısını almaq üçün USB yaddaşı çıxarmazdan əvvəl onu demontaj edin."</string>
+    <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"Data itkisinin qarşısını almaq üçün SD kartı çıxarmadan öncə demontaj edin."</string>
+    <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"USB yaddaş çıxarmaq üçün təhlükəsizdir"</string>
+    <string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"SD kart təhlükəsiz çıxarıla bilər"</string>
+    <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"Siz USB yaddaşı təhlükəsiz çıxara bilərsiniz."</string>
+    <string name="ext_media_safe_unmount_notification_message" product="default" msgid="568841278138377604">"Siz SD kartı təhlükəsiz çıxara bilərsiniz."</string>
+    <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"Silinmiş USB yaddaş"</string>
+    <string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"SD kart çıxarıldı"</string>
+    <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"USB yaddaş çıxarıldı. Yeni media əlavə edin."</string>
+    <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"SD kart çıxarıldı. Yenisini daxil edin."</string>
+    <string name="activity_list_empty" msgid="1675388330786841066">"Uyğun gələn fəaliyyət tapılmadı."</string>
+    <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"komponent istifadəsi statistikasını güncəlləyir"</string>
+    <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"Tətbiqə toplanmış istifadə statistikasını dəyişməyə imkan verir. Normal tətbiqlər tərəfindən istifadə olunmur."</string>
+    <string name="permlab_copyProtectedData" msgid="4341036311211406692">"məzmunu kopyala"</string>
+    <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Tətbiqə kontenti kopyalamaq üçün defolt konteyner servisini çağırmaq icazəsi verir. Normal tətbiqlər tərəfindən istifadə edilmir."</string>
+    <string name="permlab_route_media_output" msgid="1642024455750414694">"Media çıxışını yönləndirir"</string>
+    <string name="permdesc_route_media_output" msgid="4932818749547244346">"Tətbiqə media çıxışını digər xarici cihazlara yönləndirmək imkanı verir."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Keyguard təhlükəsiz yaddaşa çıxış"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Tətbiqə keguard təhlükəsiz yaddaşa çatmağa icazə verir."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Klaviatura kilidinin görülməsini və gizlədilməsini idarə edir"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Tətbiqə keguardı idarə etmək icazəsi verir."</string>
+    <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Zoom nəzarəti üçün iki dəfə toxunun"</string>
+    <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Widget əlavə edilə bilmədi."</string>
+    <string name="ime_action_go" msgid="8320845651737369027">"Get"</string>
+    <string name="ime_action_search" msgid="658110271822807811">"Axtar"</string>
+    <string name="ime_action_send" msgid="2316166556349314424">"Göndər"</string>
+    <string name="ime_action_next" msgid="3138843904009813834">"Növbəti"</string>
+    <string name="ime_action_done" msgid="8971516117910934605">"Tamam"</string>
+    <string name="ime_action_previous" msgid="1443550039250105948">"Əvvəlki"</string>
+    <string name="ime_action_default" msgid="2840921885558045721">"İcra edin"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"<xliff:g id="NUMBER">%s</xliff:g> istifadə etməklə\nnömrə yığın"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"<xliff:g id="NUMBER">%s</xliff:g>istifadə edərək kontakt yaradın\n"</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Aşağıdakı bir və ya daha çox tətbiqlər indi və gələcəkdə hesabınıza daxil olmaq üçün icazə istəyir."</string>
+    <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Bu istəyə izn vermək istəyirsiniz?"</string>
+    <string name="grant_permissions_header_text" msgid="6874497408201826708">"Giriş sorğusu"</string>
+    <string name="allow" msgid="7225948811296386551">"İcazə verin"</string>
+    <string name="deny" msgid="2081879885755434506">"Rədd et"</string>
+    <string name="permission_request_notification_title" msgid="6486759795926237907">"İcazə tələb olunur"</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">\n" hesabı üçün<xliff:g id="ACCOUNT">%s</xliff:g> icazə sorğusu göndərildi."</string>
+    <string name="input_method_binding_label" msgid="1283557179944992649">"Daxiletmə metodu"</string>
+    <string name="sync_binding_label" msgid="3687969138375092423">"Sinxronizasiya"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"Əlçatımlılıq"</string>
+    <string name="wallpaper_binding_label" msgid="1240087844304687662">"Divar kağızı"</string>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"Divar kağızını dəyişin"</string>
+    <string name="notification_listener_binding_label" msgid="2014162835481906429">"Bildiriş dinləyən"</string>
+    <string name="vpn_title" msgid="19615213552042827">"VPN aktivləşdirildi"</string>
+    <string name="vpn_title_long" msgid="6400714798049252294">"VPN <xliff:g id="APP">%s</xliff:g> tərəfindən aktivləşdirilib"</string>
+    <string name="vpn_text" msgid="3011306607126450322">"Şəbəkəni idarə etmək üçün toxunun."</string>
+    <string name="vpn_text_long" msgid="6407351006249174473">"<xliff:g id="SESSION">%s</xliff:g> sessiyaya qoşuludur. Şəbəkəni idarə etmək üçün toxunun."</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_error" msgid="6009249814034708175">"Həmişə aktiv VPN xətası"</string>
+    <string name="vpn_lockdown_config" msgid="6415899150671537970">"Konfiqurə etmək üçün toxun"</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>
+    <string name="submit" msgid="1602335572089911941">"Göndər"</string>
+    <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Avtomobil rejimi aktivdir"</string>
+    <string name="car_mode_disable_notification_message" msgid="8035230537563503262">"Avtomobil rejimindən çıxmaq üçün toxunun."</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"Tezerinq və ya hotspot aktivdir"</string>
+    <string name="tethered_notification_message" msgid="6857031760103062982">"Quraşdırmaq üçün toxunun."</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>
+    <string name="throttle_warning_notification_title" msgid="4890894267454867276">"Yüksək mobil data istifadəsi"</string>
+    <string name="throttle_warning_notification_message" msgid="3340822228599337743">"Mobil data istifadəsi haqqında daha çox öyrənmək üçün toxunun."</string>
+    <string name="throttled_notification_title" msgid="6269541897729781332">"Mobil data limiti keçildi"</string>
+    <string name="throttled_notification_message" msgid="5443457321354907181">"Mobil data istifadəsi haqqında daha çox öyrənmək üçün toxunun."</string>
+    <string name="no_matches" msgid="8129421908915840737">"Uyğunluq yoxdur"</string>
+    <string name="find_on_page" msgid="1946799233822820384">"Səhifədə tap"</string>
+  <plurals name="matches_found">
+    <item quantity="one" msgid="8167147081136579439">"1 uyğunluq"</item>
+    <item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> ədəddən <xliff:g id="TOTAL">%d</xliff:g>"</item>
+  </plurals>
+    <string name="action_mode_done" msgid="7217581640461922289">"Hazırdır"</string>
+    <string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"USB yaddaşı qaldırılır..."</string>
+    <string name="progress_unmounting" product="default" msgid="1327894998409537190">"SD kart demontaj edilir..."</string>
+    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"USB yaddaş silinir..."</string>
+    <string name="progress_erasing" product="default" msgid="6596988875507043042">"SD kart silinir..."</string>
+    <string name="format_error" product="nosdcard" msgid="6299769563624776948">"USB yaddaşı silinə bilmədi."</string>
+    <string name="format_error" product="default" msgid="7315248696644510935">"SD kartı silmək mümkün olmadı."</string>
+    <string name="media_bad_removal" msgid="7960864061016603281">"SD kart demontaj edilmədən öncə çıxarıldı."</string>
+    <string name="media_checking" product="nosdcard" msgid="418188720009569693">"USB yaddaş hazırda yoxlanılır."</string>
+    <string name="media_checking" product="default" msgid="7334762503904827481">"SD kart hazırda yoxlanılır."</string>
+    <string name="media_removed" msgid="7001526905057952097">"SD kart çıxarılıb."</string>
+    <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"SD kart hazırda kompüter tərəfindən istifadə edilir."</string>
+    <string name="media_shared" product="default" msgid="5706130568133540435">"SD kart hal-hazırda kompüter tərəfindən istifadə edilir."</string>
+    <string name="media_unknown_state" msgid="729192782197290385">"Naməlum vəziyyətdə xarici media."</string>
+    <string name="share" msgid="1778686618230011964">"Paylaşın"</string>
+    <string name="find" msgid="4808270900322985960">"Tapın"</string>
+    <string name="websearch" msgid="4337157977400211589">"Veb Axtarış"</string>
+    <string name="find_next" msgid="5742124618942193978">"Sonrakını tap"</string>
+    <string name="find_previous" msgid="2196723669388360506">"Əvvəlkini tap"</string>
+    <string name="gpsNotifTicker" msgid="5622683912616496172">"<xliff:g id="NAME">%s</xliff:g> tərəfindən məkan sorğusu"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Məkan sorğusu"</string>
+    <string name="gpsNotifMessage" msgid="1374718023224000702">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>) tərəfindən tələb edilib"</string>
+    <string name="gpsVerifYes" msgid="2346566072867213563">"Bəli"</string>
+    <string name="gpsVerifNo" msgid="1146564937346454865">"Xeyr"</string>
+    <string name="sync_too_many_deletes" msgid="5296321850662746890">"Limiti keçəni silin"</string>
+    <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> üçün <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> silinmiş fayl var, <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> hesabı. Nə etmək istəyirsiniz?"</string>
+    <string name="sync_really_delete" msgid="2572600103122596243">"Elementləri sil"</string>
+    <string name="sync_undo_deletes" msgid="2941317360600338602">"Silinənləri geri qaytar"</string>
+    <string name="sync_do_nothing" msgid="3743764740430821845">"İndilik heç nə etmə"</string>
+    <string name="choose_account_label" msgid="5655203089746423927">"Hesab seçin"</string>
+    <string name="add_account_label" msgid="2935267344849993553">"Hesab əlavə et"</string>
+    <string name="add_account_button_label" msgid="3611982894853435874">"Hesab əlavə edin"</string>
+    <string name="number_picker_increment_button" msgid="2412072272832284313">"Artır"</string>
+    <string name="number_picker_decrement_button" msgid="476050778386779067">"Azaldın"</string>
+    <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> toxunun və basaraq saxlayın."</string>
+    <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Artırmaq üçün yuxarı, azaltmaq üçün aşağı sürüşdürün."</string>
+    <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Dəqiqə artırın"</string>
+    <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Dəqiqəni azalt"</string>
+    <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Saatı artırın"</string>
+    <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Saatı azaldın"</string>
+    <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"PM qurun"</string>
+    <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"AM qurun"</string>
+    <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Artma ayı"</string>
+    <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Ayı azaldın"</string>
+    <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Artma günü"</string>
+    <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Azalma günü"</string>
+    <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Artım ili"</string>
+    <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Azalma ili"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Ləğv et"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Sil"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Hazırdır"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Rejim dəyişikliyi"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Daxil olun"</string>
+    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Tətbiq seçin"</string>
+    <string name="shareactionprovider_share_with" msgid="806688056141131819">"Bununla paylaşın"</string>
+    <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> ilə paylaşın"</string>
+    <string name="content_description_sliding_handle" msgid="415975056159262248">"Sürüşən qulp. Toxunaraq basılı tutun."</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> üçün yuxarı sürüşdürün."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> üçün aşağı sürüşdürün."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> üçün sola sürüşdür."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> üçün sağa sürüşdür."</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Kilidi aç"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Səssiz"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Səs açıqdır"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Axtar"</string>
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Kilidi açmaq üçün vurun."</string>
+    <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Parolların səsləndirilməsi üçün qulaqlıqları taxın."</string>
+    <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Nöqtə."</string>
+    <string name="action_bar_home_description" msgid="5293600496601490216">"Evə gedin"</string>
+    <string name="action_bar_up_description" msgid="2237496562952152589">"Yuxarı gedin"</string>
+    <string name="action_menu_overflow_description" msgid="2295659037509008453">"Əlavə seçimlər"</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="4891916833657929263">"Daxili yaddaş"</string>
+    <string name="storage_sd_card" msgid="3282948861378286745">"SD kart"</string>
+    <string name="storage_usb" msgid="3017954059538517278">"USB yaddaş"</string>
+    <string name="extract_edit_menu_button" msgid="8940478730496610137">"Redaktə et"</string>
+    <string name="data_usage_warning_title" msgid="1955638862122232342">"Data istifadə xəbərdarlığı"</string>
+    <string name="data_usage_warning_body" msgid="2814673551471969954">"İstifadə və ayarları görmək üçün toxunun"</string>
+    <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-3G data deaktivdir"</string>
+    <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G data deaktiv edildi"</string>
+    <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobil data deaktivdir"</string>
+    <string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"Wi-Fi data deaktiv edildi"</string>
+    <string name="data_usage_limit_body" msgid="3317964706973601386">"Aktivləşdirmək üçün toxunun."</string>
+    <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"2G-3G data limiti aşılıb"</string>
+    <string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"4G data limiti keçildi"</string>
+    <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"Mobil data limiti keçildi"</string>
+    <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Wi-Fi data limiti keçildi"</string>
+    <string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> müəyyən edilmiş limit aşır."</string>
+    <string name="data_usage_restricted_title" msgid="5965157361036321914">"Arxaplan datası məhdudlaşdırıldı"</string>
+    <string name="data_usage_restricted_body" msgid="6741521330997452990">"Məhdudiyyəti aradan qaldırmaq üçün toxunun"</string>
+    <string name="ssl_certificate" msgid="6510040486049237639">"Təhlükəsizlik sertifikatı"</string>
+    <string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Bu sertifikat etibarlıdır."</string>
+    <string name="issued_to" msgid="454239480274921032">"Verilib:"</string>
+    <string name="common_name" msgid="2233209299434172646">"Ümumi ad:"</string>
+    <string name="org_name" msgid="6973561190762085236">"Təşkilat:"</string>
+    <string name="org_unit" msgid="7265981890422070383">"Təşkilati vahid:"</string>
+    <string name="issued_by" msgid="2647584988057481566">"Tərəfindən verilib:"</string>
+    <string name="validity_period" msgid="8818886137545983110">"Keçərlilik:"</string>
+    <string name="issued_on" msgid="5895017404361397232">"Dərc olunub:"</string>
+    <string name="expires_on" msgid="3676242949915959821">"Bitmə vaxtı:"</string>
+    <string name="serial_number" msgid="758814067660862493">"Seriya nömrəsi:"</string>
+    <string name="fingerprints" msgid="4516019619850763049">"Barmaq izləri:"</string>
+    <string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 barmaq izi:"</string>
+    <string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 barmaq izi:"</string>
+    <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Hamısını seçın"</string>
+    <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Fəaliyyəti seçin"</string>
+    <string name="share_action_provider_share_with" msgid="5247684435979149216">"Bununla paylaşın"</string>
+    <string name="status_bar_device_locked" msgid="3092703448690669768">"Cihaz kilidləndi."</string>
+    <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="3245653681008218030">"Göndərilir..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Brauzer işə salınsın?"</string>
+    <string name="SetupCallDefault" msgid="5834948469253758575">"Zəngi qəbul edək?"</string>
+    <string name="activity_resolver_use_always" msgid="8017770747801494933">"Həmişə"</string>
+    <string name="activity_resolver_use_once" msgid="2404644797149173758">"Sadəcə bir dəfə"</string>
+    <string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"Planşet"</string>
+    <string name="default_audio_route_name" product="default" msgid="4239291273420140123">"Telefon"</string>
+    <string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Qulaqlıq"</string>
+    <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Dok spikerlər"</string>
+    <string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string>
+    <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">"Simsiz ekran"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Hazırdır"</string>
+    <string name="media_route_button_content_description" msgid="5758553567065145276">"Media çıxışı"</string>
+    <string name="media_route_status_scanning" msgid="7279908761758293783">"Skan edilir..."</string>
+    <string name="media_route_status_connecting" msgid="6422571716007825440">"Qoşulur..."</string>
+    <string name="media_route_status_available" msgid="6983258067194649391">"Əlçatımlı"</string>
+    <string name="media_route_status_not_available" msgid="6739899962681886401">"Əlçatımlı deyil"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"İstifadə olunur"</string>
+    <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Daxili ekran"</string>
+    <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"HDMI Ekran"</string>
+    <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Örtük #<xliff:g id="ID">%1$d</xliff:g>"</string>
+    <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", təhlükəsiz"</string>
+    <string name="wifi_display_notification_title" msgid="2223050649240326557">"Simsiz ekran qoşulub"</string>
+    <string name="wifi_display_notification_message" msgid="4498802012464170685">"Bu ekran digər cihazda göstərir"</string>
+    <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Bağlantını kəsin"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Təcili zəng"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Şablonu unutmuşam"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Yanlış Model"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Yanlış Şifrə"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN səhvdir"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%1$d</xliff:g> saniyə sonra yenidən cəhd edin."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Şablonunuzu çəkin"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM PIN kodu daxil edin"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"PİN kodu daxil edin"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Parol daxil edin"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM indi deaktivdir. Davam etmək üçün PUK kodu daxil edin. Əlavə məlumat üçün operatora müraciət edin."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"İstədiyiniz PİN kodu daxil edin"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"İstədiyiniz PIN kodu təsdiqləyin"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SİM kartın kilidi açılır..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Yanlış PİN kod."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4-dən 8-ə qədər rəqəmi olan PIN yazın."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK kod 8 rəqəm və ya daha çox olmalıdır."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Düzgün PUK kodu yenidən daxil edin. Təkrarlanan cəhdlər SIM\'i birdəfəlik sıradan çıxaracaq."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN kodları uyğun deyil"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Həddindən çox cəhd edildi!"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Kilidi açmaq üçün Google hesabınız ilə daxil olun."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"İstifadəçi adı (e-poçt)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Şifrə"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Daxil ol"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Yanlış istifadəçi adı və ya parol."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"İstifadəçi adınızı və ya parolunuzu unutmusunuz?\n "<b>"google.com/accounts/recovery"</b>" linkinə daxil olun."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Hesab yoxlanılır..."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN kodunuzu <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış daxil etdiniz.\n\n <xliff:g id="NUMBER_1">%d</xliff:g> saniyə ərzində yenidən yoxlayın"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Şifrənizi <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış daxil etdiniz. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> saniyə ərzində yenidən yoxlayın."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Modelinizi <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış çəkmisiniz.\n\n <xliff:g id="NUMBER_1">%d</xliff:g> saniyə ərzində yenidən yoxlayın"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Siz planşet kilidini açmaq üçün <xliff:g id="NUMBER_0">%d</xliff:g> dəfə uğursuz cəhd etmisiniz. <xliff:g id="NUMBER_1">%d</xliff:g> dəfə də uğursuz cəhd etsəniz, planşet fabrik ayarlarına sıfırlanacaq və bütün məlumatlarınız itəcək."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Siz telefon kilidini açmaq üçün <xliff:g id="NUMBER_0">%d</xliff:g> dəfə uğursuz cəhd etmisiniz. <xliff:g id="NUMBER_1">%d</xliff:g> dəfə də uğursuz cəhd etsəniz, telefon fabrik ayarlarına sıfırlanacaq və bütün məlumatlarınız itəcək."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Siz planşet kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> dəfə uğursuz cəhd etmisiniz. Planşet fabrik ayarlarına sıfırlanacaq."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Siz telefonun kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> yanlış cəhd etmisiniz. Telefon artıq defolt zavod halına sıfırlanacaq."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Siz kilidi açmaq üçün şablonu <xliff:g id="NUMBER_0">%d</xliff:g> dəfə səhv çəkdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> daha uğursuz cəhddən sonra planşetinizin kilidini e-poçt hesabınızla açmaq tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> saniyə ərzində bir daha yoxlayın."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Siz artıq modeli <xliff:g id="NUMBER_0">%d</xliff:g> dəfə yanlış daxil etmisiniz.<xliff:g id="NUMBER_1">%d</xliff:g> dəfə də yanlış daxil etsəniz, telefonun kilidinin açılması üçün elektron poçt ünvanınız tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> saniyə ərzində yenidən cəhd edin."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" - "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Yığışdır"</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Səs gücü tövsiyə edilən səviyyədən artırılsın?\nUzun müddət yüksək səs gücü ilə dinləmə Sizin eşitmə qabiliyyətinizə mənfi təsir edə bilər."</string>
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Əlçatımlığı aktivləşdirmək üçün iki barmağınızı basılı saxlayın."</string>
+    <string name="accessibility_enabled" msgid="1381972048564547685">"Əlçatımlılıq aktivləşdirildi"</string>
+    <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Giriş imkanı ləğv edilib."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Cari istifadəçi <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="owner_name" msgid="2716755460376028154">"Sahib"</string>
+    <string name="error_message_title" msgid="4510373083082500195">"Xəta"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Bu tətbiq məhdud profillər üçün hesabları dəstəkləmir."</string>
+    <string name="app_not_found" msgid="3429141853498927379">"Bu əməliyyatı idarə etmək üçün heç bir tətbiq tapılmadı."</string>
+    <string name="revoke" msgid="5404479185228271586">"Ləğv edin"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"B4 ISO"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Məktub"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Hökumət Məktubu"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Hüquqi"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Kiçik Hüquq"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Qovluq"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Qısa"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Ləğv edildi"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Kontent yazmna xətası"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN daxil edin"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Cari PIN"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Yeni PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Yeni PIN\'i təsdiq edin"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Dəyişmə məhdudiyyətləri üçün PİN yaradın"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PİN uyğun gəlmir. Yenidən cəhd edin."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"PİN çox qısadır. Ən azı 4 rəqəm olmalıdır."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="4835639969503729874">"Yanlış PİN. 1 saniyə sonra təkrar sınayın."</item>
+    <item quantity="other" msgid="8030607343223287654">"Yanlış PİN. <xliff:g id="COUNT">%d</xliff:g> saniyə sonra təkrar sınayın."</item>
+  </plurals>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Paneli göstərmək üçün ekranın küncünü sürüşdürün"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Sistem panelini göstərmək üçün ekranın küncündən sürüşdürün"</string>
+</resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index fe11bb6..22464ee 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -131,6 +131,12 @@
     <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="default" msgid="3475999286680000541">"Памяць тэлефона поўная. Выдаліце ​​некаторыя файлы, каб вызваліць месца."</string>
+    <!-- no translation found for ssl_ca_cert_warning (5848402127455021714) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Я"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Параметры планшэта"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Параметры тэлефона"</string>
@@ -279,6 +285,10 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Дазваляе прыкладанню перамяшчаць заданні на ​​пярэдні план і ў фон. Шкоднасныя прыкладанні могуць прымусова рабіць сябе асноўнымі без вашага ведама."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"спыніць запушчаныя прыкладанні"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Дазваляе прыкладанням выдаляць заданні і спыняць прыкладанні, якія іх выкарыстоўваюць. Шкоднасныя прыкладаннi могуць перашкодзiць працы іншых прыкладанняў."</string>
+    <!-- no translation found for permlab_manageActivityStacks (7391191384027303065) -->
+    <skip />
+    <!-- no translation found for permdesc_manageActivityStacks (1615881933034084440) -->
+    <skip />
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"пачынаць любы працэс"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Дазваляе прыкладанню пачынаць любы працэс, незалежна ад абароны дазволам ці стану экспарту."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"усталяваць сумяшчальнасць экранаў"</string>
@@ -356,6 +366,18 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Дазваляе ўладальніку прывязвацца да інтэрфейсу верхняга ўзроўню метада ўводу. Не патрабуецца для звычайных прыкладанняў."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"прывязацца да службы доступу"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Дазваляе ўладальніку прывязвацца да інтэрфейсу верхняга ўзроўню службы доступу. Не патрабуецца для звычайных прыкладанняў."</string>
+    <!-- no translation found for permlab_bindPrintService (8462815179572748761) -->
+    <skip />
+    <!-- no translation found for permdesc_bindPrintService (7960067623209111135) -->
+    <skip />
+    <!-- no translation found for permlab_bindPrintSpoolerService (6807762783744125954) -->
+    <skip />
+    <!-- no translation found for permdesc_bindPrintSpoolerService (3680552285933318372) -->
+    <skip />
+    <!-- no translation found for permlab_bindNfcService (2752731300419410724) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNfcService (6120647629174066862) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"звязаць з тэкставай службай"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Дазваляе ўладальніку прывязвацца да інтэрфейсу верхняга ўзроўню тэкставай паслугі (напрыклад, SpellCheckerService). Ніколі не патрабуецца для звычайных прыкладанняў."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"звязвацца з VPN сэрвісам"</string>
@@ -366,6 +388,10 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Дазваляе ўладальніку прывязвацца да інтэрфейсу верхняга ўзроўню службы віджэта. Не патрабуецца для звычайных прыкладанняў."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"узаемадзейнічаць з адміністратарам прылады"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Дазваляе ўладальніку адпраўляць намеры да адміністратара прылады. Не патрабуецца для звычайных прыкладанняў."</string>
+    <!-- no translation found for permlab_manageDeviceAdmins (4248828900045808722) -->
+    <skip />
+    <!-- no translation found for permdesc_manageDeviceAdmins (5025608167709942485) -->
+    <skip />
     <string name="permlab_setOrientation" msgid="3365947717163866844">"змяняць арыентацыю экрана"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Дазваляе прыкладанням змяняць паварот экрана ў любы час. Не патрабуецца для звычайных прыкладанняў."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"змена хутк. перамяшч. ўказ."</string>
@@ -397,6 +423,10 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Дазваляе прыкладанню счытваць розныя сістэмныя файлы гiсторый. Гэта дазваляе атрымліваць агульную інфармацыю аб тым, як выкарыстоўваецца тэлефон, у тым ліку, магчыма, асабістую або прыватную інфармацыю."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"для прайгравання выкарыстоўваць любы мультымедыйны дэкодэр"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Дазваляе прыкладанням выкарыстоўваць любы ўсталяваны iнструмент для мультымедыйнага дэкадавання, каб прайграць."</string>
+    <!-- no translation found for permlab_manageCaCertificates (1678391896786882014) -->
+    <skip />
+    <!-- no translation found for permdesc_manageCaCertificates (4015644047196937014) -->
+    <skip />
     <string name="permlab_diagnostic" msgid="8076743953908000342">"чытаць/запісваць на дыягнастычныя рэсурсы"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Дазваляе прыкладанням счытваць і запісваць любы рэсурс, які належыць дыягнастычнай групе, напрыклад файлы распрацоўшчыка ў тэчцы /dev. Патэнцыйна гэта можа паўплываць на стабільнасць і бяспеку сістэмы. Гэта павінна выкарыстоўвацца ТОЛЬКІ для апаратнай дыягностыкі вытворцам або аператарам."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"уключыць або адключыць кампаненты прыкладання"</string>
@@ -462,6 +492,22 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Дазволiць прыкладанню наладжвацца i падключацца да дысплеяў Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"кіраванне дысплеямi Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Прыкладанне зможа кіраваць нізкім узроўнем функцый дысплеяў Wi-Fi."</string>
+    <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
+    <skip />
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <!-- no translation found for permlab_captureVideoOutput (2246828773589094023) -->
+    <skip />
+    <!-- no translation found for permdesc_captureVideoOutput (359481658034149860) -->
+    <skip />
+    <!-- no translation found for permlab_captureSecureVideoOutput (7815398969303382016) -->
+    <skip />
+    <!-- no translation found for permdesc_captureSecureVideoOutput (2779793064709350289) -->
+    <skip />
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"змяняць налады аудыё"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Дазваляе прыкладанням змяняць глабальныя налады гуку, такія як моц і тое, што дынамік выкарыстоўваецца для выхаду."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"запісваць аўдыё"</string>
@@ -525,6 +571,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"забараняць тэлефону пераходзіць ў рэжым сну"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Дазваляе прыкладанням прадухіляць пераход планшэта ў рэжым сну."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Дазваляе прыкладанням прадухіляць тэлефон ад пераходу ў рэжым сну."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"Уключыць або выключыць планшэт"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"уключаць або выключаць тэлефон"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Дазваляе прыкладанням уключаць ці адключаць планшэт."</string>
@@ -613,6 +665,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Дазваляе прыкладанням запісваць на SD-карту."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"змяніць/выдаліць унутраныя носьбіты змесціва"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Дазваляе прыкладанням змяняць змесціва ўнутранай памяці."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"кіраваць сховішчам для дакументаў"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Дазваляе прыкладанню кіраваць сховішчам для дакументаў."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"доступ да знешніх захоўвання для ўсіх карыстальнікаў"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Дазваляе ўсiм карыстальнiкам прыкладання атрымлiваць доступ да знешнега сховiшча"</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"доступ да файлавай сістэмы кэша"</string>
@@ -625,10 +679,22 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Дазваляе прыкладаннм кіраваць сеткавымі палітыкамі і вызначаць правілы пэўных прыкладанняў."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"змяніць улік выкарыстання сеткі"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Дазваляе прыкладанням змяняць метад уліку выкарыстання сеткі прыкладаннямі. Не для выкарыстання звычайнымі прыкладаннямі."</string>
+    <!-- no translation found for permlab_markNetworkSocket (3658527214914959749) -->
+    <skip />
+    <!-- no translation found for permdesc_markNetworkSocket (7655568433696356578) -->
+    <skip />
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"доступ да паведамленняў"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Дазваляе прыкладанню атрымлiваць, правяраць i выдаляць апавяшчэннi, у тым лiку апублiкаваныя iншымi прыкладаннямi."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"прывязка да службы апавяшчэння слухача"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Дазваляе ўладальніку прывязвацца да верхняга ўзроўню інтэрфейсу службы  апавяшчэння слухачоў. Ніколі не патрэбнае для звычайных прыкладанняў."</string>
+    <!-- no translation found for permlab_invokeCarrierSetup (3699600833975117478) -->
+    <skip />
+    <!-- no translation found for permdesc_invokeCarrierSetup (4159549152529111920) -->
+    <skip />
+    <!-- no translation found for permlab_accessNetworkConditions (8206077447838909516) -->
+    <skip />
+    <!-- no translation found for permdesc_accessNetworkConditions (6899102075825272211) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Устанавіць правілы паролю"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Кіраванне даўжынёй і колькасцю знакаў у паролі разблакоўкі экрана."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Сачыць за спробамі разблакоўкі экрана"</string>
@@ -796,7 +862,7 @@
     <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">"Ваша SIM-карта была адключана назаўсёды.\n Звяжыцеся з аператарам бесправадной сувязі, каб атрымаць іншую SIM-карту."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Кнопка папярэдняй кампазiцыi"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Кнопка наступнай кампазiцыi"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Кнопка паўзы"</string>
@@ -808,11 +874,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Глядзіце \"Інструкцыю для карыстальніка\" або звяжыцеся са службай тэхнiчнай падтрымкі."</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">%d</xliff:g>. "\n\n"Паўтарыце спробу праз наступную колькасць секунд: <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Вы няправільна ўвялі пароль пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n"Паўтарыце спробу праз наступную колькасць секунд: <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Вы няправільна ўвялі PIN-код пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n"Паўтарыце спробу праз наступную колькасць секунд: <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Вы няправільна ўвялі графічны ключ разблакавання пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. Пасля яшчэ некалькiх няўдалых спроб (<xliff:g id="NUMBER_1">%d</xliff:g>) вам будзе прапанавана разблакаваць планшэт з дапамогай уваходу ў Google."\n\n" Паўтарыце спробу праз наступную колькасць секунд: <xliff:g id="NUMBER_2">%d</xliff:g>."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Вы няправільна ўвялі графічны ключ разблакавання пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. Пасля яшчэ некалькiх няўдалых спроб (<xliff:g id="NUMBER_1">%d</xliff:g>) вам будзе прапанавана разблакаваць тэлефон з дапамогай уваходу ў Google."\n\n" Паўтарыце спробу праз наступную колькасць секунд: <xliff:g id="NUMBER_2">%d</xliff:g>."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Вы няправільна ўвялі графічны ключ разблакавання пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. \n\nПаўтарыце спробу праз наступную колькасць секунд: <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Вы няправільна ўвялі пароль пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. \n\nПаўтарыце спробу праз наступную колькасць секунд: <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Вы няправільна ўвялі PIN-код пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. \n\nПаўтарыце спробу праз наступную колькасць секунд: <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Вы няправільна ўвялі графічны ключ разблакавання пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. Пасля яшчэ некалькiх няўдалых спроб (<xliff:g id="NUMBER_1">%d</xliff:g>) вам будзе прапанавана разблакаваць планшэт з дапамогай уваходу ў Google.\n\n Паўтарыце спробу праз наступную колькасць секунд: <xliff:g id="NUMBER_2">%d</xliff:g>."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Вы няправільна ўвялі графічны ключ разблакавання пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. Пасля яшчэ некалькiх няўдалых спроб (<xliff:g id="NUMBER_1">%d</xliff:g>) вам будзе прапанавана разблакаваць тэлефон з дапамогай уваходу ў Google.\n\n Паўтарыце спробу праз наступную колькасць секунд: <xliff:g id="NUMBER_2">%d</xliff:g>."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Вы няправільна спрабавалі разблакаваць планшэт некалькi разоў (<xliff:g id="NUMBER_0">%d</xliff:g>). Пасля яшчэ некалькiх спробаў (<xliff:g id="NUMBER_1">%d</xliff:g>) ён будзе скінуты да заводскіх налад i карыстальнiцкiя дадзеныя будуць згубленыя."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Вы няправільна спрабавалі разблакаваць планшэт некалькi разоў (<xliff:g id="NUMBER_0">%d</xliff:g>). Пасля яшчэ некалькiх спробаў (<xliff:g id="NUMBER_1">%d</xliff:g>) ён будзе скінуты да заводскіх налад i карыстальнiцкiя дадзеныя будуць згубленыя."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Вы няправільна спрабавалі разблакаваць планшэт некалькi разоў (<xliff:g id="NUMBER">%d</xliff:g>). Цяпер ён будзе скінуты да заводскіх налад."</string>
@@ -826,7 +892,7 @@
     <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_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>
@@ -874,7 +940,7 @@
     <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"Вы ўпэўнены, што хочаце пакiнуць гэту старонку?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nВы ўпэўнены, што хочаце пакiнуць гэту старонку?"</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>
@@ -1080,14 +1146,14 @@
     <string name="aerr_application" msgid="932628488013092776">"На жаль, прыкладанне <xliff:g id="APPLICATION">%1$s</xliff:g> спынілася."</string>
     <string name="aerr_process" msgid="4507058997035697579">"На жаль, працэс <xliff:g id="PROCESS">%1$s</xliff:g> спыніўся."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"Прыкладанне <xliff:g id="APPLICATION">%2$s</xliff:g> не адказвае."\n\n"Закрыць яго?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Працэс <xliff:g id="ACTIVITY">%1$s</xliff:g> не адказвае."\n\n"Закрыць яго?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"Прыкладанне <xliff:g id="APPLICATION">%2$s</xliff:g> не адказвае.\n\nЗакрыць яго?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Працэс <xliff:g id="ACTIVITY">%1$s</xliff:g> не адказвае.\n\nЗакрыць яго?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"Прыкладанне <xliff:g id="APPLICATION">%1$s</xliff:g> не адказвае. Закрыць яго?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Працэс <xliff:g id="PROCESS">%1$s</xliff:g> не адказвае."\n\n"Закрыць яго?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Працэс <xliff:g id="PROCESS">%1$s</xliff:g> не адказвае.\n\nЗакрыць яго?"</string>
     <string name="force_close" msgid="8346072094521265605">"ОК"</string>
     <string name="report" msgid="4060218260984795706">"Справаздача"</string>
     <string name="wait" msgid="7147118217226317732">"Чакаць"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"Старонка не адказвае на запыты."\n\n"Закрыць яе?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Старонка не адказвае на запыты.\n\nЗакрыць яе?"</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>
@@ -1256,6 +1322,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Дазваляе прыкладанням выклікаць службу захавання па змаўчанні для капіявання змесціва. Не выкарыстоўваецца звычайнымі прыкладаннямі."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Маршрутны мультымедыйны выхад"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Дазваляе прыкладанням маршрутызаваць мультымедыйны выхад на iншыя знешнiя прылады."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Доступ да блакіроўкі клавіятуры бяспечнага сховішча"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Дазваляе прыкладанню атрымліваць доступ да блакіроўкі клавіятуры бяспечнага сховішча."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Кiраванне адлюстраваннем і схаваннем блакiроўкi клавіятуры"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Дазваляе прыкладанню кiраваць блакiроўкай клавiятуры."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Двойчы дакраніцеся, каб змянiць маштаб"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Немагчыма дадаць віджэт."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Пачаць"</string>
@@ -1265,15 +1335,15 @@
     <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">"Набраць нумар"\n"з выкарыстаннем <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Стварыць кантакт"\n"з дапамогай<xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Набраць нумар\nз выкарыстаннем <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Стварыць кантакт\nз дапамогай<xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Гэтыя адно або некалькі прыкладанняў запытваюць дазвол на доступ да вашага ўліковага запісу цяпер і ў будучыні."</string>
     <string name="grant_credentials_permission_message_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">"Запытаны дазвол"\n"для ўліковага запісу <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Запытаны дазвол\nдля ўліковага запісу <xliff:g id="ACCOUNT">%s</xliff:g>"</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>
@@ -1420,7 +1490,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Прагледзець усё"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Выберыце працэс"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Апублікаваць з дапамогай"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Прылада заблакаваная."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Адпраўка..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Запусцiць браўзер?"</string>
@@ -1441,10 +1510,14 @@
     <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>
+    <!-- no translation found for media_route_status_in_use (4533786031090198063) -->
+    <skip />
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Убудаваны экран"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"Экран HDMI"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Оверлей # <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> кр. на цалю"</string>
+    <!-- no translation found for display_manager_overlay_display_secure_suffix (6022119702628572080) -->
+    <skip />
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Падключаны бесправадны дысплей"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Гэты экран паказваецца на іншай прыладзе"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Адключыць"</string>
@@ -1453,7 +1526,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Няправільна ключ"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Няправiльны пароль"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"Няправільны PIN-код"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Паўтарыце спробу праз <xliff:g id="NUMBER">%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>
@@ -1473,27 +1546,137 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Пароль"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Увайсцi"</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_account_recovery_hint" msgid="5690709132841752974">"Забыліся на імя карыстальніка або пароль?\nНаведайце "<b>"google.com/accounts/recovery"</b></string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Праверка ўлiковага запiсу..."</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Вы няправільна ўвялі PIN-код пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n"Паўтарыце спробу праз <xliff:g id="NUMBER_1">%d</xliff:g> с."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Вы няправільна ўвялі пароль пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n"Паўтарыце спробу праз <xliff:g id="NUMBER_1">%d</xliff:g> с."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Вы няправільна ўвялі графічны ключ разблакiроўкi пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n"Паўтарыце спробу праз <xliff:g id="NUMBER_1">%d</xliff:g> с."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Вы няправільна ўвялі PIN-код пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. \n\nПаўтарыце спробу праз <xliff:g id="NUMBER_1">%d</xliff:g> с."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Вы няправільна ўвялі пароль пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. \n\nПаўтарыце спробу праз <xliff:g id="NUMBER_1">%d</xliff:g> с."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Вы няправільна ўвялі графічны ключ разблакiроўкi пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. \n\nПаўтарыце спробу праз <xliff:g id="NUMBER_1">%d</xliff:g> с."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Вы няправільна спрабавалі разблакiраваць планшэт некалькi разоў (<xliff:g id="NUMBER_0">%d</xliff:g>). Пасля яшчэ некалькiх спроб (<xliff:g id="NUMBER_1">%d</xliff:g>) ён будзе скінуты да заводскіх налад i карыстальнiцкiя дадзеныя будуць згубленыя."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Вы няправільна спрабавалі разблакiраваць планшэт некалькi разоў (<xliff:g id="NUMBER_0">%d</xliff:g>). Пасля яшчэ некалькiх спроб (<xliff:g id="NUMBER_1">%d</xliff:g>) ён будзе скінуты да завадскіх налад i карыстальнiцкiя дадзеныя будуць згубленыя."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Вы няправільна спрабавалі разблакiраваць планшэт некалькi разоў (<xliff:g id="NUMBER">%d</xliff:g>). Цяпер ён будзе скінуты да завадскіх налад."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Вы няправільна спрабавалі разблакiраваць тэлефон некалькi разоў (<xliff:g id="NUMBER">%d</xliff:g>). Цяпер ён будзе скінуты да завадскіх налад."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Вы няправільна ўвялі графічны ключ разблакiроўкi пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. Пасля яшчэ некалькiх няўдалых спроб (<xliff:g id="NUMBER_1">%d</xliff:g>) вам будзе прапанавана разблакiраваць тэлефон, увайшоўшы ў Google."\n\n" Паўтарыце спробу праз <xliff:g id="NUMBER_2">%d</xliff:g> с."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Вы няправільна ўвялі графічны ключ разблакiроўкi пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. Пасля яшчэ некалькiх няўдалых спроб (<xliff:g id="NUMBER_1">%d</xliff:g>) вам будзе прапанавана разблакiраваць тэлефон, увайшоўшы ў Google."\n\n" Паўтарыце спробу праз <xliff:g id="NUMBER_2">%d</xliff:g> с."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Вы няправільна ўвялі графічны ключ разблакiроўкi пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. Пасля яшчэ некалькiх няўдалых спроб (<xliff:g id="NUMBER_1">%d</xliff:g>) вам будзе прапанавана разблакiраваць тэлефон, увайшоўшы ў Google.\n\n Паўтарыце спробу праз <xliff:g id="NUMBER_2">%d</xliff:g> с."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Вы няправільна ўвялі графічны ключ разблакiроўкi пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. Пасля яшчэ некалькiх няўдалых спроб (<xliff:g id="NUMBER_1">%d</xliff:g>) вам будзе прапанавана разблакiраваць тэлефон, увайшоўшы ў Google.\n\n Паўтарыце спробу праз <xliff:g id="NUMBER_2">%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">"Выдалiць"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Павялiчыць гук больш за рэкамендаваны ўзровень?"\n"Доўгае слуханне музыкi на вялiкай гучнасцi можа пашкодзiць ваш слых."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Павялiчыць гук больш за рэкамендаваны ўзровень?\nДоўгае слуханне музыкi на вялiкай гучнасцi можа пашкодзiць ваш слых."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Утрымлiвайце два пальцы, каб уключыць доступ."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Даступнасць уключана."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Даступнасць адменена."</string>
     <string name="user_switched" msgid="3768006783166984410">"Бягучы карыстальнік <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="app_no_restricted_accounts" msgid="4011285085817350390">"Гэтае прыкладанне не падтрымлівае уліковыя запісы для карыстальнікаў з абмежаваннямi"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Гэта прыкладанне не падтрымлівае ўліковыя запісы для профiляў з абмежаваннямі"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Прыкладанне для гэтага дзеяння не знойдзенае"</string>
     <string name="revoke" msgid="5404479185228271586">"Ануляваць"</string>
+    <!-- no translation found for mediaSize_iso_a0 (7875427489420821793) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_a1 (3760734499050875356) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_a2 (5973266378020144382) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_a3 (1373407105687300884) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_a4 (6689772807982597254) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_a5 (5353549652015741040) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_a6 (8585038048674911907) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_a7 (6641836716963839119) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_a8 (7571139437465693355) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_a9 (1378455891957115079) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_a10 (2480747457429475344) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_b0 (3965935097661108039) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_b1 (2505753285010115437) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_b2 (8763874709859458453) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_b3 (4210506688191764076) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_b4 (5749404165888526034) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_b5 (7640627414621904733) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_b6 (7342988864712748544) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_b7 (5069844065235382429) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_b8 (7316818922278779774) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_b9 (5414727094026532341) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_b10 (5251253731832048185) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_c0 (4003138342671964217) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_c1 (1935188063393553008) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_c2 (3197307969712069904) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_c3 (4335826087321913508) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_c4 (3745639598281015005) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_c5 (8269457765822791013) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_c6 (566666105260346930) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_c7 (8678413180782608498) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_c8 (8392376206627041730) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_c9 (9191613372324845405) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_c10 (7327709699184920822) -->
+    <skip />
+    <!-- no translation found for mediaSize_na_letter (4191805615829472953) -->
+    <skip />
+    <!-- no translation found for mediaSize_na_gvrnmt_letter (7853382192649405507) -->
+    <skip />
+    <!-- no translation found for mediaSize_na_legal (6697982988283823150) -->
+    <skip />
+    <!-- no translation found for mediaSize_na_junior_legal (3727743969902758948) -->
+    <skip />
+    <!-- no translation found for mediaSize_na_ledger (281871464896601236) -->
+    <skip />
+    <!-- no translation found for mediaSize_na_tabloid (5775966416333578127) -->
+    <skip />
+    <!-- no translation found for write_fail_reason_cancelled (7091258378121627624) -->
+    <skip />
+    <!-- no translation found for write_fail_reason_cannot_write (8132505417935337724) -->
+    <skip />
+    <!-- no translation found for reason_unknown (6048913880184628119) -->
+    <skip />
+    <!-- no translation found for restr_pin_enter_admin_pin (783643731895143970) -->
+    <skip />
+    <!-- no translation found for restr_pin_enter_pin (3395953421368476103) -->
+    <skip />
+    <!-- no translation found for restr_pin_incorrect (8571512003955077924) -->
+    <skip />
+    <!-- no translation found for restr_pin_enter_old_pin (1462206225512910757) -->
+    <skip />
+    <!-- no translation found for restr_pin_enter_new_pin (5959606691619959184) -->
+    <skip />
+    <!-- no translation found for restr_pin_confirm_pin (8501523829633146239) -->
+    <skip />
+    <!-- no translation found for restr_pin_create_pin (8017600000263450337) -->
+    <skip />
+    <!-- no translation found for restr_pin_error_doesnt_match (2224214190906994548) -->
+    <skip />
+    <!-- no translation found for restr_pin_error_too_short (8173982756265777792) -->
+    <skip />
+    <!-- no translation found for restr_pin_countdown:one (311050995198548675) -->
+    <!-- no translation found for restr_pin_countdown:other (4730868920742952817) -->
+    <!-- no translation found for restr_pin_try_later (973144472490532377) -->
+    <skip />
+    <!-- no translation found for transient_navigation_confirmation (4907844043611123426) -->
+    <skip />
+    <!-- no translation found for transient_navigation_confirmation_long (8061685920508086697) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 76cab7a..f492ff5 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -131,6 +131,11 @@
     <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="default" msgid="3475999286680000541">"Хранилището на телефона е пълно. Изтрийте файлове, за да освободите място."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Мрежата може да се наблюдава"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Аз"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Опции за таблета"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Опции на телефона"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Разрешава на приложението да прехвърля задачи на преден и на заден план. То може да направи това без вашето потвърждение."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"спиране на изпълняваните приложения"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Разрешава на приложението да премахва задачи и да прекратява приложенията им. Злонамерените приложения могат да нарушат поведението на други приложения."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"управление на стековете за активност"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Разрешава на приложението да добавя, премахва и променя стековете за активност, в които се изпълняват другите приложения. Работата им може да бъде нарушена от злонамерени приложения."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"започване на дейности"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Разрешава на приложението да започва дейности независимо от защитата на базата на разрешения или състоянието при експортиране."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"задаване на съвместимост на екрана"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Разрешава на притежателя да се обвърже с интерфейса от най-високото ниво на метод на въвеждане. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"обвързване с услуга за достъпност"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Разрешава на притежателя да се обвърже с интерфейса от най-високото ниво на услуга за достъпност. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"обвързване с услуга за отпечатване"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Разрешава на притежателя да се обвърже с интерфейса от най-високото ниво на услуга за отпечатване. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"обвързване с услуга за спулер за отпечатване"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Разрешава на притежателя да се обвърже с интерфейса от най-високото ниво на услуга за спулер за отпечатване. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"обвързване с услуга за КБП"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Разрешава на притежателя да се обвързва с приложения, които емулират карти за КБП. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"обвързване с текстова услуга"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Разрешава на притежателя да се обвърже с интерфейса от най-високото ниво на текстова услуга (напр. SpellCheckerService). Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"обвързване с услуга за VPN"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Разрешава на притежателя да се обвърже с интерфейса от най-високото ниво на услуга за приспособления. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"взаимодействие с администратор на устройството"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Разрешава на притежателя да изпраща намерения до администратор на устройството. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"добавяне или премахване на администратор на устройства"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Разрешава на притежателя да добавя или премахва администратори на активни устройства. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"промяна на ориентацията на екрана"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Разрешава на приложението да променя ориентацията на екрана по всяко време. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"промяна на скоростта на курсор"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Разрешава на приложението да чете от различните регистрационни файлове на системата. Това му позволява да получи обща информация какво правите с телефона, потенциално включително и лични или поверителни данни."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"използване на всеки медиен декодер за възпроизвеждане"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Разрешава на приложението да използва всеки инсталиран медиен декодер с цел декодиране за възпроизвеждане."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"управление на надеждните идентификационни данни"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Разрешава на приложението да инсталира и деинсталира сертификати от сертифициращи органи като надеждни идентификационни данни."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"четене/запис в ресурси, притежавани от diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Разрешава на приложението да чете и записва във всеки ресурс, притежаван от групата diag, например файловете в /dev. Това потенциално може да засегне стабилността и сигурността на системата. То трябва да се използва САМО за диагностика, конкретно за хардуера, от страна на производителя или оператора."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"активиране или деактивиране на компоненти на приложенията"</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Разрешава на приложението да конфигурира и да се свързва с дисплеите през WiFi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"контролиране на дисплеите през WiFi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Разрешава на приложението да контролира функциите от ниско ниво на дисплеите през WiFi."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"записване на възпроизвеждания звук"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Разрешава на приложението да записва и пренасочва възпроизвеждания звук."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"записване на възпроизвеждания образ"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Разрешава на приложението да записва и пренасочва възпроизвеждания образ."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"записване на защитеното възпроизвеждане на образ"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Разрешава на приложението да записва и пренасочва защитеното възпроизвеждане на образ."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"промяна на настройките ви за звука"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Разрешава на приложението да променя глобалните настройки за звука, като например силата и това, кой високоговорител се използва за изход."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"запис на звук"</string>
@@ -525,6 +552,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"предотвратява спящ режим на телефона"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Разрешава на приложението да предотвратява преминаването на таблета в спящ режим."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Разрешава на приложението да предотвратява преминаването на телефона в спящ режим."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"включване или изключване на таблета"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"включване или изключване на телефона"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Разрешава на приложението да включва или изключва таблета."</string>
@@ -613,6 +646,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Разрешава на приложението да записва върху SD картата."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"пром./изтр. на съдърж. на вътр. мултим. хранил."</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Разрешава на приложението да променя съдържанието на вътрешното мултимедийно хранилище."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"управл. на хранил. с документи"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Разрешава на приложението да управлява хранилището с документи."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"достъп до външ. хранилище за всички потребители"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Разрешава на приложението достъп до външното хранилище за всички потребители."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"достъп до файловата система на кеша"</string>
@@ -625,10 +660,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Разрешава на приложението да управлява правилата на мрежата и да определя такива за конкретно приложение."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"промяна на отчетността на употребата на мрежа"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Разрешава на приложението да променя това как употребата на мрежа се отчита спрямо приложенията. Не е предназначено за нормални приложения."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"промяна на означенията на сокетите"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Разрешава на приложението да променя означенията на сокетите за маршрутизиране."</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_invokeCarrierSetup" msgid="3699600833975117478">"извикване на предоставеното от оператора приложение за конфигуриране"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Разрешава на притежателя да извиква предоставеното от оператора приложение за конфигуриране. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"слушане за наблюдения на мрежовите условия"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Разрешава на приложението да слуша за наблюдения на мрежовите условия. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Задаване на правила за паролата"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролирайте дължината и разрешените знаци за паролите за отключване на екрана."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Наблюдаване на опитите за отключване на екрана"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +836,7 @@
     <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"Свържете се с оператора на безжичната си връзка, за да получите друга."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"SIM картата ви е деактивирана за постоянно.\nСвържете се с оператора на безжичната си връзка, за да получите друга."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Бутон за предишния запис"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Бутон за следващия запис"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Бутон за пауза"</string>
@@ -808,11 +848,11 @@
     <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">%d</xliff:g> пъти. "\n\n"Опитайте отново след <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Въведохте неправилно паролата си <xliff:g id="NUMBER_0">%d</xliff:g> пъти. "\n\n"Опитайте отново след <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Въведохте неправилно ПИН кода си <xliff:g id="NUMBER_0">%d</xliff:g> пъти. "\n\n"Опитайте отново след <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдете помолени да отключите таблета посредством данните си за вход в Google."\n\n"Опитайте отново след <xliff:g id="NUMBER_2">%d</xliff:g> секунди."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдете помолени да отключите телефона посредством данните си за вход в Google."\n\n" Опитайте отново след <xliff:g id="NUMBER_2">%d</xliff:g> секунди."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%d</xliff:g> пъти. \n\nОпитайте отново след <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Въведохте неправилно паролата си <xliff:g id="NUMBER_0">%d</xliff:g> пъти. \n\nОпитайте отново след <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Въведохте неправилно ПИН кода си <xliff:g id="NUMBER_0">%d</xliff:g> пъти. \n\nОпитайте отново след <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдете помолени да отключите таблета посредством данните си за вход в Google.\n\nОпитайте отново след <xliff:g id="NUMBER_2">%d</xliff:g> секунди."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдете помолени да отключите телефона посредством данните си за вход в Google.\n\n Опитайте отново след <xliff:g id="NUMBER_2">%d</xliff:g> секунди."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Направихте опит да отключите таблета неправилно <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдат възстановени стандартните му фабрични настройки и всички потребителски данни ще бъдат заличени."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Направихте опит да отключите телефона неправилно <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдат възстановени стандартните му фабрични настройки и всички потребителски данни ще бъдат заличени."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Направихте опит да отключите таблета неправилно <xliff:g id="NUMBER">%d</xliff:g> пъти. Сега ще бъдат възстановени стандартните му фабрични настройки."</string>
@@ -826,7 +866,7 @@
     <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_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>
@@ -874,7 +914,7 @@
     <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="autofill_this_form" msgid="4616758841157816676">"Автопоп."</string>
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"За съжаление <xliff:g id="APPLICATION">%1$s</xliff:g> спря."</string>
     <string name="aerr_process" msgid="4507058997035697579">"За съжаление процесът <xliff:g id="PROCESS">%1$s</xliff:g> спря."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"Приложението „<xliff:g id="APPLICATION">%2$s</xliff:g>“ не отговаря."\n\n"Искате ли да го затворите?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Дейността „<xliff:g id="ACTIVITY">%1$s</xliff:g>“ не отговаря."\n\n"Искате ли да я затворите?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"Приложението „<xliff:g id="APPLICATION">%2$s</xliff:g>“ не отговаря.\n\nИскате ли да го затворите?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Дейността „<xliff:g id="ACTIVITY">%1$s</xliff:g>“ не отговаря.\n\nИскате ли да я затворите?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"Приложението „<xliff:g id="APPLICATION">%1$s</xliff:g>“ не отговаря. Искате ли да го затворите?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Процесът „<xliff:g id="PROCESS">%1$s</xliff:g>“ не отговаря."\n\n"Искате ли да го затворите?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Процесът „<xliff:g id="PROCESS">%1$s</xliff:g>“ не отговаря.\n\nИскате ли да го затворите?"</string>
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"Подаване на сигнал"</string>
     <string name="wait" msgid="7147118217226317732">"Изчакване"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"Страницата не отговаря."\n\n"Искате ли да я затворите?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Страницата не отговаря.\n\nИскате ли да я затворите?"</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>
@@ -1256,6 +1296,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Разрешава на приложението да извиква стандартната услуга на контейнера, за да се копира съдържание. Не е предназначено за нормални приложения."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Насочване на изходящата мултимедия"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Разрешава на приложението да насочва изходящата мултимедия към други външни устройства."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Достъп до надеждното хранилище, свързано с функцията за защита на клавишите"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Позволява на приложението да осъществява достъп до надеждното хранилище, свързано с функцията за защита на клавишите."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Контролиране на показването и скриването на функцията за защита на клавишите"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Разрешава на приложението да контролира функцията за защита на клавишите."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Докоснете двукратно за управление на промяната на мащаба"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Приспособлението не можа да бъде добавено."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Старт"</string>
@@ -1265,15 +1309,15 @@
     <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">"Набиране"\n"с използване на <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Създаване на контакт"\n"с използване на <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Набиране\nс използване на <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Създаване на контакт\nс използване на <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Следните едно или повече приложения искат разрешение за достъп до профила ви сега и в бъдеще."</string>
     <string name="grant_credentials_permission_message_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">"Иска се разрешение"\n"за профила <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Иска се разрешение\nза профила <xliff:g id="ACCOUNT">%s</xliff:g>."</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>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Вижте всички"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Избор на активност"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Споделяне със:"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Устройството е заключено."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Изпраща се..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Да се стартира ли браузърът?"</string>
@@ -1441,10 +1484,12 @@
     <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>
+    <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_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="wifi_display_notification_title" msgid="2223050649240326557">"Безжичният дисплей е свързан"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Този екран се показва на друго устройство"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Прекратяване на връзката"</string>
@@ -1453,7 +1498,7 @@
     <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_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Опитайте отново след <xliff:g id="NUMBER">%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">"Въведете ПИН кода за SIM картата"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Въведете ПИН код"</string>
@@ -1473,27 +1518,85 @@
     <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_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">%d</xliff:g> пъти. "\n\n"Опитайте отново след <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Въведохте неправилно паролата си <xliff:g id="NUMBER_0">%d</xliff:g> пъти. "\n\n"Опитайте отново след <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%d</xliff:g> пъти. "\n\n"Опитайте отново след <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Въведохте неправилно ПИН кода си <xliff:g id="NUMBER_0">%d</xliff:g> пъти. \n\nОпитайте отново след <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Въведохте неправилно паролата си <xliff:g id="NUMBER_0">%d</xliff:g> пъти. \n\nОпитайте отново след <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%d</xliff:g> пъти. \n\nОпитайте отново след <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Направихте опит да отключите неправилно таблета <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдат възстановени стандартните му фабрични настройки и всички потребителски данни ще бъдат заличени."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Направихте опит да отключите неправилно телефона <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдете помолени да отключите таблета посредством имейл адрес."\n\n" Опитайте отново след <xliff:g id="NUMBER_2">%d</xliff:g> секунди."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдете помолени да отключите телефона посредством имейл адрес."\n\n" Опитайте отново след <xliff:g id="NUMBER_2">%d</xliff:g> секунди."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдете помолени да отключите таблета посредством имейл адрес.\n\n Опитайте отново след <xliff:g id="NUMBER_2">%d</xliff:g> секунди."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдете помолени да отключите телефона посредством имейл адрес.\n\n Опитайте отново след <xliff:g id="NUMBER_2">%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="7324161939475478066">"Да се увеличи ли силата на звука над препоръчаното ниво?"\n"Продължителното слушане при висока сила на звука може да увреди слуха ви."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Да се увеличи ли силата на звука над препоръчаното ниво?\nПродължителното слушане при висока сила на звука може да увреди слуха ви."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Продължете да натискате с два пръста, за да активирате функцията за достъпност."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Достъпността е активирана."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Функцията за достъпност е анулирана."</string>
     <string name="user_switched" msgid="3768006783166984410">"Текущ потребител <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="app_no_restricted_accounts" msgid="4011285085817350390">"Това приложение не поддържа профили за потребителски профили с ограничена функционалност"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Това приложение не поддържа профили за потребителски профили с ограничена функционалност"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Няма намерено приложение за извършване на това действие"</string>
     <string name="revoke" msgid="5404479185228271586">"Отмяна"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Анулирано"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Грешка при записване на съдържанието"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"неизвестно"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Въведете ПИН кода на администратор"</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>
+    <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">"Създаване на ПИН код за промяна на ограниченията"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"ПИН кодовете не са идентични. Опитайте отново."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"ПИН кодът е твърде кратък. Трябва да е поне 4 цифри."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Опитайте отново след 1 секунда"</item>
+    <item quantity="other" msgid="4730868920742952817">"Опитайте отново след <xliff:g id="COUNT">%d</xliff:g> секунди"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Опитайте отново по-късно"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"За показв. на лентата прек. пръст по ръба на екрана"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Прекарайте пръст от ръба на екрана, за да се покаже системната лента"</string>
 </resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 8c82e3a..6ea3299 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -131,6 +131,11 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Massa supressions de <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"L\'emmagatzematge de la tauleta és ple. Suprimeix uns quants fitxers per alliberar espai."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"L\'emmagatzematge del telèfon és ple. Suprimeix uns quants fitxers per alliberar espai."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Pot ser que la xarxa se supervisi."</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Mi"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opcions de la tauleta"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Opcions del telèfon"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Permet que l\'aplicació desplaci tasques en primer o segon pla. L\'aplicació pot fer-ho sense que tu ho indiquis."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"atura les aplicacions que s\'estan executant"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Permet que l\'aplicació elimini tasques i finalitzi les seves aplicacions. Les aplicacions malicioses poden alterar el comportament d\'altres aplicacions."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"gestiona les piles d\'activitats"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Permet que l\'aplicació, afegeixi, suprimeixi i modifiqui les piles d\'activitats on s\'executen altres aplicacions. És possible que les aplicacions malicioses interrompin el comportament d\'altres aplicacions."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"iniciar qualsevol activitat"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Permet que l\'aplicació iniciï qualsevol activitat, amb independència de la protecció del permís o de l\'estat exportat."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"definició de la compatibilitat de pantalla"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Permet que el titular vinculi a la interfície de nivell superior d\'un mètode d\'entrada. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"vincular amb un servei d\'accessibilitat"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permet vincular amb la interfície de nivell superior d\'un servei d\'accessibilitat. Les aplicacions normals no haurien de necessitar-ho."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"vincula amb un servei d\'impressió"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Permet que el titular vinculi a la interfície de nivell superior d\'un servei d\'impressió. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"vincula amb un servei de gestor de cues d\'impressió"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Permet que el titular vinculi a la interfície de nivell superior d\'un servei de gestor de cues d\'impressió. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"vincula al servei NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Permet que el titular es vinculi a les aplicacions que emulen les targetes de NFC. No hauria de ser mai necessari per a les aplicacions normals."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"vincula a un servei de text"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Permet al titular vincular amb la interfície de nivell superior d\'un servei de text (per exemple, SpellCheckerService). Les aplicacions normals mai no ho haurien de necessitar."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"vincula a un servei de VPN"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Permet que el titular vinculi a la interfície de nivell superior d\'un servei de widget. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interactuar amb un administrador del dispositiu"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Permet que el titular enviï intents a un administrador del sistema. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"afegeix un administrador al dispositiu o suprimeix-lo"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Permet que el titular afegeixi administradors actius al dispositiu o en suprimeixi. No s\'hauria de necessitar per a les aplicacions normals."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"canviar l\'orientació de la pantalla"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Permet que l\'aplicació canviï el gir de la pantalla en qualsevol moment. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"canvi de velocitat del punter"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Permet que l\'aplicació llegeixi els diversos fitxers de registre del sistema. Això li permet descobrir informació general sobre què estàs fent amb el telèfon i, potencialment, pot incloure informació personal o privada."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"utilitza qualsevol descodificador de mitjans per a la reproducció"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Permet que l\'aplicació utilitzi qualsevol descodificador de mitjans instal·lat per descodificar per a la reproducció."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"gestiona les credencials de confiança"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Permet que l\'aplicació instal·li i desinstal·li certificats de CA com a credencials de confiança."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"llegir/escriure recursos propietat de diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permet que l\'aplicació llegeixi i escrigui a qualsevol recurs propietat del grup diag; per exemple, els fitxers de /dev. Això podria afectar l\'estabilitat i la seguretat del sistema. NOMÉS l\'hauria d\'utilitzar el fabricant o l\'operador per a diagnòstics específics de maquinari."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"activa o desactiva els components de l\'aplicació"</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permet a l\'aplicació configurar-se i connectar-se a les pantalles Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"control de les pantalles Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Permet a l\'aplicació controlar les funcions de baix nivell de les pantalles Wi-Fi."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"captura la sortida d\'àudio"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Permet que l\'aplicació capturi i redirigeixi la sortida d\'àudio."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"captura la sortida de vídeo"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Permet que l\'aplicació capturi i redirigeixi la sortida de vídeo."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"captura la sortida de vídeo segur"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Permet que l\'aplicació capturi i redirigeixi la sortida de vídeo segur."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"canviar la configuració d\'àudio"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Permet que l\'aplicació modifiqui la configuració d\'àudio general, com ara el volum i l\'altaveu de sortida que es fa servir."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"enregistrar àudio"</string>
@@ -512,19 +539,25 @@
     <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"iniciar directament la configuració del telèfon CDMA"</string>
     <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"Permet que l\'aplicació iniciï l\'aprovisionament CDMA. Les aplicacions malicioses poden iniciar l\'aprovisionament CDMA innecessàriament."</string>
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"controlar les notificacions d\'actualització de la ubicació"</string>
-    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Permet que l\'aplicació activi i desactivi les notificacions d\'actualització de la ubicació de la ràdio. No la poden fer servir les aplicacions normals."</string>
+    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Permet que l\'aplicació activi i desactivi les notificacions d\'actualització de la ubicació del senyal mòbil. No la poden fer servir les aplicacions normals."</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"accedir a les propietats d\'accés"</string>
     <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Permet a l\'aplicació l\'accés de lectura/escriptura a les propietats penjades pel servei de registre. No es pot fer servir per a les aplicacions normals."</string>
     <string name="permlab_bindGadget" msgid="776905339015863471">"triar widgets"</string>
     <string name="permdesc_bindGadget" msgid="8261326938599049290">"Permet que l\'aplicació indiqui al sistema quins widgets pot utilitzar cada aplicació. Amb aquest permís, les aplicacions poden concedir accés a les dades personals a altres aplicacions. No indicat per a les aplicacions normals."</string>
     <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"modificar l\'estat del telèfon"</string>
-    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Permet que l\'aplicació controli les funcions de telèfon del dispositiu. Una aplicació amb aquest permís pot canviar de xarxa, activar i desactivar la ràdio del telèfon i dur a terme accions semblants sense notificar-t\'ho."</string>
+    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Permet que l\'aplicació controli les funcions de telèfon del dispositiu. Una aplicació amb aquest permís pot canviar de xarxa, activar i desactivar el senyal mòbil i dur a terme accions semblants sense notificar-t\'ho."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"veure l\'estat i la identitat del telèfon"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permet que l\'aplicació accedeixi a les funcions de telèfon del dispositiu. Aquest permís permet que l\'aplicació determini el número de telèfon i els identificadors del dispositiu, si hi ha una trucada activa i el número remot connectat amb una trucada."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"evita que la tauleta entri en mode d\'inactivitat"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"impedir que el telèfon entri en mode de repòs"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Permet que l\'aplicació impedeixi que la tauleta entri en repòs."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Permet que l\'aplicació impedeixi que el telèfon entri en repòs."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"activa o desactiva la tauleta"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"engegar o apagar el telèfon"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Permet que l\'aplicació encengui i apagui la tauleta."</string>
@@ -575,14 +608,14 @@
     <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Permet que l\'aplicació rebi paquets enviats a tots els dispositius d\'una xarxa Wi-Fi mitjançant les adreces multidifusió, no només a la teva tauleta. Fa servir més energia que el mode que no és multidifusió."</string>
     <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Permet que l\'aplicació rebi paquets enviats a tots els dispositius d\'una xarxa Wi-Fi mitjançant les adreces multidifusió, no només al teu telèfon. Fa servir més energia que el mode que no és multidifusió."</string>
     <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"accés a la configuració de Bluetooth"</string>
-    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Permet que l\'aplicació configuri la tauleta Bluetooth local i que cerqui i sincronitzi dispositius remots."</string>
-    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Permet que l\'aplicació configuri el telèfon Bluetooth local i que cerqui i sincronitzi dispositius remots."</string>
+    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Permet que l\'aplicació configuri la tauleta Bluetooth local i que detecti i emparelli dispositius remots."</string>
+    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Permet que l\'aplicació configuri el telèfon Bluetooth local i que detecti i emparelli dispositius remots."</string>
     <string name="permlab_accessWimaxState" msgid="4195907010610205703">"connecta i desconnecta de WiMAX"</string>
     <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"Permet que l\'aplicació determini si WiMAX està activat i que vegi la informació sobre totes les xarxes WiMAX que estan connectades."</string>
     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Canvia l\'estat de WiMAX"</string>
     <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Permet que l\'aplicació connecti i desconnecti la tauleta de les xarxes WiMAX."</string>
     <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"Permet que l\'aplicació connecti i desconnecti el telèfon de les xarxes WiMAX."</string>
-    <string name="permlab_bluetooth" msgid="6127769336339276828">"sincronització amb dispositius Bluetooth"</string>
+    <string name="permlab_bluetooth" msgid="6127769336339276828">"emparella amb dispositius Bluetooth"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Permet que l\'aplicació visualitzi la configuració de Bluetooth de la tauleta i que estableixi i accepti connexions amb dispositius sincronitzats."</string>
     <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Permet que una aplicació visualitzi la configuració de Bluetooth del telèfon i que estableixi i accepti connexions amb els dispositius sincronitzats."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"controla Near Field Communication (NFC)"</string>
@@ -613,6 +646,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Permet a l\'aplicació escriure a la targeta SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"Canvia/esborra emmagatz. intern"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Permet que l\'aplicació modifiqui el contingut de l\'emmagatzematge multimèdia intern."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"gestió emmagatzematge docum."</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Permet que l\'aplicació gestioni l\'emmagatzematge de documents."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"accedeix a l\'emmagatzematge extern per a tots els usuaris"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Permet que l\'aplicació accedeixi a l\'emmagatzematge extern per a tots els usuaris."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"accedir al sistema de fitxers de la memòria cau"</string>
@@ -625,10 +660,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Permet que l\'aplicació gestioni les polítiques de la xarxa i que defineixi les regles específiques d\'aplicació."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"modificació del càlcul d\'ús de la xarxa"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Permet que l\'aplicació modifiqui la manera com es calcula l\'ús de la xarxa per part de les aplicacions. No indicat per a les aplicacions normals."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"modifica les marques dels sòcols"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Permet que l\'aplicació modifiqui les marques de sòcols per a l\'encaminament"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"accedeix a les notificacions"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Permet que l\'aplicació recuperi, examini i esborri les notificacions, incloses les que han publicat altres aplicacions."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"vincula a un servei de processament de notificacions"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Permet que el titular vinculi la interfície de nivell superior d\'un servei de processament de notificacions. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"invoca l\'aplicació de configuració proporcionada per l\'operador"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Permet que el titular invoqui l\'aplicació de configuració proporcionada per l\'operador. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"conèixer les observacions sobre les condicions de la xarxa"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permet que una aplicació conegui les observacions sobre les condicions de la xarxa. No s\'ha de necessitar mai per a aplicacions normals."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Defineix les normes de contrasenya"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controla la longitud i els caràcters permesos a les contrasenyes de desbloqueig de pantalla."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Control d\'intents de desbloqueig de pantalla"</string>
@@ -708,7 +749,7 @@
     <string name="phoneTypeIsdn" msgid="8022453193171370337">"XDSI"</string>
     <string name="phoneTypeMain" msgid="6766137010628326916">"Principal"</string>
     <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Altres faxos"</string>
-    <string name="phoneTypeRadio" msgid="4093738079908667513">"Ràdio"</string>
+    <string name="phoneTypeRadio" msgid="4093738079908667513">"Senyal mòbil"</string>
     <string name="phoneTypeTelex" msgid="3367879952476250512">"Tèlex"</string>
     <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY TDD"</string>
     <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Mòbil de la feina"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +836,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Insereix una targeta SIM."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Falta la targeta SIM o no es pot llegir. Insereix-ne una."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Targeta SIM no utilitzable."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"La targeta SIM està desactivada permanentment."\n" Contacta amb el teu proveïdor de serveis sense fil per obtenir-ne una altra."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"La targeta SIM està desactivada permanentment.\n Contacta amb el teu proveïdor de serveis sense fil per obtenir-ne una altra."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Botó de pista anterior"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Botó de pista següent"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Botó de pausa"</string>
@@ -808,11 +848,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Consulta la guia de l\'usuari o posa\'t en contacte amb el servei d\'atenció al client."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"La targeta SIM està bloquejada."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"S\'està desbloquejant la targeta SIM..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Has dibuixat el patró de desbloqueig de manera incorrecta <xliff:g id="NUMBER_0">%d</xliff:g> vegades. "\n\n"Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Has escrit malament la contrasenya <xliff:g id="NUMBER_0">%d</xliff:g> vegades. "\n\n"Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Has escrit malament la contrasenya <xliff:g id="NUMBER_0">%d</xliff:g> vegades. "\n\n"Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Després de <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, se\'t demanarà que desbloquegis la tauleta amb l\'inici de sessió de Google."\n\n" Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Després de <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, se\'t demanarà que desbloquegis el telèfon amb l\'inici de sessió de Google."\n\n" Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Has dibuixat el patró de desbloqueig de manera incorrecta <xliff:g id="NUMBER_0">%d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Has escrit malament la contrasenya <xliff:g id="NUMBER_0">%d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Has escrit malament la contrasenya <xliff:g id="NUMBER_0">%d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Després de <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, se\'t demanarà que desbloquegis la tauleta amb l\'inici de sessió de Google.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Després de <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, se\'t demanarà que desbloquegis el telèfon amb l\'inici de sessió de Google.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER_0">%d</xliff:g> vegades incorrectament. D\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, la tauleta es restablirà a la configuració predeterminada de fàbrica i es perdran totes les dades dels usuaris."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER_0">%d</xliff:g> vegades incorrectament. D\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, la tauleta es restablirà a la configuració predeterminada de fàbrica i es perdran totes les dades dels usuaris."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER">%d</xliff:g> vegades incorrectament. Ara la tauleta es restablirà a la configuració predeterminada de fàbrica."</string>
@@ -826,7 +866,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Contrasenya"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Inicia la sessió"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nom d\'usuari o contrasenya no vàlids."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Has oblidat el teu nom d\'usuari o la contrasenya?"\n"Visita "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Has oblidat el teu nom d\'usuari o la contrasenya?\nVisita "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"S\'està comprovant..."</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Desbloqueja"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"So activat"</string>
@@ -874,7 +914,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Confirmació de la navegació"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Surt d\'aquesta pàgina"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Queda\'t en aquesta pàgina"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Estàs segur que vols sortir d\'aquesta pàgina?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nEstàs segur que vols sortir d\'aquesta pàgina?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Confirma"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Consell: Pica dos cops per ampliar i per reduir."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Em. aut."</string>
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"<xliff:g id="APPLICATION">%1$s</xliff:g> s\'ha aturat."</string>
     <string name="aerr_process" msgid="4507058997035697579">"El procés <xliff:g id="PROCESS">%1$s</xliff:g> s\'ha aturat."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> no respon."\n\n"Vols tancar-la?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"L\'activitat <xliff:g id="ACTIVITY">%1$s</xliff:g> no respon."\n\n"Vols tancar-la?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> no respon.\n\nVols tancar-la?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"L\'activitat <xliff:g id="ACTIVITY">%1$s</xliff:g> no respon.\n\nVols tancar-la?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> no respon. Vols tancar-la?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"El procés <xliff:g id="PROCESS">%1$s</xliff:g> no respon."\n\n"Vols tancar-lo?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"El procés <xliff:g id="PROCESS">%1$s</xliff:g> no respon.\n\nVols tancar-lo?"</string>
     <string name="force_close" msgid="8346072094521265605">"D\'acord"</string>
     <string name="report" msgid="4060218260984795706">"Informe"</string>
     <string name="wait" msgid="7147118217226317732">"Espera"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"La pàgina ha deixat de respondre."\n\n"Vols tancar-la?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"La pàgina ha deixat de respondre.\n\nVols tancar-la?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Aplicació redirigida"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> s\'està executant."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> es va iniciar originalment."</string>
@@ -1256,6 +1296,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Permet invocar el servei de contenidor predeterminat per copiar contingut. No indicat per a les aplicacions normals."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Indicació de ruta de sortida de contingut multimèdia"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Permet que una aplicació indiqui la ruta de sortida de contingut multimèdia a altres dispositius externs."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Accedeix a l\'emmagatzematge protegit per contrasenya"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Permet que una aplicació accedeixi a l\'emmagatzematge protegit per contrasenya."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Controla si es mostra o s\'amaga el bloqueig de les tecles."</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Permet que una aplicació controli el bloqueig de les tecles."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Toca dos cops per controlar el zoom"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"No s\'ha pogut afegir el widget."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Vés"</string>
@@ -1265,15 +1309,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Fet"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Anterior"</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Executa"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Marca el número"\n"mitjançant <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Crea un contacte"\n"mitjançant <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Marca el número\nmitjançant <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Crea un contacte\nmitjançant <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Les aplicacions següents sol·liciten permís per accedir al teu compte, ara i en el futur."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Voleu permetre aquesta sol·licitud?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Sol·licitud d\'accés"</string>
     <string name="allow" msgid="7225948811296386551">"Permet"</string>
     <string name="deny" msgid="2081879885755434506">"Denega"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Permís sol·licitat"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"S\'ha sol·licitat permís"\n"per al compte <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"S\'ha sol·licitat permís\nper al compte <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Mètode d\'introducció de text"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Sincronització"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Accessibilitat"</string>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Mostra-les totes"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Selecció de l\'activitat"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Comparteix amb"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Dispositiu bloquejat."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"S\'està enviant…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Vols iniciar el navegador?"</string>
@@ -1430,7 +1473,7 @@
     <string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"Tauleta"</string>
     <string name="default_audio_route_name" product="default" msgid="4239291273420140123">"Telèfon"</string>
     <string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Auriculars"</string>
-    <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Altaveus del connector"</string>
+    <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Altaveus de la base"</string>
     <string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistema"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Àudio per Bluetooth"</string>
@@ -1441,10 +1484,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"S\'està connectant..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Disponible"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"No disponible"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"En ús"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Pantalla integrada"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"Pantalla HDMI"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Superposa #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", segur"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"La pantalla sense fil està connectada"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Aquesta pantalla es mostra en un altre dispositiu"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Desconnecta"</string>
@@ -1453,7 +1498,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Patró incorrecte"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Contrasenya incorrecta"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN incorrecte"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Torna-ho a provar d\'aquí a <xliff:g id="NUMBER">%d</xliff:g> segons."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Torna-ho a provar d\'aquí a <xliff:g id="NUMBER">%1$d</xliff:g> segons."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Dibuixa el patró"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Introdueix el PIN de la SIM"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Introdueix el PIN"</string>
@@ -1473,27 +1518,85 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Contrasenya"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Inicia la sessió"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nom d\'usuari o contrasenya no vàlids."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Has oblidat el teu nom d\'usuari o la contrasenya?"\n"Visita "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Has oblidat el teu nom d\'usuari o la contrasenya?\nVisita "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"S\'està comprovant el compte…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Has escrit malament el PIN <xliff:g id="NUMBER_0">%d</xliff:g> vegades. "\n\n"Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Has escrit malament la contrasenya <xliff:g id="NUMBER_0">%d</xliff:g> vegades. "\n\n"Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Has dibuixat el patró de desbloqueig de manera incorrecta <xliff:g id="NUMBER_0">%d</xliff:g> vegades. "\n\n"Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Has escrit malament el PIN <xliff:g id="NUMBER_0">%d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Has escrit malament la contrasenya <xliff:g id="NUMBER_0">%d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Has dibuixat el patró de desbloqueig de manera incorrecta <xliff:g id="NUMBER_0">%d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. D\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, la tauleta es restablirà a la configuració predeterminada de fàbrica i es perdran totes les dades dels usuaris."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. D\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, el telèfon es restablirà a la configuració predeterminada de fàbrica i es perdran totes les dades dels usuaris."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER">%d</xliff:g> vegades de manera incorrecta. Ara la tauleta es restablirà a la configuració predeterminada de fàbrica."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER">%d</xliff:g> vegades de manera incorrecta. Ara el telèfon es restablirà a la configuració predeterminada de fàbrica."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Després de <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, se\'t demanarà que desbloquegis la tauleta amb un compte de correu electrònic."\n\n" Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Després de <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, se\'t demanarà que desbloquegis el telèfon amb un compte de correu electrònic."\n\n" Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Després de <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, se\'t demanarà que desbloquegis la tauleta amb un compte de correu electrònic.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Després de <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, se\'t demanarà que desbloquegis el telèfon amb un compte de correu electrònic.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Elimina"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Vols augmentar el volum per sobre del nivell recomanat?"\n"Escoltar sons a un volum alt durant períodes de temps llargs pot danyar l\'oïda."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Vols augmentar el volum per sobre del nivell recomanat?\nEscoltar sons a un volum alt durant períodes de temps llargs pot danyar l\'oïda."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Mantén premuts els dos dits per activar l\'accessibilitat."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"S\'ha activat l\'accessibilitat."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accessibilitat cancel·lada."</string>
     <string name="user_switched" msgid="3768006783166984410">"Usuari actual: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Propietari"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Error"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"L\'aplicació no és compatible amb comptes de perfils restringits."</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"L\'aplicació no és compatible amb comptes de perfils restringits"</string>
     <string name="app_not_found" msgid="3429141853498927379">"No s\'ha trobat cap aplicació per processar aquesta acció"</string>
     <string name="revoke" msgid="5404479185228271586">"Revoca"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Carta"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Carta governamental"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Legal Junior"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Llibre major"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloide"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Cancel·lada"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Error en escriure el contingut"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"desconegut"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Introdueix el PIN d\'administrador"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Introdueix el PIN"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Incorrecte"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN actual"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"PIN nou"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Confirma el PIN nou"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Crea un pin per modificar les restriccions"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"Els PIN no coincideixen. Torna-ho a provar."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"El PIN és massa curt. Ha de tenir quatre dígits com a mínim."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Torna-ho a provar d\'aquí a 1 segon"</item>
+    <item quantity="other" msgid="4730868920742952817">"Torna-ho a provar d\'aquí a <xliff:g id="COUNT">%d</xliff:g> segons"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Torna-ho a provar més tard"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Llisca des de vora per mostrar barra"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Fes lliscar el dit des de la vora de la pantalla perquè es mostri la barra del sistema"</string>
 </resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index a465d7c..0bd1b2f1 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -131,6 +131,11 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Příliš mnoho smazaných položek služby <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Úložiště tabletu je plné. Uvolněte místo smazáním některých souborů."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Paměť telefonu je plná. Uvolněte místo smazáním některých souborů."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Síť může být monitorována"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Já"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Možnosti tabletu"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Možnosti telefonu"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Umožňuje aplikaci přesunout úlohy na popředí nebo pozadí. Aplikace tak může činit bez vašeho zásahu."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"zastavení činnosti aplikací"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Umožňuje aplikaci odstranit úlohy a ukončit jejich aplikace. Škodlivé aplikace mohou narušit chování ostatních aplikací."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"spravovat zásobníky aktivit"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Umožňuje aplikaci přidat, odstranit nebo upravit zásobníky aktivit jiných aplikací. Škodlivé aplikace mohou narušit chování ostatních aplikací."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"zahájení libovolné činnosti"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Umožňuje aplikaci zahájit libovolnou aktivitu bez ohledu na ochranu pomocí oprávnění či exportovaný stav."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"nastavit kompatibilitu obrazovky"</string>
@@ -326,7 +333,7 @@
     <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"vynucení zavření aplikací na pozadí"</string>
     <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"Umožňuje aplikaci ovládat, zda budou činnosti po přechodu na pozadí vždy ukončeny. Běžné aplikace toto oprávnění nikdy nepožadují."</string>
     <string name="permlab_batteryStats" msgid="2789610673514103364">"čtení statistických údajů o baterii"</string>
-    <string name="permdesc_batteryStats" msgid="5897346582882915114">"Umožňuje aplikaci číst aktuální podrobné údaje o využití baterie. Aplikace to může využít k získání podrobných informací o tom, které aplikace používáte."</string>
+    <string name="permdesc_batteryStats" msgid="5897346582882915114">"Umožňuje aplikaci číst aktuální podrobné údaje o využívání baterie. Aplikace to může využít k získání podrobných informací o tom, které aplikace používáte."</string>
     <string name="permlab_updateBatteryStats" msgid="3719689764536379557">"změna statistických údajů o baterii"</string>
     <string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"Umožňuje aplikaci upravit shromážděné statistiky o baterii. Toto oprávnění není určeno pro běžné aplikace."</string>
     <string name="permlab_getAppOpsStats" msgid="1508779687436585744">"načtení statistik operací aplikace"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Umožňuje držiteli vázat se na nejvyšší úroveň rozhraní pro zadávání dat. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"navázat se na službu usnadnění přístupu"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Umožňuje držiteli navázat se na nejvyšší úroveň rozhraní služby usnadnění přístupu. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"navázat se na tiskovou službu"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Umožňuje navázání na nejvyšší úroveň tiskové služby. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"navázat se na službu zařazování tisku"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Umožňuje držiteli navázat se na nejvyšší úroveň služby zařazování tisku. Běžné aplikace by toto oprávnění neměly nikdy potřebovat."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"navázat se na službu NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Umožňuje držiteli navázat se na aplikace, které emulují karty NFC. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"navázat se na textovou službu"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Umožňuje držiteli připojit se k nejvyšší úrovni rozhraní textové služby (např. SpellCheckerService). Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"navázat se na službu VPN"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Umožňuje držiteli navázat se na nejvyšší úroveň služby widgetu. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"komunikovat se správcem zařízení"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Umožňuje držiteli oprávnění odesílat informace správci zařízení. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"přidat nebo odebrat správce zařízení"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Opravňuje držitele přidávat nebo odebírat aktivní správce zařízení. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"změna orientace obrazovky"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Umožňuje aplikaci kdykoli změnit otočení obrazovky. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"změna rychlosti kurzoru"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Umožňuje aplikaci číst různé systémové soubory protokolů. Toto oprávnění aplikaci umožní získat obecné informace o činnostech s telefonem, které by mohly obsahovat osobní či soukromé informace."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"použít jakýkoliv dekodér pro přehrávání médií"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Umožňuje aplikaci používat libovolný nainstalovaný dekodér médií k dekódování při přehrávání."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"správa důvěryhodných identifikačních údajů"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Umožňuje aplikaci instalovat a odinstalovat certifikáty CA jako důvěryhodné identifikační údaje."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"čtení nebo zápis do prostředků funkce diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Umožňuje aplikaci číst libovolné prostředky ve skupině diag, např. soubory ve složce /dev, a zapisovat do nich. Může dojít k ovlivnění stability a bezpečnosti systému. Toto nastavení by měl používat POUZE výrobce či operátor pro diagnostiku hardwaru."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"aktivace či deaktivace komponent aplikací"</string>
@@ -462,6 +479,14 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Povoluje aplikaci připojit a konfigurovat displeje přes Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"ovládat displeje přes Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Povoluje aplikaci ovládat základní funkce displejů přes Wi-Fi."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"zachytit výstup zvuku"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Umožní aplikaci zachytit a přesměrovat výstup zvuku."</string>
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Detekce klíčových slov"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Umožní aplikaci zaznamenávat zvuk za účelem detekce klíčových slov. Záznam může probíhat na pozadí a nebrání jinému zaznamenávání zvuku (například videokamerou)."</string>
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"zachytit výstup videa"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Umožní aplikaci zachytit a přesměrovat výstup videa."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"zachytit zabezpečený výstup videa"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Umožní aplikaci zachytit a přesměrovat zabezpečený výstup videa."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"změna nastavení zvuku"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Umožňuje aplikaci změnit globální nastavení zvuku, například hlasitost či reproduktor pro výstup zvuku."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"nahrávání zvuku"</string>
@@ -525,6 +550,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"bránění přechodu telefonu do režimu spánku"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Umožňuje aplikaci zabránit přechodu tabletu do režimu spánku."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Umožňuje aplikaci zabránit přechodu telefonu do režimu spánku."</string>
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"infračervený přenos"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Umožňuje aplikaci využívat infračervený vysílač tabletu."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Umožňuje aplikaci využívat infračervený vysílač telefonu."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"zapnutí či vypnutí tabletu"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"zapnutí či vypnutí telefonu"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Umožňuje aplikaci zapnout či vypnout tablet."</string>
@@ -555,7 +583,7 @@
     <string name="permdesc_manageAccounts" msgid="8698295625488292506">"Umožňuje aplikaci provádět operace, jako je přidávání nebo odebírání účtů nebo mazání jejich hesel."</string>
     <string name="permlab_useCredentials" msgid="235481396163877642">"používání účtů v zařízení"</string>
     <string name="permdesc_useCredentials" msgid="7984227147403346422">"Umožňuje aplikaci požadovat ověřovací tokeny."</string>
-    <string name="permlab_accessNetworkState" msgid="4951027964348974773">"zobrazení síťových připojení"</string>
+    <string name="permlab_accessNetworkState" msgid="4951027964348974773">"zobrazování síťových připojení"</string>
     <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Umožňuje aplikaci zobrazit informace o síťových připojeních, například o tom, které sítě jsou k dispozici a které jsou připojené."</string>
     <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"úplný přístup k síti"</string>
     <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Umožňuje aplikaci vytvářet síťové sokety a používat vlastní síťové protokoly. K odesílání údajů na internet toto oprávnění není nutné, protože údaje lze na internet odesílat prostřednictvím prohlížečů a dalších aplikací."</string>
@@ -613,6 +641,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Umožňuje aplikaci zapisovat na kartu SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"Upravit/smazat interní úlož."</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Umožňuje aplikaci upravovat obsah interního úložiště médií."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"spravovat úložiště dokumentů"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Umožňuje aplikaci spravovat úložiště dokumentů."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"přístup k externímu úložišti všech uživatelů"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Umožňuje aplikaci přistupovat k externímu úložišti pro všechny uživatele."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"přistupovat do souborového systému mezipaměti"</string>
@@ -625,10 +655,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Umožňuje aplikaci spravovat zásady sítě a definovat pravidla pro konkrétní aplikace."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"upravit kontrolu používání sítě"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Umožňuje aplikaci upravit způsob výpočtu využití sítě aplikacemi. Toto oprávnění není určeno pro běžné aplikace."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"upravit značky soketů"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Umožňuje aplikaci upravit značky soketů pro směrování"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"přístup k oznámením"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Umožňuje aplikacím načítat, zobrazovat a mazat oznámení včetně těch přidaných jinými aplikacemi."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"navázání na službu pro poslouchání oznámení"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Umožňuje držiteli navázat se na nejvyšší úroveň služby pro poslouchání oznámení. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"vyvolat konfigurační aplikaci poskytnutou operátorem"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Umožňuje vyvolání konfigurační aplikace poskytnuté operátorem. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"naslouchat informacím o stavu sítě"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Umožňuje aplikaci naslouchat informacím o stavu sítě. Běžné aplikace by toto oprávnění neměly nikdy potřebovat."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Nastavit pravidla pro heslo"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Řídit délku hesel pro odemčení obrazovky a povolené znaky."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Sledovat pokusy o odemčení obrazovky"</string>
@@ -738,8 +774,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +831,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Vložte SIM kartu."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM karta chybí nebo je nečitelná. Vložte SIM kartu."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Nepoužitelná karta SIM."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Vaše SIM karta byla natrvalo zablokována."\n" Požádejte svého poskytovatele bezdrátových služeb o další SIM kartu."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Vaše SIM karta byla natrvalo zablokována.\n Požádejte svého poskytovatele bezdrátových služeb o další SIM kartu."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Tlačítko Předchozí stopa"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Tlačítko Další stopa"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Tlačítko Pozastavit"</string>
@@ -808,11 +843,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Další informace naleznete v uživatelské příručce; nebo kontaktujte zákaznickou podporu."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM karta je zablokována."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Odblokování SIM karty..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste použili nesprávné bezpečnostní gesto. "\n\n"Zkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně zadali heslo. "\n\n"Zkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně zadali kód PIN. "\n\n"Zkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně nakreslili své heslo odemknutí. Po dalších neúspěšných pokusech (<xliff:g id="NUMBER_1">%d</xliff:g>) budete požádáni o odemčení tabletu pomocí přihlášení Google."\n\n" Zkuste to znovu za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně nakreslili své heslo odemknutí. Po dalších neúspěšných pokusech (<xliff:g id="NUMBER_1">%d</xliff:g>) budete požádáni o odemčení telefonu pomocí přihlášení Google."\n\n" Zkuste to znovu za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste použili nesprávné bezpečnostní gesto. \n\nZkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně zadali heslo. \n\nZkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně zadali kód PIN. \n\nZkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně nakreslili své heslo odemknutí. Po dalších neúspěšných pokusech (<xliff:g id="NUMBER_1">%d</xliff:g>) budete požádáni o odemčení tabletu pomocí přihlášení Google.\n\n Zkuste to znovu za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně nakreslili své heslo odemknutí. Po dalších neúspěšných pokusech (<xliff:g id="NUMBER_1">%d</xliff:g>) budete požádáni o odemčení telefonu pomocí přihlášení Google.\n\n Zkuste to znovu za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Tablet jste se pokusili nesprávným způsobem odemknout <xliff:g id="NUMBER_0">%d</xliff:g>krát. Po <xliff:g id="NUMBER_1">%d</xliff:g> dalších neúspěšných pokusech se v tabletu obnoví tovární nastavení a veškerá uživatelská data budou ztracena."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Telefon jste se pokusili nesprávným způsobem odemknout <xliff:g id="NUMBER_0">%d</xliff:g>krát. Po <xliff:g id="NUMBER_1">%d</xliff:g> dalších neúspěšných pokusech se v telefonu obnoví tovární nastavení a veškerá uživatelská data budou ztracena."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Tablet jste se pokusili nesprávným způsobem odemknout <xliff:g id="NUMBER">%d</xliff:g>krát. V tabletu se nyní obnoví výchozí tovární nastavení."</string>
@@ -826,7 +861,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Heslo"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Přihlásit se"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Neplatné uživatelské jméno nebo heslo."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Zapomněli jste uživatelské jméno nebo heslo?"\n"Přejděte na stránku "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Zapomněli jste uživatelské jméno nebo heslo?\nPřejděte na stránku "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Kontrola..."</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Odemknout"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Zapnout zvuk"</string>
@@ -874,7 +909,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Potvrďte přechod"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Opustit stránku"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Zůstat na této stránce"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Opravdu tuto stránku chcete opustit?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nOpravdu tuto stránku chcete opustit?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Potvrdit"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Tip: Dvojitým klepnutím můžete zobrazení přiblížit nebo oddálit."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Aut.vyp."</string>
@@ -1080,14 +1115,14 @@
     <string name="aerr_application" msgid="932628488013092776">"Aplikace <xliff:g id="APPLICATION">%1$s</xliff:g> bohužel přestala pracovat."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> byl bohužel ukončen."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"Aplikace <xliff:g id="APPLICATION">%2$s</xliff:g> nereaguje."\n\n"Chcete ji ukončit?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Aktivita <xliff:g id="ACTIVITY">%1$s</xliff:g> nereaguje."\n\n"Chcete ji ukončit?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"Aplikace <xliff:g id="APPLICATION">%2$s</xliff:g> nereaguje.\n\nChcete ji ukončit?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Aktivita <xliff:g id="ACTIVITY">%1$s</xliff:g> nereaguje.\n\nChcete ji ukončit?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"Aplikace <xliff:g id="APPLICATION">%1$s</xliff:g> nereaguje. Chcete ji ukončit?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> nereaguje."\n\n"Chcete jej ukončit?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> nereaguje.\n\nChcete jej ukončit?"</string>
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"Hlášení"</string>
     <string name="wait" msgid="7147118217226317732">"Počkat"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"Stránka nereaguje."\n\n"Chcete ji zavřít?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Stránka nereaguje.\n\nChcete ji zavřít?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Přesměrování aplikace"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"Je spuštěna aplikace <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"Původně byla spuštěna aplikace <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
@@ -1256,6 +1291,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Umožňuje aplikaci dát výchozí službě kontejneru příkaz ke zkopírování obsahu. Toto oprávnění není určeno pro běžné aplikace."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Směrování výstupu médií"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Umožňuje aplikaci směrovat výstup médií do dalších externích zařízení."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Přístup k bezpečnému úložišti keyguard"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Umožňuje aplikaci přístup k bezpečnému úložišti keyguard."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Ovládání zobrazování a skrývání zámku obrazovky"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Umožňuje aplikaci ovládat zámek obrazovky."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Dvojitým dotykem můžete ovládat přiblížení"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Widget nelze přidat."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Přejít"</string>
@@ -1265,15 +1304,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Hotovo"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Předch."</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Spustit"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Vytočit číslo"\n" <xliff:g id="NUMBER">%s</xliff:g>."</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Vytvořit kontakt"\n"pro <xliff:g id="NUMBER">%s</xliff:g>."</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Vytočit číslo\n <xliff:g id="NUMBER">%s</xliff:g>."</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Vytvořit kontakt\npro <xliff:g id="NUMBER">%s</xliff:g>."</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Následující aplikace požadují oprávnění k přístupu do vašeho účtu (nyní i v budoucnu)."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Chcete tento požadavek povolit?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Žádost o přístup"</string>
     <string name="allow" msgid="7225948811296386551">"Povolit"</string>
     <string name="deny" msgid="2081879885755434506">"Odepřít"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Požadováno oprávnění"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Požadováno oprávnění"\n"pro účet <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Požadováno oprávnění\npro účet <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Metoda zadávání dat"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Synchronizace"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Usnadnění"</string>
@@ -1420,7 +1459,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Zobrazit vše"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Vybrat aktivitu"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Sdílet s"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Zařízení je uzamčeno."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Odesílání..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Spustit prohlížeč?"</string>
@@ -1441,10 +1479,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Připojování…"</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Dostupná"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"Není k dispozici"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"Používá se"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Integrovaná obrazovka"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"Obrazovka HDMI"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Překryvná vrstva č. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", zabezpečené"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Bezdrátový displej je připojen"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Tato obrazovka se zobrazuje v jiném zařízení"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Odpojit"</string>
@@ -1453,7 +1493,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Nesprávné gesto"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Nesprávné heslo"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"Nesprávný kód PIN"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Zkuste to znovu za <xliff:g id="NUMBER">%d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Zkuste to znovu za <xliff:g id="NUMBER">%1$d</xliff:g> s."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Nakreslete gesto"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Zadejte kód PIN SIM karty"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Zadejte kód PIN"</string>
@@ -1473,27 +1513,85 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Heslo"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Přihlásit se"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Neplatné uživatelské jméno nebo heslo."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Zapomněli jste uživatelské jméno nebo heslo?"\n"Přejděte na stránku "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Zapomněli jste uživatelské jméno nebo heslo?\nPřejděte na stránku "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Kontrola účtu…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste zadali nesprávný kód PIN. "\n\n"Zkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně zadali heslo. "\n\n"Zkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste zadali nesprávné bezpečnostní gesto. "\n\n"Zkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste zadali nesprávný kód PIN. \n\nZkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně zadali heslo. \n\nZkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste zadali nesprávné bezpečnostní gesto. \n\nZkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Již jste se <xliff:g id="NUMBER_0">%d</xliff:g>krát pokusili odemknout tablet nesprávným způsobem. Po <xliff:g id="NUMBER_1">%d</xliff:g> dalších neúspěšných pokusech se v tabletu obnoví tovární nastavení a veškerá uživatelská data budou ztracena."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Již jste se <xliff:g id="NUMBER_0">%d</xliff:g>krát pokusili odemknout telefon nesprávným způsobem. Po <xliff:g id="NUMBER_1">%d</xliff:g> dalších neúspěšných pokusech se v telefonu obnoví tovární nastavení a veškerá uživatelská data budou ztracena."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Již jste se <xliff:g id="NUMBER">%d</xliff:g>krát pokusili odemknout tablet nesprávným způsobem. V tabletu se nyní obnoví výchozí tovární nastavení."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Již jste se <xliff:g id="NUMBER">%d</xliff:g>krát pokusili odemknout telefon nesprávným způsobem. V telefonu se nyní obnoví výchozí tovární nastavení."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně nakreslili své heslo odemknutí. Po <xliff:g id="NUMBER_1">%d</xliff:g>dalších neúspěšných pokusech budete požádáni o odemčení tabletu pomocí e-mailového účtu."\n\n" Zkuste to znovu za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně nakreslili své heslo odemknutí. Po <xliff:g id="NUMBER_1">%d</xliff:g> dalších neúspěšných pokusech budete požádáni o odemčení telefonu pomocí e-mailového účtu."\n\n" Zkuste to znovu za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně nakreslili své heslo odemknutí. Po <xliff:g id="NUMBER_1">%d</xliff:g>dalších neúspěšných pokusech budete požádáni o odemčení tabletu pomocí e-mailového účtu.\n\n Zkuste to znovu za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně nakreslili své heslo odemknutí. Po <xliff:g id="NUMBER_1">%d</xliff:g> dalších neúspěšných pokusech budete požádáni o odemčení telefonu pomocí e-mailového účtu.\n\n Zkuste to znovu za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Odebrat"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Zvýšit hlasitost nad doporučenou úroveň?"\n"Dlouhodobý poslech hlasitého zvuku může poškodit sluch."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Zvýšit hlasitost nad doporučenou úroveň?\nDlouhodobý poslech hlasitého zvuku může poškodit sluch."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Usnadnění zapnete dlouhým stisknutím dvěma prsty."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Usnadnění přístupu je aktivováno."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Usnadnění zrušeno."</string>
     <string name="user_switched" msgid="3768006783166984410">"Aktuální uživatel je <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Vlastník"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Chyba"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Tato aplikace nepodporuje účty pro omezené profily."</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Tato aplikace nepodporuje účty pro omezené profily"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Aplikace potřebná k provedení této akce nebyla nalezena"</string>
     <string name="revoke" msgid="5404479185228271586">"Zrušit"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Zrušeno"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Při zápisu obsahu došlo k chybě"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"neznámé"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Zadejte PIN administrátora"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Zadejte kód PIN"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Nesprávné"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Aktuální kód PIN"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Nový kód PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Potvrďte nový PIN"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Vytvořit kód PIN pro úpravy omezení"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"Kódy PIN se neshodují. Zkuste to znovu."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"Kód PIN je příliš krátký. Musí mít alespoň čtyři číslice."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Zkuste to znovu za 1 s"</item>
+    <item quantity="other" msgid="4730868920742952817">"Zkuste to znovu za <xliff:g id="COUNT">%d</xliff:g> s"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Zkuste to znovu později"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Panel zobrazíte přejetím přes kraje obrazovky"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Systémový panel zobrazíte přejetím přes okraj obrazovky"</string>
 </resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 6c9a5f3..9822263 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -131,6 +131,11 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"For mange <xliff:g id="CONTENT_TYPE">%s</xliff:g> sletninger"</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Din tablets lager er fuldt. Slet nogle filer for at frigøre plads."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Telefonens lager er fuldt. Slet nogle filer for at frigøre plads."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Netværket kan være overvåget"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Mig"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Valgmuligheder for tabletcomputeren"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Telefonvalgmuligheder"</string>
@@ -245,9 +250,9 @@
     <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"Tillader, at appen kan udvide og skjule statusbjælken."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"omdirigere udgående opkald"</string>
     <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Tillader, at appen kan behandle udgående opkald og ændre det nummer, der skal ringes til. Med denne tilladelse kan appen overvåge, omdirigere eller forhindre udgående opkald."</string>
-    <string name="permlab_receiveSms" msgid="8673471768947895082">"modtage tekstbeskeder (SMS)"</string>
+    <string name="permlab_receiveSms" msgid="8673471768947895082">"modtage tekstbeskeder (sms)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Tillader, at appen kan modtage og behandle sms-beskeder. Det betyder, at appen kan overvåge eller slette de beskeder, der sendes til din enhed, uden at vise dem til dig."</string>
-    <string name="permlab_receiveMms" msgid="1821317344668257098">"modtage tekstbeskeder (MMS)"</string>
+    <string name="permlab_receiveMms" msgid="1821317344668257098">"modtage tekstbeskeder (mms)"</string>
     <string name="permdesc_receiveMms" msgid="533019437263212260">"Tillader, at appen kan modtage og behandle mms-beskeder. Det betyder, at appen kan overvåge eller slette de beskeder, der sendes til din enhed, uden at vise dem til dig."</string>
     <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"modtage nødudsendelser"</string>
     <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Tillader, at appen kan modtage og behandle nødtransmissioner. Denne tilladelse er kun tilgængelig for systemapps."</string>
@@ -257,10 +262,10 @@
     <string name="permdesc_sendSms" msgid="7094729298204937667">"Tillader, at appen kan sende sms-beskeder. Dette kan resultere i uventede opkrævninger. Skadelige apps kan koste dig penge ved at sende beskeder uden din bekræftelse."</string>
     <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"send hændelser, hvor der skal svares pr. besked"</string>
     <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"Tillader, at appen kan sende anmodninger til andre apps til beskeder for at håndtere hændelser, hvor der skal svares pr. besked."</string>
-    <string name="permlab_readSms" msgid="8745086572213270480">"læse dine tekstbeskeder (SMS eller MMS)"</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"læse dine tekstbeskeder (sms eller mms)"</string>
     <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Tillader, at appen kan læse de sms-beskeder, der er gemt på din tablet eller dit SIM-kort. Med denne tilladelse kan appen læse alle sms-beskeder, uanset indhold eller fortrolighed."</string>
     <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Tillader, at appen kan læse de sms-beskeder, der er gemt på din telefon eller dit SIM-kort. Med denne tilladelse kan appen læse alle sms-beskeder, uanset indhold eller fortrolighed."</string>
-    <string name="permlab_writeSms" msgid="3216950472636214774">"redigere dine tekstbeskeder (SMS eller MMS)"</string>
+    <string name="permlab_writeSms" msgid="3216950472636214774">"redigere dine tekstbeskeder (sms eller mms)"</string>
     <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Tillader, at appen kan skrive til sms-beskeder, der er gemt på din tablet eller på SIM-kortet. Ondsindede apps kan slette dine beskeder."</string>
     <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Tillader, at appen kan skrive til sms-beskeder, der er gemt på din telefon eller dit SIM-kort. Ondsindede apps kan slette dine beskeder."</string>
     <string name="permlab_receiveWapPush" msgid="5991398711936590410">"modtage tekstbeskeder (WAP)"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Tillader, at appen kan flytte opgaver til forgrunden og baggrunden. Appen kan gøre dette uden din bekræftelse."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"stoppe kørsel af apps"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Tillader, at en app kan fjerne opgaver og lukke deres apps. Ondsindede apps kan forstyrre adfærden for andre apps."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"administrere aktivitetsstakke"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Tillader, at appen tilføjer, fjerner og ændrer aktivitetsstakkene, hvori andre apps kører. Skadelige apps kan forstyrre adfærden for andre apps."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"starte en aktivitet"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Tillader, at appen starter en hvilken som helst aktivitet, uanset tilladelsesbeskyttelse eller eksporteret tilstand."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"indstil skærmens kompatibilitet"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Tillader, at brugeren kan forpligter sig til en inputmetodes grænseflade på øverste niveau. Bør aldrig være nødvendigt til almindelige apps."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"bind dig til en tilgængelighedstjeneste"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Tillader, at brugeren binder sig til en grænseflade for en tilgængelighedstjeneste på øverste niveau. Bør aldrig være nødvendigt til almindelige apps."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"forbinde til en udskriftstjeneste"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Tillader, at brugeren forbinder til grænsefladen for en udskriftstjeneste på øverste niveau. Dette bør aldrig være nødvendigt for almindelige apps."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"forbinde til en udskriftsspoolertjeneste"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Tillader, at brugeren forbinder til grænsefladen for en udskriftsspoolertjeneste på øverste niveau. Dette bør aldrig være nødvendigt for almindelige apps."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"Knyt til NFC-tjeneste"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Tillader, at indehaveren opretter tilknytninger til applikationer, der efterligner NFC-kort. Dette bør aldrig være nødvendigt for normale apps."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"forpligte sig til en sms-tjeneste"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Tillader, at ejeren kan binde en teksttjenestes grænseflade (f. eks. SpellCheckerService) på øverste niveau. Dette bør aldrig være nødvendigt til normale apps."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"bind til en VPN-tjeneste"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Tillader, at brugeren kan forpligte sig til en grænseflade for en widgettjeneste på øverste niveau. Bør aldrig være nødvendigt til almindelige apps."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"kommunikere med en enhedsadministrator"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Tillader, at brugeren kan sende hensigter til en enhedsadministrator. Dette bør aldrig være nødvendigt for almindelige apps."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"tilføje eller fjerne en enhedsadministrator"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Tillader, at man tilføjer eller fjerner aktive enhedsadministratorer. Dette burde aldrig være nødvendigt til normale apps."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"skift skærmretning"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Tillader, at appen kan ændre skærmretningen på et hvilket som helst tidspunkt. Bør aldrig være nødvendigt for almindelige apps."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"ændre markørens hastighed"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Tillader, at appen kan læse i systemets forskellige logfiler. Dermed kan generelle oplysninger om, hvad du laver med telefonen registreres, også personlige eller private oplysninger."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"brug enhver mediedekoder til afspilning"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Tillader, at appen bruger enhver installeret medieafkoder til at afkode til afspilning."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"administrer pålidelige logonoplysninger"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Tillader, at appen installerer og afinstallerer CA-certifikater som pålidelige loginoplysninger."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"læs/skriv til ressourcer ejet af diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Tillader, at appen kan læse og skrive til alle ressourcer, der ejes af diag-gruppen,  f.eks. filer i /dev. Dette kan muligvis påvirke systemets stabilitet og sikkerhed. Dette bør KUN bruges til hardwarespecifik diagnosticering, som foretages af producenten eller udbyderen."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"aktivere eller deaktivere appkomponenter"</string>
@@ -462,6 +479,14 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Tillader, at appen konfigurerer og opretter forbindelse til Wi-Fi-skærme."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"kontrollér Wi-Fi-skærme"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Tillader, at appen kontrollerer Wi-Fi-skærmfunktioner på lavt niveau."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"opfang et lydoutput"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Tillader, at appen opfanger og omdirigerer et lydoutput."</string>
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Registrering af kommandoord"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Tillader, at appen optager lyd til registrering af kommandoord. Optagelsen kan ske i baggrunden, men forhindrer ikke andre lydoptagelser (f.eks. videokamera)."</string>
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"opfang et videooutput"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Tillader, at appen opfanger og omdirigerer et videooutput."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"opfang et sikkert videooutput"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Tillader, at appen opfanger og omdirigerer et sikkert videooutput."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"skift dine lydindstillinger"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Tillader, at appen kan ændre globale lydindstillinger, som f.eks. lydstyrke og hvilken højttaler der bruges til output."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"optage lyd"</string>
@@ -525,6 +550,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"afholde telefonen fra at gå i dvale"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Tillader, at appen kan forhindre tabletten i at gå i dvale."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Tillader, at appen kan forhindre, at telefonen går i dvale."</string>
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"send infrarød"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Tillader, at appen bruger tablettens infrarøde sender."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Tillader, at appen bruger telefonens infrarøde sender."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"tænd eller sluk for tabletcomputeren"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"tænd eller sluk for telefonen"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Tillader, at appen kan slukke og tænde din tablet."</string>
@@ -555,7 +583,7 @@
     <string name="permdesc_manageAccounts" msgid="8698295625488292506">"Tillader, at appen kan foretage handlinger såsom at tilføje og fjerne konti og slette adgangskoden."</string>
     <string name="permlab_useCredentials" msgid="235481396163877642">"bruge konti på enheden"</string>
     <string name="permdesc_useCredentials" msgid="7984227147403346422">"Tillader, at appen kan anmode om godkendelsestokens."</string>
-    <string name="permlab_accessNetworkState" msgid="4951027964348974773">"få vist netværksforbindelser"</string>
+    <string name="permlab_accessNetworkState" msgid="4951027964348974773">"se netværksforbindelser"</string>
     <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Tillader, at appen kan læse oplysninger om netværksforbindelser, f.eks. eksisterende og forbundne netværk."</string>
     <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"fuld netværksadgang"</string>
     <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Tillader, at appen kan oprette netværkssockets og bruge tilpassede netværksprotokoller. Browseren og andre applikationer indeholder midler til at sende data til internettet, så med denne tilladelse er der ingen forpligtelse til at sende data til internettet."</string>
@@ -567,7 +595,7 @@
     <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Tillader, at appen kan ændre tilstand for en netværksforbindelse via netdeling."</string>
     <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"skift brugerindstilling for baggrundsdata"</string>
     <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Tillader, at appen kan ændre indstillingen for brug af baggrundsdata."</string>
-    <string name="permlab_accessWifiState" msgid="5202012949247040011">"få vist Wi-Fi-forbindelser"</string>
+    <string name="permlab_accessWifiState" msgid="5202012949247040011">"se Wi-Fi-forbindelser"</string>
     <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Tillader, at appen kan læse oplysninger om Wi-Fi-netværk, f.eks. hvorvidt Wi-Fi er aktiveret og navnet på forbundne Wi-Fi-enheder."</string>
     <string name="permlab_changeWifiState" msgid="6550641188749128035">"oprette og afbryde Wi-Fi-forbindelse"</string>
     <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Tillader, at appen kan oprette og afbryde forbindelsen fra Wi-Fi-adgangspunkter og foretage ændringer i enhedskonfigurationen for Wi-Fi-netværk."</string>
@@ -613,6 +641,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Tillader, at appen kan skrive til SD-kortet."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"Rediger/slet internt medielagringsindhold"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Tillader, appen kan ændre indholdet af det interne medielager."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"administrer dokumentlagring"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Tillader, at appen kan administrere dokumentlagring."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"få adgang til alle brugeres eksterne lagre"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Tillader, at appen får adgang til eksterne lagre for alle brugere."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"få adgang til cache-filsystemet"</string>
@@ -625,10 +655,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Tillader, at appen kan administrere netværkspolitikker og definere appspecifikke regler."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"skift afregning af netværksbrug"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Tillader, at appen kan ændre den måde, som netværksforbrug udregnes på i forhold til apps. Anvendes ikke af normale apps."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"ændre socketmærker"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Tillader, at appen ændrer socketmærker ved omdirigering"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"adgang til underretninger"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Tillader, at appen kan hente, undersøge og rydde underretninger, herunder dem, der er sendt af andre apps."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"forpligte sig til en underretningslyttertjeneste"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Tillader brugeren at forpligte sig til en underretningslyttertjenestes grænseflade på øverste niveau. Bør aldrig være nødvendigt til almindelige apps."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"aktivere konfigurationsappen, der leveres af mobilselskabet"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Tillader, at brugeren aktiverer konfigurationsappen, der er forsynet af mobilselskabet. Dette bør aldrig være nødvendigt for almindelige apps."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"observer netværksforhold"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Tillader, at en applikation observerer netværksforhold. Bør aldrig være nødvendigt for almindelige apps."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Indstil regler for adgangskode"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontroller længden samt tilladte tegn i adgangskoder til oplåsning af skærmen."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Overvåg forsøg på oplåsning af skærm"</string>
@@ -664,13 +700,13 @@
   <string-array name="emailAddressTypes">
     <item msgid="8073994352956129127">"Hjem"</item>
     <item msgid="7084237356602625604">"Arbejde"</item>
-    <item msgid="1112044410659011023">"Andre"</item>
+    <item msgid="1112044410659011023">"Andet"</item>
     <item msgid="2374913952870110618">"Tilpasset"</item>
   </string-array>
   <string-array name="postalAddressTypes">
     <item msgid="6880257626740047286">"Hjem"</item>
     <item msgid="5629153956045109251">"Arbejde"</item>
-    <item msgid="4966604264500343469">"Andre"</item>
+    <item msgid="4966604264500343469">"Andet"</item>
     <item msgid="4932682847595299369">"Tilpasset"</item>
   </string-array>
   <string-array name="imAddressTypes">
@@ -681,7 +717,7 @@
   </string-array>
   <string-array name="organizationTypes">
     <item msgid="7546335612189115615">"Arbejde"</item>
-    <item msgid="4378074129049520373">"Andre"</item>
+    <item msgid="4378074129049520373">"Andet"</item>
     <item msgid="3455047468583965104">"Tilpasset"</item>
   </string-array>
   <string-array name="imProtocols">
@@ -701,7 +737,7 @@
     <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Arbejdsfax"</string>
     <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Hjemmefax"</string>
     <string name="phoneTypePager" msgid="7582359955394921732">"Personsøger"</string>
-    <string name="phoneTypeOther" msgid="1544425847868765990">"Andre"</string>
+    <string name="phoneTypeOther" msgid="1544425847868765990">"Andet"</string>
     <string name="phoneTypeCallback" msgid="2712175203065678206">"Tilbagekald"</string>
     <string name="phoneTypeCar" msgid="8738360689616716982">"Bil"</string>
     <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Virksomhed (hovednummer)"</string>
@@ -718,33 +754,32 @@
     <string name="eventTypeCustom" msgid="7837586198458073404">"Tilpasset"</string>
     <string name="eventTypeBirthday" msgid="2813379844211390740">"Fødselsdato"</string>
     <string name="eventTypeAnniversary" msgid="3876779744518284000">"Årsdag"</string>
-    <string name="eventTypeOther" msgid="7388178939010143077">"Andre"</string>
+    <string name="eventTypeOther" msgid="7388178939010143077">"Andet"</string>
     <string name="emailTypeCustom" msgid="8525960257804213846">"Tilpasset"</string>
     <string name="emailTypeHome" msgid="449227236140433919">"Hjem"</string>
     <string name="emailTypeWork" msgid="3548058059601149973">"Arbejde"</string>
-    <string name="emailTypeOther" msgid="2923008695272639549">"Andre"</string>
+    <string name="emailTypeOther" msgid="2923008695272639549">"Andet"</string>
     <string name="emailTypeMobile" msgid="119919005321166205">"Mobil"</string>
     <string name="postalTypeCustom" msgid="8903206903060479902">"Tilpasset"</string>
     <string name="postalTypeHome" msgid="8165756977184483097">"Hjem"</string>
     <string name="postalTypeWork" msgid="5268172772387694495">"Arbejde"</string>
-    <string name="postalTypeOther" msgid="2726111966623584341">"Andre"</string>
+    <string name="postalTypeOther" msgid="2726111966623584341">"Andet"</string>
     <string name="imTypeCustom" msgid="2074028755527826046">"Tilpasset"</string>
     <string name="imTypeHome" msgid="6241181032954263892">"Hjem"</string>
     <string name="imTypeWork" msgid="1371489290242433090">"Arbejde"</string>
-    <string name="imTypeOther" msgid="5377007495735915478">"Andre"</string>
+    <string name="imTypeOther" msgid="5377007495735915478">"Andet"</string>
     <string name="imProtocolCustom" msgid="6919453836618749992">"Tilpasset"</string>
     <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string>
     <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string>
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
     <string name="orgTypeWork" msgid="29268870505363872">"Arbejde"</string>
-    <string name="orgTypeOther" msgid="3951781131570124082">"Andre"</string>
+    <string name="orgTypeOther" msgid="3951781131570124082">"Andet"</string>
     <string name="orgTypeCustom" msgid="225523415372088322">"Tilpasset"</string>
     <string name="relationTypeCustom" msgid="3542403679827297300">"Tilpasset"</string>
     <string name="relationTypeAssistant" msgid="6274334825195379076">"Assistent"</string>
@@ -764,7 +799,7 @@
     <string name="sipAddressTypeCustom" msgid="2473580593111590945">"Tilpasset"</string>
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Hjem"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Arbejde"</string>
-    <string name="sipAddressTypeOther" msgid="4408436162950119849">"Andre"</string>
+    <string name="sipAddressTypeOther" msgid="4408436162950119849">"Andet"</string>
     <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Indtast pinkode"</string>
     <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Indtast PUK- og pinkode"</string>
     <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-kode"</string>
@@ -796,7 +831,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Indsæt et SIM-kort."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM-kortet mangler eller kan ikke læses. Indsæt et SIM-kort."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Ubrugeligt SIM-kort."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Dit SIM-kort er blevet permanent deaktiveret."\n"Kontakt din tjenesteudbyder for at få et nyt SIM-kort."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Dit SIM-kort er blevet permanent deaktiveret.\nKontakt din tjenesteudbyder for at få et nyt SIM-kort."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Knap til forrige nummer"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Knap til næste nummer"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Pause-knap"</string>
@@ -808,11 +843,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Se brugervejledningen, eller kontakt kundeservice."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM-kortet er låst."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Låser SIM-kortet op ..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. "\n\n"Prøv igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Du har indtastet din adgangskode forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. "\n\n"Prøv igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Du har indtastet en forkert pinkode <xliff:g id="NUMBER_0">%d</xliff:g> gange. "\n\n"Prøv igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> yderligere forsøg vil du blive bedt om at låse din tablet op ved hjælp af dit Google-login"\n\n"  Prøv igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> forsøg til vil du blive bedt om at låse din telefon op ved hjælp af dit Google-login."\n\n" Prøv igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. \n\nPrøv igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Du har indtastet din adgangskode forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. \n\nPrøv igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Du har indtastet en forkert pinkode <xliff:g id="NUMBER_0">%d</xliff:g> gange. \n\nPrøv igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> yderligere forsøg vil du blive bedt om at låse din tablet op ved hjælp af dit Google-login\n\n  Prøv igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> forsøg til vil du blive bedt om at låse din telefon op ved hjælp af dit Google-login.\n\n Prøv igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Du har forsøgt at låse tabletten op forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter yderligere <xliff:g id="NUMBER_1">%d</xliff:g> mislykkede forsøg nulstilles tabletten til fabriksindstillingerne, og alle brugerdata mistes."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Du har forsøgt at låse telefonen op forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter yderligere <xliff:g id="NUMBER_1">%d</xliff:g> mislykkede forsøg, nulstilles telefonen til fabriksindstillingerne, og alle brugerdata mistes."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Du har forsøgt at låse tabletten op forkert <xliff:g id="NUMBER">%d</xliff:g> gange. Tabletten nulstilles til fabriksindstillingerne."</string>
@@ -826,7 +861,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Adgangskode"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Log ind"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Ugyldigt brugernavn eller ugyldig adgangskode."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Har du glemt dit brugernavn eller din adgangskode?"\n"Besøg "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Har du glemt dit brugernavn eller din adgangskode?\nBesøg "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Kontrollerer..."</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Lås op"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Lyd slået til"</string>
@@ -874,7 +909,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Bekræft navigation"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Forlad denne side"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Bliv på denne side"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Er du sikker på, at du vil navigere væk fra denne side?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nEr du sikker på, at du vil navigere væk fra denne side?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Bekræft"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Tip! Dobbeltklik for at zoome ind eller ud."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Autofyld"</string>
@@ -1080,14 +1115,14 @@
     <string name="aerr_application" msgid="932628488013092776">"Applikationen <xliff:g id="APPLICATION">%1$s</xliff:g> er desværre stoppet."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Processen <xliff:g id="PROCESS">%1$s</xliff:g> er desværre stoppet."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> svarer ikke."\n\n"Vil du lukke den?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Aktiviteten <xliff:g id="ACTIVITY">%1$s</xliff:g> svarer ikke."\n\n"Vil du at lukke den?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> svarer ikke.\n\nVil du lukke den?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Aktiviteten <xliff:g id="ACTIVITY">%1$s</xliff:g> svarer ikke.\n\nVil du at lukke den?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> svarer ikke. Vil du lukke den?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Processen <xliff:g id="PROCESS">%1$s</xliff:g> svarer ikke."\n\n"Vil du lukke den?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Processen <xliff:g id="PROCESS">%1$s</xliff:g> svarer ikke.\n\nVil du lukke den?"</string>
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"Rapportér"</string>
     <string name="wait" msgid="7147118217226317732">"Vent"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"Siden svarer ikke."\n\n"Vil du lukke den?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Siden svarer ikke.\n\nVil du lukke den?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Appen er omdirigeret"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> kører nu."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> blev oprindeligt åbnet."</string>
@@ -1256,6 +1291,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Tillader, at appen kan benytte standardlagertjenesten til at kopiere indhold. Anvendes ikke af almindelige apps."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Viderefør medieoutput"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Tillader, at en applikation viderefører medieoutput til andre eksterne enheder."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Få adgang nøglebeskyttet lager"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Tillader, at en applikation får adgang til et nøglebeskyttet lager."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Administrer, om nøglebeskyttelse skal vises eller skjules"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Tillader, at en applikation styrer nøglebeskyttelsen."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Tryk to gange for zoomstyring"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Widget kunne ikke tilføjes."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Gå"</string>
@@ -1265,15 +1304,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Afslut"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Forrige"</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Udfør"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Ring til nummer"\n"ved hjælp af <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Opret kontakt"\n"ved hjælp af <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Ring til nummer\nved hjælp af <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Opret kontakt\nved hjælp af <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Følgende app eller apps anmoder om at få adgang til din konto nu og fremover."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Vil du tillade denne anmodning?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Anmodning om adgang"</string>
     <string name="allow" msgid="7225948811296386551">"Tillad"</string>
     <string name="deny" msgid="2081879885755434506">"Afvis"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Der er anmodet om tilladelse"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Der er anmodet om tilladelse"\n"for kontoen <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Der er anmodet om tilladelse\nfor kontoen <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Inputmetode"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Synkroniser"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Tilgængelighed"</string>
@@ -1420,7 +1459,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Se alle"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Vælg aktivitet"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Del med"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Enhed låst."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Sender..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Vil du starte browseren?"</string>
@@ -1441,10 +1479,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Opretter forbindelse..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Tilgængelig"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"Ikke tilgængelig"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"I brug"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Indbygget skærm"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"HDMI-skærm"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlejring nr. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", sikker"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Der er tilsluttet en trådløs skærm"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Denne skærm vises på en anden enhed"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Afbryd forbindelsen"</string>
@@ -1453,7 +1493,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Forkert mønster"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Forkert adgangskode"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"Forkert pinkode"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Prøv igen om <xliff:g id="NUMBER">%d</xliff:g> sekunder."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Prøv igen om <xliff:g id="NUMBER">%1$d</xliff:g> sekunder."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Tegn dit mønster"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Indtast pinkode til SIM"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Indtast pinkode"</string>
@@ -1473,27 +1513,85 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Adgangskode"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Log ind"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Ugyldigt brugernavn eller ugyldig adgangskode."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Har du glemt dit brugernavn eller din adgangskode?"\n"Gå til "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Har du glemt dit brugernavn eller din adgangskode?\nGå til "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Kontoen kontrolleres…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Du har indtastet en forkert pinkode <xliff:g id="NUMBER_0">%d</xliff:g> gange. "\n\n"Prøv igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Du har indtastet din adgangskode forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. "\n\n"Prøv igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. "\n\n"Prøv igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Du har indtastet en forkert pinkode <xliff:g id="NUMBER_0">%d</xliff:g> gange. \n\nPrøv igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Du har indtastet din adgangskode forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. \n\nPrøv igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. \n\nPrøv igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Du har forsøgt at låse tabletten op forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> yderligere mislykkede forsøg nulstilles tabletten til fabriksindstillingerne, og alle brugerdata mistes."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Du har forsøgt at låse telefonen op forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> yderligere mislykkede forsøg, nulstilles telefonen til fabriksindstillingerne, og alle brugerdata mistes."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Du har forsøgt at låse tabletten op forkert <xliff:g id="NUMBER">%d</xliff:g> gange. Tabletten nulstilles til fabriksindstillingerne."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Du har forsøgt at låse telefonen op forkert <xliff:g id="NUMBER">%d</xliff:g> gange. Telefonen nulstilles til fabriksindstillingerne."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> yderligere mislykkede forsøg vil du blive bedt om at låse din tablet op ved hjælp af en e-mailkonto"\n\n" Prøv igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> yderligere mislykkede forsøg til vil du blive bedt om at låse din telefon op ved hjælp af en e-mailkonto."\n\n" Prøv igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> yderligere mislykkede forsøg vil du blive bedt om at låse din tablet op ved hjælp af en e-mailkonto\n\n Prøv igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> yderligere mislykkede forsøg til vil du blive bedt om at låse din telefon op ved hjælp af en e-mailkonto.\n\n Prøv igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Fjern"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Skal lydstyrken være over det anbefalede niveau?"\n"Du kan skade din hørelse ved at lytte ved høj lydstyrke i længere tid."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Skal lydstyrken være over det anbefalede niveau?\nDu kan skade din hørelse ved at lytte ved høj lydstyrke i længere tid."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Hold fortsat to fingre nede for at aktivere tilgængelighed."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Tilgængelighed aktiveret."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Tilgængelighed er annulleret."</string>
     <string name="user_switched" msgid="3768006783166984410">"Nuværende bruger <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Ejer"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Fejl"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Denne applikation understøtter ikke konti for begrænsede profiler"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Denne applikation understøtter ikke konti for begrænsede profiler"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Der blev ikke fundet nogen applikation, der kan håndtere denne handling"</string>
     <string name="revoke" msgid="5404479185228271586">"Tilbagekald"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Amerikansk \"Letter\""</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Amerikansk \"Government Letter\""</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Amerikansk \"Legal\""</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Amerikansk \"Junior Legal\""</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Amerikansk \"Ledger\""</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Amerikansk \"Tabloid\""</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Annulleret"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Fejl ved skrivning af indhold"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"ukendt"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Indtast administratorpinkoden"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Indtast pinkode"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Forkert"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Aktuel pinkode:"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Ny pinkode"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Bekræft den nye pinkode"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Opret en pinkode til ændring af begrænsninger"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"Pinkoderne stemmer ikke overens. Prøv igen."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"Pinkoden er for kort. Den skal være på mindst 4 tal."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Prøv igen om 1 sekund"</item>
+    <item quantity="other" msgid="4730868920742952817">"Prøv igen om <xliff:g id="COUNT">%d</xliff:g> sekunder"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Prøv igen senere"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Stryg fra skærmkanten for at se bjælken"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Stryg med fingeren fra skærmens kant for at se systembjælken"</string>
 </resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 50a7c8c..cbea74f 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -131,6 +131,11 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Zu viele <xliff:g id="CONTENT_TYPE">%s</xliff:g> gelöscht."</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Der Tablet-Speicher ist voll. Löschen Sie Dateien, um Speicherplatz freizugeben."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Der Handyspeicher ist voll! Löschen Sie Dateien, um Speicherplatz freizugeben."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Das Netzwerk wird möglicherweise überwacht."</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Eigene"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Tablet-Optionen"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Telefonoptionen"</string>
@@ -236,7 +241,7 @@
     <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Verbesserte Web-Bedienung aktivieren"</string>
     <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Skripts können installiert werden, um den Zugriff auf App-Inhalte zu erleichtern."</string>
     <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Text bei der Eingabe beobachten"</string>
-    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Einschließlich persönlicher Daten wie Kreditkartennummern und Passwörter."</string>
+    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Einschließlich personenbezogener Daten wie Kreditkartennummern und Passwörter."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"Statusleiste deaktivieren oder ändern"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Ermöglicht der App, die Statusleiste zu deaktivieren oder Systemsymbole hinzuzufügen oder zu entfernen"</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"Statusleiste"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Ermöglicht der App, Aufgaben in den Vorder- und Hintergrund zu verschieben, ohne dass dazu ein Eingreifen Ihrerseits notwendig ist."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"Aktive Apps beenden"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Ermöglicht der App, Aufgaben zu entfernen und die entsprechenden Apps zu beenden. Schädliche Apps können das Verhalten anderer Apps stören."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"Aktivitätsstapel verwalten"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Ermöglicht der App das Hinzufügen, Entfernen und Ändern der Aktivitätsstapel, in denen andere Apps ausgeführt werden. Schädliche Apps können das Verhalten anderer Apps beeinträchtigen."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"Beliebige Aktivität starten"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Ermöglicht der App, ungeachtet der Berechtigungen oder des Exportstatus beliebige Aktivitäten zu starten"</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"Bildschirmkompatibilität festlegen"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Ermöglicht dem Halter, sich an die Oberfläche einer Eingabemethode auf oberster Ebene zu binden. Sollte nie für normale Apps benötigt werden."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"An eine Bedienungshilfe binden"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Ermöglicht dem Halter, sich an die Oberfläche einer Bedienungshilfe auf oberster Ebene zu binden. Sollte nie für normale Apps benötigt werden."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"An einen Druckdienst binden"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Ermöglicht dem Inhaber, sich an die Oberfläche eines Druckdienstes auf oberster Ebene zu binden. Sollte für normale Apps nie benötigt werden."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"An Druck-Spooler-Dienst binden"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Ermöglicht dem Inhaber, sich an die Oberfläche eines Druck-Spooler-Dienstes auf oberster Ebene zu binden. Sollte für normale Apps nie benötigt werden."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"An NFC-Dienst binden"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Ermöglicht dem Inhaber die Bindung an Apps, die NFC-Karten emulieren. Dies sollte für normale Apps niemals notwendig sein."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"An einen Textdienst binden"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Ermöglicht dem Halter, sich an die Oberfläche eines Textdienstes auf oberster Ebene zu binden, z. B. eines Rechtschreibprüfungsdienstes. Sollte nie für normale Apps benötigt werden."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"An einen VPN-Dienst binden"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Ermöglicht dem Halter, sich an die Oberfläche eines Widget-Dienstes auf oberster Ebene zu binden. Sollte nie für normale Apps benötigt werden."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"Interaktion mit einem Geräteadministrator"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Ermöglicht dem Halter, Intents an einen Geräteadministrator zu senden. Sollte nie für normale Apps benötigt werden."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"Geräteadministrator hinzufügen oder entfernen"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Ermöglicht dem Inhaber, aktive Geräteadministratoren hinzuzufügen oder zu entfernen. Sollte für normale Apps nie benötigt werden."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"Bildschirmausrichtung ändern"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Ermöglicht der App, die Bildschirmdrehung jederzeit zu ändern. Sollte nie für normale Apps benötigt werden."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"Zeigergeschwindigkeit ändern"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Ermöglicht der App, die verschiedenen Protokolldateien des Systems zu lesen. So können allgemeine Informationen zu den auf Ihrem Telefon durchgeführten Aktionen eingesehen werden, darunter auch personenbezogene oder vertrauliche Daten."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"Für Wiedergabe beliebigen Mediendecodierer verwenden"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Ermöglicht der App, alle installierten Mediendecodierer zur Wiedergabe zu verwenden."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"Vertrauenswürdige Anmeldedaten verwalten"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Ermöglicht der App, CA-Zertifikate als vertrauenswürdige Anmeldedaten zu installieren und zu deinstallieren."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"Lese-/Schreibberechtigung für zu Diagnosegruppe gehörige Elemente"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Ermöglicht der App, alle Elemente in der Diagnosegruppe zu lesen und zu bearbeiten, etwa Dateien in \"/dev\". Dies könnte eine potenzielle Gefährdung für die Stabilität und Sicherheit des Systems darstellen und sollte NUR für hardwarespezifische Diagnosen des Herstellers oder Mobilfunkanbieters verwendet werden."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"App-Komponenten aktivieren oder deaktivieren"</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Erlaubt der App, WLAN-Anzeigen zu konfigurieren und eine Verbindung zu diesen herzustellen"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"WLAN-Anzeigen steuern"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Erlaubt der App, untergeordnete Funktionen von WLAN-Anzeigen zu steuern"</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"Audioausgabe erfassen"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Ermöglicht der App die Erfassung und Weiterleitung von Audioausgaben"</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"Videoausgabe erfassen"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Ermöglicht der App die Erfassung und Weiterleitung von Videoausgaben"</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"Sichere Videoausgabe erfassen"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Ermöglicht der App die Erfassung und Weiterleitung von sicheren Videoausgaben"</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"Audio-Einstellungen ändern"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Ermöglicht der App, globale Audio-Einstellungen zu ändern, etwa die Lautstärke und den Lautsprecher für die Ausgabe."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"Audio aufnehmen"</string>
@@ -525,6 +552,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"Ruhezustand deaktivieren"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Ermöglicht der App, den Ruhezustand des Tablets zu deaktivieren"</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Ermöglicht der App, den Ruhezustand des Telefons zu deaktivieren"</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"Tablet ein- oder ausschalten"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"Gerät ein- oder ausschalten"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Ermöglicht der App, das Tablet ein- oder auszuschalten"</string>
@@ -613,6 +646,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Ermöglicht der App, auf die SD-Karte zu schreiben"</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"Internen Medienspeicher ändern/löschen"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Ermöglicht der App, den Inhalt des internen Medienspeichers zu ändern"</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"Dokumentenspeicher verwalten"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"App kann Dokumentenspeicher verwalten"</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"Auf externen Speicher aller Nutzer zugreifen"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Ermöglicht der App, auf externen Speicher aller Nutzer zuzugreifen."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"Auf das Cache-Dateisystem zugreifen"</string>
@@ -625,22 +660,28 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Ermöglicht der App, Netzwerkrichtlinien zu verwalten und anwendungsspezifische Regeln festzulegen"</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"Zuordnung für Netzwerknutzung ändern"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Ermöglicht der App, die Art und Weise zu ändern, wie der Netzwerkverbrauch im Hinblick auf Apps berechnet wird. Nicht für normale Apps vorgesehen."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"Socket-Markierungen ändern"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Ermöglicht der App das Ändern von Socket-Markierungen für das Routing"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"Auf Benachrichtigungen zugreifen"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Ermöglicht der App das Abrufen, Überprüfen und Löschen von Benachrichtigungen, einschließlich Benachrichtigungen, die von anderen Apps gepostet wurden"</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"An Benachrichtigungs-Listener-Dienst binden"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Ermöglicht dem Inhaber, sich an die Oberfläche der obersten Ebene eines Benachrichtigungs-Listener-Dienstes zu binden. Sollte nie für normale Apps benötigt werden."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"Vom Mobilfunkanbieter bereitgestellte Konfigurations-App aufrufen"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Ermöglicht dem Inhaber, die vom Mobilfunkanbieter bereitgestellte Konfigurations-App aufzurufen. Sollte für normale Apps nie benötigt werden."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"Informationen zu den Netzwerkbedingungen erfassen"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Ermöglicht der App, Informationen zu den Netzwerkbedingungen zu erfassen. Sollte für normale Apps nie benötigt werden."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Passwortregeln festlegen"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Zulässige Länge und Zeichen für Passwörter zum Entsperren des Bildschirms festlegen"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Versuche zum Entsperren des Displays überwachen"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Anzahl der falsch eingegebenen Passwörter beim Entsperren des Displays überwachen und Tablet sperren oder alle Daten auf dem Tablet löschen, wenn zu häufig ein falsches Passwort eingegeben wird"</string>
     <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Anzahl der falsch eingegebenen Passwörter beim Entsperren des Bildschirms überwachen und Telefon sperren oder alle Daten auf dem Telefon löschen, wenn zu häufig ein falsches Passwort eingegeben wird"</string>
-    <string name="policylab_resetPassword" msgid="2620077191242688955">"Passwort zum Entsperren des Displays ändern"</string>
-    <string name="policydesc_resetPassword" msgid="605963962301904458">"Passwort zum Entsperren des Bildschirms ändern"</string>
+    <string name="policylab_resetPassword" msgid="2620077191242688955">"Passwort zum Entsperren des Bildschirms ändern"</string>
+    <string name="policydesc_resetPassword" msgid="605963962301904458">"Ändern Sie das Passwort zum Entsperren des Bildschirms."</string>
     <string name="policylab_forceLock" msgid="2274085384704248431">"Display sperren"</string>
     <string name="policydesc_forceLock" msgid="1141797588403827138">"Legen Sie fest, wie und wann der Bildschirm gesperrt wird."</string>
     <string name="policylab_wipeData" msgid="3910545446758639713">"Alle Daten löschen"</string>
     <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Auf Werkseinstellungen zurücksetzen und Daten auf dem Tablet ohne Warnung löschen"</string>
-    <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Auf Werkseinstellungen zurücksetzen und Daten auf dem Telefon ohne Warnung löschen"</string>
+    <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Setzen Sie das Telefon auf Werkseinstellungen zurück. Dabei werden alle Daten ohne Warnung gelöscht."</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Den globalen Proxy des Geräts festlegen"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Den bei aktivierter Richtlinie zu verwendenden globalen Proxy des Geräts festlegen. Nur der erste Geräteadministrator kann den gültigen globalen Proxy festlegen."</string>
     <string name="policylab_expirePassword" msgid="885279151847254056">"Ablauf von Sperr-Passwort festlegen"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo!"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +836,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Legen Sie eine SIM-Karte ein."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM-Karte fehlt oder ist nicht lesbar. Bitte legen Sie eine SIM-Karte ein."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"SIM-Karte unbrauchbar"</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Ihre SIM-Karte wurde dauerhaft deaktiviert."\n" Wenden Sie sich an Ihren Mobilfunkanbieter, um eine andere SIM-Karte zu erhalten."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Ihre SIM-Karte wurde dauerhaft deaktiviert.\n Wenden Sie sich an Ihren Mobilfunkanbieter, um eine andere SIM-Karte zu erhalten."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Schaltfläche für vorherigen Track"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Schaltfläche für nächsten Track"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Schaltfläche für Pause"</string>
@@ -808,11 +848,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Weitere Informationen erhalten Sie im Nutzerhandbuch oder beim Kundendienst."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"PIN eingeben"</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM-Karte wird entsperrt..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch gezeichnet. "\n\n"Bitte versuchen Sie es in <xliff:g id="NUMBER_1">%d</xliff:g> Sekunden noch einmal."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Sie haben Ihr Passwort <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch eingegeben."\n\n"Bitte versuchen Sie es in <xliff:g id="NUMBER_1">%d</xliff:g> Sekunden noch einmal."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Sie haben Ihr Passwort <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch eingegeben."\n\n"Bitte versuchen Sie es in <xliff:g id="NUMBER_1">%d</xliff:g> Sekunden noch einmal."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%d</xliff:g> weiteren erfolglosen Versuchen werden Sie aufgefordert, Ihr Tablet mithilfe Ihrer Google-Anmeldeinformationen zu entsperren."\n\n" Bitte versuchen Sie es in <xliff:g id="NUMBER_2">%d</xliff:g> Sekunden noch einmal."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%d</xliff:g> weiteren erfolglosen Versuchen werden Sie aufgefordert, Ihr Telefon mithilfe Ihrer Google-Anmeldeinformationen zu entsperren."\n\n"Bitte versuchen Sie es in <xliff:g id="NUMBER_2">%d</xliff:g> Sekunden noch einmal."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch gezeichnet. \n\nBitte versuchen Sie es in <xliff:g id="NUMBER_1">%d</xliff:g> Sekunden noch einmal."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Sie haben Ihr Passwort <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch eingegeben.\n\nBitte versuchen Sie es in <xliff:g id="NUMBER_1">%d</xliff:g> Sekunden noch einmal."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Sie haben Ihr Passwort <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch eingegeben.\n\nBitte versuchen Sie es in <xliff:g id="NUMBER_1">%d</xliff:g> Sekunden noch einmal."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%d</xliff:g> weiteren erfolglosen Versuchen werden Sie aufgefordert, Ihr Tablet mithilfe Ihrer Google-Anmeldeinformationen zu entsperren.\n\n Bitte versuchen Sie es in <xliff:g id="NUMBER_2">%d</xliff:g> Sekunden noch einmal."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%d</xliff:g> weiteren erfolglosen Versuchen werden Sie aufgefordert, Ihr Telefon mithilfe Ihrer Google-Anmeldeinformationen zu entsperren.\n\nBitte versuchen Sie es in <xliff:g id="NUMBER_2">%d</xliff:g> Sekunden noch einmal."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Sie haben <xliff:g id="NUMBER_0">%d</xliff:g> Mal erfolglos versucht, das Tablet zu entsperren. Nach <xliff:g id="NUMBER_1">%d</xliff:g> weiteren erfolglosen Versuchen wird das Tablet auf die Werkseinstellungen zurückgesetzt und alle Nutzerdaten gehen verloren."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Sie haben <xliff:g id="NUMBER_0">%d</xliff:g> Mal erfolglos versucht, das Telefon zu entsperren. Nach <xliff:g id="NUMBER_1">%d</xliff:g> weiteren erfolglosen Versuchen wird das Telefon auf die Werkseinstellungen zurückgesetzt und alle Nutzerdaten gehen verloren."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Sie haben <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Das Tablet wird nun auf die Werkseinstellungen zurückgesetzt."</string>
@@ -826,7 +866,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Passwort"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Anmelden"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Ungültiger  Nutzername oder ungültiges Passwort."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Nutzernamen oder Passwort vergessen?"\n"Besuchen Sie "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Nutzernamen oder Passwort vergessen?\nBesuchen Sie "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Überprüfung..."</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Entsperren"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Ton ein"</string>
@@ -874,7 +914,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Navigation bestätigen"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Diese Seite verlassen"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Auf dieser Seite bleiben"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Möchten Sie diese Seite wirklich verlassen?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nMöchten Sie diese Seite wirklich verlassen?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Bestätigen"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Tipp: Zum Vergrößern und Verkleinern zweimal tippen"</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"AutoFill"</string>
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"\"<xliff:g id="APPLICATION">%1$s</xliff:g>\" wurde beendet."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Der Prozess \"<xliff:g id="PROCESS">%1$s</xliff:g>\" wurde beendet."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> reagiert nicht."\n\n"Möchten Sie die App schließen?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Aktivität \"<xliff:g id="ACTIVITY">%1$s</xliff:g>\" reagiert nicht."\n\n"Möchten Sie sie beenden?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> reagiert nicht.\n\nMöchten Sie die App schließen?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Aktivität \"<xliff:g id="ACTIVITY">%1$s</xliff:g>\" reagiert nicht.\n\nMöchten Sie sie beenden?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> reagiert nicht. Möchten Sie die App schließen?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Prozess \"<xliff:g id="PROCESS">%1$s</xliff:g>\" reagiert nicht."\n\n"Möchten Sie ihn beenden?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Prozess \"<xliff:g id="PROCESS">%1$s</xliff:g>\" reagiert nicht.\n\nMöchten Sie ihn beenden?"</string>
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"Bericht"</string>
     <string name="wait" msgid="7147118217226317732">"Warten"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"Die Seite reagiert nicht mehr."\n\n"Möchten Sie die Seite schließen?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Die Seite reagiert nicht mehr.\n\nMöchten Sie die Seite schließen?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"App umgeleitet"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> wird jetzt ausgeführt."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> wurde ursprünglich gestartet."</string>
@@ -1256,6 +1296,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Ermöglicht der App das Aufrufen des Standard-Containerdienstes zum Kopieren von Inhalten. Nicht für normale Apps vorgesehen."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Medienausgabe umleiten"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Ermöglicht einer App, die Medienausgabe auf andere externe Geräte umzuleiten."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Zugriff auf mit Keyguard geschützten Speicher"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Ermöglicht einer App den Zugriff auf mit Keyguard geschützten Speicher"</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Anzeige und Ausblenden des Keyguard steuern"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Apps können den Keyguard steuern."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Für Zoomeinstellung zweimal berühren"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Widget konnte nicht hinzugefügt werden."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Los"</string>
@@ -1265,15 +1309,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Fertig"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Zurück"</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Ausführen"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Nummer"\n"mit <xliff:g id="NUMBER">%s</xliff:g> wählen"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Neuer Kontakt"\n"mit <xliff:g id="NUMBER">%s</xliff:g> erstellen"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Nummer\nmit <xliff:g id="NUMBER">%s</xliff:g> wählen"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Neuer Kontakt\nmit <xliff:g id="NUMBER">%s</xliff:g> erstellen"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Die folgenden Apps benötigen die Berechtigung zum aktuellen und zukünftigen Zugriff auf Ihr Konto."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Möchten Sie diese Anfrage zulassen?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Zugriffsanforderung"</string>
     <string name="allow" msgid="7225948811296386551">"Zulassen"</string>
     <string name="deny" msgid="2081879885755434506">"Ablehnen"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Berechtigung angefordert"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Berechtigung angefordert"\n"für Konto <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Berechtigung angefordert\nfür Konto <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Eingabemethode"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Synchronisieren"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Bedienungshilfen"</string>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Alle anzeigen"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Aktivität wählen"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Teilen mit"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Gerät gesperrt"</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Wird gesendet..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Browser starten?"</string>
@@ -1441,10 +1484,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Verbindung wird hergestellt..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Verfügbar"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"Nicht verfügbar"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"In Verwendung"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Integrierter Bildschirm"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"HDMI-Bildschirm"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlay-Nr. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", sicher"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Kabellose Übertragung (WiDi) ist aktiviert."</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Dieser Bildschirm wird auf einem anderen Gerät angezeigt."</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Verbindung trennen"</string>
@@ -1453,7 +1498,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Falsches Muster"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Falsches Passwort"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"Falsche PIN"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Versuchen Sie es in <xliff:g id="NUMBER">%d</xliff:g> Sekunden erneut."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Versuchen Sie es in <xliff:g id="NUMBER">%1$d</xliff:g> Sekunden erneut."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Muster zeichnen"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM-PIN eingeben"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN eingeben"</string>
@@ -1473,27 +1518,85 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Passwort"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Anmelden"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Ungültiger Nutzername oder ungültiges Passwort"</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Nutzernamen oder Passwort vergessen?"\n"Besuchen Sie "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Nutzernamen oder Passwort vergessen?\nBesuchen Sie "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Konto wird geprüft…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Sie haben Ihre PIN <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch eingegeben."\n\n"Versuchen Sie es in <xliff:g id="NUMBER_1">%d</xliff:g> Sekunden erneut."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Sie haben Ihr Passwort <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch eingegeben."\n\n"Versuchen Sie es in <xliff:g id="NUMBER_1">%d</xliff:g> Sekunden erneut."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch gezeichnet. "\n\n"Versuchen Sie es in <xliff:g id="NUMBER_1">%d</xliff:g> Sekunden erneut."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Sie haben Ihre PIN <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch eingegeben.\n\nVersuchen Sie es in <xliff:g id="NUMBER_1">%d</xliff:g> Sekunden erneut."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Sie haben Ihr Passwort <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch eingegeben.\n\nVersuchen Sie es in <xliff:g id="NUMBER_1">%d</xliff:g> Sekunden erneut."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch gezeichnet. \n\nVersuchen Sie es in <xliff:g id="NUMBER_1">%d</xliff:g> Sekunden erneut."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Sie haben <xliff:g id="NUMBER_0">%d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Nach <xliff:g id="NUMBER_1">%d</xliff:g> weiteren erfolglosen Versuchen wird das Tablet auf die Werkseinstellungen zurückgesetzt und alle Nutzerdaten gehen verloren."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Sie haben <xliff:g id="NUMBER_0">%d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Nach <xliff:g id="NUMBER_1">%d</xliff:g> weiteren erfolglosen Versuchen wird das Telefon auf die Werkseinstellungen zurückgesetzt und alle Nutzerdaten gehen verloren."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Sie haben <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Das Tablet wird nun auf die Werkseinstellungen zurückgesetzt."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Sie haben <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Das Telefon wird nun auf die Werkseinstellungen zurückgesetzt."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%d</xliff:g> weiteren erfolglosen Versuchen werden Sie aufgefordert, Ihr Tablet mithilfe eines E-Mail-Kontos zu entsperren."\n\n" Versuchen Sie es in <xliff:g id="NUMBER_2">%d</xliff:g> Sekunden erneut."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%d</xliff:g> weiteren erfolglosen Versuchen werden Sie aufgefordert, Ihr Telefon mithilfe eines E-Mail-Kontos zu entsperren."\n\n" Versuchen Sie es in <xliff:g id="NUMBER_2">%d</xliff:g> Sekunden erneut."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%d</xliff:g> weiteren erfolglosen Versuchen werden Sie aufgefordert, Ihr Tablet mithilfe eines E-Mail-Kontos zu entsperren.\n\n Versuchen Sie es in <xliff:g id="NUMBER_2">%d</xliff:g> Sekunden erneut."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%d</xliff:g> weiteren erfolglosen Versuchen werden Sie aufgefordert, Ihr Telefon mithilfe eines E-Mail-Kontos zu entsperren.\n\n Versuchen Sie es in <xliff:g id="NUMBER_2">%d</xliff:g> Sekunden erneut."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Entfernen"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Lautstärke über den Schwellenwert anheben?"\n"Wenn Sie über längere Zeiträume hinweg Musik in hoher Lautstärke hören, kann dies Ihr Gehör schädigen."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Lautstärke über den Schwellenwert anheben?\nWenn Sie über längere Zeiträume hinweg Musik in hoher Lautstärke hören, kann dies Ihr Gehör schädigen."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Drücken Sie mit zwei Fingern, um die Bedienungshilfen zu aktivieren."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Bedienungshilfen aktiviert"</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Bedienungshilfen abgebrochen"</string>
     <string name="user_switched" msgid="3768006783166984410">"Aktueller Nutzer <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="owner_name" msgid="2716755460376028154">"Eigentümer"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Fehler"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Diese App unterstützt keine Konten für eingeschränkte Profile."</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Diese App unterstützt keine Konten für eingeschränkte Profile."</string>
     <string name="app_not_found" msgid="3429141853498927379">"Für diese Aktion wurde keine App gefunden."</string>
     <string name="revoke" msgid="5404479185228271586">"Aufheben"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Abgebrochen"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Fehler beim Schreiben von Inhalten"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"Unbekannt"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Administrator-PIN eingeben"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN eingeben"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Falsch"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Aktuelle PIN"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Neue PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Neue PIN bestätigen"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"PIN für das Ändern von Einschränkungen erstellen"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"Die PINs stimmen nicht überein. Bitte versuchen Sie es erneut."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"Die PIN ist zu kurz. Sie muss mindestens 4 Ziffern umfassen."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"In 1 Sek. wiederholen"</item>
+    <item quantity="other" msgid="4730868920742952817">"In <xliff:g id="COUNT">%d</xliff:g> Sek. wiederholen"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Später erneut versuchen"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Zum Einblenden der Leiste vom Rand weg wischen"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Zum Einblenden der Systemleiste vom Rand weg wischen"</string>
 </resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 968aba9..ca628bf 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -131,6 +131,11 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Πάρα πολλές <xliff:g id="CONTENT_TYPE">%s</xliff:g> διαγραφές."</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Ο αποθηκευτικός χώρος του tablet είναι πλήρης. Διαγράψτε μερικά αρχεία για να δημιουργήσετε ελεύθερο χώρο."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Ο αποθηκευτικός χώρος του τηλεφώνου είναι πλήρης. Διαγράψτε μερικά αρχεία για να δημιουργήσετε ελεύθερο χώρο."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Το δίκτυο ενδέχεται να παρακολουθείται"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Για εμένα"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Επιλογές tablet"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Επιλογές τηλεφώνου"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Επιτρέπει στην εφαρμογή τη μετακίνηση εργασιών στο προσκήνιο και το παρασκήνιο. Η εφαρμογή μπορεί να το κάνει αυτό χωρίς να καταχωρίσετε δεδομένα εισόδου."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"διακοπή εκτέλεσης εφαρμογών"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Επιτρέπει στην εφαρμογή την κατάργηση ενεργειών και την απομάκρυνση των εφαρμογών τους. Τυχόν κακόβουλες εφαρμογές ενδέχεται να διαταράξουν τη λειτουργία άλλων εφαρμογών."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"διαχείριση στοιβών δραστηριότητας"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Επιτρέπει στην εφαρμογή την προσθήκη, την κατάργηση και την τροποποίηση των στοιβών δραστηριότητας στις οποίες εκτελούνται άλλες εφαρμογές. Οι κακόβουλες εφαρμογές ενδέχεται να προκαλέσουν προβλήματα στη συμπεριφορά άλλων συσκευών."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"έναρξη οποιασδήποτε δραστηριότητας"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Επιτρέπει στην εφαρμογή την έναρξη οποιασδήποτε δραστηριότητας, ανεξάρτητα από την προστασία αδειών ή την κατάσταση εξαγωγής."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"ρύθμιση συμβατότητας οθόνης"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Επιτρέπει στον κάτοχο τη δέσμευση στη διεπαφή ανωτάτου επιπέδου μιας μεθόδου εισόδου. Δεν απαιτείται για συνήθεις εφαρμογές."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"δέσμευση σε υπηρεσία προσβασιμότητας"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Επιτρέπει στον κάτοχο τη δέσμευση στη διεπαφή ανώτατου επιπέδου μιας υπηρεσίας προσβασιμότητας. Δεν απαιτείται σε κανονικές εφαρμογές."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"δέσμευση σε υπηρεσία εκτύπωσης"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Επιτρέπει στον κάτοχο τη δέσμευση στη διεπαφή ανωτάτου επιπέδου μιας υπηρεσίας εκτύπωσης. Δεν απαιτείται για κανονικές εφαρμογές."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"σύνδεση με μια υπηρεσία εκτύπωσης σε ουράς"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Επιτρέπει στον κάτοχο τη σύνδεση στη διεπαφή ανωτάτου επιπέδου μιας υπηρεσίας εκτύπωσης σε ουρά. Δεν απαιτείται για κανονικές εφαρμογές."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"σύνδεση με υπηρεσία NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Δίνει στον κάτοχο τη δυνατότητα σύνδεσης με εφαρμογές που προσομοιώνουν κάρτες NFC. Δεν ζητείται ποτέ για κανονικές εφαρμογές."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"δέσμευση σε υπηρεσία ανταλλαγής μηνυμάτων"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Επιτρέπει στον κάτοχο τη σύνδεση με τη διεπαφή ανωτέρου επιπέδου μιας υπηρεσίας ανταλλαγής μηνυμάτων (π.χ. SpellCheckerService). Δεν είναι απαραίτητο για κανονικές εφαρμογές."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"δέσμευση σε υπηρεσία VPN"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Επιτρέπει στον κάτοχο τη δέσμευση στη διεπαφή ανωτάτου επιπέδου μιας υπηρεσίας γραφικών στοιχείων. Δεν απαιτείται για κανονικές εφαρμογές."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"επικοινωνία με έναν διαχειριστή συσκευής"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Επιτρέπει στον κάτοχο την αποστολή στόχων σε έναν διαχειριστή συσκευής. Δεν είναι απαραίτητο για συνήθεις εφαρμογές."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"προσθήκη ή κατάργηση ενός διαχειριστή συσκευής"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Επιτρέπει στον κάτοχο να προσθέτει ή να καταργεί ενεργούς διαχειριστές συσκευών. Δεν θα πρέπει να ζητείται ποτέ για κανονικές εφαρμογές."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"αλλαγή προσανατολισμού οθόνης"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Επιτρέπει στην εφαρμογή την αλλαγή της περιστροφής της οθόνης ανά πάσα στιγμή. Δεν απαιτείται για συνήθεις εφαρμογές."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"αλλαγή ταχύτητας δείκτη"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Επιτρέπει στην εφαρμογή την ανάγνωση των αρχείων καταγραφής του συστήματος. Έτσι, μπορεί να ανακαλύψει γενικές πληροφορίες σχετικά με τις δραστηριότητές σας στο τηλέφωνο, συμπεριλαμβάνοντας πιθανώς και προσωπικές ή ιδιωτικές πληροφορίες."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"χρήση οποιουδήποτε αποκωδικοποιητή μέσων για αναπαραγωγή"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Επιτρέπει στην εφαρμογή τη χρήση οποιουδήποτε εγκατεστημένου αποκωδικοποιητή μέσων για αναπαραγωγή."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"διαχείριση αξιόπιστων διαπιστευτηρίων"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Επιτρέπει στην εφαρμογή την εγκατάσταση και την απεγκατάσταση πιστοποιητικών CA ως αξιόπιστων διαπιστευτηρίων."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"ανάγνωση/εγγραφή σε πόρους που ανήκουν στο διαγνωστικό"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Επιτρέπει στην εφαρμογή την ανάγνωση και την εγγραφή σε οποιονδήποτε πόρο που ανήκει στην ομάδα διαγνωστικού (π.χ. αρχεία στον κατάλογο /dev). Αυτό ενδέχεται να επηρεάσει την σταθερότητα και την ασφάλεια του συστήματος. Θα πρέπει να χρησιμοποιείται ΜΟΝΟ για διαγνωστικά υλικού από τον κατασκευαστή ή τον χειριστή."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"ενεργοποίηση ή απενεργοποίηση στοιχείων εφαρμογής"</string>
@@ -462,6 +479,14 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Επιτρέπει τη διαμόρφωση της εφαρμογής και τη σύνδεσης σε οθόνες Wifi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"έλεγχος οθονών Wifi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Επιτρέπει στην εφαρμογή τον έλεγχο των λειτουργιών χαμηλού επιπέδου των οθονών Wifi."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"έγγραφή εξόδου ήχου"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Δίνει στην εφαρμογή τη δυνατότητα εγγραφής και ανακατεύθυνσης εξόδου ήχου."</string>
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Ανίχνευση ενεργών λέξεων"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Επιτρέπει στην εφαρμογή την εγγραφή ήχου για ανίχνευση ενεργών λέξεων. Η εγγραφή μπορεί να πραγματοποιηθεί στο παρασκήνιο, αλλά δεν εμποδίζει την εγγραφή ήχου από άλλες πηγές (π.χ. βιντεοκάμερα)."</string>
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"έγγραφή εξόδου βίντεο"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Δίνει στην εφαρμογή τη δυνατότητα εγγραφής και ανακατεύθυνσης εξόδου βίντεο."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"έγγραφή ασφαλούς εξόδου βίντεο"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Δίνει στην εφαρμογή τη δυνατότητα εγγραφής και ανακατεύθυνσης ασφαλούς εξόδου βίντεο."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"αλλαγή των ρυθμίσεων ήχου"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Επιτρέπει στην εφαρμογή την τροποποίηση καθολικών ρυθμίσεων ήχου, όπως η ένταση και ποιο ηχείο χρησιμοποιείται για έξοδο."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"εγγραφή ήχου"</string>
@@ -525,6 +550,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"παρεμπόδιση μετάβασης του τηλεφώνου σε κατάσταση αδράνειας"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Επιτρέπει στην εφαρμογή την παρεμπόδιση της μετάβασης του tablet σε κατάσταση αδράνειας."</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">"Επιτρέπει στην εφαρμογή να χρησιμοποιεί τον πομπό υπερύθρων του tablet."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Επιτρέπει στην εφαρμογή να χρησιμοποιεί τον πομπό υπερύθρων του τηλεφώνου."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"ενεργοποίηση και απενεργοποίηση tablet"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"ενεργοποίηση και απενεργοποίηση τηλεφώνου"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Επιτρέπει στην εφαρμογή να ενεργοποιήσει ή να απενεργοποιήσει το tablet."</string>
@@ -613,6 +641,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Επιτρέπει στην εφαρμογή την εγγραφή στην κάρτα SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"τροπ./διαγ. περ. απ. εσ. μνήμ."</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Επιτρέπει στην εφαρμογή να τροποποιήσει τα περιεχόμενα των εσωτερικών μέσων αποθήκευσης."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"διαχείριση αποθ.χώρου εγγράφων"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Επιτρέπει στην εφαρμογή τη διαχείριση του αποθηκευτικού χώρου εγγράφων."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"πρόσβ.εξωτ.χωρ. αποθ. όλων των χρηστ."</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Επιτρέπει στην εφαρμογή να αποκτήσει πρόσβαση σε εξωτερικό χώρο αποθήκευσης για όλους τους χρήστες."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"πρόσβαση στο σύστημα αρχείων προσωρινής μνήμης"</string>
@@ -625,10 +655,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Επιτρέπει στην εφαρμογή τη διαχείριση των πολιτικών δικτύου και τον ορισμό κανόνων για ορισμένες εφαρμογές."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"τροποποίηση υπολογισμού χρήσης δικτύου"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Επιτρέπει στην εφαρμογή την τροποποίηση του τρόπου υπολογισμού της χρήσης δικτύου έναντι των εφαρμογών. Δεν προορίζεται για χρήση από συνήθεις εφαρμογές."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"τροποποίηση σημείων υποδοχής"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Επιτρέπει στην εφαρμογή την τροποποίηση σημείων υποδοχής για δρομολόγηση"</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_invokeCarrierSetup" msgid="3699600833975117478">"κλήση της εφαρμογής διαμόρφωσης που παρέχεται από την εταιρεία κινητής τηλεφωνίας"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Επιτρέπει στον κάτοχο την κλήση της εφαρμογής διαμόρφωσης που παρέχεται από την εταιρεία κινητής τηλεφωνίας. Δεν απαιτείται για κανονικές εφαρμογές."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"λήψη παρατηρήσεων σχετικά με την κατάσταση δικτύου"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Επιτρέπει σε μια εφαρμογή να λαμβάνει παρατηρήσεις σχετικά με την κατάσταση δικτύου. Δεν θα πρέπει να απαιτείται ποτέ για κανονικές εφαρμογές."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Ορισμός κανόνων κωδικού πρόσβασης"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Έλεγχος του μεγέθους και των χαρακτήρων που επιτρέπονται στους κωδικούς πρόσβασης ξεκλειδώματος οθόνης."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Παρακολούθηση προσπαθειών ξεκλειδώματος οθόνης"</string>
@@ -738,8 +774,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +831,7 @@
     <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">"Η κάρτα SIM έχει απενεργοποιηθεί οριστικά.\n Επικοινωνήστε με τον παροχέα υπηρεσιών ασύρματου δικτύου για να λάβετε μια νέα κάρτα SIM."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Κουμπί προηγούμενου κομματιού"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Κουμπί επόμενου κομματιού"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Κουμπί παύσης"</string>
@@ -808,11 +843,11 @@
     <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">%d</xliff:g> φορές. "\n\n"Προσπαθήστε ξανά σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλεπτα."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Έχετε πληκτρολογήσει τον κωδικό πρόσβασης εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. "\n\n"Προσπαθήστε ξανά σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλεπτα."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Έχετε πληκτρολογήσει τον αριθμό σας PIN εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. "\n\n"Προσπαθήστε ξανά σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλεπτα."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Σχεδιάσατε το μοτίβο ξεκλειδώματος εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> ανεπιτυχείς προσπάθειες ακόμη, θα σας ζητηθεί να ξεκλειδώσετε το tablet σας με τη χρήση της σύνδεσής σας Google."\n\n" Προσπαθήστε ξανά σε <xliff:g id="NUMBER_2">%d</xliff:g> δευτερόλεπτα."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Σχεδιάσατε το μοτίβο ξεκλειδώματος εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> ανεπιτυχείς προσπάθειες ακόμη, θα σας ζητηθεί να ξεκλειδώσετε το τηλέφωνό σας με τη χρήση της σύνδεσής σας Google."\n\n" Προσπαθήστε ξανά σε <xliff:g id="NUMBER_2">%d</xliff:g> δευτερόλεπτα."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Σχεδιάσατε εσφαλμένα το μοτίβο ξεκλειδώματος<xliff:g id="NUMBER_0">%d</xliff:g> φορές. \n\nΠροσπαθήστε ξανά σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλεπτα."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Έχετε πληκτρολογήσει τον κωδικό πρόσβασης εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. \n\nΠροσπαθήστε ξανά σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλεπτα."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Έχετε πληκτρολογήσει τον αριθμό σας PIN εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. \n\nΠροσπαθήστε ξανά σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλεπτα."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Σχεδιάσατε το μοτίβο ξεκλειδώματος εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> ανεπιτυχείς προσπάθειες ακόμη, θα σας ζητηθεί να ξεκλειδώσετε το tablet σας με τη χρήση της σύνδεσής σας Google.\n\n Προσπαθήστε ξανά σε <xliff:g id="NUMBER_2">%d</xliff:g> δευτερόλεπτα."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Σχεδιάσατε το μοτίβο ξεκλειδώματος εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> ανεπιτυχείς προσπάθειες ακόμη, θα σας ζητηθεί να ξεκλειδώσετε το τηλέφωνό σας με τη χρήση της σύνδεσής σας Google.\n\n Προσπαθήστε ξανά σε <xliff:g id="NUMBER_2">%d</xliff:g> δευτερόλεπτα."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Προσπαθήσατε να ξεκλειδώσετε εσφαλμένα το tablet <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> προσπάθειες, το tablet θα επαναφερθεί στις εργοστασιακές ρυθμίσεις και όλα τα δεδομένα χρήστη θα χαθούν."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Προσπαθήσατε να ξεκλειδώσετε εσφαλμένα το τηλέφωνο <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> προσπάθειες, το τηλέφωνο θα επαναφερθεί στις εργοστασιακές ρυθμίσεις και όλα τα δεδομένα χρήστη θα χαθούν."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Προσπαθήσατε να ξεκλειδώσετε εσφαλμένα το tablet <xliff:g id="NUMBER">%d</xliff:g> φορές. Το tablet θα επαναφερθεί στην εργοστασιακή προεπιλογή."</string>
@@ -826,7 +861,7 @@
     <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_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>
@@ -874,7 +909,7 @@
     <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="autofill_this_form" msgid="4616758841157816676">"Αυτόματη συμπλήρωση"</string>
@@ -1080,14 +1115,14 @@
     <string name="aerr_application" msgid="932628488013092776">"Δυστυχώς, η εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g> έχει σταματήσει."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Δυστυχώς, η διαδικασία <xliff:g id="PROCESS">%1$s</xliff:g> έχει σταματήσει."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"Η εφαρμογή <xliff:g id="APPLICATION">%2$s</xliff:g> δεν ανταποκρίνεται."\n\n"Θέλετε να την κλείσετε;"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Η δραστηριότητα <xliff:g id="ACTIVITY">%1$s</xliff:g> δεν ανταποκρίνεται."\n\n"Θέλετε να την κλείσετε;"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"Η εφαρμογή <xliff:g id="APPLICATION">%2$s</xliff:g> δεν ανταποκρίνεται.\n\nΘέλετε να την κλείσετε;"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Η δραστηριότητα <xliff:g id="ACTIVITY">%1$s</xliff:g> δεν ανταποκρίνεται.\n\nΘέλετε να την κλείσετε;"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"Η εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g> δεν ανταποκρίνεται. Θέλετε να την κλείσετε;"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Η διεργασία <xliff:g id="PROCESS">%1$s</xliff:g> δεν ανταποκρίνεται."\n\n"Θέλετε να την κλείσετε;"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Η διεργασία <xliff:g id="PROCESS">%1$s</xliff:g> δεν ανταποκρίνεται.\n\nΘέλετε να την κλείσετε;"</string>
     <string name="force_close" msgid="8346072094521265605">"ΟΚ"</string>
     <string name="report" msgid="4060218260984795706">"Αναφορά"</string>
     <string name="wait" msgid="7147118217226317732">"Αναμονή"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"Η σελίδα δεν ανταποκρίνεται πια."\n\n"Θέλετε να την κλείσετε;"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Η σελίδα δεν ανταποκρίνεται πια.\n\nΘέλετε να την κλείσετε;"</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>
@@ -1256,6 +1291,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Επιτρέπει στην εφαρμογή την κλήση της προεπιλεγμένης υπηρεσίας κοντέινερ για την αντιγραφή περιεχομένου. Δεν χρησιμοποιείται από συνήθεις εφαρμογές."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Διαγραφή διαδρομής δεδομένων εξόδου μέσων"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Επιτρέπει σε μια εφαρμογή τη διαγραφή διαδρομής δεδομένων εξόδου μέσων σε άλλες εξωτερικές συσκευές."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Πρόσβαση στον ασφαλή αποθηκευτικό χώρο με κλείδωμα"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Επιτρέπει σε μια εφαρμογή να αποκτήσει πρόσβαση στον ασφαλή αποθηκευτικό χώρο με κλείδωμα."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Έλεγχος εμφάνισης και απόκρυψης κλειδώματος πληκτρολογίου"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Επιτρέπει σε μια εφαρμογή τον έλεγχο του κλειδώματος πληκτρολογίου."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Αγγίξτε δύο φορές για έλεγχο εστίασης"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Δεν ήταν δυνατή η προσθήκη του γραφικού στοιχείου."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Μετάβαση"</string>
@@ -1265,15 +1304,15 @@
     <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">"Κλήση αριθμού"\n"με τη χρήση <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Δημιουργία επαφής"\n"με τη χρήση του <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Κλήση αριθμού\nμε τη χρήση <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Δημιουργία επαφής\nμε τη χρήση του <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Η παρακάτω εφαρμογή ή οι παρακάτω εφαρμογές ζητούν άδεια για άμεση πρόσβαση στο λογαριασμό σας, η οποία θα ισχύει και για μελλοντική χρήση."</string>
     <string name="grant_credentials_permission_message_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">"Ζητήθηκε άδεια"\n"για τον λογαριασμό <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Ζητήθηκε άδεια\nγια τον λογαριασμό <xliff:g id="ACCOUNT">%s</xliff:g>."</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>
@@ -1420,7 +1459,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Εμφάνιση όλων"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Επιλογή δραστηριότητας"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Κοινή χρήση με"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Η συσκευή κλειδώθηκε."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Γίνεται αποστολή…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Εκκίνηση προγράμματος περιήγησης;"</string>
@@ -1441,10 +1479,12 @@
     <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>
+    <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_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="wifi_display_notification_title" msgid="2223050649240326557">"Έχει συνδεθεί ασύρματη οθόνη"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Αυτή η οθόνη εμφανίζεται σε μια άλλη συσκευή"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Αποσύνδεση"</string>
@@ -1453,7 +1493,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">%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>
@@ -1473,27 +1513,85 @@
     <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_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">%d</xliff:g> φορές. "\n\n"Δοκιμάστε ξανά σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλεπτα."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Έχετε πληκτρολογήσει τον κωδικό πρόσβασης εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. "\n\n"Δοκιμάστε ξανά σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλεπτα."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Σχεδιάσατε εσφαλμένα το μοτίβο ξεκλειδώματος <xliff:g id="NUMBER_0">%d</xliff:g> φορές. "\n\n"Δοκιμάστε ξανά σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλετπα."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Έχετε πληκτρολογήσει εσφαλμένα τον κωδικό σας PIN <xliff:g id="NUMBER_0">%d</xliff:g> φορές. \n\nΔοκιμάστε ξανά σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλεπτα."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Έχετε πληκτρολογήσει τον κωδικό πρόσβασης εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. \n\nΔοκιμάστε ξανά σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλεπτα."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Σχεδιάσατε εσφαλμένα το μοτίβο ξεκλειδώματος <xliff:g id="NUMBER_0">%d</xliff:g> φορές. \n\nΔοκιμάστε ξανά σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλετπα."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Προσπαθήσατε να ξεκλειδώσετε εσφαλμένα το tablet <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> προσπάθειες, το tablet θα επαναφερθεί στις εργοστασιακές ρυθμίσεις και όλα τα δεδομένα χρήστη θα χαθούν."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Προσπαθήσατε να ξεκλειδώσετε εσφαλμένα το τηλέφωνο <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> προσπάθειες, το τηλέφωνο θα επαναφερθεί στις εργοστασιακές ρυθμίσεις και όλα τα δεδομένα χρήστη θα χαθούν."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Προσπαθήσατε να ξεκλειδώσετε εσφαλμένα το tablet <xliff:g id="NUMBER">%d</xliff:g> φορές. Το tablet θα επαναφερθεί στις εργοστασιακές ρυθμίσεις."</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">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> ανεπιτυχείς προσπάθειες ακόμη, θα σας ζητηθεί να ξεκλειδώσετε το tablet σας με τη χρήση ενός λογαριασμού ηλεκτρονικού ταχυδρομείου."\n\n" Δοκιμάστε να συνδεθείτε ξανά σε <xliff:g id="NUMBER_2">%d</xliff:g> δευτερόλεπτα."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Σχεδιάσατε το μοτίβο ξεκλειδώματος εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> ανεπιτυχείς προσπάθειες ακόμη, θα σας ζητηθεί να ξεκλειδώσετε το τηλέφωνό σας με τη χρήση ενός λογαριασμού ηλεκτρονικού ταχυδρομείου."\n\n" Δοκιμάστε ξανά σε <xliff:g id="NUMBER_2">%d</xliff:g> δευτερόλεπτα."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Σχεδιάσατε το μοτίβο ξεκλειδώματος εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> ανεπιτυχείς προσπάθειες ακόμη, θα σας ζητηθεί να ξεκλειδώσετε το tablet σας με τη χρήση ενός λογαριασμού ηλεκτρονικού ταχυδρομείου.\n\n Δοκιμάστε να συνδεθείτε ξανά σε <xliff:g id="NUMBER_2">%d</xliff:g> δευτερόλεπτα."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Σχεδιάσατε το μοτίβο ξεκλειδώματος εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> ανεπιτυχείς προσπάθειες ακόμη, θα σας ζητηθεί να ξεκλειδώσετε το τηλέφωνό σας με τη χρήση ενός λογαριασμού ηλεκτρονικού ταχυδρομείου.\n\n Δοκιμάστε ξανά σε <xliff:g id="NUMBER_2">%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="7324161939475478066">"Αυξάνετε την ένταση ήχου πάνω από το επίπεδο ασφαλείας;"\n"Αν ακούτε μουσική σε υψηλή ένταση για μεγάλο χρονικό διάστημα ενδέχεται να προκληθεί βλάβη στην ακοή σας."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Αυξάνετε την ένταση ήχου πάνω από το επίπεδο ασφαλείας;\nΑν ακούτε μουσική σε υψηλή ένταση για μεγάλο χρονικό διάστημα ενδέχεται να προκληθεί βλάβη στην ακοή σας."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Αγγίξτε παρατεταμένα με δύο δάχτυλα για να ενεργοποιήσετε τη λειτουργία προσβασιμότητας."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Ενεργοποιήθηκε η προσβασιμότητα."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Η λειτουργία προσβασιμότητας ακυρώθηκε."</string>
     <string name="user_switched" msgid="3768006783166984410">"Τρέχων χρήστης <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="app_no_restricted_accounts" msgid="4011285085817350390">"Αυτή η εφαρμογή δεν υποστηρίζει λογαριασμούς για περιορισμένα προφίλ"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Αυτή η εφαρμογή δεν υποστηρίζει λογαριασμούς για περιορισμένα προφίλ"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Δεν υπάρχει εφαρμογή για τη διαχείριση αυτής της ενέργειας"</string>
     <string name="revoke" msgid="5404479185228271586">"Ανάκληση"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Επιστολή"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Κρατική επιστολή"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Νομικό"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Λογιστικό"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Ακυρώθηκε"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Σφάλμα κατά την εγγραφή περιεχομένου"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"άγνωστο"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Εισαγάγετε κωδικό 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>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Νέος κωδικός PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Επιβεβαίωση νέου κωδικού PIN"</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_too_short" msgid="8173982756265777792">"Το PIN είναι υπερβολικά μικρό. Πρέπει να έχει μέγεθος τουλάχιστον 4 χαρακτήρων."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Επανάληψη σε 1 δευτ."</item>
+    <item quantity="other" msgid="4730868920742952817">"Επανάληψη σε <xliff:g id="COUNT">%d</xliff:g> δευτ."</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Δοκιμάστε ξανά αργότερα"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Σύρετε την άκρη για εμφάν.γραμμής"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Σύρετε από την άκρη της οθόνης για να εμφανίσετε τη γραμμή συστήματος"</string>
 </resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index a37c945..a449835 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -131,6 +131,11 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Too many <xliff:g id="CONTENT_TYPE">%s</xliff:g> deletions."</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Tablet storage is full. Delete some files to free space."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Phone storage is full. Delete some files to free space."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Network may be monitored"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Me"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Tablet options"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Phone options"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Allows the app to move tasks to the foreground and background. The app may do this without your input."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"stop running apps"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Allows the app to remove tasks and kill their apps. Malicious apps may disrupt the behaviour of other apps."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"manage activity stacks"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Allows the app to add, remove and modify the activity stacks in which other apps run. Malicious apps may disrupt the behaviour of other apps."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"start any activity"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Allows the app to start any activity, regardless of permission protection or exported state."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"set screen compatibility"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Allows the holder to bind to the top-level interface of an input method. Should never be needed for normal apps."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"bind to an accessibility service"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Allows the holder to bind to the top-level interface of an accessibility service. Should never be needed for normal apps."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"bind to a print service"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Allows the holder to bind to the top-level interface of a print service. Should never be needed for normal apps."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"bind to a print spooler service"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Allows the holder to bind to the top-level interface of a print spooler service. Should never be needed for normal apps."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"bind to NFC service"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Allows the holder to bind to applications that are emulating NFC cards. Should never be needed for normal apps."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"bind to a text service"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Allows the holder to bind to the top-level interface of a text service (e.g. SpellCheckerService). Should never be needed for normal applications."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"bind to a VPN service"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Allows the holder to bind to the top-level interface of a widget service. Should never be needed for normal apps."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interact with device admin"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Allows the holder to send intents to a device administrator. Should never be needed for normal apps."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"add or remove a device admin"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Allows the holder to add or remove active device administrators. Should never be needed for normal apps."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"change screen orientation"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Allows the app to change the rotation of the screen at any time. Should never be needed for normal apps."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"change pointer speed"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Allows the app to read from the system\'s various log files. This allows it to discover general information about what you are doing with the phone, potentially including personal or private information."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"use any media decoder for playback"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Allows the app to use any installed media decoder to decode for playback."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"manage trusted credentials"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Allows the app to install and uninstall CA certificates as trusted credentials."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"read/write to resources owned by diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Allows the app to read and write to any resource owned by the diag group; for example, files in /dev. This could potentially affect system stability and security. This should ONLY be used for hardware-specific diagnostics by the manufacturer or operator."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"enable or disable app components"</string>
@@ -462,6 +479,14 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Allows the app to configure and connect to Wi-Fi displays."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"control Wi-Fi displays"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Allows the app to control low-level features of Wi-Fi displays."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"capture audio output"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Allows the app to capture and redirect audio output."</string>
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Hotword detection"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Allows the app to capture audio for Hotword detection. The capture can happen in the background but does not prevent other audio capture (e.g. Camcorder)."</string>
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"capture video output"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Allows the app to capture and redirect video output."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"capture secure video output"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Allows the app to capture and redirect secure video output."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"change your audio settings"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Allows the app to modify global audio settings such as volume and which speaker is used for output."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"record audio"</string>
@@ -525,6 +550,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"prevent phone from sleeping"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Allows the app to prevent the tablet from going to sleep."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Allows the app to prevent the phone from going to sleep."</string>
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"transmit infrared"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Allows the app to use the tablet\'s infrared transmitter."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Allows the app to use the phone\'s infrared transmitter."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"turn tablet on or off"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"turn phone on or off"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Allows the app to turn the tablet on or off."</string>
@@ -613,6 +641,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Allows the app to write to the SD card."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modify/delete internal media storage contents"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Allows the app to modify the contents of the internal media storage."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"manage document storage"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Allows the app to manage document storage."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"access external storage of all users"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Allows the app to access external storage for all users."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"access the cache file system"</string>
@@ -625,10 +655,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Allows the app to manage network policies and define app-specific rules."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"modify network usage accounting"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Allows the app to modify how network usage is accounted against apps. Not for use by normal apps."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"modify socket marks"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Allows the app to modify socket marks for routing"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"access notifications"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Allows the app to retrieve, examine, and clear notifications, including those posted by other apps."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"bind to a notification listener service"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Allows the holder to bind to the top-level interface of a notification listener service. Should never be needed for normal apps."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"invoke the carrier-provided configuration app"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Allows the holder to invoke the carrier-provided configuration app. Should never be needed for normal apps."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"listen for observations on network conditions"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Allows an application to listen for observations on network conditions. Should never be needed for normal apps."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Set password rules"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Control the length and the characters allowed in screen-unlock passwords."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitor screen-unlock attempts"</string>
@@ -738,8 +774,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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">"Net Meeting"</string>
@@ -796,7 +831,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Insert a SIM card."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"The SIM card is missing or not readable. Insert a SIM card."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Unusable SIM card."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Your SIM card has been permanently disabled."\n" Contact your wireless service provider for another SIM card."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Your SIM card has been permanently disabled.\n Contact your wireless service provider for another SIM card."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Previous track button"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Next-track button"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Pause button"</string>
@@ -808,11 +843,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"See the User Guide or contact Customer Care."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM card is locked."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Unlocking SIM card…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. "\n\n"Try again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%d</xliff:g> times. "\n\n"Try again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%d</xliff:g> times. "\n\n"Try again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using your Google sign-in."\n\n" Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"You have drawn your unlock pattern incorrectly <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using your Google sign-in."\n\n" Please try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using your Google sign-in.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"You have drawn your unlock pattern incorrectly <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using your Google sign-in.\n\n Please try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the tablet will be reset to factory default and all user data will be lost."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the phone will be reset to factory default and all user data will be lost."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. The tablet will now be reset to factory default."</string>
@@ -826,7 +861,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Password"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Sign in"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Invalid username or password."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Forgot your username or password?"\n"Visit "<b>"google.co.uk/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Forgot your username or password?\nVisit "<b>"google.co.uk/accounts/recovery"</b>"."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Checking…"</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Unlock"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Sound on"</string>
@@ -874,7 +909,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Confirm Navigation"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Leave this Page"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Stay on this Page"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Are you sure you want to navigate away from this page?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nAre you sure you want to navigate away from this page?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Confirm"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Tip: double-tap to zoom in and out."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Auto-fill"</string>
@@ -1080,14 +1115,14 @@
     <string name="aerr_application" msgid="932628488013092776">"Unfortunately, <xliff:g id="APPLICATION">%1$s</xliff:g> has stopped."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Unfortunately, the process <xliff:g id="PROCESS">%1$s</xliff:g> has stopped."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> isn\'t responding."\n\n"Do you want to close it?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Activity <xliff:g id="ACTIVITY">%1$s</xliff:g> isn\'t responding."\n\n"Do you want to close it?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> isn\'t responding.\n\nDo you want to close it?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Activity <xliff:g id="ACTIVITY">%1$s</xliff:g> isn\'t responding.\n\nDo you want to close it?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> isn\'t responding. Do you want to close it?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Process <xliff:g id="PROCESS">%1$s</xliff:g> isn\'t responding."\n\n"Do you want to close it?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Process <xliff:g id="PROCESS">%1$s</xliff:g> isn\'t responding.\n\nDo you want to close it?"</string>
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"Report"</string>
     <string name="wait" msgid="7147118217226317732">"Wait"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"The page has become unresponsive."\n\n"Do you want to close it?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"The page has become unresponsive.\n\nDo you want to close it?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"App redirected"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> is now running."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> was originally launched."</string>
@@ -1256,6 +1291,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Allows the app to invoke default container service to copy content. Not for use by normal apps."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Route media output"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Allows an application to route media output to other external devices."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Access keyguard secure storage"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Allows an application to access keyguard secure storage."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Control displaying and hiding keyguard"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Allows an application to control keyguard."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Touch twice for zoom control"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Couldn\'t add widget."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Go"</string>
@@ -1265,15 +1304,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Done"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Prev"</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Execute"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Dial number"\n" using <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Create contact"\n" using <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Dial number\n using <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Create contact\n using <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"The following one or more applications request permission to access your account, now and in the future."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Do you want to allow this request?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Access request"</string>
     <string name="allow" msgid="7225948811296386551">"Allow"</string>
     <string name="deny" msgid="2081879885755434506">"Deny"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Permission requested"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Permission requested"\n"for account <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Permission requested\nfor account <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Input Method"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Sync"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Accessibility"</string>
@@ -1420,7 +1459,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"See all"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Choose activity"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Share with"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Device locked."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Sending…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Launch Browser?"</string>
@@ -1441,10 +1479,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Connecting..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Available"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"Not available"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"In use"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Built-in Screen"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"HDMI Screen"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlay #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", secure"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Wireless display is connected"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"This screen is showing on another device"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Disconnect"</string>
@@ -1453,7 +1493,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Wrong Pattern"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Wrong Password"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"Wrong PIN"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Try again in <xliff:g id="NUMBER">%d</xliff:g> seconds."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Try again in <xliff:g id="NUMBER">%1$d</xliff:g> seconds."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Draw your pattern"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Enter SIM PIN"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Enter PIN"</string>
@@ -1473,27 +1513,85 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Password"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Sign in"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Invalid username or password."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Forgot your username or password?"\n"Visit "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Forgot your username or password?\nVisit "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Checking account…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%d</xliff:g> times. "\n\n"Try again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%d</xliff:g> times. "\n\n"Try again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. "\n\n"Try again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the tablet will be reset to factory default and all user data will be lost."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the phone will be reset to factory default and all user data will be lost."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. The tablet will now be reset to factory default."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The phone will now be reset to factory default."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account."\n\n" Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account."\n\n" Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Remove"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Raise volume above recommended level?"\n"Listening at high volume for long periods may damage your hearing."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Raise volume above recommended level?\nListening at high volume for long periods may damage your hearing."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Keep holding down two fingers to enable accessibility."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Accessibility enabled."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accessibility cancelled."</string>
     <string name="user_switched" msgid="3768006783166984410">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Owner"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Error"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"This application does not support accounts for restricted profiles"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"This app doesn\'t support accounts for restricted profiles"</string>
     <string name="app_not_found" msgid="3429141853498927379">"No application found to handle this action"</string>
     <string name="revoke" msgid="5404479185228271586">"Revoke"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Cancelled"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Error writing content"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"unknown"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Enter administrator PIN"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Enter PIN"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Incorrect"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Current PIN:"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"New PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Confirm new PIN"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Create a PIN for modifying restrictions"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PINs don\'t match. Try again."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"PIN is too short. Must be at least 4 digits."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Try again in 1 second"</item>
+    <item quantity="other" msgid="4730868920742952817">"Try again in <xliff:g id="COUNT">%d</xliff:g> seconds"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Try again later"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Swipe edge of screen to reveal bar"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Swipe from edge of screen to reveal system bar"</string>
 </resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..a449835
--- /dev/null
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -0,0 +1,1597 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<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="5973789783504771878">"KB"</string>
+    <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
+    <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
+    <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
+    <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
+    <string name="untitled" msgid="4638956954852782576">"&lt;Untitled&gt;"</string>
+    <string name="ellipsis" msgid="7899829516048813237">"…"</string>
+    <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
+    <string name="emptyPhoneNumber" msgid="7694063042079676517">"(No phone number)"</string>
+    <string name="unknownName" msgid="2277556546742746522">"(Unknown)"</string>
+    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Voicemail"</string>
+    <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
+    <string name="mmiError" msgid="5154499457739052907">"Connection problem or invalid MMI code."</string>
+    <string name="mmiFdnError" msgid="5224398216385316471">"Operation is restricted to fixed dialling numbers only."</string>
+    <string name="serviceEnabled" msgid="8147278346414714315">"Service was enabled."</string>
+    <string name="serviceEnabledFor" msgid="6856228140453471041">"Service was enabled for:"</string>
+    <string name="serviceDisabled" msgid="1937553226592516411">"Service has been disabled."</string>
+    <string name="serviceRegistered" msgid="6275019082598102493">"Registration was successful."</string>
+    <string name="serviceErased" msgid="1288584695297200972">"Erase successful."</string>
+    <string name="passwordIncorrect" msgid="7612208839450128715">"Incorrect password."</string>
+    <string name="mmiComplete" msgid="8232527495411698359">"MMI complete."</string>
+    <string name="badPin" msgid="9015277645546710014">"The old PIN that you typed is incorrect."</string>
+    <string name="badPuk" msgid="5487257647081132201">"The PUK that you typed isn\'t correct."</string>
+    <string name="mismatchPin" msgid="609379054496863419">"The PINs that you typed don\'t match."</string>
+    <string name="invalidPin" msgid="3850018445187475377">"Type a PIN that is 4 to 8 numbers."</string>
+    <string name="invalidPuk" msgid="8761456210898036513">"Type a PUK that is 8 numbers or longer."</string>
+    <string name="needPuk" msgid="919668385956251611">"Your SIM card is PUK-locked. Type the PUK code to unlock it."</string>
+    <string name="needPuk2" msgid="4526033371987193070">"Type PUK2 to unblock SIM card."</string>
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
+    <string name="ClipMmi" msgid="6952821216480289285">"Incoming Caller ID"</string>
+    <string name="ClirMmi" msgid="7784673673446833091">"Outgoing Caller ID"</string>
+    <string name="CfMmi" msgid="5123218989141573515">"Call forwarding"</string>
+    <string name="CwMmi" msgid="9129678056795016867">"Call waiting"</string>
+    <string name="BaMmi" msgid="455193067926770581">"Call barring"</string>
+    <string name="PwdMmi" msgid="7043715687905254199">"Password change"</string>
+    <string name="PinMmi" msgid="3113117780361190304">"PIN change"</string>
+    <string name="CnipMmi" msgid="3110534680557857162">"Calling number present"</string>
+    <string name="CnirMmi" msgid="3062102121430548731">"Calling number restricted"</string>
+    <string name="ThreeWCMmi" msgid="9051047170321190368">"Three-way calling"</string>
+    <string name="RuacMmi" msgid="7827887459138308886">"Rejection of undesired annoying calls"</string>
+    <string name="CndMmi" msgid="3116446237081575808">"Calling number delivery"</string>
+    <string name="DndMmi" msgid="1265478932418334331">"Do not disturb"</string>
+    <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"Caller ID defaults to restricted. Next call: Restricted"</string>
+    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"Caller ID defaults to restricted. Next call: Not restricted"</string>
+    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"Caller ID defaults to not restricted. Next call: Restricted"</string>
+    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"Caller ID defaults to not restricted. Next call: Not restricted"</string>
+    <string name="serviceNotProvisioned" msgid="8614830180508686666">"Service not provisioned."</string>
+    <string name="CLIRPermanent" msgid="3377371145926835671">"You can\'t change the caller ID setting."</string>
+    <string name="RestrictedChangedTitle" msgid="5592189398956187498">"Restricted access changed"</string>
+    <string name="RestrictedOnData" msgid="8653794784690065540">"Data service is blocked."</string>
+    <string name="RestrictedOnEmergency" msgid="6581163779072833665">"Emergency service is blocked."</string>
+    <string name="RestrictedOnNormal" msgid="4953867011389750673">"Voice service is blocked."</string>
+    <string name="RestrictedOnAllVoice" msgid="3396963652108151260">"All voice services are blocked."</string>
+    <string name="RestrictedOnSms" msgid="8314352327461638897">"SMS service is blocked."</string>
+    <string name="RestrictedOnVoiceData" msgid="996636487106171320">"Voice/Data services are blocked."</string>
+    <string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Voice/SMS services are blocked."</string>
+    <string name="RestrictedOnAll" msgid="5643028264466092821">"All voice/data/SMS services are blocked."</string>
+    <string name="serviceClassVoice" msgid="1258393812335258019">"Voice"</string>
+    <string name="serviceClassData" msgid="872456782077937893">"Data"</string>
+    <string name="serviceClassFAX" msgid="5566624998840486475">"FAX"</string>
+    <string name="serviceClassSMS" msgid="2015460373701527489">"SMS"</string>
+    <string name="serviceClassDataAsync" msgid="4523454783498551468">"Async"</string>
+    <string name="serviceClassDataSync" msgid="7530000519646054776">"Sync"</string>
+    <string name="serviceClassPacket" msgid="6991006557993423453">"Packet"</string>
+    <string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
+    <string name="roamingText0" msgid="7170335472198694945">"Roaming Indicator On"</string>
+    <string name="roamingText1" msgid="5314861519752538922">"Roaming Indicator Off"</string>
+    <string name="roamingText2" msgid="8969929049081268115">"Roaming Indicator Flashing"</string>
+    <string name="roamingText3" msgid="5148255027043943317">"Out of local area"</string>
+    <string name="roamingText4" msgid="8808456682550796530">"Out of Building"</string>
+    <string name="roamingText5" msgid="7604063252850354350">"Roaming - Preferred System"</string>
+    <string name="roamingText6" msgid="2059440825782871513">"Roaming - Available System"</string>
+    <string name="roamingText7" msgid="7112078724097233605">"Roaming - Alliance Partner"</string>
+    <string name="roamingText8" msgid="5989569778604089291">"Roaming - Premium Partner"</string>
+    <string name="roamingText9" msgid="7969296811355152491">"Roaming - Full Service Functionality"</string>
+    <string name="roamingText10" msgid="3992906999815316417">"Roaming - Partial Service Functionality"</string>
+    <string name="roamingText11" msgid="4154476854426920970">"Roaming Banner On"</string>
+    <string name="roamingText12" msgid="1189071119992726320">"Roaming Banner Off"</string>
+    <string name="roamingTextSearching" msgid="8360141885972279963">"Searching for Service"</string>
+    <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Not forwarded"</string>
+    <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
+    <string name="cfTemplateForwardedTime" msgid="9206251736527085256">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> after <xliff:g id="TIME_DELAY">{2}</xliff:g> seconds"</string>
+    <string name="cfTemplateRegistered" msgid="5073237827620166285">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Not forwarded"</string>
+    <string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Not forwarded"</string>
+    <string name="fcComplete" msgid="3118848230966886575">"Feature code complete."</string>
+    <string name="fcError" msgid="3327560126588500777">"Connection problem or invalid feature code."</string>
+    <string name="httpErrorOk" msgid="1191919378083472204">"OK"</string>
+    <string name="httpError" msgid="7956392511146698522">"There was a network error."</string>
+    <string name="httpErrorLookup" msgid="4711687456111963163">"Couldn\'t find the URL."</string>
+    <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"The site authentication scheme isn\'t supported."</string>
+    <string name="httpErrorAuth" msgid="1435065629438044534">"Couldn\'t authenticate."</string>
+    <string name="httpErrorProxyAuth" msgid="1788207010559081331">"Authentication via the proxy server was unsuccessful."</string>
+    <string name="httpErrorConnect" msgid="8714273236364640549">"Couldn\'t connect to the server."</string>
+    <string name="httpErrorIO" msgid="2340558197489302188">"Couldn\'t communicate with the server. Try again later."</string>
+    <string name="httpErrorTimeout" msgid="4743403703762883954">"The connection to the server timed out."</string>
+    <string name="httpErrorRedirectLoop" msgid="8679596090392779516">"The page contains too many server redirects."</string>
+    <string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"The protocol isn\'t supported."</string>
+    <string name="httpErrorFailedSslHandshake" msgid="96549606000658641">"Couldn\'t establish a secure connection."</string>
+    <string name="httpErrorBadUrl" msgid="3636929722728881972">"Couldn\'t open the page because the URL is invalid."</string>
+    <string name="httpErrorFile" msgid="2170788515052558676">"Couldn\'t access the file."</string>
+    <string name="httpErrorFileNotFound" msgid="6203856612042655084">"Couldn\'t find the requested file."</string>
+    <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Too many requests are being processed. Try again later."</string>
+    <string name="notification_title" msgid="8967710025036163822">"Sign-in error for <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string>
+    <string name="contentServiceSync" msgid="8353523060269335667">"Sync"</string>
+    <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Sync"</string>
+    <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Too many <xliff:g id="CONTENT_TYPE">%s</xliff:g> deletions."</string>
+    <string name="low_memory" product="tablet" msgid="6494019234102154896">"Tablet storage is full. Delete some files to free space."</string>
+    <string name="low_memory" product="default" msgid="3475999286680000541">"Phone storage is full. Delete some files to free space."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Network may be monitored"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
+    <string name="me" msgid="6545696007631404292">"Me"</string>
+    <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Tablet options"</string>
+    <string name="power_dialog" product="default" msgid="1319919075463988638">"Phone options"</string>
+    <string name="silent_mode" msgid="7167703389802618663">"Silent mode"</string>
+    <string name="turn_on_radio" msgid="3912793092339962371">"Turn on wireless"</string>
+    <string name="turn_off_radio" msgid="8198784949987062346">"Turn off wireless"</string>
+    <string name="screen_lock" msgid="799094655496098153">"Screen lock"</string>
+    <string name="power_off" msgid="4266614107412865048">"Power off"</string>
+    <string name="silent_mode_silent" msgid="319298163018473078">"Ringer off"</string>
+    <string name="silent_mode_vibrate" msgid="7072043388581551395">"Ringer vibrate"</string>
+    <string name="silent_mode_ring" msgid="8592241816194074353">"Ringer on"</string>
+    <string name="shutdown_progress" msgid="2281079257329981203">"Shutting down…"</string>
+    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Your tablet will shut down."</string>
+    <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Your phone will shut down."</string>
+    <string name="shutdown_confirm_question" msgid="2906544768881136183">"Do you want to shut down?"</string>
+    <string name="reboot_safemode_title" msgid="7054509914500140361">"Reboot to safe mode"</string>
+    <string name="reboot_safemode_confirm" msgid="55293944502784668">"Do you want to reboot into safe mode? This will disable all third-party applications that you have installed. They will be restored when you reboot again."</string>
+    <string name="recent_tasks_title" msgid="3691764623638127888">"Recent"</string>
+    <string name="no_recent_tasks" msgid="8794906658732193473">"No recent apps"</string>
+    <string name="global_actions" product="tablet" msgid="408477140088053665">"Tablet options"</string>
+    <string name="global_actions" product="default" msgid="2406416831541615258">"Phone options"</string>
+    <string name="global_action_lock" msgid="2844945191792119712">"Screen lock"</string>
+    <string name="global_action_power_off" msgid="4471879440839879722">"Power off"</string>
+    <string name="global_action_bug_report" msgid="7934010578922304799">"Bug report"</string>
+    <string name="bugreport_title" msgid="2667494803742548533">"Take bug report"</string>
+    <string name="bugreport_message" msgid="398447048750350456">"This will collect information about your current device state, to send as an email message. It will take a little time from starting the bug report until it is ready to be sent. Please be patient."</string>
+    <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Silent mode"</string>
+    <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Sound is OFF"</string>
+    <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Sound is ON"</string>
+    <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Aeroplane mode"</string>
+    <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Aeroplane mode is ON"</string>
+    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Aeroplane mode is OFF"</string>
+    <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
+    <string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
+    <string name="android_system_label" msgid="6577375335728551336">"Android System"</string>
+    <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Services that cost you money"</string>
+    <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Do things that can cost you money."</string>
+    <string name="permgrouplab_messages" msgid="7521249148445456662">"Your messages"</string>
+    <string name="permgroupdesc_messages" msgid="7821999071003699236">"Read and write your SMS, email and other messages."</string>
+    <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Your personal information"</string>
+    <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"Direct access to information about you, stored in on your contact card."</string>
+    <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Your social information"</string>
+    <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Direct access to information about your contacts and social connections."</string>
+    <string name="permgrouplab_location" msgid="635149742436692049">"Your location"</string>
+    <string name="permgroupdesc_location" msgid="5704679763124170100">"Monitor your physical location."</string>
+    <string name="permgrouplab_network" msgid="5808983377727109831">"Network communication"</string>
+    <string name="permgroupdesc_network" msgid="4478299413241861987">"Access various network features."</string>
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"Bluetooth"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"Access devices and networks through Bluetooth."</string>
+    <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"Audio Settings"</string>
+    <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"Change audio settings."</string>
+    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Affects Battery"</string>
+    <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Use features that can quickly drain battery."</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendar"</string>
+    <string name="permgroupdesc_calendar" msgid="5777534316982184416">"Direct access to calendar and events."</string>
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"Read User Dictionary"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"Read words in user dictionary."</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"Write User Dictionary"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"Add words to the user dictionary."</string>
+    <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Bookmarks and History"</string>
+    <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Direct access to bookmarks and browser history."</string>
+    <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"Alarm"</string>
+    <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"Set the alarm clock."</string>
+    <string name="permgrouplab_voicemail" msgid="4162237145027592133">"Voicemail"</string>
+    <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"Direct access to voicemail."</string>
+    <string name="permgrouplab_microphone" msgid="171539900250043464">"Microphone"</string>
+    <string name="permgroupdesc_microphone" msgid="7106618286905738408">"Direct access to the microphone to record audio."</string>
+    <string name="permgrouplab_camera" msgid="4820372495894586615">"Camera"</string>
+    <string name="permgroupdesc_camera" msgid="2933667372289567714">"Direct access to camera for image or video capture."</string>
+    <string name="permgrouplab_screenlock" msgid="8275500173330718168">"Lock screen"</string>
+    <string name="permgroupdesc_screenlock" msgid="7067497128925499401">"Ability to affect behaviour of the lock screen on your device."</string>
+    <string name="permgrouplab_appInfo" msgid="8028789762634147725">"Your applications information"</string>
+    <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"Ability to affect behaviour of other applications on your device."</string>
+    <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"Wallpaper"</string>
+    <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"Change the device wallpaper settings."</string>
+    <string name="permgrouplab_systemClock" msgid="406535759236612992">"Clock"</string>
+    <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"Change the device time or timezone."</string>
+    <string name="permgrouplab_statusBar" msgid="2095862568113945398">"Status Bar"</string>
+    <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"Change the device status bar settings."</string>
+    <string name="permgrouplab_syncSettings" msgid="3341990986147826541">"Sync Settings"</string>
+    <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"Access to the sync settings."</string>
+    <string name="permgrouplab_accounts" msgid="3359646291125325519">"Your accounts"</string>
+    <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Access the available accounts."</string>
+    <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Hardware controls"</string>
+    <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Direct access to hardware on the handset."</string>
+    <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Phone calls"</string>
+    <string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"Monitor, record and process phone calls."</string>
+    <string name="permgrouplab_systemTools" msgid="4652191644082714048">"System tools"</string>
+    <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"Lower-level access and control of the system."</string>
+    <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"Development tools"</string>
+    <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"Features only needed for app developers."</string>
+    <string name="permgrouplab_display" msgid="4279909676036402636">"Other Application UI"</string>
+    <string name="permgroupdesc_display" msgid="6051002031933013714">"Effect the UI of other applications."</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"Storage"</string>
+    <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Access the USB storage."</string>
+    <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Access the SD card."</string>
+    <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"Accessibility features"</string>
+    <string name="permgroupdesc_accessibilityFeatures" msgid="4205196881678144335">"Features that assistive technology can request."</string>
+    <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Retrieve window content"</string>
+    <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspect the content of a window that you\'re interacting with."</string>
+    <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Turn on Explore by Touch"</string>
+    <string name="capability_desc_canRequestTouchExploration" msgid="5800552516779249356">"Touched items will be spoken aloud and the screen can be explored using gestures."</string>
+    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Turn on enhanced web accessibility"</string>
+    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Scripts may be installed to make app content more accessible."</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Observe text that you type"</string>
+    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Includes personal data such as credit card numbers and passwords."</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"disable or modify status bar"</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"Allows the app to disable the status bar or add and remove system icons."</string>
+    <string name="permlab_statusBarService" msgid="7247281911387931485">"status bar"</string>
+    <string name="permdesc_statusBarService" msgid="716113660795976060">"Allows the app to be the status bar."</string>
+    <string name="permlab_expandStatusBar" msgid="1148198785937489264">"expand/collapse status bar"</string>
+    <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"Allows the app to expand or collapse the status bar."</string>
+    <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"reroute outgoing calls"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Allows the app to process outgoing calls and change the number to be dialled. This permission allows the app to monitor, redirect or prevent outgoing calls."</string>
+    <string name="permlab_receiveSms" msgid="8673471768947895082">"receive text messages (SMS)"</string>
+    <string name="permdesc_receiveSms" msgid="6424387754228766939">"Allows the app to receive and process SMS messages. This means that the app could monitor or delete messages sent to your device without showing them to you."</string>
+    <string name="permlab_receiveMms" msgid="1821317344668257098">"receive text messages (MMS)"</string>
+    <string name="permdesc_receiveMms" msgid="533019437263212260">"Allows the app to receive and process MMS messages. This means that the app could monitor or delete messages sent to your device without showing them to you."</string>
+    <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"receive emergency broadcasts"</string>
+    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Allows the app to receive and process emergency broadcast messages. This permission is only available for system apps."</string>
+    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"read mobile broadcast messages"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Allows the app to read mobile broadcast messages received by your device. Cell broadcast alerts are delivered in some locations to warn you of emergency situations. Malicious apps may interfere with the performance or operation of your device when an emergency mobile broadcast is received."</string>
+    <string name="permlab_sendSms" msgid="5600830612147671529">"send SMS messages"</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"Allows the app to send SMS messages. This may result in unexpected charges. Malicious apps may cost you money by sending messages without your confirmation."</string>
+    <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"send respond-via-message events"</string>
+    <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"Allows the app to send requests to other messaging apps to handle respond-via-message events for incoming calls."</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"read your text messages (SMS or MMS)"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Allows the app to read SMS messages stored on your tablet or SIM card. This allows the app to read all SMS messages, regardless of content or confidentiality."</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Allows the app to read SMS messages stored on your phone or SIM card. This allows the app to read all SMS messages, regardless of content or confidentiality."</string>
+    <string name="permlab_writeSms" msgid="3216950472636214774">"edit your text messages (SMS or MMS)"</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Allows the app to write to SMS messages stored on your tablet or SIM card. Malicious apps may delete your messages."</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Allows the app to write to SMS messages stored on your phone or SIM card. Malicious apps may delete your messages."</string>
+    <string name="permlab_receiveWapPush" msgid="5991398711936590410">"receive text messages (WAP)"</string>
+    <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Allows the app to receive and process WAP messages. This permission includes the ability to monitor or delete messages sent to you without showing them to you."</string>
+    <string name="permlab_getTasks" msgid="6466095396623933906">"retrieve running apps"</string>
+    <string name="permdesc_getTasks" msgid="7454215995847658102">"Allows the app to retrieve information about currently and recently running tasks. This may allow the app to discover information about which applications are used on the device."</string>
+    <string name="permlab_interactAcrossUsers" msgid="7114255281944211682">"interact across users"</string>
+    <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Allows the app to perform actions across different users on the device. Malicious apps may use this to violate the protection between users."</string>
+    <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"full license to interact across users"</string>
+    <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Allows all possible interactions across users."</string>
+    <string name="permlab_manageUsers" msgid="1676150911672282428">"manage users"</string>
+    <string name="permdesc_manageUsers" msgid="8409306667645355638">"Allows apps to manage users on the device, including query, creation and deletion."</string>
+    <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"retrieve details of running apps"</string>
+    <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Allows the app to retrieve detailed information about currently and recently running tasks. Malicious apps may discover private information about other apps."</string>
+    <string name="permlab_reorderTasks" msgid="2018575526934422779">"re-order running apps"</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Allows the app to move tasks to the foreground and background. The app may do this without your input."</string>
+    <string name="permlab_removeTasks" msgid="6821513401870377403">"stop running apps"</string>
+    <string name="permdesc_removeTasks" msgid="1394714352062635493">"Allows the app to remove tasks and kill their apps. Malicious apps may disrupt the behaviour of other apps."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"manage activity stacks"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Allows the app to add, remove and modify the activity stacks in which other apps run. Malicious apps may disrupt the behaviour of other apps."</string>
+    <string name="permlab_startAnyActivity" msgid="2918768238045206456">"start any activity"</string>
+    <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Allows the app to start any activity, regardless of permission protection or exported state."</string>
+    <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"set screen compatibility"</string>
+    <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Allows the app to control the screen compatibility mode of other applications. Malicious applications may break the behaviour of other applications."</string>
+    <string name="permlab_setDebugApp" msgid="3022107198686584052">"enable app debugging"</string>
+    <string name="permdesc_setDebugApp" msgid="4474512416299013256">"Allows the app to turn on debugging for another app. Malicious apps may use this to kill other apps."</string>
+    <string name="permlab_changeConfiguration" msgid="4162092185124234480">"change system display settings"</string>
+    <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"Allows the app to change the current configuration, such as the locale or overall font size."</string>
+    <string name="permlab_enableCarMode" msgid="5684504058192921098">"enable car mode"</string>
+    <string name="permdesc_enableCarMode" msgid="4853187425751419467">"Allows the app to enable the car mode."</string>
+    <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"close other apps"</string>
+    <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"Allows the app to end background processes of other apps. This may cause other apps to stop running."</string>
+    <string name="permlab_forceStopPackages" msgid="2329627428832067700">"force stop other apps"</string>
+    <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"Allows the app to forcibly stop other apps."</string>
+    <string name="permlab_forceBack" msgid="652935204072584616">"force app to close"</string>
+    <string name="permdesc_forceBack" msgid="3892295830419513623">"Allows the app to force any activity that is in the foreground to close and go back. Should never be needed for normal apps."</string>
+    <string name="permlab_dump" msgid="1681799862438954752">"retrieve system internal status"</string>
+    <string name="permdesc_dump" msgid="1778299088692290329">"Allows the app to retrieve the internal state of the system. Malicious apps may retrieve a wide variety of private and secure information that they should never normally need."</string>
+    <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"retrieve screen content"</string>
+    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Allows the app to retrieve the content of the active window. Malicious apps may retrieve the entire window content and examine all its text except passwords."</string>
+    <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"temporary enable accessibility"</string>
+    <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"Allows an application to temporarily enable accessibility on the device. Malicious apps may enable accessibility without user consent."</string>
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"retrieve window info"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Allows an application to retrieve information about the windows from the window manager. Malicious apps may retrieve information that is intended for internal system usage."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"filter events"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Allows an application to register an input filter which filters the stream of all user events before they are dispatched. Malicious app may control the system UI without user intervention."</string>
+    <string name="permlab_magnify_display" msgid="5973626738170618775">"magnify display"</string>
+    <string name="permdesc_magnify_display" msgid="7121235684515003792">"Allows an application to magnify the content of a display. Malicious apps may transform the display content in a way that renders the device unusable."</string>
+    <string name="permlab_shutdown" msgid="7185747824038909016">"partial shutdown"</string>
+    <string name="permdesc_shutdown" msgid="7046500838746291775">"Puts the activity manager into a shut-down state. Does not perform a complete shut down."</string>
+    <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"prevent app switches"</string>
+    <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Prevents the user from switching to another app."</string>
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"get current app info"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Allows the holder to retrieve private information about the current application in the foreground of the screen."</string>
+    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"monitor and control all app launching"</string>
+    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Allows the app to monitor and control how the system launches activities. Malicious apps may completely compromise the system. This permission is only needed for development, never for normal use."</string>
+    <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"send package removed broadcast"</string>
+    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"Allows the app to broadcast a notification that an app package has been removed. Malicious apps may use this to kill any other running app."</string>
+    <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"send SMS-received broadcast"</string>
+    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"Allows the app to broadcast a notification that an SMS message has been received. Malicious apps may use this to forge incoming SMS messages."</string>
+    <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"send WAP-PUSH-received broadcast"</string>
+    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"Allows the app to broadcast a notification that a WAP PUSH message has been received. Malicious apps may use this to forge MMS message receipt or to silently replace the content of any web page with malicious variants."</string>
+    <string name="permlab_setProcessLimit" msgid="2451873664363662666">"limit number of running processes"</string>
+    <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"Allows the app to control the maximum number of processes that will run. Never needed for normal apps."</string>
+    <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"force background apps to close"</string>
+    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"Allows the app to control whether activities are always finished as soon as they go to the background. Never needed for normal apps."</string>
+    <string name="permlab_batteryStats" msgid="2789610673514103364">"read battery statistics"</string>
+    <string name="permdesc_batteryStats" msgid="5897346582882915114">"Allows an application to read the current low-level battery use data. May allow the application to find out detailed information about which apps you use."</string>
+    <string name="permlab_updateBatteryStats" msgid="3719689764536379557">"modify battery statistics"</string>
+    <string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"Allows the app to modify collected battery statistics. Not for use by normal apps."</string>
+    <string name="permlab_getAppOpsStats" msgid="1508779687436585744">"retrieve app ops statistics"</string>
+    <string name="permdesc_getAppOpsStats" msgid="6243887041577912877">"Allows the app to retrieve collected application operation statistics. Not for use by normal apps."</string>
+    <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"modify app ops statistics"</string>
+    <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"Allows the app to modify collected component usage statistics. Not for use by normal apps."</string>
+    <string name="permlab_backup" msgid="470013022865453920">"control system back up and restore"</string>
+    <string name="permdesc_backup" msgid="6912230525140589891">"Allows the app to control the system\'s backup and restore mechanism. Not for use by normal apps."</string>
+    <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"confirm a full backup or restore operation"</string>
+    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"Allows the app to launch the full backup confirmation UI. Not to be used by any app."</string>
+    <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"display unauthorised windows"</string>
+    <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"Allows the app to create windows that are intended to be used by the internal system user interface. Not for use by normal apps."</string>
+    <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"draw over other apps"</string>
+    <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"Allows the app to draw on top of other applications or parts of the user interface. They may interfere with your use of the interface in any application, or change what you think you are seeing in other applications."</string>
+    <string name="permlab_setAnimationScale" msgid="2805103241153907174">"modify global animation speed"</string>
+    <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"Allows the app to change the global animation speed (faster or slower animations) at any time."</string>
+    <string name="permlab_manageAppTokens" msgid="1286505717050121370">"manage app tokens"</string>
+    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"Allows the app to create and manage their own tokens, bypassing their normal Z-ordering. Should never be needed for normal apps."</string>
+    <string name="permlab_freezeScreen" msgid="4708181184441880175">"freeze screen"</string>
+    <string name="permdesc_freezeScreen" msgid="8558923789222670064">"Allows the application to temporarily freeze the screen for a full-screen transition."</string>
+    <string name="permlab_injectEvents" msgid="1378746584023586600">"press keys and control buttons"</string>
+    <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"Allows the app to deliver its own input events (key presses, etc.) to other apps. Malicious apps may use this to take over the tablet."</string>
+    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"Allows the app to deliver its own input events (key presses, etc.) to other apps. Malicious apps may use this to take over the phone."</string>
+    <string name="permlab_readInputState" msgid="469428900041249234">"record what you type and actions that you take"</string>
+    <string name="permdesc_readInputState" msgid="8387754901688728043">"Allows the app to watch the keys that you press even when interacting with another app (such as typing a password). Should never be needed for normal apps."</string>
+    <string name="permlab_bindInputMethod" msgid="3360064620230515776">"bind to an input method"</string>
+    <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Allows the holder to bind to the top-level interface of an input method. Should never be needed for normal apps."</string>
+    <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"bind to an accessibility service"</string>
+    <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Allows the holder to bind to the top-level interface of an accessibility service. Should never be needed for normal apps."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"bind to a print service"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Allows the holder to bind to the top-level interface of a print service. Should never be needed for normal apps."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"bind to a print spooler service"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Allows the holder to bind to the top-level interface of a print spooler service. Should never be needed for normal apps."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"bind to NFC service"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Allows the holder to bind to applications that are emulating NFC cards. Should never be needed for normal apps."</string>
+    <string name="permlab_bindTextService" msgid="7358378401915287938">"bind to a text service"</string>
+    <string name="permdesc_bindTextService" msgid="8151968910973998670">"Allows the holder to bind to the top-level interface of a text service (e.g. SpellCheckerService). Should never be needed for normal applications."</string>
+    <string name="permlab_bindVpnService" msgid="4708596021161473255">"bind to a VPN service"</string>
+    <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Allows the holder to bind to the top-level interface of a Vpn service. Should never be needed for normal apps."</string>
+    <string name="permlab_bindWallpaper" msgid="8716400279937856462">"bind to wallpaper"</string>
+    <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Allows the holder to bind to the top-level interface of wallpaper. Should never be needed for normal applications."</string>
+    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"bind to a widget service"</string>
+    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Allows the holder to bind to the top-level interface of a widget service. Should never be needed for normal apps."</string>
+    <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interact with device admin"</string>
+    <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Allows the holder to send intents to a device administrator. Should never be needed for normal apps."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"add or remove a device admin"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Allows the holder to add or remove active device administrators. Should never be needed for normal apps."</string>
+    <string name="permlab_setOrientation" msgid="3365947717163866844">"change screen orientation"</string>
+    <string name="permdesc_setOrientation" msgid="3046126619316671476">"Allows the app to change the rotation of the screen at any time. Should never be needed for normal apps."</string>
+    <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"change pointer speed"</string>
+    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Allows the app to change the mouse or touch pad pointer speed at any time. Should never be needed for normal apps."</string>
+    <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"change keyboard layout"</string>
+    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Allows the app to change the keyboard layout. Should never be needed for normal apps."</string>
+    <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"send Linux signals to apps"</string>
+    <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Allows the app to request that the supplied signal be sent to all persistent processes."</string>
+    <string name="permlab_persistentActivity" msgid="8841113627955563938">"make app always run"</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Allows the app to make parts of itself persistent in memory. This can limit the memory available to other apps, slowing down the tablet."</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"Allows the app to make parts of itself persistent in memory. This can limit the memory available to other apps, slowing down the phone."</string>
+    <string name="permlab_deletePackages" msgid="184385129537705938">"delete apps"</string>
+    <string name="permdesc_deletePackages" msgid="7411480275167205081">"Allows the app to delete Android packages. Malicious apps may use this to delete important apps."</string>
+    <string name="permlab_clearAppUserData" msgid="274109191845842756">"delete other apps\' data"</string>
+    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"Allows the app to clear user data."</string>
+    <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"delete other apps\' caches"</string>
+    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"Allows the app to delete cache files."</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"measure app storage space"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Allows the app to retrieve its code, data and cache sizes"</string>
+    <string name="permlab_installPackages" msgid="2199128482820306924">"directly install apps"</string>
+    <string name="permdesc_installPackages" msgid="5628530972548071284">"Allows the app to install new or updated Android packages. Malicious apps may use this to add new apps with arbitrarily powerful permissions."</string>
+    <string name="permlab_clearAppCache" msgid="7487279391723526815">"delete all app cache data"</string>
+    <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"Allows the app to free tablet storage by deleting files in the cache directories of other applications. This may cause other applications to start up more slowly as they need to re-retrieve their data."</string>
+    <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"Allows the app to free phone storage by deleting files in the cache directories of other applications. This may cause other applications to start up more slowly as they need to re-retrieve their data."</string>
+    <string name="permlab_movePackage" msgid="3289890271645921411">"move app resources"</string>
+    <string name="permdesc_movePackage" msgid="319562217778244524">"Allows the app to move app resources from internal to external media and vice versa."</string>
+    <string name="permlab_readLogs" msgid="6615778543198967614">"read sensitive log data"</string>
+    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Allows the app to read from the system\'s various log files. This allows it to discover general information about what you are doing with the tablet, potentially including personal or private information."</string>
+    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Allows the app to read from the system\'s various log files. This allows it to discover general information about what you are doing with the phone, potentially including personal or private information."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"use any media decoder for playback"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Allows the app to use any installed media decoder to decode for playback."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"manage trusted credentials"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Allows the app to install and uninstall CA certificates as trusted credentials."</string>
+    <string name="permlab_diagnostic" msgid="8076743953908000342">"read/write to resources owned by diag"</string>
+    <string name="permdesc_diagnostic" msgid="6608295692002452283">"Allows the app to read and write to any resource owned by the diag group; for example, files in /dev. This could potentially affect system stability and security. This should ONLY be used for hardware-specific diagnostics by the manufacturer or operator."</string>
+    <string name="permlab_changeComponentState" msgid="6335576775711095931">"enable or disable app components"</string>
+    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Allows the app to change whether a component of another app is enabled or not. Malicious apps may use this to disable important tablet capabilities. Care must be taken with this permission, as it is possible to get app components into an unusable, inconsistent or unstable state."</string>
+    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Allows the app to change whether a component of another app is enabled or not. Malicious apps may use this to disable important phone capabilities. Care must be taken with this permission, as it is possible to get app components into an unusable, inconsistent or unstable state."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"grant or revoke permissions"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Allows an application to grant or revoke specific permissions for it or other applications. Malicious applications may use this to access features for which you have not granted them permission."</string>
+    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"set preferred apps"</string>
+    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Allows the app to modify your preferred apps. Malicious apps may silently change the apps that are run, spoofing your existing apps to collect private data from you."</string>
+    <string name="permlab_writeSettings" msgid="2226195290955224730">"modify system settings"</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"Allows the app to modify the system\'s settings data. Malicious apps may corrupt your system\'s configuration."</string>
+    <string name="permlab_writeSecureSettings" msgid="204676251876718288">"modify secure system settings"</string>
+    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"Allows the app to modify the system\'s secure settings data. Not for use by normal apps."</string>
+    <string name="permlab_writeGservices" msgid="2149426664226152185">"modify the Google services map"</string>
+    <string name="permdesc_writeGservices" msgid="1287309437638380229">"Allows the app to modify the Google services map. Not for use by normal apps."</string>
+    <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"run at startup"</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Allows the app to have itself started as soon as the system has finished booting. This can make it take longer to start the tablet and allow the app to slow down the overall tablet by always running."</string>
+    <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Allows the app to have itself started as soon as the system has finished booting. This can make it take longer to start the phone and allow the app to slow down the overall phone by always running."</string>
+    <string name="permlab_broadcastSticky" msgid="7919126372606881614">"send sticky broadcast"</string>
+    <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Allows the app to send sticky broadcasts, which remain after the broadcast ends. Excessive use may make the tablet slow or unstable by causing it to use too much memory."</string>
+    <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Allows the app to send sticky broadcasts, which remain after the broadcast ends. Excessive use may make the phone slow or unstable by causing it to use too much memory."</string>
+    <string name="permlab_readContacts" msgid="8348481131899886131">"read your contacts"</string>
+    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Allows the app to read data about your contacts stored on your tablet, including the frequency with which you\'ve called, emailed or communicated in other ways with specific individuals. This permission allows apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
+    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Allows the app to read data about your contacts stored on your phone, including the frequency with which you\'ve called, emailed or communicated in other ways with specific individuals. This permission allows apps to save your contact data, and malicious apps may share contact data without your knowledge."</string>
+    <string name="permlab_writeContacts" msgid="5107492086416793544">"modify your contacts"</string>
+    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Allows the app to modify the data about your contacts stored on your tablet, including the frequency with which you\'ve called, emailed or communicated in other ways with specific contacts. This permission allows apps to delete contact data."</string>
+    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Allows the app to modify the data about your contacts stored on your phone, including the frequency with which you\'ve called, emailed or communicated in other ways with specific contacts. This permission allows apps to delete contact data."</string>
+    <string name="permlab_readCallLog" msgid="3478133184624102739">"read call log"</string>
+    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Allows the app to read your tablet\'s call log, including data about incoming and outgoing calls. This permission allows apps to save your call log data, and malicious apps may share call log data without your knowledge."</string>
+    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Allows the app to read your phone\'s call log, including data about incoming and outgoing calls. This permission allows apps to save your call log data, and malicious apps may share call log data without your knowledge."</string>
+    <string name="permlab_writeCallLog" msgid="8552045664743499354">"write call log"</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Allows the app to modify your tablet\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to erase or modify your call log."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Allows the app to modify your phone\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to erase or modify your call log."</string>
+    <string name="permlab_readProfile" msgid="4701889852612716678">"read your own contact card"</string>
+    <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Allows the app to read personal profile information stored on your device, such as your name and contact information. This means that the app can identify you and may send your profile information to others."</string>
+    <string name="permlab_writeProfile" msgid="907793628777397643">"modify your own contact card"</string>
+    <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Allows the app to change or add to personal profile information stored on your device, such as your name and contact information. This means that the app can identify you and may send your profile information to others."</string>
+    <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"read your social stream"</string>
+    <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Allows the app to access and sync social updates from you and your friends. Be careful when sharing information - this allows the app to read communications between you and your friends on social networks, regardless of confidentiality. Note: this permission may not be enforced on all social networks."</string>
+    <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"write to your social stream"</string>
+    <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Allows the app to display social updates from your friends. Be careful when sharing information - this allows the app to produce messages that may appear to come from a friend. Note: this permission may not be enforced on all social networks."</string>
+    <string name="permlab_readCalendar" msgid="5972727560257612398">"read calendar events plus confidential information"</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Allows the app to read all calendar events stored on your tablet, including those of friends or co-workers. This may allow the app to share or save your calendar data, regardless of confidentiality or sensitivity."</string>
+    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Allows the app to read all calendar events stored on your phone, including those of friends or co-workers. This may allow the app to share or save your calendar data, regardless of confidentiality or sensitivity."</string>
+    <string name="permlab_writeCalendar" msgid="8438874755193825647">"add or modify calendar events and send emails to guests without owners\' knowledge"</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Allows the app to add, remove and change events that you can modify on your tablet, including those of friends or co-workers. This may allow the app to send messages that appear to come from calendar owners, or modify events without the owners\' knowledge."</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Allows the app to add, remove and change events that you can modify on your phone, including those of friends or co-workers. This may allow the app to send messages that appear to come from calendar owners, or modify events without the owners\' knowledge."</string>
+    <string name="permlab_accessMockLocation" msgid="8688334974036823330">"mock location sources for testing"</string>
+    <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Create mock location sources for testing or install a new location provider. This allows the app to override the location and/or status returned by other location sources such as GPS or location providers."</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"access extra location provider commands"</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"Allows the app to access extra location provider commands. This may allow the app to interfere with the operation of the GPS or other location sources."</string>
+    <string name="permlab_installLocationProvider" msgid="6578101199825193873">"permission to install a location provider"</string>
+    <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"Create mock location sources for testing or install a new location provider. This allows the app to override the location and/or status returned by other location sources such as GPS or location providers."</string>
+    <string name="permlab_accessFineLocation" msgid="1191898061965273372">"precise location (GPS and network-based)"</string>
+    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Allows the app to get your precise location using the Global Positioning System (GPS) or network location sources such as mobile towers and Wi-Fi. These location services must be turned on and available to your device for the app to use them. Apps may use this to determine where you are, and may consume additional battery power."</string>
+    <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"approximate location (network-based)"</string>
+    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Allows the app to get your approximate location. This location is derived by location services using network location sources such as mobile towers and Wi-Fi. These location services must be turned on and available to your device for the app to use them. Apps may use this to determine approximately where you are."</string>
+    <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"access SurfaceFlinger"</string>
+    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Allows the app to use SurfaceFlinger low-level features."</string>
+    <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"read frame buffer"</string>
+    <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Allows the app to read the content of the frame buffer."</string>
+    <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"configure Wi-Fi displays"</string>
+    <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Allows the app to configure and connect to Wi-Fi displays."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"control Wi-Fi displays"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Allows the app to control low-level features of Wi-Fi displays."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"capture audio output"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Allows the app to capture and redirect audio output."</string>
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Hotword detection"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Allows the app to capture audio for Hotword detection. The capture can happen in the background but does not prevent other audio capture (e.g. Camcorder)."</string>
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"capture video output"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Allows the app to capture and redirect video output."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"capture secure video output"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Allows the app to capture and redirect secure video output."</string>
+    <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"change your audio settings"</string>
+    <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Allows the app to modify global audio settings such as volume and which speaker is used for output."</string>
+    <string name="permlab_recordAudio" msgid="3876049771427466323">"record audio"</string>
+    <string name="permdesc_recordAudio" msgid="4906839301087980680">"Allows the app to record audio with the microphone. This permission allows the app to record audio at any time without your confirmation."</string>
+    <string name="permlab_camera" msgid="3616391919559751192">"take pictures and videos"</string>
+    <string name="permdesc_camera" msgid="8497216524735535009">"Allows the app to take pictures and videos with the camera. This permission allows the app to use the camera at any time without your confirmation."</string>
+    <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"disable transmit indicator LED when camera is in use"</string>
+    <string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"Allows a pre-installed system application to disable the camera use indicator LED."</string>
+    <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"permanently disable tablet"</string>
+    <string name="permlab_brick" product="default" msgid="8337817093326370537">"permanently disable phone"</string>
+    <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"Allows the app to permanently disable the entire tablet. This is very dangerous."</string>
+    <string name="permdesc_brick" product="default" msgid="5788903297627283099">"Allows the app to permanently disable the entire phone. This is very dangerous."</string>
+    <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"force tablet reboot"</string>
+    <string name="permlab_reboot" product="default" msgid="2898560872462638242">"force phone reboot"</string>
+    <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"Allows the app to force the tablet to reboot."</string>
+    <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"Allows the app to force the phone to reboot."</string>
+    <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"access USB storage filesystem"</string>
+    <string name="permlab_mount_unmount_filesystems" product="default" msgid="4402305049890953810">"access SD Card filesystem"</string>
+    <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"Allows the app to mount and unmount file systems for removable storage."</string>
+    <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"Erase USB storage"</string>
+    <string name="permlab_mount_format_filesystems" product="default" msgid="262582698639274056">"erase SD Card"</string>
+    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"Allows the app to format removable storage."</string>
+    <string name="permlab_asec_access" msgid="3411338632002193846">"get information on internal storage"</string>
+    <string name="permdesc_asec_access" msgid="3094563844593878548">"Allows the application to access information on internal storage."</string>
+    <string name="permlab_asec_create" msgid="6414757234789336327">"create internal storage"</string>
+    <string name="permdesc_asec_create" msgid="4558869273585856876">"Allows the application to create internal storage."</string>
+    <string name="permlab_asec_destroy" msgid="526928328301618022">"destroy internal storage"</string>
+    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"Allows the app to destroy internal storage."</string>
+    <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"mount/unmount internal storage"</string>
+    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"Allows the app to mount/unmount internal storage."</string>
+    <string name="permlab_asec_rename" msgid="7496633954080472417">"rename internal storage"</string>
+    <string name="permdesc_asec_rename" msgid="1794757588472127675">"Allows the app to rename internal storage."</string>
+    <string name="permlab_vibrate" msgid="7696427026057705834">"control vibration"</string>
+    <string name="permdesc_vibrate" msgid="6284989245902300945">"Allows the app to control the vibrator."</string>
+    <string name="permlab_flashlight" msgid="2155920810121984215">"control flashlight"</string>
+    <string name="permdesc_flashlight" msgid="6522284794568368310">"Allows the app to control the flashlight."</string>
+    <string name="permlab_manageUsb" msgid="1113453430645402723">"manage preferences and permissions for USB devices"</string>
+    <string name="permdesc_manageUsb" msgid="7776155430218239833">"Allows the app to manage preferences and permissions for USB devices."</string>
+    <string name="permlab_accessMtp" msgid="4953468676795917042">"implement MTP protocol"</string>
+    <string name="permdesc_accessMtp" msgid="6532961200486791570">"Allows access to the kernel MTP driver to implement the MTP USB protocol."</string>
+    <string name="permlab_hardware_test" msgid="4148290860400659146">"test hardware"</string>
+    <string name="permdesc_hardware_test" msgid="6597964191208016605">"Allows the app to control various peripherals for the purpose of hardware testing."</string>
+    <string name="permlab_callPhone" msgid="3925836347681847954">"directly call phone numbers"</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"Allows the app to call phone numbers without your intervention. This may result in unexpected charges or calls. Note that this doesn\'t allow the app to call emergency numbers. Malicious apps may cost you money by making calls without your confirmation."</string>
+    <string name="permlab_callPrivileged" msgid="4198349211108497879">"directly call any phone numbers"</string>
+    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"Allows the app to call any phone number, including emergency numbers, without your intervention. Malicious apps may place unnecessary and illegal calls to emergency services."</string>
+    <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"directly start CDMA tablet setup"</string>
+    <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"directly start CDMA phone setup"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"Allows the app to start CDMA provisioning. Malicious apps may unnecessarily start CDMA provisioning."</string>
+    <string name="permlab_locationUpdates" msgid="7785408253364335740">"control location update notifications"</string>
+    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Allows the app to enable/disable location update notifications from the radio. Not for use by normal apps."</string>
+    <string name="permlab_checkinProperties" msgid="7855259461268734914">"access check-in properties"</string>
+    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Allows the app read/write access to properties uploaded by the check-in service. Not for use by normal apps."</string>
+    <string name="permlab_bindGadget" msgid="776905339015863471">"choose widgets"</string>
+    <string name="permdesc_bindGadget" msgid="8261326938599049290">"Allows the app to tell the system which widgets can be used by which app. An app with this permission can give other apps access to personal data. Not for use by normal apps."</string>
+    <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"modify phone status"</string>
+    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Allows the app to control the phone features of the device. An app with this permission can switch networks, turn the phone radio on and off and the like without ever notifying you."</string>
+    <string name="permlab_readPhoneState" msgid="9178228524507610486">"read phone status and identity"</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Allows the app to access the phone features of the device. This permission allows the app to determine the phone number and device IDs, whether a call is active and the remote number connected by a call."</string>
+    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"prevent tablet from sleeping"</string>
+    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"prevent phone from sleeping"</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Allows the app to prevent the tablet from going to sleep."</string>
+    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Allows the app to prevent the phone from going to sleep."</string>
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"transmit infrared"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Allows the app to use the tablet\'s infrared transmitter."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Allows the app to use the phone\'s infrared transmitter."</string>
+    <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"turn tablet on or off"</string>
+    <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"turn phone on or off"</string>
+    <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Allows the app to turn the tablet on or off."</string>
+    <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"Allows the app to turn the phone on or off."</string>
+    <string name="permlab_factoryTest" msgid="3715225492696416187">"run in factory test mode"</string>
+    <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"Run as a low-level manufacturer test, allowing complete access to the tablet hardware. Only available when a tablet is running in manufacturer test mode."</string>
+    <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"Run as a low-level manufacturer test, allowing complete access to the phone hardware. Only available when a phone is running in manufacturer test mode."</string>
+    <string name="permlab_setWallpaper" msgid="6627192333373465143">"set wallpaper"</string>
+    <string name="permdesc_setWallpaper" msgid="7373447920977624745">"Allows the app to set the system wallpaper."</string>
+    <string name="permlab_setWallpaperHints" msgid="3278608165977736538">"adjust your wallpaper size"</string>
+    <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Allows the app to set the system wallpaper size hints."</string>
+    <string name="permlab_masterClear" msgid="2315750423139697397">"reset system to factory defaults"</string>
+    <string name="permdesc_masterClear" msgid="3665380492633910226">"Allows the app to completely reset the system to its factory settings, erasing all data, configuration and installed apps."</string>
+    <string name="permlab_setTime" msgid="2021614829591775646">"set time"</string>
+    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"Allows the app to change the tablet\'s clock time."</string>
+    <string name="permdesc_setTime" product="default" msgid="1855702730738020">"Allows the app to change the phone\'s clock time."</string>
+    <string name="permlab_setTimeZone" msgid="2945079801013077340">"set time zone"</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Allows the app to change the tablet\'s time zone."</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Allows the app to change the phone\'s time zone."</string>
+    <string name="permlab_accountManagerService" msgid="4829262349691386986">"act as the Account Manager Service"</string>
+    <string name="permdesc_accountManagerService" msgid="1948455552333615954">"Allows the app to make calls to Account Authenticators."</string>
+    <string name="permlab_getAccounts" msgid="1086795467760122114">"find accounts on the device"</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Allows the app to get the list of accounts known by the tablet. This may include any accounts created by applications that you have installed."</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Allows the app to get the list of accounts known by the phone. This may include any accounts created by applications that you have installed."</string>
+    <string name="permlab_authenticateAccounts" msgid="5265908481172736933">"create accounts and set passwords"</string>
+    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"Allows the app to use the account authenticator capabilities of the Account Manager, including creating accounts and getting and setting their passwords."</string>
+    <string name="permlab_manageAccounts" msgid="4983126304757177305">"add or remove accounts"</string>
+    <string name="permdesc_manageAccounts" msgid="8698295625488292506">"Allows the app to perform operations like adding and removing accounts, and deleting their password."</string>
+    <string name="permlab_useCredentials" msgid="235481396163877642">"use accounts on the device"</string>
+    <string name="permdesc_useCredentials" msgid="7984227147403346422">"Allows the app to request authentication tokens."</string>
+    <string name="permlab_accessNetworkState" msgid="4951027964348974773">"view network connections"</string>
+    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Allows the app to view information about network connections such as which networks exist and are connected."</string>
+    <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"full network access"</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Allows the app to create network sockets and use customised network protocols. The browser and other applications provide means to send data to the Internet, so this permission is not required to send data to the Internet."</string>
+    <string name="permlab_writeApnSettings" msgid="505660159675751896">"change/intercept network settings and traffic"</string>
+    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Allows the app to change network settings and to intercept and inspect all network traffic, for example to change the proxy and port of any APN. Malicious apps may monitor, redirect or modify network packets without your knowledge."</string>
+    <string name="permlab_changeNetworkState" msgid="958884291454327309">"change network connectivity"</string>
+    <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Allows the app to change the state of network connectivity."</string>
+    <string name="permlab_changeTetherState" msgid="5952584964373017960">"change tethered connectivity"</string>
+    <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Allows the app to change the state of tethered network connectivity."</string>
+    <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"change background data usage setting"</string>
+    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Allows the app to change the background data usage setting."</string>
+    <string name="permlab_accessWifiState" msgid="5202012949247040011">"view Wi-Fi connections"</string>
+    <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Allows the app to view information about Wi-Fi networking, such as whether Wi-Fi is enabled and name of connected Wi-Fi devices."</string>
+    <string name="permlab_changeWifiState" msgid="6550641188749128035">"connect and disconnect from Wi-Fi"</string>
+    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Allows the app to connect to and disconnect from Wi-Fi access points and to make changes to device configuration for Wi-Fi networks."</string>
+    <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"allow Wi-Fi Multicast reception"</string>
+    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Allows the app to receive packets sent to all devices on a Wi-Fi network using multicast addresses, not just your tablet. It uses more power than the non-multicast mode."</string>
+    <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Allows the app to receive packets sent to all devices on a Wi-Fi network using multicast addresses, not just your phone. It uses more power than the non-multicast mode."</string>
+    <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"access Bluetooth settings"</string>
+    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Allows the app to configure the local Bluetooth tablet and to discover and pair with remote devices."</string>
+    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Allows the app to configure the local Bluetooth phone and to discover and pair with remote devices."</string>
+    <string name="permlab_accessWimaxState" msgid="4195907010610205703">"connect and disconnect from WiMAX"</string>
+    <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"Allows the app to determine whether WiMAX is enabled and information about any WiMAX networks that are connected."</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"change WiMAX state"</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Allows the app to connect the tablet to and disconnect the tablet from WiMAX networks."</string>
+    <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"Allows the app to connect the phone to and disconnect the phone from WiMAX networks."</string>
+    <string name="permlab_bluetooth" msgid="6127769336339276828">"pair with Bluetooth devices"</string>
+    <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Allows the app to view the configuration of Bluetooth on the tablet and to make and accept connections with paired devices."</string>
+    <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Allows the app to view the configuration of the Bluetooth on the phone and to make and accept connections with paired devices."</string>
+    <string name="permlab_nfc" msgid="4423351274757876953">"control Near-Field Communication"</string>
+    <string name="permdesc_nfc" msgid="7120611819401789907">"Allows the app to communicate with Near Field Communication (NFC) tags, cards and readers."</string>
+    <string name="permlab_disableKeyguard" msgid="3598496301486439258">"disable your screen lock"</string>
+    <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Allows the app to disable the keylock and any associated password security. For example, the phone disables the keylock when receiving an incoming phone call, then re-enables the keylock when the call is finished."</string>
+    <string name="permlab_readSyncSettings" msgid="6201810008230503052">"read sync settings"</string>
+    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Allows the app to read the sync settings for an account. For example, this can determine whether the People app is synced with an account."</string>
+    <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"toggle sync on and off"</string>
+    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Allows an app to modify the sync settings for an account. For example, this can be used to enable syncing of the People app with an account."</string>
+    <string name="permlab_readSyncStats" msgid="7396577451360202448">"read sync statistics"</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Allows an app to read the sync stats for an account, including the history of sync events and how much data is synced."</string>
+    <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"read subscribed feeds"</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Allows the app to get details about the currently synced feeds."</string>
+    <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"write subscribed feeds"</string>
+    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"Allows the app to modify your currently synced feeds. Malicious apps may change your synced feeds."</string>
+    <string name="permlab_readDictionary" msgid="4107101525746035718">"read terms you added to the dictionary"</string>
+    <string name="permdesc_readDictionary" msgid="659614600338904243">"Allows the app to read all words, names and phrases that the user may have stored in the user dictionary."</string>
+    <string name="permlab_writeDictionary" msgid="2183110402314441106">"add words to user-defined dictionary"</string>
+    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Allows the app to write new words into the user dictionary."</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"test access to protected storage"</string>
+    <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"test access to protected storage"</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"Allows the app to test a permission for USB storage that will be available on future devices."</string>
+    <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"Allows the app to test a permission for the SD card that will be available on future devices."</string>
+    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"modify or delete the contents of your USB storage"</string>
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"modify or delete the contents of your SD card"</string>
+    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Allows the app to write to the USB storage."</string>
+    <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Allows the app to write to the SD card."</string>
+    <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modify/delete internal media storage contents"</string>
+    <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Allows the app to modify the contents of the internal media storage."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"manage document storage"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Allows the app to manage document storage."</string>
+    <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"access external storage of all users"</string>
+    <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Allows the app to access external storage for all users."</string>
+    <string name="permlab_cache_filesystem" msgid="5656487264819669824">"access the cache file system"</string>
+    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Allows the app to read and write the cache file system."</string>
+    <string name="permlab_use_sip" msgid="5986952362795870502">"make/receive Internet calls"</string>
+    <string name="permdesc_use_sip" msgid="4717632000062674294">"Allows the app to use the SIP service to make/receive Internet calls."</string>
+    <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"read historical network usage"</string>
+    <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"Allows the app to read historical network usage for specific networks and apps."</string>
+    <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"manage network policy"</string>
+    <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Allows the app to manage network policies and define app-specific rules."</string>
+    <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"modify network usage accounting"</string>
+    <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Allows the app to modify how network usage is accounted against apps. Not for use by normal apps."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"modify socket marks"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Allows the app to modify socket marks for routing"</string>
+    <string name="permlab_accessNotifications" msgid="7673416487873432268">"access notifications"</string>
+    <string name="permdesc_accessNotifications" msgid="458457742683431387">"Allows the app to retrieve, examine, and clear notifications, including those posted by other apps."</string>
+    <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"bind to a notification listener service"</string>
+    <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Allows the holder to bind to the top-level interface of a notification listener service. Should never be needed for normal apps."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"invoke the carrier-provided configuration app"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Allows the holder to invoke the carrier-provided configuration app. Should never be needed for normal apps."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"listen for observations on network conditions"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Allows an application to listen for observations on network conditions. Should never be needed for normal apps."</string>
+    <string name="policylab_limitPassword" msgid="4497420728857585791">"Set password rules"</string>
+    <string name="policydesc_limitPassword" msgid="3252114203919510394">"Control the length and the characters allowed in screen-unlock passwords."</string>
+    <string name="policylab_watchLogin" msgid="914130646942199503">"Monitor screen-unlock attempts"</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Monitor the number of incorrect passwords typed when unlocking the screen and lock the tablet or erase all the tablet\'s data if too many incorrect passwords are typed."</string>
+    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Monitor the number of incorrect passwords typed when unlocking the screen and lock the phone or erase all the phone\'s data if too many incorrect passwords are typed."</string>
+    <string name="policylab_resetPassword" msgid="2620077191242688955">"Change the screen-unlock password"</string>
+    <string name="policydesc_resetPassword" msgid="605963962301904458">"Change the screen-unlock password."</string>
+    <string name="policylab_forceLock" msgid="2274085384704248431">"Lock the screen"</string>
+    <string name="policydesc_forceLock" msgid="1141797588403827138">"Control how and when the screen locks."</string>
+    <string name="policylab_wipeData" msgid="3910545446758639713">"Erase all data"</string>
+    <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Erase the tablet\'s data without warning by performing a factory data reset."</string>
+    <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Erase the phone\'s data without warning by performing a factory data reset."</string>
+    <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Set the device global proxy"</string>
+    <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Set the device\'s global proxy to be used while policy is enabled. Only the first device admin sets the effective global proxy."</string>
+    <string name="policylab_expirePassword" msgid="885279151847254056">"Set lock-screen password expiry"</string>
+    <string name="policydesc_expirePassword" msgid="1729725226314691591">"Control how frequently the lock-screen password must be changed."</string>
+    <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Set storage encryption"</string>
+    <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"Require that stored app data be encrypted."</string>
+    <string name="policylab_disableCamera" msgid="6395301023152297826">"Disable cameras"</string>
+    <string name="policydesc_disableCamera" msgid="2306349042834754597">"Prevent use of all device cameras."</string>
+    <string name="policylab_disableKeyguardFeatures" msgid="266329104542638802">"Disable features in keyguard"</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="3467082272186534614">"Prevent use of some features in keyguard."</string>
+  <string-array name="phoneTypes">
+    <item msgid="8901098336658710359">"Home"</item>
+    <item msgid="869923650527136615">"Mobile"</item>
+    <item msgid="7897544654242874543">"Work"</item>
+    <item msgid="1103601433382158155">"Work Fax"</item>
+    <item msgid="1735177144948329370">"Home Fax"</item>
+    <item msgid="603878674477207394">"Pager"</item>
+    <item msgid="1650824275177931637">"Other"</item>
+    <item msgid="9192514806975898961">"Custom"</item>
+  </string-array>
+  <string-array name="emailAddressTypes">
+    <item msgid="8073994352956129127">"Home"</item>
+    <item msgid="7084237356602625604">"Work"</item>
+    <item msgid="1112044410659011023">"Other"</item>
+    <item msgid="2374913952870110618">"Custom"</item>
+  </string-array>
+  <string-array name="postalAddressTypes">
+    <item msgid="6880257626740047286">"Home"</item>
+    <item msgid="5629153956045109251">"Work"</item>
+    <item msgid="4966604264500343469">"Other"</item>
+    <item msgid="4932682847595299369">"Custom"</item>
+  </string-array>
+  <string-array name="imAddressTypes">
+    <item msgid="1738585194601476694">"Home"</item>
+    <item msgid="1359644565647383708">"Work"</item>
+    <item msgid="7868549401053615677">"Other"</item>
+    <item msgid="3145118944639869809">"Custom"</item>
+  </string-array>
+  <string-array name="organizationTypes">
+    <item msgid="7546335612189115615">"Work"</item>
+    <item msgid="4378074129049520373">"Other"</item>
+    <item msgid="3455047468583965104">"Custom"</item>
+  </string-array>
+  <string-array name="imProtocols">
+    <item msgid="8595261363518459565">"AIM"</item>
+    <item msgid="7390473628275490700">"Windows Live"</item>
+    <item msgid="7882877134931458217">"Yahoo"</item>
+    <item msgid="5035376313200585242">"Skype"</item>
+    <item msgid="7532363178459444943">"QQ"</item>
+    <item msgid="3713441034299660749">"Google Talk"</item>
+    <item msgid="2506857312718630823">"ICQ"</item>
+    <item msgid="1648797903785279353">"Jabber"</item>
+  </string-array>
+    <string name="phoneTypeCustom" msgid="1644738059053355820">"Custom"</string>
+    <string name="phoneTypeHome" msgid="2570923463033985887">"Home"</string>
+    <string name="phoneTypeMobile" msgid="6501463557754751037">"Mobile"</string>
+    <string name="phoneTypeWork" msgid="8863939667059911633">"Work"</string>
+    <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Work Fax"</string>
+    <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Home Fax"</string>
+    <string name="phoneTypePager" msgid="7582359955394921732">"Pager"</string>
+    <string name="phoneTypeOther" msgid="1544425847868765990">"Other"</string>
+    <string name="phoneTypeCallback" msgid="2712175203065678206">"Callback"</string>
+    <string name="phoneTypeCar" msgid="8738360689616716982">"Car"</string>
+    <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Company Main"</string>
+    <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string>
+    <string name="phoneTypeMain" msgid="6766137010628326916">"Main"</string>
+    <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Other Fax"</string>
+    <string name="phoneTypeRadio" msgid="4093738079908667513">"Radio"</string>
+    <string name="phoneTypeTelex" msgid="3367879952476250512">"Telex"</string>
+    <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY/TDD"</string>
+    <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Work Mobile"</string>
+    <string name="phoneTypeWorkPager" msgid="649938731231157056">"Work Pager"</string>
+    <string name="phoneTypeAssistant" msgid="5596772636128562884">"Assistant"</string>
+    <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string>
+    <string name="eventTypeCustom" msgid="7837586198458073404">"Customised"</string>
+    <string name="eventTypeBirthday" msgid="2813379844211390740">"Birthday"</string>
+    <string name="eventTypeAnniversary" msgid="3876779744518284000">"Anniversary"</string>
+    <string name="eventTypeOther" msgid="7388178939010143077">"Other"</string>
+    <string name="emailTypeCustom" msgid="8525960257804213846">"Custom"</string>
+    <string name="emailTypeHome" msgid="449227236140433919">"Home"</string>
+    <string name="emailTypeWork" msgid="3548058059601149973">"Work"</string>
+    <string name="emailTypeOther" msgid="2923008695272639549">"Other"</string>
+    <string name="emailTypeMobile" msgid="119919005321166205">"Mobile"</string>
+    <string name="postalTypeCustom" msgid="8903206903060479902">"Custom"</string>
+    <string name="postalTypeHome" msgid="8165756977184483097">"Home"</string>
+    <string name="postalTypeWork" msgid="5268172772387694495">"Work"</string>
+    <string name="postalTypeOther" msgid="2726111966623584341">"Other"</string>
+    <string name="imTypeCustom" msgid="2074028755527826046">"Custom"</string>
+    <string name="imTypeHome" msgid="6241181032954263892">"Home"</string>
+    <string name="imTypeWork" msgid="1371489290242433090">"Work"</string>
+    <string name="imTypeOther" msgid="5377007495735915478">"Other"</string>
+    <string name="imProtocolCustom" msgid="6919453836618749992">"Custom"</string>
+    <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string>
+    <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string>
+    <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">"Hangouts"</string>
+    <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string>
+    <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string>
+    <string name="imProtocolNetMeeting" msgid="8287625655986827971">"Net Meeting"</string>
+    <string name="orgTypeWork" msgid="29268870505363872">"Work"</string>
+    <string name="orgTypeOther" msgid="3951781131570124082">"Other"</string>
+    <string name="orgTypeCustom" msgid="225523415372088322">"Custom"</string>
+    <string name="relationTypeCustom" msgid="3542403679827297300">"Customised"</string>
+    <string name="relationTypeAssistant" msgid="6274334825195379076">"Assistant"</string>
+    <string name="relationTypeBrother" msgid="8757913506784067713">"Brother"</string>
+    <string name="relationTypeChild" msgid="1890746277276881626">"Child"</string>
+    <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"Domestic Partner"</string>
+    <string name="relationTypeFather" msgid="5228034687082050725">"Father"</string>
+    <string name="relationTypeFriend" msgid="7313106762483391262">"Friend"</string>
+    <string name="relationTypeManager" msgid="6365677861610137895">"Manager"</string>
+    <string name="relationTypeMother" msgid="4578571352962758304">"Mother"</string>
+    <string name="relationTypeParent" msgid="4755635567562925226">"Parent"</string>
+    <string name="relationTypePartner" msgid="7266490285120262781">"Partner"</string>
+    <string name="relationTypeReferredBy" msgid="101573059844135524">"Referred by"</string>
+    <string name="relationTypeRelative" msgid="1799819930085610271">"Relative"</string>
+    <string name="relationTypeSister" msgid="1735983554479076481">"Sister"</string>
+    <string name="relationTypeSpouse" msgid="394136939428698117">"Spouse"</string>
+    <string name="sipAddressTypeCustom" msgid="2473580593111590945">"Customised"</string>
+    <string name="sipAddressTypeHome" msgid="6093598181069359295">"Home"</string>
+    <string name="sipAddressTypeWork" msgid="6920725730797099047">"Work"</string>
+    <string name="sipAddressTypeOther" msgid="4408436162950119849">"Other"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Type PIN code"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Type PUK and new PIN code"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK code"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"New PIN Code"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Touch to type password"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Type password to unlock"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Type PIN to unlock"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Incorrect PIN code."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"To unlock, press Menu, then 0."</string>
+    <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"Emergency number"</string>
+    <string name="lockscreen_carrier_default" msgid="8963839242565653192">"No service"</string>
+    <string name="lockscreen_screen_locked" msgid="7288443074806832904">"Screen locked."</string>
+    <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Press Menu to unlock or place emergency call."</string>
+    <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Press Menu to unlock."</string>
+    <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Draw pattern to unlock"</string>
+    <string name="lockscreen_emergency_call" msgid="5347633784401285225">"Emergency call"</string>
+    <string name="lockscreen_return_to_call" msgid="5244259785500040021">"Return to call"</string>
+    <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Correct!"</string>
+    <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Try again"</string>
+    <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Try again"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Maximum Face Unlock attempts exceeded"</string>
+    <string name="lockscreen_plugged_in" msgid="8057762828355572315">"Charging, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_charged" msgid="321635745684060624">"Charged"</string>
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_low_battery" msgid="1482873981919249740">"Connect your charger."</string>
+    <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"No SIM card"</string>
+    <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"No SIM card in tablet."</string>
+    <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"No SIM card in phone."</string>
+    <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Insert a SIM card."</string>
+    <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"The SIM card is missing or not readable. Insert a SIM card."</string>
+    <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Unusable SIM card."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Your SIM card has been permanently disabled.\n Contact your wireless service provider for another SIM card."</string>
+    <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Previous track button"</string>
+    <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Next-track button"</string>
+    <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Pause button"</string>
+    <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Play button"</string>
+    <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Stop button"</string>
+    <string name="emergency_calls_only" msgid="6733978304386365407">"Emergency calls only"</string>
+    <string name="lockscreen_network_locked_message" msgid="143389224986028501">"Network locked"</string>
+    <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM card is PUK-locked."</string>
+    <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"See the User Guide or contact Customer Care."</string>
+    <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM card is locked."</string>
+    <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Unlocking SIM card…"</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using your Google sign-in.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"You have drawn your unlock pattern incorrectly <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using your Google sign-in.\n\n Please try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the tablet will be reset to factory default and all user data will be lost."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the phone will be reset to factory default and all user data will be lost."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. The tablet will now be reset to factory default."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The phone will now be reset to factory default."</string>
+    <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Try again in <xliff:g id="NUMBER">%d</xliff:g> seconds."</string>
+    <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Forgotten pattern?"</string>
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Account unlock"</string>
+    <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"Too many pattern attempts"</string>
+    <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"To unlock, sign in with your Google account."</string>
+    <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Username (email)"</string>
+    <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Password"</string>
+    <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Sign in"</string>
+    <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Invalid username or password."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Forgot your username or password?\nVisit "<b>"google.co.uk/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Checking…"</string>
+    <string name="lockscreen_unlock_label" msgid="737440483220667054">"Unlock"</string>
+    <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Sound on"</string>
+    <string name="lockscreen_sound_off_label" msgid="996822825154319026">"Sound off"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Pattern started"</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Pattern cleared"</string>
+    <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Cell added"</string>
+    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Pattern completed"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d of %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Add widget"</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Empty"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Unlock area expanded."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Unlock area collapsed."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> widget."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"User selector"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Status"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Camera"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Media controls"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Widget reordering started."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Widget reordering ended."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> deleted."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Expand unlock area."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Slide unlock."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Pattern unlock."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Face unlock."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Pin unlock."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Password unlock."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Pattern area."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Slide area."</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="granularity_label_character" msgid="7336470535385009523">"character"</string>
+    <string name="granularity_label_word" msgid="7075570328374918660">"word"</string>
+    <string name="granularity_label_link" msgid="5815508880782488267">"link"</string>
+    <string name="granularity_label_line" msgid="5764267235026120888">"line"</string>
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
+    <string name="factorytest_failed" msgid="5410270329114212041">"Factory test failed"</string>
+    <string name="factorytest_not_system" msgid="4435201656767276723">"The FACTORY_TEST action is only supported for packages installed in /system/app."</string>
+    <string name="factorytest_no_action" msgid="872991874799998561">"No package was found that provides the FACTORY_TEST action."</string>
+    <string name="factorytest_reboot" msgid="6320168203050791643">"Reboot"</string>
+    <string name="js_dialog_title" msgid="1987483977834603872">"The page at \"<xliff:g id="TITLE">%s</xliff:g>\" says:"</string>
+    <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
+    <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Confirm Navigation"</string>
+    <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Leave this Page"</string>
+    <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Stay on this Page"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nAre you sure you want to navigate away from this page?"</string>
+    <string name="save_password_label" msgid="6860261758665825069">"Confirm"</string>
+    <string name="double_tap_toast" msgid="4595046515400268881">"Tip: double-tap to zoom in and out."</string>
+    <string name="autofill_this_form" msgid="4616758841157816676">"Auto-fill"</string>
+    <string name="setup_autofill" msgid="7103495070180590814">"Set up Auto-fill"</string>
+    <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
+    <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
+    <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
+    <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
+    <string name="autofill_province" msgid="2231806553863422300">"Province"</string>
+    <string name="autofill_postal_code" msgid="4696430407689377108">"Postcode"</string>
+    <string name="autofill_state" msgid="6988894195520044613">"State"</string>
+    <string name="autofill_zip_code" msgid="8697544592627322946">"Zip code"</string>
+    <string name="autofill_county" msgid="237073771020362891">"County"</string>
+    <string name="autofill_island" msgid="4020100875984667025">"Island"</string>
+    <string name="autofill_district" msgid="8400735073392267672">"District"</string>
+    <string name="autofill_department" msgid="5343279462564453309">"Department"</string>
+    <string name="autofill_prefecture" msgid="2028499485065800419">"Prefecture"</string>
+    <string name="autofill_parish" msgid="8202206105468820057">"Parish"</string>
+    <string name="autofill_area" msgid="3547409050889952423">"Area"</string>
+    <string name="autofill_emirate" msgid="2893880978835698818">"Emirate"</string>
+    <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"read your Web bookmarks and history"</string>
+    <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Allows the app to read the history of all URLs that the Browser has visited, and all of the Browser\'s bookmarks. Note: this permission may not be enforced by third-party browsers or other applications with web browsing capabilities."</string>
+    <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"write web bookmarks and history"</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Allows the app to modify the Browser\'s history or bookmarks stored on your tablet. This may allow the app to delete or modify Browser data. Note: this permission may not be enforced by third-party browsers or other applications with web browsing capabilities."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Allows the app to modify the Browser\'s history or bookmarks stored on your phone. This may allow the app to delete or modify Browser data. Note: this permission may not be enforced by third-party browsers or other applications with web browsing capabilities."</string>
+    <string name="permlab_setAlarm" msgid="1379294556362091814">"set an alarm"</string>
+    <string name="permdesc_setAlarm" msgid="316392039157473848">"Allows the app to set an alarm in an installed alarm clock app. Some alarm clock apps may not implement this feature."</string>
+    <string name="permlab_addVoicemail" msgid="5525660026090959044">"add voicemail"</string>
+    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Allows the app to add messages to your voicemail inbox."</string>
+    <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"Modify Browser geo-location permissions"</string>
+    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Allows the app to modify the Browser\'s geo-location permissions. Malicious apps may use this to allow sending location information to arbitrary websites."</string>
+    <string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"verify packages"</string>
+    <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"Allows the app to verify a package is installable."</string>
+    <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"bind to a package verifier"</string>
+    <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Allows the holder to make requests of package verifiers. Should never be needed for normal apps."</string>
+    <string name="permlab_serialPort" msgid="546083327654631076">"access serial ports"</string>
+    <string name="permdesc_serialPort" msgid="2991639985224598193">"Allows the holder to access serial ports using the SerialManager API."</string>
+    <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"access content providers externally"</string>
+    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Allows the holder to access content providers from the shell. Should never be needed for normal apps."</string>
+    <string name="permlab_updateLock" msgid="3527558366616680889">"discourage automatic device updates"</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"Allows the holder to offer information to the system about when would be a good time for a non-interactive reboot to upgrade the device."</string>
+    <string name="save_password_message" msgid="767344687139195790">"Do you want the browser to remember this password?"</string>
+    <string name="save_password_notnow" msgid="6389675316706699758">"Not now"</string>
+    <string name="save_password_remember" msgid="6491879678996749466">"Remember"</string>
+    <string name="save_password_never" msgid="8274330296785855105">"Never"</string>
+    <string name="open_permission_deny" msgid="7374036708316629800">"You don\'t have permission to open this page."</string>
+    <string name="text_copied" msgid="4985729524670131385">"Text copied to clipboard."</string>
+    <string name="more_item_label" msgid="4650918923083320495">"More"</string>
+    <string name="prepend_shortcut_label" msgid="2572214461676015642">"Menu+"</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">"delete"</string>
+    <string name="search_go" msgid="8298016669822141719">"Search"</string>
+    <string name="searchview_description_search" msgid="6749826639098512120">"Search"</string>
+    <string name="searchview_description_query" msgid="5911778593125355124">"Search query"</string>
+    <string name="searchview_description_clear" msgid="1330281990951833033">"Clear query"</string>
+    <string name="searchview_description_submit" msgid="2688450133297983542">"Submit query"</string>
+    <string name="searchview_description_voice" msgid="2453203695674994440">"Voice search"</string>
+    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Enable Explore by Touch?"</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> wants to enable Explore by Touch. When Explore by Touch is turned on, you can hear or see descriptions of what\'s under your finger or perform gestures to interact with the tablet."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> wants to enable Explore by Touch. When Explore by Touch is turned on, you can hear or see descriptions of what\'s under your finger or perform gestures to interact with the phone."</string>
+    <string name="oneMonthDurationPast" msgid="7396384508953779925">"1 month ago"</string>
+    <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Before 1 month ago"</string>
+  <plurals name="num_seconds_ago">
+    <item quantity="one" msgid="4869870056547896011">"1 second ago"</item>
+    <item quantity="other" msgid="3903706804349556379">"<xliff:g id="COUNT">%d</xliff:g> seconds ago"</item>
+  </plurals>
+  <plurals name="num_minutes_ago">
+    <item quantity="one" msgid="3306787433088810191">"1 minute ago"</item>
+    <item quantity="other" msgid="2176942008915455116">"<xliff:g id="COUNT">%d</xliff:g> minutes ago"</item>
+  </plurals>
+  <plurals name="num_hours_ago">
+    <item quantity="one" msgid="9150797944610821849">"1 hour ago"</item>
+    <item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> hours ago"</item>
+  </plurals>
+  <plurals name="last_num_days">
+    <item quantity="other" msgid="3069992808164318268">"Last <xliff:g id="COUNT">%d</xliff:g> days"</item>
+  </plurals>
+    <string name="last_month" msgid="3959346739979055432">"Last month"</string>
+    <string name="older" msgid="5211975022815554840">"Older"</string>
+  <plurals name="num_days_ago">
+    <item quantity="one" msgid="861358534398115820">"yesterday"</item>
+    <item quantity="other" msgid="2479586466153314633">"<xliff:g id="COUNT">%d</xliff:g> days ago"</item>
+  </plurals>
+  <plurals name="in_num_seconds">
+    <item quantity="one" msgid="2729745560954905102">"in 1 second"</item>
+    <item quantity="other" msgid="1241926116443974687">"in <xliff:g id="COUNT">%d</xliff:g> seconds"</item>
+  </plurals>
+  <plurals name="in_num_minutes">
+    <item quantity="one" msgid="8793095251325200395">"in 1 minute"</item>
+    <item quantity="other" msgid="3330713936399448749">"in <xliff:g id="COUNT">%d</xliff:g> minutes"</item>
+  </plurals>
+  <plurals name="in_num_hours">
+    <item quantity="one" msgid="7164353342477769999">"in 1 hour"</item>
+    <item quantity="other" msgid="547290677353727389">"in <xliff:g id="COUNT">%d</xliff:g> hours"</item>
+  </plurals>
+  <plurals name="in_num_days">
+    <item quantity="one" msgid="5413088743009839518">"tomorrow"</item>
+    <item quantity="other" msgid="5109449375100953247">"in <xliff:g id="COUNT">%d</xliff:g> days"</item>
+  </plurals>
+  <plurals name="abbrev_num_seconds_ago">
+    <item quantity="one" msgid="1849036840200069118">"1 sec ago"</item>
+    <item quantity="other" msgid="3699169366650930415">"<xliff:g id="COUNT">%d</xliff:g> secs ago"</item>
+  </plurals>
+  <plurals name="abbrev_num_minutes_ago">
+    <item quantity="one" msgid="6361490147113871545">"1 min ago"</item>
+    <item quantity="other" msgid="851164968597150710">"<xliff:g id="COUNT">%d</xliff:g> mins ago"</item>
+  </plurals>
+  <plurals name="abbrev_num_hours_ago">
+    <item quantity="one" msgid="4796212039724722116">"1 hour ago"</item>
+    <item quantity="other" msgid="6889970745748538901">"<xliff:g id="COUNT">%d</xliff:g> hours ago"</item>
+  </plurals>
+  <plurals name="abbrev_num_days_ago">
+    <item quantity="one" msgid="8463161711492680309">"yesterday"</item>
+    <item quantity="other" msgid="3453342639616481191">"<xliff:g id="COUNT">%d</xliff:g> days ago"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_seconds">
+    <item quantity="one" msgid="5842225370795066299">"in 1 sec"</item>
+    <item quantity="other" msgid="5495880108825805108">"in <xliff:g id="COUNT">%d</xliff:g> secs"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_minutes">
+    <item quantity="one" msgid="562786149928284878">"in 1 min"</item>
+    <item quantity="other" msgid="4216113292706568726">"in <xliff:g id="COUNT">%d</xliff:g> mins"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_hours">
+    <item quantity="one" msgid="3274708118124045246">"in 1 hour"</item>
+    <item quantity="other" msgid="3705373766798013406">"in <xliff:g id="COUNT">%d</xliff:g> hours"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_days">
+    <item quantity="one" msgid="2178576254385739855">"tomorrow"</item>
+    <item quantity="other" msgid="2973062968038355991">"in <xliff:g id="COUNT">%d</xliff:g> days"</item>
+  </plurals>
+    <string name="preposition_for_date" msgid="9093949757757445117">"on <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="preposition_for_time" msgid="5506831244263083793">"at <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="preposition_for_year" msgid="5040395640711867177">"in<xliff:g id="YEAR">%s</xliff:g>"</string>
+    <string name="day" msgid="8144195776058119424">"day"</string>
+    <string name="days" msgid="4774547661021344602">"days"</string>
+    <string name="hour" msgid="2126771916426189481">"hour"</string>
+    <string name="hours" msgid="894424005266852993">"hours"</string>
+    <string name="minute" msgid="9148878657703769868">"min"</string>
+    <string name="minutes" msgid="5646001005827034509">"mins"</string>
+    <string name="second" msgid="3184235808021478">"sec"</string>
+    <string name="seconds" msgid="3161515347216589235">"secs"</string>
+    <string name="week" msgid="5617961537173061583">"week"</string>
+    <string name="weeks" msgid="6509623834583944518">"weeks"</string>
+    <string name="year" msgid="4001118221013892076">"year"</string>
+    <string name="years" msgid="6881577717993213522">"years"</string>
+  <plurals name="duration_seconds">
+    <item quantity="one" msgid="6962015528372969481">"1 second"</item>
+    <item quantity="other" msgid="1886107766577166786">"<xliff:g id="COUNT">%d</xliff:g> seconds"</item>
+  </plurals>
+  <plurals name="duration_minutes">
+    <item quantity="one" msgid="4915414002546085617">"1 minute"</item>
+    <item quantity="other" msgid="3165187169224908775">"<xliff:g id="COUNT">%d</xliff:g> minutes"</item>
+  </plurals>
+  <plurals name="duration_hours">
+    <item quantity="one" msgid="8917467491248809972">"1 hour"</item>
+    <item quantity="other" msgid="3863962854246773930">"<xliff:g id="COUNT">%d</xliff:g> hours"</item>
+  </plurals>
+    <string name="VideoView_error_title" msgid="3534509135438353077">"Video problem"</string>
+    <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"This video isn\'t valid for streaming to this device."</string>
+    <string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Can\'t play this video."</string>
+    <string name="VideoView_error_button" msgid="2822238215100679592">"OK"</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">"noon"</string>
+    <string name="Noon" msgid="3342127745230013127">"Noon"</string>
+    <string name="midnight" msgid="7166259508850457595">"midnight"</string>
+    <string name="Midnight" msgid="5630806906897892201">"Midnight"</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">"Select all"</string>
+    <string name="cut" msgid="3092569408438626261">"Cut"</string>
+    <string name="copy" msgid="2681946229533511987">"Copy"</string>
+    <string name="paste" msgid="5629880836805036433">"Paste"</string>
+    <string name="replace" msgid="5781686059063148930">"Replace..."</string>
+    <string name="delete" msgid="6098684844021697789">"Delete"</string>
+    <string name="copyUrl" msgid="2538211579596067402">"Copy URL"</string>
+    <string name="selectTextMode" msgid="1018691815143165326">"Select text"</string>
+    <string name="textSelectionCABTitle" msgid="5236850394370820357">"Text selection"</string>
+    <string name="addToDictionary" msgid="4352161534510057874">"Add to dictionary"</string>
+    <string name="deleteText" msgid="6979668428458199034">"Delete"</string>
+    <string name="inputMethod" msgid="1653630062304567879">"Input method"</string>
+    <string name="editTextMenuTitle" msgid="4909135564941815494">"Text actions"</string>
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Storage space running out"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Some system functions may not work"</string>
+    <string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> is running"</string>
+    <string name="app_running_notification_text" msgid="4653586947747330058">"Touch for more information or to stop the app."</string>
+    <string name="ok" msgid="5970060430562524910">"OK"</string>
+    <string name="cancel" msgid="6442560571259935130">"Cancel"</string>
+    <string name="yes" msgid="5362982303337969312">"OK"</string>
+    <string name="no" msgid="5141531044935541497">"Cancel"</string>
+    <string name="dialog_alert_title" msgid="2049658708609043103">"Attention"</string>
+    <string name="loading" msgid="7933681260296021180">"Loading…"</string>
+    <string name="capital_on" msgid="1544682755514494298">"ON"</string>
+    <string name="capital_off" msgid="6815870386972805832">"OFF"</string>
+    <string name="whichApplication" msgid="4533185947064773386">"Complete action using"</string>
+    <string name="alwaysUse" msgid="4583018368000610438">"Use by default for this action."</string>
+    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Clear default in System settings &gt; Apps &gt; Downloaded."</string>
+    <string name="chooseActivity" msgid="7486876147751803333">"Choose an action"</string>
+    <string name="chooseUsbActivity" msgid="6894748416073583509">"Choose an app for the USB device"</string>
+    <string name="noApplications" msgid="2991814273936504689">"No apps can perform this action."</string>
+    <string name="aerr_title" msgid="1905800560317137752"></string>
+    <string name="aerr_application" msgid="932628488013092776">"Unfortunately, <xliff:g id="APPLICATION">%1$s</xliff:g> has stopped."</string>
+    <string name="aerr_process" msgid="4507058997035697579">"Unfortunately, the process <xliff:g id="PROCESS">%1$s</xliff:g> has stopped."</string>
+    <string name="anr_title" msgid="4351948481459135709"></string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> isn\'t responding.\n\nDo you want to close it?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Activity <xliff:g id="ACTIVITY">%1$s</xliff:g> isn\'t responding.\n\nDo you want to close it?"</string>
+    <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> isn\'t responding. Do you want to close it?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Process <xliff:g id="PROCESS">%1$s</xliff:g> isn\'t responding.\n\nDo you want to close it?"</string>
+    <string name="force_close" msgid="8346072094521265605">"OK"</string>
+    <string name="report" msgid="4060218260984795706">"Report"</string>
+    <string name="wait" msgid="7147118217226317732">"Wait"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"The page has become unresponsive.\n\nDo you want to close it?"</string>
+    <string name="launch_warning_title" msgid="1547997780506713581">"App redirected"</string>
+    <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> is now running."</string>
+    <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> was originally launched."</string>
+    <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Scale"</string>
+    <string name="screen_compat_mode_show" msgid="4013878876486655892">"Always show"</string>
+    <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Re-enable this in System settings &gt; Apps &gt; Downloaded."</string>
+    <string name="smv_application" msgid="3307209192155442829">"The app <xliff:g id="APPLICATION">%1$s</xliff:g> (process <xliff:g id="PROCESS">%2$s</xliff:g>) has violated its self-enforced Strict Mode policy."</string>
+    <string name="smv_process" msgid="5120397012047462446">"The process <xliff:g id="PROCESS">%1$s</xliff:g> has violated its self-enforced StrictMode policy."</string>
+    <string name="android_upgrading_title" msgid="1584192285441405746">"Android is upgrading…"</string>
+    <string name="android_upgrading_apk" msgid="7904042682111526169">"Optimising app <xliff:g id="NUMBER_0">%1$d</xliff:g> of <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+    <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Starting apps."</string>
+    <string name="android_upgrading_complete" msgid="1405954754112999229">"Finishing boot."</string>
+    <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> running"</string>
+    <string name="heavy_weight_notification_detail" msgid="1721681741617898865">"Touch to switch to app"</string>
+    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Switch apps?"</string>
+    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Another app is already running that must be stopped before you can start a new one."</string>
+    <string name="old_app_action" msgid="493129172238566282">"Return to <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
+    <string name="old_app_description" msgid="2082094275580358049">"Don\'t start the new app."</string>
+    <string name="new_app_action" msgid="5472756926945440706">"Start <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
+    <string name="new_app_description" msgid="1932143598371537340">"Stop the old app without saving."</string>
+    <string name="sendText" msgid="5209874571959469142">"Choose an action for text"</string>
+    <string name="volume_ringtone" msgid="6885421406845734650">"Ringer volume"</string>
+    <string name="volume_music" msgid="5421651157138628171">"Media volume"</string>
+    <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"Playing through Bluetooth"</string>
+    <string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"Silent ringtone set"</string>
+    <string name="volume_call" msgid="3941680041282788711">"In-call volume"</string>
+    <string name="volume_bluetooth_call" msgid="2002891926351151534">"Bluetooth in-call volume"</string>
+    <string name="volume_alarm" msgid="1985191616042689100">"Alarm volume"</string>
+    <string name="volume_notification" msgid="2422265656744276715">"Notification volume"</string>
+    <string name="volume_unknown" msgid="1400219669770445902">"Volume"</string>
+    <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"Bluetooth volume"</string>
+    <string name="volume_icon_description_ringer" msgid="3326003847006162496">"Ringtone volume"</string>
+    <string name="volume_icon_description_incall" msgid="8890073218154543397">"Call volume"</string>
+    <string name="volume_icon_description_media" msgid="4217311719665194215">"Media volume"</string>
+    <string name="volume_icon_description_notification" msgid="7044986546477282274">"Notification volume"</string>
+    <string name="ringtone_default" msgid="3789758980357696936">"Default ringtone"</string>
+    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Default ringtone (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <string name="ringtone_silent" msgid="7937634392408977062">"None"</string>
+    <string name="ringtone_picker_title" msgid="3515143939175119094">"Ringtones"</string>
+    <string name="ringtone_unknown" msgid="5477919988701784788">"Unknown ringtone"</string>
+  <plurals name="wifi_available">
+    <item quantity="one" msgid="6654123987418168693">"Wi-Fi network available"</item>
+    <item quantity="other" msgid="4192424489168397386">"Wi-Fi networks available"</item>
+  </plurals>
+  <plurals name="wifi_available_detailed">
+    <item quantity="one" msgid="1634101450343277345">"Open available Wi-Fi network"</item>
+    <item quantity="other" msgid="7915895323644292768">"Open Wi-Fi networks available"</item>
+  </plurals>
+    <string name="wifi_available_sign_in" msgid="4029489716605255386">"Sign in to Wi-Fi network"</string>
+    <string name="network_available_sign_in" msgid="8495155593358054676">"Sign in to network"</string>
+    <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
+    <skip />
+    <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Couldn\'t connect to Wi-Fi"</string>
+    <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" has a poor Internet connection."</string>
+    <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+    <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Start Wi-Fi Direct. This will turn off Wi-Fi client/hotspot."</string>
+    <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Couldn\'t start Wi-Fi Direct."</string>
+    <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct is on"</string>
+    <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Touch for settings"</string>
+    <string name="accept" msgid="1645267259272829559">"Accept"</string>
+    <string name="decline" msgid="2112225451706137894">"Decline"</string>
+    <string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Invitation sent"</string>
+    <string name="wifi_p2p_invitation_to_connect_title" msgid="4958803948658533637">"Invitation to connect"</string>
+    <string name="wifi_p2p_from_message" msgid="570389174731951769">"From:"</string>
+    <string name="wifi_p2p_to_message" msgid="248968974522044099">"To:"</string>
+    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"Type the required PIN:"</string>
+    <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"The tablet will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"The phone will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="select_character" msgid="3365550120617701745">"Insert character"</string>
+    <string name="sms_control_title" msgid="7296612781128917719">"Sending SMS messages"</string>
+    <string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; is sending a large number of SMS messages. Do you want to allow this app to continue sending messages?"</string>
+    <string name="sms_control_yes" msgid="3663725993855816807">"Allow"</string>
+    <string name="sms_control_no" msgid="625438561395534982">"Deny"</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; would like to send a message to &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt;."</string>
+    <string name="sms_short_code_details" msgid="3492025719868078457">"This "<font fgcolor="#ffffb060">"may cause charges"</font>" on your mobile account."</string>
+    <string name="sms_premium_short_code_details" msgid="5523826349105123687"><font fgcolor="#ffffb060">"This will cause charges on your mobile account."</font></string>
+    <string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"Send"</string>
+    <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"Cancel"</string>
+    <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"Remember my choice"</string>
+    <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"You can change this later in Settings &gt; Apps"</string>
+    <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Always Allow*"</string>
+    <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Never Allow"</string>
+    <string name="sim_removed_title" msgid="6227712319223226185">"SIM card removed"</string>
+    <string name="sim_removed_message" msgid="2333164559970958645">"The mobile network will be unavailable until you restart with a valid SIM card inserted."</string>
+    <string name="sim_done_button" msgid="827949989369963775">"Done"</string>
+    <string name="sim_added_title" msgid="3719670512889674693">"SIM card added"</string>
+    <string name="sim_added_message" msgid="6599945301141050216">"Restart your device to access the mobile network."</string>
+    <string name="sim_restart_button" msgid="4722407842815232347">"Restart"</string>
+    <string name="time_picker_dialog_title" msgid="8349362623068819295">"Set time"</string>
+    <string name="date_picker_dialog_title" msgid="5879450659453782278">"Set date"</string>
+    <string name="date_time_set" msgid="5777075614321087758">"Set"</string>
+    <string name="date_time_done" msgid="2507683751759308828">"Done"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff33b5e5">"NEW: "</font></string>
+    <string name="perms_description_app" msgid="5139836143293299417">"Provided by <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+    <string name="no_permissions" msgid="7283357728219338112">"No permission required"</string>
+    <string name="perm_costs_money" msgid="4902470324142151116">"this may cost you money"</string>
+    <string name="usb_storage_activity_title" msgid="4465055157209648641">"USB mass storage"</string>
+    <string name="usb_storage_title" msgid="5901459041398751495">"USB connected"</string>
+    <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"You\'ve connected to your computer via USB. Touch the button below if you want to copy files between your computer and your Android\'s USB storage."</string>
+    <string name="usb_storage_message" product="default" msgid="805351000446037811">"You\'ve connected to your computer via USB. Touch the button below if you want to copy files between your computer and your Android\'s SD card."</string>
+    <string name="usb_storage_button_mount" msgid="1052259930369508235">"Turn on USB storage"</string>
+    <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"There\'s a problem using your USB storage for USB mass storage."</string>
+    <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"There\'s a problem using your SD card for USB mass storage."</string>
+    <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB connected"</string>
+    <string name="usb_storage_notification_message" msgid="939822783828183763">"Touch to copy files to/from your computer."</string>
+    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Turn off USB storage"</string>
+    <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"Touch to turn off USB storage."</string>
+    <string name="usb_storage_stop_title" msgid="660129851708775853">"USB storage in use"</string>
+    <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"Before turning off USB storage, unmount (\"eject\") your Android\'s USB storage from your computer."</string>
+    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"Before turning off USB storage, unmount (\"eject\") your Android\'s SD card from your computer."</string>
+    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"Turn off USB storage"</string>
+    <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"There was a problem turning off USB storage. Check that you\'ve unmounted the USB host, then try again."</string>
+    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Turn off USB storage"</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"If you turn on USB storage, some apps that you\'re using will stop and may be unavailable until you turn off USB storage."</string>
+    <string name="dlg_error_title" msgid="7323658469626514207">"USB operation unsuccessful"</string>
+    <string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
+    <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Connected as a media device"</string>
+    <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Connected as a camera"</string>
+    <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Connected as an installer"</string>
+    <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connected to a USB accessory"</string>
+    <string name="usb_notification_message" msgid="2290859399983720271">"Touch for other USB options."</string>
+    <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Format USB storage?"</string>
+    <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Format SD card?"</string>
+    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"All files stored in your USB storage will be erased. This action can\'t be reversed!"</string>
+    <string name="extmedia_format_message" product="default" msgid="14131895027543830">"All data on your card will be lost."</string>
+    <string name="extmedia_format_button_format" msgid="4131064560127478695">"Format"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"USB debugging connected"</string>
+    <string name="adb_active_notification_message" msgid="1016654627626476142">"Touch to disable USB debugging."</string>
+    <string name="select_input_method" msgid="4653387336791222978">"Choose input method"</string>
+    <string name="configure_input_methods" msgid="9091652157722495116">"Set up input methods"</string>
+    <string name="use_physical_keyboard" msgid="6203112478095117625">"Physical keyboard"</string>
+    <string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Select keyboard layout"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Touch to select a keyboard layout."</string>
+    <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="candidates_style" msgid="4333913089637062257"><u>"candidates"</u></string>
+    <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"Preparing USB storage"</string>
+    <string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"Preparing SD card"</string>
+    <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"Checking for errors."</string>
+    <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"Blank USB storage"</string>
+    <string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"Blank SD card"</string>
+    <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"USB storage is blank or has unsupported filesystem."</string>
+    <string name="ext_media_nofs_notification_message" product="default" msgid="8641065641786923604">"SD card is blank or has unsupported file system."</string>
+    <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"Damaged USB storage"</string>
+    <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"Damaged SD card"</string>
+    <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="1795917578395333280">"USB storage is damaged. Try reformatting it."</string>
+    <string name="ext_media_unmountable_notification_message" product="default" msgid="1753898567525568253">"SD card is damaged. Try reformatting it."</string>
+    <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"USB storage removed unexpectedly"</string>
+    <string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"SD card removed unexpectedly"</string>
+    <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"Unmount USB storage before removing to avoid data loss."</string>
+    <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"Unmount SD card before removing to avoid data loss."</string>
+    <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"USB storage safe to remove"</string>
+    <string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"SD card safe to remove"</string>
+    <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"You can safely remove USB storage."</string>
+    <string name="ext_media_safe_unmount_notification_message" product="default" msgid="568841278138377604">"You can safely remove SD card."</string>
+    <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"Removed USB storage"</string>
+    <string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"Removed SD card"</string>
+    <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"USB storage removed. Insert new media."</string>
+    <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"SD card removed. Insert a new one."</string>
+    <string name="activity_list_empty" msgid="1675388330786841066">"No matching activities found."</string>
+    <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"update component usage statistics"</string>
+    <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"Allows the app to modify collected component usage statistics. Not for use by normal apps."</string>
+    <string name="permlab_copyProtectedData" msgid="4341036311211406692">"copy content"</string>
+    <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Allows the app to invoke default container service to copy content. Not for use by normal apps."</string>
+    <string name="permlab_route_media_output" msgid="1642024455750414694">"Route media output"</string>
+    <string name="permdesc_route_media_output" msgid="4932818749547244346">"Allows an application to route media output to other external devices."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Access keyguard secure storage"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Allows an application to access keyguard secure storage."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Control displaying and hiding keyguard"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Allows an application to control keyguard."</string>
+    <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Touch twice for zoom control"</string>
+    <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Couldn\'t add widget."</string>
+    <string name="ime_action_go" msgid="8320845651737369027">"Go"</string>
+    <string name="ime_action_search" msgid="658110271822807811">"Search"</string>
+    <string name="ime_action_send" msgid="2316166556349314424">"Send"</string>
+    <string name="ime_action_next" msgid="3138843904009813834">"Next"</string>
+    <string name="ime_action_done" msgid="8971516117910934605">"Done"</string>
+    <string name="ime_action_previous" msgid="1443550039250105948">"Prev"</string>
+    <string name="ime_action_default" msgid="2840921885558045721">"Execute"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Dial number\n using <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Create contact\n using <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"The following one or more applications request permission to access your account, now and in the future."</string>
+    <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Do you want to allow this request?"</string>
+    <string name="grant_permissions_header_text" msgid="6874497408201826708">"Access request"</string>
+    <string name="allow" msgid="7225948811296386551">"Allow"</string>
+    <string name="deny" msgid="2081879885755434506">"Deny"</string>
+    <string name="permission_request_notification_title" msgid="6486759795926237907">"Permission requested"</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Permission requested\nfor account <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="input_method_binding_label" msgid="1283557179944992649">"Input Method"</string>
+    <string name="sync_binding_label" msgid="3687969138375092423">"Sync"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"Accessibility"</string>
+    <string name="wallpaper_binding_label" msgid="1240087844304687662">"Wallpaper"</string>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"Change wallpaper"</string>
+    <string name="notification_listener_binding_label" msgid="2014162835481906429">"Notification listener"</string>
+    <string name="vpn_title" msgid="19615213552042827">"VPN activated"</string>
+    <string name="vpn_title_long" msgid="6400714798049252294">"VPN is activated by <xliff:g id="APP">%s</xliff:g>"</string>
+    <string name="vpn_text" msgid="3011306607126450322">"Touch to manage the network."</string>
+    <string name="vpn_text_long" msgid="6407351006249174473">"Connected to <xliff:g id="SESSION">%s</xliff:g>. Touch 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_error" msgid="6009249814034708175">"Always-on VPN error"</string>
+    <string name="vpn_lockdown_config" msgid="6415899150671537970">"Touch to configure"</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>
+    <string name="submit" msgid="1602335572089911941">"Submit"</string>
+    <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Car mode enabled"</string>
+    <string name="car_mode_disable_notification_message" msgid="8035230537563503262">"Touch to exit car mode."</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string>
+    <string name="tethered_notification_message" msgid="6857031760103062982">"Touch to set up."</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>
+    <string name="throttle_warning_notification_title" msgid="4890894267454867276">"High mobile data use"</string>
+    <string name="throttle_warning_notification_message" msgid="3340822228599337743">"Touch to learn more about mobile data use."</string>
+    <string name="throttled_notification_title" msgid="6269541897729781332">"Mobile data limit exceeded"</string>
+    <string name="throttled_notification_message" msgid="5443457321354907181">"Touch to learn more about mobile data use."</string>
+    <string name="no_matches" msgid="8129421908915840737">"No matches"</string>
+    <string name="find_on_page" msgid="1946799233822820384">"Find on page"</string>
+  <plurals name="matches_found">
+    <item quantity="one" msgid="8167147081136579439">"1 Match"</item>
+    <item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> of <xliff:g id="TOTAL">%d</xliff:g>"</item>
+  </plurals>
+    <string name="action_mode_done" msgid="7217581640461922289">"Done"</string>
+    <string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"Unmounting USB storage…"</string>
+    <string name="progress_unmounting" product="default" msgid="1327894998409537190">"Unmounting SD card…"</string>
+    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"Erasing USB storage..."</string>
+    <string name="progress_erasing" product="default" msgid="6596988875507043042">"Erasing SD card…"</string>
+    <string name="format_error" product="nosdcard" msgid="6299769563624776948">"Couldn\'t erase USB storage."</string>
+    <string name="format_error" product="default" msgid="7315248696644510935">"Couldn\'t erase SD card."</string>
+    <string name="media_bad_removal" msgid="7960864061016603281">"SD card was removed before being unmounted."</string>
+    <string name="media_checking" product="nosdcard" msgid="418188720009569693">"USB storage is currently being checked."</string>
+    <string name="media_checking" product="default" msgid="7334762503904827481">"SD card is currently being checked."</string>
+    <string name="media_removed" msgid="7001526905057952097">"SD card has been removed."</string>
+    <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"USB storage is currently in use by a computer."</string>
+    <string name="media_shared" product="default" msgid="5706130568133540435">"SD card is currently in use by a computer."</string>
+    <string name="media_unknown_state" msgid="729192782197290385">"External media in unknown state."</string>
+    <string name="share" msgid="1778686618230011964">"Share"</string>
+    <string name="find" msgid="4808270900322985960">"Find"</string>
+    <string name="websearch" msgid="4337157977400211589">"Web Search"</string>
+    <string name="find_next" msgid="5742124618942193978">"Find next"</string>
+    <string name="find_previous" msgid="2196723669388360506">"Find previous"</string>
+    <string name="gpsNotifTicker" msgid="5622683912616496172">"Location request from <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Location request"</string>
+    <string name="gpsNotifMessage" msgid="1374718023224000702">"Requested by <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+    <string name="gpsVerifYes" msgid="2346566072867213563">"Yes"</string>
+    <string name="gpsVerifNo" msgid="1146564937346454865">"No"</string>
+    <string name="sync_too_many_deletes" msgid="5296321850662746890">"Deletion limit exceeded"</string>
+    <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"There are <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> deleted items for <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, account <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. What do you want to do?"</string>
+    <string name="sync_really_delete" msgid="2572600103122596243">"Delete the items"</string>
+    <string name="sync_undo_deletes" msgid="2941317360600338602">"Undo the deletes"</string>
+    <string name="sync_do_nothing" msgid="3743764740430821845">"Do nothing for now"</string>
+    <string name="choose_account_label" msgid="5655203089746423927">"Choose an account"</string>
+    <string name="add_account_label" msgid="2935267344849993553">"Add an account"</string>
+    <string name="add_account_button_label" msgid="3611982894853435874">"Add account"</string>
+    <string name="number_picker_increment_button" msgid="2412072272832284313">"Increase"</string>
+    <string name="number_picker_decrement_button" msgid="476050778386779067">"Decrease"</string>
+    <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> touch and hold."</string>
+    <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Slide up to increase and down to decrease."</string>
+    <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Increase minute"</string>
+    <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Decrease minute"</string>
+    <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Increase hour"</string>
+    <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Decrease hour"</string>
+    <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Set p.m."</string>
+    <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Set a.m."</string>
+    <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Increase month"</string>
+    <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Decrease month"</string>
+    <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Increase day"</string>
+    <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Decrease day"</string>
+    <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Increase year"</string>
+    <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Decrease year"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Cancel"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Done"</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>
+    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Choose an app"</string>
+    <string name="shareactionprovider_share_with" msgid="806688056141131819">"Share with"</string>
+    <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Share with <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+    <string name="content_description_sliding_handle" msgid="415975056159262248">"Sliding handle. Touch &amp; hold."</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Slide up for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Slide down for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Slide left for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Slide right for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Unlock"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Camera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Silent"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Sound on"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Search"</string>
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Swipe to unlock."</string>
+    <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Plug in a headset to hear password keys spoken."</string>
+    <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Dot"</string>
+    <string name="action_bar_home_description" msgid="5293600496601490216">"Navigate home"</string>
+    <string name="action_bar_up_description" msgid="2237496562952152589">"Navigate up"</string>
+    <string name="action_menu_overflow_description" msgid="2295659037509008453">"More options"</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="4891916833657929263">"Internal storage"</string>
+    <string name="storage_sd_card" msgid="3282948861378286745">"SD card"</string>
+    <string name="storage_usb" msgid="3017954059538517278">"USB storage"</string>
+    <string name="extract_edit_menu_button" msgid="8940478730496610137">"Edit"</string>
+    <string name="data_usage_warning_title" msgid="1955638862122232342">"Data usage warning"</string>
+    <string name="data_usage_warning_body" msgid="2814673551471969954">"Touch to view usage and settings."</string>
+    <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-3G data disabled"</string>
+    <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G data disabled"</string>
+    <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobile data disabled"</string>
+    <string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"Wi-Fi data disabled"</string>
+    <string name="data_usage_limit_body" msgid="3317964706973601386">"Touch to enable."</string>
+    <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"2G-3G data limit exceeded"</string>
+    <string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"4G data limit exceeded"</string>
+    <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"Mobile data limit exceeded"</string>
+    <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Wi-Fi data limit exceeded"</string>
+    <string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> over specified limit."</string>
+    <string name="data_usage_restricted_title" msgid="5965157361036321914">"Background data restricted"</string>
+    <string name="data_usage_restricted_body" msgid="6741521330997452990">"Touch to remove restriction."</string>
+    <string name="ssl_certificate" msgid="6510040486049237639">"Security certificate"</string>
+    <string name="ssl_certificate_is_valid" msgid="6825263250774569373">"This certificate is valid."</string>
+    <string name="issued_to" msgid="454239480274921032">"Issued to:"</string>
+    <string name="common_name" msgid="2233209299434172646">"Common name:"</string>
+    <string name="org_name" msgid="6973561190762085236">"Organisation:"</string>
+    <string name="org_unit" msgid="7265981890422070383">"Organisational unit:"</string>
+    <string name="issued_by" msgid="2647584988057481566">"Issued by:"</string>
+    <string name="validity_period" msgid="8818886137545983110">"Validity:"</string>
+    <string name="issued_on" msgid="5895017404361397232">"Issued on:"</string>
+    <string name="expires_on" msgid="3676242949915959821">"Expires on:"</string>
+    <string name="serial_number" msgid="758814067660862493">"Serial number:"</string>
+    <string name="fingerprints" msgid="4516019619850763049">"Fingerprints:"</string>
+    <string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 fingerprint"</string>
+    <string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 fingerprint"</string>
+    <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"See all"</string>
+    <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Choose activity"</string>
+    <string name="share_action_provider_share_with" msgid="5247684435979149216">"Share with"</string>
+    <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="3245653681008218030">"Sending…"</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Launch Browser?"</string>
+    <string name="SetupCallDefault" msgid="5834948469253758575">"Accept call?"</string>
+    <string name="activity_resolver_use_always" msgid="8017770747801494933">"Always"</string>
+    <string name="activity_resolver_use_once" msgid="2404644797149173758">"Just once"</string>
+    <string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"Tablet"</string>
+    <string name="default_audio_route_name" product="default" msgid="4239291273420140123">"Phone"</string>
+    <string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Headphones"</string>
+    <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Dock speakers"</string>
+    <string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string>
+    <string name="default_audio_route_category_name" msgid="3722811174003886946">"System"</string>
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth audio"</string>
+    <string name="wireless_display_route_description" msgid="9070346425023979651">"Wireless display"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Done"</string>
+    <string name="media_route_button_content_description" msgid="5758553567065145276">"Media output"</string>
+    <string name="media_route_status_scanning" msgid="7279908761758293783">"Scanning..."</string>
+    <string name="media_route_status_connecting" msgid="6422571716007825440">"Connecting..."</string>
+    <string name="media_route_status_available" msgid="6983258067194649391">"Available"</string>
+    <string name="media_route_status_not_available" msgid="6739899962681886401">"Not available"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"In use"</string>
+    <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Built-in Screen"</string>
+    <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"HDMI Screen"</string>
+    <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlay #<xliff:g id="ID">%1$d</xliff:g>"</string>
+    <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", secure"</string>
+    <string name="wifi_display_notification_title" msgid="2223050649240326557">"Wireless display is connected"</string>
+    <string name="wifi_display_notification_message" msgid="4498802012464170685">"This screen is showing on another device"</string>
+    <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Disconnect"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Emergency call"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Forgot Pattern"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Wrong Pattern"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Wrong Password"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Wrong PIN"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Try again in <xliff:g id="NUMBER">%1$d</xliff:g> seconds."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Draw your pattern"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Enter SIM PIN"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Enter PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Enter Password"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM is now disabled. Enter PUK code to continue. Contact carrier for details."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Enter desired PIN code"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Confirm desired PIN code"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Unlocking SIM card…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Incorrect PIN code."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Type a PIN that is 4 to 8 numbers."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK code should be 8 numbers or more."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Re-enter the correct PUK code. Repeated attempts will permanently disable the SIM."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN codes do not match"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Too many pattern attempts"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"To unlock, sign in with your Google account."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Username (email)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Password"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Sign in"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Invalid username or password."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Forgot your username or password?\nVisit "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Checking account…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the tablet will be reset to factory default and all user data will be lost."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the phone will be reset to factory default and all user data will be lost."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. The tablet will now be reset to factory default."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The phone will now be reset to factory default."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Remove"</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Raise volume above recommended level?\nListening at high volume for long periods may damage your hearing."</string>
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Keep holding down two fingers to enable accessibility."</string>
+    <string name="accessibility_enabled" msgid="1381972048564547685">"Accessibility enabled."</string>
+    <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accessibility cancelled."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="owner_name" msgid="2716755460376028154">"Owner"</string>
+    <string name="error_message_title" msgid="4510373083082500195">"Error"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"This app doesn\'t support accounts for restricted profiles"</string>
+    <string name="app_not_found" msgid="3429141853498927379">"No application found to handle this action"</string>
+    <string name="revoke" msgid="5404479185228271586">"Revoke"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Cancelled"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Error writing content"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"unknown"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Enter administrator PIN"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Enter PIN"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Incorrect"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Current PIN:"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"New PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Confirm new PIN"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Create a PIN for modifying restrictions"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PINs don\'t match. Try again."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"PIN is too short. Must be at least 4 digits."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Try again in 1 second"</item>
+    <item quantity="other" msgid="4730868920742952817">"Try again in <xliff:g id="COUNT">%d</xliff:g> seconds"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Try again later"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Swipe edge of screen to reveal bar"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Swipe from edge of screen to reveal system bar"</string>
+</resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index a39e61f..29a3023 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -131,6 +131,11 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Demasiadas eliminaciones de <xliff:g id="CONTENT_TYPE">%s</xliff:g>"</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Se ha agotado el espacio de almacenamiento de la tablet. Elimina algunos archivos para liberar espacio."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Se ha agotado el espacio de almacenamiento del dispositivo. Elimina algunos archivos para liberar espacio."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Es posible que la red esté supervisada."</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Yo"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opciones de tablet"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Opciones de dispositivo"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Permite que la aplicación mueva tareas a segundo o a primer plano. La aplicación puede utilizar este permiso para realizar estos movimientos sin indicártelo."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"detener las aplicaciones en ejecución"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Permite que la aplicación elimine tareas y cierre sus aplicaciones. Las aplicaciones malintencionadas pueden usar este permiso para interferir en el comportamiento de otras aplicaciones."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"administrar pilas de actividad"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Permite que la aplicación agregue, elimine y modifique las pilas de actividad en las que se ejecutan otras aplicaciones. Las aplicaciones maliciosas pueden interrumpir el comportamiento de otras aplicaciones."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"Iniciar cualquier actividad"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Permite a la aplicación iniciar una actividad, sin importar si fue exportada ni si se encuentra protegida por permisos."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"Definir compatibilidad de pantalla"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Permite al propietario vincularse a la interfaz de nivel superior de un método de entrada. Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"vincular a un servicio de accesibilidad"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permite al propietario vincularse a la interfaz de nivel superior de un servicio de accesibilidad. Las aplicaciones normales no deberían necesitar este permiso."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"vincular a un servicio de impresión"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Permite al propietario vincularse a la interfaz de nivel superior de un servicio de impresión. Las aplicaciones normales no deberían necesitar este permiso."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"Vincular a un servicio de administración de trabajos de impresión"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Permite al propietario vincularse con la interfaz de nivel superior de un servicio de administración de trabajos de impresión. Las aplicaciones normales no deberían necesitar este permiso."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"Vincular con servicio NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Permite vincular con aplicaciones que emulen tarjetas NFC. Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"vincular a un servicio de texto"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Permite al titular vincularse a la interfaz de nivel superior de un servicio de texto (p. ej., SpellCheckerService). Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"vincular con un servicio de VPN"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Permite al propietario vincularse a la interfaz de nivel superior del servicio de widget. Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interactuar con un administrador de dispositivos"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Permite enviar intentos a un administrador de dispositivos. Las aplicaciones normales no deberían necesitar este permiso."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"agregar o eliminar un administrador de dispositivos"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Permite al propietario agregar o eliminar administradores de dispositivos activos. Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"cambiar la orientación de la pantalla"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Permite que la aplicación cambie la rotación de la pantalla en cualquier momento. Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"cambiar velocidad del puntero"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Permite que la aplicación lea los diversos archivos de registro del sistema. Esto le permite descubrir información general acerca de lo que haces con el dispositivo, que puede incluir información personal o privada."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"Usar cualquier decodificador de medios para la reproducción"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Permite que la aplicación use cualquier decodificador de archivos multimedia instalado para la reproducción."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"administrar credenciales de confianza"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Permite que la aplicación instale y desinstale certificados de CA como credenciales de confianza."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"leer y escribir a recursos dentro del grupo de diagnóstico"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permite que la aplicación lea y escriba en cualquier recurso propiedad del grupo de diagnóstico como, por ejemplo, archivos in/dev. Este permiso podría afectar la seguridad y estabilidad del sistema. SOLO se debe utilizar para diagnósticos específicos de hardware realizados por el fabricante o el operador."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"activar o desactivar componentes de la aplicación"</string>
@@ -462,6 +479,14 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permite que la aplicación configure y se conecte a pantallas Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"controlar pantallas Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Permite que la aplicación controle funciones de bajo nivel de las pantallas Wi-Fi."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"Capturar salida de audio"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Permite que la aplicación capture y redirija la salida de audio."</string>
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Detectar palabras activas"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Permite que la aplicación capture audio para la detección de palabras activas. La captura puede ocurrir en segundo plano, pero no impide otras capturas de audio (por ejemplo, de la videocámara)."</string>
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"Capturar salida de video"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Permite que la aplicación capture y redirija la salida de video."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"Capturar salida de video segura"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Permite que la aplicación capture y redirija la salida de video segura."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"cambiar tu configuración de audio"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Permite que la aplicación modifique la configuración de audio global, por ejemplo, el volumen y el altavoz de salida."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"grabar audio"</string>
@@ -525,6 +550,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"evitar que el dispositivo entre en estado de inactividad"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Permite que la aplicación evite que la tablet entre en estado de inactividad."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Permite que la aplicación evite que el dispositivo entre en estado de inactividad."</string>
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"Transmitir por infrarrojos"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Permite que la aplicación utilice el transmisor infrarrojo de la tablet."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Permite que la aplicación utilice el transmisor infrarrojo del teléfono."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"apagar o encender el tablet"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"apagar o encender el dispositivo"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Permite que la aplicación encienda o apague la tablet."</string>
@@ -613,6 +641,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Admite que la aplicación escriba en la tarjeta SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modificar/eliminar los contenidos del almacenamientos de medios internos"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Permite que la aplicación modifique el contenido del almacenamiento de medios interno."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"Administrar almac. de documen."</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Permite que la aplicación administre el almacenamiento de documentos."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"acceder almacenamiento externo"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Permite que la aplicación acceda al almacenamiento externo de todos los usuarios."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"Acceder al sistema de archivos caché"</string>
@@ -625,10 +655,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Permite que la aplicación administre las políticas de red y defina reglas específicas de la aplicación."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"Modificar la administración del uso de redes"</string>
     <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_markNetworkSocket" msgid="3658527214914959749">"modificar marcas de socket"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Permite que la aplicación modifique marcas de socket para enrutamiento."</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 elimine notificaciones, incluidas aquellas publicadas por otras aplicaciones."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"Vincular a un servicio de agente de escucha de notificaciones"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Permite al propietario vincularse a la interfaz de nivel superior de un servicio de agente de escucha de notificaciones. 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 proveedor"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Permite al propietario ejecutar la aplicación de configuración proporcionada por el proveedor. Las aplicaciones normales no deberían necesitar este permiso."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"Detectar cambios en el estado de la red"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permite que una aplicación detecte cambios en el estado de la red. Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Establecer reglas de contraseña"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlar la longitud y los caracteres permitidos en las contraseñas para desbloquear la pantalla"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Supervisa los intentos para desbloquear la pantalla"</string>
@@ -738,8 +774,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -787,7 +822,7 @@
     <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Volver a intentarlo"</string>
     <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Se superó el máximo de intentos permitido para el desbloqueo facial del dispositivo."</string>
     <string name="lockscreen_plugged_in" msgid="8057762828355572315">"Cargando <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
-    <string name="lockscreen_charged" msgid="321635745684060624">"Cargado"</string>
+    <string name="lockscreen_charged" msgid="321635745684060624">"Cargada"</string>
     <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
     <string name="lockscreen_low_battery" msgid="1482873981919249740">"Conecta tu cargador."</string>
     <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"Sin tarjeta SIM"</string>
@@ -796,7 +831,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Inserta una tarjeta SIM."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Falta la tarjeta SIM o no se puede leer. Introduce una tarjeta SIM."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Tarjeta SIM inutilizable"</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Tu tarjeta SIM se ha inhabilitado de forma permanente."\n" Ponte en contacto con tu proveedor de servicios inalámbricos para obtener otra tarjeta SIM."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Tu tarjeta SIM se ha inhabilitado de forma permanente.\n Ponte en contacto con tu proveedor de servicios inalámbricos para obtener otra tarjeta SIM."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Botón para pista anterior"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Botón para pista siguiente"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Botón Pausa"</string>
@@ -808,11 +843,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Consulta la guía del usuario o comunícate con el servicio de atención al cliente."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"La tarjeta SIM está bloqueada."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Desbloqueando tarjeta SIM…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Estableciste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. "\n\n"Vuelve a intentarlo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Escribiste incorrectamente tu contraseña <xliff:g id="NUMBER_0">%d</xliff:g> veces. "\n\n"Vuelve a intentarlo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Escribiste incorrectamente tu PIN <xliff:g id="NUMBER_0">%d</xliff:g> veces. "\n\n"Vuelve a intentarlo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Has establecido incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos, se te solicitará que desbloquees tu tablet mediante el uso de tu información de acceso de Google."\n\n" Vuelve a intentarlo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Has establecido incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos, se te solicitará que desbloquees tu dispositivo mediante el uso de tu información de acceso de Google."\n\n" Vuelve a intentarlo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Estableciste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nVuelve a intentarlo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Escribiste incorrectamente tu contraseña <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nVuelve a intentarlo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Escribiste incorrectamente tu PIN <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nVuelve a intentarlo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Has establecido incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos, se te solicitará que desbloquees tu tablet mediante el uso de tu información de acceso de Google.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Has establecido incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos, se te solicitará que desbloquees tu dispositivo mediante el uso de tu información de acceso de Google.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Intentaste desbloquear la tablet <xliff:g id="NUMBER_0">%d</xliff:g> veces, pero no lo lograste. Puedes intentarlo <xliff:g id="NUMBER_1">%d</xliff:g> veces más antes de que se restablezcan los valores predeterminados de fábrica de la tablet y se pierdan todos los datos de usuario."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Intentaste desbloquear el dispositivo <xliff:g id="NUMBER_0">%d</xliff:g> veces, pero no lo lograste. Puedes intentarlo <xliff:g id="NUMBER_1">%d</xliff:g> veces más antes de que se restablezcan los valores predeterminados de fábrica del dispositivo y se pierdan todos los datos de usuario."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Intentaste desbloquear la tablet <xliff:g id="NUMBER">%d</xliff:g> veces, pero no lo lograste. Se restablecerán los valores predeterminados de fábrica de la tablet."</string>
@@ -826,7 +861,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Contraseña"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Inicia sesión"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nombre de usuario o contraseña incorrecta."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"¿Olvidaste tu nombre de usuario o contraseña?"\n"Accede a "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"¿Olvidaste tu nombre de usuario o contraseña?\nAccede a "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Comprobando..."</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Desbloquear"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Sonido activado"</string>
@@ -874,7 +909,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Confirmar navegación"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Abandonar esta página"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Quedarme en la página"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"¿Confirmas que quieres salir de esta página?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\n¿Confirmas que quieres salir de esta página?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Confirmar"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Consejo: Toca dos veces para acercar y alejar la imagen."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Autocompletar"</string>
@@ -1080,14 +1115,14 @@
     <string name="aerr_application" msgid="932628488013092776">"Lamentablemente, la aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> se detuvo."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Lamentablemente, el proceso <xliff:g id="PROCESS">%1$s</xliff:g> se detuvo."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> no responde."\n\n"¿Deseas cerrarla?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"La actividad <xliff:g id="ACTIVITY">%1$s</xliff:g> no responde."\n\n"¿Deseas cerrarla?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> no responde.\n\n¿Deseas cerrarla?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"La actividad <xliff:g id="ACTIVITY">%1$s</xliff:g> no responde.\n\n¿Deseas cerrarla?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> no responde. ¿Deseas cerrarla?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"El proceso <xliff:g id="PROCESS">%1$s</xliff:g> no responde."\n\n"¿Deseas cerrarlo?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"El proceso <xliff:g id="PROCESS">%1$s</xliff:g> no responde.\n\n¿Deseas cerrarlo?"</string>
     <string name="force_close" msgid="8346072094521265605">"Aceptar"</string>
     <string name="report" msgid="4060218260984795706">"Notificar"</string>
     <string name="wait" msgid="7147118217226317732">"Esperar"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"La página no responde."\n\n"¿Deseas cerrarla?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"La página no responde.\n\n¿Deseas cerrarla?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Aplicación redireccionada"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> se está ejecutando ahora."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> se inició originalmente."</string>
@@ -1256,6 +1291,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Permite que la aplicación ejecute el servicio de contenedor predeterminado para que copie contenido. Las aplicaciones normales no deben utilizar este permiso."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Dirigir salida de medios"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Permite que la aplicación dirija salidas de medios a otros dispositivos externos."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Acceder al almacenamiento seguro de bloqueos"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Permite que una aplicación acceda al almacenamiento seguro de bloqueos."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Controlar cuándo se muestra y se oculta el bloqueo"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Permite que una aplicación controle los bloqueos."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Toca dos veces para acceder al control de zoom."</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"No se pudo agregar el widget."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Ir"</string>
@@ -1265,15 +1304,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Listo"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Ant."</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Ejecutar"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Marcar el número"\n"con <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Crear contacto "\n"con <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Marcar el número\ncon <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Crear contacto \ncon <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Las siguientes aplicaciones solicitan permiso para acceder a tu cuenta ahora y en el futuro."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"¿Deseas permitir esta solicitud?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Solicitud de acceso"</string>
     <string name="allow" msgid="7225948811296386551">"Permitir"</string>
     <string name="deny" msgid="2081879885755434506">"Denegar"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Permiso solicitado"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Permiso solicitado"\n"para la cuenta <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Permiso solicitado\npara la cuenta <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Método de entrada"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Sincronización"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Accesibilidad"</string>
@@ -1420,7 +1459,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Ver todas"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Elige actividad"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Compartir con"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Dispositivo bloqueado"</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Enviando..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"¿Deseas iniciar el navegador?"</string>
@@ -1441,10 +1479,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Conectando..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Disponible"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"No disponible"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"En uso"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Pantalla integrada"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"Pantalla HDMI"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Superposición #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> ppp"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", segura"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Se conectó la pantalla inalámbrica"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Esta pantalla se muestra en otro dispositivo."</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Desconectar"</string>
@@ -1453,7 +1493,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Patrón incorrecto"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Contraseña incorrecta"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN incorrecto"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Vuelve a intentarlo en <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Vuelve a intentarlo en <xliff:g id="NUMBER">%1$d</xliff:g> segundos."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Dibuja tu patrón."</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Ingresa el PIN de la tarjeta SIM."</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Ingresa el PIN."</string>
@@ -1473,27 +1513,85 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Contraseña"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Acceder"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nombre de usuario o contraseña incorrectos"</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"¿Olvidaste tu nombre de usuario o contraseña?"\n"Accede a "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"¿Olvidaste tu nombre de usuario o contraseña?\nAccede a "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Comprobando la cuenta…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Escribiste incorrectamente tu PIN <xliff:g id="NUMBER_0">%d</xliff:g> veces. "\n\n"Vuelve a intentarlo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Escribiste incorrectamente tu contraseña <xliff:g id="NUMBER_0">%d</xliff:g> veces. "\n\n"Vuelve a intentarlo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Dibujaste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. "\n\n"Vuelve a intentarlo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Escribiste incorrectamente tu PIN <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nVuelve a intentarlo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Escribiste incorrectamente tu contraseña <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nVuelve a intentarlo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Dibujaste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nVuelve a intentarlo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Intentaste desbloquear la tablet <xliff:g id="NUMBER_0">%d</xliff:g> veces, pero no lo lograste. Puedes intentarlo <xliff:g id="NUMBER_1">%d</xliff:g> veces más antes de que se restablezcan los valores predeterminados de fábrica de la tablet y se pierdan todos los datos del usuario."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Intentaste desbloquear el dispositivo <xliff:g id="NUMBER_0">%d</xliff:g> veces, pero no lo lograste. Puedes intentarlo <xliff:g id="NUMBER_1">%d</xliff:g> veces más antes de que se restablezcan los valores predeterminados de fábrica del dispositivo y se pierdan todos los datos del usuario."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Intentaste desbloquear la tablet <xliff:g id="NUMBER">%d</xliff:g> veces, pero no lo lograste. Se restablecerán los valores predeterminados de fábrica de la tablet."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Intentaste desbloquear el dispositivo <xliff:g id="NUMBER">%d</xliff:g> veces, pero no lo lograste. Se restablecerán los valores predeterminados de fábrica del dispositivo."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Dibujaste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos más, se te solicitará que desbloquees tu tablet mediante el uso de una cuenta de correo."\n\n" Vuelve a intentarlo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Dibujaste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos más, se te solicitará que desbloquees tu dispositivo mediante el uso de una cuenta de correo."\n\n" Vuelve a intentarlo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Dibujaste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos más, se te solicitará que desbloquees tu tablet mediante el uso de una cuenta de correo.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Dibujaste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos más, se te solicitará que desbloquees tu dispositivo mediante el uso de una cuenta de correo.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Eliminar"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"¿Quieres subir el volumen por encima del nivel recomendado?"\n"Si escuchas música con el volumen alto durante períodos prolongados, puedes dañar tu audición."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"¿Quieres subir el volumen por encima del nivel recomendado?\nSi escuchas música con el volumen alto durante períodos prolongados, puedes dañar tu audición."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Mantén presionado con dos dedos para activar la accesibilidad."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Se activó la accesibilidad."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Se canceló la accesibilidad."</string>
     <string name="user_switched" msgid="3768006783166984410">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="owner_name" msgid="2716755460376028154">"Propietario"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Error"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Esta aplicación no admite cuentas de perfiles restringidos."</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Esta aplicación no admite cuentas de perfiles restringidos."</string>
     <string name="app_not_found" msgid="3429141853498927379">"No se encontró una aplicación para manejar esta acción."</string>
     <string name="revoke" msgid="5404479185228271586">"Revocar"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Carta"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Carta del gobierno (EE. UU.)"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Oficio"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Oficio Junior"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Doble carta"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloide"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Cancelada"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Error al escribir contenido"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"desconocido"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Ingresar PIN de administrador"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Ingresar PIN"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Incorrecto"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN actual"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"PIN nuevo"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Confirmar PIN nuevo"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Crear PIN para modificar restricciones"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"Los PIN no coinciden. Vuelve a intentarlo."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"El PIN es demasiado corto. Debe tener al menos 4 dígitos."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Intentar en 1 s"</item>
+    <item quantity="other" msgid="4730868920742952817">"Intentar en <xliff:g id="COUNT">%d</xliff:g> s"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Vuelve a intentar más tarde."</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Desliza el borde para ver la barra."</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Desliza el dedo desde el borde de la pantalla para mostrar la barra del sistema."</string>
 </resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 8b666d8..96d81d4 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -131,6 +131,11 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Demasiadas eliminaciones de <xliff:g id="CONTENT_TYPE">%s</xliff:g>"</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Se ha agotado el espacio de almacenamiento del tablet. Elimina algunos archivos para liberar espacio."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Se ha agotado el espacio de almacenamiento del teléfono. Elimina algunos archivos para liberar espacio."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Es posible que la red esté supervisada"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Yo"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opciones del tablet"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Opciones del teléfono"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Permite que la aplicación mueva tareas a segundo o a primer plano. La aplicación puede utilizar este permiso para realizar estos movimientos sin que se lo indique el usuario."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"detener aplicaciones en ejecución"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Permite que la aplicación termine tareas y cierre sus aplicaciones. Las aplicaciones malintencionadas pueden usar este permiso para interferir en el comportamiento de otras aplicaciones."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"administrar pilas de actividad"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Permite que la aplicación añada, elimine y modifique las pilas de actividad en las que se ejecutan otras aplicaciones. Las aplicaciones maliciosas pueden interrumpir el comportamiento de otras aplicaciones."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"iniciar una actividad"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Permite que la aplicación inicie una actividad, independientemente de la protección de permisos o de si está exportada."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"establecer compatibilidad de pantalla"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Permite que se enlace con la interfaz de nivel superior de un método de introducción de texto. Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"enlazar con un servicio de accesibilidad"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permite enlazar con la interfaz de nivel superior de un servicio de accesibilidad. Las aplicaciones normales no deberían necesitar este permiso."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"enlazar con un servicio de impresión"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Permite enlazar con la interfaz de nivel superior de un servicio de impresión. No debe ser necesario para las aplicaciones normales."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"enlazar con un servicio de cola de impresión"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Permite enlazar con la interfaz de nivel superior de un servicio de cola de impresión. No debe ser necesario para las aplicaciones normales."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"enlazar con servicio NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Permite enlazar con aplicaciones que emulen tarjetas NFC. No debe ser necesario para las aplicaciones normales."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"enlazar con un servicio de texto"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Permite enlazar con la interfaz de nivel superior de un servicio de texto (por ejemplo, SpellCheckerService). Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"enlazar con un servicio VPN"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Permite enlazar con la interfaz de nivel superior de un servicio de widget. Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interactuar con el administrador de un dispositivo"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Permite que se envíen intentos a un administrador de dispositivos. Las aplicaciones normales nunca deberían necesitar este permiso."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"añadir o eliminar un administrador de dispositivos"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Permite añadir o eliminar administradores de dispositivos activos. No debe ser necesario para aplicaciones normales."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"cambiar orientación de la pantalla"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Permite que la aplicación cambie la rotación de la pantalla en cualquier momento. Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"cambiar velocidad del puntero"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Permite que la aplicación consulte distintos archivos de registro del sistema. La aplicación puede usar este permiso para obtener información general sobre las acciones que realizas con el dispositivo, que puede incluir datos personales o privados."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"Utilizar cualquier decodificador de archivos multimedia para la reproducción"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Permite que la aplicación use cualquier decodificador de archivos multimedia instalado para la reproducción."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"administrar credenciales de confianza"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Permite que la aplicación instale y desinstale certificados de CA como credenciales de confianza."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"leer/escribir en los recursos propiedad del grupo de diagnóstico"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permite que la aplicación consulte y escriba en cualquier recurso del grupo de diagnóstico como, por ejemplo, archivos en /dev. Este permiso podría afectar a la seguridad y estabilidad del sistema. SOLO se debe usar para diagnósticos específicos de hardware realizados por el fabricante o el operador."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"habilitar o inhabilitar componentes de la aplicación"</string>
@@ -462,6 +479,14 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permite que la aplicación configure pantallas Wi-Fi y se conecte a ellas."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"controlar pantallas Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Permite que la aplicación controle funciones de bajo nivel de pantallas Wi-Fi."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"capturar salida de audio"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Permite que la aplicación capture y redirija la salida de audio."</string>
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Detectar palabras activas"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Permite que la aplicación grabe audio para detectar palabras activas. La grabación se puede realizar en segundo plano pero no impide que se grabe otro tipo de audio (p.ej. la videocámara)."</string>
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"capturar salida de vídeo"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Permite que la aplicación capture y redirija la salida de vídeo."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"capturar salida de vídeo segura"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Permite que la aplicación capture y redirija la salida de vídeo segura."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"cambiar la configuración de audio"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Permite que la aplicación modifique la configuración de audio global (por ejemplo, el volumen y el altavoz de salida)."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"grabar sonido"</string>
@@ -525,6 +550,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"impedir que el teléfono entre en modo de suspensión"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Permite que la aplicación impida que el tablet entre en modo de suspensión."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Permite que la aplicación impida que el teléfono entre en modo de suspensión."</string>
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"transmitir infrarrojos"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Permite que la aplicación utilice el transmisor de infrarrojos del tablet."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Permite que la aplicación utilice el transmisor de infrarrojos del teléfono."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"encender o apagar el tablet"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"encender o apagar el teléfono"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Permite que la aplicación encienda o apague el tablet."</string>
@@ -613,6 +641,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Permite que la aplicación escriba en la tarjeta SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modificar o eliminar el contenido del almacenamiento de medios interno"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Permite que la aplicación modifique el contenido del almacenamiento multimedia interno."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"administrar el almacenamiento de documentos"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Permite que la aplicación administre el almacenamiento de documentos."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"acceder al almacenamiento externo de todos los usuarios"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Permite que la aplicación acceda al almacenamiento externo de todos los usuarios."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"acceder al sistema de archivos almacenado en caché"</string>
@@ -625,10 +655,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Permite que la aplicación administre políticas de red y defina reglas específicas de la aplicación."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"modificar cálculo de uso de red"</string>
     <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_markNetworkSocket" msgid="3658527214914959749">"modificar marcas de socket"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Permite que la aplicación modifique marcas de socket para enrutamiento"</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_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>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permite que una aplicación detecte cambios en el estado de la red. No debe ser necesario para aplicaciones normales."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Establecimiento de reglas de contraseña"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlar la longitud y los caracteres permitidos en las contraseñas de bloqueo de pantalla"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Control de intentos de bloqueo de pantalla"</string>
@@ -738,8 +774,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo!"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <string name="imProtocolGoogleTalk" msgid="493902321140277304">"Conversaciones"</string>
     <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string>
     <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string>
     <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string>
@@ -753,7 +788,7 @@
     <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"Pareja de hecho"</string>
     <string name="relationTypeFather" msgid="5228034687082050725">"Padre"</string>
     <string name="relationTypeFriend" msgid="7313106762483391262">"Amigo/a"</string>
-    <string name="relationTypeManager" msgid="6365677861610137895">"Manager"</string>
+    <string name="relationTypeManager" msgid="6365677861610137895">"Jefe"</string>
     <string name="relationTypeMother" msgid="4578571352962758304">"Madre"</string>
     <string name="relationTypeParent" msgid="4755635567562925226">"Padre/madre"</string>
     <string name="relationTypePartner" msgid="7266490285120262781">"Pareja"</string>
@@ -787,7 +822,7 @@
     <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Vuelve a intentarlo"</string>
     <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Se ha superado el número máximo de intentos de desbloqueo facial."</string>
     <string name="lockscreen_plugged_in" msgid="8057762828355572315">"Cargando (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
-    <string name="lockscreen_charged" msgid="321635745684060624">"Cargado"</string>
+    <string name="lockscreen_charged" msgid="321635745684060624">"Cargada"</string>
     <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
     <string name="lockscreen_low_battery" msgid="1482873981919249740">"Conecta el cargador"</string>
     <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"Falta la tarjeta SIM."</string>
@@ -796,7 +831,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Inserta una tarjeta SIM."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Falta la tarjeta SIM o no se puede leer. Introduce una tarjeta SIM."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Tarjeta SIM inutilizable"</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Tu tarjeta SIM se ha inhabilitado permanentemente."\n" Para obtener otra tarjeta SIM, ponte en contacto con tu proveedor de servicios de telefonía."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Tu tarjeta SIM se ha inhabilitado permanentemente.\n Para obtener otra tarjeta SIM, ponte en contacto con tu proveedor de servicios de telefonía."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Botón de canción anterior"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Botón de siguiente canción"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Botón de pausa"</string>
@@ -808,11 +843,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Consulta la guía del usuario o ponte en contacto con el servicio de atención al cliente."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Introduce el código PIN."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Desbloqueando tarjeta SIM..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Has realizado <xliff:g id="NUMBER_0">%d</xliff:g> intentos fallidos de creación de un patrón de desbloqueo. "\n\n"Inténtalo de nuevo dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Has introducido una contraseña incorrecta <xliff:g id="NUMBER_0">%d</xliff:g> veces. "\n\n"Inténtalo de nuevo dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Has introducido un código PIN incorrecto <xliff:g id="NUMBER_0">%d</xliff:g> veces. "\n\n"Inténtalo de nuevo dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Has fallado <xliff:g id="NUMBER_0">%d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras  <xliff:g id="NUMBER_1">%d</xliff:g> veces, deberás usar tus credenciales de acceso de Google para desbloquear el tablet."\n\n" Inténtalo de nuevo dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Has fallado <xliff:g id="NUMBER_0">%d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras <xliff:g id="NUMBER_1">%d</xliff:g> veces, deberás usar tus credenciales de acceso de Google para desbloquear el teléfono."\n\n" Inténtalo de nuevo dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Has realizado <xliff:g id="NUMBER_0">%d</xliff:g> intentos fallidos de creación de un patrón de desbloqueo. \n\nInténtalo de nuevo dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Has introducido una contraseña incorrecta <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nInténtalo de nuevo dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Has introducido un código PIN incorrecto <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nInténtalo de nuevo dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Has fallado <xliff:g id="NUMBER_0">%d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras  <xliff:g id="NUMBER_1">%d</xliff:g> veces, deberás usar tus credenciales de acceso de Google para desbloquear el tablet.\n\n Inténtalo de nuevo dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Has fallado <xliff:g id="NUMBER_0">%d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras <xliff:g id="NUMBER_1">%d</xliff:g> veces, deberás usar tus credenciales de acceso de Google para desbloquear el teléfono.\n\n Inténtalo de nuevo dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Has intentado desbloquear el tablet <xliff:g id="NUMBER_0">%d</xliff:g> veces, pero no lo has conseguido. Si fallas <xliff:g id="NUMBER_1">%d</xliff:g> veces más, se restablecerán los datos de fábrica y se perderán todos los datos del usuario."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Has intentado desbloquear el teléfono <xliff:g id="NUMBER_0">%d</xliff:g> veces, pero no lo has conseguido. Si fallas <xliff:g id="NUMBER_1">%d</xliff:g> veces más, se restablecerán los datos de fábrica y se perderán todos los datos del usuario."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Has intentado desbloquear el tablet <xliff:g id="NUMBER">%d</xliff:g> veces, pero no lo has conseguido. Se restablecerán los datos de fábrica del dispositivo."</string>
@@ -826,7 +861,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Contraseña"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Iniciar sesión"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nombre de usuario o contraseña no válido"</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Si has olvidado tu nombre de usuario o tu contraseña,"\n"accede a la página "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Si has olvidado tu nombre de usuario o tu contraseña,\naccede a la página "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Comprobando..."</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Desbloquear"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Activar sonido"</string>
@@ -874,7 +909,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Confirmar navegación"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Salir de esta página"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Permanecer en esta página"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"¿Seguro que quieres salir de esta página?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\n¿Seguro que quieres salir de esta página?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Confirmar"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Sugerencia: toca dos veces para ampliar o reducir el contenido."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Autocompletar"</string>
@@ -1080,14 +1115,14 @@
     <string name="aerr_application" msgid="932628488013092776">"Se ha detenido la aplicación <xliff:g id="APPLICATION">%1$s</xliff:g>."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Se ha detenido el proceso <xliff:g id="PROCESS">%1$s</xliff:g>."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"La aplicación <xliff:g id="APPLICATION">%2$s</xliff:g> no responde."\n\n"¿Quieres cerrarla?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"La actividad <xliff:g id="ACTIVITY">%1$s</xliff:g> no responde."\n\n"¿Quieres cerrarla?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"La aplicación <xliff:g id="APPLICATION">%2$s</xliff:g> no responde.\n\n¿Quieres cerrarla?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"La actividad <xliff:g id="ACTIVITY">%1$s</xliff:g> no responde.\n\n¿Quieres cerrarla?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"La aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> no responde. ¿Quieres cerrarla?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"El proceso <xliff:g id="PROCESS">%1$s</xliff:g> no responde."\n\n"¿Quieres cerrarlo?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"El proceso <xliff:g id="PROCESS">%1$s</xliff:g> no responde.\n\n¿Quieres cerrarlo?"</string>
     <string name="force_close" msgid="8346072094521265605">"Aceptar"</string>
     <string name="report" msgid="4060218260984795706">"Informar"</string>
     <string name="wait" msgid="7147118217226317732">"Esperar"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"La página no responde."\n\n"¿Quieres cerrarla?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"La página no responde.\n\n¿Quieres cerrarla?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Aplicación redireccionada"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> se está ejecutando."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"Inicialmente, se inició la aplicación <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
@@ -1256,6 +1291,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Permite que la aplicación ejecute el servicio de contenedor predeterminado para copiar contenido. Las aplicaciones normales no deben usar este permiso."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Dirigir salida de medio"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Permite que la aplicación dirija salidas de medios a otros dispositivos externos."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Acceder al almacenamiento seguro de bloqueos"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Permite que una aplicación acceda al almacenamiento seguro de bloqueos."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Controlar cuándo se muestra y se oculta el bloqueo"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Permite que una aplicación controle los bloqueos."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Toca dos veces para acceder al control de zoom."</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"No se ha podido añadir el widget."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Ir"</string>
@@ -1265,15 +1304,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Listo"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Anterior"</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Ejecutar"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Marcar número"\n"con <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Crear un contacto"\n"a partir de <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Marcar número\ncon <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Crear un contacto\na partir de <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Las siguientes aplicaciones solicitan permiso para acceder a tu cuenta ahora y en el futuro."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"¿Quieres permitir esta solicitud?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Solicitud de acceso"</string>
     <string name="allow" msgid="7225948811296386551">"Permitir"</string>
     <string name="deny" msgid="2081879885755434506">"Denegar"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Permiso solicitado"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Permiso solicitado"\n"para la cuenta <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Permiso solicitado\npara la cuenta <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Método de introducción de texto"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Sincronización"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Accesibilidad"</string>
@@ -1420,7 +1459,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Ver todo"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Seleccionar actividad"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Compartir con"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Dispositivo bloqueado"</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Enviando..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"¿Iniciar el navegador?"</string>
@@ -1441,10 +1479,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Conectando..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Disponible"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"No disponible"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"En uso"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Pantalla integrada"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"Pantalla HDMI"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Superposición #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", seguro"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Pantalla inalámbrica conectada"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Esta pantalla se muestra en otro dispositivo."</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Desconectar"</string>
@@ -1453,7 +1493,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"El patrón es incorrecto"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Contraseña incorrecta"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN incorrecto"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Inténtalo de nuevo en <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Inténtalo de nuevo en <xliff:g id="NUMBER">%1$d</xliff:g> segundos."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Dibuja tu patrón de desbloqueo."</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Introduce el PIN de la tarjeta SIM."</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Introduce el PIN."</string>
@@ -1473,27 +1513,85 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Contraseña"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Iniciar sesión"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"El nombre de usuario o la contraseña no son válidos."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Si has olvidado tu nombre de usuario o tu contraseña,"\n"accede a la página "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Si has olvidado tu nombre de usuario o tu contraseña,\naccede a la página "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Comprobando cuenta…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Has introducido un código PIN incorrecto <xliff:g id="NUMBER_0">%d</xliff:g> veces. "\n\n"Inténtalo de nuevo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Has introducido una contraseña incorrecta <xliff:g id="NUMBER_0">%d</xliff:g> veces. "\n\n"Inténtalo de nuevo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Has fallado <xliff:g id="NUMBER_0">%d</xliff:g> veces al dibujar tu patrón de desbloqueo. "\n\n"Inténtalo de nuevo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Has introducido un código PIN incorrecto <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nInténtalo de nuevo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Has introducido una contraseña incorrecta <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nInténtalo de nuevo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Has fallado <xliff:g id="NUMBER_0">%d</xliff:g> veces al dibujar tu patrón de desbloqueo. \n\nInténtalo de nuevo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Has intentado desbloquear el tablet <xliff:g id="NUMBER_0">%d</xliff:g> veces, pero no lo has conseguido. Si fallas otras <xliff:g id="NUMBER_1">%d</xliff:g> veces, se restablecerán los datos de fábrica y se perderán todos los datos del usuario."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Has intentado desbloquear el teléfono <xliff:g id="NUMBER_0">%d</xliff:g> veces, pero no lo has conseguido. Si fallas otras <xliff:g id="NUMBER_1">%d</xliff:g> veces, se restablecerán los datos de fábrica y se perderán todos los datos del usuario."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Has intentado desbloquear el tablet <xliff:g id="NUMBER">%d</xliff:g> veces, pero no lo has conseguido. Se restablecerán los datos de fábrica del dispositivo."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Has intentado desbloquear el teléfono <xliff:g id="NUMBER">%d</xliff:g> veces, pero no lo has conseguido. Se restablecerán los datos de fábrica del dispositivo."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Has fallado <xliff:g id="NUMBER_0">%d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras <xliff:g id="NUMBER_1">%d</xliff:g> veces, deberás usar una cuenta de correo electrónico para desbloquear el tablet."\n\n" Inténtalo de nuevo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Has fallado <xliff:g id="NUMBER_0">%d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras <xliff:g id="NUMBER_1">%d</xliff:g> veces, deberás usar una cuenta de correo electrónico para desbloquear el teléfono."\n\n" Inténtalo de nuevo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Has fallado <xliff:g id="NUMBER_0">%d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras <xliff:g id="NUMBER_1">%d</xliff:g> veces, deberás usar una cuenta de correo electrónico para desbloquear el tablet.\n\n Inténtalo de nuevo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Has fallado <xliff:g id="NUMBER_0">%d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras <xliff:g id="NUMBER_1">%d</xliff:g> veces, deberás usar una cuenta de correo electrónico para desbloquear el teléfono.\n\n Inténtalo de nuevo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Eliminar"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"¿Quieres subir el volumen por encima del nivel recomendado?"\n"Escuchar sonidos a alto volumen durante largos períodos de tiempo puede dañar los oídos."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"¿Quieres subir el volumen por encima del nivel recomendado?\nEscuchar sonidos a alto volumen durante largos períodos de tiempo puede dañar los oídos."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Mantén la pantalla pulsada con dos dedos para habilitar las funciones de accesibilidad."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Accesibilidad habilitada"</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accesibilidad cancelada"</string>
     <string name="user_switched" msgid="3768006783166984410">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="owner_name" msgid="2716755460376028154">"Propietario"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Error"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Esta aplicación no admite cuentas de perfiles restringidos"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Esta aplicación no admite cuentas de perfiles restringidos"</string>
     <string name="app_not_found" msgid="3429141853498927379">"No se ha encontrado ninguna aplicación que pueda realizar esta acción."</string>
     <string name="revoke" msgid="5404479185228271586">"Revocar"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Carta"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Carta del gobierno"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Doble carta"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloide"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Cancelado"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Error al escribir contenido"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"desconocido"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Introduce el PIN del administrador"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Introducir PIN"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Incorrecto"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN actual"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"PIN nuevo"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Confirma tu nuevo PIN"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Crear PIN para modificar restricciones"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"Los números PIN no coinciden. Inténtalo de nuevo."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"El PIN es demasiado corto. Debe tener al menos 4 dígitos."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Inténtalo en 1 s"</item>
+    <item quantity="other" msgid="4730868920742952817">"Inténtalo en <xliff:g id="COUNT">%d</xliff:g> s"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Volver a intentar más tarde"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Deslizar borde para mostrar barra"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Desliza el borde de la pantalla para mostrar la barra del sistema"</string>
 </resources>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
new file mode 100644
index 0000000..fd1da20
--- /dev/null
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -0,0 +1,1602 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<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="5973789783504771878">"kB"</string>
+    <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
+    <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
+    <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
+    <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
+    <string name="untitled" msgid="4638956954852782576">"&lt;Pealkirjata&gt;"</string>
+    <string name="ellipsis" msgid="7899829516048813237">"…"</string>
+    <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥."</string>
+    <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Telefoninumbrit pole)"</string>
+    <string name="unknownName" msgid="2277556546742746522">"(Tundmatu)"</string>
+    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Kõnepost"</string>
+    <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
+    <string name="mmiError" msgid="5154499457739052907">"Ühendusprobleem või kehtetu MMI-kood."</string>
+    <string name="mmiFdnError" msgid="5224398216385316471">"Toiming on ainult fikseeritud valimisnumbritele."</string>
+    <string name="serviceEnabled" msgid="8147278346414714315">"Teenus on lubatud."</string>
+    <string name="serviceEnabledFor" msgid="6856228140453471041">"Teenus oli lubatud järgmisele:"</string>
+    <string name="serviceDisabled" msgid="1937553226592516411">"Teenus on keelatud."</string>
+    <string name="serviceRegistered" msgid="6275019082598102493">"Registreerimine õnnestus."</string>
+    <string name="serviceErased" msgid="1288584695297200972">"Kustutamine oli edukas."</string>
+    <string name="passwordIncorrect" msgid="7612208839450128715">"Vale parool."</string>
+    <string name="mmiComplete" msgid="8232527495411698359">"MMI on lõpule viidud."</string>
+    <string name="badPin" msgid="9015277645546710014">"Sisestatud vana PIN-kood pole õige."</string>
+    <string name="badPuk" msgid="5487257647081132201">"Sisestatud PUK-kood pole õige."</string>
+    <string name="mismatchPin" msgid="609379054496863419">"Sisestatud PIN-koodid ei kattu."</string>
+    <string name="invalidPin" msgid="3850018445187475377">"Sisestage 4–8-numbriline PIN-kood."</string>
+    <string name="invalidPuk" msgid="8761456210898036513">"Sisestage 8- või enamanumbriline PUK-kood."</string>
+    <string name="needPuk" msgid="919668385956251611">"SIM-kaart on PUK-lukustatud. Avamiseks sisestage PUK-kood."</string>
+    <string name="needPuk2" msgid="4526033371987193070">"Sisestage SIM-kaardi blokeeringu tühistamiseks PUK2-kood."</string>
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
+    <string name="ClipMmi" msgid="6952821216480289285">"Sissetuleva kõne helistaja ID"</string>
+    <string name="ClirMmi" msgid="7784673673446833091">"Väljuva kõne helistaja ID"</string>
+    <string name="CfMmi" msgid="5123218989141573515">"Kõnede suunamine"</string>
+    <string name="CwMmi" msgid="9129678056795016867">"Koputus"</string>
+    <string name="BaMmi" msgid="455193067926770581">"Kõnepiirang"</string>
+    <string name="PwdMmi" msgid="7043715687905254199">"Parooli muutmine"</string>
+    <string name="PinMmi" msgid="3113117780361190304">"PIN-koodi muutmine"</string>
+    <string name="CnipMmi" msgid="3110534680557857162">"Helistaja number olemas"</string>
+    <string name="CnirMmi" msgid="3062102121430548731">"Helistaja number piiratud"</string>
+    <string name="ThreeWCMmi" msgid="9051047170321190368">"Kolmesuunaline kõne"</string>
+    <string name="RuacMmi" msgid="7827887459138308886">"Soovimatute tüütute kõnede hülgamine"</string>
+    <string name="CndMmi" msgid="3116446237081575808">"Helistaja numbri kohaletoimetamine"</string>
+    <string name="DndMmi" msgid="1265478932418334331">"Mitte häirida"</string>
+    <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"Helistaja ID vaikimisi piiratud. Järgmine kõne: piiratud"</string>
+    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"Helistaja ID vaikimisi piiratud. Järgmine kõne: pole piiratud"</string>
+    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"Vaikimisi pole helistaja ID piiratud. Järgmine kõne: piiratud"</string>
+    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"Helistaja ID pole vaikimisi piiratud. Järgmine kõne: pole piiratud"</string>
+    <string name="serviceNotProvisioned" msgid="8614830180508686666">"Teenus pole ette valmistatud."</string>
+    <string name="CLIRPermanent" msgid="3377371145926835671">"Helistaja ID seadet ei saa muuta."</string>
+    <string name="RestrictedChangedTitle" msgid="5592189398956187498">"Piiratud juurdepääs muutunud"</string>
+    <string name="RestrictedOnData" msgid="8653794784690065540">"Andmesideteenus on blokeeritud."</string>
+    <string name="RestrictedOnEmergency" msgid="6581163779072833665">"Hädaabiteenus on blokeeritud."</string>
+    <string name="RestrictedOnNormal" msgid="4953867011389750673">"Häälteenus on blokeeritud."</string>
+    <string name="RestrictedOnAllVoice" msgid="3396963652108151260">"Kõik häälteenused on blokeeritud."</string>
+    <string name="RestrictedOnSms" msgid="8314352327461638897">"SMS-teenus on blokeeritud."</string>
+    <string name="RestrictedOnVoiceData" msgid="996636487106171320">"Hääl-/andmeteenused on blokeeritud."</string>
+    <string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Hääl-/SMS-teenused on blokeeritud."</string>
+    <string name="RestrictedOnAll" msgid="5643028264466092821">"Kõik hääl-/andme-/SMS-teenused on blokeeritud."</string>
+    <string name="serviceClassVoice" msgid="1258393812335258019">"Hääl"</string>
+    <string name="serviceClassData" msgid="872456782077937893">"Andmed"</string>
+    <string name="serviceClassFAX" msgid="5566624998840486475">"FAKS"</string>
+    <string name="serviceClassSMS" msgid="2015460373701527489">"SMS"</string>
+    <string name="serviceClassDataAsync" msgid="4523454783498551468">"Asünkrooni"</string>
+    <string name="serviceClassDataSync" msgid="7530000519646054776">"Sünkroonimine"</string>
+    <string name="serviceClassPacket" msgid="6991006557993423453">"Pakett"</string>
+    <string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
+    <string name="roamingText0" msgid="7170335472198694945">"Rändlusindikaator sees"</string>
+    <string name="roamingText1" msgid="5314861519752538922">"Rändlusindikaator väljas"</string>
+    <string name="roamingText2" msgid="8969929049081268115">"Rändlusindikaator vilgub"</string>
+    <string name="roamingText3" msgid="5148255027043943317">"Naabruskonnast väljas"</string>
+    <string name="roamingText4" msgid="8808456682550796530">"Arendusest väljas"</string>
+    <string name="roamingText5" msgid="7604063252850354350">"Rändlus – eelistatud süsteem"</string>
+    <string name="roamingText6" msgid="2059440825782871513">"Rändlus – saadaolev süsteem"</string>
+    <string name="roamingText7" msgid="7112078724097233605">"Rändlus – Alliance\'i partner"</string>
+    <string name="roamingText8" msgid="5989569778604089291">"Rändlus – Premiumi partner"</string>
+    <string name="roamingText9" msgid="7969296811355152491">"Rändlus - täisteenuse funktsionaalsus"</string>
+    <string name="roamingText10" msgid="3992906999815316417">"Rändlus - osaline teenusefunktsionaalsus"</string>
+    <string name="roamingText11" msgid="4154476854426920970">"Rändluse bänner sees"</string>
+    <string name="roamingText12" msgid="1189071119992726320">"Rändlusbänner väljas"</string>
+    <string name="roamingTextSearching" msgid="8360141885972279963">"Teenuse otsimine"</string>
+    <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: pole suunatud"</string>
+    <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
+    <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> sekundi pärast"</string>
+    <string name="cfTemplateRegistered" msgid="5073237827620166285">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: pole suunatud"</string>
+    <string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: pole edastatud"</string>
+    <string name="fcComplete" msgid="3118848230966886575">"Funktsioonikood valmis."</string>
+    <string name="fcError" msgid="3327560126588500777">"Ühendusprobleem või kehtetu funktsioonikood."</string>
+    <string name="httpErrorOk" msgid="1191919378083472204">"OK"</string>
+    <string name="httpError" msgid="7956392511146698522">"Ilmnes võrgu viga."</string>
+    <string name="httpErrorLookup" msgid="4711687456111963163">"URL-i ei leita."</string>
+    <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"Saidi autentimise skeemi ei toetata."</string>
+    <string name="httpErrorAuth" msgid="1435065629438044534">"Autentimine ebaõnnestus."</string>
+    <string name="httpErrorProxyAuth" msgid="1788207010559081331">"Puhverserveri kaudu autentimine ebaõnnestus."</string>
+    <string name="httpErrorConnect" msgid="8714273236364640549">"Serveriga ei saanud ühendust."</string>
+    <string name="httpErrorIO" msgid="2340558197489302188">"Serveriga ei saanud ühendust. Proovige hiljem uuesti."</string>
+    <string name="httpErrorTimeout" msgid="4743403703762883954">"Ühendus serveriga aegunud."</string>
+    <string name="httpErrorRedirectLoop" msgid="8679596090392779516">"Leht sisaldab liiga palju serveri ümbersuunamisi."</string>
+    <string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"Protokolli ei toetata."</string>
+    <string name="httpErrorFailedSslHandshake" msgid="96549606000658641">"Turvalist ühendust ei saanud luua."</string>
+    <string name="httpErrorBadUrl" msgid="3636929722728881972">"Lehte pole võimalik avada, kuna URL on vale."</string>
+    <string name="httpErrorFile" msgid="2170788515052558676">"Failile ei pääse juurde."</string>
+    <string name="httpErrorFileNotFound" msgid="6203856612042655084">"Soovitud faili ei leitud."</string>
+    <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Töötlemisel on liiga palju taotlusi. Proovige hiljem uuesti."</string>
+    <string name="notification_title" msgid="8967710025036163822">"Viga kontole <xliff:g id="ACCOUNT">%1$s</xliff:g> sisselogimisel"</string>
+    <string name="contentServiceSync" msgid="8353523060269335667">"Sünkroonimine"</string>
+    <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Sünkroonimine"</string>
+    <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Liiga palju üksuse <xliff:g id="CONTENT_TYPE">%s</xliff:g> kustutusi."</string>
+    <string name="low_memory" product="tablet" msgid="6494019234102154896">"Tahvelarvuti mäluruum on täis. Ruumi vabastamiseks kustutage mõned failid."</string>
+    <string name="low_memory" product="default" msgid="3475999286680000541">"Telefonimälu on täis. Ruumi vabastamiseks kustutage mõned failid."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Võrku võidakse jälgida"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
+    <string name="me" msgid="6545696007631404292">"Mina"</string>
+    <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Tahvelarvuti valikud"</string>
+    <string name="power_dialog" product="default" msgid="1319919075463988638">"Telefonivalikud"</string>
+    <string name="silent_mode" msgid="7167703389802618663">"Hääletu režiim"</string>
+    <string name="turn_on_radio" msgid="3912793092339962371">"Lülitage traadita side sisse"</string>
+    <string name="turn_off_radio" msgid="8198784949987062346">"Lülitage raadioside välja"</string>
+    <string name="screen_lock" msgid="799094655496098153">"Ekraanilukk"</string>
+    <string name="power_off" msgid="4266614107412865048">"Lülita välja"</string>
+    <string name="silent_mode_silent" msgid="319298163018473078">"Helin on väljas"</string>
+    <string name="silent_mode_vibrate" msgid="7072043388581551395">"Vibreeriv helin"</string>
+    <string name="silent_mode_ring" msgid="8592241816194074353">"Helin on sees"</string>
+    <string name="shutdown_progress" msgid="2281079257329981203">"Väljalülitamine ..."</string>
+    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Teie tahvelarvuti lülitub välja."</string>
+    <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Teie telefon lülitub välja."</string>
+    <string name="shutdown_confirm_question" msgid="2906544768881136183">"Kas soovite välja lülitada?"</string>
+    <string name="reboot_safemode_title" msgid="7054509914500140361">"Ohutus režiimis taaskäivitamine"</string>
+    <string name="reboot_safemode_confirm" msgid="55293944502784668">"Kas soovite taaskäivitada ohutus režiimis? See keelab kõik installitud kolmandate osapoolte rakendused. Need taastatakse pärast uuesti taaskäivitamist."</string>
+    <string name="recent_tasks_title" msgid="3691764623638127888">"Hiljutised"</string>
+    <string name="no_recent_tasks" msgid="8794906658732193473">"Hiljutisi rakendusi pole."</string>
+    <string name="global_actions" product="tablet" msgid="408477140088053665">"Tahvelarvuti valikud"</string>
+    <string name="global_actions" product="default" msgid="2406416831541615258">"Telefonivalikud"</string>
+    <string name="global_action_lock" msgid="2844945191792119712">"Ekraanilukk"</string>
+    <string name="global_action_power_off" msgid="4471879440839879722">"Lülita välja"</string>
+    <string name="global_action_bug_report" msgid="7934010578922304799">"Veaaruanne"</string>
+    <string name="bugreport_title" msgid="2667494803742548533">"Veaaruande võtmine"</string>
+    <string name="bugreport_message" msgid="398447048750350456">"Nii kogutakse teavet teie seadme praeguse oleku kohta, et saata see meilisõnumina. Enne kui saate veaaruande ära saata, võtab selle loomine natuke aega; varuge kannatust."</string>
+    <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Hääletu režiim"</string>
+    <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Heli on VÄLJAS"</string>
+    <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Heli on SEES"</string>
+    <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Lennurežiim"</string>
+    <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Lennurežiim on SEES"</string>
+    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Lennurežiim on VÄLJAS"</string>
+    <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
+    <string name="safeMode" msgid="2788228061547930246">"Turvarežiim"</string>
+    <string name="android_system_label" msgid="6577375335728551336">"Android-süsteem"</string>
+    <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Tasulised teenused"</string>
+    <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Tasuliste toimingute tegemine."</string>
+    <string name="permgrouplab_messages" msgid="7521249148445456662">"Teie sõnumid"</string>
+    <string name="permgroupdesc_messages" msgid="7821999071003699236">"Teie SMS-, meili- ja muude sõnumite lugemine ja kirjutamine."</string>
+    <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Teie isiklikud andmed"</string>
+    <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"Otsene juurdepääs teie kohta käivale teabele, mis on salvestatud teie kontaktikaardile."</string>
+    <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Teie sotsiaalne teave"</string>
+    <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Otsene juurdepääs teie kontaktide teabele ja sotsiaalsetele sidemetele."</string>
+    <string name="permgrouplab_location" msgid="635149742436692049">"Teie asukoht"</string>
+    <string name="permgroupdesc_location" msgid="5704679763124170100">"Jälgige oma füüsilist asukohta."</string>
+    <string name="permgrouplab_network" msgid="5808983377727109831">"Võrgusuhtlus"</string>
+    <string name="permgroupdesc_network" msgid="4478299413241861987">"Juurdepääs erinevatele võrgufunktsioonidele."</string>
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"Bluetooth"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"Juurdepääs seadmetele ja võrkudele Bluetoothi kaudu."</string>
+    <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"Heliseaded"</string>
+    <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"Heliseadete muutmine."</string>
+    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Aku mõjutamine"</string>
+    <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Funktsioonide, mis võivad aku kiiresti tühjendada, kasutamine."</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
+    <string name="permgroupdesc_calendar" msgid="5777534316982184416">"Otsene juurdepääs kalendrile ja sündmustele."</string>
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"Kasutaja sõnaraamatu lugemine"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"Kasutaja sõnaraamatu sõnade lugemine."</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"Kasutaja sõnaraamatusse kirjutamine"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"Kasutaja sõnaraamatusse sõnade lisamine."</string>
+    <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Järjehoidjad ja ajalugu"</string>
+    <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Otsene juurdepääs järjehoidjatele ja brauseri ajaloole."</string>
+    <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"Alarm"</string>
+    <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"Äratuskella seadmine."</string>
+    <string name="permgrouplab_voicemail" msgid="4162237145027592133">"Kõnepost"</string>
+    <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"Otsene juurdepääs kõnepostile."</string>
+    <string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
+    <string name="permgroupdesc_microphone" msgid="7106618286905738408">"Otsene juurdepääs mikrofonile heli salvestamiseks."</string>
+    <string name="permgrouplab_camera" msgid="4820372495894586615">"Kaamera"</string>
+    <string name="permgroupdesc_camera" msgid="2933667372289567714">"Otsene juurdepääs kaamerale fotode või videote jäädvustamiseks."</string>
+    <string name="permgrouplab_screenlock" msgid="8275500173330718168">"Lukustuskuva"</string>
+    <string name="permgroupdesc_screenlock" msgid="7067497128925499401">"Võime mõjutada lukustuskuva käitumist seadmes."</string>
+    <string name="permgrouplab_appInfo" msgid="8028789762634147725">"Teie rakenduste teave"</string>
+    <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"Võime mõjutada teiste seadmes olevate rakenduste käitumist."</string>
+    <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"Taustapilt"</string>
+    <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"Seadme taustapildi seadete muutmine."</string>
+    <string name="permgrouplab_systemClock" msgid="406535759236612992">"Kell"</string>
+    <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"Seadme aja või ajavööndi muutmine."</string>
+    <string name="permgrouplab_statusBar" msgid="2095862568113945398">"Olekuriba"</string>
+    <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"Seadme olekuriba seadete muutmine."</string>
+    <string name="permgrouplab_syncSettings" msgid="3341990986147826541">"Sünkroonimisseaded"</string>
+    <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"Juurdepääs sünkroonimisseadetele."</string>
+    <string name="permgrouplab_accounts" msgid="3359646291125325519">"Teie kontod"</string>
+    <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Juurdepääs saadaolevatele kontodele."</string>
+    <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Riistvara juhtelemendid"</string>
+    <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Otsene juurdepääs mobiiltelefoni riistvarale."</string>
+    <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Telefonikõned"</string>
+    <string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"Telefonikõnede jälgimine, salvestamine ja töötlemine."</string>
+    <string name="permgrouplab_systemTools" msgid="4652191644082714048">"Süsteemitööriistad"</string>
+    <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"Süsteemi madalama taseme juurdepääs ja juhtimine."</string>
+    <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"Arendustööriistad"</string>
+    <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"Funktsioonid on vajalikud ainult rakenduste arendajatele."</string>
+    <string name="permgrouplab_display" msgid="4279909676036402636">"Muu rakenduse kasutajaliides"</string>
+    <string name="permgroupdesc_display" msgid="6051002031933013714">"Teiste rakenduste kasutajaliidese mõjutamine."</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"Mäluruum"</string>
+    <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Juurdepääs USB-mäluseadmele."</string>
+    <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Juurdepääs SD-kaardile."</string>
+    <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"Pääsufunktsioonid"</string>
+    <string name="permgroupdesc_accessibilityFeatures" msgid="4205196881678144335">"Funktsioonid, mida saab taotleda abistav tehnoloogia."</string>
+    <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Akna sisu toomine"</string>
+    <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Tutvuge kasutatava akna sisuga."</string>
+    <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Puudutusega sirvimise sisselülitamine"</string>
+    <string name="capability_desc_canRequestTouchExploration" msgid="5800552516779249356">"Puudutatud üksuste nimesid esitatakse häälega ning ekraani saab sirvida puudutustega."</string>
+    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Veebi täiustatud juurdepääsu sisselülitamine"</string>
+    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Rakenduse sisu kättesaadavamaks muutmiseks võidakse installida skripte."</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Sisestatud teksti jälgimine"</string>
+    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Sisaldab isiklikke andmeid, nt krediitkaardi numbreid ja paroole."</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"keela või muuda olekuriba"</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"Võimaldab rakendusel keelata olekuriba või lisada ja eemaldada süsteemiikoone."</string>
+    <string name="permlab_statusBarService" msgid="7247281911387931485">"olekuriba"</string>
+    <string name="permdesc_statusBarService" msgid="716113660795976060">"Võimaldab rakendusel olla olekuriba."</string>
+    <string name="permlab_expandStatusBar" msgid="1148198785937489264">"laienda/ahenda olekuriba"</string>
+    <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"Võimaldab rakendusel laiendada või ahendada olekuriba."</string>
+    <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"marsruutige väljuvad kõned uuesti"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Võimaldab rakendusel töödelda väljuvaid kõnesid ja muuta valitavat numbrit. Luba võimaldab rakendusel jälgida, ümber suunata või takistada väljuvaid kõnesid."</string>
+    <string name="permlab_receiveSms" msgid="8673471768947895082">"võtke vastu tekstisõnumeid (SMS)"</string>
+    <string name="permdesc_receiveSms" msgid="6424387754228766939">"Võimaldab rakendusel vastu võtta ja töödelda SMS-sõnumeid. See tähendab, et rakendus võib jälgida või kustutada teie seadmele saadetud sõnumeid neid teile näitamata."</string>
+    <string name="permlab_receiveMms" msgid="1821317344668257098">"võtke vastu tekstisõnumeid (MMS)"</string>
+    <string name="permdesc_receiveMms" msgid="533019437263212260">"Võimaldab rakendusel vastu võtta ja töödelda multimeediumsõnumeid. See tähendab, et rakendus võib jälgida või kustutada teie seadmele saadetud sõnumeid neid teile näitamata."</string>
+    <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"hädaabiteadete vastuvõtmine"</string>
+    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Võimaldab rakendusel vastu võtta ja töödelda hädaabisõnumeid. See õigus on saadaval ainult süsteemirakendustele."</string>
+    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"mobiilsidesõnumite lugemine"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Võimaldab rakendusel lugeda seadme vastu võetud mobiilsidesõnumeid. Mobiilsidemärguandeid edastatakse mõnes asukohas eriolukorrast teavitamiseks. Pahatahtlikud rakendused võivad segada seadme toimivust või tööd eriolukorra sõnumi vastuvõtmisel."</string>
+    <string name="permlab_sendSms" msgid="5600830612147671529">"saada SMS-sõnumeid"</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"Võimaldab rakendusel saata SMS-sõnumeid. See võib kaasa tuua ootamatuid tasusid. Pahatahtlikud rakendused võivad teile tekitada kulusid, saates sõnumeid teie kinnituseta."</string>
+    <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"sõnumiga vastamise sündmuste saatmine"</string>
+    <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"Lubab rakendusel saata taotlusi teistele sõnumiside rakendustele, et käsitleda sissetulevate kõnedele sõnumiga vastamise sündmusi."</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"lugege oma tekstisõnumeid (SMS või MMS)"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Võimaldab rakendusel lugeda tahvelarvutisse või SIM-kaardile salvestatud SMS-sõnumeid. See võimaldab rakendusel lugeda kõiki SMS-sõnumeid sisust või konfidentsiaalsusest hoolimata."</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Võimaldab rakendusel lugeda telefoni või SIM-kaardile salvestatud SMS-sõnumeid. See võimaldab rakendusel lugeda kõiki SMS-sõnumeid sisust või konfidentsiaalsusest hoolimata."</string>
+    <string name="permlab_writeSms" msgid="3216950472636214774">"muutke oma tekstisõnumeid (SMS või MMS)"</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Võimaldab rakendusel kirjutada teie tahvelarvutisse või SIM-kaardile salvestatud SMS-sõnumitesse. Pahatahtlikud rakendused võivad teie sõnumid kustutada."</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Võimaldab rakendusel kirjutada teie telefoni või SIM-kaardile salvestatud SMS-sõnumitesse. Pahatahtlikud rakendused võivad teie sõnumid kustutada."</string>
+    <string name="permlab_receiveWapPush" msgid="5991398711936590410">"võtke vastu tekstisõnumeid (WAP)"</string>
+    <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Võimaldab rakendusel vastu võtta ja töödelda WAP-sõnumeid. See luba hõlmab võimet jälgida või kustutada teile saadetud sõnumeid neid teile näitamata."</string>
+    <string name="permlab_getTasks" msgid="6466095396623933906">"Käitatud rakenduste toomine"</string>
+    <string name="permdesc_getTasks" msgid="7454215995847658102">"Võimaldab rakendusel tuua teavet praegu ja hiljuti käitatud ülesannete kohta. See võib lubada rakendusel avastada teavet selle kohta, milliseid rakendusi seadmes kasutatakse."</string>
+    <string name="permlab_interactAcrossUsers" msgid="7114255281944211682">"toimingud erinevatel kasutajakontodel"</string>
+    <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Lubab rakendusel teha toiminguid seadme erinevatel kasutajakontodel. Pahatahtlikud rakendused võivad kasutada seda kasutajatevahelise kaitse rikkumiseks."</string>
+    <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"täielik litsents teha toiminguid erinevatel kasutajakontodel"</string>
+    <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Lubab kõiki võimalikke toiminguid erinevatel kasutajakontodel."</string>
+    <string name="permlab_manageUsers" msgid="1676150911672282428">"kasutajate haldamine"</string>
+    <string name="permdesc_manageUsers" msgid="8409306667645355638">"Võimaldab rakendustel hallata seadme kasutajaid, sealhulgas päringuid, loomist ja kustutamist."</string>
+    <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"töötavate rakenduste üksikasjade toomine"</string>
+    <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Võimaldab rakendusel tuua üksikasjalikku teavet praegu töötavate ja hiljuti käitatud ülesannete kohta. Pahatahtlikud rakendused võivad tuvastada privaatset teavet muude rakenduste kohta."</string>
+    <string name="permlab_reorderTasks" msgid="2018575526934422779">"käitatud rakenduste ümberjärjestamine"</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Võimaldab rakendusel teisaldada ülesanded esiplaanile ja taustale. Rakendus võib seda teha teie sisendita."</string>
+    <string name="permlab_removeTasks" msgid="6821513401870377403">"käitatud rakenduste peatamine"</string>
+    <string name="permdesc_removeTasks" msgid="1394714352062635493">"Võimaldab rakendusel eemaldada ülesanded ja peatada nende rakendused. Pahatahtlikud rakendused võivad häirida teiste rakenduste käitumist."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"tegevusvirnade haldamine"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Lubab rakendusel lisada, eemaldada ja muuta tegevusvirnasid, kus teised rakendused töötavad. Pahatahtlikud rakendused võivad häirida teiste rakenduste käitumist."</string>
+    <string name="permlab_startAnyActivity" msgid="2918768238045206456">"mis tahes toimingu alustamine"</string>
+    <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Võimaldab rakendusel käivitada mis tahes toimingu loa kaitsest või eksporditud olekust sõltumata."</string>
+    <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"kuva ühilduvuse seadmine"</string>
+    <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Võimaldab rakendusel juhtida teiste rakenduste kuva ühilduvuse režiimi. Pahatahtlikud rakendused võivad teisi rakendusi häirida."</string>
+    <string name="permlab_setDebugApp" msgid="3022107198686584052">"Rakenduse silumise lubamine"</string>
+    <string name="permdesc_setDebugApp" msgid="4474512416299013256">"Võimaldab rakendusel lülitada sisse teise rakenduse silumise. Pahatahtlikud rakendused võivad seda kasutada teiste rakenduste peatamiseks."</string>
+    <string name="permlab_changeConfiguration" msgid="4162092185124234480">"muutke süsteemi kuvaseadeid"</string>
+    <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"Võimaldab rakendusel muuta praegust konfiguratsiooni, näiteks lokaati või üldist kirjasuurust."</string>
+    <string name="permlab_enableCarMode" msgid="5684504058192921098">"autorežiimi lubamine"</string>
+    <string name="permdesc_enableCarMode" msgid="4853187425751419467">"Võimaldab rakendusel autorežiimi lubada."</string>
+    <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"sulgege teised rakendused"</string>
+    <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"Võimaldab rakendusel lõpetada teiste rakenduste taustaprotsesse. See võib peatada teiste rakenduste töö."</string>
+    <string name="permlab_forceStopPackages" msgid="2329627428832067700">"Teiste rakenduste jõuga peatamine"</string>
+    <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"Lubab rakendusel sunniviisiliselt teisi rakendusi peatada."</string>
+    <string name="permlab_forceBack" msgid="652935204072584616">"Rakenduse sulguma sundimine"</string>
+    <string name="permdesc_forceBack" msgid="3892295830419513623">"Võimaldab rakendusel sundida iga esiplaanil oleva rakenduse sulgema ja tagasi minema. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
+    <string name="permlab_dump" msgid="1681799862438954752">"võta vastu süsteemi siseolek"</string>
+    <string name="permdesc_dump" msgid="1778299088692290329">"Võimaldab rakendusel teada saada süsteemi sisemist olekut. Pahatahtlikud rakendused võivad hankida mitmesugust privaatset ja turvateavet, mida neil tavaliselt kunagi vaja ei lähe."</string>
+    <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"ekraanisisu taastamine"</string>
+    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Võimaldab rakendusel kätte saada aktiivse akna sisu. Pahatahtlikud rakendused võivad hankida kogu akna sisu ja uurida kogu selle teksti, välja arvatud paroole."</string>
+    <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"ajutine hõlbustuse lubamine"</string>
+    <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"Lubab rakendusel ajutiselt lubada seadmes hõlbustuse. Pahatahtlikud rakendused võivad lubada hõlbustuse kasutaja nõusolekuta."</string>
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"hangi akna teave"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Võimaldab rakendusel hankida teavet aknahalduri akende kohta. Pahatahtlikud rakendused võivad hankida teavet, mis on mõeldud süsteemisiseseks kasutamiseks."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"filtreeri sündmused"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Võimaldab rakendusel registreerida sisestusfiltri, mis filtreerib kõigi kasutaja sündmuste voo, enne kui need ära saadetakse. Pahatahtlik rakendus võib süsteemi kasutajaliidest juhtida ilma kasutaja sekkumiseta."</string>
+    <string name="permlab_magnify_display" msgid="5973626738170618775">"kuva suurendamine"</string>
+    <string name="permdesc_magnify_display" msgid="7121235684515003792">"Lubab rakendusel ekraani sisu suurendada. Pahatahtlikud rakendused võivad muundada kuva sisu nii, et seade muutub ebastabiilseks."</string>
+    <string name="permlab_shutdown" msgid="7185747824038909016">"osaline väljalülitamine"</string>
+    <string name="permdesc_shutdown" msgid="7046500838746291775">"Lülitab tegevushalduri väljalülitusolekusse. Ei lülita lõplikult välja."</string>
+    <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"väldi rakenduste ümberlülitamist"</string>
+    <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Takistab kasutaja lülitumist teisele rakendusele."</string>
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"aktiivse rakenduse teabe hankimine"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Lubab õiguste saajal hankida privaatset teavet ekraanil esiplaanil oleva aktiivse rakenduse kohta."</string>
+    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"Kõigi rakenduste käivitumise jälgimine ja juhtimine"</string>
+    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Võimaldab rakendusel jälgida ja juhtida, kuidas süsteem tegevusi käivitab. Pahatahtlikud rakendused võivad süsteemi täielikult rikkuda. Seda õigust on vaja ainult arenduseks, mitte tavakasutuse korral."</string>
+    <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"saada paketist eemaldatud saade"</string>
+    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"Võimaldab rakendusel edastada teatise rakenduse paketi eemaldamise kohta. Pahatahtlikud rakendused võivad seda kasutada teiste käitatud rakenduste peatamiseks."</string>
+    <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"saada SMS-i teel vastuvõetud saade"</string>
+    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"Võimaldab rakendusel edastada teatise SMS-sõnumi vastuvõtmise kohta. Pahatahtlikud rakendused võivad seda kasutada sissetulevate SMS-sõnumite võltsimiseks."</string>
+    <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"saada WAP-PUSH-vastuvõetud saateid"</string>
+    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"Võimaldab rakendusel edastada teatise WAP PUSH-sõnumi vastuvõtmise kohta. Pahatahtlikud rakendused võivad seda kasutada MMS-sõnumite vastuvõtmise võltsimiseks või mis tahes veebilehe sisu salaja asendamiseks pahatahtlikuga."</string>
+    <string name="permlab_setProcessLimit" msgid="2451873664363662666">"piira töötavate protsesside arvu"</string>
+    <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"Võimaldab rakendusel juhtida töötavate protsesside maksimaalset arvu. Tavarakenduste puhul pole seda vaja."</string>
+    <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"sundige taustarakendused sulguma"</string>
+    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"Võimaldab rakendusel määrata, kas tegevused lõpetatakse kohe, kui need liiguvad taustale. Tavarakenduste puhul pole seda vaja."</string>
+    <string name="permlab_batteryStats" msgid="2789610673514103364">"aku statistika lugemine"</string>
+    <string name="permdesc_batteryStats" msgid="5897346582882915114">"Lubab rakendusel lugeda madala akutaseme kasutusandmeid. Võib lubada rakendusel hankida üksikasjalikku teavet selle kohta, mis rakendusi te kasutate."</string>
+    <string name="permlab_updateBatteryStats" msgid="3719689764536379557">"aku statistika muutmine"</string>
+    <string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"Võimaldab rakendusel muuta aku kohta kogutud statistikat. Mitte kasutada tavarakenduste puhul."</string>
+    <string name="permlab_getAppOpsStats" msgid="1508779687436585744">"rakenduse tööstatistika hankimine"</string>
+    <string name="permdesc_getAppOpsStats" msgid="6243887041577912877">"Võimaldab rakendusel hankida kogutud rakenduse tööstatistikat. Mitte kasutada tavarakenduste puhul."</string>
+    <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"rakenduse tööstatistika muutmine"</string>
+    <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"Võimaldab rakendusel muuta kogutud rakenduse tööstatistikat. Mitte kasutada tavarakenduste puhul."</string>
+    <string name="permlab_backup" msgid="470013022865453920">"juhi süsteemi varundust ja taastet"</string>
+    <string name="permdesc_backup" msgid="6912230525140589891">"Võimaldab rakendusel juhtida süsteemi varundus- ja taastemehhanismi. Mitte kasutada tavarakenduste puhul."</string>
+    <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"täieliku varukoopia kinnitamine või toimingu taastamine"</string>
+    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"Võimaldab rakendusel käivitada täieliku varukoopia kinnitusliidese. Mitte kasutada üheski rakenduses."</string>
+    <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"kuva volituseta aknad"</string>
+    <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"Võimaldab rakendusel luua aknaid, mis on mõeldud kasutamiseks süsteemisisesele kasutajaliidesele. Mitte kasutada tavarakenduste puhul."</string>
+    <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"tõmmake üle teiste rakenduste"</string>
+    <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"Lubab rakendusel joonistada teistele rakendustele või nende kasutajaliidestele. See võib segada ükskõik millise rakenduse liidese kasutamist või muuta seda, mida arvate nägevat."</string>
+    <string name="permlab_setAnimationScale" msgid="2805103241153907174">"muuda üldist animatsioonikiirust"</string>
+    <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"Võimaldab rakendusel muuta animatsiooni üldist kiirust (animatsioone kiirendada või aeglustada) ükskõik millal."</string>
+    <string name="permlab_manageAppTokens" msgid="1286505717050121370">"Rakenduse lubade haldamine"</string>
+    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"Võimaldab rakendusel luua ja hallata tema enda lube, möödudes tavapärasest Z-järjekorrast. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
+    <string name="permlab_freezeScreen" msgid="4708181184441880175">"ekraanikuva peatamine"</string>
+    <string name="permdesc_freezeScreen" msgid="8558923789222670064">"Lubab rakendusel ajutiselt peatada ekraani kuva täisekraanile üleminekuks."</string>
+    <string name="permlab_injectEvents" msgid="1378746584023586600">"vajuta klahve ja juhtnuppe"</string>
+    <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"Võimaldab rakendusel saata oma sisendtoiminguid (klahvivajutusi jms) teistele rakendustele. Pahatahtlikud rakendused võivad seda kasutada tahvelarvuti ülevõtmiseks."</string>
+    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"Võimaldab rakendusel saata oma sisendtoiminguid (klahvivajutusi jms) teistele rakendustele. Pahatahtlikud rakendused võivad seda kasutada telefoni ülevõtmiseks."</string>
+    <string name="permlab_readInputState" msgid="469428900041249234">"salvesta sisestatav tekst ja tehtavad toimingud"</string>
+    <string name="permdesc_readInputState" msgid="8387754901688728043">"Võimaldab rakendusel vaadata vajutatavaid klahve, isegi kui suhtlete teise rakendusega (näiteks parooli sisestamisel). Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
+    <string name="permlab_bindInputMethod" msgid="3360064620230515776">"seo sisestusmeetodiga"</string>
+    <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Lubab omanikul siduda sisestusmeetodi ülataseme liidesega. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
+    <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"sidumine juurdepääsuteenusega"</string>
+    <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Lubab omanikul luua sideme juurdepääsuteenuse ülataseme liidesega. Tavarakenduste puhul ei tohiks seda kunagi vaja minna."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"sidumine printimisteenusega"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Lubab omanikul siduda printimisteenuse ülataseme liidesega. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"seo printimise spuulerteenusega"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Lubab omanikul siduda printimise spuulerteenuse ülataseme liidesega. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC-teenusega sidumine"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Lubab õiguste omajal luua seosed rakendustega, mis emuleerivad NFC-kaarte. Pole kunagi vajalik tavaliste rakenduste korral."</string>
+    <string name="permlab_bindTextService" msgid="7358378401915287938">"tekstiteenusega sidumine"</string>
+    <string name="permdesc_bindTextService" msgid="8151968910973998670">"Võimaldab omanikul siduda tekstiteenuse (nt SpellCheckerService) ülataseme liidesega. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
+    <string name="permlab_bindVpnService" msgid="4708596021161473255">"seo VPN-teenusega"</string>
+    <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Võimaldab omanikul siduda VPN-teenuse ülataseme liidesega. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
+    <string name="permlab_bindWallpaper" msgid="8716400279937856462">"taustapildiga sidumine"</string>
+    <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Lubab omanikul siduda taustapildi ülataseme liidesega. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
+    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"vidinateenusega sidumine"</string>
+    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Lubab omanikul siduda vidina teenuse ülataseme liidesega. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
+    <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"seadme administraatoriga suhtlemine"</string>
+    <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Võimaldab omanikul saata kavatsusi seadme administraatorile. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"seadme administraatori lisamine või eemaldamine"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Võimaldab omanikul lisada või eemaldada aktiivseid seadme administraatoreid. Tavarakenduste puhul ei tohiks see kunagi vajalik olla."</string>
+    <string name="permlab_setOrientation" msgid="3365947717163866844">"muuda ekraani paigutust"</string>
+    <string name="permdesc_setOrientation" msgid="3046126619316671476">"Võimaldab rakendusel muuta ekraani pööramist mis tahes ajal. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
+    <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"kursorikiiruse muutmine"</string>
+    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Võimaldab rakendusel muuta igal ajal hiire- või puutepadjakursori kiirust. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
+    <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"klaviatuuri paigutuse muutmine"</string>
+    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Lubab rakendusel muuta klaviatuuri paigutust. Tavarakenduste puhul ei peaks kunagi vaja olema."</string>
+    <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"Linuxi signaalide saatmine rakendustele"</string>
+    <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Võimaldab rakendusel taotleda edastatud signaali saatmist kõigile püsiprotsessidele."</string>
+    <string name="permlab_persistentActivity" msgid="8841113627955563938">"Rakenduste pidev töös hoidmine"</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Võimaldab rakendusel muuta oma osi mälus püsivaks. See võib piirata teistele (tahvelarvutit aeglasemaks muutvatele) rakendustele saadaolevat mälu."</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"Võimaldab rakendusel muuta oma osi mälus püsivaks. See võib piirata teistele (telefoni aeglasemaks muutvatele) rakendustele saadaolevat mälu."</string>
+    <string name="permlab_deletePackages" msgid="184385129537705938">"Rakenduste kustutamine"</string>
+    <string name="permdesc_deletePackages" msgid="7411480275167205081">"Võimaldab rakendusel kustutada Android-pakette. Pahatahtlikud rakendused võivad seda kasutada oluliste rakenduste kustutamiseks."</string>
+    <string name="permlab_clearAppUserData" msgid="274109191845842756">"Teiste rakenduste andmete kustutamine"</string>
+    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"Võimaldab rakendusel kustutada kasutaja andmed."</string>
+    <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"Teiste rakenduste vahemälu kustutamine"</string>
+    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"Võimaldab rakendusel kustutada vahemälu failid."</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"Rakenduse mäluruumi mõõtmine"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Võimaldab rakendusel tuua oma koodi, andmed ja vahemälu suurused"</string>
+    <string name="permlab_installPackages" msgid="2199128482820306924">"Rakenduste otse installimine"</string>
+    <string name="permdesc_installPackages" msgid="5628530972548071284">"Võimaldab rakendusel installida uusi või värskendatud Android-pakette. Pahatahtlikud rakendused võivad selle abil lisada uusi meelevaldse tegevuse lubadega rakendusi."</string>
+    <string name="permlab_clearAppCache" msgid="7487279391723526815">"Kõigi rakenduse vahemäluandmete kustutamine"</string>
+    <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"Lubab rakendusel vabastada tahvelarvuti mäluruumi, kustutades faile teiste rakenduste vahemälu kataloogides. Selle tagajärjel võivad teised rakendused käivituda aeglasemalt, sest need peavad oma andmed uuesti tooma."</string>
+    <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"Lubab rakendusel vabastada telefoni mäluruumi, kustutades faile teiste rakenduste vahemälu kataloogides. Selle tagajärjel võivad teised rakendused käivituda aeglasemalt, sest need peavad oma andmed uuesti tooma."</string>
+    <string name="permlab_movePackage" msgid="3289890271645921411">"Rakenduse ressursside teisaldamine"</string>
+    <string name="permdesc_movePackage" msgid="319562217778244524">"Võimaldab rakendusel teisalda rakenduseressursid sisemiselt kandjalt välisele ja vastupidi."</string>
+    <string name="permlab_readLogs" msgid="6615778543198967614">"tundlike logiandmete lugemine"</string>
+    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Võimaldab rakendusel lugeda süsteemi erinevaid logifaile. Nii on võimalik avastada üldist teavet selle kohta, mida te tahvelarvutiga teete, sh isiklikku või privaatset teavet."</string>
+    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Võimaldab rakendusel lugeda süsteemi erinevaid logifaile. Nii on võimalik avastada üldist teavet selle kohta, mida te telefoniga teete, mis võib kaasata ka isiklikku või privaatset teavet."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"Mis tahes meediumidekooderi kasutamine taasesituseks"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Võimaldab rakendusel taasesituseks kasutada mis tahes installitud meediumidekooderit."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"usaldusväärsete mandaatide haldamine"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Lubab rakendusel installida ja desinstallida usaldusväärsete mandaatidena CA-sertifikaate."</string>
+    <string name="permlab_diagnostic" msgid="8076743953908000342">"loe/kirjuta valija allikaid"</string>
+    <string name="permdesc_diagnostic" msgid="6608295692002452283">"Võimaldab rakendusel lugeda valimisrühma mis tahes ressurssi ja sellesse kirjutada (näiteks kaustas /dev olevad failid). See võib mõjutada süsteemi stabiilsust ja turvet. Seda tohiks kasutada tootja või operaator AINULT riistvaraspetsiifiliseks diagnostikaks."</string>
+    <string name="permlab_changeComponentState" msgid="6335576775711095931">"Rakenduse komponentide lubamine või keelamine"</string>
+    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Võimaldab rakendusel määrata, kas teise rakenduse komponent on lubatud või mitte. Pahatahtlikud rakendused võivad kasutada seda oluliste tahvelarvutirakenduste keelamiseks. Nende õiguste puhul peab olema ettevaatlik, kuna need võimaldavad muuta rakenduse komponente kasutuks, ebaühtlaseks või ebastabiilseks."</string>
+    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Võimaldab rakendusel määrata, kas teise rakenduse komponent on lubatud või mitte. Pahatahtlikud rakendused võivad kasutada seda oluliste telefonirakenduste keelamiseks. Nende õiguste puhul peab olema ettevaatlik, kuna need võimaldavad muuta rakenduse komponente kasutuks, ebaühtlaseks või ebastabiilseks."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"lubade andmine või tühistamine"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Võimaldab rakendusel anda või tühistada teatud lubasid endale või teistele rakendustele. Pahatahtlikud rakendused võivad kasutada seda juurdepääsu hankimiseks sellistele funktsioonidele, mille jaoks te pole luba andnud."</string>
+    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"Eelistatud rakenduste määramine"</string>
+    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Võimaldab rakendusel muuta teie eelistatud rakendusi. Pahatahtlikud rakendused võivad salaja muuta töötavaid rakendusi, pettes teie olemasolevad rakendused koguma teilt privaatseid andmeid."</string>
+    <string name="permlab_writeSettings" msgid="2226195290955224730">"muutke süsteemi seadeid"</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"Võimaldab rakendusel muuta süsteemiseadete andmeid. Pahatahtlikud rakendused võivad rikkuda teie süsteemi konfiguratsiooni."</string>
+    <string name="permlab_writeSecureSettings" msgid="204676251876718288">"muuda turvalisi süsteemiseadeid"</string>
+    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"Võimaldab rakendusel muuta süsteemi turvaseadete andmeid. Mitte kasutada tavarakenduste puhul."</string>
+    <string name="permlab_writeGservices" msgid="2149426664226152185">"muuda Google\'i teenustekaarti"</string>
+    <string name="permdesc_writeGservices" msgid="1287309437638380229">"Võimaldab rakendusel muuta Google\'i teenustekaarti. Mitte kasutada tavarakenduste puhul."</string>
+    <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"käitage käivitamisel"</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Võimaldab rakendusel käivituda ise kohe, kui süsteem on käivitunud. See võib tahvelarvuti käivitamist aeglustada ja lubab rakendusel muuta tahvelarvuti ka üldiselt aeglasemaks, kuna töötab pidevalt."</string>
+    <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Võimaldab rakendusel käivituda ise kohe, kui süsteem on käivitunud. See võib telefoni käivitamist aeglustada ja lubab rakendusel muuta telefoni ka üldiselt aeglasemaks, kuna töötab pidevalt."</string>
+    <string name="permlab_broadcastSticky" msgid="7919126372606881614">"kleepsaate saatmine"</string>
+    <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Võimaldab rakendusel saata püsivaid edastusi, mis jäävad pärast saate lõppemist alles. Ülemäärane kasutamine võib muuta tahvelarvuti aeglaseks või ebastabiilseks, põhjustades selle liiga suure mälukasutuse."</string>
+    <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Võimaldab rakendusel saata püsivaid edastusi, mis jäävad pärast saate lõppemist alles. Ülemäärane kasutamine võib muuta telefoni aeglaseks või ebastabiilseks, põhjustades selle liiga suure mälukasutuse."</string>
+    <string name="permlab_readContacts" msgid="8348481131899886131">"lugege oma kontakte"</string>
+    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Võimaldab rakendusel lugeda andmeid teie tahvelarvutisse salvestatud kontaktide kohta, näiteks seda, kui tihti te kellelegi helistate, meilite või nendega muul viisil suhtlete. See luba võimaldab rakendustel salvestada teie kontaktandmeid ja pahatahtlikud rakendused võivad teie teadmata kontaktandmeid jagada."</string>
+    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Võimaldab rakendusel lugeda andmeid teie telefoni salvestatud kontaktide kohta, näiteks seda, kui tihti te kellelegi helistate, meilite või nendega muul viisil suhtlete. See luba võimaldab rakendustel salvestada teie kontaktandmeid ja pahatahtlikud rakendused võivad teie teadmata kontaktandmeid jagada."</string>
+    <string name="permlab_writeContacts" msgid="5107492086416793544">"muutke oma kontakte"</string>
+    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Võimaldab rakendusel muuta tahvelarvutisse salvestatud kontaktide andmeid, sealhulgas seda, kui tihti olete konkreetsetele kontaktidele helistanud, meilinud või nendega muul viisil suhelnud. See luba võimaldab rakendustel kustutada kontaktandmeid."</string>
+    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Võimaldab rakendusel muuta telefoni salvestatud kontaktide andmeid, sealhulgas seda, kui tihti olete konkreetsetele kontaktidele helistanud, meilinud või nendega muul viisil suhelnud. See luba võimaldab rakendustel kustutada kontaktandmeid."</string>
+    <string name="permlab_readCallLog" msgid="3478133184624102739">"kõnelogi lugemine"</string>
+    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Võimaldab rakendusel lugeda teie tahvelarvuti kõnelogi, sh andmeid sissetulevate ja väljuvate kõnede kohta. See luba võimaldab rakendustel salvestada teie kõnelogi andmeid ja pahatahtlikud rakendused võivad teie teadmata kõnelogi andmeid jagada."</string>
+    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Võimaldab rakendusel lugeda teie telefoni kõnelogi, sh andmeid sissetulevate ja väljuvate kõnede kohta. See luba võimaldab rakendustel salvestada teie kõnelogi andmeid ja pahatahtlikud rakendused võivad teie teadmata kõnelogi andmeid jagada."</string>
+    <string name="permlab_writeCallLog" msgid="8552045664743499354">"kõnelogi kirjutamine"</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Lubab rakendusel muuta tahvelarvuti kõnelogi, sh sissetulevate ja väljaminevate kõnede andmeid. Pahatahtlikud rakendused võivad kasutada seda kõnelogi kustutamiseks või muutmiseks."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Lubab rakendusel muuta telefoni kõnelogi, sh sissetulevate ja väljaminevate kõnede andmeid. Pahatahtlikud rakendused võivad kasutada seda kõnelogi kustutamiseks või muutmiseks."</string>
+    <string name="permlab_readProfile" msgid="4701889852612716678">"lugege oma kontaktikaarti"</string>
+    <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Võimaldab rakendusel lugeda seadmesse salvestatud isiklikku profiiliteavet, näiteks teie nime ja kontaktteavet. See tähendab, et rakendus saab teid tuvastada ja saata teie profiiliteavet teistele."</string>
+    <string name="permlab_writeProfile" msgid="907793628777397643">"muutke oma kontaktikaarti"</string>
+    <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Võimaldab rakendusel muuta või lisada seadmesse salvestatud isiklikku profiiliteavet, näiteks teie nime ja kontaktteavet. See tähendab, et rakendus saab teid tuvastada ja saata teie profiiliteavet teistele."</string>
+    <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"Sotsiaalvoo lugemine"</string>
+    <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Annab rakendusele juurdepääsu ja võimaldab sünkroonida teie ja teie sõprade sotsiaalseid värskendusi. Olge teabe jagamisel ettevaatlik – see võimaldab rakendusel lugeda teie suhtlusi sõpradega suhtlusvõrgustikes konfidentsiaalsusest hoolimata. Märkus: see luba ei pruugi jõustuda kõigis suhtlusvõrgustikes."</string>
+    <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"Sotsiaalvoogu kirjutamine"</string>
+    <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Võimaldab rakendusel kuvada sõprade sotsiaalseid värskendusi. Olge teabe jagamisel ettevaatlik – see võimaldab rakendusel luua sõnumeid, mis võivad näida tulevat sõpradelt. Märkus: see luba ei pruugi jõustuda kõikides suhtlusvõrgustikes."</string>
+    <string name="permlab_readCalendar" msgid="5972727560257612398">"kalendrisündmuste lugemine ja konfidentsiaalne teave"</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Võimaldab rakendusel lugeda kõiki tahvelarvutisse salvestatud kalendrisündmusi, sh sõprade või töökaaslaste omi. See võib lubada rakendusel jagada või salvestada teie kalendriandmeid, hoolimata konfidentsiaalsusest või tundlikkusest."</string>
+    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Võimaldab rakendusel lugeda kõiki telefoni salvestatud kalendrisündmusi, sh sõprade või töökaaslaste omi. See võib lubada rakendusel jagada või salvestada teie kalendriandmeid, hoolimata konfidentsiaalsusest või tundlikkusest."</string>
+    <string name="permlab_writeCalendar" msgid="8438874755193825647">"kalendrisündmuste lisamine või muutmine ja külalistele omanike teadmata meili saatmine"</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Võimaldab rakendusel lisada, eemaldada ja muuta sündmusi, mida saate muuta oma tahvelarvutis, sh sõprade ja töökaaslaste omi. See võib võimaldada rakendusel saata sõnumeid, mis näivad tulevat kalendri omanikelt, või muuta sündmusi omaniku teadmata."</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Võimaldab rakendusel lisada, eemaldada ja muuta sündmusi, mida saate muuta oma telefonis, sh sõprade ja töökaaslaste omi. See võib võimaldada rakendusel saata sõnumeid, mis näivad tulevat kalendri omanikelt, või muuta sündmusi omaniku teadmata."</string>
+    <string name="permlab_accessMockLocation" msgid="8688334974036823330">"võltsasukohad testimiseks"</string>
+    <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Looge võltsasukoha allikaid, et katsetada või installida uut asukohapakkujat. See lubab rakendusel tühistada teiste asukohaallikate, näiteks GPS-i või asukohapakkujate tagastatud asukoha ja/või oleku."</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"juurdepääs asukohapakkuja lisakäskudele"</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"Võimaldab rakendusel pääseda juurde asukohapakkuja erikäskudele. See võib lubada rakendusel segada GPS-i või muude asukohaallikate tööd."</string>
+    <string name="permlab_installLocationProvider" msgid="6578101199825193873">"luba asukohapakkuja installimiseks"</string>
+    <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"Looge võltsasukoha allikaid, et katsetada või installida uut asukohapakkujat. See lubab rakendusel tühistada teiste asukohaallikate, näiteks GPS-i või asukohapakkujate tagastatud asukoha ja/või oleku."</string>
+    <string name="permlab_accessFineLocation" msgid="1191898061965273372">"täpne asukoht (GPS- ja võrgupõhine)"</string>
+    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Lubab rakendusel hankida teie täpse asukoha globaalse positsioneerimissüsteemi (GPS) või võrgu asukohaallikate (nt mobiilimastide ja WiFi) järgi. Need asukohateenused peavad olema sisse lülitatud ja teie seadme jaoks saadaval, et rakendus saaks neid kasutada. Rakendused võivad kasutada seda teie asukoha tuvastamiseks ja tarbida akut."</string>
+    <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"ligikaudne asukoht (võrgupõhine)"</string>
+    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Lubab rakendusel hankida juurdepääsu ligikaudsele asukohale. Asukoht tuletatakse asukohateenuste järgi, kasutades võrgu asukohaallikaid, nt mobiilimastid ja WiFi. Need asukohateenused peavad olema sisse lülitatud ja teie seadme jaoks saadaval, et rakendus saaks neid kasutada. Rakendused võivad kasutada seda teie ligikaudse asukoha tuvastamiseks."</string>
+    <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"juurdepääs SurfaceFlingerile"</string>
+    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Võimaldab rakendusel kasutada SurfaceFlingeri madalatasemelisi funktsioone."</string>
+    <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"loe kaadripuhvrit"</string>
+    <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Võimaldab rakendusel kaadripuhvri sisu lugeda."</string>
+    <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"WiFi-ekraanide seadistamine"</string>
+    <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Lubab rakendusel seadistada WiFi-ekraane ja nendega ühendus luua."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"WiFi-ekraanide juhtimine"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Lubab rakendusel juhtida WiFi-ekraanide madala taseme funktsioone."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"heliväljundi jäädvustamine"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Lubab rakendusel jäädvustada ja ümber suunata heliväljundit."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"videoväljundi jäädvustamine"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Lubab rakendusel jäädvustada ja ümber suunata videoväljundit."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"kaitstud videoväljundi jäädvustamine"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Lubab rakendusel jäädvustada ja ümber suunata kaitstud videoväljundit."</string>
+    <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"muuda heliseadeid"</string>
+    <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Võimaldab rakendusel muuta üldiseid heliseadeid, näiteks helitugevust ja seda, millist kõlarit kasutatakse väljundiks."</string>
+    <string name="permlab_recordAudio" msgid="3876049771427466323">"salvesta heli"</string>
+    <string name="permdesc_recordAudio" msgid="4906839301087980680">"Võimaldab rakendusel salvestada mikrofoniga heli. See luba võimaldab rakendusel salvestada heli igal ajal ilma teie kinnituseta."</string>
+    <string name="permlab_camera" msgid="3616391919559751192">"piltide ja videote tegemine"</string>
+    <string name="permdesc_camera" msgid="8497216524735535009">"Võimaldab rakendusel teha kaameraga pilte ja videoid. See luba võimaldab rakendusel kasutada kaamerat mis tahes ajal teie kinnituseta."</string>
+    <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"keela kaamera kasutamisel näidikutule kasutamine"</string>
+    <string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"Lubab eelinstallitud süsteemirakendusel keelata kaamera näidikutule kasutamise."</string>
+    <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"blokeeri tahvelarvuti jäädavalt"</string>
+    <string name="permlab_brick" product="default" msgid="8337817093326370537">"blokeeri telefon jäädavalt"</string>
+    <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"Võimaldab rakendusel kogu tahvelarvuti jäädavalt keelata. See on väga ohtlik."</string>
+    <string name="permdesc_brick" product="default" msgid="5788903297627283099">"Võimaldab rakendusel kogu telefoni jäädavalt keelata. See on väga ohtlik."</string>
+    <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"sunni tahvelarvuti taaskäivituma"</string>
+    <string name="permlab_reboot" product="default" msgid="2898560872462638242">"sunni telefoni taaskäivitus"</string>
+    <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"Võimaldab rakendusel sundida tahvelarvutit taaskäivituma."</string>
+    <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"Võimaldab rakendusel sundida telefoni taaskäivituma."</string>
+    <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"juurdep. USB-ruumi failisüst."</string>
+    <string name="permlab_mount_unmount_filesystems" product="default" msgid="4402305049890953810">"juurdepääs SD-kaardi failisüsteemile"</string>
+    <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"Võimaldab rakendusel failisüsteeme irdmällu paigaldada ja sealt lahutada."</string>
+    <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"tühjendage USB-salvestusruum"</string>
+    <string name="permlab_mount_format_filesystems" product="default" msgid="262582698639274056">"tühjendage SD-kaart"</string>
+    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"Võimaldab rakendusel vormindada irdmälu."</string>
+    <string name="permlab_asec_access" msgid="3411338632002193846">"hangi teavet sisemälu kohta"</string>
+    <string name="permdesc_asec_access" msgid="3094563844593878548">"Võimaldab rakendusel hankida sisemälu teavet."</string>
+    <string name="permlab_asec_create" msgid="6414757234789336327">"sisemälu loomine"</string>
+    <string name="permdesc_asec_create" msgid="4558869273585856876">"Lubab rakendusel luua sisemälu."</string>
+    <string name="permlab_asec_destroy" msgid="526928328301618022">"hävita sisemälu"</string>
+    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"Lubab rakendusel sisemälu hävitada."</string>
+    <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"Sisemälu paigaldamine/eemaldamine"</string>
+    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"Võimaldab rakendusel sisemäluseadme paigaldada/eraldada."</string>
+    <string name="permlab_asec_rename" msgid="7496633954080472417">"sisemälu ümbernimetamine"</string>
+    <string name="permdesc_asec_rename" msgid="1794757588472127675">"Võimaldab rakendusel sisemälu ümber nimetada."</string>
+    <string name="permlab_vibrate" msgid="7696427026057705834">"juhtige vibreerimist"</string>
+    <string name="permdesc_vibrate" msgid="6284989245902300945">"Võimaldab rakendusel juhtida vibreerimist."</string>
+    <string name="permlab_flashlight" msgid="2155920810121984215">"juhi taskulampi"</string>
+    <string name="permdesc_flashlight" msgid="6522284794568368310">"Võimaldab rakendusel juhtida taskulampi."</string>
+    <string name="permlab_manageUsb" msgid="1113453430645402723">"USB-seadmete eelistuste ja lubade haldamine"</string>
+    <string name="permdesc_manageUsb" msgid="7776155430218239833">"Võimaldab rakendusel hallata USB-seadmete eelistusi ja lube."</string>
+    <string name="permlab_accessMtp" msgid="4953468676795917042">"MTP-protokolli rakendamine"</string>
+    <string name="permdesc_accessMtp" msgid="6532961200486791570">"Lubab juurdepääsu tuuma MTP-draiverile MTP USB-protokolli rakendamiseks."</string>
+    <string name="permlab_hardware_test" msgid="4148290860400659146">"testi riistvara"</string>
+    <string name="permdesc_hardware_test" msgid="6597964191208016605">"Võimaldab rakendusel juhtida erinevaid välisseadmeid riistvara testimise eesmärgil."</string>
+    <string name="permlab_callPhone" msgid="3925836347681847954">"helista otse telefoninumbritele"</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"Võimaldab rakendusel teie sekkumiseta telefoninumbritele helistada. See võib põhjustada ootamatuid tasusid või telefonikõnesid. Pange tähele, et see ei luba rakendusel helistada hädaabinumbritele. Pahatahtlikud rakendused võivad teile kulusid tekitada, tehes telefonikõnesid teie kinnituseta."</string>
+    <string name="permlab_callPrivileged" msgid="4198349211108497879">"helista otse mis tahes telefoninumbritele"</string>
+    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"Võimaldab rakendusel helistada mis tahes telefoninumbrile, sh hädaabinumbritele ilma teie sekkumiseta. Pahatahtlikud rakendused võivad teha hädaabiteenustele mittevajalikke ja ebaseaduslikke kõnesid."</string>
+    <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"käivita otse CDMA-tahvelarvuti seadistamine"</string>
+    <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"CDMA-telefoniseadistuse otse käivitamine"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"Võimaldab rakendusel käivitada CDMA ettevalmistamise. Pahatahtlikud rakendused võivad CDMA ettevalmistamise asjatult käivitada."</string>
+    <string name="permlab_locationUpdates" msgid="7785408253364335740">"kontrolli asukoha värskendamise teatisi"</string>
+    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Võimaldab rakendusel lubada/keelata asukoha värskendamise teatised raadiost. Mitte kasutada tavarakenduste puhul."</string>
+    <string name="permlab_checkinProperties" msgid="7855259461268734914">"juurdepääs registreerimisatribuutidele"</string>
+    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Annab rakendusele lugemis-/kirjutusõiguse registreerimisteenusega üles laaditud atribuutidele. Mitte kasutada tavarakenduste puhul."</string>
+    <string name="permlab_bindGadget" msgid="776905339015863471">"vali vidinaid"</string>
+    <string name="permdesc_bindGadget" msgid="8261326938599049290">"Võimaldab rakendusel öelda süsteemile, milline rakendus saab kasutada milliseid vidinaid. Selle õigusega rakendus võib anda teistele rakendustele juurdepääsu isiklikele andmetele. Mitte kasutada tavarakenduste puhul."</string>
+    <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"muuda telefoni olekut"</string>
+    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Võimaldab rakendusel juhtida seadme telefonifunktsioone. Selle loaga rakendus saab vahetada võrke, lülitada telefoniraadiot sisse ja välja ning teha muudki ilma teid teavitamata."</string>
+    <string name="permlab_readPhoneState" msgid="9178228524507610486">"lugege telefoni olekut ja identiteeti"</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Annab rakendusele juurdepääsu seadme telefonifunktsioonidele. See luba võimaldab rakendusel määrata telefoninumbri ja seadme ID-d ning kontrollida, kas kõne on aktiivne ja kaugnumber on kõne kaudu telefoniga ühendatud."</string>
+    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"tahvelarvuti uinumise vältimine"</string>
+    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"väldi telefoni uinumist"</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Võimaldab rakendusel vältida tahvelarvuti uinumist."</string>
+    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Võimaldab rakendusel vältida telefoni uinumist."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
+    <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"lülita tahvelarvuti sisse või välja"</string>
+    <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"lülita telefon sisse või välja"</string>
+    <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Võimaldab rakendusel tahvelarvutit sisse või välja lülitada."</string>
+    <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"Võimaldab rakendusel telefoni sisse või välja lülitada."</string>
+    <string name="permlab_factoryTest" msgid="3715225492696416187">"käivita tehase testrežiimis"</string>
+    <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"Käitage madalatasemelise tootjatestina, mis annab täieliku juurdepääsu tahvelarvuti riistvarale. Saadaval ainult siis, kui tahvelarvuti töötab tootjatesti režiimis."</string>
+    <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"Käivitage madalatasemelise tootjatestina, mis võimaldab täielikku juurdepääsu telefoni riistvarale. Kasutatav ainult juhul, kui telefon töötab tootja testrežiimis."</string>
+    <string name="permlab_setWallpaper" msgid="6627192333373465143">"määra taustapilt"</string>
+    <string name="permdesc_setWallpaper" msgid="7373447920977624745">"Võimaldab rakendusel määrata süsteemi taustapildi."</string>
+    <string name="permlab_setWallpaperHints" msgid="3278608165977736538">"korrigeerige oma taustapildi suurust"</string>
+    <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Võimaldab rakendusel määrata süsteemi taustapildi suuruse vihjeid."</string>
+    <string name="permlab_masterClear" msgid="2315750423139697397">"lähtesta süsteem tehase vaikeseadetele"</string>
+    <string name="permdesc_masterClear" msgid="3665380492633910226">"Võimaldab rakendusel süsteemi tehaseseaded täielikult lähtestada, kustutades kõik andmed, konfiguratsiooni ja installitud rakendused."</string>
+    <string name="permlab_setTime" msgid="2021614829591775646">"kellaaja määramine"</string>
+    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"Võimaldab rakendusel muuta tahvelarvuti kellaaega."</string>
+    <string name="permdesc_setTime" product="default" msgid="1855702730738020">"Võimaldab rakendusel muuta telefoni kellaaega."</string>
+    <string name="permlab_setTimeZone" msgid="2945079801013077340">"määra ajavöönd"</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Võimaldab rakendusel muuta tahvelarvuti ajavööndit."</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Võimaldab rakendusel muuta telefoni ajavööndit."</string>
+    <string name="permlab_accountManagerService" msgid="4829262349691386986">"AccountManagerService\'ina tegutsemine"</string>
+    <string name="permdesc_accountManagerService" msgid="1948455552333615954">"Võimaldab rakendusel helistada konto autentijatele."</string>
+    <string name="permlab_getAccounts" msgid="1086795467760122114">"leidke seadmest kontod"</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Võimaldab rakendusel hankida tahvelarvutile teadaolevaid kontoloendeid. See võib hõlmata mis tahes kontosid, mille on loonud teie installitud rakendused."</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Võimaldab rakendusel hankida telefonile teadaolevaid kontoloendeid. See võib hõlmata mis tahes kontosid, mille on loonud teie installitud rakendused."</string>
+    <string name="permlab_authenticateAccounts" msgid="5265908481172736933">"looge kontod ja määrake paroolid"</string>
+    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"Võimaldab rakendusel kasutada kontohalduri konto autentija võimalusi, sh luua kontosid ning hankida ja määrata paroole."</string>
+    <string name="permlab_manageAccounts" msgid="4983126304757177305">"lisage või eemaldage kontosid"</string>
+    <string name="permdesc_manageAccounts" msgid="8698295625488292506">"Võimaldab rakendusel teha toiminguid, nagu kontode lisamine ja eemaldamine ning nende paroolide kustutamine."</string>
+    <string name="permlab_useCredentials" msgid="235481396163877642">"kasutage seadmes olevaid kontosid"</string>
+    <string name="permdesc_useCredentials" msgid="7984227147403346422">"Võimaldab rakendusel taotleda autentimise lubasid."</string>
+    <string name="permlab_accessNetworkState" msgid="4951027964348974773">"vaadake võrguühendusi"</string>
+    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Lubab rakendusel vaadata teavet võrguühenduste kohta, näiteks seda, millised võrgud on olemas ja ühendatud."</string>
+    <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"täielik juurdepääs võrgule"</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Võimaldab rakendusel luua võrgupesasid ja kasutada kohandatud võrguprotokolle. Brauser ja teised rakendused annavad vahendid andmete saatmiseks Internetti, nii et seda luba ei ole vaja andmete saatmiseks Internetti."</string>
+    <string name="permlab_writeApnSettings" msgid="505660159675751896">"võrguseadete ja -liikluse muutmine/hõivamine"</string>
+    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Võimaldab rakendusel muuta võrguseadeid ning peatada ja kontrollida kogu võrguliiklust, näiteks muuta mis tahes APN-i puhverserverit ja porti. Pahatahtlikud rakendused võivad võrgupakette jälgida, ümber suunata või muuta teie teadmata."</string>
+    <string name="permlab_changeNetworkState" msgid="958884291454327309">"muuda võrguühenduvust"</string>
+    <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Võimaldab rakendusel muuta võrguühenduvuse olekut."</string>
+    <string name="permlab_changeTetherState" msgid="5952584964373017960">"Jagatud ühenduvuse muutmine"</string>
+    <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Võimaldab rakendusel muuta jagatud võrgu ühenduvuse olekut."</string>
+    <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"muuda taustaandmete kasutusseadeid"</string>
+    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Võimaldab rakendusel muuta taustaandmete kasutuse seadeid."</string>
+    <string name="permlab_accessWifiState" msgid="5202012949247040011">"vaadake WiFi-ühendusi"</string>
+    <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Võimaldab rakendusel vaadata teavet WiFi-võrgu kohta, näiteks ühendatud WiFi-seadmete nimesid ja seda, kas WiFi on lubatud."</string>
+    <string name="permlab_changeWifiState" msgid="6550641188749128035">"ühendage ja katkestage ühendus WiFi-ga"</string>
+    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Võimaldab rakendusel luua ja katkestada ühenduse WiFi-pääsupunktidega ning teha muudatusi seadme konfiguratsioonis WiFi-võrkudesse."</string>
+    <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"luba WiFi multiedastusvastuvõtt"</string>
+    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Võimaldab rakendusel vastu võtta pakette, mis on saadetud kõikidele WiFi-võrguga ühendatud seadmetele, mis kasutavad multiedastuse aadresse, mitte ainult teie tahvelarvutit. See võtab rohkem energiat kui mittemultiedastuse režiim."</string>
+    <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Võimaldab rakendusel vastu võtta pakette, mis on saadetud kõikidele WiFi-võrguga ühendatud seadmetele, mis kasutavad multiedastuse aadresse, mitte ainult teie telefoni. See võtab rohkem energiat kui mittemultiedastuse režiim."</string>
+    <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"juurdepääs Bluetoothi ​​seadetele"</string>
+    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Võimaldab rakendusel seadistada kohalikku Bluetooth-tahvelarvutit ning leida ja siduda seda kaugseadmetega."</string>
+    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Võimaldab rakendusel seadistada kohalikku Bluetooth-telefoni ning leida ja siduda seda kaugseadmetega."</string>
+    <string name="permlab_accessWimaxState" msgid="4195907010610205703">"WiMAX-iga ühenduse loomine ja ühenduse katkestamine"</string>
+    <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"Võimaldab rakendusel määrata, kas WiMAX on lubatud, ja vaadata teavet kõikide ühendatud WiMAX-võrkude kohta."</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"WiMAX-i oleku muutmine"</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Võimaldab rakendusel luua ja katkestada tahvelarvuti ühenduse WiMAX-i võrkudega."</string>
+    <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"Võimaldab rakendusel luua ja katkestada telefoni ühenduse WiMAX-i võrkudega."</string>
+    <string name="permlab_bluetooth" msgid="6127769336339276828">"siduge Bluetoothi seadmetega"</string>
+    <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Võimaldab rakendusel vaadata tahvelarvuti Bluetooth-konfiguratsiooni ning luua ja heaks kiita ühendusi seotud seadmetega."</string>
+    <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Võimaldab rakendusel vaadata telefoni Bluetooth-konfiguratsiooni ning luua ja heaks kiita ühendusi seotud seadmetega."</string>
+    <string name="permlab_nfc" msgid="4423351274757876953">"lähiväljaside juhtimine"</string>
+    <string name="permdesc_nfc" msgid="7120611819401789907">"Võimaldab rakendusel suhelda lähiväljaside (NFC) märgendite, kaartide ja lugeritega."</string>
+    <string name="permlab_disableKeyguard" msgid="3598496301486439258">"keelake ekraanilukk"</string>
+    <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Võimaldab rakendusel keelata klahviluku ja muu seotud parooli turvalisuse. Näiteks keelab telefon klahviluku sissetuleva kõne vastuvõtmisel ja lubab klahviluku uuesti, kui kõne on lõpetatud."</string>
+    <string name="permlab_readSyncSettings" msgid="6201810008230503052">"loe sünkroonimisseadeid"</string>
+    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Võimaldab rakendusel lugeda konto sünkroonimisseadeid. Näiteks võib see määrata, kas rakendus Inimesed on kontoga sünkroonitud."</string>
+    <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"lülitage sünkroonimine sisse ja välja"</string>
+    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Võimaldab rakendusel muuta konto sünkroonimisseadeid. Näiteks saab seda kasutada, et lubada rakenduse Inimesed sünkroonimine kontoga."</string>
+    <string name="permlab_readSyncStats" msgid="7396577451360202448">"loe sünkroonimisstatistikat"</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Võimaldab rakendusel lugeda konto sünkroonimisstatistikat, sh sünkroonimissündmuste ajalugu ja sünkroonitud andmete hulka."</string>
+    <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"loe tellitud kanaleid"</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Võimaldab rakendusel saada üksikasju praegu sünkroonitavate voogude kohta."</string>
+    <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"kirjuta tellitud kanaleid"</string>
+    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"Võimaldab rakendusel muuta teie praegu sünkroonitud vooge. Pahatahtlikud rakendused võivad muuta teie sünkroonitud vooge."</string>
+    <string name="permlab_readDictionary" msgid="4107101525746035718">"lugege termineid, mis te sõnastikku lisasite"</string>
+    <string name="permdesc_readDictionary" msgid="659614600338904243">"Võimaldab rakendusel lugeda kõiki sõnu, nimesid ja fraase, mille kasutaja on kasutaja sõnaraamatusse salvestanud."</string>
+    <string name="permlab_writeDictionary" msgid="2183110402314441106">"sõnade lisamine kasutaja määratletud sõnastikku"</string>
+    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Võimaldab rakendusel kirjutada kasutajasõnastikku uusi sõnu."</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"kaitstud salvestusruumi juurdepääsu katsetamine"</string>
+    <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"kaitstud salvestusruumi juurdepääsu katsetamine"</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"Võimaldab rakendusel testida luba USB-salvestuseks, mis on saadaval tulevastes seadmetes."</string>
+    <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"Võimaldab rakendusel katsetada SD-kaardi luba, mis on saadaval tulevastel seadmetel."</string>
+    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"muutke, kustut. USB-ruumi sisu"</string>
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"SD-kaardi sisu muutmine või kustutamine"</string>
+    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Võimaldab rakendusel kirjutada USB-mäluseadmele."</string>
+    <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Võimaldab rakendusel kirjutada SD-kaardile."</string>
+    <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"sisemälu sisu muutm./kustut."</string>
+    <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Võimaldab rakendusel muuta sisemise andmekandja sisu."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"dokumendi talletuse haldamine"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Lubab rakendusel hallata dokumendi talletamist."</string>
+    <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"juurdepääs välismäluseadmele (kõikidele kasutajatele)"</string>
+    <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Võimaldab rakenduse kõikidel kasutajatel pöörduda välismäluseadme poole."</string>
+    <string name="permlab_cache_filesystem" msgid="5656487264819669824">"juurdepääs vahemälu failisüsteemile"</string>
+    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Võimaldab rakendusel vahemälu failisüsteemi lugeda ja kirjutada."</string>
+    <string name="permlab_use_sip" msgid="5986952362795870502">"Interneti-kõnede tegemine/vastuvõtmine"</string>
+    <string name="permdesc_use_sip" msgid="4717632000062674294">"Võimaldab rakendusel kasutada SIP-teenust Interneti-kõnede valimiseks/vastuvõtmiseks."</string>
+    <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"võrgukasutuse ajaloo lugemine"</string>
+    <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"Võimaldab rakendusel lugeda võrgukasutuse ajalugu teatud võrkude ja rakenduste puhul."</string>
+    <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"võrgueeskirjade haldamine"</string>
+    <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Võimaldab rakendusel hallata võrgueeskirju ja määratleda rakendusespetsiifilisi reegleid."</string>
+    <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"võrgukasutuse arvestamise muutmine"</string>
+    <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Võimaldab rakendusel muuta võrgukasutuse loendamist rakenduste suhtes. Mitte kasutada tavarakenduste puhul."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"sokli märkide muutmine"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Lubab rakendusel muuta marsruutimiseks sokli märke"</string>
+    <string name="permlab_accessNotifications" msgid="7673416487873432268">"juurdepääsu märguanded"</string>
+    <string name="permdesc_accessNotifications" msgid="458457742683431387">"Võimaldab rakendusel tuua, kontrollida ja kustutada märguandeid, sh neid, mille on postitanud teised rakendused."</string>
+    <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"seo märguannete kuulamisteenusega"</string>
+    <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Võimaldab omanikul siduda märguannete kuulamisteenuse ülemise taseme kasutajaliidese. Seda ei tohiks tavarakenduste puhul kunagi vaja olla."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"operaatoripoolse konfiguratsioonirakenduse aktiveerimine"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Lubab omanikul aktiveerida operaatoripoolse konfiguratsioonirakenduse. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"võrgutingimuste teabe kuulamine"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Lubab rakendusel kuulata võrgutingimuste teavet. Ei ole kunagi vajalik tavaliste rakenduste puhul."</string>
+    <string name="policylab_limitPassword" msgid="4497420728857585791">"Parooli reeglite määramine"</string>
+    <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrollige ekraaniluku avamise paroolide pikkust ja tähemärke."</string>
+    <string name="policylab_watchLogin" msgid="914130646942199503">"Ekraani avamiskatsed"</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Jälgib ekraani avamisel valesti sisestatud paroolide arvu ja lukustab tahvelarvuti või kustutab kõik selle andmed, kui vale parool sisestatakse liiga palju kordi."</string>
+    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Jälgib ekraani avamisel valesti sisestatud paroolide arvu ja lukustab telefoni või kustutab kõik selle andmed, kui vale parool sisestatakse liiga palju kordi."</string>
+    <string name="policylab_resetPassword" msgid="2620077191242688955">"Ekraaniluku parooli muutmine"</string>
+    <string name="policydesc_resetPassword" msgid="605963962301904458">"Ekraaniluku parooli muutmine."</string>
+    <string name="policylab_forceLock" msgid="2274085384704248431">"Ekraani lukustamine"</string>
+    <string name="policydesc_forceLock" msgid="1141797588403827138">"Määrake, kuidas ja millal ekraan lukustub."</string>
+    <string name="policylab_wipeData" msgid="3910545446758639713">"Kõikide andmete kustutamine"</string>
+    <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Kustutage tahvelarvuti andmed hoiatamata, lähtestades arvuti tehaseandmetele."</string>
+    <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Kustuta telefoniandmed hoiatuseta, lähtestades telefoni tehaseandmetele."</string>
+    <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Määra seadme globaalne puhverserver"</string>
+    <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Eeskirjade lubamise ajal kasutatava seadme globaalse puhverserveri määramine. Ainult esimese seadme administraator määrab tõhusa globaalse puhverserveri."</string>
+    <string name="policylab_expirePassword" msgid="885279151847254056">"Ekraaniluku parooli aegumise määramine"</string>
+    <string name="policydesc_expirePassword" msgid="1729725226314691591">"Määrake ekraaniluku parooli muutmissagedus."</string>
+    <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Salvestamise krüpt. määramine"</string>
+    <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"Nõua salvestatud rakenduse andmete krüpteerimist."</string>
+    <string name="policylab_disableCamera" msgid="6395301023152297826">"Keela kaamerad"</string>
+    <string name="policydesc_disableCamera" msgid="2306349042834754597">"Vältige seadme kõigi kaamerate kasutamist."</string>
+    <string name="policylab_disableKeyguardFeatures" msgid="266329104542638802">"Klahviluku funkts. keelamine"</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="3467082272186534614">"Takistage klahviluku mõne funktsiooni kasutamist."</string>
+  <string-array name="phoneTypes">
+    <item msgid="8901098336658710359">"Kodu"</item>
+    <item msgid="869923650527136615">"Mobiil"</item>
+    <item msgid="7897544654242874543">"Töö"</item>
+    <item msgid="1103601433382158155">"Tööfaks"</item>
+    <item msgid="1735177144948329370">"Kodufaks"</item>
+    <item msgid="603878674477207394">"Piipar"</item>
+    <item msgid="1650824275177931637">"Muu"</item>
+    <item msgid="9192514806975898961">"Kohandatud"</item>
+  </string-array>
+  <string-array name="emailAddressTypes">
+    <item msgid="8073994352956129127">"Kodu"</item>
+    <item msgid="7084237356602625604">"Töö"</item>
+    <item msgid="1112044410659011023">"Muu"</item>
+    <item msgid="2374913952870110618">"Kohandatud"</item>
+  </string-array>
+  <string-array name="postalAddressTypes">
+    <item msgid="6880257626740047286">"Kodu"</item>
+    <item msgid="5629153956045109251">"Töö"</item>
+    <item msgid="4966604264500343469">"Muu"</item>
+    <item msgid="4932682847595299369">"Kohandatud"</item>
+  </string-array>
+  <string-array name="imAddressTypes">
+    <item msgid="1738585194601476694">"Kodu"</item>
+    <item msgid="1359644565647383708">"Töö"</item>
+    <item msgid="7868549401053615677">"Muu"</item>
+    <item msgid="3145118944639869809">"Kohandatud"</item>
+  </string-array>
+  <string-array name="organizationTypes">
+    <item msgid="7546335612189115615">"Töö"</item>
+    <item msgid="4378074129049520373">"Muu"</item>
+    <item msgid="3455047468583965104">"Kohandatud"</item>
+  </string-array>
+  <string-array name="imProtocols">
+    <item msgid="8595261363518459565">"AIM"</item>
+    <item msgid="7390473628275490700">"Windows Live"</item>
+    <item msgid="7882877134931458217">"Yahoo"</item>
+    <item msgid="5035376313200585242">"Skype"</item>
+    <item msgid="7532363178459444943">"QQ"</item>
+    <item msgid="3713441034299660749">"Google Talk"</item>
+    <item msgid="2506857312718630823">"ICQ"</item>
+    <item msgid="1648797903785279353">"Jabber"</item>
+  </string-array>
+    <string name="phoneTypeCustom" msgid="1644738059053355820">"Kohandatud"</string>
+    <string name="phoneTypeHome" msgid="2570923463033985887">"Kodune telefon"</string>
+    <string name="phoneTypeMobile" msgid="6501463557754751037">"Mobiil"</string>
+    <string name="phoneTypeWork" msgid="8863939667059911633">"Töökoha telefon"</string>
+    <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Töökoha faksinumber"</string>
+    <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Kodune faksinumber"</string>
+    <string name="phoneTypePager" msgid="7582359955394921732">"Piipar"</string>
+    <string name="phoneTypeOther" msgid="1544425847868765990">"Muu"</string>
+    <string name="phoneTypeCallback" msgid="2712175203065678206">"Tagasihelistus"</string>
+    <string name="phoneTypeCar" msgid="8738360689616716982">"Auto"</string>
+    <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Ettevõtte üldtelefon"</string>
+    <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string>
+    <string name="phoneTypeMain" msgid="6766137010628326916">"Peamine"</string>
+    <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Teine faks"</string>
+    <string name="phoneTypeRadio" msgid="4093738079908667513">"Raadiotelefon"</string>
+    <string name="phoneTypeTelex" msgid="3367879952476250512">"Teleksinumber"</string>
+    <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY TDD"</string>
+    <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Töökoha mobiiltelefon"</string>
+    <string name="phoneTypeWorkPager" msgid="649938731231157056">"Töökoha piipar"</string>
+    <string name="phoneTypeAssistant" msgid="5596772636128562884">"Assistent"</string>
+    <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string>
+    <string name="eventTypeCustom" msgid="7837586198458073404">"Kohandatud"</string>
+    <string name="eventTypeBirthday" msgid="2813379844211390740">"Sünnipäev"</string>
+    <string name="eventTypeAnniversary" msgid="3876779744518284000">"Aastapäev"</string>
+    <string name="eventTypeOther" msgid="7388178939010143077">"Muu"</string>
+    <string name="emailTypeCustom" msgid="8525960257804213846">"Kohandatud"</string>
+    <string name="emailTypeHome" msgid="449227236140433919">"Kodune e-post"</string>
+    <string name="emailTypeWork" msgid="3548058059601149973">"Töökoha e-post"</string>
+    <string name="emailTypeOther" msgid="2923008695272639549">"Muu"</string>
+    <string name="emailTypeMobile" msgid="119919005321166205">"Mobiil"</string>
+    <string name="postalTypeCustom" msgid="8903206903060479902">"Kohandatud"</string>
+    <string name="postalTypeHome" msgid="8165756977184483097">"Kodune aadress"</string>
+    <string name="postalTypeWork" msgid="5268172772387694495">"Töökoha aadress"</string>
+    <string name="postalTypeOther" msgid="2726111966623584341">"Muu"</string>
+    <string name="imTypeCustom" msgid="2074028755527826046">"Kohandatud"</string>
+    <string name="imTypeHome" msgid="6241181032954263892">"Kodune IM-aadress"</string>
+    <string name="imTypeWork" msgid="1371489290242433090">"Töökoha IM-aadress"</string>
+    <string name="imTypeOther" msgid="5377007495735915478">"Muu"</string>
+    <string name="imProtocolCustom" msgid="6919453836618749992">"Kohandatud"</string>
+    <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string>
+    <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string>
+    <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">"Hangouts"</string>
+    <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">"Töö"</string>
+    <string name="orgTypeOther" msgid="3951781131570124082">"Muu"</string>
+    <string name="orgTypeCustom" msgid="225523415372088322">"Kohandatud"</string>
+    <string name="relationTypeCustom" msgid="3542403679827297300">"Kohandatud"</string>
+    <string name="relationTypeAssistant" msgid="6274334825195379076">"Assistent"</string>
+    <string name="relationTypeBrother" msgid="8757913506784067713">"Vend"</string>
+    <string name="relationTypeChild" msgid="1890746277276881626">"Laps"</string>
+    <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"Elukaaslane"</string>
+    <string name="relationTypeFather" msgid="5228034687082050725">"Isa"</string>
+    <string name="relationTypeFriend" msgid="7313106762483391262">"Sõber"</string>
+    <string name="relationTypeManager" msgid="6365677861610137895">"Haldur"</string>
+    <string name="relationTypeMother" msgid="4578571352962758304">"Ema"</string>
+    <string name="relationTypeParent" msgid="4755635567562925226">"Vanem"</string>
+    <string name="relationTypePartner" msgid="7266490285120262781">"Partner"</string>
+    <string name="relationTypeReferredBy" msgid="101573059844135524">"Viitas:"</string>
+    <string name="relationTypeRelative" msgid="1799819930085610271">"Sugulane"</string>
+    <string name="relationTypeSister" msgid="1735983554479076481">"Õde"</string>
+    <string name="relationTypeSpouse" msgid="394136939428698117">"Abikaasa"</string>
+    <string name="sipAddressTypeCustom" msgid="2473580593111590945">"Kohandatud"</string>
+    <string name="sipAddressTypeHome" msgid="6093598181069359295">"Kodu"</string>
+    <string name="sipAddressTypeWork" msgid="6920725730797099047">"Töö"</string>
+    <string name="sipAddressTypeOther" msgid="4408436162950119849">"Muu"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Sisestage PIN-kood"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Sisestage PUK-kood ja uus PIN-kood"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-kood"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Uus PIN-kood"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Puudutage parooli sisestamiseks"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Avamiseks sisestage parool"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Avamiseks sisestage PIN-kood"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Vale PIN-kood."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Avamiseks vajutage menüüklahvi, seejärel klahvi 0."</string>
+    <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"Hädaabinumber"</string>
+    <string name="lockscreen_carrier_default" msgid="8963839242565653192">"Teenus puudub."</string>
+    <string name="lockscreen_screen_locked" msgid="7288443074806832904">"Ekraan lukus."</string>
+    <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Vajutage avamiseks või hädaabikõne tegemiseks menüünuppu"</string>
+    <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Vajutage avamiseks menüüklahvi."</string>
+    <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Avamiseks joonistage muster"</string>
+    <string name="lockscreen_emergency_call" msgid="5347633784401285225">"Hädaabikõne"</string>
+    <string name="lockscreen_return_to_call" msgid="5244259785500040021">"Kõne juurde tagasi"</string>
+    <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Õige."</string>
+    <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Proovige uuesti"</string>
+    <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Proovige uuesti"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Maksimaalne teenusega Face Unlock avamise katsete arv on ületatud"</string>
+    <string name="lockscreen_plugged_in" msgid="8057762828355572315">"Laadimine, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_charged" msgid="321635745684060624">"Laetud"</string>
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_low_battery" msgid="1482873981919249740">"Ühendage laadija."</string>
+    <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"SIM-kaarti pole"</string>
+    <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Tahvelarvutis pole SIM-kaarti."</string>
+    <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"Telefonis pole SIM-kaarti."</string>
+    <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Sisestage SIM-kaart."</string>
+    <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM-kaart puudub või on loetamatu. Sisestage SIM-kaart."</string>
+    <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Kasutamiskõlbmatu SIM-kaart."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"SIM-kaart on jäädavalt keelatud.\n Teise SIM-kaardi saamiseks võtke ühendust oma traadita side teenusepakkujaga."</string>
+    <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Eelmise loo nupp"</string>
+    <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Nupp Järgmine rada"</string>
+    <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Nupp Peata"</string>
+    <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Nupp Esita"</string>
+    <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Nupp Peata"</string>
+    <string name="emergency_calls_only" msgid="6733978304386365407">"Ainult hädaabikõned"</string>
+    <string name="lockscreen_network_locked_message" msgid="143389224986028501">"Võrk suletud"</string>
+    <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM-kaart on PUK-lukus."</string>
+    <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Vaadake kasutusjuhendit või võtke ühendust klienditeenindusega."</string>
+    <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM-kaart on lukus."</string>
+    <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM-kaardi avamine ..."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Olete oma avamismustrit <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti koostanud. \n\nProovige <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast uuesti."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Olete parooli <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti sisestanud. \n\nProovige <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast uuesti."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Olete PIN-koodi <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti sisestanud. \n\nProovige <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast uuesti."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset palutakse teil tahvelarvuti avada Google\'i sisselogimisega.\n\n Proovige <xliff:g id="NUMBER_2">%d</xliff:g> sekundi pärast uuesti."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset palutakse teil telefon avada Google\'i sisselogimisega.\n\n Proovige <xliff:g id="NUMBER_2">%d</xliff:g> sekundi pärast uuesti."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Olete üritanud <xliff:g id="NUMBER_0">%d</xliff:g> korda tahvelarvutit valesti avada. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> edutut katset lähtestatakse tahvelarvuti tehase vaikeseadetele ja kõik kasutajaandmed lähevad kaotsi."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Olete üritanud <xliff:g id="NUMBER_0">%d</xliff:g> korda telefoni valesti avada. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset lähtestatakse telefon tehase vaikeseadetele ja kõik kasutajaandmed lähevad kaotsi."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Olete püüdnud tahvelarvutit <xliff:g id="NUMBER">%d</xliff:g> korda valesti avada. Tahvelarvuti lähtestatakse nüüd tehase vaikeseadetele."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Olete püüdnud telefoni <xliff:g id="NUMBER">%d</xliff:g> korda valesti avada. Telefon lähtestatakse nüüd tehase vaikeseadetele."</string>
+    <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Proovige uuesti <xliff:g id="NUMBER">%d</xliff:g> sekundi pärast."</string>
+    <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Kas unustasite mustri?"</string>
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Konto avamine"</string>
+    <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"Liiga palju mustrikatseid"</string>
+    <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"Avamiseks logige sisse oma Google\'i kontoga."</string>
+    <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Kasutajanimi (e-post)"</string>
+    <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Parool"</string>
+    <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Logi sisse"</string>
+    <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Vale kasutajanimi või parool."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Kas unustasite oma kasutajanime või parooli?\nKülastage aadressi "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Kontrollimine ..."</string>
+    <string name="lockscreen_unlock_label" msgid="737440483220667054">"Ava"</string>
+    <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Heli sisse"</string>
+    <string name="lockscreen_sound_off_label" msgid="996822825154319026">"Heli välja"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Mustri koostamisega on alustatud"</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Muster on kustutatud"</string>
+    <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Lahter on lisatud"</string>
+    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Muster on valmis"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Vidin %2$d/%3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Vidina lisamine."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tühi"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Avamisala on laiendatud."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Avamisala on ahendatud."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Vidin <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Kasutaja valija"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Olek"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Kaamera"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Meedia juhtnupud"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Vidina ümberkorraldamine algas."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Vidina ümberkorraldamine lõppes."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Vidin <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> on kustutatud."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Avamisala laiendamine."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Lohistamisega avamine."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Mustriga avamine."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Näoga avamine."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"PIN-koodiga avamine."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Parooliga avamine."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Mustri ala."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Lohistamisala."</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="granularity_label_character" msgid="7336470535385009523">"tähemärk"</string>
+    <string name="granularity_label_word" msgid="7075570328374918660">"sõna"</string>
+    <string name="granularity_label_link" msgid="5815508880782488267">"link"</string>
+    <string name="granularity_label_line" msgid="5764267235026120888">"rida"</string>
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
+    <string name="factorytest_failed" msgid="5410270329114212041">"Tehasetest ebaõnnestus"</string>
+    <string name="factorytest_not_system" msgid="4435201656767276723">"Toimingut FACTORY_TEST toetatakse ainult kausta \\system\\app installitud pakettide puhul."</string>
+    <string name="factorytest_no_action" msgid="872991874799998561">"Ei leitud ühtegi paketti, mis võimaldaks toimingut FACTORY_TEST."</string>
+    <string name="factorytest_reboot" msgid="6320168203050791643">"Taaskäivita"</string>
+    <string name="js_dialog_title" msgid="1987483977834603872">"Leht  „<xliff:g id="TITLE">%s</xliff:g>” ütleb järgmist."</string>
+    <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
+    <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Navigeerimise kinnitamine"</string>
+    <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Lahku sellelt lehelt"</string>
+    <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Jää sellele lehele"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nKas soovite kindlasti sellelt lehelt lahkuda?"</string>
+    <string name="save_password_label" msgid="6860261758665825069">"Kinnita"</string>
+    <string name="double_tap_toast" msgid="4595046515400268881">"Vihje: suurendamiseks ja vähendamiseks puudutage kaks korda."</string>
+    <string name="autofill_this_form" msgid="4616758841157816676">"Automaatne täitmine"</string>
+    <string name="setup_autofill" msgid="7103495070180590814">"Automaatse täitmise seadistamine"</string>
+    <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
+    <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
+    <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
+    <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
+    <string name="autofill_province" msgid="2231806553863422300">"Provints"</string>
+    <string name="autofill_postal_code" msgid="4696430407689377108">"Sihtnumber"</string>
+    <string name="autofill_state" msgid="6988894195520044613">"Olek"</string>
+    <string name="autofill_zip_code" msgid="8697544592627322946">"Sihtnumber"</string>
+    <string name="autofill_county" msgid="237073771020362891">"Maakond"</string>
+    <string name="autofill_island" msgid="4020100875984667025">"Saar"</string>
+    <string name="autofill_district" msgid="8400735073392267672">"Piirkond"</string>
+    <string name="autofill_department" msgid="5343279462564453309">"Osakond"</string>
+    <string name="autofill_prefecture" msgid="2028499485065800419">"Prefektuur"</string>
+    <string name="autofill_parish" msgid="8202206105468820057">"Vald"</string>
+    <string name="autofill_area" msgid="3547409050889952423">"Piirkond"</string>
+    <string name="autofill_emirate" msgid="2893880978835698818">"Emiraat"</string>
+    <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"lugege oma veebijärjehoidjaid ja -ajalugu"</string>
+    <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Võimaldab rakendusel lugeda kõikide URL-ide ajalugu, mida brauser on külastanud, ja kõiki brauseri järjehoidjaid. Märkus: see luba ei pruugi jõustuda kolmanda osapoole brauseritega või teiste veebisirvimisvõimega rakendustega."</string>
+    <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"kirjutage veebijärjehoidjaid ja -ajalugu"</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Võimaldab rakendusel muuta tahvelarvutisse salvestatud brauseri ajalugu või järjehoidjaid. See võimaldab rakendusel kustutada või muuta brauseri andmeid. Märkus: see luba ei pruugi jõustuda kolmanda osapoole brauserites või teistes veebisirvimisvõimega rakendustes."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Võimaldab rakendusel muuta telefoni salvestatud brauseri ajalugu või järjehoidjaid. See võimaldab rakendusel kustutada või muuta brauseri andmeid. Märkus: see luba ei pruugi jõustuda kolmanda osapoole brauserites või teistes veebisirvimisvõimega rakendustes."</string>
+    <string name="permlab_setAlarm" msgid="1379294556362091814">"määrake äratus"</string>
+    <string name="permdesc_setAlarm" msgid="316392039157473848">"Võimaldab rakendusel seada installitud äratuskellarakenduses äratuse. Mõned äratuskellarakendused ei pruugi seda funktsiooni juurutada."</string>
+    <string name="permlab_addVoicemail" msgid="5525660026090959044">"lisa kõneposti"</string>
+    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Võimaldab rakendusel lisada sõnumeid teie kõneposti postkasti."</string>
+    <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"Brauseri geolokatsiooniõiguste muutmine"</string>
+    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Võimaldab rakendusel muuta brauseri geolokatsiooniõigusi. Pahatahtlikud rakendused võivad seda kasutada asukohateabe saatmise lubamiseks suvalistele veebisaitidele."</string>
+    <string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"pakettide kinnitamine"</string>
+    <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"Võimaldab rakendusel kinnitada, et paketti saab installida."</string>
+    <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"sidumine paketi kinnitajaga"</string>
+    <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Lubab omanikul teha taotlusi paketi kinnitajate kohta. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
+    <string name="permlab_serialPort" msgid="546083327654631076">"juurdepääs jadaportidele"</string>
+    <string name="permdesc_serialPort" msgid="2991639985224598193">"Võimaldab omanikul SerialManageri API-liidese abil jadaportidele juurde pääseda."</string>
+    <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"väline juurdepääs sisupakkujatele"</string>
+    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Võimaldab valdajal hankida juurdepääsu sisupakkujatele kesta kaudu. Pole kunagi vajalik tavaliste rakenduste puhul."</string>
+    <string name="permlab_updateLock" msgid="3527558366616680889">"seadme autom. värskendamiste takistamine"</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"Võimaldab valdajal pakkuda süsteemile teavet selle kohta, kas on sobiv aeg mitteinteraktiivseks taaskäivitamiseks, et viia seade üle uuele versioonile."</string>
+    <string name="save_password_message" msgid="767344687139195790">"Kas soovite, et brauser jätaks selle parooli meelde?"</string>
+    <string name="save_password_notnow" msgid="6389675316706699758">"Mitte praegu"</string>
+    <string name="save_password_remember" msgid="6491879678996749466">"Pidage meeles"</string>
+    <string name="save_password_never" msgid="8274330296785855105">"Mitte kunagi"</string>
+    <string name="open_permission_deny" msgid="7374036708316629800">"Teil pole luba selle lehe avamiseks."</string>
+    <string name="text_copied" msgid="4985729524670131385">"Lõikelauale kopeeritud tekst."</string>
+    <string name="more_item_label" msgid="4650918923083320495">"Rohkem"</string>
+    <string name="prepend_shortcut_label" msgid="2572214461676015642">"Menüü+"</string>
+    <string name="menu_space_shortcut_label" msgid="2410328639272162537">"tühik"</string>
+    <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"sisestusklahv"</string>
+    <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"kustuta"</string>
+    <string name="search_go" msgid="8298016669822141719">"Otsing"</string>
+    <string name="searchview_description_search" msgid="6749826639098512120">"Otsing"</string>
+    <string name="searchview_description_query" msgid="5911778593125355124">"Otsingupäring"</string>
+    <string name="searchview_description_clear" msgid="1330281990951833033">"Tühjenda päring"</string>
+    <string name="searchview_description_submit" msgid="2688450133297983542">"Päringu esitamine"</string>
+    <string name="searchview_description_voice" msgid="2453203695674994440">"Häälotsing"</string>
+    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Kas lubada puudutusega uurimine?"</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> soovib lubada puudutusega uurimise. Kui puudutusega uurimine on sisse lülitatud, kuulete või näete kirjeldusi asjade kohta, mis on teie sõrme all, või saate suhelda tahvelarvutiga liigutuste abil."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> soovib lubada puudutusega uurimise. Kui puudutusega uurimine on sisse lülitatud, kuulete või näete kirjeldusi asjade kohta, mis on teie sõrme all, või saate suhelda telefoniga liigutuste abil."</string>
+    <string name="oneMonthDurationPast" msgid="7396384508953779925">"1 kuu tagasi"</string>
+    <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Varem kui 1 kuu tagasi"</string>
+  <plurals name="num_seconds_ago">
+    <item quantity="one" msgid="4869870056547896011">"1 sekund tagasi"</item>
+    <item quantity="other" msgid="3903706804349556379">"<xliff:g id="COUNT">%d</xliff:g> sekundit tagasi"</item>
+  </plurals>
+  <plurals name="num_minutes_ago">
+    <item quantity="one" msgid="3306787433088810191">"1 minut tagasi"</item>
+    <item quantity="other" msgid="2176942008915455116">"<xliff:g id="COUNT">%d</xliff:g> minutit tagasi"</item>
+  </plurals>
+  <plurals name="num_hours_ago">
+    <item quantity="one" msgid="9150797944610821849">"1 tund tagasi"</item>
+    <item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> tundi tagasi"</item>
+  </plurals>
+  <plurals name="last_num_days">
+    <item quantity="other" msgid="3069992808164318268">"Viimased <xliff:g id="COUNT">%d</xliff:g> päeva"</item>
+  </plurals>
+    <string name="last_month" msgid="3959346739979055432">"Eelmisel kuul"</string>
+    <string name="older" msgid="5211975022815554840">"Vanem"</string>
+  <plurals name="num_days_ago">
+    <item quantity="one" msgid="861358534398115820">"eile"</item>
+    <item quantity="other" msgid="2479586466153314633">"<xliff:g id="COUNT">%d</xliff:g> päeva tagasi"</item>
+  </plurals>
+  <plurals name="in_num_seconds">
+    <item quantity="one" msgid="2729745560954905102">"1 sekundi pärast"</item>
+    <item quantity="other" msgid="1241926116443974687">"<xliff:g id="COUNT">%d</xliff:g> sekundi pärast"</item>
+  </plurals>
+  <plurals name="in_num_minutes">
+    <item quantity="one" msgid="8793095251325200395">"1 minuti pärast"</item>
+    <item quantity="other" msgid="3330713936399448749">"<xliff:g id="COUNT">%d</xliff:g> minuti pärast"</item>
+  </plurals>
+  <plurals name="in_num_hours">
+    <item quantity="one" msgid="7164353342477769999">"1 tunni pärast"</item>
+    <item quantity="other" msgid="547290677353727389">"<xliff:g id="COUNT">%d</xliff:g> tunni pärast"</item>
+  </plurals>
+  <plurals name="in_num_days">
+    <item quantity="one" msgid="5413088743009839518">"homme"</item>
+    <item quantity="other" msgid="5109449375100953247">"<xliff:g id="COUNT">%d</xliff:g> päeva pärast"</item>
+  </plurals>
+  <plurals name="abbrev_num_seconds_ago">
+    <item quantity="one" msgid="1849036840200069118">"1 s tagasi"</item>
+    <item quantity="other" msgid="3699169366650930415">"<xliff:g id="COUNT">%d</xliff:g> sekundit tagasi"</item>
+  </plurals>
+  <plurals name="abbrev_num_minutes_ago">
+    <item quantity="one" msgid="6361490147113871545">"1 minut tagasi"</item>
+    <item quantity="other" msgid="851164968597150710">"<xliff:g id="COUNT">%d</xliff:g> minutit tagasi"</item>
+  </plurals>
+  <plurals name="abbrev_num_hours_ago">
+    <item quantity="one" msgid="4796212039724722116">"1 tund tagasi"</item>
+    <item quantity="other" msgid="6889970745748538901">"<xliff:g id="COUNT">%d</xliff:g> tundi tagasi"</item>
+  </plurals>
+  <plurals name="abbrev_num_days_ago">
+    <item quantity="one" msgid="8463161711492680309">"eile"</item>
+    <item quantity="other" msgid="3453342639616481191">"<xliff:g id="COUNT">%d</xliff:g> päeva tagasi"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_seconds">
+    <item quantity="one" msgid="5842225370795066299">"1 sekundi pärast"</item>
+    <item quantity="other" msgid="5495880108825805108">"<xliff:g id="COUNT">%d</xliff:g> sekundi pärast"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_minutes">
+    <item quantity="one" msgid="562786149928284878">"1 minuti pärast"</item>
+    <item quantity="other" msgid="4216113292706568726">"<xliff:g id="COUNT">%d</xliff:g> minuti pärast"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_hours">
+    <item quantity="one" msgid="3274708118124045246">"1 tunni pärast"</item>
+    <item quantity="other" msgid="3705373766798013406">"<xliff:g id="COUNT">%d</xliff:g> tunni pärast"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_days">
+    <item quantity="one" msgid="2178576254385739855">"homme"</item>
+    <item quantity="other" msgid="2973062968038355991">"<xliff:g id="COUNT">%d</xliff:g> päeva pärast"</item>
+  </plurals>
+    <string name="preposition_for_date" msgid="9093949757757445117">"kuupäeval <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="preposition_for_time" msgid="5506831244263083793">"kell <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="preposition_for_year" msgid="5040395640711867177">"aastal <xliff:g id="YEAR">%s</xliff:g>"</string>
+    <string name="day" msgid="8144195776058119424">"päev"</string>
+    <string name="days" msgid="4774547661021344602">"päeva"</string>
+    <string name="hour" msgid="2126771916426189481">"tund"</string>
+    <string name="hours" msgid="894424005266852993">"tundi"</string>
+    <string name="minute" msgid="9148878657703769868">"min"</string>
+    <string name="minutes" msgid="5646001005827034509">"min"</string>
+    <string name="second" msgid="3184235808021478">"s"</string>
+    <string name="seconds" msgid="3161515347216589235">"s"</string>
+    <string name="week" msgid="5617961537173061583">"nädal"</string>
+    <string name="weeks" msgid="6509623834583944518">"nädalat"</string>
+    <string name="year" msgid="4001118221013892076">"aasta"</string>
+    <string name="years" msgid="6881577717993213522">"aastat"</string>
+  <plurals name="duration_seconds">
+    <item quantity="one" msgid="6962015528372969481">"1 sekund"</item>
+    <item quantity="other" msgid="1886107766577166786">"<xliff:g id="COUNT">%d</xliff:g> sekundit"</item>
+  </plurals>
+  <plurals name="duration_minutes">
+    <item quantity="one" msgid="4915414002546085617">"1 minut"</item>
+    <item quantity="other" msgid="3165187169224908775">"<xliff:g id="COUNT">%d</xliff:g> minutit"</item>
+  </plurals>
+  <plurals name="duration_hours">
+    <item quantity="one" msgid="8917467491248809972">"1 tund"</item>
+    <item quantity="other" msgid="3863962854246773930">"<xliff:g id="COUNT">%d</xliff:g> tundi"</item>
+  </plurals>
+    <string name="VideoView_error_title" msgid="3534509135438353077">"Probleem videoga"</string>
+    <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"See video ei sobi voogesituseks selles seadmes."</string>
+    <string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Videot ei saa esitada."</string>
+    <string name="VideoView_error_button" msgid="2822238215100679592">"OK"</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">"keskpäev"</string>
+    <string name="Noon" msgid="3342127745230013127">"Keskpäev"</string>
+    <string name="midnight" msgid="7166259508850457595">"kesköö"</string>
+    <string name="Midnight" msgid="5630806906897892201">"Kesköö"</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">"Vali kõik"</string>
+    <string name="cut" msgid="3092569408438626261">"Lõika"</string>
+    <string name="copy" msgid="2681946229533511987">"Kopeeri"</string>
+    <string name="paste" msgid="5629880836805036433">"Kleebi"</string>
+    <string name="replace" msgid="5781686059063148930">"Asenda..."</string>
+    <string name="delete" msgid="6098684844021697789">"Kustuta"</string>
+    <string name="copyUrl" msgid="2538211579596067402">"Kopeeri URL"</string>
+    <string name="selectTextMode" msgid="1018691815143165326">"Valige tekst"</string>
+    <string name="textSelectionCABTitle" msgid="5236850394370820357">"Teksti valimine"</string>
+    <string name="addToDictionary" msgid="4352161534510057874">"Lisa sõnastikku"</string>
+    <string name="deleteText" msgid="6979668428458199034">"Kustuta"</string>
+    <string name="inputMethod" msgid="1653630062304567879">"Sisestusmeetod"</string>
+    <string name="editTextMenuTitle" msgid="4909135564941815494">"Tekstitoimingud"</string>
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Talletusruum saab täis"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Mõned süsteemifunktsioonid ei pruugi töötada"</string>
+    <string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> töötab"</string>
+    <string name="app_running_notification_text" msgid="4653586947747330058">"Puudutage lisateabe saamiseks või rakenduse peatamiseks."</string>
+    <string name="ok" msgid="5970060430562524910">"OK"</string>
+    <string name="cancel" msgid="6442560571259935130">"Tühista"</string>
+    <string name="yes" msgid="5362982303337969312">"OK"</string>
+    <string name="no" msgid="5141531044935541497">"Tühista"</string>
+    <string name="dialog_alert_title" msgid="2049658708609043103">"Tähelepanu"</string>
+    <string name="loading" msgid="7933681260296021180">"Laadimine ..."</string>
+    <string name="capital_on" msgid="1544682755514494298">"SEES"</string>
+    <string name="capital_off" msgid="6815870386972805832">"VÄLJAS"</string>
+    <string name="whichApplication" msgid="4533185947064773386">"Lõpetage toiming rakendusega"</string>
+    <string name="alwaysUse" msgid="4583018368000610438">"Kasuta vaikimisi selleks toiminguks."</string>
+    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Tühjendage vaikeandmed valikutes Süsteemiseaded &gt; Rakendused &gt; Allalaaditud."</string>
+    <string name="chooseActivity" msgid="7486876147751803333">"Toimingu valimine"</string>
+    <string name="chooseUsbActivity" msgid="6894748416073583509">"USB-seadme jaoks rakenduse valimine"</string>
+    <string name="noApplications" msgid="2991814273936504689">"Ükski rakendus ei saa seda toimingut teostada."</string>
+    <string name="aerr_title" msgid="1905800560317137752"></string>
+    <string name="aerr_application" msgid="932628488013092776">"Kahjuks on rakendus <xliff:g id="APPLICATION">%1$s</xliff:g> peatunud."</string>
+    <string name="aerr_process" msgid="4507058997035697579">"Kahjuks on protsess <xliff:g id="PROCESS">%1$s</xliff:g> peatunud."</string>
+    <string name="anr_title" msgid="4351948481459135709"></string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> ei vasta.\n\nKas soovite selle sulgeda?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Tegevus <xliff:g id="ACTIVITY">%1$s</xliff:g> ei vasta.\n\nKas soovite selle sulgeda?"</string>
+    <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> ei vasta. Kas soovite selle sulgeda?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Protsess <xliff:g id="PROCESS">%1$s</xliff:g> ei vasta.\n\nKas soovite selle sulgeda?"</string>
+    <string name="force_close" msgid="8346072094521265605">"OK"</string>
+    <string name="report" msgid="4060218260984795706">"Teata"</string>
+    <string name="wait" msgid="7147118217226317732">"Oodake"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Leht ei reageeri.\n\nKas soovite selle sulgeda?"</string>
+    <string name="launch_warning_title" msgid="1547997780506713581">"Rakendus on ümber suunatud"</string>
+    <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> on nüüd käivitunud."</string>
+    <string name="launch_warning_original" msgid="188102023021668683">"Algselt käivitati rakendus <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+    <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Mõõtkava"</string>
+    <string name="screen_compat_mode_show" msgid="4013878876486655892">"Kuva alati"</string>
+    <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Lubage see uuesti valikutes Süsteemiseaded &gt; Rakendused &gt; Allalaaditud."</string>
+    <string name="smv_application" msgid="3307209192155442829">"Rakendus <xliff:g id="APPLICATION">%1$s</xliff:g> (protsess <xliff:g id="PROCESS">%2$s</xliff:g>) on rikkunud isekehtestatud StrictMode\'i eeskirju."</string>
+    <string name="smv_process" msgid="5120397012047462446">"Protsess <xliff:g id="PROCESS">%1$s</xliff:g> on rikkunud isejõustatud StrictMode\'i eeskirju."</string>
+    <string name="android_upgrading_title" msgid="1584192285441405746">"Android viiakse üle uuemale versioonile ..."</string>
+    <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_0">%1$d</xliff:g>. rakenduse <xliff:g id="NUMBER_1">%2$d</xliff:g>-st optimeerimine."</string>
+    <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Rakenduste käivitamine."</string>
+    <string name="android_upgrading_complete" msgid="1405954754112999229">"Käivitamise lõpuleviimine."</string>
+    <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> töötab"</string>
+    <string name="heavy_weight_notification_detail" msgid="1721681741617898865">"Puudutage rakendusele lülitumiseks"</string>
+    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Kas lülituda teisele rakendusele?"</string>
+    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Teine rakendus juba töötab ja see tuleb peatada, et saaksite uue käivitada."</string>
+    <string name="old_app_action" msgid="493129172238566282">"Tagasi rakendusse <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
+    <string name="old_app_description" msgid="2082094275580358049">"Ärge käivitage uut rakendust."</string>
+    <string name="new_app_action" msgid="5472756926945440706">"Käivitage rakendus <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
+    <string name="new_app_description" msgid="1932143598371537340">"Peatage vana rakendus salvestamata."</string>
+    <string name="sendText" msgid="5209874571959469142">"Valige teksti jaoks toiming"</string>
+    <string name="volume_ringtone" msgid="6885421406845734650">"Helina helitugevus"</string>
+    <string name="volume_music" msgid="5421651157138628171">"Meediumi helitugevus"</string>
+    <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"Esitatakse Bluetoothi kaudu"</string>
+    <string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"Valitud on hääletu märguanne"</string>
+    <string name="volume_call" msgid="3941680041282788711">"Kõne helitugevus"</string>
+    <string name="volume_bluetooth_call" msgid="2002891926351151534">"Bluetoothi kõne helitugevus"</string>
+    <string name="volume_alarm" msgid="1985191616042689100">"Alarmi helitugevus"</string>
+    <string name="volume_notification" msgid="2422265656744276715">"Teadistusheli"</string>
+    <string name="volume_unknown" msgid="1400219669770445902">"Helitugevus"</string>
+    <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"Bluetoothi maht"</string>
+    <string name="volume_icon_description_ringer" msgid="3326003847006162496">"Helina tugevus"</string>
+    <string name="volume_icon_description_incall" msgid="8890073218154543397">"Kõne helitugevus"</string>
+    <string name="volume_icon_description_media" msgid="4217311719665194215">"Meediumi helitugevus"</string>
+    <string name="volume_icon_description_notification" msgid="7044986546477282274">"Teatise helitugevus"</string>
+    <string name="ringtone_default" msgid="3789758980357696936">"Vaikehelin"</string>
+    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Vaikehelin (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <string name="ringtone_silent" msgid="7937634392408977062">"Puudub"</string>
+    <string name="ringtone_picker_title" msgid="3515143939175119094">"Helinad"</string>
+    <string name="ringtone_unknown" msgid="5477919988701784788">"Tundmatu helin"</string>
+  <plurals name="wifi_available">
+    <item quantity="one" msgid="6654123987418168693">"WiFi-võrk on saadaval"</item>
+    <item quantity="other" msgid="4192424489168397386">"WiFi-võrgud saadaval"</item>
+  </plurals>
+  <plurals name="wifi_available_detailed">
+    <item quantity="one" msgid="1634101450343277345">"Avatud WiFi võrk on saadaval"</item>
+    <item quantity="other" msgid="7915895323644292768">"Avatud WiFi-võrgud on saadaval"</item>
+  </plurals>
+    <string name="wifi_available_sign_in" msgid="4029489716605255386">"Logige sisse WiFi-võrku"</string>
+    <string name="network_available_sign_in" msgid="8495155593358054676">"Logige võrku"</string>
+    <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
+    <skip />
+    <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Ei saanud WiFi-ga ühendust"</string>
+    <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" on halb Interneti-ühendus."</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_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="1638949953993894335">"Puuted seadete jaoks"</string>
+    <string name="accept" msgid="1645267259272829559">"Nõustu"</string>
+    <string name="decline" msgid="2112225451706137894">"Keeldu"</string>
+    <string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Kutse on saadetud"</string>
+    <string name="wifi_p2p_invitation_to_connect_title" msgid="4958803948658533637">"Kutse ühendamiseks"</string>
+    <string name="wifi_p2p_from_message" msgid="570389174731951769">"Saatja:"</string>
+    <string name="wifi_p2p_to_message" msgid="248968974522044099">"Saaja:"</string>
+    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"Sisestage nõutav PIN-kood:"</string>
+    <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN-kood:"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"Tahvelarvuti ühendus WiFi-ga katkestatakse ajutiselt, kui see on ühendatud seadmega <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"Telefoni ühendus WiFi-ga katkestatakse ajutiselt, kui see on ühendatud seadmega <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="select_character" msgid="3365550120617701745">"Sisesta tähemärk"</string>
+    <string name="sms_control_title" msgid="7296612781128917719">"SMS-sõnumite saatmine"</string>
+    <string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; saadab suurel hulgal SMS-sõnumeid. Kas tahate lubada sellel rakendusel ka edaspidi sõnumeid saata?"</string>
+    <string name="sms_control_yes" msgid="3663725993855816807">"Luba"</string>
+    <string name="sms_control_no" msgid="625438561395534982">"Keela"</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; soovib saata sõnumi aadressile &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt;."</string>
+    <string name="sms_short_code_details" msgid="3492025719868078457">"See "<font fgcolor="#ffffb060">"võib põhjustada kulusid"</font>" teie mobiilikontole."</string>
+    <string name="sms_premium_short_code_details" msgid="5523826349105123687"><font fgcolor="#ffffb060">"See lisab kulusid teie mobiilikontole."</font></string>
+    <string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"Saada"</string>
+    <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"Tühista"</string>
+    <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"Jäta minu valik meelde"</string>
+    <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"Saate muuta jaotises Seaded &gt; Rakendused"</string>
+    <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Luba alati"</string>
+    <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Ära luba"</string>
+    <string name="sim_removed_title" msgid="6227712319223226185">"SIM-kaart eemaldatud"</string>
+    <string name="sim_removed_message" msgid="2333164559970958645">"Mobiilsidevõrk ei ole saadaval, kuni sisestate kehtiva SIM-kaardi ja taaskäivitate seadme."</string>
+    <string name="sim_done_button" msgid="827949989369963775">"Valmis"</string>
+    <string name="sim_added_title" msgid="3719670512889674693">"SIM-kaart lisatud"</string>
+    <string name="sim_added_message" msgid="6599945301141050216">"Mobiilsidevõrku pääsemiseks taaskäivitage seade."</string>
+    <string name="sim_restart_button" msgid="4722407842815232347">"Taaskäivita"</string>
+    <string name="time_picker_dialog_title" msgid="8349362623068819295">"Kellaaja määramine"</string>
+    <string name="date_picker_dialog_title" msgid="5879450659453782278">"Kuupäeva määramine"</string>
+    <string name="date_time_set" msgid="5777075614321087758">"Määra"</string>
+    <string name="date_time_done" msgid="2507683751759308828">"Valmis"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff33b5e5">"UUS: "</font></string>
+    <string name="perms_description_app" msgid="5139836143293299417">"Teenusepakkuja: <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+    <string name="no_permissions" msgid="7283357728219338112">"Lube pole vaja"</string>
+    <string name="perm_costs_money" msgid="4902470324142151116">"see võib olla tasuline"</string>
+    <string name="usb_storage_activity_title" msgid="4465055157209648641">"USB-massmälu"</string>
+    <string name="usb_storage_title" msgid="5901459041398751495">"USB ühendatud"</string>
+    <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"Teil on arvutiga ühendus USB kaudu. Puudutage allolevat nuppu, kui soovite faile arvuti ja Androidi USB-salvestusruumi vahel kopeerida."</string>
+    <string name="usb_storage_message" product="default" msgid="805351000446037811">"Olete arvutiga ühendatud USB kaudu. Puudutage allolevat nuppu, kui soovite faile arvuti ja Androidi SD-kaardi vahel kopeerida."</string>
+    <string name="usb_storage_button_mount" msgid="1052259930369508235">"Lülita USB-mäluseade sisse"</string>
+    <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"Probleem USB-salvestusruumi kasutamisel USB-mäluseadmena."</string>
+    <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"Probleem SD-kaardi kasutamisel USB-mäluseadmena."</string>
+    <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB ühendatud"</string>
+    <string name="usb_storage_notification_message" msgid="939822783828183763">"Puudutage, et kopeerida faile arvutist/arvutisse."</string>
+    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Lülita USB-mäluseade välja"</string>
+    <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"USB-salvestusruumi väljalülitamiseks puudutage."</string>
+    <string name="usb_storage_stop_title" msgid="660129851708775853">"USB kasutusel"</string>
+    <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"Enne USB-salvestusruumi väljalülitamist eraldage (väljutage) Androidi USB-salvestusruum arvutist."</string>
+    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"Enne USB-salvestusruumi väljalülitamist eemaldage (väljutage) Androidi SD-kaart arvutist."</string>
+    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"Lülita USB-mäluseade välja"</string>
+    <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"Tekkis probleem USB-salvestusruumi väljalülitamisega. Kontrollige, kas olete USB-hosti eemaldanud, ja proovige seejärel uuesti."</string>
+    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Lülita USB-mäluseade sisse"</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Kui lülitate USB-salvestusruumi sisse, võivad mõned kasutatavad rakendused peatuda ega pruugi olla saadaval enne USB-salvestusruumi väljalülitamist."</string>
+    <string name="dlg_error_title" msgid="7323658469626514207">"USB toiming ebaõnnestus"</string>
+    <string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
+    <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Ühendatud meediumiseadmena"</string>
+    <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Ühendatud kaamerana"</string>
+    <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Ühendatud installijana"</string>
+    <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Ühendatud USB-lisaseadmega"</string>
+    <string name="usb_notification_message" msgid="2290859399983720271">"Puudutage teisi USB valikuid."</string>
+    <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Vormind. USB-seade?"</string>
+    <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Kas vormindada SD-kaart?"</string>
+    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Kõik USB-mäluseadmele salvestatud failid kustutatakse. Seda toimingut ei saa tagasi võtta."</string>
+    <string name="extmedia_format_message" product="default" msgid="14131895027543830">"Kõik kaardil olevad andmed lähevad kaduma."</string>
+    <string name="extmedia_format_button_format" msgid="4131064560127478695">"Vorminda"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-silumine ühendatud"</string>
+    <string name="adb_active_notification_message" msgid="1016654627626476142">"Puudutage USB-silumise keelamiseks."</string>
+    <string name="select_input_method" msgid="4653387336791222978">"Valige sisestusmeetod"</string>
+    <string name="configure_input_methods" msgid="9091652157722495116">"Seadista sisestusmeetodid"</string>
+    <string name="use_physical_keyboard" msgid="6203112478095117625">"Füüsiline klaviatuur"</string>
+    <string name="hardware" msgid="7517821086888990278">"Riistvara"</string>
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Klaviatuuri paigutuse valimine"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Puudutage klaviatuuri paigutuse valimiseks."</string>
+    <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSŠZŽTUVWÕÄÖÜXY"</string>
+    <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSŠZŽTUVWÕÄÖÜXY"</string>
+    <string name="candidates_style" msgid="4333913089637062257"><u>"kandidaadid"</u></string>
+    <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"USB-mäluseadme ettevalm. ..."</string>
+    <string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"SD-kaardi ettevalmistamine"</string>
+    <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"Vigade kontrollimine."</string>
+    <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"Tühi USB-mäluseade"</string>
+    <string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"Tühi SD-kaart"</string>
+    <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"USB-salvestusruum on tühi või ei toeta failisüsteemi."</string>
+    <string name="ext_media_nofs_notification_message" product="default" msgid="8641065641786923604">"SD-kaart on tühi või ei toetata selle failisüsteemi."</string>
+    <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"Kahjustatud USB-mäluseade"</string>
+    <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"Kahjustatud SD-kaart"</string>
+    <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="1795917578395333280">"USB-salvestusruum on kahjustatud. Proovige uuesti vormindada."</string>
+    <string name="ext_media_unmountable_notification_message" product="default" msgid="1753898567525568253">"SD-kaart on kahjustatud. Proovige uuesti vormindada."</string>
+    <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"USB-seade eemaldati ootamatult"</string>
+    <string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"SD-kaart on ootamatult eemaldatud"</string>
+    <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"Andmekao vältimiseks lahutage USB-mäluseade enne eemaldamist."</string>
+    <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"Andmekao vältimiseks lahutage SD-kaart enne eemaldamist."</string>
+    <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"USB-seadme eemaldamine ohutu"</string>
+    <string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"SD-kaardi eemaldamine on ohutu"</string>
+    <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"Saate USB-mäluseadme ohutult eemaldada."</string>
+    <string name="ext_media_safe_unmount_notification_message" product="default" msgid="568841278138377604">"SD-kaardi saate ohutult eemaldada."</string>
+    <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"USB-mäluseade eemaldatud"</string>
+    <string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"Eemaldatud SD-kaart"</string>
+    <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"USB-mäluseade eemaldatud. Sisestage uus meedium."</string>
+    <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"SD-kaart on eemaldatud. Sisestage uus."</string>
+    <string name="activity_list_empty" msgid="1675388330786841066">"Sobivat tegevust ei leitud"</string>
+    <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"värskenda komponentide kasutusstatistikat"</string>
+    <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"Võimaldab rakendusel muuta komponendi kohta kogutud kasutusstatistikat. Mitte kasutada tavarakenduste puhul."</string>
+    <string name="permlab_copyProtectedData" msgid="4341036311211406692">"Sisu kopeerimine"</string>
+    <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Võimaldab rakendusel võtta sisu kopeerimiseks appi vaikekonteinerteenuse. Mitte kasutada tavarakenduste puhul."</string>
+    <string name="permlab_route_media_output" msgid="1642024455750414694">"Meediaväljundi teekonna koostamine"</string>
+    <string name="permdesc_route_media_output" msgid="4932818749547244346">"Võimaldab rakendusel koostada teekonna meediaväljundist teistesse välistesse seadmetesse."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Juurdepääs võtmekaitsega turvalisele talletusruumile"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Lubab rakendusel hankida juurdepääsu võtmekaitsega turvalisele talletusruumile."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Võtmekaitse kuvamise ja peitmise juhtimine"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Lubab rakendusel võtmekaitset juhtida."</string>
+    <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Suumi juhtimiseks puudutage kaks korda"</string>
+    <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Vidinat ei saanud lisada."</string>
+    <string name="ime_action_go" msgid="8320845651737369027">"Mine"</string>
+    <string name="ime_action_search" msgid="658110271822807811">"Otsing"</string>
+    <string name="ime_action_send" msgid="2316166556349314424">"Saada"</string>
+    <string name="ime_action_next" msgid="3138843904009813834">"Järgmine"</string>
+    <string name="ime_action_done" msgid="8971516117910934605">"Valmis"</string>
+    <string name="ime_action_previous" msgid="1443550039250105948">"Eelm."</string>
+    <string name="ime_action_default" msgid="2840921885558045721">"Täida"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Vali number\n kasutades numbrit <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Loo kontakt\nnumbriga <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Üks või mitu rakendust taotlevad luba pääseda nüüd ja edaspidi teie kontole juurde."</string>
+    <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Kas soovite taotluse lubada?"</string>
+    <string name="grant_permissions_header_text" msgid="6874497408201826708">"Juurdepääsutaotlus"</string>
+    <string name="allow" msgid="7225948811296386551">"Luba"</string>
+    <string name="deny" msgid="2081879885755434506">"Keela"</string>
+    <string name="permission_request_notification_title" msgid="6486759795926237907">"Taotletud luba"</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Luba on taotletud\nkontole <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="input_method_binding_label" msgid="1283557179944992649">"Sisestusmeetod"</string>
+    <string name="sync_binding_label" msgid="3687969138375092423">"Sünkroonimine"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"Juurdepääsetavus"</string>
+    <string name="wallpaper_binding_label" msgid="1240087844304687662">"Taustapilt"</string>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"Muutke taustapilti"</string>
+    <string name="notification_listener_binding_label" msgid="2014162835481906429">"Märguannete kuulamisteenus"</string>
+    <string name="vpn_title" msgid="19615213552042827">"VPN on aktiveeritud"</string>
+    <string name="vpn_title_long" msgid="6400714798049252294">"VPN-i aktiveeris <xliff:g id="APP">%s</xliff:g>"</string>
+    <string name="vpn_text" msgid="3011306607126450322">"Võrgu haldamiseks puudutage."</string>
+    <string name="vpn_text_long" msgid="6407351006249174473">"Ühendatud seansiga <xliff:g id="SESSION">%s</xliff:g>. Võrgu haldamiseks puudutage."</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_error" msgid="6009249814034708175">"Alati sees VPN-i viga"</string>
+    <string name="vpn_lockdown_config" msgid="6415899150671537970">"Puudutage seadistamiseks"</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="8035230537563503262">"Autorežiimist väljumiseks puudutage."</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"Jagamine või tööpunkt on aktiivne"</string>
+    <string name="tethered_notification_message" msgid="6857031760103062982">"Seadistamiseks puudutage."</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>
+    <string name="throttle_warning_notification_title" msgid="4890894267454867276">"Kõrge mobiilse andmeside kasutus"</string>
+    <string name="throttle_warning_notification_message" msgid="3340822228599337743">"Mobiilse andmeside kasutamise kohta lisateabe saamiseks puudutage."</string>
+    <string name="throttled_notification_title" msgid="6269541897729781332">"Mobiili andmemahupiirang ületatud"</string>
+    <string name="throttled_notification_message" msgid="5443457321354907181">"Mobiilse andmeside kasutamise kohta lisateabe saamiseks puudutage."</string>
+    <string name="no_matches" msgid="8129421908915840737">"Vasted puuduvad"</string>
+    <string name="find_on_page" msgid="1946799233822820384">"Otsige lehelt"</string>
+  <plurals name="matches_found">
+    <item quantity="one" msgid="8167147081136579439">"1 vaste"</item>
+    <item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g>/<xliff:g id="TOTAL">%d</xliff:g>"</item>
+  </plurals>
+    <string name="action_mode_done" msgid="7217581640461922289">"Valmis"</string>
+    <string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"USB-salvestusruumi eemaldamine ..."</string>
+    <string name="progress_unmounting" product="default" msgid="1327894998409537190">"SD-kaardi eemaldamine ..."</string>
+    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"USB-salvestusruumi kustutamine ..."</string>
+    <string name="progress_erasing" product="default" msgid="6596988875507043042">"SD-kaardi kustutamine ..."</string>
+    <string name="format_error" product="nosdcard" msgid="6299769563624776948">"USB-mäluseadme tühjendamine ebaõnnestus."</string>
+    <string name="format_error" product="default" msgid="7315248696644510935">"SD-kaardi kustutamine ebaõnnestus."</string>
+    <string name="media_bad_removal" msgid="7960864061016603281">"SD-kaart eemaldati enne lahutamist."</string>
+    <string name="media_checking" product="nosdcard" msgid="418188720009569693">"USB-mäluseadet kontrollitakse praegu."</string>
+    <string name="media_checking" product="default" msgid="7334762503904827481">"SD-kaarti kontrollitakse praegu."</string>
+    <string name="media_removed" msgid="7001526905057952097">"SD-kaart on eemaldatud."</string>
+    <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"Praegu kasutab USB-mäluseadet arvuti."</string>
+    <string name="media_shared" product="default" msgid="5706130568133540435">"Praegu kasutab SD-kaarti arvuti."</string>
+    <string name="media_unknown_state" msgid="729192782197290385">"Väline meedium on tundmatus olekus."</string>
+    <string name="share" msgid="1778686618230011964">"Jaga"</string>
+    <string name="find" msgid="4808270900322985960">"Otsi"</string>
+    <string name="websearch" msgid="4337157977400211589">"Veebiotsing"</string>
+    <string name="find_next" msgid="5742124618942193978">"Leia järgmine"</string>
+    <string name="find_previous" msgid="2196723669388360506">"Leia eelmine"</string>
+    <string name="gpsNotifTicker" msgid="5622683912616496172">"Asukohapäring kasutajalt <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Asukohapäring"</string>
+    <string name="gpsNotifMessage" msgid="1374718023224000702">"Taotleja: <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+    <string name="gpsVerifYes" msgid="2346566072867213563">"Jah"</string>
+    <string name="gpsVerifNo" msgid="1146564937346454865">"Ei"</string>
+    <string name="sync_too_many_deletes" msgid="5296321850662746890">"Kustutamiste piirarv on ületatud"</string>
+    <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"Kustutatavad üksused kontol <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> sünkroonimistüübi <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> jaoks: <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g>. Mida soovite teha?"</string>
+    <string name="sync_really_delete" msgid="2572600103122596243">"Kustuta üksused"</string>
+    <string name="sync_undo_deletes" msgid="2941317360600338602">"Võtke kustutamised tagasi"</string>
+    <string name="sync_do_nothing" msgid="3743764740430821845">"Ära tee praegu midagi"</string>
+    <string name="choose_account_label" msgid="5655203089746423927">"Konto valimine"</string>
+    <string name="add_account_label" msgid="2935267344849993553">"Konto lisamine"</string>
+    <string name="add_account_button_label" msgid="3611982894853435874">"Lisa konto"</string>
+    <string name="number_picker_increment_button" msgid="2412072272832284313">"Suurendamine"</string>
+    <string name="number_picker_decrement_button" msgid="476050778386779067">"Vähendamine"</string>
+    <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> puudutage ja hoidke."</string>
+    <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Suurendamiseks lohistage üles, vähendamiseks alla."</string>
+    <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Minutite suurendamine"</string>
+    <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Minutite vähendamine"</string>
+    <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Tundide suurendamine"</string>
+    <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Tundide vähendamine"</string>
+    <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"PM-i seadmine"</string>
+    <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"AM-i seadmine"</string>
+    <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Kuu suurendamine"</string>
+    <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Kuu vähendamine"</string>
+    <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Päeva suurendamine"</string>
+    <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Päeva vähendamine"</string>
+    <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Aasta suurendamine"</string>
+    <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Aasta vähendamine"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Tühista"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Kustuta"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Valmis"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Režiimi muutmine"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Tõstuklahv"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Sisestusklahv"</string>
+    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Valige rakendus"</string>
+    <string name="shareactionprovider_share_with" msgid="806688056141131819">"Jaga:"</string>
+    <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Jaga rakendusega <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+    <string name="content_description_sliding_handle" msgid="415975056159262248">"Libistamispide. Puudutage ja hoidke all."</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Lohistage üles: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Lohistage alla: <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="description_direction_right" msgid="8034433242579600980">"Lohistage paremale: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Luku avamine"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Kaamera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Hääletu"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Heli on sees"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Otsing"</string>
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Avamiseks tõmmake sõrmega."</string>
+    <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Paroolide kuulamiseks ühendage peakomplekt."</string>
+    <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punkt."</string>
+    <string name="action_bar_home_description" msgid="5293600496601490216">"Liigu avalehele"</string>
+    <string name="action_bar_up_description" msgid="2237496562952152589">"Liigu üles"</string>
+    <string name="action_menu_overflow_description" msgid="2295659037509008453">"Rohkem valikuid"</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="4891916833657929263">"Sisemine salvestusruum"</string>
+    <string name="storage_sd_card" msgid="3282948861378286745">"SD-kaart"</string>
+    <string name="storage_usb" msgid="3017954059538517278">"USB-mäluseade"</string>
+    <string name="extract_edit_menu_button" msgid="8940478730496610137">"Muuda"</string>
+    <string name="data_usage_warning_title" msgid="1955638862122232342">"Andmete kasutamise hoiatus"</string>
+    <string name="data_usage_warning_body" msgid="2814673551471969954">"Kasutuse/sätete vaat. puudutage."</string>
+    <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G–3G-andmeside on keelatud"</string>
+    <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G-andmeside on keelatud"</string>
+    <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobiilne andmeside on keelatud"</string>
+    <string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"WiFi-andmed on keelatud"</string>
+    <string name="data_usage_limit_body" msgid="3317964706973601386">"Lubamiseks puudutage."</string>
+    <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"2G-3G andmemahupiirang ületatud"</string>
+    <string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"4G andmemahupiirang ületatud"</string>
+    <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"Mobiilne andmemahupiirang ületatud"</string>
+    <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"WiFi-andmete piir on ületatud"</string>
+    <string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> üle määratud piirmäära."</string>
+    <string name="data_usage_restricted_title" msgid="5965157361036321914">"Taustandmed on piiratud"</string>
+    <string name="data_usage_restricted_body" msgid="6741521330997452990">"Piirangu eemaldamiseks puudut."</string>
+    <string name="ssl_certificate" msgid="6510040486049237639">"Turvasertifikaat"</string>
+    <string name="ssl_certificate_is_valid" msgid="6825263250774569373">"See sertifikaat on kehtiv."</string>
+    <string name="issued_to" msgid="454239480274921032">"Väljastatud subjektile:"</string>
+    <string name="common_name" msgid="2233209299434172646">"Pärisnimi:"</string>
+    <string name="org_name" msgid="6973561190762085236">"Organisatsioon:"</string>
+    <string name="org_unit" msgid="7265981890422070383">"Organisatsiooniüksus:"</string>
+    <string name="issued_by" msgid="2647584988057481566">"Väljastaja:"</string>
+    <string name="validity_period" msgid="8818886137545983110">"Kehtivus:"</string>
+    <string name="issued_on" msgid="5895017404361397232">"Väljastamiskuupäev:"</string>
+    <string name="expires_on" msgid="3676242949915959821">"Aegumiskuupäev:"</string>
+    <string name="serial_number" msgid="758814067660862493">"Seerianumber:"</string>
+    <string name="fingerprints" msgid="4516019619850763049">"Sõrmejäljed:"</string>
+    <string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 sõrmejälg:"</string>
+    <string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 sõrmejälg:"</string>
+    <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Kuva kõik"</string>
+    <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Tegevuse valimine"</string>
+    <string name="share_action_provider_share_with" msgid="5247684435979149216">"Jagamine rakendusega:"</string>
+    <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="3245653681008218030">"Saatmine ..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Kas käivitada brauser?"</string>
+    <string name="SetupCallDefault" msgid="5834948469253758575">"Kas vastata kõnele?"</string>
+    <string name="activity_resolver_use_always" msgid="8017770747801494933">"Alati"</string>
+    <string name="activity_resolver_use_once" msgid="2404644797149173758">"Ainult üks kord"</string>
+    <string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"Tahvelarvuti"</string>
+    <string name="default_audio_route_name" product="default" msgid="4239291273420140123">"Telefon"</string>
+    <string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Kõrvaklapid"</string>
+    <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Doki kõlarid"</string>
+    <string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string>
+    <string name="default_audio_route_category_name" msgid="3722811174003886946">"Süsteem"</string>
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-heli"</string>
+    <string name="wireless_display_route_description" msgid="9070346425023979651">"Juhtmeta ekraan"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Valmis"</string>
+    <string name="media_route_button_content_description" msgid="5758553567065145276">"Meediaväljund"</string>
+    <string name="media_route_status_scanning" msgid="7279908761758293783">"Skaneering ..."</string>
+    <string name="media_route_status_connecting" msgid="6422571716007825440">"Ühendan..."</string>
+    <string name="media_route_status_available" msgid="6983258067194649391">"Saadaval"</string>
+    <string name="media_route_status_not_available" msgid="6739899962681886401">"Ei ole saadaval"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"Kasutusel"</string>
+    <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Sisseehitatud ekraan"</string>
+    <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"HDMI-ekraan"</string>
+    <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Ülekate nr .<xliff:g id="ID">%1$d</xliff:g>"</string>
+    <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", turvaline"</string>
+    <string name="wifi_display_notification_title" msgid="2223050649240326557">"Juhtmeta ekraaniühendus on loodud"</string>
+    <string name="wifi_display_notification_message" msgid="4498802012464170685">"Ekraan on näha teises seadmes"</string>
+    <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Katkesta ühendus"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Hädaabikõne"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Unustasin mustri"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Vale muster"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Vale parool"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Vale PIN-kood"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Proovige uuesti <xliff:g id="NUMBER">%1$d</xliff:g> sekundi pärast."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Joonistage oma muster"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Sisestage SIM-i PIN-kood"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Sisestage PIN-kood"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Sisestage parool"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM on nüüd keelatud. Jätkamiseks sisestage PUK-kood. Üksikasju küsige operaatorilt."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Sisestage soovitud PIN-kood"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Kinnitage soovitud PIN-kood"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM-kaardi avamine ..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Vale PIN-kood."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Sisestage 4–8-numbriline PIN-kood."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK-koodi pikkus peab olema vähemalt 8 numbrit."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Sisestage uuesti õige PUK-kood. Korduvkatsete korral keelatakse SIM jäädavalt."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-koodid ei ole vastavuses"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Liiga palju mustrikatseid"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Avamiseks logige sisse oma Google\'i kontoga."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Kasutajanimi (e-post)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Parool"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Logi sisse"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Vale kasutajanimi või parool."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Kas unustasite kasutajanime või parooli?\nKülastage aadressi "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Konto kontrollimine ..."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Olete PIN-koodi <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti sisestanud.\n\nProovige <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast uuesti."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Olete parooli <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti sisestanud. \n\nProovige uuesti <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti.\n\nProovige <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast uuesti."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Olete üritanud <xliff:g id="NUMBER_0">%d</xliff:g> korda tahvelarvutit valesti avada. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset lähtestatakse tahvelarvuti tehase vaikeseadetele ja kõik kasutajaandmed lähevad kaotsi."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Olete üritanud <xliff:g id="NUMBER_0">%d</xliff:g> korda telefoni valesti avada. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset lähtestatakse telefon tehase vaikeseadetele ja kõik kasutajaandmed lähevad kaotsi."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Olete püüdnud tahvelarvutit <xliff:g id="NUMBER">%d</xliff:g> korda valesti avada. Tahvelarvuti lähtestatakse nüüd tehase vaikeseadetele."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Olete püüdnud telefoni <xliff:g id="NUMBER">%d</xliff:g> korda valesti avada. Telefon lähtestatakse nüüd tehase vaikeseadetele."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset palutakse teil tahvelarvuti avada meilikontoga.\n\n Proovige uuesti <xliff:g id="NUMBER_2">%d</xliff:g> sekundi pärast."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset palutakse teil telefon avada meilikontoga.\n\n Proovige uuesti <xliff:g id="NUMBER_2">%d</xliff:g> sekundi pärast."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Eemalda"</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Kas suurendada helitugevust üle soovitatud taseme?\nPikaajaline suure helitugevusega muusika kuulamine võib kahjustada kuulmist."</string>
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Hõlbustuse lubamiseks hoidke kaht sõrme all."</string>
+    <string name="accessibility_enabled" msgid="1381972048564547685">"Hõlbustus on lubatud."</string>
+    <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Hõlbustus on tühistatud."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Praegune kasutaja <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="owner_name" msgid="2716755460376028154">"Omanik"</string>
+    <string name="error_message_title" msgid="4510373083082500195">"Viga"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"See rakendus ei toeta piiratud profiilide kontosid"</string>
+    <string name="app_not_found" msgid="3429141853498927379">"Selle toimingu käsitlemiseks ei leitud ühtegi rakendust"</string>
+    <string name="revoke" msgid="5404479185228271586">"Tühista"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Tühistatud"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Viga sisu kirjutamisel"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"teadmata"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Administraatori PIN-koodi sisestamine"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Sisestage PIN-kood"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Vale"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Praegune PIN-kood"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Uus PIN-kood"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Kinnitage uus PIN-kood"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Looge PIN-kood piirangute muutmiseks"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PIN-kood ei sobi. Proovige uuesti."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"PIN-kood on liiga lühike. Peab olema vähemalt 4-kohaline."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Proovige uuesti 1 sekundi pärast"</item>
+    <item quantity="other" msgid="4730868920742952817">"Proovige uuesti <xliff:g id="COUNT">%d</xliff:g> sekundi pärast"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Proovige hiljem uuesti"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Riba kuvam. pühkige ekraani serva"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Süsteemiriba kuvamiseks pühkige ekraani servast"</string>
+</resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 92a1e93..0694744 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -279,6 +279,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Võimaldab rakendusel teisaldada ülesanded esiplaanile ja taustale. Rakendus võib seda teha teie sisendita."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"käitatud rakenduste peatamine"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Võimaldab rakendusel eemaldada ülesanded ja peatada nende rakendused. Pahatahtlikud rakendused võivad häirida teiste rakenduste käitumist."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"tegevusvirnade haldamine"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Lubab rakendusel lisada, eemaldada ja muuta tegevusvirnasid, kus teised rakendused töötavad. Pahatahtlikud rakendused võivad häirida teiste rakenduste käitumist."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"mis tahes toimingu alustamine"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Võimaldab rakendusel käivitada mis tahes toimingu loa kaitsest või eksporditud olekust sõltumata."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"kuva ühilduvuse seadmine"</string>
@@ -312,7 +314,7 @@
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"väldi rakenduste ümberlülitamist"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Takistab kasutaja lülitumist teisele rakendusele."</string>
     <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"aktiivse rakenduse teabe hankimine"</string>
-    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Lubab õiguste saajal hankida privaatset teavet ekraanil esiplaanil oleva aktiivse rakenduse kohta."</string>
+    <string name="permdesc_getTopActivityInfo" msgid="8153651434145132505">"Lubab õiguse omanikul hankida privaatset teavet ekraani esiplaanil oleva aktiivse rakenduse ja teenuste kohta."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"Kõigi rakenduste käivitumise jälgimine ja juhtimine"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Võimaldab rakendusel jälgida ja juhtida, kuidas süsteem tegevusi käivitab. Pahatahtlikud rakendused võivad süsteemi täielikult rikkuda. Seda õigust on vaja ainult arenduseks, mitte tavakasutuse korral."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"saada paketist eemaldatud saade"</string>
@@ -356,6 +358,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Lubab omanikul siduda sisestusmeetodi ülataseme liidesega. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"sidumine juurdepääsuteenusega"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Lubab omanikul luua sideme juurdepääsuteenuse ülataseme liidesega. Tavarakenduste puhul ei tohiks seda kunagi vaja minna."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"sidumine printimisteenusega"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Lubab omanikul siduda printimisteenuse ülataseme liidesega. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
+    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"juurdepääs kõikidele printimistöödele"</string>
+    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Lubab omanikule juurdepääsu teise rakenduse loodud printimistöödele. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC-teenusega sidumine"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Lubab õiguste omajal luua seosed rakendustega, mis emuleerivad NFC-kaarte. Pole kunagi vajalik tavaliste rakenduste korral."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"tekstiteenusega sidumine"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Võimaldab omanikul siduda tekstiteenuse (nt SpellCheckerService) ülataseme liidesega. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"seo VPN-teenusega"</string>
@@ -366,6 +374,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Lubab omanikul siduda vidina teenuse ülataseme liidesega. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"seadme administraatoriga suhtlemine"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Võimaldab omanikul saata kavatsusi seadme administraatorile. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"seadme administraatori lisamine või eemaldamine"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Võimaldab omanikul lisada või eemaldada aktiivseid seadme administraatoreid. Tavarakenduste puhul ei tohiks see kunagi vajalik olla."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"muuda ekraani paigutust"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Võimaldab rakendusel muuta ekraani pööramist mis tahes ajal. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"kursorikiiruse muutmine"</string>
@@ -397,6 +407,10 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Võimaldab rakendusel lugeda süsteemi erinevaid logifaile. Nii on võimalik avastada üldist teavet selle kohta, mida te telefoniga teete, mis võib kaasata ka isiklikku või privaatset teavet."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"Mis tahes meediumidekooderi kasutamine taasesituseks"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Võimaldab rakendusel taasesituseks kasutada mis tahes installitud meediumidekooderit."</string>
+    <!-- no translation found for permlab_manageCaCertificates (1678391896786882014) -->
+    <skip />
+    <!-- no translation found for permdesc_manageCaCertificates (4015644047196937014) -->
+    <skip />
     <string name="permlab_diagnostic" msgid="8076743953908000342">"loe/kirjuta valija allikaid"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Võimaldab rakendusel lugeda valimisrühma mis tahes ressurssi ja sellesse kirjutada (näiteks kaustas /dev olevad failid). See võib mõjutada süsteemi stabiilsust ja turvet. Seda tohiks kasutada tootja või operaator AINULT riistvaraspetsiifiliseks diagnostikaks."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"Rakenduse komponentide lubamine või keelamine"</string>
@@ -458,10 +472,18 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Võimaldab rakendusel kasutada SurfaceFlingeri madalatasemelisi funktsioone."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"loe kaadripuhvrit"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Võimaldab rakendusel kaadripuhvri sisu lugeda."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"juurdepääs InputFlingerile"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Lubab rakendusel kasutada InputFlingeri madalatasemelisi funktsioone."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"WiFi-ekraanide seadistamine"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Lubab rakendusel seadistada WiFi-ekraane ja nendega ühendus luua."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"WiFi-ekraanide juhtimine"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Lubab rakendusel juhtida WiFi-ekraanide madala taseme funktsioone."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"heliväljundi jäädvustamine"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Lubab rakendusel jäädvustada ja ümber suunata heliväljundit."</string>
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"videoväljundi jäädvustamine"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Lubab rakendusel jäädvustada ja ümber suunata videoväljundit."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"kaitstud videoväljundi jäädvustamine"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Lubab rakendusel jäädvustada ja ümber suunata kaitstud videoväljundit."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"muuda heliseadeid"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Võimaldab rakendusel muuta üldiseid heliseadeid, näiteks helitugevust ja seda, millist kõlarit kasutatakse väljundiks."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"salvesta heli"</string>
@@ -613,6 +635,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Võimaldab rakendusel kirjutada SD-kaardile."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"sisemälu sisu muutm./kustut."</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Võimaldab rakendusel muuta sisemise andmekandja sisu."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"dokumendi talletuse haldamine"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Lubab rakendusel hallata dokumendi talletamist."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"juurdepääs välismäluseadmele (kõikidele kasutajatele)"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Võimaldab rakenduse kõikidel kasutajatel pöörduda välismäluseadme poole."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"juurdepääs vahemälu failisüsteemile"</string>
@@ -625,10 +649,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Võimaldab rakendusel hallata võrgueeskirju ja määratleda rakendusespetsiifilisi reegleid."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"võrgukasutuse arvestamise muutmine"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Võimaldab rakendusel muuta võrgukasutuse loendamist rakenduste suhtes. Mitte kasutada tavarakenduste puhul."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"sokli märkide muutmine"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Lubab rakendusel muuta marsruutimiseks sokli märke"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"juurdepääsu märguanded"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Võimaldab rakendusel tuua, kontrollida ja kustutada märguandeid, sh neid, mille on postitanud teised rakendused."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"seo märguannete kuulamisteenusega"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Võimaldab omanikul siduda märguannete kuulamisteenuse ülemise taseme kasutajaliidese. Seda ei tohiks tavarakenduste puhul kunagi vaja olla."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"operaatoripoolse konfiguratsioonirakenduse aktiveerimine"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Lubab omanikul aktiveerida operaatoripoolse konfiguratsioonirakenduse. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"võrgutingimuste teabe kuulamine"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Lubab rakendusel kuulata võrgutingimuste teavet. Ei ole kunagi vajalik tavaliste rakenduste puhul."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Parooli reeglite määramine"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrollige ekraaniluku avamise paroolide pikkust ja tähemärke."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Ekraani avamiskatsed"</string>
@@ -738,8 +768,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +825,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Sisestage SIM-kaart."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM-kaart puudub või on loetamatu. Sisestage SIM-kaart."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Kasutamiskõlbmatu SIM-kaart."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"SIM-kaart on jäädavalt keelatud."\n" Teise SIM-kaardi saamiseks võtke ühendust oma traadita side teenusepakkujaga."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"SIM-kaart on jäädavalt keelatud.\n Teise SIM-kaardi saamiseks võtke ühendust oma traadita side teenusepakkujaga."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Eelmise loo nupp"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Nupp Järgmine rada"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Nupp Peata"</string>
@@ -808,11 +837,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Vaadake kasutusjuhendit või võtke ühendust klienditeenindusega."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM-kaart on lukus."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM-kaardi avamine ..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Olete oma avamismustrit <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti koostanud. "\n\n"Proovige <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast uuesti."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Olete parooli <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti sisestanud. "\n\n"Proovige <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast uuesti."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Olete PIN-koodi <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti sisestanud. "\n\n"Proovige <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast uuesti."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset palutakse teil tahvelarvuti avada Google\'i sisselogimisega."\n\n" Proovige <xliff:g id="NUMBER_2">%d</xliff:g> sekundi pärast uuesti."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset palutakse teil telefon avada Google\'i sisselogimisega."\n\n" Proovige <xliff:g id="NUMBER_2">%d</xliff:g> sekundi pärast uuesti."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Olete oma avamismustrit <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti koostanud. \n\nProovige <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast uuesti."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Olete parooli <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti sisestanud. \n\nProovige <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast uuesti."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Olete PIN-koodi <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti sisestanud. \n\nProovige <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast uuesti."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset palutakse teil tahvelarvuti avada Google\'i sisselogimisega.\n\n Proovige <xliff:g id="NUMBER_2">%d</xliff:g> sekundi pärast uuesti."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset palutakse teil telefon avada Google\'i sisselogimisega.\n\n Proovige <xliff:g id="NUMBER_2">%d</xliff:g> sekundi pärast uuesti."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Olete üritanud <xliff:g id="NUMBER_0">%d</xliff:g> korda tahvelarvutit valesti avada. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> edutut katset lähtestatakse tahvelarvuti tehase vaikeseadetele ja kõik kasutajaandmed lähevad kaotsi."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Olete üritanud <xliff:g id="NUMBER_0">%d</xliff:g> korda telefoni valesti avada. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset lähtestatakse telefon tehase vaikeseadetele ja kõik kasutajaandmed lähevad kaotsi."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Olete püüdnud tahvelarvutit <xliff:g id="NUMBER">%d</xliff:g> korda valesti avada. Tahvelarvuti lähtestatakse nüüd tehase vaikeseadetele."</string>
@@ -826,7 +855,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Parool"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Logi sisse"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Vale kasutajanimi või parool."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Kas unustasite oma kasutajanime või parooli?"\n"Külastage aadressi "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Kas unustasite oma kasutajanime või parooli?\nKülastage aadressi "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Kontrollimine ..."</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Ava"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Heli sisse"</string>
@@ -874,7 +903,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Navigeerimise kinnitamine"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Lahku sellelt lehelt"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Jää sellele lehele"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Kas soovite kindlasti sellelt lehelt lahkuda?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nKas soovite kindlasti sellelt lehelt lahkuda?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Kinnita"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Vihje: suurendamiseks ja vähendamiseks puudutage kaks korda."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Automaatne täitmine"</string>
@@ -1080,14 +1109,14 @@
     <string name="aerr_application" msgid="932628488013092776">"Kahjuks on rakendus <xliff:g id="APPLICATION">%1$s</xliff:g> peatunud."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Kahjuks on protsess <xliff:g id="PROCESS">%1$s</xliff:g> peatunud."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> ei vasta."\n\n"Kas soovite selle sulgeda?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Tegevus <xliff:g id="ACTIVITY">%1$s</xliff:g> ei vasta."\n\n"Kas soovite selle sulgeda?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> ei vasta.\n\nKas soovite selle sulgeda?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Tegevus <xliff:g id="ACTIVITY">%1$s</xliff:g> ei vasta.\n\nKas soovite selle sulgeda?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> ei vasta. Kas soovite selle sulgeda?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Protsess <xliff:g id="PROCESS">%1$s</xliff:g> ei vasta."\n\n"Kas soovite selle sulgeda?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Protsess <xliff:g id="PROCESS">%1$s</xliff:g> ei vasta.\n\nKas soovite selle sulgeda?"</string>
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"Teata"</string>
     <string name="wait" msgid="7147118217226317732">"Oodake"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"Leht ei reageeri."\n\n"Kas soovite selle sulgeda?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Leht ei reageeri.\n\nKas soovite selle sulgeda?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Rakendus on ümber suunatud"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> on nüüd käivitunud."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"Algselt käivitati rakendus <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
@@ -1256,6 +1285,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Võimaldab rakendusel võtta sisu kopeerimiseks appi vaikekonteinerteenuse. Mitte kasutada tavarakenduste puhul."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Meediaväljundi teekonna koostamine"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Võimaldab rakendusel koostada teekonna meediaväljundist teistesse välistesse seadmetesse."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Juurdepääs võtmekaitsega turvalisele talletusruumile"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Lubab rakendusel hankida juurdepääsu võtmekaitsega turvalisele talletusruumile."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Võtmekaitse kuvamise ja peitmise juhtimine"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Lubab rakendusel võtmekaitset juhtida."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Suumi juhtimiseks puudutage kaks korda"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Vidinat ei saanud lisada."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Mine"</string>
@@ -1265,15 +1298,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Valmis"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Eelm."</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Täida"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Vali number"\n" kasutades numbrit <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Loo kontakt"\n"numbriga <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Vali number\n kasutades numbrit <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Loo kontakt\nnumbriga <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Üks või mitu rakendust taotlevad luba pääseda nüüd ja edaspidi teie kontole juurde."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Kas soovite taotluse lubada?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Juurdepääsutaotlus"</string>
     <string name="allow" msgid="7225948811296386551">"Luba"</string>
     <string name="deny" msgid="2081879885755434506">"Keela"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Taotletud luba"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Luba on taotletud"\n"kontole <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Luba on taotletud\nkontole <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Sisestusmeetod"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Sünkroonimine"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Juurdepääsetavus"</string>
@@ -1441,10 +1474,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Ühendan..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Saadaval"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"Ei ole saadaval"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"Kasutusel"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Sisseehitatud ekraan"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"HDMI-ekraan"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Ülekate nr .<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", turvaline"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Juhtmeta ekraaniühendus on loodud"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Ekraan on näha teises seadmes"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Katkesta ühendus"</string>
@@ -1453,7 +1488,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Vale muster"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Vale parool"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"Vale PIN-kood"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Proovige uuesti <xliff:g id="NUMBER">%d</xliff:g> sekundi pärast."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Proovige uuesti <xliff:g id="NUMBER">%1$d</xliff:g> sekundi pärast."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Joonistage oma muster"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Sisestage SIM-i PIN-kood"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Sisestage PIN-kood"</string>
@@ -1473,27 +1508,81 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Parool"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Logi sisse"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Vale kasutajanimi või parool."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Kas unustasite kasutajanime või parooli?"\n"Külastage aadressi "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Kas unustasite kasutajanime või parooli?\nKülastage aadressi "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Konto kontrollimine ..."</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Olete PIN-koodi <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti sisestanud."\n\n"Proovige <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast uuesti."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Olete parooli <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti sisestanud. "\n\n"Proovige uuesti <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti."\n\n"Proovige <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast uuesti."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Olete PIN-koodi <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti sisestanud.\n\nProovige <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast uuesti."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Olete parooli <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti sisestanud. \n\nProovige uuesti <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti.\n\nProovige <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast uuesti."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Olete üritanud <xliff:g id="NUMBER_0">%d</xliff:g> korda tahvelarvutit valesti avada. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset lähtestatakse tahvelarvuti tehase vaikeseadetele ja kõik kasutajaandmed lähevad kaotsi."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Olete üritanud <xliff:g id="NUMBER_0">%d</xliff:g> korda telefoni valesti avada. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset lähtestatakse telefon tehase vaikeseadetele ja kõik kasutajaandmed lähevad kaotsi."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Olete püüdnud tahvelarvutit <xliff:g id="NUMBER">%d</xliff:g> korda valesti avada. Tahvelarvuti lähtestatakse nüüd tehase vaikeseadetele."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Olete püüdnud telefoni <xliff:g id="NUMBER">%d</xliff:g> korda valesti avada. Telefon lähtestatakse nüüd tehase vaikeseadetele."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset palutakse teil tahvelarvuti avada meilikontoga."\n\n" Proovige uuesti <xliff:g id="NUMBER_2">%d</xliff:g> sekundi pärast."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset palutakse teil telefon avada meilikontoga."\n\n" Proovige uuesti <xliff:g id="NUMBER_2">%d</xliff:g> sekundi pärast."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset palutakse teil tahvelarvuti avada meilikontoga.\n\n Proovige uuesti <xliff:g id="NUMBER_2">%d</xliff:g> sekundi pärast."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset palutakse teil telefon avada meilikontoga.\n\n Proovige uuesti <xliff:g id="NUMBER_2">%d</xliff:g> sekundi pärast."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Eemalda"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Kas suurendada helitugevust üle soovitatud taseme?"\n"Pikaajaline suure helitugevusega muusika kuulamine võib kahjustada kuulmist."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Kas suurendada helitugevust üle soovitatud taseme?\nPikaajaline suure helitugevusega muusika kuulamine võib kahjustada kuulmist."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Hõlbustuse lubamiseks hoidke kaht sõrme all."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Hõlbustus on lubatud."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Hõlbustus on tühistatud."</string>
     <string name="user_switched" msgid="3768006783166984410">"Praegune kasutaja <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Omanik"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Viga"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"See rakendus ei toeta piiratud profiilide kontosid"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"See rakendus ei toeta piiratud profiilide kontosid"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Selle toimingu käsitlemiseks ei leitud ühtegi rakendust"</string>
     <string name="revoke" msgid="5404479185228271586">"Tühista"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Tühistatud"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Viga sisu kirjutamisel"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Sisestage PIN-kood"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Praegune PIN-kood"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Uus PIN-kood"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Kinnitage uus PIN-kood"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Looge PIN-kood piirangute muutmiseks"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PIN-kood ei sobi. Proovige uuesti."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"PIN-kood on liiga lühike. Peab olema vähemalt 4-kohaline."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="4835639969503729874">"Vale PIN-kood. Proovige 1 s pärast."</item>
+    <item quantity="other" msgid="8030607343223287654">"Vale PIN-kood. Proovige <xliff:g id="COUNT">%d</xliff:g> s pärast."</item>
+  </plurals>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Riba kuvam. pühkige ekraani serva"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Süsteemiriba kuvamiseks pühkige ekraani servast"</string>
 </resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 459e1c3..120f3ee 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -131,6 +131,11 @@
     <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="default" msgid="3475999286680000541">"حافظه تلفن پر است. بعضی از فایل‌ها را حذف کنید تا فضا آزاد شود."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"ممکن است شبکه نظارت شده باشد"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"من"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"گزینه‌های رایانهٔ لوحی"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"گزینه‌های تلفن"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"به برنامه اجازه می‎دهد تا کارها را به پیش‌زمینه و پس‌زمینه منتقل کند. برنامه‎ ممکن است بدون دخالت شما این کار را انجام دهد."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"متوقف کردن برنامه‎های در حال اجرا"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"به برنامه اجازه می‎دهد تا کارها را حذف کند و برنامه‎های آن‌ها را متوقف کند. برنامه‎های مخرب می‌توانند در اجرای برنامه‎های دیگر اختلال ایجاد ‎کنند."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"مدیریت پشته‌های فعالیت"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"به برنامه اجازه می‌دهد پشته‌های فعالیتی که سایر برنامه‌ها در آنها اجرا می‌شوند را اضافه یا حذف کند و تغییر دهد. برنامه‌های مخرب ممکن است فعالیت برنامه‌های دیگر را مختل کنند."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"شروع هر نوع فعالیت"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"به برنامه اجازه می‎دهد هر فعالیتی را شروع کند بدون اینکه وضعیت صادرشده یا حفاظت با مجوز در نظر گرفته شود."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"تنظیم سازگاری با صفحهٔ نمایش"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"به دارنده این دستگاه اجازه می‎دهد تا به رابط سطح بالای یک روش ورودی متصل شود. این ویژگی هیچگاه برای برنامه‎های معمولی ضروری نمی‎باشد."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"اتصال به سرویس دسترسی"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"به دارنده اجازه می‌دهد که به رابط سطح بالای سرویس دسترسی متصل شود. هرگز برای برنامه‌های معمولی مورد نیاز نیست."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"اتصال به یک سرویس چاپ"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"به برنامه اجازه می‌دهد که به رابط سطح بالای سرویس چاپ متصل شود. هرگز برای برنامه‌های معمولی مورد نیاز نیست."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"اتصال به سرویس هماهنگ‌کننده چاپ"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"به دارنده اجازه می‌دهد که به واسط سطح بالای سرویس هماهنگ‌کننده چاپ متصل شود. هرگز برای برنامه‌های معمولی مورد نیاز نیست."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"اتصال به سرویس NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"به دارنده اجازه می‌دهد به برنامه‌هایی متصل شود که مشابه با کارت‌های NFC عمل می‌کنند. هرگز نباید برای برنامه‌های عادی مورد نیاز باشد."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"اتصال به یک سرویس متنی"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"به دارنده اجازه می‌دهد خود را به یک رابط سطح بالای خدمات متنی مرتبط کند (برای مثال SpellCheckerService). هرگز برای برنامه‌های عادی لازم نیست."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"اتصال به یک سرویس VPN"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"به دارنده اجازه می‌دهد که به رابط سطح بالای سرویس ابزارک متصل شود. هرگز برای برنامه‌های معمولی مورد نیاز نیست."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"تعامل با یک سرپرست دستگاه"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"به دارنده اجازه می‎دهد اهداف خود را به سرپرست دستگاه ارسال کند. برنامه‎های معمولی هیچگاه به این ویژگی نیازی ندارند."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"اضافه یا حذف سرپرست دستگاه"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"به دارنده اجازه می‌دهد سرپرستان دستگاه فعال را اضافه یا حذف کند.هرگز نباید برای برنامه‌های عادی مورد نیاز باشد."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"تغییر جهت صفحه"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"به برنامه اجازه می‎دهد تا چرخش صفحه را هر وقت بخواهد تغییر دهد. برای برنامه‎های عادی نیاز نیست."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"تغییر سرعت اشاره‌گر"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"به برنامه اجازه می‎دهد تا فایل‌های گزارش مختلف سیستم را بخواند. این کار به برنامه اجازه می‎دهد اطلاعات عمومی کاری که با تلفن انجام می‎دهید مثلا اطلاعات خصوصی و شخصی را کشف کند."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"استفاده از هر رمزگشای رسانه‎ای برای بازپخش"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"اجازه می‎دهد برنامه از هر رمزگشای رسانه نصب شده‌ای استفاده کند تا برای پخش رمزگشایی شود."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"مدیریت اطلاعات کاربری مورد اعتماد"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"به برنامه امکان می‌دهد گواهینامه‌های CA را به عنوان اطلاعات کاربری مورد اعتماد نصب یا حذف نصب کند."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"خواندن/نوشتن منابع متعلق به تشخیص"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"به برنامه اجازه می‌دهد هر منبعی را که متعلق به گروه تشخیص است بخواند و در آن بنویسد؛ به‌عنوان مثال، فایل‌های /dev. این امر به‌صورت بالقوه می‌تواند بر پایدار بودن و امنیت سیستم تأثیر بگذارد. این تنها باید برای تشخیص‎‌های مختص سخت‌افزار توسط تولیدکننده یا اپراتور استفاده شود."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"فعال یا غیر فعال کردن اجزای برنامه"</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"به برنامه اجازه می‌دهد تا اتصال به صفحات نمایش Wi‑Fi را پیکربندی کند."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"کنترل صفحه نمایش‌های Wi‑Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"به برنامه اجازه می‌دهد که ویژگی‌های سطح پایین صفحه‌های نمایش Wi‑Fi را کنترل کند."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"ضبط خروجی صدا"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"به برنامه امکان می‌دهد خروجی صدا را ضبط و هدایت کند."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"ضبط خروجی ویدیو"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"به برنامه امکان می‌دهد خروجی ویدیو را ضبط و هدایت کند."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"ضبط خروجی ویدیوی ایمن"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"به برنامه امکان می‌دهد خروجی ویدیوی ایمن را ضبط و هدایت کند."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"تغییر تنظیمات صوتی"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"به برنامه امکان می‌دهد تنظیمات صوتی کلی مانند میزان صدا و بلندگوی مورد استفاده برای پخش صدا را اصلاح کند."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"ضبط صدا"</string>
@@ -525,6 +552,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"ممانعت از به خواب رفتن تلفن"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"به برنامه اجازه می‎دهد تا از غیرفعال شدن رایانهٔ لوحی جلوگیری کند."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"به برنامه اجازه می‎دهد تا از غیرفعال شدن تلفن جلوگیری کند."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"روشن/خاموش کردن رایانهٔ لوحی"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"روشن/خاموش کردن تلفن"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"به برنامه اجازه می‎دهد رایانهٔ لوحی را روشن یا خاموش کند."</string>
@@ -582,7 +615,7 @@
     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"تغییر وضعیت WiMAX"</string>
     <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"به برنامه امکان می‌دهد رایانهٔ لوحی را به شبکه‌های وایمکس متصل کرده یا اتصال آن را از این شبکه‌ها قطع کند."</string>
     <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"به برنامه امکان می‎دهد تا تلفن را به شبکه‌های وایمکس متصل کرده یا اتصال آنرا از این شبکه‌ها قطع کند."</string>
-    <string name="permlab_bluetooth" msgid="6127769336339276828">"مرتبط‌ سازی با دستگاه‌های بلوتوث"</string>
+    <string name="permlab_bluetooth" msgid="6127769336339276828">"جفت کردن با دستگاه‌های بلوتوث"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"به برنامه اجازه می‎دهد تا پیکربندی بلوتوث در رایانهٔ لوحی را مشاهده کند و اتصال با دستگاه‌های مرتبط را برقرار کرده و بپذیرد."</string>
     <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"به برنامه اجازه می‎دهد تا پیکربندی بلوتوث در تلفن را مشاهده کند، و اتصالات دستگاه‌های مرتبط را برقرار کرده و بپذیرد."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"کنترل ارتباط راه نزدیک"</string>
@@ -613,6 +646,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"به برنامه اجازه می‎دهد تا در کارت SD بنویسد."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"تغییر/حذف محتواهای حافظه رسانه داخلی"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"به برنامه اجازه می‎دهد تا محتویات حافظه رسانه داخلی را تغییر دهد."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"مدیریت فضای ذخیره‌سازی اسناد"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"به برنامه اجازه می‌دهد فضای ذخیره‌سازی اسناد را مدیریت کند."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"دسترسی به دستگاه ذخیره خارجی تمام کاربران"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"به برنامه اجازه می‌دهد به دستگاه ذخیره خارجی برای همه کاربران دسترسی داشته باشد."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"دسترسی به سیستم فایل حافظهٔ پنهان"</string>
@@ -625,10 +660,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"به برنامه اجازه می‎دهد تا خط مشی‎های شبکه را مدیریت کند و قوانین خاص برنامه را تعیین کند."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"اصلاح محاسبه استفاده از شبکه"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"به برنامه اجازه می‎دهد تا نحوه محاسبه کاربرد شبکه در برنامه را تغییر دهد. برای استفاده برنامه‎های عادی نیست."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"تغییر علائم سوکت"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"به برنامه اجازه می‌دهد برای مسیریابی علائم سوکت را تغییر دهد."</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_invokeCarrierSetup" msgid="3699600833975117478">"لغو برنامه پیکربندی ارائه شده توسط شرکت مخابراتی"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"به دارنده اجازه می‌دهد که تنظیمات برنامه شرکت مخابراتی را لغو کند. هرگز برای برنامه‌های معمولی مورد نیاز نیست."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"گوش دادن برای بررسی شرایط شبکه"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"به برنامه امکان می‌دهد برای بررسی شرایط شبکه گوش دهد. این امکان هرگز نباید برای برنامه‌های معمولی مورد نیاز باشد."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"تنظیم قوانین رمز ورود"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"طول و نویسه‎های مجاز در گذرواژه‌های بازکردن قفل صفحه را کنترل کنید."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"نمایش تلاش‌های قفل گشایی صفحه"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +836,7 @@
     <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="201594905152746886">"دکمه تراک قبلی"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"دکمه تراک بعدی"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"دکمه مکث"</string>
@@ -808,11 +848,11 @@
     <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">%d</xliff:g> بار اشتباه کشیده‎اید. "\n\n"لطفاً پس از <xliff:g id="NUMBER_1">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"گذرواژهٔ خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه تایپ کرده‌اید. "\n\n"پس از <xliff:g id="NUMBER_1">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"پین را<xliff:g id="NUMBER_0">%d</xliff:g>  بار اشتباه تایپ کرده‎اید. "\n\n"پس از <xliff:g id="NUMBER_1">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"شما الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه کشیده‎اید. بعد از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق، از شما خواسته می‎شود که برای بازگشایی قفل رایانهٔ لوحی خود به Google وارد شوید."\n\n" لطفاً پس از <xliff:g id="NUMBER_2">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"شما الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه کشیده‌اید. پس از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق دیگر از شما خواسته می‎شود که برای بازگشایی قفل گوشی خود به برنامهٔ Google وارد شوید."\n\n" لطفاً پس از <xliff:g id="NUMBER_2">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه کشیده‎اید. \n\nلطفاً پس از <xliff:g id="NUMBER_1">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"گذرواژهٔ خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه تایپ کرده‌اید. \n\nپس از <xliff:g id="NUMBER_1">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"پین را<xliff:g id="NUMBER_0">%d</xliff:g>  بار اشتباه تایپ کرده‎اید. \n\nپس از <xliff:g id="NUMBER_1">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"شما الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه کشیده‎اید. بعد از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق، از شما خواسته می‎شود که برای بازگشایی قفل رایانهٔ لوحی خود به Google وارد شوید.\n\n لطفاً پس از <xliff:g id="NUMBER_2">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"شما الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه کشیده‌اید. پس از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق دیگر از شما خواسته می‎شود که برای بازگشایی قفل گوشی خود به برنامهٔ Google وارد شوید.\n\n لطفاً پس از <xliff:g id="NUMBER_2">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"شما به اشتباه <xliff:g id="NUMBER_0">%d</xliff:g> بار اقدام به باز کردن قفل رایانهٔ لوحی کرده‌اید. پس از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق دیگر، رایانهٔ لوحی به پیش‌فرض کارخانه بازنشانی می‌شود و تمام داده‌های کاربر از دست خواهد رفت."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"شما به اشتباه <xliff:g id="NUMBER_0">%d</xliff:g> بار اقدام به باز کردن قفل تلفن کرده‌اید. پس از<xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق دیگر، تلفن به پیش‌فرض کارخانه بازنشانی می‌شود و تمام داده‌های کاربر از دست خواهد رفت."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"شما به اشتباه اقدام به باز کردن قفل <xliff:g id="NUMBER">%d</xliff:g> رایانهٔ لوحی کرده‌اید. رایانهٔ لوحی در حال حاضر به پیش‌فرض کارخانه بازنشانی می‌شود."</string>
@@ -826,7 +866,7 @@
     <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_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>
@@ -874,7 +914,7 @@
     <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="autofill_this_form" msgid="4616758841157816676">"تکمیل خودکار"</string>
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"متأسفانه، <xliff:g id="APPLICATION">%1$s</xliff:g> متوقف شده است."</string>
     <string name="aerr_process" msgid="4507058997035697579">"متأسفانه، پردازش <xliff:g id="PROCESS">%1$s</xliff:g> متوقف شده است."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> پاسخ نمی‎دهد."\n\n"آیا می‎خواهید آنرا ببندید؟"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"فعالیت <xliff:g id="ACTIVITY">%1$s</xliff:g> پاسخ نمی‎دهد."\n\n"آیا می‎خواهید آن را ببندید؟"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> پاسخ نمی‎دهد.\n\nآیا می‎خواهید آنرا ببندید؟"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"فعالیت <xliff:g id="ACTIVITY">%1$s</xliff:g> پاسخ نمی‎دهد.\n\nآیا می‎خواهید آن را ببندید؟"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> پاسخ نمی‎دهد. آیا می‎خواهید آن را ببندید؟"</string>
-    <string name="anr_process" msgid="6513209874880517125">"روند <xliff:g id="PROCESS">%1$s</xliff:g> پاسخ نمی‎دهد. "\n\n"آیا می‎خواهید آن را ببندید؟"</string>
+    <string name="anr_process" msgid="6513209874880517125">"روند <xliff:g id="PROCESS">%1$s</xliff:g> پاسخ نمی‎دهد. \n\nآیا می‎خواهید آن را ببندید؟"</string>
     <string name="force_close" msgid="8346072094521265605">"تأیید"</string>
     <string name="report" msgid="4060218260984795706">"گزارش"</string>
     <string name="wait" msgid="7147118217226317732">"منتظر بمانید"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"این صفحه پاسخ نمی‌دهد."\n\n"آیا می‌خواهید آن را ببندید؟"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"این صفحه پاسخ نمی‌دهد.\n\nآیا می‌خواهید آن را ببندید؟"</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>
@@ -1256,6 +1296,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"به برنامه اجازه می‎دهد تا سرویس پیش‌فرض را فراخوانی کند و محتوا را کپی کند. برای استفاده برنامه‎های عادی مورد نیاز نیست."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"تعیین مسیر خروجی رسانه"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"به یک برنامه اجازه می‌دهد خروجی رسانه را به دستگاه‌های خارجی دیگر تعیین مسیر کند."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"دسترسی به فضای ذخیره‌سازی ایمن محافظ کلید"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"به یک برنامه کاربردی برای دسترسی به فضای ذخیره‌سازی ایمن محافظ کلید اجازه می‌دهد."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"کنترل نمایش و پنهان کردن محافظ کلید"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"اجازه می‌دهد برنامه‌ای محافظ کلید را کنترل کند."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"دوبار لمس کنید تا بزرگنمایی کنترل شود"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"افزودن ابزارک انجام نشد."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"برو"</string>
@@ -1265,15 +1309,15 @@
     <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">"شماره گیری "\n"با استفاده از <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"ایجاد مخاطب"\n"با استفاده از <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"شماره گیری \nبا استفاده از <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"ایجاد مخاطب\nبا استفاده از <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"یک یا چند برنامه زیر برای دسترسی به حساب شما در زمان حال و آینده درخواست مجوز کرده‌اند."</string>
     <string name="grant_credentials_permission_message_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">"مجوز"\n"برای حساب <xliff:g id="ACCOUNT">%s</xliff:g> درخواست شد."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"مجوز\nبرای حساب <xliff:g id="ACCOUNT">%s</xliff:g> درخواست شد."</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>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"مشاهدهٔ همه"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"انتخاب فعالیت"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"اشتراک‌گذاری با"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"دستگاه قفل است."</string>
     <string name="list_delimeter" msgid="3975117572185494152">"، "</string>
     <string name="sending" msgid="3245653681008218030">"در حال ارسال..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"مرورگر راه‌اندازی شود؟"</string>
@@ -1441,10 +1484,12 @@
     <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>
+    <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_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="wifi_display_notification_title" msgid="2223050649240326557">"نمایشگر بی‌سیم متصل است"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"این صفحه در حال نمایش در دستگاه دیگری است"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"قطع اتصال"</string>
@@ -1453,7 +1498,7 @@
     <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_too_many_failed_attempts_countdown" msgid="6358110221603297548">"پس از <xliff:g id="NUMBER">%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">"پین سیم کارت را وارد کنید"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"پین را وارد کنید"</string>
@@ -1473,27 +1518,85 @@
     <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_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">%d</xliff:g> بار اشتباه تایپ کردید. "\n\n"پس از <xliff:g id="NUMBER_1">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"گذرواژه خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه تایپ کردید. "\n\n"پس از <xliff:g id="NUMBER_1">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه کشیدید. "\n\n"لطفاً پس از <xliff:g id="NUMBER_1">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"پین خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه تایپ کردید. \n\nپس از <xliff:g id="NUMBER_1">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"گذرواژه خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه تایپ کردید. \n\nپس از <xliff:g id="NUMBER_1">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه کشیدید. \n\nلطفاً پس از <xliff:g id="NUMBER_1">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"شما به اشتباه <xliff:g id="NUMBER_0">%d</xliff:g> بار اقدام به باز کردن قفل رایانه لوحی کرده‌اید. پس از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق دیگر، رایانهٔ لوحی به پیش‌فرض کارخانه بازنشانی می‌شود و تمام داده‌های کاربر از دست خواهد رفت."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"شما به اشتباه <xliff:g id="NUMBER_0">%d</xliff:g> بار اقدام به باز کردن قفل تلفن کرده‌اید. پس از <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> بار اشتباه کشیده‎اید. بعد از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق، از شما خواسته می‎شود که با استفاده از یک حساب ایمیل قفل رایانه لوحی خود را باز کنید."\n\n" لطفاً پس از <xliff:g id="NUMBER_2">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"شما الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه کشیده‌اید. پس از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق، از شما خواسته می‎شود که با استفاده از یک حساب ایمیل قفل تلفن خود را باز کنید."\n\n" لطفاً پس از <xliff:g id="NUMBER_2">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"شما الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه کشیده‎اید. بعد از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق، از شما خواسته می‎شود که با استفاده از یک حساب ایمیل قفل رایانه لوحی خود را باز کنید.\n\n لطفاً پس از <xliff:g id="NUMBER_2">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"شما الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه کشیده‌اید. پس از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق، از شما خواسته می‎شود که با استفاده از یک حساب ایمیل قفل تلفن خود را باز کنید.\n\n لطفاً پس از <xliff:g id="NUMBER_2">%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="7324161939475478066">"صدا به بالاتر از سطح توصیه شده افزایش یابد؟"\n"گوش دادن به صدای بلند برای مدت طولانی می‌تواند به شنوایی شما آسیب برساند."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"صدا به بالاتر از سطح توصیه شده افزایش یابد؟\nگوش دادن به صدای بلند برای مدت طولانی می‌تواند به شنوایی شما آسیب برساند."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"برای فعال کردن قابلیت دسترسی، با دو انگشت خود همچنان به طرف پایین فشار دهید."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"قابلیت دسترسی فعال شد."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"قابلیت دسترسی لغو شد."</string>
     <string name="user_switched" msgid="3768006783166984410">"کاربر کنونی <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="app_no_restricted_accounts" msgid="4011285085817350390">"این برنامه از حساب‌های متعلق به نمایه‌های محدود پشتیبانی نمی‌کند"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"این برنامه از حساب‌های متعلق به نمایه‌های محدود پشتیبانی نمی‌کند"</string>
     <string name="app_not_found" msgid="3429141853498927379">"برنامه‌ای برای انجام این عملکرد موجود نیست"</string>
     <string name="revoke" msgid="5404479185228271586">"لغو"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"لغو شد"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"خطا هنگام نوشتن محتوا"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"نامعلوم"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"پین سرپرست را وارد کنید"</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>
+    <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">"یک پین برای تغییر محدودیت‌ها ایجاد کنید"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"پین‌ها مطابقت ندارند. دوباره امتحان کنید."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"پین بیش از حد کوتاه است. باید حداقل ۴ رقم باشد."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"امتحان پس از ۱ ثانیه"</item>
+    <item quantity="other" msgid="4730868920742952817">"امتحان پس از <xliff:g id="COUNT">%d</xliff:g> ثانیه"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"بعداً دوباره امتحان کنید"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"کشیدن از لبه صفحه برای نمایش نوار"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"برای نمایش نوار سیستم، انگشت خود را از لبه‌ صفحه به داخل بکشید"</string>
 </resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 9740070..98faa98 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -131,6 +131,11 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Liikaa <xliff:g id="CONTENT_TYPE">%s</xliff:g>-poistoja."</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Tablet-laitteen tallennustila on täynnä. Vapauta tilaa poistamalla tiedostoja."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Puhelimen tallennustila on täynnä. Vapauta tilaa poistamalla tiedostoja."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Verkkoa saatetaan valvoa"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Minä"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Tablet-laitteen asetukset"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Puhelimen asetukset"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Antaa sovelluksen siirtää tehtäviä etualalle ja taustalle. Sovellus ei tarvitse toimiin käyttäjän lupaa."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"käynnissä olevien sovellusten pysäyttäminen"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Antaa sovelluksen poistaa tehtäviä ja lopettaa niiden sovelluksia. Haitalliset sovellukset voivat häiritä muiden sovellusten toimintaa."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"Toimintapinojen hallinta"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Antaa sovelluksen lisätä, poistaa ja muokata niitä toimintapinoja, joissa muut sovellukset suoritetaan. Haitalliset sovellukset voivat häiritä muiden sovellusten toimintaa."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"käynnistä mikä tahansa toiminto"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Antaa sovelluksen käynnistää minkä tahansa toiminnon käyttölupasuojauksesta tai viennin tilasta huolimatta."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"aseta näytön yhteensopivuus"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Antaa sovelluksen sitoutua syötetavan ylätason käyttöliittymään. Ei tavallisten sovellusten käyttöön."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"sitoudu esteettömyyspalveluun"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Antaa sovelluksen sitoutua esteettömyyspalvelun ylemmän tason käyttöliittymään. Ei tavallisten sovelluksien käyttöön."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"Tulostuspalveluun sitoutuminen"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Antaa sovelluksen sitoutua tulostuspalvelun ylemmän tason käyttöliittymään. Ei tavallisten sovelluksien käyttöön."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"tulostuspalveluun sitoutuminen"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Antaa sovelluksen sitoutua tulostuspalvelun ylemmän tason käyttöliittymään. Ei tavallisten sovelluksien käyttöön."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"luo sidos NFC-palveluun"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Sallii oikeuden haltijan luoda sidoksia sovelluksiin, jotka jäljittelevät NFC-kortteja. Tämän ei pitäisi olla tarpeen tavallisille sovelluksille."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"tekstipalveluun sitoutuminen"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Antaa sovelluksen sitoutua tekstipalvelun (kuten SpellCheckerServicen) ylätason liittymään. Ei tavallisten sovellusten käyttöön."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"sitoudu VPN-palveluun"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Antaa sovelluksen sitoutua widget-palvelun ylemmän tason käyttöliittymään. Ei tavallisten sovelluksien käyttöön."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"kommunikoi laitteen järjestelmänvalvojan kanssa"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Antaa sovelluksen lähettää aikomuksia laitteen järjestelmänvalvojalle. Ei tavallisten sovellusten käyttöön."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"lisää tai poista laitteen järjestelmänvalvoja"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Haltija voi lisätä tai poistaa aktiivisen laitteen järjestelmänvalvojia. Tätä ei pitäisi tarvita tavallisille sovelluksille."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"muuta näytön suuntaa"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Antaa sovelluksen muuttaa näytön kiertoa milloin tahansa. Ei tavallisten sovellusten käyttöön."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"muuta osoittimen nopeutta"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Antaa sovelluksen lukea järjestelmän lokitiedostoja. Näin sovellus saa yleisiä tietoja siitä, mitä teet puhelimella, sekä mahdollisia yksityisiä tai arkaluonteisia tietoja."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"käytä mitä tahansa tietovälineen koodin purkajaa toistoa varten"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Sallii sovelluksen käyttää mitä tahansa asennettua tietovälineen koodin purkajaa toistoa varten."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"hallinnoi luotettavia varmenteita"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Antaa sovellukselle luvan asentaa ja poistaa luotettavia CA-varmenteita."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"lue diag:in omistamia resursseja / kirjoita resursseihin"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Antaa sovelluksen lukea ja kirjoittaa diag-ryhmän omistamiin resursseihin, esimerkiksi /dev-hakemistossa oleviin tiedostoihin. Tämä voi vaikuttaa järjestelmän vakauteen ja turvallisuuteen. Tämä lupa tulee myöntää VAIN valmistajan tai operaattorin laitteistotesteille."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"sovelluskomponenttien ottaminen käyttöön tai pois käytöstä"</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Antaa sovelluksen määrittää wifi-näyttöjä ja muodostaa yhteyden niihin."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"hallitse wifi-näyttöjä"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Antaa sovelluksen hallita wifi-näyttöjen matalan tason ominaisuuksia."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"äänentoiston kaappaus"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Antaa sovellukselle luvan äänentoiston kaappaamiseen ja uudelleenohjaamiseen."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"videokuvan kaappaus"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Antaa sovellukselle luvan videokuvan kaappaamiseen ja uudelleenohjaamiseen"</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"suojatun videokuvan kaappaus"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Antaa sovellukselle luvan suojatun videokuvan kaappaamiseen ja uudelleenohjaamiseen."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"muuta ääniasetuksia"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Antaa sovelluksen muokata yleisiä ääniasetuksia, kuten äänenvoimakkuutta ja käytettävää kaiutinta."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"tallentaa ääntä"</string>
@@ -525,6 +552,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"estä puhelinta menemästä virransäästötilaan"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Antaa sovelluksen estää tablet-laitetta siirtymästä virransäästötilaan."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Antaa sovelluksen estää puhelinta siirtymästä virransäästötilaan."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"käynnistä tai sammuta tablet-laite"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"sammutta tai käynnistä puhelin"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Antaa sovelluksen sammuttaa tai käynnistää tablet-laitteen."</string>
@@ -613,6 +646,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Antaa sovelluksen kirjoittaa SD-kortille."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"muokkaa/poista sisäisen säilytystilan sisältöä"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Antaa sovelluksen muokata sisäisen tallennustilan sisältöä."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"hallinnoi dokum. tallennusta"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Antaa sovelluksen hallinnoida dokumenttien tallennusta."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"käyttää kaikkien käyttäjien ulk. tallennustilaa"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Sallii sovelluksen käyttää ulkoista tallennustilaa kaikille käyttäjille."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"käytä välimuistin tiedostojärjestelmää"</string>
@@ -625,10 +660,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Sallii sovelluksen hallinnoida verkkokäytäntöjä ja määritellä sovelluskohtaisia sääntöjä."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"verkon käytön seurannan muokkaaminen"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Antaa sovelluksen muokata, miten sovellusten verkonkäyttöä lasketaan. Ei tavallisten sovellusten käyttöön."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"Pistokemerkkien muokkaaminen"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Antaa sovelluksen muokata reitityksen pistokemerkkejä"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"käytä ilmoituksia"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Antaa sovelluksen noutaa, tutkia ja tyhjentää ilmoituksia (myös muiden sovelluksien lähettämiä)."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"sido ilmoituskuuntelijapalveluun"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Antaa sovelluksen sitoutua ilmoituskuuntelijan ylimmän tason käyttöliittymään. Ei tavallisten sovelluksien käyttöön."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"Palveluntarjoajan määrityssovelluksen käynnistäminen"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Antaa luvanhaltijan käynnistää palveluntarjoajan määrityssovelluksen. Ei tavallisten sovelluksien käyttöön."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"verkon tilahavaintojen kuunteleminen"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Antaa sovellukselle luvan kuunnella verkon tilahavaintoja. Ei tavallisten sovellusten käyttöön."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Aseta salasanasäännöt"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Hallinnoi ruudun lukituksenpoistosalasanoissa sallittuja merkkejä ja salasanan pituutta."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Tarkkaile ruudun lukituksen poistoyrityksiä"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +836,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Aseta SIM-kortti."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM-korttia ei löydy tai ei voi lukea. Kytke SIM-kortti."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"SIM-kortti ei kelpaa."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"SIM-kortti on poistettu pysyvästi käytöstä."\n" Ota yhteyttä operaattoriisi ja hanki uusi SIM-kortti."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"SIM-kortti on poistettu pysyvästi käytöstä.\n Ota yhteyttä operaattoriisi ja hanki uusi SIM-kortti."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Edellinen kappale -painike"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Seuraava kappale -painike"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Tauko-painike"</string>
@@ -808,11 +848,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Katso ohjeita käyttöoppaasta tai ota yhteyttä asiakaspalveluun."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM-kortti on lukittu."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM-kortin lukitusta poistetaan…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Olet piirtänyt lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. "\n\n"Yritä uudelleen <xliff:g id="NUMBER_1">%d</xliff:g> sekunnin kuluttua."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Olet kirjoittanut salasanan väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. "\n\n"Yritä uudelleen <xliff:g id="NUMBER_1">%d</xliff:g> sekunnin kuluttua."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Olet kirjoittanut PIN-koodin väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. "\n\n"Yritä uudelleen <xliff:g id="NUMBER_1">%d</xliff:g> sekunnin kuluttua."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%d</xliff:g> kertaa, sinua pyydetään poistamaan tablet-laitteesi lukitus Google-sisäänkirjautumisen avulla."\n\n" Yritä uudelleen <xliff:g id="NUMBER_2">%d</xliff:g> sekunnin kuluttua."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%d</xliff:g> kertaa, sinua pyydetään poistamaan puhelimesi lukitus Google-sisäänkirjautumisen avulla."\n\n" Yritä uudelleen <xliff:g id="NUMBER_2">%d</xliff:g> sekunnin kuluttua."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Olet piirtänyt lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. \n\nYritä uudelleen <xliff:g id="NUMBER_1">%d</xliff:g> sekunnin kuluttua."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Olet kirjoittanut salasanan väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. \n\nYritä uudelleen <xliff:g id="NUMBER_1">%d</xliff:g> sekunnin kuluttua."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Olet kirjoittanut PIN-koodin väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. \n\nYritä uudelleen <xliff:g id="NUMBER_1">%d</xliff:g> sekunnin kuluttua."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%d</xliff:g> kertaa, sinua pyydetään poistamaan tablet-laitteesi lukitus Google-sisäänkirjautumisen avulla.\n\n Yritä uudelleen <xliff:g id="NUMBER_2">%d</xliff:g> sekunnin kuluttua."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%d</xliff:g> kertaa, sinua pyydetään poistamaan puhelimesi lukitus Google-sisäänkirjautumisen avulla.\n\n Yritä uudelleen <xliff:g id="NUMBER_2">%d</xliff:g> sekunnin kuluttua."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Tablet-laitteen lukituksen poisto epäonnistui <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos teet vielä <xliff:g id="NUMBER_1">%d</xliff:g> epäonnistunutta yritystä, tablet-laitteeseen palautetaan tehdasasetukset ja kaikki käyttäjätiedot häviävät."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Puhelimen lukituksen poisto epäonnistui <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos teet vielä <xliff:g id="NUMBER_1">%d</xliff:g> epäonnistunutta yritystä, puhelimeen palautetaan tehdasasetukset ja kaikki käyttäjätiedot häviävät."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Tablet-laitteen lukituksen poisto epäonnistui <xliff:g id="NUMBER">%d</xliff:g> kertaa. Laitteeseen palautetaan nyt tehdasasetukset."</string>
@@ -826,7 +866,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Salasana"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Kirjaudu sisään"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Virheellinen käyttäjänimi tai salasana."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Unohditko käyttäjänimesi tai salasanasi?"\n"Käy osoitteessa "<b>"google.com/accounts/recovery"</b></string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Unohditko käyttäjänimesi tai salasanasi?\nKäy osoitteessa "<b>"google.com/accounts/recovery"</b></string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Tarkistetaan..."</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Poista lukitus"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Ääni käytössä"</string>
@@ -874,7 +914,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Vahvista siirtyminen"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Poistu tältä sivulta"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Pysy tällä sivulla"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Haluatko varmasti siirtyä pois tältä sivulta?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nHaluatko varmasti siirtyä pois tältä sivulta?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Vahvista"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Vinkki: lähennä ja loitonna kaksoisnapauttamalla."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Aut. täyttö"</string>
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"<xliff:g id="APPLICATION">%1$s</xliff:g> on pysähtynyt."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Prosessi <xliff:g id="PROCESS">%1$s</xliff:g> on pysähtynyt."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> ei vastaa."\n\n"Haluatko sulkea sen?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Toiminto <xliff:g id="ACTIVITY">%1$s</xliff:g> ei vastaa."\n\n"Haluatko sulkea sen?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> ei vastaa.\n\nHaluatko sulkea sen?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Toiminto <xliff:g id="ACTIVITY">%1$s</xliff:g> ei vastaa.\n\nHaluatko sulkea sen?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> ei vastaa. Haluatko sulkea sen?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Prosessi <xliff:g id="PROCESS">%1$s</xliff:g> ei vastaa."\n\n"Haluatko sulkea sen?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Prosessi <xliff:g id="PROCESS">%1$s</xliff:g> ei vastaa.\n\nHaluatko sulkea sen?"</string>
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"Ilmoita"</string>
     <string name="wait" msgid="7147118217226317732">"Odota"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"Sivu ei vastaa."\n\n"Haluatko sulkea sen?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Sivu ei vastaa.\n\nHaluatko sulkea sen?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Sovelluksen uud.ohjaus"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> on nyt käynnissä."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> käynnistettiin alun perin."</string>
@@ -1256,6 +1296,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Antaa sovelluksen kutsua oletussäilöpalvelua sisällön kopioimiseen. Ei tavallisten sovellusten käyttöön."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Median reititys"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Antaa sovelluksen reitittää mediaa muihin ulkoisiin laitteisiin."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Salasanalla suojatun tallennustilan hallinta"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Sallii sovelluksen käyttää salasanalla suojattua tallennustilaa."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Hallinnoi näppäinvahdin näyttämistä ja piilottamista"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Antaa sovelluksen hallita näppäinvahtia."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Ohjaa zoomausta napauttamalla kahdesti"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Widgetin lisääminen epäonnistui."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Siirry"</string>
@@ -1265,15 +1309,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Valmis"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Edell."</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Suorita"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Valitse numero"\n" <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Luo yhteystieto"\n"käyttäen numeroa <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Valitse numero\n <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Luo yhteystieto\nkäyttäen numeroa <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Seuraavat sovellukset pyytävät lupaa käyttää tiliäsi nyt ja tulevaisuudessa."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Sallitko tämän pyynnön?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Käyttöoikeuspyyntö"</string>
     <string name="allow" msgid="7225948811296386551">"Salli"</string>
     <string name="deny" msgid="2081879885755434506">"Kiellä"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Lupa pyydetty"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Pyydetään lupaa"\n"tilille <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Pyydetään lupaa\ntilille <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Syöttötapa"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Synkronointi"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Esteettömyys"</string>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Näytä kaikki"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Valitse toiminto"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Jaa seuraavien kanssa"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Laite lukittu."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Lähetetään…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Käynnistetäänkö selain?"</string>
@@ -1441,10 +1484,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Yhdistetään..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Käytettävissä"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"Ei käytettävissä"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"Käytössä"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Yhdysrakenteinen näyttö"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"HDMI-ruutu"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Peittokuva # <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", suojattu"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Langaton näyttö on yhdistetty"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Tämä ruutu näkyy toisella laitteella"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Katkaise yhteys"</string>
@@ -1453,7 +1498,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Väärä kuvio"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Väärä salasana"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"Väärä PIN-koodi"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Yritä uudelleen <xliff:g id="NUMBER">%d</xliff:g> sekunnin kuluttua."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Yritä uudelleen <xliff:g id="NUMBER">%1$d</xliff:g> sekunnin kuluttua."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Piirrä kuvio"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Anna SIM-kortin PIN-koodi"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Anna PIN-koodi"</string>
@@ -1473,27 +1518,85 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Salasana"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Kirjaudu sisään"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Virheellinen käyttäjänimi tai salasana."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Unohditko käyttäjänimesi tai salasanasi?"\n"Käy osoitteessa "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Unohditko käyttäjänimesi tai salasanasi?\nKäy osoitteessa "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Tarkistetaan tiliä..."</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Olet kirjoittanut PIN-koodin väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. "\n\n"Yritä uudelleen <xliff:g id="NUMBER_1">%d</xliff:g> sekunnin kuluttua."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Olet kirjoittanut salasanan väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. "\n\n"Yritä uudelleen <xliff:g id="NUMBER_1">%d</xliff:g> sekunnin kuluttua."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Olet piirtänyt lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. "\n\n"Yritä uudelleen <xliff:g id="NUMBER_1">%d</xliff:g> sekunnin kuluttua."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Olet kirjoittanut PIN-koodin väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. \n\nYritä uudelleen <xliff:g id="NUMBER_1">%d</xliff:g> sekunnin kuluttua."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Olet kirjoittanut salasanan väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. \n\nYritä uudelleen <xliff:g id="NUMBER_1">%d</xliff:g> sekunnin kuluttua."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Olet piirtänyt lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. \n\nYritä uudelleen <xliff:g id="NUMBER_1">%d</xliff:g> sekunnin kuluttua."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tablet-laitteen lukituksen poisto epäonnistui <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos teet vielä <xliff:g id="NUMBER_1">%d</xliff:g> epäonnistunutta yritystä, tablet-laitteeseen palautetaan tehdasasetukset ja kaikki käyttäjätiedot häviävät."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Puhelimen lukituksen poisto epäonnistui <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos teet vielä <xliff:g id="NUMBER_1">%d</xliff:g> epäonnistunutta yritystä, puhelimeen palautetaan tehdasasetukset ja kaikki käyttäjätiedot häviävät."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Tablet-laitteen lukituksen poisto epäonnistui <xliff:g id="NUMBER">%d</xliff:g> kertaa. Laitteeseen palautetaan nyt tehdasasetukset."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Puhelimen lukituksen poisto epäonnistui <xliff:g id="NUMBER">%d</xliff:g> kertaa. Puhelimeen palautetaan nyt tehdasasetukset."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%d</xliff:g> kertaa, sinua pyydetään poistamaan tablet-laitteesi lukitus sähköpostitilin avulla."\n\n" Yritä uudelleen <xliff:g id="NUMBER_2">%d</xliff:g> sekunnin kuluttua."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%d</xliff:g> kertaa, sinua pyydetään poistamaan puhelimesi lukitus sähköpostitilin avulla."\n\n" Yritä uudelleen <xliff:g id="NUMBER_2">%d</xliff:g> sekunnin kuluttua."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%d</xliff:g> kertaa, sinua pyydetään poistamaan tablet-laitteesi lukitus sähköpostitilin avulla.\n\n Yritä uudelleen <xliff:g id="NUMBER_2">%d</xliff:g> sekunnin kuluttua."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%d</xliff:g> kertaa, sinua pyydetään poistamaan puhelimesi lukitus sähköpostitilin avulla.\n\n Yritä uudelleen <xliff:g id="NUMBER_2">%d</xliff:g> sekunnin kuluttua."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Poista"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Nostetaanko äänenvoimakkuus suositeltua tasoa voimakkaammaksi?"\n"Jos kuuntelet suurella äänenvoimakkuudella pitkiä aikoja, kuulosi voi vahingoittua."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Nostetaanko äänenvoimakkuus suositeltua tasoa voimakkaammaksi?\nJos kuuntelet suurella äänenvoimakkuudella pitkiä aikoja, kuulosi voi vahingoittua."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Ota esteettömyystila käyttöön koskettamalla pitkään kahdella sormella."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Esteettömyystila käytössä."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Esteettömyystila peruutettu."</string>
     <string name="user_switched" msgid="3768006783166984410">"Nykyinen käyttäjä: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Omistaja"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Virhe"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Tämä sovellus ei tue rajoitettujen profiilien tilejä"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Tämä sovellus ei tue rajoitettujen profiilien tilejä"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Tätä toimintoa käsittelevää sovellusta ei löydy"</string>
     <string name="revoke" msgid="5404479185228271586">"Peruuta"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Peruutettu"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Sisällön kirjoittamisessa tapahtui virhe"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"tuntematon"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Anna järjestelmänvalvojan PIN-koodi"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Anna PIN-koodi"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Virheellinen"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Nykyinen PIN-koodi"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Uusi PIN-koodi"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Vahvista uusi PIN-koodi"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Luo uusi PIN-koodi rajoitusten muokkaamista varten"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PIN-koodit eivät vastaa toisiaan. Yritä uudelleen."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"PIN-koodi on liian lyhyt. Vähimmäispituus on neljä merkkiä."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Yritä uud. 1 s kul."</item>
+    <item quantity="other" msgid="4730868920742952817">"Yritä uud. <xliff:g id="COUNT">%d</xliff:g> s kul."</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Yritä myöhemmin uudelleen"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Näytä palkki liu\'uttamalla reunasta"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Tuo järjestelmäpalkki näkyviin liu\'uttamalla ruudun reunasta"</string>
 </resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..832a34e
--- /dev/null
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -0,0 +1,1597 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<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="5973789783504771878">"Ko"</string>
+    <string name="megabyteShort" msgid="6355851576770428922">"Mo"</string>
+    <string name="gigabyteShort" msgid="3259882455212193214">"Go"</string>
+    <string name="terabyteShort" msgid="231613018159186962">"To"</string>
+    <string name="petabyteShort" msgid="5637816680144990219">"Po"</string>
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
+    <string name="untitled" msgid="4638956954852782576">"&lt;Sans_titre&gt;"</string>
+    <string name="ellipsis" msgid="7899829516048813237">"..."</string>
+    <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
+    <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Aucun numéro de téléphone)"</string>
+    <string name="unknownName" msgid="2277556546742746522">"(Inconnu)"</string>
+    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Messagerie vocale"</string>
+    <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
+    <string name="mmiError" msgid="5154499457739052907">"Problème de connexion ou code IHM incorrect"</string>
+    <string name="mmiFdnError" msgid="5224398216385316471">"Opération réservée aux numéros autorisés"</string>
+    <string name="serviceEnabled" msgid="8147278346414714315">"Le service a été activé."</string>
+    <string name="serviceEnabledFor" msgid="6856228140453471041">"Ce service a été activé pour :"</string>
+    <string name="serviceDisabled" msgid="1937553226592516411">"Ce service a été désactivé."</string>
+    <string name="serviceRegistered" msgid="6275019082598102493">"Enregistrement réussi"</string>
+    <string name="serviceErased" msgid="1288584695297200972">"Effacement réussi."</string>
+    <string name="passwordIncorrect" msgid="7612208839450128715">"Mot de passe incorrect"</string>
+    <string name="mmiComplete" msgid="8232527495411698359">"IHM terminée."</string>
+    <string name="badPin" msgid="9015277645546710014">"L\'ancien NIP saisi est incorrect."</string>
+    <string name="badPuk" msgid="5487257647081132201">"La clé PUK saisie est incorrecte."</string>
+    <string name="mismatchPin" msgid="609379054496863419">"Les NIP saisis ne correspondent pas."</string>
+    <string name="invalidPin" msgid="3850018445187475377">"Veuillez saisir un NIP comprenant entre quatre et huit chiffres."</string>
+    <string name="invalidPuk" msgid="8761456210898036513">"Veuillez saisir une clé PUK comportant au moins huit chiffres."</string>
+    <string name="needPuk" msgid="919668385956251611">"Votre carte SIM est verrouillée par clé PUK. Saisissez la clé PUK pour la déverrouiller."</string>
+    <string name="needPuk2" msgid="4526033371987193070">"Saisissez la clé PUK2 pour débloquer la carte SIM."</string>
+    <string name="imei" msgid="2625429890869005782">"Code IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
+    <string name="ClipMmi" msgid="6952821216480289285">"Numéro de l\'appelant (entrant)"</string>
+    <string name="ClirMmi" msgid="7784673673446833091">"Numéro de l\'appelant (sortant)"</string>
+    <string name="CfMmi" msgid="5123218989141573515">"Transfert d\'appel"</string>
+    <string name="CwMmi" msgid="9129678056795016867">"Appel en attente"</string>
+    <string name="BaMmi" msgid="455193067926770581">"Interdiction d\'appel"</string>
+    <string name="PwdMmi" msgid="7043715687905254199">"Modification du mot de passe"</string>
+    <string name="PinMmi" msgid="3113117780361190304">"Modification du NIP"</string>
+    <string name="CnipMmi" msgid="3110534680557857162">"Présentation du numéro d\'appelant"</string>
+    <string name="CnirMmi" msgid="3062102121430548731">"Numéro de l\'appelant masqué"</string>
+    <string name="ThreeWCMmi" msgid="9051047170321190368">"Conférence téléphonique à trois"</string>
+    <string name="RuacMmi" msgid="7827887459138308886">"Rejeter les appels indésirables"</string>
+    <string name="CndMmi" msgid="3116446237081575808">"Livraison du numéro d\'appel"</string>
+    <string name="DndMmi" msgid="1265478932418334331">"Ne pas déranger"</string>
+    <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"Par défaut, les numéros des appelants ne sont pas restreints. Appel suivant : restreint"</string>
+    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"Par défaut, les numéros des appelants ne sont pas restreints. Appel suivant : non restreint"</string>
+    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"Par défaut, les numéros des appelants ne sont pas restreints. Appel suivant : restreint"</string>
+    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"Par défaut, les numéros des appelants ne sont pas restreints. Appel suivant : non restreint"</string>
+    <string name="serviceNotProvisioned" msgid="8614830180508686666">"Ce service n\'est pas pris en charge."</string>
+    <string name="CLIRPermanent" msgid="3377371145926835671">"Impossible de modifier le paramètre relatif au numéro de l\'appelant."</string>
+    <string name="RestrictedChangedTitle" msgid="5592189398956187498">"L\'accès limité a été modifié."</string>
+    <string name="RestrictedOnData" msgid="8653794784690065540">"Le service de données est bloqué."</string>
+    <string name="RestrictedOnEmergency" msgid="6581163779072833665">"Le service d\'appel d\'urgence est bloqué."</string>
+    <string name="RestrictedOnNormal" msgid="4953867011389750673">"Le service vocal est bloqué."</string>
+    <string name="RestrictedOnAllVoice" msgid="3396963652108151260">"Tous les services voix sont bloqués."</string>
+    <string name="RestrictedOnSms" msgid="8314352327461638897">"Le service SMS est bloqué."</string>
+    <string name="RestrictedOnVoiceData" msgid="996636487106171320">"Les services vocaux/de données sont bloqués."</string>
+    <string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Les services voix/SMS sont bloqués."</string>
+    <string name="RestrictedOnAll" msgid="5643028264466092821">"Tous les services vocaux/de données/SMS sont bloqués."</string>
+    <string name="serviceClassVoice" msgid="1258393812335258019">"Google Voice"</string>
+    <string name="serviceClassData" msgid="872456782077937893">"Données"</string>
+    <string name="serviceClassFAX" msgid="5566624998840486475">"Télécopie"</string>
+    <string name="serviceClassSMS" msgid="2015460373701527489">"SMS"</string>
+    <string name="serviceClassDataAsync" msgid="4523454783498551468">"Asynchrones"</string>
+    <string name="serviceClassDataSync" msgid="7530000519646054776">"Synchroniser"</string>
+    <string name="serviceClassPacket" msgid="6991006557993423453">"Paquet"</string>
+    <string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
+    <string name="roamingText0" msgid="7170335472198694945">"Indicateur d\'itinérance activé"</string>
+    <string name="roamingText1" msgid="5314861519752538922">"Indicateur d\'itinérance désactivé"</string>
+    <string name="roamingText2" msgid="8969929049081268115">"Indicateur d\'itinérance clignotant"</string>
+    <string name="roamingText3" msgid="5148255027043943317">"Hors zone"</string>
+    <string name="roamingText4" msgid="8808456682550796530">"Hors du bâtiment"</string>
+    <string name="roamingText5" msgid="7604063252850354350">"Itinérance - Système préféré"</string>
+    <string name="roamingText6" msgid="2059440825782871513">"Itinérance - Système disponible"</string>
+    <string name="roamingText7" msgid="7112078724097233605">"Itinérance - Partenaire Alliance"</string>
+    <string name="roamingText8" msgid="5989569778604089291">"Itinérance - Partenaire Premium"</string>
+    <string name="roamingText9" msgid="7969296811355152491">"Itinérance - Tous services disponibles"</string>
+    <string name="roamingText10" msgid="3992906999815316417">"Itinérance - Services partiellement disponibles"</string>
+    <string name="roamingText11" msgid="4154476854426920970">"Bannière d\'itinérance activée"</string>
+    <string name="roamingText12" msgid="1189071119992726320">"Bannière d\'itinérance désactivée"</string>
+    <string name="roamingTextSearching" msgid="8360141885972279963">"Recherche des services disponibles"</string>
+    <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> : non transféré"</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> au bout de <xliff:g id="TIME_DELAY">{2}</xliff:g> secondes"</string>
+    <string name="cfTemplateRegistered" msgid="5073237827620166285">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> : non transféré"</string>
+    <string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> : non transféré"</string>
+    <string name="fcComplete" msgid="3118848230966886575">"Code de service terminé"</string>
+    <string name="fcError" msgid="3327560126588500777">"Problème de connexion ou code de service non valide"</string>
+    <string name="httpErrorOk" msgid="1191919378083472204">"OK"</string>
+    <string name="httpError" msgid="7956392511146698522">"Une erreur réseau s\'est produite."</string>
+    <string name="httpErrorLookup" msgid="4711687456111963163">"Impossible de trouver l\'URL."</string>
+    <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"Le modèle d\'authentification du site n\'est pas compatible."</string>
+    <string name="httpErrorAuth" msgid="1435065629438044534">"Impossible de procéder à l\'authentification."</string>
+    <string name="httpErrorProxyAuth" msgid="1788207010559081331">"Échec de l\'authentification par un serveur mandataire."</string>
+    <string name="httpErrorConnect" msgid="8714273236364640549">"Impossible de se connecter au serveur."</string>
+    <string name="httpErrorIO" msgid="2340558197489302188">"Impossible d\'établir une communication avec le serveur. Veuillez réessayer plus tard."</string>
+    <string name="httpErrorTimeout" msgid="4743403703762883954">"Délai de connexion au serveur dépassé."</string>
+    <string name="httpErrorRedirectLoop" msgid="8679596090392779516">"Cette page contient trop de redirections de serveurs."</string>
+    <string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"Ce protocole n\'est pas compatible."</string>
+    <string name="httpErrorFailedSslHandshake" msgid="96549606000658641">"Impossible d\'établir une connexion sécurisée."</string>
+    <string name="httpErrorBadUrl" msgid="3636929722728881972">"Impossible d\'ouvrir la page, car l\'URL n\'est pas valide."</string>
+    <string name="httpErrorFile" msgid="2170788515052558676">"Impossible d\'accéder au fichier."</string>
+    <string name="httpErrorFileNotFound" msgid="6203856612042655084">"Impossible de trouver le fichier demandé."</string>
+    <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Trop de requêtes sont en cours de traitement. Veuillez réessayer plus tard."</string>
+    <string name="notification_title" msgid="8967710025036163822">"Erreur de connexion au compte <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string>
+    <string name="contentServiceSync" msgid="8353523060269335667">"Synchroniser"</string>
+    <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Synchroniser"</string>
+    <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Trop de contenus supprimés (<xliff:g id="CONTENT_TYPE">%s</xliff:g>)."</string>
+    <string name="low_memory" product="tablet" msgid="6494019234102154896">"La mémoire de la tablette est pleine. Supprimez des fichiers pour libérer de l\'espace."</string>
+    <string name="low_memory" product="default" msgid="3475999286680000541">"La mémoire du téléphone est pleine. Veuillez supprimer des fichiers pour libérer de l\'espace."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Le réseau peut être surveillé"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
+    <string name="me" msgid="6545696007631404292">"Moi"</string>
+    <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Options de la tablette"</string>
+    <string name="power_dialog" product="default" msgid="1319919075463988638">"Options du téléphone"</string>
+    <string name="silent_mode" msgid="7167703389802618663">"Mode silencieux"</string>
+    <string name="turn_on_radio" msgid="3912793092339962371">"Activer le mode sans fil"</string>
+    <string name="turn_off_radio" msgid="8198784949987062346">"Désactiver le mode sans fil"</string>
+    <string name="screen_lock" msgid="799094655496098153">"Verrouillage de l\'écran"</string>
+    <string name="power_off" msgid="4266614107412865048">"Éteindre"</string>
+    <string name="silent_mode_silent" msgid="319298163018473078">"Sonnerie désactivée"</string>
+    <string name="silent_mode_vibrate" msgid="7072043388581551395">"Sonnerie en mode vibreur"</string>
+    <string name="silent_mode_ring" msgid="8592241816194074353">"Sonnerie activée"</string>
+    <string name="shutdown_progress" msgid="2281079257329981203">"Arrêt en cours..."</string>
+    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Votre tablette va s\'éteindre."</string>
+    <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Votre téléphone va s\'éteindre."</string>
+    <string name="shutdown_confirm_question" msgid="2906544768881136183">"Voulez-vous éteindre l\'appareil?"</string>
+    <string name="reboot_safemode_title" msgid="7054509914500140361">"Redémarrer en mode sans échec"</string>
+    <string name="reboot_safemode_confirm" msgid="55293944502784668">"Voulez-vous redémarrer en mode sans échec? Cette opération aura pour effet de désactiver toutes les applications tierces que vous avez installées. Elles seront réactivées au prochain redémarrage."</string>
+    <string name="recent_tasks_title" msgid="3691764623638127888">"Récents"</string>
+    <string name="no_recent_tasks" msgid="8794906658732193473">"Aucune application récente"</string>
+    <string name="global_actions" product="tablet" msgid="408477140088053665">"Options de la tablette"</string>
+    <string name="global_actions" product="default" msgid="2406416831541615258">"Options du téléphone"</string>
+    <string name="global_action_lock" msgid="2844945191792119712">"Verrouillage de l\'écran"</string>
+    <string name="global_action_power_off" msgid="4471879440839879722">"Éteindre"</string>
+    <string name="global_action_bug_report" msgid="7934010578922304799">"Rapport de bogue"</string>
+    <string name="bugreport_title" msgid="2667494803742548533">"Créer un rapport de bogue"</string>
+    <string name="bugreport_message" msgid="398447048750350456">"Cela permet de recueillir des informations concernant l\'état actuel de votre appareil. Ces informations sont ensuite envoyées sous forme de courriel. Merci de patienter pendant la préparation du rapport de bogue. Cette opération peut prendre quelques instants."</string>
+    <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Mode silencieux"</string>
+    <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Le son est désactivé."</string>
+    <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Le son est activé."</string>
+    <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Mode Avion"</string>
+    <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Le mode Avion est activé."</string>
+    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Le mode Avion est désactivé."</string>
+    <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"&gt;999"</string>
+    <string name="safeMode" msgid="2788228061547930246">"Mode sécurisé"</string>
+    <string name="android_system_label" msgid="6577375335728551336">"Système Android"</string>
+    <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Services payants"</string>
+    <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Effectuer des opérations payantes"</string>
+    <string name="permgrouplab_messages" msgid="7521249148445456662">"Vos messages"</string>
+    <string name="permgroupdesc_messages" msgid="7821999071003699236">"Permet de lire et de rédiger vos SMS, courriels et autres messages."</string>
+    <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Vos données personnelles"</string>
+    <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"Accès direct aux informations vous concernant enregistrées dans la fiche de contact"</string>
+    <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Vos données sur les réseaux sociaux"</string>
+    <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Accès direct aux informations sur vos contacts et vos amis sur les réseaux sociaux"</string>
+    <string name="permgrouplab_location" msgid="635149742436692049">"Votre position"</string>
+    <string name="permgroupdesc_location" msgid="5704679763124170100">"Déterminer votre position géographique"</string>
+    <string name="permgrouplab_network" msgid="5808983377727109831">"Communications réseau"</string>
+    <string name="permgroupdesc_network" msgid="4478299413241861987">"Accéder à différentes fonctionnalités du réseau"</string>
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"Bluetooth"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"Accéder aux appareils et aux réseaux via Bluetooth"</string>
+    <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"Paramètres audio"</string>
+    <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"Modification des paramètres audio"</string>
+    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Affecte la batterie"</string>
+    <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Utilisation de fonctionnalités qui peuvent épuiser rapidement la batterie"</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"Agenda"</string>
+    <string name="permgroupdesc_calendar" msgid="5777534316982184416">"Accès direct à l\'agenda et aux événements"</string>
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"Consulter le dictionnaire personnel"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"Consulter les mots ajoutés au dictionnaire personnel"</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"Modifier le dictionnaire personnel"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"Ajouter des mots au dictionnaire personnel"</string>
+    <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Favoris et historique"</string>
+    <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Accès direct aux favoris et à l\'historique du navigateur"</string>
+    <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"Alarme"</string>
+    <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"Réglage du réveil"</string>
+    <string name="permgrouplab_voicemail" msgid="4162237145027592133">"Messagerie vocale"</string>
+    <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"Accès direct à la messagerie vocale"</string>
+    <string name="permgrouplab_microphone" msgid="171539900250043464">"Microphone"</string>
+    <string name="permgroupdesc_microphone" msgid="7106618286905738408">"Accès direct au microphone pour enregistrer du contenu audio"</string>
+    <string name="permgrouplab_camera" msgid="4820372495894586615">"Appareil photo"</string>
+    <string name="permgroupdesc_camera" msgid="2933667372289567714">"Accès direct à la caméra pour la capture d\'images ou de vidéos"</string>
+    <string name="permgrouplab_screenlock" msgid="8275500173330718168">"Écran de verrouillage"</string>
+    <string name="permgroupdesc_screenlock" msgid="7067497128925499401">"Modifier le comportement de l\'écran de verrouillage sur votre appareil"</string>
+    <string name="permgrouplab_appInfo" msgid="8028789762634147725">"Informations sur vos applications"</string>
+    <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"Possibilité de modifier le comportement des autres applications sur votre appareil"</string>
+    <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"Fond d\'écran"</string>
+    <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"Modification des paramètres du fond d\'écran de l\'appareil"</string>
+    <string name="permgrouplab_systemClock" msgid="406535759236612992">"Horloge"</string>
+    <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"Modification de l\'heure ou du fuseau horaire de l\'appareil"</string>
+    <string name="permgrouplab_statusBar" msgid="2095862568113945398">"Barre d\'état"</string>
+    <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"Modification des paramètres de la barre d\'état de l\'appareil"</string>
+    <string name="permgrouplab_syncSettings" msgid="3341990986147826541">"Paramètres de synchronisation"</string>
+    <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"Accès aux paramètres de synchronisation"</string>
+    <string name="permgrouplab_accounts" msgid="3359646291125325519">"Vos comptes"</string>
+    <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Accéder aux comptes disponibles"</string>
+    <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Contrôle du matériel"</string>
+    <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Accès direct au matériel de l\'appareil"</string>
+    <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Appels téléphoniques"</string>
+    <string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"Suivre, enregistrer et traiter les appels téléphoniques"</string>
+    <string name="permgrouplab_systemTools" msgid="4652191644082714048">"Outils système"</string>
+    <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"Accès et contrôle de faible niveau du système."</string>
+    <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"Outils de conception"</string>
+    <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"Ces fonctionnalités sont destinées uniquement aux développeurs d\'applications."</string>
+    <string name="permgrouplab_display" msgid="4279909676036402636">"Interface utilisateur d\'une autre application"</string>
+    <string name="permgroupdesc_display" msgid="6051002031933013714">"Effet sur l\'interface utilisateur d\'autres applications"</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"Stockage"</string>
+    <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Accéder à la mémoire de stockage USB"</string>
+    <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Accès à la carte SD"</string>
+    <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"Fonctionnalités d\'accessibilité"</string>
+    <string name="permgroupdesc_accessibilityFeatures" msgid="4205196881678144335">"Fonctionnalités pouvant être requises dans le cadre des technologies d\'assistance"</string>
+    <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Récupérer le contenu d\'une fenêtre"</string>
+    <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecter le contenu d\'une fenêtre avec laquelle vous interagissez."</string>
+    <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activer la fonctionnalité Explorer au toucher"</string>
+    <string name="capability_desc_canRequestTouchExploration" msgid="5800552516779249356">"Les éléments sélectionnés sont énoncés à voix haute. Vous pouvez explorer l\'écran à l\'aide de gestes."</string>
+    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Activer l\'accessibilité Web améliorée"</string>
+    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Vous pouvez installer des scripts pour rendre le contenu des applications plus accessible."</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Observer le texte que vous saisissez"</string>
+    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Inclut des données personnelles telles que les numéros de cartes de paiement et les mots de passe."</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"désactiver ou modifier la barre d\'état"</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"Permet à l\'application de désactiver la barre d\'état, ou d\'ajouter et de supprimer des icônes système."</string>
+    <string name="permlab_statusBarService" msgid="7247281911387931485">"barre d\'état"</string>
+    <string name="permdesc_statusBarService" msgid="716113660795976060">"Permet à l\'application de faire office de barre d\'état."</string>
+    <string name="permlab_expandStatusBar" msgid="1148198785937489264">"agrandir ou réduire la barre d\'état"</string>
+    <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"Permet à l\'application de réduire ou de développer la barre d\'état."</string>
+    <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"transférer les appels sortants"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Permet à l\'application de traiter les appels sortants et de modifier le numéro à composer. Cette autorisation lui permet de surveiller, rediriger ou empêcher les appels sortants."</string>
+    <string name="permlab_receiveSms" msgid="8673471768947895082">"recevoir des messages texte"</string>
+    <string name="permdesc_receiveSms" msgid="6424387754228766939">"Permet à l\'application de recevoir et de traiter les messages texte. Cette autorisation lui donne la possibilité de surveiller ou de supprimer les messages envoyés à votre appareil sans vous les montrer."</string>
+    <string name="permlab_receiveMms" msgid="1821317344668257098">"recevoir des messages multimédias"</string>
+    <string name="permdesc_receiveMms" msgid="533019437263212260">"Permet à l\'application de recevoir et de traiter les messages multimédias. Cette autorisation lui donne la possibilité de surveiller ou de supprimer les messages envoyés à votre appareil sans vous les montrer."</string>
+    <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"recevoir les messages de diffusion d\'urgence"</string>
+    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Permet à l\'application de recevoir et de traiter les messages d\'urgence. Cette autorisation n\'est possible que pour les applications système."</string>
+    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"lire les messages de diffusion cellulaire"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permet à l\'application de lire les messages de diffusion cellulaire que votre appareil reçoit. Dans certaines zones géographiques, des alertes vous sont envoyées afin de vous prévenir en cas de situation d\'urgence. Des applications malveillantes peuvent venir perturber les performances ou le fonctionnement de votre appareil lors de la réception d\'un message de diffusion cellulaire."</string>
+    <string name="permlab_sendSms" msgid="5600830612147671529">"envoyer des messages texte"</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"Permet à l\'application d\'envoyer des messages texte. Cette autorisation peut entraîner des frais inattendus. Des applications malveillantes peuvent générer des frais en envoyant des messages sans votre consentement."</string>
+    <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"envoyer des réponses par message"</string>
+    <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"Permet à l\'application d\'envoyer à d\'autres applications de SMS/MMS des demandes pour gérer les réponses par message pour les appels entrants."</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"voir les messages texte ou multimédias"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Permet à l\'application de lire les SMS stockés sur votre tablette ou sur la carte SIM. Cette autorisation lui permet de lire tous les SMS, indépendamment de leur contenu ou de leur caractère confidentiel."</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Permet à l\'application de lire les SMS stockés sur votre téléphone ou sur la carte SIM. Cette autorisation lui permet de lire tous les SMS, indépendamment de leur contenu ou de leur caractère confidentiel."</string>
+    <string name="permlab_writeSms" msgid="3216950472636214774">"modifier les messages texte ou multimédias"</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Permet à l\'application de modifier les SMS stockés sur votre tablette ou sur la carte SIM. Des applications malveillantes peuvent exploiter cette fonctionnalité pour supprimer vos messages."</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Permet à l\'application de modifier les SMS stockés sur votre téléphone ou sur votre carte SIM. Des applications malveillantes peuvent exploiter cette fonctionnalité pour supprimer vos messages."</string>
+    <string name="permlab_receiveWapPush" msgid="5991398711936590410">"recevoir des messages WAP"</string>
+    <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Permet à l\'application de recevoir et de traiter les messages WAP. Cette autorisation lui donne la possibilité de surveiller ou de supprimer les messages envoyés à votre appareil sans vous les montrer."</string>
+    <string name="permlab_getTasks" msgid="6466095396623933906">"récupérer les données des applications en cours d\'exécution"</string>
+    <string name="permdesc_getTasks" msgid="7454215995847658102">"Permet à l\'application de récupérer des données sur des tâches en cours d\'exécution et récemment exécutées. L\'application est ainsi susceptible d\'obtenir des données concernant les applications utilisées sur l\'appareil."</string>
+    <string name="permlab_interactAcrossUsers" msgid="7114255281944211682">"interagir entre les utilisateurs"</string>
+    <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Permet à l\'application d\'effectuer des actions entre les différents utilisateurs de l\'appareil. Les applications malveillantes peuvent utiliser cette autorisation pour passer outre la protection entre les utilisateurs."</string>
+    <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"autorisation totale d\'interagir entre les utilisateurs"</string>
+    <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Permet toutes les interactions possibles entre les utilisateurs."</string>
+    <string name="permlab_manageUsers" msgid="1676150911672282428">"Gérer les utilisateurs"</string>
+    <string name="permdesc_manageUsers" msgid="8409306667645355638">"Permet aux applications de gérer les utilisateurs de l\'appareil, y compris la recherche, la création et la suppression d\'utilisateurs."</string>
+    <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"récupérer les détails des applications en cours d\'exécution"</string>
+    <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Permet à l\'application de récupérer des données détaillées sur les tâches en cours d\'exécution ou récemment exécutées. Des applications malveillantes peuvent utiliser cette fonctionnalité pour obtenir des données confidentielles relatives à d\'autres applications."</string>
+    <string name="permlab_reorderTasks" msgid="2018575526934422779">"réorganiser les applications en cours d\'exécution"</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Permet à l\'application de déplacer les tâches au premier plan et en arrière-plan. L\'application peut procéder à ces opérations sans votre intervention."</string>
+    <string name="permlab_removeTasks" msgid="6821513401870377403">"arrêter les applications en cours d\'exécution"</string>
+    <string name="permdesc_removeTasks" msgid="1394714352062635493">"Permet à l\'application de supprimer des tâches et de fermer les applications qui les exécutent. Des applications malveillantes peuvent utiliser cette fonctionnalité pour perturber le comportement d\'autres applications."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"gérer des piles d\'activité"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Permet à l\'application d\'ajouter, de supprimer et de modifier l\'activité des piles dans lesquelles d\'autres applications fonctionnent. Des applications malveillantes peuvent perturber le comportement des autres applications."</string>
+    <string name="permlab_startAnyActivity" msgid="2918768238045206456">"démarrer n\'importe quelle activité"</string>
+    <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Permet à l\'application de démarrer n\'importe quelle activité, quels que soient l\'état exporté ou le degré de protection appliqué à l\'autorisation."</string>
+    <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"définir la compatibilité de l\'écran"</string>
+    <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Permettre de contrôler le mode de compatibilité de l\'écran des autres applications. Des applications malveillantes peuvent perturber le fonctionnement d\'autres applications."</string>
+    <string name="permlab_setDebugApp" msgid="3022107198686584052">"activer le débogage des applications"</string>
+    <string name="permdesc_setDebugApp" msgid="4474512416299013256">"Permet à l\'application d\'activer le débogage d\'une autre application. Des applications malveillantes peuvent utiliser cette fonctionnalité pour en fermer d\'autres."</string>
+    <string name="permlab_changeConfiguration" msgid="4162092185124234480">"modifier les paramètres d\'affichage du système"</string>
+    <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"Permet à l\'application de modifier la configuration actuelle, par exemple les paramètres régionaux ou la taille de la police."</string>
+    <string name="permlab_enableCarMode" msgid="5684504058192921098">"activer le mode voiture"</string>
+    <string name="permdesc_enableCarMode" msgid="4853187425751419467">"Permet à l\'application d\'activer le mode Voiture."</string>
+    <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"fermer les autres applications"</string>
+    <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"Permet à l\'application de mettre fin aux processus d\'autres applications exécutés en arrière-plan. Cette autorisation peut interrompre l\'exécution d\'autres applications."</string>
+    <string name="permlab_forceStopPackages" msgid="2329627428832067700">"forcer l\'arrêt d\'autres applications"</string>
+    <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"Permet à l\'application de forcer l\'arrêt d\'autres applications."</string>
+    <string name="permlab_forceBack" msgid="652935204072584616">"forcer la fermeture de l\'application"</string>
+    <string name="permdesc_forceBack" msgid="3892295830419513623">"Permet à l\'application de forcer l\'arrêt de toute activité au premier plan et de la faire passer en arrière-plan. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
+    <string name="permlab_dump" msgid="1681799862438954752">"vérifier l\'état interne du système"</string>
+    <string name="permdesc_dump" msgid="1778299088692290329">"Permet à l\'application de récupérer l\'état interne du système. Des applications malveillantes peuvent utiliser cette fonctionnalité pour récupérer de nombreuses données confidentielles et sécurisées dont elles ne devraient pas avoir besoin normalement."</string>
+    <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"récupérer le contenu de l\'écran"</string>
+    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Permet à l\'application de récupérer le contenu de la fenêtre active. Des applications malveillantes peuvent exploiter cette fonctionnalité pour récupérer et lire la totalité du contenu de la fenêtre, à l\'exception des mots de passe."</string>
+    <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"activer temporairement l\'accessibilité"</string>
+    <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"Permet à une application d\'activer temporairement l\'accessibilité sur l\'appareil. Des applications malveillantes peuvent activer l\'accessibilité sans le consentement de l\'utilisateur."</string>
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"récupérer les données sur les fenêtres"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Permet à une application de récupérer les données sur les fenêtres dans le gestionnaire de fenêtres. Des applications malveillantes peuvent récupérer des données destinées à un usage interne du système."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"filtrer les événements"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Permet à une application d\'enregistrer un filtre d\'entrée pour filtrer le flux de tous les événements des utilisateurs avant qu\'ils ne soient traités. Des applications malveillantes peuvent contrôler l\'interface utilisateur du système sans l\'intervention de l\'utilisateur."</string>
+    <string name="permlab_magnify_display" msgid="5973626738170618775">"agrandir l\'écran"</string>
+    <string name="permdesc_magnify_display" msgid="7121235684515003792">"Permet à une application d\'agrandir le contenu à l\'écran. Les applications malveillantes peuvent transformer ce contenu et rendre l\'appareil inutilisable."</string>
+    <string name="permlab_shutdown" msgid="7185747824038909016">"arrêt partiel"</string>
+    <string name="permdesc_shutdown" msgid="7046500838746291775">"Place le gestionnaire d\'activités en état d\'arrêt, mais n\'effectue pas d\'arrêt complet."</string>
+    <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"empêcher les changements d\'applications"</string>
+    <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Empêche l\'utilisateur de changer d\'application."</string>
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"récupérer des informations sur l\'application actuelle"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Permet à l\'application autorisée de récupérer des informations confidentielles à propos de l\'application exécutée au premier plan sur l\'écran."</string>
+    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"suivre et gérer le lancement de toutes les applications"</string>
+    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Permet à l\'application de suivre et de gérer la façon dont le système lance les activités. Des applications malveillantes peuvent utiliser cette fonctionnalité pour entièrement compromettre l\'intégrité du système. Cette autorisation est uniquement destinée aux concepteurs. Elle ne doit jamais être activée dans le cadre d\'une utilisation standard."</string>
+    <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"envoyer une diffusion sans paquet"</string>
+    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"Permet à l\'application d\'envoyer une notification indiquant la suppression d\'un paquet d\'application. Des applications malveillantes peuvent utiliser cette fonctionnalité pour fermer les autres applications en cours d\'exécution."</string>
+    <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"envoyer une diffusion reçue par message texte"</string>
+    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"Permet à l\'application d\'envoyer une notification indiquant la réception d\'un message texte. Des applications malveillantes peuvent utiliser cette fonctionnalité pour créer de faux messages entrants."</string>
+    <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"envoyer une diffusion de réception de WAP par poussée"</string>
+    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"Permet à l\'application d\'envoyer une notification indiquant la réception d\'un message WAP par poussée. Des applications malveillantes peuvent utiliser cette fonctionnalité pour créer de faux messages multimédias entrants ou pour remplacer le contenu d\'une page Web par du contenu malveillant."</string>
+    <string name="permlab_setProcessLimit" msgid="2451873664363662666">"restreindre le nombre de processus en cours d\'exécution"</string>
+    <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"Permet à l\'application de définir le nombre maximal de processus devant s\'exécuter. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
+    <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"forcer la fermeture des applications en arrière-plan"</string>
+    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"Permet à l\'application de définir si les activités sont toujours terminées lorsqu\'elles passent en arrière-plan. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
+    <string name="permlab_batteryStats" msgid="2789610673514103364">"lire les statistiques de la batterie"</string>
+    <string name="permdesc_batteryStats" msgid="5897346582882915114">"Permet à une application de lire les données de consommation actuelles indiquant le faible niveau de la batterie. Permet éventuellement à l\'application d\'obtenir des informations détaillées sur les applications que vous utilisez."</string>
+    <string name="permlab_updateBatteryStats" msgid="3719689764536379557">"modifier les statistiques de la batterie"</string>
+    <string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"Permet à l\'application de modifier les statistiques collectées concernant la batterie. Les applications standards ne doivent pas utiliser cette fonctionnalité."</string>
+    <string name="permlab_getAppOpsStats" msgid="1508779687436585744">"récupérer les statistiques de fonctionnement des applications"</string>
+    <string name="permdesc_getAppOpsStats" msgid="6243887041577912877">"Permet à l\'application de récupérer les statistiques de fonctionnement des applications recueillies. Les applications standards ne doivent pas utiliser cette fonctionnalité."</string>
+    <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"modifier les statistiques de fonctionnement des applications"</string>
+    <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"Permet à l\'application de modifier les statistiques de fonctionnement des applications collectées. Les applications standards ne doivent pas utiliser cette fonctionnalité."</string>
+    <string name="permlab_backup" msgid="470013022865453920">"gérer la sauvegarde et la restauration du système"</string>
+    <string name="permdesc_backup" msgid="6912230525140589891">"Permet à l\'application de contrôler le mécanisme de sauvegarde et de restauration du système. Les applications standards ne doivent pas utiliser cette fonctionnalité."</string>
+    <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"confirmer une sauvegarde complète ou une restauration"</string>
+    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"Permet à l\'application de lancer l\'interface utilisateur de confirmation de sauvegarde complète. Seules certaines applications peuvent bénéficier de cette autorisation."</string>
+    <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"afficher les fenêtres non autorisées"</string>
+    <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"Permet à l\'application de créer des fenêtres destinées à être utilisées par l\'interface utilisateur du système interne. Les applications standards ne doivent pas utiliser cette fonctionnalité."</string>
+    <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"ignorer les autres applications"</string>
+    <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"Permet à l\'application d\'ignorer d\'autres applications ou certaines parties de l\'interface utilisateur. Cela peut altérer votre utilisation de l\'interface de n\'importe quelle application, ou modifier ce que vous pensez voir dans d\'autres applications."</string>
+    <string name="permlab_setAnimationScale" msgid="2805103241153907174">"modifier la vitesse des animations"</string>
+    <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"Permet à l\'application de modifier à tout moment la vitesse générale des animations pour les ralentir ou les accélérer."</string>
+    <string name="permlab_manageAppTokens" msgid="1286505717050121370">"gérer les jetons d\'application"</string>
+    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"Permet à l\'application de créer et de gérer ses propres jetons en ignorant l\'ordre de plan normal. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
+    <string name="permlab_freezeScreen" msgid="4708181184441880175">"bloquer l\'écran"</string>
+    <string name="permdesc_freezeScreen" msgid="8558923789222670064">"Permet à l\'application de bloquer temporairement l\'écran pour passer en mode plein écran."</string>
+    <string name="permlab_injectEvents" msgid="1378746584023586600">"utiliser les touches et les boutons de commande"</string>
+    <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"Permet à l\'application de fournir ses propres événements d\'entrée (pression de touche, etc.) à d\'autres applications. Des applications malveillantes peuvent exploiter cette fonctionnalité pour prendre le contrôle de la tablette."</string>
+    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"Permet à l\'application de fournir ses propres événements d\'entrée (pression de touche, etc.) à d\'autres applications. Des applications malveillantes peuvent exploiter cette fonctionnalité pour prendre le contrôle du téléphone."</string>
+    <string name="permlab_readInputState" msgid="469428900041249234">"enregistrer le texte entré et les actions effectuées"</string>
+    <string name="permdesc_readInputState" msgid="8387754901688728043">"Permet à l\'application d\'identifier les touches sur lesquelles vous appuyez, même lorsque vous utilisez une autre application (lorsque vous entrez un mot de passe, par exemple). Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
+    <string name="permlab_bindInputMethod" msgid="3360064620230515776">"s\'associer à un mode d\'entrée"</string>
+    <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un mode d\'entrée. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
+    <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"s\'associer à un service d\'accessibilité"</string>
+    <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un service d\'accessibilité. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"lier à un service d\'impression"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un service de widget. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"s\'associer à un service d\'impression désynchronisée"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Permet à l\'application autorisée de s\'associer à l\'interface de niveau supérieur d\'un service d\'impression désynchronisée. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"s\'associer au service NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Permet à l\'application autorisée de s\'associer aux applications qui reproduisent le fonctionnement des cartes NFC. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
+    <string name="permlab_bindTextService" msgid="7358378401915287938">"s\'associer à un service de texte"</string>
+    <string name="permdesc_bindTextService" msgid="8151968910973998670">"Permet à l\'application de s\'associer à l\'interface de haut niveau d\'un service de texte (par exemple, SpellCheckerService). Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
+    <string name="permlab_bindVpnService" msgid="4708596021161473255">"s\'associer à un service RPV"</string>
+    <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un service RPV. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
+    <string name="permlab_bindWallpaper" msgid="8716400279937856462">"se fixer à un fond d\'écran"</string>
+    <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un fond d\'écran. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
+    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"s\'associer à un service de widget"</string>
+    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un service de widget. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
+    <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interagir avec l\'administrateur d\'un périphérique"</string>
+    <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Permet à l\'application autorisée d\'envoyer des intentions à l\'administrateur de l\'appareil. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"ajouter ou supprimer un administrateur de l\'appareil"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Permet à l\'application d\'ajouter ou de supprimer des administrateurs actifs de l\'appareil. Les applications standards ne devraient jamais utiliser cette autorisation."</string>
+    <string name="permlab_setOrientation" msgid="3365947717163866844">"modifier l\'orientation de l\'écran"</string>
+    <string name="permdesc_setOrientation" msgid="3046126619316671476">"Permet à l\'application de changer l\'orientation de l\'écran à tout moment. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
+    <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"modifier la vitesse du pointeur"</string>
+    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Permet à l\'application de modifier à tout moment la vitesse du pointeur de la souris ou du pavé tactile. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
+    <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"changer la disposition du clavier"</string>
+    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Permet à l\'application de changer la disposition du clavier. Les applications standards ne devraient pas nécessiter cette autorisation."</string>
+    <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"envoyer des signaux Linux aux applications"</string>
+    <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Permet à l\'application de demander que le signal fourni soit envoyé à tous les processus persistants."</string>
+    <string name="permlab_persistentActivity" msgid="8841113627955563938">"exécuter l\'application en continu"</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Permet à l\'application de rendre certains de ces composants persistants dans la mémoire. Cette autorisation peut limiter la mémoire disponible pour d\'autres applications et ralentir la tablette."</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"Permet à l\'application de rendre certains de ces composants persistants dans la mémoire. Cette autorisation peut limiter la mémoire disponible pour d\'autres applications et ralentir le téléphone."</string>
+    <string name="permlab_deletePackages" msgid="184385129537705938">"supprimer des applications"</string>
+    <string name="permdesc_deletePackages" msgid="7411480275167205081">"Permet à l\'application de supprimer des paquets Android. Des applications malveillantes peuvent utiliser cette fonctionnalité pour supprimer des applications importantes."</string>
+    <string name="permlab_clearAppUserData" msgid="274109191845842756">"supprimer les données d\'autres applications"</string>
+    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"Permet à l\'application d\'effacer les données utilisateur."</string>
+    <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"vider le cache d\'autres applications"</string>
+    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"Permet à l\'application de supprimer les fichiers du cache."</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"évaluer l\'espace de stockage de l\'application"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Permet à l\'application de récupérer la taille de son code, de ses données et de sa mémoire cache."</string>
+    <string name="permlab_installPackages" msgid="2199128482820306924">"installer directement des applications"</string>
+    <string name="permdesc_installPackages" msgid="5628530972548071284">"Permet à l\'application d\'installer des paquets Android nouveaux ou mis à jour. Des applications malveillantes peuvent utiliser cette fonctionnalité pour ajouter de nouvelles applications à l\'aide d\'autorisations anormalement puissantes."</string>
+    <string name="permlab_clearAppCache" msgid="7487279391723526815">"supprimer toutes les données du cache de l\'application"</string>
+    <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"Permet à l\'application de libérer de la mémoire de stockage sur la tablette en supprimant des fichiers dans les répertoires en cache d\'autres applications. Cette autorisation peut occasionner un démarrage plus lent de ces applications, dans la mesure où une nouvelle récupération de leurs données est requise."</string>
+    <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"Permet à l\'application de libérer de la mémoire de stockage sur le téléphone en supprimant des fichiers dans les répertoires en cache d\'autres applications. Cette autorisation peut occasionner un démarrage plus lent de ces applications, dans la mesure où une nouvelle récupération de leurs données est requise."</string>
+    <string name="permlab_movePackage" msgid="3289890271645921411">"déplacer les ressources d\'une application"</string>
+    <string name="permdesc_movePackage" msgid="319562217778244524">"Permet à l\'application de déplacer les ressources d\'une application à partir d\'un support interne vers un support externe, et inversement."</string>
+    <string name="permlab_readLogs" msgid="6615778543198967614">"lire les données des journaux à caractère confidentiel"</string>
+    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Permet à l\'application de lire les différents fichiers journaux du système afin d\'obtenir des informations générales sur la façon dont vous utilisez votre tablette. Celles-ci peuvent éventuellement inclure des informations d\'ordre personnel ou privé."</string>
+    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Permet à l\'application de lire les différents fichiers journaux du système afin d\'obtenir des informations générales sur la façon dont vous utilisez votre téléphone. Celles-ci peuvent éventuellement inclure des informations d\'ordre personnel ou privé."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"utiliser n\'importe quel décodeur pour lire les fichiers multimédias"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Permet à une application d\'utiliser n\'importe quel décodeur installé pour lire les fichiers multimédias."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"gérer les certificats de confiance"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Permet à l\'application d\'installer et de désinstaller les certificats CA en tant que certificats de confiance."</string>
+    <string name="permlab_diagnostic" msgid="8076743953908000342">"lire ou modifier les ressources appartenant au groupe de diagnostics"</string>
+    <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permet à l\'application d\'obtenir des droits en lecture et en écriture pour toute ressource appartenant au groupe de diagnostics (par exemple, les fichiers du répertoire /dev). Cela peut affecter la stabilité et la sécurité du système. Cette fonctionnalité est UNIQUEMENT réservée aux diagnostics matériels effectués par le fabricant ou le fournisseur de services."</string>
+    <string name="permlab_changeComponentState" msgid="6335576775711095931">"activer ou désactiver les composants d\'une application"</string>
+    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Permet à l\'application d\'activer ou de désactiver un composant d\'une autre application. Des applications malveillantes peuvent exploiter cette fonctionnalité pour désactiver les fonctionnalités principales de votre tablette. Cette autorisation doit être utilisée avec prudence, car elle peut rendre les composants d\'une application instables, voire inutilisables."</string>
+    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Permet à l\'application d\'activer ou de désactiver un composant d\'une autre application. Des applications malveillantes peuvent exploiter cette fonctionnalité pour désactiver les fonctionnalités principales de votre téléphone. Cette autorisation doit être utilisée avec prudence, car elle peut rendre les composants d\'une application instables, voire inutilisables."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"accorder ou révoquer des autorisations"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Permet à une application d\'accorder ou de révoquer des autorisations propres à celle-ci ou pour d\'autres applications. Des applications malveillantes peuvent exploiter cette autorisation pour accéder à des fonctionnalités auxquelles vous ne leur avez pas donné accès."</string>
+    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"définir les applications préférées"</string>
+    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Permet à l\'application de modifier vos applications préférées. Des applications malveillantes peuvent utiliser cette fonctionnalité pour modifier les applications exécutées en usurpant l\'identité de vos applications existantes dans le but de recueillir des données confidentielles."</string>
+    <string name="permlab_writeSettings" msgid="2226195290955224730">"modifier les paramètres du système"</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"Permet à l\'application de modifier les paramètres du système. Des applications malveillantes peuvent utiliser cette fonctionnalité pour corrompre la configuration de votre système."</string>
+    <string name="permlab_writeSecureSettings" msgid="204676251876718288">"modifier les paramètres de sécurité du système"</string>
+    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"Permet à l\'application de modifier les paramètres sécurisés du système. Les applications standards ne doivent pas utiliser cette fonctionnalité."</string>
+    <string name="permlab_writeGservices" msgid="2149426664226152185">"modifier la carte des services Google"</string>
+    <string name="permdesc_writeGservices" msgid="1287309437638380229">"Permet à l\'application de modifier la carte des services Google. Les applications standards ne doivent pas utiliser cette fonctionnalité."</string>
+    <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"s\'exécuter au démarrage"</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Permet à l\'application de se lancer une fois le démarrage du système terminé. Elle peut rallonger le temps de démarrage de la tablette et ralentir son fonctionnement global en raison de son exécution continue."</string>
+    <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Permet à l\'application de se lancer une fois le démarrage du système terminé. Elle peut rallonger le temps de démarrage du téléphone et ralentir son fonctionnement global en raison de son exécution continue."</string>
+    <string name="permlab_broadcastSticky" msgid="7919126372606881614">"envoyer une diffusion persistante"</string>
+    <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Permet à l\'application d\'envoyer des intentions de diffusion \"persistantes\", qui perdurent une fois la diffusion terminée. Une utilisation excessive peut ralentir la tablette ou la rendre instable en l\'obligeant à utiliser trop de mémoire."</string>
+    <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Permet à l\'application d\'envoyer des intentions de diffusion \"persistantes\", qui perdurent une fois la diffusion terminée. Une utilisation excessive peut ralentir le téléphone ou le rendre instable en l\'obligeant à utiliser trop de mémoire."</string>
+    <string name="permlab_readContacts" msgid="8348481131899886131">"lire vos contacts"</string>
+    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Permet à l\'application de lire les données relatives aux contacts stockés sur votre tablette, y compris la fréquence à laquelle vous avez appelé des personnes spécifiques, leur avez envoyé des courriels ou avez communiqué avec elles par d\'autres moyens. Cette autorisation permet aux applications d\'enregistrer ces données. Les applications malveillantes peuvent les partager à votre insu."</string>
+    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Permet à l\'application de lire les données relatives aux contacts stockés sur votre téléphone, y compris la fréquence à laquelle vous avez appelé des personnes spécifiques, leur avez envoyé des courriels ou avez communiqué avec elles par d\'autres moyens. Cette autorisation permet aux applications d\'enregistrer ces données. Les applications malveillantes peuvent les partager à votre insu."</string>
+    <string name="permlab_writeContacts" msgid="5107492086416793544">"modifier vos contacts"</string>
+    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Permet à l\'application de modifier les données relatives aux contacts stockés sur votre tablette, y compris la fréquence à laquelle vous avez appelé des personnes spécifiques, leur avez envoyé des courriels ou avez communiqué avec elles par d\'autres moyens. Cette autorisation permet aux applications de supprimer ces données."</string>
+    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Permet à l\'application de modifier les données relatives aux contacts stockés sur votre téléphone, y compris la fréquence à laquelle vous avez appelé des personnes spécifiques, leur avez envoyé des courriels ou avez communiqué avec elles par d\'autres moyens. Cette autorisation permet aux applications de supprimer ces données."</string>
+    <string name="permlab_readCallLog" msgid="3478133184624102739">"lire le journal d\'appels"</string>
+    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Permet à l\'application d\'accéder au journal d\'appels de votre tablette, y compris aux données relatives aux appels entrants et sortants. Cette autorisation permet aux applications d\'enregistrer les données du journal d\'appels. Les applications malveillantes peuvent partager ces données à votre insu."</string>
+    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Permet à l\'application d\'accéder au journal d\'appels de votre téléphone, y compris aux données relatives aux appels entrants et sortants. Cette autorisation permet aux applications d\'enregistrer les données du journal d\'appels. Les applications malveillantes peuvent partager ces données à votre insu."</string>
+    <string name="permlab_writeCallLog" msgid="8552045664743499354">"modifier le journal d\'appels"</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Permet à l\'application de lire le journal d\'appels de votre tablette, y compris les données relatives aux appels entrants et sortants. Des applications malveillantes peuvent utiliser cette fonctionnalité pour effacer ou modifier votre journal d\'appels."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Permet à l\'application de lire le journal d\'appels de votre téléphone, y compris les données relatives aux appels entrants et sortants. Des applications malveillantes peuvent utiliser cette fonctionnalité pour effacer ou modifier votre journal d\'appels."</string>
+    <string name="permlab_readProfile" msgid="4701889852612716678">"lire votre fiche de contact"</string>
+    <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Permet à l\'application d\'accéder aux données de profil enregistrées sur votre appareil, comme votre nom et vos coordonnées. L\'application peut alors vous identifier et envoyer les données de votre profil à des tiers."</string>
+    <string name="permlab_writeProfile" msgid="907793628777397643">"modifier votre fiche de contact"</string>
+    <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Permet à l\'application de modifier les données de profil enregistrées sur votre appareil, telles que votre nom et vos coordonnées, ou d\'en ajouter. Elle peut alors vous identifier et envoyer vos données de profil à des tiers."</string>
+    <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"lire les flux de réseaux sociaux"</string>
+    <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Permet à l\'application d\'accéder à vos mises à jour sur les réseaux sociaux, ainsi qu\'à celles de vos amis, et de les synchroniser. Soyez prudent lorsque vous partagez de l\'information. Cette autorisation permet à l\'application de lire les communications entre vous et vos amis sur les réseaux sociaux, indépendamment de leur caractère confidentiel. Remarque : Il est possible que cette autorisation ne soit pas appliquée sur tous les réseaux sociaux."</string>
+    <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"modifier vos flux de réseaux sociaux"</string>
+    <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Permet à l\'application d\'afficher les mises à jour de vos amis sur les réseaux sociaux. Soyez prudent lorsque vous partagez de l\'information. Cette autorisation permet à l\'application de générer des messages qui peuvent sembler provenir d\'un ami. Remarque : Il est possible que cette autorisation ne soit pas appliquée sur tous les réseaux sociaux."</string>
+    <string name="permlab_readCalendar" msgid="5972727560257612398">"consulter les événements d\'agenda ainsi que les données confidentielles qu\'ils contiennent"</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Permet à l\'application de lire tous les événements d\'agenda stockés sur votre tablette, y compris ceux de vos amis ou de vos collègues. Cette autorisation peut lui permettre de partager ou d\'enregistrer vos données d\'agenda, indépendamment de leur caractère confidentiel ou sensible."</string>
+    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Permet à l\'application de lire tous les événements d\'agenda stockés sur votre téléphone, y compris ceux de vos amis ou de vos collègues. Cette autorisation peut lui permettre de partager ou d\'enregistrer vos données d\'agenda, indépendamment de leur caractère confidentiel ou sensible."</string>
+    <string name="permlab_writeCalendar" msgid="8438874755193825647">"ajouter ou modifier des événements d\'agenda et envoyer des courriels aux invités à l\'insu du propriétaire"</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Permet à l\'application d\'ajouter, de supprimer et d\'apporter des modifications aux événements modifiables sur votre tablette, y compris ceux de vos amis ou de vos collègues. Cette autorisation peut lui permettre d\'envoyer des messages qui semblent provenir de propriétaires de l\'agenda ou de modifier les événements à l\'insu des propriétaires."</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Permet à l\'application d\'ajouter, de supprimer et d\'apporter des modifications aux événements modifiables sur votre téléphone, y compris ceux de vos amis ou de vos collègues. Cette autorisation peut lui permettre d\'envoyer des messages qui semblent provenir de propriétaires de l\'agenda ou de modifier les événements à l\'insu des propriétaires."</string>
+    <string name="permlab_accessMockLocation" msgid="8688334974036823330">"créer des sources de localisation fictives à des fins de test"</string>
+    <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Permet de créer des sources de localisation fictives à des fins de tests ou pour installer un nouveau fournisseur de position. L\'application peut ainsi modifier la position ou l\'état renvoyé par d\'autres sources de localisation telles que le GPS ou les fournisseurs de position."</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"accéder aux commandes de fournisseur de position géographique supplémentaires"</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"Permet à l\'application d\'accéder à des commandes de fournisseur de position supplémentaires. Elle est ainsi susceptible d\'interférer avec le bon fonctionnement du GPS ou de toute autre source de localisation."</string>
+    <string name="permlab_installLocationProvider" msgid="6578101199825193873">"autorisation d\'installer un fournisseur de services de localisation"</string>
+    <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"Permet de créer des sources de localisation fictives à des fins de tests ou pour installer un nouveau fournisseur de position. L\'application peut ainsi modifier la position ou l\'état renvoyé par d\'autres sources de localisation telles que le GPS ou les fournisseurs de position."</string>
+    <string name="permlab_accessFineLocation" msgid="1191898061965273372">"position précise (GPS et réseau)"</string>
+    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Permet à l\'application d\'obtenir votre position exacte à l\'aide du récepteur satellite GPS ou des sources de localisation de réseau tels que les points d\'accès Wi-Fi et les antennes-relais. Ces services de localisation doivent être activés et disponibles sur votre appareil pour que l\'application puissent déterminer où vous vous trouvez, le cas échéant. Cette autorisation peut entraîner une utilisation accrue de la batterie."</string>
+    <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"position approximative (réseau)"</string>
+    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Permet à l\'application d\'obtenir votre position approximative. Celle-ci est fournie par des services de localisation sur la base des sources de localisation de réseau tels que les points d\'accès Wi-Fi et les antennes-relais. Ces services de localisation doivent être activés et disponibles sur votre appareil pour que l\'application puisse déterminer où vous vous trouvez de façon approximative, le cas échéant."</string>
+    <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"accéder à SurfaceFlinger"</string>
+    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Permet à l\'application d\'utiliser les fonctionnalités de bas niveau de SurfaceFlinger."</string>
+    <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"lire la mémoire tampon graphique"</string>
+    <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Permet à l\'application de lire le contenu de la mémoire tampon graphique."</string>
+    <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"configurer les écrans Wi-Fi"</string>
+    <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permet à l\'application de configurer des écrans Wi-Fi et de s\'y connecter."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"contrôler les écrans Wi-Fi"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Permet à l\'application de contrôler les fonctionnalités de base des écrans Wi-Fi."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"capturer la sortie audio"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Autoriser l\'application à capturer et à rediriger la sortie audio."</string>
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Détection de mots clés"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Permet à l\'application de capturer de l\'audio pour la détection de mots clés. La capture peut s\'effectuer en arrière-plan, et n\'empêche pas les autres opérations de capture audio (par exemple, avec un caméscope)."</string>
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"capturer la sortie vidéo"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Autoriser l\'application à capturer et à rediriger la sortie vidéo."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"capturer la sortie vidéo sécurisée"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Autoriser l\'application à capturer et à rediriger la sortie vidéo sécurisée."</string>
+    <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"modifier vos paramètres audio"</string>
+    <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Permet à l\'application de modifier les paramètres audio généraux, tels que le volume et la sortie audio utilisée."</string>
+    <string name="permlab_recordAudio" msgid="3876049771427466323">"enregistrer fichier audio"</string>
+    <string name="permdesc_recordAudio" msgid="4906839301087980680">"Permet à l\'application d\'enregistrer des contenus audio à l\'aide du microphone. Cette autorisation lui donne la possibilité d\'enregistrer du contenu audio à tout moment sans votre consentement."</string>
+    <string name="permlab_camera" msgid="3616391919559751192">"prendre des photos et filmer des vidéos"</string>
+    <string name="permdesc_camera" msgid="8497216524735535009">"Permet à l\'application de prendre des photos et de filmer des vidéos avec l\'appareil photo. Cette autorisation lui permet d\'utiliser l\'appareil photo à tout moment sans votre consentement."</string>
+    <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"désactiver l\'indicateur d\'émission LED lorsque la caméra est en cours d\'utilisation"</string>
+    <string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"Permet à une application système préinstallée de désactiver l\'indicateur LED d\'utilisation de la caméra."</string>
+    <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"désactiver définitivement la tablette"</string>
+    <string name="permlab_brick" product="default" msgid="8337817093326370537">"désactiver définitivement le téléphone"</string>
+    <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"Permet à l\'application de désactiver définitivement la tablette. Cette fonctionnalité peut avoir des répercussions très sérieuses."</string>
+    <string name="permdesc_brick" product="default" msgid="5788903297627283099">"Permet à l\'application de désactiver définitivement le téléphone. Cette fonctionnalité peut avoir des répercussions très sérieuses."</string>
+    <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"forcer le redémarrage de la tablette"</string>
+    <string name="permlab_reboot" product="default" msgid="2898560872462638242">"forcer le redémarrage du téléphone"</string>
+    <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"Permet à l\'application de forcer le redémarrage de la tablette."</string>
+    <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"Permet à l\'application de forcer le redémarrage du téléphone."</string>
+    <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"accéder système fichiers mémoire USB"</string>
+    <string name="permlab_mount_unmount_filesystems" product="default" msgid="4402305049890953810">"accéder au système de fichiers de la carte SD"</string>
+    <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"Permet à l\'application d\'installer et de désinstaller des systèmes de fichiers pour des périphériques de stockage amovibles."</string>
+    <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"effacer la mémoire USB"</string>
+    <string name="permlab_mount_format_filesystems" product="default" msgid="262582698639274056">"effacer la carte SD"</string>
+    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"Permet à l\'application de formater le périphérique de stockage amovible."</string>
+    <string name="permlab_asec_access" msgid="3411338632002193846">"obtenir des données sur la mémoire de stockage interne"</string>
+    <string name="permdesc_asec_access" msgid="3094563844593878548">"Permet à l\'application d\'obtenir des données sur la mémoire de stockage interne."</string>
+    <string name="permlab_asec_create" msgid="6414757234789336327">"créer une mémoire de stockage interne"</string>
+    <string name="permdesc_asec_create" msgid="4558869273585856876">"Permet à l\'application de créer une mémoire de stockage interne."</string>
+    <string name="permlab_asec_destroy" msgid="526928328301618022">"détruire la mémoire de stockage interne"</string>
+    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"Permet à l\'application de détruire la mémoire de stockage interne."</string>
+    <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"monter ou démonter de la mémoire de stockage interne"</string>
+    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"Permet à l\'application de monter ou de démonter la mémoire de stockage interne."</string>
+    <string name="permlab_asec_rename" msgid="7496633954080472417">"renommer la mémoire de stockage interne"</string>
+    <string name="permdesc_asec_rename" msgid="1794757588472127675">"Permet à l\'application de renommer la mémoire de stockage interne."</string>
+    <string name="permlab_vibrate" msgid="7696427026057705834">"gérer le vibreur"</string>
+    <string name="permdesc_vibrate" msgid="6284989245902300945">"Permet à l\'application de gérer le vibreur de l\'appareil."</string>
+    <string name="permlab_flashlight" msgid="2155920810121984215">"gérer la lampe de poche"</string>
+    <string name="permdesc_flashlight" msgid="6522284794568368310">"Permet à l\'application de gérer la lampe de poche."</string>
+    <string name="permlab_manageUsb" msgid="1113453430645402723">"gérer les préférences et les autorisations des périphériques USB"</string>
+    <string name="permdesc_manageUsb" msgid="7776155430218239833">"Permet à l\'application de gérer les préférences et les autorisations des périphériques USB."</string>
+    <string name="permlab_accessMtp" msgid="4953468676795917042">"mettre en œuvre le protocole MTP"</string>
+    <string name="permdesc_accessMtp" msgid="6532961200486791570">"Permet l\'accès au pilote MTP du noyau afin de mettre en œuvre le protocole USB MTP."</string>
+    <string name="permlab_hardware_test" msgid="4148290860400659146">"tester le matériel"</string>
+    <string name="permdesc_hardware_test" msgid="6597964191208016605">"Permet à l\'application de contrôler différents périphériques à des fins de test matériel."</string>
+    <string name="permlab_callPhone" msgid="3925836347681847954">"appeler directement des numéros de téléphone"</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"Permet à l\'application d\'appeler des numéros de téléphone sans votre intervention. Cette autorisation peut entraîner des frais ou des appels imprévus et ne permet pas à l\'application d\'appeler des numéros d\'urgence. Des applications malveillantes peuvent générer des frais en passant des appels sans votre consentement."</string>
+    <string name="permlab_callPrivileged" msgid="4198349211108497879">"appeler directement tout numéro de téléphone"</string>
+    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"Permet à l\'application d\'appeler n\'importe quel numéro de téléphone, y compris les numéros d\'urgence, sans votre intervention. Des applications malveillantes peuvent passer des appels inutiles et interdits aux services d\'urgence."</string>
+    <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"lancer directement la configuration de la tablette CDMA"</string>
+    <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"démarrer directement la configuration du téléphone CDMA"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"Permet à l\'application de lancer le déploiement CDMA. Des applications malveillantes sont susceptibles de le lancer inutilement."</string>
+    <string name="permlab_locationUpdates" msgid="7785408253364335740">"contrôler les notifications de mise à jour de la position géographique"</string>
+    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Permet à l\'application d\'activer ou de désactiver les notifications de mise à jour de la position à partir du signal radio. Les applications standards ne doivent pas utiliser cette fonctionnalité."</string>
+    <string name="permlab_checkinProperties" msgid="7855259461268734914">"accéder aux propriétés d\'enregistrement"</string>
+    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Permet à l\'application d\'obtenir des droits d\'accès en lecture et en écriture pour les propriétés envoyées par le service d\'enregistrement. Les applications standards ne doivent pas utiliser cette fonctionnalité."</string>
+    <string name="permlab_bindGadget" msgid="776905339015863471">"choisir les widgets"</string>
+    <string name="permdesc_bindGadget" msgid="8261326938599049290">"Permet à l\'application d\'indiquer au système les widgets qui peuvent être utilisés par les applications. Une application disposant de cette autorisation peut accorder à d\'autres applications l\'accès à des données personnelles. Les applications standards ne doivent pas utiliser cette fonctionnalité."</string>
+    <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"modifier l\'état du téléphone"</string>
+    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Permet à l\'application de contrôler les fonctionnalités de téléphonie de l\'appareil. Une application disposant de cette autorisation peut, par exemple, basculer d\'un réseau à l\'autre et activer ou désactiver le signal radio du téléphone à votre insu."</string>
+    <string name="permlab_readPhoneState" msgid="9178228524507610486">"voir l\'état et l\'identité du téléphone"</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permet à l\'application d\'accéder aux fonctionnalités téléphoniques de l\'appareil. Cette autorisation permet à l\'application de déterminer le numéro de téléphone et les identifiants de l\'appareil, si un appel est actif et le numéro distant connecté par un appel."</string>
+    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"empêcher la tablette de passer en mode veille"</string>
+    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"empêcher le téléphone de passer en mode veille"</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Permet à l\'application d\'empêcher la tablette de passer en mode veille."</string>
+    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Permet à l\'application d\'empêcher le téléphone de passer en mode veille."</string>
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"transmettre des signaux infrarouges"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Permet à l\'application d\'utiliser l\'émetteur infrarouge de la tablette."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Permet à l\'application d\'utiliser l\'émetteur infrarouge du téléphone."</string>
+    <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"éteindre ou allumer la tablette"</string>
+    <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"éteindre ou allumer le téléphone"</string>
+    <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Permet à l\'application d\'éteindre et d\'allumer la tablette."</string>
+    <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"Permet à l\'application d\'éteindre et d\'allumer le téléphone."</string>
+    <string name="permlab_factoryTest" msgid="3715225492696416187">"exécuter en mode test d\'usine"</string>
+    <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"Permet d\'exécuter une application en mode test fabricant de faible niveau, autorisant ainsi l\'accès complet à la tablette. Cette fonctionnalité est uniquement disponible lorsque la tablette est en mode test fabricant."</string>
+    <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"Permet d\'exécuter en tant que test fabricant de faible niveau en autorisant l\'accès au matériel du téléphone. Cette fonctionnalité est uniquement disponible lorsque le téléphone est en mode de test fabricant."</string>
+    <string name="permlab_setWallpaper" msgid="6627192333373465143">"définir le fond d\'écran"</string>
+    <string name="permdesc_setWallpaper" msgid="7373447920977624745">"Permet à l\'application de définir le fond d\'écran du système."</string>
+    <string name="permlab_setWallpaperHints" msgid="3278608165977736538">"modifier la taille du fond d\'écran"</string>
+    <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Permet à l\'application de définir les bulles d\'aide concernant la taille du fond d\'écran du système."</string>
+    <string name="permlab_masterClear" msgid="2315750423139697397">"réinitialiser les paramètres d\'usine du système"</string>
+    <string name="permdesc_masterClear" msgid="3665380492633910226">"Permet à l\'application de rétablir la configuration d\'usine du système. Toutes les données, ainsi que les paramètres et les applications installées sont alors effacés."</string>
+    <string name="permlab_setTime" msgid="2021614829591775646">"définir l\'heure"</string>
+    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"Permet à l\'application de modifier l\'heure de la tablette."</string>
+    <string name="permdesc_setTime" product="default" msgid="1855702730738020">"Permet à l\'application de modifier l\'heure du téléphone."</string>
+    <string name="permlab_setTimeZone" msgid="2945079801013077340">"définir le fuseau horaire"</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Permet à l\'application de modifier le fuseau horaire de la tablette."</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Permet à l\'application de modifier le fuseau horaire du téléphone."</string>
+    <string name="permlab_accountManagerService" msgid="4829262349691386986">"agir en tant que service AccountManagerService"</string>
+    <string name="permdesc_accountManagerService" msgid="1948455552333615954">"Permet à l\'application d\'appeler le service AccountAuthenticators."</string>
+    <string name="permlab_getAccounts" msgid="1086795467760122114">"rechercher des comptes sur l\'appareil"</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Permet à l\'application d\'obtenir la liste des comptes connus par la tablette. Il peut s\'agir de n\'importe quel compte créé par les applications que vous avez installées."</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Permet à l\'application d\'obtenir la liste des comptes connus par le téléphone. Il peut s\'agir de n\'importe quel compte créé par les applications que vous avez installées."</string>
+    <string name="permlab_authenticateAccounts" msgid="5265908481172736933">"créer des comptes et définir des mots de passe"</string>
+    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"Permet à l\'application d\'utiliser les fonctionnalités d\'authentification de compte du service AccountManager, y compris pour créer des comptes, et obtenir et définir les mots de passe associés."</string>
+    <string name="permlab_manageAccounts" msgid="4983126304757177305">"ajouter ou supprimer des comptes"</string>
+    <string name="permdesc_manageAccounts" msgid="8698295625488292506">"Permet à l\'application d\'effectuer certaines opérations, par exemple d\'ajouter ou de supprimer des comptes et d\'effacer les mots de passe associés."</string>
+    <string name="permlab_useCredentials" msgid="235481396163877642">"utiliser les comptes sur l\'appareil"</string>
+    <string name="permdesc_useCredentials" msgid="7984227147403346422">"Permet à l\'application de demander des jetons d\'authentification."</string>
+    <string name="permlab_accessNetworkState" msgid="4951027964348974773">"afficher les connexions réseau"</string>
+    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Permet à l\'application d\'accéder à des détails concernant les connexions réseau, comme les réseaux existants et connectés."</string>
+    <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"bénéficier d\'un accès complet au réseau"</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Permet à l\'application de créer des interfaces de connexion réseau et d\'utiliser des protocoles réseau personnalisés. Le navigateur et d\'autres applications permettent d\'envoyer des données sur Internet. Cette autorisation n\'est donc pas nécessaire pour envoyer des données sur Internet."</string>
+    <string name="permlab_writeApnSettings" msgid="505660159675751896">"changer ou intercepter les paramètres et le trafic du réseau"</string>
+    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Permet à l\'application de modifier les paramètres réseau, ainsi que d\'intercepter et de surveiller tout le trafic réseau en vue de modifier le mandataire et le port d\'un nom de point d\'accès, par exemple. Des applications malveillantes peuvent utiliser cette fonctionnalité pour surveiller, rediriger ou modifier les paquets réseau à votre insu."</string>
+    <string name="permlab_changeNetworkState" msgid="958884291454327309">"modifier la connectivité réseau"</string>
+    <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Permet à l\'application de modifier l\'état de la connectivité réseau."</string>
+    <string name="permlab_changeTetherState" msgid="5952584964373017960">"changer la connectivité du partage de connexion"</string>
+    <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Permet à l\'application de modifier l\'état de la connectivité du partage de connexion."</string>
+    <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"modifier les paramètres d\'utilisation des données en arrière-plan"</string>
+    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Permet à l\'application de modifier les paramètres de consommation des données en arrière-plan."</string>
+    <string name="permlab_accessWifiState" msgid="5202012949247040011">"afficher les connexions Wi-Fi"</string>
+    <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Permet à l\'application d\'accéder à des détails sur les réseaux Wi-Fi afin de savoir si une connexion Wi-Fi est activée et pour connaître le nom des appareils connectés au Wi-Fi, par exemple."</string>
+    <string name="permlab_changeWifiState" msgid="6550641188749128035">"activer/désactiver la connexion Wi-Fi"</string>
+    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Permet à l\'application de se connecter à des points d\'accès Wi-Fi, de s\'en déconnecter et de modifier la configuration de l\'appareil pour les réseaux Wi-Fi."</string>
+    <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"autoriser la réception de données en mode Wi-Fi multidiffusion"</string>
+    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Permet à l\'application de recevoir des paquets envoyés à tous les appareils (et pas seulement à votre tablette) d\'un réseau Wi-Fi qui utilise des adresses de multidiffusion. Cette autorisation entraîne une consommation d\'énergie supérieure au mode de diffusion simple."</string>
+    <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Permet à l\'application de recevoir des paquets envoyés à tous les appareils (et pas seulement à votre téléphone) d\'un réseau Wi-Fi qui utilise des adresses de multidiffusion. Cette autorisation entraîne une consommation d\'énergie supérieure au mode de diffusion simple."</string>
+    <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"accéder aux paramètres Bluetooth"</string>
+    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Permet à l\'application de configurer la tablette Bluetooth locale, d\'identifier des appareils distants et de les associer à la tablette."</string>
+    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Permet à l\'application de configurer le téléphone Bluetooth local, d\'identifier des appareils distants et de les associer au téléphone."</string>
+    <string name="permlab_accessWimaxState" msgid="4195907010610205703">"se connecter au réseau WiMAX et s\'en déconnecter"</string>
+    <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"Permet à l\'application de déterminer si le WiMAX est activé et d\'obtenir des détails sur tous les réseaux WiMAX connectés."</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Modifier l\'état du WiMAX"</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Permet à l\'application de connecter la tablette aux réseaux WiMAX et de l\'en déconnecter."</string>
+    <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"Permet à l\'application de connecter le téléphone aux réseaux WiMAX et de l\'en déconnecter."</string>
+    <string name="permlab_bluetooth" msgid="6127769336339276828">"s\'associer à des appareils Bluetooth"</string>
+    <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Permet à l\'application d\'accéder à la configuration du Bluetooth sur la tablette, et d\'établir et accepter des connexions avec les appareils associés."</string>
+    <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Permet à l\'application d\'accéder à la configuration du Bluetooth sur le téléphone, et d\'établir et accepter des connexions avec les appareils associés."</string>
+    <string name="permlab_nfc" msgid="4423351274757876953">"gérer la communication en champ proche"</string>
+    <string name="permdesc_nfc" msgid="7120611819401789907">"Permet à l\'application de communiquer avec des bornes, des cartes et des lecteurs compatibles avec la technologie NFC (communication en champ proche)."</string>
+    <string name="permlab_disableKeyguard" msgid="3598496301486439258">"désactiver le verrouillage de l\'écran"</string>
+    <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Permet à l\'application de désactiver le verrouillage des touches et toute mesure de sécurité par mot de passe associée. Par exemple, votre téléphone désactive le verrouillage des touches lorsque vous recevez un appel, puis le réactive lorsque vous raccrochez."</string>
+    <string name="permlab_readSyncSettings" msgid="6201810008230503052">"lire les paramètres de synchronisation"</string>
+    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Permet à l\'application d\'accéder aux paramètres de synchronisation d\'un compte. Par exemple, cette autorisation peut permettre de déterminer si l\'application Contacts est synchronisée avec un compte ou non."</string>
+    <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"activer ou désactiver la synchronisation"</string>
+    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Permet à une application de modifier les paramètres de synchronisation d\'un compte. Cette autorisation peut, par exemple, être utilisée pour activer la synchronisation de l\'application Contacts avec un compte."</string>
+    <string name="permlab_readSyncStats" msgid="7396577451360202448">"lire les statistiques de synchronisation"</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Permet à une application d\'accéder aux statistiques de synchronisation d\'un compte, y compris l\'historique des événements de synchronisation et le volume de données synchronisées."</string>
+    <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"lire les flux auxquels vous êtes abonné"</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Permet à l\'application d\'obtenir des données sur les flux en cours de synchronisation."</string>
+    <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"modifier les flux auxquels vous êtes abonné"</string>
+    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"Permet à l\'application de modifier les flux en cours de synchronisation. Des applications malveillantes peuvent utiliser cette fonctionnalité pour modifier vos flux synchronisés."</string>
+    <string name="permlab_readDictionary" msgid="4107101525746035718">"voir les termes ajoutés au dictionnaire personnel"</string>
+    <string name="permdesc_readDictionary" msgid="659614600338904243">"Permet à l\'application d\'accéder aux mots, noms et expressions que l\'utilisateur a pu enregistrer dans son dictionnaire personnel."</string>
+    <string name="permlab_writeDictionary" msgid="2183110402314441106">"ajouter des mots au dictionnaire personnel"</string>
+    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Permet à l\'application d\'enregistrer de nouveaux mots dans le dictionnaire personnel de l\'utilisateur."</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"tester l\'accès à la mémoire de stockage protégée"</string>
+    <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"tester l\'accès à la mémoire de stockage protégée"</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"Permet à l\'application de tester une autorisation pour la mémoire de stockage USB qui sera ensuite proposée sur les futurs appareils."</string>
+    <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"Permet à l\'application de tester une autorisation pour la carte SD qui sera ensuite proposée sur les futurs appareils."</string>
+    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"modifier ou supprimer le contenu de la mémoire USB"</string>
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"modifier ou supprimer le contenu de la carte SD"</string>
+    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Permet à l\'application de modifier le contenu de la mémoire de stockage USB."</string>
+    <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Permet à l\'application de modifier le contenu de la carte SD."</string>
+    <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modifier ou supprimer le contenu de la mémoire de stockage interne du support"</string>
+    <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Permet à l\'application de modifier le contenu de la mémoire de stockage multimédia interne."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"gérer stockage des documents"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Permet à l\'application de gérer le stockage des documents."</string>
+    <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"accéder stock. ext. tous utilis."</string>
+    <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Permet à l\'application d\'accéder à la mémoire de stockage externe pour tous les utilisateurs."</string>
+    <string name="permlab_cache_filesystem" msgid="5656487264819669824">"accéder au système de fichiers en cache"</string>
+    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Permet à l\'application d\'obtenir des droits en lecture et en écriture pour le système de fichiers du cache."</string>
+    <string name="permlab_use_sip" msgid="5986952362795870502">"faire et recevoir des appels Internet"</string>
+    <string name="permdesc_use_sip" msgid="4717632000062674294">"Permet à l\'application d\'utiliser le service SIP pour faire ou recevoir des appels Internet."</string>
+    <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"lire l\'historique d\'utilisation de réseaux"</string>
+    <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"Permet à l\'application de lire l\'historique d\'utilisation de réseaux et d\'applications particuliers."</string>
+    <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"gérer les politiques du réseau"</string>
+    <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Permet à l\'application de gérer les politiques du réseau et de définir celles propres à l\'application"</string>
+    <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"modifier le système d\'analyse de l\'utilisation du réseau"</string>
+    <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Permet à l\'application de modifier le système d\'analyse de l\'utilisation du réseau par les autres applications. Les applications standards ne doivent pas utiliser cette fonctionnalité."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"modifier les marques d\'interface de connexion"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Permet à l\'application de modifier les marques d\'interface de connexion pour le routage"</string>
+    <string name="permlab_accessNotifications" msgid="7673416487873432268">"accéder aux notifications"</string>
+    <string name="permdesc_accessNotifications" msgid="458457742683431387">"Permet aux applications de récupérer, d\'examiner et d\'autoriser les notifications, y compris celles envoyées par d\'autres applications."</string>
+    <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"s\'associer à l\'interface de niveau supérieur d\'un service d\'écoute des notifications"</string>
+    <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Permet à l\'application de s\'associer à l\'interface de niveau supérieur d\'un service d\'écoute des notifications. Ne devrait jamais être nécessaire pour les applications normales."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"faire appel à l\'application de configuration du fournisseur de services"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Permet à l\'application autorisée de faire appel à l\'application de configuration fournie par le fournisseur de services. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"détecter des observations sur les conditions du réseau"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permet à une application de détecter les observations sur les conditions du réseau. Ne devrait jamais être nécessaire pour les applications standards."</string>
+    <string name="policylab_limitPassword" msgid="4497420728857585791">"Définir les règles du mot de passe"</string>
+    <string name="policydesc_limitPassword" msgid="3252114203919510394">"Choisir le nombre et le type de caractères autorisés dans les mots de passe de déverrouillage de l\'écran"</string>
+    <string name="policylab_watchLogin" msgid="914130646942199503">"Gérer les tentatives de déverrouillage de l\'écran"</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Contrôler le nombre de mots de passe incorrects saisis pour le déverrouillage de l\'écran, puis verrouiller la tablette ou effacer toutes ses données si le nombre maximal de tentatives de saisie du mot de passe est atteint"</string>
+    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Contrôler le nombre de mots de passe incorrects saisis pour le déverrouillage de l\'écran, puis verrouille le téléphone ou efface toutes ses données si le nombre maximal de tentatives de saisie du mot de passe est atteint."</string>
+    <string name="policylab_resetPassword" msgid="2620077191242688955">"Modifier le mot de passe de déverrouillage de l\'écran"</string>
+    <string name="policydesc_resetPassword" msgid="605963962301904458">"Modifier le mot de passe de déverrouillage de l\'écran"</string>
+    <string name="policylab_forceLock" msgid="2274085384704248431">"Verrouiller l\'écran"</string>
+    <string name="policydesc_forceLock" msgid="1141797588403827138">"Gérer le mode et les conditions de verrouillage de l\'écran"</string>
+    <string name="policylab_wipeData" msgid="3910545446758639713">"Effacer toutes les données"</string>
+    <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Effacer les données de la tablette sans avertissement, en rétablissant la configuration d\'usine"</string>
+    <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Effacer les données du téléphone sans avertissement, en rétablissant la configuration d\'usine"</string>
+    <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Définir le serveur mandataire global du mobile"</string>
+    <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Indiquer le serveur mandataire global à utiliser pour ce mobile lorsque les règles sont activées. Seul l\'administrateur principal du mobile peut définir le serveur mandataire global utilisé."</string>
+    <string name="policylab_expirePassword" msgid="885279151847254056">"Définir exp. mot passe verr."</string>
+    <string name="policydesc_expirePassword" msgid="1729725226314691591">"Contrôler la fréquence de modification du mot de passe de verrouillage de l\'écran"</string>
+    <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Définir cryptage du stockage"</string>
+    <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"Exiger le chiffrement des données d\'application stockées"</string>
+    <string name="policylab_disableCamera" msgid="6395301023152297826">"Désactiver les appareils photo"</string>
+    <string name="policydesc_disableCamera" msgid="2306349042834754597">"Empêcher l\'utilisation de tous les appareils photos"</string>
+    <string name="policylab_disableKeyguardFeatures" msgid="266329104542638802">"Désact. fonct. si protec. clav."</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="3467082272186534614">"Empêcher l\'utilisation de certaines fonctionnalités lorsque la protection du clavier est activée"</string>
+  <string-array name="phoneTypes">
+    <item msgid="8901098336658710359">"Domicile"</item>
+    <item msgid="869923650527136615">"Mobile"</item>
+    <item msgid="7897544654242874543">"Travail"</item>
+    <item msgid="1103601433382158155">"Télécopieur professionnel"</item>
+    <item msgid="1735177144948329370">"Télécopieur personnel"</item>
+    <item msgid="603878674477207394">"Téléavertisseur"</item>
+    <item msgid="1650824275177931637">"Autre"</item>
+    <item msgid="9192514806975898961">"Personnaliser"</item>
+  </string-array>
+  <string-array name="emailAddressTypes">
+    <item msgid="8073994352956129127">"Domicile"</item>
+    <item msgid="7084237356602625604">"Travail"</item>
+    <item msgid="1112044410659011023">"Autre"</item>
+    <item msgid="2374913952870110618">"Personnaliser"</item>
+  </string-array>
+  <string-array name="postalAddressTypes">
+    <item msgid="6880257626740047286">"Domicile"</item>
+    <item msgid="5629153956045109251">"Travail"</item>
+    <item msgid="4966604264500343469">"Autre"</item>
+    <item msgid="4932682847595299369">"Personnaliser"</item>
+  </string-array>
+  <string-array name="imAddressTypes">
+    <item msgid="1738585194601476694">"Domicile"</item>
+    <item msgid="1359644565647383708">"Travail"</item>
+    <item msgid="7868549401053615677">"Autre"</item>
+    <item msgid="3145118944639869809">"Personnaliser"</item>
+  </string-array>
+  <string-array name="organizationTypes">
+    <item msgid="7546335612189115615">"Travail"</item>
+    <item msgid="4378074129049520373">"Autre"</item>
+    <item msgid="3455047468583965104">"Personnaliser"</item>
+  </string-array>
+  <string-array name="imProtocols">
+    <item msgid="8595261363518459565">"AIM"</item>
+    <item msgid="7390473628275490700">"Windows Live"</item>
+    <item msgid="7882877134931458217">"Yahoo"</item>
+    <item msgid="5035376313200585242">"Skype"</item>
+    <item msgid="7532363178459444943">"QQ"</item>
+    <item msgid="3713441034299660749">"Google Talk"</item>
+    <item msgid="2506857312718630823">"ICQ"</item>
+    <item msgid="1648797903785279353">"Jabber"</item>
+  </string-array>
+    <string name="phoneTypeCustom" msgid="1644738059053355820">"Personnaliser"</string>
+    <string name="phoneTypeHome" msgid="2570923463033985887">"Domicile"</string>
+    <string name="phoneTypeMobile" msgid="6501463557754751037">"Mobile"</string>
+    <string name="phoneTypeWork" msgid="8863939667059911633">"Travail"</string>
+    <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Télécopieur professionnel"</string>
+    <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Télécopieur personnel"</string>
+    <string name="phoneTypePager" msgid="7582359955394921732">"Téléavertisseur"</string>
+    <string name="phoneTypeOther" msgid="1544425847868765990">"Autre"</string>
+    <string name="phoneTypeCallback" msgid="2712175203065678206">"Rappel"</string>
+    <string name="phoneTypeCar" msgid="8738360689616716982">"Véhicule"</string>
+    <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Téléphone professionnel principal"</string>
+    <string name="phoneTypeIsdn" msgid="8022453193171370337">"RNIS"</string>
+    <string name="phoneTypeMain" msgid="6766137010628326916">"Principal"</string>
+    <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Autre télécopieur"</string>
+    <string name="phoneTypeRadio" msgid="4093738079908667513">"Satellite"</string>
+    <string name="phoneTypeTelex" msgid="3367879952476250512">"Télex"</string>
+    <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY/ATS (malentendants)"</string>
+    <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Cellulaire professionnel"</string>
+    <string name="phoneTypeWorkPager" msgid="649938731231157056">"Téléavertisseur professionnel"</string>
+    <string name="phoneTypeAssistant" msgid="5596772636128562884">"Assistant"</string>
+    <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string>
+    <string name="eventTypeCustom" msgid="7837586198458073404">"Personnaliser"</string>
+    <string name="eventTypeBirthday" msgid="2813379844211390740">"Date de naissance"</string>
+    <string name="eventTypeAnniversary" msgid="3876779744518284000">"Anniversaire"</string>
+    <string name="eventTypeOther" msgid="7388178939010143077">"Autre"</string>
+    <string name="emailTypeCustom" msgid="8525960257804213846">"Personnaliser"</string>
+    <string name="emailTypeHome" msgid="449227236140433919">"Domicile"</string>
+    <string name="emailTypeWork" msgid="3548058059601149973">"Travail"</string>
+    <string name="emailTypeOther" msgid="2923008695272639549">"Autre"</string>
+    <string name="emailTypeMobile" msgid="119919005321166205">"Mobile"</string>
+    <string name="postalTypeCustom" msgid="8903206903060479902">"Personnaliser"</string>
+    <string name="postalTypeHome" msgid="8165756977184483097">"Domicile"</string>
+    <string name="postalTypeWork" msgid="5268172772387694495">"Travail"</string>
+    <string name="postalTypeOther" msgid="2726111966623584341">"Autre"</string>
+    <string name="imTypeCustom" msgid="2074028755527826046">"Personnaliser"</string>
+    <string name="imTypeHome" msgid="6241181032954263892">"Domicile"</string>
+    <string name="imTypeWork" msgid="1371489290242433090">"Travail"</string>
+    <string name="imTypeOther" msgid="5377007495735915478">"Autre"</string>
+    <string name="imProtocolCustom" msgid="6919453836618749992">"Personnaliser"</string>
+    <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string>
+    <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string>
+    <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">"Conversations"</string>
+    <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">"Travail"</string>
+    <string name="orgTypeOther" msgid="3951781131570124082">"Autre"</string>
+    <string name="orgTypeCustom" msgid="225523415372088322">"Personnaliser"</string>
+    <string name="relationTypeCustom" msgid="3542403679827297300">"Personnaliser"</string>
+    <string name="relationTypeAssistant" msgid="6274334825195379076">"Assistant"</string>
+    <string name="relationTypeBrother" msgid="8757913506784067713">"Frère"</string>
+    <string name="relationTypeChild" msgid="1890746277276881626">"Enfant"</string>
+    <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"Compagne/Compagnon"</string>
+    <string name="relationTypeFather" msgid="5228034687082050725">"Père"</string>
+    <string name="relationTypeFriend" msgid="7313106762483391262">"Ami(e)"</string>
+    <string name="relationTypeManager" msgid="6365677861610137895">"Gestionnaire"</string>
+    <string name="relationTypeMother" msgid="4578571352962758304">"Mère"</string>
+    <string name="relationTypeParent" msgid="4755635567562925226">"Parent"</string>
+    <string name="relationTypePartner" msgid="7266490285120262781">"Partenaire"</string>
+    <string name="relationTypeReferredBy" msgid="101573059844135524">"Recommandé par"</string>
+    <string name="relationTypeRelative" msgid="1799819930085610271">"Proche"</string>
+    <string name="relationTypeSister" msgid="1735983554479076481">"Sœur"</string>
+    <string name="relationTypeSpouse" msgid="394136939428698117">"Conjoint(e)"</string>
+    <string name="sipAddressTypeCustom" msgid="2473580593111590945">"Personnaliser"</string>
+    <string name="sipAddressTypeHome" msgid="6093598181069359295">"Domicile"</string>
+    <string name="sipAddressTypeWork" msgid="6920725730797099047">"Travail"</string>
+    <string name="sipAddressTypeOther" msgid="4408436162950119849">"Autre"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Saisissez le NIP."</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Saisissez la clé PUK et le nouveau NIP."</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Clé PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Nouveau NIP"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Appuyer pour saisir mot passe"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Saisissez le mot de passe pour déverrouiller le clavier."</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Saisissez le NIP pour déverrouiller le clavier."</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"NIP erroné."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Pour déverrouiller le téléphone, appuyez sur \"Menu\", puis sur 0."</string>
+    <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"Numéro d\'urgence"</string>
+    <string name="lockscreen_carrier_default" msgid="8963839242565653192">"Aucun service"</string>
+    <string name="lockscreen_screen_locked" msgid="7288443074806832904">"Écran verrouillé"</string>
+    <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Appuyez sur \"Menu\" pour débloquer le téléphone ou appeler un numéro d\'urgence."</string>
+    <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Appuyez sur \"Menu\" pour déverrouiller l\'appareil."</string>
+    <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Dessinez un schéma pour déverrouiller le téléphone"</string>
+    <string name="lockscreen_emergency_call" msgid="5347633784401285225">"Appel d\'urgence"</string>
+    <string name="lockscreen_return_to_call" msgid="5244259785500040021">"Retour à l\'appel"</string>
+    <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"C\'est exact!"</string>
+    <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Réessayer"</string>
+    <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Réessayer"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Nombre maximal autorisé de tentatives Face Unlock atteint."</string>
+    <string name="lockscreen_plugged_in" msgid="8057762828355572315">"En charge (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
+    <string name="lockscreen_charged" msgid="321635745684060624">"Chargé"</string>
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_low_battery" msgid="1482873981919249740">"Branchez votre chargeur."</string>
+    <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"Aucune carte SIM"</string>
+    <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Aucune carte SIM n\'est insérée dans la tablette."</string>
+    <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"Aucune carte SIM n\'est insérée dans le téléphone."</string>
+    <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Insérez une carte SIM."</string>
+    <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Carte SIM absente ou illisible. Veuillez insérer une carte SIM."</string>
+    <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Carte SIM inutilisable."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Votre carte SIM a été définitivement désactivée.\n Veuillez contacter votre opérateur de téléphonie mobile pour en obtenir une autre."</string>
+    <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Bouton pour revenir au titre précédent"</string>
+    <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Bouton pour atteindre le titre suivant"</string>
+    <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Bouton de pause"</string>
+    <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Bouton de lecture"</string>
+    <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Bouton d\'arrêt"</string>
+    <string name="emergency_calls_only" msgid="6733978304386365407">"Appels d\'urgence uniquement"</string>
+    <string name="lockscreen_network_locked_message" msgid="143389224986028501">"Réseau verrouillé"</string>
+    <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"La carte SIM est verrouillée par clé PUK."</string>
+    <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Veuillez consulter le guide utilisateur ou contacter le service à la clientèle."</string>
+    <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"La carte SIM est verrouillée."</string>
+    <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Déverrouillage de la carte SIM en cours…"</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Vous avez saisi un mot de passe incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Vous avez saisi un NIP incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Au bout de <xliff:g id="NUMBER_1">%d</xliff:g> échecs supplémentaires, vous devrez déverrouiller votre tablette à l\'aide de votre identifiant Google.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Au bout de <xliff:g id="NUMBER_1">%d</xliff:g> échecs supplémentaires, vous devrez déverrouiller votre téléphone à l\'aide de votre identifiant Google.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Sa configuration d\'usine va être rétablie."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Sa configuration d\'usine va être rétablie."</string>
+    <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Veuillez réessayer dans <xliff:g id="NUMBER">%d</xliff:g> secondes."</string>
+    <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Schéma oublié?"</string>
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Déverrouillage du compte"</string>
+    <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"Nombre maximal de tentatives de déverrouillage par schéma dépassé."</string>
+    <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"Pour déverrouiller l\'appareil, connectez-vous avec votre compte Google."</string>
+    <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Nom d\'utilisateur (courriel)"</string>
+    <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Mot de passe"</string>
+    <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Connexion"</string>
+    <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nom d\'utilisateur ou mot de passe erroné."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Vous avez oublié votre nom d\'utilisateur ou votre mot de passe?\nRendez-vous sur la page "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Vérification en cours…"</string>
+    <string name="lockscreen_unlock_label" msgid="737440483220667054">"Déverrouiller"</string>
+    <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Son activé"</string>
+    <string name="lockscreen_sound_off_label" msgid="996822825154319026">"Son désactivé"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Schéma commencé."</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Schéma effacé."</string>
+    <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Cellule ajoutée."</string>
+    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Schéma terminé."</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d sur %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Ajouter un widget"</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Vide"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Développement de la zone de déverrouillage"</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Réduction de la zone de déverrouillage"</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>"</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Sélecteur d\'utilisateur"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"État"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Caméra"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Commandes multimédias"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Début de la réorganisation des widgets"</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Fin de la réorganisation des widgets"</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Le widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> a été supprimé."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Développer la zone de déverrouillage"</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Déverrouillage en faisant glisser votre doigt sur l\'écran"</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Déverrouillage par schéma"</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Déverrouillage par reconnaissance faciale"</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Déverrouillage par NIP"</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Déverrouillage par mot de passe"</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Zone du schéma"</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Zone où faire glisser votre doigt sur l\'écran"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="granularity_label_character" msgid="7336470535385009523">"caractère"</string>
+    <string name="granularity_label_word" msgid="7075570328374918660">"mot"</string>
+    <string name="granularity_label_link" msgid="5815508880782488267">"Lié"</string>
+    <string name="granularity_label_line" msgid="5764267235026120888">"ligne"</string>
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
+    <string name="factorytest_failed" msgid="5410270329114212041">"Échec du test usine"</string>
+    <string name="factorytest_not_system" msgid="4435201656767276723">"L\'action FACTORY_TEST est uniquement prise en charge pour les paquets de données installés dans in/system/app."</string>
+    <string name="factorytest_no_action" msgid="872991874799998561">"Impossible de trouver un paquet proposant l\'action FACTORY_TEST."</string>
+    <string name="factorytest_reboot" msgid="6320168203050791643">"Redémarrer"</string>
+    <string name="js_dialog_title" msgid="1987483977834603872">"La page \"<xliff:g id="TITLE">%s</xliff:g>\" indique :"</string>
+    <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
+    <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Vous êtes sur le point de quitter cette page"</string>
+    <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Quitter cette page"</string>
+    <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Rester sur cette page"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nVoulez-vous vraiment quitter cette page?"</string>
+    <string name="save_password_label" msgid="6860261758665825069">"Confirmer"</string>
+    <string name="double_tap_toast" msgid="4595046515400268881">"Conseil : Appuyez deux fois pour faire un zoom avant ou arrière."</string>
+    <string name="autofill_this_form" msgid="4616758841157816676">"Saisie auto"</string>
+    <string name="setup_autofill" msgid="7103495070180590814">"Conf. saisie auto"</string>
+    <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
+    <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
+    <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
+    <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
+    <string name="autofill_province" msgid="2231806553863422300">"Province"</string>
+    <string name="autofill_postal_code" msgid="4696430407689377108">"Code postal"</string>
+    <string name="autofill_state" msgid="6988894195520044613">"État"</string>
+    <string name="autofill_zip_code" msgid="8697544592627322946">"Code postal"</string>
+    <string name="autofill_county" msgid="237073771020362891">"Comté"</string>
+    <string name="autofill_island" msgid="4020100875984667025">"Île"</string>
+    <string name="autofill_district" msgid="8400735073392267672">"District"</string>
+    <string name="autofill_department" msgid="5343279462564453309">"Département"</string>
+    <string name="autofill_prefecture" msgid="2028499485065800419">"Préfecture"</string>
+    <string name="autofill_parish" msgid="8202206105468820057">"Paroisse"</string>
+    <string name="autofill_area" msgid="3547409050889952423">"Zone"</string>
+    <string name="autofill_emirate" msgid="2893880978835698818">"Émirat"</string>
+    <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"voir l\'historique et les favoris Web"</string>
+    <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Permet à l\'application d\'accéder à l\'historique de toutes les URL auxquelles le navigateur a accédé, ainsi qu\'à l\'ensemble des favoris du navigateur. Remarque : Il est possible que cette autorisation ne soit pas appliquée par les navigateurs tiers ni par d\'autres applications permettant de naviguer sur le Web."</string>
+    <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"modifier l\'historique et les favoris Web"</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Permet à l\'application de modifier l\'historique du navigateur ou les favoris enregistrés sur votre tablette. Cette autorisation peut lui permettre d\'effacer ou de modifier les données du navigateur. Remarque : il est possible que cette autorisation ne soit pas appliquée par les navigateurs tiers ni par d\'autres applications permettant de naviguer sur le Web."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Permet à l\'application de modifier l\'historique du navigateur ou les favoris enregistrés sur votre téléphone. Cette autorisation peut lui permettre d\'effacer ou de modifier les données du navigateur. Remarque : il est possible que cette autorisation ne soit pas appliquée par les navigateurs tiers ni par d\'autres applications permettant de naviguer sur le Web."</string>
+    <string name="permlab_setAlarm" msgid="1379294556362091814">"définir une alarme"</string>
+    <string name="permdesc_setAlarm" msgid="316392039157473848">"Permet à l\'application de régler la sonnerie d\'une fonction de réveil installée sur votre appareil. Cette fonctionnalité n\'est pas compatible avec toutes les applications de réveils."</string>
+    <string name="permlab_addVoicemail" msgid="5525660026090959044">"ajouter des messages vocaux"</string>
+    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Permet à l\'application d\'ajouter des messages à votre messagerie vocale."</string>
+    <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"modifier les autorisations de géolocalisation du navigateur"</string>
+    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Permet à l\'application de modifier les autorisations de géolocalisation du navigateur. Des applications malveillantes peuvent exploiter cette fonctionnalité pour permettre l\'envoi de données de localisation à des sites Web arbitraires."</string>
+    <string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"vérifier les paquets"</string>
+    <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"Permet à l\'application de vérifier qu\'un paquet peut être installé."</string>
+    <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"s\'associer à un vérificateur de paquet"</string>
+    <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Permet à l\'application autorisée d\'effectuer des requêtes de vérificateurs de paquet. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
+    <string name="permlab_serialPort" msgid="546083327654631076">"accéder aux ports série"</string>
+    <string name="permdesc_serialPort" msgid="2991639985224598193">"Permet à l\'application autorisée d\'accéder aux ports série avec l\'API SerialManager."</string>
+    <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"accès externe aux fournisseurs de contenu"</string>
+    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Permettre à l\'application titulaire d\'accéder à des fournisseurs de contenu depuis l\'interface de commande. Les applications standards ne devraient jamais avoir recours à cette autorisation."</string>
+    <string name="permlab_updateLock" msgid="3527558366616680889">"déconseiller les mises à jour automatiques de l\'appareil"</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"Permet à l\'application autorisée d\'indiquer au système le moment opportun pour un redémarrage non interactif en vue de la mise à jour de l\'appareil."</string>
+    <string name="save_password_message" msgid="767344687139195790">"Voulez-vous que le navigateur se souvienne de ce mot de passe?"</string>
+    <string name="save_password_notnow" msgid="6389675316706699758">"Pas maintenant"</string>
+    <string name="save_password_remember" msgid="6491879678996749466">"Rappelez-vous"</string>
+    <string name="save_password_never" msgid="8274330296785855105">"Jamais"</string>
+    <string name="open_permission_deny" msgid="7374036708316629800">"Vous n\'êtes pas autorisé à ouvrir cette page."</string>
+    <string name="text_copied" msgid="4985729524670131385">"Le texte a été copié dans le presse-papiers."</string>
+    <string name="more_item_label" msgid="4650918923083320495">"Plus"</string>
+    <string name="prepend_shortcut_label" msgid="2572214461676015642">"Menu+"</string>
+    <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="searchview_description_search" msgid="6749826639098512120">"Recherche"</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>
+    <string name="searchview_description_voice" msgid="2453203695674994440">"Recherche vocale"</string>
+    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Activer \"Explorer au toucher\"?"</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> souhaite activer la fonctionnalité \"Explorer au toucher\". Lorsque celle-ci est activée, vous pouvez entendre ou voir les descriptions des éléments que vous sélectionnez, ou bien interagir avec la tablette en effectuant certains gestes."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> souhaite activer la fonctionnalité \"Explorer au toucher\". Lorsque celle-ci est activée, vous pouvez entendre ou voir les descriptions des éléments que vous sélectionnez, ou bien interagir avec le téléphone en effectuant certains gestes."</string>
+    <string name="oneMonthDurationPast" msgid="7396384508953779925">"Il y a 1 mois"</string>
+    <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Il y a plus d\'un mois"</string>
+  <plurals name="num_seconds_ago">
+    <item quantity="one" msgid="4869870056547896011">"il y a 1 seconde"</item>
+    <item quantity="other" msgid="3903706804349556379">"Il y a <xliff:g id="COUNT">%d</xliff:g> secondes"</item>
+  </plurals>
+  <plurals name="num_minutes_ago">
+    <item quantity="one" msgid="3306787433088810191">"Il y a 1 minute"</item>
+    <item quantity="other" msgid="2176942008915455116">"Il y a <xliff:g id="COUNT">%d</xliff:g> minutes"</item>
+  </plurals>
+  <plurals name="num_hours_ago">
+    <item quantity="one" msgid="9150797944610821849">"Il y a 1 heure"</item>
+    <item quantity="other" msgid="2467273239587587569">"il y a <xliff:g id="COUNT">%d</xliff:g> heures"</item>
+  </plurals>
+  <plurals name="last_num_days">
+    <item quantity="other" msgid="3069992808164318268">"Les <xliff:g id="COUNT">%d</xliff:g> derniers jours"</item>
+  </plurals>
+    <string name="last_month" msgid="3959346739979055432">"Le mois dernier"</string>
+    <string name="older" msgid="5211975022815554840">"Précédent"</string>
+  <plurals name="num_days_ago">
+    <item quantity="one" msgid="861358534398115820">"hier"</item>
+    <item quantity="other" msgid="2479586466153314633">"il y a <xliff:g id="COUNT">%d</xliff:g> jours"</item>
+  </plurals>
+  <plurals name="in_num_seconds">
+    <item quantity="one" msgid="2729745560954905102">"dans 1 seconde"</item>
+    <item quantity="other" msgid="1241926116443974687">"dans <xliff:g id="COUNT">%d</xliff:g> secondes"</item>
+  </plurals>
+  <plurals name="in_num_minutes">
+    <item quantity="one" msgid="8793095251325200395">"dans 1 minute"</item>
+    <item quantity="other" msgid="3330713936399448749">"dans <xliff:g id="COUNT">%d</xliff:g> minutes"</item>
+  </plurals>
+  <plurals name="in_num_hours">
+    <item quantity="one" msgid="7164353342477769999">"dans 1 heure"</item>
+    <item quantity="other" msgid="547290677353727389">"dans <xliff:g id="COUNT">%d</xliff:g> heures"</item>
+  </plurals>
+  <plurals name="in_num_days">
+    <item quantity="one" msgid="5413088743009839518">"demain"</item>
+    <item quantity="other" msgid="5109449375100953247">"dans <xliff:g id="COUNT">%d</xliff:g> jours"</item>
+  </plurals>
+  <plurals name="abbrev_num_seconds_ago">
+    <item quantity="one" msgid="1849036840200069118">"il y a 1 seconde"</item>
+    <item quantity="other" msgid="3699169366650930415">"il y a <xliff:g id="COUNT">%d</xliff:g> secondes"</item>
+  </plurals>
+  <plurals name="abbrev_num_minutes_ago">
+    <item quantity="one" msgid="6361490147113871545">"il y a 1 min"</item>
+    <item quantity="other" msgid="851164968597150710">"il y a <xliff:g id="COUNT">%d</xliff:g> minutes"</item>
+  </plurals>
+  <plurals name="abbrev_num_hours_ago">
+    <item quantity="one" msgid="4796212039724722116">"Il y a 1 h."</item>
+    <item quantity="other" msgid="6889970745748538901">"il y a <xliff:g id="COUNT">%d</xliff:g> heures"</item>
+  </plurals>
+  <plurals name="abbrev_num_days_ago">
+    <item quantity="one" msgid="8463161711492680309">"hier"</item>
+    <item quantity="other" msgid="3453342639616481191">"il y a <xliff:g id="COUNT">%d</xliff:g> jours"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_seconds">
+    <item quantity="one" msgid="5842225370795066299">"dans 1 seconde"</item>
+    <item quantity="other" msgid="5495880108825805108">"dans <xliff:g id="COUNT">%d</xliff:g> secondes"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_minutes">
+    <item quantity="one" msgid="562786149928284878">"dans 1 minute"</item>
+    <item quantity="other" msgid="4216113292706568726">"dans <xliff:g id="COUNT">%d</xliff:g> minutes"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_hours">
+    <item quantity="one" msgid="3274708118124045246">"dans 1 heure"</item>
+    <item quantity="other" msgid="3705373766798013406">"dans <xliff:g id="COUNT">%d</xliff:g> heures"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_days">
+    <item quantity="one" msgid="2178576254385739855">"demain"</item>
+    <item quantity="other" msgid="2973062968038355991">"dans <xliff:g id="COUNT">%d</xliff:g> jours"</item>
+  </plurals>
+    <string name="preposition_for_date" msgid="9093949757757445117">"le <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">"en <xliff:g id="YEAR">%s</xliff:g>"</string>
+    <string name="day" msgid="8144195776058119424">"Jour"</string>
+    <string name="days" msgid="4774547661021344602">"jours"</string>
+    <string name="hour" msgid="2126771916426189481">"heure"</string>
+    <string name="hours" msgid="894424005266852993">"heures"</string>
+    <string name="minute" msgid="9148878657703769868">"min"</string>
+    <string name="minutes" msgid="5646001005827034509">"min"</string>
+    <string name="second" msgid="3184235808021478">"s"</string>
+    <string name="seconds" msgid="3161515347216589235">"s"</string>
+    <string name="week" msgid="5617961537173061583">"semaine"</string>
+    <string name="weeks" msgid="6509623834583944518">"semaines"</string>
+    <string name="year" msgid="4001118221013892076">"an"</string>
+    <string name="years" msgid="6881577717993213522">"ans"</string>
+  <plurals name="duration_seconds">
+    <item quantity="one" msgid="6962015528372969481">"1 seconde"</item>
+    <item quantity="other" msgid="1886107766577166786">"<xliff:g id="COUNT">%d</xliff:g> secondes"</item>
+  </plurals>
+  <plurals name="duration_minutes">
+    <item quantity="one" msgid="4915414002546085617">"1 minute"</item>
+    <item quantity="other" msgid="3165187169224908775">"<xliff:g id="COUNT">%d</xliff:g>minutes"</item>
+  </plurals>
+  <plurals name="duration_hours">
+    <item quantity="one" msgid="8917467491248809972">"1 heure"</item>
+    <item quantity="other" msgid="3863962854246773930">"<xliff:g id="COUNT">%d</xliff:g> heures"</item>
+  </plurals>
+    <string name="VideoView_error_title" msgid="3534509135438353077">"Problème vidéo"</string>
+    <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Impossible de lire cette vidéo en continu sur cet appareil."</string>
+    <string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Impossible de lire la vidéo."</string>
+    <string name="VideoView_error_button" msgid="2822238215100679592">"OK"</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">"midi"</string>
+    <string name="Noon" msgid="3342127745230013127">"Midi"</string>
+    <string name="midnight" msgid="7166259508850457595">"minuit"</string>
+    <string name="Midnight" msgid="5630806906897892201">"Minuit"</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">"Tout sélectionner"</string>
+    <string name="cut" msgid="3092569408438626261">"Couper"</string>
+    <string name="copy" msgid="2681946229533511987">"Copier"</string>
+    <string name="paste" msgid="5629880836805036433">"Coller"</string>
+    <string name="replace" msgid="5781686059063148930">"Remplacer..."</string>
+    <string name="delete" msgid="6098684844021697789">"Supprimer"</string>
+    <string name="copyUrl" msgid="2538211579596067402">"Copier l\'URL"</string>
+    <string name="selectTextMode" msgid="1018691815143165326">"Sélectionner du texte"</string>
+    <string name="textSelectionCABTitle" msgid="5236850394370820357">"Sélection de texte"</string>
+    <string name="addToDictionary" msgid="4352161534510057874">"Ajouter au dictionnaire"</string>
+    <string name="deleteText" msgid="6979668428458199034">"Supprimer"</string>
+    <string name="inputMethod" msgid="1653630062304567879">"Mode de saisie"</string>
+    <string name="editTextMenuTitle" msgid="4909135564941815494">"Actions sur le texte"</string>
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Espace de stockage bientôt saturé"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Il est possible que certaines fonctionnalités du système ne soient pas opérationnelles."</string>
+    <string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> en cours d\'exécution"</string>
+    <string name="app_running_notification_text" msgid="4653586947747330058">"Appuyez ici pour en savoir plus ou arrêter l\'application."</string>
+    <string name="ok" msgid="5970060430562524910">"OK"</string>
+    <string name="cancel" msgid="6442560571259935130">"Annuler"</string>
+    <string name="yes" msgid="5362982303337969312">"OK"</string>
+    <string name="no" msgid="5141531044935541497">"Annuler"</string>
+    <string name="dialog_alert_title" msgid="2049658708609043103">"Attention"</string>
+    <string name="loading" msgid="7933681260296021180">"Chargement en cours..."</string>
+    <string name="capital_on" msgid="1544682755514494298">"ACTIVÉE"</string>
+    <string name="capital_off" msgid="6815870386972805832">"DÉSACTIVÉE"</string>
+    <string name="whichApplication" msgid="4533185947064773386">"Continuer avec"</string>
+    <string name="alwaysUse" msgid="4583018368000610438">"Utiliser cette application par défaut pour cette action"</string>
+    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Pour supprimer les valeurs par défaut, accédez à Paramètres système &gt; Applications &gt; Téléchargements."</string>
+    <string name="chooseActivity" msgid="7486876147751803333">"Sélectionnez une action"</string>
+    <string name="chooseUsbActivity" msgid="6894748416073583509">"Sélectionnez une application pour le périphérique de stockage USB"</string>
+    <string name="noApplications" msgid="2991814273936504689">"Aucune application ne peut effectuer cette action."</string>
+    <string name="aerr_title" msgid="1905800560317137752"></string>
+    <string name="aerr_application" msgid="932628488013092776">"L\'application \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" s\'est arrêtée."</string>
+    <string name="aerr_process" msgid="4507058997035697579">"Le processus <xliff:g id="PROCESS">%1$s</xliff:g> s\'est interrompu."</string>
+    <string name="anr_title" msgid="4351948481459135709"></string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"L\'application <xliff:g id="APPLICATION">%2$s</xliff:g> ne répond pas.\n\nVoulez-vous quitter?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"L\'activité <xliff:g id="ACTIVITY">%1$s</xliff:g> ne répond pas.\n\nVoulez-vous quitter?"</string>
+    <string name="anr_application_process" msgid="8941757607340481057">"L\'application <xliff:g id="APPLICATION">%1$s</xliff:g> ne répond pas. Voulez-vous quitter?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Le processus <xliff:g id="PROCESS">%1$s</xliff:g> ne répond pas.\n\nVoulez-vous quitter?"</string>
+    <string name="force_close" msgid="8346072094521265605">"OK"</string>
+    <string name="report" msgid="4060218260984795706">"Signaler"</string>
+    <string name="wait" msgid="7147118217226317732">"Attendre"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"La page ne répond pas.\n \nVoulez-vous la fermer?"</string>
+    <string name="launch_warning_title" msgid="1547997780506713581">"Application redirigée"</string>
+    <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> est maintenant lancée."</string>
+    <string name="launch_warning_original" msgid="188102023021668683">"L\'application <xliff:g id="APP_NAME">%1$s</xliff:g> a été lancée initialement."</string>
+    <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Redimensionner"</string>
+    <string name="screen_compat_mode_show" msgid="4013878876486655892">"Toujours afficher"</string>
+    <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Réactivez ce mode en accédant à Paramètres système &gt; Applications &gt; Téléchargements"</string>
+    <string name="smv_application" msgid="3307209192155442829">"L\'application <xliff:g id="APPLICATION">%1$s</xliff:g> (du processus <xliff:g id="PROCESS">%2$s</xliff:g>) a enfreint ses propres règles du mode strict."</string>
+    <string name="smv_process" msgid="5120397012047462446">"Le processus <xliff:g id="PROCESS">%1$s</xliff:g> a enfreint ses propres règles du mode strict."</string>
+    <string name="android_upgrading_title" msgid="1584192285441405746">"Mise à jour d\'Android…"</string>
+    <string name="android_upgrading_apk" msgid="7904042682111526169">"Optimisation de l\'application <xliff:g id="NUMBER_0">%1$d</xliff:g> sur <xliff:g id="NUMBER_1">%2$d</xliff:g>…"</string>
+    <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Lancement des applications…"</string>
+    <string name="android_upgrading_complete" msgid="1405954754112999229">"Finalisation de la mise à jour."</string>
+    <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> en cours d\'exécution"</string>
+    <string name="heavy_weight_notification_detail" msgid="1721681741617898865">"Appuyez ici pour changer d\'application."</string>
+    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Changer d\'application?"</string>
+    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Une autre application est déjà en cours d\'exécution. Arrêtez-la avant d\'en lancer une nouvelle."</string>
+    <string name="old_app_action" msgid="493129172238566282">"Revenir à <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
+    <string name="old_app_description" msgid="2082094275580358049">"Ne pas lancer la nouvelle application"</string>
+    <string name="new_app_action" msgid="5472756926945440706">"Démarrer <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
+    <string name="new_app_description" msgid="1932143598371537340">"Arrêtez l\'ancienne application sans enregistrer."</string>
+    <string name="sendText" msgid="5209874571959469142">"Sélectionner une action pour le texte"</string>
+    <string name="volume_ringtone" msgid="6885421406845734650">"Volume de la sonnerie"</string>
+    <string name="volume_music" msgid="5421651157138628171">"Volume"</string>
+    <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"Lecture via Bluetooth"</string>
+    <string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"Sonnerie silencieuse sélectionnée"</string>
+    <string name="volume_call" msgid="3941680041282788711">"Volume des appels entrants"</string>
+    <string name="volume_bluetooth_call" msgid="2002891926351151534">"Volume d\'appels entrants sur Bluetooth"</string>
+    <string name="volume_alarm" msgid="1985191616042689100">"Volume de l\'alarme"</string>
+    <string name="volume_notification" msgid="2422265656744276715">"Volume des notifications"</string>
+    <string name="volume_unknown" msgid="1400219669770445902">"Volume"</string>
+    <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"Volume Bluetooth"</string>
+    <string name="volume_icon_description_ringer" msgid="3326003847006162496">"Volume de la sonnerie"</string>
+    <string name="volume_icon_description_incall" msgid="8890073218154543397">"Volume d\'appel"</string>
+    <string name="volume_icon_description_media" msgid="4217311719665194215">"Volume"</string>
+    <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="8129563480895990372">"Sonnerie par défaut (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <string name="ringtone_silent" msgid="7937634392408977062">"Aucune"</string>
+    <string name="ringtone_picker_title" msgid="3515143939175119094">"Sonneries"</string>
+    <string name="ringtone_unknown" msgid="5477919988701784788">"Sonnerie inconnue"</string>
+  <plurals name="wifi_available">
+    <item quantity="one" msgid="6654123987418168693">"Réseau Wi-Fi disponible"</item>
+    <item quantity="other" msgid="4192424489168397386">"Réseaux Wi-Fi disponibles"</item>
+  </plurals>
+  <plurals name="wifi_available_detailed">
+    <item quantity="one" msgid="1634101450343277345">"Réseau Wi-Fi ouvert disponible"</item>
+    <item quantity="other" msgid="7915895323644292768">"Réseaux Wi-Fi ouverts disponibles"</item>
+  </plurals>
+    <string name="wifi_available_sign_in" msgid="4029489716605255386">"Connectez-vous au réseau Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="8495155593358054676">"Se connecter au réseau"</string>
+    <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
+    <skip />
+    <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Impossible de se connecter au Wi-Fi."</string>
+    <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" dispose d\'une mauvaise connexion Internet."</string>
+    <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+    <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Lancer le Wi-Fi Direct. Cela désactive le fonctionnement du Wi-Fi client ou via un point d\'accès."</string>
+    <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Impossible d\'activer le Wi-Fi Direct."</string>
+    <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct activé"</string>
+    <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Appuyez pour accéder aux paramètres."</string>
+    <string name="accept" msgid="1645267259272829559">"Accepter"</string>
+    <string name="decline" msgid="2112225451706137894">"Refuser"</string>
+    <string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Invitation envoyée"</string>
+    <string name="wifi_p2p_invitation_to_connect_title" msgid="4958803948658533637">"Invitation à se connecter"</string>
+    <string name="wifi_p2p_from_message" msgid="570389174731951769">"De :"</string>
+    <string name="wifi_p2p_to_message" msgid="248968974522044099">"À :"</string>
+    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"Saisissez le NIP requis :"</string>
+    <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"NIP :"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"La tablette sera déconnectée du réseau Wi-Fi tant qu\'elle sera connectée à l\'appareil \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\"."</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"Le téléphone sera déconnecté du réseau Wi-Fi tant qu\'il sera connecté à l\'appareil <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
+    <string name="select_character" msgid="3365550120617701745">"Insérer un caractère"</string>
+    <string name="sms_control_title" msgid="7296612781128917719">"Envoi de messages SMS"</string>
+    <string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; envoie un grand nombre de SMS. Autorisez-vous cette application à poursuivre l\'envoi des messages?"</string>
+    <string name="sms_control_yes" msgid="3663725993855816807">"Autoriser"</string>
+    <string name="sms_control_no" msgid="625438561395534982">"Refuser"</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; souhaite envoyer un message à &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt;."</string>
+    <string name="sms_short_code_details" msgid="3492025719868078457">"Ceci "<font fgcolor="#ffffb060">"peut entraîner des frais"</font>" sur votre compte mobile."</string>
+    <string name="sms_premium_short_code_details" msgid="5523826349105123687"><font fgcolor="#ffffb060">"Ceci entraînera des frais sur votre compte mobile."</font></string>
+    <string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"Envoyer"</string>
+    <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"Annuler"</string>
+    <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"Mémoriser mon choix"</string>
+    <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"Pour modifier : Paramètres &gt; Applications"</string>
+    <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Toujours autoriser"</string>
+    <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Ne jamais autoriser"</string>
+    <string name="sim_removed_title" msgid="6227712319223226185">"Carte SIM retirée"</string>
+    <string name="sim_removed_message" msgid="2333164559970958645">"Le réseau mobile ne sera pas disponible avant le redémarrage avec une carte SIM valide insérée."</string>
+    <string name="sim_done_button" msgid="827949989369963775">"Terminé"</string>
+    <string name="sim_added_title" msgid="3719670512889674693">"Carte SIM ajoutée."</string>
+    <string name="sim_added_message" msgid="6599945301141050216">"Redémarrez votre appareil pour accéder au réseau mobile."</string>
+    <string name="sim_restart_button" msgid="4722407842815232347">"Recommencer"</string>
+    <string name="time_picker_dialog_title" msgid="8349362623068819295">"Définir l\'heure"</string>
+    <string name="date_picker_dialog_title" msgid="5879450659453782278">"Définir la date"</string>
+    <string name="date_time_set" msgid="5777075614321087758">"Paramètres"</string>
+    <string name="date_time_done" msgid="2507683751759308828">"Terminé"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff33b5e5">"NOUVEAU"</font>" :"</string>
+    <string name="perms_description_app" msgid="5139836143293299417">"Fourni par <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="no_permissions" msgid="7283357728219338112">"Aucune autorisation requise"</string>
+    <string name="perm_costs_money" msgid="4902470324142151116">"cela peut engendrer des frais"</string>
+    <string name="usb_storage_activity_title" msgid="4465055157209648641">"Mémoire de stockage de masse USB"</string>
+    <string name="usb_storage_title" msgid="5901459041398751495">"USB connectée"</string>
+    <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"Vous êtes connecté à votre ordinateur via un câble USB. Appuyez sur le bouton ci-dessous pour copier des fichiers de votre ordinateur vers la mémoire de stockage USB de votre appareil Android, ou inversement."</string>
+    <string name="usb_storage_message" product="default" msgid="805351000446037811">"Vous êtes connecté à votre ordinateur via un câble USB. Appuyez sur le bouton ci-dessous pour copier des fichiers de votre ordinateur vers la carte SD de votre appareil Android, ou inversement."</string>
+    <string name="usb_storage_button_mount" msgid="1052259930369508235">"Activer la mémoire de stockage USB"</string>
+    <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"Un problème est survenu lors de l\'utilisation de votre mémoire de stockage USB comme périphérique de stockage de masse."</string>
+    <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"Un problème est survenu lors de l\'utilisation de votre carte SD comme périphérique de stockage de masse USB."</string>
+    <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB connectée"</string>
+    <string name="usb_storage_notification_message" msgid="939822783828183763">"Appuyez ici pour copier des fichiers depuis votre ordinateur ou vers celui-ci."</string>
+    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Désactiver la mémoire de stockage USB"</string>
+    <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"Appuyez ici pour désactiver la mémoire de stockage USB."</string>
+    <string name="usb_storage_stop_title" msgid="660129851708775853">"Mémoire de stockage USB en cours d\'utilisation"</string>
+    <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"Avant de désactiver la mémoire de stockage USB, veuillez désinstaller (\"éjecter\") de votre ordinateur la mémoire de stockage USB de l\'appareil Android."</string>
+    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"Avant de désactiver la mémoire de stockage USB, veuillez désinstaller (\"éjecter\") de votre ordinateur la carte SD de votre appareil Android."</string>
+    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"Désactiver la mémoire de stockage USB"</string>
+    <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"Un problème est survenu lors de la désactivation de la mémoire de stockage USB. Assurez-vous que l\'hôte USB a bien été désinstallé, puis réessayez."</string>
+    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Activer la mémoire de stockage USB"</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Si vous activez la mémoire de stockage USB, certaines applications en cours d\'utilisation vont être fermées et risquent de rester indisponibles jusqu\'à ce que la mémoire de stockage USB soit désactivée."</string>
+    <string name="dlg_error_title" msgid="7323658469626514207">"Échec du fonctionnement de la mémoire de stockage USB."</string>
+    <string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
+    <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Connecté en tant qu\'appareil multimédia"</string>
+    <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Connecté en tant qu\'appareil photo"</string>
+    <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Connecté en tant que programme d\'installation"</string>
+    <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connecté à un accessoire USB"</string>
+    <string name="usb_notification_message" msgid="2290859399983720271">"Appuyez ici pour accéder aux autres options USB."</string>
+    <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Formater mémoire?"</string>
+    <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Formater la carte SD?"</string>
+    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Tous les fichiers stockés sur la mémoire de stockage USB vont être effacés. Cette action est irréversible."</string>
+    <string name="extmedia_format_message" product="default" msgid="14131895027543830">"Toutes les données stockées sur votre carte seront perdues."</string>
+    <string name="extmedia_format_button_format" msgid="4131064560127478695">"Mise en forme"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"Débogage USB connecté"</string>
+    <string name="adb_active_notification_message" msgid="1016654627626476142">"Appuyez pour désactiver le débogage USB."</string>
+    <string name="select_input_method" msgid="4653387336791222978">"Sélectionnez le mode de saisie"</string>
+    <string name="configure_input_methods" msgid="9091652157722495116">"Configurer les modes de saisie"</string>
+    <string name="use_physical_keyboard" msgid="6203112478095117625">"Clavier physique"</string>
+    <string name="hardware" msgid="7517821086888990278">"Matériel"</string>
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Sélectionnez la disposition du clavier"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Appuyez ici pour sélectionner une disposition de clavier."</string>
+    <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="candidates_style" msgid="4333913089637062257"><u>"candidats"</u></string>
+    <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"Préparation de la mémoire de stockage USB"</string>
+    <string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"Préparation de la carte SD"</string>
+    <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"Recherche d\'erreurs en cours"</string>
+    <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"Mémoire de stockage USB vide"</string>
+    <string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"Carte SD vide"</string>
+    <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"La mémoire de stockage USB est vide, ou son système de fichiers n\'est pas compatible."</string>
+    <string name="ext_media_nofs_notification_message" product="default" msgid="8641065641786923604">"La carte SD est vide, ou son système de fichiers n\'est pas compatible."</string>
+    <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"Mémoire de stockage USB endommagée"</string>
+    <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"Carte SD endommagée"</string>
+    <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="1795917578395333280">"La mémoire de stockage USB est endommagée. Veuillez essayer de la reformater."</string>
+    <string name="ext_media_unmountable_notification_message" product="default" msgid="1753898567525568253">"La carte SD est endommagée. Veuillez tenter de la reformater."</string>
+    <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"Mémoire de stockage USB retirée inopinément"</string>
+    <string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"Carte SD retirée inopinément"</string>
+    <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"Désinstaller la mémoire de stockage USB avant de la retirer pour éviter toute perte de données."</string>
+    <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"Désactivez la carte SD avant de la retirer pour éviter toute perte de données."</string>
+    <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"La mémoire de stockage USB peut être retirée en toute sécurité."</string>
+    <string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"La carte SD peut être retirée en toute sécurité"</string>
+    <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"Vous pouvez retirer la mémoire de stockage USB en toute sécurité."</string>
+    <string name="ext_media_safe_unmount_notification_message" product="default" msgid="568841278138377604">"Vous pouvez retirer la carte SD en toute sécurité."</string>
+    <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"Mémoire de stockage USB retirée"</string>
+    <string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"Carte SD retirée"</string>
+    <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"Mémoire de stockage USB retirée. Insérez un nouveau support."</string>
+    <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"La carte SD a été retirée. Insérez-en une autre."</string>
+    <string name="activity_list_empty" msgid="1675388330786841066">"Aucune activité correspondante trouvée."</string>
+    <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"mettre à jour les données statistiques du composant"</string>
+    <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"Permet à l\'application de modifier les statistiques d\'utilisation des composants collectées. Les applications standards ne doivent pas utiliser cette fonctionnalité."</string>
+    <string name="permlab_copyProtectedData" msgid="4341036311211406692">"copier du contenu"</string>
+    <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Permet à l\'application d\'invoquer le service de conteneur par défaut pour copier du contenu. Les applications standards ne doivent pas utiliser cette fonctionnalité."</string>
+    <string name="permlab_route_media_output" msgid="1642024455750414694">"Diriger la sortie multimédia"</string>
+    <string name="permdesc_route_media_output" msgid="4932818749547244346">"Permet à une application de diriger la sortie multimédia vers d\'autres appareils externes."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Accéder au stockage sécurisé keyguard"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Permet à une application d\'accéder au stockage sécurisé keyguard."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Contrôler l\'affichage et le masquage de la protection des touches"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Permet à une application de contrôler la protection des touches."</string>
+    <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"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_send" msgid="2316166556349314424">"Envoyer"</string>
+    <string name="ime_action_next" msgid="3138843904009813834">"Suivante"</string>
+    <string name="ime_action_done" msgid="8971516117910934605">"Terminé"</string>
+    <string name="ime_action_previous" msgid="1443550039250105948">"Précédente"</string>
+    <string name="ime_action_default" msgid="2840921885558045721">"Exécuter"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Composer le numéro\nen utilisant <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Ajouter un contact\nen utilisant <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Les applications suivantes demandent l\'autorisation d\'accéder à votre compte à partir de maintenant."</string>
+    <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Voulez-vous autoriser cette demande?"</string>
+    <string name="grant_permissions_header_text" msgid="6874497408201826708">"Demande d\'accès"</string>
+    <string name="allow" msgid="7225948811296386551">"Autoriser"</string>
+    <string name="deny" msgid="2081879885755434506">"Refuser"</string>
+    <string name="permission_request_notification_title" msgid="6486759795926237907">"Autorisation demandée"</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Autorisation demandée\npour le compte \"<xliff:g id="ACCOUNT">%s</xliff:g>\""</string>
+    <string name="input_method_binding_label" msgid="1283557179944992649">"Mode de saisie"</string>
+    <string name="sync_binding_label" msgid="3687969138375092423">"Synchroniser"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"Accessibilité"</string>
+    <string name="wallpaper_binding_label" msgid="1240087844304687662">"Fond d\'écran"</string>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"Changer de fond d\'écran"</string>
+    <string name="notification_listener_binding_label" msgid="2014162835481906429">"Outil d\'écoute des notifications"</string>
+    <string name="vpn_title" msgid="19615213552042827">"VPN activé"</string>
+    <string name="vpn_title_long" msgid="6400714798049252294">"VPN activé par <xliff:g id="APP">%s</xliff:g>"</string>
+    <string name="vpn_text" msgid="3011306607126450322">"Appuyez ici pour gérer le réseau."</string>
+    <string name="vpn_text_long" msgid="6407351006249174473">"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_error" msgid="6009249814034708175">"Erreur du VPN permanent"</string>
+    <string name="vpn_lockdown_config" msgid="6415899150671537970">"Appuyer pour configurer"</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>
+    <string name="submit" msgid="1602335572089911941">"Envoyer"</string>
+    <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Mode Voiture activé"</string>
+    <string name="car_mode_disable_notification_message" msgid="8035230537563503262">"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="6857031760103062982">"Appuyez pour configurer."</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>
+    <string name="throttle_warning_notification_title" msgid="4890894267454867276">"Utilisation élevée des données mobiles"</string>
+    <string name="throttle_warning_notification_message" msgid="3340822228599337743">"Appuyez ici pour en savoir plus sur la consommation des données mobiles."</string>
+    <string name="throttled_notification_title" msgid="6269541897729781332">"Quota utilisation données dépassé"</string>
+    <string name="throttled_notification_message" msgid="5443457321354907181">"Appuyez ici pour en savoir plus sur la consommation des données mobiles."</string>
+    <string name="no_matches" msgid="8129421908915840737">"Aucune partie"</string>
+    <string name="find_on_page" msgid="1946799233822820384">"Rechercher sur la page"</string>
+  <plurals name="matches_found">
+    <item quantity="one" msgid="8167147081136579439">"1 correspondance"</item>
+    <item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> sur <xliff:g id="TOTAL">%d</xliff:g>"</item>
+  </plurals>
+    <string name="action_mode_done" msgid="7217581640461922289">"Terminé"</string>
+    <string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"Désinstallation de la mémoire de stockage USB en cours…"</string>
+    <string name="progress_unmounting" product="default" msgid="1327894998409537190">"Désinstallation de la carte SD en cours…"</string>
+    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"Effacement de la mémoire de stockage USB en cours…"</string>
+    <string name="progress_erasing" product="default" msgid="6596988875507043042">"Effacement de la carte SD en cours…"</string>
+    <string name="format_error" product="nosdcard" msgid="6299769563624776948">"Impossible d\'effacer la mémoire de stockage USB."</string>
+    <string name="format_error" product="default" msgid="7315248696644510935">"Impossible d\'effacer la carte SD."</string>
+    <string name="media_bad_removal" msgid="7960864061016603281">"La carte SD a été retirée sans avoir été désinstallée."</string>
+    <string name="media_checking" product="nosdcard" msgid="418188720009569693">"Vérification de la mémoire de stockage USB en cours"</string>
+    <string name="media_checking" product="default" msgid="7334762503904827481">"Vérification de la carte SD en cours"</string>
+    <string name="media_removed" msgid="7001526905057952097">"La carte SD a été retirée."</string>
+    <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"La mémoire de stockage USB est en cours d\'utilisation par l\'ordinateur."</string>
+    <string name="media_shared" product="default" msgid="5706130568133540435">"La carte SD est en cours d\'utilisation par un ordinateur."</string>
+    <string name="media_unknown_state" msgid="729192782197290385">"État du support externe inconnu"</string>
+    <string name="share" msgid="1778686618230011964">"Partager"</string>
+    <string name="find" msgid="4808270900322985960">"Trouver"</string>
+    <string name="websearch" msgid="4337157977400211589">"Recherche Web"</string>
+    <string name="find_next" msgid="5742124618942193978">"Rechercher suivante"</string>
+    <string name="find_previous" msgid="2196723669388360506">"Rechercher précédent"</string>
+    <string name="gpsNotifTicker" msgid="5622683912616496172">"Demande de position de <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Demande de position"</string>
+    <string name="gpsNotifMessage" msgid="1374718023224000702">"Demande de <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+    <string name="gpsVerifYes" msgid="2346566072867213563">"Oui"</string>
+    <string name="gpsVerifNo" msgid="1146564937346454865">"Non"</string>
+    <string name="sync_too_many_deletes" msgid="5296321850662746890">"Le nombre maximal de suppressions a été atteint."</string>
+    <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> éléments vont être supprimés lors de la synchronisation <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> pour le compte <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Voulez-vous continuer?"</string>
+    <string name="sync_really_delete" msgid="2572600103122596243">"Supprimer les éléments"</string>
+    <string name="sync_undo_deletes" msgid="2941317360600338602">"Annuler les suppressions"</string>
+    <string name="sync_do_nothing" msgid="3743764740430821845">"Ne rien faire pour l\'instant"</string>
+    <string name="choose_account_label" msgid="5655203089746423927">"Sélectionner un compte"</string>
+    <string name="add_account_label" msgid="2935267344849993553">"Ajouter un compte"</string>
+    <string name="add_account_button_label" msgid="3611982894853435874">"Ajouter un compte"</string>
+    <string name="number_picker_increment_button" msgid="2412072272832284313">"Augmenter"</string>
+    <string name="number_picker_decrement_button" msgid="476050778386779067">"Diminuer"</string>
+    <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> appuyez de manière prolongée."</string>
+    <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Faites glisser vers le haut pour augmenter et vers le bas pour diminuer."</string>
+    <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Minute suivante"</string>
+    <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Minute précédente"</string>
+    <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Heure suivante"</string>
+    <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Heure précédente"</string>
+    <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Définir la valeur PM"</string>
+    <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Définir la valeur AM"</string>
+    <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Mois suivant"</string>
+    <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Mois précédent"</string>
+    <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Jour suivant"</string>
+    <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Jour précédent"</string>
+    <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Année suivante"</string>
+    <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Année précédente"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Annuler"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Supprimer"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Terminé"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Changement de mode"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Maj"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Entrée"</string>
+    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Sélectionnez une application"</string>
+    <string name="shareactionprovider_share_with" msgid="806688056141131819">"Partagez avec"</string>
+    <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Partager avec <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+    <string name="content_description_sliding_handle" msgid="415975056159262248">"Poignée coulissante. Appuyez de manière prolongée."</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_down" msgid="5087739728639014595">"Faire glisser le doigt vers le bas : <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="description_direction_right" msgid="8034433242579600980">"Faites glisser votre doigt vers la droite pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Déverrouiller"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Appareil photo"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Mode silencieux"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Son activé"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Recherche"</string>
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Faites glisser votre doigt pour déverrouiller l\'appareil."</string>
+    <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Branchez des écouteurs pour entendre l\'énoncé des touches lors de la saisie du mot de passe."</string>
+    <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Point."</string>
+    <string name="action_bar_home_description" msgid="5293600496601490216">"Revenir à l\'accueil"</string>
+    <string name="action_bar_up_description" msgid="2237496562952152589">"Revenir en haut de la page"</string>
+    <string name="action_menu_overflow_description" msgid="2295659037509008453">"Plus d\'options"</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="4891916833657929263">"Mémoire de stockage interne"</string>
+    <string name="storage_sd_card" msgid="3282948861378286745">"Carte SD"</string>
+    <string name="storage_usb" msgid="3017954059538517278">"Mémoire de stockage USB"</string>
+    <string name="extract_edit_menu_button" msgid="8940478730496610137">"Modifier"</string>
+    <string name="data_usage_warning_title" msgid="1955638862122232342">"Avertissement utilisation données"</string>
+    <string name="data_usage_warning_body" msgid="2814673551471969954">"Appuyez pour conso/paramètres"</string>
+    <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"Données 2G-3G  désactivées"</string>
+    <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Données 4G désactivées"</string>
+    <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Données mobiles désactivées"</string>
+    <string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"Wi-Fi désactivé"</string>
+    <string name="data_usage_limit_body" msgid="3317964706973601386">"Appuyez ici pour réactiver."</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>
+    <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Quota de données Wi-Fi dépassé"</string>
+    <string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> au-delà de la limite spécifiée."</string>
+    <string name="data_usage_restricted_title" msgid="5965157361036321914">"Données en arrière-plan limitées"</string>
+    <string name="data_usage_restricted_body" msgid="6741521330997452990">"Appuyez pour suppr. restriction."</string>
+    <string name="ssl_certificate" msgid="6510040486049237639">"Certificat de sécurité"</string>
+    <string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Ce certificat est valide."</string>
+    <string name="issued_to" msgid="454239480274921032">"Émis à :"</string>
+    <string name="common_name" msgid="2233209299434172646">"Nom commun :"</string>
+    <string name="org_name" msgid="6973561190762085236">"Organisation :"</string>
+    <string name="org_unit" msgid="7265981890422070383">"Unité organisationnelle :"</string>
+    <string name="issued_by" msgid="2647584988057481566">"Émis par :"</string>
+    <string name="validity_period" msgid="8818886137545983110">"Validité :"</string>
+    <string name="issued_on" msgid="5895017404361397232">"Émis le :"</string>
+    <string name="expires_on" msgid="3676242949915959821">"Expire le :"</string>
+    <string name="serial_number" msgid="758814067660862493">"Numéro de série :"</string>
+    <string name="fingerprints" msgid="4516019619850763049">"Empreintes :"</string>
+    <string name="sha256_fingerprint" msgid="4391271286477279263">"Empreinte SHA-256 :"</string>
+    <string name="sha1_fingerprint" msgid="7930330235269404581">"Empreinte SHA-1 :"</string>
+    <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Tout afficher"</string>
+    <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Sélectionnez une activité"</string>
+    <string name="share_action_provider_share_with" msgid="5247684435979149216">"Partagez avec"</string>
+    <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="3245653681008218030">"Envoi…"</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Lancer le navigateur?"</string>
+    <string name="SetupCallDefault" msgid="5834948469253758575">"Prendre l\'appel?"</string>
+    <string name="activity_resolver_use_always" msgid="8017770747801494933">"Toujours"</string>
+    <string name="activity_resolver_use_once" msgid="2404644797149173758">"Une seule fois"</string>
+    <string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"Tablette"</string>
+    <string name="default_audio_route_name" product="default" msgid="4239291273420140123">"Téléphone"</string>
+    <string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Oreillettes"</string>
+    <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Haut-parleurs de la station d\'accueil"</string>
+    <string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string>
+    <string name="default_audio_route_category_name" msgid="3722811174003886946">"Système"</string>
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio Bluetooth"</string>
+    <string name="wireless_display_route_description" msgid="9070346425023979651">"Affichage sans fil"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Terminé"</string>
+    <string name="media_route_button_content_description" msgid="5758553567065145276">"Sortie multimédia"</string>
+    <string name="media_route_status_scanning" msgid="7279908761758293783">"Analyse en cours..."</string>
+    <string name="media_route_status_connecting" msgid="6422571716007825440">"Connexion en cours..."</string>
+    <string name="media_route_status_available" msgid="6983258067194649391">"Disponible"</string>
+    <string name="media_route_status_not_available" msgid="6739899962681886401">"Indisponible"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"En cours d\'utilisation"</string>
+    <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Écran intégré"</string>
+    <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"Écran HDMI"</string>
+    <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Superposition n° <xliff:g id="ID">%1$d</xliff:g>"</string>
+    <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g> : <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> ppp"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", sécurisé"</string>
+    <string name="wifi_display_notification_title" msgid="2223050649240326557">"L\'affichage sans fil est connecté."</string>
+    <string name="wifi_display_notification_message" msgid="4498802012464170685">"Cet écran s\'affiche sur un autre appareil."</string>
+    <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Déconnecter"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Appel d\'urgence"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"J\'ai oublié le schéma"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Schéma incorrect."</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Mot de passe incorrect."</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"NIP incorrect."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Réessayez dans <xliff:g id="NUMBER">%1$d</xliff:g> secondes."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Dessinez votre schéma."</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Saisissez le NIP de la carte SIM"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Saisissez le NIP."</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Saisissez votre mot de passe."</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"La carte SIM est maintenant désactivée. Saisissez le code PUK pour continuer. Contactez votre opérateur pour en savoir plus."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Saisir le NIP souhaité"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Confirmer le NIP souhaité"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Déblocage de la carte SIM en cours…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"NIP erroné."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Saisissez un NIP comprenant entre quatre et huit chiffres"</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Le code PUK doit contenir au moins 8 chiffres."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Veuillez saisir de nouveau le code PUK correct. Des tentatives répétées désactivent définitivement la carte SIM."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Les codes PIN ne correspondent pas."</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Trop de tentatives."</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Pour déverrouiller l\'appareil, connectez-vous avec votre compte Google."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Nom d\'utilisateur (courriel)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Mot de passe"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Connexion"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nom d\'utilisateur ou mot de passe non valide."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Vous avez oublié votre nom d\'utilisateur ou votre mot de passe?\nRendez-vous sur la page "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Vérification du compte en cours…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Vous avez saisi un NIP incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Vous avez saisi un mot de passe incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Sa configuration d\'usine va être rétablie."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Sa configuration d\'usine va être rétablie."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, vous devrez déverrouiller votre tablette à l\'aide d\'un compte de messagerie électronique.\n\n Veuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, vous devrez déverrouiller votre téléphone à l\'aide d\'un compte de messagerie électronique.\n\n Veuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Supprimer"</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Augmenter le volume au-dessus du niveau recommandé?\nL\'écoute à un volume élevé pendant des périodes prolongées peut endommager votre audition."</string>
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Pour activer l\'accessibilité, appuyez de manière prolongée avec deux doigts."</string>
+    <string name="accessibility_enabled" msgid="1381972048564547685">"L\'accessibilité a bien été activée."</string>
+    <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accessibilité annulée."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="owner_name" msgid="2716755460376028154">"Propriétaire"</string>
+    <string name="error_message_title" msgid="4510373083082500195">"Erreur"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Les comptes des profils en accès limité ne sont pas compatibles avec cette application."</string>
+    <string name="app_not_found" msgid="3429141853498927379">"Aucune application trouvée pour gérer cette action."</string>
+    <string name="revoke" msgid="5404479185228271586">"Révoquer"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Lettre"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Légal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Annulé"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Erreur lors de l\'écriture du contenu"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"inconnu"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Entrez le NIP d\'administrateur"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Saisissez le NIP"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Incorrect"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"NIP actuel"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Nouveau NIP"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Confirmer le nouveau NIP"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Créez un NIP pour modifier les restrictions"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"Les NIP ne correspondent pas. Essayez à nouveau."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"Le NIP est trop court. Il doit comporter au moins 4 chiffres."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Réessayer dans 1 s"</item>
+    <item quantity="other" msgid="4730868920742952817">"Réessayer dans <xliff:g id="COUNT">%d</xliff:g> s"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Réessayez plus tard"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Gliss. doigt sur côté écr. aff. barre"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Faites glisser votre doigt à partir d\'un côté de l\'écran pour afficher la barre système"</string>
+</resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index a1c795f..27ef5d7 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -131,6 +131,11 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Trop de contenus supprimés (<xliff:g id="CONTENT_TYPE">%s</xliff:g>)."</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"La mémoire de la tablette est pleine. Supprimez des fichiers pour libérer de l\'espace."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"La mémoire du téléphone est pleine. Veuillez supprimer des fichiers pour libérer de l\'espace."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Il est possible que le réseau soit surveillé."</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Moi"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Options de la tablette"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Options du téléphone"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Permet à l\'application de déplacer les tâches au premier plan et en arrière-plan. L\'application peut procéder à ces opérations sans votre intervention."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"arrêter les applications en cours d\'exécution"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Permet à l\'application de supprimer des tâches et de fermer les applications qui les exécutent. Des applications malveillantes peuvent exploiter cette fonctionnalité pour perturber le comportement des autres applications."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"gérer les piles d\'activités"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Permet à l\'application d\'ajouter, de supprimer et de modifier les piles d\'activités dans lesquelles d\'autres applications fonctionnent. Des applications malveillantes peuvent perturber le comportement d\'autres applications."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"démarrer n\'importe quelle activité"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Permet à l\'application de démarrer n\'importe quelle activité, quels que soient l\'état exporté ou le degré de protection appliqué à l\'autorisation."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"définir la compatibilité de l\'écran"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un mode de saisie. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"associer à un service d\'accessibilité"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un service d\'accessibilité. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"s\'associer à un service d\'impression"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Permet à l\'application autorisée de s\'associer à l\'interface de niveau supérieur d\'un service d\'impression. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"s\'associer à un service de spouleur d\'impression"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Permet à l\'application autorisée de s\'associer à l\'interface de niveau supérieur d\'un service de spouleur d\'impression. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"s\'associer au service NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Permet à l\'application autorisée de s\'associer aux applications qui reproduisent le fonctionnement des cartes NFC. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"associer à un service de texte"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Permet à l\'application de s\'associer à l\'interface de haut niveau d\'un service de texte (par exemple, SpellCheckerService). Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"associer à un service VPN"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un service widget. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interagir avec l\'administrateur du périphérique"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Permet à l\'application autorisée d\'envoyer des intentions à l\'administrateur de l\'appareil. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"ajouter ou supprimer un administrateur de l\'appareil"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Permet à l\'application autorisée d\'ajouter ou de supprimer des administrateurs actifs de l\'appareil. Les applications standards ne devraient pas nécessiter cette autorisation."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"Changement d\'orientation de l\'écran"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Permet à l\'application de changer l\'orientation de l\'écran à tout moment. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"changer la vitesse du pointeur"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Permet à l\'application de lire les différents fichiers journaux du système afin d\'obtenir des informations générales sur la façon dont vous utilisez votre téléphone. Celles-ci peuvent éventuellement inclure des informations d\'ordre personnel ou privé."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"utiliser n\'importe quel décodeur pour lire les fichiers multimédias"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Permet à une application d\'utiliser n\'importe quel décodeur installé pour lire les fichiers multimédias."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"gérer les certificats de confiance"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Permet à l\'application d\'installer et de désinstaller les certificats CA en tant que certificats de confiance."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"Lecture/écriture dans les ressources appartenant aux diagnostics"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permet à l\'application d\'obtenir des droits en lecture/écriture concernant toute ressource appartenant au groupe de diagnostics (par exemple, les fichiers du répertoire /dev). Ceci peut affecter la stabilité et la sécurité du système. Cette fonctionnalité est UNIQUEMENT réservée aux diagnostics matériels effectués par le fabricant ou l\'opérateur."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"activer ou désactiver les composants de l\'application"</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permet à l\'application de configurer des écrans Wi-Fi et de s\'y connecter."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"contrôler les écrans Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Permet à l\'application de contrôler les fonctionnalités de base des écrans Wi-Fi."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"enregistrer les sorties audio"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Autoriser l\'application à enregistrer et à rediriger les sorties audio"</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"enregistrer les sorties vidéo"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Autoriser l\'application à enregistrer et à rediriger les sorties vidéo"</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"enregistrer les sorties vidéo sécurisées"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Autoriser l\'application à enregistrer et à rediriger les sorties vidéo sécurisées"</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"modifier vos paramètres audio"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Permet à l\'application de modifier les paramètres audio généraux, tels que le volume et la sortie audio utilisée."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"Enregistrer des fichiers audio"</string>
@@ -525,6 +552,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"empêcher le téléphone de passer en mode veille"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Permet à l\'application d\'empêcher la tablette de passer en mode veille."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Permet à l\'application d\'empêcher le téléphone de passer en mode veille."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"éteindre ou allumer la tablette"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"Éteindre ou allumer le téléphone"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Permet à l\'application d\'éteindre et d\'allumer la tablette."</string>
@@ -613,6 +646,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Permet à l\'application de modifier le contenu de la carte SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"Modifier/Supprimer contenu mémoire interne"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Permet à l\'application de modifier le contenu de la mémoire de stockage multimédia interne."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"gérer stockage des documents"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Permet à l\'application de gérer le stockage des documents."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"Accès stock. ext. tous utilis."</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Permet à l\'application d\'accéder à la mémoire de stockage externe pour tous les utilisateurs."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"accéder au système de fichiers en cache"</string>
@@ -625,10 +660,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Permet à l\'application de gérer les stratégies du réseau et de définir celles qui sont spécifiques à l\'application."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"modifier le système de comptabilisation de l\'utilisation du réseau"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Permet à l\'application de modifier l\'utilisation du réseau par les autres applications. Les applications standards ne doivent pas utiliser cette fonctionnalité."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"modifier les marques de sockets"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Permet à l\'application de modifier les marques de sockets pour les redirections."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"accéder aux notifications"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Permet aux applications de récupérer, d\'examiner et d\'autoriser les notifications, y compris celles envoyées par d\'autres applications."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"s\'associer à l\'interface de niveau supérieur d\'un service d\'écoute des notifications"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Permet à l\'application de s\'associer à l\'interface de niveau supérieur d\'un service d\'écoute des notifications. Ne devrait jamais être nécessaire pour les applications normales."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"faire appel à l\'application de configuration fournie par l\'opérateur"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Permet à l\'application autorisée de faire appel à l\'application de configuration fournie par l\'opérateur. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"détecter des observations sur les conditions du réseau"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permet à une application de détecter des observations sur les conditions du réseau. Les applications standards ne devraient pas nécessiter cette autorisation."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Définir les règles du mot de passe"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Choisir le nombre et le type de caractères autorisés dans les mots de passe de déverrouillage de l\'écran"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Gérer les tentatives de déverrouillage de l\'écran"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +836,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Insérez une carte SIM."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Carte SIM absente ou illisible. Insérez une carte SIM."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Carte SIM inutilisable."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Votre carte SIM a été définitivement désactivée."\n" Veuillez contacter votre opérateur de téléphonie mobile pour en obtenir une autre."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Votre carte SIM a été définitivement désactivée.\n Veuillez contacter votre opérateur de téléphonie mobile pour en obtenir une autre."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Bouton du titre précédent"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Bouton du titre suivant"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Bouton de pause"</string>
@@ -808,11 +848,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Veuillez consulter le guide utilisateur ou contacter le service client."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"La carte SIM est verrouillée."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Déblocage de la carte SIM..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises."\n\n"Veuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Vous avez saisi un mot de passe incorrect <xliff:g id="NUMBER_0">%d</xliff:g> fois. "\n\n"Veuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Vous avez saisi un code PIN incorrect <xliff:g id="NUMBER_0">%d</xliff:g> fois. "\n\n"Veuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Au bout de <xliff:g id="NUMBER_1">%d</xliff:g> échecs supplémentaires, vous devrez déverrouiller votre tablette à l\'aide de votre identifiant Google."\n\n"Veuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Au bout de <xliff:g id="NUMBER_1">%d</xliff:g> échecs supplémentaires, vous devrez déverrouiller votre téléphone à l\'aide de votre identifiant Google."\n\n"Veuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Vous avez saisi un mot de passe incorrect <xliff:g id="NUMBER_0">%d</xliff:g> fois. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Vous avez saisi un code PIN incorrect <xliff:g id="NUMBER_0">%d</xliff:g> fois. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Au bout de <xliff:g id="NUMBER_1">%d</xliff:g> échecs supplémentaires, vous devrez déverrouiller votre tablette à l\'aide de votre identifiant Google.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Au bout de <xliff:g id="NUMBER_1">%d</xliff:g> échecs supplémentaires, vous devrez déverrouiller votre téléphone à l\'aide de votre identifiant Google.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Sa configuration d\'usine va être rétablie."</string>
@@ -826,7 +866,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Mot de passe"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Se connecter"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nom d\'utilisateur ou mot de passe incorrect."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Vous avez oublié votre nom d\'utilisateur ou votre mot de passe ?"\n"Accédez à la page "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Vous avez oublié votre nom d\'utilisateur ou votre mot de passe ?\nAccédez à la page "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Vérification en cours…"</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Déverrouiller"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Son activé"</string>
@@ -874,7 +914,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Quitter la page"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Quitter cette page"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Rester sur cette page"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Voulez-vous vraiment quitter cette page ?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nVoulez-vous vraiment quitter cette page ?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Confirmer"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Conseil : Appuyez deux fois pour faire un zoom avant ou arrière."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Saisie auto"</string>
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"L\'application \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" s\'est arrêtée."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Le processus <xliff:g id="PROCESS">%1$s</xliff:g> s\'est interrompu."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"L\'application <xliff:g id="APPLICATION">%2$s</xliff:g> ne répond pas."\n\n"Voulez-vous quitter ?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"L\'activité <xliff:g id="ACTIVITY">%1$s</xliff:g> ne répond pas."\n\n"Voulez-vous quitter ?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"L\'application <xliff:g id="APPLICATION">%2$s</xliff:g> ne répond pas.\n\nVoulez-vous quitter ?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"L\'activité <xliff:g id="ACTIVITY">%1$s</xliff:g> ne répond pas.\n\nVoulez-vous quitter ?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"L\'application <xliff:g id="APPLICATION">%1$s</xliff:g> ne répond pas. Voulez-vous quitter ?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Le processus <xliff:g id="PROCESS">%1$s</xliff:g> ne répond pas."\n\n"Voulez-vous quitter ?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Le processus <xliff:g id="PROCESS">%1$s</xliff:g> ne répond pas.\n\nVoulez-vous quitter ?"</string>
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"Rapport"</string>
     <string name="wait" msgid="7147118217226317732">"Attendre"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"La page ne répond pas."\n" "\n"Voulez-vous la fermer ?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"La page ne répond pas.\n \nVoulez-vous la fermer ?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Application redirigée"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> est maintenant lancée."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"Application lancée initialement : <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
@@ -1256,6 +1296,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Permet à l\'application d\'invoquer le service de conteneur par défaut pour copier du contenu. Les applications standards ne doivent pas utiliser cette fonctionnalité."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Diriger la sortie multimédia"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Permet à une application de diriger la sortie multimédia vers d\'autres appareils externes."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Accéder au stockage sécurisé keyguard"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Permet à une application d\'accéder au stockage sécurisé keyguard."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Contrôler l\'affichage et le masquage de la protection des touches"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Permet à une application de contrôler la protection des touches."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Appuyez 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">"OK"</string>
@@ -1265,15 +1309,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"OK"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Préc."</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Exécuter"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Composer le numéro"\n"en utilisant <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Ajouter un contact"\n"en utilisant <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Composer le numéro\nen utilisant <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Ajouter un contact\nen utilisant <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Les applications suivantes demandent l\'autorisation d\'accéder à votre compte à partir de maintenant."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Voulez-vous autoriser cette demande ?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Demande d\'accès"</string>
     <string name="allow" msgid="7225948811296386551">"Autoriser"</string>
     <string name="deny" msgid="2081879885755434506">"Refuser"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Autorisation demandée"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Autorisation demandée"\n"pour le compte \"<xliff:g id="ACCOUNT">%s</xliff:g>\""</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Autorisation demandée\npour le compte \"<xliff:g id="ACCOUNT">%s</xliff:g>\""</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Mode de saisie"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Synchronisation"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Accessibilité"</string>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Tout afficher"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Sélectionnez une activité"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Partager avec"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Appareil verrouillé"</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Envoi en cours…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Lancer le navigateur ?"</string>
@@ -1441,10 +1484,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Connexion en cours..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Disponible"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"Indisponible"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"En cours d\'utilisation"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Écran intégré"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"Écran HDMI"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Superposition n° <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g> : <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", sécurisé"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"L\'affichage sans fil est connecté."</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Cet écran s\'affiche sur un autre appareil."</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Déconnecter"</string>
@@ -1453,7 +1498,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Schéma incorrect."</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Mot de passe incorrect."</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"Code PIN incorrect."</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Réessayez dans <xliff:g id="NUMBER">%d</xliff:g> secondes."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Réessayez dans <xliff:g id="NUMBER">%1$d</xliff:g> secondes."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Dessinez votre schéma."</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Saisissez le code PIN de la carte SIM."</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Saisissez le code PIN."</string>
@@ -1473,27 +1518,85 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Mot de passe"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Connexion"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nom d\'utilisateur ou mot de passe non valide."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Vous avez oublié votre nom d\'utilisateur ou votre mot de passe ?"\n"Rendez-vous sur la page "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Vous avez oublié votre nom d\'utilisateur ou votre mot de passe ?\nRendez-vous sur la page "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Vérification du compte en cours…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Vous avez saisi un code PIN incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. "\n\n"Veuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Vous avez saisi un mot de passe incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. "\n\n"Veuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises."\n\n"Veuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Vous avez saisi un code PIN incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Vous avez saisi un mot de passe incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Sa configuration d\'usine va être rétablie."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Sa configuration d\'usine va être rétablie."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, vous devrez déverrouiller votre tablette à l\'aide d\'un compte de messagerie électronique."\n\n" Veuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, vous devrez déverrouiller votre téléphone à l\'aide d\'un compte de messagerie électronique."\n\n" Veuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, vous devrez déverrouiller votre tablette à l\'aide d\'un compte de messagerie électronique.\n\n Veuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, vous devrez déverrouiller votre téléphone à l\'aide d\'un compte de messagerie électronique.\n\n Veuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Supprimer"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Augmenter le volume au-dessus du niveau recommandé ?"\n"L\'écoute à un volume élevé pendant des périodes prolongées peut endommager votre audition."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Augmenter le volume au-dessus du niveau recommandé ?\nL\'écoute à un volume élevé pendant des périodes prolongées peut endommager votre audition."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Pour activer l\'accessibilité, appuyez de manière prolongée avec deux doigts."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"L\'accessibilité a bien été activée."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accessibilité annulée."</string>
     <string name="user_switched" msgid="3768006783166984410">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="owner_name" msgid="2716755460376028154">"Propriétaire"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Erreur"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Les comptes des profils limités ne sont pas acceptés pour cette application."</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Les comptes des profils en accès limité ne sont pas compatibles avec cette application."</string>
     <string name="app_not_found" msgid="3429141853498927379">"Aucune application trouvée pour gérer cette action."</string>
     <string name="revoke" msgid="5404479185228271586">"Révoquer"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Lettre"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloïd"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Tâche annulée."</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Erreur lors de la modification du contenu."</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"inconnu"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Saisir le code PIN d\'administrateur"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Saisir le code PIN"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Incorrect."</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Code PIN actuel"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Nouveau code PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Confirmer le nouveau code PIN"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Créer un code PIN pour modifier les restrictions"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"Les codes PIN ne correspondent pas. Veuillez réessayer."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"Le code PIN est trop court. Il doit comporter au moins 4 chiffres."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Réessayer dans 1 s"</item>
+    <item quantity="other" msgid="4730868920742952817">"Réessayer dans <xliff:g id="COUNT">%d</xliff:g> s"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Veuillez réessayer ultérieurement."</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Faire glisser côté pour voir barre."</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Faites glisser le doigt à partir d\'un côté de l\'écran pour afficher la barre système."</string>
 </resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index a2180a8..e7e6518 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -109,7 +109,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>
@@ -125,12 +125,17 @@
     <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>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"टेबलेट संग्रहण भर गया है. स्‍थान रिक्त करने के लिए कुछ फ़ाइलें हटाएं."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"फ़ोन संग्रहण भर गया है. स्‍थान रिक्त करने के लिए कुछ फ़ाइलें हटाएं."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"नेटवर्क को मॉनिटर किया जा सकता है"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"मैं"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"टेबलेट विकल्‍प"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"फ़ोन विकल्‍प"</string>
@@ -147,9 +152,9 @@
     <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="reboot_safemode_confirm" msgid="55293944502784668">"क्या आप सुरक्षित मोड में रीबूट करना चाहते हैं? इससे आपके इंस्टॉल किए हुए सभी तृतीय पक्ष एप्स अक्षम हो जाएंगे. जब आप फिर से रीबूट करेंगे तो वे पुनर्स्थापित हो जाएंगे."</string>
     <string name="recent_tasks_title" msgid="3691764623638127888">"हाल के"</string>
-    <string name="no_recent_tasks" msgid="8794906658732193473">"कोई हाल ही के एप्लिकेशन नहीं."</string>
+    <string name="no_recent_tasks" msgid="8794906658732193473">"कोई हाल ही के एप्स नहीं."</string>
     <string name="global_actions" product="tablet" msgid="408477140088053665">"टेबलेट विकल्‍प"</string>
     <string name="global_actions" product="default" msgid="2406416831541615258">"फ़ोन विकल्‍प"</string>
     <string name="global_action_lock" msgid="2844945191792119712">"स्‍क्रीन लॉक"</string>
@@ -202,8 +207,8 @@
     <string name="permgroupdesc_camera" msgid="2933667372289567714">"चित्र या वीडियो कैप्‍चर के लिए कैमरे पर सीधी पहुंच."</string>
     <string name="permgrouplab_screenlock" msgid="8275500173330718168">"स्‍क्रीन लॉक करें"</string>
     <string name="permgroupdesc_screenlock" msgid="7067497128925499401">"आपके उपकरण की लॉक स्क्रीन का व्यवहार प्रभावित करने की क्षमता."</string>
-    <string name="permgrouplab_appInfo" msgid="8028789762634147725">"आपके एप्‍लिकेशन की जानकारी"</string>
-    <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"अपने उपकरण पर अन्‍य एप्‍लिकेशन के व्‍यवहार को प्रभावित करने की क्षमता."</string>
+    <string name="permgrouplab_appInfo" msgid="8028789762634147725">"आपके एप्‍स की जानकारी"</string>
+    <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"अपने उपकरण पर अन्‍य एप्‍स के व्‍यवहार को प्रभावित करने की क्षमता."</string>
     <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"वॉलपेपर"</string>
     <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"उपकरण की वॉलपेपर सेटिंग बदलें."</string>
     <string name="permgrouplab_systemClock" msgid="406535759236612992">"घड़ी"</string>
@@ -221,9 +226,9 @@
     <string name="permgrouplab_systemTools" msgid="4652191644082714048">"सिस्‍टम टूल"</string>
     <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"सिस्‍टम का निम्‍न-स्‍तर पहुंच और नियंत्रण."</string>
     <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"डेवलपमेंट टूल"</string>
-    <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"सुविधाएं जो केवल एप्लिकेशन डेवलपर के लिए आवश्यक हैं."</string>
-    <string name="permgrouplab_display" msgid="4279909676036402636">"अन्‍य एप्‍लिकेशन UI"</string>
-    <string name="permgroupdesc_display" msgid="6051002031933013714">"अन्‍य एप्‍लिकेशन के UI को प्रभावित करें."</string>
+    <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"सुविधाएं जो केवल एप्स डेवलपर के लिए आवश्यक हैं."</string>
+    <string name="permgrouplab_display" msgid="4279909676036402636">"अन्‍य एप्‍स UI"</string>
+    <string name="permgroupdesc_display" msgid="6051002031933013714">"अन्‍य एप्‍स के UI को प्रभावित करें."</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"संग्रहण"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"USB संग्रहण में पहुंचें."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"SD कार्ड में पहुंचें."</string>
@@ -234,401 +239,437 @@
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"स्पर्श द्वारा एक्सप्लोर करें को चालू करें"</string>
     <string name="capability_desc_canRequestTouchExploration" msgid="5800552516779249356">"स्पर्श किए गए आइटम ज़ोर से बोले जाएंगे और स्क्रीन को जेस्चर के उपयोग से एक्सप्लोर किया जा सकेगा."</string>
     <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"एन्हांस की गई वेब पहुंच-योग्यता चालू करें"</string>
-    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"एप्लिकेशन सामग्री को अधिक पहुंच-योग्य बनाने के लिए स्क्रिप्ट इंस्टॉल किए जा सकते हैं."</string>
+    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"एप्स सामग्री को अधिक पहुंच-योग्य बनाने के लिए स्क्रिप्ट इंस्टॉल किए जा सकते हैं."</string>
     <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"आपके द्वारा लिखे हुए पाठ को ध्यान से देखें"</string>
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"क्रेडिट कार्ड नंबर और पासवर्ड जैसा व्यक्तिगत डेटा शामिल होता है."</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="7247281911387931485">"स्‍थिति बार"</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_processOutgoingCalls" msgid="3906007831192990946">"आउटगोइंग कॉल को कहीं और भेजें"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"एप्‍लिकेशन को आउटगोइंग कॉल संसाधित करने और डायल किए जाने वाला नंबर बदलने देता है. यह अनुमति एप्‍लिकेशन को आउटगोइंग कॉल की निगरानी करने, रीडायरेक्‍ट करने, या उन्‍हें रोकने देती है."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"एप्‍स को आउटगोइंग कॉल संसाधित करने और डायल किए जाने वाला नंबर बदलने देता है. यह अनुमति एप्‍स को आउटगोइंग कॉल की निगरानी करने, रीडायरेक्‍ट करने, या उन्‍हें रोकने देती है."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"पाठ संदेश (SMS) प्राप्त करें"</string>
-    <string name="permdesc_receiveSms" msgid="6424387754228766939">"एप्लिकेशन को 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="permdesc_receiveMms" msgid="533019437263212260">"एप्स को MMS संदेशों को प्राप्‍त और संसाधित करने देता है. इसका अर्थ है कि एप्स आपके उपकरण पर भेजे गए संदेशों की निगरानी आपको दिखाए बिना कर सकता है और उन्‍हें हटा सकता है."</string>
     <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"आपातकालीन प्रसारण प्राप्त करें"</string>
-    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"एप्लिकेशन को आपातकालीन प्रसारण संदेशों को प्राप्त करने और संसाधित करने देता है. यह अनुमति केवल सिस्टम एप्लिकेशन में उपलब्ध है."</string>
+    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"एप्स को आपातकालीन प्रसारण संदेशों को प्राप्त करने और संसाधित करने देता है. यह अनुमति केवल सिस्टम एप्स में उपलब्ध है."</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_sendSms" msgid="5600830612147671529">"SMS संदेश भेजें"</string>
-    <string name="permdesc_sendSms" msgid="7094729298204937667">"एप्लिकेशन को SMS संदेशों को भेजने देता है. इसके परिणामस्वरूप अप्रत्‍याशित शुल्‍क लागू हो सकते हैं. दुर्भावनापूर्ण एप्लिकेशन आपकी पुष्टि के बिना संदेश भेजकर आपका धन व्‍यय कर सकते हैं."</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"एप्स को SMS संदेशों को भेजने देता है. इसके परिणामस्वरूप अप्रत्‍याशित शुल्‍क लागू हो सकते हैं. दुर्भावनापूर्ण एप्स आपकी पुष्टि के बिना संदेश भेजकर आपका धन व्‍यय कर सकते हैं."</string>
     <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"संदेश-द्वारा-जवाब भेजें ईवेंट"</string>
-    <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"इनकमिंग कॉल के संदेश-द्वारा-जवाब देने के ईवेंट प्रबंधित करने के लिए, एप्लिकेशन को अन्य संदेश सेवा एप्लिकेशन को अनुरोध भेजने देती है."</string>
+    <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"इनकमिंग कॉल के संदेश-द्वारा-जवाब देने के ईवेंट प्रबंधित करने के लिए, एप्स को अन्य संदेश सेवा एप्स को अनुरोध भेजने देती है."</string>
     <string name="permlab_readSms" msgid="8745086572213270480">"अपने पाठ संदेश (SMS या MMS) पढ़ें"</string>
-    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"एप्लिकेशन को आपके टेबलेट या SIM कार्ड में संग्रहीत SMS संदेश पढ़ने देता है. इससे सामग्री या गोपनीयता पर ध्यान दिए बिना, एप्लिकेशन सभी SMS संदेश पढ़ सकता है."</string>
-    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"एप्लिकेशन को आपके फ़ोन या SIM कार्ड में संग्रहीत SMS संदेश पढ़ने देता है. इससे सामग्री या गोपनीयता पर ध्यान दिए बिना, एप्लिकेशन सभी SMS संदेश पढ़ सकता है."</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"एप्स को आपके टेबलेट या SIM कार्ड में संग्रहीत SMS संदेश पढ़ने देता है. इससे सामग्री या गोपनीयता पर ध्यान दिए बिना, एप्स सभी SMS संदेश पढ़ सकता है."</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"एप्स को आपके फ़ोन या SIM कार्ड में संग्रहीत SMS संदेश पढ़ने देता है. इससे सामग्री या गोपनीयता पर ध्यान दिए बिना, एप्स सभी SMS संदेश पढ़ सकता है."</string>
     <string name="permlab_writeSms" msgid="3216950472636214774">"अपने पाठ संदेश (SMS या MMS) संपादित करें"</string>
-    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"एप्लिकेशन को आपके टेबलेट या सिम कार्ड में संग्रहीत SMS संदेशों में लिखने देता है. दुर्भावनापूर्ण एप्लिकेशन आपके संदेशों को हटा सकते हैं."</string>
-    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"एप्लिकेशन को आपके फ़ोन या सिम कार्ड में संग्रहीत SMS संदेशों को लिखने देता है.  दुर्भावनापूर्ण एप्लिकेशन आपके संदेशों को हटा सकते हैं."</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"एप्स को आपके टेबलेट या सिम कार्ड में संग्रहीत SMS संदेशों में लिखने देता है. दुर्भावनापूर्ण एप्स आपके संदेशों को हटा सकते हैं."</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"एप्स को आपके फ़ोन या सिम कार्ड में संग्रहीत 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="permdesc_receiveWapPush" msgid="748232190220583385">"एप्स को WAP संदेशों को प्राप्‍त और संसाधित करने देता है. इस अनुमति में आपको भेजे गए संदेशों की निगरानी आपको दिखाए बिना करने और हटाने की क्षमता शामिल है."</string>
+    <string name="permlab_getTasks" msgid="6466095396623933906">"चल रहे एप्‍स पुनर्प्राप्त करें"</string>
+    <string name="permdesc_getTasks" msgid="7454215995847658102">"एप्स को वर्तमान में और हाल ही में चल रहे कार्यों के बारे में जानकारी को पुन: प्राप्‍त करने देता है. इससे एप्स उपकरण पर उपयोग किए गए एप्स के बारे में जानकारी खोज सकता है."</string>
     <string name="permlab_interactAcrossUsers" msgid="7114255281944211682">"उपयोगकर्ताओं के बीच सहभागिता करें"</string>
-    <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"एप्लिकेशन को उपकरण पर भिन्न उपयोगकर्ताओं के बीच कार्य निष्पादित करने देता है. दुर्भावनापूर्ण एप्लिकेशन उपयोगकर्ताओं के बीच सुरक्षा का उल्लंघन करने के लिए इसका उपयोग कर सकते हैं."</string>
+    <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"एप्स को उपकरण पर भिन्न उपयोगकर्ताओं के बीच कार्य निष्पादित करने देता है. दुर्भावनापूर्ण एप्स उपयोगकर्ताओं के बीच सुरक्षा का उल्लंघन करने के लिए इसका उपयोग कर सकते हैं."</string>
     <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"उपयोगकर्ताओं के बीच सहभागिता करने के लिए पूर्ण लाइसेंस"</string>
     <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"उपयोगकर्ताओं के बीच सभी संभव सहभागिता करने देता है."</string>
     <string name="permlab_manageUsers" msgid="1676150911672282428">"उपयोगकर्ता प्रबंधित करें"</string>
-    <string name="permdesc_manageUsers" msgid="8409306667645355638">"एप्लिकेशन को उपकरण पर क्वेरी, निर्माण और हटाने सहित उपयोगकर्ताओं को प्रबंधित करने की सुविधा देता है."</string>
-    <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"चल रहे एप्‍लिकेशन के विवरण प्राप्त करें"</string>
-    <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"एप्लिकेशन को वर्तमान में और हाल ही में चल रहे कार्यों की जानकारी प्राप्त करने देता है. दुर्भावनापूर्ण एप्लिकेशन अन्य एप्लिकेशन के बारे में निजी जानकारी खोज सकते हैं."</string>
-    <string name="permlab_reorderTasks" msgid="2018575526934422779">"चल रहे एप्‍लिकेशन पुन: क्रमित करें"</string>
-    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"एप्लिकेशन को कार्यों को अग्रभूमि और पृष्‍ठभूमि पर ले जाने देता है. एप्लिकेशन आपके इनपुट के बिना यह कर सकता है."</string>
-    <string name="permlab_removeTasks" msgid="6821513401870377403">"चलने वाले एप्लिकेशन रोकें"</string>
-    <string name="permdesc_removeTasks" msgid="1394714352062635493">"किसी एप्‍लिकेशन को कार्यों को निकालने और उनके एप्‍लिकेशन समाप्त करने देता है. दुर्भावनापूर्ण एप्‍लिकेशन अन्‍य एप्‍लिकेशन का व्‍यवहार बाधित कर सकते हैं."</string>
+    <string name="permdesc_manageUsers" msgid="8409306667645355638">"एप्स को उपकरण पर क्वेरी, निर्माण और हटाने सहित उपयोगकर्ताओं को प्रबंधित करने की सुविधा देता है."</string>
+    <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"चल रहे एप्‍स के विवरण प्राप्त करें"</string>
+    <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"एप्स को वर्तमान में और हाल ही में चल रहे कार्यों की जानकारी प्राप्त करने देता है. दुर्भावनापूर्ण एप्स अन्य एप्स के बारे में निजी जानकारी खोज सकते हैं."</string>
+    <string name="permlab_reorderTasks" msgid="2018575526934422779">"चल रहे एप्‍स पुन: क्रमित करें"</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"एप्स को कार्यों को अग्रभूमि और पृष्‍ठभूमि पर ले जाने देता है. एप्स आपके इनपुट के बिना यह कर सकता है."</string>
+    <string name="permlab_removeTasks" msgid="6821513401870377403">"चलने वाले एप्स रोकें"</string>
+    <string name="permdesc_removeTasks" msgid="1394714352062635493">"किसी एप्‍स को कार्यों को निकालने और उनके एप्‍स समाप्त करने देता है. दुर्भावनापूर्ण एप्‍स अन्‍य एप्‍स का व्‍यवहार बाधित कर सकते हैं."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"गतिविधि स्टैक प्रबंधित करें"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"एप्स को ऐसे गतिविधि स्टैक जोड़ने, निकालने, और बदलने देता है जिनमें अन्य एप्स चलते हों. दुर्भावनापूर्ण एप्स अन्य एप्स के व्यवहार में बाधा डाल सकते हैं."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"कोई गतिविधि प्रारंभ करें"</string>
-    <string name="permdesc_startAnyActivity" msgid="997823695343584001">"अनुमति सुरक्षा या निर्यात की स्‍थिति पर ध्‍यान दिए बिना, एप्‍लिकेशन को कोई गतिविधि प्रारंभ करने देता है."</string>
+    <string name="permdesc_startAnyActivity" msgid="997823695343584001">"अनुमति सुरक्षा या निर्यात की स्‍थिति पर ध्‍यान दिए बिना, एप्‍स को कोई गतिविधि प्रारंभ करने देता है."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"स्‍क्रीन संगतता सेट करें"</string>
-    <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"एप्‍लिकेशन को अन्‍य एप्‍लिकेशन के स्‍क्रीन संगतता मोड को नियंत्रित करने देता है. दुर्भावनापूर्ण एप्‍लिकेशन अन्‍य एप्‍लिकेशन का व्‍यवहार बाधित कर सकते हैं."</string>
-    <string name="permlab_setDebugApp" msgid="3022107198686584052">"एप्‍लिकेशन डीबग करना सक्षम करें"</string>
-    <string name="permdesc_setDebugApp" msgid="4474512416299013256">"एप्लिकेशन को अन्य एप्लिकेशन के लिए डीबग किया जाना चालू करने देता है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग अन्य एप्लिकेशन को समाप्त करने के लिए कर सकते हैं."</string>
+    <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"एप्‍स को अन्‍य एप्‍स के स्‍क्रीन संगतता मोड को नियंत्रित करने देता है. दुर्भावनापूर्ण एप्‍स अन्‍य एप्‍स का व्‍यवहार बाधित कर सकते हैं."</string>
+    <string name="permlab_setDebugApp" msgid="3022107198686584052">"एप्‍स डीबग करना सक्षम करें"</string>
+    <string name="permdesc_setDebugApp" msgid="4474512416299013256">"एप्स को अन्य एप्स के लिए डीबग किया जाना चालू करने देता है. दुर्भावनापूर्ण एप्स इसका उपयोग अन्य एप्स को समाप्त करने के लिए कर सकते हैं."</string>
     <string name="permlab_changeConfiguration" msgid="4162092185124234480">"सिस्‍टम प्रदर्शन सेटिंग बदलें"</string>
-    <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"एप्लिकेशन को वर्तमान कॉन्फ़िगरेशन, जैसे स्थान या समग्र फ़ॉन्ट आकार, बदलने देता है."</string>
+    <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"एप्स को वर्तमान कॉन्फ़िगरेशन, जैसे स्थान या समग्र अक्षरों का आकार, बदलने देता है."</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_forceStopPackages" msgid="2329627428832067700">"अन्‍य एप्‍लिकेशन बलपूर्वक बंद करें"</string>
-    <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"एप्लिकेशन को अन्य एप्लिकेशन बलपूर्वक बंद करने देता है."</string>
-    <string name="permlab_forceBack" msgid="652935204072584616">"एप्‍लिकेशन को बलपूर्वक बंद करें"</string>
-    <string name="permdesc_forceBack" msgid="3892295830419513623">"एप्लिकेशन को अग्रभूमि में चल रही कोई भी गतिविधि बलपूर्वक बंद करने और वापस जाने देता है. सामान्‍य एप्‍लिकेशन के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</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_forceStopPackages" msgid="2329627428832067700">"अन्‍य एप्‍स बलपूर्वक बंद करें"</string>
+    <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"एप्स को अन्य एप्स बलपूर्वक बंद करने देता है."</string>
+    <string name="permlab_forceBack" msgid="652935204072584616">"एप्‍स को बलपूर्वक बंद करें"</string>
+    <string name="permdesc_forceBack" msgid="3892295830419513623">"एप्स को अग्रभूमि में चल रही कोई भी गतिविधि बलपूर्वक बंद करने और वापस जाने देता है. सामान्‍य एप्‍स के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
     <string name="permlab_dump" msgid="1681799862438954752">"सिस्‍टम की आंतरिक स्‍थिति पुनर्प्राप्त करें"</string>
-    <string name="permdesc_dump" msgid="1778299088692290329">"एप्‍लिकेशन को सिस्‍टम की आंतरिक स्‍थिति पुनर्प्राप्त करने देता है. दुर्भावनापूर्ण एप्‍लिकेशन विभिन्‍न प्रकार की निजी और सुरक्षा जानकारी प्राप्त कर सकते हैं जिनकी उन्‍हें सामान्‍यत: आवश्‍यकता नहीं होती."</string>
+    <string name="permdesc_dump" msgid="1778299088692290329">"एप्‍स को सिस्‍टम की आंतरिक स्‍थिति पुनर्प्राप्त करने देता है. दुर्भावनापूर्ण एप्‍स विभिन्‍न प्रकार की निजी और सुरक्षा जानकारी प्राप्त कर सकते हैं जिनकी उन्‍हें सामान्‍यत: आवश्‍यकता नहीं होती."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"स्‍क्रीन सामग्री पुनर्प्राप्त करें"</string>
-    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"एप्‍लिकेशन को सक्रिय विंडो की सामग्री पुनर्प्राप्त करने देता है. दुर्भावनापूर्ण एप्‍लिकेशन विंडो की संपूर्ण सामग्री प्राप्त कर सकते हैं और पासवर्ड को छोड़कर इसके सभी पाठ जांच सकते हैं."</string>
+    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"एप्‍स को सक्रिय विंडो की सामग्री पुनर्प्राप्त करने देता है. दुर्भावनापूर्ण एप्‍स विंडो की संपूर्ण सामग्री प्राप्त कर सकते हैं और पासवर्ड को छोड़कर इसके सभी पाठ जांच सकते हैं."</string>
     <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"पहुंच-योग्यता को अस्थायी रूप से सक्षम करें"</string>
-    <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"एप्लिकेशन को उपकरण पर पहुंच-योग्यता को अस्थायी रूप से सक्षम करने देता है. दुर्भावनापूर्ण एप्लिकेशन उपयोगकर्ता की सहमति के बिना पहुंच-योग्यता को सक्षम कर सकते हैं."</string>
+    <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"एप्स को उपकरण पर पहुंच-योग्यता को अस्थायी रूप से सक्षम करने देता है. दुर्भावनापूर्ण एप्स उपयोगकर्ता की सहमति के बिना पहुंच-योग्यता को सक्षम कर सकते हैं."</string>
     <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"विंडो जानकारी प्राप्त करें"</string>
-    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"एप्‍लिकेशन को विंडो प्रबंधक से windows के बारे में जानकारी प्राप्त करने देता है. दुर्भावनापूर्ण एप्‍लिकेशन आंतरिक सिस्टम उपयोग के लिए अभिप्रेत जानकारी को प्राप्त कर सकते हैं."</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"एप्‍स को विंडो प्रबंधक से windows के बारे में जानकारी प्राप्त करने देता है. दुर्भावनापूर्ण एप्‍स आंतरिक सिस्टम उपयोग के लिए अभिप्रेत जानकारी को प्राप्त कर सकते हैं."</string>
     <string name="permlab_filter_events" msgid="8675535648807427389">"ईवेंट फ़िल्टर करें"</string>
-    <string name="permdesc_filter_events" msgid="8006236315888347680">"एप्‍लिकेशन को इनपुट फ़िल्‍टर पंजीकृत करने देता है, जो सभी उपयोगकर्ता ईवेंट के स्‍ट्रीम को भेजे जाने से पहले फ़िल्‍टर करता है. दुर्भावनापूर्ण एप्‍लिकेशन उपयोगकर्ता के हस्‍तक्षेप के बिना सिस्‍टम UI को नियंत्रित कर सकता है."</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"एप्‍स को इनपुट फ़िल्‍टर पंजीकृत करने देता है, जो सभी उपयोगकर्ता ईवेंट के स्‍ट्रीम को भेजे जाने से पहले फ़िल्‍टर करता है. दुर्भावनापूर्ण एप्‍स उपयोगकर्ता के हस्‍तक्षेप के बिना सिस्‍टम UI को नियंत्रित कर सकता है."</string>
     <string name="permlab_magnify_display" msgid="5973626738170618775">"डिस्प्ले को आवर्धित करें"</string>
-    <string name="permdesc_magnify_display" msgid="7121235684515003792">"एप्लिकेशन को डिस्प्ले की सामग्री आवर्धित करने देता है. दुर्भावनापूर्ण एप्लिकेशन डिस्प्ले सामग्री को इस तरह से बदल सकते हैं कि उपकरण अनुपयोगी रेंडर होता है."</string>
+    <string name="permdesc_magnify_display" msgid="7121235684515003792">"एप्स को डिस्प्ले की सामग्री आवर्धित करने देता है. दुर्भावनापूर्ण एप्स डिस्प्ले सामग्री को इस तरह से बदल सकते हैं कि उपकरण अनुपयोगी रेंडर होता है."</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"आंशिक शटडाउन"</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"गतिविधि प्रबंधक को शटडाउन स्‍थिति में रखता है. पूर्ण शटडाउन निष्‍पादित नहीं करता है."</string>
-    <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"एप्‍लिकेशन स्‍विच करने से रोकता है"</string>
-    <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"उपयोगकर्ता को दूसरे एप्‍लिकेशन पर स्‍विच करने से रोकता है."</string>
-    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"वर्तमान एप्लिकेशन की जानकारी प्राप्त करें"</string>
-    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"धारक को स्क्रीन के अग्रभाग में स्थित वर्तमान एप्लिकेशन के बारे में निजी जानकारी प्राप्त करने देती है."</string>
-    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"सभी एप्‍लिकेशन की लॉन्‍चिंग की निगरानी करें और उसे नियंत्रित करें"</string>
-    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"एप्लिकेशन को यह निगरानी और नियंत्रित करने देता है कि सिस्टम कैसे गतिविधियां लॉन्च करता है. दुर्भावनापूर्ण एप्लिकेशन सिस्टम को पूरी तरह से जोखिम में डाल सकते हैं. इस अनुमति की आवश्यकता केवल विकास के लिए है, सामान्य उपयोग के लिए कभी नहीं."</string>
+    <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"एप्‍स स्‍विच करने से रोकता है"</string>
+    <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"उपयोगकर्ता को दूसरे एप्‍स पर स्‍विच करने से रोकता है."</string>
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"वर्तमान एप्स की जानकारी प्राप्त करें"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"धारक को स्क्रीन के अग्रभाग में स्थित वर्तमान एप्स के बारे में निजी जानकारी प्राप्त करने देती है."</string>
+    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"सभी एप्‍स की लॉन्‍चिंग की निगरानी करें और उसे नियंत्रित करें"</string>
+    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"एप्स को यह निगरानी और नियंत्रित करने देता है कि सिस्टम कैसे गतिविधियां लॉन्च करता है. दुर्भावनापूर्ण एप्स सिस्टम को पूरी तरह से जोखिम में डाल सकते हैं. इस अनुमति की आवश्यकता केवल विकास के लिए है, सामान्य उपयोग के लिए कभी नहीं."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"पैकेज निकाले गए प्रसारण भेजें"</string>
-    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"एप्लिकेशन को कोई ऐसी सूचना प्रसारित करने देता है जिसे किसी एप्लिकेशन पैकेज ने निकाल दिया गया हो. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग चल रहे अन्य एप्लिकेशन को समाप्त करने के लिए कर सकते हैं."</string>
+    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"एप्स को कोई ऐसी सूचना प्रसारित करने देता है जिसे किसी एप्स पैकेज ने निकाल दिया गया हो. दुर्भावनापूर्ण एप्स इसका उपयोग चल रहे अन्य एप्स को समाप्त करने के लिए कर सकते हैं."</string>
     <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"SMS-प्राप्त प्रसार भेजें"</string>
-    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"एप्लिकेशन को वह सूचना प्रसारित करने देता है जो SMS संदेश ने प्राप्त की है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग नकली इनकमिंग संदेश गढ़ने के लिए कर सकते हैं."</string>
+    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"एप्स को वह सूचना प्रसारित करने देता है जो SMS संदेश ने प्राप्त की है. दुर्भावनापूर्ण एप्स इसका उपयोग नकली इनकमिंग संदेश गढ़ने के लिए कर सकते हैं."</string>
     <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"WAP-PUSH-प्राप्त प्रसारण भेजें"</string>
-    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"एप्लिकेशन को वह सूचना प्रसारित करने देता है जो WAP PUSH संदेश को प्राप्त हुआ है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग नकली MMS संदेश प्राप्त करने या किसी वेबपृष्ठ की सामग्री को दुर्भावनापूर्ण दूसरे रूप से चुपचाप प्रतिस्थापित करने के लिए कर सकते हैं."</string>
+    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"एप्स को वह सूचना प्रसारित करने देता है जो WAP PUSH संदेश को प्राप्त हुआ है. दुर्भावनापूर्ण एप्स इसका उपयोग नकली MMS संदेश प्राप्त करने या किसी वेबपृष्ठ की सामग्री को दुर्भावनापूर्ण दूसरे रूप से चुपचाप प्रतिस्थापित करने के लिए कर सकते हैं."</string>
     <string name="permlab_setProcessLimit" msgid="2451873664363662666">"चल रही प्रक्रियाओं की संख्‍या सीमित करें"</string>
-    <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"एप्लिकेशन को चलाई जाने वाली अधिकतम प्रक्रियाओं को नियंत्रित करने देता है. सामान्य एप्लिकेशन के लिए कभी आवश्यक नहीं होती."</string>
-    <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"पृष्ठभूमि एप्‍लिकेशन को बलपूर्वक बंद करें"</string>
-    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"एप्लिकेशन को यह नियंत्रित करने देता है कि पृष्ठभूमि में जाते ही गतिविधियां पूर्ण हो जाती है या नही. सामान्य एप्लिकेशन के लिए कभी आवश्यकता नहीं होती."</string>
+    <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"एप्स को चलाई जाने वाली अधिकतम प्रक्रियाओं को नियंत्रित करने देता है. सामान्य एप्स के लिए कभी आवश्यक नहीं होती."</string>
+    <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"पृष्ठभूमि एप्‍स को बलपूर्वक बंद करें"</string>
+    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"एप्स को यह नियंत्रित करने देता है कि पृष्ठभूमि में जाते ही गतिविधियां पूर्ण हो जाती है या नही. सामान्य एप्स के लिए कभी आवश्यकता नहीं होती."</string>
     <string name="permlab_batteryStats" msgid="2789610673514103364">"बैटरी के आंकड़े पढ़ें"</string>
-    <string name="permdesc_batteryStats" msgid="5897346582882915114">"एप्लिकेशन को वर्तमान निम्न-स्तरीय बैटरी उपयोग डेटा पढ़ने देती है. एप्लिकेशन को आपके द्वारा उपयोग किए जाने वाले एप्लिकेशन के बारे में विस्तृत जानकारी ढूंढने दे सकती है."</string>
+    <string name="permdesc_batteryStats" msgid="5897346582882915114">"एप्स को वर्तमान निम्न-स्तरीय बैटरी उपयोग डेटा पढ़ने देती है. एप्स को आपके द्वारा उपयोग किए जाने वाले एप्स के बारे में विस्तृत जानकारी ढूंढने दे सकती है."</string>
     <string name="permlab_updateBatteryStats" msgid="3719689764536379557">"बैटरी के आंकड़े संशोधित करें"</string>
-    <string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"एप्‍लिकेशन को बैटरी के संकलित आंकड़ों को संशोधित करने देती है. सामान्‍य एप्‍लिकेशन के द्वारा उपयोग करने के लिए नहीं."</string>
-    <string name="permlab_getAppOpsStats" msgid="1508779687436585744">"एप्लिकेशन संचालन आंकड़े प्राप्त करें"</string>
-    <string name="permdesc_getAppOpsStats" msgid="6243887041577912877">"एप्लिकेशन को संकलित एप्लिकेशन संचालन आंकड़े प्राप्त करने देता है. सामान्य एप्लिकेशन के द्वारा उपयोग के लिए नहीं."</string>
-    <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"एप्लिकेशन कार्यवाही के आंकड़े बदलें"</string>
-    <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"एप्लिकेशन को एप्लिकेशन कार्यवाही के एकत्रित आंकड़े बदलने देता है. सामान्य एप्लिकेशन के द्वारा उपयोग करने के लिए नहीं."</string>
-    <string name="permlab_backup" msgid="470013022865453920">"सिस्‍टम बैकअप नियंत्रित और पुनर्स्‍थापित करें"</string>
-    <string name="permdesc_backup" msgid="6912230525140589891">"एप्लिकेशन को सिस्टम के बैकअप को नियंत्रित और क्रियाविधि को पुर्नस्थापित करने देता है. सामान्‍य एप्‍लिकेशन द्वारा उपयोग करने के लिए नहीं."</string>
-    <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"पूर्ण बैकअप या पुनर्स्‍थापना कार्यवाही की पुष्टि करें"</string>
-    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"एप्‍लिकेशन को पूर्ण बैकअप पुष्टिकरण UI लॉन्‍च करने देता है. किसी एप्‍लिकेशन द्वारा उपयोग के लिए नहीं."</string>
+    <string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"एप्‍स को बैटरी के संकलित आंकड़ों को संशोधित करने देती है. सामान्‍य एप्‍स के द्वारा उपयोग करने के लिए नहीं."</string>
+    <string name="permlab_getAppOpsStats" msgid="1508779687436585744">"एप्स संचालन आंकड़े प्राप्त करें"</string>
+    <string name="permdesc_getAppOpsStats" msgid="6243887041577912877">"एप्स को संकलित एप्स संचालन आंकड़े प्राप्त करने देता है. सामान्य एप्स के द्वारा उपयोग के लिए नहीं."</string>
+    <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"एप्स कार्यवाही के आंकड़े बदलें"</string>
+    <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"एप्स को एप्स कार्यवाही के एकत्रित आंकड़े बदलने देता है. सामान्य एप्स के द्वारा उपयोग करने के लिए नहीं."</string>
+    <string name="permlab_backup" msgid="470013022865453920">"सिस्‍टम सुरक्षा नियंत्रित और पुनर्स्‍थापित करें"</string>
+    <string name="permdesc_backup" msgid="6912230525140589891">"एप्स को सिस्टम के बैकअप को नियंत्रित और क्रियाविधि को पुर्नस्थापित करने देता है. सामान्‍य एप्‍स द्वारा उपयोग करने के लिए नहीं."</string>
+    <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"पूर्ण सुरक्षा या पुनर्स्‍थापना कार्यवाही की पुष्टि करें"</string>
+    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"एप्‍स को पूर्ण बैकअप पुष्टिकरण UI लॉन्‍च करने देता है. किसी एप्‍स द्वारा उपयोग के लिए नहीं."</string>
     <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"अनधिकृत विंडो दिखाएं"</string>
-    <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"किसी एप्‍लिकेशन को ऐसी विंडो बनाने देता है जिनका उपयोग आंतरिक सिस्‍टम उपयोगकर्ता इंटरफ़ेस द्वारा किया जाना है. सामान्‍य एप्‍लिकेशन द्वारा उपयोग करने के लिए नहीं."</string>
-    <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"अन्‍य एप्‍लिकेशन पर खींचें"</string>
-    <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"एप्लिकेशन को अन्य एप्लिकेशन के शीर्ष पर या उपयोगकर्ता इंटरफ़ेस के हिस्सों पर आने देती है. वे किसी भी एप्लिकेशन में इंटरफ़ेस के आपके उपयोग में हस्तक्षेप कर सकते हैं, या उस चीज को बदल सकती है जिसके बारे में आपको लगता है कि आप उसे अन्य एप्लिकेशन में देख रहे हैं."</string>
+    <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"किसी एप्‍स को ऐसी विंडो बनाने देता है जिनका उपयोग आंतरिक सिस्‍टम उपयोगकर्ता इंटरफ़ेस द्वारा किया जाना है. सामान्‍य एप्‍स द्वारा उपयोग करने के लिए नहीं."</string>
+    <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"अन्‍य एप्‍स पर खींचें"</string>
+    <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"एप्स को अन्य एप्स के शीर्ष पर या उपयोगकर्ता इंटरफ़ेस के हिस्सों पर आने देती है. वे किसी भी एप्स में इंटरफ़ेस के आपके उपयोग में हस्तक्षेप कर सकते हैं, या उस चीज को बदल सकती है जिसके बारे में आपको लगता है कि आप उसे अन्य एप्स में देख रहे हैं."</string>
     <string name="permlab_setAnimationScale" msgid="2805103241153907174">"वैश्विक एनिमेशन गति बदलें"</string>
-    <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"एप्‍लिकेशन को किसी भी समय वैश्विक एनिमेशन गति (तेज़ या धीमे एनिमेशन) बदलने देता है."</string>
-    <string name="permlab_manageAppTokens" msgid="1286505717050121370">"एप्‍लिकेशन टोकन प्रबंधित करें"</string>
-    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"एप्लिकेशन को उनके सामान्य Z-क्रमों पर न पहुंचते हुए उनके स्वयं के टोकन बनाने और प्रबंधित करने देता है. सामान्‍य एप्‍लिकेशन के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
+    <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"एप्‍स को किसी भी समय वैश्विक एनिमेशन गति (तेज़ या धीमे एनिमेशन) बदलने देता है."</string>
+    <string name="permlab_manageAppTokens" msgid="1286505717050121370">"एप्‍स टोकन प्रबंधित करें"</string>
+    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"एप्स को उनके सामान्य Z-क्रमों पर न पहुंचते हुए उनके स्वयं के टोकन बनाने और प्रबंधित करने देता है. सामान्‍य एप्‍स के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
     <string name="permlab_freezeScreen" msgid="4708181184441880175">"स्क्रीन को स्थिर करें"</string>
-    <string name="permdesc_freezeScreen" msgid="8558923789222670064">"पूर्ण-स्क्रीन संक्रमण के लिए एप्लिकेशन को अस्थायी रूप से स्क्रीन को स्थिर करने देता है."</string>
+    <string name="permdesc_freezeScreen" msgid="8558923789222670064">"पूर्ण-स्क्रीन संक्रमण के लिए एप्स को अस्थायी रूप से स्क्रीन को स्थिर करने देता है."</string>
     <string name="permlab_injectEvents" msgid="1378746584023586600">"कुंजियों और नियंत्रण बटन को दबाएं"</string>
-    <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"एप्‍लिकेशन को स्‍वयं के इनपुट ईवेंट (कुंजी दबाना, आदि) को अन्‍य एप्‍लिकेशन को वितरित करने देता है. दुर्भावनापूर्ण एप्‍लिकेशन टेबलेट को टेक ओवर करने में इसका उपयोग कर सकते हैं."</string>
-    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"एप्‍लिकेशन को स्‍वयं के इनपुट ईवेंट (कुंजी दबाना, आदि) अन्‍य एप्‍लिकेशन को वितरित करने देता है. दुर्भावनापूर्ण एप्‍लिकेशन इसका उपयोग फ़ोन को टेक ओवर करने में कर सकते हैं."</string>
+    <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"एप्‍स को स्‍वयं के इनपुट ईवेंट (कुंजी दबाना, आदि) को अन्‍य एप्‍स को वितरित करने देता है. दुर्भावनापूर्ण एप्‍स टेबलेट को टेक ओवर करने में इसका उपयोग कर सकते हैं."</string>
+    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"एप्‍स को स्‍वयं के इनपुट ईवेंट (कुंजी दबाना, आदि) अन्‍य एप्‍स को वितरित करने देता है. दुर्भावनापूर्ण एप्‍स इसका उपयोग फ़ोन को टेक ओवर करने में कर सकते हैं."</string>
     <string name="permlab_readInputState" msgid="469428900041249234">"आप जो भी लिखते हैं और जो कार्यवाहियां करते हैं उन्‍हें रिकॉर्ड करें"</string>
-    <string name="permdesc_readInputState" msgid="8387754901688728043">"एप्लिकेशन को अन्य एप्लिकेशन के साथ सहभागिता करते समय भी आपके द्वारा दबाई जाने वाली कुंजियां देखने देता है (जैसे कोई पासवर्ड लिखना). सामान्‍य एप्‍लिकेशन के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
+    <string name="permdesc_readInputState" msgid="8387754901688728043">"एप्स को अन्य एप्स के साथ सहभागिता करते समय भी आपके द्वारा दबाई जाने वाली कुंजियां देखने देता है (जैसे कोई पासवर्ड लिखना). सामान्‍य एप्‍स के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
     <string name="permlab_bindInputMethod" msgid="3360064620230515776">"किसी इनपुट विधि से आबद्ध करें"</string>
-    <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"धारक को किसी इनपुट विधि के शीर्ष-स्‍तर इंटरफ़ेस से आबद्ध होने देता है. सामान्‍य एप्‍लिकेशन के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
+    <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"धारक को किसी इनपुट विधि के शीर्ष-स्‍तर इंटरफ़ेस से आबद्ध होने देता है. सामान्‍य एप्‍स के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"पहुंच-योग्‍यता सेवा से आबद्ध करें"</string>
-    <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"धारक को किसी पहुंच-योग्यता सेवा के शीर्ष-स्‍तर इंटरफ़ेस से आबद्ध होने देता है. सामान्‍य एप्‍लिकेशन के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
+    <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"धारक को किसी पहुंच-योग्यता सेवा के शीर्ष-स्‍तर इंटरफ़ेस से आबद्ध होने देता है. सामान्‍य एप्‍स के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"प्रिंट सेवा से आबद्ध करें"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"धारक को किसी प्रिंट सेवा के शीर्ष-स्‍तर इंटरफ़ेस से आबद्ध होने देता है. सामान्‍य एप्‍स के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"प्रिंट स्पूलर सेवा से आबद्ध करें"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"धारक को प्रिंट स्पूलर सेवा के शीर्ष-स्‍तर इंटरफ़ेस से आबद्ध होने देता है. सामान्‍य एप्‍स के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC सेवा से आबद्ध रहें"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"धारक को ऐसे एप्स से आबद्ध रहने देता है जो NFC कार्ड का अनुकरण कर रहे हैं. सामान्य एप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"किसी पाठ सेवा पर बने रहें"</string>
-    <string name="permdesc_bindTextService" msgid="8151968910973998670">"धारक को किसी पाठ सेवा (उदा. SpellCheckerService) के शीर्ष-स्‍तर इंटरफ़ेस पर आबद्ध होने देता है. सामान्‍य एप्‍लिकेशन के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
+    <string name="permdesc_bindTextService" msgid="8151968910973998670">"धारक को किसी पाठ सेवा (उदा. SpellCheckerService) के शीर्ष-स्‍तर इंटरफ़ेस पर आबद्ध होने देता है. सामान्‍य एप्‍स के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"किसी VPN सेवा से आबद्ध करें"</string>
-    <string name="permdesc_bindVpnService" msgid="2067845564581693905">"धारक को किसी Vpn सेवा के शीर्ष-स्‍तर इंटरफ़ेस से आबद्ध होने देता है. सामान्‍य एप्‍लिकेशन के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
+    <string name="permdesc_bindVpnService" msgid="2067845564581693905">"धारक को किसी Vpn सेवा के शीर्ष-स्‍तर इंटरफ़ेस से आबद्ध होने देता है. सामान्‍य एप्‍स के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"वॉलपेपर से आबद्ध करें"</string>
-    <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"धारक को किसी वॉलपेपर के शीर्ष-स्‍तर इंटरफ़ेस से आबद्ध होने देता है. सामान्‍य एप्‍लिकेशन के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
+    <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"धारक को किसी वॉलपेपर के शीर्ष-स्‍तर इंटरफ़ेस से आबद्ध होने देता है. सामान्‍य एप्‍स के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"किसी विजेट सेवा से आबद्ध करें"</string>
-    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"धारक को किसी विजेट सेवा के शीर्ष-स्‍तर इंटरफ़ेस से आबद्ध होने देता है. सामान्‍य एप्‍लिकेशन के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
+    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"धारक को किसी विजेट सेवा के शीर्ष-स्‍तर इंटरफ़ेस से आबद्ध होने देता है. सामान्‍य एप्‍स के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"किसी उपकरण व्‍यवस्‍थापक के साथ सहभागिता करें"</string>
-    <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"धारक को किसी उपकरण व्‍यवस्‍थापक को उद्देश्य भेजने देता है. सामान्‍य एप्‍लिकेशन के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
+    <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"धारक को किसी उपकरण व्‍यवस्‍थापक को उद्देश्य भेजने देता है. सामान्‍य एप्‍स के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"उपकरण उपकरण सुचारू ढ़ंग से चलाने वाले को जोड़ें या निकालें"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"धारक को सक्रिय डिवाइस व्यवस्थापकों को जोड़ने या निकालने देता है. सामान्य एप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"स्‍क्रीन अभिविन्‍यास बदलें"</string>
-    <string name="permdesc_setOrientation" msgid="3046126619316671476">"एप्‍लिकेशन को किसी भी समय स्‍क्रीन का रोटेशन बदलने देता है. सामान्‍य एप्‍लिकेशन के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
+    <string name="permdesc_setOrientation" msgid="3046126619316671476">"एप्‍स को किसी भी समय स्‍क्रीन का रोटेशन बदलने देता है. सामान्‍य एप्‍स के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"सूचक गति बदलें"</string>
-    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"एप्लिकेशन को माउस या ट्रैकपैड सूचक गति को किसी भी समय बदलने देता है. सामान्‍य एप्‍लिकेशन के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
+    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"एप्स को माउस या ट्रैकपैड सूचक गति को किसी भी समय बदलने देता है. सामान्‍य एप्‍स के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
     <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"कीबोर्ड लेआउट बदलें"</string>
-    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"एप्‍लिकेशन को कीबोर्ड लेआउट बदलने देता है. सामान्‍य एप्‍लिकेशन के लिए कभी आवश्‍यक नहीं है."</string>
-    <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"एप्लिकेशन को Linux सिग्नल भेजें"</string>
-    <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"एप्‍लिकेशन को यह अनुरोध करने देता है कि दिया गया सिग्नल सभी जारी प्रक्रियाओं को भेजा जाए."</string>
-    <string name="permlab_persistentActivity" msgid="8841113627955563938">"एप्‍लिकेशन को हमेशा चलने वाला बनाएं"</string>
-    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"एप्‍लिकेशन को स्मृति में स्‍वयं के कुछ हिस्सों को लगातार बनाने की अनुमति देता है. यह अन्‍य एप्लिकेशन के लिए उपलब्‍ध स्‍मृति को सीमित कर टेबलेट को धीमा कर सकता है."</string>
-    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"एप्‍लिकेशन को स्मृति में स्‍वयं के कुछ हिस्सों को लगातार बनाने देता है. यह अन्‍य एप्लिकेशन के लिए उपलब्‍ध स्‍मृति को सीमित कर फ़ोन को धीमा कर सकता है."</string>
-    <string name="permlab_deletePackages" msgid="184385129537705938">"एप्‍लिकेशन हटाएं"</string>
-    <string name="permdesc_deletePackages" msgid="7411480275167205081">"एप्लिकेशन को Android पैकेज हटाने देता है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग महत्वपूर्ण एप्लिकेशन हटाने के लिए कर सकते हैं."</string>
-    <string name="permlab_clearAppUserData" msgid="274109191845842756">"अन्‍य एप्‍लिकेशन का डेटा हटाएं"</string>
-    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"एप्लिकेशन को उपयोगकर्ता डेटा साफ़ करने देता है."</string>
-    <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"अन्‍य एप्‍लिकेशन के संचय हटाएं"</string>
-    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"एप्लिकेशन को संचय फ़ाइलें हटाने देता है."</string>
-    <string name="permlab_getPackageSize" msgid="7472921768357981986">"एप्लिकेशन संग्रहण स्थान मापें"</string>
-    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"एप्लिकेशन को उसका कोड, डेटा, और संचय आकारों को प्राप्त करने देता है"</string>
-    <string name="permlab_installPackages" msgid="2199128482820306924">"सीधे एप्‍लिकेशन इंस्‍टॉल करें"</string>
-    <string name="permdesc_installPackages" msgid="5628530972548071284">"एप्लिकेशन को नए या अपडेट किए गए Android पैकेज इंस्टॉल करने देता है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग अनियंत्रित रूप से सशक्त अनुमतियों वाले नए एप्लिकेशन जोड़ने में कर सकते हैं."</string>
-    <string name="permlab_clearAppCache" msgid="7487279391723526815">"सभी एप्लिकेशन संचय डेटा हटाएं"</string>
-    <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"एप्लिकेशन को अन्य एप्लिकेशन की संचय निर्देशिकाओं में से फ़ाइलें हटाकर टेबलेट संग्रहण को खाली करने देती है. इससे अन्य एप्लिकेशन अधिक धीमे प्रारंभ हो सकते हैं क्योंकि उन्हें अपना डेटा पुनर्प्राप्त करने की आवश्यकता होती है."</string>
-    <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"एप्लिकेशन को अन्य एप्लिकेशन की संचय निर्देशिकाओं में से फ़ाइलें हटाकर फ़ोन संग्रहण को खाली करने देती है. इससे अन्य एप्लिकेशन अधिक धीमे प्रारंभ हो सकते हैं क्योंकि उन्हें अपना डेटा पुनर्प्राप्त करने की आवश्यकता होती है."</string>
-    <string name="permlab_movePackage" msgid="3289890271645921411">"एप्‍लिकेशन संसाधनों को ले जाएं"</string>
-    <string name="permdesc_movePackage" msgid="319562217778244524">"एप्‍लिकेशन को एप्‍लिकेशन संसाधनों को आंतरिक से बाहरी मीडिया में और इसके विपरीत ले जाने देता है."</string>
+    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"एप्‍स को कीबोर्ड लेआउट बदलने देता है. सामान्‍य एप्‍स के लिए कभी आवश्‍यक नहीं है."</string>
+    <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"एप्स को Linux सिग्नल भेजें"</string>
+    <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"एप्‍स को यह अनुरोध करने देता है कि दिया गया सिग्नल सभी जारी प्रक्रियाओं को भेजा जाए."</string>
+    <string name="permlab_persistentActivity" msgid="8841113627955563938">"एप्‍स को हमेशा चलने वाला बनाएं"</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"एप्‍स को स्मृति में स्‍वयं के कुछ हिस्सों को लगातार बनाने की अनुमति देता है. यह अन्‍य एप्स के लिए उपलब्‍ध स्‍मृति को सीमित कर टेबलेट को धीमा कर सकता है."</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"एप्‍स को स्मृति में स्‍वयं के कुछ हिस्सों को लगातार बनाने देता है. यह अन्‍य एप्स के लिए उपलब्‍ध स्‍मृति को सीमित कर फ़ोन को धीमा कर सकता है."</string>
+    <string name="permlab_deletePackages" msgid="184385129537705938">"एप्‍स हटाएं"</string>
+    <string name="permdesc_deletePackages" msgid="7411480275167205081">"एप्स को Android पैकेज हटाने देता है. दुर्भावनापूर्ण एप्स इसका उपयोग महत्वपूर्ण एप्स हटाने के लिए कर सकते हैं."</string>
+    <string name="permlab_clearAppUserData" msgid="274109191845842756">"अन्‍य एप्‍स का डेटा हटाएं"</string>
+    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"एप्स को उपयोगकर्ता डेटा साफ़ करने देता है."</string>
+    <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"अन्‍य एप्‍स के संचय हटाएं"</string>
+    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"एप्स को संचय फ़ाइलें हटाने देता है."</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"एप्स संग्रहण स्थान मापें"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"एप्स को उसका कोड, डेटा, और संचय आकारों को प्राप्त करने देता है"</string>
+    <string name="permlab_installPackages" msgid="2199128482820306924">"सीधे एप्‍स इंस्‍टॉल करें"</string>
+    <string name="permdesc_installPackages" msgid="5628530972548071284">"एप को नए या नई जानकारी वाले Android पैकेज इंस्टॉल करने देता है. दुर्भावनापूर्ण एप्स इसका उपयोग अनियंत्रित रूप से सशक्त अनुमतियों वाले नए एप्स जोड़ने में कर सकते हैं."</string>
+    <string name="permlab_clearAppCache" msgid="7487279391723526815">"सभी एप्स संचय डेटा हटाएं"</string>
+    <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"एप्स को अन्य एप्स की संचय निर्देशिकाओं में से फ़ाइलें हटाकर टेबलेट संग्रहण को खाली करने देती है. इससे अन्य एप्स अधिक धीमे प्रारंभ हो सकते हैं क्योंकि उन्हें अपना डेटा पुनर्प्राप्त करने की आवश्यकता होती है."</string>
+    <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"एप्स को अन्य एप्स की संचय निर्देशिकाओं में से फ़ाइलें हटाकर फ़ोन संग्रहण को खाली करने देती है. इससे अन्य एप्स अधिक धीमे प्रारंभ हो सकते हैं क्योंकि उन्हें अपना डेटा पुनर्प्राप्त करने की आवश्यकता होती है."</string>
+    <string name="permlab_movePackage" msgid="3289890271645921411">"एप्‍स संसाधनों को ले जाएं"</string>
+    <string name="permdesc_movePackage" msgid="319562217778244524">"एप्‍स को एप्‍स संसाधनों को आंतरिक से बाहरी मीडिया में और इसके विपरीत ले जाने देता है."</string>
     <string name="permlab_readLogs" msgid="6615778543198967614">"संवेदनशील लॉग डेटा पढ़ें"</string>
-    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"किसी एप्‍लिकेशन को सिस्‍टम की विभिन्‍न लॉग फ़ाइलों से पढ़ने देता है. संभावित रूप से व्यक्तिगत या निजी जानकारी शामिल करते हुए, टेबलेट के साथ आप क्‍या कर रहे हैं इस बारे में सामान्‍य जानकारी खोजने देता है."</string>
-    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"एप्‍लिकेशन को सिस्‍टम की विभिन्‍न लॉग फ़ाइलें पढ़ने देता है. संभावित रूप से व्यक्तिगत या निजी जानकारी सहित, यह इसे इस बारे में सामान्य जानकारी खोजने देता है कि आप फ़ोन से क्‍या कर रहे हैं."</string>
+    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"किसी एप्‍स को सिस्‍टम की विभिन्‍न लॉग फ़ाइलों से पढ़ने देता है. संभावित रूप से व्यक्तिगत या निजी जानकारी शामिल करते हुए, टेबलेट के साथ आप क्‍या कर रहे हैं इस बारे में सामान्‍य जानकारी खोजने देता है."</string>
+    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"एप्‍स को सिस्‍टम की विभिन्‍न लॉग फ़ाइलें पढ़ने देता है. संभावित रूप से व्यक्तिगत या निजी जानकारी सहित, यह इसे इस बारे में सामान्य जानकारी खोजने देता है कि आप फ़ोन से क्‍या कर रहे हैं."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"प्लेबैक के लिए किसी भी मीडिया डीकोडर का उपयोग करें"</string>
-    <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"एप्लिकेशन को प्लेबैक डीकोड करने के लिए किसी भी इंस्टॉल किए गए डीकोडर का उपयोग करने देता है."</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"एप्स को प्लेबैक डीकोड करने के लिए किसी भी इंस्टॉल किए गए डीकोडर का उपयोग करने देता है."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"विश्वसनीय क्रेडेंशियल प्रबंधित करें"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"एप्स को CA प्रमाणपत्रों को विश्वसनीय क्रेडेंशियल के रूप में इंस्टॉल और अनइंस्टॉल करने दें"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"निदान के स्‍वामित्‍व वाले संसाधनों को पढ़ें/लिखें"</string>
-    <string name="permdesc_diagnostic" msgid="6608295692002452283">"एप्‍लिकेशन को diag समूह के स्‍वामित्‍व वाले किसी संसाधन को पढ़ने और उसमें लिखने देता है; उदाहरण के लिए, /dev की फ़ाइलें. यह सिस्‍टम की स्‍थिरता और सुरक्षा को संभावित रूप से प्रभावित कर सकता है. इसका उपयोग निर्माता या ऑपरेटर द्वारा केवल हार्डवेयर-विशिष्ट निदान के लिए किया जाना चाहिए."</string>
-    <string name="permlab_changeComponentState" msgid="6335576775711095931">"एप्‍लिकेशन घटकों को सक्षम या अक्षम करें"</string>
-    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"एप्‍लिकेशन को यह बदलने देता है कि किसी अन्‍य एप्‍लिकेशन का घटक सक्षम है या नहीं. दुर्भावनापूर्ण एप्‍लिकेशन महत्‍वपूर्ण फ़ोन क्षमताओं को अक्षम करने में इसका उपयोग कर सकते हैं. इस अनुमति का उपयोग सावधानी के साथ करना चाहिए, क्योंकि इससे एप्‍लिकेशन घटकों के अनुपयोगी, असंगत, या अस्‍थिर स्‍थिति में जाने की संभावना है."</string>
-    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"एप्‍लिकेशन को यह बदलने देता है कि किसी अन्‍य एप्‍लिकेशन का घटक सक्षम है या नहीं. दुर्भावनापूर्ण एप्‍लिकेशन महत्‍वपूर्ण फ़ोन क्षमताओं को अक्षम करने में इसका उपयोग कर सकते हैं. इस अनुमति का उपयोग सावधानी के साथ करना चाहिए, क्योंकि इससे एप्‍लिकेशन घटकों के अनुपयोगी, असंगत, या अस्‍थिर स्‍थिति में जाने की संभावना है."</string>
+    <string name="permdesc_diagnostic" msgid="6608295692002452283">"एप्‍स को diag समूह के स्‍वामित्‍व वाले किसी संसाधन को पढ़ने और उसमें लिखने देता है; उदाहरण के लिए, /dev की फ़ाइलें. यह सिस्‍टम की स्‍थिरता और सुरक्षा को संभावित रूप से प्रभावित कर सकता है. इसका उपयोग निर्माता या ऑपरेटर द्वारा केवल हार्डवेयर-विशिष्ट निदान के लिए किया जाना चाहिए."</string>
+    <string name="permlab_changeComponentState" msgid="6335576775711095931">"एप्‍स घटकों को सक्षम या अक्षम करें"</string>
+    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"एप्‍स को यह बदलने देता है कि किसी अन्‍य एप्‍स का घटक सक्षम है या नहीं. दुर्भावनापूर्ण एप्‍स महत्‍वपूर्ण फ़ोन क्षमताओं को अक्षम करने में इसका उपयोग कर सकते हैं. इस अनुमति का उपयोग सावधानी के साथ करना चाहिए, क्योंकि इससे एप्‍स घटकों के अनुपयोगी, असंगत, या अस्‍थिर स्‍थिति में जाने की संभावना है."</string>
+    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"एप्‍स को यह बदलने देता है कि किसी अन्‍य एप्‍स का घटक सक्षम है या नहीं. दुर्भावनापूर्ण एप्‍स महत्‍वपूर्ण फ़ोन क्षमताओं को अक्षम करने में इसका उपयोग कर सकते हैं. इस अनुमति का उपयोग सावधानी के साथ करना चाहिए, क्योंकि इससे एप्‍स घटकों के अनुपयोगी, असंगत, या अस्‍थिर स्‍थिति में जाने की संभावना है."</string>
     <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"अनुमति दें या रद्द करें"</string>
-    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"एप्लिकेशन को उसके या अन्य एप्लिकेशन के लिए विशेष अनुमतियां देने या रद्द करने देता है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग उन सुविधाओं तक पहुंचने के लिए कर सकते हैं जो आपने उन्हें नहीं दी हैं."</string>
-    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"पसंदीदा एप्‍लिकेशन सेट करें"</string>
-    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"एप्लिकेशन को आपके पसंदीदा एप्लिकेशन को संशोधित करने देता है. दुर्भावनापूर्ण एप्लिकेशन आपसे निजी डेटा एकत्रित करने के लिए आपके मौजूदा एप्लिकेशन को स्पूफ़ करके, चलाए जाने वाले एप्लिकेशन को चुपचाप बदल सकते हैं."</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"एप्स को उसके या अन्य एप्स के लिए विशेष अनुमतियां देने या रद्द करने देता है. दुर्भावनापूर्ण एप्स इसका उपयोग उन सुविधाओं तक पहुंचने के लिए कर सकते हैं जो आपने उन्हें नहीं दी हैं."</string>
+    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"पसंदीदा एप्‍स सेट करें"</string>
+    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"एप्स को आपके पसंदीदा एप्स को संशोधित करने देता है. दुर्भावनापूर्ण एप्स आपसे निजी डेटा एकत्रित करने के लिए आपके मौजूदा एप्स को स्पूफ़ करके, चलाए जाने वाले एप्स को चुपचाप बदल सकते हैं."</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_writeSecureSettings" msgid="204676251876718288">"सुरक्षित सिस्‍टम सेटिंग बदलें"</string>
-    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"एप्लिकेशन को सिस्टम के सुरक्षित सेटिंग डेटा को संशोधित करने देता है. सामान्‍य एप्‍लिकेशन द्वारा उपयोग करने के लिए नहीं."</string>
-    <string name="permlab_writeGservices" msgid="2149426664226152185">"Google सेवाएं मैप बदलें"</string>
-    <string name="permdesc_writeGservices" msgid="1287309437638380229">"एप्‍लिकेशन को Google सेवाओं का मानचित्र संशोधित करने देता है. सामान्‍य एप्‍लिकेशन द्वारा उपयोग करने के लिए नहीं."</string>
+    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"एप्स को सिस्टम के सुरक्षित सेटिंग डेटा को संशोधित करने देता है. सामान्‍य एप्‍स द्वारा उपयोग करने के लिए नहीं."</string>
+    <string name="permlab_writeGservices" msgid="2149426664226152185">"Google सेवाएं नक्शा बदलें"</string>
+    <string name="permdesc_writeGservices" msgid="1287309437638380229">"एप्‍स को Google सेवाओं का नक्शे संशोधित करने देता है. सामान्‍य एप्‍स द्वारा उपयोग करने के लिए नहीं."</string>
     <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"प्रारंभ होने पर चलाएं"</string>
-    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"एप्लिकेशन को सिस्टम द्वारा बूटिंग पूर्ण करते ही स्वतः आरंभ करने देता है. इससे टेबलेट को आरंभ होने में अधिक समय लग सकता है और एप्लिकेशन को निरंतर चलाकर संपूर्ण टेबलेट को धीमा करने देता है."</string>
-    <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"एप्लिकेशन को सिस्टम द्वारा बूटिंग पूर्ण करते ही स्वतः प्रारंभ होने देता है. इससे फ़ोन को प्रारंभ होने में अधिक समय लग सकता है और एप्लिकेशन के निरंतर चलते रहने से संपूर्ण फ़ोन प्रक्रियाएं धीमी हो सकती हैं."</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"एप्स को सिस्टम द्वारा बूटिंग पूर्ण करते ही स्वतः आरंभ करने देता है. इससे टेबलेट को आरंभ होने में अधिक समय लग सकता है और एप्स को निरंतर चलाकर संपूर्ण टेबलेट को धीमा करने देता है."</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="default" msgid="2825803764232445091">"एप्‍लिकेशन को स्‍टिकी प्रसारण भेजने देता है, जो प्रसारण समाप्त होने के बाद भी बने रहते हैं. अत्यधिक उपयोग, फ़ोन की बहुत अधिक स्मृति का उपयोग करके उसे धीमा या अस्‍थिर कर सकता है."</string>
+    <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"एप्‍स को स्‍टिकी प्रसारण भेजने देता है, जो प्रसारण समाप्त होने के बाद भी बने रहते हैं. अत्यधिक उपयोग, टेबलेट की बहुत अधिक स्मृति का उपयोग करके उसे धीमा या अस्‍थिर कर सकता है."</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="default" msgid="8440654152457300662">"एप्लिकेशन को आपके फ़ोन में संग्रहीत संपर्कों के डेटा को, साथ ही आपके द्वारा विशिष्ट व्यक्तियों को कॉल करने, ईमेल करने, या अन्‍य तरीके से संवाद करने की आवृत्ति को पढ़ने देता है. यह अनुमति एप्लिकेशन को आपके संपर्क डेटा को सहेजने देती है, और दुर्भावनापूर्ण एप्लिकेशन आपकी जानकारी के बिना संपर्क डेटा को साझा कर सकते हैं."</string>
+    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"एप्स को आपके टेबलेट में संग्रहीत संपर्कों के डेटा को, साथ ही आपके द्वारा विशिष्ट व्यक्तियों को कॉल करने, ईमेल करने, या अन्‍य तरीके से संवाद करने की आवृत्ति को पढ़ने देता है. यह अनुमति एप्स को आपके संपर्क डेटा को सहेजने देती है, और दुर्भावनापूर्ण एप्स आपकी जानकारी के बिना संपर्क डेटा को साझा कर सकते हैं."</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="default" msgid="589869224625163558">"एप्लिकेशन को आपके फ़ोन में संग्रहीत संपर्कों के डेटा को, साथ ही आपके द्वारा विशिष्ट व्यक्तियों को कॉल करने, ईमेल करने, या अन्‍य तरीके से संवाद करने की आवृत्ति को संशोधित करने देता है. यह अनुमति एप्लिकेशन को आपके संपर्क डेटा को हटाने देती है."</string>
+    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"एप्स को आपके टेबलेट में संग्रहीत संपर्कों के डेटा को, साथ ही आपके द्वारा विशिष्ट व्यक्तियों को कॉल करने, ईमेल करने, या अन्‍य तरीके से संवाद करने की आवृत्ति को संशोधित करने देता है. यह अनुमति एप्स को आपके संपर्क डेटा को हटाने देती है."</string>
+    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"एप्स को आपके फ़ोन में संग्रहीत संपर्कों के डेटा को, साथ ही आपके द्वारा विशिष्ट व्यक्तियों को कॉल करने, ईमेल करने, या अन्‍य तरीके से संवाद करने की आवृत्ति को संशोधित करने देता है. यह अनुमति एप्स को आपके संपर्क डेटा को हटाने देती है."</string>
     <string name="permlab_readCallLog" msgid="3478133184624102739">"कॉल लॉग पढ़ें"</string>
-    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"एप्लिकेशन को आपके फ़ोन का कॉल लॉग पढ़ने देता है, जिसमें इनकमिंग और आउटगोइंग कॉल का डेटा शामिल है. यह अनुमति एप्लिकेशन को आपके कॉल लॉग डेटा को सहेजने देती है, और दुर्भावनापूर्ण एप्लिकेशन आपकी जानकारी के बिना कॉल लॉग डेटा को साझा कर सकते हैं."</string>
-    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"एप्लिकेशन को आपके फ़ोन का कॉल लॉग पढ़ने देता है, जिसमें इनकमिंग और आउटगोइंग कॉल का डेटा शामिल है. यह अनुमति एप्लिकेशन को आपके कॉल लॉग डेटा को सहेजने देती है, और दुर्भावनापूर्ण एप्लिकेशन आपकी जानकारी के बिना कॉल लॉग डेटा को साझा कर सकते हैं."</string>
+    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"एप्स को आपके फ़ोन का कॉल लॉग पढ़ने देता है, जिसमें इनकमिंग और आउटगोइंग कॉल का डेटा शामिल है. यह अनुमति एप्स को आपके कॉल लॉग डेटा को सहेजने देती है, और दुर्भावनापूर्ण एप्स आपकी जानकारी के बिना कॉल लॉग डेटा को साझा कर सकते हैं."</string>
+    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"एप्स को आपके फ़ोन का कॉल लॉग पढ़ने देता है, जिसमें इनकमिंग और आउटगोइंग कॉल का डेटा शामिल है. यह अनुमति एप्स को आपके कॉल लॉग डेटा को सहेजने देती है, और दुर्भावनापूर्ण एप्स आपकी जानकारी के बिना कॉल लॉग डेटा को साझा कर सकते हैं."</string>
     <string name="permlab_writeCallLog" msgid="8552045664743499354">"कॉल लॉग लिखें"</string>
-    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"एप्‍लिकेशन को इनकमिंग और आउटगोइंग कॉल के डेटा सहित, आपके टेबलेट का कॉल लॉग संशोधित करने देता है. दुर्भावनापूर्ण एप्‍लिकेशन आपके कॉल लॉग को मिटाने या संशोधित करने के लिए इसका उपयोग कर सकते हैं."</string>
-    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"एप्‍लिकेशन को इनकमिंग और आउटगोइंग कॉल के डेटा सहित, आपके फ़ोन का कॉल लॉग संशोधित करने देता है. दुर्भावनापूर्ण एप्‍लिकेशन आपके कॉल लॉग को मिटाने या संशोधित करने के लिए इसका उपयोग कर सकते हैं."</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"एप्‍स को इनकमिंग और आउटगोइंग कॉल के डेटा सहित, आपके टेबलेट का कॉल लॉग संशोधित करने देता है. दुर्भावनापूर्ण एप्‍स आपके कॉल लॉग को मिटाने या संशोधित करने के लिए इसका उपयोग कर सकते हैं."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"एप्‍स को इनकमिंग और आउटगोइंग कॉल के डेटा सहित, आपके फ़ोन का कॉल लॉग संशोधित करने देता है. दुर्भावनापूर्ण एप्‍स आपके कॉल लॉग को मिटाने या संशोधित करने के लिए इसका उपयोग कर सकते हैं."</string>
     <string name="permlab_readProfile" msgid="4701889852612716678">"स्‍वयं का संपर्क कार्ड पढ़ें"</string>
-    <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"एप्लिकेशन को आपके उपकरण में संग्रहीत व्यक्तिगत प्रोफ़ाइल जानकारी, जैसे आपका नाम और संपर्क जानकारी, पढ़ने देता है. इसका अर्थ है कि एप्लिकेशन आपको पहचान सकता है और आपकी प्रोफ़ाइल जानकारी अन्य लोगों को भेज सकता है."</string>
+    <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"एप्स को आपके उपकरण में संग्रहीत व्यक्तिगत प्रोफ़ाइल जानकारी, जैसे आपका नाम और संपर्क जानकारी, पढ़ने देता है. इसका अर्थ है कि एप्स आपको पहचान सकता है और आपकी प्रोफ़ाइल जानकारी अन्य लोगों को भेज सकता है."</string>
     <string name="permlab_writeProfile" msgid="907793628777397643">"स्‍वयं का संपर्क कार्ड बदलें"</string>
-    <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"एप्लिकेशन को आपके उपकरण में संग्रहीत निजी प्रोफ़ाइल जानकारी, जैसे आपका नाम और संपर्क जानकारी को बदलने या उसमें कुछ जोड़ने देता है. इसका अर्थ है कि एप्लिकेशन आपको पहचान सकता है और आपकी प्रोफ़ाइल जानकारी अन्य लोगों को भेज सकता है."</string>
+    <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"एप्स को आपके उपकरण में संग्रहीत निजी प्रोफ़ाइल जानकारी, जैसे आपका नाम और संपर्क जानकारी को बदलने या उसमें कुछ जोड़ने देता है. इसका अर्थ है कि एप्स आपको पहचान सकता है और आपकी प्रोफ़ाइल जानकारी अन्य लोगों को भेज सकता है."</string>
     <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"अपनी सामाजिक स्‍ट्रीम पढ़ें"</string>
-    <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"एप्लिकेशन को आपके और आपके मित्रों के सामाजिक अपडेट तक पहुंचने और उन्हें समन्‍वयित करने देता है. जानकारी साझा करते समय सावधान रहें - इससे गोपनीयता पर ध्यान दिए बिना, एप्लिकेशन सामाजिक नेटवर्क पर आपके और आपके मित्रों के बीच संचारों को पढ़ सकता है. ध्‍यान दें: यह अनुमति सभी सामाजिक नेटवर्क पर लागू नहीं की जा सकती."</string>
+    <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"एप को आपके और आपके मित्रों की नई सामाजिक जानकारी तक पहुंचने और उन्हें समन्‍वयित करने देता है. जानकारी साझा करते समय सावधान रहें - इससे गोपनीयता पर ध्यान दिए बिना, एप सामाजिक नेटवर्क पर आपके और आपके मित्रों के बीच संचारों को पढ़ सकता है. ध्‍यान दें: यह अनुमति सभी सामाजिक नेटवर्क पर लागू नहीं की जा सकती."</string>
     <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"सामाजिक स्‍ट्रीम में लिखें"</string>
-    <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"एप्लिकेशन को आपके मित्रों के सामाजिक अपडेट प्रदर्शित करने देता है. जानकारी साझा करते समय सावधान रहें - इससे एप्लिकेशन ऐसे संदेश बना सकता है जो किसी मित्र की ओर से आते दिखाई देते हैं. ध्‍यान दें: यह अनुमति सभी सामाजिक नेटवर्क पर लागू नहीं की जा सकती."</string>
+    <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"एप को आपके मित्रों की नई सामाजिक जानकारी प्रदर्शित करने देता है. जानकारी साझा करते समय सावधान रहें - इससे एप्स ऐसे संदेश बना सकता है जो किसी मित्र की ओर से आते दिखाई देते हैं. ध्‍यान दें: यह अनुमति सभी सामाजिक नेटवर्क पर लागू नहीं की जा सकती."</string>
     <string name="permlab_readCalendar" msgid="5972727560257612398">"केलैंडर ईवेंट के साथ-साथ गोपनीय जानकारी पढ़ें"</string>
-    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"एप्लिकेशन को मित्रों या सहकर्मियों के कैलेंडर इवेंट सहित, आपके टेबलेट पर संग्रहीत कैलेंडर इवेंट पढ़ने देता है. इससे गोपनीयता या संवेदनशीलता पर ध्यान दिए बिना, एप्लिकेशन आपके कैलेंडर डेटा को साझा कर सकता है या सहेज सकता है."</string>
-    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"एप्लिकेशन को मित्रों या सहकर्मियों के कैलेंडर इवेंट सहित, आपके फ़ोन पर संग्रहीत कैलेंडर इवेंट पढ़ने देता है. इससे गोपनीयता या संवेदनशीलता पर ध्यान दिए बिना, एप्लिकेशन आपके कैलेंडर डेटा को साझा कर सकता है या सहेज सकता है."</string>
-    <string name="permlab_writeCalendar" msgid="8438874755193825647">"स्‍वामी की जानकारी के बि‍ना कैलेंडर ईवेंट जोड़ें या संशोधि‍त करें और अति‍थि‍यों को ईमेल भेजें"</string>
-    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"एप्लिकेशन को मित्रों या सहकर्मियों के ईवेंट के साथ ही वे ईवेंट जोड़ने, निकालने, बदलने देता है जिन्हें आप अपने टेबलेट पर संशोधित कर सकते हैं. इससे एप्लिकेशन, स्‍वामी की जानकारी के बिना उन संदेशों को भेज सकता है जो कैलेंडर स्वामियों की ओर से आते दिखाई देते हैं, या ईवेंट संशोधित कर सकता है."</string>
-    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"एप्लिकेशन को मित्रों या सहकर्मियों के ईवेंट के साथ ही वे ईवेंट जोड़ने, निकालने, बदलने देता है जिन्हें आप अपने फ़ोन पर संशोधित कर सकते हैं. इससे एप्लिकेशन, स्‍वामी की जानकारी के बिना उन संदेशों को भेज सकता है जो कैलेंडर स्वामियों की ओर से आते दिखाई देते हैं, या ईवेंट संशोधित कर सकता है."</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"एप्स को मित्रों या सहकर्मियों के कैलेंडर इवेंट सहित, आपके टेबलेट पर संग्रहीत कैलेंडर इवेंट पढ़ने देता है. इससे गोपनीयता या संवेदनशीलता पर ध्यान दिए बिना, एप्स आपके कैलेंडर डेटा को साझा कर सकता है या सहेज सकता है."</string>
+    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"एप्स को मित्रों या सहकर्मियों के कैलेंडर इवेंट सहित, आपके फ़ोन पर संग्रहीत कैलेंडर इवेंट पढ़ने देता है. इससे गोपनीयता या संवेदनशीलता पर ध्यान दिए बिना, एप्स आपके कैलेंडर डेटा को साझा कर सकता है या सहेज सकता है."</string>
+    <string name="permlab_writeCalendar" msgid="8438874755193825647">"अपनी जानकारी के बि‍ना कैलेंडर ईवेंट जोड़ें या संशोधि‍त करें और अति‍थि‍यों को ईमेल भेजें"</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"एप्स को मित्रों या सहकर्मियों के ईवेंट के साथ ही वे ईवेंट जोड़ने, निकालने, बदलने देता है जिन्हें आप अपने टेबलेट पर संशोधित कर सकते हैं. इससे एप्स,अपनी जानकारी के बिना उन संदेशों को भेज सकता है जो कैलेंडर स्वामियों की ओर से आते दिखाई देते हैं, या ईवेंट संशोधित कर सकता है."</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"एप्स को मित्रों या सहकर्मियों के ईवेंट के साथ ही वे ईवेंट जोड़ने, निकालने, बदलने देता है जिन्हें आप अपने फ़ोन पर संशोधित कर सकते हैं. इससे एप्स, अपनी जानकारी के बिना उन संदेशों को भेज सकता है जो कैलेंडर स्वामियों की ओर से आते दिखाई देते हैं, या ईवेंट संशोधित कर सकता है."</string>
     <string name="permlab_accessMockLocation" msgid="8688334974036823330">"परीक्षण के लिए नकली स्‍थान स्रोत"</string>
-    <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"परीक्षण के लिए कृत्रिम स्थान स्रोत बनाएं या एक नया स्थान प्रदाता इंस्‍टॉल करें. यह एप्लिकेशन को स्‍थान और/या अन्‍य स्थान स्रोतों जैसे GPS या स्‍थान प्रदाताओं द्वारा लौटाई गई स्थिति को ओवरराइड करने देता है."</string>
+    <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"परीक्षण के लिए कृत्रिम स्थान स्रोत बनाएं या एक नया स्थान प्रदाता इंस्‍टॉल करें. यह एप्स को स्‍थान और/या अन्‍य स्थान स्रोतों जैसे GPS या स्‍थान प्रदाताओं द्वारा लौटाई गई स्थिति को ओवरराइड करने देता है."</string>
     <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"अतिरिक्त स्‍थान प्रदाता आदेशों में पहुंचे"</string>
-    <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"एप्लिकेशन को अतिरिक्त स्थान प्रदाता आदेशों पर पहुंचने देता है. यह एप्लिकेशन को GPS या अन्य स्थान स्रोतों के संचालन में बाधा पहुंचाने दे सकता है."</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"एप्स को अतिरिक्त स्थान प्रदाता आदेशों पर पहुंचने देता है. यह एप्स को GPS या अन्य स्थान स्रोतों के संचालन में बाधा पहुंचाने दे सकता है."</string>
     <string name="permlab_installLocationProvider" msgid="6578101199825193873">"किसी स्‍थान प्रदाता को इंस्‍टॉल करने की अनुमति"</string>
-    <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"परीक्षण के लिए कृत्रिम स्थान स्रोत बनाएं या एक नए स्थान प्रदाता को इंस्‍टॉल करें. यह एप्लिकेशन को स्‍थान और/या अन्‍य स्थान स्रोतों जैसे GPS या स्‍थान प्रदाताओं द्वारा लौटाई गई स्थिति को ओवरराइड करने देता है."</string>
+    <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"परीक्षण के लिए कृत्रिम स्थान स्रोत बनाएं या एक नए स्थान प्रदाता को इंस्‍टॉल करें. यह एप्स को स्‍थान और/या अन्‍य स्थान स्रोतों जैसे GPS या स्‍थान प्रदाताओं द्वारा लौटाई गई स्थिति को ओवरराइड करने देता है."</string>
     <string name="permlab_accessFineLocation" msgid="1191898061965273372">"सटीक स्थान (GPS और नेटवर्क-आधारित)"</string>
-    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"एप्लिकेशन को ग्लोबल पोज़िशनिंग सिस्टम (GPS) या सेल टॉवर और Wi-Fi जैसे नेटवर्क स्थान स्रोतों का उपयोग करके आपका सटीक स्थान प्राप्त करने देती है. एप्लिकेशन द्वारा इन स्थान सेवाओं का उपयोग किए जाने के लिए इन्हें चालू होना चाहिए और आपके उपकरण पर उपलब्ध होना चाहिए. एप्लिकेशन इसका उपयोग यह पता करने में कर सकते हैं कि आप कहां पर हैं, और अतिरिक्त बैटरी की खपत कर सकते हैं."</string>
+    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"एप्स को ग्लोबल पोज़िशनिंग सिस्टम (GPS) या सेल टॉवर और Wi-Fi जैसे नेटवर्क स्थान स्रोतों का उपयोग करके आपका सटीक स्थान प्राप्त करने देती है. एप्स द्वारा इन स्थान सेवाओं का उपयोग किए जाने के लिए इन्हें चालू होना चाहिए और आपके उपकरण पर उपलब्ध होना चाहिए. एप्स इसका उपयोग यह पता करने में कर सकते हैं कि आप कहां पर हैं, और अतिरिक्त बैटरी की खपत कर सकते हैं."</string>
     <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"अनुमानित स्थान (नेटवर्क-आधारित)"</string>
-    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"एप्लिकेशन को आपका अनुमानित स्थान प्राप्त करने देती है. इस स्थान को सेल टॉवर और Wi-Fi जैसे नेटवर्क स्थान स्रोतों का उपयोग करके स्थान सेवाओं द्वारा प्राप्त किया गया है. एप्लिकेशन द्वारा इन स्थान सेवाओं का उपयोग करने के लिए इन्हें चालू होना चाहिए और आपके उपकरण में उपलब्ध होना चाहिए. एप्लिकेशन इसका उपयोग यह पता लगाने में कर सकते हैं कि आप लगभग कहां पर हैं."</string>
+    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"एप्स को आपका अनुमानित स्थान प्राप्त करने देती है. इस स्थान को सेल टॉवर और Wi-Fi जैसे नेटवर्क स्थान स्रोतों का उपयोग करके स्थान सेवाओं द्वारा प्राप्त किया गया है. एप्स द्वारा इन स्थान सेवाओं का उपयोग करने के लिए इन्हें चालू होना चाहिए और आपके उपकरण में उपलब्ध होना चाहिए. एप्स इसका उपयोग यह पता लगाने में कर सकते हैं कि आप लगभग कहां पर हैं."</string>
     <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"SurfaceFlinger में पहुंचें"</string>
-    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"एप्‍लिकेशन को SurfaceFlinger निम्‍न-स्‍तर सुविधाएं उपयोग करने देता है."</string>
+    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"एप्‍स को SurfaceFlinger निम्‍न-स्‍तर सुविधाएं उपयोग करने देता है."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"फ़्रेम बफ़र पढ़ें"</string>
-    <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"एप्‍लिकेशन को फ़्रेम बफ़र की सामग्री पढ़ने देता है."</string>
+    <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"एप्‍स को फ़्रेम बफ़र की सामग्री पढ़ने देता है."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Wifi डिस्प्ले को कॉन्फ़िगर करें"</string>
-    <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"एप्लिकेशन को कॉन्फ़िगर करने देता है और Wifi डिस्प्ले से कनेक्ट करता है."</string>
+    <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"एप्स को कॉन्फ़िगर करने देता है और Wifi डिस्प्ले से कनेक्ट करता है."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wifi डिस्प्ले को नियंत्रित करें"</string>
-    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"एप्लिकेशन को Wifi डिस्प्ले की निम्न-स्तर की सुविधाएं नियंत्रित करने देता है."</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"एप्स को Wifi डिस्प्ले की निम्न-स्तर की सुविधाएं नियंत्रित करने देता है."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"ऑडियो आउटपुट को कैप्‍चर करें"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"एप्‍स को ऑडियो आउटपुट को कैप्‍चर और रीडायरेक्‍ट करने देता है."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"वीडियो आउटपुट को कैप्‍चर करें"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"एप्‍स को वीडियो आउटपुट को कैप्‍चर और रीडायरेक्‍ट करने देता है."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"सुरक्षित वीडियो आउटपुट को कैप्‍चर करें"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"एप्‍स को सुरक्षित वीडियो आउटपुट को कैप्‍चर और रीडायरेक्‍ट करने देता है."</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="4906839301087980680">"एप्लिकेशन को माइक्रोफ़ोन द्वारा ऑडियो रिकार्ड करने देता है. यह अनुमति एप्लिकेशन को आपकी पुष्टि के बिना किसी भी समय ऑडियो रिकार्ड करने देती है."</string>
+    <string name="permdesc_recordAudio" msgid="4906839301087980680">"एप्स को माइक्रोफ़ोन द्वारा ऑडियो रिकार्ड करने देता है. यह अनुमति एप्स को आपकी पुष्टि के बिना किसी भी समय ऑडियो रिकार्ड करने देती है."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"चित्र और वीडियो लें"</string>
-    <string name="permdesc_camera" msgid="8497216524735535009">"एप्लिकेशन को कैमरे से चित्र और वीडियो लेने देता है. यह अनुमति एप्लिकेशन को किसी भी समय आपकी पुष्टि के बिना कैमरे का उपयोग करने देती है."</string>
+    <string name="permdesc_camera" msgid="8497216524735535009">"एप्स को कैमरे से चित्र और वीडियो लेने देता है. यह अनुमति एप्स को किसी भी समय आपकी पुष्टि के बिना कैमरे का उपयोग करने देती है."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"कैमरा उपयोग में होने पर संचारण संकेतक LED अक्षम करें"</string>
-    <string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"पहले से इंस्टॉल किए गए सिस्टम एप्लिकेशन को कैमरे को संकेतक LED का उपयोग करने से अक्षम करती है."</string>
+    <string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"पहले से इंस्टॉल किए गए सिस्टम एप्स को कैमरे को संकेतक LED का उपयोग करने से अक्षम करती है."</string>
     <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"स्‍थायी रूप से टेबलेट अक्षम करें"</string>
     <string name="permlab_brick" product="default" msgid="8337817093326370537">"फ़ोन को स्‍थायी रूप से अक्षम करें"</string>
-    <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"एप्‍लिकेशन को संपूर्ण टेबलेट को स्‍थायी रूप से अक्षम करने देता है. यह बहुत खतरनाक है."</string>
-    <string name="permdesc_brick" product="default" msgid="5788903297627283099">"एप्‍लिकेशन को संपूर्ण फ़ोन को स्‍थायी रूप से अक्षम करने देता है. यह बहुत खतरनाक है."</string>
+    <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"एप्‍स को संपूर्ण टेबलेट को स्‍थायी रूप से अक्षम करने देता है. यह बहुत खतरनाक है."</string>
+    <string name="permdesc_brick" product="default" msgid="5788903297627283099">"एप्‍स को संपूर्ण फ़ोन को स्‍थायी रूप से अक्षम करने देता है. यह बहुत खतरनाक है."</string>
     <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"टेबलेट रीबूट के लिए बाध्‍य करें"</string>
     <string name="permlab_reboot" product="default" msgid="2898560872462638242">"फ़ोन रीबूट के लिए बाध्‍य करें"</string>
-    <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"एप्‍लिकेशन को टेबलेट रीबूट करने के लिए बाध्‍य करने देता है."</string>
-    <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"एप्‍लिकेशन को फ़ोन बलपूर्वक रीबूट करने देता है."</string>
+    <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"एप्‍स को टेबलेट रीबूट करने के लिए बाध्‍य करने देता है."</string>
+    <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"एप्‍स को फ़ोन बलपूर्वक रीबूट करने देता है."</string>
     <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"USB संग्रहण फ़ाइल सिस्‍टम पर पहुंचें"</string>
     <string name="permlab_mount_unmount_filesystems" product="default" msgid="4402305049890953810">"SD कार्ड फ़ाइल सिस्‍टम पर पहुंचें"</string>
-    <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"एप्‍लिकेशन को निकाले जाने योग्‍य संग्रहण के लिए फ़ाइल सिस्‍टम माउंट और अनमाउंट करने देता है."</string>
+    <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"एप्‍स को निकाले जाने योग्‍य संग्रहण के लिए फ़ाइल सिस्‍टम माउंट और अनमाउंट करने देता है."</string>
     <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"USB संग्रहण मिटाएं"</string>
     <string name="permlab_mount_format_filesystems" product="default" msgid="262582698639274056">"SD कार्ड मिटाएं"</string>
-    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"एप्‍लिकेशन को निकालने योग्‍य संग्रहण फ़ॉर्मेट करने देता है."</string>
-    <string name="permlab_asec_access" msgid="3411338632002193846">"आंतरिक संग्रहण पर जानकारी प्राप्त करें"</string>
-    <string name="permdesc_asec_access" msgid="3094563844593878548">"एप्लिकेशन को आंतरिक संग्रहण की जानकारी प्राप्‍त करने देता है."</string>
-    <string name="permlab_asec_create" msgid="6414757234789336327">"आंतरिक संग्रहण बनाएं"</string>
-    <string name="permdesc_asec_create" msgid="4558869273585856876">"एप्‍लिकेशन को आंतरिक संग्रहण बनाने देता है."</string>
-    <string name="permlab_asec_destroy" msgid="526928328301618022">"आंतरिक संग्रहण नष्ट करें"</string>
-    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"एप्‍लिकेशन को आंतरिक संग्रहण नष्ट करने देता है."</string>
-    <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"आंतरिक संग्रहण माउंट/अनमाउंट करें"</string>
-    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"एप्‍लिकेशन को आंतरिक संग्रहण माउंट/अनमाउंट करने देता है."</string>
-    <string name="permlab_asec_rename" msgid="7496633954080472417">"आंतरिक संग्रहण का नाम बदलें"</string>
-    <string name="permdesc_asec_rename" msgid="1794757588472127675">"एप्‍लिकेशन को आंतरिक संग्रहण का नाम बदलने देता है."</string>
+    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"एप्‍स को निकालने योग्‍य संग्रहण फ़ॉर्मेट करने देता है."</string>
+    <string name="permlab_asec_access" msgid="3411338632002193846">"मोबाइल संग्रहण पर जानकारी प्राप्त करें"</string>
+    <string name="permdesc_asec_access" msgid="3094563844593878548">"एप्स को मोबाइल संग्रहण की जानकारी प्राप्‍त करने देता है."</string>
+    <string name="permlab_asec_create" msgid="6414757234789336327">"मोबाइल संग्रहण बनाएं"</string>
+    <string name="permdesc_asec_create" msgid="4558869273585856876">"एप्‍स को मोबाइल संग्रहण बनाने देता है."</string>
+    <string name="permlab_asec_destroy" msgid="526928328301618022">"मोबाइल संग्रहण नष्ट करें"</string>
+    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"एप्‍स को मोबाइल संग्रहण नष्ट करने देता है."</string>
+    <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"मोबाइल संग्रहण माउंट/अनमाउंट करें"</string>
+    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"एप्‍स को मोबाइल संग्रहण माउंट/अनमाउंट करने देता है."</string>
+    <string name="permlab_asec_rename" msgid="7496633954080472417">"मोबाइल संग्रहण का नाम बदलें"</string>
+    <string name="permdesc_asec_rename" msgid="1794757588472127675">"एप्‍स को मोबाइल संग्रहण का नाम बदलने देता है."</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_flashlight" msgid="2155920810121984215">"फ़्लैशलाइट नियंत्रित करें"</string>
-    <string name="permdesc_flashlight" msgid="6522284794568368310">"एप्‍लिकेशन को फ़्लैशलाइट नियंत्रित करने देता है."</string>
+    <string name="permdesc_flashlight" msgid="6522284794568368310">"एप्‍स को फ़्लैशलाइट नियंत्रित करने देता है."</string>
     <string name="permlab_manageUsb" msgid="1113453430645402723">"USB उपकरणों की प्राथमिकताएं और अनुमतियां प्रबंधित करें"</string>
-    <string name="permdesc_manageUsb" msgid="7776155430218239833">"एप्‍लिकेशन को USB उपकरणों की प्राथमिकताओं और अनुमतियों को प्रबंधित करने देता है."</string>
+    <string name="permdesc_manageUsb" msgid="7776155430218239833">"एप्‍स को USB उपकरणों की प्राथमिकताओं और अनुमतियों को प्रबंधित करने देता है."</string>
     <string name="permlab_accessMtp" msgid="4953468676795917042">"MTP प्रोटोकॉल लागू करें"</string>
     <string name="permdesc_accessMtp" msgid="6532961200486791570">"MTP USB प्रोटोकॉल लागू करने के लिए कर्नेल MTP ड्राइवर में पहुंच की अनुमति देता है."</string>
     <string name="permlab_hardware_test" msgid="4148290860400659146">"परीक्षण हार्डवेयर"</string>
-    <string name="permdesc_hardware_test" msgid="6597964191208016605">"एप्‍लिकेशन को हार्डवेयर परीक्षण के लिए विविध सहायक उपकरणों को नियंत्रित करने देता है."</string>
+    <string name="permdesc_hardware_test" msgid="6597964191208016605">"एप्‍स को हार्डवेयर परीक्षण के लिए विविध सहायक उपकरणों को नियंत्रित करने देता है."</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_callPrivileged" msgid="4198349211108497879">"किसी भी फ़ोन नंबर पर सीधे कॉल करें"</string>
-    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"एप्‍लिकेशन को आपके हस्‍तक्षेप के बिना आपातकालीन नंबरों सहित, किसी भी फ़ोन नंबर पर कॉल करने देता है. दुर्भावनापूर्ण एप्‍लिकेशन आपातकालीन सेवाओं पर अनावश्‍यक और अवैध कॉल कर सकते हैं."</string>
+    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"एप्‍स को आपके हस्‍तक्षेप के बिना आपातकालीन नंबरों सहित, किसी भी फ़ोन नंबर पर कॉल करने देता है. दुर्भावनापूर्ण एप्‍स आपातकालीन सेवाओं पर अनावश्‍यक और अवैध कॉल कर सकते हैं."</string>
     <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"सीधे CDMA टेबलेट सेटअप प्रारंभ करें"</string>
     <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"सीधे CDMA फ़ोन सेटअप प्रारंभ करें"</string>
-    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"एप्‍लिकेशन को CDMA प्रावधान प्रारंभ करने देता है. दुर्भावनापूर्ण एप्‍लिकेशन अनावश्‍यक रूप से CDMA प्रावधान प्रारंभ कर सकते हैं."</string>
-    <string name="permlab_locationUpdates" msgid="7785408253364335740">"स्‍थान अपडेट सूचनाएं नियंत्रित करें"</string>
-    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"एप्‍लिकेशन को रेडियो से स्‍थान अपडेट सूचनाएं सक्षम/अक्षम करने देता है. सामान्‍य एप्‍लिकेशन द्वारा उपयोग करने के लिए नहीं."</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"एप्‍स को CDMA प्रावधान प्रारंभ करने देता है. दुर्भावनापूर्ण एप्‍स अनावश्‍यक रूप से CDMA प्रावधान प्रारंभ कर सकते हैं."</string>
+    <string name="permlab_locationUpdates" msgid="7785408253364335740">"स्‍थान के बारे में नई जानकारी की सूचनाओं को नियंत्रित करें"</string>
+    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"एप को रेडियो से स्‍थान के बारे में नई जानकारी की सूचनाएं सक्षम/अक्षम करने देता है. सामान्‍य एप्‍स द्वारा उपयोग करने के लिए नहीं."</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"चेकइन गुणों में पहुंचें"</string>
-    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"एप्लिकेशन को चेकइन सेवा द्वारा अपलोड किए गए गुणों पर पढ़ें/लिखें पहुंच देता है. सामान्‍य एप्‍लिकेशन द्वारा उपयोग करने के लिए नहीं."</string>
+    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"एप्स को चेकइन सेवा द्वारा अपलोड किए गए गुणों पर पढ़ें/लिखें पहुंच देता है. सामान्‍य एप्‍स द्वारा उपयोग करने के लिए नहीं."</string>
     <string name="permlab_bindGadget" msgid="776905339015863471">"विजेट चुनें"</string>
-    <string name="permdesc_bindGadget" msgid="8261326938599049290">"एप्लिकेशन को सिस्टम को यह बताने देता है कि किस एप्लिकेशन द्वारा कौन से विजेट का उपयोग किया जा सकता है. कोई एप्लिकेशन, इस अनुमति के साथ अन्य एप्लिकेशन के निजी डेटा पर पहुंच सकते हैं. सामान्‍य एप्‍लिकेशन द्वारा उपयोग करने के लिए नहीं."</string>
+    <string name="permdesc_bindGadget" msgid="8261326938599049290">"एप्स को सिस्टम को यह बताने देता है कि किस एप्स द्वारा कौन से विजेट का उपयोग किया जा सकता है. कोई एप्स, इस अनुमति के साथ अन्य एप्स के निजी डेटा पर पहुंच सकते हैं. सामान्‍य एप्‍स द्वारा उपयोग करने के लिए नहीं."</string>
     <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"फ़ोन स्‍थिति बदलें"</string>
-    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"एप्‍लिकेशन को उपकरण की फ़ोन सुविधाएं नियंत्रित करने देता है. इस अनुमति वाला कोई एप्‍लिकेशन आपको सूचित किए बिना नेटवर्क स्‍विच कर सकता है, फ़ोन का रेडियो चालू और बंद कर सकता है और ऐसे ही अन्य कार्य कर सकता है."</string>
+    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"एप्‍स को उपकरण की फ़ोन सुविधाएं नियंत्रित करने देता है. इस अनुमति वाला कोई एप्‍स आपको सूचित किए बिना नेटवर्क स्‍विच कर सकता है, फ़ोन का रेडियो चालू और बंद कर सकता है और ऐसे ही अन्य कार्य कर सकता है."</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_wakeLock" product="tablet" msgid="1531731435011495015">"टेबलेट को निष्‍क्रिय होने से रोकें"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"फ़ोन को निष्‍क्रिय होने से रोकें"</string>
-    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"एप्लिकेशन को टेबलेट को निष्क्रिय हो जाने से रोकता है."</string>
-    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"एप्लिकेशन को फ़ोन को निष्क्रिय होने से रोकता है."</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"एप्स को टेबलेट को प्रयोग में नहीं हो जाने से रोकता है."</string>
+    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"एप्स को फ़ोन को प्रयोग में नहीं होने से रोकता है."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"टेबलेट चालू या बंद करें"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"फ़ोन चालू या बंद करें"</string>
-    <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"एप्‍लिकेशन को टेबलेट चालू या बंद करने देता है."</string>
-    <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"एप्‍लिकेशन को फ़ोन चालू या बंद करने देता है."</string>
+    <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"एप्‍स को टेबलेट चालू या बंद करने देता है."</string>
+    <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"एप्‍स को फ़ोन चालू या बंद करने देता है."</string>
     <string name="permlab_factoryTest" msgid="3715225492696416187">"फ़ैक्‍ट्री परीक्षण मोड में चलाएं"</string>
     <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"टेबलेट हार्डवेयर में पूर्ण पहुंच की अनुमति देते हुए निम्‍न-स्‍तर निर्माता परीक्षण के रूप में चलाएं. केवल तभी उपलब्‍ध जब कोई टेबलेट निर्माता परीक्षण मोड में चल रहा हो."</string>
     <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"फ़ोन हार्डवेयर में पूर्ण पहुंच की अनुमति देते हुए निम्‍न-स्‍तर निर्माता परीक्षण के रूप में चलाएं. केवल तभी उपलब्‍ध जब कोई फ़ोन निर्माता परीक्षण मोड में चल रहा हो."</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_masterClear" msgid="2315750423139697397">"फ़ैक्‍ट्री डिफ़ॉल्‍ट पर सिस्‍टम रीसेट करें"</string>
-    <string name="permdesc_masterClear" msgid="3665380492633910226">"एप्लिकेशन को सभी डेटा, कॉन्फ़िगरेशन, और इंस्टॉल एप्लिकेशन मिटाकर, सिस्टम को पूरी तरह उसकी फ़ैक्टरी सेटिंग पर रीसेट करने देता है."</string>
+    <string name="permdesc_masterClear" msgid="3665380492633910226">"एप्स को सभी डेटा, कॉन्फ़िगरेशन, और इंस्टॉल एप्स मिटाकर, सिस्टम को पूरी तरह उसकी फ़ैक्टरी सेटिंग पर रीसेट करने देता है."</string>
     <string name="permlab_setTime" msgid="2021614829591775646">"समय सेट करें"</string>
-    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"एप्‍लिकेशन को टेबलेट की घड़ी का समय बदलने देता है."</string>
-    <string name="permdesc_setTime" product="default" msgid="1855702730738020">"एप्‍लिकेशन को फ़ोन की घड़ी का समय बदलने देता है."</string>
+    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"एप्‍स को टेबलेट की घड़ी का समय बदलने देता है."</string>
+    <string name="permdesc_setTime" product="default" msgid="1855702730738020">"एप्‍स को फ़ोन की घड़ी का समय बदलने देता है."</string>
     <string name="permlab_setTimeZone" msgid="2945079801013077340">"समय क्षेत्र सेट करें"</string>
-    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"एप्‍लिकेशन को टेबलेट का समय क्षेत्र बदलने देता है."</string>
-    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"एप्‍लिकेशन को टेबलेट का समय क्षेत्र बदलने देता है."</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"एप्‍स को टेबलेट का समय क्षेत्र बदलने देता है."</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"एप्‍स को टेबलेट का समय क्षेत्र बदलने देता है."</string>
     <string name="permlab_accountManagerService" msgid="4829262349691386986">"खाता प्रबंधक सेवा के रूप में कार्य करें"</string>
-    <string name="permdesc_accountManagerService" msgid="1948455552333615954">"एप्‍लिकेशन को खाता प्रमाणकों को कॉल करने देता है."</string>
+    <string name="permdesc_accountManagerService" msgid="1948455552333615954">"एप्‍स को खाता प्रमाणकों को कॉल करने देता है."</string>
     <string name="permlab_getAccounts" msgid="1086795467760122114">"उपकरण पर खाते ढूंढें"</string>
-    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"एप्लिकेशन को टेबलेट द्वारा ज्ञात खातों की सूची प्राप्‍त करने देता है. इसमें वे खाते शामिल हो सकते हैं जिन्‍हें आपके द्वारा इंस्‍टॉल किए गए एप्लिकेशन ने बनाया है."</string>
-    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"एप्लिकेशन को फ़ोन द्वारा ज्ञात खातों की सूची प्राप्‍त करने देता है. इसमें वे खाते शामिल हो सकते हैं जिन्‍हें आपके द्वारा इंस्‍टॉल किए गए एप्लिकेशन ने बनाया है."</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"एप्स को टेबलेट द्वारा ज्ञात खातों की सूची प्राप्‍त करने देता है. इसमें वे खाते शामिल हो सकते हैं जिन्‍हें आपके द्वारा इंस्‍टॉल किए गए एप्स ने बनाया है."</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"एप्स को फ़ोन द्वारा ज्ञात खातों की सूची प्राप्‍त करने देता है. इसमें वे खाते शामिल हो सकते हैं जिन्‍हें आपके द्वारा इंस्‍टॉल किए गए एप्स ने बनाया है."</string>
     <string name="permlab_authenticateAccounts" msgid="5265908481172736933">"खाते बनाएं और पासवर्ड सेट करें"</string>
     <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"एप्‍िलकेशन को खाता बनाने और उनके पासवर्ड प्राप्त करने और सेट करने सहित, खाता प्रबंधक की खाता प्रमाणक क्षमताओं का उपयोग करने देता है."</string>
     <string name="permlab_manageAccounts" msgid="4983126304757177305">"खाते जोडें या निकालें"</string>
-    <string name="permdesc_manageAccounts" msgid="8698295625488292506">"एप्‍लिकेशन को खाते जोड़ना और निकालना और उनके पासवर्ड हटाने जैसे कार्य करने देता है."</string>
+    <string name="permdesc_manageAccounts" msgid="8698295625488292506">"एप्‍स को खाते जोड़ना और निकालना और उनके पासवर्ड हटाने जैसे कार्य करने देता है."</string>
     <string name="permlab_useCredentials" msgid="235481396163877642">"उपकरण पर खातों का उपयोग करें"</string>
-    <string name="permdesc_useCredentials" msgid="7984227147403346422">"एप्लिकेशन को प्रमाणीकरण टोकन का अनुरोध करने देता है."</string>
+    <string name="permdesc_useCredentials" msgid="7984227147403346422">"एप्स को प्रमाणीकरण टोकन का अनुरोध करने देता है."</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="8018758136404323658">"पूर्ण नेटवर्क पहुंच"</string>
-    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"एप्लिकेशन को नेटवर्क सॉकेट बनाने और कस्‍टम नेटवर्क प्रोटोकॉल का उपयोग करने देता है. ब्राउज़र और अन्‍य एप्लिकेशन इंटरनेट को डेटा भेजने के साधन उपलब्‍ध कराते हैं, ताकि इंटरनेट को डेटा भेजने के लिए इस अनुमति की आवश्‍यकता नहीं हो."</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"एप्स को नेटवर्क सॉकेट बनाने और कस्‍टम नेटवर्क प्रोटोकॉल का उपयोग करने देता है. ब्राउज़र और अन्‍य एप्स इंटरनेट को डेटा भेजने के साधन उपलब्‍ध कराते हैं, ताकि इंटरनेट को डेटा भेजने के लिए इस अनुमति की आवश्‍यकता नहीं हो."</string>
     <string name="permlab_writeApnSettings" msgid="505660159675751896">"नेटवर्क सेटिंग और ट्रैफ़िक बदलें/रोकें"</string>
-    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"एप्लिकेशन को नेटवर्क सेटिंग बदलने और सभी ट्रैफ़िक नेटवर्क को बाधित और निरीक्षण करने देता है, उदाहरण के लिए किसी APN का प्रॉक्सी और पोर्ट बदलना. दुर्भावनापूर्ण एप्लिकेशन आपकी जानकारी के बिना नेटवर्क पैकेट की निगरानी कर सकते हैं, उन्हें रीडायरेक्ट, या संशोधित कर सकते हैं."</string>
+    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"एप्स को नेटवर्क सेटिंग बदलने और सभी ट्रैफ़िक नेटवर्क को बाधित और निरीक्षण करने देता है, उदाहरण के लिए किसी APN का प्रॉक्सी और पोर्ट बदलना. दुर्भावनापूर्ण एप्स आपकी जानकारी के बिना नेटवर्क पैकेट की निगरानी कर सकते हैं, उन्हें रीडायरेक्ट, या संशोधित कर सकते हैं."</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_changeBackgroundDataSetting" msgid="1400666012671648741">"पृष्ठभूमि डेटा उपयोग सेटिंग बदलें"</string>
-    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"एप्‍लिकेशन को पृष्ठभूमि डेटा उपयोग सेटिंग बदलने देता है."</string>
+    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"एप्‍स को पृष्ठभूमि डेटा उपयोग सेटिंग बदलने देता है."</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="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 मल्‍टीकास्‍ट प्राप्ति को अनुमति दें"</string>
-    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"एप्लिकेशन को Wi-Fi नेटवर्क पर मल्टीकास्ट पते के उपयोग से केवल आपके टेबलेट पर ही नहीं, बल्कि सभी उपकरणों पर भेजे गए पैकेट प्राप्‍त करने देता है. यह गैर-मल्टीकास्ट मोड से अधिक पावर का उपयोग करता है."</string>
-    <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"एप्लिकेशन को Wi-Fi नेटवर्क पर मल्टीकास्ट पते के उपयोग से केवल आपके फ़ोन पर ही नहीं, बल्कि सभी उपकरणों पर भेजे गए पैकेट प्राप्‍त करने देता है. यह गैर-मल्टीकास्ट मोड से अधिक पावर का उपयोग करता है."</string>
+    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"एप्स को 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="default" msgid="8931682159331542137">"एप्‍लिकेशन को स्‍थानीय Bluetooth फ़ोन कॉन्‍फ़िगर करने देता है, और रिमोट उपकरणों के साथ खोजने और युग्‍मित करने देता है."</string>
+    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"किसी एप्‍स को स्‍थानीय Bluetooth टेबलेट कॉन्‍फ़िगर करने की और रिमोट उपकरणों के साथ खोजने और युग्‍मित करने देता है."</string>
+    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"एप्‍स को स्‍थानीय Bluetooth फ़ोन कॉन्‍फ़िगर करने देता है, और रिमोट उपकरणों के साथ खोजने और युग्‍मित करने देता है."</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="2405042267131496579">"WiMAX स्‍थिति बदलें"</string>
-    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"एप्‍लिकेशन को WiMAX नेटवर्क से टेबलेट को कनेक्‍ट और डिस्‍कनेक्‍ट करने देता है."</string>
-    <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"एप्‍लिकेशन को WiMAX नेटवर्क से फ़ोन को कनेक्‍ट और डिस्‍कनेक्‍ट करने देता है."</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"एप्‍स को 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="default" msgid="3207106324452312739">"एप्‍लिकेशन को फ़ोन पर Bluetooth का कॉन्‍फ़िगरेशन देखने, और युग्‍मित उपकरणों के साथ कनेक्‍शन बनाने और स्‍वीकार करने देता है."</string>
+    <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"एप्‍स को टेबलेट पर 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">"एप्लिकेशन को नियर फ़ील्ड कम्यूनिकेशन (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_readSyncSettings" msgid="6201810008230503052">"समन्वयन सेटिंग पढ़ें"</string>
-    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"एप्लिकेशन को किसी खाते की समन्वयन सेटिंग पढ़ने देता है. उदाहरण के लिए, इससे यह निर्धारित किया जा सकता है कि लोग एप्लिकेशन किसी खाते के साथ समन्‍वयित है या नहीं."</string>
+    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"एप्स को किसी खाते की समन्वयन सेटिंग पढ़ने देता है. उदाहरण के लिए, इससे यह निर्धारित किया जा सकता है कि लोग एप्स किसी खाते के साथ समन्‍वयित है या नहीं."</string>
     <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"समन्‍वयन बंद या चालू टॉगल करें"</string>
-    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"एप्लिकेशन को किसी खाते की समन्वयन सेटिंग संशोधित करने देता है. उदाहरण के लिए, इसका उपयोग लोग एप्लिकेशन का समन्‍वयन किसी खाते से सक्षम करने में हो सकता है."</string>
+    <string name="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_subscribedFeedsRead" msgid="4756609637053353318">"ग्राहकी-प्राप्त फ़ीड पढ़ें"</string>
-    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"एप्‍लिकेशन को वर्तमान में समन्वयित फ़ीड के बारे में विवरण प्राप्त करने देता है."</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"एप्‍स को वर्तमान में समन्वयित फ़ीड के बारे में विवरण प्राप्त करने देता है."</string>
     <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"ग्राहकी-प्राप्त फ़ीड लिखें"</string>
-    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"एप्लिकेशन को आपके वर्तमान समन्वयित फ़ीड को संशोधित करने देता है. दुर्भावनापूर्ण एप्लिकेशन आपके समन्वयित फ़ीड को बदल सकते है."</string>
-    <string name="permlab_readDictionary" msgid="4107101525746035718">"डिक्शनरी में आपके द्वारा जोड़े गए शब्‍दों को पढ़ें"</string>
-    <string name="permdesc_readDictionary" msgid="659614600338904243">"एप्‍लिकेशन को ऐसे सभी शब्‍दों, नामों और वाक्यांशों को पढ़ने देता है जो संभवत: उपयोगकर्ता द्वारा उपयोगकर्ता ‍डिक्शनरी में संग्रहीत किए गए हों."</string>
-    <string name="permlab_writeDictionary" msgid="2183110402314441106">"उपयोगकर्ता द्वारा परिभाषित डिक्शनरी में शब्द जोड़ें"</string>
-    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"एप्लिकेशन को उपयोगकर्ता डिक्शनरी में नए शब्द लिखने देता है."</string>
+    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"एप्स को आपके वर्तमान समन्वयित फ़ीड को संशोधित करने देता है. दुर्भावनापूर्ण एप्स आपके समन्वयित फ़ीड को बदल सकते है."</string>
+    <string name="permlab_readDictionary" msgid="4107101525746035718">"शब्दकोश में आपके द्वारा जोड़े गए शब्‍दों को पढ़ें"</string>
+    <string name="permdesc_readDictionary" msgid="659614600338904243">"एप्‍स को ऐसे सभी शब्‍दों, नामों और वाक्यांशों को पढ़ने देता है जो संभवत: उपयोगकर्ता द्वारा उपयोगकर्ता ‍शब्दकोश में संग्रहीत किए गए हों."</string>
+    <string name="permlab_writeDictionary" msgid="2183110402314441106">"उपयोगकर्ता द्वारा परिभाषित शब्दकोश में शब्द जोड़ें"</string>
+    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"एप्स को उपयोगकर्ता शब्दकोश में नए शब्द लिखने देता है."</string>
     <string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"संरक्ष‍ित संग्रहण पर पहुंच का परीक्षण करें"</string>
     <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"संरक्ष‍ित संग्रहण पर पहुंच का परीक्षण करें"</string>
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"एप्लि. को USB संग्रहण अनुमति का परीक्षण करने देता है जो भविष्‍य के उपकरणों में उपलब्‍ध होगा."</string>
-    <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"एप्लिकेशन को SD कार्ड के लिए किसी अनुमति का परीक्षण करने देता है जो भविष्‍य के उपकरणों में उपलब्‍ध होगा."</string>
+    <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"एप्स को 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="default" msgid="4337417790936632090">"एप्स को SD कार्ड पर लिखने देता है."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"आंतरिक मीडिया संग्रहण सामग्रियों को बदलें/हटाएं"</string>
-    <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"एप्लिकेशन को आंतरिक मीडिया संग्रहण की सामग्री को संशोधित करने देता है."</string>
+    <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"एप्स को आंतरिक मीडिया संग्रहण की सामग्री को संशोधित करने देता है."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"दस्तावेज़ संग्रहण प्रबंधित करें"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"एप्स को दस्तावेज़ संग्रहण प्रबंधित करने की अनुमति दें."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"सभी उपयोगकर्ताओं के बाहरी संग्रहण तक पहुंचें"</string>
-    <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"एप्लिकेशन को सभी उपयोगकर्ताओं के बाहरी संग्रहण तक पहुंचने दें."</string>
+    <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"एप्स को सभी उपयोगकर्ताओं के बाहरी संग्रहण तक पहुंचने दें."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"कैश फ़ाइल सिस्‍टम में पहंचे"</string>
-    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"एप्‍लिकेशन को संचय फ़ाइल सिस्‍टम पढ़ने और लिखने देता है."</string>
+    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"एप्‍स को संचय फ़ाइल सिस्‍टम पढ़ने और लिखने देता है."</string>
     <string name="permlab_use_sip" msgid="5986952362795870502">"इंटरनेट कॉल करें/प्राप्त करें"</string>
-    <string name="permdesc_use_sip" msgid="4717632000062674294">"एप्लिकेशन को इंटरनेट कॉल करने/प्राप्त करने के लिए SIP सेवा का उपयोग करने देता है."</string>
+    <string name="permdesc_use_sip" msgid="4717632000062674294">"एप्स को इंटरनेट कॉल करने/प्राप्त करने के लिए SIP सेवा का उपयोग करने देता है."</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="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"एप्स को यह संशोधित करने देता है कि एप्‍स की तुलना में नेटवर्क उपयोग का मूल्यांकन कैसे किया जाता है. सामान्‍य एप्‍स द्वारा उपयोग करने के लिए नहीं."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"सॉकेट मार्क बदलें"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"एप्स को रूटिंग के लिए सॉकेट मार्क बदलने देता है"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"सूचनाओं तक पहुंचें"</string>
-    <string name="permdesc_accessNotifications" msgid="458457742683431387">"एप्लिकेशन को सूचनाओं को प्राप्त करने, जांच करने, और साफ़ करने देता है, जिनमें अन्य एप्लिकेशन के द्वारा पोस्ट की गई सूचनाएं भी शामिल हैं."</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_invokeCarrierSetup" msgid="3699600833975117478">"वाहक के द्वारा उपलब्ध कराया गया कॉन्फ़िगरेशन एप्स प्रारंभ करें"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"धारक को वाहक के द्वारा उपलब्ध कराया गया कॉन्फ़िगरेशन एप्स प्रारंभ करने देता है. सामान्‍य एप्‍स के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"नेटवर्क स्थितियों के अवलोकनों को सुनें"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"एप्स को नेटवर्क स्थितियों के अवलोकनों को सुनने देता है. सामान्य एप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"पासवर्ड नियम सेट करें"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"स्‍क्रीन-अनलॉक पासवर्ड में अनुमति प्राप्त लंबाई और वर्णों को नियंत्रित करें."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"स्‍क्रीन-अनलॉक के प्रयासों पर निगरानी रखें"</string>
@@ -646,7 +687,7 @@
     <string name="policylab_expirePassword" msgid="885279151847254056">"स्‍क्रीन लॉक करें पासवर्ड समाप्ति सेट करें"</string>
     <string name="policydesc_expirePassword" msgid="1729725226314691591">"नियंत्रित करें कि कितने समय में लॉक-स्‍क्रीन पासवर्ड बदला जाना चाहिए."</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="266329104542638802">"कीगार्ड में सुविधाएं अक्षम करें"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -779,7 +819,7 @@
     <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_pattern_instructions" msgid="7478703254964810302">"अनलॉक करने के लिए आकार आरेखित करें"</string>
     <string name="lockscreen_emergency_call" msgid="5347633784401285225">"आपातकालीन कॉल"</string>
     <string name="lockscreen_return_to_call" msgid="5244259785500040021">"कॉल पर वापस लौटें"</string>
     <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"सही!"</string>
@@ -796,7 +836,7 @@
     <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">"अनुपयोगी SIM कार्ड."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"आपका सिम कार्ड स्‍थायी रूप से अक्षम कर दिया गया है."\n" दूसरे SIM कार्ड के लिए अपने वायरलेस सेवा प्रदाता से संपर्क करें."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"आपका सिम कार्ड स्‍थायी रूप से अक्षम कर दिया गया है.\n दूसरे SIM कार्ड के लिए अपने वायरलेस सेवा प्रदाता से संपर्क करें."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"पिछला ट्रैक बटन"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"अगला ट्रैक बटन"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"पॉज़ करें बटन"</string>
@@ -808,33 +848,33 @@
     <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">%d</xliff:g> बार गलत बनाया है. "\n\n" <xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"आपने अपना पासवर्ड <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से लिखा है. "\n\n"<xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"आपने अपना पिन <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से लिखा है. "\n\n"<xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में पुनः प्रयास करें."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"आपने अपना अनलॉक प्रतिमान <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत बनाया है. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने Google साइन-इन का उपयोग करके आपके टेबलेट को अनलॉक करने को कहा जाएगा."\n\n" <xliff:g id="NUMBER_2">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"आपने अपना अनलॉक प्रतिमान <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत बनाया है. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने Google साइन-इन का उपयोग करके आपके फ़ोन को अनलॉक करने को कहा जाएगा."\n\n" <xliff:g id="NUMBER_2">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"आपने अपना अनलॉक आकार <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत बनाया है. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"आपने अपना पासवर्ड <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से लिखा है. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"आपने अपना पिन <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से लिखा है. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में पुनः प्रयास करें."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"आपने अपना अनलॉक आकार <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत बनाया है. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने Google साइन-इन का उपयोग करके आपके टेबलेट को अनलॉक करने को कहा जाएगा.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"आपने अपना अनलॉक आकार <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत बनाया है. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने Google साइन-इन का उपयोग करके आपके फ़ोन को अनलॉक करने को कहा जाएगा.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"आप गलत तरीके से टेबलेट को अनलॉक करने का प्रयास <xliff:g id="NUMBER_0">%d</xliff:g> बार कर चुके हैं. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयास के बाद, टेबलेट फ़ैक्‍टरी डिफ़ॉल्‍ट पर रीसेट हो जाएगा और सभी उपयोगकर्ता डेटा खो जाएगा."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"आप गलत तरीके से फ़ोन को अनलॉक करने का प्रयास <xliff:g id="NUMBER_0">%d</xliff:g> बार कर चुके हैं. <xliff:g id="NUMBER_1">%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="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_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_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_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_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>
     <string name="lockscreen_sound_off_label" msgid="996822825154319026">"ध्वनि बंद"</string>
-    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"प्रतिमान प्रारंभ किया गया"</string>
-    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"प्रतिमान साफ़ किया गया"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"आकार प्रारंभ किया गया"</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"आकार साफ़ किया गया"</string>
     <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"कक्ष जोड़ा गया"</string>
-    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"प्रतिमान पूरा किया गया"</string>
+    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"आकार पूरा किया गया"</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_widget_empty_slot" msgid="1281505703307930757">"रिक्त"</string>
@@ -850,11 +890,11 @@
     <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_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_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>
     <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
@@ -871,10 +911,10 @@
     <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_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="autofill_this_form" msgid="4616758841157816676">"स्‍वत: भरण"</string>
@@ -896,25 +936,25 @@
     <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="default" msgid="8497389531014185509">"एप्लिकेशन को आपके फ़ोन में संग्रहीत ब्राउज़र के इतिहास या बुकमार्क को संशोधित करने देता है. इससे एप्लिकेशन ब्राउज़र डेटा को मिटा सकता है या संशोधित कर सकता है. ध्‍यान दें: यह अनुमति तृतीय-पक्ष ब्राउज़र या वेब ब्राउज़िंग क्षमताओं वाले अन्‍य एप्लिकेशन द्वारा लागू नहीं की जा सकती."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"एप्स को आपके टेबलेट में संग्रहीत ब्राउज़र के इतिहास या बुकमार्क को संशोधित करने देता है. इससे एप्स ब्राउज़र डेटा को मिटा सकता है या संशोधित कर सकता है. ध्‍यान दें: यह अनुमति तृतीय-पक्ष ब्राउज़र या वेब ब्राउज़िंग क्षमताओं वाले अन्‍य एप्स द्वारा लागू नहीं की जा सकती."</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="permlab_packageVerificationAgent" msgid="5568139100645829117">"पैकेज सत्‍यापि‍त करें"</string>
     <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"एप्‍लि‍केशन को इंस्‍टॉल करने योग्‍य पैकेज सत्‍यापि‍त करने देता है."</string>
     <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"पैकेज प्रमाणक से आबद्ध करें"</string>
-    <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"धारक को पैकेज प्रमाणक के अनुरोध की अनुमति‍ देता है. सामान्‍य एप्‍लिकेशन के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
+    <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"धारक को पैकेज प्रमाणक के अनुरोध की अनुमति‍ देता है. सामान्‍य एप्‍स के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
     <string name="permlab_serialPort" msgid="546083327654631076">"सीरियल पोर्ट पर पहुंचें"</string>
     <string name="permdesc_serialPort" msgid="2991639985224598193">"SerialManager API का उपयोग करके धारक को सीरियल पोर्ट पर पहुंच प्रदान करता है."</string>
     <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"बाह्य रूप से सामग्री प्रदाताओं पर पहुंच"</string>
-    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"धारक को शेल से सामग्री प्रदाताओं तक पहुंचने देता है. सामान्य एप्लिकेशन के लिए कभी भी आवश्यकता नहीं होनी चाहिए."</string>
-    <string name="permlab_updateLock" msgid="3527558366616680889">"स्वचालित उपकरण अपडेट का समर्थन न करें"</string>
+    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"धारक को शेल से सामग्री प्रदाताओं तक पहुंचने देता है. सामान्य एप्स के लिए कभी भी आवश्यकता नहीं होनी चाहिए."</string>
+    <string name="permlab_updateLock" msgid="3527558366616680889">"अपनेआप उपकरण की नई जानकारी न लें"</string>
     <string name="permdesc_updateLock" msgid="1655625832166778492">"धारक को उपकरण अपग्रेड करने के लिए, गैर-सहभागी रीबूट के ठीक समय के बारे में सिस्टम पर जानकारी प्रस्तुत करने देता है."</string>
     <string name="save_password_message" msgid="767344687139195790">"क्‍या आप चाहते हैं कि ब्राउज़र पासवर्ड को याद रखे?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"अभी नहीं"</string>
@@ -932,7 +972,7 @@
     <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="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>
@@ -1037,7 +1077,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>
@@ -1061,10 +1101,10 @@
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"संग्रहण स्‍थान समाप्‍त हो रहा है"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"हो सकता है कुछ सिस्टम फ़ंक्शन कार्य न करें"</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="4653586947747330058">"अधिक जानकारी के लिए या एप्लिकेशन रोकने के लिए स्पर्श करें."</string>
-    <string name="ok" msgid="5970060430562524910">"ठीक"</string>
+    <string name="app_running_notification_text" msgid="4653586947747330058">"अधिक जानकारी के लिए या एप्स रोकने के लिए स्पर्श करें."</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>
@@ -1074,40 +1114,40 @@
     <string name="alwaysUse" msgid="4583018368000610438">"इस क्रिया के लिए डिफ़ॉल्‍ट रूप से उपयोग करें."</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>
+    <string name="chooseUsbActivity" msgid="6894748416073583509">"USB उपकरण के लिए कोई एप्स चुनें"</string>
+    <string name="noApplications" msgid="2991814273936504689">"कोई भी एप्‍स यह कार्यवाही नहीं कर सकता."</string>
     <string name="aerr_title" msgid="1905800560317137752"></string>
     <string name="aerr_application" msgid="932628488013092776">"दुर्भाग्‍यवश, <xliff:g id="APPLICATION">%1$s</xliff:g> रुक गया है."</string>
     <string name="aerr_process" msgid="4507058997035697579">"दुर्भाग्‍यवश, <xliff:g id="PROCESS">%1$s</xliff:g> प्रक्रिया रुक गई है."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> प्रतिसाद नहीं दे रहा है."\n\n"क्‍या आप इसे बंद करना चाहते हैं?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"गतिविधि <xliff:g id="ACTIVITY">%1$s</xliff:g> प्रतिसाद नहीं दे रही है."\n\n"क्या आप इसे बंद करना चाहते हैं?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> प्रतिसाद नहीं दे रहा है.\n\nक्‍या आप इसे बंद करना चाहते हैं?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"गतिविधि <xliff:g id="ACTIVITY">%1$s</xliff:g> प्रतिसाद नहीं दे रही है.\n\nक्या आप इसे बंद करना चाहते हैं?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> प्रतिसाद नहीं दे रहा है. क्या आप इसे बंद करना चाहते हैं?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"प्रक्रिया <xliff:g id="PROCESS">%1$s</xliff:g> प्रतिसाद नहीं दे रही है."\n\n"क्‍या आप इसे बंद करना चाहते हैं?"</string>
-    <string name="force_close" msgid="8346072094521265605">"ठीक"</string>
+    <string name="anr_process" msgid="6513209874880517125">"प्रक्रिया <xliff:g id="PROCESS">%1$s</xliff:g> प्रतिसाद नहीं दे रही है.\n\nक्‍या आप इसे बंद करना चाहते हैं?"</string>
+    <string name="force_close" msgid="8346072094521265605">"ठीक है"</string>
     <string name="report" msgid="4060218260984795706">"रिपोर्ट करें"</string>
     <string name="wait" msgid="7147118217226317732">"प्रतीक्षा करें"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"पृष्ठ प्रतिसाद नहीं दे रहा है."\n\n"क्‍या आप इसे बंद करना चाहते हैं?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"पृष्ठ प्रतिसाद नहीं दे रहा है.\n\nक्‍या आप इसे बंद करना चाहते हैं?"</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="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_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>
     <string name="android_upgrading_title" msgid="1584192285441405746">"Android अपग्रेड हो रहा है..."</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_starting_apps" msgid="451464516346926713">"एप्लिकेशन प्रारंभ होने वाले हैं"</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_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="1721681741617898865">"एप्‍लिकेशन पर स्‍विच करने के लिए स्‍पर्श करें"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"एप्लिकेशन स्विच करें?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"दूसरा एप्लिकेशन पहले से चल रहा है जिसे किसी नए एप्‍लिकेशन को प्रारंभ करने के पहले बंद किया जाना आवश्‍यक है."</string>
+    <string name="heavy_weight_notification_detail" msgid="1721681741617898865">"एप्‍स पर स्‍विच करने के लिए स्‍पर्श करें"</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>
+    <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="sendText" msgid="5209874571959469142">"पाठ के लिए किसी क्रिया को चुनें"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"रिंगर वॉल्‍यूम"</string>
     <string name="volume_music" msgid="5421651157138628171">"मीडिया वॉल्‍यूम"</string>
@@ -1115,9 +1155,9 @@
     <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_alarm" msgid="1985191616042689100">"अलार्म वॉल्यूम"</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_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>
@@ -1136,8 +1176,8 @@
     <item quantity="one" msgid="1634101450343277345">"उपलब्‍ध Wi-Fi नेटवर्क खोलें"</item>
     <item quantity="other" msgid="7915895323644292768">"खुले Wi-Fi नेटवर्क उपलब्‍ध है"</item>
   </plurals>
-    <string name="wifi_available_sign_in" msgid="4029489716605255386">"Wi-Fi नेटवर्क में साइन इन करें"</string>
-    <string name="network_available_sign_in" msgid="8495155593358054676">"नेटवर्क में साइन इन करें"</string>
+    <string name="wifi_available_sign_in" msgid="4029489716605255386">"Wi-Fi नेटवर्क में प्रवेश करें"</string>
+    <string name="network_available_sign_in" msgid="8495155593358054676">"नेटवर्क में प्रवेश करें"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi से कनेक्‍ट नहीं हो सका"</string>
@@ -1159,7 +1199,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>
@@ -1168,7 +1208,7 @@
     <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">"सिमकार्ड निकाला गया"</string>
@@ -1202,9 +1242,9 @@
     <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"USB संग्रहण बंद करें"</string>
     <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"USB संग्रहण बंद करने में कोई समस्‍या हुई थी. जांचें कि आपने USB होस्‍ट अनमाउंट किया है या नहीं, तब पुन: प्रयास करें."</string>
     <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"USB संग्रहण चालू करें"</string>
-    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"यदि आप USB संग्रहण चालू करते हैं, तो आपके द्वारा उपयोग किए जा रहे कुछ एप्‍लिकेशन रुक जाएंगे और हो सकता है कि वे तब तक अनुपलब्‍ध रहें जब तक कि आप USB संग्रहण बंद नहीं कर देते."</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"यदि आप USB संग्रहण चालू करते हैं, तो आपके द्वारा उपयोग किए जा रहे कुछ एप्‍स रुक जाएंगे और हो सकता है कि वे तब तक अनुपलब्‍ध रहें जब तक कि आप USB संग्रहण बंद नहीं कर देते."</string>
     <string name="dlg_error_title" msgid="7323658469626514207">"USB कार्यवाही विफल"</string>
-    <string name="dlg_ok" msgid="7376953167039865701">"ठीक"</string>
+    <string name="dlg_ok" msgid="7376953167039865701">"ठीक है"</string>
     <string name="usb_mtp_notification_title" msgid="3699913097391550394">"किसी मीडिया उपकरण के रूप में कनेक्‍ट किया गया"</string>
     <string name="usb_ptp_notification_title" msgid="1960817192216064833">"कैमरे के रूप में कनेक्‍ट करें"</string>
     <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"किसी इंस्‍टॉलर के रूप में कनेक्‍ट किया गया"</string>
@@ -1250,12 +1290,16 @@
     <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"USB संग्रहण निकाला गया. नया मीडिया सम्‍मिलित करें."</string>
     <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"SD कार्ड निकाला गया. एक नया सम्‍मिलित करें."</string>
     <string name="activity_list_empty" msgid="1675388330786841066">"कोई मिलती-जुलती गतिविधि नहीं मिली."</string>
-    <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"घटक उपयोग आंकड़े अपडेट करें"</string>
-    <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"एप्‍लिकेशन को घटक उपयोग के संकलित आंकड़े संशोधित करने देता है. सामान्‍य एप्‍लिकेशन द्वारा उपयोग करने के लिए नहीं."</string>
+    <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"घटक उपयोग आंकड़ों की नई जानकारी पाएं"</string>
+    <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"एप्‍स को घटक उपयोग के संकलित आंकड़े संशोधित करने देता है. सामान्‍य एप्‍स द्वारा उपयोग करने के लिए नहीं."</string>
     <string name="permlab_copyProtectedData" msgid="4341036311211406692">"सामग्री की प्रतिलिपि बनाएं"</string>
-    <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"एप्लिकेशन को सामग्री की प्रतिलिपि बनाने के लिए डिफ़ॉल्ट कंटेनर सेवा शुरू करने देता है. सामान्‍य एप्‍लिकेशन द्वारा उपयोग करने के लिए नहीं."</string>
+    <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"एप्स को सामग्री की प्रतिलिपि बनाने के लिए डिफ़ॉल्ट कंटेनर सेवा शुरू करने देता है. सामान्‍य एप्‍स द्वारा उपयोग करने के लिए नहीं."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"मीडिया आउटपुट को रूट करें"</string>
-    <string name="permdesc_route_media_output" msgid="4932818749547244346">"एप्लिकेशन को मीडिया आउटपुट को अन्य बाहरी उपकरणों पर रूट करने देता है."</string>
+    <string name="permdesc_route_media_output" msgid="4932818749547244346">"एप्स को मीडिया आउटपुट को अन्य बाहरी उपकरणों पर रूट करने देता है."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"कीगार्ड सुरक्षित संग्रहण एक्सेस करें"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"एप्स को कीगार्ड सुरक्षित संग्रहण एक्सेस करने देती है."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"कीगार्ड दिखाना और छिपाना नियंत्रित करें"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"एप्स को कीगार्ड नियंत्रित करने देती है."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"ज़ूम नियंत्रण के लिए दो बार स्पर्श करें"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"विजेट नहीं जोड़ा जा सका."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"जाएं"</string>
@@ -1265,15 +1309,15 @@
     <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="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="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="permission_request_notification_with_subtitle" msgid="8530393139639560189">"<xliff:g id="ACCOUNT">%s</xliff:g> खाते के लिए अनुमति\nका अनुरोध किया गया."</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>
@@ -1364,7 +1408,7 @@
     <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>
-    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"कोई एप्‍लिकेशन चुनें"</string>
+    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"कोई एप्‍स चुनें"</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">"स्लाइडिंग हैंडल. स्पर्श करके रखें."</string>
@@ -1385,7 +1429,7 @@
     <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="4891916833657929263">"आंतरिक संग्रहण"</string>
+    <string name="storage_internal" msgid="4891916833657929263">"मोबाइल संग्रहण"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD कार्ड"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB संग्रहण"</string>
     <string name="extract_edit_menu_button" msgid="8940478730496610137">"संपादित करें"</string>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"सभी देखें"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"गतिविधि चुनें"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"इसके साथ साझा करें:"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"उपकरण लॉक कर दिया गया."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"भेजा जा रहा है…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"ब्राउज़र लॉन्च करें?"</string>
@@ -1441,20 +1484,22 @@
     <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>
+    <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_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="wifi_display_notification_title" msgid="2223050649240326557">"वायरलेस डिस्प्ले कनेक्ट है"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"यह स्क्रीन अन्य उपकरण पर दिखाई दे रही है"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"डिस्कनेक्ट करें"</string>
     <string name="kg_emergency_call_label" msgid="684946192523830531">"आपातकालीन कॉल"</string>
-    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"प्रतिमान भूल गए"</string>
-    <string name="kg_wrong_pattern" msgid="1850806070801358830">"गलत प्रतिमान"</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">"गलत PIN"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
-    <string name="kg_pattern_instructions" msgid="398978611683075868">"अपना प्रतिमान आरेखित करें"</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 डालें"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN डालें"</string>
     <string name="kg_password_instructions" msgid="5753646556186936819">"पासवर्ड डालें"</string>
@@ -1467,33 +1512,91 @@
     <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK कोड 8 या अधिक संख्या वाला होना चाहिए."</string>
     <string name="kg_invalid_puk" msgid="3638289409676051243">"सही PUK कोड पुन: डालें. बार-बार प्रयास करने से सिम स्थायी रूप से अक्षम हो जाएगी."</string>
     <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"पिन कोड का मिलान नहीं होता"</string>
-    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"बहुत अधिक प्रतिमान प्रयास"</string>
-    <string name="kg_login_instructions" msgid="1100551261265506448">"अनलॉक करने के लिए, अपने Google खाते से साइन इन करें."</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_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_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">%d</xliff:g> बार गलत तरीके से लिख चुके हैं. "\n\n" <xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"आप अपना पासवर्ड <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से लिख चुके हैं. "\n\n" <xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"आपने अपना अनलॉक प्रतिमान <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से आरेखित किया है. "\n\n" <xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"आप अपना PIN <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से लिख चुके हैं. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"आप अपना पासवर्ड <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से लिख चुके हैं. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"आपने अपना अनलॉक आकार <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से आरेखित किया है. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"आप टेबलेट को अनलॉक करने के लिए <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से प्रयास कर चुके हैं. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, टेबलेट फ़ैक्टरी डिफ़ॉल्ट पर रीसेट हो जाएगा और सभी उपयोगकर्ता डेटा खो जाएगा."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"आप फ़ोन को अनलॉक करने के लिए <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से प्रयास कर चुके हैं. <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> बार गलत तरीके से आरेखित किया है. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने टेबलेट को किसी ईमेल खाते के उपयोग से अनलॉक करने के लिए कहा जाएगा."\n\n" <xliff:g id="NUMBER_2">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"आपने अपने अनलॉक प्रतिमान को <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से आरेखित किया है. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने फ़ोन को किसी ईमेल खाते का उपयोग करके अनलॉक करने के लिए कहा जाएगा."\n\n" <xliff:g id="NUMBER_2">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"आपने अपने अनलॉक आकार को <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से आरेखित किया है. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने टेबलेट को किसी ईमेल खाते के उपयोग से अनलॉक करने के लिए कहा जाएगा.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"आपने अपने अनलॉक आकार को <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से आरेखित किया है. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने फ़ोन को किसी ईमेल खाते का उपयोग करके अनलॉक करने के लिए कहा जाएगा.\n\n <xliff:g id="NUMBER_2">%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="7324161939475478066">"वॉल्यूम को उपरोक्त अनुशंसित स्तर तक बढ़ाएं?"\n"लंबे समय तक अधिक वॉल्यूम पर सुनने से आपकी सुनने की क्षमता को क्षति पहुंच सकती है."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"आवाज़ को उपरोक्त सुझाव दिया गया स्तर तक बढ़ाएं?\nलंबे समय तक अधिक आवाज़ पर सुनने से आपकी सुनने की क्षमता को क्षति पहुंच सकती है."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"पहुंच-योग्यता को सक्षम करने के लिए दो अंगुलियों से नीचे दबाए रखें."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"पहुंच-योग्यता सक्षम कर दी है."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"पहुंच-योग्यता रद्द की गई."</string>
     <string name="user_switched" msgid="3768006783166984410">"वर्तमान उपयोगकर्ता <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="app_no_restricted_accounts" msgid="4011285085817350390">"यह एप्लिकेशन प्रतिबंधित प्रोफ़ाइल के खातों का समर्थन नहीं करता है"</string>
-    <string name="app_not_found" msgid="3429141853498927379">"इस कार्यवाही को प्रबंधित करने के लिए कोई एप्लिकेशन नहीं मिला"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"यह एप्स प्रतिबंधित प्रोफ़ाइल के खातों का समर्थन नहीं करता है"</string>
+    <string name="app_not_found" msgid="3429141853498927379">"इस कार्यवाही को प्रबंधित करने के लिए कोई एप्स नहीं मिला"</string>
     <string name="revoke" msgid="5404479185228271586">"निरस्‍त करें"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"लेटर"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"गवर्नमेंट लेटर"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"लीगल"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"जूनियर लीगल"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"लेजर"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"टेबलॉइड"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"रद्द कर दी गई"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"सामग्री लिखने में त्रुटि"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"अज्ञात"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"व्यवस्थापक पिन डालें"</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">"वर्तमान पिन"</string>
+    <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_too_short" msgid="8173982756265777792">"PIN बहुत छोटा है. कम से कम 4 अंकों का होना चाहिए."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"1 सेकंड में पुन: प्रयास करें"</item>
+    <item quantity="other" msgid="4730868920742952817">"<xliff:g id="COUNT">%d</xliff:g> सेकंड में पुन: प्रयास करें"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"बाद में पुनः प्रयास करें"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"बार को प्रदर्शित करने के लिए स्क्रीन के किनारे को स्वाइप करें"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"सिस्टम बार को प्रदर्शित करने के लिए स्क्रीन के किनारे से स्वाइप करें"</string>
 </resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 733a0e3..e839579 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -131,6 +131,11 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Previše brisanja stavki <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Prostor za pohranu tabletnog računala pun je. Izbrišite nekoliko datoteka kako biste oslobodili prostor."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Prostor za pohranu na telefonu je pun. Izbrišite nekoliko datoteka kako biste oslobodili prostor."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Mreža se možda nadzire"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Ja"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opcije tabletnog uređaja"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Opcije telefona"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Aplikaciji omogućuje premještanje zadataka u prednji plan ili pozadinu. Aplikacija to može napraviti bez vašeg naloga."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"zaustavljanje pokrenutih aplikacija"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Omogućuje aplikaciji uklanjanje zadataka i uklanjanje njihovih aplikacija. Zlonamjerne aplikacije mogu poremetiti rad drugih aplikacija."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"upravljaj snopovima aktivnosti"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Dopušta aplikaciji dodavanje, uklanjanje i izmjenu snopova aktivnosti u kojima se druge aplikacije izvršavaju. Zlonamjerne aplikacije mogu poremetiti ponašanje ostalih aplikacija."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"započni bilo kakvu aktivnost"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Omogućuje aplikaciji da započne bilo koju aktivnost, bez obzira na zaštitu pomoću dozvola ili stanje izvoza."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"postavljanje kompatibilnosti sa zaslonom"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Nositelju omogućuje povezivanje sučelja najviše razine načina unosa. Ne bi smjelo biti potrebno za normalne aplikacije."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"vezivanje uz uslugu dostupnosti"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Nositelju omogućuje vezanje uz sučelje najviše razine usluge dostupnosti. Ne bi smjelo biti potrebno za normalne aplikacije."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"veži se uz uslugu ispisa"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Dopušta nositelju vezanje uza sučelje usluge ispisa najviše razine. Ne bi smjelo biti potrebno za uobičajene aplikacije."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"veži se uz uslugu predmemoriranja ispisa"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Dopušta nositelju vezanje uza sučelje usluge predmemoriranja ispisa najviše razine. Ne bi smjelo biti potrebno za uobičajene aplikacije."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"povezivanje s NFC uslugom"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Omogućuje nositelju povezivanje s aplikacijama koje emuliraju NFC kartice. Nikada ne bi trebalo biti potrebno za uobičajene aplikacije."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"vezanje na tekstualnu uslugu"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Omogućuje korisniku povezivanje s najvišom razinom sučelja tekstualne usluge (npr. SpellCheckerService). Ne bi smjelo biti potrebno za normalne aplikacije."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"vezanje na VPN uslugu"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Nositelju omogućuje vezanje uz sučelje najviše razine usluge widgeta. Ne bi smjelo biti potrebno za normalne aplikacije."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interakcija s administratorom uređaja"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Nositelju omogućuje slanje namjera administratoru uređaja. Ne bi smjelo biti potrebno za normalne aplikacije."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"dodavanje ili uklanjanje administratora uređaja"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Omogućuje nositelju dodavanje ili uklanjanje administratora aktivnih uređaja. Nikada ne bi trebalo biti potrebno za uobičajene aplikacije."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"promjena orijentacije zaslona"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Omogućuje aplikaciji promjenu rotacije zaslona u bilo kojem trenutku. Ne bi smjelo biti potrebno za normalne aplikacije."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"promjena brzine pokazivača"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Aplikaciji omogućuje čitanje raznih sistemskih datoteka zapisnika. Tako može otkriti opće informacije o tome što radite na telefonu, što potencijalno uključuje osobne ili privatne informacije."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"upotrijebi bilo koji dekoder za reprodukciju"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Aplikaciji omogućuje korištenje bilo kojim instaliranim dekoderom medija za dekodiranje radi reprodukcije."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"upravljanje pouzdanim vjerodajnicama"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Omogućuje aplikaciji instaliranje i deinstaliranje CA certifikata kao pouzdanih vjerodajnica."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"pisanje/čitanje u resursima čije je vlasnik dijagnostika"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Aplikaciji omogućuje čitanje i pisanje na bilo koji resurs u vlasništvu dijag. grupe; na primjer, datoteke u sustavu /dev. To bi moglo utjecati na stabilnost sustava i sigurnost. Dozvolu bi trebao upotrebljavati proizvođač ili operater SAMO za dijagnostiku koja se odnosi na hardver."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"omogućavanje ili onemogućavanje komponenti aplikacije"</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Omogućuje aplikaciji konfiguriranje i povezivanje s Wi-Fi zaslonima."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"upravljaj Wifi zaslonima"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Omogućuje aplikaciji upravljanje značajkama Wi-Fi zaslona niske razine."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"primanje audioizlaza"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Omogućuje aplikaciji primanje i preusmjeravanje audioizlaza."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"primanje videoizlaza"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Omogućuje aplikaciji primanje i preusmjeravanje videoizlaza."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"primanje sigurnog videoizlaza"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Omogućuje aplikaciji primanje i preusmjeravanje sigurnog videoizlaza."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"promjena postavki zvuka"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Aplikaciji omogućuje izmjenu globalnih postavki zvuka, primjerice glasnoće i zvučnika koji se upotrebljava za izlaz."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"snimanje zvuka"</string>
@@ -525,6 +552,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"sprečava telefon da prijeđe u stanje mirovanja"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Aplikaciji omogućuje sprječavanje prelaska tabletnog računala u mirovanje."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Aplikaciji omogućuje da spriječi prelazak telefona u mirovanje."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"uključivanje ili isključivanje tabletnog uređaja"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"uključivanje ili isključivanje telefona"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Aplikaciji omogućuje uključivanje i isključivanje tabletnog računala."</string>
@@ -613,6 +646,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Aplikaciji omogućuje pisanje na SD karticu."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"izmijeni/izbriši sadržaj pohranjen na internim medijima"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Aplikaciji omogućuje izmjenu sadržaja pohranjenog na internim medijima."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"upravljanje pohr. dokumenata"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Omogućuje aplikaciji upravljanje pohranom dokumenata."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"pristup vanjskoj pohrani svima"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Omogućuje aplikaciji pristup vanjskoj pohrani za sve korisnike."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"pristup sustavu datoteka predmemorije"</string>
@@ -625,10 +660,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Aplikaciji omogućuje upravljanje mrežnim pravilima i određivanje pravila za aplikacije."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"izmjena evidencije mrežne upotrebe"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Omogućuje aplikaciji izmjenu načina upotrebe mreže u odnosu na aplikacije. Nije namijenjeno uobičajenim aplikacijama."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"izmijeni oznake utičnica"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Dopušta aplikaciji izmjenu oznaka utičnica za usmjeravanje"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"pristup obavijestima"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Omogućuje aplikaciji dohvaćanje, pregledavanje i brisanje obavijesti, uključujući obavijesti drugih aplikacija."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"vezanje uz uslugu slušatelja obavijesti"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Nositelju omogućuje vezanje uz sučelje najviše razine usluge slušatelja obavijesti. Ne bi smjelo biti potrebno za uobičajene aplikacije."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"pozovi operaterovu aplikaciju za konfiguraciju"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Dopušta nositelju pozivanje operaterove aplikacije za konfiguraciju. Ne bi smjelo biti potrebno za uobičajene aplikacije."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"praćenje motrenja mrežnih uvjeta"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Omogućuje aplikaciji praćenje motrenja mrežnih uvjeta. Ne bi trebalo biti potrebno za uobičajene aplikacije."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Postavi pravila zaporke"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Upravljajte duljinom zaporki za otključavanje zaslona i dopuštenim znakovima u tim zaporkama."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Nadgledaj pokušaje otključavanja zaslona"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +836,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Umetnite SIM karticu."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM kartica nedostaje ili nije čitljiva. Umetnite SIM karticu."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Neupotrebljiva SIM kartica."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Vaša SIM kartica trajno je onemogućena."\n" Obratite se svom pružatelju bežičnih usluga da biste dobili drugu SIM karticu."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Vaša SIM kartica trajno je onemogućena.\n Obratite se svom pružatelju bežičnih usluga da biste dobili drugu SIM karticu."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Gumb Prethodni zapis"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Gumb Sljedeći zapis"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Gumb Pauza"</string>
@@ -808,11 +848,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Pogledajte korisnički priručnik ili kontaktirajte korisničku službu."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM kartica je zaključana."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Otključavanje SIM kartice…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%d</xliff:g> puta. "\n\n"Pokušajte ponovo za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Netočno ste napisali zaporku <xliff:g id="NUMBER_0">%d</xliff:g> puta. "\n\n"Pokušajte ponovo za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Netočno ste napisali PIN <xliff:g id="NUMBER_0">%d</xliff:g> puta. "\n\n"Pokušajte ponovo za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%d</xliff:g> puta. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g> zamolit ćemo vas da otključate tabletno računalo putem prijave na Google."\n\n" Pokušajte ponovo za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%d</xliff:g> puta. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g> morat ćete otključati telefon putem prijave na Google."\n\n" Pokušajte ponovo za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Netočno ste napisali zaporku <xliff:g id="NUMBER_0">%d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Netočno ste napisali PIN <xliff:g id="NUMBER_0">%d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%d</xliff:g> puta. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g> zamolit ćemo vas da otključate tabletno računalo putem prijave na Google.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%d</xliff:g> puta. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g> morat ćete otključati telefon putem prijave na Google.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Neispravno ste pokušali otključati tabletno računalo ovoliko puta: <xliff:g id="NUMBER_0">%d</xliff:g>. Ono će se vratiti na tvorničke postavke i svi korisnički podaci bit će izgubljeni nakon još ovoliko neuspjelih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Neispravno ste pokušali otključati telefon ovoliko puta: <xliff:g id="NUMBER_0">%d</xliff:g>. On će se vratiti na tvorničke postavke i svi korisnički podaci bit će izgubljeni nakon još ovoliko neuspjelih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Neispravno ste pokušali otključati tabletno računalo ovoliko puta: <xliff:g id="NUMBER">%d</xliff:g>. Sada će biti vraćeno na tvorničke postavke."</string>
@@ -826,7 +866,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Zaporka"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Prijava"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nevažeće korisničko ime ili zaporka."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Zaboravili ste korisničko ime ili zaporku?"\n"Posjetite "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Zaboravili ste korisničko ime ili zaporku?\nPosjetite "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Provjeravanje..."</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Otključaj"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Zvuk je uključen"</string>
@@ -874,7 +914,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Potvrda kretanja"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Napusti stranicu"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Ostani na ovoj stranici"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Jeste li sigurni da želite napustiti ovu stranicu?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nJeste li sigurni da želite napustiti ovu stranicu?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Potvrdi"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Savjet: Dvaput dotaknite za povećavanje i smanjivanje."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Aut.pop."</string>
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"Nažalost, aplikacija <xliff:g id="APPLICATION">%1$s</xliff:g> prekinula je s radom."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Nažalost, zaustavljen je proces <xliff:g id="PROCESS">%1$s</xliff:g>."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"Aplikacija <xliff:g id="APPLICATION">%2$s</xliff:g> ne reagira."\n\n"Želite li je zatvoriti?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Aktivnost <xliff:g id="ACTIVITY">%1$s</xliff:g> ne reagira."\n\n"Želite li je zatvoriti?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"Aplikacija <xliff:g id="APPLICATION">%2$s</xliff:g> ne reagira.\n\nŽelite li je zatvoriti?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Aktivnost <xliff:g id="ACTIVITY">%1$s</xliff:g> ne reagira.\n\nŽelite li je zatvoriti?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"Aplikacija <xliff:g id="APPLICATION">%1$s</xliff:g> ne reagira. Želite li je zatvoriti?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Postupak <xliff:g id="PROCESS">%1$s</xliff:g> ne reagira."\n\n"Želite li ga zatvoriti?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Postupak <xliff:g id="PROCESS">%1$s</xliff:g> ne reagira.\n\nŽelite li ga zatvoriti?"</string>
     <string name="force_close" msgid="8346072094521265605">"U redu"</string>
     <string name="report" msgid="4060218260984795706">"Izvješće"</string>
     <string name="wait" msgid="7147118217226317732">"Pričekaj"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"Stranica ne reagira."\n\n"Želite li ju zatvoriti?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Stranica ne reagira.\n\nŽelite li ju zatvoriti?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Aplikacija preusmjerena"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> se izvodi sada."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> pokrenuta je prva."</string>
@@ -1256,6 +1296,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Omogućuje aplikaciji dozivanje usluge zadanog spremnika radi kopiranja sadržaja. Nije namijenjena uobičajenim aplikacijama."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Usmjeravanje medijskog izlaza"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Aplikaciji omogućuje usmjeravanje medijskog izlaza na druge vanjske uređaje."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Pristup zaključanoj sigurnoj pohrani"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Omogućuje aplikaciji pristupanje zaključanoj sigurnoj pohrani."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Upravljanje prikazivanjem i skrivanjem zaključavanja tipkovnice"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Omogućuje aplikaciji upravljanje zaključavanjem tipkovnice."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Dodirnite dvaput za upravljanje zumiranjem"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Widget nije moguće dodati."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Idi"</string>
@@ -1265,15 +1309,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Gotovo"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Preth."</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Pokreni"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Biraj broj"\n"koristeći <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Stvori kontakt"\n"koristeći <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Biraj broj\nkoristeći <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Stvori kontakt\nkoristeći <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Sljedeća aplikacija ili više njih zahtijevaju dozvolu za pristup vašem računu, sad i u budućnosti."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Dopuštate li taj zahtjev?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Zahtjev za pristup"</string>
     <string name="allow" msgid="7225948811296386551">"Dopusti"</string>
     <string name="deny" msgid="2081879885755434506">"Odbij"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Zatražena je dozvola"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Zatražena je dozvola"\n"za račun <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Zatražena je dozvola\nza račun <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Način unosa"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Sinkronizacija"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Dostupnost"</string>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Prikaži sve"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Odabir aktivnosti"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Dijeljenje s"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Uređaj zaključan."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Slanje..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Pokrenuti preglednik?"</string>
@@ -1441,10 +1484,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Povezivanje..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Dostupno"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"Nije dostupno"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"U upotrebi"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Ugrađeni zaslon"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"HDMI zaslon"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Preklapanje br. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", sigurno"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Bežični je prikaz povezan"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Ovaj se zaslon prikazuje na nekom drugom uređaju"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Isključi"</string>
@@ -1453,7 +1498,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Pogrešan obrazac"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Pogrešna zaporka"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"Pogrešan PIN"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Pokušajte ponovo za <xliff:g id="NUMBER">%d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Pokušajte ponovo za <xliff:g id="NUMBER">%1$d</xliff:g> s."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Iscrtajte svoj obrazac"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Unesite PIN za SIM"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Unesite PIN"</string>
@@ -1473,27 +1518,85 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Zaporka"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Prijava"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nevažeće korisničko ime ili zaporka."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Zaboravili ste korisničko ime ili zaporku?"\n"Posjetite "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Zaboravili ste korisničko ime ili zaporku?\nPosjetite "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Provjera računa..."</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Netočno ste napisali PIN <xliff:g id="NUMBER_0">%d</xliff:g> puta. "\n\n"Pokušajte ponovo za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Netočno ste napisali zaporku <xliff:g id="NUMBER_0">%d</xliff:g> puta. "\n\n"Pokušajte ponovo za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Netočno ste iscrtali obrazac za otključavanje <xliff:g id="NUMBER_0">%d</xliff:g> puta. "\n\n"Pokušajte ponovo za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Netočno ste napisali PIN <xliff:g id="NUMBER_0">%d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Netočno ste napisali zaporku <xliff:g id="NUMBER_0">%d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Netočno ste iscrtali obrazac za otključavanje <xliff:g id="NUMBER_0">%d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Netočno ste pokušali otključati tabletno računalo <xliff:g id="NUMBER_0">%d</xliff:g> puta. Ono će se vratiti na tvorničke postavke i svi korisnički podaci bit će izgubljeni nakon još ovoliko neuspjelih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Netočno ste pokušali otključati telefon <xliff:g id="NUMBER_0">%d</xliff:g> puta. On će se vratiti na tvorničke postavke i svi korisnički podaci bit će izgubljeni nakon još ovoliko neuspjelih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Netočno ste pokušali otključati tabletno računalo <xliff:g id="NUMBER">%d</xliff:g> puta. Sada će se vratiti na tvorničke postavke."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Netočno ste pokušali otključati telefon <xliff:g id="NUMBER">%d</xliff:g> puta. Sada će se vratiti na tvorničke postavke."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Netočno ste iscrtali obrazac za otključavanje <xliff:g id="NUMBER_0">%d</xliff:g> puta. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g> morat ćete otključati tabletno računalo pomoću računa e-pošte."\n\n" Pokušajte ponovo za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Netočno ste iscrtali obrazac za otključavanje <xliff:g id="NUMBER_0">%d</xliff:g> puta. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g> morat ćete otključati telefon pomoću računa e-pošte."\n\n" Pokušajte ponovo za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Netočno ste iscrtali obrazac za otključavanje <xliff:g id="NUMBER_0">%d</xliff:g> puta. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g> morat ćete otključati tabletno računalo pomoću računa e-pošte.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Netočno ste iscrtali obrazac za otključavanje <xliff:g id="NUMBER_0">%d</xliff:g> puta. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g> morat ćete otključati telefon pomoću računa e-pošte.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
     <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="7324161939475478066">"Želite li pojačati iznad preporučene razine?"\n"Dulje slušanje preglasne glazbe može vam oštetiti sluh."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Želite li pojačati iznad preporučene razine?\nDulje slušanje preglasne glazbe može vam oštetiti sluh."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Nastavite držati s dva prsta kako biste omogućili pristupačnost."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Dostupnost je omogućena."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Pristupačnost otkazana."</string>
     <string name="user_switched" msgid="3768006783166984410">"Trenutačni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Vlasnik"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Pogreška"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Aplikacija ne podržava račune za ograničene profile"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Aplikacija ne podržava račune za ograničene profile"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Nije pronađena aplikacija za upravljanje ovom radnjom"</string>
     <string name="revoke" msgid="5404479185228271586">"Opozovi"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Otkazano"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Pogreška prilikom pisanja sadržaja"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"nepoznato"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Unesite PIN administratora"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Unesite PIN"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Netočno"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Trenutačni PIN"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Novi PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Potvrdite novi PIN"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Izradite PIN za izmjenu ograničenja"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PIN-ovi se ne podudaraju. Pokušajte ponovo."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"PIN je prekratak. Mora imati barem 4 znamenke."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Ponovite za 1 s"</item>
+    <item quantity="other" msgid="4730868920742952817">"Ponovite za <xliff:g id="COUNT">%d</xliff:g> s"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Pokušajte ponovo kasnije"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Prijeđite po rubu za prikaz trake"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Prijeđite prstom od ruba zaslona da bi se prikazala traka sustava"</string>
 </resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index dab8941..b313efb 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -131,6 +131,11 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Túl sok <xliff:g id="CONTENT_TYPE">%s</xliff:g> törlés."</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"A táblagép tárhelye tele van. Szabadítson fel helyet néhány fájl törlésével."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"A telefon tárhelye megtelt. Hely felszabadításához töröljön néhány fájlt."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Lehet, hogy a hálózat felügyelt"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Saját"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Táblagép beállításai"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Telefonbeállítások"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Lehetővé teszi az alkalmazás számára, hogy feladatokat helyezzen át az előtérből a háttérbe és fordítva. Az alkalmazás ezt az Ön jóváhagyása nélkül is megteheti."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"futó alkalmazások leállítása"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Lehetővé teszi, hogy az alkalmazás feladatokat távolítson el és leállítsa azok alkalmazásait. Rosszindulatú alkalmazások megzavarhatják más alkalmazások viselkedését."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"tevékenységkötegek kezelése"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Engedélyezi az alkalmazás számára, hogy hozzáadjon, eltávolítson vagy módosítson olyan tevékenységkötegeket, amelyekben más alkalmazások futnak. A rosszindulatú alkalmazások tönkretehetik más alkalmazások működését."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"bármely tevékenység elindítása"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Lehetővé teszi az alkalmazás számára bármely tevékenység elindítását az engedélyektől és exportált állapottól függetlenül."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"Képernyő-kompatibilitás beállítása"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Lehetővé teszi, hogy a tulajdonos kötelezővé tegye egy beviteli mód legfelső szintű felületét. A normál alkalmazásoknak erre soha nincs szüksége."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"csatlakozás egy kisegítő szolgáltatáshoz"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Lehetővé teszi a használó számára, hogy csatlakozzon egy kisegítő szolgáltatás legfelső szintű kezelőfelületéhez. A normál alkalmazásoknak erre soha nincs szükségük."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"csatlakozás egy nyomtatási szolgáltatáshoz"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Lehetővé teszi a használó számára, hogy csatlakozzon egy nyomtatási szolgáltatás legfelső szintű kezelőfelületéhez. A normál alkalmazásoknak erre soha nincs szükségük."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"csatlakozás egy nyomtatásisor-kezelő szolgáltatáshoz"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Lehetővé teszi a használó számára, hogy csatlakozzon egy nyomtatásisor-kezelő legfelső szintű kezelőfelületéhez. A normál alkalmazásoknak erre soha nincs szükségük."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"csatlakozás NFC-szolgáltatáshoz"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Az eszköz kezelője csatlakozhat NFC-kártyákat emuláló alkalmazásokhoz. A normál alkalmazásoknak nincs rá szükségük."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"csatlakozás szövegszolgáltatáshoz"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Lehetővé teszi, hogy a tulajdonos egy szöveges szolgáltatás felső szintjéhez kapcsolódjon (pl. SpellCheckerService). A normál alkalmazásoknak erre soha nincs szüksége."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"csatlakozás egy VPN-szolgáltatáshoz"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Lehetővé teszi a használó számára, hogy csatlakozzon egy modulszolgáltatás legfelső szintű kezelőfelületéhez. A normál alkalmazásoknak erre soha nincs szüksége."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"az eszközkezelő használata"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Lehetővé teszi a tulajdonos számára, hogy célokat küldjön egy eszközkezelőnek. A normál alkalmazásoknak erre soha nincs szüksége."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"eszközrendszergazda hozzáadása vagy eltávolítása"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Lehetővé teszi a tulajdonos számára, hogy aktív eszközrendszergazdákat adjon meg vagy távolítson el. A normál alkalmazásoknál erre soha nincs szükség."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"képernyő irányának módosítása"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Lehetővé teszi az alkalmazás számára a képernyő elforgatásának bármikori módosítását. A normál alkalmazásoknak erre soha nincs szüksége."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"mutató sebességének módosítása"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Lehetővé teszi az alkalmazás számára, hogy olvassa a rendszer különböző naplófájljait. Ezáltal általános információkat deríthet ki arról, hogy mire használja a telefonját, valamint személyes, magánjellegű adatokhoz is hozzájuthat."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"bármely médiadekóder használata lejátszáshoz"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Lehetővé teszi egy alkalmazás számára bármely telepített médiadekóder használatát a lejátszás dekódolásához."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"megbízható tanúsítványok kezelése"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Lehetővé teszi az alkalmazás számára a CA tanúsítványok telepítését és eltávolítását."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"a diag tulajdonában lévő erőforrások olvasása és írása"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Lehetővé teszi egy alkalmazás számára, hogy olvassa és írja a diagnosztikai csoport minden erőforrását, például a /dev könyvtárban lévő fájlokat. Ez potenciálisan befolyásolhatja a rendszer stabilitását és biztonságát, ezért CSAK a gyártó vagy a szolgáltató használhatja hardverspecifikus diagnosztizálásra."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"alkalmazáskomponensek be- és kikapcsolása"</string>
@@ -462,6 +479,14 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Lehetővé teszi, hogy az alkalmazás Wi-Fi kijelzőket konfiguráljon, és csatlakozzon hozzájuk."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wi-Fi kijelzők irányítása"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Lehetővé teszi, hogy az alkalmazás irányítsa a Wi-Fi kijelzők alacsonyabb szintű funkcióit."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"audiokimenet rögzítése"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Engedélyezi az alkalmazásnak a hangkimenet rögzítését és átirányítását."</string>
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Hotwordérzékelés"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Lehetővé teszi, hogy alkalmazás rögzítse a befelé jövő hangokat hotwordérzékelés céljából. A rögzítés végbemehet a háttérben, és nem zavarja a más jellegű hangrögzítést, például a kamera esetében."</string>
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"videokimenet rögzítése"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Engedélyezi az alkalmazásnak a videokimenet rögzítését és átirányítását."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"biztonságos videokimenet rögzítése"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Engedélyezi az alkalmazásnak a biztonságos videokimenet rögzítését és átirányítását."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"hangbeállítások módosítása"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Lehetővé teszi az alkalmazás számára az általános hangbeállítások, például a hangerő és a használni kívánt kimeneti hangszóró módosítását."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"hanganyag rögzítése"</string>
@@ -525,6 +550,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"telefon alvó üzemmódjának megakadályozása"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Lehetővé teszi az alkalmazás számára, hogy megakadályozza, hogy a táblagép alvó üzemmódra váltson."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Lehetővé teszi az alkalmazás számára, hogy megakadályozza, hogy a telefon alvó üzemmódra váltson."</string>
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"infravörös érzékelő"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Engedélyezi, hogy az alkalmazás használhassa a táblagép infravörös érzékelőjét."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Engedélyezi, hogy az alkalmazás használhassa a telefon infravörös érzékelőjét."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"a táblagép be- és kikapcsolása"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"a telefon be- és kikapcsolása"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Lehetővé teszi az alkalmazás számára a táblagép be- és kikapcsolását."</string>
@@ -613,6 +641,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Lehetővé teszi az alkalmazás számára, hogy írjon az SD-kártyára."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"belső tár tartalmának módosítása/törlése"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Lehetővé teszi az alkalmazás számára, hogy módosítsa a belső háttértár tartalmát."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"dokumentumtárhely kezelése"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Lehetővé teszi az alkalmazás számára a dokumentumtárhely kezelését."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"hozzáf. minden felh. külső tár"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Minden felhasználó számára lehetővé teszi, hogy az alkalmazás hozzáférjen külső tárolókhoz."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"hozzáférés a gyorsítótár fájlrendszeréhez"</string>
@@ -625,10 +655,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Lehetővé teszi az alkalmazás számára, hogy kezelje a hálózati irányelveket és meghatározza az alkalmazásspecifikus szabályokat."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"hálózathasználat elszámolásának módosítása"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Lehetővé teszi az alkalmazás számára annak módosítását, hogy a hálózathasználatot hogyan számolják el az alkalmazások esetében. Normál alkalmazások nem használhatják."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"szoftvercsatorna-jelölések módosítása"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Lehetővé teszi, hogy az alkalmazás módosítsa az útválasztáshoz használt szoftvercsatorna-jelöléseket"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"hozzáférési értesítések"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Lehetővé teszi, hogy az alkalmazás értesítéseket kérdezzen le, vizsgáljon és tisztítson meg, beleértve az egyéb alkalmazások által közzétett értesítéseket is."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"csatlakozzon értesítésfigyelő szolgáltatáshoz"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Lehetővé teszi a használó számára, hogy csatlakozzon egy értesítésfigyelő szolgáltatás legfelső szintű felületéhez. A normál alkalmazásoknak erre soha nincs szükségük."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"a szolgáltatói konfigurációs alkalmazás hívása"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Lehetővé teszi a használó számára a szolgáltató által biztosított konfigurációs alkalmazás hívását. A normál alkalmazásoknak erre soha nincs szükségük."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"hálózati körülményekkel kapcsolatos észrevételek figyelemmel kísérése"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Lehetővé teszi egy alkalmazás számára, hogy figyelemmel kísérje a hálózati körülményekkel kapcsolatos észrevételeket. A normál alkalmazásoknak erre soha nincs szükségük."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Jelszavakkal kapcsolatos szabályok beállítása"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"A képernyőzár-feloldási jelszavakban engedélyezett karakterek és hosszúság vezérlése."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Képernyőzár-feloldási kísérletek figyelése"</string>
@@ -738,8 +774,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +831,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Helyezzen be egy SIM kártyát."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"A SIM kártya hiányzik vagy nem olvasható. Helyezzen be egy SIM kártyát."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"A SIM kártya nem használható."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"SIM kártyája véglegesen letiltva."\n" Forduljon a vezeték nélküli szolgáltatójához másik SIM kártya beszerzése érdekében."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"SIM kártyája véglegesen letiltva.\n Forduljon a vezeték nélküli szolgáltatójához másik SIM kártya beszerzése érdekében."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Előző szám gomb"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Következő szám gomb"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Szünet gomb"</string>
@@ -808,11 +843,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Nézze meg a felhasználói útmutatót, vagy vegye fel a kapcsolatot az ügyfélszolgálattal."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"A SIM-kártya le van zárva."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM-kártya feloldása..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal rosszul rajzolta le feloldási mintát. "\n\n"Kérjük, <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva próbálja újra."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Ön helytelenül adta meg a jelszót <xliff:g id="NUMBER_0">%d</xliff:g> alkalommal. "\n" "\n" Próbálja újra <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Ön <xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül adta meg PIN kódját. "\n" "\n" Próbálja újra <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Helytelenül rajzolta le a feloldási mintát <xliff:g id="NUMBER_0">%d</xliff:g> alkalommal. További <xliff:g id="NUMBER_1">%d</xliff:g> sikertelen kísérlet után a Google rendszerében használt bejelentkezési adataival kell feloldania a táblagépét."\n\n" Kérjük, próbálja újra <xliff:g id="NUMBER_2">%d</xliff:g> másodperc múlva."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Helytelenül rajzolta le a feloldási mintát <xliff:g id="NUMBER_0">%d</xliff:g> alkalommal. További <xliff:g id="NUMBER_1">%d</xliff:g> sikertelen kísérlet után a Google rendszerében használt bejelentkezési adataival kell feloldania a telefonját."\n\n" Kérjük, próbálja újra <xliff:g id="NUMBER_2">%d</xliff:g> másodperc múlva."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal rosszul rajzolta le feloldási mintát. \n\nKérjük, <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva próbálja újra."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Ön helytelenül adta meg a jelszót <xliff:g id="NUMBER_0">%d</xliff:g> alkalommal. \n \n Próbálja újra <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Ön <xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül adta meg PIN kódját. \n \n Próbálja újra <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Helytelenül rajzolta le a feloldási mintát <xliff:g id="NUMBER_0">%d</xliff:g> alkalommal. További <xliff:g id="NUMBER_1">%d</xliff:g> sikertelen kísérlet után a Google rendszerében használt bejelentkezési adataival kell feloldania a táblagépét.\n\n Kérjük, próbálja újra <xliff:g id="NUMBER_2">%d</xliff:g> másodperc múlva."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Helytelenül rajzolta le a feloldási mintát <xliff:g id="NUMBER_0">%d</xliff:g> alkalommal. További <xliff:g id="NUMBER_1">%d</xliff:g> sikertelen kísérlet után a Google rendszerében használt bejelentkezési adataival kell feloldania a telefonját.\n\n Kérjük, próbálja újra <xliff:g id="NUMBER_2">%d</xliff:g> másodperc múlva."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"A táblagépet <xliff:g id="NUMBER_0">%d</xliff:g> alkalommal próbálta meg sikertelenül feloldani. <xliff:g id="NUMBER_1">%d</xliff:g> további sikertelen próbálkozás után a rendszer visszaállítja a táblagép gyári alapértelmezett beállításait, és minden felhasználói adat elvész."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"A telefont <xliff:g id="NUMBER_0">%d</xliff:g> alkalommal próbálta meg sikertelenül feloldani. <xliff:g id="NUMBER_1">%d</xliff:g> további sikertelen próbálkozás után a rendszer visszaállítja a telefon gyári alapértelmezett beállításait, és minden felhasználói adat elvész."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"A táblagépet <xliff:g id="NUMBER">%d</xliff:g> alkalommal próbálta meg sikertelenül feloldani. A rendszer visszaállítja a táblagép gyári alapértelmezett beállításait."</string>
@@ -826,7 +861,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Jelszó"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Bejelentkezés"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Érvénytelen felhasználónév vagy jelszó."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Elfelejtette a felhasználónevét vagy jelszavát?"\n"Keresse fel a "<b>"google.com/accounts/recovery"</b>" webhelyet."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Elfelejtette a felhasználónevét vagy jelszavát?\nKeresse fel a "<b>"google.com/accounts/recovery"</b>" webhelyet."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Ellenőrzés..."</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Feloldás"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Hang bekapcsolása"</string>
@@ -874,7 +909,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Navigáció megerősítése"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Oldal elhagyása"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Ezen az oldalon maradok"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Biztosan szeretné elhagyni az oldalt?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nBiztosan szeretné elhagyni az oldalt?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Megerősítés"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Tipp: érintse meg kétszer a nagyításhoz és kicsinyítéshez."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Kitöltés"</string>
@@ -1080,14 +1115,14 @@
     <string name="aerr_application" msgid="932628488013092776">"A(z) <xliff:g id="APPLICATION">%1$s</xliff:g> alkalmazás sajnos leállt."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Sajnos a <xliff:g id="PROCESS">%1$s</xliff:g> alkalmazás leállt."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"A(z) <xliff:g id="APPLICATION">%2$s</xliff:g> nem válaszol."\n\n"Szeretné bezárni?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"A(z) <xliff:g id="ACTIVITY">%1$s</xliff:g> tevékenység nem válaszol."\n\n"Szeretné bezárni?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"A(z) <xliff:g id="APPLICATION">%2$s</xliff:g> nem válaszol.\n\nSzeretné bezárni?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"A(z) <xliff:g id="ACTIVITY">%1$s</xliff:g> tevékenység nem válaszol.\n\nSzeretné bezárni?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"A(z) <xliff:g id="APPLICATION">%1$s</xliff:g> alkalmazás nem válaszol. Szeretné bezárni?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"A(z) <xliff:g id="PROCESS">%1$s</xliff:g> folyamat nem válaszol. "\n\n"Szeretné bezárni?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"A(z) <xliff:g id="PROCESS">%1$s</xliff:g> folyamat nem válaszol. \n\nSzeretné bezárni?"</string>
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"Jelentés"</string>
     <string name="wait" msgid="7147118217226317732">"Várakozás"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"Az oldal nem válaszol."\n\n"Szeretné bezárni?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Az oldal nem válaszol.\n\nSzeretné bezárni?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Alkalmazás átirányítva"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> éppen fut."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> volt eredetileg elindítva."</string>
@@ -1256,6 +1291,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Lehetővé teszi az alkalmazás számára az alapértelmezett tárolószolgáltatás használatát tartalom másolásához. Normál alkalmazások nem használhatják."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Médiafájlok kimenetének irányítása"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Lehetővé teszi az alkalmazás számára, hogy más külső eszközökre irányítsa a médiafájlok lejátszását."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Hozzáférés a kóddal védett tárhelyhez"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Lehetővé teszi egy alkalmazás számára, hogy hozzáférjen a kóddal védett tárhelyhez."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Billentyűzár megjelenítésének és elrejtésének vezérlése"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Lehetővé teszi egy alkalmazás számára a billentyűzár vezérlését."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Érintse meg kétszer a nagyítás beállításához"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Nem sikerült hozzáadni a modult."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Ugrás"</string>
@@ -1265,15 +1304,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Kész"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Előző"</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Végrehajtás"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Szám hívása"\n"ezzel: <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Névjegy létrehozása "\n"a(z) <xliff:g id="NUMBER">%s</xliff:g> szám használatával"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Szám hívása\nezzel: <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Névjegy létrehozása \na(z) <xliff:g id="NUMBER">%s</xliff:g> szám használatával"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"A következő egy vagy több alkalmazás hozzáférési engedélyt kér a fiókjához mostanra és a jövőre nézve is."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Engedélyezi ezt a kérelmet?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Hozzáférési kérelem"</string>
     <string name="allow" msgid="7225948811296386551">"Engedélyezés"</string>
     <string name="deny" msgid="2081879885755434506">"Elutasítás"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Az engedélykérés megtörtént"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Az engedélykérés megtörtént"\n"a(z) <xliff:g id="ACCOUNT">%s</xliff:g> fiók számára."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Az engedélykérés megtörtént\na(z) <xliff:g id="ACCOUNT">%s</xliff:g> fiók számára."</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Beviteli mód"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Szinkronizálás"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Kisegítő lehetőségek"</string>
@@ -1420,7 +1459,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Összes megtekintése"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Tevékenység kiválasztása"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Megosztás"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Az eszköz le van zárva."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Küldés…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Böngésző indítása?"</string>
@@ -1441,10 +1479,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Kapcsolódás..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Elérhető"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"Nem érhető el"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"Használatban"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Beépített képernyő"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"HDMI-képernyő"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"<xliff:g id="ID">%1$d</xliff:g>. fedvény"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> képpont"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", biztonságos"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Vezeték nélküli kijelző csatlakoztatva"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Ez a kijelző megjelenítést végez egy másik eszközön"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Szétkapcsol"</string>
@@ -1453,7 +1493,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Helytelen minta"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Helytelen jelszó"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"Helytelen PIN kód"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Próbálkozzon újra <xliff:g id="NUMBER">%d</xliff:g> másodperc múlva."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Próbálkozzon újra <xliff:g id="NUMBER">%1$d</xliff:g> másodperc múlva."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Rajzolja le a mintát"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Adja meg a SIM kártya PIN kódját"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Adja meg a PIN kódot"</string>
@@ -1473,27 +1513,85 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Jelszó"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Bejelentkezés"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Érvénytelen felhasználónév vagy jelszó."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Elfelejtette a felhasználónevét vagy jelszavát?"\n"Keresse fel a "<b>"google.com/accounts/recovery"</b>" webhelyet."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Elfelejtette a felhasználónevét vagy jelszavát?\nKeresse fel a "<b>"google.com/accounts/recovery"</b>" webhelyet."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Fiók ellenőrzése..."</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül adta meg PIN kódját. "\n\n"Próbálja újra <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül adta meg a jelszót. "\n\n" Próbálja újra <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal rosszul rajzolta le feloldási mintát. "\n\n"Próbálja újra <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül adta meg PIN kódját. \n\nPróbálja újra <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül adta meg a jelszót. \n\n Próbálja újra <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal rosszul rajzolta le feloldási mintát. \n\nPróbálja újra <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"A táblagépet <xliff:g id="NUMBER_0">%d</xliff:g> alkalommal próbálta meg sikertelenül feloldani. <xliff:g id="NUMBER_1">%d</xliff:g> további sikertelen próbálkozás után a rendszer visszaállítja a táblagép gyári alapértelmezett beállításait, és minden felhasználói adat elvész."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"A telefont <xliff:g id="NUMBER_0">%d</xliff:g> alkalommal próbálta meg sikertelenül feloldani. <xliff:g id="NUMBER_1">%d</xliff:g> további sikertelen próbálkozás után a rendszer visszaállítja a telefon gyári alapértelmezett beállításait, és minden felhasználói adat elvész."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"A táblagépet <xliff:g id="NUMBER">%d</xliff:g> alkalommal próbálta meg sikertelenül feloldani. A rendszer visszaállítja a táblagép gyári alapértelmezett beállításait."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"A telefont <xliff:g id="NUMBER">%d</xliff:g> alkalommal próbálta meg sikertelenül feloldani. A rendszer visszaállítja a telefon gyári alapértelmezett beállításait."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül rajzolta le a feloldási mintát. További <xliff:g id="NUMBER_1">%d</xliff:g> sikertelen kísérlet után egy e-mail fiók használatával kell feloldania a táblagépét."\n\n" Kérjük, próbálja újra <xliff:g id="NUMBER_2">%d</xliff:g> másodperc múlva."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül rajzolta le a feloldási mintát. További <xliff:g id="NUMBER_1">%d</xliff:g> sikertelen kísérlet után egy e-mail fiók használatával kell feloldania a telefonját."\n\n" Kérjük, próbálja újra <xliff:g id="NUMBER_2">%d</xliff:g> másodperc múlva."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül rajzolta le a feloldási mintát. További <xliff:g id="NUMBER_1">%d</xliff:g> sikertelen kísérlet után egy e-mail fiók használatával kell feloldania a táblagépét.\n\n Kérjük, próbálja újra <xliff:g id="NUMBER_2">%d</xliff:g> másodperc múlva."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül rajzolta le a feloldási mintát. További <xliff:g id="NUMBER_1">%d</xliff:g> sikertelen kísérlet után egy e-mail fiók használatával kell feloldania a telefonját.\n\n Kérjük, próbálja újra <xliff:g id="NUMBER_2">%d</xliff:g> másodperc múlva."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Eltávolítás"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"A javasolt szint fölé emeli a hangerőt?"\n"Ha hosszú ideig hangosan hallgatja a zenét, az károsíthatja a hallását."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"A javasolt szint fölé emeli a hangerőt?\nHa hosszú ideig hangosan hallgatja a zenét, az károsíthatja a hallását."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Továbbra is tartsa lenyomva két ujját a hozzáférés engedélyezéséhez."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Hozzáférés engedélyezve"</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Hozzáférés megszakítva."</string>
     <string name="user_switched" msgid="3768006783166984410">"<xliff:g id="NAME">%1$s</xliff:g> az aktuális felhasználó."</string>
     <string name="owner_name" msgid="2716755460376028154">"Tulajdonos"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Hiba"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Ez az alkalmazás nem támogatja a korlátozott profilokkal rendelkező fiókokat"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Ez az alkalmazás nem támogatja a korlátozott profilokkal rendelkező fiókokat"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Nincs megfelelő alkalmazás a művelet elvégzésére."</string>
     <string name="revoke" msgid="5404479185228271586">"Visszavonás"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"„Letter” méret"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"„Government Letter” méret"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"„Legal” méret"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"„Junior Legal\" méret"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"„Ledger” méret"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"„Tabloid” méret"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Törölve"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Hiba történt a tartalomírás közben"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"ismeretlen"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Rendszergazdai PIN kód megadása"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN kód megadása"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Helytelen"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Jelenlegi PIN kód"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Új PIN kód"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Új PIN kód megerősítése"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"PIN kód létrehozása a korlátozások módosításához"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"A PIN kódok nem egyeznek. Próbálja újra."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"A PIN kód túl rövid. Legalább 4 számjegyből kell állnia."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Próbálja újra 1 másodperc múlva"</item>
+    <item quantity="other" msgid="4730868920742952817">"Próbálja újra <xliff:g id="COUNT">%d</xliff:g> másodperc múlva"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Próbálkozzon később"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Csúsztatás a képernyő szélén a sávhoz"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Csúsztassa ujját a képernyő szélétől a rendszersáv megjelenítéséhez"</string>
 </resources>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
new file mode 100644
index 0000000..d3b8762
--- /dev/null
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -0,0 +1,1602 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<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">"Բ"</string>
+    <string name="kilobyteShort" msgid="5973789783504771878">"Կբ"</string>
+    <string name="megabyteShort" msgid="6355851576770428922">"Մբ"</string>
+    <string name="gigabyteShort" msgid="3259882455212193214">"Գբ"</string>
+    <string name="terabyteShort" msgid="231613018159186962">"Տբ"</string>
+    <string name="petabyteShort" msgid="5637816680144990219">"Պբ"</string>
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
+    <string name="untitled" msgid="4638956954852782576">"&lt;Անանուն&gt;"</string>
+    <string name="ellipsis" msgid="7899829516048813237">"…"</string>
+    <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
+    <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Հեռախոսահամար չկա)"</string>
+    <string name="unknownName" msgid="2277556546742746522">"(Անհայտ)"</string>
+    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Ձայնային փոստ"</string>
+    <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
+    <string name="mmiError" msgid="5154499457739052907">"Միացման խնդիր կամ անվավեր MMI ծածակագիր:"</string>
+    <string name="mmiFdnError" msgid="5224398216385316471">"Գործողությունը սահմանափակված է միայն ամրակայված հեռախոսահամարների համար:"</string>
+    <string name="serviceEnabled" msgid="8147278346414714315">"Ծառայությունը միացված է:"</string>
+    <string name="serviceEnabledFor" msgid="6856228140453471041">"Ծառայությունը միացված է`"</string>
+    <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="mmiComplete" msgid="8232527495411698359">"MMI-ը ավարտված է:"</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>
+    <string name="invalidPuk" msgid="8761456210898036513">"Մուտքագրեք PUK, որն 8 կամ ավել թիվ ունի:"</string>
+    <string name="needPuk" msgid="919668385956251611">"Ձեր SIM քարտը PUK-ով կողպված է: Մուտքագրեք PUK կոդը այն ապակողպելու համար:"</string>
+    <string name="needPuk2" msgid="4526033371987193070">"Մուտքագրեք PUK2-ը` SIM քարտն արգելաբացելու համար:"</string>
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
+    <string name="ClipMmi" msgid="6952821216480289285">"Մուտքային զանգողի ID"</string>
+    <string name="ClirMmi" msgid="7784673673446833091">"Ելքային զանգողի ID"</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">"PIN-ի փոփոխություն"</string>
+    <string name="CnipMmi" msgid="3110534680557857162">"Զանգող համարը առկա է"</string>
+    <string name="CnirMmi" msgid="3062102121430548731">"Զանգող հեռախոսահամարը սահմանափակված է"</string>
+    <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="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="RestrictedChangedTitle" msgid="5592189398956187498">"Սահմանափակված մուտքը փոխված է"</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="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>
+    <string name="serviceClassDataSync" msgid="7530000519646054776">"Համաժամել"</string>
+    <string name="serviceClassPacket" msgid="6991006557993423453">"Փաթեթ"</string>
+    <string name="serviceClassPAD" msgid="3235259085648271037">"Հարթակ"</string>
+    <string name="roamingText0" msgid="7170335472198694945">"Ռոումինգի ցուցիչը միացված է"</string>
+    <string name="roamingText1" msgid="5314861519752538922">"Ռոումինգի ցուցիչը անջատված է"</string>
+    <string name="roamingText2" msgid="8969929049081268115">"Ռոումինգի ցուցիչը թարթում է"</string>
+    <string name="roamingText3" msgid="5148255027043943317">"Շրջակայքից դուրս"</string>
+    <string name="roamingText4" msgid="8808456682550796530">"Շենքից դուրս"</string>
+    <string name="roamingText5" msgid="7604063252850354350">"Ռոումինգ` նախընտրելի համակարգ"</string>
+    <string name="roamingText6" msgid="2059440825782871513">"Ռոումինգ` հասանելի համակարգ"</string>
+    <string name="roamingText7" msgid="7112078724097233605">"Ռոումինգ` դաշնային գործընկեր"</string>
+    <string name="roamingText8" msgid="5989569778604089291">"Ռոումինգ` առաջնակարգ գործընկեր"</string>
+    <string name="roamingText9" msgid="7969296811355152491">"Ռոումինգ` լիարժեք ծառայության գործառություն"</string>
+    <string name="roamingText10" msgid="3992906999815316417">"Ռոումինգ` Մասնակի ծառայության գործառություն"</string>
+    <string name="roamingText11" msgid="4154476854426920970">"Ռոումինգի ազդերիզը միացված է"</string>
+    <string name="roamingText12" msgid="1189071119992726320">"Ռոումինգի ազդերիզն անջատված է"</string>
+    <string name="roamingTextSearching" msgid="8360141885972279963">"Ծառայության որոնում..."</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="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="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="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="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="default" msgid="3475999286680000541">"Հեռախոսի պահոցը լիքն է: Ջնջեք մի քանի ֆայլեր` տարածություն ազատելու համար:"</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Ցանցը կարող է վերահսկվել"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
+    <string name="me" msgid="6545696007631404292">"Իմ"</string>
+    <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Գրասալիկի ընտրանքները"</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="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="shutdown_progress" msgid="2281079257329981203">"Անջատվում է…"</string>
+    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Ձեր գրասալիկը կանջատվի:"</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="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_bug_report" msgid="7934010578922304799">"Վրիպակի զեկույց"</string>
+    <string name="bugreport_title" msgid="2667494803742548533">"Գրել սխալի զեկույց"</string>
+    <string name="bugreport_message" msgid="398447048750350456">"Սա տեղեկություններ կհավաքագրի ձեր սարքի առկա կարգավիճակի մասին և կուղարկի այն էլեկտրոնային նամակով: Որոշակի ժամանակ կպահանջվի վրիպակի մասին զեկուցելու պահից սկսած մինչ ուղարկելը: Խնդրում ենք փոքր-ինչ համբերատար լինել:"</string>
+    <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_airplane_mode_on_status" msgid="2719557982608919750">"Ինքնաթիռային ռեժիմը միացված է"</string>
+    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Ինքնաթիռային ռեժիմը անջատված է"</string>
+    <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
+    <string name="safeMode" msgid="2788228061547930246">"Անվտանգ ռեժիմ"</string>
+    <string name="android_system_label" msgid="6577375335728551336">"Android համակարգ"</string>
+    <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Ծառայություններ, որոնց համար կգանձվեք"</string>
+    <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Կատարել գործողություններ, որի դիմաց ձեր հաշվից գումար կծախսվի:"</string>
+    <string name="permgrouplab_messages" msgid="7521249148445456662">"Ձեր հաղորդագրությունները"</string>
+    <string name="permgroupdesc_messages" msgid="7821999071003699236">"Կարդալ և գրել ձեր SMS-ը, նամակը և այլ հաղորդագրություններ:"</string>
+    <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Ձեր անձնական տեղեկությունները"</string>
+    <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"Ուղղակի մուտք ձեր մասին տեղեկություններ` պահված ձեր կոնտակտային քարտում:"</string>
+    <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Ձեր սոցիալական տեղեկությունները"</string>
+    <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Ուղղակի մուտք ձեր կոնտակտների մասին տեղեկություններ և սոցիալական կապեր:"</string>
+    <string name="permgrouplab_location" msgid="635149742436692049">"Ձեր տեղադրությունը"</string>
+    <string name="permgroupdesc_location" msgid="5704679763124170100">"Վերահսկել ձեր ֆիզիկական տեղադրությունը:"</string>
+    <string name="permgrouplab_network" msgid="5808983377727109831">"Ցանցային հաղորդակցություն"</string>
+    <string name="permgroupdesc_network" msgid="4478299413241861987">"Մուտք գործել ցանցի տարբեր գործառույթներ:"</string>
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"Bluetooth"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"Մուտք գործել սարքեր և ցանցեր Bluetooth-ի միջոցով:"</string>
+    <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"Ձայնանյութի կարգավորումներ"</string>
+    <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"Փոխել ձայնանյութի կարգավորումները:"</string>
+    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Ազդում է մարտկոցի վրա"</string>
+    <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Օգտագործել գործիքները, որոնք կարող են արագ սպառել մարտկոցը:"</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"Օրացույց"</string>
+    <string name="permgroupdesc_calendar" msgid="5777534316982184416">"Անմիջական մուտք օրացույց և իրադարձություններ:"</string>
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"Կարդալ օգտվողի բառարանը"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"Կարդալ բառերը օգտվողի բառարանում:"</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"Գրել օգտվողի բառարանում"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"Ավելացնել բառեր օգտվողի բառարանում:"</string>
+    <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Էջանիշեր և պատմություն"</string>
+    <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Ուղղակի մուտք դեպի էջանիշեր և դիտարկչի պատմություն:"</string>
+    <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"Ազդանշան"</string>
+    <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"Կարգավորել զարթուցիչի ժամացույցը:"</string>
+    <string name="permgrouplab_voicemail" msgid="4162237145027592133">"Ձայնային փոստ"</string>
+    <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"Ուղղակի մուտք դեպի ձայնային փոստ:"</string>
+    <string name="permgrouplab_microphone" msgid="171539900250043464">"Բարձրախոս"</string>
+    <string name="permgroupdesc_microphone" msgid="7106618286905738408">"Ուղղակի մուտք դեպի բարձրախոս` ձայնանյութ ձայնագրելու համար:"</string>
+    <string name="permgrouplab_camera" msgid="4820372495894586615">"Ֆոտոխցիկ"</string>
+    <string name="permgroupdesc_camera" msgid="2933667372289567714">"Ուղղակի մուտք դեպի ֆոտոխցիկ` լուսանկարելու կամ տեսանկարելու համար:"</string>
+    <string name="permgrouplab_screenlock" msgid="8275500173330718168">"Կողպել էկրանը"</string>
+    <string name="permgroupdesc_screenlock" msgid="7067497128925499401">"Հնարավորություն ունի ազդելու ձեր սարքի կողպէկրանի ռեժիմի վրա:"</string>
+    <string name="permgrouplab_appInfo" msgid="8028789762634147725">"Ձեր հավելվածների տեղեկությունները"</string>
+    <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"Հնարավորություն` ազդելու մյուս հավելվածների վարքագծի վրա ձեր սարքում:"</string>
+    <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"Պաստառ"</string>
+    <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"Փոխել սարքի պաստառի կարգավորումները:"</string>
+    <string name="permgrouplab_systemClock" msgid="406535759236612992">"Ժամացույց"</string>
+    <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"Փոխել սարքի ժամը կամ ժամային գոտին:"</string>
+    <string name="permgrouplab_statusBar" msgid="2095862568113945398">"Կարգավիճակի գոտի"</string>
+    <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"Փոխել սարքի կարգավիճակի գոտու կարգավորումները:"</string>
+    <string name="permgrouplab_syncSettings" msgid="3341990986147826541">"Համաժամեցման կարգավորումներ"</string>
+    <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"Մուտք գործել համաժամեցման կարգավորումներ:"</string>
+    <string name="permgrouplab_accounts" msgid="3359646291125325519">"Ձեր հաշիվները"</string>
+    <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Մուտքի հնարավորություն առկա հաշիվներ:"</string>
+    <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Սարքաշարի կարգավորումներ"</string>
+    <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Անմիջական մուտք հեռախոսի սարքաշար:"</string>
+    <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Հեռախոսային զանգերը"</string>
+    <string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"Վերահսկել, ձայնագրելել և կատարել հեռախոսազանգեր:"</string>
+    <string name="permgrouplab_systemTools" msgid="4652191644082714048">"Համակարգի գործիքները"</string>
+    <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"Համակարգի ավելի ցածր մակարդակի մատչում և վերահսկողություն:"</string>
+    <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"Ծրագրավորման գործիքներ"</string>
+    <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"Գործառույթներ, որ անհրաժեշտ են միայն հավելվածների ծրագրավորողներին:"</string>
+    <string name="permgrouplab_display" msgid="4279909676036402636">"Այլ հավելվածի UI"</string>
+    <string name="permgroupdesc_display" msgid="6051002031933013714">"Ազդել այլ հավելվածների UI-ներին:"</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"Պահոց"</string>
+    <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Մուտք գործել USB պահոց:"</string>
+    <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Մուտք գործել SD քարտ:"</string>
+    <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"Մատչելիության գործիքներ"</string>
+    <string name="permgroupdesc_accessibilityFeatures" msgid="4205196881678144335">"Հատկություններ, որ օժանդակող տեխնոլոգիան կարող է հայցել:"</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="5800552516779249356">"Տարրերը, որոնց հպեք, բարձրաձայն կխոսեն, և էկրանը հնարավոր կլինի ուսումնասիրել ժեստերով:"</string>
+    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Միացնել ընդլայնված վեբ մատչելիությունը"</string>
+    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Հնարավոր է սկրիպտներ տեղադրվեն` ծրագրի բովանդակությունն ավելի մատչելի դարձնելու համար:"</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Զննել ձեր մուտքագրած տեքստը"</string>
+    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Ներառում է անձնական տվյալներ, ինչպիսիք են վարկային քարտերի համարները և գաղտնաբառերը:"</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"անջատել կամ փոփոխել կարգավիճակի գոտին"</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"Թույլ է տալիս հավելվածին անջատել կարգավիճակի գոտին կամ ավելացնել ու հեռացնել համակարգի պատկերակները:"</string>
+    <string name="permlab_statusBarService" msgid="7247281911387931485">"կարգավիճակի գոտի"</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_processOutgoingCalls" msgid="3906007831192990946">"վերաուղղել ելքային զանգերը"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Թույլ է տալիս հավելվածին մշակել ելքային զանգերը և փոխել համարհավաքումը: Վնասարար հավելվածները կարող են վերահսկել, վերահասցեավորել կամ կանխել ելքային զանգերը:"</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_receiveEmergencyBroadcast" msgid="1803477660846288089">"ստանալ արտակարգ իրավիճակների հաղորդումներ"</string>
+    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Թույլ է տալիս հավելվածին ստանալ և մշակել ծանուցվող արտակարգ հաղորդակցությունները: Այս թույլտվությունը հասանելի է միայն համակարգային ծրագրերին:"</string>
+    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"կարդալ բջջային զեկուցվող հաղորդագրությունները"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Թույլ է տալիս հավելվածին կարդալ ձեր սարքի կողմից ստացված բջջային հեռարձակվող հաղորդագրությունները: Բջջային հեռարձակվող զգուշացումները ուղարկվում են որոշ վայրերում` արտակարգ իրավիճակների մասին ձեզ զգուշացնելու համար: Վնասարար հավելվածները կարող են խանգարել ձեր սարքի արդյունավետությանը կամ շահագործմանը, երբ ստացվում է արտակարգ իրավիճակի մասին բջջային հաղորդում:"</string>
+    <string name="permlab_sendSms" msgid="5600830612147671529">"ուղարկել SMS հաղորդագրություններ"</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"Թույլ է տալիս հավելվածին ուղարկել SMS հաղորդագրություններ: Այն կարող է անսպասելի ծախսերի պատճառ դառնալ: Վնասարար հավելվածները կարող են ձեր հաշվից գումար ծախսել` ուղարկելով հաղորդագրություններ`  առանց ձեր հաստատման:"</string>
+    <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"պատասխանել հաղորդագրության միջոցով իրադարձություններ ուղարկել"</string>
+    <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"Թույլ է տալիս հավելվածին հարցումներ ուղարկել այլ հաղորդագրությունների հավելվածներին` կառավարելու մուտքային զանգերին հաղորդագրության միջոցով պատասխանելու դեպքերը:"</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"կարդալ ձեր տեքստային հաղորդագրությունները (SMS կամ MMS)"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Թույլ է տալիս հավելվածին կարդալ ձեր գրասալիկում կամ SIM քարտում պահված SMS հաղորդագրությունները: Սա թույլ է տալիս հավելվածին կարդալ բոլոր SMS հաղորդագրությունները` անկախ բովանդակությունից կամ գաղտնիությունից:"</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Թույլ է տալիս հավելվածին կարդալ ձեր հեռախոսում կամ SIM քարտում պահված SMS հաղորդագրությունները: Սա թույլ է տալիս հավելվածին կարդալ բոլոր SMS հաղորդագրությունները` անկախ բովանդակությունից կամ գաղտնիությունից:"</string>
+    <string name="permlab_writeSms" msgid="3216950472636214774">"խմբագրել ձեր տեքստային հաղորդագրությունները (SMS կամ MMS)"</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Թույլ է տալիս հավելվածին պատասխանել ձեր գրասալիկում կամ SIM քարտում պահված SMS հաղորդագրություններին: Վնասարար հավելվածները կարող են ջնջել ձեր հաղորդագրությունները:"</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Թույլ է տալիս հավելվածին պատասխանել ձեր հեռախոսում կամ SIM քարտում պահված 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_interactAcrossUsers" msgid="7114255281944211682">"հաղորդակցվել օգտվողների միջև"</string>
+    <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Թույլ է տալիս հավելվածին իրականացնել գործողություններ սարքի տարբեր օգտվողների միջոցով: Վնասարար հավելվածները կարող են օգտագործել սա` խախտելու օգտվողների միջև պաշտպանությունը:"</string>
+    <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"ամբողջական հաղորդակցվելու արտոնություն օգտվողների միջև"</string>
+    <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Թույլ է տալիս բոլոր հնարավոր հաղորդակցության եղանակները օգտվողների միջև:"</string>
+    <string name="permlab_manageUsers" msgid="1676150911672282428">"կառավարել օգտվողներին"</string>
+    <string name="permdesc_manageUsers" msgid="8409306667645355638">"Թույլ է տալիս հավելվածներին կառավարել սարքի օգտագործողներին, այդ թվում` հարցումները, ստեղծումն ու ջնջումը:"</string>
+    <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"առբերել աշխատող հավելվածների մանրամասները"</string>
+    <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Թույլ է տալիս հավելվածին առբերել մանրամասն տեղեկություններ առկա և վերջերս աշխատող առաջադրանքների մասին: Վնասարար հավելվածները կարող են հայտնաբերել անձնական տեղեկություններ այլ հավելվածների վերաբերյալ:"</string>
+    <string name="permlab_reorderTasks" msgid="2018575526934422779">"վերադասավորել աշխատող հավելվածները"</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Թույլ է տալիս հավելվածին փոխանցել առաջադրանքները առջևք և հետնաշերտ: Հավելվածը կարող է սա անել առանց ձեր ներածման:"</string>
+    <string name="permlab_removeTasks" msgid="6821513401870377403">"դադարեցնել հավելվածների աշխատանքը"</string>
+    <string name="permdesc_removeTasks" msgid="1394714352062635493">"Թույլ է տալիս հավելվածին հեռացնել առաջադրաքները և վերացնել դրանց հավելվածները: Վնասարար հավելվածները կարող են խանգարել այլ հավելվածների գործունեությանը:"</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"կառավարել գործունեության կույտերը"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Թույլ է տալիս ծրագրին ավելացնել, հեռացնել և փոփոխել գործունեության կույտերը, որոնցում աշխատում են այլ ծրագրեր: Վնասակար ծրագրերը կարող են խաթարել այլ ծրագրերի վարքագիծը:"</string>
+    <string name="permlab_startAnyActivity" msgid="2918768238045206456">"մեկնարկել ցանկացած գործունեություն"</string>
+    <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Թույլ է տալիս հավելվածին մեկնարկել ցանկացած գործունեություն` անկախ թույլտվության պաշտպանվածությունից կամ արտահանման կարգավիճակից:"</string>
+    <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"կարգավորել էկրանի համատեղելիությունը"</string>
+    <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Թույլ է տալիս հավելվածին վերահսկել այլ հավելվածների էկրանի համատեղելիության ռեժիմը: Վնասարար հավելվածները կարող են խաթարել այլ հավելվածների վարքագիծը:"</string>
+    <string name="permlab_setDebugApp" msgid="3022107198686584052">"միացնել հավելվածի վրիպազերծումը"</string>
+    <string name="permdesc_setDebugApp" msgid="4474512416299013256">"Թույլ է տալիս հավելվածին միացնել վրիպազերծումը այլ հավելվածի համար: Վնասարար հավելվածները կարող են օգտագործել սա` մյուս հավելվածները վերացնելու համար:"</string>
+    <string name="permlab_changeConfiguration" msgid="4162092185124234480">"փոխել համակարգի ցուցադրման կարգավորումները"</string>
+    <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"Թույլ է տալիս հավելվածին փոխել առկա կարգավորումը, ինչպես օրինակ տեղույթի կամ ընդհանուր տառաչափը:"</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_forceStopPackages" msgid="2329627428832067700">"ստիպել դադարեցնել այլ հավելվածները"</string>
+    <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"Թույլ է տալիս հավելվածին ստիպողաբար դադարեցնել այլ հավելվածները:"</string>
+    <string name="permlab_forceBack" msgid="652935204072584616">"ստիպել, որ հավելվածը փակվի"</string>
+    <string name="permdesc_forceBack" msgid="3892295830419513623">"Թույլ է տալիս հավելվածին ստիպել որևէ գործունեություն, որը գտնվում է առջևքում, փակել ու ետ գնալ: Սովորական հավելվածների համար երբևէ  անհրաժեշտ չպետք է լինի:"</string>
+    <string name="permlab_dump" msgid="1681799862438954752">"առբերել համակարգի ներքին կարգավիճակը"</string>
+    <string name="permdesc_dump" msgid="1778299088692290329">"Թույլ է տալիս հավելվածին առբերել համակարգի ներքին կարգավիճակը: Վնասարար հավելվածները կարող են առբերել բազմաթիվ անձնական և ապահով տեղեկություններ, որոնք երբեք սովորաբար անհրաժեշտ չեն:"</string>
+    <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"առբերել էկրանի բովանդակությունը"</string>
+    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Թույլ է տալիս հավելվածին առբերել ակտիվ պատուհանի պարունակությունը: Վնասարար հավելվածները կարող են առբերել պատուհանի լրիվ պարունակությունը և հետազոտել դրա ամբողջ տեքստը` բացառությամբ գաղտնաբառերի:"</string>
+    <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"ժամանակավոր միացնել մուտքի հնարավորությունը"</string>
+    <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"Թույլ է տալիս հավելվածին ժամանակավորապես մուտքի հնարավորություն տալ սարքին: Վնասարար հավելվածները կարող են մուտքի հնարավորություն ընձեռել առանց օգտվողի համաձայնության:"</string>
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"առբերել պատուհանի տեղեկություները"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Թույլ է տալիս հավելվածին առբերել պատուհանների մասին տեղեկատվություններ  պատուհանի կառավարչից: Վնասարար հավելվածները կարող են առբերել տեղեկություններ, որը նախատեսված է ներքին համակարգի օգտագործման համար:"</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"զտել իրադարձությունները"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Թույլ է տալիս հավելվածին գրանցել մուտքագրման զտիչ, որը զտում է օգտվողի իրադարձությունների ամբողջ հոսքը` նախքան դրանք կուղարկվեն: Վնասարար հավելվածը կարող է կառավարել համակարգի UI-ը` առանց ձեր միջամտության:"</string>
+    <string name="permlab_magnify_display" msgid="5973626738170618775">"խոշորացնել ցուցադրիչը"</string>
+    <string name="permdesc_magnify_display" msgid="7121235684515003792">"Թույլ է տալիս հավելվածին խոշորացնել ցուցադրիչի բովանդակությունը: Վնասարար հավելվածները կարող են փոխակերպել ցուցադրիչի բովանդակությունը այնպես, որ սարքը դառնա անպիտան:"</string>
+    <string name="permlab_shutdown" msgid="7185747824038909016">"մասնակի անջատում"</string>
+    <string name="permdesc_shutdown" msgid="7046500838746291775">"Դնում է գործունեության կառավարչին անջատման կարգավիճակի մեջ: Չի իրականացնում ամբողջական անջատում:"</string>
+    <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"կանխել ծրագրի փոխարկումները"</string>
+    <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Կանխում է օգտվողի անցումը այլ հավելվածի:"</string>
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"ստանալ ընթացիկ հավելվածի մասին տեղեկություններ"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Թույլ է տալիս սեփականատիրոջը առբերել գաղտնի տեղեկություններ ընթացիկ հավելվածի մասին էկրանի առաջին պլանում:"</string>
+    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"վերահսկել և կառավարել բոլոր հավելվածների թողարկումը"</string>
+    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Թույլ է տալիս հավելվածին հետևել և վերահսկել, թե ինչպես է համակարգը գործարկում գործողությունները: Վնասարար հավելվածները կարող են ամբողջությամբ վնասել համակարգը: Այս թույլտվությունը անհրաժեշտ է միայն ծրագրավորման համար և ոչ երբեք սովորական օգտագործման համար:"</string>
+    <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"ուղարկել հեռացված փաթեթի մասին հաղորդում"</string>
+    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"Թույլ է տալիս հավելվածին հաղորդել ծանուցում, որ հեռացվել է հավելվածի փաթեթ: Վնասարար հավելվածները կարող են օգտագործել սա ցանկացած այլ աշխատող հավելված սպանելու համար:"</string>
+    <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"ուղարկել ստացված SMS-ի հաղորդում"</string>
+    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"Թույլ է տալիս հավելվածին հաղորդել ծանուցում, որ ստացվել է SMS հաղորդագրություն: Վնասարար հավելվածները կարող են օգտագործել սա` կեղծելու մուտքային SMS հաղորդագրությունները:"</string>
+    <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"ուղարկել ստացված WAP-PUSH-ի  հաղորդում"</string>
+    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"Թույլ է տալիս հավելվածին հաղորդել ծանուցում, որ ստացվել է WAP PUSH հաղորդագրություն: Վնասարար հավելվածները կարող են օգտագործել սա` կեղծելու MMS հաղորդագրության ստացումը կամ աննկատ փոխարինելու ցանկացած կայքի բովանդակությունը վնասարար տարբերակներով:"</string>
+    <string name="permlab_setProcessLimit" msgid="2451873664363662666">"սահմանափակել աշխատող գործընթացների թիվը"</string>
+    <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"Թույլ է տալիս հավելվածին վերահսկել գործընթացների առավելագույն թիվը, որ աշխատելու են: Երբևէ անհրաժեշտ չէ սովորական հավելվածների համար:"</string>
+    <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"ստիպել, որ առաջին պլանի հավելվածները փակվեն"</string>
+    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"Թույլ է տալիս հավելվածին վերահսկել արդյոք գործողությունները միշտ ավարտված են, երբ գնում են հետին պլան: Երբևէ անհրաժեշտ չէ սովորական հավելվածների համար:"</string>
+    <string name="permlab_batteryStats" msgid="2789610673514103364">"կարդալ մարտկոցի կարգավիճակը"</string>
+    <string name="permdesc_batteryStats" msgid="5897346582882915114">"Թույլ է տալիս հավելվածին կարդալ ընթացիկ ցածր մակարդակի մարտկոցի օգտագործման տվյալները: Կարող է թույլ տալ հավելվածին պարզել մանրամասն տեղեկություններ, թե որ հավելվածներն եք օգտագործում:"</string>
+    <string name="permlab_updateBatteryStats" msgid="3719689764536379557">"փոփոխել մարտկոցի վիճակագրությունը"</string>
+    <string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"Թույլ է տալիս հավելվածին փոփոխել մարտկոցի հավաքագրված վիճակագրությունը: Սովորական հավելվածների օգտագործման համար չէ:"</string>
+    <string name="permlab_getAppOpsStats" msgid="1508779687436585744">"առբերել ծրագրի ops վիճակագրությունը"</string>
+    <string name="permdesc_getAppOpsStats" msgid="6243887041577912877">"Թույլ է տալիս հավելվածին առբերել հավելվածի հավաքագրված գործողության կարգավիճակը: Սովորական հավելվածների օգտագործման համար չէ:"</string>
+    <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"փոփոխել ծրագրի գործողությունների վիճակագրությունը"</string>
+    <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"Թույլ է տալիս հավելվածին փոփոխել գործողությունների հավաքագրված վիճակագրությունը: Սովորական հավելվածների օգտագործման համար չէ:"</string>
+    <string name="permlab_backup" msgid="470013022865453920">"հսկել համակարգի պահուստավորումը և վերականգնումը"</string>
+    <string name="permdesc_backup" msgid="6912230525140589891">"Թույլ է տալիս հավելվածին վերահսկել համակարգի պահուստավորման և վերականգնման մեխանիզմը: Սովորական հավելվածների կողմից օգտագործման համար չէ:"</string>
+    <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"հաստատել ամբողջական պահուստավորման կամ վերականգնման գործողությունը"</string>
+    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"Թույլ է տալիս հավելվածին գործարկել ամբողջական պահուստավորման հաստատման UI-ը: Որևէ հավելվածի կողմից օգտագործման համար չէ:"</string>
+    <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"ցուցադրել չարտոնված պատուհանները"</string>
+    <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"Թույլ է տալիս հավելվածին ստեղծել պատուհաններ, որոնք նախատեսված են ներքին համակարգի օգտվողի ինտերֆեյսի օգտագործման համար: Սովորական հավելվածների օգտագործման համար չէ:"</string>
+    <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"անցնել այլ ծրագրերի վրայով"</string>
+    <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"Թույլ է տալիս հավելվածին երևալ այլ հավելվածների վերևում կամ օգտվողի ինտերֆեյսի մասերում: Դրանք կարող են խոչընդոտել ձեր ինտերֆեյսի օգտագործմանը ցանկացած հավելվածում կամ փոխել այն, ինչը կարծում եք, որ տեսնում եք այլ հավելվածներում:"</string>
+    <string name="permlab_setAnimationScale" msgid="2805103241153907174">"փոփոխել համաշխարհային անիմացիոն արագությունը"</string>
+    <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"Թույլ է տալիս հավելվածին փոխել համաշխարհային անիմացիոն արագությունը (ավելի արագ կամ դանդաղ անիմացիաներ) ցանկացած ժամանակ:"</string>
+    <string name="permlab_manageAppTokens" msgid="1286505717050121370">"կառավարել ծրագրի այլանիշերը"</string>
+    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"Թույլ է տալիս հավելվածին ստեղծել և կառավարել իրենց սեփական նշանները` շրջանցելով իրենց սովորական Z հերթականությունը: Սովորական հավելվածների համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+    <string name="permlab_freezeScreen" msgid="4708181184441880175">"սառեցնել էկրանը"</string>
+    <string name="permdesc_freezeScreen" msgid="8558923789222670064">"Թույլ է տալիս հավելվածին ժամանակավորապես սառեցնել էկրանը` լրիվ էկրանին անցնելու համար:"</string>
+    <string name="permlab_injectEvents" msgid="1378746584023586600">"սեղմել ստեղները և կառավարման կոճակները"</string>
+    <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"Թույլ է տալիս հավելվածին տրամադրել իր սեփական մուտքագրված իրադարձություններն (ստեղների սեղմումներ և այլն) այլ հավելվածներին: Վնասարար հավելվածները կարող են սա օգտագործել գրասալիկի աշխատանքին միջամտելու համար:"</string>
+    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"Թույլ է տալիս հավելվածին առաքել իր սեփական ներածման իրադարձությունները (ստեղնի սեղմումներ և այլն) այլ հավելվածներին: Վնասարար հավելվածները կարող են սա օգտագործել գրասալիկը վնասելու համար:"</string>
+    <string name="permlab_readInputState" msgid="469428900041249234">"գրառել ձեր մուտքագրումները և գործողությունները"</string>
+    <string name="permdesc_readInputState" msgid="8387754901688728043">"Թույլ է տալիս հավելվածին տեսնել ձեր սեղմած ստեղները, նույնիսկ այն ժամանակ, երբ փոխգործակցում եք այլ հավելվածի հետ (օրինակ` գաղտնաբառի մուտքագրումը): Երբեք անհրաժեշտ չպետք է լինի սովորական հավելվածների համար:"</string>
+    <string name="permlab_bindInputMethod" msgid="3360064620230515776">"միանալ մուտքագրման եղանակին"</string>
+    <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Թույլ է տալիս սեփականատիրոջը միանալ մուտքագրման եղանակի վերին մակարդակի ինտերֆեյսին: Սովորական հավելվածների համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+    <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"կապվել մատչելիության ծառայության հետ"</string>
+    <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Թույլ է տալիս սեփականատիրոջը միանալ հասանելիության ծառայության վերին մակարդակի ինտերֆեյսին: Սովորական հավելվածների համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"միանալ տպման ծառայությանը"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Թույլ է տալիս սեփականատիրոջը միանալ տպման ծառայության վերին մակարդակի ինտերֆեյսին: Սովորական ծրագրերի համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"միանալ տպման կարգավարի ծառայությանը"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Թույլ է տալիս սեփականատիրոջը միանալ տպման կարգավարի ծառայության վերին մակարդակի ինտերֆեյսին: Սովորական ծրագրերի համար երբևէ  անհրաժեշտ չպետք է լինի:"</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"կապվել NFC ծառայությանը"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Թույլ է տալիս տիրոջը կապվել ծրագրերին, որոնք օգտագործում են NFC քարտեր: Սովորական ծրագրերի համար երբեք անհրաժեշտ չէ:"</string>
+    <string name="permlab_bindTextService" msgid="7358378401915287938">"միանալ տեքստային ծառայությանը"</string>
+    <string name="permdesc_bindTextService" msgid="8151968910973998670">"Թույլ է տալիս սեփականատիրոջը կապվել տեքստային ծառայության բարձր մակարդակի ինտերֆեյսին (օրինակ` Ուղղագրության ստուգման ծառայությանը): Սովորական հավելվածների համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+    <string name="permlab_bindVpnService" msgid="4708596021161473255">"կապվել VPN ծառայությանը"</string>
+    <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Թույլ է տալիս սեփականատիրոջը միանալ Vpn ծառայության վերին մակարդակի ինտերֆեյսին: Սովորական հավելվածների համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+    <string name="permlab_bindWallpaper" msgid="8716400279937856462">"միանալ պաստառին"</string>
+    <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Թույլ է տալիս սեփականատիրոջը միանալ պաստառի վերին մակարդակի ինտերֆեյսին: Սովորական հավելվածների համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"միանալ վիջեթ ծառայությանը"</string>
+    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Թույլ է տալիս սեփականատիրոջը միանալ վիջեթ ծառայության վերին մակարդակի ինտերֆեյսին: Սովորական հավելվածների համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+    <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"փոխգործակցել սարքի կառավարչի հետ"</string>
+    <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Թույլ է տալիս սեփականատիրոջը ուղարկել մտադրություններ սարքի կառավարչին: Սովորական հավելվածների համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"ավելացնել կամ հեռացնել սարքի արդմինիստրատոր"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Թույլ է տալիս սեփականատիրոջը ավելացնել կամ հեռացնել սարքի ակտիվ ադմինիստրատորներ: Երբեք չպետք է անհրաժեշտ լինի սովորական ծրագրերին:"</string>
+    <string name="permlab_setOrientation" msgid="3365947717163866844">"փոխել էկրանի դիրքավորումը"</string>
+    <string name="permdesc_setOrientation" msgid="3046126619316671476">"Թույլ է տալիս հավելվածին փոխել էկրանի պտտումը ցանկացած ժամանակ: Սովորական հավելվածների համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+    <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"փոխել ցուցչի արագությունը"</string>
+    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Թույլ է տալիս հավելվածին փոխել մկնիկի կամ հպահարթակի սլաքի արագությունը ցանկացած ժամանակ: Երբևէ անհրաժեշտ չպետք է լինի սովորական հավելվածների համար:"</string>
+    <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"փոխել ստեղնաշարի դիրքը"</string>
+    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Թույլ է տալիս հավելվածին փոխել ստեղնաշարի դիրքը: Սովորական հավելվածների համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+    <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"ուղարկել Linux ազդանշաններ հավելվածներին"</string>
+    <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Թույլ է տալիս հավելվածին հայցել, որ տրամադրված ազդանշանը ուղարկվի բոլոր մշտական գործընթացներին:"</string>
+    <string name="permlab_persistentActivity" msgid="8841113627955563938">"միշտ աշխատեցնել հավելվածը"</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Թույլ է տալիս հավելվածին մնայուն դարձնել իր մասերը հիշողության մեջ: Սա կարող է սահմանափակել այլ հավելվածներին հասանելի հիշողությունը` դանդաղեցնելով գրասալիկի աշխատանքը:"</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"Թույլ է տալիս հավելվածին մնայուն դարձնել իր մասերը հիշողության մեջ: Սա կարող է սահմանափակել այլ հավելվածներին հասանելի հիշողությունը` դանդաղեցնելով հեռախոսի աշխատանքը:"</string>
+    <string name="permlab_deletePackages" msgid="184385129537705938">"ջնջել հավելվածները"</string>
+    <string name="permdesc_deletePackages" msgid="7411480275167205081">"Թույլ է տալիս հավելվածին ջնջել Android փաթեթները: Վնասարար հավելվածները կարող են օգտագործել սա` կարևոր հավելվածները ջնջելու համար:"</string>
+    <string name="permlab_clearAppUserData" msgid="274109191845842756">"ջնջել այլ հավելվածների տվյալները"</string>
+    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"Թույլ է տալիս հավելվածին մաքրել օգտվողի տվյալները:"</string>
+    <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"ջնջել այլ հավելվածների քեշերը"</string>
+    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"Թույլ է տալիս հավելվածին ջնջել քեշ ֆայլերը:"</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"չափել հավելվածի պահոցի տարածքը"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Թույլ է տալիս հավելվածին առբերել իր կոդը, տվյալները և քեշի չափերը"</string>
+    <string name="permlab_installPackages" msgid="2199128482820306924">"ուղղակիորեն տեղադրել հավելվածները"</string>
+    <string name="permdesc_installPackages" msgid="5628530972548071284">"Թույլ է տալիս հավելվածին տեղադրել նոր կամ թարմացված Android փաթեթներ: Վնասարար հավելվածները կարող են օգտագործել սա` ավելացնելու նոր հավելվածներ` կամայականորեն հզոր թույլտվություններով:"</string>
+    <string name="permlab_clearAppCache" msgid="7487279391723526815">"ջնջել հավելվածի քեշի բոլոր տվյալները"</string>
+    <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"Թույլ է տալիս հավելվածին ազատել գրասալիկի պահոցը` ջնջելով ֆայլերը այլ հավելվածների քեշ գրացուցակներում: Սա կարող է պատճառ դառնալ, որ այլ հավելվածները ավելի դանդաղ մեկնարկեն, քանի որ դրանք պետք է նորից առբերեն իրենց տվյալները:"</string>
+    <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"Թույլ է տալիս հավելվածին ազատել հեռախոսի պահուստը` ջնջելով ֆայլերը այլ հավելվածների քեշ գրացուցակներում: Սա կարող է պատճառ դառնալ, որ այլ հավելվածները ավելի դանդաղ մեկնարկեն, քանի որ նրանք պետք է նորից առբերեն իրենց տվյալները:"</string>
+    <string name="permlab_movePackage" msgid="3289890271645921411">"Տեղափոխել հավելվածի ռեսուրսները"</string>
+    <string name="permdesc_movePackage" msgid="319562217778244524">"Թույլ է տալիս հավելվածին տեղափոխել ծրագրային ռեսուրսները ներքին մեդիաներից արտաքինին և հակառակը:"</string>
+    <string name="permlab_readLogs" msgid="6615778543198967614">"կարդալ հոսքի զգայուն տվյալները"</string>
+    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Թույլ է տալիս հավելվածին կարդալ համակարգի տարբեր գրանցամատյանային ֆայլերից: Սա թույլ է տալիս ստանալ ընդհանուր տեղեկություններ այն մասին, թե ինչ եք անում գրասալիկով, այդ թվում` անձնական կամ գաղտնի տեղեկություններ:"</string>
+    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Թույլ է տալիս հավելվածին կարդալ համակարգի տարբեր գրանցամատյանային ֆայլերից: Սա թույլ է տալիս ստանալ ընդհանուր տեղեկություններ այն մասին, թե ինչ եք անում հեռախոսով, այդ թվում` անձնական կամ գաղտնի տեղեկություններ:"</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"օգտագործել ցանկացած մեդիա վերծանիչ նվագարկման համար"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Թույլ է տալիս հավելվածին օգտագործել ցանկացած տեղադրված մեդիա վերծանիչ` նվագարկումը ապակոդավորելու համար:"</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"կառավարել վստահելի հավաստագրերը"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Թույլատրում է հավելվածին տեղադրել և ապատեղադրել CA վկայագրերը՝ որպես վստահելի հավաստագրեր:"</string>
+    <string name="permlab_diagnostic" msgid="8076743953908000342">"կարդալ կամ գրել ախտորոշիչին պատկանող ռեսուրսները"</string>
+    <string name="permdesc_diagnostic" msgid="6608295692002452283">"Թույլ է տալիս հավելվածին կարդալ և գրել ախտորոշիչ խմբին պատկանող ցանկացած ռեսուրսում, ինչպես օրինակ ֆայլերը /dev-ում: Դա կարող է ազդել համակարգի կայունության և անվտանգության վրա: Սա պետք է օգտագործել միայն արտադրողի կամ օպերատորի կողմից սարքին հատուկ ախտորոշման համար:"</string>
+    <string name="permlab_changeComponentState" msgid="6335576775711095931">"միացնել կամ անջատել հավելվածի բաղադրիչները"</string>
+    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Թույլ է տալիս հավելվածին փոխել, արդյոք այլ հավելվածի բաղադրիչը լինի միացված թե անջատված: Վնասարար հավելվածները կարող են սա օգտագործել` անջատելու գրասալիկի կարևոր հնարավորությունները: Այս թույլտվությունը պետք է օգտագործել զգուշությամբ, քանի որ հնարավոր է հավելվածի բաղադրիչները հայտնվեն անպիտան, անհամապատասխան կամ անկայուն կարգավիճակում:"</string>
+    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Թույլ է տալիս հավելվածին փոխել, արդյոք այլ հավելվածի բաղադրիչը լինի միացված թե անջատված: Վնասարար հավելվածները կարող են սա օգտագործել` անջատելու հեռախոսի կարևոր հնարավորությունները: Այս թույլտվությունը պետք է օգտագործել զգուշությամբ, քանի որ հնարավոր է հավելվածի բաղադրիչները հայտնվեն անպիտան, անհամապատասխան կամ անկայուն կարգավիճակում:"</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"շնորհել կամ չեղարկել թույլտվություններ"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Թույլ է տալիս հավելվածին հատուկ թույլտվություն շնորհել կամ չեղարկել այդ կամ այլ հավելվածների համար: Վնասարար հավելվածները կարող են օգտագործել սա` մուտք գործելու ձեր կողմից չթույլատրված գործիքներ:"</string>
+    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"սահմանել նախընտրած հավելվածները"</string>
+    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Թույլ է տալիս հավելվածին փոփոխել ձեր նախընտրած հավելվածները: Վնասարար հավելվածները կարող են աննկատ փոխել հավելվածները, որոնք կեղծում են ձեր առկա հավելվածների աշխատանքը` ձեզանից անձնական տվյալներ հավաքագրելու համար:"</string>
+    <string name="permlab_writeSettings" msgid="2226195290955224730">"փոփոխել համակարգի կարգավորումները"</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"Թույլ է տալիս հավելվածին փոփոխել համակարգի կարգավորումների տվյալները: Վնասարար հավելվածները կարող են վնասել ձեր համակարգի կարգավորումները:"</string>
+    <string name="permlab_writeSecureSettings" msgid="204676251876718288">"փոփոխել անվտանգ համակարգի կարգավորումները"</string>
+    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"Թույլ է տալիս հավելվածին փոփոխել համակարգի անվտանգ կարգավորումների տվյալները: Նախատեսված չէ սովորական հավելվածների կողմից օգտագործման համար:"</string>
+    <string name="permlab_writeGservices" msgid="2149426664226152185">"փոփոխել Google ծառայությունների քարտեզը"</string>
+    <string name="permdesc_writeGservices" msgid="1287309437638380229">"Թույլ է տալիս հավելվածին փոփոխել Google-ի ծառայությունների քարտեզը: Սովորական հավելվածների օգտագործման համար չէ:"</string>
+    <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"աշխատել մեկնարկային ռեժիմով"</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Թույլ է տալիս հավելվածին ինքնուրույն մեկնարկել համակարգի բեռնման ավարտից հետո: Սա կարող է երկարացնել գրասալիկի մեկնարկը և թույլ տալ հավելավածին դանդաղեցնել ամբողջ գրասալիկի աշխատանքը` միշտ աշխատելով:"</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="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="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="default" msgid="589869224625163558">"Թույլ է տալիս հավելվածին փոփոխել ձեր գրասալիկում պահված կոնտակտների տվյալները, այդ թվում` ձեր կատարած զանգերի, գրած նամակների կամ որոշակի անհատների հետ այլ եղանակով շփման հաճախականությունը: Այս թույլտվությունը հնարավորություն է տալիս հավելվածներին ջնջել կոնտակտային տվյալները:"</string>
+    <string name="permlab_readCallLog" msgid="3478133184624102739">"կարդալ զանգերի մատյանը"</string>
+    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Թույլ է տալիս հավելվածին կարդալ ձեր գրասալիկի զանգերի գրանցամատյանը, այդ թվում` մուտքային և ելքային զանգերի տվյալները: Սա թույլ է տալիս հավելվածին պահել ձեր զանգերի գրանցամատյանի տվյալները, և վնասարար հավելվածները կարող են տարածել դրանք` առանց ձեր իմացության:"</string>
+    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Թույլ է տալիս հավելվածին կարդալ ձեր հեռախոսի զանգերի գրանցամատյանը, այդ թվում` մուտքային և ելքային զանգերի տվյալները: Թույլտվությունը հնարավորություն է տալիս հավելվածին պահպանել ձեր զանգերի գրանցամատյանի տվյալները, և վնասարար հավելվածները կարող են տարածել գրանցամատյանի տվյալներն առանց ձեր իմացության:"</string>
+    <string name="permlab_writeCallLog" msgid="8552045664743499354">"տեսնել զանգերի գրանցամատյանը"</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Թույլ է տալիս հավելվածին փոփոխել ձեր գրասալիկի զանգերի մատյանը, այդ թվում` մուտքային և ելքային զանգերի մասին տվյալները: Վնասարար հավելվածները կարող են սա օգտագործել` ձեր զանգերի մատյանը ջնջելու կամ փոփոխելու համար:"</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Թույլ է տալիս հավելվածին փոփոխել ձեր հեռախոսի զանգերի մատյանը, այդ թվում` մուտքային և ելքային զանգերի մասին տվյալները: Վնասարար հավելվածները կարող են սա օգտագործել` ձեր զանգերի մատյանը ջնջելու կամ փոփոխելու համար:"</string>
+    <string name="permlab_readProfile" msgid="4701889852612716678">"կարդալ ձեր սեփական կոնտակտային քարտը"</string>
+    <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Թույլ է տալիս հավելվածին կարդալ ձեր սարքում պահված անհատական ​​պրոֆիլի տվյալները, ինչպիսիք են ձեր անունը և կոնտակտային տվյալները: Սա նշանակում է, որ հավելվածը կարող է ձեզ ճանաչել և ուղարկել ձեր պրոֆիլի տվյալները ուրիշներին:"</string>
+    <string name="permlab_writeProfile" msgid="907793628777397643">"փոփոխել ձեր սեփական կոնտակտային քարտը"</string>
+    <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Թույլ է տալիս հավելվածին փոխել կամ ավելացնել ձեր սարքում պահված անհատական ​​պրոֆիլի տվյալները, ինչպիսիք են ձեր անունը և կոնտակտային տվյալները: Սա նշանակում է, որ հավելվածը կարող է ձեզ ճանաչել և ուղարկել ձեր պրոֆիլի տվյալները ուրիշներին:"</string>
+    <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"կարդալ ձեր սոցիալական հոսքը"</string>
+    <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Թույլ է տալիս հավելվածին մուտք գործել և համաժամեցնել ձեր և ձեր ընկերների սոցիալական թարմացումները: Զգույշ եղեք տեղեկություններ տարածելիս. այն թույլ է տալիս հավելվածին կարդալ ձեր և ձեր ընկերների միջև անձնական հաղորդագրությունները սոցիալական ցանցերում` անկախ գաղտնիությունից: Նշում. այս թույլտվությունը չի կարող գործածվել բոլոր սոցիալական ցանցերում:"</string>
+    <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"գրել ձեր սոցիալական հոսքում"</string>
+    <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Թույլ է տալիս հավելվածին ցուցադրել ձեր ընկերների սոցիալական թարմացումները: Զգույշ եղեք տեղեկություններ տարածելիս. այն թույլ է տալիս հավելվածին հաղորդագություններ ստեղծել, որոնք իբրև ստացվում են ընկերոջից: Նշում. այս թույլտվությունը չի կարող գործածվել բոլոր սոցիալական ցանցերում:"</string>
+    <string name="permlab_readCalendar" msgid="5972727560257612398">"կարդալ օրացուցային իրադարձությունները և գաղտնի տեղեկությունները"</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Թույլ է տալիս հավելվածին կարդալ ձեր գրասալիկում պահված բոլոր օրացուցային իրադարձությունները, այդ թվում` ընկերների կամ գործընկերների: Սա կարող է թույլ տալ հավելվածին տարածել կամ պահել ձեր օրացուցային տվյալները` անկախ գաղտնիությունից կամ զգայունությունից:"</string>
+    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Թույլ է տալիս հավելվածին կարդալ ձեր հեռախոսում պահված բոլոր օրացուցային իրադարձությունները, այդ թվում` ընկերների կամ գործընկերների: Սա կարող է թույլ տալ հավելվածին տարածել կամ պահել ձեր օրացուցային տվյալները` անկախ գաղտնիությունից կամ զգայունությունից:"</string>
+    <string name="permlab_writeCalendar" msgid="8438874755193825647">"ավելացնել կամ փոփոխել օրացուցային իրադարձությունները և ուղարկել նամակ հյուրերին` առանց սեփականատերերի իմացության"</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Թույլ է տալիս հավելվածին ավելացնել, հեռացնել, փոխել իրադարձություններ, որոնք դուք կարող եք փոփոխել ձեր գրասալիկում, այդ թվում ընկերների կամ աշխատակիցների իրադարձությունները: Սա կարող է թույլ տալ հավելվածին ուղարկել հաղորդագրություններ, որոնք երևում են որպես օրացույցի սեփականատերերից ուղարկված, կամ փոփոխել իրադարձություններն առանց սեփականատերերի իմացության:"</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Թույլ է տալիս հավելվածին ավելացնել, հեռացնել, փոխել այն իրադարձությունները, որոնք կարող եք փոփոխել ձեր հեռախոսից, այդ թվում` ընկերների կամ գործընկերների: Սա կարող է թույլ տալ հավելվածին ուղարկել հաղորդագրություններ, որոնք իբրև գալիս են օրացույցի սեփականատիրոջից, կամ փոփոխել իրադարձությունները` առանց սեփականատիրոջ իմացության:"</string>
+    <string name="permlab_accessMockLocation" msgid="8688334974036823330">"կեղծ տեղանքի աղբյուրներ փորձարկման համար"</string>
+    <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Ստեղծել կեղծ տեղանքի աղբյուրներ` փորձարկման կամ տեղադրության նոր ծառայություն մատուցողի տեղադրման համար: Սա հնարավորություն է տալիս, որ ծրագիրը անտեսի տեղադրությունը և/կամ կարգավիճակը` տրամադրված տեղանքի այլ աղբյուրների կողմից, ինչպիսիք են GPS-ը կամ տեղադրության ծառայություն մատուցողները:"</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"օգտագործել տեղադրություն տրամադրող հավելվյալ հրամաններ"</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"Թույլ է տալիս հավելվածին օգտագործել տեղադրության ծառայություն մատուցողների լրացուցիչ հրամանները: Սա կարող է թույլ տալհավելվածին խանգարել GPS-ի կամ այլ տեղանքի աղբյուրների աշխատանքին:"</string>
+    <string name="permlab_installLocationProvider" msgid="6578101199825193873">"տեղադրության ծառայություն մատուցողի տեղադրման թույլտվություն"</string>
+    <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"Ստեղծել կեղծ տեղանքի աղբյուրներ` փորձարկման կամ տեղադրության նոր ծառայություն մատուցողի տեղադրման համար: Սա հնարավորություն է տալիս, որ հավելվածն անտեսի տեղադրությունը և/կամ կարգավիճակը` տրամադրված տեղանքի այլ աղբյուրների կողմից, ինչպիսիք են GPS-ը կամ տեղադրության ծառայություն մատուցողները:"</string>
+    <string name="permlab_accessFineLocation" msgid="1191898061965273372">"ճշգրիտ վայրը (ըստ GPS-ի և ցանցի)"</string>
+    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Թույլ է տալիս հավելվածին ստանալ ձեր ճշգրիտ տեղադրությունը` օգտագործելով Գլոբալ Դիրքավորման Համակարգը (GPS) կամ ցանցային տեղանքի աղբյուրները, ինչպես օրինակ` բջջային աշտարակները և Wi-Fi-ը: Այս տեղադրության ծառայությունները պետք է միացվեն և հասանելի լինեն ձեր սարքի համար, որպեսզի հավելվածն օգտագործի դրանք: Հավելվածները կարող են սա օգտագործել` որոշելու համար ձեր գտնվելու վայրը և կարող են սպառել մարտկոցի լրացուցիչ լիցք:"</string>
+    <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"մոտավոր տեղադրությունը (ցանցային)"</string>
+    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Թույլ է տալիս հավելվածին ստանալ ձեր մոտավոր տեղադրությունը: Այս տեղադրությունը ստացվում է տեղանքի ծառայությունների կողմից, ինչպես օրինակ` բջջային աշտարակներից և Wi-Fi-ից: Այս տեղանքի ծառայությունները պետք է միացված և հասանելի լինեն ձեր սարքին, որպեսզի հավելվածն օգտագործի դրանք: Հավելվածները կարող են սա օգտագործել` ձեր մոտավոր գտնվելու վայրը որոշելու համար:"</string>
+    <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"մուտք SurfaceFlinger"</string>
+    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Թույլ է տալիս հավելվածին օգտագործել SurfaceFlinger ցածր մակարդակի գործառույթները:"</string>
+    <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"կարդալ շրջանակի պահնակը"</string>
+    <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Թույլ է տալիս հավելվածին կարդալ շրջանակի պահնակի բովանդակությունը:"</string>
+    <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"կարգավորել WiFi-ի ցուցադրումը"</string>
+    <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Թույլ է տալիս հավելվածին կարգավորել և միանալ WiFi ցուցադրիչներին:"</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"կառավարել Wifi-ի ցուցադրումը"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Թույլ է տալիս հավելվածին կառավարել WiFi ցուցադրիչների ցածր մակարդակի գործառույթները:"</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"պահել աուդիո արտածումը"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Թույլ է տալիս ծրագրին պահել և վերահղել աուդիո արտածումը:"</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"պահել վիդեո արտածումը"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Թույլ է տալիս ծրագրին պահել և վերահղել վիդեո արտածումը:"</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"պահել անվտանգ վիդեո արտածումը"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Թույլ է տալիս ծրագրին պահել և վերահղել անվտանգ վիդեո արտածումը:"</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="4906839301087980680">"Թույլ է տալիս հավելվածին բարձրախոսով ձայնագրել ձայնանյութ: Այս թույլտվությունը հնարավորություն է տալիս հավելվածին ձայնանյութ ձայնագրել ցանկացած ժամանակ` առանց ձեր հաստատման:"</string>
+    <string name="permlab_camera" msgid="3616391919559751192">"լուսանկարել և տեսանկարել"</string>
+    <string name="permdesc_camera" msgid="8497216524735535009">"Թույլ է տալիս հավելվածին ֆոտոխցիկով լուսանկարել և տեսանկարել: Այս թույլտվությունը հնարավորություն է տալիս հավելվածին օգտագործել ֆոտոխցիկը ցանկացած ժամանակ` առանց ձեր հաստատման:"</string>
+    <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"անջատել փոխանցող LED ցուցիչը, երբ ֆոտոխցիկը օգտագործվում է"</string>
+    <string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"Թույլ է տալիս նախապես տեղադրված համակարգային ծրագրին անջատել ֆոտոխցիկի օգտագործման LED ցուցիչը:"</string>
+    <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"մշտապես անջատել գրասալիկը"</string>
+    <string name="permlab_brick" product="default" msgid="8337817093326370537">"ընդմիշտ կասեցնել հեռախոսը"</string>
+    <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"Թույլ է տալիս հավելվածին ընդմիշտ անջատել ամբողջ գրասալիկը: Սա շատ վտանգավոր է:"</string>
+    <string name="permdesc_brick" product="default" msgid="5788903297627283099">"Թույլ է տալիս հավելվածին ընդմիշտ անջատել ամբողջ հեռախոսը: Սա շատ վտանգավոր է:"</string>
+    <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"ստիպել, որ գրասալիկը վերաբեռնվի"</string>
+    <string name="permlab_reboot" product="default" msgid="2898560872462638242">"ստիպել, որ հեռախոսը վերաբեռնվի"</string>
+    <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"Թույլ է տալիս հավելվածին ստիպել, որ գրասալիկը վերաբեռնվի:"</string>
+    <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"Թույլ է տալիս հավելվածին ստիպել, որ հեռախոսը վերաբեռնվի:"</string>
+    <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"մուտք ունենալ USB կրիչի ֆայլային համակարգ"</string>
+    <string name="permlab_mount_unmount_filesystems" product="default" msgid="4402305049890953810">"մուտք ունենալ SD քարտի ֆայլային համակարգ"</string>
+    <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"Թույլ է տալիս հավելվածին միացնել և անջատել շարժական կրիչների ֆայլային համակարգերը:"</string>
+    <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"ջնջել USB կրիչը"</string>
+    <string name="permlab_mount_format_filesystems" product="default" msgid="262582698639274056">"ջնջել SD քարտը"</string>
+    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"Թույլ է տալիս հավելվածին ֆորմատավորել շարժական կրիչը:"</string>
+    <string name="permlab_asec_access" msgid="3411338632002193846">"տեղեկություններ ստանալ ներքին պահոցի վերաբերյալ"</string>
+    <string name="permdesc_asec_access" msgid="3094563844593878548">"Թույլ է տալիս հավելվածին ստանալ տեղեկություններ ներքին պահոցի վերաբերյալ:"</string>
+    <string name="permlab_asec_create" msgid="6414757234789336327">"ստեղծել ներքին պահոց"</string>
+    <string name="permdesc_asec_create" msgid="4558869273585856876">"Թույլ է տալիս հավելվածին ստեղծել ներքին պահոց:"</string>
+    <string name="permlab_asec_destroy" msgid="526928328301618022">"ոչնչացնել ներքին պահոցը"</string>
+    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"Թույլ է տալիս հավելվածին ոչնչացնել ներքին պահոցը:"</string>
+    <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"միացնել կամ անջատել ներքին պահոցը"</string>
+    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"Թույլ է տալիս հավելվածին միացնել/անջատել ներքին պահոցը:"</string>
+    <string name="permlab_asec_rename" msgid="7496633954080472417">"վերանվանել ներքին պահոցը"</string>
+    <string name="permdesc_asec_rename" msgid="1794757588472127675">"Թույլ է տալիս հավելվածին վերանվանել ներքին պահոցը:"</string>
+    <string name="permlab_vibrate" msgid="7696427026057705834">"կառավարել թրթռումը"</string>
+    <string name="permdesc_vibrate" msgid="6284989245902300945">"Թույլ է տալիս հավելվածին կառավարել թրթռոցը:"</string>
+    <string name="permlab_flashlight" msgid="2155920810121984215">"կառավարել լապտերը"</string>
+    <string name="permdesc_flashlight" msgid="6522284794568368310">"Թույլ է տալիս հավելվածին կառավարել լապտերը:"</string>
+    <string name="permlab_manageUsb" msgid="1113453430645402723">"կառավարել նախապատվությունները և թույլտվությունները USB սարքերի համար"</string>
+    <string name="permdesc_manageUsb" msgid="7776155430218239833">"Թույլ է տալիս հավելվածին կառավարել նախասիրություններն ու թույլտվությունները USB սարքերի համար:"</string>
+    <string name="permlab_accessMtp" msgid="4953468676795917042">"կիրառել MTP պրոտոկոլը"</string>
+    <string name="permdesc_accessMtp" msgid="6532961200486791570">"Մուտքի հնարավորություն է տալիս միջուկի MTP սարքավարին MTP USB պրոտոկոլը կիրառելու համար:"</string>
+    <string name="permlab_hardware_test" msgid="4148290860400659146">"փորձարկել սարքը"</string>
+    <string name="permdesc_hardware_test" msgid="6597964191208016605">"Թույլ է տալիս հավելվածին կառավարել տարբեր արտաքին սարքավորումեր` սարքաշարի փորձարկման նպատակով:"</string>
+    <string name="permlab_callPhone" msgid="3925836347681847954">"ուղղակիորեն զանգել հեռախոսահամարներին"</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"Թույլ է տալիս հավելվածին զանգել հեռախոսահամարներին առանց ձեր միջամտության: Սա կարող է հանգեցնել անկանխատեսելի գանձումների կամ զանգերի: Նկատի ունեցեք, որ սա թույլ չի տալիս հավելվածին զանգել արտակարգ իրավիճակների համարներին: Վնասարար հավելվածները կարող են ձեր հաշվից զանգեր կատարել` առանց ձեր հաստատման:"</string>
+    <string name="permlab_callPrivileged" msgid="4198349211108497879">"ուղղակիորեն զանգահարել որևէ հեռախոսահամարի"</string>
+    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"Թույլ է տալիս հավելվածին զանգել ցանկացած հեռախոսահամարի, այդ թվում` արտակարգ իրավիճակների համարներին` առանց ձեր միջամտության: Վնասարար հավելվածները կարող են կատարել անցանկալի և անօրինական զանգեր արտակարգ իրավիճակների ծառայություններին:"</string>
+    <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"ուղղակիորեն սկսել CDMA գրասալիկի կագավորումը"</string>
+    <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"ուղղակիորեն սկսել CDMA հեռախոսի կարգավորումը"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"Թույլ է տալիս հավելվածին մեկնարկել CDMA-ի տրամադրումը: Վնասարար հավելվածները կարող են անտեղի սկսել CDMA-ի տրամադրում:"</string>
+    <string name="permlab_locationUpdates" msgid="7785408253364335740">"վերահսկել տեղանքի թարմացման ծանուցումները"</string>
+    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Թույլ է տալիս հավելվածին միացնել կամ անջատել տեղանքի թարմացման ծանուցումները ռադիոյից: Սովորական հավելվածների օգտագործման համար չէ:"</string>
+    <string name="permlab_checkinProperties" msgid="7855259461268734914">"մուտք գործել գրանցանշման կարգավորումներ"</string>
+    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Թույլ է տալիս հավելվածին կարդալ/գրել գրանցանշման ծառայության կողմից վերբեռնված հատկությունների մուտքը: Սովորական հավելվածների օգտագործման համար չէ:"</string>
+    <string name="permlab_bindGadget" msgid="776905339015863471">"ընտրել վիջեթներ"</string>
+    <string name="permdesc_bindGadget" msgid="8261326938599049290">"Թույլ է տալիս հավելվածին թելադրել համակարգին, թե որ վիջեթները որ հավելվածի միջոցով է հնարավոր օգտագործել: Այս թույլտվությամբ հավելվածը կարող է այլ հավելվածներին մուտք տալ դեպի անձնական տվյալներ: Սովորական հավելվածների օգտագործման համար չէ:"</string>
+    <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"փոփոխել հեռախոսի կարգավիճակը"</string>
+    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Թույլ է տալիս հավելվածին կառավարել սարքի հեռախոսային գործիքները: Այս թույլտվությամբ հավելվածը կարող է փոխարկել ցանցերը, միացնելև անջատել հեռախոսի ռադիոն և նման այլ բաներ` առանց ձեզ երբևէ տեղեկացնելու:"</string>
+    <string name="permlab_readPhoneState" msgid="9178228524507610486">"կարդալ հեռախոսի կարգավիճակը և ինքնությունը"</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Թույլ է տալիս հավելվածին օգտագործել սարքի հեռախոսային գործիքները: Այս թույլտվությունը հավելվածին հնարավորություն է տալիս որոշել հեռախոսահամարը և սարքի ID-ները, արդյոք զանգը ակտիվ է և միացված զանգի հեռակա հեռախոսահամարը:"</string>
+    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"զերծ պահել գրասալիկը քնելուց"</string>
+    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"կանխել հեռախոսի քնի ռեժիմին անցնելը"</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Թույլ է տալիս հավելվածին կանխել գրասալիկի` քնի ռեժիմին անցնելը:"</string>
+    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Թույլ է տալիս հավելվածին կանխել հեռախոսի` քնի ռեժիմին անցնելը:"</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
+    <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"գրասալիկը միացնել կամ անջատել"</string>
+    <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"հեռախոսը միացնել կամ անջատել"</string>
+    <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Թույլ է տալիս հավելվածին միացնել կամ անջատել գրասալիկը:"</string>
+    <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"Թույլ է տալիս հավելվածին միացնել կամ անջատել հեռախոսը:"</string>
+    <string name="permlab_factoryTest" msgid="3715225492696416187">"աշխատել գործարանային փորձնական ռեժիմում"</string>
+    <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"Աշխատեցնել որպես արտադրողի ցածր մակարդակի փորձարկում` թույլատրելով գրասալիկի սարքին լիարժեք մուտք: Հասանելի է միայն այն ժամանակ, երբ գրասալիկը աշխատում է արտադրողի փորձնական ռեժիմում:"</string>
+    <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"Աշխատեցնել որպես արտադրողի ցածր մակարդակի փորձարկում` թույլատրելով լիարժեք մուտք հեռախոսի սարքաշարին: Հասանելի է միայն այն ժամանակ, երբ հեռախոսն աշխատում է արտադրողի փորձնական ռեժիմում:"</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_masterClear" msgid="2315750423139697397">"վերակայել համակարգը գործարանային լռելյայնի"</string>
+    <string name="permdesc_masterClear" msgid="3665380492633910226">"Թույլ է տալիս հավելվածին ամբողջությամբ վերակայել համակարգը իր գործարանային կարգավորումներին` ջնջելով բոլոր տվյալները, կարգավորումները և տեղադրված հավելվածները:"</string>
+    <string name="permlab_setTime" msgid="2021614829591775646">"կարգավորել ժամը"</string>
+    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"Թույլ է տալիս հավելվածին փոխել գրասալիկի ժամացույցի ժամանակը:"</string>
+    <string name="permdesc_setTime" product="default" msgid="1855702730738020">"Թույլ է տալիս հավելվածին փոխել հեռախոսի ժամացույցի ժամանակը:"</string>
+    <string name="permlab_setTimeZone" msgid="2945079801013077340">"կարգավորել ժամային գոտին"</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Թույլ է տալիս հավելվածին փոխել գրասալիկի ժամային գոտին:"</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Թույլ է տալիս հավելվածին փոխել հեռախոսի ժամային գոտին:"</string>
+    <string name="permlab_accountManagerService" msgid="4829262349691386986">"գործել որպես Հաշվի կառավարիչ ծառայություն"</string>
+    <string name="permdesc_accountManagerService" msgid="1948455552333615954">"Թույլ է տալիս հավելվածին զանգել Հաշվի իսկորոշիչներին:"</string>
+    <string name="permlab_getAccounts" msgid="1086795467760122114">"գտնել հաշիվներ սարքում"</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Թույլ է տալիս հավելվածին ստանալ գրասալիկի կողմից ճանաչված հաշիվների ցանկը: Սա կարող է ներառել ցանկացած հաշիվ, որ ստեղծվել է ձեր տեղադրած հավելվածների կողմից:"</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Թույլ է տալիս հավելվածին ստանալ հեռախոսի կողմից ճանաչված հաշիվների ցանկը: Սա կարող է ներառել ցանկացած հաշիվ, որ ստեղծվել է ձեր տեղադրած հավելվածների կողմից:"</string>
+    <string name="permlab_authenticateAccounts" msgid="5265908481172736933">"ստեղծել հաշիվներ և դնել գաղտնաբառեր"</string>
+    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"Թույլ է տալիս հավելվածին օգտագործել հաշվի կառավարչի նույնականացնող հնարավորությունները, ինչպես նաև ստեղծել հաշիվներ, ստանալ և կարգավորել դրանց գաղտնաբառերը:"</string>
+    <string name="permlab_manageAccounts" msgid="4983126304757177305">"ավելացնել կամ հեռացնել հաշիվներ"</string>
+    <string name="permdesc_manageAccounts" msgid="8698295625488292506">"Թույլ է տալիս հավելվածին իրականացնել գործողություններ, ինչպիսիք են` ավելացնել և հեռացնել հաշիվներ և ջնջել դրանց գաղտնաբառերը:"</string>
+    <string name="permlab_useCredentials" msgid="235481396163877642">"օգտագործել սարքի հաշիվները"</string>
+    <string name="permdesc_useCredentials" msgid="7984227147403346422">"Թույլ է տալիս հավելվածին հայցել նույնականացման նշաններ:"</string>
+    <string name="permlab_accessNetworkState" msgid="4951027964348974773">"դիտել ցանցային միացումները"</string>
+    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Թույլ է տալիս հավելվածին տեսնել ցանցային կապերի մասին տեղեկություններ, ինչպես օրինակ, թե ինչ կապեր կան և որոնք են միացված:"</string>
+    <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"լրիվ ցանցային մուտք"</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Թույլ է տալիս հավելվածին ստեղծել ցանցային բնիկներ և օգտագործել հատուկ ցանցային պրոտոկոլներ: Զննարկիչը և այլ հավելվածները միջոցներ են տրամադրում ինտերնետին տվյալներ ուղարկելու համար, ուստի այս թույլտվությունը չի պահանջվում ինտերնետին տվյալներ ուղարկելու համար:"</string>
+    <string name="permlab_writeApnSettings" msgid="505660159675751896">"փոխել/կասեցնել ցանցային կարգավորումները և շարժը"</string>
+    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Թույլ է տալիս հավելվածին փոխել ցանցային կարգավորումները և կասեցնել ու ստուգել ամբողջ ցանցային շարժը, օրինակ` փոխել ցանկացած APN-ի պրոքսին և միացքը: Վնասարար հավելվածները կարող են հետևել, վերահասցեավորել կամ փոփոխել ցանցային փաթեթները` առանց ձեր իմացության:"</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_changeBackgroundDataSetting" msgid="1400666012671648741">"փոխել ֆոնային տվյալների օգտագործման կարգավորումը"</string>
+    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Թույլ է տալիս հավելվածին փոխել ֆոնային տվյալների օգտագործման կարգավորումները:"</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="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="default" msgid="8931682159331542137">"Թույլ է տալիս հավելվածին կարգավորել տեղային Bluetooth հեռախոսը և հայտնաբերել ու զուգակցվել հեռակա սարքերի հետ:"</string>
+    <string name="permlab_accessWimaxState" msgid="4195907010610205703">"միանալ WiMAX-ին և անջատվել դրանից"</string>
+    <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"Թույլ է տալիս հավելվածին պարզել, արդյոք WiMAX-ը միացված է և ցանկացած միացված WiMAX ցանցի մասին տեղեկություններ:"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Փոխել WiMAX-ի կարգավիճակը"</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Թույլ է տալիս հավելվածին գրասալիկը միացնել 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="default" msgid="3207106324452312739">"Թույլ է տալիս հավելվածին տեսնել Bluetooth-ի կարգավորումը հեռախոսի վրա և կապվել ու կապեր ընդունել զուգակցված սարքերի հետ:"</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_readSyncSettings" msgid="6201810008230503052">"կարդալ համաժամեցման կարգավորումները"</string>
+    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Թույլ է տալիս հավելվածին կարդալ համաժամեցման կարգավորումները հաշվի համար: Օրինակ` այն կարող է որոշել, արդյոք Մարդիկ հավելվածը համաժամեցված է հաշվի հետ:"</string>
+    <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"համաժամեցումը փոխարկել միացվածի և անջատվածի"</string>
+    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Թույլ է տալիս հավելվածին փոփոխել համաժամեցման կարգավորումները հաշվի համար: Օրինակ, այն կարող է օգտագործվել` միացնելու Մարդիկ հավելվածի համաժամեցումը հաշվի հետ:"</string>
+    <string name="permlab_readSyncStats" msgid="7396577451360202448">"կարդալ համաժամեցման վիճակագրությունը"</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Թույլ է տալիս հավելվածին կարդալ հաշվի համաժամեցման վիճակագրությունը, այդ թվում` համաժամեցման իրադարձությունների պատմությունը և թե որքան տվյալ է համաժամեցված:"</string>
+    <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"կարդալ բաժանորդագրված հոսքերը"</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Թույլ է տալիս հավելվածին մանրամասներ ստանալ ընթացիկ համաժամեցված հոսքերի մասին:"</string>
+    <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"գրել բաժանորդագրված հոսքերը"</string>
+    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"Թույլ է տալիս հավելվածին փոփոխել ձեր ներկայումս համաժամեցված հոսքերը: Վնասարար հավելվածները կարող են փոխել ձեր համաժամեցված հոսքերը:"</string>
+    <string name="permlab_readDictionary" msgid="4107101525746035718">"կարդալ պայմանները, որ ավելացրել եք բառարանում"</string>
+    <string name="permdesc_readDictionary" msgid="659614600338904243">"Թույլ է տալիս հավելվածին կարդալ բոլոր բառերը, անունները և արտահայտությունները, որոնք օգտագործողը հնարավոր է պահել է օգտվողի բառարանում:"</string>
+    <string name="permlab_writeDictionary" msgid="2183110402314441106">"ավելացնել բառեր օգտվողի համար սահմանված բառարանում"</string>
+    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Թույլ է տալիս հավելվածին գրել նոր բառեր օգտվողի բառարանում:"</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"փորձարկել մուտքը դեպի պաշտպանված պահոց"</string>
+    <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"փորձարկել մուտքը դեպի պաշտպանված պահոց"</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"Թույլ է տալիս հավելվածին փորձարկել USB կրիչի թույլտվությունը, որը հասանելի կլինի հետագա սարքերում:"</string>
+    <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"Թույլ է տալիս հավելվածին փորձարկել 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_mediaStorageWrite" product="default" msgid="6859839199706879015">"փոփոխել/ջնջել ներքին մեդիա կրիչի բովանդակությունը"</string>
+    <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Թույլ է տալիս հավելվածին փոփոխել ներքին մեդիա պահոցի բովանդակությունը:"</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"կառավարել փաստաթղթերի պահոցը"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Թույլ է տալիս հավելվածին կառավարել փաստաթղթի պահոցը:"</string>
+    <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"մուտք ունենալ բոլոր օգտվողների արտաքին պահոց"</string>
+    <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Թույլ է տալիս հավելվածին մուտք գործել արտաքին պահոց բոլոր օգտվողների համար:"</string>
+    <string name="permlab_cache_filesystem" msgid="5656487264819669824">"մուտք քեշի ֆայլերի համակարգ"</string>
+    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Թույլ է տալիս հավելվածին գրել և կարդալ քեշ ֆայլային համակարգը:"</string>
+    <string name="permlab_use_sip" msgid="5986952362795870502">"կատարել կամ ստանալ ինտերնետային զանգեր"</string>
+    <string name="permdesc_use_sip" msgid="4717632000062674294">"Թույլ է տալիս հավելվածին օգտագործել SIP ծառայությունը` ինտերնետային զանգեր կատարելու/ստանալու համար:"</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_markNetworkSocket" msgid="3658527214914959749">"փոփոխել բնիկի նշանները"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Թույլ է տալիս ծրագրին փոփոխել բնիկի նշանները երթուղման համար"</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_invokeCarrierSetup" msgid="3699600833975117478">"գործարկել օպերատորի կողմից տրամադրված կազմաձևման ծրագիրը"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Թույլ է տալիս սեփականատիրոջը գործարկել օպերատորի կողմից տրամադրված կազմաձևման ծրագիրը: Սովորական ծրագրերի համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"լսել դիտարկումներ ցանցային պայմանների վերաբերյալ"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Հավելվածին թույլ է տալիս լսել դիտարկումներ ցանցային պայմանների վերաբերյալ: Սովորական հավելվածների համար երբեք պետք չի գալիս:"</string>
+    <string name="policylab_limitPassword" msgid="4497420728857585791">"Սահմանել գաղտնաբառի կանոնները"</string>
+    <string name="policydesc_limitPassword" msgid="3252114203919510394">"Վերահսկել էկրանի ապակողպման գաղտնաբառերի թույլատրելի երկարությունն ու գրանշանները:"</string>
+    <string name="policylab_watchLogin" msgid="914130646942199503">"Վերահսկել էկրանի ապակողպման փորձերը"</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Վերահսկել սխալ գաղտնաբառերի թիվը, որոնք մուտքագրվել են էկրանն ապակողպելիս, և կողպել գրասալիկը կամ ջնջել գրասալիկի բոլոր տվյալները, եթե մուտքագրվել են չափից շատ սխալ գաղտնաբառեր:"</string>
+    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Վերահսկել սխալ գաղտնաբառերի թիվը, որոնք մուտքագրվել են էկրանն ապակողպելիս, և կողպել հեռախոսը կամ ջնջել հեռախոսի բոլոր տվյալները, եթե մուտքագրվել են չափից շատ սխալ գաղտնաբառեր:"</string>
+    <string name="policylab_resetPassword" msgid="2620077191242688955">"Փոխել էկրանի ապակողպման գաղտնաբառը"</string>
+    <string name="policydesc_resetPassword" msgid="605963962301904458">"Փոխել էկրանի ապակողպման գաղտնաբառը:"</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="default" msgid="5096895604574188391">"Ջնջել հեռախոսի տվյալներն առանց նախազգուշացման` կատարելով գործարանային տվյալների վերակայում:"</string>
+    <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Կարգավորել սարքի համաշխարհային պրոքսին"</string>
+    <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Սարքը կարգավորել, որ համաշխարհային պրոքսին օգտագործվի, երբ քաղաքականությունը միացված է: Միայն առաջին սարքի կառավարիչն է կարգավորում գործող համաշխարհային պրոքսին:"</string>
+    <string name="policylab_expirePassword" msgid="885279151847254056">"Սահմանել էկրանի կողպման գաղտնաբառի սպառման ժամկետը"</string>
+    <string name="policydesc_expirePassword" msgid="1729725226314691591">"Վերահսկել` ինչ հաճախականությամբ պետք է էկրանի կողպման գաղտնաբառը փոխվի:"</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="policylab_disableKeyguardFeatures" msgid="266329104542638802">"Անջատել ստեղնակողպեքի գործառույթները"</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="3467082272186534614">"Կանխել ստեղնակողպեքի որոշ գործառույթների օգտագործումը:"</string>
+  <string-array name="phoneTypes">
+    <item msgid="8901098336658710359">"Տնային"</item>
+    <item msgid="869923650527136615">"Բջջային"</item>
+    <item msgid="7897544654242874543">"Աշխատանքային"</item>
+    <item msgid="1103601433382158155">"Աշխատանքային ֆաքս"</item>
+    <item msgid="1735177144948329370">"Տնային ֆաքս"</item>
+    <item msgid="603878674477207394">"Փեյջեր"</item>
+    <item msgid="1650824275177931637">"Այլ"</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>
+  </string-array>
+  <string-array name="postalAddressTypes">
+    <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="1359644565647383708">"Աշխատանքային"</item>
+    <item msgid="7868549401053615677">"Այլ"</item>
+    <item msgid="3145118944639869809">"Հատուկ"</item>
+  </string-array>
+  <string-array name="organizationTypes">
+    <item msgid="7546335612189115615">"Աշխատանքային"</item>
+    <item msgid="4378074129049520373">"Այլ"</item>
+    <item msgid="3455047468583965104">"Հատուկ"</item>
+  </string-array>
+  <string-array name="imProtocols">
+    <item msgid="8595261363518459565">"AIM"</item>
+    <item msgid="7390473628275490700">"Windows Live"</item>
+    <item msgid="7882877134931458217">"Yahoo"</item>
+    <item msgid="5035376313200585242">"Skype"</item>
+    <item msgid="7532363178459444943">"QQ"</item>
+    <item msgid="3713441034299660749">"Google Talk"</item>
+    <item msgid="2506857312718630823">"ICQ"</item>
+    <item msgid="1648797903785279353">"Jabber"</item>
+  </string-array>
+    <string name="phoneTypeCustom" msgid="1644738059053355820">"Հատուկ"</string>
+    <string name="phoneTypeHome" msgid="2570923463033985887">"Տնային"</string>
+    <string name="phoneTypeMobile" msgid="6501463557754751037">"Բջջային"</string>
+    <string name="phoneTypeWork" msgid="8863939667059911633">"Աշխատանքային"</string>
+    <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Աշխատանքային ֆաքս"</string>
+    <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Տնային ֆաքս"</string>
+    <string name="phoneTypePager" msgid="7582359955394921732">"Փեյջեր"</string>
+    <string name="phoneTypeOther" msgid="1544425847868765990">"Այլ"</string>
+    <string name="phoneTypeCallback" msgid="2712175203065678206">"Ետզանգ"</string>
+    <string name="phoneTypeCar" msgid="8738360689616716982">"Մեքենա"</string>
+    <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Ընկերության գլխավոր"</string>
+    <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string>
+    <string name="phoneTypeMain" msgid="6766137010628326916">"Հիմնական"</string>
+    <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Այլ ֆաքս"</string>
+    <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="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="eventTypeBirthday" msgid="2813379844211390740">"Ծննդյան օր"</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>
+    <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="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="imTypeWork" msgid="1371489290242433090">"Աշխատանքային"</string>
+    <string name="imTypeOther" msgid="5377007495735915478">"Այլ"</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>
+    <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
+    <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</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>
+    <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="relationTypeAssistant" msgid="6274334825195379076">"Օգնական"</string>
+    <string name="relationTypeBrother" msgid="8757913506784067713">"Եղբայր"</string>
+    <string name="relationTypeChild" msgid="1890746277276881626">"Երեխա"</string>
+    <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"Տեղական գործընկեր"</string>
+    <string name="relationTypeFather" msgid="5228034687082050725">"Հայր"</string>
+    <string name="relationTypeFriend" msgid="7313106762483391262">"Ընկեր"</string>
+    <string name="relationTypeManager" msgid="6365677861610137895">"Կառավարիչ"</string>
+    <string name="relationTypeMother" msgid="4578571352962758304">"Մայր"</string>
+    <string name="relationTypeParent" msgid="4755635567562925226">"Ծնող"</string>
+    <string name="relationTypePartner" msgid="7266490285120262781">"Գործընկեր"</string>
+    <string name="relationTypeReferredBy" msgid="101573059844135524">"Հղված է"</string>
+    <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="sipAddressTypeHome" msgid="6093598181069359295">"Տնային"</string>
+    <string name="sipAddressTypeWork" msgid="6920725730797099047">"Աշխատանքային"</string>
+    <string name="sipAddressTypeOther" msgid="4408436162950119849">"Այլ"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Մուտքագրեք PIN կոդը"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Մուտքագրեք PUK-ը և նոր PIN կոդը"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK կոդ"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Նոր PIN ծածկագիր"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><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">"Մուտքագրեք PIN-ը ապակողպման համար"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Սխալ PIN ծածկագիր:"</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="8963839242565653192">"Ծառայություն չկա:"</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="5347633784401285225">"Արտակարգ իրավիճակների հեռախոսազանգ"</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="faceunlock_multiple_failures" msgid="754137583022792429">"Առավելագույն Դեմքով ապակողպման փորձերը գերազանցված են"</string>
+    <string name="lockscreen_plugged_in" msgid="8057762828355572315">"Լիցքավորում, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_charged" msgid="321635745684060624">"Լիցքավորված է"</string>
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_low_battery" msgid="1482873981919249740">"Միացրեք ձեր լիցքավորիչը:"</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="default" msgid="2186920585695169078">"Հեռախոսում SIM քարտ չկա:"</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_transport_prev_description" msgid="201594905152746886">"Նախորդ հետքի կոճակ"</string>
+    <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Հաջորդ հետագծի կոճակ"</string>
+    <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Դադարի կոճակ"</string>
+    <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Նվագարկման կոճակ"</string>
+    <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Կանգի կոճակ"</string>
+    <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">"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">%d</xliff:g> անգամ սխալ եք հավաքել ձեր ապակողպման սխեման: \n\nՓորձեք կրկին <xliff:g id="NUMBER_1">%d</xliff:g> վայրկյանից:"</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Դուք սխալ եք մուտքագրել ձեր գաղտնաբառը <xliff:g id="NUMBER_0">%d</xliff:g> անգամ: \n\n Փորձեք կրկին <xliff:g id="NUMBER_1">%d</xliff:g> վայրկյանից:"</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ եք մուտքագրել ձեր PIN-ը: \n\nՓորձեք կրկին <xliff:g id="NUMBER_1">%d</xliff:g> վայրկյանից:"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ եք հավաքել ձեր ապակողպման սխեման: <xliff:g id="NUMBER_1">%d</xliff:g> անգամից ավել անհաջող փորձերից հետո ձեզ կառաջարկվի ապակողպել ձեր գրասալիկը` օգտագործելով ձեր Google-ի մուտքի օգտանունը:\n \n Փորձեք կրկին <xliff:g id="NUMBER_2">%d</xliff:g> վայրկյանից:"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ եք հավաքել ձեր ապակողպման սխեման: Եվս <xliff:g id="NUMBER_1">%d</xliff:g> անհաջող փորձից հետո ձեզ կառաջարկվի ապակողպել ձեր հեռախոսը` օգտագործելով Google-ի ձեր մուտքը:\n \n Փորձեք կրկին <xliff:g id="NUMBER_2">%d</xliff:g> վայրկյանից:"</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ գրասալիկն ապակողպելու սխալ փորձ եք արել: Եվս <xliff:g id="NUMBER_1">%d</xliff:g> անհաջող փորձից հետո գրասալիկը կվերակարգավորվի գործարանային լռելյայնի, և օգտվողի բոլոր տվյալները կկորեն:"</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ հեռախոսը ապակողպելու սխալ փորձ եք արել: Եվս <xliff:g id="NUMBER_1">%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="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_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_checking_password" msgid="7114627351286933867">"Ստուգվում է..."</string>
+    <string name="lockscreen_unlock_label" msgid="737440483220667054">"Ապակողպել"</string>
+    <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Ձայնը միացնել"</string>
+    <string name="lockscreen_sound_off_label" msgid="996822825154319026">"Անձայն"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Սխեմայի հավաքումը սկսված է"</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Սխեման մաքրված է"</string>
+    <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Ավելացվել է վանդակ"</string>
+    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Սխեմայի հավաքումն ավարտված է"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Վիջեթ %2$d of %3$d:"</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_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>
+    <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_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">"Pin-ն ապակողպված է:"</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>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <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_line" msgid="5764267235026120888">"գիծ"</string>
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</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_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="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>
+    <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
+    <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
+    <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
+    <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
+    <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_county" msgid="237073771020362891">"Մարզ"</string>
+    <string name="autofill_island" msgid="4020100875984667025">"Կղզի"</string>
+    <string name="autofill_district" msgid="8400735073392267672">"Շրջան"</string>
+    <string name="autofill_department" msgid="5343279462564453309">"Դեպարտամենտ"</string>
+    <string name="autofill_prefecture" msgid="2028499485065800419">"Պրեֆեկտուրա"</string>
+    <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="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_packageVerificationAgent" msgid="5568139100645829117">"հաստատել փաթեթները"</string>
+    <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"Թույլ է տալիս հավելվածին հաստատել, որ փաթեթը տեղադրելի է:"</string>
+    <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"միանալ փաթեթի ստուգիչին"</string>
+    <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Թույլ է տալիս սեփականատիրոջը փաթեթի ստուգիչների հարցում կատարել: Սովորական հավելվածների համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+    <string name="permlab_serialPort" msgid="546083327654631076">"մուտք գործել հաջորդական միացքներ"</string>
+    <string name="permdesc_serialPort" msgid="2991639985224598193">"Թույլ է տալիս սեփականատիրոջը մուտք գործել հաջորդական միացքներ` օգտագործելով SerialManager API-ը:"</string>
+    <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"դրսից մատչել բովանդակություն տրամադրողներին"</string>
+    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Սեփականատիրոջը հնարավորություն է տալիս կապվել ծառայության մատակարարների հետ վահանակից: Սովորական հավելվածների համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+    <string name="permlab_updateLock" msgid="3527558366616680889">"կասեցնել սարքի ավտոմատ թարմացումները"</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"Թույլ է տալիս սեփականատիրոջը համակարգին տեղեկացնել հարմար ժամանակի մասին` սարքը նորացնելու նպատակով ոչ փոխազդական վերաբեռնման համար:"</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>
+    <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="menu_space_shortcut_label" msgid="2410328639272162537">"բացակ"</string>
+    <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"մուտք"</string>
+    <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"ջնջել"</string>
+    <string name="search_go" msgid="8298016669822141719">"Որոնել"</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="oneMonthDurationPast" msgid="7396384508953779925">"1 ամիս առաջ"</string>
+    <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Ավելի շուտ քան 1 ամիս"</string>
+  <plurals name="num_seconds_ago">
+    <item quantity="one" msgid="4869870056547896011">"1 վայրկյան առաջ"</item>
+    <item quantity="other" msgid="3903706804349556379">"<xliff:g id="COUNT">%d</xliff:g> վայրկյան առաջ"</item>
+  </plurals>
+  <plurals name="num_minutes_ago">
+    <item quantity="one" msgid="3306787433088810191">"1 րոպե առաջ"</item>
+    <item quantity="other" msgid="2176942008915455116">"<xliff:g id="COUNT">%d</xliff:g> րոպե առաջ"</item>
+  </plurals>
+  <plurals name="num_hours_ago">
+    <item quantity="one" msgid="9150797944610821849">"1 ժամ առաջ"</item>
+    <item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> ժամ առաջ"</item>
+  </plurals>
+  <plurals name="last_num_days">
+    <item quantity="other" msgid="3069992808164318268">"Վերջին <xliff:g id="COUNT">%d</xliff:g> օրերին"</item>
+  </plurals>
+    <string name="last_month" msgid="3959346739979055432">"Անցյալ ամիս"</string>
+    <string name="older" msgid="5211975022815554840">"Ավելի հին"</string>
+  <plurals name="num_days_ago">
+    <item quantity="one" msgid="861358534398115820">"երեկ"</item>
+    <item quantity="other" msgid="2479586466153314633">"<xliff:g id="COUNT">%d</xliff:g> օր առաջ"</item>
+  </plurals>
+  <plurals name="in_num_seconds">
+    <item quantity="one" msgid="2729745560954905102">"1 վայրկյանից"</item>
+    <item quantity="other" msgid="1241926116443974687">"<xliff:g id="COUNT">%d</xliff:g> վայրկյանից"</item>
+  </plurals>
+  <plurals name="in_num_minutes">
+    <item quantity="one" msgid="8793095251325200395">"1 րոպեից"</item>
+    <item quantity="other" msgid="3330713936399448749">"<xliff:g id="COUNT">%d</xliff:g> րոպեից"</item>
+  </plurals>
+  <plurals name="in_num_hours">
+    <item quantity="one" msgid="7164353342477769999">"1 ժամից"</item>
+    <item quantity="other" msgid="547290677353727389">"<xliff:g id="COUNT">%d</xliff:g> ժամից"</item>
+  </plurals>
+  <plurals name="in_num_days">
+    <item quantity="one" msgid="5413088743009839518">"վաղը"</item>
+    <item quantity="other" msgid="5109449375100953247">"<xliff:g id="COUNT">%d</xliff:g> օրից"</item>
+  </plurals>
+  <plurals name="abbrev_num_seconds_ago">
+    <item quantity="one" msgid="1849036840200069118">"1 վրկ առաջ"</item>
+    <item quantity="other" msgid="3699169366650930415">"<xliff:g id="COUNT">%d</xliff:g> վրկ. առաջ"</item>
+  </plurals>
+  <plurals name="abbrev_num_minutes_ago">
+    <item quantity="one" msgid="6361490147113871545">"1 րոպե առաջ"</item>
+    <item quantity="other" msgid="851164968597150710">"<xliff:g id="COUNT">%d</xliff:g> րոպե առաջ"</item>
+  </plurals>
+  <plurals name="abbrev_num_hours_ago">
+    <item quantity="one" msgid="4796212039724722116">"1 ժամ առաջ"</item>
+    <item quantity="other" msgid="6889970745748538901">"<xliff:g id="COUNT">%d</xliff:g> ժամ առաջ"</item>
+  </plurals>
+  <plurals name="abbrev_num_days_ago">
+    <item quantity="one" msgid="8463161711492680309">"երեկ"</item>
+    <item quantity="other" msgid="3453342639616481191">"<xliff:g id="COUNT">%d</xliff:g> օր առաջ"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_seconds">
+    <item quantity="one" msgid="5842225370795066299">"1 վրկ-ից"</item>
+    <item quantity="other" msgid="5495880108825805108">"<xliff:g id="COUNT">%d</xliff:g> վրկ-ից"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_minutes">
+    <item quantity="one" msgid="562786149928284878">"1 րոպեից"</item>
+    <item quantity="other" msgid="4216113292706568726">"<xliff:g id="COUNT">%d</xliff:g> րոպեից"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_hours">
+    <item quantity="one" msgid="3274708118124045246">"1 ժամից"</item>
+    <item quantity="other" msgid="3705373766798013406">"<xliff:g id="COUNT">%d</xliff:g> ժամից"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_days">
+    <item quantity="one" msgid="2178576254385739855">"վաղը"</item>
+    <item quantity="other" msgid="2973062968038355991">"<xliff:g id="COUNT">%d</xliff:g> օրից"</item>
+  </plurals>
+    <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>
+    <string name="days" msgid="4774547661021344602">"օր"</string>
+    <string name="hour" msgid="2126771916426189481">"ժամ"</string>
+    <string name="hours" msgid="894424005266852993">"ժամ"</string>
+    <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="week" msgid="5617961537173061583">"շաբաթ"</string>
+    <string name="weeks" msgid="6509623834583944518">"շաբաթ"</string>
+    <string name="year" msgid="4001118221013892076">"տարի"</string>
+    <string name="years" msgid="6881577717993213522">"տարի"</string>
+  <plurals name="duration_seconds">
+    <item quantity="one" msgid="6962015528372969481">"1 վայրկյան"</item>
+    <item quantity="other" msgid="1886107766577166786">"<xliff:g id="COUNT">%d</xliff:g> վայրկյան"</item>
+  </plurals>
+  <plurals name="duration_minutes">
+    <item quantity="one" msgid="4915414002546085617">"1 րոպե"</item>
+    <item quantity="other" msgid="3165187169224908775">"<xliff:g id="COUNT">%d</xliff:g> րոպե"</item>
+  </plurals>
+  <plurals name="duration_hours">
+    <item quantity="one" msgid="8917467491248809972">"1 ժամ"</item>
+    <item quantity="other" msgid="3863962854246773930">"<xliff:g id="COUNT">%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_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>
+    <string name="midnight" msgid="7166259508850457595">"կեսգիշեր"</string>
+    <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="cut" msgid="3092569408438626261">"Կտրել"</string>
+    <string name="copy" msgid="2681946229533511987">"Պատճենել"</string>
+    <string name="paste" msgid="5629880836805036433">"Տեղադրել"</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="textSelectionCABTitle" msgid="5236850394370820357">"Տեքստի ընտրություն"</string>
+    <string name="addToDictionary" msgid="4352161534510057874">"Ավելացնել բառարանում"</string>
+    <string name="deleteText" msgid="6979668428458199034">"Ջնջել"</string>
+    <string name="inputMethod" msgid="1653630062304567879">"Մուտքագրման եղանակը"</string>
+    <string name="editTextMenuTitle" msgid="4909135564941815494">"Տեքստի գործողությունները"</string>
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Պահոցային տարածքը սպառվում է"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Համակարգի որոշ գործառույթներ հնարավոր է չաշխատեն"</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="4653586947747330058">"Հպեք` լրացուցիչ տեղեկությունները կամ ծրագիրը դադարեցնելու համար:"</string>
+    <string name="ok" msgid="5970060430562524910">"Լավ"</string>
+    <string name="cancel" msgid="6442560571259935130">"Չեղարկել"</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>
+    <string name="capital_on" msgid="1544682755514494298">"I"</string>
+    <string name="capital_off" msgid="6815870386972805832">"O"</string>
+    <string name="whichApplication" msgid="4533185947064773386">"ավարտել գործողությունը` օգտագործելով"</string>
+    <string name="alwaysUse" msgid="4583018368000610438">"Օգտագործել լռելյայն այս գործողության համար:"</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="aerr_title" msgid="1905800560317137752"></string>
+    <string name="aerr_application" msgid="932628488013092776">"Ցավոք, <xliff:g id="APPLICATION">%1$s</xliff:g>-ը ընդհատվել է:"</string>
+    <string name="aerr_process" msgid="4507058997035697579">"Ցավոք, <xliff:g id="PROCESS">%1$s</xliff:g> գործընթացը դադարել է:"</string>
+    <string name="anr_title" msgid="4351948481459135709"></string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g>-ը չի արձագանքում:\n\nՑանկանու՞մ եք փակել այն:"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"<xliff:g id="ACTIVITY">%1$s</xliff:g> գործողությունը չի պատասխանում:\n\nՑանկանու՞մ եք այն փակել:"</string>
+    <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g>-ը չի արձագանքում: Ցանկանու՞մ եք փակել այն:"</string>
+    <string name="anr_process" msgid="6513209874880517125">"<xliff:g id="PROCESS">%1$s</xliff:g> գործընթացը չի արձագանքում:\n\nՑանկանու՞մ եք փակել այն:"</string>
+    <string name="force_close" msgid="8346072094521265605">"Լավ"</string>
+    <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_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">"Կրկին ակտիվացնել սա Համակարգի կարգավորումներում &amp;gt Ծրագրեր &gt; Ներբեռնումներ:"</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_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_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="1721681741617898865">"Հպեք` հավելվածին անցնելու համար"</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>
+    <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="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_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_notification" msgid="7044986546477282274">"Ծանուցումների ձայնի ուժգնությունը"</string>
+    <string name="ringtone_default" msgid="3789758980357696936">"Լռելյայն զանգերանգ"</string>
+    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Լռելյայն զանգերանգ (<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_unknown" msgid="5477919988701784788">"Անհայտ զանգերանգ"</string>
+  <plurals name="wifi_available">
+    <item quantity="one" msgid="6654123987418168693">"Wi-Fi ցանցը հասանելի է"</item>
+    <item quantity="other" msgid="4192424489168397386">"հասանելի են Wi-Fi ցանցեր"</item>
+  </plurals>
+  <plurals name="wifi_available_detailed">
+    <item quantity="one" msgid="1634101450343277345">"Բաց Wi-Fi ցանցը հասանելի է"</item>
+    <item quantity="other" msgid="7915895323644292768">"Հասանելի են բաց Wi-Fi ցանցեր"</item>
+  </plurals>
+    <string name="wifi_available_sign_in" msgid="4029489716605255386">"Մուտք գործեք Wi-Fi ցանց"</string>
+    <string name="network_available_sign_in" msgid="8495155593358054676">"Մուտք գործել ցանց"</string>
+    <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
+    <skip />
+    <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Չհաջողվեց միանալ Wi-Fi-ին"</string>
+    <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ունի թույլ ինտերնետ կապ:"</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_enabled_notification_message" msgid="1638949953993894335">"Հպեք կարգավորումների համար"</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_to_connect_title" msgid="4958803948658533637">"Միացման հրավեր"</string>
+    <string name="wifi_p2p_from_message" msgid="570389174731951769">"Ուղարկող`"</string>
+    <string name="wifi_p2p_to_message" msgid="248968974522044099">"Ում`"</string>
+    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"Մուտքագրեք պահանջվող PIN-ը:"</string>
+    <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN-ը`"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"Գրասալիկը ժամանակավորապես կանջատվի Wi-Fi-ից, քանի դեռ այն կապակցված է <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ին"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"Հեռախոսը ժամանակավորապես կանջատվի Wi-Fi-ից, քանի դեռ այն միացված է <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ին"</string>
+    <string name="select_character" msgid="3365550120617701745">"Զետեղել նշան"</string>
+    <string name="sms_control_title" msgid="7296612781128917719">"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="3492025719868078457">"Այս "<font fgcolor="#ffffb060">"-ը կարող է գանձումներ առաջացնել"</font>" ձեր բջջային հաշվի վրա:"</string>
+    <string name="sms_premium_short_code_details" msgid="5523826349105123687"><font fgcolor="#ffffb060">"Սրա հետևանքով ձեր բջջային հաշվին կներկայացվի հաշիվ:"</font></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_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_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="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_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="usb_storage_activity_title" msgid="4465055157209648641">"USB զանգվածային կրիչ"</string>
+    <string name="usb_storage_title" msgid="5901459041398751495">"USB-ն կապակցված  է"</string>
+    <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"Դուք կապակցվել եք ձեր համակարգչին USB-ի միջոցով: Հպեք ներքևի կոճակը, եթե ցանկանում եք պատճենել ֆայլերը ձեր համակարգչի և ձեր Android-ի USB կրիչի միջև:"</string>
+    <string name="usb_storage_message" product="default" msgid="805351000446037811">"Դուք միացել եք ձեր համակարգչին USB-ի միջոցով: Հպեք ներքևի կոճակին, եթե ցանկանում եք պատճենել ֆայլերը ձեր համակարգչի և ձեր Android-ի SD քարտի միջև:"</string>
+    <string name="usb_storage_button_mount" msgid="1052259930369508235">"Միացնել USB կրիչը"</string>
+    <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"Խնդիր է ծագել ձեր USB կրիչը USB զանգվածային կրիչի համար օգտագործելիս:"</string>
+    <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"Խնդիր է ծագել ձեր SD քարտը USB զանգվածային կրիչի համար օգտագործելիս:"</string>
+    <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB-ն կապակցված է"</string>
+    <string name="usb_storage_notification_message" msgid="939822783828183763">"Հպեք` ֆայլերը պատճենելու համար ձեր համակարգչում կամ համակարգչից:"</string>
+    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Անջատել USB կրիչը"</string>
+    <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"Հպեք` USB կրիչն անջատելու համար:"</string>
+    <string name="usb_storage_stop_title" msgid="660129851708775853">"USB կրիչը օգտագործվում է"</string>
+    <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"Նախքան USB կրիչն անջատելը, անջատեք («հանեք») ձեր Android-ի USB կրիչը համակարգչից:"</string>
+    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"Նախքան USB կրիչն անջատելը, անջատեք («հանեք») ձեր Android-ի SD քարտը համակարգչից:"</string>
+    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"Անջատել USB կրիչը"</string>
+    <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"Խնդիր առաջացավ USB կրիչն անջատելիս: Ստուգեք, արդյոք անջատել եք USB հանգույցը, ապա փորձեք կրկին:"</string>
+    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Միացնել USB կրիչը"</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Եթե ​​դուք միացնեք USB կրիչը, որոշ ծրագրեր,որոնցից օգտվում եք, կդադարեն աշխատել և կարող են անհասանելի լինել, քանի դեռ չեք անջատել USB կրիչը:"</string>
+    <string name="dlg_error_title" msgid="7323658469626514207">"USB գործողությունը անհաջող էր"</string>
+    <string name="dlg_ok" msgid="7376953167039865701">"Լավ"</string>
+    <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Կապակցված է որպես մեդիա սարք"</string>
+    <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Միացված է որպես ֆոտոխցիկ"</string>
+    <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Միացված է որպես տեղադրիչ"</string>
+    <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Կապակցված է USB լրասարքի"</string>
+    <string name="usb_notification_message" msgid="2290859399983720271">"Հպեք` այլ USB ընտրանքների համար:"</string>
+    <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Ֆորմատավորե՞լ USB կրիչը:"</string>
+    <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Ֆորմատավորե՞լ SD քարտը:"</string>
+    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Ձեր USB կրիչում պահվող բոլոր ֆայլերը կջնջվեն: Այս գործողությունը անշրջելի է:"</string>
+    <string name="extmedia_format_message" product="default" msgid="14131895027543830">"Ձեր քարտի բոլոր տվյալները կկորեն:"</string>
+    <string name="extmedia_format_button_format" msgid="4131064560127478695">"Ձևաչափ"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"USB վրիպազերծումը միացված է"</string>
+    <string name="adb_active_notification_message" msgid="1016654627626476142">"Հպեք` USB կարգաբերումը կասեցնելու համար:"</string>
+    <string name="select_input_method" msgid="4653387336791222978">"Ընտրեք մուտքագրման եղանակը"</string>
+    <string name="configure_input_methods" msgid="9091652157722495116">"Կարգավորել ներածման եղանակները"</string>
+    <string name="use_physical_keyboard" msgid="6203112478095117625">"Ֆիզիկական ստեղնաշար"</string>
+    <string name="hardware" msgid="7517821086888990278">"Սարքաշար"</string>
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Ընտրեք ստեղնաշարի դիրքը"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Հպեք` ստեղնաշարի դիրքը ընտրելու համար:"</string>
+    <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉՊՋՌՍՎՏՐՑՈՒՓՔԵւՕՖ"</string>
+    <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="candidates_style" msgid="4333913089637062257"><u>"թեկնածուները"</u></string>
+    <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"Պատրաստում է USB կրիչը"</string>
+    <string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"Պատրաստվում է SD քարտը"</string>
+    <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"Սխալների ստուգում:"</string>
+    <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"USB կրիչը դատարկ է"</string>
+    <string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"Դատարկ SD քարտ"</string>
+    <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"USB կրիչը դատարկ է կամ ունի չաջակցվող ֆայլային համակարգ:"</string>
+    <string name="ext_media_nofs_notification_message" product="default" msgid="8641065641786923604">"SD քարտը դատարկ է կամ ունի չաջակցվող ֆայլային համակարգ:"</string>
+    <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"Վնասված USB կրիչ"</string>
+    <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"Վնասված SD քարտ"</string>
+    <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="1795917578395333280">"USB կրիչը վնասված է: Փորձեք վերաֆորմատավորել այն:"</string>
+    <string name="ext_media_unmountable_notification_message" product="default" msgid="1753898567525568253">"SD քարտը վնասված է: Փորձեք վերաֆորմատավորել այն:"</string>
+    <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"USB կրիչն անսպասելիորեն հեռացվել է"</string>
+    <string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"SD քարտը անսպասելիորեն հեռացվել է"</string>
+    <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"Անջատել USB կրիչը հեռացնելուց առաջ` տվյալների կորստից խուսափելու համար:"</string>
+    <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"Անջատել SD քարտը հեռացնելուց առաջ` տվյալների կորստից խուսափելու համար:"</string>
+    <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"USB կրիչը կարող է անվտանգ հեռացվել"</string>
+    <string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"SD քարտն անվտանգ է հեռացման համար"</string>
+    <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"Դուք կարող եք ապահով հեռացնել USB կրիչը:"</string>
+    <string name="ext_media_safe_unmount_notification_message" product="default" msgid="568841278138377604">"Դուք կարող եք անվտանգ հեռացնել SD քարտը:"</string>
+    <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"USB կրիչը հեռացված է"</string>
+    <string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"SD քարտը հեռացված է"</string>
+    <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"USB կրիչը հեռացված է: Մտցրեք նոր կրիչ:"</string>
+    <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"SD քարտը հեռացված է: Տեղադրեք նորը:"</string>
+    <string name="activity_list_empty" msgid="1675388330786841066">"Համընկնող գործունեություններ չգտնվեցին:"</string>
+    <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"թարմացնել բաղադրիչի օգտագործման վիճակագրությունը"</string>
+    <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"Թույլ է տալիս հավելվածին փոփոխել հավաքագրված բաղադրիչի վիճակագրությունը: Սովորական հավելվածների օգտագործման համար չէ:"</string>
+    <string name="permlab_copyProtectedData" msgid="4341036311211406692">"պատճենել բովանդակությունը"</string>
+    <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Թույլ է տալիս հայցել լռելյայն զետեղարանի ծառայությունը` բովանդակությունը պատճենելու համար: Սովորական հավելվածների օգտագործման համար չէ:"</string>
+    <string name="permlab_route_media_output" msgid="1642024455750414694">"Երթուղել մեդիա արտածումը"</string>
+    <string name="permdesc_route_media_output" msgid="4932818749547244346">"Թույլ է տալիս հավելվածին մեդիա արտածումը երթուղել այլ արտաքին սարքեր:"</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Մուտք գործել ստեղնակողպեքով պաշտպանված պահոց"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Թույլ է տալիս հավելվածին մուտք գործել ստեղնակողպեքով պաշտպանված պահոց:"</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Կառավարել ստեղնակողպեքի ցուցադրումը և թաքցնումը"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Թույլ է տալիս հավելվածին կառավարել ստեղնաշարի պաշտպանիչը:"</string>
+    <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Հպեք երկու անգամ` դիտափոխման կարգավորման համար"</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>
+    <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">"Հավաքել հեռախոսահամարը`\nօգտագործելով <xliff:g id="NUMBER">%s</xliff:g>-ը"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Ստեղծել կոնտակտ`\nօգտագործելով <xliff:g id="NUMBER">%s</xliff:g>-ը"</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Հետևյալ մեկ կամ ավել հավելվածներ մուտքի թույլտվության հարցում են անում` այժմ և հետագայում ձեր հաշվին մուտք ունենալու համար:"</string>
+    <string name="grant_credentials_permission_message_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">"Թույլտվության հարցում է արված\n<xliff:g id="ACCOUNT">%s</xliff:g> հաշվի համար:"</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>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"Փոխել պաստառը"</string>
+    <string name="notification_listener_binding_label" msgid="2014162835481906429">"Ծանուցման ունկնդիր"</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="3011306607126450322">"Հպեք` ցանցի կառավարման համար:"</string>
+    <string name="vpn_text_long" msgid="6407351006249174473">"Միացված է <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_error" msgid="6009249814034708175">"VPN սխալը միշտ միացված"</string>
+    <string name="vpn_lockdown_config" msgid="6415899150671537970">"Հպեք կարգավորելու համար"</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="8035230537563503262">"Հպեք` մեքենայի ռեժիմից դուրս գալու համար:"</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"Մուտքը կամ թեժ կետը ակտիվ է"</string>
+    <string name="tethered_notification_message" msgid="6857031760103062982">"Հպեք կարգավորելու համար:"</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="throttle_warning_notification_title" msgid="4890894267454867276">"Շարժական տվյալների օգտագործման բարձր մակարդակ"</string>
+    <string name="throttle_warning_notification_message" msgid="3340822228599337743">"Հպեք` շարժական տվյալների օգտագործման մասին ավելին իմանալու համար:"</string>
+    <string name="throttled_notification_title" msgid="6269541897729781332">"Շարժական տվյալների սահմանը գերազանցված է"</string>
+    <string name="throttled_notification_message" msgid="5443457321354907181">"Հպել` շարժական տվյալների օգտագործման մասին ավելին իմանալու համար:"</string>
+    <string name="no_matches" msgid="8129421908915840737">"Համընկնում չկա"</string>
+    <string name="find_on_page" msgid="1946799233822820384">"Գտեք էջում"</string>
+  <plurals name="matches_found">
+    <item quantity="one" msgid="8167147081136579439">"1 համընկնում"</item>
+    <item quantity="other" msgid="4641872797067609177">"<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="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"Անջատվում է USB կրիչը..."</string>
+    <string name="progress_unmounting" product="default" msgid="1327894998409537190">"Անջատում է SD քարտը..."</string>
+    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"Ջնջում է USB կրիչը..."</string>
+    <string name="progress_erasing" product="default" msgid="6596988875507043042">"Ջնջում է SD քարտը..."</string>
+    <string name="format_error" product="nosdcard" msgid="6299769563624776948">"Չհաջողվեց ջնջել USB կրիչը:"</string>
+    <string name="format_error" product="default" msgid="7315248696644510935">"SD քարտը չհաջողվեց ջնջել:"</string>
+    <string name="media_bad_removal" msgid="7960864061016603281">"SD քարտը հեռացվել է նախքան անջատելը:"</string>
+    <string name="media_checking" product="nosdcard" msgid="418188720009569693">"USB կրիչն այժմ ստուգվում է:"</string>
+    <string name="media_checking" product="default" msgid="7334762503904827481">"SD քարտը այժմ ստուգվում է:"</string>
+    <string name="media_removed" msgid="7001526905057952097">"SD քարտը հեռացվել է:"</string>
+    <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"USB կրիչն այժմ օգտագործվում է համակարգչի կողմից:"</string>
+    <string name="media_shared" product="default" msgid="5706130568133540435">"SD քարտն այժմ օգտագործվում է համակարգչի կողմից:"</string>
+    <string name="media_unknown_state" msgid="729192782197290385">"Արտաքին մեդիան անհայտ է վիճակում է:"</string>
+    <string name="share" msgid="1778686618230011964">"Տարածել"</string>
+    <string name="find" msgid="4808270900322985960">"Գտնել"</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="gpsNotifMessage" msgid="1374718023224000702">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)-ի հարցմամբ"</string>
+    <string name="gpsVerifYes" msgid="2346566072867213563">"Այո"</string>
+    <string name="gpsVerifNo" msgid="1146564937346454865">"Ոչ"</string>
+    <string name="sync_too_many_deletes" msgid="5296321850662746890">"Ջնջելու սահմանը գերազանցվել է"</string>
+    <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> ջնջված տարր կա <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>-ի համար, <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>-ի հաշիվ: Ի՞նչ եք ցանկանում անել:"</string>
+    <string name="sync_really_delete" msgid="2572600103122596243">"Ջնջել տարրերը"</string>
+    <string name="sync_undo_deletes" msgid="2941317360600338602">"Հետարկել ջնջումները"</string>
+    <string name="sync_do_nothing" msgid="3743764740430821845">"Առայժմ ոչինչ չանեք"</string>
+    <string name="choose_account_label" msgid="5655203089746423927">"Ընտրել հաշիվը"</string>
+    <string name="add_account_label" msgid="2935267344849993553">"Ավելացնել հաշիվ"</string>
+    <string name="add_account_button_label" msgid="3611982894853435874">"Ավելացնել հաշիվ"</string>
+    <string name="number_picker_increment_button" msgid="2412072272832284313">"Ավելացնել"</string>
+    <string name="number_picker_decrement_button" msgid="476050778386779067">"Նվազեցնել"</string>
+    <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> հպեք և պահեք:"</string>
+    <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Սահեցրեք վերև` ավելացնելու համար, և ներքև` նվազեցնելու համար:"</string>
+    <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Աճեցնել րոպեն"</string>
+    <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Նվազեցնել րոպեն"</string>
+    <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Աճեցնել ժամը"</string>
+    <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Նվազեցնել ժամը"</string>
+    <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Դնել PM"</string>
+    <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Դնել AM"</string>
+    <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Աճեցնել ամիսը"</string>
+    <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Նվազեցնել ամիսը"</string>
+    <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Աճեցնել օրը"</string>
+    <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Նվազեցնել օրը"</string>
+    <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Աճեցնել տարին"</string>
+    <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Նվազեցնել տարին"</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_enter" msgid="2985864015076059467">"Մուտք"</string>
+    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Ընտրել ծրագիր"</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_direction_up" msgid="7169032478259485180">"Սահեցրեք վերև <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-ի համար:"</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Սահեցրեք ցած <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="description_direction_right" msgid="8034433242579600980">"Սահեցրեք աջ` <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-ի համար:"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Ապակողպել"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Ֆոտոխցիկ"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Լուռ"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Ձայնը միացնել"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Որոնել"</string>
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Սահեցրեք` ապակողպելու համար:"</string>
+    <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Միացրեք ականջակալները` արտասանվող գաղտնաբառը լսելու համար:"</string>
+    <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Կետ:"</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="4891916833657929263">"Ներքին պահոց"</string>
+    <string name="storage_sd_card" msgid="3282948861378286745">"SD քարտ"</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="1955638862122232342">"Տվյալների օգտագործման նախազգուշացում"</string>
+    <string name="data_usage_warning_body" msgid="2814673551471969954">"Հպեք` օգտագործումը և կարգավորումները տեսնելու համար:"</string>
+    <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-3G տվյալները կասեցված են"</string>
+    <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G տվյալները անջատված են"</string>
+    <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Շարժական տվյալները կասեցված են"</string>
+    <string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"Wi-Fi տվյալները անջատված են"</string>
+    <string name="data_usage_limit_body" msgid="3317964706973601386">"Հպեք` միացնելու համար:"</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_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="6741521330997452990">"Հպեք` սահմանափակումը հեռացնելու համար:"</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>
+    <string name="org_unit" msgid="7265981890422070383">"Կազմակերպական միավոր`"</string>
+    <string name="issued_by" msgid="2647584988057481566">"Թողարկվել է`"</string>
+    <string name="validity_period" msgid="8818886137545983110">"Վավերականություն`"</string>
+    <string name="issued_on" msgid="5895017404361397232">"Թողարկվել է`"</string>
+    <string name="expires_on" msgid="3676242949915959821">"Սպառվում է`"</string>
+    <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>
+    <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Տեսնել բոլորը"</string>
+    <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Ընտրել գործունեությունը"</string>
+    <string name="share_action_provider_share_with" msgid="5247684435979149216">"Տարածել"</string>
+    <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="3245653681008218030">"Ուղարկվում է..."</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="default_audio_route_name" product="tablet" msgid="4617053898167127471">"Գրասալիկ"</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="media_route_chooser_grouping_done" msgid="7966438307723317169">"Կատարված է"</string>
+    <string name="media_route_button_content_description" msgid="5758553567065145276">"Մեդիա արտածում"</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>
+    <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_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>. <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> կմվ"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", անվտանգ"</string>
+    <string name="wifi_display_notification_title" msgid="2223050649240326557">"Անլար ցուցադրումը կապակցված է"</string>
+    <string name="wifi_display_notification_message" msgid="4498802012464170685">"Այս էկրանը ցուցադրվում է այլ սարքում"</string>
+    <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Անջատել"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Արտակարգ իրավիճակի հեռախոսազանգ"</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">"Սխալ PIN"</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">"Մուտքագրեք SIM-ի PIN-ը"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Մուտքագրեք PIN-ը"</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">"Մուտքագրեք ցանկալի PIN ծածկագիրը"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Հաստատեք ցանկալի PIN ծածկագիրը"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Ապակողպում է SIM քարտը ..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Սխալ PIN ծածկագիր:"</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Մուտքագրեք PIN, որը 4-ից 8 թիվ է:"</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK կոդը պետք է լինի 8 կամ ավելի թիվ:"</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Վերամուտքագրեք ճիշտ PUK ծածկագիրը: Կրկնվող փորձերը ընդմիշտ կկասեցնեն SIM քարտը:"</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN ծածկագրերը չեն համընկնում"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Չափից շատ սխեմայի փորձեր"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Ապակողպելու համար` մուտք գործեք ձեր Google հաշվով:"</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"Հաշիվը ստուգվում է..."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ եք մուտքագրել ձեր PIN-ը: \n\nՓորձեք կրկին <xliff:g id="NUMBER_1">%d</xliff:g> վայրկյանից:"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Դուք սխալ եք մուտքագրել ձեր գաղտնաբառը <xliff:g id="NUMBER_0">%d</xliff:g> անգամ: \n\nՓորձեք կրկին <xliff:g id="NUMBER_1">%d</xliff:g> վայրկյանից:"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ եք հավաքել ձեր ապակողպման սխեման: \n\nՓորձեք կրկին <xliff:g id="NUMBER_1">%d</xliff:g> վայրկյանից:"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ փորձ եք արել գրասալիկն ապակողպելու համար: <xliff:g id="NUMBER_1">%d</xliff:g> անգամից ավել անհաջող փորձերից հետո գրասալիկը կվերակարգավորվի գործարանային լռելյայնի, և օգտվողի բոլոր տվյալները կկորեն:"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ փորձ եք արել հեռախոսն ապակողպելու համար: <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> անգամ: Եվս <xliff:g id="NUMBER_1">%d</xliff:g> անհաջող փորձից հետո ձեզանից կպահանջվի ապակողպել ձեր գրասալիկը` օգտագործելով էլփոստի հաշիվ:\n\n Փորձեք կրկին <xliff:g id="NUMBER_2">%d</xliff:g> վայրկյանից:"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ եք հավաքել ձեր ապակողպման նմուշը: <xliff:g id="NUMBER_1">%d</xliff:g> անգամից ավել անհաջող փորձերից հետո ձեզ կառաջարկվի ապակողպել ձեր հեռախոսը` օգտագործելով էլփոստի հաշիվ:\n\n Փորձեք կրկին <xliff:g id="NUMBER_2">%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="7324161939475478066">"Բարձրացնե՞լ ձայնը առաջարկվող շեմից բարձր:\nԵրկար ժամանակ բարձրաձայն լսելը կարող է վնասել ձեր լսողությունը:"</string>
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Սեղմած պահեք երկու մատները` մատչելիությունը միացնելու համար:"</string>
+    <string name="accessibility_enabled" msgid="1381972048564547685">"Մատչելիությունը միացված է:"</string>
+    <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Մուտքի հնարավորությունը չեղարկված է:"</string>
+    <string name="user_switched" msgid="3768006783166984410">"Ներկայիս օգտվողը <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="app_no_restricted_accounts" msgid="5739463249673727736">"Այս ծրագիրը չի աջակցում սահմանափակված պրոֆիլների հաշիվներ:"</string>
+    <string name="app_not_found" msgid="3429141853498927379">"Այս գործողությունը կատարելու համար ոչ մի ծրագիր չի գտնվել:"</string>
+    <string name="revoke" msgid="5404479185228271586">"Չեղարկել"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Չեղարկված է"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Բովանդակության գրելու սխալ"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"անհայտ"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Մուտքագրեք կառավարչի 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>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Նոր PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Հաստատեք նոր PIN-ը"</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_too_short" msgid="8173982756265777792">"PIN-ը չափազանց կարճ է: Պետք է ունենա առնվազն 4 թվանիշ:"</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Կրկին փորձեք 1 վայրկյանից"</item>
+    <item quantity="other" msgid="4730868920742952817">"Կրկին փորձեք <xliff:g id="COUNT">%d</xliff:g> վայրկյանից"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Կրկին փորձեք մի փոքր ուշ"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Սահեցրեք էկրանի եզրով՝ գոտին բացելու համար"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Սահեցրեք էկրանի եզրով՝ համակարգային գոտին բացելու համար"</string>
+</resources>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
new file mode 100644
index 0000000..60c5c55
--- /dev/null
+++ b/core/res/res/values-hy/strings.xml
@@ -0,0 +1,1586 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<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">"Բ"</string>
+    <string name="kilobyteShort" msgid="5973789783504771878">"Կբ"</string>
+    <string name="megabyteShort" msgid="6355851576770428922">"Մբ"</string>
+    <string name="gigabyteShort" msgid="3259882455212193214">"Գբ"</string>
+    <string name="terabyteShort" msgid="231613018159186962">"Տբ"</string>
+    <string name="petabyteShort" msgid="5637816680144990219">"Պբ"</string>
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
+    <string name="untitled" msgid="4638956954852782576">"&lt;Անանուն&gt;"</string>
+    <string name="ellipsis" msgid="7899829516048813237">"…"</string>
+    <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
+    <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Հեռախոսահամար չկա)"</string>
+    <string name="unknownName" msgid="2277556546742746522">"(Անհայտ)"</string>
+    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Ձայնային փոստ"</string>
+    <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
+    <string name="mmiError" msgid="5154499457739052907">"Միացման խնդիր կամ անվավեր MMI ծածակագիր:"</string>
+    <string name="mmiFdnError" msgid="5224398216385316471">"Գործողությունը սահմանափակված է միայն ամրակայված հեռախոսահամարների համար:"</string>
+    <string name="serviceEnabled" msgid="8147278346414714315">"Ծառայությունը միացված է:"</string>
+    <string name="serviceEnabledFor" msgid="6856228140453471041">"Ծառայությունը միացված է`"</string>
+    <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="mmiComplete" msgid="8232527495411698359">"MMI-ը ավարտված է:"</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>
+    <string name="invalidPuk" msgid="8761456210898036513">"Մուտքագրեք PUK, որն 8 կամ ավել թիվ ունի:"</string>
+    <string name="needPuk" msgid="919668385956251611">"Ձեր SIM քարտը PUK-ով կողպված է: Մուտքագրեք PUK կոդը այն ապակողպելու համար:"</string>
+    <string name="needPuk2" msgid="4526033371987193070">"Մուտքագրեք PUK2-ը` SIM քարտն արգելաբացելու համար:"</string>
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
+    <string name="ClipMmi" msgid="6952821216480289285">"Մուտքային զանգողի ID"</string>
+    <string name="ClirMmi" msgid="7784673673446833091">"Ելքային զանգողի ID"</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">"PIN-ի փոփոխություն"</string>
+    <string name="CnipMmi" msgid="3110534680557857162">"Զանգող համարը առկա է"</string>
+    <string name="CnirMmi" msgid="3062102121430548731">"Զանգող հեռախոսահամարը սահմանափակված է"</string>
+    <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="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="RestrictedChangedTitle" msgid="5592189398956187498">"Սահմանափակված մուտքը փոխված է"</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="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>
+    <string name="serviceClassDataSync" msgid="7530000519646054776">"Համաժամել"</string>
+    <string name="serviceClassPacket" msgid="6991006557993423453">"Փաթեթ"</string>
+    <string name="serviceClassPAD" msgid="3235259085648271037">"Հարթակ"</string>
+    <string name="roamingText0" msgid="7170335472198694945">"Ռոումինգի ցուցիչը միացված է"</string>
+    <string name="roamingText1" msgid="5314861519752538922">"Ռոումինգի ցուցիչը անջատված է"</string>
+    <string name="roamingText2" msgid="8969929049081268115">"Ռոումինգի ցուցիչը թարթում է"</string>
+    <string name="roamingText3" msgid="5148255027043943317">"Շրջակայքից դուրս"</string>
+    <string name="roamingText4" msgid="8808456682550796530">"Շենքից դուրս"</string>
+    <string name="roamingText5" msgid="7604063252850354350">"Ռոումինգ` նախընտրելի համակարգ"</string>
+    <string name="roamingText6" msgid="2059440825782871513">"Ռոումինգ` հասանելի համակարգ"</string>
+    <string name="roamingText7" msgid="7112078724097233605">"Ռոումինգ` դաշնային գործընկեր"</string>
+    <string name="roamingText8" msgid="5989569778604089291">"Ռոումինգ` առաջնակարգ գործընկեր"</string>
+    <string name="roamingText9" msgid="7969296811355152491">"Ռոումինգ` լիարժեք ծառայության գործառություն"</string>
+    <string name="roamingText10" msgid="3992906999815316417">"Ռոումինգ` Մասնակի ծառայության գործառություն"</string>
+    <string name="roamingText11" msgid="4154476854426920970">"Ռոումինգի ազդերիզը միացված է"</string>
+    <string name="roamingText12" msgid="1189071119992726320">"Ռոումինգի ազդերիզն անջատված է"</string>
+    <string name="roamingTextSearching" msgid="8360141885972279963">"Ծառայության որոնում..."</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="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="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="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="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="default" msgid="3475999286680000541">"Հեռախոսի պահոցը լիքն է: Ջնջեք մի քանի ֆայլեր` տարածություն ազատելու համար:"</string>
+    <string name="me" msgid="6545696007631404292">"Իմ"</string>
+    <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Գրասալիկի ընտրանքները"</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="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="shutdown_progress" msgid="2281079257329981203">"Անջատվում է…"</string>
+    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Ձեր գրասալիկը կանջատվի:"</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="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_bug_report" msgid="7934010578922304799">"Վրիպակի զեկույց"</string>
+    <string name="bugreport_title" msgid="2667494803742548533">"Գրել սխալի զեկույց"</string>
+    <string name="bugreport_message" msgid="398447048750350456">"Սա տեղեկություններ կհավաքագրի ձեր սարքի առկա կարգավիճակի մասին և կուղարկի այն էլեկտրոնային նամակով: Որոշակի ժամանակ կպահանջվի վրիպակի մասին զեկուցելու պահից սկսած մինչ ուղարկելը: Խնդրում ենք փոքր-ինչ համբերատար լինել:"</string>
+    <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_airplane_mode_on_status" msgid="2719557982608919750">"Ինքնաթիռային ռեժիմը միացված է"</string>
+    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Ինքնաթիռային ռեժիմը անջատված է"</string>
+    <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
+    <string name="safeMode" msgid="2788228061547930246">"Անվտանգ ռեժիմ"</string>
+    <string name="android_system_label" msgid="6577375335728551336">"Android համակարգ"</string>
+    <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Ծառայություններ, որոնց համար կգանձվեք"</string>
+    <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Կատարել գործողություններ, որի դիմաց ձեր հաշվից գումար կծախսվի:"</string>
+    <string name="permgrouplab_messages" msgid="7521249148445456662">"Ձեր հաղորդագրությունները"</string>
+    <string name="permgroupdesc_messages" msgid="7821999071003699236">"Կարդալ և գրել ձեր SMS-ը, նամակը և այլ հաղորդագրություններ:"</string>
+    <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Ձեր անձնական տեղեկությունները"</string>
+    <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"Ուղղակի մուտք ձեր մասին տեղեկություններ` պահված ձեր կոնտակտային քարտում:"</string>
+    <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Ձեր սոցիալական տեղեկությունները"</string>
+    <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Ուղղակի մուտք ձեր կոնտակտների մասին տեղեկություններ և սոցիալական կապեր:"</string>
+    <string name="permgrouplab_location" msgid="635149742436692049">"Ձեր տեղադրությունը"</string>
+    <string name="permgroupdesc_location" msgid="5704679763124170100">"Վերահսկել ձեր ֆիզիկական տեղադրությունը:"</string>
+    <string name="permgrouplab_network" msgid="5808983377727109831">"Ցանցային հաղորդակցություն"</string>
+    <string name="permgroupdesc_network" msgid="4478299413241861987">"Մուտք գործել ցանցի տարբեր գործառույթներ:"</string>
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"Bluetooth"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"Մուտք գործել սարքեր և ցանցեր Bluetooth-ի միջոցով:"</string>
+    <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"Ձայնանյութի կարգավորումներ"</string>
+    <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"Փոխել ձայնանյութի կարգավորումները:"</string>
+    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Ազդում է մարտկոցի վրա"</string>
+    <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Օգտագործել գործիքները, որոնք կարող են արագ սպառել մարտկոցը:"</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"Օրացույց"</string>
+    <string name="permgroupdesc_calendar" msgid="5777534316982184416">"Անմիջական մուտք օրացույց և իրադարձություններ:"</string>
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"Կարդալ օգտվողի բառարանը"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"Կարդալ բառերը օգտվողի բառարանում:"</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"Գրել օգտվողի բառարանում"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"Ավելացնել բառեր օգտվողի բառարանում:"</string>
+    <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Էջանիշեր և պատմություն"</string>
+    <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Ուղղակի մուտք դեպի էջանիշեր և դիտարկչի պատմություն:"</string>
+    <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"Ազդանշան"</string>
+    <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"Կարգավորել զարթուցիչի ժամացույցը:"</string>
+    <string name="permgrouplab_voicemail" msgid="4162237145027592133">"Ձայնային փոստ"</string>
+    <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"Ուղղակի մուտք դեպի ձայնային փոստ:"</string>
+    <string name="permgrouplab_microphone" msgid="171539900250043464">"Բարձրախոս"</string>
+    <string name="permgroupdesc_microphone" msgid="7106618286905738408">"Ուղղակի մուտք դեպի բարձրախոս` ձայնանյութ ձայնագրելու համար:"</string>
+    <string name="permgrouplab_camera" msgid="4820372495894586615">"Ֆոտոխցիկ"</string>
+    <string name="permgroupdesc_camera" msgid="2933667372289567714">"Ուղղակի մուտք դեպի ֆոտոխցիկ` լուսանկարելու կամ տեսանկարելու համար:"</string>
+    <string name="permgrouplab_screenlock" msgid="8275500173330718168">"Կողպել էկրանը"</string>
+    <string name="permgroupdesc_screenlock" msgid="7067497128925499401">"Հնարավորություն ունի ազդելու ձեր սարքի կողպէկրանի ռեժիմի վրա:"</string>
+    <string name="permgrouplab_appInfo" msgid="8028789762634147725">"Ձեր հավելվածների տեղեկությունները"</string>
+    <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"Հնարավորություն` ազդելու մյուս հավելվածների վարքագծի վրա ձեր սարքում:"</string>
+    <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"Պաստառ"</string>
+    <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"Փոխել սարքի պաստառի կարգավորումները:"</string>
+    <string name="permgrouplab_systemClock" msgid="406535759236612992">"Ժամացույց"</string>
+    <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"Փոխել սարքի ժամը կամ ժամային գոտին:"</string>
+    <string name="permgrouplab_statusBar" msgid="2095862568113945398">"Կարգավիճակի գոտի"</string>
+    <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"Փոխել սարքի կարգավիճակի գոտու կարգավորումները:"</string>
+    <string name="permgrouplab_syncSettings" msgid="3341990986147826541">"Համաժամեցման կարգավորումներ"</string>
+    <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"Մուտք գործել համաժամեցման կարգավորումներ:"</string>
+    <string name="permgrouplab_accounts" msgid="3359646291125325519">"Ձեր հաշիվները"</string>
+    <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Մուտքի հնարավորություն առկա հաշիվներ:"</string>
+    <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Սարքաշարի կարգավորումներ"</string>
+    <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Անմիջական մուտք հեռախոսի սարքաշար:"</string>
+    <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Հեռախոսային զանգերը"</string>
+    <string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"Վերահսկել, ձայնագրելել և կատարել հեռախոսազանգեր:"</string>
+    <string name="permgrouplab_systemTools" msgid="4652191644082714048">"Համակարգի գործիքները"</string>
+    <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"Համակարգի ավելի ցածր մակարդակի մատչում և վերահսկողություն:"</string>
+    <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"Ծրագրավորման գործիքներ"</string>
+    <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"Գործառույթներ, որ անհրաժեշտ են միայն հավելվածների ծրագրավորողներին:"</string>
+    <string name="permgrouplab_display" msgid="4279909676036402636">"Այլ հավելվածի UI"</string>
+    <string name="permgroupdesc_display" msgid="6051002031933013714">"Ազդել այլ հավելվածների UI-ներին:"</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"Պահոց"</string>
+    <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Մուտք գործել USB պահոց:"</string>
+    <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Մուտք գործել SD քարտ:"</string>
+    <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"Մատչելիության գործիքներ"</string>
+    <string name="permgroupdesc_accessibilityFeatures" msgid="4205196881678144335">"Հատկություններ, որ օժանդակող տեխնոլոգիան կարող է հայցել:"</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="5800552516779249356">"Տարրերը, որոնց հպեք, բարձրաձայն կխոսեն, և էկրանը հնարավոր կլինի ուսումնասիրել ժեստերով:"</string>
+    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Միացնել ընդլայնված վեբ մատչելիությունը"</string>
+    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Հնարավոր է սկրիպտներ տեղադրվեն` ծրագրի բովանդակությունն ավելի մատչելի դարձնելու համար:"</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Զննել ձեր մուտքագրած տեքստը"</string>
+    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Ներառում է անձնական տվյալներ, ինչպիսիք են վարկային քարտերի համարները և գաղտնաբառերը:"</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"անջատել կամ փոփոխել կարգավիճակի գոտին"</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"Թույլ է տալիս հավելվածին անջատել կարգավիճակի գոտին կամ ավելացնել ու հեռացնել համակարգի պատկերակները:"</string>
+    <string name="permlab_statusBarService" msgid="7247281911387931485">"կարգավիճակի գոտի"</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_processOutgoingCalls" msgid="3906007831192990946">"վերաուղղել ելքային զանգերը"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Թույլ է տալիս հավելվածին մշակել ելքային զանգերը և փոխել համարհավաքումը: Վնասարար հավելվածները կարող են վերահսկել, վերահասցեավորել կամ կանխել ելքային զանգերը:"</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_receiveEmergencyBroadcast" msgid="1803477660846288089">"ստանալ արտակարգ իրավիճակների հաղորդումներ"</string>
+    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Թույլ է տալիս հավելվածին ստանալ և մշակել ծանուցվող արտակարգ հաղորդակցությունները: Այս թույլտվությունը հասանելի է միայն համակարգային ծրագրերին:"</string>
+    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"կարդալ բջջային զեկուցվող հաղորդագրությունները"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Թույլ է տալիս հավելվածին կարդալ ձեր սարքի կողմից ստացված բջջային հեռարձակվող հաղորդագրությունները: Բջջային հեռարձակվող զգուշացումները ուղարկվում են որոշ վայրերում` արտակարգ իրավիճակների մասին ձեզ զգուշացնելու համար: Վնասարար հավելվածները կարող են խանգարել ձեր սարքի արդյունավետությանը կամ շահագործմանը, երբ ստացվում է արտակարգ իրավիճակի մասին բջջային հաղորդում:"</string>
+    <string name="permlab_sendSms" msgid="5600830612147671529">"ուղարկել SMS հաղորդագրություններ"</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"Թույլ է տալիս հավելվածին ուղարկել SMS հաղորդագրություններ: Այն կարող է անսպասելի ծախսերի պատճառ դառնալ: Վնասարար հավելվածները կարող են ձեր հաշվից գումար ծախսել` ուղարկելով հաղորդագրություններ`  առանց ձեր հաստատման:"</string>
+    <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"պատասխանել հաղորդագրության միջոցով իրադարձություններ ուղարկել"</string>
+    <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"Թույլ է տալիս հավելվածին հարցումներ ուղարկել այլ հաղորդագրությունների հավելվածներին` կառավարելու մուտքային զանգերին հաղորդագրության միջոցով պատասխանելու դեպքերը:"</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"կարդալ ձեր տեքստային հաղորդագրությունները (SMS կամ MMS)"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Թույլ է տալիս հավելվածին կարդալ ձեր գրասալիկում կամ SIM քարտում պահված SMS հաղորդագրությունները: Սա թույլ է տալիս հավելվածին կարդալ բոլոր SMS հաղորդագրությունները` անկախ բովանդակությունից կամ գաղտնիությունից:"</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Թույլ է տալիս հավելվածին կարդալ ձեր հեռախոսում կամ SIM քարտում պահված SMS հաղորդագրությունները: Սա թույլ է տալիս հավելվածին կարդալ բոլոր SMS հաղորդագրությունները` անկախ բովանդակությունից կամ գաղտնիությունից:"</string>
+    <string name="permlab_writeSms" msgid="3216950472636214774">"խմբագրել ձեր տեքստային հաղորդագրությունները (SMS կամ MMS)"</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Թույլ է տալիս հավելվածին պատասխանել ձեր գրասալիկում կամ SIM քարտում պահված SMS հաղորդագրություններին: Վնասարար հավելվածները կարող են ջնջել ձեր հաղորդագրությունները:"</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Թույլ է տալիս հավելվածին պատասխանել ձեր հեռախոսում կամ SIM քարտում պահված 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_interactAcrossUsers" msgid="7114255281944211682">"հաղորդակցվել օգտվողների միջև"</string>
+    <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Թույլ է տալիս հավելվածին իրականացնել գործողություններ սարքի տարբեր օգտվողների միջոցով: Վնասարար հավելվածները կարող են օգտագործել սա` խախտելու օգտվողների միջև պաշտպանությունը:"</string>
+    <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"ամբողջական հաղորդակցվելու արտոնություն օգտվողների միջև"</string>
+    <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Թույլ է տալիս բոլոր հնարավոր հաղորդակցության եղանակները օգտվողների միջև:"</string>
+    <string name="permlab_manageUsers" msgid="1676150911672282428">"կառավարել օգտվողներին"</string>
+    <string name="permdesc_manageUsers" msgid="8409306667645355638">"Թույլ է տալիս հավելվածներին կառավարել սարքի օգտագործողներին, այդ թվում` հարցումները, ստեղծումն ու ջնջումը:"</string>
+    <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"առբերել աշխատող հավելվածների մանրամասները"</string>
+    <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Թույլ է տալիս հավելվածին առբերել մանրամասն տեղեկություններ առկա և վերջերս աշխատող առաջադրանքների մասին: Վնասարար հավելվածները կարող են հայտնաբերել անձնական տեղեկություններ այլ հավելվածների վերաբերյալ:"</string>
+    <string name="permlab_reorderTasks" msgid="2018575526934422779">"վերադասավորել աշխատող հավելվածները"</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Թույլ է տալիս հավելվածին փոխանցել առաջադրանքները առջևք և հետնաշերտ: Հավելվածը կարող է սա անել առանց ձեր ներածման:"</string>
+    <string name="permlab_removeTasks" msgid="6821513401870377403">"դադարեցնել հավելվածների աշխատանքը"</string>
+    <string name="permdesc_removeTasks" msgid="1394714352062635493">"Թույլ է տալիս հավելվածին հեռացնել առաջադրաքները և վերացնել դրանց հավելվածները: Վնասարար հավելվածները կարող են խանգարել այլ հավելվածների գործունեությանը:"</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"կառավարել գործունեության կույտերը"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Թույլ է տալիս ծրագրին ավելացնել, հեռացնել և փոփոխել գործունեության կույտերը, որոնցում աշխատում են այլ ծրագրեր: Վնասակար ծրագրերը կարող են խաթարել այլ ծրագրերի վարքագիծը:"</string>
+    <string name="permlab_startAnyActivity" msgid="2918768238045206456">"մեկնարկել ցանկացած գործունեություն"</string>
+    <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Թույլ է տալիս հավելվածին մեկնարկել ցանկացած գործունեություն` անկախ թույլտվության պաշտպանվածությունից կամ արտահանման կարգավիճակից:"</string>
+    <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"կարգավորել էկրանի համատեղելիությունը"</string>
+    <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Թույլ է տալիս հավելվածին վերահսկել այլ հավելվածների էկրանի համատեղելիության ռեժիմը: Վնասարար հավելվածները կարող են խաթարել այլ հավելվածների վարքագիծը:"</string>
+    <string name="permlab_setDebugApp" msgid="3022107198686584052">"միացնել հավելվածի վրիպազերծումը"</string>
+    <string name="permdesc_setDebugApp" msgid="4474512416299013256">"Թույլ է տալիս հավելվածին միացնել վրիպազերծումը այլ հավելվածի համար: Վնասարար հավելվածները կարող են օգտագործել սա` մյուս հավելվածները վերացնելու համար:"</string>
+    <string name="permlab_changeConfiguration" msgid="4162092185124234480">"փոխել համակարգի ցուցադրման կարգավորումները"</string>
+    <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"Թույլ է տալիս հավելվածին փոխել առկա կարգավորումը, ինչպես օրինակ տեղույթի կամ ընդհանուր տառաչափը:"</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_forceStopPackages" msgid="2329627428832067700">"ստիպել դադարեցնել այլ հավելվածները"</string>
+    <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"Թույլ է տալիս հավելվածին ստիպողաբար դադարեցնել այլ հավելվածները:"</string>
+    <string name="permlab_forceBack" msgid="652935204072584616">"ստիպել, որ հավելվածը փակվի"</string>
+    <string name="permdesc_forceBack" msgid="3892295830419513623">"Թույլ է տալիս հավելվածին ստիպել որևէ գործունեություն, որը գտնվում է առջևքում, փակել ու ետ գնալ: Սովորական հավելվածների համար երբևէ  անհրաժեշտ չպետք է լինի:"</string>
+    <string name="permlab_dump" msgid="1681799862438954752">"առբերել համակարգի ներքին կարգավիճակը"</string>
+    <string name="permdesc_dump" msgid="1778299088692290329">"Թույլ է տալիս հավելվածին առբերել համակարգի ներքին կարգավիճակը: Վնասարար հավելվածները կարող են առբերել բազմաթիվ անձնական և ապահով տեղեկություններ, որոնք երբեք սովորաբար անհրաժեշտ չեն:"</string>
+    <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"առբերել էկրանի բովանդակությունը"</string>
+    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Թույլ է տալիս հավելվածին առբերել ակտիվ պատուհանի պարունակությունը: Վնասարար հավելվածները կարող են առբերել պատուհանի լրիվ պարունակությունը և հետազոտել դրա ամբողջ տեքստը` բացառությամբ գաղտնաբառերի:"</string>
+    <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"ժամանակավոր միացնել մուտքի հնարավորությունը"</string>
+    <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"Թույլ է տալիս հավելվածին ժամանակավորապես մուտքի հնարավորություն տալ սարքին: Վնասարար հավելվածները կարող են մուտքի հնարավորություն ընձեռել առանց օգտվողի համաձայնության:"</string>
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"առբերել պատուհանի տեղեկություները"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Թույլ է տալիս հավելվածին առբերել պատուհանների մասին տեղեկատվություններ  պատուհանի կառավարչից: Վնասարար հավելվածները կարող են առբերել տեղեկություններ, որը նախատեսված է ներքին համակարգի օգտագործման համար:"</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"զտել իրադարձությունները"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Թույլ է տալիս հավելվածին գրանցել մուտքագրման զտիչ, որը զտում է օգտվողի իրադարձությունների ամբողջ հոսքը` նախքան դրանք կուղարկվեն: Վնասարար հավելվածը կարող է կառավարել համակարգի UI-ը` առանց ձեր միջամտության:"</string>
+    <string name="permlab_magnify_display" msgid="5973626738170618775">"խոշորացնել ցուցադրիչը"</string>
+    <string name="permdesc_magnify_display" msgid="7121235684515003792">"Թույլ է տալիս հավելվածին խոշորացնել ցուցադրիչի բովանդակությունը: Վնասարար հավելվածները կարող են փոխակերպել ցուցադրիչի բովանդակությունը այնպես, որ սարքը դառնա անպիտան:"</string>
+    <string name="permlab_shutdown" msgid="7185747824038909016">"մասնակի անջատում"</string>
+    <string name="permdesc_shutdown" msgid="7046500838746291775">"Դնում է գործունեության կառավարչին անջատման կարգավիճակի մեջ: Չի իրականացնում ամբողջական անջատում:"</string>
+    <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"կանխել ծրագրի փոխարկումները"</string>
+    <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Կանխում է օգտվողի անցումը այլ հավելվածի:"</string>
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"ստանալ ընթացիկ հավելվածի մասին տեղեկություններ"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="8153651434145132505">"Թույլ է տալիս սեփականատիրոջը առբերել գաղտնի տեղեկություններ ընթացիկ հավելվածի և ծառայությունների մասին էկրանի առաջին պլանում:"</string>
+    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"վերահսկել և կառավարել բոլոր հավելվածների թողարկումը"</string>
+    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Թույլ է տալիս հավելվածին հետևել և վերահսկել, թե ինչպես է համակարգը գործարկում գործողությունները: Վնասարար հավելվածները կարող են ամբողջությամբ վնասել համակարգը: Այս թույլտվությունը անհրաժեշտ է միայն ծրագրավորման համար և ոչ երբեք սովորական օգտագործման համար:"</string>
+    <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"ուղարկել հեռացված փաթեթի մասին հաղորդում"</string>
+    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"Թույլ է տալիս հավելվածին հաղորդել ծանուցում, որ հեռացվել է հավելվածի փաթեթ: Վնասարար հավելվածները կարող են օգտագործել սա ցանկացած այլ աշխատող հավելված սպանելու համար:"</string>
+    <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"ուղարկել ստացված SMS-ի հաղորդում"</string>
+    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"Թույլ է տալիս հավելվածին հաղորդել ծանուցում, որ ստացվել է SMS հաղորդագրություն: Վնասարար հավելվածները կարող են օգտագործել սա` կեղծելու մուտքային SMS հաղորդագրությունները:"</string>
+    <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"ուղարկել ստացված WAP-PUSH-ի  հաղորդում"</string>
+    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"Թույլ է տալիս հավելվածին հաղորդել ծանուցում, որ ստացվել է WAP PUSH հաղորդագրություն: Վնասարար հավելվածները կարող են օգտագործել սա` կեղծելու MMS հաղորդագրության ստացումը կամ աննկատ փոխարինելու ցանկացած կայքի բովանդակությունը վնասարար տարբերակներով:"</string>
+    <string name="permlab_setProcessLimit" msgid="2451873664363662666">"սահմանափակել աշխատող գործընթացների թիվը"</string>
+    <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"Թույլ է տալիս հավելվածին վերահսկել գործընթացների առավելագույն թիվը, որ աշխատելու են: Երբևէ անհրաժեշտ չէ սովորական հավելվածների համար:"</string>
+    <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"ստիպել, որ առաջին պլանի հավելվածները փակվեն"</string>
+    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"Թույլ է տալիս հավելվածին վերահսկել արդյոք գործողությունները միշտ ավարտված են, երբ գնում են հետին պլան: Երբևէ անհրաժեշտ չէ սովորական հավելվածների համար:"</string>
+    <string name="permlab_batteryStats" msgid="2789610673514103364">"կարդալ մարտկոցի կարգավիճակը"</string>
+    <string name="permdesc_batteryStats" msgid="5897346582882915114">"Թույլ է տալիս հավելվածին կարդալ ընթացիկ ցածր մակարդակի մարտկոցի օգտագործման տվյալները: Կարող է թույլ տալ հավելվածին պարզել մանրամասն տեղեկություններ, թե որ հավելվածներն եք օգտագործում:"</string>
+    <string name="permlab_updateBatteryStats" msgid="3719689764536379557">"փոփոխել մարտկոցի վիճակագրությունը"</string>
+    <string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"Թույլ է տալիս հավելվածին փոփոխել մարտկոցի հավաքագրված վիճակագրությունը: Սովորական հավելվածների օգտագործման համար չէ:"</string>
+    <string name="permlab_getAppOpsStats" msgid="1508779687436585744">"առբերել ծրագրի ops վիճակագրությունը"</string>
+    <string name="permdesc_getAppOpsStats" msgid="6243887041577912877">"Թույլ է տալիս հավելվածին առբերել հավելվածի հավաքագրված գործողության կարգավիճակը: Սովորական հավելվածների օգտագործման համար չէ:"</string>
+    <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"փոփոխել ծրագրի գործողությունների վիճակագրությունը"</string>
+    <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"Թույլ է տալիս հավելվածին փոփոխել գործողությունների հավաքագրված վիճակագրությունը: Սովորական հավելվածների օգտագործման համար չէ:"</string>
+    <string name="permlab_backup" msgid="470013022865453920">"հսկել համակարգի պահուստավորումը և վերականգնումը"</string>
+    <string name="permdesc_backup" msgid="6912230525140589891">"Թույլ է տալիս հավելվածին վերահսկել համակարգի պահուստավորման և վերականգնման մեխանիզմը: Սովորական հավելվածների կողմից օգտագործման համար չէ:"</string>
+    <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"հաստատել ամբողջական պահուստավորման կամ վերականգնման գործողությունը"</string>
+    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"Թույլ է տալիս հավելվածին գործարկել ամբողջական պահուստավորման հաստատման UI-ը: Որևէ հավելվածի կողմից օգտագործման համար չէ:"</string>
+    <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"ցուցադրել չարտոնված պատուհանները"</string>
+    <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"Թույլ է տալիս հավելվածին ստեղծել պատուհաններ, որոնք նախատեսված են ներքին համակարգի օգտվողի ինտերֆեյսի օգտագործման համար: Սովորական հավելվածների օգտագործման համար չէ:"</string>
+    <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"անցնել այլ ծրագրերի վրայով"</string>
+    <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"Թույլ է տալիս հավելվածին երևալ այլ հավելվածների վերևում կամ օգտվողի ինտերֆեյսի մասերում: Դրանք կարող են խոչընդոտել ձեր ինտերֆեյսի օգտագործմանը ցանկացած հավելվածում կամ փոխել այն, ինչը կարծում եք, որ տեսնում եք այլ հավելվածներում:"</string>
+    <string name="permlab_setAnimationScale" msgid="2805103241153907174">"փոփոխել համաշխարհային անիմացիոն արագությունը"</string>
+    <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"Թույլ է տալիս հավելվածին փոխել համաշխարհային անիմացիոն արագությունը (ավելի արագ կամ դանդաղ անիմացիաներ) ցանկացած ժամանակ:"</string>
+    <string name="permlab_manageAppTokens" msgid="1286505717050121370">"կառավարել ծրագրի այլանիշերը"</string>
+    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"Թույլ է տալիս հավելվածին ստեղծել և կառավարել իրենց սեփական նշանները` շրջանցելով իրենց սովորական Z հերթականությունը: Սովորական հավելվածների համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+    <string name="permlab_freezeScreen" msgid="4708181184441880175">"սառեցնել էկրանը"</string>
+    <string name="permdesc_freezeScreen" msgid="8558923789222670064">"Թույլ է տալիս հավելվածին ժամանակավորապես սառեցնել էկրանը` լրիվ էկրանին անցնելու համար:"</string>
+    <string name="permlab_injectEvents" msgid="1378746584023586600">"սեղմել ստեղները և կառավարման կոճակները"</string>
+    <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"Թույլ է տալիս հավելվածին տրամադրել իր սեփական մուտքագրված իրադարձություններն (ստեղների սեղմումներ և այլն) այլ հավելվածներին: Վնասարար հավելվածները կարող են սա օգտագործել գրասալիկի աշխատանքին միջամտելու համար:"</string>
+    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"Թույլ է տալիս հավելվածին առաքել իր սեփական ներածման իրադարձությունները (ստեղնի սեղմումներ և այլն) այլ հավելվածներին: Վնասարար հավելվածները կարող են սա օգտագործել գրասալիկը վնասելու համար:"</string>
+    <string name="permlab_readInputState" msgid="469428900041249234">"գրառել ձեր մուտքագրումները և գործողությունները"</string>
+    <string name="permdesc_readInputState" msgid="8387754901688728043">"Թույլ է տալիս հավելվածին տեսնել ձեր սեղմած ստեղները, նույնիսկ այն ժամանակ, երբ փոխգործակցում եք այլ հավելվածի հետ (օրինակ` գաղտնաբառի մուտքագրումը): Երբեք անհրաժեշտ չպետք է լինի սովորական հավելվածների համար:"</string>
+    <string name="permlab_bindInputMethod" msgid="3360064620230515776">"միանալ մուտքագրման եղանակին"</string>
+    <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Թույլ է տալիս սեփականատիրոջը միանալ մուտքագրման եղանակի վերին մակարդակի ինտերֆեյսին: Սովորական հավելվածների համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+    <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"կապվել մատչելիության ծառայության հետ"</string>
+    <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Թույլ է տալիս սեփականատիրոջը միանալ հասանելիության ծառայության վերին մակարդակի ինտերֆեյսին: Սովորական հավելվածների համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"միանալ տպման ծառայությանը"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Թույլ է տալիս սեփականատիրոջը միանալ տպման ծառայության վերին մակարդակի ինտերֆեյսին: Սովորական ծրագրերի համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"մուտքի գործել բոլոր տպման աշխատանքներ"</string>
+    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Թույլ է տալիս սեփականատիրոջը մուտք ունենալ մեկ այլ ծրագրի կողմից ստեղծված տպման աշխատանքներ: Սովորական ծրագրերի համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"կապվել NFC ծառայությանը"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Թույլ է տալիս տիրոջը կապվել ծրագրերին, որոնք օգտագործում են NFC քարտեր: Սովորական ծրագրերի համար երբեք անհրաժեշտ չէ:"</string>
+    <string name="permlab_bindTextService" msgid="7358378401915287938">"միանալ տեքստային ծառայությանը"</string>
+    <string name="permdesc_bindTextService" msgid="8151968910973998670">"Թույլ է տալիս սեփականատիրոջը կապվել տեքստային ծառայության բարձր մակարդակի ինտերֆեյսին (օրինակ` Ուղղագրության ստուգման ծառայությանը): Սովորական հավելվածների համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+    <string name="permlab_bindVpnService" msgid="4708596021161473255">"կապվել VPN ծառայությանը"</string>
+    <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Թույլ է տալիս սեփականատիրոջը միանալ Vpn ծառայության վերին մակարդակի ինտերֆեյսին: Սովորական հավելվածների համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+    <string name="permlab_bindWallpaper" msgid="8716400279937856462">"միանալ պաստառին"</string>
+    <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Թույլ է տալիս սեփականատիրոջը միանալ պաստառի վերին մակարդակի ինտերֆեյսին: Սովորական հավելվածների համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"միանալ վիջեթ ծառայությանը"</string>
+    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Թույլ է տալիս սեփականատիրոջը միանալ վիջեթ ծառայության վերին մակարդակի ինտերֆեյսին: Սովորական հավելվածների համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+    <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"փոխգործակցել սարքի կառավարչի հետ"</string>
+    <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Թույլ է տալիս սեփականատիրոջը ուղարկել մտադրություններ սարքի կառավարչին: Սովորական հավելվածների համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"ավելացնել կամ հեռացնել սարքի արդմինիստրատոր"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Թույլ է տալիս սեփականատիրոջը ավելացնել կամ հեռացնել սարքի ակտիվ ադմինիստրատորներ: Երբեք չպետք է անհրաժեշտ լինի սովորական ծրագրերին:"</string>
+    <string name="permlab_setOrientation" msgid="3365947717163866844">"փոխել էկրանի դիրքավորումը"</string>
+    <string name="permdesc_setOrientation" msgid="3046126619316671476">"Թույլ է տալիս հավելվածին փոխել էկրանի պտտումը ցանկացած ժամանակ: Սովորական հավելվածների համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+    <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"փոխել ցուցչի արագությունը"</string>
+    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Թույլ է տալիս հավելվածին փոխել մկնիկի կամ հպահարթակի սլաքի արագությունը ցանկացած ժամանակ: Երբևէ անհրաժեշտ չպետք է լինի սովորական հավելվածների համար:"</string>
+    <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"փոխել ստեղնաշարի դիրքը"</string>
+    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Թույլ է տալիս հավելվածին փոխել ստեղնաշարի դիրքը: Սովորական հավելվածների համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+    <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"ուղարկել Linux ազդանշաններ հավելվածներին"</string>
+    <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Թույլ է տալիս հավելվածին հայցել, որ տրամադրված ազդանշանը ուղարկվի բոլոր մշտական գործընթացներին:"</string>
+    <string name="permlab_persistentActivity" msgid="8841113627955563938">"միշտ աշխատեցնել հավելվածը"</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Թույլ է տալիս հավելվածին մնայուն դարձնել իր մասերը հիշողության մեջ: Սա կարող է սահմանափակել այլ հավելվածներին հասանելի հիշողությունը` դանդաղեցնելով գրասալիկի աշխատանքը:"</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"Թույլ է տալիս հավելվածին մնայուն դարձնել իր մասերը հիշողության մեջ: Սա կարող է սահմանափակել այլ հավելվածներին հասանելի հիշողությունը` դանդաղեցնելով հեռախոսի աշխատանքը:"</string>
+    <string name="permlab_deletePackages" msgid="184385129537705938">"ջնջել հավելվածները"</string>
+    <string name="permdesc_deletePackages" msgid="7411480275167205081">"Թույլ է տալիս հավելվածին ջնջել Android փաթեթները: Վնասարար հավելվածները կարող են օգտագործել սա` կարևոր հավելվածները ջնջելու համար:"</string>
+    <string name="permlab_clearAppUserData" msgid="274109191845842756">"ջնջել այլ հավելվածների տվյալները"</string>
+    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"Թույլ է տալիս հավելվածին մաքրել օգտվողի տվյալները:"</string>
+    <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"ջնջել այլ հավելվածների քեշերը"</string>
+    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"Թույլ է տալիս հավելվածին ջնջել քեշ ֆայլերը:"</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"չափել հավելվածի պահոցի տարածքը"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Թույլ է տալիս հավելվածին առբերել իր կոդը, տվյալները և քեշի չափերը"</string>
+    <string name="permlab_installPackages" msgid="2199128482820306924">"ուղղակիորեն տեղադրել հավելվածները"</string>
+    <string name="permdesc_installPackages" msgid="5628530972548071284">"Թույլ է տալիս հավելվածին տեղադրել նոր կամ թարմացված Android փաթեթներ: Վնասարար հավելվածները կարող են օգտագործել սա` ավելացնելու նոր հավելվածներ` կամայականորեն հզոր թույլտվություններով:"</string>
+    <string name="permlab_clearAppCache" msgid="7487279391723526815">"ջնջել հավելվածի քեշի բոլոր տվյալները"</string>
+    <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"Թույլ է տալիս հավելվածին ազատել գրասալիկի պահոցը` ջնջելով ֆայլերը այլ հավելվածների քեշ գրացուցակներում: Սա կարող է պատճառ դառնալ, որ այլ հավելվածները ավելի դանդաղ մեկնարկեն, քանի որ դրանք պետք է նորից առբերեն իրենց տվյալները:"</string>
+    <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"Թույլ է տալիս հավելվածին ազատել հեռախոսի պահուստը` ջնջելով ֆայլերը այլ հավելվածների քեշ գրացուցակներում: Սա կարող է պատճառ դառնալ, որ այլ հավելվածները ավելի դանդաղ մեկնարկեն, քանի որ նրանք պետք է նորից առբերեն իրենց տվյալները:"</string>
+    <string name="permlab_movePackage" msgid="3289890271645921411">"Տեղափոխել հավելվածի ռեսուրսները"</string>
+    <string name="permdesc_movePackage" msgid="319562217778244524">"Թույլ է տալիս հավելվածին տեղափոխել ծրագրային ռեսուրսները ներքին մեդիաներից արտաքինին և հակառակը:"</string>
+    <string name="permlab_readLogs" msgid="6615778543198967614">"կարդալ հոսքի զգայուն տվյալները"</string>
+    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Թույլ է տալիս հավելվածին կարդալ համակարգի տարբեր գրանցամատյանային ֆայլերից: Սա թույլ է տալիս ստանալ ընդհանուր տեղեկություններ այն մասին, թե ինչ եք անում գրասալիկով, այդ թվում` անձնական կամ գաղտնի տեղեկություններ:"</string>
+    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Թույլ է տալիս հավելվածին կարդալ համակարգի տարբեր գրանցամատյանային ֆայլերից: Սա թույլ է տալիս ստանալ ընդհանուր տեղեկություններ այն մասին, թե ինչ եք անում հեռախոսով, այդ թվում` անձնական կամ գաղտնի տեղեկություններ:"</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"օգտագործել ցանկացած մեդիա վերծանիչ նվագարկման համար"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Թույլ է տալիս հավելվածին օգտագործել ցանկացած տեղադրված մեդիա վերծանիչ` նվագարկումը ապակոդավորելու համար:"</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"կառավարեք վստահելի վկայագրերը"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Թույլատրում է հավելվածին տեղադրել և ապատեղադրել CA վկայագրերը՝ որպես վստահելի:"</string>
+    <string name="permlab_diagnostic" msgid="8076743953908000342">"կարդալ կամ գրել ախտորոշիչին պատկանող ռեսուրսները"</string>
+    <string name="permdesc_diagnostic" msgid="6608295692002452283">"Թույլ է տալիս հավելվածին կարդալ և գրել ախտորոշիչ խմբին պատկանող ցանկացած ռեսուրսում, ինչպես օրինակ ֆայլերը /dev-ում: Դա կարող է ազդել համակարգի կայունության և անվտանգության վրա: Սա պետք է օգտագործել միայն արտադրողի կամ օպերատորի կողմից սարքին հատուկ ախտորոշման համար:"</string>
+    <string name="permlab_changeComponentState" msgid="6335576775711095931">"միացնել կամ անջատել հավելվածի բաղադրիչները"</string>
+    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Թույլ է տալիս հավելվածին փոխել, արդյոք այլ հավելվածի բաղադրիչը լինի միացված թե անջատված: Վնասարար հավելվածները կարող են սա օգտագործել` անջատելու գրասալիկի կարևոր հնարավորությունները: Այս թույլտվությունը պետք է օգտագործել զգուշությամբ, քանի որ հնարավոր է հավելվածի բաղադրիչները հայտնվեն անպիտան, անհամապատասխան կամ անկայուն կարգավիճակում:"</string>
+    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Թույլ է տալիս հավելվածին փոխել, արդյոք այլ հավելվածի բաղադրիչը լինի միացված թե անջատված: Վնասարար հավելվածները կարող են սա օգտագործել` անջատելու հեռախոսի կարևոր հնարավորությունները: Այս թույլտվությունը պետք է օգտագործել զգուշությամբ, քանի որ հնարավոր է հավելվածի բաղադրիչները հայտնվեն անպիտան, անհամապատասխան կամ անկայուն կարգավիճակում:"</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"շնորհել կամ չեղարկել թույլտվություններ"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Թույլ է տալիս հավելվածին հատուկ թույլտվություն շնորհել կամ չեղարկել այդ կամ այլ հավելվածների համար: Վնասարար հավելվածները կարող են օգտագործել սա` մուտք գործելու ձեր կողմից չթույլատրված գործիքներ:"</string>
+    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"սահմանել նախընտրած հավելվածները"</string>
+    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Թույլ է տալիս հավելվածին փոփոխել ձեր նախընտրած հավելվածները: Վնասարար հավելվածները կարող են աննկատ փոխել հավելվածները, որոնք կեղծում են ձեր առկա հավելվածների աշխատանքը` ձեզանից անձնական տվյալներ հավաքագրելու համար:"</string>
+    <string name="permlab_writeSettings" msgid="2226195290955224730">"փոփոխել համակարգի կարգավորումները"</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"Թույլ է տալիս հավելվածին փոփոխել համակարգի կարգավորումների տվյալները: Վնասարար հավելվածները կարող են վնասել ձեր համակարգի կարգավորումները:"</string>
+    <string name="permlab_writeSecureSettings" msgid="204676251876718288">"փոփոխել անվտանգ համակարգի կարգավորումները"</string>
+    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"Թույլ է տալիս հավելվածին փոփոխել համակարգի անվտանգ կարգավորումների տվյալները: Նախատեսված չէ սովորական հավելվածների կողմից օգտագործման համար:"</string>
+    <string name="permlab_writeGservices" msgid="2149426664226152185">"փոփոխել Google ծառայությունների քարտեզը"</string>
+    <string name="permdesc_writeGservices" msgid="1287309437638380229">"Թույլ է տալիս հավելվածին փոփոխել Google-ի ծառայությունների քարտեզը: Սովորական հավելվածների օգտագործման համար չէ:"</string>
+    <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"աշխատել մեկնարկային ռեժիմով"</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Թույլ է տալիս հավելվածին ինքնուրույն մեկնարկել համակարգի բեռնման ավարտից հետո: Սա կարող է երկարացնել գրասալիկի մեկնարկը և թույլ տալ հավելավածին դանդաղեցնել ամբողջ գրասալիկի աշխատանքը` միշտ աշխատելով:"</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="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="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="default" msgid="589869224625163558">"Թույլ է տալիս հավելվածին փոփոխել ձեր գրասալիկում պահված կոնտակտների տվյալները, այդ թվում` ձեր կատարած զանգերի, գրած նամակների կամ որոշակի անհատների հետ այլ եղանակով շփման հաճախականությունը: Այս թույլտվությունը հնարավորություն է տալիս հավելվածներին ջնջել կոնտակտային տվյալները:"</string>
+    <string name="permlab_readCallLog" msgid="3478133184624102739">"կարդալ զանգերի մատյանը"</string>
+    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Թույլ է տալիս հավելվածին կարդալ ձեր գրասալիկի զանգերի գրանցամատյանը, այդ թվում` մուտքային և ելքային զանգերի տվյալները: Սա թույլ է տալիս հավելվածին պահել ձեր զանգերի գրանցամատյանի տվյալները, և վնասարար հավելվածները կարող են տարածել դրանք` առանց ձեր իմացության:"</string>
+    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Թույլ է տալիս հավելվածին կարդալ ձեր հեռախոսի զանգերի գրանցամատյանը, այդ թվում` մուտքային և ելքային զանգերի տվյալները: Թույլտվությունը հնարավորություն է տալիս հավելվածին պահպանել ձեր զանգերի գրանցամատյանի տվյալները, և վնասարար հավելվածները կարող են տարածել գրանցամատյանի տվյալներն առանց ձեր իմացության:"</string>
+    <string name="permlab_writeCallLog" msgid="8552045664743499354">"տեսնել զանգերի գրանցամատյանը"</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Թույլ է տալիս հավելվածին փոփոխել ձեր գրասալիկի զանգերի մատյանը, այդ թվում` մուտքային և ելքային զանգերի մասին տվյալները: Վնասարար հավելվածները կարող են սա օգտագործել` ձեր զանգերի մատյանը ջնջելու կամ փոփոխելու համար:"</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Թույլ է տալիս հավելվածին փոփոխել ձեր հեռախոսի զանգերի մատյանը, այդ թվում` մուտքային և ելքային զանգերի մասին տվյալները: Վնասարար հավելվածները կարող են սա օգտագործել` ձեր զանգերի մատյանը ջնջելու կամ փոփոխելու համար:"</string>
+    <string name="permlab_readProfile" msgid="4701889852612716678">"կարդալ ձեր սեփական կոնտակտային քարտը"</string>
+    <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Թույլ է տալիս հավելվածին կարդալ ձեր սարքում պահված անհատական ​​պրոֆիլի տվյալները, ինչպիսիք են ձեր անունը և կոնտակտային տվյալները: Սա նշանակում է, որ հավելվածը կարող է ձեզ ճանաչել և ուղարկել ձեր պրոֆիլի տվյալները ուրիշներին:"</string>
+    <string name="permlab_writeProfile" msgid="907793628777397643">"փոփոխել ձեր սեփական կոնտակտային քարտը"</string>
+    <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Թույլ է տալիս հավելվածին փոխել կամ ավելացնել ձեր սարքում պահված անհատական ​​պրոֆիլի տվյալները, ինչպիսիք են ձեր անունը և կոնտակտային տվյալները: Սա նշանակում է, որ հավելվածը կարող է ձեզ ճանաչել և ուղարկել ձեր պրոֆիլի տվյալները ուրիշներին:"</string>
+    <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"կարդալ ձեր սոցիալական հոսքը"</string>
+    <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Թույլ է տալիս հավելվածին մուտք գործել և համաժամեցնել ձեր և ձեր ընկերների սոցիալական թարմացումները: Զգույշ եղեք տեղեկություններ տարածելիս. այն թույլ է տալիս հավելվածին կարդալ ձեր և ձեր ընկերների միջև անձնական հաղորդագրությունները սոցիալական ցանցերում` անկախ գաղտնիությունից: Նշում. այս թույլտվությունը չի կարող գործածվել բոլոր սոցիալական ցանցերում:"</string>
+    <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"գրել ձեր սոցիալական հոսքում"</string>
+    <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Թույլ է տալիս հավելվածին ցուցադրել ձեր ընկերների սոցիալական թարմացումները: Զգույշ եղեք տեղեկություններ տարածելիս. այն թույլ է տալիս հավելվածին հաղորդագություններ ստեղծել, որոնք իբրև ստացվում են ընկերոջից: Նշում. այս թույլտվությունը չի կարող գործածվել բոլոր սոցիալական ցանցերում:"</string>
+    <string name="permlab_readCalendar" msgid="5972727560257612398">"կարդալ օրացուցային իրադարձությունները և գաղտնի տեղեկությունները"</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Թույլ է տալիս հավելվածին կարդալ ձեր գրասալիկում պահված բոլոր օրացուցային իրադարձությունները, այդ թվում` ընկերների կամ գործընկերների: Սա կարող է թույլ տալ հավելվածին տարածել կամ պահել ձեր օրացուցային տվյալները` անկախ գաղտնիությունից կամ զգայունությունից:"</string>
+    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Թույլ է տալիս հավելվածին կարդալ ձեր հեռախոսում պահված բոլոր օրացուցային իրադարձությունները, այդ թվում` ընկերների կամ գործընկերների: Սա կարող է թույլ տալ հավելվածին տարածել կամ պահել ձեր օրացուցային տվյալները` անկախ գաղտնիությունից կամ զգայունությունից:"</string>
+    <string name="permlab_writeCalendar" msgid="8438874755193825647">"ավելացնել կամ փոփոխել օրացուցային իրադարձությունները և ուղարկել նամակ հյուրերին` առանց սեփականատերերի իմացության"</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Թույլ է տալիս հավելվածին ավելացնել, հեռացնել, փոխել իրադարձություններ, որոնք դուք կարող եք փոփոխել ձեր գրասալիկում, այդ թվում ընկերների կամ աշխատակիցների իրադարձությունները: Սա կարող է թույլ տալ հավելվածին ուղարկել հաղորդագրություններ, որոնք երևում են որպես օրացույցի սեփականատերերից ուղարկված, կամ փոփոխել իրադարձություններն առանց սեփականատերերի իմացության:"</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Թույլ է տալիս հավելվածին ավելացնել, հեռացնել, փոխել այն իրադարձությունները, որոնք կարող եք փոփոխել ձեր հեռախոսից, այդ թվում` ընկերների կամ գործընկերների: Սա կարող է թույլ տալ հավելվածին ուղարկել հաղորդագրություններ, որոնք իբրև գալիս են օրացույցի սեփականատիրոջից, կամ փոփոխել իրադարձությունները` առանց սեփականատիրոջ իմացության:"</string>
+    <string name="permlab_accessMockLocation" msgid="8688334974036823330">"կեղծ տեղանքի աղբյուրներ փորձարկման համար"</string>
+    <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Ստեղծել կեղծ տեղանքի աղբյուրներ` փորձարկման կամ տեղադրության նոր ծառայություն մատուցողի տեղադրման համար: Սա հնարավորություն է տալիս, որ ծրագիրը անտեսի տեղադրությունը և/կամ կարգավիճակը` տրամադրված տեղանքի այլ աղբյուրների կողմից, ինչպիսիք են GPS-ը կամ տեղադրության ծառայություն մատուցողները:"</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"օգտագործել տեղադրություն տրամադրող հավելվյալ հրամաններ"</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"Թույլ է տալիս հավելվածին օգտագործել տեղադրության ծառայություն մատուցողների լրացուցիչ հրամանները: Սա կարող է թույլ տալհավելվածին խանգարել GPS-ի կամ այլ տեղանքի աղբյուրների աշխատանքին:"</string>
+    <string name="permlab_installLocationProvider" msgid="6578101199825193873">"տեղադրության ծառայություն մատուցողի տեղադրման թույլտվություն"</string>
+    <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"Ստեղծել կեղծ տեղանքի աղբյուրներ` փորձարկման կամ տեղադրության նոր ծառայություն մատուցողի տեղադրման համար: Սա հնարավորություն է տալիս, որ հավելվածն անտեսի տեղադրությունը և/կամ կարգավիճակը` տրամադրված տեղանքի այլ աղբյուրների կողմից, ինչպիսիք են GPS-ը կամ տեղադրության ծառայություն մատուցողները:"</string>
+    <string name="permlab_accessFineLocation" msgid="1191898061965273372">"ճշգրիտ վայրը (ըստ GPS-ի և ցանցի)"</string>
+    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Թույլ է տալիս հավելվածին ստանալ ձեր ճշգրիտ տեղադրությունը` օգտագործելով Գլոբալ Դիրքավորման Համակարգը (GPS) կամ ցանցային տեղանքի աղբյուրները, ինչպես օրինակ` բջջային աշտարակները և Wi-Fi-ը: Այս տեղադրության ծառայությունները պետք է միացվեն և հասանելի լինեն ձեր սարքի համար, որպեսզի հավելվածն օգտագործի դրանք: Հավելվածները կարող են սա օգտագործել` որոշելու համար ձեր գտնվելու վայրը և կարող են սպառել մարտկոցի լրացուցիչ լիցք:"</string>
+    <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"մոտավոր տեղադրությունը (ցանցային)"</string>
+    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Թույլ է տալիս հավելվածին ստանալ ձեր մոտավոր տեղադրությունը: Այս տեղադրությունը ստացվում է տեղանքի ծառայությունների կողմից, ինչպես օրինակ` բջջային աշտարակներից և Wi-Fi-ից: Այս տեղանքի ծառայությունները պետք է միացված և հասանելի լինեն ձեր սարքին, որպեսզի հավելվածն օգտագործի դրանք: Հավելվածները կարող են սա օգտագործել` ձեր մոտավոր գտնվելու վայրը որոշելու համար:"</string>
+    <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"մուտք SurfaceFlinger"</string>
+    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Թույլ է տալիս հավելվածին օգտագործել SurfaceFlinger ցածր մակարդակի գործառույթները:"</string>
+    <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"կարդալ շրջանակի պահնակը"</string>
+    <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Թույլ է տալիս հավելվածին կարդալ շրջանակի պահնակի բովանդակությունը:"</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"մուտք գործել InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Թույլ է տալիս ծրագրին օգտագործել InputFlinger ցածր մակարդակի գործառույթները:"</string>
+    <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"կարգավորել WiFi-ի ցուցադրումը"</string>
+    <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Թույլ է տալիս հավելվածին կարգավորել և միանալ WiFi ցուցադրիչներին:"</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"կառավարել Wifi-ի ցուցադրումը"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Թույլ է տալիս հավելվածին կառավարել WiFi ցուցադրիչների ցածր մակարդակի գործառույթները:"</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"պահել աուդիո արտածումը"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Թույլ է տալիս ծրագրին պահել և վերահղել աուդիո արտածումը:"</string>
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"պահել վիդեո արտածումը"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Թույլ է տալիս ծրագրին պահել և վերահղել վիդեո արտածումը:"</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"պահել անվտանգ վիդեո արտածումը"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Թույլ է տալիս ծրագրին պահել և վերահղել անվտանգ վիդեո արտածումը:"</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="4906839301087980680">"Թույլ է տալիս հավելվածին բարձրախոսով ձայնագրել ձայնանյութ: Այս թույլտվությունը հնարավորություն է տալիս հավելվածին ձայնանյութ ձայնագրել ցանկացած ժամանակ` առանց ձեր հաստատման:"</string>
+    <string name="permlab_camera" msgid="3616391919559751192">"լուսանկարել և տեսանկարել"</string>
+    <string name="permdesc_camera" msgid="8497216524735535009">"Թույլ է տալիս հավելվածին ֆոտոխցիկով լուսանկարել և տեսանկարել: Այս թույլտվությունը հնարավորություն է տալիս հավելվածին օգտագործել ֆոտոխցիկը ցանկացած ժամանակ` առանց ձեր հաստատման:"</string>
+    <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"անջատել փոխանցող LED ցուցիչը, երբ ֆոտոխցիկը օգտագործվում է"</string>
+    <string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"Թույլ է տալիս նախապես տեղադրված համակարգային ծրագրին անջատել ֆոտոխցիկի օգտագործման LED ցուցիչը:"</string>
+    <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"մշտապես անջատել գրասալիկը"</string>
+    <string name="permlab_brick" product="default" msgid="8337817093326370537">"ընդմիշտ կասեցնել հեռախոսը"</string>
+    <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"Թույլ է տալիս հավելվածին ընդմիշտ անջատել ամբողջ գրասալիկը: Սա շատ վտանգավոր է:"</string>
+    <string name="permdesc_brick" product="default" msgid="5788903297627283099">"Թույլ է տալիս հավելվածին ընդմիշտ անջատել ամբողջ հեռախոսը: Սա շատ վտանգավոր է:"</string>
+    <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"ստիպել, որ գրասալիկը վերաբեռնվի"</string>
+    <string name="permlab_reboot" product="default" msgid="2898560872462638242">"ստիպել, որ հեռախոսը վերաբեռնվի"</string>
+    <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"Թույլ է տալիս հավելվածին ստիպել, որ գրասալիկը վերաբեռնվի:"</string>
+    <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"Թույլ է տալիս հավելվածին ստիպել, որ հեռախոսը վերաբեռնվի:"</string>
+    <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"մուտք ունենալ USB կրիչի ֆայլային համակարգ"</string>
+    <string name="permlab_mount_unmount_filesystems" product="default" msgid="4402305049890953810">"մուտք ունենալ SD քարտի ֆայլային համակարգ"</string>
+    <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"Թույլ է տալիս հավելվածին միացնել և անջատել շարժական կրիչների ֆայլային համակարգերը:"</string>
+    <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"ջնջել USB կրիչը"</string>
+    <string name="permlab_mount_format_filesystems" product="default" msgid="262582698639274056">"ջնջել SD քարտը"</string>
+    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"Թույլ է տալիս հավելվածին ֆորմատավորել շարժական կրիչը:"</string>
+    <string name="permlab_asec_access" msgid="3411338632002193846">"տեղեկություններ ստանալ ներքին պահոցի վերաբերյալ"</string>
+    <string name="permdesc_asec_access" msgid="3094563844593878548">"Թույլ է տալիս հավելվածին ստանալ տեղեկություններ ներքին պահոցի վերաբերյալ:"</string>
+    <string name="permlab_asec_create" msgid="6414757234789336327">"ստեղծել ներքին պահոց"</string>
+    <string name="permdesc_asec_create" msgid="4558869273585856876">"Թույլ է տալիս հավելվածին ստեղծել ներքին պահոց:"</string>
+    <string name="permlab_asec_destroy" msgid="526928328301618022">"ոչնչացնել ներքին պահոցը"</string>
+    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"Թույլ է տալիս հավելվածին ոչնչացնել ներքին պահոցը:"</string>
+    <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"միացնել կամ անջատել ներքին պահոցը"</string>
+    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"Թույլ է տալիս հավելվածին միացնել/անջատել ներքին պահոցը:"</string>
+    <string name="permlab_asec_rename" msgid="7496633954080472417">"վերանվանել ներքին պահոցը"</string>
+    <string name="permdesc_asec_rename" msgid="1794757588472127675">"Թույլ է տալիս հավելվածին վերանվանել ներքին պահոցը:"</string>
+    <string name="permlab_vibrate" msgid="7696427026057705834">"կառավարել թրթռումը"</string>
+    <string name="permdesc_vibrate" msgid="6284989245902300945">"Թույլ է տալիս հավելվածին կառավարել թրթռոցը:"</string>
+    <string name="permlab_flashlight" msgid="2155920810121984215">"կառավարել լապտերը"</string>
+    <string name="permdesc_flashlight" msgid="6522284794568368310">"Թույլ է տալիս հավելվածին կառավարել լապտերը:"</string>
+    <string name="permlab_manageUsb" msgid="1113453430645402723">"կառավարել նախապատվությունները և թույլտվությունները USB սարքերի համար"</string>
+    <string name="permdesc_manageUsb" msgid="7776155430218239833">"Թույլ է տալիս հավելվածին կառավարել նախասիրություններն ու թույլտվությունները USB սարքերի համար:"</string>
+    <string name="permlab_accessMtp" msgid="4953468676795917042">"կիրառել MTP պրոտոկոլը"</string>
+    <string name="permdesc_accessMtp" msgid="6532961200486791570">"Մուտքի հնարավորություն է տալիս միջուկի MTP սարքավարին MTP USB պրոտոկոլը կիրառելու համար:"</string>
+    <string name="permlab_hardware_test" msgid="4148290860400659146">"փորձարկել սարքը"</string>
+    <string name="permdesc_hardware_test" msgid="6597964191208016605">"Թույլ է տալիս հավելվածին կառավարել տարբեր արտաքին սարքավորումեր` սարքաշարի փորձարկման նպատակով:"</string>
+    <string name="permlab_callPhone" msgid="3925836347681847954">"ուղղակիորեն զանգել հեռախոսահամարներին"</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"Թույլ է տալիս հավելվածին զանգել հեռախոսահամարներին առանց ձեր միջամտության: Սա կարող է հանգեցնել անկանխատեսելի գանձումների կամ զանգերի: Նկատի ունեցեք, որ սա թույլ չի տալիս հավելվածին զանգել արտակարգ իրավիճակների համարներին: Վնասարար հավելվածները կարող են ձեր հաշվից զանգեր կատարել` առանց ձեր հաստատման:"</string>
+    <string name="permlab_callPrivileged" msgid="4198349211108497879">"ուղղակիորեն զանգահարել որևէ հեռախոսահամարի"</string>
+    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"Թույլ է տալիս հավելվածին զանգել ցանկացած հեռախոսահամարի, այդ թվում` արտակարգ իրավիճակների համարներին` առանց ձեր միջամտության: Վնասարար հավելվածները կարող են կատարել անցանկալի և անօրինական զանգեր արտակարգ իրավիճակների ծառայություններին:"</string>
+    <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"ուղղակիորեն սկսել CDMA գրասալիկի կագավորումը"</string>
+    <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"ուղղակիորեն սկսել CDMA հեռախոսի կարգավորումը"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"Թույլ է տալիս հավելվածին մեկնարկել CDMA-ի տրամադրումը: Վնասարար հավելվածները կարող են անտեղի սկսել CDMA-ի տրամադրում:"</string>
+    <string name="permlab_locationUpdates" msgid="7785408253364335740">"վերահսկել տեղանքի թարմացման ծանուցումները"</string>
+    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Թույլ է տալիս հավելվածին միացնել կամ անջատել տեղանքի թարմացման ծանուցումները ռադիոյից: Սովորական հավելվածների օգտագործման համար չէ:"</string>
+    <string name="permlab_checkinProperties" msgid="7855259461268734914">"մուտք գործել գրանցանշման կարգավորումներ"</string>
+    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Թույլ է տալիս հավելվածին կարդալ/գրել գրանցանշման ծառայության կողմից վերբեռնված հատկությունների մուտքը: Սովորական հավելվածների օգտագործման համար չէ:"</string>
+    <string name="permlab_bindGadget" msgid="776905339015863471">"ընտրել վիջեթներ"</string>
+    <string name="permdesc_bindGadget" msgid="8261326938599049290">"Թույլ է տալիս հավելվածին թելադրել համակարգին, թե որ վիջեթները որ հավելվածի միջոցով է հնարավոր օգտագործել: Այս թույլտվությամբ հավելվածը կարող է այլ հավելվածներին մուտք տալ դեպի անձնական տվյալներ: Սովորական հավելվածների օգտագործման համար չէ:"</string>
+    <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"փոփոխել հեռախոսի կարգավիճակը"</string>
+    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Թույլ է տալիս հավելվածին կառավարել սարքի հեռախոսային գործիքները: Այս թույլտվությամբ հավելվածը կարող է փոխարկել ցանցերը, միացնելև անջատել հեռախոսի ռադիոն և նման այլ բաներ` առանց ձեզ երբևէ տեղեկացնելու:"</string>
+    <string name="permlab_readPhoneState" msgid="9178228524507610486">"կարդալ հեռախոսի կարգավիճակը և ինքնությունը"</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Թույլ է տալիս հավելվածին օգտագործել սարքի հեռախոսային գործիքները: Այս թույլտվությունը հավելվածին հնարավորություն է տալիս որոշել հեռախոսահամարը և սարքի ID-ները, արդյոք զանգը ակտիվ է և միացված զանգի հեռակա հեռախոսահամարը:"</string>
+    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"զերծ պահել գրասալիկը քնելուց"</string>
+    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"կանխել հեռախոսի քնի ռեժիմին անցնելը"</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Թույլ է տալիս հավելվածին կանխել գրասալիկի` քնի ռեժիմին անցնելը:"</string>
+    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Թույլ է տալիս հավելվածին կանխել հեռախոսի` քնի ռեժիմին անցնելը:"</string>
+    <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"գրասալիկը միացնել կամ անջատել"</string>
+    <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"հեռախոսը միացնել կամ անջատել"</string>
+    <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Թույլ է տալիս հավելվածին միացնել կամ անջատել գրասալիկը:"</string>
+    <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"Թույլ է տալիս հավելվածին միացնել կամ անջատել հեռախոսը:"</string>
+    <string name="permlab_factoryTest" msgid="3715225492696416187">"աշխատել գործարանային փորձնական ռեժիմում"</string>
+    <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"Աշխատեցնել որպես արտադրողի ցածր մակարդակի փորձարկում` թույլատրելով գրասալիկի սարքին լիարժեք մուտք: Հասանելի է միայն այն ժամանակ, երբ գրասալիկը աշխատում է արտադրողի փորձնական ռեժիմում:"</string>
+    <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"Աշխատեցնել որպես արտադրողի ցածր մակարդակի փորձարկում` թույլատրելով լիարժեք մուտք հեռախոսի սարքաշարին: Հասանելի է միայն այն ժամանակ, երբ հեռախոսն աշխատում է արտադրողի փորձնական ռեժիմում:"</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_masterClear" msgid="2315750423139697397">"վերակայել համակարգը գործարանային լռելյայնի"</string>
+    <string name="permdesc_masterClear" msgid="3665380492633910226">"Թույլ է տալիս հավելվածին ամբողջությամբ վերակայել համակարգը իր գործարանային կարգավորումներին` ջնջելով բոլոր տվյալները, կարգավորումները և տեղադրված հավելվածները:"</string>
+    <string name="permlab_setTime" msgid="2021614829591775646">"կարգավորել ժամը"</string>
+    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"Թույլ է տալիս հավելվածին փոխել գրասալիկի ժամացույցի ժամանակը:"</string>
+    <string name="permdesc_setTime" product="default" msgid="1855702730738020">"Թույլ է տալիս հավելվածին փոխել հեռախոսի ժամացույցի ժամանակը:"</string>
+    <string name="permlab_setTimeZone" msgid="2945079801013077340">"կարգավորել ժամային գոտին"</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Թույլ է տալիս հավելվածին փոխել գրասալիկի ժամային գոտին:"</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Թույլ է տալիս հավելվածին փոխել հեռախոսի ժամային գոտին:"</string>
+    <string name="permlab_accountManagerService" msgid="4829262349691386986">"գործել որպես Հաշվի կառավարիչ ծառայություն"</string>
+    <string name="permdesc_accountManagerService" msgid="1948455552333615954">"Թույլ է տալիս հավելվածին զանգել Հաշվի իսկորոշիչներին:"</string>
+    <string name="permlab_getAccounts" msgid="1086795467760122114">"գտնել հաշիվներ սարքում"</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Թույլ է տալիս հավելվածին ստանալ գրասալիկի կողմից ճանաչված հաշիվների ցանկը: Սա կարող է ներառել ցանկացած հաշիվ, որ ստեղծվել է ձեր տեղադրած հավելվածների կողմից:"</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Թույլ է տալիս հավելվածին ստանալ հեռախոսի կողմից ճանաչված հաշիվների ցանկը: Սա կարող է ներառել ցանկացած հաշիվ, որ ստեղծվել է ձեր տեղադրած հավելվածների կողմից:"</string>
+    <string name="permlab_authenticateAccounts" msgid="5265908481172736933">"ստեղծել հաշիվներ և դնել գաղտնաբառեր"</string>
+    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"Թույլ է տալիս հավելվածին օգտագործել հաշվի կառավարչի նույնականացնող հնարավորությունները, ինչպես նաև ստեղծել հաշիվներ, ստանալ և կարգավորել դրանց գաղտնաբառերը:"</string>
+    <string name="permlab_manageAccounts" msgid="4983126304757177305">"ավելացնել կամ հեռացնել հաշիվներ"</string>
+    <string name="permdesc_manageAccounts" msgid="8698295625488292506">"Թույլ է տալիս հավելվածին իրականացնել գործողություններ, ինչպիսիք են` ավելացնել և հեռացնել հաշիվներ և ջնջել դրանց գաղտնաբառերը:"</string>
+    <string name="permlab_useCredentials" msgid="235481396163877642">"օգտագործել սարքի հաշիվները"</string>
+    <string name="permdesc_useCredentials" msgid="7984227147403346422">"Թույլ է տալիս հավելվածին հայցել նույնականացման նշաններ:"</string>
+    <string name="permlab_accessNetworkState" msgid="4951027964348974773">"դիտել ցանցային միացումները"</string>
+    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Թույլ է տալիս հավելվածին տեսնել ցանցային կապերի մասին տեղեկություններ, ինչպես օրինակ, թե ինչ կապեր կան և որոնք են միացված:"</string>
+    <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"լրիվ ցանցային մուտք"</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Թույլ է տալիս հավելվածին ստեղծել ցանցային բնիկներ և օգտագործել հատուկ ցանցային պրոտոկոլներ: Զննարկիչը և այլ հավելվածները միջոցներ են տրամադրում ինտերնետին տվյալներ ուղարկելու համար, ուստի այս թույլտվությունը չի պահանջվում ինտերնետին տվյալներ ուղարկելու համար:"</string>
+    <string name="permlab_writeApnSettings" msgid="505660159675751896">"փոխել/կասեցնել ցանցային կարգավորումները և շարժը"</string>
+    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Թույլ է տալիս հավելվածին փոխել ցանցային կարգավորումները և կասեցնել ու ստուգել ամբողջ ցանցային շարժը, օրինակ` փոխել ցանկացած APN-ի պրոքսին և միացքը: Վնասարար հավելվածները կարող են հետևել, վերահասցեավորել կամ փոփոխել ցանցային փաթեթները` առանց ձեր իմացության:"</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_changeBackgroundDataSetting" msgid="1400666012671648741">"փոխել ֆոնային տվյալների օգտագործման կարգավորումը"</string>
+    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Թույլ է տալիս հավելվածին փոխել ֆոնային տվյալների օգտագործման կարգավորումները:"</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="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="default" msgid="8931682159331542137">"Թույլ է տալիս հավելվածին կարգավորել տեղային Bluetooth հեռախոսը և հայտնաբերել ու զուգակցվել հեռակա սարքերի հետ:"</string>
+    <string name="permlab_accessWimaxState" msgid="4195907010610205703">"միանալ WiMAX-ին և անջատվել դրանից"</string>
+    <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"Թույլ է տալիս հավելվածին պարզել, արդյոք WiMAX-ը միացված է և ցանկացած միացված WiMAX ցանցի մասին տեղեկություններ:"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Փոխել WiMAX-ի կարգավիճակը"</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Թույլ է տալիս հավելվածին գրասալիկը միացնել 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="default" msgid="3207106324452312739">"Թույլ է տալիս հավելվածին տեսնել Bluetooth-ի կարգավորումը հեռախոսի վրա և կապվել ու կապեր ընդունել զուգակցված սարքերի հետ:"</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_readSyncSettings" msgid="6201810008230503052">"կարդալ համաժամեցման կարգավորումները"</string>
+    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Թույլ է տալիս հավելվածին կարդալ համաժամեցման կարգավորումները հաշվի համար: Օրինակ` այն կարող է որոշել, արդյոք Մարդիկ հավելվածը համաժամեցված է հաշվի հետ:"</string>
+    <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"համաժամեցումը փոխարկել միացվածի և անջատվածի"</string>
+    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Թույլ է տալիս հավելվածին փոփոխել համաժամեցման կարգավորումները հաշվի համար: Օրինակ, այն կարող է օգտագործվել` միացնելու Մարդիկ հավելվածի համաժամեցումը հաշվի հետ:"</string>
+    <string name="permlab_readSyncStats" msgid="7396577451360202448">"կարդալ համաժամեցման վիճակագրությունը"</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Թույլ է տալիս հավելվածին կարդալ հաշվի համաժամեցման վիճակագրությունը, այդ թվում` համաժամեցման իրադարձությունների պատմությունը և թե որքան տվյալ է համաժամեցված:"</string>
+    <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"կարդալ բաժանորդագրված հոսքերը"</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Թույլ է տալիս հավելվածին մանրամասներ ստանալ ընթացիկ համաժամեցված հոսքերի մասին:"</string>
+    <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"գրել բաժանորդագրված հոսքերը"</string>
+    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"Թույլ է տալիս հավելվածին փոփոխել ձեր ներկայումս համաժամեցված հոսքերը: Վնասարար հավելվածները կարող են փոխել ձեր համաժամեցված հոսքերը:"</string>
+    <string name="permlab_readDictionary" msgid="4107101525746035718">"կարդալ պայմանները, որ ավելացրել եք բառարանում"</string>
+    <string name="permdesc_readDictionary" msgid="659614600338904243">"Թույլ է տալիս հավելվածին կարդալ բոլոր բառերը, անունները և արտահայտությունները, որոնք օգտագործողը հնարավոր է պահել է օգտվողի բառարանում:"</string>
+    <string name="permlab_writeDictionary" msgid="2183110402314441106">"ավելացնել բառեր օգտվողի համար սահմանված բառարանում"</string>
+    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Թույլ է տալիս հավելվածին գրել նոր բառեր օգտվողի բառարանում:"</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"փորձարկել մուտքը դեպի պաշտպանված պահոց"</string>
+    <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"փորձարկել մուտքը դեպի պաշտպանված պահոց"</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"Թույլ է տալիս հավելվածին փորձարկել USB կրիչի թույլտվությունը, որը հասանելի կլինի հետագա սարքերում:"</string>
+    <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"Թույլ է տալիս հավելվածին փորձարկել 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_mediaStorageWrite" product="default" msgid="6859839199706879015">"փոփոխել/ջնջել ներքին մեդիա կրիչի բովանդակությունը"</string>
+    <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Թույլ է տալիս հավելվածին փոփոխել ներքին մեդիա պահոցի բովանդակությունը:"</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"կառավարել փաստաթղթերի պահոցը"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Թույլ է տալիս հավելվածին կառավարել փաստաթղթի պահոցը:"</string>
+    <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"մուտք ունենալ բոլոր օգտվողների արտաքին պահոց"</string>
+    <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Թույլ է տալիս հավելվածին մուտք գործել արտաքին պահոց բոլոր օգտվողների համար:"</string>
+    <string name="permlab_cache_filesystem" msgid="5656487264819669824">"մուտք քեշի ֆայլերի համակարգ"</string>
+    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Թույլ է տալիս հավելվածին գրել և կարդալ քեշ ֆայլային համակարգը:"</string>
+    <string name="permlab_use_sip" msgid="5986952362795870502">"կատարել կամ ստանալ ինտերնետային զանգեր"</string>
+    <string name="permdesc_use_sip" msgid="4717632000062674294">"Թույլ է տալիս հավելվածին օգտագործել SIP ծառայությունը` ինտերնետային զանգեր կատարելու/ստանալու համար:"</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_markNetworkSocket" msgid="3658527214914959749">"փոփոխել բնիկի նշանները"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Թույլ է տալիս ծրագրին փոփոխել բնիկի նշանները երթուղման համար"</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_invokeCarrierSetup" msgid="3699600833975117478">"գործարկել օպերատորի կողմից տրամադրված կազմաձևման ծրագիրը"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Թույլ է տալիս սեփականատիրոջը գործարկել օպերատորի կողմից տրամադրված կազմաձևման ծրագիրը: Սովորական ծրագրերի համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"լսել դիտարկումներ ցանցային պայմանների վերաբերյալ"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Հավելվածին թույլ է տալիս լսել դիտարկումներ ցանցային պայմանների վերաբերյալ: Սովորական հավելվածների համար երբեք պետք չի գալիս:"</string>
+    <string name="policylab_limitPassword" msgid="4497420728857585791">"Սահմանել գաղտնաբառի կանոնները"</string>
+    <string name="policydesc_limitPassword" msgid="3252114203919510394">"Վերահսկել էկրանի ապակողպման գաղտնաբառերի թույլատրելի երկարությունն ու գրանշանները:"</string>
+    <string name="policylab_watchLogin" msgid="914130646942199503">"Վերահսկել էկրանի ապակողպման փորձերը"</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Վերահսկել սխալ գաղտնաբառերի թիվը, որոնք մուտքագրվել են էկրանն ապակողպելիս, և կողպել գրասալիկը կամ ջնջել գրասալիկի բոլոր տվյալները, եթե մուտքագրվել են չափից շատ սխալ գաղտնաբառեր:"</string>
+    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Վերահսկել սխալ գաղտնաբառերի թիվը, որոնք մուտքագրվել են էկրանն ապակողպելիս, և կողպել հեռախոսը կամ ջնջել հեռախոսի բոլոր տվյալները, եթե մուտքագրվել են չափից շատ սխալ գաղտնաբառեր:"</string>
+    <string name="policylab_resetPassword" msgid="2620077191242688955">"Փոխել էկրանի ապակողպման գաղտնաբառը"</string>
+    <string name="policydesc_resetPassword" msgid="605963962301904458">"Փոխել էկրանի ապակողպման գաղտնաբառը:"</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="default" msgid="5096895604574188391">"Ջնջել հեռախոսի տվյալներն առանց նախազգուշացման` կատարելով գործարանային տվյալների վերակայում:"</string>
+    <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Կարգավորել սարքի համաշխարհային պրոքսին"</string>
+    <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Սարքը կարգավորել, որ համաշխարհային պրոքսին օգտագործվի, երբ քաղաքականությունը միացված է: Միայն առաջին սարքի կառավարիչն է կարգավորում գործող համաշխարհային պրոքսին:"</string>
+    <string name="policylab_expirePassword" msgid="885279151847254056">"Սահմանել էկրանի կողպման գաղտնաբառի սպառման ժամկետը"</string>
+    <string name="policydesc_expirePassword" msgid="1729725226314691591">"Վերահսկել` ինչ հաճախականությամբ պետք է էկրանի կողպման գաղտնաբառը փոխվի:"</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="policylab_disableKeyguardFeatures" msgid="266329104542638802">"Անջատել ստեղնակողպեքի գործառույթները"</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="3467082272186534614">"Կանխել ստեղնակողպեքի որոշ գործառույթների օգտագործումը:"</string>
+  <string-array name="phoneTypes">
+    <item msgid="8901098336658710359">"Տնային"</item>
+    <item msgid="869923650527136615">"Բջջային"</item>
+    <item msgid="7897544654242874543">"Աշխատանքային"</item>
+    <item msgid="1103601433382158155">"Աշխատանքային ֆաքս"</item>
+    <item msgid="1735177144948329370">"Տնային ֆաքս"</item>
+    <item msgid="603878674477207394">"Փեյջեր"</item>
+    <item msgid="1650824275177931637">"Այլ"</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>
+  </string-array>
+  <string-array name="postalAddressTypes">
+    <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="1359644565647383708">"Աշխատանքային"</item>
+    <item msgid="7868549401053615677">"Այլ"</item>
+    <item msgid="3145118944639869809">"Հատուկ"</item>
+  </string-array>
+  <string-array name="organizationTypes">
+    <item msgid="7546335612189115615">"Աշխատանքային"</item>
+    <item msgid="4378074129049520373">"Այլ"</item>
+    <item msgid="3455047468583965104">"Հատուկ"</item>
+  </string-array>
+  <string-array name="imProtocols">
+    <item msgid="8595261363518459565">"AIM"</item>
+    <item msgid="7390473628275490700">"Windows Live"</item>
+    <item msgid="7882877134931458217">"Yahoo"</item>
+    <item msgid="5035376313200585242">"Skype"</item>
+    <item msgid="7532363178459444943">"QQ"</item>
+    <item msgid="3713441034299660749">"Google Talk"</item>
+    <item msgid="2506857312718630823">"ICQ"</item>
+    <item msgid="1648797903785279353">"Jabber"</item>
+  </string-array>
+    <string name="phoneTypeCustom" msgid="1644738059053355820">"Հատուկ"</string>
+    <string name="phoneTypeHome" msgid="2570923463033985887">"Տնային"</string>
+    <string name="phoneTypeMobile" msgid="6501463557754751037">"Բջջային"</string>
+    <string name="phoneTypeWork" msgid="8863939667059911633">"Աշխատանքային"</string>
+    <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Աշխատանքային ֆաքս"</string>
+    <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Տնային ֆաքս"</string>
+    <string name="phoneTypePager" msgid="7582359955394921732">"Փեյջեր"</string>
+    <string name="phoneTypeOther" msgid="1544425847868765990">"Այլ"</string>
+    <string name="phoneTypeCallback" msgid="2712175203065678206">"Ետզանգ"</string>
+    <string name="phoneTypeCar" msgid="8738360689616716982">"Մեքենա"</string>
+    <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Ընկերության գլխավոր"</string>
+    <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string>
+    <string name="phoneTypeMain" msgid="6766137010628326916">"Հիմնական"</string>
+    <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Այլ ֆաքս"</string>
+    <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="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="eventTypeBirthday" msgid="2813379844211390740">"Ծննդյան օր"</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>
+    <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="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="imTypeWork" msgid="1371489290242433090">"Աշխատանքային"</string>
+    <string name="imTypeOther" msgid="5377007495735915478">"Այլ"</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>
+    <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
+    <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</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>
+    <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="relationTypeAssistant" msgid="6274334825195379076">"Օգնական"</string>
+    <string name="relationTypeBrother" msgid="8757913506784067713">"Եղբայր"</string>
+    <string name="relationTypeChild" msgid="1890746277276881626">"Երեխա"</string>
+    <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"Տեղական գործընկեր"</string>
+    <string name="relationTypeFather" msgid="5228034687082050725">"Հայր"</string>
+    <string name="relationTypeFriend" msgid="7313106762483391262">"Ընկեր"</string>
+    <string name="relationTypeManager" msgid="6365677861610137895">"Կառավարիչ"</string>
+    <string name="relationTypeMother" msgid="4578571352962758304">"Մայր"</string>
+    <string name="relationTypeParent" msgid="4755635567562925226">"Ծնող"</string>
+    <string name="relationTypePartner" msgid="7266490285120262781">"Գործընկեր"</string>
+    <string name="relationTypeReferredBy" msgid="101573059844135524">"Հղված է"</string>
+    <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="sipAddressTypeHome" msgid="6093598181069359295">"Տնային"</string>
+    <string name="sipAddressTypeWork" msgid="6920725730797099047">"Աշխատանքային"</string>
+    <string name="sipAddressTypeOther" msgid="4408436162950119849">"Այլ"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Մուտքագրեք PIN կոդը"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Մուտքագրեք PUK-ը և նոր PIN կոդը"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK կոդ"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Նոր PIN ծածկագիր"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><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">"Մուտքագրեք PIN-ը ապակողպման համար"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Սխալ PIN ծածկագիր:"</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="8963839242565653192">"Ծառայություն չկա:"</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="5347633784401285225">"Արտակարգ իրավիճակների հեռախոսազանգ"</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="faceunlock_multiple_failures" msgid="754137583022792429">"Առավելագույն Դեմքով ապակողպման փորձերը գերազանցված են"</string>
+    <string name="lockscreen_plugged_in" msgid="8057762828355572315">"Լիցքավորում, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_charged" msgid="321635745684060624">"Լիցքավորված է"</string>
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_low_battery" msgid="1482873981919249740">"Միացրեք ձեր լիցքավորիչը:"</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="default" msgid="2186920585695169078">"Հեռախոսում SIM քարտ չկա:"</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_transport_prev_description" msgid="201594905152746886">"Նախորդ հետքի կոճակ"</string>
+    <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Հաջորդ հետագծի կոճակ"</string>
+    <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Դադարի կոճակ"</string>
+    <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Նվագարկման կոճակ"</string>
+    <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Կանգի կոճակ"</string>
+    <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">"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">%d</xliff:g> անգամ սխալ եք հավաքել ձեր ապակողպման սխեման: \n\nՓորձեք կրկին <xliff:g id="NUMBER_1">%d</xliff:g> վայրկյանից:"</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Դուք սխալ եք մուտքագրել ձեր գաղտնաբառը <xliff:g id="NUMBER_0">%d</xliff:g> անգամ: \n\n Փորձեք կրկին <xliff:g id="NUMBER_1">%d</xliff:g> վայրկյանից:"</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ եք մուտքագրել ձեր PIN-ը: \n\nՓորձեք կրկին <xliff:g id="NUMBER_1">%d</xliff:g> վայրկյանից:"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ եք հավաքել ձեր ապակողպման սխեման: <xliff:g id="NUMBER_1">%d</xliff:g> անգամից ավել անհաջող փորձերից հետո ձեզ կառաջարկվի ապակողպել ձեր գրասալիկը` օգտագործելով ձեր Google-ի մուտքի օգտանունը:\n \n Փորձեք կրկին <xliff:g id="NUMBER_2">%d</xliff:g> վայրկյանից:"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ եք հավաքել ձեր ապակողպման սխեման: Եվս <xliff:g id="NUMBER_1">%d</xliff:g> անհաջող փորձից հետո ձեզ կառաջարկվի ապակողպել ձեր հեռախոսը` օգտագործելով Google-ի ձեր մուտքը:\n \n Փորձեք կրկին <xliff:g id="NUMBER_2">%d</xliff:g> վայրկյանից:"</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ գրասալիկն ապակողպելու սխալ փորձ եք արել: Եվս <xliff:g id="NUMBER_1">%d</xliff:g> անհաջող փորձից հետո գրասալիկը կվերակարգավորվի գործարանային լռելյայնի, և օգտվողի բոլոր տվյալները կկորեն:"</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ հեռախոսը ապակողպելու սխալ փորձ եք արել: Եվս <xliff:g id="NUMBER_1">%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="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_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_checking_password" msgid="7114627351286933867">"Ստուգվում է..."</string>
+    <string name="lockscreen_unlock_label" msgid="737440483220667054">"Ապակողպել"</string>
+    <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Ձայնը միացնել"</string>
+    <string name="lockscreen_sound_off_label" msgid="996822825154319026">"Անձայն"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Սխեմայի հավաքումը սկսված է"</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Սխեման մաքրված է"</string>
+    <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Ավելացվել է վանդակ"</string>
+    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Սխեմայի հավաքումն ավարտված է"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Վիջեթ %2$d of %3$d:"</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_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>
+    <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_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">"Pin-ն ապակողպված է:"</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>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <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_line" msgid="5764267235026120888">"գիծ"</string>
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</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_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="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>
+    <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
+    <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
+    <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
+    <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
+    <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_county" msgid="237073771020362891">"Մարզ"</string>
+    <string name="autofill_island" msgid="4020100875984667025">"Կղզի"</string>
+    <string name="autofill_district" msgid="8400735073392267672">"Շրջան"</string>
+    <string name="autofill_department" msgid="5343279462564453309">"Դեպարտամենտ"</string>
+    <string name="autofill_prefecture" msgid="2028499485065800419">"Պրեֆեկտուրա"</string>
+    <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="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_packageVerificationAgent" msgid="5568139100645829117">"հաստատել փաթեթները"</string>
+    <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"Թույլ է տալիս հավելվածին հաստատել, որ փաթեթը տեղադրելի է:"</string>
+    <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"միանալ փաթեթի ստուգիչին"</string>
+    <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Թույլ է տալիս սեփականատիրոջը փաթեթի ստուգիչների հարցում կատարել: Սովորական հավելվածների համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+    <string name="permlab_serialPort" msgid="546083327654631076">"մուտք գործել հաջորդական միացքներ"</string>
+    <string name="permdesc_serialPort" msgid="2991639985224598193">"Թույլ է տալիս սեփականատիրոջը մուտք գործել հաջորդական միացքներ` օգտագործելով SerialManager API-ը:"</string>
+    <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"դրսից մատչել բովանդակություն տրամադրողներին"</string>
+    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Սեփականատիրոջը հնարավորություն է տալիս կապվել ծառայության մատակարարների հետ վահանակից: Սովորական հավելվածների համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+    <string name="permlab_updateLock" msgid="3527558366616680889">"կասեցնել սարքի ավտոմատ թարմացումները"</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"Թույլ է տալիս սեփականատիրոջը համակարգին տեղեկացնել հարմար ժամանակի մասին` սարքը նորացնելու նպատակով ոչ փոխազդական վերաբեռնման համար:"</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>
+    <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="menu_space_shortcut_label" msgid="2410328639272162537">"բացակ"</string>
+    <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"մուտք"</string>
+    <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"ջնջել"</string>
+    <string name="search_go" msgid="8298016669822141719">"Որոնել"</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="oneMonthDurationPast" msgid="7396384508953779925">"1 ամիս առաջ"</string>
+    <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Ավելի շուտ քան 1 ամիս"</string>
+  <plurals name="num_seconds_ago">
+    <item quantity="one" msgid="4869870056547896011">"1 վայրկյան առաջ"</item>
+    <item quantity="other" msgid="3903706804349556379">"<xliff:g id="COUNT">%d</xliff:g> վայրկյան առաջ"</item>
+  </plurals>
+  <plurals name="num_minutes_ago">
+    <item quantity="one" msgid="3306787433088810191">"1 րոպե առաջ"</item>
+    <item quantity="other" msgid="2176942008915455116">"<xliff:g id="COUNT">%d</xliff:g> րոպե առաջ"</item>
+  </plurals>
+  <plurals name="num_hours_ago">
+    <item quantity="one" msgid="9150797944610821849">"1 ժամ առաջ"</item>
+    <item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> ժամ առաջ"</item>
+  </plurals>
+  <plurals name="last_num_days">
+    <item quantity="other" msgid="3069992808164318268">"Վերջին <xliff:g id="COUNT">%d</xliff:g> օրերին"</item>
+  </plurals>
+    <string name="last_month" msgid="3959346739979055432">"Անցյալ ամիս"</string>
+    <string name="older" msgid="5211975022815554840">"Ավելի հին"</string>
+  <plurals name="num_days_ago">
+    <item quantity="one" msgid="861358534398115820">"երեկ"</item>
+    <item quantity="other" msgid="2479586466153314633">"<xliff:g id="COUNT">%d</xliff:g> օր առաջ"</item>
+  </plurals>
+  <plurals name="in_num_seconds">
+    <item quantity="one" msgid="2729745560954905102">"1 վայրկյանից"</item>
+    <item quantity="other" msgid="1241926116443974687">"<xliff:g id="COUNT">%d</xliff:g> վայրկյանից"</item>
+  </plurals>
+  <plurals name="in_num_minutes">
+    <item quantity="one" msgid="8793095251325200395">"1 րոպեից"</item>
+    <item quantity="other" msgid="3330713936399448749">"<xliff:g id="COUNT">%d</xliff:g> րոպեից"</item>
+  </plurals>
+  <plurals name="in_num_hours">
+    <item quantity="one" msgid="7164353342477769999">"1 ժամից"</item>
+    <item quantity="other" msgid="547290677353727389">"<xliff:g id="COUNT">%d</xliff:g> ժամից"</item>
+  </plurals>
+  <plurals name="in_num_days">
+    <item quantity="one" msgid="5413088743009839518">"վաղը"</item>
+    <item quantity="other" msgid="5109449375100953247">"<xliff:g id="COUNT">%d</xliff:g> օրից"</item>
+  </plurals>
+  <plurals name="abbrev_num_seconds_ago">
+    <item quantity="one" msgid="1849036840200069118">"1 վրկ առաջ"</item>
+    <item quantity="other" msgid="3699169366650930415">"<xliff:g id="COUNT">%d</xliff:g> վրկ. առաջ"</item>
+  </plurals>
+  <plurals name="abbrev_num_minutes_ago">
+    <item quantity="one" msgid="6361490147113871545">"1 րոպե առաջ"</item>
+    <item quantity="other" msgid="851164968597150710">"<xliff:g id="COUNT">%d</xliff:g> րոպե առաջ"</item>
+  </plurals>
+  <plurals name="abbrev_num_hours_ago">
+    <item quantity="one" msgid="4796212039724722116">"1 ժամ առաջ"</item>
+    <item quantity="other" msgid="6889970745748538901">"<xliff:g id="COUNT">%d</xliff:g> ժամ առաջ"</item>
+  </plurals>
+  <plurals name="abbrev_num_days_ago">
+    <item quantity="one" msgid="8463161711492680309">"երեկ"</item>
+    <item quantity="other" msgid="3453342639616481191">"<xliff:g id="COUNT">%d</xliff:g> օր առաջ"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_seconds">
+    <item quantity="one" msgid="5842225370795066299">"1 վրկ-ից"</item>
+    <item quantity="other" msgid="5495880108825805108">"<xliff:g id="COUNT">%d</xliff:g> վրկ-ից"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_minutes">
+    <item quantity="one" msgid="562786149928284878">"1 րոպեից"</item>
+    <item quantity="other" msgid="4216113292706568726">"<xliff:g id="COUNT">%d</xliff:g> րոպեից"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_hours">
+    <item quantity="one" msgid="3274708118124045246">"1 ժամից"</item>
+    <item quantity="other" msgid="3705373766798013406">"<xliff:g id="COUNT">%d</xliff:g> ժամից"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_days">
+    <item quantity="one" msgid="2178576254385739855">"վաղը"</item>
+    <item quantity="other" msgid="2973062968038355991">"<xliff:g id="COUNT">%d</xliff:g> օրից"</item>
+  </plurals>
+    <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>
+    <string name="days" msgid="4774547661021344602">"օր"</string>
+    <string name="hour" msgid="2126771916426189481">"ժամ"</string>
+    <string name="hours" msgid="894424005266852993">"ժամ"</string>
+    <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="week" msgid="5617961537173061583">"շաբաթ"</string>
+    <string name="weeks" msgid="6509623834583944518">"շաբաթ"</string>
+    <string name="year" msgid="4001118221013892076">"տարի"</string>
+    <string name="years" msgid="6881577717993213522">"տարի"</string>
+  <plurals name="duration_seconds">
+    <item quantity="one" msgid="6962015528372969481">"1 վայրկյան"</item>
+    <item quantity="other" msgid="1886107766577166786">"<xliff:g id="COUNT">%d</xliff:g> վայրկյան"</item>
+  </plurals>
+  <plurals name="duration_minutes">
+    <item quantity="one" msgid="4915414002546085617">"1 րոպե"</item>
+    <item quantity="other" msgid="3165187169224908775">"<xliff:g id="COUNT">%d</xliff:g> րոպե"</item>
+  </plurals>
+  <plurals name="duration_hours">
+    <item quantity="one" msgid="8917467491248809972">"1 ժամ"</item>
+    <item quantity="other" msgid="3863962854246773930">"<xliff:g id="COUNT">%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_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>
+    <string name="midnight" msgid="7166259508850457595">"կեսգիշեր"</string>
+    <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="cut" msgid="3092569408438626261">"Կտրել"</string>
+    <string name="copy" msgid="2681946229533511987">"Պատճենել"</string>
+    <string name="paste" msgid="5629880836805036433">"Տեղադրել"</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="textSelectionCABTitle" msgid="5236850394370820357">"Տեքստի ընտրություն"</string>
+    <string name="addToDictionary" msgid="4352161534510057874">"Ավելացնել բառարանում"</string>
+    <string name="deleteText" msgid="6979668428458199034">"Ջնջել"</string>
+    <string name="inputMethod" msgid="1653630062304567879">"Մուտքագրման եղանակը"</string>
+    <string name="editTextMenuTitle" msgid="4909135564941815494">"Տեքստի գործողությունները"</string>
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Պահոցային տարածքը սպառվում է"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Համակարգի որոշ գործառույթներ հնարավոր է չաշխատեն"</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="4653586947747330058">"Հպեք` լրացուցիչ տեղեկությունները կամ ծրագիրը դադարեցնելու համար:"</string>
+    <string name="ok" msgid="5970060430562524910">"Լավ"</string>
+    <string name="cancel" msgid="6442560571259935130">"Չեղարկել"</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>
+    <string name="capital_on" msgid="1544682755514494298">"Միացնել"</string>
+    <string name="capital_off" msgid="6815870386972805832">"Անջատել"</string>
+    <string name="whichApplication" msgid="4533185947064773386">"ավարտել գործողությունը` օգտագործելով"</string>
+    <string name="alwaysUse" msgid="4583018368000610438">"Օգտագործել լռելյայն այս գործողության համար:"</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="aerr_title" msgid="1905800560317137752"></string>
+    <string name="aerr_application" msgid="932628488013092776">"Ցավոք, <xliff:g id="APPLICATION">%1$s</xliff:g>-ը ընդհատվել է:"</string>
+    <string name="aerr_process" msgid="4507058997035697579">"Ցավոք, <xliff:g id="PROCESS">%1$s</xliff:g> գործընթացը դադարել է:"</string>
+    <string name="anr_title" msgid="4351948481459135709"></string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g>-ը չի արձագանքում:\n\nՑանկանու՞մ եք փակել այն:"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"<xliff:g id="ACTIVITY">%1$s</xliff:g> գործողությունը չի պատասխանում:\n\nՑանկանու՞մ եք այն փակել:"</string>
+    <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g>-ը չի արձագանքում: Ցանկանու՞մ եք փակել այն:"</string>
+    <string name="anr_process" msgid="6513209874880517125">"<xliff:g id="PROCESS">%1$s</xliff:g> գործընթացը չի արձագանքում:\n\nՑանկանու՞մ եք փակել այն:"</string>
+    <string name="force_close" msgid="8346072094521265605">"Լավ"</string>
+    <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_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">"Կրկին ակտիվացնել սա Համակարգի կարգավորումներում &amp;gt Ծրագրեր &gt; Ներբեռնումներ:"</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_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_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="1721681741617898865">"Հպեք` հավելվածին անցնելու համար"</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>
+    <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="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_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_notification" msgid="7044986546477282274">"Ծանուցումների ձայնի ուժգնությունը"</string>
+    <string name="ringtone_default" msgid="3789758980357696936">"Լռելյայն զանգերանգ"</string>
+    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Լռելյայն զանգերանգ (<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_unknown" msgid="5477919988701784788">"Անհայտ զանգերանգ"</string>
+  <plurals name="wifi_available">
+    <item quantity="one" msgid="6654123987418168693">"Wi-Fi ցանցը հասանելի է"</item>
+    <item quantity="other" msgid="4192424489168397386">"հասանելի են Wi-Fi ցանցեր"</item>
+  </plurals>
+  <plurals name="wifi_available_detailed">
+    <item quantity="one" msgid="1634101450343277345">"Բաց Wi-Fi ցանցը հասանելի է"</item>
+    <item quantity="other" msgid="7915895323644292768">"Հասանելի են բաց Wi-Fi ցանցեր"</item>
+  </plurals>
+    <string name="wifi_available_sign_in" msgid="4029489716605255386">"Մուտք գործեք Wi-Fi ցանց"</string>
+    <string name="network_available_sign_in" msgid="8495155593358054676">"Մուտք գործել ցանց"</string>
+    <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
+    <skip />
+    <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Չհաջողվեց միանալ Wi-Fi-ին"</string>
+    <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ունի թույլ ինտերնետ կապ:"</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_enabled_notification_message" msgid="1638949953993894335">"Հպեք կարգավորումների համար"</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_to_connect_title" msgid="4958803948658533637">"Միացման հրավեր"</string>
+    <string name="wifi_p2p_from_message" msgid="570389174731951769">"Ուղարկող`"</string>
+    <string name="wifi_p2p_to_message" msgid="248968974522044099">"Ում`"</string>
+    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"Մուտքագրեք պահանջվող PIN-ը:"</string>
+    <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN-ը`"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"Գրասալիկը ժամանակավորապես կանջատվի Wi-Fi-ից, քանի դեռ այն կապակցված է <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ին"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"Հեռախոսը ժամանակավորապես կանջատվի Wi-Fi-ից, քանի դեռ այն միացված է <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ին"</string>
+    <string name="select_character" msgid="3365550120617701745">"Զետեղել նշան"</string>
+    <string name="sms_control_title" msgid="7296612781128917719">"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="3492025719868078457">"Այս "<font fgcolor="#ffffb060">"-ը կարող է գանձումներ առաջացնել"</font>" ձեր բջջային հաշվի վրա:"</string>
+    <string name="sms_premium_short_code_details" msgid="5523826349105123687"><font fgcolor="#ffffb060">"Սրա հետևանքով ձեր բջջային հաշվին կներկայացվի հաշիվ:"</font></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_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_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="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_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="usb_storage_activity_title" msgid="4465055157209648641">"USB զանգվածային կրիչ"</string>
+    <string name="usb_storage_title" msgid="5901459041398751495">"USB-ն կապակցված  է"</string>
+    <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"Դուք կապակցվել եք ձեր համակարգչին USB-ի միջոցով: Հպեք ներքևի կոճակը, եթե ցանկանում եք պատճենել ֆայլերը ձեր համակարգչի և ձեր Android-ի USB կրիչի միջև:"</string>
+    <string name="usb_storage_message" product="default" msgid="805351000446037811">"Դուք միացել եք ձեր համակարգչին USB-ի միջոցով: Հպեք ներքևի կոճակին, եթե ցանկանում եք պատճենել ֆայլերը ձեր համակարգչի և ձեր Android-ի SD քարտի միջև:"</string>
+    <string name="usb_storage_button_mount" msgid="1052259930369508235">"Միացնել USB կրիչը"</string>
+    <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"Խնդիր է ծագել ձեր USB կրիչը USB զանգվածային կրիչի համար օգտագործելիս:"</string>
+    <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"Խնդիր է ծագել ձեր SD քարտը USB զանգվածային կրիչի համար օգտագործելիս:"</string>
+    <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB-ն կապակցված է"</string>
+    <string name="usb_storage_notification_message" msgid="939822783828183763">"Հպեք` ֆայլերը պատճենելու համար ձեր համակարգչում կամ համակարգչից:"</string>
+    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Անջատել USB կրիչը"</string>
+    <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"Հպեք` USB կրիչն անջատելու համար:"</string>
+    <string name="usb_storage_stop_title" msgid="660129851708775853">"USB կրիչը օգտագործվում է"</string>
+    <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"Նախքան USB կրիչն անջատելը, անջատեք («հանեք») ձեր Android-ի USB կրիչը համակարգչից:"</string>
+    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"Նախքան USB կրիչն անջատելը, անջատեք («հանեք») ձեր Android-ի SD քարտը համակարգչից:"</string>
+    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"Անջատել USB կրիչը"</string>
+    <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"Խնդիր առաջացավ USB կրիչն անջատելիս: Ստուգեք, արդյոք անջատել եք USB հանգույցը, ապա փորձեք կրկին:"</string>
+    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Միացնել USB կրիչը"</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Եթե ​​դուք միացնեք USB կրիչը, որոշ ծրագրեր,որոնցից օգտվում եք, կդադարեն աշխատել և կարող են անհասանելի լինել, քանի դեռ չեք անջատել USB կրիչը:"</string>
+    <string name="dlg_error_title" msgid="7323658469626514207">"USB գործողությունը անհաջող էր"</string>
+    <string name="dlg_ok" msgid="7376953167039865701">"Լավ"</string>
+    <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Կապակցված է որպես մեդիա սարք"</string>
+    <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Միացված է որպես ֆոտոխցիկ"</string>
+    <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Միացված է որպես տեղադրիչ"</string>
+    <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Կապակցված է USB լրասարքի"</string>
+    <string name="usb_notification_message" msgid="2290859399983720271">"Հպեք` այլ USB ընտրանքների համար:"</string>
+    <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Ֆորմատավորե՞լ USB կրիչը:"</string>
+    <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Ֆորմատավորե՞լ SD քարտը:"</string>
+    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Ձեր USB կրիչում պահվող բոլոր ֆայլերը կջնջվեն: Այս գործողությունը անշրջելի է:"</string>
+    <string name="extmedia_format_message" product="default" msgid="14131895027543830">"Ձեր քարտի բոլոր տվյալները կկորեն:"</string>
+    <string name="extmedia_format_button_format" msgid="4131064560127478695">"Ձևաչափ"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"USB վրիպազերծումը միացված է"</string>
+    <string name="adb_active_notification_message" msgid="1016654627626476142">"Հպեք` USB կարգաբերումը կասեցնելու համար:"</string>
+    <string name="select_input_method" msgid="4653387336791222978">"Ընտրեք մուտքագրման եղանակը"</string>
+    <string name="configure_input_methods" msgid="9091652157722495116">"Կարգավորել ներածման եղանակները"</string>
+    <string name="use_physical_keyboard" msgid="6203112478095117625">"Ֆիզիկական ստեղնաշար"</string>
+    <string name="hardware" msgid="7517821086888990278">"Սարքաշար"</string>
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Ընտրեք ստեղնաշարի դիրքը"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Հպեք` ստեղնաշարի դիրքը ընտրելու համար:"</string>
+    <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉՊՋՌՍՎՏՐՑՈՒՓՔԵւՕՖ"</string>
+    <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="candidates_style" msgid="4333913089637062257"><u>"թեկնածուները"</u></string>
+    <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"Պատրաստում է USB կրիչը"</string>
+    <string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"Պատրաստվում է SD քարտը"</string>
+    <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"Սխալների ստուգում:"</string>
+    <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"USB կրիչը դատարկ է"</string>
+    <string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"Դատարկ SD քարտ"</string>
+    <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"USB կրիչը դատարկ է կամ ունի չաջակցվող ֆայլային համակարգ:"</string>
+    <string name="ext_media_nofs_notification_message" product="default" msgid="8641065641786923604">"SD քարտը դատարկ է կամ ունի չաջակցվող ֆայլային համակարգ:"</string>
+    <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"Վնասված USB կրիչ"</string>
+    <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"Վնասված SD քարտ"</string>
+    <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="1795917578395333280">"USB կրիչը վնասված է: Փորձեք վերաֆորմատավորել այն:"</string>
+    <string name="ext_media_unmountable_notification_message" product="default" msgid="1753898567525568253">"SD քարտը վնասված է: Փորձեք վերաֆորմատավորել այն:"</string>
+    <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"USB կրիչն անսպասելիորեն հեռացվել է"</string>
+    <string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"SD քարտը անսպասելիորեն հեռացվել է"</string>
+    <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"Անջատել USB կրիչը հեռացնելուց առաջ` տվյալների կորստից խուսափելու համար:"</string>
+    <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"Անջատել SD քարտը հեռացնելուց առաջ` տվյալների կորստից խուսափելու համար:"</string>
+    <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"USB կրիչը կարող է անվտանգ հեռացվել"</string>
+    <string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"SD քարտն անվտանգ է հեռացման համար"</string>
+    <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"Դուք կարող եք ապահով հեռացնել USB կրիչը:"</string>
+    <string name="ext_media_safe_unmount_notification_message" product="default" msgid="568841278138377604">"Դուք կարող եք անվտանգ հեռացնել SD քարտը:"</string>
+    <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"USB կրիչը հեռացված է"</string>
+    <string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"SD քարտը հեռացված է"</string>
+    <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"USB կրիչը հեռացված է: Մտցրեք նոր կրիչ:"</string>
+    <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"SD քարտը հեռացված է: Տեղադրեք նորը:"</string>
+    <string name="activity_list_empty" msgid="1675388330786841066">"Համընկնող գործունեություններ չգտնվեցին:"</string>
+    <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"թարմացնել բաղադրիչի օգտագործման վիճակագրությունը"</string>
+    <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"Թույլ է տալիս հավելվածին փոփոխել հավաքագրված բաղադրիչի վիճակագրությունը: Սովորական հավելվածների օգտագործման համար չէ:"</string>
+    <string name="permlab_copyProtectedData" msgid="4341036311211406692">"պատճենել բովանդակությունը"</string>
+    <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Թույլ է տալիս հայցել լռելյայն զետեղարանի ծառայությունը` բովանդակությունը պատճենելու համար: Սովորական հավելվածների օգտագործման համար չէ:"</string>
+    <string name="permlab_route_media_output" msgid="1642024455750414694">"Երթուղել մեդիա արտածումը"</string>
+    <string name="permdesc_route_media_output" msgid="4932818749547244346">"Թույլ է տալիս հավելվածին մեդիա արտածումը երթուղել այլ արտաքին սարքեր:"</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Մուտք գործել ստեղնակողպեքով պաշտպանված պահոց"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Թույլ է տալիս հավելվածին մուտք գործել ստեղնակողպեքով պաշտպանված պահոց:"</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Կառավարել ստեղնակողպեքի ցուցադրումը և թաքցնումը"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Թույլ է տալիս հավելվածին կառավարել ստեղնաշարի պաշտպանիչը:"</string>
+    <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Հպեք երկու անգամ` դիտափոխման կարգավորման համար"</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>
+    <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">"Հավաքել հեռախոսահամարը`\nօգտագործելով <xliff:g id="NUMBER">%s</xliff:g>-ը"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Ստեղծել կոնտակտ`\nօգտագործելով <xliff:g id="NUMBER">%s</xliff:g>-ը"</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Հետևյալ մեկ կամ ավել հավելվածներ մուտքի թույլտվության հարցում են անում` այժմ և հետագայում ձեր հաշվին մուտք ունենալու համար:"</string>
+    <string name="grant_credentials_permission_message_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">"Թույլտվության հարցում է արված\n<xliff:g id="ACCOUNT">%s</xliff:g> հաշվի համար:"</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>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"Փոխել պաստառը"</string>
+    <string name="notification_listener_binding_label" msgid="2014162835481906429">"Ծանուցման ունկնդիր"</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="3011306607126450322">"Հպեք` ցանցի կառավարման համար:"</string>
+    <string name="vpn_text_long" msgid="6407351006249174473">"Միացված է <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_error" msgid="6009249814034708175">"VPN սխալը միշտ միացված"</string>
+    <string name="vpn_lockdown_config" msgid="6415899150671537970">"Հպեք կարգավորելու համար"</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="8035230537563503262">"Հպեք` մեքենայի ռեժիմից դուրս գալու համար:"</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"Մուտքը կամ թեժ կետը ակտիվ է"</string>
+    <string name="tethered_notification_message" msgid="6857031760103062982">"Հպեք կարգավորելու համար:"</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="throttle_warning_notification_title" msgid="4890894267454867276">"Շարժական տվյալների օգտագործման բարձր մակարդակ"</string>
+    <string name="throttle_warning_notification_message" msgid="3340822228599337743">"Հպեք` շարժական տվյալների օգտագործման մասին ավելին իմանալու համար:"</string>
+    <string name="throttled_notification_title" msgid="6269541897729781332">"Շարժական տվյալների սահմանը գերազանցված է"</string>
+    <string name="throttled_notification_message" msgid="5443457321354907181">"Հպել` շարժական տվյալների օգտագործման մասին ավելին իմանալու համար:"</string>
+    <string name="no_matches" msgid="8129421908915840737">"Համընկնում չկա"</string>
+    <string name="find_on_page" msgid="1946799233822820384">"Գտեք էջում"</string>
+  <plurals name="matches_found">
+    <item quantity="one" msgid="8167147081136579439">"1 համընկնում"</item>
+    <item quantity="other" msgid="4641872797067609177">"<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="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"Անջատվում է USB կրիչը..."</string>
+    <string name="progress_unmounting" product="default" msgid="1327894998409537190">"Անջատում է SD քարտը..."</string>
+    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"Ջնջում է USB կրիչը..."</string>
+    <string name="progress_erasing" product="default" msgid="6596988875507043042">"Ջնջում է SD քարտը..."</string>
+    <string name="format_error" product="nosdcard" msgid="6299769563624776948">"Չհաջողվեց ջնջել USB կրիչը:"</string>
+    <string name="format_error" product="default" msgid="7315248696644510935">"SD քարտը չհաջողվեց ջնջել:"</string>
+    <string name="media_bad_removal" msgid="7960864061016603281">"SD քարտը հեռացվել է նախքան անջատելը:"</string>
+    <string name="media_checking" product="nosdcard" msgid="418188720009569693">"USB կրիչն այժմ ստուգվում է:"</string>
+    <string name="media_checking" product="default" msgid="7334762503904827481">"SD քարտը այժմ ստուգվում է:"</string>
+    <string name="media_removed" msgid="7001526905057952097">"SD քարտը հեռացվել է:"</string>
+    <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"USB կրիչն այժմ օգտագործվում է համակարգչի կողմից:"</string>
+    <string name="media_shared" product="default" msgid="5706130568133540435">"SD քարտն այժմ օգտագործվում է համակարգչի կողմից:"</string>
+    <string name="media_unknown_state" msgid="729192782197290385">"Արտաքին մեդիան անհայտ է վիճակում է:"</string>
+    <string name="share" msgid="1778686618230011964">"Տարածել"</string>
+    <string name="find" msgid="4808270900322985960">"Գտնել"</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="gpsNotifMessage" msgid="1374718023224000702">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)-ի հարցմամբ"</string>
+    <string name="gpsVerifYes" msgid="2346566072867213563">"Այո"</string>
+    <string name="gpsVerifNo" msgid="1146564937346454865">"Ոչ"</string>
+    <string name="sync_too_many_deletes" msgid="5296321850662746890">"Ջնջելու սահմանը գերազանցվել է"</string>
+    <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> ջնջված տարր կա <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>-ի համար, <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>-ի հաշիվ: Ի՞նչ եք ցանկանում անել:"</string>
+    <string name="sync_really_delete" msgid="2572600103122596243">"Ջնջել տարրերը"</string>
+    <string name="sync_undo_deletes" msgid="2941317360600338602">"Հետարկել ջնջումները"</string>
+    <string name="sync_do_nothing" msgid="3743764740430821845">"Առայժմ ոչինչ չանեք"</string>
+    <string name="choose_account_label" msgid="5655203089746423927">"Ընտրել հաշիվը"</string>
+    <string name="add_account_label" msgid="2935267344849993553">"Ավելացնել հաշիվ"</string>
+    <string name="add_account_button_label" msgid="3611982894853435874">"Ավելացնել հաշիվ"</string>
+    <string name="number_picker_increment_button" msgid="2412072272832284313">"Ավելացնել"</string>
+    <string name="number_picker_decrement_button" msgid="476050778386779067">"Նվազեցնել"</string>
+    <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> հպեք և պահեք:"</string>
+    <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Սահեցրեք վերև` ավելացնելու համար, և ներքև` նվազեցնելու համար:"</string>
+    <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Աճեցնել րոպեն"</string>
+    <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Նվազեցնել րոպեն"</string>
+    <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Աճեցնել ժամը"</string>
+    <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Նվազեցնել ժամը"</string>
+    <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Դնել PM"</string>
+    <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Դնել AM"</string>
+    <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Աճեցնել ամիսը"</string>
+    <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Նվազեցնել ամիսը"</string>
+    <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Աճեցնել օրը"</string>
+    <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Նվազեցնել օրը"</string>
+    <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Աճեցնել տարին"</string>
+    <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Նվազեցնել տարին"</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_enter" msgid="2985864015076059467">"Մուտք"</string>
+    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Ընտրել ծրագիր"</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_direction_up" msgid="7169032478259485180">"Սահեցրեք վերև <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-ի համար:"</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Սահեցրեք ցած <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="description_direction_right" msgid="8034433242579600980">"Սահեցրեք աջ` <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-ի համար:"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Ապակողպել"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Ֆոտոխցիկ"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Լուռ"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Ձայնը միացնել"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Որոնել"</string>
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Սահեցրեք` ապակողպելու համար:"</string>
+    <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Միացրեք ականջակալները` արտասանվող գաղտնաբառը լսելու համար:"</string>
+    <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Կետ:"</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="4891916833657929263">"Ներքին պահոց"</string>
+    <string name="storage_sd_card" msgid="3282948861378286745">"SD քարտ"</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="1955638862122232342">"Տվյալների օգտագործման նախազգուշացում"</string>
+    <string name="data_usage_warning_body" msgid="2814673551471969954">"Հպեք` օգտագործումը և կարգավորումները տեսնելու համար:"</string>
+    <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-3G տվյալները կասեցված են"</string>
+    <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G տվյալները անջատված են"</string>
+    <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Շարժական տվյալները կասեցված են"</string>
+    <string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"Wi-Fi տվյալները անջատված են"</string>
+    <string name="data_usage_limit_body" msgid="3317964706973601386">"Հպեք` միացնելու համար:"</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_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="6741521330997452990">"Հպեք` սահմանափակումը հեռացնելու համար:"</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>
+    <string name="org_unit" msgid="7265981890422070383">"Կազմակերպական միավոր`"</string>
+    <string name="issued_by" msgid="2647584988057481566">"Թողարկվել է`"</string>
+    <string name="validity_period" msgid="8818886137545983110">"Վավերականություն`"</string>
+    <string name="issued_on" msgid="5895017404361397232">"Թողարկվել է`"</string>
+    <string name="expires_on" msgid="3676242949915959821">"Սպառվում է`"</string>
+    <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>
+    <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Տեսնել բոլորը"</string>
+    <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Ընտրել գործունեությունը"</string>
+    <string name="share_action_provider_share_with" msgid="5247684435979149216">"Տարածել"</string>
+    <string name="status_bar_device_locked" msgid="3092703448690669768">"Սարքը կողպված է:"</string>
+    <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="3245653681008218030">"Ուղարկվում է..."</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="default_audio_route_name" product="tablet" msgid="4617053898167127471">"Գրասալիկ"</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="media_route_chooser_grouping_done" msgid="7966438307723317169">"Կատարված է"</string>
+    <string name="media_route_button_content_description" msgid="5758553567065145276">"Մեդիա արտածում"</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>
+    <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_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>. <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> կմվ"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", անվտանգ"</string>
+    <string name="wifi_display_notification_title" msgid="2223050649240326557">"Անլար ցուցադրումը կապակցված է"</string>
+    <string name="wifi_display_notification_message" msgid="4498802012464170685">"Այս էկրանը ցուցադրվում է այլ սարքում"</string>
+    <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Անջատել"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Արտակարգ իրավիճակի հեռախոսազանգ"</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">"Սխալ PIN"</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">"Մուտքագրեք SIM-ի PIN-ը"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Մուտքագրեք PIN-ը"</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">"Մուտքագրեք ցանկալի PIN ծածկագիրը"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Հաստատեք ցանկալի PIN ծածկագիրը"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Ապակողպում է SIM քարտը ..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Սխալ PIN ծածկագիր:"</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Մուտքագրեք PIN, որը 4-ից 8 թիվ է:"</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK կոդը պետք է լինի 8 կամ ավելի թիվ:"</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Վերամուտքագրեք ճիշտ PUK ծածկագիրը: Կրկնվող փորձերը ընդմիշտ կկասեցնեն SIM քարտը:"</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN ծածկագրերը չեն համընկնում"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Չափից շատ սխեմայի փորձեր"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Ապակողպելու համար` մուտք գործեք ձեր Google հաշվով:"</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"Հաշիվը ստուգվում է..."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ եք մուտքագրել ձեր PIN-ը: \n\nՓորձեք կրկին <xliff:g id="NUMBER_1">%d</xliff:g> վայրկյանից:"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Դուք սխալ եք մուտքագրել ձեր գաղտնաբառը <xliff:g id="NUMBER_0">%d</xliff:g> անգամ: \n\nՓորձեք կրկին <xliff:g id="NUMBER_1">%d</xliff:g> վայրկյանից:"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ եք հավաքել ձեր ապակողպման սխեման: \n\nՓորձեք կրկին <xliff:g id="NUMBER_1">%d</xliff:g> վայրկյանից:"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ փորձ եք արել գրասալիկն ապակողպելու համար: <xliff:g id="NUMBER_1">%d</xliff:g> անգամից ավել անհաջող փորձերից հետո գրասալիկը կվերակարգավորվի գործարանային լռելյայնի, և օգտվողի բոլոր տվյալները կկորեն:"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ փորձ եք արել հեռախոսն ապակողպելու համար: <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> անգամ: Եվս <xliff:g id="NUMBER_1">%d</xliff:g> անհաջող փորձից հետո ձեզանից կպահանջվի ապակողպել ձեր գրասալիկը` օգտագործելով էլփոստի հաշիվ:\n\n Փորձեք կրկին <xliff:g id="NUMBER_2">%d</xliff:g> վայրկյանից:"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ եք հավաքել ձեր ապակողպման նմուշը: <xliff:g id="NUMBER_1">%d</xliff:g> անգամից ավել անհաջող փորձերից հետո ձեզ կառաջարկվի ապակողպել ձեր հեռախոսը` օգտագործելով էլփոստի հաշիվ:\n\n Փորձեք կրկին <xliff:g id="NUMBER_2">%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="7324161939475478066">"Բարձրացնե՞լ ձայնը առաջարկվող շեմից բարձր:\nԵրկար ժամանակ բարձրաձայն լսելը կարող է վնասել ձեր լսողությունը:"</string>
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Սեղմած պահեք երկու մատները` մատչելիությունը միացնելու համար:"</string>
+    <string name="accessibility_enabled" msgid="1381972048564547685">"Մատչելիությունը միացված է:"</string>
+    <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Մուտքի հնարավորությունը չեղարկված է:"</string>
+    <string name="user_switched" msgid="3768006783166984410">"Ներկայիս օգտվողը <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="app_no_restricted_accounts" msgid="5739463249673727736">"Այս ծրագիրը չի աջակցում սահմանափակված պրոֆիլների հաշիվներ:"</string>
+    <string name="app_not_found" msgid="3429141853498927379">"Այս գործողությունը կատարելու համար ոչ մի ծրագիր չի գտնվել:"</string>
+    <string name="revoke" msgid="5404479185228271586">"Չեղարկել"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Չեղարկված է"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Բովանդակության գրելու սխալ"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Մուտքագրեք PIN-ը"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Ընթացիկ PIN"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Նոր PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Հաստատեք նոր PIN-ը"</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_too_short" msgid="8173982756265777792">"PIN-ը չափազանց կարճ է: Պետք է ունենա առնվազն 4 թվանիշ:"</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="4835639969503729874">"PIN-ը սխալ է: Փորձեք կրկին 1 վայրկյանից:"</item>
+    <item quantity="other" msgid="8030607343223287654">"PIN-ը սխալ է: Փորձեք կրկին <xliff:g id="COUNT">%d</xliff:g> վայրկյանից:"</item>
+  </plurals>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Սահեցրեք էկրանի եզրով՝ գոտին բացելու համար"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Սահեցրեք էկրանի եզրով՝ համակարգային գոտին բացելու համար"</string>
+</resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 3db9137..078fb0c 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -131,6 +131,11 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Terlalu banyak <xliff:g id="CONTENT_TYPE">%s</xliff:g> penghapusan."</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Penyimpanan tablet penuh. Hapus beberapa file untuk mengosongkan ruang."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Penyimpanan di ponsel penuh. Hapus sebagian file untuk mengosongkan ruang."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Jaringan mungkin dipantau"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Saya"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opsi tablet"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Opsi telepon"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Memungkinkan aplikasi memindah tugas ke latar depan dan latar belakang. Aplikasi dapat melakukannya tanpa masukan dari Anda."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"menghentikan apl yang berjalan"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Memungkinkan apl menghapus tugas dan menutup aplikasinya. Apl berbahaya dapat mengganggu perilaku apl lain."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"mengelola tumpukan aktivitas"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Memungkinkan aplikasi menambahkan, menghapus, dan mengubah tumpukan aktivitas yang dijalankan oleh aplikasi lain. Aplikasi berbahaya dapat mengganggu perilaku aplikasi lain."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"memulai aktivitas apa pun"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Mengizinkan aplikasi memulai aktivitas apa pun, terlepas dari perlindungan izin atau status yang diekspor."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"menyetel kompatibilitas layar"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Mengizinkan pemegang mengikat antarmuka tingkat tinggi dari suatu metode masukan. Tidak pernah diperlukan oleh apl normal."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"mengikat ke layanan aksesibilitas"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Mengizinkan pemegang untuk mengikat antarmuka tingkat tinggi dari suatu layanan. Tidak pernah diperlukan oleh aplikasi normal."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"mengikat ke layanan pencetakan"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Memungkinkan pemegang mengikat antarmuka tingkat tinggi dari suatu layanan pencetakan. Tidak pernah diperlukan oleh aplikasi normal."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"mengikat ke layanan penampung pencetakan"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Memungkinkan pemegang mengikat antarmuka tingkat tinggi dari layanan penampung pencetakan. Tidak pernah diperlukan oleh aplikasi normal."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"mengikat ke layanan NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Memungkinkan pemegang mengikat ke aplikasi yang meniru kartu NFC. Tidak pernah dibutuhkan untuk aplikasi normal."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"mengikat ke layanan SMS"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Mengizinkan pemegang mengikat antarmuka tingkat tinggi dari suatu layanan teks (misal: SpellCheckerService). Tidak pernah diperlukan oleh apl normal."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"mengikat ke layanan VPN"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Mengizinkan pemegang mengikat antarmuka tingkat tinggi dari suatu layanan widget. Tidak pernah diperlukan oleh apl normal."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"berinteraksi dengan admin perangkat"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Mengizinkan pemegang mengirimkan tujuan kepada administrator perangkat. Tidak pernah diperlukan oleh apl normal."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"menambah atau menghapus admin perangkat"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Memungkinkan pemegang menambahkan atau menghapus administrator perangkat aktif. Tidak pernah dibutuhkan oleh aplikasi normal."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"ubah orientasi layar"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Mengizinkan apl mengubah rotasi layar kapan saja. Tidak pernah dibutuhkan oleh apl normal."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"ubah kecepatan penunjuk"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Mengizinkan apl membaca dari berbagai file log sistem. Izin ini memungkinkan apl menemukan informasi umum tentang hal-hal yang Anda lakukan di ponsel, kemungkinan termasuk informasi pribadi."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"menggunakan media pengawasandi apa pun untuk pemutaran"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Mengizinkan apl menggunakan pengawasandi media apa pun yang terpasang guna mengawasandikan media untuk diputar."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"kelola kredensial tepercaya"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Izinkan aplikasi memasang dan mencopot pemasangan sertifikat CA sebagai kredensial tepercaya."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"baca/tulis ke sumber daya yang dimiliki oleh diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Mengizinkan apl membaca dan menulis ke sumber daya apa pun yang dimiliki oleh grup diag; misalnya, file dalam /dev. Izin ini berpotensi memengaruhi kestabilan dan keamanan sistem. Sebaiknya ini HANYA digunakan untuk diagnosis khusus perangkat keras oleh pabrikan atau operator."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"mengaktifkan atau menonaktifkan komponen apl"</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Izinkan aplikasi mengonfigurasi dan terhubung ke tampilan Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"mengontrol tampilan Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Izinkan aplikasi mengontrol fitur tingkat rendah dari tampilan Wi-Fi."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"tangkap keluaran audio"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Memungkinkan aplikasi menangkap dan mengalihkan keluaran audio."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"tangkap keluaran video"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Memungkinkan aplikasi menangkap dan mengalihkan keluaran video."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"tangkap keluaran video aman"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Memungkinkan aplikasi menangkap dan mengalihkan keluaran video aman."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"ubah setelan audio Anda"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Memungkinkan aplikasi mengubah setelan audio global, misalnya volume dan pengeras suara mana yang digunakan untuk keluaran."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"rekam audio"</string>
@@ -525,6 +552,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"mencegah ponsel menjadi tidak aktif"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Mengizinkan apl mencegah tablet tidur."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Mengizinkan apl mencegah ponsel tidur."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"hidupkan atau matikan tablet"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"daya ponsel hidup atau mati"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Mengizinkan apl menyalakan atau mematikan tablet."</string>
@@ -607,12 +640,14 @@
     <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"akses uji coba ke penyimpanan yang dilindungi"</string>
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"Memungkinkan aplikasi menguji izin penyimpanan USB yang akan tersedia di perangkat mendatang."</string>
     <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"Memungkinkan aplikasi menguji izin untuk kartu SD yang akan tersedia pada perangkat yang akan datang."</string>
-    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"ubah/hapus konten pympanan USB"</string>
+    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"ubah/hapus isi penyimpanan USB"</string>
     <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"mengubah atau menghapus konten kartu SD Anda"</string>
     <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Mengizinkan apl menulis ke penyimpanan USB."</string>
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Memungkinkan apl menulis ke kartu SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"ubah/hapus konten penyimpanan media internal"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Mengizinkan apl memodifikasi konten penyimpanan media internal."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"kelola penyimpanan dokumen"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Mengizinkan aplikasi mengelola penyimpanan dokumen."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"akses penyimpanan eksternal"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Izinkan aplikasi mengakses penyimpanan eksternal untuk semua pengguna."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"akses sistem file cache."</string>
@@ -625,10 +660,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Mengizinkan apl mengelola kebijakan jaringan dan menentukan peraturan khusus apl."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"mengubah penghitungan penggunaan jaringan"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Mengizinkan apl memodifikasi cara penggunaan jaringan diperhitungkan terhadap apl. Tidak untuk digunakan oleh apl normal."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"mengubah tanda soket"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Memungkinkan aplikasi mengubah tanda soket untuk perutean"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"mengakses pemberitahuan"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Mengizinkan aplikasi mengambil, memeriksa, dan menghapus pemberitahuan, termasuk pemberitahuan yang diposkan oleh aplikasi lain."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"mengikat layanan pendengar pemberitahuan"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Memungkinkan pemegang mengikat antarmuka tingkat teratas dari suatu layanan pendengar pemberitahuan. Tidak pernah diperlukan oleh aplikasi normal."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"memanggil aplikasi konfigurasi yang disediakan operator"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Memungkinkan pemegang meminta aplikasi konfigurasi yang disediakan operator. Tidak pernah diperlukan aplikasi normal."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"mendengar untuk observasi kondisi jaringan"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Memungkinkan aplikasi mendengar untuk observasi kondisi jaringan. Tidak pernah dibutuhkan oleh aplikasi normal."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Setel aturan sandi"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrol panjang dan karakter yang diizinkan dalam sandi pembuka layar."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Upaya pembukaan kunci layar monitor"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +836,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Masukkan kartu SIM."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Kartu SIM tidak ada atau tidak dapat dibaca. Masukkan kartu SIM."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Kartu SIM tidak dapat digunakan."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Kartu SIM Anda telah dinonaktifkan secara permanen."\n" Hubungi penyedia layanan nirkabel Anda untuk kartu SIM lain."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Kartu SIM Anda telah dinonaktifkan secara permanen.\n Hubungi penyedia layanan nirkabel Anda untuk kartu SIM lain."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Tombol trek sebelumnya"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Tombol trek berikutnya"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Tombol jeda"</string>
@@ -808,11 +848,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Lihatlah Panduan Pengguna atau hubungi Layanan Pelanggan."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Kartu SIM terkunci."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Membuka kartu SIM…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. "\n\n"Coba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> detik."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah mengetik sandi. "\n\n"Coba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> detik."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah mengetik PIN. "\n\n"Coba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> detik."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci tablet menggunakan proses masuk Google."\n\n"Coba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> detik."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci ponsel menggunakan proses masuk Google."\n\n"Coba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> detik."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> detik."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah mengetik sandi. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> detik."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah mengetik PIN. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> detik."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci tablet menggunakan proses masuk Google.\n\nCoba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> detik."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci ponsel menggunakan proses masuk Google.\n\nCoba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> detik."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Anda telah gagal mencoba membuka gembok tablet sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> upaya gagal lagi, tablet akan disetel ulang ke setelan default pabrik dan semua data pengguna hilang."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Anda telah gagal mencoba membuka gembok ponsel sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> upaya gagal lagi, ponsel akan disetel ulang ke setelan default pabrik dan semua data pengguna hilang."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Anda telah gagal mencoba membuka gembok tablet sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Kini tablet akan disetel ulang ke setelan default pabrik."</string>
@@ -826,7 +866,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Sandi"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Masuk"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nama pengguna atau sandi tidak valid."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Lupa nama pengguna atau sandi Anda?"\n"Kunjungi "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Lupa nama pengguna atau sandi Anda?\nKunjungi "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Memeriksa..."</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Buka kunci"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Suara hidup"</string>
@@ -874,7 +914,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\n"Yakin 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 laman 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>
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"Sayangnya, <xliff:g id="APPLICATION">%1$s</xliff:g> telah berhenti."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Sayangnya, proses <xliff:g id="PROCESS">%1$s</xliff:g> telah berhenti."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> tidak menanggapi."\n\n"Anda ingin menutupnya?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Aktivitas <xliff:g id="ACTIVITY">%1$s</xliff:g> tidak menanggapi."\n\n"Anda ingin menutupnya?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> tidak menanggapi.\n\nAnda ingin menutupnya?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Aktivitas <xliff:g id="ACTIVITY">%1$s</xliff:g> tidak menanggapi.\n\nAnda ingin menutupnya?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> tidak menanggapi. Anda ingin menutupnya?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Proses <xliff:g id="PROCESS">%1$s</xliff:g> tidak menanggapi."\n\n"Anda ingin menutupnya?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Proses <xliff:g id="PROCESS">%1$s</xliff:g> tidak menanggapi.\n\nAnda ingin menutupnya?"</string>
     <string name="force_close" msgid="8346072094521265605">"Oke"</string>
     <string name="report" msgid="4060218260984795706">"Laporkan"</string>
     <string name="wait" msgid="7147118217226317732">"Tunggu"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"Laman ini tidak menanggapi."\n\n"Apakah Anda ingin menutupnya?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Laman ini tidak menanggapi.\n\nApakah Anda ingin menutupnya?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Apl dialihkan"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang berjalan."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> telah diluncurkan aslinya."</string>
@@ -1256,6 +1296,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Mengizinkan apl menjalankan layanan kontainer default untuk menyalin konten. Tidak untuk digunakan oleh apl normal."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Menentukan rute keluaran media"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Memungkinkan aplikasi menentukan rute keluaran media ke perangkat eksternal lainnya."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Mengakses pengaman penyimpanan aman"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Mengizinkan aplikasi mengakses pengaman penyimpanan aman."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Kontrol untuk menampilkan dan menyembunyikan pengaman"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Izinkan aplikasi untuk mengontrol pengaman."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Sentuh dua kali untuk mengontrol perbesar/perkecil"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Tidak dapat menambahkan widget."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Buka"</string>
@@ -1265,15 +1309,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Selesai"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Sebelumnya"</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Lakukan"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Panggil nomor "\n"menggunakan<xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Buat kontak "\n"menggunakan <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Panggil nomor \nmenggunakan<xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Buat kontak \nmenggunakan <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Satu atau beberapa apl meminta izin untuk mengakses akun Anda, sekarang dan di masa mendatang."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Apakah Anda ingin mengizinkan permintaan ini?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Permintaan akses"</string>
     <string name="allow" msgid="7225948811296386551">"Izinkan"</string>
     <string name="deny" msgid="2081879885755434506">"Tolak"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Izin dimintakan"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Izin dimintakan"\n"untuk akun <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Izin dimintakan\nuntuk akun <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Metode masukan"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Sinkron"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Aksesibilitas"</string>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Lihat semua"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Pilih kegiatan"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Berbagi dengan"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Perangkat tergembok."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Mengirim..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Luncurkan Browser?"</string>
@@ -1441,10 +1484,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Menyambung..."</string>
     <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_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>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", aman"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Layar nirkabel tersambung"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Layar ini ditampilkan di perangkat lain"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Putuskan sambungan"</string>
@@ -1453,7 +1498,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Pola Salah"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Sandi Salah"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN Salah"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Coba lagi dalam <xliff:g id="NUMBER">%d</xliff:g> detik."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Coba lagi dalam <xliff:g id="NUMBER">%1$d</xliff:g> detik."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Gambar pola Anda"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Masukkan PIN SIM"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Masukkan PIN"</string>
@@ -1473,27 +1518,85 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Sandi"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Masuk"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nama pengguna atau sandi tidak valid."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Lupa nama pengguna atau sandi Anda?"\n"Kunjungi "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Lupa nama pengguna atau sandi Anda?\nKunjungi "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Memeriksa akun…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah mengetik PIN. "\n\n"Coba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> detik."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah mengetik sandi. "\n\n"Coba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> detik."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. "\n\n"Coba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> detik."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah mengetik PIN. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> detik."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah mengetik sandi. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> detik."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> detik."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali gagal saat berusaha membuka kunci tablet. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, tablet akan disetel ulang ke setelan default pabrik dan semua data pengguna akan hilang."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali gagal saat berusaha membuka kunci ponsel. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, ponsel akan disetel ulang ke setelan default pabrik dan semua data pengguna akan hilang."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali gagal saat berusaha membuka kunci tablet. Kini tablet akan disetel ulang ke setelan default pabrik."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali gagal saat berusaha untuk membuka kunci ponsel. Kini ponsel akan disetel ulang ke setelan default pabrik."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci tablet menggunakan akun email."\n\n"Coba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> detik."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci ponsel menggunakan akun email."\n\n"Coba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> detik."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci tablet menggunakan akun email.\n\nCoba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> detik."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci ponsel menggunakan akun email.\n\nCoba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> detik."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Hapus"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Naikkan volume di atas tingkat aman?"\n"Mendengarkan volume tinggi dalam jangka waktu yang lama dapat merusak pendengaran Anda."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Naikkan volume di atas tingkat aman?\nMendengarkan volume tinggi dalam jangka waktu yang lama dapat merusak pendengaran Anda."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Tahan terus dua jari untuk mengaktifkan aksesibilitas."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Aksesibilitas diaktifkan."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Aksesibilitas dibatalkan."</string>
     <string name="user_switched" msgid="3768006783166984410">"Pengguna saat ini <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Pemilik"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Kesalahan"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Aplikasi ini tidak mendukung akun untuk profil yang dibatasi"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Aplikasi ini tidak mendukung akun untuk profil yang dibatasi"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Tidak ada aplikasi yang ditemukan untuk menangani tindakan ini"</string>
     <string name="revoke" msgid="5404479185228271586">"Cabut"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Dibatalkan"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Terjadi kesalahan saat menulis konten"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"tak diketahui"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Masukkan PIN administrator"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Masukkan PIN"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Tidak benar"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN Saat Ini"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"PIN Baru"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Konfirmasi PIN baru"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Buat PIN untuk mengubah batasan"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PIN tidak cocok. Coba lagi."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"PIN terlalu pendek. Minimal 4 digit."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Coba 1 dtk lagi"</item>
+    <item quantity="other" msgid="4730868920742952817">"Coba <xliff:g id="COUNT">%d</xliff:g> detik lagi"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Coba lagi nanti"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Gesek tepi layar untuk membuka bilah"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Gesek dari bagian tepi layar untuk membuka bilah sistem"</string>
 </resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 416c534..613715b 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -131,6 +131,11 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Troppe eliminazioni di <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Spazio di archiviazione del tablet esaurito. Elimina alcuni file per liberare spazio."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Spazio di archiviazione del telefono esaurito. Elimina alcuni file per liberare spazio."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"La rete potrebbe essere monitorata"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Io"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opzioni tablet"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Opzioni telefono"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Consente all\'applicazione di spostare attività in primo piano e in background. L\'applicazione potrebbe farlo senza un tuo comando."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"interruzione applicazioni in esecuzione"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Consente all\'applicazione di rimuovere le attività e terminare le loro applicazioni. Le applicazioni dannose potrebbero interferire con il comportamento di altre applicazioni."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"gestione di stack attività"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Consente all\'app di aggiungere, rimuovere e modificare stack attività in cui vengono eseguite altre app. Le app dannose possono alterare il funzionamento delle altre app."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"inizio di un\'attività"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Consente all\'applicazione di iniziare un\'attività, indipendentemente dalla protezione delle autorizzazioni o dallo stato esportato."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"impostazione compatibilità schermo"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Consente l\'associazione di un metodo di inserimento all\'interfaccia principale. Non dovrebbe mai essere necessaria per le normali applicazioni."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"collegamento a un servizio di accessibilità"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Consente al titolare di collegarsi all\'interfaccia di primo livello di un servizio di accessibilità. Non dovrebbe essere mai necessaria per le normali applicazioni."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"collegamento a un servizio di stampa"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Consente al titolare di collegarsi all\'interfaccia di primo livello di un servizio di stampa. Non dovrebbe essere mai necessaria per le normali applicazioni."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"collegamento a un servizio spooler di stampa"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Consente al titolare di collegarsi all\'interfaccia di primo livello di un servizio spooler di stampa. Non dovrebbe essere mai necessaria per le normali app."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"associazione a servizio NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Consente al titolare di collegarsi alle applicazioni che emulano carte NFC. Non dovrebbe mai essere necessario per le normali applicazioni."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"associazione a un servizio di testo"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Consente al titolare di collegarsi all\'interfaccia di primo livello di un servizio di testo (ad esempio SpellCheckerService). Non dovrebbe essere mai necessaria per le normali applicazioni."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"associazione a un servizio VPN"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Consente l\'associazione all\'interfaccia principale di un servizio widget. Non dovrebbe mai essere necessario per le normali applicazioni."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interazione con un amministratore dispositivo"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Consente l\'invio di intent a un amministratore del dispositivo. L\'autorizzazione non dovrebbe mai essere necessaria per le normali applicazioni."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"aggiungere o rimuovere un amministratore del dispositivo"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Consente al titolare di aggiungere o rimuovere gli amministratori attivi del dispositivo. Non dovrebbe mai essere necessario per le normali applicazioni."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"modifica orientamento dello schermo"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Consente all\'applicazione di cambiare la rotazione dello schermo in qualsiasi momento. Non dovrebbe mai essere necessario per le normali applicazioni."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"cambio velocità del puntatore"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Consente all\'applicazione di leggere vari file di registro del sistema per trovare informazioni generali sulle operazioni effettuate con il telefono. Tali file potrebbero contenere informazioni personali o riservate."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"uso di qualsiasi decoder multimediale per la riproduzione"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Consente all\'applicazione di utilizzare qualsiasi decoder multimediale installato per la decodifica ai fini della riproduzione."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"gestione di credenziali attendibili"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Consente all\'app di installare e disinstallare certificati CA come credenziali attendibili."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"lettura/scrittura risorse di proprietà di diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Consente all\'applicazione di leggere le risorse del gruppo diag e scrivere in esse, ad esempio i file in /dev. Ciò potrebbe influire su stabilità e sicurezza del sistema. Dovrebbe essere utilizzata SOLTANTO per diagnostiche specifiche dell\'hardware effettuate dal produttore o dall\'operatore."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"attivazione/disattivazione componenti applicazioni"</string>
@@ -432,7 +449,7 @@
     <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Consente all\'applicazione di modificare il registro chiamate del telefono, inclusi i dati sulle chiamate in arrivo e in uscita. Le applicazioni dannose potrebbero farne uso per cancellare o modificare il registro chiamate."</string>
     <string name="permlab_readProfile" msgid="4701889852612716678">"lettura scheda cont. personale"</string>
     <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Consente all\'applicazione di leggere informazioni del profilo personale memorizzate sul dispositivo, come il tuo nome e le tue informazioni di contatto. Ciò significa che l\'applicazione può identificarti e inviare le informazioni del tuo profilo ad altri."</string>
-    <string name="permlab_writeProfile" msgid="907793628777397643">"modifica scheda cont. personale"</string>
+    <string name="permlab_writeProfile" msgid="907793628777397643">"modifica scheda contatti"</string>
     <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Consente all\'applicazione di modificare o aggiungere informazioni ai dati del profilo personale memorizzati sul dispositivo, come il tuo nome e le tue informazioni di contatto. Significa che l\'applicazione può identificarti e inviare le informazioni del tuo profilo ad altri."</string>
     <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"lettura del tuo stream sociale"</string>
     <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Consente all\'applicazione di accedere agli aggiornamenti dei social network tra te e i tuoi amici e di sincronizzarli. Fai attenzione quando condividi informazioni: questa autorizzazione consente all\'applicazione di leggere le comunicazioni tra te e i tuoi amici sui social network, indipendentemente dal livello di riservatezza. Nota. È possibile che questa autorizzazione non sia applicabile su tutti i social network."</string>
@@ -462,6 +479,14 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Consente all\'applicazione di configurare schermi Wi-Fi e di collegarsi a essi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"controllo di schermi Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Consente all\'applicazione di controllare le funzioni di basso livello di schermi Wi-Fi."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"acquisizione dell\'uscita audio"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Consente all\'app di acquisire e reindirizzare l\'uscita audio."</string>
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Rilevamento hotword"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Consente all\'app di acquisire l\'audio per il rilevamento Hotword. L\'acquisizione può avvenire in background ma non impedisce l\'acquisizione di altro audio (ad esempio con la videocamera)."</string>
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"acquisizione dell\'uscita video"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Consente all\'app di acquisire e reindirizzare l\'uscita video."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"acquisizione dell\'uscita video sicura"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Consente all\'app di acquisire e reindirizzare l\'uscita video sicura."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"modifica impostazioni audio"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Consente all\'applicazione di modificare le impostazioni audio globali, come il volume e quale altoparlante viene utilizzato per l\'uscita."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"registrazione audio"</string>
@@ -525,6 +550,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"disattivazione stand-by del telefono"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Consente all\'applicazione di impedire lo stand-by del tablet."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Consente all\'applicazione di impedire lo stand-by del telefono."</string>
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"trasmissione a infrarossi"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Consente all\'app di utilizzare il trasmettitore a infrarossi del tablet."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Consente all\'app di utilizzare il trasmettitore a infrarossi del telefono."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"accensione o spegnimento del tablet"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"accensione o spegnimento del telefono"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Consente all\'applicazione di accendere o spegnere il tablet."</string>
@@ -607,12 +635,14 @@
     <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"test dell\'accesso all\'archivio protetto"</string>
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"Consente all\'applicazione di testare un\'autorizzazione relativa all\'archivio USB che sarà disponibile su dispositivi futuri."</string>
     <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"Consente all\'applicazione di testare un\'autorizzazione relativa alla scheda SD che sarà disponibile su dispositivi futuri."</string>
-    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"mod./elimin. contenuti USB"</string>
+    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"Modifica/eliminazione contenuti USB"</string>
     <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"modifica o eliminazione dei contenuti della scheda SD"</string>
     <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Consente all\'applicazione di scrivere nell\'archivio USB."</string>
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Consente all\'applicazione di scrivere sulla scheda SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modifica/eliminaz. contenuti archivio media int."</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Consente all\'applicazione di modificare i contenuti dell\'archivio media interno."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"gestione della memorizzazione dei documenti"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Consente all\'app di gestire la memorizzazione dei documenti."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"accesso memoria esterna utenti"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Consente all\'applicazione di accedere alla memoria esterna di tutti gli utenti."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"accesso al filesystem nella cache"</string>
@@ -625,10 +655,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Consente all\'applicazione di gestire le norme di rete e definire le regole specifiche delle applicazioni."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"modifica calcolo dell\'utilizzo della rete"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Consente all\'applicazione di modificare il calcolo dell\'utilizzo della rete tra le applicazioni. Da non usare per normali applicazioni."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"modifica di contrassegni socket"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Consente all\'app di modificare i contrassegni socket per il routing"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"accesso a notifiche"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Consente all\'app di recuperare, esaminare e cancellare notifiche, comprese quelle pubblicate da altre app."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"vincolo a un servizio listener di notifica"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Consente al titolare di vincolarsi all\'interfaccia di primo livello di un servizio listener di notifica. Non dovrebbe mai essere necessaria per le normali applicazioni."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"richiamo dell\'app di configurazione operatore-provider"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Consente al titolare di richiamare l\'app di configurazione dell\'operatore-provider. Non dovrebbe essere mai necessaria per le normali applicazioni."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"ascolto delle osservazioni sulle condizioni di rete"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Consente a un\'applicazione di ascoltare le osservazioni sulle condizioni di rete. Da non utilizzare mai con app normali."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Imposta regole password"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlla la lunghezza e i caratteri ammessi nelle password di sblocco dello schermo."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitora tentativi di sblocco dello schermo"</string>
@@ -738,8 +774,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <string name="imProtocolGoogleTalk" msgid="493902321140277304">"Hangout"</string>
     <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string>
     <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string>
     <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string>
@@ -796,7 +831,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Inserisci una scheda SIM."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Scheda SIM mancante o non leggibile. Inserisci una scheda SIM."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Scheda SIM inutilizzabile."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"La scheda SIM è stata disattivata definitivamente."\n" Contatta il fornitore del tuo servizio wireless per ricevere un\'altra scheda SIM."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"La scheda SIM è stata disattivata definitivamente.\n Contatta il fornitore del tuo servizio wireless per ricevere un\'altra scheda SIM."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Pulsante traccia precedente"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Pulsante traccia successiva"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Pulsante Pausa"</string>
@@ -808,11 +843,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Consulta la Guida dell\'utente o contatta il servizio clienti."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"La SIM è bloccata."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Sblocco SIM..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. "\n\n"Riprova tra <xliff:g id="NUMBER_1">%d</xliff:g> secondi."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Hai digitato la tua password <xliff:g id="NUMBER_0">%d</xliff:g> volte in modo errato. "\n\n"Riprova tra <xliff:g id="NUMBER_1">%d</xliff:g> secondi."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Hai digitato il tuo PIN <xliff:g id="NUMBER_0">%d</xliff:g> volte in modo errato. "\n\n"Riprova tra <xliff:g id="NUMBER_1">%d</xliff:g> secondi."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il tablet con i tuoi dati di accesso Google."\n\n" Riprova tra <xliff:g id="NUMBER_2">%d</xliff:g> secondi."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il telefono con i tuoi dati di accesso Google."\n\n" Riprova tra <xliff:g id="NUMBER_2">%d</xliff:g> secondi."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. \n\nRiprova tra <xliff:g id="NUMBER_1">%d</xliff:g> secondi."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Hai digitato la tua password <xliff:g id="NUMBER_0">%d</xliff:g> volte in modo errato. \n\nRiprova tra <xliff:g id="NUMBER_1">%d</xliff:g> secondi."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Hai digitato il tuo PIN <xliff:g id="NUMBER_0">%d</xliff:g> volte in modo errato. \n\nRiprova tra <xliff:g id="NUMBER_1">%d</xliff:g> secondi."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il tablet con i tuoi dati di accesso Google.\n\n Riprova tra <xliff:g id="NUMBER_2">%d</xliff:g> secondi."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il telefono con i tuoi dati di accesso Google.\n\n Riprova tra <xliff:g id="NUMBER_2">%d</xliff:g> secondi."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Hai erroneamente tentato di sbloccare il tablet <xliff:g id="NUMBER_0">%d</xliff:g> volte. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi non riusciti, il tablet verrà sottoposto a un ripristino dati di fabbrica e tutti i dati utente andranno persi."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Hai erroneamente tentato di sbloccare il telefono <xliff:g id="NUMBER_0">%d</xliff:g> volte. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi non riusciti, il telefono verrà sottoposto a un ripristino dati di fabbrica e tutti i dati utente andranno persi."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Hai erroneamente tentato di sbloccare il tablet <xliff:g id="NUMBER">%d</xliff:g> volte. Il tablet ora verrà sottoposto a un ripristino dati di fabbrica."</string>
@@ -826,7 +861,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Password"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Accedi"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Password o nome utente non valido."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Hai dimenticato il nome utente o la password?"\n"Visita "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Hai dimenticato il nome utente o la password?\nVisita "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Verifica..."</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Sblocca"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Audio attivato"</string>
@@ -874,7 +909,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Conferma navigazione"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Abbandona questa pagina"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Rimani su questa pagina"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Vuoi abbandonare la pagina?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nVuoi abbandonare la pagina?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Conferma"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Suggerimento. Tocca due volte per aumentare e diminuire lo zoom."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Compilazione autom."</string>
@@ -1080,14 +1115,14 @@
     <string name="aerr_application" msgid="932628488013092776">"L\'applicazione <xliff:g id="APPLICATION">%1$s</xliff:g> si è bloccata in modo anomalo."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Il processo <xliff:g id="PROCESS">%1$s</xliff:g> si è interrotto."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> non risponde."\n\n"Vuoi chiuderla?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"L\'attività <xliff:g id="ACTIVITY">%1$s</xliff:g> non risponde."\n\n"Vuoi chiuderla?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> non risponde.\n\nVuoi chiuderla?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"L\'attività <xliff:g id="ACTIVITY">%1$s</xliff:g> non risponde.\n\nVuoi chiuderla?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> non risponde. Vuoi chiuderla?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Il processo <xliff:g id="PROCESS">%1$s</xliff:g> non risponde."\n\n"Vuoi chiuderlo?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Il processo <xliff:g id="PROCESS">%1$s</xliff:g> non risponde.\n\nVuoi chiuderlo?"</string>
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"Segnala"</string>
     <string name="wait" msgid="7147118217226317732">"Attendi"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"La pagina non risponde più."\n\n"Vuoi chiuderla?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"La pagina non risponde più.\n\nVuoi chiuderla?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Applicazione reindirizzata"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> è ora in esecuzione."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> già avviata."</string>
@@ -1256,6 +1291,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Consente all\'applicazione di richiamare il servizio container predefinito per la copia di contenuti. Da non usare per normali applicazioni."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Indirizzamento uscita media"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Consente a un\'applicazione di indirizzare l\'uscita di media verso altri dispositivi esterni."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Accesso all\'archivio sicuro keyguard"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Consente a un\'applicazione di accedere all\'archivio sicuro keguard."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Controllo della visualizzazione e dell\'occultamento di keyguard"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Consente a un\'applicazione di controllare keguard."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Tocca due volte per il comando dello zoom"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Aggiunta del widget non riuscita."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Vai"</string>
@@ -1265,15 +1304,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Fine"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Prec."</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Esegui"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Componi numero"\n"utilizzando <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Crea contatto"\n"utilizzando <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Componi numero\nutilizzando <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Crea contatto\nutilizzando <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Le seguenti applicazioni richiedono l\'autorizzazione per accedere al tuo account, adesso e in futuro."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Accettare la richiesta?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Richiesta di accesso"</string>
     <string name="allow" msgid="7225948811296386551">"Consenti"</string>
     <string name="deny" msgid="2081879885755434506">"Nega"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Autorizzazione richiesta"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Autorizzazione richiesta"\n"per l\'account <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Autorizzazione richiesta\nper l\'account <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Metodo inserimento"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Sinc"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Accessibilità"</string>
@@ -1420,7 +1459,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Mostra tutto"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Scegli attività"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Condividi con"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Dispositivo bloccato."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Invio..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Avviare l\'applicazione Browser?"</string>
@@ -1441,10 +1479,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Connessione..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Disponibile"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"Non disponibili"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"In uso"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Schermo incorporato"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"Schermo HDMI"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlay n. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", opzione sicura"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Il display wireless è connesso"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Questa schermata è mostrata su un altro dispositivo"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Disconnetti"</string>
@@ -1453,7 +1493,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Sequenza sbagliata"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Password sbagliata"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN errato"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Riprova fra <xliff:g id="NUMBER">%d</xliff:g> secondi."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Riprova fra <xliff:g id="NUMBER">%1$d</xliff:g> secondi."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Inserisci la sequenza"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Inserisci il PIN della SIM"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Inserisci PIN"</string>
@@ -1473,27 +1513,85 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Password"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Accedi"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nome utente o password non validi."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Hai dimenticato il nome utente o la password?"\n"Visita "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Hai dimenticato il nome utente o la password?\nVisita "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Controllo account…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Hai digitato il tuo PIN <xliff:g id="NUMBER_0">%d</xliff:g> volte in modo errato. "\n\n"Riprova tra <xliff:g id="NUMBER_1">%d</xliff:g> secondi."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Hai digitato la tua password <xliff:g id="NUMBER_0">%d</xliff:g> volte in modo errato. "\n\n"Riprova tra <xliff:g id="NUMBER_1">%d</xliff:g> secondi."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. "\n\n"Riprova tra <xliff:g id="NUMBER_1">%d</xliff:g> secondi."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Hai digitato il tuo PIN <xliff:g id="NUMBER_0">%d</xliff:g> volte in modo errato. \n\nRiprova tra <xliff:g id="NUMBER_1">%d</xliff:g> secondi."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Hai digitato la tua password <xliff:g id="NUMBER_0">%d</xliff:g> volte in modo errato. \n\nRiprova tra <xliff:g id="NUMBER_1">%d</xliff:g> secondi."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. \n\nRiprova tra <xliff:g id="NUMBER_1">%d</xliff:g> secondi."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di sblocco del tablet. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, il tablet verrà sottoposto a un ripristino dei dati di fabbrica e tutti i dati utente andranno persi."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di sblocco del telefono. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, il telefono verrà sottoposto a un ripristino dei dati di fabbrica e tutti i dati utente andranno persi."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"<xliff:g id="NUMBER">%d</xliff:g> tentativi errati di sblocco del tablet. Il tablet verrà sottoposto a un ripristino dei dati di fabbrica."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"<xliff:g id="NUMBER">%d</xliff:g> tentativi errati di sblocco del telefono. Il telefono verrà sottoposto a un ripristino dei dati di fabbrica."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il tablet con un account email."\n\n" Riprova tra <xliff:g id="NUMBER_2">%d</xliff:g> secondi."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il telefono con un account email."\n\n" Riprova tra <xliff:g id="NUMBER_2">%d</xliff:g> secondi."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il tablet con un account email.\n\n Riprova tra <xliff:g id="NUMBER_2">%d</xliff:g> secondi."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il telefono con un account email.\n\n Riprova tra <xliff:g id="NUMBER_2">%d</xliff:g> secondi."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Rimuovi"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Aumentare il volume oltre il livello di sicurezza?"\n"Ascoltare musica ad alto volume per lunghi periodi potrebbe danneggiare l\'udito."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Aumentare il volume oltre il livello di sicurezza?\nAscoltare musica ad alto volume per lunghi periodi potrebbe danneggiare l\'udito."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Continua a tenere premuto con due dita per attivare l\'accessibilità."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Accessibilità attivata."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accessibilità annullata."</string>
     <string name="user_switched" msgid="3768006783166984410">"Utente corrente <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Proprietario"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Errore"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Questa applicazione non supporta account relativi a profili con limitazioni"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Questa app non supporta account relativi a profili con limitazioni"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Nessuna applicazione trovata in grado di gestire questa azione"</string>
     <string name="revoke" msgid="5404479185228271586">"Revoca"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Lettera"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legale"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Legale \"junior\""</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Annullato"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Errore nella scrittura dei contenuti"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"sconosciuto"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Inserisci PIN amministratore"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Inserisci PIN"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Non corretto"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN corrente"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Nuovo PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Conferma il nuovo PIN"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Crea un PIN per la modifica delle limitazioni"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"I PIN non corrispondono. Riprova."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"Il PIN è troppo corto. Deve avere almeno quattro cifre."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Riprova fra 1 s."</item>
+    <item quantity="other" msgid="4730868920742952817">"Riprova tra <xliff:g id="COUNT">%d</xliff:g> s."</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Riprova più tardi"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Scorri bordo schermo per visual. barra"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Fai scorrere il dito dal bordo dello schermo per visualizzare la barra di sistema"</string>
 </resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 7afb72c..f01dd94 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -131,6 +131,11 @@
     <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="default" msgid="3475999286680000541">"שטח האחסון של הטלפון מלא. מחק חלק מהקבצים כדי לפנות שטח."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"ייתכן שהרשת מנוטרת"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"אני"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"אפשרויות טאבלט"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"אפשרויות טלפון"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"מאפשר ליישום להעביר משימות לחזית ולרקע. היישום עשוי לעשות זאת ללא התערבותך."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"עצירת יישומים פעילים"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"הרשאה זו מאפשרת ליישום להסיר משימות ולסגור את היישומים שבהם הן פועלות. יישומים זדוניים עלולים לשבש את פעולתם של יישומים אחרים."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"ניהול של ערימות פעילות"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"ההרשאה הזו מאפשרת לאפליקציה להוסיף, להסיר ולשנות את ערימות הפעילות שבהן רצות אפליקציות אחרות. אפליקציות זדוניות עלולת להפריע להתנהגות של אפליקציות אחרות."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"התחלת פעילות מכל סוג שהוא"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"מאפשר ליישום להתחיל בפעילות מכל סוג שהוא, ללא התחשבות בהגנת הרשאות או במצב מיוצא."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"הגדרת תאימות מסך"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"מאפשר למשתמש לבצע איגוד לממשק ברמה עליונה של שיטת קלט. הרשאה זו לעולם אינה נחוצה ליישומים רגילים."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"הכפפה לשירות נגישות"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"מתיר לבעלים להכפיף לממשק ברמה העליונה של שירות זמינות. הרשאה זו אף פעם אינה אמורה להיות נחוצה ליישומים רגילים."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"איגוד לשירות הדפסה"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"ההרשאה הזו מאפשרת לבעלים לבצע איגוד לממשק הרמה העליונה של שירות הדפסה. לעולם לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"איגוד לשירות הדפסה"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"מאפשרת לבעלים לבצע איגוד לממשק ברמה העליונה של שירות הדפסה. לעולם לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"איגוד לשירות NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"מאפשרת לבעלים לאגד את האפליקציות המחקות כרטיסיות NFC. לעולם לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"הכפפה לשירות טקסט"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"מאפשר למשתמש ליצור איגוד לממשק הרמה העליונה של שירות טקסט (למשל, SpellCheckerService). הרשאה זו לעולם אינה נחוצה ליישומים רגילים."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"אגד לשירות VPN"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"מאפשר למשתמש לבצע איגוד לממשק הרמה העליונה של שירות Widget. הרשאה זו לעולם אינה נחוצה ליישומים רגילים."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"קיים אינטראקציה עם מנהל המכשיר"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"מאפשר למשתמש לשלוח כוונות למנהל התקנים. הרשאה זו לעולם אינה נחוצה ליישומים רגילים."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"הוספה או הסרה של מנהלי מכשיר"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"מאפשרת לבעלים להוסיף או להסיר מנהלי מכשיר פעילים. לעולם לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"שנה את כיוון המסך"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"מאפשר ליישום לשנות את הסיבוב של המסך בכל עת. הרשאה זו לעולם אינה נחוצה ליישומים רגילים."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"שינוי מהירות המצביע"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"מאפשר ליישום לקרוא מקובצי היומן השונים של המערכת. כך מתאפשר ליישום לגלות מידע כללי על הפעולות שלך בטלפון, מידע שעשוי לכלול מידע אישי או פרטי."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"שימוש בכל מפענח מדיה שהוא להפעלה"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"הרשאה זו מאפשרת ליישום להשתמש בכל מפענח מדיה מותקן כדי לבצע פענוח להשמעה."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"ניהול פרטי כניסה מהימנים"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"מאפשרת לאפליקציה להתקין ולהסיר אישורי CA כפרטי כניסה מהימנים."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"קרא/כתוב במשאבים בבעלות diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"מאפשר ליישום לקרוא ולכתוב בכל משאב שבבעלות קבוצת ה-diag; לדוגמה, קבצים ב-‎/dev. פעולה זו עשויה להשפיע על היציבות והאבטחה של המערכת. אפשרות זו צריכה לשמש רק את היצרן או המפעיל, לצורך אבחונים ספציפיים לחומרה."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"הפעלה או השבתה של רכיבי יישומים"</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"מאפשר לאפליקציה להגדיר ולהתחבר לתצוגות Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"שלוט בתצוגות Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"מאפשר לאפליקציה לשלוט בתכונות ברמה נמוכה של תצוגות Wi-Fi."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"קליטת פלט אודיו"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"מאפשרת לאפליקציה לקלוט ולהפנות מחדש פלט אודיו."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"קליטת פלט וידאו"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"מאפשרת לאפליקציה לקלוט ולהפנות מחדש פלט וידאו."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"קליטת פלט וידאו מאובטח"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"מאפשרת לאפליקציה לקלוט ולהפנות מחדש פלט וידאו מאובטח."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"שנה את הגדרות האודיו שלך"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"מאפשר ליישום לשנות הגדרות אודיו גלובליות כמו עוצמת קול ובחירת הרמקול המשמש לפלט."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"הקלט אודיו"</string>
@@ -525,6 +552,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"מניעת מעבר הטלפון למצב שינה"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"מאפשר ליישום למנוע מהטבלט לעבור למצב שינה."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"מאפשר ליישום למנוע מהטלפון לעבור למצב שינה."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"הפעלה או כיבוי של טאבלט"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"הפעל או כבה את הטלפון"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"מאפשר ליישום להפעיל או לכבות את הטבלט."</string>
@@ -613,6 +646,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"מאפשר ליישום לכתוב לכרטיס ה-SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"שנה/מחק תוכן של אחסון מדיה פנימי"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"מאפשר ליישום לשנות את התוכן של אמצעי האחסון הפנימי למדיה."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"ניהול של אחסון מסמכים"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"מאפשר ליישום לנהל אחסון מסמכים."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"גישה לאחסון חיצוני, כל המשתמשים"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"מאפשר ליישום לגשת לאחסון חיצוני עבור כל המשתמשים."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"גישה למערכת הקבצים בקובץ השמור"</string>
@@ -624,11 +659,17 @@
     <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"נהל מדיניות רשת"</string>
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"מאפשר ליישום לנהל מדיניות הרשת להגדיר כללים ספציפיים-ליישום."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"שנה ניהול חשבונות של שימוש ברשת"</string>
-    <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"הרשאה זו מאפשרת ליישום לשנות את אופן החישוב של נתוני שימוש ברשת מול כל יישום. לא מיועד לשימוש ביישומים רגילים."</string>
+    <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"הרשאה זו מאפשרת לאפליקציה לשנות את אופן החישוב של נתוני שימוש ברשת מול כל אפליקציה. לא מיועד לשימוש באפליקציות רגילות."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"שינוי של סימני Socket"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"ההרשאה הזו מאפשרת לאפליקציה לשנות סימני Socket עבור ניתוב"</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_invokeCarrierSetup" msgid="3699600833975117478">"הפעלה של אפליקציית תצורה שסופקה על ידי ספק"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"ההרשאה הזו מאפשרת לבעלים להפעיל את אפליקציית התצורה שסופקה על ידי ספק. לעולם לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"קליטת מעקב אחר תנאי רשת"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"מאפשרת לאפליקציה לקלוט מעקב אחר תנאי רשת. לעולם לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"הגדר כללי סיסמה"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"שלוט באורך ובתווים המותרים בסיסמאות לביטול נעילת מסך."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"עקוב אחר ניסיונות לביטול נעילת מסך"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -785,7 +825,7 @@
     <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="faceunlock_multiple_failures" msgid="754137583022792429">"חרגת ממספר הניסיונות המרבי של זיהוי פרצוף"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"חרגת ממספר הניסיונות המרבי של זיהוי פנים"</string>
     <string name="lockscreen_plugged_in" msgid="8057762828355572315">"טוען (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
     <string name="lockscreen_charged" msgid="321635745684060624">"טעון"</string>
     <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
@@ -796,7 +836,7 @@
     <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">"כרטיס ה-SIM שלך הושבת לצמיתות.\nפנה לספק השירות האלחוטי שלך לקבלת כרטיס SIM אחר."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"לחצן הרצועה הקודמת"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"לחצן הרצועה הבאה"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"לחצן ההשהיה"</string>
@@ -808,11 +848,11 @@
     <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">%d</xliff:g> פעמים. "\n\n"נסה שוב בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"הקלדת סיסמה שגויה <xliff:g id="NUMBER_0">%d</xliff:g> פעמים."\n\n"נסה שוב בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"הקלדת קוד PIN שגוי <xliff:g id="NUMBER_0">%d</xliff:g> פעמים."\n\n"נסה שוב בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"שרטטת באופן שגוי את קו ביטול הנעילה <xliff:g id="NUMBER_0">%d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטבלט באמצעות פרטי הכניסה שלך ל-Google."\n\n"נסה שוב בעוד <xliff:g id="NUMBER_2">%d</xliff:g> שניות."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"שרטטת את קו ביטול הנעילה באופן שגוי <xliff:g id="NUMBER_0">%d</xliff:g> פעמים. בעוד <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטלפון באמצעות פרטי הכניסה שלך ל-Google‏."\n\n" נסה שוב בעוד <xliff:g id="NUMBER_2">%d</xliff:g> שניות."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"שרטטת את קו ביטול הנעילה באופן שגוי <xliff:g id="NUMBER_0">%d</xliff:g> פעמים. \n\nנסה שוב בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"הקלדת סיסמה שגויה <xliff:g id="NUMBER_0">%d</xliff:g> פעמים.\n\nנסה שוב בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"הקלדת קוד PIN שגוי <xliff:g id="NUMBER_0">%d</xliff:g> פעמים.\n\nנסה שוב בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"שרטטת באופן שגוי את קו ביטול הנעילה <xliff:g id="NUMBER_0">%d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטבלט באמצעות פרטי הכניסה שלך ל-Google.\n\nנסה שוב בעוד <xliff:g id="NUMBER_2">%d</xliff:g> שניות."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"שרטטת את קו ביטול הנעילה באופן שגוי <xliff:g id="NUMBER_0">%d</xliff:g> פעמים. בעוד <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטלפון באמצעות פרטי הכניסה שלך ל-Google‏.\n\n נסה שוב בעוד <xliff:g id="NUMBER_2">%d</xliff:g> שניות."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"ביצעת <xliff:g id="NUMBER_0">%d</xliff:g> ניסיונות שגויים לביטול נעילת הטבלט. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, הטבלט יעבור איפוס לברירת המחדל של היצרן וכל נתוני המשתמש יאבדו."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"ביצעת <xliff:g id="NUMBER_0">%d</xliff:g> ניסיונות שגויים לביטול נעילת הטלפון. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, הטלפון יעבור איפוס לברירת המחדל של היצרן וכל נתוני המשתמש יאבדו."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"ביצעת <xliff:g id="NUMBER">%d</xliff:g> ניסיונות שגויים לביטול נעילת הטבלט. הטבלט יעבור כעת איפוס לברירת המחדל של היצרן."</string>
@@ -826,7 +866,7 @@
     <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_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>
@@ -851,7 +891,7 @@
     <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"הרחב את אזור ביטול הנעילה."</string>
     <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"ביטול נעילה באמצעות הסטה."</string>
     <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"ביטול נעילה באמצעות ציור קו."</string>
-    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"ביטול נעילה באמצעות זיהוי פרצוף."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"ביטול נעילה באמצעות זיהוי פנים."</string>
     <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"ביטול נעילה באמצעות מספר PIN."</string>
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"ביטול נעילה באמצעות סיסמה."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"אזור ציור קו."</string>
@@ -874,7 +914,7 @@
     <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="autofill_this_form" msgid="4616758841157816676">"מילוי אוטומטי"</string>
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"לצערנו, פעולת <xliff:g id="APPLICATION">%1$s</xliff:g> הופסקה."</string>
     <string name="aerr_process" msgid="4507058997035697579">"לצערנו, התהליך <xliff:g id="PROCESS">%1$s</xliff:g> הופסק."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> אינו מגיב."\n\n"תרצה לסגור אותו?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"הפעילות <xliff:g id="ACTIVITY">%1$s</xliff:g> אינה מגיבה."\n\n"תרצה לסגור אותה?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> אינו מגיב.\n\nתרצה לסגור אותו?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"הפעילות <xliff:g id="ACTIVITY">%1$s</xliff:g> אינה מגיבה.\n\nתרצה לסגור אותה?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> אינו מגיב. תרצה לסגור אותו?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"תהליך <xliff:g id="PROCESS">%1$s</xliff:g> אינו מגיב."\n\n"תרצה לסגור אותו?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"תהליך <xliff:g id="PROCESS">%1$s</xliff:g> אינו מגיב.\n\nתרצה לסגור אותו?"</string>
     <string name="force_close" msgid="8346072094521265605">"אישור"</string>
     <string name="report" msgid="4060218260984795706">"שלח דוח"</string>
     <string name="wait" msgid="7147118217226317732">"המתן"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"הדף אינו מגיב."\n\n"האם אתה רוצה לסגור אותו?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"הדף אינו מגיב.\n\nהאם אתה רוצה לסגור אותו?"</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>
@@ -1096,7 +1136,7 @@
     <string name="screen_compat_mode_hint" msgid="1064524084543304459">"אפשר תכונה זו מחדש ב\'הגדרות מערכת\' &lt;‏ Google Apps‏ &lt; \'הורדות\'."</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>
-    <string name="android_upgrading_title" msgid="1584192285441405746">"Android מבצע שדרוג..."</string>
+    <string name="android_upgrading_title" msgid="1584192285441405746">"‏Android מבצע שדרוג…"</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_upgrading_starting_apps" msgid="451464516346926713">"מפעיל יישומים."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"מסיים אתחול."</string>
@@ -1256,6 +1296,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"מאפשר ליישום להפעיל שירות גורם מכיל המוגדר כברירת מחדל להעתקת תוכן. לא מיועד לשימוש על ידי יישומים רגילים."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"ניתוב פלט מדיה"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"מאפשר ליישום לנתב פלט מדיה למכשירים חיצוניים אחרים."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"גישה לאחסון המוגן באמצעות מפתח"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"מאפשר ליישום לגשת לאחסון המוגן באמצעות מפתח."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"שלוט בהצגה והסתרה של מגן המקלדת"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"מאפשר ליישום לשלוט במגן המקלדת."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"גע פעמיים לבקרת מרחק מתצוגה"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"לא ניתן להוסיף widget."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"התחל"</string>
@@ -1265,15 +1309,15 @@
     <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">"חייג למספר"\n"באמצעות <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"צור איש קשר"\n"באמצעות <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"חייג למספר\nבאמצעות <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"צור איש קשר\nבאמצעות <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"היישומים הבאים מבקשים אישור לגשת לחשבונך, כעת ובעתיד."</string>
     <string name="grant_credentials_permission_message_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">"נדרשת הרשאה"\n"לחשבון <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"נדרשת הרשאה\nלחשבון <xliff:g id="ACCOUNT">%s</xliff:g>."</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>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"הצג הכל"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"בחר פעילות"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"שתף עם"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"המכשיר נעול."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"שולח…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"להפעיל את הדפדפן?"</string>
@@ -1441,10 +1484,12 @@
     <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>
+    <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_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="wifi_display_notification_title" msgid="2223050649240326557">"מסך אלחוטי מחובר"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"מסך זה מוצג במכשיר אחר"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"נתק"</string>
@@ -1453,7 +1498,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">%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>
@@ -1473,27 +1518,85 @@
     <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_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">%d</xliff:g> פעמים. "\n\n"נסה שוב בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"הקלדת סיסמה שגויה <xliff:g id="NUMBER_0">%d</xliff:g> פעמים."\n\n"נסה שוב בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"שרטטת את קו ביטול הנעילה באופן שגוי <xliff:g id="NUMBER_0">%d</xliff:g> פעמים. "\n\n"נסה שוב בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"הקלדת מספר PIN שגוי <xliff:g id="NUMBER_0">%d</xliff:g> פעמים. \n\nנסה שוב בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"הקלדת סיסמה שגויה <xliff:g id="NUMBER_0">%d</xliff:g> פעמים.\n\nנסה שוב בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"שרטטת את קו ביטול הנעילה באופן שגוי <xliff:g id="NUMBER_0">%d</xliff:g> פעמים. \n\nנסה שוב בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"ביצעת <xliff:g id="NUMBER_0">%d</xliff:g> ניסיונות שגויים לביטול נעילת הטלפון. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, הטאבלט יעבור איפוס לברירת המחדל של היצרן וכל נתוני המשתמש יאבדו."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"ביצעת <xliff:g id="NUMBER_0">%d</xliff:g> ניסיונות שגויים לביטול נעילת הטלפון. לאחר <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטאבלט באמצעות חשבון דוא\"ל‏."\n\n"נסה שוב בעוד <xliff:g id="NUMBER_2">%d</xliff:g> שניות."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"שרטטת את קו ביטול הנעילה באופן שגוי <xliff:g id="NUMBER_0">%d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטלפון באמצעות חשבון דוא\"ל‏."\n\n"נסה שוב בעוד <xliff:g id="NUMBER_2">%d</xliff:g> שניות."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"שרטטת את קו ביטול הנעילה באופן שגוי <xliff:g id="NUMBER_0">%d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטאבלט באמצעות חשבון דוא\"ל‏.\n\nנסה שוב בעוד <xliff:g id="NUMBER_2">%d</xliff:g> שניות."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"שרטטת את קו ביטול הנעילה באופן שגוי <xliff:g id="NUMBER_0">%d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטלפון באמצעות חשבון דוא\"ל‏.\n\nנסה שוב בעוד <xliff:g id="NUMBER_2">%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="7324161939475478066">"האם להעלות את עוצמת הקול מעל לרמה המומלצת?"\n"האזנה בעוצמת קול גבוהה למשך זמן ארוך עלולה לפגוע בשמיעה."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"האם להעלות את עוצמת הקול מעל לרמה המומלצת?\nהאזנה בעוצמת קול גבוהה למשך זמן ארוך עלולה לפגוע בשמיעה."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"המשך לגעת בשתי אצבעות כדי להפעיל נגישות."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"נגישות הופעלה."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"נגישות בוטלה."</string>
     <string name="user_switched" msgid="3768006783166984410">"המשתמש הנוכחי <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="app_no_restricted_accounts" msgid="4011285085817350390">"היישום הזה לא תומך בחשבונות עבור פרופילים מוגבלים"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"האפליקציה הזו לא תומכת בחשבונות עבור פרופילים מוגבלים"</string>
     <string name="app_not_found" msgid="3429141853498927379">"לא נמצא יישום שתומך בפעולה זו"</string>
     <string name="revoke" msgid="5404479185228271586">"בטל"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"בוטלה"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"שגיאה בכתיבת תוכן"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"לא ידוע"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"הזן את מספר ה-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>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"מספר PIN חדש"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"אשר את מספר ה-PIN החדש"</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_too_short" msgid="8173982756265777792">"מספר ה-PIN קצר מדי. חייב להיות באורך 4 ספרות לפחות."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"נסה שוב בעוד שנייה"</item>
+    <item quantity="other" msgid="4730868920742952817">"נסה שוב בעוד <xliff:g id="COUNT">%d</xliff:g> שניות"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"נסה שוב מאוחר יותר"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"החלק מקצה המסך כדי להציג את הסרגל"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"החלק מקצה המסך כדי להציג את סרגל המערכת"</string>
 </resources>
diff --git a/core/res/res/values-ja/bools.xml b/core/res/res/values-ja/bools.xml
new file mode 100644
index 0000000..59cf744
--- /dev/null
+++ b/core/res/res/values-ja/bools.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <bool name="flip_controller_fallback_keys">true</bool>
+</resources>
+
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 340774c..3ad4d5a 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -131,6 +131,11 @@
     <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="default" msgid="3475999286680000541">"端末のストレージに空き領域がありません。ファイルを削除して空き領域を確保してください。"</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"ネットワークが監視される場合があります"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"自分"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"タブレットオプション"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"携帯電話オプション"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"タスクをフォアグラウンドやバックグラウンドに移動することをアプリに許可します。これにより、アプリがユーザーからの入力なしでこの処理を実行する可能性があります。"</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"実行中のアプリの停止"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"タスクの削除とアプリの終了をアプリに許可します。この許可を悪意のあるアプリケーションに利用されると、他のアプリの動作が妨害される恐れがあります。"</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"アクティビティスタックの管理"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"他のアプリを実行するアクティビティスタックを追加、削除、変更することをアプリに許可します。この許可を悪意のあるアプリに利用されると、他のアプリの動作が妨害される恐れがあります。"</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"すべてのアクティビティの開始"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"権限による保護やエクスポートされた状態を問わず、すべてのアクティビティを開始することをアプリに許可します。"</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"画面互換性の設定"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"入力方法のトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"ユーザー補助サービスにバインド"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"ユーザー補助サービスのトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"印刷サービスへのバインド"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"印刷サービスのトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"印刷スプーラサービスへのバインド"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"印刷スプーラサービスのトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"NFCサービスへのバインド"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"NFCカードをエミュレートしているアプリにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"テキストサービスにバインド"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"テキストサービス(SpellCheckerServiceなど)のトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"VPNサービスにバインド"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"ウィジェットサービスのトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"デバイス管理者との通信"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"デバイス管理者へのintentの送信を所有者に許可します。通常のアプリでは不要です。"</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"端末の管理者の追加または削除"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"有効な端末の管理者を追加または削除することを所有者に許可します。通常のアプリでは不要です。"</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"画面の向きの変更"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"いつでも画面の向きを変更することをアプリに許可します。通常のアプリでは不要です。"</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"ポインタの速度の変更"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"システムの各種ログファイルの読み取りをアプリに許可します。許可すると、アプリでは携帯端末の使用に関する全般的な情報を読み取れるようになります。この情報には個人情報や機密情報が含まれる場合があります。"</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"再生用にメディア デコーダーを使用"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"インストール済みのメディアデコーダーを使用して再生用にデコードすることをアプリに許可します。"</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"信頼できる認証情報の管理"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"CA証明書を信頼できる認証情報としてインストールしたりアンインストールしたりすることをアプリに許可します。"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"diagが所有するリソースの読み書き"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"diagグループが所有するリソース(/dev内のファイルなど)の読み書きをアプリに許可します。許可すると、システムの安定性とセキュリティに影響が生じる可能性があります。メーカー/通信事業者によるハードウェア固有の診断以外には使用しないでください。"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"アプリのコンポーネントの有効/無効化"</string>
@@ -441,7 +458,7 @@
     <string name="permlab_readCalendar" msgid="5972727560257612398">"カレンダーの予定と機密情報を読み取る"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"タブレットに保存されているカレンダーの予定(友だちや同僚の予定も含めすべて)を読み取ることをアプリに許可します。これにより、アプリがカレンダーのデータを機密性に関係なく共有または保存できるようになる可能性があります。"</string>
     <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"携帯端末に保存されているカレンダーの予定(友だちや同僚の予定も含めすべて)を読み取ることをアプリに許可します。これにより、アプリがカレンダーのデータを機密性に関係なく共有または保存できるようになる可能性があります。"</string>
-    <string name="permlab_writeCalendar" msgid="8438874755193825647">"所有者に通知せずに、カレンダーの予定の追加や変更を行い、ゲストにメールを送信する"</string>
+    <string name="permlab_writeCalendar" msgid="8438874755193825647">"カレンダーの予定の変更や追加を行う、所有者に通知せずにゲストにメールを送信する場合がある"</string>
     <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"ユーザーがタブレットから編集できる予定(友だちや同僚の予定も含む)を追加、削除、変更することをアプリに許可します。これによりアプリは、カレンダーの所有者から発信されたかのようなメッセージを送信したり、所有者の知らないうちに予定を変更したりできるようになる可能性があります。"</string>
     <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"ユーザーが携帯端末から編集できる予定(友だちや同僚の予定も含む)を追加、削除、変更することをアプリに許可します。これによりアプリは、カレンダーの所有者から発信されたかのようなメッセージを送信したり、所有者の知らないうちに予定を変更したりできるようになる可能性があります。"</string>
     <string name="permlab_accessMockLocation" msgid="8688334974036823330">"仮の位置情報でテスト"</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Wi-Fiディスプレイを設定して接続することをアプリに許可します。"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wi-Fiディスプレイの制御"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Wi-Fiディスプレイの低レベル機能を制御することをアプリに許可します。"</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"音声出力のキャプチャ"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"音声出力のキャプチャとリダイレクトをアプリに許可します。"</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"動画出力のキャプチャ"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"動画出力のキャプチャとリダイレクトをアプリに許可します。"</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"セキュリティ保護された動画出力のキャプチャ"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"セキュリティ保護された動画出力のキャプチャとリダイレクトをアプリに許可します。"</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"音声設定の変更"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"音声全般の設定(音量、出力に使用するスピーカーなど)の変更をアプリに許可します。"</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"録音"</string>
@@ -525,6 +552,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"端末のスリープを無効にする"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"タブレットのスリープを無効にすることをアプリに許可します。"</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"携帯端末のスリープを無効にすることをアプリに許可します。"</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"タブレットの電源ON/OFF"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"電源のON/OFF"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"タブレットの電源のON/OFFをアプリに許可します。"</string>
@@ -613,6 +646,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"SDカードへの書き込みをアプリに許可します。"</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"内部メディアストレージの内容の変更/削除"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"内部メディアストレージの内容を変更することをアプリに許可します。"</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"ドキュメントストレージの管理"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"ドキュメントストレージの管理をアプリに許可します。"</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"全ユーザー外部ストレージへのアクセス"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"すべてのユーザーの外部ストレージへのアクセスをアプリに許可します。"</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"キャッシュファイルシステムにアクセス"</string>
@@ -625,10 +660,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"ネットワークポリシーを管理しアプリ固有のルールを定義することをアプリに許可します。"</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"ネットワークの課金の変更"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"アプリに対するネットワーク利用の計算方法を変更することをアプリに許可します。通常のアプリでは使用しません。"</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"ソケットマークの変更"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"ルーティングのソケットマークを変更することをアプリに許可します。"</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_invokeCarrierSetup" msgid="3699600833975117478">"携帯通信会社が提供する設定アプリの呼び出し"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"携帯通信会社が提供する設定アプリを呼び出すことを所有者に許可します。通常のアプリでは不要です。"</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"ネットワーク状況監視のためのリッスン"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"ネットワーク状況を監視するためリッスンすることをアプリに許可します。通常のアプリで必要になることはありません。"</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"パスワードルールの設定"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"画面ロック解除パスワードの長さと使用できる文字を制御します。"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"画面ロック解除試行の監視"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <string name="imProtocolGoogleTalk" msgid="493902321140277304">"ハングアウト"</string>
     <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string>
     <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string>
     <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string>
@@ -796,7 +836,7 @@
     <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">"お使いのSIMカードは永久に無効となっています。\nワイヤレスサービスプロバイダに問い合わせて新しいSIMカードを入手してください。"</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"前のトラックボタン"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"次のトラックボタン"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"一時停止ボタン"</string>
@@ -808,11 +848,11 @@
     <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">%d</xliff:g>回間違えました。"\n\n"<xliff:g id="NUMBER_1">%d</xliff:g>秒後にもう一度お試しください。"</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"正しくないパスワードを<xliff:g id="NUMBER_0">%d</xliff:g>回入力しました。"\n\n"<xliff:g id="NUMBER_1">%d</xliff:g>秒後にもう一度お試しください。"</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"正しくないPINを<xliff:g id="NUMBER_0">%d</xliff:g>回入力しました。"\n\n"<xliff:g id="NUMBER_1">%d</xliff:g>秒後にもう一度お試しください。"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"ロック解除パターンの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回間違えると、タブレットのロック解除にGoogleへのログインが必要になります。"\n\n"<xliff:g id="NUMBER_2">%d</xliff:g>秒後にもう一度お試しください。"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"ロック解除パターンの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回間違えると、携帯端末のロック解除にGoogleへのログインが必要になります。"\n\n"<xliff:g id="NUMBER_2">%d</xliff:g>秒後にもう一度お試しください。"</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"ロック解除パターンの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。\n\n<xliff:g id="NUMBER_1">%d</xliff:g>秒後にもう一度お試しください。"</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"正しくないパスワードを<xliff:g id="NUMBER_0">%d</xliff:g>回入力しました。\n\n<xliff:g id="NUMBER_1">%d</xliff:g>秒後にもう一度お試しください。"</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"正しくないPINを<xliff:g id="NUMBER_0">%d</xliff:g>回入力しました。\n\n<xliff:g id="NUMBER_1">%d</xliff:g>秒後にもう一度お試しください。"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"ロック解除パターンの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回間違えると、タブレットのロック解除にGoogleへのログインが必要になります。\n\n<xliff:g id="NUMBER_2">%d</xliff:g>秒後にもう一度お試しください。"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"ロック解除パターンの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回間違えると、携帯端末のロック解除にGoogleへのログインが必要になります。\n\n<xliff:g id="NUMBER_2">%d</xliff:g>秒後にもう一度お試しください。"</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"タブレットのロック解除に<xliff:g id="NUMBER_0">%d</xliff:g>回失敗しました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回失敗すると、タブレットは工場出荷状態にリセットされ、ユーザーのデータはすべて失われます。"</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"端末のロック解除に<xliff:g id="NUMBER_0">%d</xliff:g>回失敗しました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回失敗すると、端末は工場出荷状態にリセットされ、ユーザーのデータはすべて失われます。"</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"タブレットのロック解除を<xliff:g id="NUMBER">%d</xliff:g>回失敗しました。タブレットを工場出荷状態にリセットします。"</string>
@@ -826,7 +866,7 @@
     <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_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">"サウンドON"</string>
@@ -874,7 +914,7 @@
     <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="autofill_this_form" msgid="4616758841157816676">"自動入力"</string>
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"問題が発生したため、<xliff:g id="APPLICATION">%1$s</xliff:g>を終了します。"</string>
     <string name="aerr_process" msgid="4507058997035697579">"問題が発生したため、プロセス「<xliff:g id="PROCESS">%1$s</xliff:g>」を終了します。"</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g>は応答していません。"\n\n"このアプリを終了しますか?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"操作「<xliff:g id="ACTIVITY">%1$s</xliff:g>」は応答していません。"\n\n"この操作を終了しますか?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g>は応答していません。\n\nこのアプリを終了しますか?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"操作「<xliff:g id="ACTIVITY">%1$s</xliff:g>」は応答していません。\n\nこの操作を終了しますか?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g>は応答していません。このアプリを終了しますか?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"プロセス「<xliff:g id="PROCESS">%1$s</xliff:g>」は応答していません。"\n\n"このプロセスを終了しますか?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"プロセス「<xliff:g id="PROCESS">%1$s</xliff:g>」は応答していません。\n\nこのプロセスを終了しますか?"</string>
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"レポート"</string>
     <string name="wait" msgid="7147118217226317732">"待機"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"ページが応答しません。"\n\n"ページを閉じますか?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"ページが応答しません。\n\nページを閉じますか?"</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>
@@ -1256,6 +1296,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"デフォルトのコンテナサービスを呼び出してコンテンツをコピーすることをアプリに許可します。通常のアプリでは使用しません。"</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"メディア出力のルーティング"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"メディア出力を他の外部デバイスにルーティングすることをアプリに許可します。"</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"キーガードセキュアストレージへのアクセス"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"キーガードセキュアストレージへのアクセスをアプリに許可する"</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"キーガードの表示/非表示の制御"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"キーガードの制御をアプリに許可します。"</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"ダブルタップでズームコントロール"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"ウィジェットを追加できませんでした。"</string>
     <string name="ime_action_go" msgid="8320845651737369027">"移動"</string>
@@ -1265,15 +1309,15 @@
     <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="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="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">"次のアカウントにアクセスする権限が"\n"リクエストされました: <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"次のアカウントにアクセスする権限が\nリクエストされました: <xliff:g id="ACCOUNT">%s</xliff:g>"</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>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"すべて表示"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"操作の選択"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"共有"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"端末がロックされています。"</string>
     <string name="list_delimeter" msgid="3975117572185494152">"、 "</string>
     <string name="sending" msgid="3245653681008218030">"送信中..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"ブラウザを起動しますか?"</string>
@@ -1441,10 +1484,12 @@
     <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>
+    <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_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="wifi_display_notification_title" msgid="2223050649240326557">"ワイヤレスディスプレイが接続されています"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"この画面は別の端末で表示されています"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"切断"</string>
@@ -1453,7 +1498,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">%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">"SIM PINを入力"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"PINを入力"</string>
@@ -1473,27 +1518,85 @@
     <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_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">%d</xliff:g>回間違えました。"\n\n"<xliff:g id="NUMBER_1">%d</xliff:g>秒後にもう一度お試しください。"</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"パスワードの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。"\n\n"<xliff:g id="NUMBER_1">%d</xliff:g>秒後にもう一度お試しください。"</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"ロック解除パターンの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。"\n\n"<xliff:g id="NUMBER_1">%d</xliff:g>秒後にもう一度お試しください。"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PINの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。\n\n<xliff:g id="NUMBER_1">%d</xliff:g>秒後にもう一度お試しください。"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"パスワードの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。\n\n<xliff:g id="NUMBER_1">%d</xliff:g>秒後にもう一度お試しください。"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"ロック解除パターンの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。\n\n<xliff:g id="NUMBER_1">%d</xliff:g>秒後にもう一度お試しください。"</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"タブレットのロック解除に<xliff:g id="NUMBER_0">%d</xliff:g>回失敗しました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回失敗すると、タブレットは出荷時設定にリセットされ、ユーザーのデータはすべて失われます。"</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"携帯端末のロック解除に<xliff:g id="NUMBER_0">%d</xliff:g>回失敗しました。あと<xliff:g id="NUMBER_1">%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="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">%d</xliff:g>回間違えました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回間違えると、タブレットのロック解除にメールアカウントが必要になります。"\n\n"<xliff:g id="NUMBER_2">%d</xliff:g>秒後にもう一度お試しください。"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"ロック解除パターンの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回間違えると、携帯端末のロック解除にメールアカウントが必要になります。"\n\n"<xliff:g id="NUMBER_2">%d</xliff:g>秒後にもう一度お試しください。"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"ロック解除パターンの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回間違えると、タブレットのロック解除にメールアカウントが必要になります。\n\n<xliff:g id="NUMBER_2">%d</xliff:g>秒後にもう一度お試しください。"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"ロック解除パターンの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回間違えると、携帯端末のロック解除にメールアカウントが必要になります。\n\n<xliff:g id="NUMBER_2">%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="7324161939475478066">"推奨レベルを超えるまで音量を上げますか?"\n"大音量で長時間聞き続けると、聴力を損なう恐れがあります。"</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"推奨レベルを超えるまで音量を上げますか?\n大音量で長時間聞き続けると、聴力を損なう恐れがあります。"</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"ユーザー補助機能を有効にするには2本の指で押し続けてください。"</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"ユーザー補助が有効になりました。"</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"ユーザー補助をキャンセルしました。"</string>
     <string name="user_switched" msgid="3768006783166984410">"現在のユーザーは<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="app_no_restricted_accounts" msgid="4011285085817350390">"このアプリでは制限付きプロフィールのアカウントはサポートしていません"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"このアプリでは制限付きプロフィールのアカウントはサポートしていません"</string>
     <string name="app_not_found" msgid="3429141853498927379">"この操作を行うアプリが見つかりません"</string>
     <string name="revoke" msgid="5404479185228271586">"取り消し"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"レター"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"ガバメントレター"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"リーガル"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"ジュニアリーガル"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"レジャー"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"タブロイド"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"キャンセルされました"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"コンテンツの書き込み中にエラーが発生しました"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"不明"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"管理者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>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"新しいPIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"新しいPINの確認"</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_too_short" msgid="8173982756265777792">"PINが短すぎます。4桁以上にしてください。"</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"1秒後に再試行"</item>
+    <item quantity="other" msgid="4730868920742952817">"<xliff:g id="COUNT">%d</xliff:g>秒後に再試行"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"しばらくしてから再試行"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"画面の端からスワイプしてバーを表示"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"システムバーを表示するには、画面の端からスワイプします"</string>
 </resources>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
new file mode 100644
index 0000000..56d18d3
--- /dev/null
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -0,0 +1,1602 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<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">"ბაიტი"</string>
+    <string name="kilobyteShort" msgid="5973789783504771878">"კბაიტი"</string>
+    <string name="megabyteShort" msgid="6355851576770428922">"მბაიტი"</string>
+    <string name="gigabyteShort" msgid="3259882455212193214">"გბაიტი"</string>
+    <string name="terabyteShort" msgid="231613018159186962">"ტბაიტი"</string>
+    <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
+    <string name="untitled" msgid="4638956954852782576">"უსათაურო"</string>
+    <string name="ellipsis" msgid="7899829516048813237">"…"</string>
+    <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
+    <string name="emptyPhoneNumber" msgid="7694063042079676517">"(ტელეფონის ნომრის გარეშე)"</string>
+    <string name="unknownName" msgid="2277556546742746522">"(უცნობი)"</string>
+    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"ხმოვანი ფოსტა"</string>
+    <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
+    <string name="mmiError" msgid="5154499457739052907">"კავშირის პრობლემა ან არასწორი MMI კოდი."</string>
+    <string name="mmiFdnError" msgid="5224398216385316471">"ოპერაცია შეზღუდულია მხოლოდ დაშვებულ ნომრებზე."</string>
+    <string name="serviceEnabled" msgid="8147278346414714315">"სერვისი ჩართულია."</string>
+    <string name="serviceEnabledFor" msgid="6856228140453471041">"სერვისი ჩართულია შემდეგისთვის:"</string>
+    <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="mmiComplete" msgid="8232527495411698359">"MMI დასრულდა."</string>
+    <string name="badPin" msgid="9015277645546710014">"თქვენ მიერ შეყვანილი ძველი პინ-კოდი არასწორია."</string>
+    <string name="badPuk" msgid="5487257647081132201">"თქვენ მიერ შეყვანილი PUK კოდი არასწორია."</string>
+    <string name="mismatchPin" msgid="609379054496863419">"თქვენ მიერ შეყვანილი PIN კოდები არ შეესატყვისება."</string>
+    <string name="invalidPin" msgid="3850018445187475377">"აკრიფეთ PIN, რომელიც შედგება 4-დან 8 ციფრამდე."</string>
+    <string name="invalidPuk" msgid="8761456210898036513">"აკრიფეთ PUK, რომელიც რვა ან მეტი ციფრისგან შედგება."</string>
+    <string name="needPuk" msgid="919668385956251611">"თქვენი SIM ბარათი დაბლოკილია PUK კოდით. განბლოკვისთვის შეიყვანეთ PUK კოდი."</string>
+    <string name="needPuk2" msgid="4526033371987193070">"SIM ბარათის განსაბლოკად აკრიფეთ PUK2."</string>
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
+    <string name="ClipMmi" msgid="6952821216480289285">"შემომავალი ზარის აბონენტის ID"</string>
+    <string name="ClirMmi" msgid="7784673673446833091">"გამავალი მრეკავის ID"</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">"PIN-ის შეცვლა"</string>
+    <string name="CnipMmi" msgid="3110534680557857162">"გამომძახებლის ნომერი წარმოდგენილია"</string>
+    <string name="CnirMmi" msgid="3062102121430548731">"შემოსული ზარი შეზღუდულია"</string>
+    <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="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"ნაგულისხმებად დაყენებულია ნომრის დაფარვა. შემდეგი ზარი: დაფარულია."</string>
+    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"ნაგულისხმებად დაყენებულია ნომრის დაფარვა. შემდეგი ზარი: არ არის დაფარული."</string>
+    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"ნაგულისხმებად დაყენებულია ნომრის დაფარვის გამორთვა. შემდეგი ზარი: დაფარულია."</string>
+    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"ნაგულისხმებად დაყენებულია ნომრის დაფარვის გამორთვა. შემდეგი ზარი: არ არის დაფარული."</string>
+    <string name="serviceNotProvisioned" msgid="8614830180508686666">"სერვისი არ არის მიწოდებული."</string>
+    <string name="CLIRPermanent" msgid="3377371145926835671">"არ შეგიძლიათ აბონენტის ID პარამეტრების შეცვლა."</string>
+    <string name="RestrictedChangedTitle" msgid="5592189398956187498">"წვდომის შეზღუდვები შეცვლილია"</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="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>
+    <string name="serviceClassDataSync" msgid="7530000519646054776">"სინქრონიზაცია"</string>
+    <string name="serviceClassPacket" msgid="6991006557993423453">"პაკეტი"</string>
+    <string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
+    <string name="roamingText0" msgid="7170335472198694945">"როუმინგის მაჩვენებელი ჩართულია."</string>
+    <string name="roamingText1" msgid="5314861519752538922">"როუმინგის მაჩვენებელი გამორთულია."</string>
+    <string name="roamingText2" msgid="8969929049081268115">"როუმინგის მაჩვენებლის ციმციმი"</string>
+    <string name="roamingText3" msgid="5148255027043943317">"სამეზობლოს მიღმა"</string>
+    <string name="roamingText4" msgid="8808456682550796530">"შენობის გარეთ"</string>
+    <string name="roamingText5" msgid="7604063252850354350">"როუმინგი - უპირატესი სისტემა"</string>
+    <string name="roamingText6" msgid="2059440825782871513">"როუმინგი - ხელმისაწვდომი სისტემა"</string>
+    <string name="roamingText7" msgid="7112078724097233605">"როუმინგი - ალიანსის პარტნიორი"</string>
+    <string name="roamingText8" msgid="5989569778604089291">"როუმინგი - პრემიუმ პარტნიორი"</string>
+    <string name="roamingText9" msgid="7969296811355152491">"Roaming - Full Service Functionality"</string>
+    <string name="roamingText10" msgid="3992906999815316417">"Roaming - Partial Service Functionality"</string>
+    <string name="roamingText11" msgid="4154476854426920970">"Roaming Banner ჩართულია"</string>
+    <string name="roamingText12" msgid="1189071119992726320">"როუმინგის ბანერი გამორთულია"</string>
+    <string name="roamingTextSearching" msgid="8360141885972279963">"სერვისის ძიება"</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="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="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="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="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="default" msgid="3475999286680000541">"ტელეფონის მეხსიერება გავსებულია. ადგილის გასათავისუფლებლად წაშალეთ ფაილების ნაწილი."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"შესაძლოა ქსელი მონიტორინგის ქვეშ იმყოფება"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
+    <string name="me" msgid="6545696007631404292">"მე"</string>
+    <string name="power_dialog" product="tablet" msgid="8545351420865202853">"ტაბლეტის პარამეტრები"</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="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="shutdown_progress" msgid="2281079257329981203">"გამორთვა…"</string>
+    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"თქვენი ტაბლეტი გაითიშება."</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="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_bug_report" msgid="7934010578922304799">"ხარვეზის შესახებ ანგარიში"</string>
+    <string name="bugreport_title" msgid="2667494803742548533">"შექმენით შეცდომის ანგარიში"</string>
+    <string name="bugreport_message" msgid="398447048750350456">"იგი შეაგროვებს ინფორმაციას თქვენი მოწყობილობის ამჟამინდელი მდგომარეობის შესახებ, რათა ის ელფოსტის შეტყობინების სახით გააგზავნოს. ხარვეზის ანგარიშის მომზადებასა და შეტყობინების გაგზავნას გარკვეული დრო სჭირდება. გთხოვთ, მოითმინოთ."</string>
+    <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_airplane_mode_on_status" msgid="2719557982608919750">"თვითმფრინავის რეჟიმი ჩართულია."</string>
+    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"თვითმფრინავის რეჟიმი გამორთულია."</string>
+    <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
+    <string name="safeMode" msgid="2788228061547930246">"უსაფრთხო რეჟიმი"</string>
+    <string name="android_system_label" msgid="6577375335728551336">"Android-ის სისტემა"</string>
+    <string name="permgrouplab_costMoney" msgid="5429808217861460401">"სერვისები, რომელშიც ფულის გადახდა გიწევთ"</string>
+    <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"ისეთი აქტივობების განხორციელება, რომლებშიც ფულის გადახდა მოგიწევთ."</string>
+    <string name="permgrouplab_messages" msgid="7521249148445456662">"თქვენი შეტყობინებები"</string>
+    <string name="permgroupdesc_messages" msgid="7821999071003699236">"თქვენი SMS-ის, ელფოტის და სხვა შეტყობინებების წაკითხვა და დაწერა."</string>
+    <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"თქვენი პირადი ინფორმაცია"</string>
+    <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"პირდაპირი წვდომა თქვენ შესახებ ინფორმაციაზე, რომელიც საკონტაქტო ბარათზეა შენახული."</string>
+    <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"თქვენი სოციალური ინფორმაცია"</string>
+    <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"თქვენს კონტაქტებისა და სოციალურ კავშირების შესახებ ინფორმაციაზე პირდაპირი წვდომა."</string>
+    <string name="permgrouplab_location" msgid="635149742436692049">"თქვენი მდებარეობა"</string>
+    <string name="permgroupdesc_location" msgid="5704679763124170100">"თქვენი ფიზიკური მდებარეობის მონიტორინგი"</string>
+    <string name="permgrouplab_network" msgid="5808983377727109831">"ქსელის კომუნიკაცია"</string>
+    <string name="permgroupdesc_network" msgid="4478299413241861987">"წვდომა ქსელის სხვადასხვა პარამეტრთან."</string>
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"Bluetooth"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"მოწყობილობებთან და ქსელებთან წვდომა Bluetooth მეშვეობით."</string>
+    <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"აუდიო პარამეტრები"</string>
+    <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"აუდიო პარამეტრების შეცვლა."</string>
+    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"ხარჯავს ბატარეას"</string>
+    <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"იმ ფუნქციების გამოყენება, რომელიც ელემენტს სწრაფად დახლის."</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"კალენდარი"</string>
+    <string name="permgroupdesc_calendar" msgid="5777534316982184416">"კალენდარსა და ღონისძიებებზე პირდაპირი წვდომა."</string>
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"მომხმარებლის ლექსიკონის წაკითხვა"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"მომხმარებლის ლექსიკონში სიტყვების წაკითხვა"</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"მომხმარებლის ლექსიკონში ჩაწერა"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"მომხმარებლის ლექსიკონში სიტყვების დამატება."</string>
+    <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"სანიშნეები და ისტორია"</string>
+    <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"პირდაპირი წვდომა სანიშნეებსა და ბრაუზერის ისტორიაზე"</string>
+    <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"მაღვიძარა"</string>
+    <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"მაღვიძარის დაყენება."</string>
+    <string name="permgrouplab_voicemail" msgid="4162237145027592133">"ხმოვანი ფოსტა"</string>
+    <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"პირდაპირი წვდომა ხმოვან ფოსტაზე"</string>
+    <string name="permgrouplab_microphone" msgid="171539900250043464">"მიკროფონი"</string>
+    <string name="permgroupdesc_microphone" msgid="7106618286905738408">"პირდაპირი წვდომა მიკროფონზე აუდიოს ჩასაწერად."</string>
+    <string name="permgrouplab_camera" msgid="4820372495894586615">"კამერა"</string>
+    <string name="permgroupdesc_camera" msgid="2933667372289567714">"პირდაპირი წვდომა კამერაზე სურათის ან ვიდეოს გადასაღებად"</string>
+    <string name="permgrouplab_screenlock" msgid="8275500173330718168">"ჩაკეტილი ეკრანი"</string>
+    <string name="permgroupdesc_screenlock" msgid="7067497128925499401">"მოწყობილობის ეკრანის ჩამკეტის ქცევის შეცვლის შესაძლებლობა."</string>
+    <string name="permgrouplab_appInfo" msgid="8028789762634147725">"თქვენი აპლიკაციების ინფორმაცია"</string>
+    <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"თქვენს მოწყობილობაზე სხვა აპლიკაციების ქცევის შეცვლის შესაძლებლობა."</string>
+    <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"ფონი"</string>
+    <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"მოწყობილობის ფონის პარამეტრების შეცვლა."</string>
+    <string name="permgrouplab_systemClock" msgid="406535759236612992">"საათი"</string>
+    <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"მოწყობილობის დროის ან დროითი სარტყლის შეცვლა."</string>
+    <string name="permgrouplab_statusBar" msgid="2095862568113945398">"სტატუსის ზოლი"</string>
+    <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"მოწყობილობის სტატუსების ზოლის პარამეტრების შეცვლა."</string>
+    <string name="permgrouplab_syncSettings" msgid="3341990986147826541">"სინქრონიზაციის პარამეტრები"</string>
+    <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"სინქრონიზაციის პარამეტრებზე წვდომა"</string>
+    <string name="permgrouplab_accounts" msgid="3359646291125325519">"თქვენი ანგარიშები"</string>
+    <string name="permgroupdesc_accounts" msgid="4948732641827091312">"ხელმისაწვდომ ანგარიშებზე წვდომა."</string>
+    <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"მოწყობილობების მართვა"</string>
+    <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"ყურსაცვამის აპარატურულ მოწყობილობაზე პირდაპირი წვდომა."</string>
+    <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"სატელეფონო ზარები"</string>
+    <string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"სატელეფონო ზარების მონიტორინგი, ჩაწერა და განხორციელება."</string>
+    <string name="permgrouplab_systemTools" msgid="4652191644082714048">"სისტემური ინსტრუმენტები"</string>
+    <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"დაბალი წვდომა და სისტემის კონტროლი"</string>
+    <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"დეველოპმენტის ინსტრუმენტები"</string>
+    <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"ელემენტები, რომლებიც მხოლოდ აპების დეველოპერებს სჭირდებათ."</string>
+    <string name="permgrouplab_display" msgid="4279909676036402636">"სხვა აპლიკაციის UI"</string>
+    <string name="permgroupdesc_display" msgid="6051002031933013714">"სხვა აპლიკაციების UI-ის ეფექტი."</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"შესანახი სივრცე"</string>
+    <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"USB მეხსიერებასთან წვდომა."</string>
+    <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"SD ბარათთან წვდომა."</string>
+    <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"წვდომის ფუნქციები"</string>
+    <string name="permgroupdesc_accessibilityFeatures" msgid="4205196881678144335">"ფუნქციები, რომელიც შესაძლოა მოითხოვოს დამხმარე ტექნოლოგიამ."</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="5800552516779249356">"ის ერთეულები, რომლებსაც შეეხებით, წაიკითხება ხმამაღლა და ეკრანის კვლევა შეიძლება ჟესტების გამოყენებით."</string>
+    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"ვებზე გამარტივებული წვდომის დამატებითი შესაძლებლობების ჩართვა"</string>
+    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"შესაძლებელია სკრიპტების ინსტალაცია აპის კონტენტის წვდომადობის უზრუნველსაყოფად."</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"თქვენ მიერ აკრეფილ ტექსტზე დაკვირვება"</string>
+    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"შეიცავს ისეთ პირად მონაცემებს, როგორიცაა საკრედიტო ბარათის ნომრები და პაროლები."</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"სტატუსის ზოლის გათიშვა ან ცვლილება"</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"აპს შეეძლება სტატუსების ზოლის გათიშვა და სისტემის ხატულების დამატება/წაშლა."</string>
+    <string name="permlab_statusBarService" msgid="7247281911387931485">"სტატუსის ზოლი"</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_processOutgoingCalls" msgid="3906007831192990946">"გამავალი ზარების გადამისამართება"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"აპს შეეძლება გამავალი ზარების დამუშავება და ასაკრეფი ნომრის შეცვლა. ეს უფლება აპს აძლევს შესაძლებლობას აკონტროლოს, გადაამისამართოს ან აღკვეთოს გამავალი ზარები."</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_receiveEmergencyBroadcast" msgid="1803477660846288089">"გადაუდებელი შეტყობინებების მიღება"</string>
+    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"აპს შეეძლება, მიიღოს და დაამუშაოს საგანგებო სამაუწყებლო შეტყობინებები. ეს ნებართვა ხელმისაწვდომია მხოლოდ  სისტემის აპებისთვის."</string>
+    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"მასიური დაგზავნის შეტყობინებების წაკითხვა"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"აპს შეეძლება, წაიკითხოს თქვენს მოწყობილობაზე გამოგზავნილი ქსელის სამაუწყებლო შეტყობინებები. სამაუწყებლო გაფრთხილებები მოგეწოდებათ ზოგიერთ ადგილზე ექსტრემალური სიტუაციების შესახებ გასაფრთხილებლად. ქსელის გადაუდებელი შეტყონიბენის მიღების დროს მავნე აპებმა შეიძლება ხელი შეუშალონ თქვენი მოწყობილობის ფუნქციონირებას ან ოპერაციებს."</string>
+    <string name="permlab_sendSms" msgid="5600830612147671529">"SMS შეტყობის გაგზავნა"</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"აპს შეეძლება, გაგზავნოს SMS შეტყობინებები, რამაც შეიძლება გაუთვალისწინებელი ხარჯები გამოიწვიოს. მავნე აპებმა შეიძლება დაგიხარჯონ ფული შეტყობინებების თქვენი თანხმობის გარეშე გაგზავნით."</string>
+    <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"ღონისძიებების გაგზავნა (პასუხის მიღება მხოლოდ შეტყობინებით)"</string>
+    <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"აპს შეეძლება, გაუგზავნოს მოთხოვნები სხვა შეტყობინებების აპებს შემომავალ ზარებზე შეტყობინებით პასუხის მოვლენებთან გასამკლავებლად."</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"თქვენი ტექსტური შეტყობინებების (SMS ან MMS) წაკითხვა"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"აპს შეეძლება თქვენს ტაბლეტში ან SIM ბარათში შენახული SMS შეტყობინებების წაკითხვა. ამგვარად, აპს ექნება შესაძლებლობა წაიკითხოს ყველა SMS შეტყობინება, მათი კონტენტისა და კონფიდენციალურობის მიუხედავად."</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"აპს შეეძლება თქვენს ტაბლეტში ან SIM ბარათში შენახული SMS შეტყობინებების წაკითხვა. ამგვარად, აპს ექნება შესაძლებლობა წაიკითხოს ყველა SMS შეტყობინება, მათი კონტენტისა და კონფიდენციალურობის მიუხედავად."</string>
+    <string name="permlab_writeSms" msgid="3216950472636214774">"თქვენი ტექსტური შეტყობინებების (SMS ან MMS) რედაქტირება"</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"აპს შეეძლება, უპასუხოს თქვენ ტაბლეტში ან SIM ბარათზე შენახულ SMS შეტყობინებებს. მავნე აპებმა შეიძლება წაშალონ თქვენი შეტყობინებები."</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"აპს უფლება ექნება , უპასუხოს თქვენ ტაბლეტში ან SIM ბარათზე შენახულ 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_interactAcrossUsers" msgid="7114255281944211682">"მომხმარებლებს შორის ინტერაქცია"</string>
+    <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"აპს შეეძლება, სხვადასხვა მომხმარებლის მოქმედებები შეასრულოს მოწყობილობაზე. მავნე აპებმა შეიძლება მომხმარებლებს შორის დაცვის დასარღვევად გამოიყენონ."</string>
+    <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"მომხმარებლებთან ინტერაქციის სრული ლიცენზია"</string>
+    <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"აძლევს მომხმარებლებს შორის ყველა შესაძლო ინტერაქციის უფლებას."</string>
+    <string name="permlab_manageUsers" msgid="1676150911672282428">"მომხმარებლების მართვა"</string>
+    <string name="permdesc_manageUsers" msgid="8409306667645355638">"აპს შეუძლია მომხმარებლების მართვა მოწყობილობაზე, მათ შორის მოთხოვნის, შექმნის და წაშლის."</string>
+    <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"მოქმედი აპების დეტალების მოძიება"</string>
+    <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"აპს შეეძლება მოიძიოს დეტალური ინფორმაცია ამჟამად და უახლოეს წარსულში მიმდინარე ამოცანების შესახებ. მავნე აპებს შეუძლიათ აღმოაჩინონ პირადი ინფორმაცია სხვა აპების შესახებ."</string>
+    <string name="permlab_reorderTasks" msgid="2018575526934422779">"მოქმედი აპების წყობის შეცვლა"</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"აპს შეეძლება ამოცანების გადატანა წინა და უკანა პლანზე. ამას თქვენი ჩარევის გარეშე გააკეთებს."</string>
+    <string name="permlab_removeTasks" msgid="6821513401870377403">"გაშვებული აპების შეწყვეტა"</string>
+    <string name="permdesc_removeTasks" msgid="1394714352062635493">"აპს შეეძლება ამოცანების წაშლა და მათი აპების გაუქმება. მავნე აპებმა შესაძლოა დაარღვიონ სხვა აპების მოქმედება."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"აქტივობის დასტების მართვა"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"საშუალებას აძლევს აპს დაამატოს, ამოშალოს და შეცვალოს აქტივობის დასტები, რაშიც სხვა აპები ეშვება. მავნე აპები სხვა აპებს ქცევის ხელის შეშლას შეძლებს."</string>
+    <string name="permlab_startAnyActivity" msgid="2918768238045206456">"ნებისმიერი აქტივობის წამოწყება"</string>
+    <string name="permdesc_startAnyActivity" msgid="997823695343584001">"აპს შეეძლება დაიწყოს ნებისმიერი აქტივობა, ყოველგვარი უფლებისა და სტატუსის გარეშე."</string>
+    <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"ეკრანის თავსებადობის დაყენება"</string>
+    <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"აპს შეეძლება სხვა აპლიკაციებთან ეკრანის თავსებადობის რეჟიმის კონტროლი. მავნე აპლიკაციებმა შესაძლოა სხვა აპლიაკციების ქცევა შეცვალოს."</string>
+    <string name="permlab_setDebugApp" msgid="3022107198686584052">"აპის გამართვის გააქტიურება"</string>
+    <string name="permdesc_setDebugApp" msgid="4474512416299013256">"აპს შეეძლება სხვა აპისთვის გამართვის რეჟიმის ჩართვა. მავნე აპლიკაციებს ამ ფუნქციით შეეძლებათ სხვა აპების გათიშვა."</string>
+    <string name="permlab_changeConfiguration" msgid="4162092185124234480">"სისტემის ინტერფეისის პარამეტრების შეცვლა"</string>
+    <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"აპს შეეძლება, შეცვალოს ამჟამინდელი კონფიგურაცია, მაგალითად, ენა და ქვეყნის კოდი ან შრიფტის ზომა."</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_forceStopPackages" msgid="2329627428832067700">"სხვა აპების იძულებითი შეჩერება"</string>
+    <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"აპს შეეძლება იძულებით შეწყვიტოს სხვა აპების მუშაობა."</string>
+    <string name="permlab_forceBack" msgid="652935204072584616">"აპის ძალით დახურვა"</string>
+    <string name="permdesc_forceBack" msgid="3892295830419513623">"აპს შეეძლება იძულებით დაასრულოს წინა პლანზე მიმდინარე ნებისმიერი აქტივობა და დაბრუნდეს უკან. ჩვეულებრივ აპებს მსგავსი რამ არასოდეს სჭირდება."</string>
+    <string name="permlab_dump" msgid="1681799862438954752">"სისტემის მდგომარეობის შესახებ ინფორმაციის მიღება"</string>
+    <string name="permdesc_dump" msgid="1778299088692290329">"აპს შეეძლება სისტემის შიდა მდგომარეობის ნახვა. მავნე პროგრამები შეძლებენ პირადი და დაცული ინფორმაციის ნახვას, რომელთან წვდომის საშუალებაც მათ არ უნდა ჰქონდეთ."</string>
+    <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"ეკრანის კონტენტის მოძიება"</string>
+    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"აპს შეეძლება აქტიური ფანჯრიდან კონტენტის მოძიება. მავნე აპებს შეუძლიათ ფანჯრის სრული კონტენტის მოძიება და ყველა ტექსტის წაკითხვა პაროლების გარდა."</string>
+    <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"მარტივი წვდომის დროებით გააქტიურება"</string>
+    <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"აპს შეეძლება მოწყობილობაზე გამარტივებული რეჟიმის ჩართვა. მავნე აპებს შეეძლებათ ამ რეჟიმის ჩართვა მომხმარებლის გაფრთხილების გარეშე."</string>
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"ფანჯრის ინფორმაციის მოძიება"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"აპს შეეძლება ფანჯრების მენეჯერის მეშვეობით ფანჯრების შესახებ ინფორმაციის მოპოვება. მავნე აპლიკაციებს შეეძლებათ ისეთი ინფორმაციის მოპოვება, რომელიც შიდა სისტემური მოხმარებისთვის არის განკუთვნილი."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"ღონისძიებების გაფილტვრა"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"აპლიკაციას შეეძლება რეგისტრაცია შეტანის ფილტრებისა, რომლებიც ასუფთავებენ მომხმარებლის ღონისძიების ყველა დინებას. მავნე აპმა შესაძლოა ეს ფუნქცია სისტემის UI კონტროლისთვის გამოიყენოს, მომხმარებლის ინტერვენციის გარეშე."</string>
+    <string name="permlab_magnify_display" msgid="5973626738170618775">"ეკრანის გადიდება"</string>
+    <string name="permdesc_magnify_display" msgid="7121235684515003792">"აპლიკაციას შეეძლება, შეცვალოს დისპლეის კონტენტი. მავნე აპებმა შეიძლება იმგვარად გარდაქმნან დისპლეის კონტენტი, რომ  მოწყობილობა გამოუსადეგარი გახდეს."</string>
+    <string name="permlab_shutdown" msgid="7185747824038909016">"ნაწილობრივი გამორთვა"</string>
+    <string name="permdesc_shutdown" msgid="7046500838746291775">"აქტივობების მენეჯერს გათიშვის რეჟიმში აყენებს. სრულ გათიშვას არ ახორციელებს."</string>
+    <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"აპის გადართვებისგან დაცვა"</string>
+    <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"ხელს უშლის მომხმარებლის სხვა აპზე გადართვას."</string>
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"ამჟამინდელი აპის ინფორმაციის მიღება"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"ნებას რთავს მფლობელს, მოიპოვოს მიმდინარე აპლიკაციის შესახებ პირადი ინფორმაცია ეკრანის წინა პლანზე."</string>
+    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"ყველა აპის გაშვების მონიტორინგი დ კონტროლი"</string>
+    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"აპს შეეძლება სისტემის მიერ გამოძახებული აქტივობების მონიტორინგი და მართვა. მავნე აპლიკაციებს შეეძლებათ სისტემის სრული კონტროლი. ეს ნებართვა საჭროა მხოლოდ დეველოპმენტისთვის და ჩვეულებრივი მოხმარებისთის არ გამოიყენება."</string>
+    <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"პაკეტების წაშლის შესახებ შეტყობინებების გაგზავნა"</string>
+    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"აპს შეეძლება, გაგზავნოს შეტყობინება, რომ აპის პაკეტი წაიშალა. მავნე აპებმა ეს უფლება შეიძლება გამოიყენონ სხვა ნებისმიერი გაშვებული აპების შესაწყვეტად."</string>
+    <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"SMS-ით მიღებული სამაუწყებლო შეტყობინების გაგზავნა"</string>
+    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"აპს საშუალებას აძლევს გააგზავნოს შეტყობინება SMS შეტყობინების მიღების თაობაზე. მავნე აპლიკაციებში ეს ფუნქცია შეიძლება გამოყენებული იქნას SMS შეტყობინებების მიღების იმიტაციიისათვის."</string>
+    <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"WAP-PUSH-ით მიღებული სამაუწყებლო შეტყობინების გაგზავნა"</string>
+    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"აპს შეეძლება, გაგზავნოს შეტყობინება WAP PUSH შეტყობინების მიღების თაობაზე. მავნე აპებმა ეს შეიძლება გამოიყენონ MMS შეტყობინების მიღების გასაყალბებლად ან ნებისმიერი ვებგვერდის კონტენტის სახიფათო ვარიანტებით ჩუმად ჩასანაცვლებლად."</string>
+    <string name="permlab_setProcessLimit" msgid="2451873664363662666">"მიმდინარე პროცესების რაოდენობის ლიმიტი"</string>
+    <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"აპს შეეძლება, გააკონტროლოს მიმდინარე პროცესების მაქსიმალური რაოდენობა. ჩვეულებრივ აპებში არასდროს არის საჭირო."</string>
+    <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"უკანა ფონის აპის იძულებით დახურვა"</string>
+    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"აპს შეეძლება გააკონტროლოს, არის თუ არა აქტივობები ყოველთვის დასრულებული მათი უკანა ფონზე გადასვლის დროს. არასდროს არის საჭირო ჩვეულებრივ აპებში."</string>
+    <string name="permlab_batteryStats" msgid="2789610673514103364">"ელემენტის სტატისტიკის წაკითხვა"</string>
+    <string name="permdesc_batteryStats" msgid="5897346582882915114">"აპლიკაციას შეეძლება ამჟამინდელი დაბალი დამუხტვის ელემენტის გამოყენების მონაცემების წაკითხვა. აპლიკაციამ შესაძლოა მოახერხოს თქვენ მიერ გამოყენებული აპების შესახებ დეტალური ინფორმაციის მოძიება."</string>
+    <string name="permlab_updateBatteryStats" msgid="3719689764536379557">"ელემენტის სტატისტიკის შეცვლა"</string>
+    <string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"აპს შეეძლება, შეცვალოს ბატარეის გამოყენების შეგროვებული სტატისტიკა. არ გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_getAppOpsStats" msgid="1508779687436585744">"აპის სამუშაო ჟურნალის სტატისტიკის მოძიება"</string>
+    <string name="permdesc_getAppOpsStats" msgid="6243887041577912877">"აპს შეეძლება აპლიკაციათა ოპერაციების შეგროვებული სტატისტიკის მოპოვება. არ გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"აპის სამუშაო ჟურნალის სტატისტიკის შეცვლა"</string>
+    <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"აპს შეეძლება აპლიკაციის ოპერაციების შეგროვებული სტატისტიკის მოპოვება. არ გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_backup" msgid="470013022865453920">"სისტემის სარეზერვო ასლების კონტროლი და აღდგენა"</string>
+    <string name="permdesc_backup" msgid="6912230525140589891">"აპს შეეძლება სისტემის სარეზერვო ასლების კონტროლი და მექანიზმის აღდგენა. ჩვეულებრივი აპები მსგავს შესაძლებლობებს არ იყენებენ."</string>
+    <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"სრული სარეზერვო ასლების დადასტურება ან ოპერაციის აღდგენა"</string>
+    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"აპს შეეძლება გაუშვას სრული სარეზერვო ასლების UI დადასტურება. არ იყენებს არც ერთი სხვა აპი."</string>
+    <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"არაავტორიზებული ფანჯრების ჩვენება"</string>
+    <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"აპს შეეძლება, შექმნას შიდა სისტემის მომხმარებლის ინტერფეისის მიერ გამოყენებისთვის განკუთვნილი ფანჯრები. არ გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"სხვა აპების ინტერფეისზე გადაწერა"</string>
+    <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"აპს შეეძლება თავისი ინტერფეისი ზემოდან გადააწეროს სხვა აპლიკაციებს ან მომხმარებლის ინტერფეისის ნაწილებს. ამგვარად, შესაძლოა შეიცვალოს სხვა აპლიკაციის ინტერფეისი და ხელი შეგეშალოთ სხვა მასთან მუშაობისას."</string>
+    <string name="permlab_setAnimationScale" msgid="2805103241153907174">"ანიმაციის გლობალური სიჩქარის შეცვლა"</string>
+    <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"აპს შეეძლება გლობალური ანიმაციის სიჩქარის შეცვლა (სწრაფი ან ნელი ანიმაცია) ნებისმიერ დროს."</string>
+    <string name="permlab_manageAppTokens" msgid="1286505717050121370">"აპის წინასწარი გადახდის ბარათების მართვა"</string>
+    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"აპს შეეძლება, შექმნას და მართოს საკუთარი იდენტიფიკაციის ნიშნები, ჩვეულებრივი Z-წყობის უგულვებელყოფით. ჩვეულებრივი აპებისთვის მისი გამოყენება არასდროს არის საჭირო."</string>
+    <string name="permlab_freezeScreen" msgid="4708181184441880175">"ეკრანის გაყინვა"</string>
+    <string name="permdesc_freezeScreen" msgid="8558923789222670064">"აპლიკაციას შეეძლება ეკრანის დროებით გაშეშება სრულ ეკრანზე გადასასვლელად."</string>
+    <string name="permlab_injectEvents" msgid="1378746584023586600">"ღილაკების და სამართავი ელემენტების დაჭერა"</string>
+    <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"აპს შეეძლება შეყვანის საკუთარი მოვლენების (გასაღები და ა.შ.) სხვა აპებისთვის გადაცემა. მავნე აპებმა შესაძლოა ეს გამოიყენონ ტაბლეტის საკონტროლოდ."</string>
+    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"აპს შეეძლება შეყვანის საკუთარი მოვლენების (გასაღები და ა.შ.) სხვა აპებისთვის გადაცემა. მავნე აპებმა შესაძლოა ეს გამოიყენონ ტელეფონის საკონტროლოდ."</string>
+    <string name="permlab_readInputState" msgid="469428900041249234">"მომხმარებლის ქმედებების და მის მიერ შეყვანილი ტექსტის ჩაწერა"</string>
+    <string name="permdesc_readInputState" msgid="8387754901688728043">"აპს შეეძლება დაინახოს გასაღები, როდესაც მას ბეჭდავთ თუნდაც სხვა აპში მუშაობის დროს (მაგალითად, პაროლის აკრეფა). ჩვეულებრივ აპებს მსგავსი რამ არასოდეს სჭირდება."</string>
+    <string name="permlab_bindInputMethod" msgid="3360064620230515776">"შეტანის მეთოდთან დაკავშირება"</string>
+    <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"აპს შეეძლება ზედა დონის ინტერფეისის წვდომის სისტემასთან დაკავშირება. არასდროს გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"გამარტივებული წვდომის სერვისთან მიერთება"</string>
+    <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"აპს შეეძლება გამარტივებული წვდომის სერვისის ზედა დონის ინტერფეისთან დაკავშირება. არასდროს გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"ბეჭდვის სევისზე მიბმა"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"მფლობელს შეეძლება მიებას ბეჭდვის სერვისების ზედა დონის ინტერფეისს. ჩვეულებრივ აპს ეს წესით არასოდეს არ უნდა დაჭირდეს."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"ბეჭდვის spooler სევისზე მიბმა"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"მფლობელს შეეძლება მიებას ბეჭდვის spooler სერვისების ზედა დონის ინტერფეისს. ჩვეულებრივ აპს ეს წესით არასოდეს არ უნდა დაჭირდეს."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC სერვისთან შეკავშირება"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"საშუალებას აძლევს მფლობელს შეკავშირდეს აპლიკაციებთან, რომლებიც NFC ბარათების სიმულაციას ახდენს. ჩვეულებრივ აპებს უმეტეს შემთხვევაში არ დაჭირდება."</string>
+    <string name="permlab_bindTextService" msgid="7358378401915287938">"ტექსტ სერვისთან დაკავშირება"</string>
+    <string name="permdesc_bindTextService" msgid="8151968910973998670">"აპს შეეძლება ზედა დონის ინტერფეისის ტექსტური სამსახურთან (მაგ. SpellCheckerService) დაკავშირება. არასდროს გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_bindVpnService" msgid="4708596021161473255">"VPN სერვისთან დაკავშირება"</string>
+    <string name="permdesc_bindVpnService" msgid="2067845564581693905">"აპს შეეძლება Vpn სერვისის ზედა დონის ინტერფეისთან დაკავშირება. არასდროს გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_bindWallpaper" msgid="8716400279937856462">"ფონზე მიჭედება"</string>
+    <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"მფლობელს შეეძლება ფონის ზედა დონის ინტერფეისთან დაკავშირება. არასდროს გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ვიჯეტ სერვისთან დაკავშირება"</string>
+    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"აპს შეეძლება ზედა დონის ინტერფეისის ვიჯეტთან დაკავშირება. არასდროს გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"მოწყობილობის ადმინთან ინტერაქცია"</string>
+    <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"აპს შეეძლება მოწყობილობის ადმინისტრატორისთვის intent ობიექტების გაგზავნა. არასდროს გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"მოწყობილობის ადმინისტრატორს დამატება ან ამოშლა"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"საშუალებას აძლევს მფლობელს დაამატოს ან ამოშალოს მოწყობილობის აქტიური ადმინისტრატორები. ჩვეულებრივ აპებს, ალბათ, არასოდეს დაჭირდება"</string>
+    <string name="permlab_setOrientation" msgid="3365947717163866844">"ეკრანის ორიენტაციის შეცვლა"</string>
+    <string name="permdesc_setOrientation" msgid="3046126619316671476">"აპს შეეძლება, ატრიალოს ეკრანი ნებისმიერ დროს. არასდროს იქნება საჭირო ჩვეულებრივ აპებში."</string>
+    <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"მაჩვენებლის სიჩქარის შეცვლა"</string>
+    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"აპს შეეძლება, შეცვალოს მაუსის ან თრექპედის კურსორის სიჩქარე ნებისმიერ დროს. არასდროს იქნება საჭირო ჩვეულებრივ აპებში."</string>
+    <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"კლავიატურის განლაგების შეცვლა"</string>
+    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"აპს შეეძლება შეცვალოს კლავიატურის განლაგება. ეს ფუნქცია არასდროს იქნება საჭირო ჩვეულებრივ აპებში."</string>
+    <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"აპებისთვის Linux-ის სიგნალების გაგზავნა"</string>
+    <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"აპს შეეძლება მოითხოვოს უზრუნველყოფილი სიგნალის მუდმივ პროცესებისთვის გაგზავნა."</string>
+    <string name="permlab_persistentActivity" msgid="8841113627955563938">"დააყენოს აპი მუდმივად ჩართულად"</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"აპს შეეძლება, საკუთარი ნაწილები მუდმივად ჩაწეროს მეხსიერებაში. ეს შეზღუდავს მეხსიერების ხელმისაწვდომობას სხვა აპებისთვის და შეანელებს ტაბლეტს."</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"აპს შეეძლება, საკუთარი ნაწილები მუდმივად ჩაწეროს მეხსიერებაში. ეს შეზღუდავს მეხსიერების ხელმისაწვდომობას სხვა აპებისთვის და შეანელებს ტელეფონს."</string>
+    <string name="permlab_deletePackages" msgid="184385129537705938">"აპების წაშლა"</string>
+    <string name="permdesc_deletePackages" msgid="7411480275167205081">"აპს შეეძლება Android პაკეტების წაშლა. მავნე აპებმა შეიძლება გამოიყენონ მნიშვნელოვანი აპების წასაშლელად."</string>
+    <string name="permlab_clearAppUserData" msgid="274109191845842756">"სხვა აპების მონაცემების წაშლა"</string>
+    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"აპს შეეძლება მომხმარებლის მონაცემების წაშლა."</string>
+    <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"სხვა აპების ქეშის წაშლა"</string>
+    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"აპს შეეძლება ქეშის ფაილების წაშლა."</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"აპის მეხსიერების სივრცის გაზომვა"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"აპს შეეძლება, მოიპოვოს თავისი კოდი, მონაცემები და ქეშის ზომები."</string>
+    <string name="permlab_installPackages" msgid="2199128482820306924">"აპების პირდაპირი ინსტალაცია"</string>
+    <string name="permdesc_installPackages" msgid="5628530972548071284">"აპს შეეძლება Android-ის ახალი ან განახლებული პაკეტების ინსტალაცია. მავნე აპებმა შესაძლოა ეს გამოიყენონ ახალი აპების დასამატებლად თვითნებურად, მნიშვნელოვანი უფლებებით."</string>
+    <string name="permlab_clearAppCache" msgid="7487279391723526815">"ყველა აპის მონაცემთა ქეშის წაშლა"</string>
+    <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"აპს შეეძლება, გაასუფთავოს ტაბლეტის მეხსიერება სხვა აპლიკაციების ქეშის საქაღალდეებში ფაილების წაშლით. ამან შეიძლება გამოიწვიოს სხვა აპლიკაციების უფრო ნელი გაშვება, რადგანაც მათ მონაცემების ხელახლა პოვნა სჭირდებათ."</string>
+    <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"აპს შეეძლება, გაასუფთავოს ტელეფონის მეხსიერება სხვა აპლიკაციების ქეშის საქაღალდეებში ფაილების წაშლით. ამან შეიძლება გამოიწვიოს სხვა აპლიკაციების უფრო ნელი გაშვება, რადგანაც მათ მონაცემების ხელახლა პოვნა სჭირდებათ."</string>
+    <string name="permlab_movePackage" msgid="3289890271645921411">"აპის რესურსების გადატანა"</string>
+    <string name="permdesc_movePackage" msgid="319562217778244524">"აპს შეეძლება აპების რესურსსების გადატანა გარედან შიდა მეხსიერებაზე და პირიქით."</string>
+    <string name="permlab_readLogs" msgid="6615778543198967614">"ჟურნალის სენსიტიური მონაცემების წაკითხვა"</string>
+    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"აპს შეეძლება სისტემის სხვადასხვა ჟურნალის ფაილების წაკითხვა. ეს უფლებას აძლევს, გაიგოს ზოგადი ინფორმაცია იმის შესახებ, თუ რას აკეთებთ ტაბლეტზე და, პოტენციურად, პირადი ან კონფიდენციალური ინფორმაციაც."</string>
+    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"აპს შეეძლება სისტემის სხვადასხვა ჟურნალის ფაილების წაკითხვა. ეს უფლებას აძლევს, გაიგოს ზოგადი ინფორმაცია იმის შესახებ, თუ რას აკეთებთ ტელეფონზე და, პოტენციურად, პირადი ან კონფიდენციალური ინფორმაციაც."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"ნებისმიერი მედია დეკოდერის გამოყენება"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"აპს დასაკრავად შეეძლება გამოიყენოს ნებისმიერი დაყენებული მედია დეკოდერი."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"სანდო მტკიცებულებების მართვა"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"აპისთვის ნების დართვა, მოახდინოს CA სერტიფიკატების სანდო მტკიცებულებებად ინსტალაცია და დეინსტალაცია."</string>
+    <string name="permlab_diagnostic" msgid="8076743953908000342">"სისტემის დიაგნოსტიკის რესურსებში წაკითხვა/ჩაწერის უფლება"</string>
+    <string name="permdesc_diagnostic" msgid="6608295692002452283">"აპს შეეძლება, წაიკითხოს ან ჩაწეროს ნებისმიერ რესურსში, რომელიც დიაგნოსტიკის ჯგუფს ეკუთვნის, მაგალითად, ფაილები /dev-ში. ამან შესაძლოა იმოქმედოს სისტემის სტაბილურობასა და უსაფრთხოებაზე. მისი გამოყენება მხოლოდ მწარმოებლის ან ოპერატორის მიერ ტექნიკის სპეციფიკური დიაგნოსტიკისთვის უნდა მოხდეს."</string>
+    <string name="permlab_changeComponentState" msgid="6335576775711095931">"აპის კომპონენტების ჩართვა ან გამორთვა"</string>
+    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"აპებს საშუალებას აძლევს, შეცვალონ სხვა აპების კომპონენტები. ამ გზით მავნე აპები შეძლებენ ტაბლეტის მნიშვნელვანი ფუნქციების გათიშვას. ეს ნებართვა სიფრთხილით გამოიყენეთ, რათა შემთხვევით არ დაარღვიოთ აპლიკაციის კომპონენტების მუშაობა."</string>
+    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"აპებს საშუალებას აძლევს, შეცვალონ სხვა აპების კომპონენტები. ამ გზით მავნე აპები შეძლებენ ტელეფონის მნიშვნელვანი ფუნქციების გათიშვას. ეს ნებართვა სიფრთხილით გამოიყენეთ, რათა შემთხვევით არ დაარღვიოთ აპლიკაციის კომპონენტების მუშაობა."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"ნებართვების მიცემა ან გაუქმება"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"აპლიკაციას შეეძლება, გასცეს ან გააუქმოს განსაკუთრებული ნებართვები მისთვის ან სხვა აპლიკაციებისთვის. მავნე აპლიკაციებმა შეიძლება გამოიყენონ იმ თვისებებზე წვდომისთვის, რომლებიც მათ არ მიანიჭეთ."</string>
+    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"სასურველი აპების დაყენება"</string>
+    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"აპს შეეძლება შეცვალოს თქვენი სასურველი აპები. მავნე აპებმა ეს შესაძლოა გამოიყენონ თქვენ მიერ მოხმარებადი აპების ჩუმად შესაცვლელად, თქვენგან პირადი ინფორმაციის მოსაგროვებლად."</string>
+    <string name="permlab_writeSettings" msgid="2226195290955224730">"სისტემის პარამეტრების შეცვლა"</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"აპს შეეძლება, შეცვალოს სისტემის პარამეტრების მონაცემები. მავნე აპებს შეუძლიათ დააზიანონ თქვენი სისტემის კონფიგურაცია."</string>
+    <string name="permlab_writeSecureSettings" msgid="204676251876718288">"სისტემის უზრუნველყოფის პარამეტრების შეცვლა"</string>
+    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"აპს შეეძლება სისტემის უსაფრთხოების პარამეტრების მონაცემების შეცვლა. ამ შესაძლებლობას ჩვეულებრივი აპების არასოდეს იყენებენ."</string>
+    <string name="permlab_writeGservices" msgid="2149426664226152185">"Google სერვისების რუკის შეცვლა"</string>
+    <string name="permdesc_writeGservices" msgid="1287309437638380229">"აპს შეეძლება Google სერვისების რუკის შეცვლა. არ გამოიყენება ჩვეულებრივ აპლიკაციებში."</string>
+    <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"გაშვება სისტემის ჩართვისას"</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"აპს შეეძლება საკუთარი თავის სისტემის ჩატვირთვისას ჩართვა. ამან შეიძლება გამოიწვიოს ჩატვირთვის დროის გაზრდა და ტაბლეტის შენელება, რადგან აპი ყოველთვის ჩართული იქნება."</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="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="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="default" msgid="589869224625163558">"აპს შეეძლება, შეცვალოს თქვენ ტელეფონზე შენახული კონტაქტების მონაცემები, მათ შორის ინფორმაცია კონკრეტულ ინდივიდუალებთან თქვენი დარეკვის, ელფოსტის გაგზავნის ან კომუნიკაციის სიხშირის შესახებ. ეს ნებართვა უფლებას აძლევს აპებს, წაშალოს საკონტაქტო მონაცემები. "</string>
+    <string name="permlab_readCallLog" msgid="3478133184624102739">"ზარების ჟურნალის წაკითხვა"</string>
+    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"აპს შეეძლება თქვენი ტაბლეტის გამავალი და შემომავალი ზარების ჟურნალის ნახვა, ასევე ექნება ამ ჟურნალის შენახვის უფლება. ეს მავნე აპლიკაციებს საშუალებას მისცემს ნებართვის გარეშე გააზიარონ თქვენი ზარების ჟურნალი."</string>
+    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"აპს შეეძლება თქვენი ტელეფონის გამავალი და შემომავალი ზარების ჟურნალის ნახვა, ასევე ექნება ამ ჟურნალის შენახვის უფლება. ეს მავნე აპლიკაციებს საშუალებას მისცემს ნებართვის გარეშე გააზიარონ თქვენი ზარების ჟურნალი."</string>
+    <string name="permlab_writeCallLog" msgid="8552045664743499354">"ზარების ჟურნალში ჩაწერა"</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"აპს შეეძლება, შეცვალოს თქვენი ტაბლეტის ზარების ჟურნალი, მათ შორის შემომავალი და გამავალი ზარების მონაცემები. მავნე აპებმა შეიძლება გამოიყენონ ეს თქვენი ზარების ჟურნალის წასაშლელად ან შესაცვლელად."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"აპს შეეძლება, შეცვალოს თქვენი ტელეფონის ზარების ჟურნალი, მათ შორის შემომავალი და გამავალი ზარების მონაცემები. მავნე აპებმა შეიძლება გამოიყენონ ეს თქვენი ზარების ჟურნალის წასაშლელად ან შესაცვლელად."</string>
+    <string name="permlab_readProfile" msgid="4701889852612716678">"თქვენი საკონტაქტო ინფორმაციის ნახვა"</string>
+    <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"აპს შეეძლება მოწყობილობაზე შენახული პირადი პროფილის ინფორმაციის წაკითხვა, მაგალითად, თქვენი სახელისა და საკონტაქტო ინფორმაციის. ეს ნიშნავს, რომ აპს შეუძლია თქვენი იდენტიფიცირება და თქვენი პირადი ინფორმაციის სხვებისთვის გაგზავნა."</string>
+    <string name="permlab_writeProfile" msgid="907793628777397643">"თქვენი საკონტაქტო ინფორმაციის შეცვლა"</string>
+    <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"აპს შეეძლება მოწყობილობაზე შენახული პირადი პროფილის ინფორმაციის შეცვლა ან დამატება, მაგალითად, თქვენი სახელისა და საკონტაქტო ინფორმაციის. ეს ნიშნავს, რომ აპს შეუძლია თქვენი იდენტიფიცირება და თქვენი პირადი ინფორმაციის სხვებისთვის გაგზავნა."</string>
+    <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"სოციალური ნაკადის წაკითხვა"</string>
+    <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"აპს შეეძლება თქვენი და თქვენი მეგობრების სოციალური განახლებებთან წვდომა და სინქრონიზაცია. ინფორმაციის გაზიარებისას იყავით ფრთხიად - აპს ექნება შესაძლებლობა, რომ წაიკითხოს სოციალურ ქსელებში კომუნიკაცია თქვენსა და თქვენს მეგობრებს შორის კონფიდენციალურობის მიუხედავად. შენიშვნა: ეს უფლება შესაძლოა ვერ იყოს გამოყენებული ყველა სოციალურ ქსელში."</string>
+    <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"თქვენს სოციალურ მაუწყებლობაზე დაწერა"</string>
+    <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"აპს შეეძლება, გიჩვენოთ თქვენი მეგობრების სოციალური სიახლეები. ფრთხილად იყავით ინფორმაციის გაზიარებისას - აპს შეუძლია შექმნას შეტყობინება, რომელიც თითქოსდა მეგობრისგან არის მოწერილი. შენიშვნა: ეს ნებართვა არ შეიძლება შესრულდეს ყველა სოციალურ ქსელში."</string>
+    <string name="permlab_readCalendar" msgid="5972727560257612398">"კალენდრის ღონისძიებებისა და კონფიდენციალური ინფორმაციის წაკითხვა"</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"აპს შეეძლება, წაიკითხოს თქვენ ტაბლეტზე შენახული კალენდრის ყველა მოვლენა, მათ შორის მეგობრებისა და თანამშრომლების მოვლენებიც. ამან შეიძლება უფლება მისცეს აპს, გააზიაროს ან შეინახოს თქვენი კალენდრის მონაცემები, მიუხედავად კონფიდენციალურობისა თუ მგრძობიარობისა."</string>
+    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"აპს შეეძლება, წაიკითხოს თქვენს ტელეფონზე შენახული კალენდრის ყველა მოვლენა, მათ შორის მეგობრებისა და თანამშრომლების მოვლენებიც. ამან შეიძლება უფლება მისცეს აპს, გააზიაროს ან შეინახოს თქვენი კალენდრის მონაცემები, მიუხედავად კონფიდენციალურობისა თუ მგრძობიარობისა."</string>
+    <string name="permlab_writeCalendar" msgid="8438874755193825647">"კალენდრის ღონისძიებების დამატება და შეცვლა და მფლობელის გარეშე ელფოსტის გაგზავნა სტუმრებთან."</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"აპს შეეძლება იმ ღონისძიებების დამატება, წაშლა და შეცვლა, რომლებსაც თქვენს ტაბლეტზე ქმნით, ასევე თქვენი მეგობრების და თანამშრომლების ღონისძიებებიც. ამგვარად, აპს ექნება შესაძლებლობა ისე დააგზავნოს შეტყობინებები კალენდრის მფლობელის სახელით ან შეცვალოს ღონისძიებები, რომ მფლობელმა ამის შესახებ არაფერი იცოდეს."</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"აპს შეეძლება იმ ღონისძიებების დამატება, წაშლა და შეცვლა, რომლებსაც თქვენს ტელეფონზე ქმნით, ასევე თქვენი მეგობრების და თანამშრომლების ღონისძიებებიც. ამგვარად, აპს ექნება შესაძლებლობა ისე დააგზავნოს შეტყობინებები კალენდრის მფლობელის სახელით ან შეცვალოს ღონისძიებები, რომ მფლობელმა ამის შესახებ არაფერი იცოდეს."</string>
+    <string name="permlab_accessMockLocation" msgid="8688334974036823330">"მდებარეობის წყაროების იმიტირება ტესტირებისთვის"</string>
+    <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"აპს შეეძლება ტესტირებისთვის ყალბი ლოკაციების შექმნა, ან მდებარეობის ახალი პროვაიდერის დაყენება. ეს უფლებას მისცემს აპს, შეცვალოს მდებარეობის სხვა წყაროების მიერ, მაგ. GPS  ან მდებარეობის პროვაიდერების მიერ მოწოდებული მდებარეობა და/ ან სტატუსი."</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"მდებარეობის პროვაიდერის დამატებით ბრძანებებზე წვდომა"</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"აპს შეეძლება წვდომა ჰქონდეს მდებარეობის სერვისის დამატებით ბრძანებებზე. შესაძლოა აპმა ეს გამოიყენოს GPS-ისა და მდებარეობის სხვა წყაროების მუშაობის პროცესში ჩარევისთვის."</string>
+    <string name="permlab_installLocationProvider" msgid="6578101199825193873">"მდებარეობის პროვაიდერის ინსტალაციის უფლება"</string>
+    <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"აპს შეეძლება ტესტირებისთვის ყალბი ლოკაციების შექმნა, ან მდებარეობის ახალი პროვაიდერის დაყენება. აპს საშუალება მიეცემა გადააკეთოს სხვა წყაროების მაგ.: GPS ან მდებარეობის პროვაიდერების მოწოდებული მდებარეობა ან/და სტატუსი."</string>
+    <string name="permlab_accessFineLocation" msgid="1191898061965273372">"ზუსტი მდებარეობა (GPS და ქსელის კოორდინატების მიხედვით)"</string>
+    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"აძლევს აპს უფლებას მოიპოვოს ზუსტი მდებარეობა გლობალური პოზიციონირების სისტემის (GPS) გამოყენებით ან ქსელის მდებარეობის წყაროს მიხედვით, როგორიცაა ქსელის ანძები და Wi-Fi. მდებარეობის ეს სერვისები ჩართული უნდა იყოს და თქვენს მოწყობილობაზე აპისთვის მისაწვდომი, რათა შეძლოს მათი გამოყენება. აპებში შესაძლებელია მათი გამოყენება თქვენი მდებარეობის განსასაზღვრად და ამან ელემენტის დამატებითი ხარჯვა შეიძლება გამოიწვიოს."</string>
+    <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"სავარაუდო (ქსელის კოორდინატების მიხედვით) მდებარეობა"</string>
+    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"აპს შეეძლება გაიგოს თქვენი სავარაუდო მდებარეობა. ის გამოითვლება მდებარეობის სერვისის მიერ ქსელის მონაცემების - მობილური კავშირგაბმულობის ანძებისა და Wi-Fi-ის მიხედვით. ეს სერვისები ჩართული უნდა იყოს თქვენს მოწყობილობაზე, ხოლო აპებს უნდა ჰქონდეთ მათი გამოყენების უფლება. აპები მათი მონაცემების მიხედვით სავარაუდო მდებარეობის გამოთვლას შეძლებენ."</string>
+    <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"SurfaceFlinger-ზე წვდომა"</string>
+    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"აპს შეეძლება, გამოიყენოს SurfaceFlinger-ის დაბალი დონის ელემენტები."</string>
+    <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"კადრის ბუფერის (ეკრანის შიგთავსის) წაკითხვა"</string>
+    <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"აპს შეეძლება წაიკითხოს ბუფერული ჩარჩოს კონტენტი."</string>
+    <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Wifi ეკრანის კონფიგურაცია"</string>
+    <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"აპს შეეძლება Wifi ეკრანებთან დაკავშირება და დაკონფიგურირება."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wifi ეკრანების მართვა"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"აპს შეეძლება აკონტროლოს Wifi ეკრანების დაბალი დონის ფუნქციები."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"გამომავალი აუდიოს დაჭერა"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"საშუალებას აძლევს აპს დაიჭიროს და გადაამისამართოს გამომავალი აუდიო."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"გამომავალი ვიდეოს დაჭერა"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"საშუალებას აძლევს აპს დაიჭიროს და გადაამისამართოს გამომავალი ვიდეო."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"გამომავალი დაცული ვიდეოს დაჭერა"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"საშუალებას აძლევს აპს დაიჭიროს და გადაამისამართოს გამომავალი დაცული ვიდეო."</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="4906839301087980680">"აპს შეეძლება აუდიო ჩაწერა მიკროფონით. ნებართვა აპს აუდიო ჩაწერის უფლებას აძლევს ნებისმიერ დროს, თქვენი თანხმობის გარეშე."</string>
+    <string name="permlab_camera" msgid="3616391919559751192">"სურათებისა და ვიდეოების გადაღება"</string>
+    <string name="permdesc_camera" msgid="8497216524735535009">"აპს შეეძლება კამერით სურათისა და ვიდეოს გადაღება. ეს ნებართვა აპს უფლებას აძლევს, ნებისმიერ დროს გამოიყენოს კამერა თქვენი დადასტურების გარეშე."</string>
+    <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"კამერის გამოყენებისას გადამცემი ინდიკატორის LED გათიშვა"</string>
+    <string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"ნებას რთავს წინასწარ დაყენებული სისტემის აპლიკაციას, გამორთოს კამერის გამოყენების ინდიკატორი LED."</string>
+    <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"მუდმივად გამორთული ტაბლეტი"</string>
+    <string name="permlab_brick" product="default" msgid="8337817093326370537">"ტელეფონის სამუდამოდ დეაქტივაცია"</string>
+    <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"აპს შეეძლება მთელი ტაბლეტის სამუდამოდ გათიშვა. ეს ძალიან სახიფათოა."</string>
+    <string name="permdesc_brick" product="default" msgid="5788903297627283099">"აპს შეეძლება მთელი ტელეფონის სამუდამოდ გათიშვა. ეს ძალიან სახიფათოა."</string>
+    <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"ტაბლეტის გადატვირთვის იძულება"</string>
+    <string name="permlab_reboot" product="default" msgid="2898560872462638242">"ტელეფონის გადატვირთვის იძულება"</string>
+    <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"აპს შეეძლება ტაბლეტის იძულებითი გადატვირთვა."</string>
+    <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"აპს შეეძლება მოწყობილობის იძულებითი გადატვირთვა."</string>
+    <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"UBS ბარათის ფაილურ სისტემაზე წვდომა"</string>
+    <string name="permlab_mount_unmount_filesystems" product="default" msgid="4402305049890953810">"SD ბარათის ფაილურ სისტემაზე წვდომა"</string>
+    <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"აპს შეეძლება, მიუერთოს და გამოაერთოს ფაილების სისტემები მოსახსნელი მეხსიერებისთვის."</string>
+    <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"USB მეხსიერების წაშლა"</string>
+    <string name="permlab_mount_format_filesystems" product="default" msgid="262582698639274056">"SD ბარათის წაშლა"</string>
+    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"აპს შეეძლება, დააფორმატოს მოსახსნელი მეხსიერება."</string>
+    <string name="permlab_asec_access" msgid="3411338632002193846">"შიდა მეხსიერების შესახებ ინფორმაციის მიღება"</string>
+    <string name="permdesc_asec_access" msgid="3094563844593878548">"აპს შეეძლება, მიიღოს ინფორმაცია შიდა მეხსიერებაზე."</string>
+    <string name="permlab_asec_create" msgid="6414757234789336327">"შიდა მეხსიერების შექმნა"</string>
+    <string name="permdesc_asec_create" msgid="4558869273585856876">"აპს შეეძლება მეხსიერების შიდა საცავის შექმნა."</string>
+    <string name="permlab_asec_destroy" msgid="526928328301618022">"შიდა მეხსიერების განადგურება"</string>
+    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"აპს შეეძლება შიდა მეხსიერების განადგურება."</string>
+    <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"შიდა მეხსიერების მიერთება/გამოერთება"</string>
+    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"აპს შეეძლება შიდა მეხსიერების მიერთება / გამოერთება."</string>
+    <string name="permlab_asec_rename" msgid="7496633954080472417">"შიდა მეხსიერებისთვის სახელის გადარქმევა"</string>
+    <string name="permdesc_asec_rename" msgid="1794757588472127675">"აპს შეეძლება შიდა მეხსიერებისთვის სახელის გადარქმევა."</string>
+    <string name="permlab_vibrate" msgid="7696427026057705834">"ვიბრაციის კონტროლი"</string>
+    <string name="permdesc_vibrate" msgid="6284989245902300945">"აპს შეეძლება, მართოს ვიბრირება."</string>
+    <string name="permlab_flashlight" msgid="2155920810121984215">"ფანრის მართვა"</string>
+    <string name="permdesc_flashlight" msgid="6522284794568368310">"აპს შეეძლება, მართოს განათება."</string>
+    <string name="permlab_manageUsb" msgid="1113453430645402723">"USB მოწყობილობების უფლებებისა და სასურველი პარამეტრების მართვა"</string>
+    <string name="permdesc_manageUsb" msgid="7776155430218239833">"აპს შეეძლება USB მოწყობილობების პარამეტრებისა და ნებართვების მართვა."</string>
+    <string name="permlab_accessMtp" msgid="4953468676795917042">"MTP პროტოკოლის დანერგვა"</string>
+    <string name="permdesc_accessMtp" msgid="6532961200486791570">"ანიჭებს წვდომას kernel MTP დრაივერს MTP USB პროტოკოლის იმპლემენტაციისთვის."</string>
+    <string name="permlab_hardware_test" msgid="4148290860400659146">"აპარატურული აღჭურვილობის ტესტირება"</string>
+    <string name="permdesc_hardware_test" msgid="6597964191208016605">"აპს შეეძლება, მართოს სხვადასხვა პერიფერიული მოწყობილობა აპარატურის ტესტირების მიზნით."</string>
+    <string name="permlab_callPhone" msgid="3925836347681847954">"პირდაპირი დარეკვა ტელეფონის ნომრებზე"</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"აპს შეეძლება დარეკოს ტელეფონის ნომრებზე თქვენი ჩარევის გარეშე. ამან შესაძლოა გამოიწვიოს თქვენს სატელეფონი ქვითარზე მოულოდნელი ხარჯებისა და ზარების გაჩენა. გაითვალისწინეთ, რომ აპს გადაუდებელი დახმარების ნომრებზე დარეკვა არ შეუძლია. მავნე აპებს შეეძლება თქვენი დადასტურების გარეშე ზარების განხორციელება და შესაბამისი საფასურის გადახდაც მოგიწევთ."</string>
+    <string name="permlab_callPrivileged" msgid="4198349211108497879">"პირდაპირი დარეკვა ტელეფონის ნებისმიერ ნომერზე"</string>
+    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"აპს შეეძლება თქვენი მონაწილეობის გარეშე დარეკოს ნებისმიერ ტელეფონის ნომერზე, მათ შორის საგანგებო ნომრებზე. მავნე აპები შეძლებენ არასასურველი ან უკანონო ზარების საგანგებო სამსახურების სიებში განთავსებას."</string>
+    <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"CDMA ტაბლეტის დაყენების პირდაპირ დაწყება"</string>
+    <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"CDMA ტელეფონის დაყენების პირდაპირ დაწყება"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"აპს შეეძლება, დაიწყოს CDMA უზრუნველყოფა. მავნე აპებმა შეიძლება ზედმეტად, საჭიროების გარეშე დაიწყონ CDMA უზრუნველყოფა."</string>
+    <string name="permlab_locationUpdates" msgid="7785408253364335740">"მდებარეობის განახლების შეტყობინებების კონტროლი"</string>
+    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"აპს შეეძლება მდებარეობის განახლების შესახებ რადიო შეტყობინებების აქტივაცია/დეაქტივაცია. ჩვეულებრივი აპები ამ ფუნქციას არ იყენებენ."</string>
+    <string name="permlab_checkinProperties" msgid="7855259461268734914">"სარეგისტრაციო პარამეტრებზე წვდომა"</string>
+    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"აპებს შეეძლებათ რეგისტრაციის სამსახურის მეშვეობით დამატებული თვისებების წასაკითხად ან ჩასაწერად წვდომა. არ გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_bindGadget" msgid="776905339015863471">"ვიჯეტების არჩევა"</string>
+    <string name="permdesc_bindGadget" msgid="8261326938599049290">"აპს შეეძლება უთხრას სისტემას, თუ რომელმა აპმა რომელი ვიჯეტი შეიძლება გამოიყენოს. ამ ნებართვის მქონე აპს შეუძლია, პირად მონაცემებზე წვდომა მისცეს სხვა აპებს. არ გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"ტელეფონის მდგომარეობის შეცვლა"</string>
+    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"აპს შეეძლება აკონტროლოს მოწყობილობაზე ტელეფონის ფუნქციები. ამ უფლების მქონე აპს შეუძლია ქსელების გადართვა, ტელეფონის რადიოს ჩართვა და გამორთვა, მომხმარებლისათვის შეტყობინების გარეშე."</string>
+    <string name="permlab_readPhoneState" msgid="9178228524507610486">"ტელეფონის სტატუსისა და იდენტობის წაკითხვა"</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"აპს შეეძლება ჰქონდეს წვდომა მოწყობილობის სატელეფონო ფუნქციებზე. აპმა მსგავსი უფლებით შეძლებს დაადგინოს ტელეფონის ნომერი, მისი სერიული გამოცემა, აქტიური ზარი, დაკავშირებული ნომერი და მსგავსი."</string>
+    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"დაიცავით ტაბლეტი დაძინებისგან"</string>
+    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"ტელეფონის ძილის რეჟიმში გადასვლის აღკვეთა"</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"აპს შეეძლება ხელი შეუშალოს ტაბლეტის დაძინებას."</string>
+    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"აპს შეეძლება ხელი შეუშალოს ტელეფონის დაძინებას."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
+    <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"ტაბლეტის ჩართვა ან გამორთვა"</string>
+    <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"ტელეფონის ჩართვა ან გამორთვა"</string>
+    <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"აპს შეეძლება, ჩართოს ან გამორთოს ტაბლეტი."</string>
+    <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"აპს შეეძლება, ჩართოს ან გამორთოს ტელეფონი."</string>
+    <string name="permlab_factoryTest" msgid="3715225492696416187">"ქარხნულ სატესტო რეჟიმში გაშვება"</string>
+    <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"მწარმოებლის დაბალი დონის ტესტის რეჟიმში გაშვება, რომლის დროსაც სრულად არის ხელმისაწვდომი ტაბლეტის აპარატული უზრუნველყოფა. ხელმისაწვდომია მხოლოდ მწარმოებლის ტესტის რეჟიმში ჩართულ ტაბლეტზე."</string>
+    <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"მწარმოებლის დაბალი დონის ტესტის რეჟიმში გაშვება, რომლის დროსაც სრულად არის ხელმისაწვდომი ტელეფონის აპარატული უზრუნველყოფა. ხელმისაწვდომია მხოლოდ მწარმოებლის ტესტის რეჟიმში ჩართულ ტელეფონზე."</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_masterClear" msgid="2315750423139697397">"სისტემის დაბრუნება ქარხნულ ნაგულისხმევ მდგომარეობაში"</string>
+    <string name="permdesc_masterClear" msgid="3665380492633910226">"აპს შეეძლება, სისტემა სრულად გადაყენოს ქარხნულ პარამეტრებზე და წაშალოს ყველა მონაცემი, კონფიგურაცია და დაყენებული აპები."</string>
+    <string name="permlab_setTime" msgid="2021614829591775646">"დროის დაყენება"</string>
+    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"აპს შეეძლება ტაბლეტის საათის დროის შეცვლა."</string>
+    <string name="permdesc_setTime" product="default" msgid="1855702730738020">"აპს შეეძლება ტელეფონის საათის დროის შეცვლა."</string>
+    <string name="permlab_setTimeZone" msgid="2945079801013077340">"დროის სარტყლის დაყენება"</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"აპს შეეძლება, შეცვალოს ტაბლეტის დროის სარტყელი."</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"აპს შეეძლება ტელეფონის დროის სარტყელის შეცვლა."</string>
+    <string name="permlab_accountManagerService" msgid="4829262349691386986">"იმოქმედეთ როგორც AccountManagerService"</string>
+    <string name="permdesc_accountManagerService" msgid="1948455552333615954">"აპს შეეძლება განახორციელოს ზარები AccountAuthenticators-ზე."</string>
+    <string name="permlab_getAccounts" msgid="1086795467760122114">"მოწყობილობაზე ანგარიშების მოძიება"</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"აპს შეეძლება, მიიღოს ტაბლეტისთვის ცნობილი ანგარიშების სია. ეს შეიძლება მოიცავდეს ნებისმიერ ანგარიშს, რომელიც თქვენ მიერ დაყენებული აპლიკაციებით შეიქმნა."</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"აპს შეეძლება, მიიღოს ტელეფონისთვის ცნობილი ანგარიშების სია. ეს შეიძლება მოიცავდეს ნებისმიერ ანგარიშს, რომელიც თქვენ მიერ დაყენებული აპლიკაციებით შეიქმნა."</string>
+    <string name="permlab_authenticateAccounts" msgid="5265908481172736933">"ანგარიშების შექმნა და პაროლების დაყენება"</string>
+    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"აპს შეეძლება ანგარიშების მენეჯერის ავტორიზაციის შესაძლებლობების გამოყენება. მათ შორის ანგარიშების შექმნა და მათთვის პაროლების მიღება და დაყენება."</string>
+    <string name="permlab_manageAccounts" msgid="4983126304757177305">"ანგარიშების დამატება ან წაშლა"</string>
+    <string name="permdesc_manageAccounts" msgid="8698295625488292506">"აპს შეეძლება ისეთი ოპერაციების განხორციელება, როგორიცაა ანგარიშების დამატება და წაშლა, ასევე მათი პაროლების წაშლაც."</string>
+    <string name="permlab_useCredentials" msgid="235481396163877642">"მოწყობილობაზე ანგარიშების გამოყენება"</string>
+    <string name="permdesc_useCredentials" msgid="7984227147403346422">"აპს შეეძლება, მოითხოვოს ავტორიზაციის საიდენტიფიკაციო ნიშნები."</string>
+    <string name="permlab_accessNetworkState" msgid="4951027964348974773">"ქსელის კავშირების ნახვა"</string>
+    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"აპს შეეძლება ქსელის კავშირის შესახებ ინფორმაციის ნახვა, მაგ. რომელი ქსელები არსებობს და რომელია დაკავშირებული."</string>
+    <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"ქსელზე სრული წვდომა"</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"აპს შეეძლება შექმნას ქსელური ბუდეები და გამოიყენოს მორგებული ქსელის პროტოკოლები. ბრაუზერი და სხვა აპლიკაციები უზრუნველყოფს ინტერნეტში მონაცემების გაგზავნის საშუალებას, ამგვარად ეს უფლება ინფორმაციის გასაგზავნად საჭირო არაა."</string>
+    <string name="permlab_writeApnSettings" msgid="505660159675751896">"ქსელის პარამეტრებისა და ტრაფიკის შეცვლა / შეწყვეტა"</string>
+    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"აპს შეეძლება ქსელის პარამეტრების შეცვლა, მთელი ქსელის ტრაფიკის შეწყვეტა და ინსპექტირება, მაგალითად, ნებისმიერი APN-ის პორტისა და პროქსის შეცვლა. მავნე აპებს შეეძლებათ ქსელის პაკეტების მონიტორინგი, გადამისამართება ან შეცვლა თქვენთვის შეტყობინების გარეშე."</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_changeBackgroundDataSetting" msgid="1400666012671648741">"ფონური მონაცემების გამოყენების პარამეტრების შეცვლა"</string>
+    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"აპს შეეძლება, შეცვალოს უკანა ფონის მონაცემების გამოყენების პარამეტრები."</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="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="default" msgid="8931682159331542137">"აპს შეეძლება ტელეფონის ადგილობრივი Bluetooth პარამეტრების დაყენება და დისტანციური მოწყობილობების აღმოჩენა და დაწყვილება."</string>
+    <string name="permlab_accessWimaxState" msgid="4195907010610205703">"WiMAX-თან დაკავშირება და კავშირის გაწყვეტა"</string>
+    <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"აპს შეეძლება განსაზღვროს, WiMAX არის თუ არა ჩართული და ასევე ინფორმაცია ნებისმიერი დაკავშირებული WiMAX ქსელის შესახებ."</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"WiMAX მდგომარეობის შეცვლა"</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"აპს შეეძლება, დაუკავშიროს და გამოაერთოს ტაბლეტი 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="default" msgid="3207106324452312739">"აპს შეეძლება, ნახოს Bluetooth-ის კონფიგურაცია ტელეფონზე და შექმნას და მიიღოს კავშირები დაწყვილებულ მოწყობილობებთან."</string>
+    <string name="permlab_nfc" msgid="4423351274757876953">"ახლო მოქმედების რადიოკავშირი (NFC) მართვა"</string>
+    <string name="permdesc_nfc" msgid="7120611819401789907">"აპს შეეძლება ახლო მოქმედების რადიოკავშირის (NFC) მეშვეობით ტეგების, ბარათებისა და წამკითხველების შემცველი მონაცემების მიმოცვლა."</string>
+    <string name="permlab_disableKeyguard" msgid="3598496301486439258">"თქვენი ეკრანის ბლოკის გათიშვა"</string>
+    <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"შეეძლება კლავიატურის დაბლოკვისა და პაროლით უზრუნველყოფილი ნებისმიერი უსაფრთხოების ფუნქციის დეაქტივაცია. მაგალითად, ტელეფონი შემომავალი ზარის დროს აუქმებს კლავიატურის დაბლოკვას და კვლავ ააქტიურებს მას, როგორც კი ზარი დასრულდება."</string>
+    <string name="permlab_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="permlab_readSyncStats" msgid="7396577451360202448">"სინქრონიზაციის სტატისტიკების წაკითხვა"</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"აპს შეეძლება ანგარიშის სინქრონიზაციის სტატისტიკის, მათ შორის სინქრონიზაციის მოვლენების ისტორიისა და სინქრონიზაციისას გადაცემული მონაცემების რაოდენობის წაკითხვა."</string>
+    <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"გამოწერილი არხების წაკითხვა"</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"აპს შეეძლება ინფორმაციის მოპოვება ბოლოს სინქრონიზებული არხების შესახებ."</string>
+    <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"გამოწერილი არხების შეცვლა"</string>
+    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"აპს შეეძლება თქვენი ამჟამინდელი სინქრონიზებული არხების შეცვლა. მავნე აპებმა შესაძოა შეცვალონ თქვენი სინქრონიზებული არხები."</string>
+    <string name="permlab_readDictionary" msgid="4107101525746035718">"ლექსიკონში თქვენი დამატებული ტერმინების ნახვა"</string>
+    <string name="permdesc_readDictionary" msgid="659614600338904243">"აპს შეეძლება წაიკითხოს ყველა სიტყვა, სახელი და ფრაზა, რომელიც შეიძლება მომხმარებელმა შეიტანა მომხმარებლის ლექსიკონში."</string>
+    <string name="permlab_writeDictionary" msgid="2183110402314441106">"მომხმარებლისთვის განკუთვნილ ლექსიკონში სიტყვების დამატება."</string>
+    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"აპს შეეძლება ახალი სიტყვების დამატება მომხმარებლის ლექსიკონში."</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"დაცულ მეხსიერებაზე საცდელი წვდომა"</string>
+    <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"დაცულ მეხსიერებაზე საცდელი წვდომა"</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"აპს შეეძლება, მიაწოდოს USB მეხსიერებას ნებართვა, რომლებიც შემდგომ სხვა მოწყობილობებზეც იქნება ხელმისაწვდომი."</string>
+    <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"აპს შეეძლება 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_mediaStorageWrite" product="default" msgid="6859839199706879015">"შიდა მედია მეხსიერების კონტენტის შეცვლა/წაშლა"</string>
+    <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"აპლიკაციას შეეძლება შიდა მედია მეხსიერების კონტენტის შეცვლა."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"დოკუმენტების საცავის მართვა"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"აპს შეეძლება დოკუმენტების საცავის მართვა."</string>
+    <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"ყველა მომხმარებლის გარე მეხსიერებაზე წვდომა"</string>
+    <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"აპს შეეძლება ყველა მომხმარებლის გარე მეხსიერებასთან წვდომა."</string>
+    <string name="permlab_cache_filesystem" msgid="5656487264819669824">"ქეშის ფაილურ სისტემაზე წვდომა"</string>
+    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"აპებს აძლევს ქეშირებული სისტემური ფაილების წაკითხვისა და მათში ჩანაწერების გაკეთების საშუალებას."</string>
+    <string name="permlab_use_sip" msgid="5986952362795870502">"ინტერნეტ-ზარების წამოწყება/მიღება"</string>
+    <string name="permdesc_use_sip" msgid="4717632000062674294">"აპს შეეძლება, გამოიყენოს SIP სერვისი ინტერნეტ ზარების განსახორციელებლად / საპასუხოდ."</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_markNetworkSocket" msgid="3658527214914959749">"სოკეტის ნიშნების შეცვლა"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"საშუალებას აძლევს აპს შეცვალოს მარშრუტიზაციის სოკეტის ნიშნები"</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_invokeCarrierSetup" msgid="3699600833975117478">"ოპერატორის მიერ მოწოდებული კოფიგურაციის აპის გამოხმობა"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"საშუალებას აძლევს მფლობელს გამოიწვიოს ოპერატორის მიერ მოწოდებული კონფიგურაციის აპი. ჩვეულებრივ აპს ეს წესით არასოდეს არ უნდა დაჭირდეს."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"განხორციელდეს ქსელის მდგომარეობის მონიტორინგი"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"საშუალებას აძლევს აპლიკაციებს განახორციელოს ქსელის მდგომარეობის მონიტორინგი. ეს ფუნქცია ჩვეულებრივ აპებს არ ჭირდება."</string>
+    <string name="policylab_limitPassword" msgid="4497420728857585791">"პაროლის წესების დაყენება"</string>
+    <string name="policydesc_limitPassword" msgid="3252114203919510394">"გააკონტროლეთ ეკრანის განბლოკვის პაროლში დაშვებული სიმბოლოები და მისი სიგრძე."</string>
+    <string name="policylab_watchLogin" msgid="914130646942199503">"ეკრანის განბლოკვის მცდელობების გაკონტროლება"</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"ეკრანის განბლოკვისთვის არასწორად აკრეფილი პაროლების რაოდენობის მონიტორინგი. ტაბლეტის დაბლოკვა ან მასზე არსებული ყველა მონაცემის წაშლა ძალიან ბევრჯერ არასწორი პაროლის შეყვანის შემთხვევაში."</string>
+    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"ეკრანის განბლოკვისთვის არასწორად აკრეფილი პაროლების რაოდენობის მონიტორინგი. ტელეფონის დაბლოკვა ან მასზე არსებული ყველა მონაცემის წაშლა ძალიან ბევრჯერ არასწორი პაროლის შეყვანის შემთხვევაში."</string>
+    <string name="policylab_resetPassword" msgid="2620077191242688955">"ეკრანის განბლოკვის პაროლის შეცვლა"</string>
+    <string name="policydesc_resetPassword" msgid="605963962301904458">"შეცვალეთ ეკრანის განბლოკვის პაროლი."</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="default" msgid="5096895604574188391">"ტელეფონის მონაცემების გაუფრთხილებლად წაშლა, ქარხნული მონაცემების აღდგენით"</string>
+    <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"მოწყობილობის გლობალური პროქსის დაყენება"</string>
+    <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"დააყენეთ მოწყობილობა გლობალურ პროქსის სერვერის გამოსაყენებლად, როდესაც დებულება გააქტიურებულია. მხოლოდ მოწყობილობის პირველი ადმინი აყენებს ეფექტურ გლობალურ პროქსი სერვერს."</string>
+    <string name="policylab_expirePassword" msgid="885279151847254056">"ეკრანის პაროლის ვადის დაყენება"</string>
+    <string name="policydesc_expirePassword" msgid="1729725226314691591">"გააკონტროლეთ, თუ რამდენად ხშირად უნდა შეიცვალოს ეკრანის დაბლოკვის პაროლი."</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="policylab_disableKeyguardFeatures" msgid="266329104542638802">"დაბლოკვის ფუნქციების გათიშვა"</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="3467082272186534614">"დაბლოკვისას ზოგიერთი ფუნქციის გამოყენების თავიდან აცილება."</string>
+  <string-array name="phoneTypes">
+    <item msgid="8901098336658710359">"სახლი"</item>
+    <item msgid="869923650527136615">"მობილური"</item>
+    <item msgid="7897544654242874543">"სამსახური"</item>
+    <item msgid="1103601433382158155">"სამსახურის ფაქსი"</item>
+    <item msgid="1735177144948329370">"სახლის ფაქსი"</item>
+    <item msgid="603878674477207394">"პეიჯერი"</item>
+    <item msgid="1650824275177931637">"სხვა"</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>
+  </string-array>
+  <string-array name="postalAddressTypes">
+    <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="1359644565647383708">"სამსახური"</item>
+    <item msgid="7868549401053615677">"სხვა"</item>
+    <item msgid="3145118944639869809">"მორგებული"</item>
+  </string-array>
+  <string-array name="organizationTypes">
+    <item msgid="7546335612189115615">"სამსახური"</item>
+    <item msgid="4378074129049520373">"სხვა"</item>
+    <item msgid="3455047468583965104">"მორგებული"</item>
+  </string-array>
+  <string-array name="imProtocols">
+    <item msgid="8595261363518459565">"AIM"</item>
+    <item msgid="7390473628275490700">"Windows Live"</item>
+    <item msgid="7882877134931458217">"Yahoo"</item>
+    <item msgid="5035376313200585242">"Skype"</item>
+    <item msgid="7532363178459444943">"QQ"</item>
+    <item msgid="3713441034299660749">"Google Talk"</item>
+    <item msgid="2506857312718630823">"ICQ"</item>
+    <item msgid="1648797903785279353">"Jabber"</item>
+  </string-array>
+    <string name="phoneTypeCustom" msgid="1644738059053355820">"მორგებული"</string>
+    <string name="phoneTypeHome" msgid="2570923463033985887">"სახლი"</string>
+    <string name="phoneTypeMobile" msgid="6501463557754751037">"მობილური"</string>
+    <string name="phoneTypeWork" msgid="8863939667059911633">"სამსახური"</string>
+    <string name="phoneTypeFaxWork" msgid="3517792160008890912">"სამსახურის ფაქსი"</string>
+    <string name="phoneTypeFaxHome" msgid="2067265972322971467">"სახლის ფაქსი"</string>
+    <string name="phoneTypePager" msgid="7582359955394921732">"პეიჯერი"</string>
+    <string name="phoneTypeOther" msgid="1544425847868765990">"სხვა"</string>
+    <string name="phoneTypeCallback" msgid="2712175203065678206">"გადმოსარეკი"</string>
+    <string name="phoneTypeCar" msgid="8738360689616716982">"მანქანა"</string>
+    <string name="phoneTypeCompanyMain" msgid="540434356461478916">"კომპანიის ძირ. ნომერი"</string>
+    <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string>
+    <string name="phoneTypeMain" msgid="6766137010628326916">"მთავარი"</string>
+    <string name="phoneTypeOtherFax" msgid="8587657145072446565">"სხვა ფაქსი"</string>
+    <string name="phoneTypeRadio" msgid="4093738079908667513">"რადიო"</string>
+    <string name="phoneTypeTelex" msgid="3367879952476250512">"Telex"</string>
+    <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="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="eventTypeOther" msgid="7388178939010143077">"სხვა"</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="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="imTypeWork" msgid="1371489290242433090">"სამსახური"</string>
+    <string name="imTypeOther" msgid="5377007495735915478">"სხვა"</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>
+    <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
+    <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</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>
+    <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="relationTypeAssistant" msgid="6274334825195379076">"ასისტენტი"</string>
+    <string name="relationTypeBrother" msgid="8757913506784067713">"ძმა"</string>
+    <string name="relationTypeChild" msgid="1890746277276881626">"შვილი"</string>
+    <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"საოჯახო პარტნიორი"</string>
+    <string name="relationTypeFather" msgid="5228034687082050725">"მამა"</string>
+    <string name="relationTypeFriend" msgid="7313106762483391262">"მეგობარი"</string>
+    <string name="relationTypeManager" msgid="6365677861610137895">"მენეჯერი"</string>
+    <string name="relationTypeMother" msgid="4578571352962758304">"დედა"</string>
+    <string name="relationTypeParent" msgid="4755635567562925226">"მშობელი"</string>
+    <string name="relationTypePartner" msgid="7266490285120262781">"პარტნიორი"</string>
+    <string name="relationTypeReferredBy" msgid="101573059844135524">"რეკომენდატორი:"</string>
+    <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="sipAddressTypeHome" msgid="6093598181069359295">"სახლი"</string>
+    <string name="sipAddressTypeWork" msgid="6920725730797099047">"სამსახური"</string>
+    <string name="sipAddressTypeOther" msgid="4408436162950119849">"სხვა"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"აკრიფეთ PIN კოდი"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"დაბეჭდეთ PUK კოდი და ახალი PIN კოდი."</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK კოდი"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"ახალი PIN კოდი"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384">"შეეხეთ "<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">"განსაბლოკად აკრიფეთ PIN კოდი"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"არასწორი PIN კოდი."</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="8963839242565653192">"სერვისი არ არის."</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="5347633784401285225">"გადაუდებელი ზარი"</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="faceunlock_multiple_failures" msgid="754137583022792429">"სახის ამოცნობით განბლოკვის მცდელობამ დაშვებულ რაოდენობას გადააჭარბა"</string>
+    <string name="lockscreen_plugged_in" msgid="8057762828355572315">"დამუხტვა, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_charged" msgid="321635745684060624">"დამუხტულია"</string>
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_low_battery" msgid="1482873981919249740">"შეაერთეთ დამტენი."</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="default" msgid="2186920585695169078">"არ არის SIM ბარათი ტელეფონში."</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_transport_prev_description" msgid="201594905152746886">"წინა ჩანაწერი"</string>
+    <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"შემდეგი ჩანაწერი"</string>
+    <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"პაუზა"</string>
+    <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"დაკვრის ღილაკი"</string>
+    <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"შეწყვეტა"</string>
+    <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">"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">%d</xliff:g>-ჯერ დახატეთ განბლოკვის ნიმუში. \n\nსცადეთ ხელახლა <xliff:g id="NUMBER_1">%d</xliff:g> წამში."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"თქვენ არასწორად დაბეჭდეთ თქვენი პაროლი <xliff:g id="NUMBER_0">%d</xliff:g> ჯერ. \n\nხელახლა სცადეთ <xliff:g id="NUMBER_1">%d</xliff:g> წამში."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"თქვენ <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ არასწორად შეიყვანეთ PIN კოდი. \n\nსცადეთ ხელახლა <xliff:g id="NUMBER_1">%d</xliff:g> წამში."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"თქვენ არასწორად დახატეთ განბლოკვის ნიმუში <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%d</xliff:g> წარუმატებელი ცდის შემდეგ დაგჭირდებათ თქვენი ტაბლეტის განბლოკვა Google-ში შესვლით.\n\n გთხოვთ, ხელახლა სცადოთ <xliff:g id="NUMBER_2">%d</xliff:g> წამში."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"თქვენ არასწორად დახატეთ განბლოკვის ნიმუში <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%d</xliff:g> წარუმატებელი ცდის შემდეგ დაგჭირდებათ თქვენი ტელეფონის განბლოკვა Google-ში შესვლით.\n\n გთხოვთ, ხელახლა სცადოთ <xliff:g id="NUMBER_2">%d</xliff:g> წამში."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"თქვენ არასწორად სცადეთ ტაბლეტის განბლოკვა <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%d</xliff:g> წარუმატებელი ცდის შემდეგ ტაბლეტზე დაყენდება საწყისი, ქარხნული პარამეტრები და მომხმარებლის ყველა მონაცემი დაიკარგება."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"თქვენ არასწორად სცადეთ ტელეფონის განბლოკვა <xliff:g id="NUMBER_0">%d</xliff:g> ჯერ. კიდევ <xliff:g id="NUMBER_1">%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="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_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_checking_password" msgid="7114627351286933867">"შემოწმება..."</string>
+    <string name="lockscreen_unlock_label" msgid="737440483220667054">"განბლოკვა"</string>
+    <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"ხმების ჩართვა"</string>
+    <string name="lockscreen_sound_off_label" msgid="996822825154319026">"ხმის გამორთვა"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"ნიმუშის შექმნა დაწყებულია"</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"ნიმუში წაიშალა"</string>
+    <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"უჯრედი დაემატა."</string>
+    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"ნიმუშის შექმნა დასრულებულია"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. ვიჯეტი %2$d of %3$d."</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_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>
+    <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_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">"განბლოკვა Pin-ით."</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>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <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_line" msgid="5764267235026120888">"სტრიქონი"</string>
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
+    <string name="factorytest_failed" msgid="5410270329114212041">"წარმოების ტესტი ვერ განხორციელდა"</string>
+    <string name="factorytest_not_system" msgid="4435201656767276723">"აქტივობა FACTORY_TEST მხარდაჭერილია მხოლოდ იმ პაკეტებისთვის, რომლებიც მოთავსებულია /system/app."</string>
+    <string name="factorytest_no_action" msgid="872991874799998561">"ვერ მოიძებნა პაკეტი, რომელიც უზრუნველყოფს ქარხნულ ტესტ ქმედებას."</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="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>
+    <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
+    <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
+    <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
+    <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
+    <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">"ZIP კოდი"</string>
+    <string name="autofill_county" msgid="237073771020362891">"ქვეყანა"</string>
+    <string name="autofill_island" msgid="4020100875984667025">"კუნძული"</string>
+    <string name="autofill_district" msgid="8400735073392267672">"ოლქი"</string>
+    <string name="autofill_department" msgid="5343279462564453309">"დეპარტამენტი"</string>
+    <string name="autofill_prefecture" msgid="2028499485065800419">"პრეფექტურა"</string>
+    <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="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_packageVerificationAgent" msgid="5568139100645829117">"პაკეტების გადამოწმება"</string>
+    <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"აპს შეუძლია დაადასტუროს პაკეტის დაყანების შესაძლებლობა."</string>
+    <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"პაკეტების ვერიფიკატორებთან დაკავშირება"</string>
+    <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"მფლობელს შეეძლება პაკეტის ვერიფიკატორების მოთხოვნა. არასდროს გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_serialPort" msgid="546083327654631076">"სერიულ პორტებზე წვდომა"</string>
+    <string name="permdesc_serialPort" msgid="2991639985224598193">"მფლობელს შეეძლება სერიულ პორტებზე წვდომა სერიული მენეჯერის  API-ის გამოყენებით."</string>
+    <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"კონტენტის მომწოდებლებთან გარედან წვდომა"</string>
+    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"მფლობელს აძლევს კონტენტ პროვაიდერებზე წვდომას გარემოდან. ჩვეულებრივ აპებში არასოდეს გამოიყენება."</string>
+    <string name="permlab_updateLock" msgid="3527558366616680889">"მოწყობილობის ავტომატური განახლების დაშლა"</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"მფლობელს შეეძლება სისტემისთვის ინფორმაციის მიწოდება, თუ როდის იქნება შესაფერისი დრო მოწყობილობის გასაახლებლად არაინტერაქტიული გადატვირთვისთვის."</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>
+    <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="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="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="oneMonthDurationPast" msgid="7396384508953779925">"ერთი თვის წინ"</string>
+    <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"უფრო ადრე, ვიდრე ერთი თვის წინ"</string>
+  <plurals name="num_seconds_ago">
+    <item quantity="one" msgid="4869870056547896011">"1 წამის წინ"</item>
+    <item quantity="other" msgid="3903706804349556379">"<xliff:g id="COUNT">%d</xliff:g> წამის წინ"</item>
+  </plurals>
+  <plurals name="num_minutes_ago">
+    <item quantity="one" msgid="3306787433088810191">"1 წუთის უკან"</item>
+    <item quantity="other" msgid="2176942008915455116">"<xliff:g id="COUNT">%d</xliff:g> წუთის წინ"</item>
+  </plurals>
+  <plurals name="num_hours_ago">
+    <item quantity="one" msgid="9150797944610821849">"1 საათის წინ"</item>
+    <item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> საათის წინ"</item>
+  </plurals>
+  <plurals name="last_num_days">
+    <item quantity="other" msgid="3069992808164318268">"ბოლო <xliff:g id="COUNT">%d</xliff:g> დღე"</item>
+  </plurals>
+    <string name="last_month" msgid="3959346739979055432">"გასული თვე"</string>
+    <string name="older" msgid="5211975022815554840">"უფრო ძველი"</string>
+  <plurals name="num_days_ago">
+    <item quantity="one" msgid="861358534398115820">"გუშინ"</item>
+    <item quantity="other" msgid="2479586466153314633">"<xliff:g id="COUNT">%d</xliff:g> დღის წინ"</item>
+  </plurals>
+  <plurals name="in_num_seconds">
+    <item quantity="one" msgid="2729745560954905102">"1 წამში"</item>
+    <item quantity="other" msgid="1241926116443974687">"<xliff:g id="COUNT">%d</xliff:g> წამში"</item>
+  </plurals>
+  <plurals name="in_num_minutes">
+    <item quantity="one" msgid="8793095251325200395">"1 წუთში"</item>
+    <item quantity="other" msgid="3330713936399448749">"<xliff:g id="COUNT">%d</xliff:g> წუთში"</item>
+  </plurals>
+  <plurals name="in_num_hours">
+    <item quantity="one" msgid="7164353342477769999">"1 საათში"</item>
+    <item quantity="other" msgid="547290677353727389">"<xliff:g id="COUNT">%d</xliff:g> საათში"</item>
+  </plurals>
+  <plurals name="in_num_days">
+    <item quantity="one" msgid="5413088743009839518">"ხვალ"</item>
+    <item quantity="other" msgid="5109449375100953247">"<xliff:g id="COUNT">%d</xliff:g> დღეში"</item>
+  </plurals>
+  <plurals name="abbrev_num_seconds_ago">
+    <item quantity="one" msgid="1849036840200069118">"1 წმ. წინ"</item>
+    <item quantity="other" msgid="3699169366650930415">"<xliff:g id="COUNT">%d</xliff:g> წამის წინ"</item>
+  </plurals>
+  <plurals name="abbrev_num_minutes_ago">
+    <item quantity="one" msgid="6361490147113871545">"1 წუთის წინ"</item>
+    <item quantity="other" msgid="851164968597150710">"<xliff:g id="COUNT">%d</xliff:g> წუთის წინ"</item>
+  </plurals>
+  <plurals name="abbrev_num_hours_ago">
+    <item quantity="one" msgid="4796212039724722116">"1 საათის წინ"</item>
+    <item quantity="other" msgid="6889970745748538901">"<xliff:g id="COUNT">%d</xliff:g> საათის წინ"</item>
+  </plurals>
+  <plurals name="abbrev_num_days_ago">
+    <item quantity="one" msgid="8463161711492680309">"გუშინ"</item>
+    <item quantity="other" msgid="3453342639616481191">"<xliff:g id="COUNT">%d</xliff:g> დღის წინ"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_seconds">
+    <item quantity="one" msgid="5842225370795066299">"1 წამში"</item>
+    <item quantity="other" msgid="5495880108825805108">"<xliff:g id="COUNT">%d</xliff:g> წამის წინ"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_minutes">
+    <item quantity="one" msgid="562786149928284878">"1 წუთში"</item>
+    <item quantity="other" msgid="4216113292706568726">"<xliff:g id="COUNT">%d</xliff:g> წუთში"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_hours">
+    <item quantity="one" msgid="3274708118124045246">"1 საათში"</item>
+    <item quantity="other" msgid="3705373766798013406">"<xliff:g id="COUNT">%d</xliff:g> საათში"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_days">
+    <item quantity="one" msgid="2178576254385739855">"ხვალ"</item>
+    <item quantity="other" msgid="2973062968038355991">"<xliff:g id="COUNT">%d</xliff:g> დღეში"</item>
+  </plurals>
+    <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>
+    <string name="days" msgid="4774547661021344602">"დღე"</string>
+    <string name="hour" msgid="2126771916426189481">"საათი"</string>
+    <string name="hours" msgid="894424005266852993">"საათი"</string>
+    <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="week" msgid="5617961537173061583">"კვირა"</string>
+    <string name="weeks" msgid="6509623834583944518">"კვირა"</string>
+    <string name="year" msgid="4001118221013892076">"წელი"</string>
+    <string name="years" msgid="6881577717993213522">"წელი"</string>
+  <plurals name="duration_seconds">
+    <item quantity="one" msgid="6962015528372969481">"1 წამი"</item>
+    <item quantity="other" msgid="1886107766577166786">"<xliff:g id="COUNT">%d</xliff:g> წამი"</item>
+  </plurals>
+  <plurals name="duration_minutes">
+    <item quantity="one" msgid="4915414002546085617">"1 წუთი"</item>
+    <item quantity="other" msgid="3165187169224908775">"<xliff:g id="COUNT">%d</xliff:g> წუთი"</item>
+  </plurals>
+  <plurals name="duration_hours">
+    <item quantity="one" msgid="8917467491248809972">"1 საათი"</item>
+    <item quantity="other" msgid="3863962854246773930">"<xliff:g id="COUNT">%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_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>
+    <string name="midnight" msgid="7166259508850457595">"შუაღამე"</string>
+    <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="cut" msgid="3092569408438626261">"ამოჭრა"</string>
+    <string name="copy" msgid="2681946229533511987">"კოპირება"</string>
+    <string name="paste" msgid="5629880836805036433">"ჩასმა"</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="textSelectionCABTitle" msgid="5236850394370820357">"ტექსტის მონიშვნა"</string>
+    <string name="addToDictionary" msgid="4352161534510057874">"ლექსიკონში დამატება"</string>
+    <string name="deleteText" msgid="6979668428458199034">"წაშლა"</string>
+    <string name="inputMethod" msgid="1653630062304567879">"შეყვანის მეთოდი"</string>
+    <string name="editTextMenuTitle" msgid="4909135564941815494">"ქმედებები ტექსტზე"</string>
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"თავისუფალი ადგილი იწურება"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"სისტემის ზოგიერთმა ფუნქციამ შესაძლოა არ იმუშავოს"</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="4653586947747330058">"შეეხეთ მეტი ინფორმაციისათვის ან აპის შესაწყვეტად."</string>
+    <string name="ok" msgid="5970060430562524910">"OK"</string>
+    <string name="cancel" msgid="6442560571259935130">"გაუქმება"</string>
+    <string name="yes" msgid="5362982303337969312">"OK"</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="alwaysUse" msgid="4583018368000610438">"ამ ქმედებისთვის ნაგულისხმევად გამოყენება."</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="aerr_title" msgid="1905800560317137752"></string>
+    <string name="aerr_application" msgid="932628488013092776">"სამწუხაროდ, <xliff:g id="APPLICATION">%1$s</xliff:g> შეწყდა."</string>
+    <string name="aerr_process" msgid="4507058997035697579">"სამწუხაროდ, პროცესი <xliff:g id="PROCESS">%1$s</xliff:g> შეწყდა."</string>
+    <string name="anr_title" msgid="4351948481459135709"></string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> არ რეაგირებს.\n\nგსურთ, მისი დახურვა?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"<xliff:g id="ACTIVITY">%1$s</xliff:g> აქტივობა არ რეაგირებს.\n\nგსურთ მისი დახურვა?"</string>
+    <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> არ რეაგირებს. გსურთ მისი დახურვა?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"პროცესი <xliff:g id="PROCESS">%1$s</xliff:g> არ რეაგირებს.\n\nგსურთ, მისი დახურვა?"</string>
+    <string name="force_close" msgid="8346072094521265605">"OK"</string>
+    <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_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; აპები &gt; ჩამოტვირთულები."</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>
+    <string name="android_upgrading_title" msgid="1584192285441405746">"Android ახალ ვერსიაზე გადადის…"</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_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="1721681741617898865">"აპზე გადასართველად შეეხეთ"</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>
+    <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="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_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_notification" msgid="7044986546477282274">"შეტყობინების ხმა"</string>
+    <string name="ringtone_default" msgid="3789758980357696936">"ნაგულისხმევი ზარი"</string>
+    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"ნაგულისხმევი ზარი (<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_unknown" msgid="5477919988701784788">"უცნობი ზარი"</string>
+  <plurals name="wifi_available">
+    <item quantity="one" msgid="6654123987418168693">"Wi-Fi ქსელი ხელმისაწვდომია"</item>
+    <item quantity="other" msgid="4192424489168397386">"Wi-Fi ქსელები ხელმისაწვდომია."</item>
+  </plurals>
+  <plurals name="wifi_available_detailed">
+    <item quantity="one" msgid="1634101450343277345">"ხელმისაწვდომი Wi-Fi ქსელების გახსნა"</item>
+    <item quantity="other" msgid="7915895323644292768">"ხელმისაწვდომი Wi-Fi ქსელების გახსნა"</item>
+  </plurals>
+    <string name="wifi_available_sign_in" msgid="4029489716605255386">"Wi-Fi ქსელთან დაკავშირება"</string>
+    <string name="network_available_sign_in" msgid="8495155593358054676">"ქსელში შესვლა"</string>
+    <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
+    <skip />
+    <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi-თან დაკავშირება ვერ მოხერხდა"</string>
+    <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" აქვს ცუდი ინტერნეტ კავშირი."</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_enabled_notification_message" msgid="1638949953993894335">"პარამეტრებისთვის შეეხეთ"</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_to_connect_title" msgid="4958803948658533637">"მოწვევა დასაკავშირებლად"</string>
+    <string name="wifi_p2p_from_message" msgid="570389174731951769">"გამგზავნი:"</string>
+    <string name="wifi_p2p_to_message" msgid="248968974522044099">"მიმღები:"</string>
+    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"შეიყვანეთ საჭირო PIN:"</string>
+    <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"პინ-კოდი:"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"ტაბლეტი დროებით გაითიშება Wi-Fi-დან, სანამ მიერთებულია <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ზე"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"ტელეფონი დროებით გაითიშება Wi-Fi-დან, სანამ მიერთებულია <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ზე"</string>
+    <string name="select_character" msgid="3365550120617701745">"სიმბოლოს ჩასმა"</string>
+    <string name="sms_control_title" msgid="7296612781128917719">"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="3492025719868078457">"ამან "<font fgcolor="#ffffb060">"შესაძლოა გამოიწვიოს ცვლილებები"</font>" თქვენი მობილურის ანგარიშზე."</string>
+    <string name="sms_premium_short_code_details" msgid="5523826349105123687"><font fgcolor="#ffffb060">"ეს გამოიწვევს დანახარჯებს თქვენ მობილურ ანგარიშზე."</font></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">"ამის შეცვლა შეგიძლიათ მოგვიანებით აპების პარამეტრებიდან."</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_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="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_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="usb_storage_activity_title" msgid="4465055157209648641">"USB მასიური მეხსიერება"</string>
+    <string name="usb_storage_title" msgid="5901459041398751495">"USB დაკავშირებულია"</string>
+    <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"თქვენ დაკავშირებული ხართ კომპიუტერთან USB-ის მეშვეობით. თუ გსურთ კომპიუტერსა და თქვენს Android USB მოწყობილობას შორის ფაილების კოპირება შეეხეთ ქვემოთ მდებარე ღილაკს."</string>
+    <string name="usb_storage_message" product="default" msgid="805351000446037811">"თქვენ დაუკავშირდით კომპიუტერს USB-ის მეშვეობით. შეეხეთ ქვემოთ მდებარე ღილაკს, თუ გსურთ ფაილების კოპირება თქვენ კომპიუტერსა და Android SD ბარათს შორის."</string>
+    <string name="usb_storage_button_mount" msgid="1052259930369508235">"USB მეხსიერების ჩართვა"</string>
+    <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"USB მასიური მეხსიერებისთვის თქვენი USB მეხსიერების გამოყენება პრობლემას ქმნის."</string>
+    <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"USB მასიური მეხსიერებისთვის თქვენი SD ბარათის გამოყენება პრობლემას ქმნის."</string>
+    <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB დაკავშირებულია"</string>
+    <string name="usb_storage_notification_message" msgid="939822783828183763">"შეეხეთ ფაილების კოპირებისათვის კომპიუტერში/კომპიუტერიდან."</string>
+    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"USB მეხსიერების გამორთვა"</string>
+    <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"შეეხეთ USB მეხსიერების გამოსართველად."</string>
+    <string name="usb_storage_stop_title" msgid="660129851708775853">"ხდება USB მეხსიერების გამოყენება"</string>
+    <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"USB მეხსიერების გამორთვამდე, გამოიღეთ თქვენი Android-ის USB თქვენი კომპიუტერიდან."</string>
+    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"USB მეხსიერების გამორთვამდე, გამოაერთეთ თქვენი Android SD ბარათი კომპიუტერიდან."</string>
+    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"USB მეხსიერების გამორთვა"</string>
+    <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"USB-გამორთვისას წარმოიშვა შეცდომა. შეამოწმეთ, რომ გათიშეთ თქვენი USB ჰოსტი, შემდეგ სცადეთ ხელახლა."</string>
+    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"USB მეხსიერების ჩართვა"</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"თუ USB მეხსიერებას ჩართავთ, თქვენ მიერ მოხმარებადი რამდენიმე აპი შეწყვეტს მუშაობას და შესაძლოა მიუწვდომელი გახდეს USB მეხსიერების გამორთვამდე."</string>
+    <string name="dlg_error_title" msgid="7323658469626514207">"USB ოპერაცია წარუმატებელი იყო"</string>
+    <string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
+    <string name="usb_mtp_notification_title" msgid="3699913097391550394">"დაკავშირებულია როგორც მედია მოწყობილობა"</string>
+    <string name="usb_ptp_notification_title" msgid="1960817192216064833">"დაკავშირებულია როგორც კამერა"</string>
+    <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"დაკავშირებულია როგორც დამყენებელი"</string>
+    <string name="usb_accessory_notification_title" msgid="7848236974087653666">"დაკავშირებულია USB აქსესუართან"</string>
+    <string name="usb_notification_message" msgid="2290859399983720271">"შეეხეთ USB-ის სხვა პარამეტრების სანახავად."</string>
+    <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"დავაფორმატო USB მეხსიერება?"</string>
+    <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"გსურთ SD ბარათის დაფორმატება?"</string>
+    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"თქვენ USB მეხსიერებაში შენახული ყველა ფაილი წაიშლება. ეს მოქმედება ვეღარ შეიცვლება!"</string>
+    <string name="extmedia_format_message" product="default" msgid="14131895027543830">"თქვენს ბარათზე ყველა მონაცემი დაიკარგება."</string>
+    <string name="extmedia_format_button_format" msgid="4131064560127478695">"დაფორმატება"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"USB გამართვა შეერთებულია"</string>
+    <string name="adb_active_notification_message" msgid="1016654627626476142">"შეეხეთ, რათა შეწყვიტოთ USB-ის გამართვა."</string>
+    <string name="select_input_method" msgid="4653387336791222978">"აირჩიეთ შეყვანის მეთოდი"</string>
+    <string name="configure_input_methods" msgid="9091652157722495116">"შეყვანის მეთოდების დაყენება"</string>
+    <string name="use_physical_keyboard" msgid="6203112478095117625">"ფიზიკური კლავიატურა"</string>
+    <string name="hardware" msgid="7517821086888990278">"მოწყობილობა"</string>
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"შეარჩიეთ კლავიატურის განლაგება."</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"კლავიატურის განლაგების შესარჩევად შეეხეთ."</string>
+    <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="candidates_style" msgid="4333913089637062257"><u>"კანდიდატები"</u></string>
+    <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"USB მეხსიერების მომზადება"</string>
+    <string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"SD ბარათის მომზადება"</string>
+    <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"შეცდომების შემოწმება"</string>
+    <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"ცარიელი USB მეხსიერება"</string>
+    <string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"ცარიელი SD ბარათი"</string>
+    <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"USB მეხსიერება ცარიელია ან მხარდაუჭერელი ფაილური სისტემა აქვს."</string>
+    <string name="ext_media_nofs_notification_message" product="default" msgid="8641065641786923604">"SD ბარათი ცარიელია ან ფაილური სისტემა მხარდაუჭერელია."</string>
+    <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"დაზიანებული USB მეხსიერება"</string>
+    <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"დაზიანებული SD ბარათი"</string>
+    <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="1795917578395333280">"USB მეხსიერება დაზიანებულია. სცადეთ მისი ხელახლა დაფორმატება."</string>
+    <string name="ext_media_unmountable_notification_message" product="default" msgid="1753898567525568253">"SD ბარათი დაზიანებულია. სცადეთ მისი ხელახლა დაფორმატება."</string>
+    <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"USB მეხსიერება მოულოდნელად გამოირთო"</string>
+    <string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"SD ბარათი მოულოდნელად მოიხსნა"</string>
+    <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"გამოერთებამდე გათიშეთ USB მეხსიერება, რათა თავიდან აიცილოთ მონაცემების დაკარგვა."</string>
+    <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"გამოერთებამდე გათიშეთ SD ბარათი, რათა თავიდან აიცილოთ მონაცემების დაკარგვა."</string>
+    <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"USB მეხსიერების გამორთვა უსაფრთხოა"</string>
+    <string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"SD ბარათის მოხსნა უსაფრთხოა"</string>
+    <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"შეგიძლიათ უსაფრთხოდ გამოაერთოთ USB მეხსიერება."</string>
+    <string name="ext_media_safe_unmount_notification_message" product="default" msgid="568841278138377604">"შეგიძლიათ უსაფრთხოდ გამოაერთოთ SD ბარათი."</string>
+    <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"გამორთული USB მეხსიერება"</string>
+    <string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"გამოღებულია SD ბარათი."</string>
+    <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"USB მეხსიერება გამოერთებულია. მიუერთეთ ახალი მედია."</string>
+    <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"SD ბარათი მოხსნილია. ჩასვით ახალი."</string>
+    <string name="activity_list_empty" msgid="1675388330786841066">"შესატყვისი აქტივობები არ არის."</string>
+    <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"კომპონენტების გამოყენების სტატისტიკის განახლება"</string>
+    <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"აპს შეეძლება, შეცვალოს კომპონენტის გამოყენების შეგროვებული სტატისტიკა. არ გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_copyProtectedData" msgid="4341036311211406692">"კონტენტის კოპირება"</string>
+    <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"აპს შეეძლება კონტენტის კოპირებისთვის კონტეინერის ნაგულისხმევი სერვისის გამოძახება. არ გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_route_media_output" msgid="1642024455750414694">"მულტიმედია მონაცემების გადამისამართება"</string>
+    <string name="permdesc_route_media_output" msgid="4932818749547244346">"აპლიკაციას შეეძლება გადაამისამართოს მულტიმედია მონაცემები სხვა გარე მოწყობილობებისკენ."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"ღილაკების დამცავის უსაფრთხო საცავზე წვდომა"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"აპლიკაციას ღილაკების დამცავის უსაფრთხო საცავზე წვდომის უფლება ექნება."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"ღილაკების დამცავის გამოჩენისა და დამალვის მართვა"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"აპლიკაციას შეეძლება ღილაკების დამცავის კონტროლი."</string>
+    <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"მასშტაბის მართვისთვის შეეხეთ ორჯერ."</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>
+    <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">"ნომერზე დარეკვა\n<xliff:g id="NUMBER">%s</xliff:g>-ის გამოყენებით"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"კონტაქტის შექმნა\n <xliff:g id="NUMBER">%s</xliff:g>-ის გამოყენებით"</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"მითითებული ერთი ან რამდენიმე აპი ითხოვს თქვენს ანგარიშზე წვდომის უფლებას, ახლა და მომავალში."</string>
+    <string name="grant_credentials_permission_message_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">"მოთხოვნილია ნებრათვა \nანგარიშისთვის: <xliff:g id="ACCOUNT">%s</xliff:g>"</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>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"ფონის შეცვლა"</string>
+    <string name="notification_listener_binding_label" msgid="2014162835481906429">"შეტყობინებების მსმენელი"</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="3011306607126450322">"შეეხეთ ქსელის სამართავად."</string>
+    <string name="vpn_text_long" msgid="6407351006249174473">"მიერთებულია <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_error" msgid="6009249814034708175">"შეცდომა მუდამ VPN-ზე"</string>
+    <string name="vpn_lockdown_config" msgid="6415899150671537970">"კონფიგურაციისთვის შეეხეთ"</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="8035230537563503262">"შეეხეთ მანქანის რეჟიმიდან გამოსასვლელად."</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"ინტერნეტის მიერთება ან უსადენო ქსელი აქტიურია."</string>
+    <string name="tethered_notification_message" msgid="6857031760103062982">"შესაქმნელად შეეხეთ"</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="throttle_warning_notification_title" msgid="4890894267454867276">"მობილური ინტერნეტის მაღალი მოხმარება"</string>
+    <string name="throttle_warning_notification_message" msgid="3340822228599337743">"შეეხეთ, რათა შეიტყოთ მეტი მობილურის ინტერნეტის გამოყენების შესახებ."</string>
+    <string name="throttled_notification_title" msgid="6269541897729781332">"მობილური ინტერნეტის ლიმიტი გადაჭარბებულია"</string>
+    <string name="throttled_notification_message" msgid="5443457321354907181">"შეეხეთ, რათა შეიტყოთ მეტი მობილურის ინტერნეტის გამოყენების შესახებ."</string>
+    <string name="no_matches" msgid="8129421908915840737">"შესატყვისები არ არის."</string>
+    <string name="find_on_page" msgid="1946799233822820384">"გვერდზე ძებნა"</string>
+  <plurals name="matches_found">
+    <item quantity="one" msgid="8167147081136579439">"1 დამთხვევა"</item>
+    <item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> <xliff:g id="TOTAL">%d</xliff:g>-დან"</item>
+  </plurals>
+    <string name="action_mode_done" msgid="7217581640461922289">"დასრულდა"</string>
+    <string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"USB მეხსიერების გათიშვა…"</string>
+    <string name="progress_unmounting" product="default" msgid="1327894998409537190">"მიმდინარეობს SD ბარათის მოხსნა…"</string>
+    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"მიმდინარეობს USB მეხსიერების გასუფთავება…"</string>
+    <string name="progress_erasing" product="default" msgid="6596988875507043042">"SD ბარათის წაშლა..."</string>
+    <string name="format_error" product="nosdcard" msgid="6299769563624776948">"USB მეხსიერების წაშლა ვერ მოხერხდა."</string>
+    <string name="format_error" product="default" msgid="7315248696644510935">"SD ბარათის წაშლა ვერ მოხერხდა."</string>
+    <string name="media_bad_removal" msgid="7960864061016603281">"SD ბარათი მანამ მოიხსნა, ვიდრე გამოერთებული იქნებოდა."</string>
+    <string name="media_checking" product="nosdcard" msgid="418188720009569693">"USB მეხსიერება ამჟამად შემოწმების პროცესშია."</string>
+    <string name="media_checking" product="default" msgid="7334762503904827481">"ამჟამად მიმდინარეობს SD ბარათის შემოწმება."</string>
+    <string name="media_removed" msgid="7001526905057952097">"SD ბარათი გამოერთებულია."</string>
+    <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"USB მეხსიერებას კომპიუტერი იყენებს ამჟამად."</string>
+    <string name="media_shared" product="default" msgid="5706130568133540435">"SD ბარათს კომპიუტერი იყენებს ამჟამად."</string>
+    <string name="media_unknown_state" msgid="729192782197290385">"გარე მედია უცნობ მდგომარეობაშია."</string>
+    <string name="share" msgid="1778686618230011964">"გაზიარება"</string>
+    <string name="find" msgid="4808270900322985960">"ძიება"</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="gpsNotifMessage" msgid="1374718023224000702">"მოთხოვნილია <xliff:g id="NAME">%1$s</xliff:g>-ის მიერ (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+    <string name="gpsVerifYes" msgid="2346566072867213563">"დიახ"</string>
+    <string name="gpsVerifNo" msgid="1146564937346454865">"არა"</string>
+    <string name="sync_too_many_deletes" msgid="5296321850662746890">"წაშლის შეზღუდვა გადაჭარბებულია"</string>
+    <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> წაშლილი ერთეულია <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>-თვის, ანგარიში <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. რისი გაკეთება გსურთ?"</string>
+    <string name="sync_really_delete" msgid="2572600103122596243">"ერთეულების წაშლა"</string>
+    <string name="sync_undo_deletes" msgid="2941317360600338602">"წაშლების გაუქმება"</string>
+    <string name="sync_do_nothing" msgid="3743764740430821845">"ამჟამად არაფერი გააკეთო"</string>
+    <string name="choose_account_label" msgid="5655203089746423927">"ანგარიშის არჩევა"</string>
+    <string name="add_account_label" msgid="2935267344849993553">"ანგარიშის დამატება"</string>
+    <string name="add_account_button_label" msgid="3611982894853435874">"ანგარიშის დამატება &amp;raquo;"</string>
+    <string name="number_picker_increment_button" msgid="2412072272832284313">"გაზრდა"</string>
+    <string name="number_picker_decrement_button" msgid="476050778386779067">"შემცირება"</string>
+    <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g>-ს შეეხეთ და არ აუშვათ."</string>
+    <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"აასრიალეთ ზემოთ გასაზრდელად და ჩაასრიალეთ ქვემოთ შესამცირებლად."</string>
+    <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"ერთი წუთით წინ"</string>
+    <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"წუთების შემცირება"</string>
+    <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"საათის მომატება"</string>
+    <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"საათით უკან"</string>
+    <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"PM-ის დაყენება"</string>
+    <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"AM-ის დაყენება"</string>
+    <string name="date_picker_increment_month_button" msgid="5369998479067934110">"თვის მომატება"</string>
+    <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"ერთი თვით უკან"</string>
+    <string name="date_picker_increment_day_button" msgid="7130465412308173903">"დღის მომატება"</string>
+    <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"დღის მოკლება"</string>
+    <string name="date_picker_increment_year_button" msgid="6318697384310808899">"წლის მომატება"</string>
+    <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"წლის მოკლება"</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_enter" msgid="2985864015076059467">"შეყვანა"</string>
+    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"აპის არჩევა"</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_direction_up" msgid="7169032478259485180">"გაასრიალეთ ზემოთ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-თვის."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"გაასრიალეთ ქვემოთ <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="description_direction_right" msgid="8034433242579600980">"გაასრიალეთ მარჯვნივ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-თვის."</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"განბლოკვა"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"კამერა"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"უხმო"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"ხმის ჩართვა"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"ძიება"</string>
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"განბლოკვისათვის გადაფურცლეთ"</string>
+    <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"შეაერთედ ყურსასმენები, პაროლის ღილაკები რომ გაიგოთ."</string>
+    <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"წერტილი."</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="4891916833657929263">"შიდა მეხსიერება"</string>
+    <string name="storage_sd_card" msgid="3282948861378286745">"SD ბარათი"</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="1955638862122232342">"ინტერნეტის გამოყენების გაფრთხილება"</string>
+    <string name="data_usage_warning_body" msgid="2814673551471969954">"შეეხეთ მოხმარებისა და პარამეტრების სანახავად."</string>
+    <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-3G ინტერნეტი გაითიშა."</string>
+    <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G მონაცემები გათიშულია"</string>
+    <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"მობილური ინტერნეტი გაითიშა"</string>
+    <string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"Wi‑Fi მონაცემთა გამორთვა"</string>
+    <string name="data_usage_limit_body" msgid="3317964706973601386">"გასააქტიურებლად შეეხეთ."</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_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="6741521330997452990">"შეეხეთ შეზღუდვის მოსახსნელად"</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>
+    <string name="org_unit" msgid="7265981890422070383">"ორგანიზაციული ერთეული:"</string>
+    <string name="issued_by" msgid="2647584988057481566">"გამცემი:"</string>
+    <string name="validity_period" msgid="8818886137545983110">"ვალიდურობა:"</string>
+    <string name="issued_on" msgid="5895017404361397232">"გაცემული:"</string>
+    <string name="expires_on" msgid="3676242949915959821">"ვადა იწურება:"</string>
+    <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>
+    <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"ყველას ნახვა"</string>
+    <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"აქტივობის არჩევა"</string>
+    <string name="share_action_provider_share_with" msgid="5247684435979149216">"გაზიარება"</string>
+    <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="3245653681008218030">"იგზავნება..."</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="default_audio_route_name" product="tablet" msgid="4617053898167127471">"ტაბლეტი"</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="media_route_chooser_grouping_done" msgid="7966438307723317169">"დასრულდა"</string>
+    <string name="media_route_button_content_description" msgid="5758553567065145276">"მედია გამომავალი"</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>
+    <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_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="wifi_display_notification_title" msgid="2223050649240326557">"უსადენო ეკრანი დაკავშირებულია"</string>
+    <string name="wifi_display_notification_message" msgid="4498802012464170685">"გამოსახულება გადაეცემა სხვა მოწყობილობას"</string>
+    <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"კავშირის გაწყვეტა"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"გადაუდებელი დახმარების ზარი"</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">"არასწორი PIN"</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">"SIM PIN-ის შეყვანა"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"შეიყვანეთ PIN"</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">"სასურველი PIN კოდის შეყვანა"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"სასურველი PIN კოდის დადასტურება"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM ბარათის განბლოკვა…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"არასწორი PIN კოდი."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"აკრიფეთ PIN, რომელიც შედგება 4-დან 8 ციფრამდე."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK კოდი უნდა იყოს რვა ან მეტი ციფრისგან შემდგარი."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"ხელახლა შეიყვანეთ სწორი PUK კოდი. რამდენიმე წარუმატებელი მცდელობა გამოიწვევს SIM ბარათის დაბლოკვას."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN კოდები არ ემთხვევა"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ნახატი ნიმუშის ძალიან ბევრი მცდელობა"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"განბლოკვისთვის გაიარეთ ავტორიზაცია თქვენი Google  ანგარიშით."</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"მიმდინარეობს ანგარიშის შემოწმება…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"თქვენ <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ არასწორად შეიყვანეთ PIN კოდი. \n\nსცადეთ ხელახლა <xliff:g id="NUMBER_1">%d</xliff:g> წამში."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"თქვენ <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ არასწორად დაბეჭდეთ თქვენი პაროლი. \n\nხელახლა სცადეთ <xliff:g id="NUMBER_1">%d</xliff:g> წამში."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"თქვენ <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ დახატეთ განბლოკვის ნიმუში. \n\nსცადეთ ხელახლა <xliff:g id="NUMBER_1">%d</xliff:g> წამში."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"თქვენ არასწორად სცადეთ ტაბლეტის განბლოკვა <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%d</xliff:g> წარუმატებელი ცდის შემდეგ ტაბლეტზე დაყენდება საწყისი, ქარხნული პარამეტრები და მომხმარებლის ყველა მონაცემი დაიკარგება."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"თქვენ არასწორად სცადეთ ტელეფონის განბლოკვა <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> ჯერ. კიდევ <xliff:g id="NUMBER_1">%d</xliff:g> წარუმატებელი ცდის შემდეგ მოგთხოვთ ტაბლეტის განბლოკვას ელფოსტის ანგარიშის გამოყენებით.\n\n ხელახლა სცადეთ <xliff:g id="NUMBER_2">%d</xliff:g> წამში."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"თქვენ არასწორად დახატეთ თქვენი განბლოკვის ნიმუში <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%d</xliff:g> წარუმატებელი ცდის შემდეგ, დაგჭირდებათ თქვენი ტელეფონის განბლოკვა ელფოსტის ანგარიშის გამოყენებით.\n\n ხელახლა სცადეთ <xliff:g id="NUMBER_2">%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="7324161939475478066">"რეკომენდებულ დონეზე მაღლა გსურთ ხმის აწევა?\nდიდი ხნის განმავლობაში ძალიან ხმამაღლა მოსმენამ შესაძლოა სმენა დაგიზიანოთ."</string>
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"გეჭიროთ ორი თითი მარტივი წვდომის ჩასართავად."</string>
+    <string name="accessibility_enabled" msgid="1381972048564547685">"მარტივი წვდომა ჩართულია."</string>
+    <string name="enable_accessibility_canceled" msgid="3833923257966635673">"მარტივი წვდომა გაუქმდა."</string>
+    <string name="user_switched" msgid="3768006783166984410">"ამჟამინდელი მომხმარებელი <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="app_no_restricted_accounts" msgid="5739463249673727736">"ამ აპს შეზღუდული პროფილების ანგარიშების მხარდაჭერა არ აქვს"</string>
+    <string name="app_not_found" msgid="3429141853498927379">"ამ მოქმედების შესასრულებლად აპლიკაცია ვერ მოიძებნა"</string>
+    <string name="revoke" msgid="5404479185228271586">"გაუქმება"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"გაუქმებული"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"შეცდომა კონტენტის ჩაწერისას"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"უცნობი"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"შეიყვანეთ ადმინისტრატორის 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>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"ახალი PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"გაიმეორეთ ახალი PIN"</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_too_short" msgid="8173982756265777792">"PIN ძალიან მოკლეა. უნდა შედგებოდეს სულ ცოტა 4 ციფრისგან."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"კიდევ ერთხელ სცადეთ 1 წამში"</item>
+    <item quantity="other" msgid="4730868920742952817">"კიდევ ერთხელ სცადეთ <xliff:g id="COUNT">%d</xliff:g> წამში"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"სცადეთ მოგვიანებით"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"გაასრიალეთ ეკრანის კიდეზე ზოლის გამოსაჩენად"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"გაასრიალეთ ეკრანის კიდიდან სისტემის ზოლის გამოსაჩენად"</string>
+</resources>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
new file mode 100644
index 0000000..94fb8d0
--- /dev/null
+++ b/core/res/res/values-ka/strings.xml
@@ -0,0 +1,1588 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<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="5973789783504771878">"კბაიტი"</string>
+    <string name="megabyteShort" msgid="6355851576770428922">"მბაიტი"</string>
+    <string name="gigabyteShort" msgid="3259882455212193214">"გბაიტი"</string>
+    <string name="terabyteShort" msgid="231613018159186962">"ტბაიტი"</string>
+    <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
+    <string name="untitled" msgid="4638956954852782576">"უსათაურო"</string>
+    <string name="ellipsis" msgid="7899829516048813237">"…"</string>
+    <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
+    <string name="emptyPhoneNumber" msgid="7694063042079676517">"(ტელეფონის ნომრის გარეშე)"</string>
+    <string name="unknownName" msgid="2277556546742746522">"უცნობი"</string>
+    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"ხმოვანი ფოსტა"</string>
+    <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
+    <string name="mmiError" msgid="5154499457739052907">"კავშირის პრობლემა ან არასწორი MMI კოდი."</string>
+    <string name="mmiFdnError" msgid="5224398216385316471">"ოპერაცია შეზღუდულია მხოლოდ დაშვებულ ნომრებზე."</string>
+    <string name="serviceEnabled" msgid="8147278346414714315">"სერვისი ჩართულია."</string>
+    <string name="serviceEnabledFor" msgid="6856228140453471041">"სერვისი ჩართულია შემდეგისთვის:"</string>
+    <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="mmiComplete" msgid="8232527495411698359">"MMI დასრულდა."</string>
+    <string name="badPin" msgid="9015277645546710014">"თქვენ მიერ შეყვანილი ძველი პინ-კოდი არასწორია."</string>
+    <string name="badPuk" msgid="5487257647081132201">"თქვენ მიერ შეყვანილი PUK კოდი არასწორია."</string>
+    <string name="mismatchPin" msgid="609379054496863419">"თქვენ მიერ შეყვანილი PIN კოდები არ შეესატყვისება."</string>
+    <string name="invalidPin" msgid="3850018445187475377">"აკრიფეთ PIN, რომელიც შედგება 4-დან 8 ციფრამდე."</string>
+    <string name="invalidPuk" msgid="8761456210898036513">"აკრიფეთ PUK, რომელიც რვა ან მეტი ციფრისგან შედგება."</string>
+    <string name="needPuk" msgid="919668385956251611">"თქვენი SIM ბარათი დაბლოკილია PUK კოდით. განბლოკვისთვის შეიყვანეთ PUK კოდი."</string>
+    <string name="needPuk2" msgid="4526033371987193070">"SIM ბარათის განსაბლოკად აკრიფეთ PUK2."</string>
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
+    <string name="ClipMmi" msgid="6952821216480289285">"შემომავალი ზარის აბონენტის ID"</string>
+    <string name="ClirMmi" msgid="7784673673446833091">"გამავალი მრეკავის ID"</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">"PIN-ის შეცვლა"</string>
+    <string name="CnipMmi" msgid="3110534680557857162">"გამომძახებლის ნომერი წარმოდგენილია"</string>
+    <string name="CnirMmi" msgid="3062102121430548731">"შემოსული ზარი შეზღუდულია"</string>
+    <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="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="RestrictedChangedTitle" msgid="5592189398956187498">"წვდომის შეზღუდვები შეცვლილია"</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="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>
+    <string name="serviceClassDataSync" msgid="7530000519646054776">"სინქრონიზაცია"</string>
+    <string name="serviceClassPacket" msgid="6991006557993423453">"პაკეტი"</string>
+    <string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
+    <string name="roamingText0" msgid="7170335472198694945">"როუმინგის მაჩვენებელი ჩართულია."</string>
+    <string name="roamingText1" msgid="5314861519752538922">"როუმინგის მაჩვენებელი გამორთულია."</string>
+    <string name="roamingText2" msgid="8969929049081268115">"როუმინგის მაჩვენებლის ციმციმი"</string>
+    <string name="roamingText3" msgid="5148255027043943317">"სამეზობლოს მიღმა"</string>
+    <string name="roamingText4" msgid="8808456682550796530">"შენობის გარეთ"</string>
+    <string name="roamingText5" msgid="7604063252850354350">"როუმინგი - უპირატესი სისტემა"</string>
+    <string name="roamingText6" msgid="2059440825782871513">"როუმინგი - ხელმისაწვდომი სისტემა"</string>
+    <string name="roamingText7" msgid="7112078724097233605">"როუმინგი - ალიანსის პარტნიორი"</string>
+    <string name="roamingText8" msgid="5989569778604089291">"როუმინგი - პრემიუმ პარტნიორი"</string>
+    <string name="roamingText9" msgid="7969296811355152491">"Roaming - Full Service Functionality"</string>
+    <string name="roamingText10" msgid="3992906999815316417">"Roaming - Partial Service Functionality"</string>
+    <string name="roamingText11" msgid="4154476854426920970">"Roaming Banner ჩართულია"</string>
+    <string name="roamingText12" msgid="1189071119992726320">"როუმინგის ბანერი გამორთულია"</string>
+    <string name="roamingTextSearching" msgid="8360141885972279963">"სერვისის ძიება"</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="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="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="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="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="default" msgid="3475999286680000541">"ტელეფონის მეხსიერება გავსებულია. ადგილის გასათავისუფლებლად წაშალეთ ფაილების ნაწილი."</string>
+    <string name="me" msgid="6545696007631404292">"მე"</string>
+    <string name="power_dialog" product="tablet" msgid="8545351420865202853">"ტაბლეტის პარამეტრები"</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="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="shutdown_progress" msgid="2281079257329981203">"გამორთვა…"</string>
+    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"თქვენი ტაბლეტი გაითიშება."</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="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_bug_report" msgid="7934010578922304799">"ხარვეზის შესახებ ანგარიში"</string>
+    <string name="bugreport_title" msgid="2667494803742548533">"შექმენით შეცდომის ანგარიში"</string>
+    <string name="bugreport_message" msgid="398447048750350456">"იგი შეაგროვებს ინფორმაციას თქვენი მოწყობილობის ამჟამინდელი მდგომარეობის შესახებ, რათა ის ელფოსტის შეტყობინების სახით გააგზავნოს. ხარვეზის ანგარიშის მომზადებასა და შეტყობინების გაგზავნას გარკვეული დრო სჭირდება. გთხოვთ, მოითმინოთ."</string>
+    <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_airplane_mode_on_status" msgid="2719557982608919750">"თვითმფრინავის რეჟიმი ჩართულია."</string>
+    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"თვითმფრინავის რეჟიმი გამორთულია."</string>
+    <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
+    <string name="safeMode" msgid="2788228061547930246">"უსაფრთხო რეჟიმი"</string>
+    <string name="android_system_label" msgid="6577375335728551336">"Android-ის სისტემა"</string>
+    <string name="permgrouplab_costMoney" msgid="5429808217861460401">"სერვისები, რომელშიც ფულის გადახდა გიწევთ"</string>
+    <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"ისეთი აქტივობების განხორციელება, რომლებშიც ფულის გადახდა მოგიწევთ."</string>
+    <string name="permgrouplab_messages" msgid="7521249148445456662">"თქვენი შეტყობინებები"</string>
+    <string name="permgroupdesc_messages" msgid="7821999071003699236">"თქვენი SMS-ის, ელფოტის და სხვა შეტყობინებების წაკითხვა და დაწერა."</string>
+    <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"თქვენი პირადი ინფორმაცია"</string>
+    <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"პირდაპირი წვდომა თქვენ შესახებ ინფორმაციაზე, რომელიც საკონტაქტო ბარათზეა შენახული."</string>
+    <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"თქვენი სოციალური ინფორმაცია"</string>
+    <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"თქვენს კონტაქტებისა და სოციალურ კავშირების შესახებ ინფორმაციაზე პირდაპირი წვდომა."</string>
+    <string name="permgrouplab_location" msgid="635149742436692049">"თქვენი მდებარეობა"</string>
+    <string name="permgroupdesc_location" msgid="5704679763124170100">"თქვენი ფიზიკური მდებარეობის მონიტორინგი"</string>
+    <string name="permgrouplab_network" msgid="5808983377727109831">"ქსელის კომუნიკაცია"</string>
+    <string name="permgroupdesc_network" msgid="4478299413241861987">"წვდომა ქსელის სხვადასხვა პარამეტრთან."</string>
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"Bluetooth"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"მოწყობილობებთან და ქსელებთან წვდომა Bluetooth მეშვეობით."</string>
+    <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"აუდიო პარამეტრები"</string>
+    <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"აუდიო პარამეტრების შეცვლა."</string>
+    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"აზიანებს ელემენტს"</string>
+    <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"იმ ფუნქციების გამოყენება, რომელიც ელემენტს სწრაფად დახლის."</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"კალენდარი"</string>
+    <string name="permgroupdesc_calendar" msgid="5777534316982184416">"კალენდარსა და ღონისძიებებზე პირდაპირი წვდომა."</string>
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"მომხმარებლის ლექსიკონის წაკითხვა"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"მომხმარებლის ლექსიკონში სიტყვების წაკითხვა"</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"მომხმარებლის ლექსიკონში ჩაწერა"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"მომხმარებლის ლექსიკონში სიტყვების დამატება."</string>
+    <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"სანიშნეები და ისტორია"</string>
+    <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"პირდაპირი წვდომა სანიშნეებსა და ბრაუზერის ისტორიაზე"</string>
+    <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"მაღვიძარა"</string>
+    <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"მაღვიძარის დაყენება."</string>
+    <string name="permgrouplab_voicemail" msgid="4162237145027592133">"ხმოვანი ფოსტა"</string>
+    <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"პირდაპირი წვდომა ხმოვან ფოსტაზე"</string>
+    <string name="permgrouplab_microphone" msgid="171539900250043464">"მიკროფონი"</string>
+    <string name="permgroupdesc_microphone" msgid="7106618286905738408">"პირდაპირი წვდომა მიკროფონზე აუდიოს ჩასაწერად."</string>
+    <string name="permgrouplab_camera" msgid="4820372495894586615">"კამერა"</string>
+    <string name="permgroupdesc_camera" msgid="2933667372289567714">"პირდაპირი წვდომა კამერაზე სურათის ან ვიდეოს გადასაღებად"</string>
+    <string name="permgrouplab_screenlock" msgid="8275500173330718168">"ჩაკეტილი ეკრანი"</string>
+    <string name="permgroupdesc_screenlock" msgid="7067497128925499401">"მოწყობილობის ეკრანის ჩამკეტის ქცევის შეცვლის შესაძლებლობა."</string>
+    <string name="permgrouplab_appInfo" msgid="8028789762634147725">"თქვენი აპლიკაციების ინფორმაცია"</string>
+    <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"თქვენს მოწყობილობაზე სხვა აპლიკაციების ქცევის შეცვლის შესაძლებლობა."</string>
+    <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"ფონი"</string>
+    <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"მოწყობილობის ფონის პარამეტრების შეცვლა."</string>
+    <string name="permgrouplab_systemClock" msgid="406535759236612992">"საათი"</string>
+    <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"მოწყობილობის დროის ან დროითი სარტყლის შეცვლა."</string>
+    <string name="permgrouplab_statusBar" msgid="2095862568113945398">"სტატუსის ზოლი"</string>
+    <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"მოწყობილობის სტატუსების ზოლის პარამეტრების შეცვლა."</string>
+    <string name="permgrouplab_syncSettings" msgid="3341990986147826541">"სინქრონიზაციის პარამეტრები"</string>
+    <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"სინქრონიზაციის პარამეტრებზე წვდომა"</string>
+    <string name="permgrouplab_accounts" msgid="3359646291125325519">"თქვენი ანგარიშები"</string>
+    <string name="permgroupdesc_accounts" msgid="4948732641827091312">"ხელმისაწვდომ ანგარიშებზე წვდომა."</string>
+    <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"მოწყობილობების მართვა"</string>
+    <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"ყურსაცვამის აპარატურულ მოწყობილობაზე პირდაპირი წვდომა."</string>
+    <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"სატელეფონო ზარები"</string>
+    <string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"სატელეფონო ზარების მონიტორინგი, ჩაწერა და განხორციელება."</string>
+    <string name="permgrouplab_systemTools" msgid="4652191644082714048">"სისტემის ხელსაწყოები"</string>
+    <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"დაბალი წვდომა და სისტემის კონტროლი"</string>
+    <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"დეველოპმენტის ინსტრუმენტები"</string>
+    <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"ელემენტები, რომლებიც მხოლოდ აპების დეველოპერებს სჭირდებათ."</string>
+    <string name="permgrouplab_display" msgid="4279909676036402636">"სხვა აპლიკაციის UI"</string>
+    <string name="permgroupdesc_display" msgid="6051002031933013714">"სხვა აპლიკაციების UI-ის ეფექტი."</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"შესანახი სივრცე"</string>
+    <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"USB მეხსიერებასთან წვდომა."</string>
+    <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"SD ბარათთან წვდომა."</string>
+    <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"წვდომის ფუნქციები"</string>
+    <string name="permgroupdesc_accessibilityFeatures" msgid="4205196881678144335">"ფუნქციები, რომელიც შესაძლოა მოითხოვოს დამხმარე ტექნოლოგიამ."</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="5800552516779249356">"ის ერთეულები, რომლებსაც შეეხებით, წაიკითხება ხმამაღლა და ეკრანის კვლევა შეიძლება ჟესტების გამოყენებით."</string>
+    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"ვებზე გამარტივებული წვდომის დამატებითი შესაძლებლობების ჩართვა"</string>
+    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"შესაძლებელია სკრიპტების ინსტალაცია აპის კონტენტის წვდომადობის უზრუნველსაყოფად."</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"თქვენ მიერ აკრეფილ ტექსტზე დაკვირვება"</string>
+    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"შეიცავს ისეთ პირად მონაცემებს, როგორიცაა საკრედიტო ბარათის ნომრები და პაროლები."</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"სტატუსის ზოლის გათიშვა ან ცვლილება"</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"აპს შეეძლება სტატუსების ზოლის გათიშვა და სისტემის ხატულების დამატება/წაშლა."</string>
+    <string name="permlab_statusBarService" msgid="7247281911387931485">"სტატუსის ზოლი"</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_processOutgoingCalls" msgid="3906007831192990946">"გამავალი ზარების გადამისამართება"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"აპს შეეძლება გამავალი ზარების დამუშავება და ასაკრეფი ნომრის შეცვლა. ეს უფლება აპს აძლევს შესაძლებლობას აკონტროლოს, გადაამისამართოს ან აღკვეთოს გამავალი ზარები."</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_receiveEmergencyBroadcast" msgid="1803477660846288089">"გადაუდებელი შეტყობინებების მიღება"</string>
+    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"აპს შეეძლება, მიიღოს და დაამუშაოს საგანგებო სამაუწყებლო შეტყობინებები. ეს ნებართვა ხელმისაწვდომია მხოლოდ  სისტემის აპებისთვის."</string>
+    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"მასიური დაგზავნის შეტყობინებების წაკითხვა"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"აპს შეეძლება, წაიკითხოს თქვენს მოწყობილობაზე გამოგზავნილი ქსელის სამაუწყებლო შეტყობინებები. სამაუწყებლო გაფრთხილებები მოგეწოდებათ ზოგიერთ ადგილზე ექსტრემალური სიტუაციების შესახებ გასაფრთხილებლად. ქსელის გადაუდებელი შეტყონიბენის მიღების დროს მავნე აპებმა შეიძლება ხელი შეუშალონ თქვენი მოწყობილობის ფუნქციონირებას ან ოპერაციებს."</string>
+    <string name="permlab_sendSms" msgid="5600830612147671529">"SMS შეტყობის გაგზავნა"</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"აპს შეეძლება, გაგზავნოს SMS შეტყობინებები, რამაც შეიძლება გაუთვალისწინებელი ხარჯები გამოიწვიოს. მავნე აპებმა შეიძლება დაგიხარჯონ ფული შეტყობინებების თქვენი თანხმობის გარეშე გაგზავნით."</string>
+    <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"ღონისძიებების გაგზავნა (პასუხის მიღება მხოლოდ შეტყობინებით)"</string>
+    <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"აპს შეეძლება, გაუგზავნოს მოთხოვნები სხვა შეტყობინებების აპებს შემომავალ ზარებზე შეტყობინებით პასუხის მოვლენებთან გასამკლავებლად."</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"თქვენი ტექსტური შეტყობინებების (SMS ან MMS) წაკითხვა"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"აპს შეეძლება თქვენს ტაბლეტში ან SIM ბარათში შენახული SMS შეტყობინებების წაკითხვა. ამგვარად, აპს ექნება შესაძლებლობა წაიკითხოს ყველა SMS შეტყობინება, მათი კონტენტისა და კონფიდენციალურობის მიუხედავად."</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"აპს შეეძლება თქვენს ტაბლეტში ან SIM ბარათში შენახული SMS შეტყობინებების წაკითხვა. ამგვარად, აპს ექნება შესაძლებლობა წაიკითხოს ყველა SMS შეტყობინება, მათი კონტენტისა და კონფიდენციალურობის მიუხედავად."</string>
+    <string name="permlab_writeSms" msgid="3216950472636214774">"თქვენი ტექსტური შეტყობინებების (SMS ან MMS) რედაქტირება"</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"აპს შეეძლება, უპასუხოს თქვენ ტაბლეტში ან SIM ბარათზე შენახულ SMS შეტყობინებებს. მავნე აპებმა შეიძლება წაშალონ თქვენი შეტყობინებები."</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"აპს უფლება ექნება , უპასუხოს თქვენ ტაბლეტში ან SIM ბარათზე შენახულ 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_interactAcrossUsers" msgid="7114255281944211682">"მომხმარებლებს შორის ინტერაქცია"</string>
+    <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"აპს შეეძლება, სხვადასხვა მომხმარებლის მოქმედებები შეასრულოს მოწყობილობაზე. მავნე აპებმა შეიძლება მომხმარებლებს შორის დაცვის დასარღვევად გამოიყენონ."</string>
+    <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"მომხმარებლებთან ინტერაქციის სრული ლიცენზია"</string>
+    <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"აძლევს მომხმარებლებს შორის ყველა შესაძლო ინტერაქციის უფლებას."</string>
+    <string name="permlab_manageUsers" msgid="1676150911672282428">"მომხმარებლების მართვა"</string>
+    <string name="permdesc_manageUsers" msgid="8409306667645355638">"აპს შეუძლია მომხმარებლების მართვა მოწყობილობაზე, მათ შორის მოთხოვნის, შექმნის და წაშლის."</string>
+    <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"მოქმედი აპების დეტალების მოძიება"</string>
+    <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"აპს შეეძლება მოიძიოს დეტალური ინფორმაცია ამჟამად და უახლოეს წარსულში მიმდინარე ამოცანების შესახებ. მავნე აპებს შეუძლიათ აღმოაჩინონ პირადი ინფორმაცია სხვა აპების შესახებ."</string>
+    <string name="permlab_reorderTasks" msgid="2018575526934422779">"მოქმედი აპების წყობის შეცვლა"</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"აპს შეეძლება ამოცანების გადატანა წინა და უკანა პლანზე. ამას თქვენი ჩარევის გარეშე გააკეთებს."</string>
+    <string name="permlab_removeTasks" msgid="6821513401870377403">"გაშვებული აპების შეწყვეტა"</string>
+    <string name="permdesc_removeTasks" msgid="1394714352062635493">"აპს შეეძლება ამოცანების წაშლა და მათი აპების გაუქმება. მავნე აპებმა შესაძლოა დაარღვიონ სხვა აპების მოქმედება."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"აქტივობის დასტების მართვა"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"საშუალებას აძლევს აპს დაამატოს, ამოშალოს და შეცვალოს აქტივობის დასტები, რაშიც სხვა აპები ეშვება. მავნე აპები სხვა აპებს ქცევის ხელის შეშლას შეძლებს."</string>
+    <string name="permlab_startAnyActivity" msgid="2918768238045206456">"ნებისმიერი აქტივობის წამოწყება"</string>
+    <string name="permdesc_startAnyActivity" msgid="997823695343584001">"აპს შეეძლება დაიწყოს ნებისმიერი აქტივობა, ყოველგვარი უფლებისა და სტატუსის გარეშე."</string>
+    <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"ეკრანის თავსებადობის დაყენება"</string>
+    <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"აპს შეეძლება სხვა აპლიკაციებთან ეკრანის თავსებადობის რეჟიმის კონტროლი. მავნე აპლიკაციებმა შესაძლოა სხვა აპლიაკციების ქცევა შეცვალოს."</string>
+    <string name="permlab_setDebugApp" msgid="3022107198686584052">"აპის გამართვის გააქტიურება"</string>
+    <string name="permdesc_setDebugApp" msgid="4474512416299013256">"აპს შეეძლება სხვა აპისთვის გამართვის რეჟიმის ჩართვა. მავნე აპლიკაციებს ამ ფუნქციით შეეძლებათ სხვა აპების გათიშვა."</string>
+    <string name="permlab_changeConfiguration" msgid="4162092185124234480">"სისტემის ინტერფეისის პარამეტრების შეცვლა"</string>
+    <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"აპს შეეძლება, შეცვალოს ამჟამინდელი კონფიგურაცია, მაგალითად, ენა და ქვეყნის კოდი ან შრიფტის ზომა."</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_forceStopPackages" msgid="2329627428832067700">"სხვა აპების იძულებითი შეჩერება"</string>
+    <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"აპს შეეძლება იძულებით შეწყვიტოს სხვა აპების მუშაობა."</string>
+    <string name="permlab_forceBack" msgid="652935204072584616">"აპის ძალით დახურვა"</string>
+    <string name="permdesc_forceBack" msgid="3892295830419513623">"აპს შეეძლება იძულებით დაასრულოს წინა პლანზე მიმდინარე ნებისმიერი აქტივობა და დაბრუნდეს უკან. ჩვეულებრივ აპებს მსგავსი რამ არასოდეს სჭირდება."</string>
+    <string name="permlab_dump" msgid="1681799862438954752">"სისტემის მდგომარეობის შესახებ ინფორმაციის მიღება"</string>
+    <string name="permdesc_dump" msgid="1778299088692290329">"აპს შეეძლება სისტემის შიდა მდგომარეობის ნახვა. მავნე პროგრამები შეძლებენ პირადი და დაცული ინფორმაციის ნახვას, რომელთან წვდომის საშუალებაც მათ არ უნდა ჰქონდეთ."</string>
+    <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"ეკრანის კონტენტის მოძიება"</string>
+    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"აპს შეეძლება აქტიური ფანჯრიდან კონტენტის მოძიება. მავნე აპებს შეუძლიათ ფანჯრის სრული კონტენტის მოძიება და ყველა ტექსტის წაკითხვა პაროლების გარდა."</string>
+    <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"მარტივი წვდომის დროებით გააქტიურება"</string>
+    <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"აპს შეეძლება მოწყობილობაზე გამარტივებული რეჟიმის ჩართვა. მავნე აპებს შეეძლებათ ამ რეჟიმის ჩართვა მომხმარებლის გაფრთხილების გარეშე."</string>
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"ფანჯრის ინფორმაციის მოძიება"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"აპს შეეძლება ფანჯრების მენეჯერის მეშვეობით ფანჯრების შესახებ ინფორმაციის მოპოვება. მავნე აპლიკაციებს შეეძლებათ ისეთი ინფორმაციის მოპოვება, რომელიც შიდა სისტემური მოხმარებისთვის არის განკუთვნილი."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"ღონისძიებების გაფილტვრა"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"აპლიკაციას შეეძლება რეგისტრაცია შეტანის ფილტრებისა, რომლებიც ასუფთავებენ მომხმარებლის ღონისძიების ყველა დინებას. მავნე აპმა შესაძლოა ეს ფუნქცია სისტემის UI კონტროლისთვის გამოიყენოს, მომხმარებლის ინტერვენციის გარეშე."</string>
+    <string name="permlab_magnify_display" msgid="5973626738170618775">"ეკრანის გადიდება"</string>
+    <string name="permdesc_magnify_display" msgid="7121235684515003792">"აპლიკაციას შეეძლება, შეცვალოს დისპლეის კონტენტი. მავნე აპებმა შეიძლება იმგვარად გარდაქმნან დისპლეის კონტენტი, რომ  მოწყობილობა გამოუსადეგარი გახდეს."</string>
+    <string name="permlab_shutdown" msgid="7185747824038909016">"ნაწილობრივი გამორთვა"</string>
+    <string name="permdesc_shutdown" msgid="7046500838746291775">"აქტივობების მენეჯერს გათიშვის რეჟიმში აყენებს. სრულ გათიშვას არ ახორციელებს."</string>
+    <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"აპის გადართვებისგან დაცვა"</string>
+    <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"ხელს უშლის მომხმარებლის სხვა აპზე გადართვას."</string>
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"ამჟამინდელი აპის ინფორმაციის მიღება"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="8153651434145132505">"ნებას რთავს მფლობელს, მოიპოვოს მიმდინარე აპლიკაციის და სერვისების შესახებ პირადი ინფორმაცია ეკრანის წინა პლანზე."</string>
+    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"ყველა აპის გაშვების მონიტორინგი დ კონტროლი"</string>
+    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"აპს შეეძლება სისტემის მიერ გამოძახებული აქტივობების მონიტორინგი და მართვა. მავნე აპლიკაციებს შეეძლებათ სისტემის სრული კონტროლი. ეს ნებართვა საჭროა მხოლოდ დეველოპმენტისთვის და ჩვეულებრივი მოხმარებისთის არ გამოიყენება."</string>
+    <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"პაკეტების წაშლის შესახებ შეტყობინებების გაგზავნა"</string>
+    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"აპს შეეძლება, გაგზავნოს შეტყობინება, რომ აპის პაკეტი წაიშალა. მავნე აპებმა ეს უფლება შეიძლება გამოიყენონ სხვა ნებისმიერი გაშვებული აპების შესაწყვეტად."</string>
+    <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"SMS-ით მიღებული სამაუწყებლო შეტყობინების გაგზავნა"</string>
+    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"აპს საშუალებას აძლევს გააგზავნოს შეტყობინება SMS შეტყობინების მიღების თაობაზე. მავნე აპლიკაციებში ეს ფუნქცია შეიძლება გამოყენებული იქნას SMS შეტყობინებების მიღების იმიტაციიისათვის."</string>
+    <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"WAP-PUSH-ით მიღებული სამაუწყებლო შეტყობინების გაგზავნა"</string>
+    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"აპს შეეძლება, გაგზავნოს შეტყობინება WAP PUSH შეტყობინების მიღების თაობაზე. მავნე აპებმა ეს შეიძლება გამოიყენონ MMS შეტყობინების მიღების გასაყალბებლად ან ნებისმიერი ვებგვერდის კონტენტის სახიფათო ვარიანტებით ჩუმად ჩასანაცვლებლად."</string>
+    <string name="permlab_setProcessLimit" msgid="2451873664363662666">"მიმდინარე პროცესების რაოდენობის ლიმიტი"</string>
+    <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"აპს შეეძლება, გააკონტროლოს მიმდინარე პროცესების მაქსიმალური რაოდენობა. ჩვეულებრივ აპებში არასდროს არის საჭირო."</string>
+    <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"უკანა ფონის აპის იძულებით დახურვა"</string>
+    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"აპს შეეძლება გააკონტროლოს, არის თუ არა აქტივობები ყოველთვის დასრულებული მათი უკანა ფონზე გადასვლის დროს. არასდროს არის საჭირო ჩვეულებრივ აპებში."</string>
+    <string name="permlab_batteryStats" msgid="2789610673514103364">"ელემენტის სტატისტიკის წაკითხვა"</string>
+    <string name="permdesc_batteryStats" msgid="5897346582882915114">"აპლიკაციას შეეძლება ამჟამინდელი დაბალი დამუხტვის ელემენტის გამოყენების მონაცემების წაკითხვა. აპლიკაციამ შესაძლოა მოახერხოს თქვენ მიერ გამოყენებული აპების შესახებ დეტალური ინფორმაციის მოძიება."</string>
+    <string name="permlab_updateBatteryStats" msgid="3719689764536379557">"ელემენტის სტატისტიკის შეცვლა"</string>
+    <string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"აპს შეეძლება, შეცვალოს ბატარეის გამოყენების შეგროვებული სტატისტიკა. არ გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_getAppOpsStats" msgid="1508779687436585744">"აპის სამუშაო ჟურნალის სტატისტიკის მოძიება"</string>
+    <string name="permdesc_getAppOpsStats" msgid="6243887041577912877">"აპს შეეძლება აპლიკაციათა ოპერაციების შეგროვებული სტატისტიკის მოპოვება. არ გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"აპის სამუშაო ჟურნალის სტატისტიკის შეცვლა"</string>
+    <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"აპს შეეძლება აპლიკაციის ოპერაციების შეგროვებული სტატისტიკის მოპოვება. არ გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_backup" msgid="470013022865453920">"სისტემის სარეზერვო ასლების კონტროლი და აღდგენა"</string>
+    <string name="permdesc_backup" msgid="6912230525140589891">"აპს შეეძლება სისტემის სარეზერვო ასლების კონტროლი და მექანიზმის აღდგენა. ჩვეულებრივი აპები მსგავს შესაძლებლობებს არ იყენებენ."</string>
+    <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"სრული სარეზერვო ასლების დადასტურება ან ოპერაციის აღდგენა"</string>
+    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"აპს შეეძლება გაუშვას სრული სარეზერვო ასლების UI დადასტურება. არ იყენებს არც ერთი სხვა აპი."</string>
+    <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"არაავტორიზებული ფანჯრების ჩვენება"</string>
+    <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"აპს შეეძლება, შექმნას შიდა სისტემის მომხმარებლის ინტერფეისის მიერ გამოყენებისთვის განკუთვნილი ფანჯრები. არ გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"სხვა აპების ინტერფეისზე გადაწერა"</string>
+    <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"აპს შეეძლება თავისი ინტერფეისი ზემოდან გადააწეროს სხვა აპლიკაციებს ან მომხმარებლის ინტერფეისის ნაწილებს. ამგვარად, შესაძლოა შეიცვალოს სხვა აპლიკაციის ინტერფეისი და ხელი შეგეშალოთ სხვა მასთან მუშაობისას."</string>
+    <string name="permlab_setAnimationScale" msgid="2805103241153907174">"ანიმაციის გლობალური სიჩქარის შეცვლა"</string>
+    <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"აპს შეეძლება გლობალური ანიმაციის სიჩქარის შეცვლა (სწრაფი ან ნელი ანიმაცია) ნებისმიერ დროს."</string>
+    <string name="permlab_manageAppTokens" msgid="1286505717050121370">"აპის წინასწარი გადახდის ბარათების მართვა"</string>
+    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"აპს შეეძლება, შექმნას და მართოს საკუთარი იდენტიფიკაციის ნიშნები, ჩვეულებრივი Z-წყობის უგულვებელყოფით. ჩვეულებრივი აპებისთვის მისი გამოყენება არასდროს არის საჭირო."</string>
+    <string name="permlab_freezeScreen" msgid="4708181184441880175">"ეკრანის გაყინვა"</string>
+    <string name="permdesc_freezeScreen" msgid="8558923789222670064">"აპლიკაციას შეეძლება ეკრანის დროებით გაშეშება სრულ ეკრანზე გადასასვლელად."</string>
+    <string name="permlab_injectEvents" msgid="1378746584023586600">"გასაღებზე დაჭერა და ღილაკების მართვა"</string>
+    <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"აპს შეეძლება შეყვანის საკუთარი მოვლენების (გასაღები და ა.შ.) სხვა აპებისთვის გადაცემა. მავნე აპებმა შესაძლოა ეს გამოიყენონ ტაბლეტის საკონტროლოდ."</string>
+    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"აპს შეეძლება შეყვანის საკუთარი მოვლენების (გასაღები და ა.შ.) სხვა აპებისთვის გადაცემა. მავნე აპებმა შესაძლოა ეს გამოიყენონ ტელეფონის საკონტროლოდ."</string>
+    <string name="permlab_readInputState" msgid="469428900041249234">"ჩაწერეთ რასაც ბეჭდავთ და რა ქმედებებსაც მიმართავთ."</string>
+    <string name="permdesc_readInputState" msgid="8387754901688728043">"აპს შეეძლება დაინახოს გასაღები, როდესაც მას ბეჭდავთ თუნდაც სხვა აპში მუშაობის დროს (მაგალითად, პაროლის აკრეფა). ჩვეულებრივ აპებს მსგავსი რამ არასოდეს სჭირდება."</string>
+    <string name="permlab_bindInputMethod" msgid="3360064620230515776">"შეტანის მეთოდთან დაკავშირება"</string>
+    <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"აპს შეეძლება ზედა დონის ინტერფეისის წვდომის სისტემასთან დაკავშირება. არასდროს გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"გამარტივებული წვდომის სერვისთან მიერთება"</string>
+    <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"აპს შეეძლება გამარტივებული წვდომის სერვისის ზედა დონის ინტერფეისთან დაკავშირება. არასდროს გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"ბეჭდვის სევისზე მიბმა"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"მფლობელს შეეძლება მიებას ბეჭდვის სერვისების ზედა დონის ინტერფეისს. ჩვეულებრივ აპს ეს წესით არასოდეს არ უნდა დაჭირდეს."</string>
+    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"ბეჭდვის ყველა დავალებაზე წვდომა"</string>
+    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"საშუალებას აძლევს მფლობელს იქონიოს წვდომა სხვა აპის მიერ შექმნილ ბეჭდვის დავალებებზე. ჩვეულებრივ აპს ეს წესით არასოდეს არ უნდა დაჭირდეს."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC სერვისთან შეკავშირება"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"საშუალებას აძლევს მფლობელს შეკავშირდეს აპლიკაციებთან, რომლებიც NFC ბარათების სიმულაციას ახდენს. ჩვეულებრივ აპებს უმეტეს შემთხვევაში არ დაჭირდება."</string>
+    <string name="permlab_bindTextService" msgid="7358378401915287938">"ტექსტ სერვისთან დაკავშირება"</string>
+    <string name="permdesc_bindTextService" msgid="8151968910973998670">"აპს შეეძლება ზედა დონის ინტერფეისის ტექსტური სამსახურთან (მაგ. SpellCheckerService) დაკავშირება. არასდროს გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_bindVpnService" msgid="4708596021161473255">"VPN სერვისთან დაკავშირება"</string>
+    <string name="permdesc_bindVpnService" msgid="2067845564581693905">"აპს შეეძლება Vpn სერვისის ზედა დონის ინტერფეისთან დაკავშირება. არასდროს გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_bindWallpaper" msgid="8716400279937856462">"ფონზე მიჭედება"</string>
+    <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"მფლობელს შეეძლება ფონის ზედა დონის ინტერფეისთან დაკავშირება. არასდროს გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ვიჯეტ სერვისთან დაკავშირება"</string>
+    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"აპს შეეძლება ზედა დონის ინტერფეისის ვიჯეტთან დაკავშირება. არასდროს გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"მოწყობილობის ადმინთან ინტერაქცია"</string>
+    <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"აპს შეეძლება მოწყობილობის ადმინისტრატორისთვის intent ობიექტების გაგზავნა. არასდროს გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"მოწყობილობის ადმინისტრატორს დამატება ან ამოშლა"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"საშუალებას აძლევს მფლობელს დაამატოს ან ამოშალოს მოწყობილობის აქტიური ადმინისტრატორები. ჩვეულებრივ აპებს, ალბათ, არასოდეს დაჭირდება"</string>
+    <string name="permlab_setOrientation" msgid="3365947717163866844">"ეკრანის ორიენტაციის შეცვლა"</string>
+    <string name="permdesc_setOrientation" msgid="3046126619316671476">"აპს შეეძლება, ატრიალოს ეკრანი ნებისმიერ დროს. არასდროს იქნება საჭირო ჩვეულებრივ აპებში."</string>
+    <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"მაჩვენებლის სიჩქარის შეცვლა"</string>
+    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"აპს შეეძლება, შეცვალოს მაუსის ან თრექპედის კურსორის სიჩქარე ნებისმიერ დროს. არასდროს იქნება საჭირო ჩვეულებრივ აპებში."</string>
+    <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"კლავიატურის განლაგების შეცვლა"</string>
+    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"აპს შეეძლება შეცვალოს კლავიატურის განლაგება. ეს ფუნქცია არასდროს იქნება საჭირო ჩვეულებრივ აპებში."</string>
+    <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"აპებისთვის Linux-ის სიგნალების გაგზავნა"</string>
+    <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"აპს შეეძლება მოითხოვოს უზრუნველყოფილი სიგნალის მუდმივ პროცესებისთვის გაგზავნა."</string>
+    <string name="permlab_persistentActivity" msgid="8841113627955563938">"დააყენოს აპი მუდმივად ჩართულად"</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"აპს შეეძლება, საკუთარი ნაწილები მუდმივად ჩაწეროს მეხსიერებაში. ეს შეზღუდავს მეხსიერების ხელმისაწვდომობას სხვა აპებისთვის და შეანელებს ტაბლეტს."</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"აპს შეეძლება, საკუთარი ნაწილები მუდმივად ჩაწეროს მეხსიერებაში. ეს შეზღუდავს მეხსიერების ხელმისაწვდომობას სხვა აპებისთვის და შეანელებს ტელეფონს."</string>
+    <string name="permlab_deletePackages" msgid="184385129537705938">"აპების წაშლა"</string>
+    <string name="permdesc_deletePackages" msgid="7411480275167205081">"აპს შეეძლება Android პაკეტების წაშლა. მავნე აპებმა შეიძლება გამოიყენონ მნიშვნელოვანი აპების წასაშლელად."</string>
+    <string name="permlab_clearAppUserData" msgid="274109191845842756">"სხვა აპების მონაცემების წაშლა"</string>
+    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"აპს შეეძლება მომხმარებლის მონაცემების წაშლა."</string>
+    <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"სხვა აპების ქეშის წაშლა"</string>
+    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"აპს შეეძლება ქეშის ფაილების წაშლა."</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"აპის მეხსიერების სივრცის გაზომვა"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"აპს შეეძლება, მოიპოვოს თავისი კოდი, მონაცემები და ქეშის ზომები."</string>
+    <string name="permlab_installPackages" msgid="2199128482820306924">"აპების პირდაპირი ინსტალაცია"</string>
+    <string name="permdesc_installPackages" msgid="5628530972548071284">"აპს შეეძლება Android-ის ახალი ან განახლებული პაკეტების ინსტალაცია. მავნე აპებმა შესაძლოა ეს გამოიყენონ ახალი აპების დასამატებლად თვითნებურად, მნიშვნელოვანი უფლებებით."</string>
+    <string name="permlab_clearAppCache" msgid="7487279391723526815">"ყველა აპის მონაცემთა ქეშის წაშლა"</string>
+    <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"აპს შეეძლება, გაასუფთავოს ტაბლეტის მეხსიერება სხვა აპლიკაციების ქეშის საქაღალდეებში ფაილების წაშლით. ამან შეიძლება გამოიწვიოს სხვა აპლიკაციების უფრო ნელი გაშვება, რადგანაც მათ მონაცემების ხელახლა პოვნა სჭირდებათ."</string>
+    <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"აპს შეეძლება, გაასუფთავოს ტელეფონის მეხსიერება სხვა აპლიკაციების ქეშის საქაღალდეებში ფაილების წაშლით. ამან შეიძლება გამოიწვიოს სხვა აპლიკაციების უფრო ნელი გაშვება, რადგანაც მათ მონაცემების ხელახლა პოვნა სჭირდებათ."</string>
+    <string name="permlab_movePackage" msgid="3289890271645921411">"აპის რესურსების გადატანა"</string>
+    <string name="permdesc_movePackage" msgid="319562217778244524">"აპს შეეძლება აპების რესურსსების გადატანა გარედან შიდა მეხსიერებაზე და პირიქით."</string>
+    <string name="permlab_readLogs" msgid="6615778543198967614">"ჟურნალის სენსიტიური მონაცემების წაკითხვა"</string>
+    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"აპს შეეძლება სისტემის სხვადასხვა ჟურნალის ფაილების წაკითხვა. ეს უფლებას აძლევს, გაიგოს ზოგადი ინფორმაცია იმის შესახებ, თუ რას აკეთებთ ტაბლეტზე და, პოტენციურად, პირადი ან კონფიდენციალური ინფორმაციაც."</string>
+    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"აპს შეეძლება სისტემის სხვადასხვა ჟურნალის ფაილების წაკითხვა. ეს უფლებას აძლევს, გაიგოს ზოგადი ინფორმაცია იმის შესახებ, თუ რას აკეთებთ ტელეფონზე და, პოტენციურად, პირადი ან კონფიდენციალური ინფორმაციაც."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"ნებისმიერი მედია დეკოდერის გამოყენება"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"აპს დასაკრავად შეეძლება გამოიყენოს ნებისმიერი დაყენებული მედია დეკოდერი."</string>
+    <!-- no translation found for permlab_manageCaCertificates (1678391896786882014) -->
+    <skip />
+    <!-- no translation found for permdesc_manageCaCertificates (4015644047196937014) -->
+    <skip />
+    <string name="permlab_diagnostic" msgid="8076743953908000342">"სისტემის დიაგნოსტიკის რესურსებში წაკითხვა/ჩაწერის უფლება"</string>
+    <string name="permdesc_diagnostic" msgid="6608295692002452283">"აპს შეეძლება, წაიკითხოს ან ჩაწეროს ნებისმიერ რესურსში, რომელიც დიაგნოსტიკის ჯგუფს ეკუთვნის, მაგალითად, ფაილები /dev-ში. ამან შესაძლოა იმოქმედოს სისტემის სტაბილურობასა და უსაფრთხოებაზე. მისი გამოყენება მხოლოდ მწარმოებლის ან ოპერატორის მიერ ტექნიკის სპეციფიკური დიაგნოსტიკისთვის უნდა მოხდეს."</string>
+    <string name="permlab_changeComponentState" msgid="6335576775711095931">"აპის კომპონენტების ჩართვა ან გამორთვა"</string>
+    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"აპებს საშუალებას აძლევს, შეცვალონ სხვა აპების კომპონენტები. ამ გზით მავნე აპები შეძლებენ ტაბლეტის მნიშვნელვანი ფუნქციების გათიშვას. ეს ნებართვა სიფრთხილით გამოიყენეთ, რათა შემთხვევით არ დაარღვიოთ აპლიკაციის კომპონენტების მუშაობა."</string>
+    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"აპებს საშუალებას აძლევს, შეცვალონ სხვა აპების კომპონენტები. ამ გზით მავნე აპები შეძლებენ ტელეფონის მნიშვნელვანი ფუნქციების გათიშვას. ეს ნებართვა სიფრთხილით გამოიყენეთ, რათა შემთხვევით არ დაარღვიოთ აპლიკაციის კომპონენტების მუშაობა."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"ნებართვების მიცემა ან გაუქმება"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"აპლიკაციას შეეძლება, გასცეს ან გააუქმოს განსაკუთრებული ნებართვები მისთვის ან სხვა აპლიკაციებისთვის. მავნე აპლიკაციებმა შეიძლება გამოიყენონ იმ თვისებებზე წვდომისთვის, რომლებიც მათ არ მიანიჭეთ."</string>
+    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"სასურველი აპების დაყენება"</string>
+    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"აპს შეეძლება შეცვალოს თქვენი სასურველი აპები. მავნე აპებმა ეს შესაძლოა გამოიყენონ თქვენ მიერ მოხმარებადი აპების ჩუმად შესაცვლელად, თქვენგან პირადი ინფორმაციის მოსაგროვებლად."</string>
+    <string name="permlab_writeSettings" msgid="2226195290955224730">"სისტემის პარამეტრების შეცვლა"</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"აპს შეეძლება, შეცვალოს სისტემის პარამეტრების მონაცემები. მავნე აპებს შეუძლიათ დააზიანონ თქვენი სისტემის კონფიგურაცია."</string>
+    <string name="permlab_writeSecureSettings" msgid="204676251876718288">"სისტემის უზრუნველყოფის პარამეტრების შეცვლა"</string>
+    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"აპს შეეძლება სისტემის უსაფრთხოების პარამეტრების მონაცემების შეცვლა. ამ შესაძლებლობას ჩვეულებრივი აპების არასოდეს იყენებენ."</string>
+    <string name="permlab_writeGservices" msgid="2149426664226152185">"Google სერვისების რუკის შეცვლა"</string>
+    <string name="permdesc_writeGservices" msgid="1287309437638380229">"აპს შეეძლება Google სერვისების რუკის შეცვლა. არ გამოიყენება ჩვეულებრივ აპლიკაციებში."</string>
+    <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"გაშვება სისტემის ჩართვისას"</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"აპს შეეძლება საკუთარი თავის სისტემის ჩატვირთვისას ჩართვა. ამან შეიძლება გამოიწვიოს ჩატვირთვის დროის გაზრდა და ტაბლეტის შენელება, რადგან აპი ყოველთვის ჩართული იქნება."</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="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="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="default" msgid="589869224625163558">"აპს შეეძლება, შეცვალოს თქვენ ტელეფონზე შენახული კონტაქტების მონაცემები, მათ შორის ინფორმაცია კონკრეტულ ინდივიდუალებთან თქვენი დარეკვის, ელფოსტის გაგზავნის ან კომუნიკაციის სიხშირის შესახებ. ეს ნებართვა უფლებას აძლევს აპებს, წაშალოს საკონტაქტო მონაცემები. "</string>
+    <string name="permlab_readCallLog" msgid="3478133184624102739">"ზარების ჟურნალის წაკითხვა"</string>
+    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"აპს შეეძლება თქვენი ტაბლეტის გამავალი და შემომავალი ზარების ჟურნალის ნახვა, ასევე ექნება ამ ჟურნალის შენახვის უფლება. ეს მავნე აპლიკაციებს საშუალებას მისცემს ნებართვის გარეშე გააზიარონ თქვენი ზარების ჟურნალი."</string>
+    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"აპს შეეძლება თქვენი ტელეფონის გამავალი და შემომავალი ზარების ჟურნალის ნახვა, ასევე ექნება ამ ჟურნალის შენახვის უფლება. ეს მავნე აპლიკაციებს საშუალებას მისცემს ნებართვის გარეშე გააზიარონ თქვენი ზარების ჟურნალი."</string>
+    <string name="permlab_writeCallLog" msgid="8552045664743499354">"ზარების ჟურნალში ჩაწერა"</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"აპს შეეძლება, შეცვალოს თქვენი ტაბლეტის ზარების ჟურნალი, მათ შორის შემომავალი და გამავალი ზარების მონაცემები. მავნე აპებმა შეიძლება გამოიყენონ ეს თქვენი ზარების ჟურნალის წასაშლელად ან შესაცვლელად."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"აპს შეეძლება, შეცვალოს თქვენი ტელეფონის ზარების ჟურნალი, მათ შორის შემომავალი და გამავალი ზარების მონაცემები. მავნე აპებმა შეიძლება გამოიყენონ ეს თქვენი ზარების ჟურნალის წასაშლელად ან შესაცვლელად."</string>
+    <string name="permlab_readProfile" msgid="4701889852612716678">"თქვენი საკონტაქტო ინფორმაციის ნახვა"</string>
+    <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"აპს შეეძლება მოწყობილობაზე შენახული პირადი პროფილის ინფორმაციის წაკითხვა, მაგალითად, თქვენი სახელისა და საკონტაქტო ინფორმაციის. ეს ნიშნავს, რომ აპს შეუძლია თქვენი იდენტიფიცირება და თქვენი პირადი ინფორმაციის სხვებისთვის გაგზავნა."</string>
+    <string name="permlab_writeProfile" msgid="907793628777397643">"თქვენი საკონტაქტო ინფორმაციის შეცვლა"</string>
+    <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"აპს შეეძლება მოწყობილობაზე შენახული პირადი პროფილის ინფორმაციის შეცვლა ან დამატება, მაგალითად, თქვენი სახელისა და საკონტაქტო ინფორმაციის. ეს ნიშნავს, რომ აპს შეუძლია თქვენი იდენტიფიცირება და თქვენი პირადი ინფორმაციის სხვებისთვის გაგზავნა."</string>
+    <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"სოციალური ნაკადის წაკითხვა"</string>
+    <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"აპს შეეძლება თქვენი და თქვენი მეგობრების სოციალური განახლებებთან წვდომა და სინქრონიზაცია. ინფორმაციის გაზიარებისას იყავით ფრთხიად - აპს ექნება შესაძლებლობა, რომ წაიკითხოს სოციალურ ქსელებში კომუნიკაცია თქვენსა და თქვენს მეგობრებს შორის კონფიდენციალურობის მიუხედავად. შენიშვნა: ეს უფლება შესაძლოა ვერ იყოს გამოყენებული ყველა სოციალურ ქსელში."</string>
+    <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"თქვენს სოციალურ მაუწყებლობაზე დაწერა"</string>
+    <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"აპს შეეძლება, გიჩვენოთ თქვენი მეგობრების სოციალური სიახლეები. ფრთხილად იყავით ინფორმაციის გაზიარებისას - აპს შეუძლია შექმნას შეტყობინება, რომელიც თითქოსდა მეგობრისგან არის მოწერილი. შენიშვნა: ეს ნებართვა არ შეიძლება შესრულდეს ყველა სოციალურ ქსელში."</string>
+    <string name="permlab_readCalendar" msgid="5972727560257612398">"კალენდრის ღონისძიებებისა და კონფიდენციალური ინფორმაციის წაკითხვა"</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"აპს შეეძლება, წაიკითხოს თქვენ ტაბლეტზე შენახული კალენდრის ყველა მოვლენა, მათ შორის მეგობრებისა და თანამშრომლების მოვლენებიც. ამან შეიძლება უფლება მისცეს აპს, გააზიაროს ან შეინახოს თქვენი კალენდრის მონაცემები, მიუხედავად კონფიდენციალურობისა თუ მგრძობიარობისა."</string>
+    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"აპს შეეძლება, წაიკითხოს თქვენს ტელეფონზე შენახული კალენდრის ყველა მოვლენა, მათ შორის მეგობრებისა და თანამშრომლების მოვლენებიც. ამან შეიძლება უფლება მისცეს აპს, გააზიაროს ან შეინახოს თქვენი კალენდრის მონაცემები, მიუხედავად კონფიდენციალურობისა თუ მგრძობიარობისა."</string>
+    <string name="permlab_writeCalendar" msgid="8438874755193825647">"კალენდრის ღონისძიებების დამატება და შეცვლა და მფლობელის გარეშე ელფოსტის გაგზავნა სტუმრებთან."</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"აპს შეეძლება იმ ღონისძიებების დამატება, წაშლა და შეცვლა, რომლებსაც თქვენს ტაბლეტზე ქმნით, ასევე თქვენი მეგობრების და თანამშრომლების ღონისძიებებიც. ამგვარად, აპს ექნება შესაძლებლობა ისე დააგზავნოს შეტყობინებები კალენდრის მფლობელის სახელით ან შეცვალოს ღონისძიებები, რომ მფლობელმა ამის შესახებ არაფერი იცოდეს."</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"აპს შეეძლება იმ ღონისძიებების დამატება, წაშლა და შეცვლა, რომლებსაც თქვენს ტელეფონზე ქმნით, ასევე თქვენი მეგობრების და თანამშრომლების ღონისძიებებიც. ამგვარად, აპს ექნება შესაძლებლობა ისე დააგზავნოს შეტყობინებები კალენდრის მფლობელის სახელით ან შეცვალოს ღონისძიებები, რომ მფლობელმა ამის შესახებ არაფერი იცოდეს."</string>
+    <string name="permlab_accessMockLocation" msgid="8688334974036823330">"მდებარეობის წყაროების იმიტირება ტესტირებისთვის"</string>
+    <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"აპს შეეძლება ტესტირებისთვის ყალბი ლოკაციების შექმნა, ან მდებარეობის ახალი პროვაიდერის დაყენება. ეს უფლებას მისცემს აპს, შეცვალოს მდებარეობის სხვა წყაროების მიერ, მაგ. GPS  ან მდებარეობის პროვაიდერების მიერ მოწოდებული მდებარეობა და/ ან სტატუსი."</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"მდებარეობის პროვაიდერის დამატებით ბრძანებებზე წვდომა"</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"აპს შეეძლება წვდომა ჰქონდეს მდებარეობის სერვისის დამატებით ბრძანებებზე. შესაძლოა აპმა ეს გამოიყენოს GPS-ისა და მდებარეობის სხვა წყაროების მუშაობის პროცესში ჩარევისთვის."</string>
+    <string name="permlab_installLocationProvider" msgid="6578101199825193873">"მდებარეობის პროვაიდერის ინსტალაციის უფლება"</string>
+    <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"აპს შეეძლება ტესტირებისთვის ყალბი ლოკაციების შექმნა, ან მდებარეობის ახალი პროვაიდერის დაყენება. აპს საშუალება მიეცემა გადააკეთოს სხვა წყაროების მაგ.: GPS ან მდებარეობის პროვაიდერების მოწოდებული მდებარეობა ან/და სტატუსი."</string>
+    <string name="permlab_accessFineLocation" msgid="1191898061965273372">"ზუსტი მდებარეობა (GPS და ქსელის კოორდინატების მიხედვით)"</string>
+    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"აძლევს აპს უფლებას მოიპოვოს ზუსტი მდებარეობა გლობალური პოზიციონირების სისტემის (GPS) გამოყენებით ან ქსელის მდებარეობის წყაროს მიხედვით, როგორიცაა ქსელის ანძები და Wi-Fi. მდებარეობის ეს სერვისები ჩართული უნდა იყოს და თქვენს მოწყობილობაზე აპისთვის მისაწვდომი, რათა შეძლოს მათი გამოყენება. აპებში შესაძლებელია მათი გამოყენება თქვენი მდებარეობის განსასაზღვრად და ამან ელემენტის დამატებითი ხარჯვა შეიძლება გამოიწვიოს."</string>
+    <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"სავარაუდო (ქსელის კოორდინატების მიხედვით) მდებარეობა"</string>
+    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"აპს შეეძლება გაიგოს თქვენი სავარაუდო მდებარეობა. ის გამოითვლება მდებარეობის სერვისის მიერ ქსელის მონაცემების - მობილური კავშირგაბმულობის ანძებისა და Wi-Fi-ის მიხედვით. ეს სერვისები ჩართული უნდა იყოს თქვენს მოწყობილობაზე, ხოლო აპებს უნდა ჰქონდეთ მათი გამოყენების უფლება. აპები მათი მონაცემების მიხედვით სავარაუდო მდებარეობის გამოთვლას შეძლებენ."</string>
+    <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"SurfaceFlinger-ზე წვდომა"</string>
+    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"აპს შეეძლება, გამოიყენოს SurfaceFlinger-ის დაბალი დონის ელემენტები."</string>
+    <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"ჩარჩოს ბუფერის წაკითხვა"</string>
+    <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"აპს შეეძლება წაიკითხოს ბუფერული ჩარჩოს კონტენტი."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"InputFlinger-ზე წვდომა"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"აპს შეეძლება, გამოიყენოს InputFlinger-ის დაბალი დონის ფუნქციები."</string>
+    <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Wifi ეკრანის კონფიგურაცია"</string>
+    <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"აპს შეეძლება Wifi ეკრანებთან დაკავშირება და დაკონფიგურირება."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wifi ეკრანების მართვა"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"აპს შეეძლება აკონტროლოს Wifi ეკრანების დაბალი დონის ფუნქციები."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"გამომავალი აუდიოს დაჭერა"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"საშუალებას აძლევს აპს დაიჭიროს და გადაამისამართოს გამომავალი აუდიო."</string>
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"გამომავალი ვიდეოს დაჭერა"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"საშუალებას აძლევს აპს დაიჭიროს და გადაამისამართოს გამომავალი ვიდეო."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"გამომავალი დაცული ვიდეოს დაჭერა"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"საშუალებას აძლევს აპს დაიჭიროს და გადაამისამართოს გამომავალი დაცული ვიდეო."</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="4906839301087980680">"აპს შეეძლება აუდიო ჩაწერა მიკროფონით. ნებართვა აპს აუდიო ჩაწერის უფლებას აძლევს ნებისმიერ დროს, თქვენი თანხმობის გარეშე."</string>
+    <string name="permlab_camera" msgid="3616391919559751192">"სურათებისა და ვიდეოების გადაღება"</string>
+    <string name="permdesc_camera" msgid="8497216524735535009">"აპს შეეძლება კამერით სურათისა და ვიდეოს გადაღება. ეს ნებართვა აპს უფლებას აძლევს, ნებისმიერ დროს გამოიყენოს კამერა თქვენი დადასტურების გარეშე."</string>
+    <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"კამერის გამოყენებისას გადამცემი ინდიკატორის LED გათიშვა"</string>
+    <string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"ნებას რთავს წინასწარ დაყენებული სისტემის აპლიკაციას, გამორთოს კამერის გამოყენების ინდიკატორი LED."</string>
+    <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"მუდმივად გამორთული ტაბლეტი"</string>
+    <string name="permlab_brick" product="default" msgid="8337817093326370537">"ტელეფონის სამუდამოდ დეაქტივაცია"</string>
+    <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"აპს შეეძლება მთელი ტაბლეტის სამუდამოდ გათიშვა. ეს ძალიან სახიფათოა."</string>
+    <string name="permdesc_brick" product="default" msgid="5788903297627283099">"აპს შეეძლება მთელი ტელეფონის სამუდამოდ გათიშვა. ეს ძალიან სახიფათოა."</string>
+    <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"ტაბლეტის გადატვირთვის იძულება"</string>
+    <string name="permlab_reboot" product="default" msgid="2898560872462638242">"ტელეფონის გადატვირთვის იძულება"</string>
+    <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"აპს შეეძლება ტაბლეტის იძულებითი გადატვირთვა."</string>
+    <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"აპს შეეძლება მოწყობილობის იძულებითი გადატვირთვა."</string>
+    <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"UBS ბარათის ფაილურ სისტემაზე წვდომა"</string>
+    <string name="permlab_mount_unmount_filesystems" product="default" msgid="4402305049890953810">"SD ბარათის ფაილურ სისტემაზე წვდომა"</string>
+    <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"აპს შეეძლება, მიუერთოს და გამოაერთოს ფაილების სისტემები მოსახსნელი მეხსიერებისთვის."</string>
+    <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"USB მეხსიერების წაშლა"</string>
+    <string name="permlab_mount_format_filesystems" product="default" msgid="262582698639274056">"SD ბარათის წაშლა"</string>
+    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"აპს შეეძლება, დააფორმატოს მოსახსნელი მეხსიერება."</string>
+    <string name="permlab_asec_access" msgid="3411338632002193846">"შიდა მეხსიერების შესახებ ინფორმაციის მიღება"</string>
+    <string name="permdesc_asec_access" msgid="3094563844593878548">"აპს შეეძლება, მიიღოს ინფორმაცია შიდა მეხსიერებაზე."</string>
+    <string name="permlab_asec_create" msgid="6414757234789336327">"შიდა მეხსიერების შექმნა"</string>
+    <string name="permdesc_asec_create" msgid="4558869273585856876">"აპს შეეძლება მეხსიერების შიდა საცავის შექმნა."</string>
+    <string name="permlab_asec_destroy" msgid="526928328301618022">"შიდა მეხსიერების განადგურება"</string>
+    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"აპს შეეძლება შიდა მეხსიერების განადგურება."</string>
+    <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"შიდა მეხსიერების მიერთება/გამოერთება"</string>
+    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"აპს შეეძლება შიდა მეხსიერების მიერთება / გამოერთება."</string>
+    <string name="permlab_asec_rename" msgid="7496633954080472417">"შიდა მეხსიერებისთვის სახელის გადარქმევა"</string>
+    <string name="permdesc_asec_rename" msgid="1794757588472127675">"აპს შეეძლება შიდა მეხსიერებისთვის სახელის გადარქმევა."</string>
+    <string name="permlab_vibrate" msgid="7696427026057705834">"ვიბრაციის კონტროლი"</string>
+    <string name="permdesc_vibrate" msgid="6284989245902300945">"აპს შეეძლება, მართოს ვიბრირება."</string>
+    <string name="permlab_flashlight" msgid="2155920810121984215">"სასიგნალო შუქის მართვა"</string>
+    <string name="permdesc_flashlight" msgid="6522284794568368310">"აპს შეეძლება, მართოს განათება."</string>
+    <string name="permlab_manageUsb" msgid="1113453430645402723">"USB მოწყობილობების უფლებებისა და სასურველი პარამეტრების მართვა"</string>
+    <string name="permdesc_manageUsb" msgid="7776155430218239833">"აპს შეეძლება USB მოწყობილობების პარამეტრებისა და ნებართვების მართვა."</string>
+    <string name="permlab_accessMtp" msgid="4953468676795917042">"MTP პროტოკოლის დანერგვა"</string>
+    <string name="permdesc_accessMtp" msgid="6532961200486791570">"ანიჭებს წვდომას kernel MTP დრაივერს MTP USB პროტოკოლის იმპლემენტაციისთვის."</string>
+    <string name="permlab_hardware_test" msgid="4148290860400659146">"აპარატურული აღჭურვილობის ტესტირება"</string>
+    <string name="permdesc_hardware_test" msgid="6597964191208016605">"აპს შეეძლება, მართოს სხვადასხვა პერიფერიული მოწყობილობა აპარატურის ტესტირების მიზნით."</string>
+    <string name="permlab_callPhone" msgid="3925836347681847954">"პირდაპირი დარეკვა ტელეფონის ნომრებზე"</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"აპს შეეძლება დარეკოს ტელეფონის ნომრებზე თქვენი ჩარევის გარეშე. ამან შესაძლოა გამოიწვიოს თქვენს სატელეფონი ქვითარზე მოულოდნელი ხარჯებისა და ზარების გაჩენა. გაითვალისწინეთ, რომ აპს გადაუდებელი დახმარების ნომრებზე დარეკვა არ შეუძლია. მავნე აპებს შეეძლება თქვენი დადასტურების გარეშე ზარების განხორციელება და შესაბამისი საფასურის გადახდაც მოგიწევთ."</string>
+    <string name="permlab_callPrivileged" msgid="4198349211108497879">"პირდაპირი დარეკვა ტელეფონის ნებისმიერ ნომერზე"</string>
+    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"აპს შეეძლება თქვენი მონაწილეობის გარეშე დარეკოს ნებისმიერ ტელეფონის ნომერზე, მათ შორის საგანგებო ნომრებზე. მავნე აპები შეძლებენ არასასურველი ან უკანონო ზარების საგანგებო სამსახურების სიებში განთავსებას."</string>
+    <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"CDMA ტაბლეტის დაყენების პირდაპირ დაწყება"</string>
+    <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"CDMA ტელეფონის დაყენების პირდაპირ დაწყება"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"აპს შეეძლება, დაიწყოს CDMA უზრუნველყოფა. მავნე აპებმა შეიძლება ზედმეტად, საჭიროების გარეშე დაიწყონ CDMA უზრუნველყოფა."</string>
+    <string name="permlab_locationUpdates" msgid="7785408253364335740">"მდებარეობის განახლების შეტყობინებების კონტროლი"</string>
+    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"აპს შეეძლება მდებარეობის განახლების შესახებ რადიო შეტყობინებების აქტივაცია/დეაქტივაცია. ჩვეულებრივი აპები ამ ფუნქციას არ იყენებენ."</string>
+    <string name="permlab_checkinProperties" msgid="7855259461268734914">"სარეგისტრაციო პარამეტრებზე წვდომა"</string>
+    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"აპებს შეეძლებათ რეგისტრაციის სამსახურის მეშვეობით დამატებული თვისებების წასაკითხად ან ჩასაწერად წვდომა. არ გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_bindGadget" msgid="776905339015863471">"ვიჯეტების არჩევა"</string>
+    <string name="permdesc_bindGadget" msgid="8261326938599049290">"აპს შეეძლება უთხრას სისტემას, თუ რომელმა აპმა რომელი ვიჯეტი შეიძლება გამოიყენოს. ამ ნებართვის მქონე აპს შეუძლია, პირად მონაცემებზე წვდომა მისცეს სხვა აპებს. არ გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"ტელეფონის მდგომარეობის შეცვლა"</string>
+    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"აპს შეეძლება აკონტროლოს მოწყობილობაზე ტელეფონის ფუნქციები. ამ უფლების მქონე აპს შეუძლია ქსელების გადართვა, ტელეფონის რადიოს ჩართვა და გამორთვა, მომხმარებლისათვის შეტყობინების გარეშე."</string>
+    <string name="permlab_readPhoneState" msgid="9178228524507610486">"ტელეფონის სტატუსისა და იდენტობის წაკითხვა"</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"აპს შეეძლება ჰქონდეს წვდომა მოწყობილობის სატელეფონო ფუნქციებზე. აპმა მსგავსი უფლებით შეძლებს დაადგინოს ტელეფონის ნომერი, მისი სერიული გამოცემა, აქტიური ზარი, დაკავშირებული ნომერი და მსგავსი."</string>
+    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"დაიცავით ტაბლეტი დაძინებისგან"</string>
+    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"ტელეფონის ძილის რეჟიმში გადასვლის აღკვეთა"</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"აპს შეეძლება ხელი შეუშალოს ტაბლეტის დაძინებას."</string>
+    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"აპს შეეძლება ხელი შეუშალოს ტელეფონის დაძინებას."</string>
+    <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"ტაბლეტის ჩართვა ან გამორთვა"</string>
+    <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"ტელეფონის ჩართვა ან გამორთვა"</string>
+    <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"აპს შეეძლება, ჩართოს ან გამორთოს ტაბლეტი."</string>
+    <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"აპს შეეძლება, ჩართოს ან გამორთოს ტელეფონი."</string>
+    <string name="permlab_factoryTest" msgid="3715225492696416187">"ქარხნულ სატესტო რეჟიმში გაშვება"</string>
+    <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"მწარმოებლის დაბალი დონის ტესტის რეჟიმში გაშვება, რომლის დროსაც სრულად არის ხელმისაწვდომი ტაბლეტის აპარატული უზრუნველყოფა. ხელმისაწვდომია მხოლოდ მწარმოებლის ტესტის რეჟიმში ჩართულ ტაბლეტზე."</string>
+    <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"მწარმოებლის დაბალი დონის ტესტის რეჟიმში გაშვება, რომლის დროსაც სრულად არის ხელმისაწვდომი ტელეფონის აპარატული უზრუნველყოფა. ხელმისაწვდომია მხოლოდ მწარმოებლის ტესტის რეჟიმში ჩართულ ტელეფონზე."</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_masterClear" msgid="2315750423139697397">"სისტემის დაბრუნება ქარხნულ ნაგულისხმევ მდგომარეობაში"</string>
+    <string name="permdesc_masterClear" msgid="3665380492633910226">"აპს შეეძლება, სისტემა სრულად გადაყენოს ქარხნულ პარამეტრებზე და წაშალოს ყველა მონაცემი, კონფიგურაცია და დაყენებული აპები."</string>
+    <string name="permlab_setTime" msgid="2021614829591775646">"დროის დაყენება"</string>
+    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"აპს შეეძლება ტაბლეტის საათის დროის შეცვლა."</string>
+    <string name="permdesc_setTime" product="default" msgid="1855702730738020">"აპს შეეძლება ტელეფონის საათის დროის შეცვლა."</string>
+    <string name="permlab_setTimeZone" msgid="2945079801013077340">"დროის სარტყლის დაყენება"</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"აპს შეეძლება, შეცვალოს ტაბლეტის დროის სარტყელი."</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"აპს შეეძლება ტელეფონის დროის სარტყელის შეცვლა."</string>
+    <string name="permlab_accountManagerService" msgid="4829262349691386986">"იმოქმედეთ როგორც AccountManagerService"</string>
+    <string name="permdesc_accountManagerService" msgid="1948455552333615954">"აპს შეეძლება განახორციელოს ზარები AccountAuthenticators-ზე."</string>
+    <string name="permlab_getAccounts" msgid="1086795467760122114">"მოწყობილობაზე ანგარიშების მოძიება"</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"აპს შეეძლება, მიიღოს ტაბლეტისთვის ცნობილი ანგარიშების სია. ეს შეიძლება მოიცავდეს ნებისმიერ ანგარიშს, რომელიც თქვენ მიერ დაყენებული აპლიკაციებით შეიქმნა."</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"აპს შეეძლება, მიიღოს ტელეფონისთვის ცნობილი ანგარიშების სია. ეს შეიძლება მოიცავდეს ნებისმიერ ანგარიშს, რომელიც თქვენ მიერ დაყენებული აპლიკაციებით შეიქმნა."</string>
+    <string name="permlab_authenticateAccounts" msgid="5265908481172736933">"ანგარიშების შექმნა და პაროლების დაყენება"</string>
+    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"აპს შეეძლება ანგარიშების მენეჯერის ავტორიზაციის შესაძლებლობების გამოყენება. მათ შორის ანგარიშების შექმნა და მათთვის პაროლების მიღება და დაყენება."</string>
+    <string name="permlab_manageAccounts" msgid="4983126304757177305">"ანგარიშების დამატება ან წაშლა"</string>
+    <string name="permdesc_manageAccounts" msgid="8698295625488292506">"აპს შეეძლება ისეთი ოპერაციების განხორციელება, როგორიცაა ანგარიშების დამატება და წაშლა, ასევე მათი პაროლების წაშლაც."</string>
+    <string name="permlab_useCredentials" msgid="235481396163877642">"მოწყობილობაზე ანგარიშების გამოყენება"</string>
+    <string name="permdesc_useCredentials" msgid="7984227147403346422">"აპს შეეძლება, მოითხოვოს ავტორიზაციის საიდენტიფიკაციო ნიშნები."</string>
+    <string name="permlab_accessNetworkState" msgid="4951027964348974773">"ქსელის კავშირების ნახვა"</string>
+    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"აპს შეეძლება ქსელის კავშირის შესახებ ინფორმაციის ნახვა, მაგ. რომელი ქსელები არსებობს და რომელია დაკავშირებული."</string>
+    <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"ქსელზე სრული წვდომა"</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"აპს შეეძლება შექმნას ქსელური ბუდეები და გამოიყენოს მორგებული ქსელის პროტოკოლები. ბრაუზერი და სხვა აპლიკაციები უზრუნველყოფს ინტერნეტში მონაცემების გაგზავნის საშუალებას, ამგვარად ეს უფლება ინფორმაციის გასაგზავნად საჭირო არაა."</string>
+    <string name="permlab_writeApnSettings" msgid="505660159675751896">"ქსელის პარამეტრებისა და ტრაფიკის შეცვლა / შეწყვეტა"</string>
+    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"აპს შეეძლება ქსელის პარამეტრების შეცვლა, მთელი ქსელის ტრაფიკის შეწყვეტა და ინსპექტირება, მაგალითად, ნებისმიერი APN-ის პორტისა და პროქსის შეცვლა. მავნე აპებს შეეძლებათ ქსელის პაკეტების მონიტორინგი, გადამისამართება ან შეცვლა თქვენთვის შეტყობინების გარეშე."</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_changeBackgroundDataSetting" msgid="1400666012671648741">"ფონური მონაცემების გამოყენების პარამეტრების შეცვლა"</string>
+    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"აპს შეეძლება, შეცვალოს უკანა ფონის მონაცემების გამოყენების პარამეტრები."</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="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="default" msgid="8931682159331542137">"აპს შეეძლება ტელეფონის ადგილობრივი Bluetooth პარამეტრების დაყენება და დისტანციური მოწყობილობების აღმოჩენა და დაწყვილება."</string>
+    <string name="permlab_accessWimaxState" msgid="4195907010610205703">"WiMAX-თან დაკავშირება და კავშირის გაწყვეტა"</string>
+    <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"აპს შეეძლება განსაზღვროს, WiMAX არის თუ არა ჩართული და ასევე ინფორმაცია ნებისმიერი დაკავშირებული WiMAX ქსელის შესახებ."</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"WiMAX მდგომარეობის შეცვლა"</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"აპს შეეძლება, დაუკავშიროს და გამოაერთოს ტაბლეტი 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="default" msgid="3207106324452312739">"აპს შეეძლება, ნახოს Bluetooth-ის კონფიგურაცია ტელეფონზე და შექმნას და მიიღოს კავშირები დაწყვილებულ მოწყობილობებთან."</string>
+    <string name="permlab_nfc" msgid="4423351274757876953">"ახლო მოქმედების რადიოკავშირი (NFC) მართვა"</string>
+    <string name="permdesc_nfc" msgid="7120611819401789907">"აპს შეეძლება ახლო მოქმედების რადიოკავშირის (NFC) მეშვეობით ტეგების, ბარათებისა და წამკითხველების შემცველი მონაცემების მიმოცვლა."</string>
+    <string name="permlab_disableKeyguard" msgid="3598496301486439258">"თქვენი ეკრანის ბლოკის გათიშვა"</string>
+    <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"შეეძლება კლავიატურის დაბლოკვისა და პაროლით უზრუნველყოფილი ნებისმიერი უსაფრთხოების ფუნქციის დეაქტივაცია. მაგალითად, ტელეფონი შემომავალი ზარის დროს აუქმებს კლავიატურის დაბლოკვას და კვლავ ააქტიურებს მას, როგორც კი ზარი დასრულდება."</string>
+    <string name="permlab_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="permlab_readSyncStats" msgid="7396577451360202448">"სინქრონიზაციის სტატისტიკების წაკითხვა"</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"აპს შეეძლება ანგარიშის სინქრონიზაციის სტატისტიკის, მათ შორის სინქრონიზაციის მოვლენების ისტორიისა და სინქრონიზაციისას გადაცემული მონაცემების რაოდენობის წაკითხვა."</string>
+    <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"გამოწერილი არხების წაკითხვა"</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"აპს შეეძლება ინფორმაციის მოპოვება ბოლოს სინქრონიზებული არხების შესახებ."</string>
+    <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"გამოწერილი არხების შეცვლა"</string>
+    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"აპს შეეძლება თქვენი ამჟამინდელი სინქრონიზებული არხების შეცვლა. მავნე აპებმა შესაძოა შეცვალონ თქვენი სინქრონიზებული არხები."</string>
+    <string name="permlab_readDictionary" msgid="4107101525746035718">"ლექსიკონში თქვენი დამატებული ტერმინების ნახვა"</string>
+    <string name="permdesc_readDictionary" msgid="659614600338904243">"აპს შეეძლება წაიკითხოს ყველა სიტყვა, სახელი და ფრაზა, რომელიც შეიძლება მომხმარებელმა შეიტანა მომხმარებლის ლექსიკონში."</string>
+    <string name="permlab_writeDictionary" msgid="2183110402314441106">"მომხმარებლისთვის განკუთვნილ ლექსიკონში სიტყვების დამატება."</string>
+    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"აპს შეეძლება ახალი სიტყვების დამატება მომხმარებლის ლექსიკონში."</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"დაცულ მეხსიერებაზე საცდელი წვდომა"</string>
+    <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"დაცულ მეხსიერებაზე საცდელი წვდომა"</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"აპს შეეძლება, მიაწოდოს USB მეხსიერებას ნებართვა, რომლებიც შემდგომ სხვა მოწყობილობებზეც იქნება ხელმისაწვდომი."</string>
+    <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"აპს შეეძლება 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_mediaStorageWrite" product="default" msgid="6859839199706879015">"შიდა მედია მეხსიერების კონტენტის შეცვლა/წაშლა"</string>
+    <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"აპლიკაციას შეეძლება შიდა მედია მეხსიერების კონტენტის შეცვლა."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"დოკუმენტების საცავის მართვა"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"აპს შეეძლება დოკუმენტების საცავის მართვა."</string>
+    <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"ყველა მომხმარებლის გარე მეხსიერებაზე წვდომა"</string>
+    <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"აპს შეეძლება ყველა მომხმარებლის გარე მეხსიერებასთან წვდომა."</string>
+    <string name="permlab_cache_filesystem" msgid="5656487264819669824">"ქეშის ფაილურ სისტემაზე წვდომა"</string>
+    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"აპებს აძლევს ქეშირებული სისტემური ფაილების წაკითხვისა და მათში ჩანაწერების გაკეთების საშუალებას."</string>
+    <string name="permlab_use_sip" msgid="5986952362795870502">"ინტერნეტ-ზარების წამოწყება/მიღება"</string>
+    <string name="permdesc_use_sip" msgid="4717632000062674294">"აპს შეეძლება, გამოიყენოს SIP სერვისი ინტერნეტ ზარების განსახორციელებლად / საპასუხოდ."</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_markNetworkSocket" msgid="3658527214914959749">"სოკეტის ნიშნების შეცვლა"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"საშუალებას აძლევს აპს შეცვალოს მარშრუტიზაციის სოკეტის ნიშნები"</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_invokeCarrierSetup" msgid="3699600833975117478">"ოპერატორის მიერ მოწოდებული კოფიგურაციის აპის გამოხმობა"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"საშუალებას აძლევს მფლობელს გამოიწვიოს ოპერატორის მიერ მოწოდებული კონფიგურაციის აპი. ჩვეულებრივ აპს ეს წესით არასოდეს არ უნდა დაჭირდეს."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"განხორციელდეს ქსელის მდგომარეობის მონიტორინგი"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"საშუალებას აძლევს აპლიკაციებს განახორციელოს ქსელის მდგომარეობის მონიტორინგი. ეს ფუნქცია ჩვეულებრივ აპებს არ ჭირდება."</string>
+    <string name="policylab_limitPassword" msgid="4497420728857585791">"პაროლის წესების დაყენება"</string>
+    <string name="policydesc_limitPassword" msgid="3252114203919510394">"გააკონტროლეთ ეკრანის განბლოკვის პაროლში დაშვებული სიმბოლოები და მისი სიგრძე."</string>
+    <string name="policylab_watchLogin" msgid="914130646942199503">"ეკრანის განბლოკვის მცდელობების გაკონტროლება"</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"ეკრანის განბლოკვისთვის არასწორად აკრეფილი პაროლების რაოდენობის მონიტორინგი. ტაბლეტის დაბლოკვა ან მასზე არსებული ყველა მონაცემის წაშლა ძალიან ბევრჯერ არასწორი პაროლის შეყვანის შემთხვევაში."</string>
+    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"ეკრანის განბლოკვისთვის არასწორად აკრეფილი პაროლების რაოდენობის მონიტორინგი. ტელეფონის დაბლოკვა ან მასზე არსებული ყველა მონაცემის წაშლა ძალიან ბევრჯერ არასწორი პაროლის შეყვანის შემთხვევაში."</string>
+    <string name="policylab_resetPassword" msgid="2620077191242688955">"ეკრანის განბლოკვის პაროლის შეცვლა"</string>
+    <string name="policydesc_resetPassword" msgid="605963962301904458">"შეცვალეთ ეკრანის განბლოკვის პაროლი."</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="default" msgid="5096895604574188391">"ტელეფონის მონაცემების გაუფრთხილებლად წაშლა, ქარხნული მონაცემების აღდგენით"</string>
+    <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"მოწყობილობის გლობალური პროქსის დაყენება"</string>
+    <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"დააყენეთ მოწყობილობა გლობალურ პროქსის სერვერის გამოსაყენებლად, როდესაც დებულება გააქტიურებულია. მხოლოდ მოწყობილობის პირველი ადმინი აყენებს ეფექტურ გლობალურ პროქსი სერვერს."</string>
+    <string name="policylab_expirePassword" msgid="885279151847254056">"ეკრანის პაროლის ვადის დაყენება"</string>
+    <string name="policydesc_expirePassword" msgid="1729725226314691591">"გააკონტროლეთ, თუ რამდენად ხშირად უნდა შეიცვალოს ეკრანის დაბლოკვის პაროლი."</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="policylab_disableKeyguardFeatures" msgid="266329104542638802">"დაბლოკვის ფუნქციების გათიშვა"</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="3467082272186534614">"დაბლოკვისას ზოგიერთი ფუნქციის გამოყენების თავიდან აცილება."</string>
+  <string-array name="phoneTypes">
+    <item msgid="8901098336658710359">"სახლი"</item>
+    <item msgid="869923650527136615">"მობილური"</item>
+    <item msgid="7897544654242874543">"სამსახური"</item>
+    <item msgid="1103601433382158155">"სამსახურის ფაქსი"</item>
+    <item msgid="1735177144948329370">"სახლის ფაქსი"</item>
+    <item msgid="603878674477207394">"პეიჯერი"</item>
+    <item msgid="1650824275177931637">"სხვა"</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>
+  </string-array>
+  <string-array name="postalAddressTypes">
+    <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="1359644565647383708">"სამსახური"</item>
+    <item msgid="7868549401053615677">"სხვა"</item>
+    <item msgid="3145118944639869809">"მორგებული"</item>
+  </string-array>
+  <string-array name="organizationTypes">
+    <item msgid="7546335612189115615">"სამსახური"</item>
+    <item msgid="4378074129049520373">"სხვა"</item>
+    <item msgid="3455047468583965104">"მორგებული"</item>
+  </string-array>
+  <string-array name="imProtocols">
+    <item msgid="8595261363518459565">"AIM"</item>
+    <item msgid="7390473628275490700">"Windows Live"</item>
+    <item msgid="7882877134931458217">"Yahoo"</item>
+    <item msgid="5035376313200585242">"Skype"</item>
+    <item msgid="7532363178459444943">"QQ"</item>
+    <item msgid="3713441034299660749">"Google Talk"</item>
+    <item msgid="2506857312718630823">"ICQ"</item>
+    <item msgid="1648797903785279353">"Jabber"</item>
+  </string-array>
+    <string name="phoneTypeCustom" msgid="1644738059053355820">"მორგებული"</string>
+    <string name="phoneTypeHome" msgid="2570923463033985887">"სახლი"</string>
+    <string name="phoneTypeMobile" msgid="6501463557754751037">"მობილური"</string>
+    <string name="phoneTypeWork" msgid="8863939667059911633">"სამსახური"</string>
+    <string name="phoneTypeFaxWork" msgid="3517792160008890912">"სამსახურის ფაქსი"</string>
+    <string name="phoneTypeFaxHome" msgid="2067265972322971467">"სახლის ფაქსი"</string>
+    <string name="phoneTypePager" msgid="7582359955394921732">"პეიჯერი"</string>
+    <string name="phoneTypeOther" msgid="1544425847868765990">"სხვა"</string>
+    <string name="phoneTypeCallback" msgid="2712175203065678206">"გადმოსარეკი"</string>
+    <string name="phoneTypeCar" msgid="8738360689616716982">"მანქანა"</string>
+    <string name="phoneTypeCompanyMain" msgid="540434356461478916">"კომპანიის ძირ. ნომერი"</string>
+    <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string>
+    <string name="phoneTypeMain" msgid="6766137010628326916">"მთავარი"</string>
+    <string name="phoneTypeOtherFax" msgid="8587657145072446565">"სხვა ფაქსი"</string>
+    <string name="phoneTypeRadio" msgid="4093738079908667513">"რადიო"</string>
+    <string name="phoneTypeTelex" msgid="3367879952476250512">"Telex"</string>
+    <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="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="eventTypeOther" msgid="7388178939010143077">"სხვა"</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="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="imTypeWork" msgid="1371489290242433090">"სამსახური"</string>
+    <string name="imTypeOther" msgid="5377007495735915478">"სხვა"</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>
+    <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
+    <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</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>
+    <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="relationTypeAssistant" msgid="6274334825195379076">"ასისტენტი"</string>
+    <string name="relationTypeBrother" msgid="8757913506784067713">"ძმა"</string>
+    <string name="relationTypeChild" msgid="1890746277276881626">"შვილი"</string>
+    <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"საოჯახო პარტნიორი"</string>
+    <string name="relationTypeFather" msgid="5228034687082050725">"მამა"</string>
+    <string name="relationTypeFriend" msgid="7313106762483391262">"მეგობარი"</string>
+    <string name="relationTypeManager" msgid="6365677861610137895">"მენეჯერი"</string>
+    <string name="relationTypeMother" msgid="4578571352962758304">"დედა"</string>
+    <string name="relationTypeParent" msgid="4755635567562925226">"მშობელი"</string>
+    <string name="relationTypePartner" msgid="7266490285120262781">"პარტნიორი"</string>
+    <string name="relationTypeReferredBy" msgid="101573059844135524">"რეკომენდატორი:"</string>
+    <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="sipAddressTypeHome" msgid="6093598181069359295">"სახლი"</string>
+    <string name="sipAddressTypeWork" msgid="6920725730797099047">"სამსახური"</string>
+    <string name="sipAddressTypeOther" msgid="4408436162950119849">"სხვა"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"აკრიფეთ PIN კოდი"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"დაბეჭდეთ PUK კოდი და ახალი PIN კოდი."</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK კოდი"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"ახალი PIN კოდი"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384">"შეეხეთ "<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">"განსაბლოკად აკრიფეთ PIN კოდი"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"არასწორი PIN კოდი."</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="8963839242565653192">"სერვისი არ არის."</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="5347633784401285225">"გადაუდებელი ზარი"</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="faceunlock_multiple_failures" msgid="754137583022792429">"სახის ამოცნობით განბლოკვის მცდელობამ დაშვებულ რაოდენობას გადააჭარბა"</string>
+    <string name="lockscreen_plugged_in" msgid="8057762828355572315">"დამუხტვა, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_charged" msgid="321635745684060624">"დამუხტულია"</string>
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_low_battery" msgid="1482873981919249740">"შეაერთეთ დამტენი."</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="default" msgid="2186920585695169078">"არ არის SIM ბარათი ტელეფონში."</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_transport_prev_description" msgid="201594905152746886">"წინა ჩანაწერი"</string>
+    <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"შემდეგი ჩანაწერი"</string>
+    <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"პაუზა"</string>
+    <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"დაკვრის ღილაკი"</string>
+    <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"შეწყვეტა"</string>
+    <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">"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">%d</xliff:g>-ჯერ დახატეთ განბლოკვის ნიმუში. \n\nსცადეთ ხელახლა <xliff:g id="NUMBER_1">%d</xliff:g> წამში."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"თქვენ არასწორად დაბეჭდეთ თქვენი პაროლი <xliff:g id="NUMBER_0">%d</xliff:g> ჯერ. \n\nხელახლა სცადეთ <xliff:g id="NUMBER_1">%d</xliff:g> წამში."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"თქვენ <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ არასწორად შეიყვანეთ PIN კოდი. \n\nსცადეთ ხელახლა <xliff:g id="NUMBER_1">%d</xliff:g> წამში."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"თქვენ არასწორად დახატეთ განბლოკვის ნიმუში <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%d</xliff:g> წარუმატებელი ცდის შემდეგ დაგჭირდებათ თქვენი ტაბლეტის განბლოკვა Google-ში შესვლით.\n\n გთხოვთ, ხელახლა სცადოთ <xliff:g id="NUMBER_2">%d</xliff:g> წამში."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"თქვენ არასწორად დახატეთ განბლოკვის ნიმუში <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%d</xliff:g> წარუმატებელი ცდის შემდეგ დაგჭირდებათ თქვენი ტელეფონის განბლოკვა Google-ში შესვლით.\n\n გთხოვთ, ხელახლა სცადოთ <xliff:g id="NUMBER_2">%d</xliff:g> წამში."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"თქვენ არასწორად სცადეთ ტაბლეტის განბლოკვა <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%d</xliff:g> წარუმატებელი ცდის შემდეგ ტაბლეტზე დაყენდება საწყისი, ქარხნული პარამეტრები და მომხმარებლის ყველა მონაცემი დაიკარგება."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"თქვენ არასწორად სცადეთ ტელეფონის განბლოკვა <xliff:g id="NUMBER_0">%d</xliff:g> ჯერ. კიდევ <xliff:g id="NUMBER_1">%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="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_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_checking_password" msgid="7114627351286933867">"შემოწმება..."</string>
+    <string name="lockscreen_unlock_label" msgid="737440483220667054">"განბლოკვა"</string>
+    <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"ხმების ჩართვა"</string>
+    <string name="lockscreen_sound_off_label" msgid="996822825154319026">"ხმის გამორთვა"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"ნიმუშის შექმნა დაწყებულია"</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"ნიმუში წაიშალა"</string>
+    <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"უჯრედი დაემატა."</string>
+    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"ნიმუშის შექმნა დასრულებულია"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. ვიჯეტი %2$d of %3$d."</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_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>
+    <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_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">"განბლოკვა Pin-ით."</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>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <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_line" msgid="5764267235026120888">"სტრიქონი"</string>
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
+    <string name="factorytest_failed" msgid="5410270329114212041">"წარმოების ტესტი ვერ განხორციელდა"</string>
+    <string name="factorytest_not_system" msgid="4435201656767276723">"აქტივობა FACTORY_TEST მხარდაჭერილია მხოლოდ იმ პაკეტებისთვის, რომლებიც მოთავსებულია /system/app."</string>
+    <string name="factorytest_no_action" msgid="872991874799998561">"ვერ მოიძებნა პაკეტი, რომელიც უზრუნველყოფს ქარხნულ ტესტ ქმედებას."</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="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>
+    <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
+    <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
+    <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
+    <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
+    <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">"ZIP კოდი"</string>
+    <string name="autofill_county" msgid="237073771020362891">"ქვეყანა"</string>
+    <string name="autofill_island" msgid="4020100875984667025">"კუნძული"</string>
+    <string name="autofill_district" msgid="8400735073392267672">"ოლქი"</string>
+    <string name="autofill_department" msgid="5343279462564453309">"დეპარტამენტი"</string>
+    <string name="autofill_prefecture" msgid="2028499485065800419">"პრეფექტურა"</string>
+    <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="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_packageVerificationAgent" msgid="5568139100645829117">"პაკეტების გადამოწმება"</string>
+    <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"აპს შეუძლია დაადასტუროს პაკეტის დაყანების შესაძლებლობა."</string>
+    <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"პაკეტების ვერიფიკატორებთან დაკავშირება"</string>
+    <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"მფლობელს შეეძლება პაკეტის ვერიფიკატორების მოთხოვნა. არასდროს გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_serialPort" msgid="546083327654631076">"სერიულ პორტებზე წვდომა"</string>
+    <string name="permdesc_serialPort" msgid="2991639985224598193">"მფლობელს შეეძლება სერიულ პორტებზე წვდომა სერიული მენეჯერის  API-ის გამოყენებით."</string>
+    <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"კონტენტის მომწოდებლებთან გარედან წვდომა"</string>
+    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"მფლობელს აძლევს კონტენტ პროვაიდერებზე წვდომას გარემოდან. ჩვეულებრივ აპებში არასოდეს გამოიყენება."</string>
+    <string name="permlab_updateLock" msgid="3527558366616680889">"მოწყობილობის ავტომატური განახლების დაშლა"</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"მფლობელს შეეძლება სისტემისთვის ინფორმაციის მიწოდება, თუ როდის იქნება შესაფერისი დრო მოწყობილობის გასაახლებლად არაინტერაქტიული გადატვირთვისთვის."</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>
+    <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="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="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="oneMonthDurationPast" msgid="7396384508953779925">"ერთი თვის წინ"</string>
+    <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"უფრო ადრე, ვიდრე ერთი თვის წინ"</string>
+  <plurals name="num_seconds_ago">
+    <item quantity="one" msgid="4869870056547896011">"1 წამის წინ"</item>
+    <item quantity="other" msgid="3903706804349556379">"<xliff:g id="COUNT">%d</xliff:g> წამის წინ"</item>
+  </plurals>
+  <plurals name="num_minutes_ago">
+    <item quantity="one" msgid="3306787433088810191">"1 წუთის უკან"</item>
+    <item quantity="other" msgid="2176942008915455116">"<xliff:g id="COUNT">%d</xliff:g> წუთის წინ"</item>
+  </plurals>
+  <plurals name="num_hours_ago">
+    <item quantity="one" msgid="9150797944610821849">"1 საათის წინ"</item>
+    <item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> საათის წინ"</item>
+  </plurals>
+  <plurals name="last_num_days">
+    <item quantity="other" msgid="3069992808164318268">"ბოლო <xliff:g id="COUNT">%d</xliff:g> დღე"</item>
+  </plurals>
+    <string name="last_month" msgid="3959346739979055432">"გასული თვე"</string>
+    <string name="older" msgid="5211975022815554840">"უფრო ძველი"</string>
+  <plurals name="num_days_ago">
+    <item quantity="one" msgid="861358534398115820">"გუშინ"</item>
+    <item quantity="other" msgid="2479586466153314633">"<xliff:g id="COUNT">%d</xliff:g> დღის წინ"</item>
+  </plurals>
+  <plurals name="in_num_seconds">
+    <item quantity="one" msgid="2729745560954905102">"1 წამში"</item>
+    <item quantity="other" msgid="1241926116443974687">"<xliff:g id="COUNT">%d</xliff:g> წამში"</item>
+  </plurals>
+  <plurals name="in_num_minutes">
+    <item quantity="one" msgid="8793095251325200395">"1 წუთში"</item>
+    <item quantity="other" msgid="3330713936399448749">"<xliff:g id="COUNT">%d</xliff:g> წუთში"</item>
+  </plurals>
+  <plurals name="in_num_hours">
+    <item quantity="one" msgid="7164353342477769999">"1 საათში"</item>
+    <item quantity="other" msgid="547290677353727389">"<xliff:g id="COUNT">%d</xliff:g> საათში"</item>
+  </plurals>
+  <plurals name="in_num_days">
+    <item quantity="one" msgid="5413088743009839518">"ხვალ"</item>
+    <item quantity="other" msgid="5109449375100953247">"<xliff:g id="COUNT">%d</xliff:g> დღეში"</item>
+  </plurals>
+  <plurals name="abbrev_num_seconds_ago">
+    <item quantity="one" msgid="1849036840200069118">"1 წმ. წინ"</item>
+    <item quantity="other" msgid="3699169366650930415">"<xliff:g id="COUNT">%d</xliff:g> წამის წინ"</item>
+  </plurals>
+  <plurals name="abbrev_num_minutes_ago">
+    <item quantity="one" msgid="6361490147113871545">"1 წუთის წინ"</item>
+    <item quantity="other" msgid="851164968597150710">"<xliff:g id="COUNT">%d</xliff:g> წუთის წინ"</item>
+  </plurals>
+  <plurals name="abbrev_num_hours_ago">
+    <item quantity="one" msgid="4796212039724722116">"1 საათის წინ"</item>
+    <item quantity="other" msgid="6889970745748538901">"<xliff:g id="COUNT">%d</xliff:g> საათის წინ"</item>
+  </plurals>
+  <plurals name="abbrev_num_days_ago">
+    <item quantity="one" msgid="8463161711492680309">"გუშინ"</item>
+    <item quantity="other" msgid="3453342639616481191">"<xliff:g id="COUNT">%d</xliff:g> დღის წინ"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_seconds">
+    <item quantity="one" msgid="5842225370795066299">"1 წამში"</item>
+    <item quantity="other" msgid="5495880108825805108">"<xliff:g id="COUNT">%d</xliff:g> წამის წინ"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_minutes">
+    <item quantity="one" msgid="562786149928284878">"1 წუთში"</item>
+    <item quantity="other" msgid="4216113292706568726">"<xliff:g id="COUNT">%d</xliff:g> წუთში"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_hours">
+    <item quantity="one" msgid="3274708118124045246">"1 საათში"</item>
+    <item quantity="other" msgid="3705373766798013406">"<xliff:g id="COUNT">%d</xliff:g> საათში"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_days">
+    <item quantity="one" msgid="2178576254385739855">"ხვალ"</item>
+    <item quantity="other" msgid="2973062968038355991">"<xliff:g id="COUNT">%d</xliff:g> დღეში"</item>
+  </plurals>
+    <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>
+    <string name="days" msgid="4774547661021344602">"დღეები"</string>
+    <string name="hour" msgid="2126771916426189481">"საათი"</string>
+    <string name="hours" msgid="894424005266852993">"საათი"</string>
+    <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="week" msgid="5617961537173061583">"კვირა"</string>
+    <string name="weeks" msgid="6509623834583944518">"კვირები"</string>
+    <string name="year" msgid="4001118221013892076">"წელი"</string>
+    <string name="years" msgid="6881577717993213522">"წელი"</string>
+  <plurals name="duration_seconds">
+    <item quantity="one" msgid="6962015528372969481">"1 წამი"</item>
+    <item quantity="other" msgid="1886107766577166786">"<xliff:g id="COUNT">%d</xliff:g> წამი"</item>
+  </plurals>
+  <plurals name="duration_minutes">
+    <item quantity="one" msgid="4915414002546085617">"1 წუთი"</item>
+    <item quantity="other" msgid="3165187169224908775">"<xliff:g id="COUNT">%d</xliff:g> წუთი"</item>
+  </plurals>
+  <plurals name="duration_hours">
+    <item quantity="one" msgid="8917467491248809972">"1 საათი"</item>
+    <item quantity="other" msgid="3863962854246773930">"<xliff:g id="COUNT">%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_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>
+    <string name="midnight" msgid="7166259508850457595">"შუაღამე"</string>
+    <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="cut" msgid="3092569408438626261">"ამოჭრა"</string>
+    <string name="copy" msgid="2681946229533511987">"კოპირება"</string>
+    <string name="paste" msgid="5629880836805036433">"ჩასმა"</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="textSelectionCABTitle" msgid="5236850394370820357">"ტექსტის მონიშვნა"</string>
+    <string name="addToDictionary" msgid="4352161534510057874">"ლექსიკონში დამატება"</string>
+    <string name="deleteText" msgid="6979668428458199034">"წაშლა"</string>
+    <string name="inputMethod" msgid="1653630062304567879">"შეყვანის მეთოდი"</string>
+    <string name="editTextMenuTitle" msgid="4909135564941815494">"ქმედებები ტექსტზე"</string>
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"თავისუფალი ადგილი იწურება"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"სისტემის ზოგიერთმა ფუნქციამ შესაძლოა არ იმუშავოს"</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="4653586947747330058">"შეეხეთ მეტი ინფორმაციისათვის ან აპის შესაწყვეტად."</string>
+    <string name="ok" msgid="5970060430562524910">"OK"</string>
+    <string name="cancel" msgid="6442560571259935130">"გაუქმება"</string>
+    <string name="yes" msgid="5362982303337969312">"OK"</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="alwaysUse" msgid="4583018368000610438">"ამ ქმედებისთვის ნაგულისხმევად გამოყენება."</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="aerr_title" msgid="1905800560317137752"></string>
+    <string name="aerr_application" msgid="932628488013092776">"სამწუხაროდ, <xliff:g id="APPLICATION">%1$s</xliff:g> შეწყდა."</string>
+    <string name="aerr_process" msgid="4507058997035697579">"სამწუხაროდ, პროცესი <xliff:g id="PROCESS">%1$s</xliff:g> შეწყდა."</string>
+    <string name="anr_title" msgid="4351948481459135709"></string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> არ რეაგირებს.\n\nგსურთ, მისი დახურვა?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"<xliff:g id="ACTIVITY">%1$s</xliff:g> აქტივობა არ რეაგირებს.\n\nგსურთ მისი დახურვა?"</string>
+    <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> არ რეაგირებს. გსურთ მისი დახურვა?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"პროცესი <xliff:g id="PROCESS">%1$s</xliff:g> არ რეაგირებს.\n\nგსურთ, მისი დახურვა?"</string>
+    <string name="force_close" msgid="8346072094521265605">"OK"</string>
+    <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_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; აპები &gt; ჩამოტვირთულები."</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>
+    <string name="android_upgrading_title" msgid="1584192285441405746">"Android ახალ ვერსიაზე გადადის…"</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_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="1721681741617898865">"აპზე გადასართველად შეეხეთ"</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>
+    <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="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_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_notification" msgid="7044986546477282274">"შეტყობინების ხმა"</string>
+    <string name="ringtone_default" msgid="3789758980357696936">"ნაგულისხმევი ზარი"</string>
+    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"ნაგულისხმევი ზარი (<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_unknown" msgid="5477919988701784788">"უცნობი ზარი"</string>
+  <plurals name="wifi_available">
+    <item quantity="one" msgid="6654123987418168693">"Wi-Fi ქსელი ხელმისაწვდომია"</item>
+    <item quantity="other" msgid="4192424489168397386">"Wi-Fi ქსელები ხელმისაწვდომია."</item>
+  </plurals>
+  <plurals name="wifi_available_detailed">
+    <item quantity="one" msgid="1634101450343277345">"ხელმისაწვდომი Wi-Fi ქსელების გახსნა"</item>
+    <item quantity="other" msgid="7915895323644292768">"ხელმისაწვდომი Wi-Fi ქსელების გახსნა"</item>
+  </plurals>
+    <string name="wifi_available_sign_in" msgid="4029489716605255386">"Wi-Fi ქსელთან დაკავშირება"</string>
+    <string name="network_available_sign_in" msgid="8495155593358054676">"ქსელში შესვლა"</string>
+    <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
+    <skip />
+    <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi-თან დაკავშირება ვერ მოხერხდა"</string>
+    <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" აქვს ცუდი ინტერნეტ კავშირი."</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_enabled_notification_message" msgid="1638949953993894335">"პარამეტრებისთვის შეეხეთ"</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_to_connect_title" msgid="4958803948658533637">"მოწვევა დასაკავშირებლად"</string>
+    <string name="wifi_p2p_from_message" msgid="570389174731951769">"გამგზავნი:"</string>
+    <string name="wifi_p2p_to_message" msgid="248968974522044099">"მიმღები:"</string>
+    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"შეიყვანეთ საჭირო PIN:"</string>
+    <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"პინ-კოდი:"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"ტაბლეტი დროებით გაითიშება Wi-Fi-დან, სანამ მიერთებულია <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ზე"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"ტელეფონი დროებით გაითიშება Wi-Fi-დან, სანამ მიერთებულია <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ზე"</string>
+    <string name="select_character" msgid="3365550120617701745">"სიმბოლოს ჩასმა"</string>
+    <string name="sms_control_title" msgid="7296612781128917719">"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="3492025719868078457">"ამან "<font fgcolor="#ffffb060">"შესაძლოა გამოიწვიოს ცვლილებები"</font>" თქვენი მობილურის ანგარიშზე."</string>
+    <string name="sms_premium_short_code_details" msgid="5523826349105123687"><font fgcolor="#ffffb060">"ეს გამოიწვევს დანახარჯებს თქვენ მობილურ ანგარიშზე."</font></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">"ამის შეცვლა შეგიძლიათ მოგვიანებით აპების პარამეტრებიდან."</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_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="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_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="usb_storage_activity_title" msgid="4465055157209648641">"USB მასიური მეხსიერება"</string>
+    <string name="usb_storage_title" msgid="5901459041398751495">"USB დაკავშირებულია"</string>
+    <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"თქვენ დაკავშირებული ხართ კომპიუტერთან USB-ის მეშვეობით. თუ გსურთ კომპიუტერსა და თქვენს Android USB მოწყობილობას შორის ფაილების კოპირება შეეხეთ ქვემოთ მდებარე ღილაკს."</string>
+    <string name="usb_storage_message" product="default" msgid="805351000446037811">"თქვენ დაუკავშირდით კომპიუტერს USB-ის მეშვეობით. შეეხეთ ქვემოთ მდებარე ღილაკს, თუ გსურთ ფაილების კოპირება თქვენ კომპიუტერსა და Android SD ბარათს შორის."</string>
+    <string name="usb_storage_button_mount" msgid="1052259930369508235">"USB მეხსიერების ჩართვა"</string>
+    <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"USB მასიური მეხსიერებისთვის თქვენი USB მეხსიერების გამოყენება პრობლემას ქმნის."</string>
+    <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"USB მასიური მეხსიერებისთვის თქვენი SD ბარათის გამოყენება პრობლემას ქმნის."</string>
+    <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB დაკავშირებულია"</string>
+    <string name="usb_storage_notification_message" msgid="939822783828183763">"შეეხეთ ფაილების კოპირებისათვის კომპიუტერში/კომპიუტერიდან."</string>
+    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"USB მეხსიერების გამორთვა"</string>
+    <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"შეეხეთ USB მეხსიერების გამოსართველად."</string>
+    <string name="usb_storage_stop_title" msgid="660129851708775853">"ხდება USB მეხსიერების გამოყენება"</string>
+    <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"USB მეხსიერების გამორთვამდე, გამოიღეთ თქვენი Android-ის USB თქვენი კომპიუტერიდან."</string>
+    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"USB მეხსიერების გამორთვამდე, გამოაერთეთ თქვენი Android SD ბარათი კომპიუტერიდან."</string>
+    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"USB მეხსიერების გამორთვა"</string>
+    <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"USB-გამორთვისას წარმოიშვა შეცდომა. შეამოწმეთ, რომ გათიშეთ თქვენი USB ჰოსტი, შემდეგ სცადეთ ხელახლა."</string>
+    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"USB მეხსიერების ჩართვა"</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"თუ USB მეხსიერებას ჩართავთ, თქვენ მიერ მოხმარებადი რამდენიმე აპი შეწყვეტს მუშაობას და შესაძლოა მიუწვდომელი გახდეს USB მეხსიერების გამორთვამდე."</string>
+    <string name="dlg_error_title" msgid="7323658469626514207">"USB ოპერაცია წარუმატებელი იყო"</string>
+    <string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
+    <string name="usb_mtp_notification_title" msgid="3699913097391550394">"დაკავშირებულია როგორც მედია მოწყობილობა"</string>
+    <string name="usb_ptp_notification_title" msgid="1960817192216064833">"დაკავშირებულია როგორც კამერა"</string>
+    <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"დაკავშირებულია როგორც დამყენებელი"</string>
+    <string name="usb_accessory_notification_title" msgid="7848236974087653666">"დაკავშირებულია USB აქსესუართან"</string>
+    <string name="usb_notification_message" msgid="2290859399983720271">"შეეხეთ USB-ის სხვა პარამეტრების სანახავად."</string>
+    <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"დავაფორმატო USB მეხსიერება?"</string>
+    <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"გსურთ SD ბარათის დაფორმატება?"</string>
+    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"თქვენ USB მეხსიერებაში შენახული ყველა ფაილი წაიშლება. ეს მოქმედება ვეღარ შეიცვლება!"</string>
+    <string name="extmedia_format_message" product="default" msgid="14131895027543830">"თქვენს ბარათზე ყველა მონაცემი დაიკარგება."</string>
+    <string name="extmedia_format_button_format" msgid="4131064560127478695">"დაფორმატება"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"USB გამართვა შეერთებულია"</string>
+    <string name="adb_active_notification_message" msgid="1016654627626476142">"შეეხეთ, რათა შეწყვიტოთ USB-ის გამართვა."</string>
+    <string name="select_input_method" msgid="4653387336791222978">"აირჩიეთ შეყვანის მეთოდი"</string>
+    <string name="configure_input_methods" msgid="9091652157722495116">"შეყვანის მეთოდების დაყენება"</string>
+    <string name="use_physical_keyboard" msgid="6203112478095117625">"ფიზიკური კლავიატურა"</string>
+    <string name="hardware" msgid="7517821086888990278">"მოწყობილობა"</string>
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"შეარჩიეთ კლავიატურის განლაგება."</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"კლავიატურის განლაგების შესარჩევად შეეხეთ."</string>
+    <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="candidates_style" msgid="4333913089637062257"><u>"კანდიდატები"</u></string>
+    <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"USB მეხსიერების მომზადება"</string>
+    <string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"SD ბარათის მომზადება"</string>
+    <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"შეცდომების შემოწმება"</string>
+    <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"ცარიელი USB მეხსიერება"</string>
+    <string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"ცარიელი SD ბარათი"</string>
+    <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"USB მეხსიერება ცარიელია ან მხარდაუჭერელი ფაილური სისტემა აქვს."</string>
+    <string name="ext_media_nofs_notification_message" product="default" msgid="8641065641786923604">"SD ბარათი ცარიელია ან ფაილური სისტემა მხარდაუჭერელია."</string>
+    <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"დაზიანებული USB მეხსიერება"</string>
+    <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"დაზიანებული SD ბარათი"</string>
+    <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="1795917578395333280">"USB მეხსიერება დაზიანებულია. სცადეთ მისი ხელახლა დაფორმატება."</string>
+    <string name="ext_media_unmountable_notification_message" product="default" msgid="1753898567525568253">"SD ბარათი დაზიანებულია. სცადეთ მისი ხელახლა დაფორმატება."</string>
+    <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"USB მეხსიერება მოულოდნელად გამოირთო"</string>
+    <string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"SD ბარათი მოულოდნელად მოიხსნა"</string>
+    <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"გამოერთებამდე გათიშეთ USB მეხსიერება, რათა თავიდან აიცილოთ მონაცემების დაკარგვა."</string>
+    <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"გამოერთებამდე გათიშეთ SD ბარათი, რათა თავიდან აიცილოთ მონაცემების დაკარგვა."</string>
+    <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"USB მეხსიერების გამორთვა უსაფრთხოა"</string>
+    <string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"SD ბარათის მოხსნა უსაფრთხოა"</string>
+    <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"შეგიძლიათ უსაფრთხოდ გამოაერთოთ USB მეხსიერება."</string>
+    <string name="ext_media_safe_unmount_notification_message" product="default" msgid="568841278138377604">"შეგიძლიათ უსაფრთხოდ გამოაერთოთ SD ბარათი."</string>
+    <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"გამორთული USB მეხსიერება"</string>
+    <string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"გამოღებულია SD ბარათი."</string>
+    <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"USB მეხსიერება გამოერთებულია. მიუერთეთ ახალი მედია."</string>
+    <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"SD ბარათი მოხსნილია. ჩასვით ახალი."</string>
+    <string name="activity_list_empty" msgid="1675388330786841066">"შესატყვისი აქტივობები არ არის."</string>
+    <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"კომპონენტების გამოყენების სტატისტიკის განახლება"</string>
+    <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"აპს შეეძლება, შეცვალოს კომპონენტის გამოყენების შეგროვებული სტატისტიკა. არ გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_copyProtectedData" msgid="4341036311211406692">"კონტენტის კოპირება"</string>
+    <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"აპს შეეძლება კონტენტის კოპირებისთვის კონტეინერის ნაგულისხმევი სერვისის გამოძახება. არ გამოიყენება ჩვეულებრივ აპებში."</string>
+    <string name="permlab_route_media_output" msgid="1642024455750414694">"მულტიმედია მონაცემების გადამისამართება"</string>
+    <string name="permdesc_route_media_output" msgid="4932818749547244346">"აპლიკაციას შეეძლება გადაამისამართოს მულტიმედია მონაცემები სხვა გარე მოწყობილობებისკენ."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"ღილაკების დამცავის უსაფრთხო საცავზე წვდომა"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"აპლიკაციას ღილაკების დამცავის უსაფრთხო საცავზე წვდომის უფლება ექნება."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"ღილაკების დამცავის გამოჩენისა და დამალვის მართვა"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"აპლიკაციას შეეძლება ღილაკების დამცავის კონტროლი."</string>
+    <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"მასშტაბის მართვისთვის შეეხეთ ორჯერ."</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>
+    <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">"ნომერზე დარეკვა\n<xliff:g id="NUMBER">%s</xliff:g>-ის გამოყენებით"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"კონტაქტის შექმნა\n <xliff:g id="NUMBER">%s</xliff:g>-ის გამოყენებით"</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"მითითებული ერთი ან რამდენიმე აპი ითხოვს თქვენს ანგარიშზე წვდომის უფლებას, ახლა და მომავალში."</string>
+    <string name="grant_credentials_permission_message_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">"მოთხოვნილია ნებრათვა \nანგარიშისთვის: <xliff:g id="ACCOUNT">%s</xliff:g>"</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>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"ფონის შეცვლა"</string>
+    <string name="notification_listener_binding_label" msgid="2014162835481906429">"შეტყობინებების მსმენელი"</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="3011306607126450322">"შეეხეთ ქსელის სამართავად."</string>
+    <string name="vpn_text_long" msgid="6407351006249174473">"მიერთებულია <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_error" msgid="6009249814034708175">"შეცდომა მუდამ VPN-ზე"</string>
+    <string name="vpn_lockdown_config" msgid="6415899150671537970">"კონფიგურაციისთვის შეეხეთ"</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="8035230537563503262">"შეეხეთ მანქანის რეჟიმიდან გამოსასვლელად."</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"ინტერნეტის მიერთება ან უსადენო ქსელი აქტიურია."</string>
+    <string name="tethered_notification_message" msgid="6857031760103062982">"შესაქმნელად შეეხეთ"</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="throttle_warning_notification_title" msgid="4890894267454867276">"მობილური ინტერნეტის მაღალი მოხმარება"</string>
+    <string name="throttle_warning_notification_message" msgid="3340822228599337743">"შეეხეთ, რათა შეიტყოთ მეტი მობილურის ინტერნეტის გამოყენების შესახებ."</string>
+    <string name="throttled_notification_title" msgid="6269541897729781332">"მობილური ინტერნეტის ლიმიტი გადაჭარბებულია"</string>
+    <string name="throttled_notification_message" msgid="5443457321354907181">"შეეხეთ, რათა შეიტყოთ მეტი მობილურის ინტერნეტის გამოყენების შესახებ."</string>
+    <string name="no_matches" msgid="8129421908915840737">"შესატყვისები არ არის."</string>
+    <string name="find_on_page" msgid="1946799233822820384">"გვერდზე ძებნა"</string>
+  <plurals name="matches_found">
+    <item quantity="one" msgid="8167147081136579439">"1 დამთხვევა"</item>
+    <item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> <xliff:g id="TOTAL">%d</xliff:g>-დან"</item>
+  </plurals>
+    <string name="action_mode_done" msgid="7217581640461922289">"დასრულდა"</string>
+    <string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"USB მეხსიერების გათიშვა…"</string>
+    <string name="progress_unmounting" product="default" msgid="1327894998409537190">"მიმდინარეობს SD ბარათის მოხსნა…"</string>
+    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"მიმდინარეობს USB მეხსიერების გასუფთავება…"</string>
+    <string name="progress_erasing" product="default" msgid="6596988875507043042">"SD ბარათის წაშლა..."</string>
+    <string name="format_error" product="nosdcard" msgid="6299769563624776948">"USB მეხსიერების წაშლა ვერ მოხერხდა."</string>
+    <string name="format_error" product="default" msgid="7315248696644510935">"SD ბარათის წაშლა ვერ მოხერხდა."</string>
+    <string name="media_bad_removal" msgid="7960864061016603281">"SD ბარათი მანამ მოიხსნა, ვიდრე გამოერთებული იქნებოდა."</string>
+    <string name="media_checking" product="nosdcard" msgid="418188720009569693">"USB მეხსიერება ამჟამად შემოწმების პროცესშია."</string>
+    <string name="media_checking" product="default" msgid="7334762503904827481">"ამჟამად მიმდინარეობს SD ბარათის შემოწმება."</string>
+    <string name="media_removed" msgid="7001526905057952097">"SD ბარათი გამოერთებულია."</string>
+    <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"USB მეხსიერებას კომპიუტერი იყენებს ამჟამად."</string>
+    <string name="media_shared" product="default" msgid="5706130568133540435">"SD ბარათს კომპიუტერი იყენებს ამჟამად."</string>
+    <string name="media_unknown_state" msgid="729192782197290385">"გარე მედია უცნობ მდგომარეობაშია."</string>
+    <string name="share" msgid="1778686618230011964">"გაზიარება"</string>
+    <string name="find" msgid="4808270900322985960">"ძიება"</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="gpsNotifMessage" msgid="1374718023224000702">"მოთხოვნილია <xliff:g id="NAME">%1$s</xliff:g>-ის მიერ (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+    <string name="gpsVerifYes" msgid="2346566072867213563">"დიახ"</string>
+    <string name="gpsVerifNo" msgid="1146564937346454865">"არა"</string>
+    <string name="sync_too_many_deletes" msgid="5296321850662746890">"წაშლის შეზღუდვა გადაჭარბებულია"</string>
+    <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> წაშლილი ერთეულია <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>-თვის, ანგარიში <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. რისი გაკეთება გსურთ?"</string>
+    <string name="sync_really_delete" msgid="2572600103122596243">"ერთეულების წაშლა"</string>
+    <string name="sync_undo_deletes" msgid="2941317360600338602">"წაშლების გაუქმება"</string>
+    <string name="sync_do_nothing" msgid="3743764740430821845">"ამჟამად არაფერი გააკეთო"</string>
+    <string name="choose_account_label" msgid="5655203089746423927">"ანგარიშის არჩევა"</string>
+    <string name="add_account_label" msgid="2935267344849993553">"ანგარიშის დამატება"</string>
+    <string name="add_account_button_label" msgid="3611982894853435874">"ანგარიშის დამატება &amp;raquo;"</string>
+    <string name="number_picker_increment_button" msgid="2412072272832284313">"გაზრდა"</string>
+    <string name="number_picker_decrement_button" msgid="476050778386779067">"შემცირება"</string>
+    <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g>-ს შეეხეთ და არ აუშვათ."</string>
+    <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"აასრიალეთ ზემოთ გასაზრდელად და ჩაასრიალეთ ქვემოთ შესამცირებლად."</string>
+    <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"ერთი წუთით წინ"</string>
+    <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"წუთების შემცირება"</string>
+    <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"საათის მომატება"</string>
+    <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"საათით უკან"</string>
+    <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"PM-ის დაყენება"</string>
+    <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"AM-ის დაყენება"</string>
+    <string name="date_picker_increment_month_button" msgid="5369998479067934110">"თვის მომატება"</string>
+    <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"ერთი თვით უკან"</string>
+    <string name="date_picker_increment_day_button" msgid="7130465412308173903">"დღის მომატება"</string>
+    <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"დღის მოკლება"</string>
+    <string name="date_picker_increment_year_button" msgid="6318697384310808899">"წლის მომატება"</string>
+    <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"წლის მოკლება"</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_enter" msgid="2985864015076059467">"შეყვანა"</string>
+    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"აპის არჩევა"</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_direction_up" msgid="7169032478259485180">"გაასრიალეთ ზემოთ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-თვის."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"გაასრიალეთ ქვემოთ <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="description_direction_right" msgid="8034433242579600980">"გაასრიალეთ მარჯვნივ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-თვის."</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"განბლოკვა"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"კამერა"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"უხმო"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"ხმის ჩართვა"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"ძიება"</string>
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"განბლოკვისათვის გადაფურცლეთ"</string>
+    <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"შეაერთედ ყურსასმენები, პაროლის ღილაკები რომ გაიგოთ."</string>
+    <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"წერტილი."</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="4891916833657929263">"შიდა მეხსიერება"</string>
+    <string name="storage_sd_card" msgid="3282948861378286745">"SD ბარათი"</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="1955638862122232342">"ინტერნეტის გამოყენების გაფრთხილება"</string>
+    <string name="data_usage_warning_body" msgid="2814673551471969954">"შეეხეთ მოხმარებისა და პარამეტრების სანახავად."</string>
+    <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-3G ინტერნეტი გაითიშა."</string>
+    <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G მონაცემები გათიშულია"</string>
+    <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"მობილური ინტერნეტი გაითიშა"</string>
+    <string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"Wi‑Fi მონაცემთა გამორთვა"</string>
+    <string name="data_usage_limit_body" msgid="3317964706973601386">"გასააქტიურებლად შეეხეთ."</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_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="6741521330997452990">"შეეხეთ შეზღუდვის მოსახსნელად"</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>
+    <string name="org_unit" msgid="7265981890422070383">"ორგანიზაციული ერთეული:"</string>
+    <string name="issued_by" msgid="2647584988057481566">"გამცემი:"</string>
+    <string name="validity_period" msgid="8818886137545983110">"ვალიდურობა:"</string>
+    <string name="issued_on" msgid="5895017404361397232">"გაცემული:"</string>
+    <string name="expires_on" msgid="3676242949915959821">"ვადა იწურება:"</string>
+    <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>
+    <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"ყველას ნახვა"</string>
+    <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"აქტივობის არჩევა"</string>
+    <string name="share_action_provider_share_with" msgid="5247684435979149216">"გაზიარება"</string>
+    <string name="status_bar_device_locked" msgid="3092703448690669768">"მოწყობილობა ჩაკეტილია."</string>
+    <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="3245653681008218030">"იგზავნება..."</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="default_audio_route_name" product="tablet" msgid="4617053898167127471">"ტაბლეტი"</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="media_route_chooser_grouping_done" msgid="7966438307723317169">"დასრულდა"</string>
+    <string name="media_route_button_content_description" msgid="5758553567065145276">"მედია გამომავალი"</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>
+    <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_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="wifi_display_notification_title" msgid="2223050649240326557">"უსადენო ეკრანი დაკავშირებულია"</string>
+    <string name="wifi_display_notification_message" msgid="4498802012464170685">"გამოსახულება გადაეცემა სხვა მოწყობილობას"</string>
+    <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"კავშირის გაწყვეტა"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"გადაუდებელი დახმარების ზარი"</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">"არასწორი PIN"</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">"SIM PIN-ის შეყვანა"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"შეიყვანეთ PIN"</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">"სასურველი PIN კოდის შეყვანა"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"სასურველი PIN კოდის დადასტურება"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM ბარათის განბლოკვა…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"არასწორი PIN კოდი."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"აკრიფეთ PIN, რომელიც შედგება 4-დან 8 ციფრამდე."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK კოდი უნდა იყოს რვა ან მეტი ციფრისგან შემდგარი."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"ხელახლა შეიყვანეთ სწორი PUK კოდი. რამდენიმე წარუმატებელი მცდელობა გამოიწვევს SIM ბარათის დაბლოკვას."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN კოდები არ ემთხვევა"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ნახატი ნიმუშის ძალიან ბევრი მცდელობა"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"განბლოკვისთვის გაიარეთ ავტორიზაცია თქვენი Google  ანგარიშით."</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"მიმდინარეობს ანგარიშის შემოწმება…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"თქვენ <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ არასწორად შეიყვანეთ PIN კოდი. \n\nსცადეთ ხელახლა <xliff:g id="NUMBER_1">%d</xliff:g> წამში."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"თქვენ <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ არასწორად დაბეჭდეთ თქვენი პაროლი. \n\nხელახლა სცადეთ <xliff:g id="NUMBER_1">%d</xliff:g> წამში."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"თქვენ <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ დახატეთ განბლოკვის ნიმუში. \n\nსცადეთ ხელახლა <xliff:g id="NUMBER_1">%d</xliff:g> წამში."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"თქვენ არასწორად სცადეთ ტაბლეტის განბლოკვა <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%d</xliff:g> წარუმატებელი ცდის შემდეგ ტაბლეტზე დაყენდება საწყისი, ქარხნული პარამეტრები და მომხმარებლის ყველა მონაცემი დაიკარგება."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"თქვენ არასწორად სცადეთ ტელეფონის განბლოკვა <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> ჯერ. კიდევ <xliff:g id="NUMBER_1">%d</xliff:g> წარუმატებელი ცდის შემდეგ მოგთხოვთ ტაბლეტის განბლოკვას ელფოსტის ანგარიშის გამოყენებით.\n\n ხელახლა სცადეთ <xliff:g id="NUMBER_2">%d</xliff:g> წამში."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"თქვენ არასწორად დახატეთ თქვენი განბლოკვის ნიმუში <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%d</xliff:g> წარუმატებელი ცდის შემდეგ, დაგჭირდებათ თქვენი ტელეფონის განბლოკვა ელფოსტის ანგარიშის გამოყენებით.\n\n ხელახლა სცადეთ <xliff:g id="NUMBER_2">%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="7324161939475478066">"რეკომენდებულ დონეზე მაღლა გსურთ ხმის აწევა?\nდიდი ხნის განმავლობაში ძალიან ხმამაღლა მოსმენამ შესაძლოა სმენა დაგიზიანოთ."</string>
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"გეჭიროთ ორი თითი მარტივი წვდომის ჩასართავად."</string>
+    <string name="accessibility_enabled" msgid="1381972048564547685">"მარტივი წვდომა ჩართულია."</string>
+    <string name="enable_accessibility_canceled" msgid="3833923257966635673">"მარტივი წვდომა გაუქმდა."</string>
+    <string name="user_switched" msgid="3768006783166984410">"ამჟამინდელი მომხმარებელი <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="app_no_restricted_accounts" msgid="5739463249673727736">"ამ აპს შეზღუდული პროფილების ანგარიშების მხარდაჭერა არ აქვს"</string>
+    <string name="app_not_found" msgid="3429141853498927379">"ამ მოქმედების შესასრულებლად აპლიკაცია ვერ მოიძებნა"</string>
+    <string name="revoke" msgid="5404479185228271586">"გაუქმება"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"გაუქმებული"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"შეცდომა კონტენტის ჩაწერისას"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"შეიყვანეთ PIN"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"ამჟამინდელი PIN"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"ახალი PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"გაიმეორეთ ახალი PIN"</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_too_short" msgid="8173982756265777792">"PIN ძალიან მოკლეა. უნდა შედგებოდეს სულ ცოტა 4 ციფრისგან."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="4835639969503729874">"არასწორი PIN. სცადეთ ისევ 1 წამში."</item>
+    <item quantity="other" msgid="8030607343223287654">"არასწორი PIN. სცადეთ ისევ <xliff:g id="COUNT">%d</xliff:g> წამში."</item>
+  </plurals>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"გაასრიალეთ ეკრანის კიდეზე ზოლის გამოსაჩენად"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"გაასრიალეთ ეკრანის კიდიდან სისტემის ზოლის გამოსაჩენად"</string>
+</resources>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
new file mode 100644
index 0000000..4c131f5
--- /dev/null
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -0,0 +1,1602 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<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="5973789783504771878">"គីឡូបៃ"</string>
+    <string name="megabyteShort" msgid="6355851576770428922">"មេកាបៃ"</string>
+    <string name="gigabyteShort" msgid="3259882455212193214">"ជីកាបៃ"</string>
+    <string name="terabyteShort" msgid="231613018159186962">"តេរ៉ាបៃ"</string>
+    <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
+    <string name="untitled" msgid="4638956954852782576">"&lt;គ្មាន​ចំណង​ជើង&gt;"</string>
+    <string name="ellipsis" msgid="7899829516048813237">"…"</string>
+    <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
+    <string name="emptyPhoneNumber" msgid="7694063042079676517">"(គ្មាន​លេខ​ទូរស័ព្ទ)"</string>
+    <string name="unknownName" msgid="2277556546742746522">"(មិន​ស្គាល់)"</string>
+    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"សារ​ជា​សំឡេង"</string>
+    <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
+    <string name="mmiError" msgid="5154499457739052907">"បញ្ហា​ក្នុង​ការ​តភ្ជាប់​ ឬ​កូដ MMI មិន​ត្រឹមត្រូវ។"</string>
+    <string name="mmiFdnError" msgid="5224398216385316471">"ប្រតិបត្តិការ​ត្រូវ​បាន​ដាក់​កម្រិត​​​ចំពោះ​លេខ​ហៅ​ថេរ​តែ​ប៉ុណ្ណោះ។"</string>
+    <string name="serviceEnabled" msgid="8147278346414714315">"បាន​បើក​សេវាកម្ម។"</string>
+    <string name="serviceEnabledFor" msgid="6856228140453471041">"បាន​បើក​សេវាកម្ម​សម្រាប់៖"</string>
+    <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="mmiComplete" msgid="8232527495411698359">"MMI បញ្ចប់​។"</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 ដែល​មាន​​​ពី ៤ ដល់ ៨​លេខ"</string>
+    <string name="invalidPuk" msgid="8761456210898036513">"បញ្ចូល​កូដ PUK ដែល​មាន​ពី​ ៨ លេខ​ ឬ​វែង​ជាង​នេះ។"</string>
+    <string name="needPuk" msgid="919668385956251611">"ស៊ីមកាត​​របស់​អ្នក​ជាប់​កូដ PUK ។ បញ្ចូល​កូដ PUK ដើម្បី​ដោះ​សោ។"</string>
+    <string name="needPuk2" msgid="4526033371987193070">"បញ្ចូល​កូដ PUK2 ដើម្បី​ដោះ​សោ​ស៊ីម​កាត។"</string>
+    <string name="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="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">"ប្ដូរ​កូដ PIN"</string>
+    <string name="CnipMmi" msgid="3110534680557857162">"បង្ហាញ​ការ​ហៅ​លេខ"</string>
+    <string name="CnirMmi" msgid="3062102121430548731">"បាន​ដាក់​កម្រិត​ការ​ហៅ​លេខ"</string>
+    <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="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"បាន​ដាក់​កម្រិត​លំនាំដើម​លេខ​សម្គាល់​អ្នក​ហៅ។​​​ ការ​ហៅ​បន្ទាប់៖​ បាន​ដាក់កម្រិត"</string>
+    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"មិន​បាន​ដាក់កម្រិត​លំនាំដើម​លេខ​សម្គាល់​អ្នក​ហៅ។ ការ​ហៅ​បន្ទាប់៖ មិន​បាន​ដាក់​កម្រិត។"</string>
+    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"មិន​បាន​ដាក់​កម្រិត​លេខ​សម្គាល់​អ្នក​ហៅ​លំនាំ​ដើម។ ការ​ហៅ​បន្ទាប់៖​ បាន​ដាក់កម្រិត"</string>
+    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"មិន​បាន​ដាក់កម្រិត​លំនាំដើម​លេខ​សម្គាល់​អ្នក​ហៅ។ ការ​ហៅ​បន្ទាប់៖ មិន​បាន​ដាក់​កម្រិត។"</string>
+    <string name="serviceNotProvisioned" msgid="8614830180508686666">"មិន​បាន​ផ្ដល់​សេវាកម្ម។"</string>
+    <string name="CLIRPermanent" msgid="3377371145926835671">"អ្នក​មិន​អាច​ប្ដូរ​ការ​កំណត់​លេខ​សម្គាល់​អ្នក​ហៅ​បានទេ។"</string>
+    <string name="RestrictedChangedTitle" msgid="5592189398956187498">"បាន​ប្ដូរ​ការ​ចូល​ដំណើរការ​ដែល​បាន​ដាក់​​កម្រិត"</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="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>
+    <string name="serviceClassDataSync" msgid="7530000519646054776">"ធ្វើ​សម​កាល​កម្ម"</string>
+    <string name="serviceClassPacket" msgid="6991006557993423453">"កញ្ចប់​ព័ត៌មាន"</string>
+    <string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
+    <string name="roamingText0" msgid="7170335472198694945">"បើក​ទ្រនិច​បង្ហាញ​រ៉ូមីង"</string>
+    <string name="roamingText1" msgid="5314861519752538922">"បិទ​ទ្រនិច​បង្ហាញ​រ៉ូមីង"</string>
+    <string name="roamingText2" msgid="8969929049081268115">"ពន្លឺ​​ទ្រនិច​បង្ហាញ​រ៉ូមីង"</string>
+    <string name="roamingText3" msgid="5148255027043943317">"ចេញ​ពី​អ្នកជិតខាង"</string>
+    <string name="roamingText4" msgid="8808456682550796530">"ក្រៅ​​អាគារ"</string>
+    <string name="roamingText5" msgid="7604063252850354350">"រ៉ូមីង - ប្រព័ន្ធ​ពេញចិត្ត"</string>
+    <string name="roamingText6" msgid="2059440825782871513">"រ៉ូ​មីង - ប្រព័ន្ធ​​អាច​ប្រើ​បាន"</string>
+    <string name="roamingText7" msgid="7112078724097233605">"រ៉ូ​មីង - ​សម្ពន្ធភាព"</string>
+    <string name="roamingText8" msgid="5989569778604089291">"រ៉ូ​មីង - ដៃគូ​ពិសេស"</string>
+    <string name="roamingText9" msgid="7969296811355152491">"រ៉ូ​មីង - មុខងារ​សេវា​កម្ម​ពេញលេញ"</string>
+    <string name="roamingText10" msgid="3992906999815316417">"រ៉ូ​មីង - មុខងារ​សេវា​តាម​​ផ្នែក"</string>
+    <string name="roamingText11" msgid="4154476854426920970">"បើក​បដា​រ៉ូមីង"</string>
+    <string name="roamingText12" msgid="1189071119992726320">"បិទ​បដា​រ៉ូមីង"</string>
+    <string name="roamingTextSearching" msgid="8360141885972279963">"​ស្វែង​រក​សេវាកម្ម"</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="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="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="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="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="default" msgid="3475999286680000541">"ឧបករណ៍​ផ្ទុក​ទូរស័ព្ទ​ពេញ! លុប​ឯកសារ​មួយ​ចំនួន​ដើម្បី​បង្កើន​ទំហំ។"</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"បណ្ដាញ​អាច​ត្រូវ​បាន​តាមដាន"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
+    <string name="me" msgid="6545696007631404292">"ខ្ញុំ"</string>
+    <string name="power_dialog" product="tablet" msgid="8545351420865202853">"ជម្រើស​កុំព្យូទ័រ​បន្ទះ"</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="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="shutdown_progress" msgid="2281079257329981203">"កំពុង​បិទ..."</string>
+    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"កុំព្យូទ័រ​បន្ទះ​របស់​អ្នក​នឹង​បិទ។"</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="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_bug_report" msgid="7934010578922304799">"របាយការណ៍​កំហុស"</string>
+    <string name="bugreport_title" msgid="2667494803742548533">"យក​របាយការណ៍​កំហុស"</string>
+    <string name="bugreport_message" msgid="398447048750350456">"វា​នឹង​​ប្រមូល​ព័ត៌មាន​អំពី​ស្ថានភាព​ឧបករណ៍​របស់​អ្នក ដើម្បី​ផ្ញើ​ជា​សារ​អ៊ីមែល។ វា​នឹង​ចំណាយ​ពេល​តិច​ពី​ពេល​ចាប់ផ្ដើម​របាយការណ៍​រហូត​ដល់​ពេល​វា​រួចរាល់​ដើម្បី​ផ្ញើ សូម​អត់ធ្មត់។"</string>
+    <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_airplane_mode_on_status" msgid="2719557982608919750">"បាន​បើក​របៀប​ពេល​ជិះ​យន្ត​ហោះ"</string>
+    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"បាន​បិទ​របៀប​យន្តហោះ"</string>
+    <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
+    <string name="safeMode" msgid="2788228061547930246">"របៀប​​​សុវត្ថិភាព"</string>
+    <string name="android_system_label" msgid="6577375335728551336">"ប្រព័ន្ធ​​ Android"</string>
+    <string name="permgrouplab_costMoney" msgid="5429808217861460401">"សេវាកម្ម​ដែល​កាត់​លុយ​របស់​អ្នក"</string>
+    <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"ធ្វើ​អ្វី​ដែល​អាច​កាត់​លុយ​របស់​អ្នក។"</string>
+    <string name="permgrouplab_messages" msgid="7521249148445456662">"សារ​របស់​អ្នក"</string>
+    <string name="permgroupdesc_messages" msgid="7821999071003699236">"អាន និង​សរសេរ​សារ SMS, អ៊ីមែល និង​សារ​ផ្សេងៗ​ទៀត​របស់​អ្នក។"</string>
+    <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"ព័ត៌មាន​ផ្ទាល់ខ្លួន​របស់​អ្នក"</string>
+    <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"ចូល​ដំណើរការ​ព័ត៌មាន​ដោយ​ផ្ទាល់​អំពី​អ្នក​ ដែល​បា​ន​រក្សាទុក​ក្នុង​កាត​ទំនាក់ទំនង​របស់​អ្នក។"</string>
+    <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"ព័ត៌មាន​សង្គម​របស់​អ្នក"</string>
+    <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"ចូល​ដំណើរការ​ព័ត៌មាន​ដោយ​ផ្ទាល់​អំពី​ទំនាក់ទំនង និង​ការ​ភ្ជាប់​សង្គម​របស់​អ្នក។"</string>
+    <string name="permgrouplab_location" msgid="635149742436692049">"ទីតាំង​របស់​អ្នក"</string>
+    <string name="permgroupdesc_location" msgid="5704679763124170100">"តាមដាន​ទីតាំង​ជាក់ស្ដែង​របស់​អ្នក។"</string>
+    <string name="permgrouplab_network" msgid="5808983377727109831">"ការ​ទាក់ទង​បណ្ដាញ"</string>
+    <string name="permgroupdesc_network" msgid="4478299413241861987">"ចូល​ដំណើរការ​លក្ខណៈ​​បណ្ដាញ​ផ្សេងៗ។"</string>
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"ប៊្លូធូស"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"ចូល​ដំណើរការ​ឧបករណ៍ និង​បណ្ដាញ​តាម​ប៊្លូធូស។"</string>
+    <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"ការ​កំណត់​អូឌីយ៉ូ"</string>
+    <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"ប្ដូរ​ការ​កំណត់​អូឌីយ៉ូ។"</string>
+    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"ប៉ះពាល់​ដល់​ថ្ម"</string>
+    <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"ប្រើ​លក្ខណៈ​ដែល​អាច​ប្រើ​ថាមពល​ថ្ម​យ៉ាង​រហ័ស។"</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"ប្រតិទិន"</string>
+    <string name="permgroupdesc_calendar" msgid="5777534316982184416">"​ចូល​ដំណើរការ​​ប្រតិទិន​\"និង​ព្រឹត្តិការណ៍​ដោយ​ផ្ទាល់​។"</string>
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"អាន​វចនានុក្រម​អ្នក​ប្រើ"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"អាន​ពាក្យ​នៅ​ក្នុង​វចនានុក្រម​​អ្នក​ប្រើ​។"</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"សរសេរ​វចនានុក្រម​អ្នក​ប្រើ"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"បន្ថែម​ពាក្យ​ទៅ​វចនានុក្រម​អ្នក​ប្រើ។"</string>
+    <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"ចំណាំ​ និង​ប្រវត្តិ"</string>
+    <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"ចូល​​ដំណើរការ​ចំណាំ និង​ប្រវត្តិ​កម្មវិធី​អ៊ីនធឺណិត​ដោយ​ផ្ទាល់។"</string>
+    <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"រោទ៍"</string>
+    <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"កំណត់​នាឡិកា​រោទ៍"</string>
+    <string name="permgrouplab_voicemail" msgid="4162237145027592133">"សារ​ជា​សំឡេង"</string>
+    <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"ចូល​ដំណើរការ​សារ​ជា​សំឡេង​ដោយ​ផ្ទាល់។"</string>
+    <string name="permgrouplab_microphone" msgid="171539900250043464">"មីក្រូ​ហ្វូន"</string>
+    <string name="permgroupdesc_microphone" msgid="7106618286905738408">"ចូល​ដំណើរការ​​មីក្រូហ្វូន​ដោយ​ផ្ទាល់ ​ដើម្បី​ថត​សំឡេង​។"</string>
+    <string name="permgrouplab_camera" msgid="4820372495894586615">"ម៉ាស៊ីន​ថត"</string>
+    <string name="permgroupdesc_camera" msgid="2933667372289567714">"ចូល​ដំណើរការ​ម៉ាស៊ីន​ថត​រូប ឬ​វីដេអូ​ដោយ​ផ្ទាល់។"</string>
+    <string name="permgrouplab_screenlock" msgid="8275500173330718168">"ចាក់សោ​​អេក្រង់"</string>
+    <string name="permgroupdesc_screenlock" msgid="7067497128925499401">"មាន​សមត្ថភាព​ប៉ះពាល់​ឥរិយាបថ​ការ​ចាក់​សោ​អេក្រង់​លើ​ឧបករណ៍​របស់​អ្នក។"</string>
+    <string name="permgrouplab_appInfo" msgid="8028789762634147725">"ព័ត៌មាន​កម្មវិធី​របស់​អ្នក"</string>
+    <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"លទ្ធភាព​ប៉ះពាល់​ដល់​ឥរិយាបថ​កម្មវិធី​ផ្សេងៗ​លើ​ឧបករណ៍​របស់​អ្នក។"</string>
+    <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"ផ្ទាំង​រូបភាព"</string>
+    <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"ប្ដូរ​ការ​កំណត់​ផ្ទាំង​រូបភាព​ឧបករណ៍"</string>
+    <string name="permgrouplab_systemClock" msgid="406535759236612992">"នាឡិកា"</string>
+    <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"ប្ដូរ​ពេលវេលា ឬ​តំបន់​ពេលវេលា​ឧបករណ៍"</string>
+    <string name="permgrouplab_statusBar" msgid="2095862568113945398">"របារ​ស្ថានភាព"</string>
+    <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"ប្ដូរ​ការ​កំណត់​របារ​ស្ថានភាព​ឧបករណ៍។"</string>
+    <string name="permgrouplab_syncSettings" msgid="3341990986147826541">"ការ​កំណត់​​​ធ្វើ​សម​កាល​កម្ម"</string>
+    <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"ចូល​ដំណើរការ​ការ​កំណត់​ធ្វើ​សម​កាល​កម្ម។"</string>
+    <string name="permgrouplab_accounts" msgid="3359646291125325519">"គណនី​របស់​អ្នក"</string>
+    <string name="permgroupdesc_accounts" msgid="4948732641827091312">"ចូល​ដំណើរការ​គណនី​ដែល​មាន។"</string>
+    <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"ពិនិត្យ​ផ្នែករឹង"</string>
+    <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"ចូល​ដំណើរការ​ផ្នែក​រឹង​ដោយ​ផ្ទាល់​ក្នុង​ទូរស័ព្ទ។"</string>
+    <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"ហៅ​ទូរស័ព្ទ"</string>
+    <string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"តាមដាន ថត និង​ដំណើរការ​ការ​ហៅ​ទូរស័ព្ទ។"</string>
+    <string name="permgrouplab_systemTools" msgid="4652191644082714048">"ឧបករណ៍​ប្រព័ន្ធ"</string>
+    <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"ចូល​ដំណើរការ​កម្រិត​ទាប និង​ពិនិត្យ​ប្រព័ន្ធ។"</string>
+    <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"ឧបករណ៍​​អភិវឌ្ឍ"</string>
+    <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"លក្ខណៈ​ចាំបាច់​សម្រាប់​តែ​អ្នក​អភិវឌ្ឍ​កម្មវិធី។"</string>
+    <string name="permgrouplab_display" msgid="4279909676036402636">"ចំណុច​ប្រទាក់​អ្នក​ប្រើ​កម្មវិធី​ផ្សេងៗ"</string>
+    <string name="permgroupdesc_display" msgid="6051002031933013714">"ប្រសិទ្ធ​ភាព​ចំណុច​ប្រទាក់​អ្នក​ប្រើ​នៃ​កម្មវិធី​ផ្សេងៗ។"</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"ការ​ផ្ទុក"</string>
+    <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"ចូល​ដំណើរការ​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី។"</string>
+    <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"ចូល​ដំណើរការ​កាត​អេសឌី"</string>
+    <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"លក្ខណៈ​ភាព​ងាយស្រួល"</string>
+    <string name="permgroupdesc_accessibilityFeatures" msgid="4205196881678144335">"លក្ខណៈ​ដែល​ជា​បច្ចេកវិទ្យា​ជំនួយ​អាច​ស្នើ។"</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="5800552516779249356">"ធាតុ​បាន​ប៉ះ​នឹង​ត្រូវ​បាន​អាន​ឮ​ៗ អេក្រង់​អាច​ត្រូវ​បាន​ស្វែងរក​ដោយ​ប្រើ​កាយវិការ។"</string>
+    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"បើក​ការ​ចូល​ដំណើរការ​បណ្ដាញ​ដែល​បាន​ធ្វើ​ឲ្យ​ប្រសើរ"</string>
+    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"ស្គ្រីប​អាច​ត្រូវ​បាន​ដំឡើង​ ដើម្បី​ធ្វើ​ឲ្យ​មាតិកា​កម្មវិធី​អាច​ចូល​ដំណើរការ​បាន​កាន់តែ​ច្រើន។"</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"មើល​អត្ថបទ​ដែល​វាយ"</string>
+    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"រួម​បញ្ចូល​ទិន្នន័យ​ផ្ទាល់​ខ្លួន​ ដូចជា​លេខ​កាត​ឥណទាន និង​ពាក្យ​សម្ងាត់។"</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"បិទ ឬ​កែ​របារ​ស្ថានភាព"</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"ឲ្យ​កម្មវិធី​បិទ​របារ​ស្ថានភាព ឬ​បន្ថែម និង​លុប​រូប​តំណាង​ប្រព័ន្ធ។"</string>
+    <string name="permlab_statusBarService" msgid="7247281911387931485">"របារ​ស្ថានភាព"</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_processOutgoingCalls" msgid="3906007831192990946">"នាំ​ផ្លូវ​ការ​ហៅ​ចេញ​ឡើងវិញ"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"ឲ្យ​កម្មវិធី​ដំណើរការ​ការ​ហៅ​ចេញ និង​ប្ដូរ​លេខ​ត្រូវ​ហៅ។ សិទ្ធិ​នេះ​អនុញ្ញាត​ឲ្យ​កម្មវិធី​តាមដាន ប្ដូរ​ទិស ឬ​ការពារ​ការ​ហៅ​ចេញ។"</string>
+    <string name="permlab_receiveSms" msgid="8673471768947895082">"ទទួល​សារ​អត្ថបទ (សារ SMS​)"</string>
+    <string name="permdesc_receiveSms" msgid="6424387754228766939">"ឲ្យ​កម្មវិធី​ទទួល និង​ដំណើរការ​​សារ MMS ។ មាន​ន័យ​ថា កម្មវិធី​អាច​ត្រួតពិនិត្យ​ ឬ​លុប​សារ​ដែល​បាន​ផ្ញើ​ទៅ​ឧបករណ៍​របស់​អ្នក ដោយ​​មិន​បង្ហាញ​អ្នក។"</string>
+    <string name="permlab_receiveMms" msgid="1821317344668257098">"ទទួល​សារ​អត្ថបទ (MMS​)"</string>
+    <string name="permdesc_receiveMms" msgid="533019437263212260">"ឲ្យ​កម្មវិធី​ទទួល និង​ដំណើរការ​​សារ​ MMS ។ វា​មាន​ន័យ​ថា កម្មវិធី​អាច​តាមដាន​ ឬ​លុប​សារ​ដែល​បាន​ផ្ញើ​ទៅ​ឧបករណ៍​របស់​អ្នក​ដោយ​មិន​បង្ហាញ​ពួកវា។"</string>
+    <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"ទទួល​ការ​ប្រកាស​ពេល​​​អាសន្ន"</string>
+    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"ឲ្យ​កម្មវិធី​ទទួល​​ដំណើរការ​សារ​ប្រកាស​ពេល​អាសន្ន។ សិទ្ធិ​នេះ​មាន​តែ​​កម្មវិធី​ប្រព័ន្ធ​ប៉ុណ្ណោះ​​អាច​ប្រើ​បាន​។"</string>
+    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"អាន​សារ​ប្រកាស​ចល័ត"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"ឲ្យ​កម្មវិធី​អាន​សារ​ប្រកាស​ការ​ហៅ​ដែល​ឧបករណ៍​របស់​​អ្នក​បាន​ទទួល។ ការ​ជូន​ដំណឹង​ប្រកាស​ចល័ត​ត្រូវ​បាន​បញ្ជូន​ទៅ​ទីតាំង​មួយ​ចំនួន ដើម្បី​ព្រមាន​អ្នក​អំពី​ស្ថានភាព​អាសន្ន។ កម្មវិធី​ព្យាបាទ​អាច​ជ្រៀតជ្រែក​ការ​អនុវត្ត ឬ​ប្រតិបត្តិការ​ឧបករណ៍​របស់​អ្នក​​ពេល​ទទួល​ការ​ប្រកាស​ចល័ត​ពេល​អាសន្ន។"</string>
+    <string name="permlab_sendSms" msgid="5600830612147671529">"ផ្ញើ​សារ SMS"</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"ឲ្យ​កម្មវិធី​ផ្ញើ​សារ​ SMS ។ វា​អាច​គិត​ថ្លៃ​សេវាកម្ម​ដែល​មិន​រំពឹង​ទុក។ កម្មវិធី​ព្យាបាទ​អាច​គិត​ថ្លៃ​សេវាកម្ម​ពី​អ្នក​ ដោយ​ផ្ញើ​សារ​ដោយ​គ្មាន​ការ​បញ្ជាក់​របស់​អ្នក។"</string>
+    <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"ផ្ញើ​ព្រឹត្តិការណ៍​សារ​តាមរយៈ​ការ​ឆ្លើយតប"</string>
+    <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"ឲ្យ​កម្មវិធី​ផ្ញើ​សំណើ​ទៅ​កម្មវិធី​ផ្ញើ​សារ ដើម្បី​គ្រប់គ្រង​ព្រឹត្តិការណ៍​សារ​តាម​រយៈ​ការ​ឆ្លើយតប​សម្រាប់​ការ​ហៅ​ចូល។"</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"អាន​សារ​អត្ថបទ​របស់​អ្នក (SMS ឬ MMS​)"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"ឲ្យ​កម្មវិធី​​អាន​សារ SMS ដែល​មាន​ក្នុង​កុំព្យូទ័រ​បន្ទះ ឬ​ស៊ីម​កាត។ វា​ឲ្យ​កម្មវិធី​អាន​សារ SMS ទាក់ទង​នឹង​មាតិកា ឬ​ព័ត៌មាន​សម្ងាត់។"</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"ឲ្យ​​កម្មវិធី​អាន​សារ SMS ដែល​បាន​រក្សាទុក​ក្នុង​ទូរស័ព្ទ ឬ​​ស៊ីម​កាត​។ វា​ឲ្យ​កម្មវិធី​អាន​សារ SMS ទាំង​អស់​ ទាក់ទង​នឹង​មាតិកា​ ឬ​ព័ត៌មាន​សម្ងាត់។"</string>
+    <string name="permlab_writeSms" msgid="3216950472636214774">"កែសម្រួល​សារ​អត្ថបទ​របស់​អ្នក (សារ SMS ឬ MMS​)"</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"ឲ្យ​កម្មវិធី​សរសេរ​សារ SMS ដែល​​បាន​រក្សាទុក​ក្នុង​កុំព្យូទ័រ​បន្ទះ ឬ​ស៊ីម​កាត​របស់​អ្នក។ កម្មវិធី​ព្យាបាទ​អាច​លុប​សារ​របស់​អ្នក។"</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"ឲ្យ​កម្មវិធី​សរសេរ​សារ 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_interactAcrossUsers" msgid="7114255281944211682">"អន្តរកម្ម​តាម​​អ្នក​ប្រើ"</string>
+    <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"ឲ្យ​កម្មវិធី​អនុវត្ត​សកម្មភាព​ឆ្លង​អ្នកប្រើ​ផ្សេងៗ​​លើ​ឧបករណ៍។ កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា ដើម្បី​បំពាន​ការ​ការពារ​រវាង​អ្នក​ប្រើ។"</string>
+    <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"អាជ្ញាប័ណ្ណ​ពេញលេញ​ ដើម្បី​ទាក់ទង​អ្នក​ប្រើ"</string>
+    <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"ឲ្យ​អន្តរកម្ម​ដែល​មាន​ទាំង​អស់​គ្រប់​អ្នក​ប្រើ។"</string>
+    <string name="permlab_manageUsers" msgid="1676150911672282428">"គ្រប់គ្រង​អ្នក​ប្រើ"</string>
+    <string name="permdesc_manageUsers" msgid="8409306667645355638">"ឲ្យ​កម្មវិធី​គ្រប់គ្រង​អ្នកប្រើ​លើ​ឧបករណ៍ រួមមាន​ការ​ច្រោះ បង្កើត និង​លុប។"</string>
+    <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"ទៅ​យក​សេចក្ដី​លម្អិត​កម្មវិធី​កំពុង​ដំណើរការ"</string>
+    <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"ឲ្យ​កម្មវិធី​ទៅ​យក​ព័ត៌មាន​លម្អិត​អំពី​កិច្ចការ​ដែល​កំពុង​ដំណើរការ​បច្ចុប្បន្ន។ កម្មវិធី​ព្យាបាទ​អាច​រកមើល​ព័ត៌មាន​ឯកជន​អំពី​កម្មវិធី​ផ្សេងៗ។"</string>
+    <string name="permlab_reorderTasks" msgid="2018575526934422779">"តម្រៀប​កម្មវិធី​កំពុង​ដំណើរការ​ឡើងវិញ"</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"ឲ្យ​កម្មវិធី​ផ្លាស់ទី​ភារកិច្ច​​ទៅ​ផ្ទៃ​ខាង​មុខ។​ កម្មវិធី​អាច​ធ្វើ​វា​ដោយ​គ្មាន​ការ​បញ្ចូល​របស់​អ្នក។"</string>
+    <string name="permlab_removeTasks" msgid="6821513401870377403">"បញ្ឈប់​ដំណើរការ​កម្មវិធី"</string>
+    <string name="permdesc_removeTasks" msgid="1394714352062635493">"ឲ្យ​កម្មវិធី​លុប​ភារកិច្ច​ និង​បញ្ឈប់​កម្មវិធី​របស់​ពួកវា។ កម្មវិធី​ព្យាបាទ​អាច​រំខាន​ឥរិយាបថ​កម្មវិធី​ផ្សេងៗ។"</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"គ្រប់គ្រង​ជង់​សកម្មភាព"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"ឲ្យ​កម្មវិធី​បន្ថែម, លុប និង​កែ​ជង់​សកម្មភាព​ដែល​កម្មវិធី​ផ្សេង​ដំណើរការ។ កម្មវិធី​ព្យាបាទ​អាច​រំខាន​ឥរិយាបថ​កម្មវិធី។"</string>
+    <string name="permlab_startAnyActivity" msgid="2918768238045206456">"ចាប់ផ្ដើម​សកម្មភាព​ណា​មួយ"</string>
+    <string name="permdesc_startAnyActivity" msgid="997823695343584001">"ឲ្យ​កម្មវិធី​ចាប់ផ្ដើម​សកម្មភាព​ណា​មួយ ទាក់ទង​នឹង​សិទ្ធិ​ការពារ​ ឬ​ស្ថានភាព​បាន​នាំចេញ។"</string>
+    <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"កំណត់​ភាព​ឆប​គ្នា​នៃ​អេក្រង់"</string>
+    <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"ឲ្យ​កម្មវិធី​ពិនិត្យ​របៀប​​ត្រូវ​​គ្នា​របស់​​អេក្រង់​នៃ​កម្មវិធី​ផ្សេងៗ។ កម្មវិធី​ព្យាបាទ​អាច​បំផ្លាញ​ឥរិយាបថ​នៃ​កម្មវិធី​ផ្សេងៗ។"</string>
+    <string name="permlab_setDebugApp" msgid="3022107198686584052">"បើក​ការ​កែ​កំហុស​កម្មវិធី"</string>
+    <string name="permdesc_setDebugApp" msgid="4474512416299013256">"ឲ្យ​កម្មវិធី​បើក​ការ​កែ​កំហុស​សម្រាប់​កម្មវិធី​ផ្សេង​ទៀត។ កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា ដើម្បី​បញ្ឈប់​កម្មវិធី​ផ្សេង។"</string>
+    <string name="permlab_changeConfiguration" msgid="4162092185124234480">"ប្ដូរ​ការ​កំណត់​បង្ហាញ​ប្រព័ន្ធ"</string>
+    <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"ឲ្យ​កម្មវិធី​ប្ដូរ​ការ​កំណត់​​រចនាសម្ព័ន្ធ​បច្ចុប្បន្ន ដូច​ជា​មូលដ្ឋាន ឬ​ទំហំ​ពុម្ពអក្សរ​ទាំងអស់។"</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_forceStopPackages" msgid="2329627428832067700">"បង្ខំ​ឲ្យ​បញ្ឈប់​កម្មវិធី​ផ្សេង"</string>
+    <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"ឲ្យ​កម្មវិធី​បញ្ឈប់​កម្មវិធី​ផ្សេង​ដោយ​បង្ខំ។"</string>
+    <string name="permlab_forceBack" msgid="652935204072584616">"បង្ខំ​ឲ្យ​កម្មវិធី​បិទ"</string>
+    <string name="permdesc_forceBack" msgid="3892295830419513623">"ឲ្យ​កម្មវិធី​បង្ខំ​សកម្មភាព​ផ្សេងៗ​ដែល​នៅ​ក្នុង​ផ្ទៃ​ខាង​មុខ​បិទ និង​ទៅ​ក្នុង​ផ្ទៃ​ខាង​ក្រោយ។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_dump" msgid="1681799862438954752">"ទៅ​យក​ស្ថានភាព​ខាង​ក្នុង​ប្រព័ន្ធ"</string>
+    <string name="permdesc_dump" msgid="1778299088692290329">"ឲ្យ​កម្មវិធី​ទៅ​យក​ស្ថានភាព​ខាង​ក្នុង​នៃ​ប្រព័ន្ធ។ កម្មវិធី​ព្យាបាទ​អាច​ទៅ​យក​ព័ត៌មាន​ឯកជន​និង​មាន​សុវត្ថិភាព​ផ្សេងៗ​ដែល​ពួកវា​មិន​គួរ​ត្រូវការ​តាម​ធម្មតា។"</string>
+    <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"ទៅ​យក​មាតិកា​អេក្រង់"</string>
+    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"ឲ្យ​កម្មវិធី​ទៅ​យក​មាតិកា​បង្អួច​សកម្ម។ កម្មវិធី​ព្យាបាទ​អាច​ទៅ​យក​មាតិកា​បង្អួច​ទាំង​មូល និង​ពិនិត្យ​អត្ថបទ​ទាំងអស់ លើកលែង​តែ​ពាក្យ​សម្ងាត់។"</string>
+    <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"បើក​មធ្យោបាយ​ងាយស្រួល​ជា​បណ្ដោះ​អាសន្ន"</string>
+    <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"ឲ្យ​កម្មវិធី​បើក​ភាព​ងាយស្រួល​លើ​ឧបករណ៍​ជា​បណ្ដោះអាសន្ន។ កម្មវិធី​ព្យាបាទ​អាច​បើក​ភាព​ងាយស្រួល​ដោយ​មិន​ឲ្យ​អ្នក​ប្រើ​ដឹង។"</string>
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"ទៅ​យក​ព័ត៌មាន​បង្អួច"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"ឲ្យ​កម្មវិធី ទៅ​យក​ព័ត៌មាន​អំពី​បង្អួច​ពី​កម្មវិធី​គ្រប់គ្រង​បង្អួច។ កម្មវិធី​ព្យាបាទ​អាច​ទៅ​យក​ព័ត៌មាន​ដែល​មាន​បំណង​សម្រាប់​ការ​ប្រើ​ប្រព័ន្ធ​ខាង​ក្នុង។"</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"ច្រោះ​ព្រឹត្តិការណ៍"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"ឲ្យ​កម្មវិធី​ចុះ​ឈ្មោះ​តម្រង​បញ្ចូល​​ដែល​ច្រោះ​​ព្រឹត្តិការណ៍​របស់​អ្នក​ប្រើ​ទាំងអស់​មុន​ពេល​ពួក​វា​ត្រូវ​បាន​ផ្ដាច់។ កម្មវិធី​ព្យាបាទ​អាច​ពិនិត្យ​ចំណុច​ប្រទាក់​ប្រព័ន្ធ​ដោយ​គ្មាន​អំពើ​ពី​អ្នក​ប្រើ។"</string>
+    <string name="permlab_magnify_display" msgid="5973626738170618775">"ពង្រីក​ការ​បង្ហាញ"</string>
+    <string name="permdesc_magnify_display" msgid="7121235684515003792">"ឲ្យ​កម្មវិធី​ពង្រីក​មាតិកា​នៃ​ការ​បង្ហាញ។ កម្មវិធី​ព្យាបាទ​អាច​ប្ដូរ​មាតិកា​ការ​បង្ហាញ​តាមវិធី​ដែល​បង្ហាញ​ថា​ឧបករណ៍​មិន​អាច​ប្រើ​បាន។"</string>
+    <string name="permlab_shutdown" msgid="7185747824038909016">"បិទ​​ដោយ​ផ្នែក"</string>
+    <string name="permdesc_shutdown" msgid="7046500838746291775">"ដាក់​កម្មវិធី​គ្រប់គ្រង​​សកម្មភាព​ក្នុង​ស្ថាន​ភាព​បិទ។ មិន​អនុវត្ត​ការ​បិទ​ពេញលេញ​ទេ។"</string>
+    <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"ការ​ពារ​​ការ​ប្ដូរ​កម្មវិធី"</string>
+    <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"ការ​ពារ​អ្នក​ប្រើ​មិន​ឲ្យ​ប្ដូរ​​ទៅ​កម្មវិធី​ផ្សេង។"</string>
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"យក​ព័ត៌មាន​កម្មវិធី​បច្ចុប្បន្ន"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"ឲ្យ​ម្ចាស់​ទៅ​យក​ព័ត៌មាន​ផ្ទាល់ខ្លួន​អំពី​កម្មវិធី​បច្ចុប្បន្ន​ក្នុង​ផ្ទៃ​ខាង​មុខ​នៃ​អេក្រង់។"</string>
+    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"តាមដាន និង​ពិនិត្យ​ការ​ចាប់ផ្ដើម​កម្មវិធី"</string>
+    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"ឲ្យ​កម្មវិធី​តាមដាន និង​ពិនិត្យ​វិធី​ដែល​ប្រព័ន្ធ​ចាប់ផ្ដើម​​សកម្មភាព។ កម្មវិធី​ព្យាបាទ​អាច​​សម្របសម្រួល​ប្រព័ន្ធ​ទាំង​ស្រុង។ សិទ្ធិ​នេះ​ចាំបាច់​សម្រាប់​តែ​ការ​អភិវឌ្ឍ មិន​សម្រាប់​​ប្រើ​ធម្ម​តា​ទេ។"</string>
+    <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"ផ្ញើ​កញ្ចប់​​ការ​ប្រកាស​បាន​យកចេញ"</string>
+    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"ឲ្យ​កម្មវិធី​ប្រកាស​ការ​ជូន​ដំណឹង​ថា កញ្ចប់​កម្មវិធី​ត្រូវ​បាន​លុប​។ កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា ដើម្បី​​បញ្ឈប់​កម្មវិធី​ដែល​កំពុង​ដំណើរ​ការ​ផ្សេង​ៗ។"</string>
+    <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"ផ្ញើ​ការ​ប្រកាស​បាន​ទទួល SMS"</string>
+    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"ឲ្យ​កម្មវិធី​ប្រកាស​ការ​ជូន​ដំណឹង​​ការ​ទទួល​សារ​ SMS ។ កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា​​ដើម្បី​​បន្លំ​សារ SMS ចូល។"</string>
+    <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"ផ្ញើ​ការ​ប្រកាស​បាន​ទទួល​ WAP-PUSH"</string>
+    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"ឲ្យ​កម្មវិធី​ប្រកាស​ការ​ជូន​ដំណឹង​ថា​បាន​ទទួល​សារ WAP PUSH ។ កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា​ដើម្បី​​ក្លែង​​បង្កាន់ដៃ​សារ MMS ឬ​ជំនួស​មាតិកា​ទំព័រ​បណ្ដាញ​ណាមួយ​ស្ងាត់​ៗ​​​ដោយ​អ្វី​ដែល​ក្លែងក្លាយ។"</string>
+    <string name="permlab_setProcessLimit" msgid="2451873664363662666">"កំណត់​ចំនួន​ដំណើរការ​ដែល​កំពុង​ដំណើរការ"</string>
+    <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"ឲ្យ​កម្មវិធី​ពិនិត្យ​ចំនួន​ដំណើរការ​អតិបរមា​ដែល​នឹង​ដំណើរការ។ មិន​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"បង្ខំ​​ឲ្យ​បិទ​កម្មវិធី​ក្នុង​ផ្ទៃ​ខាង​ក្រោយ"</string>
+    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"ឲ្យ​កម្មវិធី​ពិនិត្យ​ថា​តើ​សកម្មភាព​​ត្រូវ​បាន​បញ្ចប់​ជា​និច្ច​ដរាប​ណា​ពួកគេ​​ទៅ​ក្នុង​ផ្ទៃ​ខាង​ក្រោយ។ មិន​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_batteryStats" msgid="2789610673514103364">"អាន​ស្ថិតិ​ថ្ម"</string>
+    <string name="permdesc_batteryStats" msgid="5897346582882915114">"ឲ្យ​កម្មវិធី​អាន​ទិន្នន័យ​ប្រើ​ថ្ម​កម្រិត​ទាប​បច្ចុប្បន្ន។ អាច​ឲ្យ​កម្មវិធី​ស្វែងយល់​ព័ត៌មាន​លម្អិត​អំពី​កម្មវិធី​ដែល​អ្នក​ប្រើ។"</string>
+    <string name="permlab_updateBatteryStats" msgid="3719689764536379557">"កែ​ស្ថិតិ​ថ្ម"</string>
+    <string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"ឲ្យ​កម្មវិធី​កែ​ស្ថិតិ​ថ្ម​ដែល​បាន​ប្រមូល។ មិន​សម្រាប់​ប្រើ​ដោយ​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_getAppOpsStats" msgid="1508779687436585744">"ទៅ​យក​ស្ថិតិ​ប្រតិបត្តិការ​កម្មវិធី"</string>
+    <string name="permdesc_getAppOpsStats" msgid="6243887041577912877">"ឲ្យ​កម្មវិធី​ទៅ​យក​ស្ថិតិ​ប្រតិបត្តិការ​កម្មវិធី​បាន​ប្រមូល។ មិន​សម្រាប់​ប្រើ​ដោយ​កម្មវិធី​ធម្មតា។"</string>
+    <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"កែ​ស្ថិតិ​ប្រតិបត្តិការ​​កម្មវិធី"</string>
+    <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"ឲ្យ​កម្មវិធី​កែ​ស្ថិតិ​ប្រតិបត្តិការ​កម្មវិធី​បាន​ប្រមូល។ មិន​សម្រាប់​ប្រើ​ដោយ​កម្មវិធី​ធម្មតា។"</string>
+    <string name="permlab_backup" msgid="470013022865453920">"ពិនិត្យ​ការ​ស្ដារ និង​បម្រុង​ទុក​ប្រព័ន្ធ"</string>
+    <string name="permdesc_backup" msgid="6912230525140589891">"ឲ្យ​កម្មវិធី​ពិនិត្យ​​យន្តការ​​បម្រុងទុក​ និង​ស្ដារ​ឡើងវិញ​របស់​ប្រព័ន្ធ។ មិន​សម្រាប់​ប្រើ​ដោយ​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"បញ្ជាក់​​ប្រតិបត្តិការ​ស្ដារ​ឡើងវិញ ឬ​បម្រុង​ទុក​ពេញលេញ"</string>
+    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"ឲ្យ​កម្មវិធី​ចាប់ផ្ដើម​ចំណុច​ប្រទាក់​​បញ្ជាក់​ការ​បម្រុង​ទុក​ពេញលេញ។ មិន​សម្រាប់​ប្រើ​ដោយ​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"បង្ហាញ​បង្អួច​គ្មាន​សិទ្ធិ"</string>
+    <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"ឲ្យ​កម្មវិធី​បង្កើត​បង្អួច​​សម្រាប់​ប្រើ​ដោយ​ចំណុច​ប្រទាក់​អ្នកប្រើ​ប្រព័ន្ធ​ខាង​ក្នុង។ មិន​សម្រាប់​ប្រើ​ដោយ​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"គូរ​លើ​កម្មវិធី​ផ្សេង"</string>
+    <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"ឲ្យ​​កម្មវិធី​គូរ​លើ​ផ្នែក​ខាង​លើ​នៃ​កម្មវិធី​ផ្សេងៗ ឬ​ជា​ផ្នែក​នៃ​ចំណុច​ប្រទាក់។ វា​អាច​រំខាន​ការ​ប្រើ​ចំណុច​ប្រទាក់​របស់​អ្នក​​ក្នុង​កម្មវិធី​ណាមួយ ឬ​ប្ដូរ​អ្វី​ដែល​អ្នក​គិត​ថា​អ្នក​កំពុង​មើល​ក្នុង​កម្មវិធី​ផ្សេងៗ។"</string>
+    <string name="permlab_setAnimationScale" msgid="2805103241153907174">"កែ​ល្បឿន​ចលនា​សកល"</string>
+    <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"ឲ្យ​កម្មវិធី​ប្ដូរ​ល្បឿន​ចលនា​សកល (ចលនា​លឿន​ ឬ​យឺត) នៅ​ពេលណា​មួយ។"</string>
+    <string name="permlab_manageAppTokens" msgid="1286505717050121370">"គ្រប់គ្រង​និមិត្តសញ្ញា​កម្មវិធី"</string>
+    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"ឲ្យ​កម្មវិធី​បង្កើត និង​គ្រប់គ្រង​និមិត្តសញ្ញា​ផ្ទាល់​របស់​ពួក​វា ដោយ​ឆ្លង​កាត់​លំដាប់ Z ធម្មតា​របស់​វា។ មិន​គួរ​​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_freezeScreen" msgid="4708181184441880175">"បង្ក​ក​​អេក្រង់"</string>
+    <string name="permdesc_freezeScreen" msgid="8558923789222670064">"ឲ្យ​កម្មវិធី​បង្កក​អេក្រង់​ជា​បណ្ដោះអាសន្ន​សម្រាប់​​ការ​​ផ្លាស់ប្ដូរ​ពេញ​អេក្រង់។"</string>
+    <string name="permlab_injectEvents" msgid="1378746584023586600">"ចុច​គ្រាប់ចុច និង​គ្រប់គ្រង​ប៊ូតុង"</string>
+    <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"ឲ្យ​កម្មវិធី​ផ្ដល់​ព្រឹត្តិការណ៍​បញ្ចូល​ផ្ទាល់​ខ្លួន​(ចុច​គ្រាប់ចុច ។ល។) ទៅ​កម្មវិធី​ផ្សេង។​ កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា​ដើម្បី​គ្រប់គ្រង​កុំព្យូទ័រ​បន្ទះ។"</string>
+    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"ឲ្យ​កម្មវិធី​ផ្ដល់​ព្រឹត្តិការណ៍​បញ្ចូល​ផ្ទាល់​ខ្លួន​របស់​វា (ចុច​គ្រាប់​ចុច ។ល។) ចំពោះ​កម្មវិធី​ផ្សេងៗ។ កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា​ដើម្បី​គ្រប់គ្រង​ទូរស័ព្ទ។"</string>
+    <string name="permlab_readInputState" msgid="469428900041249234">"កត់ត្រា​នូវ​អ្វី​ដែល​អ្នក​វាយ​ និង​សកម្មភាព​ដែល​អ្នក​បាន​យក"</string>
+    <string name="permdesc_readInputState" msgid="8387754901688728043">"ឲ្យ​កម្មវិធី​មើល​គ្រាប់​ចុច​ដែល​អ្នក​ចុច​ពេល​មាន​អន្តរកម្ម​ជា​មួយ​កម្មវិធី​ផ្សេង (ដូចជា បញ្ចូល​ពាក្យ​សម្ងាត់)។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_bindInputMethod" msgid="3360064620230515776">"ចង​ទៅ​វិធីសាស្ត្រ​បញ្ចូល"</string>
+    <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"ឲ្យ​ម្ចាស់​ចង​ចំណុច​ប្រទាក់​កម្រិត​កំពូល​នៃ​វិធី​សាស្ត្រ​បញ្ចូល។ មិន​គួរ​​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"ចង​សេវា​កម្ម​ភាព​មធ្យោបាយ​ងាយស្រួល"</string>
+    <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"ឲ្យ​​ម្ចាស់​ចង​ចំណុច​ប្រទាក់​កម្រិត​កំពូល​នៃ​សេវាកម្ម​ភាព​ងាយស្រួល។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"ចង​សេវាកម្ម​​បោះពុម្ព"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"ឲ្យ​ម្ចាស់​ចង​ចំណុច​ប្រទាក់​កម្រិត​កំពូល​នៃ​សេវាកម្ម​ធាតុ​ក្រាហ្វិក។ មិន​គួរ​​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"ភ្ជាប់​ទៅ​សេវាកម្ម print spooler"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"អនុញ្ញាត​ឲ្យ​ម្ចាស់​ភ្ជាប់​ទៅ​ចំណុច​ប្រទាក់​កម្រិត​កំពូល​នៃ​សេវាកម្ម print spooler ។ មិន​គួរ​ទាមទារ​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"ភ្ជាប់​ជាមួយ​សេវាកម្ម NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"អនុញ្ញាត​ឲ្យ​​ភ្ជាប់​​​បញ្ជី​ជាមួយ​​កម្មវិធី​ដែល​ត្រូវ​បាន​ត្រាប់​តាម​​កាត NFC ។ មិន​គួរ​ត្រូវ​​ការ​សម្រាប់​កម្មវិធី​ធម្មតា​។"</string>
+    <string name="permlab_bindTextService" msgid="7358378401915287938">"ចង​សេវា​កម្ម​អត្ថបទ"</string>
+    <string name="permdesc_bindTextService" msgid="8151968910973998670">"ឲ្យ​ម្ចាស់​ចង​ចំណុច​ប្រទាក់​កម្រិត​កំពូល​នៃ​សេវាកម្ម​អត្ថបទ (ឧ. SpellCheckerService) ។ មិន​គួរ​ប្រើ​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_bindVpnService" msgid="4708596021161473255">"ចង​ជា​មួយ​សេវាកម្ម VPN"</string>
+    <string name="permdesc_bindVpnService" msgid="2067845564581693905">"ឲ្យ​ម្ចាស់​ចង​ចំណុច​ប្រទាក់​កម្រិត​កំពូល​នៃ​សេវាកម្ម Vpn ។​ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_bindWallpaper" msgid="8716400279937856462">"ចង​ទៅ​ផ្ទាំង​រូបភាព"</string>
+    <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"ឲ្យ​ម្ចាស់​ចង​ចំណុចប្រទាក់​កម្រិត​កំពូល​នៃ​ផ្ទាំង​រូបភាព។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ចង​សេវា​កម្ម​ធាតុ​ក្រាហ្វិក"</string>
+    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"ឲ្យ​ម្ចាស់​ចង​ចំណុច​ប្រទាក់​កម្រិត​កំពូល​នៃ​សេវាកម្ម​ធាតុ​ក្រាហ្វិក។ មិន​គួរ​​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"ទាក់ទង​ជា​មួយ​អ្នកគ្រប់គ្រង​ឧបករណ៍"</string>
+    <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"ឲ្យ​ម្ចាស់​ផ្ញើ​គោលបំណង​​ទៅ​អ្នក​គ្រប់គ្រង​ឧបករណ៍។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"បន្ថែម​ ឬ​លុប​កម្មវិធី​គ្រប់គ្រង​​​ឧបករណ៍"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"អនុញ្ញាត​​​ឲ្យ​ម្ចាស់​​​បន្ថែម​ ឬ​លុប​កម្មវិធី​គ្រប់គ្រង​ឧបករណ៍​សកម្ម​ចេញ​។ មិន​គួរ​ប្រើ​សម្រាប់​កម្មវិធី​​ធម្មតា​ទេ​។"</string>
+    <string name="permlab_setOrientation" msgid="3365947717163866844">"ប្ដូរ​ទិស​អេក្រង់"</string>
+    <string name="permdesc_setOrientation" msgid="3046126619316671476">"ឲ្យ​កម្មវិធី​ប្ដូរ​ការ​បង្វិល​អេក្រង់​នៅ​ពេល​ណា​មួយ។ មិន​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"ប្ដូរ​ល្បឿន​ទ្រនិច"</string>
+    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"ឲ្យ​កម្មវិធី​ប្ដូរ​ល្បឿន​ទ្រនិច​​កណ្ដុរ ឬ​បន្ទះ​ប៉ះ​​​នៅ​ពេល​ណា​មួយ។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"ប្ដូរ​ប្លង់​ក្ដារ​ចុច"</string>
+    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"ឲ្យ​កម្មវិធី​ប្ដូរ​ប្លង់​ក្ដារ​ចុច។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"ផ្ញើ​សញ្ញា​លីនុច​ទៅ​កម្មវិធី"</string>
+    <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"ឲ្យ​កម្មវិធី​ស្នើ​​សញ្ញា​ដែល​បាន​ផ្ដល់​ត្រូវ​ផ្ញើ​ទៅ​ដំណើរការ​ស្ថិតស្ថេរ​​ទាំង​អស់។"</string>
+    <string name="permlab_persistentActivity" msgid="8841113627955563938">"ធ្វើ​ឲ្យ​កម្មវិធី​ដំណើរការ​ជា​និច្ច"</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"ឲ្យ​កម្មវិធី​ធ្វើជា​ផ្នែក​​ស្ថិតស្ថេរ​ដោយ​ខ្លួន​ឯង​ក្នុង​អង្គ​ចងចាំ។ វា​អាច​កំណត់​អង្គ​ចងចាំ​ដែល​អាច​ប្រើ​បាន​ចំពោះ​កម្មវិធី​ផ្សេងៗ​ ដោយ​ធ្វើឲ្យ​កុំព្យូទ័រ​បន្ទះ​យឺត។"</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"ឲ្យ​កម្មវិធី ធ្វើជា​ផ្នែក​អចិន្ត្រៃយ៍​នៃ​ខ្លួន​ក្នុង​អង្គ​ចងចាំ។ វា​អាច​កម្រិត​អង្គ​ចងចាំ​អាច​ប្រើ​បាន​ ដើម្បី​ធ្វើ​ឲ្យ​កម្មវិធី​ផ្សេង​ធ្វើ​ឲ្យ​ទូរស័ព្ទ​របស់​អ្នក​យឺត។"</string>
+    <string name="permlab_deletePackages" msgid="184385129537705938">"លុប​កម្មវិធី"</string>
+    <string name="permdesc_deletePackages" msgid="7411480275167205081">"ឲ្យ​កម្មវិធី​លុប​កញ្ចប់ Android ។ កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា ដើម្បី​លុប​កម្មវិធី​សំខាន់​ៗ។"</string>
+    <string name="permlab_clearAppUserData" msgid="274109191845842756">"លុប​ទិន្នន័យ​របស់​​កម្មវិធី​ផ្សេង"</string>
+    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"ឲ្យ​កម្មវិធី​សម្អាត​ទិន្នន័យ​អ្នក​ប្រើ។"</string>
+    <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"លុប​ឃ្លាំង​សម្ងាត់​កម្មវិធី​ផ្សេងៗ"</string>
+    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"ឲ្យ​កម្មវិធី​លុប​ឯកសារ​ឃ្លាំង​សម្ងាត់។"</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"វាស់​ទំហំ​ការ​ផ្ទុក​​កម្មវិធី"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"ឲ្យ​កម្មវិធី​ទៅ​យក​កូដ ទិន្នន័យ និង​ទំហំ​ឃ្លាំង​សម្ងាត់​របស់​វា"</string>
+    <string name="permlab_installPackages" msgid="2199128482820306924">"ដំឡើង​កម្មវិធី​ដោយ​ផ្ទាល់"</string>
+    <string name="permdesc_installPackages" msgid="5628530972548071284">"ឲ្យ​កម្មវិធី​ដំឡើង​កញ្ចប់​ Android ដែល​បាន​ធ្វើ​បច្ចុប្បន្ន ឬ​ថ្មី។ កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា ដើម្បី​បន្ថែម​កម្មវិធី​ដែល​មាន​សិទ្ធិ​ដោយ​បំពាន។"</string>
+    <string name="permlab_clearAppCache" msgid="7487279391723526815">"លុប​ទិន្នន័យ​ឃ្លាំង​សម្ងាត់​កម្មវិធី​ទាំងអស់"</string>
+    <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"ឲ្យ​កម្មវិធី​បង្កើន​ទំហំ​ផ្ទុក​កុំព្យូទ័រ​បន្ទះ ដោយ​លុប​ឯកសារ​ក្នុង​ថត​ឃ្លាំង​សម្ងាត់​នៃ​កម្មវិធី​ផ្សេង។ វា​អាច​ធ្វើ​ឲ្យ​កម្មវិធី​ផ្សេង​ចាប់ផ្ដើម​យឺត​ព្រោះថា​​ពួកវា​ត្រូវ​ទៅ​យក​ទិន្នន័យ​ឡើងវិញ។"</string>
+    <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"ឲ្យ​កម្មវិធី​បង្កើន​ទំហំ​ផ្ទុក​ទូរស័ព្ទ​ ដោយ​លុប​ឯកសារ​ក្នុង​ថត​ឃ្លាំង​សម្ងាត់​កម្មវិធី។ វា​អាច​ធ្វើ​ឲ្យ​កម្មវិធី​ផ្សេង​កាន់​តែ​យឺត ព្រោះ​ថា​ពួកវា​​ត្រូវ​ទៅ​យក​ទិន្នន័យ​របស់​ពួកវា។"</string>
+    <string name="permlab_movePackage" msgid="3289890271645921411">"ផ្លាស់ទី​ធនធាន​កម្មវិធី"</string>
+    <string name="permdesc_movePackage" msgid="319562217778244524">"ឲ្យ​កម្មវិធី​ផ្លាស់ទី​ប្រភព​កម្មវិធី​ពី​មេឌៀ​ខាង​ក្នុង​ទៅ​ខាង​ក្រៅ​​ និង​ផ្ទុយ​មក​វិញ។"</string>
+    <string name="permlab_readLogs" msgid="6615778543198967614">"អាន​ទិន្នន័យ​កំណត់​ហេតុ​ប្រែប្រួល"</string>
+    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"ឲ្យ​កម្មវិធី​អាន​ពី​ឯកសារ​កំណត់ហេតុ​ប្រព័ន្ធ។ វា​អនុញ្ញាត​ឲ្យ​រក​មើល​ព័ត៌មាន​ទូទៅ​អំពី​អ្វី​ដែល​អ្នក​កំពុង​ធ្វើជា​មួយ​កុំព្យូទ័រ​បន្ទះ សំខាន់​រួមមាន​ព័ត៌មាន​ផ្ទាល់​ខ្លួន​ ឬ​ឯកជន។"</string>
+    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"ឲ្យ​កម្មវិធី​អាន​ពី​ឯកសារ​កំណត់ហេតុ​ប្រព័ន្ធ។ វា​អនុញ្ញាត​ឲ្យ​រក​មើល​ព័ត៌មាន​ទូទៅ​អំពី​អ្វី​ដែល​អ្នក​កំពុង​ធ្វើជា​មួយ​កុំព្យូទ័រ​បន្ទះ សំខាន់​រួមមាន​ព័ត៌មាន​ផ្ទាល់​ខ្លួន​ ឬ​ឯកជន។"</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"ប្រើ​កម្មវិធី​ឌិកូដ​​មេឌៀ​ណា​មួយ​សម្រាប់​ចាក់​ឡើងវិញ"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"ឲ្យ​កម្មវិធី​ប្រើ​កម្មវិធី​ឌិកូដ​មេឌៀ​ដែល​បាន​ដំឡើង ដើម្បី​ឌិកូដ​សម្រាប់​ការ​ចាក់​ឡើងវិញ។"</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"គ្រប់គ្រង​ព័ត៌មាន​សម្ងាត់​ដែល​ទុកចិត្ត"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"អនុញ្ញាត​ឲ្យ​កម្មវិធី​ដំឡើង និង​លុប​វិញ្ញាបនបត្រ CA នៅ​ពេល​មាន​ព័ត៌មាន​សម្ងាត់​ដែល​ទុកចិត្ត។"</string>
+    <string name="permlab_diagnostic" msgid="8076743953908000342">"អាន/សរសេរ​ធនធាន​គ្រប់គ្រង​ប្រអប់"</string>
+    <string name="permdesc_diagnostic" msgid="6608295692002452283">"ឲ្យ​កម្មវិធី​អាន និង​សរសេរ​ប្រភព​ណាមួយ​ដែល​គ្រប់គ្រង​ដោយ​ក្រុម​អ្នក​វិនិច្ឆ័យ ឧទាហរណ៍ ឯកសារ​នៅ​ក្នុង /dev ។ វា​អាច​ប៉ះពាល់​យ៉ាង​ខ្លាំង​ដល់​ស្ថេរ​ភាព​ និង​សុវត្ថិភាព​ប្រព័ន្ធ។ វា​គួរ​ត្រូវ​បាន​ប្រើ​សម្រាប់​វិនិច្ឆ័យ​ផ្នែក​រឹង​ជាក់​លាក់​ដោយ​ក្រុមហ៊ុន​ផលិត ឬ​ប្រតិបត្តិ​ករ។"</string>
+    <string name="permlab_changeComponentState" msgid="6335576775711095931">"បិទ ឬ​បើក​សមាសធាតុ​កម្មវិធី"</string>
+    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"ឲ្យ​កម្មវិធី​ប្ដូរ​ថា​តើ​សមាសធាតុ​កម្មវិធី​ផ្សេង​ត្រូវ​បាន​បើក​​ ឬ​ក៏​អត់។ កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា ដើម្បី​បិទ​សមត្ថភាព​ទូរស័ព្ទ​សំខាន់។ ប្រើ​ដោយ​ប្រុងប្រយ័ត្ន​ជា​មួយ​​សិទ្ធិ​នេះ ព្រោះ​ថា​វា​អាច​ធ្វើ​ឲ្យ​សមាសធាតុ​មិន​អាច​ប្រើ​បាន​ ស្ថិតស្ថេរ ឬ​​មិន​ស្ថិតស្ថេរ។"</string>
+    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"ឲ្យ​កម្មវិធី​ប្ដូរ​ថាតើ​សមាសធាតុ​កម្មវិធី​ផ្សេង​ត្រូវ​បាន​បើក​​ ឬ​ក៏​អត់។ កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា ដើម្បី​បិទ​សមត្ថភាព​ទូរស័ព្ទ​សំខាន់។ ប្រើ​ដោយ​ប្រុងប្រយ័ត្ន​ជា​មួយ​​សិទ្ធិ​នេះ ព្រោះ​ថា​វា​អាច​ធ្វើ​ឲ្យ​សមាសធាតុ​មិន​អាច​ប្រើ​បាន​ ស្ថិតស្ថេរ ឬ​​មិន​ស្ថិតស្ថេរ។"</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"ផ្ដល់ ឬ​ដក​សិទ្ធិ"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"ឲ្យ​កម្មវិធី​ផ្ដល់ ឬ​ដក​សិទ្ធិ​ជាក់លាក់​សម្រាប់​វា ឬ​កម្មវិធី​ផ្សេង។ កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា​ដើម្បី​ចូល​លក្ខណៈ​ដែល​អ្នក​មិន​បាន​ផ្ដល់​ឲ្យ​ពួកវា។"</string>
+    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"កំណត់​កម្មវិធី​ពេញ​ចិត្ត"</string>
+    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"ឲ្យ​កម្មវិធី​កែ​កម្មវិធី​ដែល​អ្នក​ពេញ​ចិត្ត។ កម្មវិធី​ព្យាបាទ​អាច​ប្ដូរ​កម្មវិធី​ដែល​ដំណើរការ​ស្ងាត់​ៗ ដោយ​​​បញ្ឆោត​កម្មវិធី​ដែល​មាន​ស្រាប់​​របស់​អ្នក​ ដើម្បី​ប្រមូល​ទិន្នន័យ​ឯកជន​​ពី​អ្នក។"</string>
+    <string name="permlab_writeSettings" msgid="2226195290955224730">"កែ​​ការ​កំណត់​ប្រព័ន្ធ"</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"ឲ្យ​កម្មវិធី​កែ​ទិន្នន័យ​កំណត់​ប្រព័ន្ធ។ កម្មវិធី​ព្យាបាទ​អាច​បង្ខូច​ការ​កំណត់​រចនាសម័្ពន្ធ​នៃ​ប្រព័ន្ធ​របស់​អ្នក។"</string>
+    <string name="permlab_writeSecureSettings" msgid="204676251876718288">"កែ​ការ​កំណត់​ប្រព័ន្ធ​សុវត្ថិភាព"</string>
+    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"ឲ្យ​កម្មវិធី​កែ​ទិន្នន័យ​កំណត់​​សុវត្ថិភាព​​របស់​ប្រព័ន្ធ។ មិន​សម្រាប់​ប្រើ​ដោយ​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_writeGservices" msgid="2149426664226152185">"កែ​ផែនទី​សេវាកម្ម​ Google"</string>
+    <string name="permdesc_writeGservices" msgid="1287309437638380229">"ឲ្យ​កម្មវិធី​កែ​ផែនទី​សេវាកម្ម​ Google ។ មិន​សម្រាប់​ប្រើ​ដោយ​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"ដំណើរការ​ពេល​ចាប់ផ្ដើម"</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"ឲ្យ​កម្មវិធី​ចាប់ផ្ដើម​ដោយ​ខ្លួន​វា​ផ្ទាល់​ដរាប​​ណា​ប្រព័ន្ធ​​បាន​ចាប់ផ្ដើម​​រួចរាល់។ វា​អាច​​ចំណាយ​ពេល​យូរ​ដើម្បី​ចាប់ផ្ដើម​កុំព្យូទ័រ​បន្ទះ និង​ឲ្យ​កម្មវិធី​ធ្វើ​ឲ្យ​កុំព្យូទ័រ​បន្ទះ​យឺត​ដោយ​ដំណើរការ​ជា​និច្ច។"</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="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="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="default" msgid="589869224625163558">"ឲ្យ​កម្មវិធី​កែ​ទិន្នន័យ​អំពី​ទំនាក់ទំនង​របស់​អ្នក​ដែល​បាន​រក្សាទុក​ក្នុង​ទូរស័ព្ទ​របស់​អ្នក រួមមាន​ប្រេកង់​ដែល​អ្នក​បាន​ហៅ អ៊ីមែល ឬ​បាន​ទាក់ទង​​តាម​វិធី​ផ្សេងៗ​ជា​មួយ​ទំនាក់​ទំនាក់​ជាក់លាក់។ សិទ្ធិ​នេះ​ឲ្យ​កម្មវិធី​លុប​ទិន្នន័យ​ទំនាក់ទំនង។"</string>
+    <string name="permlab_readCallLog" msgid="3478133184624102739">"អាន​​កំណត់​ហេតុ​​​ហៅ"</string>
+    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"ឲ្យ​កម្មវិធី​អាន​បញ្ជី​ហៅ​កុំព្យូទ័រ​បន្ទះ​របស់​អ្នក រួមមាន​ទិន្នន័យ​អំពី​ការ​ហៅ​ចូល និង​ចេញ។ សិទ្ធិ​នេះ​អនុញ្ញាត​ឲ្យ​កម្មវិធី​រក្សាទុក​ទិន្នន័យ​បញ្ជី​ហៅ​របស់​អ្នក ហើយ​កម្មវិធី​ព្យាបាទ​អាច​ចែករំលែក​ទិន្នន័យ​បញ្ជី​ហៅ​ដោយ​មិន​ឲ្យ​អ្នក​ដឹង។"</string>
+    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"ឲ្យ​កម្មវិធី​អាន​​​បញ្ជី​ហៅ​ទូរស័ព្ទ​របស់​អ្នក រួមមាន​ទិន្នន័យ​អំពី​ការ​ហៅ​ចូល និង​ចេញ។ សិទ្ធិ​នេះ​អនុញ្ញាត​ឲ្យ​កម្មវិធី​រក្សាទុក​ទិន្នន័យ​បញ្ជី​ហៅ​របស់​អ្នក ហើយ​កម្មវិធី​ព្យាបាទ​អាច​ចែករំលែក​ទិន្នន័យ​បញ្ជី​ហៅ​ដោយ​មិន​ឲ្យ​អ្នកដឹង។"</string>
+    <string name="permlab_writeCallLog" msgid="8552045664743499354">"សរសេរ​បញ្ជី​ហៅ"</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ឲ្យ​កម្មវិធី​កែ​បញ្ជី​ហៅ​កុំព្យូទ័រ​បន្ទះ​របស់​អ្នក​រួមមាន​ទិន្នន័យ​អំពី​ការ​ហៅ​ចូល និង​ចេញ។​កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា ដើម្បី​លុប ឬ​កែ​បញ្ជី​ហៅ​របស់​អ្នក។"</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"ឲ្យ​កម្មវិធី​កែ​បញ្ជី​ហៅ​នៃ​ទូរស័ព្ទ​របស់​អ្នក រួមមាន​ទិន្នន័យ​អំពី​ការ​ហៅ​ចូល និង​ចេញ។ កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា ដើម្បី​លុប ឬ​កែ​បញ្ជី​ការ​ហៅ​របស់​អ្នក។"</string>
+    <string name="permlab_readProfile" msgid="4701889852612716678">"អាន​កាត​ទំនាក់ទំនង​ផ្ទាល់ខ្លួន​​របស់​អ្នក"</string>
+    <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"ឲ្យ​កម្មវិធី​អាន​ព័ត៌មាន​ប្រវត្តិរូប​ផ្ទាល់ខ្លួន​ដែល​មាន​លើ​ឧបករណ៍​របស់​អ្នក ដូច​ជា ឈ្មោះ និង​ព័ត៌មាន​ទំនាក់ទំនង។ វា​មាន​ន័យ​ថា កម្មវិធី​អាច​កំណត់​អ្នក និង​អាច​ផ្ញើ​ព័ត៌មាន​ប្រវត្តិរូប​របស់​អ្នក​ទៅ​អ្នក​ផ្សេង។"</string>
+    <string name="permlab_writeProfile" msgid="907793628777397643">"កែ​កាត​ទំនាក់ទំនង​ផ្ទាល់​ខ្លួន​របស់​អ្នក"</string>
+    <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"ឲ្យ​កម្មវិធី​ប្ដូរ ឬ​បន្ថែម​ព័ត៌មាន​ប្រវត្តិរូប​ផ្ទាល់​ខ្លួន​ដែល​បាន​រក្សាទុក​ក្នុង​ឧបករណ៍​របស់​អ្នក ដូចជា ឈ្មោះ និង​ព័ត៌មាន​ទំនាក់ទំនង​របស់​អ្នក។ នេះ​មាន​ន័យ​ថា​កម្មវិធី​អាច​កំណត់​អ្នក និង​ផ្ញើ​ព័ត៌មាន​ប្រវត្តិរូប​របស់​អ្នក​ទៅ​អ្នក​ផ្សេង។"</string>
+    <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"អាន​ចរន្ត​​សង្គម​របស់​អ្នក"</string>
+    <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"ឲ្យ​កម្មវិធី​ចូល​ដំណើរការ និង​ធ្វើ​សម​កាល​កម្ម​បច្ចុប្បន្នភាព​សង្គម​ពី​អ្នក​ និង​មិត្តភ័ក្ដិ។ ប្រយ័ត្ន​ពេល​ចែករំលែក​ព័ត៌មាន វា​អនុញ្ញាត​ឲ្យ​កម្មវិធី​អាន​ការ​ទាក់ទង​រវាង​អ្នក​ និង​មិត្តភ័ក្ដិ​លើ​បណ្ដាញ​សង្គម ទាក់ទង​នឹង​ព័ត៌មាន​សម្ងាត់។ ចំណាំ៖​ សិទ្ធិ​នេះ​មិន​អាច​ត្រូវ​បាន​​អនុវត្ត​លើ​បណ្ដាញ​សង្គម​ទាំង​អស់​បាន​ទេ។"</string>
+    <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"សរសេរ​ទៅ​ចរន្ត​សង្គម​របស់​អ្នក"</string>
+    <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"ឲ្យ​កម្មវិធី​បង្ហាញ​បច្ចុប្បន្នភាព​សង្គម​ពី​មិត្តភ័ក្ដិ​របស់​អ្នក។ ប្រយ័ត្ន​ពេល​ចែករំលែក​ព័ត៌មាន វា​ឲ្យ​កម្មវិធី​បង្កើត​​​សារ​​ដែល​អាច​បង្ហាញ​ថា​មក​ពី​មិត្តភ័ក្ដិ។ ចំណាំ៖ សិទ្ធិ​នេះ​មិន​អាច​ប្រើ​លើ​បណ្ដាញ​សង្គម​បាន​ទេ។"</string>
+    <string name="permlab_readCalendar" msgid="5972727560257612398">"អាន​ព្រឹត្តិការណ៍​ប្រតិទិន​​និង​ព័ត៌មាន​សម្ងាត់"</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"ឲ្យ​កម្មវិធី​អាច​​ព្រឹត្តិការណ៍​ប្រតិទិន​ទាំងអស់​ដែល​បាន​រក្សាទុក​ក្នុង​ទូរស័ព្ទ​របស់​អ្នក  រួមមាន​មិត្តភ័ក្ដិ និង​មិត្ត​រួម​ការងារ។ វា​អាច​ឲ្យ​កម្មវិធី​ចែករំលែក​ ឬ​រក្សាទុក​ទិន្នន័យ​ប្រតិទិន​របស់​អ្នក​​ដោយ​មិន​គិត​ពី​ការ​សម្ងាត់ ឬ​ការ​យល់​ដឹង។"</string>
+    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"ឲ្យ​កម្មវិធី​អាន​ព្រឹត្តិការណ៍​ប្រតិទិន​ទាំងអស់​ដែល​មាន​ក្នុង​កុំព្យូទ័រ​បន្ទះ​របស់​អ្នក រួមមាន​មិត្តភ័ក្ដិ ឬ​មិត្ត​រួម​ការងារ។ វា​អាច​អនុញ្ញាត​ឲ្យ​យ​កម្ម​វិធី​ចែករំលែក ឬ​រក្សាទុក​ទិន្នន័យ​ប្រតិទិន​របស់​អ្នក​ដែល​ទាក់ទង​នឹង​ព័ត៌មាន​សម្ងាត់ ឬ​​ការ​ប្រែប្រួល។"</string>
+    <string name="permlab_writeCalendar" msgid="8438874755193825647">"បន្ថែម ឬ​កែ​ព្រឹត្តិការណ៍​ប្រតិទិន​ និង​ផ្ញើ​អ៊ីមែល​ទៅ​ភ្ញៀវ​ដោយ​មិន​ឲ្យ​ម្ចាស់​ដឹង"</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"ឲ្យ​កម្មវិធី​បន្ថែម លុប ឬ​ប្ដូរ​ព្រឹត្តិការណ៍​ដែល​អ្នក​អាច​កែ​លើ​កុំព្យូទ័រ​បន្ទះ​របស់​អ្នក រួមមាន​មិត្តភ័ក្ដិ ឬ​មិត្ត​រួម​ការងារ។ វា​អាច​ឲ្យ​កម្មវិធី​ផ្ញើ​សារ​ដែល​បង្ហាញ​ថា​មក​ពី​ម្ចាស់​ប្រតិទិន​ ឬ​កែ​ព្រឹត្តិការណ៍​ដោយ​មិន​ឲ្យ​ម្ចាស់​ដឹង។"</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"ឲ្យ​កម្មវិធី​បន្ថែម លុប ឬ​ប្ដូរ​ព្រឹត្តិការណ៍​ដែល​អ្នក​អាច​កែប្រែ​លើ​ទូរស័ព្ទ​របស់​អ្នក រួមមាន​មិត្តភ័ក្ដិ ឬ​មិត្ត​រួម​ការងារ។ វា​​អាច​ឲ្យ​កម្មវិធី​ផ្ញើ​សារ​ដែល​បង្ហាញ​ថា​មក​ពី​ម្ចាស់​ប្រតិទិន ឬ​កែ​ព្រឹត្តិការណ៍​ដោយ​មិន​ឲ្យ​​អ្នក​ដឹង។"</string>
+    <string name="permlab_accessMockLocation" msgid="8688334974036823330">"ក្លែង​ប្រភព​ទីតាំង​សម្រាប់​សាកល្បង"</string>
+    <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"បង្កើត​ប្រភព​ទីតាំង​ក្លែង​ក្លាយ​សម្រាប់​សាកល្បង ឬ​ដំឡើង​ក្រុមហ៊ុន​ផ្ដល់​ទីតាំង​ថ្មី។ វា​អនុញ្ញាត​ឲ្យ​កម្មវិធី​បដិសេធ​ទីតាំង​​ និង/ឬ​ស្ថានភាព​បាន​ត្រឡប់​ដោយ​ប្រភព​ទីតាំង​ផ្សេង​ដូច​ជា GPS ឬ​ក្រុមហ៊ុន​ផ្ដល់​ទីតាំង។"</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"ចូល​ដំណើរការ​ពាក្យ​បញ្ជា​ក្រុមហ៊ុន​ផ្ដល់​ទីតាំង"</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"ឲ្យ​កម្មវិធី​ចូល​ពាក្យ​បញ្ជា​ក្រុមហ៊ុន​ផ្ដល់​ទីតាំង​បន្ថែម។ កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា​ដើម្បី​ជ្រៀតជ្រែក​ជា​មួយ​ប្រតិបត្តិការ​ GPS ឬ​ប្រភព​ទីតាំង​ផ្សេង​ទៀត។"</string>
+    <string name="permlab_installLocationProvider" msgid="6578101199825193873">"សិទ្ធិ ដើម្បី​ដំឡើង​ក្រុមហ៊ុន​ផ្ដល់​ទីតាំង"</string>
+    <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"បង្កើត​ប្រភព​ទីតាំង​ក្លែងក្លាយ​សម្រាប់​សាកល្បង ឬ​ដំឡើង​ក្រុមហ៊ុន​ផ្ដល់​ទីតាំង​ថ្មី។ វា​អនុញ្ញាត​ឲ្យ​កម្មវិធី​បដិសេធ​ទីតាំង​ និង/ឬ​ស្ថានភាព​បាន​ត្រឡប់​ដោយ​ប្រភព​ទីតាំង​ផ្សេងៗ​ដូចជា GPS ឬ​ក្រុមហ៊ុន​ផ្ដល់​ទីតាំង។"</string>
+    <string name="permlab_accessFineLocation" msgid="1191898061965273372">"ទីតាំង​ពិតប្រាកដ (GPS និង​មាន​មូលដ្ឋាន​លើ​បណ្ដាញ)"</string>
+    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"ឲ្យ​កម្មវិធី​ទទួល​ទីតាំង​ពិតប្រាកដ​របស់​អ្នក ដោយ​ប្រើ​ប្រព័ន្ធ​កំណត់​ទីតាំង​សកម្ម (GPS) ឬ​ប្រភព​ទីតាំង​បណ្ដាញ​ដូច​ជា អង់តែន​ចល័ត និង​វ៉ាយហ្វាយ។ សេវាកម្ម​ទីតាំង​ទាំង​នេះ​ត្រូវតែ​បើក និង​អាច​ប្រើ​ចំពោះ​ឧបករណ៍​របស់​អ្នក​សម្រាប់​កម្មវិធី​ដែល​ប្រើ​ពួក​វា។ កម្មវិធី​អាច​ប្រើ​វា ដើម្បី​កំណត់​​ទីកន្លែង​របស់​អ្នក និង​អាច​ប្រើ​ថាមពល​ថ្ម​បន្ថែម។"</string>
+    <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"ទីតាំង​ប្រហាក់ប្រហែល (​​មាន​មូលដ្ឋាន​លើ​បណ្ដាញ)"</string>
+    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"ឲ្យ​កម្មវិធី​ទទួល​ទីតាំង​ប្រហាក់ប្រហែល។ ទីតាំង​នេះ​ត្រូវ​បាន​ទទួល​តាម​សេវាកម្ម​ទីតាំង​ដោយ​ប្រើ​ប្រភព​ទីតាំង​បណ្ដាញ​ដូច​ជា អង់តែន និង​វ៉ាយហ្វាយ។ សេវាកម្ម​ទីតាំង​ទាំង​នេះ​ត្រូវ​តែ​បើក និង​អាច​ប្រើ​បាន​ចំពោះ​ឧបករណ៍​របស់​អ្នក​សម្រាប់​កម្មវិធី​ដែល​ប្រើ​ពួកវា។ កម្មវិធី​អាច​ប្រើ​វា ដើម្បី​កំណត់កន្លែង​ដែល​អ្នក​នៅ​ប្រហាក់ប្រហែល។"</string>
+    <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"ចូល​ដំណើរការ​ SurfaceFlinger"</string>
+    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"ឲ្យ​កម្មវិធី​ប្រើ​លក្ខណៈ​កម្រិត​ទាប​របស់ SurfaceFlinger ។"</string>
+    <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"អាន​អង្គ​ចងចាំ​បណ្ដោះ​អាសន្ន"</string>
+    <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"ឲ្យ​កម្មវិធី​អាន​មាតិកា​នៃ​អង្គ​ចងចាំ​បណ្ដោះ​អាសន្ន។"</string>
+    <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"កំណត់​រចនាសម្ព័ន្ធ​ការ​បង្ហាញ​វ៉ាយហ្វាយ"</string>
+    <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"ឲ្យ​កម្មវិធី​កំណត់​រចនាសម្ព័ន្ធ​ និង​ភ្ជាប់​ទៅ​ការ​បង្ហាញ​វ៉ាយហ្វាយ។"</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"ពិនិត្យ​ការ​បង្ហាញ​វ៉ាយហ្វាយ"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"ឲ្យ​កម្មវិធី​ពិនិត្យ​លក្ខណៈ​កម្រិត​ទាប​​នៃ​ការ​បង្ហាញ​វ៉ាយហ្វាយ។"</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"ចាប់​យក​លទ្ធផល​អូឌីយ៉ូ"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"​ឱ្យ​កម្មវិធី​ដើម្បី​ចាប់​យក​ និង​​ប្ដូរ​​ទិស​លទ្ធផល​អូឌីយ៉ូ​។"</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"ចាប់​យក​លទ្ធផល​វីដេអូ"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"ឲ្យ​កម្មវិធី​ចាប់​យក​ និង​ប្ដូរ​​ទិស​លទ្ធផល​វីដេអូ​។"</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"ចាប់​យក​លទ្ធផល​វីដេអូ​សុវត្ថិភាព"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"ឲ្យ​​កម្មវិធី​​​ចាប់​យក ​និង​ប្ដូរ​ទិស​លទ្ធផល​វីដេអូ​ដែល​មាន​សុវត្ថិភាព​។"</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="4906839301087980680">"​ឱ្យ​កម្មវិធី​ថត​សំឡេង​​ជាមួយ​មីក្រូហ្វូន​​​។ សិទ្ធិ​នេះ​អនុញ្ញាត​ឲ្យ​កម្មវិធី​ថត​សំឡេង​​នៅ​ពេល​ណា​មួយ​ដោយ​គ្មាន​ការ​បញ្ជាក់​របស់​អ្នក។"</string>
+    <string name="permlab_camera" msgid="3616391919559751192">"ថត​រូប និងវីដេអូ"</string>
+    <string name="permdesc_camera" msgid="8497216524735535009">"ឲ្យ​កម្មវិធី​ថត​រូប និង​វីដេអូ​ដោយ​ប្រើ​ម៉ាស៊ីន​ថត។ វា​ឲ្យ​កម្មវិធី​​ប្រើ​ម៉ាស៊ីន​ថត​នៅ​ពេល​​ណាមួយ​ដោយ​គ្មាន​ការ​បញ្ជាក់​របស់​អ្នក។"</string>
+    <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"បិទ​​ពន្លឺ​បង្ហាញ​ការ​បញ្ជូន​​ពេល​ម៉ាស៊ីន​ថត​កំពុង​ប្រើ"</string>
+    <string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"ឲ្យ​កម្មវិធី​ប្រព័ន្ធ​ដែល​បាន​ដំឡើង​រួច​បិទ​​ LED បង្ហាញ​ការ​ប្រើ​ម៉ាស៊ីន​ថត។"</string>
+    <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"បិទ​កុំព្យូទ័រ​បន្ទះ​ជា​អចិន្ត្រៃយ៍"</string>
+    <string name="permlab_brick" product="default" msgid="8337817093326370537">"បិទ​ទូរស័ព្ទ​ជា​អចិន្ត្រៃយ៍"</string>
+    <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"ឲ្យ​កម្មវិធី​បិទ​កុំព្យូទ័រ​បន្ទះ​​​ជា​អចិន្ត្រៃយ៍។ វា​មាន​គ្រោះថ្នាក់​ណាស់។"</string>
+    <string name="permdesc_brick" product="default" msgid="5788903297627283099">"ឲ្យ​កម្មវិធី​បិទ​ទូរស័ព្ទ​ទាំង​មូល​​ជា​អចិន្ត្រៃយ៍។ វា​មាន​គ្រោះ​ថ្នាក់​ណាស់។"</string>
+    <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"បង្ខំ​ឲ្យ​ចាប់ផ្ដើម​កុំព្យូទ័រ​បន្ទះ​ឡើង​វិញ"</string>
+    <string name="permlab_reboot" product="default" msgid="2898560872462638242">"បង្ខំ​ឲ្យ​ទូរស័ព្ទ​ចាប់ផ្ដើម​ឡើងវិញ"</string>
+    <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"ឲ្យ​កម្មវិធី​បង្ខំ​ឲ្យ​​កុំព្យូទ័រ​បន្ទះ​ចាប់ផ្ដើម​ឡើងវិញ។"</string>
+    <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"ឲ្យ​កម្មវិធី​បង្ខំ​​ឲ្យ​ទូរស័ព្ទ​ចាប់ផ្ដើម​ឡើងវិញ។"</string>
+    <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"ការ​ចូល​ដំណើរការ​ប្រព័ន្ធ​ឯកសារ​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី"</string>
+    <string name="permlab_mount_unmount_filesystems" product="default" msgid="4402305049890953810">"ការ​ចូល​ដំណើរការ​ប្រព័ន្ធ​ឯកសារ​កាត​អេសឌី"</string>
+    <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"ឲ្យ​កម្មវិធី​ភ្ជាប់ និង​ផ្ដាច់​ប្រព័ន្ធ​ឯកសារ​សម្រាប់​ឧបករណ៍​ផ្ទុក​ចល័ត។"</string>
+    <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"លុប​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី"</string>
+    <string name="permlab_mount_format_filesystems" product="default" msgid="262582698639274056">"លុប​កាត​អេសឌី"</string>
+    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"ឲ្យ​កម្មវិធី​ធ្វើ​ទ្រង់ទ្រាយ​ឧបករណ៍​ផ្ទុក​ចល័ត។"</string>
+    <string name="permlab_asec_access" msgid="3411338632002193846">"យក​​ព័ត៌មាន​នៅ​លើ​ឧបករណ៍​​ផ្ទុក​ខាងក្នុង"</string>
+    <string name="permdesc_asec_access" msgid="3094563844593878548">"ឲ្យ​កម្មវិធី​យក​ព័ត៌មាន​លើ​ការ​​ផ្ទុក​ខាង​ក្នុង។"</string>
+    <string name="permlab_asec_create" msgid="6414757234789336327">"បង្កើត​​ឧបករណ៍​ផ្ទុក​ខាងក្នុង"</string>
+    <string name="permdesc_asec_create" msgid="4558869273585856876">"ឲ្យ​កម្មវិធី​បង្កើត​ឧបករណ៍​ផ្ទុក​ខាង​ក្នុង។"</string>
+    <string name="permlab_asec_destroy" msgid="526928328301618022">"បំផ្លាញ​​ឧបករណ៍​​ផ្ទុក​ខាងក្នុង"</string>
+    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"ឲ្យ​កម្មវិធី​បំផ្លាញ​ឧបករណ៍​ផ្ទុក​ខាង​ក្នុង។"</string>
+    <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"ភ្ជាប់/ផ្ដាច់​ឧបករណ៍​ផ្ទុក​ខាង​ក្នុង"</string>
+    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"ឲ្យ​កម្មវិធី​ភ្ជាប់/ផ្ដាច់​ឧបករណ៍​ផ្ទុក​ខាង​ក្នុង។"</string>
+    <string name="permlab_asec_rename" msgid="7496633954080472417">"ប្ដូរ​ឈ្មោះ​ឧបករណ៍​ផ្ទុក​ខាង​ក្នុង"</string>
+    <string name="permdesc_asec_rename" msgid="1794757588472127675">"ឲ្យ​កម្មវិធី​ប្ដូរ​ឈ្មោះ​ឧបករណ៍​ផ្ទុក​ខាង​ក្នុង។"</string>
+    <string name="permlab_vibrate" msgid="7696427026057705834">"ពិនិត្យ​ការ​ញ័រ"</string>
+    <string name="permdesc_vibrate" msgid="6284989245902300945">"ឲ្យ​កម្មវិធី​គ្រប់គ្រង​កម្មវិធី​ញ័រ។"</string>
+    <string name="permlab_flashlight" msgid="2155920810121984215">"ត្រួតពិនិត្យ​ពិល"</string>
+    <string name="permdesc_flashlight" msgid="6522284794568368310">"ឲ្យ​កម្មវិធី​ពិនិត្យ​ពិល។"</string>
+    <string name="permlab_manageUsb" msgid="1113453430645402723">"គ្រប់គ្រង​ចំណូល​ចិត្ត និង​សិទ្ធិ​សម្រាប់​ឧបករណ៍​យូអេសប៊ី"</string>
+    <string name="permdesc_manageUsb" msgid="7776155430218239833">"ឲ្យ​កម្មវិធី​គ្រប់គ្រង​ចំណូល​ចិត្ត និង​សិទ្ធិ​ឧបករណ៍​យូអេសប៊ី។"</string>
+    <string name="permlab_accessMtp" msgid="4953468676795917042">"អនុវត្ត​ពិធីការ MTP"</string>
+    <string name="permdesc_accessMtp" msgid="6532961200486791570">"ចូល​ដំណើរការ​កម្មវិធី​បញ្ជា kernel MTP ដើម្បី​អនុវត្ត​ពិធីការ​យូអេសប៊ី MTP ។"</string>
+    <string name="permlab_hardware_test" msgid="4148290860400659146">"សាកល្បង​ផ្នែក​រឹង"</string>
+    <string name="permdesc_hardware_test" msgid="6597964191208016605">"ឲ្យ​កម្មវិធី​ពិនិត្យ​គ្រឿង​ផ្សេងៗ​​សម្រាប់​សាកល្បង​ផ្នែក​រឹង។"</string>
+    <string name="permlab_callPhone" msgid="3925836347681847954">"ហៅ​លេខ​ទូរស័ព្ទ​ដោយ​ផ្ទាល់"</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"ឲ្យ​កម្មវិធី​ហៅ​លេខ​ទូរស័ព្ទ​ដោយ​គ្មាន​សកម្មភាព​របស់​អ្នក។​ វា​អាច​កាត់​លុយ​ ឬ​ហៅ​ដោយ​មិន​រំពឹង​ទុក។ ចំណាំ​ថា​ វា​មិន​អនុញ្ញាត​ឲ្យ​កម្មវិធី​ហៅ​លេខ​ពេល​អាសន្ន​ទេ។ កម្មវិធី​ព្យាបាទ​អាច​កាត់​លុយ​របស់​អ្នក​ ដោយ​ធ្វើការ​ហៅ​ដោយ​គ្មាន​ការ​បញ្ជាក់​របស់​អ្នក។"</string>
+    <string name="permlab_callPrivileged" msgid="4198349211108497879">"ហៅ​លេខ​ទូរស័ព្ទ​ណាមួយ​ដោយ​ផ្ទាល់"</string>
+    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"ឲ្យ​កម្មវិធី​ហៅ​លេខ​ទូរស័ព្ទ រួមមាន​លេខ​ពេល​អាសន្ន​ដោយ​គ្មាន​​អំពើ​របស់​អ្នក។ កម្មវិធី​ព្យាបាទ​អាច​ដាក់​ការ​ហៅ​មិន​ត្រឹមត្រូវ និង​ចាំបាច់​ទៅ​សេវាកម្ម​ពេល​អាសន្ន។"</string>
+    <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"ចាប់ផ្ដើម​រៀបចំ​កុំព្យូទ័រ​បន្ទះ CDMA ដោយ​ផ្ទាល់"</string>
+    <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"ចាប់ផ្ដើម​រៀបចំ​កុំព្យូទ័រ​បន្ទះ CDMA ដោយ​ផ្ទាល់"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"ឲ្យ​កម្មវិធី​ចាប់ផ្ដើម​ការ​ផ្ដល់ CDMA ។ កម្មវិធី​ព្យាបាទ​អាច​មិន​ចាំបាច់​ចាប់ផ្ដើម​ការ​ផ្ដល់ CDMA ។"</string>
+    <string name="permlab_locationUpdates" msgid="7785408253364335740">"ពិនិត្យ​​ការ​ជូន​ដំណឹង​បច្ចុប្បន្ន​ភាព​ទីតាំង"</string>
+    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"ឲ្យ​កម្មវិធី​បិទ/បើក​ការ​ជូន​ដំណឹង​បច្ចុប្បន្នភាព​ទីតាំង​ពី​វិទ្យុ។ មិន​សម្រាប់​ប្រើ​ដោយ​កម្មវិធី​ធម្មតា​ទេ។។"</string>
+    <string name="permlab_checkinProperties" msgid="7855259461268734914">"ចូល​ដំណើរការ​លក្ខណៈ​សម្បត្តិ​ពិនិត្យ​មើល"</string>
+    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"ឲ្យ​កម្មវិធី​អាន/សរសេរ​លក្ខណសម្បត្តិ​បាន​ផ្ទុក​ឡើង​ដោយ​សេវាកម្ម​ពិនិត្យ​មើល។ មិន​សម្រាប់​ប្រើ​ដោយ​កម្មវិធី​ធម្មតា។"</string>
+    <string name="permlab_bindGadget" msgid="776905339015863471">"ជ្រើស​​ធាតុ​ក្រាហ្វិក"</string>
+    <string name="permdesc_bindGadget" msgid="8261326938599049290">"ឲ្យ​កម្មវិធី​ប្រាប់​ប្រព័ន្ធ​ថា​ធាតុ​ក្រាហ្វិក​ណាមួយ​​អាច​ត្រូវ​បាន​ប្រើ​ដោយ​​កម្មវិធី​ណា​មួយ។​កម្មវិធី​ដែល​មាន​សិទ្ធិ​នេះ​អាច​ឲ្យ​កម្មវិធី​ផ្សេង​ចូល​ដំណើរការ​ទិន្នន័យ​ផ្ទាល់ខ្លួន។ មិន​សម្រាប់​ប្រើ​ដោយ​កម្មវិធី​ធម្មតា។"</string>
+    <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"កែ​ស្ថានភាព​ទូរស័ព្ទ"</string>
+    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"ឲ្យ​កម្មវិធី​ពិនិត្យ​លក្ខណៈ​ទូរស័ព្ទ​នៃ​ឧបករណ៍។ កម្មវិធី​ដែល​មាន​សិទ្ធិ​នេះ​អាច​ប្ដូរ​បណ្ដាញ បិទ និង​បើកវិទ្យុ​ក្នុង​ទូរស័ព្ទ​ដោយ​មិន​ជូន​ដំណឹង​អ្នក។"</string>
+    <string name="permlab_readPhoneState" msgid="9178228524507610486">"អាន​ស្ថានភាព និង​អត្តសញ្ញាណ​ទូរស័ព្ទ"</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"ឲ្យ​កម្មវិធី​ចូល​ដំណើរការ​លក្ខណៈ​ទូរស័ព្ទ​នៃ​ឧបករណ៍។ សិទ្ធិ​នេះ​​ឲ្យ​កម្មវិធី​កំណត់​លេខ​ទូរស័ព្ទ និង​លេខ​សម្គាល់​ឧបករណ៍ ថា​តើ​ការ​ហៅ​សកម្ម និង​លេខ​ពី​ចម្ងាយ​បាន​ភ្ជាប់​ដោយ​ការ​ហៅ។"</string>
+    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"ការពារ​​កុំព្យូទ័រ​បន្ទះ​មិន​ឲ្យ​ដេក"</string>
+    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"ការ​ពារ​ទូរស័ព្ទ​មិន​ឲ្យ​ដេក"</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"ឲ្យ​​កម្មវិធី​ការពារ​កុំព្យូទ័រ​បន្ទះ​មិន​ឲ្យ​ដេក។"</string>
+    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"ឲ្យ​កម្មវិធី​ការពារ​ទូរស័ព្ទ​មិន​ឲ្យ​ដេក។"</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
+    <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"បិទ/បើក​កុំព្យូទ័រ​បន្ទះ"</string>
+    <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"បិទ/បើក​ទូរស័ព្ទ"</string>
+    <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"ឲ្យ​កម្មវិធី​បិទ/បើក​កុំព្យូទ័រ​បន្ទះ។"</string>
+    <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"ឲ្យ​កម្មវិធី​បិទ/បើក​ទូរស័ព្ទ។"</string>
+    <string name="permlab_factoryTest" msgid="3715225492696416187">"ដំណើរការ​ក្នុង​របៀប​សាកល្បង​ពី​រោងចក្រ"</string>
+    <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"ដំណើរការ​សាកល្បង​ក្រុមហ៊ុន​ផលិត​កម្រិត​ទាប ដោយ​អនុញ្ញាត​ឲ្យ​ចូល​ផ្នែក​រឹង​កុំព្យូទ័រ​បន្ទះ។ អាច​ប្រើ​​បាន​តែ​ពេល​កុំព្យូទ័រ​កំពុង​ដំណើរការ​ក្នុង​របៀប​សាកល្បង​ក្រុមហ៊ុន​ផលិត។"</string>
+    <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"ដំណើរ​ការ​ការ​សាកល្បង​ក្រុមហ៊ុន​ផលិត​កម្រិត​ទាប ដោយ​អនុញ្ញាត​ការ​ចូល​ដំណើរការ​ផ្នែក​រឹង​ទូរស័ព្ទ។ អាច​ប្រើ​បាន​តែ​នៅ​ពេល​ទូរស័ព្ទ​កំពុង​ដំណើរការ​របៀប​សាកល្បង​ក្រុមហ៊ុន​ផលិត។"</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_masterClear" msgid="2315750423139697397">"កំណត់​ប្រព័ន្ធ​ទៅ​លំនាំដើម​រោងចក្រ​ឡើងវិញ"</string>
+    <string name="permdesc_masterClear" msgid="3665380492633910226">"ឲ្យ​កម្មវិធី​កំណត់​ប្រព័ន្ធ​​ដូច​ការ​កំណត់​ចេញ​ពី​រោងចក្រ​ឡើងវិញ​ពេញលេញ ដោយ​លុប​ទិន្នន័យ ការ​កំណត់​រចនាសម្ព័ន្ធ និង​កម្មវិធី​បាន​ដំឡើង។"</string>
+    <string name="permlab_setTime" msgid="2021614829591775646">"កំណត់​​ម៉ោង"</string>
+    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"ឲ្យ​កម្មវិធី​ប្ដូរ​ម៉ោង​កុំព្យូទ័រ​បន្ទះ។"</string>
+    <string name="permdesc_setTime" product="default" msgid="1855702730738020">"ឲ្យ​កម្មវិធី​ប្ដូរ​ម៉ោង​ទូរស័ព្ទ។"</string>
+    <string name="permlab_setTimeZone" msgid="2945079801013077340">"កំណត់​តំបន់​ពេលវេលា"</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"ឲ្យ​កម្មវិធី​ប្ដូរ​តំបន់​ពេលវេលា​របស់​កុំព្យូទ័រ​បន្ទះ​នេះ។"</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"ឲ្យ​កម្មវិធី​ប្ដូរ​តំបន់​ពេលវេលា​របស់​ទូរស័ព្ទ។"</string>
+    <string name="permlab_accountManagerService" msgid="4829262349691386986">"ដើរ​តួ​ជា AccountManagerService"</string>
+    <string name="permdesc_accountManagerService" msgid="1948455552333615954">"ឲ្យ​កម្មវិធី​ហៅ​ទៅ​​កម្មវិធី​​ផ្ទៀងផ្ទាត់​គណនី។"</string>
+    <string name="permlab_getAccounts" msgid="1086795467760122114">"រក​គណនី​លើ​ឧបករណ៍"</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"ឲ្យ​កម្មវិធី​ទទួល​បញ្ជី​គណនី​ដែល​បាន​ស្គាល់​ដោយ​កុំព្យូទ័រ​បន្ទះ។ វា​អាច​រួម​មាន​គណនី​ណាមួយ​ដែល​បាន​បង្កើត​ដោយ​កម្មវិធី​ដែល​អ្នក​បាន​ដំឡើង។"</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"ឲ្យ​កម្មវិធី​ទទួល​បញ្ជី​គណនី​ដែល​ទូរស័ព្ទ​​បាន​ស្គាល់​។ វា​អាច​មាន​គណនី​ដែល​បាន​បង្កើត​ដោយ​កម្មវិធី​ដែល​អ្នក​បាន​ដំឡើង។"</string>
+    <string name="permlab_authenticateAccounts" msgid="5265908481172736933">"បង្កើត​គណនី និង​កំណត់​ពាក្យ​សម្ងាត់"</string>
+    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"ឲ្យ​កម្មវិធី​ប្រើ​សមត្ថភាព​កម្មវិធី​ផ្ទៀងផ្ទាត់​គណនី​នៃ​កម្មវិធី​គ្រប់គ្រង​គណនី រួមមាន​បង្កើត​គណនី និង​ទទួល ព្រម​ទាំង​កំណត់​ពាក្យ​សម្ងាត់​។"</string>
+    <string name="permlab_manageAccounts" msgid="4983126304757177305">"បន្ថែម​ ឬ​លុប​​គណនី"</string>
+    <string name="permdesc_manageAccounts" msgid="8698295625488292506">"ឲ្យ​កម្មវិធី​​អនុវត្ត​ប្រតិបត្តិការ​ដូចជា បន្ថែម និង​លុប​គណនី ព្រម​ទាំង​លុប​ពាក្យ​សម្ងាត់។"</string>
+    <string name="permlab_useCredentials" msgid="235481396163877642">"ប្រើ​គណនី​​​លើ​ឧបករណ៍"</string>
+    <string name="permdesc_useCredentials" msgid="7984227147403346422">"ឲ្យ​កម្មវិធី​ស្នើ​និមិត្តសញ្ញា​ផ្ទៀងផ្ទាត់។"</string>
+    <string name="permlab_accessNetworkState" msgid="4951027964348974773">"មើល​ការ​តភ្ជាប់​បណ្ដាញ"</string>
+    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"ឲ្យ​កម្មវិធី​មើល​ព័ត៌មាន​អំពី​ការ​តភ្ជាប់​បណ្ដាញ​ដូចជា​​មាន​បណ្ដាញ​ណាមួយ​ និង​បណ្ដាញ​ត្រូវ​បាន​ភ្ជាប់។"</string>
+    <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"ចូល​ដំណើរការ​បណ្ដាញ​ពេញ​លេញ"</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"ឲ្យ​កម្មវិធី​បង្កើត​រន្ធ​បណ្ដាញ​ និង​ប្រើ​ពិធីការ​បណ្ដាញ​តាម​បំណង។ កម្មវិធី​អ៊ីនធឺណិត​ និង​កម្មវិធី​ផ្សេង​ៗ​ផ្ដល់​វិធី​ផ្ញើ​ទិន្នន័យ​ទៅ​អ៊ីនធឺណិត ដូច្នេះ​សិទ្ធិ​នេះ​មិន​ទាមទារ​ឲ្យ​ផ្ញើ​ទិន្នន័យ​ទៅ​អ៊ីនធឺណិត។"</string>
+    <string name="permlab_writeApnSettings" msgid="505660159675751896">"ប្ដូរ/បញ្ឈប់​ចរាចរណ៍ និង​ការ​កំណត់​​បណ្ដាញ"</string>
+    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"ឲ្យ​កម្មវិធី​ប្ដូរ​ការ​កំណត់​បណ្ដាញ និង​រារាំង​ និង​តាមដាន​ចរាចរណ៍​បណ្ដាញ ឧទាហរណ៍ ដើម្បី​ប្ដូរ​ប្រូកស៊ី និង​ច្រក APN ។​ កម្មវិធី​ព្យាបាទ​អាច​ពិនិត្យ បញ្ជូន​បន្ត ឬ​កែ​កញ្ចប់​ព័ត៌មាន​បណ្ដាញ​ដោយ​មិន​ឲ្យ​អ្នក​ដឹង។"</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_changeBackgroundDataSetting" msgid="1400666012671648741">"ប្ដូរ​ការ​កំណត់​ប្រើ​ទិន្នន័យ​ផ្ទៃ​ខាង​ក្រោយ"</string>
+    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"ឲ្យ​កម្មវិធី​ប្ដូរ​ការ​កំណត់​ការ​ប្រើ​ទិន្នន័យ​ផ្ទៃ​ខាង​ក្រោយ។"</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="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="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="2405042267131496579">"ប្ដូរ​ស្ថានភាព WiMAX"</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"ឲ្យ​កម្មវិធី​តភ្ជាប់​ និង​ផ្ដាច់​កុំព្យូទ័រ​បន្ទះ​ពី​បណ្ដាញ 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="default" msgid="3207106324452312739">"ឲ្យ​កម្មវិធី​មើល​​ការ​កំណត់​រចនាសម្ព័ន្ធ​ប៊្លូធូស​ក្នុង​ទូរស័ព្ទ ដើម្បី​ទទួល និង​តភ្ជាប់​ជា​មួយ​ឧបករណ៍​បាន​ផ្គូផ្គង។"</string>
+    <string name="permlab_nfc" msgid="4423351274757876953">"ពិនិត្យ​ការ​ទាក់ទង​នៅ​ក្បែរ (NFC)"</string>
+    <string name="permdesc_nfc" msgid="7120611819401789907">"ឲ្យ​កម្មវិធី​ទាក់ទង​ជា​មួយ​ស្លាក (NFC) កាត និង​កម្មវិធី​អាន។"</string>
+    <string name="permlab_disableKeyguard" msgid="3598496301486439258">"បិទ​ការ​ចាក់​សោ​អេក្រង់​របស់​អ្នក"</string>
+    <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"ឲ្យ​កម្មវិធី​បិទ​ការ​ចាក់សោ​សុវត្ថិភាព​ពាក្យ​សម្ងាត់​ដែល​បាន​ភ្ជាប់​ណា​មួយ។ ​ឧទាហរណ៍​ត្រឹមត្រូវ​​​នៃ​ការ​បិទ​ទូរស័ព្ទ​ពេល​ទទួលការ​ហៅ​ចូល បន្ទាប់​ម​បើក​សោ​ពេល​ការ​ហៅ​បាន​បញ្ចប់។"</string>
+    <string name="permlab_readSyncSettings" msgid="6201810008230503052">"អាន​ការ​កំណត់​ធ្វើ​សម​កាល​កម្ម"</string>
+    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"ឲ្យ​កម្មវិធី​អាន​ការ​កំណត់​ធ្វើ​សម​កាល​កម្ម​សម្រាប់​គណនី។ ឧទាហរណ៍ វា​អាច​កំណត់​ថា​តើ​​​កម្មវិធី​ត្រូវ​បាន​បើក​ជា​មួយ​គណនី​ដែរ​ឬទេ។"</string>
+    <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"បិទ/បើក​ការ​ធ្វើ​សម​កាល​កម្ម"</string>
+    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"ឲ្យ​កម្មវិធី​កែ​ការ​កំណត់​ធ្វើ​សម​កាល​កម្ម​សម្រាប់​គណនី។ ឧទាហរណ៍ វា​អាច​ត្រូវ​បាន​ប្រើ​ដើម្បី​បើក​ការ​ធ្វើ​សម​កាល​កម្ម​កម្មវិធី​របស់​មនុស្ស​ជា​មួយ​គណនី។"</string>
+    <string name="permlab_readSyncStats" msgid="7396577451360202448">"អាន​ស្ថិតិ​ធ្វើ​សម​កាល​កម្ម"</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"ឲ្យ​កម្មវិធី​អាន​ស្ថានភាព​ធ្វើ​សម​កាល​កម្ម​សម្រាប់​គណនី រួមមាន​ព្រឹត្តិការណ៍​ប្រវត្តិ​ធ្វើ​សម​កាល​កម្ម ​និង​ទំហំ​ទិន្នន័យ​បាន​ធ្វើ​សម​កាល​កម្ម។"</string>
+    <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"អាន​អត្ថបទ​ព័ត៌មាន​បាន​ជាវ"</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"ឲ្យ​កម្មវិធី​ទទួល​ព័ត៌មាន​លម្អិត​អំពី​អត្ថបទ​ព័ត៌មាន​​បាន​ធ្វើ​សម​កាល​កម្ម​បច្ចុប្បន្ន។"</string>
+    <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"សរសេរ​​អត្ថបទ​ព័ត៌មាន​ដែល​​បាន​ជាវ"</string>
+    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"ឲ្យ​កម្មវិធី​កែ​អត្ថបទ​ព័ត៌មាន​បាន​ធ្វើ​សម​កាល​កម្ម​បច្ចុប្បន្ន​របស់​អ្នក។ កម្មវិធី​ព្យាបាទ​អាច​ប្ដូរ​អត្ថបទ​បាន​ធ្វើ​សម​កាល​កម្ម​របស់​អ្នក។"</string>
+    <string name="permlab_readDictionary" msgid="4107101525746035718">"អាន​ពាក្យ​ដែល​អ្នក​បាន​បន្ថែម​ទៅ​វចនានុក្រម"</string>
+    <string name="permdesc_readDictionary" msgid="659614600338904243">"ឲ្យ​កម្មវិធី​អាន​ពាក្យ ឈ្មោះ និង​ឃ្លា​ទាំងអស់​ដែល​អ្នកប្រើ​អាច​​រក្សាទុក​ក្នុង​វចនានុក្រម​​អ្នកប្រើ។"</string>
+    <string name="permlab_writeDictionary" msgid="2183110402314441106">"បន្ថែម​ពាក្យ​ទៅ​វចនានុក្រម​កំណត់​ដោយ​អ្នកប្រើ"</string>
+    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"ឲ្យ​កម្មវិធី​សរសេរ​ពាក្យ​ថ្មី​ក្នុង​វចនានុក្រម​អ្នកប្រើ។"</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"សាកល្បង​ចូល​ដំណើរការ​ការ​ផ្ទុក​ដែល​បាន​ការពារ"</string>
+    <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"សាកល្បង​ចូល​ដំណើរការ​ការ​ផ្ទុក​ដែល​បាន​ការពារ"</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"ឲ្យ​កម្មវិធី​សាកល្បង​សិទ្ធិ​សម្រាប់​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី ដែល​នឹង​អាច​ប្រើ​បាន​លើ​ឧបករណ៍​​ពេល​អនាគត។"</string>
+    <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"ឲ្យ​កម្មវិធី​សាកល្បង​សិទ្ធិ​សម្រាប់​កាត​អេសឌី​ដែល​នឹង​អាច​ប្រើ​បាន​លើ​ឧបករណ៍​នា​ពេល​អនាគត។"</string>
+    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"កែ​ ឬ​លុប​មាតិកា​នៃ​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី​របស់​អ្នក"</string>
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"កែ ឬ​លុប​មាតិកា​កាត​អេសឌី"</string>
+    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"ឲ្យ​កម្មវិធី​សរសេរ​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី។"</string>
+    <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"ឲ្យ​​កម្មវិធី​សរសេរ​ទៅ​កាត​អេសឌី។"</string>
+    <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"កែ/លុប​មាតិកា​ឧបករណ៍​ផ្ទុក​មេឌៀ​ខាង​ក្នុង"</string>
+    <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"ឲ្យ​កម្មវិធី​កែ​មាតិកា​នៃ​ឧបករណ៍​ផ្ទុក​ខាង​ក្នុង។"</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"គ្រប់គ្រង​ការ​ផ្ទុក​ឯកសារ"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"ឲ្យ​កម្មវិធី​គ្រប់គ្រង​ការ​ផ្ទុក​ឯកសារ។"</string>
+    <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"ចូល​ដំណើរការ​ឧបករណ៍​ផ្ទុក​ខាង​ក្រៅ​នៃ​អ្នកប្រើ​ទាំងអស់"</string>
+    <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"ឲ្យ​កម្មវិធី​ចូល​ដំណើរការ​ឧបករណ៍​ផ្ទុក​ខាង​ក្រៅ​សម្រាប់​អ្នកប្រើ​ទាំងអស់។"</string>
+    <string name="permlab_cache_filesystem" msgid="5656487264819669824">"ចូល​ដំណើរការ​ប្រព័ន្ធ​​​ឯកសារ​ឃ្លាំង​សម្ងាត់"</string>
+    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"ឲ្យ​កម្មវិធី​អាន និង​សរសេរ​ប្រព័ន្ធ​ឯកសារ​ឃ្លាំង​សម្ងាត់។"</string>
+    <string name="permlab_use_sip" msgid="5986952362795870502">"ធ្វើ​ការ​ហៅ/ទទួល​តាម​អ៊ីនធឺណិត"</string>
+    <string name="permdesc_use_sip" msgid="4717632000062674294">"ឲ្យ​កម្មវិធី​ប្រើ​សេវាកម្ម SIP ដើម្បី​​​ហៅ/ទទួល​​​តាម​អ៊ីនធឺណិត។"</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_markNetworkSocket" msgid="3658527214914959749">"កែប្រែ​សញ្ញា​រន្ធ"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"ឲ្យ​កម្មវិធី​កែ​សញ្ញា​រន្ធ​​សម្រាប់​នាំ​ផ្លូវ"</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_invokeCarrierSetup" msgid="3699600833975117478">"ដកហូត​កម្មវិធី​កំណត់​រចនាសម្ព័ន្ធ​ដែល​បាន​ផ្ដល់​ដោយ​ក្រុមហ៊ុន​បញ្ជូន"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"អនុញ្ញាត​ឲ្យ​ម្ចាស់​ដក​ហូត​កម្មវិធី​កំណត់​រចនាសម្ព័ន្ធ​ដែល​បាន​ផ្ដល់​ដោយ​ក្រុមហ៊ុន​បញ្ជូន។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"សង្កេត​មើល​លើ​លក្ខខណ្ឌ​បណ្ដាញ"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"ឲ្យ​កម្មវិធី​សង្កេត​មើល​​លើ​លក្ខខណ្ឌ​បណ្ដាញ​។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="policylab_limitPassword" msgid="4497420728857585791">"កំណត់​ក្បួន​ពាក្យ​សម្ងាត់"</string>
+    <string name="policydesc_limitPassword" msgid="3252114203919510394">"ពិនិត្យ​ប្រវែង និង​តួអក្សរ​ដែល​បាន​អនុញ្ញាត​ក្នុង​ពាក្យ​សម្ងាត់​ចាក់​សោ​អេក្រង់។"</string>
+    <string name="policylab_watchLogin" msgid="914130646942199503">"ពិនិត្យ​ការ​ព្យាយាម​ដោះ​សោ​អេក្រង់"</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"ពិនិត្យ​ចំនួន​​បញ្ចូល​ពាក្យ​សម្ងាត់​មិន​ត្រឹមត្រូវ។ ពេល​ដោះ​សោ​អេក្រង់ និង​ចាក់​សោ​ទូរស័ព្ទ ឬ​លុប​ទិន្នន័យ​ទូរស័ព្ទ​ទាំងអស់​ ប្រសិន​បើ​មាន​ពាក្យ​សម្ងាត់​បញ្ចូល​មិន​ត្រឹមត្រូវ​ច្រើន​ដង​ពេក។"</string>
+    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"ពិនិត្យ​ចំនួន​​បញ្ចូល​ពាក្យ​សម្ងាត់​មិន​ត្រឹមត្រូវ។ ពេល​ដោះ​សោ​អេក្រង់ និង​ចាក់​សោ​ទូរស័ព្ទ ឬ​លុប​ទិន្នន័យ​ទូរស័ព្ទ​ទាំងអស់​ ប្រសិន​បើ​មាន​ពាក្យ​សម្ងាត់​បញ្ចូល​មិន​ត្រឹមត្រូវ​ច្រើន​ដង​ពេក។"</string>
+    <string name="policylab_resetPassword" msgid="2620077191242688955">"ប្ដូរ​ពាក្យ​សម្ងាត់​ដោះ​សោ​អេក្រង់"</string>
+    <string name="policydesc_resetPassword" msgid="605963962301904458">"ប្ដូរ​ពាក្យ​សម្ងាត់​​ដោះ​សោ​អេក្រង់។"</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="default" msgid="5096895604574188391">"លុប​ទិន្នន័យ​ទូរស័ព្ទ​ដោយ​មិន​ព្រមាន ដោយ​អនុវត្ត​ការ​កំណត់​ទិន្នន័យ​ដូច​ចេញ​ពី​រោងចក្រ ។"</string>
+    <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"កំណត់​ប្រូកស៊ី​សកល​របស់​ឧបករណ៍"</string>
+    <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"កំណត់​ប្រូកស៊ី​សកល​របស់​ឧបករណ៍​ត្រូវ​ប្រើ​ពេល​បាន​បើក​គោលនយោបាយ។ មាន​តែ​អ្នក​គ្រប់គ្រង​ឧបករណ៍​ដំបូង​ប៉ុណ្ណោះ​កំណត់​ប្រូកស៊ី​សកល​ត្រឹមត្រូវ។"</string>
+    <string name="policylab_expirePassword" msgid="885279151847254056">"កំណត់​សុពលភាព​ពាក្យ​សម្ងាត់​ចាក់សោ​អេក្រង់"</string>
+    <string name="policydesc_expirePassword" msgid="1729725226314691591">"ពិនិត្យ​វិធី​ដែល​ប្ដូរ​ពាក្យ​សម្ងាត់​ចាក់​សោ​អេក្រង់​ញឹកញាប់។"</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="policylab_disableKeyguardFeatures" msgid="266329104542638802">"បិទ​លក្ខណៈ​ក្នុង​ការ​ចាក់សោ"</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="3467082272186534614">"ការ​ពារ​មិន​ឲ្យ​ប្រើ​លក្ខណៈ​មួយ​ចំនួន​ក្នុង​ការ​ចាក់សោ។"</string>
+  <string-array name="phoneTypes">
+    <item msgid="8901098336658710359">"ផ្ទះ"</item>
+    <item msgid="869923650527136615">"​ចល័ត"</item>
+    <item msgid="7897544654242874543">"កន្លែង​ធ្វើការ"</item>
+    <item msgid="1103601433382158155">"ទូរសារ​កន្លែង​ធ្វើ"</item>
+    <item msgid="1735177144948329370">"ទូរសារ​ផ្ទះ"</item>
+    <item msgid="603878674477207394">"ភេយ័រ"</item>
+    <item msgid="1650824275177931637">"ផ្សេងៗ"</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>
+  </string-array>
+  <string-array name="postalAddressTypes">
+    <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="1359644565647383708">"កន្លែង​ធ្វើការ"</item>
+    <item msgid="7868549401053615677">"ផ្សេងៗ"</item>
+    <item msgid="3145118944639869809">"តាម​តម្រូវការ"</item>
+  </string-array>
+  <string-array name="organizationTypes">
+    <item msgid="7546335612189115615">"កន្លែង​ធ្វើការ"</item>
+    <item msgid="4378074129049520373">"ផ្សេងៗ"</item>
+    <item msgid="3455047468583965104">"តាម​តម្រូវ​ការ"</item>
+  </string-array>
+  <string-array name="imProtocols">
+    <item msgid="8595261363518459565">"AIM"</item>
+    <item msgid="7390473628275490700">"Windows Live"</item>
+    <item msgid="7882877134931458217">"Yahoo"</item>
+    <item msgid="5035376313200585242">"Skype"</item>
+    <item msgid="7532363178459444943">"QQ"</item>
+    <item msgid="3713441034299660749">"ជជែក​ Google"</item>
+    <item msgid="2506857312718630823">"ICQ"</item>
+    <item msgid="1648797903785279353">"Jabber"</item>
+  </string-array>
+    <string name="phoneTypeCustom" msgid="1644738059053355820">"តាម​បំណង"</string>
+    <string name="phoneTypeHome" msgid="2570923463033985887">"ផ្ទះ"</string>
+    <string name="phoneTypeMobile" msgid="6501463557754751037">"​ចល័ត"</string>
+    <string name="phoneTypeWork" msgid="8863939667059911633">"កន្លែង​ធ្វើការ"</string>
+    <string name="phoneTypeFaxWork" msgid="3517792160008890912">"ទូរសារ​កន្លែង​ធ្វើការ"</string>
+    <string name="phoneTypeFaxHome" msgid="2067265972322971467">"ទូរសារ​ផ្ទះ"</string>
+    <string name="phoneTypePager" msgid="7582359955394921732">"ភេយ័រ"</string>
+    <string name="phoneTypeOther" msgid="1544425847868765990">"ផ្សេងៗ"</string>
+    <string name="phoneTypeCallback" msgid="2712175203065678206">"ហៅ​មក​វិញ"</string>
+    <string name="phoneTypeCar" msgid="8738360689616716982">"រថយន្ត"</string>
+    <string name="phoneTypeCompanyMain" msgid="540434356461478916">"លេខ​សំខាន់​ក្រុមហ៊ុន"</string>
+    <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string>
+    <string name="phoneTypeMain" msgid="6766137010628326916">"លេខ​សំខាន់"</string>
+    <string name="phoneTypeOtherFax" msgid="8587657145072446565">"ទូរសារ​ផ្សេង"</string>
+    <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="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="eventTypeBirthday" msgid="2813379844211390740">"ថ្ងៃ​ខួប​កំណើត"</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>
+    <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="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="imTypeWork" msgid="1371489290242433090">"កន្លែង​ធ្វើការ"</string>
+    <string name="imTypeOther" msgid="5377007495735915478">"ផ្សេងៗ"</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>
+    <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
+    <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
+    <string name="imProtocolGoogleTalk" msgid="493902321140277304">"ការ​ជជែក"</string>
+    <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">"កន្លែង​ធ្វើការ"</string>
+    <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="relationTypeBrother" msgid="8757913506784067713">"បងប្អូន​ប្រុស"</string>
+    <string name="relationTypeChild" msgid="1890746277276881626">"កូន"</string>
+    <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"ដៃគូ​ក្នុងស្រុក"</string>
+    <string name="relationTypeFather" msgid="5228034687082050725">"ឪពុក"</string>
+    <string name="relationTypeFriend" msgid="7313106762483391262">"មិត្តភ័ក្ដិ"</string>
+    <string name="relationTypeManager" msgid="6365677861610137895">"អ្នក​គ្រប់គ្រង"</string>
+    <string name="relationTypeMother" msgid="4578571352962758304">"ម្ដាយ"</string>
+    <string name="relationTypeParent" msgid="4755635567562925226">"ឪពុកម្ដាយ"</string>
+    <string name="relationTypePartner" msgid="7266490285120262781">"ដៃគូ"</string>
+    <string name="relationTypeReferredBy" msgid="101573059844135524">"យោង​ដោយ"</string>
+    <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="sipAddressTypeHome" msgid="6093598181069359295">"គេហ​ទំព័រ"</string>
+    <string name="sipAddressTypeWork" msgid="6920725730797099047">"កន្លែង​ធ្វើការ"</string>
+    <string name="sipAddressTypeOther" msgid="4408436162950119849">"ផ្សេងៗ"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"បញ្ចូល​កូដ PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"បញ្ចូល​កូដ PUK និង​ PIN ថ្មី"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"កូដ PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"កូដ PIN ថ្មី"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><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">"បញ្ចូល​កូដ PIN ដើម្បី​ដោះ​សោ"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"កូដ PIN មិន​ត្រឹមត្រូវ។"</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="8963839242565653192">"គ្មាន​សេវា។"</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="5347633784401285225">"ការ​ហៅ​​ពេល​អាសន្ន"</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="faceunlock_multiple_failures" msgid="754137583022792429">"បាន​លើស​ការ​ព្យាយាម​ដោះ​សោ​តាម​ទម្រង់​មុខ"</string>
+    <string name="lockscreen_plugged_in" msgid="8057762828355572315">"បញ្ចូល​ថ្ម <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_charged" msgid="321635745684060624">"បាន​បញ្ចូល​ពេញ។"</string>
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_low_battery" msgid="1482873981919249740">"ភ្ជាប់​ឧបករណ៍​បញ្ចូល​ថ្ម។"</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="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_transport_prev_description" msgid="201594905152746886">"ប៊ូតុង​បទ​មុន"</string>
+    <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"ប៊ូតុង​បទ​បន្ទាប់"</string>
+    <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"ប៊ូតុង​​ផ្អាក"</string>
+    <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"ប៊ូតុង​ចាក់"</string>
+    <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"ប៊ូតុង​បញ្ឈប់"</string>
+    <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_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">%d</xliff:g> ដង។ \n\nព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_1">%d</xliff:g> វិនាទី។"</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"អ្នក​បាន​បញ្ចូល​ពាក្យ​សម្ងាត់​របស់​អ្នក​មិន​ត្រឹមត្រូវ <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ \n\nព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_1">%d</xliff:g> វិនាទី។"</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"អ្នក​បាន​បញ្ចូល​កូដ​ PIN មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ \n\n ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_1">%d</xliff:g> វិនាទី។"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"អ្នក​បាន​គូរ​លំនាំ​ដោះ​សោ​របស់​អ្នក​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម​មិន​ជោគជ័យ​​ច្រើន​ជាង <xliff:g id="NUMBER_1">%d</xliff:g> ដង អ្នក​នឹង​ត្រូវ​បាន​ស្នើ​ឲ្យ​ដោះ​សោ​​កុំព្យូទ័រ​បន្ទះ​​របស់​អ្នក ដោយ​ប្រើ​ការ​ចូល​ក្នុង​គណនី Google របស់​អ្នក។\n\n សូម​ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_2">%d</xliff:g> វិនាទី។"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"អ្នក​បាន​គូរ​លំនាំ​ដោះ​សោ​របស់​អ្នក​មិន​ត្រឹមត្រូវ <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម​មិន​ជោគជ័យ <xliff:g id="NUMBER_1">%d</xliff:g> ដង​ទៀត អ្នក​នឹង​ត្រូវ​បាន​ស្នើ​ឲ្យ​ដោះ​សោ​ទូរស័ព្ទ​របស់​អ្នក​ដោយ​ប្រើ​ការ​ចូល​ Google ។\n\n ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_2">%d</xliff:g> វិនាទី។"</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"អ្នក​បាន​ព្យាយាម​ដោះ​សោ​កុំព្យូទ័រ​បន្ទះ​មិន​ត្រឹមត្រូវ <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម​មិន​ជោគជ័យ​ <xliff:g id="NUMBER_1">%d</xliff:g> ដង​ទៀត កុំព្យូទ័រ​បន្ទះ​នឹង​ត្រូវ​បាន​កំណត់​ដូច​ចេញ​ពី​រោងចក្រ​ឡើងវិញ ហើយ​ទិន្នន័យ​អ្នក​ប្រើ​ទាំងអស់​នឹង​បាត់បង់។"</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"អ្នក​បាន​ព្យាយាម​​ដោះ​សោ​​ទូរស័ព្ទ​មិន​ត្រឹមត្រូវ​ <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម​មិន​ជោគជ័យ <xliff:g id="NUMBER_1">%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="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_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_checking_password" msgid="7114627351286933867">"កំពុង​ពិនិត្យ..."</string>
+    <string name="lockscreen_unlock_label" msgid="737440483220667054">"ដោះ​សោ"</string>
+    <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"បើក​សំឡេង"</string>
+    <string name="lockscreen_sound_off_label" msgid="996822825154319026">"បិទសំឡេង"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"បាន​ចាប់​ផ្ដើម​លំនាំ"</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"បាន​សម្អាត​លំនាំ"</string>
+    <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"បាន​បន្ថែម​ក្រឡា"</string>
+    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"បាន​បញ្ចប់​លំនាំ"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. ធាតុ​ក្រាហ្វិក %2$d នៃ %3$d ។"</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_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>
+    <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_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">"កូដ PIN ដោះ​សោ។"</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>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <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_line" msgid="5764267235026120888">"បន្ទាត់"</string>
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
+    <string name="factorytest_failed" msgid="5410270329114212041">"បាន​បរាជ័យ​ក្នុង​ការ​សាកល្បង​រោងចក្រ"</string>
+    <string name="factorytest_not_system" msgid="4435201656767276723">"សកម្មភាព FACTORY_TEST ត្រូវ​បាន​គាំទ្រ​សម្រាប់​តែ​កញ្ចប់​បាន​ដំឡើង​ក្នុង /system/app."</string>
+    <string name="factorytest_no_action" msgid="872991874799998561">"រក​មិន​ឃើញ​កញ្ចប់​ដែល​ផ្ដល់​សកម្មភាព FACTORY_TEST ។"</string>
+    <string name="factorytest_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="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>
+    <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
+    <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
+    <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
+    <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
+    <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_county" msgid="237073771020362891">"ប្រទេស"</string>
+    <string name="autofill_island" msgid="4020100875984667025">"កោះ"</string>
+    <string name="autofill_district" msgid="8400735073392267672">"ស្រុក"</string>
+    <string name="autofill_department" msgid="5343279462564453309">"ផ្នែក"</string>
+    <string name="autofill_prefecture" msgid="2028499485065800419">"Prefecture"</string>
+    <string name="autofill_parish" msgid="8202206105468820057">"Parish"</string>
+    <string name="autofill_area" msgid="3547409050889952423">"តំបន់"</string>
+    <string name="autofill_emirate" msgid="2893880978835698818">"Emirate"</string>
+    <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"អាន​ប្រវត្តិ និង​ចំណាំ​បណ្ដាញ"</string>
+    <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"ឲ្យ​កម្មវិធី​អាន​ប្រវត្តិ URLs ទាំង​អស់​ដែល​កម្មវិធី​អ៊ីនធឺណិត​បាន​ទស្សនា ព្រម​ទាំង​ចំណាំ​របស់​​កម្មវិធី​អ៊ីនធឺណិត។ ចំណាំ៖ សិទ្ធិ​នេះ​​មិន​អាច​ត្រូវ​បាន​អនុវត្ត​ដោយ​កម្មវិធី​អ៊ីនធឺណិត​ភាគី​ទីបី ឬ​កម្មវិធី​ដែល​មាន​សមត្ថភាព​រុករក​បណ្ដាញ។"</string>
+    <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"សរសេរ​ចំណាំ និង​ប្រវត្តិ​បណ្ដាញ"</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"ឲ្យ​កម្មវិធី​កែ​ប្រវត្តិ​កម្មវិធី​អ៊ីនធឺណិត ឬ​ចំណាំ​ដែល​មាន​ក្នុង​កុំព្យូទ័រ​បន្ទះ​របស់​អ្នក។ វា​អាច​ឲ្យ​កម្មវិធី​លុប ឬ​កែ​​ទិន្នន័យ​កម្មវិធី​អ៊ីនធឺណិត។ ចំណាំ៖ សិទ្ធិ​នេះ​​អាច​កត់​សម្គាល់​ថា​ត្រូវ​បាន​អនុវត្ត​ដោយ​កម្មវិធី​អ៊ីនធឺណិត​ភាគី​ទី​បី ឬ​កម្មវិធី​ផ្សេង​ដែល​មាន​សមត្ថភាព​​រុករក​បណ្ដាញ។"</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_packageVerificationAgent" msgid="5568139100645829117">"ផ្ទៀងផ្ទាត់​កញ្ចប់"</string>
+    <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"ឲ្យ​កម្មវិធី​ផ្ទៀងផ្ទាត់​កញ្ចប់​ដែល​អាច​ដំឡើង​បាន។"</string>
+    <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"ចង​ទៅ​កម្មវិធី​ផ្ទៀងផ្ទាត់​កញ្ចប់"</string>
+    <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"ឲ្យ​ម្ចាស់​ស្នើ​កម្មវិធី​ផ្ទៀងផ្ទាត់​កញ្ចប់។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_serialPort" msgid="546083327654631076">"ចូល​ដំណើរការ​ច្រក​ស៊េរី"</string>
+    <string name="permdesc_serialPort" msgid="2991639985224598193">"អនុញ្ញាត​ឱ្យ​ចូល​ដំណើរ​ការ​ទៅ​កាន់​ច្រក​សៀរៀល​ដោយ​ប្រើ SerialManager API ។"</string>
+    <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"ចូល​ដំណើរការ​ក្រុមហ៊ុន​ផ្ដល់​មាតិកា​ខាង​ក្រៅ"</string>
+    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"ឲ្យ​ម្ចាស់​ចូល​ដំណើរការ​ក្រុមហ៊ុន​ផ្ដល់​មាតិកា​ពី​សែល។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_updateLock" msgid="3527558366616680889">"ការ​ពារ​បច្ចុប្បន្នភាព​ឧបករណ៍​ស្វ័យ​ប្រវត្តិ"</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"ឲ្យ​ម្ចាស់​ផ្ដល់​ព័ត៌មាន​ទៅ​ប្រព័ន្ធ​អំពី​ពេលវេលា​ដែល​ល្អ​សម្រាប់​ចាប់ផ្ដើម​ឡើងវិញ​ដោយ​គ្មាន​អន្តរកម្ម ដើម្បី​ធ្វើ​បច្ចុប្បន្ន​ឧបករណ៍។"</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>
+    <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="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="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="oneMonthDurationPast" msgid="7396384508953779925">"1 ខែ​មុន"</string>
+    <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"មុន​ពេល ១ ខែ​មុន"</string>
+  <plurals name="num_seconds_ago">
+    <item quantity="one" msgid="4869870056547896011">"១ វិនាទី​មុន"</item>
+    <item quantity="other" msgid="3903706804349556379">"<xliff:g id="COUNT">%d</xliff:g> វិនាទី​មុន"</item>
+  </plurals>
+  <plurals name="num_minutes_ago">
+    <item quantity="one" msgid="3306787433088810191">"១ នាទី​មុន"</item>
+    <item quantity="other" msgid="2176942008915455116">"<xliff:g id="COUNT">%d</xliff:g> នាទី​​មុន"</item>
+  </plurals>
+  <plurals name="num_hours_ago">
+    <item quantity="one" msgid="9150797944610821849">"១ ម៉ោង​មុន"</item>
+    <item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> ម៉ោង​មុន"</item>
+  </plurals>
+  <plurals name="last_num_days">
+    <item quantity="other" msgid="3069992808164318268">"<xliff:g id="COUNT">%d</xliff:g> ថ្ងៃ​ចុងក្រោយ"</item>
+  </plurals>
+    <string name="last_month" msgid="3959346739979055432">"ខែ​មុន"</string>
+    <string name="older" msgid="5211975022815554840">"ចាស់​ជាង"</string>
+  <plurals name="num_days_ago">
+    <item quantity="one" msgid="861358534398115820">"ម្សិលមិញ"</item>
+    <item quantity="other" msgid="2479586466153314633">"<xliff:g id="COUNT">%d</xliff:g> ថ្ងៃ​មុន"</item>
+  </plurals>
+  <plurals name="in_num_seconds">
+    <item quantity="one" msgid="2729745560954905102">"ក្នុង​រយៈ​ពេល ១ វិនាទី"</item>
+    <item quantity="other" msgid="1241926116443974687">"ក្នុង​រយៈ​ពេល <xliff:g id="COUNT">%d</xliff:g> វិនាទី"</item>
+  </plurals>
+  <plurals name="in_num_minutes">
+    <item quantity="one" msgid="8793095251325200395">"ក្នុង​រយៈពេល ១ នាទី"</item>
+    <item quantity="other" msgid="3330713936399448749">"រយៈពេល <xliff:g id="COUNT">%d</xliff:g> នាទី"</item>
+  </plurals>
+  <plurals name="in_num_hours">
+    <item quantity="one" msgid="7164353342477769999">"រយៈពេល ១ ម៉ោង"</item>
+    <item quantity="other" msgid="547290677353727389">"រយៈពេល <xliff:g id="COUNT">%d</xliff:g> ម៉ោង"</item>
+  </plurals>
+  <plurals name="in_num_days">
+    <item quantity="one" msgid="5413088743009839518">"ថ្ងៃស្អែក"</item>
+    <item quantity="other" msgid="5109449375100953247">"រយៈពេល <xliff:g id="COUNT">%d</xliff:g> ថ្ងៃ"</item>
+  </plurals>
+  <plurals name="abbrev_num_seconds_ago">
+    <item quantity="one" msgid="1849036840200069118">"១ វិនាទី​មុន"</item>
+    <item quantity="other" msgid="3699169366650930415">"<xliff:g id="COUNT">%d</xliff:g> វិនាទី​មុន"</item>
+  </plurals>
+  <plurals name="abbrev_num_minutes_ago">
+    <item quantity="one" msgid="6361490147113871545">"១ នាទី​មុន"</item>
+    <item quantity="other" msgid="851164968597150710">"<xliff:g id="COUNT">%d</xliff:g> នាទី​​មុន"</item>
+  </plurals>
+  <plurals name="abbrev_num_hours_ago">
+    <item quantity="one" msgid="4796212039724722116">"១ ម៉ោង​មុន"</item>
+    <item quantity="other" msgid="6889970745748538901">"<xliff:g id="COUNT">%d</xliff:g> ម៉ោង​មុន"</item>
+  </plurals>
+  <plurals name="abbrev_num_days_ago">
+    <item quantity="one" msgid="8463161711492680309">"ម្សិលមិញ"</item>
+    <item quantity="other" msgid="3453342639616481191">"<xliff:g id="COUNT">%d</xliff:g> ថ្ងៃ​​មុន"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_seconds">
+    <item quantity="one" msgid="5842225370795066299">"ក្នុង​ពេល​ 1 វិនាទី"</item>
+    <item quantity="other" msgid="5495880108825805108">"ក្នុង​ពេល <xliff:g id="COUNT">%d</xliff:g> វិនាទី"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_minutes">
+    <item quantity="one" msgid="562786149928284878">"ក្នុង​ពេល 1 នាទី"</item>
+    <item quantity="other" msgid="4216113292706568726">"នៅ​រយៈពេល <xliff:g id="COUNT">%d</xliff:g> នាទី"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_hours">
+    <item quantity="one" msgid="3274708118124045246">"ក្នុង​រយៈ​ពេល ១ ម៉ោង"</item>
+    <item quantity="other" msgid="3705373766798013406">"ក្នុង​រយៈ​ពេល <xliff:g id="COUNT">%d</xliff:g> ម៉ោង"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_days">
+    <item quantity="one" msgid="2178576254385739855">"ថ្ងៃស្អែក"</item>
+    <item quantity="other" msgid="2973062968038355991">"ក្នុង​រយៈ​ពេល <xliff:g id="COUNT">%d</xliff:g> ថ្ងៃ"</item>
+  </plurals>
+    <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>
+    <string name="days" msgid="4774547661021344602">"​ថ្ងៃ"</string>
+    <string name="hour" msgid="2126771916426189481">"ម៉ោង"</string>
+    <string name="hours" msgid="894424005266852993">"ម៉ោង"</string>
+    <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="week" msgid="5617961537173061583">"សប្ដាហ៍"</string>
+    <string name="weeks" msgid="6509623834583944518">"សប្ដាហ៍"</string>
+    <string name="year" msgid="4001118221013892076">"ឆ្នាំ"</string>
+    <string name="years" msgid="6881577717993213522">"ឆ្នាំ"</string>
+  <plurals name="duration_seconds">
+    <item quantity="one" msgid="6962015528372969481">"1 វិនាទី"</item>
+    <item quantity="other" msgid="1886107766577166786">"<xliff:g id="COUNT">%d</xliff:g> វិនាទី"</item>
+  </plurals>
+  <plurals name="duration_minutes">
+    <item quantity="one" msgid="4915414002546085617">"១ នាទី"</item>
+    <item quantity="other" msgid="3165187169224908775">"<xliff:g id="COUNT">%d</xliff:g> នាទី"</item>
+  </plurals>
+  <plurals name="duration_hours">
+    <item quantity="one" msgid="8917467491248809972">"១ ម៉ោង"</item>
+    <item quantity="other" msgid="3863962854246773930">"<xliff:g id="COUNT">%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_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>
+    <string name="midnight" msgid="7166259508850457595">"កណ្ដាលអធ្រាត្រ"</string>
+    <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="cut" msgid="3092569408438626261">"កាត់"</string>
+    <string name="copy" msgid="2681946229533511987">"ចម្លង"</string>
+    <string name="paste" msgid="5629880836805036433">"បិទ​ភ្ជាប់"</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="textSelectionCABTitle" msgid="5236850394370820357">"ការ​ជ្រើស​អត្ថបទ"</string>
+    <string name="addToDictionary" msgid="4352161534510057874">"បន្ថែម​ទៅ​វចនានុក្រម"</string>
+    <string name="deleteText" msgid="6979668428458199034">"លុប"</string>
+    <string name="inputMethod" msgid="1653630062304567879">"វិធីសាស្ត្រ​បញ្ចូល"</string>
+    <string name="editTextMenuTitle" msgid="4909135564941815494">"សកម្មភាព​អត្ថបទ"</string>
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"អស់​ទំហំ​ផ្ទុក"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"មុខងារ​ប្រព័ន្ធ​មួយ​ចំនួន​អាច​មិន​ដំណើរការ"</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="4653586947747330058">"ប៉ះ​ ដើម្បី​មើល​ព័ត៌មាន​បន្ថែម ឬ​បញ្ឈប់​កម្មវិធី។"</string>
+    <string name="ok" msgid="5970060430562524910">"យល់​ព្រម"</string>
+    <string name="cancel" msgid="6442560571259935130">"បោះ​បង់"</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>
+    <string name="capital_on" msgid="1544682755514494298">"បើក"</string>
+    <string name="capital_off" msgid="6815870386972805832">"បិទ"</string>
+    <string name="whichApplication" msgid="4533185947064773386">"បញ្ចប់​សកម្មភាព​ដោយ​ប្រើ"</string>
+    <string name="alwaysUse" msgid="4583018368000610438">"ប្រើ​តាម​លំនាំដើម​សម្រាប់​សកម្មភាព​នេះ។"</string>
+    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"សម្អាត​លំនាំដើម​ក្នុង​ការកំណត់​ប្រព័ន្ធ &gt; កម្មវិធី &gt; ទាញ​យក។"</string>
+    <string name="chooseActivity" msgid="7486876147751803333">"ជ្រើស​សកម្មភាព"</string>
+    <string name="chooseUsbActivity" msgid="6894748416073583509">"ជ្រើស​កម្មវិធី​សម្រាប់​ឧបករណ៍​យូអេសប៊ី"</string>
+    <string name="noApplications" msgid="2991814273936504689">"គ្មាន​កម្មវិធី​អាច​អនុវត្ត​សកម្មភាព​នេះ។"</string>
+    <string name="aerr_title" msgid="1905800560317137752"></string>
+    <string name="aerr_application" msgid="932628488013092776">"ដោយ​បរាជ័យ <xliff:g id="APPLICATION">%1$s</xliff:g> បាន​បញ្ឈប់។"</string>
+    <string name="aerr_process" msgid="4507058997035697579">"ជា​អកុសល ដំណើរការ <xliff:g id="PROCESS">%1$s</xliff:g> បាន​បញ្ឈប់។"</string>
+    <string name="anr_title" msgid="4351948481459135709"></string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> មិន​ឆ្លើយតប។\n\nតើ​អ្នក​ចង់​បិទ​វា​ឬ?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"សកម្មភាព <xliff:g id="ACTIVITY">%1$s</xliff:g> មិន​ឆ្លើយតប។\n\nតើ​អ្នក​ចង់​បិទ​វា?"</string>
+    <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> មិន​ឆ្លើយតប។ តើ​អ្នក​ចង់​បិទ​វា?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"ដំណើរការ <xliff:g id="PROCESS">%1$s</xliff:g> មិន​ឆ្លើយតប។ \n\nតើ​អ្នក​ចង់​បិទ​វា​ឬ?"</string>
+    <string name="force_close" msgid="8346072094521265605">"យល់​ព្រម"</string>
+    <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_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; កម្មវិធី &gt; ទាញ​យក។"</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_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_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="1721681741617898865">"ប៉ះ​ ដើម្បី​ប្ដូរ​​​កម្មវិធី"</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>
+    <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="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_silent_ringtone_selected" msgid="8310739960973156272">"កំណត់​សំឡេង​រោទ៍​ស្ងាត់"</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">"កម្រិត​សំឡេង​ប៊្លូធូស"</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="8129563480895990372">"សំឡេង​រោទ៍​លំនាំដើម (<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_unknown" msgid="5477919988701784788">"សំឡេង​រោទ៍​មិន​ស្គាល់"</string>
+  <plurals name="wifi_available">
+    <item quantity="one" msgid="6654123987418168693">"មាន​បណ្ដាញ​វ៉ាយហ្វាយ"</item>
+    <item quantity="other" msgid="4192424489168397386">"មាន​បណ្ដាញ​វ៉ាយហ្វាយ"</item>
+  </plurals>
+  <plurals name="wifi_available_detailed">
+    <item quantity="one" msgid="1634101450343277345">"បើក​បណ្ដាញ​វ៉ាយហ្វាយ​​ដែល​មាន"</item>
+    <item quantity="other" msgid="7915895323644292768">"មាន​បណ្ដាញ​វ៉ាយហ្វាយ​បើក"</item>
+  </plurals>
+    <string name="wifi_available_sign_in" msgid="4029489716605255386">"ចូល​បណ្ដាញ​វ៉ាយហ្វាយ"</string>
+    <string name="network_available_sign_in" msgid="8495155593358054676">"ចូល​ក្នុង​បណ្ដាញ"</string>
+    <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
+    <skip />
+    <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"មិន​​អាច​តភ្ជាប់​វ៉ាយហ្វាយ"</string>
+    <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" មាន​ការ​តភ្ជាប់​អ៊ីនធឺណិត​មិន​ល្អ។"</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="1638949953993894335">"ប៉ះ​ ដើម្បី​កំណត់"</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_to_connect_title" msgid="4958803948658533637">"អញ្ជើញ​ឲ្យ​ភ្ជាប់"</string>
+    <string name="wifi_p2p_from_message" msgid="570389174731951769">"ពី៖"</string>
+    <string name="wifi_p2p_to_message" msgid="248968974522044099">"ទៅ៖"</string>
+    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"បញ្ចូល​កូដ PIN ដែល​ទាមទារ៖"</string>
+    <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"កូដ PIN ៖"</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="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="3492025719868078457"><font fgcolor="#ffffb060">"នេះ​អាច​កាត់​លុយ"</font>" លើ​គណនី​ចល័ត​របស់​អ្នក។"</string>
+    <string name="sms_premium_short_code_details" msgid="5523826349105123687"><font fgcolor="#ffffb060">"វា​នឹង​គិត​ថ្លៃ​សេវាកម្ម​លើ​គណនី​ចល័ត​របស់​អ្នក។"</font></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_confirm_always_allow" msgid="3241181154869493368">"អនុញ្ញាត​ជា​និច្ច"</string>
+    <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"កុំ​អនុញ្ញាត"</string>
+    <string name="sim_removed_title" msgid="6227712319223226185">"បាន​ដក​ស៊ីម​កាត​ចេញ"</string>
+    <string name="sim_removed_message" msgid="2333164559970958645">"បណ្ដាញ​ចល័ត​នឹង​ប្រើ​លែង​បាន​រហូត​ដល់​អ្នក​ចាប់ផ្ដើម​ជា​មួយ​ស៊ីម​កាត​ដែល​បា​បញ្ចូល​ត្រឹមត្រូវ។"</string>
+    <string name="sim_done_button" msgid="827949989369963775">"រួចរាល់"</string>
+    <string name="sim_added_title" msgid="3719670512889674693">"បាន​បន្ថែម​ស៊ីម​កាត"</string>
+    <string name="sim_added_message" msgid="6599945301141050216">"ចាប់ផ្ដើម​ឧបករណ៍​របស់​អ្នក​ឡើង​វិញ ដើម្បី​ចូល​ដំណើរការ​បណ្ដាញ​ចល័ត។"</string>
+    <string name="sim_restart_button" msgid="4722407842815232347">"ចាប់ផ្ដើម​ឡើងវិញ"</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_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="usb_storage_activity_title" msgid="4465055157209648641">"ឧបករណ៍​យូអេសប៊ី"</string>
+    <string name="usb_storage_title" msgid="5901459041398751495">"បាន​ភ្ជាប់​យូអេសប៊ី"</string>
+    <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"អ្នក​បាន​ភ្ជាប់​កុំព្យូទ័រ​របស់​អ្នក​តាម​​យូអេសប៊ី។ ប៉ះ ប៊ូតុង​ខាង​ក្រោម បើ​អ្នក​ចង់​ចម្លង​ឯកសារ​រវាង​កុំព្យូទ័រ និង​ឧបករណ៍​ផ្ទុក Android របស់​អ្នក។"</string>
+    <string name="usb_storage_message" product="default" msgid="805351000446037811">"អ្នក​បាន​ភ្ជាប់​កុំព្យូទ័រ​របស់​អ្នក​តាម​យូអេសប៊ី។ ប៉ះ ប៊ូតុង​ខាង​ក្រោម​ប្រសិន​បើ​អ្នក​ចង់​ចម្លង​ឯកសារ​រវាង​កុំព្យូទ័រ​របស់​អ្នក និង​កាត​អេសឌី​នៃ Android របស់​អ្នក។"</string>
+    <string name="usb_storage_button_mount" msgid="1052259930369508235">"បើក​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី"</string>
+    <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"មាន​បញ្ហា​ក្នុង​ការ​ផ្អាក​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី​សម្រាប់​ជា​ឧបករណ៍​ផ្ទុក។"</string>
+    <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"មាន​បញ្ហា​ក្នុង​ការ​ប្រើ​កាត​អេសឌី​សម្រាប់​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី។"</string>
+    <string name="usb_storage_notification_title" msgid="8175892554757216525">"បាន​ភ្ជាប់​យូអេសប៊ី"</string>
+    <string name="usb_storage_notification_message" msgid="939822783828183763">"ប៉ះ ដើម្បី​ចម្លង​ឯកសារ​ទៅ/ពី​កុំព្យូទ័រ​របស់​​អ្នក។"</string>
+    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"បិទ​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី"</string>
+    <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"ប៉ះ ដើម្បី​បិទ​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី។"</string>
+    <string name="usb_storage_stop_title" msgid="660129851708775853">"ឧបករណ៍​ផ្ទុក​យូអេសប៊ី​កំពុង​ប្រើ"</string>
+    <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"មុន​ពេល​បិទ​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី ផ្ដាច់ (\"បដិសេធ\") ឧបករណ៍​ផ្ទុក​យូអេសប៊ី Android របស់​អ្នក​ពី​កុំព្យូទ័រ។"</string>
+    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"មុន​ពេល​បិទ​​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី ផ្ដាច់ (\"បដិសេធ\") កាត​អេសឌី Android របស់​អ្នក​ពី​កុំព្យូទ័រ។"</string>
+    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"បិទ​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី"</string>
+    <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"មាន​បញ្ហា​ក្នុង​ការ​បិទ​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី។ ពិនិត្យ​ថា​អ្នក​បាន​ផ្ដាច់​យូអេសប៊ី បន្ទាប់​មក​ព្យាយាម​ម្ដង​ទៀត។"</string>
+    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"បើក​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី"</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"បើ​អ្នក​បើក​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី កម្មវិធី​មួយ​ចំនួន​ដែល​អ្នក​កំពុង​ប្រើ​នឹង​បញ្ឈប់ ហើយ​អាច​ប្រើ​លែង​បាន​រហូត​ដល់​អ្នក​បិទ​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី។"</string>
+    <string name="dlg_error_title" msgid="7323658469626514207">"ប្រតិបត្តិការ​យូអេសប៊ី​​បរាជ័យ"</string>
+    <string name="dlg_ok" msgid="7376953167039865701">"យល់ព្រម"</string>
+    <string name="usb_mtp_notification_title" msgid="3699913097391550394">"បាន​តភ្ជាប់​ជា​ឧបករណ៍​​ផ្ទុក"</string>
+    <string name="usb_ptp_notification_title" msgid="1960817192216064833">"បាន​ភ្ជាប់​ជា​ម៉ាស៊ីន​ថត"</string>
+    <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"បាន​ភ្ជាប់​ជា​កម្មវិធី​ដំឡើង"</string>
+    <string name="usb_accessory_notification_title" msgid="7848236974087653666">"បាន​ភ្ជាប់​ឧបករណ៍​យូអេសប៊ី"</string>
+    <string name="usb_notification_message" msgid="2290859399983720271">"ប៉ះ ដើម្បី​មើល​ជម្រើស​យូអេសប៊ី​ផ្សេង។"</string>
+    <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"ធ្វើ​ទ្រង់ទ្រាយ​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី?"</string>
+    <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"ធ្វើ​ទ្រង់ទ្រាយ​កាត​អេសឌី?"</string>
+    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"ឯកសារ​ទាំងអស់​ដែល​បាន​រក្សាទុក​ក្នុង​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី​នឹង​ត្រូវ​បាន​លុប។ សកម្មភាព​នេះ​មិន​អាច​ត្រឡប់​វិញ​បាន​ទេ!"</string>
+    <string name="extmedia_format_message" product="default" msgid="14131895027543830">"ទិន្នន័យ​ទាំងអស់​ក្នុង​កាត​របស់​អ្នក​នឹង​បាត់បង់។"</string>
+    <string name="extmedia_format_button_format" msgid="4131064560127478695">"ធ្វើ​ទ្រង់ទ្រាយ"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"បាន​ភ្ជាប់​ការ​កែ​កំហុស​យូអេសប៊ី"</string>
+    <string name="adb_active_notification_message" msgid="1016654627626476142">"ប៉ះ ដើម្បី​បិទ​ការ​កែ​កំហុស​យូអេសប៊ី។"</string>
+    <string name="select_input_method" msgid="4653387336791222978">"ជ្រើស​វិធីសាស្ត្រ​បញ្ចូល"</string>
+    <string name="configure_input_methods" msgid="9091652157722495116">"រៀបចំ​វិធីសាស្ត្រ​បញ្ចូល"</string>
+    <string name="use_physical_keyboard" msgid="6203112478095117625">"ក្ដារ​ចុច​​ពិតប្រាកដ"</string>
+    <string name="hardware" msgid="7517821086888990278">"ផ្នែក​រឹង"</string>
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"ជ្រើស​ប្លង់​ក្ដារ​ចុច"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"ប៉ះ ​ដើម្បី​ជ្រើស​ប្លង់​​ក្ដារចុច។"</string>
+    <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="candidates_style" msgid="4333913089637062257"><u>"បេក្ខជន"</u></string>
+    <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"រៀបចំ​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី"</string>
+    <string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"រៀបចំ​កាត​អេសឌី"</string>
+    <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"ពិនិត្យ​រក​កំហុស។"</string>
+    <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"ឧបករណ៍​ផ្ទុក​យូអេសប៊ី​ទទេ"</string>
+    <string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"ការ​​អេសឌី​ទទេ"</string>
+    <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"ឧបករណ៍​ផ្ទុក​យូអេសប៊ី​ទទេ ឬ​មាន​ប្រព័ន្ធ​ឯកសារ​ដែល​មិន​បា​គាំទ្រ។"</string>
+    <string name="ext_media_nofs_notification_message" product="default" msgid="8641065641786923604">"កាត​អេសឌី​ទទេ ឬ​មាន​ប្រព័ន្ធ​ឯកសារ​មិន​បាន​គាំទ្រ។"</string>
+    <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"ឧបករណ៍​ផ្ទុក​យូអេសប៊ី​ខូច"</string>
+    <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"កាត​អេសឌី​ខូច"</string>
+    <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="1795917578395333280">"ឧបករណ៍​ផ្ទុក​យូអេសប៊ី​ខូច។ ព្យាយាម​ធ្វើ​ទ្រង់ទ្រាយ​វា​ឡើងវិញ។"</string>
+    <string name="ext_media_unmountable_notification_message" product="default" msgid="1753898567525568253">"កាត​អេសឌី​ខូច។ ព្យាយាម​ធ្វើ​ទ្រង់ទ្រាយ​វា​ឡើងវិញ។"</string>
+    <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"បាន​ដក​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី​ដោយ​មិន​រំពឹង​ទុក"</string>
+    <string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"បាន​ដក​កាត​អេសឌី​ដោយ​មិន​រំពឹង​ទុក"</string>
+    <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"ផ្ដាច់​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី​មុន​នឹង​​លុប​​​ជៀសវាង​ការ​បាត់​ទិន្នន័យ។"</string>
+    <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"ផ្ដាច់​កាត​អេសឌី​មុន​នឹង​ដក់​ចេញ ជៀសវាង​បាត់បង់​ទិន្នន័យ។"</string>
+    <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"ឧបករណ៍​យូអេសប៊ី​មាន​សុវត្ថិភាព ដើម្បី​ដក"</string>
+    <string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"មាន​សុវត្ថិភាព​ក្នុង​ការ​ដក​កាត​អេសឌី"</string>
+    <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"អ្នក​អាច​ដក​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី​ដោយ​សុវត្ថិភាព។"</string>
+    <string name="ext_media_safe_unmount_notification_message" product="default" msgid="568841278138377604">"អ្នក​អាច​ដក​កាត​អេសឌី​ដោយ​មាន​សុវត្ថិភាព។"</string>
+    <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"បាន​លុប​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី"</string>
+    <string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"បាន​ដក​កាត​អេសឌី"</string>
+    <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"បាន​ដក​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី។ បញ្ចូល​មេឌៀ​ថ្មី។"</string>
+    <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"បាន​ដក​កាត​អេសឌី។ បញ្ចូល​ថ្មី​មួយ។"</string>
+    <string name="activity_list_empty" msgid="1675388330786841066">"រក​មិន​ឃើញ​សកម្មភាព​ផ្គូផ្គង។"</string>
+    <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"ធ្វើ​បច្ចុប្បន្ន​សមាសធាតុ​ស្ថិតិ​ការ​ប្រើ"</string>
+    <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"ឲ្យ​កម្មវិធី​កែ​ស្ថិតិ​ប្រើ​សមាសភាគ​ដែល​បា​ន​ប្រមូល។​​ មិន​សម្រាប់​ប្រើ​ដោយ​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_copyProtectedData" msgid="4341036311211406692">"ចម្លង​មាតិកា"</string>
+    <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"ឲ្យ​កម្មវិធី​ដក​សេវាកម្ម​នៃ​កម្មវិធី​ផ្ទុក​​លំនាំដើម ដើម្បី​ចម្លង​មាតិកា។​ មិន​សម្រាប់​ប្រើ​ដោយ​កម្មវិធី​លំនាំដើម។"</string>
+    <string name="permlab_route_media_output" msgid="1642024455750414694">"នាំ​ផ្លូវ​លទ្ធផល​មេឌៀ"</string>
+    <string name="permdesc_route_media_output" msgid="4932818749547244346">"ឲ្យ​កម្មវិធី​នាំ​ផ្លូវ​លទ្ធផល​មេឌៀ​ទៅ​ឧបករណ៍​​ខាង​ក្រៅ​ផ្សេង។"</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"ចូល​ដំណើរការ​ឧបករណ៍​ផ្ទុក​សុវត្ថិភាព"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"ឲ្យ​កម្មវិធី​ចូល​​ការ​ផ្ទុក​មាន​សុវត្ថិភាព keguard ។"</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"ពិនិត្យ​ការ​បង្ហាញ និង​លាក់​ការ​ការពារ"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"ឲ្យ​កម្មវិធី​គ្រប់គ្រង keguard ។"</string>
+    <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"ប៉ះ​ពីរ​ដង ​​ដើម្បី​គ្រប់គ្រង​ការ​ពង្រីក"</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>
+    <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">"ចុច​លេខ​\nដោយ​ប្រើ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"បង្កើត​ទំនាក់ទំនង\nដោយ​ប្រើ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"កម្មវិធី​មួយ ឬ​ច្រើន​ដូច​ខាង​ក្រោម​ស្នើ​សិទ្ធិ ដើម្បី​ចូល​គណនី​របស់​អ្នក​ឥឡូវ និង​ពេល​អនាគត។"</string>
+    <string name="grant_credentials_permission_message_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">"បាន​ស្នើ​សិទ្ធិ\nសម្រាប់​គណនី <xliff:g id="ACCOUNT">%s</xliff:g> ។"</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>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"ប្ដូរ​ផ្ទាំង​រូបភាព"</string>
+    <string name="notification_listener_binding_label" msgid="2014162835481906429">"កម្មវិធី​ស្ដាប់​ការ​ជូន​ដំណឹង"</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="3011306607126450322">"ប៉ះ ដើម្បី​គ្រប់គ្រង​បណ្ដាញ។"</string>
+    <string name="vpn_text_long" msgid="6407351006249174473">"បាន​តភ្ជាប់​ទៅ <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_error" msgid="6009249814034708175">"បើក​កំហុស VPN ជា​និច្ច"</string>
+    <string name="vpn_lockdown_config" msgid="6415899150671537970">"ប៉ះ ​ដើម្បី​កំណត់​រចនា​សម្ព័ន្ធ"</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="8035230537563503262">"ប៉ះ​ ដើម្បី​ចេញ​ពី​របៀប​រថយន្ត​។"</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"​ភ្ជាប់ ឬ​ hotspot សកម្ម"</string>
+    <string name="tethered_notification_message" msgid="6857031760103062982">"ប៉ះ​ ដើម្បី​រៀបចំ។"</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="throttle_warning_notification_title" msgid="4890894267454867276">"ការ​ប្រើ​ទិន្នន័យ​ចល័ត​ខ្ពស់"</string>
+    <string name="throttle_warning_notification_message" msgid="3340822228599337743">"ប៉ះ​ ដើម្បី​​ស្វែងយល់​បន្ថែម​អំពី​ការ​ប្រើ​​​ទិន្នន័យ​ចល័ត​។"</string>
+    <string name="throttled_notification_title" msgid="6269541897729781332">"លើក​ដែន​កំណត់​ទិន្នន័យ​ចល័ត"</string>
+    <string name="throttled_notification_message" msgid="5443457321354907181">"ប៉ះ ដើម្បី​ស្វែងយល់​បន្ថែម​អំពី​ការ​ប្រើ​ទិន្នន័យ​ចល័ត។"</string>
+    <string name="no_matches" msgid="8129421908915840737">"គ្មាន​ការ​ផ្គូផ្គង"</string>
+    <string name="find_on_page" msgid="1946799233822820384">"រក​ក្នុង​ទំព័រ"</string>
+  <plurals name="matches_found">
+    <item quantity="one" msgid="8167147081136579439">"១ ប្រកួត"</item>
+    <item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> នៃ <xliff:g id="TOTAL">%d</xliff:g>"</item>
+  </plurals>
+    <string name="action_mode_done" msgid="7217581640461922289">"រួចរាល់"</string>
+    <string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"កំពុង​ផ្ដាច់​ឧបករណ៍​យូអេសប៊ី..."</string>
+    <string name="progress_unmounting" product="default" msgid="1327894998409537190">"កំពុង​ផ្ដាច់​កាត​អេសឌី..."</string>
+    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"កំពុង​លុប​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី..."</string>
+    <string name="progress_erasing" product="default" msgid="6596988875507043042">"កំពុង​លុប​កាត​អេសឌី..."</string>
+    <string name="format_error" product="nosdcard" msgid="6299769563624776948">"មិន​​អាច​លុប​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី។"</string>
+    <string name="format_error" product="default" msgid="7315248696644510935">"មិន​អាច​លុប​កាត​អេសឌី។"</string>
+    <string name="media_bad_removal" msgid="7960864061016603281">"បាន​ដក​កាត​អេសឌី​មុន​នឹង​ផ្ដាច់។"</string>
+    <string name="media_checking" product="nosdcard" msgid="418188720009569693">"បច្ចុប្បន្ន​កំពុង​ពិនិត្យ​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី។"</string>
+    <string name="media_checking" product="default" msgid="7334762503904827481">"បច្ចុប្បន្ន​កំពុង​ពិនិត្យ​មើល​កាត​អេសឌី។"</string>
+    <string name="media_removed" msgid="7001526905057952097">"បាន​ដក​កាត​អេសឌី។"</string>
+    <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"ឧបករណ៍​ផ្ទុក​យូអេសប៊ី​បច្ចុប្បន្ន​កំពុង​ប្រើ​ដោយ​កុំព្យូទ័រ។"</string>
+    <string name="media_shared" product="default" msgid="5706130568133540435">"បច្ចុប្បន្ន​កាត​អេសឌី​កំពុង​ប្រើ​ដោយ​កុំព្យូទ័រ"</string>
+    <string name="media_unknown_state" msgid="729192782197290385">"មិន​ស្គាល់​ស្ថានភាព​មេឌៀ​ខាង​ក្រៅ។"</string>
+    <string name="share" msgid="1778686618230011964">"ចែក​រំលែក"</string>
+    <string name="find" msgid="4808270900322985960">"រក"</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="gpsNotifMessage" msgid="1374718023224000702">"បាន​ស្នើ​ដោយ <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+    <string name="gpsVerifYes" msgid="2346566072867213563">"បាទ/ចាស"</string>
+    <string name="gpsVerifNo" msgid="1146564937346454865">"ទេ"</string>
+    <string name="sync_too_many_deletes" msgid="5296321850662746890">"លុប​​លើស​ដែន​កំណត់"</string>
+    <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"មាន​ធាតុ​បាន​លុប <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> សម្រាប់ <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> គណនី <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> ។ តើ​អ្នក​ចង់​ធ្វើ​អ្វី​ខ្លះ​?"</string>
+    <string name="sync_really_delete" msgid="2572600103122596243">"លុប​ធាតុ"</string>
+    <string name="sync_undo_deletes" msgid="2941317360600338602">"មិន​ធ្វើ​ការ​លុប​វិញ"</string>
+    <string name="sync_do_nothing" msgid="3743764740430821845">"មិន​ធ្វើអ្វី​ទេ​ឥឡូវ"</string>
+    <string name="choose_account_label" msgid="5655203089746423927">"ជ្រើស​គណនី"</string>
+    <string name="add_account_label" msgid="2935267344849993553">"បន្ថែម​គណនី​ថ្មី"</string>
+    <string name="add_account_button_label" msgid="3611982894853435874">"បន្ថែម​គណនី"</string>
+    <string name="number_picker_increment_button" msgid="2412072272832284313">"បង្កើន"</string>
+    <string name="number_picker_decrement_button" msgid="476050778386779067">"បន្ថយ"</string>
+    <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> ប៉ះ និង​សង្កត់។"</string>
+    <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"រុញ​ឡើងលើ ដើម្បី​បង្កើន និង​ចុះក្រោម​ដើម្បី​បន្ថយ។"</string>
+    <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"បង្កើន​នាទី"</string>
+    <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"បន្ថយ​នាទី"</string>
+    <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"បង្កើន​ម៉ោង"</string>
+    <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"បន្ថយ​ម៉ោង"</string>
+    <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"កំណត់​ PM"</string>
+    <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"កំណត់ AM"</string>
+    <string name="date_picker_increment_month_button" msgid="5369998479067934110">"បង្កើន​ខែ"</string>
+    <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"បន្ថយ​ខែ"</string>
+    <string name="date_picker_increment_day_button" msgid="7130465412308173903">"បង្កើន​ថ្ងៃ"</string>
+    <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"បន្ថយ​ថ្ងៃ"</string>
+    <string name="date_picker_increment_year_button" msgid="6318697384310808899">"បង្កើន​​ឆ្នាំ"</string>
+    <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"បន្ថយ​ឆ្នាំ"</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_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"ជ្រើស​កម្មវិធី"</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_direction_up" msgid="7169032478259485180">"រុញ​ឡើង​លើ​ដើម្បី <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"រុញ​ចុះក្រោម​សម្រាប់ <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="description_direction_right" msgid="8034433242579600980">"រុញ​​ទៅ​ស្ដាំ​ដើម្បី <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"ដោះ​​សោ"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"ម៉ាស៊ីន​ថត"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"ស្ងាត់"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"បើក​សំឡេង"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"ស្វែងរក"</string>
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"អូស​ ដើម្បី​ដោះ​សោ។"</string>
+    <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"ដោត​កាស​ដើម្បី​ស្ដាប់​ពាក្យ​សម្ងាត់​បាន​និយាយ។"</string>
+    <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Dot."</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="4891916833657929263">"ឧបករណ៍​ផ្ទុក​ខាង​ក្នុង"</string>
+    <string name="storage_sd_card" msgid="3282948861378286745">"កាត​អេសឌី"</string>
+    <string name="storage_usb" msgid="3017954059538517278">"ឧបករណ៍​ផ្ទុក​យូអេសប៊ី"</string>
+    <string name="extract_edit_menu_button" msgid="8940478730496610137">"កែសម្រួល"</string>
+    <string name="data_usage_warning_title" msgid="1955638862122232342">"ការព្រមាន​ប្រើ​ទិន្នន័យ"</string>
+    <string name="data_usage_warning_body" msgid="2814673551471969954">"ប៉ះ ដើម្បី​មើល​ការ​ប្រើ និង​ការ​កំណត់។"</string>
+    <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"បាន​បិទ​ទិន្នន័យ 2G​-3G"</string>
+    <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"បាន​បិទ​ទិន្នន័យ 4G"</string>
+    <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"បាន​បិទ​ទិន្នន័យ​ចល័ត"</string>
+    <string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"បាន​បិទ​ទិន្នន័យ​វ៉ាយហ្វាយ"</string>
+    <string name="data_usage_limit_body" msgid="3317964706973601386">"ប៉ះ​​ ដើម្បី​បើក​។"</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="6741521330997452990">"ប៉ះ ដើម្បី​លុប​ការ​ដាក់កម្រិត។"</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>
+    <string name="org_unit" msgid="7265981890422070383">"ផ្នែក​នៃ​ស្ថាប័ន៖"</string>
+    <string name="issued_by" msgid="2647584988057481566">"បាន​ចេញ​ដោយ​៖"</string>
+    <string name="validity_period" msgid="8818886137545983110">"សុពលភាព៖"</string>
+    <string name="issued_on" msgid="5895017404361397232">"ចេញ​នៅ៖"</string>
+    <string name="expires_on" msgid="3676242949915959821">"ផុត​កំណត់​នៅ៖"</string>
+    <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>
+    <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"មើល​ទាំងអស់"</string>
+    <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"ជ្រើស​សកម្មភាព"</string>
+    <string name="share_action_provider_share_with" msgid="5247684435979149216">"ចែករំលែក​ជា​មួយ"</string>
+    <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="3245653681008218030">"កំពុង​ផ្ញើ..."</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="default_audio_route_name" product="tablet" msgid="4617053898167127471">"កុំព្យូទ័រ​បន្ទះ"</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">"សំឡេង​ប៊្លូធូស"</string>
+    <string name="wireless_display_route_description" msgid="9070346425023979651">"បង្ហាញ​បណ្ដាញ​ឥត​ខ្សែ"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"រួចរាល់"</string>
+    <string name="media_route_button_content_description" msgid="5758553567065145276">"លទ្ធផល​មេឌៀ"</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>
+    <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_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="wifi_display_notification_title" msgid="2223050649240326557">"បាន​ភ្ជាប់​ការ​បង្ហាញ​បណ្ដាញ​ឥត​ខ្សែ"</string>
+    <string name="wifi_display_notification_message" msgid="4498802012464170685">"អេក្រង់​នេះ​បង្ហាញ​លើ​ឧបករណ៍​ផ្សេង"</string>
+    <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"ផ្ដាច់"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"ការ​ហៅ​ពេល​អាសន្ន"</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">"កូដ PIN មិន​ត្រឹមត្រូវ"</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 ស៊ីម​កាត"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"បញ្ចូល​​កូដ PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"បញ្ចូល​ពាក្យ​សម្ងាត់"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"ឥឡូវ​ស៊ីមកាត​ត្រូវ​បាន​បិទ។ បញ្ចូល​កូដ PUK ដើម្បី​បន្ត។ ចំពោះ​ព័ត៌មាន​លម្អិត​ទាក់ទង​ក្រុមហ៊ុន​បញ្ជូន​របស់​អ្នក។"</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"បញ្ចូល​កូដ PIN ដែល​ចង់​បាន"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"បញ្ជាក់​កូដ PIN ដែល​ចង់​បាន"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"កំពុង​ដោះ​សោ​​ស៊ីម​កាត..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"កូដ PIN មិន​ត្រឹមត្រូវ។"</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"បញ្ចូល​កូដ PIN ដែល​មាន​ពី ៤ ដល់ ៨ លេខ។"</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"កូដ PUK គួរ​តែ​មាន​​ ៨ លេខ ឬ​​ច្រើន​ជាង​នេះ។"</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"បញ្ចូល​កូដ PUK ម្ដង​ទៀត។ ការ​ព្យាយាម​ដដែល​ច្រើន​ដឹង​នឹង​បិទ​ស៊ីម​កាត​ជា​អចិន្ត្រៃយ៍។"</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"កូដ PIN មិន​ដូច​គ្នា"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ព្យាយាម​លំនាំ​ច្រើន​ពេក"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"ដើម្បី​ដោះ​សោ ចូល​ក្នុង​គណនី Google ។"</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"កំពុង​ពិនិត្យ​មើល​គណនី..."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"អ្នក​បាន​បញ្ចូល​កូដ PIN របស់​អ្នក​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។\n\n ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_1">%d</xliff:g> វិនាទី។"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"អ្នក​បាន​បញ្ចូល​ពាក្យ​សម្ងាត់​មិន​ត្រឹមត្រូវ <xliff:g id="NUMBER_0">%d</xliff:g> ដង។\n\nព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_1">%d</xliff:g> វិនាទី។"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"អ្នក​បាន​​គូរ​លំនាំ​ដោះ​សោ​របស់​អ្នក​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។\n\nព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_1">%d</xliff:g> វិនាទី។"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"អ្នក​បាន​ព្យាយាម​ដោះ​សោ​​កុំព្យូទ័រ​បន្ទះ​​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម​មិន​ជោគជ័យ​​ច្រើន​ជាង <xliff:g id="NUMBER_1">%d</xliff:g> ដង កុំព្យូទ័រ​បន្ទះ​​នឹង​ត្រូវ​បាន​កំណត់​ទៅ​លំនាំដើម​ដូច​ចេញ​ពី​រោងចក្រ ហើយ​ទិន្នន័យ​អ្នកប្រើ​នឹង​បាត់បង់។"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"អ្នក​បាន​ព្យាយាម​ដោះ​សោ​ទូរស័ព្ទ​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម​មិន​ជោគជ័យ​​ច្រើន​ជាង <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម <xliff:g id="NUMBER_1">%d</xliff:g> ដង​មិន​ជោគជ័យ អ្នក​នឹង​ត្រូវ​បាន​ស្នើ​ឲ្យ​ដោះ​សោ​កុំព្យូទ័រ​បន្ទះ​របស់​អ្នក ដោយ​ប្រើ​គណនី​អ៊ីមែល។\n\n ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_2">%d</xliff:g> វិនាទី។"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"អ្នក​បាន​គូរ​លំនាំ​ដោះ​​សោ​របស់​អ្នក​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម​មិន​ជោគជ័យ​​ច្រើនជាង <xliff:g id="NUMBER_1">%d</xliff:g> ដង អ្នក​នឹង​ត្រូវ​បាន​​ស្នើ​ឲ្យ​ដោះ​សោ​ទូរស័ព្ទ​របស់​អ្នក​ដោយ​ប្រើ​គណនី​អ៊ីមែល។\n\n ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_2">%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="7324161939475478066">"បង្កើន​កម្រិត​សំឡេង​ខាង​លើ​កម្រិត​បាន​​ណែនាំ?\nស្ដាប់​កម្រិត​សំឡេង​ខ្ពស់​រយៈ​ពេល​យូរ​អាច​ឲ្យ​ខូច​ត្រចៀក។"</string>
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"សង្កត់​ដោយ​ម្រាមដៃ​ពីរ ដើម្បី​បើក​ភាព​ងាយស្រួល។"</string>
+    <string name="accessibility_enabled" msgid="1381972048564547685">"បាន​បើក​មធ្យោបាយ​ងាយស្រួល​។"</string>
+    <string name="enable_accessibility_canceled" msgid="3833923257966635673">"បាន​បោះបង់​ភាព​ងាយស្រួល។"</string>
+    <string name="user_switched" msgid="3768006783166984410">"អ្នក​ប្រើ​បច្ចុប្បន្ន <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="app_no_restricted_accounts" msgid="5739463249673727736">"កម្មវិធី​នេះ​មិន​គាំទ្រ​គណនី​សម្រាប់​ប្រវត្តិរូប​ដែល​បាន​ដាក់​កម្រិត​ទេ"</string>
+    <string name="app_not_found" msgid="3429141853498927379">"រក​មិន​ឃើញ​កម្មវិធី​ ដើម្បី​គ្រប់គ្រង​សកម្មភាព​នេះ"</string>
+    <string name="revoke" msgid="5404479185228271586">"ដកហូត"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"លិខិត​រដ្ឋាភិបាល"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"បាន​បោះ​បង់"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"កំហុស​ក្នុង​ការ​សរសេរ​មាតិកា"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"មិន​ស្គាល់"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"បញ្ចូល​លេខ​កូដ​សម្ងាត់​អ្នក​គ្រប់គ្រង"</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>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"កូដ PIN ថ្មី"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"បញ្ជាក់​កូដ PIN ថ្មី"</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_too_short" msgid="8173982756265777792">"កូដ​ PIN ខ្លី​ពេក។ ត្រូវ​តែ​មាន​យ៉ាង​ហោច​ណាស់ ៤ តួ។"</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល​ ១​វិនាទី។"</item>
+    <item quantity="other" msgid="4730868920742952817">"សូម​ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈពេល <xliff:g id="COUNT">%d</xliff:g> វិនាទី"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"សូម​ព្យាយាម​ម្ដងទៀត​នៅ​ពេល​ក្រោយ។"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"អូស​គែម​អេក្រង់ ដើម្បី​បង្ហាញ​របារ"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"អូស​ពី​គែម​អេក្រង់ ដើម្បី​បង្ហាញ​របារ​ប្រព័ន្ធ"</string>
+</resources>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
new file mode 100644
index 0000000..e8c8bb4
--- /dev/null
+++ b/core/res/res/values-km/strings.xml
@@ -0,0 +1,1588 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<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="5973789783504771878">"គីឡូបៃ"</string>
+    <string name="megabyteShort" msgid="6355851576770428922">"មេកាបៃ"</string>
+    <string name="gigabyteShort" msgid="3259882455212193214">"ជីកាបៃ"</string>
+    <string name="terabyteShort" msgid="231613018159186962">"តេរ៉ាបៃ"</string>
+    <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
+    <string name="untitled" msgid="4638956954852782576">"&lt;គ្មាន​ចំណង​ជើង&gt;"</string>
+    <string name="ellipsis" msgid="7899829516048813237">"…"</string>
+    <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
+    <string name="emptyPhoneNumber" msgid="7694063042079676517">"(គ្មាន​លេខ​ទូរស័ព្ទ)"</string>
+    <string name="unknownName" msgid="2277556546742746522">"(មិន​ស្គាល់)"</string>
+    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"សារ​ជា​សំឡេង"</string>
+    <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
+    <string name="mmiError" msgid="5154499457739052907">"បញ្ហា​ក្នុង​ការ​តភ្ជាប់​ ឬ​កូដ MMI មិន​ត្រឹមត្រូវ។"</string>
+    <string name="mmiFdnError" msgid="5224398216385316471">"ប្រតិបត្តិការ​ត្រូវ​បាន​ដាក់​កម្រិត​​​ចំពោះ​លេខ​ហៅ​ថេរ​តែ​ប៉ុណ្ណោះ។"</string>
+    <string name="serviceEnabled" msgid="8147278346414714315">"បាន​បើក​សេវាកម្ម។"</string>
+    <string name="serviceEnabledFor" msgid="6856228140453471041">"បាន​បើក​សេវាកម្ម​សម្រាប់៖"</string>
+    <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="mmiComplete" msgid="8232527495411698359">"MMI បញ្ចប់​។"</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 ដែល​មាន​​​ពី ៤ ដល់ ៨​លេខ"</string>
+    <string name="invalidPuk" msgid="8761456210898036513">"បញ្ចូល​កូដ PUK ដែល​មាន​ពី​ ៨ លេខ​ ឬ​វែង​ជាង​នេះ។"</string>
+    <string name="needPuk" msgid="919668385956251611">"ស៊ីមកាត​​របស់​អ្នក​ជាប់​កូដ PUK ។ បញ្ចូល​កូដ PUK ដើម្បី​ដោះ​សោ។"</string>
+    <string name="needPuk2" msgid="4526033371987193070">"បញ្ចូល​កូដ PUK2 ដើម្បី​ដោះ​សោ​ស៊ីម​កាត។"</string>
+    <string name="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="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">"ប្ដូរ​កូដ PIN"</string>
+    <string name="CnipMmi" msgid="3110534680557857162">"បង្ហាញ​ការ​ហៅ​លេខ"</string>
+    <string name="CnirMmi" msgid="3062102121430548731">"បាន​ដាក់​កម្រិត​ការ​ហៅ​លេខ"</string>
+    <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="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"បាន​ដាក់​កម្រិត​លំនាំដើម​លេខ​សម្គាល់​អ្នក​ហៅ។​​​ ការ​ហៅ​បន្ទាប់៖​ បាន​ដាក់កម្រិត"</string>
+    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"មិន​បាន​ដាក់កម្រិត​លំនាំដើម​លេខ​សម្គាល់​អ្នក​ហៅ។ ការ​ហៅ​បន្ទាប់៖ មិន​បាន​ដាក់​កម្រិត។"</string>
+    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"មិន​បាន​ដាក់​កម្រិត​លេខ​សម្គាល់​អ្នក​ហៅ​លំនាំ​ដើម។ ការ​ហៅ​បន្ទាប់៖​ បាន​ដាក់កម្រិត"</string>
+    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"មិន​បាន​ដាក់កម្រិត​លំនាំដើម​លេខ​សម្គាល់​អ្នក​ហៅ។ ការ​ហៅ​បន្ទាប់៖ មិន​បាន​ដាក់​កម្រិត។"</string>
+    <string name="serviceNotProvisioned" msgid="8614830180508686666">"មិន​បាន​ផ្ដល់​សេវាកម្ម។"</string>
+    <string name="CLIRPermanent" msgid="3377371145926835671">"អ្នក​មិន​អាច​ប្ដូរ​ការ​កំណត់​លេខ​សម្គាល់​អ្នក​ហៅ​បានទេ។"</string>
+    <string name="RestrictedChangedTitle" msgid="5592189398956187498">"បាន​ប្ដូរ​ការ​ចូល​ដំណើរការ​ដែល​បាន​ដាក់​​កម្រិត"</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="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>
+    <string name="serviceClassDataSync" msgid="7530000519646054776">"ធ្វើ​សម​កាល​កម្ម"</string>
+    <string name="serviceClassPacket" msgid="6991006557993423453">"កញ្ចប់​ព័ត៌មាន"</string>
+    <string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
+    <string name="roamingText0" msgid="7170335472198694945">"បើក​ទ្រនិច​បង្ហាញ​រ៉ូមីង"</string>
+    <string name="roamingText1" msgid="5314861519752538922">"បិទ​ទ្រនិច​បង្ហាញ​រ៉ូមីង"</string>
+    <string name="roamingText2" msgid="8969929049081268115">"ពន្លឺ​​ទ្រនិច​បង្ហាញ​រ៉ូមីង"</string>
+    <string name="roamingText3" msgid="5148255027043943317">"ចេញ​ពី​អ្នកជិតខាង"</string>
+    <string name="roamingText4" msgid="8808456682550796530">"ក្រៅ​​អាគារ"</string>
+    <string name="roamingText5" msgid="7604063252850354350">"រ៉ូមីង - ប្រព័ន្ធ​ពេញចិត្ត"</string>
+    <string name="roamingText6" msgid="2059440825782871513">"រ៉ូ​មីង - ប្រព័ន្ធ​​អាច​ប្រើ​បាន"</string>
+    <string name="roamingText7" msgid="7112078724097233605">"រ៉ូ​មីង - ​សម្ពន្ធភាព"</string>
+    <string name="roamingText8" msgid="5989569778604089291">"រ៉ូ​មីង - ដៃគូ​ពិសេស"</string>
+    <string name="roamingText9" msgid="7969296811355152491">"រ៉ូ​មីង - មុខងារ​សេវា​កម្ម​ពេញលេញ"</string>
+    <string name="roamingText10" msgid="3992906999815316417">"រ៉ូ​មីង - មុខងារ​សេវា​តាម​​ផ្នែក"</string>
+    <string name="roamingText11" msgid="4154476854426920970">"បើក​បដា​រ៉ូមីង"</string>
+    <string name="roamingText12" msgid="1189071119992726320">"បិទ​បដា​រ៉ូមីង"</string>
+    <string name="roamingTextSearching" msgid="8360141885972279963">"​ស្វែង​រក​សេវាកម្ម"</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="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="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="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="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="default" msgid="3475999286680000541">"ឧបករណ៍​ផ្ទុក​ទូរស័ព្ទ​ពេញ! លុប​ឯកសារ​មួយ​ចំនួន​ដើម្បី​បង្កើន​ទំហំ។"</string>
+    <string name="me" msgid="6545696007631404292">"ខ្ញុំ"</string>
+    <string name="power_dialog" product="tablet" msgid="8545351420865202853">"ជម្រើស​កុំព្យូទ័រ​បន្ទះ"</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="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="shutdown_progress" msgid="2281079257329981203">"កំពុង​បិទ..."</string>
+    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"កុំព្យូទ័រ​បន្ទះ​របស់​អ្នក​នឹង​បិទ។"</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="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_bug_report" msgid="7934010578922304799">"របាយការណ៍​កំហុស"</string>
+    <string name="bugreport_title" msgid="2667494803742548533">"យក​របាយការណ៍​កំហុស"</string>
+    <string name="bugreport_message" msgid="398447048750350456">"វា​នឹង​​ប្រមូល​ព័ត៌មាន​អំពី​ស្ថានភាព​ឧបករណ៍​របស់​អ្នក ដើម្បី​ផ្ញើ​ជា​សារ​អ៊ីមែល។ វា​នឹង​ចំណាយ​ពេល​តិច​ពី​ពេល​ចាប់ផ្ដើម​របាយការណ៍​រហូត​ដល់​ពេល​វា​រួចរាល់​ដើម្បី​ផ្ញើ សូម​អត់ធ្មត់។"</string>
+    <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_airplane_mode_on_status" msgid="2719557982608919750">"បាន​បើក​របៀប​ពេល​ជិះ​យន្ត​ហោះ"</string>
+    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"បាន​បិទ​របៀប​យន្តហោះ"</string>
+    <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
+    <string name="safeMode" msgid="2788228061547930246">"របៀប​​​សុវត្ថិភាព"</string>
+    <string name="android_system_label" msgid="6577375335728551336">"ប្រព័ន្ធ​​ Android"</string>
+    <string name="permgrouplab_costMoney" msgid="5429808217861460401">"សេវាកម្ម​ដែល​កាត់​លុយ​របស់​អ្នក"</string>
+    <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"ធ្វើ​អ្វី​ដែល​អាច​កាត់​លុយ​របស់​អ្នក។"</string>
+    <string name="permgrouplab_messages" msgid="7521249148445456662">"សារ​របស់​អ្នក"</string>
+    <string name="permgroupdesc_messages" msgid="7821999071003699236">"អាន និង​សរសេរ​សារ SMS, អ៊ីមែល និង​សារ​ផ្សេងៗ​ទៀត​របស់​អ្នក។"</string>
+    <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"ព័ត៌មាន​ផ្ទាល់ខ្លួន​របស់​អ្នក"</string>
+    <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"ចូល​ដំណើរការ​ព័ត៌មាន​ដោយ​ផ្ទាល់​អំពី​អ្នក​ ដែល​បា​ន​រក្សាទុក​ក្នុង​កាត​ទំនាក់ទំនង​របស់​អ្នក។"</string>
+    <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"ព័ត៌មាន​សង្គម​របស់​អ្នក"</string>
+    <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"ចូល​ដំណើរការ​ព័ត៌មាន​ដោយ​ផ្ទាល់​អំពី​ទំនាក់ទំនង និង​ការ​ភ្ជាប់​សង្គម​របស់​អ្នក។"</string>
+    <string name="permgrouplab_location" msgid="635149742436692049">"ទីតាំង​របស់​អ្នក"</string>
+    <string name="permgroupdesc_location" msgid="5704679763124170100">"តាមដាន​ទីតាំង​ជាក់ស្ដែង​របស់​អ្នក។"</string>
+    <string name="permgrouplab_network" msgid="5808983377727109831">"ការ​ទាក់ទង​បណ្ដាញ"</string>
+    <string name="permgroupdesc_network" msgid="4478299413241861987">"ចូល​ដំណើរការ​លក្ខណៈ​​បណ្ដាញ​ផ្សេងៗ។"</string>
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"ប៊្លូធូស"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"ចូល​ដំណើរការ​ឧបករណ៍ និង​បណ្ដាញ​តាម​ប៊្លូធូស។"</string>
+    <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"ការ​កំណត់​អូឌីយ៉ូ"</string>
+    <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"ប្ដូរ​ការ​កំណត់​អូឌីយ៉ូ។"</string>
+    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"ប៉ះពាល់​ដល់​ថ្ម"</string>
+    <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"ប្រើ​លក្ខណៈ​ដែល​អាច​ប្រើ​ថាមពល​ថ្ម​យ៉ាង​រហ័ស។"</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"ប្រតិទិន"</string>
+    <string name="permgroupdesc_calendar" msgid="5777534316982184416">"​ចូល​ដំណើរការ​​ប្រតិទិន​\"និង​ព្រឹត្តិការណ៍​ដោយ​ផ្ទាល់​។"</string>
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"អាន​វចនានុក្រម​អ្នក​ប្រើ"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"អាន​ពាក្យ​នៅ​ក្នុង​វចនានុក្រម​​អ្នក​ប្រើ​។"</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"សរសេរ​វចនានុក្រម​អ្នក​ប្រើ"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"បន្ថែម​ពាក្យ​ទៅ​វចនានុក្រម​អ្នក​ប្រើ។"</string>
+    <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"ចំណាំ​ និង​ប្រវត្តិ"</string>
+    <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"ចូល​​ដំណើរការ​ចំណាំ និង​ប្រវត្តិ​កម្មវិធី​អ៊ីនធឺណិត​ដោយ​ផ្ទាល់។"</string>
+    <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"រោទ៍"</string>
+    <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"កំណត់​នាឡិកា​រោទ៍"</string>
+    <string name="permgrouplab_voicemail" msgid="4162237145027592133">"សារ​ជា​សំឡេង"</string>
+    <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"ចូល​ដំណើរការ​សារ​ជា​សំឡេង​ដោយ​ផ្ទាល់។"</string>
+    <string name="permgrouplab_microphone" msgid="171539900250043464">"មីក្រូ​ហ្វូន"</string>
+    <string name="permgroupdesc_microphone" msgid="7106618286905738408">"ចូល​ដំណើរការ​​មីក្រូហ្វូន​ដោយ​ផ្ទាល់ ​ដើម្បី​ថត​សំឡេង​។"</string>
+    <string name="permgrouplab_camera" msgid="4820372495894586615">"ម៉ាស៊ីន​ថត"</string>
+    <string name="permgroupdesc_camera" msgid="2933667372289567714">"ចូល​ដំណើរការ​ម៉ាស៊ីន​ថត​រូប ឬ​វីដេអូ​ដោយ​ផ្ទាល់។"</string>
+    <string name="permgrouplab_screenlock" msgid="8275500173330718168">"ចាក់សោ​​អេក្រង់"</string>
+    <string name="permgroupdesc_screenlock" msgid="7067497128925499401">"មាន​សមត្ថភាព​ប៉ះពាល់​ឥរិយាបថ​ការ​ចាក់​សោ​អេក្រង់​លើ​ឧបករណ៍​របស់​អ្នក។"</string>
+    <string name="permgrouplab_appInfo" msgid="8028789762634147725">"ព័ត៌មាន​កម្មវិធី​របស់​អ្នក"</string>
+    <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"លទ្ធភាព​ប៉ះពាល់​ដល់​ឥរិយាបថ​កម្មវិធី​ផ្សេងៗ​លើ​ឧបករណ៍​របស់​អ្នក។"</string>
+    <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"ផ្ទាំង​រូបភាព"</string>
+    <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"ប្ដូរ​ការ​កំណត់​ផ្ទាំង​រូបភាព​ឧបករណ៍"</string>
+    <string name="permgrouplab_systemClock" msgid="406535759236612992">"នាឡិកា"</string>
+    <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"ប្ដូរ​ពេលវេលា ឬ​តំបន់​ពេលវេលា​ឧបករណ៍"</string>
+    <string name="permgrouplab_statusBar" msgid="2095862568113945398">"របារ​ស្ថានភាព"</string>
+    <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"ប្ដូរ​ការ​កំណត់​របារ​ស្ថានភាព​ឧបករណ៍។"</string>
+    <string name="permgrouplab_syncSettings" msgid="3341990986147826541">"ការ​កំណត់​​​ធ្វើ​សម​កាល​កម្ម"</string>
+    <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"ចូល​ដំណើរការ​ការ​កំណត់​ធ្វើ​សម​កាល​កម្ម។"</string>
+    <string name="permgrouplab_accounts" msgid="3359646291125325519">"គណនី​របស់​អ្នក"</string>
+    <string name="permgroupdesc_accounts" msgid="4948732641827091312">"ចូល​ដំណើរការ​គណនី​ដែល​មាន។"</string>
+    <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"ពិនិត្យ​ផ្នែករឹង"</string>
+    <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"ចូល​ដំណើរការ​ផ្នែក​រឹង​ដោយ​ផ្ទាល់​ក្នុង​ទូរស័ព្ទ។"</string>
+    <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"ហៅ​ទូរស័ព្ទ"</string>
+    <string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"តាមដាន ថត និង​ដំណើរការ​ការ​ហៅ​ទូរស័ព្ទ។"</string>
+    <string name="permgrouplab_systemTools" msgid="4652191644082714048">"ឧបករណ៍​ប្រព័ន្ធ"</string>
+    <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"ចូល​ដំណើរការ​កម្រិត​ទាប និង​ពិនិត្យ​ប្រព័ន្ធ។"</string>
+    <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"ឧបករណ៍​​អភិវឌ្ឍ"</string>
+    <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"លក្ខណៈ​ចាំបាច់​សម្រាប់​តែ​អ្នក​អភិវឌ្ឍ​កម្មវិធី។"</string>
+    <string name="permgrouplab_display" msgid="4279909676036402636">"ចំណុច​ប្រទាក់​អ្នក​ប្រើ​កម្មវិធី​ផ្សេងៗ"</string>
+    <string name="permgroupdesc_display" msgid="6051002031933013714">"ប្រសិទ្ធ​ភាព​ចំណុច​ប្រទាក់​អ្នក​ប្រើ​នៃ​កម្មវិធី​ផ្សេងៗ។"</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"ការ​ផ្ទុក"</string>
+    <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"ចូល​ដំណើរការ​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី។"</string>
+    <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"ចូល​ដំណើរការ​កាត​អេសឌី"</string>
+    <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"លក្ខណៈ​ភាព​ងាយស្រួល"</string>
+    <string name="permgroupdesc_accessibilityFeatures" msgid="4205196881678144335">"លក្ខណៈ​ដែល​ជា​បច្ចេកវិទ្យា​ជំនួយ​អាច​ស្នើ។"</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="5800552516779249356">"ធាតុ​បាន​ប៉ះ​នឹង​ត្រូវ​បាន​អាន​ឮ​ៗ អេក្រង់​អាច​ត្រូវ​បាន​ស្វែងរក​ដោយ​ប្រើ​កាយវិការ។"</string>
+    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"បើក​ការ​ចូល​ដំណើរការ​បណ្ដាញ​ដែល​បាន​ធ្វើ​ឲ្យ​ប្រសើរ"</string>
+    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"ស្គ្រីប​អាច​ត្រូវ​បាន​ដំឡើង​ ដើម្បី​ធ្វើ​ឲ្យ​មាតិកា​កម្មវិធី​អាច​ចូល​ដំណើរការ​បាន​កាន់តែ​ច្រើន។"</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"មើល​អត្ថបទ​ដែល​វាយ"</string>
+    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"រួម​បញ្ចូល​ទិន្នន័យ​ផ្ទាល់​ខ្លួន​ ដូចជា​លេខ​កាត​ឥណទាន និង​ពាក្យ​សម្ងាត់។"</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"បិទ ឬ​កែ​របារ​ស្ថានភាព"</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"ឲ្យ​កម្មវិធី​បិទ​របារ​ស្ថានភាព ឬ​បន្ថែម និង​លុប​រូប​តំណាង​ប្រព័ន្ធ។"</string>
+    <string name="permlab_statusBarService" msgid="7247281911387931485">"របារ​ស្ថានភាព"</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_processOutgoingCalls" msgid="3906007831192990946">"នាំ​ផ្លូវ​ការ​ហៅ​ចេញ​ឡើងវិញ"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"ឲ្យ​កម្មវិធី​ដំណើរការ​ការ​ហៅ​ចេញ និង​ប្ដូរ​លេខ​ត្រូវ​ហៅ។ សិទ្ធិ​នេះ​អនុញ្ញាត​ឲ្យ​កម្មវិធី​តាមដាន ប្ដូរ​ទិស ឬ​ការពារ​ការ​ហៅ​ចេញ។"</string>
+    <string name="permlab_receiveSms" msgid="8673471768947895082">"ទទួល​សារ​អត្ថបទ (សារ SMS​)"</string>
+    <string name="permdesc_receiveSms" msgid="6424387754228766939">"ឲ្យ​កម្មវិធី​ទទួល និង​ដំណើរការ​​សារ MMS ។ មាន​ន័យ​ថា កម្មវិធី​អាច​ត្រួតពិនិត្យ​ ឬ​លុប​សារ​ដែល​បាន​ផ្ញើ​ទៅ​ឧបករណ៍​របស់​អ្នក ដោយ​​មិន​បង្ហាញ​អ្នក។"</string>
+    <string name="permlab_receiveMms" msgid="1821317344668257098">"ទទួល​សារ​អត្ថបទ (MMS​)"</string>
+    <string name="permdesc_receiveMms" msgid="533019437263212260">"ឲ្យ​កម្មវិធី​ទទួល និង​ដំណើរការ​​សារ​ MMS ។ វា​មាន​ន័យ​ថា កម្មវិធី​អាច​តាមដាន​ ឬ​លុប​សារ​ដែល​បាន​ផ្ញើ​ទៅ​ឧបករណ៍​របស់​អ្នក​ដោយ​មិន​បង្ហាញ​ពួកវា។"</string>
+    <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"ទទួល​ការ​ប្រកាស​ពេល​​​អាសន្ន"</string>
+    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"ឲ្យ​កម្មវិធី​ទទួល​​ដំណើរការ​សារ​ប្រកាស​ពេល​អាសន្ន។ សិទ្ធិ​នេះ​មាន​តែ​​កម្មវិធី​ប្រព័ន្ធ​ប៉ុណ្ណោះ​​អាច​ប្រើ​បាន​។"</string>
+    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"អាន​សារ​ប្រកាស​ចល័ត"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"ឲ្យ​កម្មវិធី​អាន​សារ​ប្រកាស​ការ​ហៅ​ដែល​ឧបករណ៍​របស់​​អ្នក​បាន​ទទួល។ ការ​ជូន​ដំណឹង​ប្រកាស​ចល័ត​ត្រូវ​បាន​បញ្ជូន​ទៅ​ទីតាំង​មួយ​ចំនួន ដើម្បី​ព្រមាន​អ្នក​អំពី​ស្ថានភាព​អាសន្ន។ កម្មវិធី​ព្យាបាទ​អាច​ជ្រៀតជ្រែក​ការ​អនុវត្ត ឬ​ប្រតិបត្តិការ​ឧបករណ៍​របស់​អ្នក​​ពេល​ទទួល​ការ​ប្រកាស​ចល័ត​ពេល​អាសន្ន។"</string>
+    <string name="permlab_sendSms" msgid="5600830612147671529">"ផ្ញើ​សារ SMS"</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"ឲ្យ​កម្មវិធី​ផ្ញើ​សារ​ SMS ។ វា​អាច​គិត​ថ្លៃ​សេវាកម្ម​ដែល​មិន​រំពឹង​ទុក។ កម្មវិធី​ព្យាបាទ​អាច​គិត​ថ្លៃ​សេវាកម្ម​ពី​អ្នក​ ដោយ​ផ្ញើ​សារ​ដោយ​គ្មាន​ការ​បញ្ជាក់​របស់​អ្នក។"</string>
+    <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"ផ្ញើ​ព្រឹត្តិការណ៍​សារ​តាមរយៈ​ការ​ឆ្លើយតប"</string>
+    <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"ឲ្យ​កម្មវិធី​ផ្ញើ​សំណើ​ទៅ​កម្មវិធី​ផ្ញើ​សារ ដើម្បី​គ្រប់គ្រង​ព្រឹត្តិការណ៍​សារ​តាម​រយៈ​ការ​ឆ្លើយតប​សម្រាប់​ការ​ហៅ​ចូល។"</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"អាន​សារ​អត្ថបទ​របស់​អ្នក (SMS ឬ MMS​)"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"ឲ្យ​កម្មវិធី​​អាន​សារ SMS ដែល​មាន​ក្នុង​កុំព្យូទ័រ​បន្ទះ ឬ​ស៊ីម​កាត។ វា​ឲ្យ​កម្មវិធី​អាន​សារ SMS ទាក់ទង​នឹង​មាតិកា ឬ​ព័ត៌មាន​សម្ងាត់។"</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"ឲ្យ​​កម្មវិធី​អាន​សារ SMS ដែល​បាន​រក្សាទុក​ក្នុង​ទូរស័ព្ទ ឬ​​ស៊ីម​កាត​។ វា​ឲ្យ​កម្មវិធី​អាន​សារ SMS ទាំង​អស់​ ទាក់ទង​នឹង​មាតិកា​ ឬ​ព័ត៌មាន​សម្ងាត់។"</string>
+    <string name="permlab_writeSms" msgid="3216950472636214774">"កែសម្រួល​សារ​អត្ថបទ​របស់​អ្នក (សារ SMS ឬ MMS​)"</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"ឲ្យ​កម្មវិធី​សរសេរ​សារ SMS ដែល​​បាន​រក្សាទុក​ក្នុង​កុំព្យូទ័រ​បន្ទះ ឬ​ស៊ីម​កាត​របស់​អ្នក។ កម្មវិធី​ព្យាបាទ​អាច​លុប​សារ​របស់​អ្នក។"</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"ឲ្យ​កម្មវិធី​សរសេរ​សារ 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_interactAcrossUsers" msgid="7114255281944211682">"អន្តរកម្ម​តាម​​អ្នក​ប្រើ"</string>
+    <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"ឲ្យ​កម្មវិធី​អនុវត្ត​សកម្មភាព​ឆ្លង​អ្នកប្រើ​ផ្សេងៗ​​លើ​ឧបករណ៍។ កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា ដើម្បី​បំពាន​ការ​ការពារ​រវាង​អ្នក​ប្រើ។"</string>
+    <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"អាជ្ញាប័ណ្ណ​ពេញលេញ​ ដើម្បី​ទាក់ទង​អ្នក​ប្រើ"</string>
+    <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"ឲ្យ​អន្តរកម្ម​ដែល​មាន​ទាំង​អស់​គ្រប់​អ្នក​ប្រើ។"</string>
+    <string name="permlab_manageUsers" msgid="1676150911672282428">"គ្រប់គ្រង​អ្នក​ប្រើ"</string>
+    <string name="permdesc_manageUsers" msgid="8409306667645355638">"ឲ្យ​កម្មវិធី​គ្រប់គ្រង​អ្នកប្រើ​លើ​ឧបករណ៍ រួមមាន​ការ​ច្រោះ បង្កើត និង​លុប។"</string>
+    <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"ទៅ​យក​សេចក្ដី​លម្អិត​កម្មវិធី​កំពុង​ដំណើរការ"</string>
+    <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"ឲ្យ​កម្មវិធី​ទៅ​យក​ព័ត៌មាន​លម្អិត​អំពី​កិច្ចការ​ដែល​កំពុង​ដំណើរការ​បច្ចុប្បន្ន។ កម្មវិធី​ព្យាបាទ​អាច​រកមើល​ព័ត៌មាន​ឯកជន​អំពី​កម្មវិធី​ផ្សេងៗ។"</string>
+    <string name="permlab_reorderTasks" msgid="2018575526934422779">"តម្រៀប​កម្មវិធី​កំពុង​ដំណើរការ​ឡើងវិញ"</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"ឲ្យ​កម្មវិធី​ផ្លាស់ទី​ភារកិច្ច​​ទៅ​ផ្ទៃ​ខាង​មុខ។​ កម្មវិធី​អាច​ធ្វើ​វា​ដោយ​គ្មាន​ការ​បញ្ចូល​របស់​អ្នក។"</string>
+    <string name="permlab_removeTasks" msgid="6821513401870377403">"បញ្ឈប់​ដំណើរការ​កម្មវិធី"</string>
+    <string name="permdesc_removeTasks" msgid="1394714352062635493">"ឲ្យ​កម្មវិធី​លុប​ភារកិច្ច​ និង​បញ្ឈប់​កម្មវិធី​របស់​ពួកវា។ កម្មវិធី​ព្យាបាទ​អាច​រំខាន​ឥរិយាបថ​កម្មវិធី​ផ្សេងៗ។"</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"គ្រប់គ្រង​ជង់​សកម្មភាព"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"ឲ្យ​កម្មវិធី​បន្ថែម, លុប និង​កែ​ជង់​សកម្មភាព​ដែល​កម្មវិធី​ផ្សេង​ដំណើរការ។ កម្មវិធី​ព្យាបាទ​អាច​រំខាន​ឥរិយាបថ​កម្មវិធី។"</string>
+    <string name="permlab_startAnyActivity" msgid="2918768238045206456">"ចាប់ផ្ដើម​សកម្មភាព​ណា​មួយ"</string>
+    <string name="permdesc_startAnyActivity" msgid="997823695343584001">"ឲ្យ​កម្មវិធី​ចាប់ផ្ដើម​សកម្មភាព​ណា​មួយ ទាក់ទង​នឹង​សិទ្ធិ​ការពារ​ ឬ​ស្ថានភាព​បាន​នាំចេញ។"</string>
+    <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"កំណត់​ភាព​ឆប​គ្នា​នៃ​អេក្រង់"</string>
+    <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"ឲ្យ​កម្មវិធី​ពិនិត្យ​របៀប​​ត្រូវ​​គ្នា​របស់​​អេក្រង់​នៃ​កម្មវិធី​ផ្សេងៗ។ កម្មវិធី​ព្យាបាទ​អាច​បំផ្លាញ​ឥរិយាបថ​នៃ​កម្មវិធី​ផ្សេងៗ។"</string>
+    <string name="permlab_setDebugApp" msgid="3022107198686584052">"បើក​ការ​កែ​កំហុស​កម្មវិធី"</string>
+    <string name="permdesc_setDebugApp" msgid="4474512416299013256">"ឲ្យ​កម្មវិធី​បើក​ការ​កែ​កំហុស​សម្រាប់​កម្មវិធី​ផ្សេង​ទៀត។ កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា ដើម្បី​បញ្ឈប់​កម្មវិធី​ផ្សេង។"</string>
+    <string name="permlab_changeConfiguration" msgid="4162092185124234480">"ប្ដូរ​ការ​កំណត់​បង្ហាញ​ប្រព័ន្ធ"</string>
+    <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"ឲ្យ​កម្មវិធី​ប្ដូរ​ការ​កំណត់​​រចនាសម្ព័ន្ធ​បច្ចុប្បន្ន ដូច​ជា​មូលដ្ឋាន ឬ​ទំហំ​ពុម្ពអក្សរ​ទាំងអស់។"</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_forceStopPackages" msgid="2329627428832067700">"បង្ខំ​ឲ្យ​បញ្ឈប់​កម្មវិធី​ផ្សេង"</string>
+    <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"ឲ្យ​កម្មវិធី​បញ្ឈប់​កម្មវិធី​ផ្សេង​ដោយ​បង្ខំ។"</string>
+    <string name="permlab_forceBack" msgid="652935204072584616">"បង្ខំ​ឲ្យ​កម្មវិធី​បិទ"</string>
+    <string name="permdesc_forceBack" msgid="3892295830419513623">"ឲ្យ​កម្មវិធី​បង្ខំ​សកម្មភាព​ផ្សេងៗ​ដែល​នៅ​ក្នុង​ផ្ទៃ​ខាង​មុខ​បិទ និង​ទៅ​ក្នុង​ផ្ទៃ​ខាង​ក្រោយ។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_dump" msgid="1681799862438954752">"ទៅ​យក​ស្ថានភាព​ខាង​ក្នុង​ប្រព័ន្ធ"</string>
+    <string name="permdesc_dump" msgid="1778299088692290329">"ឲ្យ​កម្មវិធី​ទៅ​យក​ស្ថានភាព​ខាង​ក្នុង​នៃ​ប្រព័ន្ធ។ កម្មវិធី​ព្យាបាទ​អាច​ទៅ​យក​ព័ត៌មាន​ឯកជន​និង​មាន​សុវត្ថិភាព​ផ្សេងៗ​ដែល​ពួកវា​មិន​គួរ​ត្រូវការ​តាម​ធម្មតា។"</string>
+    <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"ទៅ​យក​មាតិកា​អេក្រង់"</string>
+    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"ឲ្យ​កម្មវិធី​ទៅ​យក​មាតិកា​បង្អួច​សកម្ម។ កម្មវិធី​ព្យាបាទ​អាច​ទៅ​យក​មាតិកា​បង្អួច​ទាំង​មូល និង​ពិនិត្យ​អត្ថបទ​ទាំងអស់ លើកលែង​តែ​ពាក្យ​សម្ងាត់។"</string>
+    <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"បើក​មធ្យោបាយ​ងាយស្រួល​ជា​បណ្ដោះ​អាសន្ន"</string>
+    <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"ឲ្យ​កម្មវិធី​បើក​ភាព​ងាយស្រួល​លើ​ឧបករណ៍​ជា​បណ្ដោះអាសន្ន។ កម្មវិធី​ព្យាបាទ​អាច​បើក​ភាព​ងាយស្រួល​ដោយ​មិន​ឲ្យ​អ្នក​ប្រើ​ដឹង។"</string>
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"ទៅ​យក​ព័ត៌មាន​បង្អួច"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"ឲ្យ​កម្មវិធី ទៅ​យក​ព័ត៌មាន​អំពី​បង្អួច​ពី​កម្មវិធី​គ្រប់គ្រង​បង្អួច។ កម្មវិធី​ព្យាបាទ​អាច​ទៅ​យក​ព័ត៌មាន​ដែល​មាន​បំណង​សម្រាប់​ការ​ប្រើ​ប្រព័ន្ធ​ខាង​ក្នុង។"</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"ច្រោះ​ព្រឹត្តិការណ៍"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"ឲ្យ​កម្មវិធី​ចុះ​ឈ្មោះ​តម្រង​បញ្ចូល​​ដែល​ច្រោះ​​ព្រឹត្តិការណ៍​របស់​អ្នក​ប្រើ​ទាំងអស់​មុន​ពេល​ពួក​វា​ត្រូវ​បាន​ផ្ដាច់។ កម្មវិធី​ព្យាបាទ​អាច​ពិនិត្យ​ចំណុច​ប្រទាក់​ប្រព័ន្ធ​ដោយ​គ្មាន​អំពើ​ពី​អ្នក​ប្រើ។"</string>
+    <string name="permlab_magnify_display" msgid="5973626738170618775">"ពង្រីក​ការ​បង្ហាញ"</string>
+    <string name="permdesc_magnify_display" msgid="7121235684515003792">"ឲ្យ​កម្មវិធី​ពង្រីក​មាតិកា​នៃ​ការ​បង្ហាញ។ កម្មវិធី​ព្យាបាទ​អាច​ប្ដូរ​មាតិកា​ការ​បង្ហាញ​តាមវិធី​ដែល​បង្ហាញ​ថា​ឧបករណ៍​មិន​អាច​ប្រើ​បាន។"</string>
+    <string name="permlab_shutdown" msgid="7185747824038909016">"បិទ​​ដោយ​ផ្នែក"</string>
+    <string name="permdesc_shutdown" msgid="7046500838746291775">"ដាក់​កម្មវិធី​គ្រប់គ្រង​​សកម្មភាព​ក្នុង​ស្ថាន​ភាព​បិទ។ មិន​អនុវត្ត​ការ​បិទ​ពេញលេញ​ទេ។"</string>
+    <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"ការ​ពារ​​ការ​ប្ដូរ​កម្មវិធី"</string>
+    <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"ការ​ពារ​អ្នក​ប្រើ​មិន​ឲ្យ​ប្ដូរ​​ទៅ​កម្មវិធី​ផ្សេង។"</string>
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"យក​ព័ត៌មាន​កម្មវិធី​បច្ចុប្បន្ន"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="8153651434145132505">"អនុញ្ញាត​ឱ្យ​ម្ចាស់ទៅ​យក​ព័​ត៌​មាន​ឯកជន​អំពី​កម្មវិធី​បច្ចុប្បន្ន ​និង​សេវាកម្ម​នៅ​ក្នុង​ផ្ទៃ​ខាងមុខ​របស់​អេក្រង់​។"</string>
+    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"តាមដាន និង​ពិនិត្យ​ការ​ចាប់ផ្ដើម​កម្មវិធី"</string>
+    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"ឲ្យ​កម្មវិធី​តាមដាន និង​ពិនិត្យ​វិធី​ដែល​ប្រព័ន្ធ​ចាប់ផ្ដើម​​សកម្មភាព។ កម្មវិធី​ព្យាបាទ​អាច​​សម្របសម្រួល​ប្រព័ន្ធ​ទាំង​ស្រុង។ សិទ្ធិ​នេះ​ចាំបាច់​សម្រាប់​តែ​ការ​អភិវឌ្ឍ មិន​សម្រាប់​​ប្រើ​ធម្ម​តា​ទេ។"</string>
+    <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"ផ្ញើ​កញ្ចប់​​ការ​ប្រកាស​បាន​យកចេញ"</string>
+    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"ឲ្យ​កម្មវិធី​ប្រកាស​ការ​ជូន​ដំណឹង​ថា កញ្ចប់​កម្មវិធី​ត្រូវ​បាន​លុប​។ កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា ដើម្បី​​បញ្ឈប់​កម្មវិធី​ដែល​កំពុង​ដំណើរ​ការ​ផ្សេង​ៗ។"</string>
+    <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"ផ្ញើ​ការ​ប្រកាស​បាន​ទទួល SMS"</string>
+    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"ឲ្យ​កម្មវិធី​ប្រកាស​ការ​ជូន​ដំណឹង​​ការ​ទទួល​សារ​ SMS ។ កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា​​ដើម្បី​​បន្លំ​សារ SMS ចូល។"</string>
+    <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"ផ្ញើ​ការ​ប្រកាស​បាន​ទទួល​ WAP-PUSH"</string>
+    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"ឲ្យ​កម្មវិធី​ប្រកាស​ការ​ជូន​ដំណឹង​ថា​បាន​ទទួល​សារ WAP PUSH ។ កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា​ដើម្បី​​ក្លែង​​បង្កាន់ដៃ​សារ MMS ឬ​ជំនួស​មាតិកា​ទំព័រ​បណ្ដាញ​ណាមួយ​ស្ងាត់​ៗ​​​ដោយ​អ្វី​ដែល​ក្លែងក្លាយ។"</string>
+    <string name="permlab_setProcessLimit" msgid="2451873664363662666">"កំណត់​ចំនួន​ដំណើរការ​ដែល​កំពុង​ដំណើរការ"</string>
+    <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"ឲ្យ​កម្មវិធី​ពិនិត្យ​ចំនួន​ដំណើរការ​អតិបរមា​ដែល​នឹង​ដំណើរការ។ មិន​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"បង្ខំ​​ឲ្យ​បិទ​កម្មវិធី​ក្នុង​ផ្ទៃ​ខាង​ក្រោយ"</string>
+    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"ឲ្យ​កម្មវិធី​ពិនិត្យ​ថា​តើ​សកម្មភាព​​ត្រូវ​បាន​បញ្ចប់​ជា​និច្ច​ដរាប​ណា​ពួកគេ​​ទៅ​ក្នុង​ផ្ទៃ​ខាង​ក្រោយ។ មិន​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_batteryStats" msgid="2789610673514103364">"អាន​ស្ថិតិ​ថ្ម"</string>
+    <string name="permdesc_batteryStats" msgid="5897346582882915114">"ឲ្យ​កម្មវិធី​អាន​ទិន្នន័យ​ប្រើ​ថ្ម​កម្រិត​ទាប​បច្ចុប្បន្ន។ អាច​ឲ្យ​កម្មវិធី​ស្វែងយល់​ព័ត៌មាន​លម្អិត​អំពី​កម្មវិធី​ដែល​អ្នក​ប្រើ។"</string>
+    <string name="permlab_updateBatteryStats" msgid="3719689764536379557">"កែ​ស្ថិតិ​ថ្ម"</string>
+    <string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"ឲ្យ​កម្មវិធី​កែ​ស្ថិតិ​ថ្ម​ដែល​បាន​ប្រមូល។ មិន​សម្រាប់​ប្រើ​ដោយ​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_getAppOpsStats" msgid="1508779687436585744">"ទៅ​យក​ស្ថិតិ​ប្រតិបត្តិការ​កម្មវិធី"</string>
+    <string name="permdesc_getAppOpsStats" msgid="6243887041577912877">"ឲ្យ​កម្មវិធី​ទៅ​យក​ស្ថិតិ​ប្រតិបត្តិការ​កម្មវិធី​បាន​ប្រមូល។ មិន​សម្រាប់​ប្រើ​ដោយ​កម្មវិធី​ធម្មតា។"</string>
+    <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"កែ​ស្ថិតិ​ប្រតិបត្តិការ​​កម្មវិធី"</string>
+    <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"ឲ្យ​កម្មវិធី​កែ​ស្ថិតិ​ប្រតិបត្តិការ​កម្មវិធី​បាន​ប្រមូល។ មិន​សម្រាប់​ប្រើ​ដោយ​កម្មវិធី​ធម្មតា។"</string>
+    <string name="permlab_backup" msgid="470013022865453920">"ពិនិត្យ​ការ​ស្ដារ និង​បម្រុង​ទុក​ប្រព័ន្ធ"</string>
+    <string name="permdesc_backup" msgid="6912230525140589891">"ឲ្យ​កម្មវិធី​ពិនិត្យ​​យន្តការ​​បម្រុងទុក​ និង​ស្ដារ​ឡើងវិញ​របស់​ប្រព័ន្ធ។ មិន​សម្រាប់​ប្រើ​ដោយ​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"បញ្ជាក់​​ប្រតិបត្តិការ​ស្ដារ​ឡើងវិញ ឬ​បម្រុង​ទុក​ពេញលេញ"</string>
+    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"ឲ្យ​កម្មវិធី​ចាប់ផ្ដើម​ចំណុច​ប្រទាក់​​បញ្ជាក់​ការ​បម្រុង​ទុក​ពេញលេញ។ មិន​សម្រាប់​ប្រើ​ដោយ​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"បង្ហាញ​បង្អួច​គ្មាន​សិទ្ធិ"</string>
+    <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"ឲ្យ​កម្មវិធី​បង្កើត​បង្អួច​​សម្រាប់​ប្រើ​ដោយ​ចំណុច​ប្រទាក់​អ្នកប្រើ​ប្រព័ន្ធ​ខាង​ក្នុង។ មិន​សម្រាប់​ប្រើ​ដោយ​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"គូរ​លើ​កម្មវិធី​ផ្សេង"</string>
+    <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"ឲ្យ​​កម្មវិធី​គូរ​លើ​ផ្នែក​ខាង​លើ​នៃ​កម្មវិធី​ផ្សេងៗ ឬ​ជា​ផ្នែក​នៃ​ចំណុច​ប្រទាក់។ វា​អាច​រំខាន​ការ​ប្រើ​ចំណុច​ប្រទាក់​របស់​អ្នក​​ក្នុង​កម្មវិធី​ណាមួយ ឬ​ប្ដូរ​អ្វី​ដែល​អ្នក​គិត​ថា​អ្នក​កំពុង​មើល​ក្នុង​កម្មវិធី​ផ្សេងៗ។"</string>
+    <string name="permlab_setAnimationScale" msgid="2805103241153907174">"កែ​ល្បឿន​ចលនា​សកល"</string>
+    <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"ឲ្យ​កម្មវិធី​ប្ដូរ​ល្បឿន​ចលនា​សកល (ចលនា​លឿន​ ឬ​យឺត) នៅ​ពេលណា​មួយ។"</string>
+    <string name="permlab_manageAppTokens" msgid="1286505717050121370">"គ្រប់គ្រង​និមិត្តសញ្ញា​កម្មវិធី"</string>
+    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"ឲ្យ​កម្មវិធី​បង្កើត និង​គ្រប់គ្រង​និមិត្តសញ្ញា​ផ្ទាល់​របស់​ពួក​វា ដោយ​ឆ្លង​កាត់​លំដាប់ Z ធម្មតា​របស់​វា។ មិន​គួរ​​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_freezeScreen" msgid="4708181184441880175">"បង្ក​ក​​អេក្រង់"</string>
+    <string name="permdesc_freezeScreen" msgid="8558923789222670064">"ឲ្យ​កម្មវិធី​បង្កក​អេក្រង់​ជា​បណ្ដោះអាសន្ន​សម្រាប់​​ការ​​ផ្លាស់ប្ដូរ​ពេញ​អេក្រង់។"</string>
+    <string name="permlab_injectEvents" msgid="1378746584023586600">"ចុច​គ្រាប់ចុច និង​គ្រប់គ្រង​ប៊ូតុង"</string>
+    <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"ឲ្យ​កម្មវិធី​ផ្ដល់​ព្រឹត្តិការណ៍​បញ្ចូល​ផ្ទាល់​ខ្លួន​(ចុច​គ្រាប់ចុច ។ល។) ទៅ​កម្មវិធី​ផ្សេង។​ កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា​ដើម្បី​គ្រប់គ្រង​កុំព្យូទ័រ​បន្ទះ។"</string>
+    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"ឲ្យ​កម្មវិធី​ផ្ដល់​ព្រឹត្តិការណ៍​បញ្ចូល​ផ្ទាល់​ខ្លួន​របស់​វា (ចុច​គ្រាប់​ចុច ។ល។) ចំពោះ​កម្មវិធី​ផ្សេងៗ។ កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា​ដើម្បី​គ្រប់គ្រង​ទូរស័ព្ទ។"</string>
+    <string name="permlab_readInputState" msgid="469428900041249234">"កត់ត្រា​នូវ​អ្វី​ដែល​អ្នក​វាយ​ និង​សកម្មភាព​ដែល​អ្នក​បាន​យក"</string>
+    <string name="permdesc_readInputState" msgid="8387754901688728043">"ឲ្យ​កម្មវិធី​មើល​គ្រាប់​ចុច​ដែល​អ្នក​ចុច​ពេល​មាន​អន្តរកម្ម​ជា​មួយ​កម្មវិធី​ផ្សេង (ដូចជា បញ្ចូល​ពាក្យ​សម្ងាត់)។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_bindInputMethod" msgid="3360064620230515776">"ចង​ទៅ​វិធីសាស្ត្រ​បញ្ចូល"</string>
+    <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"ឲ្យ​ម្ចាស់​ចង​ចំណុច​ប្រទាក់​កម្រិត​កំពូល​នៃ​វិធី​សាស្ត្រ​បញ្ចូល។ មិន​គួរ​​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"ចង​សេវា​កម្ម​ភាព​មធ្យោបាយ​ងាយស្រួល"</string>
+    <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"ឲ្យ​​ម្ចាស់​ចង​ចំណុច​ប្រទាក់​កម្រិត​កំពូល​នៃ​សេវាកម្ម​ភាព​ងាយស្រួល។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"ចង​សេវាកម្ម​​បោះពុម្ព"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"ឲ្យ​ម្ចាស់​ចង​ចំណុច​ប្រទាក់​កម្រិត​កំពូល​នៃ​សេវាកម្ម​ធាតុ​ក្រាហ្វិក។ មិន​គួរ​​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"ចូល​ដំណើរការ​​ការងារ​បោះពុម្ព​ទាំងអស់"</string>
+    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"អនុញ្ញាត​ឲ្យ​ម្ចាស់​អាច​បោះពុម្ព​ការងារ​ដែល​បាន​បង្កើត​ដោយ​កម្មវិធី​ផ្សេង។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"ភ្ជាប់​ជាមួយ​សេវាកម្ម NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"អនុញ្ញាត​ឲ្យ​​ភ្ជាប់​​​បញ្ជី​ជាមួយ​​កម្មវិធី​ដែល​ត្រូវ​បាន​ត្រាប់​តាម​​កាត NFC ។ មិន​គួរ​ត្រូវ​​ការ​សម្រាប់​កម្មវិធី​ធម្មតា​។"</string>
+    <string name="permlab_bindTextService" msgid="7358378401915287938">"ចង​សេវា​កម្ម​អត្ថបទ"</string>
+    <string name="permdesc_bindTextService" msgid="8151968910973998670">"ឲ្យ​ម្ចាស់​ចង​ចំណុច​ប្រទាក់​កម្រិត​កំពូល​នៃ​សេវាកម្ម​អត្ថបទ (ឧ. SpellCheckerService) ។ មិន​គួរ​ប្រើ​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_bindVpnService" msgid="4708596021161473255">"ចង​ជា​មួយ​សេវាកម្ម VPN"</string>
+    <string name="permdesc_bindVpnService" msgid="2067845564581693905">"ឲ្យ​ម្ចាស់​ចង​ចំណុច​ប្រទាក់​កម្រិត​កំពូល​នៃ​សេវាកម្ម Vpn ។​ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_bindWallpaper" msgid="8716400279937856462">"ចង​ទៅ​ផ្ទាំង​រូបភាព"</string>
+    <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"ឲ្យ​ម្ចាស់​ចង​ចំណុចប្រទាក់​កម្រិត​កំពូល​នៃ​ផ្ទាំង​រូបភាព។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ចង​សេវា​កម្ម​ធាតុ​ក្រាហ្វិក"</string>
+    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"ឲ្យ​ម្ចាស់​ចង​ចំណុច​ប្រទាក់​កម្រិត​កំពូល​នៃ​សេវាកម្ម​ធាតុ​ក្រាហ្វិក។ មិន​គួរ​​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"ទាក់ទង​ជា​មួយ​អ្នកគ្រប់គ្រង​ឧបករណ៍"</string>
+    <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"ឲ្យ​ម្ចាស់​ផ្ញើ​គោលបំណង​​ទៅ​អ្នក​គ្រប់គ្រង​ឧបករណ៍។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"បន្ថែម​ ឬ​លុប​កម្មវិធី​គ្រប់គ្រង​​​ឧបករណ៍"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"អនុញ្ញាត​​​ឲ្យ​ម្ចាស់​​​បន្ថែម​ ឬ​លុប​កម្មវិធី​គ្រប់គ្រង​ឧបករណ៍​សកម្ម​ចេញ​។ មិន​គួរ​ប្រើ​សម្រាប់​កម្មវិធី​​ធម្មតា​ទេ​។"</string>
+    <string name="permlab_setOrientation" msgid="3365947717163866844">"ប្ដូរ​ទិស​អេក្រង់"</string>
+    <string name="permdesc_setOrientation" msgid="3046126619316671476">"ឲ្យ​កម្មវិធី​ប្ដូរ​ការ​បង្វិល​អេក្រង់​នៅ​ពេល​ណា​មួយ។ មិន​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"ប្ដូរ​ល្បឿន​ទ្រនិច"</string>
+    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"ឲ្យ​កម្មវិធី​ប្ដូរ​ល្បឿន​ទ្រនិច​​កណ្ដុរ ឬ​បន្ទះ​ប៉ះ​​​នៅ​ពេល​ណា​មួយ។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"ប្ដូរ​ប្លង់​ក្ដារ​ចុច"</string>
+    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"ឲ្យ​កម្មវិធី​ប្ដូរ​ប្លង់​ក្ដារ​ចុច។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"ផ្ញើ​សញ្ញា​លីនុច​ទៅ​កម្មវិធី"</string>
+    <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"ឲ្យ​កម្មវិធី​ស្នើ​​សញ្ញា​ដែល​បាន​ផ្ដល់​ត្រូវ​ផ្ញើ​ទៅ​ដំណើរការ​ស្ថិតស្ថេរ​​ទាំង​អស់។"</string>
+    <string name="permlab_persistentActivity" msgid="8841113627955563938">"ធ្វើ​ឲ្យ​កម្មវិធី​ដំណើរការ​ជា​និច្ច"</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"ឲ្យ​កម្មវិធី​ធ្វើជា​ផ្នែក​​ស្ថិតស្ថេរ​ដោយ​ខ្លួន​ឯង​ក្នុង​អង្គ​ចងចាំ។ វា​អាច​កំណត់​អង្គ​ចងចាំ​ដែល​អាច​ប្រើ​បាន​ចំពោះ​កម្មវិធី​ផ្សេងៗ​ ដោយ​ធ្វើឲ្យ​កុំព្យូទ័រ​បន្ទះ​យឺត។"</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"ឲ្យ​កម្មវិធី ធ្វើជា​ផ្នែក​អចិន្ត្រៃយ៍​នៃ​ខ្លួន​ក្នុង​អង្គ​ចងចាំ។ វា​អាច​កម្រិត​អង្គ​ចងចាំ​អាច​ប្រើ​បាន​ ដើម្បី​ធ្វើ​ឲ្យ​កម្មវិធី​ផ្សេង​ធ្វើ​ឲ្យ​ទូរស័ព្ទ​របស់​អ្នក​យឺត។"</string>
+    <string name="permlab_deletePackages" msgid="184385129537705938">"លុប​កម្មវិធី"</string>
+    <string name="permdesc_deletePackages" msgid="7411480275167205081">"ឲ្យ​កម្មវិធី​លុប​កញ្ចប់ Android ។ កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា ដើម្បី​លុប​កម្មវិធី​សំខាន់​ៗ។"</string>
+    <string name="permlab_clearAppUserData" msgid="274109191845842756">"លុប​ទិន្នន័យ​របស់​​កម្មវិធី​ផ្សេង"</string>
+    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"ឲ្យ​កម្មវិធី​សម្អាត​ទិន្នន័យ​អ្នក​ប្រើ។"</string>
+    <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"លុប​ឃ្លាំង​សម្ងាត់​កម្មវិធី​ផ្សេងៗ"</string>
+    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"ឲ្យ​កម្មវិធី​លុប​ឯកសារ​ឃ្លាំង​សម្ងាត់។"</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"វាស់​ទំហំ​ការ​ផ្ទុក​​កម្មវិធី"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"ឲ្យ​កម្មវិធី​ទៅ​យក​កូដ ទិន្នន័យ និង​ទំហំ​ឃ្លាំង​សម្ងាត់​របស់​វា"</string>
+    <string name="permlab_installPackages" msgid="2199128482820306924">"ដំឡើង​កម្មវិធី​ដោយ​ផ្ទាល់"</string>
+    <string name="permdesc_installPackages" msgid="5628530972548071284">"ឲ្យ​កម្មវិធី​ដំឡើង​កញ្ចប់​ Android ដែល​បាន​ធ្វើ​បច្ចុប្បន្ន ឬ​ថ្មី។ កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា ដើម្បី​បន្ថែម​កម្មវិធី​ដែល​មាន​សិទ្ធិ​ដោយ​បំពាន។"</string>
+    <string name="permlab_clearAppCache" msgid="7487279391723526815">"លុប​ទិន្នន័យ​ឃ្លាំង​សម្ងាត់​កម្មវិធី​ទាំងអស់"</string>
+    <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"ឲ្យ​កម្មវិធី​បង្កើន​ទំហំ​ផ្ទុក​កុំព្យូទ័រ​បន្ទះ ដោយ​លុប​ឯកសារ​ក្នុង​ថត​ឃ្លាំង​សម្ងាត់​នៃ​កម្មវិធី​ផ្សេង។ វា​អាច​ធ្វើ​ឲ្យ​កម្មវិធី​ផ្សេង​ចាប់ផ្ដើម​យឺត​ព្រោះថា​​ពួកវា​ត្រូវ​ទៅ​យក​ទិន្នន័យ​ឡើងវិញ។"</string>
+    <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"ឲ្យ​កម្មវិធី​បង្កើន​ទំហំ​ផ្ទុក​ទូរស័ព្ទ​ ដោយ​លុប​ឯកសារ​ក្នុង​ថត​ឃ្លាំង​សម្ងាត់​កម្មវិធី។ វា​អាច​ធ្វើ​ឲ្យ​កម្មវិធី​ផ្សេង​កាន់​តែ​យឺត ព្រោះ​ថា​ពួកវា​​ត្រូវ​ទៅ​យក​ទិន្នន័យ​របស់​ពួកវា។"</string>
+    <string name="permlab_movePackage" msgid="3289890271645921411">"ផ្លាស់ទី​ធនធាន​កម្មវិធី"</string>
+    <string name="permdesc_movePackage" msgid="319562217778244524">"ឲ្យ​កម្មវិធី​ផ្លាស់ទី​ប្រភព​កម្មវិធី​ពី​មេឌៀ​ខាង​ក្នុង​ទៅ​ខាង​ក្រៅ​​ និង​ផ្ទុយ​មក​វិញ។"</string>
+    <string name="permlab_readLogs" msgid="6615778543198967614">"អាន​ទិន្នន័យ​កំណត់​ហេតុ​ប្រែប្រួល"</string>
+    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"ឲ្យ​កម្មវិធី​អាន​ពី​ឯកសារ​កំណត់ហេតុ​ប្រព័ន្ធ។ វា​អនុញ្ញាត​ឲ្យ​រក​មើល​ព័ត៌មាន​ទូទៅ​អំពី​អ្វី​ដែល​អ្នក​កំពុង​ធ្វើជា​មួយ​កុំព្យូទ័រ​បន្ទះ សំខាន់​រួមមាន​ព័ត៌មាន​ផ្ទាល់​ខ្លួន​ ឬ​ឯកជន។"</string>
+    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"ឲ្យ​កម្មវិធី​អាន​ពី​ឯកសារ​កំណត់ហេតុ​ប្រព័ន្ធ។ វា​អនុញ្ញាត​ឲ្យ​រក​មើល​ព័ត៌មាន​ទូទៅ​អំពី​អ្វី​ដែល​អ្នក​កំពុង​ធ្វើជា​មួយ​កុំព្យូទ័រ​បន្ទះ សំខាន់​រួមមាន​ព័ត៌មាន​ផ្ទាល់​ខ្លួន​ ឬ​ឯកជន។"</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"ប្រើ​កម្មវិធី​ឌិកូដ​​មេឌៀ​ណា​មួយ​សម្រាប់​ចាក់​ឡើងវិញ"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"ឲ្យ​កម្មវិធី​ប្រើ​កម្មវិធី​ឌិកូដ​មេឌៀ​ដែល​បាន​ដំឡើង ដើម្បី​ឌិកូដ​សម្រាប់​ការ​ចាក់​ឡើងវិញ។"</string>
+    <!-- no translation found for permlab_manageCaCertificates (1678391896786882014) -->
+    <skip />
+    <!-- no translation found for permdesc_manageCaCertificates (4015644047196937014) -->
+    <skip />
+    <string name="permlab_diagnostic" msgid="8076743953908000342">"អាន/សរសេរ​ធនធាន​គ្រប់គ្រង​ប្រអប់"</string>
+    <string name="permdesc_diagnostic" msgid="6608295692002452283">"ឲ្យ​កម្មវិធី​អាន និង​សរសេរ​ប្រភព​ណាមួយ​ដែល​គ្រប់គ្រង​ដោយ​ក្រុម​អ្នក​វិនិច្ឆ័យ ឧទាហរណ៍ ឯកសារ​នៅ​ក្នុង /dev ។ វា​អាច​ប៉ះពាល់​យ៉ាង​ខ្លាំង​ដល់​ស្ថេរ​ភាព​ និង​សុវត្ថិភាព​ប្រព័ន្ធ។ វា​គួរ​ត្រូវ​បាន​ប្រើ​សម្រាប់​វិនិច្ឆ័យ​ផ្នែក​រឹង​ជាក់​លាក់​ដោយ​ក្រុមហ៊ុន​ផលិត ឬ​ប្រតិបត្តិ​ករ។"</string>
+    <string name="permlab_changeComponentState" msgid="6335576775711095931">"បិទ ឬ​បើក​សមាសធាតុ​កម្មវិធី"</string>
+    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"ឲ្យ​កម្មវិធី​ប្ដូរ​ថា​តើ​សមាសធាតុ​កម្មវិធី​ផ្សេង​ត្រូវ​បាន​បើក​​ ឬ​ក៏​អត់។ កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា ដើម្បី​បិទ​សមត្ថភាព​ទូរស័ព្ទ​សំខាន់។ ប្រើ​ដោយ​ប្រុងប្រយ័ត្ន​ជា​មួយ​​សិទ្ធិ​នេះ ព្រោះ​ថា​វា​អាច​ធ្វើ​ឲ្យ​សមាសធាតុ​មិន​អាច​ប្រើ​បាន​ ស្ថិតស្ថេរ ឬ​​មិន​ស្ថិតស្ថេរ។"</string>
+    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"ឲ្យ​កម្មវិធី​ប្ដូរ​ថាតើ​សមាសធាតុ​កម្មវិធី​ផ្សេង​ត្រូវ​បាន​បើក​​ ឬ​ក៏​អត់។ កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា ដើម្បី​បិទ​សមត្ថភាព​ទូរស័ព្ទ​សំខាន់។ ប្រើ​ដោយ​ប្រុងប្រយ័ត្ន​ជា​មួយ​​សិទ្ធិ​នេះ ព្រោះ​ថា​វា​អាច​ធ្វើ​ឲ្យ​សមាសធាតុ​មិន​អាច​ប្រើ​បាន​ ស្ថិតស្ថេរ ឬ​​មិន​ស្ថិតស្ថេរ។"</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"ផ្ដល់ ឬ​ដក​សិទ្ធិ"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"ឲ្យ​កម្មវិធី​ផ្ដល់ ឬ​ដក​សិទ្ធិ​ជាក់លាក់​សម្រាប់​វា ឬ​កម្មវិធី​ផ្សេង។ កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា​ដើម្បី​ចូល​លក្ខណៈ​ដែល​អ្នក​មិន​បាន​ផ្ដល់​ឲ្យ​ពួកវា។"</string>
+    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"កំណត់​កម្មវិធី​ពេញ​ចិត្ត"</string>
+    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"ឲ្យ​កម្មវិធី​កែ​កម្មវិធី​ដែល​អ្នក​ពេញ​ចិត្ត។ កម្មវិធី​ព្យាបាទ​អាច​ប្ដូរ​កម្មវិធី​ដែល​ដំណើរការ​ស្ងាត់​ៗ ដោយ​​​បញ្ឆោត​កម្មវិធី​ដែល​មាន​ស្រាប់​​របស់​អ្នក​ ដើម្បី​ប្រមូល​ទិន្នន័យ​ឯកជន​​ពី​អ្នក។"</string>
+    <string name="permlab_writeSettings" msgid="2226195290955224730">"កែ​​ការ​កំណត់​ប្រព័ន្ធ"</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"ឲ្យ​កម្មវិធី​កែ​ទិន្នន័យ​កំណត់​ប្រព័ន្ធ។ កម្មវិធី​ព្យាបាទ​អាច​បង្ខូច​ការ​កំណត់​រចនាសម័្ពន្ធ​នៃ​ប្រព័ន្ធ​របស់​អ្នក។"</string>
+    <string name="permlab_writeSecureSettings" msgid="204676251876718288">"កែ​ការ​កំណត់​ប្រព័ន្ធ​សុវត្ថិភាព"</string>
+    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"ឲ្យ​កម្មវិធី​កែ​ទិន្នន័យ​កំណត់​​សុវត្ថិភាព​​របស់​ប្រព័ន្ធ។ មិន​សម្រាប់​ប្រើ​ដោយ​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_writeGservices" msgid="2149426664226152185">"កែ​ផែនទី​សេវាកម្ម​ Google"</string>
+    <string name="permdesc_writeGservices" msgid="1287309437638380229">"ឲ្យ​កម្មវិធី​កែ​ផែនទី​សេវាកម្ម​ Google ។ មិន​សម្រាប់​ប្រើ​ដោយ​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"ដំណើរការ​ពេល​ចាប់ផ្ដើម"</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"ឲ្យ​កម្មវិធី​ចាប់ផ្ដើម​ដោយ​ខ្លួន​វា​ផ្ទាល់​ដរាប​​ណា​ប្រព័ន្ធ​​បាន​ចាប់ផ្ដើម​​រួចរាល់។ វា​អាច​​ចំណាយ​ពេល​យូរ​ដើម្បី​ចាប់ផ្ដើម​កុំព្យូទ័រ​បន្ទះ និង​ឲ្យ​កម្មវិធី​ធ្វើ​ឲ្យ​កុំព្យូទ័រ​បន្ទះ​យឺត​ដោយ​ដំណើរការ​ជា​និច្ច។"</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="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="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="default" msgid="589869224625163558">"ឲ្យ​កម្មវិធី​កែ​ទិន្នន័យ​អំពី​ទំនាក់ទំនង​របស់​អ្នក​ដែល​បាន​រក្សាទុក​ក្នុង​ទូរស័ព្ទ​របស់​អ្នក រួមមាន​ប្រេកង់​ដែល​អ្នក​បាន​ហៅ អ៊ីមែល ឬ​បាន​ទាក់ទង​​តាម​វិធី​ផ្សេងៗ​ជា​មួយ​ទំនាក់​ទំនាក់​ជាក់លាក់។ សិទ្ធិ​នេះ​ឲ្យ​កម្មវិធី​លុប​ទិន្នន័យ​ទំនាក់ទំនង។"</string>
+    <string name="permlab_readCallLog" msgid="3478133184624102739">"អាន​​កំណត់​ហេតុ​​​ហៅ"</string>
+    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"ឲ្យ​កម្មវិធី​អាន​បញ្ជី​ហៅ​កុំព្យូទ័រ​បន្ទះ​របស់​អ្នក រួមមាន​ទិន្នន័យ​អំពី​ការ​ហៅ​ចូល និង​ចេញ។ សិទ្ធិ​នេះ​អនុញ្ញាត​ឲ្យ​កម្មវិធី​រក្សាទុក​ទិន្នន័យ​បញ្ជី​ហៅ​របស់​អ្នក ហើយ​កម្មវិធី​ព្យាបាទ​អាច​ចែករំលែក​ទិន្នន័យ​បញ្ជី​ហៅ​ដោយ​មិន​ឲ្យ​អ្នក​ដឹង។"</string>
+    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"ឲ្យ​កម្មវិធី​អាន​​​បញ្ជី​ហៅ​ទូរស័ព្ទ​របស់​អ្នក រួមមាន​ទិន្នន័យ​អំពី​ការ​ហៅ​ចូល និង​ចេញ។ សិទ្ធិ​នេះ​អនុញ្ញាត​ឲ្យ​កម្មវិធី​រក្សាទុក​ទិន្នន័យ​បញ្ជី​ហៅ​របស់​អ្នក ហើយ​កម្មវិធី​ព្យាបាទ​អាច​ចែករំលែក​ទិន្នន័យ​បញ្ជី​ហៅ​ដោយ​មិន​ឲ្យ​អ្នកដឹង។"</string>
+    <string name="permlab_writeCallLog" msgid="8552045664743499354">"សរសេរ​បញ្ជី​ហៅ"</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ឲ្យ​កម្មវិធី​កែ​បញ្ជី​ហៅ​កុំព្យូទ័រ​បន្ទះ​របស់​អ្នក​រួមមាន​ទិន្នន័យ​អំពី​ការ​ហៅ​ចូល និង​ចេញ។​កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា ដើម្បី​លុប ឬ​កែ​បញ្ជី​ហៅ​របស់​អ្នក។"</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"ឲ្យ​កម្មវិធី​កែ​បញ្ជី​ហៅ​នៃ​ទូរស័ព្ទ​របស់​អ្នក រួមមាន​ទិន្នន័យ​អំពី​ការ​ហៅ​ចូល និង​ចេញ។ កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា ដើម្បី​លុប ឬ​កែ​បញ្ជី​ការ​ហៅ​របស់​អ្នក។"</string>
+    <string name="permlab_readProfile" msgid="4701889852612716678">"អាន​កាត​ទំនាក់ទំនង​ផ្ទាល់ខ្លួន​​របស់​អ្នក"</string>
+    <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"ឲ្យ​កម្មវិធី​អាន​ព័ត៌មាន​ប្រវត្តិរូប​ផ្ទាល់ខ្លួន​ដែល​មាន​លើ​ឧបករណ៍​របស់​អ្នក ដូច​ជា ឈ្មោះ និង​ព័ត៌មាន​ទំនាក់ទំនង។ វា​មាន​ន័យ​ថា កម្មវិធី​អាច​កំណត់​អ្នក និង​អាច​ផ្ញើ​ព័ត៌មាន​ប្រវត្តិរូប​របស់​អ្នក​ទៅ​អ្នក​ផ្សេង។"</string>
+    <string name="permlab_writeProfile" msgid="907793628777397643">"កែ​កាត​ទំនាក់ទំនង​ផ្ទាល់​ខ្លួន​របស់​អ្នក"</string>
+    <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"ឲ្យ​កម្មវិធី​ប្ដូរ ឬ​បន្ថែម​ព័ត៌មាន​ប្រវត្តិរូប​ផ្ទាល់​ខ្លួន​ដែល​បាន​រក្សាទុក​ក្នុង​ឧបករណ៍​របស់​អ្នក ដូចជា ឈ្មោះ និង​ព័ត៌មាន​ទំនាក់ទំនង​របស់​អ្នក។ នេះ​មាន​ន័យ​ថា​កម្មវិធី​អាច​កំណត់​អ្នក និង​ផ្ញើ​ព័ត៌មាន​ប្រវត្តិរូប​របស់​អ្នក​ទៅ​អ្នក​ផ្សេង។"</string>
+    <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"អាន​ចរន្ត​​សង្គម​របស់​អ្នក"</string>
+    <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"ឲ្យ​កម្មវិធី​ចូល​ដំណើរការ និង​ធ្វើ​សម​កាល​កម្ម​បច្ចុប្បន្នភាព​សង្គម​ពី​អ្នក​ និង​មិត្តភ័ក្ដិ។ ប្រយ័ត្ន​ពេល​ចែករំលែក​ព័ត៌មាន វា​អនុញ្ញាត​ឲ្យ​កម្មវិធី​អាន​ការ​ទាក់ទង​រវាង​អ្នក​ និង​មិត្តភ័ក្ដិ​លើ​បណ្ដាញ​សង្គម ទាក់ទង​នឹង​ព័ត៌មាន​សម្ងាត់។ ចំណាំ៖​ សិទ្ធិ​នេះ​មិន​អាច​ត្រូវ​បាន​​អនុវត្ត​លើ​បណ្ដាញ​សង្គម​ទាំង​អស់​បាន​ទេ។"</string>
+    <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"សរសេរ​ទៅ​ចរន្ត​សង្គម​របស់​អ្នក"</string>
+    <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"ឲ្យ​កម្មវិធី​បង្ហាញ​បច្ចុប្បន្នភាព​សង្គម​ពី​មិត្តភ័ក្ដិ​របស់​អ្នក។ ប្រយ័ត្ន​ពេល​ចែករំលែក​ព័ត៌មាន វា​ឲ្យ​កម្មវិធី​បង្កើត​​​សារ​​ដែល​អាច​បង្ហាញ​ថា​មក​ពី​មិត្តភ័ក្ដិ។ ចំណាំ៖ សិទ្ធិ​នេះ​មិន​អាច​ប្រើ​លើ​បណ្ដាញ​សង្គម​បាន​ទេ។"</string>
+    <string name="permlab_readCalendar" msgid="5972727560257612398">"អាន​ព្រឹត្តិការណ៍​ប្រតិទិន​​និង​ព័ត៌មាន​សម្ងាត់"</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"ឲ្យ​កម្មវិធី​អាច​​ព្រឹត្តិការណ៍​ប្រតិទិន​ទាំងអស់​ដែល​បាន​រក្សាទុក​ក្នុង​ទូរស័ព្ទ​របស់​អ្នក  រួមមាន​មិត្តភ័ក្ដិ និង​មិត្ត​រួម​ការងារ។ វា​អាច​ឲ្យ​កម្មវិធី​ចែករំលែក​ ឬ​រក្សាទុក​ទិន្នន័យ​ប្រតិទិន​របស់​អ្នក​​ដោយ​មិន​គិត​ពី​ការ​សម្ងាត់ ឬ​ការ​យល់​ដឹង។"</string>
+    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"ឲ្យ​កម្មវិធី​អាន​ព្រឹត្តិការណ៍​ប្រតិទិន​ទាំងអស់​ដែល​មាន​ក្នុង​កុំព្យូទ័រ​បន្ទះ​របស់​អ្នក រួមមាន​មិត្តភ័ក្ដិ ឬ​មិត្ត​រួម​ការងារ។ វា​អាច​អនុញ្ញាត​ឲ្យ​យ​កម្ម​វិធី​ចែករំលែក ឬ​រក្សាទុក​ទិន្នន័យ​ប្រតិទិន​របស់​អ្នក​ដែល​ទាក់ទង​នឹង​ព័ត៌មាន​សម្ងាត់ ឬ​​ការ​ប្រែប្រួល។"</string>
+    <string name="permlab_writeCalendar" msgid="8438874755193825647">"បន្ថែម ឬ​កែ​ព្រឹត្តិការណ៍​ប្រតិទិន​ និង​ផ្ញើ​អ៊ីមែល​ទៅ​ភ្ញៀវ​ដោយ​មិន​ឲ្យ​ម្ចាស់​ដឹង"</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"ឲ្យ​កម្មវិធី​បន្ថែម លុប ឬ​ប្ដូរ​ព្រឹត្តិការណ៍​ដែល​អ្នក​អាច​កែ​លើ​កុំព្យូទ័រ​បន្ទះ​របស់​អ្នក រួមមាន​មិត្តភ័ក្ដិ ឬ​មិត្ត​រួម​ការងារ។ វា​អាច​ឲ្យ​កម្មវិធី​ផ្ញើ​សារ​ដែល​បង្ហាញ​ថា​មក​ពី​ម្ចាស់​ប្រតិទិន​ ឬ​កែ​ព្រឹត្តិការណ៍​ដោយ​មិន​ឲ្យ​ម្ចាស់​ដឹង។"</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"ឲ្យ​កម្មវិធី​បន្ថែម លុប ឬ​ប្ដូរ​ព្រឹត្តិការណ៍​ដែល​អ្នក​អាច​កែប្រែ​លើ​ទូរស័ព្ទ​របស់​អ្នក រួមមាន​មិត្តភ័ក្ដិ ឬ​មិត្ត​រួម​ការងារ។ វា​​អាច​ឲ្យ​កម្មវិធី​ផ្ញើ​សារ​ដែល​បង្ហាញ​ថា​មក​ពី​ម្ចាស់​ប្រតិទិន ឬ​កែ​ព្រឹត្តិការណ៍​ដោយ​មិន​ឲ្យ​​អ្នក​ដឹង។"</string>
+    <string name="permlab_accessMockLocation" msgid="8688334974036823330">"ក្លែង​ប្រភព​ទីតាំង​សម្រាប់​សាកល្បង"</string>
+    <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"បង្កើត​ប្រភព​ទីតាំង​ក្លែង​ក្លាយ​សម្រាប់​សាកល្បង ឬ​ដំឡើង​ក្រុមហ៊ុន​ផ្ដល់​ទីតាំង​ថ្មី។ វា​អនុញ្ញាត​ឲ្យ​កម្មវិធី​បដិសេធ​ទីតាំង​​ និង/ឬ​ស្ថានភាព​បាន​ត្រឡប់​ដោយ​ប្រភព​ទីតាំង​ផ្សេង​ដូច​ជា GPS ឬ​ក្រុមហ៊ុន​ផ្ដល់​ទីតាំង។"</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"ចូល​ដំណើរការ​ពាក្យ​បញ្ជា​ក្រុមហ៊ុន​ផ្ដល់​ទីតាំង"</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"ឲ្យ​កម្មវិធី​ចូល​ពាក្យ​បញ្ជា​ក្រុមហ៊ុន​ផ្ដល់​ទីតាំង​បន្ថែម។ កម្មវិធី​ព្យាបាទ​អាច​ប្រើ​វា​ដើម្បី​ជ្រៀតជ្រែក​ជា​មួយ​ប្រតិបត្តិការ​ GPS ឬ​ប្រភព​ទីតាំង​ផ្សេង​ទៀត។"</string>
+    <string name="permlab_installLocationProvider" msgid="6578101199825193873">"សិទ្ធិ ដើម្បី​ដំឡើង​ក្រុមហ៊ុន​ផ្ដល់​ទីតាំង"</string>
+    <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"បង្កើត​ប្រភព​ទីតាំង​ក្លែងក្លាយ​សម្រាប់​សាកល្បង ឬ​ដំឡើង​ក្រុមហ៊ុន​ផ្ដល់​ទីតាំង​ថ្មី។ វា​អនុញ្ញាត​ឲ្យ​កម្មវិធី​បដិសេធ​ទីតាំង​ និង/ឬ​ស្ថានភាព​បាន​ត្រឡប់​ដោយ​ប្រភព​ទីតាំង​ផ្សេងៗ​ដូចជា GPS ឬ​ក្រុមហ៊ុន​ផ្ដល់​ទីតាំង។"</string>
+    <string name="permlab_accessFineLocation" msgid="1191898061965273372">"ទីតាំង​ពិតប្រាកដ (GPS និង​មាន​មូលដ្ឋាន​លើ​បណ្ដាញ)"</string>
+    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"ឲ្យ​កម្មវិធី​ទទួល​ទីតាំង​ពិតប្រាកដ​របស់​អ្នក ដោយ​ប្រើ​ប្រព័ន្ធ​កំណត់​ទីតាំង​សកម្ម (GPS) ឬ​ប្រភព​ទីតាំង​បណ្ដាញ​ដូច​ជា អង់តែន​ចល័ត និង​វ៉ាយហ្វាយ។ សេវាកម្ម​ទីតាំង​ទាំង​នេះ​ត្រូវតែ​បើក និង​អាច​ប្រើ​ចំពោះ​ឧបករណ៍​របស់​អ្នក​សម្រាប់​កម្មវិធី​ដែល​ប្រើ​ពួក​វា។ កម្មវិធី​អាច​ប្រើ​វា ដើម្បី​កំណត់​​ទីកន្លែង​របស់​អ្នក និង​អាច​ប្រើ​ថាមពល​ថ្ម​បន្ថែម។"</string>
+    <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"ទីតាំង​ប្រហាក់ប្រហែល (​​មាន​មូលដ្ឋាន​លើ​បណ្ដាញ)"</string>
+    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"ឲ្យ​កម្មវិធី​ទទួល​ទីតាំង​ប្រហាក់ប្រហែល។ ទីតាំង​នេះ​ត្រូវ​បាន​ទទួល​តាម​សេវាកម្ម​ទីតាំង​ដោយ​ប្រើ​ប្រភព​ទីតាំង​បណ្ដាញ​ដូច​ជា អង់តែន និង​វ៉ាយហ្វាយ។ សេវាកម្ម​ទីតាំង​ទាំង​នេះ​ត្រូវ​តែ​បើក និង​អាច​ប្រើ​បាន​ចំពោះ​ឧបករណ៍​របស់​អ្នក​សម្រាប់​កម្មវិធី​ដែល​ប្រើ​ពួកវា។ កម្មវិធី​អាច​ប្រើ​វា ដើម្បី​កំណត់កន្លែង​ដែល​អ្នក​នៅ​ប្រហាក់ប្រហែល។"</string>
+    <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"ចូល​ដំណើរការ​ SurfaceFlinger"</string>
+    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"ឲ្យ​កម្មវិធី​ប្រើ​លក្ខណៈ​កម្រិត​ទាប​របស់ SurfaceFlinger ។"</string>
+    <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"អាន​អង្គ​ចងចាំ​បណ្ដោះ​អាសន្ន"</string>
+    <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"ឲ្យ​កម្មវិធី​អាន​មាតិកា​នៃ​អង្គ​ចងចាំ​បណ្ដោះ​អាសន្ន។"</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"ចូល​ដំណើរការ InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"ឲ្យ​កម្មវិធី​ប្រើ​លក្ខណៈ​កម្រិត​ទាប InputFlinger ។"</string>
+    <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"កំណត់​រចនាសម្ព័ន្ធ​ការ​បង្ហាញ​វ៉ាយហ្វាយ"</string>
+    <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"ឲ្យ​កម្មវិធី​កំណត់​រចនាសម្ព័ន្ធ​ និង​ភ្ជាប់​ទៅ​ការ​បង្ហាញ​វ៉ាយហ្វាយ។"</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"ពិនិត្យ​ការ​បង្ហាញ​វ៉ាយហ្វាយ"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"ឲ្យ​កម្មវិធី​ពិនិត្យ​លក្ខណៈ​កម្រិត​ទាប​​នៃ​ការ​បង្ហាញ​វ៉ាយហ្វាយ។"</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"ចាប់​យក​លទ្ធផល​អូឌីយ៉ូ"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"​ឱ្យ​កម្មវិធី​ដើម្បី​ចាប់​យក​ និង​​ប្ដូរ​​ទិស​លទ្ធផល​អូឌីយ៉ូ​។"</string>
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"ចាប់​យក​លទ្ធផល​វីដេអូ"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"ឲ្យ​កម្មវិធី​ចាប់​យក​ និង​ប្ដូរ​​ទិស​លទ្ធផល​វីដេអូ​។"</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"ចាប់​យក​លទ្ធផល​វីដេអូ​សុវត្ថិភាព"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"ឲ្យ​​កម្មវិធី​​​ចាប់​យក ​និង​ប្ដូរ​ទិស​លទ្ធផល​វីដេអូ​ដែល​មាន​សុវត្ថិភាព​។"</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="4906839301087980680">"​ឱ្យ​កម្មវិធី​ថត​សំឡេង​​ជាមួយ​មីក្រូហ្វូន​​​។ សិទ្ធិ​នេះ​អនុញ្ញាត​ឲ្យ​កម្មវិធី​ថត​សំឡេង​​នៅ​ពេល​ណា​មួយ​ដោយ​គ្មាន​ការ​បញ្ជាក់​របស់​អ្នក។"</string>
+    <string name="permlab_camera" msgid="3616391919559751192">"ថត​រូប និងវីដេអូ"</string>
+    <string name="permdesc_camera" msgid="8497216524735535009">"ឲ្យ​កម្មវិធី​ថត​រូប និង​វីដេអូ​ដោយ​ប្រើ​ម៉ាស៊ីន​ថត។ វា​ឲ្យ​កម្មវិធី​​ប្រើ​ម៉ាស៊ីន​ថត​នៅ​ពេល​​ណាមួយ​ដោយ​គ្មាន​ការ​បញ្ជាក់​របស់​អ្នក។"</string>
+    <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"បិទ​​ពន្លឺ​បង្ហាញ​ការ​បញ្ជូន​​ពេល​ម៉ាស៊ីន​ថត​កំពុង​ប្រើ"</string>
+    <string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"ឲ្យ​កម្មវិធី​ប្រព័ន្ធ​ដែល​បាន​ដំឡើង​រួច​បិទ​​ LED បង្ហាញ​ការ​ប្រើ​ម៉ាស៊ីន​ថត។"</string>
+    <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"បិទ​កុំព្យូទ័រ​បន្ទះ​ជា​អចិន្ត្រៃយ៍"</string>
+    <string name="permlab_brick" product="default" msgid="8337817093326370537">"បិទ​ទូរស័ព្ទ​ជា​អចិន្ត្រៃយ៍"</string>
+    <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"ឲ្យ​កម្មវិធី​បិទ​កុំព្យូទ័រ​បន្ទះ​​​ជា​អចិន្ត្រៃយ៍។ វា​មាន​គ្រោះថ្នាក់​ណាស់។"</string>
+    <string name="permdesc_brick" product="default" msgid="5788903297627283099">"ឲ្យ​កម្មវិធី​បិទ​ទូរស័ព្ទ​ទាំង​មូល​​ជា​អចិន្ត្រៃយ៍។ វា​មាន​គ្រោះ​ថ្នាក់​ណាស់។"</string>
+    <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"បង្ខំ​ឲ្យ​ចាប់ផ្ដើម​កុំព្យូទ័រ​បន្ទះ​ឡើង​វិញ"</string>
+    <string name="permlab_reboot" product="default" msgid="2898560872462638242">"បង្ខំ​ឲ្យ​ទូរស័ព្ទ​ចាប់ផ្ដើម​ឡើងវិញ"</string>
+    <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"ឲ្យ​កម្មវិធី​បង្ខំ​ឲ្យ​​កុំព្យូទ័រ​បន្ទះ​ចាប់ផ្ដើម​ឡើងវិញ។"</string>
+    <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"ឲ្យ​កម្មវិធី​បង្ខំ​​ឲ្យ​ទូរស័ព្ទ​ចាប់ផ្ដើម​ឡើងវិញ។"</string>
+    <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"ការ​ចូល​ដំណើរការ​ប្រព័ន្ធ​ឯកសារ​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី"</string>
+    <string name="permlab_mount_unmount_filesystems" product="default" msgid="4402305049890953810">"ការ​ចូល​ដំណើរការ​ប្រព័ន្ធ​ឯកសារ​កាត​អេសឌី"</string>
+    <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"ឲ្យ​កម្មវិធី​ភ្ជាប់ និង​ផ្ដាច់​ប្រព័ន្ធ​ឯកសារ​សម្រាប់​ឧបករណ៍​ផ្ទុក​ចល័ត។"</string>
+    <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"លុប​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី"</string>
+    <string name="permlab_mount_format_filesystems" product="default" msgid="262582698639274056">"លុប​កាត​អេសឌី"</string>
+    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"ឲ្យ​កម្មវិធី​ធ្វើ​ទ្រង់ទ្រាយ​ឧបករណ៍​ផ្ទុក​ចល័ត។"</string>
+    <string name="permlab_asec_access" msgid="3411338632002193846">"យក​​ព័ត៌មាន​នៅ​លើ​ឧបករណ៍​​ផ្ទុក​ខាងក្នុង"</string>
+    <string name="permdesc_asec_access" msgid="3094563844593878548">"ឲ្យ​កម្មវិធី​យក​ព័ត៌មាន​លើ​ការ​​ផ្ទុក​ខាង​ក្នុង។"</string>
+    <string name="permlab_asec_create" msgid="6414757234789336327">"បង្កើត​​ឧបករណ៍​ផ្ទុក​ខាងក្នុង"</string>
+    <string name="permdesc_asec_create" msgid="4558869273585856876">"ឲ្យ​កម្មវិធី​បង្កើត​ឧបករណ៍​ផ្ទុក​ខាង​ក្នុង។"</string>
+    <string name="permlab_asec_destroy" msgid="526928328301618022">"បំផ្លាញ​​ឧបករណ៍​​ផ្ទុក​ខាងក្នុង"</string>
+    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"ឲ្យ​កម្មវិធី​បំផ្លាញ​ឧបករណ៍​ផ្ទុក​ខាង​ក្នុង។"</string>
+    <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"ភ្ជាប់/ផ្ដាច់​ឧបករណ៍​ផ្ទុក​ខាង​ក្នុង"</string>
+    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"ឲ្យ​កម្មវិធី​ភ្ជាប់/ផ្ដាច់​ឧបករណ៍​ផ្ទុក​ខាង​ក្នុង។"</string>
+    <string name="permlab_asec_rename" msgid="7496633954080472417">"ប្ដូរ​ឈ្មោះ​ឧបករណ៍​ផ្ទុក​ខាង​ក្នុង"</string>
+    <string name="permdesc_asec_rename" msgid="1794757588472127675">"ឲ្យ​កម្មវិធី​ប្ដូរ​ឈ្មោះ​ឧបករណ៍​ផ្ទុក​ខាង​ក្នុង។"</string>
+    <string name="permlab_vibrate" msgid="7696427026057705834">"ពិនិត្យ​ការ​ញ័រ"</string>
+    <string name="permdesc_vibrate" msgid="6284989245902300945">"ឲ្យ​កម្មវិធី​គ្រប់គ្រង​កម្មវិធី​ញ័រ។"</string>
+    <string name="permlab_flashlight" msgid="2155920810121984215">"ត្រួតពិនិត្យ​ពិល"</string>
+    <string name="permdesc_flashlight" msgid="6522284794568368310">"ឲ្យ​កម្មវិធី​ពិនិត្យ​ពិល។"</string>
+    <string name="permlab_manageUsb" msgid="1113453430645402723">"គ្រប់គ្រង​ចំណូល​ចិត្ត និង​សិទ្ធិ​សម្រាប់​ឧបករណ៍​យូអេសប៊ី"</string>
+    <string name="permdesc_manageUsb" msgid="7776155430218239833">"ឲ្យ​កម្មវិធី​គ្រប់គ្រង​ចំណូល​ចិត្ត និង​សិទ្ធិ​ឧបករណ៍​យូអេសប៊ី។"</string>
+    <string name="permlab_accessMtp" msgid="4953468676795917042">"អនុវត្ត​ពិធីការ MTP"</string>
+    <string name="permdesc_accessMtp" msgid="6532961200486791570">"ចូល​ដំណើរការ​កម្មវិធី​បញ្ជា kernel MTP ដើម្បី​អនុវត្ត​ពិធីការ​យូអេសប៊ី MTP ។"</string>
+    <string name="permlab_hardware_test" msgid="4148290860400659146">"សាកល្បង​ផ្នែក​រឹង"</string>
+    <string name="permdesc_hardware_test" msgid="6597964191208016605">"ឲ្យ​កម្មវិធី​ពិនិត្យ​គ្រឿង​ផ្សេងៗ​​សម្រាប់​សាកល្បង​ផ្នែក​រឹង។"</string>
+    <string name="permlab_callPhone" msgid="3925836347681847954">"ហៅ​លេខ​ទូរស័ព្ទ​ដោយ​ផ្ទាល់"</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"ឲ្យ​កម្មវិធី​ហៅ​លេខ​ទូរស័ព្ទ​ដោយ​គ្មាន​សកម្មភាព​របស់​អ្នក។​ វា​អាច​កាត់​លុយ​ ឬ​ហៅ​ដោយ​មិន​រំពឹង​ទុក។ ចំណាំ​ថា​ វា​មិន​អនុញ្ញាត​ឲ្យ​កម្មវិធី​ហៅ​លេខ​ពេល​អាសន្ន​ទេ។ កម្មវិធី​ព្យាបាទ​អាច​កាត់​លុយ​របស់​អ្នក​ ដោយ​ធ្វើការ​ហៅ​ដោយ​គ្មាន​ការ​បញ្ជាក់​របស់​អ្នក។"</string>
+    <string name="permlab_callPrivileged" msgid="4198349211108497879">"ហៅ​លេខ​ទូរស័ព្ទ​ណាមួយ​ដោយ​ផ្ទាល់"</string>
+    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"ឲ្យ​កម្មវិធី​ហៅ​លេខ​ទូរស័ព្ទ រួមមាន​លេខ​ពេល​អាសន្ន​ដោយ​គ្មាន​​អំពើ​របស់​អ្នក។ កម្មវិធី​ព្យាបាទ​អាច​ដាក់​ការ​ហៅ​មិន​ត្រឹមត្រូវ និង​ចាំបាច់​ទៅ​សេវាកម្ម​ពេល​អាសន្ន។"</string>
+    <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"ចាប់ផ្ដើម​រៀបចំ​កុំព្យូទ័រ​បន្ទះ CDMA ដោយ​ផ្ទាល់"</string>
+    <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"ចាប់ផ្ដើម​រៀបចំ​កុំព្យូទ័រ​បន្ទះ CDMA ដោយ​ផ្ទាល់"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"ឲ្យ​កម្មវិធី​ចាប់ផ្ដើម​ការ​ផ្ដល់ CDMA ។ កម្មវិធី​ព្យាបាទ​អាច​មិន​ចាំបាច់​ចាប់ផ្ដើម​ការ​ផ្ដល់ CDMA ។"</string>
+    <string name="permlab_locationUpdates" msgid="7785408253364335740">"ពិនិត្យ​​ការ​ជូន​ដំណឹង​បច្ចុប្បន្ន​ភាព​ទីតាំង"</string>
+    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"ឲ្យ​កម្មវិធី​បិទ/បើក​ការ​ជូន​ដំណឹង​បច្ចុប្បន្នភាព​ទីតាំង​ពី​វិទ្យុ។ មិន​សម្រាប់​ប្រើ​ដោយ​កម្មវិធី​ធម្មតា​ទេ។។"</string>
+    <string name="permlab_checkinProperties" msgid="7855259461268734914">"ចូល​ដំណើរការ​លក្ខណៈ​សម្បត្តិ​ពិនិត្យ​មើល"</string>
+    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"ឲ្យ​កម្មវិធី​អាន/សរសេរ​លក្ខណសម្បត្តិ​បាន​ផ្ទុក​ឡើង​ដោយ​សេវាកម្ម​ពិនិត្យ​មើល។ មិន​សម្រាប់​ប្រើ​ដោយ​កម្មវិធី​ធម្មតា។"</string>
+    <string name="permlab_bindGadget" msgid="776905339015863471">"ជ្រើស​​ធាតុ​ក្រាហ្វិក"</string>
+    <string name="permdesc_bindGadget" msgid="8261326938599049290">"ឲ្យ​កម្មវិធី​ប្រាប់​ប្រព័ន្ធ​ថា​ធាតុ​ក្រាហ្វិក​ណាមួយ​​អាច​ត្រូវ​បាន​ប្រើ​ដោយ​​កម្មវិធី​ណា​មួយ។​កម្មវិធី​ដែល​មាន​សិទ្ធិ​នេះ​អាច​ឲ្យ​កម្មវិធី​ផ្សេង​ចូល​ដំណើរការ​ទិន្នន័យ​ផ្ទាល់ខ្លួន។ មិន​សម្រាប់​ប្រើ​ដោយ​កម្មវិធី​ធម្មតា។"</string>
+    <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"កែ​ស្ថានភាព​ទូរស័ព្ទ"</string>
+    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"ឲ្យ​កម្មវិធី​ពិនិត្យ​លក្ខណៈ​ទូរស័ព្ទ​នៃ​ឧបករណ៍។ កម្មវិធី​ដែល​មាន​សិទ្ធិ​នេះ​អាច​ប្ដូរ​បណ្ដាញ បិទ និង​បើកវិទ្យុ​ក្នុង​ទូរស័ព្ទ​ដោយ​មិន​ជូន​ដំណឹង​អ្នក។"</string>
+    <string name="permlab_readPhoneState" msgid="9178228524507610486">"អាន​ស្ថានភាព និង​អត្តសញ្ញាណ​ទូរស័ព្ទ"</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"ឲ្យ​កម្មវិធី​ចូល​ដំណើរការ​លក្ខណៈ​ទូរស័ព្ទ​នៃ​ឧបករណ៍។ សិទ្ធិ​នេះ​​ឲ្យ​កម្មវិធី​កំណត់​លេខ​ទូរស័ព្ទ និង​លេខ​សម្គាល់​ឧបករណ៍ ថា​តើ​ការ​ហៅ​សកម្ម និង​លេខ​ពី​ចម្ងាយ​បាន​ភ្ជាប់​ដោយ​ការ​ហៅ។"</string>
+    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"ការពារ​​កុំព្យូទ័រ​បន្ទះ​មិន​ឲ្យ​ដេក"</string>
+    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"ការ​ពារ​ទូរស័ព្ទ​មិន​ឲ្យ​ដេក"</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"ឲ្យ​​កម្មវិធី​ការពារ​កុំព្យូទ័រ​បន្ទះ​មិន​ឲ្យ​ដេក។"</string>
+    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"ឲ្យ​កម្មវិធី​ការពារ​ទូរស័ព្ទ​មិន​ឲ្យ​ដេក។"</string>
+    <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"បិទ/បើក​កុំព្យូទ័រ​បន្ទះ"</string>
+    <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"បិទ/បើក​ទូរស័ព្ទ"</string>
+    <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"ឲ្យ​កម្មវិធី​បិទ/បើក​កុំព្យូទ័រ​បន្ទះ។"</string>
+    <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"ឲ្យ​កម្មវិធី​បិទ/បើក​ទូរស័ព្ទ។"</string>
+    <string name="permlab_factoryTest" msgid="3715225492696416187">"ដំណើរការ​ក្នុង​របៀប​សាកល្បង​ពី​រោងចក្រ"</string>
+    <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"ដំណើរការ​សាកល្បង​ក្រុមហ៊ុន​ផលិត​កម្រិត​ទាប ដោយ​អនុញ្ញាត​ឲ្យ​ចូល​ផ្នែក​រឹង​កុំព្យូទ័រ​បន្ទះ។ អាច​ប្រើ​​បាន​តែ​ពេល​កុំព្យូទ័រ​កំពុង​ដំណើរការ​ក្នុង​របៀប​សាកល្បង​ក្រុមហ៊ុន​ផលិត។"</string>
+    <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"ដំណើរ​ការ​ការ​សាកល្បង​ក្រុមហ៊ុន​ផលិត​កម្រិត​ទាប ដោយ​អនុញ្ញាត​ការ​ចូល​ដំណើរការ​ផ្នែក​រឹង​ទូរស័ព្ទ។ អាច​ប្រើ​បាន​តែ​នៅ​ពេល​ទូរស័ព្ទ​កំពុង​ដំណើរការ​របៀប​សាកល្បង​ក្រុមហ៊ុន​ផលិត។"</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_masterClear" msgid="2315750423139697397">"កំណត់​ប្រព័ន្ធ​ទៅ​លំនាំដើម​រោងចក្រ​ឡើងវិញ"</string>
+    <string name="permdesc_masterClear" msgid="3665380492633910226">"ឲ្យ​កម្មវិធី​កំណត់​ប្រព័ន្ធ​​ដូច​ការ​កំណត់​ចេញ​ពី​រោងចក្រ​ឡើងវិញ​ពេញលេញ ដោយ​លុប​ទិន្នន័យ ការ​កំណត់​រចនាសម្ព័ន្ធ និង​កម្មវិធី​បាន​ដំឡើង។"</string>
+    <string name="permlab_setTime" msgid="2021614829591775646">"កំណត់​​ម៉ោង"</string>
+    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"ឲ្យ​កម្មវិធី​ប្ដូរ​ម៉ោង​កុំព្យូទ័រ​បន្ទះ។"</string>
+    <string name="permdesc_setTime" product="default" msgid="1855702730738020">"ឲ្យ​កម្មវិធី​ប្ដូរ​ម៉ោង​ទូរស័ព្ទ។"</string>
+    <string name="permlab_setTimeZone" msgid="2945079801013077340">"កំណត់​តំបន់​ពេលវេលា"</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"ឲ្យ​កម្មវិធី​ប្ដូរ​តំបន់​ពេលវេលា​របស់​កុំព្យូទ័រ​បន្ទះ​នេះ។"</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"ឲ្យ​កម្មវិធី​ប្ដូរ​តំបន់​ពេលវេលា​របស់​ទូរស័ព្ទ។"</string>
+    <string name="permlab_accountManagerService" msgid="4829262349691386986">"ដើរ​តួ​ជា AccountManagerService"</string>
+    <string name="permdesc_accountManagerService" msgid="1948455552333615954">"ឲ្យ​កម្មវិធី​ហៅ​ទៅ​​កម្មវិធី​​ផ្ទៀងផ្ទាត់​គណនី។"</string>
+    <string name="permlab_getAccounts" msgid="1086795467760122114">"រក​គណនី​លើ​ឧបករណ៍"</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"ឲ្យ​កម្មវិធី​ទទួល​បញ្ជី​គណនី​ដែល​បាន​ស្គាល់​ដោយ​កុំព្យូទ័រ​បន្ទះ។ វា​អាច​រួម​មាន​គណនី​ណាមួយ​ដែល​បាន​បង្កើត​ដោយ​កម្មវិធី​ដែល​អ្នក​បាន​ដំឡើង។"</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"ឲ្យ​កម្មវិធី​ទទួល​បញ្ជី​គណនី​ដែល​ទូរស័ព្ទ​​បាន​ស្គាល់​។ វា​អាច​មាន​គណនី​ដែល​បាន​បង្កើត​ដោយ​កម្មវិធី​ដែល​អ្នក​បាន​ដំឡើង។"</string>
+    <string name="permlab_authenticateAccounts" msgid="5265908481172736933">"បង្កើត​គណនី និង​កំណត់​ពាក្យ​សម្ងាត់"</string>
+    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"ឲ្យ​កម្មវិធី​ប្រើ​សមត្ថភាព​កម្មវិធី​ផ្ទៀងផ្ទាត់​គណនី​នៃ​កម្មវិធី​គ្រប់គ្រង​គណនី រួមមាន​បង្កើត​គណនី និង​ទទួល ព្រម​ទាំង​កំណត់​ពាក្យ​សម្ងាត់​។"</string>
+    <string name="permlab_manageAccounts" msgid="4983126304757177305">"បន្ថែម​ ឬ​លុប​​គណនី"</string>
+    <string name="permdesc_manageAccounts" msgid="8698295625488292506">"ឲ្យ​កម្មវិធី​​អនុវត្ត​ប្រតិបត្តិការ​ដូចជា បន្ថែម និង​លុប​គណនី ព្រម​ទាំង​លុប​ពាក្យ​សម្ងាត់។"</string>
+    <string name="permlab_useCredentials" msgid="235481396163877642">"ប្រើ​គណនី​​​លើ​ឧបករណ៍"</string>
+    <string name="permdesc_useCredentials" msgid="7984227147403346422">"ឲ្យ​កម្មវិធី​ស្នើ​និមិត្តសញ្ញា​ផ្ទៀងផ្ទាត់។"</string>
+    <string name="permlab_accessNetworkState" msgid="4951027964348974773">"មើល​ការ​តភ្ជាប់​បណ្ដាញ"</string>
+    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"ឲ្យ​កម្មវិធី​មើល​ព័ត៌មាន​អំពី​ការ​តភ្ជាប់​បណ្ដាញ​ដូចជា​​មាន​បណ្ដាញ​ណាមួយ​ និង​បណ្ដាញ​ត្រូវ​បាន​ភ្ជាប់។"</string>
+    <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"ចូល​ដំណើរការ​បណ្ដាញ​ពេញ​លេញ"</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"ឲ្យ​កម្មវិធី​បង្កើត​រន្ធ​បណ្ដាញ​ និង​ប្រើ​ពិធីការ​បណ្ដាញ​តាម​បំណង។ កម្មវិធី​អ៊ីនធឺណិត​ និង​កម្មវិធី​ផ្សេង​ៗ​ផ្ដល់​វិធី​ផ្ញើ​ទិន្នន័យ​ទៅ​អ៊ីនធឺណិត ដូច្នេះ​សិទ្ធិ​នេះ​មិន​ទាមទារ​ឲ្យ​ផ្ញើ​ទិន្នន័យ​ទៅ​អ៊ីនធឺណិត។"</string>
+    <string name="permlab_writeApnSettings" msgid="505660159675751896">"ប្ដូរ/បញ្ឈប់​ចរាចរណ៍ និង​ការ​កំណត់​​បណ្ដាញ"</string>
+    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"ឲ្យ​កម្មវិធី​ប្ដូរ​ការ​កំណត់​បណ្ដាញ និង​រារាំង​ និង​តាមដាន​ចរាចរណ៍​បណ្ដាញ ឧទាហរណ៍ ដើម្បី​ប្ដូរ​ប្រូកស៊ី និង​ច្រក APN ។​ កម្មវិធី​ព្យាបាទ​អាច​ពិនិត្យ បញ្ជូន​បន្ត ឬ​កែ​កញ្ចប់​ព័ត៌មាន​បណ្ដាញ​ដោយ​មិន​ឲ្យ​អ្នក​ដឹង។"</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_changeBackgroundDataSetting" msgid="1400666012671648741">"ប្ដូរ​ការ​កំណត់​ប្រើ​ទិន្នន័យ​ផ្ទៃ​ខាង​ក្រោយ"</string>
+    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"ឲ្យ​កម្មវិធី​ប្ដូរ​ការ​កំណត់​ការ​ប្រើ​ទិន្នន័យ​ផ្ទៃ​ខាង​ក្រោយ។"</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="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="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="2405042267131496579">"ប្ដូរ​ស្ថានភាព WiMAX"</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"ឲ្យ​កម្មវិធី​តភ្ជាប់​ និង​ផ្ដាច់​កុំព្យូទ័រ​បន្ទះ​ពី​បណ្ដាញ 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="default" msgid="3207106324452312739">"ឲ្យ​កម្មវិធី​មើល​​ការ​កំណត់​រចនាសម្ព័ន្ធ​ប៊្លូធូស​ក្នុង​ទូរស័ព្ទ ដើម្បី​ទទួល និង​តភ្ជាប់​ជា​មួយ​ឧបករណ៍​បាន​ផ្គូផ្គង។"</string>
+    <string name="permlab_nfc" msgid="4423351274757876953">"ពិនិត្យ​ការ​ទាក់ទង​នៅ​ក្បែរ (NFC)"</string>
+    <string name="permdesc_nfc" msgid="7120611819401789907">"ឲ្យ​កម្មវិធី​ទាក់ទង​ជា​មួយ​ស្លាក (NFC) កាត និង​កម្មវិធី​អាន។"</string>
+    <string name="permlab_disableKeyguard" msgid="3598496301486439258">"បិទ​ការ​ចាក់​សោ​អេក្រង់​របស់​អ្នក"</string>
+    <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"ឲ្យ​កម្មវិធី​បិទ​ការ​ចាក់សោ​សុវត្ថិភាព​ពាក្យ​សម្ងាត់​ដែល​បាន​ភ្ជាប់​ណា​មួយ។ ​ឧទាហរណ៍​ត្រឹមត្រូវ​​​នៃ​ការ​បិទ​ទូរស័ព្ទ​ពេល​ទទួលការ​ហៅ​ចូល បន្ទាប់​ម​បើក​សោ​ពេល​ការ​ហៅ​បាន​បញ្ចប់។"</string>
+    <string name="permlab_readSyncSettings" msgid="6201810008230503052">"អាន​ការ​កំណត់​ធ្វើ​សម​កាល​កម្ម"</string>
+    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"ឲ្យ​កម្មវិធី​អាន​ការ​កំណត់​ធ្វើ​សម​កាល​កម្ម​សម្រាប់​គណនី។ ឧទាហរណ៍ វា​អាច​កំណត់​ថា​តើ​​​កម្មវិធី​ត្រូវ​បាន​បើក​ជា​មួយ​គណនី​ដែរ​ឬទេ។"</string>
+    <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"បិទ/បើក​ការ​ធ្វើ​សម​កាល​កម្ម"</string>
+    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"ឲ្យ​កម្មវិធី​កែ​ការ​កំណត់​ធ្វើ​សម​កាល​កម្ម​សម្រាប់​គណនី។ ឧទាហរណ៍ វា​អាច​ត្រូវ​បាន​ប្រើ​ដើម្បី​បើក​ការ​ធ្វើ​សម​កាល​កម្ម​កម្មវិធី​របស់​មនុស្ស​ជា​មួយ​គណនី។"</string>
+    <string name="permlab_readSyncStats" msgid="7396577451360202448">"អាន​ស្ថិតិ​ធ្វើ​សម​កាល​កម្ម"</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"ឲ្យ​កម្មវិធី​អាន​ស្ថានភាព​ធ្វើ​សម​កាល​កម្ម​សម្រាប់​គណនី រួមមាន​ព្រឹត្តិការណ៍​ប្រវត្តិ​ធ្វើ​សម​កាល​កម្ម ​និង​ទំហំ​ទិន្នន័យ​បាន​ធ្វើ​សម​កាល​កម្ម។"</string>
+    <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"អាន​អត្ថបទ​ព័ត៌មាន​បាន​ជាវ"</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"ឲ្យ​កម្មវិធី​ទទួល​ព័ត៌មាន​លម្អិត​អំពី​អត្ថបទ​ព័ត៌មាន​​បាន​ធ្វើ​សម​កាល​កម្ម​បច្ចុប្បន្ន។"</string>
+    <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"សរសេរ​​អត្ថបទ​ព័ត៌មាន​ដែល​​បាន​ជាវ"</string>
+    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"ឲ្យ​កម្មវិធី​កែ​អត្ថបទ​ព័ត៌មាន​បាន​ធ្វើ​សម​កាល​កម្ម​បច្ចុប្បន្ន​របស់​អ្នក។ កម្មវិធី​ព្យាបាទ​អាច​ប្ដូរ​អត្ថបទ​បាន​ធ្វើ​សម​កាល​កម្ម​របស់​អ្នក។"</string>
+    <string name="permlab_readDictionary" msgid="4107101525746035718">"អាន​ពាក្យ​ដែល​អ្នក​បាន​បន្ថែម​ទៅ​វចនានុក្រម"</string>
+    <string name="permdesc_readDictionary" msgid="659614600338904243">"ឲ្យ​កម្មវិធី​អាន​ពាក្យ ឈ្មោះ និង​ឃ្លា​ទាំងអស់​ដែល​អ្នកប្រើ​អាច​​រក្សាទុក​ក្នុង​វចនានុក្រម​​អ្នកប្រើ។"</string>
+    <string name="permlab_writeDictionary" msgid="2183110402314441106">"បន្ថែម​ពាក្យ​ទៅ​វចនានុក្រម​កំណត់​ដោយ​អ្នកប្រើ"</string>
+    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"ឲ្យ​កម្មវិធី​សរសេរ​ពាក្យ​ថ្មី​ក្នុង​វចនានុក្រម​អ្នកប្រើ។"</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"សាកល្បង​ចូល​ដំណើរការ​ការ​ផ្ទុក​ដែល​បាន​ការពារ"</string>
+    <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"សាកល្បង​ចូល​ដំណើរការ​ការ​ផ្ទុក​ដែល​បាន​ការពារ"</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"ឲ្យ​កម្មវិធី​សាកល្បង​សិទ្ធិ​សម្រាប់​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី ដែល​នឹង​អាច​ប្រើ​បាន​លើ​ឧបករណ៍​​ពេល​អនាគត។"</string>
+    <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"ឲ្យ​កម្មវិធី​សាកល្បង​សិទ្ធិ​សម្រាប់​កាត​អេសឌី​ដែល​នឹង​អាច​ប្រើ​បាន​លើ​ឧបករណ៍​នា​ពេល​អនាគត។"</string>
+    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"កែ​ ឬ​លុប​មាតិកា​នៃ​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី​របស់​អ្នក"</string>
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"កែ ឬ​លុប​មាតិកា​កាត​អេសឌី"</string>
+    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"ឲ្យ​កម្មវិធី​សរសេរ​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី។"</string>
+    <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"ឲ្យ​​កម្មវិធី​សរសេរ​ទៅ​កាត​អេសឌី។"</string>
+    <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"កែ/លុប​មាតិកា​ឧបករណ៍​ផ្ទុក​មេឌៀ​ខាង​ក្នុង"</string>
+    <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"ឲ្យ​កម្មវិធី​កែ​មាតិកា​នៃ​ឧបករណ៍​ផ្ទុក​ខាង​ក្នុង។"</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"គ្រប់គ្រង​ការ​ផ្ទុក​ឯកសារ"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"ឲ្យ​កម្មវិធី​គ្រប់គ្រង​ការ​ផ្ទុក​ឯកសារ។"</string>
+    <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"ចូល​ដំណើរការ​ឧបករណ៍​ផ្ទុក​ខាង​ក្រៅ​នៃ​អ្នកប្រើ​ទាំងអស់"</string>
+    <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"ឲ្យ​កម្មវិធី​ចូល​ដំណើរការ​ឧបករណ៍​ផ្ទុក​ខាង​ក្រៅ​សម្រាប់​អ្នកប្រើ​ទាំងអស់។"</string>
+    <string name="permlab_cache_filesystem" msgid="5656487264819669824">"ចូល​ដំណើរការ​ប្រព័ន្ធ​​​ឯកសារ​ឃ្លាំង​សម្ងាត់"</string>
+    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"ឲ្យ​កម្មវិធី​អាន និង​សរសេរ​ប្រព័ន្ធ​ឯកសារ​ឃ្លាំង​សម្ងាត់។"</string>
+    <string name="permlab_use_sip" msgid="5986952362795870502">"ធ្វើ​ការ​ហៅ/ទទួល​តាម​អ៊ីនធឺណិត"</string>
+    <string name="permdesc_use_sip" msgid="4717632000062674294">"ឲ្យ​កម្មវិធី​ប្រើ​សេវាកម្ម SIP ដើម្បី​​​ហៅ/ទទួល​​​តាម​អ៊ីនធឺណិត។"</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_markNetworkSocket" msgid="3658527214914959749">"កែប្រែ​សញ្ញា​រន្ធ"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"ឲ្យ​កម្មវិធី​កែ​សញ្ញា​រន្ធ​​សម្រាប់​នាំ​ផ្លូវ"</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_invokeCarrierSetup" msgid="3699600833975117478">"ដកហូត​កម្មវិធី​កំណត់​រចនាសម្ព័ន្ធ​ដែល​បាន​ផ្ដល់​ដោយ​ក្រុមហ៊ុន​បញ្ជូន"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"អនុញ្ញាត​ឲ្យ​ម្ចាស់​ដក​ហូត​កម្មវិធី​កំណត់​រចនាសម្ព័ន្ធ​ដែល​បាន​ផ្ដល់​ដោយ​ក្រុមហ៊ុន​បញ្ជូន។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"សង្កេត​មើល​លើ​លក្ខខណ្ឌ​បណ្ដាញ"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"ឲ្យ​កម្មវិធី​សង្កេត​មើល​​លើ​លក្ខខណ្ឌ​បណ្ដាញ​។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="policylab_limitPassword" msgid="4497420728857585791">"កំណត់​ក្បួន​ពាក្យ​សម្ងាត់"</string>
+    <string name="policydesc_limitPassword" msgid="3252114203919510394">"ពិនិត្យ​ប្រវែង និង​តួអក្សរ​ដែល​បាន​អនុញ្ញាត​ក្នុង​ពាក្យ​សម្ងាត់​ចាក់​សោ​អេក្រង់។"</string>
+    <string name="policylab_watchLogin" msgid="914130646942199503">"ពិនិត្យ​ការ​ព្យាយាម​ដោះ​សោ​អេក្រង់"</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"ពិនិត្យ​ចំនួន​​បញ្ចូល​ពាក្យ​សម្ងាត់​មិន​ត្រឹមត្រូវ។ ពេល​ដោះ​សោ​អេក្រង់ និង​ចាក់​សោ​ទូរស័ព្ទ ឬ​លុប​ទិន្នន័យ​ទូរស័ព្ទ​ទាំងអស់​ ប្រសិន​បើ​មាន​ពាក្យ​សម្ងាត់​បញ្ចូល​មិន​ត្រឹមត្រូវ​ច្រើន​ដង​ពេក។"</string>
+    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"ពិនិត្យ​ចំនួន​​បញ្ចូល​ពាក្យ​សម្ងាត់​មិន​ត្រឹមត្រូវ។ ពេល​ដោះ​សោ​អេក្រង់ និង​ចាក់​សោ​ទូរស័ព្ទ ឬ​លុប​ទិន្នន័យ​ទូរស័ព្ទ​ទាំងអស់​ ប្រសិន​បើ​មាន​ពាក្យ​សម្ងាត់​បញ្ចូល​មិន​ត្រឹមត្រូវ​ច្រើន​ដង​ពេក។"</string>
+    <string name="policylab_resetPassword" msgid="2620077191242688955">"ប្ដូរ​ពាក្យ​សម្ងាត់​ដោះ​សោ​អេក្រង់"</string>
+    <string name="policydesc_resetPassword" msgid="605963962301904458">"ប្ដូរ​ពាក្យ​សម្ងាត់​​ដោះ​សោ​អេក្រង់។"</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="default" msgid="5096895604574188391">"លុប​ទិន្នន័យ​ទូរស័ព្ទ​ដោយ​មិន​ព្រមាន ដោយ​អនុវត្ត​ការ​កំណត់​ទិន្នន័យ​ដូច​ចេញ​ពី​រោងចក្រ ។"</string>
+    <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"កំណត់​ប្រូកស៊ី​សកល​របស់​ឧបករណ៍"</string>
+    <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"កំណត់​ប្រូកស៊ី​សកល​របស់​ឧបករណ៍​ត្រូវ​ប្រើ​ពេល​បាន​បើក​គោលនយោបាយ។ មាន​តែ​អ្នក​គ្រប់គ្រង​ឧបករណ៍​ដំបូង​ប៉ុណ្ណោះ​កំណត់​ប្រូកស៊ី​សកល​ត្រឹមត្រូវ។"</string>
+    <string name="policylab_expirePassword" msgid="885279151847254056">"កំណត់​សុពលភាព​ពាក្យ​សម្ងាត់​ចាក់សោ​អេក្រង់"</string>
+    <string name="policydesc_expirePassword" msgid="1729725226314691591">"ពិនិត្យ​វិធី​ដែល​ប្ដូរ​ពាក្យ​សម្ងាត់​ចាក់​សោ​អេក្រង់​ញឹកញាប់។"</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="policylab_disableKeyguardFeatures" msgid="266329104542638802">"បិទ​លក្ខណៈ​ក្នុង​ការ​ចាក់សោ"</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="3467082272186534614">"ការ​ពារ​មិន​ឲ្យ​ប្រើ​លក្ខណៈ​មួយ​ចំនួន​ក្នុង​ការ​ចាក់សោ។"</string>
+  <string-array name="phoneTypes">
+    <item msgid="8901098336658710359">"ផ្ទះ"</item>
+    <item msgid="869923650527136615">"​ចល័ត"</item>
+    <item msgid="7897544654242874543">"កន្លែង​ធ្វើការ"</item>
+    <item msgid="1103601433382158155">"ទូរសារ​កន្លែង​ធ្វើ"</item>
+    <item msgid="1735177144948329370">"ទូរសារ​ផ្ទះ"</item>
+    <item msgid="603878674477207394">"ភេយ័រ"</item>
+    <item msgid="1650824275177931637">"ផ្សេងៗ"</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>
+  </string-array>
+  <string-array name="postalAddressTypes">
+    <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="1359644565647383708">"កន្លែង​ធ្វើការ"</item>
+    <item msgid="7868549401053615677">"ផ្សេងៗ"</item>
+    <item msgid="3145118944639869809">"តាម​តម្រូវការ"</item>
+  </string-array>
+  <string-array name="organizationTypes">
+    <item msgid="7546335612189115615">"កន្លែង​ធ្វើការ"</item>
+    <item msgid="4378074129049520373">"ផ្សេងៗ"</item>
+    <item msgid="3455047468583965104">"តាម​តម្រូវ​ការ"</item>
+  </string-array>
+  <string-array name="imProtocols">
+    <item msgid="8595261363518459565">"AIM"</item>
+    <item msgid="7390473628275490700">"Windows Live"</item>
+    <item msgid="7882877134931458217">"Yahoo"</item>
+    <item msgid="5035376313200585242">"Skype"</item>
+    <item msgid="7532363178459444943">"QQ"</item>
+    <item msgid="3713441034299660749">"ជជែក​ Google"</item>
+    <item msgid="2506857312718630823">"ICQ"</item>
+    <item msgid="1648797903785279353">"Jabber"</item>
+  </string-array>
+    <string name="phoneTypeCustom" msgid="1644738059053355820">"តាម​បំណង"</string>
+    <string name="phoneTypeHome" msgid="2570923463033985887">"ផ្ទះ"</string>
+    <string name="phoneTypeMobile" msgid="6501463557754751037">"​ចល័ត"</string>
+    <string name="phoneTypeWork" msgid="8863939667059911633">"កន្លែង​ធ្វើការ"</string>
+    <string name="phoneTypeFaxWork" msgid="3517792160008890912">"ទូរសារ​កន្លែង​ធ្វើការ"</string>
+    <string name="phoneTypeFaxHome" msgid="2067265972322971467">"ទូរសារ​ផ្ទះ"</string>
+    <string name="phoneTypePager" msgid="7582359955394921732">"ភេយ័រ"</string>
+    <string name="phoneTypeOther" msgid="1544425847868765990">"ផ្សេងៗ"</string>
+    <string name="phoneTypeCallback" msgid="2712175203065678206">"ហៅ​មក​វិញ"</string>
+    <string name="phoneTypeCar" msgid="8738360689616716982">"រថយន្ត"</string>
+    <string name="phoneTypeCompanyMain" msgid="540434356461478916">"លេខ​សំខាន់​ក្រុមហ៊ុន"</string>
+    <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string>
+    <string name="phoneTypeMain" msgid="6766137010628326916">"លេខ​សំខាន់"</string>
+    <string name="phoneTypeOtherFax" msgid="8587657145072446565">"ទូរសារ​ផ្សេង"</string>
+    <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="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="eventTypeBirthday" msgid="2813379844211390740">"ថ្ងៃ​ខួប​កំណើត"</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>
+    <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="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="imTypeWork" msgid="1371489290242433090">"កន្លែង​ធ្វើការ"</string>
+    <string name="imTypeOther" msgid="5377007495735915478">"ផ្សេងៗ"</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>
+    <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
+    <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
+    <string name="imProtocolGoogleTalk" msgid="493902321140277304">"ការ​ជជែក"</string>
+    <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">"កន្លែង​ធ្វើការ"</string>
+    <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="relationTypeBrother" msgid="8757913506784067713">"បងប្អូន​ប្រុស"</string>
+    <string name="relationTypeChild" msgid="1890746277276881626">"កូន"</string>
+    <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"ដៃគូ​ក្នុងស្រុក"</string>
+    <string name="relationTypeFather" msgid="5228034687082050725">"ឪពុក"</string>
+    <string name="relationTypeFriend" msgid="7313106762483391262">"មិត្តភ័ក្ដិ"</string>
+    <string name="relationTypeManager" msgid="6365677861610137895">"អ្នក​គ្រប់គ្រង"</string>
+    <string name="relationTypeMother" msgid="4578571352962758304">"ម្ដាយ"</string>
+    <string name="relationTypeParent" msgid="4755635567562925226">"ឪពុកម្ដាយ"</string>
+    <string name="relationTypePartner" msgid="7266490285120262781">"ដៃគូ"</string>
+    <string name="relationTypeReferredBy" msgid="101573059844135524">"យោង​ដោយ"</string>
+    <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="sipAddressTypeHome" msgid="6093598181069359295">"គេហ​ទំព័រ"</string>
+    <string name="sipAddressTypeWork" msgid="6920725730797099047">"កន្លែង​ធ្វើការ"</string>
+    <string name="sipAddressTypeOther" msgid="4408436162950119849">"ផ្សេងៗ"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"បញ្ចូល​កូដ PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"បញ្ចូល​កូដ PUK និង​ PIN ថ្មី"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"កូដ PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"កូដ PIN ថ្មី"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><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">"បញ្ចូល​កូដ PIN ដើម្បី​ដោះ​សោ"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"កូដ PIN មិន​ត្រឹមត្រូវ។"</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="8963839242565653192">"គ្មាន​សេវា។"</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="5347633784401285225">"ការ​ហៅ​​ពេល​អាសន្ន"</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="faceunlock_multiple_failures" msgid="754137583022792429">"បាន​លើស​ការ​ព្យាយាម​ដោះ​សោ​តាម​ទម្រង់​មុខ"</string>
+    <string name="lockscreen_plugged_in" msgid="8057762828355572315">"បញ្ចូល​ថ្ម <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_charged" msgid="321635745684060624">"បាន​បញ្ចូល​ពេញ។"</string>
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_low_battery" msgid="1482873981919249740">"ភ្ជាប់​ឧបករណ៍​បញ្ចូល​ថ្ម។"</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="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_transport_prev_description" msgid="201594905152746886">"ប៊ូតុង​បទ​មុន"</string>
+    <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"ប៊ូតុង​បទ​បន្ទាប់"</string>
+    <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"ប៊ូតុង​​ផ្អាក"</string>
+    <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"ប៊ូតុង​ចាក់"</string>
+    <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"ប៊ូតុង​បញ្ឈប់"</string>
+    <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_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">%d</xliff:g> ដង។ \n\nព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_1">%d</xliff:g> វិនាទី។"</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"អ្នក​បាន​បញ្ចូល​ពាក្យ​សម្ងាត់​របស់​អ្នក​មិន​ត្រឹមត្រូវ <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ \n\nព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_1">%d</xliff:g> វិនាទី។"</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"អ្នក​បាន​បញ្ចូល​កូដ​ PIN មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ \n\n ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_1">%d</xliff:g> វិនាទី។"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"អ្នក​បាន​គូរ​លំនាំ​ដោះ​សោ​របស់​អ្នក​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម​មិន​ជោគជ័យ​​ច្រើន​ជាង <xliff:g id="NUMBER_1">%d</xliff:g> ដង អ្នក​នឹង​ត្រូវ​បាន​ស្នើ​ឲ្យ​ដោះ​សោ​​កុំព្យូទ័រ​បន្ទះ​​របស់​អ្នក ដោយ​ប្រើ​ការ​ចូល​ក្នុង​គណនី Google របស់​អ្នក។\n\n សូម​ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_2">%d</xliff:g> វិនាទី។"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"អ្នក​បាន​គូរ​លំនាំ​ដោះ​សោ​របស់​អ្នក​មិន​ត្រឹមត្រូវ <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម​មិន​ជោគជ័យ <xliff:g id="NUMBER_1">%d</xliff:g> ដង​ទៀត អ្នក​នឹង​ត្រូវ​បាន​ស្នើ​ឲ្យ​ដោះ​សោ​ទូរស័ព្ទ​របស់​អ្នក​ដោយ​ប្រើ​ការ​ចូល​ Google ។\n\n ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_2">%d</xliff:g> វិនាទី។"</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"អ្នក​បាន​ព្យាយាម​ដោះ​សោ​កុំព្យូទ័រ​បន្ទះ​មិន​ត្រឹមត្រូវ <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម​មិន​ជោគជ័យ​ <xliff:g id="NUMBER_1">%d</xliff:g> ដង​ទៀត កុំព្យូទ័រ​បន្ទះ​នឹង​ត្រូវ​បាន​កំណត់​ដូច​ចេញ​ពី​រោងចក្រ​ឡើងវិញ ហើយ​ទិន្នន័យ​អ្នក​ប្រើ​ទាំងអស់​នឹង​បាត់បង់។"</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"អ្នក​បាន​ព្យាយាម​​ដោះ​សោ​​ទូរស័ព្ទ​មិន​ត្រឹមត្រូវ​ <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម​មិន​ជោគជ័យ <xliff:g id="NUMBER_1">%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="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_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_checking_password" msgid="7114627351286933867">"កំពុង​ពិនិត្យ..."</string>
+    <string name="lockscreen_unlock_label" msgid="737440483220667054">"ដោះ​សោ"</string>
+    <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"បើក​សំឡេង"</string>
+    <string name="lockscreen_sound_off_label" msgid="996822825154319026">"បិទសំឡេង"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"បាន​ចាប់​ផ្ដើម​លំនាំ"</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"បាន​សម្អាត​លំនាំ"</string>
+    <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"បាន​បន្ថែម​ក្រឡា"</string>
+    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"បាន​បញ្ចប់​លំនាំ"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. ធាតុ​ក្រាហ្វិក %2$d នៃ %3$d ។"</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_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>
+    <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_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">"កូដ PIN ដោះ​សោ។"</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>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <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_line" msgid="5764267235026120888">"បន្ទាត់"</string>
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
+    <string name="factorytest_failed" msgid="5410270329114212041">"បាន​បរាជ័យ​ក្នុង​ការ​សាកល្បង​រោងចក្រ"</string>
+    <string name="factorytest_not_system" msgid="4435201656767276723">"សកម្មភាព FACTORY_TEST ត្រូវ​បាន​គាំទ្រ​សម្រាប់​តែ​កញ្ចប់​បាន​ដំឡើង​ក្នុង /system/app."</string>
+    <string name="factorytest_no_action" msgid="872991874799998561">"រក​មិន​ឃើញ​កញ្ចប់​ដែល​ផ្ដល់​សកម្មភាព FACTORY_TEST ។"</string>
+    <string name="factorytest_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="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>
+    <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
+    <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
+    <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
+    <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
+    <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_county" msgid="237073771020362891">"ប្រទេស"</string>
+    <string name="autofill_island" msgid="4020100875984667025">"កោះ"</string>
+    <string name="autofill_district" msgid="8400735073392267672">"ស្រុក"</string>
+    <string name="autofill_department" msgid="5343279462564453309">"ផ្នែក"</string>
+    <string name="autofill_prefecture" msgid="2028499485065800419">"Prefecture"</string>
+    <string name="autofill_parish" msgid="8202206105468820057">"Parish"</string>
+    <string name="autofill_area" msgid="3547409050889952423">"តំបន់"</string>
+    <string name="autofill_emirate" msgid="2893880978835698818">"Emirate"</string>
+    <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"អាន​ប្រវត្តិ និង​ចំណាំ​បណ្ដាញ"</string>
+    <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"ឲ្យ​កម្មវិធី​អាន​ប្រវត្តិ URLs ទាំង​អស់​ដែល​កម្មវិធី​អ៊ីនធឺណិត​បាន​ទស្សនា ព្រម​ទាំង​ចំណាំ​របស់​​កម្មវិធី​អ៊ីនធឺណិត។ ចំណាំ៖ សិទ្ធិ​នេះ​​មិន​អាច​ត្រូវ​បាន​អនុវត្ត​ដោយ​កម្មវិធី​អ៊ីនធឺណិត​ភាគី​ទីបី ឬ​កម្មវិធី​ដែល​មាន​សមត្ថភាព​រុករក​បណ្ដាញ។"</string>
+    <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"សរសេរ​ចំណាំ និង​ប្រវត្តិ​បណ្ដាញ"</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"ឲ្យ​កម្មវិធី​កែ​ប្រវត្តិ​កម្មវិធី​អ៊ីនធឺណិត ឬ​ចំណាំ​ដែល​មាន​ក្នុង​កុំព្យូទ័រ​បន្ទះ​របស់​អ្នក។ វា​អាច​ឲ្យ​កម្មវិធី​លុប ឬ​កែ​​ទិន្នន័យ​កម្មវិធី​អ៊ីនធឺណិត។ ចំណាំ៖ សិទ្ធិ​នេះ​​អាច​កត់​សម្គាល់​ថា​ត្រូវ​បាន​អនុវត្ត​ដោយ​កម្មវិធី​អ៊ីនធឺណិត​ភាគី​ទី​បី ឬ​កម្មវិធី​ផ្សេង​ដែល​មាន​សមត្ថភាព​​រុករក​បណ្ដាញ។"</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_packageVerificationAgent" msgid="5568139100645829117">"ផ្ទៀងផ្ទាត់​កញ្ចប់"</string>
+    <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"ឲ្យ​កម្មវិធី​ផ្ទៀងផ្ទាត់​កញ្ចប់​ដែល​អាច​ដំឡើង​បាន។"</string>
+    <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"ចង​ទៅ​កម្មវិធី​ផ្ទៀងផ្ទាត់​កញ្ចប់"</string>
+    <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"ឲ្យ​ម្ចាស់​ស្នើ​កម្មវិធី​ផ្ទៀងផ្ទាត់​កញ្ចប់។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_serialPort" msgid="546083327654631076">"ចូល​ដំណើរការ​ច្រក​ស៊េរី"</string>
+    <string name="permdesc_serialPort" msgid="2991639985224598193">"អនុញ្ញាត​ឱ្យ​ចូល​ដំណើរ​ការ​ទៅ​កាន់​ច្រក​សៀរៀល​ដោយ​ប្រើ SerialManager API ។"</string>
+    <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"ចូល​ដំណើរការ​ក្រុមហ៊ុន​ផ្ដល់​មាតិកា​ខាង​ក្រៅ"</string>
+    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"ឲ្យ​ម្ចាស់​ចូល​ដំណើរការ​ក្រុមហ៊ុន​ផ្ដល់​មាតិកា​ពី​សែល។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_updateLock" msgid="3527558366616680889">"ការ​ពារ​បច្ចុប្បន្នភាព​ឧបករណ៍​ស្វ័យ​ប្រវត្តិ"</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"ឲ្យ​ម្ចាស់​ផ្ដល់​ព័ត៌មាន​ទៅ​ប្រព័ន្ធ​អំពី​ពេលវេលា​ដែល​ល្អ​សម្រាប់​ចាប់ផ្ដើម​ឡើងវិញ​ដោយ​គ្មាន​អន្តរកម្ម ដើម្បី​ធ្វើ​បច្ចុប្បន្ន​ឧបករណ៍។"</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>
+    <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="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="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="oneMonthDurationPast" msgid="7396384508953779925">"1 ខែ​មុន"</string>
+    <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"មុន​ពេល ១ ខែ​មុន"</string>
+  <plurals name="num_seconds_ago">
+    <item quantity="one" msgid="4869870056547896011">"១ វិនាទី​មុន"</item>
+    <item quantity="other" msgid="3903706804349556379">"<xliff:g id="COUNT">%d</xliff:g> វិនាទី​មុន"</item>
+  </plurals>
+  <plurals name="num_minutes_ago">
+    <item quantity="one" msgid="3306787433088810191">"១ នាទី​មុន"</item>
+    <item quantity="other" msgid="2176942008915455116">"<xliff:g id="COUNT">%d</xliff:g> នាទី​​មុន"</item>
+  </plurals>
+  <plurals name="num_hours_ago">
+    <item quantity="one" msgid="9150797944610821849">"១ ម៉ោង​មុន"</item>
+    <item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> ម៉ោង​មុន"</item>
+  </plurals>
+  <plurals name="last_num_days">
+    <item quantity="other" msgid="3069992808164318268">"<xliff:g id="COUNT">%d</xliff:g> ថ្ងៃ​ចុងក្រោយ"</item>
+  </plurals>
+    <string name="last_month" msgid="3959346739979055432">"ខែ​មុន"</string>
+    <string name="older" msgid="5211975022815554840">"ចាស់​ជាង"</string>
+  <plurals name="num_days_ago">
+    <item quantity="one" msgid="861358534398115820">"ម្សិលមិញ"</item>
+    <item quantity="other" msgid="2479586466153314633">"<xliff:g id="COUNT">%d</xliff:g> ថ្ងៃ​មុន"</item>
+  </plurals>
+  <plurals name="in_num_seconds">
+    <item quantity="one" msgid="2729745560954905102">"ក្នុង​រយៈ​ពេល ១ វិនាទី"</item>
+    <item quantity="other" msgid="1241926116443974687">"ក្នុង​រយៈ​ពេល <xliff:g id="COUNT">%d</xliff:g> វិនាទី"</item>
+  </plurals>
+  <plurals name="in_num_minutes">
+    <item quantity="one" msgid="8793095251325200395">"ក្នុង​រយៈពេល ១ នាទី"</item>
+    <item quantity="other" msgid="3330713936399448749">"រយៈពេល <xliff:g id="COUNT">%d</xliff:g> នាទី"</item>
+  </plurals>
+  <plurals name="in_num_hours">
+    <item quantity="one" msgid="7164353342477769999">"រយៈពេល ១ ម៉ោង"</item>
+    <item quantity="other" msgid="547290677353727389">"រយៈពេល <xliff:g id="COUNT">%d</xliff:g> ម៉ោង"</item>
+  </plurals>
+  <plurals name="in_num_days">
+    <item quantity="one" msgid="5413088743009839518">"ថ្ងៃស្អែក"</item>
+    <item quantity="other" msgid="5109449375100953247">"រយៈពេល <xliff:g id="COUNT">%d</xliff:g> ថ្ងៃ"</item>
+  </plurals>
+  <plurals name="abbrev_num_seconds_ago">
+    <item quantity="one" msgid="1849036840200069118">"១ វិនាទី​មុន"</item>
+    <item quantity="other" msgid="3699169366650930415">"<xliff:g id="COUNT">%d</xliff:g> វិនាទី​មុន"</item>
+  </plurals>
+  <plurals name="abbrev_num_minutes_ago">
+    <item quantity="one" msgid="6361490147113871545">"១ នាទី​មុន"</item>
+    <item quantity="other" msgid="851164968597150710">"<xliff:g id="COUNT">%d</xliff:g> នាទី​​មុន"</item>
+  </plurals>
+  <plurals name="abbrev_num_hours_ago">
+    <item quantity="one" msgid="4796212039724722116">"១ ម៉ោង​មុន"</item>
+    <item quantity="other" msgid="6889970745748538901">"<xliff:g id="COUNT">%d</xliff:g> ម៉ោង​មុន"</item>
+  </plurals>
+  <plurals name="abbrev_num_days_ago">
+    <item quantity="one" msgid="8463161711492680309">"ម្សិលមិញ"</item>
+    <item quantity="other" msgid="3453342639616481191">"<xliff:g id="COUNT">%d</xliff:g> ថ្ងៃ​​មុន"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_seconds">
+    <item quantity="one" msgid="5842225370795066299">"ក្នុង​ពេល​ 1 វិនាទី"</item>
+    <item quantity="other" msgid="5495880108825805108">"ក្នុង​ពេល <xliff:g id="COUNT">%d</xliff:g> វិនាទី"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_minutes">
+    <item quantity="one" msgid="562786149928284878">"ក្នុង​ពេល 1 នាទី"</item>
+    <item quantity="other" msgid="4216113292706568726">"នៅ​រយៈពេល <xliff:g id="COUNT">%d</xliff:g> នាទី"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_hours">
+    <item quantity="one" msgid="3274708118124045246">"ក្នុង​រយៈ​ពេល ១ ម៉ោង"</item>
+    <item quantity="other" msgid="3705373766798013406">"ក្នុង​រយៈ​ពេល <xliff:g id="COUNT">%d</xliff:g> ម៉ោង"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_days">
+    <item quantity="one" msgid="2178576254385739855">"ថ្ងៃស្អែក"</item>
+    <item quantity="other" msgid="2973062968038355991">"ក្នុង​រយៈ​ពេល <xliff:g id="COUNT">%d</xliff:g> ថ្ងៃ"</item>
+  </plurals>
+    <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>
+    <string name="days" msgid="4774547661021344602">"​ថ្ងៃ"</string>
+    <string name="hour" msgid="2126771916426189481">"ម៉ោង"</string>
+    <string name="hours" msgid="894424005266852993">"ម៉ោង"</string>
+    <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="week" msgid="5617961537173061583">"សប្ដាហ៍"</string>
+    <string name="weeks" msgid="6509623834583944518">"សប្ដាហ៍"</string>
+    <string name="year" msgid="4001118221013892076">"ឆ្នាំ"</string>
+    <string name="years" msgid="6881577717993213522">"ឆ្នាំ"</string>
+  <plurals name="duration_seconds">
+    <item quantity="one" msgid="6962015528372969481">"1 វិនាទី"</item>
+    <item quantity="other" msgid="1886107766577166786">"<xliff:g id="COUNT">%d</xliff:g> វិនាទី"</item>
+  </plurals>
+  <plurals name="duration_minutes">
+    <item quantity="one" msgid="4915414002546085617">"១ នាទី"</item>
+    <item quantity="other" msgid="3165187169224908775">"<xliff:g id="COUNT">%d</xliff:g> នាទី"</item>
+  </plurals>
+  <plurals name="duration_hours">
+    <item quantity="one" msgid="8917467491248809972">"១ ម៉ោង"</item>
+    <item quantity="other" msgid="3863962854246773930">"<xliff:g id="COUNT">%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_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>
+    <string name="midnight" msgid="7166259508850457595">"កណ្ដាលអធ្រាត្រ"</string>
+    <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="cut" msgid="3092569408438626261">"កាត់"</string>
+    <string name="copy" msgid="2681946229533511987">"ចម្លង"</string>
+    <string name="paste" msgid="5629880836805036433">"បិទ​ភ្ជាប់"</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="textSelectionCABTitle" msgid="5236850394370820357">"ការ​ជ្រើស​អត្ថបទ"</string>
+    <string name="addToDictionary" msgid="4352161534510057874">"បន្ថែម​ទៅ​វចនានុក្រម"</string>
+    <string name="deleteText" msgid="6979668428458199034">"លុប"</string>
+    <string name="inputMethod" msgid="1653630062304567879">"វិធីសាស្ត្រ​បញ្ចូល"</string>
+    <string name="editTextMenuTitle" msgid="4909135564941815494">"សកម្មភាព​អត្ថបទ"</string>
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"អស់​ទំហំ​ផ្ទុក"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"មុខងារ​ប្រព័ន្ធ​មួយ​ចំនួន​អាច​មិន​ដំណើរការ"</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="4653586947747330058">"ប៉ះ​ ដើម្បី​មើល​ព័ត៌មាន​បន្ថែម ឬ​បញ្ឈប់​កម្មវិធី។"</string>
+    <string name="ok" msgid="5970060430562524910">"យល់​ព្រម"</string>
+    <string name="cancel" msgid="6442560571259935130">"បោះ​បង់"</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>
+    <string name="capital_on" msgid="1544682755514494298">"បើក"</string>
+    <string name="capital_off" msgid="6815870386972805832">"បិទ"</string>
+    <string name="whichApplication" msgid="4533185947064773386">"បញ្ចប់​សកម្មភាព​ដោយ​ប្រើ"</string>
+    <string name="alwaysUse" msgid="4583018368000610438">"ប្រើ​តាម​លំនាំដើម​សម្រាប់​សកម្មភាព​នេះ។"</string>
+    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"សម្អាត​លំនាំដើម​ក្នុង​ការកំណត់​ប្រព័ន្ធ &gt; កម្មវិធី &gt; ទាញ​យក។"</string>
+    <string name="chooseActivity" msgid="7486876147751803333">"ជ្រើស​សកម្មភាព"</string>
+    <string name="chooseUsbActivity" msgid="6894748416073583509">"ជ្រើស​កម្មវិធី​សម្រាប់​ឧបករណ៍​យូអេសប៊ី"</string>
+    <string name="noApplications" msgid="2991814273936504689">"គ្មាន​កម្មវិធី​អាច​អនុវត្ត​សកម្មភាព​នេះ។"</string>
+    <string name="aerr_title" msgid="1905800560317137752"></string>
+    <string name="aerr_application" msgid="932628488013092776">"ដោយ​បរាជ័យ <xliff:g id="APPLICATION">%1$s</xliff:g> បាន​បញ្ឈប់។"</string>
+    <string name="aerr_process" msgid="4507058997035697579">"ជា​អកុសល ដំណើរការ <xliff:g id="PROCESS">%1$s</xliff:g> បាន​បញ្ឈប់។"</string>
+    <string name="anr_title" msgid="4351948481459135709"></string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> មិន​ឆ្លើយតប។\n\nតើ​អ្នក​ចង់​បិទ​វា​ឬ?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"សកម្មភាព <xliff:g id="ACTIVITY">%1$s</xliff:g> មិន​ឆ្លើយតប។\n\nតើ​អ្នក​ចង់​បិទ​វា?"</string>
+    <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> មិន​ឆ្លើយតប។ តើ​អ្នក​ចង់​បិទ​វា?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"ដំណើរការ <xliff:g id="PROCESS">%1$s</xliff:g> មិន​ឆ្លើយតប។ \n\nតើ​អ្នក​ចង់​បិទ​វា​ឬ?"</string>
+    <string name="force_close" msgid="8346072094521265605">"យល់​ព្រម"</string>
+    <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_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; កម្មវិធី &gt; ទាញ​យក។"</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_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_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="1721681741617898865">"ប៉ះ​ ដើម្បី​ប្ដូរ​​​កម្មវិធី"</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>
+    <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="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_silent_ringtone_selected" msgid="8310739960973156272">"កំណត់​សំឡេង​រោទ៍​ស្ងាត់"</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">"កម្រិត​សំឡេង​ប៊្លូធូស"</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="8129563480895990372">"សំឡេង​រោទ៍​លំនាំដើម (<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_unknown" msgid="5477919988701784788">"សំឡេង​រោទ៍​មិន​ស្គាល់"</string>
+  <plurals name="wifi_available">
+    <item quantity="one" msgid="6654123987418168693">"មាន​បណ្ដាញ​វ៉ាយហ្វាយ"</item>
+    <item quantity="other" msgid="4192424489168397386">"មាន​បណ្ដាញ​វ៉ាយហ្វាយ"</item>
+  </plurals>
+  <plurals name="wifi_available_detailed">
+    <item quantity="one" msgid="1634101450343277345">"បើក​បណ្ដាញ​វ៉ាយហ្វាយ​​ដែល​មាន"</item>
+    <item quantity="other" msgid="7915895323644292768">"មាន​បណ្ដាញ​វ៉ាយហ្វាយ​បើក"</item>
+  </plurals>
+    <string name="wifi_available_sign_in" msgid="4029489716605255386">"ចូល​បណ្ដាញ​វ៉ាយហ្វាយ"</string>
+    <string name="network_available_sign_in" msgid="8495155593358054676">"ចូល​ក្នុង​បណ្ដាញ"</string>
+    <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
+    <skip />
+    <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"មិន​​អាច​តភ្ជាប់​វ៉ាយហ្វាយ"</string>
+    <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" មាន​ការ​តភ្ជាប់​អ៊ីនធឺណិត​មិន​ល្អ។"</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="1638949953993894335">"ប៉ះ​ ដើម្បី​កំណត់"</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_to_connect_title" msgid="4958803948658533637">"អញ្ជើញ​ឲ្យ​ភ្ជាប់"</string>
+    <string name="wifi_p2p_from_message" msgid="570389174731951769">"ពី៖"</string>
+    <string name="wifi_p2p_to_message" msgid="248968974522044099">"ទៅ៖"</string>
+    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"បញ្ចូល​កូដ PIN ដែល​ទាមទារ៖"</string>
+    <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"កូដ PIN ៖"</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="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="3492025719868078457"><font fgcolor="#ffffb060">"នេះ​អាច​កាត់​លុយ"</font>" លើ​គណនី​ចល័ត​របស់​អ្នក។"</string>
+    <string name="sms_premium_short_code_details" msgid="5523826349105123687"><font fgcolor="#ffffb060">"វា​នឹង​គិត​ថ្លៃ​សេវាកម្ម​លើ​គណនី​ចល័ត​របស់​អ្នក។"</font></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_confirm_always_allow" msgid="3241181154869493368">"អនុញ្ញាត​ជា​និច្ច"</string>
+    <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"កុំ​អនុញ្ញាត"</string>
+    <string name="sim_removed_title" msgid="6227712319223226185">"បាន​ដក​ស៊ីម​កាត​ចេញ"</string>
+    <string name="sim_removed_message" msgid="2333164559970958645">"បណ្ដាញ​ចល័ត​នឹង​ប្រើ​លែង​បាន​រហូត​ដល់​អ្នក​ចាប់ផ្ដើម​ជា​មួយ​ស៊ីម​កាត​ដែល​បា​បញ្ចូល​ត្រឹមត្រូវ។"</string>
+    <string name="sim_done_button" msgid="827949989369963775">"រួចរាល់"</string>
+    <string name="sim_added_title" msgid="3719670512889674693">"បាន​បន្ថែម​ស៊ីម​កាត"</string>
+    <string name="sim_added_message" msgid="6599945301141050216">"ចាប់ផ្ដើម​ឧបករណ៍​របស់​អ្នក​ឡើង​វិញ ដើម្បី​ចូល​ដំណើរការ​បណ្ដាញ​ចល័ត។"</string>
+    <string name="sim_restart_button" msgid="4722407842815232347">"ចាប់ផ្ដើម​ឡើងវិញ"</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_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="usb_storage_activity_title" msgid="4465055157209648641">"ឧបករណ៍​យូអេសប៊ី"</string>
+    <string name="usb_storage_title" msgid="5901459041398751495">"បាន​ភ្ជាប់​យូអេសប៊ី"</string>
+    <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"អ្នក​បាន​ភ្ជាប់​កុំព្យូទ័រ​របស់​អ្នក​តាម​​យូអេសប៊ី។ ប៉ះ ប៊ូតុង​ខាង​ក្រោម បើ​អ្នក​ចង់​ចម្លង​ឯកសារ​រវាង​កុំព្យូទ័រ និង​ឧបករណ៍​ផ្ទុក Android របស់​អ្នក។"</string>
+    <string name="usb_storage_message" product="default" msgid="805351000446037811">"អ្នក​បាន​ភ្ជាប់​កុំព្យូទ័រ​របស់​អ្នក​តាម​យូអេសប៊ី។ ប៉ះ ប៊ូតុង​ខាង​ក្រោម​ប្រសិន​បើ​អ្នក​ចង់​ចម្លង​ឯកសារ​រវាង​កុំព្យូទ័រ​របស់​អ្នក និង​កាត​អេសឌី​នៃ Android របស់​អ្នក។"</string>
+    <string name="usb_storage_button_mount" msgid="1052259930369508235">"បើក​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី"</string>
+    <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"មាន​បញ្ហា​ក្នុង​ការ​ផ្អាក​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី​សម្រាប់​ជា​ឧបករណ៍​ផ្ទុក។"</string>
+    <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"មាន​បញ្ហា​ក្នុង​ការ​ប្រើ​កាត​អេសឌី​សម្រាប់​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី។"</string>
+    <string name="usb_storage_notification_title" msgid="8175892554757216525">"បាន​ភ្ជាប់​យូអេសប៊ី"</string>
+    <string name="usb_storage_notification_message" msgid="939822783828183763">"ប៉ះ ដើម្បី​ចម្លង​ឯកសារ​ទៅ/ពី​កុំព្យូទ័រ​របស់​​អ្នក។"</string>
+    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"បិទ​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី"</string>
+    <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"ប៉ះ ដើម្បី​បិទ​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី។"</string>
+    <string name="usb_storage_stop_title" msgid="660129851708775853">"ឧបករណ៍​ផ្ទុក​យូអេសប៊ី​កំពុង​ប្រើ"</string>
+    <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"មុន​ពេល​បិទ​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី ផ្ដាច់ (\"បដិសេធ\") ឧបករណ៍​ផ្ទុក​យូអេសប៊ី Android របស់​អ្នក​ពី​កុំព្យូទ័រ។"</string>
+    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"មុន​ពេល​បិទ​​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី ផ្ដាច់ (\"បដិសេធ\") កាត​អេសឌី Android របស់​អ្នក​ពី​កុំព្យូទ័រ។"</string>
+    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"បិទ​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី"</string>
+    <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"មាន​បញ្ហា​ក្នុង​ការ​បិទ​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី។ ពិនិត្យ​ថា​អ្នក​បាន​ផ្ដាច់​យូអេសប៊ី បន្ទាប់​មក​ព្យាយាម​ម្ដង​ទៀត។"</string>
+    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"បើក​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី"</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"បើ​អ្នក​បើក​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី កម្មវិធី​មួយ​ចំនួន​ដែល​អ្នក​កំពុង​ប្រើ​នឹង​បញ្ឈប់ ហើយ​អាច​ប្រើ​លែង​បាន​រហូត​ដល់​អ្នក​បិទ​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី។"</string>
+    <string name="dlg_error_title" msgid="7323658469626514207">"ប្រតិបត្តិការ​យូអេសប៊ី​​បរាជ័យ"</string>
+    <string name="dlg_ok" msgid="7376953167039865701">"យល់ព្រម"</string>
+    <string name="usb_mtp_notification_title" msgid="3699913097391550394">"បាន​តភ្ជាប់​ជា​ឧបករណ៍​​ផ្ទុក"</string>
+    <string name="usb_ptp_notification_title" msgid="1960817192216064833">"បាន​ភ្ជាប់​ជា​ម៉ាស៊ីន​ថត"</string>
+    <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"បាន​ភ្ជាប់​ជា​កម្មវិធី​ដំឡើង"</string>
+    <string name="usb_accessory_notification_title" msgid="7848236974087653666">"បាន​ភ្ជាប់​ឧបករណ៍​យូអេសប៊ី"</string>
+    <string name="usb_notification_message" msgid="2290859399983720271">"ប៉ះ ដើម្បី​មើល​ជម្រើស​យូអេសប៊ី​ផ្សេង។"</string>
+    <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"ធ្វើ​ទ្រង់ទ្រាយ​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី?"</string>
+    <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"ធ្វើ​ទ្រង់ទ្រាយ​កាត​អេសឌី?"</string>
+    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"ឯកសារ​ទាំងអស់​ដែល​បាន​រក្សាទុក​ក្នុង​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី​នឹង​ត្រូវ​បាន​លុប។ សកម្មភាព​នេះ​មិន​អាច​ត្រឡប់​វិញ​បាន​ទេ!"</string>
+    <string name="extmedia_format_message" product="default" msgid="14131895027543830">"ទិន្នន័យ​ទាំងអស់​ក្នុង​កាត​របស់​អ្នក​នឹង​បាត់បង់។"</string>
+    <string name="extmedia_format_button_format" msgid="4131064560127478695">"ធ្វើ​ទ្រង់ទ្រាយ"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"បាន​ភ្ជាប់​ការ​កែ​កំហុស​យូអេសប៊ី"</string>
+    <string name="adb_active_notification_message" msgid="1016654627626476142">"ប៉ះ ដើម្បី​បិទ​ការ​កែ​កំហុស​យូអេសប៊ី។"</string>
+    <string name="select_input_method" msgid="4653387336791222978">"ជ្រើស​វិធីសាស្ត្រ​បញ្ចូល"</string>
+    <string name="configure_input_methods" msgid="9091652157722495116">"រៀបចំ​វិធីសាស្ត្រ​បញ្ចូល"</string>
+    <string name="use_physical_keyboard" msgid="6203112478095117625">"ក្ដារ​ចុច​​ពិតប្រាកដ"</string>
+    <string name="hardware" msgid="7517821086888990278">"ផ្នែក​រឹង"</string>
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"ជ្រើស​ប្លង់​ក្ដារ​ចុច"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"ប៉ះ ​ដើម្បី​ជ្រើស​ប្លង់​​ក្ដារចុច។"</string>
+    <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="candidates_style" msgid="4333913089637062257"><u>"បេក្ខជន"</u></string>
+    <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"រៀបចំ​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី"</string>
+    <string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"រៀបចំ​កាត​អេសឌី"</string>
+    <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"ពិនិត្យ​រក​កំហុស។"</string>
+    <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"ឧបករណ៍​ផ្ទុក​យូអេសប៊ី​ទទេ"</string>
+    <string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"ការ​​អេសឌី​ទទេ"</string>
+    <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"ឧបករណ៍​ផ្ទុក​យូអេសប៊ី​ទទេ ឬ​មាន​ប្រព័ន្ធ​ឯកសារ​ដែល​មិន​បា​គាំទ្រ។"</string>
+    <string name="ext_media_nofs_notification_message" product="default" msgid="8641065641786923604">"កាត​អេសឌី​ទទេ ឬ​មាន​ប្រព័ន្ធ​ឯកសារ​មិន​បាន​គាំទ្រ។"</string>
+    <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"ឧបករណ៍​ផ្ទុក​យូអេសប៊ី​ខូច"</string>
+    <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"កាត​អេសឌី​ខូច"</string>
+    <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="1795917578395333280">"ឧបករណ៍​ផ្ទុក​យូអេសប៊ី​ខូច។ ព្យាយាម​ធ្វើ​ទ្រង់ទ្រាយ​វា​ឡើងវិញ។"</string>
+    <string name="ext_media_unmountable_notification_message" product="default" msgid="1753898567525568253">"កាត​អេសឌី​ខូច។ ព្យាយាម​ធ្វើ​ទ្រង់ទ្រាយ​វា​ឡើងវិញ។"</string>
+    <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"បាន​ដក​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី​ដោយ​មិន​រំពឹង​ទុក"</string>
+    <string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"បាន​ដក​កាត​អេសឌី​ដោយ​មិន​រំពឹង​ទុក"</string>
+    <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"ផ្ដាច់​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី​មុន​នឹង​​លុប​​​ជៀសវាង​ការ​បាត់​ទិន្នន័យ។"</string>
+    <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"ផ្ដាច់​កាត​អេសឌី​មុន​នឹង​ដក់​ចេញ ជៀសវាង​បាត់បង់​ទិន្នន័យ។"</string>
+    <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"ឧបករណ៍​យូអេសប៊ី​មាន​សុវត្ថិភាព ដើម្បី​ដក"</string>
+    <string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"មាន​សុវត្ថិភាព​ក្នុង​ការ​ដក​កាត​អេសឌី"</string>
+    <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"អ្នក​អាច​ដក​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី​ដោយ​សុវត្ថិភាព។"</string>
+    <string name="ext_media_safe_unmount_notification_message" product="default" msgid="568841278138377604">"អ្នក​អាច​ដក​កាត​អេសឌី​ដោយ​មាន​សុវត្ថិភាព។"</string>
+    <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"បាន​លុប​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី"</string>
+    <string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"បាន​ដក​កាត​អេសឌី"</string>
+    <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"បាន​ដក​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី។ បញ្ចូល​មេឌៀ​ថ្មី។"</string>
+    <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"បាន​ដក​កាត​អេសឌី។ បញ្ចូល​ថ្មី​មួយ។"</string>
+    <string name="activity_list_empty" msgid="1675388330786841066">"រក​មិន​ឃើញ​សកម្មភាព​ផ្គូផ្គង។"</string>
+    <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"ធ្វើ​បច្ចុប្បន្ន​សមាសធាតុ​ស្ថិតិ​ការ​ប្រើ"</string>
+    <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"ឲ្យ​កម្មវិធី​កែ​ស្ថិតិ​ប្រើ​សមាសភាគ​ដែល​បា​ន​ប្រមូល។​​ មិន​សម្រាប់​ប្រើ​ដោយ​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_copyProtectedData" msgid="4341036311211406692">"ចម្លង​មាតិកា"</string>
+    <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"ឲ្យ​កម្មវិធី​ដក​សេវាកម្ម​នៃ​កម្មវិធី​ផ្ទុក​​លំនាំដើម ដើម្បី​ចម្លង​មាតិកា។​ មិន​សម្រាប់​ប្រើ​ដោយ​កម្មវិធី​លំនាំដើម។"</string>
+    <string name="permlab_route_media_output" msgid="1642024455750414694">"នាំ​ផ្លូវ​លទ្ធផល​មេឌៀ"</string>
+    <string name="permdesc_route_media_output" msgid="4932818749547244346">"ឲ្យ​កម្មវិធី​នាំ​ផ្លូវ​លទ្ធផល​មេឌៀ​ទៅ​ឧបករណ៍​​ខាង​ក្រៅ​ផ្សេង។"</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"ចូល​ដំណើរការ​ឧបករណ៍​ផ្ទុក​សុវត្ថិភាព"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"ឲ្យ​កម្មវិធី​ចូល​​ការ​ផ្ទុក​មាន​សុវត្ថិភាព keguard ។"</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"ពិនិត្យ​ការ​បង្ហាញ និង​លាក់​ការ​ការពារ"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"ឲ្យ​កម្មវិធី​គ្រប់គ្រង keguard ។"</string>
+    <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"ប៉ះ​ពីរ​ដង ​​ដើម្បី​គ្រប់គ្រង​ការ​ពង្រីក"</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>
+    <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">"ចុច​លេខ​\nដោយ​ប្រើ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"បង្កើត​ទំនាក់ទំនង\nដោយ​ប្រើ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"កម្មវិធី​មួយ ឬ​ច្រើន​ដូច​ខាង​ក្រោម​ស្នើ​សិទ្ធិ ដើម្បី​ចូល​គណនី​របស់​អ្នក​ឥឡូវ និង​ពេល​អនាគត។"</string>
+    <string name="grant_credentials_permission_message_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">"បាន​ស្នើ​សិទ្ធិ\nសម្រាប់​គណនី <xliff:g id="ACCOUNT">%s</xliff:g> ។"</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>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"ប្ដូរ​ផ្ទាំង​រូបភាព"</string>
+    <string name="notification_listener_binding_label" msgid="2014162835481906429">"កម្មវិធី​ស្ដាប់​ការ​ជូន​ដំណឹង"</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="3011306607126450322">"ប៉ះ ដើម្បី​គ្រប់គ្រង​បណ្ដាញ។"</string>
+    <string name="vpn_text_long" msgid="6407351006249174473">"បាន​តភ្ជាប់​ទៅ <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_error" msgid="6009249814034708175">"បើក​កំហុស VPN ជា​និច្ច"</string>
+    <string name="vpn_lockdown_config" msgid="6415899150671537970">"ប៉ះ ​ដើម្បី​កំណត់​រចនា​សម្ព័ន្ធ"</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="8035230537563503262">"ប៉ះ​ ដើម្បី​ចេញ​ពី​របៀប​រថយន្ត​។"</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"​ភ្ជាប់ ឬ​ hotspot សកម្ម"</string>
+    <string name="tethered_notification_message" msgid="6857031760103062982">"ប៉ះ​ ដើម្បី​រៀបចំ។"</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="throttle_warning_notification_title" msgid="4890894267454867276">"ការ​ប្រើ​ទិន្នន័យ​ចល័ត​ខ្ពស់"</string>
+    <string name="throttle_warning_notification_message" msgid="3340822228599337743">"ប៉ះ​ ដើម្បី​​ស្វែងយល់​បន្ថែម​អំពី​ការ​ប្រើ​​​ទិន្នន័យ​ចល័ត​។"</string>
+    <string name="throttled_notification_title" msgid="6269541897729781332">"លើក​ដែន​កំណត់​ទិន្នន័យ​ចល័ត"</string>
+    <string name="throttled_notification_message" msgid="5443457321354907181">"ប៉ះ ដើម្បី​ស្វែងយល់​បន្ថែម​អំពី​ការ​ប្រើ​ទិន្នន័យ​ចល័ត។"</string>
+    <string name="no_matches" msgid="8129421908915840737">"គ្មាន​ការ​ផ្គូផ្គង"</string>
+    <string name="find_on_page" msgid="1946799233822820384">"រក​ក្នុង​ទំព័រ"</string>
+  <plurals name="matches_found">
+    <item quantity="one" msgid="8167147081136579439">"១ ប្រកួត"</item>
+    <item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> នៃ <xliff:g id="TOTAL">%d</xliff:g>"</item>
+  </plurals>
+    <string name="action_mode_done" msgid="7217581640461922289">"រួចរាល់"</string>
+    <string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"កំពុង​ផ្ដាច់​ឧបករណ៍​យូអេសប៊ី..."</string>
+    <string name="progress_unmounting" product="default" msgid="1327894998409537190">"កំពុង​ផ្ដាច់​កាត​អេសឌី..."</string>
+    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"កំពុង​លុប​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី..."</string>
+    <string name="progress_erasing" product="default" msgid="6596988875507043042">"កំពុង​លុប​កាត​អេសឌី..."</string>
+    <string name="format_error" product="nosdcard" msgid="6299769563624776948">"មិន​​អាច​លុប​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី។"</string>
+    <string name="format_error" product="default" msgid="7315248696644510935">"មិន​អាច​លុប​កាត​អេសឌី។"</string>
+    <string name="media_bad_removal" msgid="7960864061016603281">"បាន​ដក​កាត​អេសឌី​មុន​នឹង​ផ្ដាច់។"</string>
+    <string name="media_checking" product="nosdcard" msgid="418188720009569693">"បច្ចុប្បន្ន​កំពុង​ពិនិត្យ​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី។"</string>
+    <string name="media_checking" product="default" msgid="7334762503904827481">"បច្ចុប្បន្ន​កំពុង​ពិនិត្យ​មើល​កាត​អេសឌី។"</string>
+    <string name="media_removed" msgid="7001526905057952097">"បាន​ដក​កាត​អេសឌី។"</string>
+    <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"ឧបករណ៍​ផ្ទុក​យូអេសប៊ី​បច្ចុប្បន្ន​កំពុង​ប្រើ​ដោយ​កុំព្យូទ័រ។"</string>
+    <string name="media_shared" product="default" msgid="5706130568133540435">"បច្ចុប្បន្ន​កាត​អេសឌី​កំពុង​ប្រើ​ដោយ​កុំព្យូទ័រ"</string>
+    <string name="media_unknown_state" msgid="729192782197290385">"មិន​ស្គាល់​ស្ថានភាព​មេឌៀ​ខាង​ក្រៅ។"</string>
+    <string name="share" msgid="1778686618230011964">"ចែក​រំលែក"</string>
+    <string name="find" msgid="4808270900322985960">"រក"</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="gpsNotifMessage" msgid="1374718023224000702">"បាន​ស្នើ​ដោយ <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+    <string name="gpsVerifYes" msgid="2346566072867213563">"បាទ/ចាស"</string>
+    <string name="gpsVerifNo" msgid="1146564937346454865">"ទេ"</string>
+    <string name="sync_too_many_deletes" msgid="5296321850662746890">"លុប​​លើស​ដែន​កំណត់"</string>
+    <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"មាន​ធាតុ​បាន​លុប <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> សម្រាប់ <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> គណនី <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> ។ តើ​អ្នក​ចង់​ធ្វើ​អ្វី​ខ្លះ​?"</string>
+    <string name="sync_really_delete" msgid="2572600103122596243">"លុប​ធាតុ"</string>
+    <string name="sync_undo_deletes" msgid="2941317360600338602">"មិន​ធ្វើ​ការ​លុប​វិញ"</string>
+    <string name="sync_do_nothing" msgid="3743764740430821845">"មិន​ធ្វើអ្វី​ទេ​ឥឡូវ"</string>
+    <string name="choose_account_label" msgid="5655203089746423927">"ជ្រើស​គណនី"</string>
+    <string name="add_account_label" msgid="2935267344849993553">"បន្ថែម​គណនី​ថ្មី"</string>
+    <string name="add_account_button_label" msgid="3611982894853435874">"បន្ថែម​គណនី"</string>
+    <string name="number_picker_increment_button" msgid="2412072272832284313">"បង្កើន"</string>
+    <string name="number_picker_decrement_button" msgid="476050778386779067">"បន្ថយ"</string>
+    <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> ប៉ះ និង​សង្កត់។"</string>
+    <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"រុញ​ឡើងលើ ដើម្បី​បង្កើន និង​ចុះក្រោម​ដើម្បី​បន្ថយ។"</string>
+    <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"បង្កើន​នាទី"</string>
+    <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"បន្ថយ​នាទី"</string>
+    <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"បង្កើន​ម៉ោង"</string>
+    <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"បន្ថយ​ម៉ោង"</string>
+    <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"កំណត់​ PM"</string>
+    <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"កំណត់ AM"</string>
+    <string name="date_picker_increment_month_button" msgid="5369998479067934110">"បង្កើន​ខែ"</string>
+    <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"បន្ថយ​ខែ"</string>
+    <string name="date_picker_increment_day_button" msgid="7130465412308173903">"បង្កើន​ថ្ងៃ"</string>
+    <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"បន្ថយ​ថ្ងៃ"</string>
+    <string name="date_picker_increment_year_button" msgid="6318697384310808899">"បង្កើន​​ឆ្នាំ"</string>
+    <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"បន្ថយ​ឆ្នាំ"</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_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"ជ្រើស​កម្មវិធី"</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_direction_up" msgid="7169032478259485180">"រុញ​ឡើង​លើ​ដើម្បី <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"រុញ​ចុះក្រោម​សម្រាប់ <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="description_direction_right" msgid="8034433242579600980">"រុញ​​ទៅ​ស្ដាំ​ដើម្បី <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"ដោះ​​សោ"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"ម៉ាស៊ីន​ថត"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"ស្ងាត់"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"បើក​សំឡេង"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"ស្វែងរក"</string>
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"អូស​ ដើម្បី​ដោះ​សោ។"</string>
+    <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"ដោត​កាស​ដើម្បី​ស្ដាប់​ពាក្យ​សម្ងាត់​បាន​និយាយ។"</string>
+    <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Dot."</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="4891916833657929263">"ឧបករណ៍​ផ្ទុក​ខាង​ក្នុង"</string>
+    <string name="storage_sd_card" msgid="3282948861378286745">"កាត​អេសឌី"</string>
+    <string name="storage_usb" msgid="3017954059538517278">"ឧបករណ៍​ផ្ទុក​យូអេសប៊ី"</string>
+    <string name="extract_edit_menu_button" msgid="8940478730496610137">"កែសម្រួល"</string>
+    <string name="data_usage_warning_title" msgid="1955638862122232342">"ការព្រមាន​ប្រើ​ទិន្នន័យ"</string>
+    <string name="data_usage_warning_body" msgid="2814673551471969954">"ប៉ះ ដើម្បី​មើល​ការ​ប្រើ និង​ការ​កំណត់។"</string>
+    <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"បាន​បិទ​ទិន្នន័យ 2G​-3G"</string>
+    <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"បាន​បិទ​ទិន្នន័យ 4G"</string>
+    <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"បាន​បិទ​ទិន្នន័យ​ចល័ត"</string>
+    <string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"បាន​បិទ​ទិន្នន័យ​វ៉ាយហ្វាយ"</string>
+    <string name="data_usage_limit_body" msgid="3317964706973601386">"ប៉ះ​​ ដើម្បី​បើក​។"</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="6741521330997452990">"ប៉ះ ដើម្បី​លុប​ការ​ដាក់កម្រិត។"</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>
+    <string name="org_unit" msgid="7265981890422070383">"ផ្នែក​នៃ​ស្ថាប័ន៖"</string>
+    <string name="issued_by" msgid="2647584988057481566">"បាន​ចេញ​ដោយ​៖"</string>
+    <string name="validity_period" msgid="8818886137545983110">"សុពលភាព៖"</string>
+    <string name="issued_on" msgid="5895017404361397232">"ចេញ​នៅ៖"</string>
+    <string name="expires_on" msgid="3676242949915959821">"ផុត​កំណត់​នៅ៖"</string>
+    <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>
+    <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"មើល​ទាំងអស់"</string>
+    <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"ជ្រើស​សកម្មភាព"</string>
+    <string name="share_action_provider_share_with" msgid="5247684435979149216">"ចែករំលែក​ជា​មួយ"</string>
+    <string name="status_bar_device_locked" msgid="3092703448690669768">"ឧបករណ៍​ជាប់​សោ​។"</string>
+    <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="3245653681008218030">"កំពុង​ផ្ញើ..."</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="default_audio_route_name" product="tablet" msgid="4617053898167127471">"កុំព្យូទ័រ​បន្ទះ"</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">"សំឡេង​ប៊្លូធូស"</string>
+    <string name="wireless_display_route_description" msgid="9070346425023979651">"បង្ហាញ​បណ្ដាញ​ឥត​ខ្សែ"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"រួចរាល់"</string>
+    <string name="media_route_button_content_description" msgid="5758553567065145276">"លទ្ធផល​មេឌៀ"</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>
+    <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_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="wifi_display_notification_title" msgid="2223050649240326557">"បាន​ភ្ជាប់​ការ​បង្ហាញ​បណ្ដាញ​ឥត​ខ្សែ"</string>
+    <string name="wifi_display_notification_message" msgid="4498802012464170685">"អេក្រង់​នេះ​បង្ហាញ​លើ​ឧបករណ៍​ផ្សេង"</string>
+    <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"ផ្ដាច់"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"ការ​ហៅ​ពេល​អាសន្ន"</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">"កូដ PIN មិន​ត្រឹមត្រូវ"</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 ស៊ីម​កាត"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"បញ្ចូល​​កូដ PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"បញ្ចូល​ពាក្យ​សម្ងាត់"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"ឥឡូវ​ស៊ីមកាត​ត្រូវ​បាន​បិទ។ បញ្ចូល​កូដ PUK ដើម្បី​បន្ត។ ចំពោះ​ព័ត៌មាន​លម្អិត​ទាក់ទង​ក្រុមហ៊ុន​បញ្ជូន​របស់​អ្នក។"</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"បញ្ចូល​កូដ PIN ដែល​ចង់​បាន"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"បញ្ជាក់​កូដ PIN ដែល​ចង់​បាន"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"កំពុង​ដោះ​សោ​​ស៊ីម​កាត..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"កូដ PIN មិន​ត្រឹមត្រូវ។"</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"បញ្ចូល​កូដ PIN ដែល​មាន​ពី ៤ ដល់ ៨ លេខ។"</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"កូដ PUK គួរ​តែ​មាន​​ ៨ លេខ ឬ​​ច្រើន​ជាង​នេះ។"</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"បញ្ចូល​កូដ PUK ម្ដង​ទៀត។ ការ​ព្យាយាម​ដដែល​ច្រើន​ដឹង​នឹង​បិទ​ស៊ីម​កាត​ជា​អចិន្ត្រៃយ៍។"</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"កូដ PIN មិន​ដូច​គ្នា"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ព្យាយាម​លំនាំ​ច្រើន​ពេក"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"ដើម្បី​ដោះ​សោ ចូល​ក្នុង​គណនី Google ។"</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"កំពុង​ពិនិត្យ​មើល​គណនី..."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"អ្នក​បាន​បញ្ចូល​កូដ PIN របស់​អ្នក​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។\n\n ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_1">%d</xliff:g> វិនាទី។"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"អ្នក​បាន​បញ្ចូល​ពាក្យ​សម្ងាត់​មិន​ត្រឹមត្រូវ <xliff:g id="NUMBER_0">%d</xliff:g> ដង។\n\nព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_1">%d</xliff:g> វិនាទី។"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"អ្នក​បាន​​គូរ​លំនាំ​ដោះ​សោ​របស់​អ្នក​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។\n\nព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_1">%d</xliff:g> វិនាទី។"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"អ្នក​បាន​ព្យាយាម​ដោះ​សោ​​កុំព្យូទ័រ​បន្ទះ​​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម​មិន​ជោគជ័យ​​ច្រើន​ជាង <xliff:g id="NUMBER_1">%d</xliff:g> ដង កុំព្យូទ័រ​បន្ទះ​​នឹង​ត្រូវ​បាន​កំណត់​ទៅ​លំនាំដើម​ដូច​ចេញ​ពី​រោងចក្រ ហើយ​ទិន្នន័យ​អ្នកប្រើ​នឹង​បាត់បង់។"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"អ្នក​បាន​ព្យាយាម​ដោះ​សោ​ទូរស័ព្ទ​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម​មិន​ជោគជ័យ​​ច្រើន​ជាង <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម <xliff:g id="NUMBER_1">%d</xliff:g> ដង​មិន​ជោគជ័យ អ្នក​នឹង​ត្រូវ​បាន​ស្នើ​ឲ្យ​ដោះ​សោ​កុំព្យូទ័រ​បន្ទះ​របស់​អ្នក ដោយ​ប្រើ​គណនី​អ៊ីមែល។\n\n ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_2">%d</xliff:g> វិនាទី។"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"អ្នក​បាន​គូរ​លំនាំ​ដោះ​​សោ​របស់​អ្នក​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម​មិន​ជោគជ័យ​​ច្រើនជាង <xliff:g id="NUMBER_1">%d</xliff:g> ដង អ្នក​នឹង​ត្រូវ​បាន​​ស្នើ​ឲ្យ​ដោះ​សោ​ទូរស័ព្ទ​របស់​អ្នក​ដោយ​ប្រើ​គណនី​អ៊ីមែល។\n\n ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_2">%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="7324161939475478066">"បង្កើន​កម្រិត​សំឡេង​ខាង​លើ​កម្រិត​បាន​​ណែនាំ?\nស្ដាប់​កម្រិត​សំឡេង​ខ្ពស់​រយៈ​ពេល​យូរ​អាច​ឲ្យ​ខូច​ត្រចៀក។"</string>
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"សង្កត់​ដោយ​ម្រាមដៃ​ពីរ ដើម្បី​បើក​ភាព​ងាយស្រួល។"</string>
+    <string name="accessibility_enabled" msgid="1381972048564547685">"បាន​បើក​មធ្យោបាយ​ងាយស្រួល​។"</string>
+    <string name="enable_accessibility_canceled" msgid="3833923257966635673">"បាន​បោះបង់​ភាព​ងាយស្រួល។"</string>
+    <string name="user_switched" msgid="3768006783166984410">"អ្នក​ប្រើ​បច្ចុប្បន្ន <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="app_no_restricted_accounts" msgid="5739463249673727736">"កម្មវិធី​នេះ​មិន​គាំទ្រ​គណនី​សម្រាប់​ប្រវត្តិរូប​ដែល​បាន​ដាក់​កម្រិត​ទេ"</string>
+    <string name="app_not_found" msgid="3429141853498927379">"រក​មិន​ឃើញ​កម្មវិធី​ ដើម្បី​គ្រប់គ្រង​សកម្មភាព​នេះ"</string>
+    <string name="revoke" msgid="5404479185228271586">"ដកហូត"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"លិខិត​រដ្ឋាភិបាល"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"បាន​បោះ​បង់"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"កំហុស​ក្នុង​ការ​សរសេរ​មាតិកា"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"បញ្ចូល​​កូដ PIN"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"កូដ PIN បច្ចុប្បន្ន"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"កូដ PIN ថ្មី"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"បញ្ជាក់​កូដ PIN ថ្មី"</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_too_short" msgid="8173982756265777792">"កូដ​ PIN ខ្លី​ពេក។ ត្រូវ​តែ​មាន​យ៉ាង​ហោច​ណាស់ ៤ តួ។"</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="4835639969503729874">"លេខ​កូដ​ PIN មិន​ត្រឹមត្រូវ។ ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល ១ វិនាទី។"</item>
+    <item quantity="other" msgid="8030607343223287654">"លេខ​កូដ​ PIN មិន​ត្រឹមត្រូវ។ ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="COUNT">%d</xliff:g> វិនាទី​។"</item>
+  </plurals>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"អូស​គែម​អេក្រង់ ដើម្បី​បង្ហាញ​របារ"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"អូស​ពី​គែម​អេក្រង់ ដើម្បី​បង្ហាញ​របារ​ប្រព័ន្ធ"</string>
+</resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 73cdb1c..21e343f 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -131,6 +131,11 @@
     <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="default" msgid="3475999286680000541">"휴대전화 저장공간이 꽉 찼습니다. 일부 파일을 삭제하여 저장공간을 늘리세요."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"네트워크가 모니터링될 수 있음"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"나"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"태블릿 옵션"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"휴대전화 옵션"</string>
@@ -229,7 +234,7 @@
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"SD 카드에 액세스합니다."</string>
     <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"접근성 기능"</string>
     <string name="permgroupdesc_accessibilityFeatures" msgid="4205196881678144335">"장애인 보조 기술이 요청할 수 있는 기능입니다."</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="5800552516779249356">"항목을 터치하면 소리 내어 알려주며 제스처를 사용하여 화면을 탐색할 수 있습니다."</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"앱이 사용자의 입력 없이 작업을 포그라운드나 백그라운드로 이동할 수 있도록 허용합니다."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"실행 중인 앱 중지"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"애플리케이션이 작업을 삭제하거나 다른 애플리케이션을 중지시킬 수 있도록 허용합니다. 이 경우 악성 애플리케이션이 다른 애플리케이션의 동작을 멈추게 할 수 있습니다."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"작업 스택 관리"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"앱이 다른 앱에서 실행하는 작업 스택을 추가, 삭제 또는 수정하도록 합니다. 악성 앱은 다른 앱의 동작을 방해할 수 있습니다."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"원하는 활동 시작"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"권한 보호나 내보낸 상태에 관계없이 앱이 활동을 시작하도록 합니다."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"화면 호환성 설정"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"권한을 가진 프로그램이 입력 방법에 대한 최상위 인터페이스를 사용하도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"접근성 서비스와 연결"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"권한을 가진 프로그램이 접근성 서비스에 대한 최상위 인터페이스를 사용하도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"인쇄 서비스 사용"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"권한을 가진 프로그램이 인쇄 서비스에 대한 최상위 인터페이스를 사용하도록 합니다. 일반 앱에는 필요하지 않습니다."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"인쇄 스풀러 서비스 사용"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"권한을 가진 프로그램이 인쇄 스풀러 서비스에 대한 최상위 인터페이스를 사용하도록 합니다. 일반 앱에는 필요하지 않습니다."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC 서비스 사용"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"권한을 가진 프로그램이 NFC 카드를 에뮬레이션하는 애플리케이션을 사용하도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"텍스트 서비스 연결"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"권한을 가진 프로그램이 텍스트 서비스(예: SpellCheckerService)에 대한 최상위 인터페이스를 사용하도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"VPN 서비스와 연결"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"권한을 가진 프로그램이 위젯 서비스에 대한 최상위 인터페이스를 사용하도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"기기 관리자와 상호 작용"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"권한을 가진 프로그램이 기기 관리자에게 인텐트를 보낼 수 있도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"기기 관리자 추가 또는 삭제"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"권한을 가진 프로그램이 활성화된 기기의 관리자를 추가 또는 삭제하도록 합니다. 일반 앱에는 필요하지 않습니다."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"화면 방향 변경"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"앱이 언제든지 화면 회전을 변경할 수 있도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"포인터 속도 변경"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"앱이 시스템의 다양한 로그 파일을 읽을 수 있도록 허용합니다. 이렇게 되면 앱이 개인정보 또는 비공개 정보를 포함하여 휴대전화로 수행하는 작업에 대한 일반적인 정보를 검색할 수 있습니다."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"재생에 모든 미디어 디코더 사용"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"애플리케이션에서 설치된 모든 미디어 디코더를 사용하여 재생하는 데 디코딩할 수 있도록 허용합니다."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"신뢰할 수 있는 자격증명 관리"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"앱에서 CA 인증서를 신뢰할 수 있는 자격증명으로 설치 및 제거하도록 허용합니다."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"진단 그룹 소유의 리소스 읽기/쓰기"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"앱이 진단 그룹 소유의 리소스(예: /dev에 있는 파일)를 읽고 쓸 수 있도록 허용합니다. 이 기능은 시스템 안정성 및 보안에 영향을 미칠 수 있으므로 제조업체 또는 사업자가 하드웨어 관련 진단을 수행하는 경우에만 사용해야 합니다."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"앱 구성요소 사용 또는 사용 안함"</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"앱이 Wi-Fi 디스플레이를 설정하고 연결하도록 허용합니다."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wi-Fi 디스플레이 제어"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"앱이 Wi-Fi 디스플레이의 하위 수준 기능을 제어하도록 허용합니다."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"오디오 출력 캡처"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"앱이 오디오 출력을 캡처하고 리디렉션하도록 허용합니다."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"동영상 출력 캡처"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"앱이 동영상 출력을 캡처하고 리디렉션하도록 허용합니다."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"안전한 동영상 출력 캡처"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"앱이 안전한 동영상 출력을 캡처하고 리디렉션하도록 허용합니다."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"오디오 설정 변경"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"앱이 음량이나 출력을 위해 사용하는 스피커 등 전체 오디오 설정을 변경할 수 있도록 허용합니다."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"오디오 녹음"</string>
@@ -525,6 +552,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"휴대전화가 절전 모드로 전환되지 않도록 설정"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"앱이 태블릿의 절전 모드 전환을 막도록 허용합니다."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"앱이 휴대전화의 절전 모드 전환을 막도록 허용합니다."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"태블릿 전원 켜고 끄기"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"휴대전화 전원 켜고 끄기"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"앱이 태블릿을 켜거나 끌 수 있도록 허용합니다."</string>
@@ -613,6 +646,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"앱이 SD 카드에 쓸 수 있도록 허용합니다."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"내부 미디어 저장소 콘텐츠 수정/삭제"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"앱이 내부 미디어 저장소의 콘텐츠를 수정할 수 있도록 허용합니다."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"문서 저장공간 관리"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"앱이 문서 저장공간을 관리할 수 있도록 허용합니다."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"모든 사용자의 외부 저장소에 액세스"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"앱이 모든 사용자의 외부 저장소에 액세스하도록 허용합니다."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"캐시 파일시스템 액세스"</string>
@@ -625,10 +660,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"앱이 네트워크 정책을 관리하고 앱별 규칙을 정의할 수 있도록 허용합니다."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"네트워크 사용량 계산 수정"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"애플리케이션이 애플리케이션의 네트워크 사용량을 계산하는 방식을 수정할 수 있도록 허용합니다. 일반 애플리케이션에서는 사용하지 않습니다."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"소켓 마크 수정"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"앱이 라우팅의 소켓 마크를 수정하도록 합니다."</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_invokeCarrierSetup" msgid="3699600833975117478">"이동통신사에서 제공한 구성 앱 호출"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"권한을 가진 프로그램이 이동통신사에서 제공한 구성 앱을 호출하도록 합니다. 일반 앱에는 필요하지 않습니다."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"네트워크 상태에 대한 관측 보고 수신"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"애플리케이션이 네트워크 상태에 대한 관측 보고를 수신하도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"비밀번호 규칙 설정"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"화면 잠금해제 비밀번호에 허용되는 길이 및 문자 수를 제어합니다."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"화면 잠금해제 시도 모니터링"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <string name="imProtocolGoogleTalk" msgid="493902321140277304">"행아웃"</string>
     <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string>
     <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string>
     <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string>
@@ -796,7 +836,7 @@
     <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">"SIM 카드 사용이 영구적으로 사용중지되었습니다.\n다른 SIM 카드를 사용하려면 무선 서비스 제공업체에 문의하시기 바랍니다."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"이전 트랙 버튼"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"다음 트랙 버튼"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"일시중지 버튼"</string>
@@ -808,11 +848,11 @@
     <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">%d</xliff:g>회 잘못 그렸습니다. "\n\n"<xliff:g id="NUMBER_1">%d</xliff:g>초 후에 다시 시도하세요."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"비밀번호를 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 입력했습니다. "\n\n"<xliff:g id="NUMBER_1">%d</xliff:g>초 후에 다시 시도하세요."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"PIN을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 입력했습니다. "\n\n"<xliff:g id="NUMBER_1">%d</xliff:g>초 후에 다시 시도하세요."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 그렸습니다. <xliff:g id="NUMBER_1">%d</xliff:g>회 더 실패하면 Google 로그인을 통해 태블릿을 잠금해제해야 합니다."\n\n" <xliff:g id="NUMBER_2">%d</xliff:g>초 후에 다시 시도하세요."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 그렸습니다. <xliff:g id="NUMBER_1">%d</xliff:g>회 더 실패하면 Google 로그인을 통해 휴대전화를 잠금해제해야 합니다."\n\n" <xliff:g id="NUMBER_2">%d</xliff:g>초 후에 다시 시도하세요."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 그렸습니다. \n\n<xliff:g id="NUMBER_1">%d</xliff:g>초 후에 다시 시도하세요."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"비밀번호를 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 입력했습니다. \n\n<xliff:g id="NUMBER_1">%d</xliff:g>초 후에 다시 시도하세요."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"PIN을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 입력했습니다. \n\n<xliff:g id="NUMBER_1">%d</xliff:g>초 후에 다시 시도하세요."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 그렸습니다. <xliff:g id="NUMBER_1">%d</xliff:g>회 더 실패하면 Google 로그인을 통해 태블릿을 잠금해제해야 합니다.\n\n <xliff:g id="NUMBER_2">%d</xliff:g>초 후에 다시 시도하세요."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 그렸습니다. <xliff:g id="NUMBER_1">%d</xliff:g>회 더 실패하면 Google 로그인을 통해 휴대전화를 잠금해제해야 합니다.\n\n <xliff:g id="NUMBER_2">%d</xliff:g>초 후에 다시 시도하세요."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"태블릿을 잠금 해제하려는 시도가 <xliff:g id="NUMBER_0">%d</xliff:g>번 잘못되었습니다. <xliff:g id="NUMBER_1">%d</xliff:g>번 더 실패하면 태블릿이 초기화되고 사용자 데이터가 모두 손실됩니다."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"휴대전화를 잠금 해제하려는 시도가 <xliff:g id="NUMBER_0">%d</xliff:g>번 잘못되었습니다. <xliff:g id="NUMBER_1">%d</xliff:g>번 더 실패하면 휴대전화가 초기화되고 사용자 데이터가 모두 손실됩니다."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"태블릿을 잠금 해제하려는 시도가 <xliff:g id="NUMBER">%d</xliff:g>번 잘못되었습니다. 태블릿이 초기화됩니다."</string>
@@ -826,7 +866,7 @@
     <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_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>
@@ -874,7 +914,7 @@
     <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="autofill_this_form" msgid="4616758841157816676">"자동완성"</string>
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"<xliff:g id="APPLICATION">%1$s</xliff:g>(이)가 중지되었습니다."</string>
     <string name="aerr_process" msgid="4507058997035697579">"<xliff:g id="PROCESS">%1$s</xliff:g> 프로세스가 중지되었습니다."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g>이(가) 응답하지 않습니다."\n\n"닫으시겠습니까?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"<xliff:g id="ACTIVITY">%1$s</xliff:g>이(가) 응답하지 않습니다."\n\n"닫으시겠습니까?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g>이(가) 응답하지 않습니다.\n\n닫으시겠습니까?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"<xliff:g id="ACTIVITY">%1$s</xliff:g>이(가) 응답하지 않습니다.\n\n닫으시겠습니까?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g>이(가) 응답하지 않습니다. 닫으시겠습니까?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"<xliff:g id="PROCESS">%1$s</xliff:g> 프로세스가 응답하지 않습니다."\n\n"닫으시겠습니까?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"<xliff:g id="PROCESS">%1$s</xliff:g> 프로세스가 응답하지 않습니다.\n\n닫으시겠습니까?"</string>
     <string name="force_close" msgid="8346072094521265605">"확인"</string>
     <string name="report" msgid="4060218260984795706">"신고"</string>
     <string name="wait" msgid="7147118217226317732">"대기"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"페이지가 응답하지 않습니다."\n\n"페이지를 닫으시겠습니까?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"페이지가 응답하지 않습니다.\n\n페이지를 닫으시겠습니까?"</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>
@@ -1256,6 +1296,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"기본 컨테이너 서비스를 호출하여 콘텐츠를 복사할 수 있도록 허용합니다. 일반 앱에서는 사용하지 않습니다."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"미디어 출력 연결"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"앱이 미디어 출력을 기타 외부 기기에 연결할 수 있도록 허용합니다."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"키가드 보안 저장소 액세스"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"애플리케이션에서 키가드 보안 저장소에 액세스하도록 허용합니다."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"키가드 표시 및 숨기기 설정"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"애플리케이션에서 키가드를 제어하도록 허용합니다."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"확대/축소하려면 두 번 터치하세요."</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"위젯을 추가할 수 없습니다."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"이동"</string>
@@ -1265,15 +1309,15 @@
     <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">"전화하기 "\n"<xliff:g id="NUMBER">%s</xliff:g>에 연결"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"전화번호부에"\n"<xliff:g id="NUMBER">%s</xliff:g> 추가"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"전화하기 \n<xliff:g id="NUMBER">%s</xliff:g>에 연결"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"전화번호부에\n<xliff:g id="NUMBER">%s</xliff:g> 추가"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"다음 앱에서 앞으로 계정에 액세스할 수 있도록 권한을 요청합니다."</string>
     <string name="grant_credentials_permission_message_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="permission_request_notification_with_subtitle" msgid="8530393139639560189">"<xliff:g id="ACCOUNT">%s</xliff:g> 계정에 대해\n권한 요청"</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>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"전체 보기"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"작업 선택"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"공유 대상"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"기기가 잠겼습니다."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"전송 중..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"브라우저를 실행하시겠습니까?"</string>
@@ -1441,10 +1484,12 @@
     <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>
+    <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_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="wifi_display_notification_title" msgid="2223050649240326557">"무선 디스플레이가 연결되었습니다."</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"이 화면은 다른 기기에서 표시되고 있습니다."</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"연결 해제"</string>
@@ -1453,7 +1498,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">%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">"SIM PIN 입력"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN 입력"</string>
@@ -1473,27 +1518,85 @@
     <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_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">%d</xliff:g>회 잘못 입력했습니다. "\n\n"<xliff:g id="NUMBER_1">%d</xliff:g>초 후에 다시 시도해 주세요."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"비밀번호를 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 입력했습니다. "\n\n"<xliff:g id="NUMBER_1">%d</xliff:g>초 후에 다시 시도해 주세요."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 그렸습니다. "\n\n"<xliff:g id="NUMBER_1">%d</xliff:g>초 후에 다시 시도해 주세요."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 입력했습니다. \n\n<xliff:g id="NUMBER_1">%d</xliff:g>초 후에 다시 시도해 주세요."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"비밀번호를 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 입력했습니다. \n\n<xliff:g id="NUMBER_1">%d</xliff:g>초 후에 다시 시도해 주세요."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 그렸습니다. \n\n<xliff:g id="NUMBER_1">%d</xliff:g>초 후에 다시 시도해 주세요."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"태블릿을 잠금해제하려는 시도가 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못되었습니다. <xliff:g id="NUMBER_1">%d</xliff:g>회 더 실패하면 태블릿이 초기화되고 사용자 데이터가 모두 사라집니다."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"휴대전화를 잠금해제하려는 시도가 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못되었습니다. <xliff:g id="NUMBER_1">%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="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">%d</xliff:g>회 잘못 그렸습니다. <xliff:g id="NUMBER_1">%d</xliff:g>회 더 실패하면 이메일 계정을 사용하여 태블릿을 잠금해제해야 합니다."\n\n" <xliff:g id="NUMBER_2">%d</xliff:g>초 후에 다시 시도해 주세요."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 그렸습니다. <xliff:g id="NUMBER_1">%d</xliff:g>회 더 실패하면 이메일 계정을 사용하여 휴대전화를 잠금해제해야 합니다."\n\n" <xliff:g id="NUMBER_2">%d</xliff:g>초 후에 다시 시도해 주세요."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 그렸습니다. <xliff:g id="NUMBER_1">%d</xliff:g>회 더 실패하면 이메일 계정을 사용하여 태블릿을 잠금해제해야 합니다.\n\n <xliff:g id="NUMBER_2">%d</xliff:g>초 후에 다시 시도해 주세요."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 그렸습니다. <xliff:g id="NUMBER_1">%d</xliff:g>회 더 실패하면 이메일 계정을 사용하여 휴대전화를 잠금해제해야 합니다.\n\n <xliff:g id="NUMBER_2">%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="7324161939475478066">"안전한 수준 이상으로 볼륨을 높이시겠습니까?"\n"높은 볼륨으로 장시간 청취하면 청력에 손상이 올 수 있습니다."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"안전한 수준 이상으로 볼륨을 높이시겠습니까?\n높은 볼륨으로 장시간 청취하면 청력에 손상이 올 수 있습니다."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"두 손가락으로 길게 누르면 접근성을 사용하도록 설정됩니다."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"접근성을 사용 설정했습니다."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"접근성이 취소되었습니다."</string>
     <string name="user_switched" msgid="3768006783166984410">"현재 사용자는 <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="app_no_restricted_accounts" msgid="4011285085817350390">"이 애플리케이션은 제한된 프로필의 계정을 지원하지 않습니다."</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"이 앱은 제한된 프로필의 계정을 지원하지 않습니다."</string>
     <string name="app_not_found" msgid="3429141853498927379">"이 작업을 처리하는 애플리케이션을 찾을 수 없습니다."</string>
     <string name="revoke" msgid="5404479185228271586">"취소"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"레터"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"거번먼트 레터"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"리걸"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"주니어 리걸"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"원장"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"타블로이드"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"취소됨"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"콘텐츠 작성 중 오류"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"알 수 없음"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"관리자 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>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"새 PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"새 PIN 확인"</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_too_short" msgid="8173982756265777792">"PIN이 너무 짧습니다. 최소 4자 이상이어야 합니다."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"1초 후에 다시 시도하세요."</item>
+    <item quantity="other" msgid="4730868920742952817">"<xliff:g id="COUNT">%d</xliff:g>초 후에 다시 시도하세요."</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"나중에 다시 시도"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"화면 가장자리에서 스와이프하여 표시줄 표시"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"화면 가장자리에서 스와이프하여 시스템 표시줄 표시"</string>
 </resources>
diff --git a/core/res/res/values-land/alias.xml b/core/res/res/values-land/alias.xml
deleted file mode 100644
index eac5ece..0000000
--- a/core/res/res/values-land/alias.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/assets/res/any/colors.xml
-**
-** 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.
-*/
--->
-<resources>
-    <!-- Alias used to reference one of two possible layouts in keyguard.  -->
-    <item type="layout" name="keyguard_eca">@android:layout/keyguard_emergency_carrier_area_empty</item>
-</resources>
diff --git a/core/res/res/values-land/arrays.xml b/core/res/res/values-land/arrays.xml
index 240b9e4..5602a1c 100644
--- a/core/res/res/values-land/arrays.xml
+++ b/core/res/res/values-land/arrays.xml
@@ -19,54 +19,4 @@
 -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
 
-    <!-- Resources for GlowPadView in LockScreen -->
-    <array name="lockscreen_targets_when_silent">
-        <item>@null</item>"
-        <item>@drawable/ic_action_assist_generic</item>
-        <item>@drawable/ic_lockscreen_soundon</item>
-        <item>@drawable/ic_lockscreen_unlock</item>
-    </array>
-
-    <array name="lockscreen_target_descriptions_when_silent">
-        <item>@null</item>
-        <item>@string/description_target_search</item>
-        <item>@string/description_target_soundon</item>
-        <item>@string/description_target_unlock</item>
-    </array>
-
-    <array name="lockscreen_direction_descriptions">
-        <item>@null</item>
-        <item>@string/description_direction_up</item>
-        <item>@string/description_direction_left</item>
-        <item>@string/description_direction_down</item>
-    </array>
-
-    <array name="lockscreen_targets_when_soundon">
-        <item>@null</item>
-        <item>@drawable/ic_action_assist_generic</item>
-        <item>@drawable/ic_lockscreen_silent</item>
-        <item>@drawable/ic_lockscreen_unlock</item>
-    </array>
-
-    <array name="lockscreen_target_descriptions_when_soundon">
-        <item>@null</item>
-        <item>@string/description_target_search</item>
-        <item>@string/description_target_silent</item>
-        <item>@string/description_target_unlock</item>
-    </array>
-
-    <array name="lockscreen_targets_with_camera">
-        <item>@null</item>
-        <item>@drawable/ic_action_assist_generic</item>
-        <item>@drawable/ic_lockscreen_camera</item>
-        <item>@drawable/ic_lockscreen_unlock</item>
-    </array>
-
-    <array name="lockscreen_target_descriptions_with_camera">
-        <item>@null</item>
-        <item>@string/description_target_search</item>
-        <item>@string/description_target_camera</item>
-        <item>@string/description_target_unlock</item>
-    </array>
-
 </resources>
diff --git a/core/res/res/values-land/refs.xml b/core/res/res/values-land/refs.xml
new file mode 100644
index 0000000..cda38cf
--- /dev/null
+++ b/core/res/res/values-land/refs.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2013, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+-->
+<resources>
+    <item type="string" name="transient_navigation_confirmation">@string/transient_navigation_confirmation_long</item>
+</resources>
\ No newline at end of file
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
new file mode 100644
index 0000000..e8cd4e2
--- /dev/null
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -0,0 +1,1602 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<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="5973789783504771878">"KB"</string>
+    <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
+    <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
+    <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
+    <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
+    <string name="untitled" msgid="4638956954852782576">"&lt;ບໍ່ມີຊື່&gt;"</string>
+    <string name="ellipsis" msgid="7899829516048813237">"…"</string>
+    <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
+    <string name="emptyPhoneNumber" msgid="7694063042079676517">"(ບໍ່ມີເບີໂທລະສັບ)"</string>
+    <string name="unknownName" msgid="2277556546742746522">"(ບໍ່ຮູ້)"</string>
+    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"ຂໍ້ຄວາມສຽງ"</string>
+    <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
+    <string name="mmiError" msgid="5154499457739052907">"ມີບັນຫາໃນການເຊື່ອມຕໍ່ ຫຼືລະຫັດ MMI ບໍ່ຖືກຕ້ອງ."</string>
+    <string name="mmiFdnError" msgid="5224398216385316471">"ການດຳເນີນການຖືກຈຳກັດເປັນ ຈຳກັດໝາຍເລກໂທອອກເທົ່ານັ້ນ."</string>
+    <string name="serviceEnabled" msgid="8147278346414714315">"ບໍລິການຖືກເປີດໄວ້ແລ້ວ."</string>
+    <string name="serviceEnabledFor" msgid="6856228140453471041">"ບໍລິການຖືກເປີດໃຊ້ສຳລັບ:"</string>
+    <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="mmiComplete" msgid="8232527495411698359">"MMI ສຳເລັດ."</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>
+    <string name="invalidPuk" msgid="8761456210898036513">"ພິມລະຫັດ PUK ທີ່ມີ 8 ໂຕເລກ ຫຼືຫຼາຍກວ່ານັ້ນ."</string>
+    <string name="needPuk" msgid="919668385956251611">"ຊິມກາດຂອງທ່ານຖືກລັອກດ້ວຍລະຫັດ PUK. ໃຫ້ພິມລະຫັດ PUK ເພື່ອປົດລັອກມັນ."</string>
+    <string name="needPuk2" msgid="4526033371987193070">"ພິມ PUK2 ເພື່ອປົດລັອກ SIM card."</string>
+    <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="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">"ການປ່ຽນແປງ PIN"</string>
+    <string name="CnipMmi" msgid="3110534680557857162">"ສະແດງໝາຍເລກທີ່ໂທ"</string>
+    <string name="CnirMmi" msgid="3062102121430548731">"ເບີໂທທີ່ຖືກຈຳກັດ"</string>
+    <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="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"ໝາຍເລກຜູ່ໂທຖືກຕັ້ງຄ່າເລີ່ມຕົ້ນໃຫ້ຖືກຈຳກັດ. ການໂທຄັ້ງຕໍ່ໄປ: ຖືກຈຳກັດ"</string>
+    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"ໝາຍເລກຜູ່ໂທ ໄດ້ຮັບການຕັ້ງຄ່າເລີ່ມຕົ້ນເປັນ ຖືກຈຳກັດ. ການໂທຄັ້ງຕໍ່ໄປ: ບໍ່ຖືກຈຳກັດ."</string>
+    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"Caller ID ໂດຍເລີ່ມຕົ້ນຖືກປັບໃຫ້ບໍ່ມີການປິດກັ້ນ. ການໂທຕໍ່ໄປ:ປິດກັ້ນ"</string>
+    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"ໝາຍເລກຜູ່ໂທ ໄດ້ຮັບການຕັ້ງຄ່າເລີ່ມຕົ້ນເປັນ ບໍ່ຖືກຈຳກັດ. ການໂທຄັ້ງຕໍ່ໄປ: ບໍ່ຖືກຈຳກັດ."</string>
+    <string name="serviceNotProvisioned" msgid="8614830180508686666">"ບໍ່ໄດ້ເປີດໃຊ້ບໍລິການ."</string>
+    <string name="CLIRPermanent" msgid="3377371145926835671">"ທ່ານບໍ່ສາມາດປ່ຽນແປງການຕັ້ງຄ່າ Caller ID"</string>
+    <string name="RestrictedChangedTitle" msgid="5592189398956187498">"ປ່ຽນການເຂົ້າເຖິງທີ່ຖືກຈຳກັດແລ້ວ"</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="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>
+    <string name="serviceClassDataSync" msgid="7530000519646054776">"ຊິ້ງຂໍ້ມູນ"</string>
+    <string name="serviceClassPacket" msgid="6991006557993423453">"ແພັກເກັດ"</string>
+    <string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
+    <string name="roamingText0" msgid="7170335472198694945">"ໂຕບອກການເຊື່ອມຕໍ່ກັບເຄືອຂ່າຍພາຍນອກເປີດຢູ່"</string>
+    <string name="roamingText1" msgid="5314861519752538922">"ໂຕບອກການເຊື່ອມຕໍ່ກັບເຄືອຂ່າຍພາຍນອກປິດຢູ່"</string>
+    <string name="roamingText2" msgid="8969929049081268115">"ໂຕບອກການເຊື່ອມຕໍ່ກັບເຄືອຂ່າຍພາຍນອກກະພິບ"</string>
+    <string name="roamingText3" msgid="5148255027043943317">"ຢູ່ນອກເຂດໃກ້ຄຽງ"</string>
+    <string name="roamingText4" msgid="8808456682550796530">"ດ້ານນອກຂອງອາຄານ"</string>
+    <string name="roamingText5" msgid="7604063252850354350">"ໂຣມມິງ - ລະບົບທີ່ຕ້ອງການ"</string>
+    <string name="roamingText6" msgid="2059440825782871513">"ໂຣມມິງ - ລະບົບທີ່ໃຊ້ໄດ້"</string>
+    <string name="roamingText7" msgid="7112078724097233605">"ໂຣມມິງ - ຮຸ້ນສ່ວນພັນທະມິດ"</string>
+    <string name="roamingText8" msgid="5989569778604089291">"ໂຣມມິງ - ຮຸ້ນສ່ວນພຣີມຽມ"</string>
+    <string name="roamingText9" msgid="7969296811355152491">"ໂຣມມິງ - ຟັງຊັນບໍລິການເຕັມຮູບແບບ"</string>
+    <string name="roamingText10" msgid="3992906999815316417">"ໂຣມມິງ - ຟັງຊັນບໍລິການບາງສ່ວນ"</string>
+    <string name="roamingText11" msgid="4154476854426920970">"ເປີດໂຣມມິງແບນເນີ"</string>
+    <string name="roamingText12" msgid="1189071119992726320">"ປິດໂຣມມິງແບນເນີ"</string>
+    <string name="roamingTextSearching" msgid="8360141885972279963">"ຊອກຫາບໍລິການ"</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="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="httpErrorProxyAuth" msgid="1788207010559081331">"ການພິສູດຢືນຢັນຜ່ານເຊີບເວີ Proxy ບໍ່ສຳເລັດ."</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="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="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="default" msgid="3475999286680000541">"ພື້ນທີ່ໃນໂທລະສັບເຕັມແລ້ວ. ກະລຸນາລຶບບາງໄຟລ໌ອອກເພື່ອເພີ່ມພື້ນທີ່ຫວ່າງ."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"ການນຳໃຊ້ເຄືອຂ່າຍອາດມີການກວດສອບຕິດຕາມ"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
+    <string name="me" msgid="6545696007631404292">"ຂ້າພະເຈົ້າ"</string>
+    <string name="power_dialog" product="tablet" msgid="8545351420865202853">"ໂຕເລືອກແທັບເລັດ"</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">"ປິດ wireless"</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="shutdown_progress" msgid="2281079257329981203">"ກຳລັງປິດລົງ..."</string>
+    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"ແທັບເລັດຂອງທ່ານຈະຖືກປິດ."</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">"ຣີບູດເຂົ້າ safe mode"</string>
+    <string name="reboot_safemode_confirm" msgid="55293944502784668">"ທ່ານຕ້ອງການຣີບູດເຂົ້າ safe mode ຫຼືບໍ່? ນີ້ຈະເປັນການປິດການເຮັດວຽກຂອງແອັບພລິເຄຊັນ ຈາກພາກສ່ວນທີສາມທັງໝົດທີ່ທ່ານໄດ້ຕິດຕັ້ງໄວ້. ແອັບພລິເຄຊັນເຫຼົ່ານັ້ນ ຈະກັບມາເຮັດວຽກໄດ້ອີກຫຼັງຈາກທ່ານຣີບູດອີກຄັ້ງ."</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="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_bug_report" msgid="7934010578922304799">"ລາຍງານຂໍ້ຜິດພາດ"</string>
+    <string name="bugreport_title" msgid="2667494803742548533">"ໃຊ້ລາຍງານຂໍ້ບົກພ່ອງ"</string>
+    <string name="bugreport_message" msgid="398447048750350456">"ນີ້ຈະເປັນການເກັບກຳຂໍ້ມູນກ່ຽວກັບ ສະຖານະປັດຈຸບັນຂອງອຸປະກອນທ່ານ ເພື່ອສົ່ງເປັນຂໍ້ຄວາມທາງອີເມວ. ມັນຈະໃຊ້ເວລາໜ້ອຍນຶ່ງ ໃນການເລີ່ມຕົ້ນການລາຍງານຂໍ້ຜິດພາດ ຈົນກວ່າຈະພ້ອມທີ່ຈະສົ່ງໄດ້, ກະລຸນາລໍຖ້າ."</string>
+    <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_airplane_mode_on_status" msgid="2719557982608919750">"ເປີດໂໝດຢູ່ໃນຍົນແລ້ວ"</string>
+    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"ປິດໂໝດໃນຍົນແລ້ວ"</string>
+    <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
+    <string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
+    <string name="android_system_label" msgid="6577375335728551336">"ລະບົບ Android"</string>
+    <string name="permgrouplab_costMoney" msgid="5429808217861460401">"ບໍລິການທີ່ເຮັດໃຫ້ທ່ານເສຍເງິນ"</string>
+    <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"ເຮັດສິ່ງທີ່ທ່ານຕ້ອງເສຍຄ່າໃຊ້ຈ່າຍ."</string>
+    <string name="permgrouplab_messages" msgid="7521249148445456662">"ຂໍ້ຄວາມຂອງທ່ານ"</string>
+    <string name="permgroupdesc_messages" msgid="7821999071003699236">"ອ່ານ ແລະຂຽນ SMS, ອີເມວ ແລະຂໍ້ຄວາມອື່ນໆຂອງທ່ານ."</string>
+    <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"ຂໍ້ມູນສ່ວນໂຕຂອງທ່ານ"</string>
+    <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"ເຂົ້າເຖິງຂໍ້ມູນກ່ຽວກັບທ່ານໂດຍກົງ, ບັນທຶກໄວ້ໃນບັດລາຍຊື່ຜູ່ຕິດຕໍ່ຂອງທ່ານ."</string>
+    <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"ຂໍ້ມູນສັງຄົມຂອງທ່ານ"</string>
+    <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"ເຂົ້າເຖິງຂໍ້ມູນກ່ຽວກັບລາຍຊື່ຜູ່ຕິດຕໍ່ ແລະການເຊື່ອມຕໍ່ທາງສັງຄົມຂອງທ່ານໂດຍກົງ."</string>
+    <string name="permgrouplab_location" msgid="635149742436692049">"ສະຖານທີ່ຂອງທ່ານ"</string>
+    <string name="permgroupdesc_location" msgid="5704679763124170100">"ຕິດຕາມສະຖານທີ່ທາງກາຍະພາບຂອງທ່ານ."</string>
+    <string name="permgrouplab_network" msgid="5808983377727109831">"ການສື່ສານເຄືອຂ່າຍ"</string>
+    <string name="permgroupdesc_network" msgid="4478299413241861987">"ເຂົ້າເຖິງຄຸນສົມບັດຕ່າງໆຂອງເຄືອຂ່າຍ."</string>
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"Bluetooth"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"ເຂົ້າເຖິງອຸປະກອນ ແລະເຄືອຂ່າຍຜ່ານ Bluetooth."</string>
+    <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"ການຕັ້ງຄ່າສຽງ"</string>
+    <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"ປ່ຽນການຕັ້ງຄ່າສຽງ."</string>
+    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"ສົ່ງຜົນຕໍ່ແບັດເຕີຣີ"</string>
+    <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"ໃຊ້ຄວາມສາມາດທີ່ເຮັດໃຫ້ພະລັງງານແບັດເຕີຣີຫຼຸດລົງຢ່າງໄວວາ."</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"ປະຕິທິນ"</string>
+    <string name="permgroupdesc_calendar" msgid="5777534316982184416">"ເຂົ້າເຖິງປະຕິທິນ ແລະນັດໝາຍໂດຍກົງ."</string>
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"ອ່ານວັດຈະນານຸກົມຜູ່ໃຊ້"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"ອ່ານຄຳສັບໃນວັດຈະນານຸກົມຜູ່ໃຊ້."</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"ຂຽນວັດຈະນານຸກົມຜູ່ໃຊ້"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"ເພີ່ມຄຳສັບໃສ່ວັດຈະນານຸກົມຜູ່ໃຊ້."</string>
+    <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"ບຸກມາກ ແລະປະຫວັດເວັບໄຊ"</string>
+    <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"ເຂົ້ານຳໃຊ້ບຸກແລະປະຫວັດການທ່ອງເວັບໂດຍກົງ."</string>
+    <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"ໂມງປຸກ"</string>
+    <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"ຕັ້ງໂມງປຸກ."</string>
+    <string name="permgrouplab_voicemail" msgid="4162237145027592133">"ຂໍ້ຄວາມສຽງ"</string>
+    <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"ເຂົ້າໃຊ້ຂໍ້ຄວາມສຽງໂດຍກົງ"</string>
+    <string name="permgrouplab_microphone" msgid="171539900250043464">"ໄມໂຄຣໂຟນ"</string>
+    <string name="permgroupdesc_microphone" msgid="7106618286905738408">"ເຂົ້າເຖິງໄມໂຄຣໂຟນໂດຍກົງເພື່ອບັນທຶກສຽງ."</string>
+    <string name="permgrouplab_camera" msgid="4820372495894586615">"ກ້ອງ"</string>
+    <string name="permgroupdesc_camera" msgid="2933667372289567714">"ເຂົ້າໃຊ້ກ້ອງຖ່າຍຮູບສຳລັບການຖ່າຍຮູບ ແລະວິດີໂອໂດຍກົງ."</string>
+    <string name="permgrouplab_screenlock" msgid="8275500173330718168">"ລັອກໜ້າຈໍ"</string>
+    <string name="permgroupdesc_screenlock" msgid="7067497128925499401">"ຄວາມສາມາດໃນການສົ່ງຜົນຕໍ່ພຶດຕິກຳ ຂອງການລັອກໜ້າຈໍໃນອຸປະກອນຂອງທ່ານ."</string>
+    <string name="permgrouplab_appInfo" msgid="8028789762634147725">"ເບິ່ງຂໍ້ມູນແອັບພລິເຄຊັນຂອງທ່ານ"</string>
+    <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"ສາມາດສົ່ງຜົນຕໍ່ການເຮັດວຽກ ຂອງແອັບພລິເຄຊັນອື່ນໃນອຸປະກອນຂອງທ່ານ."</string>
+    <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"ພາບພື້ນຫຼັງ"</string>
+    <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"ປ່ຽນການຕັ້ງຄ່າພາບພື້ນຫຼັງຂອງອຸປະກອນ."</string>
+    <string name="permgrouplab_systemClock" msgid="406535759236612992">"ໂມງ"</string>
+    <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"ປ່ຽນເວລາ ຫຼືເຂດເວລາໃນອຸປະກອນ."</string>
+    <string name="permgrouplab_statusBar" msgid="2095862568113945398">"ແຖບສະຖານະ"</string>
+    <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"ປ່ຽນການຕັ້ງຄ່າແຖບສະຖານະອຸປະກອນ."</string>
+    <string name="permgrouplab_syncSettings" msgid="3341990986147826541">"ຕັ້ງຄ່າການຊິ້ງຂໍ້ມູນ"</string>
+    <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"ເຂົ້າໃຊ້ການຕັ້ງຄ່າການຊິ້ງຂໍ້ມູນ"</string>
+    <string name="permgrouplab_accounts" msgid="3359646291125325519">"ບັນຊີຂອງທ່ານ"</string>
+    <string name="permgroupdesc_accounts" msgid="4948732641827091312">"ເຂົ້າເຖິງບັນຊີທີ່ໃຊ້ໄດ້."</string>
+    <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"ການຄວບຄຸມຮາດແວ"</string>
+    <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"ເຂົ້າເຖິງຮາດແວຂອງຊຸດຫູຟັງໂດຍກົງ."</string>
+    <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"ການໂທ"</string>
+    <string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"ຕິດຕາມ, ເກັບກຳ ແລະປະມວນຜົນການໂທລະສັບ."</string>
+    <string name="permgrouplab_systemTools" msgid="4652191644082714048">"ເຄື່ອງມືລະບົບ"</string>
+    <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"ການເຂົ້າເຖິງ ແລະການຄວບຄຸມລະບົບໃນລະດັບຕ່ຳ."</string>
+    <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"ເຄື່ອງມືການພັດທະນາ"</string>
+    <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"ມີພຽງນັກພັດທະນາແອັບຯເທົ່ານັ້ນທີ່ຈະຕ້ອງການຄວາມສາມາດເຫຼົ່ານີ້."</string>
+    <string name="permgrouplab_display" msgid="4279909676036402636">"ສ່ວນຕິດຕໍ່ຜູ່ໃຊ້ຂອງແອັບພລິເຄຊັນອື່ນ"</string>
+    <string name="permgroupdesc_display" msgid="6051002031933013714">"ສົ່ງຜົນຕໍ່ສ່ວນຕິດຕໍ່ຜູ່ໃຊ້ຂອງແອັບພລິເຄຊັນອື່ນ."</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"ພື້ນທີ່ຈັດເກັບຂໍ້ມູນ"</string>
+    <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"ການເຂົ້າເຖິງບ່ອນຈັດເກັບຂໍ້ມູນ USB."</string>
+    <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"ການເຂົ້າເຖິງ SD card."</string>
+    <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"ຄວາມສາມາດການຊ່ວຍເຂົ້າເຖິງ"</string>
+    <string name="permgroupdesc_accessibilityFeatures" msgid="4205196881678144335">"ຄຸນສົມບັດທີ່ເທັກໂນໂລຢີຄວາມຊ່ວຍເຫຼືອສາມາດຮ້ອງຂໍໄດ້."</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="5800552516779249356">"ລາຍການທີ່ສຳພັດຈະຖືກເວົ້າອອກມາ ແລະສາມາດສຳຫຼວດໜ້າຈໍໄດ້ດ້ວຍທ່າທາງ."</string>
+    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"ເປີດການເຂົ້າເຖິງເວັບທີ່ມີປະສິດທິພາບຫຼາຍຂຶ້ນ"</string>
+    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"ສະຄຣິບອາດຖືກຕິດຕັ້ງ ເພື່ອເຮັດໃຫ້ເນື້ອຫາແອັບຯເຂົ້າເຖິງໄດ້ຫຼາຍຂຶ້ນ."</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"ຕິດຕາມ​ເບິ່ງ​ຂໍ້​ຄວາມ​ທີ່​ທ່ານ​ພິມ"</string>
+    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"ຮວມທັງຂໍ້ມູນສ່ວນໂຕເຊັ່ນ: ເລກບັດເຄຣດິດ ແລະລະຫັດຜ່ານ."</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"ປິດການນນຳໃຊ້ ຫຼື ແກ້ໄຂແຖບສະຖານະ"</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"ອະນຸຍາດໃຫ້ແອັບຯປິດການເຮັດວຽກຂອງແຖບສະຖານະ ຫຼືເພີ່ມ ແລະລຶບໄອຄອນລະບົບອອກໄດ້."</string>
+    <string name="permlab_statusBarService" msgid="7247281911387931485">"ແຖບສະຖານະ"</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_processOutgoingCalls" msgid="3906007831192990946">"ປ່ຽນເສັ້ນທາງການໂທອອກ"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"ອະນຸຍາດໃຫ້ແອັບຯປະມວນຜົນສາຍທີ່ໂທອອກ ແລະປ່ຽນໝາຍເລກທີ່ຈະໂທອອກ. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດກວດສອບ, ໂອນສາຍ ຫຼືຂັດຂວາງບໍ່ໃຫ້ໂທອອກໄດ້."</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_receiveEmergencyBroadcast" msgid="1803477660846288089">"ຮັບການກະຈາຍສັນຍານສຸກເສີນ"</string>
+    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"ອະນຸຍາດໃຫ້ແອັບຯຮັບ ແລະປະມວນຜົນການກະຈາຍຂໍ້ຄວາມດ່ວນໄດ້. ການອະນຸຍາດນີ້ຈະສາມາດນຳໃຊ້ໄດ້ໂດຍແອັບຯຂອງລະບົບເທົ່ານັ້ນ."</string>
+    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"ອ່ານຂໍ້ຄວາມກະຈາຍສັນຍານຂອງເສົາສັນຍານ"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"ອະນຸຍາດໃຫ້ແອັບຯ ສາມາດອ່ານຂໍ້ຄວາມແຈ້ງເຕືອນເຫດສຸກເສີນ ທີ່ໄດ້ຮັບໂດຍອຸປະກອນຂອງທ່ານ. ການແຈ້ງເຕືອນສຸກເສີນທີ່ມີໃຫ້ບໍລິການໃນບາງພື້ນທີ່ ເພື່ອແຈ້ງເຕືອນໃຫ້ທ່ານຮູ້ເຖິງສະຖານະການສຸກເສີນ. ແອັບພລິເຄຊັນທີ່ເປັນອັນຕະລາຍອາດລົບກວນປະສິດທິພາບ ຫຼືການດຳເນີນງານຂອງອຸປະກອນຂອງທ່ານ ເມື່ອໄດ້ການຮັບແຈ້ງເຕືອນສຸກເສີນຈາກສະຖານີມືຖື."</string>
+    <string name="permlab_sendSms" msgid="5600830612147671529">"ສົ່ງຂໍ້ຄວາມ SMS"</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"ອະນຸຍາດໃຫ້ແອັບຯສົ່ງຂໍ້ຄວາມ SMS ໄດ້. ນີ້ອາດເຮັດໃຫ້ທ່ານເກີດການຄິດຄ່າບໍລິການທີ່ບໍ່ຄາດຄິດໄດ້. ແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດເຮັດໃຫ້ທ່ານເສຍເງິນຍ້ອນການສົ່ງຂໍ້ຄວາມໂດຍທີ່ທ່ານບໍ່ຮູ້ໂຕໄດ້."</string>
+    <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"ສົ່ງກິດຈະກຳການຕອບສະໜອງຜ່ານທາງຂໍ້ຄວາມ"</string>
+    <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"ອະນຸຍາດໃຫ້ແອັບຯສົ່ງຄຳຂໍ ໄປຫາແອັບຯຂໍ້ຄວາມອື່ນໆເພື່ອຈັດການ ກໍລະນີການຕອບດ້ວຍຂໍ້ຄວາມ ສຳລັບສາຍທີ່ໂທເຂົ້າມາ."</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"ອ່ານຂໍ້ຄວາມຂອງທ່ານ (SMS ຫຼື MMS)"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"ອະນຸຍາດໃຫ້ແອັບຯອ່ານ SMS ທີ່ບັນທຶກໄວ້ໃນແທັບເລັດ ຫຼື SIM card ຂອງທ່ານ. ຄຸນສົມບັດນີ້ຈະເຮັດໃຫ້ແອັບຯສາມາດອ່ານຂໍ້ຄວາມ SMS ທັງໝົດໄດ້ ບໍ່ເນື້ອຫາຂອງມັນຈະແມ່ນຫຍັງກໍຕາມ."</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"ອະນຸຍາດໃຫ້ແອັບຯ ອ່ານຂໍ້ຄວາມ SMS ທີ່ເກັບໄວ້ໃນໂທລະສັບຂອງທ່ານ ຫຼືຊິມກາດ. ນີ້ອະນຸຍາດໃຫ້ແອັບຯ ອ່ານຂໍ້ຄວາມ SMS ທັງໝົດ, ໂດຍບໍ່ຄຳນຶງເຖິງເນື້ອຫາ ຫຼືຄວາມລັບ."</string>
+    <string name="permlab_writeSms" msgid="3216950472636214774">"ແກ້ໄຂຂໍ້ຄວາມຂອງທ່ານ (SMS ຫຼື MMS)"</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"ອະນຸຍາດໃຫ້ແອັບຯຂຽນຂໍ້ຄວາມ SMS ທີ່ບັນທຶກໄວ້ໃນແທັບເລັດຂອງທ່ານ ຫຼືຊິມກາດຂອງທ່ານ. ແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດລຶບຂໍ້ຄວາມຂອງທ່ານໄດ້."</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"ອະນຸຍາດໃຫ້ແອັບຯ ຂຽນລົງໃສ່ຂໍ້ຄວາມ 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_interactAcrossUsers" msgid="7114255281944211682">"ການຕອບໂຕ້ລະຫວ່າງຜູ່ໃຊ້"</string>
+    <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"ອະນຸຍາດໃຫ້ແອັບຯດຳເນີນການ ສັ່ງງານຜ່ານຜູ່ໃຊ້ອື່ນໆໃນອຸປະກອນ. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດໃຊ້ຄວາມສາມາດນີ້ ເພື່ອລະເມີດການປ້ອງກັນລະຫວ່າງຜູ່ໃຊ້."</string>
+    <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"ໃບອະນຸຍາດສະບັບເຕັມໃນການໂຕ້ຕອບລະຫວ່າງຜູ່ໃຊ້"</string>
+    <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"ອະນຸຍາດທຸກການໂຕ້ຕອບທີ່ເປັນໄປໄດ້ລະຫວ່າງຜູ່ໃຊ້."</string>
+    <string name="permlab_manageUsers" msgid="1676150911672282428">"ຈັດການຜູ່ໃຊ້"</string>
+    <string name="permdesc_manageUsers" msgid="8409306667645355638">"ອະນຸຍາດໃຫ້ແອັບຯຈັດການຜູ່ໃຊ້ໃນອຸປະກອນ, ຮວມທັງການເອີ້ນ, ການສ້າງ ແລະການລຶບຂໍ້ມູນ."</string>
+    <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"ດຶງລາຍລະອຽດຂອງແອັບຯທີ່ກຳລັງເຮັດວຽກຢູ່"</string>
+    <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"ອະນຸຍາດໃຫ້ແອັບຯດຶງຂໍ້ມູນຢ່າງລະອຽດ ກ່ຽວກັບການເຮັດວຽກໃນປັດຈຸບັນ ແລະຫາກໍຜ່ານມາ. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດຄົ້ນພົບຂໍ້ມູນສ່ວນໂຕ ກ່ຽວກັບແອັບຯອື່ນໄດ້."</string>
+    <string name="permlab_reorderTasks" msgid="2018575526934422779">"ຮຽງລຳດັບແອັບຯທີ່ກຳລັງເຮັດວຽກຄືນໃໝ່"</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"ອະນຸຍາດໃຫ້ແອັບຯຍ້າຍການເຮັດວຽກໄປໃສ່ດ້ານໜ້າ ແລະພື້ນຫຼັງໄດ້. ແອັບຯອາດຈະດຳເນີນການໂດຍບໍ່ຕ້ອງໃຫ້ທ່ານບອກ."</string>
+    <string name="permlab_removeTasks" msgid="6821513401870377403">"ຢຸດແອັບຯທີ່ເຮັດວຽກຢູ່"</string>
+    <string name="permdesc_removeTasks" msgid="1394714352062635493">"ອະນຸຍາດໃຫ້ແອັບຯລຶບການເຮັດວຽກ ແລະປິດແອັບຯຂອງວຽກເຫຼົ່ານັ້ນ. ແອັບຯທີ່ເປັນອັນຕະລາຍ ສາມາດລົບກວນການເຮັດວຽກຂອງແອັບຯອື່ນໄດ້."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"ຈັດການສະແຕັກການເຄື່ອນໄຫວ"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"ອະ​ນຸ​ຍາດ​ໃຫ້ແອັບຯເພື່ອເພີ່ມ, ລຶບ ແລະ ແກ້ໄຂສະແຕັກການເຄື່ອນໄຫວ ທີ່ແອັບຯອື່ນໆເຮັດວຽກ. ແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດລົບກວນການເຮັດວຽກຂອງແອັບຯອື່ນ."</string>
+    <string name="permlab_startAnyActivity" msgid="2918768238045206456">"ເລີ່ມການເຮັດວຽກໃດນຶ່ງ"</string>
+    <string name="permdesc_startAnyActivity" msgid="997823695343584001">"ອະນຸຍາດໃຫ້ແອັບຯເລີ່ມການເຮັດວຽກໃດກໍໄດ້ ບໍ່ວ່າການອະນຸຍາດ ຫຼືສະຖານະການສົ່ງອອກຈະເປັນແນວໃດກໍຕາມ."</string>
+    <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"ຕັ້ງຄວາມເຂົ້າກັນໄດ້ຂອງໜ້າຈໍ"</string>
+    <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"ອະນຸຍາດໃຫ້ແອັບຯຄວບຄຸມໂໝດຄວາມເຂົ້າກັນໄດ້ ຂອງໜ້າຈໍແອັບພລິເຄຊັນອື່ນໆ. ແອັບພລິເຄຊັນທີ່ເປັນອັນຕະລາຍ ອາດເຮັດໃຫ້ແອັບພລິເຄຊັນອື່ນເຮັດວຽກຜິດພາດໄດ້."</string>
+    <string name="permlab_setDebugApp" msgid="3022107198686584052">"ເປີດການເກັບຂໍ້ມູນເພື່ອແກ້ໄຂບັນຫາ"</string>
+    <string name="permdesc_setDebugApp" msgid="4474512416299013256">"ອະນຸຍາດໃຫ້ແອັບຯ ເປີດການເກັບຂໍ້ມູນແກ້ບັນຫາສຳລັບແອັບຯອື່ນ. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດໃຊ້ຄຸນສົມບັດນີ້ເພື່ອປິດແອັບຯອື່ນ."</string>
+    <string name="permlab_changeConfiguration" msgid="4162092185124234480">"ປ່ຽນການຕັ້ງຄ່າໜ້າຈໍຂອງລະບົບ"</string>
+    <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"ອະນຸຍາດໃຫ້ແອັບຯປ່ຽນແປງການຕັ້ງຄ່າໃນປັດຈຸບັນ ເຊັ່ນ: ການຕັ້ງຄ່າທ້ອງຖິ່ນ ຫຼືຂະໜາດໂຕອັກສອນໂດຍຮວມ."</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_forceStopPackages" msgid="2329627428832067700">"ບັງຄັບໃຫ້ແອັບຯອື່ນຢຸດເຮັດວຽກ"</string>
+    <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"ອະນຸຍາດໃຫ້ແອັບຯບັງຄັບປິດແອັບຯອື່ນໆໄດ້."</string>
+    <string name="permlab_forceBack" msgid="652935204072584616">"ບັງຄັບປິດແອັບຯ"</string>
+    <string name="permdesc_forceBack" msgid="3892295830419513623">"ອະນຸຍາດໃຫ້ແອັບຯບັງຄັບການເຮັດວຽກທີ່ຢູ່ດ້ານໜ້າປິດ ແລະກັບຄືນໄດ້. ແອັບພລິເຄຊັນທົ່ວໄປບໍ່ຄວນຈຳເປັນຕ້ອງໃຊ້."</string>
+    <string name="permlab_dump" msgid="1681799862438954752">"ດຶງຂໍ້ມູນສະຖານະພາຍໃນຂອງລະບົບ"</string>
+    <string name="permdesc_dump" msgid="1778299088692290329">"ອະນຸຍາດໃຫ້ແອັບຯ ດຶງເອົາສະຖານະພາຍໃນຂອງລະບົບ. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດຈະດຶງເອົາຂໍ້ມູນສ່ວນຕົວ ແລະຂໍ້ມູນຄວາມປອດໄພ ຫຼາກຫຼາຍປະເພດທີ່ບໍ່ຈຳເປັນຕໍ່ພວກມັນເລີຍ."</string>
+    <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"ດຶງເອົາເນື້ອຫາໜ້າຈໍ"</string>
+    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"ອະນຸຍາດໃຫ້ແອັບຯດຶງຂໍ້ມູນເນື້ອຫາຂອງໜ້າຈໍທີ່ໃຊ້ຢູ່ໄດ້. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດດຶງຂໍ້ມູນທັງໝົດໃນໜ້າຈໍ ແລະກວດສອບຂໍ້ຄວາມທັງໝົດໃນນັ້ນໄດ້ ຍົກເວັ້ນລະຫັດຜ່ານ."</string>
+    <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"ປິດການຊ່ວຍການເຂົ້າເຖິງຊົ່ວຄາວ"</string>
+    <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນ ເປີດໃຊ້ການຊ່ວຍເຂົ້າເຖິງແບບຊົ່ວຄາວໃນອຸປະກອນ. ແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດເປີດໃຊ້ການຊ່ວຍເຂົ້າເຖິງ ໂດຍບໍ່ໄດ້ຮັບການຍິນຍອມຈາກຜູ່ໃຊ້."</string>
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"ດຶງເອົາຂໍ້ມູນໜ້າຈໍ"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນ ດຶງເອົາຂໍ້ມູນກ່ຽວກັບໜ້າຈໍຈາກໂຕຈັດການໜ້າຈໍ. ແອັບຯທີ່ບໍ່ປອດໄພອາດດຶງເອົາຂໍ້ມູນທີ່ໃຊ້ສຳລັບພາຍໃນລະບົບໄດ້."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"ກັ່ນຕອງເຫດການ"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນ ລົງທະບຽນການກັ່ນຕອງຂາເຂົ້າ ທີ່ກັ່ນຕອງການສົ່ງຂໍ້ມູນເຫດການຜູ່ໃຊ້ທັງໝົດ ກ່ອນທີ່ພວກມັນຈະຖືກເຜີຍແຜ່. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດຄວບຄຸມ UI ຂອງລະບົບໂດຍບໍ່ຕ້ອງໃຫ້ຜູ່ໃຊ້ຈັດການໄດ້."</string>
+    <string name="permlab_magnify_display" msgid="5973626738170618775">"ຂະຫຍາຍການສະແດງຜົນ"</string>
+    <string name="permdesc_magnify_display" msgid="7121235684515003792">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນ ສາມາດຂະຫຍາຍເນື້ອຫາທີ່ສະແດງຜົນໄດ້. ແອັບພລິເຄຊັນທີ່ເປັນອັນຕະລາຍ ອາດປ່ຽນເນື້ອຫາທີ່ສະແດງໃນລັກສະນະ ທີ່ເຮັດໃຫ້ບໍ່ສາມາດນຳໃຊ້ອຸປະກອນໄດ້."</string>
+    <string name="permlab_shutdown" msgid="7185747824038909016">"ປິດລົງບາງສ່ວນ"</string>
+    <string name="permdesc_shutdown" msgid="7046500838746291775">"ກຳນົດໃຫ້ໂຕຈັດການກິດຈະກຳຢູ່ໃນສະຖານະປິດລະບົບ ໂດຍບໍ່ໄດ້ປິດລະບົບຢ່າງສົມບູນ."</string>
+    <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"ຂັດຂວາງການສະລັບແອັບຯ"</string>
+    <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"ປ້ອງກັນບໍ່ໃຫ້ຜູ່ໃຊ້ສະຫຼັບໄປຫາແອັບຯອື່ນ."</string>
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"ດຶງຂໍ້ມູນແອັບຯໃນປັດຈຸບັນ"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງດຶງຂໍ້ມູນສ່ວນໂຕ ກ່ຽວກັບແອັບພລິເຄຊັນປັດຈຸບັນໃນສ່ວນຂອງໜ້າຈໍໄດ້."</string>
+    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"ຕິດຕາມ ແລະຄວບຄຸມການເປີດໂຕຂອງແອັບຯທັງໝົດ"</string>
+    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"ອະນຸຍາດໃຫ້ແອັບຯ ຕິດຕາມ ແລະຄວບຄຸມວິທີທີ່ລະບົບເລີ່ມການເຮັດວຽກຕ່າງໆ. ແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດເຮັດໃຫ້ລະບົບທັງໝົດເກີດອັນຕະລາຍໄດ້. ການກຳນົດສິດນີ້ຈຳເປັນສຳລັບການພັດທະນາເທົ່ານັ້ນ, ບໍ່ແມ່ນສຳລັບການນຳໃຊ້ທົ່ວໄປ."</string>
+    <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"ສົ່ງການກະຈ່າຍຂໍ້ມູນທີ່ເອົາແພັກເກດອອກແລ້ວ"</string>
+    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"ອະນຸຍາດໃຫ້ແອັບຯສົ່ງການແຈ້ງເຕືອນວ່າ ແພັກເກັດຂອງແອັບຯດັ່ງໄດ້ລຶບອອກໄປແລ້ວ. ແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດໃຊ້ຄວາມສາມາດນີ້ ເພື່ອປິດການເຮັດວຽກຂອງແອັບຯອື່ນໆ ທີ່ກຳລັງເຮັດວຽກຢູ່."</string>
+    <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"ສົ່ງການກະຈາຍ SMS ທີ່ໄດ້ຮັບ"</string>
+    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"ອະນຸຍາດໃຫ້ແອັບຯ ກະຈາຍສັນຍານການແຈ້ງເຕືອນວ່າຂໍ້ຄວາມ SMS ໄດ້ຮັບແລ້ວ. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດຈະໃຊ້ສິ່ງນີ້ໃນການປອມແປງຂໍ້ຄວາມ SMS ຂາເຂົ້າ."</string>
+    <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"ສົ່ງການກະຈາຍ WAP-PUSH ທີ່ໄດ້ຮັບ"</string>
+    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"ອະນຸຍາດໃຫ້ແອັບຯສົ່ງການແຈ້ງເຕືອນໃນເວລາທີ່ໄດ້ຮັບຂໍ້ມຄວາມ WAP PUSH. ແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດໃຊ້ການກະທຳນີ້ເພື່ອປອມການໄດ້ຮັບຂໍ້ຄວາມ MMS ຫຼືລັກປ່ຽນເນື້ອຫາຂອງໜ້າເວັບຕ່າງໆ ດ້ວຍສິ່ງອັນຕະລາຍທັງຫຼາຍຢ່າງງຽບໆ."</string>
+    <string name="permlab_setProcessLimit" msgid="2451873664363662666">"ຈຳກັດຈຳນວນຂອງໂປຣເຊສທີ່ເຮັດວຽກຢູ່"</string>
+    <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"ອະນຸຍາດໃຫ້ແອັບຯຄວບຄຸມຈຳນວນສູງສຸດ ຂອງໂປຣເຊສທີ່ຈະເຮັດວຽກ. ບໍ່ຄວນຖືກໃຊ້ກັບແອັບພລິເຄຊັນທົ່ວໄປ."</string>
+    <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"ບັງຄັບໃຫ້ແອັບຯທີ່ເຮັດວຽກຢູ່ພື້ນຫຼັງປິດໂຕລົງ"</string>
+    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"ອະນຸຍາດໃຫ້ແອັບຯຄວບຄຸມວ່າການເຮັດວຽກໃດ ຄວນຈະຖືກປິດລົງ ຫຼັງຈາກທີ່ພວກມັນຖືກປ່ຽນໃຫ້ໄປເຮັດວຽກໃນຫຼັງລະບົບ. ບໍ່ຄວນໃຊ້ກັບແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_batteryStats" msgid="2789610673514103364">"ອ່ານສະຖິຕິແບັດເຕີຣີ"</string>
+    <string name="permdesc_batteryStats" msgid="5897346582882915114">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນ ອ່ານຂໍ້ມູນການນຳໃຊ້ປະຈຸບັນຂອງຖ່ານໃນລະດັບຕໍ່າ. ອາດຈະເຮັດໃຫ້ແອັບພລິເຄຊັນ ສາມາດຊອກຫາຂໍ້ມູນລະອຽດ ກ່ຽວກັບແອັບຯທີ່ທ່ານໃຊ້."</string>
+    <string name="permlab_updateBatteryStats" msgid="3719689764536379557">"ແກ້ໄຂສະຖິຕິແບັດເຕີຣີ"</string>
+    <string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"ອະນຸຍາດໃຫ້ແອັບຯ ແກ້ໄຂສະຖິຕິກ່ຽວກັບແບັດເຕີຣີທີ່ເກັບກຳມາໄດ້. ບໍ່ໃຊ້ສຳລັບແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_getAppOpsStats" msgid="1508779687436585744">"ດຶງຂໍ້ມູນສະຖິຕິການເຮັດວຽກຂອງແອັບຯ"</string>
+    <string name="permdesc_getAppOpsStats" msgid="6243887041577912877">"ອະນຸຍາດໃຫ້ແອັບຯດຶງເອົາຂໍ້ມູນ ສະຖິຕິຂອງແອັບພລິເຄຊັນທີ່ໄດ້ເກັບກຳມາ. ບໍ່ໄດ້ໃຊ້ໃນແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"ແກ້ໄຂສະຖິຕິການເຮັດວຽກຂອງແອັບຯ"</string>
+    <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"ອະນຸຍາດໃຫ້ແອັບຯແກ້ໄຂສະຖິຕິ ການເຮັດວຽກຂອງແອັບພລິເຄຊັນທີ່ເກັບກຳມາ. ແອັບຯທົ່ວໄປບໍ່ຈຳເປັນຕ້ອງໃຊ້."</string>
+    <string name="permlab_backup" msgid="470013022865453920">"ຄວບຄຸມການສຳຮອງ ແລະການກູ້ຂໍ້ມູນລະບົບ"</string>
+    <string name="permdesc_backup" msgid="6912230525140589891">"ອະນຸຍາດໃຫ້ແອັບຯຄວບຄຸມກົນໄກການສຳຮອງ ແລະກູ້ຂໍ້ມູນຂອງລະບົບໄດ້. ແອັບຯທຳມະດາບໍ່ໄດ້ໃຊ້."</string>
+    <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"ຢືນຢັນການສຳຮອງ ຫຼືການກູ້ຂໍ້ມູນເຕັມຮູບແບບ"</string>
+    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"ອະນຸຍາດໃຫ້ແອັບຯເປີດການເຮັດວຽກ ຂອງສ່ວນຕິດຕໍ່ຜູ່ໃຊ້ສຳລັບຢືນຢັນການສຳຮອງຂໍ້ມູນເຕັມຮູບແບບ. ບໍ່ມີແອັບຯໃດຕ້ອງໃຊ້ຄຸນສົມບັດນີ້."</string>
+    <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"ສະແດງໜ້າຈໍທີ່ບໍ່ໄດ້ຮັບອະນຸຍາດ"</string>
+    <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"ອະນຸຍາດໃຫ້ແອັບຯສ້າງໜ້າຈໍສຳລັບການນຳໃຊ້ພາຍໃນລະບົບ. ແອັບຯທົ່ວໄປບໍ່ໄດ້ໃຊ້."</string>
+    <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"ບັງແອັບຯອື່ນໆ"</string>
+    <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"ອະນຸຍາດໃຫ້ແອັບຯເຮັດວຽກເທິງແອັບຯ ຫຼືບ່ອນອື່ນໆຂອງສ່ວນຕິດຕໍ່ຜູ່ໃຊ້ ເຊິ່ງອາດລົບກວນການເຮັດວຽກຂອງສ່ວນຕິດຕໍ່ ໃນແອັບພລິເຄຊັນຕ່າງໆ ຫຼືປ່ຽນສິ່ງທີ່ທ່ານຄິດວ່າທ່ານເຫັນໃນແອັບພລິເຄຊັນອື່ນໆໄດ້."</string>
+    <string name="permlab_setAnimationScale" msgid="2805103241153907174">"ແກ້ໄຂຄວາມໄວຂອງອະນິເມຊັນໂດຍຮວມ"</string>
+    <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"ອະນຸຍາດໃຫ້ແອັບຯ ປ່ຽນຄວາມໄວອະນິເມຊັນທົ່ວໄປ (ອະນິເມຊັນໄວຂຶ້ນ ຫຼືຊ້າລົງ) ໄດ້ຕະຫຼອດເວລາ."</string>
+    <string name="permlab_manageAppTokens" msgid="1286505717050121370">"ຈັດການໂທເຄນຂອງແອັບຯ"</string>
+    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"ອະນຸຍາດໃຫ້ແອັບຯສ້າງ ແລະຈັດການໂທເຄນຂອງຕົນເອງ ໂດຍຂ້າມການຈັດຕາມລຳດັບ Z ປົກກະຕິຂອງພວກມັນໄປ. ແອັບຯທົ່ວໄປບໍ່ຄວນຈຳເປັນຕ້ອງໃຊ້."</string>
+    <string name="permlab_freezeScreen" msgid="4708181184441880175">"ຄ້າງໜ້າຈໍ"</string>
+    <string name="permdesc_freezeScreen" msgid="8558923789222670064">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນຄ້າງໜ້າຈໍໄວ້ຊົ່ວຄາວ ສຳລັບການປ່ຽນເປັນແບບເຕັມໜ້າຈໍ."</string>
+    <string name="permlab_injectEvents" msgid="1378746584023586600">"ກົດປຸ່ມແລະປຸ່ມຄວບຄຸມ"</string>
+    <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"ອະນຸຍາດໃຫ້ແອັບຯສົ່ງກິດຈະກຳການປ້ອນຂໍ້ມູນຂອງມັນ (ເຊັ່ນ: ການກົດປຸ່ມ ແລະອື່ນໆ) ຫາແອັບຯອື່ນ. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດໃຊ້ຄຸນສົມບັດນີ້ ເພື່ອຄວບຄຸມແທັບເລັດໄດ້."</string>
+    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"ອະນຸຍາດໃຫ້ແອັບຯ ສົ່ງການປ້ອນຂໍ້ມູນຂອງຕົນເອງ (ການກົດປຸ່ມ ແລະອື່ນໆ.) ໃຫ້ແອັບຯອື່ນ. ແອັບຯທີ່ເປັນອັນຕະລາຍ ສາມາດໃຊ້ສິ່ງນີ້ເພື່ອຍຶດເອົາການຄວບຄຸມໂທລະສັບທັງໝົດໄດ້."</string>
+    <string name="permlab_readInputState" msgid="469428900041249234">"ບັນທຶກສິ່ງທີ່ທ່ານພິມ ແລະການກະທຳທີ່ທ່ານເຮັດ"</string>
+    <string name="permdesc_readInputState" msgid="8387754901688728043">"ອະນຸຍາດໃຫ້ແອັບຯເບິ່ງການກົດປຸ່ມຂອງທ່ານ ເມື່ອມີປະຕິສຳພັນກັບແອັບຯອື່ນ (ເຊັ່ນ: ການພິມລະຫັດຜ່ານ). ແອັບຯທົ່ວໄປບໍ່ຄວນຈຳເປັນຕ້ອງໃຊ້."</string>
+    <string name="permlab_bindInputMethod" msgid="3360064620230515776">"ເຊື່ອມໂຍງກັບວິທີປ້ອນຂໍ້ມູນ"</string>
+    <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"ອະນຸຍາດໃຫ້ຜູ່ຖືຜູກກັບອິນເຕີເຟດລະດັບສູງສຸດ ຂອງຮູບແບບການປ້ອນຂໍ້ມູນ. ບໍ່ຈຳເປັນສຳລັບແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"ເຊື່ອມໂຍງກັບບໍລິການຊ່ວຍການເຂົ້າເຖິງໃດນຶ່ງ"</string>
+    <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງ ເຊື່ອມໂຍງສ່ວນຕິດຕໍ່ລະດັບເທິງສຸດ ຂອງບໍລິການການເຂົ້າເຖິງ. ແອັບຯທົ່ວໄປບໍ່ຄວນຈຳເປັນຕ້ອງໃຊ້."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"ຜູກ​ມັດ​ກັບ​ການ​ບໍ​ລິ​ການ​ພິມ"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງຜູກກັບສ່ວນຕິດຕໍ່ຜູ່ໃຊ້ຂອງການບໍລິການການພິມ. ບໍ່ໜ້າຈະຕ້ອງການສຳລັບແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"ຜູກ​ມັດ​ກັບບໍລິການການພິມແບບ spooler"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງຜູກກັບສ່ວນຕິດຕໍ່ຜູ່ໃຊ້ຂອງການບໍລິການການພິມ. ບໍ່ໜ້າຈະຕ້ອງການສຳລັບແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"ເຊື່ອມໂຍງກັບບໍລິການ NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"ອະນຸຍາດໃຫ້ຜູ່ຖືອຸປະກອນໃຫ້ສາມາດເຊື່ອມໂຍງແອັບພລິເຄຊັນ ທີ່ຄ້າຍກັບບັດ NFC. ມັນບໍ່ຈຳເປັນຕ້ອງໃຊ້ໃນແອັບຯທຳມະດາ."</string>
+    <string name="permlab_bindTextService" msgid="7358378401915287938">"ເຊື່ອມໂຍງໄປຫາບໍລິການສົ່ງຂໍ້ຄວາມ"</string>
+    <string name="permdesc_bindTextService" msgid="8151968910973998670">"ອະນຸຍາດໃຫ້ຜູ່ຖືຜູກກັບອິນເຕີເຟດລະດັບສູງສຸດ ຂອງບໍລິການຂໍ້ຄວາມ(ຕ.ຢ. SpellCheckerService). ບໍ່ຈຳເປັນສຳລັບແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_bindVpnService" msgid="4708596021161473255">"ເຊື່ອມໂຍງກັບບໍລິການ VPN"</string>
+    <string name="permdesc_bindVpnService" msgid="2067845564581693905">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງເຊື່ອມໂຍງກັບສ່ວນຕິດຕໍ່ລະດັບເທິງສຸດ ຂອງບໍລິການ VPN. ແອັບຯທົ່ວໄປບໍ່ຄວນຈຳເປັນຕ້ອງໃຊ້."</string>
+    <string name="permlab_bindWallpaper" msgid="8716400279937856462">"ເຊື່ອມໂຍງກັບພາບພື້ນຫຼັງ"</string>
+    <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"ອະນຸຍາດໃຫ້ຜູ່ໃຊ້ເຊື່ອມໂຍງກັບສ່ວນຕິດຕໍ່ລະດັບສູງສຸດ ຂອງພາບພື້ນຫຼັງໃດນຶ່ງ. ແອັບຯທຳມະດາບໍ່ຄວນຈຳເປັນຕ້ອງໃຊ້."</string>
+    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ເຊື່ອມໂຍງໄປຫາບໍລິການວິດເຈັດ"</string>
+    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"ອະນຸຍາດໃຫ້ຜູ່ຖືຜູກກັບອິນເຕີເຟດລະດັບສູງສຸດ ຂອງບໍລິການວິເຈັດ. ບໍ່ຈຳເປັນສຳລັບແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"ຕິດຕໍ່ກັບຜູ່ເບິ່ງແຍງອຸປະກອນ"</string>
+    <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງສົ່ງເຈດຕະນາຫາຜູ່ເບິ່ງແຍງລະບົບອຸປະກອນ. ແອັບຯທົ່ວໄປບໍ່ຄວນຈຳເປັນຕ້ອງໃຊ້."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"ເພີ່ມ ຫຼືລຶບຜູ່ເບິ່ງແຍງລະບົບອຸປະກອນ"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງສາມາດລຶບ ຫຼືລຶບຂໍ້ມູນອຸປະກອນທີ່ນຳໃຊ້ໄດ້. ແອັບຯທົ່ວໄປບໍ່ຈຳເປັນຕ້ອງໃຊ້."</string>
+    <string name="permlab_setOrientation" msgid="3365947717163866844">"ປ່ຽນລວງຂອງໜ້າຈໍ"</string>
+    <string name="permdesc_setOrientation" msgid="3046126619316671476">"ອະນຸຍາດໃຫ້ແອັບຯປ່ຽນການໝຸນຂອງໜ້າຈໍໄດ້ທຸກເວລາ. ບໍ່ຄວນຖືກໃຊ້ໃນແອັບພລິເຄຊັນທົ່ວໄປ."</string>
+    <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"ປ່ຽນຄວາມໄວລູກສອນ"</string>
+    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"ອະນຸຍາດໃຫ້ແອັບຯປ່ຽນຄວາມໄວເມົ້າ ຫຼືລູກສອນແທຣັກແພດໃນເວລາໃດກໍໄດ້. ແອັບຯທົ່ວໄປບໍ່ຄວນຈຳເປັນຕ້ອງໃຊ້."</string>
+    <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"ປ່ຽນຮູບແບບແປ້ນພິມ"</string>
+    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"ອະນຸຍາດໃຫ້ແອັບຯປ່ຽນຮູບແບບຂອງແປ້ນຳພິມ. ບໍ່ຈຳເປັນສຳລັບແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"ສົ່ງສັນຍານ Linux ຫາແອັບຯ"</string>
+    <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"ອະນຸຍາດໃຫ້ແອັບຯຮ້ອງຂໍໃຫ້ສົ່ງສັນຍານ ແຈ້ງໄປຫາໂປຣເຊສທີ່ຍັງເຮັດວຽກຢູ່ທັງໝົດ."</string>
+    <string name="permlab_persistentActivity" msgid="8841113627955563938">"ເຮັດໃຫ້ແອັບຯເຮັດວຽກຕະຫຼອດເວລາ"</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"ອະນຸຍາດໃຫ້ແອັບຯ ສາມາດເຮັດໃຫ້ບາງພາກສ່ວນຂອງມັນເອັງ ຄົງໂຕໃນໜ່ວຍຄວາມຈຳ. ສິ່ງນີ້ສາມາດຈຳກັດໜ່ວຍຄວາມຈຳທີ່ສາມາດໃຊ້ໄດ້ໂດຍແອັບຯອື່ນ ເຮັດໃຫ້ແທັບເລັດຊ້າລົງ."</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"ອະນຸຍາດໃຫ້ແອັບຯເຮັດໃຫ້ສ່ວນນຶ່ງຂອງຕົນເອງ ຄົງຢູ່ຖາວອນໃນໜ່ວຍຄວາມຈຳ ເຊິ່ງອາດສາມາດ ເຮັດໃຫ້ການນຳໃຊ້ໜ່ວຍຄວາມຈຳຂອງແອັບຯ ອື່ນຖືກຈຳກັດ ສົ່ງຜົນເຮັດໃຫ້ມືຖືຂອງທ່ານເຮັດວຽກຊ້າລົງໄດ້."</string>
+    <string name="permlab_deletePackages" msgid="184385129537705938">"ລຶບແອັບຯ"</string>
+    <string name="permdesc_deletePackages" msgid="7411480275167205081">"ອະນຸຍາດໃຫ້ແອັບຯລຶບແພັກເກັດ Android ຕ່າງໆໄດ້. ແອັບຯອັນຕະລາຍອາດໃຊ້ຄວາມສາມາດນີ້ ເພື່ອລຶບແອັບຯທີ່ສຳຄັນໄດ້."</string>
+    <string name="permlab_clearAppUserData" msgid="274109191845842756">"ລຶບຂໍ້ມູນຂອງແອັບຯອື່ນ"</string>
+    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"ອະນຸຍາດໃຫ້ແອັບຯລຶບຂໍ້ມູນຜູ່ໃຊ້."</string>
+    <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"ລຶບ cache ຂອງແອັບຯອື່ນ"</string>
+    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"ອະນຸຍາດໃຫ້ແອັບຯລຶບໄຟລ໌ cache ໄດ້."</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"ກວດສອບພື້ນທີ່ຈັດເກັບຂໍ້ມູນແອັບຯ"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"ອະນຸຍາດໃຫ້ແອັບຯດຶງໂຄດ, ຂໍ້ມູນ ແລະຂະໜາດ cache ຂອງມັນໄດ້."</string>
+    <string name="permlab_installPackages" msgid="2199128482820306924">"ຕິດຕັ້ງແອັບຯໂດຍກົງ"</string>
+    <string name="permdesc_installPackages" msgid="5628530972548071284">"ອະນຸຍາດໃຫ້ແອັບຯຕິດຕັ້ງແພັກເກດ Android ໃໝ່ ຫຼືແພັກເກດທີ່ອັບເດດແລ້ວ. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດໃຊ້ຄຸນສົມບັດນີ້ ເພື່ອສ້າງແອັບຯໃໝ່ທີ່ມີສິດອະນຸຍາດສູງກວ່າໄດ້."</string>
+    <string name="permlab_clearAppCache" msgid="7487279391723526815">"ລຶບຂໍ້ມູນ cache ຂອງແອັບຯທັງໝົດ"</string>
+    <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"ອະນຸຍາດໃຫ້ແອັບຯສ້າງພື້ນທີ່ຫວ່າງໃນແທັບເລັດ ໂດຍການລຶບໄຟລ໌ໃນໄດເຣັກທໍຣີ cache ຂອງແອັບພລິເຄຊັນອື່ນ. ຄຸນສົມບັດນີ້ອາດເຮັດໃຫ້ແອັບພລິເຄຊັນອື່ນ ເລີ່ມເຮັດວຽກຊ້າລົງເພາະຕ້ອງຂຽນຂໍ້ມູນຄືນໃໝ່."</string>
+    <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນເພີ່ມເນື້ອທີ່ຫວ່າງໃຫ້ໂທລະສັບ ໂດຍການລຶບໄຟລ໌ໃນໄດເຣັກທໍຣີ cache ຂອງແອັບພລິເຄຊັນອື່ນໆ. ການກະທຳນີ້ອາດເຮັດໃຫ້ແອັບພລິເຄຊັນອື່ນ ເຮັດວຽກໄດ້ຊ້າລົງເນື່ອງຈາກພວກມັນຕ້ອງໄດ້ດຶງຂໍ້ມູນຄືນໃໝ່."</string>
+    <string name="permlab_movePackage" msgid="3289890271645921411">"ຍ້າຍຊັບພະຍາກອນແອັບຯ"</string>
+    <string name="permdesc_movePackage" msgid="319562217778244524">"ອະນຸຍາດໃຫ້ແອັບຯຍ້າຍແຫລ່ງຊັບພະຍາກອນແອັບຯ ຈາກບ່ອນຈັດເກັບຂໍ້ມູນພາຍໃນ ສູ່ບ່ອນຈັດເກັບຂໍ້ມູນພາຍນອກ ແລະໃນທາງກັບກັນໄດ້."</string>
+    <string name="permlab_readLogs" msgid="6615778543198967614">"ອ່ານຂໍ້ມູນບັນທຶກທີ່ສຳຄັນ"</string>
+    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"ອະນຸຍາດໃຫ້ແອັບຯອ່ານໄຟລ໌ບັນທຶກລະບົບຕ່າງໆຂອງລະບົບ. ຄຸນສົມບັດນີ້ຈະອະນຸຍາດໃຫ້ແອັບຯ ສາມາດຄົ້ນພົບຂໍ້ມູນທົ່ວໄປ ກ່ຽວກັບສິ່ງທີ່ທ່ານກຳລັງເຮັດກັບແທັບເລັດ ເຊິ່ງອາດຮວມເຖິງຂໍ້ມູນສ່ວນໂຕນຳໄດ້."</string>
+    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"ອະນຸຍາດໃຫ້ແອັບຯອ່ານໄຟລ໌ບັນທຶກລະບົບຕ່າງໆຂອງລະບົບ. ຄຸນສົມບັດນີ້ຈະອະນຸຍາດໃຫ້ແອັບຯ ສາມາດຄົ້ນພົບຂໍ້ມູນທົ່ວໄປ ກ່ຽວກັບສິ່ງທີ່ທ່ານກຳລັງເຮັດກັບໂທລະສັບ ເຊິ່ງອາດຮວມເຖິງຂໍ້ມູນສ່ວນໂຕນຳໄດ້."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"ໃຊ້ຕົວຖອດລະຫັດໃດກໍໄດ້ເພື່ອການຫຼິ້ນ"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"ອະນຸຍາດໃຫ້ແອັບຯໃຊ້ທຸກຕົວຖອດລະຫັດສື່ທີ່ຕິດຕັ້ງໄວ້ແລ້ວ ເພື່ອການຖອດລະຫັດການຫຼິ້ນໄຟລ໌ຕ່າງໆ."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"ຈັດການໜັງສືຮັບຮອງທີ່ເຊື່ອຖືໄດ້."</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"ອະ​ນຸ​ຍາດ​ໃຫ້ແອັບຯ ຕິດຕັ້ງ ແລະ ຖອນການຕິດຕັ້ງໃບຢັ້ງຢືນ CA ທີ່ເປັນໃບຮັບຮອງທີ່ເຊື່ອຖືໄດ້."</string>
+    <string name="permlab_diagnostic" msgid="8076743953908000342">"ອ່ານ/ຂຽນ ໃສ່ຊັບພະຍາກອນທີ່ເປັນຂອງກຸ່ມວິໄຈ"</string>
+    <string name="permdesc_diagnostic" msgid="6608295692002452283">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນອ່ານ ແລະຂຽນ ໃສ່ທຸກຊັບພະຍາກອນທີ່ເປັນຂອງກຸ່ມວິນິໄສ; ຕົວຢ່າງ: ໄຟລ໌ໃນ /dev. ສິ່ງນີ້ອາດສົ່ງຜົນກະທົບຕໍ່ຄວາມສະຖຽນ ແລະຄວາມປອດໄພຂອງລະບົບ. ສິ່ງນີ້ຄວນໃຊ້ສຳຫຼັບການວິເຄາະບັນຫາຈຳເພາະ ຂອງບາງຮາດແວໂດຍຜູ່ຜະລິດ ຫຼືຜູ່ປະຕິບັດການເທົ່ານັ້ນ."</string>
+    <string name="permlab_changeComponentState" msgid="6335576775711095931">"ເປີດ ຫຼືປິດນຳໃຊ້ອົງປະກອບຂອງແອັບຯ"</string>
+    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"ອະນຸຍາດໃຫ້ແອັບຯ ປ່ຽນແປງອົງປະກອບຂອງແອັບຯອື່ນ ວ່າຖືກເປີດນຳໃຊ້ ຫຼືບໍ່. ແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດໃຊ້ຄວາມສາມາດນີ້ ເພື່ອປິດການນຳໃຊ້ຄວາມສາມາດສຳຄັນຂອງແທັບເລັດ. ການກຳນົດສິດນີ້ຄວນຖືກໃຊ້ຢ່າງລະມັດລະວັງ, ເພາະມັນເປັນໄປໄດ້ທີ່ຈະເຮັດໃຫ້ອົງປະກອບຂອງແອັບຯຢູ່ໃນສະຖານະ ໃຊ້ການບໍ່ໄດ້, ບໍ່ແນ່ນອນ ຫຼືບໍ່ສະຖຽນ."</string>
+    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"ອະນຸຍາດໃຫ້ແອັບຯ ປ່ຽນແປງອົງປະກອບຂອງແອັບຯອື່ນ ວ່າຖືກເປີດນຳໃຊ້ ຫຼືບໍ່. ແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດໃຊ້ຄວາມສາມາດນີ້ ເພື່ອປິດການນຳໃຊ້ຄວາມສາມາດສຳຄັນຂອງໂທລະສັບ. ການກຳນົດສິດນີ້ຄວນຖືກໃຊ້ຢ່າງລະມັດລະວັງ, ເພາະມັນເປັນໄປໄດ້ທີ່ຈະເຮັດໃຫ້ອົງປະກອບຂອງແອັບຯຢູ່ໃນສະຖານະ ໃຊ້ການບໍ່ໄດ້, ບໍ່ແນ່ນອນ ຫຼືບໍ່ສະຖຽນ."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"ອະນຸມັດ ຫຼືຖອດຖານການອະນຸຍາດ"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນອະນຸມັດ ຫຼືຖອນການອະນຸມັດສິດໃດນຶ່ງສຳລັບໂຕມັນເອງ ຫຼືແອັບພລິເຄຊັນອື່ນໆ. ແອັບພລິເຄຊັນທີ່ເປັນອັນຕະລາຍ ອາດໃຊ້ຄວາມສາມາດນີ້ ເພື່ອເຂົ້າເຖິງຄຸນສົມບັດບາງຢ່າງທີ່ທ່ານບໍ່ໄດ້ອະນຸມັດໃຫ້ພວກມັນ."</string>
+    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"ຕັ້ງຄ່າແອັບຯທີ່ຕ້ອງການ"</string>
+    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"ອະນຸຍາດໃຫ້ແອັບຯ ແກ້ໄຂແອັບຯທີ່ທ່ານຕ້ອງການໃຊ້. ແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດປ່ຽນແປງແອັບທີ່ເຮັດວຽກຢູ່ໂດຍບໍ່ແຈ້ງໃຫ້ຮູ້ ໂດຍການປອມແປງວ່າເປັນແອັບຯທີ່ທ່ານຕ້ອງການ ເພື່ອເກັບຂໍ້ມູນສ່ວນໂຕ."</string>
+    <string name="permlab_writeSettings" msgid="2226195290955224730">"ແກ້ໄຂການຕັ້ງຄ່າລະບົບ"</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"ອະນຸຍາດໃຫ້ແອັບຯ ແກ້ໄຂຂໍ້ມູນການຕັ້ງຄ່າລະບົບ. ແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດເຮັດໃຫ້ການຕັ້ງຄ່າຂອງລະບົບເສຍຫາຍໄດ້."</string>
+    <string name="permlab_writeSecureSettings" msgid="204676251876718288">"ແກ້ໄຂການຕັ້ງຄ່າລະບົບ"</string>
+    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"ອະນຸຍາດໃຫ້ແອັບຯ ແກ້ໄຂຂໍ້ມູນການຕັ້ງຄ່າຄວາມປອດໄພຂອງລະບົບ. ແອັບຯທົ່ວໄປບໍ່ໄດ້ໃຊ້ຄຸນສົມບັດນີ້."</string>
+    <string name="permlab_writeGservices" msgid="2149426664226152185">"ແກ້ໄຂແຜນທີ່ບໍລິການ Google"</string>
+    <string name="permdesc_writeGservices" msgid="1287309437638380229">"ອະນຸຍາດໃຫ້ແອັບຯ ແກ້ໄຂການວາງແຜນບໍລິການ Google. ບໍ່ໄດ້ໃຊ້ສຳລັບແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"ເຮັດວຽກໃນຕອນລະບົບເລີ່ມ"</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"ອະນຸຍາດໃຫ້ແອັບຯ ເປີດໂຕມັນເອງທັນທີທີ່ເປີດລະບົບຂຶ້ນມາສຳເລັດ. ນີ້ສາມາດເຮັດໃຫ້ການເລີ່ມເປີດຂອງແທັບເລັດໃຊ້ເວລາດົນຂຶ້ນ ແລະເຮັດໃຫ້ການເຮັດວຽກໂດຍຮວມຂອງແທັບເລັດຊ້າລົງ ໂດຍການເຮັດວຽກຕະຫຼອດເວລາ."</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="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="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="default" msgid="589869224625163558">"ອະນຸຍາດໃຫ້ແອັບຯແກ້ໄຂຂໍ້ມູນກ່ຽວກັບລາຍຊື່ຜູ່ຕິດຕໍ່ ທີ່ບັນທຶກໃນໂທລະສັບຂອງທ່ານ ຮວມທັງຄວາມຖີ່ຂອງການໂທ, ການອີເມວ ຫຼືການຕິດຕໍ່ໃນຮູບແບບອື່ນກັບລາຍຊື່ຜູ່ຕິດຕໍ່ໃດນຶ່ງນຳ. ການອະນຸຍາດນີ້ຈະເຮັດໃຫ້ແອັບຯ ສາມາດລຶບຂໍ້ມູນລາຍຊື່ຜູ່ຕິດຕໍ່ໄດ້."</string>
+    <string name="permlab_readCallLog" msgid="3478133184624102739">"ອ່ານບັນທຶກການໂທ"</string>
+    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"ອະນຸຍາດໃຫ້ແອັບຯ ອ່ານບັນທຶກການໂທຂອງແທັບເລັດທ່ານ ຮວມທັງຂໍ້ມູນການໂທເຂົ້າ ແລະການໂທອອກ. ການກຳນົດສິດນີ້ເຮັດໃຫ້ແອັບຯສາມາດ ບັນທຶກຂໍ້ມູນການໂທຂອງທ່ານ ແລະແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດຈະເຜີຍແຜ່ຂໍ້ມູນການໂທໂດຍທີ່ທ່ານບໍ່ຮັບຮູ້."</string>
+    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"ອະນຸຍາດໃຫ້ແອັບຯອ່ານບັນທຶກການໂທຂອງໂທລະສັບທ່ານ ຮວມທັງຂໍ້ມູນກ່ຽວກັບສາຍໂທເຂົ້າ ແລະໂທອອກ. ການອະນຸຍາດນີ້ຈະເຮັດໃຫ້ແອັບຯ ສາມາດບັນທຶກຂໍ້ມູນການໂທ ແລະເຮັດໃຫ້ແອັບຯທີ່ເປັນອັນຕະລາຍສາມາດ ສົ່ງຕໍ່ຂໍ້ມູນບັນທຶກການໂທໂດຍບໍ່ໃຫ້ທ່ານຮູ້ໄດ້."</string>
+    <string name="permlab_writeCallLog" msgid="8552045664743499354">"ຂຽນຂໍ້ມູນການໂທ"</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ອະນຸຍາດໃຫ້ແອັບຯແກ້ໄຂບັນທຶກການໂທຂອງແທັບເລັດ ຮວມທັງຂໍ້ມູນກ່ຽວກັບການໂທອອກ ແລະໂທເຂົ້ານຳ. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດໃຊ້ຄຸນສົມບັດນີ້ເພື່ອລຶບ ຫຼືແກ້ໄຂບັນທຶກການໂທຂອງທ່ານໄດ້."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"ອະນຸຍາດໃຫ້ແອັບຯ ແກ້ໄຂລາຍການການໂທໃນໂທລະສັບຂອງທ່ານ, ຮວມທັງຂໍ້ມູນກ່ຽວກັບສາຍໂທເຂົ້າ ແລະການໂທອອກ. ແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດໃຊ້ຄວາມສາມາດນີ້ ເພື່ອລຶບ ຫຼືແກ້ໄຂລາຍການການໂທຂອງທ່ານໄດ້."</string>
+    <string name="permlab_readProfile" msgid="4701889852612716678">"ອ່ານບັດລາຍຊື່ຜູ່ຕິດຕໍ່ຂອງທ່ານເອງ"</string>
+    <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"ອະນຸຍາດໃຫ້ແອັບຯ ອ່ານຂໍ້ມູນໂປໄຟລ໌ສ່ວນໂຕໃນອຸປະກອນຂອງທ່ານເຊັ່ນ: ຊື່ຂອງທ່ານ ແລະຂໍ້ມູນການຕິດຕໍ່ຂອງທ່ານ. ນີ້ໝາຍຄວາມວ່າແອັບຯຈະສາມາດລະບຸໂຕຕົນຂອງທ່ານ ແລະສົ່ງຂໍ້ມູນໂປຣໄຟລ໌ຂອງທ່ານໃຫ້ຜູ່ອື່ນໄດ້."</string>
+    <string name="permlab_writeProfile" msgid="907793628777397643">"ແກ້ໄຂບັດລາຍຊື່ຜູ່ຕິດຕໍ່ຂອງທ່ານເອງ"</string>
+    <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"ອະນຸຍາດໃຫ້ແອັບຯ ປ່ຽນແປງ ຫຼືເພີ່ມຂໍ້ມູນໃສ່ໂປຣໄຟລ໌ສ່ວນບຸກຄົນທີ່ເກັບໄວ້ໃນອຸປະກອນຂອງທ່ານ, ເຊັ່ນ: ຊື່ ແລະຂໍ້ມູນຕິດຕໍ່ທ່ານ. ນີ້ໝາຍຄວາມວ່າແອັບຯສາມາດບົ່ງບອກໂຕທ່ານ ແລະອາດສົ່ງຂໍ້ມູນໂປຣໄຟລ໌ຂອງທ່ານໃຫ້ຜູ່ອື່ນໄດ້."</string>
+    <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"ອ່ານການອັບເດດສັງຄົມອອນລາຍຂອງທ່ານ"</string>
+    <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"ອະນຸຍາດໃຫ້ແອັບຯ ເຂົ້າເຖິງ ແລະຊິ້ງຂໍ້ມູນຂ່າວສານສັງຄົມຈາກທ່ານ ແລະໝູ່ຂອງທ່ານ. ຄວນລະມັດລະວັງໃນເວລາທີ່ແລກປ່ຽນຂໍ້ມູນ -- ນີ້ຈະເປັນການອະນຸຍາດໃຫ້ແອັບຯ ອ່ານການສື່ສານລະຫວ່າງທ່ານ ກັບໝູ່ຂອງທ່ານເທິງເຄືອຂ່າຍສັງຄົມ ໂດຍບໍ່ຄຳນຶງເຖິງຄວາມລັບ. ໝາຍເຫດ: ການກຳນົດສິດນີ້ອາດບໍ່ໄດ້ບັງຄັບໃຊ້ໃນທຸກເຄືອຂ່າຍສັງຄົມ."</string>
+    <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"ຂຽນໃສ່ເຄືອຂ່າຍສັງຄົມຂອງທ່ານ"</string>
+    <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"ອະນຸຍາດໃຫ້ແອັບຯສະແດງການອັບເດດຈາກໝູ່ຂອງທ່ານ. ຄວນລະວັງໃນການແປ່ງປັນຂໍ້ມູນ. ມັນຈະໄປອະນຸຍາດໃຫ້ແອັບຯ ສ້າງຂໍ້ຄວາມທີ່ອ້າງວ່າມາຈາກໝູ່ຂອງທ່ານ. ໝາຍເຫດ: ການອະນຸຍາດອາດບໍ່ຖືກບັງຄັບ ໃນບໍລິການເຄືອຂ່າຍສັງຄອມອອນລາຍທຸກອັນ."</string>
+    <string name="permlab_readCalendar" msgid="5972727560257612398">"ອ່ານກຳນົດການໃນປະຕິທິນຮວມທັງຂໍ້ມູນຄວາມລັບ"</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"ອະນຸຍາດໃຫ້ແອັບຯ ອ່ານການນັດໝາຍທັງໝົດທີ່ມີບັນທຶກໃນແທັບເລັດຂອງທ່ານ, ຮວມທັງຂອງໝູ່ ຫຼືໝູ່ທີ່ເຮັດວຽກນຳກັນໄດ້ ເຊິ່ງອາດເຮັດໃຫ້ແອັບຯສາມາດສົ່ງຕໍ່ ຫຼືບັນທຶກຂໍ້ມູນປະຕິທິນຂອງທ່ານ ບໍ່ວ່າຈະເປັນເລື່ອງຄວາມລັບ ຫຼືເລື່ອງລະອຽດອ່ອນແບບໃດກໍຕາມ."</string>
+    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"ອະນຸຍາດໃຫ້ແອັບຯ ອ່ານກຳນົດການໃນປະຕິທິນທັງໝົດ ທີ່ເກັບໄວ້ໃນໂທລະສັບຂອງທ່ານ, ຮວມເຖິງຂອງໝູ່ຄູ່ ຫຼືເພື່ອນຮ່ວມວຽກ. ນີ້ອາດຈະເຮັດໃຫ້ແອັບຯສາມາດເຜີຍແຜ່ ຫຼືບັນທຶກຂໍ້ມູນປະຕິທິນຂອງທ່ານ, ໂດຍບໍ່ຄຳນຶງເຖິງ ຄວາມລະອຽດອ່ອນ ຫຼືຄວາມລັບໃດໆໄດ້."</string>
+    <string name="permlab_writeCalendar" msgid="8438874755193825647">"ເພີ່ມ ຫຼືແກ້ໄຂນັດໝາຍໃນປະຕິທິນ ແລະສົ່ງອີເມວຫາຜູ່ເຂົ້າຮ່ວມໂດຍບໍ່ຕ້ອງໃຫ້ເຈົ້າຂອງຮັບຮູ້"</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"ອະນຸຍາດໃຫ້ແອັບຯເພີ່ມ, ລຶບ ແລະປ່ຽນກິດຈະກຳທີ່ທ່ານສາມາດແກ້ໄຂ ໃນແທັບເລັດຂອງທ່ານໄດ້ ຮວມທັງກິດຈະກຳຂອງໝູ່ ຫຼືໝູ່ຮ່ວມເຮັດວຽກ ເຊິ່ງອາດອະນຸຍາດໃຫ້ແອັບຯສົ່ງຂໍ້ຄວາມທີ່ຄືກັບວ່າ ມາຈາກເຈົ້າຂອງປະຕິທິນ ຫຼືແກ້ໄຂການນັດໝາຍໄດ້ ໂດຍບໍ່ໃຫ້ເຈົ້າຂອງຮັບຮູ້."</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"ອະນຸຍາດໃຫ້ແອັບຯ ເພີ່ມ, ລຶບ, ປ່ຽນແປງນັດໝາຍທີ່ທ່ານສາມາດແກ້ໄຂໄດ້ໃນໂທລະສັບຂອງທ່ານ, ຮວມທັງຂອງໝູ່ຄູ່ ຫຼືເພື່ອນຮ່ວມວຽກ. ນີ້ອາດເຮັດໃຫ້ແອັບຯສາມາດສົ່ງຂໍ້ຄວາມ ທີ່ເບິ່ງຄືວ່າມາຈາກເຈົ້າຂອງປະຕິທິນ ຫຼືແກ້ໄຂນັດໝາຍໂດຍທີ່ທ່ານບໍ່ໄດ້ຮັບຮູ້ໄດ້."</string>
+    <string name="permlab_accessMockLocation" msgid="8688334974036823330">"ຈຳລອງແຫລ່ງຂໍ້ມູນສະຖານທີ່ເພື່ອການທົດສອບ"</string>
+    <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"ສ້າງແຫລ່ງຂໍ້ມູນຈຳລອງຂອງສະຖານທີ່ ເພື່ອການທົດສອບ ຫຼືຕິດຕັ້ງແຫລ່ງຂໍ້ມູນສະຖານທີ່ໃໝ່. ນີ້ຈະອະນຸຍາດໃຫ້ແອັບຯສາມາດຂຽນທັບຂໍ້ມູນຂອງສະຖານທີ່ ແລະ/ຫຼື ຂໍ້ມູນທີ່ສົ່ງກັບມາຈາກແຫລ່ງຂໍ້ມູນສະຖານທີ່ອື່ນ ເຊັ່ນ: GPS ຫຼືແຫລ່ງຂໍ້ມູນສະຖານທີ່ອື່ນໄດ້."</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"ເຂົ້າເຖິງຄຳສັ່ງຜູ່ໃຫ້ບໍລິການພິກັດສະຖານທີ່"</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"ອະນຸຍາດໃຫ້ແອັບຯ ເຂົ້າເຖິງຄຳສັ່ງເພີ່ມເຕີມຂອງຜູ່ໃຫ້ບໍລິການສະຖານທີ່. ນີ້ອາດຈະເປັນການເຮັດໃຫ້ແອັບຯ ລົບກວນການເຮັດວຽກຂອງ GPS ຫຼືແຫລ່ງຂໍ້ມູນສະຖານທີ່ອື່ນໆໄດ້."</string>
+    <string name="permlab_installLocationProvider" msgid="6578101199825193873">"ສິດໃນການຕິດຕັ້ງແຫຼ່ງສະໜອງສະຖານທີ່"</string>
+    <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"ສ້າງສະຖານທີ່ຈຳລອງເພື່ອການທົດລອງ ຫຼືຕິດຕັ້ງແຫຼ່ງຂໍ້ມູນສະຖານທີ່ໃໝ່. ສິ່ງນີ້ເຮັດໃຫ້ແອັບຯສາມາດຂຽນທັບສະຖານທີ່ ແລະ/ຫຼື ສະຖານະທີ່ໄດ້ຈາກແຫຼ່ງສະຖານທີ່ອື່ນເຊັ່ນ: GPS ຫຼືຜູ່ສະໜອງສະຖານທີ່ຕ່າງໆ."</string>
+    <string name="permlab_accessFineLocation" msgid="1191898061965273372">"ສະຖານທີ່ແນ່ນອນ (ອ້າງອີງຈາກ GPS ແລະເຄືອຂ່າຍ)"</string>
+    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"ອະນຸຍາດໃຫ້ແອັບຯ ຮັບຕຳແໜ່ງສະຖານທີ່ລະອຽດຂອງທ່ານໂດຍໃຊ້ GPS ຫຼືແຫລ່ງຂໍ້ມູນເຄືອຂ່າຍສະຖານທີ່ເຊັ່ນ: ເສົາສັນຍານມືຖື ແລະ Wi-Fi. ບໍລິການສະຖານທີ່ເຫຼົ່ານີ້ຕ້ອງຖືກເປີດນຳໃຊ້ ແລະແລະມີຂໍ້ມູນໃຫ້ກັບອຸປະກອນຂອງທ່ານ ເພື່ອໃຫ້ແອັບຯໃຊ້ໄດ້. ແອັບຯຕ່າງໆອາດໃຊ້ຂໍ້ມູນນີ້ເພື່ອລະບຸສະຖານທີ່ຢູ່ຂອງທ່ານ ແລະອາດນຳໃຊ້ແບັດເຕີຣີເພີ່ມເຕີມໄດ້."</string>
+    <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"ສະຖານທີ່ໂດຍປະມານ (ອ້າງອີງຈາກເຄືອຂ່າຍ)"</string>
+    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"ອະນຸຍາດໃຫ້ແອັບຯ ລະບຸສະຖານທີ່ໂດຍປະມານຂອງທ່ານ. ສະຖານທີ່ນີ້ໄດ້ຮັບມາຈາກບໍລິການສະຖານທີ່ ໂດຍອາໃສສະຖານທີ່ເຄືອຂ່າຍເຊັ່ນ: ເສົາສັນຍານ ແລະ Wi-Fi. ບໍລິການສະຖານທີ່ເຫຼົ່ານີ້ຕ້ອງຖືກເປີດໃຊ້ ແລະ ມີໃນອຸປະກອນຂອງທ່ານເພື່ອທີ່ແອັບຯຈະສາມາດໃຊ້ພວກມັນໄດ້. ແອັບຯອາດຈະໃຊ້ຄຸນສົມບັດນີ້ ເພື່ອກວດສອບສະຖານທີ່ໂດຍປະມານຂອງທ່ານ."</string>
+    <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"ເຂົ້າເຖິງ SurfaceFlinger"</string>
+    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"ອະນຸຍາດໃຫ້ແອັບຯນຳໃຊ້ຄວາມສາມາດລະດັບຕ່ຳ SurfaceFlinger"</string>
+    <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"ອ່ານເຟຣມບັບເຟີ"</string>
+    <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"ອະນຸຍາດໃຫ້ແອັບຯອ່ານເນື້ອຫາຂອງເຟຣມບັບເຟີ."</string>
+    <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"ປັບຄ່າການສະແດງຜົນ WiFi"</string>
+    <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"ອະນຸຍາດໃຫ້ແອັບຯຕັ້ງຄ່າ ແລະເຊື່ອມຕໍ່ຈໍສະແດງຜົນ WiFi."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"ຄວບຄຸມການສະແດງ WiFi"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"ອະນຸຍາດໃຫ້ແອັບຯ ຄວບຄຸມຄວາມສາມາດລະດັບຕໍ່າຂອງການສະແດງຜົນ Wifi."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"ບັນທຶກສຽງອອກ"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"ອະນຸຍາດໃຫ້ແອັບຯບັນທຶກ ແລະປ່ຽນເສັ້ນທາງການປ້ອນຂໍ້ມູນອອກຂອງສຽງ."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"ບັນທຶກວິດີໂອອອກ"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"ອະນຸຍາດໃຫ້ແອັບຯບັນທຶກ ແລະປ່ຽນເສັ້ນທາງການປ້ອນຂໍ້ມູນອອກຂອງວິດີໂອ."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"ບັນທຶກວິດີໂອອອກຢ່າງປອດໄພ"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"ອະນຸຍາດໃຫ້ແອັບຯບັນທຶກ ແລະປ່ຽນເສັ້ນທາງການປ້ອນຂໍ້ມູນອອກຂອງວິດີໂອທີ່ປອດໄພ."</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="4906839301087980680">"ອະນຸຍາດໃຫ້ແອັບຯບັນທຶກສຽງດ້ວຍໄມໂຄຣໂຟນໄດ້. ການອະນຸຍາດນີ້ຈະເຮັດໃຫ້ແອັບຯ ສາມາດບັນທຶກສຽງໄດ້ຕະຫລອດເວລາ ໂດຍບໍ່ຕ້ອງຖ້າການຢືນຢັນຈາກທ່ານ."</string>
+    <string name="permlab_camera" msgid="3616391919559751192">"ຖ່າຍຮູບ ແລະວິດີໂອ"</string>
+    <string name="permdesc_camera" msgid="8497216524735535009">"ອະນຸຍາດໃຫ້ແອັບຯຖ່າຍຮູບ ແລະວິດີໂອດ້ວຍກ້ອງຖ່າຍຮູບ. ການອະນຸຍາດນີ້ຈະອານຸຍາດໃຫ້ແອັບຯ ສາມາດໃຊ້ກ້ອງຖ່າຍຮູບໄດ້ຕະຫລອດເວລາ ໂດຍບໍ່ຕ້ອງຖ້າການຢືນຢັນຈາກທ່ານ."</string>
+    <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"ປິດໄຟສັນຍານ LED ເມື່ອນຳໃຊ້ກ້ອງ"</string>
+    <string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນທີ່ມາກັບໂຕເຄື່ອງ ປິດການນຳໃຊ້ໄຟ LED ໃນກ້ອງຖ່າຍຮູບ."</string>
+    <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"ປິດການນຳໃຊ້ແທັບເລັດຖາວອນ"</string>
+    <string name="permlab_brick" product="default" msgid="8337817093326370537">"ປິດການເຮັດວຽກຂອງໂທລະສັບຖາວອນ"</string>
+    <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"ອະນຸຍາດໃຫ້ແອັບຯປິດການນຳໃຊ້ແທັບເລັດທັງໝົດໂດຍຖາວອນ. ຄຸນສົມບັດນີ້ເປັນສິ່ງອັນຕະລາຍຫຼາຍ."</string>
+    <string name="permdesc_brick" product="default" msgid="5788903297627283099">"ອະນຸຍາດໃຫ້ແອັບຯປິດການນຳໃຊ້ໂທລະສັບທັງໝົດແບບຖາວອນ. ອັນຕະລາຍຫຼາຍ."</string>
+    <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"ບັງຄັບໃຫ້ແທັບເລັດປິດແລ້ວເປີດໃໝ່"</string>
+    <string name="permlab_reboot" product="default" msgid="2898560872462638242">"ບັງຄັບໃຫ້ໂທລະສັບປິດແລ້ວເປີດໃໝ່"</string>
+    <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"ອະນຸຍາດໃຫ້ແອັບຯ ບັງຄັບແທັບເລັດໃຫ້ປິດເປີດໃໝ່."</string>
+    <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"ອະນຸຍາດໃຫ້ແອັບຯ ບັງຄັບໃຫ້ໂທລະສັບປິດເປີດໃໝ່."</string>
+    <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"ເຂົ້າເຖິງໄຟລ໌ລະບົບຂອງບ່ອນຈັດເກັບຂໍ້ມູນ USB"</string>
+    <string name="permlab_mount_unmount_filesystems" product="default" msgid="4402305049890953810">"ເຂົ້າເຖິງໄຟລ໌ລະບົບຂອງ SD card"</string>
+    <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"ອະນຸຍາດໃຫ້ແອັບຯ ເຊື່ອມຕໍ່ ແລະຖອນການເຊື່ອມຕໍ່ຈາກລະບົບໄຟລ໌ ຂອງອຸປະກອນເກັບຂໍ້ມູນແບບຖອດອອກໄດ້."</string>
+    <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"ລຶບບ່ອນຈັດເກັບຂໍ້ມູນ USB"</string>
+    <string name="permlab_mount_format_filesystems" product="default" msgid="262582698639274056">"ລຶບ SD card"</string>
+    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"ອະນຸຍາດໃຫ້ແອັບຯ ຟໍແມັດອຸປະກອນເກັບຂໍ້ມູນທີ່ສາມາດຖອດອອກໄດ້."</string>
+    <string name="permlab_asec_access" msgid="3411338632002193846">"ດຶງຂໍ້ມູນຈາກບ່ອນຈັດເກັບຂໍ້ມູນພາຍໃນ"</string>
+    <string name="permdesc_asec_access" msgid="3094563844593878548">"ອະນຸຍາດໃຫ້ແອັບຯດຶງຂໍ້ມູນໃນບ່ອນຈັດເກັບຂໍ້ມູນພາຍໃນໄດ້."</string>
+    <string name="permlab_asec_create" msgid="6414757234789336327">"ສ້າງບ່ອນຈັດເກັບຂໍ້ມູນພາຍໃນ"</string>
+    <string name="permdesc_asec_create" msgid="4558869273585856876">"ອະນຸຍາດໃຫ້ແອັບຯສ້າງພື້ນທີ່ຈັດເກັບຂໍ້ມູນພາຍໃນ."</string>
+    <string name="permlab_asec_destroy" msgid="526928328301618022">"ທຳລາຍບ່ອນຈັດເກັບຂໍ້ມູນພາຍໃນ"</string>
+    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"ອະນຸຍາດໃຫ້ແອັບຯທຳລາຍບ່ອນຈັດເກັບຂໍ້ມູນພາຍໃນ."</string>
+    <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"ເຊື່ອມຕໍ່/ຖອນການເຊື່ອມຕໍ່ ບ່ອນຈັດເກັບຂໍ້ມູນພາຍໃນ"</string>
+    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"ອະນຸຍາດໃຫ້ແອັບຯ ເຊື່ອມຕໍ່/ຖອດການເຊື່ອມຕໍ່ ບ່ອນຈັດເກັບຂໍ້ມູນພາຍໃນ."</string>
+    <string name="permlab_asec_rename" msgid="7496633954080472417">"ປ່ຽນຊື່ບ່ອນເກັບຂໍ້ມູນພາຍໃນ"</string>
+    <string name="permdesc_asec_rename" msgid="1794757588472127675">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນປ່ຽນຊື່ພື້ນທີ່ເກັບຂໍ້ມູນພາຍໃນ."</string>
+    <string name="permlab_vibrate" msgid="7696427026057705834">"ຄວບຄຸມການສັ່ນ"</string>
+    <string name="permdesc_vibrate" msgid="6284989245902300945">"ອະນຸຍາດໃຫ້ແອັບຯຄວບຄຸມໂຕສັ່ນ."</string>
+    <string name="permlab_flashlight" msgid="2155920810121984215">"ຄວບຄຸມໄຟແຟລດ"</string>
+    <string name="permdesc_flashlight" msgid="6522284794568368310">"ອະນຸຍາດໃຫ້ແອັບຯ ຄວບຄຸມໄຟແຟລດ."</string>
+    <string name="permlab_manageUsb" msgid="1113453430645402723">"ຈັດການການກຳນົດຄ່າ ແລະການອະນຸຍາດສຳລັບອຸປະກອນ USB"</string>
+    <string name="permdesc_manageUsb" msgid="7776155430218239833">"ອະນຸຍາດໃຫ້ແອັບຯ ຈັດການການຕັ້ງຄ່າຄວາມຕ້ອງການ ແລະການກຳນົດສິດສຳລັບອຸປະກອນ USB."</string>
+    <string name="permlab_accessMtp" msgid="4953468676795917042">"ໃຊ້ໂປຣໂຕຄອນ MTP"</string>
+    <string name="permdesc_accessMtp" msgid="6532961200486791570">"ອະນຸຍາດການເຂົ້າເຖິງ kernel MPT driver ເພື່ອໃຊ້ໂປຣໂຕຄອນ MTP USB."</string>
+    <string name="permlab_hardware_test" msgid="4148290860400659146">"ທົດສອບຮາດແວ"</string>
+    <string name="permdesc_hardware_test" msgid="6597964191208016605">"ອະນຸຍາດໃຫ້ແອັບຯຄວບຄຸມອຸປະກອນຕໍ່ພ່ວງທັງຫຼາຍ ເພື່ອຈຸດປະສົງການທົດສອບຮາດແວ."</string>
+    <string name="permlab_callPhone" msgid="3925836347681847954">"ໂທຫາເບີໂທລະສັບໂດຍກົງ"</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"ອະນຸຍາດໃຫ້ແອັບຯໂທຫາເບີໂທລະສັບໄດ້ ໂດຍບໍ່ຕ້ອງຖ້າການດຳເນີນການໃດໆຈາກທ່ານ. ຄຸນສົມບັດນີ້ອາດກໍ່ໃຫ້ເກີດຄ່າໃຊ້ຈ່າຍໃນການໂທທີ່ບໍ່ຄາດຄິດໄດ້. ໝາຍເຫດ: ຄຸນສົມບັດນີ້ບໍ່ໄດ້ເປັນການອະນຸຍາດໃຫ້ແອັບຯ ສາມາດໂທຫາເບີສຸກເສີນ. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດເຮັດໃຫ້ທ່ານ ຕ້ອງເສຍຄ່າໂທໂດຍທີ່ບໍ່ໄດ້ຄາດຄິດ."</string>
+    <string name="permlab_callPrivileged" msgid="4198349211108497879">"ໂທໂດຍກົງໄປຫາເບີໂທໃດກໍໄດ້"</string>
+    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"ອະນຸຍາດໃຫ້ແອັບຯໂທອອກຫາເບີໂທລະສັບໃດກໍໄດ້, ຮວມທັງເບີສຸກເສີນ, ໂດຍບໍ່ມີການແຊກແຊງຂອງທ່ານ. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດໂທອອກໂດຍບໍ່ຈຳເປັນ ແລະໂທຫາບໍລິການເບີສຸກເສີນແບບຜິດກົດໝາຍ."</string>
+    <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"ເລີ່ມການຕັ້ງຄ່າແທັບເລັດ CDMA ໂດຍກົງ"</string>
+    <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"ເລີ່ມການຕັ້ງຄ່າໂທລະສັບ CDMA ໂດຍກົງ"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"ອະນຸຍາດໃຫ້ແອັບຯເລີ່ມການເຮັດວຽກຂອງ CDMA. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດເລີ່ມການເຮັດວຽກຂອງ CDMA ໂດຍບໍ່ຈຳເປັນ."</string>
+    <string name="permlab_locationUpdates" msgid="7785408253364335740">"ຄວບຄຸມການແຈ້ງເຕືອນອັບເດດສະຖານທີ່"</string>
+    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"ອະນຸຍາດໃຫ້ແອັບຯ ເປີດ/ປິດ ການເຮັດວຽກຂອງການແຈ້ງເຕືອນອັບເດດສະຖານທີ່ຈາກວິທະຍຸ. ແອັບຯທົ່ວໄປບໍ່ຈຳເປັນຕ້ອງໃຊ້."</string>
+    <string name="permlab_checkinProperties" msgid="7855259461268734914">"ເຂົ້າເຖິງຄຸນສົມບັດການເຊັກອິນ"</string>
+    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"ອະນຸຍາດໃຫ້ແອັບຯໄດ້ຮັບສິດ ອ່ານ/ຂຽນ ໃສ່ສິ່ງທີ່ອັບໂຫຼດຂຶ້ນໂດຍບໍລິການເຊັກອິນ. ບໍ່ໃຊ້ໃນແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_bindGadget" msgid="776905339015863471">"ເລືອກວິດເຈັດ"</string>
+    <string name="permdesc_bindGadget" msgid="8261326938599049290">"ອະນຸຍາດໃຫ້ແອັບຯບອກລະບົບວ່າ ວິດເຈັດໃດສາມາດນຳໃຊ້ໂດຍແອັບຯໃດ. ແອັບຯທີ່ມີການອະນຸຍາດນີ້ຈະມອບການເຂົ້າເຖິງຂໍ້ມູນສ່ວນໂຕ ໃຫ້ກັບແອັບຯອື່ນໄດ້. ບໍ່ໄດ້ໃຊ້ໂດຍແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"ແກ້ໄຂສະຖານະໂທລະສັບ"</string>
+    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"ອະນຸຍາດໃຫ້ແອັບຯຄວບຄຸມຄວາມສາມາດຂອງໂທລະສັບໃນອຸປະກອນ. ແອັບຯທີ່ມີການອະນຸຍາດນີ້ຈະສາມາດສະລັບເຄືອຂ່າຍ, ເປີດ ຫຼືປິດສັນຍານວິທະຍຸ ແລະຄວາມສາມາດອື່ນທີ່ຄ້າຍກັນ ໂດຍບໍ່ມີການແຈ້ງເຕືອນທ່ານ."</string>
+    <string name="permlab_readPhoneState" msgid="9178228524507610486">"ອ່ານສະຖານະ ແລະຂໍ້ມູນລະບຸໂຕຕົນຂອງໂທລະສັບ"</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"ອະນຸຍາດໃຫ້ແອັບຯ ເຂົ້າເຖິງຄວາມສາມາດການໂທລະສັບຂອງອຸປະກອນ. ການກຳນົດສິດນີ້ເຮັດໃຫ້ແອັບຯສາມາດກວດສອບເບີໂທລະສັບ ແລະ ID ຂອງອຸປະກອນ, ບໍ່ວ່າການໂທຈະຍັງດຳເນີນຢູ່ ແລະເບີປາຍທາງເຊື່ອມຕໍ່ຢູ່ຫຼືບໍ່ກໍຕາມ."</string>
+    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"ຂັດຂວາງບໍ່ໃຫ້ປິດໜ້າຈໍແທັບເລັດ"</string>
+    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"ຂັດຂວາງບໍ່ໃຫ້ໂທລະສັບປິດໜ້າຈໍ"</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"ອະນຸຍາດໃຫ້ແອັບຯ ປ້ອງກັນບໍ່ໃຫ້ປິດໜ້າຈໍແທັບເລັດ."</string>
+    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"ອະນຸຍາດໃຫ້ແອັບຯປ້ອງກັນບໍ່ໃຫ້ປິດໜ້າຈໍໂທລະສັບ."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
+    <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"ເປີດ ຫຼືປິດແທັບເລັດ"</string>
+    <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"ເປີດ ຫຼືປິດໂທລະສັບ"</string>
+    <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"ອະນຸຍາດໃຫ້ແອັບຯເປີດ ຫຼືປິດແທັບເລັດ."</string>
+    <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນປິດ ຫຼືເປີດແທັບເລັດໄດ້."</string>
+    <string name="permlab_factoryTest" msgid="3715225492696416187">"ເຮັດວຽກໃນໂໝດການທົດສອບຂອງໂຮງງານ"</string>
+    <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"ເຮັດວຽກໃນຮູບແບບທົດສອບໃນລະດັບຕໍ່າຂອງຜູ່ຜະລິດ, ອະນຸຍາດການເຂົ້າເຖິງແບບເຕັມຮູບແບບຫາຮາດແວຂອງແທັບເລັດ. ໃຊ້ໄດ້ສະເພາະໃນເວລາທີ່ແທັບເລັດກຳລັງຢູ່ໃນໂໝດ ການທົດສອບຂອງຜູ່ຜະລິດgmqjkoaho."</string>
+    <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"ເປີດໃຊ້ໃນແບບການທົດສອບຂອງຜູ່ລະລິດໃນລະດັບຕໍ່າ, ອະນຸຍາດການເຂົ້າເຖິງຮາດແວຂອງໂທລະສັບແບບສົມບູນ. ສະເພາະເມື່ອໂທລະສັບຖືກເປີດໃຊ້ ໃນໂໝດການທົດສອບຂອງຜູ່ຜະລິດເທົ່ານັ້ນ."</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_masterClear" msgid="2315750423139697397">"ຣີເຊັດລະບົບໃຫ້ເປັນຄ່າເລີ່ມຕົ້ນທີ່ມາຈາກໂຮງງານ"</string>
+    <string name="permdesc_masterClear" msgid="3665380492633910226">"ອະນຸຍາດໃຫ້ແອັບຯ ຣີເຊັດຄ່າທັງໝົດຂອງລະບົບໃຫ້ກັບໄປເປັນແບບທີ່ມາຈາກໂຮງງານ, ລຶບຂໍ້ມູນ, ການຕັ້ງຄ່າ ແລະແອັບຯທີ່ໄດ້ຕິດຕັ້ງໄວ້ທັງໝົດ."</string>
+    <string name="permlab_setTime" msgid="2021614829591775646">"ຕັ້ງເວລາ"</string>
+    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"ອະນຸຍາດໃຫ້ແອັບຯປ່ຽນເວລາຂອງໂມງໃນແທັບເລັດໄດ້."</string>
+    <string name="permdesc_setTime" product="default" msgid="1855702730738020">"ອະນຸຍາດໃຫ້ແອັບຯປ່ຽນເວລາຂອງໂມງໃນໂທລະສັບໄດ້."</string>
+    <string name="permlab_setTimeZone" msgid="2945079801013077340">"ຕັ້ງເຂດເວລາ"</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"ອະນຸຍາດໃຫ້ແອັບຯປ່ຽນເຂດເວລາຂອງແທັບເລັດ."</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"ອະນຸຍາດໃຫ້ແອັບຯ ປ່ຽນເຂດເວລາຂອງໂທລະສັບ."</string>
+    <string name="permlab_accountManagerService" msgid="4829262349691386986">"ເຮັດໜ້າທີ່ເປັນ AccountManagerService"</string>
+    <string name="permdesc_accountManagerService" msgid="1948455552333615954">"ອະນຸຍາດໃຫ້ແອັບຯເອີ້ນຫາ AccountAuthenticators."</string>
+    <string name="permlab_getAccounts" msgid="1086795467760122114">"ຊອກຫາບັນຊີໃນອຸປະກອນ"</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"ອະນຸຍາດໃຫ້ແອັບຯຮັບເອົາລາຍການຂອງບັນຊີທີ່ຮູ້ຈັກໂດຍແທັບເລັດ. ນີ້ອາດຮວມທັງບັນຊີຕ່າງໆ ທີ່ຖືກສ້າງໂດຍແອັບພລິເຄຊັນທີ່ທ່ານໄດ້ຕິດຕັ້ງໄວ້."</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນ ດຶງຂໍ້ມູນລາຍຊື່ຂອງບັນຊີທີ່ໂທລະສັບມີ ເຊິ່ງອາດຮວມເຖິງບັນຊີທີ່ໃດໆທີ່ສ້າງຂຶ້ນ ໂດຍແອັບພລິເຄຊັນທີ່ທ່ານຕິດຕັ້ງໄວ້."</string>
+    <string name="permlab_authenticateAccounts" msgid="5265908481172736933">"ສ້າງບັນຊີ ແລະຕັ້ງລະຫັດຜ່ານ"</string>
+    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"ອະນຸຍາດໃຫ້ແອັບຯ ໃຊ້ຄວາມສາມາດຂອງຕົວພິສູດສິດບັນຊີຂອງ AccountManager ຮວມທັງການສ້າງບັນຊີ, ການຂໍເບິ່ງ ແລະຕັ້ງຄ່າລະຫັດຜ່ານ."</string>
+    <string name="permlab_manageAccounts" msgid="4983126304757177305">"ສ້າງ ຫຼືລຶບບັນຊີ"</string>
+    <string name="permdesc_manageAccounts" msgid="8698295625488292506">"ອະນຸຍາດໃຫ້ແອັບຯດຳເນີນການເຊັ່ນ: ເພີ່ມ ຫຼືລຶບບັນຊີ ແລະລຶບລະຫັດຜ່ານຂອງບັນຊີໄດ້."</string>
+    <string name="permlab_useCredentials" msgid="235481396163877642">"ໃຊ້ບັນຊີໃນອຸປະກອນ"</string>
+    <string name="permdesc_useCredentials" msgid="7984227147403346422">"ອະນຸຍາດໃຫ້ແອັບຯຮ້ອງຂໍໂທເຄນການພິສູດຢືນຢັນໄດ້."</string>
+    <string name="permlab_accessNetworkState" msgid="4951027964348974773">"ເບິ່ງການເຊື່ອມຕໍ່ເຄືອຂ່າຍ"</string>
+    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"ອະນຸຍາດໃຫ້ແອັບຯ ເບິ່ງຂໍ້ມູນກ່ຽວກັບການເຊື່ອມຕໍ່ເຄືອຂ່າຍ ເຊັ່ນວ່າມີເຄືອຂ່າຍໃດແດ່ ແລະໄດ້ເຊື່ອມຕໍ່ກັບເຄືອຂ່າຍໃດ."</string>
+    <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"ເຂົ້າເຖິງເຄືອຂ່າຍເຕັມຮູບແບບ"</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"ອະນຸຍາດໃຫ້ແອັບຯສ້າງຊັອກເກັດເຄືອຂ່າຍ ແລະໂປຣໂຕຄອນເຄືອຂ່າຍແບບກຳນົດເອງ. ໂປຣແກຣມທ່ອງເວັບ ແລະແອັບພລິເຄຊັນອື່ນໆຈະສົ່ງຂໍ້ມູນສູ່ອິນເຕີເນັດຢູ່ແລ້ວ ດັ່ງນັ້ນການອະນຸຍາດນີ້ຈຶ່ງບໍ່ຈຳເປັນຕ້ອງໃຊ້ ເພື່ອສົ່ງຂໍ້ມູນສູ່ອິນເຕີເນັດ."</string>
+    <string name="permlab_writeApnSettings" msgid="505660159675751896">"ປ່ຽນ/ສະກັດກັ້ນການຕັ້ງຄ່າເຄືອຂ່າຍ ແລະຂໍ້ມູນ"</string>
+    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"ອະນຸຍາດໃຫ້ແອັບຯປ່ຽນການຕັ້ງຄ່າເຄືອຂ່າຍ ແລະສະກັດກັ້ນ ແລະກວດສອບການເດີນທາງຂອງຂໍ້ມູນທັງໝົດ, ຍົກຕົວຢ່າງ: ໃນການປ່ຽນພອດຂອງ Proxy ຂອງ APN ໃດກໍຕາມ. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດຕິດຕາມ, ປ່ຽນແປງ ແລະແກ້ໄຂແພັກເກັດຂອງທ່ານໂດຍທີ່ທ່ານບໍ່ຮູ້ໂຕ."</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_changeBackgroundDataSetting" msgid="1400666012671648741">"ປ່ຽນການຕັ້ງຄ່າການນຳໃຊ້ຂໍ້ມູນພື້ນຫຼັງ"</string>
+    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"ອະນຸຍາດໃຫ້ແອັບຯປ່ຽນການຕັ້ງຄ່າການໃຊ້ອິນເຕີເນັດ ຂອງແອັບຯທີ່ເຮັດວຽກຢູ່ດ້ານຫຼັງລະບົບ."</string>
+    <string name="permlab_accessWifiState" msgid="5202012949247040011">"ເບິ່ງການເຊື່ອມຕໍ່ Wi-Fi"</string>
+    <string name="permdesc_accessWifiState" msgid="5002798077387803726">"ອະນຸຍາດໃຫ້ແອັບຯເບິ່ງຂໍ້ມູນກ່ຽວກັບເຄືອຂ່າຍ Wi-Fi ເຊັ່ນວ່າ WiFi ກຳລັງຖືກນຳໃຊ້ຢູ່ບໍ່ ແລະຊື່ຂອງອຸປະກອນ WiFi ທີ່ກຳລັງເຊື່ອມຕໍ່ຢູ່."</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 Multicast"</string>
+    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"ອະນຸຍາດໃຫ້ແອັບຯຮັບຂໍ້ມູນແພັກເກັດ ທີ່ຖືກສົ່ງ ໄປຫາທຸກອຸປະກອນໃນເຄືອຂ່າຍ WiFi ໂດຍການນຳໃຊ້ການກະຈາຍຂໍ້ມູນໃນວົງກວ້າງ, ບໍ່ແມ່ນສະເພາະແທັບເລັດຂອງທ່ານ. ມັນໃຊ້ພະລັງງານຫຼາຍກວ່າໂຫມດກະຈາຍຂໍ້ມູນແບບໂດຍກົງ."</string>
+    <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"ອະນຸຍາດໃຫ້ແອັບຯ ຮັບຂໍ້ມູນແພັກເກດທີ່ສົ່ງໄປໃຫ້ທຸກອຸປະກອນໃນເຄືອຂ່າຍ Wi-Fi ໂດຍໃຊ້ທີ່ຢູ່ multicast ບໍ່ສະເພາະພຽງໂທລະສັບຂອງທ່ານ, ເຊິ່ງຈະໃຊ້ພະລັງງານຫຼາຍກວ່າໃນໂໝດທີ່ບໍ່ແມ່ນ multicast."</string>
+    <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"ເຂົ້າເຖິງການຕັ້ງຄ່າ Bluetooth"</string>
+    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"ອະນຸຍາດໃຫ້ແອັບຯຕັ້ງຄ່າແທັບເລັດ Bluetooth ພາຍໃນ ແລະຊອກຫາ ແລະເຊື່ອມຕໍ່ໄວ້ກັບອຸປະກອນພາຍນອກ."</string>
+    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"ອະນຸຍາດໃຫ້ແອັບຯຕັ້ງຄ່າ Bluetooth ໃນໂທລະສັບ ເພື່ອຊອກຫາ ແລະການເຊື່ອມຕໍ່ກັບອຸປະກອນໄຮ້ສາຍພາຍນອກ."</string>
+    <string name="permlab_accessWimaxState" msgid="4195907010610205703">"ເຊື່ອມຕໍ່ ແລະຕັດການເຊື່ອມຕໍ່ຈາກ WiMAX"</string>
+    <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"ອະນຸຍາດໃຫ້ແອັບຯກວດເບິ່ງວ່າ WiMAX ຖືກເປີດນຳໃຊ້ຢູ່ບໍ່ ແລະຂໍ້ມູນກ່ຽວກັບເຄືອຂ່າຍ WiMAX ອື່ນໆທີ່ກຳລັງເຊື່ອມຕໍ່ຢູ່."</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"ປ່ຽນສະຖານະ WiMAX"</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"ອະນຸຍາດໃຫ້ແອັບຯເຊື່ອມຕໍ່ ແລະຕັດການເຊື່ອມຕໍ່ແທັບເລັດຈາກເຄືອຂ່າຍ 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="default" msgid="3207106324452312739">"ອະນຸຍາດໃຫ້ແອັບຯເບິ່ງການຕັ້ງຄ່າຂອງ Bluetooth ໃນໂທລະສັບ, ຮວມທັງໃຫ້ສ້າງ ແລະຮັບການເຊື່ອມຕໍ່ຈາກອຸປະກອນທີ່ຈັບຄູ່ກັນ."</string>
+    <string name="permlab_nfc" msgid="4423351274757876953">"ຄວບຄຸມ Near Field Communication"</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_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="permlab_readSyncStats" msgid="7396577451360202448">"ອ່ານສະຖິຕິການຊິ້ງຂໍ້ມູນ"</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"ອະນຸຍາດໃຫ້ແອັບຯ ອ່ານສະຖິຕິການຊິ້ງຂໍ້ມູນຂອງບັນຊີໃດນຶ່ງ ຮວມທັງປະຫວັດການຊິ້ງຂໍ້ມູນ ແລະຈຳນວນຂໍ້ມູນທີ່ຖືກຊິ້ງ."</string>
+    <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"ອ່ານຂໍ້ມູນຟີດທີ່ສະໝັກໄວ້"</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"ອະນຸຍາດໃຫ້ແອັບຯ ດຶງລາຍລະອຽດກ່ຽວກັບຂໍ້ມູນທີ່ກຳລັງຊິ້ງຢູ່."</string>
+    <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"ຂຽນຂໍ້ມູນຟີດທີ່ສະໝັກໄວ້"</string>
+    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"ອະນຸຍາດໃຫ້ແອັບຯ ແກ້ໄຂຟີດທີ່ຖືກຊິ້ງຂໍ້ມູນເມື່ອໄວໆນີ້ຂອງທ່ານ. ແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດປ່ຽນແປງຟີດຂອງທ່ານທີ່ຊິ້ງມາ."</string>
+    <string name="permlab_readDictionary" msgid="4107101525746035718">"ອ່ານຄຳສັບທີ່ທ່ານເພີ່ມໃສ່ວັດຈະນານຸກົມ"</string>
+    <string name="permdesc_readDictionary" msgid="659614600338904243">"ອະນຸຍາດແອັບຯອ່ານຄຳສັບ, ຊື່ ແລະປະໂຫຍກທັງໝົດທີ່ຜູ່ໃຊ້ອາດບັນທຶກໄວ້ໃນວັດຈະນານຸກົມຜູ່ໃຊ້."</string>
+    <string name="permlab_writeDictionary" msgid="2183110402314441106">"ເພີ່ມຄຳສັບໃສ່ວັດຈະນານຸກົມທີ່ຜູ່ໃຊ້ກຳນົດເອງ"</string>
+    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"ອະນຸຍາດໃຫ້ແອັບຯຂຽນຄຳສັບໃໝ່ ໃສ່ວັດຈະນານຸກົມຜູ່ໃຊ້."</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"ທົດສອບການເຂົ້າເຖິງບ່ອນຈັດເກັບຂໍ້ມູນທີ່ຖືກປ້ອງກັນໄວ້"</string>
+    <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"ທົດສອບການເຂົ້າເຖິງບ່ອນຈັດເກັບຂໍ້ມູນທີ່ຖືກປ້ອງກັນໄວ້"</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"ອະນຸຍາດໃຫ້ແອັບຯທົດສອບການອະນຸຍາດຂອງ ບ່ອນຈັດເກັບຂໍ້ມູນ USB ເຊິ່ງຈະຖືກໃຊ້ໃນອຸປະກອນໃນອະນາຄົດ."</string>
+    <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"ອະນຸຍາດໃຫ້ແອັບຯ ທົດລອງສິດໃດນຶ່ງສຳລັບ SD card ທີ່ຈະມີໃນອຸປະກອນໃນອະນາຄົດ."</string>
+    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"ແກ້ໄຂ ຫຼືລຶບເນື້ອຫາໃນບ່ອນຈັດເກັບຂໍ້ມູນ USB ຂອງທ່ານ"</string>
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"ແກ້ໄຂ ຫຼືລຶບເນື້ອຫາຂອງ SD card ຂອງທ່ານ"</string>
+    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"ອະນຸຍາດໃຫ້ແອັບຯຂຽນຂໍ້ມູນໃສ່ບ່ອນຈັດເກັບຂໍ້ມູນ USB."</string>
+    <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"ອະນຸຍາດໃຫ້ແອັບຯຂຽນຂໍ້ມູນລົງໃນ SD card ໄດ້."</string>
+    <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"ແກ້ໄຂ/ລຶບ ເນື້ອຫາບ່ອນຈັດເກັບສື່ພາຍໃນ"</string>
+    <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"ອະນຸຍາດໃຫ້ແອັບຯແກ້ໄຂເນື້ອຫາຂອງໂຕເກັບຂໍ້ມູນໃນໂຕເຄື່ອງ."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"ຈັດການພື້ນທີ່ຈັດເກັບເອກະສານ"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"ອະນຸຍາດໃຫ້ແອັບຯຈັດການກັບບ່ອນຈັດເກັບຂໍ້ມູນເອກະສານ."</string>
+    <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"ເຂົ້າເຖິງພື້ນທີ່ຈັດເກັບຂໍ້ມູນພາຍນອກຂອງທຸກຜູ່ໃຊ້"</string>
+    <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"ອະນຸຍາດໃຫ້ແອັບຯ ເຂົ້າເຖິງພື້ນທີ່ຈັດເກັບຂໍ້ມູນພາຍນອກ ສຳລັບທຸກຜູ່ໃຊ້."</string>
+    <string name="permlab_cache_filesystem" msgid="5656487264819669824">"ເຂົ້າເຖິງໄຟລ໌ cache ຂອງລະບົບ"</string>
+    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"ອະນຸຍາດໃຫ້ແອັບຯ ອ່ານ ແລະຂຽນ ລະບົບໄຟລ໌ແຄດ."</string>
+    <string name="permlab_use_sip" msgid="5986952362795870502">"ສົ່ງ/ຮັບ ການໂທຜ່ານອິນເຕີເນັດ"</string>
+    <string name="permdesc_use_sip" msgid="4717632000062674294">"ອະນຸຍາດໃຫ້ແອັບຯ ໃຊ້ບໍລິການ SIP ເພື່ອ ໂທອອກ/ຮັບສາຍ ການໂທຜ່ານອິນເຕີເນັດ."</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_markNetworkSocket" msgid="3658527214914959749">"ດັດ​ແປງຊັອກເກັດມາກ"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"ອະ​ນຸ​ຍາດ​ໃຫ້ແອັບຯແກ້ໄຂຊັອກເກັດທີ່ໝາຍໄວ້ສຳລັບກຳນົດເສັ້ນທາງ"</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_invokeCarrierSetup" msgid="3699600833975117478">"ຮ້ອງຂໍແອັບຯປັບຄ່າທີ່ສະໜອງໂດຍຜູ່ໃຫ້ບໍລິການ"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"ອະ​ນຸ​ຍາດ​ໃຫ້​ເຈົ້າຂອງຮ້ອງຂໍແອັບຯປັບຄ່າທີ່ສະໜອງໂດຍຜູ່ໃຫ້ບໍລິການ. ບໍ່ໜ້າຈະຕ້ອງການສຳລັບແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"ຕິດຕາມເພື່ອສັງເກດສະພາບຂອງເຄືອຂ່າຍ"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັ່ນຕິດຕາມເພື່ອສັງເກດສະພາບຂອງເຄືອຂ່າຍ. ປົກກະຕິແລ້ວແອັບຯທຳມະດາຈະບໍ່ຕ້ອງການໃຊ້."</string>
+    <string name="policylab_limitPassword" msgid="4497420728857585791">"ຕັ້ງຄ່າກົດຂອງລະຫັດຜ່ານ"</string>
+    <string name="policydesc_limitPassword" msgid="3252114203919510394">"ຄວບຄຸມຄວາມຍາວຂອງໂຕອັກສອນທີ່ສາມາດໃຊ້ກັບລະຫັດປົດລັອກໜ້າຈໍ"</string>
+    <string name="policylab_watchLogin" msgid="914130646942199503">"ຕິດຕາມການພະຍາຍາມປົດລັອກໜ້າຈໍ"</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"ຕິດຕາມເບິ່ງຈຳນວນການພິມລະຫັດຜ່ານທີ່ບໍ່ຖືກຕ້ອງ ໃນເວລາປົດລັອກໜ້າຈໍ ແລະລັອກແທັບເລັດ ຫຼືລຶບຂໍ້ມູນທັງໝົດຂອງແທັບເລັດ ຖ້າມີການພິມລະຫັດຜ່ານບໍ່ຖືກຕ້ອງຫຼາຍເທື່ອເກີນໄປ."</string>
+    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"ຕິດຕາມເບິ່ງຈຳນວນການພິມລະຫັດຜ່ານບໍ່ຖືກຕ້ອງ ໃນເວລາປົດລັອກໜ້າຈໍ ແລະລັອກໂທລະສັບ ຫຼືລຶບຂໍ້ມູນທັງໝົດຂອງໂປລະສັບ ຖ້າມີການພິມລະຫັດຜ່ານບໍ່ຖືກຕ້ອງຫຼາຍເທື່ອເກີນໄປ."</string>
+    <string name="policylab_resetPassword" msgid="2620077191242688955">"ປ່ຽນລະຫັດລັອກໜ້າຈໍ"</string>
+    <string name="policydesc_resetPassword" msgid="605963962301904458">"ປ່ຽນລະຫັດປົດລັອກໜ້າຈໍ"</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="default" msgid="5096895604574188391">"ລຶບຂໍ້ມູນຂອງໂທລະສັບໂດຍບໍ່ມີການເຕືອນ ໂດຍການຣີເຊັດກັບຄືນໃຫ້ເປັນແບບທີ່ມາຈາກໂຮງງານ."</string>
+    <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"ປ່ຽນ proxy ຮວມຂອງອຸປະກອນ"</string>
+    <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"ຕັ້ງໃຫ້ພຣັອກຊີສ່ວນກາງຂອງອຸປະກອນ ທີ່ຈະໃຊ້ໃນຂະນະທີ່ເປີດນຳໃຊ້ນະໂຍບາຍ. ສະເເພາະຜູ່ເບິ່ງແຍງອຸປະກອນຄົນທຳອິດເທົ່ານັ້ນ ທີ່ຈະຕັ້ງຄ່າພຣັອກຊີສ່ວນກາງທີ່ມີຜົນນຳໃຊ້ໄດ້."</string>
+    <string name="policylab_expirePassword" msgid="885279151847254056">"ຕັ້ງວັນໝົດກຳນົດຂອງລະຫັດລັອກໜ້າຈໍ"</string>
+    <string name="policydesc_expirePassword" msgid="1729725226314691591">"ຄວບຄຸມຄວາມຖີ່ໃນການປ່ຽນລະຫັດໜ້າຈໍລັອກ."</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="policylab_disableKeyguardFeatures" msgid="266329104542638802">"ປິດການນຳໃຊ້ການລັອກປຸ່ມ"</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="3467082272186534614">"ປ້ອງກັນການໃຊ້ຄວາມສາມາດບາງສ່ວນໃນການລັອກປຸ່ມ."</string>
+  <string-array name="phoneTypes">
+    <item msgid="8901098336658710359">"ເຮືອນ"</item>
+    <item msgid="869923650527136615">"ມືຖື"</item>
+    <item msgid="7897544654242874543">"ວຽກ"</item>
+    <item msgid="1103601433382158155">"ແຟັກບ່ອນເຮັດວຽກ"</item>
+    <item msgid="1735177144948329370">"ແຟັກເຮືອນ"</item>
+    <item msgid="603878674477207394">"ເພກເຈີ"</item>
+    <item msgid="1650824275177931637">"ອື່ນໆ"</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>
+  </string-array>
+  <string-array name="postalAddressTypes">
+    <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="1359644565647383708">"ບ່ອນເຮັດວຽກ"</item>
+    <item msgid="7868549401053615677">"ອື່ນໆ"</item>
+    <item msgid="3145118944639869809">"ກຳນົດເອງ"</item>
+  </string-array>
+  <string-array name="organizationTypes">
+    <item msgid="7546335612189115615">"ບ່ອນເຮັດວຽກ"</item>
+    <item msgid="4378074129049520373">"ອື່ນໆ"</item>
+    <item msgid="3455047468583965104">"ກຳນົດເອງ"</item>
+  </string-array>
+  <string-array name="imProtocols">
+    <item msgid="8595261363518459565">"AIM"</item>
+    <item msgid="7390473628275490700">"Windows Live"</item>
+    <item msgid="7882877134931458217">"Yahoo"</item>
+    <item msgid="5035376313200585242">"Skype"</item>
+    <item msgid="7532363178459444943">"QQ"</item>
+    <item msgid="3713441034299660749">"Google Talk"</item>
+    <item msgid="2506857312718630823">"ICQ"</item>
+    <item msgid="1648797903785279353">"Jabber"</item>
+  </string-array>
+    <string name="phoneTypeCustom" msgid="1644738059053355820">"ກຳນົດເອງ"</string>
+    <string name="phoneTypeHome" msgid="2570923463033985887">"ເຮືອນ"</string>
+    <string name="phoneTypeMobile" msgid="6501463557754751037">"ມືຖື"</string>
+    <string name="phoneTypeWork" msgid="8863939667059911633">"ບ່ອນເຮັດວຽກ"</string>
+    <string name="phoneTypeFaxWork" msgid="3517792160008890912">"ແຟັກບ່ອນເຮັດວຽກ"</string>
+    <string name="phoneTypeFaxHome" msgid="2067265972322971467">"ແຟັກເຮືອນ"</string>
+    <string name="phoneTypePager" msgid="7582359955394921732">"ເພກເຈີ"</string>
+    <string name="phoneTypeOther" msgid="1544425847868765990">"ອື່ນໆ"</string>
+    <string name="phoneTypeCallback" msgid="2712175203065678206">"ໂທກັບ"</string>
+    <string name="phoneTypeCar" msgid="8738360689616716982">"ລົດ"</string>
+    <string name="phoneTypeCompanyMain" msgid="540434356461478916">"ເບີໂທຫຼັກບໍລິສັດ"</string>
+    <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string>
+    <string name="phoneTypeMain" msgid="6766137010628326916">"ຫຼັກ"</string>
+    <string name="phoneTypeOtherFax" msgid="8587657145072446565">"ແຟັກອື່ນໆ"</string>
+    <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="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="eventTypeBirthday" msgid="2813379844211390740">"ວັນເດືອນປີເກີດ"</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>
+    <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="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="imTypeWork" msgid="1371489290242433090">"ວຽກ"</string>
+    <string name="imTypeOther" msgid="5377007495735915478">"ອື່ນໆ"</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>
+    <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
+    <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</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>
+    <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="relationTypeAssistant" msgid="6274334825195379076">"ຜູ່ຊ່ວຍ"</string>
+    <string name="relationTypeBrother" msgid="8757913506784067713">"ອ້າຍ-ນ້ອງ"</string>
+    <string name="relationTypeChild" msgid="1890746277276881626">"ລູກ"</string>
+    <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"ຮຸ້ນສ່ວນພາຍໃນ"</string>
+    <string name="relationTypeFather" msgid="5228034687082050725">"ພໍ່"</string>
+    <string name="relationTypeFriend" msgid="7313106762483391262">"ໝູ່ເພື່ອນ"</string>
+    <string name="relationTypeManager" msgid="6365677861610137895">"ຜູ່ຈັດການ"</string>
+    <string name="relationTypeMother" msgid="4578571352962758304">"ແມ່"</string>
+    <string name="relationTypeParent" msgid="4755635567562925226">"ພໍ່ແມ່"</string>
+    <string name="relationTypePartner" msgid="7266490285120262781">"ຮຸ້ນສ່ວນ"</string>
+    <string name="relationTypeReferredBy" msgid="101573059844135524">"ແນະນຳໂດຍ"</string>
+    <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="sipAddressTypeHome" msgid="6093598181069359295">"ເຮືອນ"</string>
+    <string name="sipAddressTypeWork" msgid="6920725730797099047">"ບ່ອນເຮັດວຽກ"</string>
+    <string name="sipAddressTypeOther" msgid="4408436162950119849">"ອື່ນໆ"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"ພິມລະຫັດ PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"ພິມລະຫັດ PUK ແລະ​ລະ​ຫັດ PIN ອັນໃໝ່"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"ລະ​ຫັດ PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"ລະຫັດ PIN ໃໝ່"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><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">"ພິມລະຫັດ PIN ເພື່ອປົດລັອກ"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"ລະຫັດ PIN ບໍ່ຖືກຕ້ອງ."</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="8963839242565653192">"ບໍ່ມີບໍລິການ."</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="5347633784401285225">"ໂທສຸກເສີນ"</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="faceunlock_multiple_failures" msgid="754137583022792429">"ຄວາມພະຍາຍາມປົດລັອກດ້ວຍໜ້ານັ້ນ ເກີນຈຳນວນທີ່ກຳນົດແລ້ວ"</string>
+    <string name="lockscreen_plugged_in" msgid="8057762828355572315">"ກຳລັງສາກ <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_charged" msgid="321635745684060624">"ສາກເຕັມແລ້ວ."</string>
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_low_battery" msgid="1482873981919249740">"ເຊື່ອມຕໍ່ສາຍສາກຂອງທ່ານ."</string>
+    <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"ບໍ່ມີ SIM card."</string>
+    <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"ບໍ່ມີຊິມກາດໃນແທັບເລັດ."</string>
+    <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"ບໍ່ມີ SIM card ໃນໂທລະສັບ."</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">"SIM card ບໍ່ສາມາດໃຊ້ໄດ້."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"ຊິມກາດຂອງທ່ານຖືກປິດການນຳໃຊ້ຢ່າງຖາວອນແລ້ວ.\n ກະລຸນາຕິດຕໍ່ຜູ່ໃຫ້ບໍລິການໂທລະສັບຂອງທ່ານ ເພື່ອຂໍເອົາຊິມກາດໃໝ່."</string>
+    <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"ປຸ່ມເພງກ່ອນໜ້ານີ້"</string>
+    <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"ປຸ່ມເພງຕໍ່ໄປ"</string>
+    <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"ປຸ່ມຢຸດຊົ່ວຄາວ"</string>
+    <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"ປຸ່ມຫຼິ້ນ"</string>
+    <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"ປຸ່ມຢຸດ"</string>
+    <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">"SIM card ຖືກລັອກດ້ວຍລະຫັດ PUK."</string>
+    <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"ເບິ່ງຄູ່ມືຜູ່ໃຊ້ ຫຼືຕິດຕໍ່ສູນບໍລິການລູກຄ້າ."</string>
+    <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM card ຖືກລັອກ."</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">%d</xliff:g> ເທື່ອແລ້ວ. \n\nລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ວິນາທີ."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"ທ່ານພິມລະຫັດຜ່ານຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. \n\nໃຫ້ລອງໃໝ່ອີກຄັ້ງໃນອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ວິນາທີ."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"ທ່ານພິມລະຫັດ PIN ຂອງທ່ານຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. \n\nລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ວິນາທີ."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"ທ່ານແຕ້ມຮູບແບບປົດລັອກຂອງທ່ານຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກຄວາມພະຍາຍາມອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ເທື່ອ ທ່ານຈະຖືກຖາມໃຫ້ປົດລັອກແທັບເລັດຂອງທ່ານ ດ້ວຍການເຂົ້າສູ່ລະບົບຂອງ Google.\n\n ລອງໃໝ່ອີກຄັ້ງໃນ <xliff:g id="NUMBER_2">%d</xliff:g> ວິນາທີ."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"ທ່ານແຕ້ມຮູບແບບປົດລັອກຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກແຕ້ມຜິດອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ເທື່ອ, ທ່ານຈະຖືກຖາມໃຫ້ປົດລັອກໂທລະສັບຂອງທ່ານ ດ້ວຍການເຂົ້າສູ່ລະບົບ Google.\n\n ລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_2">%d</xliff:g> ວິນາທີ."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"ທ່ານພະຍາຍາມປັດລັອກແທັບເລັດຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກຜິດອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ເທື່ອ, ແທັບເລັດຈະຖືກຣີເຊັດໃຫ້ເປັນແບບທີ່ມາຈາກໂຮງງານ ແລະຂໍ້ມູນທັງໝົດຈະຖືກຫາຍໄປ."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"ທ່ານໄດ້ພະຍາຍາມປົດລັອກໂທລະສັບເປັນຈຳນວນ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກການພະຍາຍາມອີກ <xliff:g id="NUMBER_1">%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="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_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_checking_password" msgid="7114627351286933867">"ກຳລັງກວດສອບ..."</string>
+    <string name="lockscreen_unlock_label" msgid="737440483220667054">"ປົດລັອກ"</string>
+    <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"ເປີດສຽງແລ້ວ"</string>
+    <string name="lockscreen_sound_off_label" msgid="996822825154319026">"ປິດສຽງ"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"ຮູບແບບເລີ່ມຕົ້ນແລ້ວ"</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"ລຶບລ້າງຮູບແບບແລ້ວ"</string>
+    <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"ຕາລາງຖືກເພີ່ມແລ້ວ"</string>
+    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"ຮູບແບບສຳເລັດແລ້ວ"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. ວິດເຈັດ %2$d ຈາກທັງໝົດ %3$d."</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_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>
+    <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_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">"ປົດລັອກດ້ວຍ PIN."</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>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <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_line" msgid="5764267235026120888">"ເສັ້ນ"</string>
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
+    <string name="factorytest_failed" msgid="5410270329114212041">"ການທົດສອບຈາກໂຮງງານລົ້ມເຫລວ"</string>
+    <string name="factorytest_not_system" msgid="4435201656767276723">"ການເຮັດ FACTORY_TEST ຮອງຮັບສະເພາະແພັກເກດທີ່ຖືກຕິດຕັ້ງໃນ /system/app ເທົ່ານັ້ນ."</string>
+    <string name="factorytest_no_action" msgid="872991874799998561">"ບໍ່ພົບແພັກເກດທີ່ມີການເຮັດວຽກ FACTORY_TEST."</string>
+    <string name="factorytest_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="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>
+    <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
+    <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
+    <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
+    <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
+    <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">"ລະຫັດ ZIP"</string>
+    <string name="autofill_county" msgid="237073771020362891">"ປະເທດ"</string>
+    <string name="autofill_island" msgid="4020100875984667025">"ເກາະ"</string>
+    <string name="autofill_district" msgid="8400735073392267672">"ເມືອງ"</string>
+    <string name="autofill_department" msgid="5343279462564453309">"ພະແນກ"</string>
+    <string name="autofill_prefecture" msgid="2028499485065800419">"ເຂດປົກຄອງ"</string>
+    <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="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_packageVerificationAgent" msgid="5568139100645829117">"ຢັ້ງຢືນແພັກເກດ"</string>
+    <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"ອະນຸຍາດໃຫ້ແອັບຯຢືນຢັນວ່າແພັກເກດໃດນຶ່ງ ສາມາດຕິດຕັ້ງໄດ້."</string>
+    <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"ເຊື່ອມໂຍງກັບໂຕຢືນຢັນແພັກເກດ"</string>
+    <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງເຮັດການຮ້ອງຂໍໂຕຢືນຢັນແພັກເກັດ. ບໍ່ຈຳເປັນສຳລັບແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_serialPort" msgid="546083327654631076">"ເຂົ້າເຖິງພອດຊີຣຽວ"</string>
+    <string name="permdesc_serialPort" msgid="2991639985224598193">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງສາມາດເຂົ້າເບິ່ງ serial ports ໂດຍການນຳໃຊ້ SerialManager API."</string>
+    <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"ເຂົ້າເຖິງຜູ່ສະໜອງເນື້ອຫາພາຍນອກ"</string>
+    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"ຊ່ວຍໃຫ້ເຈົ້າຂອງສາມາດ ເຂົ້າເຖິງຜູ່ໃຫ້ບໍລິການເນື້ອຫາຈາກໜ້າ shell ໄດ້. ແອັບພລິເຄຊັນທົ່ວໄປບໍ່ຄວນຈຳເປັນຕ້ອງໃຊ້."</string>
+    <string name="permlab_updateLock" msgid="3527558366616680889">"ປ້ອງກັນການອັບເດດອຸປະກອນໂດຍອັດຕະໂນມັດ"</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງກຳນົດຂໍ້ມູນໃນລະບົບ ກ່ຽວກັບເວລາທີ່ເໝາະສົມໃນການຣີບູດແບບບໍ່ໂຕ້ຕອບ ເພື່ອອັບເກຣດອຸປະກອນ."</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>
+    <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="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="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="oneMonthDurationPast" msgid="7396384508953779925">"1 ເດືອນກ່ອນຫນ້ານີ້"</string>
+    <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"ຫຼາຍກວ່າ 1 ເດືອນກ່ອນ"</string>
+  <plurals name="num_seconds_ago">
+    <item quantity="one" msgid="4869870056547896011">"1 ວິນາທີກ່ອນ"</item>
+    <item quantity="other" msgid="3903706804349556379">"<xliff:g id="COUNT">%d</xliff:g> ວິນາທີກ່ອນໜ້ານີ້"</item>
+  </plurals>
+  <plurals name="num_minutes_ago">
+    <item quantity="one" msgid="3306787433088810191">"1 ນາທີກ່ອນໜ້ານີ້"</item>
+    <item quantity="other" msgid="2176942008915455116">"<xliff:g id="COUNT">%d</xliff:g> ນາ​ທີ​ທີ່ຜ່ານມາ"</item>
+  </plurals>
+  <plurals name="num_hours_ago">
+    <item quantity="one" msgid="9150797944610821849">"1 ຊົ່ວໂມງກ່ອນໜ້ານີ້"</item>
+    <item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> ຊົ່ວໂມງທີ່ຜ່ານມາ"</item>
+  </plurals>
+  <plurals name="last_num_days">
+    <item quantity="other" msgid="3069992808164318268">"<xliff:g id="COUNT">%d</xliff:g> ມື້ທີ່ຜ່ານມາ"</item>
+  </plurals>
+    <string name="last_month" msgid="3959346739979055432">"ເດືອນແລ້ວ"</string>
+    <string name="older" msgid="5211975022815554840">"ເກົ່າກວ່າ"</string>
+  <plurals name="num_days_ago">
+    <item quantity="one" msgid="861358534398115820">"ມື້​ວານ​ນີ້"</item>
+    <item quantity="other" msgid="2479586466153314633">"<xliff:g id="COUNT">%d</xliff:g> ມື້​ກ່ອນ"</item>
+  </plurals>
+  <plurals name="in_num_seconds">
+    <item quantity="one" msgid="2729745560954905102">"ໃນອີກ 1 ວິນາທີ"</item>
+    <item quantity="other" msgid="1241926116443974687">"ໃນ <xliff:g id="COUNT">%d</xliff:g> ວິ​ນາ​ທີ"</item>
+  </plurals>
+  <plurals name="in_num_minutes">
+    <item quantity="one" msgid="8793095251325200395">"ໃນ 1 ນາທີ"</item>
+    <item quantity="other" msgid="3330713936399448749">"ໃນ <xliff:g id="COUNT">%d</xliff:g> ນາທີ"</item>
+  </plurals>
+  <plurals name="in_num_hours">
+    <item quantity="one" msgid="7164353342477769999">"ໃນ 1 ຊົ່ວໂມງ"</item>
+    <item quantity="other" msgid="547290677353727389">"ໃນ <xliff:g id="COUNT">%d</xliff:g> ຊົ່ວໂມງ"</item>
+  </plurals>
+  <plurals name="in_num_days">
+    <item quantity="one" msgid="5413088743009839518">"ມື້ອື່ນ"</item>
+    <item quantity="other" msgid="5109449375100953247">"ໃນ <xliff:g id="COUNT">%d</xliff:g> ມື້"</item>
+  </plurals>
+  <plurals name="abbrev_num_seconds_ago">
+    <item quantity="one" msgid="1849036840200069118">"1 ວິນາທີກ່ອນ"</item>
+    <item quantity="other" msgid="3699169366650930415">"<xliff:g id="COUNT">%d</xliff:g> ວິ ກ່ອນໜ້ານີ້"</item>
+  </plurals>
+  <plurals name="abbrev_num_minutes_ago">
+    <item quantity="one" msgid="6361490147113871545">"1 ນທ ກ່ອນ"</item>
+    <item quantity="other" msgid="851164968597150710">"<xliff:g id="COUNT">%d</xliff:g> ນທ ກ່ອນໜ້ານີ້"</item>
+  </plurals>
+  <plurals name="abbrev_num_hours_ago">
+    <item quantity="one" msgid="4796212039724722116">"1 ຊົ່ວໂມງກ່ອນ"</item>
+    <item quantity="other" msgid="6889970745748538901">"<xliff:g id="COUNT">%d</xliff:g> ຊົ່ວໂມງກ່ອນໜ້ານີ້"</item>
+  </plurals>
+  <plurals name="abbrev_num_days_ago">
+    <item quantity="one" msgid="8463161711492680309">"ມື້ວານນີ້"</item>
+    <item quantity="other" msgid="3453342639616481191">"<xliff:g id="COUNT">%d</xliff:g> ມື້ກ່ອນໜ້ານີ້"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_seconds">
+    <item quantity="one" msgid="5842225370795066299">"ໃນ 1 ວິ"</item>
+    <item quantity="other" msgid="5495880108825805108">"ໃນ <xliff:g id="COUNT">%d</xliff:g> ວິ"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_minutes">
+    <item quantity="one" msgid="562786149928284878">"ໃນ 1 ນາທີ"</item>
+    <item quantity="other" msgid="4216113292706568726">"ໃນ <xliff:g id="COUNT">%d</xliff:g> ນທ"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_hours">
+    <item quantity="one" msgid="3274708118124045246">"ໃນ 1 ຊົ່ວໂມງ"</item>
+    <item quantity="other" msgid="3705373766798013406">"ໃນ <xliff:g id="COUNT">%d</xliff:g> ຊົ່ວໂມງ"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_days">
+    <item quantity="one" msgid="2178576254385739855">"ມື້ອື່ນ"</item>
+    <item quantity="other" msgid="2973062968038355991">"ໃນ <xliff:g id="COUNT">%d</xliff:g> ມື້"</item>
+  </plurals>
+    <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>
+    <string name="days" msgid="4774547661021344602">"ມື້"</string>
+    <string name="hour" msgid="2126771916426189481">"ຊົ່ວໂມງ"</string>
+    <string name="hours" msgid="894424005266852993">"ຊົ່ວໂມງ"</string>
+    <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="week" msgid="5617961537173061583">"ອາທິດ"</string>
+    <string name="weeks" msgid="6509623834583944518">"ອາທິດ"</string>
+    <string name="year" msgid="4001118221013892076">"ປີ"</string>
+    <string name="years" msgid="6881577717993213522">"ປິ"</string>
+  <plurals name="duration_seconds">
+    <item quantity="one" msgid="6962015528372969481">"1 ວິນາທີ"</item>
+    <item quantity="other" msgid="1886107766577166786">"<xliff:g id="COUNT">%d</xliff:g> ວິນາທີ"</item>
+  </plurals>
+  <plurals name="duration_minutes">
+    <item quantity="one" msgid="4915414002546085617">"1 ນາ​ທີ"</item>
+    <item quantity="other" msgid="3165187169224908775">"<xliff:g id="COUNT">%d</xliff:g> ນາທີ"</item>
+  </plurals>
+  <plurals name="duration_hours">
+    <item quantity="one" msgid="8917467491248809972">"1 ຊົ່ວ​ໂມງ"</item>
+    <item quantity="other" msgid="3863962854246773930">"<xliff:g id="COUNT">%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_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>
+    <string name="midnight" msgid="7166259508850457595">"ທ່ຽງຄືນ"</string>
+    <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="cut" msgid="3092569408438626261">"ຕັດ"</string>
+    <string name="copy" msgid="2681946229533511987">"ສຳເນົາ"</string>
+    <string name="paste" msgid="5629880836805036433">"ວາງ"</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="textSelectionCABTitle" msgid="5236850394370820357">"ການເລືອກຂໍ້ຄວາມ"</string>
+    <string name="addToDictionary" msgid="4352161534510057874">"ເພີ່ມໄປທີ່ວັດຈະນານຸກົມ"</string>
+    <string name="deleteText" msgid="6979668428458199034">"ລຶບ"</string>
+    <string name="inputMethod" msgid="1653630062304567879">"ຮູບແບບການປ້ອນຂໍ້ມູນ"</string>
+    <string name="editTextMenuTitle" msgid="4909135564941815494">"ການເຮັດວຽກຂອງຂໍ້ຄວາມ"</string>
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"ພື້ນທີ່ຈັດເກັບຂໍ້ມູນກຳລັງຈະເຕັມ"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"ການເຮັດວຽກບາງຢ່າງຂອງລະບົບບາງອາດຈະໃຊ້ບໍ່ໄດ້"</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="4653586947747330058">"ແຕະເພື່ອເບິ່ງຂໍ້ມູນເພີ່ມເຕີມ ຫຼືເພື່ອຢຸດການເຮັດວຽກຂອງແອັບຯນີ້."</string>
+    <string name="ok" msgid="5970060430562524910">"ຕົກລົງ"</string>
+    <string name="cancel" msgid="6442560571259935130">"ຍົກເລີກ"</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>
+    <string name="capital_on" msgid="1544682755514494298">"ເປີດ"</string>
+    <string name="capital_off" msgid="6815870386972805832">"ປິດ"</string>
+    <string name="whichApplication" msgid="4533185947064773386">"ເຮັດວຽກໃຫ້ສຳເລັດໂດຍໃຊ້"</string>
+    <string name="alwaysUse" msgid="4583018368000610438">"ໃຊ້ໂດຍຄ່າເລີ່ມຕົນສຳລັບການເຮັດວຽກນີ້."</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="aerr_title" msgid="1905800560317137752"></string>
+    <string name="aerr_application" msgid="932628488013092776">"ຂໍອະໄພ, <xliff:g id="APPLICATION">%1$s</xliff:g> ຢຸດການເຮັດວຽກແລ້ວ."</string>
+    <string name="aerr_process" msgid="4507058997035697579">"ຂໍອະໄພ, ໂປຣເຊສ <xliff:g id="PROCESS">%1$s</xliff:g> ໄດ້ຢຸດການເຮັດວຽກແລ້ວ."</string>
+    <string name="anr_title" msgid="4351948481459135709"></string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> ບໍ່ຕອບສະໜອງ. \n\nທ່ານຕ້ອງການປິດມັນບໍ່?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"ການເຮັດວຽກ <xliff:g id="ACTIVITY">%1$s</xliff:g> ບໍ່ຕອບສະໜອງ. \n\n ທ່ານຕ້ອງການທີ່ຈະປິດມັນບໍ່?"</string>
+    <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> ບໍ່ຕອບສະໜອງ. ທ່ານຕ້ອງການປິດມັນບໍ່?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"ໂປຣເຊສ <xliff:g id="PROCESS">%1$s</xliff:g> ບໍ່ຕອບສະໜອງ. \n\n ທ່ານຕ້ອງການປິດມັນບໍ່?"</string>
+    <string name="force_close" msgid="8346072094521265605">"ຕົກລົງ"</string>
+    <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_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; ແອັບຯ &gt; ດາວໂຫລດແລ້ວ"</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>
+    <string name="android_upgrading_title" msgid="1584192285441405746">"ກຳລັງອັບເກຣດ Android..."</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_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="1721681741617898865">"ແຕະເພື່ອສະລັບກັບໄປຫາແອັບຯ"</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>
+    <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="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_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_notification" msgid="7044986546477282274">"ລະດັບສຽງການແຈ້ງເຕືອນ"</string>
+    <string name="ringtone_default" msgid="3789758980357696936">"ຣິງໂທນເລີ່ມຕົ້ນ"</string>
+    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"ຣິງໂທນເລີ່ມຕົ້ນ (<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_unknown" msgid="5477919988701784788">"ຣິງໂທນທີ່ບໍ່ຮູ້ຈັກ"</string>
+  <plurals name="wifi_available">
+    <item quantity="one" msgid="6654123987418168693">"ເຄືອຂ່າຍ Wi-Fi ທີ່ພົບ"</item>
+    <item quantity="other" msgid="4192424489168397386">"ມີເຄືອຂ່າຍ Wi​-Fi ໃຫ້ໃຊ້"</item>
+  </plurals>
+  <plurals name="wifi_available_detailed">
+    <item quantity="one" msgid="1634101450343277345">"ເປີດ Wi-Fi ເຄືອຂ່າຍທີ່ມີ"</item>
+    <item quantity="other" msgid="7915895323644292768">"ເຄືອຂ່າຍ Wi-Fi ແບບເປີດທີ່ພົບ"</item>
+  </plurals>
+    <string name="wifi_available_sign_in" msgid="4029489716605255386">"ເຂົ້າສູ່ລະບົບເຄືອຂ່າຍ Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="8495155593358054676">"ເຂົ້າສູ່ລະບົບເຄືອຂ່າຍ"</string>
+    <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
+    <skip />
+    <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"ບໍ່ສາມາດເຊື່ອມຕໍ່ Wi-Fi ໄດ້"</string>
+    <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ມີສັນຍານອິນເຕີເນັດທີ່ບໍ່ດີ."</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 client/hotspot."</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_enabled_notification_message" msgid="1638949953993894335">"ແຕະເພື່ອຕັ້ງຄ່າ"</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_to_connect_title" msgid="4958803948658533637">"ການເຊີນຊວນເພື່ອເຊື່ອມຕໍ່"</string>
+    <string name="wifi_p2p_from_message" msgid="570389174731951769">"ຈາກ:"</string>
+    <string name="wifi_p2p_to_message" msgid="248968974522044099">"ຈາກ:"</string>
+    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"ພິມລະຫັດ PIN:"</string>
+    <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"ແທັບເລັດຈະຖືກຕັດການເຊື່ອມຕໍ່ຈາກ Wi-Fi ເປັນການຊົ່ວຄາວ ໃນຂະນະທີ່ມັນເຊື່ອມຕໍ່ກັບ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ຢູ່."</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"ໂທລະສັບຈະຖືກຢຸດການເຊື່ອມຕໍ່ຊົ່ວຄາວຈາກ Wi-Fi ໃນຂະນະທີ່ມັນເຊື່ອມຕໍ່ກັບ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="select_character" msgid="3365550120617701745">"ໃສ່ໂຕອັກສອນ"</string>
+    <string name="sms_control_title" msgid="7296612781128917719">"ກຳລັງສົ່ງຂໍ້ຄວາມ 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="3492025719868078457">"ນີ້ "<font fgcolor="#ffffb060">"ອາດເຮັດໃຫ້ເກີດຄ່າໃຊ້ຈ່າຍ"</font>" ໃນບັນຊີມືຖືຂອງທ່ານໄດ້."</string>
+    <string name="sms_premium_short_code_details" msgid="5523826349105123687"><font fgcolor="#ffffb060">"ມັນຈະເຮັດໃຫ້ທ່ານເສຍຄ່າບໍລິການໃນບັນຊີຂອງທ່ານ."</font></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_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 card ອອກແລ້ວ"</string>
+    <string name="sim_removed_message" msgid="2333164559970958645">"ເຄືອຂ່າຍມືຖືຈະບໍ່ສາມາດໃຊ້ໄດ້ ຈົນກວ່າທ່ານຈະປິດແລ້ວເປີດໃໝ່ພ້ອມກັບໃສ່ SIM card ທີ່ຖືກຕ້ອງ."</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="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_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="usb_storage_activity_title" msgid="4465055157209648641">"ບ່ອນຈັດເກັບຂໍ້ມູນ USB"</string>
+    <string name="usb_storage_title" msgid="5901459041398751495">"ເຊື່ອມຕໍ່ USB ແລ້ວ"</string>
+    <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"ທ່ານໄດ້ເຊື່ອມຕໍ່ກັບຄອມພິວເຕີຂອງທ່ານຜ່ານ USB ແລ້ວ. ໃຫ້ແຕະປຸ່ມຂ້າງລຸ່ມຖ້າທ່ານຕ້ອງການສຳເນົາໄຟລ໌ ລະຫວ່າງຄອມພິວເຕີ ແລະບ່ອນຈັດເກັບຂໍ້ມູນ USB ຂອງ Android ທ່ານ."</string>
+    <string name="usb_storage_message" product="default" msgid="805351000446037811">"ທ່ານໄດ້ເຊື່ອມຕໍ່ກັບຄອມພິວເຕີຂອງທ່ານດ້ວຍ USB ແລ້ວ. ໃຫ້ປຸ່ມທາງດ້ານລຸ່ມນີ້ຫາກທ່ານຕ້ອງການ ທີ່ຈະສຳເນົາໄຟລ໌ຂໍ້ມູນລະຫວ່າງຄອມພິວເຕີ ແລະ SD card ຂອງ Android ຂອງທ່ານ."</string>
+    <string name="usb_storage_button_mount" msgid="1052259930369508235">"ເປີດ ບ່ອນຈັດເກັບຂໍ້ມູນ USB"</string>
+    <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"ມີບັນຫາໃນການໃຊ້ບ່ອນຈັດເກັບຂໍ້ມູນ USB ຂອງທ່ານເປັນບ່ອນຈັດເກັບຂໍ້ມູນຈຳນວນຫຼາຍດ້ວຍ USB."</string>
+    <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"ມີບັນຫາໃນການໃຊ້ SD card ຂອງທ່ານເປັນບ່ອນຈັດເກັບຂໍ້ມູນຈຳນວນຫຼາຍດ້ວຍ USB."</string>
+    <string name="usb_storage_notification_title" msgid="8175892554757216525">"ເຊື່ອມຕໍ່ USB ແລ້ວ"</string>
+    <string name="usb_storage_notification_message" msgid="939822783828183763">"ແຕະເພື່ອສຳເນົາໄຟລ໌ ໃສ່/ຈາກ ຄອມພິວເຕີຂອງທ່ານ."</string>
+    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"ປິດບ່ອນຈັດເກັບຂໍ້ມູນ USB"</string>
+    <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"ແຕະເພື່ອປິດ ບ່ອນຈັດເກັບຂໍ້ມູນ USB ."</string>
+    <string name="usb_storage_stop_title" msgid="660129851708775853">"ບ່ອນຈັດເກັບຂໍ້ມູນ USB ກຳລັງຖືກນຳໃຊ້ຢູ່"</string>
+    <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"ກ່ອນປິດບ່ອນຈັດເກັບຂໍ້ມູນ USB, ຖອນ (\"eject\") ບ່ອນຈັດເກັບຂໍ້ມູນ USB ຂອງ Android ຂອງທ່ານຈາກຄອມພິວເຕີຂອງທ່ານ."</string>
+    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"ກ່ອນການປິດບ່ອນຈັດເກັບຂໍ້ມູນ USB, ໃຫ້ຖອນການເຊື່ອມຕໍ່ (eject) SD card ຂອງ Android ທ່ານອອກຈາກຄອມພິວເຕີກ່ອນ."</string>
+    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"ປິດບ່ອນຈັດເກັບຂໍ້ມູນ USB"</string>
+    <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"ເກີດບັນຫາໃນການປິດບ່ອນຈັດເກັບຂໍ້ມູນ USB. ໃຫ້ກວດສອບວ່າທ່ານໄດ້ຖອນການເຊື່ອມຕໍ່ USB host ແລ້ວຫຼືຍັງ ຈາກນັ້ນຈຶ່ງລອງອີກຄັ້ງ."</string>
+    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"ເປີດໃຊ້ບ່ອນຈັດເກັບຂໍ້ມູນ USB"</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"ຫາກທ່ານເປີດນຳໃຊ້ບ່ອນຈັດເກັບຂໍ້ມູນ USB ຈະເຮັດໃຫ້ບາງແອັບຯທີ່ທ່ານເຮັດວຽກຢູ່ນັ້ນ ຢຸດເຮັດວຽກ ແລະອາດຈະບໍ່ສາມາດໃຊ້ໄດ້ຈົນກວ່າທ່ານປິດບ່ອນຈັດເກັບຂໍ້ມູນ USB ກ່ອນ."</string>
+    <string name="dlg_error_title" msgid="7323658469626514207">"ປະຕິບັດການ USB ບໍ່ສຳເລັດ"</string>
+    <string name="dlg_ok" msgid="7376953167039865701">"ຕົກລົງ"</string>
+    <string name="usb_mtp_notification_title" msgid="3699913097391550394">"ເຊື່ອມຕໍ່ເປັນອຸປະກອນສື່"</string>
+    <string name="usb_ptp_notification_title" msgid="1960817192216064833">"ເຊື່ອມຕໍ່ເປັນກ້ອງຖ່າຍຮູບແລ້ວ"</string>
+    <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"ເຊື່ອມຕໍ່ໃນນາມຕົວຕິດຕັ້ງ"</string>
+    <string name="usb_accessory_notification_title" msgid="7848236974087653666">"ເຊື່ອມຕໍ່ກັບອຸປະກອນເສີມ USB ແລ້ວ"</string>
+    <string name="usb_notification_message" msgid="2290859399983720271">"ແຕະເພື່ອເບິ່ງໂຕເລືອກເລືອກ USB ອື່ນໆ."</string>
+    <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"ຟໍແມັດ ບ່ອນຈັດເກັບຂໍ້ມູນ USB?"</string>
+    <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"ຟໍແມັດ SD card?"</string>
+    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"ໄຟລ໌ທັງໝົດທີ່ຢູ່ໃນບ່ອນຈັດເກັບຂໍ້ມູນ USB ຂອງທ່ານຈະຖືກລຶບອອກໝົດ. ການກະທຳຈະບໍ່ສາມາດຍົກເລີກໄດ້!"</string>
+    <string name="extmedia_format_message" product="default" msgid="14131895027543830">"ຂໍ້ມູນທັງໝົດໃນກາດຂອງທ່ານຈະຫາຍໄປ."</string>
+    <string name="extmedia_format_button_format" msgid="4131064560127478695">"ຟໍແມັດ"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"ເຊື່ອມຕໍ່ການດີບັ໊ກຜ່ານ USB ແລ້ວ"</string>
+    <string name="adb_active_notification_message" msgid="1016654627626476142">"ແຕະເພື່ອປິດການດີບັ໊ກຜ່ານ USB."</string>
+    <string name="select_input_method" msgid="4653387336791222978">"ເລືອກຮູບແບບການປ້ອນ"</string>
+    <string name="configure_input_methods" msgid="9091652157722495116">"ຕັ້ງຄ່າວິທີການປ້ອນຂໍ້ມູນ"</string>
+    <string name="use_physical_keyboard" msgid="6203112478095117625">"ແປ້ນພິມແທ້"</string>
+    <string name="hardware" msgid="7517821086888990278">"ຮາດແວ"</string>
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"ເລືອກຮູບແບບແປ້ນພິມ"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"ກົດເພື່ອເລືອກຮູບແບບແປ້ນພິມ."</string>
+    <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="candidates_style" msgid="4333913089637062257"><u>"ຕົວເລືອກ"</u></string>
+    <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"ກຳລັງກຽມບ່ອນຈັດເກັບຂໍ້ມູນ USB"</string>
+    <string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"ກຳລັງກະກຽມ SD card"</string>
+    <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"ກຳລັງກວດຫາຂໍ້ຜິດພາດ."</string>
+    <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"ບ່ອນຈັດເກັບຂໍ້ມູນ USB ເປົ່າຫວ່າງ"</string>
+    <string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"SD card ຫວ່າງເປົ່າ"</string>
+    <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"ບ່ອນຈັດເກັບຂໍ້ມູນ USB ຫວ່າງເປົ່າ ຫຼືມີໄຟລ໌ລະບົບທີ່ບໍ່ຮອງຮັບ."</string>
+    <string name="ext_media_nofs_notification_message" product="default" msgid="8641065641786923604">"SD card ຫວ່າງເປົ່າ ຫຼືມີລະບົບໄຟລ໌ທີ່ບໍ່ຮອງຮັບ."</string>
+    <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"ບ່ອນຈັດເກັບຂໍ້ມູນ USB ທີ່ເສຍຫາຍ."</string>
+    <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"SD card ທີ່ເສຍຫາຍ."</string>
+    <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="1795917578395333280">"ບ່ອນຈັດເກັບຂໍ້ມູນ USB ເສຍຫາຍ. ລອງຟໍແມັດມັນອີກຄັ້ງເບິ່ງ."</string>
+    <string name="ext_media_unmountable_notification_message" product="default" msgid="1753898567525568253">"SD card ເສຍຫາຍ. ລອງຟໍແມັດມັນອີກຄັ້ງເບິ່ງ."</string>
+    <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"ບ່ອນຈັດເກັບຂໍ້ມູນ USB ຖືກຖອດອອກແບບບໍ່ປອດໄພ"</string>
+    <string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"SD card ຖືກຖອດອອກໂດຍບໍ່ຄາດຄິດ"</string>
+    <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"ຖອດການເຊື່ອມຕໍ່ບ່ອນຈັດເກັບຂໍ້ມູນ USB ກ່ອນທີ່ຈະຖອດອອກ ເພື່ອປ້ອງກັນການສູນເສຍຂໍ້ມູນ."</string>
+    <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"ຖອນການເຊື່ອມຕໍ່ SD card ກ່ອນຈະຖອດອອກເພື່ອປ້ອງກັນການສູນເສຍຂໍ້ມູນ."</string>
+    <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"ບ່ອນຈັດເກັບຂໍ້ມູນ USB ສາມາດຖອດອອກໄດ້ຢ່າງປອດໄພ"</string>
+    <string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"ສາມາດຖອດ SD card ອອກໄດ້ປອດໄພແລ້ວ"</string>
+    <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"ທ່ານສາມາດຖອດບ່ອນຈັດເກັບຂໍ້ມູນ USB ອອກໄດ້ຢ່າງປອດໄພ."</string>
+    <string name="ext_media_safe_unmount_notification_message" product="default" msgid="568841278138377604">"ທ່ານສາມາດຖອດ SD card ອອກໄດ້ຢ່າງປອດໄພ."</string>
+    <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"ບ່ອນຈັດເກັບຂໍ້ມູນ USB ຖືກຖອດອອກແລ້ວ"</string>
+    <string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"SD card ຖືກຖອດອອກ"</string>
+    <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"ບ່ອນຈັດເກບັຂໍ້ມູນ USB ຖືກຖອດອອກແລ້ວ. ໃຫ້ໃສ່ອັນໃໝ່ເຂົ້າໄປ."</string>
+    <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"SD card ຖືກຖອດອອກແລ້ວ. ກະລຸນາໃສ່ອັນໃໝ່."</string>
+    <string name="activity_list_empty" msgid="1675388330786841066">"ບໍ່ພົບກິດຈະກຳທີ່ກົງກັນ."</string>
+    <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"ອັບເດດສະຖິຕິການນຳໃຊ້ອົງປະກອບ"</string>
+    <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"ອະນຸຍາດໃຫ້ແອັບຯແກ້ໄຂສະຖິຕິ ການນຳໃຊ້ຂໍ້ມູນສ່ວນປະກອບທີ່ເກັບກຳມາ. ແອັບຯທົ່ວໄປບໍ່ຈຳເປັນຕ້ອງໃຊ້."</string>
+    <string name="permlab_copyProtectedData" msgid="4341036311211406692">"ສຳເນົາເນື້ອຫາ"</string>
+    <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"ອະນຸຍາດໃຫ້ຮ້ອງຂໍບໍລິການຄອນເທັນເນີຫຼັກ ໃນການສຳເນົາເນື້ອຫາ. ບໍ່ໃຊ້ໃນແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_route_media_output" msgid="1642024455750414694">"ກຳນົດເສັ້ນທາງເອົ້າພຸດຂອງສື່"</string>
+    <string name="permdesc_route_media_output" msgid="4932818749547244346">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນ ກຳນົດເສັ້ນທາງເອົ້າພຸດຂອງສື່ໄປຫາອຸປະກອນພາຍນອກອື່ນໆ."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"ເຂົ້າໃຊ້ບ່ອນຈັດເກັບຂໍ້ມູນຄວາມປອດໄພຄີກາດ"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນ ເຂົ້າເຖິງບ່ອນຈັດເກັບຂໍ້ມູນຄວາມປອດໄພດ້ວຍຄີກາດ."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"ຄວບຄຸມການສະແດງ ແລະການເຊື່ອງໂຕລັອກປຸ່ມກົດ"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນສາມາດຄວບຄຸມຄີກາດໄດ້."</string>
+    <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"ແຕະສອງເທື່ອສຳລັບການຄວບຄຸມການຊູມ"</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>
+    <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">"ກົດເລກໝາຍ\nໂດຍໃຊ້ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"ສ້າງລາຍຊື່ຜູ່ຕິດຕໍ່\nໂດຍການໃຊ້ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"ມີນຶ່ງແອັບຯ ຫຼືຫຼາຍກວ່ານັ້ນກຳລັງຮ້ອງຂໍການອະນຸຍາດ ເພື່ອເຂົ້າເຖິງບັນຊີຂອງທ່ານໃນຕອນນີ້ ແລະອະນາຄົດ."</string>
+    <string name="grant_credentials_permission_message_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">"ຮ້ອງຂໍການກຳນົດສິດ\nສຳລັບບັນຊີ <xliff:g id="ACCOUNT">%s</xliff:g> ແລ້ວ."</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>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"ປ່ຽນພາບພື້ນຫຼັງ"</string>
+    <string name="notification_listener_binding_label" msgid="2014162835481906429">"ໂຕຟັງການແຈ້ງເຕືອນ"</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="3011306607126450322">"ແຕະເພື່ອຈັດການເຄືອຂ່າຍ."</string>
+    <string name="vpn_text_long" msgid="6407351006249174473">"ເຊື່ອມຕໍ່ຢູ່ກັບ <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_error" msgid="6009249814034708175">"VPN ແບບເປີດຕະຫຼອດເກີດຄວາມຜິດພາດ"</string>
+    <string name="vpn_lockdown_config" msgid="6415899150671537970">"ແຕະເພື່ອປັບຄ່າ"</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="8035230537563503262">"ກົດເພື່ອປິດໂຫມດຂັບລົດ."</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"ການປ່ອຍສັນຍານ ຫຼືຮັອດສະປອດທີ່ເຮັດວຽກຢູ່"</string>
+    <string name="tethered_notification_message" msgid="6857031760103062982">"ແຕະເພື່ອຕິດຕັ້ງ."</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="throttle_warning_notification_title" msgid="4890894267454867276">"ມີການໃຊ້ອິນເຕີເນັດຫຼາຍ"</string>
+    <string name="throttle_warning_notification_message" msgid="3340822228599337743">"ແຕະເພື່ອສຶກສາເພີ່ມເຕີມກ່ຽວກັບການໃຊ້ຂໍ້ມູນມືຖື."</string>
+    <string name="throttled_notification_title" msgid="6269541897729781332">"ການນຳໃຊ້ອິນເຕີເນັດຮອດຂີດຈຳກັດແລ້ວ"</string>
+    <string name="throttled_notification_message" msgid="5443457321354907181">"ແຕະເພື່ອສຶກສາເພີ່ມເຕີມກ່ຽວກັບການນຳໃຊ້ຂໍ້ມູນມືຖື."</string>
+    <string name="no_matches" msgid="8129421908915840737">"ບໍ່ພົບຜົນການຊອກຫາ"</string>
+    <string name="find_on_page" msgid="1946799233822820384">"ຊອກໃນໜ້າ"</string>
+  <plurals name="matches_found">
+    <item quantity="one" msgid="8167147081136579439">"1 ກົງກັນ"</item>
+    <item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> ຈາກທັງໝົດ <xliff:g id="TOTAL">%d</xliff:g>"</item>
+  </plurals>
+    <string name="action_mode_done" msgid="7217581640461922289">"ແລ້ວໆ"</string>
+    <string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"ກຳລັງຖອນການເຊື່ອມຕໍ່ບ່ອນຈັດເກັບຂໍ້ມູນ USB …"</string>
+    <string name="progress_unmounting" product="default" msgid="1327894998409537190">"ຖອນການເຊື່ອມຕໍ່ SD card..."</string>
+    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"ກຳລັງລຶບ ບ່ອນຈັດເກັບຂໍ້ມູນ USB …"</string>
+    <string name="progress_erasing" product="default" msgid="6596988875507043042">"ກຳລັງລຶບ​ SD card..."</string>
+    <string name="format_error" product="nosdcard" msgid="6299769563624776948">"ບໍ່ສາມາດລຶບບ່ອນຈັດເກັບຂໍ້ມູນ USB ໄດ້."</string>
+    <string name="format_error" product="default" msgid="7315248696644510935">"ບໍ່ສາມາດລຶບ SD card ໄດ້."</string>
+    <string name="media_bad_removal" msgid="7960864061016603281">"SD card ຖືກຖອດອອກກ່ອນການຖອນການເຊື່ອມຕໍ່."</string>
+    <string name="media_checking" product="nosdcard" msgid="418188720009569693">"ບ່ອນຈັດເກັບຂໍ້ມູນກຳລັງຢູ່ໃນລະຫວ່າງການກວດສອບ."</string>
+    <string name="media_checking" product="default" msgid="7334762503904827481">"ກຳລັງກວດສອບ SD card ຢູ່ໃນຂະນະນີ້."</string>
+    <string name="media_removed" msgid="7001526905057952097">"SD card ຖືກຖອດອອກແລ້ວ."</string>
+    <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"ບ່ອນຈັດເກັບຂໍ້ມູນ USB ກຳລັງຖືກນຳໃຊ້ໂດຍຄອມພິວເຕີ."</string>
+    <string name="media_shared" product="default" msgid="5706130568133540435">"SD card ກຳລັງຖືກນຳໃຊ້ໂດຍຄອມພິວເຕີຢູ່."</string>
+    <string name="media_unknown_state" msgid="729192782197290385">"ຂໍ້ມູນພາຍນອກຢູ່ໃນສະຖານະທີ່ບໍ່ຮູ້ຈັກ."</string>
+    <string name="share" msgid="1778686618230011964">"ແບ່ງປັນ"</string>
+    <string name="find" msgid="4808270900322985960">"ຊອກຫາ"</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="gpsNotifMessage" msgid="1374718023224000702">"ຮ້ອງຂໍໂດຍ <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+    <string name="gpsVerifYes" msgid="2346566072867213563">"ຕົກລົງ"</string>
+    <string name="gpsVerifNo" msgid="1146564937346454865">"ບໍ່"</string>
+    <string name="sync_too_many_deletes" msgid="5296321850662746890">"ກາຍເຂດກຳນົດການລຶບ"</string>
+    <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"ມີ <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> ລາຍການທີ່ຖືກລຶບສຳລັບ <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, ບັນຊີ <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. ທ່ານຕ້ອງການຈະເຮັດແນວໃດ?"</string>
+    <string name="sync_really_delete" msgid="2572600103122596243">"ລຶບລາຍການ"</string>
+    <string name="sync_undo_deletes" msgid="2941317360600338602">"ຍົກເລີກການລຶບ"</string>
+    <string name="sync_do_nothing" msgid="3743764740430821845">"ບໍ່ເຮັດຫຍັງໃນຕອນນີ້"</string>
+    <string name="choose_account_label" msgid="5655203089746423927">"ເລືອກບັນຊີ"</string>
+    <string name="add_account_label" msgid="2935267344849993553">"ເພີ່ມບັນຊີ"</string>
+    <string name="add_account_button_label" msgid="3611982894853435874">"ເພີ່ມບັນຊີ"</string>
+    <string name="number_picker_increment_button" msgid="2412072272832284313">"ເພີ່ມ"</string>
+    <string name="number_picker_decrement_button" msgid="476050778386779067">"ປັບລົງ"</string>
+    <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> ສຳພັດຄ້າງໄວ້."</string>
+    <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"ເລື່ອນຂຶ້ນເພື່ອເພີ່ມ ແລະເລື່ອນລົງເພື່ອຫຼຸດ."</string>
+    <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"ເພີ່ມນາທີ"</string>
+    <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"ປັບນາທີລົງ"</string>
+    <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"ເພີ່ມຊົ່ວໂມງ"</string>
+    <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"ຫຼຸດຊົ່ວໂມງ"</string>
+    <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"ຕັ້ງ PM"</string>
+    <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"ຕັ້ງ AM"</string>
+    <string name="date_picker_increment_month_button" msgid="5369998479067934110">"ເພີ່ມຈຳນວນເດືອນ"</string>
+    <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"ຫຼຸດເດືອນ"</string>
+    <string name="date_picker_increment_day_button" msgid="7130465412308173903">"ເພີ່ມຈຳນວນມື້"</string>
+    <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"ຫຼຸດຈຳນວນມື້"</string>
+    <string name="date_picker_increment_year_button" msgid="6318697384310808899">"ເພີ່ມປີຂຶ້ນ"</string>
+    <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"ຫຼຸດຈຳນວນປີ"</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_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"ເລືອກແອັບຯ"</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">"ເລື່ອນບ່ອນຖື ແລ້ວແຕະຄ້າງໄວ້."</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"ເລື່ອນຂຶ້ນເພື່ອ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"ເລື່ອນລົງເພື່ອ <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="description_direction_right" msgid="8034433242579600980">"ເລື່ອນໄປທາງຂວາເພື່ອ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"ປົດລັອກ"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"ກ້ອງ"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"ປິດສຽງ"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"ເປີດສຽງ"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"ຊອກຫາ"</string>
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"ປັດເພື່ອປົດລັອກ."</string>
+    <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"ສຽບສາຍຫູຟັງເພື່ອຟັງລະຫັດຜ່ານ."</string>
+    <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"ຈໍ້າເມັດ."</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="4891916833657929263">"ບ່ອນຈັດເກັບຂໍ້ມູນພາຍໃນ"</string>
+    <string name="storage_sd_card" msgid="3282948861378286745">"SD card"</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="1955638862122232342">"ເຕືອນກ່ຽວກັບການນຳໃຊ້ຂໍ້ມູນ"</string>
+    <string name="data_usage_warning_body" msgid="2814673551471969954">"ແຕະເພື່ອເບິ່ງການນຳໃຊ້ ແລະການຕັ້ງຄ່າ."</string>
+    <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"ປິດການນຳໃຊ້ຂໍ້ມູນ 2G-3G"</string>
+    <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"ການນຳໃຊ້ຂໍ້ມູນ 4G ຖືກປິດແລ້ວ"</string>
+    <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"ຂໍ້ມູນມືຖືຖືກປິດໄວ້"</string>
+    <string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"ປິດຂໍ້ມູນ Wi-Fi ແລ້ວ"</string>
+    <string name="data_usage_limit_body" msgid="3317964706973601386">"ແຕະເພື່ອເປີດໃຊ້."</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_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="6741521330997452990">"ແຕະເພື່ອເອົາການຈຳກັດອອກ"</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>
+    <string name="org_unit" msgid="7265981890422070383">"ໜ່ວຍອົງກອນ:"</string>
+    <string name="issued_by" msgid="2647584988057481566">"ອອກໃຫ້ໂດຍ:"</string>
+    <string name="validity_period" msgid="8818886137545983110">"ອາຍຸການນຳໃຊ້:"</string>
+    <string name="issued_on" msgid="5895017404361397232">"ອອກໃຫ້ເມື່ອ:"</string>
+    <string name="expires_on" msgid="3676242949915959821">"ໝົດອາຍຸໃນ:"</string>
+    <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>
+    <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"ເບິ່ງທັງຫມົດ"</string>
+    <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"ເລືອກກິດຈະກຳ"</string>
+    <string name="share_action_provider_share_with" msgid="5247684435979149216">"ແບ່ງປັນກັບ"</string>
+    <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="3245653681008218030">"ກຳລັງສົ່ງ..."</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="default_audio_route_name" product="tablet" msgid="4617053898167127471">"ແທັບເລັດ"</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="media_route_chooser_grouping_done" msgid="7966438307723317169">"ແລ້ວໆ"</string>
+    <string name="media_route_button_content_description" msgid="5758553567065145276">"ມີເດຍເອົ້າພຸດ"</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>
+    <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_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="wifi_display_notification_title" msgid="2223050649240326557">"ເຊື່ອມຕໍ່ການສະແດງຜົນໄຮ້ສາຍແລ້ວ"</string>
+    <string name="wifi_display_notification_message" msgid="4498802012464170685">"ຈໍນີ້ກຳລັງສະແດງຢູ່ໃນອຸປະກອນອື່ນ"</string>
+    <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"ຢຸດການເຊື່ອມຕໍ່"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"ການໂທສຸກເສີນ"</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">"ລະຫັດ PIN ຜິດ"</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 ຂອງຊິມ"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"ໃສ່ລະຫັດ PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"ໃສ່ລະຫັດຜ່ານ"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"ຊິມຖືກປິດການນຳໃຊ້ແລ້ວ. ປ້ອນລະຫັດ PUK ເພື່ອດຳເນີນການຕໍ່. ຕິດຕໍ່ຜູ່ໃຫ້ບໍລິການສຳລັບລາຍລະອຽດ."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"ໃສ່ລະຫັດ PIN ທີ່ຕ້ອງການ."</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"ຢືນຢັນລະຫັດ PIN ທີ່ຕ້ອງການ"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"ປົດລັອກ SIM card..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"ລະຫັດ PIN ບໍ່ຖືກຕ້ອງ."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"ພິມລະຫັດ PIN ຄວາມຍາວ 4 ເຖິງ 8 ໂຕເລກ."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"ລະຫັດ PUK ຄວນມີຢ່າງໜ້ອຍ 8 ໂຕເລກ."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"ປ້ອນລະຫັດ PUK ທີ່ຖືກຕ້ອງຄືນໃໝ່. ການພະຍາຍາມໃສ່ຫຼາຍເທື່ອຈະເຮັດໃຫ້ຊິມກາດໃຊ້ບໍ່ໄດ້ຖາວອນ."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"ລະຫັດ PIN ບໍ່ກົງກັນ"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ແຕ້ມຮູບແບບປົດລັອກຫຼາຍເກີນໄປ"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"ເພື່ອປົດລັອກ, ເຂົ້າສູ່ລະບົບດ້ວຍບັນຊີ Google ຂອງທ່ານ."</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"ກຳລັງກວດສອບບັນຊີ..."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"ທ່ານພິມລະຫັດ PIN​ ຂອງທ່ານຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. \n\nກະລຸນາລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ວິນາທີ."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"ທ່ານພິມລະຫັດຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. \n\nລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ວິນາທີ."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"ທ່ານແຕ້ມຮູບແບບປົດລັອກຂອງທ່ານຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. \n\nກະລຸນາລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ວິນາທີ."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"ທ່ານໄດ້ພະຍາຍາມປົດລັອກແທັບເລັດບໍ່ສຳເລັດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກຄວາມພະຍາຍາມອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ເທື່ອ ແທັບເລັດຂອງທ່ານຈະຖືກຕັ້ງ ໃຫ້ກັບໄປໃຊ້ຄ່າເລີ່ມຕົ້ນຈາກໂຮງງານຄືນໃໝ່ ແລະຂໍ້ມູນຜູ່ໃຊ້ທັງໝົດຈະສູນຫາຍໄປ."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"ທ່ານໄດ້ພະຍາຍາມປົດລັອກໂທລະສັບບໍ່ສຳເລັດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກຄວາມພະຍາຍາມອີກ <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກແຕ້ມຜິດອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ເທື່ອ, ທ່ານຈະຖືກຖາມໃຫ້ປົດລັອກແທັບເລັດຂອງທ່ານ ດ້ວຍການເຂົ້າສູ່ລະບົບໂດຍໃຊ້ອີເມວຂອງທ່ານ.\n\n ກະລຸນາລອງໃໝ່ອີກຄັ້ງໃນອີກ <xliff:g id="NUMBER_2">%d</xliff:g> ວິນາທີ."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"ທ່ານແຕ້ມຮູບແບບປົດລັອກຂອງທ່ານຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກຄວາມພະຍາຍາມອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ເທື່ອ ທ່ານຈະຖືກຖາມໃຫ້ປົດລັອກໂທລະສັບຂອງທ່ານດ້ວຍບັນຊີອີເມວ.\n\n ລອງໃໝ່ອີກຄັ້ງໃນ <xliff:g id="NUMBER_2">%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="7324161939475478066">"ຕ້ອງການເພີ່ມລະດັບສຽງຈົນເກີນລະດັບທີ່ແນະນຳ?\nການຟັງໃນລະດັບສຽງດັງເປັນເວລາດົນ ອາດທຳລາຍການໄດ້ຍິນສຽງຂອງທ່ານໄດ້."</string>
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"ກົດສອງນິ້ວຄ້າງໄວ້ເພື່ອເປີດໃຊ້ການຊ່ວຍເຂົ້າເຖິງ"</string>
+    <string name="accessibility_enabled" msgid="1381972048564547685">"ເປີດການຊ່ວຍເຂົ້າເຖິງແລ້ວ."</string>
+    <string name="enable_accessibility_canceled" msgid="3833923257966635673">"ຍົກເລີກໂຕຊ່ວຍການເຂົ້າເຖິງແລ້ວ."</string>
+    <string name="user_switched" msgid="3768006783166984410">"ຜູ່ໃຊ້ປັດຈຸບັນ <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="app_no_restricted_accounts" msgid="5739463249673727736">"ແອັບພລິເຄຊັນນີ້ບໍ່ຮອງຮັບບັນຊີຂອງໂປຣໄຟລ໌ທີ່ຖືກຈຳກັດ."</string>
+    <string name="app_not_found" msgid="3429141853498927379">"ບໍ່ພົບແອັບພລິເຄຊັນເພື່ອຈັດການເຮັດວຽກນີ້."</string>
+    <string name="revoke" msgid="5404479185228271586">"ຖອນ"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"ຈົດໝາຍ"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"ຈົດ​ຫມາຍທາງ​ລັດ​ຖະ​ບານ"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"ກົດຫມາຍ"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"ກົດໝາຍຂັ້ນຕ່ຳ"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"ບັນ​ຊີ"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"ແຖບບລອຍ"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"ຍົກເລີກແລ້ວ"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"ເນື້ອ​ໃນ​ການຂຽນຜິດພາດ"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"ບໍ່ຮູ້ຈັກ"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"ໃສ່ 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>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"ລະຫັດ PIN ໃໝ່"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"ຢືນຢັນລະຫັດ PIN ໃໝ່"</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_too_short" msgid="8173982756265777792">"PIN ​ສັ້ນ​ເກີນ​ໄປ​. ຕ້ອງມີຢ່າງໜ້ອຍ 4 ຫຼັກ​."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"ລອງໃໝ່ໃນອີກ 1 ວິນາທີ"</item>
+    <item quantity="other" msgid="4730868920742952817">"ລອງໃໝ່ໃນອີກ <xliff:g id="COUNT">%d</xliff:g> ວິນາທີ"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"ລອງໃໝ່ອີກຄັ້ງໃນພາຍຫລັງ."</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"ປັດຢູ່ຂອບຂອງໜ້າຈໍເພື່ອສະແດງແຖບ"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"ປັດຢູ່ຂອບຂອງໜ້າຈໍເພື່ອສະແດງແຖບຂອງລະບົບ"</string>
+</resources>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
new file mode 100644
index 0000000..9d07ae6
--- /dev/null
+++ b/core/res/res/values-lo/strings.xml
@@ -0,0 +1,1588 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<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="5973789783504771878">"KB"</string>
+    <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
+    <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
+    <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
+    <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
+    <string name="untitled" msgid="4638956954852782576">"&lt;ບໍ່ມີຊື່&gt;"</string>
+    <string name="ellipsis" msgid="7899829516048813237">"…"</string>
+    <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
+    <string name="emptyPhoneNumber" msgid="7694063042079676517">"(ບໍ່ມີເບີໂທລະສັບ)"</string>
+    <string name="unknownName" msgid="2277556546742746522">"(ບໍ່ຮູ້)"</string>
+    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"ຂໍ້ຄວາມສຽງ"</string>
+    <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
+    <string name="mmiError" msgid="5154499457739052907">"ມີບັນຫາໃນການເຊື່ອມຕໍ່ ຫຼືລະຫັດ MMI ບໍ່ຖືກຕ້ອງ."</string>
+    <string name="mmiFdnError" msgid="5224398216385316471">"ການດຳເນີນການຖືກຈຳກັດເປັນ ຈຳກັດໝາຍເລກໂທອອກເທົ່ານັ້ນ."</string>
+    <string name="serviceEnabled" msgid="8147278346414714315">"ບໍລິການຖືກເປີດໄວ້ແລ້ວ."</string>
+    <string name="serviceEnabledFor" msgid="6856228140453471041">"ບໍລິການຖືກເປີດໃຊ້ສຳລັບ:"</string>
+    <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="mmiComplete" msgid="8232527495411698359">"MMI ສຳເລັດ."</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>
+    <string name="invalidPuk" msgid="8761456210898036513">"ພິມລະຫັດ PUK ທີ່ມີ 8 ໂຕເລກ ຫຼືຫຼາຍກວ່ານັ້ນ."</string>
+    <string name="needPuk" msgid="919668385956251611">"ຊິມກາດຂອງທ່ານຖືກລັອກດ້ວຍລະຫັດ PUK. ໃຫ້ພິມລະຫັດ PUK ເພື່ອປົດລັອກມັນ."</string>
+    <string name="needPuk2" msgid="4526033371987193070">"ພິມ PUK2 ເພື່ອປົດລັອກ SIM card."</string>
+    <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="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">"ການປ່ຽນແປງ PIN"</string>
+    <string name="CnipMmi" msgid="3110534680557857162">"ສະແດງໝາຍເລກທີ່ໂທ"</string>
+    <string name="CnirMmi" msgid="3062102121430548731">"ເບີໂທທີ່ຖືກຈຳກັດ"</string>
+    <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="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"ໝາຍເລກຜູ່ໂທຖືກຕັ້ງຄ່າເລີ່ມຕົ້ນໃຫ້ຖືກຈຳກັດ. ການໂທຄັ້ງຕໍ່ໄປ: ຖືກຈຳກັດ"</string>
+    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"ໝາຍເລກຜູ່ໂທ ໄດ້ຮັບການຕັ້ງຄ່າເລີ່ມຕົ້ນເປັນ ຖືກຈຳກັດ. ການໂທຄັ້ງຕໍ່ໄປ: ບໍ່ຖືກຈຳກັດ."</string>
+    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"Caller ID ໂດຍເລີ່ມຕົ້ນຖືກປັບໃຫ້ບໍ່ມີການປິດກັ້ນ. ການໂທຕໍ່ໄປ:ປິດກັ້ນ"</string>
+    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"ໝາຍເລກຜູ່ໂທ ໄດ້ຮັບການຕັ້ງຄ່າເລີ່ມຕົ້ນເປັນ ບໍ່ຖືກຈຳກັດ. ການໂທຄັ້ງຕໍ່ໄປ: ບໍ່ຖືກຈຳກັດ."</string>
+    <string name="serviceNotProvisioned" msgid="8614830180508686666">"ບໍ່ໄດ້ເປີດໃຊ້ບໍລິການ."</string>
+    <string name="CLIRPermanent" msgid="3377371145926835671">"ທ່ານບໍ່ສາມາດປ່ຽນແປງການຕັ້ງຄ່າ Caller ID"</string>
+    <string name="RestrictedChangedTitle" msgid="5592189398956187498">"ປ່ຽນການເຂົ້າເຖິງທີ່ຖືກຈຳກັດແລ້ວ"</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="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>
+    <string name="serviceClassDataSync" msgid="7530000519646054776">"ຊິ້ງຂໍ້ມູນ"</string>
+    <string name="serviceClassPacket" msgid="6991006557993423453">"ແພັກເກັດ"</string>
+    <string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
+    <string name="roamingText0" msgid="7170335472198694945">"ໂຕບອກການເຊື່ອມຕໍ່ກັບເຄືອຂ່າຍພາຍນອກເປີດຢູ່"</string>
+    <string name="roamingText1" msgid="5314861519752538922">"ໂຕບອກການເຊື່ອມຕໍ່ກັບເຄືອຂ່າຍພາຍນອກປິດຢູ່"</string>
+    <string name="roamingText2" msgid="8969929049081268115">"ໂຕບອກການເຊື່ອມຕໍ່ກັບເຄືອຂ່າຍພາຍນອກກະພິບ"</string>
+    <string name="roamingText3" msgid="5148255027043943317">"ຢູ່ນອກເຂດໃກ້ຄຽງ"</string>
+    <string name="roamingText4" msgid="8808456682550796530">"ດ້ານນອກຂອງອາຄານ"</string>
+    <string name="roamingText5" msgid="7604063252850354350">"ໂຣມມິງ - ລະບົບທີ່ຕ້ອງການ"</string>
+    <string name="roamingText6" msgid="2059440825782871513">"ໂຣມມິງ - ລະບົບທີ່ໃຊ້ໄດ້"</string>
+    <string name="roamingText7" msgid="7112078724097233605">"ໂຣມມິງ - ຮຸ້ນສ່ວນພັນທະມິດ"</string>
+    <string name="roamingText8" msgid="5989569778604089291">"ໂຣມມິງ - ຮຸ້ນສ່ວນພຣີມຽມ"</string>
+    <string name="roamingText9" msgid="7969296811355152491">"ໂຣມມິງ - ຟັງຊັນບໍລິການເຕັມຮູບແບບ"</string>
+    <string name="roamingText10" msgid="3992906999815316417">"ໂຣມມິງ - ຟັງຊັນບໍລິການບາງສ່ວນ"</string>
+    <string name="roamingText11" msgid="4154476854426920970">"ເປີດໂຣມມິງແບນເນີ"</string>
+    <string name="roamingText12" msgid="1189071119992726320">"ປິດໂຣມມິງແບນເນີ"</string>
+    <string name="roamingTextSearching" msgid="8360141885972279963">"ຊອກຫາບໍລິການ"</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="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="httpErrorProxyAuth" msgid="1788207010559081331">"ການພິສູດຢືນຢັນຜ່ານເຊີບເວີ Proxy ບໍ່ສຳເລັດ."</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="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="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="default" msgid="3475999286680000541">"ພື້ນທີ່ໃນໂທລະສັບເຕັມແລ້ວ. ກະລຸນາລຶບບາງໄຟລ໌ອອກເພື່ອເພີ່ມພື້ນທີ່ຫວ່າງ."</string>
+    <string name="me" msgid="6545696007631404292">"ຂ້າພະເຈົ້າ"</string>
+    <string name="power_dialog" product="tablet" msgid="8545351420865202853">"ໂຕເລືອກແທັບເລັດ"</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">"ປິດ wireless"</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="shutdown_progress" msgid="2281079257329981203">"ກຳລັງປິດລົງ..."</string>
+    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"ແທັບເລັດຂອງທ່ານຈະຖືກປິດ."</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">"ຣີບູດເຂົ້າ safe mode"</string>
+    <string name="reboot_safemode_confirm" msgid="55293944502784668">"ທ່ານຕ້ອງການຣີບູດເຂົ້າ safe mode ຫຼືບໍ່? ນີ້ຈະເປັນການປິດການເຮັດວຽກຂອງແອັບພລິເຄຊັນ ຈາກພາກສ່ວນທີສາມທັງໝົດທີ່ທ່ານໄດ້ຕິດຕັ້ງໄວ້. ແອັບພລິເຄຊັນເຫຼົ່ານັ້ນ ຈະກັບມາເຮັດວຽກໄດ້ອີກຫຼັງຈາກທ່ານຣີບູດອີກຄັ້ງ."</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="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_bug_report" msgid="7934010578922304799">"ລາຍງານຂໍ້ຜິດພາດ"</string>
+    <string name="bugreport_title" msgid="2667494803742548533">"ໃຊ້ລາຍງານຂໍ້ບົກພ່ອງ"</string>
+    <string name="bugreport_message" msgid="398447048750350456">"ນີ້ຈະເປັນການເກັບກຳຂໍ້ມູນກ່ຽວກັບ ສະຖານະປັດຈຸບັນຂອງອຸປະກອນທ່ານ ເພື່ອສົ່ງເປັນຂໍ້ຄວາມທາງອີເມວ. ມັນຈະໃຊ້ເວລາໜ້ອຍນຶ່ງ ໃນການເລີ່ມຕົ້ນການລາຍງານຂໍ້ຜິດພາດ ຈົນກວ່າຈະພ້ອມທີ່ຈະສົ່ງໄດ້, ກະລຸນາລໍຖ້າ."</string>
+    <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_airplane_mode_on_status" msgid="2719557982608919750">"ເປີດໂໝດຢູ່ໃນຍົນແລ້ວ"</string>
+    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"ປິດໂໝດໃນຍົນແລ້ວ"</string>
+    <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
+    <string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
+    <string name="android_system_label" msgid="6577375335728551336">"ລະບົບ Android"</string>
+    <string name="permgrouplab_costMoney" msgid="5429808217861460401">"ບໍລິການທີ່ເຮັດໃຫ້ທ່ານເສຍເງິນ"</string>
+    <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"ເຮັດສິ່ງທີ່ທ່ານຕ້ອງເສຍຄ່າໃຊ້ຈ່າຍ."</string>
+    <string name="permgrouplab_messages" msgid="7521249148445456662">"ຂໍ້ຄວາມຂອງທ່ານ"</string>
+    <string name="permgroupdesc_messages" msgid="7821999071003699236">"ອ່ານ ແລະຂຽນ SMS, ອີເມວ ແລະຂໍ້ຄວາມອື່ນໆຂອງທ່ານ."</string>
+    <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"ຂໍ້ມູນສ່ວນໂຕຂອງທ່ານ"</string>
+    <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"ເຂົ້າເຖິງຂໍ້ມູນກ່ຽວກັບທ່ານໂດຍກົງ, ບັນທຶກໄວ້ໃນບັດລາຍຊື່ຜູ່ຕິດຕໍ່ຂອງທ່ານ."</string>
+    <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"ຂໍ້ມູນສັງຄົມຂອງທ່ານ"</string>
+    <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"ເຂົ້າເຖິງຂໍ້ມູນກ່ຽວກັບລາຍຊື່ຜູ່ຕິດຕໍ່ ແລະການເຊື່ອມຕໍ່ທາງສັງຄົມຂອງທ່ານໂດຍກົງ."</string>
+    <string name="permgrouplab_location" msgid="635149742436692049">"ສະຖານທີ່ຂອງທ່ານ"</string>
+    <string name="permgroupdesc_location" msgid="5704679763124170100">"ຕິດຕາມສະຖານທີ່ທາງກາຍະພາບຂອງທ່ານ."</string>
+    <string name="permgrouplab_network" msgid="5808983377727109831">"ການສື່ສານເຄືອຂ່າຍ"</string>
+    <string name="permgroupdesc_network" msgid="4478299413241861987">"ເຂົ້າເຖິງຄຸນສົມບັດຕ່າງໆຂອງເຄືອຂ່າຍ."</string>
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"Bluetooth"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"ເຂົ້າເຖິງອຸປະກອນ ແລະເຄືອຂ່າຍຜ່ານ Bluetooth."</string>
+    <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"ການຕັ້ງຄ່າສຽງ"</string>
+    <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"ປ່ຽນການຕັ້ງຄ່າສຽງ."</string>
+    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"ສົ່ງຜົນຕໍ່ແບັດເຕີຣີ"</string>
+    <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"ໃຊ້ຄວາມສາມາດທີ່ເຮັດໃຫ້ພະລັງງານແບັດເຕີຣີຫຼຸດລົງຢ່າງໄວວາ."</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"ປະຕິທິນ"</string>
+    <string name="permgroupdesc_calendar" msgid="5777534316982184416">"ເຂົ້າເຖິງປະຕິທິນ ແລະນັດໝາຍໂດຍກົງ."</string>
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"ອ່ານວັດຈະນານຸກົມຜູ່ໃຊ້"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"ອ່ານຄຳສັບໃນວັດຈະນານຸກົມຜູ່ໃຊ້."</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"ຂຽນວັດຈະນານຸກົມຜູ່ໃຊ້"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"ເພີ່ມຄຳສັບໃສ່ວັດຈະນານຸກົມຜູ່ໃຊ້."</string>
+    <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"ບຸກມາກ ແລະປະຫວັດເວັບໄຊ"</string>
+    <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"ເຂົ້ານຳໃຊ້ບຸກແລະປະຫວັດການທ່ອງເວັບໂດຍກົງ."</string>
+    <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"ໂມງປຸກ"</string>
+    <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"ຕັ້ງໂມງປຸກ."</string>
+    <string name="permgrouplab_voicemail" msgid="4162237145027592133">"ຂໍ້ຄວາມສຽງ"</string>
+    <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"ເຂົ້າໃຊ້ຂໍ້ຄວາມສຽງໂດຍກົງ"</string>
+    <string name="permgrouplab_microphone" msgid="171539900250043464">"ໄມໂຄຣໂຟນ"</string>
+    <string name="permgroupdesc_microphone" msgid="7106618286905738408">"ເຂົ້າເຖິງໄມໂຄຣໂຟນໂດຍກົງເພື່ອບັນທຶກສຽງ."</string>
+    <string name="permgrouplab_camera" msgid="4820372495894586615">"ກ້ອງ"</string>
+    <string name="permgroupdesc_camera" msgid="2933667372289567714">"ເຂົ້າໃຊ້ກ້ອງຖ່າຍຮູບສຳລັບການຖ່າຍຮູບ ແລະວິດີໂອໂດຍກົງ."</string>
+    <string name="permgrouplab_screenlock" msgid="8275500173330718168">"ລັອກໜ້າຈໍ"</string>
+    <string name="permgroupdesc_screenlock" msgid="7067497128925499401">"ຄວາມສາມາດໃນການສົ່ງຜົນຕໍ່ພຶດຕິກຳ ຂອງການລັອກໜ້າຈໍໃນອຸປະກອນຂອງທ່ານ."</string>
+    <string name="permgrouplab_appInfo" msgid="8028789762634147725">"ເບິ່ງຂໍ້ມູນແອັບພລິເຄຊັນຂອງທ່ານ"</string>
+    <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"ສາມາດສົ່ງຜົນຕໍ່ການເຮັດວຽກ ຂອງແອັບພລິເຄຊັນອື່ນໃນອຸປະກອນຂອງທ່ານ."</string>
+    <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"ພາບພື້ນຫຼັງ"</string>
+    <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"ປ່ຽນການຕັ້ງຄ່າພາບພື້ນຫຼັງຂອງອຸປະກອນ."</string>
+    <string name="permgrouplab_systemClock" msgid="406535759236612992">"ໂມງ"</string>
+    <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"ປ່ຽນເວລາ ຫຼືເຂດເວລາໃນອຸປະກອນ."</string>
+    <string name="permgrouplab_statusBar" msgid="2095862568113945398">"ແຖບສະຖານະ"</string>
+    <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"ປ່ຽນການຕັ້ງຄ່າແຖບສະຖານະອຸປະກອນ."</string>
+    <string name="permgrouplab_syncSettings" msgid="3341990986147826541">"ຕັ້ງຄ່າການຊິ້ງຂໍ້ມູນ"</string>
+    <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"ເຂົ້າໃຊ້ການຕັ້ງຄ່າການຊິ້ງຂໍ້ມູນ"</string>
+    <string name="permgrouplab_accounts" msgid="3359646291125325519">"ບັນຊີຂອງທ່ານ"</string>
+    <string name="permgroupdesc_accounts" msgid="4948732641827091312">"ເຂົ້າເຖິງບັນຊີທີ່ໃຊ້ໄດ້."</string>
+    <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"ການຄວບຄຸມຮາດແວ"</string>
+    <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"ເຂົ້າເຖິງຮາດແວຂອງຊຸດຫູຟັງໂດຍກົງ."</string>
+    <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"ການໂທ"</string>
+    <string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"ຕິດຕາມ, ເກັບກຳ ແລະປະມວນຜົນການໂທລະສັບ."</string>
+    <string name="permgrouplab_systemTools" msgid="4652191644082714048">"ເຄື່ອງມືລະບົບ"</string>
+    <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"ການເຂົ້າເຖິງ ແລະການຄວບຄຸມລະບົບໃນລະດັບຕ່ຳ."</string>
+    <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"ເຄື່ອງມືການພັດທະນາ"</string>
+    <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"ມີພຽງນັກພັດທະນາແອັບຯເທົ່ານັ້ນທີ່ຈະຕ້ອງການຄວາມສາມາດເຫຼົ່ານີ້."</string>
+    <string name="permgrouplab_display" msgid="4279909676036402636">"ສ່ວນຕິດຕໍ່ຜູ່ໃຊ້ຂອງແອັບພລິເຄຊັນອື່ນ"</string>
+    <string name="permgroupdesc_display" msgid="6051002031933013714">"ສົ່ງຜົນຕໍ່ສ່ວນຕິດຕໍ່ຜູ່ໃຊ້ຂອງແອັບພລິເຄຊັນອື່ນ."</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"ພື້ນທີ່ຈັດເກັບຂໍ້ມູນ"</string>
+    <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"ການເຂົ້າເຖິງບ່ອນຈັດເກັບຂໍ້ມູນ USB."</string>
+    <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"ການເຂົ້າເຖິງ SD card."</string>
+    <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"ຄວາມສາມາດການຊ່ວຍເຂົ້າເຖິງ"</string>
+    <string name="permgroupdesc_accessibilityFeatures" msgid="4205196881678144335">"ຄຸນສົມບັດທີ່ເທັກໂນໂລຢີຄວາມຊ່ວຍເຫຼືອສາມາດຮ້ອງຂໍໄດ້."</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="5800552516779249356">"ລາຍການທີ່ສຳພັດຈະຖືກເວົ້າອອກມາ ແລະສາມາດສຳຫຼວດໜ້າຈໍໄດ້ດ້ວຍທ່າທາງ."</string>
+    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"ເປີດການເຂົ້າເຖິງເວັບທີ່ມີປະສິດທິພາບຫຼາຍຂຶ້ນ"</string>
+    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"ສະຄຣິບອາດຖືກຕິດຕັ້ງ ເພື່ອເຮັດໃຫ້ເນື້ອຫາແອັບຯເຂົ້າເຖິງໄດ້ຫຼາຍຂຶ້ນ."</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"ຕິດຕາມ​ເບິ່ງ​ຂໍ້​ຄວາມ​ທີ່​ທ່ານ​ພິມ"</string>
+    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"ຮວມທັງຂໍ້ມູນສ່ວນໂຕເຊັ່ນ: ເລກບັດເຄຣດິດ ແລະລະຫັດຜ່ານ."</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"ປິດການນນຳໃຊ້ ຫຼື ແກ້ໄຂແຖບສະຖານະ"</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"ອະນຸຍາດໃຫ້ແອັບຯປິດການເຮັດວຽກຂອງແຖບສະຖານະ ຫຼືເພີ່ມ ແລະລຶບໄອຄອນລະບົບອອກໄດ້."</string>
+    <string name="permlab_statusBarService" msgid="7247281911387931485">"ແຖບສະຖານະ"</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_processOutgoingCalls" msgid="3906007831192990946">"ປ່ຽນເສັ້ນທາງການໂທອອກ"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"ອະນຸຍາດໃຫ້ແອັບຯປະມວນຜົນສາຍທີ່ໂທອອກ ແລະປ່ຽນໝາຍເລກທີ່ຈະໂທອອກ. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດກວດສອບ, ໂອນສາຍ ຫຼືຂັດຂວາງບໍ່ໃຫ້ໂທອອກໄດ້."</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_receiveEmergencyBroadcast" msgid="1803477660846288089">"ຮັບການກະຈາຍສັນຍານສຸກເສີນ"</string>
+    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"ອະນຸຍາດໃຫ້ແອັບຯຮັບ ແລະປະມວນຜົນການກະຈາຍຂໍ້ຄວາມດ່ວນໄດ້. ການອະນຸຍາດນີ້ຈະສາມາດນຳໃຊ້ໄດ້ໂດຍແອັບຯຂອງລະບົບເທົ່ານັ້ນ."</string>
+    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"ອ່ານຂໍ້ຄວາມກະຈາຍສັນຍານຂອງເສົາສັນຍານ"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"ອະນຸຍາດໃຫ້ແອັບຯ ສາມາດອ່ານຂໍ້ຄວາມແຈ້ງເຕືອນເຫດສຸກເສີນ ທີ່ໄດ້ຮັບໂດຍອຸປະກອນຂອງທ່ານ. ການແຈ້ງເຕືອນສຸກເສີນທີ່ມີໃຫ້ບໍລິການໃນບາງພື້ນທີ່ ເພື່ອແຈ້ງເຕືອນໃຫ້ທ່ານຮູ້ເຖິງສະຖານະການສຸກເສີນ. ແອັບພລິເຄຊັນທີ່ເປັນອັນຕະລາຍອາດລົບກວນປະສິດທິພາບ ຫຼືການດຳເນີນງານຂອງອຸປະກອນຂອງທ່ານ ເມື່ອໄດ້ການຮັບແຈ້ງເຕືອນສຸກເສີນຈາກສະຖານີມືຖື."</string>
+    <string name="permlab_sendSms" msgid="5600830612147671529">"ສົ່ງຂໍ້ຄວາມ SMS"</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"ອະນຸຍາດໃຫ້ແອັບຯສົ່ງຂໍ້ຄວາມ SMS ໄດ້. ນີ້ອາດເຮັດໃຫ້ທ່ານເກີດການຄິດຄ່າບໍລິການທີ່ບໍ່ຄາດຄິດໄດ້. ແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດເຮັດໃຫ້ທ່ານເສຍເງິນຍ້ອນການສົ່ງຂໍ້ຄວາມໂດຍທີ່ທ່ານບໍ່ຮູ້ໂຕໄດ້."</string>
+    <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"ສົ່ງກິດຈະກຳການຕອບສະໜອງຜ່ານທາງຂໍ້ຄວາມ"</string>
+    <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"ອະນຸຍາດໃຫ້ແອັບຯສົ່ງຄຳຂໍ ໄປຫາແອັບຯຂໍ້ຄວາມອື່ນໆເພື່ອຈັດການ ກໍລະນີການຕອບດ້ວຍຂໍ້ຄວາມ ສຳລັບສາຍທີ່ໂທເຂົ້າມາ."</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"ອ່ານຂໍ້ຄວາມຂອງທ່ານ (SMS ຫຼື MMS)"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"ອະນຸຍາດໃຫ້ແອັບຯອ່ານ SMS ທີ່ບັນທຶກໄວ້ໃນແທັບເລັດ ຫຼື SIM card ຂອງທ່ານ. ຄຸນສົມບັດນີ້ຈະເຮັດໃຫ້ແອັບຯສາມາດອ່ານຂໍ້ຄວາມ SMS ທັງໝົດໄດ້ ບໍ່ເນື້ອຫາຂອງມັນຈະແມ່ນຫຍັງກໍຕາມ."</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"ອະນຸຍາດໃຫ້ແອັບຯ ອ່ານຂໍ້ຄວາມ SMS ທີ່ເກັບໄວ້ໃນໂທລະສັບຂອງທ່ານ ຫຼືຊິມກາດ. ນີ້ອະນຸຍາດໃຫ້ແອັບຯ ອ່ານຂໍ້ຄວາມ SMS ທັງໝົດ, ໂດຍບໍ່ຄຳນຶງເຖິງເນື້ອຫາ ຫຼືຄວາມລັບ."</string>
+    <string name="permlab_writeSms" msgid="3216950472636214774">"ແກ້ໄຂຂໍ້ຄວາມຂອງທ່ານ (SMS ຫຼື MMS)"</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"ອະນຸຍາດໃຫ້ແອັບຯຂຽນຂໍ້ຄວາມ SMS ທີ່ບັນທຶກໄວ້ໃນແທັບເລັດຂອງທ່ານ ຫຼືຊິມກາດຂອງທ່ານ. ແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດລຶບຂໍ້ຄວາມຂອງທ່ານໄດ້."</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"ອະນຸຍາດໃຫ້ແອັບຯ ຂຽນລົງໃສ່ຂໍ້ຄວາມ 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_interactAcrossUsers" msgid="7114255281944211682">"ການຕອບໂຕ້ລະຫວ່າງຜູ່ໃຊ້"</string>
+    <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"ອະນຸຍາດໃຫ້ແອັບຯດຳເນີນການ ສັ່ງງານຜ່ານຜູ່ໃຊ້ອື່ນໆໃນອຸປະກອນ. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດໃຊ້ຄວາມສາມາດນີ້ ເພື່ອລະເມີດການປ້ອງກັນລະຫວ່າງຜູ່ໃຊ້."</string>
+    <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"ໃບອະນຸຍາດສະບັບເຕັມໃນການໂຕ້ຕອບລະຫວ່າງຜູ່ໃຊ້"</string>
+    <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"ອະນຸຍາດທຸກການໂຕ້ຕອບທີ່ເປັນໄປໄດ້ລະຫວ່າງຜູ່ໃຊ້."</string>
+    <string name="permlab_manageUsers" msgid="1676150911672282428">"ຈັດການຜູ່ໃຊ້"</string>
+    <string name="permdesc_manageUsers" msgid="8409306667645355638">"ອະນຸຍາດໃຫ້ແອັບຯຈັດການຜູ່ໃຊ້ໃນອຸປະກອນ, ຮວມທັງການເອີ້ນ, ການສ້າງ ແລະການລຶບຂໍ້ມູນ."</string>
+    <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"ດຶງລາຍລະອຽດຂອງແອັບຯທີ່ກຳລັງເຮັດວຽກຢູ່"</string>
+    <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"ອະນຸຍາດໃຫ້ແອັບຯດຶງຂໍ້ມູນຢ່າງລະອຽດ ກ່ຽວກັບການເຮັດວຽກໃນປັດຈຸບັນ ແລະຫາກໍຜ່ານມາ. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດຄົ້ນພົບຂໍ້ມູນສ່ວນໂຕ ກ່ຽວກັບແອັບຯອື່ນໄດ້."</string>
+    <string name="permlab_reorderTasks" msgid="2018575526934422779">"ຮຽງລຳດັບແອັບຯທີ່ກຳລັງເຮັດວຽກຄືນໃໝ່"</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"ອະນຸຍາດໃຫ້ແອັບຯຍ້າຍການເຮັດວຽກໄປໃສ່ດ້ານໜ້າ ແລະພື້ນຫຼັງໄດ້. ແອັບຯອາດຈະດຳເນີນການໂດຍບໍ່ຕ້ອງໃຫ້ທ່ານບອກ."</string>
+    <string name="permlab_removeTasks" msgid="6821513401870377403">"ຢຸດແອັບຯທີ່ເຮັດວຽກຢູ່"</string>
+    <string name="permdesc_removeTasks" msgid="1394714352062635493">"ອະນຸຍາດໃຫ້ແອັບຯລຶບການເຮັດວຽກ ແລະປິດແອັບຯຂອງວຽກເຫຼົ່ານັ້ນ. ແອັບຯທີ່ເປັນອັນຕະລາຍ ສາມາດລົບກວນການເຮັດວຽກຂອງແອັບຯອື່ນໄດ້."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"ຈັດການສະແຕັກການເຄື່ອນໄຫວ"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"ອະ​ນຸ​ຍາດ​ໃຫ້ແອັບຯເພື່ອເພີ່ມ, ລຶບ ແລະ ແກ້ໄຂສະແຕັກການເຄື່ອນໄຫວ ທີ່ແອັບຯອື່ນໆເຮັດວຽກ. ແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດລົບກວນການເຮັດວຽກຂອງແອັບຯອື່ນ."</string>
+    <string name="permlab_startAnyActivity" msgid="2918768238045206456">"ເລີ່ມການເຮັດວຽກໃດນຶ່ງ"</string>
+    <string name="permdesc_startAnyActivity" msgid="997823695343584001">"ອະນຸຍາດໃຫ້ແອັບຯເລີ່ມການເຮັດວຽກໃດກໍໄດ້ ບໍ່ວ່າການອະນຸຍາດ ຫຼືສະຖານະການສົ່ງອອກຈະເປັນແນວໃດກໍຕາມ."</string>
+    <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"ຕັ້ງຄວາມເຂົ້າກັນໄດ້ຂອງໜ້າຈໍ"</string>
+    <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"ອະນຸຍາດໃຫ້ແອັບຯຄວບຄຸມໂໝດຄວາມເຂົ້າກັນໄດ້ ຂອງໜ້າຈໍແອັບພລິເຄຊັນອື່ນໆ. ແອັບພລິເຄຊັນທີ່ເປັນອັນຕະລາຍ ອາດເຮັດໃຫ້ແອັບພລິເຄຊັນອື່ນເຮັດວຽກຜິດພາດໄດ້."</string>
+    <string name="permlab_setDebugApp" msgid="3022107198686584052">"ເປີດການເກັບຂໍ້ມູນເພື່ອແກ້ໄຂບັນຫາ"</string>
+    <string name="permdesc_setDebugApp" msgid="4474512416299013256">"ອະນຸຍາດໃຫ້ແອັບຯ ເປີດການເກັບຂໍ້ມູນແກ້ບັນຫາສຳລັບແອັບຯອື່ນ. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດໃຊ້ຄຸນສົມບັດນີ້ເພື່ອປິດແອັບຯອື່ນ."</string>
+    <string name="permlab_changeConfiguration" msgid="4162092185124234480">"ປ່ຽນການຕັ້ງຄ່າໜ້າຈໍຂອງລະບົບ"</string>
+    <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"ອະນຸຍາດໃຫ້ແອັບຯປ່ຽນແປງການຕັ້ງຄ່າໃນປັດຈຸບັນ ເຊັ່ນ: ການຕັ້ງຄ່າທ້ອງຖິ່ນ ຫຼືຂະໜາດໂຕອັກສອນໂດຍຮວມ."</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_forceStopPackages" msgid="2329627428832067700">"ບັງຄັບໃຫ້ແອັບຯອື່ນຢຸດເຮັດວຽກ"</string>
+    <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"ອະນຸຍາດໃຫ້ແອັບຯບັງຄັບປິດແອັບຯອື່ນໆໄດ້."</string>
+    <string name="permlab_forceBack" msgid="652935204072584616">"ບັງຄັບປິດແອັບຯ"</string>
+    <string name="permdesc_forceBack" msgid="3892295830419513623">"ອະນຸຍາດໃຫ້ແອັບຯບັງຄັບການເຮັດວຽກທີ່ຢູ່ດ້ານໜ້າປິດ ແລະກັບຄືນໄດ້. ແອັບພລິເຄຊັນທົ່ວໄປບໍ່ຄວນຈຳເປັນຕ້ອງໃຊ້."</string>
+    <string name="permlab_dump" msgid="1681799862438954752">"ດຶງຂໍ້ມູນສະຖານະພາຍໃນຂອງລະບົບ"</string>
+    <string name="permdesc_dump" msgid="1778299088692290329">"ອະນຸຍາດໃຫ້ແອັບຯ ດຶງເອົາສະຖານະພາຍໃນຂອງລະບົບ. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດຈະດຶງເອົາຂໍ້ມູນສ່ວນຕົວ ແລະຂໍ້ມູນຄວາມປອດໄພ ຫຼາກຫຼາຍປະເພດທີ່ບໍ່ຈຳເປັນຕໍ່ພວກມັນເລີຍ."</string>
+    <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"ດຶງເອົາເນື້ອຫາໜ້າຈໍ"</string>
+    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"ອະນຸຍາດໃຫ້ແອັບຯດຶງຂໍ້ມູນເນື້ອຫາຂອງໜ້າຈໍທີ່ໃຊ້ຢູ່ໄດ້. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດດຶງຂໍ້ມູນທັງໝົດໃນໜ້າຈໍ ແລະກວດສອບຂໍ້ຄວາມທັງໝົດໃນນັ້ນໄດ້ ຍົກເວັ້ນລະຫັດຜ່ານ."</string>
+    <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"ປິດການຊ່ວຍການເຂົ້າເຖິງຊົ່ວຄາວ"</string>
+    <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນ ເປີດໃຊ້ການຊ່ວຍເຂົ້າເຖິງແບບຊົ່ວຄາວໃນອຸປະກອນ. ແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດເປີດໃຊ້ການຊ່ວຍເຂົ້າເຖິງ ໂດຍບໍ່ໄດ້ຮັບການຍິນຍອມຈາກຜູ່ໃຊ້."</string>
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"ດຶງເອົາຂໍ້ມູນໜ້າຈໍ"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນ ດຶງເອົາຂໍ້ມູນກ່ຽວກັບໜ້າຈໍຈາກໂຕຈັດການໜ້າຈໍ. ແອັບຯທີ່ບໍ່ປອດໄພອາດດຶງເອົາຂໍ້ມູນທີ່ໃຊ້ສຳລັບພາຍໃນລະບົບໄດ້."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"ກັ່ນຕອງເຫດການ"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນ ລົງທະບຽນການກັ່ນຕອງຂາເຂົ້າ ທີ່ກັ່ນຕອງການສົ່ງຂໍ້ມູນເຫດການຜູ່ໃຊ້ທັງໝົດ ກ່ອນທີ່ພວກມັນຈະຖືກເຜີຍແຜ່. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດຄວບຄຸມ UI ຂອງລະບົບໂດຍບໍ່ຕ້ອງໃຫ້ຜູ່ໃຊ້ຈັດການໄດ້."</string>
+    <string name="permlab_magnify_display" msgid="5973626738170618775">"ຂະຫຍາຍການສະແດງຜົນ"</string>
+    <string name="permdesc_magnify_display" msgid="7121235684515003792">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນ ສາມາດຂະຫຍາຍເນື້ອຫາທີ່ສະແດງຜົນໄດ້. ແອັບພລິເຄຊັນທີ່ເປັນອັນຕະລາຍ ອາດປ່ຽນເນື້ອຫາທີ່ສະແດງໃນລັກສະນະ ທີ່ເຮັດໃຫ້ບໍ່ສາມາດນຳໃຊ້ອຸປະກອນໄດ້."</string>
+    <string name="permlab_shutdown" msgid="7185747824038909016">"ປິດລົງບາງສ່ວນ"</string>
+    <string name="permdesc_shutdown" msgid="7046500838746291775">"ກຳນົດໃຫ້ໂຕຈັດການກິດຈະກຳຢູ່ໃນສະຖານະປິດລະບົບ ໂດຍບໍ່ໄດ້ປິດລະບົບຢ່າງສົມບູນ."</string>
+    <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"ຂັດຂວາງການສະລັບແອັບຯ"</string>
+    <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"ປ້ອງກັນບໍ່ໃຫ້ຜູ່ໃຊ້ສະຫຼັບໄປຫາແອັບຯອື່ນ."</string>
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"ດຶງຂໍ້ມູນແອັບຯໃນປັດຈຸບັນ"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="8153651434145132505">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງດຶງຂໍ້ມູນສ່ວນໂຕ ກ່ຽວກັບແອັບພລິເຄຊັນ ແລະ ການບໍລິການປັດຈຸບັນໃນໜ້າຈໍໄດ້."</string>
+    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"ຕິດຕາມ ແລະຄວບຄຸມການເປີດໂຕຂອງແອັບຯທັງໝົດ"</string>
+    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"ອະນຸຍາດໃຫ້ແອັບຯ ຕິດຕາມ ແລະຄວບຄຸມວິທີທີ່ລະບົບເລີ່ມການເຮັດວຽກຕ່າງໆ. ແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດເຮັດໃຫ້ລະບົບທັງໝົດເກີດອັນຕະລາຍໄດ້. ການກຳນົດສິດນີ້ຈຳເປັນສຳລັບການພັດທະນາເທົ່ານັ້ນ, ບໍ່ແມ່ນສຳລັບການນຳໃຊ້ທົ່ວໄປ."</string>
+    <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"ສົ່ງການກະຈ່າຍຂໍ້ມູນທີ່ເອົາແພັກເກດອອກແລ້ວ"</string>
+    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"ອະນຸຍາດໃຫ້ແອັບຯສົ່ງການແຈ້ງເຕືອນວ່າ ແພັກເກັດຂອງແອັບຯດັ່ງໄດ້ລຶບອອກໄປແລ້ວ. ແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດໃຊ້ຄວາມສາມາດນີ້ ເພື່ອປິດການເຮັດວຽກຂອງແອັບຯອື່ນໆ ທີ່ກຳລັງເຮັດວຽກຢູ່."</string>
+    <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"ສົ່ງການກະຈາຍ SMS ທີ່ໄດ້ຮັບ"</string>
+    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"ອະນຸຍາດໃຫ້ແອັບຯ ກະຈາຍສັນຍານການແຈ້ງເຕືອນວ່າຂໍ້ຄວາມ SMS ໄດ້ຮັບແລ້ວ. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດຈະໃຊ້ສິ່ງນີ້ໃນການປອມແປງຂໍ້ຄວາມ SMS ຂາເຂົ້າ."</string>
+    <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"ສົ່ງການກະຈາຍ WAP-PUSH ທີ່ໄດ້ຮັບ"</string>
+    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"ອະນຸຍາດໃຫ້ແອັບຯສົ່ງການແຈ້ງເຕືອນໃນເວລາທີ່ໄດ້ຮັບຂໍ້ມຄວາມ WAP PUSH. ແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດໃຊ້ການກະທຳນີ້ເພື່ອປອມການໄດ້ຮັບຂໍ້ຄວາມ MMS ຫຼືລັກປ່ຽນເນື້ອຫາຂອງໜ້າເວັບຕ່າງໆ ດ້ວຍສິ່ງອັນຕະລາຍທັງຫຼາຍຢ່າງງຽບໆ."</string>
+    <string name="permlab_setProcessLimit" msgid="2451873664363662666">"ຈຳກັດຈຳນວນຂອງໂປຣເຊສທີ່ເຮັດວຽກຢູ່"</string>
+    <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"ອະນຸຍາດໃຫ້ແອັບຯຄວບຄຸມຈຳນວນສູງສຸດ ຂອງໂປຣເຊສທີ່ຈະເຮັດວຽກ. ບໍ່ຄວນຖືກໃຊ້ກັບແອັບພລິເຄຊັນທົ່ວໄປ."</string>
+    <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"ບັງຄັບໃຫ້ແອັບຯທີ່ເຮັດວຽກຢູ່ພື້ນຫຼັງປິດໂຕລົງ"</string>
+    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"ອະນຸຍາດໃຫ້ແອັບຯຄວບຄຸມວ່າການເຮັດວຽກໃດ ຄວນຈະຖືກປິດລົງ ຫຼັງຈາກທີ່ພວກມັນຖືກປ່ຽນໃຫ້ໄປເຮັດວຽກໃນຫຼັງລະບົບ. ບໍ່ຄວນໃຊ້ກັບແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_batteryStats" msgid="2789610673514103364">"ອ່ານສະຖິຕິແບັດເຕີຣີ"</string>
+    <string name="permdesc_batteryStats" msgid="5897346582882915114">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນ ອ່ານຂໍ້ມູນການນຳໃຊ້ປະຈຸບັນຂອງຖ່ານໃນລະດັບຕໍ່າ. ອາດຈະເຮັດໃຫ້ແອັບພລິເຄຊັນ ສາມາດຊອກຫາຂໍ້ມູນລະອຽດ ກ່ຽວກັບແອັບຯທີ່ທ່ານໃຊ້."</string>
+    <string name="permlab_updateBatteryStats" msgid="3719689764536379557">"ແກ້ໄຂສະຖິຕິແບັດເຕີຣີ"</string>
+    <string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"ອະນຸຍາດໃຫ້ແອັບຯ ແກ້ໄຂສະຖິຕິກ່ຽວກັບແບັດເຕີຣີທີ່ເກັບກຳມາໄດ້. ບໍ່ໃຊ້ສຳລັບແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_getAppOpsStats" msgid="1508779687436585744">"ດຶງຂໍ້ມູນສະຖິຕິການເຮັດວຽກຂອງແອັບຯ"</string>
+    <string name="permdesc_getAppOpsStats" msgid="6243887041577912877">"ອະນຸຍາດໃຫ້ແອັບຯດຶງເອົາຂໍ້ມູນ ສະຖິຕິຂອງແອັບພລິເຄຊັນທີ່ໄດ້ເກັບກຳມາ. ບໍ່ໄດ້ໃຊ້ໃນແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"ແກ້ໄຂສະຖິຕິການເຮັດວຽກຂອງແອັບຯ"</string>
+    <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"ອະນຸຍາດໃຫ້ແອັບຯແກ້ໄຂສະຖິຕິ ການເຮັດວຽກຂອງແອັບພລິເຄຊັນທີ່ເກັບກຳມາ. ແອັບຯທົ່ວໄປບໍ່ຈຳເປັນຕ້ອງໃຊ້."</string>
+    <string name="permlab_backup" msgid="470013022865453920">"ຄວບຄຸມການສຳຮອງ ແລະການກູ້ຂໍ້ມູນລະບົບ"</string>
+    <string name="permdesc_backup" msgid="6912230525140589891">"ອະນຸຍາດໃຫ້ແອັບຯຄວບຄຸມກົນໄກການສຳຮອງ ແລະກູ້ຂໍ້ມູນຂອງລະບົບໄດ້. ແອັບຯທຳມະດາບໍ່ໄດ້ໃຊ້."</string>
+    <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"ຢືນຢັນການສຳຮອງ ຫຼືການກູ້ຂໍ້ມູນເຕັມຮູບແບບ"</string>
+    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"ອະນຸຍາດໃຫ້ແອັບຯເປີດການເຮັດວຽກ ຂອງສ່ວນຕິດຕໍ່ຜູ່ໃຊ້ສຳລັບຢືນຢັນການສຳຮອງຂໍ້ມູນເຕັມຮູບແບບ. ບໍ່ມີແອັບຯໃດຕ້ອງໃຊ້ຄຸນສົມບັດນີ້."</string>
+    <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"ສະແດງໜ້າຈໍທີ່ບໍ່ໄດ້ຮັບອະນຸຍາດ"</string>
+    <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"ອະນຸຍາດໃຫ້ແອັບຯສ້າງໜ້າຈໍສຳລັບການນຳໃຊ້ພາຍໃນລະບົບ. ແອັບຯທົ່ວໄປບໍ່ໄດ້ໃຊ້."</string>
+    <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"ບັງແອັບຯອື່ນໆ"</string>
+    <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"ອະນຸຍາດໃຫ້ແອັບຯເຮັດວຽກເທິງແອັບຯ ຫຼືບ່ອນອື່ນໆຂອງສ່ວນຕິດຕໍ່ຜູ່ໃຊ້ ເຊິ່ງອາດລົບກວນການເຮັດວຽກຂອງສ່ວນຕິດຕໍ່ ໃນແອັບພລິເຄຊັນຕ່າງໆ ຫຼືປ່ຽນສິ່ງທີ່ທ່ານຄິດວ່າທ່ານເຫັນໃນແອັບພລິເຄຊັນອື່ນໆໄດ້."</string>
+    <string name="permlab_setAnimationScale" msgid="2805103241153907174">"ແກ້ໄຂຄວາມໄວຂອງອະນິເມຊັນໂດຍຮວມ"</string>
+    <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"ອະນຸຍາດໃຫ້ແອັບຯ ປ່ຽນຄວາມໄວອະນິເມຊັນທົ່ວໄປ (ອະນິເມຊັນໄວຂຶ້ນ ຫຼືຊ້າລົງ) ໄດ້ຕະຫຼອດເວລາ."</string>
+    <string name="permlab_manageAppTokens" msgid="1286505717050121370">"ຈັດການໂທເຄນຂອງແອັບຯ"</string>
+    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"ອະນຸຍາດໃຫ້ແອັບຯສ້າງ ແລະຈັດການໂທເຄນຂອງຕົນເອງ ໂດຍຂ້າມການຈັດຕາມລຳດັບ Z ປົກກະຕິຂອງພວກມັນໄປ. ແອັບຯທົ່ວໄປບໍ່ຄວນຈຳເປັນຕ້ອງໃຊ້."</string>
+    <string name="permlab_freezeScreen" msgid="4708181184441880175">"ຄ້າງໜ້າຈໍ"</string>
+    <string name="permdesc_freezeScreen" msgid="8558923789222670064">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນຄ້າງໜ້າຈໍໄວ້ຊົ່ວຄາວ ສຳລັບການປ່ຽນເປັນແບບເຕັມໜ້າຈໍ."</string>
+    <string name="permlab_injectEvents" msgid="1378746584023586600">"ກົດປຸ່ມແລະປຸ່ມຄວບຄຸມ"</string>
+    <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"ອະນຸຍາດໃຫ້ແອັບຯສົ່ງກິດຈະກຳການປ້ອນຂໍ້ມູນຂອງມັນ (ເຊັ່ນ: ການກົດປຸ່ມ ແລະອື່ນໆ) ຫາແອັບຯອື່ນ. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດໃຊ້ຄຸນສົມບັດນີ້ ເພື່ອຄວບຄຸມແທັບເລັດໄດ້."</string>
+    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"ອະນຸຍາດໃຫ້ແອັບຯ ສົ່ງການປ້ອນຂໍ້ມູນຂອງຕົນເອງ (ການກົດປຸ່ມ ແລະອື່ນໆ.) ໃຫ້ແອັບຯອື່ນ. ແອັບຯທີ່ເປັນອັນຕະລາຍ ສາມາດໃຊ້ສິ່ງນີ້ເພື່ອຍຶດເອົາການຄວບຄຸມໂທລະສັບທັງໝົດໄດ້."</string>
+    <string name="permlab_readInputState" msgid="469428900041249234">"ບັນທຶກສິ່ງທີ່ທ່ານພິມ ແລະການກະທຳທີ່ທ່ານເຮັດ"</string>
+    <string name="permdesc_readInputState" msgid="8387754901688728043">"ອະນຸຍາດໃຫ້ແອັບຯເບິ່ງການກົດປຸ່ມຂອງທ່ານ ເມື່ອມີປະຕິສຳພັນກັບແອັບຯອື່ນ (ເຊັ່ນ: ການພິມລະຫັດຜ່ານ). ແອັບຯທົ່ວໄປບໍ່ຄວນຈຳເປັນຕ້ອງໃຊ້."</string>
+    <string name="permlab_bindInputMethod" msgid="3360064620230515776">"ເຊື່ອມໂຍງກັບວິທີປ້ອນຂໍ້ມູນ"</string>
+    <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"ອະນຸຍາດໃຫ້ຜູ່ຖືຜູກກັບອິນເຕີເຟດລະດັບສູງສຸດ ຂອງຮູບແບບການປ້ອນຂໍ້ມູນ. ບໍ່ຈຳເປັນສຳລັບແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"ເຊື່ອມໂຍງກັບບໍລິການຊ່ວຍການເຂົ້າເຖິງໃດນຶ່ງ"</string>
+    <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງ ເຊື່ອມໂຍງສ່ວນຕິດຕໍ່ລະດັບເທິງສຸດ ຂອງບໍລິການການເຂົ້າເຖິງ. ແອັບຯທົ່ວໄປບໍ່ຄວນຈຳເປັນຕ້ອງໃຊ້."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"ຜູກ​ມັດ​ກັບ​ການ​ບໍ​ລິ​ການ​ພິມ"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງຜູກກັບສ່ວນຕິດຕໍ່ຜູ່ໃຊ້ຂອງການບໍລິການການພິມ. ບໍ່ໜ້າຈະຕ້ອງການສຳລັບແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"ເຂົ້າເຖິງວຽກການພິມທັງໝົດ"</string>
+    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງເຂົ້າເຖິງວຽກການພິມທີ່ຖືກສ້າງໂດຍແອັບຯອື່ນ. ບໍ່ໜ້າຈະຕ້ອງການສຳລັບແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"ເຊື່ອມໂຍງກັບບໍລິການ NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"ອະນຸຍາດໃຫ້ຜູ່ຖືອຸປະກອນໃຫ້ສາມາດເຊື່ອມໂຍງແອັບພລິເຄຊັນ ທີ່ຄ້າຍກັບບັດ NFC. ມັນບໍ່ຈຳເປັນຕ້ອງໃຊ້ໃນແອັບຯທຳມະດາ."</string>
+    <string name="permlab_bindTextService" msgid="7358378401915287938">"ເຊື່ອມໂຍງໄປຫາບໍລິການສົ່ງຂໍ້ຄວາມ"</string>
+    <string name="permdesc_bindTextService" msgid="8151968910973998670">"ອະນຸຍາດໃຫ້ຜູ່ຖືຜູກກັບອິນເຕີເຟດລະດັບສູງສຸດ ຂອງບໍລິການຂໍ້ຄວາມ(ຕ.ຢ. SpellCheckerService). ບໍ່ຈຳເປັນສຳລັບແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_bindVpnService" msgid="4708596021161473255">"ເຊື່ອມໂຍງກັບບໍລິການ VPN"</string>
+    <string name="permdesc_bindVpnService" msgid="2067845564581693905">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງເຊື່ອມໂຍງກັບສ່ວນຕິດຕໍ່ລະດັບເທິງສຸດ ຂອງບໍລິການ VPN. ແອັບຯທົ່ວໄປບໍ່ຄວນຈຳເປັນຕ້ອງໃຊ້."</string>
+    <string name="permlab_bindWallpaper" msgid="8716400279937856462">"ເຊື່ອມໂຍງກັບພາບພື້ນຫຼັງ"</string>
+    <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"ອະນຸຍາດໃຫ້ຜູ່ໃຊ້ເຊື່ອມໂຍງກັບສ່ວນຕິດຕໍ່ລະດັບສູງສຸດ ຂອງພາບພື້ນຫຼັງໃດນຶ່ງ. ແອັບຯທຳມະດາບໍ່ຄວນຈຳເປັນຕ້ອງໃຊ້."</string>
+    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ເຊື່ອມໂຍງໄປຫາບໍລິການວິດເຈັດ"</string>
+    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"ອະນຸຍາດໃຫ້ຜູ່ຖືຜູກກັບອິນເຕີເຟດລະດັບສູງສຸດ ຂອງບໍລິການວິເຈັດ. ບໍ່ຈຳເປັນສຳລັບແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"ຕິດຕໍ່ກັບຜູ່ເບິ່ງແຍງອຸປະກອນ"</string>
+    <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງສົ່ງເຈດຕະນາຫາຜູ່ເບິ່ງແຍງລະບົບອຸປະກອນ. ແອັບຯທົ່ວໄປບໍ່ຄວນຈຳເປັນຕ້ອງໃຊ້."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"ເພີ່ມ ຫຼືລຶບຜູ່ເບິ່ງແຍງລະບົບອຸປະກອນ"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງສາມາດລຶບ ຫຼືລຶບຂໍ້ມູນອຸປະກອນທີ່ນຳໃຊ້ໄດ້. ແອັບຯທົ່ວໄປບໍ່ຈຳເປັນຕ້ອງໃຊ້."</string>
+    <string name="permlab_setOrientation" msgid="3365947717163866844">"ປ່ຽນລວງຂອງໜ້າຈໍ"</string>
+    <string name="permdesc_setOrientation" msgid="3046126619316671476">"ອະນຸຍາດໃຫ້ແອັບຯປ່ຽນການໝຸນຂອງໜ້າຈໍໄດ້ທຸກເວລາ. ບໍ່ຄວນຖືກໃຊ້ໃນແອັບພລິເຄຊັນທົ່ວໄປ."</string>
+    <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"ປ່ຽນຄວາມໄວລູກສອນ"</string>
+    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"ອະນຸຍາດໃຫ້ແອັບຯປ່ຽນຄວາມໄວເມົ້າ ຫຼືລູກສອນແທຣັກແພດໃນເວລາໃດກໍໄດ້. ແອັບຯທົ່ວໄປບໍ່ຄວນຈຳເປັນຕ້ອງໃຊ້."</string>
+    <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"ປ່ຽນຮູບແບບແປ້ນພິມ"</string>
+    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"ອະນຸຍາດໃຫ້ແອັບຯປ່ຽນຮູບແບບຂອງແປ້ນຳພິມ. ບໍ່ຈຳເປັນສຳລັບແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"ສົ່ງສັນຍານ Linux ຫາແອັບຯ"</string>
+    <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"ອະນຸຍາດໃຫ້ແອັບຯຮ້ອງຂໍໃຫ້ສົ່ງສັນຍານ ແຈ້ງໄປຫາໂປຣເຊສທີ່ຍັງເຮັດວຽກຢູ່ທັງໝົດ."</string>
+    <string name="permlab_persistentActivity" msgid="8841113627955563938">"ເຮັດໃຫ້ແອັບຯເຮັດວຽກຕະຫຼອດເວລາ"</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"ອະນຸຍາດໃຫ້ແອັບຯ ສາມາດເຮັດໃຫ້ບາງພາກສ່ວນຂອງມັນເອັງ ຄົງໂຕໃນໜ່ວຍຄວາມຈຳ. ສິ່ງນີ້ສາມາດຈຳກັດໜ່ວຍຄວາມຈຳທີ່ສາມາດໃຊ້ໄດ້ໂດຍແອັບຯອື່ນ ເຮັດໃຫ້ແທັບເລັດຊ້າລົງ."</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"ອະນຸຍາດໃຫ້ແອັບຯເຮັດໃຫ້ສ່ວນນຶ່ງຂອງຕົນເອງ ຄົງຢູ່ຖາວອນໃນໜ່ວຍຄວາມຈຳ ເຊິ່ງອາດສາມາດ ເຮັດໃຫ້ການນຳໃຊ້ໜ່ວຍຄວາມຈຳຂອງແອັບຯ ອື່ນຖືກຈຳກັດ ສົ່ງຜົນເຮັດໃຫ້ມືຖືຂອງທ່ານເຮັດວຽກຊ້າລົງໄດ້."</string>
+    <string name="permlab_deletePackages" msgid="184385129537705938">"ລຶບແອັບຯ"</string>
+    <string name="permdesc_deletePackages" msgid="7411480275167205081">"ອະນຸຍາດໃຫ້ແອັບຯລຶບແພັກເກັດ Android ຕ່າງໆໄດ້. ແອັບຯອັນຕະລາຍອາດໃຊ້ຄວາມສາມາດນີ້ ເພື່ອລຶບແອັບຯທີ່ສຳຄັນໄດ້."</string>
+    <string name="permlab_clearAppUserData" msgid="274109191845842756">"ລຶບຂໍ້ມູນຂອງແອັບຯອື່ນ"</string>
+    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"ອະນຸຍາດໃຫ້ແອັບຯລຶບຂໍ້ມູນຜູ່ໃຊ້."</string>
+    <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"ລຶບ cache ຂອງແອັບຯອື່ນ"</string>
+    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"ອະນຸຍາດໃຫ້ແອັບຯລຶບໄຟລ໌ cache ໄດ້."</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"ກວດສອບພື້ນທີ່ຈັດເກັບຂໍ້ມູນແອັບຯ"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"ອະນຸຍາດໃຫ້ແອັບຯດຶງໂຄດ, ຂໍ້ມູນ ແລະຂະໜາດ cache ຂອງມັນໄດ້."</string>
+    <string name="permlab_installPackages" msgid="2199128482820306924">"ຕິດຕັ້ງແອັບຯໂດຍກົງ"</string>
+    <string name="permdesc_installPackages" msgid="5628530972548071284">"ອະນຸຍາດໃຫ້ແອັບຯຕິດຕັ້ງແພັກເກດ Android ໃໝ່ ຫຼືແພັກເກດທີ່ອັບເດດແລ້ວ. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດໃຊ້ຄຸນສົມບັດນີ້ ເພື່ອສ້າງແອັບຯໃໝ່ທີ່ມີສິດອະນຸຍາດສູງກວ່າໄດ້."</string>
+    <string name="permlab_clearAppCache" msgid="7487279391723526815">"ລຶບຂໍ້ມູນ cache ຂອງແອັບຯທັງໝົດ"</string>
+    <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"ອະນຸຍາດໃຫ້ແອັບຯສ້າງພື້ນທີ່ຫວ່າງໃນແທັບເລັດ ໂດຍການລຶບໄຟລ໌ໃນໄດເຣັກທໍຣີ cache ຂອງແອັບພລິເຄຊັນອື່ນ. ຄຸນສົມບັດນີ້ອາດເຮັດໃຫ້ແອັບພລິເຄຊັນອື່ນ ເລີ່ມເຮັດວຽກຊ້າລົງເພາະຕ້ອງຂຽນຂໍ້ມູນຄືນໃໝ່."</string>
+    <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນເພີ່ມເນື້ອທີ່ຫວ່າງໃຫ້ໂທລະສັບ ໂດຍການລຶບໄຟລ໌ໃນໄດເຣັກທໍຣີ cache ຂອງແອັບພລິເຄຊັນອື່ນໆ. ການກະທຳນີ້ອາດເຮັດໃຫ້ແອັບພລິເຄຊັນອື່ນ ເຮັດວຽກໄດ້ຊ້າລົງເນື່ອງຈາກພວກມັນຕ້ອງໄດ້ດຶງຂໍ້ມູນຄືນໃໝ່."</string>
+    <string name="permlab_movePackage" msgid="3289890271645921411">"ຍ້າຍຊັບພະຍາກອນແອັບຯ"</string>
+    <string name="permdesc_movePackage" msgid="319562217778244524">"ອະນຸຍາດໃຫ້ແອັບຯຍ້າຍແຫລ່ງຊັບພະຍາກອນແອັບຯ ຈາກບ່ອນຈັດເກັບຂໍ້ມູນພາຍໃນ ສູ່ບ່ອນຈັດເກັບຂໍ້ມູນພາຍນອກ ແລະໃນທາງກັບກັນໄດ້."</string>
+    <string name="permlab_readLogs" msgid="6615778543198967614">"ອ່ານຂໍ້ມູນບັນທຶກທີ່ສຳຄັນ"</string>
+    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"ອະນຸຍາດໃຫ້ແອັບຯອ່ານໄຟລ໌ບັນທຶກລະບົບຕ່າງໆຂອງລະບົບ. ຄຸນສົມບັດນີ້ຈະອະນຸຍາດໃຫ້ແອັບຯ ສາມາດຄົ້ນພົບຂໍ້ມູນທົ່ວໄປ ກ່ຽວກັບສິ່ງທີ່ທ່ານກຳລັງເຮັດກັບແທັບເລັດ ເຊິ່ງອາດຮວມເຖິງຂໍ້ມູນສ່ວນໂຕນຳໄດ້."</string>
+    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"ອະນຸຍາດໃຫ້ແອັບຯອ່ານໄຟລ໌ບັນທຶກລະບົບຕ່າງໆຂອງລະບົບ. ຄຸນສົມບັດນີ້ຈະອະນຸຍາດໃຫ້ແອັບຯ ສາມາດຄົ້ນພົບຂໍ້ມູນທົ່ວໄປ ກ່ຽວກັບສິ່ງທີ່ທ່ານກຳລັງເຮັດກັບໂທລະສັບ ເຊິ່ງອາດຮວມເຖິງຂໍ້ມູນສ່ວນໂຕນຳໄດ້."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"ໃຊ້ຕົວຖອດລະຫັດໃດກໍໄດ້ເພື່ອການຫຼິ້ນ"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"ອະນຸຍາດໃຫ້ແອັບຯໃຊ້ທຸກຕົວຖອດລະຫັດສື່ທີ່ຕິດຕັ້ງໄວ້ແລ້ວ ເພື່ອການຖອດລະຫັດການຫຼິ້ນໄຟລ໌ຕ່າງໆ."</string>
+    <!-- no translation found for permlab_manageCaCertificates (1678391896786882014) -->
+    <skip />
+    <!-- no translation found for permdesc_manageCaCertificates (4015644047196937014) -->
+    <skip />
+    <string name="permlab_diagnostic" msgid="8076743953908000342">"ອ່ານ/ຂຽນ ໃສ່ຊັບພະຍາກອນທີ່ເປັນຂອງກຸ່ມວິໄຈ"</string>
+    <string name="permdesc_diagnostic" msgid="6608295692002452283">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນອ່ານ ແລະຂຽນ ໃສ່ທຸກຊັບພະຍາກອນທີ່ເປັນຂອງກຸ່ມວິນິໄສ; ຕົວຢ່າງ: ໄຟລ໌ໃນ /dev. ສິ່ງນີ້ອາດສົ່ງຜົນກະທົບຕໍ່ຄວາມສະຖຽນ ແລະຄວາມປອດໄພຂອງລະບົບ. ສິ່ງນີ້ຄວນໃຊ້ສຳຫຼັບການວິເຄາະບັນຫາຈຳເພາະ ຂອງບາງຮາດແວໂດຍຜູ່ຜະລິດ ຫຼືຜູ່ປະຕິບັດການເທົ່ານັ້ນ."</string>
+    <string name="permlab_changeComponentState" msgid="6335576775711095931">"ເປີດ ຫຼືປິດນຳໃຊ້ອົງປະກອບຂອງແອັບຯ"</string>
+    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"ອະນຸຍາດໃຫ້ແອັບຯ ປ່ຽນແປງອົງປະກອບຂອງແອັບຯອື່ນ ວ່າຖືກເປີດນຳໃຊ້ ຫຼືບໍ່. ແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດໃຊ້ຄວາມສາມາດນີ້ ເພື່ອປິດການນຳໃຊ້ຄວາມສາມາດສຳຄັນຂອງແທັບເລັດ. ການກຳນົດສິດນີ້ຄວນຖືກໃຊ້ຢ່າງລະມັດລະວັງ, ເພາະມັນເປັນໄປໄດ້ທີ່ຈະເຮັດໃຫ້ອົງປະກອບຂອງແອັບຯຢູ່ໃນສະຖານະ ໃຊ້ການບໍ່ໄດ້, ບໍ່ແນ່ນອນ ຫຼືບໍ່ສະຖຽນ."</string>
+    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"ອະນຸຍາດໃຫ້ແອັບຯ ປ່ຽນແປງອົງປະກອບຂອງແອັບຯອື່ນ ວ່າຖືກເປີດນຳໃຊ້ ຫຼືບໍ່. ແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດໃຊ້ຄວາມສາມາດນີ້ ເພື່ອປິດການນຳໃຊ້ຄວາມສາມາດສຳຄັນຂອງໂທລະສັບ. ການກຳນົດສິດນີ້ຄວນຖືກໃຊ້ຢ່າງລະມັດລະວັງ, ເພາະມັນເປັນໄປໄດ້ທີ່ຈະເຮັດໃຫ້ອົງປະກອບຂອງແອັບຯຢູ່ໃນສະຖານະ ໃຊ້ການບໍ່ໄດ້, ບໍ່ແນ່ນອນ ຫຼືບໍ່ສະຖຽນ."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"ອະນຸມັດ ຫຼືຖອດຖານການອະນຸຍາດ"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນອະນຸມັດ ຫຼືຖອນການອະນຸມັດສິດໃດນຶ່ງສຳລັບໂຕມັນເອງ ຫຼືແອັບພລິເຄຊັນອື່ນໆ. ແອັບພລິເຄຊັນທີ່ເປັນອັນຕະລາຍ ອາດໃຊ້ຄວາມສາມາດນີ້ ເພື່ອເຂົ້າເຖິງຄຸນສົມບັດບາງຢ່າງທີ່ທ່ານບໍ່ໄດ້ອະນຸມັດໃຫ້ພວກມັນ."</string>
+    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"ຕັ້ງຄ່າແອັບຯທີ່ຕ້ອງການ"</string>
+    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"ອະນຸຍາດໃຫ້ແອັບຯ ແກ້ໄຂແອັບຯທີ່ທ່ານຕ້ອງການໃຊ້. ແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດປ່ຽນແປງແອັບທີ່ເຮັດວຽກຢູ່ໂດຍບໍ່ແຈ້ງໃຫ້ຮູ້ ໂດຍການປອມແປງວ່າເປັນແອັບຯທີ່ທ່ານຕ້ອງການ ເພື່ອເກັບຂໍ້ມູນສ່ວນໂຕ."</string>
+    <string name="permlab_writeSettings" msgid="2226195290955224730">"ແກ້ໄຂການຕັ້ງຄ່າລະບົບ"</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"ອະນຸຍາດໃຫ້ແອັບຯ ແກ້ໄຂຂໍ້ມູນການຕັ້ງຄ່າລະບົບ. ແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດເຮັດໃຫ້ການຕັ້ງຄ່າຂອງລະບົບເສຍຫາຍໄດ້."</string>
+    <string name="permlab_writeSecureSettings" msgid="204676251876718288">"ແກ້ໄຂການຕັ້ງຄ່າລະບົບ"</string>
+    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"ອະນຸຍາດໃຫ້ແອັບຯ ແກ້ໄຂຂໍ້ມູນການຕັ້ງຄ່າຄວາມປອດໄພຂອງລະບົບ. ແອັບຯທົ່ວໄປບໍ່ໄດ້ໃຊ້ຄຸນສົມບັດນີ້."</string>
+    <string name="permlab_writeGservices" msgid="2149426664226152185">"ແກ້ໄຂແຜນທີ່ບໍລິການ Google"</string>
+    <string name="permdesc_writeGservices" msgid="1287309437638380229">"ອະນຸຍາດໃຫ້ແອັບຯ ແກ້ໄຂການວາງແຜນບໍລິການ Google. ບໍ່ໄດ້ໃຊ້ສຳລັບແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"ເຮັດວຽກໃນຕອນລະບົບເລີ່ມ"</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"ອະນຸຍາດໃຫ້ແອັບຯ ເປີດໂຕມັນເອງທັນທີທີ່ເປີດລະບົບຂຶ້ນມາສຳເລັດ. ນີ້ສາມາດເຮັດໃຫ້ການເລີ່ມເປີດຂອງແທັບເລັດໃຊ້ເວລາດົນຂຶ້ນ ແລະເຮັດໃຫ້ການເຮັດວຽກໂດຍຮວມຂອງແທັບເລັດຊ້າລົງ ໂດຍການເຮັດວຽກຕະຫຼອດເວລາ."</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="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="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="default" msgid="589869224625163558">"ອະນຸຍາດໃຫ້ແອັບຯແກ້ໄຂຂໍ້ມູນກ່ຽວກັບລາຍຊື່ຜູ່ຕິດຕໍ່ ທີ່ບັນທຶກໃນໂທລະສັບຂອງທ່ານ ຮວມທັງຄວາມຖີ່ຂອງການໂທ, ການອີເມວ ຫຼືການຕິດຕໍ່ໃນຮູບແບບອື່ນກັບລາຍຊື່ຜູ່ຕິດຕໍ່ໃດນຶ່ງນຳ. ການອະນຸຍາດນີ້ຈະເຮັດໃຫ້ແອັບຯ ສາມາດລຶບຂໍ້ມູນລາຍຊື່ຜູ່ຕິດຕໍ່ໄດ້."</string>
+    <string name="permlab_readCallLog" msgid="3478133184624102739">"ອ່ານບັນທຶກການໂທ"</string>
+    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"ອະນຸຍາດໃຫ້ແອັບຯ ອ່ານບັນທຶກການໂທຂອງແທັບເລັດທ່ານ ຮວມທັງຂໍ້ມູນການໂທເຂົ້າ ແລະການໂທອອກ. ການກຳນົດສິດນີ້ເຮັດໃຫ້ແອັບຯສາມາດ ບັນທຶກຂໍ້ມູນການໂທຂອງທ່ານ ແລະແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດຈະເຜີຍແຜ່ຂໍ້ມູນການໂທໂດຍທີ່ທ່ານບໍ່ຮັບຮູ້."</string>
+    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"ອະນຸຍາດໃຫ້ແອັບຯອ່ານບັນທຶກການໂທຂອງໂທລະສັບທ່ານ ຮວມທັງຂໍ້ມູນກ່ຽວກັບສາຍໂທເຂົ້າ ແລະໂທອອກ. ການອະນຸຍາດນີ້ຈະເຮັດໃຫ້ແອັບຯ ສາມາດບັນທຶກຂໍ້ມູນການໂທ ແລະເຮັດໃຫ້ແອັບຯທີ່ເປັນອັນຕະລາຍສາມາດ ສົ່ງຕໍ່ຂໍ້ມູນບັນທຶກການໂທໂດຍບໍ່ໃຫ້ທ່ານຮູ້ໄດ້."</string>
+    <string name="permlab_writeCallLog" msgid="8552045664743499354">"ຂຽນຂໍ້ມູນການໂທ"</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ອະນຸຍາດໃຫ້ແອັບຯແກ້ໄຂບັນທຶກການໂທຂອງແທັບເລັດ ຮວມທັງຂໍ້ມູນກ່ຽວກັບການໂທອອກ ແລະໂທເຂົ້ານຳ. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດໃຊ້ຄຸນສົມບັດນີ້ເພື່ອລຶບ ຫຼືແກ້ໄຂບັນທຶກການໂທຂອງທ່ານໄດ້."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"ອະນຸຍາດໃຫ້ແອັບຯ ແກ້ໄຂລາຍການການໂທໃນໂທລະສັບຂອງທ່ານ, ຮວມທັງຂໍ້ມູນກ່ຽວກັບສາຍໂທເຂົ້າ ແລະການໂທອອກ. ແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດໃຊ້ຄວາມສາມາດນີ້ ເພື່ອລຶບ ຫຼືແກ້ໄຂລາຍການການໂທຂອງທ່ານໄດ້."</string>
+    <string name="permlab_readProfile" msgid="4701889852612716678">"ອ່ານບັດລາຍຊື່ຜູ່ຕິດຕໍ່ຂອງທ່ານເອງ"</string>
+    <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"ອະນຸຍາດໃຫ້ແອັບຯ ອ່ານຂໍ້ມູນໂປໄຟລ໌ສ່ວນໂຕໃນອຸປະກອນຂອງທ່ານເຊັ່ນ: ຊື່ຂອງທ່ານ ແລະຂໍ້ມູນການຕິດຕໍ່ຂອງທ່ານ. ນີ້ໝາຍຄວາມວ່າແອັບຯຈະສາມາດລະບຸໂຕຕົນຂອງທ່ານ ແລະສົ່ງຂໍ້ມູນໂປຣໄຟລ໌ຂອງທ່ານໃຫ້ຜູ່ອື່ນໄດ້."</string>
+    <string name="permlab_writeProfile" msgid="907793628777397643">"ແກ້ໄຂບັດລາຍຊື່ຜູ່ຕິດຕໍ່ຂອງທ່ານເອງ"</string>
+    <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"ອະນຸຍາດໃຫ້ແອັບຯ ປ່ຽນແປງ ຫຼືເພີ່ມຂໍ້ມູນໃສ່ໂປຣໄຟລ໌ສ່ວນບຸກຄົນທີ່ເກັບໄວ້ໃນອຸປະກອນຂອງທ່ານ, ເຊັ່ນ: ຊື່ ແລະຂໍ້ມູນຕິດຕໍ່ທ່ານ. ນີ້ໝາຍຄວາມວ່າແອັບຯສາມາດບົ່ງບອກໂຕທ່ານ ແລະອາດສົ່ງຂໍ້ມູນໂປຣໄຟລ໌ຂອງທ່ານໃຫ້ຜູ່ອື່ນໄດ້."</string>
+    <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"ອ່ານການອັບເດດສັງຄົມອອນລາຍຂອງທ່ານ"</string>
+    <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"ອະນຸຍາດໃຫ້ແອັບຯ ເຂົ້າເຖິງ ແລະຊິ້ງຂໍ້ມູນຂ່າວສານສັງຄົມຈາກທ່ານ ແລະໝູ່ຂອງທ່ານ. ຄວນລະມັດລະວັງໃນເວລາທີ່ແລກປ່ຽນຂໍ້ມູນ -- ນີ້ຈະເປັນການອະນຸຍາດໃຫ້ແອັບຯ ອ່ານການສື່ສານລະຫວ່າງທ່ານ ກັບໝູ່ຂອງທ່ານເທິງເຄືອຂ່າຍສັງຄົມ ໂດຍບໍ່ຄຳນຶງເຖິງຄວາມລັບ. ໝາຍເຫດ: ການກຳນົດສິດນີ້ອາດບໍ່ໄດ້ບັງຄັບໃຊ້ໃນທຸກເຄືອຂ່າຍສັງຄົມ."</string>
+    <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"ຂຽນໃສ່ເຄືອຂ່າຍສັງຄົມຂອງທ່ານ"</string>
+    <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"ອະນຸຍາດໃຫ້ແອັບຯສະແດງການອັບເດດຈາກໝູ່ຂອງທ່ານ. ຄວນລະວັງໃນການແປ່ງປັນຂໍ້ມູນ. ມັນຈະໄປອະນຸຍາດໃຫ້ແອັບຯ ສ້າງຂໍ້ຄວາມທີ່ອ້າງວ່າມາຈາກໝູ່ຂອງທ່ານ. ໝາຍເຫດ: ການອະນຸຍາດອາດບໍ່ຖືກບັງຄັບ ໃນບໍລິການເຄືອຂ່າຍສັງຄອມອອນລາຍທຸກອັນ."</string>
+    <string name="permlab_readCalendar" msgid="5972727560257612398">"ອ່ານກຳນົດການໃນປະຕິທິນຮວມທັງຂໍ້ມູນຄວາມລັບ"</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"ອະນຸຍາດໃຫ້ແອັບຯ ອ່ານການນັດໝາຍທັງໝົດທີ່ມີບັນທຶກໃນແທັບເລັດຂອງທ່ານ, ຮວມທັງຂອງໝູ່ ຫຼືໝູ່ທີ່ເຮັດວຽກນຳກັນໄດ້ ເຊິ່ງອາດເຮັດໃຫ້ແອັບຯສາມາດສົ່ງຕໍ່ ຫຼືບັນທຶກຂໍ້ມູນປະຕິທິນຂອງທ່ານ ບໍ່ວ່າຈະເປັນເລື່ອງຄວາມລັບ ຫຼືເລື່ອງລະອຽດອ່ອນແບບໃດກໍຕາມ."</string>
+    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"ອະນຸຍາດໃຫ້ແອັບຯ ອ່ານກຳນົດການໃນປະຕິທິນທັງໝົດ ທີ່ເກັບໄວ້ໃນໂທລະສັບຂອງທ່ານ, ຮວມເຖິງຂອງໝູ່ຄູ່ ຫຼືເພື່ອນຮ່ວມວຽກ. ນີ້ອາດຈະເຮັດໃຫ້ແອັບຯສາມາດເຜີຍແຜ່ ຫຼືບັນທຶກຂໍ້ມູນປະຕິທິນຂອງທ່ານ, ໂດຍບໍ່ຄຳນຶງເຖິງ ຄວາມລະອຽດອ່ອນ ຫຼືຄວາມລັບໃດໆໄດ້."</string>
+    <string name="permlab_writeCalendar" msgid="8438874755193825647">"ເພີ່ມ ຫຼືແກ້ໄຂນັດໝາຍໃນປະຕິທິນ ແລະສົ່ງອີເມວຫາຜູ່ເຂົ້າຮ່ວມໂດຍບໍ່ຕ້ອງໃຫ້ເຈົ້າຂອງຮັບຮູ້"</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"ອະນຸຍາດໃຫ້ແອັບຯເພີ່ມ, ລຶບ ແລະປ່ຽນກິດຈະກຳທີ່ທ່ານສາມາດແກ້ໄຂ ໃນແທັບເລັດຂອງທ່ານໄດ້ ຮວມທັງກິດຈະກຳຂອງໝູ່ ຫຼືໝູ່ຮ່ວມເຮັດວຽກ ເຊິ່ງອາດອະນຸຍາດໃຫ້ແອັບຯສົ່ງຂໍ້ຄວາມທີ່ຄືກັບວ່າ ມາຈາກເຈົ້າຂອງປະຕິທິນ ຫຼືແກ້ໄຂການນັດໝາຍໄດ້ ໂດຍບໍ່ໃຫ້ເຈົ້າຂອງຮັບຮູ້."</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"ອະນຸຍາດໃຫ້ແອັບຯ ເພີ່ມ, ລຶບ, ປ່ຽນແປງນັດໝາຍທີ່ທ່ານສາມາດແກ້ໄຂໄດ້ໃນໂທລະສັບຂອງທ່ານ, ຮວມທັງຂອງໝູ່ຄູ່ ຫຼືເພື່ອນຮ່ວມວຽກ. ນີ້ອາດເຮັດໃຫ້ແອັບຯສາມາດສົ່ງຂໍ້ຄວາມ ທີ່ເບິ່ງຄືວ່າມາຈາກເຈົ້າຂອງປະຕິທິນ ຫຼືແກ້ໄຂນັດໝາຍໂດຍທີ່ທ່ານບໍ່ໄດ້ຮັບຮູ້ໄດ້."</string>
+    <string name="permlab_accessMockLocation" msgid="8688334974036823330">"ຈຳລອງແຫລ່ງຂໍ້ມູນສະຖານທີ່ເພື່ອການທົດສອບ"</string>
+    <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"ສ້າງແຫລ່ງຂໍ້ມູນຈຳລອງຂອງສະຖານທີ່ ເພື່ອການທົດສອບ ຫຼືຕິດຕັ້ງແຫລ່ງຂໍ້ມູນສະຖານທີ່ໃໝ່. ນີ້ຈະອະນຸຍາດໃຫ້ແອັບຯສາມາດຂຽນທັບຂໍ້ມູນຂອງສະຖານທີ່ ແລະ/ຫຼື ຂໍ້ມູນທີ່ສົ່ງກັບມາຈາກແຫລ່ງຂໍ້ມູນສະຖານທີ່ອື່ນ ເຊັ່ນ: GPS ຫຼືແຫລ່ງຂໍ້ມູນສະຖານທີ່ອື່ນໄດ້."</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"ເຂົ້າເຖິງຄຳສັ່ງຜູ່ໃຫ້ບໍລິການພິກັດສະຖານທີ່"</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"ອະນຸຍາດໃຫ້ແອັບຯ ເຂົ້າເຖິງຄຳສັ່ງເພີ່ມເຕີມຂອງຜູ່ໃຫ້ບໍລິການສະຖານທີ່. ນີ້ອາດຈະເປັນການເຮັດໃຫ້ແອັບຯ ລົບກວນການເຮັດວຽກຂອງ GPS ຫຼືແຫລ່ງຂໍ້ມູນສະຖານທີ່ອື່ນໆໄດ້."</string>
+    <string name="permlab_installLocationProvider" msgid="6578101199825193873">"ສິດໃນການຕິດຕັ້ງແຫຼ່ງສະໜອງສະຖານທີ່"</string>
+    <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"ສ້າງສະຖານທີ່ຈຳລອງເພື່ອການທົດລອງ ຫຼືຕິດຕັ້ງແຫຼ່ງຂໍ້ມູນສະຖານທີ່ໃໝ່. ສິ່ງນີ້ເຮັດໃຫ້ແອັບຯສາມາດຂຽນທັບສະຖານທີ່ ແລະ/ຫຼື ສະຖານະທີ່ໄດ້ຈາກແຫຼ່ງສະຖານທີ່ອື່ນເຊັ່ນ: GPS ຫຼືຜູ່ສະໜອງສະຖານທີ່ຕ່າງໆ."</string>
+    <string name="permlab_accessFineLocation" msgid="1191898061965273372">"ສະຖານທີ່ແນ່ນອນ (ອ້າງອີງຈາກ GPS ແລະເຄືອຂ່າຍ)"</string>
+    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"ອະນຸຍາດໃຫ້ແອັບຯ ຮັບຕຳແໜ່ງສະຖານທີ່ລະອຽດຂອງທ່ານໂດຍໃຊ້ GPS ຫຼືແຫລ່ງຂໍ້ມູນເຄືອຂ່າຍສະຖານທີ່ເຊັ່ນ: ເສົາສັນຍານມືຖື ແລະ Wi-Fi. ບໍລິການສະຖານທີ່ເຫຼົ່ານີ້ຕ້ອງຖືກເປີດນຳໃຊ້ ແລະແລະມີຂໍ້ມູນໃຫ້ກັບອຸປະກອນຂອງທ່ານ ເພື່ອໃຫ້ແອັບຯໃຊ້ໄດ້. ແອັບຯຕ່າງໆອາດໃຊ້ຂໍ້ມູນນີ້ເພື່ອລະບຸສະຖານທີ່ຢູ່ຂອງທ່ານ ແລະອາດນຳໃຊ້ແບັດເຕີຣີເພີ່ມເຕີມໄດ້."</string>
+    <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"ສະຖານທີ່ໂດຍປະມານ (ອ້າງອີງຈາກເຄືອຂ່າຍ)"</string>
+    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"ອະນຸຍາດໃຫ້ແອັບຯ ລະບຸສະຖານທີ່ໂດຍປະມານຂອງທ່ານ. ສະຖານທີ່ນີ້ໄດ້ຮັບມາຈາກບໍລິການສະຖານທີ່ ໂດຍອາໃສສະຖານທີ່ເຄືອຂ່າຍເຊັ່ນ: ເສົາສັນຍານ ແລະ Wi-Fi. ບໍລິການສະຖານທີ່ເຫຼົ່ານີ້ຕ້ອງຖືກເປີດໃຊ້ ແລະ ມີໃນອຸປະກອນຂອງທ່ານເພື່ອທີ່ແອັບຯຈະສາມາດໃຊ້ພວກມັນໄດ້. ແອັບຯອາດຈະໃຊ້ຄຸນສົມບັດນີ້ ເພື່ອກວດສອບສະຖານທີ່ໂດຍປະມານຂອງທ່ານ."</string>
+    <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"ເຂົ້າເຖິງ SurfaceFlinger"</string>
+    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"ອະນຸຍາດໃຫ້ແອັບຯນຳໃຊ້ຄວາມສາມາດລະດັບຕ່ຳ SurfaceFlinger"</string>
+    <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"ອ່ານເຟຣມບັບເຟີ"</string>
+    <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"ອະນຸຍາດໃຫ້ແອັບຯອ່ານເນື້ອຫາຂອງເຟຣມບັບເຟີ."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"ເຂົ້າເຖິງ InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"ອະນຸຍາດໃຫ້ແອັບຯນຳໃຊ້ຄວາມສາມາດ InputFlinger ລະດັບຕ່ຳ"</string>
+    <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"ປັບຄ່າການສະແດງຜົນ WiFi"</string>
+    <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"ອະນຸຍາດໃຫ້ແອັບຯຕັ້ງຄ່າ ແລະເຊື່ອມຕໍ່ຈໍສະແດງຜົນ WiFi."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"ຄວບຄຸມການສະແດງ WiFi"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"ອະນຸຍາດໃຫ້ແອັບຯ ຄວບຄຸມຄວາມສາມາດລະດັບຕໍ່າຂອງການສະແດງຜົນ Wifi."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"ບັນທຶກສຽງອອກ"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"ອະນຸຍາດໃຫ້ແອັບຯບັນທຶກ ແລະປ່ຽນເສັ້ນທາງການປ້ອນຂໍ້ມູນອອກຂອງສຽງ."</string>
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"ບັນທຶກວິດີໂອອອກ"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"ອະນຸຍາດໃຫ້ແອັບຯບັນທຶກ ແລະປ່ຽນເສັ້ນທາງການປ້ອນຂໍ້ມູນອອກຂອງວິດີໂອ."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"ບັນທຶກວິດີໂອອອກຢ່າງປອດໄພ"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"ອະນຸຍາດໃຫ້ແອັບຯບັນທຶກ ແລະປ່ຽນເສັ້ນທາງການປ້ອນຂໍ້ມູນອອກຂອງວິດີໂອທີ່ປອດໄພ."</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="4906839301087980680">"ອະນຸຍາດໃຫ້ແອັບຯບັນທຶກສຽງດ້ວຍໄມໂຄຣໂຟນໄດ້. ການອະນຸຍາດນີ້ຈະເຮັດໃຫ້ແອັບຯ ສາມາດບັນທຶກສຽງໄດ້ຕະຫລອດເວລາ ໂດຍບໍ່ຕ້ອງຖ້າການຢືນຢັນຈາກທ່ານ."</string>
+    <string name="permlab_camera" msgid="3616391919559751192">"ຖ່າຍຮູບ ແລະວິດີໂອ"</string>
+    <string name="permdesc_camera" msgid="8497216524735535009">"ອະນຸຍາດໃຫ້ແອັບຯຖ່າຍຮູບ ແລະວິດີໂອດ້ວຍກ້ອງຖ່າຍຮູບ. ການອະນຸຍາດນີ້ຈະອານຸຍາດໃຫ້ແອັບຯ ສາມາດໃຊ້ກ້ອງຖ່າຍຮູບໄດ້ຕະຫລອດເວລາ ໂດຍບໍ່ຕ້ອງຖ້າການຢືນຢັນຈາກທ່ານ."</string>
+    <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"ປິດໄຟສັນຍານ LED ເມື່ອນຳໃຊ້ກ້ອງ"</string>
+    <string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນທີ່ມາກັບໂຕເຄື່ອງ ປິດການນຳໃຊ້ໄຟ LED ໃນກ້ອງຖ່າຍຮູບ."</string>
+    <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"ປິດການນຳໃຊ້ແທັບເລັດຖາວອນ"</string>
+    <string name="permlab_brick" product="default" msgid="8337817093326370537">"ປິດການເຮັດວຽກຂອງໂທລະສັບຖາວອນ"</string>
+    <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"ອະນຸຍາດໃຫ້ແອັບຯປິດການນຳໃຊ້ແທັບເລັດທັງໝົດໂດຍຖາວອນ. ຄຸນສົມບັດນີ້ເປັນສິ່ງອັນຕະລາຍຫຼາຍ."</string>
+    <string name="permdesc_brick" product="default" msgid="5788903297627283099">"ອະນຸຍາດໃຫ້ແອັບຯປິດການນຳໃຊ້ໂທລະສັບທັງໝົດແບບຖາວອນ. ອັນຕະລາຍຫຼາຍ."</string>
+    <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"ບັງຄັບໃຫ້ແທັບເລັດປິດແລ້ວເປີດໃໝ່"</string>
+    <string name="permlab_reboot" product="default" msgid="2898560872462638242">"ບັງຄັບໃຫ້ໂທລະສັບປິດແລ້ວເປີດໃໝ່"</string>
+    <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"ອະນຸຍາດໃຫ້ແອັບຯ ບັງຄັບແທັບເລັດໃຫ້ປິດເປີດໃໝ່."</string>
+    <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"ອະນຸຍາດໃຫ້ແອັບຯ ບັງຄັບໃຫ້ໂທລະສັບປິດເປີດໃໝ່."</string>
+    <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"ເຂົ້າເຖິງໄຟລ໌ລະບົບຂອງບ່ອນຈັດເກັບຂໍ້ມູນ USB"</string>
+    <string name="permlab_mount_unmount_filesystems" product="default" msgid="4402305049890953810">"ເຂົ້າເຖິງໄຟລ໌ລະບົບຂອງ SD card"</string>
+    <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"ອະນຸຍາດໃຫ້ແອັບຯ ເຊື່ອມຕໍ່ ແລະຖອນການເຊື່ອມຕໍ່ຈາກລະບົບໄຟລ໌ ຂອງອຸປະກອນເກັບຂໍ້ມູນແບບຖອດອອກໄດ້."</string>
+    <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"ລຶບບ່ອນຈັດເກັບຂໍ້ມູນ USB"</string>
+    <string name="permlab_mount_format_filesystems" product="default" msgid="262582698639274056">"ລຶບ SD card"</string>
+    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"ອະນຸຍາດໃຫ້ແອັບຯ ຟໍແມັດອຸປະກອນເກັບຂໍ້ມູນທີ່ສາມາດຖອດອອກໄດ້."</string>
+    <string name="permlab_asec_access" msgid="3411338632002193846">"ດຶງຂໍ້ມູນຈາກບ່ອນຈັດເກັບຂໍ້ມູນພາຍໃນ"</string>
+    <string name="permdesc_asec_access" msgid="3094563844593878548">"ອະນຸຍາດໃຫ້ແອັບຯດຶງຂໍ້ມູນໃນບ່ອນຈັດເກັບຂໍ້ມູນພາຍໃນໄດ້."</string>
+    <string name="permlab_asec_create" msgid="6414757234789336327">"ສ້າງບ່ອນຈັດເກັບຂໍ້ມູນພາຍໃນ"</string>
+    <string name="permdesc_asec_create" msgid="4558869273585856876">"ອະນຸຍາດໃຫ້ແອັບຯສ້າງພື້ນທີ່ຈັດເກັບຂໍ້ມູນພາຍໃນ."</string>
+    <string name="permlab_asec_destroy" msgid="526928328301618022">"ທຳລາຍບ່ອນຈັດເກັບຂໍ້ມູນພາຍໃນ"</string>
+    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"ອະນຸຍາດໃຫ້ແອັບຯທຳລາຍບ່ອນຈັດເກັບຂໍ້ມູນພາຍໃນ."</string>
+    <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"ເຊື່ອມຕໍ່/ຖອນການເຊື່ອມຕໍ່ ບ່ອນຈັດເກັບຂໍ້ມູນພາຍໃນ"</string>
+    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"ອະນຸຍາດໃຫ້ແອັບຯ ເຊື່ອມຕໍ່/ຖອດການເຊື່ອມຕໍ່ ບ່ອນຈັດເກັບຂໍ້ມູນພາຍໃນ."</string>
+    <string name="permlab_asec_rename" msgid="7496633954080472417">"ປ່ຽນຊື່ບ່ອນເກັບຂໍ້ມູນພາຍໃນ"</string>
+    <string name="permdesc_asec_rename" msgid="1794757588472127675">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນປ່ຽນຊື່ພື້ນທີ່ເກັບຂໍ້ມູນພາຍໃນ."</string>
+    <string name="permlab_vibrate" msgid="7696427026057705834">"ຄວບຄຸມການສັ່ນ"</string>
+    <string name="permdesc_vibrate" msgid="6284989245902300945">"ອະນຸຍາດໃຫ້ແອັບຯຄວບຄຸມໂຕສັ່ນ."</string>
+    <string name="permlab_flashlight" msgid="2155920810121984215">"ຄວບຄຸມໄຟແຟລດ"</string>
+    <string name="permdesc_flashlight" msgid="6522284794568368310">"ອະນຸຍາດໃຫ້ແອັບຯ ຄວບຄຸມໄຟແຟລດ."</string>
+    <string name="permlab_manageUsb" msgid="1113453430645402723">"ຈັດການການກຳນົດຄ່າ ແລະການອະນຸຍາດສຳລັບອຸປະກອນ USB"</string>
+    <string name="permdesc_manageUsb" msgid="7776155430218239833">"ອະນຸຍາດໃຫ້ແອັບຯ ຈັດການການຕັ້ງຄ່າຄວາມຕ້ອງການ ແລະການກຳນົດສິດສຳລັບອຸປະກອນ USB."</string>
+    <string name="permlab_accessMtp" msgid="4953468676795917042">"ໃຊ້ໂປຣໂຕຄອນ MTP"</string>
+    <string name="permdesc_accessMtp" msgid="6532961200486791570">"ອະນຸຍາດການເຂົ້າເຖິງ kernel MPT driver ເພື່ອໃຊ້ໂປຣໂຕຄອນ MTP USB."</string>
+    <string name="permlab_hardware_test" msgid="4148290860400659146">"ທົດສອບຮາດແວ"</string>
+    <string name="permdesc_hardware_test" msgid="6597964191208016605">"ອະນຸຍາດໃຫ້ແອັບຯຄວບຄຸມອຸປະກອນຕໍ່ພ່ວງທັງຫຼາຍ ເພື່ອຈຸດປະສົງການທົດສອບຮາດແວ."</string>
+    <string name="permlab_callPhone" msgid="3925836347681847954">"ໂທຫາເບີໂທລະສັບໂດຍກົງ"</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"ອະນຸຍາດໃຫ້ແອັບຯໂທຫາເບີໂທລະສັບໄດ້ ໂດຍບໍ່ຕ້ອງຖ້າການດຳເນີນການໃດໆຈາກທ່ານ. ຄຸນສົມບັດນີ້ອາດກໍ່ໃຫ້ເກີດຄ່າໃຊ້ຈ່າຍໃນການໂທທີ່ບໍ່ຄາດຄິດໄດ້. ໝາຍເຫດ: ຄຸນສົມບັດນີ້ບໍ່ໄດ້ເປັນການອະນຸຍາດໃຫ້ແອັບຯ ສາມາດໂທຫາເບີສຸກເສີນ. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດເຮັດໃຫ້ທ່ານ ຕ້ອງເສຍຄ່າໂທໂດຍທີ່ບໍ່ໄດ້ຄາດຄິດ."</string>
+    <string name="permlab_callPrivileged" msgid="4198349211108497879">"ໂທໂດຍກົງໄປຫາເບີໂທໃດກໍໄດ້"</string>
+    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"ອະນຸຍາດໃຫ້ແອັບຯໂທອອກຫາເບີໂທລະສັບໃດກໍໄດ້, ຮວມທັງເບີສຸກເສີນ, ໂດຍບໍ່ມີການແຊກແຊງຂອງທ່ານ. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດໂທອອກໂດຍບໍ່ຈຳເປັນ ແລະໂທຫາບໍລິການເບີສຸກເສີນແບບຜິດກົດໝາຍ."</string>
+    <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"ເລີ່ມການຕັ້ງຄ່າແທັບເລັດ CDMA ໂດຍກົງ"</string>
+    <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"ເລີ່ມການຕັ້ງຄ່າໂທລະສັບ CDMA ໂດຍກົງ"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"ອະນຸຍາດໃຫ້ແອັບຯເລີ່ມການເຮັດວຽກຂອງ CDMA. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດເລີ່ມການເຮັດວຽກຂອງ CDMA ໂດຍບໍ່ຈຳເປັນ."</string>
+    <string name="permlab_locationUpdates" msgid="7785408253364335740">"ຄວບຄຸມການແຈ້ງເຕືອນອັບເດດສະຖານທີ່"</string>
+    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"ອະນຸຍາດໃຫ້ແອັບຯ ເປີດ/ປິດ ການເຮັດວຽກຂອງການແຈ້ງເຕືອນອັບເດດສະຖານທີ່ຈາກວິທະຍຸ. ແອັບຯທົ່ວໄປບໍ່ຈຳເປັນຕ້ອງໃຊ້."</string>
+    <string name="permlab_checkinProperties" msgid="7855259461268734914">"ເຂົ້າເຖິງຄຸນສົມບັດການເຊັກອິນ"</string>
+    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"ອະນຸຍາດໃຫ້ແອັບຯໄດ້ຮັບສິດ ອ່ານ/ຂຽນ ໃສ່ສິ່ງທີ່ອັບໂຫຼດຂຶ້ນໂດຍບໍລິການເຊັກອິນ. ບໍ່ໃຊ້ໃນແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_bindGadget" msgid="776905339015863471">"ເລືອກວິດເຈັດ"</string>
+    <string name="permdesc_bindGadget" msgid="8261326938599049290">"ອະນຸຍາດໃຫ້ແອັບຯບອກລະບົບວ່າ ວິດເຈັດໃດສາມາດນຳໃຊ້ໂດຍແອັບຯໃດ. ແອັບຯທີ່ມີການອະນຸຍາດນີ້ຈະມອບການເຂົ້າເຖິງຂໍ້ມູນສ່ວນໂຕ ໃຫ້ກັບແອັບຯອື່ນໄດ້. ບໍ່ໄດ້ໃຊ້ໂດຍແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"ແກ້ໄຂສະຖານະໂທລະສັບ"</string>
+    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"ອະນຸຍາດໃຫ້ແອັບຯຄວບຄຸມຄວາມສາມາດຂອງໂທລະສັບໃນອຸປະກອນ. ແອັບຯທີ່ມີການອະນຸຍາດນີ້ຈະສາມາດສະລັບເຄືອຂ່າຍ, ເປີດ ຫຼືປິດສັນຍານວິທະຍຸ ແລະຄວາມສາມາດອື່ນທີ່ຄ້າຍກັນ ໂດຍບໍ່ມີການແຈ້ງເຕືອນທ່ານ."</string>
+    <string name="permlab_readPhoneState" msgid="9178228524507610486">"ອ່ານສະຖານະ ແລະຂໍ້ມູນລະບຸໂຕຕົນຂອງໂທລະສັບ"</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"ອະນຸຍາດໃຫ້ແອັບຯ ເຂົ້າເຖິງຄວາມສາມາດການໂທລະສັບຂອງອຸປະກອນ. ການກຳນົດສິດນີ້ເຮັດໃຫ້ແອັບຯສາມາດກວດສອບເບີໂທລະສັບ ແລະ ID ຂອງອຸປະກອນ, ບໍ່ວ່າການໂທຈະຍັງດຳເນີນຢູ່ ແລະເບີປາຍທາງເຊື່ອມຕໍ່ຢູ່ຫຼືບໍ່ກໍຕາມ."</string>
+    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"ຂັດຂວາງບໍ່ໃຫ້ປິດໜ້າຈໍແທັບເລັດ"</string>
+    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"ຂັດຂວາງບໍ່ໃຫ້ໂທລະສັບປິດໜ້າຈໍ"</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"ອະນຸຍາດໃຫ້ແອັບຯ ປ້ອງກັນບໍ່ໃຫ້ປິດໜ້າຈໍແທັບເລັດ."</string>
+    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"ອະນຸຍາດໃຫ້ແອັບຯປ້ອງກັນບໍ່ໃຫ້ປິດໜ້າຈໍໂທລະສັບ."</string>
+    <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"ເປີດ ຫຼືປິດແທັບເລັດ"</string>
+    <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"ເປີດ ຫຼືປິດໂທລະສັບ"</string>
+    <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"ອະນຸຍາດໃຫ້ແອັບຯເປີດ ຫຼືປິດແທັບເລັດ."</string>
+    <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນປິດ ຫຼືເປີດແທັບເລັດໄດ້."</string>
+    <string name="permlab_factoryTest" msgid="3715225492696416187">"ເຮັດວຽກໃນໂໝດການທົດສອບຂອງໂຮງງານ"</string>
+    <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"ເຮັດວຽກໃນຮູບແບບທົດສອບໃນລະດັບຕໍ່າຂອງຜູ່ຜະລິດ, ອະນຸຍາດການເຂົ້າເຖິງແບບເຕັມຮູບແບບຫາຮາດແວຂອງແທັບເລັດ. ໃຊ້ໄດ້ສະເພາະໃນເວລາທີ່ແທັບເລັດກຳລັງຢູ່ໃນໂໝດ ການທົດສອບຂອງຜູ່ຜະລິດgmqjkoaho."</string>
+    <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"ເປີດໃຊ້ໃນແບບການທົດສອບຂອງຜູ່ລະລິດໃນລະດັບຕໍ່າ, ອະນຸຍາດການເຂົ້າເຖິງຮາດແວຂອງໂທລະສັບແບບສົມບູນ. ສະເພາະເມື່ອໂທລະສັບຖືກເປີດໃຊ້ ໃນໂໝດການທົດສອບຂອງຜູ່ຜະລິດເທົ່ານັ້ນ."</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_masterClear" msgid="2315750423139697397">"ຣີເຊັດລະບົບໃຫ້ເປັນຄ່າເລີ່ມຕົ້ນທີ່ມາຈາກໂຮງງານ"</string>
+    <string name="permdesc_masterClear" msgid="3665380492633910226">"ອະນຸຍາດໃຫ້ແອັບຯ ຣີເຊັດຄ່າທັງໝົດຂອງລະບົບໃຫ້ກັບໄປເປັນແບບທີ່ມາຈາກໂຮງງານ, ລຶບຂໍ້ມູນ, ການຕັ້ງຄ່າ ແລະແອັບຯທີ່ໄດ້ຕິດຕັ້ງໄວ້ທັງໝົດ."</string>
+    <string name="permlab_setTime" msgid="2021614829591775646">"ຕັ້ງເວລາ"</string>
+    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"ອະນຸຍາດໃຫ້ແອັບຯປ່ຽນເວລາຂອງໂມງໃນແທັບເລັດໄດ້."</string>
+    <string name="permdesc_setTime" product="default" msgid="1855702730738020">"ອະນຸຍາດໃຫ້ແອັບຯປ່ຽນເວລາຂອງໂມງໃນໂທລະສັບໄດ້."</string>
+    <string name="permlab_setTimeZone" msgid="2945079801013077340">"ຕັ້ງເຂດເວລາ"</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"ອະນຸຍາດໃຫ້ແອັບຯປ່ຽນເຂດເວລາຂອງແທັບເລັດ."</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"ອະນຸຍາດໃຫ້ແອັບຯ ປ່ຽນເຂດເວລາຂອງໂທລະສັບ."</string>
+    <string name="permlab_accountManagerService" msgid="4829262349691386986">"ເຮັດໜ້າທີ່ເປັນ AccountManagerService"</string>
+    <string name="permdesc_accountManagerService" msgid="1948455552333615954">"ອະນຸຍາດໃຫ້ແອັບຯເອີ້ນຫາ AccountAuthenticators."</string>
+    <string name="permlab_getAccounts" msgid="1086795467760122114">"ຊອກຫາບັນຊີໃນອຸປະກອນ"</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"ອະນຸຍາດໃຫ້ແອັບຯຮັບເອົາລາຍການຂອງບັນຊີທີ່ຮູ້ຈັກໂດຍແທັບເລັດ. ນີ້ອາດຮວມທັງບັນຊີຕ່າງໆ ທີ່ຖືກສ້າງໂດຍແອັບພລິເຄຊັນທີ່ທ່ານໄດ້ຕິດຕັ້ງໄວ້."</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນ ດຶງຂໍ້ມູນລາຍຊື່ຂອງບັນຊີທີ່ໂທລະສັບມີ ເຊິ່ງອາດຮວມເຖິງບັນຊີທີ່ໃດໆທີ່ສ້າງຂຶ້ນ ໂດຍແອັບພລິເຄຊັນທີ່ທ່ານຕິດຕັ້ງໄວ້."</string>
+    <string name="permlab_authenticateAccounts" msgid="5265908481172736933">"ສ້າງບັນຊີ ແລະຕັ້ງລະຫັດຜ່ານ"</string>
+    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"ອະນຸຍາດໃຫ້ແອັບຯ ໃຊ້ຄວາມສາມາດຂອງຕົວພິສູດສິດບັນຊີຂອງ AccountManager ຮວມທັງການສ້າງບັນຊີ, ການຂໍເບິ່ງ ແລະຕັ້ງຄ່າລະຫັດຜ່ານ."</string>
+    <string name="permlab_manageAccounts" msgid="4983126304757177305">"ສ້າງ ຫຼືລຶບບັນຊີ"</string>
+    <string name="permdesc_manageAccounts" msgid="8698295625488292506">"ອະນຸຍາດໃຫ້ແອັບຯດຳເນີນການເຊັ່ນ: ເພີ່ມ ຫຼືລຶບບັນຊີ ແລະລຶບລະຫັດຜ່ານຂອງບັນຊີໄດ້."</string>
+    <string name="permlab_useCredentials" msgid="235481396163877642">"ໃຊ້ບັນຊີໃນອຸປະກອນ"</string>
+    <string name="permdesc_useCredentials" msgid="7984227147403346422">"ອະນຸຍາດໃຫ້ແອັບຯຮ້ອງຂໍໂທເຄນການພິສູດຢືນຢັນໄດ້."</string>
+    <string name="permlab_accessNetworkState" msgid="4951027964348974773">"ເບິ່ງການເຊື່ອມຕໍ່ເຄືອຂ່າຍ"</string>
+    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"ອະນຸຍາດໃຫ້ແອັບຯ ເບິ່ງຂໍ້ມູນກ່ຽວກັບການເຊື່ອມຕໍ່ເຄືອຂ່າຍ ເຊັ່ນວ່າມີເຄືອຂ່າຍໃດແດ່ ແລະໄດ້ເຊື່ອມຕໍ່ກັບເຄືອຂ່າຍໃດ."</string>
+    <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"ເຂົ້າເຖິງເຄືອຂ່າຍເຕັມຮູບແບບ"</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"ອະນຸຍາດໃຫ້ແອັບຯສ້າງຊັອກເກັດເຄືອຂ່າຍ ແລະໂປຣໂຕຄອນເຄືອຂ່າຍແບບກຳນົດເອງ. ໂປຣແກຣມທ່ອງເວັບ ແລະແອັບພລິເຄຊັນອື່ນໆຈະສົ່ງຂໍ້ມູນສູ່ອິນເຕີເນັດຢູ່ແລ້ວ ດັ່ງນັ້ນການອະນຸຍາດນີ້ຈຶ່ງບໍ່ຈຳເປັນຕ້ອງໃຊ້ ເພື່ອສົ່ງຂໍ້ມູນສູ່ອິນເຕີເນັດ."</string>
+    <string name="permlab_writeApnSettings" msgid="505660159675751896">"ປ່ຽນ/ສະກັດກັ້ນການຕັ້ງຄ່າເຄືອຂ່າຍ ແລະຂໍ້ມູນ"</string>
+    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"ອະນຸຍາດໃຫ້ແອັບຯປ່ຽນການຕັ້ງຄ່າເຄືອຂ່າຍ ແລະສະກັດກັ້ນ ແລະກວດສອບການເດີນທາງຂອງຂໍ້ມູນທັງໝົດ, ຍົກຕົວຢ່າງ: ໃນການປ່ຽນພອດຂອງ Proxy ຂອງ APN ໃດກໍຕາມ. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດຕິດຕາມ, ປ່ຽນແປງ ແລະແກ້ໄຂແພັກເກັດຂອງທ່ານໂດຍທີ່ທ່ານບໍ່ຮູ້ໂຕ."</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_changeBackgroundDataSetting" msgid="1400666012671648741">"ປ່ຽນການຕັ້ງຄ່າການນຳໃຊ້ຂໍ້ມູນພື້ນຫຼັງ"</string>
+    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"ອະນຸຍາດໃຫ້ແອັບຯປ່ຽນການຕັ້ງຄ່າການໃຊ້ອິນເຕີເນັດ ຂອງແອັບຯທີ່ເຮັດວຽກຢູ່ດ້ານຫຼັງລະບົບ."</string>
+    <string name="permlab_accessWifiState" msgid="5202012949247040011">"ເບິ່ງການເຊື່ອມຕໍ່ Wi-Fi"</string>
+    <string name="permdesc_accessWifiState" msgid="5002798077387803726">"ອະນຸຍາດໃຫ້ແອັບຯເບິ່ງຂໍ້ມູນກ່ຽວກັບເຄືອຂ່າຍ Wi-Fi ເຊັ່ນວ່າ WiFi ກຳລັງຖືກນຳໃຊ້ຢູ່ບໍ່ ແລະຊື່ຂອງອຸປະກອນ WiFi ທີ່ກຳລັງເຊື່ອມຕໍ່ຢູ່."</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 Multicast"</string>
+    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"ອະນຸຍາດໃຫ້ແອັບຯຮັບຂໍ້ມູນແພັກເກັດ ທີ່ຖືກສົ່ງ ໄປຫາທຸກອຸປະກອນໃນເຄືອຂ່າຍ WiFi ໂດຍການນຳໃຊ້ການກະຈາຍຂໍ້ມູນໃນວົງກວ້າງ, ບໍ່ແມ່ນສະເພາະແທັບເລັດຂອງທ່ານ. ມັນໃຊ້ພະລັງງານຫຼາຍກວ່າໂຫມດກະຈາຍຂໍ້ມູນແບບໂດຍກົງ."</string>
+    <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"ອະນຸຍາດໃຫ້ແອັບຯ ຮັບຂໍ້ມູນແພັກເກດທີ່ສົ່ງໄປໃຫ້ທຸກອຸປະກອນໃນເຄືອຂ່າຍ Wi-Fi ໂດຍໃຊ້ທີ່ຢູ່ multicast ບໍ່ສະເພາະພຽງໂທລະສັບຂອງທ່ານ, ເຊິ່ງຈະໃຊ້ພະລັງງານຫຼາຍກວ່າໃນໂໝດທີ່ບໍ່ແມ່ນ multicast."</string>
+    <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"ເຂົ້າເຖິງການຕັ້ງຄ່າ Bluetooth"</string>
+    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"ອະນຸຍາດໃຫ້ແອັບຯຕັ້ງຄ່າແທັບເລັດ Bluetooth ພາຍໃນ ແລະຊອກຫາ ແລະເຊື່ອມຕໍ່ໄວ້ກັບອຸປະກອນພາຍນອກ."</string>
+    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"ອະນຸຍາດໃຫ້ແອັບຯຕັ້ງຄ່າ Bluetooth ໃນໂທລະສັບ ເພື່ອຊອກຫາ ແລະການເຊື່ອມຕໍ່ກັບອຸປະກອນໄຮ້ສາຍພາຍນອກ."</string>
+    <string name="permlab_accessWimaxState" msgid="4195907010610205703">"ເຊື່ອມຕໍ່ ແລະຕັດການເຊື່ອມຕໍ່ຈາກ WiMAX"</string>
+    <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"ອະນຸຍາດໃຫ້ແອັບຯກວດເບິ່ງວ່າ WiMAX ຖືກເປີດນຳໃຊ້ຢູ່ບໍ່ ແລະຂໍ້ມູນກ່ຽວກັບເຄືອຂ່າຍ WiMAX ອື່ນໆທີ່ກຳລັງເຊື່ອມຕໍ່ຢູ່."</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"ປ່ຽນສະຖານະ WiMAX"</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"ອະນຸຍາດໃຫ້ແອັບຯເຊື່ອມຕໍ່ ແລະຕັດການເຊື່ອມຕໍ່ແທັບເລັດຈາກເຄືອຂ່າຍ 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="default" msgid="3207106324452312739">"ອະນຸຍາດໃຫ້ແອັບຯເບິ່ງການຕັ້ງຄ່າຂອງ Bluetooth ໃນໂທລະສັບ, ຮວມທັງໃຫ້ສ້າງ ແລະຮັບການເຊື່ອມຕໍ່ຈາກອຸປະກອນທີ່ຈັບຄູ່ກັນ."</string>
+    <string name="permlab_nfc" msgid="4423351274757876953">"ຄວບຄຸມ Near Field Communication"</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_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="permlab_readSyncStats" msgid="7396577451360202448">"ອ່ານສະຖິຕິການຊິ້ງຂໍ້ມູນ"</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"ອະນຸຍາດໃຫ້ແອັບຯ ອ່ານສະຖິຕິການຊິ້ງຂໍ້ມູນຂອງບັນຊີໃດນຶ່ງ ຮວມທັງປະຫວັດການຊິ້ງຂໍ້ມູນ ແລະຈຳນວນຂໍ້ມູນທີ່ຖືກຊິ້ງ."</string>
+    <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"ອ່ານຂໍ້ມູນຟີດທີ່ສະໝັກໄວ້"</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"ອະນຸຍາດໃຫ້ແອັບຯ ດຶງລາຍລະອຽດກ່ຽວກັບຂໍ້ມູນທີ່ກຳລັງຊິ້ງຢູ່."</string>
+    <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"ຂຽນຂໍ້ມູນຟີດທີ່ສະໝັກໄວ້"</string>
+    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"ອະນຸຍາດໃຫ້ແອັບຯ ແກ້ໄຂຟີດທີ່ຖືກຊິ້ງຂໍ້ມູນເມື່ອໄວໆນີ້ຂອງທ່ານ. ແອັບຯທີ່ເປັນອັນຕະລາຍ ອາດປ່ຽນແປງຟີດຂອງທ່ານທີ່ຊິ້ງມາ."</string>
+    <string name="permlab_readDictionary" msgid="4107101525746035718">"ອ່ານຄຳສັບທີ່ທ່ານເພີ່ມໃສ່ວັດຈະນານຸກົມ"</string>
+    <string name="permdesc_readDictionary" msgid="659614600338904243">"ອະນຸຍາດແອັບຯອ່ານຄຳສັບ, ຊື່ ແລະປະໂຫຍກທັງໝົດທີ່ຜູ່ໃຊ້ອາດບັນທຶກໄວ້ໃນວັດຈະນານຸກົມຜູ່ໃຊ້."</string>
+    <string name="permlab_writeDictionary" msgid="2183110402314441106">"ເພີ່ມຄຳສັບໃສ່ວັດຈະນານຸກົມທີ່ຜູ່ໃຊ້ກຳນົດເອງ"</string>
+    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"ອະນຸຍາດໃຫ້ແອັບຯຂຽນຄຳສັບໃໝ່ ໃສ່ວັດຈະນານຸກົມຜູ່ໃຊ້."</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"ທົດສອບການເຂົ້າເຖິງບ່ອນຈັດເກັບຂໍ້ມູນທີ່ຖືກປ້ອງກັນໄວ້"</string>
+    <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"ທົດສອບການເຂົ້າເຖິງບ່ອນຈັດເກັບຂໍ້ມູນທີ່ຖືກປ້ອງກັນໄວ້"</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"ອະນຸຍາດໃຫ້ແອັບຯທົດສອບການອະນຸຍາດຂອງ ບ່ອນຈັດເກັບຂໍ້ມູນ USB ເຊິ່ງຈະຖືກໃຊ້ໃນອຸປະກອນໃນອະນາຄົດ."</string>
+    <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"ອະນຸຍາດໃຫ້ແອັບຯ ທົດລອງສິດໃດນຶ່ງສຳລັບ SD card ທີ່ຈະມີໃນອຸປະກອນໃນອະນາຄົດ."</string>
+    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"ແກ້ໄຂ ຫຼືລຶບເນື້ອຫາໃນບ່ອນຈັດເກັບຂໍ້ມູນ USB ຂອງທ່ານ"</string>
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"ແກ້ໄຂ ຫຼືລຶບເນື້ອຫາຂອງ SD card ຂອງທ່ານ"</string>
+    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"ອະນຸຍາດໃຫ້ແອັບຯຂຽນຂໍ້ມູນໃສ່ບ່ອນຈັດເກັບຂໍ້ມູນ USB."</string>
+    <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"ອະນຸຍາດໃຫ້ແອັບຯຂຽນຂໍ້ມູນລົງໃນ SD card ໄດ້."</string>
+    <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"ແກ້ໄຂ/ລຶບ ເນື້ອຫາບ່ອນຈັດເກັບສື່ພາຍໃນ"</string>
+    <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"ອະນຸຍາດໃຫ້ແອັບຯແກ້ໄຂເນື້ອຫາຂອງໂຕເກັບຂໍ້ມູນໃນໂຕເຄື່ອງ."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"ຈັດການພື້ນທີ່ຈັດເກັບເອກະສານ"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"ອະນຸຍາດໃຫ້ແອັບຯຈັດການກັບບ່ອນຈັດເກັບຂໍ້ມູນເອກະສານ."</string>
+    <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"ເຂົ້າເຖິງພື້ນທີ່ຈັດເກັບຂໍ້ມູນພາຍນອກຂອງທຸກຜູ່ໃຊ້"</string>
+    <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"ອະນຸຍາດໃຫ້ແອັບຯ ເຂົ້າເຖິງພື້ນທີ່ຈັດເກັບຂໍ້ມູນພາຍນອກ ສຳລັບທຸກຜູ່ໃຊ້."</string>
+    <string name="permlab_cache_filesystem" msgid="5656487264819669824">"ເຂົ້າເຖິງໄຟລ໌ cache ຂອງລະບົບ"</string>
+    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"ອະນຸຍາດໃຫ້ແອັບຯ ອ່ານ ແລະຂຽນ ລະບົບໄຟລ໌ແຄດ."</string>
+    <string name="permlab_use_sip" msgid="5986952362795870502">"ສົ່ງ/ຮັບ ການໂທຜ່ານອິນເຕີເນັດ"</string>
+    <string name="permdesc_use_sip" msgid="4717632000062674294">"ອະນຸຍາດໃຫ້ແອັບຯ ໃຊ້ບໍລິການ SIP ເພື່ອ ໂທອອກ/ຮັບສາຍ ການໂທຜ່ານອິນເຕີເນັດ."</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_markNetworkSocket" msgid="3658527214914959749">"ດັດ​ແປງຊັອກເກັດມາກ"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"ອະ​ນຸ​ຍາດ​ໃຫ້ແອັບຯແກ້ໄຂຊັອກເກັດທີ່ໝາຍໄວ້ສຳລັບກຳນົດເສັ້ນທາງ"</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_invokeCarrierSetup" msgid="3699600833975117478">"ຮ້ອງຂໍແອັບຯປັບຄ່າທີ່ສະໜອງໂດຍຜູ່ໃຫ້ບໍລິການ"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"ອະ​ນຸ​ຍາດ​ໃຫ້​ເຈົ້າຂອງຮ້ອງຂໍແອັບຯປັບຄ່າທີ່ສະໜອງໂດຍຜູ່ໃຫ້ບໍລິການ. ບໍ່ໜ້າຈະຕ້ອງການສຳລັບແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"ຕິດຕາມເພື່ອສັງເກດສະພາບຂອງເຄືອຂ່າຍ"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັ່ນຕິດຕາມເພື່ອສັງເກດສະພາບຂອງເຄືອຂ່າຍ. ປົກກະຕິແລ້ວແອັບຯທຳມະດາຈະບໍ່ຕ້ອງການໃຊ້."</string>
+    <string name="policylab_limitPassword" msgid="4497420728857585791">"ຕັ້ງຄ່າກົດຂອງລະຫັດຜ່ານ"</string>
+    <string name="policydesc_limitPassword" msgid="3252114203919510394">"ຄວບຄຸມຄວາມຍາວຂອງໂຕອັກສອນທີ່ສາມາດໃຊ້ກັບລະຫັດປົດລັອກໜ້າຈໍ"</string>
+    <string name="policylab_watchLogin" msgid="914130646942199503">"ຕິດຕາມການພະຍາຍາມປົດລັອກໜ້າຈໍ"</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"ຕິດຕາມເບິ່ງຈຳນວນການພິມລະຫັດຜ່ານທີ່ບໍ່ຖືກຕ້ອງ ໃນເວລາປົດລັອກໜ້າຈໍ ແລະລັອກແທັບເລັດ ຫຼືລຶບຂໍ້ມູນທັງໝົດຂອງແທັບເລັດ ຖ້າມີການພິມລະຫັດຜ່ານບໍ່ຖືກຕ້ອງຫຼາຍເທື່ອເກີນໄປ."</string>
+    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"ຕິດຕາມເບິ່ງຈຳນວນການພິມລະຫັດຜ່ານບໍ່ຖືກຕ້ອງ ໃນເວລາປົດລັອກໜ້າຈໍ ແລະລັອກໂທລະສັບ ຫຼືລຶບຂໍ້ມູນທັງໝົດຂອງໂປລະສັບ ຖ້າມີການພິມລະຫັດຜ່ານບໍ່ຖືກຕ້ອງຫຼາຍເທື່ອເກີນໄປ."</string>
+    <string name="policylab_resetPassword" msgid="2620077191242688955">"ປ່ຽນລະຫັດລັອກໜ້າຈໍ"</string>
+    <string name="policydesc_resetPassword" msgid="605963962301904458">"ປ່ຽນລະຫັດປົດລັອກໜ້າຈໍ"</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="default" msgid="5096895604574188391">"ລຶບຂໍ້ມູນຂອງໂທລະສັບໂດຍບໍ່ມີການເຕືອນ ໂດຍການຣີເຊັດກັບຄືນໃຫ້ເປັນແບບທີ່ມາຈາກໂຮງງານ."</string>
+    <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"ປ່ຽນ proxy ຮວມຂອງອຸປະກອນ"</string>
+    <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"ຕັ້ງໃຫ້ພຣັອກຊີສ່ວນກາງຂອງອຸປະກອນ ທີ່ຈະໃຊ້ໃນຂະນະທີ່ເປີດນຳໃຊ້ນະໂຍບາຍ. ສະເເພາະຜູ່ເບິ່ງແຍງອຸປະກອນຄົນທຳອິດເທົ່ານັ້ນ ທີ່ຈະຕັ້ງຄ່າພຣັອກຊີສ່ວນກາງທີ່ມີຜົນນຳໃຊ້ໄດ້."</string>
+    <string name="policylab_expirePassword" msgid="885279151847254056">"ຕັ້ງວັນໝົດກຳນົດຂອງລະຫັດລັອກໜ້າຈໍ"</string>
+    <string name="policydesc_expirePassword" msgid="1729725226314691591">"ຄວບຄຸມຄວາມຖີ່ໃນການປ່ຽນລະຫັດໜ້າຈໍລັອກ."</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="policylab_disableKeyguardFeatures" msgid="266329104542638802">"ປິດການນຳໃຊ້ການລັອກປຸ່ມ"</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="3467082272186534614">"ປ້ອງກັນການໃຊ້ຄວາມສາມາດບາງສ່ວນໃນການລັອກປຸ່ມ."</string>
+  <string-array name="phoneTypes">
+    <item msgid="8901098336658710359">"ເຮືອນ"</item>
+    <item msgid="869923650527136615">"ມືຖື"</item>
+    <item msgid="7897544654242874543">"ວຽກ"</item>
+    <item msgid="1103601433382158155">"ແຟັກບ່ອນເຮັດວຽກ"</item>
+    <item msgid="1735177144948329370">"ແຟັກເຮືອນ"</item>
+    <item msgid="603878674477207394">"ເພກເຈີ"</item>
+    <item msgid="1650824275177931637">"ອື່ນໆ"</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>
+  </string-array>
+  <string-array name="postalAddressTypes">
+    <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="1359644565647383708">"ບ່ອນເຮັດວຽກ"</item>
+    <item msgid="7868549401053615677">"ອື່ນໆ"</item>
+    <item msgid="3145118944639869809">"ກຳນົດເອງ"</item>
+  </string-array>
+  <string-array name="organizationTypes">
+    <item msgid="7546335612189115615">"ບ່ອນເຮັດວຽກ"</item>
+    <item msgid="4378074129049520373">"ອື່ນໆ"</item>
+    <item msgid="3455047468583965104">"ກຳນົດເອງ"</item>
+  </string-array>
+  <string-array name="imProtocols">
+    <item msgid="8595261363518459565">"AIM"</item>
+    <item msgid="7390473628275490700">"Windows Live"</item>
+    <item msgid="7882877134931458217">"Yahoo"</item>
+    <item msgid="5035376313200585242">"Skype"</item>
+    <item msgid="7532363178459444943">"QQ"</item>
+    <item msgid="3713441034299660749">"Google Talk"</item>
+    <item msgid="2506857312718630823">"ICQ"</item>
+    <item msgid="1648797903785279353">"Jabber"</item>
+  </string-array>
+    <string name="phoneTypeCustom" msgid="1644738059053355820">"ກຳນົດເອງ"</string>
+    <string name="phoneTypeHome" msgid="2570923463033985887">"ເຮືອນ"</string>
+    <string name="phoneTypeMobile" msgid="6501463557754751037">"ມືຖື"</string>
+    <string name="phoneTypeWork" msgid="8863939667059911633">"ບ່ອນເຮັດວຽກ"</string>
+    <string name="phoneTypeFaxWork" msgid="3517792160008890912">"ແຟັກບ່ອນເຮັດວຽກ"</string>
+    <string name="phoneTypeFaxHome" msgid="2067265972322971467">"ແຟັກເຮືອນ"</string>
+    <string name="phoneTypePager" msgid="7582359955394921732">"ເພກເຈີ"</string>
+    <string name="phoneTypeOther" msgid="1544425847868765990">"ອື່ນໆ"</string>
+    <string name="phoneTypeCallback" msgid="2712175203065678206">"ໂທກັບ"</string>
+    <string name="phoneTypeCar" msgid="8738360689616716982">"ລົດ"</string>
+    <string name="phoneTypeCompanyMain" msgid="540434356461478916">"ເບີໂທຫຼັກບໍລິສັດ"</string>
+    <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string>
+    <string name="phoneTypeMain" msgid="6766137010628326916">"ຫຼັກ"</string>
+    <string name="phoneTypeOtherFax" msgid="8587657145072446565">"ແຟັກອື່ນໆ"</string>
+    <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="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="eventTypeBirthday" msgid="2813379844211390740">"ວັນເດືອນປີເກີດ"</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>
+    <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="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="imTypeWork" msgid="1371489290242433090">"ວຽກ"</string>
+    <string name="imTypeOther" msgid="5377007495735915478">"ອື່ນໆ"</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>
+    <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
+    <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</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>
+    <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="relationTypeAssistant" msgid="6274334825195379076">"ຜູ່ຊ່ວຍ"</string>
+    <string name="relationTypeBrother" msgid="8757913506784067713">"ອ້າຍ-ນ້ອງ"</string>
+    <string name="relationTypeChild" msgid="1890746277276881626">"ລູກ"</string>
+    <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"ຮຸ້ນສ່ວນພາຍໃນ"</string>
+    <string name="relationTypeFather" msgid="5228034687082050725">"ພໍ່"</string>
+    <string name="relationTypeFriend" msgid="7313106762483391262">"ໝູ່ເພື່ອນ"</string>
+    <string name="relationTypeManager" msgid="6365677861610137895">"ຜູ່ຈັດການ"</string>
+    <string name="relationTypeMother" msgid="4578571352962758304">"ແມ່"</string>
+    <string name="relationTypeParent" msgid="4755635567562925226">"ພໍ່ແມ່"</string>
+    <string name="relationTypePartner" msgid="7266490285120262781">"ຮຸ້ນສ່ວນ"</string>
+    <string name="relationTypeReferredBy" msgid="101573059844135524">"ແນະນຳໂດຍ"</string>
+    <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="sipAddressTypeHome" msgid="6093598181069359295">"ເຮືອນ"</string>
+    <string name="sipAddressTypeWork" msgid="6920725730797099047">"ບ່ອນເຮັດວຽກ"</string>
+    <string name="sipAddressTypeOther" msgid="4408436162950119849">"ອື່ນໆ"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"ພິມລະຫັດ PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"ພິມລະຫັດ PUK ແລະ​ລະ​ຫັດ PIN ອັນໃໝ່"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"ລະ​ຫັດ PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"ລະຫັດ PIN ໃໝ່"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><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">"ພິມລະຫັດ PIN ເພື່ອປົດລັອກ"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"ລະຫັດ PIN ບໍ່ຖືກຕ້ອງ."</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="8963839242565653192">"ບໍ່ມີບໍລິການ."</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="5347633784401285225">"ໂທສຸກເສີນ"</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="faceunlock_multiple_failures" msgid="754137583022792429">"ຄວາມພະຍາຍາມປົດລັອກດ້ວຍໜ້ານັ້ນ ເກີນຈຳນວນທີ່ກຳນົດແລ້ວ"</string>
+    <string name="lockscreen_plugged_in" msgid="8057762828355572315">"ກຳລັງສາກ <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_charged" msgid="321635745684060624">"ສາກເຕັມແລ້ວ."</string>
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_low_battery" msgid="1482873981919249740">"ເຊື່ອມຕໍ່ສາຍສາກຂອງທ່ານ."</string>
+    <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"ບໍ່ມີ SIM card."</string>
+    <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"ບໍ່ມີຊິມກາດໃນແທັບເລັດ."</string>
+    <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"ບໍ່ມີ SIM card ໃນໂທລະສັບ."</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">"SIM card ບໍ່ສາມາດໃຊ້ໄດ້."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"ຊິມກາດຂອງທ່ານຖືກປິດການນຳໃຊ້ຢ່າງຖາວອນແລ້ວ.\n ກະລຸນາຕິດຕໍ່ຜູ່ໃຫ້ບໍລິການໂທລະສັບຂອງທ່ານ ເພື່ອຂໍເອົາຊິມກາດໃໝ່."</string>
+    <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"ປຸ່ມເພງກ່ອນໜ້ານີ້"</string>
+    <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"ປຸ່ມເພງຕໍ່ໄປ"</string>
+    <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"ປຸ່ມຢຸດຊົ່ວຄາວ"</string>
+    <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"ປຸ່ມຫຼິ້ນ"</string>
+    <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"ປຸ່ມຢຸດ"</string>
+    <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">"SIM card ຖືກລັອກດ້ວຍລະຫັດ PUK."</string>
+    <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"ເບິ່ງຄູ່ມືຜູ່ໃຊ້ ຫຼືຕິດຕໍ່ສູນບໍລິການລູກຄ້າ."</string>
+    <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM card ຖືກລັອກ."</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">%d</xliff:g> ເທື່ອແລ້ວ. \n\nລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ວິນາທີ."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"ທ່ານພິມລະຫັດຜ່ານຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. \n\nໃຫ້ລອງໃໝ່ອີກຄັ້ງໃນອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ວິນາທີ."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"ທ່ານພິມລະຫັດ PIN ຂອງທ່ານຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. \n\nລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ວິນາທີ."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"ທ່ານແຕ້ມຮູບແບບປົດລັອກຂອງທ່ານຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກຄວາມພະຍາຍາມອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ເທື່ອ ທ່ານຈະຖືກຖາມໃຫ້ປົດລັອກແທັບເລັດຂອງທ່ານ ດ້ວຍການເຂົ້າສູ່ລະບົບຂອງ Google.\n\n ລອງໃໝ່ອີກຄັ້ງໃນ <xliff:g id="NUMBER_2">%d</xliff:g> ວິນາທີ."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"ທ່ານແຕ້ມຮູບແບບປົດລັອກຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກແຕ້ມຜິດອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ເທື່ອ, ທ່ານຈະຖືກຖາມໃຫ້ປົດລັອກໂທລະສັບຂອງທ່ານ ດ້ວຍການເຂົ້າສູ່ລະບົບ Google.\n\n ລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_2">%d</xliff:g> ວິນາທີ."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"ທ່ານພະຍາຍາມປັດລັອກແທັບເລັດຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກຜິດອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ເທື່ອ, ແທັບເລັດຈະຖືກຣີເຊັດໃຫ້ເປັນແບບທີ່ມາຈາກໂຮງງານ ແລະຂໍ້ມູນທັງໝົດຈະຖືກຫາຍໄປ."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"ທ່ານໄດ້ພະຍາຍາມປົດລັອກໂທລະສັບເປັນຈຳນວນ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກການພະຍາຍາມອີກ <xliff:g id="NUMBER_1">%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="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_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_checking_password" msgid="7114627351286933867">"ກຳລັງກວດສອບ..."</string>
+    <string name="lockscreen_unlock_label" msgid="737440483220667054">"ປົດລັອກ"</string>
+    <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"ເປີດສຽງແລ້ວ"</string>
+    <string name="lockscreen_sound_off_label" msgid="996822825154319026">"ປິດສຽງ"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"ຮູບແບບເລີ່ມຕົ້ນແລ້ວ"</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"ລຶບລ້າງຮູບແບບແລ້ວ"</string>
+    <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"ຕາລາງຖືກເພີ່ມແລ້ວ"</string>
+    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"ຮູບແບບສຳເລັດແລ້ວ"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. ວິດເຈັດ %2$d ຈາກທັງໝົດ %3$d."</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_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>
+    <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_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">"ປົດລັອກດ້ວຍ PIN."</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>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <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_line" msgid="5764267235026120888">"ເສັ້ນ"</string>
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
+    <string name="factorytest_failed" msgid="5410270329114212041">"ການທົດສອບຈາກໂຮງງານລົ້ມເຫລວ"</string>
+    <string name="factorytest_not_system" msgid="4435201656767276723">"ການເຮັດ FACTORY_TEST ຮອງຮັບສະເພາະແພັກເກດທີ່ຖືກຕິດຕັ້ງໃນ /system/app ເທົ່ານັ້ນ."</string>
+    <string name="factorytest_no_action" msgid="872991874799998561">"ບໍ່ພົບແພັກເກດທີ່ມີການເຮັດວຽກ FACTORY_TEST."</string>
+    <string name="factorytest_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="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>
+    <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
+    <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
+    <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
+    <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
+    <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">"ລະຫັດ ZIP"</string>
+    <string name="autofill_county" msgid="237073771020362891">"ປະເທດ"</string>
+    <string name="autofill_island" msgid="4020100875984667025">"ເກາະ"</string>
+    <string name="autofill_district" msgid="8400735073392267672">"ເມືອງ"</string>
+    <string name="autofill_department" msgid="5343279462564453309">"ພະແນກ"</string>
+    <string name="autofill_prefecture" msgid="2028499485065800419">"ເຂດປົກຄອງ"</string>
+    <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="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_packageVerificationAgent" msgid="5568139100645829117">"ຢັ້ງຢືນແພັກເກດ"</string>
+    <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"ອະນຸຍາດໃຫ້ແອັບຯຢືນຢັນວ່າແພັກເກດໃດນຶ່ງ ສາມາດຕິດຕັ້ງໄດ້."</string>
+    <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"ເຊື່ອມໂຍງກັບໂຕຢືນຢັນແພັກເກດ"</string>
+    <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງເຮັດການຮ້ອງຂໍໂຕຢືນຢັນແພັກເກັດ. ບໍ່ຈຳເປັນສຳລັບແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_serialPort" msgid="546083327654631076">"ເຂົ້າເຖິງພອດຊີຣຽວ"</string>
+    <string name="permdesc_serialPort" msgid="2991639985224598193">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງສາມາດເຂົ້າເບິ່ງ serial ports ໂດຍການນຳໃຊ້ SerialManager API."</string>
+    <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"ເຂົ້າເຖິງຜູ່ສະໜອງເນື້ອຫາພາຍນອກ"</string>
+    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"ຊ່ວຍໃຫ້ເຈົ້າຂອງສາມາດ ເຂົ້າເຖິງຜູ່ໃຫ້ບໍລິການເນື້ອຫາຈາກໜ້າ shell ໄດ້. ແອັບພລິເຄຊັນທົ່ວໄປບໍ່ຄວນຈຳເປັນຕ້ອງໃຊ້."</string>
+    <string name="permlab_updateLock" msgid="3527558366616680889">"ປ້ອງກັນການອັບເດດອຸປະກອນໂດຍອັດຕະໂນມັດ"</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງກຳນົດຂໍ້ມູນໃນລະບົບ ກ່ຽວກັບເວລາທີ່ເໝາະສົມໃນການຣີບູດແບບບໍ່ໂຕ້ຕອບ ເພື່ອອັບເກຣດອຸປະກອນ."</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>
+    <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="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="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="oneMonthDurationPast" msgid="7396384508953779925">"1 ເດືອນກ່ອນຫນ້ານີ້"</string>
+    <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"ຫຼາຍກວ່າ 1 ເດືອນກ່ອນ"</string>
+  <plurals name="num_seconds_ago">
+    <item quantity="one" msgid="4869870056547896011">"1 ວິນາທີກ່ອນ"</item>
+    <item quantity="other" msgid="3903706804349556379">"<xliff:g id="COUNT">%d</xliff:g> ວິນາທີກ່ອນໜ້ານີ້"</item>
+  </plurals>
+  <plurals name="num_minutes_ago">
+    <item quantity="one" msgid="3306787433088810191">"1 ນາທີກ່ອນໜ້ານີ້"</item>
+    <item quantity="other" msgid="2176942008915455116">"<xliff:g id="COUNT">%d</xliff:g> ນາ​ທີ​ທີ່ຜ່ານມາ"</item>
+  </plurals>
+  <plurals name="num_hours_ago">
+    <item quantity="one" msgid="9150797944610821849">"1 ຊົ່ວໂມງກ່ອນໜ້ານີ້"</item>
+    <item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> ຊົ່ວໂມງທີ່ຜ່ານມາ"</item>
+  </plurals>
+  <plurals name="last_num_days">
+    <item quantity="other" msgid="3069992808164318268">"<xliff:g id="COUNT">%d</xliff:g> ມື້ທີ່ຜ່ານມາ"</item>
+  </plurals>
+    <string name="last_month" msgid="3959346739979055432">"ເດືອນແລ້ວ"</string>
+    <string name="older" msgid="5211975022815554840">"ເກົ່າກວ່າ"</string>
+  <plurals name="num_days_ago">
+    <item quantity="one" msgid="861358534398115820">"ມື້​ວານ​ນີ້"</item>
+    <item quantity="other" msgid="2479586466153314633">"<xliff:g id="COUNT">%d</xliff:g> ມື້​ກ່ອນ"</item>
+  </plurals>
+  <plurals name="in_num_seconds">
+    <item quantity="one" msgid="2729745560954905102">"ໃນອີກ 1 ວິນາທີ"</item>
+    <item quantity="other" msgid="1241926116443974687">"ໃນ <xliff:g id="COUNT">%d</xliff:g> ວິ​ນາ​ທີ"</item>
+  </plurals>
+  <plurals name="in_num_minutes">
+    <item quantity="one" msgid="8793095251325200395">"ໃນ 1 ນາທີ"</item>
+    <item quantity="other" msgid="3330713936399448749">"ໃນ <xliff:g id="COUNT">%d</xliff:g> ນາທີ"</item>
+  </plurals>
+  <plurals name="in_num_hours">
+    <item quantity="one" msgid="7164353342477769999">"ໃນ 1 ຊົ່ວໂມງ"</item>
+    <item quantity="other" msgid="547290677353727389">"ໃນ <xliff:g id="COUNT">%d</xliff:g> ຊົ່ວໂມງ"</item>
+  </plurals>
+  <plurals name="in_num_days">
+    <item quantity="one" msgid="5413088743009839518">"ມື້ອື່ນ"</item>
+    <item quantity="other" msgid="5109449375100953247">"ໃນ <xliff:g id="COUNT">%d</xliff:g> ມື້"</item>
+  </plurals>
+  <plurals name="abbrev_num_seconds_ago">
+    <item quantity="one" msgid="1849036840200069118">"1 ວິນາທີກ່ອນ"</item>
+    <item quantity="other" msgid="3699169366650930415">"<xliff:g id="COUNT">%d</xliff:g> ວິ ກ່ອນໜ້ານີ້"</item>
+  </plurals>
+  <plurals name="abbrev_num_minutes_ago">
+    <item quantity="one" msgid="6361490147113871545">"1 ນທ ກ່ອນ"</item>
+    <item quantity="other" msgid="851164968597150710">"<xliff:g id="COUNT">%d</xliff:g> ນທ ກ່ອນໜ້ານີ້"</item>
+  </plurals>
+  <plurals name="abbrev_num_hours_ago">
+    <item quantity="one" msgid="4796212039724722116">"1 ຊົ່ວໂມງກ່ອນ"</item>
+    <item quantity="other" msgid="6889970745748538901">"<xliff:g id="COUNT">%d</xliff:g> ຊົ່ວໂມງກ່ອນໜ້ານີ້"</item>
+  </plurals>
+  <plurals name="abbrev_num_days_ago">
+    <item quantity="one" msgid="8463161711492680309">"ມື້ວານນີ້"</item>
+    <item quantity="other" msgid="3453342639616481191">"<xliff:g id="COUNT">%d</xliff:g> ມື້ກ່ອນໜ້ານີ້"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_seconds">
+    <item quantity="one" msgid="5842225370795066299">"ໃນ 1 ວິ"</item>
+    <item quantity="other" msgid="5495880108825805108">"ໃນ <xliff:g id="COUNT">%d</xliff:g> ວິ"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_minutes">
+    <item quantity="one" msgid="562786149928284878">"ໃນ 1 ນາທີ"</item>
+    <item quantity="other" msgid="4216113292706568726">"ໃນ <xliff:g id="COUNT">%d</xliff:g> ນທ"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_hours">
+    <item quantity="one" msgid="3274708118124045246">"ໃນ 1 ຊົ່ວໂມງ"</item>
+    <item quantity="other" msgid="3705373766798013406">"ໃນ <xliff:g id="COUNT">%d</xliff:g> ຊົ່ວໂມງ"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_days">
+    <item quantity="one" msgid="2178576254385739855">"ມື້ອື່ນ"</item>
+    <item quantity="other" msgid="2973062968038355991">"ໃນ <xliff:g id="COUNT">%d</xliff:g> ມື້"</item>
+  </plurals>
+    <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>
+    <string name="days" msgid="4774547661021344602">"ມື້"</string>
+    <string name="hour" msgid="2126771916426189481">"ຊົ່ວໂມງ"</string>
+    <string name="hours" msgid="894424005266852993">"ຊົ່ວໂມງ"</string>
+    <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="week" msgid="5617961537173061583">"ອາທິດ"</string>
+    <string name="weeks" msgid="6509623834583944518">"ອາທິດ"</string>
+    <string name="year" msgid="4001118221013892076">"ປີ"</string>
+    <string name="years" msgid="6881577717993213522">"ປິ"</string>
+  <plurals name="duration_seconds">
+    <item quantity="one" msgid="6962015528372969481">"1 ວິນາທີ"</item>
+    <item quantity="other" msgid="1886107766577166786">"<xliff:g id="COUNT">%d</xliff:g> ວິນາທີ"</item>
+  </plurals>
+  <plurals name="duration_minutes">
+    <item quantity="one" msgid="4915414002546085617">"1 ນາ​ທີ"</item>
+    <item quantity="other" msgid="3165187169224908775">"<xliff:g id="COUNT">%d</xliff:g> ນາທີ"</item>
+  </plurals>
+  <plurals name="duration_hours">
+    <item quantity="one" msgid="8917467491248809972">"1 ຊົ່ວ​ໂມງ"</item>
+    <item quantity="other" msgid="3863962854246773930">"<xliff:g id="COUNT">%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_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>
+    <string name="midnight" msgid="7166259508850457595">"ທ່ຽງຄືນ"</string>
+    <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="cut" msgid="3092569408438626261">"ຕັດ"</string>
+    <string name="copy" msgid="2681946229533511987">"ສຳເນົາ"</string>
+    <string name="paste" msgid="5629880836805036433">"ວາງ"</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="textSelectionCABTitle" msgid="5236850394370820357">"ການເລືອກຂໍ້ຄວາມ"</string>
+    <string name="addToDictionary" msgid="4352161534510057874">"ເພີ່ມໄປທີ່ວັດຈະນານຸກົມ"</string>
+    <string name="deleteText" msgid="6979668428458199034">"ລຶບ"</string>
+    <string name="inputMethod" msgid="1653630062304567879">"ຮູບແບບການປ້ອນຂໍ້ມູນ"</string>
+    <string name="editTextMenuTitle" msgid="4909135564941815494">"ການເຮັດວຽກຂອງຂໍ້ຄວາມ"</string>
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"ພື້ນທີ່ຈັດເກັບຂໍ້ມູນກຳລັງຈະເຕັມ"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"ການເຮັດວຽກບາງຢ່າງຂອງລະບົບບາງອາດຈະໃຊ້ບໍ່ໄດ້"</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="4653586947747330058">"ແຕະເພື່ອເບິ່ງຂໍ້ມູນເພີ່ມເຕີມ ຫຼືເພື່ອຢຸດການເຮັດວຽກຂອງແອັບຯນີ້."</string>
+    <string name="ok" msgid="5970060430562524910">"ຕົກລົງ"</string>
+    <string name="cancel" msgid="6442560571259935130">"ຍົກເລີກ"</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>
+    <string name="capital_on" msgid="1544682755514494298">"ເປີດ"</string>
+    <string name="capital_off" msgid="6815870386972805832">"ປິດ"</string>
+    <string name="whichApplication" msgid="4533185947064773386">"ເຮັດວຽກໃຫ້ສຳເລັດໂດຍໃຊ້"</string>
+    <string name="alwaysUse" msgid="4583018368000610438">"ໃຊ້ໂດຍຄ່າເລີ່ມຕົນສຳລັບການເຮັດວຽກນີ້."</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="aerr_title" msgid="1905800560317137752"></string>
+    <string name="aerr_application" msgid="932628488013092776">"ຂໍອະໄພ, <xliff:g id="APPLICATION">%1$s</xliff:g> ຢຸດການເຮັດວຽກແລ້ວ."</string>
+    <string name="aerr_process" msgid="4507058997035697579">"ຂໍອະໄພ, ໂປຣເຊສ <xliff:g id="PROCESS">%1$s</xliff:g> ໄດ້ຢຸດການເຮັດວຽກແລ້ວ."</string>
+    <string name="anr_title" msgid="4351948481459135709"></string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> ບໍ່ຕອບສະໜອງ. \n\nທ່ານຕ້ອງການປິດມັນບໍ່?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"ການເຮັດວຽກ <xliff:g id="ACTIVITY">%1$s</xliff:g> ບໍ່ຕອບສະໜອງ. \n\n ທ່ານຕ້ອງການທີ່ຈະປິດມັນບໍ່?"</string>
+    <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> ບໍ່ຕອບສະໜອງ. ທ່ານຕ້ອງການປິດມັນບໍ່?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"ໂປຣເຊສ <xliff:g id="PROCESS">%1$s</xliff:g> ບໍ່ຕອບສະໜອງ. \n\n ທ່ານຕ້ອງການປິດມັນບໍ່?"</string>
+    <string name="force_close" msgid="8346072094521265605">"ຕົກລົງ"</string>
+    <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_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; ແອັບຯ &gt; ດາວໂຫລດແລ້ວ"</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>
+    <string name="android_upgrading_title" msgid="1584192285441405746">"ກຳລັງອັບເກຣດ Android..."</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_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="1721681741617898865">"ແຕະເພື່ອສະລັບກັບໄປຫາແອັບຯ"</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>
+    <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="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_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_notification" msgid="7044986546477282274">"ລະດັບສຽງການແຈ້ງເຕືອນ"</string>
+    <string name="ringtone_default" msgid="3789758980357696936">"ຣິງໂທນເລີ່ມຕົ້ນ"</string>
+    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"ຣິງໂທນເລີ່ມຕົ້ນ (<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_unknown" msgid="5477919988701784788">"ຣິງໂທນທີ່ບໍ່ຮູ້ຈັກ"</string>
+  <plurals name="wifi_available">
+    <item quantity="one" msgid="6654123987418168693">"ເຄືອຂ່າຍ Wi-Fi ທີ່ພົບ"</item>
+    <item quantity="other" msgid="4192424489168397386">"ມີເຄືອຂ່າຍ Wi​-Fi ໃຫ້ໃຊ້"</item>
+  </plurals>
+  <plurals name="wifi_available_detailed">
+    <item quantity="one" msgid="1634101450343277345">"ເປີດ Wi-Fi ເຄືອຂ່າຍທີ່ມີ"</item>
+    <item quantity="other" msgid="7915895323644292768">"ເຄືອຂ່າຍ Wi-Fi ແບບເປີດທີ່ພົບ"</item>
+  </plurals>
+    <string name="wifi_available_sign_in" msgid="4029489716605255386">"ເຂົ້າສູ່ລະບົບເຄືອຂ່າຍ Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="8495155593358054676">"ເຂົ້າສູ່ລະບົບເຄືອຂ່າຍ"</string>
+    <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
+    <skip />
+    <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"ບໍ່ສາມາດເຊື່ອມຕໍ່ Wi-Fi ໄດ້"</string>
+    <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ມີສັນຍານອິນເຕີເນັດທີ່ບໍ່ດີ."</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 client/hotspot."</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_enabled_notification_message" msgid="1638949953993894335">"ແຕະເພື່ອຕັ້ງຄ່າ"</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_to_connect_title" msgid="4958803948658533637">"ການເຊີນຊວນເພື່ອເຊື່ອມຕໍ່"</string>
+    <string name="wifi_p2p_from_message" msgid="570389174731951769">"ຈາກ:"</string>
+    <string name="wifi_p2p_to_message" msgid="248968974522044099">"ຈາກ:"</string>
+    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"ພິມລະຫັດ PIN:"</string>
+    <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"ແທັບເລັດຈະຖືກຕັດການເຊື່ອມຕໍ່ຈາກ Wi-Fi ເປັນການຊົ່ວຄາວ ໃນຂະນະທີ່ມັນເຊື່ອມຕໍ່ກັບ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ຢູ່."</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"ໂທລະສັບຈະຖືກຢຸດການເຊື່ອມຕໍ່ຊົ່ວຄາວຈາກ Wi-Fi ໃນຂະນະທີ່ມັນເຊື່ອມຕໍ່ກັບ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="select_character" msgid="3365550120617701745">"ໃສ່ໂຕອັກສອນ"</string>
+    <string name="sms_control_title" msgid="7296612781128917719">"ກຳລັງສົ່ງຂໍ້ຄວາມ 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="3492025719868078457">"ນີ້ "<font fgcolor="#ffffb060">"ອາດເຮັດໃຫ້ເກີດຄ່າໃຊ້ຈ່າຍ"</font>" ໃນບັນຊີມືຖືຂອງທ່ານໄດ້."</string>
+    <string name="sms_premium_short_code_details" msgid="5523826349105123687"><font fgcolor="#ffffb060">"ມັນຈະເຮັດໃຫ້ທ່ານເສຍຄ່າບໍລິການໃນບັນຊີຂອງທ່ານ."</font></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_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 card ອອກແລ້ວ"</string>
+    <string name="sim_removed_message" msgid="2333164559970958645">"ເຄືອຂ່າຍມືຖືຈະບໍ່ສາມາດໃຊ້ໄດ້ ຈົນກວ່າທ່ານຈະປິດແລ້ວເປີດໃໝ່ພ້ອມກັບໃສ່ SIM card ທີ່ຖືກຕ້ອງ."</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="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_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="usb_storage_activity_title" msgid="4465055157209648641">"ບ່ອນຈັດເກັບຂໍ້ມູນ USB"</string>
+    <string name="usb_storage_title" msgid="5901459041398751495">"ເຊື່ອມຕໍ່ USB ແລ້ວ"</string>
+    <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"ທ່ານໄດ້ເຊື່ອມຕໍ່ກັບຄອມພິວເຕີຂອງທ່ານຜ່ານ USB ແລ້ວ. ໃຫ້ແຕະປຸ່ມຂ້າງລຸ່ມຖ້າທ່ານຕ້ອງການສຳເນົາໄຟລ໌ ລະຫວ່າງຄອມພິວເຕີ ແລະບ່ອນຈັດເກັບຂໍ້ມູນ USB ຂອງ Android ທ່ານ."</string>
+    <string name="usb_storage_message" product="default" msgid="805351000446037811">"ທ່ານໄດ້ເຊື່ອມຕໍ່ກັບຄອມພິວເຕີຂອງທ່ານດ້ວຍ USB ແລ້ວ. ໃຫ້ປຸ່ມທາງດ້ານລຸ່ມນີ້ຫາກທ່ານຕ້ອງການ ທີ່ຈະສຳເນົາໄຟລ໌ຂໍ້ມູນລະຫວ່າງຄອມພິວເຕີ ແລະ SD card ຂອງ Android ຂອງທ່ານ."</string>
+    <string name="usb_storage_button_mount" msgid="1052259930369508235">"ເປີດ ບ່ອນຈັດເກັບຂໍ້ມູນ USB"</string>
+    <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"ມີບັນຫາໃນການໃຊ້ບ່ອນຈັດເກັບຂໍ້ມູນ USB ຂອງທ່ານເປັນບ່ອນຈັດເກັບຂໍ້ມູນຈຳນວນຫຼາຍດ້ວຍ USB."</string>
+    <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"ມີບັນຫາໃນການໃຊ້ SD card ຂອງທ່ານເປັນບ່ອນຈັດເກັບຂໍ້ມູນຈຳນວນຫຼາຍດ້ວຍ USB."</string>
+    <string name="usb_storage_notification_title" msgid="8175892554757216525">"ເຊື່ອມຕໍ່ USB ແລ້ວ"</string>
+    <string name="usb_storage_notification_message" msgid="939822783828183763">"ແຕະເພື່ອສຳເນົາໄຟລ໌ ໃສ່/ຈາກ ຄອມພິວເຕີຂອງທ່ານ."</string>
+    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"ປິດບ່ອນຈັດເກັບຂໍ້ມູນ USB"</string>
+    <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"ແຕະເພື່ອປິດ ບ່ອນຈັດເກັບຂໍ້ມູນ USB ."</string>
+    <string name="usb_storage_stop_title" msgid="660129851708775853">"ບ່ອນຈັດເກັບຂໍ້ມູນ USB ກຳລັງຖືກນຳໃຊ້ຢູ່"</string>
+    <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"ກ່ອນປິດບ່ອນຈັດເກັບຂໍ້ມູນ USB, ຖອນ (\"eject\") ບ່ອນຈັດເກັບຂໍ້ມູນ USB ຂອງ Android ຂອງທ່ານຈາກຄອມພິວເຕີຂອງທ່ານ."</string>
+    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"ກ່ອນການປິດບ່ອນຈັດເກັບຂໍ້ມູນ USB, ໃຫ້ຖອນການເຊື່ອມຕໍ່ (eject) SD card ຂອງ Android ທ່ານອອກຈາກຄອມພິວເຕີກ່ອນ."</string>
+    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"ປິດບ່ອນຈັດເກັບຂໍ້ມູນ USB"</string>
+    <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"ເກີດບັນຫາໃນການປິດບ່ອນຈັດເກັບຂໍ້ມູນ USB. ໃຫ້ກວດສອບວ່າທ່ານໄດ້ຖອນການເຊື່ອມຕໍ່ USB host ແລ້ວຫຼືຍັງ ຈາກນັ້ນຈຶ່ງລອງອີກຄັ້ງ."</string>
+    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"ເປີດໃຊ້ບ່ອນຈັດເກັບຂໍ້ມູນ USB"</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"ຫາກທ່ານເປີດນຳໃຊ້ບ່ອນຈັດເກັບຂໍ້ມູນ USB ຈະເຮັດໃຫ້ບາງແອັບຯທີ່ທ່ານເຮັດວຽກຢູ່ນັ້ນ ຢຸດເຮັດວຽກ ແລະອາດຈະບໍ່ສາມາດໃຊ້ໄດ້ຈົນກວ່າທ່ານປິດບ່ອນຈັດເກັບຂໍ້ມູນ USB ກ່ອນ."</string>
+    <string name="dlg_error_title" msgid="7323658469626514207">"ປະຕິບັດການ USB ບໍ່ສຳເລັດ"</string>
+    <string name="dlg_ok" msgid="7376953167039865701">"ຕົກລົງ"</string>
+    <string name="usb_mtp_notification_title" msgid="3699913097391550394">"ເຊື່ອມຕໍ່ເປັນອຸປະກອນສື່"</string>
+    <string name="usb_ptp_notification_title" msgid="1960817192216064833">"ເຊື່ອມຕໍ່ເປັນກ້ອງຖ່າຍຮູບແລ້ວ"</string>
+    <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"ເຊື່ອມຕໍ່ໃນນາມຕົວຕິດຕັ້ງ"</string>
+    <string name="usb_accessory_notification_title" msgid="7848236974087653666">"ເຊື່ອມຕໍ່ກັບອຸປະກອນເສີມ USB ແລ້ວ"</string>
+    <string name="usb_notification_message" msgid="2290859399983720271">"ແຕະເພື່ອເບິ່ງໂຕເລືອກເລືອກ USB ອື່ນໆ."</string>
+    <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"ຟໍແມັດ ບ່ອນຈັດເກັບຂໍ້ມູນ USB?"</string>
+    <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"ຟໍແມັດ SD card?"</string>
+    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"ໄຟລ໌ທັງໝົດທີ່ຢູ່ໃນບ່ອນຈັດເກັບຂໍ້ມູນ USB ຂອງທ່ານຈະຖືກລຶບອອກໝົດ. ການກະທຳຈະບໍ່ສາມາດຍົກເລີກໄດ້!"</string>
+    <string name="extmedia_format_message" product="default" msgid="14131895027543830">"ຂໍ້ມູນທັງໝົດໃນກາດຂອງທ່ານຈະຫາຍໄປ."</string>
+    <string name="extmedia_format_button_format" msgid="4131064560127478695">"ຟໍແມັດ"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"ເຊື່ອມຕໍ່ການດີບັ໊ກຜ່ານ USB ແລ້ວ"</string>
+    <string name="adb_active_notification_message" msgid="1016654627626476142">"ແຕະເພື່ອປິດການດີບັ໊ກຜ່ານ USB."</string>
+    <string name="select_input_method" msgid="4653387336791222978">"ເລືອກຮູບແບບການປ້ອນ"</string>
+    <string name="configure_input_methods" msgid="9091652157722495116">"ຕັ້ງຄ່າວິທີການປ້ອນຂໍ້ມູນ"</string>
+    <string name="use_physical_keyboard" msgid="6203112478095117625">"ແປ້ນພິມແທ້"</string>
+    <string name="hardware" msgid="7517821086888990278">"ຮາດແວ"</string>
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"ເລືອກຮູບແບບແປ້ນພິມ"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"ກົດເພື່ອເລືອກຮູບແບບແປ້ນພິມ."</string>
+    <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="candidates_style" msgid="4333913089637062257"><u>"ຕົວເລືອກ"</u></string>
+    <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"ກຳລັງກຽມບ່ອນຈັດເກັບຂໍ້ມູນ USB"</string>
+    <string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"ກຳລັງກະກຽມ SD card"</string>
+    <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"ກຳລັງກວດຫາຂໍ້ຜິດພາດ."</string>
+    <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"ບ່ອນຈັດເກັບຂໍ້ມູນ USB ເປົ່າຫວ່າງ"</string>
+    <string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"SD card ຫວ່າງເປົ່າ"</string>
+    <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"ບ່ອນຈັດເກັບຂໍ້ມູນ USB ຫວ່າງເປົ່າ ຫຼືມີໄຟລ໌ລະບົບທີ່ບໍ່ຮອງຮັບ."</string>
+    <string name="ext_media_nofs_notification_message" product="default" msgid="8641065641786923604">"SD card ຫວ່າງເປົ່າ ຫຼືມີລະບົບໄຟລ໌ທີ່ບໍ່ຮອງຮັບ."</string>
+    <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"ບ່ອນຈັດເກັບຂໍ້ມູນ USB ທີ່ເສຍຫາຍ."</string>
+    <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"SD card ທີ່ເສຍຫາຍ."</string>
+    <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="1795917578395333280">"ບ່ອນຈັດເກັບຂໍ້ມູນ USB ເສຍຫາຍ. ລອງຟໍແມັດມັນອີກຄັ້ງເບິ່ງ."</string>
+    <string name="ext_media_unmountable_notification_message" product="default" msgid="1753898567525568253">"SD card ເສຍຫາຍ. ລອງຟໍແມັດມັນອີກຄັ້ງເບິ່ງ."</string>
+    <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"ບ່ອນຈັດເກັບຂໍ້ມູນ USB ຖືກຖອດອອກແບບບໍ່ປອດໄພ"</string>
+    <string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"SD card ຖືກຖອດອອກໂດຍບໍ່ຄາດຄິດ"</string>
+    <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"ຖອດການເຊື່ອມຕໍ່ບ່ອນຈັດເກັບຂໍ້ມູນ USB ກ່ອນທີ່ຈະຖອດອອກ ເພື່ອປ້ອງກັນການສູນເສຍຂໍ້ມູນ."</string>
+    <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"ຖອນການເຊື່ອມຕໍ່ SD card ກ່ອນຈະຖອດອອກເພື່ອປ້ອງກັນການສູນເສຍຂໍ້ມູນ."</string>
+    <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"ບ່ອນຈັດເກັບຂໍ້ມູນ USB ສາມາດຖອດອອກໄດ້ຢ່າງປອດໄພ"</string>
+    <string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"ສາມາດຖອດ SD card ອອກໄດ້ປອດໄພແລ້ວ"</string>
+    <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"ທ່ານສາມາດຖອດບ່ອນຈັດເກັບຂໍ້ມູນ USB ອອກໄດ້ຢ່າງປອດໄພ."</string>
+    <string name="ext_media_safe_unmount_notification_message" product="default" msgid="568841278138377604">"ທ່ານສາມາດຖອດ SD card ອອກໄດ້ຢ່າງປອດໄພ."</string>
+    <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"ບ່ອນຈັດເກັບຂໍ້ມູນ USB ຖືກຖອດອອກແລ້ວ"</string>
+    <string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"SD card ຖືກຖອດອອກ"</string>
+    <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"ບ່ອນຈັດເກບັຂໍ້ມູນ USB ຖືກຖອດອອກແລ້ວ. ໃຫ້ໃສ່ອັນໃໝ່ເຂົ້າໄປ."</string>
+    <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"SD card ຖືກຖອດອອກແລ້ວ. ກະລຸນາໃສ່ອັນໃໝ່."</string>
+    <string name="activity_list_empty" msgid="1675388330786841066">"ບໍ່ພົບກິດຈະກຳທີ່ກົງກັນ."</string>
+    <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"ອັບເດດສະຖິຕິການນຳໃຊ້ອົງປະກອບ"</string>
+    <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"ອະນຸຍາດໃຫ້ແອັບຯແກ້ໄຂສະຖິຕິ ການນຳໃຊ້ຂໍ້ມູນສ່ວນປະກອບທີ່ເກັບກຳມາ. ແອັບຯທົ່ວໄປບໍ່ຈຳເປັນຕ້ອງໃຊ້."</string>
+    <string name="permlab_copyProtectedData" msgid="4341036311211406692">"ສຳເນົາເນື້ອຫາ"</string>
+    <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"ອະນຸຍາດໃຫ້ຮ້ອງຂໍບໍລິການຄອນເທັນເນີຫຼັກ ໃນການສຳເນົາເນື້ອຫາ. ບໍ່ໃຊ້ໃນແອັບຯທົ່ວໄປ."</string>
+    <string name="permlab_route_media_output" msgid="1642024455750414694">"ກຳນົດເສັ້ນທາງເອົ້າພຸດຂອງສື່"</string>
+    <string name="permdesc_route_media_output" msgid="4932818749547244346">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນ ກຳນົດເສັ້ນທາງເອົ້າພຸດຂອງສື່ໄປຫາອຸປະກອນພາຍນອກອື່ນໆ."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"ເຂົ້າໃຊ້ບ່ອນຈັດເກັບຂໍ້ມູນຄວາມປອດໄພຄີກາດ"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນ ເຂົ້າເຖິງບ່ອນຈັດເກັບຂໍ້ມູນຄວາມປອດໄພດ້ວຍຄີກາດ."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"ຄວບຄຸມການສະແດງ ແລະການເຊື່ອງໂຕລັອກປຸ່ມກົດ"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນສາມາດຄວບຄຸມຄີກາດໄດ້."</string>
+    <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"ແຕະສອງເທື່ອສຳລັບການຄວບຄຸມການຊູມ"</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>
+    <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">"ກົດເລກໝາຍ\nໂດຍໃຊ້ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"ສ້າງລາຍຊື່ຜູ່ຕິດຕໍ່\nໂດຍການໃຊ້ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"ມີນຶ່ງແອັບຯ ຫຼືຫຼາຍກວ່ານັ້ນກຳລັງຮ້ອງຂໍການອະນຸຍາດ ເພື່ອເຂົ້າເຖິງບັນຊີຂອງທ່ານໃນຕອນນີ້ ແລະອະນາຄົດ."</string>
+    <string name="grant_credentials_permission_message_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">"ຮ້ອງຂໍການກຳນົດສິດ\nສຳລັບບັນຊີ <xliff:g id="ACCOUNT">%s</xliff:g> ແລ້ວ."</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>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"ປ່ຽນພາບພື້ນຫຼັງ"</string>
+    <string name="notification_listener_binding_label" msgid="2014162835481906429">"ໂຕຟັງການແຈ້ງເຕືອນ"</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="3011306607126450322">"ແຕະເພື່ອຈັດການເຄືອຂ່າຍ."</string>
+    <string name="vpn_text_long" msgid="6407351006249174473">"ເຊື່ອມຕໍ່ຢູ່ກັບ <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_error" msgid="6009249814034708175">"VPN ແບບເປີດຕະຫຼອດເກີດຄວາມຜິດພາດ"</string>
+    <string name="vpn_lockdown_config" msgid="6415899150671537970">"ແຕະເພື່ອປັບຄ່າ"</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="8035230537563503262">"ກົດເພື່ອປິດໂຫມດຂັບລົດ."</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"ການປ່ອຍສັນຍານ ຫຼືຮັອດສະປອດທີ່ເຮັດວຽກຢູ່"</string>
+    <string name="tethered_notification_message" msgid="6857031760103062982">"ແຕະເພື່ອຕິດຕັ້ງ."</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="throttle_warning_notification_title" msgid="4890894267454867276">"ມີການໃຊ້ອິນເຕີເນັດຫຼາຍ"</string>
+    <string name="throttle_warning_notification_message" msgid="3340822228599337743">"ແຕະເພື່ອສຶກສາເພີ່ມເຕີມກ່ຽວກັບການໃຊ້ຂໍ້ມູນມືຖື."</string>
+    <string name="throttled_notification_title" msgid="6269541897729781332">"ການນຳໃຊ້ອິນເຕີເນັດຮອດຂີດຈຳກັດແລ້ວ"</string>
+    <string name="throttled_notification_message" msgid="5443457321354907181">"ແຕະເພື່ອສຶກສາເພີ່ມເຕີມກ່ຽວກັບການນຳໃຊ້ຂໍ້ມູນມືຖື."</string>
+    <string name="no_matches" msgid="8129421908915840737">"ບໍ່ພົບຜົນການຊອກຫາ"</string>
+    <string name="find_on_page" msgid="1946799233822820384">"ຊອກໃນໜ້າ"</string>
+  <plurals name="matches_found">
+    <item quantity="one" msgid="8167147081136579439">"1 ກົງກັນ"</item>
+    <item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> ຈາກທັງໝົດ <xliff:g id="TOTAL">%d</xliff:g>"</item>
+  </plurals>
+    <string name="action_mode_done" msgid="7217581640461922289">"ແລ້ວໆ"</string>
+    <string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"ກຳລັງຖອນການເຊື່ອມຕໍ່ບ່ອນຈັດເກັບຂໍ້ມູນ USB …"</string>
+    <string name="progress_unmounting" product="default" msgid="1327894998409537190">"ຖອນການເຊື່ອມຕໍ່ SD card..."</string>
+    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"ກຳລັງລຶບ ບ່ອນຈັດເກັບຂໍ້ມູນ USB …"</string>
+    <string name="progress_erasing" product="default" msgid="6596988875507043042">"ກຳລັງລຶບ​ SD card..."</string>
+    <string name="format_error" product="nosdcard" msgid="6299769563624776948">"ບໍ່ສາມາດລຶບບ່ອນຈັດເກັບຂໍ້ມູນ USB ໄດ້."</string>
+    <string name="format_error" product="default" msgid="7315248696644510935">"ບໍ່ສາມາດລຶບ SD card ໄດ້."</string>
+    <string name="media_bad_removal" msgid="7960864061016603281">"SD card ຖືກຖອດອອກກ່ອນການຖອນການເຊື່ອມຕໍ່."</string>
+    <string name="media_checking" product="nosdcard" msgid="418188720009569693">"ບ່ອນຈັດເກັບຂໍ້ມູນກຳລັງຢູ່ໃນລະຫວ່າງການກວດສອບ."</string>
+    <string name="media_checking" product="default" msgid="7334762503904827481">"ກຳລັງກວດສອບ SD card ຢູ່ໃນຂະນະນີ້."</string>
+    <string name="media_removed" msgid="7001526905057952097">"SD card ຖືກຖອດອອກແລ້ວ."</string>
+    <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"ບ່ອນຈັດເກັບຂໍ້ມູນ USB ກຳລັງຖືກນຳໃຊ້ໂດຍຄອມພິວເຕີ."</string>
+    <string name="media_shared" product="default" msgid="5706130568133540435">"SD card ກຳລັງຖືກນຳໃຊ້ໂດຍຄອມພິວເຕີຢູ່."</string>
+    <string name="media_unknown_state" msgid="729192782197290385">"ຂໍ້ມູນພາຍນອກຢູ່ໃນສະຖານະທີ່ບໍ່ຮູ້ຈັກ."</string>
+    <string name="share" msgid="1778686618230011964">"ແບ່ງປັນ"</string>
+    <string name="find" msgid="4808270900322985960">"ຊອກຫາ"</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="gpsNotifMessage" msgid="1374718023224000702">"ຮ້ອງຂໍໂດຍ <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+    <string name="gpsVerifYes" msgid="2346566072867213563">"ຕົກລົງ"</string>
+    <string name="gpsVerifNo" msgid="1146564937346454865">"ບໍ່"</string>
+    <string name="sync_too_many_deletes" msgid="5296321850662746890">"ກາຍເຂດກຳນົດການລຶບ"</string>
+    <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"ມີ <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> ລາຍການທີ່ຖືກລຶບສຳລັບ <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, ບັນຊີ <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. ທ່ານຕ້ອງການຈະເຮັດແນວໃດ?"</string>
+    <string name="sync_really_delete" msgid="2572600103122596243">"ລຶບລາຍການ"</string>
+    <string name="sync_undo_deletes" msgid="2941317360600338602">"ຍົກເລີກການລຶບ"</string>
+    <string name="sync_do_nothing" msgid="3743764740430821845">"ບໍ່ເຮັດຫຍັງໃນຕອນນີ້"</string>
+    <string name="choose_account_label" msgid="5655203089746423927">"ເລືອກບັນຊີ"</string>
+    <string name="add_account_label" msgid="2935267344849993553">"ເພີ່ມບັນຊີ"</string>
+    <string name="add_account_button_label" msgid="3611982894853435874">"ເພີ່ມບັນຊີ"</string>
+    <string name="number_picker_increment_button" msgid="2412072272832284313">"ເພີ່ມ"</string>
+    <string name="number_picker_decrement_button" msgid="476050778386779067">"ປັບລົງ"</string>
+    <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> ສຳພັດຄ້າງໄວ້."</string>
+    <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"ເລື່ອນຂຶ້ນເພື່ອເພີ່ມ ແລະເລື່ອນລົງເພື່ອຫຼຸດ."</string>
+    <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"ເພີ່ມນາທີ"</string>
+    <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"ປັບນາທີລົງ"</string>
+    <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"ເພີ່ມຊົ່ວໂມງ"</string>
+    <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"ຫຼຸດຊົ່ວໂມງ"</string>
+    <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"ຕັ້ງ PM"</string>
+    <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"ຕັ້ງ AM"</string>
+    <string name="date_picker_increment_month_button" msgid="5369998479067934110">"ເພີ່ມຈຳນວນເດືອນ"</string>
+    <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"ຫຼຸດເດືອນ"</string>
+    <string name="date_picker_increment_day_button" msgid="7130465412308173903">"ເພີ່ມຈຳນວນມື້"</string>
+    <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"ຫຼຸດຈຳນວນມື້"</string>
+    <string name="date_picker_increment_year_button" msgid="6318697384310808899">"ເພີ່ມປີຂຶ້ນ"</string>
+    <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"ຫຼຸດຈຳນວນປີ"</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_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"ເລືອກແອັບຯ"</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">"ເລື່ອນບ່ອນຖື ແລ້ວແຕະຄ້າງໄວ້."</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"ເລື່ອນຂຶ້ນເພື່ອ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"ເລື່ອນລົງເພື່ອ <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="description_direction_right" msgid="8034433242579600980">"ເລື່ອນໄປທາງຂວາເພື່ອ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"ປົດລັອກ"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"ກ້ອງ"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"ປິດສຽງ"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"ເປີດສຽງ"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"ຊອກຫາ"</string>
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"ປັດເພື່ອປົດລັອກ."</string>
+    <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"ສຽບສາຍຫູຟັງເພື່ອຟັງລະຫັດຜ່ານ."</string>
+    <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"ຈໍ້າເມັດ."</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="4891916833657929263">"ບ່ອນຈັດເກັບຂໍ້ມູນພາຍໃນ"</string>
+    <string name="storage_sd_card" msgid="3282948861378286745">"SD card"</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="1955638862122232342">"ເຕືອນກ່ຽວກັບການນຳໃຊ້ຂໍ້ມູນ"</string>
+    <string name="data_usage_warning_body" msgid="2814673551471969954">"ແຕະເພື່ອເບິ່ງການນຳໃຊ້ ແລະການຕັ້ງຄ່າ."</string>
+    <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"ປິດການນຳໃຊ້ຂໍ້ມູນ 2G-3G"</string>
+    <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"ການນຳໃຊ້ຂໍ້ມູນ 4G ຖືກປິດແລ້ວ"</string>
+    <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"ຂໍ້ມູນມືຖືຖືກປິດໄວ້"</string>
+    <string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"ປິດຂໍ້ມູນ Wi-Fi ແລ້ວ"</string>
+    <string name="data_usage_limit_body" msgid="3317964706973601386">"ແຕະເພື່ອເປີດໃຊ້."</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_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="6741521330997452990">"ແຕະເພື່ອເອົາການຈຳກັດອອກ"</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>
+    <string name="org_unit" msgid="7265981890422070383">"ໜ່ວຍອົງກອນ:"</string>
+    <string name="issued_by" msgid="2647584988057481566">"ອອກໃຫ້ໂດຍ:"</string>
+    <string name="validity_period" msgid="8818886137545983110">"ອາຍຸການນຳໃຊ້:"</string>
+    <string name="issued_on" msgid="5895017404361397232">"ອອກໃຫ້ເມື່ອ:"</string>
+    <string name="expires_on" msgid="3676242949915959821">"ໝົດອາຍຸໃນ:"</string>
+    <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>
+    <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"ເບິ່ງທັງຫມົດ"</string>
+    <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"ເລືອກກິດຈະກຳ"</string>
+    <string name="share_action_provider_share_with" msgid="5247684435979149216">"ແບ່ງປັນກັບ"</string>
+    <string name="status_bar_device_locked" msgid="3092703448690669768">"ອຸປະກອນລັອກ."</string>
+    <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="3245653681008218030">"ກຳລັງສົ່ງ..."</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="default_audio_route_name" product="tablet" msgid="4617053898167127471">"ແທັບເລັດ"</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="media_route_chooser_grouping_done" msgid="7966438307723317169">"ແລ້ວໆ"</string>
+    <string name="media_route_button_content_description" msgid="5758553567065145276">"ມີເດຍເອົ້າພຸດ"</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>
+    <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_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="wifi_display_notification_title" msgid="2223050649240326557">"ເຊື່ອມຕໍ່ການສະແດງຜົນໄຮ້ສາຍແລ້ວ"</string>
+    <string name="wifi_display_notification_message" msgid="4498802012464170685">"ຈໍນີ້ກຳລັງສະແດງຢູ່ໃນອຸປະກອນອື່ນ"</string>
+    <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"ຢຸດການເຊື່ອມຕໍ່"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"ການໂທສຸກເສີນ"</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">"ລະຫັດ PIN ຜິດ"</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 ຂອງຊິມ"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"ໃສ່ລະຫັດ PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"ໃສ່ລະຫັດຜ່ານ"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"ຊິມຖືກປິດການນຳໃຊ້ແລ້ວ. ປ້ອນລະຫັດ PUK ເພື່ອດຳເນີນການຕໍ່. ຕິດຕໍ່ຜູ່ໃຫ້ບໍລິການສຳລັບລາຍລະອຽດ."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"ໃສ່ລະຫັດ PIN ທີ່ຕ້ອງການ."</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"ຢືນຢັນລະຫັດ PIN ທີ່ຕ້ອງການ"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"ປົດລັອກ SIM card..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"ລະຫັດ PIN ບໍ່ຖືກຕ້ອງ."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"ພິມລະຫັດ PIN ຄວາມຍາວ 4 ເຖິງ 8 ໂຕເລກ."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"ລະຫັດ PUK ຄວນມີຢ່າງໜ້ອຍ 8 ໂຕເລກ."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"ປ້ອນລະຫັດ PUK ທີ່ຖືກຕ້ອງຄືນໃໝ່. ການພະຍາຍາມໃສ່ຫຼາຍເທື່ອຈະເຮັດໃຫ້ຊິມກາດໃຊ້ບໍ່ໄດ້ຖາວອນ."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"ລະຫັດ PIN ບໍ່ກົງກັນ"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ແຕ້ມຮູບແບບປົດລັອກຫຼາຍເກີນໄປ"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"ເພື່ອປົດລັອກ, ເຂົ້າສູ່ລະບົບດ້ວຍບັນຊີ Google ຂອງທ່ານ."</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"ກຳລັງກວດສອບບັນຊີ..."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"ທ່ານພິມລະຫັດ PIN​ ຂອງທ່ານຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. \n\nກະລຸນາລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ວິນາທີ."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"ທ່ານພິມລະຫັດຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. \n\nລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ວິນາທີ."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"ທ່ານແຕ້ມຮູບແບບປົດລັອກຂອງທ່ານຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. \n\nກະລຸນາລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ວິນາທີ."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"ທ່ານໄດ້ພະຍາຍາມປົດລັອກແທັບເລັດບໍ່ສຳເລັດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກຄວາມພະຍາຍາມອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ເທື່ອ ແທັບເລັດຂອງທ່ານຈະຖືກຕັ້ງ ໃຫ້ກັບໄປໃຊ້ຄ່າເລີ່ມຕົ້ນຈາກໂຮງງານຄືນໃໝ່ ແລະຂໍ້ມູນຜູ່ໃຊ້ທັງໝົດຈະສູນຫາຍໄປ."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"ທ່ານໄດ້ພະຍາຍາມປົດລັອກໂທລະສັບບໍ່ສຳເລັດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກຄວາມພະຍາຍາມອີກ <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກແຕ້ມຜິດອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ເທື່ອ, ທ່ານຈະຖືກຖາມໃຫ້ປົດລັອກແທັບເລັດຂອງທ່ານ ດ້ວຍການເຂົ້າສູ່ລະບົບໂດຍໃຊ້ອີເມວຂອງທ່ານ.\n\n ກະລຸນາລອງໃໝ່ອີກຄັ້ງໃນອີກ <xliff:g id="NUMBER_2">%d</xliff:g> ວິນາທີ."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"ທ່ານແຕ້ມຮູບແບບປົດລັອກຂອງທ່ານຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກຄວາມພະຍາຍາມອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ເທື່ອ ທ່ານຈະຖືກຖາມໃຫ້ປົດລັອກໂທລະສັບຂອງທ່ານດ້ວຍບັນຊີອີເມວ.\n\n ລອງໃໝ່ອີກຄັ້ງໃນ <xliff:g id="NUMBER_2">%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="7324161939475478066">"ຕ້ອງການເພີ່ມລະດັບສຽງຈົນເກີນລະດັບທີ່ແນະນຳ?\nການຟັງໃນລະດັບສຽງດັງເປັນເວລາດົນ ອາດທຳລາຍການໄດ້ຍິນສຽງຂອງທ່ານໄດ້."</string>
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"ກົດສອງນິ້ວຄ້າງໄວ້ເພື່ອເປີດໃຊ້ການຊ່ວຍເຂົ້າເຖິງ"</string>
+    <string name="accessibility_enabled" msgid="1381972048564547685">"ເປີດການຊ່ວຍເຂົ້າເຖິງແລ້ວ."</string>
+    <string name="enable_accessibility_canceled" msgid="3833923257966635673">"ຍົກເລີກໂຕຊ່ວຍການເຂົ້າເຖິງແລ້ວ."</string>
+    <string name="user_switched" msgid="3768006783166984410">"ຜູ່ໃຊ້ປັດຈຸບັນ <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="app_no_restricted_accounts" msgid="5739463249673727736">"ແອັບພລິເຄຊັນນີ້ບໍ່ຮອງຮັບບັນຊີຂອງໂປຣໄຟລ໌ທີ່ຖືກຈຳກັດ."</string>
+    <string name="app_not_found" msgid="3429141853498927379">"ບໍ່ພົບແອັບພລິເຄຊັນເພື່ອຈັດການເຮັດວຽກນີ້."</string>
+    <string name="revoke" msgid="5404479185228271586">"ຖອນ"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"ຈົດໝາຍ"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"ຈົດ​ຫມາຍທາງ​ລັດ​ຖະ​ບານ"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"ກົດຫມາຍ"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"ກົດໝາຍຂັ້ນຕ່ຳ"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"ບັນ​ຊີ"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"ແຖບບລອຍ"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"ຍົກເລີກແລ້ວ"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"ເນື້ອ​ໃນ​ການຂຽນຜິດພາດ"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"ໃສ່ລະຫັດ PIN"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN ປະ​ຈຸ​ບັນ"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"ລະຫັດ PIN ໃໝ່"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"ຢືນຢັນລະຫັດ PIN ໃໝ່"</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_too_short" msgid="8173982756265777792">"PIN ​ສັ້ນ​ເກີນ​ໄປ​. ຕ້ອງມີຢ່າງໜ້ອຍ 4 ຫຼັກ​."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="4835639969503729874">"PIN ​ບໍ່​ຖືກ​ຕ້ອງ​. ລອງໃໝ່ໃນອີກ 1 ວິນາທີ."</item>
+    <item quantity="other" msgid="8030607343223287654">"PIN ບໍ່​ຖືກ​ຕ້ອງ​. ລອງໃໝ່ໃນອີກ <xliff:g id="COUNT">%d</xliff:g> ວິ​ນາ​ທີ​."</item>
+  </plurals>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"ປັດຢູ່ຂອບຂອງໜ້າຈໍເພື່ອສະແດງແຖບ"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"ປັດຢູ່ຂອບຂອງໜ້າຈໍເພື່ອສະແດງແຖບຂອງລະບົບ"</string>
+</resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 593316f..ff2079a 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -131,6 +131,11 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Per daug <xliff:g id="CONTENT_TYPE">%s</xliff:g> trynimo."</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Planšetinio kompiuterio atmintis pilna. Kad atlaisvintumėte vietos, ištrinkite kelis failus."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Telefono atmintis pilna. Ištrinkite kai kuriuos failus, kad atlaisvintumėte vietos."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Tinklas gali būti stebimas"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Aš"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Planšetinio kompiuterio parinktys"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Telefono parinktys"</string>
@@ -138,7 +143,7 @@
     <string name="turn_on_radio" msgid="3912793092339962371">"Įjungti bevielį"</string>
     <string name="turn_off_radio" msgid="8198784949987062346">"Išjungti bevielį"</string>
     <string name="screen_lock" msgid="799094655496098153">"Ekrano užraktas"</string>
-    <string name="power_off" msgid="4266614107412865048">"Išjungti maitinimą"</string>
+    <string name="power_off" msgid="4266614107412865048">"Išjungiamas maitinimas"</string>
     <string name="silent_mode_silent" msgid="319298163018473078">"Skambutis išjungtas"</string>
     <string name="silent_mode_vibrate" msgid="7072043388581551395">"Vibracija skambinant"</string>
     <string name="silent_mode_ring" msgid="8592241816194074353">"Skambutis įjungtas"</string>
@@ -153,7 +158,7 @@
     <string name="global_actions" product="tablet" msgid="408477140088053665">"Planšetinio kompiuterio parinktys"</string>
     <string name="global_actions" product="default" msgid="2406416831541615258">"Telefono parinktys"</string>
     <string name="global_action_lock" msgid="2844945191792119712">"Ekrano užraktas"</string>
-    <string name="global_action_power_off" msgid="4471879440839879722">"Išjungti maitinimą"</string>
+    <string name="global_action_power_off" msgid="4471879440839879722">"Išjungiamas maitinimas"</string>
     <string name="global_action_bug_report" msgid="7934010578922304799">"Pranešimas apie triktį"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Pranešti apie triktį"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Bus surinkta informacija apie dabartinę įrenginio būseną ir išsiųsta el. pašto pranešimu. Šiek tiek užtruks, kol pranešimas apie triktį bus paruoštas siųsti; būkite kantrūs."</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Leidžiama programai perkelti užduotis į priekinį planą ir foną. Programa gali tai daryti be jūsų įsikišimo."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"sustabdyti vykdomas programas"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Leidžiama programai pašalinti užduotis ir panaikinti jų programas. Kenkėjiškos programos gali trikdyti kitų programų veikimą."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"tvarkyti veiklos krūvas"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Programai leidžiama pridėti, pašalinti ir modifikuoti veiklos krūvas, kuriose paleistos kitos programos. Kenkėjiškos programos gali trikdyti kitų programų elgseną."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"pradėti bet kokią veiklą"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Programai leidžiama pradėti bet kokią veiklą, nepaisant leidimo apsaugos ar eksportuotos būsenos."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"nustatyti ekrano suderinamumo režimą"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Leidžiama savininką susaistyti su įvesties metodo aukščiausio lygio sąsaja. Įprastoms programoms to neturėtų prireikti."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"susisaistyti su pasiekiamumo paslauga"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Savininkui leidžiama susisaistyti su aukščiausio lygio pasiekiamumo paslaugos sąsaja. Įprastoms programoms to neturėtų prireikti."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"susisaistyti su spausdinimo paslauga"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Turėtojui leidžiama susisaistyti su spausdinimo paslaugos aukščiausio lygio sąsaja. Įprastoms programoms to neturėtų prireikti."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"susaistyti su spausdinimo kaupimo paslauga"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Turėtojui leidžiama susaistyti programą su spausdinimo kaupimo paslaugos aukščiausio lygio sąsaja. Įprastoms programoms to neturėtų prireikti."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"susaistyti su ALR paslauga"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Savininkui leidžiama susaistyti programas, kurios kopijuoja ALR korteles. Neturėtų prireikti įprastoms programoms."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"priskirti teksto paslaugą"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Leidžiama savininkui priskirti aukščiausio lygio teksto paslaugos (pvz., „SpellCheckerService“) sąsają. Įprastoms programoms to neturėtų prireikti."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"susaistyti su VPN paslauga"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Leidžiama savininkui susisaistyti su aukščiausio lygio valdiklio paslaugos sąsaja. Įprastoms programoms to neturėtų prireikti."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"sąveikauti su įrenginio administratoriumi"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Leidžiama savininkui siųsti tikslus įrenginio administratoriui. Įprastoms programoms to neturėtų prireikti."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"pridėti arba pašalinti įrenginio administratorių"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Savininkui leidžiama pridėti aktyvių įrenginio administratorių arba juos pašalinti. Neturėtų reikėti įprastoms programoms."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"keisti ekrano padėtį"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Leidžiama programai bet kada kaitalioti ekraną. Įprastoms programoms to neturėtų prireikti."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"keisti žymiklio greitį"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Leidžiama programai skaityti iš įvairių sistemos žurnalų failų. Taip galima atrasti bendrą informaciją apie tai, ką darote telefonu, potencialiai įtraukiant asmeninę ar privačią informaciją."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"atkuriant naudoti bet kurį medijos dekoderį"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Leidžiama programai naudoti bet kurį įdiegtą medijos dekoderį norint iššifruoti atkūrimą."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"tvarkyti patikimus prisijungimo duomenis"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Programoje galima įdiegti ir iš jos pašalinti CA sertifikatus kaip patikimus prisijungimo duomenis."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"skaityti / rašyti ištekliuose, priklausančiuose diagnostikai"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Leidžiama programai skaityti ir rašyti visuose diagnostikos grupei priklausančiuose ištekliuose, pvz., failuose, esančiuose /dev. Tai gali paveikti sistemos stabilumą ir saugą. Tai turėtų būti naudojama TIK gamintojui ar operatoriui atliekant aparatinės įrangos diagnostiką."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"įgalinti programos komponentus arba jų neleisti"</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Leidžiama programai konfigūruoti ir prisijungti prie „Wi-Fi“ pateikčių."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"valdyti „Wi-Fi“ pateiktis"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Leidžiama programai valdyti „Wi-Fi“ pateikčių žemo lygio funkcijas."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"fiksuoti garso išvestį"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Programai leidžiama fiksuoti ir peradresuoti garso išvestį."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"fiksuoti vaizdo išvestį"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Programai leidžiama fiksuoti ir peradresuoti vaizdo išvestį."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"fiksuoti saugią vaizdo išvestį"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Programai leidžiama fiksuoti ir peradresuoti saugią vaizdo išvestį."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"keisti garso nustatymus"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Leidžiama programai keisti visuotinius garso nustatymus, pvz., garsumą ir tai, kuris garsiakalbis naudojamas išvesčiai."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"įrašyti garsą"</string>
@@ -525,6 +552,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"neleisti telefonui snausti"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Leidžiama programai neleisti planšetiniam kompiuteriui užmigti."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Leidžiama programai neleisti telefonui užmigti."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"įjungti arba išjungti planšetinį kompiuterį"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"telefono įjungimas ir išjungimas"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Leidžiama programai įjungti ar išjungti planšetinį kompiuterį."</string>
@@ -613,6 +646,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Leidžiama programai rašyti į SD kortelę."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"keisti / ištr. vid. med. atm. tur."</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Leidžiama programai keisti vidinės medijos saugyklos turinį."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"tvarkyti dokumentų saugyklą"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Leidžiama programai tvarkyti dokumentų saugyklą."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"pasiekti visų naud. išor. atm."</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Leidžiama programai pasiekti visų naudotojų išorinę atmintinę."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"pasiekti talpyklos failų sistemą"</string>
@@ -625,10 +660,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Leidžiama programai valdyti tinklo politiką ir apibrėžti konkrečios programos taisykles."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"keisti tinklo naudojimo apskaitą"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Leidžiama programai keisti, kaip tinklas naudojamas, palyginti su programomis. Neskirta naudoti įprastoms programoms."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"modifikuoti lizdų ženklus"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Programai leidžiama modifikuoti maršrutui parinkti skirtus lizdų ženklus"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"pasiekti pranešimus"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Programai leidžiama gauti, patikrinti ir išvalyti pranešimus, įskaitant pranešimus, kuriuos paskelbė kitos programos."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"susisaistyti su pranešimų skaitymo priemonės paslauga"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Leidžiama turėtojui susisaistyti su pranešimų skaitymo priemonės paslaugos aukščiausio lygio sąsaja. Įprastoms programoms to neturėtų prireikti."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"iškviesti operatoriaus pateiktą konfigūravimo programą"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Turėtojui leidžiama iškviesti operatoriaus pateiktą konfigūravimo programą. Įprastoms programoms to neturėtų prireikti."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"vykdyti tinklo sąlygų stebėjimą"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Leidžiama programai vykdyti tinklo sąlygų stebėjimą. To niekada neturėtų prireikti naudojant įprastas programas."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Nustatyti slaptažodžio taisykles"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Valdyti leidžiamą ekrano atrakinimo slaptažodžių ilgį ir leidžiamus naudoti simbolius."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Stebėti bandymus atrakinti ekraną"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <string name="imProtocolGoogleTalk" msgid="493902321140277304">"Hangout"</string>
     <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string>
     <string name="imProtocolJabber" msgid="2279917630875771722">"„Jabber“"</string>
     <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string>
@@ -796,7 +836,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Įdėkite SIM kortelę."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Trūksta SIM kortelės arba ji neskaitoma. Įdėkite SIM kortelę."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Negalima naudoti SIM kortelės."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"SIM kortelė visam laikui neleidžiama."\n" Jei norite gauti kitą SIM kortelę, susisiekite su belaidžio ryšio paslaugos teikėju."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"SIM kortelė visam laikui neleidžiama.\n Jei norite gauti kitą SIM kortelę, susisiekite su belaidžio ryšio paslaugos teikėju."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Ankstesnio takelio mygtukas"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Kito takelio mygtukas"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Pristabdymo mygtukas"</string>
@@ -808,11 +848,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Žr. naudotojo vadovą arba susisiekite su klientų priežiūros tarnyba."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM kortelė užrakinta."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Atrakinama SD kortelė..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Neteisingai apibrėžėte atrakinimo modelį <xliff:g id="NUMBER_0">%d</xliff:g> k. "\n\n"Bandykite dar kartą po <xliff:g id="NUMBER_1">%d</xliff:g> sek."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Neteisingai įvedėte slaptažodį <xliff:g id="NUMBER_0">%d</xliff:g> k. "\n\n"Bandykite dar kartą po <xliff:g id="NUMBER_1">%d</xliff:g> sek."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"PIN kodą neteisingai įvedėte <xliff:g id="NUMBER_0">%d</xliff:g> k. "\n\n"Bandykite dar kartą po <xliff:g id="NUMBER_1">%d</xliff:g> sek."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Neteisingai nurodėte savo atrakinimo modelį <xliff:g id="NUMBER_0">%d</xliff:g> k. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. būsite paprašyti atrakinti planšetinį kompiuterį naudodami „Google“ prisijungimo duomenis."\n\n" Bandykite dar kartą po <xliff:g id="NUMBER_2">%d</xliff:g> sek."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Neteisingai nurodėte savo atrakinimo modelį <xliff:g id="NUMBER_0">%d</xliff:g> k. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. būsite paprašyti atrakinti telefoną naudodami „Google“ prisijungimo duomenis."\n\n" Bandykite dar kartą po <xliff:g id="NUMBER_2">%d</xliff:g> sek."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Neteisingai apibrėžėte atrakinimo modelį <xliff:g id="NUMBER_0">%d</xliff:g> k. \n\nBandykite dar kartą po <xliff:g id="NUMBER_1">%d</xliff:g> sek."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Neteisingai įvedėte slaptažodį <xliff:g id="NUMBER_0">%d</xliff:g> k. \n\nBandykite dar kartą po <xliff:g id="NUMBER_1">%d</xliff:g> sek."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"PIN kodą neteisingai įvedėte <xliff:g id="NUMBER_0">%d</xliff:g> k. \n\nBandykite dar kartą po <xliff:g id="NUMBER_1">%d</xliff:g> sek."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Neteisingai nurodėte savo atrakinimo modelį <xliff:g id="NUMBER_0">%d</xliff:g> k. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. būsite paprašyti atrakinti planšetinį kompiuterį naudodami „Google“ prisijungimo duomenis.\n\n Bandykite dar kartą po <xliff:g id="NUMBER_2">%d</xliff:g> sek."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Neteisingai nurodėte savo atrakinimo modelį <xliff:g id="NUMBER_0">%d</xliff:g> k. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. būsite paprašyti atrakinti telefoną naudodami „Google“ prisijungimo duomenis.\n\n Bandykite dar kartą po <xliff:g id="NUMBER_2">%d</xliff:g> sek."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"<xliff:g id="NUMBER_0">%d</xliff:g> kart. bandėte netinkamai atrakinti planšetinį kompiuterį. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. planšetiniame kompiuteryje bus iš naujo nustatyti numatytieji gamyklos nustatymai ir bus prarasti visi naudotojo duomenys."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"<xliff:g id="NUMBER_0">%d</xliff:g> kart. bandėte netinkamai atrakinti telefoną. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. telefone bus iš naujo nustatyti numatytieji gamyklos nustatymai ir bus prarasti visi naudotojo duomenys."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"<xliff:g id="NUMBER">%d</xliff:g> kart. bandėte netinkamai atrakinti planšetinį kompiuterį. Planšetinis kompiuteris bus iš naujo nustatytas į numatytuosius gamyklos nustatymus."</string>
@@ -826,7 +866,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Slaptažodis"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Prisijungti"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Neteisingas naudotojo vardas ar slaptažodis."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Pamiršote naudotojo vardą ar slaptažodį?"\n"Apsilankykite šiuo adresu: "<b>"google.com/accounts/recovery?hl=lt"</b></string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Pamiršote naudotojo vardą ar slaptažodį?\nApsilankykite šiuo adresu: "<b>"google.com/accounts/recovery?hl=lt"</b></string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Tikrinama..."</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Atblokuoti"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Garsas įjungtas"</string>
@@ -874,7 +914,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Patvirtinti išėjimą"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Išeiti iš šio puslapio"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Likti šiame puslapyje"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Tikrai norite išeiti iš šio puslapio?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nTikrai norite išeiti iš šio puslapio?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Patvirtinti"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Patarimas: palieskite dukart, kad padidintumėte ar sumažintumėte mastelį."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Automatinis pildymas"</string>
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"Deja, <xliff:g id="APPLICATION">%1$s</xliff:g> sustojo."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Deja, <xliff:g id="PROCESS">%1$s</xliff:g> sustojo."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"„<xliff:g id="APPLICATION">%2$s</xliff:g>“ neatsako."\n\n"Ar norite ją uždaryti?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Veiksmas „<xliff:g id="ACTIVITY">%1$s</xliff:g>“ neatsako."\n\n"Ar norite jį uždaryti?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"„<xliff:g id="APPLICATION">%2$s</xliff:g>“ neatsako.\n\nAr norite ją uždaryti?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Veiksmas „<xliff:g id="ACTIVITY">%1$s</xliff:g>“ neatsako.\n\nAr norite jį uždaryti?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"„<xliff:g id="APPLICATION">%1$s</xliff:g>“ neatsako. Ar norite ją uždaryti?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Procesas „<xliff:g id="PROCESS">%1$s</xliff:g>“ neatsako."\n\n"Ar norite jį uždaryti?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Procesas „<xliff:g id="PROCESS">%1$s</xliff:g>“ neatsako.\n\nAr norite jį uždaryti?"</string>
     <string name="force_close" msgid="8346072094521265605">"Gerai"</string>
     <string name="report" msgid="4060218260984795706">"Ataskaita"</string>
     <string name="wait" msgid="7147118217226317732">"Palaukti"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"Puslapis neatsako."\n\n"Ar norite jį uždaryti?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Puslapis neatsako.\n\nAr norite jį uždaryti?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Programa peradresuota"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ dabar vykdoma."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ buvo iš pradžių paleista."</string>
@@ -1256,6 +1296,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Leidžiama programai iškviesti numatytąją sudėtinio rodinio paslaugą, kad būtų kopijuojamas turinys. Neskirta naudoti įprastoms programoms."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Medijos išvesties nukreipimas"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Leidžiama programai nukreipti medijos išvestį į kitus išorinius įrenginius."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Pasiekti „KeyGuard“ saugyklą"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Programai leidžiama pasiekti „KeyGuard“ saugyklą."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Valdyti „KeyGuard“ rodymą ir slėpimą"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Programai leidžiama valdyti „KeyGuard“."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Dukart palieskite, kad valdytumėte mastelio keitimą"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Nepavyko pridėti."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Pradėti"</string>
@@ -1265,15 +1309,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Atlikta"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Perž."</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Vykdyti"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Rinkti numerį "\n"naudojant <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Sukurti adresatą"\n"naudojant <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Rinkti numerį \nnaudojant <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Sukurti adresatą\nnaudojant <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Pateikta mažiausiai vienos toliau nurodytos programos užklausa dėl leidimo dabar ir ateityje pasiekti jūsų paskyrą."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Ar norite leisti šią užklausą?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Užklausa dėl prieigos"</string>
     <string name="allow" msgid="7225948811296386551">"Leisti"</string>
     <string name="deny" msgid="2081879885755434506">"Atmesti"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Pateikta užklausa dėl leidimo"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Pateikta leidimo užklausa"\n"dėl <xliff:g id="ACCOUNT">%s</xliff:g> paskyros"</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Pateikta leidimo užklausa\ndėl <xliff:g id="ACCOUNT">%s</xliff:g> paskyros"</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Įvesties būdas"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Sinchronizuoti"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Pasiekiamumas"</string>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Žr. viską"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Pasirinkti veiklą"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Bendrinti su"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Įrenginys užrakintas."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Siunčiama…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Paleisti naršyklę?"</string>
@@ -1441,10 +1484,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Jungiama..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Pasiekiama"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"Nepasiekiama"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"Naudojama"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Integruotas ekranas"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"HDMI ekranas"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Perdanga nr. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"„<xliff:g id="NAME">%1$s</xliff:g>“: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> tašk. colyje"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", saugu"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Prijungtas belaidis monitorius"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Šis ekranas rodomas kitame įrenginyje"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Atjungti"</string>
@@ -1453,7 +1498,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Netinkamas atrakinimo piešinys"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Netinkamas slaptažodis"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"Netinkamas PIN kodas"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Bandyti dar kartą po <xliff:g id="NUMBER">%d</xliff:g> sek."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Bandyti dar kartą po <xliff:g id="NUMBER">%1$d</xliff:g> sek."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Nupieškite atrakinimo piešinį"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Įveskite SIM PIN kodą"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Įveskite PIN kodą"</string>
@@ -1473,27 +1518,85 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Slaptažodis"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Prisijungti"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Netinkamas naudotojo vardas ar slaptažodis."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Pamiršote naudotojo vardą ar slaptažodį?"\n"Apsilankykite šiuo adresu: "<b>"google.com/accounts/recovery"</b></string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Pamiršote naudotojo vardą ar slaptažodį?\nApsilankykite šiuo adresu: "<b>"google.com/accounts/recovery"</b></string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Tikrinama paskyra…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN kodą netinkamai įvedėte <xliff:g id="NUMBER_0">%d</xliff:g> k. "\n\n"Bandykite dar kartą po <xliff:g id="NUMBER_1">%d</xliff:g> sek."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Neteisingai įvedėte slaptažodį <xliff:g id="NUMBER_0">%d</xliff:g> k. "\n\n"Bandykite dar kartą po <xliff:g id="NUMBER_1">%d</xliff:g> sek."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Netinkamai nupiešėte atrakinimo piešinį <xliff:g id="NUMBER_0">%d</xliff:g> k. "\n\n"Bandykite dar kartą po <xliff:g id="NUMBER_1">%d</xliff:g> sek."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN kodą netinkamai įvedėte <xliff:g id="NUMBER_0">%d</xliff:g> k. \n\nBandykite dar kartą po <xliff:g id="NUMBER_1">%d</xliff:g> sek."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Neteisingai įvedėte slaptažodį <xliff:g id="NUMBER_0">%d</xliff:g> k. \n\nBandykite dar kartą po <xliff:g id="NUMBER_1">%d</xliff:g> sek."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Netinkamai nupiešėte atrakinimo piešinį <xliff:g id="NUMBER_0">%d</xliff:g> k. \n\nBandykite dar kartą po <xliff:g id="NUMBER_1">%d</xliff:g> sek."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"<xliff:g id="NUMBER_0">%d</xliff:g> k. bandėte netinkamai atrakinti planšetinį kompiuterį. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. planšetiniame kompiuteryje bus iš naujo nustatyti numatytieji gamyklos nustatymai ir bus prarasti visi naudotojo duomenys."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"<xliff:g id="NUMBER_0">%d</xliff:g> k. bandėte netinkamai atrakinti telefoną. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. telefone bus iš naujo nustatyti numatytieji gamyklos nustatymai ir bus prarasti visi naudotojo duomenys."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"<xliff:g id="NUMBER">%d</xliff:g> k. bandėte netinkamai atrakinti planšetinį kompiuterį. Planšetiniame kompiuteryje bus iš naujo nustatyti numatytieji gamyklos nustatymai."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"<xliff:g id="NUMBER">%d</xliff:g> k. bandėte netinkamai atrakinti telefoną. Telefone bus iš naujo nustatyti numatytieji gamyklos nustatymai."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Netinkamai nupiešėte atrakinimo piešinį <xliff:g id="NUMBER_0">%d</xliff:g> k. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. būsite paprašyti atrakinti planšetinį kompiuterį naudodami „Google“ prisijungimo duomenis."\n\n" Bandykite dar kartą po <xliff:g id="NUMBER_2">%d</xliff:g> sek."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Netinkamai nupiešėte atrakinimo piešinį <xliff:g id="NUMBER_0">%d</xliff:g> k. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. būsite paprašyti atrakinti telefoną naudodami „Google“ prisijungimo duomenis."\n\n" Bandykite dar kartą po <xliff:g id="NUMBER_2">%d</xliff:g> sek."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Netinkamai nupiešėte atrakinimo piešinį <xliff:g id="NUMBER_0">%d</xliff:g> k. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. būsite paprašyti atrakinti planšetinį kompiuterį naudodami „Google“ prisijungimo duomenis.\n\n Bandykite dar kartą po <xliff:g id="NUMBER_2">%d</xliff:g> sek."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Netinkamai nupiešėte atrakinimo piešinį <xliff:g id="NUMBER_0">%d</xliff:g> k. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. būsite paprašyti atrakinti telefoną naudodami „Google“ prisijungimo duomenis.\n\n Bandykite dar kartą po <xliff:g id="NUMBER_2">%d</xliff:g> sek."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Pašalinti"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Padidinti garsumą viršijant saugų lygį?"\n"Ilgai klausantis dideliu garsumu gali sutrikti klausa."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Padidinti garsumą viršijant saugų lygį?\nIlgai klausantis dideliu garsumu gali sutrikti klausa."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Laikykite palietę dviem pirštais, kad įgalintumėte pritaikymo neįgaliesiems režimą."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Pritaikymas neįgaliesiems įgalintas."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Pritaikymo neįgaliesiems režimas atšauktas."</string>
     <string name="user_switched" msgid="3768006783166984410">"Dabartinis naudotojas: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Savininkas"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Klaida"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Ši programa nepalaiko apribotų profilių paskyrų"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Ši programa nepalaiko apribotų profilių paskyrų"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Nerasta programa šiam veiksmui apdoroti"</string>
     <string name="revoke" msgid="5404479185228271586">"Anuliuoti"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO S9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Laiškas"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Oficialus laiškas"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Teisinis"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Mažas teisinis"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Buhalterinis"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Bulvarinė spauda"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Atšaukta"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Klaida rašant turinį"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"nežinoma"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Įveskite administratoriaus PIN kodą"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Įveskite PIN kodą"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Neteisingas"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Dabartinis PIN kodas"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Naujas PIN kodas"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Patvirtinti naują PIN kodą"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Sukurti modifikavimo apribojimų PIN kodą"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PIN kodas neatitinka. Bandykite dar kartą."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"PIN kodas per trumpas. Jis turi būti bent 4 skaitmenų."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Band. dar po 1 s"</item>
+    <item quantity="other" msgid="4730868920742952817">"Band. dar po <xliff:g id="COUNT">%d</xliff:g> s"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Vėliau bandykite dar kartą"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Perbr. ekr. kr., kad atsir. juost."</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Perbraukite iš ekrano krašto, kad atsirastų sistemos juosta"</string>
 </resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 11e0116..55dece8 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -131,6 +131,11 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Pārāk daudz <xliff:g id="CONTENT_TYPE">%s</xliff:g> dzēsto vienumu."</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Planšetdatora atmiņa ir pilna. Dzēsiet dažus failus, lai atbrīvotu vietu."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Tālruņa atmiņa ir pilna! Dzēsiet dažus failus, lai atbrīvotu vietu."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Iespējams, tīklā veiktās darbības tiek pārraudzītas."</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Man"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Planšetdatora opcijas"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Tālruņa opcijas"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Ļauj lietotnei pārvietot uzdevumus priekšplānā un fonā. Lietotne var to izdarīt bez jūsu apstiprinājuma."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"apturēt izmantoto lietotņu darbību"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Ļauj lietotnei noņemt uzdevumus un pārtraukt to lietotņu darbību. Ļaunprātīgas lietotnes var traucēt citu lietotņu darbību."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"Darbību kaskāžu pārvaldība"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Ļauj lietotnei pievienot, noņemt un mainīt darbību kaskādes, kurās darbojas citas lietotnes. Ļaunprātīgas lietotnes var traucēt citu lietotņu darbību."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"jebkuras darbības sākšana"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Ļauj lietotnei sākt jebkuru darbību neatkarīgi no atļaujas aizsardzības vai eksportētā stāvokļa."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"Ekrāna saderības noteikšana"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Ļauj īpašniekam izveidot saiti ar ievades metodes augstākā līmeņa saskarni. Parastajām lietotnēm tas nekad nav nepieciešams."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"saistīt ar pieejamības pakalpojumu"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Ļauj īpašniekam izveidot saiti ar pieejamības pakalpojuma augšējā līmeņa saskarni. Parastajām lietotnēm šī atļauja nav nepieciešama."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"Savienojuma izveide ar drukāšanas pakalpojumu"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Ļauj īpašniekam izveidot savienojumu ar drukāšanas pakalpojuma augšējā līmeņa saskarni. Parastajām lietotnēm tas nekad nav nepieciešams."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"izveidot savienojumu ar drukas spolētāja pakalpojumu"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Ļauj īpašniekam izveidot savienojumu ar drukas spolētāja pakalpojuma augšējā līmeņa saskarni. Parastajām lietotnēm tas nekad nav nepieciešams."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"Saistīt ar TDLS pakalpojumu"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Ļauj īpašniekam saistīt lietojumprogrammas, kas emulē TDLS kartes. Parastajām lietotnēm šī atļauja nav nepieciešama."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"saistīt ar īsziņu pakalpojumu"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Ļauj īpašniekam veikt saistīšanu ar īsziņu pakalpojuma augstākā līmeņa saskarni (piem., SpellCheckerService). Parastajām lietotnēm tas nekad nav nepieciešams."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"saistīt ar VPN pakalpojumu"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Ļauj īpašniekam izveidot saiti ar logrīka pakalpojuma augšējā līmeņa saskarni. Parastajām lietotnēm tas nekad nav nepieciešams."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"mijiedarboties ar ierīces administratoru"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Ļauj īpašniekam nosūtīt informāciju par nodomiem ierīces administratoram. Parastajām lietotnēm tas nekad nav nepieciešams."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"pievienot vai noņemt ierīces administratoru"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Ļauj īpašniekam pievienot vai noņemt aktīvos ierīces administratorus. Nekad nav nepieciešama parastām lietotnēm."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"mainīt ekrāna orientāciju"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Ļauj lietotnei jebkurā laikā mainīt ekrāna pozīciju. Parastajām lietotnēm tas nekad nav nepieciešams."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"Rādītāja ātruma mainīšana"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Ļauj lietotnei lasīt informāciju no dažādiem sistēmas žurnālfailiem. Šādi lietotne var atrast vispārīgu informāciju par jūsu darbībām tālrunī, tostarp arī personas vai privātu informāciju."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"multivides failu atskaņošanai izmantot jebkuru dekodētāju"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Ļauj lietotnei izmantot jebkuru instalētu multivides failu dekodētāju, lai dekodētu failus atskaņošanai."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"Uzticamo akreditācijas datu pārvaldība"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Ļauj lietotnei instalēt un atinstalēt CA sertifikātus kā uzticamus akreditācijas datus."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"lasīt grupas “diag” resursus un rakstīt tajos"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Ļauj lietotnei lasīt un rakstīt jebkurā resursā, kas pieder diagnostikas grupai, piemēram, failiem mapē /dev. Tas var ietekmēt sistēmas stabilitāti un drošību. Var izmantot ražotājs vai operators TIKAI konkrētas aparatūras diagnostikai."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"iespējot vai atspējot lietotnes komponentus"</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Ļauj lietotnei konfigurēt Wi-Fi displejus un veidot savienojumu ar tiem."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wi-Fi displeju vadība"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Ļauj lietotnei kontrolēt zema līmeņa funkcijas Wi-Fi displejos."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"tvert audio izvadi"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Ļauj lietotnei tvert un novirzīt audio izvadi."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"tvert video izvadi"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Ļauj lietotnei tvert un novirzīt video izvadi."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"tvert drošu video izvadi"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Ļauj lietotnei tvert un novirzīt drošu video izvadi."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"mainīt audio iestatījumus"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Ļauj lietotnei mainīt globālos audio iestatījumus, piemēram, skaļumu un izejai izmantoto skaļruni."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"ierakstīt audio"</string>
@@ -525,6 +552,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"novērst tālruņa pāriešanu miega režīmā"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Ļauj lietotnei novērst planšetdatora pāriešanu miega režīmā."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Ļauj lietotnei novērst tālruņa pāriešanu miega režīmā."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"ieslēgt vai izslēgt planšetdatoru"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"ieslēgt vai izslēgt tālruni"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Ļauj lietotnei ieslēgt vai izslēgt planšetdatoru."</string>
@@ -613,6 +646,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Ļauj lietotnei rakstīt SD kartē."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"pārv./dz.datu n.iekš.atm.sat."</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Ļauj lietotnei modificēt datu nesēja iekšējās atmiņas saturu."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"Dokumentu krātuves pārvaldība"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Ļauj lietotnei pārvaldīt dokumentu krātuvi."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"piekļ. visu liet. ārējai krāt."</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Ļauj lietotnei piekļūt visu lietotāju ārējai krātuvei."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"piekļūt kešatmiņas failu sistēmai"</string>
@@ -625,10 +660,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Ļauj lietotnei pārvaldīt tīkla politikas un noteikt lietotnes kārtulas."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"Tīkla lietojuma uzskaites mainīšana"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Ļauj lietotnei mainīt to, kā tīkla lietojums tiek uzskaitīts saistībā ar lietotnēm. Atļauja neattiecas uz parastām lietotnēm."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"Ligzdu atzīmju izmaiņas"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Ļauj lietotnei mainīt maršrutēšanai paredzēto ligzdu atzīmes."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"piekļuve paziņojumiem"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Ļauj lietotnei izgūt, pārbaudīt un dzēst paziņojumus, tostarp lietotņu publicētos paziņojumus."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"saites izveidošana ar paziņojumu uztvērēja pakalpojumu"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Ļauj īpašniekam izveidot saiti ar paziņojumu uztvērēja pakalpojuma augšējā līmeņa saskarni. Parastajām lietotnēm tas nekad nav nepieciešams."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"Operatora nodrošinātas konfigurācijas lietotnes izsaukšana"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Ļauj īpašniekam izsaukt operatora nodrošināto konfigurācijas lietotni. Parastām lietotnēm tas nekad nav nepieciešams."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"iegūt informāciju par tīkla stāvokļa novērojumiem"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Ļauj lietojumprogrammai iegūt informāciju par tīkla stāvokļa novērojumiem. Parastām lietotnēm šī atļauja nekad nav nepieciešama."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Paroles kārtulu iestatīšana"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrolē ekrāna atbloķēšanas parolē atļautās rakstzīmes un garumu."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Ekrāna atbloķēšanas mēģinājumu pārraudzīšana"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +836,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Ievietojiet SIM karti."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Nav SIM kartes, vai arī to nevar nolasīt. Ievietojiet SIM karti."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Nelietojama SIM karte."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Jūsu SIM karte ir neatgriezeniski atspējota."\n"Sazinieties ar savu bezvadu pakalpojumu sniedzēju, lai iegūtu citu SIM karti."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Jūsu SIM karte ir neatgriezeniski atspējota.\nSazinieties ar savu bezvadu pakalpojumu sniedzēju, lai iegūtu citu SIM karti."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Iepriekšējā ieraksta poga"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Nākamā ieraksta poga"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Pārtraukšanas poga"</string>
@@ -808,11 +848,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Skatiet lietotāja rokasgrāmatu vai sazinieties ar klientu apkalpošanas dienestu."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM karte ir bloķēta."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Notiek SIM kartes atbloķēšana..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Atbloķēšanas kombinācija tika nepareizi uzzīmēta <xliff:g id="NUMBER_0">%d</xliff:g> reizes."\n\n"Mēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%d</xliff:g> sekundēm."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Jūs esat ievadījis nepareizu paroli <xliff:g id="NUMBER_0">%d</xliff:g> reizes."\n\n"Mēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%d</xliff:g> sekundēm."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Jūs esat ievadījis nepareizu PIN <xliff:g id="NUMBER_0">%d</xliff:g> reizes."\n\n"Mēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%d</xliff:g> sekundēm."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Atbloķēšanas kombinācija tika nepareizi uzzīmēta <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīgiem mēģinājumiem planšetdators būs jāatbloķē, izmantojot pierakstīšanos Google kontā."\n\n"Mēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%d</xliff:g> sekundēm."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Atbloķēšanas kombinācija tika nepareizi uzzīmēta <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīgiem mēģinājumiem tālrunis būs jāatbloķē, izmantojot pierakstīšanos Google kontā."\n\n"Mēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%d</xliff:g> sekundēm."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Atbloķēšanas kombinācija tika nepareizi uzzīmēta <xliff:g id="NUMBER_0">%d</xliff:g> reizes.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%d</xliff:g> sekundēm."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Jūs esat ievadījis nepareizu paroli <xliff:g id="NUMBER_0">%d</xliff:g> reizes.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%d</xliff:g> sekundēm."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Jūs esat ievadījis nepareizu PIN <xliff:g id="NUMBER_0">%d</xliff:g> reizes.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%d</xliff:g> sekundēm."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Atbloķēšanas kombinācija tika nepareizi uzzīmēta <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīgiem mēģinājumiem planšetdators būs jāatbloķē, izmantojot pierakstīšanos Google kontā.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%d</xliff:g> sekundēm."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Atbloķēšanas kombinācija tika nepareizi uzzīmēta <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīgiem mēģinājumiem tālrunis būs jāatbloķē, izmantojot pierakstīšanos Google kontā.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%d</xliff:g> sekundēm."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Jūs nepareizi veicāt planšetdatora atbloķēšanu <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīga(-iem) mēģinājuma(-iem) planšetdatorā tiks atiestatīti rūpnīcas noklusējuma iestatījumi, un lietotāja dati tiks zaudēti."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Jūs nepareizi veicāt tālruņa atbloķēšanu <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīga(-iem) mēģinājuma(-iem) tālrunī tiks atiestatīti rūpnīcas noklusējuma iestatījumi, un lietotāja dati tiks zaudēti."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Jūs nepareizi veicāt planšetdatora atbloķēšanu <xliff:g id="NUMBER">%d</xliff:g> reizes. Planšetdatorā tiks atiestatīti rūpnīcas noklusējuma iestatījumi."</string>
@@ -826,7 +866,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Parole"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Pierakstīties"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Lietotājvārds vai parole nav derīga."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Vai aizmirsāt lietotājvārdu vai paroli?"\n"Apmeklējiet vietni "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Vai aizmirsāt lietotājvārdu vai paroli?\nApmeklējiet vietni "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Notiek pārbaude..."</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Atbloķēt"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Skaņa ir ieslēgta"</string>
@@ -874,7 +914,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Navigācijas apstiprināšana"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Pamest šo lapu"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Palikt šajā lapā"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Vai tiešām vēlaties pamest šo lapu?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nVai tiešām vēlaties pamest šo lapu?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Apstiprināt"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Padoms. Divreiz pieskarieties, lai tuvinātu un tālinātu."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Automātiskā aizpilde"</string>
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"Diemžēl lietojumprogrammas <xliff:g id="APPLICATION">%1$s</xliff:g> darbība ir apturēta."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Diemžēl process <xliff:g id="PROCESS">%1$s</xliff:g> ir apturēts."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"Lietojumprogramma <xliff:g id="APPLICATION">%2$s</xliff:g> nereaģē."\n\n"Vai vēlaties to aizvērt?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Darbība <xliff:g id="ACTIVITY">%1$s</xliff:g> nereaģē."\n\n"Vai vēlaties to aizvērt?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"Lietojumprogramma <xliff:g id="APPLICATION">%2$s</xliff:g> nereaģē.\n\nVai vēlaties to aizvērt?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Darbība <xliff:g id="ACTIVITY">%1$s</xliff:g> nereaģē.\n\nVai vēlaties to aizvērt?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"Lietojumprogramma <xliff:g id="APPLICATION">%1$s</xliff:g> nereaģē. Vai vēlaties to aizvērt?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Process <xliff:g id="PROCESS">%1$s</xliff:g> nereaģē."\n\n"Vai vēlaties to aizvērt?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Process <xliff:g id="PROCESS">%1$s</xliff:g> nereaģē.\n\nVai vēlaties to aizvērt?"</string>
     <string name="force_close" msgid="8346072094521265605">"Labi"</string>
     <string name="report" msgid="4060218260984795706">"Pārskats"</string>
     <string name="wait" msgid="7147118217226317732">"Gaidīt"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"No lapas netiek saņemta atbilde."\n\n"Vai vēlaties to aizvērt?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"No lapas netiek saņemta atbilde.\n\nVai vēlaties to aizvērt?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Lietotne ir novirzīta"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> tagad darbojas."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"Sākotnēji tika palaista lietojumprogramma <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
@@ -1256,6 +1296,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Ļauj lietotnei izsaukt noklusējuma konteinera pakalpojumu, lai kopētu saturu. Atļauja neattiecas uz parastām lietotnēm."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Multivides datu izejas maršrutēšana"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Ļauj lietojumprogrammai maršrutēt multivides datu izeju uz citām ārējām ierīcēm."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Piekļūt krātuvei, kas aizsargāta ar atslēgu"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Ļauj lietojumprogrammai piekļūt krātuvei, kas aizsargāta ar atslēgu."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Pārvaldīt krātuves rādīšanu un paslēpšanu."</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Ļauj lietojumprogrammai pārvaldīt krātuvi."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Pieskarieties divreiz, lai kontrolētu tālummaiņu."</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Nevarēja pievienot logrīku."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Doties uz"</string>
@@ -1265,15 +1309,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Gatavs"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Iepr."</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Izpildīt"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Sastādiet numuru"\n"izmantojot <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Izveidot kontaktpersonu"\n"izmantojot šo numuru: <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Sastādiet numuru\nizmantojot <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Izveidot kontaktpersonu\nizmantojot šo numuru: <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Viena vai vairākas no tālāk minētajām lietotnēm pieprasa atļauju piekļūt jūsu kontam tagad un arī turpmāk."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Vai vēlaties atļaut šo pieprasījumu?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Piekļuves pieprasījums"</string>
     <string name="allow" msgid="7225948811296386551">"Atļaut"</string>
     <string name="deny" msgid="2081879885755434506">"Noraidīt"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Atļauja ir pieprasīta."</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Atļauja kontam <xliff:g id="ACCOUNT">%s</xliff:g>"\n"ir pieprasīta."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Atļauja kontam <xliff:g id="ACCOUNT">%s</xliff:g>\nir pieprasīta."</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Ievades metode"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Sinhronizācija"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Pieejamība"</string>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Skatīt visu"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Darbības izvēle"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Kopīgošana ar:"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Ierīce ir bloķēta."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Notiek sūtīšana…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Vai palaist pārlūkprogrammu?"</string>
@@ -1441,10 +1484,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Notiek savienojuma izveide..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Pieejams"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"Nav pieejams"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"Tiek lietots"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Iebūvēts ekrāns"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"HDMI ekrāns"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Pārklājums Nr. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", drošs"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Bezvadu attēlošanas savienojums ir izveidots."</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Šis ekrāns tiek rādīts citā ierīcē."</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Pārtraukt savienojumu"</string>
@@ -1453,7 +1498,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Nepareiza kombinācija"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Nepareiza parole"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"Nepareizs PIN"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Mēģiniet vēlreiz pēc <xliff:g id="NUMBER">%d</xliff:g> sekundēm."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Mēģiniet vēlreiz pēc <xliff:g id="NUMBER">%1$d</xliff:g> sekundēm."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Norādiet savu kombināciju"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Ievadiet SIM kartes PIN"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Ievadiet PIN"</string>
@@ -1473,27 +1518,85 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Parole"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Pierakstīties"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nederīgs lietotājvārds vai parole."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Vai aizmirsāt lietotājvārdu vai paroli?"\n"Apmeklējiet vietni "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Vai aizmirsāt lietotājvārdu vai paroli?\nApmeklējiet vietni "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Notiek konta pārbaude…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Jūs nepareizi ievadījāt PIN <xliff:g id="NUMBER_0">%d</xliff:g> reizes."\n\n"Mēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%d</xliff:g> sekundēm."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Jūs nepareizi ievadījāt paroli <xliff:g id="NUMBER_0">%d</xliff:g> reizes."\n\n"Mēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%d</xliff:g> sekundēm."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Jūs nepareizi norādījāt atbloķēšanas kombināciju <xliff:g id="NUMBER_0">%d</xliff:g> reizes."\n\n"Mēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%d</xliff:g> sekundēm."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Jūs nepareizi ievadījāt PIN <xliff:g id="NUMBER_0">%d</xliff:g> reizes.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%d</xliff:g> sekundēm."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Jūs nepareizi ievadījāt paroli <xliff:g id="NUMBER_0">%d</xliff:g> reizes.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%d</xliff:g> sekundēm."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Jūs nepareizi norādījāt atbloķēšanas kombināciju <xliff:g id="NUMBER_0">%d</xliff:g> reizes.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%d</xliff:g> sekundēm."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Jūs nepareizi veicāt planšetdatora atbloķēšanu <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīgiem mēģinājumiem planšetdatorā tiks atiestatīti rūpnīcas noklusējuma iestatījumi un lietotāja dati tiks zaudēti."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Jūs nepareizi veicāt tālruņa atbloķēšanu <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīgiem mēģinājumiem tālrunī tiks atiestatīti rūpnīcas noklusējuma iestatījumi un lietotāja dati tiks zaudēti."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Jūs nepareizi veicāt planšetdatora atbloķēšanu <xliff:g id="NUMBER">%d</xliff:g> reizes. Planšetdatorā tiks atiestatīti rūpnīcas noklusējuma iestatījumi."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Jūs nepareizi veicāt tālruņa atbloķēšanu <xliff:g id="NUMBER">%d</xliff:g> reizes. Tālrunī tiks atiestatīti rūpnīcas noklusējuma iestatījumi."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Jūs nepareizi norādījāt atbloķēšanas kombināciju <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīgiem mēģinājumiem planšetdators būs jāatbloķē, izmantojot e-pasta kontu."\n\n"Mēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%d</xliff:g> sekundēm."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Jūs nepareizi norādījāt atbloķēšanas kombināciju <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīgiem mēģinājumiem tālrunis būs jāatbloķē, izmantojot e-pasta kontu."\n\n"Mēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%d</xliff:g> sekundēm."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Jūs nepareizi norādījāt atbloķēšanas kombināciju <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīgiem mēģinājumiem planšetdators būs jāatbloķē, izmantojot e-pasta kontu.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%d</xliff:g> sekundēm."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Jūs nepareizi norādījāt atbloķēšanas kombināciju <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīgiem mēģinājumiem tālrunis būs jāatbloķē, izmantojot e-pasta kontu.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%d</xliff:g> sekundēm."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">"  — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Noņemt"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Vai palielināt skaļumu virs ieteicamā līmeņa?"\n"Ilgstoši klausoties skaņu lielā skaļumā, var tikt bojāta dzirde."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Vai palielināt skaļumu virs ieteicamā līmeņa?\nIlgstoši klausoties skaņu lielā skaļumā, var tikt bojāta dzirde."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Lai iespējotu pieejamību, turiet nospiestus divus pirkstus."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Pieejamības režīms ir iespējots."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Pieejamība ir atcelta."</string>
     <string name="user_switched" msgid="3768006783166984410">"Pašreizējais lietotājs: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Īpašnieks"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Kļūda"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Šajā lietojumprogrammā netiek atbalstīti ierobežotu profilu konti."</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Šajā lietotnē netiek atbalstīti ierobežotu profilu konti."</string>
     <string name="app_not_found" msgid="3429141853498927379">"Netika atrasta neviena lietojumprogramma, kas var veikt šo darbību."</string>
     <string name="revoke" msgid="5404479185228271586">"Atsaukt"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Atcelts"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Rakstot saturu, radās kļūda."</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"nezināms"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Administratora PIN ievadīšana"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Ievadiet PIN."</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Nepareizs"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Pašreizējais PIN"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Jaunais PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Apstipriniet jauno PIN."</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Izveidojiet PIN, lai mainītu ierobežojumus."</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"Ievadītie PIN neatbilst. Mēģiniet vēlreiz."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"PIN ir pārāk īss. Tam ir jābūt vismaz 4 ciparus garam."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Mēģ. vēl pēc 1 s"</item>
+    <item quantity="other" msgid="4730868920742952817">"Mēģ. vēl pēc <xliff:g id="COUNT">%d</xliff:g> s"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Vēlāk mēģiniet vēlreiz."</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Velciet no malas, lai atvērtu joslu"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Velciet no ekrāna malas, lai atvērtu sistēmas joslu."</string>
 </resources>
diff --git a/core/res/res/values-mcc202/config.xml b/core/res/res/values-mcc202/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc202/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc204-mnc04/config.xml b/core/res/res/values-mcc204-mnc04/config.xml
new file mode 100644
index 0000000..7a48342
--- /dev/null
+++ b/core/res/res/values-mcc204-mnc04/config.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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 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:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Configure mobile network MTU. Carrier specific value is set here.
+    -->
+    <integer name="config_mobile_mtu">1358</integer>
+
+</resources>
diff --git a/core/res/res/values-mcc204/config.xml b/core/res/res/values-mcc204/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc204/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc206/config.xml b/core/res/res/values-mcc206/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc206/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc208-mnc26/config.xml b/core/res/res/values-mcc208-mnc26/config.xml
new file mode 100644
index 0000000..31d2d0f
--- /dev/null
+++ b/core/res/res/values-mcc208-mnc26/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Don't use roaming icon for considered operators -->
+    <string-array translatable="false" name="config_operatorConsideredNonRoaming">
+        <item>20801</item>
+        <item>20810</item>
+    </string-array>
+</resources>
diff --git a/core/res/res/values-mcc208/config.xml b/core/res/res/values-mcc208/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc208/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc214-mnc04/config.xml b/core/res/res/values-mcc214-mnc04/config.xml
new file mode 100644
index 0000000..71301d5
--- /dev/null
+++ b/core/res/res/values-mcc214-mnc04/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Don't use roaming icon for considered operators -->
+    <string-array translatable="false" name="config_operatorConsideredNonRoaming">
+        <item>21407</item>
+    </string-array>
+</resources>
diff --git a/core/res/res/values-mcc214/config.xml b/core/res/res/values-mcc214/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc214/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc216/config.xml b/core/res/res/values-mcc216/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc216/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc219/config.xml b/core/res/res/values-mcc219/config.xml
index 7ae82fa..80f4e58 100644
--- a/core/res/res/values-mcc219/config.xml
+++ b/core/res/res/values-mcc219/config.xml
@@ -29,4 +29,7 @@
         <item>"96"</item>
     </string-array>
 
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
 </resources>
diff --git a/core/res/res/values-mcc222/config.xml b/core/res/res/values-mcc222/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc222/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc226/config.xml b/core/res/res/values-mcc226/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc226/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc228/config.xml b/core/res/res/values-mcc228/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc228/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc230/config.xml b/core/res/res/values-mcc230/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc230/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc231/config.xml b/core/res/res/values-mcc231/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc231/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc232/config.xml b/core/res/res/values-mcc232/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc232/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc234-mnc30/config.xml b/core/res/res/values-mcc234-mnc30/config.xml
new file mode 100644
index 0000000..eabdf9a
--- /dev/null
+++ b/core/res/res/values-mcc234-mnc30/config.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Don't use roaming icon for considered operators -->
+    <string-array translatable="false" name="config_operatorConsideredNonRoaming">
+        <item>23430</item>
+        <item>23431</item>
+        <item>23432</item>
+        <item>23433</item>
+        <item>23434</item>
+        <item>23486</item>
+    </string-array>
+</resources>
diff --git a/core/res/res/values-mcc234-mnc31/config.xml b/core/res/res/values-mcc234-mnc31/config.xml
new file mode 100644
index 0000000..eabdf9a
--- /dev/null
+++ b/core/res/res/values-mcc234-mnc31/config.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Don't use roaming icon for considered operators -->
+    <string-array translatable="false" name="config_operatorConsideredNonRoaming">
+        <item>23430</item>
+        <item>23431</item>
+        <item>23432</item>
+        <item>23433</item>
+        <item>23434</item>
+        <item>23486</item>
+    </string-array>
+</resources>
diff --git a/core/res/res/values-mcc234-mnc32/config.xml b/core/res/res/values-mcc234-mnc32/config.xml
new file mode 100644
index 0000000..eabdf9a
--- /dev/null
+++ b/core/res/res/values-mcc234-mnc32/config.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Don't use roaming icon for considered operators -->
+    <string-array translatable="false" name="config_operatorConsideredNonRoaming">
+        <item>23430</item>
+        <item>23431</item>
+        <item>23432</item>
+        <item>23433</item>
+        <item>23434</item>
+        <item>23486</item>
+    </string-array>
+</resources>
diff --git a/core/res/res/values-mcc234-mnc33/config.xml b/core/res/res/values-mcc234-mnc33/config.xml
index d79d212..175f76e 100644
--- a/core/res/res/values-mcc234-mnc33/config.xml
+++ b/core/res/res/values-mcc234-mnc33/config.xml
@@ -35,4 +35,14 @@
          "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
     <string translatable="false" name="config_tether_apndata">Consumer Broadband,consumerbroadband,,,,,,,,,234,33,,DUN</string>
+
+    <!-- Don't use roaming icon for considered operators -->
+    <string-array translatable="false" name="config_operatorConsideredNonRoaming">
+        <item>23430</item>
+        <item>23431</item>
+        <item>23432</item>
+        <item>23433</item>
+        <item>23434</item>
+        <item>23486</item>
+    </string-array>
 </resources>
diff --git a/core/res/res/values-mcc234-mnc34/config.xml b/core/res/res/values-mcc234-mnc34/config.xml
new file mode 100644
index 0000000..eabdf9a
--- /dev/null
+++ b/core/res/res/values-mcc234-mnc34/config.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Don't use roaming icon for considered operators -->
+    <string-array translatable="false" name="config_operatorConsideredNonRoaming">
+        <item>23430</item>
+        <item>23431</item>
+        <item>23432</item>
+        <item>23433</item>
+        <item>23434</item>
+        <item>23486</item>
+    </string-array>
+</resources>
diff --git a/core/res/res/values-mcc234-mnc86/config.xml b/core/res/res/values-mcc234-mnc86/config.xml
new file mode 100644
index 0000000..eabdf9a
--- /dev/null
+++ b/core/res/res/values-mcc234-mnc86/config.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Don't use roaming icon for considered operators -->
+    <string-array translatable="false" name="config_operatorConsideredNonRoaming">
+        <item>23430</item>
+        <item>23431</item>
+        <item>23432</item>
+        <item>23433</item>
+        <item>23434</item>
+        <item>23486</item>
+    </string-array>
+</resources>
diff --git a/core/res/res/values-mcc234/config.xml b/core/res/res/values-mcc234/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc234/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc238/config.xml b/core/res/res/values-mcc238/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc238/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc240/config.xml b/core/res/res/values-mcc240/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc240/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc242/config.xml b/core/res/res/values-mcc242/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc242/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc244/config.xml b/core/res/res/values-mcc244/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc244/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc246/config.xml b/core/res/res/values-mcc246/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc246/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc247/config.xml b/core/res/res/values-mcc247/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc247/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc248/config.xml b/core/res/res/values-mcc248/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc248/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc260/config.xml b/core/res/res/values-mcc260/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc260/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc262/config.xml b/core/res/res/values-mcc262/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc262/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc268/config.xml b/core/res/res/values-mcc268/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc268/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc270/config.xml b/core/res/res/values-mcc270/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc270/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc272/config.xml b/core/res/res/values-mcc272/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc272/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc274/config.xml b/core/res/res/values-mcc274/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc274/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc278/config.xml b/core/res/res/values-mcc278/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc278/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc280/config.xml b/core/res/res/values-mcc280/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc280/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc284/config.xml b/core/res/res/values-mcc284/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc284/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc286/config.xml b/core/res/res/values-mcc286/config.xml
index d99d051..f73a523 100644
--- a/core/res/res/values-mcc286/config.xml
+++ b/core/res/res/values-mcc286/config.xml
@@ -61,4 +61,7 @@
          to enable use of the new Release 9 tables for Indic languages. -->
     <!-- <integer-array name="config_sms_enabled_locking_shift_tables"></integer-array> -->
 
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
 </resources>
diff --git a/core/res/res/values-mcc293/config.xml b/core/res/res/values-mcc293/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc293/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc294/config.xml b/core/res/res/values-mcc294/config.xml
new file mode 100644
index 0000000..8d6d3b1
--- /dev/null
+++ b/core/res/res/values-mcc294/config.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Whether safe headphone volume is enabled or not (country specific). -->
+    <bool name="config_safe_media_volume_enabled">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc302-mnc370/config.xml b/core/res/res/values-mcc302-mnc370/config.xml
index 3d2ea75..4fb2232 100644
--- a/core/res/res/values-mcc302-mnc370/config.xml
+++ b/core/res/res/values-mcc302-mnc370/config.xml
@@ -36,4 +36,8 @@
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
     <string translatable="false" name="config_tether_apndata">Fido LTE Tethering,ltedata.apn,,,,,,,,,302,370,,DUN</string>
 
+    <!-- Configure mobile network MTU. Carrier specific value is set here.
+    -->
+    <integer name="config_mobile_mtu">1410</integer>
+
 </resources>
diff --git a/core/res/res/values-mcc302-mnc610/config.xml b/core/res/res/values-mcc302-mnc610/config.xml
new file mode 100644
index 0000000..638aa92
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc610/config.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Don't use roaming icon for considered operators -->
+    <string-array translatable="false" name="config_operatorConsideredNonRoaming">
+        <item>302</item>
+    </string-array>
+
+    <!-- Configure mobile network MTU. Carrier specific value is set here.
+    -->
+    <integer name="config_mobile_mtu">1358</integer>
+
+</resources>
diff --git a/core/res/res/values-mcc302-mnc640/config.xml b/core/res/res/values-mcc302-mnc640/config.xml
new file mode 100644
index 0000000..706570c
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc640/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Don't use roaming icon for considered operators -->
+    <string-array translatable="false" name="config_operatorConsideredNonRoaming">
+        <item>302</item>
+    </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc660/config.xml b/core/res/res/values-mcc302-mnc660/config.xml
index 37853cf..76f7968 100644
--- a/core/res/res/values-mcc302-mnc660/config.xml
+++ b/core/res/res/values-mcc302-mnc660/config.xml
@@ -35,4 +35,9 @@
          "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
     <string translatable="false" name="config_tether_apndata">MTS -Tethering,internet.mts,,,,,,,,,302,660,,DUN</string>
+
+    <!-- Configure mobile network MTU. Carrier specific value is set here.
+    -->
+    <integer name="config_mobile_mtu">1430</integer>
+
 </resources>
diff --git a/core/res/res/values-mcc302-mnc720/config.xml b/core/res/res/values-mcc302-mnc720/config.xml
index 680f1a3..4eceffc 100644
--- a/core/res/res/values-mcc302-mnc720/config.xml
+++ b/core/res/res/values-mcc302-mnc720/config.xml
@@ -36,4 +36,8 @@
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
     <string translatable="false" name="config_tether_apndata">Rogers LTE Tethering,ltedata.apn,,,,,,,,,302,720,,DUN</string>
 
+    <!-- Configure mobile network MTU. Carrier specific value is set here.
+    -->
+    <integer name="config_mobile_mtu">1430</integer>
+
 </resources>
diff --git a/core/res/res/values-mcc302-mnc780/config.xml b/core/res/res/values-mcc302-mnc780/config.xml
index 42d4956..cd40191 100644
--- a/core/res/res/values-mcc302-mnc780/config.xml
+++ b/core/res/res/values-mcc302-mnc780/config.xml
@@ -37,4 +37,13 @@
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
     <string translatable="false" name="config_tether_apndata">SaskTel Tethering,inet.stm.sk.ca,,,,,,,,,302,780,,DUN</string>
 
+    <!-- Don't use roaming icon for considered operators -->
+    <string-array translatable="false" name="config_operatorConsideredNonRoaming">
+        <item>302</item>
+    </string-array>
+
+    <!-- Configure mobile network MTU. Carrier specific value is set here.
+    -->
+    <integer name="config_mobile_mtu">1358</integer>
+
 </resources>
diff --git a/core/res/res/values-mcc310-mnc120/config.xml b/core/res/res/values-mcc310-mnc120/config.xml
new file mode 100644
index 0000000..62001d9
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc120/config.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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 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:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Configure mobile network MTU. Carrier specific value is set here.
+    -->
+    <integer name="config_mobile_mtu">1422</integer>
+
+</resources>
diff --git a/core/res/res/values-mcc310-mnc260/config.xml b/core/res/res/values-mcc310-mnc260/config.xml
index 56a5d4e..886ecbe 100644
--- a/core/res/res/values-mcc310-mnc260/config.xml
+++ b/core/res/res/values-mcc310-mnc260/config.xml
@@ -37,4 +37,8 @@
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
     <string translatable="false" name="config_tether_apndata">T-Mobile Tethering,pcweb.tmobile.com,,,,,,,,,310,260,,DUN</string>
 
+    <!-- Configure mobile network MTU. Carrier specific value is set here.
+    -->
+    <integer name="config_mobile_mtu">1440</integer>
+
 </resources>
diff --git a/core/res/res/values-mcc310-mnc410/config.xml b/core/res/res/values-mcc310-mnc410/config.xml
new file mode 100644
index 0000000..73aa1ce
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc410/config.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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 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:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Configure mobile network MTU. Carrier specific value is set here.
+    -->
+    <integer name="config_mobile_mtu">1410</integer>
+
+</resources>
diff --git a/core/res/res/values-mcc310/config.xml b/core/res/res/values-mcc310/config.xml
deleted file mode 100644
index df398f9..0000000
--- a/core/res/res/values-mcc310/config.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?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.
-*/
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-
-    <!-- Whether safe headphone volume is enabled or not (country specific). -->
-    <bool name="config_safe_media_volume_enabled">false</bool>
-
-</resources>
diff --git a/core/res/res/values-mcc311/config.xml b/core/res/res/values-mcc311/config.xml
deleted file mode 100644
index df398f9..0000000
--- a/core/res/res/values-mcc311/config.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?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.
-*/
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-
-    <!-- Whether safe headphone volume is enabled or not (country specific). -->
-    <bool name="config_safe_media_volume_enabled">false</bool>
-
-</resources>
diff --git a/core/res/res/values-mcc312/config.xml b/core/res/res/values-mcc312/config.xml
deleted file mode 100644
index df398f9..0000000
--- a/core/res/res/values-mcc312/config.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?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.
-*/
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-
-    <!-- Whether safe headphone volume is enabled or not (country specific). -->
-    <bool name="config_safe_media_volume_enabled">false</bool>
-
-</resources>
diff --git a/core/res/res/values-mcc313/config.xml b/core/res/res/values-mcc313/config.xml
deleted file mode 100644
index df398f9..0000000
--- a/core/res/res/values-mcc313/config.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?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.
-*/
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-
-    <!-- Whether safe headphone volume is enabled or not (country specific). -->
-    <bool name="config_safe_media_volume_enabled">false</bool>
-
-</resources>
diff --git a/core/res/res/values-mcc314/config.xml b/core/res/res/values-mcc314/config.xml
deleted file mode 100644
index df398f9..0000000
--- a/core/res/res/values-mcc314/config.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?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.
-*/
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-
-    <!-- Whether safe headphone volume is enabled or not (country specific). -->
-    <bool name="config_safe_media_volume_enabled">false</bool>
-
-</resources>
diff --git a/core/res/res/values-mcc315/config.xml b/core/res/res/values-mcc315/config.xml
deleted file mode 100644
index df398f9..0000000
--- a/core/res/res/values-mcc315/config.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?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.
-*/
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-
-    <!-- Whether safe headphone volume is enabled or not (country specific). -->
-    <bool name="config_safe_media_volume_enabled">false</bool>
-
-</resources>
diff --git a/core/res/res/values-mcc316/config.xml b/core/res/res/values-mcc316/config.xml
deleted file mode 100644
index df398f9..0000000
--- a/core/res/res/values-mcc316/config.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?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.
-*/
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-
-    <!-- Whether safe headphone volume is enabled or not (country specific). -->
-    <bool name="config_safe_media_volume_enabled">false</bool>
-
-</resources>
diff --git a/core/res/res/values-mcc425-mnc07/config.xml b/core/res/res/values-mcc425-mnc07/config.xml
index 890420e..51a9934 100644
--- a/core/res/res/values-mcc425-mnc07/config.xml
+++ b/core/res/res/values-mcc425-mnc07/config.xml
@@ -37,4 +37,8 @@
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
     <string translatable="false" name="config_tether_apndata">PC HOT mobile,pc.hotm,,,,,,,,,425,07,,DUN</string>
 
+    <!-- Don't use roaming icon for considered operators -->
+    <string-array translatable="false" name="config_operatorConsideredNonRoaming">
+        <item>42503</item>
+    </string-array>
 </resources>
diff --git a/core/res/res/values-mcc425-mnc08/config.xml b/core/res/res/values-mcc425-mnc08/config.xml
new file mode 100644
index 0000000..8470b86
--- /dev/null
+++ b/core/res/res/values-mcc425-mnc08/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Don't use roaming icon for considered operators -->
+    <string-array translatable="false" name="config_operatorConsideredNonRoaming">
+        <item>42502</item>
+    </string-array>
+</resources>
diff --git a/core/res/res/values-mcc440-mnc20/config.xml b/core/res/res/values-mcc440-mnc20/config.xml
new file mode 100644
index 0000000..ba709fa
--- /dev/null
+++ b/core/res/res/values-mcc440-mnc20/config.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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 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:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Configure mobile network MTU. Carrier specific value is set here.
+    -->
+    <integer name="config_mobile_mtu">1340</integer>
+
+</resources>
diff --git a/core/res/res/values-mcc440-mnc50/config.xml b/core/res/res/values-mcc440-mnc50/config.xml
new file mode 100644
index 0000000..fa5cba4
--- /dev/null
+++ b/core/res/res/values-mcc440-mnc50/config.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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 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:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Configure mobile network MTU. Carrier specific value is set here.
+    -->
+    <integer name="config_mobile_mtu">1420</integer>
+
+</resources>
diff --git a/core/res/res/values-mcc440-mnc54/config.xml b/core/res/res/values-mcc440-mnc54/config.xml
new file mode 100644
index 0000000..fa5cba4
--- /dev/null
+++ b/core/res/res/values-mcc440-mnc54/config.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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 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:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Configure mobile network MTU. Carrier specific value is set here.
+    -->
+    <integer name="config_mobile_mtu">1420</integer>
+
+</resources>
diff --git a/core/res/res/values-mcc450-mnc05/config.xml b/core/res/res/values-mcc450-mnc05/config.xml
new file mode 100644
index 0000000..d602c9f
--- /dev/null
+++ b/core/res/res/values-mcc450-mnc05/config.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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 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:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Configure mobile network MTU. Carrier specific value is set here.
+    -->
+    <integer name="config_mobile_mtu">1440</integer>
+
+</resources>
diff --git a/core/res/res/values-mcc450-mnc06/config.xml b/core/res/res/values-mcc450-mnc06/config.xml
new file mode 100644
index 0000000..63f9823
--- /dev/null
+++ b/core/res/res/values-mcc450-mnc06/config.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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 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:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Configure mobile network MTU. Carrier specific value is set here.
+    -->
+    <integer name="config_mobile_mtu">1428</integer>
+
+</resources>
diff --git a/core/res/res/values-mcc450-mnc08/config.xml b/core/res/res/values-mcc450-mnc08/config.xml
new file mode 100644
index 0000000..950c62b
--- /dev/null
+++ b/core/res/res/values-mcc450-mnc08/config.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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 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:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Configure mobile network MTU. Carrier specific value is set here.
+    -->
+    <integer name="config_mobile_mtu">1450</integer>
+
+</resources>
diff --git a/core/res/res/values-mcc505-mnc01/config.xml b/core/res/res/values-mcc505-mnc01/config.xml
index f9d9ac7..7331c50 100644
--- a/core/res/res/values-mcc505-mnc01/config.xml
+++ b/core/res/res/values-mcc505-mnc01/config.xml
@@ -37,4 +37,8 @@
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
     <string translatable="false" name="config_tether_apndata">Telstra Tethering,telstra.internet,,,,,,,,,505,01,,DUN</string>
 
+    <!-- Configure mobile network MTU. Carrier specific value is set here.
+    -->
+    <integer name="config_mobile_mtu">1400</integer>
+
 </resources>
diff --git a/core/res/res/values-mcc510-mnc21/config.xml b/core/res/res/values-mcc510-mnc21/config.xml
new file mode 100644
index 0000000..1fd9dfa
--- /dev/null
+++ b/core/res/res/values-mcc510-mnc21/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Don't use roaming icon for considered operators -->
+    <string-array translatable="false" name="config_operatorConsideredNonRoaming">
+        <item>51001</item>
+    </string-array>
+</resources>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
new file mode 100644
index 0000000..e50854d
--- /dev/null
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -0,0 +1,1602 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<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="5973789783504771878">"КБ"</string>
+    <string name="megabyteShort" msgid="6355851576770428922">"МБ"</string>
+    <string name="gigabyteShort" msgid="3259882455212193214">"ГБ"</string>
+    <string name="terabyteShort" msgid="231613018159186962">"TБ"</string>
+    <string name="petabyteShort" msgid="5637816680144990219">"ПБ"</string>
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
+    <string name="untitled" msgid="4638956954852782576">"&lt;Гарчиггүй&gt;"</string>
+    <string name="ellipsis" msgid="7899829516048813237">"…"</string>
+    <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
+    <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Утасны дугаар байхгүй)"</string>
+    <string name="unknownName" msgid="2277556546742746522">"(Тодорхойгүй)"</string>
+    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"дуут шуудан"</string>
+    <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
+    <string name="mmiError" msgid="5154499457739052907">"Холболтын асуудал эсвэл буруу MMI код."</string>
+    <string name="mmiFdnError" msgid="5224398216385316471">"Ажиллагаа зөвөх тогтсон дугаараар хязгаарлагдсан."</string>
+    <string name="serviceEnabled" msgid="8147278346414714315">"Үйлчилгээ идэвхжсэн."</string>
+    <string name="serviceEnabledFor" msgid="6856228140453471041">"Дараах үйлчилгээ идэвхтэй болсон:"</string>
+    <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="mmiComplete" msgid="8232527495411698359">"MMI дууссан."</string>
+    <string name="badPin" msgid="9015277645546710014">"Таны бичсэн хуучин PIN буруу байна."</string>
+    <string name="badPuk" msgid="5487257647081132201">"Таны бичсэн PUК буруу байна."</string>
+    <string name="mismatchPin" msgid="609379054496863419">"Таны оруулсан PIN таарахгүй байна."</string>
+    <string name="invalidPin" msgid="3850018445187475377">"4-8 тооноос бүтэх PIN-г бичнэ үү."</string>
+    <string name="invalidPuk" msgid="8761456210898036513">"8-с цөөнгүй тооноос бүтэх PUK-г бичнэ үү."</string>
+    <string name="needPuk" msgid="919668385956251611">"SIM картны PUK-түгжигдсэн. Тайлах бол PUK кодыг бичнэ үү."</string>
+    <string name="needPuk2" msgid="4526033371987193070">"SIM картын хаалтыг болиулах бол PUK2-г бичнэ үү."</string>
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
+    <string name="ClipMmi" msgid="6952821216480289285">"Дуудлага хийгчийн ID"</string>
+    <string name="ClirMmi" msgid="7784673673446833091">"Гарч байгаа дуудлага хийгчийн ID"</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">"PIN солих"</string>
+    <string name="CnipMmi" msgid="3110534680557857162">"Дуудсан дугаар харуулах"</string>
+    <string name="CnirMmi" msgid="3062102121430548731">"Дуудлага хийгчийн дугаар хязгаарлагдсан"</string>
+    <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="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="RestrictedChangedTitle" msgid="5592189398956187498">"Хязгаарлагдсан хандалт өөрчлөгдөв"</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="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>
+    <string name="serviceClassDataSync" msgid="7530000519646054776">"Синк"</string>
+    <string name="serviceClassPacket" msgid="6991006557993423453">"Пакет"</string>
+    <string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
+    <string name="roamingText0" msgid="7170335472198694945">"Роуминг заагч ассан"</string>
+    <string name="roamingText1" msgid="5314861519752538922">"Роуминг заагч унтарсан"</string>
+    <string name="roamingText2" msgid="8969929049081268115">"Роуминг заагч анивчиж байна"</string>
+    <string name="roamingText3" msgid="5148255027043943317">"Хөрш дотор"</string>
+    <string name="roamingText4" msgid="8808456682550796530">"Барилгын гадна"</string>
+    <string name="roamingText5" msgid="7604063252850354350">"Роуминг - Сонгогдсон Систем"</string>
+    <string name="roamingText6" msgid="2059440825782871513">"Роуминг- Боломжтой Систем"</string>
+    <string name="roamingText7" msgid="7112078724097233605">"Роуминг- Холбоотон Түнш"</string>
+    <string name="roamingText8" msgid="5989569778604089291">"Роуминг- Урамшууллын Түнш"</string>
+    <string name="roamingText9" msgid="7969296811355152491">"Рүүминг - Үйлчилгээний Ажиллагаа Бүрэн"</string>
+    <string name="roamingText10" msgid="3992906999815316417">"Рүүминг - Хэсэгчилсэн үйлчилгээний функционал"</string>
+    <string name="roamingText11" msgid="4154476854426920970">"Рүүминг Баннер Асаалттай"</string>
+    <string name="roamingText12" msgid="1189071119992726320">"Баннергүй рүүминг"</string>
+    <string name="roamingTextSearching" msgid="8360141885972279963">"Үйлчилгээг хайж байна…"</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="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="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="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="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="default" msgid="3475999286680000541">"Утасны сан дүүрсэн. Зай чөлөөлөх бол зарим файлыг устгана уу."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Сүлжээ хянагдаж байж болзошгүй"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
+    <string name="me" msgid="6545696007631404292">"Би"</string>
+    <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Таблетын сонголтууд"</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="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="shutdown_progress" msgid="2281079257329981203">"Унтрааж байна…"</string>
+    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Таны таблет унтрах болно."</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="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_bug_report" msgid="7934010578922304799">"Алдаа мэдээллэх"</string>
+    <string name="bugreport_title" msgid="2667494803742548533">"Согог репорт авах"</string>
+    <string name="bugreport_message" msgid="398447048750350456">"Энэ таны төхөөрөмжийн одоогийн статусын талаарх мэдээллийг цуглуулах ба имэйл мессеж болгон илгээнэ. Алдааны мэдэгдлээс эхэлж илгээхэд бэлэн болоход хэсэг хугацаа зарцуулагдана тэвчээртэй байна уу."</string>
+    <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_airplane_mode_on_status" msgid="2719557982608919750">"Нислэгийн горим асав"</string>
+    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Нислэгийн горим унтарсан"</string>
+    <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
+    <string name="safeMode" msgid="2788228061547930246">"Аюулгүй горим"</string>
+    <string name="android_system_label" msgid="6577375335728551336">"Андройд систем"</string>
+    <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Танаас төлбөр авдаг үйлчилгээнүүд"</string>
+    <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Таны төлбөрт оруулах зүйлийг хийх."</string>
+    <string name="permgrouplab_messages" msgid="7521249148445456662">"Таны мессеж"</string>
+    <string name="permgroupdesc_messages" msgid="7821999071003699236">"Таны SMS, и-мэйл ба бусад мессежийг унших болон бичих."</string>
+    <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Таны хувийн мэдээлэл"</string>
+    <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"Таны харилцагчдын картанд хадгалагдсан таны мэдээлэлд шууд хандах."</string>
+    <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Таны нийтийн мэдээлэл"</string>
+    <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Таны харилцагчид болон нийтийн холбооны тухай мэдээлэлд шууд хандах."</string>
+    <string name="permgrouplab_location" msgid="635149742436692049">"Таны байршил"</string>
+    <string name="permgroupdesc_location" msgid="5704679763124170100">"Таны бодит байршлыг хянах."</string>
+    <string name="permgrouplab_network" msgid="5808983377727109831">"Сүлжээний холбоо"</string>
+    <string name="permgroupdesc_network" msgid="4478299413241861987">"Төрөл бүрийн сүлжээний функцүүдэд хандах"</string>
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"Блютүүт"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"Блютүүтээр төхөөрөмж болон сүлжээнд хандах."</string>
+    <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"Аудио тохиргоо"</string>
+    <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"Аудио тохиргоо солих."</string>
+    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Батерейд нөлөөлөх"</string>
+    <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Батерей хурдан дуусгах функцийг ашиглах."</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"Календарь"</string>
+    <string name="permgroupdesc_calendar" msgid="5777534316982184416">"Календар болон үйл явдалд шууд хандах."</string>
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"Хэрэглэгчийн толиос унших"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"Хэрэглэгчийн толь бичгээс үг унших."</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"Хэрэглэгчийн тольд бичих"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"Хэрэглэгчийн толь бичигт үг нэмэх."</string>
+    <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Хавчуурга болон түүх"</string>
+    <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Хавчуурга болон хөтчийн түүхрүү шууд хандах."</string>
+    <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"Сэрүүлэг"</string>
+    <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"Сэрүүлэг тохируулах."</string>
+    <string name="permgrouplab_voicemail" msgid="4162237145027592133">"Дуут шуудан"</string>
+    <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"Дуут шууданд шууд хандах."</string>
+    <string name="permgrouplab_microphone" msgid="171539900250043464">"Микрофон"</string>
+    <string name="permgroupdesc_microphone" msgid="7106618286905738408">"Аудио бичихийн тулд микрофонд шууд хандах."</string>
+    <string name="permgrouplab_camera" msgid="4820372495894586615">"Камер"</string>
+    <string name="permgroupdesc_camera" msgid="2933667372289567714">"Зураг эвсэл бичлэг хийхээр камерт шууд хандах."</string>
+    <string name="permgrouplab_screenlock" msgid="8275500173330718168">"Дэлгэц түгжих"</string>
+    <string name="permgroupdesc_screenlock" msgid="7067497128925499401">"Таны төхөөрөмжийн дэлгэцийн түгжээнд нөлөөлөх чадвар."</string>
+    <string name="permgrouplab_appInfo" msgid="8028789762634147725">"Таны аппликешны мэдээлэл"</string>
+    <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"Таны төхөөрөмжийн бусад аппликешнд нөлөөлөх чадвар."</string>
+    <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"Ханын зураг"</string>
+    <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"Төхөөрөмжийн ханын зургийн тохиргоог солих."</string>
+    <string name="permgrouplab_systemClock" msgid="406535759236612992">"Цаг"</string>
+    <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"Төхөөрөмжийн цаг эсвэл цагийн бүсийг солих."</string>
+    <string name="permgrouplab_statusBar" msgid="2095862568113945398">"Статус самбар"</string>
+    <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"Төхөөрөмжийн статус самбарын тохиргоог солих."</string>
+    <string name="permgrouplab_syncSettings" msgid="3341990986147826541">"Синк тохиргоо"</string>
+    <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"Синк тохиргоонд хандах."</string>
+    <string name="permgrouplab_accounts" msgid="3359646291125325519">"Таны акаунт"</string>
+    <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Боломжит акаунтад хандах."</string>
+    <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Хардвер контрол"</string>
+    <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Гар төхөөрөмжийн хардверт шууд хандах."</string>
+    <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Утсаар ярих"</string>
+    <string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"Утасны дуудлагыг хянах, бичих болон боловсруулах."</string>
+    <string name="permgrouplab_systemTools" msgid="4652191644082714048">"Системийн багаж"</string>
+    <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"Системрүү доод төвшиний хандах болон удирдах."</string>
+    <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"Хөгжүүлэх багаж"</string>
+    <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"Зөвхөн аппликешн хөгжүүлэгчдэд хэрэгтэй функц."</string>
+    <string name="permgrouplab_display" msgid="4279909676036402636">"Бусад аппликешн UI"</string>
+    <string name="permgroupdesc_display" msgid="6051002031933013714">"Бусад аппликешны UI-д нөлөөлөх."</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"Сан"</string>
+    <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"USB санд хандах."</string>
+    <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"SD картад хандах."</string>
+    <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"Хялбар хандах функц"</string>
+    <string name="permgroupdesc_accessibilityFeatures" msgid="4205196881678144335">"Туслах технологиос хүсэлт илгээх боломжтой функц"</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="5800552516779249356">"Хүрсэн зүйлсийг чангаар дуудах ба дохио ашиглан дэлгэцийг таньж болно."</string>
+    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Сайжруулсан веб хандалтыг асаах"</string>
+    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Апп контентод илүү хялбар хандуулахын тулд скриптыг суулгана."</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Бичсэн текстээ ажиглах"</string>
+    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Кредит картын дугаар болон нууц үг зэрэг хувийн датаг агуулж байна."</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"статус самбарыг идэвхгүй болгох болон өөрчлөх"</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"Апп нь статус самбарыг идэвхгүй болгох эсвэл систем дүрсийг нэмэх, хасах боломжтой."</string>
+    <string name="permlab_statusBarService" msgid="7247281911387931485">"статус самбар"</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_processOutgoingCalls" msgid="3906007831192990946">"гарсан дуудлагыг чиглэлийг өөрчлөх"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Апп нь дуудлага хийх болон залгаж байгаа дугаарыг өөрчлөх боломжтой. Энэ зөвшөөрөл нь апп-г залгасан дуудлагыг хаах, хянах болон дахин чиглүүлэх боломжтой болгодог."</string>
+    <string name="permlab_receiveSms" msgid="8673471768947895082">"текст мессеж(SMS) хүлээж авах"</string>
+    <string name="permdesc_receiveSms" msgid="6424387754228766939">"Апп нь SMS мессежийг хүлээн авах болон гүйцэтгэх боломжтой. Ингэснээр апп нь таны төхөөрөмжрүү илгээсэн мессежийг танд үзүүлэхгүйгээр хянах болон устгаж чадна."</string>
+    <string name="permlab_receiveMms" msgid="1821317344668257098">"текст мессеж(МMS) хүлээж авах"</string>
+    <string name="permdesc_receiveMms" msgid="533019437263212260">"Апп нь MMS мессежийг хүлээн авах болон гүйцэтгэх боломжтой. Ингэснээр апп нь таны төхөөрөмжрүү илгээсэн мессежийг танд үзүүлэхгүйгээр хянах болон устгаж чадна."</string>
+    <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"Яаралтай өргөн дамжууллыг хүлээн авах"</string>
+    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Апп нь яаралтай өргөн дамжууллын мессежийг хүлээн авах болон гүйцэтгэх боломжтой. Энэ зөвшөөрөл нь зөвхөн систем аппликешнд л боломжтой."</string>
+    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"үүрэн өргөн дамжууллын мессеж унших"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Апп нь таны төхөөрөмжийн хүлээн авсан үүрэн өргөн дамжуулах мессежийг унших боломжтой. Үүрэн өргөн дамжууллын мэдэгдэл нь яаралтай нөхцөл байдлыг анхааруулах зорилгоор зарим байршлуудад хүрдэг. Хортой апп нь яаралтай үүрэн өргөн дамжууллыг хүлээн авсан үед таны төхөөрөмжийн ажиллагаа болон чадамжид нөлөөлөх боломжтой."</string>
+    <string name="permlab_sendSms" msgid="5600830612147671529">"SMS мессеж илгээх"</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"Апп нь SMS мессеж илгээх боломжтой. Энэ нь санаандгүй төлбөрт оруулж болзошгүй. Хортой апп нь таны зөвшөөрөлгүйгээр мессеж илгээн таныг төлбөрт оруулж болзошгүй."</string>
+    <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"мессежээр хариулах үйл явдалыг илгээх"</string>
+    <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"Апп нь дуудлага ирэх үед мессежээр хариу өгөх үйл явдлыг зохицуулахын тулд бусад мессежийн апп-д хүсэлт илгээх боломжтой."</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"таны текст мессежийг унших(SMS эсвэл MMS)"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Апп нь таны утас эсвэл SIM картанд хадгалагдсан SMS мессежийг унших боломжтой. Энэ нь апп-д бүх мессежийг контент эсвэл нууц эсэхээс нь үл хамааран унших боломжийг олгоно."</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Апп нь таны утас эсвэл SIM картанд хадгалагдсан SMS мессежийг унших боломжтой. Энэ нь апп-д бүх мессежийг контент эсвэл нууц эсэхээс нь үл хамааран унших боломжийг олгоно."</string>
+    <string name="permlab_writeSms" msgid="3216950472636214774">"Текст мессежийг засах (SMS эсвэл MMS)"</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Апп нь таны таблет эсвэл SIM картанд хадгалагдсан SMS мессежрүү бичих боломжтой. Хортой апп нь таны мессежүүдийг устгах боломжтой."</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Апп нь таны утас эсвэл SIM картанд хадгалагдсан 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_interactAcrossUsers" msgid="7114255281944211682">"хэрэглэгчидтэй харилцан үйлчлэлцэх"</string>
+    <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Апп нь төхөөрөмж дээрх ялгаатай хэрэглэгчдэд үйлдэл гүйцэтгэх боломжтой. Хортой апп нь энийг ашиглан хэрэглэгч хоорондын хамгаалалтыг зөрчих боломжтой."</string>
+    <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"хэрэглэгчидтэй харилцан үйлчлэлцэх бүрэн зөвшөөрөл"</string>
+    <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Бүх хэрэглэгчдэд боломжит бүх харилцан үйлдлийг зөвшөөрнө."</string>
+    <string name="permlab_manageUsers" msgid="1676150911672282428">"хэрэгчлэгч удирдах"</string>
+    <string name="permdesc_manageUsers" msgid="8409306667645355638">"Апп нь төхөөрөмж дээр асуулга, үүсгэлт болон устгалт зэргийг багтаасан хэрэглэгч удирдах боломжтой."</string>
+    <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"ажиллаж байгаа апп-н дэлгэрэнгүйг авах"</string>
+    <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Апп нь одоо ажиллаж байгаа болон сүүлд ажилласан даалгаврын талаарх дэлгэрэнгүй мэдээллийг авах боломжтой. Хортой апп нь бусад апп-н хувийн мэдээлийг олох боломжтой."</string>
+    <string name="permlab_reorderTasks" msgid="2018575526934422779">"ажиллаж байгаа апп-уудыг дахин эрэмбэлэх"</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Апп нь даалгавруудыг нүүрлүү болон арлуу зөөх боломжтой. Апп нь энийг таны оролцоогүйгээр хийж болзошгүй"</string>
+    <string name="permlab_removeTasks" msgid="6821513401870377403">"ажиллаж байгаа апп-г зогсоох"</string>
+    <string name="permdesc_removeTasks" msgid="1394714352062635493">"Апп нь даалгаврууд устгах болон тэдгээрийн апп-г зогсоох боломжтой. Хортой апп нь бусад апп-н ажиллагааг тасалдуулж болзошгүй."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"идэвхжилтийн стекүүдийг удирдах"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Апп-д бусад апп-уудын ажилладаг идэвхжилтийн стекүүдийг нэмэх, хасах буюу өөрчлөх боломж олгоно. Хорлонтой апп-ууд бусад апп-уудын авирт нөлөөлөх боломжтой."</string>
+    <string name="permlab_startAnyActivity" msgid="2918768238045206456">"ямарч активитиг эхлүүлэх"</string>
+    <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Апп нь зөвшөөрөл хамгаалалтай эсвэл экспорт хийсэн статусаас үл хамааран ямарч активитиг эхлүүлэх боломжтой."</string>
+    <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"дэлгэцний зохицолыг тохируулах"</string>
+    <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Апп нь бусад аппликешны дэлгэцний тохиромжит горимыг удирдах боломжтой.  Хортой аппликешн нь бусад аппликешны чадамжийг эвдэх боломжтой."</string>
+    <string name="permlab_setDebugApp" msgid="3022107198686584052">"апп дебагыг идэвхжүүлэх"</string>
+    <string name="permdesc_setDebugApp" msgid="4474512416299013256">"Апп нь бусад апп-г дебаг хийхийг асаах боломжтой. Хортой апп нь энийг ашиглан бусад апп-г зогсоох боломжтой."</string>
+    <string name="permlab_changeConfiguration" msgid="4162092185124234480">"системийн дэлгэцний тохиргоог солих"</string>
+    <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"Апп нь нутагшил эсвэл фонтын хэмжээ зэрэг одоогийн тохиргоог солих боломжтой."</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_forceStopPackages" msgid="2329627428832067700">"бусад апп-г хүчээр зогсоох"</string>
+    <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"Апп нь бусад апп-г хүчээр зогсоох боломжтой."</string>
+    <string name="permlab_forceBack" msgid="652935204072584616">"апп-г хүчээр унтраах"</string>
+    <string name="permdesc_forceBack" msgid="3892295830419513623">"Апп нь нүүрэнд ажиллаж байгаа активитиг хүчээр зогсоох болгон арлуу явуулах боломжтой. Энгийн апп-д хэрэглэхгүй."</string>
+    <string name="permlab_dump" msgid="1681799862438954752">"системийн дотоод статусыг дуудах"</string>
+    <string name="permdesc_dump" msgid="1778299088692290329">"Апп нь системийн дотоод статусыг дуудах боломжтой. Хортой апп нь энийг ашиглах шаардлагагүй аюулгүй байдлын болон хувийн мэдээллийг дуудах боломжтой."</string>
+    <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"Дэлгэцийн контентыг унших"</string>
+    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Апп нь идэвхтэй цонхны контентыг авах боломжтой. Хортой апп нь цонхны контентыг бүхэлд авах болон нууц үгнээс бусад бүх текстийг шалгаж болзошгүй"</string>
+    <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"Хялбар байдлыг түр идэвхтэй болгох"</string>
+    <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"Аппликешн нь төхөөрөмжийн хялбар байдлыг түр зуур идэвхжүүлэх боломжтой. Хортой апп нь хэрэглэгчийн зөвшөөрөлгүйгээр хялбар байдлыг идэвхжүүлж болзошгүй."</string>
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"цонхны мэдээллийг унших"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Аппликешн нь цонхны менежерээс цонхны талаар мэдээллийг дуудах боломжтой. Хортой апп нь дотоод системийн хэрэглээнд зориулагдсан мэдээллийг дуудаж болзошгүй."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"үйл явдлыг шүүх"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Аппликешн нь хэрэглэгчийн бүх үйл явдалын илгээгдэхээс өмнөх урсгалыг шүүж байгаа оролтын шүүлтйиг бүртгэх боломжтой. Хортой апп нь хэрэглэгчийн интервэшнгүйгээр системийн UI-г удирдах боломжтой."</string>
+    <string name="permlab_magnify_display" msgid="5973626738170618775">"дэлгэц томруулах"</string>
+    <string name="permdesc_magnify_display" msgid="7121235684515003792">"Аппликешн нь дэлгэцний контентийг өсгөх боломжтой. Хортой апп нь дэлгэцийн контентыг төхөөрөмжнөөс ашиглаж болохгүй болгон хувиргах боломжтой."</string>
+    <string name="permlab_shutdown" msgid="7185747824038909016">"хэсэгчилсэн унтраалт"</string>
+    <string name="permdesc_shutdown" msgid="7046500838746291775">"Активити менежерийг унтраана. Бүрэн унтраалтыг хийхгүй."</string>
+    <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"апп шилжүүлэхийг хориглох"</string>
+    <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Хэрэглэгч бусад апп-руу сэлгэхийг хориглох."</string>
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"одоогийн апп-н мэдээллийг авах"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Эзэмшигч нь дэлгэцний нүүрэнд байгаа одоогийн аппликешны талаарх хувийн мэдээллийг унших боломжтой."</string>
+    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"бүх апп-ын эхлэлийг хянах болон удирдах"</string>
+    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Апп нь систем активитиг яаж эхлүүлж байгааг хянах болон удирдан боломжтой. Хортой апп нь системд бүрэн нөлөөлж болзошгүй. Энэ эрх нь зөвхөн хөгжүүлэлтийн үед л хэрэгтэй ба энгийн хэрэглээнд огт хэрэггүй."</string>
+    <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"багц хасагдсан өргөн дамжууллыг илгээх"</string>
+    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"Апп нь апп багц устгагдсан талаарх мэдэгдлийг өргөн дамжуулах боломжтой. Хортой апп энийг ашиглан бусад ажиллаж байгаа апп-г зогсоох боломжтой."</string>
+    <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"SMS-хүлээн авав өргөн дамжууллыг илгээх"</string>
+    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"Апп нь SMS мессеж хүлээн авсан талаарх мэдэгдлийг өргөн дамжуулах боломжтой. Хортой апп энийг ашиглан ирсэн SMS мессежийг хуурамчаар хийх боломжтой."</string>
+    <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"WAP-PUSH-хүлээн авав өргөн дамжууллыг илгээх"</string>
+    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"Аппликешн нь WAP PUSH мессеж хүлээж авсан мэдэгдлийг өргөн дамжуулах боломжтой. Хортой апп нь энийг ашиглан MMS мессеж хүлээн авсан гэж хуурамчаар мэдэгдэх эсвэл хортой хувьсагч агуулсан веб хуудасны контентыг чимээгүй орлуулах боломжтой."</string>
+    <string name="permlab_setProcessLimit" msgid="2451873664363662666">"ажиллаж байгаа процессийн тоог хязгаарлах"</string>
+    <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"Апп нь нэг зэрэг ажиллах процессийн тооны дээд утгыг удирдах боломжтой. Энгийн апп-д хэзээ ч ашиглагдахгүй."</string>
+    <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"арын апп-г хүчээр хаах"</string>
+    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"Апп нь активитинүүд арын болонгуутаа дуусах эсэхийг удирдах боломжтой. Энгийн апп-д хэрэглэгдэхгүй."</string>
+    <string name="permlab_batteryStats" msgid="2789610673514103364">"батерейны статистикийг унших"</string>
+    <string name="permdesc_batteryStats" msgid="5897346582882915114">"Аппликешн нь батерей хэрэглээний доод-төвшиний одоогийн датаг унших боломжтой. Аппликешнд таны ашиглаж байгаа апп-н талаарх дэлгэрэнгүй мэдээллийг олох боломжийг олгоно."</string>
+    <string name="permlab_updateBatteryStats" msgid="3719689764536379557">"батерейн статистикийг өөрчлөх"</string>
+    <string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"Апп нь батерейн цуглуулагдсан статистикийг өөрчлөх боломжтой. Энгийн апп-д шаардлагагүй."</string>
+    <string name="permlab_getAppOpsStats" msgid="1508779687436585744">"апп-н ажиллагааны статистикийг авах"</string>
+    <string name="permdesc_getAppOpsStats" msgid="6243887041577912877">"Апп нь аппликешны ажиллагааны цуглуулсан статистикийг дуудах боломжтой. Энгийн апп-д ашиглагдахгүй."</string>
+    <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"апп ажиллагааны статистикийг өөрчлөх"</string>
+    <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"Апп нь аппликешны ажиллагааны цуглуулсан статистикийг өөрчлөх боломжтой. Энгийн апп-д ашиглагдахгүй."</string>
+    <string name="permlab_backup" msgid="470013022865453920">"систем нөөшлөлт болон сэргээлтийг удирдах"</string>
+    <string name="permdesc_backup" msgid="6912230525140589891">"Апп нь системийн нөөшлөх болон сэргээх тогтолцоог удирдах боломжтой. Энгийн апп-уудад хэрэглэгдэхгүй."</string>
+    <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"бүтэн нөөшлөлтийг бататгах эсвэл ажиллагааг сэргээх"</string>
+    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"Апп нь бүрэн нөөшлөлтийг баталгаажуулах UI-г эхлүүлэх боломжтой. Энгийн апп-д ашиглагдахгүй."</string>
+    <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"эрхжүүлэгдээгүй цонхыг үзүүлэх"</string>
+    <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"Апп нь дотоод системийн хэрэглэгчийн интерфейст ашиглагдах цонхыг үүсгэх боломжтой. Энгийн апп-д ашиглагдахгүй."</string>
+    <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"бусад апп-р зурах"</string>
+    <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"Апп нь бусад аппликешн эсвэл хэрэглэгчийн интерфейсын дээд талд зурах боломжтой. Эдгээр нь бүх аппликешны интерфейсыг ашиглахад саад болох эсвэл   бусад аппликешн дээр таны харж байгааг солих боломжтой."</string>
+    <string name="permlab_setAnimationScale" msgid="2805103241153907174">"глобал энимешн хурдыг өөрчлөх"</string>
+    <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"Апп нь ямар ч үед глобал энимешн хурдыг(хурдан удаан энимешн) солих боломжтой."</string>
+    <string name="permlab_manageAppTokens" msgid="1286505717050121370">"апп бүтвэрийг удирдах"</string>
+    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"Апп нь өөрийн нормал Z эрэмбийг дамжуулах замаар өөрсдийн бүтвэрийг үүсгэх болон удирдах боломжтой. Энгийн апп-д хэрэглэгдэхгүй"</string>
+    <string name="permlab_freezeScreen" msgid="4708181184441880175">"дэлгэцийг хөдөлгөөнгүй болгох"</string>
+    <string name="permdesc_freezeScreen" msgid="8558923789222670064">"Аппликешн нь бүтэн дэлгэцрүү шилжихэд дэлгэцийг хөдөлгөөнгүй болгох боломжтой."</string>
+    <string name="permlab_injectEvents" msgid="1378746584023586600">"товч болон контрол товч дарах"</string>
+    <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"Алл нь өөрийн оролтын үйл явдлыг(товч дарагдах г.м) бусад апп-д дамжуулах боломжтой. Хортой апп нь энийг ашиглан таблетыг удирдах боломжтой."</string>
+    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"Алл нь өөрийн оролтын үйл явдлыг(товч дарагдах г.м) бусад апп-д дамжуулах боломжтой. Хортой апп нь энийг ашиглан утсыг удирдах боломжтой."</string>
+    <string name="permlab_readInputState" msgid="469428900041249234">"таны хийж байгаа үйлдэл болон бичиж байгааг бичлэг хийх"</string>
+    <string name="permdesc_readInputState" msgid="8387754901688728043">"Апп нь бусад апп-тай харилцан үйлчилж(нууц үг оруулах) таны дарсан товчийг ажиглах боломжтой. Энгийн апп-д хэрэглэгдэхгүй."</string>
+    <string name="permlab_bindInputMethod" msgid="3360064620230515776">"оролтын аргатай холбох"</string>
+    <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Эзэмшигч нь оруулах аргын дээд-төвшиний интерфейстэй холбох боломжтой. Энгийн апп-д хэрэглэгдэхгүй."</string>
+    <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"хандалтын үйлчилгээнд холбогдох"</string>
+    <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Эзэмшигч нь хандах үйлчилгээний дээд-төвшиний интерфейстэй холбох боломжтой. Энгийн апп-д шаардлагагүй."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"хэвлэх үйлчилгээтэй холбох"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Эзэмшигчид хэвлэх үйлчилгээний дээд-түвшний интерфейстэй холбох боломж олгоно. Энгийн апп-уудад хэзээ ч ашиглагдахгүй."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"хэвлэгчийн буфер үйлчилгээтэй холбох"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Эзэмшигчид хэвлэх үйлчилгээний дээд-түвшний интерфейстэй холбох боломж олгоно. Энгийн апп-уудад хэзээ ч ашиглагдахгүй."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC үйлчилгээтэй холбох"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Эзэмшигчид NFC картуудыг дуурайлгадаг аппликешнүүдийг холбох боломж олгоно. Энгийн апп-уудад хэзээ ч шаардагдахгүй."</string>
+    <string name="permlab_bindTextService" msgid="7358378401915287938">"текст үйлчилгээтэй холбох"</string>
+    <string name="permdesc_bindTextService" msgid="8151968910973998670">"Эзэмшигч нь текст үйлчилгээний(ж.нь. SpellCheckerService) дээд-төвшиний интерфейстэй холбох боломжтой. Энгийн апп-д хэрэглэгдэхгүй."</string>
+    <string name="permlab_bindVpnService" msgid="4708596021161473255">"VPN үйлчилгээтэй холбох"</string>
+    <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Эзэмшигч нь VPN үйлчилгээний дээд-төвшиний интерфейстэй холбох боломжтой. Энгийн апп-д шаардлагагүй."</string>
+    <string name="permlab_bindWallpaper" msgid="8716400279937856462">"ханын зурагтай холбох"</string>
+    <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Эзэмшигч нь ханын зурагны дээд-төвшиний интерфейстэй холбох боломжтой. Энгийн апп-уудад шаардлагагүй."</string>
+    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"виджет үйлчилгээтэй холбох"</string>
+    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Эзэмшигч нь виджет үйлчилгээний дээд-төвшиний интерфейстэй холбох боломжтой. Энгийн апп-д шаардлагагүй."</string>
+    <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"төхөөрөмжийн админтай харилцан үйлчлэх"</string>
+    <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Эзэмшигч нь төхөөрөмжийн админруу интент илгээх боломжтой. Энгийн апп-д шаардлагагүй."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"төхөөрөмжийн админ нэмэх, хасах"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Эзэмшигч нь идэвхтэй төхөөрөмжийн администраторыг нэмэх, хасах боломжтой. Энгийн апп-д шаардлагагүй."</string>
+    <string name="permlab_setOrientation" msgid="3365947717163866844">"дэлгэцний чиглэлийг солих"</string>
+    <string name="permdesc_setOrientation" msgid="3046126619316671476">"Апп нь ямар ч үед дэлгэцний эргэлтийг солих боломжтой. Энгийн аппликешнд хэзээ ч ашиглахгүй."</string>
+    <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"заагчийн хурдыг солих"</string>
+    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Апп нь хулгана эсвэл хөдлөх самбарын заагчийн хурдыг ямарч үед солих боломжтой. Энгийн апп-д хэрэглэгдэхгүй."</string>
+    <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"гарын схемийг солих"</string>
+    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Апп нь гарын схемыг солих боломжтой. Энгийн апп-д хэрэглэгдэхгүй."</string>
+    <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"аппруу Linux дохио илгээх"</string>
+    <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Апп нь бүх байнгын процессруу хангамжийн дохиог илгээх хүсэлтийг хийх боломжтой."</string>
+    <string name="permlab_persistentActivity" msgid="8841113627955563938">"апп-г байнга ажиллуулах"</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Апп нь өөрийн хэсгийн санах ойд байнга байлгах боломжтой. Энэ нь бусад апп-уудын ашиглах санах ойг хязгаарлан таблетыг удаашруулах болно."</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"Апп нь өөрийн хэсгийг санах ойд байнга байлгах боломжтой. Энэ нь бусад апп-уудын ашиглах санах ойг хязгаарлан утсыг удаашруулах болно."</string>
+    <string name="permlab_deletePackages" msgid="184385129537705938">"апп устгах"</string>
+    <string name="permdesc_deletePackages" msgid="7411480275167205081">"Апп нь Андройд багцийг устгах боломжтой. Хортой апп нь энийг ашиглан чухал апп-г устгах боломжтой."</string>
+    <string name="permlab_clearAppUserData" msgid="274109191845842756">"бусад апп-н датаг устгах"</string>
+    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"Апп нь хэрэглэгчийн датаг арилгах боломжтой."</string>
+    <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"бусад апп-н кешээс устгах"</string>
+    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"Апп нь кеш файлаас устгах боломжтой."</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"апп сангийн хэмжээг хэмжих"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Апп нь өөрийн код, дата болон кеш хэмжээг унших боломжтой"</string>
+    <string name="permlab_installPackages" msgid="2199128482820306924">"апп-г шууд суулгах"</string>
+    <string name="permdesc_installPackages" msgid="5628530972548071284">"Апп нь шинэ эсвэл шинэчлэгдсэн Андройд багцийг суулгах боломжтой. Хортой апп нь энийг ашиглан дурын эрхтэй шинэ апп-г суулгах боломжтой."</string>
+    <string name="permlab_clearAppCache" msgid="7487279391723526815">"бүх апп-н кеш датаг устгах"</string>
+    <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"Апп нь бусад аппликешны кеш директороос файл устган таблетын санг чөлөөлөх боломжтой. Энэ  нь бусад аппликешнд нөлөөлж, тэдгээр нь эхлэхдээ шаардлагатай датагаа дахин дуудах тул удааширч болзошгүй."</string>
+    <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"Апп нь бусад аппликешны кеш директороос файл устган утасны санг чөлөөлөх боломжтой. Энэ нь бусад аппликешнд нөлөөлж, тэдгээр нь эхлэхдээ шаардлагатай датагаа дахин дуудах тул удааширч болзошгүй."</string>
+    <string name="permlab_movePackage" msgid="3289890271645921411">"апп нөөцийг шилжүүлэх"</string>
+    <string name="permdesc_movePackage" msgid="319562217778244524">"Апп нь апп нөөцийг дотроос гадна медиаруу болон эсрэгээр нь зөөх боломжтой."</string>
+    <string name="permlab_readLogs" msgid="6615778543198967614">"нууц лог дата унших"</string>
+    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Апп нь системийн төрөл бүрийн лог файлыг унших боломжтой. Энэ нь та таблет дээрээ юу хийсэн талаарх хувийн болон нууц мэдээллийг олох боломжтой болгоно."</string>
+    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Апп нь системийн төрөл бүрийн лог файлыг унших боломжтой. Энэ нь та утсан дээрээ юу хийсэн талаарх хувийн болон нууц мэдээллийг олох боломжтой болгоно."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"тоглуулахын тулд дурын медиа шифрлэгчийг ашиглах"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Апп нь тоглуулах үедээ код тайлахдаа суулгагдсан ямарч медиа код тайлагчийг ашиглах боломжтой."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"итгэмжлэгдсэн жуухуудыг удирдах"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Апп-д CA сертификатуудыг итгэмжлэгдсэн жуух байдлаар суулгах болон устгахыг зөвшөөрнө."</string>
+    <string name="permlab_diagnostic" msgid="8076743953908000342">"оношлох грүпийн эзэмшдэг нөөцрүү унших/бичих"</string>
+    <string name="permdesc_diagnostic" msgid="6608295692002452283">"Апп нь оношлох грүпийн эзэмшдэг, жишээ нь /dev доторх файлууд, дурын  нөөцийг унших бичих боломжтой.Энэ нь системийн тогвортой байдал болон аюулгүй байдалд бодитоор нөлөөлнө. Энэ нь үйлдвэрлэгч болон операторын хардверт-зориулсан оношлогоонд ашиглагдана."</string>
+    <string name="permlab_changeComponentState" msgid="6335576775711095931">"апп компонентыг идэвхжүүлэх эсвэл идэвхгүй болгох"</string>
+    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Апп нь өөр апп-н компонент идэвхтэй эсэхийг солих боломжтой. Хортой апп нь энийг ашиглан таблетын чухал чадамжийг идэвхгүй болгож болзошгүй. Зөвшөөрөл нь аппликешн компонентыг тогтворгүй, ашиглаж болохгүй, тохиромжгүй төлөвт оруулах боломжтой тул ашиглахдаа болгоомжтой байх шаардлагатай."</string>
+    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Апп нь өөр апп-н компонент идэвхтэй эсэхийг солих боломжтой. Хортой апп нь энийг ашиглан утасны чухал чадамжийг идэвхгүй болгож болзошгүй. Зөвшөөрөл нь аппликешн компонентыг тогтворгүй, ашиглаж болохгүй, тохиромжгүй төлөвт оруулах боломжтой тул ашиглахдаа болгоомжтой байх шаардлагатай."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"зөвшөөрөл олгох эсвэл цуцлах"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Аппликешн нь өөртэй болон бусад аппликешнд тусгай зөвшөөрлийг олгох болон цуцлах боломжтой. Хортой аппликешн нь энийг ашиглан таны олгоогүй эрхэнд хандах боломжтой."</string>
+    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"үндсэн апп-г тохируулах"</string>
+    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Апп нь таны тусгай апп-уудыг өөрчлөх боломжтой. Хортой апп нь ажиллаж байгаа апп-г нууцаар өөрчлөн, таны хуучин апп-г таны хувийн датаг цуглуулагч болгон хуурах боломжтой."</string>
+    <string name="permlab_writeSettings" msgid="2226195290955224730">"систем тохиргоог өөрчлөх"</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"Апп нь системийн тохиргооны датаг өөрчлөх боломжтой. Хортой апп нь таны системийн тохиргоог сүйтгэх боломжтой."</string>
+    <string name="permlab_writeSecureSettings" msgid="204676251876718288">"аюулгүй систем тохиргоог өөрчлөх"</string>
+    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"Апп нь системийн аюулгүй байдлын тохиргооны датаг өөрчлөх боломжтой. Энгийн апп-д ашиглагдахгүй."</string>
+    <string name="permlab_writeGservices" msgid="2149426664226152185">"Google газрын зургийн үйлчилгээг өөрчлөх"</string>
+    <string name="permdesc_writeGservices" msgid="1287309437638380229">"Апп нь Google-н газрын зургийн үйлчилгээг өөрчлөх боломжтой. Энгийн апп-д ашиглагдахгүй."</string>
+    <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"Эхлэхэд ажиллуулах"</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Апп нь систем асаж дуусахад шууд өөрийгөө асаах боломжтой. Ингэснээр таблетыг асахад их хугацаа орох болон байнга ажилладаг апп нь таблетийг бүхэлд нь удаашруулах боломжтой."</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="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="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="default" msgid="589869224625163558">"Апп нь таны утсаар ярьсан, имэйл илгээсэн давтамж эсвэл харилцагдчидтайгаа өөр аргаар холбоо барьсан байдал зэргийг агуулсан утсан дээр хадгалагдсан харилцагчдын талаарх датаг өөрчлөх боломжтой. Энэ зөвшөөрөл нь апп-д харилцагчийн датаг устгах боломжийг олгоно."</string>
+    <string name="permlab_readCallLog" msgid="3478133184624102739">"дуудлагын логийг унших"</string>
+    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Апп нь таны таблетын ирсэн гарсан дуудлага зэргийг агуулсан дуудлагын логыг унших боломжтой. Энэ зөвшөөрөл нь апп-д таны дуудлагын логын датаг хадгалах боломжийг олгох ба хортой апп нь танд мэдэгдэлгүйгээр дуудлагын лог датаг хуваалцах боломжтой."</string>
+    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Апп нь таны утасны ирсэн гарсан дуудлага зэргийг агуулсан дуудлагын логыг унших боломжтой. Энэ зөвшөөрөл нь апп-д таны дуудлагын логын датаг хадгалах боломжийг олгох ба хортой апп нь танд мэдэгдэлгүйгээр дуудлагын лог датаг хуваалцах боломжтой."</string>
+    <string name="permlab_writeCallLog" msgid="8552045664743499354">"дуудлагын логруу бичих"</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Апп нь таны таблетын ирсэн гарсан дуудлага зэргийг агуулсан дуудлагын логыг унших боломжтой. Хортой апп нь энийг ашиглан таны дуудлагын логыг өөрчлөх болон арилгах боломжтой."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Апп нь таны утасны ирсэн гарсан дуудлага зэргийг агуулсан дуудлагын логыг өөрчлөх боломжтой. Хортой апп нь энийг ашиглан таны дуудлагын логыг өөрчлөх болон арилгах боломжтой."</string>
+    <string name="permlab_readProfile" msgid="4701889852612716678">"та өөрийн харилцагчийн картыг унших"</string>
+    <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Апп нь таны нэр болон холбоо барих мэдээлэл зэрэг таны утсан дээр хадгалагдсан хувийн профайл мэдээллийг унших боломжтой. Ингэснээр апп нь танийг таньж чадах ба таны профайл мэдээллийг бусдад илгээх боломжтой."</string>
+    <string name="permlab_writeProfile" msgid="907793628777397643">"та өөрийн харилцагчийн картыг өөрчлөх"</string>
+    <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Апп нь таны нэр болон холбоо барих мэдээлэл зэрэг таны төхөөрөмж дээр хадгалагдсан хувийн профайл мэдээллийг солих эсвэл нэмэх боломжтой. Ингэснээр апп нь танийг таньж чадах ба таны профайл мэдээллийг бусдад илгээх боломжтой."</string>
+    <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"таны нийтийн урсгалаас унших"</string>
+    <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Апп нь та болон таны найзуудын нийтийн шинэчлэлтэд хандах болон синк хийх боломжтой. Мэдээлэл хуваалцахдаа болгоомжтой байна уу - энэ нь апп-д нийтийн сүлжээндэх та болон таны найзууд хоорондын холбоог нууц эсэхээс үл хамааран унших боломжтой. Анхаар: энэ зөвшөөрөл нь бүх нийтийн сүлжээнд ашиглаж боломжгүй."</string>
+    <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"Таны нийтийн урсгалруу бичих"</string>
+    <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Апп нь таны найзуудын нийтийн шинэчлэлтийг дүрслэх боломжтой.Мэдээлэл хуваалцахдаа болгоомжтой байна уу - энэ нь апп-д таны найзаас ирсэн мэт харагдах мессеж хийх боломжийг олгоно. Анхаар: энэ зөвшөөрөл нь бүх нийтийн сүлжээнд ашиглаж боломжгүй."</string>
+    <string name="permlab_readCalendar" msgid="5972727560257612398">"календарийн хуваарийн нууц мэдээллийг унших"</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Апп нь таны таблет дээр хадгалагдсан найзууд болон хамтран ажиллагсдын календарийн бүх хуваарийг унших боломжтой. Энэ нь апп-д таны календарийн датаг нууц эсвэл эмзэг эсэхээс нь үл хамааран хуваалцах эсвэл хадгалах боломжийг олгоно."</string>
+    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Allows the app to read all calendar events stored on your phone, including those of friends or co-workers. This may allow the app to share or save your calendar data, regardless of confidentiality or sensitivity. Апп нь таны утсан дээр хадгалагдсан найзууд болон хамтран ажиллагсдын календарийн бүх хуваарийг унших боломжтой. Энэ нь апп-д таны календарийн датаг нууц эсвэл эмзэг эсэхээс нь үл хамааран хуваалцах эсвэл хадгалах боломжийг олгоно."</string>
+    <string name="permlab_writeCalendar" msgid="8438874755193825647">"календарын хуваарийг нэмэх эсвэл өөрчлөх болон эзэмшигчид мэдэгдэлгүйгээр зочидруу имэйл илгээх"</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Апп нь таблет дээр та болон таны найзууд, хамтран ажиллагсдын өөрчилж чадах үйл явдлуудыг нэмэх, хасах болон солих боломжтой. Энэ нь апп-д, календарь эзэмшигчээс ирсэн мэт харагдах мессежийг илгээх эсвэл эзэмшигчд нь мэдэгдэлгүйгээр үйл явдлуудыг өөрчлөх боломжийг олгоно."</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Апп нь утсан дээр та болон таны найзууд, хамтран ажиллагсдын өөрчилж чадах үйл явдлуудыг нэмэх, хасах болон солих боломжтой. Энэ нь апп-д, календарь эзэмшигчээс ирсэн мэт харагдах мессежийг илгээх эсвэл эзэмшигчид нь мэдэгдэлгүйгээр үйл явдлуудыг өөрчлөх боломжийг олгоно."</string>
+    <string name="permlab_accessMockLocation" msgid="8688334974036823330">"тест хийх байршлын эх үүсвэрийг үүсгэх"</string>
+    <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Тестэд ашиглах хуурамч байршлын эх үүсвэрийг үүсгэх болон шинэ байршил өгөгчийг суулгах боломжтой. Ингэснээр апп нь GPS эсвэл байршил өгөгч зэрэг бусад байршлын эх үүсвэрээс ирсэн байршил болон статусыг өөрчлөх боломжтой."</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"байршил нийлүүлэгчийн нэмэлт тушаалд хандах"</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"Апп нь байршил нийлүүлэгчийн нэмэлт тушаалд хандах боломжтой. Энэ нь апп-д GPS эсвэл бусад байршлын үйлчилгээний ажиллагаанд нөлөөлөх боломжийг олгоно."</string>
+    <string name="permlab_installLocationProvider" msgid="6578101199825193873">"байршил нийлүүлэгчийг суулгах зөвшөөрөх"</string>
+    <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"Тестэд ашиглах хуурамч байршлын эх үүсвэрийг үүсгэх болон шинэ байршил өгөгчийг суулгах боломжтой. Ингэснээр апп нь GPS эсвэл байршил өгөгч зэрэг бусад байршлын эх үүсвэрээс ирсэн байршил болон статусыг өөрчлөх боломжтой."</string>
+    <string name="permlab_accessFineLocation" msgid="1191898061965273372">"Тодорхой байршил(GPS болон сүлжээнд суурилсан)"</string>
+    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Апп нь GPS эсвэл үүрэн цамхаг болон Wi-Fi зэрэг сүлжээний байршлын эх үүсвэрийг ашиглан таны тодорхой байршлыг авах боломжтой. Эдгээр байршлын үйлчилгээнүүд нь асаалттай байх шаардлагатай ба таны төхөөрөмж дээрх апп-ууд ашиглах боломжтой байх шаардлагатай. Апп-ууд энийг ашиглан таныг хаана байгааг тогтоох боломжтой ба батерей зарцуулалт нэмэгдэнэ."</string>
+    <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"ойролцоох байршил(сүлжээнд суурилсан)"</string>
+    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Апп нь таны ойролцоох байршлыг оло боломжтой. Энэ байршил нь үүрэн цамхаг болон Wi-Fi зэрэг сүлжээний байршлын эх сурвалжийг ашигладаг байршлын үйлчилгээнээс олдоно. Эдгээр байршлын үйлчилгээнүүд нь таны төхөөрөмж дээр асаалттай байх шаардлагатай ба апп-д тэдгээрийг ашиглах боломжтой байх шаардлагатай. Апп-д тэдгээрийг ашиглан таны байршлыг ойролцоогоор олох боломжтой."</string>
+    <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"SurfaceFlinger-т хандах"</string>
+    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Апп нь SurfaceFlinger доод-төвшиний функцийг ашиглах боломжтой."</string>
+    <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"Фрэйм буферээс унших"</string>
+    <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Апп нь фрэйм буферын контентыг унших боломжтой."</string>
+    <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Wifi дэлгэцийг тохируулах"</string>
+    <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Апп нь Wifi дэлгэцийг тохируулах болон холбогдох боломжтой."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wifi дэлгэцийг удирдах"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Апп нь Wifi дэлгэцний доод-төвшиний функцийг удирдах боломжтой."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"аудио гаралтыг барих"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Апп-т аудио гаралтыг барих, дахин чиглүүлэхийг зөвшөөрнө."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"видео гаралтыг барих"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Апп-т видео гаралтыг барих, дахин чиглүүлэхийг зөвшөөрнө."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"найдвартай видео гаралтыг барих"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Апп-т найдвартай видео гаралтыг барих, дахин чиглүүлэхийг зөвшөөрнө."</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="4906839301087980680">"Апп нь микрофоноор аудио бичих боломжтой. Энэ зөвшөөрөл нь апп-д ямар ч үед таны зөвшөөрөлгүйгээр аудио бичих боломжийг олгоно."</string>
+    <string name="permlab_camera" msgid="3616391919559751192">"зураг авах болон видео бичих"</string>
+    <string name="permdesc_camera" msgid="8497216524735535009">"Апп нь камераар зураг авах болон видео бичих боломжтой. Энэ зөвшөөрөл нь апп-д ямар ч үед таны зөвшөөрөлгүйгээр камер ашиглах боломжийг олгоно."</string>
+    <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"камер ашиглаж байх үед дамжууллыг заагч LED-г идэвхгүй болгох"</string>
+    <string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"Урьдчилан суусан систем аппликешн нь камер ашиглалтыг заасан LED-г идэвхгүй болгох боломжтой."</string>
+    <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"таблетыг бүрмөсөн идэвхгүй болгох"</string>
+    <string name="permlab_brick" product="default" msgid="8337817093326370537">"утсыг бүрмөсөн идэвхгүй болгох"</string>
+    <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"Апп нь таблетыг бүхэлд нь бүрмөсөн идэвхгүй болгох боломжтой. Энэ маш аюултайэ"</string>
+    <string name="permdesc_brick" product="default" msgid="5788903297627283099">"Апп нь утсыг бүхэлд нь бүрмөсөн идэвхгүй болгох боломжтой. Энэ маш аюултай."</string>
+    <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"таблет хүчээр дахин асаах"</string>
+    <string name="permlab_reboot" product="default" msgid="2898560872462638242">"утсыг хүчээр дахин асаах"</string>
+    <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"Апп нь таблетыг хүчээр дахин асаах боломжтой."</string>
+    <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"Апп нь утсыг хүчээр дахин асаах боломжтой."</string>
+    <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"USB сан файл системд хандах"</string>
+    <string name="permlab_mount_unmount_filesystems" product="default" msgid="4402305049890953810">"SD карт файл системд хандах"</string>
+    <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"Апп нь сугалдаг санг файл системд залгах болон салгах боломжтой."</string>
+    <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"USB санг арилгах"</string>
+    <string name="permlab_mount_format_filesystems" product="default" msgid="262582698639274056">"SD картыг арилгах"</string>
+    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"Апп нь зөөврийн санг форматлах боломжтой."</string>
+    <string name="permlab_asec_access" msgid="3411338632002193846">"дотоод сангийн мэдээллийг авах"</string>
+    <string name="permdesc_asec_access" msgid="3094563844593878548">"Апп нь дотоод сангаас мэдээллийг авах боломжтой"</string>
+    <string name="permlab_asec_create" msgid="6414757234789336327">"дотоод санд үүсгэх"</string>
+    <string name="permdesc_asec_create" msgid="4558869273585856876">"Апп нь дотоод сан үүсгэх боломжтой."</string>
+    <string name="permlab_asec_destroy" msgid="526928328301618022">"дотоод сангаас устгах"</string>
+    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"Апп нь дотоод сангаас устгах боломжтой."</string>
+    <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"дотоод санг залгах/салгах"</string>
+    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"Апп нь дотоод санг залгах/салгах боломжтой."</string>
+    <string name="permlab_asec_rename" msgid="7496633954080472417">"дотоод сангийн нэрийг өөрчлөх"</string>
+    <string name="permdesc_asec_rename" msgid="1794757588472127675">"Апп нь дотоод сангийн нэрийг өөрчлөх боломжтой."</string>
+    <string name="permlab_vibrate" msgid="7696427026057705834">"чичиргээг удирдах"</string>
+    <string name="permdesc_vibrate" msgid="6284989245902300945">"Апп нь чичиргээг удирдах боломжтой."</string>
+    <string name="permlab_flashlight" msgid="2155920810121984215">"гар чийдэн удирдах"</string>
+    <string name="permdesc_flashlight" msgid="6522284794568368310">"Апп нь гар чийдэнг удирдах боломжтой."</string>
+    <string name="permlab_manageUsb" msgid="1113453430645402723">"USB төхөөрөмжийн тохиргоо болон зөвшөөрлийг удирдах"</string>
+    <string name="permdesc_manageUsb" msgid="7776155430218239833">"Апп нь USB төхөөрөмжийн зөвшөөрөл болон тохируулгыг удирдах боломжтой."</string>
+    <string name="permlab_accessMtp" msgid="4953468676795917042">"MTP протоколыг гүйцэтгэх"</string>
+    <string name="permdesc_accessMtp" msgid="6532961200486791570">"MTP USB протокол биелүүлэхээр MTP цөм драйверт хандах боломжтой."</string>
+    <string name="permlab_hardware_test" msgid="4148290860400659146">"хардвер теслэх"</string>
+    <string name="permdesc_hardware_test" msgid="6597964191208016605">"Апп нь хардверийг тестлэх зорилгоор олон төрлийн туслах төхөөрөмжийг удирдах боломжтой."</string>
+    <string name="permlab_callPhone" msgid="3925836347681847954">"утасны дугаарт шууд дуудлага хийх"</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"Апп нь таны оролцоогүйгээр дуудлага хийх боломжтой. Энэ нь төлөвлөгдөөгүй төлбөрт оруулах эсвэл дуудлага хийнэ. Энэ нь апп-г яаралтай дугаарт дуудлага хийхйг зөвшөөрөхгүй. Хортой апп нь таны зөвшөөрөлгүйгээр дуудлага хийж таныг төлбөрт оруулж болзошгүй"</string>
+    <string name="permlab_callPrivileged" msgid="4198349211108497879">"дурны утасны дугаарт шууд дуудлага хийх"</string>
+    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"Апп нь таны оролцоогүйгээр яаралтай тусламжийн дугааруудыг оруулаад ямарч дугаарлуу дуудлага хийх боломжтой. Хортой апп нь шаардлагагүй, хууль бус дуудлагыг яаралтай тусламжийн үйлчилгээрүү хийж болзошгүй."</string>
+    <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"CDMA таблет тохиргоог шууд эхлүүлэх"</string>
+    <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"CDMA утасны тохиргоог шууд эхлүүлэх"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"Апп нь CDMA провишныг эхлүүлэх боломжтой. Хортой апп нь шаардлагагүй байхад CDMA провишныг эхлүүлж болзошгүй."</string>
+    <string name="permlab_locationUpdates" msgid="7785408253364335740">"байршил шинэчлэх мэдэгдлийг удирдах"</string>
+    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Апп нь радиогоос ирсэн байршил шинэчлэх мэдэгдлийг идэвхтэй/идэвхгүй болгох боломжтой. Энгийн апп-д хэрэглэглэхгүй."</string>
+    <string name="permlab_checkinProperties" msgid="7855259461268734914">"бүртгэх пропертид хандах"</string>
+    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Апп нь бүртгэл үйлчилгээгээр байршуулагдсан пропертиг унших/бичих боломжтой. Энгийн апп-д хэрэглэгдэхгүй."</string>
+    <string name="permlab_bindGadget" msgid="776905339015863471">"виджет сонгох"</string>
+    <string name="permdesc_bindGadget" msgid="8261326938599049290">"Апп нь аль апп ямар виджетийг ашиглаж байгаа тухай системд мэдэгдэх боломжтой. Энэ зөвшөөрөлтэй апп нь бусад апп-д хувийн датад хандах эрхийг өгөх боломжтой. Энгийн апп-д ашиглагдахгүй."</string>
+    <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"утасны статусыг өөрчлөх"</string>
+    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Апп-н төхөөрөмжийн утасны функцийг удирдах боломжтой. Энэ зөвшөөрөлтэй апп  нь танд анхааруулахгүйгээр сүлжээг сэлгэх, утасны радиог асаах, унтраах боломжтой."</string>
+    <string name="permlab_readPhoneState" msgid="9178228524507610486">"утасны статус ба таниулбарыг унших"</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Апп нь төхөөрөмжийн утасны функцд хандах боломжтой. Энэ зөвшөөрөл нь апп-д утасны дугаар болон төхөөрөмжийн ID-г, дуудлага идэвхтэй эсэх, холын дугаар дуудлагаар холбогдсон байгаа эсэхийг тогтоох боломжийг олгоно,"</string>
+    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"таблетыг унтуулахгүй байлгах"</string>
+    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"утсыг унтуулахгүй байлгах"</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Апп нь таблетыг унтахаас сэргийлэх боломжтой"</string>
+    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Апп нь утсыг унтахаас сэргийлэх боломжтой"</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
+    <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"таблетыг унтраах эсвэл асаах"</string>
+    <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"утсыг унтраах эсвэл асаах"</string>
+    <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Апп нь таблетыг асаах, унтраах боломжтой."</string>
+    <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"Апп нь утсыг асаах, унтраах боломжтой."</string>
+    <string name="permlab_factoryTest" msgid="3715225492696416187">"үйлдвэрийн тест горимд ажиллуулах"</string>
+    <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"Доод төвшиний үйлдвэрийн тестийг ажиллуулан таблетын хардверт бүрэн хандах боломжтой. Таблет нь үйлдвэрийн тестийн горимд ажиллах үед л боломжтой."</string>
+    <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"Доод төвшиний үйлдвэрийн тестийг ажиллуулан утасны хардверт бүрэн хандах боломжтой. Утас үйлдвэрийн тестийн горимд ажиллах үед л боломжтой."</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_masterClear" msgid="2315750423139697397">"системийг үйлдвэрийн үндсэн утгаар тохируулах"</string>
+    <string name="permdesc_masterClear" msgid="3665380492633910226">"Апп нь бүх датаг арилгах болон бүх суулгасан апп-г арилган системийг бүхэлд үйлдвэрийн тохиргоогоор бүрэн тохируулах боломжтой"</string>
+    <string name="permlab_setTime" msgid="2021614829591775646">"цагийн тохиргоо"</string>
+    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"Апп нь таблетын цагийг солих боломжтой."</string>
+    <string name="permdesc_setTime" product="default" msgid="1855702730738020">"Апп нь утасны цагийг солих боломжтой."</string>
+    <string name="permlab_setTimeZone" msgid="2945079801013077340">"цагийн бүсийн тохиргоо"</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Апп нь таблетын цагийн бүсийг солих боломжтой."</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Апп нь утасны цагийн бүсийг өөрчлөх боломжтой."</string>
+    <string name="permlab_accountManagerService" msgid="4829262349691386986">"AccountManagerService болж ажиллах"</string>
+    <string name="permdesc_accountManagerService" msgid="1948455552333615954">"Апп нь Акаунт гэрчлэгчрүү дуудлага хийх боломжтой."</string>
+    <string name="permlab_getAccounts" msgid="1086795467760122114">"төхөөрөмж дээрх акаунтыг олох"</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Апп нь таблетэд мэдэгдэж байгаа акаунтын жагсаалтыг авах боломжтой. Энд таны суулгасан аппликешнүүдийн үүсгэсэн бүх акаунтууд хамрагдана."</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Апп нь утсанд мэдэгдэж байгаа акаунтын жагсаалтыг авах боломжтой. Энд таны суулгасан аппликешнүүдийн үүсгэсэн бүх акаунтууд хамрагдана."</string>
+    <string name="permlab_authenticateAccounts" msgid="5265908481172736933">"акаунт үүсгэх болон нууц үг тохируулах"</string>
+    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"Апп нь акаунт үүсгэх, тэдгээрийн нууц үгийг тохируулах зэрэг акаунт удирдагчийн акаунт гэрчлэгчийн функцийг ашиглах боломжтой."</string>
+    <string name="permlab_manageAccounts" msgid="4983126304757177305">"акаунт нэмэх эсвэл хасах"</string>
+    <string name="permdesc_manageAccounts" msgid="8698295625488292506">"Апп нь акаунт нэмэх, устгах ба тэдний нууц үгийг устгах зэрэг үйлдлийг гүйцэтгэх боломжтой."</string>
+    <string name="permlab_useCredentials" msgid="235481396163877642">"төхөөрөмж дээрх акаунтыг ашиглах"</string>
+    <string name="permdesc_useCredentials" msgid="7984227147403346422">"Апп нь гэрчлэлийн бүтвэрийг хүсэх боломжтой."</string>
+    <string name="permlab_accessNetworkState" msgid="4951027964348974773">"сүлжээний холболтыг үзэх"</string>
+    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Апп нь сүлжээ байгаа болон холбогдсон эсэх зэрэг сүлжээний холболтын талаарх мэдээллийг харах боломжтой."</string>
+    <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"сүлжээнд бүрэн хандах"</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Апп нь сүлжээний сокетыг үүсгэх болон тусгай сүлжээний протокол ашиглах боломжтой. Хөтөч болон бусад аппликешнүүд Интернетээр дата илгээх боломжтой  тул энэ зөвшөөрөл нь Интернетээр дата илгээхэд шаардлагагүй."</string>
+    <string name="permlab_writeApnSettings" msgid="505660159675751896">"сүлжээний тохиргоо болон урсгалыг солих/таслах"</string>
+    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Апп нь сүлжээний тохиргоог солих болон сүлжээний бүх урсгалыг APN-н прокси болон портыг солих замаар таслах, хянах боломжтой. Хортой апп нь танд мэдэгдэлгүйгээр сүлжээний пакетыг хянах, дахин чиглүүлэх болон өөрчлөх боломжтой."</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_changeBackgroundDataSetting" msgid="1400666012671648741">"арын дата ашиглалтын тохиргоог солих"</string>
+    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Апп нь арын дата хэрэглээний тохиргоог солих боломжтой."</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="default" msgid="6851949706025349926">"Апп нь олон дамжуулал ашиглан Wi-Fi сүлжээн дэх бүх төхөөрөмжрүү пакет илгээх болон хүлээн авах боломжтой. Энэ нь олон дамжуулал ашиглахгүй горимоос илүү их тэжээл зарцуулна."</string>
+    <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"Блютүүт тохиргоонд хандах"</string>
+    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Апп нь дотоод блютүүт таблетын тохиргоог харах боломжтой ба хос болох төхөөрөмжтэй холболтыг зөвшөөрөх болон хийх боломжтой"</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="2405042267131496579">"WiMAX статусыг өөрчлөх"</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Апп нь 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="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_readSyncSettings" msgid="6201810008230503052">"синк тохиргоог унших"</string>
+    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Апп нь акаунтын синк тохиргоог унших боломжтой. Жишээ нь энэ нь Хүмүүс апп акаунттай синк хийгдсэн эсэхийг тодорхойлох боломжтой."</string>
+    <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"синкийг унтрааж асаах тохиргоо"</string>
+    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Апп нь акаунтын синк тохиргоог өөрчлөх боломжтой. Жишээ нь энэ нь Хүмүүс апп акаунттай синк хийхийг идэвхжүүлэх боломжтой."</string>
+    <string name="permlab_readSyncStats" msgid="7396577451360202448">"синк статистикийг унших"</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Апп нь синк үйлдэлийн түүх болон хэр их дата синк хийгдсэн зэрэг акаунтын синк статусыг унших боломжтой."</string>
+    <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"бүртгүүлсэн хангамжийг унших"</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Апп нь одоогийн синк хийгдсэн хангамжийн талаарх мэдээллийг авах боломжтой."</string>
+    <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"бүртгүүлсэн хангамжруу бичих"</string>
+    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"Апп нь таны одоогийн синк хийгдсэн хангамжийг өөрчлөх боломжтой. Хортой апп нь таны синк хийгдсэн хангамжийг өөрчлөх боломжтой."</string>
+    <string name="permlab_readDictionary" msgid="4107101525746035718">"таны толь бичигт нэмсэн нөхцөлийг унших"</string>
+    <string name="permdesc_readDictionary" msgid="659614600338904243">"Апп нь хэрэглэгч хэрэглэгчийн толь бичигт хадгалсан бүх үгс, нэрс болон хэлцийг унших боломжтой."</string>
+    <string name="permlab_writeDictionary" msgid="2183110402314441106">"хэрэглэгчийн толь бичигт үгс нэмэх"</string>
+    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Апп нь хэрэглэгчийн толь бичигт шинэ үг бичих боломжтой."</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"хамгаалагдсан санд хандах тест хийх"</string>
+    <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"хамгаалагдсан санд хандах тест хийх"</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"Апп нь дараагийн төхөөрөмжүүдэд ашиглах боломжтой болох SD карт зөвшөөрлийг тестлэх боломжтой."</string>
+    <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"Апп нь дараагийн төхөөрөмжүүдэд ашиглах боломжтой болох 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_mediaStorageWrite" product="default" msgid="6859839199706879015">"дотоод медиа сангийн контентыг өөрчлөх/устгах"</string>
+    <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Апп нь дотоод медиа сангийн контентыг өөрчлөх боломжтой."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"документ санг удирдах"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Апп нь документ санг удирдах боломжтой."</string>
+    <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"бүх хэрэглэгчдийн гадаар санд хандах"</string>
+    <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Апп нь бүх хэрэглэгчдийн гадаад санд хандах боломжтой."</string>
+    <string name="permlab_cache_filesystem" msgid="5656487264819669824">"кеш файлсистемд хандах"</string>
+    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Апп нь кеш файлсистемийг унших бичих боломжтой."</string>
+    <string name="permlab_use_sip" msgid="5986952362795870502">"Интернет дуудлага хийх/хүлээн авах"</string>
+    <string name="permdesc_use_sip" msgid="4717632000062674294">"Апп нь Интернет дуудлага хийх/хүлээн авахын тулд SIP үйлчилгээг ашиглах боломжтой."</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_markNetworkSocket" msgid="3658527214914959749">"соккетын тэмдгүүдийг өөрчлөх"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Апп-д чиглэлийн соккетын тэмдгийг өөрчлөх боломж олгоно"</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_invokeCarrierSetup" msgid="3699600833975117478">"үүрэн компанийн нийлүүлсэн тохируулгын апп-г өдөөх"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Эзэмшигчид үүрэн компанийн нийлүүлсэн тохируулах апп-г өдөөх боломж олгоно. Энгийн апп-уудад хэзээ ч ашиглагдахгүй."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"Сүлжээний байдлын талаар ажиглалтуудыг хүлээн авах"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Аппликешнд сүлжээний байдлын талаар ажиглалтуудыг хүлээн авахыг зөвшөөрнө. Энгийн апп-уудад хэзээ ч ашиглагдахгүй."</string>
+    <string name="policylab_limitPassword" msgid="4497420728857585791">"Нууц үгний дүрмийг тохируулах"</string>
+    <string name="policydesc_limitPassword" msgid="3252114203919510394">"Дэлгэц түгжих нууц үгэнд зөвшөөрөгдсөн тэмдэгт болон уртыг удирдах"</string>
+    <string name="policylab_watchLogin" msgid="914130646942199503">"Дэлгэц тайлах оролдлогыг хянах"</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Дэлгэц түгжигдсэн үед нууц үг буруу оруулалтын тоог хянах ба хэрэв хэт олон удаа нууц үгийг буруу оруулбал таблетыг түгжих болон таблетын бүх датаг арилгана"</string>
+    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Дэлгэц түгжигдсэн үед нууц үг буруу оруулалтын тоог хянах, ба хэрэв хэт олон удаа нууц үгийг буруу оруулбал утсыг түгжих болон утасны бүх датаг арилгана"</string>
+    <string name="policylab_resetPassword" msgid="2620077191242688955">"Дэлгэц түгжих нууц үгийг солих"</string>
+    <string name="policydesc_resetPassword" msgid="605963962301904458">"Дэлгэц түгжих нууц үгийг солих"</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="default" msgid="5096895604574188391">"Үйлдвэрийн дата утгыг өгсөнөөр утасны дата шууд арилгагдана."</string>
+    <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Төхөрөөмжийн глобал проксиг тохируулах"</string>
+    <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Бодлого идэвхтэй үед төхөөрөмжийн глобал проксиг ашиглахаар тохируулсан. Зөвхөн эхний төхөөрөмжийн админ л үр дүнтэй глобал проксиг тохируулна."</string>
+    <string name="policylab_expirePassword" msgid="885279151847254056">"Дэлгэц түгжих нууц үгний хүчинтэй хугацааг тохируулах"</string>
+    <string name="policydesc_expirePassword" msgid="1729725226314691591">"Дэлгэцний түгжих нууц үг хэр давтамжтай солигдохыг удирдах."</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="policylab_disableKeyguardFeatures" msgid="266329104542638802">"Түлхүүр хамгаалтын функцийг унтраах"</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="3467082272186534614">"Түлхүүр хамгаалалтын зарим функцийг ашиглахыг хориглох."</string>
+  <string-array name="phoneTypes">
+    <item msgid="8901098336658710359">"Гэрийн"</item>
+    <item msgid="869923650527136615">"Мобайл"</item>
+    <item msgid="7897544654242874543">"Ажлын"</item>
+    <item msgid="1103601433382158155">"Ажлын факс"</item>
+    <item msgid="1735177144948329370">"Гэрийн Факс"</item>
+    <item msgid="603878674477207394">"Пэйжер"</item>
+    <item msgid="1650824275177931637">"Бусад"</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>
+  </string-array>
+  <string-array name="postalAddressTypes">
+    <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="1359644565647383708">"Ажлын"</item>
+    <item msgid="7868549401053615677">"Бусад"</item>
+    <item msgid="3145118944639869809">"Тусгай"</item>
+  </string-array>
+  <string-array name="organizationTypes">
+    <item msgid="7546335612189115615">"Ажлын"</item>
+    <item msgid="4378074129049520373">"Бусад"</item>
+    <item msgid="3455047468583965104">"Тусгай"</item>
+  </string-array>
+  <string-array name="imProtocols">
+    <item msgid="8595261363518459565">"AIM"</item>
+    <item msgid="7390473628275490700">"Windows Live"</item>
+    <item msgid="7882877134931458217">"Yahoo"</item>
+    <item msgid="5035376313200585242">"Skype"</item>
+    <item msgid="7532363178459444943">"QQ"</item>
+    <item msgid="3713441034299660749">"Google Talk"</item>
+    <item msgid="2506857312718630823">"ICQ"</item>
+    <item msgid="1648797903785279353">"Jabber"</item>
+  </string-array>
+    <string name="phoneTypeCustom" msgid="1644738059053355820">"Тусгай"</string>
+    <string name="phoneTypeHome" msgid="2570923463033985887">"Гэрийн"</string>
+    <string name="phoneTypeMobile" msgid="6501463557754751037">"Мобайл"</string>
+    <string name="phoneTypeWork" msgid="8863939667059911633">"Ажлын"</string>
+    <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Ажлын факс"</string>
+    <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Гэрийн Факс"</string>
+    <string name="phoneTypePager" msgid="7582359955394921732">"Пэйжер"</string>
+    <string name="phoneTypeOther" msgid="1544425847868765990">"Бусад"</string>
+    <string name="phoneTypeCallback" msgid="2712175203065678206">"Буцаж холбоо барих"</string>
+    <string name="phoneTypeCar" msgid="8738360689616716982">"Машин"</string>
+    <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Байгууллагын үндсэн"</string>
+    <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string>
+    <string name="phoneTypeMain" msgid="6766137010628326916">"Үндсэн"</string>
+    <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Бусад факс"</string>
+    <string name="phoneTypeRadio" msgid="4093738079908667513">"Радио"</string>
+    <string name="phoneTypeTelex" msgid="3367879952476250512">"Tелекс"</string>
+    <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="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="eventTypeOther" msgid="7388178939010143077">"Бусад"</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="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="imTypeWork" msgid="1371489290242433090">"Ажлын"</string>
+    <string name="imTypeOther" msgid="5377007495735915478">"Бусад"</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>
+    <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
+    <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
+    <string name="imProtocolGoogleTalk" msgid="493902321140277304">"Цугларалт"</string>
+    <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">"Ажлын"</string>
+    <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="relationTypeBrother" msgid="8757913506784067713">"Ах"</string>
+    <string name="relationTypeChild" msgid="1890746277276881626">"Хүүхэд"</string>
+    <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"Дотоод Түнш"</string>
+    <string name="relationTypeFather" msgid="5228034687082050725">"Эцэг"</string>
+    <string name="relationTypeFriend" msgid="7313106762483391262">"Найз"</string>
+    <string name="relationTypeManager" msgid="6365677861610137895">"Менежер"</string>
+    <string name="relationTypeMother" msgid="4578571352962758304">"Эх"</string>
+    <string name="relationTypeParent" msgid="4755635567562925226">"Эцэг эх"</string>
+    <string name="relationTypePartner" msgid="7266490285120262781">"Түнш"</string>
+    <string name="relationTypeReferredBy" msgid="101573059844135524">"Дурдагдсан"</string>
+    <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="sipAddressTypeHome" msgid="6093598181069359295">"Гэрийн"</string>
+    <string name="sipAddressTypeWork" msgid="6920725730797099047">"Ажлын"</string>
+    <string name="sipAddressTypeOther" msgid="4408436162950119849">"Бусад"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN кодыг бичнэ үү"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK-г бичээд шинэ PIN код оруулна уу"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK код"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Шинэ PIN код"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><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">"Тайлах PIN-г оруулна уу"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Буруу PIN код."</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="8963839242565653192">"Үйлчилгээ байхгүй."</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="5347633784401285225">"Яаралтай дуудлага"</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="faceunlock_multiple_failures" msgid="754137583022792429">"Нүүрээр түгжээ тайлах оролдлогын тоо дээд хэмжээнээс хэтэрсэн"</string>
+    <string name="lockscreen_plugged_in" msgid="8057762828355572315">"Цэнэглэж байна, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_charged" msgid="321635745684060624">"Цэнэглэгдэв"</string>
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_low_battery" msgid="1482873981919249740">"Цэнэглэгчээ холбоно уу."</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="default" msgid="2186920585695169078">"Утсанд SIM карт байхгүй."</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_transport_prev_description" msgid="201594905152746886">"Өмнөх бичлэг товч"</string>
+    <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Дараагийн бичлэг товч"</string>
+    <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Түр зогсоох товч"</string>
+    <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Тоглуулах товч"</string>
+    <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Зогсоох товч"</string>
+    <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">"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">%d</xliff:g> удаа буруу зурлаа. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Та нууц үгээ <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу бичив. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Та PIN кодоо <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу бичив. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Та тайлах хээг <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу зурлаа. <xliff:g id="NUMBER_1">%d</xliff:g> удаа дахин буруу оруулбал, та таблетаа тайлахын тулд Google нэвтрэлтээ ашиглах шаардлагатай болно.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Та тайлах хээг <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу зурлаа. <xliff:g id="NUMBER_1">%d</xliff:g> удаа дахин буруу оролдвол, та таблетаа тайлахын тулд Google нэвтрэлтээ ашиглах шаардлагатай болно.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Та таблетыг тайлах гэж <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу оролдлоо. <xliff:g id="NUMBER_1">%d</xliff:g> удаа дахин буруу оролдвол таблет үйлдвэрийн үндсэн утгаараа тохируулагдах ба хэрэглэгчийн дата бүхэлдээ устана."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Та утсыг тайлах гэж <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу оролдлоо. <xliff:g id="NUMBER_1">%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="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_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_checking_password" msgid="7114627351286933867">"Шалгаж байна..."</string>
+    <string name="lockscreen_unlock_label" msgid="737440483220667054">"Тайлах"</string>
+    <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Дуу идэвхтэй"</string>
+    <string name="lockscreen_sound_off_label" msgid="996822825154319026">"Дууг хаагдсан"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Хээ эхэлж байна"</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Хээ цэвэрлэгдэв"</string>
+    <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Нүд нэмэгдсэн"</string>
+    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Хээ дуусав"</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_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_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>
+    <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_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>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"АБВ"</string>
+    <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_line" msgid="5764267235026120888">"Мөр"</string>
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
+    <string name="factorytest_failed" msgid="5410270329114212041">"Үйлдлвэрийн тест бүтэлгүйтэв"</string>
+    <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST үйлдэл нь зөвхөн /system/app-д суусан багцуудад дэмжигдэнэ."</string>
+    <string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST үйлдлийг хангах багц олдсонгүй."</string>
+    <string name="factorytest_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="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>
+    <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
+    <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
+    <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
+    <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
+    <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">"ZIP код"</string>
+    <string name="autofill_county" msgid="237073771020362891">"Муж"</string>
+    <string name="autofill_island" msgid="4020100875984667025">"Арал"</string>
+    <string name="autofill_district" msgid="8400735073392267672">"Дүүрэг"</string>
+    <string name="autofill_department" msgid="5343279462564453309">"Хэлтэс"</string>
+    <string name="autofill_prefecture" msgid="2028499485065800419">"Муж"</string>
+    <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="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_packageVerificationAgent" msgid="5568139100645829117">"багцийг тулгах"</string>
+    <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"Апп нь багцыг суулгаж болох эсэхийг шалгах боломжтой."</string>
+    <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"багц тулгагчтэй холбох"</string>
+    <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Эзэмшигч нь багц тулгагчдад хүсэлт тавих боломжтой. Энгийн апп-д хэрэглэгдэхгүй."</string>
+    <string name="permlab_serialPort" msgid="546083327654631076">"сериал портруу хандах"</string>
+    <string name="permdesc_serialPort" msgid="2991639985224598193">"Эзэмшигч нь SerialManager API ашиглан сериал портод хандах боломжтой."</string>
+    <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"контент нийлүүлэгчид гаднаас хандах"</string>
+    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Эзэмшигч нь шелээс контент нийлүүлэгчид хандах боломжтой. Энгийн апп-с хэрэглэхгүй."</string>
+    <string name="permlab_updateLock" msgid="3527558366616680889">"төхөөрөмжийн автомат шинэчлэлтийг хориглох"</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"Эзэмшигч нь төхөөрөмжийг дэвшүүлэхээр хэзээ дахин асаавал тохирох тухай системд мэдээлэл санал болгох боломжтой."</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>
+    <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="menu_space_shortcut_label" msgid="2410328639272162537">"зай"</string>
+    <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"оруулах"</string>
+    <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"устгах"</string>
+    <string name="search_go" msgid="8298016669822141719">"Хайх"</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="oneMonthDurationPast" msgid="7396384508953779925">"1 сарын өмнө"</string>
+    <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"1 сарын өмнө"</string>
+  <plurals name="num_seconds_ago">
+    <item quantity="one" msgid="4869870056547896011">"1 секундын өмнө"</item>
+    <item quantity="other" msgid="3903706804349556379">"<xliff:g id="COUNT">%d</xliff:g> секундын өмнө"</item>
+  </plurals>
+  <plurals name="num_minutes_ago">
+    <item quantity="one" msgid="3306787433088810191">"1 минутын өмнө"</item>
+    <item quantity="other" msgid="2176942008915455116">"<xliff:g id="COUNT">%d</xliff:g> минутын өмнө"</item>
+  </plurals>
+  <plurals name="num_hours_ago">
+    <item quantity="one" msgid="9150797944610821849">"1 цагийн өмнө"</item>
+    <item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> цагийн өмнө"</item>
+  </plurals>
+  <plurals name="last_num_days">
+    <item quantity="other" msgid="3069992808164318268">"Сүүлийн <xliff:g id="COUNT">%d</xliff:g> өдөр"</item>
+  </plurals>
+    <string name="last_month" msgid="3959346739979055432">"Сүүлийн сар"</string>
+    <string name="older" msgid="5211975022815554840">"Хуучин"</string>
+  <plurals name="num_days_ago">
+    <item quantity="one" msgid="861358534398115820">"өчигдөр"</item>
+    <item quantity="other" msgid="2479586466153314633">"<xliff:g id="COUNT">%d</xliff:g> өдрийн өмнө"</item>
+  </plurals>
+  <plurals name="in_num_seconds">
+    <item quantity="one" msgid="2729745560954905102">"1 секундын дараа"</item>
+    <item quantity="other" msgid="1241926116443974687">"<xliff:g id="COUNT">%d</xliff:g> секундын дараа"</item>
+  </plurals>
+  <plurals name="in_num_minutes">
+    <item quantity="one" msgid="8793095251325200395">"1 минутын дараа"</item>
+    <item quantity="other" msgid="3330713936399448749">"<xliff:g id="COUNT">%d</xliff:g> минутын дараа"</item>
+  </plurals>
+  <plurals name="in_num_hours">
+    <item quantity="one" msgid="7164353342477769999">"1 цагийн дараа"</item>
+    <item quantity="other" msgid="547290677353727389">"<xliff:g id="COUNT">%d</xliff:g> цагийн дараа"</item>
+  </plurals>
+  <plurals name="in_num_days">
+    <item quantity="one" msgid="5413088743009839518">"маргааш"</item>
+    <item quantity="other" msgid="5109449375100953247">"<xliff:g id="COUNT">%d</xliff:g> өдрийн дараа"</item>
+  </plurals>
+  <plurals name="abbrev_num_seconds_ago">
+    <item quantity="one" msgid="1849036840200069118">"1 секундын өмнө"</item>
+    <item quantity="other" msgid="3699169366650930415">"<xliff:g id="COUNT">%d</xliff:g> сек дараа"</item>
+  </plurals>
+  <plurals name="abbrev_num_minutes_ago">
+    <item quantity="one" msgid="6361490147113871545">"1 мин өмнө"</item>
+    <item quantity="other" msgid="851164968597150710">"<xliff:g id="COUNT">%d</xliff:g> минутын өмнө"</item>
+  </plurals>
+  <plurals name="abbrev_num_hours_ago">
+    <item quantity="one" msgid="4796212039724722116">"1 цагийн өмнө"</item>
+    <item quantity="other" msgid="6889970745748538901">"<xliff:g id="COUNT">%d</xliff:g> цагийн өмнө"</item>
+  </plurals>
+  <plurals name="abbrev_num_days_ago">
+    <item quantity="one" msgid="8463161711492680309">"өчигдөр"</item>
+    <item quantity="other" msgid="3453342639616481191">"<xliff:g id="COUNT">%d</xliff:g> өдрийн өмнө"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_seconds">
+    <item quantity="one" msgid="5842225370795066299">"1 сек дараа"</item>
+    <item quantity="other" msgid="5495880108825805108">"<xliff:g id="COUNT">%d</xliff:g> сек дараа"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_minutes">
+    <item quantity="one" msgid="562786149928284878">"1 мин дараа"</item>
+    <item quantity="other" msgid="4216113292706568726">"<xliff:g id="COUNT">%d</xliff:g> минутын дараа"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_hours">
+    <item quantity="one" msgid="3274708118124045246">"1 цагийн дараа"</item>
+    <item quantity="other" msgid="3705373766798013406">"<xliff:g id="COUNT">%d</xliff:g> цагийн дараа"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_days">
+    <item quantity="one" msgid="2178576254385739855">"маргааш"</item>
+    <item quantity="other" msgid="2973062968038355991">"<xliff:g id="COUNT">%d</xliff:g> өдрийн дараа"</item>
+  </plurals>
+    <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>
+    <string name="days" msgid="4774547661021344602">"өдөр"</string>
+    <string name="hour" msgid="2126771916426189481">"цаг"</string>
+    <string name="hours" msgid="894424005266852993">"цаг"</string>
+    <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="week" msgid="5617961537173061583">"7 хоног"</string>
+    <string name="weeks" msgid="6509623834583944518">"7 хоног"</string>
+    <string name="year" msgid="4001118221013892076">"жил"</string>
+    <string name="years" msgid="6881577717993213522">"жил"</string>
+  <plurals name="duration_seconds">
+    <item quantity="one" msgid="6962015528372969481">"1 секунд"</item>
+    <item quantity="other" msgid="1886107766577166786">"<xliff:g id="COUNT">%d</xliff:g> секунд"</item>
+  </plurals>
+  <plurals name="duration_minutes">
+    <item quantity="one" msgid="4915414002546085617">"1 минут"</item>
+    <item quantity="other" msgid="3165187169224908775">"<xliff:g id="COUNT">%d</xliff:g> минут"</item>
+  </plurals>
+  <plurals name="duration_hours">
+    <item quantity="one" msgid="8917467491248809972">"1 цаг"</item>
+    <item quantity="other" msgid="3863962854246773930">"<xliff:g id="COUNT">%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_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>
+    <string name="midnight" msgid="7166259508850457595">"шөнө дунд"</string>
+    <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="cut" msgid="3092569408438626261">"Таслах"</string>
+    <string name="copy" msgid="2681946229533511987">"Хуулах"</string>
+    <string name="paste" msgid="5629880836805036433">"Буулгах"</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="textSelectionCABTitle" msgid="5236850394370820357">"Текст сонгох"</string>
+    <string name="addToDictionary" msgid="4352161534510057874">"Толь бичигт нэмэх"</string>
+    <string name="deleteText" msgid="6979668428458199034">"Устгах"</string>
+    <string name="inputMethod" msgid="1653630062304567879">"Оруулах арга"</string>
+    <string name="editTextMenuTitle" msgid="4909135564941815494">"Текст үйлдэл"</string>
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Сангийн хэмжээ дутагдаж байна"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Зарим систем функц ажиллахгүй байна"</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="4653586947747330058">"Илүү мэдээлэл авах бол хүрэх эсвэл апп-г зогсооно уу ."</string>
+    <string name="ok" msgid="5970060430562524910">"Тийм"</string>
+    <string name="cancel" msgid="6442560571259935130">"Цуцлах"</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>
+    <string name="capital_on" msgid="1544682755514494298">"Идэвхтэй"</string>
+    <string name="capital_off" msgid="6815870386972805832">"Идэвхгүй"</string>
+    <string name="whichApplication" msgid="4533185947064773386">"Үйлдлийг дуусгах"</string>
+    <string name="alwaysUse" msgid="4583018368000610438">"Энэ ажиллагааг үндсэн болгох."</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="aerr_title" msgid="1905800560317137752"></string>
+    <string name="aerr_application" msgid="932628488013092776">"Харамсалтай, <xliff:g id="APPLICATION">%1$s</xliff:g> зогссон."</string>
+    <string name="aerr_process" msgid="4507058997035697579">"Харамсалтай нь <xliff:g id="PROCESS">%1$s</xliff:g> процесс зогссон."</string>
+    <string name="anr_title" msgid="4351948481459135709"></string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> хариу өгөхгүй байна.\n\nТа хаамаар байна уу?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"<xliff:g id="ACTIVITY">%1$s</xliff:g> активити хариу өгөхгүй байна.\n\nТа энийг хаах уу?"</string>
+    <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> хариу өгөхгүй байна. Та энийг хаамаар байна уу?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"<xliff:g id="PROCESS">%1$s</xliff:g> процесс хариу өгөхгүй байн.\n\nТа хаамаар байна уу?"</string>
+    <string name="force_close" msgid="8346072094521265605">"Тийм"</string>
+    <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">"Aпп дахин чиглүүлэгдэв"</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; Апп &gt; Татаж авсан дотроос дахин идэвхтэй болгох боломжтой."</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>
+    <string name="android_upgrading_title" msgid="1584192285441405746">"Андройдыг дэвшүүлж байна…"</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_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="1721681741617898865">"Апп сэлгэх бол хүрнэ үү"</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>
+    <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="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_silent_ringtone_selected" msgid="8310739960973156272">"Хонхны дууг чимээгүй болгов"</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">"Блютүүтын хэмжээ"</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="8129563480895990372">"Үндсэн хонхны ая (<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_unknown" msgid="5477919988701784788">"Үл мэдэгдэх хонхны ая"</string>
+  <plurals name="wifi_available">
+    <item quantity="one" msgid="6654123987418168693">"Wi-Fi сүлжээ ашиглах боломжтой"</item>
+    <item quantity="other" msgid="4192424489168397386">"Wi-Fi сүлжээ ашиглах боломжгүй"</item>
+  </plurals>
+  <plurals name="wifi_available_detailed">
+    <item quantity="one" msgid="1634101450343277345">"Нээллтэй Wi-Fi сүлжээ ашиглах боломжтой"</item>
+    <item quantity="other" msgid="7915895323644292768">"Нээлттэй Wi-Fi сүлжээ ашиглах боломжтой"</item>
+  </plurals>
+    <string name="wifi_available_sign_in" msgid="4029489716605255386">"Wi-Fi сүлжээнд нэвтэрнэ үү"</string>
+    <string name="network_available_sign_in" msgid="8495155593358054676">"Сүлжээнд нэвтрэх"</string>
+    <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
+    <skip />
+    <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi-д холбогдож чадсангүй"</string>
+    <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" Интернет холболт муу байна."</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_enabled_notification_message" msgid="1638949953993894335">"Тохируулах бол хүрнэ үү"</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_to_connect_title" msgid="4958803948658533637">"Холбох урилга"</string>
+    <string name="wifi_p2p_from_message" msgid="570389174731951769">"Хэнээс:"</string>
+    <string name="wifi_p2p_to_message" msgid="248968974522044099">"Хэнд:"</string>
+    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"Шаардлагатай PIN-г бичнэ үү:"</string>
+    <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</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="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_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="3492025719868078457">"Энэ таны мобайл акаунтад "<font fgcolor="#ffffb060">"төлбөр гаргаж"</font>" болзошгүй."</string>
+    <string name="sms_premium_short_code_details" msgid="5523826349105123687"><font fgcolor="#ffffb060">"Энэ таны мобайл акаунтад төлбөр гаргах болно."</font></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_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_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="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_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="usb_storage_activity_title" msgid="4465055157209648641">"USB масс сан"</string>
+    <string name="usb_storage_title" msgid="5901459041398751495">"USB холбогдсон"</string>
+    <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"Та өөрийн компьютертээ USB-р холбогдсон байна. Хэрэв та өөрийн компьютер болон өөрийн Андройдын USB сан хооронд файл хуулах бол доорх товчинд хүрнэ үү."</string>
+    <string name="usb_storage_message" product="default" msgid="805351000446037811">"Та өөрийн компьютертээ USB-р холбогдсон байна. Хэрэв та өөрийн компьютер болон өөрийн Андройдын USB сан хооронд файл хуулах бол доорх товчинд хүрнэ үү."</string>
+    <string name="usb_storage_button_mount" msgid="1052259930369508235">"USB санг асаах"</string>
+    <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"USB санг USB масс сан болгон ашиглахад алдаа гарав."</string>
+    <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"SD картыг USB масс сан болгон ашиглахад алдаа гарав."</string>
+    <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB холбогдсон"</string>
+    <string name="usb_storage_notification_message" msgid="939822783828183763">"Өөрийн компьютер- ээс/луу файл хуулах бол хүрнэ үү"</string>
+    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"USB санг унтраах"</string>
+    <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"USB санг унтраах бол хүрнэ үү."</string>
+    <string name="usb_storage_stop_title" msgid="660129851708775853">"USB сан ашиглагдаж байна"</string>
+    <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"USB санг унтраахаас өмнө өөрийн Андройдын SD картыг компьютерээсээ салгана(\"гаргана\") уу."</string>
+    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"USB санг унтраахаас өмнө өөрийн Андройдын SD картыг компьютерээсээ салгана(\"гаргана\") уу."</string>
+    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"USB санг унтраах"</string>
+    <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"USB санг унтраахад алдаа гарав. USB хостоо салгасан эсэхээ шалгаад дахин оролдоно уу."</string>
+    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"USB санг асаах"</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Хэрэв та USB санг асуувал таны ашиглаж байга зарим апп зогсох ба та USB сангаа унтраатал ашиглах боломжгүй байж болзошгүй."</string>
+    <string name="dlg_error_title" msgid="7323658469626514207">"USB ажиллагаа бүтэлгүйтэв"</string>
+    <string name="dlg_ok" msgid="7376953167039865701">"Тийм"</string>
+    <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Медиа төхөөрөмж болон холбогдов"</string>
+    <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Камер болгон холбов"</string>
+    <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Суулгагч болгон холбогдсон"</string>
+    <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB төхөөрөмжид холбогдов"</string>
+    <string name="usb_notification_message" msgid="2290859399983720271">"Бусад USB сонголт хийх бол хүрнэ үү."</string>
+    <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB санг форматлах уу?"</string>
+    <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD картыг форматлах уу?"</string>
+    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Таны USB санд хадгалагдсан бүх файл арилгагдана. Энэ үйлдлийг буцаах боломжгүй!"</string>
+    <string name="extmedia_format_message" product="default" msgid="14131895027543830">"Таны картан дээрх бүх дата устах болно."</string>
+    <string name="extmedia_format_button_format" msgid="4131064560127478695">"Форматлах"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"USB дебаг холбогдсон"</string>
+    <string name="adb_active_notification_message" msgid="1016654627626476142">"USB дебаг хийхийг идэвхгүй болгох бол хүрнэ үү."</string>
+    <string name="select_input_method" msgid="4653387336791222978">"Оруулах аргыг сонгоно уу"</string>
+    <string name="configure_input_methods" msgid="9091652157722495116">"Оруулах аргыг тохируулах"</string>
+    <string name="use_physical_keyboard" msgid="6203112478095117625">"Бодит гар"</string>
+    <string name="hardware" msgid="7517821086888990278">"Хардвер"</string>
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Гарын схемийг сонгох"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Гарын схемийг сонгох бол хүрнэ үү."</string>
+    <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="candidates_style" msgid="4333913089637062257"><u>"нэр дэвшигч"</u></string>
+    <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"USB санг бэлдэж байна"</string>
+    <string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"SD карт бэлдэж байна"</string>
+    <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"Алдааг шалгаж байна."</string>
+    <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"Хоосон USB сан"</string>
+    <string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"Хоосон SD карт"</string>
+    <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"USB сан хоосон эсвэл дэмжигдэхгүй файл системтэй."</string>
+    <string name="ext_media_nofs_notification_message" product="default" msgid="8641065641786923604">"SD карт хоосон эсвэл дэмжигдэхгүй файл систем."</string>
+    <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"Гэмтсэн USB сан"</string>
+    <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"Гэмтсэн SD карт"</string>
+    <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="1795917578395333280">"USB сан гэмтсэн байна. Дахин форматлаж үзнэ үү."</string>
+    <string name="ext_media_unmountable_notification_message" product="default" msgid="1753898567525568253">"SD карт гэмтсэн байна. Дахин форматлаж үзнэ үү."</string>
+    <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"USB санг санамсаргүй хасагдав"</string>
+    <string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"SD карт санамсаргүй хасагдав"</string>
+    <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"Дата хохирлоос сэргийлж USB санг сугалахаасаа өмнө салгаж байна уу."</string>
+    <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"Дата хохирлоос сэргийлж SD картыг хасахаасаа өмнө салгаж байна уу."</string>
+    <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"USB санг салгаж авахад аюулгүй."</string>
+    <string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"SD картыг хасахад аюулгүй"</string>
+    <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"USB санг сугалахад аюулгүй."</string>
+    <string name="ext_media_safe_unmount_notification_message" product="default" msgid="568841278138377604">"SD картаа салгаж авах аюулгүй."</string>
+    <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"Хасагдсан USB сан"</string>
+    <string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"Сугалсан SD карт"</string>
+    <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"USB сан сугалагдав. Шинэ медиаг хийнэ үү."</string>
+    <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"SD карт хасагдав. Шинийг хийнэ үү."</string>
+    <string name="activity_list_empty" msgid="1675388330786841066">"Таарах активити олдсонгүй."</string>
+    <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"компонент ашиглалтын статистикийг шинэчлэх"</string>
+    <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"Апп нь компонент хэрэглээний цуглуулагдсан статистикийг өөрчлөх боломжтой. Энгийн апп-д шаардлагагүй."</string>
+    <string name="permlab_copyProtectedData" msgid="4341036311211406692">"контент хуулах"</string>
+    <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Апп нь контентыг хуулах үндсэн контейнер үйлчилгээг дуудах боломжтой. Энгийн апп-д ашиглах боломжгүй."</string>
+    <string name="permlab_route_media_output" msgid="1642024455750414694">"Медиа гаралтыг чиглүүлэх"</string>
+    <string name="permdesc_route_media_output" msgid="4932818749547244346">"Аппликешн нь медиа гаралтыг бусад гадаад төхөөрөмжрүү чиглүүлэх боломжтой."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Түлхүүр хамгаалах аюулгүй санд хандах"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Аппликешн нь хамгаалалттай аюулгүй санд хандах боломжтой."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Түлхүүр хамгаалалтын харуулах болон далдлахыг удирдах"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Аппликешн нь түлхүүр хамгаалагчыг удирдах боломжтой."</string>
+    <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Өсгөх контрол дээр хоёр удаа товшино уу"</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>
+    <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_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="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>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"Ханын зураг солих"</string>
+    <string name="notification_listener_binding_label" msgid="2014162835481906429">"Мэдэгдэл сонсогч"</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="3011306607126450322">"Сүлжээг удирдах бол хүрнэ үү."</string>
+    <string name="vpn_text_long" msgid="6407351006249174473">"<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_error" msgid="6009249814034708175">"Байнгын VPN алдаа"</string>
+    <string name="vpn_lockdown_config" msgid="6415899150671537970">"Тохируулах бол хүрнэ үү"</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="8035230537563503262">"Машины горимоос гарах бол хүрнэ үү."</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"Модем болгох эсвэл идэвхтэй цэг болгох"</string>
+    <string name="tethered_notification_message" msgid="6857031760103062982">"Тохируулах бол хүрнэ үү."</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="throttle_warning_notification_title" msgid="4890894267454867276">"Мобайл дата хэрэглээ өндөр"</string>
+    <string name="throttle_warning_notification_message" msgid="3340822228599337743">"Мобайл дата хэрэглээний талаар дэлгэрэнгүй үзэх бол хүрнэ үү"</string>
+    <string name="throttled_notification_title" msgid="6269541897729781332">"Мобайл дата хязгаар хэтрэв"</string>
+    <string name="throttled_notification_message" msgid="5443457321354907181">"Мобайл дата хэрэглээний талаар дэлгэрэнгүй үзэх бол хүрнэ үү"</string>
+    <string name="no_matches" msgid="8129421908915840737">"Илэрц алга"</string>
+    <string name="find_on_page" msgid="1946799233822820384">"Хуудаснаас олох"</string>
+  <plurals name="matches_found">
+    <item quantity="one" msgid="8167147081136579439">"1 утга"</item>
+    <item quantity="other" msgid="4641872797067609177">"<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="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"USB санг салгаж байна…"</string>
+    <string name="progress_unmounting" product="default" msgid="1327894998409537190">"SD картыг салгаж байна…"</string>
+    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"USB санг арилгаж байна…"</string>
+    <string name="progress_erasing" product="default" msgid="6596988875507043042">"SD картыг цэвэрлэж байна…"</string>
+    <string name="format_error" product="nosdcard" msgid="6299769563624776948">"USB санг арилгаж чадсангүй."</string>
+    <string name="format_error" product="default" msgid="7315248696644510935">"SD картыг арилгаж чадсангүй."</string>
+    <string name="media_bad_removal" msgid="7960864061016603281">"SD картыг салгалгүйгээр хассан байна."</string>
+    <string name="media_checking" product="nosdcard" msgid="418188720009569693">"USB санг одоо шалгаж байна."</string>
+    <string name="media_checking" product="default" msgid="7334762503904827481">"SD картыг одоо шалгаж байна."</string>
+    <string name="media_removed" msgid="7001526905057952097">"SD картыг сугалсан байна."</string>
+    <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"USB санг одоо компьютерээс ашиглаж байна."</string>
+    <string name="media_shared" product="default" msgid="5706130568133540435">"USB санг одоо компьютерээс ашиглаж байна."</string>
+    <string name="media_unknown_state" msgid="729192782197290385">"Гадаад медиа үл мэдэгдэх статустай байна."</string>
+    <string name="share" msgid="1778686618230011964">"Хуваалцах"</string>
+    <string name="find" msgid="4808270900322985960">"Олох"</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="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_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>
+    <string name="add_account_button_label" msgid="3611982894853435874">"Аккаунт нэмэх"</string>
+    <string name="number_picker_increment_button" msgid="2412072272832284313">"Өсөх"</string>
+    <string name="number_picker_decrement_button" msgid="476050778386779067">"Бууруулах"</string>
+    <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> хүрээд барина уу."</string>
+    <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Өсгөх бол дээшээ бууруулах бол доошоо гулсуулна уу."</string>
+    <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Минут өсгөх"</string>
+    <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Минутыг бууруулах"</string>
+    <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Цаг өсгөх"</string>
+    <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Цаг бууруулах"</string>
+    <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"PM тохируулах"</string>
+    <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"AM тохируулах"</string>
+    <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Сар өсгөх"</string>
+    <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Сарыг бууруулах"</string>
+    <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Өдөр өсгөх"</string>
+    <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Өдрийг бууруулах"</string>
+    <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Жилийг өсгөх"</string>
+    <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Жил бууруулах"</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">"Шифт"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Оруулах"</string>
+    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Апп сонгох"</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">"Бариулыг гулсуулна. Хүрээд хүлээнэ."</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-г гулсуулах."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"<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="description_direction_right" msgid="8034433242579600980">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> хийх бол баруунлуу гулсуулах."</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Тайлах"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Камер"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Чимээгүй"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Дуунууд идэвхтэй"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Хайх"</string>
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Түгжээг тайлах бол татна уу"</string>
+    <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Нууц үгний дуудлагыг сонсох бол чихэвчийг залгана уу."</string>
+    <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Цэг."</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="4891916833657929263">"Дотоод сан"</string>
+    <string name="storage_sd_card" msgid="3282948861378286745">"SD карт"</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="1955638862122232342">"Дата хэрэглээний анхааруулга"</string>
+    <string name="data_usage_warning_body" msgid="2814673551471969954">"Ашиглалт болон тохиргоог харах бол хүрнэ үү."</string>
+    <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-3G дата идэвхгүй болов"</string>
+    <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G дата идэвхгүй байна"</string>
+    <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Мобайл дата идэвхгүй"</string>
+    <string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"Wi-Fi дата идэвхгүй"</string>
+    <string name="data_usage_limit_body" msgid="3317964706973601386">"Идэвхжүүлэх бол хүрнэ үү."</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_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="6741521330997452990">"Хязгаарлалтыг хасах бол хүрнэ үү."</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>
+    <string name="org_unit" msgid="7265981890422070383">"Байгууллагын нэгж:"</string>
+    <string name="issued_by" msgid="2647584988057481566">"Гаргасан:"</string>
+    <string name="validity_period" msgid="8818886137545983110">"Хүчинтэй байх:"</string>
+    <string name="issued_on" msgid="5895017404361397232">"Гаргасан:"</string>
+    <string name="expires_on" msgid="3676242949915959821">"Хүртэл хүчинтэй:"</string>
+    <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>
+    <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Бүгдийг харах"</string>
+    <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Активити сонгох"</string>
+    <string name="share_action_provider_share_with" msgid="5247684435979149216">"Хуваалцах"</string>
+    <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="3245653681008218030">"Илгээж байна ..."</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="default_audio_route_name" product="tablet" msgid="4617053898167127471">"Таблет"</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">"Блютүүт аудио"</string>
+    <string name="wireless_display_route_description" msgid="9070346425023979651">"Утасгүй дэлгэц"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Дууссан"</string>
+    <string name="media_route_button_content_description" msgid="5758553567065145276">"Медиа гаралт"</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>
+    <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_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="wifi_display_notification_title" msgid="2223050649240326557">"Утасгүй дэлгэц холбогдов"</string>
+    <string name="wifi_display_notification_message" msgid="4498802012464170685">"Энэ дэлгэц өөр төхөөрөмжийг харуулж байна"</string>
+    <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Салгах"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Яаралтай дуудлага"</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">"PIN буруу"</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">"SIM PIN оруулна уу"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN оруулна уу"</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">"Хүссэн PIN кодоо оруулна уу"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Хүссэн PIN кодоо дахин оруулна уу"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM картны түгжээг гаргаж байна…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Буруу PIN код."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4-8 тооноос бүтэх PIN-г бичнэ үү."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK код 8-с цөөнгүй тооноос бүтнэ."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Зөв PUK кодыг дахин оруулна уу. Давтан оролдвол SIM нь бүрмөсөн идэвхгүй болгоно."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN кодууд таарахгүй байна"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Хээ оруулах оролдлого хэт олон"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Түгжээг тайлах бол Google акаунтаараа нэвтэрнэ үү."</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"Акаунт шалгаж байна…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Та PIN кодоо <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу бичив. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Та PIN кодоо <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу бичив. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Та тайлах хээг <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу зурлаа. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Та таблетыг тайлах гэж <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу оролдлоо. <xliff:g id="NUMBER_1">%d</xliff:g> удаа дахин буруу оролдвол таблет үйлдвэрийн үндсэн утгаараа тохируулагдах ба хэрэглэгчийн дата бүхэлдээ устана."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Та утсыг тайлах гэж <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу оролдлоо. <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> удаа буруу зурлаа. <xliff:g id="NUMBER_1">%d</xliff:g> удаа дахин буруу оруулбал, та таблетаа тайлахын тулд имэйл акаунт шаардлагатай болно.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Та тайлах хээг <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу зурлаа. <xliff:g id="NUMBER_1">%d</xliff:g> удаа дахин буруу оруулбал, та утсаа тайлахын тулд имэйл акаунтаа ашиглах шаардлагатай болно.\n\n <xliff:g id="NUMBER_2">%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="7324161939475478066">"Дууг санал болгосон дээд төвшинөөс өсгөх үү. \n Өндөр дуугаар урт хугацаанд сонсох нь таны сонсголд хортой."</string>
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Хялбар горимыг идэвхжүүлэх бол хоёр хуруугаараа доошлуулаад хүлээнэ үү."</string>
+    <string name="accessibility_enabled" msgid="1381972048564547685">"Хялбаршуулсан горим идэвхжив."</string>
+    <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Хандалт цуцлагдсан."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Одоогийн хэрэглэгч <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="app_no_restricted_accounts" msgid="5739463249673727736">"Энэ аппликешн хязгаарлагдсан профайлын акаунтыг дэмжихгүй."</string>
+    <string name="app_not_found" msgid="3429141853498927379">"Энэ ажиллагааг зохицуулах аппликешн олдсонгүй."</string>
+    <string name="revoke" msgid="5404479185228271586">"Цуцлах"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Цуцлагдсан"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Контентыг бичих явцад алдаа гарсан"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"тодорхойгүй"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Админ 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>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Шинэ PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Шинэ PIN-г баталгаажуулах"</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_too_short" msgid="8173982756265777792">"PIN хэт богино байна. Хамгийн багадаа 4 цифртэй байх ёстой."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"1 секундын дараа дахин оролдоно уу"</item>
+    <item quantity="other" msgid="4730868920742952817">"<xliff:g id="COUNT">%d</xliff:g> секундын дараа дахин оролдоно уу"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Дараа дахин оролдоно уу"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Баганыг харуулахын тулд дэлгэцийн ирмэгийг шудрана уу"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Системийн баганыг гаргахын тулд дэлгэцийн ирмэгээс шудрана уу"</string>
+</resources>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
new file mode 100644
index 0000000..67ec195
--- /dev/null
+++ b/core/res/res/values-mn/strings.xml
@@ -0,0 +1,1584 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<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="5973789783504771878">"КБ"</string>
+    <string name="megabyteShort" msgid="6355851576770428922">"МБ"</string>
+    <string name="gigabyteShort" msgid="3259882455212193214">"ГБ"</string>
+    <string name="terabyteShort" msgid="231613018159186962">"TБ"</string>
+    <string name="petabyteShort" msgid="5637816680144990219">"ПБ"</string>
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
+    <string name="untitled" msgid="4638956954852782576">"&lt;Гарчиггүй&gt;"</string>
+    <string name="ellipsis" msgid="7899829516048813237">"…"</string>
+    <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
+    <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Утасны дугаар байхгүй)"</string>
+    <string name="unknownName" msgid="2277556546742746522">"(Тодорхойгүй)"</string>
+    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"дуут шуудан"</string>
+    <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
+    <string name="mmiError" msgid="5154499457739052907">"Холболтын асуудал эсвэл буруу MMI код."</string>
+    <string name="mmiFdnError" msgid="5224398216385316471">"Ажиллагаа зөвөх тогтсон дугаараар хязгаарлагдсан."</string>
+    <string name="serviceEnabled" msgid="8147278346414714315">"Үйлчилгээ идэвхжсэн."</string>
+    <string name="serviceEnabledFor" msgid="6856228140453471041">"Дараах үйлчилгээ идэвхтэй болсон:"</string>
+    <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="mmiComplete" msgid="8232527495411698359">"MMI дууссан."</string>
+    <string name="badPin" msgid="9015277645546710014">"Таны бичсэн хуучин PIN буруу байна."</string>
+    <string name="badPuk" msgid="5487257647081132201">"Таны бичсэн PUК буруу байна."</string>
+    <string name="mismatchPin" msgid="609379054496863419">"Таны оруулсан PIN таарахгүй байна."</string>
+    <string name="invalidPin" msgid="3850018445187475377">"4-8 тооноос бүтэх PIN-г бичнэ үү."</string>
+    <string name="invalidPuk" msgid="8761456210898036513">"8-с цөөнгүй тооноос бүтэх PUK-г бичнэ үү."</string>
+    <string name="needPuk" msgid="919668385956251611">"SIM картны PUK-түгжигдсэн. Тайлах бол PUK кодыг бичнэ үү."</string>
+    <string name="needPuk2" msgid="4526033371987193070">"SIM картын хаалтыг болиулах бол PUK2-г бичнэ үү."</string>
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
+    <string name="ClipMmi" msgid="6952821216480289285">"Дуудлага хийгчийн ID"</string>
+    <string name="ClirMmi" msgid="7784673673446833091">"Гарч байгаа дуудлага хийгчийн ID"</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">"PIN солих"</string>
+    <string name="CnipMmi" msgid="3110534680557857162">"Дуудсан дугаар харуулах"</string>
+    <string name="CnirMmi" msgid="3062102121430548731">"Дуудлага хийгчийн дугаар хязгаарлагдсан"</string>
+    <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="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="RestrictedChangedTitle" msgid="5592189398956187498">"Хязгаарлагдсан хандалт өөрчлөгдөв"</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="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>
+    <string name="serviceClassDataSync" msgid="7530000519646054776">"Синк"</string>
+    <string name="serviceClassPacket" msgid="6991006557993423453">"Пакет"</string>
+    <string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
+    <string name="roamingText0" msgid="7170335472198694945">"Роуминг заагч ассан"</string>
+    <string name="roamingText1" msgid="5314861519752538922">"Роуминг заагч унтарсан"</string>
+    <string name="roamingText2" msgid="8969929049081268115">"Роуминг заагч анивчиж байна"</string>
+    <string name="roamingText3" msgid="5148255027043943317">"Хөрш дотор"</string>
+    <string name="roamingText4" msgid="8808456682550796530">"Барилгын гадна"</string>
+    <string name="roamingText5" msgid="7604063252850354350">"Роуминг - Сонгогдсон Систем"</string>
+    <string name="roamingText6" msgid="2059440825782871513">"Роуминг- Боломжтой Систем"</string>
+    <string name="roamingText7" msgid="7112078724097233605">"Роуминг- Холбоотон Түнш"</string>
+    <string name="roamingText8" msgid="5989569778604089291">"Роуминг- Урамшууллын Түнш"</string>
+    <string name="roamingText9" msgid="7969296811355152491">"Рүүминг - Үйлчилгээний Ажиллагаа Бүрэн"</string>
+    <string name="roamingText10" msgid="3992906999815316417">"Рүүминг - Хэсэгчилсэн үйлчилгээний функционал"</string>
+    <string name="roamingText11" msgid="4154476854426920970">"Рүүминг Баннер Асаалттай"</string>
+    <string name="roamingText12" msgid="1189071119992726320">"Баннергүй рүүминг"</string>
+    <string name="roamingTextSearching" msgid="8360141885972279963">"Үйлчилгээг хайж байна…"</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="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="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="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="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="default" msgid="3475999286680000541">"Утасны сан дүүрсэн. Зай чөлөөлөх бол зарим файлыг устгана уу."</string>
+    <string name="me" msgid="6545696007631404292">"Би"</string>
+    <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Таблетын сонголтууд"</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="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="shutdown_progress" msgid="2281079257329981203">"Унтрааж байна…"</string>
+    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Таны таблет унтрах болно."</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="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_bug_report" msgid="7934010578922304799">"Алдаа мэдээллэх"</string>
+    <string name="bugreport_title" msgid="2667494803742548533">"Согог репорт авах"</string>
+    <string name="bugreport_message" msgid="398447048750350456">"Энэ таны төхөөрөмжийн одоогийн статусын талаарх мэдээллийг цуглуулах ба имэйл мессеж болгон илгээнэ. Алдааны мэдэгдлээс эхэлж илгээхэд бэлэн болоход хэсэг хугацаа зарцуулагдана тэвчээртэй байна уу."</string>
+    <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_airplane_mode_on_status" msgid="2719557982608919750">"Нислэгийн горим асав"</string>
+    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Нислэгийн горим унтарсан"</string>
+    <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
+    <string name="safeMode" msgid="2788228061547930246">"Аюулгүй горим"</string>
+    <string name="android_system_label" msgid="6577375335728551336">"Андройд систем"</string>
+    <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Танаас төлбөр авдаг үйлчилгээнүүд"</string>
+    <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Таны төлбөрт оруулах зүйлийг хийх."</string>
+    <string name="permgrouplab_messages" msgid="7521249148445456662">"Таны мессеж"</string>
+    <string name="permgroupdesc_messages" msgid="7821999071003699236">"Таны SMS, и-мэйл ба бусад мессежийг унших болон бичих."</string>
+    <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Таны хувийн мэдээлэл"</string>
+    <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"Таны харилцагчдын картанд хадгалагдсан таны мэдээлэлд шууд хандах."</string>
+    <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Таны нийтийн мэдээлэл"</string>
+    <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Таны харилцагчид болон нийтийн холбооны тухай мэдээлэлд шууд хандах."</string>
+    <string name="permgrouplab_location" msgid="635149742436692049">"Таны байршил"</string>
+    <string name="permgroupdesc_location" msgid="5704679763124170100">"Таны бодит байршлыг хянах."</string>
+    <string name="permgrouplab_network" msgid="5808983377727109831">"Сүлжээний холбоо"</string>
+    <string name="permgroupdesc_network" msgid="4478299413241861987">"Төрөл бүрийн сүлжээний функцүүдэд хандах"</string>
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"Блютүүт"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"Блютүүтээр төхөөрөмж болон сүлжээнд хандах."</string>
+    <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"Аудио тохиргоо"</string>
+    <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"Аудио тохиргоо солих."</string>
+    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Батерейд нөлөөлөх"</string>
+    <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Батерей хурдан дуусгах функцийг ашиглах."</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"Календарь"</string>
+    <string name="permgroupdesc_calendar" msgid="5777534316982184416">"Календар болон үйл явдалд шууд хандах."</string>
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"Хэрэглэгчийн толиос унших"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"Хэрэглэгчийн толь бичгээс үг унших."</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"Хэрэглэгчийн тольд бичих"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"Хэрэглэгчийн толь бичигт үг нэмэх."</string>
+    <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Хавчуурга болон түүх"</string>
+    <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Хавчуурга болон хөтчийн түүхрүү шууд хандах."</string>
+    <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"Сэрүүлэг"</string>
+    <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"Сэрүүлэг тохируулах."</string>
+    <string name="permgrouplab_voicemail" msgid="4162237145027592133">"Дуут шуудан"</string>
+    <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"Дуут шууданд шууд хандах."</string>
+    <string name="permgrouplab_microphone" msgid="171539900250043464">"Микрофон"</string>
+    <string name="permgroupdesc_microphone" msgid="7106618286905738408">"Аудио бичихийн тулд микрофонд шууд хандах."</string>
+    <string name="permgrouplab_camera" msgid="4820372495894586615">"Камер"</string>
+    <string name="permgroupdesc_camera" msgid="2933667372289567714">"Зураг эвсэл бичлэг хийхээр камерт шууд хандах."</string>
+    <string name="permgrouplab_screenlock" msgid="8275500173330718168">"Дэлгэц түгжих"</string>
+    <string name="permgroupdesc_screenlock" msgid="7067497128925499401">"Таны төхөөрөмжийн дэлгэцийн түгжээнд нөлөөлөх чадвар."</string>
+    <string name="permgrouplab_appInfo" msgid="8028789762634147725">"Таны аппликешны мэдээлэл"</string>
+    <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"Таны төхөөрөмжийн бусад аппликешнд нөлөөлөх чадвар."</string>
+    <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"Ханын зураг"</string>
+    <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"Төхөөрөмжийн ханын зургийн тохиргоог солих."</string>
+    <string name="permgrouplab_systemClock" msgid="406535759236612992">"Цаг"</string>
+    <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"Төхөөрөмжийн цаг эсвэл цагийн бүсийг солих."</string>
+    <string name="permgrouplab_statusBar" msgid="2095862568113945398">"Статус самбар"</string>
+    <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"Төхөөрөмжийн статус самбарын тохиргоог солих."</string>
+    <string name="permgrouplab_syncSettings" msgid="3341990986147826541">"Синк тохиргоо"</string>
+    <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"Синк тохиргоонд хандах."</string>
+    <string name="permgrouplab_accounts" msgid="3359646291125325519">"Таны акаунт"</string>
+    <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Боломжит акаунтад хандах."</string>
+    <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Хардвер контрол"</string>
+    <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Гар төхөөрөмжийн хардверт шууд хандах."</string>
+    <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Утсаар ярих"</string>
+    <string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"Утасны дуудлагыг хянах, бичих болон боловсруулах."</string>
+    <string name="permgrouplab_systemTools" msgid="4652191644082714048">"Системийн багаж"</string>
+    <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"Системрүү доод төвшиний хандах болон удирдах."</string>
+    <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"Хөгжүүлэх багаж"</string>
+    <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"Зөвхөн аппликешн хөгжүүлэгчдэд хэрэгтэй функц."</string>
+    <string name="permgrouplab_display" msgid="4279909676036402636">"Бусад аппликешн UI"</string>
+    <string name="permgroupdesc_display" msgid="6051002031933013714">"Бусад аппликешны UI-д нөлөөлөх."</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"Сан"</string>
+    <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"USB санд хандах."</string>
+    <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"SD картад хандах."</string>
+    <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"Хялбар хандах функц"</string>
+    <string name="permgroupdesc_accessibilityFeatures" msgid="4205196881678144335">"Туслах технологиос хүсэлт илгээх боломжтой функц"</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="5800552516779249356">"Хүрсэн зүйлсийг чангаар дуудах ба дохио ашиглан дэлгэцийг таньж болно."</string>
+    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Сайжруулсан веб хандалтыг асаах"</string>
+    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Апп контентод илүү хялбар хандуулахын тулд скриптыг суулгана."</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Бичсэн текстээ ажиглах"</string>
+    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Кредит картын дугаар болон нууц үг зэрэг хувийн датаг агуулж байна."</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"статус самбарыг идэвхгүй болгох болон өөрчлөх"</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"Апп нь статус самбарыг идэвхгүй болгох эсвэл систем дүрсийг нэмэх, хасах боломжтой."</string>
+    <string name="permlab_statusBarService" msgid="7247281911387931485">"статус самбар"</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_processOutgoingCalls" msgid="3906007831192990946">"гарсан дуудлагыг чиглэлийг өөрчлөх"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Апп нь дуудлага хийх болон залгаж байгаа дугаарыг өөрчлөх боломжтой. Энэ зөвшөөрөл нь апп-г залгасан дуудлагыг хаах, хянах болон дахин чиглүүлэх боломжтой болгодог."</string>
+    <string name="permlab_receiveSms" msgid="8673471768947895082">"текст мессеж(SMS) хүлээж авах"</string>
+    <string name="permdesc_receiveSms" msgid="6424387754228766939">"Апп нь SMS мессежийг хүлээн авах болон гүйцэтгэх боломжтой. Ингэснээр апп нь таны төхөөрөмжрүү илгээсэн мессежийг танд үзүүлэхгүйгээр хянах болон устгаж чадна."</string>
+    <string name="permlab_receiveMms" msgid="1821317344668257098">"текст мессеж(МMS) хүлээж авах"</string>
+    <string name="permdesc_receiveMms" msgid="533019437263212260">"Апп нь MMS мессежийг хүлээн авах болон гүйцэтгэх боломжтой. Ингэснээр апп нь таны төхөөрөмжрүү илгээсэн мессежийг танд үзүүлэхгүйгээр хянах болон устгаж чадна."</string>
+    <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"Яаралтай өргөн дамжууллыг хүлээн авах"</string>
+    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Апп нь яаралтай өргөн дамжууллын мессежийг хүлээн авах болон гүйцэтгэх боломжтой. Энэ зөвшөөрөл нь зөвхөн систем аппликешнд л боломжтой."</string>
+    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"үүрэн өргөн дамжууллын мессеж унших"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Апп нь таны төхөөрөмжийн хүлээн авсан үүрэн өргөн дамжуулах мессежийг унших боломжтой. Үүрэн өргөн дамжууллын мэдэгдэл нь яаралтай нөхцөл байдлыг анхааруулах зорилгоор зарим байршлуудад хүрдэг. Хортой апп нь яаралтай үүрэн өргөн дамжууллыг хүлээн авсан үед таны төхөөрөмжийн ажиллагаа болон чадамжид нөлөөлөх боломжтой."</string>
+    <string name="permlab_sendSms" msgid="5600830612147671529">"SMS мессеж илгээх"</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"Апп нь SMS мессеж илгээх боломжтой. Энэ нь санаандгүй төлбөрт оруулж болзошгүй. Хортой апп нь таны зөвшөөрөлгүйгээр мессеж илгээн таныг төлбөрт оруулж болзошгүй."</string>
+    <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"мессежээр хариулах үйл явдалыг илгээх"</string>
+    <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"Апп нь дуудлага ирэх үед мессежээр хариу өгөх үйл явдлыг зохицуулахын тулд бусад мессежийн апп-д хүсэлт илгээх боломжтой."</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"таны текст мессежийг унших(SMS эсвэл MMS)"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Апп нь таны утас эсвэл SIM картанд хадгалагдсан SMS мессежийг унших боломжтой. Энэ нь апп-д бүх мессежийг контент эсвэл нууц эсэхээс нь үл хамааран унших боломжийг олгоно."</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Апп нь таны утас эсвэл SIM картанд хадгалагдсан SMS мессежийг унших боломжтой. Энэ нь апп-д бүх мессежийг контент эсвэл нууц эсэхээс нь үл хамааран унших боломжийг олгоно."</string>
+    <string name="permlab_writeSms" msgid="3216950472636214774">"Текст мессежийг засах (SMS эсвэл MMS)"</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Апп нь таны таблет эсвэл SIM картанд хадгалагдсан SMS мессежрүү бичих боломжтой. Хортой апп нь таны мессежүүдийг устгах боломжтой."</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Апп нь таны утас эсвэл SIM картанд хадгалагдсан 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_interactAcrossUsers" msgid="7114255281944211682">"хэрэглэгчидтэй харилцан үйлчлэлцэх"</string>
+    <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Апп нь төхөөрөмж дээрх ялгаатай хэрэглэгчдэд үйлдэл гүйцэтгэх боломжтой. Хортой апп нь энийг ашиглан хэрэглэгч хоорондын хамгаалалтыг зөрчих боломжтой."</string>
+    <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"хэрэглэгчидтэй харилцан үйлчлэлцэх бүрэн зөвшөөрөл"</string>
+    <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Бүх хэрэглэгчдэд боломжит бүх харилцан үйлдлийг зөвшөөрнө."</string>
+    <string name="permlab_manageUsers" msgid="1676150911672282428">"хэрэгчлэгч удирдах"</string>
+    <string name="permdesc_manageUsers" msgid="8409306667645355638">"Апп нь төхөөрөмж дээр асуулга, үүсгэлт болон устгалт зэргийг багтаасан хэрэглэгч удирдах боломжтой."</string>
+    <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"ажиллаж байгаа апп-н дэлгэрэнгүйг авах"</string>
+    <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Апп нь одоо ажиллаж байгаа болон сүүлд ажилласан даалгаврын талаарх дэлгэрэнгүй мэдээллийг авах боломжтой. Хортой апп нь бусад апп-н хувийн мэдээлийг олох боломжтой."</string>
+    <string name="permlab_reorderTasks" msgid="2018575526934422779">"ажиллаж байгаа апп-уудыг дахин эрэмбэлэх"</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Апп нь даалгавруудыг нүүрлүү болон арлуу зөөх боломжтой. Апп нь энийг таны оролцоогүйгээр хийж болзошгүй"</string>
+    <string name="permlab_removeTasks" msgid="6821513401870377403">"ажиллаж байгаа апп-г зогсоох"</string>
+    <string name="permdesc_removeTasks" msgid="1394714352062635493">"Апп нь даалгаврууд устгах болон тэдгээрийн апп-г зогсоох боломжтой. Хортой апп нь бусад апп-н ажиллагааг тасалдуулж болзошгүй."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"идэвхжилтийн стекүүдийг удирдах"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Апп-д бусад апп-уудын ажилладаг идэвхжилтийн стекүүдийг нэмэх, хасах буюу өөрчлөх боломж олгоно. Хорлонтой апп-ууд бусад апп-уудын авирт нөлөөлөх боломжтой."</string>
+    <string name="permlab_startAnyActivity" msgid="2918768238045206456">"ямарч активитиг эхлүүлэх"</string>
+    <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Апп нь зөвшөөрөл хамгаалалтай эсвэл экспорт хийсэн статусаас үл хамааран ямарч активитиг эхлүүлэх боломжтой."</string>
+    <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"дэлгэцний зохицолыг тохируулах"</string>
+    <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Апп нь бусад аппликешны дэлгэцний тохиромжит горимыг удирдах боломжтой.  Хортой аппликешн нь бусад аппликешны чадамжийг эвдэх боломжтой."</string>
+    <string name="permlab_setDebugApp" msgid="3022107198686584052">"апп дебагыг идэвхжүүлэх"</string>
+    <string name="permdesc_setDebugApp" msgid="4474512416299013256">"Апп нь бусад апп-г дебаг хийхийг асаах боломжтой. Хортой апп нь энийг ашиглан бусад апп-г зогсоох боломжтой."</string>
+    <string name="permlab_changeConfiguration" msgid="4162092185124234480">"системийн дэлгэцний тохиргоог солих"</string>
+    <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"Апп нь нутагшил эсвэл фонтын хэмжээ зэрэг одоогийн тохиргоог солих боломжтой."</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_forceStopPackages" msgid="2329627428832067700">"бусад апп-г хүчээр зогсоох"</string>
+    <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"Апп нь бусад апп-г хүчээр зогсоох боломжтой."</string>
+    <string name="permlab_forceBack" msgid="652935204072584616">"апп-г хүчээр унтраах"</string>
+    <string name="permdesc_forceBack" msgid="3892295830419513623">"Апп нь нүүрэнд ажиллаж байгаа активитиг хүчээр зогсоох болгон арлуу явуулах боломжтой. Энгийн апп-д хэрэглэхгүй."</string>
+    <string name="permlab_dump" msgid="1681799862438954752">"системийн дотоод статусыг дуудах"</string>
+    <string name="permdesc_dump" msgid="1778299088692290329">"Апп нь системийн дотоод статусыг дуудах боломжтой. Хортой апп нь энийг ашиглах шаардлагагүй аюулгүй байдлын болон хувийн мэдээллийг дуудах боломжтой."</string>
+    <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"Дэлгэцийн контентыг унших"</string>
+    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Апп нь идэвхтэй цонхны контентыг авах боломжтой. Хортой апп нь цонхны контентыг бүхэлд авах болон нууц үгнээс бусад бүх текстийг шалгаж болзошгүй"</string>
+    <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"Хялбар байдлыг түр идэвхтэй болгох"</string>
+    <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"Аппликешн нь төхөөрөмжийн хялбар байдлыг түр зуур идэвхжүүлэх боломжтой. Хортой апп нь хэрэглэгчийн зөвшөөрөлгүйгээр хялбар байдлыг идэвхжүүлж болзошгүй."</string>
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"цонхны мэдээллийг унших"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Аппликешн нь цонхны менежерээс цонхны талаар мэдээллийг дуудах боломжтой. Хортой апп нь дотоод системийн хэрэглээнд зориулагдсан мэдээллийг дуудаж болзошгүй."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"үйл явдлыг шүүх"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Аппликешн нь хэрэглэгчийн бүх үйл явдалын илгээгдэхээс өмнөх урсгалыг шүүж байгаа оролтын шүүлтйиг бүртгэх боломжтой. Хортой апп нь хэрэглэгчийн интервэшнгүйгээр системийн UI-г удирдах боломжтой."</string>
+    <string name="permlab_magnify_display" msgid="5973626738170618775">"дэлгэц томруулах"</string>
+    <string name="permdesc_magnify_display" msgid="7121235684515003792">"Аппликешн нь дэлгэцний контентийг өсгөх боломжтой. Хортой апп нь дэлгэцийн контентыг төхөөрөмжнөөс ашиглаж болохгүй болгон хувиргах боломжтой."</string>
+    <string name="permlab_shutdown" msgid="7185747824038909016">"хэсэгчилсэн унтраалт"</string>
+    <string name="permdesc_shutdown" msgid="7046500838746291775">"Активити менежерийг унтраана. Бүрэн унтраалтыг хийхгүй."</string>
+    <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"апп шилжүүлэхийг хориглох"</string>
+    <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Хэрэглэгч бусад апп-руу сэлгэхийг хориглох."</string>
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"одоогийн апп-н мэдээллийг авах"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="8153651434145132505">"Эзэмшигч нь дэлгэцний нүүрэнд байгаа одоогийн аппликешн болон үйлчилгээний талаарх хувийн мэдээллийг унших боломжтой."</string>
+    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"бүх апп-ын эхлэлийг хянах болон удирдах"</string>
+    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Апп нь систем активитиг яаж эхлүүлж байгааг хянах болон удирдан боломжтой. Хортой апп нь системд бүрэн нөлөөлж болзошгүй. Энэ эрх нь зөвхөн хөгжүүлэлтийн үед л хэрэгтэй ба энгийн хэрэглээнд огт хэрэггүй."</string>
+    <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"багц хасагдсан өргөн дамжууллыг илгээх"</string>
+    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"Апп нь апп багц устгагдсан талаарх мэдэгдлийг өргөн дамжуулах боломжтой. Хортой апп энийг ашиглан бусад ажиллаж байгаа апп-г зогсоох боломжтой."</string>
+    <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"SMS-хүлээн авав өргөн дамжууллыг илгээх"</string>
+    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"Апп нь SMS мессеж хүлээн авсан талаарх мэдэгдлийг өргөн дамжуулах боломжтой. Хортой апп энийг ашиглан ирсэн SMS мессежийг хуурамчаар хийх боломжтой."</string>
+    <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"WAP-PUSH-хүлээн авав өргөн дамжууллыг илгээх"</string>
+    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"Аппликешн нь WAP PUSH мессеж хүлээж авсан мэдэгдлийг өргөн дамжуулах боломжтой. Хортой апп нь энийг ашиглан MMS мессеж хүлээн авсан гэж хуурамчаар мэдэгдэх эсвэл хортой хувьсагч агуулсан веб хуудасны контентыг чимээгүй орлуулах боломжтой."</string>
+    <string name="permlab_setProcessLimit" msgid="2451873664363662666">"ажиллаж байгаа процессийн тоог хязгаарлах"</string>
+    <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"Апп нь нэг зэрэг ажиллах процессийн тооны дээд утгыг удирдах боломжтой. Энгийн апп-д хэзээ ч ашиглагдахгүй."</string>
+    <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"арын апп-г хүчээр хаах"</string>
+    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"Апп нь активитинүүд арын болонгуутаа дуусах эсэхийг удирдах боломжтой. Энгийн апп-д хэрэглэгдэхгүй."</string>
+    <string name="permlab_batteryStats" msgid="2789610673514103364">"батерейны статистикийг унших"</string>
+    <string name="permdesc_batteryStats" msgid="5897346582882915114">"Аппликешн нь батерей хэрэглээний доод-төвшиний одоогийн датаг унших боломжтой. Аппликешнд таны ашиглаж байгаа апп-н талаарх дэлгэрэнгүй мэдээллийг олох боломжийг олгоно."</string>
+    <string name="permlab_updateBatteryStats" msgid="3719689764536379557">"батерейн статистикийг өөрчлөх"</string>
+    <string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"Апп нь батерейн цуглуулагдсан статистикийг өөрчлөх боломжтой. Энгийн апп-д шаардлагагүй."</string>
+    <string name="permlab_getAppOpsStats" msgid="1508779687436585744">"апп-н ажиллагааны статистикийг авах"</string>
+    <string name="permdesc_getAppOpsStats" msgid="6243887041577912877">"Апп нь аппликешны ажиллагааны цуглуулсан статистикийг дуудах боломжтой. Энгийн апп-д ашиглагдахгүй."</string>
+    <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"апп ажиллагааны статистикийг өөрчлөх"</string>
+    <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"Апп нь аппликешны ажиллагааны цуглуулсан статистикийг өөрчлөх боломжтой. Энгийн апп-д ашиглагдахгүй."</string>
+    <string name="permlab_backup" msgid="470013022865453920">"систем нөөшлөлт болон сэргээлтийг удирдах"</string>
+    <string name="permdesc_backup" msgid="6912230525140589891">"Апп нь системийн нөөшлөх болон сэргээх тогтолцоог удирдах боломжтой. Энгийн апп-уудад хэрэглэгдэхгүй."</string>
+    <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"бүтэн нөөшлөлтийг бататгах эсвэл ажиллагааг сэргээх"</string>
+    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"Апп нь бүрэн нөөшлөлтийг баталгаажуулах UI-г эхлүүлэх боломжтой. Энгийн апп-д ашиглагдахгүй."</string>
+    <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"эрхжүүлэгдээгүй цонхыг үзүүлэх"</string>
+    <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"Апп нь дотоод системийн хэрэглэгчийн интерфейст ашиглагдах цонхыг үүсгэх боломжтой. Энгийн апп-д ашиглагдахгүй."</string>
+    <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"бусад апп-р зурах"</string>
+    <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"Апп нь бусад аппликешн эсвэл хэрэглэгчийн интерфейсын дээд талд зурах боломжтой. Эдгээр нь бүх аппликешны интерфейсыг ашиглахад саад болох эсвэл   бусад аппликешн дээр таны харж байгааг солих боломжтой."</string>
+    <string name="permlab_setAnimationScale" msgid="2805103241153907174">"глобал энимешн хурдыг өөрчлөх"</string>
+    <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"Апп нь ямар ч үед глобал энимешн хурдыг(хурдан удаан энимешн) солих боломжтой."</string>
+    <string name="permlab_manageAppTokens" msgid="1286505717050121370">"апп бүтвэрийг удирдах"</string>
+    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"Апп нь өөрийн нормал Z эрэмбийг дамжуулах замаар өөрсдийн бүтвэрийг үүсгэх болон удирдах боломжтой. Энгийн апп-д хэрэглэгдэхгүй"</string>
+    <string name="permlab_freezeScreen" msgid="4708181184441880175">"дэлгэцийг хөдөлгөөнгүй болгох"</string>
+    <string name="permdesc_freezeScreen" msgid="8558923789222670064">"Аппликешн нь бүтэн дэлгэцрүү шилжихэд дэлгэцийг хөдөлгөөнгүй болгох боломжтой."</string>
+    <string name="permlab_injectEvents" msgid="1378746584023586600">"товч болон контрол товч дарах"</string>
+    <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"Алл нь өөрийн оролтын үйл явдлыг(товч дарагдах г.м) бусад апп-д дамжуулах боломжтой. Хортой апп нь энийг ашиглан таблетыг удирдах боломжтой."</string>
+    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"Алл нь өөрийн оролтын үйл явдлыг(товч дарагдах г.м) бусад апп-д дамжуулах боломжтой. Хортой апп нь энийг ашиглан утсыг удирдах боломжтой."</string>
+    <string name="permlab_readInputState" msgid="469428900041249234">"таны хийж байгаа үйлдэл болон бичиж байгааг бичлэг хийх"</string>
+    <string name="permdesc_readInputState" msgid="8387754901688728043">"Апп нь бусад апп-тай харилцан үйлчилж(нууц үг оруулах) таны дарсан товчийг ажиглах боломжтой. Энгийн апп-д хэрэглэгдэхгүй."</string>
+    <string name="permlab_bindInputMethod" msgid="3360064620230515776">"оролтын аргатай холбох"</string>
+    <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Эзэмшигч нь оруулах аргын дээд-төвшиний интерфейстэй холбох боломжтой. Энгийн апп-д хэрэглэгдэхгүй."</string>
+    <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"хандалтын үйлчилгээнд холбогдох"</string>
+    <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Эзэмшигч нь хандах үйлчилгээний дээд-төвшиний интерфейстэй холбох боломжтой. Энгийн апп-д шаардлагагүй."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"хэвлэх үйлчилгээтэй холбох"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Эзэмшигчид хэвлэх үйлчилгээний дээд-түвшний интерфейстэй холбох боломж олгоно. Энгийн апп-уудад хэзээ ч ашиглагдахгүй."</string>
+    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"бүх хэвлэх ажилд хандалт хийх"</string>
+    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Эзэмшигчид өөр апп-аас үүсгэсэн хэвлэх ажилд хандалт хийх боломж олгоно. Энгийн апп-уудад хэзээ ч ашиглагдахгүй."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC үйлчилгээтэй холбох"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Эзэмшигчид NFC картуудыг дуурайлгадаг аппликешнүүдийг холбох боломж олгоно. Энгийн апп-уудад хэзээ ч шаардагдахгүй."</string>
+    <string name="permlab_bindTextService" msgid="7358378401915287938">"текст үйлчилгээтэй холбох"</string>
+    <string name="permdesc_bindTextService" msgid="8151968910973998670">"Эзэмшигч нь текст үйлчилгээний(ж.нь. SpellCheckerService) дээд-төвшиний интерфейстэй холбох боломжтой. Энгийн апп-д хэрэглэгдэхгүй."</string>
+    <string name="permlab_bindVpnService" msgid="4708596021161473255">"VPN үйлчилгээтэй холбох"</string>
+    <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Эзэмшигч нь VPN үйлчилгээний дээд-төвшиний интерфейстэй холбох боломжтой. Энгийн апп-д шаардлагагүй."</string>
+    <string name="permlab_bindWallpaper" msgid="8716400279937856462">"ханын зурагтай холбох"</string>
+    <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Эзэмшигч нь ханын зурагны дээд-төвшиний интерфейстэй холбох боломжтой. Энгийн апп-уудад шаардлагагүй."</string>
+    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"виджет үйлчилгээтэй холбох"</string>
+    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Эзэмшигч нь виджет үйлчилгээний дээд-төвшиний интерфейстэй холбох боломжтой. Энгийн апп-д шаардлагагүй."</string>
+    <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"төхөөрөмжийн админтай харилцан үйлчлэх"</string>
+    <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Эзэмшигч нь төхөөрөмжийн админруу интент илгээх боломжтой. Энгийн апп-д шаардлагагүй."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"төхөөрөмжийн админ нэмэх, хасах"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Эзэмшигч нь идэвхтэй төхөөрөмжийн администраторыг нэмэх, хасах боломжтой. Энгийн апп-д шаардлагагүй."</string>
+    <string name="permlab_setOrientation" msgid="3365947717163866844">"дэлгэцний чиглэлийг солих"</string>
+    <string name="permdesc_setOrientation" msgid="3046126619316671476">"Апп нь ямар ч үед дэлгэцний эргэлтийг солих боломжтой. Энгийн аппликешнд хэзээ ч ашиглахгүй."</string>
+    <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"заагчийн хурдыг солих"</string>
+    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Апп нь хулгана эсвэл хөдлөх самбарын заагчийн хурдыг ямарч үед солих боломжтой. Энгийн апп-д хэрэглэгдэхгүй."</string>
+    <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"гарын схемийг солих"</string>
+    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Апп нь гарын схемыг солих боломжтой. Энгийн апп-д хэрэглэгдэхгүй."</string>
+    <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"аппруу Linux дохио илгээх"</string>
+    <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Апп нь бүх байнгын процессруу хангамжийн дохиог илгээх хүсэлтийг хийх боломжтой."</string>
+    <string name="permlab_persistentActivity" msgid="8841113627955563938">"апп-г байнга ажиллуулах"</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Апп нь өөрийн хэсгийн санах ойд байнга байлгах боломжтой. Энэ нь бусад апп-уудын ашиглах санах ойг хязгаарлан таблетыг удаашруулах болно."</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"Апп нь өөрийн хэсгийг санах ойд байнга байлгах боломжтой. Энэ нь бусад апп-уудын ашиглах санах ойг хязгаарлан утсыг удаашруулах болно."</string>
+    <string name="permlab_deletePackages" msgid="184385129537705938">"апп устгах"</string>
+    <string name="permdesc_deletePackages" msgid="7411480275167205081">"Апп нь Андройд багцийг устгах боломжтой. Хортой апп нь энийг ашиглан чухал апп-г устгах боломжтой."</string>
+    <string name="permlab_clearAppUserData" msgid="274109191845842756">"бусад апп-н датаг устгах"</string>
+    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"Апп нь хэрэглэгчийн датаг арилгах боломжтой."</string>
+    <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"бусад апп-н кешээс устгах"</string>
+    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"Апп нь кеш файлаас устгах боломжтой."</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"апп сангийн хэмжээг хэмжих"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Апп нь өөрийн код, дата болон кеш хэмжээг унших боломжтой"</string>
+    <string name="permlab_installPackages" msgid="2199128482820306924">"апп-г шууд суулгах"</string>
+    <string name="permdesc_installPackages" msgid="5628530972548071284">"Апп нь шинэ эсвэл шинэчлэгдсэн Андройд багцийг суулгах боломжтой. Хортой апп нь энийг ашиглан дурын эрхтэй шинэ апп-г суулгах боломжтой."</string>
+    <string name="permlab_clearAppCache" msgid="7487279391723526815">"бүх апп-н кеш датаг устгах"</string>
+    <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"Апп нь бусад аппликешны кеш директороос файл устган таблетын санг чөлөөлөх боломжтой. Энэ  нь бусад аппликешнд нөлөөлж, тэдгээр нь эхлэхдээ шаардлагатай датагаа дахин дуудах тул удааширч болзошгүй."</string>
+    <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"Апп нь бусад аппликешны кеш директороос файл устган утасны санг чөлөөлөх боломжтой. Энэ нь бусад аппликешнд нөлөөлж, тэдгээр нь эхлэхдээ шаардлагатай датагаа дахин дуудах тул удааширч болзошгүй."</string>
+    <string name="permlab_movePackage" msgid="3289890271645921411">"апп нөөцийг шилжүүлэх"</string>
+    <string name="permdesc_movePackage" msgid="319562217778244524">"Апп нь апп нөөцийг дотроос гадна медиаруу болон эсрэгээр нь зөөх боломжтой."</string>
+    <string name="permlab_readLogs" msgid="6615778543198967614">"нууц лог дата унших"</string>
+    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Апп нь системийн төрөл бүрийн лог файлыг унших боломжтой. Энэ нь та таблет дээрээ юу хийсэн талаарх хувийн болон нууц мэдээллийг олох боломжтой болгоно."</string>
+    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Апп нь системийн төрөл бүрийн лог файлыг унших боломжтой. Энэ нь та утсан дээрээ юу хийсэн талаарх хувийн болон нууц мэдээллийг олох боломжтой болгоно."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"тоглуулахын тулд дурын медиа шифрлэгчийг ашиглах"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Апп нь тоглуулах үедээ код тайлахдаа суулгагдсан ямарч медиа код тайлагчийг ашиглах боломжтой."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"итгэмжлэгдсэн жуухуудыг удирдах"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Апп-д CA сертификатуудыг итгэмжлэгдсэн жуух байдлаар суулгах болон устгахыг зөвшөөрнө."</string>
+    <string name="permlab_diagnostic" msgid="8076743953908000342">"оношлох грүпийн эзэмшдэг нөөцрүү унших/бичих"</string>
+    <string name="permdesc_diagnostic" msgid="6608295692002452283">"Апп нь оношлох грүпийн эзэмшдэг, жишээ нь /dev доторх файлууд, дурын  нөөцийг унших бичих боломжтой.Энэ нь системийн тогвортой байдал болон аюулгүй байдалд бодитоор нөлөөлнө. Энэ нь үйлдвэрлэгч болон операторын хардверт-зориулсан оношлогоонд ашиглагдана."</string>
+    <string name="permlab_changeComponentState" msgid="6335576775711095931">"апп компонентыг идэвхжүүлэх эсвэл идэвхгүй болгох"</string>
+    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Апп нь өөр апп-н компонент идэвхтэй эсэхийг солих боломжтой. Хортой апп нь энийг ашиглан таблетын чухал чадамжийг идэвхгүй болгож болзошгүй. Зөвшөөрөл нь аппликешн компонентыг тогтворгүй, ашиглаж болохгүй, тохиромжгүй төлөвт оруулах боломжтой тул ашиглахдаа болгоомжтой байх шаардлагатай."</string>
+    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Апп нь өөр апп-н компонент идэвхтэй эсэхийг солих боломжтой. Хортой апп нь энийг ашиглан утасны чухал чадамжийг идэвхгүй болгож болзошгүй. Зөвшөөрөл нь аппликешн компонентыг тогтворгүй, ашиглаж болохгүй, тохиромжгүй төлөвт оруулах боломжтой тул ашиглахдаа болгоомжтой байх шаардлагатай."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"зөвшөөрөл олгох эсвэл цуцлах"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Аппликешн нь өөртэй болон бусад аппликешнд тусгай зөвшөөрлийг олгох болон цуцлах боломжтой. Хортой аппликешн нь энийг ашиглан таны олгоогүй эрхэнд хандах боломжтой."</string>
+    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"үндсэн апп-г тохируулах"</string>
+    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Апп нь таны тусгай апп-уудыг өөрчлөх боломжтой. Хортой апп нь ажиллаж байгаа апп-г нууцаар өөрчлөн, таны хуучин апп-г таны хувийн датаг цуглуулагч болгон хуурах боломжтой."</string>
+    <string name="permlab_writeSettings" msgid="2226195290955224730">"систем тохиргоог өөрчлөх"</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"Апп нь системийн тохиргооны датаг өөрчлөх боломжтой. Хортой апп нь таны системийн тохиргоог сүйтгэх боломжтой."</string>
+    <string name="permlab_writeSecureSettings" msgid="204676251876718288">"аюулгүй систем тохиргоог өөрчлөх"</string>
+    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"Апп нь системийн аюулгүй байдлын тохиргооны датаг өөрчлөх боломжтой. Энгийн апп-д ашиглагдахгүй."</string>
+    <string name="permlab_writeGservices" msgid="2149426664226152185">"Google газрын зургийн үйлчилгээг өөрчлөх"</string>
+    <string name="permdesc_writeGservices" msgid="1287309437638380229">"Апп нь Google-н газрын зургийн үйлчилгээг өөрчлөх боломжтой. Энгийн апп-д ашиглагдахгүй."</string>
+    <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"Эхлэхэд ажиллуулах"</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Апп нь систем асаж дуусахад шууд өөрийгөө асаах боломжтой. Ингэснээр таблетыг асахад их хугацаа орох болон байнга ажилладаг апп нь таблетийг бүхэлд нь удаашруулах боломжтой."</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="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="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="default" msgid="589869224625163558">"Апп нь таны утсаар ярьсан, имэйл илгээсэн давтамж эсвэл харилцагдчидтайгаа өөр аргаар холбоо барьсан байдал зэргийг агуулсан утсан дээр хадгалагдсан харилцагчдын талаарх датаг өөрчлөх боломжтой. Энэ зөвшөөрөл нь апп-д харилцагчийн датаг устгах боломжийг олгоно."</string>
+    <string name="permlab_readCallLog" msgid="3478133184624102739">"дуудлагын логийг унших"</string>
+    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Апп нь таны таблетын ирсэн гарсан дуудлага зэргийг агуулсан дуудлагын логыг унших боломжтой. Энэ зөвшөөрөл нь апп-д таны дуудлагын логын датаг хадгалах боломжийг олгох ба хортой апп нь танд мэдэгдэлгүйгээр дуудлагын лог датаг хуваалцах боломжтой."</string>
+    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Апп нь таны утасны ирсэн гарсан дуудлага зэргийг агуулсан дуудлагын логыг унших боломжтой. Энэ зөвшөөрөл нь апп-д таны дуудлагын логын датаг хадгалах боломжийг олгох ба хортой апп нь танд мэдэгдэлгүйгээр дуудлагын лог датаг хуваалцах боломжтой."</string>
+    <string name="permlab_writeCallLog" msgid="8552045664743499354">"дуудлагын логруу бичих"</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Апп нь таны таблетын ирсэн гарсан дуудлага зэргийг агуулсан дуудлагын логыг унших боломжтой. Хортой апп нь энийг ашиглан таны дуудлагын логыг өөрчлөх болон арилгах боломжтой."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Апп нь таны утасны ирсэн гарсан дуудлага зэргийг агуулсан дуудлагын логыг өөрчлөх боломжтой. Хортой апп нь энийг ашиглан таны дуудлагын логыг өөрчлөх болон арилгах боломжтой."</string>
+    <string name="permlab_readProfile" msgid="4701889852612716678">"та өөрийн харилцагчийн картыг унших"</string>
+    <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Апп нь таны нэр болон холбоо барих мэдээлэл зэрэг таны утсан дээр хадгалагдсан хувийн профайл мэдээллийг унших боломжтой. Ингэснээр апп нь танийг таньж чадах ба таны профайл мэдээллийг бусдад илгээх боломжтой."</string>
+    <string name="permlab_writeProfile" msgid="907793628777397643">"та өөрийн харилцагчийн картыг өөрчлөх"</string>
+    <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Апп нь таны нэр болон холбоо барих мэдээлэл зэрэг таны төхөөрөмж дээр хадгалагдсан хувийн профайл мэдээллийг солих эсвэл нэмэх боломжтой. Ингэснээр апп нь танийг таньж чадах ба таны профайл мэдээллийг бусдад илгээх боломжтой."</string>
+    <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"таны нийтийн урсгалаас унших"</string>
+    <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Апп нь та болон таны найзуудын нийтийн шинэчлэлтэд хандах болон синк хийх боломжтой. Мэдээлэл хуваалцахдаа болгоомжтой байна уу - энэ нь апп-д нийтийн сүлжээндэх та болон таны найзууд хоорондын холбоог нууц эсэхээс үл хамааран унших боломжтой. Анхаар: энэ зөвшөөрөл нь бүх нийтийн сүлжээнд ашиглаж боломжгүй."</string>
+    <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"Таны нийтийн урсгалруу бичих"</string>
+    <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Апп нь таны найзуудын нийтийн шинэчлэлтийг дүрслэх боломжтой.Мэдээлэл хуваалцахдаа болгоомжтой байна уу - энэ нь апп-д таны найзаас ирсэн мэт харагдах мессеж хийх боломжийг олгоно. Анхаар: энэ зөвшөөрөл нь бүх нийтийн сүлжээнд ашиглаж боломжгүй."</string>
+    <string name="permlab_readCalendar" msgid="5972727560257612398">"календарийн хуваарийн нууц мэдээллийг унших"</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Апп нь таны таблет дээр хадгалагдсан найзууд болон хамтран ажиллагсдын календарийн бүх хуваарийг унших боломжтой. Энэ нь апп-д таны календарийн датаг нууц эсвэл эмзэг эсэхээс нь үл хамааран хуваалцах эсвэл хадгалах боломжийг олгоно."</string>
+    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Allows the app to read all calendar events stored on your phone, including those of friends or co-workers. This may allow the app to share or save your calendar data, regardless of confidentiality or sensitivity. Апп нь таны утсан дээр хадгалагдсан найзууд болон хамтран ажиллагсдын календарийн бүх хуваарийг унших боломжтой. Энэ нь апп-д таны календарийн датаг нууц эсвэл эмзэг эсэхээс нь үл хамааран хуваалцах эсвэл хадгалах боломжийг олгоно."</string>
+    <string name="permlab_writeCalendar" msgid="8438874755193825647">"календарын хуваарийг нэмэх эсвэл өөрчлөх болон эзэмшигчид мэдэгдэлгүйгээр зочидруу имэйл илгээх"</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Апп нь таблет дээр та болон таны найзууд, хамтран ажиллагсдын өөрчилж чадах үйл явдлуудыг нэмэх, хасах болон солих боломжтой. Энэ нь апп-д, календарь эзэмшигчээс ирсэн мэт харагдах мессежийг илгээх эсвэл эзэмшигчд нь мэдэгдэлгүйгээр үйл явдлуудыг өөрчлөх боломжийг олгоно."</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Апп нь утсан дээр та болон таны найзууд, хамтран ажиллагсдын өөрчилж чадах үйл явдлуудыг нэмэх, хасах болон солих боломжтой. Энэ нь апп-д, календарь эзэмшигчээс ирсэн мэт харагдах мессежийг илгээх эсвэл эзэмшигчид нь мэдэгдэлгүйгээр үйл явдлуудыг өөрчлөх боломжийг олгоно."</string>
+    <string name="permlab_accessMockLocation" msgid="8688334974036823330">"тест хийх байршлын эх үүсвэрийг үүсгэх"</string>
+    <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Тестэд ашиглах хуурамч байршлын эх үүсвэрийг үүсгэх болон шинэ байршил өгөгчийг суулгах боломжтой. Ингэснээр апп нь GPS эсвэл байршил өгөгч зэрэг бусад байршлын эх үүсвэрээс ирсэн байршил болон статусыг өөрчлөх боломжтой."</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"байршил нийлүүлэгчийн нэмэлт тушаалд хандах"</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"Апп нь байршил нийлүүлэгчийн нэмэлт тушаалд хандах боломжтой. Энэ нь апп-д GPS эсвэл бусад байршлын үйлчилгээний ажиллагаанд нөлөөлөх боломжийг олгоно."</string>
+    <string name="permlab_installLocationProvider" msgid="6578101199825193873">"байршил нийлүүлэгчийг суулгах зөвшөөрөх"</string>
+    <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"Тестэд ашиглах хуурамч байршлын эх үүсвэрийг үүсгэх болон шинэ байршил өгөгчийг суулгах боломжтой. Ингэснээр апп нь GPS эсвэл байршил өгөгч зэрэг бусад байршлын эх үүсвэрээс ирсэн байршил болон статусыг өөрчлөх боломжтой."</string>
+    <string name="permlab_accessFineLocation" msgid="1191898061965273372">"Тодорхой байршил(GPS болон сүлжээнд суурилсан)"</string>
+    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Апп нь GPS эсвэл үүрэн цамхаг болон Wi-Fi зэрэг сүлжээний байршлын эх үүсвэрийг ашиглан таны тодорхой байршлыг авах боломжтой. Эдгээр байршлын үйлчилгээнүүд нь асаалттай байх шаардлагатай ба таны төхөөрөмж дээрх апп-ууд ашиглах боломжтой байх шаардлагатай. Апп-ууд энийг ашиглан таныг хаана байгааг тогтоох боломжтой ба батерей зарцуулалт нэмэгдэнэ."</string>
+    <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"ойролцоох байршил(сүлжээнд суурилсан)"</string>
+    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Апп нь таны ойролцоох байршлыг оло боломжтой. Энэ байршил нь үүрэн цамхаг болон Wi-Fi зэрэг сүлжээний байршлын эх сурвалжийг ашигладаг байршлын үйлчилгээнээс олдоно. Эдгээр байршлын үйлчилгээнүүд нь таны төхөөрөмж дээр асаалттай байх шаардлагатай ба апп-д тэдгээрийг ашиглах боломжтой байх шаардлагатай. Апп-д тэдгээрийг ашиглан таны байршлыг ойролцоогоор олох боломжтой."</string>
+    <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"SurfaceFlinger-т хандах"</string>
+    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Апп нь SurfaceFlinger доод-төвшиний функцийг ашиглах боломжтой."</string>
+    <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"Фрэйм буферээс унших"</string>
+    <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Апп нь фрэйм буферын контентыг унших боломжтой."</string>
+    <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Wifi дэлгэцийг тохируулах"</string>
+    <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Апп нь Wifi дэлгэцийг тохируулах болон холбогдох боломжтой."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wifi дэлгэцийг удирдах"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Апп нь Wifi дэлгэцний доод-төвшиний функцийг удирдах боломжтой."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"аудио гаралтыг барих"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Апп-т аудио гаралтыг барих, дахин чиглүүлэхийг зөвшөөрнө."</string>
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"видео гаралтыг барих"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Апп-т видео гаралтыг барих, дахин чиглүүлэхийг зөвшөөрнө."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"найдвартай видео гаралтыг барих"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Апп-т найдвартай видео гаралтыг барих, дахин чиглүүлэхийг зөвшөөрнө."</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="4906839301087980680">"Апп нь микрофоноор аудио бичих боломжтой. Энэ зөвшөөрөл нь апп-д ямар ч үед таны зөвшөөрөлгүйгээр аудио бичих боломжийг олгоно."</string>
+    <string name="permlab_camera" msgid="3616391919559751192">"зураг авах болон видео бичих"</string>
+    <string name="permdesc_camera" msgid="8497216524735535009">"Апп нь камераар зураг авах болон видео бичих боломжтой. Энэ зөвшөөрөл нь апп-д ямар ч үед таны зөвшөөрөлгүйгээр камер ашиглах боломжийг олгоно."</string>
+    <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"камер ашиглаж байх үед дамжууллыг заагч LED-г идэвхгүй болгох"</string>
+    <string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"Урьдчилан суусан систем аппликешн нь камер ашиглалтыг заасан LED-г идэвхгүй болгох боломжтой."</string>
+    <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"таблетыг бүрмөсөн идэвхгүй болгох"</string>
+    <string name="permlab_brick" product="default" msgid="8337817093326370537">"утсыг бүрмөсөн идэвхгүй болгох"</string>
+    <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"Апп нь таблетыг бүхэлд нь бүрмөсөн идэвхгүй болгох боломжтой. Энэ маш аюултайэ"</string>
+    <string name="permdesc_brick" product="default" msgid="5788903297627283099">"Апп нь утсыг бүхэлд нь бүрмөсөн идэвхгүй болгох боломжтой. Энэ маш аюултай."</string>
+    <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"таблет хүчээр дахин асаах"</string>
+    <string name="permlab_reboot" product="default" msgid="2898560872462638242">"утсыг хүчээр дахин асаах"</string>
+    <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"Апп нь таблетыг хүчээр дахин асаах боломжтой."</string>
+    <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"Апп нь утсыг хүчээр дахин асаах боломжтой."</string>
+    <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"USB сан файл системд хандах"</string>
+    <string name="permlab_mount_unmount_filesystems" product="default" msgid="4402305049890953810">"SD карт файл системд хандах"</string>
+    <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"Апп нь сугалдаг санг файл системд залгах болон салгах боломжтой."</string>
+    <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"USB санг арилгах"</string>
+    <string name="permlab_mount_format_filesystems" product="default" msgid="262582698639274056">"SD картыг арилгах"</string>
+    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"Апп нь зөөврийн санг форматлах боломжтой."</string>
+    <string name="permlab_asec_access" msgid="3411338632002193846">"дотоод сангийн мэдээллийг авах"</string>
+    <string name="permdesc_asec_access" msgid="3094563844593878548">"Апп нь дотоод сангаас мэдээллийг авах боломжтой"</string>
+    <string name="permlab_asec_create" msgid="6414757234789336327">"дотоод санд үүсгэх"</string>
+    <string name="permdesc_asec_create" msgid="4558869273585856876">"Апп нь дотоод сан үүсгэх боломжтой."</string>
+    <string name="permlab_asec_destroy" msgid="526928328301618022">"дотоод сангаас устгах"</string>
+    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"Апп нь дотоод сангаас устгах боломжтой."</string>
+    <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"дотоод санг залгах/салгах"</string>
+    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"Апп нь дотоод санг залгах/салгах боломжтой."</string>
+    <string name="permlab_asec_rename" msgid="7496633954080472417">"дотоод сангийн нэрийг өөрчлөх"</string>
+    <string name="permdesc_asec_rename" msgid="1794757588472127675">"Апп нь дотоод сангийн нэрийг өөрчлөх боломжтой."</string>
+    <string name="permlab_vibrate" msgid="7696427026057705834">"чичиргээг удирдах"</string>
+    <string name="permdesc_vibrate" msgid="6284989245902300945">"Апп нь чичиргээг удирдах боломжтой."</string>
+    <string name="permlab_flashlight" msgid="2155920810121984215">"гар чийдэн удирдах"</string>
+    <string name="permdesc_flashlight" msgid="6522284794568368310">"Апп нь гар чийдэнг удирдах боломжтой."</string>
+    <string name="permlab_manageUsb" msgid="1113453430645402723">"USB төхөөрөмжийн тохиргоо болон зөвшөөрлийг удирдах"</string>
+    <string name="permdesc_manageUsb" msgid="7776155430218239833">"Апп нь USB төхөөрөмжийн зөвшөөрөл болон тохируулгыг удирдах боломжтой."</string>
+    <string name="permlab_accessMtp" msgid="4953468676795917042">"MTP протоколыг гүйцэтгэх"</string>
+    <string name="permdesc_accessMtp" msgid="6532961200486791570">"MTP USB протокол биелүүлэхээр MTP цөм драйверт хандах боломжтой."</string>
+    <string name="permlab_hardware_test" msgid="4148290860400659146">"хардвер теслэх"</string>
+    <string name="permdesc_hardware_test" msgid="6597964191208016605">"Апп нь хардверийг тестлэх зорилгоор олон төрлийн туслах төхөөрөмжийг удирдах боломжтой."</string>
+    <string name="permlab_callPhone" msgid="3925836347681847954">"утасны дугаарт шууд дуудлага хийх"</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"Апп нь таны оролцоогүйгээр дуудлага хийх боломжтой. Энэ нь төлөвлөгдөөгүй төлбөрт оруулах эсвэл дуудлага хийнэ. Энэ нь апп-г яаралтай дугаарт дуудлага хийхйг зөвшөөрөхгүй. Хортой апп нь таны зөвшөөрөлгүйгээр дуудлага хийж таныг төлбөрт оруулж болзошгүй"</string>
+    <string name="permlab_callPrivileged" msgid="4198349211108497879">"дурны утасны дугаарт шууд дуудлага хийх"</string>
+    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"Апп нь таны оролцоогүйгээр яаралтай тусламжийн дугааруудыг оруулаад ямарч дугаарлуу дуудлага хийх боломжтой. Хортой апп нь шаардлагагүй, хууль бус дуудлагыг яаралтай тусламжийн үйлчилгээрүү хийж болзошгүй."</string>
+    <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"CDMA таблет тохиргоог шууд эхлүүлэх"</string>
+    <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"CDMA утасны тохиргоог шууд эхлүүлэх"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"Апп нь CDMA провишныг эхлүүлэх боломжтой. Хортой апп нь шаардлагагүй байхад CDMA провишныг эхлүүлж болзошгүй."</string>
+    <string name="permlab_locationUpdates" msgid="7785408253364335740">"байршил шинэчлэх мэдэгдлийг удирдах"</string>
+    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Апп нь радиогоос ирсэн байршил шинэчлэх мэдэгдлийг идэвхтэй/идэвхгүй болгох боломжтой. Энгийн апп-д хэрэглэглэхгүй."</string>
+    <string name="permlab_checkinProperties" msgid="7855259461268734914">"бүртгэх пропертид хандах"</string>
+    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Апп нь бүртгэл үйлчилгээгээр байршуулагдсан пропертиг унших/бичих боломжтой. Энгийн апп-д хэрэглэгдэхгүй."</string>
+    <string name="permlab_bindGadget" msgid="776905339015863471">"виджет сонгох"</string>
+    <string name="permdesc_bindGadget" msgid="8261326938599049290">"Апп нь аль апп ямар виджетийг ашиглаж байгаа тухай системд мэдэгдэх боломжтой. Энэ зөвшөөрөлтэй апп нь бусад апп-д хувийн датад хандах эрхийг өгөх боломжтой. Энгийн апп-д ашиглагдахгүй."</string>
+    <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"утасны статусыг өөрчлөх"</string>
+    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Апп-н төхөөрөмжийн утасны функцийг удирдах боломжтой. Энэ зөвшөөрөлтэй апп  нь танд анхааруулахгүйгээр сүлжээг сэлгэх, утасны радиог асаах, унтраах боломжтой."</string>
+    <string name="permlab_readPhoneState" msgid="9178228524507610486">"утасны статус ба таниулбарыг унших"</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Апп нь төхөөрөмжийн утасны функцд хандах боломжтой. Энэ зөвшөөрөл нь апп-д утасны дугаар болон төхөөрөмжийн ID-г, дуудлага идэвхтэй эсэх, холын дугаар дуудлагаар холбогдсон байгаа эсэхийг тогтоох боломжийг олгоно,"</string>
+    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"таблетыг унтуулахгүй байлгах"</string>
+    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"утсыг унтуулахгүй байлгах"</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Апп нь таблетыг унтахаас сэргийлэх боломжтой"</string>
+    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Апп нь утсыг унтахаас сэргийлэх боломжтой"</string>
+    <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"таблетыг унтраах эсвэл асаах"</string>
+    <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"утсыг унтраах эсвэл асаах"</string>
+    <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Апп нь таблетыг асаах, унтраах боломжтой."</string>
+    <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"Апп нь утсыг асаах, унтраах боломжтой."</string>
+    <string name="permlab_factoryTest" msgid="3715225492696416187">"үйлдвэрийн тест горимд ажиллуулах"</string>
+    <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"Доод төвшиний үйлдвэрийн тестийг ажиллуулан таблетын хардверт бүрэн хандах боломжтой. Таблет нь үйлдвэрийн тестийн горимд ажиллах үед л боломжтой."</string>
+    <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"Доод төвшиний үйлдвэрийн тестийг ажиллуулан утасны хардверт бүрэн хандах боломжтой. Утас үйлдвэрийн тестийн горимд ажиллах үед л боломжтой."</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_masterClear" msgid="2315750423139697397">"системийг үйлдвэрийн үндсэн утгаар тохируулах"</string>
+    <string name="permdesc_masterClear" msgid="3665380492633910226">"Апп нь бүх датаг арилгах болон бүх суулгасан апп-г арилган системийг бүхэлд үйлдвэрийн тохиргоогоор бүрэн тохируулах боломжтой"</string>
+    <string name="permlab_setTime" msgid="2021614829591775646">"цагийн тохиргоо"</string>
+    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"Апп нь таблетын цагийг солих боломжтой."</string>
+    <string name="permdesc_setTime" product="default" msgid="1855702730738020">"Апп нь утасны цагийг солих боломжтой."</string>
+    <string name="permlab_setTimeZone" msgid="2945079801013077340">"цагийн бүсийн тохиргоо"</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Апп нь таблетын цагийн бүсийг солих боломжтой."</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Апп нь утасны цагийн бүсийг өөрчлөх боломжтой."</string>
+    <string name="permlab_accountManagerService" msgid="4829262349691386986">"AccountManagerService болж ажиллах"</string>
+    <string name="permdesc_accountManagerService" msgid="1948455552333615954">"Апп нь Акаунт гэрчлэгчрүү дуудлага хийх боломжтой."</string>
+    <string name="permlab_getAccounts" msgid="1086795467760122114">"төхөөрөмж дээрх акаунтыг олох"</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Апп нь таблетэд мэдэгдэж байгаа акаунтын жагсаалтыг авах боломжтой. Энд таны суулгасан аппликешнүүдийн үүсгэсэн бүх акаунтууд хамрагдана."</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Апп нь утсанд мэдэгдэж байгаа акаунтын жагсаалтыг авах боломжтой. Энд таны суулгасан аппликешнүүдийн үүсгэсэн бүх акаунтууд хамрагдана."</string>
+    <string name="permlab_authenticateAccounts" msgid="5265908481172736933">"акаунт үүсгэх болон нууц үг тохируулах"</string>
+    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"Апп нь акаунт үүсгэх, тэдгээрийн нууц үгийг тохируулах зэрэг акаунт удирдагчийн акаунт гэрчлэгчийн функцийг ашиглах боломжтой."</string>
+    <string name="permlab_manageAccounts" msgid="4983126304757177305">"акаунт нэмэх эсвэл хасах"</string>
+    <string name="permdesc_manageAccounts" msgid="8698295625488292506">"Апп нь акаунт нэмэх, устгах ба тэдний нууц үгийг устгах зэрэг үйлдлийг гүйцэтгэх боломжтой."</string>
+    <string name="permlab_useCredentials" msgid="235481396163877642">"төхөөрөмж дээрх акаунтыг ашиглах"</string>
+    <string name="permdesc_useCredentials" msgid="7984227147403346422">"Апп нь гэрчлэлийн бүтвэрийг хүсэх боломжтой."</string>
+    <string name="permlab_accessNetworkState" msgid="4951027964348974773">"сүлжээний холболтыг үзэх"</string>
+    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Апп нь сүлжээ байгаа болон холбогдсон эсэх зэрэг сүлжээний холболтын талаарх мэдээллийг харах боломжтой."</string>
+    <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"сүлжээнд бүрэн хандах"</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Апп нь сүлжээний сокетыг үүсгэх болон тусгай сүлжээний протокол ашиглах боломжтой. Хөтөч болон бусад аппликешнүүд Интернетээр дата илгээх боломжтой  тул энэ зөвшөөрөл нь Интернетээр дата илгээхэд шаардлагагүй."</string>
+    <string name="permlab_writeApnSettings" msgid="505660159675751896">"сүлжээний тохиргоо болон урсгалыг солих/таслах"</string>
+    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Апп нь сүлжээний тохиргоог солих болон сүлжээний бүх урсгалыг APN-н прокси болон портыг солих замаар таслах, хянах боломжтой. Хортой апп нь танд мэдэгдэлгүйгээр сүлжээний пакетыг хянах, дахин чиглүүлэх болон өөрчлөх боломжтой."</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_changeBackgroundDataSetting" msgid="1400666012671648741">"арын дата ашиглалтын тохиргоог солих"</string>
+    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Апп нь арын дата хэрэглээний тохиргоог солих боломжтой."</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="default" msgid="6851949706025349926">"Апп нь олон дамжуулал ашиглан Wi-Fi сүлжээн дэх бүх төхөөрөмжрүү пакет илгээх болон хүлээн авах боломжтой. Энэ нь олон дамжуулал ашиглахгүй горимоос илүү их тэжээл зарцуулна."</string>
+    <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"Блютүүт тохиргоонд хандах"</string>
+    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Апп нь дотоод блютүүт таблетын тохиргоог харах боломжтой ба хос болох төхөөрөмжтэй холболтыг зөвшөөрөх болон хийх боломжтой"</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="2405042267131496579">"WiMAX статусыг өөрчлөх"</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Апп нь 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="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_readSyncSettings" msgid="6201810008230503052">"синк тохиргоог унших"</string>
+    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Апп нь акаунтын синк тохиргоог унших боломжтой. Жишээ нь энэ нь Хүмүүс апп акаунттай синк хийгдсэн эсэхийг тодорхойлох боломжтой."</string>
+    <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"синкийг унтрааж асаах тохиргоо"</string>
+    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Апп нь акаунтын синк тохиргоог өөрчлөх боломжтой. Жишээ нь энэ нь Хүмүүс апп акаунттай синк хийхийг идэвхжүүлэх боломжтой."</string>
+    <string name="permlab_readSyncStats" msgid="7396577451360202448">"синк статистикийг унших"</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Апп нь синк үйлдэлийн түүх болон хэр их дата синк хийгдсэн зэрэг акаунтын синк статусыг унших боломжтой."</string>
+    <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"бүртгүүлсэн хангамжийг унших"</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Апп нь одоогийн синк хийгдсэн хангамжийн талаарх мэдээллийг авах боломжтой."</string>
+    <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"бүртгүүлсэн хангамжруу бичих"</string>
+    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"Апп нь таны одоогийн синк хийгдсэн хангамжийг өөрчлөх боломжтой. Хортой апп нь таны синк хийгдсэн хангамжийг өөрчлөх боломжтой."</string>
+    <string name="permlab_readDictionary" msgid="4107101525746035718">"таны толь бичигт нэмсэн нөхцөлийг унших"</string>
+    <string name="permdesc_readDictionary" msgid="659614600338904243">"Апп нь хэрэглэгч хэрэглэгчийн толь бичигт хадгалсан бүх үгс, нэрс болон хэлцийг унших боломжтой."</string>
+    <string name="permlab_writeDictionary" msgid="2183110402314441106">"хэрэглэгчийн толь бичигт үгс нэмэх"</string>
+    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Апп нь хэрэглэгчийн толь бичигт шинэ үг бичих боломжтой."</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"хамгаалагдсан санд хандах тест хийх"</string>
+    <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"хамгаалагдсан санд хандах тест хийх"</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"Апп нь дараагийн төхөөрөмжүүдэд ашиглах боломжтой болох SD карт зөвшөөрлийг тестлэх боломжтой."</string>
+    <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"Апп нь дараагийн төхөөрөмжүүдэд ашиглах боломжтой болох 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_mediaStorageWrite" product="default" msgid="6859839199706879015">"дотоод медиа сангийн контентыг өөрчлөх/устгах"</string>
+    <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Апп нь дотоод медиа сангийн контентыг өөрчлөх боломжтой."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"документ санг удирдах"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Апп нь документ санг удирдах боломжтой."</string>
+    <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"бүх хэрэглэгчдийн гадаар санд хандах"</string>
+    <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Апп нь бүх хэрэглэгчдийн гадаад санд хандах боломжтой."</string>
+    <string name="permlab_cache_filesystem" msgid="5656487264819669824">"кеш файлсистемд хандах"</string>
+    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Апп нь кеш файлсистемийг унших бичих боломжтой."</string>
+    <string name="permlab_use_sip" msgid="5986952362795870502">"Интернет дуудлага хийх/хүлээн авах"</string>
+    <string name="permdesc_use_sip" msgid="4717632000062674294">"Апп нь Интернет дуудлага хийх/хүлээн авахын тулд SIP үйлчилгээг ашиглах боломжтой."</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_markNetworkSocket" msgid="3658527214914959749">"соккетын тэмдгүүдийг өөрчлөх"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Апп-д чиглэлийн соккетын тэмдгийг өөрчлөх боломж олгоно"</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_invokeCarrierSetup" msgid="3699600833975117478">"үүрэн компанийн нийлүүлсэн тохируулгын апп-г өдөөх"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Эзэмшигчид үүрэн компанийн нийлүүлсэн тохируулах апп-г өдөөх боломж олгоно. Энгийн апп-уудад хэзээ ч ашиглагдахгүй."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"Сүлжээний байдлын талаар ажиглалтуудыг хүлээн авах"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Аппликешнд сүлжээний байдлын талаар ажиглалтуудыг хүлээн авахыг зөвшөөрнө. Энгийн апп-уудад хэзээ ч ашиглагдахгүй."</string>
+    <string name="policylab_limitPassword" msgid="4497420728857585791">"Нууц үгний дүрмийг тохируулах"</string>
+    <string name="policydesc_limitPassword" msgid="3252114203919510394">"Дэлгэц түгжих нууц үгэнд зөвшөөрөгдсөн тэмдэгт болон уртыг удирдах"</string>
+    <string name="policylab_watchLogin" msgid="914130646942199503">"Дэлгэц тайлах оролдлогыг хянах"</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Дэлгэц түгжигдсэн үед нууц үг буруу оруулалтын тоог хянах ба хэрэв хэт олон удаа нууц үгийг буруу оруулбал таблетыг түгжих болон таблетын бүх датаг арилгана"</string>
+    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Дэлгэц түгжигдсэн үед нууц үг буруу оруулалтын тоог хянах, ба хэрэв хэт олон удаа нууц үгийг буруу оруулбал утсыг түгжих болон утасны бүх датаг арилгана"</string>
+    <string name="policylab_resetPassword" msgid="2620077191242688955">"Дэлгэц түгжих нууц үгийг солих"</string>
+    <string name="policydesc_resetPassword" msgid="605963962301904458">"Дэлгэц түгжих нууц үгийг солих"</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="default" msgid="5096895604574188391">"Үйлдвэрийн дата утгыг өгсөнөөр утасны дата шууд арилгагдана."</string>
+    <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Төхөрөөмжийн глобал проксиг тохируулах"</string>
+    <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Бодлого идэвхтэй үед төхөөрөмжийн глобал проксиг ашиглахаар тохируулсан. Зөвхөн эхний төхөөрөмжийн админ л үр дүнтэй глобал проксиг тохируулна."</string>
+    <string name="policylab_expirePassword" msgid="885279151847254056">"Дэлгэц түгжих нууц үгний хүчинтэй хугацааг тохируулах"</string>
+    <string name="policydesc_expirePassword" msgid="1729725226314691591">"Дэлгэцний түгжих нууц үг хэр давтамжтай солигдохыг удирдах."</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="policylab_disableKeyguardFeatures" msgid="266329104542638802">"Түлхүүр хамгаалтын функцийг унтраах"</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="3467082272186534614">"Түлхүүр хамгаалалтын зарим функцийг ашиглахыг хориглох."</string>
+  <string-array name="phoneTypes">
+    <item msgid="8901098336658710359">"Гэрийн"</item>
+    <item msgid="869923650527136615">"Мобайл"</item>
+    <item msgid="7897544654242874543">"Ажлын"</item>
+    <item msgid="1103601433382158155">"Ажлын факс"</item>
+    <item msgid="1735177144948329370">"Гэрийн Факс"</item>
+    <item msgid="603878674477207394">"Пэйжер"</item>
+    <item msgid="1650824275177931637">"Бусад"</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>
+  </string-array>
+  <string-array name="postalAddressTypes">
+    <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="1359644565647383708">"Ажлын"</item>
+    <item msgid="7868549401053615677">"Бусад"</item>
+    <item msgid="3145118944639869809">"Тусгай"</item>
+  </string-array>
+  <string-array name="organizationTypes">
+    <item msgid="7546335612189115615">"Ажлын"</item>
+    <item msgid="4378074129049520373">"Бусад"</item>
+    <item msgid="3455047468583965104">"Тусгай"</item>
+  </string-array>
+  <string-array name="imProtocols">
+    <item msgid="8595261363518459565">"AIM"</item>
+    <item msgid="7390473628275490700">"Windows Live"</item>
+    <item msgid="7882877134931458217">"Yahoo"</item>
+    <item msgid="5035376313200585242">"Skype"</item>
+    <item msgid="7532363178459444943">"QQ"</item>
+    <item msgid="3713441034299660749">"Google Talk"</item>
+    <item msgid="2506857312718630823">"ICQ"</item>
+    <item msgid="1648797903785279353">"Jabber"</item>
+  </string-array>
+    <string name="phoneTypeCustom" msgid="1644738059053355820">"Тусгай"</string>
+    <string name="phoneTypeHome" msgid="2570923463033985887">"Гэрийн"</string>
+    <string name="phoneTypeMobile" msgid="6501463557754751037">"Мобайл"</string>
+    <string name="phoneTypeWork" msgid="8863939667059911633">"Ажлын"</string>
+    <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Ажлын факс"</string>
+    <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Гэрийн Факс"</string>
+    <string name="phoneTypePager" msgid="7582359955394921732">"Пэйжер"</string>
+    <string name="phoneTypeOther" msgid="1544425847868765990">"Бусад"</string>
+    <string name="phoneTypeCallback" msgid="2712175203065678206">"Буцаж холбоо барих"</string>
+    <string name="phoneTypeCar" msgid="8738360689616716982">"Машин"</string>
+    <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Байгууллагын үндсэн"</string>
+    <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string>
+    <string name="phoneTypeMain" msgid="6766137010628326916">"Үндсэн"</string>
+    <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Бусад факс"</string>
+    <string name="phoneTypeRadio" msgid="4093738079908667513">"Радио"</string>
+    <string name="phoneTypeTelex" msgid="3367879952476250512">"Tелекс"</string>
+    <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="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="eventTypeOther" msgid="7388178939010143077">"Бусад"</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="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="imTypeWork" msgid="1371489290242433090">"Ажлын"</string>
+    <string name="imTypeOther" msgid="5377007495735915478">"Бусад"</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>
+    <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
+    <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
+    <string name="imProtocolGoogleTalk" msgid="493902321140277304">"Цугларалт"</string>
+    <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">"Ажлын"</string>
+    <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="relationTypeBrother" msgid="8757913506784067713">"Ах"</string>
+    <string name="relationTypeChild" msgid="1890746277276881626">"Хүүхэд"</string>
+    <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"Дотоод Түнш"</string>
+    <string name="relationTypeFather" msgid="5228034687082050725">"Эцэг"</string>
+    <string name="relationTypeFriend" msgid="7313106762483391262">"Найз"</string>
+    <string name="relationTypeManager" msgid="6365677861610137895">"Менежер"</string>
+    <string name="relationTypeMother" msgid="4578571352962758304">"Эх"</string>
+    <string name="relationTypeParent" msgid="4755635567562925226">"Эцэг эх"</string>
+    <string name="relationTypePartner" msgid="7266490285120262781">"Түнш"</string>
+    <string name="relationTypeReferredBy" msgid="101573059844135524">"Дурдагдсан"</string>
+    <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="sipAddressTypeHome" msgid="6093598181069359295">"Гэрийн"</string>
+    <string name="sipAddressTypeWork" msgid="6920725730797099047">"Ажлын"</string>
+    <string name="sipAddressTypeOther" msgid="4408436162950119849">"Бусад"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN кодыг бичнэ үү"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK-г бичээд шинэ PIN код оруулна уу"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK код"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Шинэ PIN код"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><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">"Тайлах PIN-г оруулна уу"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Буруу PIN код."</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="8963839242565653192">"Үйлчилгээ байхгүй."</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="5347633784401285225">"Яаралтай дуудлага"</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="faceunlock_multiple_failures" msgid="754137583022792429">"Нүүрээр түгжээ тайлах оролдлогын тоо дээд хэмжээнээс хэтэрсэн"</string>
+    <string name="lockscreen_plugged_in" msgid="8057762828355572315">"Цэнэглэж байна, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_charged" msgid="321635745684060624">"Цэнэглэгдэв"</string>
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_low_battery" msgid="1482873981919249740">"Цэнэглэгчээ холбоно уу."</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="default" msgid="2186920585695169078">"Утсанд SIM карт байхгүй."</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_transport_prev_description" msgid="201594905152746886">"Өмнөх бичлэг товч"</string>
+    <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Дараагийн бичлэг товч"</string>
+    <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Түр зогсоох товч"</string>
+    <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Тоглуулах товч"</string>
+    <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Зогсоох товч"</string>
+    <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">"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">%d</xliff:g> удаа буруу зурлаа. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Та нууц үгээ <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу бичив. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Та PIN кодоо <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу бичив. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Та тайлах хээг <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу зурлаа. <xliff:g id="NUMBER_1">%d</xliff:g> удаа дахин буруу оруулбал, та таблетаа тайлахын тулд Google нэвтрэлтээ ашиглах шаардлагатай болно.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Та тайлах хээг <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу зурлаа. <xliff:g id="NUMBER_1">%d</xliff:g> удаа дахин буруу оролдвол, та таблетаа тайлахын тулд Google нэвтрэлтээ ашиглах шаардлагатай болно.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Та таблетыг тайлах гэж <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу оролдлоо. <xliff:g id="NUMBER_1">%d</xliff:g> удаа дахин буруу оролдвол таблет үйлдвэрийн үндсэн утгаараа тохируулагдах ба хэрэглэгчийн дата бүхэлдээ устана."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Та утсыг тайлах гэж <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу оролдлоо. <xliff:g id="NUMBER_1">%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="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_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_checking_password" msgid="7114627351286933867">"Шалгаж байна..."</string>
+    <string name="lockscreen_unlock_label" msgid="737440483220667054">"Тайлах"</string>
+    <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Дуу идэвхтэй"</string>
+    <string name="lockscreen_sound_off_label" msgid="996822825154319026">"Дууг хаагдсан"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Хээ эхэлж байна"</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Хээ цэвэрлэгдэв"</string>
+    <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Нүд нэмэгдсэн"</string>
+    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Хээ дуусав"</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_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_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>
+    <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_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>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"АБВ"</string>
+    <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_line" msgid="5764267235026120888">"Мөр"</string>
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
+    <string name="factorytest_failed" msgid="5410270329114212041">"Үйлдлвэрийн тест бүтэлгүйтэв"</string>
+    <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST үйлдэл нь зөвхөн /system/app-д суусан багцуудад дэмжигдэнэ."</string>
+    <string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST үйлдлийг хангах багц олдсонгүй."</string>
+    <string name="factorytest_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="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>
+    <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
+    <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
+    <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
+    <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
+    <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">"ZIP код"</string>
+    <string name="autofill_county" msgid="237073771020362891">"Муж"</string>
+    <string name="autofill_island" msgid="4020100875984667025">"Арал"</string>
+    <string name="autofill_district" msgid="8400735073392267672">"Дүүрэг"</string>
+    <string name="autofill_department" msgid="5343279462564453309">"Хэлтэс"</string>
+    <string name="autofill_prefecture" msgid="2028499485065800419">"Муж"</string>
+    <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="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_packageVerificationAgent" msgid="5568139100645829117">"багцийг тулгах"</string>
+    <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"Апп нь багцыг суулгаж болох эсэхийг шалгах боломжтой."</string>
+    <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"багц тулгагчтэй холбох"</string>
+    <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Эзэмшигч нь багц тулгагчдад хүсэлт тавих боломжтой. Энгийн апп-д хэрэглэгдэхгүй."</string>
+    <string name="permlab_serialPort" msgid="546083327654631076">"сериал портруу хандах"</string>
+    <string name="permdesc_serialPort" msgid="2991639985224598193">"Эзэмшигч нь SerialManager API ашиглан сериал портод хандах боломжтой."</string>
+    <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"контент нийлүүлэгчид гаднаас хандах"</string>
+    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Эзэмшигч нь шелээс контент нийлүүлэгчид хандах боломжтой. Энгийн апп-с хэрэглэхгүй."</string>
+    <string name="permlab_updateLock" msgid="3527558366616680889">"төхөөрөмжийн автомат шинэчлэлтийг хориглох"</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"Эзэмшигч нь төхөөрөмжийг дэвшүүлэхээр хэзээ дахин асаавал тохирох тухай системд мэдээлэл санал болгох боломжтой."</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>
+    <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="menu_space_shortcut_label" msgid="2410328639272162537">"зай"</string>
+    <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"оруулах"</string>
+    <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"устгах"</string>
+    <string name="search_go" msgid="8298016669822141719">"Хайх"</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="oneMonthDurationPast" msgid="7396384508953779925">"1 сарын өмнө"</string>
+    <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"1 сарын өмнө"</string>
+  <plurals name="num_seconds_ago">
+    <item quantity="one" msgid="4869870056547896011">"1 секундын өмнө"</item>
+    <item quantity="other" msgid="3903706804349556379">"<xliff:g id="COUNT">%d</xliff:g> секундын өмнө"</item>
+  </plurals>
+  <plurals name="num_minutes_ago">
+    <item quantity="one" msgid="3306787433088810191">"1 минутын өмнө"</item>
+    <item quantity="other" msgid="2176942008915455116">"<xliff:g id="COUNT">%d</xliff:g> минутын өмнө"</item>
+  </plurals>
+  <plurals name="num_hours_ago">
+    <item quantity="one" msgid="9150797944610821849">"1 цагийн өмнө"</item>
+    <item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> цагийн өмнө"</item>
+  </plurals>
+  <plurals name="last_num_days">
+    <item quantity="other" msgid="3069992808164318268">"Сүүлийн <xliff:g id="COUNT">%d</xliff:g> өдөр"</item>
+  </plurals>
+    <string name="last_month" msgid="3959346739979055432">"Сүүлийн сар"</string>
+    <string name="older" msgid="5211975022815554840">"Хуучин"</string>
+  <plurals name="num_days_ago">
+    <item quantity="one" msgid="861358534398115820">"өчигдөр"</item>
+    <item quantity="other" msgid="2479586466153314633">"<xliff:g id="COUNT">%d</xliff:g> өдрийн өмнө"</item>
+  </plurals>
+  <plurals name="in_num_seconds">
+    <item quantity="one" msgid="2729745560954905102">"1 секундын дараа"</item>
+    <item quantity="other" msgid="1241926116443974687">"<xliff:g id="COUNT">%d</xliff:g> секундын дараа"</item>
+  </plurals>
+  <plurals name="in_num_minutes">
+    <item quantity="one" msgid="8793095251325200395">"1 минутын дараа"</item>
+    <item quantity="other" msgid="3330713936399448749">"<xliff:g id="COUNT">%d</xliff:g> минутын дараа"</item>
+  </plurals>
+  <plurals name="in_num_hours">
+    <item quantity="one" msgid="7164353342477769999">"1 цагийн дараа"</item>
+    <item quantity="other" msgid="547290677353727389">"<xliff:g id="COUNT">%d</xliff:g> цагийн дараа"</item>
+  </plurals>
+  <plurals name="in_num_days">
+    <item quantity="one" msgid="5413088743009839518">"маргааш"</item>
+    <item quantity="other" msgid="5109449375100953247">"<xliff:g id="COUNT">%d</xliff:g> өдрийн дараа"</item>
+  </plurals>
+  <plurals name="abbrev_num_seconds_ago">
+    <item quantity="one" msgid="1849036840200069118">"1 секундын өмнө"</item>
+    <item quantity="other" msgid="3699169366650930415">"<xliff:g id="COUNT">%d</xliff:g> сек дараа"</item>
+  </plurals>
+  <plurals name="abbrev_num_minutes_ago">
+    <item quantity="one" msgid="6361490147113871545">"1 мин өмнө"</item>
+    <item quantity="other" msgid="851164968597150710">"<xliff:g id="COUNT">%d</xliff:g> минутын өмнө"</item>
+  </plurals>
+  <plurals name="abbrev_num_hours_ago">
+    <item quantity="one" msgid="4796212039724722116">"1 цагийн өмнө"</item>
+    <item quantity="other" msgid="6889970745748538901">"<xliff:g id="COUNT">%d</xliff:g> цагийн өмнө"</item>
+  </plurals>
+  <plurals name="abbrev_num_days_ago">
+    <item quantity="one" msgid="8463161711492680309">"өчигдөр"</item>
+    <item quantity="other" msgid="3453342639616481191">"<xliff:g id="COUNT">%d</xliff:g> өдрийн өмнө"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_seconds">
+    <item quantity="one" msgid="5842225370795066299">"1 сек дараа"</item>
+    <item quantity="other" msgid="5495880108825805108">"<xliff:g id="COUNT">%d</xliff:g> сек дараа"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_minutes">
+    <item quantity="one" msgid="562786149928284878">"1 мин дараа"</item>
+    <item quantity="other" msgid="4216113292706568726">"<xliff:g id="COUNT">%d</xliff:g> минутын дараа"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_hours">
+    <item quantity="one" msgid="3274708118124045246">"1 цагийн дараа"</item>
+    <item quantity="other" msgid="3705373766798013406">"<xliff:g id="COUNT">%d</xliff:g> цагийн дараа"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_days">
+    <item quantity="one" msgid="2178576254385739855">"маргааш"</item>
+    <item quantity="other" msgid="2973062968038355991">"<xliff:g id="COUNT">%d</xliff:g> өдрийн дараа"</item>
+  </plurals>
+    <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>
+    <string name="days" msgid="4774547661021344602">"өдөр"</string>
+    <string name="hour" msgid="2126771916426189481">"цаг"</string>
+    <string name="hours" msgid="894424005266852993">"цаг"</string>
+    <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="week" msgid="5617961537173061583">"7 хоног"</string>
+    <string name="weeks" msgid="6509623834583944518">"7 хоног"</string>
+    <string name="year" msgid="4001118221013892076">"жил"</string>
+    <string name="years" msgid="6881577717993213522">"жил"</string>
+  <plurals name="duration_seconds">
+    <item quantity="one" msgid="6962015528372969481">"1 секунд"</item>
+    <item quantity="other" msgid="1886107766577166786">"<xliff:g id="COUNT">%d</xliff:g> секунд"</item>
+  </plurals>
+  <plurals name="duration_minutes">
+    <item quantity="one" msgid="4915414002546085617">"1 минут"</item>
+    <item quantity="other" msgid="3165187169224908775">"<xliff:g id="COUNT">%d</xliff:g> минут"</item>
+  </plurals>
+  <plurals name="duration_hours">
+    <item quantity="one" msgid="8917467491248809972">"1 цаг"</item>
+    <item quantity="other" msgid="3863962854246773930">"<xliff:g id="COUNT">%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_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>
+    <string name="midnight" msgid="7166259508850457595">"шөнө дунд"</string>
+    <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="cut" msgid="3092569408438626261">"Таслах"</string>
+    <string name="copy" msgid="2681946229533511987">"Хуулах"</string>
+    <string name="paste" msgid="5629880836805036433">"Буулгах"</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="textSelectionCABTitle" msgid="5236850394370820357">"Текст сонгох"</string>
+    <string name="addToDictionary" msgid="4352161534510057874">"Толь бичигт нэмэх"</string>
+    <string name="deleteText" msgid="6979668428458199034">"Устгах"</string>
+    <string name="inputMethod" msgid="1653630062304567879">"Оруулах арга"</string>
+    <string name="editTextMenuTitle" msgid="4909135564941815494">"Текст үйлдэл"</string>
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Сангийн хэмжээ дутагдаж байна"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Зарим систем функц ажиллахгүй байна"</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="4653586947747330058">"Илүү мэдээлэл авах бол хүрэх эсвэл апп-г зогсооно уу ."</string>
+    <string name="ok" msgid="5970060430562524910">"Тийм"</string>
+    <string name="cancel" msgid="6442560571259935130">"Цуцлах"</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>
+    <string name="capital_on" msgid="1544682755514494298">"Идэвхтэй"</string>
+    <string name="capital_off" msgid="6815870386972805832">"Идэвхгүй"</string>
+    <string name="whichApplication" msgid="4533185947064773386">"Үйлдлийг дуусгах"</string>
+    <string name="alwaysUse" msgid="4583018368000610438">"Энэ ажиллагааг үндсэн болгох."</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="aerr_title" msgid="1905800560317137752"></string>
+    <string name="aerr_application" msgid="932628488013092776">"Харамсалтай, <xliff:g id="APPLICATION">%1$s</xliff:g> зогссон."</string>
+    <string name="aerr_process" msgid="4507058997035697579">"Харамсалтай нь <xliff:g id="PROCESS">%1$s</xliff:g> процесс зогссон."</string>
+    <string name="anr_title" msgid="4351948481459135709"></string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> хариу өгөхгүй байна.\n\nТа хаамаар байна уу?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"<xliff:g id="ACTIVITY">%1$s</xliff:g> активити хариу өгөхгүй байна.\n\nТа энийг хаах уу?"</string>
+    <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> хариу өгөхгүй байна. Та энийг хаамаар байна уу?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"<xliff:g id="PROCESS">%1$s</xliff:g> процесс хариу өгөхгүй байн.\n\nТа хаамаар байна уу?"</string>
+    <string name="force_close" msgid="8346072094521265605">"Тийм"</string>
+    <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">"Aпп дахин чиглүүлэгдэв"</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; Апп &gt; Татаж авсан дотроос дахин идэвхтэй болгох боломжтой."</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>
+    <string name="android_upgrading_title" msgid="1584192285441405746">"Андройдыг дэвшүүлж байна…"</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_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="1721681741617898865">"Апп сэлгэх бол хүрнэ үү"</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>
+    <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="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_silent_ringtone_selected" msgid="8310739960973156272">"Хонхны дууг чимээгүй болгов"</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">"Блютүүтын хэмжээ"</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="8129563480895990372">"Үндсэн хонхны ая (<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_unknown" msgid="5477919988701784788">"Үл мэдэгдэх хонхны ая"</string>
+  <plurals name="wifi_available">
+    <item quantity="one" msgid="6654123987418168693">"Wi-Fi сүлжээ ашиглах боломжтой"</item>
+    <item quantity="other" msgid="4192424489168397386">"Wi-Fi сүлжээ ашиглах боломжгүй"</item>
+  </plurals>
+  <plurals name="wifi_available_detailed">
+    <item quantity="one" msgid="1634101450343277345">"Нээллтэй Wi-Fi сүлжээ ашиглах боломжтой"</item>
+    <item quantity="other" msgid="7915895323644292768">"Нээлттэй Wi-Fi сүлжээ ашиглах боломжтой"</item>
+  </plurals>
+    <string name="wifi_available_sign_in" msgid="4029489716605255386">"Wi-Fi сүлжээнд нэвтэрнэ үү"</string>
+    <string name="network_available_sign_in" msgid="8495155593358054676">"Сүлжээнд нэвтрэх"</string>
+    <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
+    <skip />
+    <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi-д холбогдож чадсангүй"</string>
+    <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" Интернет холболт муу байна."</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_enabled_notification_message" msgid="1638949953993894335">"Тохируулах бол хүрнэ үү"</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_to_connect_title" msgid="4958803948658533637">"Холбох урилга"</string>
+    <string name="wifi_p2p_from_message" msgid="570389174731951769">"Хэнээс:"</string>
+    <string name="wifi_p2p_to_message" msgid="248968974522044099">"Хэнд:"</string>
+    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"Шаардлагатай PIN-г бичнэ үү:"</string>
+    <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</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="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_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="3492025719868078457">"Энэ таны мобайл акаунтад "<font fgcolor="#ffffb060">"төлбөр гаргаж"</font>" болзошгүй."</string>
+    <string name="sms_premium_short_code_details" msgid="5523826349105123687"><font fgcolor="#ffffb060">"Энэ таны мобайл акаунтад төлбөр гаргах болно."</font></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_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_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="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_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="usb_storage_activity_title" msgid="4465055157209648641">"USB масс сан"</string>
+    <string name="usb_storage_title" msgid="5901459041398751495">"USB холбогдсон"</string>
+    <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"Та өөрийн компьютертээ USB-р холбогдсон байна. Хэрэв та өөрийн компьютер болон өөрийн Андройдын USB сан хооронд файл хуулах бол доорх товчинд хүрнэ үү."</string>
+    <string name="usb_storage_message" product="default" msgid="805351000446037811">"Та өөрийн компьютертээ USB-р холбогдсон байна. Хэрэв та өөрийн компьютер болон өөрийн Андройдын USB сан хооронд файл хуулах бол доорх товчинд хүрнэ үү."</string>
+    <string name="usb_storage_button_mount" msgid="1052259930369508235">"USB санг асаах"</string>
+    <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"USB санг USB масс сан болгон ашиглахад алдаа гарав."</string>
+    <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"SD картыг USB масс сан болгон ашиглахад алдаа гарав."</string>
+    <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB холбогдсон"</string>
+    <string name="usb_storage_notification_message" msgid="939822783828183763">"Өөрийн компьютер- ээс/луу файл хуулах бол хүрнэ үү"</string>
+    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"USB санг унтраах"</string>
+    <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"USB санг унтраах бол хүрнэ үү."</string>
+    <string name="usb_storage_stop_title" msgid="660129851708775853">"USB сан ашиглагдаж байна"</string>
+    <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"USB санг унтраахаас өмнө өөрийн Андройдын SD картыг компьютерээсээ салгана(\"гаргана\") уу."</string>
+    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"USB санг унтраахаас өмнө өөрийн Андройдын SD картыг компьютерээсээ салгана(\"гаргана\") уу."</string>
+    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"USB санг унтраах"</string>
+    <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"USB санг унтраахад алдаа гарав. USB хостоо салгасан эсэхээ шалгаад дахин оролдоно уу."</string>
+    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"USB санг асаах"</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Хэрэв та USB санг асуувал таны ашиглаж байга зарим апп зогсох ба та USB сангаа унтраатал ашиглах боломжгүй байж болзошгүй."</string>
+    <string name="dlg_error_title" msgid="7323658469626514207">"USB ажиллагаа бүтэлгүйтэв"</string>
+    <string name="dlg_ok" msgid="7376953167039865701">"Тийм"</string>
+    <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Медиа төхөөрөмж болон холбогдов"</string>
+    <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Камер болгон холбов"</string>
+    <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Суулгагч болгон холбогдсон"</string>
+    <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB төхөөрөмжид холбогдов"</string>
+    <string name="usb_notification_message" msgid="2290859399983720271">"Бусад USB сонголт хийх бол хүрнэ үү."</string>
+    <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB санг форматлах уу?"</string>
+    <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD картыг форматлах уу?"</string>
+    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Таны USB санд хадгалагдсан бүх файл арилгагдана. Энэ үйлдлийг буцаах боломжгүй!"</string>
+    <string name="extmedia_format_message" product="default" msgid="14131895027543830">"Таны картан дээрх бүх дата устах болно."</string>
+    <string name="extmedia_format_button_format" msgid="4131064560127478695">"Форматлах"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"USB дебаг холбогдсон"</string>
+    <string name="adb_active_notification_message" msgid="1016654627626476142">"USB дебаг хийхийг идэвхгүй болгох бол хүрнэ үү."</string>
+    <string name="select_input_method" msgid="4653387336791222978">"Оруулах аргыг сонгоно уу"</string>
+    <string name="configure_input_methods" msgid="9091652157722495116">"Оруулах аргыг тохируулах"</string>
+    <string name="use_physical_keyboard" msgid="6203112478095117625">"Бодит гар"</string>
+    <string name="hardware" msgid="7517821086888990278">"Хардвер"</string>
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Гарын схемийг сонгох"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Гарын схемийг сонгох бол хүрнэ үү."</string>
+    <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="candidates_style" msgid="4333913089637062257"><u>"нэр дэвшигч"</u></string>
+    <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"USB санг бэлдэж байна"</string>
+    <string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"SD карт бэлдэж байна"</string>
+    <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"Алдааг шалгаж байна."</string>
+    <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"Хоосон USB сан"</string>
+    <string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"Хоосон SD карт"</string>
+    <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"USB сан хоосон эсвэл дэмжигдэхгүй файл системтэй."</string>
+    <string name="ext_media_nofs_notification_message" product="default" msgid="8641065641786923604">"SD карт хоосон эсвэл дэмжигдэхгүй файл систем."</string>
+    <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"Гэмтсэн USB сан"</string>
+    <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"Гэмтсэн SD карт"</string>
+    <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="1795917578395333280">"USB сан гэмтсэн байна. Дахин форматлаж үзнэ үү."</string>
+    <string name="ext_media_unmountable_notification_message" product="default" msgid="1753898567525568253">"SD карт гэмтсэн байна. Дахин форматлаж үзнэ үү."</string>
+    <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"USB санг санамсаргүй хасагдав"</string>
+    <string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"SD карт санамсаргүй хасагдав"</string>
+    <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"Дата хохирлоос сэргийлж USB санг сугалахаасаа өмнө салгаж байна уу."</string>
+    <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"Дата хохирлоос сэргийлж SD картыг хасахаасаа өмнө салгаж байна уу."</string>
+    <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"USB санг салгаж авахад аюулгүй."</string>
+    <string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"SD картыг хасахад аюулгүй"</string>
+    <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"USB санг сугалахад аюулгүй."</string>
+    <string name="ext_media_safe_unmount_notification_message" product="default" msgid="568841278138377604">"SD картаа салгаж авах аюулгүй."</string>
+    <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"Хасагдсан USB сан"</string>
+    <string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"Сугалсан SD карт"</string>
+    <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"USB сан сугалагдав. Шинэ медиаг хийнэ үү."</string>
+    <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"SD карт хасагдав. Шинийг хийнэ үү."</string>
+    <string name="activity_list_empty" msgid="1675388330786841066">"Таарах активити олдсонгүй."</string>
+    <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"компонент ашиглалтын статистикийг шинэчлэх"</string>
+    <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"Апп нь компонент хэрэглээний цуглуулагдсан статистикийг өөрчлөх боломжтой. Энгийн апп-д шаардлагагүй."</string>
+    <string name="permlab_copyProtectedData" msgid="4341036311211406692">"контент хуулах"</string>
+    <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Апп нь контентыг хуулах үндсэн контейнер үйлчилгээг дуудах боломжтой. Энгийн апп-д ашиглах боломжгүй."</string>
+    <string name="permlab_route_media_output" msgid="1642024455750414694">"Медиа гаралтыг чиглүүлэх"</string>
+    <string name="permdesc_route_media_output" msgid="4932818749547244346">"Аппликешн нь медиа гаралтыг бусад гадаад төхөөрөмжрүү чиглүүлэх боломжтой."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Түлхүүр хамгаалах аюулгүй санд хандах"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Аппликешн нь хамгаалалттай аюулгүй санд хандах боломжтой."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Түлхүүр хамгаалалтын харуулах болон далдлахыг удирдах"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Аппликешн нь түлхүүр хамгаалагчыг удирдах боломжтой."</string>
+    <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Өсгөх контрол дээр хоёр удаа товшино уу"</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>
+    <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_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="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>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"Ханын зураг солих"</string>
+    <string name="notification_listener_binding_label" msgid="2014162835481906429">"Мэдэгдэл сонсогч"</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="3011306607126450322">"Сүлжээг удирдах бол хүрнэ үү."</string>
+    <string name="vpn_text_long" msgid="6407351006249174473">"<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_error" msgid="6009249814034708175">"Байнгын VPN алдаа"</string>
+    <string name="vpn_lockdown_config" msgid="6415899150671537970">"Тохируулах бол хүрнэ үү"</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="8035230537563503262">"Машины горимоос гарах бол хүрнэ үү."</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"Модем болгох эсвэл идэвхтэй цэг болгох"</string>
+    <string name="tethered_notification_message" msgid="6857031760103062982">"Тохируулах бол хүрнэ үү."</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="throttle_warning_notification_title" msgid="4890894267454867276">"Мобайл дата хэрэглээ өндөр"</string>
+    <string name="throttle_warning_notification_message" msgid="3340822228599337743">"Мобайл дата хэрэглээний талаар дэлгэрэнгүй үзэх бол хүрнэ үү"</string>
+    <string name="throttled_notification_title" msgid="6269541897729781332">"Мобайл дата хязгаар хэтрэв"</string>
+    <string name="throttled_notification_message" msgid="5443457321354907181">"Мобайл дата хэрэглээний талаар дэлгэрэнгүй үзэх бол хүрнэ үү"</string>
+    <string name="no_matches" msgid="8129421908915840737">"Илэрц алга"</string>
+    <string name="find_on_page" msgid="1946799233822820384">"Хуудаснаас олох"</string>
+  <plurals name="matches_found">
+    <item quantity="one" msgid="8167147081136579439">"1 утга"</item>
+    <item quantity="other" msgid="4641872797067609177">"<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="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"USB санг салгаж байна…"</string>
+    <string name="progress_unmounting" product="default" msgid="1327894998409537190">"SD картыг салгаж байна…"</string>
+    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"USB санг арилгаж байна…"</string>
+    <string name="progress_erasing" product="default" msgid="6596988875507043042">"SD картыг цэвэрлэж байна…"</string>
+    <string name="format_error" product="nosdcard" msgid="6299769563624776948">"USB санг арилгаж чадсангүй."</string>
+    <string name="format_error" product="default" msgid="7315248696644510935">"SD картыг арилгаж чадсангүй."</string>
+    <string name="media_bad_removal" msgid="7960864061016603281">"SD картыг салгалгүйгээр хассан байна."</string>
+    <string name="media_checking" product="nosdcard" msgid="418188720009569693">"USB санг одоо шалгаж байна."</string>
+    <string name="media_checking" product="default" msgid="7334762503904827481">"SD картыг одоо шалгаж байна."</string>
+    <string name="media_removed" msgid="7001526905057952097">"SD картыг сугалсан байна."</string>
+    <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"USB санг одоо компьютерээс ашиглаж байна."</string>
+    <string name="media_shared" product="default" msgid="5706130568133540435">"USB санг одоо компьютерээс ашиглаж байна."</string>
+    <string name="media_unknown_state" msgid="729192782197290385">"Гадаад медиа үл мэдэгдэх статустай байна."</string>
+    <string name="share" msgid="1778686618230011964">"Хуваалцах"</string>
+    <string name="find" msgid="4808270900322985960">"Олох"</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="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_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>
+    <string name="add_account_button_label" msgid="3611982894853435874">"Аккаунт нэмэх"</string>
+    <string name="number_picker_increment_button" msgid="2412072272832284313">"Өсөх"</string>
+    <string name="number_picker_decrement_button" msgid="476050778386779067">"Бууруулах"</string>
+    <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> хүрээд барина уу."</string>
+    <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Өсгөх бол дээшээ бууруулах бол доошоо гулсуулна уу."</string>
+    <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Минут өсгөх"</string>
+    <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Минутыг бууруулах"</string>
+    <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Цаг өсгөх"</string>
+    <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Цаг бууруулах"</string>
+    <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"PM тохируулах"</string>
+    <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"AM тохируулах"</string>
+    <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Сар өсгөх"</string>
+    <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Сарыг бууруулах"</string>
+    <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Өдөр өсгөх"</string>
+    <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Өдрийг бууруулах"</string>
+    <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Жилийг өсгөх"</string>
+    <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Жил бууруулах"</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">"Шифт"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Оруулах"</string>
+    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Апп сонгох"</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">"Бариулыг гулсуулна. Хүрээд хүлээнэ."</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-г гулсуулах."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"<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="description_direction_right" msgid="8034433242579600980">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> хийх бол баруунлуу гулсуулах."</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Тайлах"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Камер"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Чимээгүй"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Дуунууд идэвхтэй"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Хайх"</string>
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Түгжээг тайлах бол татна уу"</string>
+    <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Нууц үгний дуудлагыг сонсох бол чихэвчийг залгана уу."</string>
+    <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Цэг."</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="4891916833657929263">"Дотоод сан"</string>
+    <string name="storage_sd_card" msgid="3282948861378286745">"SD карт"</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="1955638862122232342">"Дата хэрэглээний анхааруулга"</string>
+    <string name="data_usage_warning_body" msgid="2814673551471969954">"Ашиглалт болон тохиргоог харах бол хүрнэ үү."</string>
+    <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-3G дата идэвхгүй болов"</string>
+    <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G дата идэвхгүй байна"</string>
+    <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Мобайл дата идэвхгүй"</string>
+    <string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"Wi-Fi дата идэвхгүй"</string>
+    <string name="data_usage_limit_body" msgid="3317964706973601386">"Идэвхжүүлэх бол хүрнэ үү."</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_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="6741521330997452990">"Хязгаарлалтыг хасах бол хүрнэ үү."</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>
+    <string name="org_unit" msgid="7265981890422070383">"Байгууллагын нэгж:"</string>
+    <string name="issued_by" msgid="2647584988057481566">"Гаргасан:"</string>
+    <string name="validity_period" msgid="8818886137545983110">"Хүчинтэй байх:"</string>
+    <string name="issued_on" msgid="5895017404361397232">"Гаргасан:"</string>
+    <string name="expires_on" msgid="3676242949915959821">"Хүртэл хүчинтэй:"</string>
+    <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>
+    <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Бүгдийг харах"</string>
+    <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Активити сонгох"</string>
+    <string name="share_action_provider_share_with" msgid="5247684435979149216">"Хуваалцах"</string>
+    <string name="status_bar_device_locked" msgid="3092703448690669768">"Төхөөрөмж түгжигдсэн."</string>
+    <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="3245653681008218030">"Илгээж байна ..."</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="default_audio_route_name" product="tablet" msgid="4617053898167127471">"Таблет"</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">"Блютүүт аудио"</string>
+    <string name="wireless_display_route_description" msgid="9070346425023979651">"Утасгүй дэлгэц"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Дууссан"</string>
+    <string name="media_route_button_content_description" msgid="5758553567065145276">"Медиа гаралт"</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>
+    <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_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="wifi_display_notification_title" msgid="2223050649240326557">"Утасгүй дэлгэц холбогдов"</string>
+    <string name="wifi_display_notification_message" msgid="4498802012464170685">"Энэ дэлгэц өөр төхөөрөмжийг харуулж байна"</string>
+    <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Салгах"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Яаралтай дуудлага"</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">"PIN буруу"</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">"SIM PIN оруулна уу"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN оруулна уу"</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">"Хүссэн PIN кодоо оруулна уу"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Хүссэн PIN кодоо дахин оруулна уу"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM картны түгжээг гаргаж байна…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Буруу PIN код."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4-8 тооноос бүтэх PIN-г бичнэ үү."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK код 8-с цөөнгүй тооноос бүтнэ."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Зөв PUK кодыг дахин оруулна уу. Давтан оролдвол SIM нь бүрмөсөн идэвхгүй болгоно."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN кодууд таарахгүй байна"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Хээ оруулах оролдлого хэт олон"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Түгжээг тайлах бол Google акаунтаараа нэвтэрнэ үү."</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"Акаунт шалгаж байна…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Та PIN кодоо <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу бичив. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Та PIN кодоо <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу бичив. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Та тайлах хээг <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу зурлаа. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Та таблетыг тайлах гэж <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу оролдлоо. <xliff:g id="NUMBER_1">%d</xliff:g> удаа дахин буруу оролдвол таблет үйлдвэрийн үндсэн утгаараа тохируулагдах ба хэрэглэгчийн дата бүхэлдээ устана."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Та утсыг тайлах гэж <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу оролдлоо. <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> удаа буруу зурлаа. <xliff:g id="NUMBER_1">%d</xliff:g> удаа дахин буруу оруулбал, та таблетаа тайлахын тулд имэйл акаунт шаардлагатай болно.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Та тайлах хээг <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу зурлаа. <xliff:g id="NUMBER_1">%d</xliff:g> удаа дахин буруу оруулбал, та утсаа тайлахын тулд имэйл акаунтаа ашиглах шаардлагатай болно.\n\n <xliff:g id="NUMBER_2">%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="7324161939475478066">"Дууг санал болгосон дээд төвшинөөс өсгөх үү. \n Өндөр дуугаар урт хугацаанд сонсох нь таны сонсголд хортой."</string>
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Хялбар горимыг идэвхжүүлэх бол хоёр хуруугаараа доошлуулаад хүлээнэ үү."</string>
+    <string name="accessibility_enabled" msgid="1381972048564547685">"Хялбаршуулсан горим идэвхжив."</string>
+    <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Хандалт цуцлагдсан."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Одоогийн хэрэглэгч <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="app_no_restricted_accounts" msgid="5739463249673727736">"Энэ аппликешн хязгаарлагдсан профайлын акаунтыг дэмжихгүй."</string>
+    <string name="app_not_found" msgid="3429141853498927379">"Энэ ажиллагааг зохицуулах аппликешн олдсонгүй."</string>
+    <string name="revoke" msgid="5404479185228271586">"Цуцлах"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Цуцлагдсан"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Контентыг бичих явцад алдаа гарсан"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN оруулна уу"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Одоогийн PIN"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Шинэ PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Шинэ PIN-г баталгаажуулах"</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_too_short" msgid="8173982756265777792">"PIN хэт богино байна. Хамгийн багадаа 4 цифртэй байх ёстой."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="4835639969503729874">"Буруу PIN. 1 секундын дараа дахин оролдоно уу."</item>
+    <item quantity="other" msgid="8030607343223287654">"Буруу PIN. <xliff:g id="COUNT">%d</xliff:g> секундын дараа дахин оролдоно уу."</item>
+  </plurals>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Баганыг харуулахын тулд дэлгэцийн ирмэгийг шудрана уу"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Системийн баганыг гаргахын тулд дэлгэцийн ирмэгээс шудрана уу"</string>
+</resources>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
new file mode 100644
index 0000000..1fed75d
--- /dev/null
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -0,0 +1,1602 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<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="5973789783504771878">"KB"</string>
+    <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
+    <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
+    <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
+    <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
+    <string name="untitled" msgid="4638956954852782576">"&lt;Tidak bertajuk&gt;"</string>
+    <string name="ellipsis" msgid="7899829516048813237">"..."</string>
+    <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
+    <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Tiada nombor telefon)"</string>
+    <string name="unknownName" msgid="2277556546742746522">"(Tidak diketahui)"</string>
+    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Mel suara"</string>
+    <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
+    <string name="mmiError" msgid="5154499457739052907">"Masalah sambungan atau kod MMI tidak sah"</string>
+    <string name="mmiFdnError" msgid="5224398216385316471">"Pengendalian dihadkan kepada nombor dailan tetap sahaja."</string>
+    <string name="serviceEnabled" msgid="8147278346414714315">"Perkhidmatan telah didayakan."</string>
+    <string name="serviceEnabledFor" msgid="6856228140453471041">"Perkhidmatan didayakan untuk:"</string>
+    <string name="serviceDisabled" msgid="1937553226592516411">"Perkhidmatan telah dilumpuhkan."</string>
+    <string name="serviceRegistered" msgid="6275019082598102493">"Pendaftaran berjaya."</string>
+    <string name="serviceErased" msgid="1288584695297200972">"Pemadaman berjaya."</string>
+    <string name="passwordIncorrect" msgid="7612208839450128715">"Kata laluan salah"</string>
+    <string name="mmiComplete" msgid="8232527495411698359">"MMI selesai."</string>
+    <string name="badPin" msgid="9015277645546710014">"PIN lama yang anda taipkan tidak betul."</string>
+    <string name="badPuk" msgid="5487257647081132201">"Kod PUK yang anda taipkan tidak betul."</string>
+    <string name="mismatchPin" msgid="609379054496863419">"PIN yang anda taip tidak sepadan."</string>
+    <string name="invalidPin" msgid="3850018445187475377">"Taipkan PIN yang mengandungi 4 hingga 8 nombor."</string>
+    <string name="invalidPuk" msgid="8761456210898036513">"Taipkan PUK yang mempunyai 8 nombor atau lebih panjang."</string>
+    <string name="needPuk" msgid="919668385956251611">"Kad SIM anda dikunci PUK. Taipkan kod PUK untuk membuka kuncinya."</string>
+    <string name="needPuk2" msgid="4526033371987193070">"Taipkan PUK2 untuk menyahsekat kad SIM."</string>
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
+    <string name="ClipMmi" msgid="6952821216480289285">"ID Pemanggil Masuk"</string>
+    <string name="ClirMmi" msgid="7784673673446833091">"ID Pemanggil Keluar"</string>
+    <string name="CfMmi" msgid="5123218989141573515">"Pemajuan panggilan"</string>
+    <string name="CwMmi" msgid="9129678056795016867">"Panggilan menunggu"</string>
+    <string name="BaMmi" msgid="455193067926770581">"Sekatan panggilan"</string>
+    <string name="PwdMmi" msgid="7043715687905254199">"Tukar kata laluan"</string>
+    <string name="PinMmi" msgid="3113117780361190304">"Penukaran PIN"</string>
+    <string name="CnipMmi" msgid="3110534680557857162">"Nombor panggilan ada"</string>
+    <string name="CnirMmi" msgid="3062102121430548731">"Nombor panggilan terhad"</string>
+    <string name="ThreeWCMmi" msgid="9051047170321190368">"Panggilan tiga hala"</string>
+    <string name="RuacMmi" msgid="7827887459138308886">"Penolakan panggilan mengganggu yang tidak diingini"</string>
+    <string name="CndMmi" msgid="3116446237081575808">"Penghantaran nombor panggilan"</string>
+    <string name="DndMmi" msgid="1265478932418334331">"Jangan ganggu"</string>
+    <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"ID pemanggil secara lalainya ditetapkan kepada terhad. Panggilan seterusnya: Terhad"</string>
+    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"ID pemanggil secara lalainya ditetapkan kepada terhad. Panggilan seterusnya: Tidak terhad"</string>
+    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"ID pemanggil secara lalainya ditetapkan kepada tidak terhad. Panggilan seterusnya: Terhad"</string>
+    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"ID pemanggil secara lalainya ditetapkan kepada tidak dihadkan. Panggilan seterusnya: Tidak terhad"</string>
+    <string name="serviceNotProvisioned" msgid="8614830180508686666">"Perkhidmatan yang tidak diuntukkan."</string>
+    <string name="CLIRPermanent" msgid="3377371145926835671">"Anda tidak boleh mengubah tetapan ID pemanggil."</string>
+    <string name="RestrictedChangedTitle" msgid="5592189398956187498">"Akses terhad diubah"</string>
+    <string name="RestrictedOnData" msgid="8653794784690065540">"Perkhidmatan data disekat."</string>
+    <string name="RestrictedOnEmergency" msgid="6581163779072833665">"Perkhidmatan kecemasan disekat."</string>
+    <string name="RestrictedOnNormal" msgid="4953867011389750673">"Perkhidmatan suara disekat."</string>
+    <string name="RestrictedOnAllVoice" msgid="3396963652108151260">"Semua perkhidmatan suara disekat."</string>
+    <string name="RestrictedOnSms" msgid="8314352327461638897">"Perkhidmatan SMS disekat."</string>
+    <string name="RestrictedOnVoiceData" msgid="996636487106171320">"Perkhidmatan suara/data disekat."</string>
+    <string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Perkhidmatan suara/SMS disekat."</string>
+    <string name="RestrictedOnAll" msgid="5643028264466092821">"Semua perkhidmatan suara/data/SMS disekat."</string>
+    <string name="serviceClassVoice" msgid="1258393812335258019">"Suara"</string>
+    <string name="serviceClassData" msgid="872456782077937893">"Data"</string>
+    <string name="serviceClassFAX" msgid="5566624998840486475">"FAKS"</string>
+    <string name="serviceClassSMS" msgid="2015460373701527489">"SMS"</string>
+    <string name="serviceClassDataAsync" msgid="4523454783498551468">"Tak segerak"</string>
+    <string name="serviceClassDataSync" msgid="7530000519646054776">"Penyegerakan"</string>
+    <string name="serviceClassPacket" msgid="6991006557993423453">"Bingkisan"</string>
+    <string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
+    <string name="roamingText0" msgid="7170335472198694945">"Penunjuk Perayauan Dihidupkan"</string>
+    <string name="roamingText1" msgid="5314861519752538922">"Penunjuk Perayauan Dimatikan"</string>
+    <string name="roamingText2" msgid="8969929049081268115">"Penunjuk Perayauan Berkelip"</string>
+    <string name="roamingText3" msgid="5148255027043943317">"Di luar kawasan kejiranan"</string>
+    <string name="roamingText4" msgid="8808456682550796530">"Di luar Bangunan"</string>
+    <string name="roamingText5" msgid="7604063252850354350">"Perayauan - Sistem Diutamakan"</string>
+    <string name="roamingText6" msgid="2059440825782871513">"Perayauan - Sistem Tersedia"</string>
+    <string name="roamingText7" msgid="7112078724097233605">"Perayauan - Rakan Kongsi Gabungan"</string>
+    <string name="roamingText8" msgid="5989569778604089291">"Perayauan - Rakan Kongsi Premium"</string>
+    <string name="roamingText9" msgid="7969296811355152491">"Perayauan - Kefungsian Perkhidmatan Penuh"</string>
+    <string name="roamingText10" msgid="3992906999815316417">"Perayauan - Kefungsian Perkhidmatan Separa"</string>
+    <string name="roamingText11" msgid="4154476854426920970">"Sepanduk Perayauan Dihidupkan"</string>
+    <string name="roamingText12" msgid="1189071119992726320">"Sepanduk Perayauan Dimatikan"</string>
+    <string name="roamingTextSearching" msgid="8360141885972279963">"Mencari Perkhidmatan"</string>
+    <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Tidak dimajukan"</string>
+    <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
+    <string name="cfTemplateForwardedTime" msgid="9206251736527085256">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> selepas <xliff:g id="TIME_DELAY">{2}</xliff:g> saat"</string>
+    <string name="cfTemplateRegistered" msgid="5073237827620166285">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Tidak dimajukan"</string>
+    <string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Tidak dimajukan"</string>
+    <string name="fcComplete" msgid="3118848230966886575">"Kod ciri selesai."</string>
+    <string name="fcError" msgid="3327560126588500777">"Masalah sambungan atau kod ciri tidak sah."</string>
+    <string name="httpErrorOk" msgid="1191919378083472204">"OK"</string>
+    <string name="httpError" msgid="7956392511146698522">"Berlaku ralat rangkaian."</string>
+    <string name="httpErrorLookup" msgid="4711687456111963163">"Tidak menemui URL."</string>
+    <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"Skema pengesahan tapak tidak disokong."</string>
+    <string name="httpErrorAuth" msgid="1435065629438044534">"Tidak dapat mengesahkan."</string>
+    <string name="httpErrorProxyAuth" msgid="1788207010559081331">"Pengesahan melalui pelayan proksi tidak berjaya."</string>
+    <string name="httpErrorConnect" msgid="8714273236364640549">"Tidak dapat menyambung ke pelayan."</string>
+    <string name="httpErrorIO" msgid="2340558197489302188">"Tidak dapat berkomunikasi dengan pelayan. Cuba sebentar lagi."</string>
+    <string name="httpErrorTimeout" msgid="4743403703762883954">"Sambungan ke pelayan tamat masa."</string>
+    <string name="httpErrorRedirectLoop" msgid="8679596090392779516">"Halaman ini mengandungi terlalu banyak pengubahhalaan pelayan."</string>
+    <string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"Protokol tidak disokong."</string>
+    <string name="httpErrorFailedSslHandshake" msgid="96549606000658641">"Tidak dapat mewujudkan sambungan selamat."</string>
+    <string name="httpErrorBadUrl" msgid="3636929722728881972">"Tidak dapat membuka halaman kerana URL tidak sah."</string>
+    <string name="httpErrorFile" msgid="2170788515052558676">"Tidak dapat mengakses fail."</string>
+    <string name="httpErrorFileNotFound" msgid="6203856612042655084">"Tidak menemui fail yang diminta."</string>
+    <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Terlalu banyak permintaan sedang diproses. Cuba sebentar lagi."</string>
+    <string name="notification_title" msgid="8967710025036163822">"Ralat log masuk untuk <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string>
+    <string name="contentServiceSync" msgid="8353523060269335667">"Penyegerakan"</string>
+    <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Penyegerakan"</string>
+    <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Terlalu banyak pemadaman <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
+    <string name="low_memory" product="tablet" msgid="6494019234102154896">"Storan tablet penuh. Padamkan beberapa fail untuk mengosongkan ruang."</string>
+    <string name="low_memory" product="default" msgid="3475999286680000541">"Storan telefon penuh. Padamkan beberapa fail untuk mengosongkan ruang."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Rangkaian mungkin dipantau"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
+    <string name="me" msgid="6545696007631404292">"Saya"</string>
+    <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Pilihan tablet"</string>
+    <string name="power_dialog" product="default" msgid="1319919075463988638">"Pilihan telefon"</string>
+    <string name="silent_mode" msgid="7167703389802618663">"Mod senyap"</string>
+    <string name="turn_on_radio" msgid="3912793092339962371">"Hidupkan wayarles"</string>
+    <string name="turn_off_radio" msgid="8198784949987062346">"Matikan wayarles"</string>
+    <string name="screen_lock" msgid="799094655496098153">"Kunci skrin"</string>
+    <string name="power_off" msgid="4266614107412865048">"Matikan kuasa"</string>
+    <string name="silent_mode_silent" msgid="319298163018473078">"Pendering dimatikan"</string>
+    <string name="silent_mode_vibrate" msgid="7072043388581551395">"Pendering bergetar"</string>
+    <string name="silent_mode_ring" msgid="8592241816194074353">"Pendering dihidupkan"</string>
+    <string name="shutdown_progress" msgid="2281079257329981203">"Mematikan..."</string>
+    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Tablet anda akan dimatikan."</string>
+    <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Telefon anda akan dimatikan."</string>
+    <string name="shutdown_confirm_question" msgid="2906544768881136183">"Adakah anda mahu menutup?"</string>
+    <string name="reboot_safemode_title" msgid="7054509914500140361">"But semula ke mod selamat"</string>
+    <string name="reboot_safemode_confirm" msgid="55293944502784668">"Adakah anda mahu but semula ke dalam mod selamat? Ini akan melumpuhkan semua aplikasi pihak ketiga yang telah anda pasang. Semua aplikasi itu akan dipulihkan semula apabila anda membut semula."</string>
+    <string name="recent_tasks_title" msgid="3691764623638127888">"Baru-baru ini"</string>
+    <string name="no_recent_tasks" msgid="8794906658732193473">"Tiada apl terbaharu"</string>
+    <string name="global_actions" product="tablet" msgid="408477140088053665">"Pilihan tablet"</string>
+    <string name="global_actions" product="default" msgid="2406416831541615258">"Pilihan telefon"</string>
+    <string name="global_action_lock" msgid="2844945191792119712">"Kunci skrin"</string>
+    <string name="global_action_power_off" msgid="4471879440839879722">"Matikan kuasa"</string>
+    <string name="global_action_bug_report" msgid="7934010578922304799">"Laporan pepijat"</string>
+    <string name="bugreport_title" msgid="2667494803742548533">"Ambil laporan pepijat"</string>
+    <string name="bugreport_message" msgid="398447048750350456">"Ini akan mengumpul maklumat tentang keadaan peranti semasa anda untuk dihantarkan sebagai mesej e-mel. Proses ini akan mengambil sedikit masa bermula dari laporan pepijat sehingga siap untuk dihantar; jadi diharap bersabar."</string>
+    <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Mod senyap"</string>
+    <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Bunyi DIMATIKAN"</string>
+    <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Bunyi DIHIDUPKAN"</string>
+    <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Mod pesawat"</string>
+    <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Mod Pesawat DIHIDUPKAN"</string>
+    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Mod Pesawat DIMATIKAN"</string>
+    <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
+    <string name="safeMode" msgid="2788228061547930246">"Mod selamat"</string>
+    <string name="android_system_label" msgid="6577375335728551336">"Sistem Android"</string>
+    <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Perkhidmatan yang anda perlu bayar"</string>
+    <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Melakukan perkara yang boleh mengenakan bayaran kepada anda."</string>
+    <string name="permgrouplab_messages" msgid="7521249148445456662">"Mesej anda"</string>
+    <string name="permgroupdesc_messages" msgid="7821999071003699236">"Membaca dan menulis SMS, e-mel, dan mesej lain."</string>
+    <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Maklumat peribadi anda"</string>
+    <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"Akses langsung ke maklumat tentang anda, yang disimpan pada kad kenalan anda."</string>
+    <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Maklumat sosial anda"</string>
+    <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Akses langsung ke maklumat tentang kenalan anda dan sambungan sosial."</string>
+    <string name="permgrouplab_location" msgid="635149742436692049">"Lokasi anda"</string>
+    <string name="permgroupdesc_location" msgid="5704679763124170100">"Pantau lokasi fizikal anda."</string>
+    <string name="permgrouplab_network" msgid="5808983377727109831">"Komunikasi rangkaian"</string>
+    <string name="permgroupdesc_network" msgid="4478299413241861987">"Akses pelbagai ciri rangkaian."</string>
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"Bluetooth"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"Akses peranti dan rangkaian melalui Bluetooth."</string>
+    <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"Tetapan Audio"</string>
+    <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"Tukar tetapan audio."</string>
+    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Menjejaskan Bateri"</string>
+    <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Gunakan ciri yang boleh menghabiskan bateri dengan cepat."</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendar"</string>
+    <string name="permgroupdesc_calendar" msgid="5777534316982184416">"Akses langsung ke kalendar dan acara."</string>
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"Baca Kamus Pengguna"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"Baca perkataan di dalam kamus pengguna."</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"Tulis Kamus Pengguna"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"Tambah perkataan ke kamus pengguna."</string>
+    <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Penanda halaman dan Sejarah"</string>
+    <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Akses langsung ke penanda halaman dan sejarah penyemak imbas."</string>
+    <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"Penggera"</string>
+    <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"Tetapkan jam penggera."</string>
+    <string name="permgrouplab_voicemail" msgid="4162237145027592133">"Mel suara"</string>
+    <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"Akses langsung ke mel suara."</string>
+    <string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
+    <string name="permgroupdesc_microphone" msgid="7106618286905738408">"Akses langsung ke mikrofon untuk merakam audio."</string>
+    <string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
+    <string name="permgroupdesc_camera" msgid="2933667372289567714">"Akses langsung ke kamera untuk merakam imej atau video."</string>
+    <string name="permgrouplab_screenlock" msgid="8275500173330718168">"Kunci skrin"</string>
+    <string name="permgroupdesc_screenlock" msgid="7067497128925499401">"Keupayaan untuk mempengaruhi kelakuan skrin kunci pada peranti anda."</string>
+    <string name="permgrouplab_appInfo" msgid="8028789762634147725">"Maklumat aplikasi anda"</string>
+    <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"Keupayaan untuk mempengaruhi tingkah laku aplikasi lain pada peranti anda."</string>
+    <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"Kertas dinding"</string>
+    <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"Tukar tetapan kertas dinding peranti."</string>
+    <string name="permgrouplab_systemClock" msgid="406535759236612992">"Jam"</string>
+    <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"Tukar masa peranti atau zon masa."</string>
+    <string name="permgrouplab_statusBar" msgid="2095862568113945398">"Bar Status"</string>
+    <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"Tukar tetapan bar status peranti."</string>
+    <string name="permgrouplab_syncSettings" msgid="3341990986147826541">"Tetapan Penyegerakan"</string>
+    <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"Akses ke tetapan segerakan."</string>
+    <string name="permgrouplab_accounts" msgid="3359646291125325519">"Akaun anda"</string>
+    <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Akses akaun yang tersedia."</string>
+    <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Kawalan perkakasan"</string>
+    <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Akses langsung kepada perkakasan pada set tangan."</string>
+    <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Panggilan telefon"</string>
+    <string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"Memantau, merekodkan dan memproses panggilan telefon."</string>
+    <string name="permgrouplab_systemTools" msgid="4652191644082714048">"Alatan sistem"</string>
+    <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"Akses dan kawalan peringkat lebih rendah bagi sistem."</string>
+    <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"Alatan pembangunan"</string>
+    <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"Ciri hanya diperlukan untuk pembangun apl."</string>
+    <string name="permgrouplab_display" msgid="4279909676036402636">"Aplikasi UI Lain"</string>
+    <string name="permgroupdesc_display" msgid="6051002031933013714">"Mempengaruhi UI aplikasi lain."</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"Storan"</string>
+    <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Akses storan USB."</string>
+    <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Akses kad SD."</string>
+    <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"Ciri kebolehaksesan"</string>
+    <string name="permgroupdesc_accessibilityFeatures" msgid="4205196881678144335">"Ciri yang boleh diminta oleh teknologi bantuan."</string>
+    <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Dapatkan kembali kandungan tetingkap"</string>
+    <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Periksa kandungan tetingkap yang berinteraksi dengan anda."</string>
+    <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Hidupkan Jelajah melalui Sentuhan"</string>
+    <string name="capability_desc_canRequestTouchExploration" msgid="5800552516779249356">"Item yang disentuh akan disebut dengan kuat dan skrin boleh dijelajah menggunakan gerak isyarat."</string>
+    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Hidupkan kebolehcapaian web dipertingkat"</string>
+    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Skrip boleh dipasang untuk menjadikan kandungan apl lebih mudah diakses."</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Perhatikan teks yang anda taip"</string>
+    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Berserta data peribadi seperti nombor kad kredit dan kata laluan."</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"lumpuhkan atau ubah suai bar status"</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"Membenarkan apl melumpuhkan bar status atau menambah dan mengalih keluar ikon sistem."</string>
+    <string name="permlab_statusBarService" msgid="7247281911387931485">"bar status"</string>
+    <string name="permdesc_statusBarService" msgid="716113660795976060">"Membenarkan apl menjadi bar status."</string>
+    <string name="permlab_expandStatusBar" msgid="1148198785937489264">"kembangkan/runtuhkan bar status"</string>
+    <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"Membenarkan apl mengembangkan atau meruntuhkan bar status."</string>
+    <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"tukar laluan panggilan keluar"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Membenarkan apl memproses panggilan keluar dan menukar nombor yang perlu didail. Kebenaran ini membolehkan apl memantau, mengalih atau menghalang panggilan keluar."</string>
+    <string name="permlab_receiveSms" msgid="8673471768947895082">"terima mesej teks (SMS)"</string>
+    <string name="permdesc_receiveSms" msgid="6424387754228766939">"Membenarkan apl menerima dan memproses mesej SMS. Ini bermakna apl boleh memantau atau memadam mesej yang dihantar ke peranti anda tanpa menunjukkannya kepada anda."</string>
+    <string name="permlab_receiveMms" msgid="1821317344668257098">"terima mesej teks (MMS)"</string>
+    <string name="permdesc_receiveMms" msgid="533019437263212260">"Membenarkan apl menerima dan memproses mesej MMS. Ini bermakna apl boleh memantau atau memadam mesej yang dihantar ke peranti anda tanpa menunjukkannya kepada anda."</string>
+    <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"terima siaran kecemasan"</string>
+    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Membenarkan apl untuk menerima dan memproses mesej siaran kecemasan. Kebenaran ini hanya tersedia kepada apl sistem."</string>
+    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"baca mesej siaran sel"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Membolehkan apl membaca mesej siaran sel yang diterima oleh peranti anda. Isyarat siaran sel dihantar di beberapa lokasi untuk memberi amaran kepada anda tentang situasi kecemasan. Apl hasad boleh mengganggu prestasi atau operasi peranti anda apabila siaran sel kecemasan diterima."</string>
+    <string name="permlab_sendSms" msgid="5600830612147671529">"hantar mesej SMS"</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"Membenarkan apl menghantar mesej SMS. Ini boleh menyebabkan caj di luar jangkaan. Apl hasad boleh membuat anda kerugian wang dengan menghantar mesej tanpa pengesahan anda."</string>
+    <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"acara hantar respons-melalui-mesej"</string>
+    <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"Membenarkan apl menghantar permintaan kepada apl permesejan lain untuk mengendalikan acara respons-melalui-mesej untuk panggilan masuk."</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"baca mesej teks anda (SMS atau MMS)"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Membenarkan apl membaca mesej SMS yang tersimpan pada tablet atau kad SIM anda. Ini membenarkan apl membaca semua mesej SMS, tanpa mengira kandungan atau kerahsiaan."</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Membenarkan apl membaca mesej SMS yang tersimpan pada telefon atau kad SIM anda. Ini membenarkan apl membaca semua mesej SMS, tanpa mengira kandungan atau kerahsiaan."</string>
+    <string name="permlab_writeSms" msgid="3216950472636214774">"edit mesej teks (SMS atau MMS)"</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Membenarkan apl untuk menulis kepada mesej SMS yang disimpan pada tablet atau kad SIM anda. Apl hasad boleh memadam mesej anda."</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Membenarkan apl untuk menulis kepada mesej SMS yang disimpan pada telefon atau kad SIM anda. Apl hasad boleh memadam mesej anda."</string>
+    <string name="permlab_receiveWapPush" msgid="5991398711936590410">"terima mesej teks (WAP)"</string>
+    <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Membenarkan apl menerima dan memproses mesej WAP. Kebenaran ini termasuk keupayaan untuk memantau atau memadam mesej yang dihantar kepada anda tanpa menunjukkannya kepada anda."</string>
+    <string name="permlab_getTasks" msgid="6466095396623933906">"dapatkan semula apl yang sedang dijalankan"</string>
+    <string name="permdesc_getTasks" msgid="7454215995847658102">"Membenarkan apl mengambil maklumat tentang tugasan yang sedang dan baru berjalan. Ini boleh membenarkan apl untuk menemui maklumat tentang apl mana yang digunakan pada peranti."</string>
+    <string name="permlab_interactAcrossUsers" msgid="7114255281944211682">"berinteraksi sesama pengguna"</string>
+    <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Membenarkan apl melakukan tindakan merentasi pengguna berbeza pada peranti. Apl hasad boleh menggunakan ini untuk melanggar perlindungan antara pengguna."</string>
+    <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"lesen penuh untuk berinteraksi sesama pengguna"</string>
+    <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Membenarkan semua interaksi yang mungkin sesama pengguna."</string>
+    <string name="permlab_manageUsers" msgid="1676150911672282428">"urus pengguna"</string>
+    <string name="permdesc_manageUsers" msgid="8409306667645355638">"Membenarkan apl mengurus pengguna pada peranti ini, termasuk pertanyaan, pembuatan dan pemadaman."</string>
+    <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"dapatkan butiran apl yang berjalan"</string>
+    <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Membenarkan apl untuk mendapatkan maklumat terperinci tentang tugasan yang sedang dan baru berjalan. Apl hasad boleh mendapat maklumat peribadi tentang apl lain."</string>
+    <string name="permlab_reorderTasks" msgid="2018575526934422779">"susun semula tertib apl yang dijalankan"</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Membenarkan apl memindahkan tugasan ke latar depan dan latar belakang. Apl boleh melakukan ini tanpa input anda."</string>
+    <string name="permlab_removeTasks" msgid="6821513401870377403">"hentikan apl yang sedang dijalankan"</string>
+    <string name="permdesc_removeTasks" msgid="1394714352062635493">"Membenarkan apl untuk mengalih keluar tugasan dan melupuskan aplnya. Apl hasad boleh mengganggu tingkah laku apl lain."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"urus tindanan aktiviti"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Membenarkan apl menambah, mengalih keluar dan mengubah suai tindanan aktiviti tempat apl lain berjalan. Apl hasad boleh mengganggu tingkah laku apl lain."</string>
+    <string name="permlab_startAnyActivity" msgid="2918768238045206456">"mulakan sebarang aktiviti"</string>
+    <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Membenarkan apl untuk memulakan apa-apa aktiviti, tanpa mengira perlindungan kebenaran atau keadaan eksport."</string>
+    <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"tetapkan keserasian skrin"</string>
+    <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Membenarkan apl mengawal mod keserasian skrin aplikasi lain. Aplikasi hasad mungkin mematahkan kelakuan aplikasi lain."</string>
+    <string name="permlab_setDebugApp" msgid="3022107198686584052">"dayakan penyahpepijatan apl"</string>
+    <string name="permdesc_setDebugApp" msgid="4474512416299013256">"Membenarkan apl untuk menghidupkan penyahpepijatan untuk apl lain. Apl hasad boleh menggunakannya untuk menghapuskan apl lain."</string>
+    <string name="permlab_changeConfiguration" msgid="4162092185124234480">"tukar tetapan paparan sistem"</string>
+    <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"Membenarkan apl mengubah konfigurasi semasa seperti tempat peristiwa atau saiz fon keseluruhan."</string>
+    <string name="permlab_enableCarMode" msgid="5684504058192921098">"dayakan mod kereta"</string>
+    <string name="permdesc_enableCarMode" msgid="4853187425751419467">"Membenarkan apl mendayakan mod kereta."</string>
+    <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"tutup apl lain"</string>
+    <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"Membenarkan apl untuk menamatkan proses latar belakang apl lain. Ini boleh menyebabkan apl lain berhenti berjalan."</string>
+    <string name="permlab_forceStopPackages" msgid="2329627428832067700">"paksa apl lain supaya berhenti"</string>
+    <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"Membenarkan apl menghentikan apl lain secara paksa."</string>
+    <string name="permlab_forceBack" msgid="652935204072584616">"memaksa apl untuk menutup"</string>
+    <string name="permdesc_forceBack" msgid="3892295830419513623">"Membenarkan apl untuk memaksa apa-apa aktiviti yang ada di latar depan untuk tutup dan kembali. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_dump" msgid="1681799862438954752">"mendapatkan semula keadaan dalaman sistem"</string>
+    <string name="permdesc_dump" msgid="1778299088692290329">"Membenarkan apl untuk mendapatkan semula keadaan dalaman sistem. Apl hasad boleh mendapatkan pelbagai maklumat peribadi dan selamat yang biasanya tidak ia perlukan."</string>
+    <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"dapatkan semula kandungan skrin"</string>
+    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Membenarkan apl untuk mendapatkan kandungan tetingkap aktif. Apl hasad boleh mengambil keseluruhan kandungan tetingkap dan memeriksa semua teks kecuali kata laluan."</string>
+    <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"dayakan kebolehcapaian untuk sementara"</string>
+    <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"Membenarkan aplikasi untuk mendayakan kebolehcapaian untuk sementara pada peranti. Apl hasad mungkin mendayakan kebolehcapaian tanpa izin pengguna."</string>
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"dapatkan maklumat tetingkap"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Membolehkan aplikasi mendapatkan maklumat tentang tetingkap dari pengurus tetingkap. Apl hasad boleh mendapatkan maklumat yang bertujuan untuk penggunaan sistem dalaman."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"tapis acara"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"Membenarkan aplikasi mendaftarkan penapis input yang menapis strim semua acara pengguna sebelum dihantar. Apl hasad mungkin mengawal UI sistem tanpa campur tangan pengguna."</string>
+    <string name="permlab_magnify_display" msgid="5973626738170618775">"besarkan paparan"</string>
+    <string name="permdesc_magnify_display" msgid="7121235684515003792">"Membenarkan aplikasi membesarkan kandungan paparan. Apl hasad mungkin mengubah kandungan paparan yang akan membuatkan peranti tidak boleh digunakan."</string>
+    <string name="permlab_shutdown" msgid="7185747824038909016">"penutupan separa"</string>
+    <string name="permdesc_shutdown" msgid="7046500838746291775">"Meletakkan pengurus aktiviti dalam keadaan tutup. Tidak melaksanakan penutupan lengkap."</string>
+    <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"halang pertukaran apl"</string>
+    <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Menghalang pengguna daripada bertukar kepada apl lain."</string>
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"dapatkan maklumat apl semasa"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Membenarkan pemegang mendapatkan maklumat peribadi tentang permohonan semasa di latar hadapan skrin"</string>
+    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"pantau dan kawal semua pelancaran apl"</string>
+    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Membenarkan apl untuk memantau dan mengawal cara sistem melancarkan aktiviti. Apl hasad boleh menjejaskan sistem sepenuhnya. Kebenaran ini hanya diperlukan untuk pembangunan, tidak sekali-kali untuk penggunaan biasa."</string>
+    <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"hantar siaran bahawa pakej telah dialih keluar"</string>
+    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"Membenarkan apl untuk menyiarkan pemberitahuan bahawa pakej apl telah dikeluarkan. Apl hasad boleh menggunakannya untuk membunuh mana-mana apl lain yang sedang berjalan."</string>
+    <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"hantar siaran SMS diterima"</string>
+    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"Membenarkan apl untuk menyiarkan pemberitahuan bahawa mesej SMS telah diterima. Apl hasad boleh menggunakannya untuk memalsukan mesej SMS masuk."</string>
+    <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"hantar siaran WAP-TOLAK-diterima"</string>
+    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"Membenarkan apl untuk menyiarkan pemberitahuan bahawa mesej WAP PUSH telah diterima. Apl hasad boleh menggunakannya untuk memalsukan penerimaan mesej MMS atau secara diam-diam menggantikan kandungan mana-mana laman web dengan varian hasad."</string>
+    <string name="permlab_setProcessLimit" msgid="2451873664363662666">"hadkan bilangan proses yang dijalankan"</string>
+    <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"Membenarkan apl untuk mengawal bilangan maksimum proses yang akan berlangsung. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"memaksa apl latar belakang untuk menutup"</string>
+    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"Membenarkan apl untuk mengawal sama ada aktiviti sentiasa selesai sebaik sahaja ia pergi ke latar belakang. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_batteryStats" msgid="2789610673514103364">"baca statistik bateri"</string>
+    <string name="permdesc_batteryStats" msgid="5897346582882915114">"Membenarkan aplikasi membaca data penggunaan bateri tahap rendah semasa. Boleh membenarkan aplikasi untuk mencari maklumat terperinci tentang apl yang anda gunakan."</string>
+    <string name="permlab_updateBatteryStats" msgid="3719689764536379557">"ubah suai statistik bateri"</string>
+    <string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"Membenarkan apl mengubah suai statistik bateri yang dikumpul. Bukan untuk penggunaan apl normal."</string>
+    <string name="permlab_getAppOpsStats" msgid="1508779687436585744">"dapatkan semula statistik pengendalian apl"</string>
+    <string name="permdesc_getAppOpsStats" msgid="6243887041577912877">"Membenarkan apl mendapatkan semula statistik pengendalian aplikasi yang dikumpul. Bukan untuk kegunaan apl biasa."</string>
+    <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"ubah suai apl ops statistik"</string>
+    <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"Membenarkan apl mengubah suai statistik operasi aplikasi yang dikumpul. Bukan untuk kegunaan apl biasa."</string>
+    <string name="permlab_backup" msgid="470013022865453920">"sandaran dan pemulihan sistem kawalan"</string>
+    <string name="permdesc_backup" msgid="6912230525140589891">"Membenarkan apl untuk mengawal sandaran sistem dan memulihkan mekanisme. Bukan untuk digunakan oleh apl biasa."</string>
+    <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"sahkan penyandaran penuh atau pemulihan operasi"</string>
+    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"Membenarkan apl untuk memulakan UI pengesahan sandaran penuh. Bukan untuk diguakan oleh mana-mana apl."</string>
+    <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"memapaparkan tetingkap yang tiada kebenaran"</string>
+    <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"Membenarkan apl untuk membuat tetingkap yang dimaksudkan untuk digunakan oleh antara muka pengguna sistem dalaman. Bukan untuk digunakan oleh apl biasa."</string>
+    <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"lukis atas apl lain"</string>
+    <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"Membenarkan aplikasi bertindih di atas aplikasi lain atau sebahagian daripada antara muka pengguna. Ini mungkin mengganggu penggunaan antara muka anda dalam sebarang aplikasi atau menukar apa yang anda rasa anda lihat dalam aplikasi lain."</string>
+    <string name="permlab_setAnimationScale" msgid="2805103241153907174">"mengubah suai kelajuan animasi global"</string>
+    <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"Membenarkan apl menukar kelajuan animasi global (animasi yang lebih laju atau lebih perlahan) pada bila-bila masa sahaja."</string>
+    <string name="permlab_manageAppTokens" msgid="1286505717050121370">"urus token apl"</string>
+    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"Membenarkan apl untuk membuat dan menguruskan token mereka sendiri, dengan memintas susunan-Z biasanya. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_freezeScreen" msgid="4708181184441880175">"bekukan skrin"</string>
+    <string name="permdesc_freezeScreen" msgid="8558923789222670064">"Membenarkan aplikasi membekukan sementara skrin untuk peralihan skrin penuh."</string>
+    <string name="permlab_injectEvents" msgid="1378746584023586600">"menekan kekunci dan butang kawalan"</string>
+    <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"Membenarkan apl untuk menyampaikan peristiwa input sendiri (tekanan kekunci, dan sebagainya) kepada apl lain. Apl hasad boleh menggunakannya untuk mengambil alih tablet."</string>
+    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"Membenarkan apl untuk menyampaikan peristiwa input sendiri (tekanan kekunci, dan sebagainya) kepada apl lain. Apl hasad boleh menggunakannya untuk mengambil alih telefon."</string>
+    <string name="permlab_readInputState" msgid="469428900041249234">"rakam apa yang anda taipkan dan tindakan yang anda ambil"</string>
+    <string name="permdesc_readInputState" msgid="8387754901688728043">"Membenarkan apl untuk melihat kekunci yang anda tekan walaupun semasa berinteraksi dengan apl lain (seperti menaip kata laluan). Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_bindInputMethod" msgid="3360064620230515776">"terikat kepada kaedah input"</string>
+    <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi kaedah input itu. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"terikat kepada perkhidmatan yang boleh diakses"</string>
+    <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi perkhidmatan yang boleh diakses. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"terikat kepada perkhidmatan cetakan"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi perkhidmatan cetakan. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"terikat kepada perkhidmatan penspul cetakan"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi perkhidmatan penspul cetakan. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"terikat kepada perkhidmatan NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Membenarkan pemegang untuk terikat kepada aplikasi yang mengikut kad NFC. Tidak sekali-kali diperlukan untuk apl normal."</string>
+    <string name="permlab_bindTextService" msgid="7358378401915287938">"terikat kepada perkhidmatan teks"</string>
+    <string name="permdesc_bindTextService" msgid="8151968910973998670">"Membenarkan pemegang mengikat kepada antara muka peringkat atasan perkhidmatan teks(mis. PerkhidmatanPenyemakEjaan). Tidak seharusnya diperlukan untuk apl biasa."</string>
+    <string name="permlab_bindVpnService" msgid="4708596021161473255">"terikat kepada perkhidmatan VPN"</string>
+    <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi perkhidmatan Vpn. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_bindWallpaper" msgid="8716400279937856462">"terikat pada kertas dinding"</string>
+    <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi kertas dinding. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"terikat kepada perkhidmatan widget"</string>
+    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi perkhidmatan widget. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"berinteraksi dengan pentadbir peranti"</string>
+    <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Membenarkan pemegang menghantar tujuan kepada pentadbir peranti. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"tambah atau alih keluar pentadbir peranti"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Membenarkan pemegang menambah atau mengalih keluar pentadbir peranti aktif. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_setOrientation" msgid="3365947717163866844">"tukar orientasi skrin"</string>
+    <string name="permdesc_setOrientation" msgid="3046126619316671476">"Membenarkan apl untuk menukar putaran skrin pada bila-bila masa. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"tukar kelajuan penuding"</string>
+    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Membenarkan apl untuk menukar kelajuan penunjuk tetikus atau pad jejak pada bila-bila masa. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"tukar susun atur papan kekunci"</string>
+    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Membenarkan apl menukar susun atur papan kekunci. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"hantar isyarat Linux kepada apl"</string>
+    <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Membenarkan apl meminta isyarat yang dibekalkan dihantar kepada semua proses yang berterusan."</string>
+    <string name="permlab_persistentActivity" msgid="8841113627955563938">"buatkan apl sentiasa berjalan"</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Membenarkan apl untuk membuat sebahagian dirinya berterusan dalam memori. Ini boleh mengehadkan memori yang tersedia kepada apl lain dan menjadikan tablet perlahan."</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"Membenarkan apl untuk membuat sebahagian dari dirinya berterusan dalam memori. Ini boleh mengehadkan memori yang tersedia kepada apl lain dan menjadikan telefon perlahan."</string>
+    <string name="permlab_deletePackages" msgid="184385129537705938">"padam apl"</string>
+    <string name="permdesc_deletePackages" msgid="7411480275167205081">"Membenarkan apl untuk memadam pakej Android. Apl hasad boleh menggunakannya untuk memadam apl penting."</string>
+    <string name="permlab_clearAppUserData" msgid="274109191845842756">"padamkan data apl lain"</string>
+    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"Membenarkan apl mengosongkan data pengguna."</string>
+    <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"padamkan cache apl lain"</string>
+    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"Membenarkan apl memadamkan fail cache."</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"ukur ruang storan apl"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Membenarkan apl mendapatkan semula kodnya, datanya dan saiz cachenya"</string>
+    <string name="permlab_installPackages" msgid="2199128482820306924">"pasang terus apl"</string>
+    <string name="permdesc_installPackages" msgid="5628530972548071284">"Membenarkan apl untuk memasang pakej Android yang baharu atau yang dikemas kini. Apl hasad boleh menggunakannya untuk menambah apl baharu dengan keizinan berkuasa secara sewenang-wenangnya."</string>
+    <string name="permlab_clearAppCache" msgid="7487279391723526815">"padamkan semua data cache apl"</string>
+    <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"Membenarkan apl mengosongkan storan tablet dengan memadam fail dalam direktori cache aplikasi lain. Ini boleh menyebabkan aplikasi lain bermula lebih perlahan kerana perlu mendapatkan semula datanya."</string>
+    <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"Membenarkan apl mengosongkan storan telefon dengan memadam fail dalam direktori cache aplikasi lain. Ini boleh menyebabkan aplikasi lain bermula lebih perlahan kerana perlu mendapatkan semula datanya."</string>
+    <string name="permlab_movePackage" msgid="3289890271645921411">"Alih sumber apl"</string>
+    <string name="permdesc_movePackage" msgid="319562217778244524">"Membenarkan apl untuk memindahkan sumber apl dari media dalaman ke luaran dan sebaliknya."</string>
+    <string name="permlab_readLogs" msgid="6615778543198967614">"baca data log sensitif"</string>
+    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Membenarkan apl membaca daripada pelbagai fail log sistem. Hal ini membenarkannya menemui maklumat umum mengenai perkara yang anda lakukan dengan tablet, juga berpotensi menemui maklumat persendirian dan peribadi."</string>
+    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Membenarkan apl membaca daripada pelbagai fail log sistem. Hal ini membenarkannya menemui maklumat umum mengenai perkara yang anda lakukan dengan telefon, juga berpotensi menyertakan maklumat persendirian dan peribadi."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"gunakan mana-mana penyahkod media untuk main semula"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Membenarkan apl untuk menggunakan sebarang penyahkod media yang dipasangkan untuk menyahkod main semula."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"urus bukti kelayakan yang dipercayai"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Membenarkan apl memasang dan menyahpasang sijil CA sebagai bukti kelayakan yang dipercayai."</string>
+    <string name="permlab_diagnostic" msgid="8076743953908000342">"baca/tulis ke sumber yang dimiliki oleh diag"</string>
+    <string name="permdesc_diagnostic" msgid="6608295692002452283">"Membenarkan apl membaca dan menulis ke sebarang sumber yang dimiliki oleh kumpulan diag; contohnya, fail dalam /dev. Hal ini berpotensi menjejaskan kestabilan dan keselamatan sistem. Perkara ini seharusnya HANYA digunakan untuk diagnosis khusus perkakasan oleh pengilang atau pengendali."</string>
+    <string name="permlab_changeComponentState" msgid="6335576775711095931">"dayakan atau lumpuhkan komponen apl"</string>
+    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Membenarkan apl untuk menukar sama ada komponen apl lain didayakan atau tidak. Apl hasad boleh menggunakannya untuk melumpuhkan keupayaan telefon yang penting. Berhati-hati semasa menggunakan kebenaran ini, kerana hal ini boleh menjadikan komponen apl berada dalam keadaan tidak boleh digunakan, tidak konsisten, atau tidak stabil."</string>
+    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Membenarkan apl untuk menukar sama ada komponen apl lain didayakan atau tidak. Apl hasad boleh menggunakannya untuk melumpuhkan keupayaan telefon yang penting. Berhati-hati semasa menggunakan kebenaran ini, kerana hal ini boleh menjadikan komponen apl berada dalam keadaan tidak boleh digunakan, tidak konsisten, atau tidak stabil."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"berikan atau batalkan kebenaran"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Membenarkan aplikasi memberikan atau membatalkan kebenaran khusus untuk aplikasi itu sendiri atau aplikasi lain. Aplikasi berniat jahat boleh menggunakan perkara ini untuk mengakses ciri yang belum anda berikan padanya."</string>
+    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"tetapkan keutamaan apl"</string>
+    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Membenarkan apl untuk mengubah suai apl pilihan anda. Apl hasad secara diam-diam boleh menukar apl yang dijalankan, menipu apl anda yang sedia ada untuk mengumpul data peribadi daripada anda."</string>
+    <string name="permlab_writeSettings" msgid="2226195290955224730">"ubah suai tetapan sistem"</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"Membenarkan apl untuk mengubah suai data tetapan sistem. Apl hasad boleh merosakkan konfigurasi sistem anda."</string>
+    <string name="permlab_writeSecureSettings" msgid="204676251876718288">"ubah suai tetapan sistem selamat"</string>
+    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"Membenarkan apl untuk mengubah suai data tetapan selamat sistem. Bukan untuk digunakan oleh apl biasa."</string>
+    <string name="permlab_writeGservices" msgid="2149426664226152185">"mengubah suai peta perkhidmatan Google"</string>
+    <string name="permdesc_writeGservices" msgid="1287309437638380229">"Membolehkan apl mengubah suai peta perkhidmatan Google. Bukan untuk kegunaan oleh apl biasa."</string>
+    <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"jalankan pada permulaan"</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Membenarkan apl untuk memulakan dirinya sendiri sebaik sahaja sistem selesai mengebut. Ini boleh membuat masa untuk menghidupkan tablet menjadi lebih lama dan membenarkan apl untuk memperlahankan keseluruhan tablet dengan sentiasa berjalan."</string>
+    <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Membenarkan apl bermula sendiri sebaik sahaja sistem telah selesai mengebut. Ini boleh menjadikannya mengambil masa yang lama untuk menghidupkan telefon dan membenarkan apl untuk melambatkan keseluruhan telefon dengan sentiasa berjalan."</string>
+    <string name="permlab_broadcastSticky" msgid="7919126372606881614">"hantar siaran lekit"</string>
+    <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Membenarkan apl untuk menghantar siaran melekit, yang kekal selepas siaran berakhir. Penggunaan berlebihan boleh membuatkan tablet perlahan atau tidak stabil kerana menggunakan terlalu banyak memori."</string>
+    <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Membenarkan apl untuk menghantar siaran melekit, yang kekal selepas siaran berakhir. Penggunaan berlebihan boleh membuat telefon perlahan atau tidak stabil dengan menyebabkannya menggunakan memori yang terlalu banyak."</string>
+    <string name="permlab_readContacts" msgid="8348481131899886131">"baca kenalan anda"</string>
+    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Membenarkan apl membaca data tentang kenalan anda yang tersimpan di tablet anda, termasuk kekerapan anda memanggil, menghantar e-mel atau berkomunikasi dalam cara lain dengan individu tertentu. Kebenaran ini membenarkan apl untuk menyimpan data kenalan anda dan apl hasad boleh berkongsi data kenalan anda tanpa pengetahuan anda."</string>
+    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Membenarkan apl membaca data tentang kenalan anda yang tersimpan di telefon anda, termasuk kekerapan anda memanggil, menghantar e-mel atau berkomunikasi dalam cara lain dengan individu tertentu. Kebenaran ini membenarkan apl untuk menyimpan data kenalan anda dan apl hasad boleh berkongsi data kenalan anda tanpa pengetahuan anda."</string>
+    <string name="permlab_writeContacts" msgid="5107492086416793544">"ubah suai kenalan anda"</string>
+    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Membenarkan apl mengubah suai data tentang kenalan anda yang tersimpan pada tablet anda, termasuk kekerapan siapa anda panggil, hantar e-mel atau berkomunikasi dalam cara lain dengan kenalan tertentu. Kebenaran ini membenarkan apl untuk memadam data kenalan."</string>
+    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Membenarkan apl mengubah suai data tentang kenalan anda yang tersimpan pada telefon anda, termasuk kekerapan siapa anda panggil, hantar e-mel atau berkomunikasi dalam cara lain dengan kenalan tertentu. Kebenaran ini membenarkan apl untuk memadam data kenalan."</string>
+    <string name="permlab_readCallLog" msgid="3478133184624102739">"baca log panggilan"</string>
+    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Membenarkan apl membaca log panggilan tablet anda, termasuk data tentang panggilan masuk dan keluar. Kebenaran ini membenarkan apl untuk menyimpan data log panggilan anda dan apl hasad boleh berkongsi data panggilan tanpa pengetahuan anda."</string>
+    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Membenarkan apl membaca log panggilan telefon anda, termasuk data tentang panggilan masuk dan keluar. Kebenaran ini membenarkan apl untuk menyimpan data log panggilan anda dan apl hasad boleh berkongsi data panggilan tanpa pengetahuan anda."</string>
+    <string name="permlab_writeCallLog" msgid="8552045664743499354">"tulis log panggilan"</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Membenarkan apl untuk mengubah suai panggilan tablet anda, termasuk data tentang panggilan masuk dan keluar. Apl hasad boleh menggunakannya untuk memadam atau mengubah suai log panggilan anda."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Membenarkan apl untuk mengubah suai panggilan telefon anda, termasuk data tentang panggilan masuk dan keluar. Apl hasad boleh menggunakannya untuk memadam atau mengubah suai log panggilan anda."</string>
+    <string name="permlab_readProfile" msgid="4701889852612716678">"baca kad kenalan anda sendiri"</string>
+    <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Membenarkan apl membaca maklumat profil peribadi yang disimpan dalam peranti anda, seperti nama dan maklumat kenalan anda. Ini bermakna apl lain boleh mengenal pasti anda dan menghantar maklumat profil anda kepada orang lain."</string>
+    <string name="permlab_writeProfile" msgid="907793628777397643">"ubah suai kad kenalan sendiri"</string>
+    <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Membenarkan apl menukar atau menambah maklumat profil peribadi yang disimpan pada peranti anda, seperti nama dan maklumat kenalan anda. Ini bermakna apl boleh mengenal pasti anda dan menghantar maklumat profil anda kepada orang lain."</string>
+    <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"baca aliran sosial anda"</string>
+    <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Membenarkan apl mengakses dan menyegerakkan kemas kini sosial daripada anda dan rakan anda. Berhati-hati semasa berkongsi maklumat - ini membenarkan apl untuk membaca komunikasi di antara anda dan rakan anda pada rangkaian sosial tanpa mengira kerahsiaan. Nota: kebenaran ini tidak boleh dikuatkuasakan pada semua rangkaian sosial."</string>
+    <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"tulis ke aliran sosial anda"</string>
+    <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Membenarkan apl memaparkan kemas kini sosial dari rakan anda. Berhati-hati semasa berkongsi maklumat - ini membenarkan apl untuk menghasilkan mesej yang kelihatan seperti datang dari seorang rakan. Nota: kebenaran ini tidak boleh dikuatkuasakan pada semua rangkaian sosial."</string>
+    <string name="permlab_readCalendar" msgid="5972727560257612398">"baca acara kalendar serta maklumat sulit"</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Membenarkan apl membaca semua acara kalendar yang tersimpan pada tablet anda, termasuk milik rakan atau rakan sekerja. Ini boleh membenarkan apl untuk berkongsi atau menyimpan data kalendar anda, tanpa mengira kerahsiaan atau sensitiviti."</string>
+    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Membenarkan apl untuk membaca semua acara kalendar yang tersimpan pada telefon anda, termasuk milik rakan atau rakan sekerja. Ini boleh membenarkan apl untuk berkongsi atau menyimpan data kalendar anda, tanpa mengira kerahsiaan atau sensitiviti."</string>
+    <string name="permlab_writeCalendar" msgid="8438874755193825647">"tambah atau ubah suai acara kalendar dan hantar e-mel kepada tetamu tanpa pengetahuan pemilik"</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Membenarkan apl menambah, mengalih keluar, mengubah acara yang anda boleh ubah suai pada tablet anda, termasuk milik rakan atau rakan sekerja. Ini boleh membenarkan apl menghantar mesej yang kelihatan seperti datang dari pemilik kalendar atau mengubah suai acara tanpa pengetahuan pemilik."</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Membenarkan apl menambah, mengalih keluar, mengubah acara yang anda boleh ubah suai pada telefon anda, termasuk milik rakan atau rakan sekerja. Ini boleh membenarkan apl menghantar mesej yang kelihatan seperti datang dari pemilik kalendar atau mengubah suai acara tanpa pengetahuan pemilik."</string>
+    <string name="permlab_accessMockLocation" msgid="8688334974036823330">"gunakan sumber lokasi olok-olok untuk pengujian"</string>
+    <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Buat sumber lokasi palsu untuk menguji atau memasang pembekal lokasi baharu. Ini membenarkan apl untuk membatalkan lokasi dan/atau status yang dikembalikan oleh sumber lokasi lain seperti GPS atau pembekal lokasi."</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"akses perintah tambahan pembekal lokasi"</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"Membenarkan apl untuk mengakses arahan pembekal lokasi tambahan. Ini boleh membenarkan apl untuk campur tangan dengan operasi GPS atau sumber lokasi lain."</string>
+    <string name="permlab_installLocationProvider" msgid="6578101199825193873">"kebenaran untuk memasang pembekal lokasi"</string>
+    <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"Buat sumber lokasi palsu untuk menguji atau memasang pembekal lokasi baharu. Ini membenarkan apl untuk membatalkan lokasi dan/atau status yang dikembalikan oleh sumber lokasi lain seperti GPS atau pembekal lokasi."</string>
+    <string name="permlab_accessFineLocation" msgid="1191898061965273372">"lokasi tepat (GPS dan berasaskan rangkaian)"</string>
+    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Membenarkan apl mendapatkan lokasi tepat anda menggunakan Sistem Kedudukan Global (GPS) atau sumber lokasi rangkaian seperti menara sel dan Wi-Fi. Perkhidmatan lokasi ini mesti dihidupkan dan tersedia pada peranti anda untuk kegunaan apl. Apl boleh menggunakan ini untuk menentukan tempat anda berada dan mungkin menggunakan kuasa bateri tambahan."</string>
+    <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"lokasi anggaran (berasaskan rangkaian)"</string>
+    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Membenarkan apl mendapatkan lokasi anggaran anda. Lokasi ini diperolehi oleh perkhidmatan lokasi menggunakan sumber lokasi rangkaian seperti menara sel dan Wi-Fi. Perkhidmatan lokasi ini mesti dihidupkan dan tersedia pada peranti anda untuk kegunaan apl. Apl boleh menggunakan ini untuk menentukan secara anggaran tempat anda berada."</string>
+    <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"akses SurfaceFlinger"</string>
+    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Membenarkan apl menggunakan ciri peringkat rendah SurfaceFlinger."</string>
+    <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"baca penimbal bingkai"</string>
+    <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Membenarkan apl membaca kandungan penimbal bingkai."</string>
+    <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfigurasikan paparan Wifi"</string>
+    <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Membenarkan apl mengkonfigurasi dan menyambung ke paparan Wifi."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"kawal paparan Wifi"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Membenarkan apl mengawal ciri tahap rendah paparan Wifi."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"tangkap output audio"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Membenarkan apl menangkap dan mengubah hala output audio."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"tangkap output video"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Membenarkan apl menangkap dan mengubah hala output video."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"tangkap output video selamat"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Membenarkan apl menangkap dan mengubah hala output video selamat."</string>
+    <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"tukar tetapan audio anda"</string>
+    <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Membenarkan apl untuk mengubah suai tetapan audio global seperti kelantangan dan pembesar suara mana digunakan untuk output."</string>
+    <string name="permlab_recordAudio" msgid="3876049771427466323">"rakam audio"</string>
+    <string name="permdesc_recordAudio" msgid="4906839301087980680">"Membenarkan apl untuk merakam audio menggunakan mikrofon. Kebenaran ini membenarkan apl untuk merakam audio pada bila-bila masa tanpa pengesahan anda."</string>
+    <string name="permlab_camera" msgid="3616391919559751192">"ambil gambar dan video"</string>
+    <string name="permdesc_camera" msgid="8497216524735535009">"Membenarkan apl mengambil gambar dan video menggunakan kamera. Kebenaran ini membenarkan apl untuk menggunakan kamera pada bila-bila masa tanpa pengesahan anda."</string>
+    <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"lumpuhkan LED penunjuk penghantaran semasa kamera sedang digunakan"</string>
+    <string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"Membenarkan aplikasi sistem yang diprapasang untuk melumpuhkan LED penunjuk penggunaan kamera."</string>
+    <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"melumpuhkan tablet secara kekal"</string>
+    <string name="permlab_brick" product="default" msgid="8337817093326370537">"lumpuhkan telefon secara kekal"</string>
+    <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"Membenarkan apl melumpuhkan keseluruhan tablet secara kekal. Ini amat berbahaya."</string>
+    <string name="permdesc_brick" product="default" msgid="5788903297627283099">"Membenarkan apl melumpuhkan keseluruhan telefon secara kekal. Ini amat berbahaya."</string>
+    <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"memaksa tablet but semula"</string>
+    <string name="permlab_reboot" product="default" msgid="2898560872462638242">"paksa telefon but semula"</string>
+    <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"Membenarkan apl memaksa tablet untuk but semula."</string>
+    <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"Membenarkan apl memaksa telefon untuk but semula."</string>
+    <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"akses sistem fail storan USB"</string>
+    <string name="permlab_mount_unmount_filesystems" product="default" msgid="4402305049890953810">"akses sistem fail Kad SD"</string>
+    <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"Membenarkan apl melekapkan dan menyahlekapkan sistem fail untuk storan boleh alih."</string>
+    <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"padamkan storan USB"</string>
+    <string name="permlab_mount_format_filesystems" product="default" msgid="262582698639274056">"padamkan kad SD"</string>
+    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"Membenarkan apl memformatkan storan boleh alih."</string>
+    <string name="permlab_asec_access" msgid="3411338632002193846">"dapatkan maklumat tentang storan dalaman"</string>
+    <string name="permdesc_asec_access" msgid="3094563844593878548">"Membenarkan apl mendapatkan maklumat dari storan dalaman."</string>
+    <string name="permlab_asec_create" msgid="6414757234789336327">"buat storan dalaman"</string>
+    <string name="permdesc_asec_create" msgid="4558869273585856876">"Membenarkan apl membuat storan dalaman."</string>
+    <string name="permlab_asec_destroy" msgid="526928328301618022">"memusnahkan storan dalaman"</string>
+    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"Membenarkan apl memusnahkan storan dalaman."</string>
+    <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"lekap/nyahlekap storan dalaman"</string>
+    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"Membenarkan apl melekapkan/menyahlekapkan storan dalaman."</string>
+    <string name="permlab_asec_rename" msgid="7496633954080472417">"namakan semula storan dalaman"</string>
+    <string name="permdesc_asec_rename" msgid="1794757588472127675">"Membenarkan apl menamakan semula storan dalaman."</string>
+    <string name="permlab_vibrate" msgid="7696427026057705834">"kawal getaran"</string>
+    <string name="permdesc_vibrate" msgid="6284989245902300945">"Membenarkan apl mengawal penggetar."</string>
+    <string name="permlab_flashlight" msgid="2155920810121984215">"mengawal lampu suluh"</string>
+    <string name="permdesc_flashlight" msgid="6522284794568368310">"Membenarkan apl mengawal lampu suluh."</string>
+    <string name="permlab_manageUsb" msgid="1113453430645402723">"urus pilihan dan kebenaran untuk peranti USB"</string>
+    <string name="permdesc_manageUsb" msgid="7776155430218239833">"Membenarkan apl untuk menguruskan pilihan dan kebenaran untuk peranti USB."</string>
+    <string name="permlab_accessMtp" msgid="4953468676795917042">"laksanakan protokol MTP"</string>
+    <string name="permdesc_accessMtp" msgid="6532961200486791570">"Membenarkan akses kepada pemacu inti MTP untuk melaksanakan protokol USB MTP."</string>
+    <string name="permlab_hardware_test" msgid="4148290860400659146">"uji perkakasan"</string>
+    <string name="permdesc_hardware_test" msgid="6597964191208016605">"Membenarkan apl mengawal pelbagai persisian untuk tujuan pengujian perkakasan."</string>
+    <string name="permlab_callPhone" msgid="3925836347681847954">"panggil terus nombor telefon"</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"Membenarkan apl memanggil nombor telefon tanpa campur tangan anda. Ini mungkin menyebabkan caj atau panggilan yang di luar jangkaan. Apl hasad boleh menyebabkan anda kerugian wang dengan membuat panggilan tanpa pengesahan anda."</string>
+    <string name="permlab_callPrivileged" msgid="4198349211108497879">"panggil terus sebarang nombor telefon"</string>
+    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"Membenarkan apl untuk memanggil mana-mana nombor telefon, termasuk nombor kecemasan, tanpa campur tangan anda. Apl hasad boleh membuat panggilan yang tidak perlu dan salah di sisi undang-undang ke perkhidmatan kecemasan."</string>
+    <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"mulakan terus persediaan tablet CDMA"</string>
+    <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"memulakan persediaan telefon CDMA secara langsung"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"Membenarkan apl memulakan peruntukan CDMA. Apl hasad boleh memulakan peruntukan CDMA yang tidak perlu."</string>
+    <string name="permlab_locationUpdates" msgid="7785408253364335740">"kawal pemberitahuan kemas kini lokasi"</string>
+    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Membenarkan apl untuk mendayakan/melumpuhkan pemberitahuan kemas kini lokasi dari radio. Bukan untuk kegunaan apl biasa."</string>
+    <string name="permlab_checkinProperties" msgid="7855259461268734914">"akses sifat daftar masuk"</string>
+    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Membenarkan apl membaca/menulis akses kepada sifat yang dimuat naik oleh perkhidmatan checkin. Bukan untuk digunakan oleh apl biasa."</string>
+    <string name="permlab_bindGadget" msgid="776905339015863471">"pilih widget"</string>
+    <string name="permdesc_bindGadget" msgid="8261326938599049290">"Membenarkan apl untuk memberitahu sistem widget mana yang boleh digunakan oleh apl yang mana. Apl dengan kebenaran ini boleh memberi akses kepada data peribadi kepada apl lain. Bukan untuk digunakan oleh apl biasa."</string>
+    <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"ubah suai keadaan telefon"</string>
+    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Membenarkan apl untuk mengawal ciri-ciri telefon peranti. Apl dengan kebenaran ini boleh menukar rangkaian, menghidupkan dan mematikan radio telefon dan sebagainya tanpa memberitahu anda."</string>
+    <string name="permlab_readPhoneState" msgid="9178228524507610486">"baca status dan identiti telefon"</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Membenarkan apl mengakses ciri telefon pada peranti. Kebenaran ini membolehkan apl menentukan nombor telefon dan ID peranti, sama ada panggilan aktif dan nombor jauh yang dihubungkan dengan panggilan."</string>
+    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"menghalang tablet daripada tidur"</string>
+    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"halang telefon daripada tidur"</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Membenarkan apl menghalang tablet daripada tidur."</string>
+    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Membenarkan apl menghalang telefon daripada tidur."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
+    <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"menghidupkan atau mematikan kuasa tablet"</string>
+    <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"kuasakan telefon hidup atau mati"</string>
+    <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Membenarkan apl menghidupkan atau mematikan tablet."</string>
+    <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"Membenarkan apl menghidupkan atau mematikan telefon."</string>
+    <string name="permlab_factoryTest" msgid="3715225492696416187">"jalankan dalam mod ujian kilang"</string>
+    <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"Jalankan sebagai ujian pengeluar peringkat rendah, membenarkan akses penuh kepada perkakasan tablet. Hanya tersedia apabila tablet dijalankan dalam mod ujian pengeluar."</string>
+    <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"Menjalankan sebagai ujian pengilang peringkat rendah, membenarkan akses penuh kepada perkakasan telefon. Hanya tersedia apabila telefon dijalankan dalam mod ujian pengilang."</string>
+    <string name="permlab_setWallpaper" msgid="6627192333373465143">"tetapkan kertas dinding"</string>
+    <string name="permdesc_setWallpaper" msgid="7373447920977624745">"Membenarkan apl menetapkan kertas dinding sistem."</string>
+    <string name="permlab_setWallpaperHints" msgid="3278608165977736538">"laraskan saiz kertas dinding anda"</string>
+    <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Membenarkan apl menetapkan pembayang saiz kertas dinding sistem."</string>
+    <string name="permlab_masterClear" msgid="2315750423139697397">"menetapkan semula sistem kepada lalai kilang"</string>
+    <string name="permdesc_masterClear" msgid="3665380492633910226">"Membenarkan apl untuk menetapkan semula sistem kepada tetapan kilang sepenuhnya, memadam semua data, konfigurasi, dan apl yang dipasang."</string>
+    <string name="permlab_setTime" msgid="2021614829591775646">"tetapkan masa"</string>
+    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"Membenarkan apl untuk menukar masa jam tablet."</string>
+    <string name="permdesc_setTime" product="default" msgid="1855702730738020">"Membolehkan apl untuk menukar waktu jam telefon."</string>
+    <string name="permlab_setTimeZone" msgid="2945079801013077340">"tetapkan zon waktu"</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Membenarkan apl menukar zon waktu tablet."</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Membenarkan apl menukar zon waktu telefon."</string>
+    <string name="permlab_accountManagerService" msgid="4829262349691386986">"bertindak sebagai PerkhidmatanPengurusAkaun"</string>
+    <string name="permdesc_accountManagerService" msgid="1948455552333615954">"Membenarkan apl membuat panggilan ke Pengesah Akaun."</string>
+    <string name="permlab_getAccounts" msgid="1086795467760122114">"cari akaun pada peranti"</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Membenarkan apl mendapatkan senarai akaun yang dikenali oleh tablet. Ini mungkin termasuk sebarang akaun yang dibuat oleh aplikasi yang telah anda pasang."</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Membenarkan apl mendapatkan senarai akaun yang dikenali oleh telefon. Ini mungkin termasuk sebarang akaun yang dibuat oleh aplikasi yang telah anda pasang."</string>
+    <string name="permlab_authenticateAccounts" msgid="5265908481172736933">"buat akaun dan tetapkan kata laluan"</string>
+    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"Membenarkan apl menggunakan kebolehan pengesah akaun Pengurus Akaun, termasuk membuat akaun dan mendapatkan serta menetapkan kata laluannya."</string>
+    <string name="permlab_manageAccounts" msgid="4983126304757177305">"tambah atau alih keluar akaun"</string>
+    <string name="permdesc_manageAccounts" msgid="8698295625488292506">"Membenarkan apl melaksanakan operasi seperti menambah dan mengalih keluar akaun dan memadamkan kata laluannya."</string>
+    <string name="permlab_useCredentials" msgid="235481396163877642">"guna akaun pada peranti"</string>
+    <string name="permdesc_useCredentials" msgid="7984227147403346422">"Membenarkan apl meminta token pengesahan."</string>
+    <string name="permlab_accessNetworkState" msgid="4951027964348974773">"lihat sambungan rangkaian"</string>
+    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Membenarkan apl melihat maklumat tentang sambungan rangkaian seperti rangkaian mana yang wujud dan bersambung."</string>
+    <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"akses rangkaian penuh"</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Membenarkan apl membuat soket rangkaian dan menggunakan protokol rangkaian tersuai. Penyemak imbas dan aplikasi lain menyediakan cara untuk menghantar data ke internet, jadi kebenaran ini tidak diperlukan untuk menghantar data ke internet."</string>
+    <string name="permlab_writeApnSettings" msgid="505660159675751896">"mengubah/memintas tetapan dan lalu lintas rangkaian"</string>
+    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Membenarkan apl untuk menukar tetapan rangkaian dan untuk memintas serta memeriksa semua trafik rangkaian, contohnya untuk menukar proksi dan port mana-mana APN. Apl hasad boleh memantau, mengubah hala, atau mengubah suai paket rangkaian tanpa pengetahuan anda."</string>
+    <string name="permlab_changeNetworkState" msgid="958884291454327309">"tukar kesambungan rangkaian"</string>
+    <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Membenarkan apl untuk mengubah keadaan kesambungan rangkaian."</string>
+    <string name="permlab_changeTetherState" msgid="5952584964373017960">"tukar kesambungan bertambat"</string>
+    <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Membenarkan apl untuk mengubah keadaan kesambungan rangkaian tambatan."</string>
+    <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"tukar tetapan penggunaan data latar belakang"</string>
+    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Membenarkan apl menukar tetapan penggunaan data latar belakang."</string>
+    <string name="permlab_accessWifiState" msgid="5202012949247040011">"lihat sambungan Wi-Fi"</string>
+    <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Membenarkan apl melihat maklumat tentang rangkaian Wi-Fi, seperti sama ada Wi-Fi didayakan dan nama peranti Wi-Fi yang disambungkan."</string>
+    <string name="permlab_changeWifiState" msgid="6550641188749128035">"sambung dan putuskan dari Wi-Fi"</string>
+    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Membenarkan apl menyambung ke dan memutuskan sambungan dari titik capaian Wi-Fi dan membuat perubahan kepada konfigurasi peranti untuk rangkaian Wi-Fi."</string>
+    <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"benarkan penerimaan Wi-Fi Multisiar"</string>
+    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Membenarkan apl menerima paket yang dihantar kepada semua peranti pada rangkaian Wi-Fi menggunakan alamat multisiar, bukan hanya tablet anda. Apl menggunakan lebih kuasa berbanding mod bukan multisiar."</string>
+    <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Membenarkan apl menerima paket yang dihantar kepada semua peranti pada rangkaian Wi-Fi menggunakan alamat multisiar, bukan hanya telefon anda. Ia menggunakan lebih kuasa berbanding mod bukan multisiar."</string>
+    <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"akses tetapan Bluetooth"</string>
+    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Membenarkan apl mengkonfigurasikan tablet Bluetooth setempat dan menemui serta berpasangan dengan peranti jauh."</string>
+    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Membenarkan apl mengkonfigurasikan telefon Bluetooth setempat dan menemui serta berpasangan dengan peranti jauh."</string>
+    <string name="permlab_accessWimaxState" msgid="4195907010610205703">"sambung dan putuskan sambungan WiMAX"</string>
+    <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"Membenarkan apl menentukan sama ada WiMaX didayakan dan maklumat tentang sebarang rangkaian WiMaX yang disambungkan."</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Tukar keadaan WiMAX"</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Membenarkan apl untuk menyambungkan tablet ke dan menyahsambungkan tablet dari rangkaian WiMaX."</string>
+    <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"Membenarkan apl untuk menyambungkan telefon ke dan menyahsambung telefon dari rangkaian WiMaX."</string>
+    <string name="permlab_bluetooth" msgid="6127769336339276828">"berpasangan dengan peranti Bluetooth"</string>
+    <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Membenarkan apl melihat konfigurasi Bluetooth pada tablet dan untuk membuat serta menerima sambungan dengan peranti yang dipasangkan."</string>
+    <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Membenarkan apl melihat konfigurasi Bluetooth pada telefon dan membuat serta menerima sambungan dengan peranti yang dipasangkan."</string>
+    <string name="permlab_nfc" msgid="4423351274757876953">"mengawal Komunikasi Medan Dekat"</string>
+    <string name="permdesc_nfc" msgid="7120611819401789907">"Membenarkan apl berkomunikasi dengan teg, kad dan pembaca Komunikasi Medan Dekat (NFC)."</string>
+    <string name="permlab_disableKeyguard" msgid="3598496301486439258">"lumpuhkan kunci skrin anda"</string>
+    <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Membenarkan apl melumpuhkan kunci kekunci dan sebarang keselamatan kata laluan yang berkaitan. Sebagai contoh, telefon melumpuhkan kunci kekunci apabila menerima panggilan telefon masuk kemudian mendayakan semula kunci kekunci apabila panggilan selesai."</string>
+    <string name="permlab_readSyncSettings" msgid="6201810008230503052">"membaca tetapan penyegerakan"</string>
+    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Membenarkan apl membaca tetapan segerak untuk akaun. Sebagai contoh, ini boleh menentukan sama ada apl Orang disegerakkan dengan akaun."</string>
+    <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"togol segerak hidup dan mati"</string>
+    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Membenarkan apl mengubah suai tetapan segerak untuk akaun. Sebagai contoh, ini boleh digunakan untuk mendayakan penyegerakan apl Orang dengan akaun."</string>
+    <string name="permlab_readSyncStats" msgid="7396577451360202448">"baca statistik penyegerakan"</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Membenarkan apl untuk membaca statistik segerak untuk akaun, termasuk sejarah acara segerak dan berapa banyak data disegerakkan."</string>
+    <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"baca suapan langganan"</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Membenarkan apl mendapatkan butiran mengenai suapan tersegerak semasa."</string>
+    <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"tulis suapan yang dilanggan"</string>
+    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"Membenarkan apl untuk mengubah suai suapan segerakan semasa anda. Apl hasad boleh menukar suapan anda yang disegerakkan."</string>
+    <string name="permlab_readDictionary" msgid="4107101525746035718">"baca istilah yang anda tambahkan kepada kamus"</string>
+    <string name="permdesc_readDictionary" msgid="659614600338904243">"Membenarkan apl membaca semua perkataan, nama dan frasa yang mungkin telah disimpan oleh pengguna dalam kamus pengguna."</string>
+    <string name="permlab_writeDictionary" msgid="2183110402314441106">"tambah perkataan ke kamus ditakrifkan pengguna"</string>
+    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Membenarkan apl menulis perkataan baharu ke dalam kamus pengguna."</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"uji akses ke storan dilindungi"</string>
+    <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"uji akses ke storan dilindungi"</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"Apl boleh uji kebenaran USB."</string>
+    <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"Membenarkan apl menguji kebenaran untuk kad SD yang akan tersedia pada peranti akan datang."</string>
+    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"ubah suai atau padam kandungan storan USB anda"</string>
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"ubah suai atau padam kandungan kad SD anda"</string>
+    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Membenarkan apl menulis ke storan USB."</string>
+    <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Membenarkan apl menulis ke kad SD."</string>
+    <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"ubh suai/pdm kdg strn mdia dlm"</string>
+    <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Membenarkan apl mengubah suai kandungan storan media dalaman."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"urus storan dokumen"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Membenarkan apl mengurus storan dokumen."</string>
+    <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"mengakses storan luaran untuk semua pengguna"</string>
+    <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Membenarkan apl untuk mengakses storan luaran untuk semua pengguna."</string>
+    <string name="permlab_cache_filesystem" msgid="5656487264819669824">"akses sistem fail cache"</string>
+    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Membenarkan apl membaca dan menulis cache sistem fail."</string>
+    <string name="permlab_use_sip" msgid="5986952362795870502">"membuat/menerima panggilan Internet"</string>
+    <string name="permdesc_use_sip" msgid="4717632000062674294">"Membenarkan apl menggunakan perkhidmatan SIP untuk membuat/menerima panggilan Internet."</string>
+    <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"baca sejarah penggunaan rangkaian"</string>
+    <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"Membenarkan apl membaca sejarah penggunaan rangkaian untuk rangkaian dan apl khusus."</string>
+    <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"urus dasar rangkaian"</string>
+    <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Membenarkan apl mengurus dasar rangkaian dan menentukan peraturan khusus apl."</string>
+    <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"ubah suai perakaunan penggunaan rangkaian"</string>
+    <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Membenarkan apl untuk mengubah suai bagaimana penggunaan rangkaian diambil kira terhadap apl. Bukan untuk digunakan oleh apl biasa."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"ubah tanda soket"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Membenarkan apl mengubah suai tanda soket untuk laluan"</string>
+    <string name="permlab_accessNotifications" msgid="7673416487873432268">"pemberitahuan akses"</string>
+    <string name="permdesc_accessNotifications" msgid="458457742683431387">"Membenarkan apl untuk mendapatkan semula, memeriksa dan memadam bersih pemberitahuan, termasuk yang disiarkan oleh apl lain."</string>
+    <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"ikat kepada perkhidmatan pendengar pemberitahuan"</string>
+    <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi perkhidmatan pendengar pemberitahuan. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"gunakan apl konfigurasi yang disediakan oleh pembawa"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Membenarkan pemegang menggunakan apl konfigurasi yang diberikan oleh pembawa. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"dengar pemerhatian mengenai keadaan rangkaian"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Membenarkan aplikasi mendengar pemerhatian tentang keadaan rangkaian. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="policylab_limitPassword" msgid="4497420728857585791">"Tetapkan peraturan kata laluan"</string>
+    <string name="policydesc_limitPassword" msgid="3252114203919510394">"Mengawal panjang dan aksara yang dibenarkan dalam kata laluan buka kunci skrin."</string>
+    <string name="policylab_watchLogin" msgid="914130646942199503">"Memantau percubaan buka kunci skrin"</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Memantau bilangan kata laluan yang tersilap ditaip apabila membuka skrin, dan mengunci tablet atau memadam semua data tablet jika terlalu banyak kesilapan menaip kata laluan."</string>
+    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Memantau bilangan kata laluan salah yang ditaip semasa membuka skrin, dan mengunci telefon atau memadam semua data telefon jika terlalu banyak kata laluan salah ditaip."</string>
+    <string name="policylab_resetPassword" msgid="2620077191242688955">"Tukar kata laluan buka kunci skrin"</string>
+    <string name="policydesc_resetPassword" msgid="605963962301904458">"Tukar kata laluan buka kunci skrin."</string>
+    <string name="policylab_forceLock" msgid="2274085384704248431">"Kunci skrin"</string>
+    <string name="policydesc_forceLock" msgid="1141797588403827138">"Mengawal cara dan bila skrin dikunci."</string>
+    <string name="policylab_wipeData" msgid="3910545446758639713">"Padamkan semua data"</string>
+    <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Memadamkan data tablet tanpa amaran dengan melakukan tetapan semula data kilang."</string>
+    <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Memadamkan data telefon tanpa amaran dengan melakukan tetapan semula data kilang."</string>
+    <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Tetapkan proksi global peranti"</string>
+    <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Menetapkan proksi global peranti untuk digunakan sementara dasar didayakan. Hanya pentadbir peranti pertama boleh menetapkan proksi global dengan berkesan."</string>
+    <string name="policylab_expirePassword" msgid="885279151847254056">"Ttpkn tmt tmph k/lln kci skrin"</string>
+    <string name="policydesc_expirePassword" msgid="1729725226314691591">"Kawal kekerapan penukaran kata laluan kunci skrin."</string>
+    <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Tetapkan penyulitan storan"</string>
+    <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"Memerlukan data apl yang disimpan itu disulitkan."</string>
+    <string name="policylab_disableCamera" msgid="6395301023152297826">"Lumpuhkan kamera"</string>
+    <string name="policydesc_disableCamera" msgid="2306349042834754597">"Menghalang penggunaan semua kamera peranti."</string>
+    <string name="policylab_disableKeyguardFeatures" msgid="266329104542638802">"Lumpuh ciri pelindung kekunci"</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="3467082272186534614">"Cegah penggunaan beberapa ciri dalam pelindung kekunci."</string>
+  <string-array name="phoneTypes">
+    <item msgid="8901098336658710359">"Laman Utama"</item>
+    <item msgid="869923650527136615">"Mudah alih"</item>
+    <item msgid="7897544654242874543">"Kerja"</item>
+    <item msgid="1103601433382158155">"Faks Kerja"</item>
+    <item msgid="1735177144948329370">"Faks Rumah"</item>
+    <item msgid="603878674477207394">"Alat kelui"</item>
+    <item msgid="1650824275177931637">"Lain-lain"</item>
+    <item msgid="9192514806975898961">"Peribadi"</item>
+  </string-array>
+  <string-array name="emailAddressTypes">
+    <item msgid="8073994352956129127">"Rumah"</item>
+    <item msgid="7084237356602625604">"Kerja"</item>
+    <item msgid="1112044410659011023">"Lain-lain"</item>
+    <item msgid="2374913952870110618">"Peribadi"</item>
+  </string-array>
+  <string-array name="postalAddressTypes">
+    <item msgid="6880257626740047286">"Rumah"</item>
+    <item msgid="5629153956045109251">"Kerja"</item>
+    <item msgid="4966604264500343469">"Lain-lain"</item>
+    <item msgid="4932682847595299369">"Peribadi"</item>
+  </string-array>
+  <string-array name="imAddressTypes">
+    <item msgid="1738585194601476694">"Laman Utama"</item>
+    <item msgid="1359644565647383708">"Kerja"</item>
+    <item msgid="7868549401053615677">"Lain-lain"</item>
+    <item msgid="3145118944639869809">"Peribadi"</item>
+  </string-array>
+  <string-array name="organizationTypes">
+    <item msgid="7546335612189115615">"Kerja"</item>
+    <item msgid="4378074129049520373">"Lain-lain"</item>
+    <item msgid="3455047468583965104">"Peribadi"</item>
+  </string-array>
+  <string-array name="imProtocols">
+    <item msgid="8595261363518459565">"AIM"</item>
+    <item msgid="7390473628275490700">"Windows Live"</item>
+    <item msgid="7882877134931458217">"Yahoo"</item>
+    <item msgid="5035376313200585242">"Skype"</item>
+    <item msgid="7532363178459444943">"QQ"</item>
+    <item msgid="3713441034299660749">"Bual Google"</item>
+    <item msgid="2506857312718630823">"ICQ"</item>
+    <item msgid="1648797903785279353">"Jabber"</item>
+  </string-array>
+    <string name="phoneTypeCustom" msgid="1644738059053355820">"Peribadi"</string>
+    <string name="phoneTypeHome" msgid="2570923463033985887">"Laman Utama"</string>
+    <string name="phoneTypeMobile" msgid="6501463557754751037">"Mudah Alih"</string>
+    <string name="phoneTypeWork" msgid="8863939667059911633">"Kerja"</string>
+    <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Faks Kerja"</string>
+    <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Faks Rumah"</string>
+    <string name="phoneTypePager" msgid="7582359955394921732">"Alat Kelui"</string>
+    <string name="phoneTypeOther" msgid="1544425847868765990">"Lain-lain"</string>
+    <string name="phoneTypeCallback" msgid="2712175203065678206">"Panggil balik"</string>
+    <string name="phoneTypeCar" msgid="8738360689616716982">"Kereta"</string>
+    <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Nombor Utama Syarikat"</string>
+    <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string>
+    <string name="phoneTypeMain" msgid="6766137010628326916">"Utama"</string>
+    <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Faks Lain"</string>
+    <string name="phoneTypeRadio" msgid="4093738079908667513">"Radio"</string>
+    <string name="phoneTypeTelex" msgid="3367879952476250512">"Teleks"</string>
+    <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY TDD"</string>
+    <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Telefon Mudah Alih Kerja"</string>
+    <string name="phoneTypeWorkPager" msgid="649938731231157056">"Alat Kelui Kerja"</string>
+    <string name="phoneTypeAssistant" msgid="5596772636128562884">"Pembantu"</string>
+    <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string>
+    <string name="eventTypeCustom" msgid="7837586198458073404">"Peribadi"</string>
+    <string name="eventTypeBirthday" msgid="2813379844211390740">"Hari Lahir"</string>
+    <string name="eventTypeAnniversary" msgid="3876779744518284000">"Ulang tahun"</string>
+    <string name="eventTypeOther" msgid="7388178939010143077">"Lain-lain"</string>
+    <string name="emailTypeCustom" msgid="8525960257804213846">"Peribadi"</string>
+    <string name="emailTypeHome" msgid="449227236140433919">"Rumah"</string>
+    <string name="emailTypeWork" msgid="3548058059601149973">"Kerja"</string>
+    <string name="emailTypeOther" msgid="2923008695272639549">"Lain-lain"</string>
+    <string name="emailTypeMobile" msgid="119919005321166205">"Mudah Alih"</string>
+    <string name="postalTypeCustom" msgid="8903206903060479902">"Peribadi"</string>
+    <string name="postalTypeHome" msgid="8165756977184483097">"Laman Utama"</string>
+    <string name="postalTypeWork" msgid="5268172772387694495">"Kerja"</string>
+    <string name="postalTypeOther" msgid="2726111966623584341">"Lain-lain"</string>
+    <string name="imTypeCustom" msgid="2074028755527826046">"Peribadi"</string>
+    <string name="imTypeHome" msgid="6241181032954263892">"Laman Utama"</string>
+    <string name="imTypeWork" msgid="1371489290242433090">"Kerja"</string>
+    <string name="imTypeOther" msgid="5377007495735915478">"Lain-lain"</string>
+    <string name="imProtocolCustom" msgid="6919453836618749992">"Peribadi"</string>
+    <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string>
+    <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string>
+    <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">"Hangouts"</string>
+    <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">"Kerja"</string>
+    <string name="orgTypeOther" msgid="3951781131570124082">"Lain-lain"</string>
+    <string name="orgTypeCustom" msgid="225523415372088322">"Peribadi"</string>
+    <string name="relationTypeCustom" msgid="3542403679827297300">"Peribadi"</string>
+    <string name="relationTypeAssistant" msgid="6274334825195379076">"Pembantu"</string>
+    <string name="relationTypeBrother" msgid="8757913506784067713">"Abang/Adik"</string>
+    <string name="relationTypeChild" msgid="1890746277276881626">"Anak"</string>
+    <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"Rakan Kongsi Domestik"</string>
+    <string name="relationTypeFather" msgid="5228034687082050725">"Bapa"</string>
+    <string name="relationTypeFriend" msgid="7313106762483391262">"Rakan"</string>
+    <string name="relationTypeManager" msgid="6365677861610137895">"Pengurus"</string>
+    <string name="relationTypeMother" msgid="4578571352962758304">"Ibu"</string>
+    <string name="relationTypeParent" msgid="4755635567562925226">"Ibu bapa"</string>
+    <string name="relationTypePartner" msgid="7266490285120262781">"Rakan Kongsi"</string>
+    <string name="relationTypeReferredBy" msgid="101573059844135524">"Dirujuk oleh"</string>
+    <string name="relationTypeRelative" msgid="1799819930085610271">"Saudara"</string>
+    <string name="relationTypeSister" msgid="1735983554479076481">"Kakak/Adik"</string>
+    <string name="relationTypeSpouse" msgid="394136939428698117">"Pasangan"</string>
+    <string name="sipAddressTypeCustom" msgid="2473580593111590945">"Peribadi"</string>
+    <string name="sipAddressTypeHome" msgid="6093598181069359295">"Rumah"</string>
+    <string name="sipAddressTypeWork" msgid="6920725730797099047">"Kerja"</string>
+    <string name="sipAddressTypeOther" msgid="4408436162950119849">"Lain-lain"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Taip kod PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Taip PUK dan kod PIN baharu"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Kod PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Kod PIN Baharu"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Sentuh untuk menaip kata laluan"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Taip kata laluan untuk membuka kunci"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Taip PIN untuk membuka kunci"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Kod PIN salah."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Untuk membuka kunci, tekan Menu, kemudian 0."</string>
+    <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"Nombor kecemasan"</string>
+    <string name="lockscreen_carrier_default" msgid="8963839242565653192">"Tiada perkhidmatan."</string>
+    <string name="lockscreen_screen_locked" msgid="7288443074806832904">"Skrin dikunci."</string>
+    <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Tekan Menu untuk menyahsekat atau membuat panggilan kecemasan."</string>
+    <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Tekan Menu untuk membuka kunci."</string>
+    <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Lukiskan corak untuk membuka kunci"</string>
+    <string name="lockscreen_emergency_call" msgid="5347633784401285225">"Panggilan kecemasan"</string>
+    <string name="lockscreen_return_to_call" msgid="5244259785500040021">"Kembali ke panggilan"</string>
+    <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Betul!"</string>
+    <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Cuba lagi"</string>
+    <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Cuba lagi"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Telah melepasi had cubaan Buka Kunci Wajah"</string>
+    <string name="lockscreen_plugged_in" msgid="8057762828355572315">"Mengecas, (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
+    <string name="lockscreen_charged" msgid="321635745684060624">"Sudah dicas"</string>
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_low_battery" msgid="1482873981919249740">"Sambungkan pengecas anda."</string>
+    <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"Tiada kad SIM"</string>
+    <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Tiada kad SIM dalam tablet."</string>
+    <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"Kad SIM tiada dalam telefon."</string>
+    <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Masukkan kad SIM."</string>
+    <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Kad SIM tiada atau tidak boleh dibaca. Sila masukkan kad SIM."</string>
+    <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Kad SIM tidak boleh digunakan."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Kad SIM anda telah dilumpuhkan secara kekal.\n Hubungi pembekal perkhidmatan wayarles anda untuk mendapatkan kad SIM lain."</string>
+    <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Butang lagu sebelumnya"</string>
+    <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Butang lagu seterusnya"</string>
+    <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Butang Jeda"</string>
+    <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Butang main"</string>
+    <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Butang berhenti"</string>
+    <string name="emergency_calls_only" msgid="6733978304386365407">"Panggilan kecemasan sahaja"</string>
+    <string name="lockscreen_network_locked_message" msgid="143389224986028501">"Rangkaian dikunci"</string>
+    <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"Kad SIM dikunci dengan PUK."</string>
+    <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Lihat Panduan Pengguna atau hubungi Penjagaan Pelanggan."</string>
+    <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Kad SIM dikunci."</string>
+    <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Membuka kunci kad SIM..."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Anda telah tersilap melukis corak buka kunci anda sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. \n\nSila cuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Anda telah tersilap taip menaip kata laluan anda sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Anda telah tersilap taip PIN anda sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Anda telah tersilap melukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci tablet anda menggunakan log masuk Google anda.\n\n Cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Anda telah tersilap lukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci telefon anda menggunakan log masuk Google anda.\n\n Sila cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Anda telah mencuba untuk membuka kunci tablet dengan salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, tablet akan ditetapkan semula kepada tetapan lalai kilang dan semua data pengguna akan hilang."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Anda telah mencuba untuk membuka kunci telefon dengan salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, telefon akan ditetapkan semula kepada tetapan lalai kilang dan semua data pengguna akan hilang."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Anda telah mencuba untuk membuka kunci tablet secara salah sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Tablet kini akan ditetapkan semula ke tetapan lalai kilang."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Anda telah mencuba untuk membuka kunci telefon secara salah sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Telefon kini akan ditetapkan semula kepada tetapan lalai kilang."</string>
+    <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Cuba lagi dalam <xliff:g id="NUMBER">%d</xliff:g> saat."</string>
+    <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Lupa corak?"</string>
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Buka kunci akaun"</string>
+    <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"Terlalu banyak percubaan melukis corak"</string>
+    <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"Untuk membuka kunci, log masuk dengan akaun Google anda."</string>
+    <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Nama Pengguna (E-mel)"</string>
+    <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Kata laluan"</string>
+    <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Log masuk"</string>
+    <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nama pengguna atau kata laluan tidak sah."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Lupa nama pengguna atau kata laluan anda?\nLawati "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Menyemak…"</string>
+    <string name="lockscreen_unlock_label" msgid="737440483220667054">"Buka kunci"</string>
+    <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Bunyi dihidupkan"</string>
+    <string name="lockscreen_sound_off_label" msgid="996822825154319026">"Bunyi dimatikan"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Corak dimulakan"</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Corak dipadamkan"</string>
+    <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Sel ditambahkan"</string>
+    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Corak siap"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d dari %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Tambah widget."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Kosong"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Bahagian buka kunci dikembangkan."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Bahagian buka kunci diruntuhkan."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Pemilih pengguna"</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">"Kawalan media"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Penyusunan semula widget dimulakan."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Penyusunan semula widget tamat."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> dipadamkan."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Kembangkan bahagian buka kunci."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Buka kunci luncur."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Buka kunci corak."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Wajah Buka Kunci"</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Buka kunci pin."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Buka kunci kata laluan."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Kawasan corak."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Kawasan luncur."</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="granularity_label_character" msgid="7336470535385009523">"watak"</string>
+    <string name="granularity_label_word" msgid="7075570328374918660">"perkataan"</string>
+    <string name="granularity_label_link" msgid="5815508880782488267">"pautan"</string>
+    <string name="granularity_label_line" msgid="5764267235026120888">"baris"</string>
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
+    <string name="factorytest_failed" msgid="5410270329114212041">"Ujian kilang gagal"</string>
+    <string name="factorytest_not_system" msgid="4435201656767276723">"Tindakan FACTORY_TEST hanya disokong untuk pakej yang dipasangkan dalam /system/app."</string>
+    <string name="factorytest_no_action" msgid="872991874799998561">"Tiada pakej yang menyediakan tindakan FACTORY_TEST ditemui."</string>
+    <string name="factorytest_reboot" msgid="6320168203050791643">"But semula"</string>
+    <string name="js_dialog_title" msgid="1987483977834603872">"Halaman di \'<xliff:g id="TITLE">%s</xliff:g>\' berkata:"</string>
+    <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
+    <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Sahkan Navigasi"</string>
+    <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Tinggalkan Halaman ini"</string>
+    <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Kekal di Halaman ini"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nAdakah anda pasti anda mahu menavigasi keluar dari halaman ini?"</string>
+    <string name="save_password_label" msgid="6860261758665825069">"Sahkan"</string>
+    <string name="double_tap_toast" msgid="4595046515400268881">"Petua: Ketik dua kali untuk mengezum masuk dan keluar."</string>
+    <string name="autofill_this_form" msgid="4616758841157816676">"Auto isi"</string>
+    <string name="setup_autofill" msgid="7103495070180590814">"Sediakan Autoisi"</string>
+    <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
+    <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
+    <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
+    <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
+    <string name="autofill_province" msgid="2231806553863422300">"Wilayah"</string>
+    <string name="autofill_postal_code" msgid="4696430407689377108">"Poskod"</string>
+    <string name="autofill_state" msgid="6988894195520044613">"Negeri"</string>
+    <string name="autofill_zip_code" msgid="8697544592627322946">"Poskod"</string>
+    <string name="autofill_county" msgid="237073771020362891">"Wilayah"</string>
+    <string name="autofill_island" msgid="4020100875984667025">"Pulau"</string>
+    <string name="autofill_district" msgid="8400735073392267672">"Daerah"</string>
+    <string name="autofill_department" msgid="5343279462564453309">"Jabatan"</string>
+    <string name="autofill_prefecture" msgid="2028499485065800419">"Wilayah"</string>
+    <string name="autofill_parish" msgid="8202206105468820057">"Kariah"</string>
+    <string name="autofill_area" msgid="3547409050889952423">"Kawasan"</string>
+    <string name="autofill_emirate" msgid="2893880978835698818">"Emiriah"</string>
+    <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"baca penanda buku dan sejarah Web anda"</string>
+    <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Membenarkan apl membaca sejarah semua URL yang telah Penyemak Imbas lawati dan semua penanda halaman Penyemak Imbas. Nota: kebenaran ini tidak boleh dikuatkuasakan oleh penyemak imbas pihak ketiga atau aplikasi lain dengan keupayaan menyemak imbas web."</string>
+    <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"tulis penanda buku dan sejarah web"</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Membenarkan apl mengubah suai sejarah atau penanda halaman Penyemak Imbas yang tersimpan pada tablet anda. Ini boleh membenarkan apl untuk memadam atau mengubah suai data Penyemak Imbas. Nota: kebenaran ini tidak boleh dikuatkuasakan oleh penyemak imbas pihak ketiga atau aplikasi lain dengan keupayaan menyemak imbas web."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Membenarkan apl mengubah suai sejarah atau penanda halaman Penyemak Imbas yang tersimpan pada telefon anda. Ini boleh membenarkan apl untuk memadam atau mengubah suai data Penyemak Imbas. Nota: kebenaran ini tidak boleh dikuatkuasakan oleh penyemak imbas pihak ketiga atau aplikasi lain dengan keupayaan menyemak imbas web."</string>
+    <string name="permlab_setAlarm" msgid="1379294556362091814">"tetapkan penggera"</string>
+    <string name="permdesc_setAlarm" msgid="316392039157473848">"Membenarkan apl untuk menetapkan penggera dalam apl penggera jam yang dipasang. Sesetengah applikasi jam penggera tidak boleh melaksanakan ciri ini."</string>
+    <string name="permlab_addVoicemail" msgid="5525660026090959044">"tambah mel suara"</string>
+    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Membenarkan apl untuk menambahkan mesej pada peti masuk mel suara anda."</string>
+    <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"ubah suai kebenaran geolokasi Penyemak Imbas"</string>
+    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Membenarkan apl untuk mengubah suai kebenaran geolokasi Penyemak Imbas. Apl hasad boleh menggunakannya untuk membenarkan menghantar maklumat lokasi kepada laman web sembarangan."</string>
+    <string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"sahkan pakej"</string>
+    <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"Membenarkan apl untuk mengesahkan bahawa pakej boleh dipasang."</string>
+    <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"ikat kepada pengesah pakej"</string>
+    <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Membenarkan pemegang membuat permintaan pengesah pakej. Tidak sekali-kali diperlukan untuk apl normal."</string>
+    <string name="permlab_serialPort" msgid="546083327654631076">"akses port bersiri"</string>
+    <string name="permdesc_serialPort" msgid="2991639985224598193">"Membenarkan pemegang mengakses port bersiri menggunakan API SerialManager."</string>
+    <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"akses pembekal kandungan secara luaran"</string>
+    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Membolehkan pemegang mengakses pembekal kandungan dari luar. Tidak akan sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_updateLock" msgid="3527558366616680889">"tidak menggalakkan kemas kini peranti automatik"</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"Membenarkan aplikasi untuk menawarkan maklumat kepada sistem tentang bila akan menjadi masa yang baik untuk but semula bukan interaktif untuk menaik taraf peranti."</string>
+    <string name="save_password_message" msgid="767344687139195790">"Adakah anda mahu penyemak imbas mengingati kata laluan ini?"</string>
+    <string name="save_password_notnow" msgid="6389675316706699758">"Bukan sekarang"</string>
+    <string name="save_password_remember" msgid="6491879678996749466">"Ingat"</string>
+    <string name="save_password_never" msgid="8274330296785855105">"Jangan sekali-kali"</string>
+    <string name="open_permission_deny" msgid="7374036708316629800">"Anda tidak mempunyai kebenaran untuk membuka laman ini."</string>
+    <string name="text_copied" msgid="4985729524670131385">"Teks disalin ke papan keratan"</string>
+    <string name="more_item_label" msgid="4650918923083320495">"Lagi"</string>
+    <string name="prepend_shortcut_label" msgid="2572214461676015642">"Menu+"</string>
+    <string name="menu_space_shortcut_label" msgid="2410328639272162537">"ruang"</string>
+    <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"enter"</string>
+    <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"padam"</string>
+    <string name="search_go" msgid="8298016669822141719">"Cari"</string>
+    <string name="searchview_description_search" msgid="6749826639098512120">"Carian"</string>
+    <string name="searchview_description_query" msgid="5911778593125355124">"Pertanyaan carian"</string>
+    <string name="searchview_description_clear" msgid="1330281990951833033">"Pertanyaan jelas"</string>
+    <string name="searchview_description_submit" msgid="2688450133297983542">"Serah pertanyaan"</string>
+    <string name="searchview_description_voice" msgid="2453203695674994440">"Carian suara"</string>
+    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Dayakan Jelajah melalui Sentuhan?"</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ingin mendayakan Jelajah melalui Sentuhan. Apabila Jelajah melalui Sentuhan didayakan, anda boleh mendengar atau melihat penerangan tentang apa di bawah jari anda atau melakukan gerak isyarat untuk berinteraksi dengan tablet."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ingin mendayakan Jelajah melalui Sentuhan. Apabila Jelajah melalui Sentuhan didayakan, anda boleh mendengar atau melihat penerangan tentang apa di bawah jari anda atau melakukan gerak isyarat untuk berinteraksi dengan telefon."</string>
+    <string name="oneMonthDurationPast" msgid="7396384508953779925">"1 bulan yang lalu"</string>
+    <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Sebelum 1 bulan yang lalu"</string>
+  <plurals name="num_seconds_ago">
+    <item quantity="one" msgid="4869870056547896011">"1 saat yang lalu"</item>
+    <item quantity="other" msgid="3903706804349556379">"<xliff:g id="COUNT">%d</xliff:g> saat yang lalu"</item>
+  </plurals>
+  <plurals name="num_minutes_ago">
+    <item quantity="one" msgid="3306787433088810191">"1 minit yang lalu"</item>
+    <item quantity="other" msgid="2176942008915455116">"<xliff:g id="COUNT">%d</xliff:g> minit yang lalu"</item>
+  </plurals>
+  <plurals name="num_hours_ago">
+    <item quantity="one" msgid="9150797944610821849">"1 jam yang lalu"</item>
+    <item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> jam yang lalu"</item>
+  </plurals>
+  <plurals name="last_num_days">
+    <item quantity="other" msgid="3069992808164318268">"<xliff:g id="COUNT">%d</xliff:g> hari terakhir"</item>
+  </plurals>
+    <string name="last_month" msgid="3959346739979055432">"Bulan lepas"</string>
+    <string name="older" msgid="5211975022815554840">"Lebih lama"</string>
+  <plurals name="num_days_ago">
+    <item quantity="one" msgid="861358534398115820">"semalam"</item>
+    <item quantity="other" msgid="2479586466153314633">"<xliff:g id="COUNT">%d</xliff:g> hari yang lalu"</item>
+  </plurals>
+  <plurals name="in_num_seconds">
+    <item quantity="one" msgid="2729745560954905102">"dalam 1 saat"</item>
+    <item quantity="other" msgid="1241926116443974687">"dalam <xliff:g id="COUNT">%d</xliff:g> saat"</item>
+  </plurals>
+  <plurals name="in_num_minutes">
+    <item quantity="one" msgid="8793095251325200395">"dalam 1 minit"</item>
+    <item quantity="other" msgid="3330713936399448749">"dalam <xliff:g id="COUNT">%d</xliff:g> minit"</item>
+  </plurals>
+  <plurals name="in_num_hours">
+    <item quantity="one" msgid="7164353342477769999">"dalam 1 jam"</item>
+    <item quantity="other" msgid="547290677353727389">"dalam <xliff:g id="COUNT">%d</xliff:g> jam"</item>
+  </plurals>
+  <plurals name="in_num_days">
+    <item quantity="one" msgid="5413088743009839518">"esok"</item>
+    <item quantity="other" msgid="5109449375100953247">"dalam <xliff:g id="COUNT">%d</xliff:g> hari"</item>
+  </plurals>
+  <plurals name="abbrev_num_seconds_ago">
+    <item quantity="one" msgid="1849036840200069118">"1 saat yang lalu"</item>
+    <item quantity="other" msgid="3699169366650930415">"<xliff:g id="COUNT">%d</xliff:g> saat yang lalu"</item>
+  </plurals>
+  <plurals name="abbrev_num_minutes_ago">
+    <item quantity="one" msgid="6361490147113871545">"1 minit yang lalu"</item>
+    <item quantity="other" msgid="851164968597150710">"<xliff:g id="COUNT">%d</xliff:g> minit yang lalu"</item>
+  </plurals>
+  <plurals name="abbrev_num_hours_ago">
+    <item quantity="one" msgid="4796212039724722116">"1 jam yang lalu"</item>
+    <item quantity="other" msgid="6889970745748538901">"<xliff:g id="COUNT">%d</xliff:g> jam yang lalu"</item>
+  </plurals>
+  <plurals name="abbrev_num_days_ago">
+    <item quantity="one" msgid="8463161711492680309">"semalam"</item>
+    <item quantity="other" msgid="3453342639616481191">"<xliff:g id="COUNT">%d</xliff:g> hari yang lalu"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_seconds">
+    <item quantity="one" msgid="5842225370795066299">"dalam 1 saat"</item>
+    <item quantity="other" msgid="5495880108825805108">"dalam <xliff:g id="COUNT">%d</xliff:g> saat"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_minutes">
+    <item quantity="one" msgid="562786149928284878">"dalam 1 minit"</item>
+    <item quantity="other" msgid="4216113292706568726">"dalam <xliff:g id="COUNT">%d</xliff:g> minit"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_hours">
+    <item quantity="one" msgid="3274708118124045246">"dalam 1 jam"</item>
+    <item quantity="other" msgid="3705373766798013406">"dalam <xliff:g id="COUNT">%d</xliff:g> jam"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_days">
+    <item quantity="one" msgid="2178576254385739855">"esok"</item>
+    <item quantity="other" msgid="2973062968038355991">"dalam <xliff:g id="COUNT">%d</xliff:g> hari"</item>
+  </plurals>
+    <string name="preposition_for_date" msgid="9093949757757445117">"pada <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="preposition_for_time" msgid="5506831244263083793">"pada <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="preposition_for_year" msgid="5040395640711867177">"dalam <xliff:g id="YEAR">%s</xliff:g>"</string>
+    <string name="day" msgid="8144195776058119424">"hari"</string>
+    <string name="days" msgid="4774547661021344602">"hari"</string>
+    <string name="hour" msgid="2126771916426189481">"jam"</string>
+    <string name="hours" msgid="894424005266852993">"jam"</string>
+    <string name="minute" msgid="9148878657703769868">"min"</string>
+    <string name="minutes" msgid="5646001005827034509">"min"</string>
+    <string name="second" msgid="3184235808021478">"saat"</string>
+    <string name="seconds" msgid="3161515347216589235">"saat"</string>
+    <string name="week" msgid="5617961537173061583">"minggu"</string>
+    <string name="weeks" msgid="6509623834583944518">"minggu"</string>
+    <string name="year" msgid="4001118221013892076">"tahun"</string>
+    <string name="years" msgid="6881577717993213522">"tahun"</string>
+  <plurals name="duration_seconds">
+    <item quantity="one" msgid="6962015528372969481">"1 saat"</item>
+    <item quantity="other" msgid="1886107766577166786">"<xliff:g id="COUNT">%d</xliff:g> saat"</item>
+  </plurals>
+  <plurals name="duration_minutes">
+    <item quantity="one" msgid="4915414002546085617">"1 minit"</item>
+    <item quantity="other" msgid="3165187169224908775">"<xliff:g id="COUNT">%d</xliff:g> minit"</item>
+  </plurals>
+  <plurals name="duration_hours">
+    <item quantity="one" msgid="8917467491248809972">"1 jam"</item>
+    <item quantity="other" msgid="3863962854246773930">"<xliff:g id="COUNT">%d</xliff:g> jam"</item>
+  </plurals>
+    <string name="VideoView_error_title" msgid="3534509135438353077">"Masalah video"</string>
+    <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Maaf, video ini tidak sah untuk penstriman ke peranti ini."</string>
+    <string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Tidak dapat mainkan video ini."</string>
+    <string name="VideoView_error_button" msgid="2822238215100679592">"OK"</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">"tengah hari"</string>
+    <string name="Noon" msgid="3342127745230013127">"Tengah hari"</string>
+    <string name="midnight" msgid="7166259508850457595">"tengah malam"</string>
+    <string name="Midnight" msgid="5630806906897892201">"Tengah malam"</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">"Pilih semua"</string>
+    <string name="cut" msgid="3092569408438626261">"Potong"</string>
+    <string name="copy" msgid="2681946229533511987">"Salin"</string>
+    <string name="paste" msgid="5629880836805036433">"Tampal"</string>
+    <string name="replace" msgid="5781686059063148930">"Ganti..."</string>
+    <string name="delete" msgid="6098684844021697789">"Padam"</string>
+    <string name="copyUrl" msgid="2538211579596067402">"Salin URL"</string>
+    <string name="selectTextMode" msgid="1018691815143165326">"Pilih teks"</string>
+    <string name="textSelectionCABTitle" msgid="5236850394370820357">"Pemilihan teks"</string>
+    <string name="addToDictionary" msgid="4352161534510057874">"Tambah ke kamus"</string>
+    <string name="deleteText" msgid="6979668428458199034">"Padam"</string>
+    <string name="inputMethod" msgid="1653630062304567879">"Kaedah input"</string>
+    <string name="editTextMenuTitle" msgid="4909135564941815494">"Tindakan teks"</string>
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Ruang storan semakin berkurangan"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Beberapa fungsi sistem mungkin tidak berfungsi"</string>
+    <string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang berjalan"</string>
+    <string name="app_running_notification_text" msgid="4653586947747330058">"Sentuh untuk maklumat lanjut atau untuk menghentikan apl."</string>
+    <string name="ok" msgid="5970060430562524910">"OK"</string>
+    <string name="cancel" msgid="6442560571259935130">"Batal"</string>
+    <string name="yes" msgid="5362982303337969312">"OK"</string>
+    <string name="no" msgid="5141531044935541497">"Batal"</string>
+    <string name="dialog_alert_title" msgid="2049658708609043103">"Perhatian"</string>
+    <string name="loading" msgid="7933681260296021180">"Memuatkan…"</string>
+    <string name="capital_on" msgid="1544682755514494298">"HIDUP"</string>
+    <string name="capital_off" msgid="6815870386972805832">"MATIKAN"</string>
+    <string name="whichApplication" msgid="4533185947064773386">"Selesaikan tindakan menggunakan"</string>
+    <string name="alwaysUse" msgid="4583018368000610438">"Gunakannya secara lalai untuk tindakan ini."</string>
+    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Padam bersih lalai dalam tetapan Sistem &gt; Apl &gt; Dimuat turun."</string>
+    <string name="chooseActivity" msgid="7486876147751803333">"Pilih tindakan"</string>
+    <string name="chooseUsbActivity" msgid="6894748416073583509">"Pilih apl untuk peranti USB"</string>
+    <string name="noApplications" msgid="2991814273936504689">"Tiada apl yang boleh menjalankan tindakan ini."</string>
+    <string name="aerr_title" msgid="1905800560317137752"></string>
+    <string name="aerr_application" msgid="932628488013092776">"Malangnya, <xliff:g id="APPLICATION">%1$s</xliff:g> telah berhenti."</string>
+    <string name="aerr_process" msgid="4507058997035697579">"Malangnya, proses <xliff:g id="PROCESS">%1$s</xliff:g> telah berhenti."</string>
+    <string name="anr_title" msgid="4351948481459135709"></string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> tidak bertindak balas.\n\nAdakah anda mahu menutupnya?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Aktiviti <xliff:g id="ACTIVITY">%1$s</xliff:g> tidak bertindak balas. \n\n Adakah anda mahu menutupnya?"</string>
+    <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> tidak bertindak balas. Adakah anda mahu menutupnya?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Proses <xliff:g id="PROCESS">%1$s</xliff:g> tidak bertindak balas. \n\nAdakah anda mahu menutupnya?"</string>
+    <string name="force_close" msgid="8346072094521265605">"OK"</string>
+    <string name="report" msgid="4060218260984795706">"Laporkan"</string>
+    <string name="wait" msgid="7147118217226317732">"Tunggu"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Laman ini tidak bertindak balas. \n\nAdakah anda mahu menutupnya?"</string>
+    <string name="launch_warning_title" msgid="1547997780506713581">"Apl diubah hala"</string>
+    <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> kini sedang berjalan."</string>
+    <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> pada asalnya telah dilancarkan."</string>
+    <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Skala"</string>
+    <string name="screen_compat_mode_show" msgid="4013878876486655892">"Sentiasa tunjukkan"</string>
+    <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Dayakan semula kod kompak ini tetapan Sistem &gt; Apl &gt; Dimuat turun."</string>
+    <string name="smv_application" msgid="3307209192155442829">"Apl <xliff:g id="APPLICATION">%1$s</xliff:g> (proses <xliff:g id="PROCESS">%2$s</xliff:g>) telah melanggar dasar Mod Tegasnya sendiri."</string>
+    <string name="smv_process" msgid="5120397012047462446">"Proses <xliff:g id="PROCESS">%1$s</xliff:g> telah melanggar dasar Mod Tegasnya sendiri."</string>
+    <string name="android_upgrading_title" msgid="1584192285441405746">"Android sedang menaik taraf..."</string>
+    <string name="android_upgrading_apk" msgid="7904042682111526169">"Mengoptimumkan apl <xliff:g id="NUMBER_0">%1$d</xliff:g> daripada <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+    <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Memulakan apl."</string>
+    <string name="android_upgrading_complete" msgid="1405954754112999229">"But akhir."</string>
+    <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> dijalankan"</string>
+    <string name="heavy_weight_notification_detail" msgid="1721681741617898865">"Sentuh untuk bertukar ke apl"</string>
+    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Tukar apl?"</string>
+    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Apl lain sudah pun dijalankan yang mesti dihentikan sebelum anda boleh memulakan yang baharu."</string>
+    <string name="old_app_action" msgid="493129172238566282">"Kembali ke <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
+    <string name="old_app_description" msgid="2082094275580358049">"Jangan mulakan apl baharu."</string>
+    <string name="new_app_action" msgid="5472756926945440706">"Mulakan <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
+    <string name="new_app_description" msgid="1932143598371537340">"Hentikan apl lama tanpa menyimpan."</string>
+    <string name="sendText" msgid="5209874571959469142">"Pilih tindakan untuk teks"</string>
+    <string name="volume_ringtone" msgid="6885421406845734650">"Kelantangan pendering"</string>
+    <string name="volume_music" msgid="5421651157138628171">"Kelantangan media"</string>
+    <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"Bermain melalui Bluetooth"</string>
+    <string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"Nada dering senyap ditetapkan"</string>
+    <string name="volume_call" msgid="3941680041282788711">"Kelantangan semasa panggilan"</string>
+    <string name="volume_bluetooth_call" msgid="2002891926351151534">"Kelantangan semasa dalam panggilan menggunakan Bluetooth"</string>
+    <string name="volume_alarm" msgid="1985191616042689100">"Kelantangan penggera"</string>
+    <string name="volume_notification" msgid="2422265656744276715">"Kelantangan pemberitahuan"</string>
+    <string name="volume_unknown" msgid="1400219669770445902">"Kelantangan"</string>
+    <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"Kelantangan Bluetooth"</string>
+    <string name="volume_icon_description_ringer" msgid="3326003847006162496">"Kelantangan nada dering"</string>
+    <string name="volume_icon_description_incall" msgid="8890073218154543397">"Kelantangan panggilan"</string>
+    <string name="volume_icon_description_media" msgid="4217311719665194215">"Kelantangan media"</string>
+    <string name="volume_icon_description_notification" msgid="7044986546477282274">"Kelantangan pemberitahuan"</string>
+    <string name="ringtone_default" msgid="3789758980357696936">"Nada dering lalai"</string>
+    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Nada dering lalai (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <string name="ringtone_silent" msgid="7937634392408977062">"Tiada"</string>
+    <string name="ringtone_picker_title" msgid="3515143939175119094">"Nada dering"</string>
+    <string name="ringtone_unknown" msgid="5477919988701784788">"Nada dering tidak diketahui"</string>
+  <plurals name="wifi_available">
+    <item quantity="one" msgid="6654123987418168693">"Rangkaian Wi-Fi tersedia"</item>
+    <item quantity="other" msgid="4192424489168397386">"Rangkaian Wi-Fi tersedia"</item>
+  </plurals>
+  <plurals name="wifi_available_detailed">
+    <item quantity="one" msgid="1634101450343277345">"Rangkaian Wi-Fi terbuka tersedia"</item>
+    <item quantity="other" msgid="7915895323644292768">"Rangkaian Wi-Fi terbuka tersedia"</item>
+  </plurals>
+    <string name="wifi_available_sign_in" msgid="4029489716605255386">"Log masuk ke rangkaian Wi-Fi"</string>
+    <string name="network_available_sign_in" msgid="8495155593358054676">"Log masuk ke rangkaian"</string>
+    <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
+    <skip />
+    <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Tidak boleh menyambung kepada Wi-Fi"</string>
+    <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" mempunyai sambungan internet yang kurang baik."</string>
+    <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Langsung"</string>
+    <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Mulakan Wi-Fi Langsung. Hal ini akan mematikan pengendalian klien/liputan Wi-Fi."</string>
+    <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Tidak dapat memulakan Wi-Fi Langsung."</string>
+    <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct dihidupkan"</string>
+    <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Sentuh untuk tetapan"</string>
+    <string name="accept" msgid="1645267259272829559">"Terima"</string>
+    <string name="decline" msgid="2112225451706137894">"Tolak"</string>
+    <string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Jemputan dihantar"</string>
+    <string name="wifi_p2p_invitation_to_connect_title" msgid="4958803948658533637">"Jemputan untuk menyambung"</string>
+    <string name="wifi_p2p_from_message" msgid="570389174731951769">"Daripada:"</string>
+    <string name="wifi_p2p_to_message" msgid="248968974522044099">"Kepada:"</string>
+    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"Taipkan PIN yang diperlukan:"</string>
+    <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"Sambungan tablet ke Wi-Fi akan diputuskan buat sementara waktu semasa tablet bersambung ke <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"Sambungan telefon ke Wi-Fi akan diputuskan buat sementara waktu semasa telefon bersambung ke <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="select_character" msgid="3365550120617701745">"Masukkan aksara"</string>
+    <string name="sms_control_title" msgid="7296612781128917719">"Menghantar mesej SMS"</string>
+    <string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; sedang menghantar banyak mesej SMS. Adakah anda mahu membenarkan apl ini terus menghantar mesej?"</string>
+    <string name="sms_control_yes" msgid="3663725993855816807">"Benarkan"</string>
+    <string name="sms_control_no" msgid="625438561395534982">"Nafikan"</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; ingin menghantar mesej kepada &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt;."</string>
+    <string name="sms_short_code_details" msgid="3492025719868078457">"Ini akan menyebabkan akaun mudah alih anda "<font fgcolor="#ffffb060">"dikenakan caj"</font>"."</string>
+    <string name="sms_premium_short_code_details" msgid="5523826349105123687"><font fgcolor="#ffffb060">"Ini akan menyebabkan akaun mudah alih anda dikenakan caj."</font></string>
+    <string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"Hantar"</string>
+    <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"Batal"</string>
+    <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"Ingat pilihan saya"</string>
+    <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"Anda boleh menukar ini nanti dalam Tetapan &gt; Apl"</string>
+    <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Sentiasa Benarkan"</string>
+    <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Jangan Benarkan"</string>
+    <string name="sim_removed_title" msgid="6227712319223226185">"Kad SIM dikeluarkan"</string>
+    <string name="sim_removed_message" msgid="2333164559970958645">"Rangkaian mudah alih tidak akan tersedia sehingga anda mula semula dengan kad SIM yang sah dimasukkan."</string>
+    <string name="sim_done_button" msgid="827949989369963775">"Selesai"</string>
+    <string name="sim_added_title" msgid="3719670512889674693">"Kad SIM ditambah"</string>
+    <string name="sim_added_message" msgid="6599945301141050216">"Mulakan semula peranti anda untuk mengakses rangkaian mudah alih."</string>
+    <string name="sim_restart_button" msgid="4722407842815232347">"Mulakan semula"</string>
+    <string name="time_picker_dialog_title" msgid="8349362623068819295">"Tetapkan masa"</string>
+    <string name="date_picker_dialog_title" msgid="5879450659453782278">"Tetapkan tarikh"</string>
+    <string name="date_time_set" msgid="5777075614321087758">"Tetapkan"</string>
+    <string name="date_time_done" msgid="2507683751759308828">"Selesai"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff33b5e5">"BAHARU: "</font></string>
+    <string name="perms_description_app" msgid="5139836143293299417">"Disediakan oleh <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+    <string name="no_permissions" msgid="7283357728219338112">"Tiada kebenaran diperlukan"</string>
+    <string name="perm_costs_money" msgid="4902470324142151116">"anda mungkin dikenakan bayaran"</string>
+    <string name="usb_storage_activity_title" msgid="4465055157209648641">"Storan massa USB"</string>
+    <string name="usb_storage_title" msgid="5901459041398751495">"sambungan USB"</string>
+    <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"Anda bersambung ke komputer melalui USB. Sentuh butang di bawah jika anda mahu menyalin fail antara komputer dan storan USB Android anda."</string>
+    <string name="usb_storage_message" product="default" msgid="805351000446037811">"Anda telah bersambung ke komputer melalui USB. Sentuh butang di bawah jika anda mahu menyalin fail di antara komputer dan kad SD Android anda."</string>
+    <string name="usb_storage_button_mount" msgid="1052259930369508235">"Hidupkan storan USB"</string>
+    <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"Terdapat masalah menggunakan storan USB anda untuk storan massa USB."</string>
+    <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"Terdapat masalah menggunakan kad SD anda untuk storan massa USB."</string>
+    <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB disambungkan"</string>
+    <string name="usb_storage_notification_message" msgid="939822783828183763">"Pilih untuk menyalin fail ke/dari komputer anda."</string>
+    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Matikan storan USB"</string>
+    <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"Sentuh untuk mematikan storan USB."</string>
+    <string name="usb_storage_stop_title" msgid="660129851708775853">"Storan USB sedang digunakan"</string>
+    <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"Sebelum mematikan storan USB, nyahlekap (\"keluarkan\") storan USB Android dari komputer anda."</string>
+    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"Sebelum mematikan storan USB, nyah lekap (\"keluarkan\") kad SD Android dari komputer anda."</string>
+    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"Matikan storan USB"</string>
+    <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"Terdapat masalah mematikan storan USB. Semak bahawa anda telah menyahlekapkan hos USB, kemudian cuba lagi."</string>
+    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Hidupkan storan USB."</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Jika anda menghidupkan storan USB, sesetengah apl yang sedang anda gunakan akan terhenti dan mungkin tidak akan tersedia sehingga anda mematikan storan USB."</string>
+    <string name="dlg_error_title" msgid="7323658469626514207">"Operasi USB tidak berjaya"</string>
+    <string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
+    <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Disambungkan sebagai peranti media"</string>
+    <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Disambungkan sebagai kamera"</string>
+    <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Disambungkan sebagai pemasang"</string>
+    <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Disambungkan kepada aksesori USB"</string>
+    <string name="usb_notification_message" msgid="2290859399983720271">"Sentuh untuk mendapatkan pilihan USB yang lain."</string>
+    <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Format storan USB?"</string>
+    <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Format kad SD?"</string>
+    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Semua fail yang disimpan dalam storan USB anda akan dipadamkan. Tindakan ini tidak boleh diterbalikkan!"</string>
+    <string name="extmedia_format_message" product="default" msgid="14131895027543830">"Semua data pada kad anda akan hilang."</string>
+    <string name="extmedia_format_button_format" msgid="4131064560127478695">"Format"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"Penyahpepijatan USB disambungkan"</string>
+    <string name="adb_active_notification_message" msgid="1016654627626476142">"Sentuh untuk melumpuhkan penyahpepijatan USB."</string>
+    <string name="select_input_method" msgid="4653387336791222978">"Pilih kaedah input"</string>
+    <string name="configure_input_methods" msgid="9091652157722495116">"Sediakan kaedah input"</string>
+    <string name="use_physical_keyboard" msgid="6203112478095117625">"Papan kekunci fizikal"</string>
+    <string name="hardware" msgid="7517821086888990278">"Perkakasan"</string>
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Pilih susun atur papan kekunci"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Sentuh untuk memilih susun atur papan kekunci."</string>
+    <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="candidates_style" msgid="4333913089637062257"><u>"calon"</u></string>
+    <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"Menyediakan storan USB"</string>
+    <string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"Menyediakan kad SD"</string>
+    <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"Menyemak untuk mengesan ralat."</string>
+    <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"Storan USB kosong"</string>
+    <string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"Kad SD kosong"</string>
+    <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"Storan USB kosong atau mempunyai sistem fail yang tidak disokong."</string>
+    <string name="ext_media_nofs_notification_message" product="default" msgid="8641065641786923604">"Kad SD kosong atau mempunyai sistem fail yang tidak disokong."</string>
+    <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"Storan USB rosak"</string>
+    <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"Kad SD rosak"</string>
+    <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="1795917578395333280">"Storan USB rosak. Cuba formatkannya semula."</string>
+    <string name="ext_media_unmountable_notification_message" product="default" msgid="1753898567525568253">"Kad SD rosak. Cuba formatkannya semula."</string>
+    <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"Strn USB dialh klr tnpa dijgka"</string>
+    <string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"Kad SD dikeluarkan tanpa dijangka"</string>
+    <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"Nyahlekap storan USB sebelum mengeluarkannya untuk mengelakkan kehilangan data."</string>
+    <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"Nyahlekap kad SD sebelum mengeluarkannya untuk mengelakkan kehilangan data."</string>
+    <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"Strn USB slamat utk dikluarkan"</string>
+    <string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"selamat untuk mengeluarkan kad SD"</string>
+    <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"Anda boleh mengeluarkan storan USB dengan selamat."</string>
+    <string name="ext_media_safe_unmount_notification_message" product="default" msgid="568841278138377604">"Anda boleh mengeluarkan kad SD dengan selamat."</string>
+    <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"Storan USB dialih keluar"</string>
+    <string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"Kad SD dikeluarkan"</string>
+    <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"Storan USB dikeluarkan. Sisipkan media baru."</string>
+    <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"Kad SD telah dikeluarkan. Masukkan yang baru."</string>
+    <string name="activity_list_empty" msgid="1675388330786841066">"Tiada aktiviti yang sepadan ditemui."</string>
+    <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"kemas kini statistik penggunaan komponen"</string>
+    <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"Membenarkan apl untuk mengubah suai statistik penggunaan komponen yang dikumpul. Bukan untuk kegunaan apl biasa."</string>
+    <string name="permlab_copyProtectedData" msgid="4341036311211406692">"salin kandungan"</string>
+    <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Membenarkan apl untuk menggunakan perkhidmatan bekas lalai untuk menyalin kandungan. Bukan untuk digunakan oleh apl biasa."</string>
+    <string name="permlab_route_media_output" msgid="1642024455750414694">"Buat laluan output media"</string>
+    <string name="permdesc_route_media_output" msgid="4932818749547244346">"Membenarkan apl untuk membuat laluan output media ke peranti luaran lain."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Akses storan selamat pengawal kekunci"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Membenarkan aplikasi mengakses storan selamat pengawal kekunci."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Kawal paparkan dan sembunyikan pengawal kekunci"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Membenarkan aplikasi untuk mengawal pengawal kekunci."</string>
+    <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Sentuh dua kali untuk mendapatkan kawalan zum"</string>
+    <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Tidak dapat menambahkan widget."</string>
+    <string name="ime_action_go" msgid="8320845651737369027">"Pergi"</string>
+    <string name="ime_action_search" msgid="658110271822807811">"Cari"</string>
+    <string name="ime_action_send" msgid="2316166556349314424">"Hantar"</string>
+    <string name="ime_action_next" msgid="3138843904009813834">"Seterusnya"</string>
+    <string name="ime_action_done" msgid="8971516117910934605">"Selesai"</string>
+    <string name="ime_action_previous" msgid="1443550039250105948">"Sblm"</string>
+    <string name="ime_action_default" msgid="2840921885558045721">"Laksanakan"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Dail nombor\nmenggunakan <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Wujudkan kenalan\nmenggunakan <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Satu atau lebih apl berikut meminta kebenaran untuk mengakses akaun anda, sekarang dan pada masa hadapan."</string>
+    <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Adakah anda mahu membenarkan permintaan ini?"</string>
+    <string name="grant_permissions_header_text" msgid="6874497408201826708">"Permintaan akses"</string>
+    <string name="allow" msgid="7225948811296386551">"Benarkan"</string>
+    <string name="deny" msgid="2081879885755434506">"Nafi"</string>
+    <string name="permission_request_notification_title" msgid="6486759795926237907">"Kebenaran diminta"</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Kebenaran diminta\nuntuk akaun <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="input_method_binding_label" msgid="1283557179944992649">"Kaedah input"</string>
+    <string name="sync_binding_label" msgid="3687969138375092423">"Penyegerakan"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"Kebolehaksesan"</string>
+    <string name="wallpaper_binding_label" msgid="1240087844304687662">"Kertas dinding"</string>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"Tukar kertas dinding"</string>
+    <string name="notification_listener_binding_label" msgid="2014162835481906429">"Pendengar pemberitahuan"</string>
+    <string name="vpn_title" msgid="19615213552042827">"VPN diaktifkan"</string>
+    <string name="vpn_title_long" msgid="6400714798049252294">"VPN diaktifkan oleh <xliff:g id="APP">%s</xliff:g>"</string>
+    <string name="vpn_text" msgid="3011306607126450322">"Sentuh untuk mengurus rangkaian."</string>
+    <string name="vpn_text_long" msgid="6407351006249174473">"Bersambung ke <xliff:g id="SESSION">%s</xliff:g>. Sentuh 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_error" msgid="6009249814034708175">"Ralat VPN sentiasa hidup"</string>
+    <string name="vpn_lockdown_config" msgid="6415899150671537970">"Sentuh untuk mengkonfigurasikan"</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>
+    <string name="submit" msgid="1602335572089911941">"Serah"</string>
+    <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Mod kereta didayakan"</string>
+    <string name="car_mode_disable_notification_message" msgid="8035230537563503262">"Sentuh untuk keluar dari mod kereta."</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"Penambatan atau titik panas aktif"</string>
+    <string name="tethered_notification_message" msgid="6857031760103062982">"Sentuh untuk menyediakan."</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>
+    <string name="throttle_warning_notification_title" msgid="4890894267454867276">"Penggunaan tinggi data mudah alih"</string>
+    <string name="throttle_warning_notification_message" msgid="3340822228599337743">"Sentuh untuk mengetahui lebih lanjut mengenai penggunaan data."</string>
+    <string name="throttled_notification_title" msgid="6269541897729781332">"Melebihi had data mudah alih"</string>
+    <string name="throttled_notification_message" msgid="5443457321354907181">"Sentuh untuk mengetahui lebih lanjut mengenai penggunaan data mudah alih."</string>
+    <string name="no_matches" msgid="8129421908915840737">"Tiada padanan"</string>
+    <string name="find_on_page" msgid="1946799233822820384">"Cari di halaman"</string>
+  <plurals name="matches_found">
+    <item quantity="one" msgid="8167147081136579439">"1 padanan"</item>
+    <item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> daripada <xliff:g id="TOTAL">%d</xliff:g>"</item>
+  </plurals>
+    <string name="action_mode_done" msgid="7217581640461922289">"Selesai"</string>
+    <string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"Menyahlekap storan USB…"</string>
+    <string name="progress_unmounting" product="default" msgid="1327894998409537190">"Menyahlekap kad SD…"</string>
+    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"Memadamkan storan USB…"</string>
+    <string name="progress_erasing" product="default" msgid="6596988875507043042">"Memadamkan kad SD…"</string>
+    <string name="format_error" product="nosdcard" msgid="6299769563624776948">"Tidak dapat memadamkan storan USB."</string>
+    <string name="format_error" product="default" msgid="7315248696644510935">"Tidak dapat memadamkan kad SD."</string>
+    <string name="media_bad_removal" msgid="7960864061016603281">"Kad SD telah dikeluarkan sebelum dinyahlekap."</string>
+    <string name="media_checking" product="nosdcard" msgid="418188720009569693">"Storan USB sedang disemak buat masa ini."</string>
+    <string name="media_checking" product="default" msgid="7334762503904827481">"Kad SD sedang disemak buat masa ini."</string>
+    <string name="media_removed" msgid="7001526905057952097">"Kad SD telah dikeluarkan."</string>
+    <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"Storan USB sedang digunakan oleh komputer buat masa ini."</string>
+    <string name="media_shared" product="default" msgid="5706130568133540435">"Kad SD sedang digunakan oleh komputer buat masa ini."</string>
+    <string name="media_unknown_state" msgid="729192782197290385">"Media luaran dalam keadaan yang tidak diketahui."</string>
+    <string name="share" msgid="1778686618230011964">"Kongsi"</string>
+    <string name="find" msgid="4808270900322985960">"Dapatkan"</string>
+    <string name="websearch" msgid="4337157977400211589">"Carian Web"</string>
+    <string name="find_next" msgid="5742124618942193978">"Cari seterusnya"</string>
+    <string name="find_previous" msgid="2196723669388360506">"Cari sebelumnya"</string>
+    <string name="gpsNotifTicker" msgid="5622683912616496172">"Permintaan lokasi daripada <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Permintaan lokasi"</string>
+    <string name="gpsNotifMessage" msgid="1374718023224000702">"Diminta oleh <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+    <string name="gpsVerifYes" msgid="2346566072867213563">"Ya"</string>
+    <string name="gpsVerifNo" msgid="1146564937346454865">"Tidak"</string>
+    <string name="sync_too_many_deletes" msgid="5296321850662746890">"Melebihi had padam"</string>
+    <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"Terdapat <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> item yang dipadamkan untuk <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, akaun <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Apakah yang mahu anda lakukan?"</string>
+    <string name="sync_really_delete" msgid="2572600103122596243">"Padamkan item itu"</string>
+    <string name="sync_undo_deletes" msgid="2941317360600338602">"Buat asal pemadaman"</string>
+    <string name="sync_do_nothing" msgid="3743764740430821845">"Jangan lakukan apa-apa sekarang"</string>
+    <string name="choose_account_label" msgid="5655203089746423927">"Pilih akaun"</string>
+    <string name="add_account_label" msgid="2935267344849993553">"Tambah akaun"</string>
+    <string name="add_account_button_label" msgid="3611982894853435874">"Tambah akaun"</string>
+    <string name="number_picker_increment_button" msgid="2412072272832284313">"Tingkatkan"</string>
+    <string name="number_picker_decrement_button" msgid="476050778386779067">"Kurangkan"</string>
+    <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> sentuh terus."</string>
+    <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Luncurkan ke atas untuk meningkatkan dan ke bawah untuk mengurangkan."</string>
+    <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Tingkatkan minit"</string>
+    <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Kurangkan minit"</string>
+    <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Tingkatkan jam"</string>
+    <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Kurangkan jam"</string>
+    <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Tetapkan PM"</string>
+    <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Tetapkan AM"</string>
+    <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Tingkatkan bulan"</string>
+    <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Kurangkan bulan"</string>
+    <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Tingkatkan hari"</string>
+    <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Kurangkan hari"</string>
+    <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Tingkatkan tahun"</string>
+    <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Kurangkan tahun"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Batal"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Padam"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Selesai"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Perubahan mod"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Masuk"</string>
+    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Pilih apl"</string>
+    <string name="shareactionprovider_share_with" msgid="806688056141131819">"Kongsi dengan"</string>
+    <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Kongsi dengan <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+    <string name="content_description_sliding_handle" msgid="415975056159262248">"Pemegang gelongsor. Sentuh &amp; tahan."</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Luncurkan ke atas untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Luncurkan ke bawah untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Luncurkan ke kiri untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Luncurkan ke kanan untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Buka kunci"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Senyap"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Bunyi dihidupkan"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Carian"</string>
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Leret untuk membuka kunci."</string>
+    <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Pasangkan set kepala untuk mendengar kekunci kata laluan disebutkan."</string>
+    <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Titik."</string>
+    <string name="action_bar_home_description" msgid="5293600496601490216">"Navigasi laman utama"</string>
+    <string name="action_bar_up_description" msgid="2237496562952152589">"Navigasi ke atas"</string>
+    <string name="action_menu_overflow_description" msgid="2295659037509008453">"Lagi pilihan"</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="4891916833657929263">"Storan dalaman"</string>
+    <string name="storage_sd_card" msgid="3282948861378286745">"Kad SD"</string>
+    <string name="storage_usb" msgid="3017954059538517278">"Storan USB"</string>
+    <string name="extract_edit_menu_button" msgid="8940478730496610137">"Edit"</string>
+    <string name="data_usage_warning_title" msgid="1955638862122232342">"Amaran penggunaan data"</string>
+    <string name="data_usage_warning_body" msgid="2814673551471969954">"Sentuh untuk melihat penggunaan dan tetapan."</string>
+    <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"Data 2G-3G dilumpuhkan"</string>
+    <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Data 4G dilumpuhkan"</string>
+    <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Data mudah alih dilumpuhkan"</string>
+    <string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"Data Wi-Fi dilumpuhkan"</string>
+    <string name="data_usage_limit_body" msgid="3317964706973601386">"Sentuh untuk mendayakan."</string>
+    <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Melebihi had data 2G-3G"</string>
+    <string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"Melebihi had data 4G"</string>
+    <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"Melebihi had data mudah alih"</string>
+    <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Melebihi had data Wi-Fi"</string>
+    <string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> melebihi had yang ditentukan."</string>
+    <string name="data_usage_restricted_title" msgid="5965157361036321914">"Data latar belakang terhad"</string>
+    <string name="data_usage_restricted_body" msgid="6741521330997452990">"Sentuh untuk membuang sekatan."</string>
+    <string name="ssl_certificate" msgid="6510040486049237639">"Sijil keselamatan"</string>
+    <string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Sijil ini sah."</string>
+    <string name="issued_to" msgid="454239480274921032">"Dikeluarkan kepada:"</string>
+    <string name="common_name" msgid="2233209299434172646">"Nama biasa:"</string>
+    <string name="org_name" msgid="6973561190762085236">"Organisasi:"</string>
+    <string name="org_unit" msgid="7265981890422070383">"Unit organisasi:"</string>
+    <string name="issued_by" msgid="2647584988057481566">"Dikeluarkan oleh:"</string>
+    <string name="validity_period" msgid="8818886137545983110">"Kesahan:"</string>
+    <string name="issued_on" msgid="5895017404361397232">"Dikeluarkan pada:"</string>
+    <string name="expires_on" msgid="3676242949915959821">"Tamat tempoh pada:"</string>
+    <string name="serial_number" msgid="758814067660862493">"Nombor siri:"</string>
+    <string name="fingerprints" msgid="4516019619850763049">"Cap jari:"</string>
+    <string name="sha256_fingerprint" msgid="4391271286477279263">"Cap jari SHA-256:"</string>
+    <string name="sha1_fingerprint" msgid="7930330235269404581">"Cap jari SHA-1:"</string>
+    <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Lihat semua"</string>
+    <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Pilih aktiviti"</string>
+    <string name="share_action_provider_share_with" msgid="5247684435979149216">"Kongsi dengan"</string>
+    <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="3245653681008218030">"Menghantar…"</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Lancarkan Penyemak Imbas?"</string>
+    <string name="SetupCallDefault" msgid="5834948469253758575">"Terima panggilan?"</string>
+    <string name="activity_resolver_use_always" msgid="8017770747801494933">"Sentiasa"</string>
+    <string name="activity_resolver_use_once" msgid="2404644797149173758">"Hanya sekali"</string>
+    <string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"Tablet"</string>
+    <string name="default_audio_route_name" product="default" msgid="4239291273420140123">"Telefon"</string>
+    <string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Fon kepala"</string>
+    <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Pembesar suara dok"</string>
+    <string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string>
+    <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistem"</string>
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio Bluetooth"</string>
+    <string name="wireless_display_route_description" msgid="9070346425023979651">"Paparan wayarles"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Selesai"</string>
+    <string name="media_route_button_content_description" msgid="5758553567065145276">"Output media"</string>
+    <string name="media_route_status_scanning" msgid="7279908761758293783">"Mengimbas…"</string>
+    <string name="media_route_status_connecting" msgid="6422571716007825440">"Menyambung..."</string>
+    <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">"Skrin Terbina Dalam"</string>
+    <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"Skrin HDMI"</string>
+    <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Tindih #<xliff:g id="ID">%1$d</xliff:g>"</string>
+    <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", selamat"</string>
+    <string name="wifi_display_notification_title" msgid="2223050649240326557">"Paparan wayarles disambungkan"</string>
+    <string name="wifi_display_notification_message" msgid="4498802012464170685">"Skrin ini ditunjukkan pada peranti lain"</string>
+    <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Putus sambungan"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Panggilan kecemasan"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Lupa Corak"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Corak Salah"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Kata Laluan Salah"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN salah"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Cuba lagi dalam <xliff:g id="NUMBER">%1$d</xliff:g> saat."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Lukiskan corak anda"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Masukkan PIN SIM"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Masukkan PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Masukkan Kata Laluan"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"Kini SIM dilumpuhkan. Masukkan kod PUK untuk meneruskan. Hubungi pembawa untuk butiran."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Masukkan kod PIN yang diingini"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Sahkan kod PIN yang diingini"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Membuka kunci kad SIM..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Kod PIN salah."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Taipkan PIN yang mengandungi 4 hingga 8 nombor."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Kod PUK mestilah 8 nombor atau lebih."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Masukkan semula kod PIN yang betul. Percubaan berulang akan melumpuhkan SIM secara kekal."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Kod PIN tidak sepadan"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Terlalu banyak percubaan melukis corak"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Untuk membuka kunci, log masuk dengan akaun Google anda."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Nama Pengguna (E-mel)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Kata laluan"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Log masuk"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nama pengguna atau kata laluan tidak sah."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Lupa nama pengguna atau kata laluan anda?\nLawati"<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Menyemak akaun…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Anda telah menaip PIN anda secara salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Anda telah menaip kata laluan anda secara salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Anda telah tersilap melukis corak buka kunci anda sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Anda telah mencuba untuk membuka kunci tablet dengan salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, tablet akan ditetapkan semula kepada tetapan lalai kilang dan semua data pengguna akan hilang."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Anda telah mencuba untuk membuka kunci telefon dengan salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, telefon akan ditetapkan semula kepada tetapan lalai kilang dan semua data pengguna akan hilang."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Anda telah mencuba untuk membuka kunci tablet secara salah sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Tablet kini akan ditetapkan semula ke tetapan lalai kilang."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Anda telah mencuba untuk membuka kunci telefon secara salah sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Telefon kini akan ditetapkan semula ke tetapan lalai kilang."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Anda telah tersilap melukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci tablet anda menggunakan log masuk Google anda.\n\n Cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Anda telah tersilap lukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci telefon anda menggunakan log masuk Google anda.\n\n Cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Alih keluar"</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Tingkatkan kelantangan melebihi aras yang dicadangkan?\nMendengar pada kelantangan tinggi untuk tempoh yang panjang boleh merosakkan pendengaran anda."</string>
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Teruskan menahan dengan dua jari untuk mendayakan kebolehcapaian."</string>
+    <string name="accessibility_enabled" msgid="1381972048564547685">"Kebolehcapaian didayakan."</string>
+    <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Kebolehcapaian dibatalkan."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Pengguna semasa <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="owner_name" msgid="2716755460376028154">"Pemilik"</string>
+    <string name="error_message_title" msgid="4510373083082500195">"Ralat"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Apl ini tidak menyokong akaun untuk profil yang disekat"</string>
+    <string name="app_not_found" msgid="3429141853498927379">"Tidak menemui aplikasi untuk mengendalikan tindakan ini"</string>
+    <string name="revoke" msgid="5404479185228271586">"Batalkan"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Surat"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Surat Kerajaan"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Undang-undang"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Undang-undang Junior"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Lejar"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Dibatalkan"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Ralat menulis kandungan"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"tidak diketahui"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Masukkan PIN pentadbir"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Masukkan PIN"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Salah"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN semasa"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"PIN baharu"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Sahkan PIN baharu"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Buat PIN untuk mengubah suai sekatan"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PIN tidak sepadan. Cuba lagi."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"PIN terlalu pendek. Mesti sekurang-kurangnya 4 angka."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Cuba 1 saat lagi"</item>
+    <item quantity="other" msgid="4730868920742952817">"Cuba <xliff:g id="COUNT">%d</xliff:g> saat lagi"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Cuba sebentar lagi"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Leret bhg tepi skrin utk serlah bar"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Leret dari tepi skrin untuk menampakkan bar sistem"</string>
+</resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 4a0017f..e6dc0ca 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -279,6 +279,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Membenarkan apl memindahkan tugasan ke latar depan dan latar belakang. Apl boleh melakukan ini tanpa input anda."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"hentikan apl yang sedang dijalankan"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Membenarkan apl untuk mengalih keluar tugasan dan melupuskan aplnya. Apl hasad boleh mengganggu tingkah laku apl lain."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"urus tindanan aktiviti"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Membenarkan apl menambah, mengalih keluar dan mengubah suai tindanan aktiviti tempat apl lain berjalan. Apl hasad boleh mengganggu tingkah laku apl lain."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"mulakan sebarang aktiviti"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Membenarkan apl untuk memulakan apa-apa aktiviti, tanpa mengira perlindungan kebenaran atau keadaan eksport."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"tetapkan keserasian skrin"</string>
@@ -312,7 +314,7 @@
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"halang pertukaran apl"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Menghalang pengguna daripada bertukar kepada apl lain."</string>
     <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"dapatkan maklumat apl semasa"</string>
-    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Membenarkan pemegang mendapatkan maklumat peribadi tentang permohonan semasa di latar hadapan skrin"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="8153651434145132505">"Membenarkan pemegang mendapatkan maklumat peribadi tentang aplikasi dan perkhidmatan semasa di latar hadapan skrin."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"pantau dan kawal semua pelancaran apl"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Membenarkan apl untuk memantau dan mengawal cara sistem melancarkan aktiviti. Apl hasad boleh menjejaskan sistem sepenuhnya. Kebenaran ini hanya diperlukan untuk pembangunan, tidak sekali-kali untuk penggunaan biasa."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"hantar siaran bahawa pakej telah dialih keluar"</string>
@@ -356,6 +358,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi kaedah input itu. Tidak sekali-kali diperlukan untuk apl biasa."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"terikat kepada perkhidmatan yang boleh diakses"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi perkhidmatan yang boleh diakses. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"terikat kepada perkhidmatan cetakan"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi perkhidmatan cetakan. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"akses semua kerja cetakan"</string>
+    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Membenarkan pemegang mengakses kerja cetakan yang dibuat oleh apl lain. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"terikat kepada perkhidmatan NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Membenarkan pemegang untuk terikat kepada aplikasi yang mengikut kad NFC. Tidak sekali-kali diperlukan untuk apl normal."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"terikat kepada perkhidmatan teks"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Membenarkan pemegang mengikat kepada antara muka peringkat atasan perkhidmatan teks(mis. PerkhidmatanPenyemakEjaan). Tidak seharusnya diperlukan untuk apl biasa."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"terikat kepada perkhidmatan VPN"</string>
@@ -366,6 +374,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi perkhidmatan widget. Tidak sekali-kali diperlukan untuk apl biasa."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"berinteraksi dengan pentadbir peranti"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Membenarkan pemegang menghantar tujuan kepada pentadbir peranti. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"tambah atau alih keluar pentadbir peranti"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Membenarkan pemegang menambah atau mengalih keluar pentadbir peranti aktif. Tidak sekali-kali diperlukan untuk apl biasa."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"tukar orientasi skrin"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Membenarkan apl untuk menukar putaran skrin pada bila-bila masa. Tidak sekali-kali diperlukan untuk apl biasa."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"tukar kelajuan penuding"</string>
@@ -397,6 +407,10 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Membenarkan apl membaca daripada pelbagai fail log sistem. Hal ini membenarkannya menemui maklumat umum mengenai perkara yang anda lakukan dengan telefon, juga berpotensi menyertakan maklumat persendirian dan peribadi."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"gunakan mana-mana penyahkod media untuk main semula"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Membenarkan apl untuk menggunakan sebarang penyahkod media yang dipasangkan untuk menyahkod main semula."</string>
+    <!-- no translation found for permlab_manageCaCertificates (1678391896786882014) -->
+    <skip />
+    <!-- no translation found for permdesc_manageCaCertificates (4015644047196937014) -->
+    <skip />
     <string name="permlab_diagnostic" msgid="8076743953908000342">"baca/tulis ke sumber yang dimiliki oleh diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Membenarkan apl membaca dan menulis ke sebarang sumber yang dimiliki oleh kumpulan diag; contohnya, fail dalam /dev. Hal ini berpotensi menjejaskan kestabilan dan keselamatan sistem. Perkara ini seharusnya HANYA digunakan untuk diagnosis khusus perkakasan oleh pengilang atau pengendali."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"dayakan atau lumpuhkan komponen apl"</string>
@@ -458,10 +472,18 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Membenarkan apl menggunakan ciri peringkat rendah SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"baca penimbal bingkai"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Membenarkan apl membaca kandungan penimbal bingkai."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"akses InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Membenarkan apl menggunakan ciri peringkat rendah InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfigurasikan paparan Wifi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Membenarkan apl mengkonfigurasi dan menyambung ke paparan Wifi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"kawal paparan Wifi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Membenarkan apl mengawal ciri tahap rendah paparan Wifi."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"tangkap output audio"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Membenarkan apl menangkap dan mengubah hala output audio."</string>
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"tangkap output video"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Membenarkan apl menangkap dan mengubah hala output video."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"tangkap output video selamat"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Membenarkan apl menangkap dan mengubah hala output video selamat."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"tukar tetapan audio anda"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Membenarkan apl untuk mengubah suai tetapan audio global seperti kelantangan dan pembesar suara mana digunakan untuk output."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"rakam audio"</string>
@@ -613,6 +635,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Membenarkan apl menulis ke kad SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"ubh suai/pdm kdg strn mdia dlm"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Membenarkan apl mengubah suai kandungan storan media dalaman."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"urus storan dokumen"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Membenarkan apl mengurus storan dokumen."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"mengakses storan luaran untuk semua pengguna"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Membenarkan apl untuk mengakses storan luaran untuk semua pengguna."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"akses sistem fail cache"</string>
@@ -625,10 +649,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Membenarkan apl mengurus dasar rangkaian dan menentukan peraturan khusus apl."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"ubah suai perakaunan penggunaan rangkaian"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Membenarkan apl untuk mengubah suai bagaimana penggunaan rangkaian diambil kira terhadap apl. Bukan untuk digunakan oleh apl biasa."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"ubah tanda soket"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Membenarkan apl mengubah suai tanda soket untuk laluan"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"pemberitahuan akses"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Membenarkan apl untuk mendapatkan semula, memeriksa dan memadam bersih pemberitahuan, termasuk yang disiarkan oleh apl lain."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"ikat kepada perkhidmatan pendengar pemberitahuan"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi perkhidmatan pendengar pemberitahuan. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"gunakan apl konfigurasi yang disediakan oleh pembawa"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Membenarkan pemegang menggunakan apl konfigurasi yang diberikan oleh pembawa. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"dengar pemerhatian mengenai keadaan rangkaian"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Membenarkan aplikasi mendengar pemerhatian tentang keadaan rangkaian. Tidak sekali-kali diperlukan untuk apl biasa."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Tetapkan peraturan kata laluan"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Mengawal panjang dan aksara yang dibenarkan dalam kata laluan buka kunci skrin."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Memantau percubaan buka kunci skrin"</string>
@@ -738,8 +768,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +825,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Masukkan kad SIM."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Kad SIM tiada atau tidak boleh dibaca. Sila masukkan kad SIM."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Kad SIM tidak boleh digunakan."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Kad SIM anda telah dilumpuhkan secara kekal."\n" Hubungi pembekal perkhidmatan wayarles anda untuk mendapatkan kad SIM lain."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Kad SIM anda telah dilumpuhkan secara kekal.\n Hubungi pembekal perkhidmatan wayarles anda untuk mendapatkan kad SIM lain."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Butang lagu sebelumnya"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Butang lagu seterusnya"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Butang Jeda"</string>
@@ -808,11 +837,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Lihat Panduan Pengguna atau hubungi Penjagaan Pelanggan."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Kad SIM dikunci."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Membuka kunci kad SIM..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Anda telah tersilap melukis corak buka kunci anda sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. "\n\n"Sila cuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Anda telah tersilap taip menaip kata laluan anda sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. "\n\n"Cuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Anda telah tersilap taip PIN anda sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. "\n\n"Cuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Anda telah tersilap melukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci tablet anda menggunakan log masuk Google anda."\n\n" Cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Anda telah tersilap lukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci telefon anda menggunakan log masuk Google anda."\n\n" Sila cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Anda telah tersilap melukis corak buka kunci anda sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. \n\nSila cuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Anda telah tersilap taip menaip kata laluan anda sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Anda telah tersilap taip PIN anda sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Anda telah tersilap melukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci tablet anda menggunakan log masuk Google anda.\n\n Cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Anda telah tersilap lukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci telefon anda menggunakan log masuk Google anda.\n\n Sila cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Anda telah mencuba untuk membuka kunci tablet dengan salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, tablet akan ditetapkan semula kepada tetapan lalai kilang dan semua data pengguna akan hilang."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Anda telah mencuba untuk membuka kunci telefon dengan salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, telefon akan ditetapkan semula kepada tetapan lalai kilang dan semua data pengguna akan hilang."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Anda telah mencuba untuk membuka kunci tablet secara salah sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Tablet kini akan ditetapkan semula ke tetapan lalai kilang."</string>
@@ -826,7 +855,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Kata laluan"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Log masuk"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nama pengguna atau kata laluan tidak sah."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Lupa nama pengguna atau kata laluan anda?"\n"Lawati "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Lupa nama pengguna atau kata laluan anda?\nLawati "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Menyemak…"</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Buka kunci"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Bunyi dihidupkan"</string>
@@ -874,7 +903,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Sahkan Navigasi"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Tinggalkan Halaman ini"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Kekal di Halaman ini"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Adakah anda pasti anda mahu menavigasi keluar dari halaman ini?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nAdakah anda pasti anda mahu menavigasi keluar dari halaman ini?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Sahkan"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Petua: Ketik dua kali untuk mengezum masuk dan keluar."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Auto isi"</string>
@@ -1080,14 +1109,14 @@
     <string name="aerr_application" msgid="932628488013092776">"Malangnya, <xliff:g id="APPLICATION">%1$s</xliff:g> telah berhenti."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Malangnya, proses <xliff:g id="PROCESS">%1$s</xliff:g> telah berhenti."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> tidak bertindak balas."\n\n"Adakah anda mahu menutupnya?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Aktiviti <xliff:g id="ACTIVITY">%1$s</xliff:g> tidak bertindak balas. "\n\n" Adakah anda mahu menutupnya?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> tidak bertindak balas.\n\nAdakah anda mahu menutupnya?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Aktiviti <xliff:g id="ACTIVITY">%1$s</xliff:g> tidak bertindak balas. \n\n Adakah anda mahu menutupnya?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> tidak bertindak balas. Adakah anda mahu menutupnya?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Proses <xliff:g id="PROCESS">%1$s</xliff:g> tidak bertindak balas. "\n\n"Adakah anda mahu menutupnya?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Proses <xliff:g id="PROCESS">%1$s</xliff:g> tidak bertindak balas. \n\nAdakah anda mahu menutupnya?"</string>
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"Laporkan"</string>
     <string name="wait" msgid="7147118217226317732">"Tunggu"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"Laman ini tidak bertindak balas. "\n\n"Adakah anda mahu menutupnya?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Laman ini tidak bertindak balas. \n\nAdakah anda mahu menutupnya?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Apl diubah hala"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> kini sedang berjalan."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> pada asalnya telah dilancarkan."</string>
@@ -1256,6 +1285,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Membenarkan apl untuk menggunakan perkhidmatan bekas lalai untuk menyalin kandungan. Bukan untuk digunakan oleh apl biasa."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Buat laluan output media"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Membenarkan apl untuk membuat laluan output media ke peranti luaran lain."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Akses storan selamat pengawal kekunci"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Membenarkan aplikasi mengakses storan selamat pengawal kekunci."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Kawal paparkan dan sembunyikan pengawal kekunci"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Membenarkan aplikasi untuk mengawal pengawal kekunci."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Sentuh dua kali untuk mendapatkan kawalan zum"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Tidak dapat menambahkan widget."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Pergi"</string>
@@ -1265,15 +1298,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Selesai"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Sblm"</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Laksanakan"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Dail nombor"\n"menggunakan <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Wujudkan kenalan"\n"menggunakan <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Dail nombor\nmenggunakan <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Wujudkan kenalan\nmenggunakan <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Satu atau lebih apl berikut meminta kebenaran untuk mengakses akaun anda, sekarang dan pada masa hadapan."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Adakah anda mahu membenarkan permintaan ini?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Permintaan akses"</string>
     <string name="allow" msgid="7225948811296386551">"Benarkan"</string>
     <string name="deny" msgid="2081879885755434506">"Nafi"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Kebenaran diminta"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Kebenaran diminta"\n"untuk akaun <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Kebenaran diminta\nuntuk akaun <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Kaedah input"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Penyegerakan"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Kebolehaksesan"</string>
@@ -1441,10 +1474,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Menyambung..."</string>
     <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">"Skrin Terbina Dalam"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"Skrin HDMI"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Tindih #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", selamat"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Paparan wayarles disambungkan"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Skrin ini ditunjukkan pada peranti lain"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Putus sambungan"</string>
@@ -1453,7 +1488,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Corak Salah"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Kata Laluan Salah"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN salah"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Cuba lagi dalam <xliff:g id="NUMBER">%d</xliff:g> saat."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Cuba lagi dalam <xliff:g id="NUMBER">%1$d</xliff:g> saat."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Lukiskan corak anda"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Masukkan PIN SIM"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Masukkan PIN"</string>
@@ -1473,27 +1508,81 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Kata laluan"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Log masuk"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nama pengguna atau kata laluan tidak sah."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Lupa nama pengguna atau kata laluan anda?"\n"Lawati"<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Lupa nama pengguna atau kata laluan anda?\nLawati"<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Menyemak akaun…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Anda telah menaip PIN anda secara salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. "\n\n"Cuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Anda telah menaip kata laluan anda secara salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. "\n\n"Cuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Anda telah tersilap melukis corak buka kunci anda sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. "\n\n"Cuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Anda telah menaip PIN anda secara salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Anda telah menaip kata laluan anda secara salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Anda telah tersilap melukis corak buka kunci anda sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Anda telah mencuba untuk membuka kunci tablet dengan salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, tablet akan ditetapkan semula kepada tetapan lalai kilang dan semua data pengguna akan hilang."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Anda telah mencuba untuk membuka kunci telefon dengan salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, telefon akan ditetapkan semula kepada tetapan lalai kilang dan semua data pengguna akan hilang."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Anda telah mencuba untuk membuka kunci tablet secara salah sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Tablet kini akan ditetapkan semula ke tetapan lalai kilang."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Anda telah mencuba untuk membuka kunci telefon secara salah sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Telefon kini akan ditetapkan semula ke tetapan lalai kilang."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Anda telah tersilap melukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci tablet anda menggunakan log masuk Google anda."\n\n" Cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Anda telah tersilap lukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci telefon anda menggunakan log masuk Google anda."\n\n" Cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Anda telah tersilap melukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci tablet anda menggunakan log masuk Google anda.\n\n Cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Anda telah tersilap lukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci telefon anda menggunakan log masuk Google anda.\n\n Cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Alih keluar"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Tingkatkan kelantangan melebihi aras yang dicadangkan?"\n"Mendengar pada kelantangan tinggi untuk tempoh yang panjang boleh merosakkan pendengaran anda."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Tingkatkan kelantangan melebihi aras yang dicadangkan?\nMendengar pada kelantangan tinggi untuk tempoh yang panjang boleh merosakkan pendengaran anda."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Teruskan menahan dengan dua jari untuk mendayakan kebolehcapaian."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Kebolehcapaian didayakan."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Kebolehcapaian dibatalkan."</string>
     <string name="user_switched" msgid="3768006783166984410">"Pengguna semasa <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Pemilik"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Ralat"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Apl ini tidak menyokong akaun untuk profil yang disekat"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Apl ini tidak menyokong akaun untuk profil yang disekat"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Tidak menemui aplikasi untuk mengendalikan tindakan ini"</string>
     <string name="revoke" msgid="5404479185228271586">"Batalkan"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Surat"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Surat Kerajaan"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Undang-undang"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Undang-undang Junior"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Lejar"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Dibatalkan"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Ralat menulis kandungan"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Masukkan PIN"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN semasa"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"PIN baharu"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Sahkan PIN baharu"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Buat PIN untuk mengubah suai sekatan"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PIN tidak sepadan. Cuba lagi."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"PIN terlalu pendek. Mesti sekurang-kurangnya 4 angka."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="4835639969503729874">"PIN salah. Cuba lagi dalam masa 1 saat."</item>
+    <item quantity="other" msgid="8030607343223287654">"PIN salah. Cuba lagi dalam masa <xliff:g id="COUNT">%d</xliff:g> saat."</item>
+  </plurals>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Leret bhg tepi skrin utk serlah bar"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Leret dari tepi skrin untuk menampakkan bar sistem"</string>
 </resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 74d7702..625fb38 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -131,6 +131,11 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"For mange slettinger av <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Nettbrettlageret er fullt. Slett noen filer for å frigjøre lagringsplass."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Telefonlageret er fullt. Slett noen filer for å frigjøre lagringsplass."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Nettverket blir muligens overvåket"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Meg"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Innstillinger for nettbrettet"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Telefoninnstillinger"</string>
@@ -243,27 +248,27 @@
     <string name="permdesc_statusBarService" msgid="716113660795976060">"Gir appen tillatelse til å vises i statusfeltet."</string>
     <string name="permlab_expandStatusBar" msgid="1148198785937489264">"utvide/slå sammen statusfeltet"</string>
     <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"Lar appen utvide eller skjule statuslinjen."</string>
-    <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"omdirigerer utgående anrop"</string>
+    <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"omdirigere utgående anrop"</string>
     <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Lar appen behandle utgående anrop og endre nummeret som skal ringes opp. Denne tillatelsen lar appen overvåke, viderekoble eller hindre utgående anrop."</string>
-    <string name="permlab_receiveSms" msgid="8673471768947895082">"mottar tekstmeldinger (SMS)"</string>
+    <string name="permlab_receiveSms" msgid="8673471768947895082">"motta tekstmeldinger (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Lar appen motta og behandle tekstmeldinger. Dette betyr at appen kan overvåke eller slette meldinger som er sendt til enheten din uten at du har sett dem."</string>
-    <string name="permlab_receiveMms" msgid="1821317344668257098">"mottar tekstmeldinger (MMS)"</string>
+    <string name="permlab_receiveMms" msgid="1821317344668257098">"motta tekstmeldinger (MMS)"</string>
     <string name="permdesc_receiveMms" msgid="533019437263212260">"Lar appen motta og behandle multimediemeldinger. Dette betyr at appen kan overvåke eller slette meldinger som er sendt til enheten din uten at du har sett dem."</string>
     <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"motta nødkringkastinger"</string>
     <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Lar appen motta og behandle nødkringkastingsmeldinger. Denne tillatelsen er bare tilgjengelig for systemapper."</string>
-    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"lesing av kringkastede meldinger"</string>
+    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"lese kringkastede meldinger"</string>
     <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Tillater at appen kan lese kringkastede meldinger enheten din mottar. Kringkastede varsler leveres noen steder for å advare deg om nødsituasjoner. Skadelige apper kan forstyrre ytelsen eller funksjonen til enheten din når en kringkastet nødmelding mottas."</string>
     <string name="permlab_sendSms" msgid="5600830612147671529">"sende SMS-meldinger"</string>
     <string name="permdesc_sendSms" msgid="7094729298204937667">"Lar appen sende tekstmeldinger. Dette kan resultere i uventede kostnader. Merk at skadelige apper kan påføre deg kostnader ved å sende meldinger uten bekreftelse fra deg."</string>
     <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"send svar via melding-hendelser"</string>
     <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"Lar appen sende forespørsler om håndtering av svar via melding-hendelser for innkommende anrop til andre meldingsapper."</string>
-    <string name="permlab_readSms" msgid="8745086572213270480">"leser tekstmeldinger (SMS eller MMS)"</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"lese tekstmeldinger (SMS eller MMS)"</string>
     <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Lar appen lese tekstmeldinger lagret på nettbrettet eller SIM-kortet ditt. Dette lar appen lese alle tekstmeldingene dine, uavhengig av innhold og konfidensialitet."</string>
     <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Lar appen lese tekstmeldinger lagret på telefonen eller SIM-kortet ditt. Dette lar appen lese alle tekstmeldingene dine, uavhengig av innhold og konfidensialitet."</string>
     <string name="permlab_writeSms" msgid="3216950472636214774">"redigerer tekstmeldingene dine (SMS eller MMS)"</string>
     <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Lar appen skrive til SMS-meldinger som er lagret på nettbrettet eller SIM-kortet ditt. Ondsinnede apper kan komme til å slette meldingene dine."</string>
     <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Lar appen skrive til SMS-meldinger som er lagret på telefonen eller SIM-kortet ditt. Ondsinnede apper kan komme til å slette meldingene dine."</string>
-    <string name="permlab_receiveWapPush" msgid="5991398711936590410">"mottar tekstmeldinger (WAP)"</string>
+    <string name="permlab_receiveWapPush" msgid="5991398711936590410">"motta tekstmeldinger (WAP)"</string>
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Lar appen motta og behandle WAP-meldinger. Dette betyr at appen kan overvåke eller slette meldinger som er sendt til deg uten at du har sett dem."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"hente apper som kjører"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Lar appen hente informasjon om oppgaver som kjører og som nylig har kjørt. Dette kan tillate appen å oppdage informasjon om hvilke apper som brukes på enheten."</string>
@@ -279,17 +284,19 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Lar appen flytte oppgaver til forgrunnen eller bakgrunnen. Appen kan gjøre dette uten instruksjoner fra deg."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"avslutte apper som kjører"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Lar appen fjerne oppgaver og avslutte apper. Ondsinnede apper kan forstyrre atferden til andre apper."</string>
-    <string name="permlab_startAnyActivity" msgid="2918768238045206456">"igangsetting av aktiviteter"</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"administrering av aktivitetsstabler"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Gir appen tillatelse til å legge til, fjerne og endre aktivitetsstablene som andre apper kjøres i. Skadelige apper kan skape problemer i atferden til andre apper."</string>
+    <string name="permlab_startAnyActivity" msgid="2918768238045206456">"sette i gang aktiviteter"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Tillater at appen kan starte en aktivitet, uavhengig av tillatelsesbeskyttelse og eksportstatus."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"angi skjermkompatibilitet"</string>
     <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Lar appen kontrollere modus for skjermkompatibilitet i andre apper. Skadelige apper kan ødelegge funksjoner i andre apper."</string>
-    <string name="permlab_setDebugApp" msgid="3022107198686584052">"aktivere feilsøking av app"</string>
+    <string name="permlab_setDebugApp" msgid="3022107198686584052">"aktivere feilsøking av apper"</string>
     <string name="permdesc_setDebugApp" msgid="4474512416299013256">"Lar appen slå av feilsøking for andre apper. Ondsinnede apper kan bruke dette til å avslutte andre apper."</string>
     <string name="permlab_changeConfiguration" msgid="4162092185124234480">"endrer systemets skjerminnstillinger"</string>
     <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"Lar appen endre den nåværende konfigurasjonen, som for eksempel språk eller generell skriftstørrelse."</string>
-    <string name="permlab_enableCarMode" msgid="5684504058192921098">"aktiver bilmodus"</string>
+    <string name="permlab_enableCarMode" msgid="5684504058192921098">"aktivere bilmodus"</string>
     <string name="permdesc_enableCarMode" msgid="4853187425751419467">"Lar appen aktivere bilmodus."</string>
-    <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"lukker andre apper"</string>
+    <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"lukke andre apper"</string>
     <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"Lar appen avslutte andre appers bakgrunnsprosesser. Dette kan føre til at andre apper slutter å kjøre."</string>
     <string name="permlab_forceStopPackages" msgid="2329627428832067700">"tvinge andre apper til å stoppe"</string>
     <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"Lar appen tvinge andre apper til å stoppe."</string>
@@ -297,9 +304,9 @@
     <string name="permdesc_forceBack" msgid="3892295830419513623">"Lar appen tvinge alle aktiviteter som kjører i forgrunnen til å lukkes og flyttes til bakgrunnen. Skal aldri være nødvendig for vanlige apper."</string>
     <string name="permlab_dump" msgid="1681799862438954752">"hente intern systemtilstand"</string>
     <string name="permdesc_dump" msgid="1778299088692290329">"Lar appen hente ut informasjon om systemets indre tilstand. Ondsinnede apper kan hente et bredt spekter av privat og sikker informasjon som de vanligvis aldri burde ha behov for."</string>
-    <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"hent av skjerminnhold"</string>
+    <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"hente skjerminnhold"</string>
     <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Lar appen hente ut innholdet i det aktive vinduet. Ondsinnede apper kan hente ut hele vindusinnholdet og undersøke all teksten, med unntak av passord."</string>
-    <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"Aktiver tilgjengelighet midlertidig"</string>
+    <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"aktivere tilgjengelighet midlertidig"</string>
     <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"Lar en app midlertidig aktivere tilgjengelighet på enheten. Skadelige apper kan aktivere tilgjengelighet uten bekreftelse fra brukeren."</string>
     <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"hente vindusinformasjon"</string>
     <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Lar appen hente informasjon om vinduene fra vindusbehandleren. Skadelige apper kan hente informasjon som ikke er ment for intern systembruk."</string>
@@ -308,12 +315,12 @@
     <string name="permlab_magnify_display" msgid="5973626738170618775">"forstørre visningen"</string>
     <string name="permdesc_magnify_display" msgid="7121235684515003792">"Lar apper forstørre innholdet  på en skjerm. Skadelige apper kan endre skjerminnhold på en måte som gjør at enheten blir ubrukelig."</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"delvis avslutning"</string>
-    <string name="permdesc_shutdown" msgid="7046500838746291775">"Lar applikasjonen sette aktivitetshåndtereren i avslutningstilstand. Slår ikke systemet helt av."</string>
-    <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"forhindre applikasjonsbytte"</string>
+    <string name="permdesc_shutdown" msgid="7046500838746291775">"Lar appen sette aktivitetshåndtereren i avslutningstilstand. Slår ikke systemet helt av."</string>
+    <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"forhindre bytte mellom apper"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Hindrer brukeren i å bytte til en annen app."</string>
     <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"få informasjon om appen"</string>
     <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Tillater brukeren å få tilgang til privat informasjon om den aktuelle appen i forgrunnen på skjermen."</string>
-    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"avervåke og kontrollere all oppstart av apper"</string>
+    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"overvåke og kontrollere all oppstart av apper"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Lar appen overvåke og kontrollere hvordan systemet starter opp aktiviteter. Ondsinnede apper kan utsette hele systemet for sikkerhetsbrudd. Denne tillatelsen er bare nødvendig for utviklere, aldri for vanlig bruk."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"kringkaste melding om fjernet pakke"</string>
     <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"Lar appen kringkaste et varsel om at en app-pakke har blitt fjernet. Ondsinnede apper kan bruke dette til å avslutte alle andre apper som kjører."</string>
@@ -323,7 +330,7 @@
     <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"Lar appen kringkaste et varsel om at en WAP-PUSH-melding er mottatt. Ondsinnede apper kan bruke dette til å forfalske MMS-meldingskvitteringer, eller ubemerket erstatte innholdet av alle slags nettsider med ondsinnede varianter."</string>
     <string name="permlab_setProcessLimit" msgid="2451873664363662666">"begrense antallet kjørende prosesser"</string>
     <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"Lar appen kontrollere det maksimale antallet prosesser som kjører. Aldri nødvendig for vanlige apper."</string>
-    <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"tvinger bakgrunnsapper til å lukkes"</string>
+    <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"tvinge bakgrunnsapper til å lukkes"</string>
     <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"Lar appen kontrollere hvorvidt aktiviteter alltid er fullført så snart de flyttes til bakgrunnen. Aldri nødvendig for vanlige apper."</string>
     <string name="permlab_batteryStats" msgid="2789610673514103364">"lese batteristatistikk"</string>
     <string name="permdesc_batteryStats" msgid="5897346582882915114">"Lar apper lese gjeldende data på lavt nivå om batteribruk. Kan også la appen finne ut detaljert informasjon om hvilke apper du bruker."</string>
@@ -337,7 +344,7 @@
     <string name="permdesc_backup" msgid="6912230525140589891">"Lar appen kontrollere systemets mekanisme for sikkerhetskopiering og gjenoppretting. Ikke beregnet på vanlige apper."</string>
     <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"bekrefte en fullstendig sikkerhetskopi, eller gjenopprette driften"</string>
     <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"Lar appen starte det fullstendige grensesnittet for bekreftelse av sikkerhetskopiering. Skal ikke måtte brukes av noen apper."</string>
-    <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"vis uautoriserte vinduer"</string>
+    <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"vise uautoriserte vinduer"</string>
     <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"Lar appen opprette vinduer som er ment for å brukes av brukergrensesnittet til det interne systemet. Ikke beregnet på vanlige apper."</string>
     <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"overstyre andre apper"</string>
     <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"Lar appen være aktiv over andre apper eller deler av brukergrensesnittet. Dette kan virke inn på bruken din av grensesnittet i andre apper, eller endre det du tror du ser i andre apper."</string>
@@ -350,22 +357,30 @@
     <string name="permlab_injectEvents" msgid="1378746584023586600">"trykke taster og kontrolknapper"</string>
     <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"Lar appen levere sine egne inndatahendelser (tastetrykk osv.) til andre apper. Ondsinnede apper kan bruke dette til å ta over nettbrettet."</string>
     <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"Lar appen levere sine egne inndatahendelser (tastetrykk osv.) til andre apper. Ondsinnede apper kan bruke dette til å ta over telefonen."</string>
-    <string name="permlab_readInputState" msgid="469428900041249234">"ta opp hva som skrives og gjøres"</string>
+    <string name="permlab_readInputState" msgid="469428900041249234">"ta opp det du skriver og gjør"</string>
     <string name="permdesc_readInputState" msgid="8387754901688728043">"Lar appen se hvilke taster du trykker på, selv når du samhandler med en annen app (f.eks. skriver inn et passord). Skal aldri være nødvendig for vanlige apper."</string>
     <string name="permlab_bindInputMethod" msgid="3360064620230515776">"binde til en inndatametode"</string>
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Lar innehaveren binde det øverste nivået av grensesnittet til en inndatametode. Skal aldri være nødvendig for normale apper."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"binde seg til en tilgjengelighetstjeneste"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Gir innehaveren tillatelse til å bindes til det øverste nivået av grensesnittet for en tilgjengelighetstjeneste. Skal aldri være nødvendig for vanlige apper."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"binding til en utskriftstjeneste"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Gir innehaveren tillatelse til å binde til toppnivået av brukergrensesnittet for en utskriftstjeneste. Dette skal ikke være nødvendig for vanlige apper."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"binde til en utskriftskøtjeneste"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Gir innehaveren tillatelse til å binde til toppnivået av brukergrensesnittet for en utskriftskøtjeneste. Dette skal ikke være nødvendig for vanlige apper."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"binding til NFC-tjenesten"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Tillater eieren å binde seg til apper som emulerer NFC-kort. Skal aldri være nødvendig for vanlige apper."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"binde til en teksttjeneste"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Lar innehaveren binde seg til øverste grensesnittnivå for en teksttjeneste (f.eks. SpellCheckerService). Skal aldri være nødvendig for vanlige apper."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"binde deg til en VPN-tjeneste"</string>
     <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Lar innehaveren binde seg til det øverste nivået av grensesnittet for en VPN-tjeneste. Skal aldri være nødvendig for vanlige apper."</string>
-    <string name="permlab_bindWallpaper" msgid="8716400279937856462">"bind til bakgrunnsbilde"</string>
+    <string name="permlab_bindWallpaper" msgid="8716400279937856462">"binde til bakgrunnsbilde"</string>
     <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Lar innehaveren binde det øverste nivået av grensesnittet til en bakgrunn. Skal aldri være nødvendig for vanlige apper."</string>
-    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"bind til modultjenste"</string>
+    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"binde til modultjenste"</string>
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Lar innehaveren binde seg til det øverste nivået av grensesnittet for en modultjeneste. Skal aldri være nødvendig for vanlige apper."</string>
-    <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"kommuniser med enhetsadministrator"</string>
+    <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"kommunisere med enhetsadministrator"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Lar innehaveren sende hensikter til en enhetsadministrator. Skal aldri være nødvendig for normale apper."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"legge til eller fjerne en enhetsadministrator"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Tillater innehaveren å legge til eller fjerne aktive enhetsadministratorer. Dette skal aldri være nødvendig for vanlige apper."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"snu skjermen"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Gir appen tillatelse til når som helst å endre rotasjonen av skjermen. Skal aldri være nødvendig for vanlige apper."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"endre pekerhastighet"</string>
@@ -397,48 +412,50 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Lar appen lese fra diverse loggfiler på systemet. Disse inneholder generell informasjon om hva som gjøres med telefonen, og kan inneholde personlig eller privat informasjon."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"bruke en hvilken som helst mediedekoder for avspilling"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Lar appen bruke en hvilken som helst installert mediedekoder for å dekode for avspilling."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"administrer pålitelig legitimasjon"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Lar appen installere og avinstallere CA-sertifikater som pålitelig legitimasjon."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"lese/skrive ressurser eid av diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Lar appen lese og skrive til alle ressurser som eies av gruppen «diag», som for eksempel filer i /dev. Dette kan potensielt påvirke systemets sikkerhet og stabilitet. Dette bør BARE brukes av produsenten eller operatøren til maskinvarespesifikk diagnostikk."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"aktivere eller deaktivere appkomponenter"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Lar appen endre hvorvidt en komponent i en annen app er aktivert eller ikke. Ondsinnede apper kan bruke dette til å deaktivere viktige nettbrettfunksjoner. Denne tillatelsen må brukes med forsiktighet, ettersom det er mulig å få appkomponenter inn i en ubrukelig, inkonsistent eller ustabil tilstand."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Lar appen endre hvorvidt en komponent i en annen app er aktivert eller ikke. Ondsinnede apper kan bruke dette til å deaktivere viktige telefonfunksjoner. Denne tillatelsen må brukes med forsiktighet, ettersom det er mulig å få appkomponenter inn i en ubrukelig, inkonsistent eller ustabil tilstand."</string>
     <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"gi eller trekke tilbake tillatelser"</string>
-    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Lar programmer gi eller trekke tilbake spesielle tillatelser for eget bruk eller for andre programmer. Skadelige programmer kan bruke dette for å få tilgang til funksjoner de ikke skal ha tilgang til."</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Lar apper gi eller trekke tilbake spesielle tillatelser for eget bruk eller for andre apper. Skadelige apper kan bruke dette for å få tilgang til funksjoner de ikke skal ha tilgang til."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"angi foretrukne apper"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Lar appen endre de foretrukne appene dine. Ondsinnede apper kan ubemerket endre apper som kjøres, og forfalske eksisterende apper til å samle private data fra deg."</string>
-    <string name="permlab_writeSettings" msgid="2226195290955224730">"endrer systeminnstillingene"</string>
+    <string name="permlab_writeSettings" msgid="2226195290955224730">"endre systeminnstillingene"</string>
     <string name="permdesc_writeSettings" msgid="7775723441558907181">"Lar appen endre dataene i systeminnstillingene. Ondsinnede apper kan bruke dette til å skade systemkonfigurasjonen."</string>
     <string name="permlab_writeSecureSettings" msgid="204676251876718288">"endre sikre systeminnstillinger"</string>
     <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"Lar appen endre dataene for systemets sikre innstillinger. Ikke beregnet på vanlige apper."</string>
     <string name="permlab_writeGservices" msgid="2149426664226152185">"redigere Google-tjenestekartet"</string>
     <string name="permdesc_writeGservices" msgid="1287309437638380229">"Lar appen endre Google-tjenestekartet. Ikke beregnet på vanlige apper."</string>
-    <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"kjører fra oppstart"</string>
+    <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"kjøre ved oppstart"</string>
     <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Lar appen starte seg selv så snart systemet har startet opp. Dette kan føre til lengre oppstartstid for nettbrettet, i tillegg til at nettbrettet kan bli generelt tregere av at appen alltid kjører."</string>
     <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Lar appen starte seg selv så snart systemet har startet opp. Dette kan føre til lengre oppstartstid for telefonen, i tillegg til at telefonen kan bli generelt tregere av at appen alltid kjører."</string>
     <string name="permlab_broadcastSticky" msgid="7919126372606881614">"sende varige kringkastinger"</string>
     <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Lar appen sende faste kringkastinger («sticky broadcasts») som blir værende etter at kringkastingen er over. Overdreven bruk kan gjøre nettbrettet tregt eller ustabilt ved å bruke for mye minne."</string>
     <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Lar appen sende faste kringkastinger («sticky broadcasts») som blir værende etter at kringkastingen er over. Overdreven bruk kan gjøre telefonen treg eller ustabil ved å bruke for mye minne."</string>
-    <string name="permlab_readContacts" msgid="8348481131899886131">"leser kontaktene dine"</string>
+    <string name="permlab_readContacts" msgid="8348481131899886131">"lese kontaktene dine"</string>
     <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Lar appen lese informasjon om kontaktene lagret på nettbrettet ditt, inkludert hvor ofte du har ringt, sendt e-post til, eller på andre måter kommunisert med spesifikke personer. Denne tillatelsen lar apper lagre kontaktdata. Merk at skadelige apper kan dele disse dataene uten at du vet om det."</string>
     <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Lar appen lese informasjon om kontaktene lagret på telefonen din, inkludert hvor ofte du har ringt, sendt e-post til eller på andre måter kommunisert med spesifikke personer. Denne tillatelsen lar apper lagre kontaktdata. Merk at skadelige apper kan dele disse dataene uten at du vet om det."</string>
-    <string name="permlab_writeContacts" msgid="5107492086416793544">"endrer kontaktene dine"</string>
+    <string name="permlab_writeContacts" msgid="5107492086416793544">"endre kontaktene dine"</string>
     <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Lar appen endre informasjon om kontaktene lagret på nettbrettet ditt, inkludert hvor ofte du har ringt, sendt e-post til eller på andre måter kommunisert med bestemte kontakter. Denne tillatelsen lar apper slette kontaktdata."</string>
     <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Lar appen endre informasjon om kontaktene lagret på telefonen din, inkludert hvor ofte du har ringt, sendt e-post til eller på andre måter kommunisert med bestemte kontakter. Denne tillatelsen lar apper slette kontaktdata."</string>
-    <string name="permlab_readCallLog" msgid="3478133184624102739">"lar appen lese anropsloggen"</string>
+    <string name="permlab_readCallLog" msgid="3478133184624102739">"lese anropsloggen"</string>
     <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Lar appen lese samtaleloggen på nettbrettet ditt. Dette omfatter informasjon om innkommende og utgående anrop. Denne tillatelsen lar apper lagre all samtaleinformasjonen din. Merk at skadelige apper kan dele informasjonen uten at du har samtykket."</string>
     <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Lar appen lese samtaleloggen på telefonen din. Dette omfatter informasjon om innkommende og utgående anrop. Denne tillatelsen lar apper lagre all samtaleinformasjonen din. Merk at skadelige apper kan dele informasjonen uten at du har samtykket."</string>
-    <string name="permlab_writeCallLog" msgid="8552045664743499354">"lar appen endre samtaleloggen"</string>
+    <string name="permlab_writeCallLog" msgid="8552045664743499354">"endre anropsloggen"</string>
     <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Lar appen endre nettbrettets samtalelogg, inkludert data om innkommende og utgående anrop. Skadelige apper kan utnytte denne tillatelsen til å slette eller endre samtaleloggen din."</string>
     <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Lar appen endre telefonens samtalelogg, inkludert data om innkommende og utgående anrop. Skadelige apper kan utnytte denne tillatelsen til å slette eller endre samtaleloggen din."</string>
-    <string name="permlab_readProfile" msgid="4701889852612716678">"leser ditt eget kontaktkort"</string>
+    <string name="permlab_readProfile" msgid="4701889852612716678">"lese ditt eget kontaktkort"</string>
     <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Lar appen lese personlig profilinformasjon som er lagret på enheten, som for eksempel navn og kontaktinformasjon. Dette betyr at appen kan identifisere deg og sende profilinformasjonen din til andre."</string>
-    <string name="permlab_writeProfile" msgid="907793628777397643">"endrer ditt eget kontaktkort"</string>
+    <string name="permlab_writeProfile" msgid="907793628777397643">"endre ditt eget kontaktkort"</string>
     <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Lar appen endre eller legge til personlig profilinformasjon som er lagret på enheten din, som for eksempel navn og kontaktinformasjon. Dette betyr at appen kan identifisere deg og sende profilinformasjonen din til andre."</string>
     <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"lese din sosiale strøm"</string>
     <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Lar appen lese og synkronisere sosiale oppdateringer fra deg selv og vennene dine. Vær forsiktig når du deler informasjon - med denne tillatelsen kan appen lese kommunikasjon mellom deg og vennene dine på sosiale nettverk, uavhengig av konfidensialitet. Vær oppmerksom på at denne tillatelsen kanskje ikke gjelder for alle sosiale nettverk."</string>
     <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"skrive i din sosiale strøm"</string>
     <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Lar appen vise sosiale oppdateringer fra vennene dine. Vær forsiktig når du deler informasjon - med denne tillatelsen kan appen lage meldinger som ser ut som om de kommer fra en venn. Vær oppmerksom på at denne tillatelsen kanskje ikke gjelder på alle sosiale nettverk."</string>
-    <string name="permlab_readCalendar" msgid="5972727560257612398">"les kalenderhendelser og konfidensiell informasjon"</string>
+    <string name="permlab_readCalendar" msgid="5972727560257612398">"lese kalenderhendelser og konfidensiell informasjon"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Lar appen lese alle kalenderaktivitetene lagret på nettbrettet ditt, inkludert aktiviteter for venner eller kolleger. Dette kan gjøre at appen deler eller lagrer kalenderinformasjonen din uavhengig av konfidensialitet og sensitivitet."</string>
     <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Lar appen lese alle kalenderaktivitetene lagret på telefonen din, inkludert aktiviteter for venner eller kolleger. Dette kan gjøre at appen deler eller lagrer kalenderinformasjonen din uavhengig av konfidensialitet og sensitivitet."</string>
     <string name="permlab_writeCalendar" msgid="8438874755193825647">"legge til eller endre kalenderhendelser og sende e-post til gjester uten eiernes viten"</string>
@@ -446,7 +463,7 @@
     <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Lar appen legge til, fjerne og endre aktiviteter du kan redigere på telefonen din, inkludert aktiviteter for venner eller kolleger. Dette kan gjøre at appen sender meldinger som ser ut som om de kommer fra kalendereiere eller endre aktiviteter uten at eierne vet om det."</string>
     <string name="permlab_accessMockLocation" msgid="8688334974036823330">"lage simulerte posisjonskilder for testing"</string>
     <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Opprette fiktive posisjonskilder for testing eller installere en ny posisjonsangiver. Dette gjør at appen kan overstyre posisjonen eller statusen som rapporteres av ekte posisjonskilder, som for eksempel GPS eller posisjonsangivere."</string>
-    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"få tilgang til ekstra posisjonskommandoer"</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"bruke ekstra posisjonskommandoer"</string>
     <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"Lar appen få tilgang til flere kommandoer fra posisjonsangivere. Dette kan gjøre at appen forstyrrer GPS-funksjonen eller andre posisjonskilder."</string>
     <string name="permlab_installLocationProvider" msgid="6578101199825193873">"installere posisjonskilder"</string>
     <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"Opprette fiktive posisjonskilder for testing eller installere en ny posisjonsangiver. Dette gjør at appen kan overstyre posisjonen eller statusen som rapporteres av ekte posisjonskilder, som for eksempel GPS eller posisjonsangivere."</string>
@@ -454,14 +471,22 @@
     <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Lar appen se den nøyaktige posisjonen din ved hjelp av GPS (Global Positioning System) eller posisjonstjenester for nettverk, som for eksempel basestasjoner og Wi-Fi. Disse posisjonstjenestene må være slått på og tilgjengelig for enheten din, for at appen skal kunne bruke dem. Apper kan bruke dette til å fastslå hvor du er, og funksjonen kan medføre økt batteribruk."</string>
     <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"omtrentlig posisjon (nettverksbasert)"</string>
     <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Lar appen se den omtrentlige posisjonen din. Denne posisjonen hentes fra posisjonstjenester som benytter posisjonskilder som for eksempel basestasjoner og Wi-Fi. Disse posisjonstjenestene må være slått på og tilgjengelig for enheten din, for at appen skal kunne bruke dem. Apper kan bruke dette til å finne ut omtrent hvor du er."</string>
-    <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"få tilgang til SurfaceFlinger"</string>
+    <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"bruke SurfaceFlinger"</string>
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Lar appen bruke grunnleggende SurfaceFlinger-funksjoner."</string>
-    <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"lese skjermbufferet"</string>
+    <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"lese skjermbufferen"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Lar appen lese innholdet i rammebufferen."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfigurere Wi-Fi-skjermer"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Tillater appen å konfigurere og koble til Wi-Fi-skjermer."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"kontrollere Wi-Fi-skjermer"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Tillater appen å kontrollere lavnivåfunksjoner i Wi-Fi-skjermer."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"ta opp fra lydutdata"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Lar appen ta opp og omdirigere lydutdata."</string>
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Gjenkjennelse av kommandoord"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Gir appen tillatelse til å ta opp lyd for å gjenkjenne kommandoord. Opptaket kan skje i bakgrunnen, men forhindrer ikke lydopptak i andre funksjoner (f.eks. i videoopptak)."</string>
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"ta opp fra videoutdata"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Lar appen ta opp og omdirigere videoutdata."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"ta opp fra sikre videoutdata"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Lar appen ta opp og omdirigere sikre videoutdata."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"endre lydinnstillinger"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Lar appen endre globale lydinnstillinger slik som volum og hvilken høyttaler som brukes for lydavspilling."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"ta opp lyd"</string>
@@ -470,37 +495,37 @@
     <string name="permdesc_camera" msgid="8497216524735535009">"Lar appen ta bilder og filme med kameraet. Denne tillatelsen gjør at appen kan bruke kameraet når som helst uten bekreftelse fra deg."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"deaktiver LED-lyset for indikering av overføring når kameraet er i bruk"</string>
     <string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"Tillater at forhåndsinnstallerte systemapper deaktiverer LED-indikatoren for kamerabruk."</string>
-    <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"deaktiver nettbrett permanent"</string>
+    <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"deaktivere nettbrettet permanent"</string>
     <string name="permlab_brick" product="default" msgid="8337817093326370537">"deaktivere telefonen permanent"</string>
     <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"Lar appen deaktivere hele nettbrettet permanent. Dette er svært risikabelt."</string>
     <string name="permdesc_brick" product="default" msgid="5788903297627283099">"Lar appen deaktivere hele telefonen permanent. Dette er svært risikabelt."</string>
-    <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"tvungen omstart av nettbrettet"</string>
+    <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"tvinge omstart av nettbrettet"</string>
     <string name="permlab_reboot" product="default" msgid="2898560872462638242">"tvinge omstart av telefon"</string>
     <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"Lar appen fremtvinge omstart av nettbrettet."</string>
     <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"Lar appen fremtvinge omstart av telefonen."</string>
-    <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"får tilgang til filsystemet til USB-lagring"</string>
+    <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"bruke filsystemet for USB-lagring"</string>
     <string name="permlab_mount_unmount_filesystems" product="default" msgid="4402305049890953810">"får tilgang til filsystemet til SD-kort"</string>
     <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"Lar appen koble til og fra filsystemer for flyttbar lagring."</string>
-    <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"tømmer USB-lagring"</string>
-    <string name="permlab_mount_format_filesystems" product="default" msgid="262582698639274056">"tømmer SD-kort"</string>
+    <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"tømme USB-lagring"</string>
+    <string name="permlab_mount_format_filesystems" product="default" msgid="262582698639274056">"tømme SD-kort"</string>
     <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"Lar appen formatere flyttbare lagringsmedier."</string>
     <string name="permlab_asec_access" msgid="3411338632002193846">"få informasjon om intern lagring"</string>
     <string name="permdesc_asec_access" msgid="3094563844593878548">"Lar appen innhente informasjon om intern lagring."</string>
-    <string name="permlab_asec_create" msgid="6414757234789336327">"opprett intern lagring"</string>
+    <string name="permlab_asec_create" msgid="6414757234789336327">"opprette intern lagring"</string>
     <string name="permdesc_asec_create" msgid="4558869273585856876">"Lar appen opprette intern lagring."</string>
-    <string name="permlab_asec_destroy" msgid="526928328301618022">"slett intern lagring"</string>
+    <string name="permlab_asec_destroy" msgid="526928328301618022">"ødelegge intern lagring"</string>
     <string name="permdesc_asec_destroy" msgid="7218749286145526537">"Lar appen slette intern lagring."</string>
     <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"koble til eller fra intern lagring"</string>
     <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"Lar appen koble intern lagring til eller fra."</string>
     <string name="permlab_asec_rename" msgid="7496633954080472417">"gi nytt navn til intern lagring"</string>
     <string name="permdesc_asec_rename" msgid="1794757588472127675">"Lar appen gi nytt navn til intern lagring."</string>
-    <string name="permlab_vibrate" msgid="7696427026057705834">"kontrollerer vibrasjon"</string>
+    <string name="permlab_vibrate" msgid="7696427026057705834">"kontrollere vibreringen"</string>
     <string name="permdesc_vibrate" msgid="6284989245902300945">"Lar appen kontrollere vibreringsfunksjonen."</string>
     <string name="permlab_flashlight" msgid="2155920810121984215">"kontrollere lommelykten"</string>
     <string name="permdesc_flashlight" msgid="6522284794568368310">"Lar appen kontrollere lommelykten."</string>
     <string name="permlab_manageUsb" msgid="1113453430645402723">"administrere innstillinger og tillatelser for USB-enheter"</string>
     <string name="permdesc_manageUsb" msgid="7776155430218239833">"Lar appen administrere innstillinger og tillatelser for USB-enheter."</string>
-    <string name="permlab_accessMtp" msgid="4953468676795917042">"implementer MTP-protokoll"</string>
+    <string name="permlab_accessMtp" msgid="4953468676795917042">"implementere MTP-protokoll"</string>
     <string name="permdesc_accessMtp" msgid="6532961200486791570">"Tillater tilgang til kjerne-MTP-driver for implementering av MTP USB-protokollen."</string>
     <string name="permlab_hardware_test" msgid="4148290860400659146">"teste maskinvare"</string>
     <string name="permdesc_hardware_test" msgid="6597964191208016605">"Lar appen styre ulike eksterne enheter for å teste maskinvare."</string>
@@ -508,23 +533,26 @@
     <string name="permdesc_callPhone" msgid="3740797576113760827">"Lar appen ringe telefonnumre uten at du gjør noe. Dette kan resultere i uventede oppringninger og kostnader. Appen kan imidlertid ikke ringe nødnumre. Merk at skadelige apper kan påføre deg kostnader ved å ringe uten bekreftelse fra deg."</string>
     <string name="permlab_callPrivileged" msgid="4198349211108497879">"ringe vilkårlige telefonnummer direkte"</string>
     <string name="permdesc_callPrivileged" msgid="1689024901509996810">"Lar appen ringe alle slags telefonnumre, deriblant nødnumre, uten din innvirkning. Ondsinnede apper kan foreta unødvendige og ulovlige anrop til nødtjenestene."</string>
-    <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"start CDMA-nettbrettoppsett direkte"</string>
+    <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"starte CDMA-nettbrettoppsett direkte"</string>
     <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"begynne CDMA-telefonoppsett direkte"</string>
     <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"Lar appen starte CDMA-oppsett. Ondsinnede apper kan bruke dette til å starte CDMA-oppsett uten grunn."</string>
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"kontrollere varsling for plasseringsendring"</string>
     <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Lar appen aktivere og deaktivere varsler om posisjonsoppdatering fra radioen. Ikke beregnet på vanlige apper."</string>
-    <string name="permlab_checkinProperties" msgid="7855259461268734914">"få tilgang til egenskaper for innsjekking"</string>
+    <string name="permlab_checkinProperties" msgid="7855259461268734914">"bruke innsjekking"</string>
     <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Gir appen lese- og skrivetilgang til egenskaper som er lastet opp av innsjekkingstjenesten. Ikke beregnet på vanlige apper."</string>
-    <string name="permlab_bindGadget" msgid="776905339015863471">"velg gadgeter"</string>
+    <string name="permlab_bindGadget" msgid="776905339015863471">"velge moduler"</string>
     <string name="permdesc_bindGadget" msgid="8261326938599049290">"Lar appen fortelle systemet hvilke moduler som kan brukes av hvilke apper. En app som har denne tillatelsen kan gi andre apper tilgang til personlige data. Ikke beregnet på vanlige apper."</string>
     <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"endre telefontilstand"</string>
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Lar appen kontrollere telefonfunksjonene til enheten. En app som har denne tillatelsen kan bytte nettverk, slå telefonens radio på og av og lignende, uten å varsle deg i det hele tatt."</string>
-    <string name="permlab_readPhoneState" msgid="9178228524507610486">"leser telefonstatus og -identitet"</string>
+    <string name="permlab_readPhoneState" msgid="9178228524507610486">"lese telefonstatus og -identitet"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Lar appen bruke enhetens telefonfunksjoner. Med denne tillatelsen kan appen finne telefonnummer og enhets-ID-er, registrere om en samtale pågår, og se det eksterne nummeret det opprettes en forbindelse med via oppringing."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"hindre nettbrettet fra å gå over til sovemodus"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"forhindre telefonen fra å sove"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Lar appen hindre nettbrettet fra å gå over i sovemodus."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Lar appen hindre telefonen fra å gå over i sovemodus."</string>
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"infrarød overføring"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Gir appen tillatelse til å bruke nettbrettets infrarøde sender."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Gir appen tillatelse til å bruke telefonens infrarøde sender."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"slå på eller av nettbrettet"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"slå telefonen av eller på"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Lar appen slå på eller av nettbrettet."</string>
@@ -534,7 +562,7 @@
     <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"Kjøre som en lavnivås produsenttest, med full tilgang til telefonens maskinvare. Kun tilgjengelig når telefonen kjører i produsenttestmodus."</string>
     <string name="permlab_setWallpaper" msgid="6627192333373465143">"endre bakgrunnsbilde"</string>
     <string name="permdesc_setWallpaper" msgid="7373447920977624745">"Lar appen angi systembakgrunnen."</string>
-    <string name="permlab_setWallpaperHints" msgid="3278608165977736538">"endrer størrelsen på bakgrunnsbildet"</string>
+    <string name="permlab_setWallpaperHints" msgid="3278608165977736538">"endre størrelsen på bakgrunnsbildet"</string>
     <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Lar appen angi størrelsestips for systembakgrunnen."</string>
     <string name="permlab_masterClear" msgid="2315750423139697397">"tilbakestille systemet til fabrikkinnstillinger"</string>
     <string name="permdesc_masterClear" msgid="3665380492633910226">"Lar appen gjennomføre fullstendig tilbakestilling til fabrikkstandard, noe som sletter alle data, konfigurasjoner og installerte apper."</string>
@@ -559,7 +587,7 @@
     <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Lar appen se informasjon om nettverkstilkoblinger, slik som hvilke nettverk som finnes og er tilkoblet."</string>
     <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"full nettverkstilgang"</string>
     <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Lar appen opprette nettverkskontakter og bruke tilpassede nettverksprotokoller. Nettleseren og andre apper gjør det mulig å sende data til Internett, så denne tillatelsen er ikke nødvendig for å kunne sende data til Internett."</string>
-    <string name="permlab_writeApnSettings" msgid="505660159675751896">"endre eller avskjær nettverksinnstillinger og -trafikk"</string>
+    <string name="permlab_writeApnSettings" msgid="505660159675751896">"endre eller avskjære nettverksinnstillinger og -trafikk"</string>
     <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Lar appen endre nettverksinnstillinger og avbryte eller undersøke all nettverkstrafikk, for eksempel for å endre mellomtjener og port for alle navn på tilgangspunkt (APN). Ondsinnede apper kan overvåke, viderekoble eller endre nettverkspakker uten at du vet om det."</string>
     <string name="permlab_changeNetworkState" msgid="958884291454327309">"endre nettverkskonnektivitet"</string>
     <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Lar appen endre innstillingene for nettverkstilknytning."</string>
@@ -567,14 +595,14 @@
     <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Lar appen endre innstillingene for nettverkstilknytning via tethering."</string>
     <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"endre innstilling for bakgrunnsdata"</string>
     <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Lar appen endre innstillingene for bakgrunnsdatabruk."</string>
-    <string name="permlab_accessWifiState" msgid="5202012949247040011">"ser Wi-Fi-tilkoblinger"</string>
+    <string name="permlab_accessWifiState" msgid="5202012949247040011">"se Wi-Fi-tilkoblinger"</string>
     <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Lar appen se informasjon om Wi-Fi-nettverk, f.eks. hvorvidt Wi-Fi er aktivert og navn på tilkoblede Wi-Fi-enheter."</string>
-    <string name="permlab_changeWifiState" msgid="6550641188749128035">"kobler til og fra Wi-Fi"</string>
+    <string name="permlab_changeWifiState" msgid="6550641188749128035">"koble til og fra Wi-Fi"</string>
     <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Lar appen koble til og fra Wi-Fi-tilgangspunkter, og å gjøre endringer i enhetens konfigurasjon for Wi-Fi-nettverk."</string>
-    <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"tillat multicast for trådløse nettverk"</string>
+    <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"tillate multicast for trådløse nettverk"</string>
     <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Lar appen motta pakker som sendes til alle enhetene på et Wi-Fi-nettverk ved hjelp av multikastingsadresser,  Dette bruker mer strøm enn modusen uten multikasting."</string>
     <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Lar appen motta pakker som sendes til alle enhetene på et Wi-Fi-nettverk ved hjelp av multikastingsadresser,  Dette bruker mer strøm enn modusen uten multikasting."</string>
-    <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"endrer Bluetooth-innstillinger"</string>
+    <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"endre Bluetooth-innstillinger"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Lar appen konfigurere det lokale Bluetooth-nettbrettet, samt oppdage og koble sammen med eksterne enheter."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Lar appen konfigurere den lokale Bluetooth-telefonen, samt oppdage og koble sammen med eksterne enheter."</string>
     <string name="permlab_accessWimaxState" msgid="4195907010610205703">"koble til eller fra WiMAX"</string>
@@ -582,12 +610,12 @@
     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Endre WiMAX-status"</string>
     <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Lar appen koble nettbrettet til og fra WiMAX-nettverk."</string>
     <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"Lar appen koble telefonen til og fra WiMAX-nettverk."</string>
-    <string name="permlab_bluetooth" msgid="6127769336339276828">"kobler til Bluetooth-enheter"</string>
+    <string name="permlab_bluetooth" msgid="6127769336339276828">"koble til Bluetooth-enheter"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Lar appen se Bluetooth-konfigurasjonen på nettbrettet, samt opprette og godta tilkoblinger med sammenkoblede enheter."</string>
     <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Lar appen se Bluetooth-konfigurasjonen på telefonen, samt opprette og godta tilkoblinger med sammenkoblede enheter."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"kontroller overføring av data med NFC-teknologi"</string>
     <string name="permdesc_nfc" msgid="7120611819401789907">"Lar appen kommunisere med etiketter, kort og lesere som benytter NFC-teknologi."</string>
-    <string name="permlab_disableKeyguard" msgid="3598496301486439258">"deaktiverer skjermlåsen"</string>
+    <string name="permlab_disableKeyguard" msgid="3598496301486439258">"deaktivere skjermlåsen"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Lar appen deaktivere tastelåsen og eventuell tilknyttet passordsikkerhet. Et eksempel er at telefonen deaktiverer tastelåsen når du mottar et innkommende anrop, og deretter aktiverer tastelåsen igjen når samtalen er ferdig."</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"lese synkroniseringsinnstillinger"</string>
     <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Lar appen lese synkroniseringsinnstillingene for en konto. For eksempel kan den finne ut om Personer-appen er synkronisert med en konto."</string>
@@ -599,7 +627,7 @@
     <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Lar appen hente inn detaljer om strømmer som er synkroniserte for øyeblikket."</string>
     <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"endre abonnement på nyhetskilder"</string>
     <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"Lar appen endre strømmer som er synkronisert for øyeblikket. Ondsinnede apper kan endre de synkroniserte strømmene dine."</string>
-    <string name="permlab_readDictionary" msgid="4107101525746035718">"leser uttrykkene du har lagt til i ordboken"</string>
+    <string name="permlab_readDictionary" msgid="4107101525746035718">"lese ord du har lagt til i ordboken"</string>
     <string name="permdesc_readDictionary" msgid="659614600338904243">"Lar appen lese alle ord, navn og uttrykk som brukeren har lagret i brukerordlisten."</string>
     <string name="permlab_writeDictionary" msgid="2183110402314441106">"legge til ord i brukerdefinert ordliste"</string>
     <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Lar appen skrive nye ord i brukerordlisten."</string>
@@ -613,22 +641,30 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Lar appen skrive til SD-kortet."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"endre eller slette innhold på interne medier"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Lar appen endre innholdet i det interne lagringsmediet."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"administrere dokumentlagring"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Lar appen administrere dokumentlagring."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"åpne eksternlagring for alle brukere"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Tillater appen å åpne eksternlagring for alle brukere."</string>
-    <string name="permlab_cache_filesystem" msgid="5656487264819669824">"tilgang til bufrede filer"</string>
+    <string name="permlab_cache_filesystem" msgid="5656487264819669824">"bruke bufrede filer"</string>
     <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Lar appen lese og skrive til det bufrede filsystemet."</string>
     <string name="permlab_use_sip" msgid="5986952362795870502">"foreta/motta Internett-anrop"</string>
     <string name="permdesc_use_sip" msgid="4717632000062674294">"Lar appen bruke SIP-tjenesten til å foreta og motta Internett-anrop."</string>
-    <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"les tidligere nettverksbruk"</string>
+    <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"lese tidligere nettverksbruk"</string>
     <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"Lar appen lese tidligere nettverksbruk for bestemte nettverk og apper."</string>
     <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"administrer retningslinjene for nettverk"</string>
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Lar appen administrere retningslinjene for nettverket og definere appspesifikke regler."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"Modifisering av regnskapsføring av nettverksbruk"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Lar appen endre hvordan nettverksbruk regnes ut for apper. Ikke beregnet på vanlige apper."</string>
-    <string name="permlab_accessNotifications" msgid="7673416487873432268">"varseltilgang"</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"endring av kontaktmerker"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Gir appen tillatelse til å endre kontaktmerker for ruting"</string>
+    <string name="permlab_accessNotifications" msgid="7673416487873432268">"tilgang til varsler"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Lar appen hente, gjennomgå og fjerne varsler, inkludert de som sendes fra andre apper."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"binding til en varsellyttertjeneste"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Lar innehaveren binde seg til det øverste grensesnittnivået for en varsellyttertjeneste. Skal aldri være nødvendig for vanlige apper."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"starte konfigurasjonsappen som ble levert av operatøren"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Gir innehaveren tillatelse til å kalle opp den konfigurasjonsappen som ble levert av operatøren. Dette skal ikke være nødvendig for vanlige apper."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"lytte etter observasjoner om nettverksforhold"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Gir appen tillatelse til å lytte etter observasjoner om nettverksforhold. Dette skal ikke være nødvendig for vanlige apper."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Angi passordregler"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontroller tillatt lengde og tillatte tegn i passord for opplåsing av skjerm."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Overvåk forsøk på opplåsing av skjerm"</string>
@@ -738,8 +774,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"OQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +831,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Sett inn et SIM-kort."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM-kort mangler eller er uleselig. Sett inn et SIM-kort."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Ubrukelige SIM-kort."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"SIM-kortet er deaktivert permanent."\n"Ta kontakt med leverandøren av trådløstjenesten for å få et nytt SIM-kort."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"SIM-kortet er deaktivert permanent.\nTa kontakt med leverandøren av trådløstjenesten for å få et nytt SIM-kort."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Knapp for forrige sang"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Knapp for neste sang"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Pause-knappen"</string>
@@ -808,11 +843,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Les i brukerhåndboken eller kontakt brukerstøtten."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM-kortet er låst."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Låser opp SIM-kort…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Du har oppgitt feil opplåsingsmønster <xliff:g id="NUMBER_0">%d</xliff:g> ganger."\n\n"Prøv på nytt om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Du har skrevet inn feil passord <xliff:g id="NUMBER_0">%d</xliff:g> ganger."\n\n"Prøv på nytt om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Du har skrevet inn feil PIN-kode <xliff:g id="NUMBER_0">%d</xliff:g> ganger."\n\n"Prøv på nytt om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Du har tegnet inn feil opplåsingsmønster <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%d</xliff:g> mislykkede forsøk, blir du bedt om å låse opp nettbrettet ved hjelp av Google-påloggingsinformasjonen din."\n\n"Prøv på nytt om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Du har tegnet inn feil opplåsingsmønster <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%d</xliff:g> mislykkede forsøk, blir du bedt om å låse opp telefonen ved hjelp av Google-påloggingsinformasjonen din."\n\n"Prøv på nytt om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Du har oppgitt feil opplåsingsmønster <xliff:g id="NUMBER_0">%d</xliff:g> ganger.\n\nPrøv på nytt om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Du har skrevet inn feil passord <xliff:g id="NUMBER_0">%d</xliff:g> ganger.\n\nPrøv på nytt om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Du har skrevet inn feil PIN-kode <xliff:g id="NUMBER_0">%d</xliff:g> ganger.\n\nPrøv på nytt om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Du har tegnet inn feil opplåsingsmønster <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%d</xliff:g> mislykkede forsøk, blir du bedt om å låse opp nettbrettet ved hjelp av Google-påloggingsinformasjonen din.\n\nPrøv på nytt om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Du har tegnet inn feil opplåsingsmønster <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%d</xliff:g> mislykkede forsøk, blir du bedt om å låse opp telefonen ved hjelp av Google-påloggingsinformasjonen din.\n\nPrøv på nytt om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Du har foretatt <xliff:g id="NUMBER_0">%d</xliff:g> mislykkede opplåsinger av nettbrettet. Etter <xliff:g id="NUMBER_1">%d</xliff:g> flere mislykkede forsøk, blir nettbrettet tilbakestilt til fabrikkinnstillingene, og alle brukerdata går tapt."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Du har foretatt <xliff:g id="NUMBER_0">%d</xliff:g> mislykkede opplåsinger av telefonen. Etter <xliff:g id="NUMBER_1">%d</xliff:g> flere mislykkede forsøk, blir telefonen tilbakestilt til fabrikkinnstillingene, og alle brukerdata går tapt."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Du har foretatt <xliff:g id="NUMBER">%d</xliff:g> mislykkede opplåsinger av nettbrettet. Nettbrettet blir nå tilbakestilt til fabrikkinnstillingene."</string>
@@ -826,7 +861,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Passord"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Logg på"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Ugyldig brukernavn eller passord."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Har du glemt brukernavnet eller passordet ditt?"\n"Gå til "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Har du glemt brukernavnet eller passordet ditt?\nGå til "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Kontrollerer …"</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Lås opp"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Lyd på"</string>
@@ -874,7 +909,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Bekreft navigasjon"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Forlat denne siden"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Bli værende på denne siden"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Er du sikker på at du vil navigere bort fra denne siden?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nEr du sikker på at du vil navigere bort fra denne siden?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Bekreft"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Tips: Dobbelttrykk for å zoome inn og ut."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Autofyll"</string>
@@ -895,22 +930,22 @@
     <string name="autofill_parish" msgid="8202206105468820057">"Sogn"</string>
     <string name="autofill_area" msgid="3547409050889952423">"Område"</string>
     <string name="autofill_emirate" msgid="2893880978835698818">"Emirat"</string>
-    <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"leser nettbokmerkene og nettloggen din"</string>
+    <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"lese nettbokmerkene og nettloggen din"</string>
     <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Lar appen lese loggen for alle nettadressene nettleseren har besøkt, og alle bokmerkene i nettleseren. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string>
-    <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"skriver nettbokmerker og nettlogg"</string>
+    <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"skrive nettbokmerker og nettlogg"</string>
     <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Lar appen endre nettleserens logg eller bokmerker lagret på nettbrettet ditt. Dette kan føre til at appen sletter eller endrer nettleserdata. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string>
     <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Lar appen endre nettleserens logg eller bokmerker lagret på telefonen din. Dette kan føre til at appen sletter eller endrer nettleserdata. Vær oppmerksom på at denne tillatelsen kanskje ikke benyttes av tredjepartsnettlesere eller andre apper med mulighet for nettsurfing."</string>
-    <string name="permlab_setAlarm" msgid="1379294556362091814">"angir alarm"</string>
+    <string name="permlab_setAlarm" msgid="1379294556362091814">"stille alarm"</string>
     <string name="permdesc_setAlarm" msgid="316392039157473848">"Lar appen stille inn alarmen for en installert alarmklokke-app. Enkelte alarmklokke-apper implementerer kanskje ikke denne funksjonen."</string>
-    <string name="permlab_addVoicemail" msgid="5525660026090959044">"legg til talepost"</string>
+    <string name="permlab_addVoicemail" msgid="5525660026090959044">"legge til talepost"</string>
     <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Lar appen legge til meldinger i talepostkassen din."</string>
     <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"endre nettleserens tillatelser for geoposisjonering"</string>
     <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Lar appen endre nettleserens tillatelser for geoposisjonering. Ondsinnede apper kan bruke dette for å tillate sending av posisjonsinformasjon til vilkårlige nettsteder."</string>
-    <string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"bekreft pakker"</string>
+    <string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"bekrefte pakker"</string>
     <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"Lar appen bekrefte om en pakke kan installeres."</string>
     <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"bind til en pakkeverifikator"</string>
     <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Lar innehaveren sende forespørsler om pakkeverifikatorer. Skal aldri være nødvendig for normale apper."</string>
-    <string name="permlab_serialPort" msgid="546083327654631076">"tilgang til serielle porter"</string>
+    <string name="permlab_serialPort" msgid="546083327654631076">"bruke serieporter"</string>
     <string name="permdesc_serialPort" msgid="2991639985224598193">"Gir innehaveren tilgang til serielle porter ved hjelp av SerialManager API."</string>
     <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"gå til innholdsleverandører eksternt"</string>
     <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Lar innehaveren gå til innholdsleverandører fra kommandovinduet. Skal aldri være nødvendig for vanlige apper."</string>
@@ -1080,14 +1115,14 @@
     <string name="aerr_application" msgid="932628488013092776">"<xliff:g id="APPLICATION">%1$s</xliff:g> har dessverre stoppet."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Prosessen <xliff:g id="PROCESS">%1$s</xliff:g> har dessverre stoppet."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> svarer ikke."\n\n"Vil du lukke appen?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Aktiviteten <xliff:g id="ACTIVITY">%1$s</xliff:g> svarer ikke."\n\n"Vil du lukke den?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> svarer ikke.\n\nVil du lukke appen?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Aktiviteten <xliff:g id="ACTIVITY">%1$s</xliff:g> svarer ikke.\n\nVil du lukke den?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> svarer ikke. Vil du lukke appen?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Prosessen <xliff:g id="PROCESS">%1$s</xliff:g> svarer ikke."\n\n"Vil du lukke den?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Prosessen <xliff:g id="PROCESS">%1$s</xliff:g> svarer ikke.\n\nVil du lukke den?"</string>
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"Rapportér"</string>
     <string name="wait" msgid="7147118217226317732">"Vent"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"Siden svarer ikke."\n\n"Vil du lukke den?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Siden svarer ikke.\n\nVil du lukke den?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Appen er viderekoblet"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> kjører nå."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> ble opprinnelig startet."</string>
@@ -1250,12 +1285,16 @@
     <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"USB-lagring fjernet. Sett inn et nytt medium."</string>
     <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"Minnekortet ble fjernet. Sett inn et nytt."</string>
     <string name="activity_list_empty" msgid="1675388330786841066">"Finner ingen samsvarende aktiviteter."</string>
-    <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"oppdater statistikk over komponentbruk"</string>
+    <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"oppdatere statistikk over komponentbruk"</string>
     <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"Lar appen endre innsamlet bruksstatistikk om komponenter. Ikke beregnet på vanlige apper."</string>
-    <string name="permlab_copyProtectedData" msgid="4341036311211406692">"kopiére innhold"</string>
+    <string name="permlab_copyProtectedData" msgid="4341036311211406692">"kopiere innhold"</string>
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Lar appen påkalle standard meldingsbeholdertjeneste for kopiering av innhold. Ikke beregnet på vanlige apper."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Videresending av medieutdata"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Lar en app videresende medieutdata til andre eksterne enheter."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Bruk av sikker lagring via keyguard."</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Lar en app bruke sikker lagring via keyguard."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Kontrollér om tastelåsen er skjult eller vist"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Tillater at en app kontrollerer tastelåsen."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Trykk to ganger for zoomkontroll"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Kunne ikke legge til modulen."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Utfør"</string>
@@ -1265,15 +1304,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Utført"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Forrige"</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Utfør"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Ring nummeret"\n"<xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Lag kontakt"\n"med nummeret <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Ring nummeret\n<xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Lag kontakt\nmed nummeret <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Følgende app(er) ber om tilgang til kontoen din fra nå av."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Vil du tillate dette?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Tilgangsforespørsel"</string>
     <string name="allow" msgid="7225948811296386551">"Tillat"</string>
     <string name="deny" msgid="2081879885755434506">"Avslå"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Tillatelse forespurt"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Tillatelse forespurt"\n"for kontoen <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Tillatelse forespurt\nfor kontoen <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Inndatametode"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Synkronisering"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Tilgjengelighet"</string>
@@ -1420,7 +1459,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Se alle"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Velg aktivitet"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Deling med"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Enheten er låst."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Sender …"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Vil du starte nettleseren?"</string>
@@ -1441,10 +1479,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Kobler til ..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Tilgjengelig"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"Ikke tilgjengelig"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"I bruk"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Innebygd skjerm"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"HDMI-skjerm"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlegg #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", sikker"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Trådløs skjermdeling er tilkoblet"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Denne skjermen vises på en annen enhet"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Koble fra"</string>
@@ -1453,7 +1493,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Feil mønster"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Feil passord"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"Feil PIN-kode"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Prøv på nytt om <xliff:g id="NUMBER">%d</xliff:g> sekunder."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Prøv på nytt om <xliff:g id="NUMBER">%1$d</xliff:g> sekunder."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Tegn mønsteret ditt"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Skriv inn PIN-koden for SIM-kortet"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Skriv inn PIN-koden"</string>
@@ -1473,27 +1513,85 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Passord"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Logg på"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Ugyldig brukernavn eller passord."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Har du glemt brukernavnet eller passordet?"\n"Gå til "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Har du glemt brukernavnet eller passordet?\nGå til "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Sjekker kontoen ..."</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Du har oppgitt feil PIN-kode <xliff:g id="NUMBER_0">%d</xliff:g> ganger. "\n\n"Prøv på nytt om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Du har tastet inn passordet ditt feil <xliff:g id="NUMBER_0">%d</xliff:g> ganger. "\n\n"Prøv på nytt om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Du har tegnet opplåsningsmønsteret ditt feil <xliff:g id="NUMBER_0">%d</xliff:g> ganger. "\n\n"Prøv på nytt om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Du har oppgitt feil PIN-kode <xliff:g id="NUMBER_0">%d</xliff:g> ganger. \n\nPrøv på nytt om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Du har tastet inn passordet ditt feil <xliff:g id="NUMBER_0">%d</xliff:g> ganger. \n\nPrøv på nytt om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Du har tegnet opplåsningsmønsteret ditt feil <xliff:g id="NUMBER_0">%d</xliff:g> ganger. \n\nPrøv på nytt om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Du har oppgitt feil opplåsningspassord for nettbrettet <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%d</xliff:g> gale forsøk, tilbakestilles nettbrettet til fabrikkstandard og all data går tapt."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Du har oppgitt feil opplåsningspassord for telefonen <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%d</xliff:g> gale forsøk, tilbakestilles telefonen til fabrikkstandard og all data går tapt."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Du har oppgitt feil opplåsningspassord for nettbrettet <xliff:g id="NUMBER">%d</xliff:g> ganger. Telefonen tilbakestilles nå til fabrikkstandard."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Du har oppgitt feil opplåsningspassord for telefonen <xliff:g id="NUMBER">%d</xliff:g> ganger. Telefonen tilbakestilles nå til fabrikkstandard."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Du har tegnet opplåsningsmønsteret feil <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%d</xliff:g> gale forsøk, blir du bedt om å låse opp nettbrettet via en e-postkonto."\n\n" Prøv på nytt om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Du har tegnet opplåsningsmønsteret feil <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%d</xliff:g> gale forsøk, blir du bedt om å låse opp telefonen via en e-postkonto."\n\n" Prøv på nytt om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Du har tegnet opplåsningsmønsteret feil <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%d</xliff:g> gale forsøk, blir du bedt om å låse opp nettbrettet via en e-postkonto.\n\n Prøv på nytt om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Du har tegnet opplåsningsmønsteret feil <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%d</xliff:g> gale forsøk, blir du bedt om å låse opp telefonen via en e-postkonto.\n\n Prøv på nytt om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Fjern"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Vil du øke lydnivået over det anbefalte nivået?"\n"Et høyt lydnivå i lengre perioder kan skade hørselen din."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Vil du øke lydnivået over det anbefalte nivået?\nEt høyt lydnivå i lengre perioder kan skade hørselen din."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Fortsett å holde nede to fingre for å aktivere tilgjengelighet."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Tilgjengelighet er aktivert."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Tilgjengelighetstjenesten ble avbrutt."</string>
     <string name="user_switched" msgid="3768006783166984410">"Gjeldende bruker: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Eier"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Feil"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Denne appen støtter ikke kontoer for begrensede profiler"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Denne appen støtter ikke kontoer for begrensede profiler"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Finner ingen apper som kan utføre denne handlingen"</string>
     <string name="revoke" msgid="5404479185228271586">"Opphev"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Kansellert"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Feil under skriving av innhold"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"ukjent"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Skriv inn administrator-PIN-koden"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Skriv inn PIN-koden"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Feil"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Gjeldende PIN-kode:"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Ny PIN-kode"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Bekreft ny PIN-kode"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Angi en PIN-kode for endring av begrensninger"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PIN-kodene stemmer ikke overens. Prøv på nytt."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"PIN-koden er for kort. Den må bestå av minst fire sifre."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Prøv på nytt om 1 sekund"</item>
+    <item quantity="other" msgid="4730868920742952817">"Prøv på nytt om <xliff:g id="COUNT">%d</xliff:g> sekunder"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Prøv på nytt senere"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Sveip på kanten av skjermen for å få frem feltet"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Sveip fra kanten på skjermen for å få frem systemfeltet"</string>
 </resources>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
new file mode 100644
index 0000000..20ab30e
--- /dev/null
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -0,0 +1,1589 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<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="5973789783504771878">"KB"</string>
+    <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
+    <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
+    <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
+    <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
+    <string name="untitled" msgid="4638956954852782576">"&lt;बिना शीर्षक&gt;"</string>
+    <string name="ellipsis" msgid="7899829516048813237">"…"</string>
+    <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
+    <string name="emptyPhoneNumber" msgid="7694063042079676517">"(कुनै फोन नम्बर छैन)"</string>
+    <string name="unknownName" msgid="2277556546742746522">"(अज्ञात)"</string>
+    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"भ्वाइस मेल"</string>
+    <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN१"</string>
+    <string name="mmiError" msgid="5154499457739052907">"जडान समस्या वा अमान्य MMI कोड।"</string>
+    <string name="mmiFdnError" msgid="5224398216385316471">"अपरेशन निश्चित डायल नम्बरहरूको लागि मात्र प्रतिबन्धित छ।"</string>
+    <string name="serviceEnabled" msgid="8147278346414714315">"सेवा सक्षम पारियो।"</string>
+    <string name="serviceEnabledFor" msgid="6856228140453471041">"निम्न उल्लेखितको लागि सेवा सक्षम पारियो:"</string>
+    <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="mmiComplete" msgid="8232527495411698359">"MMI पुरा भयो।"</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 टाइप गर्नुहोस्।"</string>
+    <string name="invalidPuk" msgid="8761456210898036513">"८ वटा नम्बरहरू वा सो भन्दा लामो एउटा PUK टाइप गर्नुहोस्।"</string>
+    <string name="needPuk" msgid="919668385956251611">"तपाईंको SIM कार्ड PUK-लक छ। यसलाई अनलक गर्न PUK कोड टाइप गर्नुहोस्।"</string>
+    <string name="needPuk2" msgid="4526033371987193070">"SIM कार्ड अनलक गर्न PUK2 टाइप गर्नुहोस्।"</string>
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
+    <string name="ClipMmi" msgid="6952821216480289285">"आगमन कलर ID"</string>
+    <string name="ClirMmi" msgid="7784673673446833091">"बाहिरिने कलर ID"</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">"PIN परिवर्तन"</string>
+    <string name="CnipMmi" msgid="3110534680557857162">"प्रस्तुत नम्बरमा कल गर्दै"</string>
+    <string name="CnirMmi" msgid="3062102121430548731">"कल गर्ने अंक रोकेको छ।"</string>
+    <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="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="RestrictedChangedTitle" msgid="5592189398956187498">"प्रतिबन्धित पहुँच परिवर्तन भएको छ"</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="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">"Async"</string>
+    <string name="serviceClassDataSync" msgid="7530000519646054776">"सिङ्क गर्नुहोस्"</string>
+    <string name="serviceClassPacket" msgid="6991006557993423453">"प्याकेट"</string>
+    <string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
+    <string name="roamingText0" msgid="7170335472198694945">"रोमिङ सूचक खुला"</string>
+    <string name="roamingText1" msgid="5314861519752538922">"रोमिङ सूचक बन्द"</string>
+    <string name="roamingText2" msgid="8969929049081268115">"रोमिङ सूचक फ्ल्यास गर्दै"</string>
+    <string name="roamingText3" msgid="5148255027043943317">"छिमेकबाट बाहिर"</string>
+    <string name="roamingText4" msgid="8808456682550796530">"बिल्डिङको बाहिर"</string>
+    <string name="roamingText5" msgid="7604063252850354350">"रोमिङ - उपयुक्त प्रणाली"</string>
+    <string name="roamingText6" msgid="2059440825782871513">"रोमिङ - उपलब्ध प्रणाली"</string>
+    <string name="roamingText7" msgid="7112078724097233605">"रोमिङ - एलियन्सर पार्टनर"</string>
+    <string name="roamingText8" msgid="5989569778604089291">"रोमिङ - प्रिमियम पार्टनर"</string>
+    <string name="roamingText9" msgid="7969296811355152491">"रोमिङ - पूर्ण सेवा कार्यक्षमता अवस्था"</string>
+    <string name="roamingText10" msgid="3992906999815316417">"रोमिङ - आङ्शिक सेवा प्रकार्यता"</string>
+    <string name="roamingText11" msgid="4154476854426920970">"रोमिङ ध्वजा चालु छ"</string>
+    <string name="roamingText12" msgid="1189071119992726320">"रोमिङ ब्यानर बन्द छ"</string>
+    <string name="roamingTextSearching" msgid="8360141885972279963">"सेवाको खोजी गर्दै…"</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="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="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="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="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="default" msgid="3475999286680000541">"फोन भण्डारण भरिएको छ! ठाउँ खाली गर्नको लागि केही फाइलहरू मेटाउनुहोस्।"</string>
+    <string name="me" msgid="6545696007631404292">"मलाई"</string>
+    <string name="power_dialog" product="tablet" msgid="8545351420865202853">"ट्याब्लेट विकल्पहरू"</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="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="shutdown_progress" msgid="2281079257329981203">"बन्द गर्दै..."</string>
+    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"तपाईँको ट्याब्लेट बन्द हुने छ।"</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="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_bug_report" msgid="7934010578922304799">"बग रिपोर्ट"</string>
+    <string name="bugreport_title" msgid="2667494803742548533">"बग रिपोर्ट लिनुहोस्"</string>
+    <string name="bugreport_message" msgid="398447048750350456">"एउटा इमेल सन्देशको रूपमा पठाउनलाई यसले तपाईँको हालैको उपकरणको अवस्थाको बारेमा सूचना जम्मा गर्ने छ। बग रिपोर्ट सुरु गरेदेखि पठाउन तयार नभएसम्म यसले केही समय लिन्छ; कृपया धैर्य गर्नुहोस्।"</string>
+    <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_airplane_mode_on_status" msgid="2719557982608919750">"हवाइजहाज मोड खुला छ"</string>
+    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"हवाइजहाज मोड बन्द छ"</string>
+    <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"९९९+"</string>
+    <string name="safeMode" msgid="2788228061547930246">"सुरक्षित मोड"</string>
+    <string name="android_system_label" msgid="6577375335728551336">"एन्ड्रोइड प्रणाली"</string>
+    <string name="permgrouplab_costMoney" msgid="5429808217861460401">"तपाईँले तिर्नु पर्ने सेवाहरू"</string>
+    <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"तपाईँलाई महँगो पर्न सक्ने कामहरू गर्नुहोस्।"</string>
+    <string name="permgrouplab_messages" msgid="7521249148445456662">"तपाईंका सन्देशहरू"</string>
+    <string name="permgroupdesc_messages" msgid="7821999071003699236">"तपाईँका SMS, इमेल र अन्य सन्देशहरू पढ्नुहोस् र लेख्नुहोस्।"</string>
+    <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"तपाईँको निजी सूचना"</string>
+    <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"तपाईँको सम्पर्क कार्डमा भण्डारण भएका तपाईँको बारेको जानकारीमा सिधा पहुँच पुर्‍याउनुहोस्।"</string>
+    <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"तपाईँको सामाजिक सूचना"</string>
+    <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"तपाईँको सम्पर्कहरू र सामाजिक जडानहरूको बारेको जानकारीमा सिधा पहुँच पुर्‍याउनुहोस्।"</string>
+    <string name="permgrouplab_location" msgid="635149742436692049">"तपाईँको स्थान"</string>
+    <string name="permgroupdesc_location" msgid="5704679763124170100">"तपाईँको भौतिक स्थान निरीक्षण गर्नुहोस्।"</string>
+    <string name="permgrouplab_network" msgid="5808983377727109831">"नेटवर्क संचार"</string>
+    <string name="permgroupdesc_network" msgid="4478299413241861987">"विभिन्न नेटवर्क सुविधाहरूमा पहुँच राख्नुहोस्।"</string>
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"ब्लुटुथ"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"ब्लुटुथको माध्यमद्वारा उपकरणहरू र नेटवर्कहरूमाथि पहुँच राख्नुहोस्।"</string>
+    <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"अडियो सेटिङहरू"</string>
+    <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"अडियो सेटिङहरू बदल्नुहोस्।"</string>
+    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"ब्यट्रिलाई प्रभाव पार्छ"</string>
+    <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"छिट्टै ब्याट्रि सकाउन सक्ने ती विशेषताहरू प्रयोग गर्नुहोस्।"</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"पात्रो"</string>
+    <string name="permgroupdesc_calendar" msgid="5777534316982184416">"पात्रो तथा घटनाहरूमा प्रत्यक्ष पहुँच"</string>
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"प्रयोगकर्ता शब्दकोश पढ्नुहोस्"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"प्रयोगकर्ता शब्दकोशमा शब्दहरू पढ्नुहोस्।"</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"प्रयोगकर्ता शब्दकोश लेख्नुहोस्"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"प्रयोगकर्ता शब्दकोशमा शब्दहरू थप्नुहोस्।"</string>
+    <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"बुकमार्कहरू र इतिहास"</string>
+    <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"बुकमार्कहरू र ब्राउजर इतिहासमा सिधा पहुँच।"</string>
+    <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"अलार्म"</string>
+    <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"अलार्म घडी सेट गर्नुहोस्।"</string>
+    <string name="permgrouplab_voicemail" msgid="4162237145027592133">"भ्वाइस मेल"</string>
+    <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"भ्वाइसमेलमा सिधा पहुँच।"</string>
+    <string name="permgrouplab_microphone" msgid="171539900250043464">"माइक्रोफोन"</string>
+    <string name="permgroupdesc_microphone" msgid="7106618286905738408">"मा[क्रोफोनबाट रेकर्ड अडियोमा सिधा पहुँच पुर्‍याउनुहोस्।"</string>
+    <string name="permgrouplab_camera" msgid="4820372495894586615">"क्यामेरा"</string>
+    <string name="permgroupdesc_camera" msgid="2933667372289567714">"तस्बिर वा भिडियो क्याप्चरको लागि क्यामेरामा सिधा पहुँच।"</string>
+    <string name="permgrouplab_screenlock" msgid="8275500173330718168">"स्क्रिन लक गर्नुहोस्"</string>
+    <string name="permgroupdesc_screenlock" msgid="7067497128925499401">"तपाईँको उपकरणमा लक स्क्रिनको व्यवहारलाई प्रभावित गर्ने क्षमता।"</string>
+    <string name="permgrouplab_appInfo" msgid="8028789762634147725">"तपाईँका अनुप्रयोगहरूको सूचना"</string>
+    <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"तपाईँको उपकरणमा अन्य अनुप्रयोगहरूको व्यवहारमा प्रभाव पार्ने क्षमता।"</string>
+    <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"वालपेपर"</string>
+    <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"उपकरण वालपेपर सेटिङहरू बदल्नुहोस्।"</string>
+    <string name="permgrouplab_systemClock" msgid="406535759236612992">"घडी"</string>
+    <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"उपकरण समय वा समय क्षेत्र परिवर्तन गर्नुहोस्।"</string>
+    <string name="permgrouplab_statusBar" msgid="2095862568113945398">"स्थिति पट्टी"</string>
+    <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"उपकरण स्थिति सेटिङहरू परिवर्तन गर्नुहोस्।"</string>
+    <string name="permgrouplab_syncSettings" msgid="3341990986147826541">"सिङ्क सेटिङहरू"</string>
+    <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"सिङ्क सेटिङहरूमा पहुँच गर्नुहोस्।"</string>
+    <string name="permgrouplab_accounts" msgid="3359646291125325519">"तपाईँका खाताहरू"</string>
+    <string name="permgroupdesc_accounts" msgid="4948732641827091312">"उपलब्ध खाताहरू पहुँच गर्नुहोस्।"</string>
+    <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"हार्डवेयर नियन्त्रणहरू"</string>
+    <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"ह्यान्डसेटको हार्डवेयरमा प्रत्यक्ष पहुँच।"</string>
+    <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"फोन कलहरू"</string>
+    <string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"अनुगमन, रेकर्ड र फोन कलहरूको प्रसोधन गर्नुहोस।"</string>
+    <string name="permgrouplab_systemTools" msgid="4652191644082714048">"प्रणाली औजारहरू"</string>
+    <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"निम्न-स्तर पहुँच र प्रणालीको नियन्त्रण"</string>
+    <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"विकसित टुलहरू"</string>
+    <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"अनुप्रयोग विकासकर्ताहरूको लागि मात्र सुविधाहरूको आवश्यकता।"</string>
+    <string name="permgrouplab_display" msgid="4279909676036402636">"अन्य अनुप्रयोग UI"</string>
+    <string name="permgroupdesc_display" msgid="6051002031933013714">"अन्य अनुप्रयोगहरूको UI लाई असर पार्नुहोस्"</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"भण्डारण"</string>
+    <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"USB भण्डारणमाथि पहुँच गर्नुहोस्।"</string>
+    <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"SD कार्डमाथि पहुँच गर्नुहोस्।"</string>
+    <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"पहुँचीकरण विशेषताहरू"</string>
+    <string name="permgroupdesc_accessibilityFeatures" msgid="4205196881678144335">"सहयोगी प्रविधि भएको विशेषताहरूले अनुरोध गर्न सक्छन्।"</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="5800552516779249356">"छोइएका आइटमहरू चर्को स्वरमा बोलिने छ र स्क्रिन इशाराहरूको प्रयोगले अन्वेषण गर्न सकिन्छ।"</string>
+    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"उच्च वेब पहुँचलाई सुचारु गर्नुहोस्"</string>
+    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"अनुप्रयोगको सामग्रीलाई थप पहुँचयोग्य बनाउन लिपिहरू स्थापना गर्न सक्नु हुन्छ।"</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"आफुले टाइप गरेको पाठको निरीक्षण गर्नुहोस्"</string>
+    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"व्यक्तिगत डेटा जस्तै क्रेडिट कार्ड नम्बरहरू र पासवर्डहरू समावेश गर्दछ।"</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"स्थिति पट्टिलाई अक्षम वा संशोधित गर्नुहोस्"</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"स्थिति पट्टि असक्षम पार्न वा प्रणाली आइकनहरू थप्न र हटाउन अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_statusBarService" msgid="7247281911387931485">"स्थिति पट्टि"</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_processOutgoingCalls" msgid="3906007831192990946">"बहिर्गमन कलहरूलाई अर्को मार्ग दिनुहोस्"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"बहिर्गमन कलहरूको प्रशोधन गर्न र डायल गरिने नम्बर परिवर्तन गर्न अनुप्रयोगलाई अनुमति दिन्छ।  यो अनुमतिले अनुप्रयोगलाई मोनिटर गर्न, अन्यत्र पठाउन वा बाहिर जाने कलहरूलाई रोक्न दिन्छ।"</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_receiveEmergencyBroadcast" msgid="1803477660846288089">"आकस्मिक प्रसारणहरू प्राप्त गर्नुहोस्"</string>
+    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"अनुप्रयोगलाई आपतकालीन प्रसारण सन्देशहरू प्राप्त गर्न र प्रक्रिया गर्न अनुमति दिन्छ। यो अनुमति प्रणाली अनुप्रयोगहरूमा मात्र उपलब्ध छ।"</string>
+    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"सेल प्रसारित सन्देशहरू पढ्नुहोस्"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"तपाईंको उपकरणद्वारा प्राप्त सेल प्रसारण सन्देशहरू अनुप्रयोगलाई पढ्न अनुमति दिन्छ। सेल प्रसारण चेतावनीहरू केही स्थानहरूमा तपाईंलाई आपतकालीन गतिविधिहरूको बारेमा सचेत गराउन गरिएका छन्। खराब अनुप्रयोगहरूले एउटा आपतकालीन सेल प्रसारण प्राप्त गर्दछ जब तपाईंको उपकरणको प्रदर्शन वा अपरेशनको साथ हस्तक्षेप गर्न सक्दछन्।"</string>
+    <string name="permlab_sendSms" msgid="5600830612147671529">"SMS सन्देशहरू पठाउनुहोस्"</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"अनुप्रयोगलाई SMS सन्देशहरू पठाउन अनुमति दिन्छ। यसले अप्रत्यासित चार्जहरूको परिणाम दिन सक्दछ। खराब अनुप्रयोगहरूले तपाईंको पुष्टि बिना सन्देशहरू पठाएर तपाईंको पैसा खर्च गराउन सक्दछ।"</string>
+    <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"प्रतिक्रिया-मार्फत-सन्देश घटनाहरू पठाउनुहोस्"</string>
+    <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"अनुप्रयोगलाई आगत कलहरूको लागि प्रतिक्रिया-मार्फत-सन्देश घटनाहरूलाई अन्य सन्देश पठाउने अनुप्रयोगहरूमा अनुरोधहरू पठाउन अनुमति दिन्छ।"</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"तपाईंका पाठ सन्देशहरू (SMS वा MMS) पढ्नुहोस्"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"तपाईँको ट्याब्लेट वा SIM कार्डमा भण्डारण भएका SMS सन्देशहरूलाई पढ्न अनुप्रयोगलाई अनुमति दिन्छ। यसले अनुप्रयोगलाई विषयवस्तु वा गोपनीयतालाई वेवास्ता गर्दै सबै SMS सन्देशहरू पढ्ने अनुमति दिन्छ।"</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"तपाईँको फोन वा SIM कार्डमा भण्डारण भएका SMS सन्देशहरूलाई पढ्न अनुप्रयोगलाई अनुमति दिन्छ। यसले सबै SMS सन्देशहरूलाई पढ्नको लागि सामग्री वा विश्वसनियता बिना नै अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_writeSms" msgid="3216950472636214774">"तपाईँका पाठ सन्देशहरू सम्पादन गर्नुहोस् (SMS वा MMS)"</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"अनुप्रयोगलाई तपाईंको ट्याब्लेट वा SIM कार्डमा भण्डार गरिएका SMS सन्देशहरू लेख्न अनुमति दिन्छ। खराब अनुप्रयोगहरूले तपाईंको सन्देशहरू मेटाउन सक्दछ।"</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"तपाईँको फोन वा SIM कार्डमा भण्डारण भएका 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_interactAcrossUsers" msgid="7114255281944211682">"प्रयोगकर्ताहरू तर्फ अन्तर्क्रिया गर्नुहोस्"</string>
+    <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"अनुप्रयोगलाई उपकरणमा विभिन्न प्रयोगकर्ताहरू मार्फत कार्यहरू गर्न अनुमति दिन्छ। खराब अनुप्रयोगहरूले यो प्रयोगकर्ताहरू बिच सुरक्षा बिथोल्न प्रयोग गर्न सक्ने छन्।"</string>
+    <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"कुराकानी प्रयोगकर्ताहरू बिच अन्तर्क्रिया गर्न पूर्ण अनुमति"</string>
+    <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"प्रयोगकर्तासँगको कुराकानी सबै सम्भावनालाई अनुमति दिन्छ।"</string>
+    <string name="permlab_manageUsers" msgid="1676150911672282428">"प्रयोगकर्ताहरू व्यवस्थापन गर्नुहोस्"</string>
+    <string name="permdesc_manageUsers" msgid="8409306667645355638">"अनुप्रयोगलाई उपकरणमा, प्रश्न, सिर्जना र मेटाइसहित प्रयोगकर्ताहरूको प्रबन्ध गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"चलिरहेका अनुप्रयोगहरूको विवरण पुनःबहाली गर्नुहोस्"</string>
+    <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"वर्तमानमा र भरखरै चलिरहेका कार्यहरूको बारेमा विस्तृत सूचना पुनःबहाली गर्न अनुप्रयोगलाई अनुमति दिन्छ। खराब अनुप्रयोगहरूले अन्य अनुप्रयोगहरू बारेको निजी सूचना पत्ता लगाउन सक्छ।"</string>
+    <string name="permlab_reorderTasks" msgid="2018575526934422779">"चलिरहेका अनुप्रयोगहरूलाई पुनःक्रम गराउनुहोस्"</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"कामहरूलाई अग्रभाग र पृष्ठभूमिमा सार्न अनुप्रयोगलाई अनुमति दिन्छ। अनुप्रयोगले यो तपाईँको इनपुट बिना नै गर्न सक्छ।"</string>
+    <string name="permlab_removeTasks" msgid="6821513401870377403">"चालु भइरहेका अनुप्रयोगहरू रोक्नुहोस्"</string>
+    <string name="permdesc_removeTasks" msgid="1394714352062635493">"कामहरू हटाउन र उनीहरूको अनुप्रयोगहरूलाई बन्द गर्न अनुप्रयोगलाई अनुमति दिन्छ। खराब अनुप्रयोगहरूले अन्य अनुप्रयोगहरूको व्यवहारलाई अबरोध गर्न सक्छन्।"</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"activity stacks को प्रबन्ध गर्नुहोस्"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"अनुप्रयोगलाई अन्य अनुप्रयोगहरू चल्ने activity stacks लाई थप्न, हटाउन र परिवर्तन गर्न अनुमति दिन्छ। खराब अनुप्रयोगहरूले अन्य अनुप्रयोगहरूको व्यवहारलाई विघटन गर्न सक्छन्।"</string>
+    <string name="permlab_startAnyActivity" msgid="2918768238045206456">"कुनै गतिविधि सुरु गर्नुहोस्"</string>
+    <string name="permdesc_startAnyActivity" msgid="997823695343584001">"अनुमति सुरक्षा वा निर्यात अवस्थालाई वास्ता नगरिकन कुनै पनि कार्य सुरु गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"स्क्रिन अनुकूलता सेट गर्नुहोस्"</string>
+    <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"अन्य अनुप्रयोहरूको स्क्रिन मिल्दो मोडलाई नियन्त्रण गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ। अन्य अनुप्रयोहरूको व्यवहार खराब अनुप्रयोगहरूले टुटाउन सक्छन्।"</string>
+    <string name="permlab_setDebugApp" msgid="3022107198686584052">"अनुप्रयोग डिबग गर्ने सक्षम गर्नुहोस्"</string>
+    <string name="permdesc_setDebugApp" msgid="4474512416299013256">"अनुप्रयोगलाई अन्य अनुप्रयोगको लागि डिबग गर्ने प्रक्रिया चालु गर्ने अनुमति दिन्छ। खराब अनुप्रयोगले अरू अनुप्रयोगहरू समाप्त गर्न यसको उपयोग गर्न सक्दछ।"</string>
+    <string name="permlab_changeConfiguration" msgid="4162092185124234480">"प्रणाली प्रदर्शन सेटिङहरू परिवर्तन गर्नुहोस्"</string>
+    <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"वर्तमान कन्फिगरेसन जस्तै लोक्याल वा सबैतिर फन्ट आकार बदल्न अनुप्रयोगलाई अनुमति दिन्छ।"</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_forceStopPackages" msgid="2329627428832067700">"अन्य अनुप्रयोगहरू दबाबमा रोक्नुहोस्"</string>
+    <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"अन्य अनुप्रयोगहरूलाई बलपूर्वक बन्द गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_forceBack" msgid="652935204072584616">"अनुप्रयोग बन्द गर्न बल गर्नुहोस्"</string>
+    <string name="permdesc_forceBack" msgid="3892295830419513623">"अग्रभागमा भएको कुनै गतिविधिलाई जबरजस्ती बन्द गर्न र फर्केर जानका लागि अनुप्रयोगलाई अनुमति दिन्छ। सामान्य अनुप्रयोगहरूलाइ कहिल्यै आवश्यकता पर्दैन।"</string>
+    <string name="permlab_dump" msgid="1681799862438954752">"प्रणालीको आन्तरिक स्थिति प्राप्त गर्नुहोस्"</string>
+    <string name="permdesc_dump" msgid="1778299088692290329">"प्रणालीको आन्तरिक स्थिति पुनःबहाली गर्न अनुप्रयोगलाई अनुमति दिन्छ। खराब अनुप्रयोगहरूले उनीहरूलाई सामान्यतः कहिल्यै नचाहिने व्यापक विविधताको निजी र सुरक्षित सूचना पुनःबहाली गर्न सक्छन्।"</string>
+    <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"स्क्रिन सामग्री बहाली गर्नुहोस्"</string>
+    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"सक्रिय विन्डोको विषयवस्तुलाई पुनःबहाली गर्न अनुप्रयोगलाई अनुमति दिन्छ। खराब अनुप्रयोगहरूले पुरै विन्डोको विषयवस्तु पुनःबहाली गर्न सक्छन् र पासवर्डहरूबाहेक यसका सबै पाठको जाँच गर्न सक्छन्।"</string>
+    <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"पहुँचतालाई अस्थायी सक्षम गर्नुहोस्"</string>
+    <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"अनुप्रयोगलाई अस्थायी रूपमा उपकरणमाथि पहुँच राख्न अनुमति दिन्छ। खराब अनुप्रयोगले उपयोगकर्ताको सहमति बिना नै पहुँचलाई सक्षम गर्न सक्दछ।"</string>
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"विन्डो जानकारी बहाली गर्नुहोस्"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"अनुप्रयोगलाई विन्डो व्यवस्थापकबाट विन्डोहरूको बारेमा जानकारी प्राप्त गर्न अनुमति दिन्छ। खराब अनुप्रयोगले आन्तरिक प्रणाली उपयोगको लागि निमित्त जानकारी पनि प्राप्त गर्न सक्दछ।"</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"घटनाहरू छान्नुहोस्"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"इन्पुट फिल्टर जुन सबै प्रयोगकर्ता घटनाहरू पठाइनुभन्दा पहिले फिल्टर गर्नेलाई दर्ता गर्न अनुप्रयोगलाई अनुमति दिन्छ। प्रयोगकर्ताको हस्तक्षेप बिना नै UI प्रणाली खराब अनुप्रयोगले नियन्त्रण गर्न सक्छन्।"</string>
+    <string name="permlab_magnify_display" msgid="5973626738170618775">"प्रदर्शन बढाउनुहोस्"</string>
+    <string name="permdesc_magnify_display" msgid="7121235684515003792">"अनुप्रयोगलाई प्रदर्शनको सामग्री आवर्धन गर्न अनुमति दिन्छ। खराब अनुप्रयोगहरूले प्रदर्शन सामग्री संक्रमण गर्न सक्दछन् जसले उपकरणलाई अनुपयोगी बनाउँदछ।"</string>
+    <string name="permlab_shutdown" msgid="7185747824038909016">"आंशिक बन्द"</string>
+    <string name="permdesc_shutdown" msgid="7046500838746291775">"गतिविधि व्यवस्थापकलाई बन्द गर्ने अवस्थामा राख्छ। पूर्ण बन्द गर्ने काम गर्दैन।"</string>
+    <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"अनुप्रयोग स्विचहरू जोगाउनुहोस्"</string>
+    <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"अन्य अनुप्रयोगमा स्विच गर्नबाट प्रयोगकर्ताहरूलाई रोक्छ।"</string>
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"वर्तमान अनुप्रयोगको जानकारी प्राप्त गर्नुहोस्"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"होल्डरलाई स्क्रिनको पृष्ठभूमिमा वर्तमान अनुप्रयोगको बारेमा व्यक्तिगत जानकारी पुनःप्राप्त गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"सबै अनुप्रयोग सुरुवात गर्ने निरीक्षण र नियन्त्रण गर्नुहोस्"</string>
+    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"अनुप्रयोगलाई कसरी प्रणाली सुरुवात गतिहरू मोनिटर गर्न र नियन्त्रण गर्न अनुमति दिन्छ। खराब अनुप्रयोगहरूले प्रणालीमा पूर्ण सहमत गर्न सक्दछ। यो अनुमति केवल विकासको लागि आवश्यक छ, साधारण प्रयोगको लागि कहिले होइन।"</string>
+    <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"प्याकेज हटाइएको प्रसारणलाई पठाउनुहोस्"</string>
+    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"अनुप्रयोगलाई सूचना प्रसारण गर्न अनुमति दिन्छ जुन अनुप्रयोग प्याकेज हटाइएको छ। खराब अनु्प्रयोगहरूले यो कुनै अन्य चालु अनु्प्रयोग बन्द गर्न प्रयोग गर्न सक्दछन्।"</string>
+    <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"SMS-प्राप्त प्रसारण पठाउनुहोस्"</string>
+    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"त्यो एउटा SMS सन्देशबाट प्राप्त भएको सूचनालाई प्रसारण गर्न अनुप्रयोगलाई अनुमति दिन्छ। आउँदै गरेको SMS सन्देशहरूलाई जालसाजी गर्न सायद खराब भएका अनुप्रयोगहरूले यसलाई प्रयोग गर्न सक्छन्।"</string>
+    <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"WAP-PUSH-प्राप्त प्रसारण पठाउनुहोस्"</string>
+    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"अनुप्रयोगलाई सूचना प्रसारण गर्न अनुमति दिन्छ जुन एउटा WAP PUSH सन्देश प्राप्त भएको छ। खराब अनुप्रयोगहरूले यो MMS सन्देश बिगार्न वा मौन तरिकाले कुनै पनि वेबपृष्ठको सामग्री खराब विभेदहरूसँग बदल्न प्रयोग गर्न सक्दछन्।"</string>
+    <string name="permlab_setProcessLimit" msgid="2451873664363662666">"चालु प्रशोधनहरूको सङ्ख्या सीमति गर्नुहोस्"</string>
+    <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"अनुप्रयोगलाई चालु हुने प्रक्रियाहरूको अधिकतम संख्या नियन्त्रण गर्न अनुमति दिन्छ। साधारण अनुप्रयोगहरूको लागि कहिले पनि आवश्यक नपर्न सक्दछ।"</string>
+    <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"पृष्ठभूमि अनुप्रयोगहरू बन्द गर्न दबाब दिनुहोस्"</string>
+    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"अनुप्रयोगलाई गतिविधिहरू सधैँ समाप्त भयो कि भएन जब कि जति सक्दो तिनीहरू पृष्ठभूमिमा जान्छन् भन्ने नियन्त्रण गर्न अनुमति दिन्छ। साधारण अनुप्रयोगहरूको लागि कहिले पनि आवश्यक नपर्न सक्दछ।"</string>
+    <string name="permlab_batteryStats" msgid="2789610673514103364">"ब्याट्रि तथ्याङ्हरू पढ्नुहोस्"</string>
+    <string name="permdesc_batteryStats" msgid="5897346582882915114">"वर्तमान थोरै ब्याट्री प्रयोग डेटा पढ्नको लागि एक अनुप्रयोगले अनुमति दिन्छ। जुन अनुप्रयोग तपाईँले प्रयोग गरीरहनुभएको छ त्यस्को बारेका पुर्ण जानकारी प्राप्त गर्न सायद अनुप्रयोगले अनुमति दिन्छ।"</string>
+    <string name="permlab_updateBatteryStats" msgid="3719689764536379557">"ब्याट्रि तथ्याङ्कलाई परिमार्जन गर्नुहोस्"</string>
+    <string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"अनुप्रयोगलाई संकलित ब्याट्रि तथ्याङ्कहरू परिमार्जन गर्न अनुमति दिन्छ। साधारण अनुप्रयोगहरूको प्रयोगको लागि होइन।"</string>
+    <string name="permlab_getAppOpsStats" msgid="1508779687436585744">"अनुप्रयोग संचालनका तथ्याङ्कहरू पुनःबहाली गर्नुहोस्"</string>
+    <string name="permdesc_getAppOpsStats" msgid="6243887041577912877">"सङ्कलन गरिएका अनुप्रयोग संचालन तथ्याङ्लाई पुनः प्राप्त गर्न अनुप्रयोगलाई अनुमति दिन्छ। सामान्य अनुप्रयोगबाट प्रयोगको लागि होइन।"</string>
+    <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"अनुप्रयोग संचलान तथ्याङ्कहरूलाई परिमार्जन गर्नुहोस्"</string>
+    <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"सङ्कलन गरिएका अनुप्रयोग संचालन तथ्याङ्लाई परिमार्जन गर्न अनुप्रयोगलाई अनुमति दिन्छ। सामान्य अनुप्रयोगबाट प्रयोगको लागि होइन।"</string>
+    <string name="permlab_backup" msgid="470013022865453920">"प्रणाली ब्यकअप नियन्त्रण गर्नुहोस् र पुनः बहाली गर्नुहोस्"</string>
+    <string name="permdesc_backup" msgid="6912230525140589891">"प्रणालीको जगेडा नियन्त्रण गर्न र पुनःप्राप्तिको संयोजन गर्न अनुप्रयोगलाई अनुमित दिन्छ। सामान्य अनुप्रयोगद्वारा प्रयोगको लागि होइन।"</string>
+    <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"पूर्ण जगेडा गर्न वा प्रक्रिया पुनःबहाली गर्न निश्चित गर्नुहोस्"</string>
+    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"UI को पूर्ण जगेडा निश्चिन्तता सुरु गर्नका लागि अनुप्रयोगलाई अनुमति दिन्छ। कुनै अनुप्रयोगबाट प्रयोग नगरिने।"</string>
+    <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"अनधिकृत बिन्डोहरू प्रदर्शन गर्नुहोस्"</string>
+    <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"अनुप्रयोगलाई विन्डोहरू सिर्जना गर्न अनुमति दिन्छ जुन आन्तरिक प्रणाली प्रयोगकर्ता इन्टरफेसद्वारा प्रयोग गर्न अभिप्रेरित छ। साधारण अनुप्रयोगहरूद्वारा प्रयोगको लागि होइन।"</string>
+    <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"अन्य अनुप्रयोगहरूमा चित्र कोर्नुहोस्"</string>
+    <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"अरू अनुप्रयोगहरूमाथि वा प्रयोगकर्ता इन्टरफेसका भागहरूमा चित्र कोर्न अनुप्रयोगलाई अनुमति दिन्छ। तिनीहरूले कुनै अनुप्रयोगमा इन्टरफेको तपाईँको प्रयोगसँग हस्तक्षेप गर्न वा तपाईँ अन्य अनुप्रयोगहरूमा के देखिरहनु भएको छ भन्ने सोच्न हुन्छ भन्ने बदल्न सक्छन्।"</string>
+    <string name="permlab_setAnimationScale" msgid="2805103241153907174">"ग्लोबल सजीविकरण गति परिमार्जन गर्नुहोस्"</string>
+    <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"विश्वब्यापि सजीविकरण(द्रुत वा ढिला सजीविकरणहरू) लाई कुनै पनि समय परिवर्तन गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_manageAppTokens" msgid="1286505717050121370">"अनुप्रयोग टोकनहरू प्रबन्ध गर्नुहोस्"</string>
+    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"अनुप्रयोगलाई आफ्ना टोकनहरू सिर्जना गर्न र उनीहरूको साधारण Z-क्रमाङ्कन बाइपास गरेर प्रबन्ध गर्न अनुमति दिन्छ। साधारण अनुप्रयोगहरूको लागि कहिल्यै पनि आवश्यक नहुन सक्दछ।"</string>
+    <string name="permlab_freezeScreen" msgid="4708181184441880175">"स्क्रिन फ्रिज गर्नुहोस्"</string>
+    <string name="permdesc_freezeScreen" msgid="8558923789222670064">"अनुप्रयोगलाई पूर्ण-स्क्रिन संक्रमणको लागि अस्थायी रूपमा स्क्रिन स्थिर गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_injectEvents" msgid="1378746584023586600">"कुञ्जीहरू र नियन्त्रण बटनहरू थिच्नुहोस्"</string>
+    <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"यसका आफ्ना इनपुट घटनाहरू (कि थिचाइहरू, आदि) अन्य अनुप्रयोगहरूलाई वितरण गर्न अनुप्रयोगलाई अनुमति दिन्छ। खराब अनुप्रयोगहरूले यसलाई ट्याब्लेटसम्म लैजान प्रयोग गर्न सक्छन्।"</string>
+    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"यस्को आफ्नै निवेश घटनाहरू (कि थिचाइहरू, आदि.) अन्य अनुप्रोयगहरूलाई पु्र्‍याउन अनुप्रयोगलाई अनुमति दिन्छ। फोनलाई हस्तक्षेप गर्न यसको प्रयोग खराब अनुप्रयोगहरूले गर्न सक्छन्।"</string>
+    <string name="permlab_readInputState" msgid="469428900041249234">"तपाईंले के टाइप गर्नुहुन्छ र के कार्यहरू लिनुहुन्छ रेकर्ड गर्नुहोस्"</string>
+    <string name="permdesc_readInputState" msgid="8387754901688728043">"अर्को अनुप्रयोग(जस्तै पासवर्ड टाइप गराइ)सँग अन्तर्क्रिया गरेको बेला पनि तपाईँले थिचेका किहरूलाइ हेर्न अनुप्रयोगलाई अनुमति दिन्छ। सामान्य अनुप्रयोगहरूलाई कहिल्यै आवश्यक हुँदैन।"</string>
+    <string name="permlab_bindInputMethod" msgid="3360064620230515776">"एउटा निवेश तरिकामा बाँध्नुहोस्"</string>
+    <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"एउटा निवेश तरिकाको उच्च स्तरको इन्टरफेसलाई पक्का गर्नको लागि समाती राख्नेलाई अनुमति दिन्छ। साधारण अनुप्रयोगहरूलाई कहिल्यै आवश्यक पर्ने छैन।"</string>
+    <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"एउटा पहुँच सेवासँग जोड्नुहोस्"</string>
+    <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"एक पहुँच सेवाको उच्च स्तरको कुराकानीलाई पक्का गर्नको लागि समाती राख्नेले अनुमति दिन्छ। साधारण अनुप्रयोगहरूलाई कहिल्यै आवश्यक पर्ने छैन।"</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"एउटा प्रिन्ट सेवासँग जोड्नुहोस्"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"एउटा प्रिन्ट सेवाको उच्च स्तरको इन्टरफेसलाई पक्का गर्नको लागि प्रयोगकर्तालाई अनुमति दिन्छ। साधारण अनुप्रयोगहरूलाई कहिल्यै आवश्यक पर्ने छैन।"</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"प्रिन्ट स्पुलर सेवासँग बाध्नुहोस्"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"प्रिन्ट स्पुलर सेवाको शीर्ष तह इन्टर्फेसलाई बाहकसँग बाँध्न अनुमति दिन्छ। सामान्य अनुप्रयोगलाई कहिल्यै पनि आवाश्यक नपर्न सक्छ।"</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC सेवामा बाँध्नुहोस्"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"NFC कार्डहरू इमुलेट गर्ने अनुप्रयोगहरूलाई बाँध्नका लागि होल्डरलाई अनुमति दिन्छ। सामान्य अनुप्रयोगहरूका लागि कहिल्यै पनि आवश्यक पर्दैन।"</string>
+    <string name="permlab_bindTextService" msgid="7358378401915287938">"एउटा पाठ सेवासँग संगठित हुनुहोस्"</string>
+    <string name="permdesc_bindTextService" msgid="8151968910973998670">"एउटा पाठ सेवाको (उदाहरण शब्द परीक्षणसेवा) उच्च स्तरको इन्टरफेसलाई पक्का गर्नको लागि समाती राख्नेलाई अनुमति दिन्छ। साधारण अनुप्रयोगहरूलाई कहिल्यै आवश्यक पर्ने छैन।"</string>
+    <string name="permlab_bindVpnService" msgid="4708596021161473255">"VPN सेवासँग बाँध्नुहोस्।"</string>
+    <string name="permdesc_bindVpnService" msgid="2067845564581693905">"एक Vpn सेवाको उच्च स्तरको कुराकानीलाई पक्का गर्नको लागि समाती राख्नेले अनुमति दिन्छ। साधारण अनुप्रयोगहरूलाई कहिल्यै आवश्यक पर्ने छैन।"</string>
+    <string name="permlab_bindWallpaper" msgid="8716400279937856462">"एउटा वालपेपरमा बाँध्नुहोस्"</string>
+    <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"वालपेपरको माथिल्लो स्तरको इन्टरफेसमा बाँध्न धारकलाई अनुमति दिन्छ। सामान्य अनुप्रयोगहरूलाई कहिल्यै आवश्यक पर्दैन।"</string>
+    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"एउटा विजेट सेवासँग संगठित हुनुहोस्"</string>
+    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"एउटा विजेट सेवाको उच्च स्तरको इन्टरफेसलाई पक्का गर्नको लागि समाती राख्नेलाई अनुमति दिन्छ। साधारण अनुप्रयोगहरूलाई कहिल्यै आवश्यक पर्ने छैन।"</string>
+    <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"उपकरणको प्रबन्धसँग अन्तरक्रिया गर्नुहोस्"</string>
+    <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"उपकरण प्रशासक लाई आशय पठाउन समाती राख्‍नेलाई अनुमति दिन्छ। साधारण अनुप्रयोहरूको लागि कहिल्यै पनी आवश्यक पर्दैन।"</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"एउटा उपकरण व्यवस्थापक थप गर्नुहोस् वा हटाउनुहोस्"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"होल्डरलाई सक्रिय उपकरण व्यवस्थापकहरू थप गर्न वा हटाउन अनुमति दिन्छ। साधारण अनुप्रयोगहरूको लागि कहिल्यै पनि आवश्यक नहुन सक्दछ।"</string>
+    <string name="permlab_setOrientation" msgid="3365947717163866844">"स्क्रिन अभिमुखिकरण परिवर्तन गर्नुहोस्"</string>
+    <string name="permdesc_setOrientation" msgid="3046126619316671476">"अनुप्रयोगलाई कुनै पनि समयमा स्क्रिनको परिक्रमण परिवर्तन गर्न अनुमति दिन्छ। साधारण अनुप्रयोगहरूको लागि कहिले पनि आवश्यक नपर्न सक्दछ।"</string>
+    <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"सङ्केतक गति बदल्नुहोस्"</string>
+    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"कुनै पनि समयमा माउस परिवर्तन गर्न वा ट्राकप्याड संकेतकको गति बदल्न अनुप्रयोगलाई अनुमति दिन्छ। सामान्य अनुप्रयोगहरूको लागि कहिल्यै नचाहिन सक्छ।"</string>
+    <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"किबोर्ड लेआउट परिवर्तन गर्नुहोस्"</string>
+    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"किबोर्ड लेआउटलाई परिवर्तन गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ। साधारण अनुप्रयोगहरूलाई सायद कहिल्यै आवश्यक पर्ने छैन।"</string>
+    <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"Linux संकेतहरू अनुप्रयोगलाई पठाउनुहोस्"</string>
+    <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"सबै चलिरहेका प्रक्रियाहरूमा पठाइएका संकेतलाई अनुरोध गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_persistentActivity" msgid="8841113627955563938">"अनुप्रयोगहरू जहिले पनि चल्ने बनाउनुहोस्"</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"यसको आफ्नै मेमोरीमा दृढ भएकोको अंश बनाउनको लागि अनुप्रयोगलाई अनुमति दिन्छ। ट्याब्लेटलाई ढिलो गराउँदै गरेका अन्य अनुप्रयोगहरूलाई सीमित मात्रामा यसले मेमोरी उपलब्ध गराउन सक्छ।"</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"अनुप्रयोगलाई मेमोरीमा आफैंको निरन्तरको अंश बनाउन अनुमति दिन्छ। यसले फोनलाई ढिला बनाएर अन्य अनुप्रयोगहरूमा मेमोरी SIMित गर्न सक्दछन्।"</string>
+    <string name="permlab_deletePackages" msgid="184385129537705938">"अनुप्रयोगहरू मेटाउनुहोस्"</string>
+    <string name="permdesc_deletePackages" msgid="7411480275167205081">"अनुप्रयोगलाई एन्ड्रोइड प्याकेजहरू मेटाउन अनुमति दिन्छ। खराब अनुप्रयोगहरूले यसलाई महत्त्वपूर्ण अनुप्रयोगहरू मेटाउन प्रयोग गर्न सक्दछन्।"</string>
+    <string name="permlab_clearAppUserData" msgid="274109191845842756">"अन्य अनुप्रयोगहरूको डेटा मेटाउनुहोस्"</string>
+    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"प्रयगकर्ता डेटा हटाउन अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"अन्य अनुप्रयोगहरूको क्यासहरू मेटाउनुहोस्"</string>
+    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"अनुप्रयोगलाई क्यास फाइलहरू मेटाउन अनुमति दिन्छ।"</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"अनुप्रयोग भण्डारण ठाउँको मापन गर्नुहोस्"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"अनुप्रयोगलाई यसको कोड, डेटा, र क्यास आकारहरू पुनःप्राप्त गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_installPackages" msgid="2199128482820306924">"अनुप्रयोगहरू सिधै स्थापना गर्नुहोस्"</string>
+    <string name="permdesc_installPackages" msgid="5628530972548071284">"नयाँ स्थापना गर्न वा एन्ड्रोइड प्याकेजहरू अद्यावधिक गर्न अनुप्रयोगलाई अनुमति दिन्छ। खराब अनुप्रयोगहरूले यसलाई मनपरी रूपमा शक्तिशाली अनुमतिहरू भएका नयाँ अनुप्रयोगहरू थप्न प्रयोग गर्न सक्छन्।"</string>
+    <string name="permlab_clearAppCache" msgid="7487279391723526815">"सबै अनुप्रयोग क्यास डेटा मेटाउनुहोस्"</string>
+    <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"अन्य अनुप्रयोगहरूको क्यास डाइरेक्टरीहरूमा फाइलहरू हटाएर ट्याब्लेटको भण्डारण खाली गर्न अनुप्रयोगहरूलाई अनुमति दिन्छ। उनीहरूले आफ्नो डेटा पुनःबहाली गर्न पर्ने हुनाले यसले अन्य अनुप्रयोगहरूलाई स्टार्ट हुन निकै ढिलो गराउन सक्छ।"</string>
+    <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"अनुप्रयोगलाई अन्य अनुप्रयोगहरूको क्यास डाइरेक्टरीमा फाइलहरू मेटाएर फोन भण्डारण खाली गर्न अनुमति दिन्छ। यसले अन्य अनुप्रयोगहरूलाई बढी ढिला सुरु गराउँछ किनकि तिनीहरूले आफ्नो डेटा पुनःप्राप्ति गर्न आवश्यक पर्ने हुन्छ।"</string>
+    <string name="permlab_movePackage" msgid="3289890271645921411">"अनुप्रयोग स्रोतहरू सार्नुहोस्"</string>
+    <string name="permdesc_movePackage" msgid="319562217778244524">"अनुप्रयोग स्रोतहरू आन्तरिकबाट बाह्य मेडियामा र विपरितमा लैजान अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_readLogs" msgid="6615778543198967614">"संवेनशील लग डेटा पढ्नुहोस्"</string>
+    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"प्रणालीका विभिन्न फाइलहरूबाट पढ्न अनुप्रयोगलाई अनुमति दिन्छ। सम्भाव्य रूपमा व्यक्तिगत र निजी सूचनासहित तपाईँ ट्याब्लेटसँग के गरिरहनु भएको छ भन्ने बारेको साधारण सूचना पत्ता लगाउन यसलाई अनुमति दिन्छ।"</string>
+    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"प्रणालीका विभिन्न फाइलहरूबाट पढ्न अनुप्रयोगलाई अनुमति दिन्छ। सम्भाव्य रूपमा व्यक्तिगत र निजी सूचनासहित तपाईँ फोनसँग के गरिरहनु भएको छ भन्ने बारेको साधारण सूचना पत्ता लगाउन यसलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"पछाडि बजाउनको लागि कुनै मिडिया प्रयोग गर्नुहोस्"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"अनुप्रयोगलाई प्लेब्याक डिकोड गर्न कुनै पनि स्थापित मिडिया डिकोडर प्रयोगको लागि अनुमति दिन्छ।"</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"विश्वसनीय प्रमाणहरू प्रबन्ध गर्नुहोस्"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"अनुप्रयोगलाई CA प्रमाणपत्रहरू विश्वसनीय प्रमाणहरूका रूपमा स्थापना गर्न र हटाउन अनुमति दिन्छ।"</string>
+    <string name="permlab_diagnostic" msgid="8076743953908000342">"diag को स्वामित्वमा रहेको संसाधनहरूमा पढ्नुहोस्/लेख्नुहोस्"</string>
+    <string name="permdesc_diagnostic" msgid="6608295692002452283">"अनुप्रयोगलाई diag समूहद्वारा स्वामित्व प्राप्त कुनै पनि स्रोतहरूमा पढ्न र लेख्न अनुमति दिन्छ; उदाहरणको लागि, /dev  मा फाइलहरू। यसले सम्भवतः प्रणाली स्थिरता र सुरक्षामा प्रभाव पार्न सक्दछ। यो केवल निर्माता वा संचालकद्वारा हार्डवेयर-निर्दिष्टको लागि प्रयोग हुन सक्दछ।"</string>
+    <string name="permlab_changeComponentState" msgid="6335576775711095931">"अनुप्रयोग अंशहरू सक्षम वा अक्षम गर्नुहोस्"</string>
+    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"अन्य अनुप्रयोग सक्षम छ वा छैन भन्ने कुराको परिवर्तन गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ। महत्त्वपूर्ण फोन सक्षमता खराब अनुप्रोगहरूले असक्षम पार्न प्रयोग गर्न सक्छन्। यो अनुमतिसँगै होसियारी अपनाउनु पर्छ, अनुप्रयोग विषय सूचीमा प्रयोग नहुने, असंगत, अस्थिर अवस्था भएको प्राप्त हुने सम्भावना हुन्छ।"</string>
+    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"अन्य अनुप्रयोगको अंश सक्षम छ वा छैन भन्नेमा परिवर्तन गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ। महत्त्वपूर्ण फोन सक्षमता खराब अनुप्रोगहरूले असक्षम पार्न प्रयोग गर्न सक्छन्। यो अनुमतिसँगै होसियारी अपनाउनु पर्छ, अनुप्रयोग विषय सूचीमा प्रयोग नहुने, असंगत, अस्थिर अवस्था भएको प्राप्त हुने सम्भावना हुन्छ।"</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"अनुमतिहरू प्रदान गर्नुहोस् वा रद्द गर्नुहोस्"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"अनुप्रयोगलाई यो वा अन्य अनुप्रयोगहरूको लागि निर्दिष्ट स्वीकृतिहरू प्रदान गर्न वा रद्द गर्न अनुमति दिन्छ। खराब अनुप्रयोगहरूले यो तपाईंले अनुमति प्रदान नगर्नुभएका सुविधाहरूमा पहुँच गर्न सक्दछन्।"</string>
+    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"विशेष रूपमा मान्य अनुप्रयोगहरू सेट गर्नुहोस"</string>
+    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"तपाईँको मनपर्ने अनुप्रयोगलाई परिवर्तन गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ। खराब अनुप्रयोगहरूले चलिरहेका ती अनुप्रयोहरूलाई चुपचाप रूपमा परिवर्तन गर्न सक्छन्, तपाईँबाट निजी डेटा संकलन गर्नको लागि भइरहेको अनुप्रयोगलाई स्पुफ गर्न सक्छन्।"</string>
+    <string name="permlab_writeSettings" msgid="2226195290955224730">"प्रणाली सेटिङहरू परिमार्जन गर्नुहोस्"</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"प्रणालीका सेटिङ डेटालाई परिवर्तन गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ। खराब अनुप्रयोगहरूले सायद तपाईँको प्रणालीको कन्फिगरेसनलाई क्षति पुर्‍याउन सक्छन्।"</string>
+    <string name="permlab_writeSecureSettings" msgid="204676251876718288">"सुरक्षित प्रणाली सेटिङहरू परिमार्जन गर्नुहोस्"</string>
+    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"प्रणालीको सुरक्षित सेटिङ डेटा परिमार्जन गर्न अनुप्रयोगलाई अनुमति दिन्छ। सामान्य अनुप्रयोगहरूको प्रयोगको लागि होइन्।"</string>
+    <string name="permlab_writeGservices" msgid="2149426664226152185">"Google सेवा नक्सा परिवर्तन गर्नुहोस्"</string>
+    <string name="permdesc_writeGservices" msgid="1287309437638380229">"अनुप्रयोगलाई Google सेवा नक्साहरू परिमार्जन गर्न अनुमति दिन्छ। साधारण अनुप्रयोगहरूद्वाराको प्रयोगको लागि होइन।"</string>
+    <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"स्टार्टअपमा चलाउनुहोस्"</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"आनुप्रयोगलाई प्रणाली बुट प्रक्रिया पूर्ण हुने बितिकै आफैलाई सुरु गर्ने अनुमति दिन्छ। यसले ट्याब्लेट सुरु गर्नमा ढिला गर्न सक्दछ र अनुप्रयोगलाई समग्रमा ट्याब्लेट सधैँ चालु गरेर ढिला बनाउँदछ।"</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="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="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="default" msgid="589869224625163558">"तपाईँले बारम्बार कल गरेका, इमेल गरेका, वा विशेष सम्पर्कहरूसँग सञ्चार गरेका सहित तपाईँको फोनमा भण्डारण गरेका तपाईँका सम्पर्कहरू परिमार्जन गर्न अनुप्रयोगलाई अनुमति दिन्छ। यो अनुमतिले अनुप्रयोगलाई सम्पर्क डेटा मेटाउन दिन्छ।"</string>
+    <string name="permlab_readCallLog" msgid="3478133184624102739">"कल लग पढ्नुहोस्"</string>
+    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"अनुप्रयोगलाई तपाईँको ट्याब्लेटको कल लग, आगमन र बहिर्गमन कलहरू बारे डेटा सहितको कल लग पढ्न अनुमति दिन्छ। यस अनुमतिले अनुप्रयोगहरूलाई तपाईँको कल लग डेटाहरूको बचत गर्न अनुमति दिन्छ, र खराब अनुप्रयोगहरूले तपाईँको जानकारी बिना नै यो कल लग डेटालाई अरूसँग साझेदार गर्न सक्छन्।"</string>
+    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"भित्र आउने र बाहिर जाने कलहरूसहित तपाईँको फनको कल लग पढ्न अनुप्रयोगलाई अनुमति दिन्छ।  यो अनुमतिले अनुप्रयोगहरूलाई तपाईँका कल लग डेटा बचत गर्न दिन्छ र खराब अनुप्रयोगहरूले तपाईँले थाहै नपाई कल लग डेटालाई साझेदारी गर्न सक्छन्।"</string>
+    <string name="permlab_writeCallLog" msgid="8552045664743499354">"कल लग लेख्‍नुहोस्"</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"आगमन तथा बहर्गमन डेटासहित तपाईँको ट्याब्लेटको कल लगको परिमार्जन गर्न अनुप्रयोगलाई अनुमति दिन्छ। खराब अनुप्रयोगहरूले यसलाई तपाईँको कल लग परिमार्जन गर्न वा मेटाउन प्रयोग गर्न सक्छन्।"</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"अनुप्रयोगलाई तपाईंको फोनको आउने र बाहिर जाने कलहरूको बारेको डेटा सहित कल लग परिमार्जन गर्न अनुमति दिन्छ। खराब अनुप्रयोगहरूले यसलाई तपाईंको कल लग मेटाउन वा परिमार्जन गर्न प्रयोग गर्न सक्दछ।"</string>
+    <string name="permlab_readProfile" msgid="4701889852612716678">"तपाईँको आफ्नै सम्पर्क कार्ड पढ्नुहोस्"</string>
+    <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"अनुप्रयोगलाई तपाईंको उपकरणमा भण्डारण गरिएका व्यक्तिगत प्रोफाइल जानकारी पढ्न अनुमति दिन्छ, जस्तै तपाईंको नाम र सम्पर्क जानकारी। यसको मतलब अनुप्रयोगले तपाईंलाई पहिचान गर्न सक्दछ र तपाईंको प्रोफाइल जानकारी अरूलाई पठाउन सक्दछ।"</string>
+    <string name="permlab_writeProfile" msgid="907793628777397643">"तपाईँको आफ्नै सम्पर्क कार्ड परिमार्जन गर्नुहोस्"</string>
+    <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"तपाईँको उपकरणमा भण्डार भएको व्याक्तिगत प्रोफाइल जानकारी, जस्तै तपाईँको नाम वा सम्पर्क जानकारीलाई परिवर्तन गर्न वा थप्नको लागि अनुप्रयोगलाई अनुमति दिन्छ। यसको मतलब अन्य अनुप्रयोगले तपाईँलाई चिन्न सक्छन् र सायद अन्यलाई तपाईँको प्रोफाइल जानकारी पठाउन सक्छन्।"</string>
+    <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"तपाईंको सामाजिक स्ट्रिम पढ्नुहोस्"</string>
+    <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"तपाईँ र तपाईँका साथीहरूबाट सामाजिक अपडेटलाई पहुँच र सिंक गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ। जानकारी साझेदारी गर्दा सावधान रहनुहोस्  -- समाजिक नेटवर्कहरूमा तपाईँ र तपाईँको साथीको  बिचमा भएका संचारलाई पढ्न विश्वासनीयता बेगरै यसले अनुप्रयोगलाई अनुमति दिन्छ। नोट: यो अनुमति बलपूर्वक सबै सामाजिक नेटवर्कहरूमा सायद नगर्न सकिन्छ।"</string>
+    <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"तपाईँको सामाजिक प्रवाहमा लेख्‍नुहोस्"</string>
+    <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"अनुप्रयोगलाई तपाईंको साथीहरूबाट सामाजिक अपडेटहरू प्रदर्शन गर्न अनुमति दिन्छ। जानकारी साझेदारी गर्ने बेलामा होशियार रहनुहोस् -- यसले अनुप्रयोगलाई सन्देशहरू निर्माण गर्न अनुमति दिन्छ जुन साथीबाट आएको देखिन्छ। टिप्पणी: यो अनुमति सबै सामाजिक सञ्जालहरूमा लागू नहुन सक्दछ।"</string>
+    <string name="permlab_readCalendar" msgid="5972727560257612398">"गोप्य जानकारी र पात्रो घटनाहरू पढ्नुहोस्"</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"अनुप्रयोगलाई तपाईंको ट्याब्लेटमा भण्डारण गरिएका ती साथीहरू वा सहयोगीहरू सहितको पात्राका कार्यक्रमहरू पढ्न अनुमति दिन्छ। यसले गोपनीयता वा संवेदनशीलता बिना पनि अनुप्रयोगलाई तपाईंको पात्राका डेटा साझेदारी गर्न वा बचत गर्न अनुमति दिन्छ।"</string>
+    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"ती साथीहरू वा सहकर्मीहरूसहित सबै पात्रो घटनाहरू तपाईँको ट्याब्लेटमा भण्डारण भएकालाई पढ्नको लागि अनुप्रयोगलाई अनुमति दिन्छ। तपाईँको पात्रो डेटा यसले सायद सेयर गर्न वा सुरक्षित गर्नको लागि विश्वासनियता वा सम्वेदनशीलता बिना नै अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_writeCalendar" msgid="8438874755193825647">"पात्रो घटनाहरू थप्नुहोस् वा परिमार्जन गर्नुहोस् र मालिकको ज्ञान बिना नै पाहुनाहरूलाई इमेल पठाउनुहोस्"</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"ती साथीहरू वा सहकर्मीहरूसहितका घटनाहरू जसलाई तपाईँले आफ्नो ट्याब्लेटमा परिमार्जन गर्न सक्ने अनुमति अनुप्रयोगलाई दिन्छ। यसले अनुप्रयोगलाई सन्देशहरू जुन पात्राको मालिकहरूबाट आएका देखिनेलाई पठाउने वा मालिकहरूको ज्ञान बेगर घटनालाई परिमार्जन गर्ने अनुमित दिन्छ।"</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"ती साथीहरू वा सहकर्मीहरूसहित तपाईँको फोनका घटनाहरू जसलाई थप्न, हटाउन र परिवर्तन गर्न  अनुप्रयोगलाई अनुमति दिन्छ। पात्रो मालिकबाट देखा परेका वा मालिकको ज्ञान बिना परिवर्तन भएका घटनाहरू सन्देश पठाउन यसले अनुप्रयोगलाई अनुमति दिन सक्छ।"</string>
+    <string name="permlab_accessMockLocation" msgid="8688334974036823330">"परीक्षणको लागि स्थान स्रोतहरू मक गर्नुहोस्"</string>
+    <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"परीक्षणको लागि मक स्थान स्रोतहरू सिर्जना गर्नुहोस् वा नयाँ स्थान प्रदायक स्थापना गर्नुहोस्। यसले अनुप्रयोगलाई स्थानमा ओभरराइड गर्दछ र/वा स्थिति अन्य स्थान स्रोतहरू जस्तै GPS वा स्थान प्रदायकबाट फर्काइएका।"</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"अधिक स्थान प्रदायक आदेशहरू पहुँच गर्नुहोस्"</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"थप स्थान प्रदायक कमाण्डहरू सम्म पहुँच पुर्‍याउन अनुप्रयोगले अनुमति दिन्छ। यसले अनुप्रयोगलाई सायद जीपीएसको वा अन्य स्थान सेवाहरूको कार्य सँग हस्तक्षेप गर्नको लागि यसलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_installLocationProvider" msgid="6578101199825193873">"एउटा स्थान प्रदाता स्थापित गर्न अनुमति"</string>
+    <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"परीक्षणको लागि मक स्थान स्रोतहरू सिर्जना गर्नुहोस् वा नयाँ स्थान प्रदायक स्थापना गर्नुहोस्। यसले अनुप्रयोगलाई स्थानमा ओभरराइड गर्दछ र/वा स्थिति अन्य स्थान स्रोतहरू जस्तै GPS वा स्थान प्रदायकबाट फर्काइएका।"</string>
+    <string name="permlab_accessFineLocation" msgid="1191898061965273372">"सटिक स्थान (GPS र नेटवर्क आधारित)"</string>
+    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"अनुप्रयोगले विश्वव्यापी स्थान प्रणाली (GPS) वा सेल टावरहरू र वाइ-फाइ जस्ता नेटवर्क स्थान स्रोतहरूको प्रयोग गरेर तपाईँको सही स्थान प्राप्त गर्न अनुमति दिन्छ। यी स्थान सेवाहरू खोल्नु पर्छ र अनुप्रयोगहरूका लागि प्रयोग गर्न तपाईँको उपकरणमा उपलब्ध हुनु पर्छ। अनुप्रयोगहरूले तपाईँ कहाँ हुनु हुन्छ भन्ने निर्धारण गर्न यसलाई प्रयोग गर्न सक्छ र यसले अतिरिक्त ब्याट्रि उर्जा खतप गर्न सक्छ।"</string>
+    <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"अनुमानित स्थान (नेटवर्क-आधारित)"</string>
+    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"अनुप्रयोगलाई तपाईँको अनुमानित स्थान प्राप्त गर्न अनुमति दिन्छ। यो स्थान सेल टावर र वाइ-फाइजस्ता नेटवर्क स्थान स्रोतहरूको प्रोग गरी स्थान सेवाहरूबाट उत्पन्न गरिएको हो। अनुप्रयोगले यी स्थान सेवाहरूको उपयोग गर्नको लागि यी सेवाहरू तपाईँको उपकरणमा चालु र उपलब्ध हुनु आवश्यक छ। अनुप्रयोगहरूले अनुमानित रूपमा तपाईँ कहाँ हुनुहुन्छ भन्ने निर्धारण गर्न यसको प्रयोग गर्न सक्छन्।"</string>
+    <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"SurfaceFlinger पहुँच गर्नुहोस्।"</string>
+    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"SurfaceFlinger कम-स्तर सुविधाहरू प्रयोग गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"फ्रेम बफर पढ्नुहोस्"</string>
+    <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"अनुप्रयोगलाई फ्रेम बफरको सामग्री पढ्न अनुमति दिन्छ।"</string>
+    <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"वाइफाइ प्रदर्शनहरूलाई विन्यास गर्नुहोस"</string>
+    <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"अनुप्रयोगलाई कन्फिगर गर्न र वाइफाइ प्रदर्शनहरूसँग जोड्न अनुमति दिन्छ।"</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"वाइफाइ प्रदर्शनहरू नियन्त्रण गर्नुहोस्"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"वाइफाइ प्रदर्शनीका तल्लो तह विषेशताहरू नियन्त्रण गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"अडियो आउटपुट कैद गर्नुहोस्"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"अनुप्रयोगलाई अडियो आउटपुट कैद गर्न र रिडाइरेक्ट गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"भिडियो आउटपुट कैद गर्नुहोस्"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"अनुप्रयोगलाई भिडियो आउटपुट कैद गर्न र रिडाइरेक्ट गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"सुरक्षित भिडियो आउटपुट कैद गर्नुहोस्"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"अनुप्रयोगलाई सुरक्षित भिडियो आउटपुट कैद गर्न र रिडाइरेक्ट गर्न अनुमति दिन्छ।"</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="4906839301087980680">"अनुप्रयोगलाई माइक्रोफोनको साथ अडियो रेकर्ड गर्न अनुमति दिन्छ। यस अनुमतिले तपाईंको पुष्टिकरण बिना कुनै पनि समयमा अडियो रेकर्ड गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_camera" msgid="3616391919559751192">"तस्बिरहरू र भिडियोहरू लिनुहोस्।"</string>
+    <string name="permdesc_camera" msgid="8497216524735535009">"अनुप्रयोगलाई क्यामेरासँग तस्बिर र भिडियोहरू लिन अनुमति दिन्छ। यस अनुमतिले अनुप्रयोगलाई तपाईंको पुष्टिकरण बिना कुनै पनि समयमा क्यामेरा प्रयोग गर्न स्वीकृति दिन्छ।"</string>
+    <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"क्यामेरा प्रयोगमा हुँदा सूचक LED प्रसारण असक्षम गर्नुहोस्"</string>
+    <string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"पूर्व-स्थापित प्रणाली अनुप्रयोगलाई क्यामेरा उपयोग सूचक LED अक्षम गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"स्थायी रूपमा ट्याब्लेट अक्षम पार्नुहोस्"</string>
+    <string name="permlab_brick" product="default" msgid="8337817093326370537">"फोनलाई स्थायी रूपमा असक्षम पार्नहोस्"</string>
+    <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"पुरै ट्याब्लेटलाई स्थायी रूपमा असक्षम पार्न अनुप्रयोगलाई अनुमति दिन्छ। यो निकै खतरनाक हुन्छ।"</string>
+    <string name="permdesc_brick" product="default" msgid="5788903297627283099">"सम्पूर्ण फोनलाई स्थायी रूपमा असक्षम पार्न अनुप्रयोगलाई अनुमति दिन्छ। यो धेरै खतरनाक हुन्छ।"</string>
+    <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"ट्याब्लेट पुनःबुट गर्न जोड गर्नुहोस्"</string>
+    <string name="permlab_reboot" product="default" msgid="2898560872462638242">"फोन पुनःबुट गर्नु जोड गर्नुहोस्"</string>
+    <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"ट्याब्लेटलाई बलपूर्वक पुनःबुट गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"फोनलाई बलपुर्वक पुनःबुट गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"USB भण्डारण फाइल प्रणाली पहुँच गर्नुहोस्"</string>
+    <string name="permlab_mount_unmount_filesystems" product="default" msgid="4402305049890953810">"SD कार्ड फाइल प्रणाली पहुँच गर्नुहोस्"</string>
+    <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"हटाउन मिल्ने भण्डारणको लागि फाइल प्रणालीहरू माउन्ट र अनमाउन्ट गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"USB भण्डारण मेट्नुहोस्"</string>
+    <string name="permlab_mount_format_filesystems" product="default" msgid="262582698639274056">"SD कार्ड मेटाउनुहोस्"</string>
+    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"हटाउन मिल्ने भण्डारण फर्म्याट गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_asec_access" msgid="3411338632002193846">"आन्तरिक भण्डारणको सूचना प्राप्त गर्नुहोस्"</string>
+    <string name="permdesc_asec_access" msgid="3094563844593878548">"आन्तरिक भण्डारणमा सूचना प्राप्त गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_asec_create" msgid="6414757234789336327">"आन्तरिक भण्डारण सिर्जना गर्नुहोस्"</string>
+    <string name="permdesc_asec_create" msgid="4558869273585856876">"आन्तरिक भण्डारण सिर्जना गर्नको लागि अनुप्रयोगले अनुमति दिन्छ।"</string>
+    <string name="permlab_asec_destroy" msgid="526928328301618022">"आन्तरिक भण्डारण ध्वस्त पार्नुहोस्"</string>
+    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"अनुप्रयोगलाई आन्तरिक भण्डारण ध्वस्त पार्न अनुमति दिन्छ।"</string>
+    <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"आन्तरिक भण्डारणलाई माउन्ट/अनमाउन्ट गर्नुहोस्"</string>
+    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"अनुप्रयोगलाई आन्तरिक भण्डारण माउन्ट/अनमाउन्ट गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_asec_rename" msgid="7496633954080472417">"आन्तरिक भण्डारणको पुन:नामाकरण गर्नुहोस्"</string>
+    <string name="permdesc_asec_rename" msgid="1794757588472127675">"आन्तरीक भण्डारणको पुननामाकरण गर्नको लागि अनुप्रयोगले अनुमति दिन्छ।"</string>
+    <string name="permlab_vibrate" msgid="7696427026057705834">"कम्पन नियन्त्रण गर्नुहोस्"</string>
+    <string name="permdesc_vibrate" msgid="6284989245902300945">"अनुप्रयोगलाई भाइब्रेटर नियन्त्रण गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_flashlight" msgid="2155920810121984215">"फ्ल्यासलाईट नियन्त्रण गर्नुहोस्"</string>
+    <string name="permdesc_flashlight" msgid="6522284794568368310">"फ्ल्यास प्रकाशलाई नियन्त्रण गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_manageUsb" msgid="1113453430645402723">"USB उपकरणहरूको लागि प्राथमिकताहरू र अनुमतिहरू प्रबन्ध गर्नुहोस्"</string>
+    <string name="permdesc_manageUsb" msgid="7776155430218239833">"USB उपकरणहरूको लागि प्राथमिकताहरू र अनुमतिहरूलाई व्यवस्थापन गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_accessMtp" msgid="4953468676795917042">"MTP प्रोटोकल कार्यान्वयन गर्नुहोस्"</string>
+    <string name="permdesc_accessMtp" msgid="6532961200486791570">"MTP USB प्रोटोकल कार्यान्वयन गर्न केर्नल MTP ड्राइभरको पहुँचको अनुमति दिन्छ।"</string>
+    <string name="permlab_hardware_test" msgid="4148290860400659146">"हार्डवेयर परीक्षण गर्नुहोस्"</string>
+    <string name="permdesc_hardware_test" msgid="6597964191208016605">"हार्डवेयर परीक्षणको उद्देश्यका लागि विभिन्न परिधीयहरूलाई नियन्त्रण गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_callPhone" msgid="3925836347681847954">"फोन नम्बरहरूमा सिधै कल गर्नुहोस्"</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"तपाईँको हस्तक्षेप बेगरै फोन नम्बर कल गर्न अनुप्रयोगलाई अनुमति दिन्छ। यसले अनपेक्षित शुल्क वा कलहरू गराउन सक्छ। यसले अनुप्रयोगलाई आपतकालीन नम्बरहरू कल गर्न अनुमति दिँदैन विचार गर्नुहोस्। खराब अनुप्रयोगहरूले तपाईँको स्वीकार बिना कलहरू गरेर तपाईँलाई बढी पैसा तिराउन सक्छ।"</string>
+    <string name="permlab_callPrivileged" msgid="4198349211108497879">"कुनै पनि फोन नम्बरहरू सिधै कल गर्नुहोस्"</string>
+    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"कुनै पनि फोन नम्बरमा, आकस्मिक नम्बर सहित, तपाईँको हस्तक्षेप बिना कल गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ। खराब अनुप्रयोगहरूले अनावश्यक र गैर कानुनी कलहरूलाई आकस्मिकमा स्थानान्तरण गर्न सक्छन्।"</string>
+    <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"CDMA ट्याब्लेट सेटअफ सिधै सुरु गर्नुहोस्"</string>
+    <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"CDMA फोन सेटअप सिधै सुरु गर्नुहोस्"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"अनुप्रयोगलाई CDMA प्रावधान सुरu गर्न अनुमति दिन्छ। खराब अनुप्रयोगहरूले अनावश्यक रूपमा CDMA प्रावधान सुरु गर्न सक्छन्।"</string>
+    <string name="permlab_locationUpdates" msgid="7785408253364335740">"स्थान अपडेट सूचनाहरू नियन्त्रण गर्नुहोस्"</string>
+    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"रेडियोबाट स्थान अद्यावधिक सूचनाहरूलाई सक्षम/असक्षम गर्न अनुप्रयोगलाई अनुमति दिन्छ। सामान्य अनुप्रयोगहरूबाट प्रयोग नहुने।"</string>
+    <string name="permlab_checkinProperties" msgid="7855259461268734914">"परीक्षण विशेषताहरू पहुँच गर्नुहोस्"</string>
+    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"परीक्षण सेवाद्वारा विशेषता अपलोड भएको पहुँच पढ्न/लेख्‍न अनुप्रयोगलाई अनुमति दिन्छ। साधारण अनुप्रयोगद्वारा प्रयोगको लागि होइन।"</string>
+    <string name="permlab_bindGadget" msgid="776905339015863471">"विजेटहरूको चयन गर्नुहोस्"</string>
+    <string name="permdesc_bindGadget" msgid="8261326938599049290">"अनुप्रयोगलाई प्रणालीलाई कुन विजेट कुन अनुप्रयोगद्वारा प्रयोग गर्न सकिन्छ भनेर अनुमति दिन्छ। यस अनुमतिसहितको अनुप्रयोगले अन्य अनुप्रयोगहरूलाई व्यक्तिगत डेटाको पहुँच दिन सक्दछ। सामान्य अनुप्रयोगहरूको प्रयोगको लागि होइन।"</string>
+    <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"फोनको स्थिति परिमार्जन गर्नुहोस्"</string>
+    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"उपकरणका फोन विशेषताहरूलाई नियन्त्रण गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ।  यस अनुमतिले एउटा अनुप्रयोगले नेटवर्क स्विच गर्न, फोन रेडियो बन्द गर्न र खोल्न र जस्तै तपाईँ सधै सूचित नगरी गर्न सक्छ।"</string>
+    <string name="permlab_readPhoneState" msgid="9178228524507610486">"फोन स्थिति र पहिचान पढ्नुहोस्"</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"उपकरणको फोन विशेषताहरूको पहुँच गर्न अनुप्रयोगलाई अनुमति दिन्छ। यस अनुमतिले फोन नम्बर र उपकरणको IDs, कल सक्षम छ कि छैन र कलद्वारा जोडिएको टाढाको नम्बर निर्धारण गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"ट्याब्लेटलाई निन्द्रामा जानबाट रोक्नुहोस्"</string>
+    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"फोनलाई निदाउनबाट रोक्नुहोस्"</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"ट्याब्लेटलाई निस्क्रिय हुनबाट रोक्नको लागि अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"फोनलाई निस्क्रिय हुनबाट रोक्नको लागि अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"ट्याब्लेट पावर खोल्न र बन्द गर्नुहोस्"</string>
+    <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"फोन खोल्न वा बन्द गर्न उर्जा प्रदान गर्नुहोस"</string>
+    <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"ट्याब्लेटलाई खोल्न र बन्द गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"अनुप्रयोगलाई फोन खोल्न र बन्द गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_factoryTest" msgid="3715225492696416187">"फ्याक्ट्रि परीक्षण मोडमा चालु गर्नुहोस्"</string>
+    <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"ट्याब्लेट हार्डवेयरलाई पुरा पहुँच गर्न दिँदै तल्लो स्तर उत्त्पादक परीक्षणको रूपमा चलाउनुहोस्। ट्याब्लेट उत्त्पादक परीक्षण मोडमा चलिरहेको बेला मात्र उपलब्ध हुन्छ।"</string>
+    <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"तल्लो स्तर उत्त्पादक जस्तै चलाउनुहोस्, पुरा पहुँच दिन फोन हार्डवेयरलाई अनुमति हुन्छ। फोन उत्पादक परीक्षण मोडमा चलिरहेको बेला मात्र उपलब्ध हुन्छ।"</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_masterClear" msgid="2315750423139697397">"कार्यशाला पूर्वनिर्धारणको लागि प्रणाली पुनःसेट गर्नुहोस्"</string>
+    <string name="permdesc_masterClear" msgid="3665380492633910226">"यसका फ्याक्ट्रि सेटिङहरू, कन्फिगरेसन र स्थापित अनुप्रयोगहरूलाई प्रणालीमा पुरै पुनःसेट गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_setTime" msgid="2021614829591775646">"समय सेट गर्नुहोस्"</string>
+    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"ट्याब्लेटको घडीको समय बदल्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permdesc_setTime" product="default" msgid="1855702730738020">"फोनको घडीको समय बदल्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_setTimeZone" msgid="2945079801013077340">"समय क्षेत्र सेट गर्नुहोस्"</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"अनुप्रयोगलाई ट्याब्लेटको समय क्षेत्र परिवर्तन गर्न अनुमति दिन्छ।"</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"अनुप्रयोगलाई फोनको समय क्षेत्र परिवर्तन गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_accountManagerService" msgid="4829262349691386986">"AccountManagerService को रूपमा कार्य गर्नुहोस्"</string>
+    <string name="permdesc_accountManagerService" msgid="1948455552333615954">"खाता अधिकारीहरूलाई कल गर्नको लागि अनुप्रयोगले अनुमति दिन्छ।"</string>
+    <string name="permlab_getAccounts" msgid="1086795467760122114">"उपकरणमा खाताहरू भेट्टाउनुहोस्"</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"अनुप्रयोगलाई ट्याब्लेटद्वारा ज्ञात खाताहरूको सूची पाउन अनुमति दिन्छ। यसले अनुप्रयोगद्वारा तपाईंले स्थापित गर्नुभएको कुनै पनि खाताहरू समावेश गर्न सक्दछ।"</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"फोनलाई थाहा भएका खाताहरूको सूची प्राप्त गर्न अनुप्रयोगलाई अनुमति दिन्छ। यसले तपाईँले स्थापना गर्नु भएका अनुप्रयोगहरूबाट सृजित कुनै खाताहरू समावेश हुन सक्छ।"</string>
+    <string name="permlab_authenticateAccounts" msgid="5265908481172736933">"खाता सिर्जना गर्नुहोस् र पासवर्ड सेट गर्नुहोस्"</string>
+    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"खाताहरूको सिर्जना गर्ने र प्राप्त गर्ने र उनीहरूको पासवर्डहरूको सेटिङ गर्ने सहित खाता प्रबन्धकको खाता आधिकारी सक्षमताहरू प्रयोग गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_manageAccounts" msgid="4983126304757177305">"खाताहरू थप्नुहोस् वा हटाउनुहोस्"</string>
+    <string name="permdesc_manageAccounts" msgid="8698295625488292506">"खाताहरू थप्ने र हटाउने जस्ता प्रक्रियाहरू सम्पन्न गर्न, र उनीहरूको पासवर्ड मेटाउन अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_useCredentials" msgid="235481396163877642">"उपकरणमा खाताहरूको प्रयोग गर्नुहोस्"</string>
+    <string name="permdesc_useCredentials" msgid="7984227147403346422">"अनुप्रयोगलाई प्रमाणीकरण टोकनहरू अनुरोध गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_accessNetworkState" msgid="4951027964348974773">"नेटवर्क जडानहरू हेर्नहोस्"</string>
+    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"अनुप्रयोगलाई नेटवर्क जडानहरू जस्तै कुन नेटवर्कहरू अवस्थित हुन्छन् र जडित छन् जसले हेर्नलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"पूर्ण नेटवर्क पहुँच"</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"नेटवर्क सकेटहरू सिर्जना गर्न र कस्टम नेटवर्क प्रोटोकल प्रयोग गर्न अनुप्रयोगलाई अनुमति दिन्छ। ब्राउजर र अन्य अनुप्रयोगहरूले इन्टरनेटमा डेटा पठाउने माध्यम प्रदान गर्छन्, त्यसैले इन्टरनेटमा डेटा पठाउन यो अनुमतिको आवश्यकता पर्दैन।"</string>
+    <string name="permlab_writeApnSettings" msgid="505660159675751896">"नेटवर्क सेटिङहरू र ट्राफिक परिवर्तन गर्नुहोस् / रोक्नुहोस्"</string>
+    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"अनुप्रयोगलाई नेटवर्क सेटिङहरू परिवर्तन गर्न र सबै नेटवर्क ट्राफिक रोक्न र परीक्षण गर्न अनुमति दिन्छ, उदाहरणको लागि कुनै पनि APN को प्रोक्सी र पोर्ट परिवर्तन गर्न। खराब अनुप्रयोगहरूले तपाईंको ज्ञान बिना नेटवर्क प्याकेटहरू मोनिटर गर्न, पुन:निर्देशित गर्न, वा परिमार्जन गर्न सक्दछ।"</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_changeBackgroundDataSetting" msgid="1400666012671648741">"पृष्ठभूमि डेटा प्रयोग सेटिङहरू परिवर्तन गर्नुहोस्"</string>
+    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"अनुप्रयोगलाई पृष्ठभूमि डेटा उपयोग सेटिङ परिवर्तन गर्न अनुमति दिन्छ।"</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">"वाइ-फाइ Multicast स्विकृतिलाई अनुमति दिनुहोस्"</string>
+    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"अनुप्रयोगलाई मल्टिकाष्ट ठेगानाहरू प्रयोग गरेर वाइ-फाइ नेटवर्कमा पठाइएको प्याकेटहरू प्राप्त गर्न अनुमति दिन्छ, केवल तपाईंको ट्याब्लेट मात्र होइन। यसले गैर-मल्टिकाष्ट मोड भन्दा बढी उर्जा प्रयोग गर्दछ।"</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="default" msgid="8931682159331542137">"अनुप्रयोगलाई स्थानीय ब्लुटुथ फोन कन्फिगर गर्न र टाढाका उपकरणहरूसँग खोज गर्न र जोडी गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_accessWimaxState" msgid="4195907010610205703">"WiMAXसँग जोड्नुहोस् वा छुटाउनुहोस्"</string>
+    <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"अनुप्रयोगलाई वाइम्याक्स सक्षम छ कि छैन र जडान भएको कुनै पनि वाइम्याक्स नेटवर्कहरूको बारेमा जानकारी निर्धारिण गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"वाइम्याक्स स्थिति परिवर्तन गर्नुहोस्"</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"अनुप्रयोगलाई वाइम्याक्स नेटवर्कहरूबाट ट्याब्लेट जडान गर्न र ट्याब्लेट विच्छेदन गर्न अनुमति दिन्छ।"</string>
+    <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"वाइम्याक्स नेटवर्कहरूसँग फोन जोड्न र छुटाउन अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_bluetooth" msgid="6127769336339276828">"ब्लुटुथ उपकरणहरूसँग जोडी मिलाउनुहोस्"</string>
+    <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"ट्याब्लेटमा ब्लुटुथको कन्फिगुरेसनलाई हेर्न र बनाउन र जोडी उपकरणहरूसँग जडानहरूलाई स्वीकार गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</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_readSyncSettings" msgid="6201810008230503052">"समीकरण सेटिङहरू पढ्नुहोस्"</string>
+    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"अनुप्रयोगलाई खाताको लागि सिङ्क सेटिङहरू पढ्न अनुमति दिन्छ। उदाहरणको लागि यसले व्यक्तिहरको अनुप्रयोग खातासँग सिङ्क भएको नभएको निर्धारण गर्न सक्दछ।"</string>
+    <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"टगल सिङ्क खुला र बन्द"</string>
+    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"अनुप्रयोगहरूलाई खाताको लागि सिङ्क सेटिङहरू परिमार्जन गर्न अनुमति दिन्छ। उदाहरणको लागि, यो खातासँग व्यक्ति अनुप्रयोगको सिङ्क सक्षम गर्न प्रयोग गर्न सकिन्छ।"</string>
+    <string name="permlab_readSyncStats" msgid="7396577451360202448">"सिङ्क तथ्याङ्कहरू पढ्नुहोस्"</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"अनुप्रयोगलाई खाताको लागि समीकरणको आँकडा समीकरण घटनाहरूको  इतिहास र समीकरण गरिएको डेटाको मापन समेत, पढ्न अनुमति दिन्छ।"</string>
+    <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"सदस्य बनाइका फिडहरू पढ्नुहोस्"</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"अनुप्रयोगलाई अहिलेको समीकरण गरिएका सूचकहरू बारे विवरणहरू लिने अनुमति दिन्छ।"</string>
+    <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"सदस्य बनाइका फिडहरू लेख्नुहोस्"</string>
+    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"तपाईँका भर्खरै सिङ्क फिडहरूलाई परिमार्जन गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ। तपाईँको सिङ्क फिडहरूलाई परिवर्तन गर्नको लागि यसले  खराब अनुप्रयोगलाई अनुमति दिन सक्छ।"</string>
+    <string name="permlab_readDictionary" msgid="4107101525746035718">"तपाईँले शब्दकोशमा थपेका शब्दहरू पढ्नुहोस्"</string>
+    <string name="permdesc_readDictionary" msgid="659614600338904243">"अनुप्रयोगलाई प्रयोगकर्ताले प्रयोगकर्ता शब्दकोशमा भण्डारण गरेका हुन सक्ने सबै शब्दहरू, नामहरू र पदावलीहरू पढ्न अनुमति दिन्छ।"</string>
+    <string name="permlab_writeDictionary" msgid="2183110402314441106">"प्रयोगकर्ता-परिभाषित शब्दकोशमा शब्दहरू थप्नुहोस्।"</string>
+    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"प्रयोगकर्ता शब्दकोशमा नयाँ शब्द लेख्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"सुरक्षित गरिएका भण्डारण पहुँचको परीक्षण गर्नुहोस्"</string>
+    <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"सुरक्षित गरिएका भण्डारण पहुँचको परीक्षण गर्नुहोस्"</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"भविष्य उपकरणहरूमा उपलब्ध हुने USB भण्डारणको लागि अनुमति परीक्षण गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"भविष्य उपकरणहरूमा उपलब्ध हुने 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_mediaStorageWrite" product="default" msgid="6859839199706879015">"आन्तरिक मिडिया भण्डारण सामग्रीहरू परिमार्जन गर्नुहोस्/मेटाउनुहोस्"</string>
+    <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"अनुप्रयोगलाई आन्तरिक मिडिया भण्डारणको सामग्रीहरू परिमार्जन गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"कागजात भण्डारण प्रबन्ध गर्नुहोस्"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"अनुप्रयोगलाई कागजात भण्डारण समायोजन गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"सबै उपयोगकर्ताहरूको बाह्य भण्डारणको पहुँच राख्नुहोस्"</string>
+    <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"अनुप्रयोगलाई सबै उपयोगकर्ताहरूको लागि बाह्य भण्डारणमाथि पहुँच राख्न अनुमति दिन्छ।"</string>
+    <string name="permlab_cache_filesystem" msgid="5656487264819669824">"क्यास फाइल प्रणाली पहुँच गर्नुहोस्।"</string>
+    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"केस फाइल प्रणालीलाई पढ्न र लेख्‍नको लागि अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_use_sip" msgid="5986952362795870502">"इन्टरनेट कलहरू गर्नुहोस् वा प्राप्त गर्नुहोस्"</string>
+    <string name="permdesc_use_sip" msgid="4717632000062674294">"इन्टरनेट कल गर्न/प्राप्त गर्न SIP सेवालाई प्रयोग गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ।"</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_markNetworkSocket" msgid="3658527214914959749">"सकेटको निशानहरू परिवर्तन गर्नुहोस्"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"मार्ग दर्शनको लागि अनुप्रयोगलाई सकेटको निशानहरू परिवर्तन गर्न अनुमति दिन्छ"</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_invokeCarrierSetup" msgid="3699600833975117478">"वाहक-प्रदान विन्यास अनुप्रयोग सुरु गर्नुहोस्"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"प्रयोगकर्तालाई वाहक-प्रदान विन्यास अनुप्रयोग सुरु गर्न अनुमति दिन्छ। साधारण अनुप्रयोगहरूलाई कहिल्यै आवश्यक पर्ने छैन।"</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"सञ्जाल अवस्थाका पर्यवेक्षणका लागि सुन्नुहोस्"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"सञ्जाल अवस्थाका पर्यवेक्षण सुन्नका लागि अनुप्रयोगलाई अनुमति दिन्छ।सामान्य अनुप्रयोगलाई चाँहिदै नचाँहिन सक्छ।"</string>
+    <string name="permlab_hotwordRecognition" msgid="3225080408746361313">"जल्दोबल्दो शब्द पहिचानका लागि अनुरोध गर्नुहोस्"</string>
+    <string name="permdesc_hotwordRecognition" msgid="3716741260195364252">"जल्दाबल्दा शब्द पहिचानका लागि अनुरोध पठाउन अनुप्रयोगलाई अनुमति दिन्छ।सामान्य अनुप्रयोगका लागि यो कहिल्यै नचाहिन सक्छ।"</string>
+    <string name="policylab_limitPassword" msgid="4497420728857585791">"पासवर्ड नियमहरू मिलाउनुहोस्"</string>
+    <string name="policydesc_limitPassword" msgid="3252114203919510394">"स्क्रिन-अनलक पासवर्डहरूमा अनुमति दिइएको लम्बाइ र अक्षरहरू नियन्त्रण गर्नुहोस्।"</string>
+    <string name="policylab_watchLogin" msgid="914130646942199503">"मोनिटर स्क्रिन-अनलक प्रयत्नहरू"</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"स्क्रिन अनलक गर्दा गलत पासवर्ड टाइप भएको संख्या निरीक्षण गर्नुहोस् र यदि निकै धेरै गलत पासवर्डहरू टाइप भएका छन भने ट्याब्लेट लक गर्नुहोस् वा ट्याब्लेटका सबै डेटा मेट्नुहोस्।"</string>
+    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"स्क्रिनअनलक गर्दा गलत पासवर्ड टाइप भएको संख्या निरीक्षण गर्नुहोस् र यदि निकै धेरै गलत पासवर्डहरू टाइप भएका छन भने फोन लक गर्नुहोस् वा फोनका सबै डेटा मेट्नुहोस्।"</string>
+    <string name="policylab_resetPassword" msgid="2620077191242688955">"स्क्रिन-अनलक पासवर्ड बदल्नुहोस्"</string>
+    <string name="policydesc_resetPassword" msgid="605963962301904458">"स्क्रिन-अनलक पासवर्ड परिवर्तन गर्नुहोस्।"</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="default" msgid="5096895604574188391">"एउटा फ्याक्ट्रि डेटा पुनःसेट गरेर चेतावनी नआउँदै फोनको डेटा मेट्नुहोस्।"</string>
+    <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"उपकरण विश्वव्यापी प्रोक्सी मिलाउनुहोस्"</string>
+    <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"नीति सक्षम हुँदा प्रयोग हुने उपकरण  विश्वव्यापी प्रोक्सी सेट गर्नुहोस्। प्रथम उपकरण प्रशासशनले मात्र प्रभावकारी विश्वव्यापी प्रोक्सी सेट गर्छ।"</string>
+    <string name="policylab_expirePassword" msgid="885279151847254056">"लक-स्क्रिन पासवर्ड अन्त सेट गर्नुहोस्"</string>
+    <string name="policydesc_expirePassword" msgid="1729725226314691591">"प्रायः कति छिटो लक-स्क्रिन पासवर्ड बदल्नु पर्छ यसलाई नियन्त्रण गर्नुहोस्।"</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="policylab_disableKeyguardFeatures" msgid="266329104542638802">"किगार्डमा भएका विशेषताहरू असक्षम पार्नुहोस्"</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="3467082272186534614">"केही किगार्ड विशेषताहरूको प्रयोग रोक्नुहोस्।"</string>
+  <string-array name="phoneTypes">
+    <item msgid="8901098336658710359">"गृह"</item>
+    <item msgid="869923650527136615">"मोबाइल"</item>
+    <item msgid="7897544654242874543">"काम गर्नुहोस्"</item>
+    <item msgid="1103601433382158155">"कार्य फ्याक्स"</item>
+    <item msgid="1735177144948329370">"घरको फ्याक्स"</item>
+    <item msgid="603878674477207394">"पेजर"</item>
+    <item msgid="1650824275177931637">"अन्य"</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>
+  </string-array>
+  <string-array name="postalAddressTypes">
+    <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="1359644565647383708">"काम"</item>
+    <item msgid="7868549401053615677">"अन्य"</item>
+    <item msgid="3145118944639869809">"अनुकूलन"</item>
+  </string-array>
+  <string-array name="organizationTypes">
+    <item msgid="7546335612189115615">"काम गर्नुहोस्"</item>
+    <item msgid="4378074129049520373">"अन्य"</item>
+    <item msgid="3455047468583965104">"अनुकूलन"</item>
+  </string-array>
+  <string-array name="imProtocols">
+    <item msgid="8595261363518459565">"AIM"</item>
+    <item msgid="7390473628275490700">"Windows Live"</item>
+    <item msgid="7882877134931458217">"Yahoo"</item>
+    <item msgid="5035376313200585242">"स्काइप"</item>
+    <item msgid="7532363178459444943">"QQ"</item>
+    <item msgid="3713441034299660749">"Google Talk"</item>
+    <item msgid="2506857312718630823">"ICQ"</item>
+    <item msgid="1648797903785279353">"Jabber"</item>
+  </string-array>
+    <string name="phoneTypeCustom" msgid="1644738059053355820">"अनुकूलन"</string>
+    <string name="phoneTypeHome" msgid="2570923463033985887">"गृह"</string>
+    <string name="phoneTypeMobile" msgid="6501463557754751037">"मोबाइल"</string>
+    <string name="phoneTypeWork" msgid="8863939667059911633">"काम"</string>
+    <string name="phoneTypeFaxWork" msgid="3517792160008890912">"कार्य फ्याक्स"</string>
+    <string name="phoneTypeFaxHome" msgid="2067265972322971467">"घरको फ्याक्स"</string>
+    <string name="phoneTypePager" msgid="7582359955394921732">"पेजर"</string>
+    <string name="phoneTypeOther" msgid="1544425847868765990">"अन्य"</string>
+    <string name="phoneTypeCallback" msgid="2712175203065678206">"कलब्याक"</string>
+    <string name="phoneTypeCar" msgid="8738360689616716982">"कार"</string>
+    <string name="phoneTypeCompanyMain" msgid="540434356461478916">"कम्पनी मुख्य"</string>
+    <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string>
+    <string name="phoneTypeMain" msgid="6766137010628326916">"मुख्य"</string>
+    <string name="phoneTypeOtherFax" msgid="8587657145072446565">"अन्य फ्याक्स"</string>
+    <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="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="eventTypeBirthday" msgid="2813379844211390740">"जन्मदिन"</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>
+    <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="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="imTypeWork" msgid="1371489290242433090">"काम"</string>
+    <string name="imTypeOther" msgid="5377007495735915478">"अन्य"</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>
+    <string name="imProtocolSkype" msgid="9019296744622832951">"स्काइप"</string>
+    <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
+    <string name="imProtocolGoogleTalk" msgid="493902321140277304">"ह्याङआउटहरू"</string>
+    <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">"काम"</string>
+    <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="relationTypeBrother" msgid="8757913506784067713">"भाइ"</string>
+    <string name="relationTypeChild" msgid="1890746277276881626">"बच्चो"</string>
+    <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"आन्तरिक साझेदार"</string>
+    <string name="relationTypeFather" msgid="5228034687082050725">"बुबा"</string>
+    <string name="relationTypeFriend" msgid="7313106762483391262">"मित्र"</string>
+    <string name="relationTypeManager" msgid="6365677861610137895">"ब्यवस्थापक"</string>
+    <string name="relationTypeMother" msgid="4578571352962758304">"आमा"</string>
+    <string name="relationTypeParent" msgid="4755635567562925226">"अभिभावक"</string>
+    <string name="relationTypePartner" msgid="7266490285120262781">"पार्टनर"</string>
+    <string name="relationTypeReferredBy" msgid="101573059844135524">"द्वारा उल्लिखित"</string>
+    <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="sipAddressTypeHome" msgid="6093598181069359295">"गृह"</string>
+    <string name="sipAddressTypeWork" msgid="6920725730797099047">"काम गर्नुहोस्"</string>
+    <string name="sipAddressTypeOther" msgid="4408436162950119849">"अन्य"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN कोड टाइप गर्नुहोस्"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK र नयाँ PIN कोड टाइप गर्नुहोस्"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK कोड"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"नयाँ PIN कोड"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><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">"अनलक गर्न PIN कोड टाइप गर्नुहोस्"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"गलत PIN कोड।"</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"अनलक गर्न मेनु थिच्नुहोस् र त्यसपछि ० थिच्नुहोस्।"</string>
+    <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"आपतकालीन नम्बर"</string>
+    <string name="lockscreen_carrier_default" msgid="8963839242565653192">"सेवा छैन।"</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="5347633784401285225">"आपतकालीन कलहरू"</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="faceunlock_multiple_failures" msgid="754137583022792429">"अत्याधिक मोहडा खोल्ने प्रयासहरू बढी भए।"</string>
+    <string name="lockscreen_plugged_in" msgid="8057762828355572315">"चार्ज हुँदै, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_charged" msgid="321635745684060624">"चार्ज भयो"</string>
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_low_battery" msgid="1482873981919249740">"तपाईँको चार्जर जोड्नुहोस्।"</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="default" msgid="2186920585695169078">"फोनमा SIM कार्ड छैन।"</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_transport_prev_description" msgid="201594905152746886">"अघिल्लो ट्रयाक बटन"</string>
+    <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"अर्को ट्रयाक बटन"</string>
+    <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"रोक्ने बटन"</string>
+    <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"बजाउने बटन"</string>
+    <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"बटन रोक्नुहोस्"</string>
+    <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">"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">%d</xliff:g> पटक खिच्नु भएको छ। \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकेन्डमा फेरि कोसिस गर्नुहोस्।"</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"तपाईंले गलत तरिकाले आफ्नो पासवर्ड <xliff:g id="NUMBER_0">%d</xliff:g> पटक टाइप गर्नुभयो। \n\n<xliff:g id="NUMBER_1">%d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"तपाईँले गलत तरिकाले तपाईँको PIN <xliff:g id="NUMBER_0">%d</xliff:g> पटक टाइप गर्नु भएको छ। \n\n<xliff:g id="NUMBER_1">%d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"तपाईँले तपाईँको अनलक ढाँचा गलत तरिकाले <xliff:g id="NUMBER_0">%d</xliff:g> पटक खिच्नु भएको छ। पछि <xliff:g id="NUMBER_1">%d</xliff:g> थप असफल कोसिसहरू, तपाईँको Google साइन इन प्रयोग गरी तपाईँको ट्याब्लेट अनलक गर्न भनिने छ।\n\n  <xliff:g id="NUMBER_2">%d</xliff:g> सेकेन्डमा फरि प्रयास गर्नुहोस्।"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"तपाईँले <xliff:g id="NUMBER_0">%d</xliff:g> पटक गलत तरिकाले तपाईँको अनलक ढाँचालाई कोर्नु भएको छ। पछि <xliff:g id="NUMBER_1">%d</xliff:g> अरू धेरै असफल कोसिसहरूपछि, तपाईँलाई तपाईँको फोन Google साइन इन प्रयोग गरेर अनलक गर्नको लागि सोधिने छ। \n\n <xliff:g id="NUMBER_2">%d</xliff:g> सेकेन्डमा पुनः प्रयास गर्नुहोस्।"</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"तपाईँले <xliff:g id="NUMBER_0">%d</xliff:g> पटक ट्याब्लेटलाई अनलक गर्नको लागि गलत तरिकाले कोशिस गर्नुभएको छ। <xliff:g id="NUMBER_1">%d</xliff:g> अरू धेरै असफल कोसिसहरूपछि, ट्याब्लेट फ्याट्रि पूर्वनिर्धारितमा पुनःसेट हुने छ र सबै प्रयोगकर्ता डेटा हराउने छन्।"</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"तपाईंले गलत तरिकाले <xliff:g id="NUMBER_0">%d</xliff:g> पटक फोन अनलक गर्ने प्रयत्न गर्नुभयो। <xliff:g id="NUMBER_1">%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="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_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_checking_password" msgid="7114627351286933867">"जाँच गर्दै..."</string>
+    <string name="lockscreen_unlock_label" msgid="737440483220667054">"खोल्नुहोस्"</string>
+    <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"आवाज चालु छ।"</string>
+    <string name="lockscreen_sound_off_label" msgid="996822825154319026">"ध्वनि बन्द"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"ढाँचा सुरु भयो"</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"ढाँचा हटाइएको"</string>
+    <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"सेल थप गरियो"</string>
+    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"ढाँचा पुरा भयो"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. विजेट %2$d of %3$d।"</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_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>
+    <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_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">"Pin अनलक"</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">"?१२३"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <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_line" msgid="5764267235026120888">"लाइन"</string>
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
+    <string name="factorytest_failed" msgid="5410270329114212041">"कार्यशाला परीक्षण असफल भयो।"</string>
+    <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST कार्रवाइले /system/app मा स्थापित प्याकेजहरूको लागि मात्र समर्थन गर्छ।"</string>
+    <string name="factorytest_no_action" msgid="872991874799998561">"कुनै प्याकेज फेला पार्न सकिएन जसले FACTORY_TEST कार्य प्रदान गर्दछ।"</string>
+    <string name="factorytest_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>
+    <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="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>
+    <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$१$२$३"</string>
+    <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
+    <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
+    <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">"ZIP कोड"</string>
+    <string name="autofill_county" msgid="237073771020362891">"काउन्टी"</string>
+    <string name="autofill_island" msgid="4020100875984667025">"टापु"</string>
+    <string name="autofill_district" msgid="8400735073392267672">"जिल्ला"</string>
+    <string name="autofill_department" msgid="5343279462564453309">"विभाग"</string>
+    <string name="autofill_prefecture" msgid="2028499485065800419">"प्रशासकीय क्षेत्र"</string>
+    <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="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_packageVerificationAgent" msgid="5568139100645829117">"प्यकेजहरूको निरीक्षण गर्नुहोस्"</string>
+    <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"प्याकेज स्थापना योग्य छ कि भनेर रुजु गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"एउटा प्याकेज रुजुकर्तामा बाँध्नुहोस्"</string>
+    <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"होल्डरलाई प्याकेज प्रमाणितकर्ताहरूको अनुरोधहरू बनाउन अनुमति दिन्छ। सामान्य अनुप्रयोगहरूलाई कहिले पनि आवश्यक नपर्न सक्दछ।"</string>
+    <string name="permlab_serialPort" msgid="546083327654631076">"पहुँच सिरियल पोर्टहरू"</string>
+    <string name="permdesc_serialPort" msgid="2991639985224598193">"होल्डरलाई SerialManager API प्रयोग गरेर सिरियल पोर्टहरू पहुँच गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"विषयसूची प्रदातालाई बाह्य रूपमा पहुँच गर्नुहोस्"</string>
+    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"सेलबाट धारकले विषयवस्तु प्रदायकहरूसम्मको पहुँच पाउन अनुमति दिन्छ। सामान्य अनुप्रयोगहरूलाई कहिल्यै आवश्यक पर्दैन।"</string>
+    <string name="permlab_updateLock" msgid="3527558366616680889">"स्वचालित उपकरण अपडेटहरू हतोत्साहित गर्नुहोस्"</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"होल्डरलाई उपकरण अपग्रेड गर्न गैर पारस्परिक पुनःबुटको लागि उचित समयको बारेमा प्रणालीमा जानाकारी प्रस्तावको लागि अनुमति दिन्छ।"</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>
+    <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="menu_space_shortcut_label" msgid="2410328639272162537">"ठाउँ"</string>
+    <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"प्रविष्टि गर्नुहोस्"</string>
+    <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"मेटाउनुहोस्"</string>
+    <string name="search_go" msgid="8298016669822141719">"खोज्नुहोस्"</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="oneMonthDurationPast" msgid="7396384508953779925">"१ महिना अघि"</string>
+    <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"१ महिना अघि"</string>
+  <plurals name="num_seconds_ago">
+    <item quantity="one" msgid="4869870056547896011">"१ सेकेन्ड अघि"</item>
+    <item quantity="other" msgid="3903706804349556379">"<xliff:g id="COUNT">%d</xliff:g> सेकेन्ड अघि"</item>
+  </plurals>
+  <plurals name="num_minutes_ago">
+    <item quantity="one" msgid="3306787433088810191">"१ मिनेट अघि"</item>
+    <item quantity="other" msgid="2176942008915455116">"<xliff:g id="COUNT">%d</xliff:g> मिनेट अघि"</item>
+  </plurals>
+  <plurals name="num_hours_ago">
+    <item quantity="one" msgid="9150797944610821849">"१ घन्टा अघि"</item>
+    <item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> घन्टा अघि"</item>
+  </plurals>
+  <plurals name="last_num_days">
+    <item quantity="other" msgid="3069992808164318268">"अन्तिम <xliff:g id="COUNT">%d</xliff:g> दिन"</item>
+  </plurals>
+    <string name="last_month" msgid="3959346739979055432">"अन्तिम महिना"</string>
+    <string name="older" msgid="5211975022815554840">"पुरानो"</string>
+  <plurals name="num_days_ago">
+    <item quantity="one" msgid="861358534398115820">"हिजो"</item>
+    <item quantity="other" msgid="2479586466153314633">"<xliff:g id="COUNT">%d</xliff:g> दिन अघि"</item>
+  </plurals>
+  <plurals name="in_num_seconds">
+    <item quantity="one" msgid="2729745560954905102">"१ सेकेन्डमा"</item>
+    <item quantity="other" msgid="1241926116443974687">"<xliff:g id="COUNT">%d</xliff:g> सेकेन्डमा"</item>
+  </plurals>
+  <plurals name="in_num_minutes">
+    <item quantity="one" msgid="8793095251325200395">"१ मिनेटमा"</item>
+    <item quantity="other" msgid="3330713936399448749">"<xliff:g id="COUNT">%d</xliff:g>मिनेटमा"</item>
+  </plurals>
+  <plurals name="in_num_hours">
+    <item quantity="one" msgid="7164353342477769999">"१ घन्टामा"</item>
+    <item quantity="other" msgid="547290677353727389">"<xliff:g id="COUNT">%d</xliff:g> घन्टामा"</item>
+  </plurals>
+  <plurals name="in_num_days">
+    <item quantity="one" msgid="5413088743009839518">"भोलि"</item>
+    <item quantity="other" msgid="5109449375100953247">"<xliff:g id="COUNT">%d</xliff:g> दिनमा"</item>
+  </plurals>
+  <plurals name="abbrev_num_seconds_ago">
+    <item quantity="one" msgid="1849036840200069118">"१ सेकेन्ड अघि"</item>
+    <item quantity="other" msgid="3699169366650930415">"<xliff:g id="COUNT">%d</xliff:g> सेकेन्ड अगाडि"</item>
+  </plurals>
+  <plurals name="abbrev_num_minutes_ago">
+    <item quantity="one" msgid="6361490147113871545">"१ मिनेट अघि"</item>
+    <item quantity="other" msgid="851164968597150710">"<xliff:g id="COUNT">%d</xliff:g> मिनेट अघि"</item>
+  </plurals>
+  <plurals name="abbrev_num_hours_ago">
+    <item quantity="one" msgid="4796212039724722116">"१ घन्टा अघि"</item>
+    <item quantity="other" msgid="6889970745748538901">"<xliff:g id="COUNT">%d</xliff:g> घन्टा अघि"</item>
+  </plurals>
+  <plurals name="abbrev_num_days_ago">
+    <item quantity="one" msgid="8463161711492680309">"हिजो"</item>
+    <item quantity="other" msgid="3453342639616481191">"<xliff:g id="COUNT">%d</xliff:g> दिन अघि"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_seconds">
+    <item quantity="one" msgid="5842225370795066299">"१ सेकन्ड"</item>
+    <item quantity="other" msgid="5495880108825805108">"<xliff:g id="COUNT">%d</xliff:g> सेकेन्डमा"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_minutes">
+    <item quantity="one" msgid="562786149928284878">"१ मिनेटमा"</item>
+    <item quantity="other" msgid="4216113292706568726">"<xliff:g id="COUNT">%d</xliff:g> मिनेटमा"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_hours">
+    <item quantity="one" msgid="3274708118124045246">"१ घन्टामा"</item>
+    <item quantity="other" msgid="3705373766798013406">"<xliff:g id="COUNT">%d</xliff:g> घन्टामा"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_days">
+    <item quantity="one" msgid="2178576254385739855">"भोलि"</item>
+    <item quantity="other" msgid="2973062968038355991">"दिन<xliff:g id="COUNT">%d</xliff:g> मा"</item>
+  </plurals>
+    <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>
+    <string name="days" msgid="4774547661021344602">"दिन"</string>
+    <string name="hour" msgid="2126771916426189481">"घन्टा"</string>
+    <string name="hours" msgid="894424005266852993">"घन्टा"</string>
+    <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="week" msgid="5617961537173061583">"हप्ता"</string>
+    <string name="weeks" msgid="6509623834583944518">"हप्ताहरू"</string>
+    <string name="year" msgid="4001118221013892076">"वर्ष"</string>
+    <string name="years" msgid="6881577717993213522">"वर्षहरू"</string>
+  <plurals name="duration_seconds">
+    <item quantity="one" msgid="6962015528372969481">"१ सेकेन्ड"</item>
+    <item quantity="other" msgid="1886107766577166786">"<xliff:g id="COUNT">%d</xliff:g> सेकेन्ड"</item>
+  </plurals>
+  <plurals name="duration_minutes">
+    <item quantity="one" msgid="4915414002546085617">"१ मिनेट"</item>
+    <item quantity="other" msgid="3165187169224908775">"<xliff:g id="COUNT">%d</xliff:g> मिनेट"</item>
+  </plurals>
+  <plurals name="duration_hours">
+    <item quantity="one" msgid="8917467491248809972">"१ घन्टा"</item>
+    <item quantity="other" msgid="3863962854246773930">"<xliff:g id="COUNT">%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_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>
+    <string name="midnight" msgid="7166259508850457595">"मध्यरात"</string>
+    <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="cut" msgid="3092569408438626261">"काट्नुहोस्"</string>
+    <string name="copy" msgid="2681946229533511987">"प्रतिलिपि बनाउनुहोस्"</string>
+    <string name="paste" msgid="5629880836805036433">"टाँस्नुहोस्"</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="textSelectionCABTitle" msgid="5236850394370820357">"पाठ चयनता"</string>
+    <string name="addToDictionary" msgid="4352161534510057874">"शब्दकोशमा थप्नुहोस्"</string>
+    <string name="deleteText" msgid="6979668428458199034">"मेट्नुहोस्"</string>
+    <string name="inputMethod" msgid="1653630062304567879">"निवेश विधि"</string>
+    <string name="editTextMenuTitle" msgid="4909135564941815494">"पाठ कार्यहरू"</string>
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"भण्डारण ठाउँ सकिँदै छ"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"सायद केही प्रणाली कार्यक्रमहरूले काम गर्दैनन्"</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="4653586947747330058">"थप सूचनाको लागि छुनुहोस् वा अनुप्रयोग बन्द गर्नुहोस्।"</string>
+    <string name="ok" msgid="5970060430562524910">"ठिक छ"</string>
+    <string name="cancel" msgid="6442560571259935130">"रद्द गर्नुहोस्"</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>
+    <string name="capital_on" msgid="1544682755514494298">"चालु"</string>
+    <string name="capital_off" msgid="6815870386972805832">"बन्द"</string>
+    <string name="whichApplication" msgid="4533185947064773386">"प्रयोग गरेर कारबाही पुरा गर्नुहोस्"</string>
+    <string name="alwaysUse" msgid="4583018368000610438">"यस कार्यको लागि पूर्वनिर्धारितबाट प्रयोग गर्नुहोस्।"</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="aerr_title" msgid="1905800560317137752"></string>
+    <string name="aerr_application" msgid="932628488013092776">"दुर्भाग्यवश, <xliff:g id="APPLICATION">%1$s</xliff:g>ले रोकेको छ।"</string>
+    <string name="aerr_process" msgid="4507058997035697579">"दुर्भाग्यवश, प्रक्रिया <xliff:g id="PROCESS">%1$s</xliff:g> बन्द भयो।"</string>
+    <string name="anr_title" msgid="4351948481459135709"></string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g>ले कार्य गरिरहेको छैन।\n\nके तपाईँ यसलाई बन्द गर्न चाहनु हुन्छ?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"गतिविधि <xliff:g id="ACTIVITY">%1$s</xliff:g> ले प्रतिक्रिया देखाइरहेको छैन।\n\nके तपाईं यसलाई बन्द गर्न चाहनु हुन्छ?"</string>
+    <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> जवाफ दिइरहेको छैन। के तपाईँ यसलाई बन्द गर्न चाहनु हुन्छ?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"प्रक्रिया <xliff:g id="PROCESS">%1$s</xliff:g>ले कार्य गरिरहेको छैन।\n\nके तपाईँ यसलाई बन्द गर्न चाहनु हुन्छ?"</string>
+    <string name="force_close" msgid="8346072094521265605">"ठिक छ"</string>
+    <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_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; अनुप्रयोगहरू &gt; डाउनलोड गरेको।"</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">"एन्ड्रोइड अपग्रेड हुँदैछ…"</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_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="1721681741617898865">"अनुप्रयोगमा स्विच गर्न छुनुहोस्"</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>
+    <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="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_silent_ringtone_selected" msgid="8310739960973156272">"शान्त रिङ्गटोन सेट"</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">"ब्लुटुथ भोल्युम"</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="8129563480895990372">"पूर्वनिर्धारित रिङटोन (<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_unknown" msgid="5477919988701784788">"अज्ञात रिङटोन"</string>
+  <plurals name="wifi_available">
+    <item quantity="one" msgid="6654123987418168693">"वाइ-फाइ नेटवर्क उपलब्ध छ"</item>
+    <item quantity="other" msgid="4192424489168397386">"वाइ-फाइ नेटवर्कहरू उपलब्ध"</item>
+  </plurals>
+  <plurals name="wifi_available_detailed">
+    <item quantity="one" msgid="1634101450343277345">"खुल्ला वाइ-फाइ नेटवर्क उपलब्ध छ"</item>
+    <item quantity="other" msgid="7915895323644292768">"खुल्ला वाइ-फाइ नेटवर्क उपलब्ध छ"</item>
+  </plurals>
+    <string name="wifi_available_sign_in" msgid="4029489716605255386">"वाइ-फाइ नेटवर्कमा साइन गर्नुहोस्"</string>
+    <string name="network_available_sign_in" msgid="8495155593358054676">"नेटवर्कमा साइन गर्नुहोस्।"</string>
+    <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
+    <skip />
+    <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"वाइ-फाइसँग जडान गर्न सकेन"</string>
+    <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" कमजोर इन्टरनेट जडान छ।"</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="1638949953993894335">"सेटिङहरूको लागि छुनुहोस्"</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_to_connect_title" msgid="4958803948658533637">"जडानमा निमन्त्रणा"</string>
+    <string name="wifi_p2p_from_message" msgid="570389174731951769">"बाट:"</string>
+    <string name="wifi_p2p_to_message" msgid="248968974522044099">"प्रापक:"</string>
+    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"आवश्यक PIN टाइप गर्नुहोस्:"</string>
+    <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</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="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="3492025719868078457">"यसले "<font fgcolor="#ffffb060">" शुल्क लगाउन सक्छ"</font>" तपाईँको मोबाइल खातामा।"</string>
+    <string name="sms_premium_short_code_details" msgid="5523826349105123687"><font fgcolor="#ffffb060">"यसले तपाईंको मोबाइल खातामा चार्जहरू उत्पन्न गर्दछ।"</font></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_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_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="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_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="usb_storage_activity_title" msgid="4465055157209648641">"USB ठूलो भण्डारण"</string>
+    <string name="usb_storage_title" msgid="5901459041398751495">"USB जोडिएको छ"</string>
+    <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"तपाईं आफ्नो कम्प्युटरमा USB मार्फत जडान हुनुभयो। तलको बटन टच गर्नुहोस् यदि तपाईं आफ्नो कम्प्युटर र एन्ड्रोइडको USB भण्डारण बीच फाइलहरू प्रतिलिपि गर्न चाहनुहुन्छ भने।"</string>
+    <string name="usb_storage_message" product="default" msgid="805351000446037811">"तपाईं आफ्नो कम्प्युटरमा USB मार्फत जडान हुनुभयो। तलको बटन टच गर्नुहोस् यदि तपाईं आफ्नो कम्प्युटर र एन्ड्रोइडको SD कार्ड बीच फाइलहरू प्रतिलिपि गर्न चाहनुहुन्छ भने।"</string>
+    <string name="usb_storage_button_mount" msgid="1052259930369508235">"USB भण्डारण चालु गर्नुहोस्"</string>
+    <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"USB आम भण्डारणको लागि तपाईँको USB भण्डारण प्रयोग गर्दा एउटा समस्या भयो।"</string>
+    <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"USB आम भण्डारणको लागि तपाईँको SD कार्ड प्रयोग गर्दा एउटा समस्या भयो।"</string>
+    <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB जोडिएको छ"</string>
+    <string name="usb_storage_notification_message" msgid="939822783828183763">"तपाईँको कम्प्युटरबाट वा तिर फाइलहरू प्रतिलिप गर्न छुनुहोस्।"</string>
+    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"USB भण्डारण बन्द गर्नुहोस्"</string>
+    <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"USB भण्डारण बन्द गर्न छुनुहोस्।"</string>
+    <string name="usb_storage_stop_title" msgid="660129851708775853">"USB भण्डारण प्रयोगमा छ"</string>
+    <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"USB भण्डारण बन्द हुनुभन्दा पहीले तपाईँको कम्प्युटरबाट तपाईँको एन्ड्रोइड USB भण्डारण अनमाउन्ट (\"झिक्नुहोस्\") गर्नुहोस् ।"</string>
+    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"USB भण्डारण बन्द गर्नुअघि तपाईँको कम्प्युटरबाट तपाईँको एन्ड्रोइडको SD कार्ड अनमाउन्ट (\"निकालेको\") गर्नुहोस्।"</string>
+    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"USB भण्डारण बन्द गर्नुहोस्"</string>
+    <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"USB भण्डारण बन्द गर्दा एउटा समस्या भयो। तपाईँले USB होस्ट अनमाउन्ट गर्नु भएको जाँच गर्नुहोस्, त्यसपछि फेरि प्रयास गर्नुहोस्।"</string>
+    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"USB भण्डारण खोल्नुहोस्"</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"यदि तपाईँले USB भण्डारण खोल्नु भयो भने तपाईँले प्रयोग गरिरहनु भएका केही अनुप्रयोगहरू रोकिने छन् र तपाईँले USB भण्डारण बन्द नगरेसम्म अनुपलब्ध हुन सक्छन्।"</string>
+    <string name="dlg_error_title" msgid="7323658469626514207">"USB संचालन असफल"</string>
+    <string name="dlg_ok" msgid="7376953167039865701">"ठिक छ"</string>
+    <string name="usb_mtp_notification_title" msgid="3699913097391550394">"मिडिया उपकरणको रूपमा जडित"</string>
+    <string name="usb_ptp_notification_title" msgid="1960817192216064833">"क्यामेराको रूपमा जडान भएको"</string>
+    <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"एउटा स्थापनकर्ताको रूपमा जोडिएको छ"</string>
+    <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB सहायकमा जोडिएको छ"</string>
+    <string name="usb_notification_message" msgid="2290859399983720271">"अन्य USB विकल्पहरूको लागि टच गर्नुहोस्।"</string>
+    <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB भण्डारणलाई फर्म्याट  गर्न चाहनु हुन्छ?"</string>
+    <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD कार्ड फर्म्याट गर्ने?"</string>
+    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"तपाईंको USBमा सङ्ग्रह भएका सबै फाइलहरू मेटिने छन्। यो कार्य उल्टाउन सकिँदैन!"</string>
+    <string name="extmedia_format_message" product="default" msgid="14131895027543830">"तपाईँको कार्डमा भएका सबै डेटाहरू हराउने छन्।"</string>
+    <string name="extmedia_format_button_format" msgid="4131064560127478695">"फर्म्याट गर्नुहोस्"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"USB डिबग गर्ने जडित छ"</string>
+    <string name="adb_active_notification_message" msgid="1016654627626476142">"USB डिबग गर्ने असक्षम पार्न छुनुहोस्।"</string>
+    <string name="select_input_method" msgid="4653387336791222978">"निवेश विधि छान्नुहोस्"</string>
+    <string name="configure_input_methods" msgid="9091652157722495116">"इनपुट विधिहरू सेटअप गर्नुहोस्"</string>
+    <string name="use_physical_keyboard" msgid="6203112478095117625">"भौतिक किबोर्ड"</string>
+    <string name="hardware" msgid="7517821086888990278">"हार्डवेयर"</string>
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"किबोर्ड रूपरेखा चयन गर्नुहोस्"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"किबोर्ड रूपरेखा चयन गर्न टच गर्नुहोस्।"</string>
+    <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="candidates_style" msgid="4333913089637062257"><u>"उम्मेदवार"</u></string>
+    <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"USB भण्डारणको तयारी हुँदै"</string>
+    <string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"SD कार्ड तयार गर्दै"</string>
+    <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"त्रुटिहरूको लागि जाँच गर्दै।"</string>
+    <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"रिक्त USB भण्डारण"</string>
+    <string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"खाली SD कार्ड"</string>
+    <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"USB भण्डारण खाली वा असमर्थित फाइल प्रणाली छ।"</string>
+    <string name="ext_media_nofs_notification_message" product="default" msgid="8641065641786923604">"SD कार्ड खाली छ अथवा समर्थन नगरिएको फाइल प्रणाली छ।"</string>
+    <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"बिग्रिएको USB भण्डारण"</string>
+    <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"बिग्रिएको SD कार्ड"</string>
+    <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="1795917578395333280">"USB भण्डारण बिग्रिएको छ। यसलाई पुनःफर्म्याट गर्न प्रयास गर्नुहोस।"</string>
+    <string name="ext_media_unmountable_notification_message" product="default" msgid="1753898567525568253">"SD कार्ड बिग्रिएको छ। यसलाई पुनःफर्म्याट गर्न प्रयास गर्नुहोस।"</string>
+    <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"USB भण्डारण अप्रत्याशित रूपमा हटाइएको छ"</string>
+    <string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"SD कार्ड अनपेक्षित रूपमा हटाइयो"</string>
+    <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"डेटा गुम्नबाट रोक्नको लागि USB भण्डारण हटाउनुअघि अनमाउन्ट गर्नुहोस्।"</string>
+    <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"डेटा नाश हुनबाट बच्न SD कार्डलाई निकाल्नुभन्दा पहिला अनमाउन्ट गर्नुहोस्।"</string>
+    <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"USB भण्डारण हटाउनको लागि सुरक्षित छ"</string>
+    <string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"SD कार्ड हटाउन सुरक्षित छ।"</string>
+    <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"तपाईं सुरक्षित रूपमा USB भण्डारण हटाउन सक्नुहुने छ।"</string>
+    <string name="ext_media_safe_unmount_notification_message" product="default" msgid="568841278138377604">"तपाईँ SD कार्ड सुरक्षित रूपमा हटाउन सक्नु हुन्छ।"</string>
+    <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"USB भण्डारण हटाइयो"</string>
+    <string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"हटाइएको SD कार्ड"</string>
+    <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"USD भण्डारण हटाइयो। नयाँ मिडिया घुसाउनुहोस्।"</string>
+    <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"SD कार्ड हटाइयो। एउटा नयाँ छिराउनुहोस्।"</string>
+    <string name="activity_list_empty" msgid="1675388330786841066">"कुनै मिल्ने गतिविधि पाइएन।"</string>
+    <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"खण्ड प्रयोग तथ्याङ्कहरू अपडेट गर्नुहोस्"</string>
+    <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"जम्मा गरिएको घटक उपयोग तथ्याङ्कहरूलाई परिमार्जन गर्न अनुप्रयोगलाई अनुमति दिन्छ। सामान्य अनुप्रयोगहरूबाट प्रयोगको लागि होइन।"</string>
+    <string name="permlab_copyProtectedData" msgid="4341036311211406692">"सामाग्रीको नकल गर्नुहोस्"</string>
+    <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"अनुप्रयोगलाई सामग्री प्रतिलिपि गर्न पूर्वनिर्धारित कन्टेनर सेवा आह्वान गर्न अनुमति दिन्छ। साधारण अनुप्रयोगहरूद्वाराको प्रयोगको लागि होइन।"</string>
+    <string name="permlab_route_media_output" msgid="1642024455750414694">"मिडिया परिणाम दिशानिर्देश गर्नुहोस्"</string>
+    <string name="permdesc_route_media_output" msgid="4932818749547244346">"मिडिया परिणामलाई अन्य बाहिरी उपकरणहरूसँग लैजानको लागि अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"किगार्ड सुरक्षित भण्डारण पहुँच गर्नुहोस्"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"अनुप्रयोगलाई किगार्ड सुरक्षित भण्डारण पहुँच गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"किगार्ड प्रदर्शन गर्ने र लुकाउने नियन्त्रण गर्नुहोस्"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"अनुप्रयोगलाई किगार्ड नियन्त्रण गर्न अनुमति दिन्छ।"</string>
+    <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"जुम नियन्त्रणको लागि दुई चोटि टच गर्नुहोस्"</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>
+    <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">\n"नम्बर डायल गर्नुहोस् <xliff:g id="NUMBER">%s</xliff:g> प्रयोग गरेर"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"सम्पर्क सिर्जना गर्नुहोस्\nयो <xliff:g id="NUMBER">%s</xliff:g> प्रयोग गरेर"</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"निम्न एउटा वा धेरै अनुप्रयोगहरूले तपाईँको खातामा पहुँचको लागि अनुमति अहिले र भविष्यमा अनुरोध गर्छन्।"</string>
+    <string name="grant_credentials_permission_message_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">\n"खाता <xliff:g id="ACCOUNT">%s</xliff:g>को लागि अनुरोध गरिएको अनुमति।"</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>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"वालपेपर परिवर्तन गर्नुहोस्"</string>
+    <string name="notification_listener_binding_label" msgid="2014162835481906429">"सूचना सुन्नेवाला"</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="3011306607126450322">"नेटवर्क प्रबन्ध गर्न छुनुहोस्।"</string>
+    <string name="vpn_text_long" msgid="6407351006249174473">"<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_error" msgid="6009249814034708175">"सधैँ भरि VPN त्रुटिमा"</string>
+    <string name="vpn_lockdown_config" msgid="6415899150671537970">"कन्फिगर गर्न टच गर्नुहोस्"</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="8035230537563503262">"कार मोडबाट निस्कन छुनुहोस्।"</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"टेथर गर्ने वा हटस्पट सक्रिय"</string>
+    <string name="tethered_notification_message" msgid="6857031760103062982">"सेटअप गर्न टच गर्नुहोस्।"</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="throttle_warning_notification_title" msgid="4890894267454867276">"उच्च मोबाइल डेटा प्रयोग"</string>
+    <string name="throttle_warning_notification_message" msgid="3340822228599337743">"मोबाइल डेटा प्रयोगको बारेमा अरू थप जान्नको लागि  छुनुहोस्।"</string>
+    <string name="throttled_notification_title" msgid="6269541897729781332">"मोबाइल डेटा सीमा पार भयो"</string>
+    <string name="throttled_notification_message" msgid="5443457321354907181">"मोबाइल डेटा प्रयोग बारे थप सिक्न छुनुहोस्।"</string>
+    <string name="no_matches" msgid="8129421908915840737">"कुनै मिलेन"</string>
+    <string name="find_on_page" msgid="1946799233822820384">"पृष्ठमा फेला पार्नुहोस्"</string>
+  <plurals name="matches_found">
+    <item quantity="one" msgid="8167147081136579439">"१ मेल"</item>
+    <item quantity="other" msgid="4641872797067609177">"<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="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"USB  भण्डारण अनमाउन्ट गर्दै..."</string>
+    <string name="progress_unmounting" product="default" msgid="1327894998409537190">"SD कार्ड अनमाउन्ट गर्दै…"</string>
+    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"USB भण्डारण मेटाउँदै…"</string>
+    <string name="progress_erasing" product="default" msgid="6596988875507043042">"SD कार्ड मेटाउँदै…"</string>
+    <string name="format_error" product="nosdcard" msgid="6299769563624776948">"USB भण्डारणलाई मेटाउन सकेन।"</string>
+    <string name="format_error" product="default" msgid="7315248696644510935">"SD कार्ड मेटाउन सकेन"</string>
+    <string name="media_bad_removal" msgid="7960864061016603281">"SD कार्ड अनमाउन्ट हुनुभन्दा पहिला निकालियो।"</string>
+    <string name="media_checking" product="nosdcard" msgid="418188720009569693">"अहिले USB भण्डारण जाँच भइरहेको छ।"</string>
+    <string name="media_checking" product="default" msgid="7334762503904827481">"SD कार्ड अहिले परीक्षण भइरहेको छ।"</string>
+    <string name="media_removed" msgid="7001526905057952097">"SD कार्ड हटाइयो।"</string>
+    <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"SD कार्ड कम्प्युटरद्वारा अहिले प्रयोगमा छ।"</string>
+    <string name="media_shared" product="default" msgid="5706130568133540435">"SD कार्ड अहिले कम्प्युटरद्वारा प्रयोगमा छ।"</string>
+    <string name="media_unknown_state" msgid="729192782197290385">"बाह्य मिडिया अज्ञात अवस्थामा।"</string>
+    <string name="share" msgid="1778686618230011964">"साझेदारी गर्नुहोस्"</string>
+    <string name="find" msgid="4808270900322985960">"पत्ता लगाउनुहोस्"</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="gpsNotifMessage" msgid="1374718023224000702">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>) द्वारा अनुरोध गरिएको"</string>
+    <string name="gpsVerifYes" msgid="2346566072867213563">"हो"</string>
+    <string name="gpsVerifNo" msgid="1146564937346454865">"होइन"</string>
+    <string name="sync_too_many_deletes" msgid="5296321850662746890">"सीमा नाघेकाहरू मेट्नुहोस्"</string>
+    <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"त्यहाँ <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> मेटाइएका आइटमहरू छन् <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>को लागि, खाता <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>। तपाईं के गर्न चाहनु हुन्छ?"</string>
+    <string name="sync_really_delete" msgid="2572600103122596243">"वस्तुहरू मेट्नुहोस्"</string>
+    <string name="sync_undo_deletes" msgid="2941317360600338602">"मेटिएकाहरू पूर्ववत बनाउनुहोस्।"</string>
+    <string name="sync_do_nothing" msgid="3743764740430821845">"अहिलेको लागि केही नगर्नुहोस्"</string>
+    <string name="choose_account_label" msgid="5655203089746423927">"एउटा खाता छान्‍नुहोस्"</string>
+    <string name="add_account_label" msgid="2935267344849993553">"एउटा खाता थप्नुहोस्"</string>
+    <string name="add_account_button_label" msgid="3611982894853435874">"खाता थप गर्नुहोस्"</string>
+    <string name="number_picker_increment_button" msgid="2412072272832284313">"बढाउनुहोस्"</string>
+    <string name="number_picker_decrement_button" msgid="476050778386779067">"घटाउनुहोस्"</string>
+    <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g>छुनुहोस् र समाउनुहोस्।"</string>
+    <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"बढाउन माथि र घटाउन तल सार्नुहोस्।"</string>
+    <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"मिनेट बढाउनुहोस्"</string>
+    <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"मिनेट घटाउनुहोस्"</string>
+    <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"घन्टा बढाउनुहोस्"</string>
+    <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"घन्टा घटाउनुहोस्"</string>
+    <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"PM सेट गर्नुहोस्"</string>
+    <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"AM सेट गर्नुहोस्"</string>
+    <string name="date_picker_increment_month_button" msgid="5369998479067934110">"महिना बढाउनुहोस्"</string>
+    <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"महिना घटाउनुहो्स्"</string>
+    <string name="date_picker_increment_day_button" msgid="7130465412308173903">"दिन बढाउनुहोस्"</string>
+    <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"दिन घटाउनुहोस्"</string>
+    <string name="date_picker_increment_year_button" msgid="6318697384310808899">"वर्ष बढाउनुहोस्"</string>
+    <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"वर्ष घटाउनुहोस्"</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_enter" msgid="2985864015076059467">"प्रविष्टि गर्नुहोस्"</string>
+    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"एउटा अनुप्रयोग छान्नुहोस्"</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_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>को लागि माथि धिसार्नुहोस्"</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"<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="description_direction_right" msgid="8034433242579600980">"स्लाइड <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>को लागि दायाँ।"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"अनलक गर्नुहोस्"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"क्यामेरा"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"मौन"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"आवाज चालू"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"खोज्नुहोस्"</string>
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"खोल्नलाइ हुत्त्याउनुहोस्।"</string>
+    <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"बोलिएको पासवर्ड कुञ्जीहरू सुन्नको लागि हेडसेट प्लग इन गर्नुहोस्।"</string>
+    <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"डट।"</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="4891916833657929263">"आन्तरिक भण्डारण"</string>
+    <string name="storage_sd_card" msgid="3282948861378286745">"SD कार्ड"</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="1955638862122232342">"डेटा प्रयोग चेतावनी"</string>
+    <string name="data_usage_warning_body" msgid="2814673551471969954">"उपयोग र सेटिङहरू हेर्न छुनुहोस्।"</string>
+    <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-3G डेटा असक्षम गरिएको"</string>
+    <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G डेटा असक्षम गरियो"</string>
+    <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"मोबाइल डेटा असक्षम पारियो।"</string>
+    <string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"वाइ-फाइ डेटा असक्षम गरियो"</string>
+    <string name="data_usage_limit_body" msgid="3317964706973601386">"सक्षम पार्न छुनुहोस्।"</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 डेटा SIMा नाघ्यो"</string>
+    <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"मोवाइल डेटा SIMा नाघ्यो"</string>
+    <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"वाइ-फाइ डेटा SIMा नाघ्यो"</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="6741521330997452990">"अवरोध हटाउन छुनुहोस्।"</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>
+    <string name="org_unit" msgid="7265981890422070383">"संगठनात्मक एकाइ:"</string>
+    <string name="issued_by" msgid="2647584988057481566">"द्वारा जारी गरिएको:"</string>
+    <string name="validity_period" msgid="8818886137545983110">"मान्यता:"</string>
+    <string name="issued_on" msgid="5895017404361397232">"जारी गरिएको:"</string>
+    <string name="expires_on" msgid="3676242949915959821">"अवधि समाप्त:"</string>
+    <string name="serial_number" msgid="758814067660862493">"क्रम संख्या:"</string>
+    <string name="fingerprints" msgid="4516019619850763049">"औँठाछापहरू:"</string>
+    <string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-२५६ औंठाछाप:"</string>
+    <string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 औंलाछाप:"</string>
+    <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"सबै हेर्नुहोस्"</string>
+    <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"गतिविधि छनौट गर्नुहोस्"</string>
+    <string name="share_action_provider_share_with" msgid="5247684435979149216">"साझेदारी गर्नुहोस्..."</string>
+    <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="3245653681008218030">"पठाउँदै..."</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="default_audio_route_name" product="tablet" msgid="4617053898167127471">"ट्याब्लेट"</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">"ब्लुटुथ अडियो"</string>
+    <string name="wireless_display_route_description" msgid="9070346425023979651">"ताररहित प्रदर्शन"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"भयो"</string>
+    <string name="media_route_button_content_description" msgid="5758553567065145276">"मिडियाको उत्पादन"</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>
+    <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_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="wifi_display_notification_title" msgid="2223050649240326557">"ताररहित प्रदर्शन जोडिएको छ"</string>
+    <string name="wifi_display_notification_message" msgid="4498802012464170685">"अर्को उपकरणमा यो स्क्रिनले देखाइरहेको छ"</string>
+    <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"विच्छेदन गर्नुहोस्"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"आपतकालीन कल"</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">"गलत PIN"</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">"SIM PIN प्रविष्टि गर्नुहोस्"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN प्रविष्टि गर्नुहोस्"</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">"इच्छित PIN कोड प्रविष्टि गर्नुहोस्"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"मनपर्दो PIN कोड निश्चित गर्नुहोस्"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM कार्ड अनलक गर्दै…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"गलत PIN कोड।"</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"४ देखि ८ वाट नम्बर भएको एउटा PIN टाइप गर्नुहोस्।"</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK कोड ८ वटा नम्बर वा सो भन्दा बढी हुनुपर्छ।"</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"PUK कोड पुन:प्रदान गर्नुहोस्। धेरै पुन:प्रयासहरूले SIMलाई स्थायी रूपमा निष्क्रिय गरिदिने छ।"</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN कोडहरू मेल खाएन"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"निकै धेरै ढाँचा कोसिसहरू"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"अनलक गर्नको लागि, तपाईँको Google खाताको साथ साइन इन गर्नुहोस्।"</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"खाता जाँच हुँदै…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"तपाईँले गलत तरिकाले तपाईँको PIN <xliff:g id="NUMBER_0">%d</xliff:g> पटक टाइप गर्नु भएको छ। \n\n<xliff:g id="NUMBER_1">%d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"तपाईँले तपाईँक पासवर्ड <xliff:g id="NUMBER_0">%d</xliff:g> पटक गलत टाइप गर्नुभएको छ। \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"तपाईँले तपाईँको अनलक ढाँचा गलत तरिकाले <xliff:g id="NUMBER_0">%d</xliff:g> पटक खिच्नु भएको छ। \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकेन्डमा फेरि कोसिस गर्नुहोस्।"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"तपाईँले ट्याब्लेटलाई अनलक गर्न गलत तरिकाले <xliff:g id="NUMBER_0">%d</xliff:g> पटक कोसिस गर्नु भएको छ। <xliff:g id="NUMBER_1">%d</xliff:g> पछि थप असफल प्रयासहरू, ट्याब्लेट पूर्वनिर्धारित कार्यशालामा पुनःसेट गरिने छ र सबै प्रयोग डेटा हराउने छ।"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"तपाईँले गलतसँग फोनलाई अनलक गर्न <xliff:g id="NUMBER_0">%d</xliff:g> पटक कोसिस गर्नु भयो। <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> पटक कोर्नुभयो। <xliff:g id="NUMBER_1">%d</xliff:g> विफल प्रयत्नहरू पछि, तपाईंलाई आफ्नो ट्याब्लेट इमेल खाता प्रयोग गरेर अनलक गर्न सोधिने छ।\n\n फेरि प्रयास गर्नुहोस् <xliff:g id="NUMBER_2">%d</xliff:g> सेकेन्डहरूमा।"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"तपाईँले आफ्नो अनलक ढाँचा गलत रूपमा <xliff:g id="NUMBER_0">%d</xliff:g> पटक तान्नु भएको छ। <xliff:g id="NUMBER_1">%d</xliff:g> धेरै असफल प्रयासहरूपछि, तपाईँलाई एउटा इमेल खाताको प्रयोग गरेर तपाईँको फोन अनलक गर्न सोधिने छ।\n\n फेरि <xliff:g id="NUMBER_2">%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="7324161939475478066">"आवाज सल्लाह दिएको तहभन्दा माथि  बढाउने हो?\nठूलो आवाजमा सुन्दा लामो समयको लागि तपाईँको सुन्ने शक्तीलाई खत्तम पार्न सक्छ।"</string>
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"उपलब्धता सक्षम पार्न दुईवटा औंलाहरूले थिचिरहनुहोस्।"</string>
+    <string name="accessibility_enabled" msgid="1381972048564547685">"पहुँच सक्षम गरिएको।"</string>
+    <string name="enable_accessibility_canceled" msgid="3833923257966635673">"पहुँचयोग्यता रद्द गरियो।"</string>
+    <string name="user_switched" msgid="3768006783166984410">"अहिलेको प्रयोगकर्ता <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="app_no_restricted_accounts" msgid="5739463249673727736">"प्रतिबन्धित प्रोफाइलहरूको लागि यस अनुप्रयोगले खाताहरू समर्थन गर्दैन"</string>
+    <string name="app_not_found" msgid="3429141853498927379">"यस कार्य सम्हालने कुनै अनुप्रयोग भेटिएन"</string>
+    <string name="revoke" msgid="5404479185228271586">"रद्द गर्नुहोस्"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"पत्र"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"सरकारी पत्र"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"कानूनी"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"रद्द गरियो"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"सामाग्री लेखनमा त्रुटि"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"अज्ञात"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"प्रशासक 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>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"नयाँ PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"नयाँ PIN निश्चित गर्नुहोस्"</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_too_short" msgid="8173982756265777792">"PIN अति छोटो भयो। कम्तीमा ४ अङ्क हुन आवश्यक छ।"</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"१ सेकेन्ड पछि पुनः प्रयास गर्नुहोस्।"</item>
+    <item quantity="other" msgid="4730868920742952817">"<xliff:g id="COUNT">%d</xliff:g> सेकेन्डमा पुनः प्रयास गर्नुहोस्"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"पछि पुनः प्रयास गर्नुहोस्"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"पट्टि देखिने बनाउन स्क्रिनको छेउमा स्वाइप गर्नुहोस्"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"प्रणाली पट्टि देखिने बनाउन स्क्रिनको छेउबाट स्वाइप गर्नुहोस्"</string>
+</resources>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
new file mode 100644
index 0000000..b6e4fc3
--- /dev/null
+++ b/core/res/res/values-ne/strings.xml
@@ -0,0 +1,1588 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<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="5973789783504771878">"KB"</string>
+    <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
+    <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
+    <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
+    <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
+    <string name="untitled" msgid="4638956954852782576">"&lt;बिना शीर्षक&gt;"</string>
+    <string name="ellipsis" msgid="7899829516048813237">"…"</string>
+    <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
+    <string name="emptyPhoneNumber" msgid="7694063042079676517">"(कुनै फोन नम्बर छैन)"</string>
+    <string name="unknownName" msgid="2277556546742746522">"(अज्ञात)"</string>
+    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"भ्वाइस मेल"</string>
+    <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN१"</string>
+    <string name="mmiError" msgid="5154499457739052907">"जडान समस्या वा अमान्य MMI कोड।"</string>
+    <string name="mmiFdnError" msgid="5224398216385316471">"अपरेशन निश्चित डायल नम्बरहरूको लागि मात्र प्रतिबन्धित छ।"</string>
+    <string name="serviceEnabled" msgid="8147278346414714315">"सेवा सक्षम पारियो।"</string>
+    <string name="serviceEnabledFor" msgid="6856228140453471041">"निम्न उल्लेखितको लागि सेवा सक्षम पारियो:"</string>
+    <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="mmiComplete" msgid="8232527495411698359">"MMI पुरा भयो।"</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 टाइप गर्नुहोस्।"</string>
+    <string name="invalidPuk" msgid="8761456210898036513">"८ वटा नम्बरहरू वा सो भन्दा लामो एउटा PUK टाइप गर्नुहोस्।"</string>
+    <string name="needPuk" msgid="919668385956251611">"तपाईंको SIM कार्ड PUK-लक छ। यसलाई अनलक गर्न PUK कोड टाइप गर्नुहोस्।"</string>
+    <string name="needPuk2" msgid="4526033371987193070">"SIM कार्ड अनलक गर्न PUK2 टाइप गर्नुहोस्।"</string>
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
+    <string name="ClipMmi" msgid="6952821216480289285">"आगमन कलर ID"</string>
+    <string name="ClirMmi" msgid="7784673673446833091">"बाहिरिने कलर ID"</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">"PIN परिवर्तन"</string>
+    <string name="CnipMmi" msgid="3110534680557857162">"प्रस्तुत नम्बरमा कल गर्दै"</string>
+    <string name="CnirMmi" msgid="3062102121430548731">"कल गर्ने अंक रोकेको छ।"</string>
+    <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="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="RestrictedChangedTitle" msgid="5592189398956187498">"प्रतिबन्धित पहुँच परिवर्तन भएको छ"</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="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">"Async"</string>
+    <string name="serviceClassDataSync" msgid="7530000519646054776">"सिङ्क गर्नुहोस्"</string>
+    <string name="serviceClassPacket" msgid="6991006557993423453">"प्याकेट"</string>
+    <string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
+    <string name="roamingText0" msgid="7170335472198694945">"रोमिङ सूचक खुला"</string>
+    <string name="roamingText1" msgid="5314861519752538922">"रोमिङ सूचक बन्द"</string>
+    <string name="roamingText2" msgid="8969929049081268115">"रोमिङ सूचक फ्ल्यास गर्दै"</string>
+    <string name="roamingText3" msgid="5148255027043943317">"छिमेकबाट बाहिर"</string>
+    <string name="roamingText4" msgid="8808456682550796530">"बिल्डिङको बाहिर"</string>
+    <string name="roamingText5" msgid="7604063252850354350">"रोमिङ - उपयुक्त प्रणाली"</string>
+    <string name="roamingText6" msgid="2059440825782871513">"रोमिङ - उपलब्ध प्रणाली"</string>
+    <string name="roamingText7" msgid="7112078724097233605">"रोमिङ - एलियन्सर पार्टनर"</string>
+    <string name="roamingText8" msgid="5989569778604089291">"रोमिङ - प्रिमियम पार्टनर"</string>
+    <string name="roamingText9" msgid="7969296811355152491">"रोमिङ - पूर्ण सेवा कार्यक्षमता अवस्था"</string>
+    <string name="roamingText10" msgid="3992906999815316417">"रोमिङ - आङ्शिक सेवा प्रकार्यता"</string>
+    <string name="roamingText11" msgid="4154476854426920970">"रोमिङ ध्वजा चालु छ"</string>
+    <string name="roamingText12" msgid="1189071119992726320">"रोमिङ ब्यानर बन्द छ"</string>
+    <string name="roamingTextSearching" msgid="8360141885972279963">"सेवाको खोजी गर्दै…"</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="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="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="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="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="default" msgid="3475999286680000541">"फोन भण्डारण भरिएको छ! ठाउँ खाली गर्नको लागि केही फाइलहरू मेटाउनुहोस्।"</string>
+    <string name="me" msgid="6545696007631404292">"मलाई"</string>
+    <string name="power_dialog" product="tablet" msgid="8545351420865202853">"ट्याब्लेट विकल्पहरू"</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="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="shutdown_progress" msgid="2281079257329981203">"बन्द गर्दै..."</string>
+    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"तपाईँको ट्याब्लेट बन्द हुने छ।"</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="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_bug_report" msgid="7934010578922304799">"बग रिपोर्ट"</string>
+    <string name="bugreport_title" msgid="2667494803742548533">"बग रिपोर्ट लिनुहोस्"</string>
+    <string name="bugreport_message" msgid="398447048750350456">"एउटा इमेल सन्देशको रूपमा पठाउनलाई यसले तपाईँको हालैको उपकरणको अवस्थाको बारेमा सूचना जम्मा गर्ने छ। बग रिपोर्ट सुरु गरेदेखि पठाउन तयार नभएसम्म यसले केही समय लिन्छ; कृपया धैर्य गर्नुहोस्।"</string>
+    <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_airplane_mode_on_status" msgid="2719557982608919750">"उडान मोड खुला छ"</string>
+    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"हवाइजहाज मोड बन्द छ"</string>
+    <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"९९९+"</string>
+    <string name="safeMode" msgid="2788228061547930246">"सुरक्षित मोड"</string>
+    <string name="android_system_label" msgid="6577375335728551336">"एन्ड्रोइड प्रणाली"</string>
+    <string name="permgrouplab_costMoney" msgid="5429808217861460401">"तपाईँले तिर्नु पर्ने सेवाहरू"</string>
+    <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"तपाईँलाई महँगो पर्न सक्ने कामहरू गर्नुहोस्।"</string>
+    <string name="permgrouplab_messages" msgid="7521249148445456662">"तपाईंका सन्देशहरू"</string>
+    <string name="permgroupdesc_messages" msgid="7821999071003699236">"तपाईँका SMS, इमेल र अन्य सन्देशहरू पढ्नुहोस् र लेख्नुहोस्।"</string>
+    <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"तपाईँको निजी सूचना"</string>
+    <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"तपाईँको सम्पर्क कार्डमा भण्डारण भएका तपाईँको बारेको जानकारीमा सिधा पहुँच पुर्‍याउनुहोस्।"</string>
+    <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"तपाईँको सामाजिक सूचना"</string>
+    <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"तपाईँको सम्पर्कहरू र सामाजिक जडानहरूको बारेको जानकारीमा सिधा पहुँच पुर्‍याउनुहोस्।"</string>
+    <string name="permgrouplab_location" msgid="635149742436692049">"तपाईँको स्थान"</string>
+    <string name="permgroupdesc_location" msgid="5704679763124170100">"तपाईँको भौतिक स्थान निरीक्षण गर्नुहोस्।"</string>
+    <string name="permgrouplab_network" msgid="5808983377727109831">"नेटवर्क संचार"</string>
+    <string name="permgroupdesc_network" msgid="4478299413241861987">"विभिन्न नेटवर्क सुविधाहरूमा पहुँच राख्नुहोस्।"</string>
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"ब्लुटुथ"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"ब्लुटुथको माध्यमद्वारा उपकरणहरू र नेटवर्कहरूमाथि पहुँच राख्नुहोस्।"</string>
+    <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"अडियो सेटिङहरू"</string>
+    <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"अडियो सेटिङहरू बदल्नुहोस्।"</string>
+    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"ब्यट्रिलाई प्रभाव पार्छ"</string>
+    <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"छिट्टै ब्याट्रि सकाउन सक्ने ती विशेषताहरू प्रयोग गर्नुहोस्।"</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"पात्रो"</string>
+    <string name="permgroupdesc_calendar" msgid="5777534316982184416">"पात्रो तथा घटनाहरूमा प्रत्यक्ष पहुँच"</string>
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"प्रयोगकर्ता शब्दकोश पढ्नुहोस्"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"प्रयोगकर्ता शब्दकोशमा शब्दहरू पढ्नुहोस्।"</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"प्रयोगकर्ता शब्दकोश लेख्नुहोस्"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"प्रयोगकर्ता शब्दकोशमा शब्दहरू थप्नुहोस्।"</string>
+    <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"बुकमार्कहरू र इतिहास"</string>
+    <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"बुकमार्कहरू र ब्राउजर इतिहासमा सिधा पहुँच।"</string>
+    <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"अलार्म"</string>
+    <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"अलार्म घडी सेट गर्नुहोस्।"</string>
+    <string name="permgrouplab_voicemail" msgid="4162237145027592133">"भ्वाइस मेल"</string>
+    <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"भ्वाइसमेलमा सिधा पहुँच।"</string>
+    <string name="permgrouplab_microphone" msgid="171539900250043464">"माइक्रोफोन"</string>
+    <string name="permgroupdesc_microphone" msgid="7106618286905738408">"मा[क्रोफोनबाट रेकर्ड अडियोमा सिधा पहुँच पुर्‍याउनुहोस्।"</string>
+    <string name="permgrouplab_camera" msgid="4820372495894586615">"क्यामेरा"</string>
+    <string name="permgroupdesc_camera" msgid="2933667372289567714">"तस्बिर वा भिडियो क्याप्चरको लागि क्यामेरामा सिधा पहुँच।"</string>
+    <string name="permgrouplab_screenlock" msgid="8275500173330718168">"स्क्रिन लक गर्नुहोस्"</string>
+    <string name="permgroupdesc_screenlock" msgid="7067497128925499401">"तपाईँको उपकरणमा लक स्क्रिनको व्यवहारलाई प्रभावित गर्ने क्षमता।"</string>
+    <string name="permgrouplab_appInfo" msgid="8028789762634147725">"तपाईँका अनुप्रयोगहरूको सूचना"</string>
+    <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"तपाईँको उपकरणमा अन्य अनुप्रयोगहरूको व्यवहारमा प्रभाव पार्ने क्षमता।"</string>
+    <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"वालपेपर"</string>
+    <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"उपकरण वालपेपर सेटिङहरू बदल्नुहोस्।"</string>
+    <string name="permgrouplab_systemClock" msgid="406535759236612992">"घडी"</string>
+    <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"उपकरण समय वा समय क्षेत्र परिवर्तन गर्नुहोस्।"</string>
+    <string name="permgrouplab_statusBar" msgid="2095862568113945398">"स्थिति पट्टी"</string>
+    <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"उपकरण स्थिति सेटिङहरू परिवर्तन गर्नुहोस्।"</string>
+    <string name="permgrouplab_syncSettings" msgid="3341990986147826541">"सिङ्क सेटिङहरू"</string>
+    <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"सिङ्क सेटिङहरूमा पहुँच गर्नुहोस्।"</string>
+    <string name="permgrouplab_accounts" msgid="3359646291125325519">"तपाईँका खाताहरू"</string>
+    <string name="permgroupdesc_accounts" msgid="4948732641827091312">"उपलब्ध खाताहरू पहुँच गर्नुहोस्।"</string>
+    <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"हार्डवेयर नियन्त्रणहरू"</string>
+    <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"ह्यान्डसेटको हार्डवेयरमा प्रत्यक्ष पहुँच।"</string>
+    <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"फोन कलहरू"</string>
+    <string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"अनुगमन, रेकर्ड र फोन कलहरूको प्रसोधन गर्नुहोस।"</string>
+    <string name="permgrouplab_systemTools" msgid="4652191644082714048">"प्रणाली औजारहरू"</string>
+    <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"निम्न-स्तर पहुँच र प्रणालीको नियन्त्रण"</string>
+    <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"विकसित टुलहरू"</string>
+    <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"अनुप्रयोग विकासकर्ताहरूको लागि मात्र सुविधाहरूको आवश्यकता।"</string>
+    <string name="permgrouplab_display" msgid="4279909676036402636">"अन्य अनुप्रयोग UI"</string>
+    <string name="permgroupdesc_display" msgid="6051002031933013714">"अन्य अनुप्रयोगहरूको UI लाई असर पार्नुहोस्"</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"भण्डारण"</string>
+    <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"USB भण्डारणमाथि पहुँच गर्नुहोस्।"</string>
+    <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"SD कार्डमाथि पहुँच गर्नुहोस्।"</string>
+    <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"पहुँचीकरण विशेषताहरू"</string>
+    <string name="permgroupdesc_accessibilityFeatures" msgid="4205196881678144335">"सहयोगी प्रविधि भएको विशेषताहरूले अनुरोध गर्न सक्छन्।"</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="5800552516779249356">"छोइएका आइटमहरू चर्को स्वरमा बोलिने छ र स्क्रिन इशाराहरूको प्रयोगले अन्वेषण गर्न सकिन्छ।"</string>
+    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"उच्च वेब पहुँचलाई सुचारु गर्नुहोस्"</string>
+    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"अनुप्रयोगको सामग्रीलाई थप पहुँचयोग्य बनाउन लिपिहरू स्थापना गर्न सक्नु हुन्छ।"</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"आफुले टाइप गरेको पाठको निरीक्षण गर्नुहोस्"</string>
+    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"व्यक्तिगत डेटा जस्तै क्रेडिट कार्ड नम्बरहरू र पासवर्डहरू समावेश गर्दछ।"</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"स्थिति पट्टिलाई अक्षम वा संशोधित गर्नुहोस्"</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"स्थिति पट्टि असक्षम पार्न वा प्रणाली आइकनहरू थप्न र हटाउन अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_statusBarService" msgid="7247281911387931485">"स्थिति पट्टि"</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_processOutgoingCalls" msgid="3906007831192990946">"बहिर्गमन कलहरूलाई अर्को मार्ग दिनुहोस्"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"बहिर्गमन कलहरूको प्रशोधन गर्न र डायल गरिने नम्बर परिवर्तन गर्न अनुप्रयोगलाई अनुमति दिन्छ।  यो अनुमतिले अनुप्रयोगलाई मोनिटर गर्न, अन्यत्र पठाउन वा बाहिर जाने कलहरूलाई रोक्न दिन्छ।"</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_receiveEmergencyBroadcast" msgid="1803477660846288089">"आकस्मिक प्रसारणहरू प्राप्त गर्नुहोस्"</string>
+    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"अनुप्रयोगलाई आपतकालीन प्रसारण सन्देशहरू प्राप्त गर्न र प्रक्रिया गर्न अनुमति दिन्छ। यो अनुमति प्रणाली अनुप्रयोगहरूमा मात्र उपलब्ध छ।"</string>
+    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"सेल प्रसारित सन्देशहरू पढ्नुहोस्"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"तपाईंको उपकरणद्वारा प्राप्त सेल प्रसारण सन्देशहरू अनुप्रयोगलाई पढ्न अनुमति दिन्छ। सेल प्रसारण चेतावनीहरू केही स्थानहरूमा तपाईंलाई आपतकालीन गतिविधिहरूको बारेमा सचेत गराउन गरिएका छन्। खराब अनुप्रयोगहरूले एउटा आपतकालीन सेल प्रसारण प्राप्त गर्दछ जब तपाईंको उपकरणको प्रदर्शन वा अपरेशनको साथ हस्तक्षेप गर्न सक्दछन्।"</string>
+    <string name="permlab_sendSms" msgid="5600830612147671529">"SMS सन्देशहरू पठाउनुहोस्"</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"अनुप्रयोगलाई SMS सन्देशहरू पठाउन अनुमति दिन्छ। यसले अप्रत्यासित चार्जहरूको परिणाम दिन सक्दछ। खराब अनुप्रयोगहरूले तपाईंको पुष्टि बिना सन्देशहरू पठाएर तपाईंको पैसा खर्च गराउन सक्दछ।"</string>
+    <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"प्रतिक्रिया-मार्फत-सन्देश घटनाहरू पठाउनुहोस्"</string>
+    <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"अनुप्रयोगलाई आगत कलहरूको लागि प्रतिक्रिया-मार्फत-सन्देश घटनाहरूलाई अन्य सन्देश पठाउने अनुप्रयोगहरूमा अनुरोधहरू पठाउन अनुमति दिन्छ।"</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"तपाईंका पाठ सन्देशहरू (SMS वा MMS) पढ्नुहोस्"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"तपाईँको ट्याब्लेट वा SIM कार्डमा भण्डारण भएका SMS सन्देशहरूलाई पढ्न अनुप्रयोगलाई अनुमति दिन्छ। यसले अनुप्रयोगलाई विषयवस्तु वा गोपनीयतालाई वेवास्ता गर्दै सबै SMS सन्देशहरू पढ्ने अनुमति दिन्छ।"</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"तपाईँको फोन वा SIM कार्डमा भण्डारण भएका SMS सन्देशहरूलाई पढ्न अनुप्रयोगलाई अनुमति दिन्छ। यसले सबै SMS सन्देशहरूलाई पढ्नको लागि सामग्री वा विश्वसनियता बिना नै अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_writeSms" msgid="3216950472636214774">"तपाईँका पाठ सन्देशहरू सम्पादन गर्नुहोस् (SMS वा MMS)"</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"अनुप्रयोगलाई तपाईंको ट्याब्लेट वा SIM कार्डमा भण्डार गरिएका SMS सन्देशहरू लेख्न अनुमति दिन्छ। खराब अनुप्रयोगहरूले तपाईंको सन्देशहरू मेटाउन सक्दछ।"</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"तपाईँको फोन वा SIM कार्डमा भण्डारण भएका 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_interactAcrossUsers" msgid="7114255281944211682">"प्रयोगकर्ताहरू तर्फ अन्तर्क्रिया गर्नुहोस्"</string>
+    <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"अनुप्रयोगलाई उपकरणमा विभिन्न प्रयोगकर्ताहरू मार्फत कार्यहरू गर्न अनुमति दिन्छ। खराब अनुप्रयोगहरूले यो प्रयोगकर्ताहरू बिच सुरक्षा बिथोल्न प्रयोग गर्न सक्ने छन्।"</string>
+    <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"कुराकानी प्रयोगकर्ताहरू बिच अन्तर्क्रिया गर्न पूर्ण अनुमति"</string>
+    <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"प्रयोगकर्तासँगको कुराकानी सबै सम्भावनालाई अनुमति दिन्छ।"</string>
+    <string name="permlab_manageUsers" msgid="1676150911672282428">"प्रयोगकर्ताहरू व्यवस्थापन गर्नुहोस्"</string>
+    <string name="permdesc_manageUsers" msgid="8409306667645355638">"अनुप्रयोगलाई उपकरणमा, प्रश्न, सिर्जना र मेटाइसहित प्रयोगकर्ताहरूको प्रबन्ध गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"चलिरहेका अनुप्रयोगहरूको विवरण पुनःबहाली गर्नुहोस्"</string>
+    <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"वर्तमानमा र भरखरै चलिरहेका कार्यहरूको बारेमा विस्तृत सूचना पुनःबहाली गर्न अनुप्रयोगलाई अनुमति दिन्छ। खराब अनुप्रयोगहरूले अन्य अनुप्रयोगहरू बारेको निजी सूचना पत्ता लगाउन सक्छ।"</string>
+    <string name="permlab_reorderTasks" msgid="2018575526934422779">"चलिरहेका अनुप्रयोगहरूलाई पुनःक्रम गराउनुहोस्"</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"कामहरूलाई अग्रभाग र पृष्ठभूमिमा सार्न अनुप्रयोगलाई अनुमति दिन्छ। अनुप्रयोगले यो तपाईँको इनपुट बिना नै गर्न सक्छ।"</string>
+    <string name="permlab_removeTasks" msgid="6821513401870377403">"चालु भइरहेका अनुप्रयोगहरू रोक्नुहोस्"</string>
+    <string name="permdesc_removeTasks" msgid="1394714352062635493">"कामहरू हटाउन र उनीहरूको अनुप्रयोगहरूलाई बन्द गर्न अनुप्रयोगलाई अनुमति दिन्छ। खराब अनुप्रयोगहरूले अन्य अनुप्रयोगहरूको व्यवहारलाई अबरोध गर्न सक्छन्।"</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"activity stacks को प्रबन्ध गर्नुहोस्"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"अनुप्रयोगलाई अन्य अनुप्रयोगहरू चल्ने activity stacks लाई थप्न, हटाउन र परिवर्तन गर्न अनुमति दिन्छ। खराब अनुप्रयोगहरूले अन्य अनुप्रयोगहरूको व्यवहारलाई विघटन गर्न सक्छन्।"</string>
+    <string name="permlab_startAnyActivity" msgid="2918768238045206456">"कुनै गतिविधि सुरु गर्नुहोस्"</string>
+    <string name="permdesc_startAnyActivity" msgid="997823695343584001">"अनुमति सुरक्षा वा निर्यात अवस्थालाई वास्ता नगरिकन कुनै पनि कार्य सुरु गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"स्क्रिन अनुकूलता सेट गर्नुहोस्"</string>
+    <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"अन्य अनुप्रयोहरूको स्क्रिन मिल्दो मोडलाई नियन्त्रण गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ। अन्य अनुप्रयोहरूको व्यवहार खराब अनुप्रयोगहरूले टुटाउन सक्छन्।"</string>
+    <string name="permlab_setDebugApp" msgid="3022107198686584052">"अनुप्रयोग डिबग गर्ने सक्षम गर्नुहोस्"</string>
+    <string name="permdesc_setDebugApp" msgid="4474512416299013256">"अनुप्रयोगलाई अन्य अनुप्रयोगको लागि डिबग गर्ने प्रक्रिया चालु गर्ने अनुमति दिन्छ। खराब अनुप्रयोगले अरू अनुप्रयोगहरू समाप्त गर्न यसको उपयोग गर्न सक्दछ।"</string>
+    <string name="permlab_changeConfiguration" msgid="4162092185124234480">"प्रणाली प्रदर्शन सेटिङहरू परिवर्तन गर्नुहोस्"</string>
+    <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"वर्तमान कन्फिगरेसन जस्तै लोक्याल वा सबैतिर फन्ट आकार बदल्न अनुप्रयोगलाई अनुमति दिन्छ।"</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_forceStopPackages" msgid="2329627428832067700">"अन्य अनुप्रयोगहरू दबाबमा रोक्नुहोस्"</string>
+    <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"अन्य अनुप्रयोगहरूलाई बलपूर्वक बन्द गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_forceBack" msgid="652935204072584616">"अनुप्रयोग बन्द गर्न बल गर्नुहोस्"</string>
+    <string name="permdesc_forceBack" msgid="3892295830419513623">"अग्रभागमा भएको कुनै गतिविधिलाई जबरजस्ती बन्द गर्न र फर्केर जानका लागि अनुप्रयोगलाई अनुमति दिन्छ। सामान्य अनुप्रयोगहरूलाइ कहिल्यै आवश्यकता पर्दैन।"</string>
+    <string name="permlab_dump" msgid="1681799862438954752">"प्रणालीको आन्तरिक स्थिति प्राप्त गर्नुहोस्"</string>
+    <string name="permdesc_dump" msgid="1778299088692290329">"प्रणालीको आन्तरिक स्थिति पुनःबहाली गर्न अनुप्रयोगलाई अनुमति दिन्छ। खराब अनुप्रयोगहरूले उनीहरूलाई सामान्यतः कहिल्यै नचाहिने व्यापक विविधताको निजी र सुरक्षित सूचना पुनःबहाली गर्न सक्छन्।"</string>
+    <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"स्क्रिन सामग्री बहाली गर्नुहोस्"</string>
+    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"सक्रिय विन्डोको विषयवस्तुलाई पुनःबहाली गर्न अनुप्रयोगलाई अनुमति दिन्छ। खराब अनुप्रयोगहरूले पुरै विन्डोको विषयवस्तु पुनःबहाली गर्न सक्छन् र पासवर्डहरूबाहेक यसका सबै पाठको जाँच गर्न सक्छन्।"</string>
+    <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"पहुँचतालाई अस्थायी सक्षम गर्नुहोस्"</string>
+    <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"अनुप्रयोगलाई अस्थायी रूपमा उपकरणमाथि पहुँच राख्न अनुमति दिन्छ। खराब अनुप्रयोगले उपयोगकर्ताको सहमति बिना नै पहुँचलाई सक्षम गर्न सक्दछ।"</string>
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"विन्डो जानकारी बहाली गर्नुहोस्"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"अनुप्रयोगलाई विन्डो व्यवस्थापकबाट विन्डोहरूको बारेमा जानकारी प्राप्त गर्न अनुमति दिन्छ। खराब अनुप्रयोगले आन्तरिक प्रणाली उपयोगको लागि निमित्त जानकारी पनि प्राप्त गर्न सक्दछ।"</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"घटनाहरू छान्नुहोस्"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"इन्पुट फिल्टर जुन सबै प्रयोगकर्ता घटनाहरू पठाइनुभन्दा पहिले फिल्टर गर्नेलाई दर्ता गर्न अनुप्रयोगलाई अनुमति दिन्छ। प्रयोगकर्ताको हस्तक्षेप बिना नै UI प्रणाली खराब अनुप्रयोगले नियन्त्रण गर्न सक्छन्।"</string>
+    <string name="permlab_magnify_display" msgid="5973626738170618775">"प्रदर्शन बढाउनुहोस्"</string>
+    <string name="permdesc_magnify_display" msgid="7121235684515003792">"अनुप्रयोगलाई प्रदर्शनको सामग्री आवर्धन गर्न अनुमति दिन्छ। खराब अनुप्रयोगहरूले प्रदर्शन सामग्री संक्रमण गर्न सक्दछन् जसले उपकरणलाई अनुपयोगी बनाउँदछ।"</string>
+    <string name="permlab_shutdown" msgid="7185747824038909016">"आंशिक बन्द"</string>
+    <string name="permdesc_shutdown" msgid="7046500838746291775">"गतिविधि व्यवस्थापकलाई बन्द गर्ने अवस्थामा राख्छ। पूर्ण बन्द गर्ने काम गर्दैन।"</string>
+    <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"अनुप्रयोग स्विचहरू जोगाउनुहोस्"</string>
+    <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"अन्य अनुप्रयोगमा स्विच गर्नबाट प्रयोगकर्ताहरूलाई रोक्छ।"</string>
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"वर्तमान अनुप्रयोगको जानकारी प्राप्त गर्नुहोस्"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="8153651434145132505">"स्क्रिनको अग्र भागमा हालको अनुप्रयोग र सेवाहरूका बारे निजी जानकारी निकाल्न बाहकलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"सबै अनुप्रयोग सुरुवात गर्ने निरीक्षण र नियन्त्रण गर्नुहोस्"</string>
+    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"अनुप्रयोगलाई कसरी प्रणाली सुरुवात गतिहरू मोनिटर गर्न र नियन्त्रण गर्न अनुमति दिन्छ। खराब अनुप्रयोगहरूले प्रणालीमा पूर्ण सहमत गर्न सक्दछ। यो अनुमति केवल विकासको लागि आवश्यक छ, साधारण प्रयोगको लागि कहिले होइन।"</string>
+    <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"प्याकेज हटाइएको प्रसारणलाई पठाउनुहोस्"</string>
+    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"अनुप्रयोगलाई सूचना प्रसारण गर्न अनुमति दिन्छ जुन अनुप्रयोग प्याकेज हटाइएको छ। खराब अनु्प्रयोगहरूले यो कुनै अन्य चालु अनु्प्रयोग बन्द गर्न प्रयोग गर्न सक्दछन्।"</string>
+    <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"SMS-प्राप्त प्रसारण पठाउनुहोस्"</string>
+    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"त्यो एउटा SMS सन्देशबाट प्राप्त भएको सूचनालाई प्रसारण गर्न अनुप्रयोगलाई अनुमति दिन्छ। आउँदै गरेको SMS सन्देशहरूलाई जालसाजी गर्न सायद खराब भएका अनुप्रयोगहरूले यसलाई प्रयोग गर्न सक्छन्।"</string>
+    <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"WAP-PUSH-प्राप्त प्रसारण पठाउनुहोस्"</string>
+    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"अनुप्रयोगलाई सूचना प्रसारण गर्न अनुमति दिन्छ जुन एउटा WAP PUSH सन्देश प्राप्त भएको छ। खराब अनुप्रयोगहरूले यो MMS सन्देश बिगार्न वा मौन तरिकाले कुनै पनि वेबपृष्ठको सामग्री खराब विभेदहरूसँग बदल्न प्रयोग गर्न सक्दछन्।"</string>
+    <string name="permlab_setProcessLimit" msgid="2451873664363662666">"चालु प्रशोधनहरूको सङ्ख्या सीमति गर्नुहोस्"</string>
+    <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"अनुप्रयोगलाई चालु हुने प्रक्रियाहरूको अधिकतम संख्या नियन्त्रण गर्न अनुमति दिन्छ। साधारण अनुप्रयोगहरूको लागि कहिले पनि आवश्यक नपर्न सक्दछ।"</string>
+    <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"पृष्ठभूमि अनुप्रयोगहरू बन्द गर्न दबाब दिनुहोस्"</string>
+    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"अनुप्रयोगलाई गतिविधिहरू सधैँ समाप्त भयो कि भएन जब कि जति सक्दो तिनीहरू पृष्ठभूमिमा जान्छन् भन्ने नियन्त्रण गर्न अनुमति दिन्छ। साधारण अनुप्रयोगहरूको लागि कहिले पनि आवश्यक नपर्न सक्दछ।"</string>
+    <string name="permlab_batteryStats" msgid="2789610673514103364">"ब्याट्रि तथ्याङ्हरू पढ्नुहोस्"</string>
+    <string name="permdesc_batteryStats" msgid="5897346582882915114">"वर्तमान थोरै ब्याट्री प्रयोग डेटा पढ्नको लागि एक अनुप्रयोगले अनुमति दिन्छ। जुन अनुप्रयोग तपाईँले प्रयोग गरीरहनुभएको छ त्यस्को बारेका पुर्ण जानकारी प्राप्त गर्न सायद अनुप्रयोगले अनुमति दिन्छ।"</string>
+    <string name="permlab_updateBatteryStats" msgid="3719689764536379557">"ब्याट्रि तथ्याङ्कलाई परिमार्जन गर्नुहोस्"</string>
+    <string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"अनुप्रयोगलाई संकलित ब्याट्रि तथ्याङ्कहरू परिमार्जन गर्न अनुमति दिन्छ। साधारण अनुप्रयोगहरूको प्रयोगको लागि होइन।"</string>
+    <string name="permlab_getAppOpsStats" msgid="1508779687436585744">"अनुप्रयोग संचालनका तथ्याङ्कहरू पुनःबहाली गर्नुहोस्"</string>
+    <string name="permdesc_getAppOpsStats" msgid="6243887041577912877">"सङ्कलन गरिएका अनुप्रयोग संचालन तथ्याङ्लाई पुनः प्राप्त गर्न अनुप्रयोगलाई अनुमति दिन्छ। सामान्य अनुप्रयोगबाट प्रयोगको लागि होइन।"</string>
+    <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"अनुप्रयोग संचलान तथ्याङ्कहरूलाई परिमार्जन गर्नुहोस्"</string>
+    <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"सङ्कलन गरिएका अनुप्रयोग संचालन तथ्याङ्लाई परिमार्जन गर्न अनुप्रयोगलाई अनुमति दिन्छ। सामान्य अनुप्रयोगबाट प्रयोगको लागि होइन।"</string>
+    <string name="permlab_backup" msgid="470013022865453920">"प्रणाली ब्यकअप नियन्त्रण गर्नुहोस् र पुनः बहाली गर्नुहोस्"</string>
+    <string name="permdesc_backup" msgid="6912230525140589891">"प्रणालीको जगेडा नियन्त्रण गर्न र पुनःप्राप्तिको संयोजन गर्न अनुप्रयोगलाई अनुमित दिन्छ। सामान्य अनुप्रयोगद्वारा प्रयोगको लागि होइन।"</string>
+    <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"पूर्ण जगेडा गर्न वा प्रक्रिया पुनःबहाली गर्न निश्चित गर्नुहोस्"</string>
+    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"UI को पूर्ण जगेडा निश्चिन्तता सुरु गर्नका लागि अनुप्रयोगलाई अनुमति दिन्छ। कुनै अनुप्रयोगबाट प्रयोग नगरिने।"</string>
+    <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"अनधिकृत बिन्डोहरू प्रदर्शन गर्नुहोस्"</string>
+    <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"अनुप्रयोगलाई विन्डोहरू सिर्जना गर्न अनुमति दिन्छ जुन आन्तरिक प्रणाली प्रयोगकर्ता इन्टरफेसद्वारा प्रयोग गर्न अभिप्रेरित छ। साधारण अनुप्रयोगहरूद्वारा प्रयोगको लागि होइन।"</string>
+    <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"अन्य अनुप्रयोगहरूमा चित्र कोर्नुहोस्"</string>
+    <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"अरू अनुप्रयोगहरूमाथि वा प्रयोगकर्ता इन्टरफेसका भागहरूमा चित्र कोर्न अनुप्रयोगलाई अनुमति दिन्छ। तिनीहरूले कुनै अनुप्रयोगमा इन्टरफेको तपाईँको प्रयोगसँग हस्तक्षेप गर्न वा तपाईँ अन्य अनुप्रयोगहरूमा के देखिरहनु भएको छ भन्ने सोच्न हुन्छ भन्ने बदल्न सक्छन्।"</string>
+    <string name="permlab_setAnimationScale" msgid="2805103241153907174">"ग्लोबल सजीविकरण गति परिमार्जन गर्नुहोस्"</string>
+    <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"विश्वब्यापि सजीविकरण(द्रुत वा ढिला सजीविकरणहरू) लाई कुनै पनि समय परिवर्तन गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_manageAppTokens" msgid="1286505717050121370">"अनुप्रयोग टोकनहरू प्रबन्ध गर्नुहोस्"</string>
+    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"अनुप्रयोगलाई आफ्ना टोकनहरू सिर्जना गर्न र उनीहरूको साधारण Z-क्रमाङ्कन बाइपास गरेर प्रबन्ध गर्न अनुमति दिन्छ। साधारण अनुप्रयोगहरूको लागि कहिल्यै पनि आवश्यक नहुन सक्दछ।"</string>
+    <string name="permlab_freezeScreen" msgid="4708181184441880175">"स्क्रिन फ्रिज गर्नुहोस्"</string>
+    <string name="permdesc_freezeScreen" msgid="8558923789222670064">"अनुप्रयोगलाई पूर्ण-स्क्रिन संक्रमणको लागि अस्थायी रूपमा स्क्रिन स्थिर गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_injectEvents" msgid="1378746584023586600">"कुञ्जीहरू र नियन्त्रण बटनहरू थिच्नुहोस्"</string>
+    <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"यसका आफ्ना इनपुट घटनाहरू (कि थिचाइहरू, आदि) अन्य अनुप्रयोगहरूलाई वितरण गर्न अनुप्रयोगलाई अनुमति दिन्छ। खराब अनुप्रयोगहरूले यसलाई ट्याब्लेटसम्म लैजान प्रयोग गर्न सक्छन्।"</string>
+    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"यस्को आफ्नै निवेश घटनाहरू (कि थिचाइहरू, आदि.) अन्य अनुप्रोयगहरूलाई पु्र्‍याउन अनुप्रयोगलाई अनुमति दिन्छ। फोनलाई हस्तक्षेप गर्न यसको प्रयोग खराब अनुप्रयोगहरूले गर्न सक्छन्।"</string>
+    <string name="permlab_readInputState" msgid="469428900041249234">"तपाईंले के टाइप गर्नुहुन्छ र के कार्यहरू लिनुहुन्छ रेकर्ड गर्नुहोस्"</string>
+    <string name="permdesc_readInputState" msgid="8387754901688728043">"अर्को अनुप्रयोग(जस्तै पासवर्ड टाइप गराइ)सँग अन्तर्क्रिया गरेको बेला पनि तपाईँले थिचेका किहरूलाइ हेर्न अनुप्रयोगलाई अनुमति दिन्छ। सामान्य अनुप्रयोगहरूलाई कहिल्यै आवश्यक हुँदैन।"</string>
+    <string name="permlab_bindInputMethod" msgid="3360064620230515776">"एउटा निवेश तरिकामा बाँध्नुहोस्"</string>
+    <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"एउटा निवेश तरिकाको उच्च स्तरको इन्टरफेसलाई पक्का गर्नको लागि समाती राख्नेलाई अनुमति दिन्छ। साधारण अनुप्रयोगहरूलाई कहिल्यै आवश्यक पर्ने छैन।"</string>
+    <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"एउटा पहुँच सेवासँग जोड्नुहोस्"</string>
+    <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"एक पहुँच सेवाको उच्च स्तरको कुराकानीलाई पक्का गर्नको लागि समाती राख्नेले अनुमति दिन्छ। साधारण अनुप्रयोगहरूलाई कहिल्यै आवश्यक पर्ने छैन।"</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"एउटा प्रिन्ट सेवासँग जोड्नुहोस्"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"एउटा प्रिन्ट सेवाको उच्च स्तरको इन्टरफेसलाई पक्का गर्नको लागि प्रयोगकर्तालाई अनुमति दिन्छ। साधारण अनुप्रयोगहरूलाई कहिल्यै आवश्यक पर्ने छैन।"</string>
+    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"सबै प्रिन्ट कार्यहरूको पहुँच गर्नुहोस्"</string>
+    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"प्रयोगकर्तालाई अन्य अनुप्रयोगद्वारा निर्मित प्रिन्ट कार्यहरू पहुँच गर्न अनुमति दिन्छ। साधारण अनुप्रयोगहरूलाई कहिल्यै आवश्यक पर्ने छैन।"</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC सेवामा बाँध्नुहोस्"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"NFC कार्डहरू इमुलेट गर्ने अनुप्रयोगहरूलाई बाँध्नका लागि होल्डरलाई अनुमति दिन्छ। सामान्य अनुप्रयोगहरूका लागि कहिल्यै पनि आवश्यक पर्दैन।"</string>
+    <string name="permlab_bindTextService" msgid="7358378401915287938">"एउटा पाठ सेवासँग संगठित हुनुहोस्"</string>
+    <string name="permdesc_bindTextService" msgid="8151968910973998670">"एउटा पाठ सेवाको (उदाहरण शब्द परीक्षणसेवा) उच्च स्तरको इन्टरफेसलाई पक्का गर्नको लागि समाती राख्नेलाई अनुमति दिन्छ। साधारण अनुप्रयोगहरूलाई कहिल्यै आवश्यक पर्ने छैन।"</string>
+    <string name="permlab_bindVpnService" msgid="4708596021161473255">"VPN सेवासँग बाँध्नुहोस्।"</string>
+    <string name="permdesc_bindVpnService" msgid="2067845564581693905">"एक Vpn सेवाको उच्च स्तरको कुराकानीलाई पक्का गर्नको लागि समाती राख्नेले अनुमति दिन्छ। साधारण अनुप्रयोगहरूलाई कहिल्यै आवश्यक पर्ने छैन।"</string>
+    <string name="permlab_bindWallpaper" msgid="8716400279937856462">"एउटा वालपेपरमा बाँध्नुहोस्"</string>
+    <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"वालपेपरको माथिल्लो स्तरको इन्टरफेसमा बाँध्न धारकलाई अनुमति दिन्छ। सामान्य अनुप्रयोगहरूलाई कहिल्यै आवश्यक पर्दैन।"</string>
+    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"एउटा विजेट सेवासँग संगठित हुनुहोस्"</string>
+    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"एउटा विजेट सेवाको उच्च स्तरको इन्टरफेसलाई पक्का गर्नको लागि समाती राख्नेलाई अनुमति दिन्छ। साधारण अनुप्रयोगहरूलाई कहिल्यै आवश्यक पर्ने छैन।"</string>
+    <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"उपकरणको प्रबन्धसँग अन्तरक्रिया गर्नुहोस्"</string>
+    <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"उपकरण प्रशासक लाई आशय पठाउन समाती राख्‍नेलाई अनुमति दिन्छ। साधारण अनुप्रयोहरूको लागि कहिल्यै पनी आवश्यक पर्दैन।"</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"एउटा उपकरण व्यवस्थापक थप गर्नुहोस् वा हटाउनुहोस्"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"होल्डरलाई सक्रिय उपकरण व्यवस्थापकहरू थप गर्न वा हटाउन अनुमति दिन्छ। साधारण अनुप्रयोगहरूको लागि कहिल्यै पनि आवश्यक नहुन सक्दछ।"</string>
+    <string name="permlab_setOrientation" msgid="3365947717163866844">"स्क्रिन अभिमुखिकरण परिवर्तन गर्नुहोस्"</string>
+    <string name="permdesc_setOrientation" msgid="3046126619316671476">"अनुप्रयोगलाई कुनै पनि समयमा स्क्रिनको परिक्रमण परिवर्तन गर्न अनुमति दिन्छ। साधारण अनुप्रयोगहरूको लागि कहिले पनि आवश्यक नपर्न सक्दछ।"</string>
+    <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"सङ्केतक गति बदल्नुहोस्"</string>
+    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"कुनै पनि समयमा माउस परिवर्तन गर्न वा ट्राकप्याड संकेतकको गति बदल्न अनुप्रयोगलाई अनुमति दिन्छ। सामान्य अनुप्रयोगहरूको लागि कहिल्यै नचाहिन सक्छ।"</string>
+    <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"किबोर्ड लेआउट परिवर्तन गर्नुहोस्"</string>
+    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"किबोर्ड लेआउटलाई परिवर्तन गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ। साधारण अनुप्रयोगहरूलाई सायद कहिल्यै आवश्यक पर्ने छैन।"</string>
+    <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"Linux संकेतहरू अनुप्रयोगलाई पठाउनुहोस्"</string>
+    <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"सबै चलिरहेका प्रक्रियाहरूमा पठाइएका संकेतलाई अनुरोध गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_persistentActivity" msgid="8841113627955563938">"अनुप्रयोगहरू जहिले पनि चल्ने बनाउनुहोस्"</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"यसको आफ्नै मेमोरीमा दृढ भएकोको अंश बनाउनको लागि अनुप्रयोगलाई अनुमति दिन्छ। ट्याब्लेटलाई ढिलो गराउँदै गरेका अन्य अनुप्रयोगहरूलाई सीमित मात्रामा यसले मेमोरी उपलब्ध गराउन सक्छ।"</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"अनुप्रयोगलाई मेमोरीमा आफैंको निरन्तरको अंश बनाउन अनुमति दिन्छ। यसले फोनलाई ढिला बनाएर अन्य अनुप्रयोगहरूमा मेमोरी SIMित गर्न सक्दछन्।"</string>
+    <string name="permlab_deletePackages" msgid="184385129537705938">"अनुप्रयोगहरू मेटाउनुहोस्"</string>
+    <string name="permdesc_deletePackages" msgid="7411480275167205081">"अनुप्रयोगलाई एन्ड्रोइड प्याकेजहरू मेटाउन अनुमति दिन्छ। खराब अनुप्रयोगहरूले यसलाई महत्त्वपूर्ण अनुप्रयोगहरू मेटाउन प्रयोग गर्न सक्दछन्।"</string>
+    <string name="permlab_clearAppUserData" msgid="274109191845842756">"अन्य अनुप्रयोगहरूको डेटा मेटाउनुहोस्"</string>
+    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"प्रयगकर्ता डेटा हटाउन अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"अन्य अनुप्रयोगहरूको क्यासहरू मेटाउनुहोस्"</string>
+    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"अनुप्रयोगलाई क्यास फाइलहरू मेटाउन अनुमति दिन्छ।"</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"अनुप्रयोग भण्डारण ठाउँको मापन गर्नुहोस्"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"अनुप्रयोगलाई यसको कोड, डेटा, र क्यास आकारहरू पुनःप्राप्त गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_installPackages" msgid="2199128482820306924">"अनुप्रयोगहरू सिधै स्थापना गर्नुहोस्"</string>
+    <string name="permdesc_installPackages" msgid="5628530972548071284">"नयाँ स्थापना गर्न वा एन्ड्रोइड प्याकेजहरू अद्यावधिक गर्न अनुप्रयोगलाई अनुमति दिन्छ। खराब अनुप्रयोगहरूले यसलाई मनपरी रूपमा शक्तिशाली अनुमतिहरू भएका नयाँ अनुप्रयोगहरू थप्न प्रयोग गर्न सक्छन्।"</string>
+    <string name="permlab_clearAppCache" msgid="7487279391723526815">"सबै अनुप्रयोग क्यास डेटा मेटाउनुहोस्"</string>
+    <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"अन्य अनुप्रयोगहरूको क्यास डाइरेक्टरीहरूमा फाइलहरू हटाएर ट्याब्लेटको भण्डारण खाली गर्न अनुप्रयोगहरूलाई अनुमति दिन्छ। उनीहरूले आफ्नो डेटा पुनःबहाली गर्न पर्ने हुनाले यसले अन्य अनुप्रयोगहरूलाई स्टार्ट हुन निकै ढिलो गराउन सक्छ।"</string>
+    <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"अनुप्रयोगलाई अन्य अनुप्रयोगहरूको क्यास डाइरेक्टरीमा फाइलहरू मेटाएर फोन भण्डारण खाली गर्न अनुमति दिन्छ। यसले अन्य अनुप्रयोगहरूलाई बढी ढिला सुरु गराउँछ किनकि तिनीहरूले आफ्नो डेटा पुनःप्राप्ति गर्न आवश्यक पर्ने हुन्छ।"</string>
+    <string name="permlab_movePackage" msgid="3289890271645921411">"अनुप्रयोग स्रोतहरू सार्नुहोस्"</string>
+    <string name="permdesc_movePackage" msgid="319562217778244524">"अनुप्रयोग स्रोतहरू आन्तरिकबाट बाह्य मेडियामा र विपरितमा लैजान अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_readLogs" msgid="6615778543198967614">"संवेनशील लग डेटा पढ्नुहोस्"</string>
+    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"प्रणालीका विभिन्न फाइलहरूबाट पढ्न अनुप्रयोगलाई अनुमति दिन्छ। सम्भाव्य रूपमा व्यक्तिगत र निजी सूचनासहित तपाईँ ट्याब्लेटसँग के गरिरहनु भएको छ भन्ने बारेको साधारण सूचना पत्ता लगाउन यसलाई अनुमति दिन्छ।"</string>
+    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"प्रणालीका विभिन्न फाइलहरूबाट पढ्न अनुप्रयोगलाई अनुमति दिन्छ। सम्भाव्य रूपमा व्यक्तिगत र निजी सूचनासहित तपाईँ फोनसँग के गरिरहनु भएको छ भन्ने बारेको साधारण सूचना पत्ता लगाउन यसलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"पछाडि बजाउनको लागि कुनै मिडिया प्रयोग गर्नुहोस्"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"अनुप्रयोगलाई प्लेब्याक डिकोड गर्न कुनै पनि स्थापित मिडिया डिकोडर प्रयोगको लागि अनुमति दिन्छ।"</string>
+    <!-- no translation found for permlab_manageCaCertificates (1678391896786882014) -->
+    <skip />
+    <!-- no translation found for permdesc_manageCaCertificates (4015644047196937014) -->
+    <skip />
+    <string name="permlab_diagnostic" msgid="8076743953908000342">"diag को स्वामित्वमा रहेको संसाधनहरूमा पढ्नुहोस्/लेख्नुहोस्"</string>
+    <string name="permdesc_diagnostic" msgid="6608295692002452283">"अनुप्रयोगलाई diag समूहद्वारा स्वामित्व प्राप्त कुनै पनि स्रोतहरूमा पढ्न र लेख्न अनुमति दिन्छ; उदाहरणको लागि, /dev  मा फाइलहरू। यसले सम्भवतः प्रणाली स्थिरता र सुरक्षामा प्रभाव पार्न सक्दछ। यो केवल निर्माता वा संचालकद्वारा हार्डवेयर-निर्दिष्टको लागि प्रयोग हुन सक्दछ।"</string>
+    <string name="permlab_changeComponentState" msgid="6335576775711095931">"अनुप्रयोग अंशहरू सक्षम वा अक्षम गर्नुहोस्"</string>
+    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"अन्य अनुप्रयोग सक्षम छ वा छैन भन्ने कुराको परिवर्तन गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ। महत्त्वपूर्ण फोन सक्षमता खराब अनुप्रोगहरूले असक्षम पार्न प्रयोग गर्न सक्छन्। यो अनुमतिसँगै होसियारी अपनाउनु पर्छ, अनुप्रयोग विषय सूचीमा प्रयोग नहुने, असंगत, अस्थिर अवस्था भएको प्राप्त हुने सम्भावना हुन्छ।"</string>
+    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"अन्य अनुप्रयोगको अंश सक्षम छ वा छैन भन्नेमा परिवर्तन गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ। महत्त्वपूर्ण फोन सक्षमता खराब अनुप्रोगहरूले असक्षम पार्न प्रयोग गर्न सक्छन्। यो अनुमतिसँगै होसियारी अपनाउनु पर्छ, अनुप्रयोग विषय सूचीमा प्रयोग नहुने, असंगत, अस्थिर अवस्था भएको प्राप्त हुने सम्भावना हुन्छ।"</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"अनुमतिहरू प्रदान गर्नुहोस् वा रद्द गर्नुहोस्"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"अनुप्रयोगलाई यो वा अन्य अनुप्रयोगहरूको लागि निर्दिष्ट स्वीकृतिहरू प्रदान गर्न वा रद्द गर्न अनुमति दिन्छ। खराब अनुप्रयोगहरूले यो तपाईंले अनुमति प्रदान नगर्नुभएका सुविधाहरूमा पहुँच गर्न सक्दछन्।"</string>
+    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"विशेष रूपमा मान्य अनुप्रयोगहरू सेट गर्नुहोस"</string>
+    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"तपाईँको मनपर्ने अनुप्रयोगलाई परिवर्तन गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ। खराब अनुप्रयोगहरूले चलिरहेका ती अनुप्रयोहरूलाई चुपचाप रूपमा परिवर्तन गर्न सक्छन्, तपाईँबाट निजी डेटा संकलन गर्नको लागि भइरहेको अनुप्रयोगलाई स्पुफ गर्न सक्छन्।"</string>
+    <string name="permlab_writeSettings" msgid="2226195290955224730">"प्रणाली सेटिङहरू परिमार्जन गर्नुहोस्"</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"प्रणालीका सेटिङ डेटालाई परिवर्तन गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ। खराब अनुप्रयोगहरूले सायद तपाईँको प्रणालीको कन्फिगरेसनलाई क्षति पुर्‍याउन सक्छन्।"</string>
+    <string name="permlab_writeSecureSettings" msgid="204676251876718288">"सुरक्षित प्रणाली सेटिङहरू परिमार्जन गर्नुहोस्"</string>
+    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"प्रणालीको सुरक्षित सेटिङ डेटा परिमार्जन गर्न अनुप्रयोगलाई अनुमति दिन्छ। सामान्य अनुप्रयोगहरूको प्रयोगको लागि होइन्।"</string>
+    <string name="permlab_writeGservices" msgid="2149426664226152185">"Google सेवा नक्सा परिवर्तन गर्नुहोस्"</string>
+    <string name="permdesc_writeGservices" msgid="1287309437638380229">"अनुप्रयोगलाई Google सेवा नक्साहरू परिमार्जन गर्न अनुमति दिन्छ। साधारण अनुप्रयोगहरूद्वाराको प्रयोगको लागि होइन।"</string>
+    <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"स्टार्टअपमा चलाउनुहोस्"</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"आनुप्रयोगलाई प्रणाली बुट प्रक्रिया पूर्ण हुने बितिकै आफैलाई सुरु गर्ने अनुमति दिन्छ। यसले ट्याब्लेट सुरु गर्नमा ढिला गर्न सक्दछ र अनुप्रयोगलाई समग्रमा ट्याब्लेट सधैँ चालु गरेर ढिला बनाउँदछ।"</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="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="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="default" msgid="589869224625163558">"तपाईँले बारम्बार कल गरेका, इमेल गरेका, वा विशेष सम्पर्कहरूसँग सञ्चार गरेका सहित तपाईँको फोनमा भण्डारण गरेका तपाईँका सम्पर्कहरू परिमार्जन गर्न अनुप्रयोगलाई अनुमति दिन्छ। यो अनुमतिले अनुप्रयोगलाई सम्पर्क डेटा मेटाउन दिन्छ।"</string>
+    <string name="permlab_readCallLog" msgid="3478133184624102739">"कल लग पढ्नुहोस्"</string>
+    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"अनुप्रयोगलाई तपाईँको ट्याब्लेटको कल लग, आगमन र बहिर्गमन कलहरू बारे डेटा सहितको कल लग पढ्न अनुमति दिन्छ। यस अनुमतिले अनुप्रयोगहरूलाई तपाईँको कल लग डेटाहरूको बचत गर्न अनुमति दिन्छ, र खराब अनुप्रयोगहरूले तपाईँको जानकारी बिना नै यो कल लग डेटालाई अरूसँग साझेदार गर्न सक्छन्।"</string>
+    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"भित्र आउने र बाहिर जाने कलहरूसहित तपाईँको फनको कल लग पढ्न अनुप्रयोगलाई अनुमति दिन्छ।  यो अनुमतिले अनुप्रयोगहरूलाई तपाईँका कल लग डेटा बचत गर्न दिन्छ र खराब अनुप्रयोगहरूले तपाईँले थाहै नपाई कल लग डेटालाई साझेदारी गर्न सक्छन्।"</string>
+    <string name="permlab_writeCallLog" msgid="8552045664743499354">"कल लग लेख्‍नुहोस्"</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"आगमन तथा बहर्गमन डेटासहित तपाईँको ट्याब्लेटको कल लगको परिमार्जन गर्न अनुप्रयोगलाई अनुमति दिन्छ। खराब अनुप्रयोगहरूले यसलाई तपाईँको कल लग परिमार्जन गर्न वा मेटाउन प्रयोग गर्न सक्छन्।"</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"अनुप्रयोगलाई तपाईंको फोनको आउने र बाहिर जाने कलहरूको बारेको डेटा सहित कल लग परिमार्जन गर्न अनुमति दिन्छ। खराब अनुप्रयोगहरूले यसलाई तपाईंको कल लग मेटाउन वा परिमार्जन गर्न प्रयोग गर्न सक्दछ।"</string>
+    <string name="permlab_readProfile" msgid="4701889852612716678">"तपाईँको आफ्नै सम्पर्क कार्ड पढ्नुहोस्"</string>
+    <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"अनुप्रयोगलाई तपाईंको उपकरणमा भण्डारण गरिएका व्यक्तिगत प्रोफाइल जानकारी पढ्न अनुमति दिन्छ, जस्तै तपाईंको नाम र सम्पर्क जानकारी। यसको मतलब अनुप्रयोगले तपाईंलाई पहिचान गर्न सक्दछ र तपाईंको प्रोफाइल जानकारी अरूलाई पठाउन सक्दछ।"</string>
+    <string name="permlab_writeProfile" msgid="907793628777397643">"तपाईँको आफ्नै सम्पर्क कार्ड परिमार्जन गर्नुहोस्"</string>
+    <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"तपाईँको उपकरणमा भण्डार भएको व्याक्तिगत प्रोफाइल जानकारी, जस्तै तपाईँको नाम वा सम्पर्क जानकारीलाई परिवर्तन गर्न वा थप्नको लागि अनुप्रयोगलाई अनुमति दिन्छ। यसको मतलब अन्य अनुप्रयोगले तपाईँलाई चिन्न सक्छन् र सायद अन्यलाई तपाईँको प्रोफाइल जानकारी पठाउन सक्छन्।"</string>
+    <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"तपाईंको सामाजिक स्ट्रिम पढ्नुहोस्"</string>
+    <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"तपाईँ र तपाईँका साथीहरूबाट सामाजिक अपडेटलाई पहुँच र सिंक गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ। जानकारी साझेदारी गर्दा सावधान रहनुहोस्  -- समाजिक नेटवर्कहरूमा तपाईँ र तपाईँको साथीको  बिचमा भएका संचारलाई पढ्न विश्वासनीयता बेगरै यसले अनुप्रयोगलाई अनुमति दिन्छ। नोट: यो अनुमति बलपूर्वक सबै सामाजिक नेटवर्कहरूमा सायद नगर्न सकिन्छ।"</string>
+    <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"तपाईँको सामाजिक प्रवाहमा लेख्‍नुहोस्"</string>
+    <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"अनुप्रयोगलाई तपाईंको साथीहरूबाट सामाजिक अपडेटहरू प्रदर्शन गर्न अनुमति दिन्छ। जानकारी साझेदारी गर्ने बेलामा होशियार रहनुहोस् -- यसले अनुप्रयोगलाई सन्देशहरू निर्माण गर्न अनुमति दिन्छ जुन साथीबाट आएको देखिन्छ। टिप्पणी: यो अनुमति सबै सामाजिक सञ्जालहरूमा लागू नहुन सक्दछ।"</string>
+    <string name="permlab_readCalendar" msgid="5972727560257612398">"गोप्य जानकारी र पात्रो घटनाहरू पढ्नुहोस्"</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"अनुप्रयोगलाई तपाईंको ट्याब्लेटमा भण्डारण गरिएका ती साथीहरू वा सहयोगीहरू सहितको पात्राका कार्यक्रमहरू पढ्न अनुमति दिन्छ। यसले गोपनीयता वा संवेदनशीलता बिना पनि अनुप्रयोगलाई तपाईंको पात्राका डेटा साझेदारी गर्न वा बचत गर्न अनुमति दिन्छ।"</string>
+    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"ती साथीहरू वा सहकर्मीहरूसहित सबै पात्रो घटनाहरू तपाईँको ट्याब्लेटमा भण्डारण भएकालाई पढ्नको लागि अनुप्रयोगलाई अनुमति दिन्छ। तपाईँको पात्रो डेटा यसले सायद सेयर गर्न वा सुरक्षित गर्नको लागि विश्वासनियता वा सम्वेदनशीलता बिना नै अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_writeCalendar" msgid="8438874755193825647">"पात्रो घटनाहरू थप्नुहोस् वा परिमार्जन गर्नुहोस् र मालिकको ज्ञान बिना नै पाहुनाहरूलाई इमेल पठाउनुहोस्"</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"ती साथीहरू वा सहकर्मीहरूसहितका घटनाहरू जसलाई तपाईँले आफ्नो ट्याब्लेटमा परिमार्जन गर्न सक्ने अनुमति अनुप्रयोगलाई दिन्छ। यसले अनुप्रयोगलाई सन्देशहरू जुन पात्राको मालिकहरूबाट आएका देखिनेलाई पठाउने वा मालिकहरूको ज्ञान बेगर घटनालाई परिमार्जन गर्ने अनुमित दिन्छ।"</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"ती साथीहरू वा सहकर्मीहरूसहित तपाईँको फोनका घटनाहरू जसलाई थप्न, हटाउन र परिवर्तन गर्न  अनुप्रयोगलाई अनुमति दिन्छ। पात्रो मालिकबाट देखा परेका वा मालिकको ज्ञान बिना परिवर्तन भएका घटनाहरू सन्देश पठाउन यसले अनुप्रयोगलाई अनुमति दिन सक्छ।"</string>
+    <string name="permlab_accessMockLocation" msgid="8688334974036823330">"परीक्षणको लागि स्थान स्रोतहरू मक गर्नुहोस्"</string>
+    <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"परीक्षणको लागि मक स्थान स्रोतहरू सिर्जना गर्नुहोस् वा नयाँ स्थान प्रदायक स्थापना गर्नुहोस्। यसले अनुप्रयोगलाई स्थानमा ओभरराइड गर्दछ र/वा स्थिति अन्य स्थान स्रोतहरू जस्तै GPS वा स्थान प्रदायकबाट फर्काइएका।"</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"अधिक स्थान प्रदायक आदेशहरू पहुँच गर्नुहोस्"</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"थप स्थान प्रदायक कमाण्डहरू सम्म पहुँच पुर्‍याउन अनुप्रयोगले अनुमति दिन्छ। यसले अनुप्रयोगलाई सायद जीपीएसको वा अन्य स्थान सेवाहरूको कार्य सँग हस्तक्षेप गर्नको लागि यसलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_installLocationProvider" msgid="6578101199825193873">"एउटा स्थान प्रदाता स्थापित गर्न अनुमति"</string>
+    <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"परीक्षणको लागि मक स्थान स्रोतहरू सिर्जना गर्नुहोस् वा नयाँ स्थान प्रदायक स्थापना गर्नुहोस्। यसले अनुप्रयोगलाई स्थानमा ओभरराइड गर्दछ र/वा स्थिति अन्य स्थान स्रोतहरू जस्तै GPS वा स्थान प्रदायकबाट फर्काइएका।"</string>
+    <string name="permlab_accessFineLocation" msgid="1191898061965273372">"सटिक स्थान (GPS र नेटवर्क आधारित)"</string>
+    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"अनुप्रयोगले विश्वव्यापी स्थान प्रणाली (GPS) वा सेल टावरहरू र वाइ-फाइ जस्ता नेटवर्क स्थान स्रोतहरूको प्रयोग गरेर तपाईँको सही स्थान प्राप्त गर्न अनुमति दिन्छ। यी स्थान सेवाहरू खोल्नु पर्छ र अनुप्रयोगहरूका लागि प्रयोग गर्न तपाईँको उपकरणमा उपलब्ध हुनु पर्छ। अनुप्रयोगहरूले तपाईँ कहाँ हुनु हुन्छ भन्ने निर्धारण गर्न यसलाई प्रयोग गर्न सक्छ र यसले अतिरिक्त ब्याट्रि उर्जा खतप गर्न सक्छ।"</string>
+    <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"अनुमानित स्थान (नेटवर्क-आधारित)"</string>
+    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"अनुप्रयोगलाई तपाईँको अनुमानित स्थान प्राप्त गर्न अनुमति दिन्छ। यो स्थान सेल टावर र वाइ-फाइजस्ता नेटवर्क स्थान स्रोतहरूको प्रोग गरी स्थान सेवाहरूबाट उत्पन्न गरिएको हो। अनुप्रयोगले यी स्थान सेवाहरूको उपयोग गर्नको लागि यी सेवाहरू तपाईँको उपकरणमा चालु र उपलब्ध हुनु आवश्यक छ। अनुप्रयोगहरूले अनुमानित रूपमा तपाईँ कहाँ हुनुहुन्छ भन्ने निर्धारण गर्न यसको प्रयोग गर्न सक्छन्।"</string>
+    <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"SurfaceFlinger पहुँच गर्नुहोस्।"</string>
+    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"SurfaceFlinger कम-स्तर सुविधाहरू प्रयोग गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"फ्रेम बफर पढ्नुहोस्"</string>
+    <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"अनुप्रयोगलाई फ्रेम बफरको सामग्री पढ्न अनुमति दिन्छ।"</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"InputFlinger को पहुँच गर्नुहोस्"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"InputFlinger को कम-स्तर सुविधाहरू प्रयोग गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"वाइफाइ प्रदर्शनहरूलाई विन्यास गर्नुहोस"</string>
+    <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"अनुप्रयोगलाई कन्फिगर गर्न र वाइफाइ प्रदर्शनहरूसँग जोड्न अनुमति दिन्छ।"</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"वाइफाइ प्रदर्शनहरू नियन्त्रण गर्नुहोस्"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"वाइफाइ प्रदर्शनीका तल्लो तह विषेशताहरू नियन्त्रण गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"अडियो आउटपुट कैद गर्नुहोस्"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"अनुप्रयोगलाई अडियो आउटपुट कैद गर्न र रिडाइरेक्ट गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"भिडियो आउटपुट कैद गर्नुहोस्"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"अनुप्रयोगलाई भिडियो आउटपुट कैद गर्न र रिडाइरेक्ट गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"सुरक्षित भिडियो आउटपुट कैद गर्नुहोस्"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"अनुप्रयोगलाई सुरक्षित भिडियो आउटपुट कैद गर्न र रिडाइरेक्ट गर्न अनुमति दिन्छ।"</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="4906839301087980680">"अनुप्रयोगलाई माइक्रोफोनको साथ अडियो रेकर्ड गर्न अनुमति दिन्छ। यस अनुमतिले तपाईंको पुष्टिकरण बिना कुनै पनि समयमा अडियो रेकर्ड गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_camera" msgid="3616391919559751192">"तस्बिरहरू र भिडियोहरू लिनुहोस्।"</string>
+    <string name="permdesc_camera" msgid="8497216524735535009">"अनुप्रयोगलाई क्यामेरासँग तस्बिर र भिडियोहरू लिन अनुमति दिन्छ। यस अनुमतिले अनुप्रयोगलाई तपाईंको पुष्टिकरण बिना कुनै पनि समयमा क्यामेरा प्रयोग गर्न स्वीकृति दिन्छ।"</string>
+    <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"क्यामेरा प्रयोगमा हुँदा सूचक LED प्रसारण असक्षम गर्नुहोस्"</string>
+    <string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"पूर्व-स्थापित प्रणाली अनुप्रयोगलाई क्यामेरा उपयोग सूचक LED अक्षम गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"स्थायी रूपमा ट्याब्लेट अक्षम पार्नुहोस्"</string>
+    <string name="permlab_brick" product="default" msgid="8337817093326370537">"फोनलाई स्थायी रूपमा असक्षम पार्नहोस्"</string>
+    <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"पुरै ट्याब्लेटलाई स्थायी रूपमा असक्षम पार्न अनुप्रयोगलाई अनुमति दिन्छ। यो निकै खतरनाक हुन्छ।"</string>
+    <string name="permdesc_brick" product="default" msgid="5788903297627283099">"सम्पूर्ण फोनलाई स्थायी रूपमा असक्षम पार्न अनुप्रयोगलाई अनुमति दिन्छ। यो धेरै खतरनाक हुन्छ।"</string>
+    <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"ट्याब्लेट पुनःबुट गर्न जोड गर्नुहोस्"</string>
+    <string name="permlab_reboot" product="default" msgid="2898560872462638242">"फोन पुनःबुट गर्नु जोड गर्नुहोस्"</string>
+    <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"ट्याब्लेटलाई बलपूर्वक पुनःबुट गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"फोनलाई बलपुर्वक पुनःबुट गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"USB भण्डारण फाइल प्रणाली पहुँच गर्नुहोस्"</string>
+    <string name="permlab_mount_unmount_filesystems" product="default" msgid="4402305049890953810">"SD कार्ड फाइल प्रणाली पहुँच गर्नुहोस्"</string>
+    <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"हटाउन मिल्ने भण्डारणको लागि फाइल प्रणालीहरू माउन्ट र अनमाउन्ट गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"USB भण्डारण मेट्नुहोस्"</string>
+    <string name="permlab_mount_format_filesystems" product="default" msgid="262582698639274056">"SD कार्ड मेटाउनुहोस्"</string>
+    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"हटाउन मिल्ने भण्डारण फर्म्याट गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_asec_access" msgid="3411338632002193846">"आन्तरिक भण्डारणको सूचना प्राप्त गर्नुहोस्"</string>
+    <string name="permdesc_asec_access" msgid="3094563844593878548">"आन्तरिक भण्डारणमा सूचना प्राप्त गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_asec_create" msgid="6414757234789336327">"आन्तरिक भण्डारण सिर्जना गर्नुहोस्"</string>
+    <string name="permdesc_asec_create" msgid="4558869273585856876">"आन्तरिक भण्डारण सिर्जना गर्नको लागि अनुप्रयोगले अनुमति दिन्छ।"</string>
+    <string name="permlab_asec_destroy" msgid="526928328301618022">"आन्तरिक भण्डारण ध्वस्त पार्नुहोस्"</string>
+    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"अनुप्रयोगलाई आन्तरिक भण्डारण ध्वस्त पार्न अनुमति दिन्छ।"</string>
+    <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"आन्तरिक भण्डारणलाई माउन्ट/अनमाउन्ट गर्नुहोस्"</string>
+    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"अनुप्रयोगलाई आन्तरिक भण्डारण माउन्ट/अनमाउन्ट गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_asec_rename" msgid="7496633954080472417">"आन्तरिक भण्डारणको पुन:नामाकरण गर्नुहोस्"</string>
+    <string name="permdesc_asec_rename" msgid="1794757588472127675">"आन्तरीक भण्डारणको पुननामाकरण गर्नको लागि अनुप्रयोगले अनुमति दिन्छ।"</string>
+    <string name="permlab_vibrate" msgid="7696427026057705834">"कम्पन नियन्त्रण गर्नुहोस्"</string>
+    <string name="permdesc_vibrate" msgid="6284989245902300945">"अनुप्रयोगलाई भाइब्रेटर नियन्त्रण गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_flashlight" msgid="2155920810121984215">"फ्ल्यासलाईट नियन्त्रण गर्नुहोस्"</string>
+    <string name="permdesc_flashlight" msgid="6522284794568368310">"फ्ल्यास प्रकाशलाई नियन्त्रण गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_manageUsb" msgid="1113453430645402723">"USB उपकरणहरूको लागि प्राथमिकताहरू र अनुमतिहरू प्रबन्ध गर्नुहोस्"</string>
+    <string name="permdesc_manageUsb" msgid="7776155430218239833">"USB उपकरणहरूको लागि प्राथमिकताहरू र अनुमतिहरूलाई व्यवस्थापन गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_accessMtp" msgid="4953468676795917042">"MTP प्रोटोकल कार्यान्वयन गर्नुहोस्"</string>
+    <string name="permdesc_accessMtp" msgid="6532961200486791570">"MTP USB प्रोटोकल कार्यान्वयन गर्न केर्नल MTP ड्राइभरको पहुँचको अनुमति दिन्छ।"</string>
+    <string name="permlab_hardware_test" msgid="4148290860400659146">"हार्डवेयर परीक्षण गर्नुहोस्"</string>
+    <string name="permdesc_hardware_test" msgid="6597964191208016605">"हार्डवेयर परीक्षणको उद्देश्यका लागि विभिन्न परिधीयहरूलाई नियन्त्रण गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_callPhone" msgid="3925836347681847954">"फोन नम्बरहरूमा सिधै कल गर्नुहोस्"</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"तपाईँको हस्तक्षेप बेगरै फोन नम्बर कल गर्न अनुप्रयोगलाई अनुमति दिन्छ। यसले अनपेक्षित शुल्क वा कलहरू गराउन सक्छ। यसले अनुप्रयोगलाई आपतकालीन नम्बरहरू कल गर्न अनुमति दिँदैन विचार गर्नुहोस्। खराब अनुप्रयोगहरूले तपाईँको स्वीकार बिना कलहरू गरेर तपाईँलाई बढी पैसा तिराउन सक्छ।"</string>
+    <string name="permlab_callPrivileged" msgid="4198349211108497879">"कुनै पनि फोन नम्बरहरू सिधै कल गर्नुहोस्"</string>
+    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"कुनै पनि फोन नम्बरमा, आकस्मिक नम्बर सहित, तपाईँको हस्तक्षेप बिना कल गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ। खराब अनुप्रयोगहरूले अनावश्यक र गैर कानुनी कलहरूलाई आकस्मिकमा स्थानान्तरण गर्न सक्छन्।"</string>
+    <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"CDMA ट्याब्लेट सेटअफ सिधै सुरु गर्नुहोस्"</string>
+    <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"CDMA फोन सेटअप सिधै सुरु गर्नुहोस्"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"अनुप्रयोगलाई CDMA प्रावधान सुरu गर्न अनुमति दिन्छ। खराब अनुप्रयोगहरूले अनावश्यक रूपमा CDMA प्रावधान सुरु गर्न सक्छन्।"</string>
+    <string name="permlab_locationUpdates" msgid="7785408253364335740">"स्थान अपडेट सूचनाहरू नियन्त्रण गर्नुहोस्"</string>
+    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"रेडियोबाट स्थान अद्यावधिक सूचनाहरूलाई सक्षम/असक्षम गर्न अनुप्रयोगलाई अनुमति दिन्छ। सामान्य अनुप्रयोगहरूबाट प्रयोग नहुने।"</string>
+    <string name="permlab_checkinProperties" msgid="7855259461268734914">"परीक्षण विशेषताहरू पहुँच गर्नुहोस्"</string>
+    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"परीक्षण सेवाद्वारा विशेषता अपलोड भएको पहुँच पढ्न/लेख्‍न अनुप्रयोगलाई अनुमति दिन्छ। साधारण अनुप्रयोगद्वारा प्रयोगको लागि होइन।"</string>
+    <string name="permlab_bindGadget" msgid="776905339015863471">"विजेटहरूको चयन गर्नुहोस्"</string>
+    <string name="permdesc_bindGadget" msgid="8261326938599049290">"अनुप्रयोगलाई प्रणालीलाई कुन विजेट कुन अनुप्रयोगद्वारा प्रयोग गर्न सकिन्छ भनेर अनुमति दिन्छ। यस अनुमतिसहितको अनुप्रयोगले अन्य अनुप्रयोगहरूलाई व्यक्तिगत डेटाको पहुँच दिन सक्दछ। सामान्य अनुप्रयोगहरूको प्रयोगको लागि होइन।"</string>
+    <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"फोनको स्थिति परिमार्जन गर्नुहोस्"</string>
+    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"उपकरणका फोन विशेषताहरूलाई नियन्त्रण गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ।  यस अनुमतिले एउटा अनुप्रयोगले नेटवर्क स्विच गर्न, फोन रेडियो बन्द गर्न र खोल्न र जस्तै तपाईँ सधै सूचित नगरी गर्न सक्छ।"</string>
+    <string name="permlab_readPhoneState" msgid="9178228524507610486">"फोन स्थिति र पहिचान पढ्नुहोस्"</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"उपकरणको फोन विशेषताहरूको पहुँच गर्न अनुप्रयोगलाई अनुमति दिन्छ। यस अनुमतिले फोन नम्बर र उपकरणको IDs, कल सक्षम छ कि छैन र कलद्वारा जोडिएको टाढाको नम्बर निर्धारण गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"ट्याब्लेटलाई निन्द्रामा जानबाट रोक्नुहोस्"</string>
+    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"फोनलाई निदाउनबाट रोक्नुहोस्"</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"ट्याब्लेटलाई निस्क्रिय हुनबाट रोक्नको लागि अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"फोनलाई निस्क्रिय हुनबाट रोक्नको लागि अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"ट्याब्लेट पावर खोल्न र बन्द गर्नुहोस्"</string>
+    <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"फोन खोल्न वा बन्द गर्न उर्जा प्रदान गर्नुहोस"</string>
+    <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"ट्याब्लेटलाई खोल्न र बन्द गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"अनुप्रयोगलाई फोन खोल्न र बन्द गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_factoryTest" msgid="3715225492696416187">"फ्याक्ट्रि परीक्षण मोडमा चालु गर्नुहोस्"</string>
+    <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"ट्याब्लेट हार्डवेयरलाई पुरा पहुँच गर्न दिँदै तल्लो स्तर उत्त्पादक परीक्षणको रूपमा चलाउनुहोस्। ट्याब्लेट उत्त्पादक परीक्षण मोडमा चलिरहेको बेला मात्र उपलब्ध हुन्छ।"</string>
+    <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"तल्लो स्तर उत्त्पादक जस्तै चलाउनुहोस्, पुरा पहुँच दिन फोन हार्डवेयरलाई अनुमति हुन्छ। फोन उत्पादक परीक्षण मोडमा चलिरहेको बेला मात्र उपलब्ध हुन्छ।"</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_masterClear" msgid="2315750423139697397">"कार्यशाला पूर्वनिर्धारणको लागि प्रणाली पुनःसेट गर्नुहोस्"</string>
+    <string name="permdesc_masterClear" msgid="3665380492633910226">"यसका फ्याक्ट्रि सेटिङहरू, कन्फिगरेसन र स्थापित अनुप्रयोगहरूलाई प्रणालीमा पुरै पुनःसेट गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_setTime" msgid="2021614829591775646">"समय सेट गर्नुहोस्"</string>
+    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"ट्याब्लेटको घडीको समय बदल्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permdesc_setTime" product="default" msgid="1855702730738020">"फोनको घडीको समय बदल्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_setTimeZone" msgid="2945079801013077340">"समय क्षेत्र सेट गर्नुहोस्"</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"अनुप्रयोगलाई ट्याब्लेटको समय क्षेत्र परिवर्तन गर्न अनुमति दिन्छ।"</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"अनुप्रयोगलाई फोनको समय क्षेत्र परिवर्तन गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_accountManagerService" msgid="4829262349691386986">"AccountManagerService को रूपमा कार्य गर्नुहोस्"</string>
+    <string name="permdesc_accountManagerService" msgid="1948455552333615954">"खाता अधिकारीहरूलाई कल गर्नको लागि अनुप्रयोगले अनुमति दिन्छ।"</string>
+    <string name="permlab_getAccounts" msgid="1086795467760122114">"उपकरणमा खाताहरू भेट्टाउनुहोस्"</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"अनुप्रयोगलाई ट्याब्लेटद्वारा ज्ञात खाताहरूको सूची पाउन अनुमति दिन्छ। यसले अनुप्रयोगद्वारा तपाईंले स्थापित गर्नुभएको कुनै पनि खाताहरू समावेश गर्न सक्दछ।"</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"फोनलाई थाहा भएका खाताहरूको सूची प्राप्त गर्न अनुप्रयोगलाई अनुमति दिन्छ। यसले तपाईँले स्थापना गर्नु भएका अनुप्रयोगहरूबाट सृजित कुनै खाताहरू समावेश हुन सक्छ।"</string>
+    <string name="permlab_authenticateAccounts" msgid="5265908481172736933">"खाता सिर्जना गर्नुहोस् र पासवर्ड सेट गर्नुहोस्"</string>
+    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"खाताहरूको सिर्जना गर्ने र प्राप्त गर्ने र उनीहरूको पासवर्डहरूको सेटिङ गर्ने सहित खाता प्रबन्धकको खाता आधिकारी सक्षमताहरू प्रयोग गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_manageAccounts" msgid="4983126304757177305">"खाताहरू थप्नुहोस् वा हटाउनुहोस्"</string>
+    <string name="permdesc_manageAccounts" msgid="8698295625488292506">"खाताहरू थप्ने र हटाउने जस्ता प्रक्रियाहरू सम्पन्न गर्न, र उनीहरूको पासवर्ड मेटाउन अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_useCredentials" msgid="235481396163877642">"उपकरणमा खाताहरूको प्रयोग गर्नुहोस्"</string>
+    <string name="permdesc_useCredentials" msgid="7984227147403346422">"अनुप्रयोगलाई प्रमाणीकरण टोकनहरू अनुरोध गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_accessNetworkState" msgid="4951027964348974773">"नेटवर्क जडानहरू हेर्नहोस्"</string>
+    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"अनुप्रयोगलाई नेटवर्क जडानहरू जस्तै कुन नेटवर्कहरू अवस्थित हुन्छन् र जडित छन् जसले हेर्नलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"पूर्ण नेटवर्क पहुँच"</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"नेटवर्क सकेटहरू सिर्जना गर्न र कस्टम नेटवर्क प्रोटोकल प्रयोग गर्न अनुप्रयोगलाई अनुमति दिन्छ। ब्राउजर र अन्य अनुप्रयोगहरूले इन्टरनेटमा डेटा पठाउने माध्यम प्रदान गर्छन्, त्यसैले इन्टरनेटमा डेटा पठाउन यो अनुमतिको आवश्यकता पर्दैन।"</string>
+    <string name="permlab_writeApnSettings" msgid="505660159675751896">"नेटवर्क सेटिङहरू र ट्राफिक परिवर्तन गर्नुहोस् / रोक्नुहोस्"</string>
+    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"अनुप्रयोगलाई नेटवर्क सेटिङहरू परिवर्तन गर्न र सबै नेटवर्क ट्राफिक रोक्न र परीक्षण गर्न अनुमति दिन्छ, उदाहरणको लागि कुनै पनि APN को प्रोक्सी र पोर्ट परिवर्तन गर्न। खराब अनुप्रयोगहरूले तपाईंको ज्ञान बिना नेटवर्क प्याकेटहरू मोनिटर गर्न, पुन:निर्देशित गर्न, वा परिमार्जन गर्न सक्दछ।"</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_changeBackgroundDataSetting" msgid="1400666012671648741">"पृष्ठभूमि डेटा प्रयोग सेटिङहरू परिवर्तन गर्नुहोस्"</string>
+    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"अनुप्रयोगलाई पृष्ठभूमि डेटा उपयोग सेटिङ परिवर्तन गर्न अनुमति दिन्छ।"</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">"वाइ-फाइ Multicast स्विकृतिलाई अनुमति दिनुहोस्"</string>
+    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"अनुप्रयोगलाई मल्टिकाष्ट ठेगानाहरू प्रयोग गरेर वाइ-फाइ नेटवर्कमा पठाइएको प्याकेटहरू प्राप्त गर्न अनुमति दिन्छ, केवल तपाईंको ट्याब्लेट मात्र होइन। यसले गैर-मल्टिकाष्ट मोड भन्दा बढी उर्जा प्रयोग गर्दछ।"</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="default" msgid="8931682159331542137">"अनुप्रयोगलाई स्थानीय ब्लुटुथ फोन कन्फिगर गर्न र टाढाका उपकरणहरूसँग खोज गर्न र जोडी गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_accessWimaxState" msgid="4195907010610205703">"WiMAXसँग जोड्नुहोस् वा छुटाउनुहोस्"</string>
+    <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"अनुप्रयोगलाई वाइम्याक्स सक्षम छ कि छैन र जडान भएको कुनै पनि वाइम्याक्स नेटवर्कहरूको बारेमा जानकारी निर्धारिण गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"वाइम्याक्स स्थिति परिवर्तन गर्नुहोस्"</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"अनुप्रयोगलाई वाइम्याक्स नेटवर्कहरूबाट ट्याब्लेट जडान गर्न र ट्याब्लेट विच्छेदन गर्न अनुमति दिन्छ।"</string>
+    <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"वाइम्याक्स नेटवर्कहरूसँग फोन जोड्न र छुटाउन अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_bluetooth" msgid="6127769336339276828">"ब्लुटुथ उपकरणहरूसँग जोडी मिलाउनुहोस्"</string>
+    <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"ट्याब्लेटमा ब्लुटुथको कन्फिगुरेसनलाई हेर्न र बनाउन र जोडी उपकरणहरूसँग जडानहरूलाई स्वीकार गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</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_readSyncSettings" msgid="6201810008230503052">"समीकरण सेटिङहरू पढ्नुहोस्"</string>
+    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"अनुप्रयोगलाई खाताको लागि सिङ्क सेटिङहरू पढ्न अनुमति दिन्छ। उदाहरणको लागि यसले व्यक्तिहरको अनुप्रयोग खातासँग सिङ्क भएको नभएको निर्धारण गर्न सक्दछ।"</string>
+    <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"टगल सिङ्क खुला र बन्द"</string>
+    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"अनुप्रयोगहरूलाई खाताको लागि सिङ्क सेटिङहरू परिमार्जन गर्न अनुमति दिन्छ। उदाहरणको लागि, यो खातासँग व्यक्ति अनुप्रयोगको सिङ्क सक्षम गर्न प्रयोग गर्न सकिन्छ।"</string>
+    <string name="permlab_readSyncStats" msgid="7396577451360202448">"सिङ्क तथ्याङ्कहरू पढ्नुहोस्"</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"अनुप्रयोगलाई खाताको लागि समीकरणको आँकडा समीकरण घटनाहरूको  इतिहास र समीकरण गरिएको डेटाको मापन समेत, पढ्न अनुमति दिन्छ।"</string>
+    <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"सदस्य बनाइका फिडहरू पढ्नुहोस्"</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"अनुप्रयोगलाई अहिलेको समीकरण गरिएका सूचकहरू बारे विवरणहरू लिने अनुमति दिन्छ।"</string>
+    <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"सदस्य बनाइका फिडहरू लेख्नुहोस्"</string>
+    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"तपाईँका भर्खरै सिङ्क फिडहरूलाई परिमार्जन गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ। तपाईँको सिङ्क फिडहरूलाई परिवर्तन गर्नको लागि यसले  खराब अनुप्रयोगलाई अनुमति दिन सक्छ।"</string>
+    <string name="permlab_readDictionary" msgid="4107101525746035718">"तपाईँले शब्दकोशमा थपेका शब्दहरू पढ्नुहोस्"</string>
+    <string name="permdesc_readDictionary" msgid="659614600338904243">"अनुप्रयोगलाई प्रयोगकर्ताले प्रयोगकर्ता शब्दकोशमा भण्डारण गरेका हुन सक्ने सबै शब्दहरू, नामहरू र पदावलीहरू पढ्न अनुमति दिन्छ।"</string>
+    <string name="permlab_writeDictionary" msgid="2183110402314441106">"प्रयोगकर्ता-परिभाषित शब्दकोशमा शब्दहरू थप्नुहोस्।"</string>
+    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"प्रयोगकर्ता शब्दकोशमा नयाँ शब्द लेख्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"सुरक्षित गरिएका भण्डारण पहुँचको परीक्षण गर्नुहोस्"</string>
+    <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"सुरक्षित गरिएका भण्डारण पहुँचको परीक्षण गर्नुहोस्"</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"भविष्य उपकरणहरूमा उपलब्ध हुने USB भण्डारणको लागि अनुमति परीक्षण गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"भविष्य उपकरणहरूमा उपलब्ध हुने 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_mediaStorageWrite" product="default" msgid="6859839199706879015">"आन्तरिक मिडिया भण्डारण सामग्रीहरू परिमार्जन गर्नुहोस्/मेटाउनुहोस्"</string>
+    <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"अनुप्रयोगलाई आन्तरिक मिडिया भण्डारणको सामग्रीहरू परिमार्जन गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"कागजात भण्डारण प्रबन्ध गर्नुहोस्"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"अनुप्रयोगलाई कागजात भण्डारण समायोजन गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"सबै उपयोगकर्ताहरूको बाह्य भण्डारणको पहुँच राख्नुहोस्"</string>
+    <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"अनुप्रयोगलाई सबै उपयोगकर्ताहरूको लागि बाह्य भण्डारणमाथि पहुँच राख्न अनुमति दिन्छ।"</string>
+    <string name="permlab_cache_filesystem" msgid="5656487264819669824">"क्यास फाइल प्रणाली पहुँच गर्नुहोस्।"</string>
+    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"केस फाइल प्रणालीलाई पढ्न र लेख्‍नको लागि अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_use_sip" msgid="5986952362795870502">"इन्टरनेट कलहरू गर्नुहोस् वा प्राप्त गर्नुहोस्"</string>
+    <string name="permdesc_use_sip" msgid="4717632000062674294">"इन्टरनेट कल गर्न/प्राप्त गर्न SIP सेवालाई प्रयोग गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ।"</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_markNetworkSocket" msgid="3658527214914959749">"सकेटको निशानहरू परिवर्तन गर्नुहोस्"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"मार्ग दर्शनको लागि अनुप्रयोगलाई सकेटको निशानहरू परिवर्तन गर्न अनुमति दिन्छ"</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_invokeCarrierSetup" msgid="3699600833975117478">"वाहक-प्रदान विन्यास अनुप्रयोग सुरु गर्नुहोस्"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"प्रयोगकर्तालाई वाहक-प्रदान विन्यास अनुप्रयोग सुरु गर्न अनुमति दिन्छ। साधारण अनुप्रयोगहरूलाई कहिल्यै आवश्यक पर्ने छैन।"</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"सञ्जाल अवस्थाका पर्यवेक्षणका लागि सुन्नुहोस्"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"सञ्जाल अवस्थाका पर्यवेक्षण सुन्नका लागि अनुप्रयोगलाई अनुमति दिन्छ।सामान्य अनुप्रयोगलाई चाँहिदै नचाँहिन सक्छ।"</string>
+    <string name="policylab_limitPassword" msgid="4497420728857585791">"पासवर्ड नियमहरू मिलाउनुहोस्"</string>
+    <string name="policydesc_limitPassword" msgid="3252114203919510394">"स्क्रिन-अनलक पासवर्डहरूमा अनुमति दिइएको लम्बाइ र अक्षरहरू नियन्त्रण गर्नुहोस्।"</string>
+    <string name="policylab_watchLogin" msgid="914130646942199503">"मोनिटर स्क्रिन-अनलक प्रयत्नहरू"</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"स्क्रिन अनलक गर्दा गलत पासवर्ड टाइप भएको संख्या निरीक्षण गर्नुहोस् र यदि निकै धेरै गलत पासवर्डहरू टाइप भएका छन भने ट्याब्लेट लक गर्नुहोस् वा ट्याब्लेटका सबै डेटा मेट्नुहोस्।"</string>
+    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"स्क्रिनअनलक गर्दा गलत पासवर्ड टाइप भएको संख्या निरीक्षण गर्नुहोस् र यदि निकै धेरै गलत पासवर्डहरू टाइप भएका छन भने फोन लक गर्नुहोस् वा फोनका सबै डेटा मेट्नुहोस्।"</string>
+    <string name="policylab_resetPassword" msgid="2620077191242688955">"स्क्रिन-अनलक पासवर्ड बदल्नुहोस्"</string>
+    <string name="policydesc_resetPassword" msgid="605963962301904458">"स्क्रिन-अनलक पासवर्ड परिवर्तन गर्नुहोस्।"</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="default" msgid="5096895604574188391">"एउटा फ्याक्ट्रि डेटा पुनःसेट गरेर चेतावनी नआउँदै फोनको डेटा मेट्नुहोस्।"</string>
+    <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"उपकरण विश्वव्यापी प्रोक्सी मिलाउनुहोस्"</string>
+    <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"नीति सक्षम हुँदा प्रयोग हुने उपकरण  विश्वव्यापी प्रोक्सी सेट गर्नुहोस्। प्रथम उपकरण प्रशासशनले मात्र प्रभावकारी विश्वव्यापी प्रोक्सी सेट गर्छ।"</string>
+    <string name="policylab_expirePassword" msgid="885279151847254056">"लक-स्क्रिन पासवर्ड अन्त सेट गर्नुहोस्"</string>
+    <string name="policydesc_expirePassword" msgid="1729725226314691591">"प्रायः कति छिटो लक-स्क्रिन पासवर्ड बदल्नु पर्छ यसलाई नियन्त्रण गर्नुहोस्।"</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="policylab_disableKeyguardFeatures" msgid="266329104542638802">"किगार्डमा भएका विशेषताहरू असक्षम पार्नुहोस्"</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="3467082272186534614">"केही किगार्ड विशेषताहरूको प्रयोग रोक्नुहोस्।"</string>
+  <string-array name="phoneTypes">
+    <item msgid="8901098336658710359">"गृह"</item>
+    <item msgid="869923650527136615">"मोबाइल"</item>
+    <item msgid="7897544654242874543">"काम गर्नुहोस्"</item>
+    <item msgid="1103601433382158155">"कार्य फ्याक्स"</item>
+    <item msgid="1735177144948329370">"घरको फ्याक्स"</item>
+    <item msgid="603878674477207394">"पेजर"</item>
+    <item msgid="1650824275177931637">"अन्य"</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>
+  </string-array>
+  <string-array name="postalAddressTypes">
+    <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="1359644565647383708">"काम"</item>
+    <item msgid="7868549401053615677">"अन्य"</item>
+    <item msgid="3145118944639869809">"अनुकूलन"</item>
+  </string-array>
+  <string-array name="organizationTypes">
+    <item msgid="7546335612189115615">"काम गर्नुहोस्"</item>
+    <item msgid="4378074129049520373">"अन्य"</item>
+    <item msgid="3455047468583965104">"अनुकूलन"</item>
+  </string-array>
+  <string-array name="imProtocols">
+    <item msgid="8595261363518459565">"AIM"</item>
+    <item msgid="7390473628275490700">"Windows Live"</item>
+    <item msgid="7882877134931458217">"Yahoo"</item>
+    <item msgid="5035376313200585242">"स्काइप"</item>
+    <item msgid="7532363178459444943">"QQ"</item>
+    <item msgid="3713441034299660749">"Google Talk"</item>
+    <item msgid="2506857312718630823">"ICQ"</item>
+    <item msgid="1648797903785279353">"Jabber"</item>
+  </string-array>
+    <string name="phoneTypeCustom" msgid="1644738059053355820">"अनुकूलन"</string>
+    <string name="phoneTypeHome" msgid="2570923463033985887">"गृह"</string>
+    <string name="phoneTypeMobile" msgid="6501463557754751037">"मोबाइल"</string>
+    <string name="phoneTypeWork" msgid="8863939667059911633">"काम"</string>
+    <string name="phoneTypeFaxWork" msgid="3517792160008890912">"कार्य फ्याक्स"</string>
+    <string name="phoneTypeFaxHome" msgid="2067265972322971467">"घरको फ्याक्स"</string>
+    <string name="phoneTypePager" msgid="7582359955394921732">"पेजर"</string>
+    <string name="phoneTypeOther" msgid="1544425847868765990">"अन्य"</string>
+    <string name="phoneTypeCallback" msgid="2712175203065678206">"कलब्याक"</string>
+    <string name="phoneTypeCar" msgid="8738360689616716982">"कार"</string>
+    <string name="phoneTypeCompanyMain" msgid="540434356461478916">"कम्पनी मुख्य"</string>
+    <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string>
+    <string name="phoneTypeMain" msgid="6766137010628326916">"मुख्य"</string>
+    <string name="phoneTypeOtherFax" msgid="8587657145072446565">"अन्य फ्याक्स"</string>
+    <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="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="eventTypeBirthday" msgid="2813379844211390740">"जन्मदिन"</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>
+    <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="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="imTypeWork" msgid="1371489290242433090">"काम"</string>
+    <string name="imTypeOther" msgid="5377007495735915478">"अन्य"</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>
+    <string name="imProtocolSkype" msgid="9019296744622832951">"स्काइप"</string>
+    <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
+    <string name="imProtocolGoogleTalk" msgid="493902321140277304">"ह्याङआउटहरू"</string>
+    <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">"काम"</string>
+    <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="relationTypeBrother" msgid="8757913506784067713">"भाइ"</string>
+    <string name="relationTypeChild" msgid="1890746277276881626">"बच्चो"</string>
+    <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"आन्तरिक साझेदार"</string>
+    <string name="relationTypeFather" msgid="5228034687082050725">"बुबा"</string>
+    <string name="relationTypeFriend" msgid="7313106762483391262">"मित्र"</string>
+    <string name="relationTypeManager" msgid="6365677861610137895">"ब्यवस्थापक"</string>
+    <string name="relationTypeMother" msgid="4578571352962758304">"आमा"</string>
+    <string name="relationTypeParent" msgid="4755635567562925226">"अभिभावक"</string>
+    <string name="relationTypePartner" msgid="7266490285120262781">"पार्टनर"</string>
+    <string name="relationTypeReferredBy" msgid="101573059844135524">"द्वारा उल्लिखित"</string>
+    <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="sipAddressTypeHome" msgid="6093598181069359295">"गृह"</string>
+    <string name="sipAddressTypeWork" msgid="6920725730797099047">"काम गर्नुहोस्"</string>
+    <string name="sipAddressTypeOther" msgid="4408436162950119849">"अन्य"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN कोड टाइप गर्नुहोस्"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK र नयाँ PIN कोड टाइप गर्नुहोस्"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK कोड"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"नयाँ PIN कोड"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><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">"अनलक गर्न PIN कोड टाइप गर्नुहोस्"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"गलत PIN कोड।"</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"अनलक गर्न मेनु थिच्नुहोस् र त्यसपछि ० थिच्नुहोस्।"</string>
+    <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"आपतकालीन नम्बर"</string>
+    <string name="lockscreen_carrier_default" msgid="8963839242565653192">"सेवा छैन।"</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="5347633784401285225">"आपतकालीन कलहरू"</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="faceunlock_multiple_failures" msgid="754137583022792429">"अत्याधिक मोहडा खोल्ने प्रयासहरू बढी भए।"</string>
+    <string name="lockscreen_plugged_in" msgid="8057762828355572315">"चार्ज हुँदै, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_charged" msgid="321635745684060624">"चार्ज भयो"</string>
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_low_battery" msgid="1482873981919249740">"तपाईँको चार्जर जोड्नुहोस्।"</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="default" msgid="2186920585695169078">"फोनमा SIM कार्ड छैन।"</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_transport_prev_description" msgid="201594905152746886">"अघिल्लो ट्रयाक बटन"</string>
+    <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"अर्को ट्रयाक बटन"</string>
+    <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"रोक्ने बटन"</string>
+    <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"बजाउने बटन"</string>
+    <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"बटन रोक्नुहोस्"</string>
+    <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">"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">%d</xliff:g> पटक खिच्नु भएको छ। \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकेन्डमा फेरि कोसिस गर्नुहोस्।"</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"तपाईंले गलत तरिकाले आफ्नो पासवर्ड <xliff:g id="NUMBER_0">%d</xliff:g> पटक टाइप गर्नुभयो। \n\n<xliff:g id="NUMBER_1">%d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"तपाईँले गलत तरिकाले तपाईँको PIN <xliff:g id="NUMBER_0">%d</xliff:g> पटक टाइप गर्नु भएको छ। \n\n<xliff:g id="NUMBER_1">%d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"तपाईँले तपाईँको अनलक ढाँचा गलत तरिकाले <xliff:g id="NUMBER_0">%d</xliff:g> पटक खिच्नु भएको छ। पछि <xliff:g id="NUMBER_1">%d</xliff:g> थप असफल कोसिसहरू, तपाईँको Google साइन इन प्रयोग गरी तपाईँको ट्याब्लेट अनलक गर्न भनिने छ।\n\n  <xliff:g id="NUMBER_2">%d</xliff:g> सेकेन्डमा फरि प्रयास गर्नुहोस्।"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"तपाईँले <xliff:g id="NUMBER_0">%d</xliff:g> पटक गलत तरिकाले तपाईँको अनलक ढाँचालाई कोर्नु भएको छ। पछि <xliff:g id="NUMBER_1">%d</xliff:g> अरू धेरै असफल कोसिसहरूपछि, तपाईँलाई तपाईँको फोन Google साइन इन प्रयोग गरेर अनलक गर्नको लागि सोधिने छ। \n\n <xliff:g id="NUMBER_2">%d</xliff:g> सेकेन्डमा पुनः प्रयास गर्नुहोस्।"</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"तपाईँले <xliff:g id="NUMBER_0">%d</xliff:g> पटक ट्याब्लेटलाई अनलक गर्नको लागि गलत तरिकाले कोशिस गर्नुभएको छ। <xliff:g id="NUMBER_1">%d</xliff:g> अरू धेरै असफल कोसिसहरूपछि, ट्याब्लेट फ्याट्रि पूर्वनिर्धारितमा पुनःसेट हुने छ र सबै प्रयोगकर्ता डेटा हराउने छन्।"</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"तपाईंले गलत तरिकाले <xliff:g id="NUMBER_0">%d</xliff:g> पटक फोन अनलक गर्ने प्रयत्न गर्नुभयो। <xliff:g id="NUMBER_1">%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="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_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_checking_password" msgid="7114627351286933867">"जाँच गर्दै..."</string>
+    <string name="lockscreen_unlock_label" msgid="737440483220667054">"खोल्नुहोस्"</string>
+    <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"आवाज चालु छ।"</string>
+    <string name="lockscreen_sound_off_label" msgid="996822825154319026">"ध्वनि बन्द"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"ढाँचा सुरु भयो"</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"ढाँचा हटाइएको"</string>
+    <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"सेल थप गरियो"</string>
+    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"ढाँचा पुरा भयो"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. विजेट %2$d of %3$d।"</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_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>
+    <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_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">"Pin अनलक"</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">"?१२३"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <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_line" msgid="5764267235026120888">"लाइन"</string>
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
+    <string name="factorytest_failed" msgid="5410270329114212041">"कार्यशाला परीक्षण असफल भयो।"</string>
+    <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST कार्रवाइले /system/app मा स्थापित प्याकेजहरूको लागि मात्र समर्थन गर्छ।"</string>
+    <string name="factorytest_no_action" msgid="872991874799998561">"कुनै प्याकेज फेला पार्न सकिएन जसले FACTORY_TEST कार्य प्रदान गर्दछ।"</string>
+    <string name="factorytest_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>
+    <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="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>
+    <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$१$२$३"</string>
+    <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
+    <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
+    <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">"ZIP कोड"</string>
+    <string name="autofill_county" msgid="237073771020362891">"काउन्टी"</string>
+    <string name="autofill_island" msgid="4020100875984667025">"टापु"</string>
+    <string name="autofill_district" msgid="8400735073392267672">"जिल्ला"</string>
+    <string name="autofill_department" msgid="5343279462564453309">"विभाग"</string>
+    <string name="autofill_prefecture" msgid="2028499485065800419">"प्रशासकीय क्षेत्र"</string>
+    <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="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_packageVerificationAgent" msgid="5568139100645829117">"प्यकेजहरूको निरीक्षण गर्नुहोस्"</string>
+    <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"प्याकेज स्थापना योग्य छ कि भनेर रुजु गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"एउटा प्याकेज रुजुकर्तामा बाँध्नुहोस्"</string>
+    <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"होल्डरलाई प्याकेज प्रमाणितकर्ताहरूको अनुरोधहरू बनाउन अनुमति दिन्छ। सामान्य अनुप्रयोगहरूलाई कहिले पनि आवश्यक नपर्न सक्दछ।"</string>
+    <string name="permlab_serialPort" msgid="546083327654631076">"पहुँच सिरियल पोर्टहरू"</string>
+    <string name="permdesc_serialPort" msgid="2991639985224598193">"होल्डरलाई SerialManager API प्रयोग गरेर सिरियल पोर्टहरू पहुँच गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"विषयसूची प्रदातालाई बाह्य रूपमा पहुँच गर्नुहोस्"</string>
+    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"सेलबाट धारकले विषयवस्तु प्रदायकहरूसम्मको पहुँच पाउन अनुमति दिन्छ। सामान्य अनुप्रयोगहरूलाई कहिल्यै आवश्यक पर्दैन।"</string>
+    <string name="permlab_updateLock" msgid="3527558366616680889">"स्वचालित उपकरण अपडेटहरू हतोत्साहित गर्नुहोस्"</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"होल्डरलाई उपकरण अपग्रेड गर्न गैर पारस्परिक पुनःबुटको लागि उचित समयको बारेमा प्रणालीमा जानाकारी प्रस्तावको लागि अनुमति दिन्छ।"</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>
+    <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="menu_space_shortcut_label" msgid="2410328639272162537">"ठाउँ"</string>
+    <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"प्रविष्टि गर्नुहोस्"</string>
+    <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"मेटाउनुहोस्"</string>
+    <string name="search_go" msgid="8298016669822141719">"खोज्नुहोस्"</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="oneMonthDurationPast" msgid="7396384508953779925">"१ महिना अघि"</string>
+    <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"१ महिना अघि"</string>
+  <plurals name="num_seconds_ago">
+    <item quantity="one" msgid="4869870056547896011">"१ सेकेन्ड अघि"</item>
+    <item quantity="other" msgid="3903706804349556379">"<xliff:g id="COUNT">%d</xliff:g> सेकेन्ड अघि"</item>
+  </plurals>
+  <plurals name="num_minutes_ago">
+    <item quantity="one" msgid="3306787433088810191">"१ मिनेट अघि"</item>
+    <item quantity="other" msgid="2176942008915455116">"<xliff:g id="COUNT">%d</xliff:g> मिनेट अघि"</item>
+  </plurals>
+  <plurals name="num_hours_ago">
+    <item quantity="one" msgid="9150797944610821849">"१ घन्टा अघि"</item>
+    <item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> घन्टा अघि"</item>
+  </plurals>
+  <plurals name="last_num_days">
+    <item quantity="other" msgid="3069992808164318268">"अन्तिम <xliff:g id="COUNT">%d</xliff:g> दिन"</item>
+  </plurals>
+    <string name="last_month" msgid="3959346739979055432">"अन्तिम महिना"</string>
+    <string name="older" msgid="5211975022815554840">"पुरानो"</string>
+  <plurals name="num_days_ago">
+    <item quantity="one" msgid="861358534398115820">"हिजो"</item>
+    <item quantity="other" msgid="2479586466153314633">"<xliff:g id="COUNT">%d</xliff:g> दिन अघि"</item>
+  </plurals>
+  <plurals name="in_num_seconds">
+    <item quantity="one" msgid="2729745560954905102">"१ सेकेन्डमा"</item>
+    <item quantity="other" msgid="1241926116443974687">"<xliff:g id="COUNT">%d</xliff:g> सेकेन्डमा"</item>
+  </plurals>
+  <plurals name="in_num_minutes">
+    <item quantity="one" msgid="8793095251325200395">"१ मिनेटमा"</item>
+    <item quantity="other" msgid="3330713936399448749">"<xliff:g id="COUNT">%d</xliff:g>मिनेटमा"</item>
+  </plurals>
+  <plurals name="in_num_hours">
+    <item quantity="one" msgid="7164353342477769999">"१ घन्टामा"</item>
+    <item quantity="other" msgid="547290677353727389">"<xliff:g id="COUNT">%d</xliff:g> घन्टामा"</item>
+  </plurals>
+  <plurals name="in_num_days">
+    <item quantity="one" msgid="5413088743009839518">"भोलि"</item>
+    <item quantity="other" msgid="5109449375100953247">"<xliff:g id="COUNT">%d</xliff:g> दिनमा"</item>
+  </plurals>
+  <plurals name="abbrev_num_seconds_ago">
+    <item quantity="one" msgid="1849036840200069118">"१ सेकेन्ड अघि"</item>
+    <item quantity="other" msgid="3699169366650930415">"<xliff:g id="COUNT">%d</xliff:g> सेकेन्ड अगाडि"</item>
+  </plurals>
+  <plurals name="abbrev_num_minutes_ago">
+    <item quantity="one" msgid="6361490147113871545">"१ मिनेट अघि"</item>
+    <item quantity="other" msgid="851164968597150710">"<xliff:g id="COUNT">%d</xliff:g> मिनेट अघि"</item>
+  </plurals>
+  <plurals name="abbrev_num_hours_ago">
+    <item quantity="one" msgid="4796212039724722116">"१ घन्टा अघि"</item>
+    <item quantity="other" msgid="6889970745748538901">"<xliff:g id="COUNT">%d</xliff:g> घन्टा अघि"</item>
+  </plurals>
+  <plurals name="abbrev_num_days_ago">
+    <item quantity="one" msgid="8463161711492680309">"हिजो"</item>
+    <item quantity="other" msgid="3453342639616481191">"<xliff:g id="COUNT">%d</xliff:g> दिन अघि"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_seconds">
+    <item quantity="one" msgid="5842225370795066299">"१ सेकन्ड"</item>
+    <item quantity="other" msgid="5495880108825805108">"<xliff:g id="COUNT">%d</xliff:g> सेकेन्डमा"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_minutes">
+    <item quantity="one" msgid="562786149928284878">"१ मिनेटमा"</item>
+    <item quantity="other" msgid="4216113292706568726">"<xliff:g id="COUNT">%d</xliff:g> मिनेटमा"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_hours">
+    <item quantity="one" msgid="3274708118124045246">"१ घन्टामा"</item>
+    <item quantity="other" msgid="3705373766798013406">"<xliff:g id="COUNT">%d</xliff:g> घन्टामा"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_days">
+    <item quantity="one" msgid="2178576254385739855">"भोलि"</item>
+    <item quantity="other" msgid="2973062968038355991">"दिन<xliff:g id="COUNT">%d</xliff:g> मा"</item>
+  </plurals>
+    <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>
+    <string name="days" msgid="4774547661021344602">"दिन"</string>
+    <string name="hour" msgid="2126771916426189481">"घन्टा"</string>
+    <string name="hours" msgid="894424005266852993">"घन्टा"</string>
+    <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="week" msgid="5617961537173061583">"हप्ता"</string>
+    <string name="weeks" msgid="6509623834583944518">"हप्ताहरू"</string>
+    <string name="year" msgid="4001118221013892076">"वर्ष"</string>
+    <string name="years" msgid="6881577717993213522">"वर्षहरू"</string>
+  <plurals name="duration_seconds">
+    <item quantity="one" msgid="6962015528372969481">"१ सेकेन्ड"</item>
+    <item quantity="other" msgid="1886107766577166786">"<xliff:g id="COUNT">%d</xliff:g> सेकेन्ड"</item>
+  </plurals>
+  <plurals name="duration_minutes">
+    <item quantity="one" msgid="4915414002546085617">"१ मिनेट"</item>
+    <item quantity="other" msgid="3165187169224908775">"<xliff:g id="COUNT">%d</xliff:g> मिनेट"</item>
+  </plurals>
+  <plurals name="duration_hours">
+    <item quantity="one" msgid="8917467491248809972">"१ घन्टा"</item>
+    <item quantity="other" msgid="3863962854246773930">"<xliff:g id="COUNT">%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_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>
+    <string name="midnight" msgid="7166259508850457595">"मध्यरात"</string>
+    <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="cut" msgid="3092569408438626261">"काट्नुहोस्"</string>
+    <string name="copy" msgid="2681946229533511987">"प्रतिलिपि बनाउनुहोस्"</string>
+    <string name="paste" msgid="5629880836805036433">"टाँस्नुहोस्"</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="textSelectionCABTitle" msgid="5236850394370820357">"पाठ चयनता"</string>
+    <string name="addToDictionary" msgid="4352161534510057874">"शब्दकोशमा थप्नुहोस्"</string>
+    <string name="deleteText" msgid="6979668428458199034">"मेट्नुहोस्"</string>
+    <string name="inputMethod" msgid="1653630062304567879">"निवेश विधि"</string>
+    <string name="editTextMenuTitle" msgid="4909135564941815494">"पाठ कार्यहरू"</string>
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"भण्डारण ठाउँ सकिँदै छ"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"सायद केही प्रणाली कार्यक्रमहरूले काम गर्दैनन्"</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="4653586947747330058">"थप सूचनाको लागि छुनुहोस् वा अनुप्रयोग बन्द गर्नुहोस्।"</string>
+    <string name="ok" msgid="5970060430562524910">"ठिक छ"</string>
+    <string name="cancel" msgid="6442560571259935130">"रद्द गर्नुहोस्"</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>
+    <string name="capital_on" msgid="1544682755514494298">"चालु"</string>
+    <string name="capital_off" msgid="6815870386972805832">"बन्द"</string>
+    <string name="whichApplication" msgid="4533185947064773386">"प्रयोग गरेर कारबाही पुरा गर्नुहोस्"</string>
+    <string name="alwaysUse" msgid="4583018368000610438">"यस कार्यको लागि पूर्वनिर्धारितबाट प्रयोग गर्नुहोस्।"</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="aerr_title" msgid="1905800560317137752"></string>
+    <string name="aerr_application" msgid="932628488013092776">"दुर्भाग्यवश, <xliff:g id="APPLICATION">%1$s</xliff:g>ले रोकेको छ।"</string>
+    <string name="aerr_process" msgid="4507058997035697579">"दुर्भाग्यवश, प्रक्रिया <xliff:g id="PROCESS">%1$s</xliff:g> बन्द भयो।"</string>
+    <string name="anr_title" msgid="4351948481459135709"></string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g>ले कार्य गरिरहेको छैन।\n\nके तपाईँ यसलाई बन्द गर्न चाहनु हुन्छ?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"गतिविधि <xliff:g id="ACTIVITY">%1$s</xliff:g> ले प्रतिक्रिया देखाइरहेको छैन।\n\nके तपाईं यसलाई बन्द गर्न चाहनु हुन्छ?"</string>
+    <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> जवाफ दिइरहेको छैन। के तपाईँ यसलाई बन्द गर्न चाहनु हुन्छ?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"प्रक्रिया <xliff:g id="PROCESS">%1$s</xliff:g>ले कार्य गरिरहेको छैन।\n\nके तपाईँ यसलाई बन्द गर्न चाहनु हुन्छ?"</string>
+    <string name="force_close" msgid="8346072094521265605">"ठिक छ"</string>
+    <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_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; अनुप्रयोगहरू &gt; डाउनलोड गरेको।"</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">"एन्ड्रोइड अपग्रेड हुँदैछ…"</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_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="1721681741617898865">"अनुप्रयोगमा स्विच गर्न छुनुहोस्"</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>
+    <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="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_silent_ringtone_selected" msgid="8310739960973156272">"शान्त रिङ्गटोन सेट"</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">"ब्लुटुथ भोल्युम"</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="8129563480895990372">"पूर्वनिर्धारित रिङटोन (<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_unknown" msgid="5477919988701784788">"अज्ञात रिङटोन"</string>
+  <plurals name="wifi_available">
+    <item quantity="one" msgid="6654123987418168693">"वाइ-फाइ नेटवर्क उपलब्ध छ"</item>
+    <item quantity="other" msgid="4192424489168397386">"वाइ-फाइ नेटवर्कहरू उपलब्ध"</item>
+  </plurals>
+  <plurals name="wifi_available_detailed">
+    <item quantity="one" msgid="1634101450343277345">"खुल्ला वाइ-फाइ नेटवर्क उपलब्ध छ"</item>
+    <item quantity="other" msgid="7915895323644292768">"खुल्ला वाइ-फाइ नेटवर्क उपलब्ध छ"</item>
+  </plurals>
+    <string name="wifi_available_sign_in" msgid="4029489716605255386">"वाइ-फाइ नेटवर्कमा साइन गर्नुहोस्"</string>
+    <string name="network_available_sign_in" msgid="8495155593358054676">"नेटवर्कमा साइन गर्नुहोस्।"</string>
+    <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
+    <skip />
+    <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"वाइ-फाइसँग जडान गर्न सकेन"</string>
+    <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" कमजोर इन्टरनेट जडान छ।"</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="1638949953993894335">"सेटिङहरूको लागि छुनुहोस्"</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_to_connect_title" msgid="4958803948658533637">"जडानमा निमन्त्रणा"</string>
+    <string name="wifi_p2p_from_message" msgid="570389174731951769">"बाट:"</string>
+    <string name="wifi_p2p_to_message" msgid="248968974522044099">"प्रापक:"</string>
+    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"आवश्यक PIN टाइप गर्नुहोस्:"</string>
+    <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</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="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="3492025719868078457">"यसले "<font fgcolor="#ffffb060">" शुल्क लगाउन सक्छ"</font>" तपाईँको मोबाइल खातामा।"</string>
+    <string name="sms_premium_short_code_details" msgid="5523826349105123687"><font fgcolor="#ffffb060">"यसले तपाईंको मोबाइल खातामा चार्जहरू उत्पन्न गर्दछ।"</font></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_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_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="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_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="usb_storage_activity_title" msgid="4465055157209648641">"USB ठूलो भण्डारण"</string>
+    <string name="usb_storage_title" msgid="5901459041398751495">"USB जोडिएको छ"</string>
+    <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"तपाईं आफ्नो कम्प्युटरमा USB मार्फत जडान हुनुभयो। तलको बटन टच गर्नुहोस् यदि तपाईं आफ्नो कम्प्युटर र एन्ड्रोइडको USB भण्डारण बीच फाइलहरू प्रतिलिपि गर्न चाहनुहुन्छ भने।"</string>
+    <string name="usb_storage_message" product="default" msgid="805351000446037811">"तपाईं आफ्नो कम्प्युटरमा USB मार्फत जडान हुनुभयो। तलको बटन टच गर्नुहोस् यदि तपाईं आफ्नो कम्प्युटर र एन्ड्रोइडको SD कार्ड बीच फाइलहरू प्रतिलिपि गर्न चाहनुहुन्छ भने।"</string>
+    <string name="usb_storage_button_mount" msgid="1052259930369508235">"USB भण्डारण चालु गर्नुहोस्"</string>
+    <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"USB आम भण्डारणको लागि तपाईँको USB भण्डारण प्रयोग गर्दा एउटा समस्या भयो।"</string>
+    <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"USB आम भण्डारणको लागि तपाईँको SD कार्ड प्रयोग गर्दा एउटा समस्या भयो।"</string>
+    <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB जोडिएको छ"</string>
+    <string name="usb_storage_notification_message" msgid="939822783828183763">"तपाईँको कम्प्युटरबाट वा तिर फाइलहरू प्रतिलिप गर्न छुनुहोस्।"</string>
+    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"USB भण्डारण बन्द गर्नुहोस्"</string>
+    <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"USB भण्डारण बन्द गर्न छुनुहोस्।"</string>
+    <string name="usb_storage_stop_title" msgid="660129851708775853">"USB भण्डारण प्रयोगमा छ"</string>
+    <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"USB भण्डारण बन्द हुनुभन्दा पहीले तपाईँको कम्प्युटरबाट तपाईँको एन्ड्रोइड USB भण्डारण अनमाउन्ट (\"झिक्नुहोस्\") गर्नुहोस् ।"</string>
+    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"USB भण्डारण बन्द गर्नुअघि तपाईँको कम्प्युटरबाट तपाईँको एन्ड्रोइडको SD कार्ड अनमाउन्ट (\"निकालेको\") गर्नुहोस्।"</string>
+    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"USB भण्डारण बन्द गर्नुहोस्"</string>
+    <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"USB भण्डारण बन्द गर्दा एउटा समस्या भयो। तपाईँले USB होस्ट अनमाउन्ट गर्नु भएको जाँच गर्नुहोस्, त्यसपछि फेरि प्रयास गर्नुहोस्।"</string>
+    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"USB भण्डारण खोल्नुहोस्"</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"यदि तपाईँले USB भण्डारण खोल्नु भयो भने तपाईँले प्रयोग गरिरहनु भएका केही अनुप्रयोगहरू रोकिने छन् र तपाईँले USB भण्डारण बन्द नगरेसम्म अनुपलब्ध हुन सक्छन्।"</string>
+    <string name="dlg_error_title" msgid="7323658469626514207">"USB संचालन असफल"</string>
+    <string name="dlg_ok" msgid="7376953167039865701">"ठिक छ"</string>
+    <string name="usb_mtp_notification_title" msgid="3699913097391550394">"मिडिया उपकरणको रूपमा जडित"</string>
+    <string name="usb_ptp_notification_title" msgid="1960817192216064833">"क्यामेराको रूपमा जडान भएको"</string>
+    <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"एउटा स्थापनकर्ताको रूपमा जोडिएको छ"</string>
+    <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB सहायकमा जोडिएको छ"</string>
+    <string name="usb_notification_message" msgid="2290859399983720271">"अन्य USB विकल्पहरूको लागि टच गर्नुहोस्।"</string>
+    <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB भण्डारणलाई फर्म्याट  गर्न चाहनु हुन्छ?"</string>
+    <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD कार्ड फर्म्याट गर्ने?"</string>
+    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"तपाईंको USBमा सङ्ग्रह भएका सबै फाइलहरू मेटिने छन्। यो कार्य उल्टाउन सकिँदैन!"</string>
+    <string name="extmedia_format_message" product="default" msgid="14131895027543830">"तपाईँको कार्डमा भएका सबै डेटाहरू हराउने छन्।"</string>
+    <string name="extmedia_format_button_format" msgid="4131064560127478695">"फर्म्याट गर्नुहोस्"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"USB डिबग गर्ने जडित छ"</string>
+    <string name="adb_active_notification_message" msgid="1016654627626476142">"USB डिबग गर्ने असक्षम पार्न छुनुहोस्।"</string>
+    <string name="select_input_method" msgid="4653387336791222978">"निवेश विधि छान्नुहोस्"</string>
+    <string name="configure_input_methods" msgid="9091652157722495116">"इनपुट विधिहरू सेटअप गर्नुहोस्"</string>
+    <string name="use_physical_keyboard" msgid="6203112478095117625">"भौतिक किबोर्ड"</string>
+    <string name="hardware" msgid="7517821086888990278">"हार्डवेयर"</string>
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"किबोर्ड रूपरेखा चयन गर्नुहोस्"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"किबोर्ड रूपरेखा चयन गर्न टच गर्नुहोस्।"</string>
+    <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="candidates_style" msgid="4333913089637062257"><u>"उम्मेदवार"</u></string>
+    <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"USB भण्डारणको तयारी हुँदै"</string>
+    <string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"SD कार्ड तयार गर्दै"</string>
+    <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"त्रुटिहरूको लागि जाँच गर्दै।"</string>
+    <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"रिक्त USB भण्डारण"</string>
+    <string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"खाली SD कार्ड"</string>
+    <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"USB भण्डारण खाली वा असमर्थित फाइल प्रणाली छ।"</string>
+    <string name="ext_media_nofs_notification_message" product="default" msgid="8641065641786923604">"SD कार्ड खाली छ अथवा समर्थन नगरिएको फाइल प्रणाली छ।"</string>
+    <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"बिग्रिएको USB भण्डारण"</string>
+    <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"बिग्रिएको SD कार्ड"</string>
+    <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="1795917578395333280">"USB भण्डारण बिग्रिएको छ। यसलाई पुनःफर्म्याट गर्न प्रयास गर्नुहोस।"</string>
+    <string name="ext_media_unmountable_notification_message" product="default" msgid="1753898567525568253">"SD कार्ड बिग्रिएको छ। यसलाई पुनःफर्म्याट गर्न प्रयास गर्नुहोस।"</string>
+    <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"USB भण्डारण अप्रत्याशित रूपमा हटाइएको छ"</string>
+    <string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"SD कार्ड अनपेक्षित रूपमा हटाइयो"</string>
+    <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"डेटा गुम्नबाट रोक्नको लागि USB भण्डारण हटाउनुअघि अनमाउन्ट गर्नुहोस्।"</string>
+    <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"डेटा नाश हुनबाट बच्न SD कार्डलाई निकाल्नुभन्दा पहिला अनमाउन्ट गर्नुहोस्।"</string>
+    <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"USB भण्डारण हटाउनको लागि सुरक्षित छ"</string>
+    <string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"SD कार्ड हटाउन सुरक्षित छ।"</string>
+    <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"तपाईं सुरक्षित रूपमा USB भण्डारण हटाउन सक्नुहुने छ।"</string>
+    <string name="ext_media_safe_unmount_notification_message" product="default" msgid="568841278138377604">"तपाईँ SD कार्ड सुरक्षित रूपमा हटाउन सक्नु हुन्छ।"</string>
+    <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"USB भण्डारण हटाइयो"</string>
+    <string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"हटाइएको SD कार्ड"</string>
+    <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"USD भण्डारण हटाइयो। नयाँ मिडिया घुसाउनुहोस्।"</string>
+    <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"SD कार्ड हटाइयो। एउटा नयाँ छिराउनुहोस्।"</string>
+    <string name="activity_list_empty" msgid="1675388330786841066">"कुनै मिल्ने गतिविधि पाइएन।"</string>
+    <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"खण्ड प्रयोग तथ्याङ्कहरू अपडेट गर्नुहोस्"</string>
+    <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"जम्मा गरिएको घटक उपयोग तथ्याङ्कहरूलाई परिमार्जन गर्न अनुप्रयोगलाई अनुमति दिन्छ। सामान्य अनुप्रयोगहरूबाट प्रयोगको लागि होइन।"</string>
+    <string name="permlab_copyProtectedData" msgid="4341036311211406692">"सामाग्रीको नकल गर्नुहोस्"</string>
+    <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"अनुप्रयोगलाई सामग्री प्रतिलिपि गर्न पूर्वनिर्धारित कन्टेनर सेवा आह्वान गर्न अनुमति दिन्छ। साधारण अनुप्रयोगहरूद्वाराको प्रयोगको लागि होइन।"</string>
+    <string name="permlab_route_media_output" msgid="1642024455750414694">"मिडिया परिणाम दिशानिर्देश गर्नुहोस्"</string>
+    <string name="permdesc_route_media_output" msgid="4932818749547244346">"मिडिया परिणामलाई अन्य बाहिरी उपकरणहरूसँग लैजानको लागि अनुप्रयोगलाई अनुमति दिन्छ।"</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"किगार्ड सुरक्षित भण्डारण पहुँच गर्नुहोस्"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"अनुप्रयोगलाई किगार्ड सुरक्षित भण्डारण पहुँच गर्न अनुमति दिन्छ।"</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"किगार्ड प्रदर्शन गर्ने र लुकाउने नियन्त्रण गर्नुहोस्"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"अनुप्रयोगलाई किगार्ड नियन्त्रण गर्न अनुमति दिन्छ।"</string>
+    <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"जुम नियन्त्रणको लागि दुई चोटि टच गर्नुहोस्"</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>
+    <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">\n"नम्बर डायल गर्नुहोस् <xliff:g id="NUMBER">%s</xliff:g> प्रयोग गरेर"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"सम्पर्क सिर्जना गर्नुहोस्\nयो <xliff:g id="NUMBER">%s</xliff:g> प्रयोग गरेर"</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"निम्न एउटा वा धेरै अनुप्रयोगहरूले तपाईँको खातामा पहुँचको लागि अनुमति अहिले र भविष्यमा अनुरोध गर्छन्।"</string>
+    <string name="grant_credentials_permission_message_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">\n"खाता <xliff:g id="ACCOUNT">%s</xliff:g>को लागि अनुरोध गरिएको अनुमति।"</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>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"वालपेपर परिवर्तन गर्नुहोस्"</string>
+    <string name="notification_listener_binding_label" msgid="2014162835481906429">"सूचना सुन्नेवाला"</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="3011306607126450322">"नेटवर्क प्रबन्ध गर्न छुनुहोस्।"</string>
+    <string name="vpn_text_long" msgid="6407351006249174473">"<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_error" msgid="6009249814034708175">"सधैँ भरि VPN त्रुटिमा"</string>
+    <string name="vpn_lockdown_config" msgid="6415899150671537970">"कन्फिगर गर्न टच गर्नुहोस्"</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="8035230537563503262">"कार मोडबाट निस्कन छुनुहोस्।"</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"टेथर गर्ने वा हटस्पट सक्रिय"</string>
+    <string name="tethered_notification_message" msgid="6857031760103062982">"सेटअप गर्न टच गर्नुहोस्।"</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="throttle_warning_notification_title" msgid="4890894267454867276">"उच्च मोबाइल डेटा प्रयोग"</string>
+    <string name="throttle_warning_notification_message" msgid="3340822228599337743">"मोबाइल डेटा प्रयोगको बारेमा अरू थप जान्नको लागि  छुनुहोस्।"</string>
+    <string name="throttled_notification_title" msgid="6269541897729781332">"मोबाइल डेटा सीमा पार भयो"</string>
+    <string name="throttled_notification_message" msgid="5443457321354907181">"मोबाइल डेटा प्रयोग बारे थप सिक्न छुनुहोस्।"</string>
+    <string name="no_matches" msgid="8129421908915840737">"कुनै मिलेन"</string>
+    <string name="find_on_page" msgid="1946799233822820384">"पृष्ठमा फेला पार्नुहोस्"</string>
+  <plurals name="matches_found">
+    <item quantity="one" msgid="8167147081136579439">"१ मेल"</item>
+    <item quantity="other" msgid="4641872797067609177">"<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="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"USB  भण्डारण अनमाउन्ट गर्दै..."</string>
+    <string name="progress_unmounting" product="default" msgid="1327894998409537190">"SD कार्ड अनमाउन्ट गर्दै…"</string>
+    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"USB भण्डारण मेटाउँदै…"</string>
+    <string name="progress_erasing" product="default" msgid="6596988875507043042">"SD कार्ड मेटाउँदै…"</string>
+    <string name="format_error" product="nosdcard" msgid="6299769563624776948">"USB भण्डारणलाई मेटाउन सकेन।"</string>
+    <string name="format_error" product="default" msgid="7315248696644510935">"SD कार्ड मेटाउन सकेन"</string>
+    <string name="media_bad_removal" msgid="7960864061016603281">"SD कार्ड अनमाउन्ट हुनुभन्दा पहिला निकालियो।"</string>
+    <string name="media_checking" product="nosdcard" msgid="418188720009569693">"अहिले USB भण्डारण जाँच भइरहेको छ।"</string>
+    <string name="media_checking" product="default" msgid="7334762503904827481">"SD कार्ड अहिले परीक्षण भइरहेको छ।"</string>
+    <string name="media_removed" msgid="7001526905057952097">"SD कार्ड हटाइयो।"</string>
+    <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"SD कार्ड कम्प्युटरद्वारा अहिले प्रयोगमा छ।"</string>
+    <string name="media_shared" product="default" msgid="5706130568133540435">"SD कार्ड अहिले कम्प्युटरद्वारा प्रयोगमा छ।"</string>
+    <string name="media_unknown_state" msgid="729192782197290385">"बाह्य मिडिया अज्ञात अवस्थामा।"</string>
+    <string name="share" msgid="1778686618230011964">"साझेदारी गर्नुहोस्"</string>
+    <string name="find" msgid="4808270900322985960">"पत्ता लगाउनुहोस्"</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="gpsNotifMessage" msgid="1374718023224000702">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>) द्वारा अनुरोध गरिएको"</string>
+    <string name="gpsVerifYes" msgid="2346566072867213563">"हो"</string>
+    <string name="gpsVerifNo" msgid="1146564937346454865">"होइन"</string>
+    <string name="sync_too_many_deletes" msgid="5296321850662746890">"सीमा नाघेकाहरू मेट्नुहोस्"</string>
+    <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"त्यहाँ <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> मेटाइएका आइटमहरू छन् <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>को लागि, खाता <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>। तपाईं के गर्न चाहनु हुन्छ?"</string>
+    <string name="sync_really_delete" msgid="2572600103122596243">"वस्तुहरू मेट्नुहोस्"</string>
+    <string name="sync_undo_deletes" msgid="2941317360600338602">"मेटिएकाहरू पूर्ववत बनाउनुहोस्।"</string>
+    <string name="sync_do_nothing" msgid="3743764740430821845">"अहिलेको लागि केही नगर्नुहोस्"</string>
+    <string name="choose_account_label" msgid="5655203089746423927">"एउटा खाता छान्‍नुहोस्"</string>
+    <string name="add_account_label" msgid="2935267344849993553">"एउटा खाता थप्नुहोस्"</string>
+    <string name="add_account_button_label" msgid="3611982894853435874">"खाता थप गर्नुहोस्"</string>
+    <string name="number_picker_increment_button" msgid="2412072272832284313">"बढाउनुहोस्"</string>
+    <string name="number_picker_decrement_button" msgid="476050778386779067">"घटाउनुहोस्"</string>
+    <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g>छुनुहोस् र समाउनुहोस्।"</string>
+    <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"बढाउन माथि र घटाउन तल सार्नुहोस्।"</string>
+    <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"मिनेट बढाउनुहोस्"</string>
+    <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"मिनेट घटाउनुहोस्"</string>
+    <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"घन्टा बढाउनुहोस्"</string>
+    <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"घन्टा घटाउनुहोस्"</string>
+    <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"PM सेट गर्नुहोस्"</string>
+    <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"AM सेट गर्नुहोस्"</string>
+    <string name="date_picker_increment_month_button" msgid="5369998479067934110">"महिना बढाउनुहोस्"</string>
+    <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"महिना घटाउनुहो्स्"</string>
+    <string name="date_picker_increment_day_button" msgid="7130465412308173903">"दिन बढाउनुहोस्"</string>
+    <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"दिन घटाउनुहोस्"</string>
+    <string name="date_picker_increment_year_button" msgid="6318697384310808899">"वर्ष बढाउनुहोस्"</string>
+    <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"वर्ष घटाउनुहोस्"</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_enter" msgid="2985864015076059467">"प्रविष्टि गर्नुहोस्"</string>
+    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"एउटा अनुप्रयोग छान्नुहोस्"</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_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>को लागि माथि धिसार्नुहोस्"</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"<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="description_direction_right" msgid="8034433242579600980">"स्लाइड <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>को लागि दायाँ।"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"अनलक गर्नुहोस्"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"क्यामेरा"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"मौन"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"आवाज चालू"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"खोज्नुहोस्"</string>
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"खोल्नलाइ हुत्त्याउनुहोस्।"</string>
+    <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"बोलिएको पासवर्ड कुञ्जीहरू सुन्नको लागि हेडसेट प्लग इन गर्नुहोस्।"</string>
+    <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"डट।"</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="4891916833657929263">"आन्तरिक भण्डारण"</string>
+    <string name="storage_sd_card" msgid="3282948861378286745">"SD कार्ड"</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="1955638862122232342">"डेटा प्रयोग चेतावनी"</string>
+    <string name="data_usage_warning_body" msgid="2814673551471969954">"उपयोग र सेटिङहरू हेर्न छुनुहोस्।"</string>
+    <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-3G डेटा असक्षम गरिएको"</string>
+    <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G डेटा असक्षम गरियो"</string>
+    <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"मोबाइल डेटा असक्षम पारियो।"</string>
+    <string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"वाइ-फाइ डेटा असक्षम गरियो"</string>
+    <string name="data_usage_limit_body" msgid="3317964706973601386">"सक्षम पार्न छुनुहोस्।"</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 डेटा SIMा नाघ्यो"</string>
+    <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"मोवाइल डेटा SIMा नाघ्यो"</string>
+    <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"वाइ-फाइ डेटा SIMा नाघ्यो"</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="6741521330997452990">"अवरोध हटाउन छुनुहोस्।"</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>
+    <string name="org_unit" msgid="7265981890422070383">"संगठनात्मक एकाइ:"</string>
+    <string name="issued_by" msgid="2647584988057481566">"द्वारा जारी गरिएको:"</string>
+    <string name="validity_period" msgid="8818886137545983110">"मान्यता:"</string>
+    <string name="issued_on" msgid="5895017404361397232">"जारी गरिएको:"</string>
+    <string name="expires_on" msgid="3676242949915959821">"अवधि समाप्त:"</string>
+    <string name="serial_number" msgid="758814067660862493">"क्रम संख्या:"</string>
+    <string name="fingerprints" msgid="4516019619850763049">"औँठाछापहरू:"</string>
+    <string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-२५६ औंठाछाप:"</string>
+    <string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 औंलाछाप:"</string>
+    <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"सबै हेर्नुहोस्"</string>
+    <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"गतिविधि छनौट गर्नुहोस्"</string>
+    <string name="share_action_provider_share_with" msgid="5247684435979149216">"साझेदारी गर्नुहोस्..."</string>
+    <string name="status_bar_device_locked" msgid="3092703448690669768">"उपकरण लक छ।"</string>
+    <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="3245653681008218030">"पठाउँदै..."</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="default_audio_route_name" product="tablet" msgid="4617053898167127471">"ट्याब्लेट"</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">"ब्लुटुथ अडियो"</string>
+    <string name="wireless_display_route_description" msgid="9070346425023979651">"ताररहित प्रदर्शन"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"भयो"</string>
+    <string name="media_route_button_content_description" msgid="5758553567065145276">"मिडियाको उत्पादन"</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>
+    <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_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="wifi_display_notification_title" msgid="2223050649240326557">"ताररहित प्रदर्शन जोडिएको छ"</string>
+    <string name="wifi_display_notification_message" msgid="4498802012464170685">"अर्को उपकरणमा यो स्क्रिनले देखाइरहेको छ"</string>
+    <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"विच्छेदन गर्नुहोस्"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"आपतकालीन कल"</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">"गलत PIN"</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">"SIM PIN प्रविष्टि गर्नुहोस्"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN प्रविष्टि गर्नुहोस्"</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">"इच्छित PIN कोड प्रविष्टि गर्नुहोस्"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"मनपर्दो PIN कोड निश्चित गर्नुहोस्"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM कार्ड अनलक गर्दै…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"गलत PIN कोड।"</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"४ देखि ८ वाट नम्बर भएको एउटा PIN टाइप गर्नुहोस्।"</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK कोड ८ वटा नम्बर वा सो भन्दा बढी हुनुपर्छ।"</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"PUK कोड पुन:प्रदान गर्नुहोस्। धेरै पुन:प्रयासहरूले SIMलाई स्थायी रूपमा निष्क्रिय गरिदिने छ।"</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN कोडहरू मेल खाएन"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"निकै धेरै ढाँचा कोसिसहरू"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"अनलक गर्नको लागि, तपाईँको Google खाताको साथ साइन इन गर्नुहोस्।"</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"खाता जाँच हुँदै…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"तपाईँले गलत तरिकाले तपाईँको PIN <xliff:g id="NUMBER_0">%d</xliff:g> पटक टाइप गर्नु भएको छ। \n\n<xliff:g id="NUMBER_1">%d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"तपाईँले तपाईँक पासवर्ड <xliff:g id="NUMBER_0">%d</xliff:g> पटक गलत टाइप गर्नुभएको छ। \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"तपाईँले तपाईँको अनलक ढाँचा गलत तरिकाले <xliff:g id="NUMBER_0">%d</xliff:g> पटक खिच्नु भएको छ। \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकेन्डमा फेरि कोसिस गर्नुहोस्।"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"तपाईँले ट्याब्लेटलाई अनलक गर्न गलत तरिकाले <xliff:g id="NUMBER_0">%d</xliff:g> पटक कोसिस गर्नु भएको छ। <xliff:g id="NUMBER_1">%d</xliff:g> पछि थप असफल प्रयासहरू, ट्याब्लेट पूर्वनिर्धारित कार्यशालामा पुनःसेट गरिने छ र सबै प्रयोग डेटा हराउने छ।"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"तपाईँले गलतसँग फोनलाई अनलक गर्न <xliff:g id="NUMBER_0">%d</xliff:g> पटक कोसिस गर्नु भयो। <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> पटक कोर्नुभयो। <xliff:g id="NUMBER_1">%d</xliff:g> विफल प्रयत्नहरू पछि, तपाईंलाई आफ्नो ट्याब्लेट इमेल खाता प्रयोग गरेर अनलक गर्न सोधिने छ।\n\n फेरि प्रयास गर्नुहोस् <xliff:g id="NUMBER_2">%d</xliff:g> सेकेन्डहरूमा।"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"तपाईँले आफ्नो अनलक ढाँचा गलत रूपमा <xliff:g id="NUMBER_0">%d</xliff:g> पटक तान्नु भएको छ। <xliff:g id="NUMBER_1">%d</xliff:g> धेरै असफल प्रयासहरूपछि, तपाईँलाई एउटा इमेल खाताको प्रयोग गरेर तपाईँको फोन अनलक गर्न सोधिने छ।\n\n फेरि <xliff:g id="NUMBER_2">%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="7324161939475478066">"आवाज सल्लाह दिएको तहभन्दा माथि  बढाउने हो?\nठूलो आवाजमा सुन्दा लामो समयको लागि तपाईँको सुन्ने शक्तीलाई खत्तम पार्न सक्छ।"</string>
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"उपलब्धता सक्षम पार्न दुईवटा औंलाहरूले थिचिरहनुहोस्।"</string>
+    <string name="accessibility_enabled" msgid="1381972048564547685">"पहुँच सक्षम गरिएको।"</string>
+    <string name="enable_accessibility_canceled" msgid="3833923257966635673">"पहुँचयोग्यता रद्द गरियो।"</string>
+    <string name="user_switched" msgid="3768006783166984410">"अहिलेको प्रयोगकर्ता <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="app_no_restricted_accounts" msgid="5739463249673727736">"प्रतिबन्धित प्रोफाइलहरूको लागि यस अनुप्रयोगले खाताहरू समर्थन गर्दैन"</string>
+    <string name="app_not_found" msgid="3429141853498927379">"यस कार्य सम्हालने कुनै अनुप्रयोग भेटिएन"</string>
+    <string name="revoke" msgid="5404479185228271586">"रद्द गर्नुहोस्"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"पत्र"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"सरकारी पत्र"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"कानूनी"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"रद्द गरियो"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"सामाग्री लेखनमा त्रुटि"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN प्रविष्टि गर्नुहोस्"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"वर्तमान PIN"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"नयाँ PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"नयाँ PIN निश्चित गर्नुहोस्"</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_too_short" msgid="8173982756265777792">"PIN अति छोटो भयो। कम्तीमा ४ अङ्क हुन आवश्यक छ।"</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="4835639969503729874">"गलत PIN । १ सेकेन्डमा पुनः प्रयास गर्नुहोस्।"</item>
+    <item quantity="other" msgid="8030607343223287654">"गलत PIN । <xliff:g id="COUNT">%d</xliff:g> सेकेन्डमा पुनः प्रयास गर्नुहोस्।"</item>
+  </plurals>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"पट्टि देखिने बनाउन स्क्रिनको छेउमा स्वाइप गर्नुहोस्"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"प्रणाली पट्टि देखिने बनाउन स्क्रिनको छेउबाट स्वाइप गर्नुहोस्"</string>
+</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index bbdfed3..bd45ddc 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -131,6 +131,11 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Te veel verwijderen voor <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Tabletgeheugen is vol. Verwijder enkele bestanden om ruimte vrij te maken."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Telefoongeheugen is vol. Verwijder enkele bestanden om ruimte vrij te maken."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Netwerk kan worden gecontroleerd"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Ik"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Tabletopties"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Telefoonopties"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Hiermee kan de app taken naar de voor- en achtergrond verplaatsen. De app kan dit doen zonder om uw bevestiging te vragen."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"actieve apps stoppen"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Hiermee kan de app taken verwijderen en apps sluiten. Schadelijke apps kunnen het gedrag van andere apps verstoren."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"activiteitstacks beheren"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Hiermee kan de app de activiteitstacks waarin andere apps worden uitgevoerd, toevoegen, verwijderen en aanpassen. Schadelijke apps kunnen de werking van andere apps verstoren."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"elke activiteit starten"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Toestaan dat de app elke activiteit start, ongeacht rechtenbeveiliging of geëxporteerde status."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"schermcompatibiliteit instellen"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Hiermee kan de houder zich verbinden met de hoofdinterface van een invoermethode. Nooit vereist voor normale apps."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"koppelen aan een toegankelijkheidsservice"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Hiermee wordt de houder toegestaan verbinding te maken met de hoofdinterface van een toegankelijkheidsservice. Nooit vereist voor normale apps."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"koppelen aan een afdrukservice"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Hiermee kan de houder verbinding maken met de hoofdinterface van een afdrukservice. Nooit vereist voor normale apps."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"koppelen aan een afdrukspoolerservice"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Hiermee kan de houder verbinding maken met de hoofdinterface van een afdrukspoolerservice. Nooit vereist voor normale apps."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"koppelen aan NFC-service"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Hiermee kan de houder apps koppelen die NFC-kaarten emuleren. Nooit vereist voor normale apps."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"koppelen aan een sms-service"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Hiermee kan de gebruiker koppelen met de hoofdinterface van een tekstservice (zoals SpellCheckerService). Dit is niet nodig voor normale apps."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"koppelen aan een VPN-service"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Hiermee wordt de houder toegestaan verbinding te maken met de hoofdinterface van een widgetservice. Nooit vereist voor normale apps."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interactie met apparaatbeheer"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Hiermee kan de houder intenties verzenden naar een apparaatbeheerder. Nooit vereist voor normale apps."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"een apparaatbeheerder toevoegen of verwijderen"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Hiermee kan de rechtenhouder actieve apparaatbeheerders toevoegen of verwijderen. Nooit vereist voor normale apps."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"schermstand wijzigen"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Hiermee kan de app de rotatie van het scherm op elk moment wijzigen. Nooit vereist voor normale apps."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"aanwijzersnelheid wijzigen"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Hiermee kan de app de verschillende logbestanden van het systeem lezen. De app kan op deze manier algemene informatie achterhalen over uw telefoongebruik, mogelijk inclusief persoonlijke of privé-informatie."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"elke mediadecoder gebruiken voor afspelen"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Hiermee kan de app alle geïnstalleerde mediadecoders gebruiken om te decoderen voor het afspelen."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"vertrouwde inloggegevens beheren"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Hiermee kan de app CA-certificaten installeren en verwijderen als vertrouwde inloggegevens."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"lezen/schrijven naar bronnen van diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Hiermee kan de app lezen en schrijven naar elke bron die hoort bij de diagnostische groep, zoals bestanden in /dev. Hierdoor kan de systeemstabiliteit en -veiligheid worden beïnvloed. Dit mag ALLEEN worden gebruikt voor hardwarespecifieke diagnostiek door de fabrikant of provider."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"componenten van apps in- of uitschakelen"</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"De app toestaan wifi-displays te configureren en hiermee verbinding te maken."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"wifi-displays beheren"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"De app toestaan minder belangrijke functies van wifi-displays te beheren."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"audio-uitvoer vastleggen"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Hiermee kan de app audio-uitvoer vastleggen en verwerken."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"video-uitvoer vastleggen"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Hiermee kan de app video-uitvoer vastleggen en verwerken."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"beveiligde video-uitvoer vastleggen"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Hiermee kan de app beveiligde video-uitvoer vastleggen en verwerken."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"uw audio-instellingen wijzigen"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Hiermee kan de app algemene audio-instellingen wijzigen zoals het volume en welke luidspreker wordt gebruikt voor de uitvoer."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"audio opnemen"</string>
@@ -525,6 +552,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"voorkomen dat telefoon overschakelt naar slaapmodus"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Hiermee kan de app voorkomen dat de tablet overschakelt naar de slaapmodus."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Hiermee kan de app voorkomen dat de telefoon overschakelt naar de slaapmodus."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"tablet in- of uitschakelen"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"telefoon in- of uitschakelen"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Hiermee kan de app de tablet in- of uitschakelen."</string>
@@ -570,7 +603,7 @@
     <string name="permlab_accessWifiState" msgid="5202012949247040011">"wifi-verbindingen weergeven"</string>
     <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Hiermee kan de app informatie over wifi-netwerken bekijken, zoals of wifi is ingeschakeld en de naam van apparaten waarmee via wifi verbinding is gemaakt."</string>
     <string name="permlab_changeWifiState" msgid="6550641188749128035">"wifi-verbinding maken en verbreken"</string>
-    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Hiermee kan de app zich koppelen aan en loskoppelen van wifi-toegangspunten en wijzigingen aanbrengen in de apparaatconfiguratie voor wifi-netwerken."</string>
+    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Hiermee kan de app zich koppelen aan en ontkoppelen van wifi-toegangspunten en wijzigingen aanbrengen in de apparaatconfiguratie voor wifi-netwerken."</string>
     <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"Wifi Multicast-ontvangst toestaan"</string>
     <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Hiermee kan de app pakketten ontvangen die via multicastadressen naar alle apparaten in een wifi-netwerk worden verzonden, niet alleen naar uw tablet. Het stroomgebruik ligt hierbij hoger dan in de niet-multicastmodus."</string>
     <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Hiermee kan de app pakketten ontvangen die via multicastadressen naar alle apparaten in een wifi-netwerk worden verzonden, niet alleen naar uw telefoon. Het stroomgebruik ligt hierbij hoger dan in de niet-multicastmodus."</string>
@@ -613,6 +646,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Hiermee kan de app schrijven naar de SD-kaart."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"inh. mediaopsl. wijz./verw."</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Hiermee kan de app de inhoud van de interne mediaopslag aanpassen."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"documentopslag beheren"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Hiermee kan de app documentopslag beheren."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"toegang tot externe opslag van alle gebruikers"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Hiermee krijgt de app toegang tot externe opslag van alle gebruikers."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"het cachebestandssysteem openen"</string>
@@ -625,10 +660,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Hiermee kan de app het netwerkbeleid beheren en app-specifieke regels definiëren."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"verrekening van netwerkgebruik aanpassen"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Hiermee kan een app aanpassen hoe het netwerkgebruik wordt toegekend aan apps. Dit wordt niet gebruikt door normale apps."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"socketmarkeringen aanpassen"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Hiermee kan de app socketmarkeringen voor routeren aanpassen"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"toegang tot meldingen"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Hiermee kan de app meldingen ophalen, onderzoeken en wissen, waaronder meldingen die zijn verzonden door andere apps."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"koppelen aan een listener-service voor meldingen"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Hiermee kan de houder koppelen aan de hoofdinterface van een listener-service voor meldingen. Nooit vereist voor normale apps."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"de door de provider geleverde configuratie-app aanroepen"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Hiermee kan de houder de door de provider geleverde configuratie-app aanroepen. Nooit vereist voor normale apps."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"controleren op waarnemingen met betrekking tot netwerkomstandigheden"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Hiermee kan een app controleren op waarnemingen met betrekking tot netwerkomstandigheden. Nooit vereist voor normale apps."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Wachtwoordregels instellen"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"De lengte en tekens beheren die zijn toegestaan in wachtwoorden voor schermontgrendeling."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Pogingen voor schermontgrendeling bijhouden"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +836,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Plaats een simkaart."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"De simkaart ontbreekt of kan niet worden gelezen. Plaats een simkaart."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Onbruikbare simkaart."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Uw simkaart is permanent uitgeschakeld."\n" Neem contact op met uw mobiele serviceprovider voor een nieuwe simkaart."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Uw simkaart is permanent uitgeschakeld.\n Neem contact op met uw mobiele serviceprovider voor een nieuwe simkaart."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Knop voor vorig nummer"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Knop voor volgend nummer"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Knop voor onderbreken"</string>
@@ -808,11 +848,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Raadpleeg de gebruikershandleiding of neem contact op met de klantenservice."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM-kaart is vergrendeld."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM-kaart ontgrendelen..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. "\n\n"Probeer het over <xliff:g id="NUMBER_1">%d</xliff:g> seconden opnieuw."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"U heeft uw wachtwoord <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. "\n\n"Probeer het over <xliff:g id="NUMBER_1">%d</xliff:g> seconden opnieuw."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"U heeft uw pincode <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. "\n\n"Probeer het over <xliff:g id="NUMBER_1">%d</xliff:g> seconden opnieuw."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd uw tablet te ontgrendelen met uw aanmeldingsgegevens voor Google."\n\n" Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd uw telefoon te ontgrendelen met uw aanmeldingsgegevens voor Google."\n\n" Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. \n\nProbeer het over <xliff:g id="NUMBER_1">%d</xliff:g> seconden opnieuw."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"U heeft uw wachtwoord <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. \n\nProbeer het over <xliff:g id="NUMBER_1">%d</xliff:g> seconden opnieuw."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"U heeft uw pincode <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. \n\nProbeer het over <xliff:g id="NUMBER_1">%d</xliff:g> seconden opnieuw."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd uw tablet te ontgrendelen met uw aanmeldingsgegevens voor Google.\n\n Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd uw telefoon te ontgrendelen met uw aanmeldingsgegevens voor Google.\n\n Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"U heeft <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de tablet op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de tablet en gaan alle gebruikersgegevens verloren."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"U heeft nu <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de telefoon op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de telefoon en gaan alle gebruikersgegevens verloren."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"U heeft <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de tablet op een onjuiste manier te ontgrendelen. De fabrieksinstellingen worden nu hersteld op de tablet."</string>
@@ -821,12 +861,12 @@
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Patroon vergeten?"</string>
     <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Account ontgrendelen"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"Te veel patroonpogingen"</string>
-    <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"Als u wilt ontgrendelen, moet u zich aanmelden bij uw Google-account."</string>
+    <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"Log in op uw Google-account om te ontgrendelen."</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Gebruikersnaam (e-mail)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Wachtwoord"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Inloggen"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Gebruikersnaam of wachtwoord ongeldig."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Bent u uw gebruikersnaam of wachtwoord vergeten?"\n"Ga naar "<b>"https://www.google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Bent u uw gebruikersnaam of wachtwoord vergeten?\nGa naar "<b>"https://www.google.com/accounts/recovery"</b>"."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Controleren…"</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Ontgrendelen"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Geluid aan"</string>
@@ -874,7 +914,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Navigatie bevestigen"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Deze pagina verlaten"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Op deze pagina blijven"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Weet u zeker dat u deze pagina wilt verlaten?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nWeet u zeker dat u deze pagina wilt verlaten?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Bevestigen"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Tip: dubbeltik om in en uit te zoomen."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Autom. aanvullen"</string>
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"<xliff:g id="APPLICATION">%1$s</xliff:g> is gestopt."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Het proces <xliff:g id="PROCESS">%1$s</xliff:g> is gestopt."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> reageert niet."\n\n"Wilt u deze app sluiten?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Activiteit <xliff:g id="ACTIVITY">%1$s</xliff:g> reageert niet."\n\n"Wilt u deze activiteit sluiten?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> reageert niet.\n\nWilt u deze app sluiten?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Activiteit <xliff:g id="ACTIVITY">%1$s</xliff:g> reageert niet.\n\nWilt u deze activiteit sluiten?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> reageert niet. Wilt u deze app sluiten?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> reageert niet."\n\n"Wilt u het sluiten?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> reageert niet.\n\nWilt u het sluiten?"</string>
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"Rapport"</string>
     <string name="wait" msgid="7147118217226317732">"Wachten"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"De pagina reageert niet meer."\n\n"Wilt u de pagina sluiten?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"De pagina reageert niet meer.\n\nWilt u de pagina sluiten?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"App verplaatst"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> is nu actief."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> was het eerst gestart."</string>
@@ -1136,7 +1176,7 @@
     <item quantity="one" msgid="1634101450343277345">"Open wifi-netwerk beschikbaar"</item>
     <item quantity="other" msgid="7915895323644292768">"Open wifi-netwerken beschikbaar"</item>
   </plurals>
-    <string name="wifi_available_sign_in" msgid="4029489716605255386">"Aanmelden bij wifi-netwerk"</string>
+    <string name="wifi_available_sign_in" msgid="4029489716605255386">"Inloggen op wifi-netwerk"</string>
     <string name="network_available_sign_in" msgid="8495155593358054676">"Inloggen bij netwerk"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
@@ -1256,6 +1296,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Hiermee kan de app de standaard containerservice aanroepen om inhoud te kopiëren. Niet voor gebruik door normale apps."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Media-uitvoer aansturen"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Hiermee kan een app media-uitvoer naar andere externe apparaten doorsturen."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Toegang tot opslag met toetsbeveiliging"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Hiermee krijgt een app toegang tot opslag met toetsbeveiliging."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Weergeven en verbergen van toetsbeveiliging beheren"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Staat toe dat een app de toetsbeveiliging beheert."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Raak twee keer aan voor zoomregeling"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Kan widget niet toevoegen."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Ga"</string>
@@ -1265,15 +1309,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Gereed"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Vorige"</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Uitvoeren"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Nummer bellen"\n"met <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Contact maken"\n"met <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Nummer bellen\nmet <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Contact maken\nmet <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"De volgende apps verzoeken om toegang tot uw account, nu en in de toekomst."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Wilt u dit verzoek toestaan?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Verzoek om toegang"</string>
     <string name="allow" msgid="7225948811296386551">"Toestaan"</string>
     <string name="deny" msgid="2081879885755434506">"Weigeren"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Toestemming gevraagd"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Toestemming gevraagd"\n"voor account <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Toestemming gevraagd\nvoor account <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Invoermethode"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Synchroniseren"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Toegankelijkheid"</string>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Alles weergeven"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Een activiteit kiezen"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Delen met"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Apparaat vergrendeld."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Verzenden..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Browser starten?"</string>
@@ -1441,10 +1484,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Verbinden..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Beschikbaar"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"Niet beschikbaar"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"In gebruik"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Ingebouwd scherm"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"HDMI-scherm"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlay <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", beveiligd"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Draadloze display is aangesloten"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Dit scherm wordt op een ander apparaat weergegeven"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Verbinding verbreken"</string>
@@ -1453,7 +1498,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Onjuist patroon"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Onjuist wachtwoord"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"Onjuiste pincode"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Probeer het over <xliff:g id="NUMBER">%d</xliff:g> seconden opnieuw."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Probeer het over <xliff:g id="NUMBER">%1$d</xliff:g> seconden opnieuw."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Teken uw patroon"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Geef de pincode van de simkaart op"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Pincode opgeven"</string>
@@ -1473,27 +1518,85 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Wachtwoord"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Inloggen"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Ongeldige gebruikersnaam of wachtwoord."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Bent u uw gebruikersnaam of wachtwoord vergeten?"\n"Ga naar "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Bent u uw gebruikersnaam of wachtwoord vergeten?\nGa naar "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Account controleren…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"U heeft uw pincode <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. "\n\n"Probeer het over <xliff:g id="NUMBER_1">%d</xliff:g> seconden opnieuw."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"U heeft uw wachtwoord <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. "\n\n"Probeer het over <xliff:g id="NUMBER_1">%d</xliff:g> seconden opnieuw."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. "\n\n"Probeer het over <xliff:g id="NUMBER_1">%d</xliff:g> seconden opnieuw."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"U heeft uw pincode <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. \n\nProbeer het over <xliff:g id="NUMBER_1">%d</xliff:g> seconden opnieuw."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"U heeft uw wachtwoord <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. \n\nProbeer het over <xliff:g id="NUMBER_1">%d</xliff:g> seconden opnieuw."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. \n\nProbeer het over <xliff:g id="NUMBER_1">%d</xliff:g> seconden opnieuw."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"U heeft <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de tablet op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de tablet en gaan alle gebruikersgegevens verloren."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"U heeft nu <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de telefoon op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de telefoon en gaan alle gebruikersgegevens verloren."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"U heeft <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de tablet op een onjuiste manier te ontgrendelen. De fabrieksinstellingen worden nu hersteld op de tablet."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"U heeft <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de telefoon op een onjuiste manier te ontgrendelen. De fabrieksinstellingen worden nu hersteld op de telefoon."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd uw tablet te ontgrendelen via een e-mailaccount."\n\n" Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd uw telefoon te ontgrendelen via een e-mailaccount."\n\n" Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd uw tablet te ontgrendelen via een e-mailaccount.\n\n Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd uw telefoon te ontgrendelen via een e-mailaccount.\n\n Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Verwijderen"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Wilt u het volume verhogen tot boven het aanbevolen geluidsniveau?"\n"Te lang luisteren op een te hoog volume kan leiden tot gehoorbeschadiging."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Wilt u het volume verhogen tot boven het aanbevolen geluidsniveau?\nTe lang luisteren op een te hoog volume kan leiden tot gehoorbeschadiging."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Blijf het scherm met twee vingers aanraken om toegankelijkheid in te schakelen."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Toegankelijkheid ingeschakeld."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Toegankelijkheid geannuleerd."</string>
     <string name="user_switched" msgid="3768006783166984410">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Eigenaar"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Fout"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Deze app biedt geen ondersteuning voor accounts voor beperkte profielen"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Deze app biedt geen ondersteuning voor accounts voor beperkte profielen"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Er is geen app gevonden om deze actie uit te voeren"</string>
     <string name="revoke" msgid="5404479185228271586">"Intrekken"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Geannuleerd"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Fout bij schrijven van inhoud"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"onbekend"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Pincode voor beheerder opgeven"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Geef de pincode op"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Onjuist"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Huidige pincode"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Nieuwe pincode"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Nieuwe pincode bevestigen"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Maak een pincode voor het aanpassen van beperkingen"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"De pincodes komen niet overeen. Probeer het opnieuw."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"Pincode is te kort. Moet ten minste vier cijfers lang zijn."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Probeer het over één seconde opnieuw"</item>
+    <item quantity="other" msgid="4730868920742952817">"Probeer het over <xliff:g id="COUNT">%d</xliff:g> seconden opnieuw"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Probeer het later opnieuw"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Veeg vanaf de rand voor de balk"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Veeg vanaf de rand van het scherm om de systeembalk weer te geven"</string>
 </resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index e4e82f9..8c7f072 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -131,6 +131,11 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Zbyt wiele usuwanych <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Pamięć tabletu jest pełna. Usuń niektóre pliki, aby zwolnić miejsce."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Pamięć telefonu jest pełna. Usuń niektóre pliki, aby zwolnić miejsce."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Sieć może być monitorowana"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Ja"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opcje tabletu"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Opcje telefonu"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Pozwala aplikacji na przenoszenie zadań między tłem a pierwszym planem. Aplikacja może to robić bez Twojego udziału."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"zatrzymywanie uruchomionych aplikacji"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Umożliwia aplikacji usuwanie zadań i kończenie powiązanych z nimi aplikacji. Złośliwe aplikacje mogą zakłócić działanie innych aplikacji."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"zarządzanie stosami aktywności"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Zezwala aplikacji na dodawanie, usuwanie i zmianę stosów aktywności, w których działają inne aplikacje. Złośliwe aplikacje mogą zakłócić działanie innych aplikacji."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"rozpoczynanie dowolnej czynności"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Zezwala aplikacji na rozpoczynanie dowolnej czynności niezależnie od ochrony uprawnień lub stanu eksportu."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"ustaw zgodność ekranu"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Pozwala na powiązanie wybranego sposobu wprowadzania tekstu z interfejsem najwyższego poziomu. To uprawnienie nie powinno być nigdy wymagane przez zwykłe aplikacje."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"tworzenie powiązania z usługą ułatwień dostępu"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Zezwala na tworzenie powiązania z interfejsem najwyższego poziomu usługi ułatwień dostępu. Nieprzeznaczone dla zwykłych aplikacji."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"tworzenie powiązania z usługą drukowania"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Zezwala na tworzenie powiązania z interfejsem najwyższego poziomu usługi drukowania. Nieprzeznaczone dla zwykłych aplikacji."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"tworzenie powiązania z usługą buforowania wydruku"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Zezwala na tworzenie powiązania z interfejsem najwyższego poziomu usługi buforowania wydruku. Nieprzeznaczone dla zwykłych aplikacji."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"powiązanie z usługą NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Umożliwia właścicielowi powiązanie z aplikacjami emulującymi karty NFC. Nie powinno być nigdy potrzebne w normalnych aplikacjach."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"tworzenie powiązania z usługą tekstową"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Pozwala na tworzenie powiązania z interfejsem najwyższego poziomu usługi tekstowej (np. SpellCheckerService). Nie powinno być nigdy potrzebne w przypadku zwykłych aplikacji."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"tworzenie powiązania z usługą VPN"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Zezwala na tworzenie powiązania z interfejsem najwyższego poziomu usługi widżetów. Nie powinno być nigdy potrzebne w przypadku zwykłych aplikacji."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interakcja z administratorem urządzenia"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Zezwala na wysyłanie intencji do administratora urządzenia. Nie powinno być nigdy potrzebne w przypadku zwykłych aplikacji."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"dodaj lub usuń administratora urządzenia"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Umożliwia właścicielowi dodawanie i usuwanie aktywnych administratorów urządzenia. Ta opcja nie jest wykorzystywana w przypadku standardowych aplikacji."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"zmienianie orientacji ekranu"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Pozwala aplikacji na zmianę obrotu ekranu w dowolnym momencie. To uprawnienie nie powinno być potrzebne zwykłym aplikacjom."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"zmiana szybkości wskaźnika"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Pozwala aplikacji na odczyt różnych plików dzienników systemowych. Dzięki temu może ona poznać ogólne informacje na temat korzystania z telefonu, co potencjalnie może obejmować również informacje prywatne lub osobiste."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"użycie dowolnego dekodera multimediów w celu odtwarzania"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Pozwala aplikacji na użycie dowolnego zainstalowanego dekodera multimediów do odtwarzania."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"zarządzanie zaufanymi danymi uwierzytelniającymi"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Zezwala aplikacji na instalowanie i odinstalowywanie certyfikatów CA jako zaufanych danych uwierzytelniających."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"czytanie/zapisywanie w zasobach należących do diagnostyki"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Pozwala aplikacji na czytanie i zapisywanie wszystkich zasobów należących do grupy diagnostyki, na przykład plików w katalogu /dev. Może to potencjalnie wpłynąć na stabilność i bezpieczeństwo systemu. Powinno być wykorzystywane WYŁĄCZNIE do diagnozowania sprzętu przez producenta lub operatora."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"włączanie lub wyłączanie składników aplikacji"</string>
@@ -430,7 +447,7 @@
     <string name="permlab_writeCallLog" msgid="8552045664743499354">"zapisywanie rejestru połączeń"</string>
     <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Zezwala aplikacji na modyfikowanie rejestru połączeń tabletu, w tym danych o połączeniach przychodzących i wychodzących. Złośliwe aplikacje mogą wykorzystać tę możliwość, by wyczyścić lub zmodyfikować rejestr połączeń."</string>
     <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Zezwala aplikacji na modyfikowanie rejestru połączeń telefonu, w tym danych o połączeniach przychodzących i wychodzących. Złośliwe aplikacje mogą wykorzystać tę możliwość, by wyczyścić lub zmodyfikować rejestr połączeń."</string>
-    <string name="permlab_readProfile" msgid="4701889852612716678">"odczyt własnej karty kontaktu"</string>
+    <string name="permlab_readProfile" msgid="4701889852612716678">"odczytywanie własnej karty kontaktu"</string>
     <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Pozwala aplikacji na odczyt osobistych informacji przechowywanych w Twoim profilu na urządzeniu (np. imienia i nazwiska lub adresu). Oznacza to, że aplikacja może Cię zidentyfikować i wysłać informacje z Twojego profilu do innych osób."</string>
     <string name="permlab_writeProfile" msgid="907793628777397643">"zmiana własnej karty kontaktu"</string>
     <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Pozwala aplikacji na zmianę lub dodanie osobistych informacji przechowywanych w Twoim profilu na urządzeniu (np. imienia i nazwiska lub adresu). Oznacza to, że aplikacja może Cię zidentyfikować i wysłać informacje z Twojego profilu do innych osób."</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Zezwala aplikacji na konfigurację wyświetlaczy Wi-Fi i łączenie z nimi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"zarządzanie wyświetlaczami Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Zezwala aplikacji na zarządzanie niskopoziomowymi funkcjami wyświetlaczy Wi-Fi."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"przechwyć wyjście audio"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Zezwala aplikacji na przechwytywanie i przekierowywanie wyjścia audio."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"przechwyć wyjście wideo"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Zezwala aplikacji na przechwytywanie i przekierowywanie wyjścia wideo."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"przechwyć bezpieczne wyjście wideo"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Zezwala aplikacji na przechwytywanie i przekierowywanie bezpiecznego wyjścia wideo."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"zmienianie ustawień audio"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Pozwala aplikacji na modyfikowanie globalnych ustawień dźwięku, takich jak głośność oraz urządzenie wyjściowe."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"nagrywanie dźwięku"</string>
@@ -525,6 +552,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"zapobieganie przejściu telefonu w stan uśpienia"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Pozwala aplikacji na zapobieganie przechodzeniu tabletu do trybu uśpienia."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Pozwala aplikacji na zapobieganie przechodzeniu telefonu w tryb uśpienia."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"włączenie lub wyłączenie tabletu"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"włączanie lub wyłączanie telefonu"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Pozwala aplikacji na włączanie i wyłączanie tabletu."</string>
@@ -579,7 +612,7 @@
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Pozwala aplikacji na konfigurowanie lokalnego telefonu z funkcją Bluetooth oraz na wykrywanie urządzeń zdalnych i parowanie z nimi."</string>
     <string name="permlab_accessWimaxState" msgid="4195907010610205703">"łączenie się i rozłączanie z siecią WiMAX"</string>
     <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"Pozawala aplikacji określić, czy obsługa WiMAX jest włączona, oraz uzyskać informacje o wszystkich podłączonych sieciach WiMAX."</string>
-    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Zmień stan WiMAX"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"zmienianie stanu WiMAX"</string>
     <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Pozwala aplikacji na nawiązywanie i kończenie połączeń z sieciami WiMAX w tablecie."</string>
     <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"Pozwala aplikacji na nawiązywanie i kończenie połączeń z sieciami WiMAX w telefonie."</string>
     <string name="permlab_bluetooth" msgid="6127769336339276828">"parowanie z urządzeniami Bluetooth"</string>
@@ -613,6 +646,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Pozwala aplikacji na zapis na karcie SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modyfikowanie/usuwanie zawartości pamięci wew."</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Pozwala aplikacji na modyfikowanie zawartości pamięci wewnętrznej."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"zarządzaj przechowywaniem dokumentów"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Pozwala aplikacji zarządzać przechowywaniem dokumentów."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"dostęp do zewnętrznej pamięci wszystkich"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Pozwala aplikacji na dostęp do zewnętrznej pamięci masowej dla wszystkich użytkowników."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"dostęp do systemu plików pamięci podręcznej"</string>
@@ -625,10 +660,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Pozwala aplikacji na zarządzanie zasadami dotyczącymi sieci i definiowanie reguł aplikacji."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"modyfikowanie sposobu naliczania użycia sieci"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Pozwala aplikacji na zmienianie sposobu rozliczania wykorzystania sieci przez aplikacje. Nieprzeznaczone dla zwykłych aplikacji."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"zmiana oznaczeń gniazd"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Zezwala aplikacji na zmianę oznaczeń gniazd na potrzeby trasowania"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"dostęp do powiadomień"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Umożliwia aplikacji pobieranie, sprawdzanie i usuwanie powiadomień, także tych, które pochodzą z innych aplikacji."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"utwórz połączenie z usługą odbiornika powiadomień"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Zezwala na tworzenie powiązania z interfejsem najwyższego poziomu usługi odbiornika powiadomień. Nie powinno być nigdy potrzebne dla zwykłych aplikacji."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"wywoływanie aplikacji konfiguracyjnej udostępnionej przez operatora"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Zezwala na wywoływanie aplikacji konfiguracyjnej udostępnionej przez operatora. Nieprzeznaczone dla zwykłych aplikacji."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"śledź stan sieci"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Pozwala aplikacji śledzić stan sieci. Nieprzeznaczone dla zwykłych aplikacji."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Określ reguły hasła"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrolowanie długości haseł odblokowania ekranu i dozwolonych w nich znaków"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitoruj próby odblokowania ekranu"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +836,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Włóż kartę SIM."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Brak karty SIM lub nie można jej odczytać. Włóż kartę SIM."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Karta SIM bezużyteczna."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Karta SIM jest trwale wyłączona."\n" Skontaktuj się z dostawcą usług bezprzewodowych, aby uzyskać inną kartę SIM."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Karta SIM jest trwale wyłączona.\n Skontaktuj się z dostawcą usług bezprzewodowych, aby uzyskać inną kartę SIM."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Przycisk poprzedniego utworu"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Przycisk następnego utworu"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Przycisk wstrzymania"</string>
@@ -808,11 +848,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Zapoznaj się z instrukcją obsługi lub skontaktuj się z działem obsługi klienta."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Karta SIM jest zablokowana."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Odblokowywanie karty SIM..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Wzór odblokowania został nieprawidłowo narysowany <xliff:g id="NUMBER_0">%d</xliff:g> razy. "\n\n"Spróbuj ponownie za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> zostało wpisane nieprawidłowe hasło. "\n\n"Spróbuj ponownie za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> został wpisany nieprawidłowy PIN. "\n\n"Spróbuj ponownie za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Wzór odblokowania został <xliff:g id="NUMBER_0">%d</xliff:g> razy narysowany nieprawidłowo. Po <xliff:g id="NUMBER_1">%d</xliff:g> kolejnych próbach zakończonych niepowodzeniem konieczne będzie odblokowanie tabletu przy użyciu danych logowania na konto Google."\n\n" Spróbuj ponownie za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Wzór odblokowania został <xliff:g id="NUMBER_0">%d</xliff:g> razy narysowany nieprawidłowo. Po <xliff:g id="NUMBER_1">%d</xliff:g> kolejnych próbach zakończonych niepowodzeniem konieczne będzie odblokowanie telefonu przy użyciu danych logowania na konto Google."\n\n" Spróbuj ponownie za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Wzór odblokowania został nieprawidłowo narysowany <xliff:g id="NUMBER_0">%d</xliff:g> razy. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> zostało wpisane nieprawidłowe hasło. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> został wpisany nieprawidłowy PIN. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Wzór odblokowania został <xliff:g id="NUMBER_0">%d</xliff:g> razy narysowany nieprawidłowo. Po <xliff:g id="NUMBER_1">%d</xliff:g> kolejnych próbach zakończonych niepowodzeniem konieczne będzie odblokowanie tabletu przy użyciu danych logowania na konto Google.\n\n Spróbuj ponownie za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Wzór odblokowania został <xliff:g id="NUMBER_0">%d</xliff:g> razy narysowany nieprawidłowo. Po <xliff:g id="NUMBER_1">%d</xliff:g> kolejnych próbach zakończonych niepowodzeniem konieczne będzie odblokowanie telefonu przy użyciu danych logowania na konto Google.\n\n Spróbuj ponownie za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Próbowano <xliff:g id="NUMBER_0">%d</xliff:g> razy nieprawidłowo odblokować tablet. Po kolejnych <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach tablet zostanie zresetowany do ustawień fabrycznych, a wszystkie dane użytkownika zostaną utracone."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Próbowano <xliff:g id="NUMBER_0">%d</xliff:g> razy nieprawidłowo odblokować telefon. Po kolejnych <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach telefon zostanie zresetowany do ustawień fabrycznych, a wszystkie dane użytkownika zostaną utracone."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Próbowano <xliff:g id="NUMBER">%d</xliff:g> razy nieprawidłowo odblokować tablet. Tablet zostanie teraz zresetowany do ustawień fabrycznych."</string>
@@ -826,7 +866,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Hasło"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Zaloguj się"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Błędna nazwa użytkownika lub hasło."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Nie pamiętasz nazwy użytkownika lub hasła?"\n"Odwiedź stronę "<b>"google.com/accounts/recovery"</b></string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Nie pamiętasz nazwy użytkownika lub hasła?\nOdwiedź stronę "<b>"google.com/accounts/recovery"</b></string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Sprawdzanie…"</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Odblokuj"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Włącz dźwięk"</string>
@@ -874,7 +914,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Potwierdź przejście"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Opuść tę stronę"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Pozostań na tej stronie"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Czy na pewno chcesz opuścić tę stronę?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nCzy na pewno chcesz opuścić tę stronę?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Potwierdź"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Wskazówka: dotknij dwukrotnie, aby powiększyć lub pomniejszyć."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Autouzupełnianie"</string>
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"Niestety, aplikacja <xliff:g id="APPLICATION">%1$s</xliff:g> została zatrzymana."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Niestety, proces <xliff:g id="PROCESS">%1$s</xliff:g> został zatrzymany."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"Aplikacja <xliff:g id="APPLICATION">%2$s</xliff:g> nie reaguje."\n\n"Czy chcesz ją zamknąć?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Działanie <xliff:g id="ACTIVITY">%1$s</xliff:g> nie odpowiada."\n\n"Czy chcesz je zakończyć?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"Aplikacja <xliff:g id="APPLICATION">%2$s</xliff:g> nie reaguje.\n\nCzy chcesz ją zamknąć?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Działanie <xliff:g id="ACTIVITY">%1$s</xliff:g> nie odpowiada.\n\nCzy chcesz je zakończyć?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"Aplikacja <xliff:g id="APPLICATION">%1$s</xliff:g> nie reaguje. Czy chcesz ją zamknąć?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> nie odpowiada."\n\n"Czy chcesz go zakończyć?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> nie odpowiada.\n\nCzy chcesz go zakończyć?"</string>
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"Zgłoś"</string>
     <string name="wait" msgid="7147118217226317732">"Czekaj"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"Strona nie odpowiada na żądania."\n\n"Zamknąć ją?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Strona nie odpowiada na żądania.\n\nZamknąć ją?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Aplikacja przekierowana"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> jest uruchomiona."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> została pierwotnie uruchomiona."</string>
@@ -1256,6 +1296,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Pozwala aplikacji na wywoływanie domyślnej usługi kontenera w celu skopiowania zawartości. Nieprzeznaczone dla zwykłych aplikacji."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Kierowanie wyjścia multimediów"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Pozwala aplikacji na kierowanie wyjściowych danych multimedialnych do innych urządzeń zewnętrznych."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Dostęp do bezpiecznego magazynu kluczy"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Zezwala aplikacji na dostęp do bezpiecznego magazynu kluczy."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Kontroluj wyświetlanie i ukrywanie zabezpieczenia kluczami"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Umożliwia aplikacji kontrolowanie zabezpieczenia kluczami."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Dotknij dwukrotnie, aby sterować powiększeniem."</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Nie można dodać widżetu."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"OK"</string>
@@ -1265,15 +1309,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Gotowe"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Wstecz"</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Wykonaj"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Połącz"\n"z numerem <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Utwórz kontakt"\n"dla numeru <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Połącz\nz numerem <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Utwórz kontakt\ndla numeru <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Co najmniej jedna z następujących aplikacji żąda uprawnień dostępu do Twojego konta – teraz i w przyszłości."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Chcesz zezwolić na to żądanie?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Prośba o dostęp"</string>
     <string name="allow" msgid="7225948811296386551">"Zezwól"</string>
     <string name="deny" msgid="2081879885755434506">"Odmów"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Prośba o pozwolenie"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Prośba o pozwolenie"\n"dotyczące konta <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Prośba o pozwolenie\ndotyczące konta <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Sposób wprowadzania tekstu"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Synchronizacja"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Ułatwienia dostępu"</string>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Zobacz wszystkie"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Wybierz działanie"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Udostępnij przez"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Urządzenie zablokowane."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Wysyłanie..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Uruchomić przeglądarkę?"</string>
@@ -1441,10 +1484,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Łączę..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Dostępne"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"Niedostępne"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"W użyciu"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Wbudowany ekran"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"Ekran HDMI"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Nakładka nr <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", bezpieczny"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Podłączony jest wyświetlacz bezprzewodowy"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Ten ekran jest wyświetlany na innym urządzeniu"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Rozłącz"</string>
@@ -1453,7 +1498,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Nieprawidłowy wzór"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Nieprawidłowe hasło"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"Nieprawidłowy PIN"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Spróbuj ponownie za <xliff:g id="NUMBER">%d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Spróbuj ponownie za <xliff:g id="NUMBER">%1$d</xliff:g> s."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Narysuj wzór"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Podaj PIN karty SIM"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Podaj PIN"</string>
@@ -1473,27 +1518,85 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Hasło"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Zaloguj się"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nieprawidłowa nazwa użytkownika lub hasło."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Nie pamiętasz nazwy użytkownika lub hasła?"\n"Wejdź na "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Nie pamiętasz nazwy użytkownika lub hasła?\nWejdź na "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Sprawdzam konto"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> wpisałeś nieprawidłowy PIN. "\n\n"Spróbuj ponownie za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> wpisałeś nieprawidłowe hasło. "\n\n"Spróbuj ponownie za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> narysowałeś nieprawidłowy wzór odblokowania. "\n\n"Spróbuj ponownie za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> wpisałeś nieprawidłowy PIN. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> wpisałeś nieprawidłowe hasło. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> narysowałeś nieprawidłowy wzór odblokowania. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> próbowałeś nieprawidłowo odblokować tablet. Po kolejnych <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach tablet zostanie zresetowany do ustawień fabrycznych, a wszystkie dane użytkownika zostaną utracone."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> próbowałeś nieprawidłowo odblokować telefon. Po kolejnych <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach telefon zostanie zresetowany do ustawień fabrycznych, a wszystkie dane użytkownika zostaną utracone."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Po raz <xliff:g id="NUMBER">%d</xliff:g> próbowałeś nieprawidłowo odblokować tablet. Tablet zostanie teraz zresetowany do ustawień fabrycznych."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Po raz <xliff:g id="NUMBER">%d</xliff:g> próbowałeś nieprawidłowo odblokować telefon. Telefon zostanie teraz zresetowany do ustawień fabrycznych."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> nieprawidłowo narysowałeś wzór odblokowania. Po kolejnych <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach konieczne będzie odblokowanie tabletu przy użyciu danych logowania na konto Google."\n\n" Spróbuj ponownie za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> nieprawidłowo narysowałeś wzór odblokowania. Po kolejnych <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach konieczne będzie odblokowanie telefonu przy użyciu danych logowania na konto Google."\n\n" Spróbuj ponownie za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> nieprawidłowo narysowałeś wzór odblokowania. Po kolejnych <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach konieczne będzie odblokowanie tabletu przy użyciu danych logowania na konto Google.\n\n Spróbuj ponownie za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> nieprawidłowo narysowałeś wzór odblokowania. Po kolejnych <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach konieczne będzie odblokowanie telefonu przy użyciu danych logowania na konto Google.\n\n Spróbuj ponownie za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Usuń"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Chcesz ustawić głośność powyżej bezpiecznego poziomu?"\n"Słuchanie przy dużym poziomie głośności przez dłuższy czas może doprowadzić do uszkodzenia słuchu."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Chcesz ustawić głośność powyżej bezpiecznego poziomu?\nSłuchanie przy dużym poziomie głośności przez dłuższy czas może doprowadzić do uszkodzenia słuchu."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Aby włączyć ułatwienia dostępu, przytrzymaj dwa palce."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Włączono ułatwienia dostępu."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Ułatwienia dostępu zostały anulowane."</string>
     <string name="user_switched" msgid="3768006783166984410">"Bieżący użytkownik: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Właściciel"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Błąd"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Ta aplikacja nie obsługuje kont w przypadku profili z ograniczeniami"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Ta aplikacja nie obsługuje kont w profilach z ograniczeniami"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Nie znaleziono aplikacji do obsługi tej akcji"</string>
     <string name="revoke" msgid="5404479185228271586">"Cofnij"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Anulowane"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Błąd podczas zapisu treści"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"brak informacji"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Podaj PIN administratora"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Podaj PIN"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Nieprawidłowy"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Bieżący PIN"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Nowy PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Potwierdź nowy PIN"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Utwórz PIN wymagany przy zmianie ograniczeń"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"Kody PIN nie są identyczne. Spróbuj ponownie."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"PIN jest za krótki. Musi mieć co najmniej 4 cyfry."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Spróbuj za sekundę"</item>
+    <item quantity="other" msgid="4730868920742952817">"Spróbuj za <xliff:g id="COUNT">%d</xliff:g> s"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Spróbuj ponownie później"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Przesuń palcem od krawędzi ekranu, by odkryć pasek"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Przesuń palcem od krawędzi ekranu, by odkryć pasek systemu"</string>
 </resources>
diff --git a/core/res/res/values-port/alias.xml b/core/res/res/values-port/alias.xml
deleted file mode 100644
index bf3eecb..0000000
--- a/core/res/res/values-port/alias.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/assets/res/any/colors.xml
-**
-** 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.
-*/
--->
-<resources>
-    <!-- Alias used to reference one of two possible layouts in keyguard.  -->
-    <item type="layout" name="keyguard_eca">@android:layout/keyguard_emergency_carrier_area</item>
-</resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index e5c48bb..69884ab 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -100,7 +100,7 @@
     <string name="roamingText9" msgid="7969296811355152491">"Roaming - Funcionalidade de Serviço Total"</string>
     <string name="roamingText10" msgid="3992906999815316417">"Roaming - Funcionalidade de Serviço Parcial"</string>
     <string name="roamingText11" msgid="4154476854426920970">"Faixa de Roaming activada"</string>
-    <string name="roamingText12" msgid="1189071119992726320">"Faixa de Roaming desactivada"</string>
+    <string name="roamingText12" msgid="1189071119992726320">"Faixa de Roaming desativada"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"A procurar Serviço"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Não reencaminhado"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -131,12 +131,17 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Demasiadas eliminações de <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"O armazenamento do tablet está cheio. Elimine alguns ficheiros para libertar espaço."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"O armazenamento do telemóvel está cheio. Elimine alguns ficheiros para libertar espaço."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"A rede pode ser monitorizada"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Eu"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opções do tablet"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Opções do telefone"</string>
     <string name="silent_mode" msgid="7167703389802618663">"Modo silencioso"</string>
-    <string name="turn_on_radio" msgid="3912793092339962371">"Activar sem fios"</string>
-    <string name="turn_off_radio" msgid="8198784949987062346">"Desactivar sem fios"</string>
+    <string name="turn_on_radio" msgid="3912793092339962371">"Ativar sem fios"</string>
+    <string name="turn_off_radio" msgid="8198784949987062346">"Desativar sem fios"</string>
     <string name="screen_lock" msgid="799094655496098153">"Bloqueio de ecrã"</string>
     <string name="power_off" msgid="4266614107412865048">"Desligar"</string>
     <string name="silent_mode_silent" msgid="319298163018473078">"Campainha desativada"</string>
@@ -237,7 +242,7 @@
     <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Poderão ser instalados scripts para tornar o conteúdo da aplicação mais acessível."</string>
     <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Observar o texto que escreve"</string>
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Inclui dados pessoais, como números de cartões de crédito e palavras-passe."</string>
-    <string name="permlab_statusBar" msgid="7417192629601890791">"desactivar ou modificar barra de estado"</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"desativar ou modificar barra de estado"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Permite à aplicação desativar a barra de estado ou adicionar e remover ícones do sistema."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"barra de estado"</string>
     <string name="permdesc_statusBarService" msgid="716113660795976060">"Permite que a aplicação seja apresentada na barra de estado."</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Permite que a aplicação mova tarefas para primeiro e segundo plano. A aplicação poderá fazê-lo sem qualquer entrada do utilizador."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"parar aplicações em execução"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Permite que a aplicação remova tarefas e elimine as respetivas aplicações. As aplicações maliciosas podem perturbar o comportamento de outras aplicações."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"gerir pilhas de atividade"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Permite que a aplicação adicione, remova e modifique as pilhas de atividade em que são executadas outras aplicações. As aplicações maliciosas podem afetar o comportamento de outras aplicações."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"iniciar qualquer atividade"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Permite que a aplicação inicie qualquer atividade, independentemente da proteção de permissão ou do estado exportado."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"definir compatibilidade de ecrã"</string>
@@ -287,7 +294,7 @@
     <string name="permdesc_setDebugApp" msgid="4474512416299013256">"Permite que a aplicação ative a depuração para outra aplicação. As aplicações maliciosas podem utilizar isto para eliminar outras aplicações."</string>
     <string name="permlab_changeConfiguration" msgid="4162092185124234480">"alterar as definições de visualização do sistema"</string>
     <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"Permite à aplicação alterar a configuração atual, como o local ou o tamanho global do tipo de letra."</string>
-    <string name="permlab_enableCarMode" msgid="5684504058192921098">"activar modo de carro"</string>
+    <string name="permlab_enableCarMode" msgid="5684504058192921098">"ativar modo de carro"</string>
     <string name="permdesc_enableCarMode" msgid="4853187425751419467">"Permite que a aplicação ative o modo automóvel."</string>
     <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"fechar outras aplicações"</string>
     <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"Permite que a aplicação termine processos em segundo plano de outras aplicações. Isto pode fazer com que outras aplicações deixem de funcionar."</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Permite ao titular vincular-se à interface de nível superior de um método de entrada. Nunca deve ser necessário para aplicações normais."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"vincular a um serviço de acessibilidade"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permite que o titular vincule a interface de nível superior de um serviço de acessibilidade. Nunca deverá ser necessário para aplicações normais."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"vincular a um serviço de impressão"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Permite que o titular vincule a interface de nível superior de um serviço de impressão. Nunca deverá ser necessário para aplicações normais."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"vincular a um serviço spooler de impressão"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Permite que o titular vincule a interface de nível superior de um serviço spooler de impressão. Nunca deverá ser necessário para aplicações normais."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"vincular a serviço NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Permite ao titular vincular a aplicações que recriam cartões NFC. Nunca deverá ser necessário para aplicações normais."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"vincular a um serviço de texto"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Permite ao titular ligar-se à interface de nível superior de um serviço de texto (por exemplo SpellCheckerService). Nunca deverá ser necessário para aplicações normais."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"vincular a um serviço VPN"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Permite que o titular vincule a interface de nível superior de um serviço de widget. Nunca deverá ser necessário para aplicações normais."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interagir com um administrador do dispositivo"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Permite ao titular enviar intenções para um administrador do aparelho. Nunca deverá ser necessário para aplicações normais."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"adicionar ou remover um administrador de dispositivos"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Permite que o titular adicione ou remova administradores de dispositivos ativos. Nunca deverá ser necessário para aplicações normais."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"mudar orientação do ecrã"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Permite que a aplicação altere a rotação do ecrã em qualquer momento. Nunca deve ser necessário para aplicações normais."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"alterar a veloc. do ponteiro"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Permite que a aplicação leia a partir dos diversos ficheiros de registo do sistema. Isto permite descobrir informações gerais sobre a forma como o utilizador usa o telemóvel, podendo, inclusive, incluir dados pessoais ou privados."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"Utilizar qualquer descodificador de multimédia para a reprodução"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Permite que a aplicação utilize qualquer descodificador de multimédia instalado para descodificar a reprodução."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"gerir credenciais fidedignas"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Permite que a aplicação instale e desinstale certificados da AC (Autoridade de certificação) como credenciais fidedignas."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"ler/escrever em recursos propriedade de diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permite à aplicação ler e escrever em qualquer recurso que seja propriedade do grupo diag; por exemplo, ficheiros em /dev. Isto pode potencialmente afetar a estabilidade e a segurança do sistema e deve ser utilizado APENAS para diagnósticos específicos do hardware pelo fabricante ou pelo operador."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"ativar ou desativar componentes da aplicação"</string>
@@ -462,6 +479,14 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permite que a aplicação se configure e se ligue a visores Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"controlar visores Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Permite que a aplicação controle funcionalidades de baixo nível em visores Wi-Fi."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"capturar saída de áudio"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Permite à aplicação capturar e redirecionar a saída de áudio."</string>
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Deteção de Palavra de ativação"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Permite à aplicação capturar áudio para deteção da Palavra de ativação. A captura pode acontecer em segundo plano, mas não impede outras capturas de áudio (por exemplo com câmara de vídeo)."</string>
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"capturar saída de vídeo"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Permite à aplicação capturar e redirecionar a saída de vídeo."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"capturar saída de vídeo segura"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Permite à aplicação capturar e redirecionar a saída de vídeo segura."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"alterar as suas definições de áudio"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Permite que a aplicação modifique definições de áudio globais, tais como o volume e qual o altifalante utilizado para a saída de som."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"gravar áudio"</string>
@@ -470,8 +495,8 @@
     <string name="permdesc_camera" msgid="8497216524735535009">"Permite que a aplicação tire fotografias e grave vídeos com a câmara. Esta autorização permite que a aplicação utilize a câmara sem a sua confirmação em qualquer altura."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"desativar LED indicador de transmissão com a câmara em utilização"</string>
     <string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"Permite que uma aplicação de sistema pré-instalada desative o LED indicador de utilização da câmara."</string>
-    <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"desactivar tablet de forma permanente"</string>
-    <string name="permlab_brick" product="default" msgid="8337817093326370537">"desactivar telefone de forma permanente"</string>
+    <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"desativar tablet de forma permanente"</string>
+    <string name="permlab_brick" product="default" msgid="8337817093326370537">"desativar telefone de forma permanente"</string>
     <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"Permite que a aplicação desative definitivamente todo o tablet. Esta ação é muito perigosa."</string>
     <string name="permdesc_brick" product="default" msgid="5788903297627283099">"Permite que a aplicação desative definitivamente todo o telemóvel. Esta ação é muito perigosa."</string>
     <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"forçar reinício do tablet"</string>
@@ -525,6 +550,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"impedir modo de inactividade do telefone"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Permite que a aplicação impeça o tablet de entrar no modo de suspensão."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Permite que a aplicação impeça o telemóvel de entrar em inatividade."</string>
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"transmitir infravermelhos"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Permite que a aplicação utilize o transmissor de infravermelhos do tablet."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Permite que a aplicação utilize o transmissor de infravermelhos do telemóvel."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"ligar ou desligar o tablet"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"ligar ou desligar o telefone"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Permite que uma aplicação ligue ou desligue o tablet."</string>
@@ -613,6 +641,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Permite que a aplicação escreva no cartão SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modif./elim. armaz. interno"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Permite que a aplicação modifique o conteúdo de armazenamento de suportes internos."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"gerir o armaz. de documentos"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Permite que a aplicação faça a gestão do armazenamento de documentos."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"aceder ao armazenamento externo de todos os utilizadores"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Permite que a aplicação aceda ao armazenamento externo para todos os utilizadores."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"aceder ao sistema de ficheiros da cache"</string>
@@ -625,10 +655,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Permite que a aplicação faça a gestão de políticas de rede e defina regras específicas de aplicações."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"modificar contabilização da utilização da rede"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Permite que a aplicação modifique o modo como a utilização da rede é contabilizada em relação a aplicações. Nunca é necessário para aplicações normais."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"modificar marcas de socket"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Permite que a aplicação modifique as marcas de socket para encaminhamento"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"aceder às notificações"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Permite que a aplicação obtenha, examine e limpe notificações, incluindo as que foram publicadas por outras aplicações."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"vincular a um serviço de escuta de notificações"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Permite que o titular vincule a interface de nível superior de um serviço de escuta de notificações. Nunca deverá ser necessário para aplicações normais."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"invocar a aplicação de configuração fornecida pela operadora"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Permite que o titular invoque a aplicação de configuração fornecida pela operadora. Nunca deverá ser necessário para aplicações normais."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"ouvir observações sobre as condições da rede"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permite que uma aplicação ouça observações sobre as condições da rede. Nunca deverá ser necessário para aplicações normais."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Definir regras de palavra-passe"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlar o comprimento e os caracteres permitidos nas palavras-passe de desbloqueio do ecrã."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitorizar tentativas de desbloqueio do ecrã"</string>
@@ -738,8 +774,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +831,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Insira um cartão SIM."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"O cartão SIM está em falta ou não é legível. Introduza um cartão SIM."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Cartão SIM inutilizável."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"O cartão SIM foi desativado definitivamente. "\n" Contacte o seu fornecedor de serviços de rede sem fios para obter outro cartão SIM."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"O cartão SIM foi desativado definitivamente. \n Contacte o seu fornecedor de serviços de rede sem fios para obter outro cartão SIM."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Botão Faixa anterior"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Botão Faixa seguinte"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Botão Pausa"</string>
@@ -808,11 +843,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Consulte o Manual de utilizador ou contacte a Assistência a Clientes."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"O cartão SIM está bloqueado."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"A desbloquear cartão SIM..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Desenhou a sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. "\n\n"Tente novamente dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Escreveu a sua palavra-passe incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. "\n\n" Tente novamente dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Escreveu o seu número PIN incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. "\n\n" Tente novamente dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Desenhou a sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após outras <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, ser-lhe-á pedido para desbloquear o tablet com as suas credenciais de início de sessão do Google."\n\n" Tente novamente dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Desenhou a sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após outras <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, ser-lhe-á pedido para desbloquear o telemóvel com as suas credenciais de início de sessão do Google."\n\n" Tente novamente dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Desenhou a sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Escreveu a sua palavra-passe incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\n Tente novamente dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Escreveu o seu número PIN incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\n Tente novamente dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Desenhou a sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após outras <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, ser-lhe-á pedido para desbloquear o tablet com as suas credenciais de início de sessão do Google.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Desenhou a sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após outras <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, ser-lhe-á pedido para desbloquear o telemóvel com as suas credenciais de início de sessão do Google.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Tentou desbloquear o tablet <xliff:g id="NUMBER_0">%d</xliff:g> vezes de forma incorreta. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativa(s) sem êxito, as definições de origem do tablet serão repostas e todos os dados de utilizador serão perdidos."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Tentou desbloquear o telemóvel <xliff:g id="NUMBER_0">%d</xliff:g> vezes de forma incorreta. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativa(s) sem êxito, as definições de origem do telemóvel serão repostas e todos os dados de utilizador serão perdidos."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Tentou desbloquear o tablet <xliff:g id="NUMBER">%d</xliff:g> vezes de forma incorreta, pelo que serão repostas as respetivas definições de origem."</string>
@@ -826,7 +861,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Palavra-passe"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Iniciar sessão"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nome de utilizador ou palavra-passe inválidos."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Esqueceu-se do nome de utilizador ou da palavra-passe?"\n"Visite "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Esqueceu-se do nome de utilizador ou da palavra-passe?\nVisite "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"A verificar…"</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Desbloquear"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Som ativado"</string>
@@ -874,7 +909,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Confirmar Navegação"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Sair desta Página"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Permanecer nesta Página"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Tem a certeza de que pretende navegar para outra página?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nTem a certeza de que pretende navegar para outra página?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Confirmar"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Sugestão: toque duas vezes para aumentar ou diminuir o zoom."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Preenchimento Automático"</string>
@@ -1069,7 +1104,7 @@
     <string name="dialog_alert_title" msgid="2049658708609043103">"Atenção"</string>
     <string name="loading" msgid="7933681260296021180">"A carregar…"</string>
     <string name="capital_on" msgid="1544682755514494298">"Ativado"</string>
-    <string name="capital_off" msgid="6815870386972805832">"Desactivar"</string>
+    <string name="capital_off" msgid="6815870386972805832">"Desativar"</string>
     <string name="whichApplication" msgid="4533185947064773386">"Concluir ação utilizando"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"Utilizar por predefinição para esta acção."</string>
     <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Limpar a predefinição nas Definições do Sistema &gt; Aplicações &gt; Transferidas."</string>
@@ -1080,14 +1115,14 @@
     <string name="aerr_application" msgid="932628488013092776">"Lamentamos, o <xliff:g id="APPLICATION">%1$s</xliff:g> foi interrompido."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Lamentamos, o processo <xliff:g id="PROCESS">%1$s</xliff:g> foi interrompido."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> não está a responder. "\n\n"Pretende fechá-la?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"A atividade <xliff:g id="ACTIVITY">%1$s</xliff:g> não está a responder. "\n\n" Pretende fechá-la?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> não está a responder. \n\nPretende fechá-la?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"A atividade <xliff:g id="ACTIVITY">%1$s</xliff:g> não está a responder. \n\n Pretende fechá-la?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> não está a responder. Pretende fechá-la?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"O processo <xliff:g id="PROCESS">%1$s</xliff:g> não está a responder. "\n\n" Pretende fechá-lo?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"O processo <xliff:g id="PROCESS">%1$s</xliff:g> não está a responder. \n\n Pretende fechá-lo?"</string>
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"Relatório"</string>
     <string name="wait" msgid="7147118217226317732">"Esperar"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"A página deixou de responder. "\n" "\n" Pretende fechá-la?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"A página deixou de responder. \n \n Pretende fechá-la?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Aplicação redirecionada"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> está agora a ser executado."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> foi originalmente iniciado."</string>
@@ -1189,19 +1224,19 @@
     <string name="usb_storage_title" msgid="5901459041398751495">"Ligado através de USB"</string>
     <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"Ligou ao computador através de USB. Toque no botão abaixo se pretender copiar ficheiros entre o computador e a memória de armazenamento USB do Android."</string>
     <string name="usb_storage_message" product="default" msgid="805351000446037811">"Ligou ao computador através de USB. Toque no botão abaixo se pretender copiar ficheiros entre o computador e o cartão SD do Android."</string>
-    <string name="usb_storage_button_mount" msgid="1052259930369508235">"Activar armazenamento USB"</string>
+    <string name="usb_storage_button_mount" msgid="1052259930369508235">"Ativar armazenamento USB"</string>
     <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"Existe um problema ao utilizar a memória de armazenamento USB para o armazenamento em massa USB."</string>
     <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"Existe um problema ao utilizar o cartão SD para armazenamento em massa USB."</string>
     <string name="usb_storage_notification_title" msgid="8175892554757216525">"Ligado através de USB"</string>
     <string name="usb_storage_notification_message" msgid="939822783828183763">"Toque para copiar ficheiros para/do computador."</string>
-    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Desactivar armazenamento USB"</string>
+    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Desativar armazenamento USB"</string>
     <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"Toque para desativar a memória de armazenamento USB."</string>
     <string name="usb_storage_stop_title" msgid="660129851708775853">"O armazenamento USB está a ser utilizado"</string>
     <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"Antes de desativar a memória de armazenamento USB, desmonte (\"ejete\") a memória de armazenamento USB do Android do computador."</string>
     <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"Antes de desativar a memória de armazenamento USB, desmonte (\"ejete\") o cartão SD do Android do computador."</string>
-    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"Desactivar armazenamento USB"</string>
+    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"Desativar armazenamento USB"</string>
     <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"Ocorreu um problema ao desativar a memória de armazenamento USB. Verifique se desinstalou o anfitrião USB e, em seguida, tente novamente."</string>
-    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Activar armazenamento USB"</string>
+    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Ativar armazenamento USB"</string>
     <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Se ativar a memória de armazenamento USB, algumas aplicações que estiver a utilizar serão paradas e poderão ficar indisponíveis até desativar a memória de armazenamento USB."</string>
     <string name="dlg_error_title" msgid="7323658469626514207">"Operação USB sem êxito"</string>
     <string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
@@ -1256,6 +1291,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Permite à aplicação invocar o serviço de contentor predefinido para copiar conteúdo. Não se destina a ser utilizado por aplicações normais."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Encaminhar saída de som multimédia"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Permite que a aplicação encaminhe a saída de som multimédia para outros dispositivos externos."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Aceder ao armazenamento seguro de proteção de teclado"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Permite a uma aplicação aceder ao armazenamento seguro de proteção de teclado."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Controlar apresentação e ocultação de proteção de teclado"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Permite que uma aplicação controle a proteção de teclado."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Toque duas vezes para controlar o zoom"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Não foi possível adicionar widget."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Ir"</string>
@@ -1265,15 +1304,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Concluído"</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"\n"utilizando <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Criar contacto"\n"utilizando <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Marcar número\nutilizando <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Criar contacto\nutilizando <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Uma ou várias das aplicações seguintes solicitam permissão para aceder à sua conta, agora e no futuro."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Pretende autorizar este pedido?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Pedido de acesso"</string>
     <string name="allow" msgid="7225948811296386551">"Permitir"</string>
     <string name="deny" msgid="2081879885755434506">"Recusar"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Permissão solicitada"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Permissão solicitada"\n"para a conta <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Permissão solicitada\npara a conta <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Método de entrada"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Sincronização"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Acessibilidade"</string>
@@ -1420,7 +1459,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Ver tudo"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Escolher atividade"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Partilhar com"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Aparelho bloqueado."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"A enviar..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Iniciar Navegador?"</string>
@@ -1441,10 +1479,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"A ligar..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Disponível"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"Não disponível"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"Em utilização"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Ecrã Integrado"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"Ecrã HDMI"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Sobreposição #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> ppp"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", protegido"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"O Display sem fios está ligado"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Este ecrã está a ser apresentado noutro dispositivo"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Desligar"</string>
@@ -1453,7 +1493,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Sequência Incorreta"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Palavra-passe Incorreta"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN Incorreto"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Tente novamente dentro de <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Tente novamente dentro de <xliff:g id="NUMBER">%1$d</xliff:g> segundos."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Desenhe a sua sequência"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Introduzir PIN do cartão SIM"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Introduzir PIN"</string>
@@ -1473,27 +1513,85 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Palavra-passe"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Iniciar sessão"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nome de utilizador ou palavra-passe inválidos."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Esqueceu-se do nome de utilizador ou da palavra-passe?"\n"Aceda a "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Esqueceu-se do nome de utilizador ou da palavra-passe?\nAceda a "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"A verificar a conta…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Escreveu o PIN incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. "\n\n"Tente novamente dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Escreveu a palavra-passe incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. "\n\n"Tente novamente dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Desenhou a sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. "\n\n"Tente novamente dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Escreveu o PIN incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Escreveu a palavra-passe incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Desenhou a sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tentou desbloquear o tablet <xliff:g id="NUMBER_0">%d</xliff:g> vezes de forma incorreta. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem êxito, as definições de origem do telemóvel serão repostas e todos os dados do utilizador serão perdidos."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Tentou desbloquear o telemóvel <xliff:g id="NUMBER_0">%d</xliff:g> vezes de forma incorreta. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem êxito, as definições de origem do telemóvel serão repostas e todos os dados do utilizador serão perdidos."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Tentou desbloquear o tablet <xliff:g id="NUMBER">%d</xliff:g> vezes de forma incorreta, pelo que será reposta a predefinição de fábrica."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Tentou desbloquear o telemóvel <xliff:g id="NUMBER">%d</xliff:g> vezes de forma incorreta, pelo que será reposta a predefinição de fábrica."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Desenhou a sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, ser-lhe-á pedido para desbloquear o tablet através de uma conta de email."\n\n" Tente novamente dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Desenhou a sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, ser-lhe-á pedido para desbloquear o telemóvel através de uma conta de email."\n\n" Tente novamente dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Desenhou a sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, ser-lhe-á pedido para desbloquear o tablet através de uma conta de email.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Desenhou a sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, ser-lhe-á pedido para desbloquear o telemóvel através de uma conta de email.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" - "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Remover"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Aumentar o volume acima do nível recomendado?"\n"Ouvir em volume alto durante longos períodos de tempo poderá prejudicar a sua audição."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Aumentar o volume acima do nível recomendado?\nOuvir em volume alto durante longos períodos de tempo poderá prejudicar a sua audição."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Mantenha os dois dedos para ativar a acessibilidade."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Acessibilidade ativada."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Acessibilidade cancelada."</string>
     <string name="user_switched" msgid="3768006783166984410">"<xliff:g id="NAME">%1$s</xliff:g> do utilizador atual."</string>
     <string name="owner_name" msgid="2716755460376028154">"Proprietário"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Erro"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Esta aplicação não suporta contas de perfis restritos"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Esta aplicação não suporta contas de perfis restritos"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Não foram encontradas aplicações para executar esta ação"</string>
     <string name="revoke" msgid="5404479185228271586">"Revogar"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Cancelada"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Erro ao escrever conteúdo"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"desconhecido"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Introduza o PIN de administrador"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Introduzir PIN"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Incorreto"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN Atual"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Novo PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Confirme o novo PIN"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Crie um PIN para modificar as restrições"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"Os PINs não correspondem. Tente novamente."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"O PIN é demasiado pequeno. Deve ter, no mínimo, 4 dígitos."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Tente em: 1 seg"</item>
+    <item quantity="other" msgid="4730868920742952817">"Tente em: <xliff:g id="COUNT">%d</xliff:g> seg"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Tente novamente mais tarde"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Desliz. da extr. do ecrã p/ revelar barra"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Deslize da extremidade do ecrã para revelar a barra do sistema"</string>
 </resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index f0f3d60..4b6c7fa 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -131,6 +131,11 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Muitas exclusões de <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"O armazenamento do tablet está cheio. Exclua alguns arquivos para liberar espaço."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"O armazenamento do telefone está cheio. Exclua alguns arquivos para liberar espaço."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"A rede pode ser monitorada"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Eu"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opções do tablet"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Opções do telefone"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Permite que o aplicativo mova tarefas para o primeiro plano e o plano de fundo, sem sua intervenção."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"parar os aplicativos em execução"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Permite que um aplicativo remova tarefas e elimine seus aplicativos. Aplicativos maliciosos podem interferir no comportamento de outros aplicativos."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"gerenciar pilhas de atividades"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Permite que o aplicativo adicione, remova e modifique as pilhas de atividades nas quais outros aplicativos são executados. Aplicativos mal-intencionados podem comprometer o funcionamento de outros aplicativos."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"iniciar qualquer atividade"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Permite que o aplicativo inicie qualquer atividade, independentemente da permissão ou do estado exportado."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"definir a compatibilidade de tela"</string>
@@ -287,7 +294,7 @@
     <string name="permdesc_setDebugApp" msgid="4474512416299013256">"Permite que o aplicativo ative a depuração para outro aplicativo. Aplicativos maliciosos podem usar esse recurso para cancelar outros aplicativos."</string>
     <string name="permlab_changeConfiguration" msgid="4162092185124234480">"alterar configurações de exibição do sistema"</string>
     <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"Permite que o aplicativo altere a configuração atual, como o local ou o tamanho da fonte."</string>
-    <string name="permlab_enableCarMode" msgid="5684504058192921098">"ativar o modo de carro"</string>
+    <string name="permlab_enableCarMode" msgid="5684504058192921098">"ativar o modo carro"</string>
     <string name="permdesc_enableCarMode" msgid="4853187425751419467">"Permite que o aplicativo ative o modo Carro."</string>
     <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"fechar outros aplicativos"</string>
     <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"Permite que o aplicativo encerre processos em segundo plano de outros aplicativos. Pode ser que outros aplicativos parem de funcionar."</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Permite que o proprietário utilize a interface de nível superior de um método de entrada. Nunca deve ser necessário para aplicativos normais."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"usar um serviço de acessibilidade"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permite que o proprietário use a interface de nível superior de um serviço de acessibilidade. Nunca deve ser necessário para aplicativos comuns."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"associar a um serviço de impressão"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Permite que o proprietário use a interface de nível superior de um serviço de impressão. Não deve ser necessário para aplicativos comuns."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"associar a um serviço de spooler de impressão"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Permite que o proprietário use a interface de nível superior de um serviço de spooler de impressão. Não deve ser necessário para aplicativos comuns."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"associar ao serviço NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Permite ao proprietário associar a aplicativos que emulam cartões NFC. Não deve ser necessário para aplicativos comuns."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"sujeitar-se a um serviço de texto"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Permite que o proprietário utilize interface de nível superior de um serviço de texto (por exemplo, SpellCheckerService). Nunca deve ser necessário para aplicativos normais."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"se ligam a um serviço de VPN"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Permite que o proprietário utilize a interface de nível superior de um serviço de widget. Nunca deve ser necessário para aplicativos normais."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interagir com o administrador de um dispositivo"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Permite que o proprietário envie tentativas ao administrador de um aparelho. Nunca deve ser necessário para aplicativos normais."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"adicionar ou remover um administrador do dispositivo"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Permite que o proprietário adicione ou remova administradores do dispositivo ativos. Não deve ser necessário para aplicativos comuns."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"alterar orientação da tela"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Permite que o aplicativo gire a tela a qualquer momento. Nunca deve ser necessário para aplicativos normais."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"alterar velocidade do ponteiro"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Permite que o aplicativo leia os diversos arquivos de registro do sistema. Isso permite que ele descubra informações gerais sobre o que você está fazendo com o telefone, inclusive possíveis informações pessoais ou privadas."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"usar qualquer decodificador de mídia para reprodução"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Permite que o aplicativo use qualquer decodificador de mídia instalado para reprodução."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"gerenciar credenciais confiáveis"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Permite que o aplicativo instale e desinstale certificados CA como credenciais confiáveis."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"ler/gravar em recursos pertencentes ao diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permite que um aplicativo leia e grave em qualquer recurso que pertença ao grupo de diagnósticos, por exemplo, arquivos in/dev. Isso pode afetar a estabilidade e a segurança do sistema. Esse recurso deve ser usado APENAS para diagnósticos específicos do hardware realizados pelo fabricante ou pela operadora."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"ativar ou desativar os componentes do aplicativo"</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permite que o aplicativo configure e conecte a monitores Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"controlar monitores Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Permite que o aplicativo controle recursos de baixo nível de monitores Wi-Fi."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"capturar saída de áudio"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Permite que o aplicativo capture e redirecione a saída de áudio."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"capturar saída de vídeo"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Permite que o aplicativo capture e redirecione a saída de vídeo."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"capturar saída de vídeo segura"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Permite que o aplicativo capture e redirecione a saída de vídeo segura."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"alterar as suas configurações de áudio"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Permite que o aplicativo modifique configurações de áudio globais como volume e alto-falantes de saída."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"gravar áudio"</string>
@@ -525,6 +552,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"impedir modo de inatividade do telefone"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Permite que o aplicativo impeça o tablet de entrar no modo de inatividade."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Permite que o aplicativo impeça o telefone de entrar no modo de inatividade."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"ligar ou desligar o tablet"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"ligar ou desligar o telefone"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Permite que o aplicativo ative ou desative o tablet."</string>
@@ -613,6 +646,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Permite que o aplicativo grave em seu cartão SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modificar/excluir conteúdos de armazenamento de mídia internos"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Permite que o aplicativo modifique o conteúdo da mídia de armazenamento interno."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"gerenciar armaz. de documentos"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Permitir que o aplicativo gerencie o armazenamento de documentos."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"acessar arm. ext. dos usuários"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Permite que o aplicativo acesse o armazenamento externo para todos os usuários."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"acessar o sistema de arquivos de cache"</string>
@@ -625,12 +660,18 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Permite que o aplicativo gerencie políticas de rede e definia regras específicas para o aplicativo."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"modificar contagem de uso da rede"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Permite que o aplicativo modifique como o uso da rede é contabilizado em relação aos aplicativos. Não deve ser usado em aplicativos normais."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"modificar marcas de soquetes"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Permite que o aplicativo modifique marcas de soquetes para roteamento"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"acessar notificações"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Permite que o aplicativo recupere, examine e limpe notificações, inclusive as postadas por outros aplicativos."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"sujeitar a um serviço ouvinte de notificações"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Permite que o proprietário sujeite a interface de nível superior a um serviço ouvinte de notificações. Não deve ser necessário para aplicativos comuns."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"invocar o aplicativo de configuração fornecido pela operadora"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Permite que o proprietário invoque o aplicativo de configuração fornecido pela operadora. Não deve ser necessário para aplicativos comuns."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"detectar observações nas condições da rede"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permite que o aplicativo detecte observações nas condições da rede. Não deve ser necessário para aplicativos comuns."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Definir regras para senha"</string>
-    <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controle o tamanho e os caracteres permitidos nas senhas de desbloqueio de tela."</string>
+    <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlar o tamanho e os caracteres permitidos nas senhas de desbloqueio de tela."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitorar tentativas de desbloqueio da tela"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Monitorar quantas vezes a senha foi digitada incorretamente ao desbloquear a tela e bloquear o tablet ou apagar todos os dados do tablet se a senha for digitada incorretamente muitas vezes."</string>
     <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Monitorar quantas vezes a senha foi digitada incorretamente ao desbloquear a tela e bloquear o telefone ou apagar todos os dados do telefone se a senha for digitada incorretamente muitas vezes."</string>
@@ -640,7 +681,7 @@
     <string name="policydesc_forceLock" msgid="1141797588403827138">"Controle como e quando a tela é bloqueada."</string>
     <string name="policylab_wipeData" msgid="3910545446758639713">"Apagar todos os dados"</string>
     <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Apague os dados do tablet sem aviso redefinindo a configuração original."</string>
-    <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Apague os dados do telefone sem aviso redefinindo a configuração original."</string>
+    <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Apagar os dados do telefone sem aviso redefinindo a configuração original."</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Definir o proxy global do dispositivo"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Configura o proxy global do dispositivo para ser usado enquanto a política estiver ativada. Somente o primeiro administrador do dispositivo pode configurar um verdadeiro proxy global."</string>
     <string name="policylab_expirePassword" msgid="885279151847254056">"Definir val. da senha de bloqueio"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +836,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Insera um cartão SIM."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"O cartão SIM não foi inserido ou não é possível lê-lo. Insira um cartão SIM."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Cartão SIM inutilizável."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"O cartão SIM foi desativado permanentemente."\n"Entre em contato com seu provedor de serviços sem fio para obter outro cartão SIM."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"O cartão SIM foi desativado permanentemente.\nEntre em contato com seu provedor de serviços sem fio para obter outro cartão SIM."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Botão \"Faixa anterior\""</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Botão \"Próxima faixa\""</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Botão \"Pausar\""</string>
@@ -808,11 +848,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Consulte o Guia do usuário ou entre em contato com o Serviço de atendimento ao cliente."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"O cartão SIM está bloqueado."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Desbloqueando o cartão SIM…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. "\n\n"Tente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Você digitou sua senha incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. "\n\n"Tente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Você digitou seu PIN incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes."\n\n"Tente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear seu tablet."\n\n" Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear."\n\n" Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Você digitou sua senha incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Você digitou seu PIN incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes.\n\nTente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear seu tablet.\n\n Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear.\n\n Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Você tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas malsucedidas, o tablet será redefinido para o padrão de fábrica e todos os dados do usuário serão perdidos."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Você tentou desbloquear incorretamente o telefone <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas malsucedidas, o telefone será redefinido para o padrão de fábrica e todos os dados do usuário serão perdidos."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Você tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER">%d</xliff:g> vezes. O tablet será redefinido para o padrão de fábrica."</string>
@@ -826,7 +866,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Senha"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Fazer login"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nome de usuário ou senha inválidos."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Esqueceu seu nome de usuário ou senha?"\n"Acesse "<b>"google.com.br/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Esqueceu seu nome de usuário ou senha?\nAcesse "<b>"google.com.br/accounts/recovery"</b>"."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Verificando…"</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Desbloquear"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Som ativado"</string>
@@ -874,7 +914,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Confirmar navegação"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Sair desta página"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Permanecer nesta página"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Tem certeza de que deseja sair desta página?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nTem certeza de que deseja sair desta página?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Confirmar"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Dica: toque duas vezes para aumentar e diminuir o zoom."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Preench. aut."</string>
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"O <xliff:g id="APPLICATION">%1$s</xliff:g> parou."</string>
     <string name="aerr_process" msgid="4507058997035697579">"O processo <xliff:g id="PROCESS">%1$s</xliff:g> parou."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> não está respondendo."\n\n"Deseja fechá-la?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"A atividade <xliff:g id="ACTIVITY">%1$s</xliff:g> não está respondendo."\n\n"Deseja fechá-la?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> não está respondendo.\n\nDeseja fechá-la?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"A atividade <xliff:g id="ACTIVITY">%1$s</xliff:g> não está respondendo.\n\nDeseja fechá-la?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> não está respondendo. Deseja encerrar o aplicativo?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"O processo <xliff:g id="PROCESS">%1$s</xliff:g> não está respondendo."\n\n"Deseja fechá-lo?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"O processo <xliff:g id="PROCESS">%1$s</xliff:g> não está respondendo.\n\nDeseja fechá-lo?"</string>
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"Informar"</string>
     <string name="wait" msgid="7147118217226317732">"Aguardar"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"A página não responde."\n\n"Deseja fechá-la?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"A página não responde.\n\nDeseja fechá-la?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Aplicativo redirecionado"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> não está em execução."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> foi iniciado."</string>
@@ -1256,6 +1296,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Permite que o aplicativo invoque serviços contêiner padrão para copiar conteúdo. Não deve ser usado em aplicativos normais."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Rotear saída de mídia"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Permite que um aplicativo faça o roteamento de saída de mídia para outros dispositivos externos."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Acessar o armazenamento seguro do bloqueio de teclado"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Permite que o aplicativo acesse o armazenamento seguro do bloqueio de teclado."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Controlar a exibição e ocultação do bloqueio de tela"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Permite que o aplicativo controle o bloqueio de teclado."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Toque duas vezes para controlar o zoom"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Não foi possível adicionar widget."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Ir"</string>
@@ -1265,15 +1309,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Concluído"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Anter."</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Executar"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Discar número"\n"usando <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Criar contato "\n"usando <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Discar número\nusando <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Criar contato \nusando <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"O aplicativo a seguir ou outros aplicativos solicitam permissão para acessar sua conta, agora e no futuro."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Deseja permitir essa solicitação?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Solicitação de acesso"</string>
     <string name="allow" msgid="7225948811296386551">"Permitir"</string>
     <string name="deny" msgid="2081879885755434506">"Negar"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Permissão solicitada"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Permissão solicitada"\n"para a conta <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Permissão solicitada\npara a conta <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Método de entrada"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Sincronizar"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Acessibilidade"</string>
@@ -1292,7 +1336,7 @@
     <string name="no_file_chosen" msgid="6363648562170759465">"Nenhum arquivo escolhido"</string>
     <string name="reset" msgid="2448168080964209908">"Redefinir"</string>
     <string name="submit" msgid="1602335572089911941">"Enviar"</string>
-    <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Modo de carro ativado"</string>
+    <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Modo carro ativado"</string>
     <string name="car_mode_disable_notification_message" msgid="8035230537563503262">"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="6857031760103062982">"Toque para configurar."</string>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Ver tudo"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Selecione a atividade"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Compartilhar com"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Dispositivo bloqueado."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Enviando..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Abrir Navegador?"</string>
@@ -1441,10 +1484,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Conectando..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Disponível"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"Não disponível"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"Em uso"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Tela integrada"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"Tela HDMI"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Sobreposição nº <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", seguro"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"O Display sem fio está conectado"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Tela exibida em outro dispositivo."</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Desconectar"</string>
@@ -1453,7 +1498,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Padrão incorreto"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Senha incorreta"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN incorreto"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Tente novamente em <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Tente novamente em <xliff:g id="NUMBER">%1$d</xliff:g> segundos."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Desenhe seu padrão"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Digite o PIN do cartão SIM"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Digite o PIN"</string>
@@ -1473,27 +1518,85 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Senha"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Fazer login"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nome de usuário ou senha inválidos."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Esqueceu seu nome de usuário ou senha?"\n"Acesse "<b>"google.com.br/accounts/recovery"</b>"."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Esqueceu seu nome de usuário ou senha?\nAcesse "<b>"google.com.br/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Verificando a conta..."</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Você digitou seu PIN incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. "\n\n"Tente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Você digitou sua senha incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. "\n\n"Tente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. "\n\n"Tente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Você digitou seu PIN incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Você digitou sua senha incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Você tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas malsucedidas, o tablet será redefinido para o padrão de fábrica e todos os dados do usuário serão perdidos."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Você tentou desbloquear incorretamente o telefone <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas malsucedidas, o telefone será redefinido para o padrão de fábrica e todos os dados do usuário serão perdidos."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Você tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER">%d</xliff:g> vezes. O tablet será redefinido para o padrão de fábrica."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Você tentou desbloquear incorretamente o telefone <xliff:g id="NUMBER">%d</xliff:g> vezes. O telefone será redefinido para o padrão de fábrica."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear seu tablet."\n\n" Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear."\n\n" Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear seu tablet.\n\n Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear.\n\n Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Remover"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Aumentar o volume acima do nível recomendado?"\n"A audição em volume elevado por períodos longos pode prejudicar sua audição."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Aumentar o volume acima do nível recomendado?\nA audição em volume elevado por períodos longos pode prejudicar sua audição."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Mantenha pressionado com dois dedos para ativar a acessibilidade."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Acessibilidade ativada."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Acessibilidade cancelada."</string>
     <string name="user_switched" msgid="3768006783166984410">"Usuário atual <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Proprietário"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Erro"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Este aplicativo não suporta contas para perfis restritos"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Este aplicativo não suporta contas para perfis restritos"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Nenhum aplicativo encontrado para executar a ação"</string>
     <string name="revoke" msgid="5404479185228271586">"Revogar"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Carta"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Ofício"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloide"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Cancelado"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Erro ao gravar o conteúdo"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"desconhecido"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Inserir PIN do administrador"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Insira o PIN"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Incorreto"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN atual"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Novo PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Confirme o novo PIN"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Crie um PIN para modificar restrições"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"Os PINs não coincidem. Tente novamente."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"O PIN é curto demais. Deve ter pelo menos 4 dígitos."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Tente novamente em 1 segundo"</item>
+    <item quantity="other" msgid="4730868920742952817">"Tente novamente em <xliff:g id="COUNT">%d</xliff:g> segundos"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Tente novamente mais tarde"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Deslize a borda da tela para ver a barra"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Deslize a partir da borda da tela ver a barra do sistema"</string>
 </resources>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index cad9d1a..c4b5e5b 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -158,6 +158,12 @@
     <skip />
     <!-- no translation found for low_memory (3475999286680000541) -->
     <skip />
+    <!-- no translation found for ssl_ca_cert_warning (5848402127455021714) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Jau"</string>
     <!-- no translation found for power_dialog (8545351420865202853) -->
     <skip />
@@ -414,6 +420,10 @@
     <skip />
     <!-- no translation found for permdesc_removeTasks (1394714352062635493) -->
     <skip />
+    <!-- no translation found for permlab_manageActivityStacks (7391191384027303065) -->
+    <skip />
+    <!-- no translation found for permdesc_manageActivityStacks (1615881933034084440) -->
+    <skip />
     <!-- no translation found for permlab_startAnyActivity (2918768238045206456) -->
     <skip />
     <!-- no translation found for permdesc_startAnyActivity (997823695343584001) -->
@@ -553,6 +563,18 @@
     <skip />
     <!-- no translation found for permdesc_bindAccessibilityService (7034615928609331368) -->
     <skip />
+    <!-- no translation found for permlab_bindPrintService (8462815179572748761) -->
+    <skip />
+    <!-- no translation found for permdesc_bindPrintService (7960067623209111135) -->
+    <skip />
+    <!-- no translation found for permlab_bindPrintSpoolerService (6807762783744125954) -->
+    <skip />
+    <!-- no translation found for permdesc_bindPrintSpoolerService (3680552285933318372) -->
+    <skip />
+    <!-- no translation found for permlab_bindNfcService (2752731300419410724) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNfcService (6120647629174066862) -->
+    <skip />
     <!-- no translation found for permlab_bindTextService (7358378401915287938) -->
     <skip />
     <!-- no translation found for permdesc_bindTextService (8151968910973998670) -->
@@ -571,6 +593,10 @@
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interacziun cun in administratur dad apparats"</string>
     <!-- no translation found for permdesc_bindDeviceAdmin (569715419543907930) -->
     <skip />
+    <!-- no translation found for permlab_manageDeviceAdmins (4248828900045808722) -->
+    <skip />
+    <!-- no translation found for permdesc_manageDeviceAdmins (5025608167709942485) -->
+    <skip />
     <string name="permlab_setOrientation" msgid="3365947717163866844">"midar l\'orientaziun dal visur"</string>
     <!-- no translation found for permdesc_setOrientation (3046126619316671476) -->
     <skip />
@@ -632,6 +658,10 @@
     <skip />
     <!-- no translation found for permdesc_anyCodecForPlayback (8283912488433189010) -->
     <skip />
+    <!-- no translation found for permlab_manageCaCertificates (1678391896786882014) -->
+    <skip />
+    <!-- no translation found for permdesc_manageCaCertificates (4015644047196937014) -->
+    <skip />
     <string name="permlab_diagnostic" msgid="8076743953908000342">"leger/scriver en resursas che appartegnan a diagnostics"</string>
     <!-- no translation found for permdesc_diagnostic (6608295692002452283) -->
     <skip />
@@ -753,6 +783,22 @@
     <skip />
     <!-- no translation found for permdesc_controlWifiDisplay (4543912292681826986) -->
     <skip />
+    <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
+    <skip />
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <!-- no translation found for permlab_captureVideoOutput (2246828773589094023) -->
+    <skip />
+    <!-- no translation found for permdesc_captureVideoOutput (359481658034149860) -->
+    <skip />
+    <!-- no translation found for permlab_captureSecureVideoOutput (7815398969303382016) -->
+    <skip />
+    <!-- no translation found for permdesc_captureSecureVideoOutput (2779793064709350289) -->
+    <skip />
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"modifitgar Voss parameters audio"</string>
     <!-- no translation found for permdesc_modifyAudioSettings (3522565366806248517) -->
     <skip />
@@ -864,6 +910,12 @@
     <skip />
     <!-- no translation found for permdesc_wakeLock (8559100677372928754) -->
     <skip />
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <!-- no translation found for permlab_devicePower (2787034722616350417) -->
     <skip />
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"metter en/ord funcziun l\'apparat"</string>
@@ -1025,6 +1077,10 @@
     <skip />
     <!-- no translation found for permdesc_mediaStorageWrite (8189160597698529185) -->
     <skip />
+    <!-- no translation found for permlab_manageDocs (5778318598448849829) -->
+    <skip />
+    <!-- no translation found for permdesc_manageDocs (8704323176914121484) -->
+    <skip />
     <!-- no translation found for permlab_sdcardAccessAll (8150613823900460576) -->
     <skip />
     <!-- no translation found for permdesc_sdcardAccessAll (3215208357415891320) -->
@@ -1048,6 +1104,10 @@
     <skip />
     <!-- no translation found for permdesc_modifyNetworkAccounting (5443412866746198123) -->
     <skip />
+    <!-- no translation found for permlab_markNetworkSocket (3658527214914959749) -->
+    <skip />
+    <!-- no translation found for permdesc_markNetworkSocket (7655568433696356578) -->
+    <skip />
     <!-- no translation found for permlab_accessNotifications (7673416487873432268) -->
     <skip />
     <!-- no translation found for permdesc_accessNotifications (458457742683431387) -->
@@ -1056,6 +1116,14 @@
     <skip />
     <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
     <skip />
+    <!-- no translation found for permlab_invokeCarrierSetup (3699600833975117478) -->
+    <skip />
+    <!-- no translation found for permdesc_invokeCarrierSetup (4159549152529111920) -->
+    <skip />
+    <!-- no translation found for permlab_accessNetworkConditions (8206077447838909516) -->
+    <skip />
+    <!-- no translation found for permdesc_accessNetworkConditions (6899102075825272211) -->
+    <skip />
     <!-- no translation found for policylab_limitPassword (4497420728857585791) -->
     <skip />
     <!-- no translation found for policydesc_limitPassword (3252114203919510394) -->
@@ -1982,6 +2050,14 @@
     <skip />
     <!-- no translation found for permdesc_route_media_output (4932818749547244346) -->
     <skip />
+    <!-- no translation found for permlab_access_keyguard_secure_storage (7565552237977815047) -->
+    <skip />
+    <!-- no translation found for permdesc_access_keyguard_secure_storage (5866245484303285762) -->
+    <skip />
+    <!-- no translation found for permlab_control_keyguard (172195184207828387) -->
+    <skip />
+    <!-- no translation found for permdesc_control_keyguard (3043732290518629061) -->
+    <skip />
     <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4070433208160063538) -->
     <skip />
     <!-- no translation found for gadget_host_error_inflating (4882004314906466162) -->
@@ -1994,8 +2070,8 @@
     <!-- no translation found for ime_action_previous (1443550039250105948) -->
     <skip />
     <string name="ime_action_default" msgid="2840921885558045721">"Exequir"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Cumponer il numer"\n"cun utilisar <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Agiuntar in contact"\n"cun il numer <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Cumponer il numer\ncun utilisar <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Agiuntar in contact\ncun il numer <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <!-- no translation found for grant_credentials_permission_message_header (2106103817937859662) -->
     <skip />
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Vulais Vus autorisar questa dumonda?"</string>
@@ -2277,8 +2353,6 @@
     <skip />
     <!-- no translation found for share_action_provider_share_with (5247684435979149216) -->
     <skip />
-    <!-- no translation found for status_bar_device_locked (3092703448690669768) -->
-    <skip />
     <!-- no translation found for list_delimeter (3975117572185494152) -->
     <skip />
     <!-- no translation found for sending (3245653681008218030) -->
@@ -2319,6 +2393,8 @@
     <skip />
     <!-- no translation found for media_route_status_not_available (6739899962681886401) -->
     <skip />
+    <!-- no translation found for media_route_status_in_use (4533786031090198063) -->
+    <skip />
     <!-- no translation found for display_manager_built_in_display_name (2583134294292563941) -->
     <skip />
     <!-- no translation found for display_manager_hdmi_display_name (1555264559227470109) -->
@@ -2327,6 +2403,8 @@
     <skip />
     <!-- no translation found for display_manager_overlay_display_title (652124517672257172) -->
     <skip />
+    <!-- no translation found for display_manager_overlay_display_secure_suffix (6022119702628572080) -->
+    <skip />
     <!-- no translation found for wifi_display_notification_title (2223050649240326557) -->
     <skip />
     <!-- no translation found for wifi_display_notification_message (4498802012464170685) -->
@@ -2424,10 +2502,120 @@
     <skip />
     <!-- no translation found for error_message_title (4510373083082500195) -->
     <skip />
-    <!-- no translation found for app_no_restricted_accounts (4011285085817350390) -->
+    <!-- no translation found for app_no_restricted_accounts (5739463249673727736) -->
     <skip />
     <!-- no translation found for app_not_found (3429141853498927379) -->
     <skip />
     <!-- no translation found for revoke (5404479185228271586) -->
     <skip />
+    <!-- no translation found for mediaSize_iso_a0 (7875427489420821793) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_a1 (3760734499050875356) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_a2 (5973266378020144382) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_a3 (1373407105687300884) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_a4 (6689772807982597254) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_a5 (5353549652015741040) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_a6 (8585038048674911907) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_a7 (6641836716963839119) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_a8 (7571139437465693355) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_a9 (1378455891957115079) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_a10 (2480747457429475344) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_b0 (3965935097661108039) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_b1 (2505753285010115437) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_b2 (8763874709859458453) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_b3 (4210506688191764076) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_b4 (5749404165888526034) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_b5 (7640627414621904733) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_b6 (7342988864712748544) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_b7 (5069844065235382429) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_b8 (7316818922278779774) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_b9 (5414727094026532341) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_b10 (5251253731832048185) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_c0 (4003138342671964217) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_c1 (1935188063393553008) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_c2 (3197307969712069904) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_c3 (4335826087321913508) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_c4 (3745639598281015005) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_c5 (8269457765822791013) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_c6 (566666105260346930) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_c7 (8678413180782608498) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_c8 (8392376206627041730) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_c9 (9191613372324845405) -->
+    <skip />
+    <!-- no translation found for mediaSize_iso_c10 (7327709699184920822) -->
+    <skip />
+    <!-- no translation found for mediaSize_na_letter (4191805615829472953) -->
+    <skip />
+    <!-- no translation found for mediaSize_na_gvrnmt_letter (7853382192649405507) -->
+    <skip />
+    <!-- no translation found for mediaSize_na_legal (6697982988283823150) -->
+    <skip />
+    <!-- no translation found for mediaSize_na_junior_legal (3727743969902758948) -->
+    <skip />
+    <!-- no translation found for mediaSize_na_ledger (281871464896601236) -->
+    <skip />
+    <!-- no translation found for mediaSize_na_tabloid (5775966416333578127) -->
+    <skip />
+    <!-- no translation found for write_fail_reason_cancelled (7091258378121627624) -->
+    <skip />
+    <!-- no translation found for write_fail_reason_cannot_write (8132505417935337724) -->
+    <skip />
+    <!-- no translation found for reason_unknown (6048913880184628119) -->
+    <skip />
+    <!-- no translation found for restr_pin_enter_admin_pin (783643731895143970) -->
+    <skip />
+    <!-- no translation found for restr_pin_enter_pin (3395953421368476103) -->
+    <skip />
+    <!-- no translation found for restr_pin_incorrect (8571512003955077924) -->
+    <skip />
+    <!-- no translation found for restr_pin_enter_old_pin (1462206225512910757) -->
+    <skip />
+    <!-- no translation found for restr_pin_enter_new_pin (5959606691619959184) -->
+    <skip />
+    <!-- no translation found for restr_pin_confirm_pin (8501523829633146239) -->
+    <skip />
+    <!-- no translation found for restr_pin_create_pin (8017600000263450337) -->
+    <skip />
+    <!-- no translation found for restr_pin_error_doesnt_match (2224214190906994548) -->
+    <skip />
+    <!-- no translation found for restr_pin_error_too_short (8173982756265777792) -->
+    <skip />
+    <!-- no translation found for restr_pin_countdown:one (311050995198548675) -->
+    <!-- no translation found for restr_pin_countdown:other (4730868920742952817) -->
+    <!-- no translation found for restr_pin_try_later (973144472490532377) -->
+    <skip />
+    <!-- no translation found for transient_navigation_confirmation (4907844043611123426) -->
+    <skip />
+    <!-- no translation found for transient_navigation_confirmation_long (8061685920508086697) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 14f9644..75b0924 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -22,8 +22,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="byteShort" msgid="8340973892742019101">"O"</string>
     <string name="kilobyteShort" msgid="5973789783504771878">"KO"</string>
-    <string name="megabyteShort" msgid="6355851576770428922">"MO"</string>
-    <string name="gigabyteShort" msgid="3259882455212193214">"GO"</string>
+    <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
+    <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
     <string name="terabyteShort" msgid="231613018159186962">"TO"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PO"</string>
     <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
@@ -131,6 +131,11 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Prea multe ştergeri <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Stocarea pe tabletă este plină. Ștergeţi câteva fişiere pentru a elibera spaţiu."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Stocarea pe telefon este plină. Ștergeţi câteva fişiere pentru a elibera spaţiu."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Rețeaua poate fi monitorizată"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Eu"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opţiuni tablet PC"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Opţiuni telefon"</string>
@@ -229,11 +234,11 @@
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Accesează cardul SD."</string>
     <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"Funcții de accesibilitate"</string>
     <string name="permgroupdesc_accessibilityFeatures" msgid="4205196881678144335">"Funcții pe care tehnologia de asistare le poate solicita."</string>
-    <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperați conținutul ferestrei"</string>
+    <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperează conținutul ferestrei"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspectează conținutul unei ferestre cu care interacționați."</string>
-    <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activați funcția Explorați prin atingere"</string>
+    <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activează funcția Explorați prin atingere"</string>
     <string name="capability_desc_canRequestTouchExploration" msgid="5800552516779249356">"Elementele atinse vor fi rostite cu voce tare, iar ecranul poate fi explorat utilizând gesturi."</string>
-    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Activați accesibilitatea web îmbunătățită"</string>
+    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Activează accesibilitatea web îmbunătățită"</string>
     <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Pot fi instalate scripturi pentru a face conținutul aplicațiilor mai accesibil."</string>
     <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Remarcă textul pe care îl introduceți"</string>
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Include date personale, cum ar fi numere ale cardurilor de credit sau parole."</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Permite aplicaţiei să mute activităţile în prim-plan şi în fundal. Aplicaţia poate face acest lucru fără aportul dvs."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"oprire aplicaţii care rulează"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Permite aplicaţiei să elimine sarcini şi să închidă aplicaţiile corespunzătoare acestora. Aplicaţiile rău intenţionate pot perturba comportamentul altor aplicaţii."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"gestionarea grupurilor de activități"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Permite aplicației să adauge, să elimine și să modifice grupuri de activități în care rulează alte aplicații. Aplicațiile rău-intenționate pot perturba comportamentul altor aplicații."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"începe orice activitate"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Permite aplicaţiei să înceapă orice activitate, indiferent de protecţia permisiunii şi de starea de export."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"setaţi compatibilitatea ecranului"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Permite proprietarului să se conecteze la interfaţa de nivel superior a unei metode de introducere. Nu ar trebui să fie niciodată necesară pentru aplicaţiile obişnuite."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"conectare la un serviciu de accesibilitate"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permite proprietarului să se conecteze la interfaţa de nivel superior a unui serviciu de accesibilitate. Nu ar trebui să fie niciodată necesară pentru aplicaţiile obişnuite."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"conectarea la un serviciu de printare"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Permite proprietarului să se conecteze la interfața de nivel superior a unui serviciu de printare. Nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"conectare la un serviciu derulator de printare"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Permite proprietarului să se conecteze la interfața de nivel superior a unui serviciu derulator de printare. Nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"conectare la serviciul NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Permite aplicației autorizate să se asocieze cu aplicații care emulează carduri NFC. Nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"conectare la un serviciu text"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Permite proprietarului să se conecteze la o interfaţă de nivel superior a unui serviciu text (de ex., SpellCheckerService). Nu ar trebui să fie niciodată necesară pentru aplicaţiile obişnuite."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"conectare la un serviciu VPN"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Permite proprietarului să se conecteze la interfaţa de nivel superior a unui serviciu widget. Nu ar trebui să fie niciodată necesară pentru aplicaţiile obişnuite."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interacţionare cu administratorul unui dispozitiv"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Permite proprietarului să trimită intenţii către un administrator al dispozitivului. Nu ar trebui să fie niciodată necesară pentru aplicaţiile obişnuite."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"adăugarea sau eliminarea unui administrator de dispozitiv"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Permite proprietarului să adauge sau să elimine administratorii activi ai dispozitivului. Nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"modificare orientare ecran"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Permite aplicaţiei să modifice rotaţia ecranului în orice moment. Nu ar trebui să fie niciodată necesară pentru aplicaţiile obişnuite."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"modifică viteza indicatorului"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Permite aplicaţiei să citească din diverse fişiere jurnal ale sistemului. În acest mod poate descoperi informaţii generale cu privire la utilizarea telefonului de către dvs., care ar putea include şi informaţii personale sau private."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"utilizaţi orice decodor media pentru redare"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Permite aplicaţiei să utilizeze orice decodor media instalat pentru a decodifica redarea."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"gestionarea acreditărilor de încredere"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Permite aplicației să instaleze și să dezinstaleze certificate CA ca acreditări de încredere."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"citire/scriere în resursele deţinute de diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permite aplicaţiei să citească şi să scrie în orice resursă deţinută de grupul diag, de ex., fişierele din /dev. Această permisiune ar putea să afecteze stabilitatea şi securitatea sistemului. Permisiunea trebuie utilizată NUMAI de producător sau de operator pentru diagnostice specifice pentru hardware."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"activare sau dezactivare a componentelor aplicaţiei"</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Permite aplicaţiei să configureze şi să se conecteze la afişaje Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"controlează afişaje Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Permite aplicaţiei să controleze funcţiile de nivel redus ale afişajelor Wi-Fi."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"să intercepteze ieșirea audio"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Permite aplicației să intercepteze și să redirecționeze ieșirea audio."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"să intercepteze ieșirea video"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Permite aplicației să intercepteze și să redirecționeze ieșirea video."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"să intercepteze ieșirea video securizată"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Permite aplicației să intercepteze și să redirecționeze ieșirea video securizată."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"modificare setări audio"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Permite aplicaţiei să modifice setările audio globale, cum ar fi volumul şi difuzorul care este utilizat pentru ieşire."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"înregistrare audio"</string>
@@ -525,6 +552,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"împiedicare intrare telefon în repaus"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Permite aplicaţiei să împiedice intrarea tabletei în stare de repaus."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Permite aplicaţiei să împiedice intrarea telefonului în stare de repaus."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"pornire sau oprire computer tablet PC"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"telefon pornit sau oprit"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Permite aplicaţiei să pornească sau să oprească tableta."</string>
@@ -582,7 +615,7 @@
     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Schimbaţi starea WiMAX"</string>
     <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Permite aplicaţiei să conecteze şi să deconecteze tableta la şi de la reţelele WiMAX."</string>
     <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"Permite aplicaţiei să conecteze şi să deconecteze telefonul la şi de la reţelele WiMAX."</string>
-    <string name="permlab_bluetooth" msgid="6127769336339276828">"împerechează dispozitive Bluetooth"</string>
+    <string name="permlab_bluetooth" msgid="6127769336339276828">"conectează dispozitive Bluetooth"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Permite aplicaţiei să vadă configuraţia tabletei Bluetooth, să efectueze şi să accepte conexiuni cu dispozitive împerecheate."</string>
     <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Permite aplicaţiei să vadă configuraţia telefonului Bluetooth, să efectueze şi să accepte conexiuni cu dispozitive împerecheate."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"controlare schimb de date prin Near Field Communication"</string>
@@ -613,6 +646,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Permite aplicaţiei să scrie pe cardul SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modif./şterg. conţinutul media stocat intern"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Permite aplicaţiei să modifice conţinutul stocării media interne."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"gestionare stocare documente"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Permite aplicației să gestioneze stocarea documentelor."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"acces. stoc. ext. pt. toţi utilizat."</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Permite aplicaţiei să acceseze stocarea externă pentru toţi utilizatorii."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"accesare sistem de fişiere cache"</string>
@@ -625,10 +660,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Permite aplicaţiei să gestioneze politicile de reţea şi să definească regulile specifice aplicaţiilor."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"modificaţi modul de calcul al utilizării reţelei"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Permite aplicaţiei să modifice modul în care este calculată utilizarea reţelei pentru aplicaţii. Nu se utilizează de aplicaţiile obişnuite."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"modificarea mărcilor socketurilor"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Permite aplicației să modifice mărcile socketurilor pentru rutare."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"accesare notificări"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Permite aplicației să recupereze, să examineze și să șteargă notificări, inclusiv pe cele postate de alte aplicații."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"conectare la un serviciu de citire a notificărilor"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Permite proprietarului să se conecteze la interfața de nivel superior a unui serviciu de citire a notificărilor. În mod normal aplicațiile nu ar trebui să aibă nevoie de această permisiune."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"apelarea aplicației de configurare furnizată de operator"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Permite proprietarului să apeleze aplicația de configurare furnizată de operator. Nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"ascultă observații despre starea rețelei"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permite unei aplicații să asculte observații despre starea rețelei. Nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Setaţi reguli pentru parolă"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Stabiliţi lungimea şi tipul de caractere permise în parolele pentru deblocarea ecranului."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitorizaţi încercările de deblocare a ecranului"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +836,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Introduceţi un card SIM."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Cardul SIM lipseşte sau nu poate fi citit. Introduceţi un card SIM."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Card SIM inutilizabil."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Cardul dvs. SIM este dezactivat definitiv."\n" Contactaţi furnizorul de servicii wireless pentru a obţine un alt card SIM."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Cardul dvs. SIM este dezactivat definitiv.\n Contactaţi furnizorul de servicii wireless pentru a obţine un alt card SIM."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Butonul Melodia anterioară"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Butonul Melodia următoare"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Butonul Întrerupeţi"</string>
@@ -808,11 +848,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Consultaţi Ghidul de utilizare sau contactaţi Serviciul de relaţii cu clienţii."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Cardul SIM este blocat."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Se deblochează cardul SIM..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. "\n\n"Încercaţi din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Aţi introdus incorect parola de <xliff:g id="NUMBER_0">%d</xliff:g> ori. "\n\n"Încercaţi din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Aţi introdus incorect codul PIN de <xliff:g id="NUMBER_0">%d</xliff:g> ori."\n\n"Încercaţi din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, vi se va solicita să deblocaţi tableta cu ajutorul datelor de conectare la Google."\n\n" Încercaţi din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, vi se va solicita să deblocaţi telefonul cu ajutorul datelor de conectare la Google."\n\n" Încercaţi din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. \n\nÎncercaţi din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Aţi introdus incorect parola de <xliff:g id="NUMBER_0">%d</xliff:g> ori. \n\nÎncercaţi din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Aţi introdus incorect codul PIN de <xliff:g id="NUMBER_0">%d</xliff:g> ori.\n\nÎncercaţi din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, vi se va solicita să deblocaţi tableta cu ajutorul datelor de conectare la Google.\n\n Încercaţi din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, vi se va solicita să deblocaţi telefonul cu ajutorul datelor de conectare la Google.\n\n Încercaţi din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Aţi efectuat <xliff:g id="NUMBER_0">%d</xliff:g> încercări incorecte de deblocare a tabletei. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, aceasta va fi resetată la setările prestabilite din fabrică, iar toate datele de utilizator vor fi pierdute."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Aţi efectuat <xliff:g id="NUMBER_0">%d</xliff:g> încercări incorecte de deblocare a telefonului. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, acesta va fi resetat la setările prestabilite din fabrică, iar toate datele de utilizator vor fi pierdute."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Aţi efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a tabletei. Tableta va fi acum resetată la setările prestabilite din fabrică."</string>
@@ -826,7 +866,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Parolă"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Conectaţi-vă"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nume de utilizator sau parolă nevalide."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Aţi uitat numele de utilizator sau parola?"\n"Accesaţi "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Aţi uitat numele de utilizator sau parola?\nAccesaţi "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Se verifică..."</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Deblocaţi"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Sunet activat"</string>
@@ -874,7 +914,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Confirmați părăsirea paginii"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Părăsiți această pagină"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Rămâneți în această pagină"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Sigur doriți să părăsiți această pagină?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nSigur doriți să părăsiți această pagină?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Confirmaţi"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Sfat: măriţi şi micşoraţi prin dublă atingere."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Automat"</string>
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"Din păcate, <xliff:g id="APPLICATION">%1$s</xliff:g> s-a oprit."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Din păcate, procesul <xliff:g id="PROCESS">%1$s</xliff:g> s-a oprit."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"Aplicaţia <xliff:g id="APPLICATION">%2$s</xliff:g> nu răspunde."\n\n"Doriţi să o închideţi?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Activitatea <xliff:g id="ACTIVITY">%1$s</xliff:g> nu răspunde."\n\n"Doriţi să o închideţi?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"Aplicaţia <xliff:g id="APPLICATION">%2$s</xliff:g> nu răspunde.\n\nDoriţi să o închideţi?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Activitatea <xliff:g id="ACTIVITY">%1$s</xliff:g> nu răspunde.\n\nDoriţi să o închideţi?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"Aplicaţia <xliff:g id="APPLICATION">%1$s</xliff:g> nu răspunde. Doriţi să o închideţi?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Procesul <xliff:g id="PROCESS">%1$s</xliff:g> nu răspunde."\n\n"Doriţi să îl închideţi?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Procesul <xliff:g id="PROCESS">%1$s</xliff:g> nu răspunde.\n\nDoriţi să îl închideţi?"</string>
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"Raportaţi"</string>
     <string name="wait" msgid="7147118217226317732">"Aşteptaţi"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"Pagina a devenit inactivă."\n\n"Doriţi să o închideţi?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Pagina a devenit inactivă.\n\nDoriţi să o închideţi?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Aplicaţie redirecţionată"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> funcţionează acum."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> a fost lansată iniţial."</string>
@@ -1256,6 +1296,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Permite aplicaţiei să invoce serviciul containerului prestabilit pentru a copia conţinutul. Nu se utilizează de aplicaţiile obişnuite."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Direcţionează rezultatele media"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Permite unei aplicaţii să direcţioneze rezultate media către alte dispozitive externe."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Accesează stocarea securizată când tastatura este blocată"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Permite unei aplicații să acceseze stocarea securizată când tastatura este blocată."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Stabilește afișarea și ascunderea blocării tastaturii"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Permite unei aplicații să controleze blocarea tastaturii."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Atingeţi de două ori pentru a mări/micşora"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Nu s-a putut adăuga widgetul."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Accesaţi"</string>
@@ -1265,15 +1309,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Terminat"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Înapoi"</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Executaţi"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Formaţi numărul"\n"utilizând <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Creaţi contactul"\n"utilizând <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Formaţi numărul\nutilizând <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Creaţi contactul\nutilizând <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Următoarele aplicaţii solicită permisiunea de a accesa contul dvs. acum şi în viitor."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Permiteţi această solicitare?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Solicitare de acces"</string>
     <string name="allow" msgid="7225948811296386551">"Permiteţi"</string>
     <string name="deny" msgid="2081879885755434506">"Refuzaţi"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Permisiune solicitată"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Permisiune solicitată"\n"pentru contul <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Permisiune solicitată\npentru contul <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Metodă de intrare"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Sincronizare"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Accesibilitate"</string>
@@ -1294,7 +1338,7 @@
     <string name="submit" msgid="1602335572089911941">"Trimiteţi"</string>
     <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Mod Maşină activat"</string>
     <string name="car_mode_disable_notification_message" msgid="8035230537563503262">"Atingeţi pentru a ieşi din modul Maşină."</string>
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering sau hotspot active"</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering sau hotspot activ"</string>
     <string name="tethered_notification_message" msgid="6857031760103062982">"Atingeţi pentru a configura."</string>
     <string name="back_button_label" msgid="2300470004503343439">"Înapoi"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Înainte"</string>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Afişaţi-le pe toate"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Alegeţi activitatea"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Distribuiţi pentru"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Dispozitiv blocat."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Se trimite..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Lansaţi browserul?"</string>
@@ -1441,10 +1484,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Se conectează..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Disponibilă"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"Indisponibilă"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"În uz"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Ecran încorporat"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"Ecran HDMI"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Suprapunerea <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", securizat"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Ecranul wireless este conectat"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Acest ecran este afişat pe alt gadget"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Deconectaţi-vă"</string>
@@ -1453,7 +1498,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Model greşit"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Parolă greşită"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"Cod PIN greşit"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Încercaţi din nou peste <xliff:g id="NUMBER">%d</xliff:g> (de) secunde."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Încercaţi din nou peste <xliff:g id="NUMBER">%1$d</xliff:g> (de) secunde."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Desenaţi modelul"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Introduceţi codul PIN al cardului SIM"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Introduceţi codul PIN"</string>
@@ -1473,27 +1518,85 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Parolă"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Conectaţi-vă"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nume de utilizator sau parolă nevalide."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Aţi uitat numele de utilizator sau parola?"\n"Accesaţi "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Aţi uitat numele de utilizator sau parola?\nAccesaţi "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Se verifică contul…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Aţi introdus incorect codul PIN de <xliff:g id="NUMBER_0">%d</xliff:g> ori."\n\n"Încercaţi din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Aţi introdus incorect parola de <xliff:g id="NUMBER_0">%d</xliff:g> ori. "\n\n"Încercaţi din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. "\n\n"Încercaţi din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Aţi introdus incorect codul PIN de <xliff:g id="NUMBER_0">%d</xliff:g> ori.\n\nÎncercaţi din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Aţi introdus incorect parola de <xliff:g id="NUMBER_0">%d</xliff:g> ori. \n\nÎncercaţi din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. \n\nÎncercaţi din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Aţi efectuat <xliff:g id="NUMBER_0">%d</xliff:g> încercări incorecte de deblocare a tabletei. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, aceasta va fi resetată la setările prestabilite din fabrică, iar toate datele de utilizator se vor pierde."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Aţi efectuat <xliff:g id="NUMBER_0">%d</xliff:g> încercări incorecte de deblocare a telefonului. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, acesta va fi resetat la setările prestabilite din fabrică, iar toate datele de utilizator se vor pierde."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Aţi efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a tabletei. Tableta va fi acum resetată la setările prestabilite din fabrică."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Aţi efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a telefonului. Telefonul va fi acum resetat la setările prestabilite din fabrică."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, vi se va solicita să deblocaţi tableta cu ajutorul unui cont de e-mail."\n\n" Încercaţi din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, vi se va solicita să deblocaţi telefonul cu ajutorul unui cont de e-mail."\n\n" Încercaţi din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, vi se va solicita să deblocaţi tableta cu ajutorul unui cont de e-mail.\n\n Încercaţi din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, vi se va solicita să deblocaţi telefonul cu ajutorul unui cont de e-mail.\n\n Încercaţi din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Eliminaţi"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Ridicați volumul mai sus de nivelul recomandat?"\n"Ascultarea la volum ridicat pe perioade lungi de timp vă poate afecta auzul."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Ridicați volumul mai sus de nivelul recomandat?\nAscultarea la volum ridicat pe perioade lungi de timp vă poate afecta auzul."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Menţineţi două degete pe ecran pentru a activa accesibilitatea."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"S-a activat accesibilitatea."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accesibilitatea a fost anulată"</string>
     <string name="user_switched" msgid="3768006783166984410">"Utilizator curent: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Proprietar"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Eroare"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Această aplicație nu acceptă conturi pentru profilurile cu permisiuni limitate"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Această aplicație nu acceptă conturi pentru profilurile cu permisiuni limitate"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Nicio aplicație pentru gestionarea acestei acțiuni"</string>
     <string name="revoke" msgid="5404479185228271586">"Revocați"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Anulat"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Eroare la scrierea conținutului"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"necunoscut"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Introduceți codul PIN de administrator"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Introduceți codul PIN"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Incorect"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Codul PIN actual"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Codul PIN nou"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Confirmați noul cod PIN"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Creați un cod PIN pentru modificarea restricțiilor"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"Codurile PIN nu se potrivesc. Încercați din nou."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"Codul PIN este prea scurt. Trebuie să aibă cel puțin 4 cifre."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Reîncercați în 1 sec."</item>
+    <item quantity="other" msgid="4730868920742952817">"Reîncercați în <xliff:g id="COUNT">%d</xliff:g> sec."</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Reîncercați mai târziu"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Glisați din margine pentru a afișa"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Glisați dinspre marginea ecranului pentru a afișa bara de sistem"</string>
 </resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 81366f3..f710219 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -131,6 +131,11 @@
     <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="default" msgid="3475999286680000541">"Память телефона заполнена. Удалите какие-нибудь файлы, чтобы освободить место."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Действия в сети могут отслеживаться"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Я"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Настройки планшетного ПК"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Параметры телефона"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Приложение сможет переключать активный и фоновый режимы выполнения задач без вашего ведома."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"Остановка работающих приложений"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Приложение сможет удалять задачи и собственные программы. Вредоносное ПО при этом сможет нарушать работу других приложений."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"Управление стеком действий"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Приложение сможет добавлять, удалять и изменять стек действий, в котором выполняются другие программы. Вредоносные программы смогут влиять на поведение других приложений."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"Совершать любые действия"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Приложение сможет совершать любые действия независимо от наличия разрешений и состояния."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"Установка режима совместимости"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Приложение сможет подключаться к базовому интерфейсу системы ввода. Это разрешение не используется обычными приложениями."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"Подключение к службе специальных возможностей"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Приложение сможет подключаться к базовому интерфейсу службы специальных возможностей. Это разрешение не используется обычными приложениями."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"Подключение к службе печати"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Приложение сможет подключаться к базовому интерфейсу службы печати. Это разрешение не используется обычными приложениями."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"подключение к спулеру печати"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Приложение сможет подключаться к базовому интерфейсу спулера печати. Это разрешение не используется обычными приложениями."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"подключаться к службе NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Приложение сможет подключаться к программам с имитацией карт NFC. Это разрешение не используется обычными приложениями."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"Подключение к службе текстовых сообщений"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Позволяет подключаться к базовому интерфейсу службы текстовых сообщений (например, SpellCheckerService). Это разрешение не используется обычными приложениями."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"Подключение к VPN-службе"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Приложение сможет подключаться к базовому интерфейсу службы виджетов. Это разрешение не используется обычными приложениями."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"Взаимодействие с администратором устройства"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Приложение сможет отправлять объекты intent администратору устройства. Это разрешение не используется обычными приложениями."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"Добавление/удаление администратора устройства"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Владелец сможет добавлять и удалять администраторов устройства (используется лишь в некоторых приложениях)."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"Изменение ориентации экрана"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Приложение сможет менять ориентацию экрана. Это разрешение не используется обычными приложениями."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"Изменение скорости указателя"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Приложение сможет считывать информацию из различных системных журналов, а также получать сведения о работе пользователя на телефоне, в том числе к личной и конфиденциальной информации."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"Использование любых дешифраторов"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Приложение сможет использовать любой установленный дешифратор."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"Управление учетными данными"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Приложение сможет устанавливать сертификаты ЦС в качестве надежных учетных данных, а также удалять их."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"Чтение/запись данных в системы диагностики"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Приложение сможет считывать и записывать данные системы диагностики (например, файлы в каталоге /dev). Это может повлиять на стабильность и безопасность системы. Это разрешение должно использоваться ТОЛЬКО производителем или оператором для диагностики аппаратного обеспечения."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"Включение/отключение компонентов приложения"</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Приложение сможет подключаться к экранам с помощью Wi-Fi и настраивать их."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Управление мониторами, подключенными через Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Приложение сможет управлять низкоуровневыми функциями экранов, подключенных через Wi-Fi."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"захват аудиосигнала"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Приложение сможет захватывать и перенаправлять аудиосигнал."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"захват видеосигнала"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Приложение сможет захватывать и перенаправлять видеосигнал."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"захват защищенного видеосигнала"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Приложение сможет захватывать и перенаправлять защищенный видеосигнал."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"Изменение настроек аудио"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Приложение сможет изменять системные настройки звука, например уровень громкости и активный динамик."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"Запись аудио"</string>
@@ -525,6 +552,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"Отключение спящего режима"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Приложение сможет запрещать перевод планшетного ПК в спящий режим."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Приложение сможет запрещать перевод телефона в спящий режим."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"Включение/выключение планшета"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"Включение/выключение телефона"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Приложение сможет включать и выключать планшетный ПК."</string>
@@ -613,6 +646,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Приложение сможет записывать данные на SD-карту."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"Доступ к данным мультимедиа"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Приложение сможет изменять контент внутреннего хранилища мультимедиа."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"управлять хранением документов"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Приложение сможет управлять хранением документов."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"Доступ к внешним накопителям из всех аккаунтов"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Приложение сможет обращаться к внешним накопителям из всех аккаунтов."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"Доступ к файловой системе кэша"</string>
@@ -625,10 +660,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Приложение сможет управлять сетевыми политиками и определять правила для отдельных приложений."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"Изменение учета использования сети"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Приложение сможет изменять порядок расчета использования сетевых ресурсов различными программами. Это разрешение не используется обычными приложениями."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"Изменение отметок сокетов"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Приложение сможет изменять отметки сокетов для маршрутизации."</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_invokeCarrierSetup" msgid="3699600833975117478">"Запуск приложения настроек, предоставленного оператором"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Владелец сможет запускать приложение настроек, предоставленное оператором. Это разрешение не используется обычными приложениями."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"Использование данных о состоянии сети"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Приложение сможет использовать данные о состоянии сети. Это разрешение обычно используется только специальными приложениями."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Правила выбора паролей"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролировать длину и символы при вводе паролей для снятия блокировки экрана."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Отслеживать попытки снятия блокировки экрана"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +836,7 @@
     <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"Чтобы получить новую, обратитесь к своему оператору."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"SIM-карта окончательно заблокирована.\nЧтобы получить новую, обратитесь к своему оператору."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Кнопка перехода к предыдущему треку"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Кнопка перехода к следующему треку"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Кнопка паузы"</string>
@@ -808,11 +848,11 @@
     <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">%d</xliff:g> раз неверно указали графический ключ. "\n\n"Повтор через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали пароль. "\n\n"Повтор через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали PIN-код. "\n\n"Повтор через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали графический ключ. После <xliff:g id="NUMBER_1">%d</xliff:g> неверных попыток для разблокировки планшетного ПК потребуется войти в аккаунт Google. "\n\n" Повтор через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали графический ключ. После <xliff:g id="NUMBER_1">%d</xliff:g> неверных попыток для разблокировки телефона потребуется войти в аккаунт Google. "\n\n" Повтор через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали графический ключ. \n\nПовтор через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали пароль. \n\nПовтор через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали PIN-код. \n\nПовтор через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали графический ключ. После <xliff:g id="NUMBER_1">%d</xliff:g> неверных попыток для разблокировки планшетного ПК потребуется войти в аккаунт Google. \n\n Повтор через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали графический ключ. После <xliff:g id="NUMBER_1">%d</xliff:g> неверных попыток для разблокировки телефона потребуется войти в аккаунт Google. \n\n Повтор через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз не смогли разблокировать планшетный ПК. После <xliff:g id="NUMBER_1">%d</xliff:g> неверных попыток будут восстановлены заводские настройки, что приведет к удалению всех пользовательских данных."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз не смогли разблокировать телефон. После <xliff:g id="NUMBER_1">%d</xliff:g> неверных попыток будут восстановлены заводские настройки, что приведет к удалению всех пользовательских данных."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Вы <xliff:g id="NUMBER">%d</xliff:g> раз не смогли разблокировать планшетный ПК. Будут восстановлены заводские настройки."</string>
@@ -826,7 +866,7 @@
     <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_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>
@@ -874,7 +914,7 @@
     <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="autofill_this_form" msgid="4616758841157816676">"Автозаполнение"</string>
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"В приложении \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" произошла ошибка."</string>
     <string name="aerr_process" msgid="4507058997035697579">"В приложении \"<xliff:g id="PROCESS">%1$s</xliff:g>\" произошла ошибка."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"Приложение \"<xliff:g id="APPLICATION">%2$s</xliff:g>\" не отвечает."\n\n"Закрыть его?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Приложение \"<xliff:g id="ACTIVITY">%1$s</xliff:g>\" не отвечает."\n\n"Закрыть его?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"Приложение \"<xliff:g id="APPLICATION">%2$s</xliff:g>\" не отвечает.\n\nЗакрыть его?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Приложение \"<xliff:g id="ACTIVITY">%1$s</xliff:g>\" не отвечает.\n\nЗакрыть его?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"Приложение \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" не отвечает. Закрыть его?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Приложение \"<xliff:g id="PROCESS">%1$s</xliff:g>\" не отвечает."\n\n"Закрыть его?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Приложение \"<xliff:g id="PROCESS">%1$s</xliff:g>\" не отвечает.\n\nЗакрыть его?"</string>
     <string name="force_close" msgid="8346072094521265605">"ОК"</string>
     <string name="report" msgid="4060218260984795706">"Отзыв"</string>
     <string name="wait" msgid="7147118217226317732">"Подождать"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"Страница не отвечает."\n\n"Закрыть ее?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Страница не отвечает.\n\nЗакрыть ее?"</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>
@@ -1256,6 +1296,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Приложение сможет вызывать службу контейнеров по умолчанию для копирования данных. Это разрешение не используется обычными приложениями."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Перенаправление мультимедийных данных"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Приложение сможет направлять поток мультимедиа на другие внешние устройства."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Доступ к хранилищу ключей"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Приложение сможет получить доступ к хранилищу ключей."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Управлять отображением хранилища ключей"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Приложение сможет управлять хранилищем ключей."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Нажмите дважды для изменения масштаба"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Не удалось добавить виджет."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Выбрать"</string>
@@ -1265,15 +1309,15 @@
     <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">"Набрать номер"\n"<xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Создать контакт"\n"с номером <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Набрать номер\n<xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Создать контакт\nс номером <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Одному или нескольким приложениям требуется разрешение на доступ к вашему аккаунту сейчас и в дальнейшем."</string>
     <string name="grant_credentials_permission_message_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">"Требуется разрешение"\n"для аккаунта <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Требуется разрешение\nдля аккаунта <xliff:g id="ACCOUNT">%s</xliff:g>."</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>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Показать все"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Выберите"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Открыть доступ"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Устройство заблокировано."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Отправка..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Запустить браузер?"</string>
@@ -1441,10 +1484,12 @@
     <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>
+    <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_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> х <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> тчк/дюйм"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", безопасный"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Беспроводной проектор подключен"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Изображение передается на другое устройство"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Отключить"</string>
@@ -1453,7 +1498,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">%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>
@@ -1473,27 +1518,85 @@
     <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_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">%d</xliff:g> раз неверно указали PIN-код. "\n\n"Повтор через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали пароль."\n\n"Повтор через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали графический ключ."\n\n"Повтор через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали PIN-код. \n\nПовтор через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали пароль.\n\nПовтор через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали графический ключ.\n\nПовтор через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз не смогли разблокировать планшетный ПК. После <xliff:g id="NUMBER_1">%d</xliff:g> неверных попыток будут восстановлены заводские настройки, что приведет к удалению всех пользовательских данных."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз не смогли разблокировать телефон. После <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> раз неверно указали графический ключ. После <xliff:g id="NUMBER_1">%d</xliff:g> неверных попыток для разблокировки планшетного ПК потребуется войти в аккаунт Google."\n\n"Повтор через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали графический ключ. После <xliff:g id="NUMBER_1">%d</xliff:g> неверных попыток для разблокировки телефона потребуется войти в аккаунт Google."\n\n"Повтор через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали графический ключ. После <xliff:g id="NUMBER_1">%d</xliff:g> неверных попыток для разблокировки планшетного ПК потребуется войти в аккаунт Google.\n\nПовтор через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали графический ключ. После <xliff:g id="NUMBER_1">%d</xliff:g> неверных попыток для разблокировки телефона потребуется войти в аккаунт Google.\n\nПовтор через <xliff:g id="NUMBER_2">%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="7324161939475478066">"Увеличить громкость до небезопасного уровня?"\n"Долговременное прослушивание на такой громкости может повредить слух."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Увеличить громкость до небезопасного уровня?\nДолговременное прослушивание на такой громкости может повредить слух."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Чтобы включить специальные возможности, удерживайте пальцы на экране."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Специальные возможности включены."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Специальные возможности не будут включены."</string>
     <string name="user_switched" msgid="3768006783166984410">"Выбран аккаунт пользователя <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="app_no_restricted_accounts" msgid="4011285085817350390">"Это приложение не поддерживается в аккаунтах для профилей с ограниченным доступом"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Это приложение не поддерживается в аккаунтах для профилей с ограниченным доступом"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Невозможно обработать это действие"</string>
     <string name="revoke" msgid="5404479185228271586">"Отменить"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter (216 х 279 мм)"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter (203 х 267 мм)"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal (216 х 356 мм)"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal (203 х 127 мм)"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger (432 х 279 мм)"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid (279 х 432 мм)"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Печать отменена"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Ошибка записи"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"неизвестно"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Введите 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>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Новый PIN-код"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Введите новый PIN-код ещё раз"</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_too_short" msgid="8173982756265777792">"PIN-код должен содержать не менее 4 символов."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Повтор через 1 сек."</item>
+    <item quantity="other" msgid="4730868920742952817">"Повтор через <xliff:g id="COUNT">%d</xliff:g> сек."</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Повторите попытку позже."</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Провести от края к центру – открыть панель"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Чтобы открыть панель навигации, проведите пальцем от края к центру экрана"</string>
 </resources>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
new file mode 100644
index 0000000..9dc197f
--- /dev/null
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -0,0 +1,1592 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<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="5973789783504771878">"KB"</string>
+    <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
+    <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
+    <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
+    <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
+    <string name="untitled" msgid="4638956954852782576">"&lt;නම් යොදා නැත&gt;"</string>
+    <string name="ellipsis" msgid="7899829516048813237">"…"</string>
+    <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
+    <string name="emptyPhoneNumber" msgid="7694063042079676517">"(දුරකථන අංකයක් නොමැත)"</string>
+    <string name="unknownName" msgid="2277556546742746522">"(නොදනී)"</string>
+    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"කටහඬ තැපෑල"</string>
+    <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
+    <string name="mmiError" msgid="5154499457739052907">"සම්බන්ධතා ගැටළුවක් හෝ අවලංගු MMI කේතයකි."</string>
+    <string name="mmiFdnError" msgid="5224398216385316471">"ස්ථාවර ඇමතීම් අංක වලට පමණක් මෙහෙයුම සීමාකර ඇත."</string>
+    <string name="serviceEnabled" msgid="8147278346414714315">"සේවාව සබල කරන ලදි."</string>
+    <string name="serviceEnabledFor" msgid="6856228140453471041">"සේවාව සබලයි, සඳහා:"</string>
+    <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="mmiComplete" msgid="8232527495411698359">"MMI සම්පූර්ණයි."</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">"4 සිට 8 දක්වා අංක සහිත PIN එකක් ටයිප් කරන්න."</string>
+    <string name="invalidPuk" msgid="8761456210898036513">"අංක 8 ක් හෝ ඊට වැඩි PUK එකක් ටයිප් කරන්න."</string>
+    <string name="needPuk" msgid="919668385956251611">"ඔබගේ SIM පත පතට PUK අගුළු වැටී ඇත. එම අගුල ඇරීමට PUK කේතය ටයිප් කරන්න."</string>
+    <string name="needPuk2" msgid="4526033371987193070">"SIM පතේ අගුළු ඇරීමට PUK2 ටයිප් කරන්න."</string>
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
+    <string name="ClipMmi" msgid="6952821216480289285">"පැමිණෙන අමතන්නාගේ ID"</string>
+    <string name="ClirMmi" msgid="7784673673446833091">"පිටතට යන අමතන්නාගේ ID"</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">"PIN වෙනස් වී ඇත"</string>
+    <string name="CnipMmi" msgid="3110534680557857162">"ඇමතුම් අංකය ඇත"</string>
+    <string name="CnirMmi" msgid="3062102121430548731">"ඇමතුම් අංකය සීමා කර ඇත"</string>
+    <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="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="RestrictedChangedTitle" msgid="5592189398956187498">"සීමිත ප්‍රවේශය වෙනස් කෙරිණි"</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="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>
+    <string name="serviceClassDataSync" msgid="7530000519646054776">"සමමුහුර්ත කිරීම"</string>
+    <string name="serviceClassPacket" msgid="6991006557993423453">"පැකැට්ටුව"</string>
+    <string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
+    <string name="roamingText0" msgid="7170335472198694945">"රෝමිං දර්ශකය සක්‍රියයි"</string>
+    <string name="roamingText1" msgid="5314861519752538922">"රෝමිං දර්ශකය අක්‍රියයි"</string>
+    <string name="roamingText2" msgid="8969929049081268115">"රෝමිං දර්ශකය සැණෙලි වෙයි"</string>
+    <string name="roamingText3" msgid="5148255027043943317">"වටපිටාවෙන් ඉවත්ව"</string>
+    <string name="roamingText4" msgid="8808456682550796530">"ගොඩනැගිල්ලෙන් පිටත"</string>
+    <string name="roamingText5" msgid="7604063252850354350">"රෝමිං  - කැමති පද්ධතිය"</string>
+    <string name="roamingText6" msgid="2059440825782871513">"රෝමිං  - ලබාගත හැකි පද්ධතිය"</string>
+    <string name="roamingText7" msgid="7112078724097233605">"රෝමිං - මිත්‍ර හවුල්කරු"</string>
+    <string name="roamingText8" msgid="5989569778604089291">"රෝමිං - අධිමිල හවුල්කරු"</string>
+    <string name="roamingText9" msgid="7969296811355152491">"රෝමිං  - සම්පූර්ණ සේවා ක්‍රියාකාරිත්වය"</string>
+    <string name="roamingText10" msgid="3992906999815316417">"රෝමිං - අසම්පූර්ණ සේවා ක්‍රියාකාරීත්වය"</string>
+    <string name="roamingText11" msgid="4154476854426920970">"රෝමිං  බැනරය සක්‍රීයයි"</string>
+    <string name="roamingText12" msgid="1189071119992726320">"රෝමිං බැනරය අක්‍රියයි"</string>
+    <string name="roamingTextSearching" msgid="8360141885972279963">"සේවාව සඳහා සොයමින්"</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="TIME_DELAY">{2}</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>
+    <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="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="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="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="default" msgid="3475999286680000541">"දුරකථන ආචයනය පිරී ඇත. ඉඩ නිදහස් කිරීමට සමහර ගොනු මකන්න."</string>
+    <string name="me" msgid="6545696007631404292">"මම"</string>
+    <string name="power_dialog" product="tablet" msgid="8545351420865202853">"ටැබ්ලට විකල්ප"</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="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="shutdown_progress" msgid="2281079257329981203">"වසා දමමින්…"</string>
+    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"ඔබගේ ටැබ්ලටය වැසේ."</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="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_bug_report" msgid="7934010578922304799">"දෝෂ වර්තාව"</string>
+    <string name="bugreport_title" msgid="2667494803742548533">"දෝෂ වාර්තාවක් ගන්න"</string>
+    <string name="bugreport_message" msgid="398447048750350456">"ඊ-තැපැල් පණිවිඩයක් ලෙස යැවීමට මෙය ඔබගේ වත්මන් උපාංග තත්වය ගැන තොරතුරු එකතු කරනු ඇත. දෝෂ වාර්තාව ආරම්භ කර එය යැවීමට සූදානම් කරන තෙක් එයට කිසියම් කාලයක් ගතවනු ඇත; කරුණාකර ඉවසන්න."</string>
+    <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_airplane_mode_on_status" msgid="2719557982608919750">"අහස්යානා ආකාරය සක්‍රීයයි."</string>
+    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"අහස්යානා අකාරය අක්‍රියයි"</string>
+    <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
+    <string name="safeMode" msgid="2788228061547930246">"ආරක්‍ෂිත ආකාරය"</string>
+    <string name="android_system_label" msgid="6577375335728551336">"Android පද්ධතිය"</string>
+    <string name="permgrouplab_costMoney" msgid="5429808217861460401">"ඔබගේ මුදල් වැයවන සේවාවන්"</string>
+    <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"ඔබගෙන් මුදල් යන දේවල් කරන්න."</string>
+    <string name="permgrouplab_messages" msgid="7521249148445456662">"ඔබගේ පණිවිඩ"</string>
+    <string name="permgroupdesc_messages" msgid="7821999071003699236">"ඔබගේ SMS, ඊ-තැපැල්, සහ වෙනත් පණිවිඩ කියවන්න සහ ලියන්න."</string>
+    <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"ඔබගේ පෞද්ගලික තොරතුරු"</string>
+    <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"ඔබගේ සම්බන්ධතා පතේ ආචයනය කරන ලද, ඔබ ගැන තොරතුරු වලට ඍජු ප්‍රවේශය."</string>
+    <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"ඔබගේ සමාජයීය තොරතුරු"</string>
+    <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"ඔබගේ සම්බන්ධතා සහ සාමාජ සම්බන්ධයන් ගැන තොරතුරු වෙත ඍජු ප්‍රවේශය."</string>
+    <string name="permgrouplab_location" msgid="635149742436692049">"ඔබගේ ස්ථානය"</string>
+    <string name="permgroupdesc_location" msgid="5704679763124170100">"ඔබගේ භෞතික පිහිටුම නිරීක්ෂණය කරයි."</string>
+    <string name="permgrouplab_network" msgid="5808983377727109831">"ජාල සන්නිවේදනය"</string>
+    <string name="permgroupdesc_network" msgid="4478299413241861987">"විවිධ ජාල විශේෂාංග වෙත පිවිසෙන්න."</string>
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"බ්ලූටූත්"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"බ්ලූටූත් ඔස්සේ උපාංග සහ ජාල වෙත පිවිසෙන්න."</string>
+    <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"ශ්‍රව්‍ය සැකසීම්"</string>
+    <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"ශ්‍රව්‍ය සැකසීම් වෙනස් කරන්න."</string>
+    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"බැටරිය වෙත බලපායි"</string>
+    <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"බැටරියේ බලය ක්ෂණිකව අඩු වන විශේෂාංග භාවිත කරන්න."</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"දින දර්ශනය"</string>
+    <string name="permgroupdesc_calendar" msgid="5777534316982184416">"දින දර්ශන සිද්ධින්ට සෘජුව ප්‍රවේශ වීම."</string>
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"පරිශීලක ශබ්ද කෝෂය කියවන්න"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"පරිශීලක ශබ්ද කෝෂයේ වචන කියවීම."</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"පරිශීලක ශබ්දකෝෂයට ලිවිම"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"පරිශීලක ශබ්දකෝෂයට වචන එකතු කරන්න."</string>
+    <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"පිටුසන් සහ ඉතිහාසය"</string>
+    <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"පිටුසන් සහ බ්‍රව්සර ඉතිහාසය වෙත ඍජු ප්‍රවේශය."</string>
+    <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"සීනුව"</string>
+    <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"සීනුව සකසන්න."</string>
+    <string name="permgrouplab_voicemail" msgid="4162237145027592133">"හඬ තැපෑල"</string>
+    <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"හඬ තැපෑල වෙත ඍජු ප්‍රවේශය."</string>
+    <string name="permgrouplab_microphone" msgid="171539900250043464">"මයික්‍රොෆෝනය"</string>
+    <string name="permgroupdesc_microphone" msgid="7106618286905738408">"ශබ්දය පටිගත කිරීමට මයික්‍රොෆෝනය වෙත ඍජු ප්‍රවේශය."</string>
+    <string name="permgrouplab_camera" msgid="4820372495894586615">"කැමරාව"</string>
+    <string name="permgroupdesc_camera" msgid="2933667372289567714">"ඡායාරූප හෝ වීඩියෝ ග්‍රහණය සඳහා කැමරාව වෙත ඍජු ප්‍රවේශය."</string>
+    <string name="permgrouplab_screenlock" msgid="8275500173330718168">"අගුළු තිරය"</string>
+    <string name="permgroupdesc_screenlock" msgid="7067497128925499401">"ඔබගේ උපාංගයේ අගුළු තිරයේ ක්‍රියාකාරිත්වයට බලපාන හැකියාව."</string>
+    <string name="permgrouplab_appInfo" msgid="8028789762634147725">"ඔබගේ යෙදුම් වල තොරතුරු"</string>
+    <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"ඔබගේ උපාංගයේ වෙනත් යෙදුම් වල ක්‍රියාකාරිත්වයට බලපෑම් කළ හැකි බව."</string>
+    <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"බිතුපත"</string>
+    <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"උපාංග බිතුපතේ සැකසීම් වෙනස් කරන්න."</string>
+    <string name="permgrouplab_systemClock" msgid="406535759236612992">"ඔරලෝසුව"</string>
+    <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"උපාංග කාල හෝ කාල කලාප වෙනස් කරන්න."</string>
+    <string name="permgrouplab_statusBar" msgid="2095862568113945398">"තත්ව තීරුව"</string>
+    <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"උපාංග තත්ව තීරු සැකසීම් වෙනස් කරන්න."</string>
+    <string name="permgrouplab_syncSettings" msgid="3341990986147826541">"සමමුහුර්ත සැකසීම්"</string>
+    <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"සමමුහුර්ත සැකසීම් වෙත ප්‍රවේශය."</string>
+    <string name="permgrouplab_accounts" msgid="3359646291125325519">"ඔබගේ ගිණුම්"</string>
+    <string name="permgroupdesc_accounts" msgid="4948732641827091312">"ලබාගත හැකි ගිණුම් වලට ප්‍රවේශ වීම."</string>
+    <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"දෘඩාංග පාලක"</string>
+    <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"හෑන්ඩ්සෙටයේ දෘඩාංග වලට සෘජුවම ප්‍රවේශ වන්න."</string>
+    <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"දුරකථන ඇමතුම්"</string>
+    <string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"දුරකථන ඇමතුම් නිරීක්ෂණය කරන්න, පටිගත කරන්න සහ ක්‍රියාත්මක කරන්න."</string>
+    <string name="permgrouplab_systemTools" msgid="4652191644082714048">"පද්ධති මෙවලම්"</string>
+    <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"පද්ධතියේ පහල මට්ටම් ප්‍රවේශය සහ පාලනය."</string>
+    <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"සංවර්ධක මෙවලම්"</string>
+    <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"යෙදුම් සංවර්ධකයන් සඳහා පමණක් අවශ්‍ය විශේෂාංග."</string>
+    <string name="permgrouplab_display" msgid="4279909676036402636">"වෙනත් යෙදුම් UI"</string>
+    <string name="permgroupdesc_display" msgid="6051002031933013714">"වෙනත් යෙදුම්වල UI සඳහා බලපායි."</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"ආචයනය"</string>
+    <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"USB ආචයනය වෙත ප්‍රවේශය."</string>
+    <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"SD පත වෙත ප්‍රවේශය."</string>
+    <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"ප්‍රවේශ්‍යතා විශේෂාංග"</string>
+    <string name="permgroupdesc_accessibilityFeatures" msgid="4205196881678144335">"උපකාරීවන තාක්ෂණ ඉල්ලීම් කළ හැකි විශේෂාංග."</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="5800552516779249356">"ස්පර්ශ කරන අයිතම හඬ නගා කතා කෙරෙනු ඇති අතර ඉංගිති භාවිතයෙන් තිරය ගවේෂණය කිරීමට පුළුවනි."</string>
+    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"උසස් වෙබ් ප්‍රවේශ්‍යතාව සක්‍රිය කරන්න"</string>
+    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"යෙදුම් අන්තර්ගතයට ප්‍රවේශ්‍යතාවය වැඩිවන ලෙස සකස් කිරීමට ඇතැම් විට ස්ක්‍රිප්ට් ස්ථාපනය කර ඇත."</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"ඔබ ටයිප් කළ පෙළ බලන්න"</string>
+    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"ණයවරපත් අංක සහ මුරපද වැනි පුද්ගලික දත්ත ඇතුළත් වේ."</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"තත්ව තීරුව අබල කරන්න හෝ වෙනස් කරන්න"</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"තත්ව තීරුව අක්‍රිය කිරීමට හෝ පද්ධති නිරූපක එකතු හෝ ඉවත් කිරීමට යෙදුමට අවසර දේ."</string>
+    <string name="permlab_statusBarService" msgid="7247281911387931485">"තත්ව තීරුව"</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_processOutgoingCalls" msgid="3906007831192990946">"පිටවන ඇමතුම් වල මග වෙනස් කිරීම"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"පිටවන ඇමතුම් සකස් කිරීමට සහ ඇමතීමට නියමිත අංකය වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. මෙම අවසරයෙන් යෙදුමට පිටවන ඇමතුම් නිරීක්ෂණය, නැවත හැරවීම හෝ වැළක්වීම අවසර දෙයි."</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_receiveEmergencyBroadcast" msgid="1803477660846288089">"හදිසි විකාශන ලබා ගැනීම"</string>
+    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"හදිසි විකාශ පණිවිඩ ලැබීමට සහ ක්‍රියාත්මක කිරීමට යෙදුමට අවසර දෙන්න. පද්ධති යෙදුම් වලට පමණක් මෙම අවසරය අදාළ වෙයි."</string>
+    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"සෙල් ප්‍රචාරණ පණිවිඩ කියවීම"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"ඔබගේ උපාංගයට ලැබුණු සෙල් විකාශන පණිවිඩ කියවීමට යෙදුමට අවසර දෙන්න. ඔබට හදිසි අවස්ථාවන් පිළිබඳ අනතුරු ඇඟවීමට සෙල් විකාශන පණිවිඩ ඇතැම් ස්ථානවල සිට යවනු ලබයි. හදිසි සෙල් විකාශන ලැබෙන අවස්ථාවකදී, අනිෂ්ට යෙදුම් මඟින් ඔබගේ උපාංගයට කාර්ය සාධනයට හෝ ක්‍රියකරණයට බාධා සිදුවිය හැක."</string>
+    <string name="permlab_sendSms" msgid="5600830612147671529">"SMS පණිවිඩ යැවීම"</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"SMS පණිවිඩ යැවීමට යෙදුමට අවසර දෙන්න. මෙමඟින් බලාපොරොත්තු නොවූ ප්‍රතිඵල අත් විය හැක. අනිෂ්ට යෙදුම් ඔබගේ තහවුරුවකින් තොරව පණිවිඩ යැවීම මඟින් ඔබගේ මුදල් වැය කල හැක."</string>
+    <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"පණිවිඩ සිදුවීම හරහා ප්‍රතිචාර යැවීම"</string>
+    <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"පැමිණෙන ඇමතුම් සඳහා පණිවිඩ ඔස්සේ ප්‍රතිචාර සිදුවීම් හසුරුවීමට වෙනත් පණිවිඩ යෙදුම් සඳහා ඉල්ලීම් යැවීමට, යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"ඔබගේ පෙළ පණිවුඩ කියවන්න (SMS හෝ MMS)"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"ඔබගේ ටැබ්ලටයේ හෝ SIM පතේ ආචයනය කර ඇති SMS පණිවිඩ කියවීමට යෙදුමට අවසර දෙන්න. අන්තර්ගතය හෝ විශවාසදයි බවින් තොරවම සියලු SMS පණිවිඩ කියවීමට මෙමගින් යෙදුමට අවසර දෙයි."</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"ඔබගේ දුරකථනයේ හෝ SIM පතේ ආචයනය කරන ලද SMS පණිවිඩ කියවීමට යෙදුමට අවසර දෙන්න. අන්තර්ගතය හෝ විශ්වාසදායී බවින් තොරවම සියලු SMS පණිවිඩ කියවීමට මෙමගින් යෙදුමට අවසර දෙයි."</string>
+    <string name="permlab_writeSms" msgid="3216950472636214774">"ඔබගේ කෙටි පණිවිඩ සංස්කරණය කිරීම (SMS හෝ MMS)"</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"ඔබගේ ටැබ්ලටයේ හෝ SIM පතේ ගබඩා කර ඇති SMS පණිවිඩ වෙත ලිවීමට යෙදුමට අවසර දෙන්න. අනිෂ්ට යෙදුම් ඔබගේ පණිවිඩ මකා දැමිය හැක."</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"ඔබගේ ටැබ්ලටයේ හෝ SIM පතේ ආචයනය කරන ලද 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_interactAcrossUsers" msgid="7114255281944211682">"පරිශීලකයන් අතර අන්තර්ක්‍රියාකාරී වන්න"</string>
+    <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"උපාංගයේ විවිධ පරිශීලකයන් හරහා ක්‍රියාවන් දැක්වීමට යෙදුමට අවසර දෙන්න. පරිශීලකයන් අතර ආරක්ෂාව කඩකිරීමට අනිෂ්ට යෙදුම් විසින් මෙය භාවිතා කිරීමට ඉඩ ඇත."</string>
+    <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"පරිශීලකයන් අතර අන්තර් ක්‍රියාකාරී වීමට සම්පූර්ණ බලපත්‍රය"</string>
+    <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"පරිශීලකයන් හරහා සිදු කළ හැකි සියලු අන්තර් ක්‍රියා වලට අවසර දෙන්න."</string>
+    <string name="permlab_manageUsers" msgid="1676150911672282428">"පරිශීලකයන් කළමනාකරණය කරන්න"</string>
+    <string name="permdesc_manageUsers" msgid="8409306667645355638">"විස්තර ලබා ගැනීම, නිර්මාණකරණය, මකාදැමීම ඇතුළු පරිශීලකයන් කළමනාකරණයට යෙදුම්වලට අවසර දෙන්න."</string>
+    <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"ධාවනය වන යෙදුම් වල තොරතුරු සොයා ලබාගැනීම"</string>
+    <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"දැනට සහ මෑතක ක්‍රියාත්මක කාර්යයන් පිළිබඳ විස්තරාත්මක තොරතුරු ලබාගැනීමට යෙදුමට අවසර දෙන්න අනිෂ්ට යෙදුම් අනෙකුත් යෙදුම් පිළිබඳ පුද්ගලික තොරතුරු සොයා ගැනීමට ඉඩ තිබේ."</string>
+    <string name="permlab_reorderTasks" msgid="2018575526934422779">"ධාවනය වන යෙදුම් නැවත අනුපිළිවෙලට සැකසීම"</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"පෙරබිමට හෝ පසුබිමට සිදුවීම් ගෙනයාමට යෙදුමට අවසර දෙන්න. ඔබගේ ආදානයකින් තොරව යෙදුම මෙය සිදුකරයි."</string>
+    <string name="permlab_removeTasks" msgid="6821513401870377403">"යෙදුම් ධාවනය නවත්වන්න"</string>
+    <string name="permdesc_removeTasks" msgid="1394714352062635493">"කාර්යයන් ඉවත් කිරීමට සහ ඒවායෙහි යෙදුම් නැති කිරීමට යෙදුමට අවසර දෙන්න. අනෙක් යෙදුම් හැසිරීම බාධා කිරීමට අනිෂ්ට යෙදුම්වලට අවසර දෙන්න."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"ක්‍රියාකාරකම් අට්ටි කළමනාකරණය කරන්න"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"වෙනත් යෙදුම් ධාවනය වන ක්‍රියාකාරකම් අට්ටි වලට එකතු කිරීමට, ඉවත් කිරීමට, සහ වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. වෙනත් යෙදුම්වල හැසිරීම අනිෂ්ට යෙදුම් මගින් බාධා විය හැක."</string>
+    <string name="permlab_startAnyActivity" msgid="2918768238045206456">"ඕනෑම ක්‍රියාවක් අරඹන්න"</string>
+    <string name="permdesc_startAnyActivity" msgid="997823695343584001">"අවසර ආරක්ෂාව හෝ යැවුම් තත්වයෙන් තොරවම ඕනෑම ක්‍රියාවක් ආරම්භ කිරීමට යෙදුමට අවසර දේ."</string>
+    <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"තිර ගැළපුම සැකසීම"</string>
+    <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"වෙනත් යෙදුම්වල තිර ගැලපුම් මාදිලිය පාලනයට යෙදුමට අවසර දෙන්න. වෙනත් යෙදුම්වල හැසිරීම අනිෂ්ට යෙදුම් කැඩිය හැක."</string>
+    <string name="permlab_setDebugApp" msgid="3022107198686584052">"යෙදුම් නිදොස්කරණය සබල කිරීම"</string>
+    <string name="permdesc_setDebugApp" msgid="4474512416299013256">"වෙනත් යෙදුමක් සඳහා නිදොස්කරණය සක්‍රිය කිරීමට යෙදුමට අවසර දෙන්න. වෙනත් යෙදුම් විනාශ කිරීමට අනිෂ්ට යෙදුම් මෙය භාවිත කළ හැක."</string>
+    <string name="permlab_changeConfiguration" msgid="4162092185124234480">"පද්ධති සංදර්ශක සැකසීම් වෙනස් කරන්න"</string>
+    <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"පෙදෙසිය හෝ සම්පූර්ණ අකුරු ප්‍රමාණය වැනි පවතින වින්‍යාසය වෙනස් කිරීමට යෙදුමට අවසර දෙන්න."</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_forceStopPackages" msgid="2329627428832067700">"වෙනත් යෙදුම් බලෙන් නවත්වන්න"</string>
+    <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"යෙදුමට බලෙන් අනෙක් යෙදුම් නැවතීමට අවසර දෙන්න."</string>
+    <string name="permlab_forceBack" msgid="652935204072584616">"යෙදුම වැසීමට බල කිරීම"</string>
+    <string name="permdesc_forceBack" msgid="3892295830419513623">"නැවතීමට පෙරබිමේ ඇති ඕනෑම ක්‍රියාවක් බලෙන් නැවතීමට සහ පිටුපසට යාමට යෙදුමට අවසර දෙන්න. සාමාන්‍ය යෙදුම් සඳහා කිසිදා අවශ්‍ය නොවේ."</string>
+    <string name="permlab_dump" msgid="1681799862438954752">"පද්ධති අභ්‍යන්තර තත්වය සොයා ලබා ගන්න"</string>
+    <string name="permdesc_dump" msgid="1778299088692290329">"පද්ධතියේ අභ්‍යන්තර තත්වය ලැබීමට යෙදුමට අවසර දෙන්න. ඔවුන් සාමාන්‍යයෙන් භාවිත නොකරන විවිධත්වයකින් යුත් පුද්ගලික සහ ආරක්‍ෂිත තොරතුරු අනිෂ්ට යෙදුම් සොයා ලබා ගත හැක."</string>
+    <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"තිර අන්තර්ගතය සොයා ලබාගැනීම"</string>
+    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"ක්‍රියාකාරී කවුළුවක අන්තර්ගතය ලබාගැනීමට යෙදුමට අවසර දෙන්න. අනිෂ්ට යෙදුම් විසින් සම්පූර්ණ කවුළු අන්තර්ගතය ලබාගැනීම සහ මුරපදය හැර ඒවායෙහි පෙළ පරික්ෂා කිරීම සිදුකරයි."</string>
+    <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"ප්‍රවේශ්‍යතාවය තාවකාලිකව සබල කිරීම"</string>
+    <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"උපාංගය වෙත ප‍්‍රවේශ්‍යතාව තාවකාලිකව සක්‍රිය කිරීමට යෙදුමට අවසර දෙන්න. පරිශීලක අවධානයකින් තොරව අනිෂ්ට යෙදුම් ප‍්‍රවේශ්‍යතාව සක්‍රිය කළ හැක."</string>
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"තිර තොරතුරු සොයා ලබාගැනීම"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"කවුළු කළමනාකරු මගින් කවුළුව ගැන තොරතුරු සොයා ලබාගැනීමට යෙදුමට අවසර දෙන්න. අභ්‍යන්තර පද්ධති භාවිතය සඳහා කැමති තොරතුරු අනිෂ්ට යෙදුම් විසින් ලබා ගත හැක."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"සිදුවීම් පෙරන්න"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"පිටත් කිරීමට පෙර සියලු පරිශීලක සිදුවීම්වල ප්‍රවාහයක් පෙරීමට යොදා ගන්නා ආදාන පෙරීමක් ලියාපදිංචි කිරීමට යෙදුමට අවසර දෙන්න. පරිශීලක මැදිහත් වීමකින් තොරව පද්ධති UI අනිෂ්ට යෙදුම් පාලනය කරයි."</string>
+    <string name="permlab_magnify_display" msgid="5973626738170618775">"දර්ශනය විශාලනය කරන්න"</string>
+    <string name="permdesc_magnify_display" msgid="7121235684515003792">"දසුනේ අන්තර්ගතය විශාල කිරීමට යෙදුමට අවසර දෙන්න. ඇතැම් විට අනිෂ්ට යෙදුම්, උපාංගය භාවිතා කළ නොහැකි බවට පත් කරමින් දසුනේ අන්තර්ගතය වෙනස් කළ හැක."</string>
+    <string name="permlab_shutdown" msgid="7185747824038909016">"අඩ වශයෙන් වැහීම"</string>
+    <string name="permdesc_shutdown" msgid="7046500838746291775">"ක්‍රියාකාරකම් කළමනාකරු වැහීමේ තත්වයට දමන්න. සම්පූර්ණ වැහීමකට පත් නොකරන්න."</string>
+    <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"යෙදුම් මාරු වීම වැළක්වීම"</string>
+    <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"වෙනත් යෙදුමක් වෙත පරිශීලකයාව මාරු වීම වළක්වයි."</string>
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"පවතින යෙදුමේ තොරතුරු ලබාගැනීම"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"තිරයේ පෙරබිම තුළ තිබෙන දැන් පවත්නා යෙදුමේ පෞද්ගලික තොරතුරු ලබාගැනීමට දරන්නාට අවසර දෙන්න."</string>
+    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"සියලු යෙදුම් දියත් කිරීම් නිරීක්ෂණය සහ පාලනය කිරීම"</string>
+    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"පද්ධතිය ක්‍රියාකාරකම් දියත් කරන්නේ කෙසේදැයි නිරීක්ෂණයට සහ පාලනයට යෙදුමට අවසර දෙන්න. අනිෂ්ට යෙදුම් මගින් පද්ධතිය සම්පූර්ණයෙන්ම සම්මුතියකට එළඹිය හැක. වර්ධනය සඳහා පමණක් මෙම අවසරය අවශ්‍ය වෙයි, සාමාන්‍ය භාවිතය සඳහා කිසි විටෙකත් අවශ්‍ය නොවෙයි."</string>
+    <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"පැකේජ ඉවත් කිරීමේ ප්‍රචාරණයක් යවන්න"</string>
+    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"යෙදුම් පැකේජයක් ඉවත්කොට ඇති බවට දැනුම්දීමක් විකාශනයට යෙදුමට අවසර දෙයි. ධාවනය වන අනෙකුත් යෙදුමක් නැති කිරීමට අනිෂ්ට යෙදුම් විසින් මෙය භාවිත කළ හැක."</string>
+    <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"SMS-ලැබීම විකාශන යැවීම"</string>
+    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"SMS පණිවිඩයක් හරහා ලැබුණු දැනුම්දීමක් ප්‍රචාරණයට යෙදුමට අවසර දෙන්න. පැමිණෙන SMS පණිවිඩ වංචා කිරීමට අනිෂ්ට යෙදුම් මෙය භාවිත කළ හැක."</string>
+    <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"WAP-PUSH-ලැබීම විකාශන යැවීම"</string>
+    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"WAP PUSH පණිවුඩයක් ලැබී ඇති බවට දැනුම්දීමක් විකාශනය කිරීමට යෙදුමට අවසර දෙන්න. වංචාකාරී MMS පණිවුඩ ලැබීම් හෝ නිහඬව ඕනෑම වෙබ් පිටුවක අන්තර්ගතය අනිෂ්ට විචල්‍යවලින් ඉවත් කිරීමට, අනිෂ්ට යෙදුම් විසින් මෙය භාවිතා කිරීමට ඉඩ ඇත."</string>
+    <string name="permlab_setProcessLimit" msgid="2451873664363662666">"ධාවන ක්‍රියාවලි ගණන සීමා කිරීම"</string>
+    <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"ධාවනය වන උපරිම ක්‍රියාවලි ගණන පාලනය කිරීමට යෙදුමට අවසර දෙන්න. සාමාන්‍ය යෙදුම් සඳහා කිසිදා අවශ්‍ය නොවේ."</string>
+    <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"පසුබිම් යෙදුම් වලට වැසීමට බලකරන්න"</string>
+    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"පසුබිමට පිවිසෙනවාත් සමඟම ක්‍රියාකාරකම් නැවතීම පාලනයට යෙදුමට අවසර දෙන්න. සාමාන්‍ය යෙදුම්වලට කිසිසේත් අවශ්‍ය නොවෙයි."</string>
+    <string name="permlab_batteryStats" msgid="2789610673514103364">"බැටරි සංඛ්‍යාන කියවීම"</string>
+    <string name="permdesc_batteryStats" msgid="5897346582882915114">"වර්තමාන පහළ මට්ටමේ බැටරිය භාවිතා දත්ත කියවීමට යෙදුමට අවසර දෙන්න. ඔබ භාවිත කරන යෙදුම් මොනවා දැයි ගැන විස්තරාත්මක තොරතුරු ගැන දැන ගැනීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_updateBatteryStats" msgid="3719689764536379557">"බැටරි සංඛ්‍යාන වෙනස් කිරීම"</string>
+    <string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"එකතු කරගන්නා ලද බැටරි සංඛ්‍යාන වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. සාමාන්‍ය යෙදුම් වල භාවිතයට නොවේ."</string>
+    <string name="permlab_getAppOpsStats" msgid="1508779687436585744">"යෙදුමේ විකල්ප සංඛ්‍යාංක සොයා ලබාගැනීම"</string>
+    <string name="permdesc_getAppOpsStats" msgid="6243887041577912877">"එකතු කරගත් යෙදුම් ක්‍රියාකාරිත්ව සංඛ්‍යා ලේඛන වෙනස් කිරීමට උපාංගයට ඉඩ දෙන්න. සාමාන්‍ය උපාංග භාවිතය සඳහා නොවේ."</string>
+    <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"යෙදුම් විකල්ප සංඛ්‍යාංක වෙනස් කිරීම"</string>
+    <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"එකතු කරගත් යෙදුම් ක්‍රියාකාරිත්ව සංඛ්‍යා ලේඛන වෙනස් කිරීමට යෙදුමට ඉඩ දෙන්න. සාමාන්‍ය යෙදුම් භාවිතය සඳහා නොවේ."</string>
+    <string name="permlab_backup" msgid="470013022865453920">"පද්ධති උපස්ථ පාලනය කරන්න සහ නැවත පිහිටුවන්න"</string>
+    <string name="permdesc_backup" msgid="6912230525140589891">"පද්ධතියේ උපස්ථය සහ උපක්‍රම නැවත පිහිටුවීම පාලනයට යෙදුමට අවසර දෙන්න. සාමාන්‍ය යෙදුම් වල භාවිතය සඳහා නොවේ."</string>
+    <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"සම්පූර්ණ උපස්ථය හෝ මෙහෙයුම් නැවත පිහිටුවීම සනාථ කිරීම"</string>
+    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"පූර්ණ උපස්ථ තහවුරුකිරීම් UI පුරන්නට උපකරණයට ඉඩ දෙන්න. කිසිම යෙදුමක් භාවිතා නොකරනු ඇත."</string>
+    <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"අවසර නොලත් කවුළුව දර්ශනය කරන්න"</string>
+    <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"අභ්‍යන්තර පද්ධති පරිශීලක අතුරුමුහුණත් විසින් භාවිතා කිරීමට බලාපොරොත්තු වන කවුළු නිර්මාණය කිරීමට යෙදුමට අවසර දෙන්න. සාමාන්‍ය යෙදුම්වල භාවිතය සඳහා නොවේ."</string>
+    <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"වෙනත් යෙදුම් උඩින් අඳින්න"</string>
+    <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"අනෙක් යෙදුම් මත හෝ පරිශීලක අතුරු මුහුණත් කොටස්වල ඇඳීමට යෙදුමට ඉඩ දෙන්න. එය ඔබේ භාවිතයේ ඇති ඕනෑම යෙදුමක මුහුණත සමග සම්බන්ධ වීමට හෝ අනෙක් යෙදුම් ගැන ඔබට පෙනෙන ආකාරය වෙනස් කිරීමට ඉඩ ඇත."</string>
+    <string name="permlab_setAnimationScale" msgid="2805103241153907174">"ගෝලීය සජීවන වේගය වෙනස් කරන්න"</string>
+    <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"ඕනෑම වෙලාවක පොදු සජීවීකරණ වේගය (වේගවත් හෝ මන්දගාමී සජීවීකරණ) වෙනස් කිරීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_manageAppTokens" msgid="1286505717050121370">"යෙදුම් ටෝකන කළමනාකරණය කිරීම"</string>
+    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"සාමාන්‍ය Z පටිපාටිය මඟහැරයමින් යෙදුම්වලට අයිති ටෝකන් පත් නිර්මාණයට සහ කළමනාකරණයට යෙදුම්වලට අවසර දෙන්න. සාමාන්‍ය යෙදුම්වලට කිසිසේත් අවශ්‍ය නොවේ."</string>
+    <string name="permlab_freezeScreen" msgid="4708181184441880175">"තිරය නිශ්චල කරන්න"</string>
+    <string name="permdesc_freezeScreen" msgid="8558923789222670064">"සම්පූර්ණ තිර සංක්‍රමණය සඳහා තිරය තාවකාලිකව මුදවිමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_injectEvents" msgid="1378746584023586600">"යතුරු සහ පාලන බොත්තම් ඔබන්න"</string>
+    <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"තමන්ගේ ආදාන සිදුවීම් (යතුරු එබිම් , ආදී ) අනෙකුත් යෙදුම්වලට භාරදීමට යෙදුමට ඉඩ දෙන්න. අනිෂ්ට යෙදුම් මෙය ටැබ්ලටය ලබා ගැනීමට භාවිතා කිරීමට ඉඩ ඇත."</string>
+    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"වෙනත් යෙදුම්වලට එහි ආදාන සිදුවීම් (යතුරු එබීම්, යනාදිය.) ආදිය යැවීමට යෙදුමට අවසර දෙන්න. දුරකථනය අත්කර ගැනීම අනිෂ්ට යෙදුම් මෙය භාවිත කරයි."</string>
+    <string name="permlab_readInputState" msgid="469428900041249234">"ඔබ ටයිප් කරන දෙය සහ ඔබ ගන්නා ක්‍රියාවන් පටිගත කරන්න"</string>
+    <string name="permdesc_readInputState" msgid="8387754901688728043">"මුරපදය ටයිප් කිරීම වැනි අනෙකුත් යෙදුම් සමඟ අන්තර්ක්‍රියාකාරී වනවිට යනාදී ඔබ ඔබන යතුරු දැකීමට යෙදුමට අවසර දෙන්න. සාමාන්‍ය යෙදුම් සඳහා කිසිසේත් අදාළ නොවේ."</string>
+    <string name="permlab_bindInputMethod" msgid="3360064620230515776">"ආදාන ක්‍රමයක් වෙත බඳින්න"</string>
+    <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"ආදාන ක්‍රමය ඉහල මට්ටමේ අතුරු මුහුණතක් වෙත සම්බන්ධ කිරීමට ධාරකයාට අවසර දෙන්න. සාමාන්‍ය යෙදුම්වලට කිසි විටෙක අවශ්‍ය නොවෙයි."</string>
+    <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"ප‍්‍රවේශ්‍යතා සේවාවක් වෙත බදින්න"</string>
+    <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"ප‍්‍රවේශ්‍යතා සේවාවේ ඉහළ මට්ටමේ අතුරුමුහුණතට බැඳීමට දරන්නාට අවසර දේ. සාමාන්‍ය යෙදුම් සඳහා කිසිවිටක අවශ්‍ය නොවේ."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"මුද්‍රණ සේවාවකට බද්ධ වී ඇත"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"මුද්‍රණ සේවාව ඉහල මට්ටමේ අතුරු මුහුණතක් වෙත සම්බන්ධ කිරීමට ධාරකයාට අවසර දෙන්න. සාමාන්‍ය යෙදුම්වලට කිසි විටෙක අවශ්‍ය නොවෙයි."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"මුද්‍රණ සේවාවකට බද්ධ වී ඇත"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"මුද්‍රණ සේවාව ඉහල මට්ටමේ අතුරු මුහුණතක් වෙත සම්බන්ධ කිරීමට ධාරකයාට අවසර දෙන්න. සාමාන්‍ය යෙදුම්වලට කිසි විටෙක අවශ්‍ය නොවෙයි."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC සේවාව වෙත බැඳෙන්න"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"NFC කාඩ් පත් ආදර්ශනය කරන යෙදුම් රඳවනයට සම්බන්ධ වීමට ඉඩ දෙන්න. සාමාන්‍ය යෙදුම් සඳහා කිසිදා අවශ්‍ය නොවෙයි."</string>
+    <string name="permlab_bindTextService" msgid="7358378401915287938">"පෙළ සේවාවකට බඳින්න"</string>
+    <string name="permdesc_bindTextService" msgid="8151968910973998670">"කෙටි පණිවිඩ සේවාවක (උදා. SpellCheckerService) ඉහල මට්ටමේ අතුරු මුහුණතක් වෙත සම්බන්ධ කිරීමට ධාරකයාට අවසර දෙන්න. සාමාන්‍ය යෙදුම්වලට කිසි විටෙක අවශ්‍ය නොවෙයි."</string>
+    <string name="permlab_bindVpnService" msgid="4708596021161473255">"VPN සේවාවකට බැඳීම"</string>
+    <string name="permdesc_bindVpnService" msgid="2067845564581693905">"VPN සේවාව ඉහල මට්ටමේ අතුරු මුහුණතක් වෙත සම්බන්ධ කිරීමට ධාරකයාට අවසර දෙන්න. සාමාන්‍ය යෙදුම්වලට කිසි විටෙක අවශ්‍ය නොවෙයි."</string>
+    <string name="permlab_bindWallpaper" msgid="8716400279937856462">"බිතුපත වෙත බඳින්න"</string>
+    <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"බිතුපත ඉහල මට්ටමේ අතුරු මුහුණතක් වෙත සම්බන්ධ කිරීමට ධාරකයාට අවසර දෙන්න. සාමාන්‍ය යෙදුම්වලට කිසි විටෙක අවශ්‍ය නොවෙයි."</string>
+    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"විජට සේවාවකට බඳින්න"</string>
+    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"විජට් සේවාව ඉහල මට්ටමේ අතුරු මුහුණතක් වෙත සම්බන්ධ කිරීමට ධාරකයාට අවසර දෙන්න. සාමාන්‍ය යෙදුම්වලට කිසි විටෙක අවශ්‍ය නොවෙයි."</string>
+    <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"උපාංග පරිපාලක සමඟ අන්තර්ක්‍රියාකාරී වීම"</string>
+    <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"උපාංග පාලකයා වෙතට අභිප්‍රායයන් යැවීමට ධාරකයාට අවසර දෙන්න. සාමාන්‍ය යෙදුම්වලට කිසි විටෙක අවශ්‍ය නොවෙයි."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"උපාංග පරිපාලකයෙක් එක් කිරීම හෝ ඉවත් කිරීම"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"දරන්නාට උපාංග පරිපාලකයින් එක් කිරීමට හෝ ඉවත් කිරීමට අවසර දේ. සාමාන්‍ය යෙදුම් වලට කිසිදා අවශ්‍ය නොවේ."</string>
+    <string name="permlab_setOrientation" msgid="3365947717163866844">"තිර දිශානතිය වෙනස් කිරීම"</string>
+    <string name="permdesc_setOrientation" msgid="3046126619316671476">"තිරයේ භ්‍රමණය ඕනෑම වේලාවක වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. සාමාන්‍ය යෙදුම් සඳහා කිසිදා අවශ්‍ය නොවනු ඇත."</string>
+    <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"දර්ශකයේ වේගය වෙනස් කිරීම"</string>
+    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"මූසිකයේ හෝ ට්‍රැක්පෑඩයේ වේගය ඕනෑම මොහොතක වෙනස් කිරීමට උපාංගයට ඉඩ දෙන්න. සාමාන්‍ය උපාංගයන් සඳහා කිසිදා අවශ්‍ය නොවනු ඇත."</string>
+    <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"යතුරු පුවරු පිරිසැලැස්ම වෙනස් කිරීම"</string>
+    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"යතුරුපුවරු මුහුණත වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. සාමාන්‍ය යෙදුම් සඳහා කිසිදා අවශ්‍ය නොවෙයි."</string>
+    <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"යෙදුම් වෙත Linux සංඥා යැවීම"</string>
+    <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"පවතින සියලු ක්‍රියාවලි වෙත සැපයුම් සංඥා ඉල්ලවිමට යෙදුමට අවසර දේ."</string>
+    <string name="permlab_persistentActivity" msgid="8841113627955563938">"යෙදුම සැමවිටම ධාවනය කරන්න"</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"මතකයේ පවතින එහි කොටස් නොනැසී පැවතීමට යෙදුමට අවසර දෙන්න. වෙනත් යෙදුම් වලට මතකය සීමා කිරීමෙන් ටැබ්ලටය පමා කිරීම මගින්  මෙමගින් කළ හැක."</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"යෙදුමට තම කොටස් මතකය තුල නොබිඳීව රඳා පවත්වාගෙන යාමට අවසර දෙන්න. මෙය දුරකථනය මන්දගාමී කරමින් අනෙකුත් උපාංගයන් සඳහා ඉතිරි මතකය සීමා කිරීමට හැක."</string>
+    <string name="permlab_deletePackages" msgid="184385129537705938">"යෙදුම් මකන්න"</string>
+    <string name="permdesc_deletePackages" msgid="7411480275167205081">"Android පැකේජ මැකීමට යෙදුමට අවසර දෙන්න. වැදගත් යෙදුම් මැකීමට අනිෂ්ට යෙදුම් විසින් මෙය භාවිතා කිරීමට ඉඩ ඇත."</string>
+    <string name="permlab_clearAppUserData" msgid="274109191845842756">"යෙදුමේ වෙනත් දත්ත මකන්න"</string>
+    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"පරිශීලක දත්ත හිස් කිරීමට යෙදුමකට ඉඩ දේ."</string>
+    <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"අනෙක් යෙදුම්වල හැඹිලි මකන්න"</string>
+    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"හැඹිලි ගොනු මැකීමට අවසර යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"යෙදුම් ආචයනයේ ඉඩ ප්‍රමාණය මැනීම"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"යෙදුමකට එහි කේතය, දත්ත සහ හැඹිලි ප්‍රමාණ ලබාගැනීමට අවසර දෙන්න."</string>
+    <string name="permlab_installPackages" msgid="2199128482820306924">"යෙදුම් කෙළින්ම ස්ථාපනය කිරීම"</string>
+    <string name="permdesc_installPackages" msgid="5628530972548071284">"නව හෝ යාවත්කාලින කරන ලද Android පැකේජයන් ස්ථාපනය කිරීමට ඉඩ දෙන්න. බලසහිත අවසර තීන්දු සමග නව යෙදුම් එකතු කිරීමට අනිෂ්ට යෙදුම්වලට මෙය භාවිතා කිරීමට ඉඩ තිබේ."</string>
+    <string name="permlab_clearAppCache" msgid="7487279391723526815">"යෙදුමේ සියලුම හැඹිලි දත්ත මකන්න"</string>
+    <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"අනෙක් යෙදුම්වල හැඹිලි නාමාවලි තුළ ඇති ගොනු මැකීමෙන් යෙදුමට ටැබ්ලට ආචයනය නිදහස් කිරීමට අවසර දෙන්න. මෙමගින් අනෙක් යෙදුම්වලට ඒවායේ දත්ත නැවත ලබා ගැනීමට අවශ්‍ය වන නිසා, ඒවායේ ආරම්භය තවත් සෙමින් සිදුවීමට ඉඩ ඇත."</string>
+    <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"අනෙක් යෙදුම්වල හැඹිලි නාමාවලි තුළ ඇති ගොනු මැකීමෙන් යෙදුමට දුරකථන ආචයනය නිදහස් කිරීමට අවසර දෙන්න. මෙමඟින් අනෙක් යෙදුම්වලට ඒවායේ දත්ත නැවත ලබා ගැනීමට අවශ්‍ය වන නිසා, ඒවායේ ආරම්භය තවත් සෙමින් සිදුවීමට ඉඩ ඇත."</string>
+    <string name="permlab_movePackage" msgid="3289890271645921411">"යෙදුම් සම්පත් ගෙන යාම"</string>
+    <string name="permdesc_movePackage" msgid="319562217778244524">"අභ්‍යන්තර සහ බාහිර මාධ්‍යයන්ගෙන් යෙදුමේ සම්පත් ගෙනයාමට සහ යෙදුමේ සම්පත් වලින් අභ්‍යන්තර සහ බාහිර මාධ්‍යයන්ට යෙදුමේ සම්පත් ගෙනයාමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_readLogs" msgid="6615778543198967614">"සංවේදී ලොග් දත්ත කියවීම"</string>
+    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"පද්ධතියේ විවිධ ලොග් ගොනු කියවීමට යෙදුමට අවසර දෙන්න. පුද්ගලික සහ පෞද්ගලික තොරතුරු ඇතුළත්ව ඔබ ටැබ්ලටයෙන් කුමක් කරන්නෙහිද යනාදී සාමාන්‍ය තොරතුරු සෙවීමට මෙයට අවසර දෙන්න."</string>
+    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"පද්ධතියේ විවිධ ලොග් ගොනු කියවීමට යෙදුමට අවසර දෙන්න. පුද්ගලික සහ පෞද්ගලික තොරතුරු ඇතුළත්ව ඔබ දුරකථනයෙන් කුමක් කරන්නෙහිද යනාදී සාමාන්‍ය තොරතුරු සෙවීමට මෙයට අවසර දෙන්න."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"නැවත ධාවනය සඳහා ඕනෑම මාධ්‍ය විකේතකයක් හාවිතා කරන්න"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"නැවත ධාවනය සඳහා විකේතනය කිරීමට ඕනෑම ස්ථාපිත මාධ්‍ය විකේතකයක් භාවිතයට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"විශ්වාසදායී අක්තපත්‍ර කළමනාකරණය"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"යෙදුමට CA සහතික විශ්වාසදායී අක්තපත්‍ර ලෙස ස්ථාපනය සහ අස්ථාපනය කිරීමට ඉඩ දෙන්න."</string>
+    <string name="permlab_diagnostic" msgid="8076743953908000342">"Diag විසින් හිමිකාරත්වය දරණ සම්පත්වලට කියවීම/ ලිවිම"</string>
+    <string name="permdesc_diagnostic" msgid="6608295692002452283">"Diag කණ්ඩායමට අයිති ඕනෑම සම්පතක් කියවීමට සහ ලිවීමට යෙදුමට අවසර දෙන්න. උදාහරණයක් ලෙස /dev තුල ඇති ගොනු. මෙයට පද්ධති ස්ථායිතාවට සහ ආරක්ෂාවට බලපෑම් කිරීමට හැකියාවක් ඇත. නිෂ්පාදක හෝ ක්‍රියාකරු විසින් දෘඩාංග-විශේෂිත දෝෂ නිර්ණය සඳහා පමණක් මෙය යොදාගත යුතුය."</string>
+    <string name="permlab_changeComponentState" msgid="6335576775711095931">"යෙදුම් අංග සබල හෝ අබල කිරීම"</string>
+    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"වෙනත් යෙදුමක අංගයක් සබල ද නැද්ද යන්න වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. වැදගත් ටැබ්ලට් අවශ්‍යතා අබල කිරීමට අනිෂ්ට යෙදුම් මෙය භාවිත කළ හැක. මෙම අවසරය සැලකිල්ලෙන් භාවිතා කළ යුතුය, භාවිත නොකරන, අස්ථිර හෝ අස්ථායි තත්වයට යෙදුම පත් කිරීමට එයට හැකිය."</string>
+    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"වෙනත් යෙදුමක අංගයක් සබල ද නැද්ද යන්න වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. වැදගත් දුරකථන අවශ්‍යතා අක්‍රිය කිරීමට අනිෂ්ට යෙදුම් මෙය භාවිත කළ හැක. මෙම අවසරය සැලකිල්ලෙන් භාවිත කළ යුතුය, භාවිත නොකරන, අස්ථිර හෝ අස්ථායි තත්වයට යෙදුම පත් කිරීමට එයට හැකිය."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"අවසර ප්‍රදානය කිරීම හෝ අහෝසි කිරීම"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"යෙදුමකට එයට හෝ අනෙක් යෙදුම් වලට විශේෂිත අවසර ප්‍රදානයට හෝ අහෝසි කිරීමට අවසර දෙන්න. අනිෂ්ට යෙදුම්, ඒවාට අවසර ප්‍රදානය නොකළ ගුණාංග වලට ප්‍රවේශ වීමට මෙය භාවිතා කළ හැක."</string>
+    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"අභිරුචි යෙදුම් සකසන්න"</string>
+    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"ඔබගේ අභිරුචි යෙදුම් වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. ඔබගේ ධාවනය වන යෙදුම් වෙනස් කිරීම, පවතින යෙදුම් වලින් දත්ත එකතු කිරීම, ප්‍රෝඩා කිරීම වැනි දේ අනිෂ්ට යෙදුම් නිශ්ශබදවම සිදු කරයි."</string>
+    <string name="permlab_writeSettings" msgid="2226195290955224730">"පද්ධති සැකසීම් වෙනස් කිරීම"</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"පද්ධති සැකසීම් දත්ත වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. අනිෂ්ට යෙදුම් ඔබගේ පද්ධති වින්‍යාස දෝෂ ගැන්විය හැක."</string>
+    <string name="permlab_writeSecureSettings" msgid="204676251876718288">"ආරක්‍ෂිත පද්ධති සැකසීම් වෙනස් කරන්න"</string>
+    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"පද්ධතියේ ආරක්‍ෂිත දත්ත වෙනස් කිරීමට උපාංගයට අවසර දෙන්න. සාමාන්‍ය උපාංග සඳහා භාවිතයට නොවේ."</string>
+    <string name="permlab_writeGservices" msgid="2149426664226152185">"Google සේවා සිතියම වෙනස් කරන්න"</string>
+    <string name="permdesc_writeGservices" msgid="1287309437638380229">"Google සේවා සිතියම වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. සාමාන්‍ය යෙදුම් සඳහා භාවිතයට නොවෙයි."</string>
+    <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"ආරම්භයේදී ධාවනය කිරීම"</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"පද්ධතිය ඇරඹුම අවසන් වූ වහාම යෙදුම ආරම්භ වීමට යෙදුමට අවසර දෙන්න. ටැබ්ලටය ආරම්භ කිරීමට මෙමඟින් පමා කළ හැකි අතර සැමවිටම ධාවනය වන නිසා සම්පූර්ණ ටැබ්ලටයම ප්‍රමාද කිරීමට යෙදුමට අවසර දෙයි."</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="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="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="default" msgid="589869224625163558">"සඳහන් පුද්ගලයන්ට ඔබ ඇමතූ, ඊ-තැපැල් කළ හෝ ඇමතුම් කළ සංඛ්‍යාන ඇතුලත් ඔබගේ දුරකථනයේ ආචයනය කරන ලද සම්බන්ධතා (ලිපින) දත්ත වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. මෙම අවසරයෙන් යෙදුමට සම්බන්ධතා දත්ත මැකීමට අවසර දෙයි."</string>
+    <string name="permlab_readCallLog" msgid="3478133184624102739">"ඇමතුම් ලොගය කියවන්න"</string>
+    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"පැමිණෙන සහ පිටවන ඇමතුම් ගැන දත්ත ඇතුළත්, ඔබගේ ටැබ්ලටයේ ඇමතුම් ලොග කියවීමට යෙදුමට අවසර දෙන්න. ඔබගේ ඇමතුම් ලොග දත්ත සුරක්ෂිත කිරීමට මෙම අවසරය යෙදුම්වලට අවසර දෙයි සහ ඔබගේ දැනුමකින් තොරව ඇමතුම් ලොග දත්ත අනිෂ්ට යෙදුම් බෙදා ගැනීම කළ හැක."</string>
+    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"ලැබෙන සහ පිටවන ඇමතුම් පිළිබඳ දත්ත ඇතුළත්ව ඔබගේ දුරකථනයේ ඇමතුම් ලොග් කියවීමට යෙදුමට අවසර දෙන්න. මෙම අවසරය ඔබගේ ඇමතුම් ලොග් දත්ත උපස්ථ කිරීමට යෙදුමට ඉඩදෙන අතර ඔබගේ අනුදැනුමකින් තොරව අනිෂ්ට යෙදුම් විසින් ඇමතුම් ලොග් දත්ත බෙදාගැනීම කළ හැක."</string>
+    <string name="permlab_writeCallLog" msgid="8552045664743499354">"ඇමතුම් ලොගය ලිවීම"</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ලැබෙන ඇමතුම් සහ පිටවන ඇමතුම් දත්ත ඇතුළත්ව ඔබගේ ටැබ්ලටයේ ඇමතුම් ලොගය වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. ඔබගේ ඇමතුම් ලොගය මැකීමට හෝ වෙනස් කිරීමට අනිෂ්ට යෙදුම් මෙය භාවිතා කෙරේ."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"පැමිණෙන සහ පිටවෙන ඇමතුම් දත්ත ඇතුළුව ඔබගේ දුරකථනයේ ඇමතුම් ලොගය වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. ඔබගේ ඇමතුම් ලොගය මැකීමට හෝ වෙනස් කිරීමට අනිෂ්ට යෙදුම් මෙය භාවිත කල හැක."</string>
+    <string name="permlab_readProfile" msgid="4701889852612716678">"ඔබගේ සම්බන්ධතා පත කියවන්න"</string>
+    <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"ඔබගේ නම සම්බන්ධතා තොරතුරු ආදී ඔබගේ උපාංගයේ ගබඩා වී ඇති පුද්ගලික පැතිකඩ තොරතුරු කියවීමට යෙදුමට අවසර දෙන්න. මෙහි තේරුම යෙදුමට ඔබව හඳුනා ගැනීමට හැකි වන බව සහ ඔබගේ පුද්ගලික තොරතුරු අනෙක් අයට යැවීමට ද හැකි වීමයි."</string>
+    <string name="permlab_writeProfile" msgid="907793628777397643">"ඔබගේ සම්බන්ධතා පත වෙනස් කිරීම"</string>
+    <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"ඔබගේ නම සහ සම්බන්ධතා තොරතුරු වැනි ඔබගේ උපාංගයේ ආචයනය කරන ලද පුද්ගලික පැතිකඩ තොරතුරු වෙනස් කිරීමට හෝ එකතු කිරීමට යෙදුමට අවසර දෙන්න. මෙමගින් යෙදුමට ඔබව හඳුනා ගත හැකි අතර අනෙක් අයට ඔබගේ පැතිකඩ තොරතුරු යැවිය හැකි බව කියවෙයි."</string>
+    <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"ඔබගේ සමාජ ප්‍රවාහය කියවන්න"</string>
+    <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"ඔබගේ සහ ඔබගේ යහළුවන්ගේ සමාජ යාවත්කාලීනයන් වෙත පිවිසීමට හෝ සමමුහුර්ත කිරීමට යෙදුමට අවසර දෙන්න. තොරතුරු බෙදා ගැනීමේ දී සැලකිලිමත් වන්න -- විශ්වාසයකින් තොරව සමාජ ජාලවල ඔබගේ සහ ඔබගේ යහළුවන් අතර සන්නිවේදන කියවීමට මෙමගින් යෙදුමට අවසර දෙයි. සටහන: සියලු සමාජ ජාලවල මෙම අවසරය බල නොකරයි."</string>
+    <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"ඔබගේ සමාජ ප්‍රවාහය වෙත ලිවීම"</string>
+    <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"ඔබගේ යහළුවන්ගේ සමාජ යාවත්කාලීනයන් පෙන්වීමට යෙදුමට අවසර දෙන්න. තොරතුරු බෙදා ගැනීමේදී සැලකිලිමත් වන්න -- යහළුවෙක්ගෙන් පැමිණෙන ලෙස පණිවිඩ නිපදවීමට මෙමඟින් යෙදුමට අවසර දෙන්න. සටහන : සියලු සමාජ ජාල සඳහා මෙම අවසරය බල නොදෙයි."</string>
+    <string name="permlab_readCalendar" msgid="5972727560257612398">"දින දර්ශනයේ සිදුවීම් සහ රහසිගත තොරතුරු කියවීම"</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"ඔබගේ ටැබ්ලටය තුල ගබඩා  කර ඇති මිතුරන්ගේ සහ එක්ව ක්‍රියාකරන්නන්ගේ ද ඇතුළුව සියලුම දින දර්ශන සිද්ධි කියවීමට යෙදුමට අවසර දෙන්න. මෙය රහස්‍යභාවය හෝ සංවේදීතාවය නොසලකා ඔබගේ දින දර්ශන දත්ත බෙදා ගැනීමට හෝ සුරැකීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"යහළුවන් සහ සමකාලිනයන් ඇතුලත් ඔබගේ දුරකථනයේ ආචයනය කරන ලද සියලු දින දර්ශන සිදුවීම් කියවීමට යෙදුමට අවසර දෙන්න. විශ්වාසයකින් හෝ සංවේදීතාවකින් තොරව ඔබගේ දින දර්ශන දත්ත බෙදා ගැනීමට හෝ උපස්ථ කිරීමට මෙමගින් යෙදුමට අවසර දෙයි."</string>
+    <string name="permlab_writeCalendar" msgid="8438874755193825647">"දින දර්ශන සිද්ධි එකතු කිරීම හෝ වෙනස් කිරීමක් සිදුකර හිමිකරුගේ දැනීමකින් තොරව අමුත්තන්ට ඊ-තැපෑලක් යවීම"</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"යහළුවන් හෝ එකට-වැඩකරන්නන් ඇතුළත්ව ඔබට ටැබ්ලටයේ වෙනස් කළ හැකි සිද්ධි එකතු කිරීමට, ඉවත් කිරීමට, වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. මෙමඟින් දින දර්ශන හිමිකරුවන්ගෙන් පණිවිඩ යවන පරිදි මෙන් මවාපෑමට හෝ හිමිකරුගේ අනුදැනුමකින් තොරව සිද්ධි වෙනස් කිරීමට යෙදුමට අවසර ලැබේ."</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"ඔබගේ යහළුවන් හෝ සමකාලීනයන් ඇතුළත් ඔබගේ දුරකථනයේ ඔබට වෙනස් කළ හැකි සිදු වීම් එකතු කිරීමට, ඉවත් කිරීමට, වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. මෙමගින් දින දර්ශන හිමිකරුවන්ගෙන් පැමිණෙන සේ පෙනෙන පණිවිඩ යැවීමට හෝ හිමිකරුගේ දැනුමකින් තොරව සිදුවීම් වෙනස් කිරීමට යෙදුමට අවසර දෙයි."</string>
+    <string name="permlab_accessMockLocation" msgid="8688334974036823330">"පරීක්ෂණ සඳහා ආදර්ශ ස්ථාන මූලාශ්‍ර"</string>
+    <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"පරීක්ෂණයට ව්‍යාජ ස්ථාන මූලාශ්‍ර සාදන්න හෝ නව ස්ථාන සැපයුම්කරුවෙකු ස්ථාපනය කරන්න. GPS හෝ ස්ථාන සැපයුම්කරුවන් ආදී වෙනත් ස්ථාන මූලාශ්‍ර විසින් ලබා දෙන ස්ථානය සහ/හෝ තත්වය ප්‍රතිස්ථාපනය කිරීමට යෙදුමට මෙය අවසර දෙයි."</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"අමතර ස්ථාන සැපයුම්කරු විධාන වෙත ප්‍රවේශ වීම"</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"අමතර ස්ථාන සැපයුම්කරු විධාන වෙත පිවිසීමට යෙදුමට අවසර දෙන්න. GPS හෝ වෙනත් ස්ථාන මූලාශ්‍ර ක්‍රියාවලි වෙත බාධා කිරීමට මෙය අවසර දෙයි."</string>
+    <string name="permlab_installLocationProvider" msgid="6578101199825193873">"ස්ථාන සැපයුම්කරුවෙකු ස්ථාපනයට අවසරය දෙන්න"</string>
+    <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"පරීක්ෂණයට ව්‍යාජ ස්ථාන මූලාශ්‍ර සාදන්න හෝ නව ස්ථාන සැපයුම්කරුවෙකු ස්ථාපනය කරන්න. GPS හෝ ස්ථාන සැපයුම්කරුවන් ආදී වෙනත් ස්ථාන මූලාශ්‍ර විසින් ලබා දෙන ස්ථානය සහ/හෝ තත්ත්වය ප්‍රතිස්ථාපනය කිරීමට යෙදුමට මෙය අවසර දෙයි."</string>
+    <string name="permlab_accessFineLocation" msgid="1191898061965273372">"නිවැරදි ස්ථානය (GPS සහ ජාලය පදනම් කරගත්)"</string>
+    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"ගෝලීය ස්ථානීය පද්ධතිය (GPS) හෝ සෙල් කුළුණු සහ Wi-Fi වැනි ජාල ස්ථානීය ප්‍රභව භාවිතයෙන් ඔබගේ නිවැරදි ස්ථානය ලබාගැනීමට යෙදුම අවසර දෙන්න. යෙදුම් වලට ස්ථානීය සේවා භාවිතා කිරීමට  ඒවා සක්‍රිය විය යුතු වේ. ඔබව සොයා ගැනීමට යෙදුම් මෙය භාවිතා කරන අතර අමතර බැටරි බලයක්ද පරිභෝජනය කරයි."</string>
+    <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"ආසන්නතම ස්ථානය (ජාලය-පාදක වූ)"</string>
+    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"ඔබගේ දළ ස්ථානය ලබාගැනීමට යෙදුමට අවසර දෙන්න. සන්නේවේදන කුළුණු සහ Wi-Fi ආදී ජාල ස්ථාන මූලාශ්‍ර භාවිත කරන ස්ථාන සේවා විසින් මෙම ස්ථානය ව්‍යුත්පන්න කර ඇත. යෙදුමට භාවිතය සඳහා මෙම ස්ථාන සේවා සක්‍රිය කළ යුතු අතර ඔබගේ උපාංගය සඳහා පැවතිය යුතුය. ඔබ සිටින තැන දළව හඳුනා ගැනීමට යෙදුම් වලට මෙය භාවිත කළ හැකිය."</string>
+    <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"SurfaceFlinger වෙත ප්‍රවේශය"</string>
+    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"SurfaceFlinger පහල මට්ටමේ විශේෂාංග භාවිතයට යෙදුමට අවසර දෙයි."</string>
+    <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"රාමු අන්තරාචය කියවීම"</string>
+    <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"රාමු අන්තරාචයනයෙන් අන්තර්ගතයන් කියවීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Wifi සංදර්ශක වින්‍යාස කරන්න"</string>
+    <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"වින්‍යාස කිරීමට සහ Wifi සංදර්ශක වෙත සම්බන්ධ වීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wifi සංදර්ශක පාලනය"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Wifi සංදර්ශකයේ පහළ මට්ටමේ විශේෂාංග පාලනයට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"ශබ්ද ප්‍රතිදානය ග්‍රහණය"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"යෙදුමට ශබ්ද ප්‍රතිදානය ග්‍රහණය කර හරවා යැවීමට ඉඩ දේ."</string>
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"වීඩියෝ ප්‍රතිදානය"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"යෙදුමට වීඩියෝ ප්‍රතිදානය ග්‍රහණය කර හරවා යැවීමට ඉඩ දේ."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"ආරක්‍ෂිත වීඩියෝ ප්‍රතිදානය"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"යෙදුමට ආරක්‍ෂිත වීඩියෝ ප්‍රතිදානය ග්‍රහණය කර හරවා යැවීමට ඉඩ දේ."</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="4906839301087980680">"මයික්‍රොෆෝනය මඟින් ශබ්ද පටිගත කිරීමට යෙදුමට අවසර දෙන්න. මෙම අවසරය මඟින් යෙදුමට ඕනෑම වේලාවක ඔබගේ අනුදැනුමකින් තොරව ශබ්ද පටිගත කිරීමට ඉඩ ලබා දේ."</string>
+    <string name="permlab_camera" msgid="3616391919559751192">"පින්තූර සහ වීඩියෝ ගන්න"</string>
+    <string name="permdesc_camera" msgid="8497216524735535009">"කැමරාවෙන් පින්තූර ගැනීමට සහ වීඩියෝ කිරීමට යෙදුමට අවසර දෙන්න. මෙම අවසරය මඟින් ඔබගේ අනුදැනුමකින් තොරව ඕනෑම වේලාවකදී කැමරාව භාවිතා කිරීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"කැමරාව භාවිතයේදී LED දර්ශක සම්ප්‍රේෂණය අබල කරන්න"</string>
+    <string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"කැමරා භාවිතය පිළිබඳ LED දර්ශකය අක්‍රිය කිරීමට, කලින් පිහිටුවා ඇති පද්ධති යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"ටැබ්ලටය ස්ථිරවම අබල කිරීම"</string>
+    <string name="permlab_brick" product="default" msgid="8337817093326370537">"දුරකථනය ස්ථිරව අබල කිරීම"</string>
+    <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"මුළු ටැබ්ලටයම ස්ථිරවම අක්‍රිය කිරීමට යෙදුමට අවසර දෙන්න. මෙය ඉතා භයානකයි."</string>
+    <string name="permdesc_brick" product="default" msgid="5788903297627283099">"මුළු දුරකථනයම ස්ථිරවම අක්‍රිය කිරීමට යෙදුමට අවසර දෙන්න. මෙය ඉතා භයානකයි."</string>
+    <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"ටැබ්ලට් නැවත පණ ගැන්වීමට බල කරන්න"</string>
+    <string name="permlab_reboot" product="default" msgid="2898560872462638242">"දුරකථන නැවත පණ ගැන්වීමට බල කරන්න"</string>
+    <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"ටැබ්ලටය නැවත බල ගැන්වීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"ටැබ්ලටය නැවත ඇරඹීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"USB ආචයනය ගොනු පද්ධතිය ප්‍රවේශ කිරීම"</string>
+    <string name="permlab_mount_unmount_filesystems" product="default" msgid="4402305049890953810">"SD පත් ගොනු පද්ධතිය ප්‍රවේශ කිරීම"</string>
+    <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"ඉවත් කළ හැකි ආචයනය සඳහා ගොනු පද්ධති ඈඳීමට සහ ගැලවීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"USB ආචයනය මකන්න"</string>
+    <string name="permlab_mount_format_filesystems" product="default" msgid="262582698639274056">"SD පත මකන්න"</string>
+    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"ඉවත් කළ හැකි ආචයන ෆෝමැට් කිරීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_asec_access" msgid="3411338632002193846">"අභ්‍යන්තර ආචයනය පිළිබඳ තොරතුරු ලබා ගැනීම"</string>
+    <string name="permdesc_asec_access" msgid="3094563844593878548">"අභ්‍යන්තර ආචයනයේ තොරතුරු ලබාගැනීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_asec_create" msgid="6414757234789336327">"අභ්‍යන්තර ආචයනය නිර්මාණය"</string>
+    <string name="permdesc_asec_create" msgid="4558869273585856876">"අභ්‍යන්තර ආචයනය සැදීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_asec_destroy" msgid="526928328301618022">"අභ්‍යන්තර ආචයනය විනාශ කිරීම"</string>
+    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"අභ්‍යන්තර ආචයනය විනාශ කිරීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"අභ්‍යන්තර ආචයනය නංවීම/ගැලවීම"</string>
+    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"අභ්‍යන්තර ආචයනය සවි කිරීමට/ගැලවීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_asec_rename" msgid="7496633954080472417">"අභ්‍යන්තර ආචයනය නැවත නම් කරන්න"</string>
+    <string name="permdesc_asec_rename" msgid="1794757588472127675">"අභ්‍යන්තර ආචයනය නැවත නම් කිරීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_vibrate" msgid="7696427026057705834">"කම්පනය පාලනය කිරීම"</string>
+    <string name="permdesc_vibrate" msgid="6284989245902300945">"කම්පකය පාලනයට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_flashlight" msgid="2155920810121984215">"සැණෙළි ආලෝකය පාලනය කරන්න"</string>
+    <string name="permdesc_flashlight" msgid="6522284794568368310">"සැණෙළිය පාලනයට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_manageUsb" msgid="1113453430645402723">"USB උපාංග සඳහා කැමැත්ත සහ අවසර කළමනාකරණය කිරීම"</string>
+    <string name="permdesc_manageUsb" msgid="7776155430218239833">"USB උපාංග සඳහා අභිරුචි සහ අවසර කළමනාකරණයට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_accessMtp" msgid="4953468676795917042">"MTP ප්‍රොටොකෝලය ක්‍රියාත්මක කිරීම"</string>
+    <string name="permdesc_accessMtp" msgid="6532961200486791570">"MTP USB ප්‍රොටෝකෝලය ක්‍රියාත්මක කිරීමට කර්නල MTP ධාවකයට ප්‍රවේශ වීමට අවසර දෙන්න."</string>
+    <string name="permlab_hardware_test" msgid="4148290860400659146">"දෘඩාංග පරීක්ෂණය කරන්න"</string>
+    <string name="permdesc_hardware_test" msgid="6597964191208016605">"දෘඩාංග පරීක්ෂා කිරීමේ අරමුණ සඳහා යෙදුමට විවිධ පර්යන්ත පාලනය කිරීමට ඉඩ දෙන්න."</string>
+    <string name="permlab_callPhone" msgid="3925836347681847954">"දුරකථන අංක වෙත ඍජුවම අමතන්න"</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"ඔබගේ මැදිහත් වීමක් නොමැතිව දුරකථන අංක ඇමතීමට යෙදුමට අවසර දෙන්න. මෙහි ප්‍රතිඑලය වන්නේ අනපේක්ෂිත අයකිරීම් හෝ ඇමතුම් ඇතිවීමයි. මෙයන් හදිසි අංක වලට ඇමතුම් ගැනීමට යෙදුමට අවසර නොදෙන බවට සටහන් කරගන්න. ඔබගේ අනුදැනුමක් නොමැතිව ඇමතුම් ගැනීමෙන් අනිෂ්ට යෙදුම් ඔබගේ මුදල් නිකරුණේ වැය කරයි."</string>
+    <string name="permlab_callPrivileged" msgid="4198349211108497879">"ඕනෑම දුරකථන අංකයකට ඍජුවම අමතන්න"</string>
+    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"ඔබගේ මැදිහත්වීමකින් තොරව හදිසි අංක ඇතුළත්ව ඕනෑම දුරකථන අංකයකට ඇමතීමට යෙදුමට අවසර දෙන්න. හදිසි සේවා වෙත අනවශ්‍ය සහ නීතිමය නොවන ඇමතුම ලැබීමට අනිෂ්ට යෙදුම සිදු කළ හැක."</string>
+    <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"CDMA ටැබ්ලට පිහිටුම සෘජුව ඇරඹීම"</string>
+    <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"CDMA දුරකථන පිහිටුම සෘජුව ඇරඹීම"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"යෙදුමට CDMA ප්‍රතිපාදන ආරම්භ කිරීමට ඉඩදෙන්න. අනිෂ්ට යෙදුම් අනවශ්‍ය ලෙස CDMA ප්‍රතිපාදන ආරම්භ කළ හැක."</string>
+    <string name="permlab_locationUpdates" msgid="7785408253364335740">"ස්ථාන යාවත්කාලීන දැනුම්දීම් පාලනය කරන්න"</string>
+    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"ස්ථානීය යාවත්කාලින දැනුම්දීම් රේඩියෝවෙන් සබල/අබල කිරීමට යෙදුමට අවසර දෙන්න. සාමාන්‍ය යෙදුම්වල භාවිතය සඳහා නොවේ."</string>
+    <string name="permlab_checkinProperties" msgid="7855259461268734914">"පිරික්සුම් ගුණාංග වෙත ප්‍රවේශය"</string>
+    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"පිරික්සුම් සේවාව මගින් උත්ශ්‍රේණි කළ ගුණාංග වෙත කියවීම්/ලිවීම් පිවිසුම සඳහා යෙදුමට අවසර දෙන්න. සාමාන්‍ය යෙදුම් වල භාවිතයට නොවේ."</string>
+    <string name="permlab_bindGadget" msgid="776905339015863471">"විජට් තෝරන්න"</string>
+    <string name="permdesc_bindGadget" msgid="8261326938599049290">"කුමන විජටය කුමන යෙදුමෙන් භාවිතා කල හැකිද යන්න පද්ධතියට පැවසීමට යෙදුමට අවසර දෙන්න. මෙම අවසරය ඇති යෙදුමකට අනෙක් යෙදුම්වලට පුද්ගලික දත්ත වලට ප්‍රවේශය ලබා දිය හැක. සාමාන්‍ය යෙදුම් වල භාවිතයට නොවේ."</string>
+    <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"දුරකථනයේ තත්වය වෙනස් කිරීම"</string>
+    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"උපාංගයේ දුරකථන විශේෂාංග පාලනයට යෙදුමට අවසර දෙන්න. මෙම අවසරය ඇති යෙදුමට ඔබට නිවේදනයෙන් තොරව ජාල මාරු කිරීම, දුරකථන රේඩියෝව සක්‍රිය සහ අක්‍රිය කිරීම කළ හැක."</string>
+    <string name="permlab_readPhoneState" msgid="9178228524507610486">"දුරකථනයේ තත්වය සහ අනන්‍යතාවය කියවීම"</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"උපාංගයේ දුරකථන විශේෂාංග වෙත පිවිසීමට යෙදුමට අවසර දෙන්න. ඇමතුම සක්‍රිය වුවත් සහ ඇමතුමකින් දුරස්ථ අංකය සම්බන්ධ වුවත් දුරකථන අංකය සහ උපාංග ID හඳුනා ගැනීමට මෙම අවසරය යෙදුමට අවසර දෙයි."</string>
+    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"ටැබ්ලටය නින්දෙන් වැළක්වීම"</string>
+    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"දුරකථනය නින්දට යාමෙන් වළකන්න"</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"ටැබ්ලටය නින්දට යාමෙන් වැලැක්වීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"දුරකථනය නින්දට යාමෙන් වැලැක්වීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"ටැබ්ලටය සක්‍රිය හෝ අක්‍රිය කරන්න"</string>
+    <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"දුරකථනය බල ගැන්වීම හෝ වැසීම"</string>
+    <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"ටැබ්ලටය සක්‍රිය හෝ අක්‍රිය කිරීමට යෙදුමට අවසර දේ."</string>
+    <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"දුරකථනය සක්‍රිය සහ අක්‍රිය කිරීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_factoryTest" msgid="3715225492696416187">"කර්මාන්තශාලා පරීක්ෂණ ආකාරය තුළ ධාවනය කරන්න"</string>
+    <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"ටැබ්ලටයේ දෘඩාංග වෙත සම්පූර්ණ පිවිසුම සඳහා අවසර දීමෙන් පහළ මට්ටමේ නිපැවුම්කරු පරීක්ෂණයක් ලෙස ධාවනය කරන්න. නිපැවුම්කරු පරීක්ෂණ ආකාරයෙන් ටැබ්ලටයේ ධාවනය වන විට පමණි."</string>
+    <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"දුරකථනයේ දෘඩාංග වෙත සම්පූර්ණ පිවිසුම සඳහා අවසර දීමෙන් පහළ මට්ටමේ නිපැවුම්කරු පරීක්ෂණයක් ලෙස ධාවනය කරන්න. නිපැවුම්කරු පරීක්ෂණ ආකාරයෙන් දුරකථනයේ ධාවනය වන විට පමණි."</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_masterClear" msgid="2315750423139697397">"කර්මාන්තශාලා සුපුරුද්දට පද්ධතිය නැවත සකස් කිරීම"</string>
+    <string name="permdesc_masterClear" msgid="3665380492633910226">"සියලු දත්ත මැකීමෙන්, වින්‍යාස කිරීමෙන් සහ යෙදුම් ස්ථාපනයෙන් එහි කර්මාන්ත ශාලා සැකසීම් වෙත පද්ධතිය නැවත සැකසීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_setTime" msgid="2021614829591775646">"වේලාව සැකසීම"</string>
+    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"ටැබ්ලට ඔරලෝසුවේ වේලාව වෙනස් කිරීමට යෙදුමට ඉඩ දෙන්න."</string>
+    <string name="permdesc_setTime" product="default" msgid="1855702730738020">"දුරකථන ඔරලෝසුවේ වේලාව වෙනස් කිරීමට යෙදුමකට ඉඩ දෙන්න."</string>
+    <string name="permlab_setTimeZone" msgid="2945079801013077340">"වේලා කලාපය සැකසීම"</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"ටැබ්ලටයේ කාල කලාපය වෙනස් කිරීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"දුරකථනයේ වේලා කලාපය වෙනස් කිරීමට උපාංගයට අවසර දෙන්න."</string>
+    <string name="permlab_accountManagerService" msgid="4829262349691386986">"AccountManagerService ලෙස පෙනී සිටින්න"</string>
+    <string name="permdesc_accountManagerService" msgid="1948455552333615954">"AccountAuthenticators වෙත ඇමතුම් ගැනීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_getAccounts" msgid="1086795467760122114">"උපාංගයේ ඇති ගිණුම් සොයන්න"</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"ටැබ්ලටය විසින් දන්නා ගිණුම් ලැයිස්තුවක් ලබාගැනීමට යෙදුමට අවසර දෙන්න. ඔබ ස්ථාපනය කොට ඇති යෙදුම් විසින් සාදා ඇති ගිණුම් මීට ඇතුළත් වේ."</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"දුරකථනය විසින් දන්නා ගිණුම් ලැයිස්තුවක් ලබාගැනීමට යෙදුමට අවසර දෙන්න. ඔබ ස්ථාපනය කොට ඇති යෙදුම් විසින් සාදා ඇති ගිණුම් මීට ඇතුළත් වේ."</string>
+    <string name="permlab_authenticateAccounts" msgid="5265908481172736933">"ගිණුම් සාදන්න සහ මුරපද සකසන්න"</string>
+    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"ගිණුම් සැදීමට සහ රහස් පද ලබාගැනීම සහ සැකසීම් කිරීම ඇතුළත්ව AccountManager ගේ ගිණුම් සත්‍යාපන හැකියාවන් භාවිතා කිරීමට යෙදුමකට අවසර දෙන්න."</string>
+    <string name="permlab_manageAccounts" msgid="4983126304757177305">"ගිණුම් එකතු කරන්න හෝ ඉවත් කරන්න"</string>
+    <string name="permdesc_manageAccounts" msgid="8698295625488292506">"ගිණුම් එකතු කිරීම, සහ ඉවත් කිරීම සහ ඔවුන්ගේ මුරපද මැකීම ආදී ක්‍රියාවලි සිදු කිරීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_useCredentials" msgid="235481396163877642">"උපාංගයේ ඇති ගිණුම් භාවිතා කිරීම"</string>
+    <string name="permdesc_useCredentials" msgid="7984227147403346422">"සත්‍යාපන ටෝකන ඉල්ලීම සඳහා යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_accessNetworkState" msgid="4951027964348974773">"ජාල සම්බන්ධතාවයන් බැලීම"</string>
+    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"කුමන ජාල පවතින්නේ ද සහ සම්බන්ධිත ද ආදී ජාල සබඳතා ගැන තොරතුරු බැලීමට යෙදුමට අවසර දෙයි."</string>
+    <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"සම්පූර්ණ ජාල ප්‍රවේශය"</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"උපකරණයට ජාල කෙවනියන් සැදීමට සහ ජාල ප්‍රොටෝකෝල අභිරුචි භාවිතා කිරීමට උපකරණයට ඉඩ දෙන්න. අන්තර්ජාලයට දත්ත යැවීමට විධියන් බ්‍රව්සරය සහ අනෙකුත් යෙදුම් සපයයි, එනිසා මෙම අවසරය දත්ත අන්තර්ජාලයට යැවීමට අවශ්‍ය නොවේ."</string>
+    <string name="permlab_writeApnSettings" msgid="505660159675751896">"ජාලයේ සැකසීම් සහ ගමනාගමන වෙනස් කරන්න/අල්ලා ගැනීම"</string>
+    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"ඕනෑම APN එකක නියුතුව සහ තොට වෙනස් කිරීම වැනි ජාල සැකසීම් වෙනස් කිරීමට සහ සියලුම ජාල අතුරු ඇරීමට සහ සෝදිසි කිරීමට යෙදුමට අවසර දෙන්න. ඇතැම්විට ඔබගේ අනුදැනුමකින් තොරව අනිෂ්ට උපාංග ජාල පැකැට්ටු අධීක්ෂණය,ආපසු දිශාගත කිරීම හෝ වෙනස්කිරීම සිදු කිරීමට ඉඩ තිබේ."</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_changeBackgroundDataSetting" msgid="1400666012671648741">"පසුබිම් දත්ත භාවිත සැකසීම් වෙනස් කිරීම"</string>
+    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"පසුබිම් දත්ත භාවිතා සැකසීම වෙනස් කිරීමට යෙදුමට අවසර දෙන්න."</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 ජාලයේ ඇති සියලුම උපාංගවලට යැවූ පැකැට්ටු බහු විකාශ ලිපින භාවිතයෙන් ලබාගැනීමට යෙදුමට අවසර දෙන්න. non-multicast ආකාරයට වඩා වැඩි බලයක් මෙහිදී භාවිතා වේ."</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="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="2405042267131496579">"WiMAX තත්වය වෙනස් කරන්න"</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"ටැබ්ලටය 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="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_readSyncSettings" msgid="6201810008230503052">"සමමුහුර්ත සැකසීම් කියවන්න"</string>
+    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"ගිණුම සඳහා සමමුහුර්ත සැකසීම් කියවීමට යෙදුමට අවසර දෙන්න. උදාහරණයක් ලෙස, ගිණුමක් සමඟ පුද්ගල යෙදුම සමමුහුර්ත දැයි මෙයට හඳුනා ගත හැක."</string>
+    <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"සමමුහුර්ත කිරීම සක්‍රිය කරන්න සහ අක්‍රිය කරන්න"</string>
+    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"ගිණුම සඳහා සමමුහුර්ත සැකසීම් වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. උදාහරණයක් ලෙස, ගිණුම සමඟ පුද්ගල යෙදුම සමමුහුර්ත කිරීම සක්‍රිය කිරීමට භාවිත කල හැක."</string>
+    <string name="permlab_readSyncStats" msgid="7396577451360202448">"සමමුහුර්ත කිරීමේ සංඛ්‍යාන කියවීම"</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"සමමුහුර්ත කිරීමේ සිදුවීම් ඉතිහාසය සහ කෙතරම් දත්ත සමමුහුර්ත වී ඇතිදැයි ඇතුලත් ගිණුම සඳහා සමමුහුර්ත කිරීමේ සංඛ්‍යාන කියවීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"දායක වූ සංග්‍රහ කියවීම"</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"වර්තමාන සමමුහුර්ත සංග්‍රහ ගැන විස්තර ලැබීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"දායක වූ සංග්‍රහ ලිවීම"</string>
+    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"ඔබගේ වර්තමාන සමමුහුර්ත සංග්‍රහ වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. ඔබගේ සමමුහුර්ත සංග්‍රහ අනිෂ්ට යෙදුම්වලින් වෙනස් කල හැක."</string>
+    <string name="permlab_readDictionary" msgid="4107101525746035718">"ඔබ විසින් ශබ්දකෝෂයට ඇතුළත්කොට ඇති කොන්දේසි කියවීම"</string>
+    <string name="permdesc_readDictionary" msgid="659614600338904243">"පරිශීලක ශබ්ද කෝෂයේ පරිශීලකයන් විසින් ගබඩා කර තිබිය හැකි වචන, නම්, වාක්‍යංශ කියවීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_writeDictionary" msgid="2183110402314441106">"පරිශීලකයින් අර්ථ දැක්වූ ශබ්ද කෝෂයට වචන එකතු කිරීම"</string>
+    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"පරිශීලක ශබ්දකෝෂය තුළට අලුත් වචන ලිවීමට යෙදුමට ඉඩ දෙන්න."</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"ආරක්‍ෂිත ආචයනය වෙත ප්‍රවේශය පරීක්ෂා කිරීම"</string>
+    <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"ආරක්‍ෂිත ආචයනය වෙත ප්‍රවේශය පරීක්ෂා කිරීම"</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"අනාගත උපාංගවල ලබාගත හැකි USB ආචයනය සඳහා අවසරයක් පරීක්ෂා කිරීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"අනාගත උපාංගවල පැවතෙන 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_mediaStorageWrite" product="default" msgid="6859839199706879015">"අභ්‍යන්තර මාධ්‍ය ආචයනය අන්තර්ගත වෙනස් කරන්න/ මකන්න"</string>
+    <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"අභ්‍යන්තර මාධ්‍ය ආචයනයේ අන්තර්ගතය වෙනස් කිරීමට උපාංගයට අවසර දෙන්න."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"ලේඛන ආචයනය කළමනාකරණය කරන්න"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"ලේඛන ආචයනය කළමනාකරණය කිරීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"සියලුම පරිශීලකයන්ගේ බාහිර ආචයන වෙත පිවිසෙන්න"</string>
+    <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"සියලු පරිශීලකයන් සඳහා බාහිර ආචයනය වෙත පිවිසීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_cache_filesystem" msgid="5656487264819669824">"හැඹිලි ගොනු පද්ධතියට ප්‍රවේශ වීම"</string>
+    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"හැඹිලි ගොනු පද්ධති කියවීමට සහ ලිවීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_use_sip" msgid="5986952362795870502">"අන්තර්ජාල ඇමතුම් ගන්න/ලබන්න"</string>
+    <string name="permdesc_use_sip" msgid="4717632000062674294">"අන්තර්ජාල ඇමතුම් ගැනීමට/ලැබීමට SIP සේවාව භාවිතයට යෙදුමට අවසර දෙන්න."</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_markNetworkSocket" msgid="3658527214914959749">"කෙවෙනි ලකුණු වෙනස් කරන්න"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"මාර්ගගත වීම සඳහා කෙවෙනියේ ලකුණු වෙනස් කිරීමට යෙදුමට ඉඩ දෙන්න"</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_invokeCarrierSetup" msgid="3699600833975117478">"වාහකය සැපයු වින්‍යාසය යෙදුම ඉල්ලා සිටින්න"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"වාහකයා ලබාදුන් සැකසුම් යෙදුම් උත්පාදනයට ධාරකයාට අවසර දෙන්න. සාමාන්‍ය යෙදුම් සඳහා කිසිදා අවශ්‍ය නොවෙයි."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"ජාල තත්ව මත නිරීක්ෂණ වෙත ඇහුම්කන් දීම"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"යෙදුමකට ජාල තත්ව මත නිරීක්ෂණ වෙත ඇහුම්කන් දීමට අවසර දේ. සාමාන්‍ය යෙදුම් සඳහා කිසිදා අවශ්‍ය නොවේ."</string>
+    <string name="permlab_hotwordRecognition" msgid="3225080408746361313">"අණවදන හඳුනාගැනීම ඉල්ලයි"</string>
+    <string name="permdesc_hotwordRecognition" msgid="3716741260195364252">"අණවදන හඳුනාගැනීම සඳහා ඉල්ලීමට යෙදුමට ඉඩ දෙන්න. සාමාන්‍ය යෙදුම් සඳහා කිසිදා අවශ්‍ය නොවෙයි."</string>
+    <string name="policylab_limitPassword" msgid="4497420728857585791">"මුරපද නීති සකස් කිරීම"</string>
+    <string name="policydesc_limitPassword" msgid="3252114203919510394">"තිරය අගුළු ඇරීමේ මුරපදයට අනුමත අකුරු සහ දිග පාලනය කරන්න."</string>
+    <string name="policylab_watchLogin" msgid="914130646942199503">"තිරය අගුළු ඇරීමේ උත්සාහයන් නිරීක්ෂණය කරන්න"</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"තිරය අගුළු හැරීමේදී වැරදියට ටයිප් කළ මුරපද ගණන නිරීක්ෂණය කරන්න සහ ටැබ්ලටය අගුළු දමන්න හෝ වැරදි මුරපද බොහෝ ගණනක් ටයිප් කර ඇති නම් ටැබ්ලටයේ සියලු දත්ත මකන්න."</string>
+    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"තිරය අගුළු හැරීමේදී වැරදියට ටයිප් කළ මුරපද ගණන නිරීක්ෂණය කරන්න සහ දුරකථනය අගුළු දමන්න හෝ වැරදි මුරපද බොහෝ ගණනක් ටයිප් කර ඇති නම් දුරකථනයේ සියලු දත්ත මකන්න."</string>
+    <string name="policylab_resetPassword" msgid="2620077191242688955">"තිරය අගුළු ඇරීමේ මුරපදය වෙනස් කිරීම"</string>
+    <string name="policydesc_resetPassword" msgid="605963962301904458">"තිරය අගුළු ඇරීමේ මුරපදය වෙනස් කරන්න."</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="default" msgid="5096895604574188391">"කර්මාන්ත ශාලා දත්ත යළි පිහිටුවීමෙන් පසුව අනතුරු ඇඟවිමකින් තොරවම දුරකථන දත්ත මකා දමයි."</string>
+    <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"උපාංග ගෝලීය නියුතුව සකස් කිරීම"</string>
+    <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"කොන්දේසි සක්‍රිය විට පොදු නියුතු එකක් භාවිත කරන ලෙස උපාංගය සකසන්න. පළමු උපාංග පරිපාලකයා පමණක් ඵලදායි පොදු නියුතුව සකසයි."</string>
+    <string name="policylab_expirePassword" msgid="885279151847254056">"තිරය අගුළු දැමීමේ මුරපදය කල් ඉකුත්වීම සකසන්න"</string>
+    <string name="policydesc_expirePassword" msgid="1729725226314691591">"තිර-අගුළේ මුරපදය වෙනස්වීම කොපමණ කාල පරාසයකින් සිදුවිය යුතුද යන්න පාලනය කිරීම."</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="policylab_disableKeyguardFeatures" msgid="266329104542638802">"යතුරු ආරක්ෂාවේ විශේෂාංග අබල කරන්න"</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="3467082272186534614">"යතුරු ආරක්ෂාව හි සමහර විශේෂාංග භාවිතය වළක්වයි."</string>
+  <string-array name="phoneTypes">
+    <item msgid="8901098336658710359">"නිවස"</item>
+    <item msgid="869923650527136615">"ජංගම"</item>
+    <item msgid="7897544654242874543">"කාර්යාලය"</item>
+    <item msgid="1103601433382158155">"කාර්යාල ෆැක්ස්"</item>
+    <item msgid="1735177144948329370">"නිවසේ ෆැක්ස්"</item>
+    <item msgid="603878674477207394">"පේජරය"</item>
+    <item msgid="1650824275177931637">"වෙනත්"</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>
+  </string-array>
+  <string-array name="postalAddressTypes">
+    <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="1359644565647383708">"කාර්යාලය"</item>
+    <item msgid="7868549401053615677">"වෙනත්"</item>
+    <item msgid="3145118944639869809">"අභිරුචි"</item>
+  </string-array>
+  <string-array name="organizationTypes">
+    <item msgid="7546335612189115615">"කාර්යාලය"</item>
+    <item msgid="4378074129049520373">"වෙනත්"</item>
+    <item msgid="3455047468583965104">"අභිරුචි"</item>
+  </string-array>
+  <string-array name="imProtocols">
+    <item msgid="8595261363518459565">"AIM"</item>
+    <item msgid="7390473628275490700">"Windows Live"</item>
+    <item msgid="7882877134931458217">"Yahoo"</item>
+    <item msgid="5035376313200585242">"Skype"</item>
+    <item msgid="7532363178459444943">"QQ"</item>
+    <item msgid="3713441034299660749">"Google Talk"</item>
+    <item msgid="2506857312718630823">"ICQ"</item>
+    <item msgid="1648797903785279353">"Jabber"</item>
+  </string-array>
+    <string name="phoneTypeCustom" msgid="1644738059053355820">"අභිරුචි"</string>
+    <string name="phoneTypeHome" msgid="2570923463033985887">"නිවස"</string>
+    <string name="phoneTypeMobile" msgid="6501463557754751037">"ජංගම"</string>
+    <string name="phoneTypeWork" msgid="8863939667059911633">"කාර්යාලය"</string>
+    <string name="phoneTypeFaxWork" msgid="3517792160008890912">"කාර්යාල ෆැක්ස්"</string>
+    <string name="phoneTypeFaxHome" msgid="2067265972322971467">"නිවසේ ෆැක්ස්"</string>
+    <string name="phoneTypePager" msgid="7582359955394921732">"පේජරය"</string>
+    <string name="phoneTypeOther" msgid="1544425847868765990">"වෙනත්"</string>
+    <string name="phoneTypeCallback" msgid="2712175203065678206">"යළි ඇමතීම"</string>
+    <string name="phoneTypeCar" msgid="8738360689616716982">"මෝටර් රථය"</string>
+    <string name="phoneTypeCompanyMain" msgid="540434356461478916">"ආයතනයේ මූලිකය"</string>
+    <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string>
+    <string name="phoneTypeMain" msgid="6766137010628326916">"මූලික"</string>
+    <string name="phoneTypeOtherFax" msgid="8587657145072446565">"වෙනත් ෆැක්ස්"</string>
+    <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="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="eventTypeBirthday" msgid="2813379844211390740">"උපන්දිනය"</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>
+    <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="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="imTypeWork" msgid="1371489290242433090">"කාර්යාලය"</string>
+    <string name="imTypeOther" msgid="5377007495735915478">"වෙනත්"</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>
+    <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
+    <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</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>
+    <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="relationTypeAssistant" msgid="6274334825195379076">"සහායක"</string>
+    <string name="relationTypeBrother" msgid="8757913506784067713">"සහෝදරයා"</string>
+    <string name="relationTypeChild" msgid="1890746277276881626">"දරුවා"</string>
+    <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"දේශීය හවුල්කරුවා"</string>
+    <string name="relationTypeFather" msgid="5228034687082050725">"පියා"</string>
+    <string name="relationTypeFriend" msgid="7313106762483391262">"මිත්‍රයා"</string>
+    <string name="relationTypeManager" msgid="6365677861610137895">"කළමනාකරු"</string>
+    <string name="relationTypeMother" msgid="4578571352962758304">"මව"</string>
+    <string name="relationTypeParent" msgid="4755635567562925226">"මව්පිය"</string>
+    <string name="relationTypePartner" msgid="7266490285120262781">"හවුල්කරුවා"</string>
+    <string name="relationTypeReferredBy" msgid="101573059844135524">"යොමුකරන ලද්දේ"</string>
+    <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="sipAddressTypeHome" msgid="6093598181069359295">"නිවස"</string>
+    <string name="sipAddressTypeWork" msgid="6920725730797099047">"කාර්යාලය"</string>
+    <string name="sipAddressTypeOther" msgid="4408436162950119849">"වෙනත්"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN කේතය ටයිප් කරන්න"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK සහ නව PIN කේතය ටයිප් කරන්න"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK කේතය"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"නව PIN කේතය"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><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">"අගුළු හැරීමට PIN එක ටයිප් කරන්න"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"වැරදි PIN කේතයකි."</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="8963839242565653192">"සේවාව නැත."</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="5347633784401285225">"හදිසි ඇමතුම්"</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="faceunlock_multiple_failures" msgid="754137583022792429">"මුහුණ භාවිතයෙන් අඟුළු හැරීමේ උපරිම ප්‍රයන්තයන් ගණන ඉක්මවා ඇත"</string>
+    <string name="lockscreen_plugged_in" msgid="8057762828355572315">"ආරෝපණය වෙමින්, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_charged" msgid="321635745684060624">"අරෝපිතයි"</string>
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_low_battery" msgid="1482873981919249740">"ඔබගේ ආරෝපකයට සම්බන්ධ කරන්න."</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="default" msgid="2186920585695169078">"දුරකථනය තුළ SIM පත නැත."</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_transport_prev_description" msgid="201594905152746886">"පෙර ගීත බොත්තම"</string>
+    <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"ඊළඟ ගීත බොත්තම"</string>
+    <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"විරාම බොත්තම"</string>
+    <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"ධාවක බොත්තම"</string>
+    <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"නැවතීමේ බොත්තම"</string>
+    <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">"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">%d</xliff:g> වාරයක් අගුළු ඇරීමේ රටාව වැරදියට ඇඳ ඇත. \n\nතත්පර <xliff:g id="NUMBER_1">%d</xliff:g> ක් ඇතුළත නැවත උත්සාහ කරන්න."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"ඔබ මුරපදය වාර <xliff:g id="NUMBER_0">%d</xliff:g> ක් වැරදියට ටයිප්කොට ඇත. \n\nතත්පර <xliff:g id="NUMBER_1">%d</xliff:g> කින් නැවත උත්සහ කරන්න."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"ඔබ PIN අංකය <xliff:g id="NUMBER_0">%d</xliff:g> වාරයක් වැරදියට ටයිප් කොට ඇත.\n\n තත්පර <xliff:g id="NUMBER_1">%d</xliff:g> ක් ඇතුළත නැවත උත්සාහ කරන්න."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"ඔබ වැරදියට <xliff:g id="NUMBER_0">%d</xliff:g> වතාවක් ඔබගේ අගුළු හැරීමේ රටාව ඇඳ ඇත. අසාර්ථක උත්සහ කිරීම් <xliff:g id="NUMBER_1">%d</xliff:g> න් පසුව, ඔබගේ Google පුරනය වීම් භාවිතයෙන් ඔබගේ ටැබ්ලටය අගුළු හැරීමට ඔබගෙන් අසයි.\n\n තත්පර <xliff:g id="NUMBER_2">%d</xliff:g> පසුව නැවත උත්සහ කරන්න."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"ඔබ වැරදියට <xliff:g id="NUMBER_0">%d</xliff:g> වතාවක් ඔබගේ අගුළු හැරීමේ රටාව ඇඳ ඇත. අසාර්ථක උත්සහ කිරීම් <xliff:g id="NUMBER_1">%d</xliff:g> න් පසුව, ඔබගේ Google පුරනය වීම භාවිතයෙන් ඔබගේ දුරකථනය අගුළු හැරීමට ඔබගෙන් අසනු ඇත.\n\n තත්පර <xliff:g id="NUMBER_2">%d</xliff:g> පසුව නැවත උත්සහ කරන්න."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"ඔබ ටැබ්ලටය අගුළු හැරීමට වැරදියට අවස්ථා <xliff:g id="NUMBER_0">%d</xliff:g> ක් උත්සාහ කර ඇත. අවස්ථා <xliff:g id="NUMBER_1">%d</xliff:g> ක් අසාර්ථකව උත්සහ කිරීමකින් පසුව, ටැබ්ලටය කර්මාන්ත ශාලා මුල් තත්වයට නැවත පත් වන අතර සියලු පරිශීලක දත්ත නැති වෙයි."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"ඔබ දුරකථනය අගුළු ඇරීමට වාර <xliff:g id="NUMBER_0">%d</xliff:g> කදී වැරදී ප්‍රයත්නයන් ගෙන තිබේ. තවත් අසාර්ථක ප්‍රයත්න <xliff:g id="NUMBER_1">%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="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_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_checking_password" msgid="7114627351286933867">"පරික්ෂා කරමින්..."</string>
+    <string name="lockscreen_unlock_label" msgid="737440483220667054">"අඟුල අරින්න"</string>
+    <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"ශබ්දය සක්‍රීය කරන්න"</string>
+    <string name="lockscreen_sound_off_label" msgid="996822825154319026">"ශ්‍රව්‍ය අක්‍රිය කරන්න"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"රටාව අරඹන ලදි"</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"රටාව හිස් කරන ලදි"</string>
+    <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"කොටුවක් එකතු කරන ලදි"</string>
+    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"රටාව සම්පූර්ණයි"</string>
+    <!-- String.format failed for translation -->
+    <!-- no translation found for keyguard_accessibility_widget_changed (5678624624681400191) -->
+    <skip />
+    <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_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>
+    <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_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">"PIN අගුළු ඇරීම."</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>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <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_line" msgid="5764267235026120888">"රේඛාව"</string>
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
+    <string name="factorytest_failed" msgid="5410270329114212041">"කර්මාන්ත ශාලා පරීක්ෂණය අසාර්ථකයි"</string>
+    <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST ක්‍රියාව /system/app හි ස්ථාපිත පැකේජ සඳහා පමණක් සහය දක්වයි."</string>
+    <string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST ක්‍රියාව ලබාදෙන පැකේජයක් සොයාගත නොහැකි විය."</string>
+    <string name="factorytest_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>
+    <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="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>
+    <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
+    <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
+    <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
+    <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">"ZIP කේතය"</string>
+    <string name="autofill_county" msgid="237073771020362891">"ප්‍රාන්තය"</string>
+    <string name="autofill_island" msgid="4020100875984667025">"දූපත"</string>
+    <string name="autofill_district" msgid="8400735073392267672">"දිස්ත්‍රික්කය"</string>
+    <string name="autofill_department" msgid="5343279462564453309">"දෙපාර්තමේන්තුව"</string>
+    <string name="autofill_prefecture" msgid="2028499485065800419">"ප්‍රාන්තය"</string>
+    <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="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_packageVerificationAgent" msgid="5568139100645829117">"පැකේජ සත්‍යාපනය කරන්න"</string>
+    <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"ස්ථාපිත කොට ඇති පැකේජයක් සත්‍යාපනයට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"පැකේජ සත්‍යාපකයක් වෙත බඳින්න"</string>
+    <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"පැකේජ සත්‍යාපක ඉල්ලීම් වලට දරන්නාට ඉඩ ලබා දේ. සාමාන්‍ය යෙදුම් සඳහා කිසිසේත් අවශ්‍ය නොවේ."</string>
+    <string name="permlab_serialPort" msgid="546083327654631076">"ශ්‍රේණිගත පොට ප්‍රවේශ කිරීම"</string>
+    <string name="permdesc_serialPort" msgid="2991639985224598193">"SerialManager API භාවිතයෙන් අනුක්‍රම තොට වෙත ප්‍රවේශ වීමට රඳවනයට අවසර දෙන්න."</string>
+    <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"බාහිර අන්තර්ගත සැපයුම්කරුවන් වෙත ප්‍රවේශය"</string>
+    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"අන්තර්ගත සපයන්නන්ට ප්‍රවේශ වීමට දරන්නන්ට ෂෙල් එකේ සිට ප්‍රවේශ වීමට අවසර දෙන්න. සාමාන්‍ය යෙදුම් සඳහා කිසිසේත් අදාළ නොවේ."</string>
+    <string name="permlab_updateLock" msgid="3527558366616680889">"ස්වයංක්‍රීය උපාංග යවත්කාල කිරීම් පසුබට කරන්න"</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"උපාංගය උත්ශ්‍රේණිකරණයට අන්තර්ක්‍රියාකාරී නොවන යළි ඇරඹීමක් සඳහා සුදුසු වෙලාව කුමක්ද යන්න ගැන පද්ධතියට තොරතුරු ලබාදීමට දරන්නාට අවසර දෙන්න."</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>
+    <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="menu_space_shortcut_label" msgid="2410328639272162537">"space"</string>
+    <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"ඇතුල් කරන්න"</string>
+    <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"මකන්න"</string>
+    <string name="search_go" msgid="8298016669822141719">"සෙවීම"</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="oneMonthDurationPast" msgid="7396384508953779925">"මාස 1 කට පෙර"</string>
+    <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"මාස 1 කට පෙර"</string>
+  <plurals name="num_seconds_ago">
+    <item quantity="one" msgid="4869870056547896011">"තත්පර 1 කට පෙර"</item>
+    <item quantity="other" msgid="3903706804349556379">"තත්පර <xliff:g id="COUNT">%d</xliff:g> ට පෙර"</item>
+  </plurals>
+  <plurals name="num_minutes_ago">
+    <item quantity="one" msgid="3306787433088810191">"මිනිත්තු 1 ට පෙර"</item>
+    <item quantity="other" msgid="2176942008915455116">"මිනිත්තු <xliff:g id="COUNT">%d</xliff:g> කට පෙර"</item>
+  </plurals>
+  <plurals name="num_hours_ago">
+    <item quantity="one" msgid="9150797944610821849">"පැය 1 කට පෙර"</item>
+    <item quantity="other" msgid="2467273239587587569">"පැය <xliff:g id="COUNT">%d</xliff:g> කට පෙර"</item>
+  </plurals>
+  <plurals name="last_num_days">
+    <item quantity="other" msgid="3069992808164318268">"අන්තිම දවස් <xliff:g id="COUNT">%d</xliff:g>"</item>
+  </plurals>
+    <string name="last_month" msgid="3959346739979055432">"අවසාන මාසය"</string>
+    <string name="older" msgid="5211975022815554840">"පරණ"</string>
+  <plurals name="num_days_ago">
+    <item quantity="one" msgid="861358534398115820">"ඊයේ"</item>
+    <item quantity="other" msgid="2479586466153314633">"දින <xliff:g id="COUNT">%d</xliff:g> කට පෙර"</item>
+  </plurals>
+  <plurals name="in_num_seconds">
+    <item quantity="one" msgid="2729745560954905102">"තත්පර 1 කින්"</item>
+    <item quantity="other" msgid="1241926116443974687">"තත්පර <xliff:g id="COUNT">%d</xliff:g> කදී"</item>
+  </plurals>
+  <plurals name="in_num_minutes">
+    <item quantity="one" msgid="8793095251325200395">"මිනිත්තු 1 කදී"</item>
+    <item quantity="other" msgid="3330713936399448749">"මිනිත්තු <xliff:g id="COUNT">%d</xliff:g> ක් තුළ"</item>
+  </plurals>
+  <plurals name="in_num_hours">
+    <item quantity="one" msgid="7164353342477769999">"පැය 1 ක් තුළ"</item>
+    <item quantity="other" msgid="547290677353727389">"පැය <xliff:g id="COUNT">%d</xliff:g> ක් තුළ"</item>
+  </plurals>
+  <plurals name="in_num_days">
+    <item quantity="one" msgid="5413088743009839518">"හෙට"</item>
+    <item quantity="other" msgid="5109449375100953247">"දින <xliff:g id="COUNT">%d</xliff:g> ක් තුළ"</item>
+  </plurals>
+  <plurals name="abbrev_num_seconds_ago">
+    <item quantity="one" msgid="1849036840200069118">"තත්පර 1 කට පෙර"</item>
+    <item quantity="other" msgid="3699169366650930415">"තත්පර <xliff:g id="COUNT">%d</xliff:g> කට පෙර"</item>
+  </plurals>
+  <plurals name="abbrev_num_minutes_ago">
+    <item quantity="one" msgid="6361490147113871545">"මිනිත්තු 1 කට පෙර"</item>
+    <item quantity="other" msgid="851164968597150710">"මිනිත්තු <xliff:g id="COUNT">%d</xliff:g> ට පෙර"</item>
+  </plurals>
+  <plurals name="abbrev_num_hours_ago">
+    <item quantity="one" msgid="4796212039724722116">"පැය 1 කට පෙර"</item>
+    <item quantity="other" msgid="6889970745748538901">"පැය <xliff:g id="COUNT">%d</xliff:g> ට පෙර"</item>
+  </plurals>
+  <plurals name="abbrev_num_days_ago">
+    <item quantity="one" msgid="8463161711492680309">"ඊයේ"</item>
+    <item quantity="other" msgid="3453342639616481191">"දින <xliff:g id="COUNT">%d</xliff:g> ට පෙර"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_seconds">
+    <item quantity="one" msgid="5842225370795066299">"තත්පර 1 ක් තුළ"</item>
+    <item quantity="other" msgid="5495880108825805108">"තත්පර <xliff:g id="COUNT">%d</xliff:g> ක් තුළ"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_minutes">
+    <item quantity="one" msgid="562786149928284878">"මිනිත්තු 1 ක් තුළ"</item>
+    <item quantity="other" msgid="4216113292706568726">"මිනිත්තු <xliff:g id="COUNT">%d</xliff:g> ක් තුළ"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_hours">
+    <item quantity="one" msgid="3274708118124045246">"පැය 1 ක් තුළ"</item>
+    <item quantity="other" msgid="3705373766798013406">"පැය <xliff:g id="COUNT">%d</xliff:g> ක් තුළ"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_days">
+    <item quantity="one" msgid="2178576254385739855">"හෙට"</item>
+    <item quantity="other" msgid="2973062968038355991">"දින <xliff:g id="COUNT">%d</xliff:g> ක් තුළ"</item>
+  </plurals>
+    <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>
+    <string name="days" msgid="4774547661021344602">"දින"</string>
+    <string name="hour" msgid="2126771916426189481">"පැය"</string>
+    <string name="hours" msgid="894424005266852993">"පැය"</string>
+    <string name="minute" msgid="9148878657703769868">"min"</string>
+    <string name="minutes" msgid="5646001005827034509">"මිනිත්තු"</string>
+    <string name="second" msgid="3184235808021478">"තත්"</string>
+    <string name="seconds" msgid="3161515347216589235">"තත්පර"</string>
+    <string name="week" msgid="5617961537173061583">"සතිය"</string>
+    <string name="weeks" msgid="6509623834583944518">"සති"</string>
+    <string name="year" msgid="4001118221013892076">"අවුරුද්ද"</string>
+    <string name="years" msgid="6881577717993213522">"අවුරුදු"</string>
+  <plurals name="duration_seconds">
+    <item quantity="one" msgid="6962015528372969481">"තත්පර 1"</item>
+    <item quantity="other" msgid="1886107766577166786">"තත්පර <xliff:g id="COUNT">%d</xliff:g>"</item>
+  </plurals>
+  <plurals name="duration_minutes">
+    <item quantity="one" msgid="4915414002546085617">"මිනිත්තු 1"</item>
+    <item quantity="other" msgid="3165187169224908775">"මිනිත්තු <xliff:g id="COUNT">%d</xliff:g>"</item>
+  </plurals>
+  <plurals name="duration_hours">
+    <item quantity="one" msgid="8917467491248809972">"පැය 1"</item>
+    <item quantity="other" msgid="3863962854246773930">"පැය <xliff:g id="COUNT">%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_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>
+    <string name="midnight" msgid="7166259508850457595">"මධ්‍යම රාත්‍රිය"</string>
+    <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="cut" msgid="3092569408438626261">"කපන්න"</string>
+    <string name="copy" msgid="2681946229533511987">"පිටපත් කරන්න"</string>
+    <string name="paste" msgid="5629880836805036433">"අලවන්න"</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="textSelectionCABTitle" msgid="5236850394370820357">"පෙළ තේරීම"</string>
+    <string name="addToDictionary" msgid="4352161534510057874">"ශබ්ද කෝෂයට එකතු කරන්න"</string>
+    <string name="deleteText" msgid="6979668428458199034">"මකන්න"</string>
+    <string name="inputMethod" msgid="1653630062304567879">"ආදාන ක්‍රමය"</string>
+    <string name="editTextMenuTitle" msgid="4909135564941815494">"පෙළ ක්‍රියාවන්"</string>
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"ආචයනය ඉඩ ප්‍රමාණය අඩු වී ඇත"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"සමහර පද්ධති කාර්යයන් ක්‍රියා නොකරනු ඇත"</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="4653586947747330058">"වැඩිපුර තොරතුරු හෝ යෙදුම නැවතීම සඳහා ස්පර්ශ කරන්න."</string>
+    <string name="ok" msgid="5970060430562524910">"හරි"</string>
+    <string name="cancel" msgid="6442560571259935130">"අවලංගු කරන්න"</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>
+    <string name="capital_on" msgid="1544682755514494298">"සක්‍රීයයි"</string>
+    <string name="capital_off" msgid="6815870386972805832">"අක්‍රිය කරන්න"</string>
+    <string name="whichApplication" msgid="4533185947064773386">"පහත භාවිතයෙන් ක්‍රියාව සම්පූර්ණ කරන්න"</string>
+    <string name="alwaysUse" msgid="4583018368000610438">"මෙම ක්‍රියාව සඳහා සුපුරුද්දෙන් භාවිත කරන්න."</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="aerr_title" msgid="1905800560317137752"></string>
+    <string name="aerr_application" msgid="932628488013092776">"අවාසනාවන්ත ලෙස <xliff:g id="APPLICATION">%1$s</xliff:g> නැවතී ඇත."</string>
+    <string name="aerr_process" msgid="4507058997035697579">"අවාසනාවන්ත ලෙස, <xliff:g id="PROCESS">%1$s</xliff:g> ක්‍රියාවලිය නතර විණි."</string>
+    <string name="anr_title" msgid="4351948481459135709"></string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> ප්‍රතිචාර නොදක්වයි.\n\nඔබට එය නතර කිරීමට අවශ්‍යද?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ක්‍රියාකාරකම ප්‍රතිචාර නොදක්වයි.\n\nඑය වසා දැමීමට ඔබට අවශ්‍යද?"</string>
+    <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> ප්‍රතිචාර නොදක්වයි. එය වසා දැමීමට ඔබට අවශ්‍යද?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"<xliff:g id="PROCESS">%1$s</xliff:g> ක්‍රියාවලිය ප්‍රතිචාර නොදක්වයි.\n\nඔබට එය නතර කිරීමට අවශ්‍යද?"</string>
+    <string name="force_close" msgid="8346072094521265605">"හරි"</string>
+    <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_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; යෙදුම් &gt; බාගන්නා ලදි."</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>
+    <string name="android_upgrading_title" msgid="1584192285441405746">"Android උත්ශ්‍රේණි වෙමින් පවතී..."</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_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="1721681741617898865">"යෙදුමට මාරු වීමට ස්පර්ශ කරන්න"</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>
+    <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="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_silent_ringtone_selected" msgid="8310739960973156272">"නිහඬ රිගින් ටෝනයක් සකසන්න"</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">"බ්ලූටූත් ශබ්ද ත්‍රීවතාව"</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="8129563480895990372">"සුපුරුදු රින්ටෝනය (<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_unknown" msgid="5477919988701784788">"නොදන්නා රින්ටෝනය"</string>
+  <plurals name="wifi_available">
+    <item quantity="one" msgid="6654123987418168693">"Wi-Fi ජාලයක් තිබේ"</item>
+    <item quantity="other" msgid="4192424489168397386">"Wi-Fi ජාල ඇත"</item>
+  </plurals>
+  <plurals name="wifi_available_detailed">
+    <item quantity="one" msgid="1634101450343277345">"විවෘත Wi-Fi ජාලය ලබාගත හැක"</item>
+    <item quantity="other" msgid="7915895323644292768">"විවෘත Wi-Fi ජාල තිබේ"</item>
+  </plurals>
+    <string name="wifi_available_sign_in" msgid="4029489716605255386">"Wi-Fi ජලයට පුරනය වන්න"</string>
+    <string name="network_available_sign_in" msgid="8495155593358054676">"ජාලයට පුරනය වන්න"</string>
+    <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
+    <skip />
+    <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi වෙත සම්බන්ධ විය නොහැක"</string>
+    <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" දුබල අන්තර්ජාල සම්බන්ධතාවයක් ඇත."</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_enabled_notification_message" msgid="1638949953993894335">"සැකසීම් සඳහා ස්පර්ශ කරන්න"</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_to_connect_title" msgid="4958803948658533637">"සම්බන්ධතාවයට ඇරයුමකි"</string>
+    <string name="wifi_p2p_from_message" msgid="570389174731951769">"වෙතින්:"</string>
+    <string name="wifi_p2p_to_message" msgid="248968974522044099">"වෙත:"</string>
+    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"අවශ්‍ය PIN එක ටයිප් කරන්න:"</string>
+    <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</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="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_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="DEST_ADDRESS">%2$s</xliff:g>&lt;b&gt; වෙත කෙටි පණිවීඩයක් යැවීමට &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;b&gt; කැමතිය."</string>
+    <!-- syntax error in translation for sms_short_code_details (3492025719868078457) org.xmlpull.v1.XmlPullParserException: expected: /string read: font (position:END_TAG </font>@1:83 in     <string name="sms_short_code_details" msgid="3492025719868078457">"මෙය "</font>"ඔබගේ ජංගම ගිණුමේ"<font fgcolor="#ffffb060">" අය වීම් වලට හේතුවක් වේ."</string>
+)  -->
+    <string name="sms_premium_short_code_details" msgid="5523826349105123687"><font fgcolor="#ffffb060">"මෙය ඔබගේ ජංගම ගිණුමෙන් අයවීමට හේතු වේ."</font></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_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_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="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_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="usb_storage_activity_title" msgid="4465055157209648641">"USB මහා ආචයනය"</string>
+    <string name="usb_storage_title" msgid="5901459041398751495">"USB සම්බන්ධිතයි"</string>
+    <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"ඔබ ඔබගේ පරිගණකයට සම්බන්ධ වී ඇත්තේ USB ස්පර්ශය හරහාය. ඔබට ඔබේ පරිගණකය හා ඔබගේ Android USB ආචයනය අතර ගොනු පිටපත් කිරීමට අවශ්‍ය නම් පහත බොත්තම ඔබන්න."</string>
+    <string name="usb_storage_message" product="default" msgid="805351000446037811">"ඔබ ඔබගේ පරිගණකයට USB හරහා සම්බන්ධ වී ඇත. ඔබට ඔබේ පරිගණකය හා ඔබගේ Android SD පත අතර ගොනු පිටපත් කිරීමට අවශ්‍ය නම් පහත බොත්තම ස්පර්ශ කරන්න."</string>
+    <string name="usb_storage_button_mount" msgid="1052259930369508235">"USB ආචයනය සක්‍රිය කරන්න"</string>
+    <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"USB මහා ආචයනය සඳහා ඔබගේ USB ආචයනය භාවිතයේදී ගැටළුවක් තිබේ."</string>
+    <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"USB මහා ආචයනය සඳහා ඔබගේ SD පත භාවිතයේදී ගැටළුවක් තිබේ."</string>
+    <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB සම්බන්ධිතයි"</string>
+    <string name="usb_storage_notification_message" msgid="939822783828183763">"ඔබගේ පරිගණකය වෙතට/වෙතින් ගොනු පිටපත් කිරීමට ස්පර්ශ කරන්න."</string>
+    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"USB ආචයනය අක්‍රිය කරන්න"</string>
+    <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"USB ආචයනය අක්‍රිය කිරීමට ස්පර්ශ කරන්න."</string>
+    <string name="usb_storage_stop_title" msgid="660129851708775853">"USB ආචයනය භාවිතයේ පවතී"</string>
+    <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"USB ආචයනය අක්‍රිය කිරීමට පෙර, ඔබගේ පරිගණකයෙන් Android USB ආචයනය ගලවා දමන්න (\"පිට කරන්න\")."</string>
+    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"USB ආචයනය අක්‍රිය කිරීමට පෙර, ඔබගේ Android SD පත පරිගණකයෙන් ගලවන්න."</string>
+    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"USB ආචයනය අක්‍රිය කරන්න"</string>
+    <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"USB ආචයනය අක්‍රිය කිරීමේදී ගැටළුවක් ඇතිවිය. USB සංග්‍රාහකය ගලවා ඇති දැයි පරීක්ෂා කරන්න, පසුව නැවතත් උත්සහ කරන්න."</string>
+    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"USB ආචයනය සක්‍රිය කරන්න"</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"ඔබ USB ආචයනය සක්‍රිය නම්, ඔබ භාවිතා කරන සමහර යෙදුම් නැවතීම සහ ඔබ USB ආචයනය අක්‍රිය කරන තුරු නොතිබේවී."</string>
+    <string name="dlg_error_title" msgid="7323658469626514207">"USB ක්‍රියාවලිය අසාර්ථකයි"</string>
+    <string name="dlg_ok" msgid="7376953167039865701">"හරි"</string>
+    <string name="usb_mtp_notification_title" msgid="3699913097391550394">"මාධ්‍ය උපාංගයක් ලෙස සම්බන්ධිතයි"</string>
+    <string name="usb_ptp_notification_title" msgid="1960817192216064833">"කැමරාවක් ලෙස සම්බන්ධ කර ඇත"</string>
+    <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"ස්ථාපිතයක් ලෙස සම්බන්ධයි"</string>
+    <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB මෙවලමකට සම්බන්ධිතයි"</string>
+    <string name="usb_notification_message" msgid="2290859399983720271">"අනෙක් USB විකල්පය සඳහා ස්පර්ශ කරන්න."</string>
+    <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB ආචයනය ෆෝමැට් කරන්නද?"</string>
+    <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD පත ෆෝමැට් කරන්නද?"</string>
+    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"ඔබගේ USB ආචයනයේ ඇති සියලුම ගොනු මැකී යනු ඇත. මෙම ක්‍රියාව ආපසු හැරවිය නොහැක!"</string>
+    <string name="extmedia_format_message" product="default" msgid="14131895027543830">"ඔබගේ පතේ සියලු දත්ත නැති වනු ඇත."</string>
+    <string name="extmedia_format_button_format" msgid="4131064560127478695">"ෆෝමැට්"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"USB නිදොස්කරණය සම්බන්ධිතයි"</string>
+    <string name="adb_active_notification_message" msgid="1016654627626476142">"USB නිදොස්කරණය අබල කිරීමට ස්පර්ශ කරන්න."</string>
+    <string name="select_input_method" msgid="4653387336791222978">"ආදාන ක්‍රමයක් තෝරන්න"</string>
+    <string name="configure_input_methods" msgid="9091652157722495116">"ආදාන ක්‍රම සකසන්න"</string>
+    <string name="use_physical_keyboard" msgid="6203112478095117625">"භෞතික යතුරු පුවරුව"</string>
+    <string name="hardware" msgid="7517821086888990278">"දෘඨාංග"</string>
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"යතුරු පුවරුවට පිරිසැලැස්ම තෝරන්න"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"යතුරු පුවරුවට පිරිසැලැස්මක් තේරීමට ස්පර්ශ කරන්න."</string>
+    <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="candidates_style" msgid="4333913089637062257"><u>"අපේක්ෂකයන්"</u></string>
+    <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"USB ආචයනය සකසමින්"</string>
+    <string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"SD පත සුදානම් කරමින්"</string>
+    <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"වැරදි සඳහා පරීක්ෂා කරමින්."</string>
+    <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"හිස් USB ආචයනය"</string>
+    <string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"හිස් SD පත"</string>
+    <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"SD පත හිස් හෝ සහාය නොදක්වන ගොනු පද්ධතියක් ඇත."</string>
+    <string name="ext_media_nofs_notification_message" product="default" msgid="8641065641786923604">"SD පත හිස් හෝ සහය නොදක්වන ගොනු පද්ධතියක් ඇත"</string>
+    <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"හානි වූ USB ආචයනය"</string>
+    <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"හානි වූ SD පත"</string>
+    <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="1795917578395333280">"USB ආචයනයට හානි වී ඇත. එය නැවත ෆෝමැට් ගැන්වීමට උත්සහ කරන්න."</string>
+    <string name="ext_media_unmountable_notification_message" product="default" msgid="1753898567525568253">"SD පතට හානි වී ඇත. එය නැවත ෆෝමැට් ගැන්වීමට උත්සහ කරන්න."</string>
+    <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"බලාපොරොත්තු නොවූ ලෙස USB ආචයනය ඉවත් කෙරිණි"</string>
+    <string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"SD පත බලාපොරොත්තු රහිතව ඉවත් කරන ලදි"</string>
+    <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"දත්ත නැතිවීම වැළක්වීමට USB ආචයනය ඉවත්කිරීමට පෙර ගලවන්න."</string>
+    <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"දත්ත නැතිවීම වැළක්වීමට ගැලවීමට කලින් SD පත ඉවත් කරන්න."</string>
+    <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"ඉවත් කිරීමට USB ආචයනය ආරක්ෂිතයි"</string>
+    <string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"SD පත ඉවත් කිරීමට සුරක්ෂිතයි"</string>
+    <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"ඔබට USB ආචයනය ආරක්ෂිතව ඉවත් කිරීමට පුළුවනි."</string>
+    <string name="ext_media_safe_unmount_notification_message" product="default" msgid="568841278138377604">"ඔබට ආරක්ෂිතව SD පත ඉවත් කළ හැක"</string>
+    <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"USB ආචයනය ඉවත් කරන ලදි"</string>
+    <string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"SD පත ඉවත් කර ඇත"</string>
+    <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"USB ආචයනය ඉවත්කොට ඇත. අලුත් මාධ්‍යයක් ඇතුළත් කරන්න."</string>
+    <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"SD පත ඉවත් කරන ලදි. අලුත් එකක් ඇතුළත් කරන්න."</string>
+    <string name="activity_list_empty" msgid="1675388330786841066">"ගැලපෙන ක්‍රියාකාරකම් හමු නොවුණි."</string>
+    <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"සංරචකය භාවිත කිරීමේ සංඛ්‍යාන යාවත්කාලීන කරන්න"</string>
+    <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"එකතු කරන ලද සංරචකය භාවිතා සංඛ්‍යාන වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. සාමාන්‍ය යෙදුම් සඳහා නොවේ."</string>
+    <string name="permlab_copyProtectedData" msgid="4341036311211406692">"අන්තර්ගතය පිටපත් කරන්න"</string>
+    <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"අන්තර්ගතය පිටපත් කිරීමට සුපුරුදු අන්තර්ගත සේවාව ඉල්වා සිටීමට යෙදුමට අවසර දෙන්න. සාමාන්‍ය යෙදුම්වල භාවිතය සඳහා නොවේ."</string>
+    <string name="permlab_route_media_output" msgid="1642024455750414694">"මාධ්‍ය ප්‍රතිදානයේ මාර්ගගත කිරීම"</string>
+    <string name="permdesc_route_media_output" msgid="4932818749547244346">"වෙනත් බාහිර උපාංග වෙත මාධ්‍ය ප්‍රතිදානය යැවීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"යතුරු පාලක ආරක්‍ෂිත ආචයනය වෙත ප්‍රවේශය"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"යතුරු ආරක්ෂක ආචයනයට ප්‍රවේශ වීමට යෙදුමට දෙයි."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"පෙන්වීමේ හා සැඟවීමේ යතුරු ආරක්ෂකය පාලනය කරන්න"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"යතුරු ආරක්ෂකය පාලනයට යෙදුමකට අවසර දෙන්න."</string>
+    <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"විශාලන පාලනය සඳහා දෙවරක් ස්පර්ශ කරන්න"</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>
+    <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_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="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>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"බිතුපත වෙනස් කරන්න"</string>
+    <string name="notification_listener_binding_label" msgid="2014162835481906429">"දැනුම්දීම් අසන්නා"</string>
+    <string name="vpn_title" msgid="19615213552042827">"VPN ක්‍රියාත්මකයි"</string>
+    <string name="vpn_title_long" msgid="6400714798049252294">"<xliff:g id="APP">%s</xliff:g> මඟින් VPN සක්‍රීය කරන ලදි"</string>
+    <string name="vpn_text" msgid="3011306607126450322">"ජාලය කළමනාකරණය කිරීමට ස්පර්ශ කරන්න."</string>
+    <string name="vpn_text_long" msgid="6407351006249174473">"<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_error" msgid="6009249814034708175">"සැමවිට සක්‍රිය VPN දෝෂය"</string>
+    <string name="vpn_lockdown_config" msgid="6415899150671537970">"වින්‍යාස කිරීමට ස්පර්ශ කරන්න"</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="8035230537563503262">"මෝටර් රථ ආකාරයෙන් පිටවීමට ස්පර්ශ කරන්න."</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"ටෙදරින් හෝ හොට්ස්පොට් සක්‍රීයයි"</string>
+    <string name="tethered_notification_message" msgid="6857031760103062982">"සකස් කිරීමට ස්පර්ශ කරන්න."</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="throttle_warning_notification_title" msgid="4890894267454867276">"ඉහළ ජංගම දත්ත භාවිතය"</string>
+    <string name="throttle_warning_notification_message" msgid="3340822228599337743">"ජංගම දත්ත භාවිතය ගැන තව දැනගැනීමට ස්පර්ශ කරන්න."</string>
+    <string name="throttled_notification_title" msgid="6269541897729781332">"ජංගම දත්ත සීමාව ඉක්මවා ඇත"</string>
+    <string name="throttled_notification_message" msgid="5443457321354907181">"ජංගම දත්ත භාවිතය ගැන තව දැනගැනීමට ස්පර්ශ කරන්න."</string>
+    <string name="no_matches" msgid="8129421908915840737">"ගැලපීම් නැත"</string>
+    <string name="find_on_page" msgid="1946799233822820384">"පිටුවෙහි සෙවීම"</string>
+  <plurals name="matches_found">
+    <item quantity="one" msgid="8167147081136579439">"ගැළපීම් 1 යි"</item>
+    <item quantity="other" msgid="4641872797067609177">"<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="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"USB ආචයනය ගැලවීම..."</string>
+    <string name="progress_unmounting" product="default" msgid="1327894998409537190">"SD පත ගලවමින්..."</string>
+    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"USB ආචයනය මකමින්..."</string>
+    <string name="progress_erasing" product="default" msgid="6596988875507043042">"SD පත මකමින්..."</string>
+    <string name="format_error" product="nosdcard" msgid="6299769563624776948">"USB ආචයනය මැකිය නොහැක."</string>
+    <string name="format_error" product="default" msgid="7315248696644510935">"SD පත මැකීමට නොහැකි විය."</string>
+    <string name="media_bad_removal" msgid="7960864061016603281">"ගැලවීමට පෙර SD පත ඉවත්කර ඇත."</string>
+    <string name="media_checking" product="nosdcard" msgid="418188720009569693">"USB ආචයනය මේ වනවිට පරීක්ෂා කරමින් පවතී."</string>
+    <string name="media_checking" product="default" msgid="7334762503904827481">"SD පත දැන් පරීක්ෂා කරමින් පවතී."</string>
+    <string name="media_removed" msgid="7001526905057952097">"SD පත ඉවත් කර ඇත."</string>
+    <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"පරිගණකයක් විසින් දැන් USB ආචයනය භාවිතා කරයි."</string>
+    <string name="media_shared" product="default" msgid="5706130568133540435">"SD පත දැනට පරිගණකයකින් පාවිච්චි කරයි."</string>
+    <string name="media_unknown_state" msgid="729192782197290385">"බාහිර මාධ්‍යය නොදන්නා අවස්ථාවේ පවතියි."</string>
+    <string name="share" msgid="1778686618230011964">"බෙදාගන්න"</string>
+    <string name="find" msgid="4808270900322985960">"සොයන්න"</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="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_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>
+    <string name="add_account_button_label" msgid="3611982894853435874">"ගිණුමක් එකතු කරන්න"</string>
+    <string name="number_picker_increment_button" msgid="2412072272832284313">"වැඩි කරන්න"</string>
+    <string name="number_picker_decrement_button" msgid="476050778386779067">"අඩු කරන්න"</string>
+    <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> ස්පර්ශ කර රඳවා සිටින්න."</string>
+    <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"වැඩි කිරීමට ඉහලට සර්පණය කරන්න සහ අඩු කිරීමට පහලට සර්පණය කරන්න."</string>
+    <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"මිනිත්තුවක් වැඩි කරන්න"</string>
+    <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"මිනිත්තුව අඩු කරන්න"</string>
+    <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"පැය වැඩිකරන්න"</string>
+    <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"පැය අඩුකරන්න"</string>
+    <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"ප.ව.සකසන්න"</string>
+    <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"පෙ.ව. සකස් කිරීම"</string>
+    <string name="date_picker_increment_month_button" msgid="5369998479067934110">"මාසය වැඩි කරන්න"</string>
+    <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"මාසයක් අඩු කරන්න"</string>
+    <string name="date_picker_increment_day_button" msgid="7130465412308173903">"දවස වැඩි කරන්න"</string>
+    <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"දවස අඩු කරන්න"</string>
+    <string name="date_picker_increment_year_button" msgid="6318697384310808899">"වසර වැඩි කරන්න"</string>
+    <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"වසර අඩු කරන්න"</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_enter" msgid="2985864015076059467">"ඇතුල් කරන්න"</string>
+    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"යෙදුමක් තෝරන්න"</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">"සර්පණ හැඩලය. ස්පර්ශ කර රඳවා සිටීම."</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> සඳහා උඩට සර්පණය කරන්න."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"<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="description_direction_right" msgid="8034433242579600980">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> සඳහා දකුණට සර්පණය කරන්න."</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"අඟුල අරින්න"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"කැමරාව"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"නිහඬ"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"ශබ්ද සක්‍රීය කරන්න"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"සෙවීම"</string>
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"අගුළු ඇරීමට ස්වයිප් කරන්න."</string>
+    <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"මුරපද යතුරු කියවනු ඇසීමට ඉස් බණුවක් සම්බන්ධ කරන්න."</string>
+    <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"නැවතුම."</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="4891916833657929263">"අභ්‍යන්තර ආචයනය"</string>
+    <string name="storage_sd_card" msgid="3282948861378286745">"SD පත"</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="1955638862122232342">"දත්ත භාවිතා අවවාදය"</string>
+    <string name="data_usage_warning_body" msgid="2814673551471969954">"භාවිතය සහ සැකසීම් බැලීමට ස්පර්ශ කරන්න."</string>
+    <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-3G දත්ත අබලයි"</string>
+    <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G දත්ත අබල කරන ලදි"</string>
+    <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"ජංගම දත්ත අබල කර ඇත"</string>
+    <string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"Wi-Fi දත්ත අබල කරන ලදි"</string>
+    <string name="data_usage_limit_body" msgid="3317964706973601386">"සබල කිරීමට ස්පර්ශ කරන්න."</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_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="6741521330997452990">"සීමා කිරීම ඉවත් කිරීමට ස්පර්ශ කරන්න"</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>
+    <string name="org_unit" msgid="7265981890422070383">"සංවිධානාත්මක ඒකකය:"</string>
+    <string name="issued_by" msgid="2647584988057481566">"ලබාදෙන ලද්දේ:"</string>
+    <string name="validity_period" msgid="8818886137545983110">"වලංගුතාවය:"</string>
+    <string name="issued_on" msgid="5895017404361397232">"නිකුත් කරන ලද්දේ:"</string>
+    <string name="expires_on" msgid="3676242949915959821">"කල් ඉකුත් වන්නේ:"</string>
+    <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>
+    <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"සියල්ල බලන්න"</string>
+    <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"ක්‍රියාකාරකම තෝරන්න"</string>
+    <string name="share_action_provider_share_with" msgid="5247684435979149216">"සමඟ බෙදාගන්න"</string>
+    <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="3245653681008218030">"යවමින්..."</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="default_audio_route_name" product="tablet" msgid="4617053898167127471">"ටැබ්ලට්ය"</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">"බ්ලූටූත් ශ්‍රව්‍ය"</string>
+    <string name="wireless_display_route_description" msgid="9070346425023979651">"රැහැන් රහිත දර්ශනය"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"හරි"</string>
+    <string name="media_route_button_content_description" msgid="5758553567065145276">"මාධ්‍ය ප්‍රතිදානය"</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>
+    <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_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="wifi_display_notification_title" msgid="2223050649240326557">"නොරැහැන් සංදර්ශකය සම්බන්ධිතයි"</string>
+    <string name="wifi_display_notification_message" msgid="4498802012464170685">"වෙනත් උපාංගයක් මත මෙම තිරය පෙන්වයි"</string>
+    <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"විසන්ධි කරන්න"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"හදිසි ඇමතුම"</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">"PIN එක වැරදියි"</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">"SIM PIN ඇතුලු කරන්න"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN එක ඇතුළු කරන්න"</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">"අපේක්ෂිත PIN කේතය ඇතුළත් කරන්න"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"අපේක්ෂිත PIN කේතය ස්ථිර කරන්න"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM පත අගුළු අරිමින්..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"වැරදි PIN කේතයකි."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"අංක 4 සිට 8 අතර වන PIN එකක් ටයිප් කරන්න."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK කේතය සංඛ්‍යා 8 ක් හෝ වැඩි විය යුතුය."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"නිවැරදි PUK කේතය නැවත ඇතුලත් කරන්න. නැවත නැවත උත්සාහ කිරීමෙන් SIM එක ස්ථිරවම අබල කරයි."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN කේත ගැලපී නැත"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"රටා උත්සාහ කිරීම් වැඩිය"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"අගුළු ඇරීමට, ඔබගේ Google ගිණුම සමග පුරනය වන්න."</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"ගිණුම පරීක්ෂා කරමින්…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"ඔබ PIN අංකය <xliff:g id="NUMBER_0">%d</xliff:g> වාරයක් වැරදියට ටයිප් කොට ඇත.\n\n තත්පර <xliff:g id="NUMBER_1">%d</xliff:g> ක් ඇතුළත නැවත උත්සාහ කරන්න."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"<xliff:g id="NUMBER_0">%d</xliff:g> වතාවක් ඔබගේ මුරපදය ඔබ වැරදියට ටයිප් කර ඇත. \n\nතත්පර <xliff:g id="NUMBER_1">%d</xliff:g> ට පසුව නැවත උත්සහ කරන්න."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"ඔබ <xliff:g id="NUMBER_0">%d</xliff:g> වාරයක් අගුළු ඇරීමේ රටාව වැරදියට ඇඳ ඇත. \n\nතත්පර <xliff:g id="NUMBER_1">%d</xliff:g> ක් ඇතුළත නැවත උත්සාහ කරන්න."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"ඔබ ටැබ්ලටය අගුළු හැරීමට වැරදියට අවස්ථා <xliff:g id="NUMBER_0">%d</xliff:g> ක් උත්සාහ කර ඇත. අවස්ථා <xliff:g id="NUMBER_1">%d</xliff:g> ක් අසාර්ථකව උත්සහ කිරීමකින් පසුව, කර්මාන්ත ශාලා මුල් තත්වයට නැවත පත් වන අතර සියලු පරිශීලක දත්ත නැති වෙයි."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"ඔබ දුරකථනය අගුළු ඇරීමට වාර <xliff:g id="NUMBER_0">%d</xliff:g> කදී වැරදී ප්‍රයත්නයන් ගෙන තිබේ. තවත් අසාර්ථක ප්‍රයත්න <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> වතාවක් වැරදියට ඇඳ ඇත. තවත් අසාර්ථක උත්සාහ <xliff:g id="NUMBER_1">%d</xliff:g> කින් පසුව, ඊ-තැපැල් ගිණුම භාවිතා කරමින් ඔබගේ ටැබ්ලටයේ අගුළු ඇරීමට ඔබට පවසනු ඇත.\n\n නැවත තත්පර <xliff:g id="NUMBER_2">%d</xliff:g> කින් උත්සාහ කරන්න."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"ඔබ වැරදියට <xliff:g id="NUMBER_0">%d</xliff:g> වතාවක් ඔබගේ අගුළු හැරීමේ රටාව ඇඳ ඇත. අසාර්ථක උත්සහ කිරීම් <xliff:g id="NUMBER_1">%d</xliff:g> න් පසුව, ඔබගේ ඊ-තැපැල් ලිපිනය භාවිතයෙන් ඔබගේ දුරකථනය අගුළු හැරීමට ඔබගෙන් අසයි.\n\n තත්පර <xliff:g id="NUMBER_2">%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="7324161939475478066">"නිර්දේශිත මට්ටමෙන් ඉහළට ශබ්දය වැඩි කරනවද?\nවැඩි කාලයක් ඉහළ ශබ්දයක් ශ්‍රවනය කිරීමෙන් ඔබගේ ශ්‍රවනයට හානි විය හැක."</string>
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"ප්‍රවේශ්‍යතාවය සබල කිරීමට ඇඟිලි දෙකක් පහළට රඳවා සිටින්න."</string>
+    <string name="accessibility_enabled" msgid="1381972048564547685">"ප‍්‍රවේශ්‍යතාව සබල කරන ලදි."</string>
+    <string name="enable_accessibility_canceled" msgid="3833923257966635673">"ප‍්‍රවේශ්‍යතාව අවලංගු කර ඇත."</string>
+    <string name="user_switched" msgid="3768006783166984410">"දැනට සිටින පරිශීලකයා <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="app_no_restricted_accounts" msgid="5739463249673727736">"සීමා සහිත පැතිකඩ සඳහා වන ගිණුම් වෙත මෙම යෙදුම සහය නොදක්වයි"</string>
+    <string name="app_not_found" msgid="3429141853498927379">"මෙම ක්‍රියාව හසුරුවීමට යෙදුමක් සොයාගත්තේ නැත"</string>
+    <string name="revoke" msgid="5404479185228271586">"අහෝසි කරන්න"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"අකුරු"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"රජයේ ලිපිය"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"නීත්‍යනුකූල"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"ප්‍රාථමික නීතිමය"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"ලෙජරය"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"කුඩා පුවත්පත"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"අවලංගු කරන ලදි"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"අන්තර්ගතය ලිවීමේදී දෝෂයකි"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"නොදනී"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"පරිපාලකයාගේ 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>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"නව PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"නව PIN තහවුරු කරන්න"</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_too_short" msgid="8173982756265777792">"PIN කුඩා වැඩිය. ඉලක්කම් 4 වත් විය යුතුය."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"තවත් තත්පර 1 කින් යළි උත්සාහ කරන්න"</item>
+    <item quantity="other" msgid="4730868920742952817">"තත්පර <xliff:g id="COUNT">%d</xliff:g> කින් නැවත උත්සහ කරන්න"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"පසුව නැවත උත්සාහ කරන්න"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"තීරුව අනාවරණයට තිරයේ කෙලවර අදින්න"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"පද්ධති තීරුව අනාවරණයට තිරයේ කෙලවරින් අදින්න"</string>
+</resources>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
new file mode 100644
index 0000000..165163b
--- /dev/null
+++ b/core/res/res/values-si/strings.xml
@@ -0,0 +1,1591 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<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="5973789783504771878">"KB"</string>
+    <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
+    <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
+    <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
+    <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
+    <string name="untitled" msgid="4638956954852782576">"&lt;නම් යොදා නැත&gt;"</string>
+    <string name="ellipsis" msgid="7899829516048813237">"…"</string>
+    <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
+    <string name="emptyPhoneNumber" msgid="7694063042079676517">"(දුරකථන අංකයක් නොමැත)"</string>
+    <string name="unknownName" msgid="2277556546742746522">"(නොදනී)"</string>
+    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"කටහඬ තැපෑල"</string>
+    <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
+    <string name="mmiError" msgid="5154499457739052907">"සම්බන්ධතා ගැටළුවක් හෝ අවලංගු MMI කේතයකි."</string>
+    <string name="mmiFdnError" msgid="5224398216385316471">"ස්ථාවර ඇමතීම් අංක වලට පමණක් මෙහෙයුම සීමාකර ඇත."</string>
+    <string name="serviceEnabled" msgid="8147278346414714315">"සේවාව සබල කරන ලදි."</string>
+    <string name="serviceEnabledFor" msgid="6856228140453471041">"සේවාව සබලයි, සඳහා:"</string>
+    <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="mmiComplete" msgid="8232527495411698359">"MMI සම්පූර්ණයි."</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">"4 සිට 8 දක්වා අංක සහිත PIN එකක් ටයිප් කරන්න."</string>
+    <string name="invalidPuk" msgid="8761456210898036513">"අංක 8 ක් හෝ ඊට වැඩි PUK එකක් ටයිප් කරන්න."</string>
+    <string name="needPuk" msgid="919668385956251611">"ඔබගේ SIM පත පතට PUK අගුළු වැටී ඇත. එම අගුල ඇරීමට PUK කේතය ටයිප් කරන්න."</string>
+    <string name="needPuk2" msgid="4526033371987193070">"SIM පතේ අගුළු ඇරීමට PUK2 ටයිප් කරන්න."</string>
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
+    <string name="ClipMmi" msgid="6952821216480289285">"පැමිණෙන අමතන්නාගේ ID"</string>
+    <string name="ClirMmi" msgid="7784673673446833091">"පිටතට යන අමතන්නාගේ ID"</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">"PIN වෙනස් වී ඇත"</string>
+    <string name="CnipMmi" msgid="3110534680557857162">"ඇමතුම් අංකය ඇත"</string>
+    <string name="CnirMmi" msgid="3062102121430548731">"ඇමතුම් අංකය සීමා කර ඇත"</string>
+    <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="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="RestrictedChangedTitle" msgid="5592189398956187498">"සීමිත ප්‍රවේශය වෙනස් කෙරිණි"</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="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>
+    <string name="serviceClassDataSync" msgid="7530000519646054776">"සමමුහුර්ත කිරීම"</string>
+    <string name="serviceClassPacket" msgid="6991006557993423453">"පැකැට්ටුව"</string>
+    <string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
+    <string name="roamingText0" msgid="7170335472198694945">"රෝමිං දර්ශකය සක්‍රියයි"</string>
+    <string name="roamingText1" msgid="5314861519752538922">"රෝමිං දර්ශකය අක්‍රියයි"</string>
+    <string name="roamingText2" msgid="8969929049081268115">"රෝමිං දර්ශකය සැණෙලි වෙයි"</string>
+    <string name="roamingText3" msgid="5148255027043943317">"වටපිටාවෙන් ඉවත්ව"</string>
+    <string name="roamingText4" msgid="8808456682550796530">"ගොඩනැගිල්ලෙන් පිටත"</string>
+    <string name="roamingText5" msgid="7604063252850354350">"රෝමිං  - කැමති පද්ධතිය"</string>
+    <string name="roamingText6" msgid="2059440825782871513">"රෝමිං  - ලබාගත හැකි පද්ධතිය"</string>
+    <string name="roamingText7" msgid="7112078724097233605">"රෝමිං - මිත්‍ර හවුල්කරු"</string>
+    <string name="roamingText8" msgid="5989569778604089291">"රෝමිං - අධිමිල හවුල්කරු"</string>
+    <string name="roamingText9" msgid="7969296811355152491">"රෝමිං  - සම්පූර්ණ සේවා ක්‍රියාකාරිත්වය"</string>
+    <string name="roamingText10" msgid="3992906999815316417">"රෝමිං - අසම්පූර්ණ සේවා ක්‍රියාකාරීත්වය"</string>
+    <string name="roamingText11" msgid="4154476854426920970">"රෝමිං  බැනරය සක්‍රීයයි"</string>
+    <string name="roamingText12" msgid="1189071119992726320">"රෝමිං බැනරය අක්‍රියයි"</string>
+    <string name="roamingTextSearching" msgid="8360141885972279963">"සේවාව සඳහා සොයමින්"</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="TIME_DELAY">{2}</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>
+    <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="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="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="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="default" msgid="3475999286680000541">"දුරකථන ආචයනය පිරී ඇත. ඉඩ නිදහස් කිරීමට සමහර ගොනු මකන්න."</string>
+    <string name="me" msgid="6545696007631404292">"මම"</string>
+    <string name="power_dialog" product="tablet" msgid="8545351420865202853">"ටැබ්ලට විකල්ප"</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="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="shutdown_progress" msgid="2281079257329981203">"වසා දමමින්…"</string>
+    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"ඔබගේ ටැබ්ලටය වැසේ."</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="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_bug_report" msgid="7934010578922304799">"දෝෂ වර්තාව"</string>
+    <string name="bugreport_title" msgid="2667494803742548533">"දෝෂ වාර්තාවක් ගන්න"</string>
+    <string name="bugreport_message" msgid="398447048750350456">"ඊ-තැපැල් පණිවිඩයක් ලෙස යැවීමට මෙය ඔබගේ වත්මන් උපාංග තත්වය ගැන තොරතුරු එකතු කරනු ඇත. දෝෂ වාර්තාව ආරම්භ කර එය යැවීමට සූදානම් කරන තෙක් එයට කිසියම් කාලයක් ගතවනු ඇත; කරුණාකර ඉවසන්න."</string>
+    <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_airplane_mode_on_status" msgid="2719557982608919750">"අහස්යානා ආකාරය සක්‍රීයයි."</string>
+    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"අහස්යානා අකාරය අක්‍රියයි"</string>
+    <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
+    <string name="safeMode" msgid="2788228061547930246">"ආරක්‍ෂිත ආකාරය"</string>
+    <string name="android_system_label" msgid="6577375335728551336">"Android පද්ධතිය"</string>
+    <string name="permgrouplab_costMoney" msgid="5429808217861460401">"ඔබගේ මුදල් වැයවන සේවාවන්"</string>
+    <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"ඔබගෙන් මුදල් යන දේවල් කරන්න."</string>
+    <string name="permgrouplab_messages" msgid="7521249148445456662">"ඔබගේ පණිවිඩ"</string>
+    <string name="permgroupdesc_messages" msgid="7821999071003699236">"ඔබගේ SMS, ඊ-තැපැල්, සහ වෙනත් පණිවිඩ කියවන්න සහ ලියන්න."</string>
+    <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"ඔබගේ පෞද්ගලික තොරතුරු"</string>
+    <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"ඔබගේ සම්බන්ධතා පතේ ආචයනය කරන ලද, ඔබ ගැන තොරතුරු වලට ඍජු ප්‍රවේශය."</string>
+    <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"ඔබගේ සමාජයීය තොරතුරු"</string>
+    <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"ඔබගේ සම්බන්ධතා සහ සාමාජ සම්බන්ධයන් ගැන තොරතුරු වෙත ඍජු ප්‍රවේශය."</string>
+    <string name="permgrouplab_location" msgid="635149742436692049">"ඔබගේ ස්ථානය"</string>
+    <string name="permgroupdesc_location" msgid="5704679763124170100">"ඔබගේ භෞතික පිහිටුම නිරීක්ෂණය කරයි."</string>
+    <string name="permgrouplab_network" msgid="5808983377727109831">"ජාල සන්නිවේදනය"</string>
+    <string name="permgroupdesc_network" msgid="4478299413241861987">"විවිධ ජාල විශේෂාංග වෙත පිවිසෙන්න."</string>
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"බ්ලූටූත්"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"බ්ලූටූත් ඔස්සේ උපාංග සහ ජාල වෙත පිවිසෙන්න."</string>
+    <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"ශ්‍රව්‍ය සැකසීම්"</string>
+    <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"ශ්‍රව්‍ය සැකසීම් වෙනස් කරන්න."</string>
+    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"බැටරිය වෙත බලපායි"</string>
+    <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"බැටරියේ බලය ක්ෂණිකව අඩු වන විශේෂාංග භාවිත කරන්න."</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"දින දර්ශනය"</string>
+    <string name="permgroupdesc_calendar" msgid="5777534316982184416">"දින දර්ශන සිද්ධින්ට සෘජුව ප්‍රවේශ වීම."</string>
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"පරිශීලක ශබ්ද කෝෂය කියවන්න"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"පරිශීලක ශබ්ද කෝෂයේ වචන කියවීම."</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"පරිශීලක ශබ්දකෝෂයට ලිවිම"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"පරිශීලක ශබ්දකෝෂයට වචන එකතු කරන්න."</string>
+    <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"පිටුසන් සහ ඉතිහාසය"</string>
+    <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"පිටුසන් සහ බ්‍රව්සර ඉතිහාසය වෙත ඍජු ප්‍රවේශය."</string>
+    <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"සීනුව"</string>
+    <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"සීනුව සකසන්න."</string>
+    <string name="permgrouplab_voicemail" msgid="4162237145027592133">"හඬ තැපෑල"</string>
+    <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"හඬ තැපෑල වෙත ඍජු ප්‍රවේශය."</string>
+    <string name="permgrouplab_microphone" msgid="171539900250043464">"මයික්‍රොෆෝනය"</string>
+    <string name="permgroupdesc_microphone" msgid="7106618286905738408">"ශබ්දය පටිගත කිරීමට මයික්‍රොෆෝනය වෙත ඍජු ප්‍රවේශය."</string>
+    <string name="permgrouplab_camera" msgid="4820372495894586615">"කැමරාව"</string>
+    <string name="permgroupdesc_camera" msgid="2933667372289567714">"ඡායාරූප හෝ වීඩියෝ ග්‍රහණය සඳහා කැමරාව වෙත ඍජු ප්‍රවේශය."</string>
+    <string name="permgrouplab_screenlock" msgid="8275500173330718168">"අගුළු තිරය"</string>
+    <string name="permgroupdesc_screenlock" msgid="7067497128925499401">"ඔබගේ උපාංගයේ අගුළු තිරයේ ක්‍රියාකාරිත්වයට බලපාන හැකියාව."</string>
+    <string name="permgrouplab_appInfo" msgid="8028789762634147725">"ඔබගේ යෙදුම් වල තොරතුරු"</string>
+    <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"ඔබගේ උපාංගයේ වෙනත් යෙදුම් වල ක්‍රියාකාරිත්වයට බලපෑම් කළ හැකි බව."</string>
+    <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"බිතුපත"</string>
+    <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"උපාංග බිතුපතේ සැකසීම් වෙනස් කරන්න."</string>
+    <string name="permgrouplab_systemClock" msgid="406535759236612992">"ඔරලෝසුව"</string>
+    <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"උපාංග කාල හෝ කාල කලාප වෙනස් කරන්න."</string>
+    <string name="permgrouplab_statusBar" msgid="2095862568113945398">"තත්ව තීරුව"</string>
+    <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"උපාංග තත්ව තීරු සැකසීම් වෙනස් කරන්න."</string>
+    <string name="permgrouplab_syncSettings" msgid="3341990986147826541">"සමමුහුර්ත සැකසීම්"</string>
+    <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"සමමුහුර්ත සැකසීම් වෙත ප්‍රවේශය."</string>
+    <string name="permgrouplab_accounts" msgid="3359646291125325519">"ඔබගේ ගිණුම්"</string>
+    <string name="permgroupdesc_accounts" msgid="4948732641827091312">"ලබාගත හැකි ගිණුම් වලට ප්‍රවේශ වීම."</string>
+    <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"දෘඩාංග පාලක"</string>
+    <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"හෑන්ඩ්සෙටයේ දෘඩාංග වලට සෘජුවම ප්‍රවේශ වන්න."</string>
+    <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"දුරකථන ඇමතුම්"</string>
+    <string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"දුරකථන ඇමතුම් නිරීක්ෂණය කරන්න, පටිගත කරන්න සහ ක්‍රියාත්මක කරන්න."</string>
+    <string name="permgrouplab_systemTools" msgid="4652191644082714048">"පද්ධති මෙවලම්"</string>
+    <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"පද්ධතියේ පහල මට්ටම් ප්‍රවේශය සහ පාලනය."</string>
+    <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"සංවර්ධක මෙවලම්"</string>
+    <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"යෙදුම් සංවර්ධකයන් සඳහා පමණක් අවශ්‍ය විශේෂාංග."</string>
+    <string name="permgrouplab_display" msgid="4279909676036402636">"වෙනත් යෙදුම් UI"</string>
+    <string name="permgroupdesc_display" msgid="6051002031933013714">"වෙනත් යෙදුම්වල UI සඳහා බලපායි."</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"ආචයනය"</string>
+    <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"USB ආචයනය වෙත ප්‍රවේශය."</string>
+    <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"SD පත වෙත ප්‍රවේශය."</string>
+    <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"ප්‍රවේශ්‍යතා විශේෂාංග"</string>
+    <string name="permgroupdesc_accessibilityFeatures" msgid="4205196881678144335">"උපකාරීවන තාක්ෂණ ඉල්ලීම් කළ හැකි විශේෂාංග."</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="5800552516779249356">"ස්පර්ශ කරන අයිතම හඬ නගා කතා කෙරෙනු ඇති අතර ඉංගිති භාවිතයෙන් තිරය ගවේෂණය කිරීමට පුළුවනි."</string>
+    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"උසස් වෙබ් ප්‍රවේශ්‍යතාව සක්‍රිය කරන්න"</string>
+    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"යෙදුම් අන්තර්ගතයට ප්‍රවේශ්‍යතාවය වැඩිවන ලෙස සකස් කිරීමට ඇතැම් විට ස්ක්‍රිප්ට් ස්ථාපනය කර ඇත."</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"ඔබ ටයිප් කළ පෙළ බලන්න"</string>
+    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"ණයවරපත් අංක සහ මුරපද වැනි පුද්ගලික දත්ත ඇතුළත් වේ."</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"තත්ව තීරුව අබල කරන්න හෝ වෙනස් කරන්න"</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"තත්ව තීරුව අක්‍රිය කිරීමට හෝ පද්ධති නිරූපක එකතු හෝ ඉවත් කිරීමට යෙදුමට අවසර දේ."</string>
+    <string name="permlab_statusBarService" msgid="7247281911387931485">"තත්ව තීරුව"</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_processOutgoingCalls" msgid="3906007831192990946">"පිටවන ඇමතුම් වල මග වෙනස් කිරීම"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"පිටවන ඇමතුම් සකස් කිරීමට සහ ඇමතීමට නියමිත අංකය වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. මෙම අවසරයෙන් යෙදුමට පිටවන ඇමතුම් නිරීක්ෂණය, නැවත හැරවීම හෝ වැළක්වීම අවසර දෙයි."</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_receiveEmergencyBroadcast" msgid="1803477660846288089">"හදිසි විකාශන ලබා ගැනීම"</string>
+    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"හදිසි විකාශ පණිවිඩ ලැබීමට සහ ක්‍රියාත්මක කිරීමට යෙදුමට අවසර දෙන්න. පද්ධති යෙදුම් වලට පමණක් මෙම අවසරය අදාළ වෙයි."</string>
+    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"සෙල් ප්‍රචාරණ පණිවිඩ කියවීම"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"ඔබගේ උපාංගයට ලැබුණු සෙල් විකාශන පණිවිඩ කියවීමට යෙදුමට අවසර දෙන්න. ඔබට හදිසි අවස්ථාවන් පිළිබඳ අනතුරු ඇඟවීමට සෙල් විකාශන පණිවිඩ ඇතැම් ස්ථානවල සිට යවනු ලබයි. හදිසි සෙල් විකාශන ලැබෙන අවස්ථාවකදී, අනිෂ්ට යෙදුම් මඟින් ඔබගේ උපාංගයට කාර්ය සාධනයට හෝ ක්‍රියකරණයට බාධා සිදුවිය හැක."</string>
+    <string name="permlab_sendSms" msgid="5600830612147671529">"SMS පණිවිඩ යැවීම"</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"SMS පණිවිඩ යැවීමට යෙදුමට අවසර දෙන්න. මෙමඟින් බලාපොරොත්තු නොවූ ප්‍රතිඵල අත් විය හැක. අනිෂ්ට යෙදුම් ඔබගේ තහවුරුවකින් තොරව පණිවිඩ යැවීම මඟින් ඔබගේ මුදල් වැය කල හැක."</string>
+    <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"පණිවිඩ සිදුවීම හරහා ප්‍රතිචාර යැවීම"</string>
+    <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"පැමිණෙන ඇමතුම් සඳහා පණිවිඩ ඔස්සේ ප්‍රතිචාර සිදුවීම් හසුරුවීමට වෙනත් පණිවිඩ යෙදුම් සඳහා ඉල්ලීම් යැවීමට, යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"ඔබගේ පෙළ පණිවුඩ කියවන්න (SMS හෝ MMS)"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"ඔබගේ ටැබ්ලටයේ හෝ SIM පතේ ආචයනය කර ඇති SMS පණිවිඩ කියවීමට යෙදුමට අවසර දෙන්න. අන්තර්ගතය හෝ විශවාසදයි බවින් තොරවම සියලු SMS පණිවිඩ කියවීමට මෙමගින් යෙදුමට අවසර දෙයි."</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"ඔබගේ දුරකථනයේ හෝ SIM පතේ ආචයනය කරන ලද SMS පණිවිඩ කියවීමට යෙදුමට අවසර දෙන්න. අන්තර්ගතය හෝ විශ්වාසදායී බවින් තොරවම සියලු SMS පණිවිඩ කියවීමට මෙමගින් යෙදුමට අවසර දෙයි."</string>
+    <string name="permlab_writeSms" msgid="3216950472636214774">"ඔබගේ කෙටි පණිවිඩ සංස්කරණය කිරීම (SMS හෝ MMS)"</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"ඔබගේ ටැබ්ලටයේ හෝ SIM පතේ ගබඩා කර ඇති SMS පණිවිඩ වෙත ලිවීමට යෙදුමට අවසර දෙන්න. අනිෂ්ට යෙදුම් ඔබගේ පණිවිඩ මකා දැමිය හැක."</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"ඔබගේ ටැබ්ලටයේ හෝ SIM පතේ ආචයනය කරන ලද 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_interactAcrossUsers" msgid="7114255281944211682">"පරිශීලකයන් අතර අන්තර්ක්‍රියාකාරී වන්න"</string>
+    <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"උපාංගයේ විවිධ පරිශීලකයන් හරහා ක්‍රියාවන් දැක්වීමට යෙදුමට අවසර දෙන්න. පරිශීලකයන් අතර ආරක්ෂාව කඩකිරීමට අනිෂ්ට යෙදුම් විසින් මෙය භාවිතා කිරීමට ඉඩ ඇත."</string>
+    <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"පරිශීලකයන් අතර අන්තර් ක්‍රියාකාරී වීමට සම්පූර්ණ බලපත්‍රය"</string>
+    <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"පරිශීලකයන් හරහා සිදු කළ හැකි සියලු අන්තර් ක්‍රියා වලට අවසර දෙන්න."</string>
+    <string name="permlab_manageUsers" msgid="1676150911672282428">"පරිශීලකයන් කළමනාකරණය කරන්න"</string>
+    <string name="permdesc_manageUsers" msgid="8409306667645355638">"විස්තර ලබා ගැනීම, නිර්මාණකරණය, මකාදැමීම ඇතුළු පරිශීලකයන් කළමනාකරණයට යෙදුම්වලට අවසර දෙන්න."</string>
+    <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"ධාවනය වන යෙදුම් වල තොරතුරු සොයා ලබාගැනීම"</string>
+    <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"දැනට සහ මෑතක ක්‍රියාත්මක කාර්යයන් පිළිබඳ විස්තරාත්මක තොරතුරු ලබාගැනීමට යෙදුමට අවසර දෙන්න අනිෂ්ට යෙදුම් අනෙකුත් යෙදුම් පිළිබඳ පුද්ගලික තොරතුරු සොයා ගැනීමට ඉඩ තිබේ."</string>
+    <string name="permlab_reorderTasks" msgid="2018575526934422779">"ධාවනය වන යෙදුම් නැවත අනුපිළිවෙලට සැකසීම"</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"පෙරබිමට හෝ පසුබිමට සිදුවීම් ගෙනයාමට යෙදුමට අවසර දෙන්න. ඔබගේ ආදානයකින් තොරව යෙදුම මෙය සිදුකරයි."</string>
+    <string name="permlab_removeTasks" msgid="6821513401870377403">"යෙදුම් ධාවනය නවත්වන්න"</string>
+    <string name="permdesc_removeTasks" msgid="1394714352062635493">"කාර්යයන් ඉවත් කිරීමට සහ ඒවායෙහි යෙදුම් නැති කිරීමට යෙදුමට අවසර දෙන්න. අනෙක් යෙදුම් හැසිරීම බාධා කිරීමට අනිෂ්ට යෙදුම්වලට අවසර දෙන්න."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"ක්‍රියාකාරකම් අට්ටි කළමනාකරණය කරන්න"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"වෙනත් යෙදුම් ධාවනය වන ක්‍රියාකාරකම් අට්ටි වලට එකතු කිරීමට, ඉවත් කිරීමට, සහ වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. වෙනත් යෙදුම්වල හැසිරීම අනිෂ්ට යෙදුම් මගින් බාධා විය හැක."</string>
+    <string name="permlab_startAnyActivity" msgid="2918768238045206456">"ඕනෑම ක්‍රියාවක් අරඹන්න"</string>
+    <string name="permdesc_startAnyActivity" msgid="997823695343584001">"අවසර ආරක්ෂාව හෝ යැවුම් තත්වයෙන් තොරවම ඕනෑම ක්‍රියාවක් ආරම්භ කිරීමට යෙදුමට අවසර දේ."</string>
+    <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"තිර ගැළපුම සැකසීම"</string>
+    <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"වෙනත් යෙදුම්වල තිර ගැලපුම් මාදිලිය පාලනයට යෙදුමට අවසර දෙන්න. වෙනත් යෙදුම්වල හැසිරීම අනිෂ්ට යෙදුම් කැඩිය හැක."</string>
+    <string name="permlab_setDebugApp" msgid="3022107198686584052">"යෙදුම් නිදොස්කරණය සබල කිරීම"</string>
+    <string name="permdesc_setDebugApp" msgid="4474512416299013256">"වෙනත් යෙදුමක් සඳහා නිදොස්කරණය සක්‍රිය කිරීමට යෙදුමට අවසර දෙන්න. වෙනත් යෙදුම් විනාශ කිරීමට අනිෂ්ට යෙදුම් මෙය භාවිත කළ හැක."</string>
+    <string name="permlab_changeConfiguration" msgid="4162092185124234480">"පද්ධති සංදර්ශක සැකසීම් වෙනස් කරන්න"</string>
+    <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"පෙදෙසිය හෝ සම්පූර්ණ අකුරු ප්‍රමාණය වැනි පවතින වින්‍යාසය වෙනස් කිරීමට යෙදුමට අවසර දෙන්න."</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_forceStopPackages" msgid="2329627428832067700">"වෙනත් යෙදුම් බලෙන් නවත්වන්න"</string>
+    <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"යෙදුමට බලෙන් අනෙක් යෙදුම් නැවතීමට අවසර දෙන්න."</string>
+    <string name="permlab_forceBack" msgid="652935204072584616">"යෙදුම වැසීමට බල කිරීම"</string>
+    <string name="permdesc_forceBack" msgid="3892295830419513623">"නැවතීමට පෙරබිමේ ඇති ඕනෑම ක්‍රියාවක් බලෙන් නැවතීමට සහ පිටුපසට යාමට යෙදුමට අවසර දෙන්න. සාමාන්‍ය යෙදුම් සඳහා කිසිදා අවශ්‍ය නොවේ."</string>
+    <string name="permlab_dump" msgid="1681799862438954752">"පද්ධති අභ්‍යන්තර තත්වය සොයා ලබා ගන්න"</string>
+    <string name="permdesc_dump" msgid="1778299088692290329">"පද්ධතියේ අභ්‍යන්තර තත්වය ලැබීමට යෙදුමට අවසර දෙන්න. ඔවුන් සාමාන්‍යයෙන් භාවිත නොකරන විවිධත්වයකින් යුත් පුද්ගලික සහ ආරක්‍ෂිත තොරතුරු අනිෂ්ට යෙදුම් සොයා ලබා ගත හැක."</string>
+    <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"තිර අන්තර්ගතය සොයා ලබාගැනීම"</string>
+    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"ක්‍රියාකාරී කවුළුවක අන්තර්ගතය ලබාගැනීමට යෙදුමට අවසර දෙන්න. අනිෂ්ට යෙදුම් විසින් සම්පූර්ණ කවුළු අන්තර්ගතය ලබාගැනීම සහ මුරපදය හැර ඒවායෙහි පෙළ පරික්ෂා කිරීම සිදුකරයි."</string>
+    <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"ප්‍රවේශ්‍යතාවය තාවකාලිකව සබල කිරීම"</string>
+    <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"උපාංගය වෙත ප‍්‍රවේශ්‍යතාව තාවකාලිකව සක්‍රිය කිරීමට යෙදුමට අවසර දෙන්න. පරිශීලක අවධානයකින් තොරව අනිෂ්ට යෙදුම් ප‍්‍රවේශ්‍යතාව සක්‍රිය කළ හැක."</string>
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"තිර තොරතුරු සොයා ලබාගැනීම"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"කවුළු කළමනාකරු මගින් කවුළුව ගැන තොරතුරු සොයා ලබාගැනීමට යෙදුමට අවසර දෙන්න. අභ්‍යන්තර පද්ධති භාවිතය සඳහා කැමති තොරතුරු අනිෂ්ට යෙදුම් විසින් ලබා ගත හැක."</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"සිදුවීම් පෙරන්න"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"පිටත් කිරීමට පෙර සියලු පරිශීලක සිදුවීම්වල ප්‍රවාහයක් පෙරීමට යොදා ගන්නා ආදාන පෙරීමක් ලියාපදිංචි කිරීමට යෙදුමට අවසර දෙන්න. පරිශීලක මැදිහත් වීමකින් තොරව පද්ධති UI අනිෂ්ට යෙදුම් පාලනය කරයි."</string>
+    <string name="permlab_magnify_display" msgid="5973626738170618775">"දර්ශනය විශාලනය කරන්න"</string>
+    <string name="permdesc_magnify_display" msgid="7121235684515003792">"දසුනේ අන්තර්ගතය විශාල කිරීමට යෙදුමට අවසර දෙන්න. ඇතැම් විට අනිෂ්ට යෙදුම්, උපාංගය භාවිතා කළ නොහැකි බවට පත් කරමින් දසුනේ අන්තර්ගතය වෙනස් කළ හැක."</string>
+    <string name="permlab_shutdown" msgid="7185747824038909016">"අඩ වශයෙන් වැහීම"</string>
+    <string name="permdesc_shutdown" msgid="7046500838746291775">"ක්‍රියාකාරකම් කළමනාකරු වැහීමේ තත්වයට දමන්න. සම්පූර්ණ වැහීමකට පත් නොකරන්න."</string>
+    <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"යෙදුම් මාරු වීම වැළක්වීම"</string>
+    <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"වෙනත් යෙදුමක් වෙත පරිශීලකයාව මාරු වීම වළක්වයි."</string>
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"පවතින යෙදුමේ තොරතුරු ලබාගැනීම"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="8153651434145132505">"තිරයේ පෙරබිම තුළ තිබෙන දැන් පවත්නා යෙදුමේ සහ සේවාවල පෞද්ගලික තොරතුරු ලබාගැනීමට දරන්නාට අවසර දෙන්න."</string>
+    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"සියලු යෙදුම් දියත් කිරීම් නිරීක්ෂණය සහ පාලනය කිරීම"</string>
+    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"පද්ධතිය ක්‍රියාකාරකම් දියත් කරන්නේ කෙසේදැයි නිරීක්ෂණයට සහ පාලනයට යෙදුමට අවසර දෙන්න. අනිෂ්ට යෙදුම් මගින් පද්ධතිය සම්පූර්ණයෙන්ම සම්මුතියකට එළඹිය හැක. වර්ධනය සඳහා පමණක් මෙම අවසරය අවශ්‍ය වෙයි, සාමාන්‍ය භාවිතය සඳහා කිසි විටෙකත් අවශ්‍ය නොවෙයි."</string>
+    <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"පැකේජ ඉවත් කිරීමේ ප්‍රචාරණයක් යවන්න"</string>
+    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"යෙදුම් පැකේජයක් ඉවත්කොට ඇති බවට දැනුම්දීමක් විකාශනයට යෙදුමට අවසර දෙයි. ධාවනය වන අනෙකුත් යෙදුමක් නැති කිරීමට අනිෂ්ට යෙදුම් විසින් මෙය භාවිත කළ හැක."</string>
+    <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"SMS-ලැබීම විකාශන යැවීම"</string>
+    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"SMS පණිවිඩයක් හරහා ලැබුණු දැනුම්දීමක් ප්‍රචාරණයට යෙදුමට අවසර දෙන්න. පැමිණෙන SMS පණිවිඩ වංචා කිරීමට අනිෂ්ට යෙදුම් මෙය භාවිත කළ හැක."</string>
+    <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"WAP-PUSH-ලැබීම විකාශන යැවීම"</string>
+    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"WAP PUSH පණිවුඩයක් ලැබී ඇති බවට දැනුම්දීමක් විකාශනය කිරීමට යෙදුමට අවසර දෙන්න. වංචාකාරී MMS පණිවුඩ ලැබීම් හෝ නිහඬව ඕනෑම වෙබ් පිටුවක අන්තර්ගතය අනිෂ්ට විචල්‍යවලින් ඉවත් කිරීමට, අනිෂ්ට යෙදුම් විසින් මෙය භාවිතා කිරීමට ඉඩ ඇත."</string>
+    <string name="permlab_setProcessLimit" msgid="2451873664363662666">"ධාවන ක්‍රියාවලි ගණන සීමා කිරීම"</string>
+    <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"ධාවනය වන උපරිම ක්‍රියාවලි ගණන පාලනය කිරීමට යෙදුමට අවසර දෙන්න. සාමාන්‍ය යෙදුම් සඳහා කිසිදා අවශ්‍ය නොවේ."</string>
+    <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"පසුබිම් යෙදුම් වලට වැසීමට බලකරන්න"</string>
+    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"පසුබිමට පිවිසෙනවාත් සමඟම ක්‍රියාකාරකම් නැවතීම පාලනයට යෙදුමට අවසර දෙන්න. සාමාන්‍ය යෙදුම්වලට කිසිසේත් අවශ්‍ය නොවෙයි."</string>
+    <string name="permlab_batteryStats" msgid="2789610673514103364">"බැටරි සංඛ්‍යාන කියවීම"</string>
+    <string name="permdesc_batteryStats" msgid="5897346582882915114">"වර්තමාන පහළ මට්ටමේ බැටරිය භාවිතා දත්ත කියවීමට යෙදුමට අවසර දෙන්න. ඔබ භාවිත කරන යෙදුම් මොනවා දැයි ගැන විස්තරාත්මක තොරතුරු ගැන දැන ගැනීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_updateBatteryStats" msgid="3719689764536379557">"බැටරි සංඛ්‍යාන වෙනස් කිරීම"</string>
+    <string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"එකතු කරගන්නා ලද බැටරි සංඛ්‍යාන වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. සාමාන්‍ය යෙදුම් වල භාවිතයට නොවේ."</string>
+    <string name="permlab_getAppOpsStats" msgid="1508779687436585744">"යෙදුමේ විකල්ප සංඛ්‍යාංක සොයා ලබාගැනීම"</string>
+    <string name="permdesc_getAppOpsStats" msgid="6243887041577912877">"එකතු කරගත් යෙදුම් ක්‍රියාකාරිත්ව සංඛ්‍යා ලේඛන වෙනස් කිරීමට උපාංගයට ඉඩ දෙන්න. සාමාන්‍ය උපාංග භාවිතය සඳහා නොවේ."</string>
+    <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"යෙදුම් විකල්ප සංඛ්‍යාංක වෙනස් කිරීම"</string>
+    <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"එකතු කරගත් යෙදුම් ක්‍රියාකාරිත්ව සංඛ්‍යා ලේඛන වෙනස් කිරීමට යෙදුමට ඉඩ දෙන්න. සාමාන්‍ය යෙදුම් භාවිතය සඳහා නොවේ."</string>
+    <string name="permlab_backup" msgid="470013022865453920">"පද්ධති උපස්ථ පාලනය කරන්න සහ නැවත පිහිටුවන්න"</string>
+    <string name="permdesc_backup" msgid="6912230525140589891">"පද්ධතියේ උපස්ථය සහ උපක්‍රම නැවත පිහිටුවීම පාලනයට යෙදුමට අවසර දෙන්න. සාමාන්‍ය යෙදුම් වල භාවිතය සඳහා නොවේ."</string>
+    <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"සම්පූර්ණ උපස්ථය හෝ මෙහෙයුම් නැවත පිහිටුවීම සනාථ කිරීම"</string>
+    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"පූර්ණ උපස්ථ තහවුරුකිරීම් UI පුරන්නට උපකරණයට ඉඩ දෙන්න. කිසිම යෙදුමක් භාවිතා නොකරනු ඇත."</string>
+    <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"අවසර නොලත් කවුළුව දර්ශනය කරන්න"</string>
+    <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"අභ්‍යන්තර පද්ධති පරිශීලක අතුරුමුහුණත් විසින් භාවිතා කිරීමට බලාපොරොත්තු වන කවුළු නිර්මාණය කිරීමට යෙදුමට අවසර දෙන්න. සාමාන්‍ය යෙදුම්වල භාවිතය සඳහා නොවේ."</string>
+    <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"වෙනත් යෙදුම් උඩින් අඳින්න"</string>
+    <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"අනෙක් යෙදුම් මත හෝ පරිශීලක අතුරු මුහුණත් කොටස්වල ඇඳීමට යෙදුමට ඉඩ දෙන්න. එය ඔබේ භාවිතයේ ඇති ඕනෑම යෙදුමක මුහුණත සමග සම්බන්ධ වීමට හෝ අනෙක් යෙදුම් ගැන ඔබට පෙනෙන ආකාරය වෙනස් කිරීමට ඉඩ ඇත."</string>
+    <string name="permlab_setAnimationScale" msgid="2805103241153907174">"ගෝලීය සජීවන වේගය වෙනස් කරන්න"</string>
+    <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"ඕනෑම වෙලාවක පොදු සජීවීකරණ වේගය (වේගවත් හෝ මන්දගාමී සජීවීකරණ) වෙනස් කිරීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_manageAppTokens" msgid="1286505717050121370">"යෙදුම් ටෝකන කළමනාකරණය කිරීම"</string>
+    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"සාමාන්‍ය Z පටිපාටිය මඟහැරයමින් යෙදුම්වලට අයිති ටෝකන් පත් නිර්මාණයට සහ කළමනාකරණයට යෙදුම්වලට අවසර දෙන්න. සාමාන්‍ය යෙදුම්වලට කිසිසේත් අවශ්‍ය නොවේ."</string>
+    <string name="permlab_freezeScreen" msgid="4708181184441880175">"තිරය නිශ්චල කරන්න"</string>
+    <string name="permdesc_freezeScreen" msgid="8558923789222670064">"සම්පූර්ණ තිර සංක්‍රමණය සඳහා තිරය තාවකාලිකව මුදවිමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_injectEvents" msgid="1378746584023586600">"යතුරු සහ පාලන බොත්තම් ඔබන්න"</string>
+    <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"තමන්ගේ ආදාන සිදුවීම් (යතුරු එබිම් , ආදී ) අනෙකුත් යෙදුම්වලට භාරදීමට යෙදුමට ඉඩ දෙන්න. අනිෂ්ට යෙදුම් මෙය ටැබ්ලටය ලබා ගැනීමට භාවිතා කිරීමට ඉඩ ඇත."</string>
+    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"වෙනත් යෙදුම්වලට එහි ආදාන සිදුවීම් (යතුරු එබීම්, යනාදිය.) ආදිය යැවීමට යෙදුමට අවසර දෙන්න. දුරකථනය අත්කර ගැනීම අනිෂ්ට යෙදුම් මෙය භාවිත කරයි."</string>
+    <string name="permlab_readInputState" msgid="469428900041249234">"ඔබ ටයිප් කරන දෙය සහ ඔබ ගන්නා ක්‍රියාවන් පටිගත කරන්න"</string>
+    <string name="permdesc_readInputState" msgid="8387754901688728043">"මුරපදය ටයිප් කිරීම වැනි අනෙකුත් යෙදුම් සමඟ අන්තර්ක්‍රියාකාරී වනවිට යනාදී ඔබ ඔබන යතුරු දැකීමට යෙදුමට අවසර දෙන්න. සාමාන්‍ය යෙදුම් සඳහා කිසිසේත් අදාළ නොවේ."</string>
+    <string name="permlab_bindInputMethod" msgid="3360064620230515776">"ආදාන ක්‍රමයක් වෙත බඳින්න"</string>
+    <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"ආදාන ක්‍රමය ඉහල මට්ටමේ අතුරු මුහුණතක් වෙත සම්බන්ධ කිරීමට ධාරකයාට අවසර දෙන්න. සාමාන්‍ය යෙදුම්වලට කිසි විටෙක අවශ්‍ය නොවෙයි."</string>
+    <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"ප‍්‍රවේශ්‍යතා සේවාවක් වෙත බදින්න"</string>
+    <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"ප‍්‍රවේශ්‍යතා සේවාවේ ඉහළ මට්ටමේ අතුරුමුහුණතට බැඳීමට දරන්නාට අවසර දේ. සාමාන්‍ය යෙදුම් සඳහා කිසිවිටක අවශ්‍ය නොවේ."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"මුද්‍රණ සේවාවකට බද්ධ වී ඇත"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"මුද්‍රණ සේවාව ඉහල මට්ටමේ අතුරු මුහුණතක් වෙත සම්බන්ධ කිරීමට ධාරකයාට අවසර දෙන්න. සාමාන්‍ය යෙදුම්වලට කිසි විටෙක අවශ්‍ය නොවෙයි."</string>
+    <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"සියලු මුද්‍රණ කාර්යයන් වෙත පිවිසෙන්න"</string>
+    <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"වෙනත් යෙදුමකින් සෑදු මුද්‍රණ කාර්ය වෙත පිවිසීමට ධාරකයාට අවසර දෙන්න. සාමාන්‍ය යෙදුම් සඳහා කිසිදා අවශ්‍ය නොවෙයි."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC සේවාව වෙත බැඳෙන්න"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"NFC කාඩ් පත් ආදර්ශනය කරන යෙදුම් රඳවනයට සම්බන්ධ වීමට ඉඩ දෙන්න. සාමාන්‍ය යෙදුම් සඳහා කිසිදා අවශ්‍ය නොවෙයි."</string>
+    <string name="permlab_bindTextService" msgid="7358378401915287938">"පෙළ සේවාවකට බඳින්න"</string>
+    <string name="permdesc_bindTextService" msgid="8151968910973998670">"කෙටි පණිවිඩ සේවාවක (උදා. SpellCheckerService) ඉහල මට්ටමේ අතුරු මුහුණතක් වෙත සම්බන්ධ කිරීමට ධාරකයාට අවසර දෙන්න. සාමාන්‍ය යෙදුම්වලට කිසි විටෙක අවශ්‍ය නොවෙයි."</string>
+    <string name="permlab_bindVpnService" msgid="4708596021161473255">"VPN සේවාවකට බැඳීම"</string>
+    <string name="permdesc_bindVpnService" msgid="2067845564581693905">"VPN සේවාව ඉහල මට්ටමේ අතුරු මුහුණතක් වෙත සම්බන්ධ කිරීමට ධාරකයාට අවසර දෙන්න. සාමාන්‍ය යෙදුම්වලට කිසි විටෙක අවශ්‍ය නොවෙයි."</string>
+    <string name="permlab_bindWallpaper" msgid="8716400279937856462">"බිතුපත වෙත බඳින්න"</string>
+    <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"බිතුපත ඉහල මට්ටමේ අතුරු මුහුණතක් වෙත සම්බන්ධ කිරීමට ධාරකයාට අවසර දෙන්න. සාමාන්‍ය යෙදුම්වලට කිසි විටෙක අවශ්‍ය නොවෙයි."</string>
+    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"විජට සේවාවකට බඳින්න"</string>
+    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"විජට් සේවාව ඉහල මට්ටමේ අතුරු මුහුණතක් වෙත සම්බන්ධ කිරීමට ධාරකයාට අවසර දෙන්න. සාමාන්‍ය යෙදුම්වලට කිසි විටෙක අවශ්‍ය නොවෙයි."</string>
+    <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"උපාංග පරිපාලක සමඟ අන්තර්ක්‍රියාකාරී වීම"</string>
+    <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"උපාංග පාලකයා වෙතට අභිප්‍රායයන් යැවීමට ධාරකයාට අවසර දෙන්න. සාමාන්‍ය යෙදුම්වලට කිසි විටෙක අවශ්‍ය නොවෙයි."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"උපාංග පරිපාලකයෙක් එක් කිරීම හෝ ඉවත් කිරීම"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"දරන්නාට උපාංග පරිපාලකයින් එක් කිරීමට හෝ ඉවත් කිරීමට අවසර දේ. සාමාන්‍ය යෙදුම් වලට කිසිදා අවශ්‍ය නොවේ."</string>
+    <string name="permlab_setOrientation" msgid="3365947717163866844">"තිර දිශානතිය වෙනස් කිරීම"</string>
+    <string name="permdesc_setOrientation" msgid="3046126619316671476">"තිරයේ භ්‍රමණය ඕනෑම වේලාවක වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. සාමාන්‍ය යෙදුම් සඳහා කිසිදා අවශ්‍ය නොවනු ඇත."</string>
+    <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"දර්ශකයේ වේගය වෙනස් කිරීම"</string>
+    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"මූසිකයේ හෝ ට්‍රැක්පෑඩයේ වේගය ඕනෑම මොහොතක වෙනස් කිරීමට උපාංගයට ඉඩ දෙන්න. සාමාන්‍ය උපාංගයන් සඳහා කිසිදා අවශ්‍ය නොවනු ඇත."</string>
+    <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"යතුරු පුවරු පිරිසැලැස්ම වෙනස් කිරීම"</string>
+    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"යතුරුපුවරු මුහුණත වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. සාමාන්‍ය යෙදුම් සඳහා කිසිදා අවශ්‍ය නොවෙයි."</string>
+    <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"යෙදුම් වෙත Linux සංඥා යැවීම"</string>
+    <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"පවතින සියලු ක්‍රියාවලි වෙත සැපයුම් සංඥා ඉල්ලවිමට යෙදුමට අවසර දේ."</string>
+    <string name="permlab_persistentActivity" msgid="8841113627955563938">"යෙදුම සැමවිටම ධාවනය කරන්න"</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"මතකයේ පවතින එහි කොටස් නොනැසී පැවතීමට යෙදුමට අවසර දෙන්න. වෙනත් යෙදුම් වලට මතකය සීමා කිරීමෙන් ටැබ්ලටය පමා කිරීම මගින්  මෙමගින් කළ හැක."</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"යෙදුමට තම කොටස් මතකය තුල නොබිඳීව රඳා පවත්වාගෙන යාමට අවසර දෙන්න. මෙය දුරකථනය මන්දගාමී කරමින් අනෙකුත් උපාංගයන් සඳහා ඉතිරි මතකය සීමා කිරීමට හැක."</string>
+    <string name="permlab_deletePackages" msgid="184385129537705938">"යෙදුම් මකන්න"</string>
+    <string name="permdesc_deletePackages" msgid="7411480275167205081">"Android පැකේජ මැකීමට යෙදුමට අවසර දෙන්න. වැදගත් යෙදුම් මැකීමට අනිෂ්ට යෙදුම් විසින් මෙය භාවිතා කිරීමට ඉඩ ඇත."</string>
+    <string name="permlab_clearAppUserData" msgid="274109191845842756">"යෙදුමේ වෙනත් දත්ත මකන්න"</string>
+    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"පරිශීලක දත්ත හිස් කිරීමට යෙදුමකට ඉඩ දේ."</string>
+    <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"අනෙක් යෙදුම්වල හැඹිලි මකන්න"</string>
+    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"හැඹිලි ගොනු මැකීමට අවසර යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"යෙදුම් ආචයනයේ ඉඩ ප්‍රමාණය මැනීම"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"යෙදුමකට එහි කේතය, දත්ත සහ හැඹිලි ප්‍රමාණ ලබාගැනීමට අවසර දෙන්න."</string>
+    <string name="permlab_installPackages" msgid="2199128482820306924">"යෙදුම් කෙළින්ම ස්ථාපනය කිරීම"</string>
+    <string name="permdesc_installPackages" msgid="5628530972548071284">"නව හෝ යාවත්කාලින කරන ලද Android පැකේජයන් ස්ථාපනය කිරීමට ඉඩ දෙන්න. බලසහිත අවසර තීන්දු සමග නව යෙදුම් එකතු කිරීමට අනිෂ්ට යෙදුම්වලට මෙය භාවිතා කිරීමට ඉඩ තිබේ."</string>
+    <string name="permlab_clearAppCache" msgid="7487279391723526815">"යෙදුමේ සියලුම හැඹිලි දත්ත මකන්න"</string>
+    <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"අනෙක් යෙදුම්වල හැඹිලි නාමාවලි තුළ ඇති ගොනු මැකීමෙන් යෙදුමට ටැබ්ලට ආචයනය නිදහස් කිරීමට අවසර දෙන්න. මෙමගින් අනෙක් යෙදුම්වලට ඒවායේ දත්ත නැවත ලබා ගැනීමට අවශ්‍ය වන නිසා, ඒවායේ ආරම්භය තවත් සෙමින් සිදුවීමට ඉඩ ඇත."</string>
+    <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"අනෙක් යෙදුම්වල හැඹිලි නාමාවලි තුළ ඇති ගොනු මැකීමෙන් යෙදුමට දුරකථන ආචයනය නිදහස් කිරීමට අවසර දෙන්න. මෙමඟින් අනෙක් යෙදුම්වලට ඒවායේ දත්ත නැවත ලබා ගැනීමට අවශ්‍ය වන නිසා, ඒවායේ ආරම්භය තවත් සෙමින් සිදුවීමට ඉඩ ඇත."</string>
+    <string name="permlab_movePackage" msgid="3289890271645921411">"යෙදුම් සම්පත් ගෙන යාම"</string>
+    <string name="permdesc_movePackage" msgid="319562217778244524">"අභ්‍යන්තර සහ බාහිර මාධ්‍යයන්ගෙන් යෙදුමේ සම්පත් ගෙනයාමට සහ යෙදුමේ සම්පත් වලින් අභ්‍යන්තර සහ බාහිර මාධ්‍යයන්ට යෙදුමේ සම්පත් ගෙනයාමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_readLogs" msgid="6615778543198967614">"සංවේදී ලොග් දත්ත කියවීම"</string>
+    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"පද්ධතියේ විවිධ ලොග් ගොනු කියවීමට යෙදුමට අවසර දෙන්න. පුද්ගලික සහ පෞද්ගලික තොරතුරු ඇතුළත්ව ඔබ ටැබ්ලටයෙන් කුමක් කරන්නෙහිද යනාදී සාමාන්‍ය තොරතුරු සෙවීමට මෙයට අවසර දෙන්න."</string>
+    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"පද්ධතියේ විවිධ ලොග් ගොනු කියවීමට යෙදුමට අවසර දෙන්න. පුද්ගලික සහ පෞද්ගලික තොරතුරු ඇතුළත්ව ඔබ දුරකථනයෙන් කුමක් කරන්නෙහිද යනාදී සාමාන්‍ය තොරතුරු සෙවීමට මෙයට අවසර දෙන්න."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"නැවත ධාවනය සඳහා ඕනෑම මාධ්‍ය විකේතකයක් හාවිතා කරන්න"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"නැවත ධාවනය සඳහා විකේතනය කිරීමට ඕනෑම ස්ථාපිත මාධ්‍ය විකේතකයක් භාවිතයට යෙදුමට අවසර දෙන්න."</string>
+    <!-- no translation found for permlab_manageCaCertificates (1678391896786882014) -->
+    <skip />
+    <!-- no translation found for permdesc_manageCaCertificates (4015644047196937014) -->
+    <skip />
+    <string name="permlab_diagnostic" msgid="8076743953908000342">"Diag විසින් හිමිකාරත්වය දරණ සම්පත්වලට කියවීම/ ලිවිම"</string>
+    <string name="permdesc_diagnostic" msgid="6608295692002452283">"Diag කණ්ඩායමට අයිති ඕනෑම සම්පතක් කියවීමට සහ ලිවීමට යෙදුමට අවසර දෙන්න. උදාහරණයක් ලෙස /dev තුල ඇති ගොනු. මෙයට පද්ධති ස්ථායිතාවට සහ ආරක්ෂාවට බලපෑම් කිරීමට හැකියාවක් ඇත. නිෂ්පාදක හෝ ක්‍රියාකරු විසින් දෘඩාංග-විශේෂිත දෝෂ නිර්ණය සඳහා පමණක් මෙය යොදාගත යුතුය."</string>
+    <string name="permlab_changeComponentState" msgid="6335576775711095931">"යෙදුම් අංග සබල හෝ අබල කිරීම"</string>
+    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"වෙනත් යෙදුමක අංගයක් සබල ද නැද්ද යන්න වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. වැදගත් ටැබ්ලට් අවශ්‍යතා අබල කිරීමට අනිෂ්ට යෙදුම් මෙය භාවිත කළ හැක. මෙම අවසරය සැලකිල්ලෙන් භාවිතා කළ යුතුය, භාවිත නොකරන, අස්ථිර හෝ අස්ථායි තත්වයට යෙදුම පත් කිරීමට එයට හැකිය."</string>
+    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"වෙනත් යෙදුමක අංගයක් සබල ද නැද්ද යන්න වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. වැදගත් දුරකථන අවශ්‍යතා අක්‍රිය කිරීමට අනිෂ්ට යෙදුම් මෙය භාවිත කළ හැක. මෙම අවසරය සැලකිල්ලෙන් භාවිත කළ යුතුය, භාවිත නොකරන, අස්ථිර හෝ අස්ථායි තත්වයට යෙදුම පත් කිරීමට එයට හැකිය."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"අවසර ප්‍රදානය කිරීම හෝ අහෝසි කිරීම"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"යෙදුමකට එයට හෝ අනෙක් යෙදුම් වලට විශේෂිත අවසර ප්‍රදානයට හෝ අහෝසි කිරීමට අවසර දෙන්න. අනිෂ්ට යෙදුම්, ඒවාට අවසර ප්‍රදානය නොකළ ගුණාංග වලට ප්‍රවේශ වීමට මෙය භාවිතා කළ හැක."</string>
+    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"අභිරුචි යෙදුම් සකසන්න"</string>
+    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"ඔබගේ අභිරුචි යෙදුම් වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. ඔබගේ ධාවනය වන යෙදුම් වෙනස් කිරීම, පවතින යෙදුම් වලින් දත්ත එකතු කිරීම, ප්‍රෝඩා කිරීම වැනි දේ අනිෂ්ට යෙදුම් නිශ්ශබදවම සිදු කරයි."</string>
+    <string name="permlab_writeSettings" msgid="2226195290955224730">"පද්ධති සැකසීම් වෙනස් කිරීම"</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"පද්ධති සැකසීම් දත්ත වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. අනිෂ්ට යෙදුම් ඔබගේ පද්ධති වින්‍යාස දෝෂ ගැන්විය හැක."</string>
+    <string name="permlab_writeSecureSettings" msgid="204676251876718288">"ආරක්‍ෂිත පද්ධති සැකසීම් වෙනස් කරන්න"</string>
+    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"පද්ධතියේ ආරක්‍ෂිත දත්ත වෙනස් කිරීමට උපාංගයට අවසර දෙන්න. සාමාන්‍ය උපාංග සඳහා භාවිතයට නොවේ."</string>
+    <string name="permlab_writeGservices" msgid="2149426664226152185">"Google සේවා සිතියම වෙනස් කරන්න"</string>
+    <string name="permdesc_writeGservices" msgid="1287309437638380229">"Google සේවා සිතියම වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. සාමාන්‍ය යෙදුම් සඳහා භාවිතයට නොවෙයි."</string>
+    <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"ආරම්භයේදී ධාවනය කිරීම"</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"පද්ධතිය ඇරඹුම අවසන් වූ වහාම යෙදුම ආරම්භ වීමට යෙදුමට අවසර දෙන්න. ටැබ්ලටය ආරම්භ කිරීමට මෙමඟින් පමා කළ හැකි අතර සැමවිටම ධාවනය වන නිසා සම්පූර්ණ ටැබ්ලටයම ප්‍රමාද කිරීමට යෙදුමට අවසර දෙයි."</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="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="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="default" msgid="589869224625163558">"සඳහන් පුද්ගලයන්ට ඔබ ඇමතූ, ඊ-තැපැල් කළ හෝ ඇමතුම් කළ සංඛ්‍යාන ඇතුලත් ඔබගේ දුරකථනයේ ආචයනය කරන ලද සම්බන්ධතා (ලිපින) දත්ත වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. මෙම අවසරයෙන් යෙදුමට සම්බන්ධතා දත්ත මැකීමට අවසර දෙයි."</string>
+    <string name="permlab_readCallLog" msgid="3478133184624102739">"ඇමතුම් ලොගය කියවන්න"</string>
+    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"පැමිණෙන සහ පිටවන ඇමතුම් ගැන දත්ත ඇතුළත්, ඔබගේ ටැබ්ලටයේ ඇමතුම් ලොග කියවීමට යෙදුමට අවසර දෙන්න. ඔබගේ ඇමතුම් ලොග දත්ත සුරක්ෂිත කිරීමට මෙම අවසරය යෙදුම්වලට අවසර දෙයි සහ ඔබගේ දැනුමකින් තොරව ඇමතුම් ලොග දත්ත අනිෂ්ට යෙදුම් බෙදා ගැනීම කළ හැක."</string>
+    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"ලැබෙන සහ පිටවන ඇමතුම් පිළිබඳ දත්ත ඇතුළත්ව ඔබගේ දුරකථනයේ ඇමතුම් ලොග් කියවීමට යෙදුමට අවසර දෙන්න. මෙම අවසරය ඔබගේ ඇමතුම් ලොග් දත්ත උපස්ථ කිරීමට යෙදුමට ඉඩදෙන අතර ඔබගේ අනුදැනුමකින් තොරව අනිෂ්ට යෙදුම් විසින් ඇමතුම් ලොග් දත්ත බෙදාගැනීම කළ හැක."</string>
+    <string name="permlab_writeCallLog" msgid="8552045664743499354">"ඇමතුම් ලොගය ලිවීම"</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ලැබෙන ඇමතුම් සහ පිටවන ඇමතුම් දත්ත ඇතුළත්ව ඔබගේ ටැබ්ලටයේ ඇමතුම් ලොගය වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. ඔබගේ ඇමතුම් ලොගය මැකීමට හෝ වෙනස් කිරීමට අනිෂ්ට යෙදුම් මෙය භාවිතා කෙරේ."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"පැමිණෙන සහ පිටවෙන ඇමතුම් දත්ත ඇතුළුව ඔබගේ දුරකථනයේ ඇමතුම් ලොගය වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. ඔබගේ ඇමතුම් ලොගය මැකීමට හෝ වෙනස් කිරීමට අනිෂ්ට යෙදුම් මෙය භාවිත කල හැක."</string>
+    <string name="permlab_readProfile" msgid="4701889852612716678">"ඔබගේ සම්බන්ධතා පත කියවන්න"</string>
+    <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"ඔබගේ නම සම්බන්ධතා තොරතුරු ආදී ඔබගේ උපාංගයේ ගබඩා වී ඇති පුද්ගලික පැතිකඩ තොරතුරු කියවීමට යෙදුමට අවසර දෙන්න. මෙහි තේරුම යෙදුමට ඔබව හඳුනා ගැනීමට හැකි වන බව සහ ඔබගේ පුද්ගලික තොරතුරු අනෙක් අයට යැවීමට ද හැකි වීමයි."</string>
+    <string name="permlab_writeProfile" msgid="907793628777397643">"ඔබගේ සම්බන්ධතා පත වෙනස් කිරීම"</string>
+    <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"ඔබගේ නම සහ සම්බන්ධතා තොරතුරු වැනි ඔබගේ උපාංගයේ ආචයනය කරන ලද පුද්ගලික පැතිකඩ තොරතුරු වෙනස් කිරීමට හෝ එකතු කිරීමට යෙදුමට අවසර දෙන්න. මෙමගින් යෙදුමට ඔබව හඳුනා ගත හැකි අතර අනෙක් අයට ඔබගේ පැතිකඩ තොරතුරු යැවිය හැකි බව කියවෙයි."</string>
+    <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"ඔබගේ සමාජ ප්‍රවාහය කියවන්න"</string>
+    <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"ඔබගේ සහ ඔබගේ යහළුවන්ගේ සමාජ යාවත්කාලීනයන් වෙත පිවිසීමට හෝ සමමුහුර්ත කිරීමට යෙදුමට අවසර දෙන්න. තොරතුරු බෙදා ගැනීමේ දී සැලකිලිමත් වන්න -- විශ්වාසයකින් තොරව සමාජ ජාලවල ඔබගේ සහ ඔබගේ යහළුවන් අතර සන්නිවේදන කියවීමට මෙමගින් යෙදුමට අවසර දෙයි. සටහන: සියලු සමාජ ජාලවල මෙම අවසරය බල නොකරයි."</string>
+    <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"ඔබගේ සමාජ ප්‍රවාහය වෙත ලිවීම"</string>
+    <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"ඔබගේ යහළුවන්ගේ සමාජ යාවත්කාලීනයන් පෙන්වීමට යෙදුමට අවසර දෙන්න. තොරතුරු බෙදා ගැනීමේදී සැලකිලිමත් වන්න -- යහළුවෙක්ගෙන් පැමිණෙන ලෙස පණිවිඩ නිපදවීමට මෙමඟින් යෙදුමට අවසර දෙන්න. සටහන : සියලු සමාජ ජාල සඳහා මෙම අවසරය බල නොදෙයි."</string>
+    <string name="permlab_readCalendar" msgid="5972727560257612398">"දින දර්ශනයේ සිදුවීම් සහ රහසිගත තොරතුරු කියවීම"</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"ඔබගේ ටැබ්ලටය තුල ගබඩා  කර ඇති මිතුරන්ගේ සහ එක්ව ක්‍රියාකරන්නන්ගේ ද ඇතුළුව සියලුම දින දර්ශන සිද්ධි කියවීමට යෙදුමට අවසර දෙන්න. මෙය රහස්‍යභාවය හෝ සංවේදීතාවය නොසලකා ඔබගේ දින දර්ශන දත්ත බෙදා ගැනීමට හෝ සුරැකීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"යහළුවන් සහ සමකාලිනයන් ඇතුලත් ඔබගේ දුරකථනයේ ආචයනය කරන ලද සියලු දින දර්ශන සිදුවීම් කියවීමට යෙදුමට අවසර දෙන්න. විශ්වාසයකින් හෝ සංවේදීතාවකින් තොරව ඔබගේ දින දර්ශන දත්ත බෙදා ගැනීමට හෝ උපස්ථ කිරීමට මෙමගින් යෙදුමට අවසර දෙයි."</string>
+    <string name="permlab_writeCalendar" msgid="8438874755193825647">"දින දර්ශන සිද්ධි එකතු කිරීම හෝ වෙනස් කිරීමක් සිදුකර හිමිකරුගේ දැනීමකින් තොරව අමුත්තන්ට ඊ-තැපෑලක් යවීම"</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"යහළුවන් හෝ එකට-වැඩකරන්නන් ඇතුළත්ව ඔබට ටැබ්ලටයේ වෙනස් කළ හැකි සිද්ධි එකතු කිරීමට, ඉවත් කිරීමට, වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. මෙමඟින් දින දර්ශන හිමිකරුවන්ගෙන් පණිවිඩ යවන පරිදි මෙන් මවාපෑමට හෝ හිමිකරුගේ අනුදැනුමකින් තොරව සිද්ධි වෙනස් කිරීමට යෙදුමට අවසර ලැබේ."</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"ඔබගේ යහළුවන් හෝ සමකාලීනයන් ඇතුළත් ඔබගේ දුරකථනයේ ඔබට වෙනස් කළ හැකි සිදු වීම් එකතු කිරීමට, ඉවත් කිරීමට, වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. මෙමගින් දින දර්ශන හිමිකරුවන්ගෙන් පැමිණෙන සේ පෙනෙන පණිවිඩ යැවීමට හෝ හිමිකරුගේ දැනුමකින් තොරව සිදුවීම් වෙනස් කිරීමට යෙදුමට අවසර දෙයි."</string>
+    <string name="permlab_accessMockLocation" msgid="8688334974036823330">"පරීක්ෂණ සඳහා ආදර්ශ ස්ථාන මූලාශ්‍ර"</string>
+    <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"පරීක්ෂණයට ව්‍යාජ ස්ථාන මූලාශ්‍ර සාදන්න හෝ නව ස්ථාන සැපයුම්කරුවෙකු ස්ථාපනය කරන්න. GPS හෝ ස්ථාන සැපයුම්කරුවන් ආදී වෙනත් ස්ථාන මූලාශ්‍ර විසින් ලබා දෙන ස්ථානය සහ/හෝ තත්වය ප්‍රතිස්ථාපනය කිරීමට යෙදුමට මෙය අවසර දෙයි."</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"අමතර ස්ථාන සැපයුම්කරු විධාන වෙත ප්‍රවේශ වීම"</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"අමතර ස්ථාන සැපයුම්කරු විධාන වෙත පිවිසීමට යෙදුමට අවසර දෙන්න. GPS හෝ වෙනත් ස්ථාන මූලාශ්‍ර ක්‍රියාවලි වෙත බාධා කිරීමට මෙය අවසර දෙයි."</string>
+    <string name="permlab_installLocationProvider" msgid="6578101199825193873">"ස්ථාන සැපයුම්කරුවෙකු ස්ථාපනයට අවසරය දෙන්න"</string>
+    <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"පරීක්ෂණයට ව්‍යාජ ස්ථාන මූලාශ්‍ර සාදන්න හෝ නව ස්ථාන සැපයුම්කරුවෙකු ස්ථාපනය කරන්න. GPS හෝ ස්ථාන සැපයුම්කරුවන් ආදී වෙනත් ස්ථාන මූලාශ්‍ර විසින් ලබා දෙන ස්ථානය සහ/හෝ තත්ත්වය ප්‍රතිස්ථාපනය කිරීමට යෙදුමට මෙය අවසර දෙයි."</string>
+    <string name="permlab_accessFineLocation" msgid="1191898061965273372">"නිවැරදි ස්ථානය (GPS සහ ජාලය පදනම් කරගත්)"</string>
+    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"ගෝලීය ස්ථානීය පද්ධතිය (GPS) හෝ සෙල් කුළුණු සහ Wi-Fi වැනි ජාල ස්ථානීය ප්‍රභව භාවිතයෙන් ඔබගේ නිවැරදි ස්ථානය ලබාගැනීමට යෙදුම අවසර දෙන්න. යෙදුම් වලට ස්ථානීය සේවා භාවිතා කිරීමට  ඒවා සක්‍රිය විය යුතු වේ. ඔබව සොයා ගැනීමට යෙදුම් මෙය භාවිතා කරන අතර අමතර බැටරි බලයක්ද පරිභෝජනය කරයි."</string>
+    <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"ආසන්නතම ස්ථානය (ජාලය-පාදක වූ)"</string>
+    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"ඔබගේ දළ ස්ථානය ලබාගැනීමට යෙදුමට අවසර දෙන්න. සන්නේවේදන කුළුණු සහ Wi-Fi ආදී ජාල ස්ථාන මූලාශ්‍ර භාවිත කරන ස්ථාන සේවා විසින් මෙම ස්ථානය ව්‍යුත්පන්න කර ඇත. යෙදුමට භාවිතය සඳහා මෙම ස්ථාන සේවා සක්‍රිය කළ යුතු අතර ඔබගේ උපාංගය සඳහා පැවතිය යුතුය. ඔබ සිටින තැන දළව හඳුනා ගැනීමට යෙදුම් වලට මෙය භාවිත කළ හැකිය."</string>
+    <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"SurfaceFlinger වෙත ප්‍රවේශය"</string>
+    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"SurfaceFlinger පහල මට්ටමේ විශේෂාංග භාවිතයට යෙදුමට අවසර දෙයි."</string>
+    <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"රාමු අන්තරාචය කියවීම"</string>
+    <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"රාමු අන්තරාචයනයෙන් අන්තර්ගතයන් කියවීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"InputFlinger වෙත පිවිසෙන්න"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"InputFlinger පහල මට්ටමේ විශේෂාංග භාවිතයට යෙදුමට අවසර දෙයි."</string>
+    <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Wifi සංදර්ශක වින්‍යාස කරන්න"</string>
+    <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"වින්‍යාස කිරීමට සහ Wifi සංදර්ශක වෙත සම්බන්ධ වීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wifi සංදර්ශක පාලනය"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Wifi සංදර්ශකයේ පහළ මට්ටමේ විශේෂාංග පාලනයට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"ශබ්ද ප්‍රතිදානය ග්‍රහණය"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"යෙදුමට ශබ්ද ප්‍රතිදානය ග්‍රහණය කර හරවා යැවීමට ඉඩ දේ."</string>
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"වීඩියෝ ප්‍රතිදානය"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"යෙදුමට වීඩියෝ ප්‍රතිදානය ග්‍රහණය කර හරවා යැවීමට ඉඩ දේ."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"ආරක්‍ෂිත වීඩියෝ ප්‍රතිදානය"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"යෙදුමට ආරක්‍ෂිත වීඩියෝ ප්‍රතිදානය ග්‍රහණය කර හරවා යැවීමට ඉඩ දේ."</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="4906839301087980680">"මයික්‍රොෆෝනය මඟින් ශබ්ද පටිගත කිරීමට යෙදුමට අවසර දෙන්න. මෙම අවසරය මඟින් යෙදුමට ඕනෑම වේලාවක ඔබගේ අනුදැනුමකින් තොරව ශබ්ද පටිගත කිරීමට ඉඩ ලබා දේ."</string>
+    <string name="permlab_camera" msgid="3616391919559751192">"පින්තූර සහ වීඩියෝ ගන්න"</string>
+    <string name="permdesc_camera" msgid="8497216524735535009">"කැමරාවෙන් පින්තූර ගැනීමට සහ වීඩියෝ කිරීමට යෙදුමට අවසර දෙන්න. මෙම අවසරය මඟින් ඔබගේ අනුදැනුමකින් තොරව ඕනෑම වේලාවකදී කැමරාව භාවිතා කිරීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"කැමරාව භාවිතයේදී LED දර්ශක සම්ප්‍රේෂණය අබල කරන්න"</string>
+    <string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"කැමරා භාවිතය පිළිබඳ LED දර්ශකය අක්‍රිය කිරීමට, කලින් පිහිටුවා ඇති පද්ධති යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"ටැබ්ලටය ස්ථිරවම අබල කිරීම"</string>
+    <string name="permlab_brick" product="default" msgid="8337817093326370537">"දුරකථනය ස්ථිරව අබල කිරීම"</string>
+    <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"මුළු ටැබ්ලටයම ස්ථිරවම අක්‍රිය කිරීමට යෙදුමට අවසර දෙන්න. මෙය ඉතා භයානකයි."</string>
+    <string name="permdesc_brick" product="default" msgid="5788903297627283099">"මුළු දුරකථනයම ස්ථිරවම අක්‍රිය කිරීමට යෙදුමට අවසර දෙන්න. මෙය ඉතා භයානකයි."</string>
+    <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"ටැබ්ලට් නැවත පණ ගැන්වීමට බල කරන්න"</string>
+    <string name="permlab_reboot" product="default" msgid="2898560872462638242">"දුරකථන නැවත පණ ගැන්වීමට බල කරන්න"</string>
+    <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"ටැබ්ලටය නැවත බල ගැන්වීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"ටැබ්ලටය නැවත ඇරඹීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"USB ආචයනය ගොනු පද්ධතිය ප්‍රවේශ කිරීම"</string>
+    <string name="permlab_mount_unmount_filesystems" product="default" msgid="4402305049890953810">"SD පත් ගොනු පද්ධතිය ප්‍රවේශ කිරීම"</string>
+    <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"ඉවත් කළ හැකි ආචයනය සඳහා ගොනු පද්ධති ඈඳීමට සහ ගැලවීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"USB ආචයනය මකන්න"</string>
+    <string name="permlab_mount_format_filesystems" product="default" msgid="262582698639274056">"SD පත මකන්න"</string>
+    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"ඉවත් කළ හැකි ආචයන ෆෝමැට් කිරීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_asec_access" msgid="3411338632002193846">"අභ්‍යන්තර ආචයනය පිළිබඳ තොරතුරු ලබා ගැනීම"</string>
+    <string name="permdesc_asec_access" msgid="3094563844593878548">"අභ්‍යන්තර ආචයනයේ තොරතුරු ලබාගැනීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_asec_create" msgid="6414757234789336327">"අභ්‍යන්තර ආචයනය නිර්මාණය"</string>
+    <string name="permdesc_asec_create" msgid="4558869273585856876">"අභ්‍යන්තර ආචයනය සැදීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_asec_destroy" msgid="526928328301618022">"අභ්‍යන්තර ආචයනය විනාශ කිරීම"</string>
+    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"අභ්‍යන්තර ආචයනය විනාශ කිරීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"අභ්‍යන්තර ආචයනය නංවීම/ගැලවීම"</string>
+    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"අභ්‍යන්තර ආචයනය සවි කිරීමට/ගැලවීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_asec_rename" msgid="7496633954080472417">"අභ්‍යන්තර ආචයනය නැවත නම් කරන්න"</string>
+    <string name="permdesc_asec_rename" msgid="1794757588472127675">"අභ්‍යන්තර ආචයනය නැවත නම් කිරීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_vibrate" msgid="7696427026057705834">"කම්පනය පාලනය කිරීම"</string>
+    <string name="permdesc_vibrate" msgid="6284989245902300945">"කම්පකය පාලනයට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_flashlight" msgid="2155920810121984215">"සැණෙළි ආලෝකය පාලනය කරන්න"</string>
+    <string name="permdesc_flashlight" msgid="6522284794568368310">"සැණෙළිය පාලනයට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_manageUsb" msgid="1113453430645402723">"USB උපාංග සඳහා කැමැත්ත සහ අවසර කළමනාකරණය කිරීම"</string>
+    <string name="permdesc_manageUsb" msgid="7776155430218239833">"USB උපාංග සඳහා අභිරුචි සහ අවසර කළමනාකරණයට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_accessMtp" msgid="4953468676795917042">"MTP ප්‍රොටොකෝලය ක්‍රියාත්මක කිරීම"</string>
+    <string name="permdesc_accessMtp" msgid="6532961200486791570">"MTP USB ප්‍රොටෝකෝලය ක්‍රියාත්මක කිරීමට කර්නල MTP ධාවකයට ප්‍රවේශ වීමට අවසර දෙන්න."</string>
+    <string name="permlab_hardware_test" msgid="4148290860400659146">"දෘඩාංග පරීක්ෂණය කරන්න"</string>
+    <string name="permdesc_hardware_test" msgid="6597964191208016605">"දෘඩාංග පරීක්ෂා කිරීමේ අරමුණ සඳහා යෙදුමට විවිධ පර්යන්ත පාලනය කිරීමට ඉඩ දෙන්න."</string>
+    <string name="permlab_callPhone" msgid="3925836347681847954">"දුරකථන අංක වෙත ඍජුවම අමතන්න"</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"ඔබගේ මැදිහත් වීමක් නොමැතිව දුරකථන අංක ඇමතීමට යෙදුමට අවසර දෙන්න. මෙහි ප්‍රතිඑලය වන්නේ අනපේක්ෂිත අයකිරීම් හෝ ඇමතුම් ඇතිවීමයි. මෙයන් හදිසි අංක වලට ඇමතුම් ගැනීමට යෙදුමට අවසර නොදෙන බවට සටහන් කරගන්න. ඔබගේ අනුදැනුමක් නොමැතිව ඇමතුම් ගැනීමෙන් අනිෂ්ට යෙදුම් ඔබගේ මුදල් නිකරුණේ වැය කරයි."</string>
+    <string name="permlab_callPrivileged" msgid="4198349211108497879">"ඕනෑම දුරකථන අංකයකට ඍජුවම අමතන්න"</string>
+    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"ඔබගේ මැදිහත්වීමකින් තොරව හදිසි අංක ඇතුළත්ව ඕනෑම දුරකථන අංකයකට ඇමතීමට යෙදුමට අවසර දෙන්න. හදිසි සේවා වෙත අනවශ්‍ය සහ නීතිමය නොවන ඇමතුම ලැබීමට අනිෂ්ට යෙදුම සිදු කළ හැක."</string>
+    <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"CDMA ටැබ්ලට පිහිටුම සෘජුව ඇරඹීම"</string>
+    <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"CDMA දුරකථන පිහිටුම සෘජුව ඇරඹීම"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"යෙදුමට CDMA ප්‍රතිපාදන ආරම්භ කිරීමට ඉඩදෙන්න. අනිෂ්ට යෙදුම් අනවශ්‍ය ලෙස CDMA ප්‍රතිපාදන ආරම්භ කළ හැක."</string>
+    <string name="permlab_locationUpdates" msgid="7785408253364335740">"ස්ථාන යාවත්කාලීන දැනුම්දීම් පාලනය කරන්න"</string>
+    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"ස්ථානීය යාවත්කාලින දැනුම්දීම් රේඩියෝවෙන් සබල/අබල කිරීමට යෙදුමට අවසර දෙන්න. සාමාන්‍ය යෙදුම්වල භාවිතය සඳහා නොවේ."</string>
+    <string name="permlab_checkinProperties" msgid="7855259461268734914">"පිරික්සුම් ගුණාංග වෙත ප්‍රවේශය"</string>
+    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"පිරික්සුම් සේවාව මගින් උත්ශ්‍රේණි කළ ගුණාංග වෙත කියවීම්/ලිවීම් පිවිසුම සඳහා යෙදුමට අවසර දෙන්න. සාමාන්‍ය යෙදුම් වල භාවිතයට නොවේ."</string>
+    <string name="permlab_bindGadget" msgid="776905339015863471">"විජට් තෝරන්න"</string>
+    <string name="permdesc_bindGadget" msgid="8261326938599049290">"කුමන විජටය කුමන යෙදුමෙන් භාවිතා කල හැකිද යන්න පද්ධතියට පැවසීමට යෙදුමට අවසර දෙන්න. මෙම අවසරය ඇති යෙදුමකට අනෙක් යෙදුම්වලට පුද්ගලික දත්ත වලට ප්‍රවේශය ලබා දිය හැක. සාමාන්‍ය යෙදුම් වල භාවිතයට නොවේ."</string>
+    <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"දුරකථනයේ තත්වය වෙනස් කිරීම"</string>
+    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"උපාංගයේ දුරකථන විශේෂාංග පාලනයට යෙදුමට අවසර දෙන්න. මෙම අවසරය ඇති යෙදුමට ඔබට නිවේදනයෙන් තොරව ජාල මාරු කිරීම, දුරකථන රේඩියෝව සක්‍රිය සහ අක්‍රිය කිරීම කළ හැක."</string>
+    <string name="permlab_readPhoneState" msgid="9178228524507610486">"දුරකථනයේ තත්වය සහ අනන්‍යතාවය කියවීම"</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"උපාංගයේ දුරකථන විශේෂාංග වෙත පිවිසීමට යෙදුමට අවසර දෙන්න. ඇමතුම සක්‍රිය වුවත් සහ ඇමතුමකින් දුරස්ථ අංකය සම්බන්ධ වුවත් දුරකථන අංකය සහ උපාංග ID හඳුනා ගැනීමට මෙම අවසරය යෙදුමට අවසර දෙයි."</string>
+    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"ටැබ්ලටය නින්දෙන් වැළක්වීම"</string>
+    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"දුරකථනය නින්දට යාමෙන් වළකන්න"</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"ටැබ්ලටය නින්දට යාමෙන් වැලැක්වීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"දුරකථනය නින්දට යාමෙන් වැලැක්වීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"ටැබ්ලටය සක්‍රිය හෝ අක්‍රිය කරන්න"</string>
+    <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"දුරකථනය බල ගැන්වීම හෝ වැසීම"</string>
+    <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"ටැබ්ලටය සක්‍රිය හෝ අක්‍රිය කිරීමට යෙදුමට අවසර දේ."</string>
+    <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"දුරකථනය සක්‍රිය සහ අක්‍රිය කිරීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_factoryTest" msgid="3715225492696416187">"කර්මාන්තශාලා පරීක්ෂණ ආකාරය තුළ ධාවනය කරන්න"</string>
+    <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"ටැබ්ලටයේ දෘඩාංග වෙත සම්පූර්ණ පිවිසුම සඳහා අවසර දීමෙන් පහළ මට්ටමේ නිපැවුම්කරු පරීක්ෂණයක් ලෙස ධාවනය කරන්න. නිපැවුම්කරු පරීක්ෂණ ආකාරයෙන් ටැබ්ලටයේ ධාවනය වන විට පමණි."</string>
+    <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"දුරකථනයේ දෘඩාංග වෙත සම්පූර්ණ පිවිසුම සඳහා අවසර දීමෙන් පහළ මට්ටමේ නිපැවුම්කරු පරීක්ෂණයක් ලෙස ධාවනය කරන්න. නිපැවුම්කරු පරීක්ෂණ ආකාරයෙන් දුරකථනයේ ධාවනය වන විට පමණි."</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_masterClear" msgid="2315750423139697397">"කර්මාන්තශාලා සුපුරුද්දට පද්ධතිය නැවත සකස් කිරීම"</string>
+    <string name="permdesc_masterClear" msgid="3665380492633910226">"සියලු දත්ත මැකීමෙන්, වින්‍යාස කිරීමෙන් සහ යෙදුම් ස්ථාපනයෙන් එහි කර්මාන්ත ශාලා සැකසීම් වෙත පද්ධතිය නැවත සැකසීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_setTime" msgid="2021614829591775646">"වේලාව සැකසීම"</string>
+    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"ටැබ්ලට ඔරලෝසුවේ වේලාව වෙනස් කිරීමට යෙදුමට ඉඩ දෙන්න."</string>
+    <string name="permdesc_setTime" product="default" msgid="1855702730738020">"දුරකථන ඔරලෝසුවේ වේලාව වෙනස් කිරීමට යෙදුමකට ඉඩ දෙන්න."</string>
+    <string name="permlab_setTimeZone" msgid="2945079801013077340">"වේලා කලාපය සැකසීම"</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"ටැබ්ලටයේ කාල කලාපය වෙනස් කිරීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"දුරකථනයේ වේලා කලාපය වෙනස් කිරීමට උපාංගයට අවසර දෙන්න."</string>
+    <string name="permlab_accountManagerService" msgid="4829262349691386986">"AccountManagerService ලෙස පෙනී සිටින්න"</string>
+    <string name="permdesc_accountManagerService" msgid="1948455552333615954">"AccountAuthenticators වෙත ඇමතුම් ගැනීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_getAccounts" msgid="1086795467760122114">"උපාංගයේ ඇති ගිණුම් සොයන්න"</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"ටැබ්ලටය විසින් දන්නා ගිණුම් ලැයිස්තුවක් ලබාගැනීමට යෙදුමට අවසර දෙන්න. ඔබ ස්ථාපනය කොට ඇති යෙදුම් විසින් සාදා ඇති ගිණුම් මීට ඇතුළත් වේ."</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"දුරකථනය විසින් දන්නා ගිණුම් ලැයිස්තුවක් ලබාගැනීමට යෙදුමට අවසර දෙන්න. ඔබ ස්ථාපනය කොට ඇති යෙදුම් විසින් සාදා ඇති ගිණුම් මීට ඇතුළත් වේ."</string>
+    <string name="permlab_authenticateAccounts" msgid="5265908481172736933">"ගිණුම් සාදන්න සහ මුරපද සකසන්න"</string>
+    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"ගිණුම් සැදීමට සහ රහස් පද ලබාගැනීම සහ සැකසීම් කිරීම ඇතුළත්ව AccountManager ගේ ගිණුම් සත්‍යාපන හැකියාවන් භාවිතා කිරීමට යෙදුමකට අවසර දෙන්න."</string>
+    <string name="permlab_manageAccounts" msgid="4983126304757177305">"ගිණුම් එකතු කරන්න හෝ ඉවත් කරන්න"</string>
+    <string name="permdesc_manageAccounts" msgid="8698295625488292506">"ගිණුම් එකතු කිරීම, සහ ඉවත් කිරීම සහ ඔවුන්ගේ මුරපද මැකීම ආදී ක්‍රියාවලි සිදු කිරීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_useCredentials" msgid="235481396163877642">"උපාංගයේ ඇති ගිණුම් භාවිතා කිරීම"</string>
+    <string name="permdesc_useCredentials" msgid="7984227147403346422">"සත්‍යාපන ටෝකන ඉල්ලීම සඳහා යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_accessNetworkState" msgid="4951027964348974773">"ජාල සම්බන්ධතාවයන් බැලීම"</string>
+    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"කුමන ජාල පවතින්නේ ද සහ සම්බන්ධිත ද ආදී ජාල සබඳතා ගැන තොරතුරු බැලීමට යෙදුමට අවසර දෙයි."</string>
+    <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"සම්පූර්ණ ජාල ප්‍රවේශය"</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"උපකරණයට ජාල කෙවනියන් සැදීමට සහ ජාල ප්‍රොටෝකෝල අභිරුචි භාවිතා කිරීමට උපකරණයට ඉඩ දෙන්න. අන්තර්ජාලයට දත්ත යැවීමට විධියන් බ්‍රව්සරය සහ අනෙකුත් යෙදුම් සපයයි, එනිසා මෙම අවසරය දත්ත අන්තර්ජාලයට යැවීමට අවශ්‍ය නොවේ."</string>
+    <string name="permlab_writeApnSettings" msgid="505660159675751896">"ජාලයේ සැකසීම් සහ ගමනාගමන වෙනස් කරන්න/අල්ලා ගැනීම"</string>
+    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"ඕනෑම APN එකක නියුතුව සහ තොට වෙනස් කිරීම වැනි ජාල සැකසීම් වෙනස් කිරීමට සහ සියලුම ජාල අතුරු ඇරීමට සහ සෝදිසි කිරීමට යෙදුමට අවසර දෙන්න. ඇතැම්විට ඔබගේ අනුදැනුමකින් තොරව අනිෂ්ට උපාංග ජාල පැකැට්ටු අධීක්ෂණය,ආපසු දිශාගත කිරීම හෝ වෙනස්කිරීම සිදු කිරීමට ඉඩ තිබේ."</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_changeBackgroundDataSetting" msgid="1400666012671648741">"පසුබිම් දත්ත භාවිත සැකසීම් වෙනස් කිරීම"</string>
+    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"පසුබිම් දත්ත භාවිතා සැකසීම වෙනස් කිරීමට යෙදුමට අවසර දෙන්න."</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 ජාලයේ ඇති සියලුම උපාංගවලට යැවූ පැකැට්ටු බහු විකාශ ලිපින භාවිතයෙන් ලබාගැනීමට යෙදුමට අවසර දෙන්න. non-multicast ආකාරයට වඩා වැඩි බලයක් මෙහිදී භාවිතා වේ."</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="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="2405042267131496579">"WiMAX තත්වය වෙනස් කරන්න"</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"ටැබ්ලටය 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="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_readSyncSettings" msgid="6201810008230503052">"සමමුහුර්ත සැකසීම් කියවන්න"</string>
+    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"ගිණුම සඳහා සමමුහුර්ත සැකසීම් කියවීමට යෙදුමට අවසර දෙන්න. උදාහරණයක් ලෙස, ගිණුමක් සමඟ පුද්ගල යෙදුම සමමුහුර්ත දැයි මෙයට හඳුනා ගත හැක."</string>
+    <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"සමමුහුර්ත කිරීම සක්‍රිය කරන්න සහ අක්‍රිය කරන්න"</string>
+    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"ගිණුම සඳහා සමමුහුර්ත සැකසීම් වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. උදාහරණයක් ලෙස, ගිණුම සමඟ පුද්ගල යෙදුම සමමුහුර්ත කිරීම සක්‍රිය කිරීමට භාවිත කල හැක."</string>
+    <string name="permlab_readSyncStats" msgid="7396577451360202448">"සමමුහුර්ත කිරීමේ සංඛ්‍යාන කියවීම"</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"සමමුහුර්ත කිරීමේ සිදුවීම් ඉතිහාසය සහ කෙතරම් දත්ත සමමුහුර්ත වී ඇතිදැයි ඇතුලත් ගිණුම සඳහා සමමුහුර්ත කිරීමේ සංඛ්‍යාන කියවීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"දායක වූ සංග්‍රහ කියවීම"</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"වර්තමාන සමමුහුර්ත සංග්‍රහ ගැන විස්තර ලැබීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"දායක වූ සංග්‍රහ ලිවීම"</string>
+    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"ඔබගේ වර්තමාන සමමුහුර්ත සංග්‍රහ වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. ඔබගේ සමමුහුර්ත සංග්‍රහ අනිෂ්ට යෙදුම්වලින් වෙනස් කල හැක."</string>
+    <string name="permlab_readDictionary" msgid="4107101525746035718">"ඔබ විසින් ශබ්දකෝෂයට ඇතුළත්කොට ඇති කොන්දේසි කියවීම"</string>
+    <string name="permdesc_readDictionary" msgid="659614600338904243">"පරිශීලක ශබ්ද කෝෂයේ පරිශීලකයන් විසින් ගබඩා කර තිබිය හැකි වචන, නම්, වාක්‍යංශ කියවීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_writeDictionary" msgid="2183110402314441106">"පරිශීලකයින් අර්ථ දැක්වූ ශබ්ද කෝෂයට වචන එකතු කිරීම"</string>
+    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"පරිශීලක ශබ්දකෝෂය තුළට අලුත් වචන ලිවීමට යෙදුමට ඉඩ දෙන්න."</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"ආරක්‍ෂිත ආචයනය වෙත ප්‍රවේශය පරීක්ෂා කිරීම"</string>
+    <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"ආරක්‍ෂිත ආචයනය වෙත ප්‍රවේශය පරීක්ෂා කිරීම"</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"අනාගත උපාංගවල ලබාගත හැකි USB ආචයනය සඳහා අවසරයක් පරීක්ෂා කිරීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"අනාගත උපාංගවල පැවතෙන 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_mediaStorageWrite" product="default" msgid="6859839199706879015">"අභ්‍යන්තර මාධ්‍ය ආචයනය අන්තර්ගත වෙනස් කරන්න/ මකන්න"</string>
+    <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"අභ්‍යන්තර මාධ්‍ය ආචයනයේ අන්තර්ගතය වෙනස් කිරීමට උපාංගයට අවසර දෙන්න."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"ලේඛන ආචයනය කළමනාකරණය කරන්න"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"ලේඛන ආචයනය කළමනාකරණය කිරීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"සියලුම පරිශීලකයන්ගේ බාහිර ආචයන වෙත පිවිසෙන්න"</string>
+    <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"සියලු පරිශීලකයන් සඳහා බාහිර ආචයනය වෙත පිවිසීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_cache_filesystem" msgid="5656487264819669824">"හැඹිලි ගොනු පද්ධතියට ප්‍රවේශ වීම"</string>
+    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"හැඹිලි ගොනු පද්ධති කියවීමට සහ ලිවීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_use_sip" msgid="5986952362795870502">"අන්තර්ජාල ඇමතුම් ගන්න/ලබන්න"</string>
+    <string name="permdesc_use_sip" msgid="4717632000062674294">"අන්තර්ජාල ඇමතුම් ගැනීමට/ලැබීමට SIP සේවාව භාවිතයට යෙදුමට අවසර දෙන්න."</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_markNetworkSocket" msgid="3658527214914959749">"කෙවෙනි ලකුණු වෙනස් කරන්න"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"මාර්ගගත වීම සඳහා කෙවෙනියේ ලකුණු වෙනස් කිරීමට යෙදුමට ඉඩ දෙන්න"</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_invokeCarrierSetup" msgid="3699600833975117478">"වාහකය සැපයු වින්‍යාසය යෙදුම ඉල්ලා සිටින්න"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"වාහකයා ලබාදුන් සැකසුම් යෙදුම් උත්පාදනයට ධාරකයාට අවසර දෙන්න. සාමාන්‍ය යෙදුම් සඳහා කිසිදා අවශ්‍ය නොවෙයි."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"ජාල තත්ව මත නිරීක්ෂණ වෙත ඇහුම්කන් දීම"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"යෙදුමකට ජාල තත්ව මත නිරීක්ෂණ වෙත ඇහුම්කන් දීමට අවසර දේ. සාමාන්‍ය යෙදුම් සඳහා කිසිදා අවශ්‍ය නොවේ."</string>
+    <string name="policylab_limitPassword" msgid="4497420728857585791">"මුරපද නීති සකස් කිරීම"</string>
+    <string name="policydesc_limitPassword" msgid="3252114203919510394">"තිරය අගුළු ඇරීමේ මුරපදයට අනුමත අකුරු සහ දිග පාලනය කරන්න."</string>
+    <string name="policylab_watchLogin" msgid="914130646942199503">"තිරය අගුළු ඇරීමේ උත්සාහයන් නිරීක්ෂණය කරන්න"</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"තිරය අගුළු හැරීමේදී වැරදියට ටයිප් කළ මුරපද ගණන නිරීක්ෂණය කරන්න සහ ටැබ්ලටය අගුළු දමන්න හෝ වැරදි මුරපද බොහෝ ගණනක් ටයිප් කර ඇති නම් ටැබ්ලටයේ සියලු දත්ත මකන්න."</string>
+    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"තිරය අගුළු හැරීමේදී වැරදියට ටයිප් කළ මුරපද ගණන නිරීක්ෂණය කරන්න සහ දුරකථනය අගුළු දමන්න හෝ වැරදි මුරපද බොහෝ ගණනක් ටයිප් කර ඇති නම් දුරකථනයේ සියලු දත්ත මකන්න."</string>
+    <string name="policylab_resetPassword" msgid="2620077191242688955">"තිරය අගුළු ඇරීමේ මුරපදය වෙනස් කිරීම"</string>
+    <string name="policydesc_resetPassword" msgid="605963962301904458">"තිරය අගුළු ඇරීමේ මුරපදය වෙනස් කරන්න."</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="default" msgid="5096895604574188391">"කර්මාන්ත ශාලා දත්ත යළි පිහිටුවීමෙන් පසුව අනතුරු ඇඟවිමකින් තොරවම දුරකථන දත්ත මකා දමයි."</string>
+    <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"උපාංග ගෝලීය නියුතුව සකස් කිරීම"</string>
+    <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"කොන්දේසි සක්‍රිය විට පොදු නියුතු එකක් භාවිත කරන ලෙස උපාංගය සකසන්න. පළමු උපාංග පරිපාලකයා පමණක් ඵලදායි පොදු නියුතුව සකසයි."</string>
+    <string name="policylab_expirePassword" msgid="885279151847254056">"තිරය අගුළු දැමීමේ මුරපදය කල් ඉකුත්වීම සකසන්න"</string>
+    <string name="policydesc_expirePassword" msgid="1729725226314691591">"තිර-අගුළේ මුරපදය වෙනස්වීම කොපමණ කාල පරාසයකින් සිදුවිය යුතුද යන්න පාලනය කිරීම."</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="policylab_disableKeyguardFeatures" msgid="266329104542638802">"යතුරු ආරක්ෂාවේ විශේෂාංග අබල කරන්න"</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="3467082272186534614">"යතුරු ආරක්ෂාව හි සමහර විශේෂාංග භාවිතය වළක්වයි."</string>
+  <string-array name="phoneTypes">
+    <item msgid="8901098336658710359">"නිවස"</item>
+    <item msgid="869923650527136615">"ජංගම"</item>
+    <item msgid="7897544654242874543">"කාර්යාලය"</item>
+    <item msgid="1103601433382158155">"කාර්යාල ෆැක්ස්"</item>
+    <item msgid="1735177144948329370">"නිවසේ ෆැක්ස්"</item>
+    <item msgid="603878674477207394">"පේජරය"</item>
+    <item msgid="1650824275177931637">"වෙනත්"</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>
+  </string-array>
+  <string-array name="postalAddressTypes">
+    <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="1359644565647383708">"කාර්යාලය"</item>
+    <item msgid="7868549401053615677">"වෙනත්"</item>
+    <item msgid="3145118944639869809">"අභිරුචි"</item>
+  </string-array>
+  <string-array name="organizationTypes">
+    <item msgid="7546335612189115615">"කාර්යාලය"</item>
+    <item msgid="4378074129049520373">"වෙනත්"</item>
+    <item msgid="3455047468583965104">"අභිරුචි"</item>
+  </string-array>
+  <string-array name="imProtocols">
+    <item msgid="8595261363518459565">"AIM"</item>
+    <item msgid="7390473628275490700">"Windows Live"</item>
+    <item msgid="7882877134931458217">"Yahoo"</item>
+    <item msgid="5035376313200585242">"Skype"</item>
+    <item msgid="7532363178459444943">"QQ"</item>
+    <item msgid="3713441034299660749">"Google Talk"</item>
+    <item msgid="2506857312718630823">"ICQ"</item>
+    <item msgid="1648797903785279353">"Jabber"</item>
+  </string-array>
+    <string name="phoneTypeCustom" msgid="1644738059053355820">"අභිරුචි"</string>
+    <string name="phoneTypeHome" msgid="2570923463033985887">"නිවස"</string>
+    <string name="phoneTypeMobile" msgid="6501463557754751037">"ජංගම"</string>
+    <string name="phoneTypeWork" msgid="8863939667059911633">"කාර්යාලය"</string>
+    <string name="phoneTypeFaxWork" msgid="3517792160008890912">"කාර්යාල ෆැක්ස්"</string>
+    <string name="phoneTypeFaxHome" msgid="2067265972322971467">"නිවසේ ෆැක්ස්"</string>
+    <string name="phoneTypePager" msgid="7582359955394921732">"පේජරය"</string>
+    <string name="phoneTypeOther" msgid="1544425847868765990">"වෙනත්"</string>
+    <string name="phoneTypeCallback" msgid="2712175203065678206">"යළි ඇමතීම"</string>
+    <string name="phoneTypeCar" msgid="8738360689616716982">"මෝටර් රථය"</string>
+    <string name="phoneTypeCompanyMain" msgid="540434356461478916">"ආයතනයේ මූලිකය"</string>
+    <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string>
+    <string name="phoneTypeMain" msgid="6766137010628326916">"මූලික"</string>
+    <string name="phoneTypeOtherFax" msgid="8587657145072446565">"වෙනත් ෆැක්ස්"</string>
+    <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="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="eventTypeBirthday" msgid="2813379844211390740">"උපන්දිනය"</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>
+    <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="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="imTypeWork" msgid="1371489290242433090">"කාර්යාලය"</string>
+    <string name="imTypeOther" msgid="5377007495735915478">"වෙනත්"</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>
+    <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
+    <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</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>
+    <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="relationTypeAssistant" msgid="6274334825195379076">"සහායක"</string>
+    <string name="relationTypeBrother" msgid="8757913506784067713">"සහෝදරයා"</string>
+    <string name="relationTypeChild" msgid="1890746277276881626">"දරුවා"</string>
+    <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"දේශීය හවුල්කරුවා"</string>
+    <string name="relationTypeFather" msgid="5228034687082050725">"පියා"</string>
+    <string name="relationTypeFriend" msgid="7313106762483391262">"මිත්‍රයා"</string>
+    <string name="relationTypeManager" msgid="6365677861610137895">"කළමනාකරු"</string>
+    <string name="relationTypeMother" msgid="4578571352962758304">"මව"</string>
+    <string name="relationTypeParent" msgid="4755635567562925226">"මව්පිය"</string>
+    <string name="relationTypePartner" msgid="7266490285120262781">"හවුල්කරුවා"</string>
+    <string name="relationTypeReferredBy" msgid="101573059844135524">"යොමුකරන ලද්දේ"</string>
+    <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="sipAddressTypeHome" msgid="6093598181069359295">"නිවස"</string>
+    <string name="sipAddressTypeWork" msgid="6920725730797099047">"කාර්යාලය"</string>
+    <string name="sipAddressTypeOther" msgid="4408436162950119849">"වෙනත්"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN කේතය ටයිප් කරන්න"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK සහ නව PIN කේතය ටයිප් කරන්න"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK කේතය"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"නව PIN කේතය"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><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">"අගුළු හැරීමට PIN එක ටයිප් කරන්න"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"වැරදි PIN කේතයකි."</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="8963839242565653192">"සේවාව නැත."</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="5347633784401285225">"හදිසි ඇමතුම්"</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="faceunlock_multiple_failures" msgid="754137583022792429">"මුහුණ භාවිතයෙන් අඟුළු හැරීමේ උපරිම ප්‍රයන්තයන් ගණන ඉක්මවා ඇත"</string>
+    <string name="lockscreen_plugged_in" msgid="8057762828355572315">"ආරෝපණය වෙමින්, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_charged" msgid="321635745684060624">"අරෝපිතයි"</string>
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_low_battery" msgid="1482873981919249740">"ඔබගේ ආරෝපකයට සම්බන්ධ කරන්න."</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="default" msgid="2186920585695169078">"දුරකථනය තුළ SIM පත නැත."</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_transport_prev_description" msgid="201594905152746886">"පෙර ගීත බොත්තම"</string>
+    <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"ඊළඟ ගීත බොත්තම"</string>
+    <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"විරාම බොත්තම"</string>
+    <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"ධාවක බොත්තම"</string>
+    <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"නැවතීමේ බොත්තම"</string>
+    <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">"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">%d</xliff:g> වාරයක් අගුළු ඇරීමේ රටාව වැරදියට ඇඳ ඇත. \n\nතත්පර <xliff:g id="NUMBER_1">%d</xliff:g> ක් ඇතුළත නැවත උත්සාහ කරන්න."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"ඔබ මුරපදය වාර <xliff:g id="NUMBER_0">%d</xliff:g> ක් වැරදියට ටයිප්කොට ඇත. \n\nතත්පර <xliff:g id="NUMBER_1">%d</xliff:g> කින් නැවත උත්සහ කරන්න."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"ඔබ PIN අංකය <xliff:g id="NUMBER_0">%d</xliff:g> වාරයක් වැරදියට ටයිප් කොට ඇත.\n\n තත්පර <xliff:g id="NUMBER_1">%d</xliff:g> ක් ඇතුළත නැවත උත්සාහ කරන්න."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"ඔබ වැරදියට <xliff:g id="NUMBER_0">%d</xliff:g> වතාවක් ඔබගේ අගුළු හැරීමේ රටාව ඇඳ ඇත. අසාර්ථක උත්සහ කිරීම් <xliff:g id="NUMBER_1">%d</xliff:g> න් පසුව, ඔබගේ Google පුරනය වීම් භාවිතයෙන් ඔබගේ ටැබ්ලටය අගුළු හැරීමට ඔබගෙන් අසයි.\n\n තත්පර <xliff:g id="NUMBER_2">%d</xliff:g> පසුව නැවත උත්සහ කරන්න."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"ඔබ වැරදියට <xliff:g id="NUMBER_0">%d</xliff:g> වතාවක් ඔබගේ අගුළු හැරීමේ රටාව ඇඳ ඇත. අසාර්ථක උත්සහ කිරීම් <xliff:g id="NUMBER_1">%d</xliff:g> න් පසුව, ඔබගේ Google පුරනය වීම භාවිතයෙන් ඔබගේ දුරකථනය අගුළු හැරීමට ඔබගෙන් අසනු ඇත.\n\n තත්පර <xliff:g id="NUMBER_2">%d</xliff:g> පසුව නැවත උත්සහ කරන්න."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"ඔබ ටැබ්ලටය අගුළු හැරීමට වැරදියට අවස්ථා <xliff:g id="NUMBER_0">%d</xliff:g> ක් උත්සාහ කර ඇත. අවස්ථා <xliff:g id="NUMBER_1">%d</xliff:g> ක් අසාර්ථකව උත්සහ කිරීමකින් පසුව, ටැබ්ලටය කර්මාන්ත ශාලා මුල් තත්වයට නැවත පත් වන අතර සියලු පරිශීලක දත්ත නැති වෙයි."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"ඔබ දුරකථනය අගුළු ඇරීමට වාර <xliff:g id="NUMBER_0">%d</xliff:g> කදී වැරදී ප්‍රයත්නයන් ගෙන තිබේ. තවත් අසාර්ථක ප්‍රයත්න <xliff:g id="NUMBER_1">%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="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_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_checking_password" msgid="7114627351286933867">"පරික්ෂා කරමින්..."</string>
+    <string name="lockscreen_unlock_label" msgid="737440483220667054">"අඟුල අරින්න"</string>
+    <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"ශබ්දය සක්‍රීය කරන්න"</string>
+    <string name="lockscreen_sound_off_label" msgid="996822825154319026">"ශ්‍රව්‍ය අක්‍රිය කරන්න"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"රටාව අරඹන ලදි"</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"රටාව හිස් කරන ලදි"</string>
+    <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"කොටුවක් එකතු කරන ලදි"</string>
+    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"රටාව සම්පූර්ණයි"</string>
+    <!-- String.format failed for translation -->
+    <!-- no translation found for keyguard_accessibility_widget_changed (5678624624681400191) -->
+    <skip />
+    <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_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>
+    <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_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">"PIN අගුළු ඇරීම."</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>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <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_line" msgid="5764267235026120888">"රේඛාව"</string>
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
+    <string name="factorytest_failed" msgid="5410270329114212041">"කර්මාන්ත ශාලා පරීක්ෂණය අසාර්ථකයි"</string>
+    <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST ක්‍රියාව /system/app හි ස්ථාපිත පැකේජ සඳහා පමණක් සහය දක්වයි."</string>
+    <string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST ක්‍රියාව ලබාදෙන පැකේජයක් සොයාගත නොහැකි විය."</string>
+    <string name="factorytest_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>
+    <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="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>
+    <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
+    <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
+    <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
+    <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">"ZIP කේතය"</string>
+    <string name="autofill_county" msgid="237073771020362891">"ප්‍රාන්තය"</string>
+    <string name="autofill_island" msgid="4020100875984667025">"දූපත"</string>
+    <string name="autofill_district" msgid="8400735073392267672">"දිස්ත්‍රික්කය"</string>
+    <string name="autofill_department" msgid="5343279462564453309">"දෙපාර්තමේන්තුව"</string>
+    <string name="autofill_prefecture" msgid="2028499485065800419">"ප්‍රාන්තය"</string>
+    <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="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_packageVerificationAgent" msgid="5568139100645829117">"පැකේජ සත්‍යාපනය කරන්න"</string>
+    <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"ස්ථාපිත කොට ඇති පැකේජයක් සත්‍යාපනයට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"පැකේජ සත්‍යාපකයක් වෙත බඳින්න"</string>
+    <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"පැකේජ සත්‍යාපක ඉල්ලීම් වලට දරන්නාට ඉඩ ලබා දේ. සාමාන්‍ය යෙදුම් සඳහා කිසිසේත් අවශ්‍ය නොවේ."</string>
+    <string name="permlab_serialPort" msgid="546083327654631076">"ශ්‍රේණිගත පොට ප්‍රවේශ කිරීම"</string>
+    <string name="permdesc_serialPort" msgid="2991639985224598193">"SerialManager API භාවිතයෙන් අනුක්‍රම තොට වෙත ප්‍රවේශ වීමට රඳවනයට අවසර දෙන්න."</string>
+    <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"බාහිර අන්තර්ගත සැපයුම්කරුවන් වෙත ප්‍රවේශය"</string>
+    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"අන්තර්ගත සපයන්නන්ට ප්‍රවේශ වීමට දරන්නන්ට ෂෙල් එකේ සිට ප්‍රවේශ වීමට අවසර දෙන්න. සාමාන්‍ය යෙදුම් සඳහා කිසිසේත් අදාළ නොවේ."</string>
+    <string name="permlab_updateLock" msgid="3527558366616680889">"ස්වයංක්‍රීය උපාංග යවත්කාල කිරීම් පසුබට කරන්න"</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"උපාංගය උත්ශ්‍රේණිකරණයට අන්තර්ක්‍රියාකාරී නොවන යළි ඇරඹීමක් සඳහා සුදුසු වෙලාව කුමක්ද යන්න ගැන පද්ධතියට තොරතුරු ලබාදීමට දරන්නාට අවසර දෙන්න."</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>
+    <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="menu_space_shortcut_label" msgid="2410328639272162537">"space"</string>
+    <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"ඇතුල් කරන්න"</string>
+    <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"මකන්න"</string>
+    <string name="search_go" msgid="8298016669822141719">"සෙවීම"</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="oneMonthDurationPast" msgid="7396384508953779925">"මාස 1 කට පෙර"</string>
+    <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"මාස 1 කට පෙර"</string>
+  <plurals name="num_seconds_ago">
+    <item quantity="one" msgid="4869870056547896011">"තත්පර 1 කට පෙර"</item>
+    <item quantity="other" msgid="3903706804349556379">"තත්පර <xliff:g id="COUNT">%d</xliff:g> ට පෙර"</item>
+  </plurals>
+  <plurals name="num_minutes_ago">
+    <item quantity="one" msgid="3306787433088810191">"මිනිත්තු 1 ට පෙර"</item>
+    <item quantity="other" msgid="2176942008915455116">"මිනිත්තු <xliff:g id="COUNT">%d</xliff:g> කට පෙර"</item>
+  </plurals>
+  <plurals name="num_hours_ago">
+    <item quantity="one" msgid="9150797944610821849">"පැය 1 කට පෙර"</item>
+    <item quantity="other" msgid="2467273239587587569">"පැය <xliff:g id="COUNT">%d</xliff:g> කට පෙර"</item>
+  </plurals>
+  <plurals name="last_num_days">
+    <item quantity="other" msgid="3069992808164318268">"අන්තිම දවස් <xliff:g id="COUNT">%d</xliff:g>"</item>
+  </plurals>
+    <string name="last_month" msgid="3959346739979055432">"අවසාන මාසය"</string>
+    <string name="older" msgid="5211975022815554840">"පරණ"</string>
+  <plurals name="num_days_ago">
+    <item quantity="one" msgid="861358534398115820">"ඊයේ"</item>
+    <item quantity="other" msgid="2479586466153314633">"දින <xliff:g id="COUNT">%d</xliff:g> කට පෙර"</item>
+  </plurals>
+  <plurals name="in_num_seconds">
+    <item quantity="one" msgid="2729745560954905102">"තත්පර 1 කින්"</item>
+    <item quantity="other" msgid="1241926116443974687">"තත්පර <xliff:g id="COUNT">%d</xliff:g> කදී"</item>
+  </plurals>
+  <plurals name="in_num_minutes">
+    <item quantity="one" msgid="8793095251325200395">"මිනිත්තු 1 කදී"</item>
+    <item quantity="other" msgid="3330713936399448749">"මිනිත්තු <xliff:g id="COUNT">%d</xliff:g> ක් තුළ"</item>
+  </plurals>
+  <plurals name="in_num_hours">
+    <item quantity="one" msgid="7164353342477769999">"පැය 1 ක් තුළ"</item>
+    <item quantity="other" msgid="547290677353727389">"පැය <xliff:g id="COUNT">%d</xliff:g> ක් තුළ"</item>
+  </plurals>
+  <plurals name="in_num_days">
+    <item quantity="one" msgid="5413088743009839518">"හෙට"</item>
+    <item quantity="other" msgid="5109449375100953247">"දින <xliff:g id="COUNT">%d</xliff:g> ක් තුළ"</item>
+  </plurals>
+  <plurals name="abbrev_num_seconds_ago">
+    <item quantity="one" msgid="1849036840200069118">"තත්පර 1 කට පෙර"</item>
+    <item quantity="other" msgid="3699169366650930415">"තත්පර <xliff:g id="COUNT">%d</xliff:g> කට පෙර"</item>
+  </plurals>
+  <plurals name="abbrev_num_minutes_ago">
+    <item quantity="one" msgid="6361490147113871545">"මිනිත්තු 1 කට පෙර"</item>
+    <item quantity="other" msgid="851164968597150710">"මිනිත්තු <xliff:g id="COUNT">%d</xliff:g> ට පෙර"</item>
+  </plurals>
+  <plurals name="abbrev_num_hours_ago">
+    <item quantity="one" msgid="4796212039724722116">"පැය 1 කට පෙර"</item>
+    <item quantity="other" msgid="6889970745748538901">"පැය <xliff:g id="COUNT">%d</xliff:g> ට පෙර"</item>
+  </plurals>
+  <plurals name="abbrev_num_days_ago">
+    <item quantity="one" msgid="8463161711492680309">"ඊයේ"</item>
+    <item quantity="other" msgid="3453342639616481191">"දින <xliff:g id="COUNT">%d</xliff:g> ට පෙර"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_seconds">
+    <item quantity="one" msgid="5842225370795066299">"තත්පර 1 ක් තුළ"</item>
+    <item quantity="other" msgid="5495880108825805108">"තත්පර <xliff:g id="COUNT">%d</xliff:g> ක් තුළ"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_minutes">
+    <item quantity="one" msgid="562786149928284878">"මිනිත්තු 1 ක් තුළ"</item>
+    <item quantity="other" msgid="4216113292706568726">"මිනිත්තු <xliff:g id="COUNT">%d</xliff:g> ක් තුළ"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_hours">
+    <item quantity="one" msgid="3274708118124045246">"පැය 1 ක් තුළ"</item>
+    <item quantity="other" msgid="3705373766798013406">"පැය <xliff:g id="COUNT">%d</xliff:g> ක් තුළ"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_days">
+    <item quantity="one" msgid="2178576254385739855">"හෙට"</item>
+    <item quantity="other" msgid="2973062968038355991">"දින <xliff:g id="COUNT">%d</xliff:g> ක් තුළ"</item>
+  </plurals>
+    <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>
+    <string name="days" msgid="4774547661021344602">"දින"</string>
+    <string name="hour" msgid="2126771916426189481">"පැය"</string>
+    <string name="hours" msgid="894424005266852993">"පැය"</string>
+    <string name="minute" msgid="9148878657703769868">"min"</string>
+    <string name="minutes" msgid="5646001005827034509">"මිනිත්තු"</string>
+    <string name="second" msgid="3184235808021478">"තත්"</string>
+    <string name="seconds" msgid="3161515347216589235">"තත්පර"</string>
+    <string name="week" msgid="5617961537173061583">"සතිය"</string>
+    <string name="weeks" msgid="6509623834583944518">"සති"</string>
+    <string name="year" msgid="4001118221013892076">"අවුරුද්ද"</string>
+    <string name="years" msgid="6881577717993213522">"අවුරුදු"</string>
+  <plurals name="duration_seconds">
+    <item quantity="one" msgid="6962015528372969481">"තත්පර 1"</item>
+    <item quantity="other" msgid="1886107766577166786">"තත්පර <xliff:g id="COUNT">%d</xliff:g>"</item>
+  </plurals>
+  <plurals name="duration_minutes">
+    <item quantity="one" msgid="4915414002546085617">"මිනිත්තු 1"</item>
+    <item quantity="other" msgid="3165187169224908775">"මිනිත්තු <xliff:g id="COUNT">%d</xliff:g>"</item>
+  </plurals>
+  <plurals name="duration_hours">
+    <item quantity="one" msgid="8917467491248809972">"පැය 1"</item>
+    <item quantity="other" msgid="3863962854246773930">"පැය <xliff:g id="COUNT">%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_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>
+    <string name="midnight" msgid="7166259508850457595">"මධ්‍යම රාත්‍රිය"</string>
+    <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="cut" msgid="3092569408438626261">"කපන්න"</string>
+    <string name="copy" msgid="2681946229533511987">"පිටපත් කරන්න"</string>
+    <string name="paste" msgid="5629880836805036433">"අලවන්න"</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="textSelectionCABTitle" msgid="5236850394370820357">"පෙළ තේරීම"</string>
+    <string name="addToDictionary" msgid="4352161534510057874">"ශබ්ද කෝෂයට එකතු කරන්න"</string>
+    <string name="deleteText" msgid="6979668428458199034">"මකන්න"</string>
+    <string name="inputMethod" msgid="1653630062304567879">"ආදාන ක්‍රමය"</string>
+    <string name="editTextMenuTitle" msgid="4909135564941815494">"පෙළ ක්‍රියාවන්"</string>
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"ආචයනය ඉඩ ප්‍රමාණය අඩු වී ඇත"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"සමහර පද්ධති කාර්යයන් ක්‍රියා නොකරනු ඇත"</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="4653586947747330058">"වැඩිපුර තොරතුරු හෝ යෙදුම නැවතීම සඳහා ස්පර්ශ කරන්න."</string>
+    <string name="ok" msgid="5970060430562524910">"හරි"</string>
+    <string name="cancel" msgid="6442560571259935130">"අවලංගු කරන්න"</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>
+    <string name="capital_on" msgid="1544682755514494298">"සක්‍රීයයි"</string>
+    <string name="capital_off" msgid="6815870386972805832">"අක්‍රිය කරන්න"</string>
+    <string name="whichApplication" msgid="4533185947064773386">"පහත භාවිතයෙන් ක්‍රියාව සම්පූර්ණ කරන්න"</string>
+    <string name="alwaysUse" msgid="4583018368000610438">"මෙම ක්‍රියාව සඳහා සුපුරුද්දෙන් භාවිත කරන්න."</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="aerr_title" msgid="1905800560317137752"></string>
+    <string name="aerr_application" msgid="932628488013092776">"අවාසනාවන්ත ලෙස <xliff:g id="APPLICATION">%1$s</xliff:g> නැවතී ඇත."</string>
+    <string name="aerr_process" msgid="4507058997035697579">"අවාසනාවන්ත ලෙස, <xliff:g id="PROCESS">%1$s</xliff:g> ක්‍රියාවලිය නතර විණි."</string>
+    <string name="anr_title" msgid="4351948481459135709"></string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> ප්‍රතිචාර නොදක්වයි.\n\nඔබට එය නතර කිරීමට අවශ්‍යද?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ක්‍රියාකාරකම ප්‍රතිචාර නොදක්වයි.\n\nඑය වසා දැමීමට ඔබට අවශ්‍යද?"</string>
+    <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> ප්‍රතිචාර නොදක්වයි. එය වසා දැමීමට ඔබට අවශ්‍යද?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"<xliff:g id="PROCESS">%1$s</xliff:g> ක්‍රියාවලිය ප්‍රතිචාර නොදක්වයි.\n\nඔබට එය නතර කිරීමට අවශ්‍යද?"</string>
+    <string name="force_close" msgid="8346072094521265605">"හරි"</string>
+    <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_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; යෙදුම් &gt; බාගන්නා ලදි."</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>
+    <string name="android_upgrading_title" msgid="1584192285441405746">"Android උත්ශ්‍රේණි වෙමින් පවතී..."</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_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="1721681741617898865">"යෙදුමට මාරු වීමට ස්පර්ශ කරන්න"</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>
+    <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="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_silent_ringtone_selected" msgid="8310739960973156272">"නිහඬ රිගින් ටෝනයක් සකසන්න"</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">"බ්ලූටූත් ශබ්ද ත්‍රීවතාව"</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="8129563480895990372">"සුපුරුදු රින්ටෝනය (<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_unknown" msgid="5477919988701784788">"නොදන්නා රින්ටෝනය"</string>
+  <plurals name="wifi_available">
+    <item quantity="one" msgid="6654123987418168693">"Wi-Fi ජාලයක් තිබේ"</item>
+    <item quantity="other" msgid="4192424489168397386">"Wi-Fi ජාල ඇත"</item>
+  </plurals>
+  <plurals name="wifi_available_detailed">
+    <item quantity="one" msgid="1634101450343277345">"විවෘත Wi-Fi ජාලය ලබාගත හැක"</item>
+    <item quantity="other" msgid="7915895323644292768">"විවෘත Wi-Fi ජාල තිබේ"</item>
+  </plurals>
+    <string name="wifi_available_sign_in" msgid="4029489716605255386">"Wi-Fi ජලයට පුරනය වන්න"</string>
+    <string name="network_available_sign_in" msgid="8495155593358054676">"ජාලයට පුරනය වන්න"</string>
+    <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
+    <skip />
+    <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi වෙත සම්බන්ධ විය නොහැක"</string>
+    <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" දුබල අන්තර්ජාල සම්බන්ධතාවයක් ඇත."</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_enabled_notification_message" msgid="1638949953993894335">"සැකසීම් සඳහා ස්පර්ශ කරන්න"</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_to_connect_title" msgid="4958803948658533637">"සම්බන්ධතාවයට ඇරයුමකි"</string>
+    <string name="wifi_p2p_from_message" msgid="570389174731951769">"වෙතින්:"</string>
+    <string name="wifi_p2p_to_message" msgid="248968974522044099">"වෙත:"</string>
+    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"අවශ්‍ය PIN එක ටයිප් කරන්න:"</string>
+    <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</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="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_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="DEST_ADDRESS">%2$s</xliff:g>&lt;b&gt; වෙත කෙටි පණිවීඩයක් යැවීමට &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;b&gt; කැමතිය."</string>
+    <!-- syntax error in translation for sms_short_code_details (3492025719868078457) org.xmlpull.v1.XmlPullParserException: expected: /string read: font (position:END_TAG </font>@1:83 in     <string name="sms_short_code_details" msgid="3492025719868078457">"මෙය "</font>"ඔබගේ ජංගම ගිණුමේ"<font fgcolor="#ffffb060">" අය වීම් වලට හේතුවක් වේ."</string>
+)  -->
+    <string name="sms_premium_short_code_details" msgid="5523826349105123687"><font fgcolor="#ffffb060">"මෙය ඔබගේ ජංගම ගිණුමෙන් අයවීමට හේතු වේ."</font></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_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_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="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_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="usb_storage_activity_title" msgid="4465055157209648641">"USB මහා ආචයනය"</string>
+    <string name="usb_storage_title" msgid="5901459041398751495">"USB සම්බන්ධිතයි"</string>
+    <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"ඔබ ඔබගේ පරිගණකයට සම්බන්ධ වී ඇත්තේ USB ස්පර්ශය හරහාය. ඔබට ඔබේ පරිගණකය හා ඔබගේ Android USB ආචයනය අතර ගොනු පිටපත් කිරීමට අවශ්‍ය නම් පහත බොත්තම ඔබන්න."</string>
+    <string name="usb_storage_message" product="default" msgid="805351000446037811">"ඔබ ඔබගේ පරිගණකයට USB හරහා සම්බන්ධ වී ඇත. ඔබට ඔබේ පරිගණකය හා ඔබගේ Android SD පත අතර ගොනු පිටපත් කිරීමට අවශ්‍ය නම් පහත බොත්තම ස්පර්ශ කරන්න."</string>
+    <string name="usb_storage_button_mount" msgid="1052259930369508235">"USB ආචයනය සක්‍රිය කරන්න"</string>
+    <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"USB මහා ආචයනය සඳහා ඔබගේ USB ආචයනය භාවිතයේදී ගැටළුවක් තිබේ."</string>
+    <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"USB මහා ආචයනය සඳහා ඔබගේ SD පත භාවිතයේදී ගැටළුවක් තිබේ."</string>
+    <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB සම්බන්ධිතයි"</string>
+    <string name="usb_storage_notification_message" msgid="939822783828183763">"ඔබගේ පරිගණකය වෙතට/වෙතින් ගොනු පිටපත් කිරීමට ස්පර්ශ කරන්න."</string>
+    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"USB ආචයනය අක්‍රිය කරන්න"</string>
+    <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"USB ආචයනය අක්‍රිය කිරීමට ස්පර්ශ කරන්න."</string>
+    <string name="usb_storage_stop_title" msgid="660129851708775853">"USB ආචයනය භාවිතයේ පවතී"</string>
+    <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"USB ආචයනය අක්‍රිය කිරීමට පෙර, ඔබගේ පරිගණකයෙන් Android USB ආචයනය ගලවා දමන්න (\"පිට කරන්න\")."</string>
+    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"USB ආචයනය අක්‍රිය කිරීමට පෙර, ඔබගේ Android SD පත පරිගණකයෙන් ගලවන්න."</string>
+    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"USB ආචයනය අක්‍රිය කරන්න"</string>
+    <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"USB ආචයනය අක්‍රිය කිරීමේදී ගැටළුවක් ඇතිවිය. USB සංග්‍රාහකය ගලවා ඇති දැයි පරීක්ෂා කරන්න, පසුව නැවතත් උත්සහ කරන්න."</string>
+    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"USB ආචයනය සක්‍රිය කරන්න"</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"ඔබ USB ආචයනය සක්‍රිය නම්, ඔබ භාවිතා කරන සමහර යෙදුම් නැවතීම සහ ඔබ USB ආචයනය අක්‍රිය කරන තුරු නොතිබේවී."</string>
+    <string name="dlg_error_title" msgid="7323658469626514207">"USB ක්‍රියාවලිය අසාර්ථකයි"</string>
+    <string name="dlg_ok" msgid="7376953167039865701">"හරි"</string>
+    <string name="usb_mtp_notification_title" msgid="3699913097391550394">"මාධ්‍ය උපාංගයක් ලෙස සම්බන්ධිතයි"</string>
+    <string name="usb_ptp_notification_title" msgid="1960817192216064833">"කැමරාවක් ලෙස සම්බන්ධ කර ඇත"</string>
+    <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"ස්ථාපිතයක් ලෙස සම්බන්ධයි"</string>
+    <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB මෙවලමකට සම්බන්ධිතයි"</string>
+    <string name="usb_notification_message" msgid="2290859399983720271">"අනෙක් USB විකල්පය සඳහා ස්පර්ශ කරන්න."</string>
+    <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB ආචයනය ෆෝමැට් කරන්නද?"</string>
+    <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD පත ෆෝමැට් කරන්නද?"</string>
+    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"ඔබගේ USB ආචයනයේ ඇති සියලුම ගොනු මැකී යනු ඇත. මෙම ක්‍රියාව ආපසු හැරවිය නොහැක!"</string>
+    <string name="extmedia_format_message" product="default" msgid="14131895027543830">"ඔබගේ පතේ සියලු දත්ත නැති වනු ඇත."</string>
+    <string name="extmedia_format_button_format" msgid="4131064560127478695">"ෆෝමැට්"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"USB නිදොස්කරණය සම්බන්ධිතයි"</string>
+    <string name="adb_active_notification_message" msgid="1016654627626476142">"USB නිදොස්කරණය අබල කිරීමට ස්පර්ශ කරන්න."</string>
+    <string name="select_input_method" msgid="4653387336791222978">"ආදාන ක්‍රමයක් තෝරන්න"</string>
+    <string name="configure_input_methods" msgid="9091652157722495116">"ආදාන ක්‍රම සකසන්න"</string>
+    <string name="use_physical_keyboard" msgid="6203112478095117625">"භෞතික යතුරු පුවරුව"</string>
+    <string name="hardware" msgid="7517821086888990278">"දෘඨාංග"</string>
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"යතුරු පුවරුවට පිරිසැලැස්ම තෝරන්න"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"යතුරු පුවරුවට පිරිසැලැස්මක් තේරීමට ස්පර්ශ කරන්න."</string>
+    <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="candidates_style" msgid="4333913089637062257"><u>"අපේක්ෂකයන්"</u></string>
+    <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"USB ආචයනය සකසමින්"</string>
+    <string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"SD පත සුදානම් කරමින්"</string>
+    <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"වැරදි සඳහා පරීක්ෂා කරමින්."</string>
+    <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"හිස් USB ආචයනය"</string>
+    <string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"හිස් SD පත"</string>
+    <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"SD පත හිස් හෝ සහාය නොදක්වන ගොනු පද්ධතියක් ඇත."</string>
+    <string name="ext_media_nofs_notification_message" product="default" msgid="8641065641786923604">"SD පත හිස් හෝ සහය නොදක්වන ගොනු පද්ධතියක් ඇත"</string>
+    <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"හානි වූ USB ආචයනය"</string>
+    <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"හානි වූ SD පත"</string>
+    <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="1795917578395333280">"USB ආචයනයට හානි වී ඇත. එය නැවත ෆෝමැට් ගැන්වීමට උත්සහ කරන්න."</string>
+    <string name="ext_media_unmountable_notification_message" product="default" msgid="1753898567525568253">"SD පතට හානි වී ඇත. එය නැවත ෆෝමැට් ගැන්වීමට උත්සහ කරන්න."</string>
+    <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"බලාපොරොත්තු නොවූ ලෙස USB ආචයනය ඉවත් කෙරිණි"</string>
+    <string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"SD පත බලාපොරොත්තු රහිතව ඉවත් කරන ලදි"</string>
+    <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"දත්ත නැතිවීම වැළක්වීමට USB ආචයනය ඉවත්කිරීමට පෙර ගලවන්න."</string>
+    <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"දත්ත නැතිවීම වැළක්වීමට ගැලවීමට කලින් SD පත ඉවත් කරන්න."</string>
+    <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"ඉවත් කිරීමට USB ආචයනය ආරක්ෂිතයි"</string>
+    <string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"SD පත ඉවත් කිරීමට සුරක්ෂිතයි"</string>
+    <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"ඔබට USB ආචයනය ආරක්ෂිතව ඉවත් කිරීමට පුළුවනි."</string>
+    <string name="ext_media_safe_unmount_notification_message" product="default" msgid="568841278138377604">"ඔබට ආරක්ෂිතව SD පත ඉවත් කළ හැක"</string>
+    <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"USB ආචයනය ඉවත් කරන ලදි"</string>
+    <string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"SD පත ඉවත් කර ඇත"</string>
+    <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"USB ආචයනය ඉවත්කොට ඇත. අලුත් මාධ්‍යයක් ඇතුළත් කරන්න."</string>
+    <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"SD පත ඉවත් කරන ලදි. අලුත් එකක් ඇතුළත් කරන්න."</string>
+    <string name="activity_list_empty" msgid="1675388330786841066">"ගැලපෙන ක්‍රියාකාරකම් හමු නොවුණි."</string>
+    <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"සංරචකය භාවිත කිරීමේ සංඛ්‍යාන යාවත්කාලීන කරන්න"</string>
+    <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"එකතු කරන ලද සංරචකය භාවිතා සංඛ්‍යාන වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. සාමාන්‍ය යෙදුම් සඳහා නොවේ."</string>
+    <string name="permlab_copyProtectedData" msgid="4341036311211406692">"අන්තර්ගතය පිටපත් කරන්න"</string>
+    <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"අන්තර්ගතය පිටපත් කිරීමට සුපුරුදු අන්තර්ගත සේවාව ඉල්වා සිටීමට යෙදුමට අවසර දෙන්න. සාමාන්‍ය යෙදුම්වල භාවිතය සඳහා නොවේ."</string>
+    <string name="permlab_route_media_output" msgid="1642024455750414694">"මාධ්‍ය ප්‍රතිදානයේ මාර්ගගත කිරීම"</string>
+    <string name="permdesc_route_media_output" msgid="4932818749547244346">"වෙනත් බාහිර උපාංග වෙත මාධ්‍ය ප්‍රතිදානය යැවීමට යෙදුමට අවසර දෙන්න."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"යතුරු පාලක ආරක්‍ෂිත ආචයනය වෙත ප්‍රවේශය"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"යතුරු ආරක්ෂක ආචයනයට ප්‍රවේශ වීමට යෙදුමට දෙයි."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"පෙන්වීමේ හා සැඟවීමේ යතුරු ආරක්ෂකය පාලනය කරන්න"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"යතුරු ආරක්ෂකය පාලනයට යෙදුමකට අවසර දෙන්න."</string>
+    <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"විශාලන පාලනය සඳහා දෙවරක් ස්පර්ශ කරන්න"</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>
+    <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_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="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>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"බිතුපත වෙනස් කරන්න"</string>
+    <string name="notification_listener_binding_label" msgid="2014162835481906429">"දැනුම්දීම් අසන්නා"</string>
+    <string name="vpn_title" msgid="19615213552042827">"VPN ක්‍රියාත්මකයි"</string>
+    <string name="vpn_title_long" msgid="6400714798049252294">"<xliff:g id="APP">%s</xliff:g> මඟින් VPN සක්‍රීය කරන ලදි"</string>
+    <string name="vpn_text" msgid="3011306607126450322">"ජාලය කළමනාකරණය කිරීමට ස්පර්ශ කරන්න."</string>
+    <string name="vpn_text_long" msgid="6407351006249174473">"<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_error" msgid="6009249814034708175">"සැමවිට සක්‍රිය VPN දෝෂය"</string>
+    <string name="vpn_lockdown_config" msgid="6415899150671537970">"වින්‍යාස කිරීමට ස්පර්ශ කරන්න"</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="8035230537563503262">"මෝටර් රථ ආකාරයෙන් පිටවීමට ස්පර්ශ කරන්න."</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"ටෙදරින් හෝ හොට්ස්පොට් සක්‍රීයයි"</string>
+    <string name="tethered_notification_message" msgid="6857031760103062982">"සකස් කිරීමට ස්පර්ශ කරන්න."</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="throttle_warning_notification_title" msgid="4890894267454867276">"ඉහළ ජංගම දත්ත භාවිතය"</string>
+    <string name="throttle_warning_notification_message" msgid="3340822228599337743">"ජංගම දත්ත භාවිතය ගැන තව දැනගැනීමට ස්පර්ශ කරන්න."</string>
+    <string name="throttled_notification_title" msgid="6269541897729781332">"ජංගම දත්ත සීමාව ඉක්මවා ඇත"</string>
+    <string name="throttled_notification_message" msgid="5443457321354907181">"ජංගම දත්ත භාවිතය ගැන තව දැනගැනීමට ස්පර්ශ කරන්න."</string>
+    <string name="no_matches" msgid="8129421908915840737">"ගැලපීම් නැත"</string>
+    <string name="find_on_page" msgid="1946799233822820384">"පිටුවෙහි සෙවීම"</string>
+  <plurals name="matches_found">
+    <item quantity="one" msgid="8167147081136579439">"ගැළපීම් 1 යි"</item>
+    <item quantity="other" msgid="4641872797067609177">"<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="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"USB ආචයනය ගැලවීම..."</string>
+    <string name="progress_unmounting" product="default" msgid="1327894998409537190">"SD පත ගලවමින්..."</string>
+    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"USB ආචයනය මකමින්..."</string>
+    <string name="progress_erasing" product="default" msgid="6596988875507043042">"SD පත මකමින්..."</string>
+    <string name="format_error" product="nosdcard" msgid="6299769563624776948">"USB ආචයනය මැකිය නොහැක."</string>
+    <string name="format_error" product="default" msgid="7315248696644510935">"SD පත මැකීමට නොහැකි විය."</string>
+    <string name="media_bad_removal" msgid="7960864061016603281">"ගැලවීමට පෙර SD පත ඉවත්කර ඇත."</string>
+    <string name="media_checking" product="nosdcard" msgid="418188720009569693">"USB ආචයනය මේ වනවිට පරීක්ෂා කරමින් පවතී."</string>
+    <string name="media_checking" product="default" msgid="7334762503904827481">"SD පත දැන් පරීක්ෂා කරමින් පවතී."</string>
+    <string name="media_removed" msgid="7001526905057952097">"SD පත ඉවත් කර ඇත."</string>
+    <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"පරිගණකයක් විසින් දැන් USB ආචයනය භාවිතා කරයි."</string>
+    <string name="media_shared" product="default" msgid="5706130568133540435">"SD පත දැනට පරිගණකයකින් පාවිච්චි කරයි."</string>
+    <string name="media_unknown_state" msgid="729192782197290385">"බාහිර මාධ්‍යය නොදන්නා අවස්ථාවේ පවතියි."</string>
+    <string name="share" msgid="1778686618230011964">"බෙදාගන්න"</string>
+    <string name="find" msgid="4808270900322985960">"සොයන්න"</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="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_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>
+    <string name="add_account_button_label" msgid="3611982894853435874">"ගිණුමක් එකතු කරන්න"</string>
+    <string name="number_picker_increment_button" msgid="2412072272832284313">"වැඩි කරන්න"</string>
+    <string name="number_picker_decrement_button" msgid="476050778386779067">"අඩු කරන්න"</string>
+    <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> ස්පර්ශ කර රඳවා සිටින්න."</string>
+    <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"වැඩි කිරීමට ඉහලට සර්පණය කරන්න සහ අඩු කිරීමට පහලට සර්පණය කරන්න."</string>
+    <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"මිනිත්තුවක් වැඩි කරන්න"</string>
+    <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"මිනිත්තුව අඩු කරන්න"</string>
+    <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"පැය වැඩිකරන්න"</string>
+    <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"පැය අඩුකරන්න"</string>
+    <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"ප.ව.සකසන්න"</string>
+    <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"පෙ.ව. සකස් කිරීම"</string>
+    <string name="date_picker_increment_month_button" msgid="5369998479067934110">"මාසය වැඩි කරන්න"</string>
+    <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"මාසයක් අඩු කරන්න"</string>
+    <string name="date_picker_increment_day_button" msgid="7130465412308173903">"දවස වැඩි කරන්න"</string>
+    <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"දවස අඩු කරන්න"</string>
+    <string name="date_picker_increment_year_button" msgid="6318697384310808899">"වසර වැඩි කරන්න"</string>
+    <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"වසර අඩු කරන්න"</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_enter" msgid="2985864015076059467">"ඇතුල් කරන්න"</string>
+    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"යෙදුමක් තෝරන්න"</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">"සර්පණ හැඩලය. ස්පර්ශ කර රඳවා සිටීම."</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> සඳහා උඩට සර්පණය කරන්න."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"<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="description_direction_right" msgid="8034433242579600980">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> සඳහා දකුණට සර්පණය කරන්න."</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"අඟුල අරින්න"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"කැමරාව"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"නිහඬ"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"ශබ්ද සක්‍රීය කරන්න"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"සෙවීම"</string>
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"අගුළු ඇරීමට ස්වයිප් කරන්න."</string>
+    <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"මුරපද යතුරු කියවනු ඇසීමට ඉස් බණුවක් සම්බන්ධ කරන්න."</string>
+    <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"නැවතුම."</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="4891916833657929263">"අභ්‍යන්තර ආචයනය"</string>
+    <string name="storage_sd_card" msgid="3282948861378286745">"SD පත"</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="1955638862122232342">"දත්ත භාවිතා අවවාදය"</string>
+    <string name="data_usage_warning_body" msgid="2814673551471969954">"භාවිතය සහ සැකසීම් බැලීමට ස්පර්ශ කරන්න."</string>
+    <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-3G දත්ත අබලයි"</string>
+    <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G දත්ත අබල කරන ලදි"</string>
+    <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"ජංගම දත්ත අබල කර ඇත"</string>
+    <string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"Wi-Fi දත්ත අබල කරන ලදි"</string>
+    <string name="data_usage_limit_body" msgid="3317964706973601386">"සබල කිරීමට ස්පර්ශ කරන්න."</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_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="6741521330997452990">"සීමා කිරීම ඉවත් කිරීමට ස්පර්ශ කරන්න"</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>
+    <string name="org_unit" msgid="7265981890422070383">"සංවිධානාත්මක ඒකකය:"</string>
+    <string name="issued_by" msgid="2647584988057481566">"ලබාදෙන ලද්දේ:"</string>
+    <string name="validity_period" msgid="8818886137545983110">"වලංගුතාවය:"</string>
+    <string name="issued_on" msgid="5895017404361397232">"නිකුත් කරන ලද්දේ:"</string>
+    <string name="expires_on" msgid="3676242949915959821">"කල් ඉකුත් වන්නේ:"</string>
+    <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>
+    <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"සියල්ල බලන්න"</string>
+    <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"ක්‍රියාකාරකම තෝරන්න"</string>
+    <string name="share_action_provider_share_with" msgid="5247684435979149216">"සමඟ බෙදාගන්න"</string>
+    <string name="status_bar_device_locked" msgid="3092703448690669768">"උපාංගයට අගුළු වැටි ඇත."</string>
+    <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="3245653681008218030">"යවමින්..."</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="default_audio_route_name" product="tablet" msgid="4617053898167127471">"ටැබ්ලට්ය"</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">"බ්ලූටූත් ශ්‍රව්‍ය"</string>
+    <string name="wireless_display_route_description" msgid="9070346425023979651">"රැහැන් රහිත දර්ශනය"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"හරි"</string>
+    <string name="media_route_button_content_description" msgid="5758553567065145276">"මාධ්‍ය ප්‍රතිදානය"</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>
+    <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_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="wifi_display_notification_title" msgid="2223050649240326557">"නොරැහැන් සංදර්ශකය සම්බන්ධිතයි"</string>
+    <string name="wifi_display_notification_message" msgid="4498802012464170685">"වෙනත් උපාංගයක් මත මෙම තිරය පෙන්වයි"</string>
+    <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"විසන්ධි කරන්න"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"හදිසි ඇමතුම"</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">"PIN එක වැරදියි"</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">"SIM PIN ඇතුලු කරන්න"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN එක ඇතුළු කරන්න"</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">"අපේක්ෂිත PIN කේතය ඇතුළත් කරන්න"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"අපේක්ෂිත PIN කේතය ස්ථිර කරන්න"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM පත අගුළු අරිමින්..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"වැරදි PIN කේතයකි."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"අංක 4 සිට 8 අතර වන PIN එකක් ටයිප් කරන්න."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK කේතය සංඛ්‍යා 8 ක් හෝ වැඩි විය යුතුය."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"නිවැරදි PUK කේතය නැවත ඇතුලත් කරන්න. නැවත නැවත උත්සාහ කිරීමෙන් SIM එක ස්ථිරවම අබල කරයි."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN කේත ගැලපී නැත"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"රටා උත්සාහ කිරීම් වැඩිය"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"අගුළු ඇරීමට, ඔබගේ Google ගිණුම සමග පුරනය වන්න."</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"ගිණුම පරීක්ෂා කරමින්…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"ඔබ PIN අංකය <xliff:g id="NUMBER_0">%d</xliff:g> වාරයක් වැරදියට ටයිප් කොට ඇත.\n\n තත්පර <xliff:g id="NUMBER_1">%d</xliff:g> ක් ඇතුළත නැවත උත්සාහ කරන්න."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"<xliff:g id="NUMBER_0">%d</xliff:g> වතාවක් ඔබගේ මුරපදය ඔබ වැරදියට ටයිප් කර ඇත. \n\nතත්පර <xliff:g id="NUMBER_1">%d</xliff:g> ට පසුව නැවත උත්සහ කරන්න."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"ඔබ <xliff:g id="NUMBER_0">%d</xliff:g> වාරයක් අගුළු ඇරීමේ රටාව වැරදියට ඇඳ ඇත. \n\nතත්පර <xliff:g id="NUMBER_1">%d</xliff:g> ක් ඇතුළත නැවත උත්සාහ කරන්න."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"ඔබ ටැබ්ලටය අගුළු හැරීමට වැරදියට අවස්ථා <xliff:g id="NUMBER_0">%d</xliff:g> ක් උත්සාහ කර ඇත. අවස්ථා <xliff:g id="NUMBER_1">%d</xliff:g> ක් අසාර්ථකව උත්සහ කිරීමකින් පසුව, කර්මාන්ත ශාලා මුල් තත්වයට නැවත පත් වන අතර සියලු පරිශීලක දත්ත නැති වෙයි."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"ඔබ දුරකථනය අගුළු ඇරීමට වාර <xliff:g id="NUMBER_0">%d</xliff:g> කදී වැරදී ප්‍රයත්නයන් ගෙන තිබේ. තවත් අසාර්ථක ප්‍රයත්න <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> වතාවක් වැරදියට ඇඳ ඇත. තවත් අසාර්ථක උත්සාහ <xliff:g id="NUMBER_1">%d</xliff:g> කින් පසුව, ඊ-තැපැල් ගිණුම භාවිතා කරමින් ඔබගේ ටැබ්ලටයේ අගුළු ඇරීමට ඔබට පවසනු ඇත.\n\n නැවත තත්පර <xliff:g id="NUMBER_2">%d</xliff:g> කින් උත්සාහ කරන්න."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"ඔබ වැරදියට <xliff:g id="NUMBER_0">%d</xliff:g> වතාවක් ඔබගේ අගුළු හැරීමේ රටාව ඇඳ ඇත. අසාර්ථක උත්සහ කිරීම් <xliff:g id="NUMBER_1">%d</xliff:g> න් පසුව, ඔබගේ ඊ-තැපැල් ලිපිනය භාවිතයෙන් ඔබගේ දුරකථනය අගුළු හැරීමට ඔබගෙන් අසයි.\n\n තත්පර <xliff:g id="NUMBER_2">%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="7324161939475478066">"නිර්දේශිත මට්ටමෙන් ඉහළට ශබ්දය වැඩි කරනවද?\nවැඩි කාලයක් ඉහළ ශබ්දයක් ශ්‍රවනය කිරීමෙන් ඔබගේ ශ්‍රවනයට හානි විය හැක."</string>
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"ප්‍රවේශ්‍යතාවය සබල කිරීමට ඇඟිලි දෙකක් පහළට රඳවා සිටින්න."</string>
+    <string name="accessibility_enabled" msgid="1381972048564547685">"ප‍්‍රවේශ්‍යතාව සබල කරන ලදි."</string>
+    <string name="enable_accessibility_canceled" msgid="3833923257966635673">"ප‍්‍රවේශ්‍යතාව අවලංගු කර ඇත."</string>
+    <string name="user_switched" msgid="3768006783166984410">"දැනට සිටින පරිශීලකයා <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="app_no_restricted_accounts" msgid="5739463249673727736">"සීමා සහිත පැතිකඩ සඳහා වන ගිණුම් වෙත මෙම යෙදුම සහය නොදක්වයි"</string>
+    <string name="app_not_found" msgid="3429141853498927379">"මෙම ක්‍රියාව හසුරුවීමට යෙදුමක් සොයාගත්තේ නැත"</string>
+    <string name="revoke" msgid="5404479185228271586">"අහෝසි කරන්න"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"අකුරු"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"රජයේ ලිපිය"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"නීත්‍යනුකූල"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"ප්‍රාථමික නීතිමය"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"ලෙජරය"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"කුඩා පුවත්පත"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"අවලංගු කරන ලදි"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"අන්තර්ගතය ලිවීමේදී දෝෂයකි"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN එක ඇතුළු කරන්න"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"වත්මන් PIN"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"නව PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"නව PIN තහවුරු කරන්න"</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_too_short" msgid="8173982756265777792">"PIN කුඩා වැඩිය. ඉලක්කම් 4 වත් විය යුතුය."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="4835639969503729874">"වැරදි PIN. තත්පරයකින් නැවත උත්සහ කරන්න."</item>
+    <item quantity="other" msgid="8030607343223287654">"වැරදි PIN. තත්පර <xliff:g id="COUNT">%d</xliff:g> කින් නැවත උත්සහ කරන්න."</item>
+  </plurals>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"තීරුව අනාවරණයට තිරයේ කෙලවර අදින්න"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"පද්ධති තීරුව අනාවරණයට තිරයේ කෙලවරින් අදින්න"</string>
+</resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index b7dcd07..500ced4 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -131,6 +131,11 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Príliš veľa odstránených položiek služby <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Ukladací priestor tabletu je plný. Odstráňte niektoré súbory a uvoľnite miesto."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Pamäť telefónu je plná. Odstráňte niektoré súbory a uvoľnite miesto."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Sieť môže byť monitorovaná"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Ja"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Možnosti tabletu"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Možnosti telefónu"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Umožňuje aplikácii presunúť úlohy do popredia alebo do pozadia. Aplikácia tak môže urobiť bez vášho zásahu."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"zastaviť spustené aplikácie"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Umožňuje aplikácii odstrániť úlohy a ukončiť ich aplikácie. Škodlivé aplikácie môžu narušiť správanie iných aplikácií."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"spravovanie zoskupení aktivít"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Umožňuje aplikácii pridať, odstrániť alebo upraviť zoskupenia aktivít, v ktorých sú spustené ostatné aplikácie. Škodlivé aplikácie môžu narušiť správanie ostatných aplikácií."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"spustiť ľubovoľnú aktivitu"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Umožňuje aplikácii spustiť ľubovoľnú aktivitu bez ohľadu na ochranu povolení alebo exportovaný stav."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"nastaviť kompatibilitu obrazovky"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania metódy vstupu. Bežné aplikácie by toto nastavenie nemali nikdy potrebovať."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"viazať na službu zjednodušeného ovládania"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania služby zjednodušeného ovládania. Bežné aplikácie by toto nastavenie nemali nikdy potrebovať."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"viazanie na tlačovú službu"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania tlačovej služby. Bežné aplikácie by toto povolenie nemali nikdy potrebovať."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"väzba na tlačovú službu"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania tlačovej služby. Bežné aplikácie by toto povolenie nemali nikdy potrebovať."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"previazať so službou NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Umožňuje držiteľovi previazať sa s aplikáciami, ktoré vydávajú karty NFC. Bežné aplikácie toto povolenie nikdy nepotrebujú."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"väzba na textovú službu"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania textovej služby (napr. SpellCheckerService). Bežné aplikácie by toto nastavenie nemali nikdy potrebovať."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"Zaviazať k službe VPN"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania služby miniaplikácií. Bežné aplikácie by toto nastavenie nemali nikdy potrebovať."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"komunikovať so správcom zariadenia"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Umožňuje držiteľovi odosielať informácie správcovi zariadenia. Bežné aplikácie by toto nastavenie nemali nikdy potrebovať."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"pridanie alebo odstránenie správcu zariadenia"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Umožňuje držiteľovi pridať alebo odstrániť správcov aktívnych zariadení. Bežné aplikácie by toto povolenie nemali nikdy potrebovať."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"zmena orientácie obrazovky"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Umožňuje aplikácii kedykoľvek zmeniť otáčanie obrazovky. Bežné aplikácie by toto nastavenie nemali nikdy potrebovať."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"zmena rýchlosti ukazovateľa"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Umožňuje aplikácii čítať rôzne systémové súbory denníkov. Toto nastavenie aplikácii umožňuje získať všeobecné informácie o činnostiach s telefónom, ktoré by mohli obsahovať osobné alebo súkromné informácie."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"použiť ľubovoľný dekódovač médií na reprodukciu"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Umožňuje aplikácii používať na reprodukciu ľubovoľný nainštalovaný dekódovač na dekódovanie."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"spravovať dôveryhodné poverenia"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Umožňuje aplikácii inštalovať a odinštalovať certifikáty CA ako dôveryhodné poverenia."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"čítanie alebo zápis do prostriedkov funkcie diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Umožňuje aplikácii čítať ľubovoľné prostriedky v skupine diag, napr. súbory v priečinku /dev, a zapisovať do nich. Môže dôjsť k ovplyvneniu stability a bezpečnosti systému. Toto nastavenie by mal používať IBA výrobca či operátor na diagnostiku hardvéru."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"povoliť alebo zakázať súčasti aplikácie"</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Umožňuje aplikácii konfigurovať displeje a pripojiť sa k nim cez siete Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"ovládať displeje cez sieť Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Umožňuje aplikácii ovládať základné funkcie displejov cez siete Wi-Fi."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"zachytiť výstup zvuku"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Umožňuje aplikácii zachytiť a presmerovať výstup zvuku."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"zachytiť výstup videa"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Umožňuje aplikácii zachytiť a presmerovať výstup videa."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"zachytiť zabezpečený výstup videa"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Umožňuje aplikácii zachytiť a presmerovať zabezpečený výstup videa."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"zmeny vašich nastavení 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">"záznam zvuku"</string>
@@ -525,6 +552,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"zabránenie prechodu telefónu do režimu spánku"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Umožňuje aplikácii zabrániť prechodu tabletu do režimu spánku."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Umožňuje aplikácii zabrániť prechodu telefónu do režimu spánku."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"zapnutie a vypnutie tabletu"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"zapnutie a vypnutie telefónu"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Umožňuje aplikácii zapnúť a vypnúť tablet."</string>
@@ -613,6 +646,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Umožňuje aplikácii zápis na kartu SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"úprava alebo odstránenie obsahu interného ukladacieho priestoru média"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Umožňuje aplikácii zmeniť obsah interného ukladacieho priestoru média."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"správa ukladacieho priestoru dokumentov"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Umožňuje aplikácii spravovať ukladací priestor dokumentov."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"pristupovať k externému ukladaciemu priestoru pre všetkých používateľov"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Umožňuje aplikácii pristupovať k externému ukladaciemu priestoru pre všetkých používateľov."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"pristupovať do súborového systému vyrovnávacej pamäte"</string>
@@ -625,10 +660,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Umožňuje aplikácii spravovať pravidlá siete a definovať pravidlá pre konkrétnu aplikáciu."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"zmeniť kontrolu používania siete"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Umožňuje aplikácii upraviť používanie siete jednotlivými aplikáciami. Bežné aplikácie toto nastavenie nepoužívajú."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"upravenie značiek soketov"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Umožňuje aplikácii upraviť značky soketov pre smerovanie"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"prístup k upozorneniam"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Umožňuje aplikácii načítať, zobrazovať a mazať upozornenia vrátane tých, ktoré boli uverejnené inými aplikáciami."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"naviazanie sa na službu na počúvanie upozornení"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Umožňuje držiteľovi naviazať sa na najvyššiu úroveň služby na počúvanie upozornení. Bežné aplikácie by toto nastavenie nemali nikdy požadovať."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"vyvolanie aplikácie pre konfiguráciu poskytnutú operátorom"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Umožňuje držiteľovi vyvolať aplikáciu pre konfiguráciu poskytnutú operátorom. Bežné aplikácie by toto povolenie nemali nikdy potrebovať."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"zachytávať informácie o stave siete"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Umožňuje aplikácii zachytávať informácie o stave siete. Bežné aplikácie by toto povolenie nemali nikdy potrebovať."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Nastaviť pravidlá pre heslo"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Ovládanie dĺžky hesiel na odomknutie obrazovky a v nich používané znaky."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Sledovať pokusy o odomknutie obrazovky"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +836,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Vložte kartu SIM."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Karta SIM chýba alebo sa z nej nedá čítať. Vložte kartu SIM."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Karta SIM je nepoužiteľná."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Vaša karta SIM bola natrvalo zakázaná."\n"Ak chcete získať inú kartu SIM, kontaktujte svojho operátora."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Vaša karta SIM bola natrvalo zakázaná.\nAk chcete získať inú kartu SIM, kontaktujte svojho operátora."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Tlačidlo Predchádzajúca stopa"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Tlačidlo Ďalšia stopa"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Tlačidlo Pozastaviť"</string>
@@ -808,11 +848,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Prečítajte si Príručku používateľa alebo kontaktujte podporu zákazníka."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Karta SIM je uzamknutá."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Prebieha odomykanie karty SIM..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste použili nesprávny bezpečnostný vzor. "\n\n"Skúste to znova o <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste zadali nesprávne heslo. "\n\n"Skúste to znova o <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste zadali nesprávny kód PIN. "\n\n"Skúste to znova o <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste nesprávne nakreslili svoj bezpečnostný vzor. Po ďalších neúspešných pokusoch (<xliff:g id="NUMBER_1">%d</xliff:g>) budete vyzvaní odomknúť tablet pomocou prihlasovacích údajov služby Google."\n\n" Skúste to znova o <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste nesprávne nakreslili svoj bezpečnostný vzor. Po <xliff:g id="NUMBER_1">%d</xliff:g> ďalších neúspešných pokusoch sa zobrazí výzva na odomknutie telefónu pomocou prihlasovacích údajov Google."\n\n" Skúste to znova o <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste použili nesprávny bezpečnostný vzor. \n\nSkúste to znova o <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste zadali nesprávne heslo. \n\nSkúste to znova o <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste zadali nesprávny kód PIN. \n\nSkúste to znova o <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste nesprávne nakreslili svoj bezpečnostný vzor. Po ďalších neúspešných pokusoch (<xliff:g id="NUMBER_1">%d</xliff:g>) budete vyzvaní odomknúť tablet pomocou prihlasovacích údajov služby Google.\n\n Skúste to znova o <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste nesprávne nakreslili svoj bezpečnostný vzor. Po <xliff:g id="NUMBER_1">%d</xliff:g> ďalších neúspešných pokusoch sa zobrazí výzva na odomknutie telefónu pomocou prihlasovacích údajov Google.\n\n Skúste to znova o <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Tablet ste sa pokúsili odomknúť nesprávnym spôsobom <xliff:g id="NUMBER_0">%d</xliff:g>-krát. Po <xliff:g id="NUMBER_1">%d</xliff:g> ďalších neúspešných pokusoch sa v tablete obnovia predvolené továrenské nastavenia a všetky používateľské údaje budú stratené."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Telefón ste sa pokúsili odomknúť nesprávnym spôsobom <xliff:g id="NUMBER_0">%d</xliff:g>-krát. Po <xliff:g id="NUMBER_1">%d</xliff:g> ďalších neúspešných pokusoch sa v telefóne obnovia predvolené továrenské nastavenia a všetky používateľské údaje budú stratené."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Tablet ste sa pokúsili odomknúť nesprávnym spôsobom <xliff:g id="NUMBER">%d</xliff:g>-krát. V tablete sa teraz obnovia predvolené továrenské nastavenia."</string>
@@ -826,7 +866,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Heslo"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Prihlásiť sa"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Neplatné používateľské meno alebo heslo."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Zabudli ste používateľské meno alebo heslo?"\n"Navštívte stránky "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Zabudli ste používateľské meno alebo heslo?\nNavštívte stránky "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Prebieha kontrola…"</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Odomknúť"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Zapnúť zvuk"</string>
@@ -874,7 +914,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Potvrďte prechod"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Opustiť stránku"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Zostať na tejto strane"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Naozaj chcete túto stránku opustiť?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nNaozaj chcete túto stránku opustiť?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Potvrdiť"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Tip: Dvojitým klepnutím môžete zobrazenie priblížiť alebo oddialiť."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Aut.dop."</string>
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"Aplikácia <xliff:g id="APPLICATION">%1$s</xliff:g> bohužiaľ prestala pracovať."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> bohužiaľ prestal pracovať."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"Aplikácia <xliff:g id="APPLICATION">%2$s</xliff:g> neodpovedá."\n\n"Chcete ju zavrieť?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Aktivita <xliff:g id="ACTIVITY">%1$s</xliff:g> neodpovedá."\n\n"Chcete ju zavrieť?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"Aplikácia <xliff:g id="APPLICATION">%2$s</xliff:g> neodpovedá.\n\nChcete ju zavrieť?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Aktivita <xliff:g id="ACTIVITY">%1$s</xliff:g> neodpovedá.\n\nChcete ju zavrieť?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"Aplikácia <xliff:g id="APPLICATION">%1$s</xliff:g> neodpovedá. Chcete ju zavrieť?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> neodpovedá. "\n\n"Chcete ho zavrieť?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> neodpovedá. \n\nChcete ho zavrieť?"</string>
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"Prehľad"</string>
     <string name="wait" msgid="7147118217226317732">"Čakajte"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"Stránka nereaguje."\n\n"Chcete ju zavrieť?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Stránka nereaguje.\n\nChcete ju zavrieť?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Presmerovaná aplikácia"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"Je spustená aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"Pôvodne bola spustená aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
@@ -1256,6 +1296,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Umožňuje volať predvolenú službu kontajnera na skopírovanie obsahu. Bežné aplikácie toto nastavenie nepoužívajú."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Smerovanie výstupu médií"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Umožňuje aplikácii smerovať výstup médií do ďalších externých zariadení."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Prístup k ukladaciemu priestoru zabezpečenému technológiou keyguard"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Umožňuje aplikácii získať prístup k ukladaciemu priestoru zabezpečenému technológiou keyguard."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Ovládanie zobrazenia alebo skrytia technológie keyguard"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Umožňuje aplikácii ovládať technológiu keyguard."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Ovládacie prvky lupy zobrazíte dvojitým dotknutím"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Miniaplikáciu sa nepodarilo pridať."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Hľadať"</string>
@@ -1265,15 +1309,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Hotovo"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Predch."</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Vykonať"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Vytočiť číslo"\n" <xliff:g id="NUMBER">%s</xliff:g>."</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Vytvoriť kontakt"\n"pre <xliff:g id="NUMBER">%s</xliff:g>."</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Vytočiť číslo\n <xliff:g id="NUMBER">%s</xliff:g>."</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Vytvoriť kontakt\npre <xliff:g id="NUMBER">%s</xliff:g>."</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Nasledujúce aplikácie vyžadujú povolenie na prístup do vášho účtu (teraz aj v budúcnosti)."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Chcete túto žiadosť povoliť?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Žiadosť o prístup"</string>
     <string name="allow" msgid="7225948811296386551">"Povoliť"</string>
     <string name="deny" msgid="2081879885755434506">"Zamietnuť"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Vyžaduje sa povolenie"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Vyžaduje sa oprávnenie"\n"pre účet <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Vyžaduje sa oprávnenie\npre účet <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Metóda vstupu"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Synchronizovať"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Zjednodušenie"</string>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Zobraziť všetky"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Vybrať aktivitu"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Zdieľať s"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Zariadenie je zamknuté."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Odosielanie..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Spustiť prehliadač?"</string>
@@ -1441,10 +1484,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Prebieha pripájanie…"</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"K dispozícii"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"Nie je k dispozícii"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"Používa sa"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Vstavaná obrazovka"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"Obrazovka HDMI"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Prekrytie č. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", zabezpečené"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Bezdrôtový displej je pripojený"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Táto obrazovka sa zobrazuje na inom zariadení"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Odpojiť"</string>
@@ -1453,7 +1498,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Nesprávny vzor"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Nesprávne heslo"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"Nesprávny kód PIN"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Skúste to znova o <xliff:g id="NUMBER">%d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Skúste to znova o <xliff:g id="NUMBER">%1$d</xliff:g> s."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Nakreslite svoj vzor"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Zadajte kód PIN karty SIM"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Zadajte kód PIN"</string>
@@ -1473,27 +1518,85 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Heslo"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Prihlásiť sa"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Neplatné používateľské meno alebo heslo."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Zabudli ste svoje používateľské meno alebo heslo?"\n" Navštívte stránky "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Zabudli ste svoje používateľské meno alebo heslo?\n Navštívte stránky "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Prebieha kontrola účtu..."</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste zadali nesprávny kód PIN. "\n\n"Skúste to znova o <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste zadali nesprávne heslo. "\n\n"Skúste to znova o <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste použili nesprávny bezpečnostný vzor. "\n\n"Skúste to znova o <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste zadali nesprávny kód PIN. \n\nSkúste to znova o <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste zadali nesprávne heslo. \n\nSkúste to znova o <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste použili nesprávny bezpečnostný vzor. \n\nSkúste to znova o <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tablet ste sa pokúsili odomknúť nesprávnym spôsobom <xliff:g id="NUMBER_0">%d</xliff:g>-krát. Po <xliff:g id="NUMBER_1">%d</xliff:g> ďalších neúspešných pokusoch sa v tablete obnovia predvolené továrenské nastavenia a všetky používateľské údaje budú stratené."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Telefón ste sa pokúsili odomknúť nesprávnym spôsobom <xliff:g id="NUMBER_0">%d</xliff:g>-krát. Po <xliff:g id="NUMBER_1">%d</xliff:g> ďalších neúspešných pokusoch sa v telefóne obnovia predvolené továrenské nastavenia a všetky používateľské údaje budú stratené."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Tablet ste sa pokúsili odomknúť nesprávnym spôsobom <xliff:g id="NUMBER">%d</xliff:g>-krát. V tablete sa teraz obnovia predvolené továrenské nastavenia."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Telefón ste sa pokúsili odomknúť nesprávnym spôsobom <xliff:g id="NUMBER">%d</xliff:g>-krát. V telefóne sa teraz obnovia predvolené továrenské nastavenia."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste nesprávne nakreslili svoj bezpečnostný vzor. Po ďalších <xliff:g id="NUMBER_1">%d</xliff:g> neúspešných pokusoch sa zobrazí výzva na odomknutie tabletu pomocou e-mailového účtu."\n\n" Skúste to znova o <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste nesprávne nakreslili svoj bezpečnostný vzor. Po <xliff:g id="NUMBER_1">%d</xliff:g> ďalších neúspešných pokusoch sa zobrazí výzva na odomknutie telefónu pomocou e-mailového účtu."\n\n" Skúste to znova o <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste nesprávne nakreslili svoj bezpečnostný vzor. Po ďalších <xliff:g id="NUMBER_1">%d</xliff:g> neúspešných pokusoch sa zobrazí výzva na odomknutie tabletu pomocou e-mailového účtu.\n\n Skúste to znova o <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste nesprávne nakreslili svoj bezpečnostný vzor. Po <xliff:g id="NUMBER_1">%d</xliff:g> ďalších neúspešných pokusoch sa zobrazí výzva na odomknutie telefónu pomocou e-mailového účtu.\n\n Skúste to znova o <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Odstrániť"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Zvýšiť hlasitosť nad odporúčanú úroveň?"\n"Dlhodobé počúvanie pri vysokej hlasitosti môže poškodiť váš sluch."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Zvýšiť hlasitosť nad odporúčanú úroveň?\nDlhodobé počúvanie pri vysokej hlasitosti môže poškodiť váš sluch."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Zjednodušenie ovládania povolíte dlhým stlačením dvoma prstami."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Zjednodušenie ovládania je povolené."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Zjednodušenie ovládania bolo zrušené."</string>
     <string name="user_switched" msgid="3768006783166984410">"Aktuálny používateľ je <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Vlastník"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Chyba"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Táto aplikácia nepodporuje účty pre profily s obmedzením"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Táto aplikácia nepodporuje účty pre profily s obmedzením"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Aplikácia potrebná na spracovanie tejto akcie sa nenašla"</string>
     <string name="revoke" msgid="5404479185228271586">"Odvolať"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Zrušené"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Pri zapisovaní obsahu došlo ku chybe"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"neznáme"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Zadajte kód PIN správcu"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Zadajte kód PIN"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Nesprávny kód"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Aktuálny kód PIN"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Nový kód PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Potvrďte nový kód PIN"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Vytvoriť kód PIN pre obmedzenia upravovania"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"Kódy PIN sa nezhodujú. Skúste to znova."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"Kód PIN je príliš krátky. Musí mať minimálne 4 číslice."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Skúste to zas o 1 s"</item>
+    <item quantity="other" msgid="4730868920742952817">"Skúste to zas o <xliff:g id="COUNT">%d</xliff:g> s"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Skúste to znova neskôr"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Panel zobraz. prejdením okraja obr."</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Systémový panel zobrazíte posunutím cez okraj obrazovky"</string>
 </resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 11dc13d..1374366 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -131,6 +131,11 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Preveč izbrisov vsebine <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Pomnilnik tabličnega računalnika je poln. Izbrišite nekaj datotek, da sprostite prostor."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Pomnilnik telefona je poln. Izbrišite nekaj datotek, da sprostite prostor."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Omrežje je lahko nadzorovano"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Jaz"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Možnosti tabličnega računalnika"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Možnosti telefona"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Aplikaciji omogoča premikanje opravil v ospredje in ozadje. Aplikacija lahko to naredi brez vašega nadzora."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"ustavitev programov, ki se izvajajo"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Programu omogoča odstranjevanje opravil in zapiranje njihovih programov. Zlonamerni programi lahko motijo delovanje drugih programov."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"upravljanje skladov dejavnosti"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Aplikaciji omogoča dodajanje, odstranjevanje in spreminjanje skladov dejavnosti, v katerih se izvajajo druge aplikacije. Zlonamerne aplikacije lahko motijo delovanje drugih aplikacij."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"zagon poljubne dejavnosti"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Omogoča aplikaciji zagon poljubne dejavnosti, ne glede na zaščito dovoljenj ali izvoženo stanje."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"nastavitev združljivosti zaslona"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Lastniku omogoča, da se poveže z vmesnikom načina vnosa najvišje ravni. Tega nikoli ni treba uporabiti za navadne programe."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"povezovanje s storitvijo za ljudi s posebnimi potrebami"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Lastniku omogoča povezovanje z vmesnikom najvišje ravni storitve za ljudi s posebnimi potrebami. Tega nikoli ni treba uporabiti za navadne aplikacije."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"povezava s storitvijo tiskanja"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Lastniku omogoča povezovanje z vmesnikom storitve tiskanja najvišje ravni. Tega nikoli ni treba uporabiti za navadne aplikacije."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"povezava s storitvijo čakalne vrste za tiskanje"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Lastniku omogoča povezovanje z vmesnikom storitve čakalne vrste za tiskanje najvišje ravni. Tega nikoli ni treba uporabiti za navadne aplikacije."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"povezava s storitvijo NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Dovoljuje, da se lastnik poveže z aplikacijami, ki posnemajo kartice za NFC. Pri navadnih aplikacijah to ne bi smelo biti potrebno."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"poveži z besedilno storitvijo"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Dovoljuje, da se lastnik poveže z vmesnikom besedilne storitve najvišje ravni (npr. SpellCheckerService). Tega nikoli ni treba uporabiti za navadne programe."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"povezava s storitvijo navideznega zasebnega omrežja"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Lastniku omogoča povezovanje z vmesnikom storitve pripomočka najvišje ravni. Tega ni treba nikoli uporabiti za navadne programe."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interakcija s skrbnikom naprave"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Omogoča lastniku, da pošlje namere skrbniku naprave. Nikoli se ne uporablja za navadne programe."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"dodajanje ali odstranjevanje skrbnikov naprave"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Imetniku omogoča, da doda ali odstrani aktivne skrbnike naprave. Normalne aplikacije tega načeloma ne potrebujejo."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"spreminjanje usmerjenosti zaslona"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Programu omogoča, da kadar koli zasuka zaslon. Ne uporabljajte za navadne programe."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"spreminjanje hitrosti kazalca"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Programu omogoča branje različnih sistemskih dnevniških datotek. To mu omogoča dostop do splošnih podatkov v telefonu, lahko tudi do osebnih podatkov."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"uporaba katerega koli predstavnostnega dekodirnika za predvajanje"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Programu omogoča, da uporabi kateri koli dekodirnik večpredstavnosti za predvajanje."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"upravljanje preverjenih poverilnic"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Aplikaciji dovoli nameščanje in odstranjevanje potrdil overitelja potrdil kot preverjenih poverilnic."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"branje/pisanje v sredstva, ki so v lasti skupine za diagnostiko"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Programu omogoča branje in pisanje na poljuben vir, ki je v lasti skupine za diagnostiko; na primer datoteke v mapi /dev. To lahko vpliva na stabilnost in varnost sistema. To naj uporablja SAMO izdelovalec ali operater za diagnostiko, specifično za strojno opremo."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"omogočanje ali onemogočanje komponent programa"</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Omogoča aplikaciji konfiguriranje zaslonov Wi-Fi in povezovanje z njimi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"nadzor zaslonov Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Omogoča aplikaciji nadzor osnovnih funkcij zaslonov Wi-Fi."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"zajem avdioizhoda"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Omogoči aplikaciji, da zajame in preusmeri avdioizhod."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"zajem videoizhoda"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Omogoči aplikaciji, da zajame in preusmeri videoizhod."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"zajem varnega videoizhoda"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Omogoči aplikaciji, da zajame in preusmeri varni videoizhod."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"spreminjanje nastavitev zvoka"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Aplikaciji omogoča spreminjanje splošnih zvočnih nastavitev, na primer glasnost in kateri zvočnik se uporablja."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"snemanje zvoka"</string>
@@ -525,6 +552,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"preprečevanje prehoda v stanje pripravljenosti telefona"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Omogoča, da program prepreči prehod tabličnega računalnika v stanje pripravljenosti."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Programu omogoča, da v telefonu prepreči prehod v stanje pripravljenosti."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"vklop ali izklop tabličnega računalnika"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"vklop ali izklop telefona"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Programu omogoča vklop ali izklop tabličnega računalnika."</string>
@@ -613,6 +646,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Programu omogoča pisanje na kartico SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"spreminjanje/brisanje vsebine notranje shrambe nosilca podatkov"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Programu omogoča spreminjanje vsebine notranje shrambe nosilca podatkov."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"upravljanje shranjevanja dokumentov"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Aplikaciji omogoči upravljanje shranjevanja dokumentov."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"dostop do zunanje naprave za shranjevanje za vse uporabnike"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Aplikaciji omogoča dostop do zunanje naprave za shranjevanje za vse uporabnike."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"dostop do datotečnega sistema predpomnilnika"</string>
@@ -625,10 +660,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Programu omogoča upravljanje pravilnikov o omrežju in določanje pravil za program."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"spremeni obračunavanje uporabe omrežja"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Programu omogoča, da spremeni uporabo omrežja na podlagi programov. Ni za uporabo z navadnimi programi."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"spreminjanje oznak vtičnic"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Aplikaciji omogoča spreminjanje oznak vtičnic za usmerjanje"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"dostop do obvestil"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Dovoli aplikaciji, da prenese, razišče in izbriše obvestila, tudi tista, ki so jih objavile druge aplikacije."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"poveži se s storitvijo poslušalca obvestil"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Lastniku omogoča povezovanje z vmesnikom storitve poslušalca obvestil najvišje ravni. Tega nikoli ni treba uporabiti za navadne aplikacije."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"sprožitev operaterjeve aplikacije za konfiguracijo"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Lastniku omogoča sproženje operaterjeve aplikacije za konfiguracijo. Tega nikoli ni treba uporabiti za navadne aplikacije."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"spremljanje razmer v omrežju"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Aplikaciji omogoča spremljanje razmer v omrežju. Pri navadnih aplikacijah to ne bi smelo biti potrebno."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Nastavitev pravil za geslo"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Nadzor nad dolžino in znaki, ki so dovoljeni v geslih za odklepanje zaslona."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"nadzor nad poskusi odklepanja zaslona"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +836,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Vstavite kartico SIM."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Ni kartice SIM ali je ni mogoče prebrati. Vstavite kartico SIM."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Neuporabna kartica SIM."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Kartica SIM je trajno onemogočena."\n" Če želite dobiti drugo kartico SIM, se obrnite na ponudnika brezžičnih storitev."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Kartica SIM je trajno onemogočena.\n Če želite dobiti drugo kartico SIM, se obrnite na ponudnika brezžičnih storitev."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Gumb za prejšnjo skladbo"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Gumb za naslednjo skladbo"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Gumb »Premor«"</string>
@@ -808,11 +848,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Preberite uporabniški priročnik ali se obrnite na oddelek za skrb za stranke."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Kartica SIM je zaklenjena."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Odklepanje kartice SIM ..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Vzorec za odklepanje ste nepravilno narisali <xliff:g id="NUMBER_0">%d</xliff:g>-krat. "\n\n"Poskusite znova čez <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Geslo ste <xliff:g id="NUMBER_0">%d</xliff:g>-krat vnesli napačno. "\n\n"Znova poskusite čez <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"PIN ste <xliff:g id="NUMBER_0">%d</xliff:g>-krat vnesli napačno. "\n\n"Znova poskusite čez <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Vzorec za odklepanje ste nepravilno vnesli <xliff:g id="NUMBER_0">%d</xliff:g>-krat. Po <xliff:g id="NUMBER_1">%d</xliff:g> neuspešnih poskusih boste pozvani, da odklenete tablični računalnik z Googlovimi podatki za prijavo."\n\n"Poskusite znova čez <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Vzorec za odklepanje ste nepravilno vnesli <xliff:g id="NUMBER_0">%d</xliff:g>-krat. Po <xliff:g id="NUMBER_1">%d</xliff:g> neuspešnih poskusih boste pozvani, da odklenete telefon z Googlovimi podatki za prijavo."\n\n"Poskusite znova čez <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Vzorec za odklepanje ste nepravilno narisali <xliff:g id="NUMBER_0">%d</xliff:g>-krat. \n\nPoskusite znova čez <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Geslo ste <xliff:g id="NUMBER_0">%d</xliff:g>-krat vnesli napačno. \n\nZnova poskusite čez <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"PIN ste <xliff:g id="NUMBER_0">%d</xliff:g>-krat vnesli napačno. \n\nZnova poskusite čez <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Vzorec za odklepanje ste nepravilno vnesli <xliff:g id="NUMBER_0">%d</xliff:g>-krat. Po <xliff:g id="NUMBER_1">%d</xliff:g> neuspešnih poskusih boste pozvani, da odklenete tablični računalnik z Googlovimi podatki za prijavo.\n\nPoskusite znova čez <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Vzorec za odklepanje ste nepravilno vnesli <xliff:g id="NUMBER_0">%d</xliff:g>-krat. Po <xliff:g id="NUMBER_1">%d</xliff:g> neuspešnih poskusih boste pozvani, da odklenete telefon z Googlovimi podatki za prijavo.\n\nPoskusite znova čez <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Tablični računalnik ste poskusili <xliff:g id="NUMBER_0">%d</xliff:g>-krat nepravilno odkleniti. Če poskusite še <xliff:g id="NUMBER_1">%d</xliff:g>-krat in ne uspete, bo ponastavljen na privzete tovarniške nastavitve, vsi uporabniški podatki pa bodo izbrisani."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Telefon ste poskusili <xliff:g id="NUMBER_0">%d</xliff:g>-krat nepravilno odkleniti. Če poskusite še <xliff:g id="NUMBER_1">%d</xliff:g>-krat in ne uspete, bo ponastavljen na privzete tovarniške nastavitve, vsi uporabniški podatki pa bodo izgubljeni."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Tablični računalnik ste poskusili <xliff:g id="NUMBER">%d</xliff:g>-krat nepravilno odkleniti, zato bo zdaj ponastavljen na privzete tovarniške nastavitve."</string>
@@ -826,7 +866,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Geslo"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Prijava"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Neveljavno uporabniško ime ali geslo."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Ali ste pozabili uporabniško ime ali geslo?"\n"Obiščite "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Ali ste pozabili uporabniško ime ali geslo?\nObiščite "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Preverjanje ..."</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Odkleni"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Vklopi zvok"</string>
@@ -874,7 +914,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Potrditev krmarjenja"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Zapusti to stran"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Ostani na tej strani"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Ali res želite zapustiti to stran?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nAli res želite zapustiti to stran?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Potrdi"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Nasvet: Tapnite dvakrat, če želite povečati ali pomanjšati."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Samoizp."</string>
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"Žal se je program <xliff:g id="APPLICATION">%1$s</xliff:g> ustavil."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Žal se je postopek <xliff:g id="PROCESS">%1$s</xliff:g> ustavil."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"Program <xliff:g id="APPLICATION">%2$s</xliff:g> se ne odziva."\n\n"Ali ga želite zapreti?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Dejavnost <xliff:g id="ACTIVITY">%1$s</xliff:g> se ne odziva."\n\n"Ali jo želite zapreti?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"Program <xliff:g id="APPLICATION">%2$s</xliff:g> se ne odziva.\n\nAli ga želite zapreti?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Dejavnost <xliff:g id="ACTIVITY">%1$s</xliff:g> se ne odziva.\n\nAli jo želite zapreti?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"Program <xliff:g id="APPLICATION">%1$s</xliff:g> se ne odziva. Ali ga želite zapreti?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> se ne odziva."\n\n"Ali ga želite zapreti?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> se ne odziva.\n\nAli ga želite zapreti?"</string>
     <string name="force_close" msgid="8346072094521265605">"V redu"</string>
     <string name="report" msgid="4060218260984795706">"Poročaj"</string>
     <string name="wait" msgid="7147118217226317732">"Čakaj"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"Stran se ne odziva."\n" "\n"Ali jo želite zapreti?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Stran se ne odziva.\n \nAli jo želite zapreti?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Program preusmerjen"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> se izvaja."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"Prvotno je bil zagnan program <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
@@ -1256,6 +1296,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Programu omogoča pozivanje privzete storitve vsebnika, da kopira vsebino. Ni za uporabo z navadnimi programi."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Preusmeritev predstavnosti"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Aplikaciji omogoča preusmerjanje predstavnosti v druge zunanje naprave."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Dostop do varne shrambe Keyguard."</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Aplikaciji omogoča dostop do varne shrambe Keyguard."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Nadzira prikaz in skrivanje zaklepanja tipkovnice"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Aplikaciji omogoča nadzor zaklepanja tipkovnice."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Dvakrat se dotaknite za nadzor povečave/pomanjšave"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Pripomočka ni bilo mogoče dodati."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Pojdi"</string>
@@ -1265,15 +1309,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Dokončano"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Nazaj"</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Izvedi"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Pokliči številko"\n"s številko <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Ustvari stik"\n"s številko <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Pokliči številko\ns številko <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Ustvari stik\ns številko <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Ti programi zahtevajo dovoljenje za dostop do računa zdaj in v prihodnje."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Ali želite to zahtevo dovoliti?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Zahteva za dostop"</string>
     <string name="allow" msgid="7225948811296386551">"Dovoli"</string>
     <string name="deny" msgid="2081879885755434506">"Zavrni"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Zahtevano je dovoljenje"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Zahtevano je dovoljenje"\n"za račun <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Zahtevano je dovoljenje\nza račun <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Način vnosa"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Sinhronizacija"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Pripomočki za osebe s posebnimi potrebami"</string>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Pokaži vse"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Izberite dejavnost"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Delite z"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Naprava zaklenjena."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Pošiljanje ..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Ali želite odpreti brskalnik?"</string>
@@ -1441,10 +1484,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Vzpostavljanje povezave ..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Na voljo"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"Ni na voljo"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"V uporabi"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Vgrajen zaslon"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"Zaslon HDMI"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Prekrivanje #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> pik na palec"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", varen"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Brezžični zaslon je povezan"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Ta zaslon je prikazan v drugi napravi"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Prekini povezavo"</string>
@@ -1453,7 +1498,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Napačen vzorec"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Napačno geslo"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"Napačen PIN"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Čez <xliff:g id="NUMBER">%d</xliff:g> sekund poskusite znova."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Čez <xliff:g id="NUMBER">%1$d</xliff:g> sekund poskusite znova."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Narišite vzorec"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Vnesite PIN za kartico SIM"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Vnesite PIN"</string>
@@ -1473,27 +1518,85 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Geslo"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Prijava"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Neveljavno uporabniško ime ali geslo."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Ali ste pozabili uporabniško ime ali geslo?"\n"Obiščite "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Ali ste pozabili uporabniško ime ali geslo?\nObiščite "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Preverjanje računa ..."</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN ste <xliff:g id="NUMBER_0">%d</xliff:g>-krat vnesli napačno. "\n\n"Znova poskusite čez <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Geslo ste <xliff:g id="NUMBER_0">%d</xliff:g>-krat vnesli napačno. "\n\n"Znova poskusite čez <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Vzorec za odklepanje ste nepravilno narisali <xliff:g id="NUMBER_0">%d</xliff:g>-krat. "\n\n"Poskusite znova čez <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN ste <xliff:g id="NUMBER_0">%d</xliff:g>-krat vnesli napačno. \n\nZnova poskusite čez <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Geslo ste <xliff:g id="NUMBER_0">%d</xliff:g>-krat vnesli napačno. \n\nZnova poskusite čez <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Vzorec za odklepanje ste nepravilno narisali <xliff:g id="NUMBER_0">%d</xliff:g>-krat. \n\nPoskusite znova čez <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tablični računalnik ste poskusili <xliff:g id="NUMBER_0">%d</xliff:g>-krat napačno odkleniti. Če poskusite še <xliff:g id="NUMBER_1">%d</xliff:g>-krat in ne uspete, bo ponastavljen na privzete tovarniške nastavitve in vsi uporabniški podatki bodo izgubljeni."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Telefon ste poskusili <xliff:g id="NUMBER_0">%d</xliff:g>-krat napačno odkleniti. Če poskusite še <xliff:g id="NUMBER_1">%d</xliff:g>-krat in ne uspete, bo ponastavljen na privzete tovarniške nastavitve in vsi uporabniški podatki bodo izgubljeni."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Tablični računalnik ste poskusili <xliff:g id="NUMBER">%d</xliff:g>-krat napačno odkleniti, zato bo ponastavljen na privzete tovarniške nastavitve."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Telefon ste poskusili <xliff:g id="NUMBER">%d</xliff:g>-krat napačno odkleniti, zato bo ponastavljen na privzete tovarniške nastavitve."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Vzorec za odklepanje ste <xliff:g id="NUMBER_0">%d</xliff:g>-krat napačno vnesli. Po nadaljnjih <xliff:g id="NUMBER_1">%d</xliff:g> neuspešnih poskusih boste pozvani, da tablični računalnik odklenete z e-poštnim računom."\n\n"Poskusite znova čez <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Vzorec za odklepanje ste <xliff:g id="NUMBER_0">%d</xliff:g>-krat napačno vnesli. Po nadaljnjih <xliff:g id="NUMBER_1">%d</xliff:g> neuspešnih poskusih boste pozvani, da odklenete telefon z Googlovimi podatki za prijavo."\n\n"Poskusite znova čez <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Vzorec za odklepanje ste <xliff:g id="NUMBER_0">%d</xliff:g>-krat napačno vnesli. Po nadaljnjih <xliff:g id="NUMBER_1">%d</xliff:g> neuspešnih poskusih boste pozvani, da tablični računalnik odklenete z e-poštnim računom.\n\nPoskusite znova čez <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Vzorec za odklepanje ste <xliff:g id="NUMBER_0">%d</xliff:g>-krat napačno vnesli. Po nadaljnjih <xliff:g id="NUMBER_1">%d</xliff:g> neuspešnih poskusih boste pozvani, da odklenete telefon z Googlovimi podatki za prijavo.\n\nPoskusite znova čez <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Odstrani"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Želite povečati glasnost nad varno raven?"\n"Dolgotrajna izpostavljenost glasnemu predvajanju lahko poškoduje sluh."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Želite povečati glasnost nad varno raven?\nDolgotrajna izpostavljenost glasnemu predvajanju lahko poškoduje sluh."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Če želite omogočiti pripomočke za ljudi s posebnimi potrebami, na zaslonu pridržite z dvema prstoma."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Pripomočki za ljudi s posebnimi potrebami so omogočeni."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Omogočanje pripomočkov za ljudi s posebnimi potrebami preklicano."</string>
     <string name="user_switched" msgid="3768006783166984410">"Trenutni uporabnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Lastnik"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Napaka"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Ta aplikacija ne podpira računov za profile z omejitvami"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Ta aplikacija ne podpira računov za profile z omejitvami"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Najdena ni bila nobena aplikacija za izvedbo tega dejanja"</string>
     <string name="revoke" msgid="5404479185228271586">"Prekliči"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Preklicano"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Napaka pri pisanju vsebine"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"neznano"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Vnesite skrbniški PIN"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Vnesite PIN"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Napačno"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Trenutni PIN"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Novi PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Potrdite novi PIN"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Ustvarite PIN za spreminjanje omejitev"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"Kodi PIN se ne ujemata. Poskusite znova."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"PIN je prekratek. Imeti mora vsaj 4 števke."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Poskusite znova čez sekundo"</item>
+    <item quantity="other" msgid="4730868920742952817">"Poskusite znova čez <xliff:g id="COUNT">%d</xliff:g> s"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Poskusite znova pozneje"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Povlecite z roba za prikaz vrstice"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Sistemsko vrstico prikažete tako, da povlečete z roba zaslona"</string>
 </resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index d0ebddd..f119865 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -131,6 +131,11 @@
     <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="default" msgid="3475999286680000541">"Складиште телефона је пуно! Избришите неке датотеке како бисте ослободили простор."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Мрежа се можда надгледа"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Ја"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Опције за таблет"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Опције телефона"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Дозвољава апликацији да премешта задатке у први план и у позадину. Апликација може да ради ово без вашег уноса."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"заустављање покренутих апликација"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Дозвољава апликацији да уклања задатке и уништава њихове апликације. Злонамерне апликације могу да поремете понашање других апликација."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"управљање групама активности"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Дозвољава апликацији да додаје, уклања и мења групе активности у којима се покрећу друге апликације. Злонамерне апликације могу да поремете понашање других апликација."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"покретање било које активности"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Омогућава да апликација покрене било коју активност, без обзира на заштиту дозволе или стање извоза."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"подешавање компатибилности екрана"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Омогућава да се власник обавеже на интерфејс методе уноса највишег нивоа. Уобичајене апликације никада не би требало да је користе."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"повезивање са услугом приступачности"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Дозвољава власнику да се повеже са интерфејсом услуге приступачности највишег нивоа. Уобичајене апликације никада не би требало да је користе."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"повезивање са услугом штампања"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Дозвољава власнику да се повеже са интерфејсом услуге штампања највишег нивоа. Уобичајене апликације никада не би требало да је користе."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"повезивање са услугом штампања из меморије"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Дозвољава власнику да се повеже са интерфејсом највишег нивоа услуге штампања из меморије. Не би требало никада да буде потребно за нормалне апликације."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"повезивање са NFC услугом"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Дозвољава власнику да се повеже са апликацијама које опонашају NFC картице. Никада не би требало да буде потребно за обичне апликације."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"обавезивање на текстуалну услугу"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Омогућава власнику да се обавеже на интерфејс текстуалне услуге највишег нивоа (нпр. SpellCheckerService). Обичне апликације никада не би требало да је користе."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"везивање за VPN услугу"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Дозвољава власнику да се обавеже на интерфејс услуге виџета највишег нивоа. Уобичајене апликације никада не би требало да је користе."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"интеракција са администратором уређаја"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Омогућава да власник шаље своје намере администратору уређаја. Уобичајене апликације никада не би требало да је користе."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"додавање или уклањање администратора уређаја"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Дозвољава власнику да додаје или уклања активне администраторе уређаја. Уобичајене апликације никада не би требало да је користе."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"промена положаја екрана"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Дозвољава апликацији да у сваком тренутку промени ротацију екрана. Уобичајене апликације никада не би требало да је користе."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"промена брзине показивача"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Дозвољава апликацији да чита разне системске датотеке евиденције. То јој омогућава увид у опште информације о начину на који користите телефон, при чему могу да буду обухваћене личне или приватне информације."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"користи било који декодер медија за репродукцију"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Омогућава апликацији да користи било који инсталирани декодер медија за декодирање за репродукцију."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"управљање поузданим акредитивима"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Дозвољава апликацији да инсталира и деинсталира CA сертификате као поуздане акредитиве."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"читање ресурса у власништву дијагностике и уписивање података у њих"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Дозвољава апликацији да чита и уписује податке у било који ресурс у власништву групе за дијагностиковање, на пример, датотеке у директоријуму /dev. То може да угрози стабилност и безбедност система и треба да је користе САМО произвођач или оператер у сврхе дијагностиковањa хардвера."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"омогућавање или онемогућавање компоненти апликације"</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Дозвољава апликацији да конфигурише Wi-Fi екране и повезује се са њима."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"контрола Wi-Fi екрана"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Дозвољава апликацији да контролише функције Wi-Fi екрана ниског нивоа."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"снимање аудио садржаја"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Дозвољава апликацији да снима и преусмерава аудио садржај."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"снимање видео садржаја"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Дозвољава апликацији да снима и преусмерава видео садржај."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"снимање безбедног видео садржаја"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Дозвољава апликацији да снима и преусмерава безбедан видео садржај."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"промена аудио подешавања"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Дозвољава апликацији да мења глобална аудио подешавања као што су јачина звука и избор звучника који се користи као излаз."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"снимање аудио записа"</string>
@@ -525,6 +552,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"спречавање преласка телефона у стање спавања"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Дозвољава апликацији да спречи таблет да пређе у стање спавања."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Дозвољава апликацији да спречи телефон да пређе у стање спавања."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"укључивање или искључивање таблета"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"укључивање или искључивање телефона"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Дозвољава апликацији да укључује или искључује таблет."</string>
@@ -613,6 +646,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Дозвољава апликацији да уписује податке на SD картицу."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"измена/брисање интерне меморије медија"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Дозвољава апликацији да мења садржај интерне меморије медијума."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"управ. складиштењем докумената"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Дозвољава апликацији да управља складиштењем докумената."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"приступ спољној меморији свих корисника"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Дозвољава апликацији да приступа спољној меморији за све кориснике."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"приступ систему датотека кеша"</string>
@@ -625,10 +660,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Дозвољава апликацији да управља смерницама за мрежу и одређује посебна правила за апликацију."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"измените обрачунавање коришћења мреже"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Дозвољава апликацији да измени начин на који апликације користе мрежу. Не користе је уобичајене апликације."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"измена ознака утичнице"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Дозвољава апликацији да мења ознаке утичнице за усмеравање"</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_invokeCarrierSetup" msgid="3699600833975117478">"позивање апликације са конфигурацијом коју одређује оператер"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Дозвољава власнику да позива апликацију са конфигурацијом коју одређује оператер. Уобичајене апликације никада не би требало да је користе."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"праћење података о условима на мрежи"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Дозвољава апликацији да прати податке о условима на мрежи. Не би никада требало да буде потребно за нормалне апликације."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Подешавање правила за лозинку"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролишите дужину и знакове дозвољене у лозинкама за откључавање екрана."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Надгледање покушаја откључавања екрана"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +836,7 @@
     <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">"SIM картица је трајно онемогућена.\n Обратите се добављачу услуге бежичне мреже да бисте добили другу SIM картицу."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Дугме за претходну песму"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Дугме за следећу песму"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Дугме за паузу"</string>
@@ -808,11 +848,11 @@
     <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">%d</xliff:g> пута сте неправилно нацртали шаблон за откључавање. "\n\n"Покушајте поново за <xliff:g id="NUMBER_1">%d</xliff:g> секунде(и)."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"<xliff:g id="NUMBER_0">%d</xliff:g> пута сте погрешно унели лозинку. "\n\n"Покушајте поново за <xliff:g id="NUMBER_1">%d</xliff:g> секунде(и)."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"<xliff:g id="NUMBER_0">%d</xliff:g> пута сте погрешно унели PIN. "\n\n"Покушајте поново за <xliff:g id="NUMBER_1">%d</xliff:g> секунде(и)."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"<xliff:g id="NUMBER_0">%d</xliff:g> пута сте нетачно унели шаблон за откључавање. Након још <xliff:g id="NUMBER_1">%d</xliff:g> несупешна(их) покушаја, од вас ће бити затражено да откључате таблет помоћу података за пријављивање на Google."\n\n" Покушајте поново за <xliff:g id="NUMBER_2">%d</xliff:g> секунде(и)."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"<xliff:g id="NUMBER_0">%d</xliff:g> пута сте нетачно унели шаблон за откључавање. Након још <xliff:g id="NUMBER_1">%d</xliff:g> несупешна(их) покушаја, од вас ће бити затражено да откључате телефон помоћу података за пријављивање на Google."\n\n" Покушајте поново за <xliff:g id="NUMBER_2">%d</xliff:g> секунде(и)."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"<xliff:g id="NUMBER_0">%d</xliff:g> пута сте неправилно нацртали шаблон за откључавање. \n\nПокушајте поново за <xliff:g id="NUMBER_1">%d</xliff:g> секунде(и)."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"<xliff:g id="NUMBER_0">%d</xliff:g> пута сте погрешно унели лозинку. \n\nПокушајте поново за <xliff:g id="NUMBER_1">%d</xliff:g> секунде(и)."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"<xliff:g id="NUMBER_0">%d</xliff:g> пута сте погрешно унели PIN. \n\nПокушајте поново за <xliff:g id="NUMBER_1">%d</xliff:g> секунде(и)."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"<xliff:g id="NUMBER_0">%d</xliff:g> пута сте нетачно унели шаблон за откључавање. Након још <xliff:g id="NUMBER_1">%d</xliff:g> несупешна(их) покушаја, од вас ће бити затражено да откључате таблет помоћу података за пријављивање на Google.\n\n Покушајте поново за <xliff:g id="NUMBER_2">%d</xliff:g> секунде(и)."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"<xliff:g id="NUMBER_0">%d</xliff:g> пута сте нетачно унели шаблон за откључавање. Након још <xliff:g id="NUMBER_1">%d</xliff:g> несупешна(их) покушаја, од вас ће бити затражено да откључате телефон помоћу података за пријављивање на Google.\n\n Покушајте поново за <xliff:g id="NUMBER_2">%d</xliff:g> секунде(и)."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Неправилно сте покушали да откључате таблет <xliff:g id="NUMBER_0">%d</xliff:g> пута. Након још неуспешних покушаја (<xliff:g id="NUMBER_1">%d</xliff:g>) таблет ће бити враћен на подразумевана фабричка подешавања и сви кориснички подаци ће бити изгубљени."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Неисправно сте покушали да откључате телефон <xliff:g id="NUMBER_0">%d</xliff:g> пута. Након још неуспешних покушаја (<xliff:g id="NUMBER_1">%d</xliff:g>) телефон ће бити враћен на подразумевана фабричка подешавања и сви кориснички подаци ће бити изгубљени."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Неисправно сте покушали да откључате таблет <xliff:g id="NUMBER">%d</xliff:g> пута. Таблет ће сада бити враћен на подразумевана фабричка подешавања."</string>
@@ -826,7 +866,7 @@
     <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_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>
@@ -874,7 +914,7 @@
     <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="autofill_this_form" msgid="4616758841157816676">"Аутом. поп."</string>
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"Нажалост, апликација <xliff:g id="APPLICATION">%1$s</xliff:g> је престала с радом."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Нажалост, процес <xliff:g id="PROCESS">%1$s</xliff:g> је заустављен."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> не реагује."\n\n"Да ли желите да је затворите?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Активност <xliff:g id="ACTIVITY">%1$s</xliff:g> не рeагује."\n\n"Да ли желите да је затворите?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> не реагује.\n\nДа ли желите да је затворите?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Активност <xliff:g id="ACTIVITY">%1$s</xliff:g> не рeагује.\n\nДа ли желите да је затворите?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> не реагује. Да ли желите да је затворите?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Процес <xliff:g id="PROCESS">%1$s</xliff:g> не раегује."\n\n"Да ли желите да га затворите?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Процес <xliff:g id="PROCESS">%1$s</xliff:g> не раегује.\n\nДа ли желите да га затворите?"</string>
     <string name="force_close" msgid="8346072094521265605">"Потврди"</string>
     <string name="report" msgid="4060218260984795706">"Пријави"</string>
     <string name="wait" msgid="7147118217226317732">"Сачекај"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"Страница је престала да се одазива."\n\n" Да ли желите да је затворите?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Страница је престала да се одазива.\n\n Да ли желите да је затворите?"</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>
@@ -1256,6 +1296,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Дозвољава апликацији да од подразумеване услуге контејнера захтева да копира садржај. Не користе је уобичајене апликације."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Усмеравање излаза медија"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Дозвољава апликацији да усмерава излаз медија на друге спољне уређаје."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Приступај безбедној меморији заштићеној шифром"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Дозвољава апликацији да приступа безбедној меморији заштићеној шифром."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Контролиши приказивање и скривање заштите шифром"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Дозвољава апликацији да контролише заштиту шифром."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Додирните двапут да бисте контролисали зум"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Није могуће додати виџет."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Иди"</string>
@@ -1265,15 +1309,15 @@
     <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">"Бирај број"\n"користећи <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Креирајте контакт"\n"користећи <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Бирај број\nкористећи <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Креирајте контакт\nкористећи <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Следеће апликације захтевају дозволу за приступ налогу, како сада, тако и убудуће."</string>
     <string name="grant_credentials_permission_message_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">"Затражена је дозвола"\n"за налог <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Затражена је дозвола\nза налог <xliff:g id="ACCOUNT">%s</xliff:g>"</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>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Прикажи све"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Избор активности"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Дели са"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Уређај је закључан."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Слање..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Желите ли да покренете прегледач?"</string>
@@ -1441,10 +1484,12 @@
     <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>
+    <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_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>×<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", безбедно"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Бежични екран је повезан"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Овај екран се приказује на другом уређају"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Прекини везу"</string>
@@ -1453,7 +1498,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">%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>
@@ -1473,27 +1518,85 @@
     <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_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">%d</xliff:g> пута. "\n\n"Покушајте поново за <xliff:g id="NUMBER_1">%d</xliff:g> секунде(и)."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Унели сте лозинку неисправно <xliff:g id="NUMBER_0">%d</xliff:g> пута. "\n\n"Покушајте поново за <xliff:g id="NUMBER_1">%d</xliff:g> секунде(и)."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Нацртали сте шаблон за откључавање неисправно <xliff:g id="NUMBER_0">%d</xliff:g> пута. "\n\n"Покушајте поново за <xliff:g id="NUMBER_1">%d</xliff:g> секунде(и)."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Унели сте PIN неисправно <xliff:g id="NUMBER_0">%d</xliff:g> пута. \n\nПокушајте поново за <xliff:g id="NUMBER_1">%d</xliff:g> секунде(и)."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Унели сте лозинку неисправно <xliff:g id="NUMBER_0">%d</xliff:g> пута. \n\nПокушајте поново за <xliff:g id="NUMBER_1">%d</xliff:g> секунде(и)."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Нацртали сте шаблон за откључавање неисправно <xliff:g id="NUMBER_0">%d</xliff:g> пута. \n\nПокушајте поново за <xliff:g id="NUMBER_1">%d</xliff:g> секунде(и)."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Покушали сте да откључате таблет неисправно <xliff:g id="NUMBER_0">%d</xliff:g> пута. Након још <xliff:g id="NUMBER_1">%d</xliff:g> неуспешна(их) покушаја таблет ће бити враћен на подразумевана фабричка подешавања и сви кориснички подаци ће бити изгубљени."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Покушали сте да откључате телефон неисправно <xliff:g id="NUMBER_0">%d</xliff:g> пута. После још <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> пута. После још <xliff:g id="NUMBER_1">%d</xliff:g> неуспешна(их) покушаја, од вас ће бити затражено да откључате таблет помоћу налога е-поште."\n\n"Покушајте поново за <xliff:g id="NUMBER_2">%d</xliff:g> секунде(и)."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Нацртали сте шаблон за откључавање неисправно <xliff:g id="NUMBER_0">%d</xliff:g> пута. После још <xliff:g id="NUMBER_1">%d</xliff:g> неуспешна(их) покушаја, од вас ће бити затражено да откључате телефон помоћу налога е-поште."\n\n"Покушајте поново за <xliff:g id="NUMBER_2">%d</xliff:g> секунде(и)."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Нацртали сте шаблон за откључавање неисправно <xliff:g id="NUMBER_0">%d</xliff:g> пута. После још <xliff:g id="NUMBER_1">%d</xliff:g> неуспешна(их) покушаја, од вас ће бити затражено да откључате таблет помоћу налога е-поште.\n\nПокушајте поново за <xliff:g id="NUMBER_2">%d</xliff:g> секунде(и)."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Нацртали сте шаблон за откључавање неисправно <xliff:g id="NUMBER_0">%d</xliff:g> пута. После још <xliff:g id="NUMBER_1">%d</xliff:g> неуспешна(их) покушаја, од вас ће бити затражено да откључате телефон помоћу налога е-поште.\n\nПокушајте поново за <xliff:g id="NUMBER_2">%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="7324161939475478066">"Желите ли да појачате звук преко препорученог нивоа?"\n"Ако слушате гласну музику током дужег периода, може да дође до оштећења слуха."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Желите ли да појачате звук преко препорученог нивоа?\nАко слушате гласну музику током дужег периода, може да дође до оштећења слуха."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Држите са два прста да бисте омогућили приступачност."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Приступачност је омогућена."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Приступачност је отказана."</string>
     <string name="user_switched" msgid="3768006783166984410">"Актуелни корисник <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="app_no_restricted_accounts" msgid="4011285085817350390">"Ова апликација не подржава налоге за ограничене профиле"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Ова апликација не подржава налоге за ограничене профиле"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Није пронађена ниједна апликација која би могла да обави ову радњу"</string>
     <string name="revoke" msgid="5404479185228271586">"Опозови"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Отказано је"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Грешка при исписивању садржаја"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"непознато"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Унесите 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>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Нови PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Потврдите нови PIN"</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_too_short" msgid="8173982756265777792">"PIN је прекратак. Мора да садржи најмање 4 цифре."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Покушајте опет за 1 сек"</item>
+    <item quantity="other" msgid="4730868920742952817">"Покушајте опет за <xliff:g id="COUNT">%d</xliff:g> сек"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Покушајте поново касније"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Превуците по ивици екрана да би се приказала трака"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Превуците од ивице екрана да би се приказала системска трака"</string>
 </resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 80ab2ae..40405ae 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -131,6 +131,11 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"För många <xliff:g id="CONTENT_TYPE">%s</xliff:g>-borttagningar."</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Pekdatorns lagringsutrymme är fullt. Ta bort några filer för att frigöra utrymme."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Mobilens lagringsutrymme är fullt. Ta bort några filer för att frigöra utrymme."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Nätverket kan vara övervakat"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Jag"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Alternativ för surfplattan"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Telefonalternativ"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Tillåter att appen flyttar aktiviteter till förgrunden eller bakgrunden. Appen kan göra detta utan åtgärd från dig."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"avsluta appar som körs"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Tillåter att appen tar bort uppgifter och avslutar appar. Skadliga appar kan störa funktionen i andra appar."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"hantera aktivitetsstaplar"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Appen tillåts att lägga till, ta bort och ändra aktivitetsstaplar som andra appar körs i. Skadliga appar kan störa funktionerna i andra appar."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"starta alla aktiviteter"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Appen tillåts starta alla aktiviteter oavsett behörighetsskydd eller exportstatus."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"ange skärmkompatibilitet"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en inmatningsmetod. Ska inte behövas för vanliga appar."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"bind till en tillgänglighetstjänst"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en tillgänglighetstjänst. Ska inte behövas för vanliga appar."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"binda till en utskriftstjänst"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en utskriftstjänst. Ska inte behövas för vanliga appar."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"binda till en utskriftskö"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en utskriftskö. Ska inte behövas för vanliga appar."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"låsa till NFC-tjänsten"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Innehavaren får låsa appar som fungerar som NFC-kort. Behövs normalt inte för vanliga appar."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"bind till en texttjänst"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Tillåter innehavaren att binda mot den högsta gränssnittsnivån i en texttjänst (t.ex. SpellCheckerService). Bör aldrig behövas för normala appar."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"bind till en VPN-tjänst"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en widget. Ska inte behövas för vanliga appar."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"arbeta med en enhetsadministratör"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Tillåter att innehavaren skickar avsikter till en enhetsadministratör. Vanliga appar behöver aldrig göra detta."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"lägga till eller ta bort en enhetsadministratör"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Innehavaren får lägga till eller ta bort aktiva enhetsadministratörer. Detta ska normalt inte behövas för vanliga appar."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"ändra bildskärmens rikting"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Gör att appen när som helst kan ändra skärmläget. Behövs inte för vanliga appar."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"ändra markörens hastighet"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Tillåter att appen läser från systemets olika loggfiler. Det innebär att appen kan upptäcka allmän information om vad du gör med mobilen, vilket kan inkludera personlig eller privat information."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"använda alla medieavkodare för uppspelning"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Tillåter att appen använder installerade medieavkodare för att avkoda media för uppspelning."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"hantera betrodda uppgifter"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Tillåter att appen installerar och avinstallerar CA-certifikat som betrodda uppgifter."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"läsa/skriva till resurser som ägs av diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Tillåter att appen läser och skriver till en resurs som ägs av diag-gruppen, till exempel filer i /dev. Detta kan eventuellt påverka systemets stabilitet och säkerhet. Detta bör ENDAST användas av tillverkaren eller operatören för maskinvaruspecifik diagnostik."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"aktivera eller inaktivera appkomponenter"</string>
@@ -462,6 +479,14 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Tillåter att appen konfigurerar och ansluter till Wi-Fi-skärmar."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"kontrollerar Wi-Fi-skärmar"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Tillåter att appen kontrollerar grundläggande funktioner för Wi-Fi-skärmar."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"fånga upp ljudutgång"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Tillåt att appen fångar upp och omdirigerar ljudutgången."</string>
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"Kommandoordsidentifiering"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Tillåter att appen spelar in ljud för att upptäcka kommandoord. Inspelningen kan pågå i bakgrunden utan att hindra andra ljudinspelningar (t.ex. med videokamera)."</string>
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"fånga upp videoutgång"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Tillåt att appen fångar upp och omdirigerar videoutgången."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"fånga upp säker videoutgång"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Tillåt att appen fångar upp och omdirigerar säker videoutgång."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"ändra dina ljudinställningar"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Tillåter att appen ändrar globala ljudinställningar som volym och vilken högtalarutgång som används."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"spela in ljud"</string>
@@ -525,6 +550,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"förhindra att telefonen sätts i viloläge"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Tillåter att appen förhindrar att surfplattan går in i viloläge."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Tillåter att appen förhindrar att mobilen går in i viloläge."</string>
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"tillåt IR-sändning"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Tillåter att appen använder surfplattans IR-sändare."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Tillåter att appen använder mobilens IR-sändare."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"slå på eller stänga av surfplattan"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"sätta på eller stänga av telefonen"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Tillåter att appen slår på eller stänger av surfplattan."</string>
@@ -613,6 +641,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Tillåter att appen skriver till SD-kortet."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"ändra/ta bort innehåll"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Tillåter att appen ändrar innehållet på den interna lagringsenheten."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"hantera dokumentlagring"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Tillåter att appen hanterar dokumentlagring."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"åtkomst till lagringsutrymme"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Tillåter att appen får åtkomst till en extern lagringsenhet för alla användare."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"åtkomst till cachefilsystemet"</string>
@@ -625,10 +655,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Tillåter att appen hanterar nätverkspolicyer och definierar appspecifika regler."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"ändra nätverksredovisningen"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Tillåter att appen ändrar hur nätverksanvändning redovisas för appar. Används inte av vanliga appar."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"ändra socketmarkeringar"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Appen tillåts att ändra socketmarkeringar för routing"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"få åtkomst till meddelanden"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Tillåter att appen hämtar, granskar och raderar meddelanden, även sådana som skickats av andra appar."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"binda till en meddelandelyssnare"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en meddelandelyssnare. Ska inte behövas för vanliga appar."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"anropa konfigurationsappen från operatören"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Innehavaren tillåts att anropa konfigurationsappen från operatören. Ska inte behövas för vanliga appar."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"lyssna efter information om nätverksförhållanden"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Tillåter att appen lyssnar efter information om nätverksförhållanden. Vanliga appar bör aldrig behöva den här behörigheten."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Ange lösenordsregler"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Bestäm hur många och vilka tecken som är tillåtna i skärmlåsets lösenord."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Övervaka försök att låsa upp skärmen"</string>
@@ -738,8 +774,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +831,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Sätt i ett SIM-kort."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM-kort saknas eller kan inte läsas. Sätt i ett SIM-kort."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Oanvändbart SIM-kort."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"SIM-kortet har inaktiverats permanent."\n" Beställ ett nytt SIM-kort från din operatör."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"SIM-kortet har inaktiverats permanent.\n Beställ ett nytt SIM-kort från din operatör."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Knapp för föregående spår"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Knapp för nästa spår"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Pausknappen"</string>
@@ -808,11 +843,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Se användarhandboken eller kontakta kundtjänst."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM-kortet är låst."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Låser upp SIM-kort…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. "\n\n"Försök igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Du har angett fel lösenord <xliff:g id="NUMBER_0">%d</xliff:g> gånger. "\n\n"Försök igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Du har angett fel lösenord <xliff:g id="NUMBER_0">%d</xliff:g> gånger. "\n\n"Försök igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter <xliff:g id="NUMBER_1">%d</xliff:g> försök till ombeds du att låsa upp surfplattan med din Google-inloggning."\n\n" Försök igen om  <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter <xliff:g id="NUMBER_1">%d</xliff:g> försök till ombeds du att låsa upp mobilen med uppgifterna som du använder när du loggar in på Google."\n\n" Försök igen om  <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Du har angett fel lösenord <xliff:g id="NUMBER_0">%d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Du har angett fel lösenord <xliff:g id="NUMBER_0">%d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter <xliff:g id="NUMBER_1">%d</xliff:g> försök till ombeds du att låsa upp surfplattan med din Google-inloggning.\n\n Försök igen om  <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter <xliff:g id="NUMBER_1">%d</xliff:g> försök till ombeds du att låsa upp mobilen med uppgifterna som du använder när du loggar in på Google.\n\n Försök igen om  <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Du har försökt låsa upp surfplattan på fel sätt <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter <xliff:g id="NUMBER_1">%d</xliff:g> misslyckade försök till kommer surfplattan att återställas till fabriksinställningarna. Du förlorar då alla användardata."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Du har försökt låsa upp mobilen på fel sätt <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter <xliff:g id="NUMBER_1">%d</xliff:g> misslyckade försök till kommer mobilen att återställas till fabriksinställningarna. Du förlorar då alla användardata."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Du har försökt låsa upp surfplattan på fel sätt <xliff:g id="NUMBER">%d</xliff:g> gånger. Surfplattan återställs nu till fabriksinställningarna."</string>
@@ -826,7 +861,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Lösenord"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Logga in"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Ogiltigt användarnamn eller lösenord."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Har du glömt ditt användarnamn eller lösenord?"\n"Besök "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Har du glömt ditt användarnamn eller lösenord?\nBesök "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Kontrollerar …"</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Lås upp"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Ljud på"</string>
@@ -874,7 +909,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Bekräfta navigering"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Lämna den här sidan"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Stanna på den här sidan"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Vill du verkligen navigera bort från den här sidan?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nVill du verkligen navigera bort från den här sidan?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Bekräfta"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Tips! Dubbelknacka om du vill zooma in eller ut."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Autofyll"</string>
@@ -1080,14 +1115,14 @@
     <string name="aerr_application" msgid="932628488013092776">"<xliff:g id="APPLICATION">%1$s</xliff:g> har tyvärr stoppats."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Processen <xliff:g id="PROCESS">%1$s</xliff:g> har tyvärr stoppats."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> svarar inte."\n\n"Vill du stänga den?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Aktiviteten <xliff:g id="ACTIVITY">%1$s</xliff:g> svarar inte."\n" "\n"Vill du stänga den?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> svarar inte.\n\nVill du stänga den?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Aktiviteten <xliff:g id="ACTIVITY">%1$s</xliff:g> svarar inte.\n \nVill du stänga den?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> svarar inte. Vill du stänga den?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Processen <xliff:g id="PROCESS">%1$s</xliff:g> svarar inte."\n\n"Vill du stänga den?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Processen <xliff:g id="PROCESS">%1$s</xliff:g> svarar inte.\n\nVill du stänga den?"</string>
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"Rapportera"</string>
     <string name="wait" msgid="7147118217226317732">"Vänta"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"Sidan har slutat svara."\n\n"Vill du stänga sidan?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Sidan har slutat svara.\n\nVill du stänga sidan?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Appen omdirigeras"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> körs."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> startades först."</string>
@@ -1256,6 +1291,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Tillåter att appen kopierar innehåll genom att standardbehållartjänsten startas. Används inte av vanliga appar."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Omdirigera medieuppspelning"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Tillåter att appen omdirigerar medieuppspelningar till andra externa enheter."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Åtkomst till säkert keyguard-lagringsutrymme"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Tillåter att en app får åtkomst till säkert keyguard-lagringsutrymme."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Kontrollera hur knapplåset visas och döljs"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Tillåter att en app kontrollerar knapplåsfunktionen."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Tryck två gånger för zoomkontroll"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Det gick inte att lägga till widgeten."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Kör"</string>
@@ -1265,15 +1304,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Färdig"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Föreg."</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Utför"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Slå nummer "\n"med <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Skapa kontakt"\n"med <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Slå nummer \nmed <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Skapa kontakt\nmed <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Följande appar begär åtkomstbehörighet till ditt konto, både nu och i framtiden."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Vill du tillåta den här begäran?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Begäran om åtkomst"</string>
     <string name="allow" msgid="7225948811296386551">"Tillåt"</string>
     <string name="deny" msgid="2081879885755434506">"Neka"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Begärd behörighet"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Begärd behörighet"\n"för kontot <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Begärd behörighet\nför kontot <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Indatametod"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Synkronisera"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Tillgänglighet"</string>
@@ -1420,7 +1459,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Visa alla"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Välj aktivitet"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Dela med"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Enheten är låst."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Skickar ..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Vill du öppna webbläsaren?"</string>
@@ -1441,10 +1479,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Ansluter ..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Tillgängliga"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"Ej tillgängligt"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"Används"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Inbyggd skärm"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"HDMI-skärm"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Överlagring #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", säker"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Trådlös anslutning till skärm"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Den här skärmen visas på en annan enhet"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Koppla från"</string>
@@ -1453,7 +1493,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Fel grafiskt lösenord"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Fel lösenord"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"Fel PIN-kod"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Försök igen om <xliff:g id="NUMBER">%d</xliff:g> sekunder."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Försök igen om <xliff:g id="NUMBER">%1$d</xliff:g> sekunder."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Rita ditt grafiska lösenord"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Ange PIN-kod för SIM-kortet"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Ange PIN-kod"</string>
@@ -1473,27 +1513,85 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Lösenord"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Logga in"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Ogiltigt användarnamn eller lösenord."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Har du glömt ditt användarnamn eller lösenord?"\n"Besök "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Har du glömt ditt användarnamn eller lösenord?\nBesök "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Kontot kontrolleras …"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Du har angett fel lösenord <xliff:g id="NUMBER_0">%d</xliff:g> gånger. "\n\n"Försök igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Du har angett fel lösenord <xliff:g id="NUMBER_0">%d</xliff:g> gånger. "\n\n"Försök igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. "\n\n"Försök igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Du har angett fel lösenord <xliff:g id="NUMBER_0">%d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Du har angett fel lösenord <xliff:g id="NUMBER_0">%d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Du har försökt låsa upp mobilen på fel sätt <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> misslyckade försök återställs surfplattan till fabriksinställningarna. Du förlorar då alla användardata."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Du har försökt låsa upp mobilen på fel sätt <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> misslyckade försök återställs mobilen till fabriksinställningarna. Du förlorar då alla användardata."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Du har försökt låsa upp surfplattan på fel sätt <xliff:g id="NUMBER">%d</xliff:g> gånger. Surfplattan återställs nu till fabriksinställningarna."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Du har försökt låsa upp mobilen på fel sätt <xliff:g id="NUMBER">%d</xliff:g> gånger. Mobilen återställs nu till fabriksinställningarna."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> försök ombeds du låsa upp surfplattan med ett e-postkonto."\n\n" Försök igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> försök ombeds du låsa upp mobilen med hjälp av ett e-postkonto."\n\n" Försök igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> försök ombeds du låsa upp surfplattan med ett e-postkonto.\n\n Försök igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> försök ombeds du låsa upp mobilen med hjälp av ett e-postkonto.\n\n Försök igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Ta bort"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Vill du höja volymen över den rekommenderade nivån?"\n"Om du lyssnar på hög volym under långa perioder kan din hörsel skadas."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Vill du höja volymen över den rekommenderade nivån?\nOm du lyssnar på hög volym under långa perioder kan din hörsel skadas."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Fortsätt trycka med två fingrar om du vill aktivera tillgänglighetsläget."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Tillgänglighetsläget har aktiverats."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Byte till tillgänglighetsläge avbrutet."</string>
     <string name="user_switched" msgid="3768006783166984410">"Nuvarande användare: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Ägare"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Fel"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Den här appen stöder inte konton för begränsade profiler"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Den här appen stöder inte konton för begränsade profiler"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Ingen app som kan hantera åtgärden hittades"</string>
     <string name="revoke" msgid="5404479185228271586">"Återkalla"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Inställd"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Det gick inte att skriva innehållet"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"okänt"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Ange administratörspinkod"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Ange pinkod"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Felaktig"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Aktuell pinkod"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Ny pinkod"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Bekräfta din nya pinkod"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Skapa en pinkod om du vill ändra begränsningar"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"Pinkoderna stämmer inte överens. Försök igen."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"Pinkoden är för kort. Måste vara minst fyra siffror."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Försök igen om en sekund"</item>
+    <item quantity="other" msgid="4730868920742952817">"Försök igen om <xliff:g id="COUNT">%d</xliff:g> sekunder"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Försök igen senare"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Dra från kanten av skärmen om du vill visa fältet"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Dra från kanten av skärmen om du vill visa systemfältet"</string>
 </resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index b066d3a..851e6b6 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -131,6 +131,11 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Ufutaji mwingi sana <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Hifadhi ya kompyuta kibao imejaa. Futa baadhi ya faili ili kupata nafasi."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Hifadhi ya simu imejaa. Futa baadhi ya faili ili uweze kupata nafasi."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Mtandao unaweza kufuatiliwa"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Mimi"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Chaguo za kompyuta ndogo"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Machaguo ya simu"</string>
@@ -138,12 +143,12 @@
     <string name="turn_on_radio" msgid="3912793092339962371">"Washa mtandao-hewa"</string>
     <string name="turn_off_radio" msgid="8198784949987062346">"Zima pasiwaya"</string>
     <string name="screen_lock" msgid="799094655496098153">"Funga skrini"</string>
-    <string name="power_off" msgid="4266614107412865048">"Zima simu"</string>
+    <string name="power_off" msgid="4266614107412865048">"Zima"</string>
     <string name="silent_mode_silent" msgid="319298163018473078">"Programu ya milio imezimwa"</string>
     <string name="silent_mode_vibrate" msgid="7072043388581551395">"Mtetemo wa programu ya milio"</string>
     <string name="silent_mode_ring" msgid="8592241816194074353">"Programu ya milio imewashwa"</string>
     <string name="shutdown_progress" msgid="2281079257329981203">"Inafunga..."</string>
-    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Kompyuta yako ndogo itazima."</string>
+    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Kompyuta kibao yako itazima."</string>
     <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Simu yako itazima."</string>
     <string name="shutdown_confirm_question" msgid="2906544768881136183">"Unataka kuzima?"</string>
     <string name="reboot_safemode_title" msgid="7054509914500140361">"Washa upya kwa hali salama"</string>
@@ -153,16 +158,16 @@
     <string name="global_actions" product="tablet" msgid="408477140088053665">"Chaguo za kompyuta ndogo"</string>
     <string name="global_actions" product="default" msgid="2406416831541615258">"Chaguo za simu"</string>
     <string name="global_action_lock" msgid="2844945191792119712">"Funga skrini"</string>
-    <string name="global_action_power_off" msgid="4471879440839879722">"Zima simu"</string>
+    <string name="global_action_power_off" msgid="4471879440839879722">"Zima"</string>
     <string name="global_action_bug_report" msgid="7934010578922304799">"Ripoti ya hitilafu"</string>
     <string name="bugreport_title" msgid="2667494803742548533">"Chukua ripoti ya hitilafu"</string>
     <string name="bugreport_message" msgid="398447048750350456">"Hii itakusanya maelezo kuhusu hali ya kifaa chako kwa sasa, na itume kama barua pepe. Itachukua muda mfupi tangu ripoti ya hitilafu ianze kuzalishwa hadi iwe tayari kutumwa; vumilia."</string>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Mtindo wa kimya"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Sauti Imezimwa"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Sauti imewashwa"</string>
-    <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"gumzo ya ndege"</string>
+    <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Hali ya ndege"</string>
     <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Hali ya ndege IMEWASHWA"</string>
-    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"gumzo ya ndege IMEZIMWA"</string>
+    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Hali ya ndege IMEZIMWA"</string>
     <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
     <string name="safeMode" msgid="2788228061547930246">"Mtindo salama"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Mfumo wa Android"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Inaruhusu programu kusongesha kazi hadi kwenye mandhari-mbele na mandari nyuma. Programu inaweza kufanya haya bila ya maingizo yako."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"Komesha programu zinazoendeshwa"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Huruhusu programu kuondoa majukumu na kuua programu zao. Programu hasidi zinaweza kutatiza tabia ya programu zingine."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"dhibiti mabunda ya shughuli"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Inaruhusu programu kuongeza, kuondoa, na kubadilisha bunda za shughuli ambamo programu nyingine huendeshwa. Programu hasidi zinaweza kusitisha tabia ya programu nyingine."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"anzisha shughuli yoyote"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Huruhusu programu kuanzisha shughuli yoyote, pasi kujali ulinzi wa idhini au hali ya nje."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"weka utangamano wa skrini"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Inaruhusu mmiliki kushurutisha kwenye kusano ya kiwango cha juu ya mbinu ya ingizo. Haipaswi kuhitajika kwa programu za kawaida."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"funga kwa huduma ya ufikiaji"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Inamuruhusu mmiliki kufunga kipengee kinachojitokeza katika nyanja mbalimbali za kiwango cha juu cha huduma ya afikiaji. Hapaswi kuhitajika kwa programu za kawaida."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"tundika kwenye huduma ya kuchapisha"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Inaruhusu kishikiliaji kujifungilia kiolesura cha kiwango cha juu cha huduma ya kuchapisha. Haipaswi kuhitajika kwa programu za kawaida."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"Fungia kwenye huduma ya kuchapisha"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Inaruhusu mtumiaji kujifungia kiolesura cha kiwango cha juu cha huduma ya kuchapisha. Haipaswi kuhitajika kwa programu za kawaida."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"funga kwenye huduma za NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Huruhusu mmiliki kufunga kwa programu zinazoiga kadi za NFC. Haipaswi kuhitajika kamwe kwa programu za kawaida."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"Imefungwa kwa huduma ya maandishi"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Inaruhusu kishikiliaji kushurutisha kusano ya kiwango cha juu ya huduma ya matini(k.m.SpellCheckerService). Haipaswi kuhitajika kwa programu za kawaida."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"funga kwa huduma ya VPN"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Inaruhusu mmiliki kushurutisha kusano ya kiwango cha juu ya huduma ya wijeti. Haipaswi kuhitajika kwa programu za kawaida."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"jiunge na msimamizi wa kifaa"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Inamruhusu mmiliki kutuma malengo kwa msimamizi wa kifaa. Haipaswi kuhitajika kwa programu za kawaida."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"ongeza au ondoa msimamizi wa kifaa"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Inaruhusu mmiliki kuongeza au kuondoa wasimamizi wa kifaa waliopo. Kamwe kisihitajike kwa ajili ya programu za kawaida."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"badilisha uelekezo wa skrini"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Inaruhusu programu kubadilisha mzunguko wa skrini wakati wowote. Kamwe hazihitajiki kwa programu za kawaida."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"Badilisha kasi ya pointa"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Inaruhusu programu kusoma kutoka kwa faili mbalimbali za kumbukumbu za mfumo. Hii inairuhusu kutambua maelezo ya jumla kuhusu unachofanya na simu, yanayoweza kujumuisha maelezo ya kibinafsi na ya siri."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"Tumia chombo chochote cha habari cha kufasiria maandishi ya siri ili kucheza tena."</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Huruhusu programu kutumia vyombo vyovyote vya habari vilivyosakinishwa ili kusimbua kwa ajili ya kucheza tena."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"dhibiti vitambulisho vinavyoaminika"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Huruhusu programu kusakinisha na kusanidua vyeti vya CA kama vitambulisho vinavyoaminika."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"soma/andika kwa vyanzo vinavyomilikiwa na diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Inaruhusu programu kusoma na kuandika kwa chanzo chochote kinachomilikiwa na kikundi cha diag; kwa mfano, faili katika /dev. Hii inaweza kuathiri udhabiti na usalama wa mfumo. Hii inapaswa kutumiwa TU kwa utambuzi mahsusi wa maunzi na mtengenezaji au opareta."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"wezesha au lemeza vijenzi vya programu"</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Inaruhusu programu kusanidi na kuunganika kwenye maonyesho ya Wifi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"dhibiti maonyesho ya Wifi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Inaruhusu programu kudhibiti vipengele vya kiwango cha chini vya maonyesho ya Wifi."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"nasa sauti"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Inaruhusu programu kunasa na kuelekeza sauti kwingine."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"nasa sauti ya video"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Inaruhusu programu kunasa na kuelekeza video kwingine."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"nasa sauti ya video kwa usalama"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Inaruhusu programu kunasa na kuelekeza video kwingine kwa usalama."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"badilisha mipangilio yako ya sauti"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Inaruhusu programu kurekebisha mipangilio ya sauti kila mahali kama vile sauti na ni kipaza sauti kipi ambacho kinatumika kwa kutoa."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"rekodi sauti"</string>
@@ -525,6 +552,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"zuia simu dhidi ya kulala"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Inaruhusu programu kuzuia kompyuta kibao  kwenda kulala."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Inaruhusu programu kuzuia simu isiende kulala."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"Washa au zima kompyuta kibao"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"washa au zima simu"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Inaruhusu programu kuwasha au kuzima kompyuta kibao."</string>
@@ -537,13 +570,13 @@
     <string name="permlab_setWallpaperHints" msgid="3278608165977736538">"rekebisha ukubwa wa mandhari yako"</string>
     <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Inaruhusu programu kuweka vidokezo vya ukubwa wa mandhari ya mfumo."</string>
     <string name="permlab_masterClear" msgid="2315750423139697397">"weka upya mfumo kwa chaguo-msingi za kiwanda"</string>
-    <string name="permdesc_masterClear" msgid="3665380492633910226">"Huruhusu programu kurudisha mfumo kwenye mipangilio yake ya mwanzo, hatua ambayo hufuta data, usanidi, na programu zote zilizosanikishwa."</string>
+    <string name="permdesc_masterClear" msgid="3665380492633910226">"Huruhusu programu kurudisha mfumo kwenye mipangilio yake ya mwanzo, hatua ambayo hufuta data, mipangilio, na programu zote zilizosanikishwa."</string>
     <string name="permlab_setTime" msgid="2021614829591775646">"weka muda"</string>
     <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"Inaruhusu programu kubadilisha wakati wa saa ya kompyuta kibao."</string>
     <string name="permdesc_setTime" product="default" msgid="1855702730738020">"Inaruhusu programu kubadilisha wakati wa saa ya simu."</string>
     <string name="permlab_setTimeZone" msgid="2945079801013077340">"weka saa za eneo"</string>
-    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Inaruhusu programu kubadilisha  majira ya saa ya kompyuta kibao."</string>
-    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Inaruhusu programu kubadilisha  majira ya saa ya simu."</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Huruhusu programu kubadilisha saa za eneo katika kompyuta kibao."</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Huruhusu programu kubadilisha saa za eneo katika simu."</string>
     <string name="permlab_accountManagerService" msgid="4829262349691386986">"tenda kama Huduma ya Meneja wa Akaunti"</string>
     <string name="permdesc_accountManagerService" msgid="1948455552333615954">"Huruhusu programu kupiga simu kwa Wathibitishaji Akaunti."</string>
     <string name="permlab_getAccounts" msgid="1086795467760122114">"pata akaunti kwenye kifaa"</string>
@@ -613,6 +646,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Inaruhusu programu kuandikia kadi ya SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"badilisha/futa maudhui ya hifadhi ya media ya ndani."</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Inaruhusu programu kurekebisha maudhui ya hifadhi ya ndani vyombo vya habari."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"dhibiti hifadhi ya hati"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Huruhusu programu kudhibiti hifadhi ya hati."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"Fikia hifadhi ya nje ya watumiaji wote"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Inaruhusu programu kufikia hifadhi ya nje kwa watumiaji wote."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"fikia faili za mfumo za kache"</string>
@@ -625,10 +660,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Inaruhusu programu kudhibiti sera za mtandao na kufafanua sheria maalum za programu."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"badilisha uthibitishaji wa matumizi ya mtandao"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Huruhusu programu kurekebisha jinsi matumizi ya mtandao yana hesabika dhidi ya programu. Sio ya matumizi na programu za kawaida."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"rekebisha alama za soketi"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Inaruhusu programu kurekebisha alama za soketi za upelekaji"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"fikia arifa"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Huruhusu programu kurejesha, kuchunguza, na kuondoa arifa, ikiwa ni pamoja na zile zilizochapishwa na programu nyingine."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"unganisha kwenye huduma ya kisikilizi cha arifa"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Inaruhusu kishikilizi kuunganishwa kwenye kusano cha kiwango cha juu cha huduma ya kisikilizi cha arifa. Haipaswi kuhitajika tena kwa programu za kawaida."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"omba programu ya usakinishaji inayotolewa na mtoa huduma."</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Inaruhusu kishikiliaji kuomba programu ya usakinishaji inayotolewa na mto huduma. Haipaswi kuhitajika kwa programu za kawaida."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"sikiliza matukio katika hali za mtandao"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Huruhusu programu kusikiliza matukio katika hali za mtandao. Haipaswi kuhitajika kamwe kwa programu za kawaida."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Weka kanuni za nenosiri"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Dhibiti urefu na vibambo vinavyoruhusiwa katika manenosiri ya kufungua skrini."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Chunguza majaribio ya kutofun gua skrini"</string>
@@ -639,8 +680,8 @@
     <string name="policylab_forceLock" msgid="2274085384704248431">"Funga skrini"</string>
     <string name="policydesc_forceLock" msgid="1141797588403827138">"Dhibiti jinsi na wakati skrini inapofunga."</string>
     <string name="policylab_wipeData" msgid="3910545446758639713">"Futa data zote"</string>
-    <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Futa data ya kompyuta kibao bila ilani kwa kutekeleza urejeshaji wa mipangilio ya kiwandani."</string>
-    <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Futa data ya simu bila ya ilani kwa kutekeleza urejeshaji wa mipangilio ya kiwandani."</string>
+    <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Futa data ya kompyuta kibao bila ilani kwa kurejesha mipangilio ya mwanzo."</string>
+    <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Futa data ya simu bila ilani kwa kurejesha mipangilio ya mwanzo."</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Weka mbadala wa kifaa cha ulimwengu"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Weka kifaa mbadala cha ulimwengu kitakachotumiwa wakati wa kuwezesha sera. Msimamizi wa kwanza wa kifaa pekee anaweka matekelezo mbadala ya ulimwengu."</string>
     <string name="policylab_expirePassword" msgid="885279151847254056">"Weka muda wa kuisha wa nenosiri"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +836,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Ingiza SIM kadi."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM kadi haipatikani au haisomeki. Tafadhali ingiza SIM kadi."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"SIM kadi isiyotumika."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"SIM kadi yako imelemezwa kabisa."\n" Wasiliana na mtoa huduma wako wa pasi waya ili upate SIM kadi nyingine."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"SIM kadi yako imelemezwa kabisa.\n Wasiliana na mtoa huduma wako wa pasi waya ili upate SIM kadi nyingine."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Kitufe cha awali cha wimbo"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Kitufe cha wimbo unaofuata"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Kitufe cha kusitisha"</string>
@@ -808,11 +848,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Angalia Mwongozo wa Mtumiaji au wasiliana na Huduma ya Wateja."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM kadi imefungwa."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Inafungua SIM kadi..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Umekosea katika kuchora ruwaza yako ya kufungua mara <xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n" Jaribu tena kwa sekunde <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Umekosea mara <xliff:g id="NUMBER_0">%d</xliff:g> katika kuingiza nenosiri lako. "\n\n" Jaribu tena katika sekunde <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Umekosea katika kuingiza PIN yako mara <xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n" Jaribu tena katika sekunde <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Umekosea katika kuweka mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> bila kufaulu, utaulizwa kufungua kompyuta yako ndogo kwa kuingia kwa Google."\n\n" Jaribu tena katika sekunde <xliff:g id="NUMBER_2">%d</xliff:g>."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Umekosea kuchora mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> yasiyofaulu, utaulizwa kufungua simu kupitia kuingia Google."\n\n" Jaribu tena katika sekunde <xliff:g id="NUMBER_2">%d</xliff:g>."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Umekosea katika kuchora ruwaza yako ya kufungua mara <xliff:g id="NUMBER_0">%d</xliff:g>. \n\n Jaribu tena kwa sekunde <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Umekosea mara <xliff:g id="NUMBER_0">%d</xliff:g> katika kuingiza nenosiri lako. \n\n Jaribu tena katika sekunde <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Umekosea katika kuingiza PIN yako mara <xliff:g id="NUMBER_0">%d</xliff:g>. \n\n Jaribu tena katika sekunde <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Umekosea katika kuweka mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> bila kufaulu, utaulizwa kufungua kompyuta yako ndogo kwa kuingia kwa Google.\n\n Jaribu tena katika sekunde <xliff:g id="NUMBER_2">%d</xliff:g>."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Umekosea kuchora mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> yasiyofaulu, utaulizwa kufungua simu kupitia kuingia Google.\n\n Jaribu tena katika sekunde <xliff:g id="NUMBER_2">%d</xliff:g>."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Umejaribu kufungua kompyuta ndogo kwa njia isiyo sahihi mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya zaidi ya <xliff:g id="NUMBER_1">%d</xliff:g> majaribio yasiyofanikiwa, kompyuta ndogo itawekwa upya kwa kiwanda chaguo-msingi na data yote ya mtumiaji itapotea."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Umejaribu kufungua simu kwa njia isiyo sahihi mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> zaidi yasiyofanikiwa, simu itawekwa upya kwa kiwanda chaguo-msingi na data yote ya mtumiaji itapotea."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Umejaribu kufungua kompyuta ndogo kwa njia isiyo sahihi mara <xliff:g id="NUMBER">%d</xliff:g>. Kompyuta ndogo haitaweza kuwekwa upya kwa kiwanda chaguo-msingi."</string>
@@ -826,7 +866,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Nenosiri"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Ingia"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Jina la mtumiaji au nenosiri batili."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Umesahau jina lako la mtumiaji au nenosiri?"\n"Tembela "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Umesahau jina lako la mtumiaji au nenosiri?\nTembela "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Inakagua..."</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Fungua"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Sauti imewezeshwa"</string>
@@ -874,7 +914,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Thibitisha jinsi ya kuelekea"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Toka kwenye Ukurasa huu"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Bakia kwenye Ukurasa huu"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Je, una uhakika unataka kutoka kwenye ukurasa huu?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nJe, una uhakika unataka kutoka kwenye ukurasa huu?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Thibitisha"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Kidokezo: Gonga mara mbili ili kukuza ndani na nje."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Kujaza kiotomatiki"</string>
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"Kwa bahati mbaya, <xliff:g id="APPLICATION">%1$s</xliff:g> imekoma."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Kwa bahati mbaya, mchakato <xliff:g id="PROCESS">%1$s</xliff:g> umekoma."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> haifanyi kazi."\n\n"Unataka kuifunga?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Shughuli <xliff:g id="ACTIVITY">%1$s</xliff:g> haijibu. "\n\n" Unataka kuifunga?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> haifanyi kazi.\n\nUnataka kuifunga?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Shughuli <xliff:g id="ACTIVITY">%1$s</xliff:g> haijibu. \n\n Unataka kuifunga?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> haijibu. Unataka kufunga?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Mchakato <xliff:g id="PROCESS">%1$s</xliff:g> haijibu. "\n\n" Unataka kuifunga?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Mchakato <xliff:g id="PROCESS">%1$s</xliff:g> haijibu. \n\n Unataka kuifunga?"</string>
     <string name="force_close" msgid="8346072094521265605">"Sawa"</string>
     <string name="report" msgid="4060218260984795706">"Ripoti"</string>
     <string name="wait" msgid="7147118217226317732">"Subiri"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"Ukurasa umekwama. "\n" "\n" Je, unataka kuufunga?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Ukurasa umekwama. \n \n Je, unataka kuufunga?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Programu imeelekezwa kwingine"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g>inaendesha sasa."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilizinduliwa mwanzoni."</string>
@@ -1096,8 +1136,8 @@
     <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Wezesha tena hii katika mipangilio ya Mfumo &gt; Programu &gt;  iliyopakuliwa."</string>
     <string name="smv_application" msgid="3307209192155442829">"Programu <xliff:g id="APPLICATION">%1$s</xliff:g>  (utaratibu  <xliff:g id="PROCESS">%2$s</xliff:g>) imeenda kinyume na sera yake ya StrictMode."</string>
     <string name="smv_process" msgid="5120397012047462446">"Shughuli ya <xliff:g id="PROCESS">%1$s</xliff:g> imeenda kinyume na kulazimisha sera yake ya StrictMode."</string>
-    <string name="android_upgrading_title" msgid="1584192285441405746">"Android inapandishwa gredi..."</string>
-    <string name="android_upgrading_apk" msgid="7904042682111526169">"Inasadifisha programu <xliff:g id="NUMBER_0">%1$d</xliff:g> ya <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+    <string name="android_upgrading_title" msgid="1584192285441405746">"Toleo jipya la Android linawekwa..."</string>
+    <string name="android_upgrading_apk" msgid="7904042682111526169">"Inaboresha programu <xliff:g id="NUMBER_0">%1$d</xliff:g> ya <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Programu zinaanza"</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Inamaliza kuwasha."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> inaendelea"</string>
@@ -1173,7 +1213,7 @@
     <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Usiruhusu Kamwe"</string>
     <string name="sim_removed_title" msgid="6227712319223226185">"SIM kadi imeondolewa"</string>
     <string name="sim_removed_message" msgid="2333164559970958645">"mtandao wa simu hutapatika hadi uanzishe upya na SIM kadi halali iliyoingizwa."</string>
-    <string name="sim_done_button" msgid="827949989369963775">"Kwisha"</string>
+    <string name="sim_done_button" msgid="827949989369963775">"Nimemaliza"</string>
     <string name="sim_added_title" msgid="3719670512889674693">"SIM kadi imeongezwa"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"Anzisha upya kifaa chako ili kufikia mtandao wa simu."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"Anza upya"</string>
@@ -1256,24 +1296,28 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Inaruhusu programu kuomba huduma ya chombo chaguo-msingi kunakili maudhui. Si ya matumizi na programu za kawiada."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Fuatalia utoaji wa habari"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Inaruhusu programu kufuatilia utoaji wa habari kwa vifaa vingine vya nje."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Kufikia hifadhi salama ya ufunguo wa ulinzi"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Inaruhusu programu kufikia hifadhi salama ya ufunguo wa ulinzi."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Dhibiti uonyeshaji na ufichaji wa kilinda-funguo"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Huruhusu programu kudhibiti kilinda-funguo."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Gusa mara mbili kwa udhibiti cha kuza"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Haikuweza kuongeza wijeti."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Nenda"</string>
     <string name="ime_action_search" msgid="658110271822807811">"Tafuta"</string>
     <string name="ime_action_send" msgid="2316166556349314424">"Tuma"</string>
     <string name="ime_action_next" msgid="3138843904009813834">"Ifuatayo"</string>
-    <string name="ime_action_done" msgid="8971516117910934605">"Kwisha"</string>
+    <string name="ime_action_done" msgid="8971516117910934605">"Nimemaliza"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Iliyotangulia"</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Tekeleza"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Piga nambari "\n" kwa kutumia <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Unda anwani "\n" kwa kutumia <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Piga nambari \n kwa kutumia <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Unda anwani \n kwa kutumia <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Programu moja au zaidi zifuatazo zinaomba ruhusa ya kufikia akaunti yako, sasa na baadaye."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Unataka kuruhusu ombi hili?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Fikia ombi"</string>
     <string name="allow" msgid="7225948811296386551">"Ruhusu"</string>
     <string name="deny" msgid="2081879885755434506">"Kataza"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Idhini imeitishwa"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Idhini imeombwa"\n"ya akaunti<xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Idhini imeombwa\nya akaunti<xliff:g id="ACCOUNT">%s</xliff:g>."</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Mbinu ya uingizaji"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Sawazisha"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Ufikiaji"</string>
@@ -1309,7 +1353,7 @@
     <item quantity="one" msgid="8167147081136579439">"Linganisho 1"</item>
     <item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> ya <xliff:g id="TOTAL">%d</xliff:g>"</item>
   </plurals>
-    <string name="action_mode_done" msgid="7217581640461922289">"Kwisha"</string>
+    <string name="action_mode_done" msgid="7217581640461922289">"Nimemaliza"</string>
     <string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"Inaondoa hifadhi ya USB..."</string>
     <string name="progress_unmounting" product="default" msgid="1327894998409537190">"Inaondoa kadi ya SD..."</string>
     <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"Inafuta hifadhi ya USB..."</string>
@@ -1360,7 +1404,7 @@
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
     <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Ghairi"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Futa"</string>
-    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Imefanyika"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Nimemaliza"</string>
     <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Modi ya mabadiliko"</string>
     <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Songa"</string>
     <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Angalia zote"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Chagua shughuli"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Shiriki na"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Kifaa kimefungwa."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Inatuma…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Zindua Kivinjari?"</string>
@@ -1435,16 +1478,18 @@
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Mfumo"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Sauti ya Bluetooth"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Uonyeshaji usiotumia waya"</string>
-    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Kwisha"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Nimemaliza"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Towe la midia"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Inatambaza..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Inaunganisha..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Inapatikana"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"Haipatikani"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"Inatumika"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Skrini Iliyojengwa ndani"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"Skrini ya HDMI"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Uwekeleaji #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", salama"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Onyesho pasiwaya limeunganishwa"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Skrini hii inaonyesha kwenye kifaa kingine"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Tenganisha"</string>
@@ -1453,7 +1498,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Mchoro Usio sahihi"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Nenosiri Lisilo sahihi"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN isiyo sahihi"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Jaribu tena baada ya sekunde <xliff:g id="NUMBER">%d</xliff:g>."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Jaribu tena baada ya sekunde <xliff:g id="NUMBER">%1$d</xliff:g>."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Chora ruwaza yako"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Ingiza PIN ya SIM"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Ingiza PIN"</string>
@@ -1473,27 +1518,85 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Nenosiri"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Ingia"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Jina la mtumiaji au nenosiri batili."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Je, umesahau jina lako la mtumiaji au nenosiri?"\n"Tembela "<b>"Bgoogle.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Je, umesahau jina lako la mtumiaji au nenosiri?\nTembela "<b>"Bgoogle.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Inakagua akaunti…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Umeingiza nenosiri lako kwa makosa mara <xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n" Jaribu tena baada ya sekunde <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Umeingiza nenosiri lako kwa makosa mara <xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n" Jaribu tena baada ya sekunde <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Umechora ruwaza yako ya kufunga kwa makosa mara <xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n" Jaribu tena baada ya sekunde <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Umeingiza nenosiri lako kwa makosa mara <xliff:g id="NUMBER_0">%d</xliff:g>. \n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Umeingiza nenosiri lako kwa makosa mara <xliff:g id="NUMBER_0">%d</xliff:g>. \n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Umechora ruwaza yako ya kufunga kwa makosa mara <xliff:g id="NUMBER_0">%d</xliff:g>. \n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Umejaribu kufungua kompyuta ndogo kwa njia isiyo sahihi mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> zaidi yasiyofaulu, kompyuta ndogo itarejeshwa katika mfumo chaguo-msingi ilivyotoka kiwandani data yote ya mtumiaji itapotea."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Umejaribu kufungua simu kwa njia isiyo sahihi mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> zaidi yasiyofaulu, simu itarejeshwa katika mfumo chaguo-msingi ilivyotoka kiwandani na data yote ya mtumiaji itapotea."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Umejaribu kufungua kompyuta ndogo kwa njia isiyo sahihi mara <xliff:g id="NUMBER">%d</xliff:g>. Sasa kompyuta ndogo itarejeshwa katika mfumo chaguo-msingi ilivyotoka kiwandani."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Umejaribu kufungua simu kwa njia isiyo sahihi mara <xliff:g id="NUMBER">%d</xliff:g>. Sasa simu  itarejeshwa katika mfumo chaguo-msingi ilivyotoka kiwandani."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Umekosea katika kuweka mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> bila kufaulu, utaombwa kufungua kompyuta yako ndogo kwa kutumia akaunti yako ya barua pepe."\n\n" Jaribu tena baada ya sekunde <xliff:g id="NUMBER_2">%d</xliff:g>."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Umekosea kuchora mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> yasiyofaulu, utaombwa kufungua simu yako kwa kutumia akaunti ya barua pepe."\n\n" Jaribu tena baada ya sekunde <xliff:g id="NUMBER_2">%d</xliff:g>."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Umekosea katika kuweka mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> bila kufaulu, utaombwa kufungua kompyuta yako ndogo kwa kutumia akaunti yako ya barua pepe.\n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_2">%d</xliff:g>."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Umekosea kuchora mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> yasiyofaulu, utaombwa kufungua simu yako kwa kutumia akaunti ya barua pepe.\n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_2">%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">"Ondoa"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Ungependa kuongeza sauti kupita kiwango kinachopendekezwa?"\n"Kusikiliza kwa sauti ya juu kwa muda mrefu kunaweza kuharibu uwezo wako wa kusikia."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Ungependa kuongeza sauti kupita kiwango kinachopendekezwa?\nKusikiliza kwa sauti ya juu kwa muda mrefu kunaweza kuharibu uwezo wako wa kusikia."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Endelea kushikilia chini kwa vidole vyako viwili ili kuwezesha ufikivu."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Ufikivu umewezeshwa."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Ufikivu umeghairiwa."</string>
     <string name="user_switched" msgid="3768006783166984410">"Mtumiaji wa sasa <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Mmiliki"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Hitilafu"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Programu hii haiwezi kutumiwa na akaunti za wasifu zilizowekewa vikwazo"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Programu hii haiwezi kutumiwa na akaunti za wasifu zilizowekewa vikwazo"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Hakuna programu iliyopatikana ili kushughulikia kitendo hiki"</string>
     <string name="revoke" msgid="5404479185228271586">"Batilisha"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Barua"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Barua ya Serikali"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Kisheria"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Mwanasheria Mdogo"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Leja"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Kijigazeti"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Imeghairiwa"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Hitilafu katika kuandika maudhui"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"haijulikani"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Ingiza PIN ya msimamizi"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Ingiza PIN"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Sio sahihi"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN ya sasa"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"PIN mpya"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Thibitisha PIN mpya"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Unda PIN ya kurekebisha vikwazo"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PIN hazilingani. Jaribu tena."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"PIN ni fupi mno. Lazima iwe angalau tarakimu 4."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Jaribu tena baada ya sekunde 1"</item>
+    <item quantity="other" msgid="4730868920742952817">"Jaribu tena baada ya sekunde <xliff:g id="COUNT">%d</xliff:g>"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Jaribu tena baadaye"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Telezesha kidole kutoka ukingo wa skrini ili kuonyesha upau"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Telezesha kidole kutoka ukingo wa skrini ili kuonyesha upau wa mfumo"</string>
 </resources>
diff --git a/core/res/res/values-sw600dp-land/arrays.xml b/core/res/res/values-sw600dp-land/arrays.xml
index 5550216..5602a1c 100644
--- a/core/res/res/values-sw600dp-land/arrays.xml
+++ b/core/res/res/values-sw600dp-land/arrays.xml
@@ -19,54 +19,4 @@
 -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
 
-    <!-- Resources for GlowPadView in LockScreen -->
-    <array name="lockscreen_targets_when_silent">
-        <item>@drawable/ic_lockscreen_unlock</item>
-        <item>@null</item>
-        <item>@drawable/ic_lockscreen_soundon</item>
-        <item>@null</item>
-    </array>
-
-    <array name="lockscreen_target_descriptions_when_silent">
-        <item>@string/description_target_unlock</item>
-        <item>@null</item>
-        <item>@string/description_target_soundon</item>
-        <item>@null</item>
-    </array>
-
-    <array name="lockscreen_direction_descriptions">
-        <item>@string/description_direction_right</item>
-        <item>@null</item>
-        <item>@string/description_direction_left</item>
-        <item>@null</item>
-    </array>
-
-    <array name="lockscreen_targets_when_soundon">
-        <item>@drawable/ic_lockscreen_unlock</item>
-        <item>@null</item>
-        <item>@drawable/ic_lockscreen_silent</item>
-        <item>@null</item>
-    </array>
-
-    <array name="lockscreen_target_descriptions_when_soundon">
-        <item>@string/description_target_unlock</item>
-        <item>@null</item>
-        <item>@string/description_target_silent</item>
-        <item>@null</item>
-    </array>
-
-    <array name="lockscreen_targets_with_camera">
-        <item>@drawable/ic_lockscreen_unlock</item>
-        <item>@drawable/ic_action_assist_generic</item>
-        <item>@drawable/ic_lockscreen_camera</item>
-        <item>@null</item>
-    </array>
-
-    <array name="lockscreen_target_descriptions_with_camera">
-        <item>@string/description_target_unlock</item>
-        <item>@string/description_target_search</item>
-        <item>@string/description_target_camera</item>
-        <item>@null</item>
-    </array>
-
 </resources>
diff --git a/core/res/res/values-sw600dp-port/refs.xml b/core/res/res/values-sw600dp-port/refs.xml
new file mode 100644
index 0000000..cda38cf
--- /dev/null
+++ b/core/res/res/values-sw600dp-port/refs.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2013, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+-->
+<resources>
+    <item type="string" name="transient_navigation_confirmation">@string/transient_navigation_confirmation_long</item>
+</resources>
\ No newline at end of file
diff --git a/core/res/res/values-sw600dp/alias.xml b/core/res/res/values-sw600dp/alias.xml
deleted file mode 100644
index bf3eecb..0000000
--- a/core/res/res/values-sw600dp/alias.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/assets/res/any/colors.xml
-**
-** 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.
-*/
--->
-<resources>
-    <!-- Alias used to reference one of two possible layouts in keyguard.  -->
-    <item type="layout" name="keyguard_eca">@android:layout/keyguard_emergency_carrier_area</item>
-</resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 3825b40..a19ddaa 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -131,6 +131,11 @@
     <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="default" msgid="3475999286680000541">"ที่เก็บข้อมูลโทรศัพท์เต็ม ลบบางไฟล์เพื่อเพิ่มที่ว่าง"</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"เครือข่ายอาจได้รับการตรวจสอบ"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"ฉัน"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"ตัวเลือกของแท็บเล็ต"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"ตัวเลือกโทรศัพท์"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"อนุญาตให้แอปพลิเคชันย้ายงานไปยังส่วนหน้าและพื้นหลัง แอปพลิเคชันอาจดำเนินการโดยไม่รอคำสั่งจากคุณ"</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"หยุดแอปพลิเคชันที่ทำงานอยู่"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"อนุญาตให้แอปพลิเคชันลบงานออกและยุติแอปพลิเคชันต่างๆ ของงานนั้น แอปพลิเคชันที่เป็นอันตรายอาจทำให้แอปพลิเคชันอื่นๆ ทำงานได้ไม่ถูกต้อง"</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"จัดการชุดรายการกิจกรรม"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"อนุญาตให้แอปเพิ่ม นำออก และแก้ไขชุดรายการกิจกรรมที่แอปอื่นใช้งาน แอปที่อันตรายอาจรบกวนการทำงานของแอปอื่น"</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"เริ่มต้นกิจกรรมใดๆ"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"อนุญาตให้แอปพลิเคชันเริ่มกิจกรรม ไม่ว่าการอนุญาตหรือสถานะที่ส่งออกจะเป็นอย่างไรก็ตาม"</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"ตั้งค่าความเข้ากันได้ของหน้าจอ"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"อนุญาตให้ผู้ใช้เชื่อมโยงกับส่วนติดต่อผู้ใช้ระดับสูงสุดของวิธีการป้อนข้อมูล ไม่ควรต้องใช้สำหรับแอปพลิเคชันทั่วไป"</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"เชื่อมโยงกับบริการการเข้าถึง"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"อนุญาตให้เจ้าของเชื่อมโยงกับส่วนติดต่อระดับบนสุดของบริการการเข้าถึง ซึ่งแอปพลิเคชันทั่วไปไม่จำเป็นต้องใช้"</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"เชื่อมโยงกับบริการการพิมพ์"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"อนุญาตให้ผู้ใช้เชื่อมโยงกับอินเทอร์เฟซระดับสูงสุดของบริการการพิมพ์ ซึ่งแอปทั่วไปไม่จำเป็นต้องใช้"</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"เชื่อมโยงกับบริการจัดคิวและจัดการการพิมพ์"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"อนุญาตให้เชื่อมโยงกับอินเทอร์เฟซระดับสูงสุดของบริการจัดคิวและจัดการการพิมพ์ ซึ่งแอปทั่วไปไม่จำเป็นต้องใช้"</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"เชื่อมโยงกับบริการ NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"อนุญาตให้ผู้ถือเชื่อมโยงกับแอปพลิเคชันที่เลียนแบบการ์ด NFC ไม่จำเป็นสำหรับแอปทั่วไป"</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"เชื่อมโยงกับบริการข้อความ"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"อนุญาตให้ผู้ใช้เชื่อมโยงกับส่วนติดต่อผู้ใช้ระดับสูงสุดของบริการข้อความ (เช่น บริการเครื่องตรวจตัวสะกด) ไม่ควรต้องใช้สำหรับแอปพลิเคชันทั่วไป"</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"เชื่อมโยงกับบริการ VPN"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"อนุญาตให้ผู้ใช้เชื่อมโยงกับส่วนติดต่อผู้ใช้ระดับสูงสุดของบริการวิดเจ็ต ไม่ควรต้องใช้สำหรับแอปพลิเคชันทั่วไป"</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"ติดต่อกับผู้ดูแลอุปกรณ์"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"อนุญาตให้ผู้ใช้ส่งการติดต่อไปยังโปรแกรมควบคุมอุปกรณ์ ไม่ควรต้องใช้สำหรับแอปพลิเคชันทั่วไป"</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"เพิ่มหรือลบผู้ดูแลระบบอุปกรณ์"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"อนุญาตให้เจ้าของเพิ่มหรือลบผู้ดูแลระบบอุปกรณ์ที่ใช้งาน ไม่ควรต้องใช้สำหรับแอปปกติ"</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"เปลี่ยนการวางแนวหน้าจอ"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"อนุญาตให้แอปพลิเคชันเปลี่ยนการหมุนของหน้าจอได้ตลอดเวลา ไม่ควรต้องใช้สำหรับแอปพลิเคชันทั่วไป"</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"เปลี่ยนความเร็วของตัวชี้"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"อนุญาตให้แอปพลิเคชันอ่านจากไฟล์บันทึกต่างๆ ของระบบ เพื่อค้นหาข้อมูลทั่วไปเกี่ยวกับสิ่งที่คุณกำลังทำอยู่กับโทรศัพท์ ซึ่งอาจรวมไปถึงข้อมูลส่วนบุคคลหรือส่วนตัว"</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"ใช้ตัวถอดรหัสสื่อใดๆ ก็ได้สำหรับการเล่น"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"อนุญาตให้แอปพลิเคชันใช้ตัวถอดรหัสสื่อใดก็ได้ที่ติดตั้งไว้เพื่อถอดรหัสสำหรับการเล่น"</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"จัดการข้อมูลรับรองที่เชื่อถือได้"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"อนุญาตให้แอปติดตั้งและถอนการติดตั้งใบรับรอง CA ในฐานะข้อมูลรับรองที่เชื่อถือได้"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"อ่าน/เขียนไปยังรีซอร์สที่เป็นเจ้าของโดยกลุ่มวินิจฉัย"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"อนุญาตให้แอปพลิเคชันอ่านและเขียนไปยังทรัพยากรที่เป็นของกลุ่มวินิจฉัย เช่น ไฟล์ใน /dev การทำเช่นนี้อาจส่งผลต่อความเสถียรและความปลอดภัยของระบบ และควรใช้สำหรับการวินิจฉัยเกี่ยวกับฮาร์ดแวร์โดยเฉพาะที่ทำโดยผู้ผลิตหรือผู้ให้บริการเท่านั้น"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"เปิดหรือปิดใช้งานคอมโพเนนต์ของแอปพลิเคชัน"</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"อนุญาตให้แอปกำหนดค่าและเชื่อมต่อกับจอแสดงผล WiFi ได้"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"ควบคุมการแสดงผลด้วย WiFi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"อนุญาตให้แอปควบคุมคุณลักษณะต่างๆ ในระดับล่างของการแสดงผลด้วย WiFi"</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"บันทึกเอาต์พุตเสียง"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"อนุญาตให้แอปบันทึกและเปลี่ยนเส้นทางเอาต์พุตเสียง"</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"บันทึกเอาต์พุตวิดีโอ"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"อนุญาตให้แอปบันทึกและเปลี่ยนเส้นทางเอาต์พุตวิดีโอ"</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"บันทึกเอาต์พุตเสียงที่ปลอดภัย"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"อนุญาตให้แอปบันทึกและเปลี่ยนเส้นทางเอาต์พุตของวิดีโอที่ปลอดภัย"</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"เปลี่ยนการตั้งค่าเสียงของคุณ"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"อนุญาตให้แอปพลิเคชันปรับเปลี่ยนการตั้งค่าเสียงทั้งหมดได้ เช่น ระดับเสียงและลำโพงที่จะใช้งาน"</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"บันทึกเสียง"</string>
@@ -525,6 +552,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"ป้องกันไม่ให้โทรศัพท์เข้าโหมดสลีป"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"อนุญาตให้แอปพลิเคชันป้องกันไม่ให้แท็บเล็ตเข้าสู่โหมดสลีป"</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"อนุญาตให้แอปพลิเคชันป้องกันไม่ให้โทรศัพท์เข้าสู่โหมดสลีป"</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"เปิดหรือปิดเครื่องแท็บเล็ต"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"เปิดหรือปิดโทรศัพท์"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"อนุญาตให้แอปพลิเคชันเปิดหรือปิดแท็บเล็ต"</string>
@@ -613,6 +646,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"อนุญาตให้แอปพลิเคชันเขียนลงบนการ์ด SD"</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"แก้/ลบเนื้อหาข้อมูลสื่อภายใน"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"อนุญาตให้แอปพลิเคชันแก้ไขเนื้อหาของที่เก็บข้อมูลสื่อภายใน"</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"จัดการที่เก็บเอกสาร"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"อนุญาตให้แอปจัดการที่เก็บเอกสาร"</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"เข้าถึงที่จัดเก็บภายนอกของทุกคน"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"อนุญาตให้แอปพลิเคชันเข้าถึงที่จัดเก็บข้อมูลภายนอกสำหรับผู้ใช้ทั้งหมด"</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"เข้าถึงระบบไฟล์แคช"</string>
@@ -625,10 +660,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"อนุญาตให้แอปพลิเคชันจัดการนโยบายเครือข่ายและกำหนดกฎเฉพาะแอปพลิเคชัน"</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"แก้ไขการบันทึกบัญชีการใช้งานเครือข่าย"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"อนุญาตให้แอปพลิเคชันแก้ไขวิธีการบันทึกบัญชีการใช้งานเครือข่ายของแอปพลิเคชัน ไม่ใช้สำหรับแอปพลิเคชันทั่วไป"</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"แก้ไขเครื่องหมายซ็อกเก็ต"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"อนุญาตให้แอปแก้ไขเครื่องหมายซ็อกเก็ตสำหรับการกำหนดเส้นทาง"</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_invokeCarrierSetup" msgid="3699600833975117478">"เรียกใช้แอปการกำหนดค่าของผู้ให้บริการ"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"อนุญาตให้ผู้ใช้สามารถเรียกใช้แอปการกำหนดค่าของผู้ให้บริการ ซึ่งแอปทั่วไปไม่จำเป็นต้องใช้"</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"ฟังข้อสังเกตเกี่ยวกับสภาวะของเครือข่าย"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"อนุญาตให้แอปพลิเคชันฟังข้อสังเกตเกี่ยวกับสภาวะของเครือข่าย ไม่จำเป็นสำหรับแอปปกติ"</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"ตั้งค่ากฎรหัสผ่าน"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"ควบคุมความยาวและอักขระที่อนุญาตให้ใช้ในรหัสผ่านการปลดล็อกหน้าจอ"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"ตรวจสอบความพยายามในการปลดล็อกหน้าจอ"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <string name="imProtocolGoogleTalk" msgid="493902321140277304">"แฮงเอาท์"</string>
     <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string>
     <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string>
     <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string>
@@ -796,7 +836,7 @@
     <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="201594905152746886">"ปุ่มแทร็กก่อนหน้า"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"ปุ่มแทร็กถัดไป"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"ปุ่มหยุดชั่วคราว"</string>
@@ -808,11 +848,11 @@
     <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">%d</xliff:g> ครั้งแล้ว"\n\n"โปรดลองอีกครั้งในอีก <xliff:g id="NUMBER_1">%d</xliff:g> วินาที"</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"คุณพิมพ์รหัสผ่านไม่ถูกต้องไป <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว"\n\n"ลองอีกครั้งใน <xliff:g id="NUMBER_1">%d</xliff:g> วินาที"</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"คุณพิมพ์ PIN ไม่ถูกต้องไป <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว"\n\n"ลองอีกครั้งใน <xliff:g id="NUMBER_1">%d</xliff:g> วินาที"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้องไป <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว หากทำไม่สำเร็จอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง ระบบจะขอให้คุณปลดล็อกแท็บเล็ตโดยใช้การลงชื่อเข้าใช้ Google"\n\n"โปรดลองอีกครั้งในอีก <xliff:g id="NUMBER_2">%d</xliff:g> วินาที"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้อง <xliff:g id="NUMBER_0">%d</xliff:g> ครั้ง หากทำไม่สำเร็จอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง ระบบจะขอให้คุณปลดล็อกโทรศัพท์โดยใช้การลงชื่อเข้าใช้ Google"\n\n"โปรดลองอีกครั้งในอีก <xliff:g id="NUMBER_2">%d</xliff:g> วินาที"</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้องไป <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว\n\nโปรดลองอีกครั้งในอีก <xliff:g id="NUMBER_1">%d</xliff:g> วินาที"</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"คุณพิมพ์รหัสผ่านไม่ถูกต้องไป <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว\n\nลองอีกครั้งใน <xliff:g id="NUMBER_1">%d</xliff:g> วินาที"</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"คุณพิมพ์ PIN ไม่ถูกต้องไป <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว\n\nลองอีกครั้งใน <xliff:g id="NUMBER_1">%d</xliff:g> วินาที"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้องไป <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว หากทำไม่สำเร็จอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง ระบบจะขอให้คุณปลดล็อกแท็บเล็ตโดยใช้การลงชื่อเข้าใช้ Google\n\nโปรดลองอีกครั้งในอีก <xliff:g id="NUMBER_2">%d</xliff:g> วินาที"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้อง <xliff:g id="NUMBER_0">%d</xliff:g> ครั้ง หากทำไม่สำเร็จอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง ระบบจะขอให้คุณปลดล็อกโทรศัพท์โดยใช้การลงชื่อเข้าใช้ Google\n\nโปรดลองอีกครั้งในอีก <xliff:g id="NUMBER_2">%d</xliff:g> วินาที"</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"คุณพยายามปลดล็อกแท็บเล็ตอย่างไม่ถูกต้องแล้ว <xliff:g id="NUMBER_0">%d</xliff:g> ครั้ง หากการพยายามไม่สำเร็จอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง แท็บเล็ตจะถูกรีเซ็ตเป็นค่าเริ่มต้นจากโรงงานและข้อมูลทั้งหมดของผู้ใช้จะหายไป"</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"คุณพยายามปลดล็อกโทรศัพท์อย่างไม่ถูกต้องแล้ว <xliff:g id="NUMBER_0">%d</xliff:g> ครั้ง หากการพยายามไม่สำเร็จอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง โทรศัพท์จะถูกรีเซ็ตเป็นค่าเริ่มต้นจากโรงงานและข้อมูลทั้งหมดของผู้ใช้จะหายไป"</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"คุณพยายามปลดล็อกแท็บเล็ตอย่างไม่ถูกต้องแล้ว <xliff:g id="NUMBER">%d</xliff:g> ครั้ง ขณะนี้แท็บเล็ตจะถูกรีเซ็ตเป็นค่าเริ่มต้นจากโรงงาน"</string>
@@ -826,7 +866,7 @@
     <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_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>
@@ -874,7 +914,7 @@
     <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="autofill_this_form" msgid="4616758841157816676">"ป้อนอัตโนมัติ"</string>
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"ขออภัย <xliff:g id="APPLICATION">%1$s</xliff:g> หยุดการทำงานแล้ว"</string>
     <string name="aerr_process" msgid="4507058997035697579">"ขออภัย กระบวนการ <xliff:g id="PROCESS">%1$s</xliff:g> หยุดการทำงานแล้ว"</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> ไม่ตอบสนอง"\n\n"คุณต้องการปิดหรือไม่"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"กิจกรรม <xliff:g id="ACTIVITY">%1$s</xliff:g> ไม่ตอบสนอง"\n\n"คุณต้องการปิดหรือไม่"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> ไม่ตอบสนอง\n\nคุณต้องการปิดหรือไม่"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"กิจกรรม <xliff:g id="ACTIVITY">%1$s</xliff:g> ไม่ตอบสนอง\n\nคุณต้องการปิดหรือไม่"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> ไม่ตอบสนอง คุณต้องการปิดหรือไม่"</string>
-    <string name="anr_process" msgid="6513209874880517125">"กระบวนการ <xliff:g id="PROCESS">%1$s</xliff:g> ไม่ตอบสนอง"\n\n"คุณต้องการปิดหรือไม่"</string>
+    <string name="anr_process" msgid="6513209874880517125">"กระบวนการ <xliff:g id="PROCESS">%1$s</xliff:g> ไม่ตอบสนอง\n\nคุณต้องการปิดหรือไม่"</string>
     <string name="force_close" msgid="8346072094521265605">"ตกลง"</string>
     <string name="report" msgid="4060218260984795706">"รายงาน"</string>
     <string name="wait" msgid="7147118217226317732">"รอ"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"หน้าเว็บนี้ไม่ตอบสนอง"\n\n"คุณต้องการปิดหรือไม่"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"หน้าเว็บนี้ไม่ตอบสนอง\n\nคุณต้องการปิดหรือไม่"</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>
@@ -1256,6 +1296,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"อนุญาตให้แอปพลิเคชันเรียกใช้บริการที่เก็บค่าเริ่มต้นเพื่อคัดลอกเนื้อหา ไม่ใช้สำหรับแอปพลิเคชันทั่วไป"</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"กำหนดเส้นทางเอาต์พุตของสื่อ"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"อนุญาตให้แอปพลิเคชันกำหนดเส้นทางเอาต์พุตของสื่อไปยังอุปกรณ์ภายนอกอื่นๆ"</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"เข้าถึงพื้นที่จัดเก็บที่รักษาความปลอดภัยด้วยคีย์การ์ด"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"อนุญาตให้แอปพลิเคชันเข้าถึงพื้นที่จัดเก็บที่รักษาความปลอดภัยด้วยคีย์การ์ด"</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"ควบคุมการแสดงผลและการซ่อนตัวล็อกปุ่มกด"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"อนุญาตให้แอปพลิเคชันควบคุมตัวล็อกปุ่มกด"</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"แตะสองครั้งเพื่อควบคุมการซูม"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"ไม่สามารถเพิ่มวิดเจ็ต"</string>
     <string name="ime_action_go" msgid="8320845651737369027">"ไป"</string>
@@ -1265,15 +1309,15 @@
     <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">"หมุนหมายเลข "\n" โดยใช้ <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"สร้างที่อยู่ติดต่อ "\n"โดยใช้ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"หมุนหมายเลข \n โดยใช้ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"สร้างที่อยู่ติดต่อ \nโดยใช้ <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"แอปพลิเคชันต่อไปนี้ขอให้มีการอนุญาตให้เข้าถึงบัญชีของคุณในขณะนี้และในอนาคต"</string>
     <string name="grant_credentials_permission_message_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">"การอนุญาตที่ขอ"\n"สำหรับบัญชี <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"การอนุญาตที่ขอ\nสำหรับบัญชี <xliff:g id="ACCOUNT">%s</xliff:g>"</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>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"ดูทั้งหมด"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"เลือกกิจกรรม"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"แบ่งปันกับ"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"ล็อกอุปกรณ์อยู่"</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"กำลังส่ง…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"เปิดเบราว์เซอร์หรือไม่"</string>
@@ -1441,10 +1484,12 @@
     <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>
+    <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_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="wifi_display_notification_title" msgid="2223050649240326557">"เชื่อมต่อการแสดงผลแบบไร้สายอยู่"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"หน้าจอนี้กำลังแสดงบนอุปกรณ์อื่น"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"หยุดเชื่อมต่อ"</string>
@@ -1453,7 +1498,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">%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 ของซิม"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"ป้อน PIN"</string>
@@ -1473,27 +1518,85 @@
     <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_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">%d</xliff:g> ครั้งแล้ว "\n\n"โปรดลองอีกครั้งใน <xliff:g id="NUMBER_1">%d</xliff:g> วินาที"</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"คุณพิมพ์รหัสผ่านไม่ถูกต้องไป <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว "\n\n"โปรดลองอีกครั้งใน <xliff:g id="NUMBER_1">%d</xliff:g> วินาที"</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้องไป <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว "\n\n"โปรดลองอีกครั้งใน <xliff:g id="NUMBER_1">%d</xliff:g> วินาที"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"คุณพิมพ์ PIN ไม่ถูกต้องไป <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว \n\nโปรดลองอีกครั้งใน <xliff:g id="NUMBER_1">%d</xliff:g> วินาที"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"คุณพิมพ์รหัสผ่านไม่ถูกต้องไป <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว \n\nโปรดลองอีกครั้งใน <xliff:g id="NUMBER_1">%d</xliff:g> วินาที"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้องไป <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว \n\nโปรดลองอีกครั้งใน <xliff:g id="NUMBER_1">%d</xliff:g> วินาที"</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"คุณพยายามปลดล็อกแท็บเล็ตอย่างไม่ถูกต้อง <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว หากพยายามแล้วไม่สำเร็จอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง แท็บเล็ตจะถูกรีเซ็ตเป็นค่าเริ่มต้นจากโรงงานและข้อมูลผู้ใช้ทั้งหมดจะหายไป"</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"คุณพยายามปลดล็อกโทรศัพท์อย่างไม่ถูกต้อง <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว หากพยายามแล้วไม่สำเร็จอีก <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> ครั้งแล้ว หากทำไม่สำเร็จอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง ระบบจะขอให้คุณปลดล็อกแท็บเล็ตโดยใช้บัญชีอีเมล"\n\n" โปรดลองอีกครั้งใน <xliff:g id="NUMBER_2">%d</xliff:g> วินาที"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้อง <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว หากทำไม่สำเร็จอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง ระบบจะขอให้คุณปลดล็อกโทรศัพท์โดยใช้ับัญชีอีเมล"\n\n" โปรดลองอีกครั้งในอีก <xliff:g id="NUMBER_2">%d</xliff:g> วินาที"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้อง <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว หากทำไม่สำเร็จอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง ระบบจะขอให้คุณปลดล็อกแท็บเล็ตโดยใช้บัญชีอีเมล\n\n โปรดลองอีกครั้งใน <xliff:g id="NUMBER_2">%d</xliff:g> วินาที"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้อง <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว หากทำไม่สำเร็จอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง ระบบจะขอให้คุณปลดล็อกโทรศัพท์โดยใช้ับัญชีอีเมล\n\n โปรดลองอีกครั้งในอีก <xliff:g id="NUMBER_2">%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="7324161939475478066">"ในกรณีที่ต้องการเพิ่มระดับเสียงจนเกินระดับที่แนะนำ"\n"การฟังเสียงดังเป็นเวลานานอาจทำให้การได้ยินของคุณบกพร่องได้"</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"ในกรณีที่ต้องการเพิ่มระดับเสียงจนเกินระดับที่แนะนำ\nการฟังเสียงดังเป็นเวลานานอาจทำให้การได้ยินของคุณบกพร่องได้"</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"ใช้สองนิ้วแตะค้างไว้เพื่อเปิดใช้งานการเข้าถึง"</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"เปิดใช้งานการเข้าถึงแล้ว"</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"ยกเลิกการเข้าถึงแล้ว"</string>
     <string name="user_switched" msgid="3768006783166984410">"ผู้ใช้ปัจจุบัน <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="app_no_restricted_accounts" msgid="4011285085817350390">"แอปพลิเคชันนี้ไม่สนับสนุนบัญชีที่มีโปรไฟล์ที่ถูกจำกัด"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"แอปนี้ไม่สนับสนุนบัญชีที่โปรไฟล์ถูกจำกัด"</string>
     <string name="app_not_found" msgid="3429141853498927379">"ไม่พบแอปพลิเคชันสำหรับการทำงานนี้"</string>
     <string name="revoke" msgid="5404479185228271586">"เพิกถอน"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"จดหมาย"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"ยกเลิก"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"ข้อผิดพลาดในการเขียนเนื้อหา"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"ไม่ทราบ"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"ป้อน 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>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"PIN ใหม่"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"ยืนยัน PIN ใหม่"</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_too_short" msgid="8173982756265777792">"PIN สั้นเกินไป ต้องมีอย่างน้อย 4 หลัก"</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"ลองอีกใน 1 วิ"</item>
+    <item quantity="other" msgid="4730868920742952817">"ลองอีกใน <xliff:g id="COUNT">%d</xliff:g> วินาที"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"ลองอีกครั้งในภายหลัง"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"กวาดขอบของหน้าจอเพื่อแสดงแถบ"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"กวาดจากขอบของหน้าจอเพื่อแสดงแถบระบบ"</string>
 </resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 401fa42..c357eb4 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -131,6 +131,11 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Masyadong maraming pagtanggal ng <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Puno na ang storage ng tablet. Magtanggal ng ilang file upang magbakante ng espasyo."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Puno na ang storage ng telepono. Magtanggal ng ilang file upang magbakante ng espasyo."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Maaaring sinusubaybayan ang network"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Ako"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Mga pagpipilian sa tablet"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Mga pagpipilian sa telepono"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Pinapayagan ang app na maglipat ng mga gawain sa foreground at background. Maaari itong gawin ng app nang wala ng iyong input."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"ihinto ang pagpapatakbo ng apps"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Pinapayagan ang app na mag-alis ng mga gawain at i-off ang apps nito. Maaaring maantala ng nakakahamak na apps ang pagkilos ng iba pang apps."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"pamahalaan ang mga stack ng aktibidad"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Nagbibigay-daan sa app na dagdagan, alisin, at baguhin ang mga stack ng aktibidad kung saan gumagana ang iba pang apps. Maaaring makaabala ang nakakahamak na apps sa pagkilos ng iba pang apps."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"magsimula ng anumang aktibidad"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Binibigyang-daan ang app na magsimula ng anumang aktibidad, may proteksyon man ng pahintulot o na-export na katayuan."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"itakda ang pagkakatugma ng screen"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Pinapayagan ang may-hawak na sumailalim sa nangungunang interface ng pamamaraan ng pag-input. Hindi kailanman dapat na kailanganin para sa normal na apps."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"sumailalim sa isang serbisyo sa accessibility"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Binibigyang-daan ang may-ari na sumailalim sa nasa nangungunang antas na interface ng isang serbisyo sa accessibility. Hindi dapat kailanman kailanganin para sa normal na apps."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"sumailalim sa isang serbisyo sa pag-print"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Nagbibigay-daan sa may-ari na sumailalim sa interface sa nangungunang antas ng isang serbisyo sa pag-print. Hindi dapat kailanganin para sa normal na apps kahit kailan."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"mag-bind sa isang serbisyo ng print spooler"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Nagbibigay-daan sa may-ari na mag-bind sa top-level interface ng isang serbisyo ng print spooler. Hindi dapat kailanganin para sa normal na apps."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"i-bind sa serbisyo ng NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Nagbibigay-daan sa may-ari na mag-bind sa mga application na nag-e-emulate ng mga NFC card. Hindi dapat kailanman kailanganin para sa normal na apps."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"sumailalim sa serbisyo ng teksto"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Pinapayagan ang may-hawak na sumailalim sa nangungunang antas na interface (hal. SpellCheckerService). Hindi kailanman dapat na kailanganin para sa normal na apps."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"sumailalim sa isang serbisyo ng VPN"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Pinapayagan ang may-hawak na sumailalim sa nangungunang interface ng serbisyo ng widget. Hindi kailanman dapat na kailanganin para sa normal na apps."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"makipag-ugnay sa tagapangasiwa ng device"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Pinapayagan ang mga may-ari na magpadala ng mga layunin sa administrator ng device. Hindi kailanman dapat na kailanganin para sa normal na apps."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"magdagdag o mag-alis ng admin ng device"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Pinapayagan ang may-ari na magdagdag o mag-alis ng mga aktibong administrator ng device. Hindi dapat kailanganin kailanman para sa normal na apps."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"baguhin ang orientation ng screen"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Pinapayagan ang app na baguhin ang pag-ikot ng screen anumang oras. Hindi kailanman dapat na kailanganin para sa normal na apps."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"baguhin ang bilis ng pointer"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Pinapayagan ang app na magbasa mula sa iba\'t ibang mga file ng log ng system. Pinapayagan ito nito na tumuklas ng pangkalahatang impormasyon tungkol sa kung ano ang iyong ginagawa sa telepono, potensyal na kabilang ang personal o pribadong impormasyon."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"gumamit ng anumang media decoder para sa pag-playback"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Pinapayagan ang app na gumamit ng anumang naka-install na media decoder upang mag-decode para sa pag-playback."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"mga pinamamahalaang pinagkakatiwalaang kredensyal"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Pinapayagan ang app na mag-install at mag-uninstall ng mga CA certificate bilang mga pinagkakatiwalaang kredensyal."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"magbasa/magsulat sa mga mapagkukunang pag-aari ng diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Pinapayagan ang app na magbasa at magsulat sa anumang mapagkukunang pag-aari ng pangkat ng diag; halimbawa, mga file sa /dev. Maaaring potensyal na maapektuhan nito ang katatagan at seguridad ng system. Dapat LAMANG itong gamitin para sa diagnostics na tukoy sa hardware ng tagagawa o operator."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"paganahin o huwag paganahin ang mga bahagi ng app"</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Pinapayagan ang app na mag-configure at kumonekta sa mga Wifi display."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"magkontrol ng mga Wifi display"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Pinapayagan ang app na magkontrol ng mga tampok sa mababang antas ng mga dispay ng Wifi."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"kumuha ng audio output"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Pinapayagan ang app na kumuha at mag-redirect ng audio output."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"kumuha ng video output"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Pinapayagan ang app na kumuha at mag-redirect ng video output."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"kumuha ng secure na video output"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Pinapayagan ang app na kumuha at mag-redirect ng secure na video output."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"baguhin ang mga setting ng iyong audio"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Pinapayagan ang app na baguhin ang mga pandaigdigang setting ng audio gaya ng volume at kung aling speaker ang ginagamit para sa output."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"mag-record ng audio"</string>
@@ -525,6 +552,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"pigilan ang telepono mula sa paghinto"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Pinapayagan ang app na pigilan ang tablet mula sa pag-sleep."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Pinapayagan ang app na pigilan ang telepono mula sa pag-sleep."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"i-on o i-off ang power tablet"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"i-on o i-off ang telepono"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Pinapayagan ang app na i-on o i-off ang tablet."</string>
@@ -613,6 +646,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Pinapayagan ang app na magsulat sa SD card."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"baguhin/tanggalin ang mga nilalaman ng panloob na imbakan ng media"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Pinapayagan ang app na baguhin ang mga nilalaman ng panloob na media storage."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"pamahalaan document storage"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Pinapayagan ang app na pamahalaan ang storage ng dokumento."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"i-access panlabas na storage ng user"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Pinapayagan ang app na mag-access ng panlabas na storage para sa lahat ng user."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"i-access ang cache filesystem"</string>
@@ -625,10 +660,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Pinapayagan ang app na pamahalaan ang mga patakaran ng network at ilarawan ang mga patakarang tukoy sa app."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"baguhin ang pagkukuwenta sa paggamit ng network"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Pinapayagan ang app na baguhin kung paano isinasaalang-alang ang paggamit ng network laban sa apps. Hindi para sa paggamit ng normal na apps."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"baguhin ang mga socket mark"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Nagbibigay-daan sa app na baguhin ang mga socket mark para sa pagruruta"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"i-access ang mga notification"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Pinapayagan ang app na kumuha, sumuri, at mag-clear ng mga notification, kabilang ang mga na-post ng iba pang apps."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"mapailalim sa isang serbisyo ng notification listener"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Nagbibigay-daan sa may-ari na mapailalim sa interface sa tuktok na antas ng isang serbisyo ng notification listener. Hindi dapat kailanganin para sa karaniwang apps kahit kailan."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"paganahin ang app ng configuration na ibinigay ng carrier"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Nagbibigay-daan sa may-ari na paganahin ang app ng configuration na ibinigay ng carrier. Hindi dapat kailanganin para sa normal na apps kahit kailan."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"makinig sa mga obserbasyon sa mga kundisyon ng network"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Nagbibigay-daan sa isang application na makinig sa mga obserbasyon sa mga kundisyon ng network. Dapat na hindi kailanman kakailanganin para sa normal na apps."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Magtakda ng mga panuntunan sa password"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrolin ang haba at mga character na pinapayagan sa mga password sa pag-unlock ng screen."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Subaybayan ang mga pagsubok sa pag-unlock ng screen"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +836,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Maglagay ng isang SIM card."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Nawawala o hindi nababasa ang SIM card. Maglagay ng isang SIM card."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Hindi nagagamit na SIM card."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Ang iyong SIM card ay permanenteng hindi pinagana."\n" Makipag-ugnay sa iyong wireless service provider para sa isa pang SIM card."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Ang iyong SIM card ay permanenteng hindi pinagana.\n Makipag-ugnay sa iyong wireless service provider para sa isa pang SIM card."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Button na nakaraang track"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Button na Susunod na track"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Button na I-pause"</string>
@@ -808,11 +848,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Tingnan ang Gabay ng User o makipag-ugnay sa Pangangalaga sa Customer."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Naka-lock ang SIM card."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Ina-unlock ang SIM card…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Mali mong naguhit ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. "\n\n"Subukang muli sa loob ng <xliff:g id="NUMBER_1">%d</xliff:g> (na) segundo."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Na-type mo nang mali ang iyong password nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. "\n\n"Subukang muli sa loob ng <xliff:g id="NUMBER_1">%d</xliff:g> (na) segundo."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Na-type mo nang mali ang iyong PIN nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. "\n\n"Subukang muli sa loob ng <xliff:g id="NUMBER_1">%d</xliff:g> (na) segundo."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Naiguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, hihilingin sa iyong i-unlock ang iyong tablet gamit ang iyong pag-sign-in sa Google."\n\n" Subukang muli sa loob ng <xliff:g id="NUMBER_2">%d</xliff:g> (na) segundo."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Naguhit mo nang mali ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, hihilingin sa iyong i-unlock ang iyong telepono gamit ang iyong pag-sign-in sa Google."\n\n" Subukang muli sa loob ng <xliff:g id="NUMBER_2">%d</xliff:g> (na) segundo."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Mali mong naguhit ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. \n\nSubukang muli sa loob ng <xliff:g id="NUMBER_1">%d</xliff:g> (na) segundo."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Na-type mo nang mali ang iyong password nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. \n\nSubukang muli sa loob ng <xliff:g id="NUMBER_1">%d</xliff:g> (na) segundo."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Na-type mo nang mali ang iyong PIN nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. \n\nSubukang muli sa loob ng <xliff:g id="NUMBER_1">%d</xliff:g> (na) segundo."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Naiguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, hihilingin sa iyong i-unlock ang iyong tablet gamit ang iyong pag-sign-in sa Google.\n\n Subukang muli sa loob ng <xliff:g id="NUMBER_2">%d</xliff:g> (na) segundo."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Naguhit mo nang mali ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, hihilingin sa iyong i-unlock ang iyong telepono gamit ang iyong pag-sign-in sa Google.\n\n Subukang muli sa loob ng <xliff:g id="NUMBER_2">%d</xliff:g> (na) segundo."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Mali mong tinangkang ma-unlock ang tablet nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang mga hindi matagumpay na pagtatangka, mare-reset ang tablet sa factory default at mawawala ang lahat ng data ng user."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Mali mong tinangkang ma-unlock ang telepono nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang mga hindi matagumpay na pagtatangka, mare-reset ang telepono sa factory default at mawawala ang lahat ng data ng user."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Mali mong tinangkang ma-unlock ang tablet nang <xliff:g id="NUMBER">%d</xliff:g> (na) beses. Mare-reset na ngayon ang tablet sa factory default."</string>
@@ -826,7 +866,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Password"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Mag-sign in"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Di-wastong username o password."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Nakalimutan ang iyong username o password?"\n"Bisitahin ang "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Nakalimutan ang iyong username o password?\nBisitahin ang "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Tinitingnan..."</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"I-unlock"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"I-on ang tunog"</string>
@@ -874,7 +914,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Kumpirmahin ang Pag-navigate"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Umalis sa Pahinang ito"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Manatili sa Pahinang ito"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Sigurado ka bang gusto mong mag-navigate paalis sa pahinang ito?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nSigurado ka bang gusto mong mag-navigate paalis sa pahinang ito?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Kumpirmahin"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Tip: Mag-double tap upang mag-zoom in at out."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Autofill"</string>
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"Sa kasamaang palad, huminto ang <xliff:g id="APPLICATION">%1$s</xliff:g>."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Sa kasamaang palad, nahinto ang prosesong <xliff:g id="PROCESS">%1$s</xliff:g>."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"Hindi tumutugon ang <xliff:g id="APPLICATION">%2$s</xliff:g>."\n\n"Nais mo ba itong isara?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Hindi tumutugon ang aktibidad na <xliff:g id="ACTIVITY">%1$s</xliff:g>."\n\n"Nais mo ba itong isara?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"Hindi tumutugon ang <xliff:g id="APPLICATION">%2$s</xliff:g>.\n\nNais mo ba itong isara?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Hindi tumutugon ang aktibidad na <xliff:g id="ACTIVITY">%1$s</xliff:g>.\n\nNais mo ba itong isara?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"Hindi tumutugon ang <xliff:g id="APPLICATION">%1$s</xliff:g>. Nais mo ba itong isara?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Hindi tumutugon ang prosesong <xliff:g id="PROCESS">%1$s</xliff:g>."\n\n"Nais mo ba itong isara?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Hindi tumutugon ang prosesong <xliff:g id="PROCESS">%1$s</xliff:g>.\n\nNais mo ba itong isara?"</string>
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"Ulat"</string>
     <string name="wait" msgid="7147118217226317732">"Maghintay"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"Hindi na tumutugon ang pahina."\n\n"Nais mo ba itong isara?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Hindi na tumutugon ang pahina.\n\nNais mo ba itong isara?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Na-redirect ang app"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"Tumatakbo na ngayon ang <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"Orihinal na nalunsad ang <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
@@ -1256,6 +1296,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Pinapayagan ang app na i-apela ang default na serbisyo ng container upang kopyahin ang nilalaman. Hindi para sa paggamit ng normal na apps."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"I-route ang output ng media"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Pinapayagan ang application na mag-route ng output ng media sa iba pang mga panlabas na device."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"I-access ang secure na storage ng keyguard"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Nagbibigay-daan sa isang application na i-access ang secure na storage ng keyguard."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Kontrolin ang pagpapakita at pagtago sa keyguard"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Pinapayagan ang isang application na kontrolin ang keyguard."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Pindutin nang dalawang beses para sa pagkontrol ng zoom"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Hindi maidagdag ang widget."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Pumunta"</string>
@@ -1265,15 +1309,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Tapos na"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Nkraan"</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Isakatuparan"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Mag-dial ng numero"\n"gamit ang <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Lumikha ng contact"\n"gamit ang <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Mag-dial ng numero\ngamit ang <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Lumikha ng contact\ngamit ang <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Ang sumusunod na isa o higit pang mga app ay humihiling ng pahintulot na i-access ang iyong account, ngayon at sa hinaharap."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Gusto mo bang payagan ang kahilingang ito?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Kahilingan sa pag-access"</string>
     <string name="allow" msgid="7225948811296386551">"Payagan"</string>
     <string name="deny" msgid="2081879885755434506">"Tanggihan"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Hiniling ang pahintulot"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Hiniling ang pahintulot"\n"para sa account na <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Hiniling ang pahintulot\npara sa account na <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Pamamaraan ng pag-input"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"I-sync"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Kakayahang Ma-access"</string>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Tingnan lahat"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Pumili ng aktibidad"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Ibahagi sa"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Naka-lock ang device."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Ipinapadala..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Ilunsad ang Browser?"</string>
@@ -1441,10 +1484,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Kumukonekta..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Available"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"Hindi available"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"Ginagamit"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Built-in na Screen"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"HDMI Screen"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlay #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", secure"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Nakakonekta ang wireless na display"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Lumalabas ang screen na ito sa isa pang device"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Alisin sa pagkakakonekta"</string>
@@ -1453,7 +1498,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Maling Pattern"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Maling Password"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"Maling PIN"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Subukang muli sa loob ng <xliff:g id="NUMBER">%d</xliff:g> (na) segundo."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Subukang muli sa loob ng <xliff:g id="NUMBER">%1$d</xliff:g> (na) segundo."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Iguhit ang iyong pattern"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Ilagay ang SIM PIN"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Ilagay ang PIN"</string>
@@ -1473,27 +1518,85 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Password"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Mag-sign in"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Di-wastong username o password."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Nakalimutan ang iyong username o password?"\n"Bisitahin ang "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Nakalimutan ang iyong username o password?\nBisitahin ang "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Tinitingnan ang account…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Na-type mo nang hindi tama ang iyong PIN nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. "\n\n"Subukang muli sa loob ng <xliff:g id="NUMBER_1">%d</xliff:g> (na) segundo."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Na-type mo nang hindi tama ang iyong password nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. "\n\n"Subukang muli sa loob ng <xliff:g id="NUMBER_1">%d</xliff:g> (na) segundo."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. "\n\n"Subukang muli sa loob ng <xliff:g id="NUMBER_1">%d</xliff:g> (na) segundo."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Na-type mo nang hindi tama ang iyong PIN nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. \n\nSubukang muli sa loob ng <xliff:g id="NUMBER_1">%d</xliff:g> (na) segundo."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Na-type mo nang hindi tama ang iyong password nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. \n\nSubukang muli sa loob ng <xliff:g id="NUMBER_1">%d</xliff:g> (na) segundo."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. \n\nSubukang muli sa loob ng <xliff:g id="NUMBER_1">%d</xliff:g> (na) segundo."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tinangka mo sa hindi tamang paraan na i-unlock ang tabelt nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, ire-reset ang tablet sa factory default at mawawala ang lahat ng data ng user."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Tinangka mo sa hindi tamang paraan na i-unlock ang telepono nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, ire-reset ang telepono sa factory default at mawawala ang lahat ng data ng user."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Tinangka mo sa hindi tamang paraan na i-unlock ang tablet nang <xliff:g id="NUMBER">%d</xliff:g> (na) beses. Ire-reset na ngayon ang tablet sa factory default."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Tinangka mo sa hindi tamang paraan na i-unlock ang telepono nang <xliff:g id="NUMBER">%d</xliff:g> (na) beses. Ire-reset na ngayon ang telepono sa factory default."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, hihilingin sa iyong i-unlock ang tablet mo gamit ang isang email account."\n\n" Subukang muli sa loob ng <xliff:g id="NUMBER_2">%d</xliff:g> (na) segundo."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, hihilingin sa iyong i-unlock ang telepono mo gamit ang isang email account."\n\n" Subukang muli sa loob ng <xliff:g id="NUMBER_2">%d</xliff:g> (na) segundo."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, hihilingin sa iyong i-unlock ang tablet mo gamit ang isang email account.\n\n Subukang muli sa loob ng <xliff:g id="NUMBER_2">%d</xliff:g> (na) segundo."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, hihilingin sa iyong i-unlock ang telepono mo gamit ang isang email account.\n\n Subukang muli sa loob ng <xliff:g id="NUMBER_2">%d</xliff:g> (na) segundo."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Alisin"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Lakasan ang volume nang lagpas sa ligtas na antas?"\n"Maaaring mapinsala ng pakikinig sa malakas na volume sa loob ng mahahabang panahon ang iyong pandinig."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Lakasan ang volume nang lagpas sa ligtas na antas?\nMaaaring mapinsala ng pakikinig sa malakas na volume sa loob ng mahahabang panahon ang iyong pandinig."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Panatilihing nakapindot nang matagal ang iyong dalawang daliri upang paganahin ang pagiging naa-access."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Pinagana ang accessibility."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Nakansela ang pagiging naa-access."</string>
     <string name="user_switched" msgid="3768006783166984410">"Kasalukuyang user <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"May-ari"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Error"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Hindi sinusuportahan ng application na ito ang mga account para sa mga pinaghihigpitang profile"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Hindi sinusuportahan ng app na ito ang mga account para sa mga pinaghihigpitang profile"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Walang nakitang application na mangangasiwa sa pagkilos na ito"</string>
     <string name="revoke" msgid="5404479185228271586">"Bawiin"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Kinansela"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"May error sa pagsusulat ng nilalaman"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"hindi alam"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Ilagay ang PIN ng administrator"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Ilagay ang PIN"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Mali"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Kasalukuyang PIN"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Bagong PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Kumpirmahin ang bagong PIN"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Gumawa ng PIN para sa pagbago sa mga paghihigpit"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"Hindi nagtutugma ang mga PIN. Subukang muli."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"Masyadong maikli ang PIN. Hindi dapat mas maikli sa 4 na digit."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Subukan muli sa 1 seg"</item>
+    <item quantity="other" msgid="4730868920742952817">"Subukan muli sa <xliff:g id="COUNT">%d</xliff:g> seg"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Subukang muli sa ibang pagkakataon"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Mag-swipe sa dulo ng screen upang ipakita ang bar"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Mag-swipe mula sa dulo ng screen upang ipakita ang system bar"</string>
 </resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index a6d7b2a..22a3eef 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -131,6 +131,11 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Çok fazla <xliff:g id="CONTENT_TYPE">%s</xliff:g> silme var."</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Tabletin depolama alanı dolu! Yer açmak için bazı dosyaları silin."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Telefonun depolama alanı dolu! Yer açmak için bazı dosyaları silin."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Ağ izlenebilir"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Ben"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Tablet seçenekleri"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Telefon seçenekleri"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Uygulamaya, görevleri ön plana ve arka plana taşıma izni verir. Uygulama bunu sizden bir giriş olmadan yapabilir."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"çalışan uygulamaları durdur"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Uygulamaya, görevleri kaldırma ve bunlara ait uygulamaları kapatma izni verir. Kötü amaçlı uygulamalar diğer uygulamaların çalışmasını bozabilir."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"etkinlik yığınlarını yönet"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Uygulamaya, diğer uygulamaların içinde çalıştığı etkinlik yığınlarını ekleme, kaldırma ve değiştirme izni verir. Kötü amaçlı uygulamalar diğer uygulamaların davranışlarını olumsuz etkileyebilir."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"herhangi bir etkinlik başlat"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Uygulamaya, izin koruma veya dışa aktarma durumu ne olursa olsun bir etkinlik başlatma izni verir."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"ekran uyumluluğunu ayarla"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Cihazın sahibine, bir giriş yönteminin en üst düzey arayüzüne bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"erişilebilirlik hizmetine bağlan"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"İzin sahibine bir erişilebilirlik hizmetinin en üst düzey arayüzüne bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"bir yazdırma hizmetine bağlan"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"İzin sahibine, bir yazdırma hizmetinin en üst düzey arayüzüne bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"bir yazdırma biriktirici hizmetine bağlan"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"İzin sahibine, bir yazdırma biriktirici hizmetinin en üst düzey arayüzüne bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC hizmetine bağla"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"İzin sahibine, NFC kartlara öykünen uygulamalara bağlama izni verir. Normal uygulamalar için hiçbir zaman gerekmez."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"kısa mesaj hizmetine bağla"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Cihazın sahibine, bir metin hizmetinin (ör. SpellCheckerService) en üst düzey arayüzüne bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerekmez."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"VPN hizmetine bağlan"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Cihazın sahibine bir widget hizmetinin en üst düzey arayüzüne bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"bir cihaz yöneticisi ile etkileşimde bulun"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Cihazın sahibinin cihaz yöneticisine amaç göndermesine izin verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"cihaz yöneticisi ekle veya kaldır"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"İzin sahibine, etkin cihaz yöneticileri ekleyip kaldırma izni verir. Normal uygulamalar için hiçbir zaman gerekmez."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"ekran yönünü değiştir"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Uygulamaya, istediği zaman ekran dönüşünü değiştirme izni verir. Normal uygulamalar için gerekli değildir."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"işaretçi hızını değiştir"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Uygulamaya, sisteme ait çeşitli günlük dosyalarındaki bilgileri okuma izni verir. Bu izin, uygulamanın, kişisel ve gizli bilgileriniz de dahil olmak üzere telefonda yaptıklarınızla ilgili genel bilgileri bulmasına olanak verir."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"oynatma için herhangi bir medya kod çözücüyü kullan"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Uygulamaya, oynatma kodunu çözmek için herhangi bir yüklü medya kod çözücüyü kullanma izni verir."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"güvenilen kimlik bilgilerini yönetme"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Uygulamaya, güvenilir kimlik bilgileri olarak CA sertifikaları yükleme veya sertifikaların yüklemelerini kaldırma izni verir."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"sahibi tanılama olan kaynakları oku/bunlara yaz"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Uygulamaya, tanılama grubunun sahip olduğu tüm kaynaklara (örneğin /dev içindeki dosyalar) okuma ve yazma izni verir. Bu işlevin sistem kararlılığını ve güvenliğini olumsuz etkileme olasılığı vardır. Üretici veya operatör tarafından YALNIZCA donanıma özgü tanılama için kullanılmalıdır."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"uygulama bileşenlerini etkinleştir veya devre dışı bırak"</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Uygulamaya kablosuz ekranları yapılandırma ve bunlara bağlanma izni verir."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Kablosuz ekranları denetle"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Uygulamaya kablosuz ekranların alt düzey özelliklerini kontrol etme izni verir."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"ses çıkışını yakala"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Uygulamaya, ses çıkışını yakalayıp yönlendirme izni verir."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"video çıkışını yakala"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Uygulamaya, video çıkışını yakalayıp yönlendirme izni verir."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"güvenli video çıkışını yakala"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Uygulamaya, güvenli video çıkışını yakalayıp yönlendirme izni verir."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"ses ayarlarınızı değiştirin"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Uygulamaya ses düzeyi ve ses çıkışı için kullanılan hoparlör gibi genel ses ayarlarını değiştirme izni verir."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"ses kaydet"</string>
@@ -525,6 +552,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"telefonun uykuya geçmesini önleme"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Uygulamaya, tabletin uykuya geçmesini önleme izni verir."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Uygulamaya, telefonun uykuya geçmesini önleme izni verir."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"tableti aç veya kapat"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"telefonu aç veya kapat"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Uygulamaya, tabletinizi açma veya kapatma izni verir."</string>
@@ -613,6 +646,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Uygulamaya, SD karta yazma izni verir."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"dahili medya depolama birimi içeriğini değiştir/sil"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Uygulamaya, dahili medya depolama içeriğini değiştirme izni verir."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"doküman deposunu yönet"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Uygulamaya, doküman deposunu yönetme izni verir."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"tüm kullanıcılar için harici depolama eriş"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Uygulamaya tüm kullanıcılar için harici depolamaya erişim izni verir."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"önbellek dosya sistemine eriş"</string>
@@ -625,10 +660,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Uygulamaya, ağ politikalarını yönetme ve uygulamaya özgü kuralları tanımlama izni verir."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"ağ kullanım hesaplamasını değiştir"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Uygulamaya, ağın uygulamalara göre nasıl kullanılacağını değiştirme izni verir. Normal uygulamalar tarafından kullanılmak için değildir."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"yuva işaretlerini değiştir"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Uygulamaya, yönlendirme için yuva işaretlerini değiştirme izni verir"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"bildirimlere eriş"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Uygulamanın bildirimler almasına, bildirimleri incelemesine ve temizlemesine izin verir. Buna diğer uygulamalar tarafından yayınlanan bildirimler de dahildir."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"bildirim dinleyici hizmetine bağlan"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"İzin sahibine bir bildirim dinleyici hizmetinin en üst düzey arayüzüne bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"operatör tarafından sağlanan yapılandırma uygulamasını çalıştır"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"İzin sahibine, operatör tarafından sağlanan yapılandırma uygulamasını çalıştırma izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"ağ koşullarındaki gözlemleri dinle"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Bir uygulamaya, ağ koşullarındaki gözlemleri dinleme izni verir. Normal uygulamalar için hiçbir zaman gerekmez."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Şifre kuralları ayarla"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Ekran kilidini açma şifrelerinde izin verilen uzunluğu ve karakterleri denetleme."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Ekran kilidini açma denemelerini izle"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +836,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"SIM kartı takın."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM kart yok veya okunamıyor. Bir SIM kart takın."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Kullanılamayan SIM kartı"</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"SIM kartınız kalıcı olarak devre dışı bırakıldı."\n" Başka bir SIM kart için kablosuz servis sağlayıcınıza başvurun."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"SIM kartınız kalıcı olarak devre dışı bırakıldı.\n Başka bir SIM kart için kablosuz servis sağlayıcınıza başvurun."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Önceki parça düğmesi"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Sonraki parça düğmesi"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Duraklat düğmesi"</string>
@@ -808,11 +848,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Kullanıcı Rehberi\'ne bakın veya Müşteri Hizmetleri\'ne başvurun."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM kart kilitli."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM kart kilidi açılıyor…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış çizdiniz. "\n\n"<xliff:g id="NUMBER_1">%d</xliff:g> saniye içinde tekrar deneyin."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Şifrenizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış yazdınız. "\n\n"<xliff:g id="NUMBER_1">%d</xliff:g> saniye içinde tekrar deneyin."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"PIN kodunuzu <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış girdiniz. "\n\n"<xliff:g id="NUMBER_1">%d</xliff:g> saniye içinde tekrar deneyin."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> başarısız denemeden sonra, tabletinizi, Google oturum açma bilgilerinizi kullanarak açmanız istenir."\n\n"<xliff:g id="NUMBER_2">%d</xliff:g> saniye içinde tekrar deneyin."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> başarısız denemeden sonra telefonunuzu Google oturum açma bilgilerinizi kullanarak açmanız istenir."\n\n" Lütfen <xliff:g id="NUMBER_2">%d</xliff:g> saniye içinde tekrar deneyin."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış çizdiniz. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> saniye içinde tekrar deneyin."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Şifrenizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış yazdınız. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> saniye içinde tekrar deneyin."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"PIN kodunuzu <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış girdiniz. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> saniye içinde tekrar deneyin."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> başarısız denemeden sonra, tabletinizi, Google oturum açma bilgilerinizi kullanarak açmanız istenir.\n\n<xliff:g id="NUMBER_2">%d</xliff:g> saniye içinde tekrar deneyin."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> başarısız denemeden sonra telefonunuzu Google oturum açma bilgilerinizi kullanarak açmanız istenir.\n\n Lütfen <xliff:g id="NUMBER_2">%d</xliff:g> saniye içinde tekrar deneyin."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Tablet kilidini <xliff:g id="NUMBER_0">%d</xliff:g> defa yanlış bir şekilde açmaya çalıştınız. <xliff:g id="NUMBER_1">%d</xliff:g> defa daha başarısız deneme yapılırsa, tablet fabrika varsayılanına sıfırlanır ve tüm kullanıcı verileri kaybedilir."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Telefonun kilidini <xliff:g id="NUMBER_0">%d</xliff:g> defa yanlış bir şekilde açmaya çalıştınız. <xliff:g id="NUMBER_1">%d</xliff:g> defa daha başarısız deneme yapılırsa, telefon fabrika varsayılanına sıfırlanır ve tüm kullanıcı verileri kaybedilir."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Tablet kilidini <xliff:g id="NUMBER">%d</xliff:g> defa yanlış bir şekilde açmaya çalıştınız. Tablet şimdi fabrika varsayılanına sıfırlanacak."</string>
@@ -826,7 +866,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Şifre"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Oturum aç"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Geçersiz kullanıcı adı veya şifre."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Kullanıcı adınızı veya şifrenizi mi unuttunuz?"\n<b>"google.com/accounts/recovery"</b>" adresini ziyaret edin."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Kullanıcı adınızı veya şifrenizi mi unuttunuz?\n"<b>"google.com/accounts/recovery"</b>" adresini ziyaret edin."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Denetleniyor…"</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Kilit Aç"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Sesi aç"</string>
@@ -874,7 +914,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Gezinmeyi Onayla"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Bu Sayfadan Ayrıl"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Bu sayfada kal"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Bu sayfadan ayrılmak istediğinizden emin misiniz?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nBu sayfadan ayrılmak istediğinizden emin misiniz?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Onayla"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"İpucu: Yakınlaştırmak ve uzaklaştırmak için iki kez hafifçe vurun."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Otomatik Doldur"</string>
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"Maalesef <xliff:g id="APPLICATION">%1$s</xliff:g> durdu."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Maalesef <xliff:g id="PROCESS">%1$s</xliff:g> işlemi durdu."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> yanıt vermiyor."\n\n"Kapatmak ister misiniz?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"<xliff:g id="ACTIVITY">%1$s</xliff:g> yanıt vermiyor."\n\n"Kapatmak ister misiniz?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> yanıt vermiyor.\n\nKapatmak ister misiniz?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"<xliff:g id="ACTIVITY">%1$s</xliff:g> yanıt vermiyor.\n\nKapatmak ister misiniz?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> yanıt vermiyor. Kapatmak ister misiniz?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"<xliff:g id="PROCESS">%1$s</xliff:g> işlemi yanıt vermiyor."\n\n"Kapatmak ister misiniz?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"<xliff:g id="PROCESS">%1$s</xliff:g> işlemi yanıt vermiyor.\n\nKapatmak ister misiniz?"</string>
     <string name="force_close" msgid="8346072094521265605">"Tamam"</string>
     <string name="report" msgid="4060218260984795706">"Bildir"</string>
     <string name="wait" msgid="7147118217226317732">"Bekle"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"Sayfa yanıt vermiyor."\n\n"Kapatmak ister misiniz?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Sayfa yanıt vermiyor.\n\nKapatmak ister misiniz?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Uygulama yönlendirildi"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> şimdi çalışıyor."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"İlk olarak <xliff:g id="APP_NAME">%1$s</xliff:g> başlatıldı."</string>
@@ -1256,6 +1296,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Uygulamaya, içerik kopyalamak için varsayılan kapsayıcı hizmetini çağırma izni verir. Normal uygulamaların kullanımına yönelik değildir."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Medya çıktısını yönlendir"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Uygulamaya medya çıktısını başka harici cihazlara yönlendirme izni verir."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Tuş kilitli güvenli depolamaya erişim"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Bir uygulamanın tuş kilitli güvenli depolamaya erişimine izin verir."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Tuş koruyucuyu görüntülemeyi ve gizlemeyi kontrol et"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Bir uygulamaya tuş koruyucuyu denetleme izni verir."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Yakınlaştırma denetimi için iki kez dokunun"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Widget eklenemedi."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Git"</string>
@@ -1265,15 +1309,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Bitti"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Önceki"</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Çalıştır"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Numarayı çevir:"\n"<xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"<xliff:g id="NUMBER">%s</xliff:g>"\n" ile kişi oluştur"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Numarayı çevir:\n<xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"<xliff:g id="NUMBER">%s</xliff:g>\n ile kişi oluştur"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Aşağıdaki bir veya daha fazla uygulama şimdi ve ileride hesabınıza erişmek için izin istiyor."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Bu isteğe izin vermek istiyor musunuz?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Erişim isteği"</string>
     <string name="allow" msgid="7225948811296386551">"İzin Ver"</string>
     <string name="deny" msgid="2081879885755434506">"Reddet"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"İzin istendi"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"<xliff:g id="ACCOUNT">%s</xliff:g> hesabı için"\n"izin isteğinde bulunuldu."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"<xliff:g id="ACCOUNT">%s</xliff:g> hesabı için\nizin isteğinde bulunuldu."</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Giriş yöntemi"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Senkronizasyon"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Erişebilirlik"</string>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Tümünü göster"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Etkinlik seçin"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Şununla paylaş:"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Cihaz kilitli."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Gönderiliyor…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Tarayıcı Başlatılsın mı?"</string>
@@ -1441,10 +1484,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Bağlanılıyor..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Kullanılabilir"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"Yok"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"Kullanımda"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Yerleşik Ekran"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"HDMI Ekran"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Yer Paylaşımı No. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", güvenli"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Kablosuz ekrana bağlandı"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Bu ekran başka bir cihazda gösteriliyor"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Bağlantıyı kes"</string>
@@ -1453,7 +1498,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Yanlış Desen"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Yanlış Şifre"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"Yanlış PIN"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%d</xliff:g> saniye içinde yeniden deneyin."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%1$d</xliff:g> saniye içinde yeniden deneyin."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Deseninizi çizin"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM PIN kodunu girin"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN\'i girin"</string>
@@ -1473,27 +1518,85 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Şifre"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Oturum aç"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Geçersiz kullanıcı adı veya şifre."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Kullanıcı adınızı veya şifrenizi mi unuttunuz?"\n<b>"google.com/accounts/recovery"</b>" adresini ziyaret edin."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Kullanıcı adınızı veya şifrenizi mi unuttunuz?\n"<b>"google.com/accounts/recovery"</b>" adresini ziyaret edin."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Hesap denetleniyor…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN kodunuzu <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış girdiniz. "\n\n"<xliff:g id="NUMBER_1">%d</xliff:g> saniye içinde tekrar deneyin."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Şifrenizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış yazdınız. "\n\n"<xliff:g id="NUMBER_1">%d</xliff:g> saniye içinde tekrar deneyin."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış çizdiniz. "\n\n"<xliff:g id="NUMBER_1">%d</xliff:g> saniye içinde tekrar deneyin."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN kodunuzu <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış girdiniz. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> saniye içinde tekrar deneyin."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Şifrenizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış yazdınız. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> saniye içinde tekrar deneyin."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış çizdiniz. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> saniye içinde tekrar deneyin."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tablet kilidini <xliff:g id="NUMBER_0">%d</xliff:g> defa yanlış bir şekilde açmaya çalıştınız. <xliff:g id="NUMBER_1">%d</xliff:g> defa daha başarısız deneme yapılırsa, tablet fabrika varsayılan değerine sıfırlanır ve tüm kullanıcı verileri kaybedilir."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Telefonun kilidini <xliff:g id="NUMBER_0">%d</xliff:g> defa yanlış bir şekilde açmaya çalıştınız. <xliff:g id="NUMBER_1">%d</xliff:g> defa daha başarısız deneme yapılırsa, telefon fabrika varsayılan değerine sıfırlanır ve tüm kullanıcı verileri kaybedilir."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Tablet kilidini <xliff:g id="NUMBER">%d</xliff:g> defa yanlış bir şekilde açmaya çalıştınız. Tablet şimdi fabrika varsayılanına sıfırlanacak."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Telefon kilidini <xliff:g id="NUMBER">%d</xliff:g> defa yanlış bir şekilde açmaya çalıştınız. Telefon şimdi fabrika varsayılanına sıfırlanacak."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> başarısız denemeden sonra, tabletinizi bir e-posta hesabı kullanarak açmanız istenir."\n\n" <xliff:g id="NUMBER_2">%d</xliff:g> saniye içinde tekrar deneyin."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> başarısız denemeden sonra telefonunuzu bir e-posta hesabı kullanarak açmanız istenir."\n\n" <xliff:g id="NUMBER_2">%d</xliff:g> saniye içinde tekrar deneyin."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> başarısız denemeden sonra, tabletinizi bir e-posta hesabı kullanarak açmanız istenir.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> saniye içinde tekrar deneyin."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> başarısız denemeden sonra telefonunuzu bir e-posta hesabı kullanarak açmanız istenir.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> saniye içinde tekrar deneyin."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Kaldır"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Ses düzeyi önerilen seviyenin üzerine çıkarılsın mı?"\n"Uzun süre yüksek sesle dinlemek işitme duyunuza zarar verebilir."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Ses düzeyi önerilen seviyenin üzerine çıkarılsın mı?\nUzun süre yüksek sesle dinlemek işitme duyunuza zarar verebilir."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Erişilebilirliği etkinleştirmek için iki parmağınızı basılı tutmaya devam edin."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Erişilebilirlik etkinleştirildi."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Erişilebilirlik iptal edildi."</string>
     <string name="user_switched" msgid="3768006783166984410">"Geçerli kullanıcı: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Sahibi"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Hata"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Bu uygulama kısıtlanmış profillerin hesaplarını desteklemez"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Bu uygulama, kısıtlanmış profillerin hesaplarını desteklemez"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Bu eylemi gerçekleştirecek bir uygulama bulunamadı"</string>
     <string name="revoke" msgid="5404479185228271586">"İptal et"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"İptal edildi"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"İçerik yazılırken hata oluştu"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"bilinmiyor"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Yönetici PIN\'ini girin"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN\'i girin"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Yanlış"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Mevcut PIN"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Yeni PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Yeni PIN\'i doğrulayın"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Kısıtlamaları değiştirmek için PIN oluşturun"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PIN\'ler eşleşmiyor. Tekrar deneyin."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"PIN çok kısa. En az 4 basamaklı olmalı."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"1 saniye içinde tekrar deneyin"</item>
+    <item quantity="other" msgid="4730868920742952817">"<xliff:g id="COUNT">%d</xliff:g> saniye içinde tekrar deneyin"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Daha sonra tekrar deneyin"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Çubuğu görüntülemek için ekranın kenarından hızlıca kaydırın"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Sistem çubuğunu görüntülemek için ekranın kenarından hızlıca kaydırın"</string>
 </resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index d2798ad..6a9677f 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -131,6 +131,11 @@
     <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="default" msgid="3475999286680000541">"Пам’ять телефону заповнено. Видаліть якісь файли, щоб звільнити місце."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Мережу можуть відстежувати"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Я"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Парам. пристрою"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Параметри тел."</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Дозволяє програмі переміщувати завдання в активні чи фонові вікна. Програма може робити це без вашого відома."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"зупиняти запущені програми"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Дозволяє програмі видаляти завдання та примусово припиняти роботу відповідних програм. Шкідливі програми можуть переривати роботу інших програм."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"керувати стеками дій"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Дозволяє програмі додавати, вилучати та змінювати стеки дій, у яких запущено інші програми. Шкідливі програми можуть переривати роботу інших програм."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"розпочинати будь-які дії"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Дозволяє програмі розпочинати будь-які дії, незалежно від захищеного дозволу або стану експорту."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"установити сумісність екрана"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Дозволяє власнику прив’язуватися до інтерфейсу верхнього рівня методу введення. Ніколи не застосовується для звичайних програм."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"прив’язуватися до служби доступності"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Дозволяє власникові прив’язуватися до інтерфейсу верхнього рівня служби доступності. Ніколи не застосовується для звичайних програм."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"прив’язуватися до служби друку"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Дозволяє власникові прив’язуватися до інтерфейсу верхнього рівня служби друку. Ніколи не застосовується для звичайних програм."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"прив’язуватися до служби спулера друку"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Дозволяє власникові прив’язуватися до інтерфейсу верхнього рівня служби спулера друку. Ніколи не застосовується для звичайних програм."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"прив’язуватися до служби NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Дозволяє власникові прив’язуватися до програм, які емулюють картки NFC. Ніколи не використовується звичайними програмами."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"прив’язати до текстової служби"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Дозволяє власникові прив’язуватися до інтерфейсу верхнього рівня текстової служби (напр. SpellCheckerService). Ніколи не застосовується для звичайних програм."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"прив’язуватися до служби VPN"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Дозволяє власникові прив’язуватися до інтерфейсу верхнього рівня служби віджетів. Ніколи не застосовується для звичайних програм."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"взаємодіяти з адмін. пристрою"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Дозволяє власнику надсилати задавані функції адміністратору пристрою. Ніколи не застосовується для звичайних програм."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"додавати чи вилучати адміністраторів пристрою"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Дозволяє власнику додавати чи вилучати активних адміністраторів пристрою. Ніколи не застосовується для звичайних програм."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"змінювати орієнтацію екрана"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Дозволяє програмі будь-коли змінювати обертання екрана. Ніколи не застосовується для звичайних програм."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"змінювати швидкість указівника"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Дозволяє програмі читати з різних файлів журналу системи. Це дозволяє дізнаватися загальну інформацію про ваші дії в телефоні, яка потенційно може містити особисті чи конфіденційні дані."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"використовувати будь-який медіа-декодер для відтворення"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Дозволяє програмі використовувати будь-який установлений медіа-декодер для декодування з метою відтворення."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"керувати захищеними обліковими даними"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Дозволяє програмі встановлювати та видаляти сертифікати центру сертифікації (CA) як захищені облікові дані."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"чит./зап. на ресури., якими вол. діаг."</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Дозволяє програмі читати та писати на будь-який ресурс, яким володіє діагностична група; наприклад, у файли в папці /dev. Це потенційно може вплинути на стабільність і безпеку системи. Потрібно використовувати ЛИШЕ для певної діагностики обладнання, яку виконує виробник чи оператор."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"вмикати чи вимикати компоненти програми"</string>
@@ -462,6 +479,14 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Дозволяє програмі налаштовувати екрани Wi-Fi і під’єднуватися до них."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"керувати екранами Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Дозволяє програмі керувати низькорівневими функціями екранів Wi-Fi."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"отримувати доступ до аудіовиходу"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Дозволяє програмі отримувати доступ до аудіовиходу й переспрямовувати його."</string>
+    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"виявляти команди швидкого запуску"</string>
+    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"Дозволяє програмі записувати аудіо для виявлення команд швидкого запуску. Запис відбуватиметься у фоновому режимі й не перешкоджатиме запису іншого аудіо (напр., з відеокамери)."</string>
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"отримувати доступ до відеовиходу"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Дозволяє програмі отримувати доступ до відеовиходу й переспрямовувати його."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"отримувати доступ до захищеного відеовиходу"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Дозволяє програмі отримувати доступ до захищеного відеовиходу й переспрямовувати його."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"змінювати налаштув-ня звуку"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Дозволяє програмі змінювати загальні налаштування звуку, як-от гучність і динамік, який використовується для виводу сигналу."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"запис-ти аудіо"</string>
@@ -525,6 +550,9 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"недоп. перехід тел. в реж. сну"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Дозволяє програмі не допускати перехід планшетного ПК у режим сну."</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="default" msgid="7957763745020300725">"Дозволяє програмі використовувати інфрачервоний передавач телефону."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"увімк. чи вимк. пристрій"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"вмик. чи вимик. телефон"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Дозволяє програмі вимикати чи вимикати планшетний ПК."</string>
@@ -613,6 +641,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Дозволяє програмі записувати на карту SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"змінювати/видаляти вміст внутр. сховища даних"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Дозволяє програмі змінювати вміст внутрішнього сховища даних."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"керувати зберіганням"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Дозволяє програмі керувати зберіганням документів."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"доступ до зовн. пам’яті всіх корист."</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Дозволяє програмі отримувати доступ до зовнішньої пам’яті всіх користувачів."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"отр. дост. до файл. сист. кешу"</string>
@@ -625,10 +655,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Дозволяє програмі керувати політикою мережі та визначити спеціальні правила для програм."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"змінювати облік використання мережі"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Дозволяє програмі змінювати метод підрахунку того, як програми використовують мережу. Не для використання звичайними програмами."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"змінювати мітки сокетів"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Дозволяє програмі змінювати мітки сокетів для маршрутизації"</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_invokeCarrierSetup" msgid="3699600833975117478">"викликати надану оператором програму конфігурації"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Дозволяє власнику викликати надану оператором програму конфігурації. Ніколи не застосовується для звичайних програм."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"прослуховувати дані спостережень за станом мережі"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Дозволяє програмі прослуховувати дані спостережень за станом мережі. Ніколи не застосовується для звичайних програм."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Устан. правила пароля"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролювати довжину паролів для розблокування екрана та дозволені в них символи."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Відстежув. спроби розблок. екрана"</string>
@@ -738,8 +774,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +831,7 @@
     <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">"Вашу SIM-карту вимкнено назавжди.\n Зверніться до свого постачальника послуг бездротового зв’язку, щоб отримати іншу SIM-карту."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Кнопка \"Попередня доріжка\""</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Кнопка \"Наступна доріжка\""</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Кнопка \"Призупинити\""</string>
@@ -808,11 +843,11 @@
     <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">%d</xliff:g>. "\n\n"Повторіть спробу через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Пароль неправильно введено стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>."\n\n"Повторіть спробу через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"PIN-код неправильно введено стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>."\n\n"Повторіть спробу через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. Ваш планшетний ПК потрібно буде розблокувати за допомогою входу в Google після ще стількох неуспішних спроб: <xliff:g id="NUMBER_1">%d</xliff:g>."\n\n" Повторіть спробу через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. Ваш телефон потрібно буде розблокувати за допомогою входу в Google після ще стількох неуспішних спроб: <xliff:g id="NUMBER_1">%d</xliff:g>."\n\n" Повторіть спробу через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. \n\nПовторіть спробу через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Пароль неправильно введено стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>.\n\nПовторіть спробу через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"PIN-код неправильно введено стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>.\n\nПовторіть спробу через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. Ваш планшетний ПК потрібно буде розблокувати за допомогою входу в Google після ще стількох неуспішних спроб: <xliff:g id="NUMBER_1">%d</xliff:g>.\n\n Повторіть спробу через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. Ваш телефон потрібно буде розблокувати за допомогою входу в Google після ще стількох неуспішних спроб: <xliff:g id="NUMBER_1">%d</xliff:g>.\n\n Повторіть спробу через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Кількість невдалих спроб розблокувати пристрій: <xliff:g id="NUMBER_0">%d</xliff:g>. Налаштування пристрою буде змінено на заводські за умовчанням, а всі дані користувача буде втрачено після ще стількох невдалих спроб: <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Кількість невдалих спроб розблокувати телефон: <xliff:g id="NUMBER_0">%d</xliff:g>. Налаштування телефону буде змінено на заводські за умовчанням, а всі дані користувача буде втрачено після ще стількох невдалих спроб: <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Кількість невдалих спроб розблокувати пристрій: <xliff:g id="NUMBER">%d</xliff:g>. Налаштування пристрою буде змінено на заводські за умовчанням."</string>
@@ -826,7 +861,7 @@
     <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_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>
@@ -874,7 +909,7 @@
     <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="autofill_this_form" msgid="4616758841157816676">"Автозап."</string>
@@ -1080,14 +1115,14 @@
     <string name="aerr_application" msgid="932628488013092776">"На жаль, програма <xliff:g id="APPLICATION">%1$s</xliff:g> припинила роботу."</string>
     <string name="aerr_process" msgid="4507058997035697579">"На жаль, програма <xliff:g id="PROCESS">%1$s</xliff:g> припинила роботу."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"Програма <xliff:g id="APPLICATION">%2$s</xliff:g> не відповідає."\n\n"Закрити її?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Дія <xliff:g id="ACTIVITY">%1$s</xliff:g> не відповідає."\n\n"Закінчити її?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"Програма <xliff:g id="APPLICATION">%2$s</xliff:g> не відповідає.\n\nЗакрити її?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Дія <xliff:g id="ACTIVITY">%1$s</xliff:g> не відповідає.\n\nЗакінчити її?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"Програма <xliff:g id="APPLICATION">%1$s</xliff:g> не відповідає. Закрити її?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Процес <xliff:g id="PROCESS">%1$s</xliff:g> не відповідає."\n\n"Завершити його?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Процес <xliff:g id="PROCESS">%1$s</xliff:g> не відповідає.\n\nЗавершити його?"</string>
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"Повідом."</string>
     <string name="wait" msgid="7147118217226317732">"Чекати"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"Сторінка не відповідає."\n\n"Закрити її?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Сторінка не відповідає.\n\nЗакрити її?"</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>
@@ -1256,6 +1291,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Дозволяє програмі викликати службу контейнерів за умовчанням для копіювання вмісту. Не для використання звичайними програмами."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Скеровувати вивід медіа-даних"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Дозволяє програмі скеровувати вивід медіа-даних на інші зовнішні пристрої."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Отримувати доступ до безпечного сховища через клавіатуру"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Дозволяє програмі отримувати доступ до безпечного сховища через клавіатуру."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Керувати відображенням і хованням клавіатури"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Дозволяє програмі керувати клавіатурою."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Двічі торкніться, щоб керувати масштабом"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Не вдалося додати віджет."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Йти"</string>
@@ -1265,15 +1304,15 @@
     <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">"Набр. номер"\n" викор. <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Створ. контакт"\n" викор. <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Набр. номер\n викор. <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Створ. контакт\n викор. <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Указані нижче програми запитують дозвіл на доступ до вашого облікового запису зараз і в майбутньому."</string>
     <string name="grant_credentials_permission_message_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">"Запитано дозвіл"\n"для облікового запису <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Запитано дозвіл\nдля облікового запису <xliff:g id="ACCOUNT">%s</xliff:g>."</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>
@@ -1420,7 +1459,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Переглянути всі"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Вибрати дію"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Спільний доступ для:"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Пристрій заблоковано."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Надсилання…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Запустити веб-переглядач?"</string>
@@ -1441,10 +1479,12 @@
     <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>
+    <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_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>х<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", безпечний"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Бездротовий екран під’єднано"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Цей екран відображається на іншому пристрої"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Від’єднати"</string>
@@ -1453,7 +1493,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">%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>
@@ -1473,27 +1513,85 @@
     <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_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">%d</xliff:g>. "\n\n"Повторіть спробу через <xliff:g id="NUMBER_1">%d</xliff:g> с."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Пароль неправильно введено стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n"Повторіть спробу через <xliff:g id="NUMBER_1">%d</xliff:g> с."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n"Повторіть спробу через <xliff:g id="NUMBER_1">%d</xliff:g> с."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN-код неправильно введено стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. \n\nПовторіть спробу через <xliff:g id="NUMBER_1">%d</xliff:g> с."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Пароль неправильно введено стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. \n\nПовторіть спробу через <xliff:g id="NUMBER_1">%d</xliff:g> с."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. \n\nПовторіть спробу через <xliff:g id="NUMBER_1">%d</xliff:g> с."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Кількість невдалих спроб розблокувати планшетний ПК: <xliff:g id="NUMBER_0">%d</xliff:g>. У вас є ще стільки спроб: <xliff:g id="NUMBER_1">%d</xliff:g>. У разі невдачі налаштування планшетного ПК буде змінено на заводські за умовчанням, а всі дані користувача – втрачено."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Кількість невдалих спроб розблокувати телефон: <xliff:g id="NUMBER_0">%d</xliff:g>. У вас є ще стільки спроб: <xliff:g id="NUMBER_1">%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="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">%d</xliff:g>. У вас є ще стільки спроб: <xliff:g id="NUMBER_1">%d</xliff:g>. У разі невдачі з’явиться запит розблокувати планшетний ПК за допомогою облікового запису електронної пошти."\n\n" Повторіть спробу через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. У вас є ще стільки спроб: <xliff:g id="NUMBER_1">%d</xliff:g>. У разі невдачі з’явиться запит розблокувати телефон за допомогою облікового запису електронної пошти."\n\n" Повторіть спробу через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. У вас є ще стільки спроб: <xliff:g id="NUMBER_1">%d</xliff:g>. У разі невдачі з’явиться запит розблокувати планшетний ПК за допомогою облікового запису електронної пошти.\n\n Повторіть спробу через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. У вас є ще стільки спроб: <xliff:g id="NUMBER_1">%d</xliff:g>. У разі невдачі з’явиться запит розблокувати телефон за допомогою облікового запису електронної пошти.\n\n Повторіть спробу через <xliff:g id="NUMBER_2">%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="7324161939475478066">"Збільшити гучність понад рекомендований рівень?"\n"Якщо слухати надто гучну музику тривалий час, можна пошкодити слух."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Збільшити гучність понад рекомендований рівень?\nЯкщо слухати надто гучну музику тривалий час, можна пошкодити слух."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Утримуйте двома пальцями, щоб увімкнути доступність."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Доступність увімкнено."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Доступність скасовано."</string>
     <string name="user_switched" msgid="3768006783166984410">"Поточний користувач: <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="app_no_restricted_accounts" msgid="4011285085817350390">"Ця програма не підтримує облікові записи для обмежених профілів"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Ця програма не підтримує облікові записи для обмежених профілів"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Не знайдено програму для обробки цієї дії"</string>
     <string name="revoke" msgid="5404479185228271586">"Анулювати"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Скасовано"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Помилка записування вмісту"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"невідомо"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Введіть 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>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Новий PIN-код"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Підтвердьте новий PIN-код"</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_too_short" msgid="8173982756265777792">"PIN-код закороткий. Має бути принаймні 4 цифри."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Повтор за 1 с"</item>
+    <item quantity="other" msgid="4730868920742952817">"Повтор за <xliff:g id="COUNT">%d</xliff:g> с"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Спробуйте пізніше"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Гортайте від краю, щоб відкрити панель"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Проведіть пальцем від краю екрана, щоб з’явилась навігаційна панель"</string>
 </resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index d4d17a6..954e52d 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -131,6 +131,11 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Quá nhiều lần xóa <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Bộ nhớ máy tính bảng đã đầy. Hãy xóa một số tệp để tạo thêm dung lượng."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Bộ nhớ điện thoại đã đầy. Hãy xóa một số tệp để tạo thêm dung lượng."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Mạng có thể được giám sát"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Tôi"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Tùy chọn máy tính bảng"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Tùy chọn điện thoại"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Cho phép ứng dụng di chuyển công việc sang nền trước và nền sau. Ứng dụng có thể thực hiện việc này mà không cần bạn nhập."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"dừng các ứng dụng đang chạy"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Cho phép ứng dụng xóa công việc và loại bỏ các ứng dụng của chúng. Ứng dụng độc hại có thể làm gián đoạn hoạt động của các ứng dụng khác."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"quản lý ngăn xếp hoạt động"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Cho phép ứng dụng thêm, xóa và sửa đổi ngăn xếp hoạt động nơi các ứng dụng khác chạy. Ứng dụng độc hại có thể làm gián đoạn hoạt động của các ứng dụng khác."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"bắt đầu mọi hoạt động"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Cho phép ứng dụng bắt đầu mọi hoạt động, bất kể tình trạng bảo vệ quyền hay trạng thái xuất."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"đặt độ tương thích màn hình"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Cho phép chủ sở hữu liên kết với giao diện cấp cao nhất của phương thức nhập. Không cần thiết cho các ứng dụng thông thường."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"liên kết với dịch vụ truy cập"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Cho phép chủ sở hữu liên kết với giao diện cấp cao nhất của dịch vụ truy cập. Không cần thiết cho các ứng dụng thông thường."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"liên kết với dịch vụ in"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Cho phép chủ sở hữu liên kết với giao diện cấp cao nhất của dịch vụ in. Không cần thiết cho các ứng dụng thông thường."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"liên kết với dịch vụ bộ đệm in"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Cho phép chủ sở hữu liên kết với giao diện cấp cao nhất của dịch vụ bộ đệm in. Không cần thiết cho các ứng dụng thông thường."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"liên kết với dịch vụ NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Cho phép chủ sở hữu liên kết với ứng dụng đang mô phỏng thẻ NFC. Không cần thiết cho các ứng dụng thông thường."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"liên kết với dịch vụ văn bản"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Cho phép chủ sở hữu liên kết với giao diện cấp cao nhất của dịch vụ văn bản (ví dụ: SpellCheckerService). Không cần thiết cho các ứng dụng thông thường."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"liên kết với dịch vụ VPN"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Cho phép chủ sở hữu liên kết với giao diện cấp cao nhất của dịch vụ tiện ích con. Không cần thiết cho các ứng dụng thông thường."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"tương tác với quản trị viên thiết bị"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Cho phép chủ sở hữu gửi các ý định đến quản trị viên thiết bị. Không cần thiết cho các ứng dụng thông thường."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"thêm hoặc xóa quản trị viên thiết bị"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Cho phép chủ sở hữu thêm hoặc xóa quản trị viên thiết bị đang hoạt động. Không cần thiết cho các ứng dụng thông thường."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"thay đổi hướng màn hình"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Cho phép ứng dụng thay đổi độ xoay màn hình bất cứ lúc nào. Không cần thiết cho các ứng dụng thông thường."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"thay đổi tốc độ con trỏ"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Cho phép ứng dụng đọc từ nhiều tệp nhật ký khác nhau của hệ thống. Quyền này cho phép ứng dụng phát hiện thông tin chung về những gì bạn đang thực hiện với điện thoại, có thể bao gồm thông tin cá nhân hoặc riêng tư."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"sử dụng bất kỳ bộ giải mã phương tiện nào để phát lại"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Cho phép ứng dụng sử dụng bất kỳ trình giải mã phương tiện nào đã cài đặt nhằm giải mã để phát lại."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"quản lý thông tin xác thực đáng tin cậy"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Cho phép ứng dụng cài đặt và gỡ cài đặt chứng chỉ CA dưới dạng thông tin xác thực đáng tin cậy."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"đọc/ghi vào tài nguyên do chẩn đoán sở hữu"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Cho phép ứng dụng đọc và ghi vào bất kỳ tài nguyên nào do nhóm chẩn đoán sở hữu; ví dụ: các tệp trong /dev. Quyền này có thể ảnh hưởng đến sự ổn định và tính bảo mật của hệ thống. CHỈ nên sử dụng quyền này cho các chẩn đoán phần cứng cụ thể của nhà sản xuất hoặc nhà cung cấp."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"bật hoặc tắt cấu phần ứng dụng"</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Cho phép ứng dụng định cấu hình và kết nối với màn hình Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"kiểm soát màn hình Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Cho phép ứng dụng kiểm soát các tính năng cấp thấp của màn hình Wi-Fi."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"thu thập dữ liệu đầu ra âm thanh"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Cho phép ứng dụng thu thập và chuyển hướng dữ liệu đầu ra âm thanh."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"thu thập dữ liệu đầu ra video"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Cho phép ứng dụng thu thập và chuyển hướng dữ liệu đầu ra video."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"thu thập dữ liệu đầu ra video an toàn"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Cho phép ứng dụng thu thập và chuyển hướng dữ liệu đầu ra video an toàn."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"thay đổi cài đặt âm thanh của bạn"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Cho phép ứng dụng sửa đổi cài đặt âm thanh chung chẳng hạn như âm lượng và loa nào được sử dụng cho thiết bị ra."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"ghi âm"</string>
@@ -525,6 +552,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"ngăn điện thoại chuyển sang chế độ ngủ"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Cho phép ứng dụng ngăn máy tính bảng chuyển sang chế độ ngủ."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Cho phép ứng dụng ngăn điện thoại chuyển sang chế độ ngủ."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"bật hoặc tắt máy tính bảng"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"bật hoặc tắt điện thoại"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Cho phép ứng dụng bật hoặc tắt máy tính bảng."</string>
@@ -613,6 +646,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Cho phép ứng dụng ghi vào thẻ SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"sửa đổi/xóa nội dung trên bộ nhớ phương tiện cục bộ"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Cho phép ứng dụng sửa đổi nội dung của bộ lưu trữ phương tiện nội bộ."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"quản lý bộ nhớ tài liệu"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Cho phép ứng dụng quản lý bộ nhớ tài liệu."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"truy cập bộ nhớ ngoài của tất cả người dùng"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Cho phép ứng dụng truy cập bộ nhớ ngoài của tất cả người dùng."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"truy cập hệ thống tệp bộ nhớ cache"</string>
@@ -625,10 +660,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Cho phép ứng dụng quản lý chính sách mạng và xác định quy tắc dành riêng cho ứng dụng."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"sửa đổi hạch toán sử dụng mạng"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Cho phép ứng dụng sửa đổi cách tính mức sử dụng mạng so với ứng dụng. Không dành cho các ứng dụng thông thường."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"sửa đổi nhãn ổ cắm"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Cho phép ứng dụng sửa đổi nhãn ổ cắm để định tuyến"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"truy cập thông báo"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Cho phép ứng dụng truy xuất, kiểm tra và xóa thông báo, bao gồm những thông báo được đăng bởi các ứng dụng khác."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"liên kết với dịch vụ trình xử lý thông báo"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Cho phép chủ sở hữu liên kết với giao diện cấp cao nhất của dịch vụ trình xử lý thông báo. Không cần thiết cho các ứng dụng thông thường."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"gọi ra ứng dụng cấu hình do nhà cung cấp dịch vụ cung cấp"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Cho phép chủ sở hữu gọi ra ứng dụng cấu hình do nhà cung cấp dịch vụ cung cấp. Không cần thiết cho các ứng dụng thông thường."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"quan sát các điều kiện mạng"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Cho phép ứng dụng quan sát các điều kiện mạng. Không bao giờ cần cho ứng dụng thông thường."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Đặt quy tắc mật khẩu"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kiểm soát độ dài và ký tự được phép trong mật khẩu mở khóa màn hình."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Giám sát những lần thử mở khóa màn hình"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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>
@@ -796,7 +836,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Hãy lắp thẻ SIM."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Thẻ SIM bị thiếu hoặc không thể đọc được. Vui lòng lắp thẻ SIM."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Thẻ SIM không sử dụng được."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Thẻ SIM của bạn đã bị vô hiệu hóa vĩnh viễn ."\n" Hãy liên hệ với nhà cung cấp dịch vụ không dây của bạn để lấy thẻ SIM khác."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Thẻ SIM của bạn đã bị vô hiệu hóa vĩnh viễn .\n Hãy liên hệ với nhà cung cấp dịch vụ không dây của bạn để lấy thẻ SIM khác."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Nút bài hát trước"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Nút bài hát tiếp theo"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Nút tạm dừng"</string>
@@ -808,11 +848,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Vui lòng xem Hướng dẫn người dùng hoặc liên hệ với Bộ phận chăm sóc khách hàng."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Thẻ SIM đã bị khóa."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Đang mở khóa thẻ SIM…"</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần vẽ không chính xác hình mở khóa của mình. "\n\n"Vui lòng thử lại sau <xliff:g id="NUMBER_1">%d</xliff:g> giây."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần nhập sai mật khẩu. Hãy "\n\n"thử lại sau <xliff:g id="NUMBER_1">%d</xliff:g> giây."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Bạn đã nhập sai mã PIN <xliff:g id="NUMBER_0">%d</xliff:g> lần. "\n\n"Hãy thử lại sau <xliff:g id="NUMBER_1">%d</xliff:g> giây."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần vẽ không chính xác hình mở khóa của mình. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa máy tính bảng bằng thông tin đăng nhập Google của mình."\n\n" Vui lòng thử lại sau <xliff:g id="NUMBER_2">%d</xliff:g> giây."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần vẽ không chính xác hình mở khóa của mình. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa điện thoại bằng thông tin đăng nhập Google của bạn."\n\n" Vui lòng thử lại sau <xliff:g id="NUMBER_2">%d</xliff:g> giây."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần vẽ không chính xác hình mở khóa của mình. \n\nVui lòng thử lại sau <xliff:g id="NUMBER_1">%d</xliff:g> giây."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần nhập sai mật khẩu. Hãy \n\nthử lại sau <xliff:g id="NUMBER_1">%d</xliff:g> giây."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Bạn đã nhập sai mã PIN <xliff:g id="NUMBER_0">%d</xliff:g> lần. \n\nHãy thử lại sau <xliff:g id="NUMBER_1">%d</xliff:g> giây."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần vẽ không chính xác hình mở khóa của mình. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa máy tính bảng bằng thông tin đăng nhập Google của mình.\n\n Vui lòng thử lại sau <xliff:g id="NUMBER_2">%d</xliff:g> giây."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần vẽ không chính xác hình mở khóa của mình. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa điện thoại bằng thông tin đăng nhập Google của bạn.\n\n Vui lòng thử lại sau <xliff:g id="NUMBER_2">%d</xliff:g> giây."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Bạn đã mở khóa máy tính bảng không đúng cách <xliff:g id="NUMBER_0">%d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần mở khóa không thành công nữa, máy tính bảng sẽ được đặt lại về mặc định ban đầu và tất cả dữ liệu người dùng sẽ bị mất."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Bạn đã mở khóa điện thoại không đúng cách <xliff:g id="NUMBER_0">%d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần mở khóa không thành công nữa, điện thoại sẽ được đặt lại về mặc định ban đầu và tất cả dữ liệu người dùng sẽ bị mất."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Bạn đã mở khóa máy tính bảng không đúng cách <xliff:g id="NUMBER">%d</xliff:g> lần. Bây giờ, máy tính bảng sẽ được đặt lại về mặc định ban đầu."</string>
@@ -826,7 +866,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Mật khẩu"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Đăng nhập"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Tên người dùng hoặc mật khẩu không hợp lệ."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Bạn quên tên người dùng hoặc mật khẩu?"\n"Hãy truy cập "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Bạn quên tên người dùng hoặc mật khẩu?\nHãy truy cập "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Đang kiểm tra…"</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Mở khóa"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Bật âm thanh"</string>
@@ -874,7 +914,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Xác nhận điều hướng"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Rời khỏi trang này"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Ở lại trang này"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Bạn có chắc chắn muốn điều hướng khỏi trang này không?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nBạn có chắc chắn muốn điều hướng khỏi trang này không?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Xác nhận"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Mẹo: Nhấn đúp để phóng to và thu nhỏ."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Tự động điền"</string>
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"Rất tiếc, <xliff:g id="APPLICATION">%1$s</xliff:g> đã dừng lại."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Rất tiếc, quá trình <xliff:g id="PROCESS">%1$s</xliff:g> đã dừng lại."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> hiện không phản hồi."\n\n"Bạn có muốn đóng ứng dụng này không?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Hoạt động <xliff:g id="ACTIVITY">%1$s</xliff:g> không phản hồi."\n\n"Bạn có muốn đóng ứng dụng này không?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> hiện không phản hồi.\n\nBạn có muốn đóng ứng dụng này không?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Hoạt động <xliff:g id="ACTIVITY">%1$s</xliff:g> không phản hồi.\n\nBạn có muốn đóng ứng dụng này không?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> hiện không phản hồi. Bạn có muốn đóng ứng dụng không?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Quá trình <xliff:g id="PROCESS">%1$s</xliff:g> hiện không phản hồi."\n\n"Bạn có muốn đóng ứng dụng này không?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Quá trình <xliff:g id="PROCESS">%1$s</xliff:g> hiện không phản hồi.\n\nBạn có muốn đóng ứng dụng này không?"</string>
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"Báo cáo"</string>
     <string name="wait" msgid="7147118217226317732">"Đợi"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"Trang không phản hồi."\n\n"Bạn có muốn đóng trang không?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Trang không phản hồi.\n\nBạn có muốn đóng trang không?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Đã chuyển hướng ứng dụng"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> hiện đang chạy."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> được khởi chạy trước tiên."</string>
@@ -1256,6 +1296,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Cho phép ứng dụng gọi ra dịch vụ bộ chứa mặc định để sao chép nội dung. Không dành cho ứng dụng thông thường."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Định tuyến thiết bị ra phương tiện"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Cho phép ứng dụng định tuyến thiết bị ra phương tiện đến các thiết bị bên ngoài khác."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Truy cập bộ nhớ an toàn khóa bàn phím"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Cho phép ứng dụng truy cập bộ nhớ an toàn khóa"</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Kiểm soát việc hiển thị và ẩn tính năng bảo vệ phím"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Cho phép ứng dụng kiểm soát tính năng bảo vệ phím."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Chạm hai lần để kiểm soát thu phóng"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Không thể thêm tiện ích."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Đến"</string>
@@ -1265,15 +1309,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Xong"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Trước"</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Thực hiện"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Quay số"\n"sử dụng <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Tạo liên hệ"\n"sử dụng <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Quay số\nsử dụng <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Tạo liên hệ\nsử dụng <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Một hoặc nhiều ứng dụng sau đây yêu cầu quyền truy cập vào tài khoản của bạn, hiện tại và trong tương lai."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Bạn có muốn cho phép yêu cầu này không?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Yêu cầu truy cập"</string>
     <string name="allow" msgid="7225948811296386551">"Cho phép"</string>
     <string name="deny" msgid="2081879885755434506">"Từ chối"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Đã yêu cầu quyền"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Đã yêu cầu quyền"\n"cho tài khoản <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Đã yêu cầu quyền\ncho tài khoản <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Phương thức nhập"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Đồng bộ hóa"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Khả năng truy cập"</string>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Xem tất cả"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Chọn hoạt động"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Chia sẻ với"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Thiết bị đã bị khóa."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Đang gửi…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Khởi chạy trình duyệt?"</string>
@@ -1441,10 +1484,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Đang kết nối..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Khả dụng"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"Không khả dụng"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"Đang được sử dụng"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Màn hình tích hợp"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"Màn hình HDMI"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Lớp phủ #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", an toàn"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Hiển thị không dây đã được kết nối"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Màn hình này đang hiển thị trên thiết bị khác"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Ngắt kết nối"</string>
@@ -1453,7 +1498,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Hình sai"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Mật khẩu sai"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN sai"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Hãy thử lại sau <xliff:g id="NUMBER">%d</xliff:g> giây."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Hãy thử lại sau <xliff:g id="NUMBER">%1$d</xliff:g> giây."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Vẽ hình của bạn"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Nhập PIN của SIM"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Nhập PIN"</string>
@@ -1473,27 +1518,85 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Mật khẩu"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Đăng nhập"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Tên người dùng hoặc mật khẩu không hợp lệ."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Bạn quên tên người dùng hoặc mật khẩu?"\n"Hãy truy cập "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Bạn quên tên người dùng hoặc mật khẩu?\nHãy truy cập "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Đang kiểm tra tài khoản…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần nhập sai mã PIN của mình. Hãy "\n\n"thử lại sau <xliff:g id="NUMBER_1">%d</xliff:g> giây."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần nhập sai mật khẩu của mình. Hãy "\n\n"thử lại sau <xliff:g id="NUMBER_1">%d</xliff:g> giây."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần vẽ không chính xác hình mở khóa của mình. Hãy "\n\n"thử lại sau <xliff:g id="NUMBER_1">%d</xliff:g> giây."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần nhập sai mã PIN của mình. Hãy \n\nthử lại sau <xliff:g id="NUMBER_1">%d</xliff:g> giây."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần nhập sai mật khẩu của mình. Hãy \n\nthử lại sau <xliff:g id="NUMBER_1">%d</xliff:g> giây."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần vẽ không chính xác hình mở khóa của mình. Hãy \n\nthử lại sau <xliff:g id="NUMBER_1">%d</xliff:g> giây."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần mở khóa máy tính bảng không đúng cách. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần mở khóa không thành công nữa, máy tính bảng sẽ được đặt lại về mặc định ban đầu và tất cả dữ liệu người dùng sẽ bị mất."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần mở khóa điện thoại không đúng cách. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần mở khóa không thành công nữa, điện thoại sẽ được đặt lại về mặc định ban đầu và tất cả dữ liệu người dùng sẽ bị mất."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Bạn đã <xliff:g id="NUMBER">%d</xliff:g> lần mở khóa máy tính bảng không đúng cách. Bây giờ, máy tính bảng sẽ được đặt lại về mặc định ban đầu."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Bạn đã <xliff:g id="NUMBER">%d</xliff:g> lần mở khóa điện thoại không đúng cách. Bây giờ, điện thoại sẽ được đặt lại về mặc định ban đầu."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần vẽ không chính xác hình mở khóa của mình. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa máy tính bảng bằng tài khoản email."\n\n" Vui lòng thử lại sau <xliff:g id="NUMBER_2">%d</xliff:g> giây."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần vẽ không chính xác hình mở khóa của mình. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa điện thoại bằng tài khoản email."\n\n" Vui lòng thử lại sau <xliff:g id="NUMBER_2">%d</xliff:g> giây."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần vẽ không chính xác hình mở khóa của mình. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa máy tính bảng bằng tài khoản email.\n\n Vui lòng thử lại sau <xliff:g id="NUMBER_2">%d</xliff:g> giây."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần vẽ không chính xác hình mở khóa của mình. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa điện thoại bằng tài khoản email.\n\n Vui lòng thử lại sau <xliff:g id="NUMBER_2">%d</xliff:g> giây."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Xóa"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Tăng âm lượng trên mức được đề xuất?"\n"Nghe ở mức âm lượng cao trong thời gian dài có thể gây hại cho thính giác của bạn."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Tăng âm lượng trên mức được đề xuất?\nNghe ở mức âm lượng cao trong thời gian dài có thể gây hại cho thính giác của bạn."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Tiếp tục giữ hai ngón tay để bật trợ năng."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Trợ năng đã được bật."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Đã hủy trợ năng."</string>
     <string name="user_switched" msgid="3768006783166984410">"Người dùng hiện tại <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Chủ sở hữu"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Lỗi"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Ứng dụng này không hỗ trợ tài khoản cho các tiểu sử bị hạn chế"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Ứng dụng này không hỗ trợ tài khoản đối với các tiểu sử bị hạn chế"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Không tìm thấy ứng dụng nào để xử lý tác vụ này"</string>
     <string name="revoke" msgid="5404479185228271586">"Thu hồi"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Thư"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Thư của chính phủ"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Legal khổ nhỏ"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Sổ cái"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Đã hủy"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Lỗi ghi nội dung"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"không xác định"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Nhập mã PIN của quản trị viên"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Nhập mã PIN"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Không đúng"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Mã PIN hiện tại"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Mã PIN mới"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Xác nhận mã PIN mới"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Tạo mã PIN để hạn chế sửa đổi"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"Mã PIN không khớp. Hãy thử lại."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"Mã PIN quá ngắn. Phải có ít nhất 4 chữ số."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Hãy thử lại sau 1 giây"</item>
+    <item quantity="other" msgid="4730868920742952817">"Hãy thử lại sau <xliff:g id="COUNT">%d</xliff:g> giây"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Hãy thử lại sau"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Vuốt cạnh màn hình để hiện thanh"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Vuốt từ cạnh màn hình để hiển thị thanh hệ thống"</string>
 </resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 2c23f8f..c765417 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -131,6 +131,11 @@
     <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="default" msgid="3475999286680000541">"手机存储空间已满。请删除一些文件以腾出空间。"</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"网络可能会受到监控"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"我"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"平板电脑选项"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"手机选项"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"允许该应用将任务移动到前台和后台。该应用可能不经您的命令自行执行此操作。"</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"停止正在运行的应用"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"允许该应用删除任务并终止这些任务的应用。恶意应用可以籍此影响其他应用的行为。"</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"管理活动栈"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"允许应用添加、删除和修改其他应用的运行活动栈。恶意应用可以籍此影响其他应用的行为。"</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"启动任何活动"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"允许该应用启动任何活动(不考虑权限保护或导出状态)。"</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"设置屏幕兼容性"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"允许用户绑定至输入法的顶级接口。普通应用绝不需要此权限。"</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"绑定至辅助服务"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"允许应用绑定至辅助服务的顶级接口。普通应用绝不需要此权限。"</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"绑定至打印服务"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"允许应用绑定至打印服务的顶级接口。普通应用绝不需要此权限。"</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"绑定至打印处理服务"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"允许应用绑定至打印处理服务的顶级接口。普通应用绝不需要此权限。"</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"绑定到 NFC 服务"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"允许应用绑定到模拟 NFC 卡的应用。普通应用绝不需要此权限。"</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"绑定至文字服务"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"允许用户绑定至文字服务(如 SpellCheckerService)的顶级接口。普通应用绝不需要此权限。"</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"绑定到 VPN 服务"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"允许应用绑定到小部件服务的顶级接口。普通应用绝不需要此权限。"</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"与设备管理器交互"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"允许用户将意向发送给设备管理员。普通应用绝不需要此权限。"</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"添加或删除设备管理员"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"允许应用添加或删除有效的设备管理员。普通应用绝不需要此权限。"</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"更改屏幕显示方向"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"允许应用随时更改屏幕的旋转状态。普通应用绝不需要此权限。"</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"更改指针速度"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"允许应用从系统的各个日志文件中读取信息。这样,应用就可以发现关于您手机使用情况的一般信息,其中可能包含个人信息或隐私信息。"</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"使用任何媒体解码器进行播放"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"允许该应用使用任何已安装的媒体解码器进行解码,以便播放媒体。"</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"管理受信任的凭据"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"允许应用安装和卸载 CA 证书(作为受信任的凭据)。"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"读取/写入诊断所拥有的资源"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"允许应用读取/写入诊断组拥有的所有资源(例如 /dev 中的文件)。这可能会影响系统的稳定性和安全性。此权限仅供制造商或运营商诊断硬件方面的问题时使用。"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"启用或停用应用组件"</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"允许应用配置并连接到 WLAN 显示设备。"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"控制 WLAN 显示设备"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"允许应用控制 WLAN 显示设备的基础功能。"</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"捕获音频输出"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"允许该应用捕获和重定向音频输出。"</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"捕获视频输出"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"允许该应用捕获和重定向视频输出。"</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"捕获安全视频输出"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"允许该应用捕获和重定向安全视频输出。"</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"更改您的音频设置"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"允许该应用修改全局音频设置,例如音量和用于输出的扬声器。"</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"录音"</string>
@@ -525,6 +552,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"防止手机休眠"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"允许应用阻止平板电脑进入休眠状态。"</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"允许应用阻止手机进入休眠状态。"</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"打开或关闭平板电脑"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"开机或关机"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"允许应用打开或关闭平板电脑。"</string>
@@ -613,6 +646,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"允许应用写入 SD 卡。"</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"修改/删除内部媒体存储设备的内容"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"允许应用修改内部媒体存储设备的内容。"</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"管理文档存储空间"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"允许应用管理文档存储空间。"</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"访问所有用户的外部存储设备"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"允许应用访问所有用户的外部存储设备。"</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"访问缓存文件系统"</string>
@@ -625,10 +660,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"允许应用管理网络政策和定义专门针对应用的规则。"</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"修改网络使用情况记录方式"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"允许该应用修改对于各应用的网络使用情况的统计方式。普通应用不应使用此权限。"</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"修改套接字标记"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"允许应用修改用于路由的套接字标记"</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_invokeCarrierSetup" msgid="3699600833975117478">"调用运营商提供的配置应用"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"允许应用调用运营商提供的配置应用。普通应用绝不需要此权限。"</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"监听网络状况的观测信息"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"允许应用监听网络状况的观测信息。普通应用绝不需要此权限。"</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"设置密码规则"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"控制屏幕解锁密码所允许的长度和字符。"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"监视屏幕解锁尝试次数"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"雅虎"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <string name="imProtocolGoogleTalk" msgid="493902321140277304">"环聊"</string>
     <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string>
     <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string>
     <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string>
@@ -796,7 +836,7 @@
     <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">"您的 SIM 卡已永久停用。\n请与您的无线服务提供商联系,以便重新获取一张 SIM 卡。"</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"“上一曲目”按钮"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"“下一曲目”按钮"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"“暂停”按钮"</string>
@@ -808,11 +848,11 @@
     <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">%d</xliff:g> 次错误地绘制了解锁图案。"\n\n"请在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒后重试。"</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地输入了密码。"\n\n"请在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒后重试。"</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地输入了 PIN。"\n\n"请在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒后重试。"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地绘制了解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的 Google 登录信息解锁平板电脑。"\n\n"请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地绘制了解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统会要求您使用自己的 Google 登录信息解锁手机。"\n\n" 请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地绘制了解锁图案。\n\n请在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒后重试。"</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地输入了密码。\n\n请在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒后重试。"</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地输入了 PIN。\n\n请在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒后重试。"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地绘制了解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的 Google 登录信息解锁平板电脑。\n\n请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地绘制了解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统会要求您使用自己的 Google 登录信息解锁手机。\n\n 请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地尝试解锁平板电脑。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,平板电脑将重置为出厂默认设置,所有用户数据将会丢失。"</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地尝试解锁手机。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,手机将重置为出厂默认设置,所有用户数据将会丢失。"</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"您已经 <xliff:g id="NUMBER">%d</xliff:g> 次错误地尝试解锁平板电脑。平板电脑现在将重置为出厂默认设置。"</string>
@@ -826,7 +866,7 @@
     <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_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>
@@ -874,7 +914,7 @@
     <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="autofill_this_form" msgid="4616758841157816676">"自动填充"</string>
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"很抱歉,“<xliff:g id="APPLICATION">%1$s</xliff:g>”已停止运行。"</string>
     <string name="aerr_process" msgid="4507058997035697579">"抱歉,进程“<xliff:g id="PROCESS">%1$s</xliff:g>”已停止运行。"</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> 无响应。"\n\n"要将其关闭吗?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"<xliff:g id="ACTIVITY">%1$s</xliff:g> 活动无响应。"\n\n"要将其关闭吗?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> 无响应。\n\n要将其关闭吗?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"<xliff:g id="ACTIVITY">%1$s</xliff:g> 活动无响应。\n\n要将其关闭吗?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> 无响应。要将其关闭吗?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"<xliff:g id="PROCESS">%1$s</xliff:g> 进程无响应。"\n\n"要将其关闭吗?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"<xliff:g id="PROCESS">%1$s</xliff:g> 进程无响应。\n\n要将其关闭吗?"</string>
     <string name="force_close" msgid="8346072094521265605">"确定"</string>
     <string name="report" msgid="4060218260984795706">"报告"</string>
     <string name="wait" msgid="7147118217226317732">"等待"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"该网页已无响应。"\n\n"要将其关闭吗?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"该网页已无响应。\n\n要将其关闭吗?"</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>
@@ -1256,6 +1296,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"允许应用调用默认的容器服务,以便复制内容。普通应用不应使用此权限。"</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"更改媒体输出线路"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"允许该应用将媒体输出线路更改到其他外部设备。"</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"访问密钥保护安全存储空间"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"允许应用访问密钥保护安全存储空间。"</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"控制是显示还是隐藏锁屏"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"允许应用控制锁屏。"</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"触摸两次可进行缩放控制"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"无法添加小部件。"</string>
     <string name="ime_action_go" msgid="8320845651737369027">"开始"</string>
@@ -1265,15 +1309,15 @@
     <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">"拨打电话"\n"<xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"创建电话号码为"\n"<xliff:g id="NUMBER">%s</xliff:g> 的联系人"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"拨打电话\n<xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"创建电话号码为\n<xliff:g id="NUMBER">%s</xliff:g> 的联系人"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"以下一个或多个应用请求获得相应权限,以便在当前和以后访问您的帐户。"</string>
     <string name="grant_credentials_permission_message_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="permission_request_notification_with_subtitle" msgid="8530393139639560189">"应用对帐户 <xliff:g id="ACCOUNT">%s</xliff:g>\n 提出权限请求。"</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>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"查看全部"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"选择活动"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"分享方式"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"设备已锁定。"</string>
     <string name="list_delimeter" msgid="3975117572185494152">"、 "</string>
     <string name="sending" msgid="3245653681008218030">"正在发送..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"要启动浏览器吗?"</string>
@@ -1441,10 +1484,12 @@
     <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>
+    <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_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="wifi_display_notification_title" msgid="2223050649240326557">"已连接到无线显示设备"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"此屏幕的内容正显示在另一台设备上"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"断开连接"</string>
@@ -1453,7 +1498,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">%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">"输入 SIM PIN"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"输入 PIN"</string>
@@ -1473,27 +1518,85 @@
     <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_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">%d</xliff:g> 次错误地输入了 PIN。"\n\n"请在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒后重试。"</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地输入了密码。"\n\n"请在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒后重试。"</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地绘制了解锁图案。"\n\n"请在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒后重试。"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地输入了 PIN。\n\n请在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒后重试。"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地输入了密码。\n\n请在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒后重试。"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地绘制了解锁图案。\n\n请在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒后重试。"</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地尝试解锁平板电脑。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,平板电脑就会重置为出厂默认设置,而且所有用户数据都会丢失。"</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地尝试解锁手机。如果再尝试 <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> 次错误地绘制了解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐户解锁平板电脑。"\n\n"请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地绘制了解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐户解锁手机。"\n\n"请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地绘制了解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐户解锁平板电脑。\n\n请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地绘制了解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐户解锁手机。\n\n请在 <xliff:g id="NUMBER_2">%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="7324161939475478066">"将音量调高到推荐级别以上?"\n"长时间聆听高音量可能会损伤听力。"</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"将音量调高到推荐级别以上?\n长时间聆听高音量可能会损伤听力。"</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"持续按住双指即可启用辅助功能。"</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"辅助功能已启用。"</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"已取消辅助功能。"</string>
     <string name="user_switched" msgid="3768006783166984410">"当前用户是<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="app_no_restricted_accounts" msgid="4011285085817350390">"此应用不支持受限个人资料的帐户"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"此应用不支持受限个人资料的帐户"</string>
     <string name="app_not_found" msgid="3429141853498927379">"找不到可处理此操作的应用"</string>
     <string name="revoke" msgid="5404479185228271586">"撤消"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"已取消"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"写入内容时出错"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"未知"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"输入管理员 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>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"新 PIN 码"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"确认新 PIN 码"</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_too_short" msgid="8173982756265777792">"PIN 码太短,至少应包含 4 位数字。"</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"1秒后重试"</item>
+    <item quantity="other" msgid="4730868920742952817">"<xliff:g id="COUNT">%d</xliff:g>秒后重试"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"稍后重试"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"从边缘向里滑可显示系统栏"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"从屏幕边缘向里滑可显示系统栏"</string>
 </resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..3b03aa5
--- /dev/null
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -0,0 +1,1602 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<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="5973789783504771878">"KB"</string>
+    <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
+    <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
+    <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
+    <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
+    <string name="untitled" msgid="4638956954852782576">"&lt;未命名&gt;"</string>
+    <string name="ellipsis" msgid="7899829516048813237">"..."</string>
+    <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
+    <string name="emptyPhoneNumber" msgid="7694063042079676517">"(沒有電話號碼)"</string>
+    <string name="unknownName" msgid="2277556546742746522">"(未知)"</string>
+    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"留言信箱"</string>
+    <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
+    <string name="mmiError" msgid="5154499457739052907">"連線發生問題或 MMI 碼無效。"</string>
+    <string name="mmiFdnError" msgid="5224398216385316471">"僅限對固定撥號號碼執行這項運作。"</string>
+    <string name="serviceEnabled" msgid="8147278346414714315">"服務已啟用。"</string>
+    <string name="serviceEnabledFor" msgid="6856228140453471041">"已啟用服務:"</string>
+    <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="mmiComplete" msgid="8232527495411698359">"已完成 MMI。"</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">"請輸入一個 4 至 8 位數的 PIN。"</string>
+    <string name="invalidPuk" msgid="8761456210898036513">"輸入 8 位數以上的 PUK。"</string>
+    <string name="needPuk" msgid="919668385956251611">"您的 SIM 卡已鎖定 PUK,請輸入 PUK 碼以解除鎖定。"</string>
+    <string name="needPuk2" msgid="4526033371987193070">"輸入 PUK2 為 SIM 卡解除封鎖。"</string>
+    <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="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">"更改 PIN"</string>
+    <string name="CnipMmi" msgid="3110534680557857162">"顯示來電號碼"</string>
+    <string name="CnirMmi" msgid="3062102121430548731">"隱藏通話號碼"</string>
+    <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="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"預設不顯示來電號碼,下一通電話也不顯示。"</string>
+    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"預設不顯示來電號碼,但下一通電話則顯示。"</string>
+    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"預設顯示來電號碼,但下一通電話不顯示。"</string>
+    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"預設顯示來電號碼,下一通電話也繼續顯示。"</string>
+    <string name="serviceNotProvisioned" msgid="8614830180508686666">"未提供此服務。"</string>
+    <string name="CLIRPermanent" msgid="3377371145926835671">"您無法更改來電顯示設定。"</string>
+    <string name="RestrictedChangedTitle" msgid="5592189398956187498">"受限存取已更改"</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="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>
+    <string name="serviceClassDataSync" msgid="7530000519646054776">"Google Sync"</string>
+    <string name="serviceClassPacket" msgid="6991006557993423453">"封包"</string>
+    <string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
+    <string name="roamingText0" msgid="7170335472198694945">"漫遊指示開啟"</string>
+    <string name="roamingText1" msgid="5314861519752538922">"漫遊指示關閉"</string>
+    <string name="roamingText2" msgid="8969929049081268115">"漫遊指示閃爍"</string>
+    <string name="roamingText3" msgid="5148255027043943317">"超出鄰近範圍"</string>
+    <string name="roamingText4" msgid="8808456682550796530">"超出建築物範圍"</string>
+    <string name="roamingText5" msgid="7604063252850354350">"漫遊 - 首選系統"</string>
+    <string name="roamingText6" msgid="2059440825782871513">"漫遊 - 可用系統"</string>
+    <string name="roamingText7" msgid="7112078724097233605">"漫遊 - 聯盟合作夥伴"</string>
+    <string name="roamingText8" msgid="5989569778604089291">"漫遊 - Google Premium 合作夥伴"</string>
+    <string name="roamingText9" msgid="7969296811355152491">"漫遊 - 完整服務功能"</string>
+    <string name="roamingText10" msgid="3992906999815316417">"漫遊 - 部份服務功能"</string>
+    <string name="roamingText11" msgid="4154476854426920970">"漫遊橫幅開啟"</string>
+    <string name="roamingText12" msgid="1189071119992726320">"漫遊橫幅關閉"</string>
+    <string name="roamingTextSearching" msgid="8360141885972279963">"正在搜尋服務"</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="httpErrorOk" msgid="1191919378083472204">"確定"</string>
+    <string name="httpError" msgid="7956392511146698522">"發生網絡錯誤。"</string>
+    <string name="httpErrorLookup" msgid="4711687456111963163">"找不到網址。"</string>
+    <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"網站認證機制不受支援。"</string>
+    <string name="httpErrorAuth" msgid="1435065629438044534">"無法認證。"</string>
+    <string name="httpErrorProxyAuth" msgid="1788207010559081331">"透過 Proxy 伺服器進行驗證失敗。"</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="httpErrorUnsupportedScheme" msgid="5015730812906192208">"通訊協定不受支援。"</string>
+    <string name="httpErrorFailedSslHandshake" msgid="96549606000658641">"無法建立安全連線。"</string>
+    <string name="httpErrorBadUrl" msgid="3636929722728881972">"網址無效,因此無法打開網頁。"</string>
+    <string name="httpErrorFile" msgid="2170788515052558676">"無法存取檔案。"</string>
+    <string name="httpErrorFileNotFound" msgid="6203856612042655084">"找不到所要求的檔案。"</string>
+    <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"同時處理過多要求,請稍後再試。"</string>
+    <string name="notification_title" msgid="8967710025036163822">"<xliff:g id="ACCOUNT">%1$s</xliff:g> 登入錯誤"</string>
+    <string name="contentServiceSync" msgid="8353523060269335667">"Google Sync"</string>
+    <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Google Sync"</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="default" msgid="3475999286680000541">"手機的儲存空間已滿。請刪除一些檔案,以騰出可用空間。"</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"網絡可能會受到監控"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
+    <string name="me" msgid="6545696007631404292">"我本人"</string>
+    <string name="power_dialog" product="tablet" msgid="8545351420865202853">"平板電腦選項"</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="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="shutdown_progress" msgid="2281079257329981203">"正在關機..."</string>
+    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"您的平板電腦將會關機。"</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="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_bug_report" msgid="7934010578922304799">"錯誤報告"</string>
+    <string name="bugreport_title" msgid="2667494803742548533">"取得錯誤報告"</string>
+    <string name="bugreport_message" msgid="398447048750350456">"這會收集您目前裝置狀態的相關資訊,並以電郵傳送給您。從開始建立錯誤報告到準備傳送需要一段時間,請耐心等候。"</string>
+    <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_airplane_mode_on_status" msgid="2719557982608919750">"飛航模式為 [開啟]"</string>
+    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"飛行模式為 [關閉]"</string>
+    <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
+    <string name="safeMode" msgid="2788228061547930246">"安全模式"</string>
+    <string name="android_system_label" msgid="6577375335728551336">"Android 系統"</string>
+    <string name="permgrouplab_costMoney" msgid="5429808217861460401">"付費服務"</string>
+    <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"執行需付費的操作或服務。"</string>
+    <string name="permgrouplab_messages" msgid="7521249148445456662">"您的訊息"</string>
+    <string name="permgroupdesc_messages" msgid="7821999071003699236">"讀取及寫入您的短訊、電郵和其他訊息。"</string>
+    <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"您的個人資訊"</string>
+    <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"直接存取您儲存在聯絡人卡片中的個人資訊。"</string>
+    <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"您的社交資訊"</string>
+    <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"直接存取您的聯絡人資訊和社交網站資訊。"</string>
+    <string name="permgrouplab_location" msgid="635149742436692049">"您的所在位置"</string>
+    <string name="permgroupdesc_location" msgid="5704679763124170100">"監控您的實際位置。"</string>
+    <string name="permgrouplab_network" msgid="5808983377727109831">"網絡通訊"</string>
+    <string name="permgroupdesc_network" msgid="4478299413241861987">"存取各種網絡功能。"</string>
+    <string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"藍牙"</string>
+    <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"透過藍牙存取裝置和網絡。"</string>
+    <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"音效設定"</string>
+    <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"更改音效設定。"</string>
+    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"影響電池"</string>
+    <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"使用可能大量耗電的功能。"</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"日曆"</string>
+    <string name="permgroupdesc_calendar" msgid="5777534316982184416">"直接存取日曆和活動。"</string>
+    <string name="permgrouplab_dictionary" msgid="4148597128843641379">"讀取用戶字典"</string>
+    <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"讀取用戶字典中的字詞。"</string>
+    <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"寫入用戶字典"</string>
+    <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"將字詞加入用戶字典。"</string>
+    <string name="permgrouplab_bookmarks" msgid="1949519673103968229">"書籤和記錄"</string>
+    <string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"直接存取書籤和瀏覽器紀錄。"</string>
+    <string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"鬧鐘"</string>
+    <string name="permgroupdesc_deviceAlarms" msgid="4769356362251641175">"設定鬧鐘。"</string>
+    <string name="permgrouplab_voicemail" msgid="4162237145027592133">"留言信箱"</string>
+    <string name="permgroupdesc_voicemail" msgid="2498403969862951393">"直接存取留言信箱。"</string>
+    <string name="permgrouplab_microphone" msgid="171539900250043464">"麥克風"</string>
+    <string name="permgroupdesc_microphone" msgid="7106618286905738408">"直接使用麥克風錄音。"</string>
+    <string name="permgrouplab_camera" msgid="4820372495894586615">"相機"</string>
+    <string name="permgroupdesc_camera" msgid="2933667372289567714">"直接使用相機拍照或錄影。"</string>
+    <string name="permgrouplab_screenlock" msgid="8275500173330718168">"上鎖畫面"</string>
+    <string name="permgroupdesc_screenlock" msgid="7067497128925499401">"可影響裝置的上鎖畫面運作方式。"</string>
+    <string name="permgrouplab_appInfo" msgid="8028789762634147725">"您的應用程式資訊"</string>
+    <string name="permgroupdesc_appInfo" msgid="3950378538049625907">"能夠影響裝置上其他應用程式的行為。"</string>
+    <string name="permgrouplab_wallpaper" msgid="3850280158041175998">"桌布"</string>
+    <string name="permgroupdesc_wallpaper" msgid="5630417854750540154">"更改裝置桌布設定。"</string>
+    <string name="permgrouplab_systemClock" msgid="406535759236612992">"時鐘"</string>
+    <string name="permgroupdesc_systemClock" msgid="3944359833624094992">"更改裝置時間或時區。"</string>
+    <string name="permgrouplab_statusBar" msgid="2095862568113945398">"狀態列"</string>
+    <string name="permgroupdesc_statusBar" msgid="6242593432226807171">"更改裝置狀態列設定。"</string>
+    <string name="permgrouplab_syncSettings" msgid="3341990986147826541">"同步設定"</string>
+    <string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"存取同步設定。"</string>
+    <string name="permgrouplab_accounts" msgid="3359646291125325519">"您的帳戶"</string>
+    <string name="permgroupdesc_accounts" msgid="4948732641827091312">"存取可用帳戶。"</string>
+    <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"硬件控制"</string>
+    <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"直接在手機上存取硬件。"</string>
+    <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"來電"</string>
+    <string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"監控、記錄及處理手機通話。"</string>
+    <string name="permgrouplab_systemTools" msgid="4652191644082714048">"系統工具"</string>
+    <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"系統的低階存取權和控制權。"</string>
+    <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"開發工具"</string>
+    <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"僅限應用程式開發人員使用的功能。"</string>
+    <string name="permgrouplab_display" msgid="4279909676036402636">"其他應用程式用戶介面"</string>
+    <string name="permgroupdesc_display" msgid="6051002031933013714">"影響其他應用程式的用戶介面。"</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"儲存空間"</string>
+    <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"存取 USB 儲存裝置。"</string>
+    <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"存取 SD 卡。"</string>
+    <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"協助工具功能"</string>
+    <string name="permgroupdesc_accessibilityFeatures" msgid="4205196881678144335">"輔助技術可要求的功能。"</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="5800552516779249356">"朗讀您輕觸的項目,並可讓您使用手勢探索螢幕。"</string>
+    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"開啟增強版網頁無障礙設定"</string>
+    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"可能會安裝程式碼,使應用程式內容更易於存取。"</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"記錄您輸入的文字"</string>
+    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"包括個人資料,如信用卡號碼和密碼。"</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"停用或修改狀態列"</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"允許應用程式停用狀態列,並可新增或移除系統圖示。"</string>
+    <string name="permlab_statusBarService" msgid="7247281911387931485">"狀態列"</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_processOutgoingCalls" msgid="3906007831192990946">"重新設定撥出電話的路徑"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"允許應用程式處理撥出電話及更改撥打的號碼。這項權限允許應用程式監控、轉接或阻止撥出的電話。"</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_receiveEmergencyBroadcast" msgid="1803477660846288089">"接收緊急廣播"</string>
+    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"允許應用程式接收及處理緊急廣播訊息,系統應用程式才需要具有這項權限。"</string>
+    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"讀取區域廣播訊息"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"允許應用程式讀取您裝置接收的區域廣播訊息。某些地點會發出區域廣播警報,警告您發生緊急狀況。惡意應用程式可能會在裝置收到緊急區域廣播時,干擾裝置的性能或運作。"</string>
+    <string name="permlab_sendSms" msgid="5600830612147671529">"傳送 SMS 短訊"</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"允許應用程式傳送短訊,但可能產生未預期的費用。惡意應用程式可能會未經您確認擅自傳送短訊,增加您的支出。"</string>
+    <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"傳送透過短訊作出回應的活動"</string>
+    <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"允許應用程式傳送要求給其他短訊應用程式,為來電處理透過短訊作出回應的活動。"</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"讀取您的短訊 (SMS 或 MMS)"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"允許應用程式讀取平板電腦或 SIM 卡上儲存的短訊。這項權限允許應用程式不論內容及機密程度,均可讀取所有短訊。"</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"允許應用程式讀取手機或 SIM 卡上儲存的短訊。這項權限允許應用程式不論內容及機密程度,均可讀取所有短訊。"</string>
+    <string name="permlab_writeSms" msgid="3216950472636214774">"編輯您的短訊 (SMS 或 MMS)"</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"允許應用程式寫入平板電腦或 SIM 卡中儲存的短訊。惡意應用程式可能會藉此刪除您的訊息。"</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"允許應用程式寫入手機或 SIM 卡中儲存的短訊。惡意應用程式可能會藉此刪除您的訊息。"</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_interactAcrossUsers" msgid="7114255281944211682">"與其他用戶互動"</string>
+    <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"允許應用程式對裝置上的不同用戶執行各種操作。請注意,惡意應用程式可能藉此破壞各用戶之間的保護機制。"</string>
+    <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"全面授權與其他用戶互動"</string>
+    <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"允許與其他用戶進行各種可能的互動。"</string>
+    <string name="permlab_manageUsers" msgid="1676150911672282428">"管理用戶"</string>
+    <string name="permdesc_manageUsers" msgid="8409306667645355638">"允許應用程式管理裝置上的用戶,包括查詢、建立及刪除用戶。"</string>
+    <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"擷取運行中應用程式的詳細資料"</string>
+    <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"允許應用程式擷取目前及最近執行任務的詳細資訊。惡意應用程式可能會找到其他應用程式的私人資訊。"</string>
+    <string name="permlab_reorderTasks" msgid="2018575526934422779">"為執行中的應用程式重新排序"</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"允許應用程式將工作移至前景或背景。應用程式可以自行處理,您無須操作。"</string>
+    <string name="permlab_removeTasks" msgid="6821513401870377403">"停止執行中的應用程式"</string>
+    <string name="permdesc_removeTasks" msgid="1394714352062635493">"允許應用程式移除任務並終止相關的應用程式。惡意應用程式可能會干擾其他應用程式的行為。"</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"管理活動堆疊"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"允許應用程式新增、移除及修改可供其他應用程式在其中執行的活動堆疊。惡意應用程式可能會干擾其他應用程式的行為。"</string>
+    <string name="permlab_startAnyActivity" msgid="2918768238045206456">"啟動任何活動"</string>
+    <string name="permdesc_startAnyActivity" msgid="997823695343584001">"允許應用程式不論權限保護或匯出狀態皆可啟動任何活動。"</string>
+    <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"設定屏幕兼容性"</string>
+    <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"允許應用程式控制其他應用程式的屏幕兼容模式。惡意應用程式可能藉此破壞其他應用程式的正常運作。"</string>
+    <string name="permlab_setDebugApp" msgid="3022107198686584052">"啟用應用程式偵錯"</string>
+    <string name="permdesc_setDebugApp" msgid="4474512416299013256">"允許應用程式為其他程式開啟偵錯功能。惡意應用程式可能會藉此終止其他應用程式。"</string>
+    <string name="permlab_changeConfiguration" msgid="4162092185124234480">"更改系統顯示設定"</string>
+    <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"允許應用程式更改目前的設定,例如地區設定或字型大小。"</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_forceStopPackages" msgid="2329627428832067700">"強制停止其他應用程式"</string>
+    <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"允許應用程式強制停止其他應用程式。"</string>
+    <string name="permlab_forceBack" msgid="652935204072584616">"強制關閉應用程式"</string>
+    <string name="permdesc_forceBack" msgid="3892295830419513623">"允許應用程式強制結束前景中的活動並返回 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_dump" msgid="1681799862438954752">"擷取系統內部狀態"</string>
+    <string name="permdesc_dump" msgid="1778299088692290329">"允許應用程式擷取系統內部狀態。惡意應用程式可能會擷取他們通常不需要的各類私密資訊。"</string>
+    <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"取得螢幕內容"</string>
+    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"允許應用程式擷取使用中的視窗內容。惡意應用程式可能會擷取整個視窗的內容,以及檢視密碼除外的所有文字。"</string>
+    <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"暫時啟用協助工具"</string>
+    <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"允許應用程式在裝置上暫時啟用協助工具。惡意應用程式可能藉此在未經用戶同意的情況下擅自啟用協助工具。"</string>
+    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"擷取視窗資訊"</string>
+    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"允許應用程式從視窗管理程式擷取視窗的相關資訊。惡意應用程式可能會擷取專供內部系統使用的資訊。"</string>
+    <string name="permlab_filter_events" msgid="8675535648807427389">"篩選活動"</string>
+    <string name="permdesc_filter_events" msgid="8006236315888347680">"允許應用程式註冊輸入篩選器,在分派所有用戶活動的串流前先行篩選。惡意應用程式可能會繞過用戶操作,直接控制系統用戶介面。"</string>
+    <string name="permlab_magnify_display" msgid="5973626738170618775">"放大畫面"</string>
+    <string name="permdesc_magnify_display" msgid="7121235684515003792">"允許應用程式放大畫面內容。惡意應用程式可能會改變顯示內容,導致裝置失靈。"</string>
+    <string name="permlab_shutdown" msgid="7185747824038909016">"部分關機"</string>
+    <string name="permdesc_shutdown" msgid="7046500838746291775">"讓活動管理員進入關機狀態,而不執行完整的關機程序。"</string>
+    <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"防止切換應用程式"</string>
+    <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"防止用戶切換至其他應用程式。"</string>
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"取得目前的應用程式資訊"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"允許應用程式從目前屏幕前景的應用程式擷取私人資訊。"</string>
+    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"監視及控制所有應用程式的啟動程序"</string>
+    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"允許應用程式監視和控制系統啟動活動的方式。惡意應用程式可能會藉此破壞整個系統。這個權限只有開發人員才需要,一般使用上不需使用這個權限。"</string>
+    <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"傳送套件已移除廣播"</string>
+    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"允許應用程式在其他應用程式套件被移除時發送通知。惡意應用程式可能會藉此終止其他執行中的程式。"</string>
+    <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"傳送 SMS 可接收的廣播"</string>
+    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"允許應用程式在收到短訊時發出通知。惡意應用程式可能會藉此偽造外來短訊。"</string>
+    <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"傳送可由 WAP PUSH 接收的廣播"</string>
+    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"允許應用程式在收到 WAP PUSH 訊息時發送通知。惡意應用程式可能會藉此偽造 MMS 訊息回條或私自以惡意內容更換網頁。"</string>
+    <string name="permlab_setProcessLimit" msgid="2451873664363662666">"執行程序數目上限"</string>
+    <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"允許應用程式控制可執行程序的數量上限 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"強制關閉背景應用程式"</string>
+    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"允許應用程式控制活動是否隨時可於完成後立刻進入背景 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_batteryStats" msgid="2789610673514103364">"讀取電池使用統計資料"</string>
+    <string name="permdesc_batteryStats" msgid="5897346582882915114">"允許應用程式讀取目前的低電量使用資料。應用程式可能藉此找到有關您所使用應用程式的詳細資訊。"</string>
+    <string name="permlab_updateBatteryStats" msgid="3719689764536379557">"修改電池使用統計資料"</string>
+    <string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"允許應用程式修改收集到的電池使用統計資料 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_getAppOpsStats" msgid="1508779687436585744">"擷取應用程式操作統計資料"</string>
+    <string name="permdesc_getAppOpsStats" msgid="6243887041577912877">"允許應用程式擷取收集到的應用程式操作統計資料 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"修改應用程式操作統計資料"</string>
+    <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"允許應用程式修改收集到的應用程式操作統計資料 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_backup" msgid="470013022865453920">"控制系統備份和還原"</string>
+    <string name="permdesc_backup" msgid="6912230525140589891">"允許應用程式控制系統備份與還原機制 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"確認完整備份或還原作業"</string>
+    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"允許應用程式啟動完整備份確認用戶介面 (不建議任何應用程式使用)。"</string>
+    <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"顯示未經授權的視窗"</string>
+    <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"允許應用程式為內部系統用戶介面建立視窗 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"可套用至其他應用程式"</string>
+    <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"允許應用程式在其他應用程式上面或用戶介面的特定部分繪圖。這可能會干擾您使用任何應用程式的介面,或讓您誤會您在其他應用程式上所見內容的意思。"</string>
+    <string name="permlab_setAnimationScale" msgid="2805103241153907174">"修改全域動畫速度"</string>
+    <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"允許應用程式隨時更改全域的動畫速度 (更快或更慢)。"</string>
+    <string name="permlab_manageAppTokens" msgid="1286505717050121370">"管理應用程式憑證"</string>
+    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"允許應用程序略過一般程序,直接建立和管理本身的憑證 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_freezeScreen" msgid="4708181184441880175">"鎖定屏幕"</string>
+    <string name="permdesc_freezeScreen" msgid="8558923789222670064">"允許應用程式暫時鎖定屏幕畫面,顯示全屏幕轉場效果。"</string>
+    <string name="permlab_injectEvents" msgid="1378746584023586600">"按鍵及控制按鈕"</string>
+    <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"允許應用程式將本身的輸入操作 (按鍵等) 發送給其他應用程式。惡意應用程式可能會藉此操控平板電腦。"</string>
+    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"允許應用程式將本身的輸入操作 (按鍵等) 發送給其他應用程式。惡意應用程式可能會藉此操控手機。"</string>
+    <string name="permlab_readInputState" msgid="469428900041249234">"記錄您輸入的內容和採取的動作"</string>
+    <string name="permdesc_readInputState" msgid="8387754901688728043">"允許應用程式監看您的按鍵操作,包括使用其他應用程式時的按鍵操作 (例如輸入密碼) (不建議一般應用程式使用)。"</string>
+    <string name="permlab_bindInputMethod" msgid="3360064620230515776">"限定輸入法"</string>
+    <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"允許應用程式繫結至輸入法的頂層介面 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"繫結至協助工具服務"</string>
+    <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"允許應用程式繫結至協助工具服務的頂層介面 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"繫結至列印服務"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"允許應用程式繫結至列印服務的頂層介面 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"繫結至列印多工緩衝處理器服務"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"允許應用程式繫結至列印多工緩衝處理器服務的頂層介面 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"繫結至 NFC 服務"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"允許應用程式繫結至模擬 NFC 卡的應用程式 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_bindTextService" msgid="7358378401915287938">"繫結至文字服務"</string>
+    <string name="permdesc_bindTextService" msgid="8151968910973998670">"允許應用程式繫結至文字服務 (例如 SpellCheckerService) 的頂層介面 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_bindVpnService" msgid="4708596021161473255">"繫結至 VPN 服務"</string>
+    <string name="permdesc_bindVpnService" msgid="2067845564581693905">"允許應用程式繫結至 VPN 服務的頂層介面 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_bindWallpaper" msgid="8716400279937856462">"繫結至桌布"</string>
+    <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"允許應用程式繫結至桌布的頂層介面 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"繫結至小工具服務"</string>
+    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"允許應用程式繫結至小工具服務的頂層介面 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"與裝置管理員互動"</string>
+    <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"允許應用程式將調用請求傳送至裝置管理員 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"新增或移除裝置管理員"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"允許應用程式新增或移除有效的裝置管理員 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_setOrientation" msgid="3365947717163866844">"更改屏幕瀏覽方向"</string>
+    <string name="permdesc_setOrientation" msgid="3046126619316671476">"允許應用程式隨時更改屏幕定向 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"變更指標速度"</string>
+    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"允許應用程式隨時更改滑鼠或觸控板游標的移動速度 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"更改鍵盤配置"</string>
+    <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"允許應用程式更改鍵盤配置 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"將 Linux 訊號傳送給應用程式"</string>
+    <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"允許應用程式要求將提供的訊號傳送給所有持續的處理程序。"</string>
+    <string name="permlab_persistentActivity" msgid="8841113627955563938">"一律執行應用程式"</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"允許應用程式設定本身的某些部分持續佔用記憶體。這樣可能會限制其他應用程式可用的記憶體,並拖慢平板電腦的運作速度。"</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"允許應用程式設定本身的某些部分持續佔用記憶體。這樣可能會限制其他應用程式可用的記憶體,並拖慢手機的運作速度。"</string>
+    <string name="permlab_deletePackages" msgid="184385129537705938">"刪除應用程式"</string>
+    <string name="permdesc_deletePackages" msgid="7411480275167205081">"允許應用程式刪除 Android 套件。惡意應用程式可能會藉此刪除重要應用程式。"</string>
+    <string name="permlab_clearAppUserData" msgid="274109191845842756">"刪除其他應用程式資料"</string>
+    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"允許應用程式清除用戶資料。"</string>
+    <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"刪除其他應用程式的快取檔案"</string>
+    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"允許應用程式刪除快取檔案。"</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"測量應用程式儲存空間"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"允許應用程式擷取本身的程式碼、資料和快取大小"</string>
+    <string name="permlab_installPackages" msgid="2199128482820306924">"直接安裝應用程式"</string>
+    <string name="permdesc_installPackages" msgid="5628530972548071284">"允許應用程式安裝新的 Android 套件或進行更新。惡意應用程式可能會藉此新增具最高權限的應用程式。"</string>
+    <string name="permlab_clearAppCache" msgid="7487279391723526815">"刪除所有應用程式快取資料"</string>
+    <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"允許應用程式刪除其他應用程式快取目錄中的檔案,藉此騰出平板電腦的儲存空間。這可能會拖慢其他應用程式的啟動速度,因為它們必須重新擷取資料。"</string>
+    <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"允許應用程式刪除其他應用程式快取目錄中的檔案,藉此騰出手機的儲存空間。這可能會拖慢其他應用程式的啟動速度,因為它們必須重新擷取資料。"</string>
+    <string name="permlab_movePackage" msgid="3289890271645921411">"移動應用程式資源"</string>
+    <string name="permdesc_movePackage" msgid="319562217778244524">"允許應用程式將應用程式資源從內部媒體移到外部媒體,反之亦可。"</string>
+    <string name="permlab_readLogs" msgid="6615778543198967614">"讀取機密記錄資料"</string>
+    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"允許應用程式讀取系統的各種記錄檔案,這會允許應用程式查看平板電腦使用上的一般資訊,可能包含您的個人或私隱資訊。"</string>
+    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"允許應用程式讀取系統的各種記錄檔。這會允許應用程式查看一般的電話使用資訊,可能包括您的個人或私人資訊。"</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"使用任何媒體解碼器進行播放"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"允許應用程式使用任何已安裝的媒體解碼器為播放解碼。"</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"管理信任的憑證"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"允許應用程式安裝 CA 憑證為信任的憑證及解除安裝 CA 憑證。"</string>
+    <string name="permlab_diagnostic" msgid="8076743953908000342">"讀取/寫入由診斷應用程式擁有的資源"</string>
+    <string name="permdesc_diagnostic" msgid="6608295692002452283">"允許應用程式讀取及寫入診斷群組所擁有的任何資源 (例如:位於 /dev 中的檔案)。這可能會影響系統的穩定性及安全性,只應對製造商或網絡供應商所使用的硬件專用診斷程式開放這項權限。"</string>
+    <string name="permlab_changeComponentState" msgid="6335576775711095931">"啟用或停用應用程式元件"</string>
+    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"允許應用程式啟用或停用其他應用程式的元件。惡意應用程式可藉此停用平板電腦的重要功能。請謹慎授權,因為這可能會導致應用程式元件無法使用,造成不一致或不穩定的問題。"</string>
+    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"允許應用程式啟用或停用其他應用程式的元件。惡意應用程式可能會藉此停用重要的手機功能。這項權限可能導致應用程式元件無法使用、不一致或不穩定,因此請斟酌使用。"</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"授予或撤銷權限"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"允許應用程式授予或撤銷本身或其他應用程式的特定權限。惡意應用程式可能藉此存取您未授予權限的功能。"</string>
+    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"設定首選的應用程式"</string>
+    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"允許應用程式修改您喜好的應用程式。惡意應用程式可能會私自竄改執行的應用程式,或冒充現有的程式以收集您的私人資料。"</string>
+    <string name="permlab_writeSettings" msgid="2226195290955224730">"修改系統設定"</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"允許應用程式修改系統設定資料。惡意應用程式可能會毀壞系統設定。"</string>
+    <string name="permlab_writeSecureSettings" msgid="204676251876718288">"修改安全系統設定"</string>
+    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"允許應用程式修改系統安全設定資料 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_writeGservices" msgid="2149426664226152185">"修改 Google 服務地圖"</string>
+    <string name="permdesc_writeGservices" msgid="1287309437638380229">"允許應用程式修改 Google 服務地圖 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"啟動時執行"</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"允許應用程式在系統完成開機程序時立即自行啟動。這會加長平板電腦的開機時間,而且會因為系統一直執行該應用程式而拖慢平板電腦的整體運作速度。"</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="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="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="default" msgid="589869224625163558">"允許應用程式修改手機上儲存的聯絡人資料,包括您與個別聯絡人通話、電郵或以其他通訊方式聯絡的頻率。這項權限允許應用程式刪除聯絡人資料。"</string>
+    <string name="permlab_readCallLog" msgid="3478133184624102739">"讀取通話記錄"</string>
+    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"允許應用程式讀取平板電腦的通話記錄,包括來電和已撥電話相關資料。這項權限允許應用程式儲存您的通話記錄,而惡意應用程式也可能在您不知情下擅自共用通話記錄資料。"</string>
+    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"允許應用程式讀取手機的通話記錄,包括來電和已撥電話相關資料。這項權限允許應用程式儲存您的通話記錄,而惡意應用程式也可能在您不知情下擅自共用通話記錄資料。"</string>
+    <string name="permlab_writeCallLog" msgid="8552045664743499354">"寫入通話記錄"</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"允許應用程式修改平板電腦的通話記錄,包括來電和已撥電話相關資料。惡意應用程式可能會藉此刪除或修改您的通話記錄。"</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"允許應用程式修改手機的通話記錄,包括來電和已撥電話相關資料。惡意應用程式可能會藉此刪除或修改您的通話記錄。"</string>
+    <string name="permlab_readProfile" msgid="4701889852612716678">"讀取自己的聯絡資料"</string>
+    <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"允許應用程式讀取裝置上儲存的個人資料,例如您的姓名和聯絡資訊。這表示應用程式可以識別您的身份,並將您的個人資料傳送給他人。"</string>
+    <string name="permlab_writeProfile" msgid="907793628777397643">"修改自己的聯絡資料"</string>
+    <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"允許應用程式新增或更改裝置上儲存的個人資料,例如您的姓名和聯絡資訊。這表示應用程式可以識別您的身份,並將您的個人資料傳送給他人。"</string>
+    <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"讀取您的社交串流"</string>
+    <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"允許應用程式存取並同步處理您和好友的最新動態。當您分享資訊時,請務必小心,因為這項權限允許應用程式讀取您和好友在社交網絡上的私人通訊,不論是否機密。注意:這項權限可能不適用於所有社交網絡。"</string>
+    <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"寫入您的社交串流"</string>
+    <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"允許應用程式顯示好友的最新動態。當您分享資訊時,請務必小心,因為這項權限讓應用程式可偽裝好友產生訊息。注意:這項權限可能不適用於所有社交網絡。"</string>
+    <string name="permlab_readCalendar" msgid="5972727560257612398">"讀取日曆活動與機密資訊"</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"允許應用程式讀取平板電腦上儲存的所有日曆活動,包括好友或同事的活動。如此一來,應用程式或可不論資料是否機密或敏感,自行共用或儲存您的日曆資料。"</string>
+    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"允許應用程式讀取手機上儲存的所有日曆活動,包括好友或同事的活動。如此一來,應用程式或可不論資料是否機密或敏感,自行共用或儲存您的日曆資料。"</string>
+    <string name="permlab_writeCalendar" msgid="8438874755193825647">"在機主不知情下,新增或修改日曆活動,以及發送電郵給嘉賓"</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"允許應用程式新增、移除及更改您可以在平板電腦上修改的活動,包括好友或同事的活動。如此一來,應用程式或可偽裝日曆擁有者傳送訊息,或在擁有者不知情下擅自修改活動。"</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"允許應用程式新增、移除及更改您可以在手機上修改的活動,包括好友或同事的活動。如此一來,應用程式或可偽裝日曆擁有者傳送訊息,或在擁有者不知情下擅自修改活動。"</string>
+    <string name="permlab_accessMockLocation" msgid="8688334974036823330">"用於測試的模擬位置源"</string>
+    <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"建立虛構的位置資訊來源以供測試,或安裝新的位置資訊提供程式。這項權限允許應用程式覆寫 GPS 或位置資訊提供程式等其他位置資訊來源所傳回的位置資訊和/或狀態。"</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"接收額外的位置提供者指令"</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"允許應用程式存取額外位置資訊提供程式指令。如此一來,應用程式或可干擾 GPS 或其他位置資訊來源的運作。"</string>
+    <string name="permlab_installLocationProvider" msgid="6578101199825193873">"允許安裝位置提供程式"</string>
+    <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"建立虛構的位置資訊來源以供測試,或安裝新的位置資訊提供程式。這項權限允許應用程式覆寫 GPS 或位置資訊提供程式等其他位置資訊來源所傳回的位置資訊和/或狀態。"</string>
+    <string name="permlab_accessFineLocation" msgid="1191898061965273372">"精確位置 (以 GPS 和網絡為基準)"</string>
+    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"允許應用程式使用全球衛星定位系統 (GPS) 或網絡位置來源 (例如手機發射塔和 Wi-Fi) 取得您的精確位置。您必須在裝置上開啟這些位置服務供應用程式使用。應用程式可能藉此確定您所在的位置,也可能會耗用更多電量。"</string>
+    <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"約略位置 (以網絡為基準)"</string>
+    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"允許應用程式取得您的約略位置。這些位置資訊由位置服務使用網絡位置來源 (例如手機發射塔和 Wi-Fi) 取得。您必須在裝置上開啟這些位置服務供應用程式使用。應用程式可能藉此確定您的約略位置。"</string>
+    <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"存取 SurfaceFlinger"</string>
+    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"允許應用程式使用 SurfaceFlinger 的低層功能。"</string>
+    <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"讀取框架緩衝區"</string>
+    <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"允許應用程式讀取畫面緩衝區的內容。"</string>
+    <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"設定 WiFi Display"</string>
+    <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"允許應用程式設定及連接 WiFi Display。"</string>
+    <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"控制 WiFi Display"</string>
+    <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"允許應用程式控制 WiFi Display 的低階功能。"</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"擷取音頻輸出"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"允許應用程式擷取及重新導向音頻輸出。"</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"擷取視頻輸出"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"允許應用程式擷取及重新導向視頻輸出。"</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"擷取安全視頻輸出"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"允許應用程式擷取及重新導向安全視頻輸出。"</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="4906839301087980680">"允許應用程式使用麥克風錄音。這項權限允許應用程式隨時錄音,而不需經您確認。"</string>
+    <string name="permlab_camera" msgid="3616391919559751192">"拍照和拍攝影片"</string>
+    <string name="permdesc_camera" msgid="8497216524735535009">"允許應用程式使用相機拍照和錄影。這項權限允許應用程式隨時使用相機,而不需經您確認。"</string>
+    <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"使用相機時停用傳輸指示燈"</string>
+    <string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"允許預先安裝的系統應用程式停用相機指示燈。"</string>
+    <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"永久停用平板電腦"</string>
+    <string name="permlab_brick" product="default" msgid="8337817093326370537">"永久停用手機"</string>
+    <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"允許應用程式永久停用平板電腦所有功能 (這類權限具有高度風險)。"</string>
+    <string name="permdesc_brick" product="default" msgid="5788903297627283099">"允許應用程式永久停用手機所有功能 (這類權限具有高度風險)。"</string>
+    <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"強制重新啟動平板電腦"</string>
+    <string name="permlab_reboot" product="default" msgid="2898560872462638242">"強制手機重新開機"</string>
+    <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"允許應用程式強制重新啟動平板電腦。"</string>
+    <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"允許應用程式強制重新啟動手機。"</string>
+    <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"存取 USB 儲存裝置檔案系統"</string>
+    <string name="permlab_mount_unmount_filesystems" product="default" msgid="4402305049890953810">"存取 SD 記憶卡檔案系統"</string>
+    <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"允許應用程式掛接和卸載卸除式儲存裝置的檔案系統。"</string>
+    <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"清除 USB 儲存裝置資料"</string>
+    <string name="permlab_mount_format_filesystems" product="default" msgid="262582698639274056">"清除 SD 記憶卡資料"</string>
+    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"允許應用程式將可卸除式儲存裝置格式化。"</string>
+    <string name="permlab_asec_access" msgid="3411338632002193846">"取得內部儲存空間的資訊"</string>
+    <string name="permdesc_asec_access" msgid="3094563844593878548">"允許應用程式取得內部儲存空間的資訊。"</string>
+    <string name="permlab_asec_create" msgid="6414757234789336327">"建立內部儲存空間"</string>
+    <string name="permdesc_asec_create" msgid="4558869273585856876">"允許應用程式建立內部儲存空間。"</string>
+    <string name="permlab_asec_destroy" msgid="526928328301618022">"銷毀內部儲存空間"</string>
+    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"允許應用程式銷毀內部儲存空間。"</string>
+    <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"掛接/卸載內部儲存空間"</string>
+    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"允許應用程式掛接/卸載內部儲存空間。"</string>
+    <string name="permlab_asec_rename" msgid="7496633954080472417">"重新命名內部儲存空間"</string>
+    <string name="permdesc_asec_rename" msgid="1794757588472127675">"允許應用程式重新命名內部儲存空間。"</string>
+    <string name="permlab_vibrate" msgid="7696427026057705834">"控制震動"</string>
+    <string name="permdesc_vibrate" msgid="6284989245902300945">"允許應用程式控制震動。"</string>
+    <string name="permlab_flashlight" msgid="2155920810121984215">"控制閃光燈"</string>
+    <string name="permdesc_flashlight" msgid="6522284794568368310">"允許應用程式控制閃光燈。"</string>
+    <string name="permlab_manageUsb" msgid="1113453430645402723">"管理 USB 裝置的偏好設定和權限"</string>
+    <string name="permdesc_manageUsb" msgid="7776155430218239833">"允許應用程式管理 USB 裝置的喜好設定和權限。"</string>
+    <string name="permlab_accessMtp" msgid="4953468676795917042">"執行 MTP 通訊協定"</string>
+    <string name="permdesc_accessMtp" msgid="6532961200486791570">"允許存取核心 MTP 驅動程式,以執行 MTP USB 通訊協定。"</string>
+    <string name="permlab_hardware_test" msgid="4148290860400659146">"測試硬件"</string>
+    <string name="permdesc_hardware_test" msgid="6597964191208016605">"允許應用程式基於測試硬件的目的而控制各種周邊裝置。"</string>
+    <string name="permlab_callPhone" msgid="3925836347681847954">"直接撥打電話號碼"</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"允許應用程式繞過您自行撥打電話號碼,但可能會產生未預期的費用或撥打未預期的電話。注意:這項權限不允許應用程式撥打緊急電話。惡意應用程式可能未經您確認擅自撥打電話,增加您的支出。"</string>
+    <string name="permlab_callPrivileged" msgid="4198349211108497879">"直接撥打任何電話號碼"</string>
+    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"允許應用程式繞過用戶自行撥打任何電話號碼,包括緊急電話號碼。惡意應用程式可能會濫用緊急服務,撥打不必要或違法的電話。"</string>
+    <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"直接啟動 CDMA 平板電腦設定程序"</string>
+    <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"直接啟動 CDMA 手機設定程序"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"允許應用程式啟動 CDMA 佈建功能。惡意應用程式可能會在非必要的情況下啟動 CDMA 佈建功能。"</string>
+    <string name="permlab_locationUpdates" msgid="7785408253364335740">"控制位置更新通知"</string>
+    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"允許應用程式啟用/停用來自無線電的位置更新通知 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_checkinProperties" msgid="7855259461268734914">"存取登錄屬性"</string>
+    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"允許應用程式讀取/寫入由簽入服務上載的內容 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_bindGadget" msgid="776905339015863471">"選擇小工具"</string>
+    <string name="permdesc_bindGadget" msgid="8261326938599049290">"允許應用程式告知系統哪個應用程式可以使用哪些小工具。啟用這項權限後,應用程式即可讓其他應用程式使用個人資料 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"修改手機狀態"</string>
+    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"允許應用程式控制裝置上的電話功能。具備此權限的應用程式可在未通知您的情況下,進行切換網絡以及開關手機無線電之類的操作。"</string>
+    <string name="permlab_readPhoneState" msgid="9178228524507610486">"讀取手機狀態和識別碼"</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"允許應用程式使用裝置的電話功能。這項權限允許應用程式確定手機號碼和裝置編號、是否正在通話中,以及所撥打的對方號碼。"</string>
+    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"防止平板電腦進入休眠狀態"</string>
+    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"防止手機進入休眠狀態"</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"允許應用程式防止平板電腦進入休眠狀態。"</string>
+    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"允許應用程式防止手機進入休眠狀態。"</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
+    <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"開啟或關閉平板電腦"</string>
+    <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"開啟或關閉手機"</string>
+    <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"允許應用程式開啟或關閉平板電腦。"</string>
+    <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"允許應用程式開啟或關閉手機。"</string>
+    <string name="permlab_factoryTest" msgid="3715225492696416187">"以原廠測試模式執行"</string>
+    <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"允許在以低階製造商測試身分執行時,可具有平板電腦硬體的完整存取權限。只有在平板電腦以製造商測試模式執行時,才能使用此權限。"</string>
+    <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"以低階製造商測試執行,可具有手機硬件的完整存取權限。只有在手機以製造商測試模式執行時,才能使用此權限。"</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_masterClear" msgid="2315750423139697397">"將系統還原原廠預設值"</string>
+    <string name="permdesc_masterClear" msgid="3665380492633910226">"允許應用程式將系統完全恢復為原廠設定,因而清除所有資料、設定及安裝的應用程式。"</string>
+    <string name="permlab_setTime" msgid="2021614829591775646">"設定時間"</string>
+    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"允許應用程式更改平板電腦的時鐘時間。"</string>
+    <string name="permdesc_setTime" product="default" msgid="1855702730738020">"允許應用程式更改手機的時鐘時間。"</string>
+    <string name="permlab_setTimeZone" msgid="2945079801013077340">"設定時區"</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"允許應用程式更改平板電腦的時區。"</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"允許應用程式更改手機的時區。"</string>
+    <string name="permlab_accountManagerService" msgid="4829262349691386986">"作為 AccountManagerService"</string>
+    <string name="permdesc_accountManagerService" msgid="1948455552333615954">"允許應用程式調用 AccountAuthenticators。"</string>
+    <string name="permlab_getAccounts" msgid="1086795467760122114">"找出裝置上的帳戶"</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"允許應用程式取得平板電腦已知的帳戶清單,其中可能包括您安裝的應用程式所建立的任何帳戶。"</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"允許應用程式取得手機已知的帳戶清單,其中可能包括您安裝的應用程式所建立的任何帳戶。"</string>
+    <string name="permlab_authenticateAccounts" msgid="5265908481172736933">"建立帳戶及設定密碼"</string>
+    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"允許應用程式使用 AccountManager 的帳戶認證功能,包括建立帳戶、取得帳戶密碼以及設定帳戶密碼。"</string>
+    <string name="permlab_manageAccounts" msgid="4983126304757177305">"新增或移除帳戶"</string>
+    <string name="permdesc_manageAccounts" msgid="8698295625488292506">"允許應用程式執行新增、移除帳戶和刪除密碼等操作。"</string>
+    <string name="permlab_useCredentials" msgid="235481396163877642">"使用裝置上的帳戶"</string>
+    <string name="permdesc_useCredentials" msgid="7984227147403346422">"允許應用程式要求認證憑證。"</string>
+    <string name="permlab_accessNetworkState" msgid="4951027964348974773">"查看網絡連線"</string>
+    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"允許應用程式查看網絡連線相關資訊,例如有哪些網絡和已連接哪些網絡。"</string>
+    <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"全面網絡存取權"</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"允許應用程式建立網絡通訊端及使用自訂的網絡通訊協定。瀏覽器和其他應用程式提供傳送資料至互聯網的途徑,因此不需要這項權限來傳送資料至互聯網。"</string>
+    <string name="permlab_writeApnSettings" msgid="505660159675751896">"更改/攔截網絡設定和流量"</string>
+    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"允許應用程式更改網絡設定,並且攔截和檢查所有網絡流量,例如更改任何 APN 的 Proxy 及通訊埠。惡意應用程式可能會在您不知情的情況下,監視、重新導向或修改網絡封包。"</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_changeBackgroundDataSetting" msgid="1400666012671648741">"更改背景資料使用設定"</string>
+    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"允許應用程式更改背景數據用量設定。"</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="default" msgid="6851949706025349926">"允許應用程式接收透過多點傳播位址傳送給 Wi-Fi 網絡上所有裝置 (而不只是傳送給您的手機) 的封包。這樣會比非多點傳播模式耗用更多電力。"</string>
+    <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"存取藍牙設定"</string>
+    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"允許應用程式設定本機藍牙平板電腦,以及與偵測到的遠端裝置配對。"</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="2405042267131496579">"更改 WiMAX 狀態"</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"允許應用程式建立或中斷平板電腦與 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="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_readSyncSettings" msgid="6201810008230503052">"讀取同步處理設定"</string>
+    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"允許應用程式讀取帳戶的同步設定,例如確定「通訊錄」應用程式是否和某個帳戶保持同步。"</string>
+    <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"開啟和關閉同步功能"</string>
+    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"允許應用程式修改帳戶的同步設定,例如讓「通訊錄」應用程式與某個帳戶保持同步。"</string>
+    <string name="permlab_readSyncStats" msgid="7396577451360202448">"讀取同步處理統計資料"</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"允許應用程式讀取帳戶的同步統計資料,包括同步活動記錄,以及保持同步的資料量。"</string>
+    <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"讀取訂閱的資訊提供"</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"允許應用程式取得目前已同步的資訊提供的詳細資料。"</string>
+    <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"寫入訂閱的資訊提供"</string>
+    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"允許應用程式修改目前已同步的資訊提供。惡意應用程式可能會更改已同步的資訊提供。"</string>
+    <string name="permlab_readDictionary" msgid="4107101525746035718">"讀取加入字典中的字詞"</string>
+    <string name="permdesc_readDictionary" msgid="659614600338904243">"允許應用程式讀取用戶儲存在用戶字典中的所有字詞、名稱和詞組。"</string>
+    <string name="permlab_writeDictionary" msgid="2183110402314441106">"將字詞加入用戶定義字典"</string>
+    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"允許應用程式將新字詞寫入用戶字典。"</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"測試能否存取受保護的儲存裝置"</string>
+    <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"測試能否存取受保護的儲存裝置"</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"允許應用程式測試未來裝置將支援的 USB 儲存權限。"</string>
+    <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"允許應用程式測試未來裝置將支援的 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_mediaStorageWrite" product="default" msgid="6859839199706879015">"修改/刪除內部媒體儲存裝置內容"</string>
+    <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"允許應用程式修改內部媒體儲存空間的內容。"</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"管理文件儲存"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"允許應用程式管理文件儲存。"</string>
+    <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"存取外部儲存空間 (所有用戶)"</string>
+    <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"允許應用程式存取外部儲存空間 (所有用戶)。"</string>
+    <string name="permlab_cache_filesystem" msgid="5656487264819669824">"存取快取檔案系統"</string>
+    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"允許應用程式讀取及寫入快取檔案系統。"</string>
+    <string name="permlab_use_sip" msgid="5986952362795870502">"撥打/接聽網絡電話"</string>
+    <string name="permdesc_use_sip" msgid="4717632000062674294">"允許應用程式使用 SIP 服務撥打/接聽網絡電話。"</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_markNetworkSocket" msgid="3658527214914959749">"修改通訊端標記"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"允許應用程式修改路由的通訊端標記"</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_invokeCarrierSetup" msgid="3699600833975117478">"調用流動網絡供應商提供的設定應用程式"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"允許應用程式調用流動網絡供應商提供的設定應用程式 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"監聽對網絡狀況的觀察"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"允許應用程式監聽對網絡狀況的觀察 (不建議一般應用程式使用)。"</string>
+    <string name="policylab_limitPassword" msgid="4497420728857585791">"設定密碼規則"</string>
+    <string name="policydesc_limitPassword" msgid="3252114203919510394">"控制屏幕解鎖密碼所允許的長度和字元。"</string>
+    <string name="policylab_watchLogin" msgid="914130646942199503">"監控屏幕解鎖嘗試次數"</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"監視為屏幕解鎖時輸入錯誤密碼的次數;如果輸入錯誤密碼的次數過多,則會鎖定平板電腦或清除平板電腦的所有資料。"</string>
+    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"監視為屏幕解鎖時輸入錯誤密碼的次數,如果輸入錯誤密碼的次數過多,則會鎖定手機或清除手機的所有資料。"</string>
+    <string name="policylab_resetPassword" msgid="2620077191242688955">"更改屏幕解鎖密碼"</string>
+    <string name="policydesc_resetPassword" msgid="605963962301904458">"更改屏幕解鎖密碼。"</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="default" msgid="5096895604574188391">"重設手機為原廠設定,在不提出警告的情況下直接清除手機的資料。"</string>
+    <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"設定裝置的全域代理伺服器"</string>
+    <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"設定政策啟用時所要使用的裝置全域代理伺服器,只有第一個裝置管理員所設定的全域代理伺服器具有效力。"</string>
+    <string name="policylab_expirePassword" msgid="885279151847254056">"設定螢幕上鎖密碼到期日"</string>
+    <string name="policydesc_expirePassword" msgid="1729725226314691591">"控制屏幕上鎖密碼的更改頻率。"</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="policylab_disableKeyguardFeatures" msgid="266329104542638802">"停用鍵盤保護框上的功能"</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="3467082272186534614">"禁止使用鍵盤保護框上的部分功能。"</string>
+  <string-array name="phoneTypes">
+    <item msgid="8901098336658710359">"首頁"</item>
+    <item msgid="869923650527136615">"手機"</item>
+    <item msgid="7897544654242874543">"工作"</item>
+    <item msgid="1103601433382158155">"公司傳真"</item>
+    <item msgid="1735177144948329370">"住宅傳真"</item>
+    <item msgid="603878674477207394">"傳呼機"</item>
+    <item msgid="1650824275177931637">"其他"</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>
+  </string-array>
+  <string-array name="postalAddressTypes">
+    <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="1359644565647383708">"工作"</item>
+    <item msgid="7868549401053615677">"其他"</item>
+    <item msgid="3145118944639869809">"自訂"</item>
+  </string-array>
+  <string-array name="organizationTypes">
+    <item msgid="7546335612189115615">"工作"</item>
+    <item msgid="4378074129049520373">"其他"</item>
+    <item msgid="3455047468583965104">"自訂"</item>
+  </string-array>
+  <string-array name="imProtocols">
+    <item msgid="8595261363518459565">"AIM"</item>
+    <item msgid="7390473628275490700">"Windows Live"</item>
+    <item msgid="7882877134931458217">"Yahoo"</item>
+    <item msgid="5035376313200585242">"Skype"</item>
+    <item msgid="7532363178459444943">"QQ"</item>
+    <item msgid="3713441034299660749">"Google Talk"</item>
+    <item msgid="2506857312718630823">"ICQ"</item>
+    <item msgid="1648797903785279353">"Jabber"</item>
+  </string-array>
+    <string name="phoneTypeCustom" msgid="1644738059053355820">"自訂"</string>
+    <string name="phoneTypeHome" msgid="2570923463033985887">"首頁"</string>
+    <string name="phoneTypeMobile" msgid="6501463557754751037">"手機"</string>
+    <string name="phoneTypeWork" msgid="8863939667059911633">"工作"</string>
+    <string name="phoneTypeFaxWork" msgid="3517792160008890912">"公司傳真"</string>
+    <string name="phoneTypeFaxHome" msgid="2067265972322971467">"住宅傳真"</string>
+    <string name="phoneTypePager" msgid="7582359955394921732">"傳呼機"</string>
+    <string name="phoneTypeOther" msgid="1544425847868765990">"其他"</string>
+    <string name="phoneTypeCallback" msgid="2712175203065678206">"回撥電話"</string>
+    <string name="phoneTypeCar" msgid="8738360689616716982">"車用電話"</string>
+    <string name="phoneTypeCompanyMain" msgid="540434356461478916">"公司主機"</string>
+    <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string>
+    <string name="phoneTypeMain" msgid="6766137010628326916">"主要電話"</string>
+    <string name="phoneTypeOtherFax" msgid="8587657145072446565">"其他傳真"</string>
+    <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="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="eventTypeBirthday" msgid="2813379844211390740">"生日"</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>
+    <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="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="imTypeWork" msgid="1371489290242433090">"工作"</string>
+    <string name="imTypeOther" msgid="5377007495735915478">"其他"</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>
+    <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
+    <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</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>
+    <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="relationTypeAssistant" msgid="6274334825195379076">"助理"</string>
+    <string name="relationTypeBrother" msgid="8757913506784067713">"兄弟"</string>
+    <string name="relationTypeChild" msgid="1890746277276881626">"子女"</string>
+    <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"同居伴侶"</string>
+    <string name="relationTypeFather" msgid="5228034687082050725">"父親"</string>
+    <string name="relationTypeFriend" msgid="7313106762483391262">"朋友"</string>
+    <string name="relationTypeManager" msgid="6365677861610137895">"管理員"</string>
+    <string name="relationTypeMother" msgid="4578571352962758304">"母親"</string>
+    <string name="relationTypeParent" msgid="4755635567562925226">"父母"</string>
+    <string name="relationTypePartner" msgid="7266490285120262781">"夥伴"</string>
+    <string name="relationTypeReferredBy" msgid="101573059844135524">"介紹人"</string>
+    <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="sipAddressTypeHome" msgid="6093598181069359295">"家用"</string>
+    <string name="sipAddressTypeWork" msgid="6920725730797099047">"工作"</string>
+    <string name="sipAddressTypeOther" msgid="4408436162950119849">"其他"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"輸入 PIN 碼"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"輸入 PUK 碼和新 PIN 碼"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK 碼"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"新 PIN 碼"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><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">"輸入 PIN 碼即可解鎖"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PIN 碼不正確。"</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="8963839242565653192">"沒有服務。"</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="5347633784401285225">"緊急電話"</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="faceunlock_multiple_failures" msgid="754137583022792429">"已超過臉容解鎖嘗試次數上限"</string>
+    <string name="lockscreen_plugged_in" msgid="8057762828355572315">"充電中 (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
+    <string name="lockscreen_charged" msgid="321635745684060624">"充電完成"</string>
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="lockscreen_low_battery" msgid="1482873981919249740">"請連接充電器。"</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="default" msgid="2186920585695169078">"手機中沒有 SIM 卡。"</string>
+    <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"請插入 SIM 卡。"</string>
+    <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"找不到 SIM 卡或無法讀取 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_transport_prev_description" msgid="201594905152746886">"[上一首曲目] 按鈕"</string>
+    <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"[下一首曲目] 按鈕"</string>
+    <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"[暫停] 按鈕"</string>
+    <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"[播放] 按鈕"</string>
+    <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"[停止] 按鈕"</string>
+    <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">"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">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"您已輸入錯誤的密碼 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"您已輸入錯誤的 PIN 碼 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統會要求您使用您的 Google 登入資料解開上鎖的平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統會要求您使用您的 Google 登入資料解開上鎖的手機。\n\n請在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"您嘗試解除這部平板電腦的鎖定已失敗 <xliff:g id="NUMBER_0">%d</xliff:g> 次,剩餘 <xliff:g id="NUMBER_1">%d</xliff:g> 次嘗試機會。如果失敗次數超過嘗試次數限制,平板電腦將恢復原廠設定,所有用戶資料均會遺失。"</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"您嘗試解除這部手機的鎖定已失敗 <xliff:g id="NUMBER_0">%d</xliff:g> 次,剩餘 <xliff:g id="NUMBER_1">%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="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_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_checking_password" msgid="7114627351286933867">"正在檢查..."</string>
+    <string name="lockscreen_unlock_label" msgid="737440483220667054">"解除鎖定"</string>
+    <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"開啟音效"</string>
+    <string name="lockscreen_sound_off_label" msgid="996822825154319026">"關閉音效"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"已開始繪畫解鎖圖案"</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"已清除解鎖圖案"</string>
+    <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"已加入一格"</string>
+    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"已畫出解鎖圖案"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s。第 %2$d 個小工具,共 %3$d 個。"</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_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>
+    <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_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">"PIN 解鎖。"</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>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <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_line" msgid="5764267235026120888">"行"</string>
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
+    <string name="factorytest_failed" msgid="5410270329114212041">"原廠測試失敗"</string>
+    <string name="factorytest_not_system" msgid="4435201656767276723">"只有安裝在 /system/app 裡的程式套件才能支援 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="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>
+    <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
+    <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
+    <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
+    <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
+    <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_county" msgid="237073771020362891">"郡"</string>
+    <string name="autofill_island" msgid="4020100875984667025">"島"</string>
+    <string name="autofill_district" msgid="8400735073392267672">"地區"</string>
+    <string name="autofill_department" msgid="5343279462564453309">"部門"</string>
+    <string name="autofill_prefecture" msgid="2028499485065800419">"都/道/府/縣"</string>
+    <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">"允許應用程式讀取瀏覽器到訪過的所有網址記錄,以及瀏覽器的所有書籤。注意:這項權限可能不適用於第三方瀏覽器或其他具備網頁瀏覽功能的應用程式。"</string>
+    <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"寫入網上書籤和記錄"</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"允許應用程式修改平板電腦上儲存的瀏覽器記錄或書籤。如此一來,應用程式或可清除或修改瀏覽器資料。注意:這項權限可能不適用於第三方瀏覽器或其他具備網頁瀏覽功能的應用程式。"</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_packageVerificationAgent" msgid="5568139100645829117">"驗證套件"</string>
+    <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"允許應用程式驗證套件是否可安裝。"</string>
+    <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"繫結至套件驗證程序"</string>
+    <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"允許應用程式要求驗證套件 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_serialPort" msgid="546083327654631076">"接入串列通訊埠"</string>
+    <string name="permdesc_serialPort" msgid="2991639985224598193">"允許應用程式使用 SerialManager API 接入串列通訊埠。"</string>
+    <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"從外部存取內容供應商"</string>
+    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"允許應用程式透過命令介面存取內容供應商 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_updateLock" msgid="3527558366616680889">"不建議自動更新裝置"</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"允許應用程式提供資訊,以建議系統何時適合以非互動方式重新啟動並升級裝置。"</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>
+    <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="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="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="oneMonthDurationPast" msgid="7396384508953779925">"1 個月前"</string>
+    <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"1 個月前"</string>
+  <plurals name="num_seconds_ago">
+    <item quantity="one" msgid="4869870056547896011">"1 秒前"</item>
+    <item quantity="other" msgid="3903706804349556379">"<xliff:g id="COUNT">%d</xliff:g> 秒前"</item>
+  </plurals>
+  <plurals name="num_minutes_ago">
+    <item quantity="one" msgid="3306787433088810191">"1 分鐘前"</item>
+    <item quantity="other" msgid="2176942008915455116">"<xliff:g id="COUNT">%d</xliff:g> 分鐘前"</item>
+  </plurals>
+  <plurals name="num_hours_ago">
+    <item quantity="one" msgid="9150797944610821849">"1 小時前"</item>
+    <item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> 小時前"</item>
+  </plurals>
+  <plurals name="last_num_days">
+    <item quantity="other" msgid="3069992808164318268">"最近 <xliff:g id="COUNT">%d</xliff:g> 天"</item>
+  </plurals>
+    <string name="last_month" msgid="3959346739979055432">"上個月"</string>
+    <string name="older" msgid="5211975022815554840">"較舊"</string>
+  <plurals name="num_days_ago">
+    <item quantity="one" msgid="861358534398115820">"昨天"</item>
+    <item quantity="other" msgid="2479586466153314633">"<xliff:g id="COUNT">%d</xliff:g> 天前"</item>
+  </plurals>
+  <plurals name="in_num_seconds">
+    <item quantity="one" msgid="2729745560954905102">"1 秒後"</item>
+    <item quantity="other" msgid="1241926116443974687">"<xliff:g id="COUNT">%d</xliff:g> 秒後"</item>
+  </plurals>
+  <plurals name="in_num_minutes">
+    <item quantity="one" msgid="8793095251325200395">"1 分鐘後"</item>
+    <item quantity="other" msgid="3330713936399448749">"<xliff:g id="COUNT">%d</xliff:g> 分鐘後"</item>
+  </plurals>
+  <plurals name="in_num_hours">
+    <item quantity="one" msgid="7164353342477769999">"1 小時後"</item>
+    <item quantity="other" msgid="547290677353727389">"<xliff:g id="COUNT">%d</xliff:g> 小時後"</item>
+  </plurals>
+  <plurals name="in_num_days">
+    <item quantity="one" msgid="5413088743009839518">"明天"</item>
+    <item quantity="other" msgid="5109449375100953247">"<xliff:g id="COUNT">%d</xliff:g> 天後"</item>
+  </plurals>
+  <plurals name="abbrev_num_seconds_ago">
+    <item quantity="one" msgid="1849036840200069118">"1 秒前"</item>
+    <item quantity="other" msgid="3699169366650930415">"<xliff:g id="COUNT">%d</xliff:g> 秒前"</item>
+  </plurals>
+  <plurals name="abbrev_num_minutes_ago">
+    <item quantity="one" msgid="6361490147113871545">"1 分鐘前"</item>
+    <item quantity="other" msgid="851164968597150710">"<xliff:g id="COUNT">%d</xliff:g> 分鐘前"</item>
+  </plurals>
+  <plurals name="abbrev_num_hours_ago">
+    <item quantity="one" msgid="4796212039724722116">"1 小時前"</item>
+    <item quantity="other" msgid="6889970745748538901">"<xliff:g id="COUNT">%d</xliff:g> 小時前"</item>
+  </plurals>
+  <plurals name="abbrev_num_days_ago">
+    <item quantity="one" msgid="8463161711492680309">"昨天"</item>
+    <item quantity="other" msgid="3453342639616481191">"<xliff:g id="COUNT">%d</xliff:g> 天前"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_seconds">
+    <item quantity="one" msgid="5842225370795066299">"1 秒後"</item>
+    <item quantity="other" msgid="5495880108825805108">"<xliff:g id="COUNT">%d</xliff:g> 秒後"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_minutes">
+    <item quantity="one" msgid="562786149928284878">"1 分鐘後"</item>
+    <item quantity="other" msgid="4216113292706568726">"<xliff:g id="COUNT">%d</xliff:g> 分鐘後"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_hours">
+    <item quantity="one" msgid="3274708118124045246">"1 小時後"</item>
+    <item quantity="other" msgid="3705373766798013406">"<xliff:g id="COUNT">%d</xliff:g> 小時後"</item>
+  </plurals>
+  <plurals name="abbrev_in_num_days">
+    <item quantity="one" msgid="2178576254385739855">"明天"</item>
+    <item quantity="other" msgid="2973062968038355991">"<xliff:g id="COUNT">%d</xliff:g> 天後"</item>
+  </plurals>
+    <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>
+    <string name="days" msgid="4774547661021344602">"天"</string>
+    <string name="hour" msgid="2126771916426189481">"小時"</string>
+    <string name="hours" msgid="894424005266852993">"小時"</string>
+    <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="week" msgid="5617961537173061583">"星期"</string>
+    <string name="weeks" msgid="6509623834583944518">"星期"</string>
+    <string name="year" msgid="4001118221013892076">"YEAR"</string>
+    <string name="years" msgid="6881577717993213522">"年"</string>
+  <plurals name="duration_seconds">
+    <item quantity="one" msgid="6962015528372969481">"1 秒"</item>
+    <item quantity="other" msgid="1886107766577166786">"<xliff:g id="COUNT">%d</xliff:g> 秒"</item>
+  </plurals>
+  <plurals name="duration_minutes">
+    <item quantity="one" msgid="4915414002546085617">"1 分鐘"</item>
+    <item quantity="other" msgid="3165187169224908775">"<xliff:g id="COUNT">%d</xliff:g> 分鐘"</item>
+  </plurals>
+  <plurals name="duration_hours">
+    <item quantity="one" msgid="8917467491248809972">"1 小時"</item>
+    <item quantity="other" msgid="3863962854246773930">"<xliff:g id="COUNT">%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_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>
+    <string name="midnight" msgid="7166259508850457595">"午夜"</string>
+    <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="cut" msgid="3092569408438626261">"剪下"</string>
+    <string name="copy" msgid="2681946229533511987">"複製"</string>
+    <string name="paste" msgid="5629880836805036433">"貼上"</string>
+    <string name="replace" msgid="5781686059063148930">"取代..."</string>
+    <string name="delete" msgid="6098684844021697789">"刪除"</string>
+    <string name="copyUrl" msgid="2538211579596067402">"複製網址"</string>
+    <string name="selectTextMode" msgid="1018691815143165326">"選取文字"</string>
+    <string name="textSelectionCABTitle" msgid="5236850394370820357">"選取文字"</string>
+    <string name="addToDictionary" msgid="4352161534510057874">"加入字典"</string>
+    <string name="deleteText" msgid="6979668428458199034">"刪除"</string>
+    <string name="inputMethod" msgid="1653630062304567879">"輸入法"</string>
+    <string name="editTextMenuTitle" msgid="4909135564941815494">"文字操作"</string>
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"儲存空間即將用盡"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"部分系統功能可能無法運作"</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="4653586947747330058">"輕觸即可瞭解詳情或停止應用程式。"</string>
+    <string name="ok" msgid="5970060430562524910">"確定"</string>
+    <string name="cancel" msgid="6442560571259935130">"取消"</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>
+    <string name="capital_on" msgid="1544682755514494298">"開啟"</string>
+    <string name="capital_off" msgid="6815870386972805832">"關"</string>
+    <string name="whichApplication" msgid="4533185947064773386">"完成操作需使用"</string>
+    <string name="alwaysUse" msgid="4583018368000610438">"設定用於執行這項操作。"</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="aerr_title" msgid="1905800560317137752"></string>
+    <string name="aerr_application" msgid="932628488013092776">"很抱歉,<xliff:g id="APPLICATION">%1$s</xliff:g> 已停止。"</string>
+    <string name="aerr_process" msgid="4507058997035697579">"很抱歉,處理程序 <xliff:g id="PROCESS">%1$s</xliff:g> 已停止。"</string>
+    <string name="anr_title" msgid="4351948481459135709"></string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> 沒有回應。\n\n您要結束嗎?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"活動 <xliff:g id="ACTIVITY">%1$s</xliff:g> 沒有回應。\n\n您要結束嗎?"</string>
+    <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> 沒有回應。您要結束嗎?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"處理程序 <xliff:g id="PROCESS">%1$s</xliff:g> 沒有回應。\n\n您要結束嗎?"</string>
+    <string name="force_close" msgid="8346072094521265605">"確定"</string>
+    <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_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; [應用程式] &gt; [下載] 重新啟用這個模式。"</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>
+    <string name="android_upgrading_title" msgid="1584192285441405746">"正在升級 Android..."</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_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="1721681741617898865">"輕觸即可切換應用程式"</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>
+    <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="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_silent_ringtone_selected" msgid="8310739960973156272">"已將鈴聲設定為靜音"</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">"藍牙音量"</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="8129563480895990372">"預設鈴聲 (<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_unknown" msgid="5477919988701784788">"不明鈴聲"</string>
+  <plurals name="wifi_available">
+    <item quantity="one" msgid="6654123987418168693">"有 Wi-Fi 網絡可以連接"</item>
+    <item quantity="other" msgid="4192424489168397386">"有 Wi-Fi 網絡可以連接"</item>
+  </plurals>
+  <plurals name="wifi_available_detailed">
+    <item quantity="one" msgid="1634101450343277345">"有公開的 Wi-Fi 網絡可以連接"</item>
+    <item quantity="other" msgid="7915895323644292768">"有公開的 Wi-Fi 網絡可以連接"</item>
+  </plurals>
+    <string name="wifi_available_sign_in" msgid="4029489716605255386">"登入 Wi-Fi 網絡"</string>
+    <string name="network_available_sign_in" msgid="8495155593358054676">"登入網絡"</string>
+    <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
+    <skip />
+    <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"無法連線至 Wi-Fi"</string>
+    <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" 互聯網連線欠佳。"</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_enabled_notification_message" msgid="1638949953993894335">"輕觸進行設定"</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_to_connect_title" msgid="4958803948658533637">"連線邀請"</string>
+    <string name="wifi_p2p_from_message" msgid="570389174731951769">"寄件者:"</string>
+    <string name="wifi_p2p_to_message" msgid="248968974522044099">"收件者:"</string>
+    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"請輸入必要的 PIN 碼:"</string>
+    <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN 碼:"</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="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;正在傳送大量短訊。您要允許這個應用程式繼續傳送短訊嗎?"</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="3492025719868078457">"這"<font fgcolor="#ffffb060">"可能將收費計入"</font>"您的流動服務帳戶中。"</string>
+    <string name="sms_premium_short_code_details" msgid="5523826349105123687"><font fgcolor="#ffffb060">"這會將收費計入您的流動服務帳戶中。"</font></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_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_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="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_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="usb_storage_activity_title" msgid="4465055157209648641">"USB 大量儲存裝置"</string>
+    <string name="usb_storage_title" msgid="5901459041398751495">"已連接 USB"</string>
+    <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"您已透過 USB 連接電腦。如要在電腦和 Android 手機的 USB 儲存裝置之間複製檔案,請輕觸下方的按鈕。"</string>
+    <string name="usb_storage_message" product="default" msgid="805351000446037811">"您已透過 USB 連接電腦。如要在電腦和 Android 手機的 SD 記憶卡之間複製檔案,請輕觸下方的按鈕。"</string>
+    <string name="usb_storage_button_mount" msgid="1052259930369508235">"開啟 USB 儲存裝置"</string>
+    <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"使用您的 USB 儲存裝置作為 USB 大量儲存裝置時發生問題。"</string>
+    <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"使用您的 SD 記憶卡作為 USB 大量儲存裝置時發生問題。"</string>
+    <string name="usb_storage_notification_title" msgid="8175892554757216525">"已連接 USB"</string>
+    <string name="usb_storage_notification_message" msgid="939822783828183763">"輕觸即可將檔案複製到電腦或從電腦複製。"</string>
+    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"關閉 USB 儲存裝置"</string>
+    <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"輕觸即可關閉 USB 儲存裝置。"</string>
+    <string name="usb_storage_stop_title" msgid="660129851708775853">"USB 儲存裝置正在使用中"</string>
+    <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"關閉 USB 儲存裝置前,請先從電腦卸載 (退出) Android 手機的 USB 儲存裝置。"</string>
+    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"關閉 USB 儲存裝置前,請先從電腦卸載 (退出) Android 手機的 SD 記憶卡。"</string>
+    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"關閉 USB 儲存裝置"</string>
+    <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"關閉 USB 儲存裝置時發生問題。請檢查您是否已卸載 USB Host,然後再試一次。"</string>
+    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"開啟 USB 儲存裝置"</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"如果您開啟 USB 儲存裝置,則某些正在使用中的應用程式會停止運作,而且可能無法使用,直到關閉 USB 儲存裝置後才會恢復正常。"</string>
+    <string name="dlg_error_title" msgid="7323658469626514207">"USB 操作失敗"</string>
+    <string name="dlg_ok" msgid="7376953167039865701">"確定"</string>
+    <string name="usb_mtp_notification_title" msgid="3699913097391550394">"已作為媒體裝置連線"</string>
+    <string name="usb_ptp_notification_title" msgid="1960817192216064833">"已作為相機連線"</string>
+    <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"已作為安裝程式連線"</string>
+    <string name="usb_accessory_notification_title" msgid="7848236974087653666">"已連接到一個 USB 配件"</string>
+    <string name="usb_notification_message" msgid="2290859399983720271">"輕觸即可顯示其他 USB 選項。"</string>
+    <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"格式化 USB 儲存裝置?"</string>
+    <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"格式化 SD 記憶卡?"</string>
+    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"即將清除所有儲存在 USB 儲存裝置上的檔案。這項操作無法復原!"</string>
+    <string name="extmedia_format_message" product="default" msgid="14131895027543830">"儲存卡上的所有資料將會失去。"</string>
+    <string name="extmedia_format_button_format" msgid="4131064560127478695">"格式"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"已連接 USB 偵錯工具"</string>
+    <string name="adb_active_notification_message" msgid="1016654627626476142">"輕觸即可停用 USB 偵錯。"</string>
+    <string name="select_input_method" msgid="4653387336791222978">"選擇輸入法"</string>
+    <string name="configure_input_methods" msgid="9091652157722495116">"設定輸入方式"</string>
+    <string name="use_physical_keyboard" msgid="6203112478095117625">"實體鍵盤"</string>
+    <string name="hardware" msgid="7517821086888990278">"硬件"</string>
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"選取鍵盤配置"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"輕觸即可選取鍵盤配置。"</string>
+    <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="candidates_style" msgid="4333913089637062257"><u>"待選項目"</u></string>
+    <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"正在準備 USB 儲存裝置"</string>
+    <string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"正在準備 SD 卡"</string>
+    <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"正在檢查錯誤。"</string>
+    <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"USB 儲存裝置無內容"</string>
+    <string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"SD 卡為空白"</string>
+    <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"USB 儲存裝置空白,或使用不受支援的檔案系統。"</string>
+    <string name="ext_media_nofs_notification_message" product="default" msgid="8641065641786923604">"SD 記憶卡空白,或使用不受支援的檔案系統。"</string>
+    <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"USB 儲存裝置已損壞"</string>
+    <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"SD 卡已損壞"</string>
+    <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="1795917578395333280">"USB 儲存裝置已損壞。請嘗試將儲存裝置重新格式化。"</string>
+    <string name="ext_media_unmountable_notification_message" product="default" msgid="1753898567525568253">"SD 記憶卡已損壞。請嘗試將記憶卡重新格式化。"</string>
+    <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"USB 儲存裝置未正常移除"</string>
+    <string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"SD 卡突然遭移除"</string>
+    <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"請先卸載 USB 儲存裝置,再將其移除,以免資料遺失。"</string>
+    <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"請先卸載 SD 卡,再將其移除,以免資料遺失。"</string>
+    <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"現在可安全移除 USB 儲存裝置"</string>
+    <string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"可安全移除 SD 卡"</string>
+    <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"您現在可以安全移除 USB 儲存裝置。"</string>
+    <string name="ext_media_safe_unmount_notification_message" product="default" msgid="568841278138377604">"您現在可以安全地移除 SD 卡。"</string>
+    <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"USB 儲存裝置已移除"</string>
+    <string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"已移除 SD 卡"</string>
+    <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"USB 儲存裝置已移除,請插入新媒體。"</string>
+    <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"SD 卡已移除,請插入新的 SD 卡。"</string>
+    <string name="activity_list_empty" msgid="1675388330786841066">"找不到相符的活動。"</string>
+    <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"更新元件使用統計資料"</string>
+    <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"允許應用程式修改收集到的元件使用統計資料 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_copyProtectedData" msgid="4341036311211406692">"複製內容"</string>
+    <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"允許應用程式觸發預設容器服務,以便複製內容 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_route_media_output" msgid="1642024455750414694">"轉送媒體輸出"</string>
+    <string name="permdesc_route_media_output" msgid="4932818749547244346">"允許應用程式將媒體輸出轉送至其他外部裝置。"</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"存取 Keyguard 安全儲存空間"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"允許應用程式存取 Keyguard 安全儲存空間。"</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"控制顯示或隱藏鍵盤鎖"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"允許應用程式控制鍵盤鎖。"</string>
+    <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"輕觸兩下即可控制縮放"</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>
+    <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_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="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>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"變更桌布"</string>
+    <string name="notification_listener_binding_label" msgid="2014162835481906429">"通知接聽器"</string>
+    <string name="vpn_title" msgid="19615213552042827">"VPN 已啟用。"</string>
+    <string name="vpn_title_long" msgid="6400714798049252294">"<xliff:g id="APP">%s</xliff:g> 已啟用 VPN"</string>
+    <string name="vpn_text" msgid="3011306607126450322">"輕觸即可管理網絡。"</string>
+    <string name="vpn_text_long" msgid="6407351006249174473">"已連線至 <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_error" msgid="6009249814034708175">"永久連線的 VPN 發生錯誤"</string>
+    <string name="vpn_lockdown_config" msgid="6415899150671537970">"輕觸以設定"</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="8035230537563503262">"輕觸即可結束車用模式。"</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"網絡共用或無線基地台已啟用"</string>
+    <string name="tethered_notification_message" msgid="6857031760103062982">"輕觸即可設定。"</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="throttle_warning_notification_title" msgid="4890894267454867276">"高流動數據用量"</string>
+    <string name="throttle_warning_notification_message" msgid="3340822228599337743">"輕觸即可瞭解流動數據用量的詳情。"</string>
+    <string name="throttled_notification_title" msgid="6269541897729781332">"已達流動數據上限"</string>
+    <string name="throttled_notification_message" msgid="5443457321354907181">"輕觸即可瞭解流動數據用量的詳情。"</string>
+    <string name="no_matches" msgid="8129421908915840737">"沒有相符的結果"</string>
+    <string name="find_on_page" msgid="1946799233822820384">"在頁面中尋找"</string>
+  <plurals name="matches_found">
+    <item quantity="one" msgid="8167147081136579439">"1 個相符項目"</item>
+    <item quantity="other" msgid="4641872797067609177">"第 <xliff:g id="INDEX">%d</xliff:g> 個,共 <xliff:g id="TOTAL">%d</xliff:g> 個"</item>
+  </plurals>
+    <string name="action_mode_done" msgid="7217581640461922289">"完成"</string>
+    <string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"正在卸載 USB 儲存裝置..."</string>
+    <string name="progress_unmounting" product="default" msgid="1327894998409537190">"正在卸載 SD 記憶卡..."</string>
+    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"正在清除 USB 儲存裝置資料..."</string>
+    <string name="progress_erasing" product="default" msgid="6596988875507043042">"正在清除 SD 記憶卡資料..."</string>
+    <string name="format_error" product="nosdcard" msgid="6299769563624776948">"無法清除 USB 儲存裝置上的資料。"</string>
+    <string name="format_error" product="default" msgid="7315248696644510935">"無法清除 SD 卡上的資料。"</string>
+    <string name="media_bad_removal" msgid="7960864061016603281">"SD 記憶卡尚未卸載便已移除。"</string>
+    <string name="media_checking" product="nosdcard" msgid="418188720009569693">"目前正在檢查 USB 儲存裝置。"</string>
+    <string name="media_checking" product="default" msgid="7334762503904827481">"目前正在檢查 SD 記憶卡。"</string>
+    <string name="media_removed" msgid="7001526905057952097">"SD 記憶卡已移除。"</string>
+    <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"電腦目前正在使用 USB 儲存裝置。"</string>
+    <string name="media_shared" product="default" msgid="5706130568133540435">"電腦目前正在使用 SD 記憶卡。"</string>
+    <string name="media_unknown_state" msgid="729192782197290385">"外部媒體狀態未知。"</string>
+    <string name="share" msgid="1778686618230011964">"分享"</string>
+    <string name="find" msgid="4808270900322985960">"尋找"</string>
+    <string name="websearch" msgid="4337157977400211589">"Google 網頁搜尋"</string>
+    <string name="find_next" msgid="5742124618942193978">"尋找下一個"</string>
+    <string name="find_previous" msgid="2196723669388360506">"尋找上一個"</string>
+    <string name="gpsNotifTicker" msgid="5622683912616496172">"<xliff:g id="NAME">%s</xliff:g> 的位置要求"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"位置要求"</string>
+    <string name="gpsNotifMessage" msgid="1374718023224000702">"要求者:<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+    <string name="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="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_do_nothing" msgid="3743764740430821845">"暫不執行"</string>
+    <string name="choose_account_label" msgid="5655203089746423927">"選擇帳戶"</string>
+    <string name="add_account_label" msgid="2935267344849993553">"新增帳戶"</string>
+    <string name="add_account_button_label" msgid="3611982894853435874">"新增帳戶"</string>
+    <string name="number_picker_increment_button" msgid="2412072272832284313">"增加"</string>
+    <string name="number_picker_decrement_button" msgid="476050778386779067">"減少"</string>
+    <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> 輕觸並按住。"</string>
+    <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"向上滑動即可增加,向下滑動即可減少。"</string>
+    <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"增加分鐘數"</string>
+    <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"減少分鐘數"</string>
+    <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"增加時數"</string>
+    <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"減少時數"</string>
+    <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"設定 PM 值"</string>
+    <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"設定 AM 值"</string>
+    <string name="date_picker_increment_month_button" msgid="5369998479067934110">"增加月數"</string>
+    <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"減少月數"</string>
+    <string name="date_picker_increment_day_button" msgid="7130465412308173903">"增加日數"</string>
+    <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"減少日數"</string>
+    <string name="date_picker_increment_year_button" msgid="6318697384310808899">"增加年數"</string>
+    <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"減少年數"</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_enter" msgid="2985864015076059467">"Enter 鍵"</string>
+    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"選擇應用程式"</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">"滑動控制。持續輕觸。"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"向上滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"向下滑動即可<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="description_direction_right" msgid="8034433242579600980">"向右滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"解鎖"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"相機"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"靜音"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"音效已開啟"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"搜尋"</string>
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"滑動即可解鎖。"</string>
+    <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"插上耳機即可聽到系統朗讀密碼鍵。"</string>
+    <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"點。"</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="4891916833657929263">"內部儲存空間"</string>
+    <string name="storage_sd_card" msgid="3282948861378286745">"SD 記憶卡"</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="1955638862122232342">"資料用量警告"</string>
+    <string name="data_usage_warning_body" msgid="2814673551471969954">"輕觸即可查看使用量和設定。"</string>
+    <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"已停用 2G-3G 數據"</string>
+    <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"已停用 4G 數據"</string>
+    <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"已停用流動數據"</string>
+    <string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"Wi-Fi 數據已停用"</string>
+    <string name="data_usage_limit_body" msgid="3317964706973601386">"輕觸即可啟用。"</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_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="6741521330997452990">"輕觸即可解除限制。"</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>
+    <string name="org_unit" msgid="7265981890422070383">"機構單位:"</string>
+    <string name="issued_by" msgid="2647584988057481566">"發出機構:"</string>
+    <string name="validity_period" msgid="8818886137545983110">"有效期:"</string>
+    <string name="issued_on" msgid="5895017404361397232">"發出日期:"</string>
+    <string name="expires_on" msgid="3676242949915959821">"失效日期:"</string>
+    <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>
+    <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"查看全部"</string>
+    <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"選擇活動"</string>
+    <string name="share_action_provider_share_with" msgid="5247684435979149216">"分享活動"</string>
+    <string name="list_delimeter" msgid="3975117572185494152">"、 "</string>
+    <string name="sending" msgid="3245653681008218030">"正在傳送..."</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="default_audio_route_name" product="tablet" msgid="4617053898167127471">"平板電腦"</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">"藍牙音頻"</string>
+    <string name="wireless_display_route_description" msgid="9070346425023979651">"無線螢幕分享"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"完成"</string>
+    <string name="media_route_button_content_description" msgid="5758553567065145276">"媒體輸出"</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>
+    <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_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="wifi_display_notification_title" msgid="2223050649240326557">"已連接無線顯示裝置"</string>
+    <string name="wifi_display_notification_message" msgid="4498802012464170685">"這個畫面正在另一部裝置上顯示"</string>
+    <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"中斷連線"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"緊急電話"</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">"PIN 錯誤"</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">"輸入 SIM 卡 PIN 碼"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"輸入 PIN 碼"</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">"輸入所需的 PIN 碼"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"確認所需的 PIN 碼"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"正在解開上鎖的 SIM 卡..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"PIN 碼不正確。"</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"請輸入一個 4 至 8 位數的 PIN 碼。"</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK 碼應由 8 個或以上數字組成。"</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"請重新輸入正確的 PUK 碼。如果嘗試輸入的次數過多,SIM 卡將永久停用。"</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN 碼不符"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"圖案嘗試次數過多"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"如要解鎖,請以 Google 帳戶登入。"</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"正在檢查帳戶…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"您已輸入錯誤的 PIN 碼 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"您已輸入錯誤的密碼 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"您嘗試了 <xliff:g id="NUMBER_0">%d</xliff:g> 次仍未能成功解開這部上鎖的平板電腦。如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,平板電腦將回復原廠設定,所有用戶資料均會失去。"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"您嘗試了 <xliff:g id="NUMBER_0">%d</xliff:g> 次仍未能成功解開這部上鎖的手機。如果再嘗試 <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解開上鎖的平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解開上鎖的手機。\n\n請在 <xliff:g id="NUMBER_2">%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="7324161939475478066">"將音量調高至安全級別以上?\n長時間聆聽偏高音量可能會損害您的聽覺。"</string>
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"以兩隻手指按住不放,即可啟用協助工具。"</string>
+    <string name="accessibility_enabled" msgid="1381972048564547685">"協助工具已啟用。"</string>
+    <string name="enable_accessibility_canceled" msgid="3833923257966635673">"協助工具已取消。"</string>
+    <string name="user_switched" msgid="3768006783166984410">"目前的用戶是<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="app_no_restricted_accounts" msgid="5739463249673727736">"這個應用程式不支援限制存取的個人檔案帳戶"</string>
+    <string name="app_not_found" msgid="3429141853498927379">"找不到處理這項操作的應用程式"</string>
+    <string name="revoke" msgid="5404479185228271586">"撤銷"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"已取消"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"寫入內容時發生錯誤"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"不明"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"輸入管理員 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>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"新的 PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"確認新的 PIN"</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_too_short" msgid="8173982756265777792">"PIN 碼太短,至少必須為 4 位數。"</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"1 秒後再試一次"</item>
+    <item quantity="other" msgid="4730868920742952817">"<xliff:g id="COUNT">%d</xliff:g> 秒後再試一次"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"稍後再試"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"從螢幕邊緣快速滑動,即可顯示系統列"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"從螢幕邊緣快速滑動,即可顯示系統列"</string>
+</resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 6bf2bf9..b26b989 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -131,6 +131,11 @@
     <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="default" msgid="3475999286680000541">"手機儲存空間已滿。請刪除一些檔案,以釋放可用空間。"</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"網路可能會受到監控"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"我"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"平板電腦選項"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"電話選項"</string>
@@ -279,6 +284,8 @@
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"允許應用程式將工作移至前景或背景。應用程式可以自行處理,不待您操作。"</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"停止執行中的應用程式"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"允許應用程式移除工作並終止執行工作的應用程式。請注意,惡意應用程式可能利用此功能干擾其他應用程式的行為。"</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"管理活動堆疊"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"允許應用程式新增、移除及修改可供其他應用程式在其中執行的活動堆疊 (惡意應用程式可能藉此干擾其他應用程式的行為)。"</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"啟動任何活動"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"不論權限保護或匯出狀態為何,一律允許應用程式啟動任何活動。"</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"設定螢幕相容性"</string>
@@ -356,6 +363,12 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"允許應用程式繫結至輸入法的頂層介面 (一般應用程式不需使用)。"</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"繫結至協助工具服務"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"允許應用程式繫結至協助工具服務的頂層介面 (一般應用程式不需使用)。"</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"繫結至列印服務"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"允許應用程式繫結至列印服務的頂層介面 (一般應用程式並不需要)。"</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"繫結至列印多工緩衝處理器服務"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"允許應用程式繫結至列印多工緩衝處理器服務的頂層介面 (一般應用程式並不需要)。"</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"繫結至 NFC 服務"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"允許應用程式繫結至模擬 NFC 卡的應用程式 (一般應用程式並不需要)。"</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"繫結至文字服務"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"允許應用程式繫結至文字服務 (例如 SpellCheckerService) 的頂層介面 (一般應用程式不需使用)。"</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"繫結至 VPN 服務"</string>
@@ -366,6 +379,8 @@
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"允許應用程式繫結至小工具服務的頂層介面 (一般應用程式不需使用)。"</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"與裝置管理員互動"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"允許應用程式將調用請求傳送至裝置管理員 (一般應用程式不需使用)。"</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"新增或移除裝置管理員"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"允許應用程式新增或移除有效的裝置管理員 (一般應用程式並不需要)。"</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"變更螢幕顯示方向"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"允許應用程式隨時變更螢幕旋轉狀態 (一般應用程式不需使用)。"</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"變更指標速度"</string>
@@ -397,6 +412,8 @@
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"允許應用程式讀取系統的各種記錄檔。這會允許應用程式搜尋一般性的手機使用資訊,可能包含您的個人或私人資訊。"</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"使用任何媒體解碼器進行播放"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"允許應用程式使用任何已安裝的媒體解碼器進行解碼以播放影片。"</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"管理信任的憑證"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"允許應用程式安裝 CA 憑證 (做為信任的憑證) 及解除安裝 CA 憑證。"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"讀寫 diag 擁有的資源"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"允許應用程式讀取或寫入診斷群組擁有的任何資源,例如 /dev 底下的檔案。這可能會影響系統的穩定性和安全性,因此應由製造商或電信業者操作,且只用在特定硬體診斷。"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"啟用或停用應用程式元件"</string>
@@ -462,6 +479,16 @@
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"允許應用程式設定及連接 Wi-Fi 顯示裝置。"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"控制 Wi-Fi 顯示裝置"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"允許應用程式控制 Wi-Fi 顯示裝置的低階功能。"</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"擷取音訊輸出"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"允許應用程式擷取及重新導向音訊輸出。"</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"擷取視訊輸出"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"允許應用程式擷取及重新導向視訊輸出。"</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"擷取安全視訊輸出"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"允許應用程式擷取及重新導向安全視訊輸出。"</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"變更音訊設定"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"允許應用程式修改全域音訊設定,例如音量和用來輸出的喇叭。"</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"錄製音訊"</string>
@@ -525,6 +552,12 @@
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"防止手機進入待命狀態"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"允許應用程式防止平板電腦進入休眠狀態。"</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"允許應用程式防止手機進入休眠狀態。"</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"開啟或關閉平板電腦"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"開啟或關閉電源"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"允許應用程式開啟或關閉平板電腦。"</string>
@@ -613,6 +646,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"允許應用程式寫入 SD 卡。"</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"修改/刪除內部媒體儲存裝置內容"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"允許應用程式修改內部媒體儲存空間的內容。"</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"管理文件儲存空間"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"允許應用程式管理文件儲存空間。"</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"存取外部儲存空間 (所有使用者)"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"允許應用程式存取外部儲存空間 (所有使用者)。"</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"存取快取檔案系統"</string>
@@ -625,10 +660,16 @@
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"允許應用程式管理網路政策並定義應用程式專用規則。"</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"修改網路使用量計算方式"</string>
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"允許應用程式修改應用程式網路使用量的計算方式 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"修改通訊端標記"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"允許應用程式修改路由的通訊端標記"</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_invokeCarrierSetup" msgid="3699600833975117478">"叫用行動通訊業者提供的設定應用程式"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"允許應用程式叫用行動通訊業者提供的設定應用程式 (一般應用程式並不需要)。"</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"監聽網路狀況觀察資訊"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"允許應用程式監聽網路狀況觀察資訊 (一般應用程式並不需要)。"</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"設定密碼規則"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"控制螢幕解鎖密碼所允許的長度和字元。"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"監視螢幕解鎖嘗試次數"</string>
@@ -646,7 +687,7 @@
     <string name="policylab_expirePassword" msgid="885279151847254056">"設定螢幕上鎖密碼到期日"</string>
     <string name="policydesc_expirePassword" msgid="1729725226314691591">"控制螢幕上鎖密碼的變更頻率。"</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="266329104542638802">"停用鍵盤保護框上的功能"</string>
@@ -696,7 +737,7 @@
   </string-array>
     <string name="phoneTypeCustom" msgid="1644738059053355820">"自訂"</string>
     <string name="phoneTypeHome" msgid="2570923463033985887">"住家"</string>
-    <string name="phoneTypeMobile" msgid="6501463557754751037">"行動裝置"</string>
+    <string name="phoneTypeMobile" msgid="6501463557754751037">"手機"</string>
     <string name="phoneTypeWork" msgid="8863939667059911633">"公司"</string>
     <string name="phoneTypeFaxWork" msgid="3517792160008890912">"公司傳真"</string>
     <string name="phoneTypeFaxHome" msgid="2067265972322971467">"住家傳真"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <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">"網路會議"</string>
@@ -796,7 +836,7 @@
     <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">"您的 SIM 卡已遭永久停用。\n請與您的無線網路服務供應商聯絡,以取得其他 SIM 卡。"</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"[上一首曲目] 按鈕"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"[下一首曲目] 按鈕"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"[暫停] 按鈕"</string>
@@ -808,11 +848,11 @@
     <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">%d</xliff:g> 次。"\n\n"請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"您的密碼已輸錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次。"\n\n"請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"您的 PIN 已輸錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次。"\n\n"請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統就會要求您使用您的 Google 登入資訊解除平板電腦的鎖定狀態。"\n\n"請在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次,如果再試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統就會要求您使用您的 Google 登入資訊解除手機的鎖定狀態。"\n\n"請在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"您的密碼已輸錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"您的 PIN 已輸錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統就會要求您使用您的 Google 登入資訊解除平板電腦的鎖定狀態。\n\n請在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次,如果再試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統就會要求您使用您的 Google 登入資訊解除手機的鎖定狀態。\n\n請在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"您嘗試解除這個平板電腦的鎖定已失敗 <xliff:g id="NUMBER_0">%d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%d</xliff:g> 次機會。如果失敗次數超過限制,平板電腦將恢復原廠設定,所有使用者資料都會遺失。"</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"您嘗試解除這支手機的鎖定已失敗 <xliff:g id="NUMBER_0">%d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%d</xliff:g> 次機會。如果失敗次數超過限制,手機將恢復原廠設定,所有使用者資料都會遺失。"</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"您嘗試解除這個平板電腦的鎖定已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次,平板電腦現在將恢復原廠設定。"</string>
@@ -826,7 +866,7 @@
     <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_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>
@@ -874,7 +914,7 @@
     <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="autofill_this_form" msgid="4616758841157816676">"自動填入功能"</string>
@@ -1080,14 +1120,14 @@
     <string name="aerr_application" msgid="932628488013092776">"很抱歉,<xliff:g id="APPLICATION">%1$s</xliff:g> 已停止。"</string>
     <string name="aerr_process" msgid="4507058997035697579">"很抱歉,處理程序 <xliff:g id="PROCESS">%1$s</xliff:g> 已停止。"</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> 沒有回應。"\n\n"您要結束嗎?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"<xliff:g id="ACTIVITY">%1$s</xliff:g> 活動沒有回應。"\n\n"您要結束嗎?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> 沒有回應。\n\n您要結束嗎?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"<xliff:g id="ACTIVITY">%1$s</xliff:g> 活動沒有回應。\n\n您要結束嗎?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> 沒有回應。您要結束嗎?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"<xliff:g id="PROCESS">%1$s</xliff:g> 處理程序沒有回應。"\n\n"您要結束嗎?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"<xliff:g id="PROCESS">%1$s</xliff:g> 處理程序沒有回應。\n\n您要結束嗎?"</string>
     <string name="force_close" msgid="8346072094521265605">"確定"</string>
     <string name="report" msgid="4060218260984795706">"回報"</string>
     <string name="wait" msgid="7147118217226317732">"等待"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"網頁沒有回應。"\n\n"您要結束嗎?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"網頁沒有回應。\n\n您要結束嗎?"</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>
@@ -1256,6 +1296,10 @@
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"允許觸發預設容器服務,以便複製內容 (不建議一般應用程式使用)。"</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"轉送媒體輸出"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"允許應用程式將媒體輸出轉送至其他外部裝置。"</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"存取 Keyguard 安全儲存空間"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"允許應用程式存取 Keyguard 安全儲存空間。"</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"控制鍵盤鎖的顯示和隱藏"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"允許應用程式控制鍵盤鎖。"</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"輕觸兩下即可控制縮放"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"無法新增小工具。"</string>
     <string name="ime_action_go" msgid="8320845651737369027">"開始"</string>
@@ -1265,15 +1309,15 @@
     <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="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="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="permission_request_notification_with_subtitle" msgid="8530393139639560189">"帳戶 <xliff:g id="ACCOUNT">%s</xliff:g> 已提出\n權限要求。"</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>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"全部顯示"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"選擇活動"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"分享活動"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"裝置已鎖定。"</string>
     <string name="list_delimeter" msgid="3975117572185494152">"、 "</string>
     <string name="sending" msgid="3245653681008218030">"傳送中…"</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"啟動「瀏覽器」嗎?"</string>
@@ -1441,10 +1484,12 @@
     <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>
+    <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_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="wifi_display_notification_title" msgid="2223050649240326557">"已連接無線顯示器"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"其他裝置正在顯示這個畫面"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"中斷連線"</string>
@@ -1453,7 +1498,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">%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">"輸入 SIM PIN"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"輸入 PIN"</string>
@@ -1473,27 +1518,85 @@
     <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_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">%d</xliff:g> 次。"\n\n"請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"您的密碼已輸錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次。"\n\n"請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次。"\n\n"請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"您的 PIN 已輸錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"您的密碼已輸錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"您嘗試解除這個平板電腦的鎖定已失敗 <xliff:g id="NUMBER_0">%d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%d</xliff:g> 次機會。如果失敗次數超過限制,平板電腦將恢復原廠設定,所有使用者資料都會遺失。"</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"您嘗試解除這支手機的鎖定已失敗 <xliff:g id="NUMBER_0">%d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統就會要求您透過電子郵件帳戶解除平板電腦的鎖定狀態。"\n\n"請在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統就會要求您透過電子郵件帳戶解除手機的鎖定狀態。"\n\n"請在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統就會要求您透過電子郵件帳戶解除平板電腦的鎖定狀態。\n\n請在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統就會要求您透過電子郵件帳戶解除手機的鎖定狀態。\n\n請在 <xliff:g id="NUMBER_2">%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="7324161939475478066">"要將音量調高到建議等級以上嗎?"\n"長時間聆聽高音量可能會損害您的聽力。"</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"要將音量調高到建議等級以上嗎?\n長時間聆聽高音量可能會損害您的聽力。"</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"持續用兩指按住即可啟用協助工具。"</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"協助工具已啟用。"</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"協助工具已取消。"</string>
     <string name="user_switched" msgid="3768006783166984410">"目前的使用者是 <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="app_no_restricted_accounts" msgid="4011285085817350390">"這個應用程式不支援設有限制的個人資料所屬帳戶"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"這個應用程式不支援設有限制的個人資料所屬帳戶"</string>
     <string name="app_not_found" msgid="3429141853498927379">"找不到支援此操作的應用程式"</string>
     <string name="revoke" msgid="5404479185228271586">"撤銷"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Letter"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Government Letter"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Legal"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Junior Legal"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ledger"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"已取消"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"寫入內容時發生錯誤"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"不明"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"輸入管理員 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>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"新 PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"確認新 PIN"</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_too_short" msgid="8173982756265777792">"PIN 長度太短,至少必須為 4 位數。"</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"1 秒後再試一次"</item>
+    <item quantity="other" msgid="4730868920742952817">"<xliff:g id="COUNT">%d</xliff:g> 秒後再試一次"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"稍後再試"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"從螢幕邊緣向內滑動即可顯示導覽列"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"從螢幕邊緣向內滑動即可顯示導覽列"</string>
 </resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 28cefb8..24006fd 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -131,6 +131,11 @@
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Kunokususa <xliff:g id="CONTENT_TYPE">%s</xliff:g> okuningi kakhulu."</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Isilondolozi sethebhulethi sigcwele! Susa amanye amafayela ukukhulula isikhala."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"Isilondolozi sefoni sigcwele! Susa amanye amafayela ukukhulula isikhala."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Inethiwekhi ingase inganyelwe"</string>
+    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
+    <skip />
     <string name="me" msgid="6545696007631404292">"Mina"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Okukhethwa kukho kwethebhulethi"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Okukhethwa kukho kwefoni"</string>
@@ -238,11 +243,11 @@
     <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Qapha umbhalo owuthayiphayo"</string>
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Kufaka phakathi idatha yomuntu siqu efana nezinombolo zekhadi lesikweletu namaphasiwedi."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"khubaza noma guqula ibha yomumo"</string>
-    <string name="permdesc_statusBar" msgid="8434669549504290975">"Ivumela insiza ukuthi yenze umudwa ochaza ngesimo ukuthi ungasebenzi noma ukufaka noma ukukhipha izithonjana zohlelo."</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"Ivumela uhlelo lokusebenza ukuthi yenze umudwa ochaza ngesimo ukuthi ungasebenzi noma ukufaka noma ukukhipha izithonjana zohlelo."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"umudwa ochaza ngesimo"</string>
     <string name="permdesc_statusBarService" msgid="716113660795976060">"Ivumela uhlelo lokusebenza ukuthi lube umudwa ochaza ngesimo."</string>
     <string name="permlab_expandStatusBar" msgid="1148198785937489264">"khulisa/nciphisa ibha yomumo"</string>
-    <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"Ivumela insiza ukuthi ikhulise noma inciphise umudwa ochza ngesimo."</string>
+    <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"Ivumela uhlelo lokusebenza ukuthi ikhulise noma inciphise umudwa ochza ngesimo."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"thumela amakholi aphumayo kabusha"</string>
     <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Ivumela uhlelo lokusebenza ukucubungula amakholi aphumayo futhi ishintshe inombolo ezoshayelwa. Le mvume ivumela uhlelo lokusebenza ukwengamela, liqondise kabusha, noma livikele amakholi aphumayo."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"thola imiyalezo ebhaliwe (i-SMS)"</string>
@@ -250,7 +255,7 @@
     <string name="permlab_receiveMms" msgid="1821317344668257098">"thola imiyalezo ebhaliwe (i-MMS)"</string>
     <string name="permdesc_receiveMms" msgid="533019437263212260">"Ivumela uhlelo lokusebenza ukuthola nokucubungula imilayezo ye-MMS. Loku kuchaza ukuthi uhlelo lokusebenza lungangamela noma lesuse imilayezo ethunyelwe kudivayisi yakho ngaphandle kokukubonisa yona."</string>
     <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"yamukela ukusakazwa okuphuthumayo"</string>
-    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Ivumela insiza ukuthi yamukele iphinde isebenze ukusakakwa kwemiyalezo yezokuphuthumayo. Imvume itholakla ezinsizeni zesistimu kuphela."</string>
+    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Ivumela uhlelo lokusebenza ukuthi yamukele iphinde isebenze ukusakakwa kwemiyalezo yezokuphuthumayo. Imvume itholakla ezinsizeni zesistimu kuphela."</string>
     <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"funda imilayezo yokusakaza yeselula"</string>
     <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Ivumela uhlelo lokusebenza ukufunda imilayezo yokusakaza yeselula etholwe idivayisi yakho. Izaziso zokusakaza zeselula zilethwa kwezinye izindawo ukukuxwayisa ngezimo ezisheshayo. Izinhlelo zokusebenza ezingalungile zingaphazamisana nokusebenza noma umsebenzi wedivayisi yakho uma ukusakaza kweselula kwesimo esisheshayo kutholwa."</string>
     <string name="permlab_sendSms" msgid="5600830612147671529">"thumela imiyalezo ye-SMS"</string>
@@ -261,11 +266,11 @@
     <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Ivumela uhlelo lokusebenza ukufunda imilayezo ye-SMS elondolozwe kuthebulethi noma ekhadini lakho le-SIM. Lokhu kuvumela uhlelo lokusebenza ukufunda yonke imilayezo ye-SMS, ngaphandle kokuqukethwe noma ukugcinwa kuyimfihlo."</string>
     <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Ivumela uhlelo lokusebenza ukufunda imilayezo ye-SMS elondolozwe efonini noma ekhadini lakho le-SIM. Lokhu kuvumela uhlelo lokusebenza ukufunda yonke imilayezo ye-SMS, ngaphandle kokuqukethwe noma ukugcinwa kuyimfihlo."</string>
     <string name="permlab_writeSms" msgid="3216950472636214774">"hlela imiyalezo yakho yombhalo (i-SMS noma i-MMS)"</string>
-    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Ivumela insiza ukuthi ibhale imiylezo ye-SMS egcinwe ekhompyutheni yakho yepeni noma kwikhadi lakho le-SIM. Izinsiza ezinobungozi zingayisusa imiyalezo yakho."</string>
-    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Ivumela insiza ukuthi ibhale imiylezo ye-SMS egcinwe ocingweni lwakh noma kwikhadi lakho le-SIM. Izinsiza ezinobungozi zingayisusa imiyalezo yakho."</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Ivumela uhlelo lokusebenza ukuthi ibhale imiylezo ye-SMS egcinwe ekhompyutheni yakho yepeni noma kwikhadi lakho le-SIM. Izuhlelo lokusebenza ezinobungozi zingayisusa imiyalezo yakho."</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Ivumela uhlelo lokusebenza ukuthi ibhale imiylezo ye-SMS egcinwe ocingweni lwakh noma kwikhadi lakho le-SIM. Izuhlelo lokusebenza ezinobungozi zingayisusa imiyalezo yakho."</string>
     <string name="permlab_receiveWapPush" msgid="5991398711936590410">"thola imiyalezo ebhaliwe (i-WAP)"</string>
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Ivumela uhlelo lokusebenza ukuthola nokucubungula imilayezo ye-WAP. Le mvume ifaka phakathi amandla okungamela noma okwesusa imilayezo ethunyelwe kuwe ngaphandle kokukubonisa."</string>
-    <string name="permlab_getTasks" msgid="6466095396623933906">"thola izinsiza ezisebenzayo"</string>
+    <string name="permlab_getTasks" msgid="6466095396623933906">"thola izinhlelo zokusebenza ezisebenzayo"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Ivumela uhlelo lokusebenza ukubuyisa ulwazi mayelana nemisebenzi yamanje neyakamuva. Lokhu kungavumela uhlelo lokusebenza ukuthola ulwazi mayelana nokuthi iziphi izinhlelo zokusebenza ezisetshenziswa kudivayisi."</string>
     <string name="permlab_interactAcrossUsers" msgid="7114255281944211682">"ihlanganyela phakathi kwabasebenzisi"</string>
     <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Ivumela uhlelo lokusebenza ukwenza izenzo kubasebenzisi bonke kudivayisi. Izinhlelo zokusebenza ezingalungile zingasebenzisa lokhu ukwephula ukuvikela phakathi kwabasebenzisi."</string>
@@ -275,30 +280,32 @@
     <string name="permdesc_manageUsers" msgid="8409306667645355638">"Ivumela izinhlelo zokusebenza ukuphatha abasebenzisi kudivayisi, kufaka phakathi umbuzo, ukudala nokususa."</string>
     <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"thola kabusha imininingwane yezinhlelo zokusebenza ezisebenzayo"</string>
     <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Ivumela uhlelo lokusebenza ukuthola kabusha ulwazi mayelana nezinto ezenzeka manje nezisanda kwenzeka. Izinhlelo zokusebenza ezingalungile zingathola imininingwane eyimfihlo mayelana nezinye izinhlelo zokusebenza."</string>
-    <string name="permlab_reorderTasks" msgid="2018575526934422779">"misa kabusha izinsiza ezisebenzayo"</string>
+    <string name="permlab_reorderTasks" msgid="2018575526934422779">"misa kabusha izinhlelo zokusebenza ezisebenzayo"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Ivumela uhlelo lokusebenza ukugudluza imisebenzi ngaphambili nangasemuva. Uhlelo lokusebenza lungenza lokhu ngaphandle kwakho."</string>
-    <string name="permlab_removeTasks" msgid="6821513401870377403">"misa izinsiza ezisebenzayo"</string>
-    <string name="permdesc_removeTasks" msgid="1394714352062635493">"Vumela ukuthi insiza isuse okumele kwenziwe ibulale nezinsiza zakho. Izinsiza eziwubungozi zingaphazamisa ukusebenza kwezinye izinsiza."</string>
+    <string name="permlab_removeTasks" msgid="6821513401870377403">"misa izinhlelo zokusebenza ezisebenzayo"</string>
+    <string name="permdesc_removeTasks" msgid="1394714352062635493">"Vumela ukuthi uhlelo lokusebenza isuse okumele kwenziwe ibulale nezuhlelo lokusebenza zakho. Izuhlelo lokusebenza eziwubungozi zingaphazamisa ukusebenza kwezinye izinhlelo zokusebenza."</string>
+    <string name="permlab_manageActivityStacks" msgid="7391191384027303065">"phatha izitaki zomsebenzi"</string>
+    <string name="permdesc_manageActivityStacks" msgid="1615881933034084440">"Ivumela uhlelo lokusebenza ukuthi lingeze, lisuse, noma lilungise izitaki zomsebenzi lapho ezinye izinhlelo zokusebenza ziqalisa khona. Izinhlelo zokusebenza ezinobungozi zingaphazamisa ukuziphatha kwezinye izinhlelo zokusebenza."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"qala noma imuphi umsebenzi"</string>
     <string name="permdesc_startAnyActivity" msgid="997823695343584001">"Ivumela uhlelo lokusebenza ukuqala umsebenzi, ngaphandle kokuvukeleka kwemvume noma isimo sokukhishiwe."</string>
     <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"setha ukuhambelana kwesikrini"</string>
     <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Ivumela uhlelo lokusebenza ukulawula imodi yokuhambelana kwesikrini kwezinye izinhlelo zokusebenza. Izinhlelo zokusebenza ezinonya zingase zephule ukuziphatha kwezinye izinhlelo zokusebenza."</string>
-    <string name="permlab_setDebugApp" msgid="3022107198686584052">"vumela insiza ilungise inkinga"</string>
-    <string name="permdesc_setDebugApp" msgid="4474512416299013256">"Ivumela insiza ukuthi ivule uhlelo lokulungisa lwenye insiza. Izinsiza ezinobungozi zingasebenzisa lokhu ukubulala ezinye izinsiza."</string>
+    <string name="permlab_setDebugApp" msgid="3022107198686584052">"vumela uhlelo lokusebenza ilungise inkinga"</string>
+    <string name="permdesc_setDebugApp" msgid="4474512416299013256">"Ivumela uhlelo lokusebenza ukuthi ivule uhlelo lokulungisa lwenye uhlelo lokusebenza. Izuhlelo lokusebenza ezinobungozi zingasebenzisa lokhu ukubulala ezinye izinhlelo zokusebenza."</string>
     <string name="permlab_changeConfiguration" msgid="4162092185124234480">"guqula izilungiselo zohlelo zokubonisa"</string>
     <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"Ivumela uhlelo lokusebenza ukushintsha ukumisa kwamanje, njengezici zakhona noma usayizi wefonti."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"vumela imodi yemoto"</string>
-    <string name="permdesc_enableCarMode" msgid="4853187425751419467">"Ivumela insiza ukuthi yenze isimo semoto sisebenze."</string>
+    <string name="permdesc_enableCarMode" msgid="4853187425751419467">"Ivumela uhlelo lokusebenza ukuthi yenze isimo semoto sisebenze."</string>
     <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"vala ezinye izinhlelo zokusebenza"</string>
     <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"Ivumela uhelo lokusebenza ukuqeda izinqubo zangokwasemuva zezinhlelo zokusebenza. Lokhu kungababangela ezinye izinhlelo zokusebenza ukuyeka ukusebenza."</string>
-    <string name="permlab_forceStopPackages" msgid="2329627428832067700">"phoqelela ezinye izinsiza ukuthi zime"</string>
-    <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"Ivumela insiza ukuthi iphoze ezinye izinsiza ukuthi zime."</string>
-    <string name="permlab_forceBack" msgid="652935204072584616">"phoqa insiza ukuthi ivaleke"</string>
-    <string name="permdesc_forceBack" msgid="3892295830419513623">"Ivumela insiza ukuthi iphoqe nanoma isiphi isehlo esiphambili ukuthi sivale bese sibuyela emuva. Akudingeki ezinsizeni ezejwayelekile."</string>
+    <string name="permlab_forceStopPackages" msgid="2329627428832067700">"phoqelela ezinye izinhlelo zokusebenza ukuthi zime"</string>
+    <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"Ivumela uhlelo lokusebenza ukuthi iphoze ezinye izinhlelo zokusebenza ukuthi zime."</string>
+    <string name="permlab_forceBack" msgid="652935204072584616">"phoqa uhlelo lokusebenza ukuthi ivaleke"</string>
+    <string name="permdesc_forceBack" msgid="3892295830419513623">"Ivumela uhlelo lokusebenza ukuthi iphoqe nanoma isiphi isehlo esiphambili ukuthi sivale bese sibuyela emuva. Akudingeki ezinsizeni ezejwayelekile."</string>
     <string name="permlab_dump" msgid="1681799862438954752">"thola isimo sangaphakathi sesistimu"</string>
-    <string name="permdesc_dump" msgid="1778299088692290329">"Ivumela insiza ukuthi ithole kabusha ingaphakathi lesistimu. izinsiza ezinobungozi zingathola kabusha inqwaba yolwazi oluyimfihlo noluvikelekile ezingajwayele ukuthi ziludinge."</string>
+    <string name="permdesc_dump" msgid="1778299088692290329">"Ivumela uhlelo lokusebenza ukuthi ithole kabusha ingaphakathi lesistimu. izinhlelo zokusebenza ezinobungozi zingathola kabusha inqwaba yolwazi oluyimfihlo noluvikelekile ezingajwayele ukuthi ziludinge."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"letha okuqukethwe kwesikrini"</string>
-    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Ivumela insiza ukuthi ithole okuqukethe kwi-Window. Izinsiza ezinobungozi zingathola kabush iwindi eliphelele bese ibheka konke okuqukethwe ngaphandle kwaaaphasiwedi."</string>
+    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Ivumela uhlelo lokusebenza ukuthi ithole okuqukethe kwi-Window. Izuhlelo lokusebenza ezinobungozi zingathola kabush iwindi eliphelele bese ibheka konke okuqukethwe ngaphandle kwaaaphasiwedi."</string>
     <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"nika amandla okwesikhashana ukufinyelela"</string>
     <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"Ivumela uhlelo lokusebenza ukunika amandla ukufinyelela kwesikhashana kuvidayisi. Izinhlelo zokusebenza ezingalungile zinganika amandla ukufinyelela ngaphandle kwemvume yomsebenzisi."</string>
     <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"buyisa ulwazi lewindi"</string>
@@ -313,18 +320,18 @@
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Igwema umsebenzisi ukuthi ashintshele kolunye uhlelo lokusebenza."</string>
     <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"thola ulwazi lohlelo lokusebenza lwamanje"</string>
     <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Ivumela umphathi ukuthi athole ulwazi oluyimfihlo mayelana nohlelo lokusebenza lwamanje ngaphambili kwesikrini."</string>
-    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"qapha futhi ulawule ukuqaliswa kwazo zonke izinsiza"</string>
+    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"qapha futhi ulawule ukuqaliswa kwazo zonke izinhlelo zokusebenza"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Ivumela uhlelo lokusebebenza ukuthi luhlole futhi lulawule ukuthi isistimu iziqalisa kanjani imisebenzi. Izinhlelo zokusebenza ezinobungozi zingensa isistimu ibe sebungozini. Le mvume idingakalela intuthuku kuphela hhayi ukusetshenziswa okwejwayelekile."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"thumela iphakheji yomsakazo okhishiwe"</string>
-    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"Ivumela insiza ukuthi isakaze isaziso sokuthi insiza ethize isusiwe. Izinsiza ezinobungozi zingasebenzisa lokhu ukubulala nanoma iyiphi enye insiza esebenzayo."</string>
+    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"Ivumela uhlelo lokusebenza ukuthi isakaze isaziso sokuthi uhlelo lokusebenza ethize isusiwe. Izuhlelo lokusebenza ezinobungozi zingasebenzisa lokhu ukubulala nanoma iyiphi enye uhlelo lokusebenza esebenzayo."</string>
     <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"thumela umsakazo otholwe nge-SMS"</string>
-    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"Ivumela insiza ukuthi isakaze isaziso sokuthi umyalezo we-SMS utholakele. Izinsiza ezinobungozi zingasebenzisa lokhu ukufoja imiyalezo ye-SMS engenayo."</string>
+    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"Ivumela uhlelo lokusebenza ukuthi isakaze isaziso sokuthi umyalezo we-SMS utholakele. Izuhlelo lokusebenza ezinobungozi zingasebenzisa lokhu ukufoja imiyalezo ye-SMS engenayo."</string>
     <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"thumela umsakazo otholwe nge-WAP-PUSH"</string>
-    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"Ivumela insiza ukuthi isakaze isaziso sokuthi umyalezo we-WAP PUSH utholakele. Izinsiza ezinobungozi zingasebenzisa lokhu ukufoja ukutholakala kwemiyalezo ye-S noma zisuse okuqukethwe kwanoma iliphi ikhasi lewebhu eliqukethe okunobungozi."</string>
+    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"Ivumela uhlelo lokusebenza ukuthi isakaze isaziso sokuthi umyalezo we-WAP PUSH utholakele. Izuhlelo lokusebenza ezinobungozi zingasebenzisa lokhu ukufoja ukutholakala kwemiyalezo ye-S noma zisuse okuqukethwe kwanoma iliphi ikhasi lewebhu eliqukethe okunobungozi."</string>
     <string name="permlab_setProcessLimit" msgid="2451873664363662666">"khawula inani lezinqubo ezisebenzayo"</string>
-    <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"Ivumela insiza ukuthi ilawule isibalo esikhulu sezinto eziqhubekayo eziyosebenza. Ayidingakeli izinsiza ezijwayelekile."</string>
+    <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"Ivumela uhlelo lokusebenza ukuthi ilawule isibalo esikhulu sezinto eziqhubekayo eziyosebenza. Ayidingakeli izinhlelo zokusebenza ezijwayelekile."</string>
     <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"phoqa izinhlelo zokusebenza ezingemuva ukuthi zivaleke"</string>
-    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"Ivumela izinsiza ukuthi zilawule ukuthi izehlakalo ziyaphela yini emumva kokuba ziye ngemumva. Akudingakeli izinsiza ezijwayelekile."</string>
+    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"Ivumela izinhlelo zokusebenza ukuthi zilawule ukuthi izehlakalo ziyaphela yini emumva kokuba ziye ngemumva. Akudingakeli izinhlelo zokusebenza ezijwayelekile."</string>
     <string name="permlab_batteryStats" msgid="2789610673514103364">"funda izibalo zebhethri"</string>
     <string name="permdesc_batteryStats" msgid="5897346582882915114">"Ivumela uhlelo lokusebenza ukufunda idatha yokusebenza yebhethri leleveli ephansi yamanje. Ingavumela uhlelo lokusebenza ukuthola ulwazi lemininingwane mayelana nokuthi iziphi izinhlelo zokusebenza ozisebenzisayo."</string>
     <string name="permlab_updateBatteryStats" msgid="3719689764536379557">"guqula izibalo zebhetri"</string>
@@ -334,87 +341,97 @@
     <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"shintsha izinombolo zokusebenza zohlelo lokusebenza"</string>
     <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"Ivumela uhlelo lokusebenza ukuthi lishintshe izinombolo zokusebenza kohlelo lokusebenza lokuqoqiwe. Akufanele kusetshenziswe izinhlelo zokusebenza ezijwayelekile."</string>
     <string name="permlab_backup" msgid="470013022865453920">"lawula ukusekela ngokulondoloza uhlelo bese ubuyisela esimweni"</string>
-    <string name="permdesc_backup" msgid="6912230525140589891">"Ivumela insiza ukuthi ilawule isipele sesistimu kanye nohlelo lokubuyiselwa kabusha. Ayenzelwe ukusetshenziswa izinsiza ezijwayelekile."</string>
+    <string name="permdesc_backup" msgid="6912230525140589891">"Ivumela uhlelo lokusebenza ukuthi ilawule isipele sesistimu kanye nohlelo lokubuyiselwa kabusha. Ayenzelwe ukusetshenziswa izinhlelo zokusebenza ezijwayelekile."</string>
     <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"qinisekisa isipele sonke noma buyisela futhi ukusebenza"</string>
-    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"Ivumela insiza ukuthi iqalise ukuqinisekiswa okuphelele kwesipele kwe-UI. Akumelwe kusetshenziswe noma  iyiphi insiza."</string>
+    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"Ivumela uhlelo lokusebenza ukuthi iqalise ukuqinisekiswa okuphelele kwesipele kwe-UI. Akumelwe kusetshenziswe noma  iyiphi uhlelo lokusebenza."</string>
     <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"bonisa amawindi angavunyelwe"</string>
-    <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"Ivumela insiza ukuthi yakhe amawindi enzelwe ukuthi asetshenziswe inkundla yokusetshenziswa kwangaphakathi kwesistimu. Ayisethsnziswa izinsiza ezijwayelekile."</string>
+    <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"Ivumela uhlelo lokusebenza ukuthi yakhe amawindi enzelwe ukuthi asetshenziswe inkundla yokusetshenziswa kwangaphakathi kwesistimu. Ayisethsnziswa izinhlelo zokusebenza ezijwayelekile."</string>
     <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"dweba phezulu kwezinye izinhlelo zokusebenza"</string>
     <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"Ivumela uhlelo lokusebenza ukudweba phezu kwezinye izinhlelo zokusebenza noma izingxene zokusetshenziswa ukubonwa. Zingaphazamisa ukusebenzisa kwakho kokusetshenziswa kubonwa kunoma uluphi uhlelo lokusebenza, noma ukushintsha ocabanga ukuthi uyakubona kwezinye izinhlelo zokusebenza."</string>
     <string name="permlab_setAnimationScale" msgid="2805103241153907174">"guqula isivinini sokugqwayiza jikelele"</string>
     <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"Ivumela uhlelo lokusebenza ukushintsha isivinini sokugqwayiza jikelele (ukugqwayiza okusheshayo noma okulengayo) nganoma isiphi isikhathi."</string>
     <string name="permlab_manageAppTokens" msgid="1286505717050121370">"lawula amathokheni ezinsiza"</string>
-    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"Ivumela insiza ukuthi idale iphinde futhi ilawule amathokheni ayo, ngokweqa uku-oda kuka-Z okwejwayelekile. Akufanele kudingakele izinsiza ezijwayelekile."</string>
+    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"Ivumela uhlelo lokusebenza ukuthi idale iphinde futhi ilawule amathokheni ayo, ngokweqa uku-oda kuka-Z okwejwayelekile. Akufanele kudingakele izinhlelo zokusebenza ezijwayelekile."</string>
     <string name="permlab_freezeScreen" msgid="4708181184441880175">"misa kancane isikrini"</string>
     <string name="permdesc_freezeScreen" msgid="8558923789222670064">"Ivumela uhlelo lokusebenza ukumisa okwesikhashana isikrini ngokushintshwa kwesikrini esigcwele."</string>
     <string name="permlab_injectEvents" msgid="1378746584023586600">"chofoza okhiye nezinkinobho zokulawula"</string>
     <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"Ivumela uhlelo lokusebenza ukuthi lizenzele izehlakalo zalo zokufaka (ukucindezela kokhiye, njll)  kwezinye izinhlelo zokusebenza. Izinhlelo zokusebenza ezinobungozi zingasebenzisa lokhu ukuthi zilawule ithebhulethi."</string>
-    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"Ivumela insiza ukuthi ithumele imicimbi yayo (ukucindezelwa kwezinkinobho, njll) kwezinye izinsiza. Izinsiza ezinobungozi zingasebenzisa lokhu ukuthi zilawule ucingo."</string>
+    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"Ivumela uhlelo lokusebenza ukuthi ithumele imicimbi yayo (ukucindezelwa kwezinkinobho, njll) kwezinye izinhlelo zokusebenza. Izuhlelo lokusebenza ezinobungozi zingasebenzisa lokhu ukuthi zilawule ucingo."</string>
     <string name="permlab_readInputState" msgid="469428900041249234">"qopha lokho okuthayiphayo nezinyathelo ozithathayo"</string>
-    <string name="permdesc_readInputState" msgid="8387754901688728043">"Ivumela insiza ukuthi ibheke izinkinobho ozicindezelayo ngisho ngabe usebenzisana nezinye izinsiza (njengokubhala amaphasiwedi). Akufanele kudingakele izinsiza ezijwayelekile."</string>
+    <string name="permdesc_readInputState" msgid="8387754901688728043">"Ivumela uhlelo lokusebenza ukuthi ibheke izinkinobho ozicindezelayo ngisho ngabe usebenzisana nezinye izinhlelo zokusebenza (njengokubhala amaphasiwedi). Akufanele kudingakele izinhlelo zokusebenza ezijwayelekile."</string>
     <string name="permlab_bindInputMethod" msgid="3360064620230515776">"hlanganisa indlela yokufakwayo"</string>
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Ivumela isimeli ukuhlanganisa uxhumano nomsebenzisi wezinga eliphezulu lendlela yokufaka. Ayisoze yadingeka kwizinhlelo ezivamile."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"hlanganisa kusevisi yokufinyeleleka"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Ivumela isibambi ukuhlanganisa uxhumo nomsebenzisi kwezinga eliphezulu lesevisi yesinqunjwana. Akusoze kwadingekela izinhlelo zokusebenza ezivamile."</string>
+    <string name="permlab_bindPrintService" msgid="8462815179572748761">"bophezela kusevisi yokuphrinta"</string>
+    <string name="permdesc_bindPrintService" msgid="7960067623209111135">"Ivumela umnikazi ukuthi abophezele isixhumanisi esibonakalayo sezinga eliphezulu sesevisi lokuphrinta. Akumele idingelwe izinhlelo zokusebenza ezijwayelekile."</string>
+    <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"bophezela kusevisi yendawo yokuphrinta"</string>
+    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Ivumela umnikazi ukuthi abophezele isixhumanisi esibonakalayo sezinga eliphezulu sesevisi yendawo yokuphrinta. Akumele idingelwe izinhlelo zokusebenza ezijwayelekile."</string>
+    <string name="permlab_bindNfcService" msgid="2752731300419410724">"bophezela kusevisi ye-NFC"</string>
+    <string name="permdesc_bindNfcService" msgid="6120647629174066862">"Ivumela umnikazi ukuthi abophezele izinhlelo zokusebenza ezifana namakhadi we-NFC. Akumele idingeke kuzinhlelo zokusebenza ezijwayelekile."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"bophezela kunsizakalo yombhalo"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Ivumela umbambi ukuhlanganisa uxhumano nomsebenzisi kwezinga eliphezulu lwesixhumi esibonakalayo sensizakalo yombhalo(isb. InsizakaloYokuhlolaUkubhala). Akusoze kwadingeka kwezinhlelo zokusebenza ezivamile."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"hlanganisa kwinsizakalo ye-VPN"</string>
-    <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Ivumela umnini ukuthi abophele kwissekelo esingaphezulu sesevisi ye-Vpm. Ayidingakeli izinsiza ezejwayelekile."</string>
+    <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Ivumela umnini ukuthi abophele kwissekelo esingaphezulu sesevisi ye-Vpm. Ayidingakeli izinhlelo zokusebenza ezejwayelekile."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"hlanganisa kwiphephadonga"</string>
     <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Ivumela umbambi ukuhlanganisa uxhumano nomsebenzisi kwezinga eliphezulu lwephephadonga. Akusoze kwadingeka kwezinhlelo zokusebenza ezivamile."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"bophezela kube isevisi yesinqunjana"</string>
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Ivumela umbambi ukuhlanganisa uxhumano nomsebenzisi kwezinga eliphezulu lensizakalo yesinqunjwana. Akusoze kwadingeka kwezinhlelo zokusebenza ezivamile."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"xhumana nomphathi wedivaysi"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Ivumela ummeli ukuthumela okuqukethwe kumphathi wedivaysi. Akusoze kwadingeka kwizinhlelo zokusebenza ezivamile."</string>
+    <string name="permlab_manageDeviceAdmins" msgid="4248828900045808722">"engeza noma susa umlawuli wedivayisi"</string>
+    <string name="permdesc_manageDeviceAdmins" msgid="5025608167709942485">"Ivumela umnikazi ukuthi angeze noma asuse abalawuli bedivayisi esebenzayo. Akumele idingelwe izinhlelo zokusebenza ezijwayelekile."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"shintsha ukujikeleza kwesikrini"</string>
-    <string name="permdesc_setOrientation" msgid="3046126619316671476">"Ivumela insiza ukuthi iguqule ukujikeleza kweskrini nganoma isiphi isikhathi. Akudingakeli izinsiza ezejwayelekile."</string>
+    <string name="permdesc_setOrientation" msgid="3046126619316671476">"Ivumela uhlelo lokusebenza ukuthi iguqule ukujikeleza kweskrini nganoma isiphi isikhathi. Akudingakeli izinhlelo zokusebenza ezejwayelekile."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"guqula isivinini sesikhombi"</string>
-    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Ivumela insiza ukuthi iguqule ijubane legundane noma lendawo yokukhomba ngomunwe. Akufanele kudingakele izinsiza ezijwayelekile."</string>
+    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Ivumela uhlelo lokusebenza ukuthi iguqule ijubane legundane noma lendawo yokukhomba ngomunwe. Akufanele kudingakele izinhlelo zokusebenza ezijwayelekile."</string>
     <string name="permlab_setKeyboardLayout" msgid="4778731703600909340">"shintsha isendlalelo sekhibhodi"</string>
     <string name="permdesc_setKeyboardLayout" msgid="8480016771134175879">"Ivumela uhlelo lokusebenza ukushintsha isendlalelo sekhibhodi. Kufanele ingadingi izinhlelo zokusebenza ezivamile."</string>
     <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"Thumela imifanekiso ye-Linu ezinsizeni"</string>
-    <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Ivumela insiza ukuthi icele ukuthi isiginali ethunyelwe idluliselwe kuzo zonke izinqubeko ezisalelayo."</string>
-    <string name="permlab_persistentActivity" msgid="8841113627955563938">"yenza insiza ukuthi ihlale isebenza"</string>
+    <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Ivumela uhlelo lokusebenza ukuthi icele ukuthi isiginali ethunyelwe idluliselwe kuzo zonke izinqubeko ezisalelayo."</string>
+    <string name="permlab_persistentActivity" msgid="8841113627955563938">"yenza uhlelo lokusebenza ukuthi ihlale isebenza"</string>
     <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Ivumela uhlelo kusebenza ukwenza izingxenye yazo ezicindezelayo kumemori. Lokhu kungakhawulela imemori ekhona kwezinye izinhlelo zokusebenza ukwenza ukuthi ithebhulethi ingasheshi."</string>
     <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"Ivumela uhlelo kusebenza ukwenza izingxenye yazo ezicindezelayo kumemori. Lokhu kungakhawulela imemori ekhona kwezinye izinhlelo zokusebenza ukwenza ukuthi ifoni ingasheshi."</string>
-    <string name="permlab_deletePackages" msgid="184385129537705938">"susa izinsiza"</string>
-    <string name="permdesc_deletePackages" msgid="7411480275167205081">"Ivumela insiza ukuthi isuse amaphakheji e=Android. Izinsiza ezinobungozi zingasebenzisa lokhu ukusasa izinsiza ezibalulekile."</string>
+    <string name="permlab_deletePackages" msgid="184385129537705938">"susa izinhlelo zokusebenza"</string>
+    <string name="permdesc_deletePackages" msgid="7411480275167205081">"Ivumela uhlelo lokusebenza ukuthi isuse amaphakheji e=Android. Izuhlelo lokusebenza ezinobungozi zingasebenzisa lokhu ukusasa izinhlelo zokusebenza ezibalulekile."</string>
     <string name="permlab_clearAppUserData" msgid="274109191845842756">"susa eminye imininingwane yezinsiza"</string>
-    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"Ivumela insiza ukuth isule imininingwane yomsebenzisi."</string>
+    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"Ivumela uhlelo lokusebenza ukuth isule imininingwane yomsebenzisi."</string>
     <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"susa eminye imininingwane yezinsiza"</string>
-    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"Ivumela insiza ukuthi isuse amafayela alondolozwe okwesikhashana."</string>
-    <string name="permlab_getPackageSize" msgid="7472921768357981986">"linganisa isikhala sokugcina insiza"</string>
-    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Ivuela insiza ukuthi ithole kabusha ikhodi yayo, i-dat kanye nosayizi abagcinwe okwesikhashana."</string>
-    <string name="permlab_installPackages" msgid="2199128482820306924">"faka ngqo izinsiza"</string>
-    <string name="permdesc_installPackages" msgid="5628530972548071284">"Ivumela insiza ukuthi ifake amaphakheji e-Android amasha noma abuyekeziwe. Izinsiza ezinobungozi zngasebenzisa lokhu ukwengeza izinsiza ezintsha ezinemvume emndla."</string>
+    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"Ivumela uhlelo lokusebenza ukuthi isuse amafayela alondolozwe okwesikhashana."</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"linganisa isikhala sokugcina uhlelo lokusebenza"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Ivuela uhlelo lokusebenza ukuthi ithole kabusha ikhodi yayo, i-dat kanye nosayizi abagcinwe okwesikhashana."</string>
+    <string name="permlab_installPackages" msgid="2199128482820306924">"faka ngqo izinhlelo zokusebenza"</string>
+    <string name="permdesc_installPackages" msgid="5628530972548071284">"Ivumela uhlelo lokusebenza lufake amaphakheji e-Android amasha noma abuyekeziwe. Izinhlelo zokusebenza ezinobungozi zingasebenzisa lokhu ukwengeza izinhlelo ezinemvume enamandla."</string>
     <string name="permlab_clearAppCache" msgid="7487279391723526815">"Susa yonke i-data egcinwe okwesikhashana yensiza"</string>
     <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"Ivumela uhlelo lokusebenza ukukhulula isitoreji se-tablet ngokususa amafayela enqolobaneni yezinye izinhlelo zokusebenza. Lokhu kungabangela ezinye izinhlelo zokusebenza ukuqala kancane njengoba zidinga ukubuyisa idatha yazo."</string>
     <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"Ivumela uhlelo lokusebenza ukukhulula isitoreji sefoni ngokususa amafayela enqolobaneni yezinye izinhlelo zokusebenza. Lokhu kungabangela ezinye izinhlelo zokusebenza ukuqala kancane njengoba zidinga ukubuyisa idatha yazo."</string>
     <string name="permlab_movePackage" msgid="3289890271645921411">"hambis izinto zensiz"</string>
-    <string name="permdesc_movePackage" msgid="319562217778244524">"Ivumela insiza ukuthi ihambise izinto eziqukethwe insiz izisusa emidiyeni yangaphakathi kuya kweyangaphandle njalonjalo."</string>
+    <string name="permdesc_movePackage" msgid="319562217778244524">"Ivumela uhlelo lokusebenza ukuthi ihambise izinto eziqukethwe insiz izisusa emidiyeni yangaphakathi kuya kweyangaphandle njalonjalo."</string>
     <string name="permlab_readLogs" msgid="6615778543198967614">"funda idatha yefayela lokungena ebucayi"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Ivumela uhlelo lokusebenza ukufunda umafayela okungena ohlelo oluhlukene. Lokhu kuvumela ukuthola ukwaziswa okuvamile mayelana nokuthi wenzani ngethebhulethi, kodwa akumele kuqukethe ukwaziswa komuntu siqu noma okuyimfihlo."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Ivumela uhlelo lokusebenza ukufunda kumafayela okungena ahlukene esistimu. Lokhu kuvumela ukuthola ukwaziswa okuvamile mayelana nokuthi wenzani ngefoni, kuhlanganise ukwaziswa komuntu siqu noma kwangasese."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"sebenzisa noma isiphi isiqophi semidiya ukudlala"</string>
-    <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Ivumela insiza ukusebenzisa noma isiphi isiqophi semidiya esifakiwe ukuqopha ukudlala."</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Ivumela uhlelo lokusebenza ukusebenzisa noma isiphi isiqophi semidiya esifakiwe ukuqopha ukudlala."</string>
+    <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"phatha ukuqinisekisa okuthenjiwe"</string>
+    <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Ivumela uhlelo lokusebenza ukuthi lifake liphinde likhiphe izitifiketi ze-CA njengokuqinisekiswa okuthenjiwe."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"funda/bhalela emithombweni ephethwe idayegi"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Ivumela uhlelo lokusebenza ukufunda nokubhala kunoma yimuphi umthombo weqembu ledayegi; ngokwesibonelo, amafayela akwi/dev. Lokhu kungase kuthinte kakhulu ukuba nokuphepha kohlelo. Lokhu kumele kusebenziselwe KUPHELA ukuhlola ihadiwe okucacile ngumkhiqizi noma u-opheretha."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"vumela noma vimbela izingxenye zensiza"</string>
-    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Ivumela ukuthi insiza iguqule ukuthi okuqukethwe kwenye insiza kuyasebenza noma cha. Izinsiza ezinobungozi zingasebenzisa lokhu ukwenza ukuthi izinto ezisemqoka ekhompyutheni yepeni zingasebenzi. Kufanele kuqashelwe uma kukhishwa lemvume njengoba kungenzeka kwenze izinto zensiza zibe sesimweni esingazinzile, nesiguquguqukayo."</string>
-    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Ivumela ukuthi insiza iguqule ukuthi okuqukethwe kwenye insiza kuyasebenza noma cha. Izinsiza ezinobungozi zingasebenzisa lokhu ukwenza ukuthi izinto ezisemqoka ocingweni zingasebenzi. Kufanele kuqashelwe uma kukhishwa lemvume njengoba kungenzeka kwenze izinto zensiza zibe sesmweni esingazinzile, nesiguquguqukayo."</string>
+    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Ivumela ukuthi uhlelo lokusebenza iguqule ukuthi okuqukethwe kwenye uhlelo lokusebenza kuyasebenza noma cha. Izuhlelo lokusebenza ezinobungozi zingasebenzisa lokhu ukwenza ukuthi izinto ezisemqoka ekhompyutheni yepeni zingasebenzi. Kufanele kuqashelwe uma kukhishwa lemvume njengoba kungenzeka kwenze izinto zensiza zibe sesimweni esingazinzile, nesiguquguqukayo."</string>
+    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Ivumela ukuthi uhlelo lokusebenza iguqule ukuthi okuqukethwe kwenye uhlelo lokusebenza kuyasebenza noma cha. Izuhlelo lokusebenza ezinobungozi zingasebenzisa lokhu ukwenza ukuthi izinto ezisemqoka ocingweni zingasebenzi. Kufanele kuqashelwe uma kukhishwa lemvume njengoba kungenzeka kwenze izinto zensiza zibe sesmweni esingazinzile, nesiguquguqukayo."</string>
     <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"nika noma buyisa izimvume"</string>
     <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Ivumela izinhlelo zokusebenza ukunika noma ukubuyisa izimvume ezithile zayo noma ezinye izinhlelo zokusebenza. Izinhlelo zokusebenza ezingalungile zingasebenzisa lokhu ukufinyelela izici ongazinikanga zona."</string>
-    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"setha izinsiza ezincamelwayo"</string>
-    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Ivuela insiza ukuthi iguqule izinsiza ezincanyelwayo. Izinsiza ezinobungozi zingashintsha izinsiz buthule ezisebenzyo okwenza ukuthi izinsiza zakho ezikhona zingasebenzi ukuthola ze zithole imininingwane yakho eyimfihlo."</string>
+    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"setha izinhlelo zokusebenza ezincamelwayo"</string>
+    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Ivuela uhlelo lokusebenza ukuthi iguqule izinhlelo zokusebenza ezincanyelwayo. Izuhlelo lokusebenza ezinobungozi zingashintsha izinsiz buthule ezisebenzyo okwenza ukuthi izinhlelo zokusebenza zakho ezikhona zingasebenzi ukuthola ze zithole imininingwane yakho eyimfihlo."</string>
     <string name="permlab_writeSettings" msgid="2226195290955224730">"guqula izilungiselelo zohlelo"</string>
-    <string name="permdesc_writeSettings" msgid="7775723441558907181">"Ivumela insiza ukuthi iguqule i-data yezisetho zesistimu. Izinsiza ezinobungozi zingona ukusebenz kwesistimu yakho."</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"Ivumela uhlelo lokusebenza ukuthi iguqule i-data yezisetho zesistimu. Izuhlelo lokusebenza ezinobungozi zingona ukusebenz kwesistimu yakho."</string>
     <string name="permlab_writeSecureSettings" msgid="204676251876718288">"guqula izilungiselelo zohlelo oluphephile"</string>
-    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"Ivumela insiza ukuthi iguqule imioniningwane yezisetho zokuphepha kwesistimu. Ayisetshenziswa izinsiza ezijwayelekile."</string>
+    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"Ivumela uhlelo lokusebenza ukuthi iguqule imioniningwane yezisetho zokuphepha kwesistimu. Ayisetshenziswa izinhlelo zokusebenza ezijwayelekile."</string>
     <string name="permlab_writeGservices" msgid="2149426664226152185">"guqula ibalazwe lesevisi ye-Google"</string>
-    <string name="permdesc_writeGservices" msgid="1287309437638380229">"Ivumela insiza ukuthi iguqule imephu yezinsizakalo ze-Google. Ayisetshenziswa izinsiza ezijwayelekile."</string>
+    <string name="permdesc_writeGservices" msgid="1287309437638380229">"Ivumela uhlelo lokusebenza ukuthi iguqule imephu yezuhlelo lokusebenzakalo ze-Google. Ayisetshenziswa izinhlelo zokusebenza ezijwayelekile."</string>
     <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"qalisa esiqalisweni sezinhlelo"</string>
     <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Ivumela uhlelo lokusebenza ukuthi luziqalise ngokushesha emuva kokuba isistimu isiqedile ukubhutha. Lokhu kwenza ukuthi ithathe isikhathi esithe ukuba side ukuqalise ithebhulethi nokuvumela izinhlelo zokusebenza ukuthi inciphise yonke ithebhulethi ngokuthi isebenze njalo."</string>
-    <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Ivumela insiza ukuthi iziqalise ngokushesha uma isistiu isiqedile ukubhutha. Lokhu kungenz ukuthi kuthathe isikhathi esithe ukuba side ukuqalisa ucingo nokuvuela insiz ukuthi inciphise ucingo lonke ngokuthi luhlale lusebenza."</string>
+    <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Ivumela uhlelo lokusebenza ukuthi iziqalise ngokushesha uma isistiu isiqedile ukubhutha. Lokhu kungenz ukuthi kuthathe isikhathi esithe ukuba side ukuqalisa ucingo nokuvuela insiz ukuthi inciphise ucingo lonke ngokuthi luhlale lusebenza."</string>
     <string name="permlab_broadcastSticky" msgid="7919126372606881614">"thumela ukusakaza okunamathelayo"</string>
     <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Ivumela uhlelo lokusebenza ukuthumela ukusakaza okunamathelayo, okusalayo emva kokuba ukusakazwa sekuphelile. Ukusebenzisa kakhulu kuhle kwenze ithebhulethi ukuthi ingasheshi noma ingahlali kahle ngokuyibangela ukusebenzisa imemori eningi."</string>
     <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Ivumela uhlelo lokusebenza ukuthumela ukusakaza okunamathelayo, okusalayo emva kokuba ukusakazwa sekuphelile. Ukusebenzisa kakhulu kuhle kwenze ifoni ukuthi ingasheshi noma ingahlali kahle ngokuyibangela ukusebenzisa imemori eningi."</string>
@@ -455,13 +472,23 @@
     <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"indawo eseduze (kususelwe kunethiwekhi)"</string>
     <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Ivumela uhlelo lokusebenza ukuthola cishe indawo yakho. Le ndawo isuselwe kumasevisi endawo kusetshenziswa imithombo yendawo yenethiwekhi njengama-cell tower ne-Wi-Fi. Lawo masevisi endawo kufanele akhanyiswe futhi atholakale kudivayisi yakho ukuze asetshenziswe uhlelo lakho lokusebenza. Izinhlelo zokusebenza zingasebenzisa lokhu ukucacisa cishe lapho ukhona."</string>
     <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"finyelela i-SurfaceFlinger"</string>
-    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Ivumela insiza ukuthi isebenzise okuqukethwe i-SurfaceFlinger okusezingeni eliphansi."</string>
+    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Ivumela uhlelo lokusebenza ukuthi isebenzise okuqukethwe i-SurfaceFlinger okusezingeni eliphansi."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"funda isikhumbuli sesikhashana sendikimba"</string>
-    <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Ivumela insiza ukuthi ifunde okuqukethwe ifreyimu yebhafa."</string>
+    <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Ivumela uhlelo lokusebenza ukuthi ifunde okuqukethwe ifreyimu yebhafa."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"lungisa ukubukwa kwe-Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Ivumela uhlelo lokusebenza ukulungisa nokuxhuma ekubukisweni kwe-Wi-Fi."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"lawula ukubukwa kwe-Wi-Fi"</string>
     <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Uvumela uhlelo lokusebenza ukulawula izici zeleveli ephansi zokuboniswa kwe-Wi-Fi."</string>
+    <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"shutha okukhipha umsindo"</string>
+    <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"Kuvumela uhlelo lokusebenza ukuba lushuthe futhi luqondise kabusha okukhipha umsindo."</string>
+    <!-- no translation found for permlab_captureAudioHotword (1890553935650349808) -->
+    <skip />
+    <!-- no translation found for permdesc_captureAudioHotword (9151807958153056810) -->
+    <skip />
+    <string name="permlab_captureVideoOutput" msgid="2246828773589094023">"shutha okokukhipha ividiyo"</string>
+    <string name="permdesc_captureVideoOutput" msgid="359481658034149860">"Kuvumela uhlelo lokusebenza ukuba lushuthe futhi luqondise kabusha okukhipha ividiyo."</string>
+    <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"shutha okukhipha ividiyo ephephile"</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"Kuvumela uhlelo lokusebenza ukuba lushuthe futhi luqondise kabusha okukhipa ividiyo ephephile."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"shintsha izilungiselelo zakho zomsindo"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Ivumela uhlelo lokusebenza ukushintsha izilungiselelo zomsindo we-global njengevolomu nokuthi isiphi isipika esisetshenziselwa okukhiphayo."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"qopha umsindo"</string>
@@ -489,7 +516,7 @@
     <string name="permlab_asec_create" msgid="6414757234789336327">"dala isitoreji sangaphakathi"</string>
     <string name="permdesc_asec_create" msgid="4558869273585856876">"Ivumela uhlelo lokusebenza ukwenza ukugcina kwangaphakathi"</string>
     <string name="permlab_asec_destroy" msgid="526928328301618022">"yonakalisa isitoreji sangaphakathi"</string>
-    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"Ivumela insiza ukuthi ibulale ukulondolozwa kwangaphakathi."</string>
+    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"Ivumela uhlelo lokusebenza ukuthi ibulale ukulondolozwa kwangaphakathi."</string>
     <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"khweza / yehlisa isitoreji sangaphakathi"</string>
     <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"Ivumela uhlelo ukukhuphula / ukwehlisa isitoreji sangaphakathi."</string>
     <string name="permlab_asec_rename" msgid="7496633954080472417">"yetha kabusha isitoreji sangaphakathi"</string>
@@ -507,24 +534,30 @@
     <string name="permlab_callPhone" msgid="3925836347681847954">"ngokuqondile shayela izinombolo zocingo"</string>
     <string name="permdesc_callPhone" msgid="3740797576113760827">"Ivumela uhlelo lokusebenza ukushayela izinombolo zefoni ngaphandle kokuhlanganyela kwakho. Lokhu kungaholela emashajini noma amakholi angalindelekile. Qaphela ukuthi lokhu akuvumeli uhlelo lokusebenza ukushayela izinombolo zesimo esiphuthumayo. Izinhlelo zokusebenza ezingalungile zingabiza imali ngokwenze amakholi ngaphandle kokuqinisekisa kwakho."</string>
     <string name="permlab_callPrivileged" msgid="4198349211108497879">"ngokuqondile shayela noma iziphi izinombolo zocingo."</string>
-    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"Ivumela insiza ukuth ishayele noma iyiphi inombolo okubandakanya nezinombolo eziphuthumayo ngaphandle kokugammbukela. zinsiza ezinobungozi zingafaka izingcingo ezingenasiidngo nezingekho emthethweni esevisini ephuthumayo."</string>
+    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"Ivumela uhlelo lokusebenza ukuth ishayele noma iyiphi inombolo okubandakanya nezinombolo eziphuthumayo ngaphandle kokugammbukela. zuhlelo lokusebenza ezinobungozi zingafaka izingcingo ezingenasiidngo nezingekho emthethweni esevisini ephuthumayo."</string>
     <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"ngokuqondile qalisa ukumisa ithebhulethi nge-CDMA"</string>
     <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"ngokuqondile qalisa ukumisa ifoni nge-CDMA"</string>
-    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"Ivumela insiza ukuqalisa amalungiselelo e-CDMA. Izinsiza ezinobungozi ingaqalisa amalungiselelo e-CDMA ngokungenasidingo."</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"Ivumela uhlelo lokusebenza ukuqalisa amalungiselelo e-CDMA. Izuhlelo lokusebenza ezinobungozi ingaqalisa amalungiselelo e-CDMA ngokungenasidingo."</string>
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"lawula izaziso zokubuyekeza indawo"</string>
-    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Ivumela ukuthi insiza yenze izaziso zendawo zisebenze noma zingasebenzi emsakazweni. Ayenzelwe ukuthi isetshenziswe izinsiza ezijwayelekile."</string>
+    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Ivumela ukuthi uhlelo lokusebenza yenze izaziso zendawo zisebenze noma zingasebenzi emsakazweni. Ayenzelwe ukuthi isetshenziswe izinhlelo zokusebenza ezijwayelekile."</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"finyelela kwizakhiwo zokuhlola"</string>
-    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Ivumela insiza ukuthi ifunde/ibhale ukufinyelela ezintweni ezilayishwe ngokubheka amasevisi. Akusetshenziswa izinsiza ezijwayelekile."</string>
+    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Ivumela uhlelo lokusebenza ukuthi ifunde/ibhale ukufinyelela ezintweni ezilayishwe ngokubheka amasevisi. Akusetshenziswa izinhlelo zokusebenza ezijwayelekile."</string>
     <string name="permlab_bindGadget" msgid="776905339015863471">"khetha izinqunjwana"</string>
-    <string name="permdesc_bindGadget" msgid="8261326938599049290">"Ivumela insiza ukuthi itshele isistimu ukuthi amaphi amawijethi angasetshenziswa yiyiphi insiza. Insiza enalemvume inganikez ukufinyelela kwi-data yomuntu kwezinye izinsiza. Ayisetshenziswa izinsiza ezijwayelekile."</string>
+    <string name="permdesc_bindGadget" msgid="8261326938599049290">"Ivumela uhlelo lokusebenza ukuthi itshele isistimu ukuthi amaphi amawijethi angasetshenziswa yiyiphi uhlelo lokusebenza. Insiza enalemvume inganikez ukufinyelela kwi-data yomuntu kwezinye izinhlelo zokusebenza. Ayisetshenziswa izinhlelo zokusebenza ezijwayelekile."</string>
     <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"guqula isimo sefoni"</string>
-    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Ivumela ukuthi insiza ilawule okuqukethwe ocingweni edivayisini. Insiza enalemvume ingaguquguqula amanethwekhi, ivule umsakazo wocingo iphinde iwucishe kanye nokunye okufana nalokho ngaphandle kokukwazisa."</string>
+    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Ivumela ukuthi uhlelo lokusebenza ilawule okuqukethwe ocingweni edivayisini. Insiza enalemvume ingaguquguqula amanethwekhi, ivule umsakazo wocingo iphinde iwucishe kanye nokunye okufana nalokho ngaphandle kokukwazisa."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"funda isimo sefoni kanye nesazisi"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Ivumela uhlelo lokusebenza ukufinyelela izici zefoni zedivayisi. Le mvume ivumela uhlelo lokusebenza ukucacisa inombolo yefoni nobunikazi bedivayisi, ukuthi noma ikholi iyasebenza, futhi nenombolo yesilawuli kude zixhunywe ngekholi."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"gwema ithebhulethi ukuba ingalali"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"gwema ifoni ukuba ingalali"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Ivumela uhlelo lokusebenza ukuthi linqande ithebulethi yakho ukuthi ilale."</string>
-    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Ivumela insiza ukuthi inqande ucingo ukuthi lulale."</string>
+    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Ivumela uhlelo lokusebenza ukuthi inqande ucingo ukuthi lulale."</string>
+    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
+    <skip />
+    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
+    <skip />
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"amandla efoni avuliwe noma avaliwe"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"amandla efoni avuliwe noma avaliwe"</string>
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Ivumela uhlelo lokusebenza ukuvala noma ukuvula ithebhulethi."</string>
@@ -537,15 +570,15 @@
     <string name="permlab_setWallpaperHints" msgid="3278608165977736538">"shintsha usayizi wesithombe sakho sangemuva"</string>
     <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Ivumela uhlelo lokusebenza ukuhlela izihlawumbisela zosayizi wephephadonga lohlelo."</string>
     <string name="permlab_masterClear" msgid="2315750423139697397">"setha kabusha kube okumisiwe kwemboni"</string>
-    <string name="permdesc_masterClear" msgid="3665380492633910226">"Ivuela insiza ukuthi isethe kabusha isistiu ngokuphelele iyibuyisele ezisethweni eyafika nazo, isusa konke ukumisw kwemininingwane, kanye nezinsiza ezifakiwe."</string>
+    <string name="permdesc_masterClear" msgid="3665380492633910226">"Ivuela uhlelo lokusebenza ukuthi isethe kabusha isistiu ngokuphelele iyibuyisele ezisethweni eyafika nazo, isusa konke ukumisw kwemininingwane, kanye nezuhlelo lokusebenza ezifakiwe."</string>
     <string name="permlab_setTime" msgid="2021614829591775646">"setha isikhathi"</string>
-    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"Ivumela insiza ukuthi iguqule isikhathi esisekhompyutheni yepeni."</string>
-    <string name="permdesc_setTime" product="default" msgid="1855702730738020">"Ivumela insiza ukuth iguqule isikhathi esisocingweni."</string>
+    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"Ivumela uhlelo lokusebenza ukuthi iguqule isikhathi esisekhompyutheni yepeni."</string>
+    <string name="permdesc_setTime" product="default" msgid="1855702730738020">"Ivumela uhlelo lokusebenza ukuth iguqule isikhathi esisocingweni."</string>
     <string name="permlab_setTimeZone" msgid="2945079801013077340">"setha umkhawulo wesikhathi"</string>
-    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Ivumela insiza ukuthi iguqule umkhawulo wesikhathi sekhompyutha yepeni."</string>
-    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Ivumela insiza ukuth iguqule isikhathi esisocingweni."</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Ivumela uhlelo lokusebenza ukuthi iguqule umkhawulo wesikhathi sekhompyutha yepeni."</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Ivumela uhlelo lokusebenza ukuth iguqule isikhathi esisocingweni."</string>
     <string name="permlab_accountManagerService" msgid="4829262349691386986">"yenza njenge Nsizakalo Yemeneja ye-Akhawunti"</string>
-    <string name="permdesc_accountManagerService" msgid="1948455552333615954">"Ivumela insiza ukuthi ishaye izingcingo Kokokuqinisekisa Ama-akhawunti."</string>
+    <string name="permdesc_accountManagerService" msgid="1948455552333615954">"Ivumela uhlelo lokusebenza ukuthi ishaye izingcingo Kokokuqinisekisa Ama-akhawunti."</string>
     <string name="permlab_getAccounts" msgid="1086795467760122114">"thola ama-akhawunti edivayisini"</string>
     <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Ivumela uhlelo lokusebenza ukuthola uhlu lwama-akhawunti aziwa ithebhulethi. Lokhu kufaka phakathi noma yimaphi ama-akhawunti adalwe izinhlelo zokusebenza ozifakile."</string>
     <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Ivumela uhlelo lokusebenza ukuthola uhlu lwama-akhawunti aziwa ifoni. Lokhu kufaka phakathi noma yimaphi ama-akhawunti adalwe izinhlelo zokusebenza ozifakile."</string>
@@ -554,17 +587,17 @@
     <string name="permlab_manageAccounts" msgid="4983126304757177305">"engeza noma ukhiphe ama-akhawunti"</string>
     <string name="permdesc_manageAccounts" msgid="8698295625488292506">"Ivumela uhlelo lokusebenza ukwenza imisebenzi enjengokufaka, nokukhipha ama-akhawunti nokususa iphasiwedi yawo"</string>
     <string name="permlab_useCredentials" msgid="235481396163877642">"sebenzisa ama-akhawunti edivayisini"</string>
-    <string name="permdesc_useCredentials" msgid="7984227147403346422">"Ivumela insiza ukuthi icele amathokheni okuqinisekisa."</string>
+    <string name="permdesc_useCredentials" msgid="7984227147403346422">"Ivumela uhlelo lokusebenza ukuthi icele amathokheni okuqinisekisa."</string>
     <string name="permlab_accessNetworkState" msgid="4951027964348974773">"buka ukuxhumeka kunethiwekhi"</string>
     <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Ivumela uhlelo lokusebenza ukubuka ulwazi mayelana noxhumo lenethiwekhi njengokuthi imaphi amanethiwekhi akhona futhi axhunyiwe."</string>
     <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"ukufinyelela kwenethiwekhi okugcwele"</string>
     <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Ivumela uhlelo lokusebenza ukudala amasokethi enethiwekhi nokusebenzisa iziphakamiso eziyisisekelo zenethiwekhi yezifiso. Iziphequluli nezinye izinhlelo zokusebenza zinikela ngezindlela zokuthumela idatha ku-intanethi, ngakho-le le mvume ayidingekile ukuthumela idatha ku-intanethi."</string>
     <string name="permlab_writeApnSettings" msgid="505660159675751896">"shintsha/ngenelela izilungiselelo kanye nokuhamba kuhleloxhumano"</string>
-    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Ivumela insiza ukuthi iguqule izilungiselelo zenethiwekhi kanye nokunciphisa kanye nokuhlola konke ukuphithizela kwenethiwekhi, isibonelo ukushintsha i-proy kanye ne-port yanom iyiphi i-APN. Izinhlelo zokusebenza ezinobungozi zingabheka, zithumele kabusha noma ziguqule okuqukethwe enethiwekhini ngaphandle kokwazi kwakho."</string>
+    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Ivumela uhlelo lokusebenza ukuthi iguqule izilungiselelo zenethiwekhi kanye nokunciphisa kanye nokuhlola konke ukuphithizela kwenethiwekhi, isibonelo ukushintsha i-proy kanye ne-port yanom iyiphi i-APN. Izinhlelo zokusebenza ezinobungozi zingabheka, zithumele kabusha noma ziguqule okuqukethwe enethiwekhini ngaphandle kokwazi kwakho."</string>
     <string name="permlab_changeNetworkState" msgid="958884291454327309">"shintsha uxhumano lwenethiwekhi"</string>
-    <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Ivumela insiza ukuthi iguqule isimo sokuxhuaniseka kwenethiwekhi."</string>
+    <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Ivumela uhlelo lokusebenza ukuthi iguqule isimo sokuxhuaniseka kwenethiwekhi."</string>
     <string name="permlab_changeTetherState" msgid="5952584964373017960">"Shintsha uxhumano lokusebenzisa njengemodemu"</string>
-    <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Ivumela insiza ukuthi iguqule isimo sokuxhuaniseka kwenethiwekhi ehunyiwe."</string>
+    <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Ivumela uhlelo lokusebenza ukuthi iguqule isimo sokuxhuaniseka kwenethiwekhi ehunyiwe."</string>
     <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"shintsha idatha yasemuva yelungiselelo lokusebenzisa"</string>
     <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Ivumela uhlelo lokusebenza ukuthi luguqule izilungiselelo zemininingwane yokusetshenziswa kwedatha."</string>
     <string name="permlab_accessWifiState" msgid="5202012949247040011">"buka ukuxhumaneka kwi-Wi-Fi"</string>
@@ -586,7 +619,7 @@
     <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Ivumela uhlelo lokusebenza ukubuka ukucushwa kwe-Bluetooth kuthebhulethi, nokwenza futhi nokwamukela uxhumo namadivayisi amatanisiwe."</string>
     <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Ivumela uhlelo lokusebenza ukubuka ukucushwa kwe-Bluetooth efonini, ukwenza futhi nokwamukela uxhumo namadivayisi amatanisiwe."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"lawula Uxhumano Lwenkambu Eseduze"</string>
-    <string name="permdesc_nfc" msgid="7120611819401789907">"Ivuela insiza ukuthi ixhumane ne-Near Field Communication (NFC) amathegi, amakhadi kanye nezinhlelo zokufunda."</string>
+    <string name="permdesc_nfc" msgid="7120611819401789907">"Ivuela uhlelo lokusebenza ukuthi ixhumane ne-Near Field Communication (NFC) amathegi, amakhadi kanye nezinhlelo zokufunda."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"khubaza ukukhiya kwakho iskrini"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Ivumela uhlelo lokusebenza ukukhubaza ukuvala ukhiye nanoma yikuphi ukuphepha kwephasiwedi okuhlobene. Isibonelo, ifoni ikhubaza ukuvala ukhiye lapho ithola ikholi yefoni engenayo, bese inike amandla kabusha ukuvala ukhiye lapho ikholi isiqedile."</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"funda izilungiselelo zokuvumelanisa"</string>
@@ -596,39 +629,47 @@
     <string name="permlab_readSyncStats" msgid="7396577451360202448">"funda izibalo zokuvumelanisa"</string>
     <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Ivumela uhlelo lokusebenza ukufunda izibalo zokuvumelanisa ze-akhawunti, kufaka phakathi umlando wezehlakalo ezivumelanisiwe nokuthi ingakanani idatha evumelanisiwe."</string>
     <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"funda izifunzo ezikhokhelwayo"</string>
-    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Ivumela insiza ukuthi ithole imininingwane mayelana namafidi avumelnisiwe njengamanje."</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Ivumela uhlelo lokusebenza ukuthi ithole imininingwane mayelana namafidi avumelnisiwe njengamanje."</string>
     <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"bhala izifunzo ezikhokhelwayo"</string>
-    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"Ivumela insiza ukuthi iguqule amafidi akho avumelanisiwe njengamanje. Izinsiza ezinobungozi zingaguqula amafidi akho avumelanisiwe."</string>
+    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"Ivumela uhlelo lokusebenza ukuthi iguqule amafidi akho avumelanisiwe njengamanje. Izuhlelo lokusebenza ezinobungozi zingaguqula amafidi akho avumelanisiwe."</string>
     <string name="permlab_readDictionary" msgid="4107101525746035718">"funda imibandela oyengezile esichazimazwini"</string>
     <string name="permdesc_readDictionary" msgid="659614600338904243">"Ivumela uhlelo lokusebenza ukufunda onke amabizo, amagama, namatemu umsebenzisi awalondolozile kusichazamazwi somsebenzisi."</string>
     <string name="permlab_writeDictionary" msgid="2183110402314441106">"engeza amagama kusichazamazwi ezichazwe umsebenzisi"</string>
-    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Ivumela insiza ukuthi ibhale amagama amasha esichazinimazwi."</string>
+    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Ivumela uhlelo lokusebenza ukuthi ibhale amagama amasha esichazinimazwi."</string>
     <string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"ukufinyelela kokuhlola esilondolozini esivikelekile"</string>
     <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"ukufinyelela kokuhlola esilondolozini esivikelekile"</string>
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"Ivumela uhlelo lokusebenza ukuhlola imvume yesitoreji se-USB okuzotholakala kumadivayisi alandelayo."</string>
     <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"Ivumela uhlelo lokusebenza ukuhlola imvume yekhadi le-SD okuzotholakala kumadivayisi alandelayo."</string>
     <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"guqula noma ususe okuqukethwe kwakho okugciniwe okufinyeleleka nge-USB"</string>
     <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"shintsha noma ususe okuqukethwe ekhadini lakho le-SD"</string>
-    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Ivumela insiza ukuthi ibhalele ekulondolozweni kwe-USB."</string>
-    <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Ivumela insiza ukuthi ibhalele ekhadini le-SD."</string>
+    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Ivumela uhlelo lokusebenza ukuthi ibhalele ekulondolozweni kwe-USB."</string>
+    <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Ivumela uhlelo lokusebenza ukuthi ibhalele ekhadini le-SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"guqula/susa okuqukethwe kwisitoreji semidiya yangaphakathi"</string>
-    <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Ivumela insiza ukuthi iguqule okuqukethwe kokulondoloza imidiya yangaphakathi."</string>
+    <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Ivumela uhlelo lokusebenza ukuthi iguqule okuqukethwe kokulondoloza imidiya yangaphakathi."</string>
+    <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"phatha isitoreji sedokhumenti"</string>
+    <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Ivumela uhlelo lokusebenza ukuthi luphathe isitoreji sedokhumenti."</string>
     <string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"ukufinyelela isilondolozi sangaphandle sabo bonke abasebenzisi"</string>
     <string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Vumela uhlelo lokusebenza ukufinyelela isilondolozi sangaphandle kubo bonke abasebenzisi."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"finyelela kunqolobane yesistimu yefayela"</string>
-    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Ivumela insiza ukuthi ifunde futhi ibhale isistimu yokufayila amafayela esikhashana."</string>
+    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Ivumela uhlelo lokusebenza ukuthi ifunde futhi ibhale isistimu yokufayila amafayela esikhashana."</string>
     <string name="permlab_use_sip" msgid="5986952362795870502">"yena/thola amakholi e-Inthanethi"</string>
-    <string name="permdesc_use_sip" msgid="4717632000062674294">"Ivumela insiza ukuthi isebenzise isevisi ye-SIP ukwenza/ukuthola izingcingo ze-inthanethi."</string>
+    <string name="permdesc_use_sip" msgid="4717632000062674294">"Ivumela uhlelo lokusebenza ukuthi isebenzise isevisi ye-SIP ukwenza/ukuthola izingcingo ze-inthanethi."</string>
     <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"funda ukusetshenziswa komlando wohleloxhumano"</string>
-    <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"Ivumela insiza ukuthi ifunde umlando wokusetshenziswa kwenethiwekhi emanethiwekhini athize kanye nasezinsizeni."</string>
+    <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"Ivumela uhlelo lokusebenza ukuthi ifunde umlando wokusetshenziswa kwenethiwekhi emanethiwekhini athize kanye nasezinsizeni."</string>
     <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"phatha inqubomgomo yenethiwekhi"</string>
-    <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Ivumela insiza ukuthi yengamele iigomo iphinde ichaze imithetho ehambisana ngqo nensiza."</string>
+    <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Ivumela uhlelo lokusebenza ukuthi yengamele iigomo iphinde ichaze imithetho ehambisana ngqo nensiza."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"lungisa ukubala kokusebenza kohleloxhumano"</string>
-    <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Ivumela insiza ukuthi iguqule ukuthii ukusetshenziswa kwenethiwekhi kumiswa kanjani ezinsizeni. Ayisetshenziswa izinsiza ezijwayelekile."</string>
+    <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Ivumela uhlelo lokusebenza ukuthi iguqule ukuthii ukusetshenziswa kwenethiwekhi kumiswa kanjani ezinsizeni. Ayisetshenziswa izinhlelo zokusebenza ezijwayelekile."</string>
+    <string name="permlab_markNetworkSocket" msgid="3658527214914959749">"shintsha izimpawu zesokhethi"</string>
+    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"Ivumela uhlelo lokusebenza ukuthi lilungise izimpawu zesokhethi zomzila"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"finyelela kuzaziso"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Ivumela uhlelo lokusebenza ukuthi lithole, lihlole, liphinde lisuse izaziso, ezifaka lezo ezithunyelwe ezinye izinhlelo zokusebenza."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"bophezela kwisevisi yomlaleli wesaziso"</string>
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Ivumela umbambi ukubophezela kwisixhumi esibonakalayo sezinga eliphezulu lesevisi yomlaleli wesaziso. Akusoze kwadingeka kwizinhlelo zokusebenza ezivamile."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"buyisela uhlelo lokusebenza lokulungiselelwa okunikezwe yinkampani yenethiwekhi"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Ivumela umnikazi ukuthi abuyisele uhlelo lokusebenza lokulungiselelwa. Akumele idingelwe izinhlelo zokusebenza ezijwayelekile."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"Lalela okubonwayo kuzimo zenethiwekhi"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Ivumela uhlelo lokusebenza ukuthi lulalele okubonwa kuzimo zenethiwekhi. Akumele idingelwe izinhlelo zokusebenza ezijwayelekile."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Misa imithetho yephasiwedi"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Lawula ubude nezinhlamvu ezivunyelwe kumaphasiwedi okuvula isikrini"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Gaka imizamo yokuvula isikrini"</string>
@@ -738,8 +779,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"i-Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"i-Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
+    <string name="imProtocolGoogleTalk" msgid="493902321140277304">"Ama-Hangout"</string>
     <string name="imProtocolIcq" msgid="1574870433606517315">"i-ICQ"</string>
     <string name="imProtocolJabber" msgid="2279917630875771722">"i-Jabber"</string>
     <string name="imProtocolNetMeeting" msgid="8287625655986827971">"Umhlangano we-Net"</string>
@@ -796,7 +836,7 @@
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Faka ikhadi le-SIM."</string>
     <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Ikhadi le-SIM alitholakali noma alifundeki. Sicela ufake ikhadi le-SIM."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Ikhadi le-SIM elingasetshenzisiwe."</string>
-    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"I-SIM khadi ykho isiyenziwe ukuthi ingasebenzi unomphela."\n" Xhumana nomhlinzeki wakho wokuxhumana okungenazintambo ukuze uthole enye i-SIM khadi."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"I-SIM khadi ykho isiyenziwe ukuthi ingasebenzi unomphela.\n Xhumana nomhlinzeki wakho wokuxhumana okungenazintambo ukuze uthole enye i-SIM khadi."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Inkinombo yengoma yangaphambilini"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Inkinobho yengoma elandelayo"</string>
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Inkinobho yokukuma kancane"</string>
@@ -808,11 +848,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Sicela ubone Isiqondisi Somsebenzisi noma xhumana Nokunakekela Ikhasimende"</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Ikhadi le-SIM livaliwe."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Ivula ikhadi le-SIM..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Udwebe iphathini yakho yokuvula ngendlela engafanele izinkathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n" Zama futhi emuva kwamasekhondi angu-<xliff:g id="NUMBER_1">%d</xliff:g>"</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Ubhale iphasiwedi yakho ngendlela engafanele <xliff:g id="NUMBER_0">%d</xliff:g> izikhathi. "\n\n"Zama futhi <xliff:g id="NUMBER_1">%d</xliff:g> imizuzwna."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Ubhale i-PIN ykho ngendlela engafanele <xliff:g id="NUMBER_0">%d</xliff:g> izikhathi. "\n\n"Zama futhi emuva kwamasekhondi angu-<xliff:g id="NUMBER_1">%d</xliff:g>."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Udwebe ngokungalungile iphathini yakho yokuvula izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. Emva <xliff:g id="NUMBER_1">%d</xliff:g> kweminye imizamo engaphumelelanga, uzocelwa ukuvula ithebhulethi yakho usebenzisa ukungena ngemvume kwi-Google."\n\n" Sicela uzame futhi emuva kwamasekhondi angu-<xliff:g id="NUMBER_2">%d</xliff:g>"</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Ukulayisha ungenisa iphathini yakho yokuvula ngendlela engalungile izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g> Emumva kweminye imizamo engu-<xliff:g id="NUMBER_1">%d</xliff:g>, uzocelwa ukuvula ifoni yakho usebenzisa ukungena ngemvume ku-Google"\n\n" Zame futhi emuva kwamasekhondi angu- <xliff:g id="NUMBER_2">%d</xliff:g>"</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Udwebe iphathini yakho yokuvula ngendlela engafanele izinkathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. \n\n Zama futhi emuva kwamasekhondi angu-<xliff:g id="NUMBER_1">%d</xliff:g>"</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Ubhale iphasiwedi yakho ngendlela engafanele <xliff:g id="NUMBER_0">%d</xliff:g> izikhathi. \n\nZama futhi <xliff:g id="NUMBER_1">%d</xliff:g> imizuzwna."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Ubhale i-PIN ykho ngendlela engafanele <xliff:g id="NUMBER_0">%d</xliff:g> izikhathi. \n\nZama futhi emuva kwamasekhondi angu-<xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Udwebe ngokungalungile iphathini yakho yokuvula izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. Emva <xliff:g id="NUMBER_1">%d</xliff:g> kweminye imizamo engaphumelelanga, uzocelwa ukuvula ithebhulethi yakho usebenzisa ukungena ngemvume kwi-Google.\n\n Sicela uzame futhi emuva kwamasekhondi angu-<xliff:g id="NUMBER_2">%d</xliff:g>"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Ukulayisha ungenisa iphathini yakho yokuvula ngendlela engalungile izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g> Emumva kweminye imizamo engu-<xliff:g id="NUMBER_1">%d</xliff:g>, uzocelwa ukuvula ifoni yakho usebenzisa ukungena ngemvume ku-Google\n\n Zame futhi emuva kwamasekhondi angu- <xliff:g id="NUMBER_2">%d</xliff:g>"</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Uzame ngokusebenzisa indlela engafanele ukuvula izikhathi <xliff:g id="NUMBER_0">%d</xliff:g> ze-tablet. Ngemuva <xliff:g id="NUMBER_1">%d</xliff:g> kokuzama kaningana okuyimpumelelo i-tablet izobuyela kwizimo zasembonini futhi yonke imininingo yomsebenzisi izolahleka."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Uzame ngokusebenzisa indlela engafanele ukuvula izikhathi <xliff:g id="NUMBER_0">%d</xliff:g> zocingo. Ngemuva <xliff:g id="NUMBER_1">%d</xliff:g> kokuzama kaningana ngaphandle kwempumelelo, ucingo luzobiyiselwa kwizimiso zasembonini futhi yonke imininingo yomsebenzisi izolahleka."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Uzame ukuvula ngendlela engafanele izikhathi <xliff:g id="NUMBER">%d</xliff:g> ze-tablet. I-tablet manje seyizosethwa kabusha ibe yizimiso zasembonini."</string>
@@ -826,7 +866,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Iphasiwedi"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Ngena"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Igama lomsebezisi elingalungile noma iphasiwedi."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Ukhohlwe igama lomsebenzisi noma iphasiwedi?"\n"Vakashela"<b>"google.com/accounts/recovery"</b></string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Ukhohlwe igama lomsebenzisi noma iphasiwedi?\nVakashela"<b>"google.com/accounts/recovery"</b></string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Iyahlola..."</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Vula"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Umsindo uvuliwe"</string>
@@ -874,7 +914,7 @@
     <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Qinisekisa ukuzulazula"</string>
     <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Phuma kuleli khasi"</string>
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Hlala kuleli khasi"</string>
-    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Ingabe uqinisekile ukuthi ufuna ukuzulazulela ngokuphuma kuleli khasi?"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nIngabe uqinisekile ukuthi ufuna ukuzulazulela ngokuphuma kuleli khasi?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Qinisekisa"</string>
     <string name="double_tap_toast" msgid="4595046515400268881">"Ithiphu: thepha kabili ukusondeza ngaphandle nangaphakathi."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Ukugcwalisa Ngokuzenzakalelayo"</string>
@@ -901,11 +941,11 @@
     <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Ivumela uhlelo lokusebenza ukushintsha umlando wamabhukhimakhi noma wesiphequluli alondolozwe kuthebhulethi yakho. Lokhu kungavumela uhlelo lokusebenza ukususa noma ukushintsha idatha yesiphequluli. Qaphela: le mvume kungenzeka ingaphoqelelwa iziphequluli ezivela eceleni noma ezinye izinhlelo zokusebenza ezinamandla okuphequlula iwebhu."</string>
     <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Ivumela uhlelo lokusebenza ukushintsha umlando wamabhukhimakhi noma wesiphequluli alondolozwe efonini yakho. Lokhu kungavumela uhlelo lokusebenza ukususa noma ukushintsha idatha yesiphequluli. Qaphela: le mvume kungenzeka ingaphoqelelwa iziphequluli ezivela eceleni noma ezinye izinhlelo zokusebenza ezinamandla okuphequlula iwebhu."</string>
     <string name="permlab_setAlarm" msgid="1379294556362091814">"setha i-alamu"</string>
-    <string name="permdesc_setAlarm" msgid="316392039157473848">"Ivumela insiza ukuthi isethe i-alamu ensizeni efkiwe ye-alamu. Ezinye izinsiza ze-alamu kungenzeka zingakusebenzisi lokho."</string>
+    <string name="permdesc_setAlarm" msgid="316392039157473848">"Ivumela uhlelo lokusebenza ukuthi isethe i-alamu ensizeni efkiwe ye-alamu. Ezinye izinhlelo zokusebenza ze-alamu kungenzeka zingakusebenzisi lokho."</string>
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"engeza imeyili yezwi"</string>
     <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Ivumela uhlelo lokusebenza ukwengeza imiyalezo kwibhokisi lakho lemeyili yezwi."</string>
     <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"Gugula izimvume zendawo Yesiphequluli"</string>
-    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Ivumela insiza ukuthi iguqule izimvume eziphathelene nezindawo Zesiphequluli. Izinsiza eziyingozi zingasebenzisa lokhu ukuvumela ukuvumela imininingwane yendawo kunoma imaphi amawebusayithi."</string>
+    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Ivumela uhlelo lokusebenza ukuthi iguqule izimvume eziphathelene nezindawo Zesiphequluli. Izuhlelo lokusebenza eziyingozi zingasebenzisa lokhu ukuvumela ukuvumela imininingwane yendawo kunoma imaphi amawebusayithi."</string>
     <string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"qinisekisa amaphakheji"</string>
     <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"Ivumela ukuthi isisetshenziswa siqinisekise ukuthi ngabe iphakheji iyafakeka."</string>
     <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"bopha okokuqinisekisa iphakheji"</string>
@@ -1074,40 +1114,40 @@
     <string name="alwaysUse" msgid="4583018368000610438">"Sebenzisa ngokuzenzakalelayo kulesenzo."</string>
     <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Susa izilungiselelo zesistimu; Izinhlelo zokusebenza &amp; Okulandiwe"</string>
     <string name="chooseActivity" msgid="7486876147751803333">"Khetha okufanele kwenziwe"</string>
-    <string name="chooseUsbActivity" msgid="6894748416073583509">"Kheth insiza yedivayisi ye-USB"</string>
-    <string name="noApplications" msgid="2991814273936504689">"Azikho izinsiza ezingenza lokhu"</string>
+    <string name="chooseUsbActivity" msgid="6894748416073583509">"Kheth uhlelo lokusebenza yedivayisi ye-USB"</string>
+    <string name="noApplications" msgid="2991814273936504689">"Azikho izinhlelo zokusebenza ezingenza lokhu"</string>
     <string name="aerr_title" msgid="1905800560317137752"></string>
     <string name="aerr_application" msgid="932628488013092776">"Ngeshwa, <xliff:g id="APPLICATION">%1$s</xliff:g> kumile."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Ngeshwa, uhlelo  <xliff:g id="PROCESS">%1$s</xliff:g> luvele lwama."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> ayiphenduli."\n\n"Ingabe ufuna ukuyivala?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Uhlelo <xliff:g id="ACTIVITY">%1$s</xliff:g> aluphenduli."\n\n"Ingabe ufuna ukuluvala?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> ayiphenduli.\n\nIngabe ufuna ukuyivala?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Uhlelo <xliff:g id="ACTIVITY">%1$s</xliff:g> aluphenduli.\n\nIngabe ufuna ukuluvala?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> ayiphenduli. Ingabe ufuna ukuyivala?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Inqubo <xliff:g id="PROCESS">%1$s</xliff:g> ayisabeli."\n\n"Ingabe ufuna ukuyivala?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Inqubo <xliff:g id="PROCESS">%1$s</xliff:g> ayisabeli.\n\nIngabe ufuna ukuyivala?"</string>
     <string name="force_close" msgid="8346072094521265605">"KULUNGILE"</string>
     <string name="report" msgid="4060218260984795706">"Umbiko"</string>
     <string name="wait" msgid="7147118217226317732">"Linda"</string>
-    <string name="webpage_unresponsive" msgid="3272758351138122503">"Leli khasi alisaphenduli."\n\n"Ingabe ufuna ukulivala na?"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Leli khasi alisaphenduli.\n\nIngabe ufuna ukulivala na?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Insiza idluliselwe phambili"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> iyasebenza."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> iqalisiwe."</string>
     <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Isilinganisi"</string>
     <string name="screen_compat_mode_show" msgid="4013878876486655892">"Bonisa njalo"</string>
-    <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Yenza ukuthi kuphinde kusebenze lokhu ezisethweni Zesistimue &gt; Izinsiza &gt; Kulayishiwe."</string>
+    <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Yenza kuphinde kusebenze kuzilungiselelo Zesistimue &gt; Izinhlelo zokusebenza &gt; Okulayishiwe."</string>
     <string name="smv_application" msgid="3307209192155442829">"Inqubo <xliff:g id="APPLICATION">%1$s</xliff:g> (yohlelo <xliff:g id="PROCESS">%2$s</xliff:g>) iphule inqubomgomo oziphoqelela yona Yemodi Ebukhali."</string>
     <string name="smv_process" msgid="5120397012047462446">"Inqubo <xliff:g id="PROCESS">%1$s</xliff:g> yephule inqubomgomo yokuziphoqelela Yemodi Ebukhali."</string>
     <string name="android_upgrading_title" msgid="1584192285441405746">"I-Android ifaka ezakamuva..."</string>
-    <string name="android_upgrading_apk" msgid="7904042682111526169">"Ukubeka ezingeni eliphezulu <xliff:g id="NUMBER_0">%1$d</xliff:g> insiza <xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
-    <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Qalisa izinsiza."</string>
+    <string name="android_upgrading_apk" msgid="7904042682111526169">"Ukubeka ezingeni eliphezulu <xliff:g id="NUMBER_0">%1$d</xliff:g> uhlelo lokusebenza <xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
+    <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Qalisa izinhlelo zokusebenza."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Qedela ukuqala kabusha."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> iyasebenza"</string>
     <string name="heavy_weight_notification_detail" msgid="1721681741617898865">"Thinta ukuguqukela ensizeni"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Shintsha izinsiza?"</string>
+    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Shintsha izinhlelo zokusebenza?"</string>
     <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Olunye uhlelo lokusebenza luvele luyasebenza lokho kumele kumiswe ngaphambi kokuba uqalise olusha."</string>
     <string name="old_app_action" msgid="493129172238566282">"Buyisela ku:<xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Ungayiqali insiza entsha."</string>
+    <string name="old_app_description" msgid="2082094275580358049">"Ungayiqali uhlelo lokusebenza entsha."</string>
     <string name="new_app_action" msgid="5472756926945440706">"Qala <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Misa insiza endala ngaphandle kokulondoloza."</string>
+    <string name="new_app_description" msgid="1932143598371537340">"Misa uhlelo lokusebenza endala ngaphandle kokulondoloza."</string>
     <string name="sendText" msgid="5209874571959469142">"Khetha okufanele kwenziwe okomqhafazo"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Ivolumu yesishayeli"</string>
     <string name="volume_music" msgid="5421651157138628171">"Ivolumu yemidiya"</string>
@@ -1202,7 +1242,7 @@
     <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"Vala isitoreji se-USB"</string>
     <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"Kube nenkinga yokuvala okokulondoloza kwe-USB. Hlola ukuqiniseka ukuthi wehlise isikhungo se-USB, bese uzama futhi."</string>
     <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Vula isitoreji se-USB"</string>
-    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Uma uvula okokulondoloza kwe-USB, ezinye izinsiza ozisebenzisayo ziyoma futhi kungenzeka zingatholakali kuze kube ucisha ukulondoloza kwe-USB."</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Uma uvula okokulondoloza kwe-USB, ezinye izinhlelo zokusebenza ozisebenzisayo ziyoma futhi kungenzeka zingatholakali kuze kube ucisha ukulondoloza kwe-USB."</string>
     <string name="dlg_error_title" msgid="7323658469626514207">"Ukusebenza kwe-USB kwehlulekile"</string>
     <string name="dlg_ok" msgid="7376953167039865701">"KULUNGILE"</string>
     <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Ixhunyiwe njengedivayisi yemidiya"</string>
@@ -1251,11 +1291,15 @@
     <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"Ikhadi le-SD likhishiwe. Faka elisha."</string>
     <string name="activity_list_empty" msgid="1675388330786841066">"Ayikho imisebenzi efanayo etholakele"</string>
     <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"buyekeza izibalo zokusebenzisa ingxenye"</string>
-    <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"Ivumela insiza ukuthi iguqule imininingwane yokusetshenziswa kokuqoqiwe. Akwenzelwe ukuthi kusetshenziswe izinsiza ezijwayelekile."</string>
+    <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"Ivumela uhlelo lokusebenza ukuthi iguqule imininingwane yokusetshenziswa kokuqoqiwe. Akwenzelwe ukuthi kusetshenziswe izinhlelo zokusebenza ezijwayelekile."</string>
     <string name="permlab_copyProtectedData" msgid="4341036311211406692">"Kopisha okuqukethwe"</string>
-    <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Ivumela insiza ukuthi inqabe okutholakala kukhona ukukopisha okuqukethwe. Akusetshenziswa izinsiza ezijwayelekile."</string>
+    <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Ivumela uhlelo lokusebenza ukuthi inqabe okutholakala kukhona ukukopisha okuqukethwe. Akusetshenziswa izinhlelo zokusebenza ezijwayelekile."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Yenza umzila wemidiya wokukhiphayo"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"Ivumela uhlelo lokusebenza ukwenza umzila wokukhiphayo wemidiya kuya kumadivayisi angaphandle."</string>
+    <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Finyelela kusitoreji esiqashwa ngesikhiya esiphephile"</string>
+    <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Ivumela uhlelo lokusebenza ukuthi lufinyelele kusitoreji esiqashwa ngesikhiya esiphephile."</string>
+    <string name="permlab_control_keyguard" msgid="172195184207828387">"Lawula ukubonisa nokufihla ukhiye wokuqapha"</string>
+    <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Ivumela uhlelo lokusebenza ukuthi lulawule ukhiye wokuqapha."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Thinta kabili ukulawula ukusondeza"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Yehlulekile ukwengeza i-widget."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Iya"</string>
@@ -1265,15 +1309,15 @@
     <string name="ime_action_done" msgid="8971516117910934605">"Kwenziwe"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Okwandulele"</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Ukwenza"</string>
-    <string name="dial_number_using" msgid="5789176425167573586">"Dayela inombolo"\n"usebenzisa <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="create_contact_using" msgid="4947405226788104538">"Yenza othintana naye"\n" usebenzisa <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Dayela inombolo\nusebenzisa <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Yenza othintana naye\n usebenzisa <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Izinhlelo zokusebenza ezilandelayo zicela imvume yokufinyelela i-akhawunti yakho, manje ngisho nasesikhathini esizayo."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Ingabe ufuna ukuvumela lesi sicelo?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Isicelo Sokufinyelela"</string>
     <string name="allow" msgid="7225948811296386551">"Vumela"</string>
     <string name="deny" msgid="2081879885755434506">"Yala"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Imvume Iceliwe"</string>
-    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Imvume Iceliwe "\n" ye-akhawunti <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Imvume Iceliwe \n ye-akhawunti <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Indlela yokufakwayo"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Vumelanisaa"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Ukufinyeleleka"</string>
@@ -1364,7 +1408,7 @@
     <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Ukushintsha kwendlela esetshenziswayo"</string>
     <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Beka kwenye indawo"</string>
     <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Faka"</string>
-    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Khetha insiza"</string>
+    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Khetha uhlelo lokusebenza"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Yabelana no"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Yabelana no <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Ihaambis isibambo. Thinta &amp; ubambe."</string>
@@ -1420,7 +1464,6 @@
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Buka konke"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Khetha okwenziwayo"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Yabelana no"</string>
-    <string name="status_bar_device_locked" msgid="3092703448690669768">"Idivayisi ivaliwe."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Iyathumela..."</string>
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Qala Isiphequluli?"</string>
@@ -1441,10 +1484,12 @@
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Iyaxhuma..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Kuyatholakala"</string>
     <string name="media_route_status_not_available" msgid="6739899962681886401">"Ayitholakali"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"Kuyasebenza"</string>
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Okwakhelwe ngaphakathi kwesikrini"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"Isikrini se-HDMI"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Isendlalelo #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", kuphephile"</string>
     <string name="wifi_display_notification_title" msgid="2223050649240326557">"Ukubukeka okungenantambo kuxhunyiwe"</string>
     <string name="wifi_display_notification_message" msgid="4498802012464170685">"Lesi sikrini siyabonakala kwenye idivayisi"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Nqamula"</string>
@@ -1453,7 +1498,7 @@
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Iphatheni engalungile"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Iphasiwedi engalungile"</string>
     <string name="kg_wrong_pin" msgid="1131306510833563801">"Iphinikhodi engalungile"</string>
-    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Zama futhi emasekhondini angu-<xliff:g id="NUMBER">%d</xliff:g>."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Zama futhi emasekhondini angu-<xliff:g id="NUMBER">%1$d</xliff:g>."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"Dweba iphethini"</string>
     <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Faka iphinikhodi ye-SIM"</string>
     <string name="kg_pin_instructions" msgid="2377242233495111557">"Faka iphinikhodi"</string>
@@ -1473,27 +1518,85 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Iphasiwedi"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Ngena ngemvume"</string>
     <string name="kg_login_invalid_input" msgid="5754664119319872197">"Igama lomsebezisi elingalungile noma iphasiwedi."</string>
-    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Ukhohlwe igama lomsebenzisi noma iphasiwedi?"\n"Vakashela"<b>"google.com/accounts/recovery"</b></string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Ukhohlwe igama lomsebenzisi noma iphasiwedi?\nVakashela"<b>"google.com/accounts/recovery"</b></string>
     <string name="kg_login_checking_password" msgid="1052685197710252395">"Ukuhlola i-akhawunti…"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Ubhale iphinikhodi ykho ngendlela engafanele izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n"Zama futhi emasekhondini angu-<xliff:g id="NUMBER_1">%d</xliff:g>."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Ubhale iphasiwedi yakho ngendlela engafanele <xliff:g id="NUMBER_0">%d</xliff:g> izikhathi. "\n\n"Zama futhi emasekhondini angu-<xliff:g id="NUMBER_1">%d</xliff:g>."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Udwebe iphathini yakho yokuvula ngendlela engafanele-<xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n" Zama futhi emasekhondini angu-<xliff:g id="NUMBER_1">%d</xliff:g>"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Ubhale iphinikhodi ykho ngendlela engafanele izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. \n\nZama futhi emasekhondini angu-<xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Ubhale iphasiwedi yakho ngendlela engafanele <xliff:g id="NUMBER_0">%d</xliff:g> izikhathi. \n\nZama futhi emasekhondini angu-<xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Udwebe iphathini yakho yokuvula ngendlela engafanele-<xliff:g id="NUMBER_0">%d</xliff:g>. \n\n Zama futhi emasekhondini angu-<xliff:g id="NUMBER_1">%d</xliff:g>"</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Uzame ngokusebenzisa indlela engafanele ukuvula ithebhulethi izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. Ngemuva kokuzama ngaphandle kwempumelelo okungu-<xliff:g id="NUMBER_1">%d</xliff:g>, ithebhulethi izobuyiselwa kwizimiso zasembonini futhi yonke imininingwane yomsebenzisi izolahleka."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Uzame ngokusebenzisa indlela engafanele ukuvula ifoni izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. Ngemuva kokuzama ngaphandle kwempumelelo okungu-<xliff:g id="NUMBER_1">%d</xliff:g>, ifoni izobuyiselwa kwizimiso zasembonini futhi yonke imininingwane yomsebenzisi izolahleka."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Uzame ukuvula ngendlela engafanele ifoni izikhathi ezingu-<xliff:g id="NUMBER">%d</xliff:g>. Ithebhulethi manje isizosethwa kabusha ibe yizimiso ezizenzakalelayo."</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Uzame ukuvula ngendlela engafanele ifoni izikhathi ezingu-<xliff:g id="NUMBER">%d</xliff:g>. Ifoni manje isizosethwa kabusha ibe yizimiso ezizenzakalelayo."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Udwebe ngokungalungile iphathini yakho yokuvula izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. Emva <xliff:g id="NUMBER_1">%d</xliff:g> kweminye imizamo engaphumelelanga, uzocelwa ukuvula ithebhulethi yakho usebenzisa ukungena ngemvume kwi-Google."\n\n" Sicela uzame futhi emuva kwamasekhondi angu-<xliff:g id="NUMBER_2">%d</xliff:g>"</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Ukulayisha ungenisa iphathini yakho yokuvula ngendlela engalungile izikhathi ezi-<xliff:g id="NUMBER_0">%d</xliff:g> Emva kweminye imizamo engu-<xliff:g id="NUMBER_1">%d</xliff:g>, uzocelwa ukuvula ifoni yakho usebenzisa ukungena ngemvume ku-Google"\n\n" Zame futhi emumva kwengu- <xliff:g id="NUMBER_2">%d</xliff:g> amasekhondi."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Udwebe ngokungalungile iphathini yakho yokuvula izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. Emva <xliff:g id="NUMBER_1">%d</xliff:g> kweminye imizamo engaphumelelanga, uzocelwa ukuvula ithebhulethi yakho usebenzisa ukungena ngemvume kwi-Google.\n\n Sicela uzame futhi emuva kwamasekhondi angu-<xliff:g id="NUMBER_2">%d</xliff:g>"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Ukulayisha ungenisa iphathini yakho yokuvula ngendlela engalungile izikhathi ezi-<xliff:g id="NUMBER_0">%d</xliff:g> Emva kweminye imizamo engu-<xliff:g id="NUMBER_1">%d</xliff:g>, uzocelwa ukuvula ifoni yakho usebenzisa ukungena ngemvume ku-Google\n\n Zame futhi emumva kwengu- <xliff:g id="NUMBER_2">%d</xliff:g> amasekhondi."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Susa"</string>
-    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Khulisa ivolomu ngaphezu kwezinga elinconyiwe?"\n"Ukulalela ngevolomu ephezulu izikhathi ezinde kungalimaza ukuzwa kwakho."</string>
+    <string name="safe_media_volume_warning" product="default" msgid="7324161939475478066">"Khulisa ivolomu ngaphezu kwezinga elinconyiwe?\nUkulalela ngevolomu ephezulu izikhathi ezinde kungalimaza ukuzwa kwakho."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Gcina ucindezele iminwe yakho emibili ukuze unike amandla ukufinyelela."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Ukufinyelela kunikwe amandla."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Ukufinyelela kukhanseliwe."</string>
     <string name="user_switched" msgid="3768006783166984410">"Umsebenzisi wamanje <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="owner_name" msgid="2716755460376028154">"Umnikazi"</string>
     <string name="error_message_title" msgid="4510373083082500195">"Iphutha"</string>
-    <string name="app_no_restricted_accounts" msgid="4011285085817350390">"Lolu hlelo lokusebenza alusekeli ama-akhawunti wamaphrofayela akhawulelwe"</string>
+    <string name="app_no_restricted_accounts" msgid="5739463249673727736">"Lolu hlelo lokusebenza alusekeli ama-akhawunti wamaphrofayela akhawulelwe"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Alukho uhlelo lokusebenza olutholakele lokuphatha lesi senzo"</string>
     <string name="revoke" msgid="5404479185228271586">"Chitha"</string>
+    <string name="mediaSize_iso_a0" msgid="7875427489420821793">"I-ISO A0"</string>
+    <string name="mediaSize_iso_a1" msgid="3760734499050875356">"I-ISO A1"</string>
+    <string name="mediaSize_iso_a2" msgid="5973266378020144382">"I-ISO A2"</string>
+    <string name="mediaSize_iso_a3" msgid="1373407105687300884">"I-ISO A3"</string>
+    <string name="mediaSize_iso_a4" msgid="6689772807982597254">"I-ISO A4"</string>
+    <string name="mediaSize_iso_a5" msgid="5353549652015741040">"I-ISO A5"</string>
+    <string name="mediaSize_iso_a6" msgid="8585038048674911907">"I-ISO A6"</string>
+    <string name="mediaSize_iso_a7" msgid="6641836716963839119">"I-ISO A7"</string>
+    <string name="mediaSize_iso_a8" msgid="7571139437465693355">"I-ISO A8"</string>
+    <string name="mediaSize_iso_a9" msgid="1378455891957115079">"I-ISO A9"</string>
+    <string name="mediaSize_iso_a10" msgid="2480747457429475344">"I-ISO A10"</string>
+    <string name="mediaSize_iso_b0" msgid="3965935097661108039">"I-ISO B0"</string>
+    <string name="mediaSize_iso_b1" msgid="2505753285010115437">"I-ISO B1"</string>
+    <string name="mediaSize_iso_b2" msgid="8763874709859458453">"I-ISO B2"</string>
+    <string name="mediaSize_iso_b3" msgid="4210506688191764076">"I-ISO B3"</string>
+    <string name="mediaSize_iso_b4" msgid="5749404165888526034">"I-ISO B4"</string>
+    <string name="mediaSize_iso_b5" msgid="7640627414621904733">"I-ISO B5"</string>
+    <string name="mediaSize_iso_b6" msgid="7342988864712748544">"I-ISO B6"</string>
+    <string name="mediaSize_iso_b7" msgid="5069844065235382429">"I-ISO B7"</string>
+    <string name="mediaSize_iso_b8" msgid="7316818922278779774">"I-ISO B8"</string>
+    <string name="mediaSize_iso_b9" msgid="5414727094026532341">"I-ISO B9"</string>
+    <string name="mediaSize_iso_b10" msgid="5251253731832048185">"I-ISO B10"</string>
+    <string name="mediaSize_iso_c0" msgid="4003138342671964217">"I-ISO C0"</string>
+    <string name="mediaSize_iso_c1" msgid="1935188063393553008">"I-ISO C1"</string>
+    <string name="mediaSize_iso_c2" msgid="3197307969712069904">"I-ISO C2"</string>
+    <string name="mediaSize_iso_c3" msgid="4335826087321913508">"I-ISO C3"</string>
+    <string name="mediaSize_iso_c4" msgid="3745639598281015005">"I-ISO C4"</string>
+    <string name="mediaSize_iso_c5" msgid="8269457765822791013">"I-ISO C5"</string>
+    <string name="mediaSize_iso_c6" msgid="566666105260346930">"I-ISO C6"</string>
+    <string name="mediaSize_iso_c7" msgid="8678413180782608498">"I-ISO C7"</string>
+    <string name="mediaSize_iso_c8" msgid="8392376206627041730">"I-ISO C8"</string>
+    <string name="mediaSize_iso_c9" msgid="9191613372324845405">"I-ISO C9"</string>
+    <string name="mediaSize_iso_c10" msgid="7327709699184920822">"I-ISO C10"</string>
+    <string name="mediaSize_na_letter" msgid="4191805615829472953">"Incwadi"</string>
+    <string name="mediaSize_na_gvrnmt_letter" msgid="7853382192649405507">"Incwadi kahulumeni"</string>
+    <string name="mediaSize_na_legal" msgid="6697982988283823150">"Okusemthethweni"</string>
+    <string name="mediaSize_na_junior_legal" msgid="3727743969902758948">"Ezomthetho ezincane"</string>
+    <string name="mediaSize_na_ledger" msgid="281871464896601236">"Ileja"</string>
+    <string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Iphephandaba"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Kukhanseliwe"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Iphutha ekubhaleni okuqukethwe"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"akwaziwa"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Faka i-PIN yomlawuli"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Faka i-PIN"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Ayilungile"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"I-PIN yamanje"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"I-PIN entsha"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Qinisekisa i-PIN entsha"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Dala i-PIN yemikhawulo yokushintsha"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"Ama-PIN awafani. Zama futhi."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"I-PIN yimfushane kakhulu. Okungenani kumele ibe namadijithi angu-4."</string>
+  <plurals name="restr_pin_countdown">
+    <item quantity="one" msgid="311050995198548675">"Zama futhi kusekhondi elingu-1"</item>
+    <item quantity="other" msgid="4730868920742952817">"Zama futhi kumasekhondi angu-<xliff:g id="COUNT">%d</xliff:g>"</item>
+  </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Zama futhi emva kwesikhathi"</string>
+    <string name="transient_navigation_confirmation" msgid="4907844043611123426">"Swayipha emaphethelweni wesikrini ukuze uveze ibha"</string>
+    <string name="transient_navigation_confirmation_long" msgid="8061685920508086697">"Swayipha kusukela emaphethelweni wesikrini ukuze uveze ibha yesistimu"</string>
 </resources>
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index 146607e..ef30b98 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -346,75 +346,4 @@
         <item>中文 (繁體)</item>
     </string-array>
 
-    <!-- Resources for GlowPadView in LockScreen -->
-    <array name="lockscreen_targets_when_silent">
-        <item>@drawable/ic_lockscreen_unlock</item>
-        <item>@drawable/ic_action_assist_generic</item>
-        <item>@drawable/ic_lockscreen_soundon</item>
-        <item>@null</item>
-    </array>
-
-    <array name="lockscreen_target_descriptions_when_silent">
-        <item>@string/description_target_unlock</item>
-        <item>@string/description_target_search</item>
-        <item>@string/description_target_soundon</item>
-        <item>@null</item>
-    </array>
-
-    <array name="lockscreen_direction_descriptions">
-        <item>@string/description_direction_right</item>
-        <item>@string/description_direction_up</item>
-        <item>@string/description_direction_left</item>
-        <item>@null</item>
-    </array>
-
-    <array name="lockscreen_targets_when_soundon">
-        <item>@drawable/ic_lockscreen_unlock</item>
-        <item>@drawable/ic_action_assist_generic</item>
-        <item>@drawable/ic_lockscreen_silent</item>
-        <item>@null</item>
-    </array>
-
-    <array name="lockscreen_target_descriptions_when_soundon">
-        <item>@string/description_target_unlock</item>
-        <item>@string/description_target_search</item>
-        <item>@string/description_target_silent</item>
-        <item>@null</item>
-    </array>
-
-    <array name="lockscreen_targets_with_camera">
-        <item>@drawable/ic_lockscreen_unlock</item>
-        <item>@drawable/ic_action_assist_generic</item>
-        <item>@drawable/ic_lockscreen_camera</item>
-        <item>@null</item>
-    </array>
-
-    <array name="lockscreen_target_descriptions_with_camera">
-        <item>@string/description_target_unlock</item>
-        <item>@string/description_target_search</item>
-        <item>@string/description_target_camera</item>
-        <item>@null</item>
-    </array>
-
-    <array name="lockscreen_targets_unlock_only">
-        <item>@*android:drawable/ic_lockscreen_unlock</item>
-    </array>
-
-    <array name="lockscreen_target_descriptions_unlock_only">
-        <item>@*android:string/description_target_unlock</item>
-    </array>
-
-    <!-- list of 3- or 4-letter mnemonics for a 10-key numeric keypad -->
-    <string-array translatable="false" name="lockscreen_num_pad_klondike">
-        <item></item><!-- 0 -->
-        <item></item><!-- 1 -->
-        <item>ABC</item><!-- 2 -->
-        <item>DEF</item><!-- 3 -->
-        <item>GHI</item><!-- 4 -->
-        <item>JKL</item><!-- 5 -->
-        <item>MNO</item><!-- 6 -->
-        <item>PQRS</item><!-- 7 -->
-        <item>TUV</item><!-- 8 -->
-        <item>WXYZ</item><!-- 9 -->
-    </string-array>
 </resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 4dcbaec..275afb8 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -737,6 +737,14 @@
         <attr name="preferenceLayoutChild" format="reference" />
         <!-- Preference panel style -->
         <attr name="preferencePanelStyle" format="reference" />
+        <!-- Preference headers panel style -->
+        <attr name="preferenceHeaderPanelStyle" format="reference" />
+        <!-- Preference list style -->
+        <attr name="preferenceListStyle" format="reference" />
+        <!-- Preference fragment list style -->
+        <attr name="preferenceFragmentListStyle" format="reference" />
+        <!-- Preference fragment padding side -->
+        <attr name="preferenceFragmentPaddingSide" format="dimension" />
         <!-- Default style for switch preferences. -->
         <attr name="switchPreferenceStyle" format="reference" />
 
@@ -1550,6 +1558,7 @@
         <enum name="KEYCODE_ASSIST" value="219" />
         <enum name="KEYCODE_BRIGHTNESS_DOWN" value="220" />
         <enum name="KEYCODE_BRIGHTNESS_UP" value="221" />
+        <enum name="KEYCODE_MEDIA_AUDIO_TRACK" value="222" />
     </attr>
 
     <!-- ***************************************************************** -->
@@ -2175,6 +2184,18 @@
             <enum name="no" value="2" />
         </attr>
 
+        <!-- Indicates to accessibility services whether the user should be notified when
+             this view changes. -->
+        <attr name="accessibilityLiveRegion" format="integer">
+            <!-- Accessibility services should not announce changes to this view. -->
+            <enum name="none" value="0" />
+            <!-- Accessibility services should announce changes to this view. -->
+            <enum name="polite" value="1" />
+            <!-- Accessibility services should interrupt ongoing speech to immediately
+                 announce changes to this view. -->
+            <enum name="assertive" value="2" />
+        </attr>
+
         <!-- Specifies the id of a view for which this view serves as a label for
              accessibility purposes. For example, a TextView before an EditText in
              the UI usually specifies what infomation is contained in the EditText.
@@ -2369,6 +2390,15 @@
         <!-- Set to true in all of the configurations for which this input
              method should be considered an option as the default. -->
         <attr name="isDefault" format="boolean" />
+        <!-- Set to true if this input method supports ways to switch to
+             a next input method (e.g. a globe key.). When this is true and
+             InputMethodManager#shouldOfferSwitchingToNextInputMethod() returns true,
+             the IME has to offer ways to to invoke InputMethodManager#switchToNextInputMethod()
+             accordingly.
+             <p> Note that the system determines the most appropriate next input method
+             and subtype in order to provide the consistent user experience in switching
+             between IMEs and subtypes. -->
+        <attr name="supportsSwitchingToNextInputMethod" format="boolean" />
     </declare-styleable>
 
     <!-- This is the subtype of InputMethod. Subtype can describe locales (e.g. en_US, fr_FR...)
@@ -2406,6 +2436,11 @@
              constructor or 0. Arrays.hashCode(new Object[] {locale, mode, extraValue,
              isAuxiliary, overridesImplicitlyEnabledSubtype}) will be used instead. -->
         <attr name="subtypeId" format="integer"/>
+        <!-- Set to true if this subtype is ASCII capable. If the subtype is ASCII
+             capable, it should guarantee that the user can input ASCII characters with
+             this subtype. This is important because many password fields only allow
+             ASCII-characters. -->
+        <attr name="isAsciiCapable" format="boolean" />
     </declare-styleable>
 
     <!-- Use <code>spell-checker</code> as the root tag of the XML resource that
@@ -2562,6 +2597,74 @@
         <attr name="description" />
     </declare-styleable>
 
+    <!-- Use <code>print-service</code> as the root tag of the XML resource that
+         describes an {@link android.printservice.PrintService} service, which is
+         referenced from its {@link android.printservice.PrintService#SERVICE_META_DATA}
+         meta-data entry. -->
+    <declare-styleable name="PrintService">
+        <!-- Fully qualified class name of an activity that allows the user to modify
+             the settings for this service. -->
+        <attr name="settingsActivity" />
+        <!-- Fully qualified class name of an activity that allows the user to manually
+             add printers to this print service. -->
+        <attr name="addPrintersActivity" format="string"/>
+        <!-- The vendor name if this print service is vendor specific. -->
+        <attr name="vendor" format="string"/>
+    </declare-styleable>
+
+    <!-- Use <code>host-apdu-service</code> as the root tag of the XML resource that
+         describes an {@link android.nfc.cardemulation.HostApduService} service, which
+         is referenced from its {@link android.nfc.cardemulation.HostApduService#SERVICE_META_DATA}
+         entry. -->
+    <declare-styleable name="HostApduService">
+        <!-- Short description of the functionality the service implements. This attribute
+             is mandatory.-->
+        <attr name="description" />
+        <!-- Whether the device must be unlocked before routing data to this service.
+             The default is false.-->
+        <attr name="requireDeviceUnlock" format="boolean"/>
+        <!-- A drawable that can be rendered in Android's system UI for representing
+             the service. -->
+        <attr name="apduServiceBanner" format="reference"/>
+    </declare-styleable>
+
+    <!-- Use <code>offhost-apdu-service</code> as the root tag of the XML resource that
+         describes an {@link android.nfc.cardemulation.OffHostApduService}
+         service, which is referenced from its
+         {@link android.nfc.cardemulation.OffHostApduService#SERVICE_META_DATA} entry. -->
+    <declare-styleable name="OffHostApduService">
+        <!-- Short description of the functionality the service implements. This attribute
+             is mandatory.-->
+        <attr name="description" />
+        <!-- A drawable that can be rendered in Android's system UI for representing
+             the service. -->
+        <attr name="apduServiceBanner"/>
+    </declare-styleable>
+
+    <!-- Specify one or more <code>aid-group</code> elements inside a
+         <code>host-apdu-service</code> or <code>offhost-apdu-service</code>
+         element to define a group of ISO7816 Application ID (AIDs) that
+         your service can handle.-->
+    <declare-styleable name="AidGroup">
+        <!-- Short description of what the AID group implements. This attribute is mandatory.-->
+        <attr name="description" />
+        <!-- The category attribute will be used by the Android platform to present
+             multiple applications that register ISO 7816 Application IDs (AIDs) in the
+             same category uniformly.
+             Additionally, when a category is specified, Android will ensure that either
+             all AIDs in this group are routed to this application, or none at all.
+             This attribute is optional.-->
+        <attr name="category" format="string" />
+    </declare-styleable>
+
+    <!-- Specify one or more <code>aid-filter</code> elements inside a
+         <code>aid-group</code> element to specify an ISO7816 Application ID (AID)
+         your service can handle. -->
+    <declare-styleable name="AidFilter">
+        <!-- The ISO7816 Application ID. This attribute is mandatory. -->
+        <attr name="name" />
+    </declare-styleable>
+
     <declare-styleable name="ActionMenuItemView">
         <attr name="minWidth" />
     </declare-styleable>
@@ -3852,6 +3955,10 @@
              value is false.  See
              {@link android.graphics.drawable.Drawable#setVisible}. -->
         <attr name="visible" format="boolean" />
+        <!-- Indicates if the drawable needs to be mirrored when its layout direction is
+             RTL (right-to-left).  See
+             {@link android.graphics.drawable.Drawable#setAutoMirrored}. -->
+        <attr name="autoMirrored" format="boolean" />
     </declare-styleable>
 
     <!-- Drawable used to render several states. Each state is represented by
@@ -3879,6 +3986,9 @@
         <attr name="enterFadeDuration" format="integer" />
         <!-- Amount of time (in milliseconds) to fade out an old state drawable. -->
         <attr name="exitFadeDuration" format="integer" />
+        <!-- Indicates if the drawable needs to be mirrored when its layout direction is
+             RTL (right-to-left). -->
+        <attr name="autoMirrored"/>
     </declare-styleable>
 
     <!-- Drawable used to render several animated frames. -->
@@ -4030,6 +4140,9 @@
             <!-- The layer has translucent pixels. -->
             <enum name="translucent" value="-3" />
         </attr>
+        <!-- Indicates if the drawable needs to be mirrored when its layout direction is
+             RTL (right-to-left). -->
+        <attr name="autoMirrored" />
     </declare-styleable>
 
     <!-- Describes an item (or child) of a LayerDrawable. -->
@@ -4057,10 +4170,6 @@
         <attr name="drawable" />
     </declare-styleable>
 
-    <declare-styleable name="MipmapDrawableItem">
-        <attr name="drawable" />
-    </declare-styleable>
-
     <!-- Drawable used to rotate another drawable. -->
     <declare-styleable name="RotateDrawable">
         <attr name="visible" />
@@ -4123,6 +4232,9 @@
             {@link android.graphics.Bitmap#setHasMipMap(boolean)} for more information.
             Default value is false. -->
         <attr name="mipMap" format="boolean" />
+        <!-- Indicates if the drawable needs to be mirrored when its layout direction is
+             RTL (right-to-left). -->
+        <attr name="autoMirrored" />
     </declare-styleable>
 
     <!-- Drawable used to draw 9-patches. -->
@@ -4133,6 +4245,9 @@
              same pixel configuration as the screen (for instance: a ARGB 8888 bitmap with
              an RGB 565 screen). -->
         <attr name="dither" />
+        <!-- Indicates if the drawable needs to be mirrored when its layout direction is
+             RTL (right-to-left). -->
+        <attr name="autoMirrored" />
     </declare-styleable>
 
     <!-- Drawable used to draw a single color. -->
@@ -4408,6 +4523,75 @@
     </declare-styleable>
 
     <!-- ========================== -->
+    <!-- Transition attributes -->
+    <!-- ========================== -->
+    <eat-comment />
+
+    <!-- Use specific transition subclass names as the root tag of the XML resource that
+         describes a {@link android.transition.Transition Transition},
+         such as <code>move</code>, <code>fade</code>, and <code>set</code>. -->
+    <declare-styleable name="Transition">
+        <!-- Amount of time (in milliseconds) that the transition should run. -->
+        <attr name="duration" />
+        <!-- Delay in milliseconds before the transition starts. -->
+        <attr name="startDelay" format="integer" />
+        <!-- Interpolator to be used in the animations spawned by this transition. -->
+        <attr name="interpolator" />
+    </declare-styleable>
+
+    <!-- Use <code>fade</code>as the root tag of the XML resource that
+         describes a {@link android.transition.Fade Fade} transition.
+         The attributes of the {@link android.R.styleable#Transition Transition}
+         resource are available in addition to the specific attributes of Fade
+         described here. -->
+    <declare-styleable name="Fade">
+        <attr name="fadingMode">
+            <!-- Fade will only fade appearing items in. -->
+            <enum name="fade_in" value="1" />
+            <!-- Fade will only fade disappearing items out. -->
+            <enum name="fade_out" value="2" />
+            <!-- Fade will fade appearing items in and disappearing items out. -->
+            <enum name="fade_in_out" value="3" />
+        </attr>
+    </declare-styleable>
+
+    <!-- Use <code>target</code> as the root tag of the XML resource that
+     describes a {@link android.transition.Transition#addTarget(int)
+     targetId} of a transition. There can be one or more targets inside
+     a <code>targets</code> tag, which is itself inside an appropriate
+     {@link android.R.styleable#Transition Transition} tag.
+     -->
+    <declare-styleable name="TransitionTarget">
+        <!-- The id of a target on which this transition will animate changes. -->
+        <attr name="targetId" format="reference" />
+    </declare-styleable>
+
+    <!-- Use <code>set</code> as the root tag of the XML resource that
+         describes a {@link android.transition.TransitionSet
+         TransitionSet} transition. -->
+    <declare-styleable name="TransitionSet">
+        <attr name="transitionOrdering">
+            <!-- child transitions should be played together. -->
+            <enum name="together" value="0" />
+            <!-- child transitions should be played sequentially, in the same order
+            as the xml. -->
+            <enum name="sequential" value="1" />
+        </attr>
+    </declare-styleable>
+
+    <!-- Use <code>transitionManager</code> as the root tag of the XML resource that
+         describes a {@link android.transition.TransitionManager
+         TransitionManager}. -->
+    <declare-styleable name="TransitionManager">
+        <!-- The id of a transition to be used in a particular scene change. -->
+        <attr name="transition" format="reference" />
+        <!-- The originating scene in this scene change. -->
+        <attr name="fromScene" format="reference" />
+        <!-- The destination scene in this scene change. -->
+        <attr name="toScene" format="reference" />
+    </declare-styleable>
+
+    <!-- ========================== -->
     <!-- ValueAnimator class attributes -->
     <!-- ========================== -->
     <eat-comment />
@@ -5622,6 +5806,25 @@
     <declare-styleable name="SizeAdaptiveLayout" />
 
     <!-- =============================== -->
+    <!-- Location package class attributes -->
+    <!-- =============================== -->
+    <eat-comment />
+
+    <!-- Use <code>injected-location-setting</code> as the root tag of the XML resource that
+         describes an injected "Location services" setting. Note that the status value (subtitle)
+         for the setting is specified dynamically by a subclass of SettingInjectorService.
+     -->
+    <declare-styleable name="SettingInjectorService">
+        <!-- The title for the preference. -->
+        <attr name="title"/>
+        <!-- The icon for the preference, should refer to all apps covered by the setting. Typically
+             a generic icon for the developer. -->
+        <attr name="icon"/>
+        <!-- The activity to launch when the setting is clicked on. -->
+        <attr name="settingsActivity"/>
+    </declare-styleable>
+
+    <!-- =============================== -->
     <!-- LockPatternView class attributes -->
     <!-- =============================== -->
     <eat-comment />
@@ -5936,4 +6139,5 @@
         <attr name="digit" format="integer" />
         <attr name="textView" format="reference" />
     </declare-styleable>
+
 </resources>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index e7f6c53..d2ada7a 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1624,6 +1624,27 @@
              case-sensitive, unlike the formal RFC.  As a result,
              schemes here should always use lower case letters.</em></p> -->
         <attr name="scheme" format="string" />
+        <!-- Specify a URI scheme specific part that must exactly match, as per
+             {@link android.content.IntentFilter#addDataSchemeSpecificPart
+             IntentFilter.addDataSchemeSpecificPart()} with
+             {@link android.os.PatternMatcher#PATTERN_LITERAL}. -->
+        <attr name="ssp" format="string" />
+        <!-- Specify a URI scheme specific part that must be a prefix to match, as per
+             {@link android.content.IntentFilter#addDataSchemeSpecificPart
+             IntentFilter.addDataSchemeSpecificPart()} with
+             {@link android.os.PatternMatcher#PATTERN_PREFIX}. -->
+        <attr name="sspPrefix" format="string" />
+        <!-- Specify a URI scheme specific part that matches a simple pattern, as per
+             {@link android.content.IntentFilter#addDataSchemeSpecificPart
+             IntentFilter.addDataSchemeSpecificPart()} with
+             {@link android.os.PatternMatcher#PATTERN_SIMPLE_GLOB}.
+             Note that because '\' is used as an escape character when
+             reading the string from XML (before it is parsed as a pattern),
+             you will need to double-escape: for example a literal "*" would
+             be written as "\\*" and a literal "\" would be written as
+             "\\\\".  This is basically the same as what you would need to
+             write if constructing the string in Java code. -->
+        <attr name="sspPattern" format="string" />
         <!-- Specify a URI authority host that is handled, as per
              {@link android.content.IntentFilter#addDataAuthority
              IntentFilter.addDataAuthority()}.
@@ -1638,17 +1659,17 @@
         <attr name="port" format="string" />
         <!-- Specify a URI path that must exactly match, as per
              {@link android.content.IntentFilter#addDataPath
-             IntentFilter.addDataAuthority()} with
+             IntentFilter.addDataPath()} with
              {@link android.os.PatternMatcher#PATTERN_LITERAL}. -->
         <attr name="path" />
         <!-- Specify a URI path that must be a prefix to match, as per
              {@link android.content.IntentFilter#addDataPath
-             IntentFilter.addDataAuthority()} with
+             IntentFilter.addDataPath()} with
              {@link android.os.PatternMatcher#PATTERN_PREFIX}. -->
         <attr name="pathPrefix" />
         <!-- Specify a URI path that matches a simple pattern, as per
              {@link android.content.IntentFilter#addDataPath
-             IntentFilter.addDataAuthority()} with
+             IntentFilter.addDataPath()} with
              {@link android.os.PatternMatcher#PATTERN_SIMPLE_GLOB}. 
              Note that because '\' is used as an escape character when
              reading the string from XML (before it is parsed as a pattern),
@@ -1694,20 +1715,20 @@
     
     <!-- Attributes that can be supplied in an AndroidManifest.xml
          <code>screen</code> tag, a child of <code>compatible-screens</code>,
-         which is itseld a child of the root
+         which is itself a child of the root
          {@link #AndroidManifest manifest} tag. -->
     <declare-styleable name="AndroidManifestCompatibleScreensScreen"
                        parent="AndroidManifest.AndroidManifestCompatibleScreens">
         <!-- Specifies a compatible screen size, as per the device
              configuration screen size bins. -->
         <attr name="screenSize">
-            <!-- A small screen configuration, at least 240x320db. -->
+            <!-- A small screen configuration, at least 240x320dp. -->
             <enum name="small" value="200" />
-            <!-- A normal screen configuration, at least 320x480db. -->
+            <!-- A normal screen configuration, at least 320x480dp. -->
             <enum name="normal" value="300" />
-            <!-- A large screen configuration, at least 400x530db. -->
+            <!-- A large screen configuration, at least 400x530dp. -->
             <enum name="large" value="400" />
-            <!-- An extra large screen configuration, at least 600x800db. -->
+            <!-- An extra large screen configuration, at least 600x800dp. -->
             <enum name="xlarge" value="500" />
         </attr>
         <!-- Specifies a compatible screen density, as per the device
@@ -1724,6 +1745,19 @@
         </attr>
     </declare-styleable>
 
+    <!-- The <code>input-type</code> tag is a child of the <code>supports-input</code> tag, which
+         is itself a child of the root {@link #AndroidManifest manifest} tag. Each
+         <code>input-type</code> tag specifices the name of a specific input device type. When
+         grouped with the other elements of the parent <code>supports-input</code> tag it defines
+         a collection of input devices, which when all used together, are considered a supported
+         input mechanism for the application. There may be multiple <code>supports-input</code>
+         tags defined, each containing a different combination of input device types. -->
+    <declare-styleable name="AndroidManifestSupportsInputInputType"
+                       parent="AndroidManifest.AndroidManifestSupportsInput">
+        <!-- Specifices the name of the input device type -->
+        <attr name="name" />
+    </declare-styleable>
+
     <!-- The attribute that holds a Base64-encoded public key. -->
     <attr name="publicKey" format="string" />
 
@@ -1781,4 +1815,12 @@
         <!-- Concrete value to put for this named extra data. -->
         <attr name="value" />
     </declare-styleable>
+
+    <attr name="keyset" />
+    <declare-styleable name="PublicKey">
+        <attr name="value" />
+    </declare-styleable>
+    <declare-styleable name="KeySet">
+        <attr name="name" />
+    </declare-styleable>
 </resources>
diff --git a/core/res/res/values/bools.xml b/core/res/res/values/bools.xml
index 18e4f2f..10a5d85 100644
--- a/core/res/res/values/bools.xml
+++ b/core/res/res/values/bools.xml
@@ -26,4 +26,5 @@
     <bool name="show_ongoing_ime_switcher">true</bool>
     <bool name="action_bar_expanded_action_views_exclusive">true</bool>
     <bool name="target_honeycomb_needs_options_menu">true</bool>
+    <bool name="flip_controller_fallback_keys">false</bool>
 </resources>
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 604bf4b..284f613 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -195,5 +195,7 @@
     <color name="keyguard_avatar_frame_shadow_color">#80000000</color>
     <color name="keyguard_avatar_nick_color">#ffffffff</color>
     <color name="keyguard_avatar_frame_pressed_color">#ff35b5e5</color>
+
+    <color name="accessibility_focus_highlight">#80ffff00</color>
 </resources>
 
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 440ee0f..d4b834a 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -26,7 +26,7 @@
        <item><xliff:g id="id">ime</xliff:g></item>
        <item><xliff:g id="id">sync_failing</xliff:g></item>
        <item><xliff:g id="id">sync_active</xliff:g></item>
-       <item><xliff:g id="id">gps</xliff:g></item>
+       <item><xliff:g id="id">location</xliff:g></item>
        <item><xliff:g id="id">bluetooth</xliff:g></item>
        <item><xliff:g id="id">nfc</xliff:g></item>
        <item><xliff:g id="id">tty</xliff:g></item>
@@ -123,6 +123,49 @@
          of them.  This should not normally be modified. -->
     <bool name="config_closeDialogWhenTouchOutside">true</bool>
 
+    <!-- Device configuration indicating whether we should avoid using accelerated graphics
+         in certain places to reduce RAM footprint.  This is ignored if ro.config.low_ram
+         is true (in that case this is assumed true as well).  It can allow you to tune down
+         your device's memory use without going to the point of causing applications to turn
+         off features. -->
+    <bool name="config_avoidGfxAccel">false</bool>
+
+    <!-- Device configuration setting the minfree tunable in the lowmemorykiller in the kernel.
+         A high value will cause the lowmemorykiller to fire earlier, keeping more memory
+         in the file cache and preventing I/O thrashing, but allowing fewer processes to
+         stay in memory.  A low value will keep more processes in memory but may cause
+         thrashing if set too low.  Overrides the default value chosen by ActivityManager
+         based on screen size and total memory for the largest lowmemorykiller bucket, and
+         scaled proportionally to the smaller buckets.  -1 keeps the default. -->
+    <integer name="config_lowMemoryKillerMinFreeKbytesAbsolute">-1</integer>
+
+    <!-- Device configuration adjusting the minfree tunable in the lowmemorykiller in the
+         kernel.  A high value will cause the lowmemorykiller to fire earlier, keeping more
+         memory in the file cache and preventing I/O thrashing, but allowing fewer processes
+         to stay in memory.  A low value will keep more processes in memory but may cause
+         thrashing if set too low.  Directly added to the default value chosen by
+         ActivityManager based on screen size and total memory for the largest lowmemorykiller
+         bucket, and scaled proportionally to the smaller buckets. 0 keeps the default. -->
+    <integer name="config_lowMemoryKillerMinFreeKbytesAdjust">0</integer>
+
+    <!-- Device configuration setting the /proc/sys/vm/extra_free_kbytes tunable in the kernel
+         (if it exists).  A high value will increase the amount of memory that the kernel
+         tries to keep free, reducing allocation time and causing the lowmemorykiller to kill
+         earlier.  A low value allows more memory to be used by processes but may cause more
+         allocations to block waiting on disk I/O or lowmemorykiller.  Overrides the default
+         value chosen by ActivityManager based on screen size.  0 prevents keeping any extra
+         memory over what the kernel keeps by default.  -1 keeps the default. -->
+    <integer name="config_extraFreeKbytesAbsolute">-1</integer>
+
+    <!-- Device configuration adjusting the /proc/sys/vm/extra_free_kbytes tunable in the kernel
+         (if it exists).  0 uses the default value chosen by ActivityManager.  A positive value
+         will increase the amount of memory that the kernel tries to keep free, reducing
+         allocation time and causing the lowmemorykiller to kill earlier.  A negative value
+         allows more memory to be used by processes but may cause more allocations to block
+         waiting on disk I/O or lowmemorykiller.  Directly added to the default value chosen by
+         ActivityManager based on screen size. -->
+    <integer name="config_extraFreeKbytesAdjust">0</integer>
+
     <!-- The duration (in milliseconds) that the radio will scan for a signal
          when there's no network connection. If the scan doesn't timeout, use zero -->
     <integer name="config_radioScanningTimeout">0</integer>
@@ -149,6 +192,7 @@
         <item>"mobile_ims,11,0,2,60000,true"</item>
         <item>"mobile_cbs,12,0,2,60000,true"</item>
         <item>"wifi_p2p,13,1,0,-1,true"</item>
+        <item>"mobile_ia,14,0,2,-1,true"</item>
     </string-array>
 
     <!-- Array of ConnectivityManager.TYPE_xxxx constants for networks that may only
@@ -157,6 +201,7 @@
         <item>10</item>
         <item>11</item>
         <item>12</item>
+        <item>14</item>
     </integer-array>
 
     <!-- This string array should be overridden by the device to present a list of radio
@@ -179,6 +224,7 @@
         <item>10</item> <!-- TYPE_MOBILE_FOTA -->
         <item>11</item> <!-- TYPE_MOBILE_IMS -->
         <item>12</item> <!-- TYPE_MOBILE_CBS -->
+        <item>14</item> <!-- TYPE_MOBILE_IA -->
     </integer-array>
 
     <!-- The maximum duration (in milliseconds) we expect a network transition to take -->
@@ -303,6 +349,9 @@
          Default value is 2 minutes. -->
     <integer translatable="false" name="config_wifi_driver_stop_delay">120000</integer>
 
+    <!-- Wifi driver supports batched scan -->
+    <bool translatable="false" name="config_wifi_batched_scan_supported">false</bool>
+
     <!-- Flag indicating whether the we should enable the automatic brightness in Settings.
          Software implementation will be used if config_hardware_auto_brightness_available is not set -->
     <bool name="config_automatic_brightness_available">false</bool>
@@ -401,6 +450,13 @@
          The default is false. -->
     <bool name="config_lidControlsSleep">false</bool>
 
+    <!-- Indicate whether to allow the device to suspend when the screen is off
+         due to the proximity sensor.  This resource should only be set to true
+         if the sensor HAL correctly handles the proximity sensor as a wake-up source.
+         Otherwise, the device may fail to wake out of suspend reliably.
+         The default is false. -->
+    <bool name="config_suspendWhenScreenOffDueToProximity">false</bool>
+
     <!-- Control the behavior when the user long presses the power button.
             0 - Nothing
             1 - Global actions menu
@@ -725,6 +781,9 @@
          re-validation -->
     <bool name="config_bluetooth_address_validation">false</bool>
 
+    <!-- Boolean indicating if current platform supports BLE peripheral mode -->
+    <bool name="config_bluetooth_le_peripheral_mode_supported">false</bool>
+
     <!-- The default data-use polling period. -->
     <integer name="config_datause_polling_period_sec">600</integer>
 
@@ -741,6 +800,11 @@
     <!-- 2 means give warning -->
     <integer name="config_datause_notification_type">2</integer>
 
+    <!-- If Voice Radio Technology is RIL_RADIO_TECHNOLOGY_LTE:14 this is the value
+         that should be used instead. A value of RIL_RADIO_TECHNOLOGY_UNKNOWN:0 means
+         there is no replacement value and VoLTE is assumed to be supported -->
+    <integer name="config_volte_replacement_rat">0</integer>
+
     <!-- Flag indicating whether the current device is "voice capable".
          If true, this means that the device supports circuit-switched
          (i.e. voice) phone calls over the telephony network, and is
@@ -1045,6 +1109,10 @@
     players. -->
     <integer name="config_safe_media_volume_index">10</integer>
 
+    <!-- Configure mobile network MTU. The standard default is set here but each carrier
+         may have a specific value set in an overlay config.xml file. -->
+    <integer name="config_mobile_mtu">1500</integer>
+
     <!-- Whether WiFi display is supported by this device.
          There are many prerequisites for this feature to work correctly.
          Here are a few of them:
@@ -1064,7 +1132,7 @@
     <bool name="config_useDevInputEventForAudioJack">false</bool>
 
     <!-- Whether safe headphone volume is enabled or not (country specific). -->
-    <bool name="config_safe_media_volume_enabled">true</bool>
+    <bool name="config_safe_media_volume_enabled">false</bool>
 
     <!-- Set to true if the wifi display supports compositing content stored
          in gralloc protected buffers.  For this to be true, there must exist
@@ -1122,6 +1190,11 @@
     <string name="config_chooseTypeAndAccountActivity"
             >android/android.accounts.ChooseTypeAndAccountActivity</string>
 
+    <!-- Component name of a custom ResolverActivity (Intent resolver) to be used instead of
+         the default framework version. If left empty, then the framework version will be used.
+         Example: com.google.android.myapp/.resolver.MyResolverActivity  -->
+    <string name="config_customResolverActivity"></string>
+
     <!-- Apps that are authorized to access shared accounts, overridden by product overlays -->
     <string name="config_appsAuthorizedForSharedAccounts">;com.android.settings;</string>
 
@@ -1145,4 +1218,27 @@
         <item>com.android.inputmethod.latin</item>
     </string-array>
 
+    <string-array name="config_notificationScorers">
+        <item>com.android.internal.notification.DemoContactNotificationScorer</item>
+    </string-array>
+
+    <!-- Flag indicating that this device does not rotate and will always remain in its default
+         orientation. Activities that desire to run in a non-compatible orientation will be run
+         from an emulated display within the physical display. -->
+    <bool name="config_forceDefaultOrientation">false</bool>
+
+    <!-- Default Gravity setting for the system Toast view. Equivalent to: Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM -->
+    <integer name="config_toastDefaultGravity">0x00000051</integer>
+
+    <!-- set to false if we need to show user confirmation
+         when alpha identifier is not provided by the UICC -->
+    <bool name="config_stkNoAlphaUsrCnf">true</bool>
+
+    <!-- Don't use roaming icon for considered operators.
+         Can use mcc or mcc+mnc as item. For example, 302 or 21407.
+         If operators, 21404 and 21407, make roaming agreements, user of 21404 should not see
+         the roaming icon as using 21407 network.
+         To do this, add 21407 item to values-mcc214-mnc04/config.xml -->
+    <string-array translatable="false" name="config_operatorConsideredNonRoaming">
+    </string-array>
 </resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 637128a5..e902354 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -50,8 +50,12 @@
     <!-- Margin at the edge of the screen to ignore touch events for in the windowshade. -->
     <dimen name="status_bar_edge_ignore">5dp</dimen>
 
-    <!-- Size of the fastscroll hint letter -->
+    <!-- Minimum size of the fastscroll overlay -->
     <dimen name="fastscroll_overlay_size">104dp</dimen>
+    <!-- Text size of the fastscroll overlay -->
+    <dimen name="fastscroll_overlay_text_size">24sp</dimen>
+    <!-- Padding of the fastscroll overlay -->
+    <dimen name="fastscroll_overlay_padding">16dp</dimen>
     <!-- Width of the fastscroll thumb -->
     <dimen name="fastscroll_thumb_width">64dp</dimen>
     <!-- Height of the fastscroll thumb -->
@@ -340,4 +344,16 @@
     security mode. -->
     <dimen name="kg_small_widget_height">160dp</dimen>
 
+    <!-- Rounded corner radius for video subtitles. -->
+    <dimen name="subtitle_corner_radius">2dp</dimen>
+
+    <!-- Shadow radius for video subtitles. -->
+    <dimen name="subtitle_shadow_radius">2dp</dimen>
+
+    <!-- Shadow offset for video subtitles. -->
+    <dimen name="subtitle_shadow_offset">2dp</dimen>
+
+    <!-- Outline width for video subtitles. -->
+    <dimen name="subtitle_outline_width">2dp</dimen>
+
 </resources>
diff --git a/core/res/res/values/donottranslate.xml b/core/res/res/values/donottranslate.xml
index b49e7bd..a7288e1 100644
--- a/core/res/res/values/donottranslate.xml
+++ b/core/res/res/values/donottranslate.xml
@@ -24,8 +24,6 @@
     <bool name="lockscreen_isPortrait">true</bool>
     <!-- @hide DO NOT TRANSLATE. Control aspect ratio of lock pattern -->
     <string name="lock_pattern_view_aspect">square</string>
-    <!-- @hide DO NOT TRANSLATE. Separator between the hour and minute elements in a TimePicker widget -->
-    <string name="time_picker_separator">:</string>
     <!-- @hide DO NOT TRANSLATE. ICU pattern for "Mon, 14 January" -->
     <string name="icu_abbrev_wday_month_day_no_year">eeeMMMMd</string>
     <!-- @hide DO NOT TRANSLATE. date formatting pattern for system ui.-->
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index 21bae04..15df295 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -80,4 +80,5 @@
   <item type="id" name="overflow_menu_presenter" />
   <item type="id" name="popup_submenu_presenter" />
   <item type="id" name="action_bar_spinner" />
+  <item type="id" name="current_scene" />
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 22ef31b..c5d4810 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2053,4 +2053,30 @@
   <public type="style" name="Theme.DeviceDefault.NoActionBar.Overscan" id="0x010301df" />
   <public type="style" name="Theme.DeviceDefault.Light.NoActionBar.Overscan" id="0x010301e0" />
 
+<!-- ===============================================================
+    Resources added in version 19 of the platform
+    =============================================================== -->
+  <eat-comment />
+
+  <public type="attr" name="keyset" />
+  <public type="attr" name="targetId" />
+  <public type="attr" name="fromScene" />
+  <public type="attr" name="toScene" />
+  <public type="attr" name="transition" />
+  <public type="attr" name="transitionOrdering" />
+  <public type="attr" name="fadingMode" />
+  <public type="attr" name="startDelay" />
+  <public type="attr" name="ssp" />
+  <public type="attr" name="sspPrefix" />
+  <public type="attr" name="sspPattern" />
+  <public type="attr" name="addPrintersActivity" />
+  <public type="attr" name="vendor" />
+  <public type="attr" name="category" />
+  <public type="attr" name="isAsciiCapable" />
+  <public type="attr" name="autoMirrored" />
+  <public type="attr" name="supportsSwitchingToNextInputMethod" />
+  <public type="attr" name="requireDeviceUnlock" />
+  <public type="attr" name="apduServiceBanner" />
+  <public type="attr" name="accessibilityLiveRegion" />
+
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index ef0f01d..a03378e 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -273,6 +273,18 @@
     <!-- If MMS discovers there isn't much space left on the device, it will show a toast with this message. -->
     <string name="low_memory" product="default">Phone storage is full. Delete some files to free space.</string>
 
+    <!-- SSL CA cert notification --> <skip />
+    <!-- Shows up when there is a user SSL CA Cert installed on the
+         device.  Indicates to the user that SSL traffic can be intercepted.  [CHAR LIMIT=NONE] -->
+    <string name="ssl_ca_cert_warning">Network may be monitored</string>
+    <!-- Content text for a notification. The Title of the notification is "ssl_ca_cert_warning",
+         i.e.  "Network may be monitored". This says that an unknown party is doing the monitoring.
+         [CHAR LIMIT=100]-->
+    <string name="ssl_ca_cert_noti_by_unknown">By an unknown third party</string>
+    <!-- Content text for a notification. The Title of the notification is "ssl_ca_cert_warning",
+         i.e.  "Network may be monitored". This indicates who is doing the monitoring.
+         [CHAR LIMIT=100]-->
+    <string name="ssl_ca_cert_noti_managed">By <xliff:g id="managing_domain">%s</xliff:g></string>
 
     <!-- Display name for any time a piece of data refers to the owner of the phone. For example, this could be used in place of the phone's phone number. -->
     <string name="me">Me</string>
@@ -712,6 +724,15 @@
         tasks and kill their apps. Malicious apps may disrupt
         the behavior of other apps.</string>
 
+    <!-- [CHAR LIMIT=NONE] Title of an application permission, allowing an application to create,
+         change, remove activity stacks. -->
+    <string name="permlab_manageActivityStacks">manage activity stacks</string>
+    <!-- [CHAR LIMIT=NONE] Description of an application permission, allowing an application to create,
+             change, remove activity stacks. -->
+    <string name="permdesc_manageActivityStacks">Allows the app to add, remove, and
+        modify the activity stacks in which other apps run.  Malicious apps may disrupt
+        the behavior of other apps.</string>
+
     <!-- Title of an application permission, allowing an application to start any activity, regardless of permission protection or exported state. -->
     <string name="permlab_startAnyActivity">start any activity</string>
     <!-- Description of an application permission, allowing an application to start any activity, regardless of permission protection or exported state. -->
@@ -823,7 +844,7 @@
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_getTopActivityInfo">Allows the holder to retrieve private information
         about the current application in the foreground of the screen.</string>
-    
+
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_runSetActivityWatcher">monitor and control all app launching</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -970,6 +991,26 @@
         interface of an accessibility service. Should never be needed for normal apps.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_bindPrintService">bind to a print service</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_bindPrintService">Allows the holder to bind to the top-level
+        interface of a print service. Should never be needed for normal apps.</string>
+
+    <!-- Title of an application permission, listed so the user can choose
+         whether they want to allow the application to do this. -->
+    <string name="permlab_bindPrintSpoolerService">bind to a print spooler service</string>
+    <!-- Description of an application permission, listed so the user can
+         choose whether they want to allow the application to do this. -->
+    <string name="permdesc_bindPrintSpoolerService">Allows the holder to bind to the top-level
+        interface of a print spooler service. Should never be needed for normal apps.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_bindNfcService">bind to NFC service</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_bindNfcService">Allows the holder to bind to applications
+        that are emulating NFC cards. Should never be needed for normal apps.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_bindTextService">bind to a text service</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_bindTextService">Allows the holder to bind to the top-level
@@ -1000,6 +1041,12 @@
         a device administrator. Should never be needed for normal apps.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_manageDeviceAdmins">add or remove a device admin</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_manageDeviceAdmins">Allows the holder to add or remove active device
+        administrators. Should never be needed for normal apps.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_setOrientation">change screen orientation</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_setOrientation">Allows the app to change
@@ -1094,6 +1141,11 @@
     <string name="permdesc_anyCodecForPlayback">Allows the app to use any installed
         media decoder to decode for playback.</string>
 
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. This permission allows the app to install or uninstall trusted credentials, a.k.a. CA certificates. [CHAR LIMIT=NONE] -->
+    <string name="permlab_manageCaCertificates">manage trusted credentials</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=NONE]-->
+    <string name="permdesc_manageCaCertificates">Allows the app to install and uninstall CA certificates as trusted credentials.</string>
+
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_diagnostic">read/write to resources owned by diag</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -1360,6 +1412,27 @@
     <string name="permdesc_controlWifiDisplay">Allows the app to control low-level features of Wifi displays.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_captureAudioOutput">capture audio output</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_captureAudioOutput">Allows the app to capture and redirect audio output.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_captureAudioHotword">Hotword detection</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_captureAudioHotword">Allows the app to capture audio for Hotword detection. The capture can
+      happen in the background but does not prevent other audio capture (e.g. Camcorder).</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_captureVideoOutput">capture video output</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_captureVideoOutput">Allows the app to capture and redirect video output.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_captureSecureVideoOutput">capture secure video output</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_captureSecureVideoOutput">Allows the app to capture and redirect secure video output.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_modifyAudioSettings">change your audio settings</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_modifyAudioSettings">Allows the app to modify global audio settings such as volume and which speaker is used for output.</string>
@@ -1541,6 +1614,14 @@
     <string name="permdesc_wakeLock" product="default">Allows the app to prevent the phone from going to sleep.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_transmitIr">transmit infrared</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_transmitIr" product="tablet">Allows the app to use the tablet\'s infrared transmitter.</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_transmitIr" product="default">Allows the app to use the phone\'s infrared transmitter.</string>
+
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_devicePower" product="tablet">power tablet on or off</string>
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_devicePower" product="default">power phone on or off</string>
@@ -1797,6 +1878,11 @@
     <string name="permdesc_mediaStorageWrite" product="default">Allows the app to modify the contents of the internal media storage.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=30] -->
+    <string name="permlab_manageDocs" product="default">manage document storage</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=NONE] -->
+    <string name="permdesc_manageDocs" product="default">Allows the app to manage document storage.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=30] -->
     <string name="permlab_sdcardAccessAll">access external storage of all users</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_sdcardAccessAll">Allows the app to access external storage for all users.</string>
@@ -1827,6 +1913,11 @@
     <string name="permdesc_modifyNetworkAccounting">Allows the app to modify how network usage is accounted against apps. Not for use by normal apps.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_markNetworkSocket">modify socket marks</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_markNetworkSocket">Allows the app to modify socket marks for routing</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_accessNotifications">access notifications</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_accessNotifications">Allows the app to retrieve, examine, and clear notifications, including those posted by other apps.</string>
@@ -1836,6 +1927,16 @@
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_bindNotificationListenerService">Allows the holder to bind to the top-level interface of a notification listener service. Should never be needed for normal apps.</string>
 
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_invokeCarrierSetup">invoke the carrier-provided configuration app</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_invokeCarrierSetup">Allows the holder to invoke the carrier-provided configuration app. Should never be needed for normal apps.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_accessNetworkConditions">listen for observations on network conditions</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_accessNetworkConditions">Allows an application to listen for observations on network conditions. Should never be needed for normal apps.</string>
+
     <!-- Policy administration -->
 
     <!-- Title of policy access to limiting the user's password choices -->
@@ -3469,6 +3570,16 @@
     <!-- Description of an application permission that lets an application route media output. -->
     <string name="permdesc_route_media_output">Allows an application to route media output to other external devices.</string>
 
+    <!-- Title of an application permission that lets an application access keyguard secure storage. -->
+    <string name="permlab_access_keyguard_secure_storage">Access keyguard secure storage</string>
+    <!-- Description of an application permission that lets an application access keyguard secure storage. -->
+    <string name="permdesc_access_keyguard_secure_storage">Allows an application to access keguard secure storage.</string>
+
+    <!-- Title of an application permission that lets it control keyguard. -->
+    <string name="permlab_control_keyguard">Control displaying and hiding keyguard</string>
+    <!-- Description of an application permission that lets it control keyguard. -->
+    <string name="permdesc_control_keyguard">Allows an application to control keguard.</string>
+
     <!-- Shown in the tutorial for tap twice for zoom control. -->
     <string name="tutorial_double_tap_to_zoom_message_short">Touch twice for zoom control</string>
 
@@ -3885,11 +3996,6 @@
     <!-- Title for a dialog showing possible activities for sharing in ShareActionProvider [CHAR LIMIT=25] -->
     <string name="share_action_provider_share_with">Share with</string>
 
-    <!-- Status Bar icon descriptions -->
-
-    <!-- Description of for the status bar's icon that the device is locked for accessibility. [CHAR LIMIT=NONE] -->
-    <string name="status_bar_device_locked">Device locked.</string>
-
     <!-- Delimeter used between each item in a textual list; for example "Alpha, Beta". [CHAR LIMIT=3] -->
     <string name="list_delimeter">", "</string>
 
@@ -3955,6 +4061,9 @@
     <!-- Status message for remote routes that are not available for connection right now -->
     <string name="media_route_status_not_available">Not available</string>
 
+    <!-- Status message for a remote route that is in use (and thus unavailabe) right now -->
+    <string name="media_route_status_in_use">In use</string>
+
     <!-- Display manager service -->
 
     <!-- Name of the built-in display.  [CHAR LIMIT=50] -->
@@ -3969,6 +4078,9 @@
     <!-- Title text to show within the overlay.  [CHAR LIMIT=50] -->
     <string name="display_manager_overlay_display_title"><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>
 
+    <!-- Title text to append when the display is secure.  [CHAR LIMIT=30] -->
+    <string name="display_manager_overlay_display_secure_suffix">, secure</string>
+
     <!-- Title of the notification to indicate an active wifi display connection.  [CHAR LIMIT=50] -->
     <string name="wifi_display_notification_title">Wireless display is connected</string>
     <!-- Message of the notification to indicate an active wifi display connection.  [CHAR LIMIT=80] -->
@@ -3988,7 +4100,7 @@
     <!-- Message shown when user enters wrong PIN -->
     <string name="kg_wrong_pin">Wrong PIN</string>
     <!-- Countdown message shown after too many failed unlock attempts -->
-    <string name="kg_too_many_failed_attempts_countdown">Try again in <xliff:g id="number">%d</xliff:g> seconds.</string>
+    <string name="kg_too_many_failed_attempts_countdown">Try again in <xliff:g id="number">%1$d</xliff:g> seconds.</string>
     <!-- Instructions for using the pattern unlock screen -->
     <string name="kg_pattern_instructions">Draw your pattern</string>
     <!-- Instructions for using the SIM PIN unlock screen -->
@@ -4108,8 +4220,133 @@
     <!-- Error message title [CHAR LIMIT=35] -->
     <string name="error_message_title">Error</string>
     <!-- Message informing user that app is not permitted to access accounts. [CHAR LIMIT=none] -->
-    <string name="app_no_restricted_accounts">This application does not support accounts for restricted profiles</string>
+    <string name="app_no_restricted_accounts">This app doesn\'t support accounts for restricted profiles</string>
     <!-- Message informing user that the requested activity could not be found [CHAR LIMIT=none] -->
     <string name="app_not_found">No application found to handle this action</string>
     <string name="revoke">Revoke</string>
+
+    <!-- Printing -->
+
+    <!-- ISO (European standard) A0 media (paper) size: 33.11" × 46.81" -->
+    <string name="mediaSize_iso_a0">ISO A0</string>
+    <!-- ISO (European standard) A1 media (paper) size: 23.39" × 33.11" -->
+    <string name="mediaSize_iso_a1">ISO A1</string>
+    <!-- ISO (European standard) A2 media (paper) size: 16.54" x 23.39" -->
+    <string name="mediaSize_iso_a2">ISO A2</string>
+    <!-- ISO (European standard) A3 media (paper) size: 11.69" x 16.54" -->
+    <string name="mediaSize_iso_a3">ISO A3</string>
+    <!-- ISO (European standard) A4 media (paper) size: 8.27" x 11.69" -->
+    <string name="mediaSize_iso_a4">ISO A4</string>
+    <!-- ISO (European standard) A5 media (paper) size: 5.83" x 8.27" -->
+    <string name="mediaSize_iso_a5">ISO A5</string>
+    <!-- ISO (European standard) A6 media (paper) size: 4.13" x 5.83" -->
+    <string name="mediaSize_iso_a6">ISO A6</string>
+    <!-- ISO (European standard) A7 media (paper) size: 2.91" x 4.13" -->
+    <string name="mediaSize_iso_a7">ISO A7</string>
+    <!-- ISO (European standard) A8 media (paper) size: 2.05" x 2.91" -->
+    <string name="mediaSize_iso_a8">ISO A8</string>
+    <!-- ISO (European standard) A9 media (paper) size: 1.46" x 2.05" -->
+    <string name="mediaSize_iso_a9">ISO A9</string>
+    <!-- ISO (European standard) A10 media (paper) size: 1.02" x 1.46" -->
+    <string name="mediaSize_iso_a10">ISO A10</string>
+
+    <!-- ISO (European standard) B0 media (paper) size: 39.37" x 55.67" -->
+    <string name="mediaSize_iso_b0">ISO B0</string>
+    <!-- ISO (European standard) B1 media (paper) size: 27.83" x 39.37" -->
+    <string name="mediaSize_iso_b1">ISO B1</string>
+    <!-- ISO (European standard) B2 media (paper) size - 19.69" x 27.83" -->
+    <string name="mediaSize_iso_b2">ISO B2</string>
+    <!-- ISO (European standard) B3 media (paper) size: 13.90" x 19.69" -->
+    <string name="mediaSize_iso_b3">ISO B3</string>
+    <!-- ISO (European standard) B4 media (paper) size: 9.84" x 13.90" -->
+    <string name="mediaSize_iso_b4">ISO B4</string>
+    <!-- ISO (European standard) B5 media (paper) size: 6.93" x 9.84" -->
+    <string name="mediaSize_iso_b5">ISO B5</string>
+    <!-- ISO (European standard) B6 media (paper) size: 4.92" x 6.93" -->
+    <string name="mediaSize_iso_b6">ISO B6</string>
+    <!-- ISO (European standard) B7 media (paper) size: 3.46" x 4.92" -->
+    <string name="mediaSize_iso_b7">ISO B7</string>
+    <!-- ISO (European standard) B8 media (paper) size: 2.44" x 3.46" -->
+    <string name="mediaSize_iso_b8">ISO B8</string>
+    <!-- ISO (European standard) B9 media (paper) size: 1.73" x 2.44" -->
+    <string name="mediaSize_iso_b9">ISO B9</string>
+    <!-- ISO (European standard) B10 media (paper) size: 1.22" x 1.73" -->
+    <string name="mediaSize_iso_b10">ISO B10</string>
+
+    <!-- ISO (European standard) C0 media (paper) size: 36.10" x 51.06" -->
+    <string name="mediaSize_iso_c0">ISO C0</string>
+    <!-- ISO (European standard) C1 media (paper) size: 25.51" x 36.10" -->
+    <string name="mediaSize_iso_c1">ISO C1</string>
+    <!-- ISO (European standard) C2 media (paper) size: 18.03" x 25.51" -->
+    <string name="mediaSize_iso_c2">ISO C2</string>
+    <!-- ISO (European standard) C3 media (paper) size: 12.76" x 18.03" -->
+    <string name="mediaSize_iso_c3">ISO C3</string>
+    <!-- ISO (European standard) C4 media (paper) size: 9.02" x 12.76" -->
+    <string name="mediaSize_iso_c4">ISO C4</string>
+    <!-- ISO (European standard) C5 media (paper) size: 6.38" x 9.02" -->
+    <string name="mediaSize_iso_c5">ISO C5</string>
+    <!-- ISO (European standard) C6 media (paper) size: 4.49" x 6.38" -->
+    <string name="mediaSize_iso_c6">ISO C6</string>
+    <!-- ISO (European standard) C7 media (paper) size: 3.19" x 4.49" -->
+    <string name="mediaSize_iso_c7">ISO C7</string>
+    <!-- ISO ISO C8 media (paper) size: 2.24" x 3.19" -->
+    <string name="mediaSize_iso_c8">ISO C8</string>
+    <!-- ISO ISO C9 media (paper) size: 1.57" x 2.24" -->
+    <string name="mediaSize_iso_c9">ISO C9</string>
+    <!-- ISO (European standard) C10 media (paper) size: 1.10" x 1.57" -->
+    <string name="mediaSize_iso_c10">ISO C10</string>
+
+    <!-- North America Letter media (paper) size: 8.5" × 11" -->
+    <string name="mediaSize_na_letter">Letter</string>
+    <!-- North America Government Letter media (paper) size: 8.0" × 10.5" -->
+    <string name="mediaSize_na_gvrnmt_letter">Government Letter</string>
+    <!-- North America Legal media (paper) size: 8.5" × 14" -->
+    <string name="mediaSize_na_legal">Legal</string>
+    <!-- North America Junior Legal media (paper) size: 8.0" × 5.0" -->
+    <string name="mediaSize_na_junior_legal">Junior Legal</string>
+    <!-- North America Ledger media (paper) size: 17" × 11" -->
+    <string name="mediaSize_na_ledger">Ledger</string>
+    <!-- North America Tabloid media (paper) size: 11" × 17" -->
+    <string name="mediaSize_na_tabloid">Tabloid</string>
+
+    <!-- Write fail reason: printing was cancelled.[CHAR LIMIT=none] -->
+    <string name="write_fail_reason_cancelled">Cancelled</string>
+    <!-- Write fail reason: couldn't write the printed content. [CHAR LIMIT=none] -->
+    <string name="write_fail_reason_cannot_write">Error writing content</string>
+
+    <!-- Print fail reason: unknown. [CHAR LIMIT=25] -->
+    <string name="reason_unknown">unknown</string>
+
+    <!-- PIN entry dialog title for entering the administrator PIN [CHAR LIMIT=none] -->
+    <string name="restr_pin_enter_admin_pin">Enter administrator PIN</string>
+    <!-- PIN entry dialog label/hint for PIN [CHAR LIMIT=none] -->
+    <string name="restr_pin_enter_pin">Enter PIN</string>
+    <!-- PIN entry dialog label/hint for incorrect PIN entry [CHAR LIMIT=none] -->
+    <string name="restr_pin_incorrect">Incorrect</string>
+    <!-- PIN entry dialog label/hint for old PIN [CHAR LIMIT=none] -->
+    <string name="restr_pin_enter_old_pin">Current PIN</string>
+    <!-- PIN entry dialog label for new PIN [CHAR LIMIT=none] -->
+    <string name="restr_pin_enter_new_pin">New PIN</string>
+    <!-- PIN entry dialog label for new PIN confirmation [CHAR LIMIT=none] -->
+    <string name="restr_pin_confirm_pin">Confirm new PIN</string>
+    <!-- PIN creation dialog message [CHAR LIMIT=none] -->
+    <string name="restr_pin_create_pin">Create a PIN for modifying restrictions</string>
+    <!-- PIN entry dialog error when PINs are not the same [CHAR LIMIT=none] -->
+    <string name="restr_pin_error_doesnt_match">PINs don\'t match. Try again.</string>
+    <!-- PIN entry dialog error when PIN is too short [CHAR LIMIT=none] -->
+    <string name="restr_pin_error_too_short">PIN is too short. Must be at least 4 digits.</string>
+    <!-- PIN entry dialog countdown message for next chance to enter the PIN [CHAR LIMIT=none] -->
+    <!-- Phrase describing a time duration using seconds [CHAR LIMIT=16] -->
+    <plurals name="restr_pin_countdown">
+        <item quantity="one">Try again in 1 second</item>
+        <item quantity="other">Try again in <xliff:g id="count">%d</xliff:g> seconds</item>
+    </plurals>
+    <!-- PIN entry dialog tells the user to not enter a PIN for a while. [CHAR LIMIT=none] -->
+    <string name="restr_pin_try_later">Try again later</string>
+
+    <!-- Toast bar message when hiding the transient navigation bar [CHAR LIMIT=35] -->
+    <string name="transient_navigation_confirmation">Swipe edge of screen to reveal bar</string>
+
+    <!-- Longer version of toast bar message when hiding the transient navigation bar (if room) -->
+    <string name="transient_navigation_confirmation_long">Swipe from edge of screen to reveal system bar</string>
 </resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index f494d8c..ba72a2b 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -138,6 +138,12 @@
         <item name="windowExitAnimation">@anim/submenu_exit</item>
     </style>
 
+    <!-- {@hide} -->
+    <style name="Animation.ToastBar">
+        <item name="windowEnterAnimation">@anim/toast_bar_enter</item>
+        <item name="windowExitAnimation">@anim/toast_bar_exit</item>
+    </style>
+
     <style name="Animation.TypingFilter">
         <item name="windowEnterAnimation">@anim/grow_fade_in_center</item>
         <item name="windowExitAnimation">@anim/shrink_fade_out_center</item>
@@ -523,7 +529,6 @@
 
     <style name="Widget.CalendarView">
         <item name="android:showWeekNumber">true</item>
-        <item name="android:firstDayOfWeek">1</item>
         <item name="android:minDate">01/01/1900</item>
         <item name="android:maxDate">12/31/2100</item>
         <item name="android:shownWeekCount">6</item>
@@ -1052,6 +1057,24 @@
         <item name="android:background">@null</item>
     </style>
 
+    <style name="PreferenceHeaderPanel">
+        <item name="android:layout_marginStart">@dimen/preference_screen_side_margin</item>
+        <item name="android:layout_marginEnd">@dimen/preference_screen_side_margin_negative</item>
+        <item name="android:paddingTop">@dimen/preference_screen_header_vertical_padding</item>
+        <item name="android:paddingBottom">@dimen/preference_screen_header_vertical_padding</item>
+    </style>
+
+    <style name="PreferenceHeaderList">
+        <item name="android:paddingStart">@dimen/preference_screen_header_padding_side</item>
+        <item name="android:paddingEnd">@dimen/preference_screen_header_padding_side</item>
+        <item name="android:scrollbarStyle">@integer/preference_screen_header_scrollbarStyle</item>
+    </style>
+
+    <style name="PreferenceFragmentList">
+        <item name="android:paddingStart">@dimen/preference_fragment_padding_side</item>
+        <item name="android:paddingEnd">@dimen/preference_fragment_padding_side</item>
+    </style>
+
     <!-- Other Misc Styles -->
     <eat-comment />
 
@@ -2420,8 +2443,8 @@
     <style name="Widget.Holo.PreferenceFrameLayout">
         <item name="android:borderTop">0dip</item>
         <item name="android:borderBottom">@dimen/preference_fragment_padding_bottom</item>
-        <item name="android:borderLeft">@dimen/preference_fragment_padding_side</item>
-        <item name="android:borderRight">@dimen/preference_fragment_padding_side</item>
+        <item name="android:borderLeft">?attr/preferenceFragmentPaddingSide</item>
+        <item name="android:borderRight">?attr/preferenceFragmentPaddingSide</item>
     </style>
 
     <!-- Pointer styles -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
old mode 100755
new mode 100644
index a60a6d1..4148f20
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -38,16 +38,12 @@
   <java-symbol type="id" name="action_menu_presenter" />
   <java-symbol type="id" name="action_mode_close_button" />
   <java-symbol type="id" name="activity_chooser_view_content" />
-  <java-symbol type="id" name="albumart" />
   <java-symbol type="id" name="alertTitle" />
   <java-symbol type="id" name="allow_button" />
   <java-symbol type="id" name="alwaysUse" />
   <java-symbol type="id" name="amPm" />
   <java-symbol type="id" name="authtoken_type" />
   <java-symbol type="id" name="back_button" />
-  <java-symbol type="id" name="btn_next" />
-  <java-symbol type="id" name="btn_play" />
-  <java-symbol type="id" name="btn_prev" />
   <java-symbol type="id" name="button_bar" />
   <java-symbol type="id" name="buttonPanel" />
   <java-symbol type="id" name="by_common" />
@@ -58,6 +54,7 @@
   <java-symbol type="id" name="characterPicker" />
   <java-symbol type="id" name="clearDefaultHint" />
   <java-symbol type="id" name="contentPanel" />
+  <java-symbol type="id" name="current_scene" />
   <java-symbol type="id" name="customPanel" />
   <java-symbol type="id" name="datePicker" />
   <java-symbol type="id" name="day" />
@@ -179,7 +176,6 @@
   <java-symbol type="id" name="to_common" />
   <java-symbol type="id" name="to_org" />
   <java-symbol type="id" name="to_org_unit" />
-  <java-symbol type="id" name="top_action_bar" />
   <java-symbol type="id" name="topPanel" />
   <java-symbol type="id" name="up" />
   <java-symbol type="id" name="value" />
@@ -217,6 +213,13 @@
   <java-symbol type="id" name="sms_short_code_remember_undo_instruction" />
   <java-symbol type="id" name="breadcrumb_section" />
   <java-symbol type="id" name="action_bar_spinner" />
+  <java-symbol type="id" name="pin_cancel_button" />
+  <java-symbol type="id" name="pin_ok_button" />
+  <java-symbol type="id" name="pin_text" />
+  <java-symbol type="id" name="pin_new_text" />
+  <java-symbol type="id" name="pin_confirm_text" />
+  <java-symbol type="id" name="pin_error_message" />
+  <java-symbol type="id" name="timePickerLayout" />
 
   <java-symbol type="attr" name="actionModeShareDrawable" />
   <java-symbol type="attr" name="alertDialogCenterButtons" />
@@ -243,9 +246,11 @@
   <java-symbol type="bool" name="action_bar_embed_tabs" />
   <java-symbol type="bool" name="action_bar_embed_tabs_pre_jb" />
   <java-symbol type="bool" name="action_bar_expanded_action_views_exclusive" />
+  <java-symbol type="bool" name="config_avoidGfxAccel" />
   <java-symbol type="bool" name="config_allowActionMenuItemTextWithIcon" />
   <java-symbol type="bool" name="config_bluetooth_address_validation" />
   <java-symbol type="bool" name="config_bluetooth_sco_off_call" />
+  <java-symbol type="bool" name="config_bluetooth_le_peripheral_mode_supported" />
   <java-symbol type="bool" name="config_cellBroadcastAppLinks" />
   <java-symbol type="bool" name="config_duplicate_port_omadm_wappush" />
   <java-symbol type="bool" name="config_enable_emergency_call_while_sim_locked" />
@@ -255,6 +260,7 @@
   <java-symbol type="bool" name="config_sip_wifi_only" />
   <java-symbol type="bool" name="config_sms_capable" />
   <java-symbol type="bool" name="config_sms_utf8_support" />
+  <java-symbol type="bool" name="config_suspendWhenScreenOffDueToProximity" />
   <java-symbol type="bool" name="config_swipeDisambiguation" />
   <java-symbol type="bool" name="config_syncstorageengine_masterSyncAutomatically" />
   <java-symbol type="bool" name="config_telephony_use_own_number_for_voicemail" />
@@ -278,15 +284,23 @@
   <java-symbol type="bool" name="config_dontPreferApn" />
   <java-symbol type="bool" name="config_speed_up_audio_on_mt_calls" />
   <java-symbol type="bool" name="config_useFixedVolume" />
+  <java-symbol type="bool" name="config_forceDefaultOrientation" />
+  <java-symbol type="bool" name="config_wifi_batched_scan_supported" />
+  <java-symbol type="bool" name="flip_controller_fallback_keys" />
 
   <java-symbol type="integer" name="config_cursorWindowSize" />
+  <java-symbol type="integer" name="config_extraFreeKbytesAdjust" />
+  <java-symbol type="integer" name="config_extraFreeKbytesAbsolute" />
   <java-symbol type="integer" name="config_longPressOnPowerBehavior" />
+  <java-symbol type="integer" name="config_lowMemoryKillerMinFreeKbytesAdjust" />
+  <java-symbol type="integer" name="config_lowMemoryKillerMinFreeKbytesAbsolute" />
   <java-symbol type="integer" name="config_max_pan_devices" />
   <java-symbol type="integer" name="config_ntpPollingInterval" />
   <java-symbol type="integer" name="config_ntpPollingIntervalShorter" />
   <java-symbol type="integer" name="config_ntpRetry" />
   <java-symbol type="integer" name="config_ntpThreshold" />
   <java-symbol type="integer" name="config_ntpTimeout" />
+  <java-symbol type="integer" name="config_toastDefaultGravity" />
   <java-symbol type="integer" name="config_wifi_framework_scan_interval" />
   <java-symbol type="integer" name="config_wifi_supplicant_scan_interval" />
   <java-symbol type="integer" name="config_wifi_scan_interval_p2p_connected" />
@@ -299,6 +313,8 @@
   <java-symbol type="integer" name="config_lockSoundVolumeDb" />
   <java-symbol type="integer" name="config_multiuserMaximumUsers" />
   <java-symbol type="integer" name="config_safe_media_volume_index" />
+  <java-symbol type="integer" name="config_mobile_mtu" />
+  <java-symbol type="integer" name="config_volte_replacement_rat"/>
 
   <java-symbol type="color" name="tab_indicator_text_v4" />
 
@@ -313,9 +329,10 @@
   <java-symbol type="dimen" name="dropdownitem_icon_width" />
   <java-symbol type="dimen" name="dropdownitem_text_padding_left" />
   <java-symbol type="dimen" name="fastscroll_overlay_size" />
+  <java-symbol type="dimen" name="fastscroll_overlay_text_size" />
+  <java-symbol type="dimen" name="fastscroll_overlay_padding" />
   <java-symbol type="dimen" name="fastscroll_thumb_height" />
   <java-symbol type="dimen" name="fastscroll_thumb_width" />
-  <java-symbol type="dimen" name="fastscroll_thumb_width" />
   <java-symbol type="dimen" name="password_keyboard_spacebar_vertical_correction" />
   <java-symbol type="dimen" name="search_view_preferred_width" />
   <java-symbol type="dimen" name="textview_error_popup_default_width" />
@@ -478,6 +495,7 @@
   <java-symbol type="string" name="display_manager_built_in_display_name" />
   <java-symbol type="string" name="display_manager_hdmi_display_name" />
   <java-symbol type="string" name="display_manager_overlay_display_name" />
+  <java-symbol type="string" name="display_manager_overlay_display_secure_suffix" />
   <java-symbol type="string" name="display_manager_overlay_display_title" />
   <java-symbol type="string" name="double_tap_toast" />
   <java-symbol type="string" name="elapsed_time_short_format_h_mm_ss" />
@@ -563,26 +581,6 @@
   <java-symbol type="string" name="keyboardview_keycode_enter" />
   <java-symbol type="string" name="keyboardview_keycode_mode_change" />
   <java-symbol type="string" name="keyboardview_keycode_shift" />
-  <java-symbol type="string" name="keyguard_accessibility_add_widget" />
-  <java-symbol type="string" name="keyguard_accessibility_camera" />
-  <java-symbol type="string" name="keyguard_accessibility_expand_lock_area" />
-  <java-symbol type="string" name="keyguard_accessibility_face_unlock" />
-  <java-symbol type="string" name="keygaurd_accessibility_media_controls" />
-  <java-symbol type="string" name="keyguard_accessibility_pattern_area" />
-  <java-symbol type="string" name="keyguard_accessibility_pattern_unlock" />
-  <java-symbol type="string" name="keyguard_accessibility_password_unlock" />
-  <java-symbol type="string" name="keyguard_accessibility_pin_unlock" />
-  <java-symbol type="string" name="keyguard_accessibility_slide_area" />
-  <java-symbol type="string" name="keyguard_accessibility_slide_unlock" />
-  <java-symbol type="string" name="keyguard_accessibility_status" />
-  <java-symbol type="string" name="keyguard_accessibility_user_selector" />
-  <java-symbol type="string" name="keyguard_accessibility_widget" />
-  <java-symbol type="string" name="keyguard_accessibility_widget_deleted" />
-  <java-symbol type="string" name="keyguard_accessibility_widget_empty_slot" />
-  <java-symbol type="string" name="keyguard_accessibility_widget_reorder_start" />
-  <java-symbol type="string" name="keyguard_accessibility_widget_reorder_end" />
-  <java-symbol type="string" name="keyguard_accessibility_unlock_area_collapsed" />
-  <java-symbol type="string" name="keyguard_accessibility_unlock_area_expanded" />
   <java-symbol type="string" name="kilobyteShort" />
   <java-symbol type="string" name="last_month" />
   <java-symbol type="string" name="launchBrowserDefault" />
@@ -592,9 +590,6 @@
   <java-symbol type="string" name="lockscreen_access_pattern_start" />
   <java-symbol type="string" name="lockscreen_emergency_call" />
   <java-symbol type="string" name="lockscreen_return_to_call" />
-  <java-symbol type="string" name="lockscreen_transport_pause_description" />
-  <java-symbol type="string" name="lockscreen_transport_play_description" />
-  <java-symbol type="string" name="lockscreen_transport_stop_description" />
   <java-symbol type="string" name="low_memory" />
   <java-symbol type="string" name="media_bad_removal" />
   <java-symbol type="string" name="media_checking" />
@@ -787,7 +782,6 @@
   <java-symbol type="string" name="time_picker_increment_hour_button" />
   <java-symbol type="string" name="time_picker_increment_minute_button" />
   <java-symbol type="string" name="time_picker_increment_set_pm_button" />
-  <java-symbol type="string" name="time_picker_separator" />
   <java-symbol type="string" name="upload_file" />
   <java-symbol type="string" name="user_switched" />
   <java-symbol type="string" name="volume_alarm" />
@@ -834,14 +828,67 @@
   <java-symbol type="string" name="media_route_status_connecting" />
   <java-symbol type="string" name="media_route_status_available" />
   <java-symbol type="string" name="media_route_status_not_available" />
+  <java-symbol type="string" name="media_route_status_in_use" />
   <java-symbol type="string" name="owner_name" />
   <java-symbol type="string" name="config_chooseAccountActivity" />
   <java-symbol type="string" name="config_chooseTypeAndAccountActivity" />
+  <java-symbol type="string" name="config_customResolverActivity" />
   <java-symbol type="string" name="config_appsAuthorizedForSharedAccounts" />
   <java-symbol type="string" name="error_message_title" />
   <java-symbol type="string" name="action_bar_home_description_format" />
   <java-symbol type="string" name="action_bar_home_subtitle_description_format" />
   <java-symbol type="string" name="wireless_display_route_description" />
+  <java-symbol type="string" name="mediaSize_iso_a0" />
+  <java-symbol type="string" name="mediaSize_iso_a1" />
+  <java-symbol type="string" name="mediaSize_iso_a2" />
+  <java-symbol type="string" name="mediaSize_iso_a3" />
+  <java-symbol type="string" name="mediaSize_iso_a4" />
+  <java-symbol type="string" name="mediaSize_iso_a5" />
+  <java-symbol type="string" name="mediaSize_iso_a6" />
+  <java-symbol type="string" name="mediaSize_iso_a7" />
+  <java-symbol type="string" name="mediaSize_iso_a8" />
+  <java-symbol type="string" name="mediaSize_iso_a9" />
+  <java-symbol type="string" name="mediaSize_iso_a10" />
+  <java-symbol type="string" name="mediaSize_iso_b0" />
+  <java-symbol type="string" name="mediaSize_iso_b1" />
+  <java-symbol type="string" name="mediaSize_iso_b2" />
+  <java-symbol type="string" name="mediaSize_iso_b3" />
+  <java-symbol type="string" name="mediaSize_iso_b4" />
+  <java-symbol type="string" name="mediaSize_iso_b5" />
+  <java-symbol type="string" name="mediaSize_iso_b6" />
+  <java-symbol type="string" name="mediaSize_iso_b7" />
+  <java-symbol type="string" name="mediaSize_iso_b8" />
+  <java-symbol type="string" name="mediaSize_iso_b9" />
+  <java-symbol type="string" name="mediaSize_iso_b10" />
+  <java-symbol type="string" name="mediaSize_iso_c0" />
+  <java-symbol type="string" name="mediaSize_iso_c1" />
+  <java-symbol type="string" name="mediaSize_iso_c2" />
+  <java-symbol type="string" name="mediaSize_iso_c3" />
+  <java-symbol type="string" name="mediaSize_iso_c4" />
+  <java-symbol type="string" name="mediaSize_iso_c5" />
+  <java-symbol type="string" name="mediaSize_iso_c6" />
+  <java-symbol type="string" name="mediaSize_iso_c7" />
+  <java-symbol type="string" name="mediaSize_iso_c8" />
+  <java-symbol type="string" name="mediaSize_iso_c9" />
+  <java-symbol type="string" name="mediaSize_iso_c10" />
+  <java-symbol type="string" name="mediaSize_na_letter" />
+  <java-symbol type="string" name="mediaSize_na_gvrnmt_letter" />
+  <java-symbol type="string" name="mediaSize_na_legal" />
+  <java-symbol type="string" name="mediaSize_na_junior_legal" />
+  <java-symbol type="string" name="mediaSize_na_ledger" />
+  <java-symbol type="string" name="mediaSize_na_tabloid" />
+  <java-symbol type="string" name="reason_unknown" />
+  <java-symbol type="string" name="restr_pin_enter_admin_pin" />
+  <java-symbol type="string" name="restr_pin_enter_pin" />
+  <java-symbol type="string" name="restr_pin_incorrect" />
+  <java-symbol type="string" name="restr_pin_try_later" />
+  <java-symbol type="string" name="write_fail_reason_cancelled" />
+  <java-symbol type="string" name="write_fail_reason_cannot_write" />
+  <java-symbol type="string" name="transient_navigation_confirmation" />
+  <java-symbol type="string" name="transient_navigation_confirmation_long" />
+  <java-symbol type="string" name="ssl_ca_cert_noti_by_unknown" />
+  <java-symbol type="string" name="ssl_ca_cert_noti_managed" />
+  <java-symbol type="string" name="ssl_ca_cert_warning" />
 
   <java-symbol type="plurals" name="abbrev_in_num_days" />
   <java-symbol type="plurals" name="abbrev_in_num_hours" />
@@ -864,6 +911,7 @@
   <java-symbol type="plurals" name="num_hours_ago" />
   <java-symbol type="plurals" name="num_minutes_ago" />
   <java-symbol type="plurals" name="num_seconds_ago" />
+  <java-symbol type="plurals" name="restr_pin_countdown" />
 
   <java-symbol type="array" name="carrier_properties" />
   <java-symbol type="array" name="config_data_usage_network_types" />
@@ -878,6 +926,7 @@
   <java-symbol type="array" name="config_masterVolumeRamp" />
   <java-symbol type="array" name="config_cdma_dun_supported_types" />
   <java-symbol type="array" name="config_disabledUntilUsedPreinstalledImes" />
+  <java-symbol type="array" name="config_operatorConsideredNonRoaming" />
 
   <java-symbol type="drawable" name="default_wallpaper" />
   <java-symbol type="drawable" name="indicator_input_error" />
@@ -957,12 +1006,12 @@
   <java-symbol type="drawable" name="jog_tab_target_gray" />
   <java-symbol type="drawable" name="picture_emergency" />
   <java-symbol type="drawable" name="platlogo" />
-  <java-symbol type="drawable" name="platlogo_alt" />
   <java-symbol type="drawable" name="stat_notify_sync_error" />
   <java-symbol type="drawable" name="stat_notify_wifi_in_range" />
   <java-symbol type="drawable" name="stat_notify_rssi_in_range" />
   <java-symbol type="drawable" name="stat_sys_gps_on" />
   <java-symbol type="drawable" name="stat_sys_tether_wifi" />
+  <java-symbol type="drawable" name="stat_sys_certificate_info" />
   <java-symbol type="drawable" name="status_bar_background" />
   <java-symbol type="drawable" name="sym_keyboard_shift" />
   <java-symbol type="drawable" name="sym_keyboard_shift_locked" />
@@ -975,21 +1024,17 @@
   <java-symbol type="drawable" name="text_select_handle_left" />
   <java-symbol type="drawable" name="text_select_handle_middle" />
   <java-symbol type="drawable" name="text_select_handle_right" />
+  <java-symbol type="drawable" name="toast_bar_bg" />
   <java-symbol type="drawable" name="unknown_image" />
   <java-symbol type="drawable" name="unlock_default" />
   <java-symbol type="drawable" name="unlock_halo" />
   <java-symbol type="drawable" name="unlock_ring" />
   <java-symbol type="drawable" name="unlock_wave" />
-  <java-symbol type="drawable" name="ic_lockscreen_camera" />
-  <java-symbol type="drawable" name="ic_lockscreen_silent" />
-  <java-symbol type="drawable" name="ic_lockscreen_unlock" />
   <java-symbol type="drawable" name="ic_action_assist_generic" />
-  <java-symbol type="drawable" name="ic_lockscreen_alarm" />
   <java-symbol type="drawable" name="notification_bg" />
   <java-symbol type="drawable" name="notification_bg_low" />
   <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_lockscreen_unlock_phantom" />
   <java-symbol type="drawable" name="ic_media_route_on_holo_dark" />
   <java-symbol type="drawable" name="ic_media_route_disabled_holo_dark" />
 
@@ -1068,6 +1113,7 @@
   <java-symbol type="layout" name="textview_hint" />
   <java-symbol type="layout" name="time_picker" />
   <java-symbol type="layout" name="time_picker_dialog" />
+  <java-symbol type="layout" name="toast_bar" />
   <java-symbol type="layout" name="transient_notification" />
   <java-symbol type="layout" name="volume_adjust" />
   <java-symbol type="layout" name="volume_adjust_item" />
@@ -1089,12 +1135,11 @@
   <java-symbol type="layout" name="notification_template_part_time" />
   <java-symbol type="layout" name="notification_template_part_chronometer" />
   <java-symbol type="layout" name="notification_template_inbox" />
-  <java-symbol type="layout" name="keyguard_multi_user_avatar" />
-  <java-symbol type="layout" name="keyguard_multi_user_selector_widget" />
   <java-symbol type="layout" name="sms_short_code_confirmation_dialog" />
-  <java-symbol type="layout" name="keyguard_add_widget" />
   <java-symbol type="layout" name="action_bar_up_container" />
   <java-symbol type="layout" name="app_not_authorized" />
+  <java-symbol type="layout" name="restrictions_pin_challenge" />
+  <java-symbol type="layout" name="restrictions_pin_setup" />
 
   <java-symbol type="anim" name="slide_in_child_bottom" />
   <java-symbol type="anim" name="slide_in_right" />
@@ -1110,7 +1155,6 @@
   <java-symbol type="xml" name="password_kbd_qwerty_shifted" />
   <java-symbol type="xml" name="password_kbd_symbols" />
   <java-symbol type="xml" name="password_kbd_symbols_shift" />
-  <java-symbol type="xml" name="kg_password_kbd_numeric" />
   <java-symbol type="xml" name="power_profile" />
   <java-symbol type="xml" name="time_zones_by_country" />
   <java-symbol type="xml" name="sms_short_codes" />
@@ -1125,6 +1169,7 @@
   <java-symbol type="style" name="Animation.DropDownUp" />
   <java-symbol type="style" name="Animation.DropDownDown" />
   <java-symbol type="style" name="Animation.PopupWindow" />
+  <java-symbol type="style" name="Animation.ToastBar" />
   <java-symbol type="style" name="Animation.TypingFilter" />
   <java-symbol type="style" name="Animation.TypingFilterRestore" />
   <java-symbol type="style" name="Animation.Dream" />
@@ -1164,8 +1209,6 @@
 
   <!-- From android.policy -->
   <java-symbol type="anim" name="app_starting_exit" />
-  <java-symbol type="anim" name="lock_screen_behind_enter" />
-  <java-symbol type="anim" name="lock_screen_wallpaper_behind_enter" />
   <java-symbol type="anim" name="dock_top_enter" />
   <java-symbol type="anim" name="dock_top_exit" />
   <java-symbol type="anim" name="dock_bottom_enter" />
@@ -1174,22 +1217,12 @@
   <java-symbol type="anim" name="dock_left_exit" />
   <java-symbol type="anim" name="dock_right_enter" />
   <java-symbol type="anim" name="dock_right_exit" />
-  <java-symbol type="anim" name="keyguard_security_animate_in" />
-  <java-symbol type="anim" name="keyguard_security_animate_out" />
-  <java-symbol type="anim" name="keyguard_security_fade_in" />
-  <java-symbol type="anim" name="keyguard_security_fade_out" />
-  <java-symbol type="anim" name="keyguard_action_assist_exit" />
-  <java-symbol type="anim" name="keyguard_action_assist_enter" />
 
   <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_virtualKeyVibePattern" />
-  <java-symbol type="array" name="lockscreen_targets_when_silent" />
-  <java-symbol type="array" name="lockscreen_targets_when_soundon" />
-  <java-symbol type="array" name="lockscreen_targets_with_camera" />
-  <java-symbol type="array" name="lockscreen_num_pad_klondike" />
   <java-symbol type="attr" name="actionModePopupWindowStyle" />
   <java-symbol type="attr" name="dialogCustomTitleDecorLayout" />
   <java-symbol type="attr" name="dialogTitleDecorLayout" />
@@ -1204,33 +1237,11 @@
   <java-symbol type="bool" name="config_lidControlsSleep" />
   <java-symbol type="bool" name="config_reverseDefaultRotation" />
   <java-symbol type="bool" name="config_showNavigationBar" />
-  <java-symbol type="bool" name="kg_enable_camera_default_widget" />
-  <java-symbol type="bool" name="kg_share_status_area" />
-  <java-symbol type="bool" name="kg_sim_puk_account_full_screen" />
-  <java-symbol type="bool" name="kg_top_align_page_shrink_on_bouncer_visible" />
   <java-symbol type="bool" name="target_honeycomb_needs_options_menu" />
-  <java-symbol type="bool" name="kg_center_small_widgets_vertically" />
-  <java-symbol type="bool" name="kg_show_ime_at_screen_on" />
-  <java-symbol type="color" name="kg_multi_user_text_active" />
-  <java-symbol type="color" name="kg_multi_user_text_inactive" />
-  <java-symbol type="color" name="kg_widget_pager_gradient" />
-  <java-symbol type="color" name="keyguard_avatar_frame_color" />
-  <java-symbol type="color" name="keyguard_avatar_frame_pressed_color" />
-  <java-symbol type="color" name="keyguard_avatar_frame_shadow_color" />
-  <java-symbol type="color" name="keyguard_avatar_nick_color" />
   <java-symbol type="dimen" name="navigation_bar_height" />
   <java-symbol type="dimen" name="navigation_bar_height_landscape" />
   <java-symbol type="dimen" name="navigation_bar_width" />
   <java-symbol type="dimen" name="status_bar_height" />
-  <java-symbol type="dimen" name="kg_widget_pager_horizontal_padding" />
-  <java-symbol type="dimen" name="kg_widget_pager_top_padding" />
-  <java-symbol type="dimen" name="kg_widget_pager_bottom_padding" />
-  <java-symbol type="dimen" name="keyguard_avatar_size" />
-  <java-symbol type="dimen" name="keyguard_avatar_frame_stroke_width" />
-  <java-symbol type="dimen" name="keyguard_avatar_frame_shadow_radius" />
-  <java-symbol type="dimen" name="kg_edge_swipe_region_size" />
-  <java-symbol type="dimen" name="kg_squashed_layout_threshold" />
-  <java-symbol type="dimen" name="kg_small_widget_height" />
   <java-symbol type="drawable" name="ic_jog_dial_sound_off" />
   <java-symbol type="drawable" name="ic_jog_dial_sound_on" />
   <java-symbol type="drawable" name="ic_jog_dial_unlock" />
@@ -1248,10 +1259,7 @@
   <java-symbol type="drawable" name="jog_tab_target_yellow" />
   <java-symbol type="drawable" name="magnified_region_frame" />
   <java-symbol type="drawable" name="menu_background" />
-  <java-symbol type="drawable" name="stat_sys_secure" />
-  <java-symbol type="drawable" name="kg_widget_bg_padded" />
   <java-symbol type="id" name="action_mode_bar_stub" />
-  <java-symbol type="id" name="alarm_status" />
   <java-symbol type="id" name="button0" />
   <java-symbol type="id" name="button4" />
   <java-symbol type="id" name="button5" />
@@ -1259,15 +1267,12 @@
   <java-symbol type="id" name="button7" />
   <java-symbol type="id" name="date" />
   <java-symbol type="id" name="eight" />
-  <java-symbol type="id" name="face_unlock_area_view" />
-  <java-symbol type="id" name="face_unlock_cancel_button" />
   <java-symbol type="id" name="five" />
   <java-symbol type="id" name="four" />
   <java-symbol type="id" name="icon_menu_presenter" />
   <java-symbol type="id" name="keyboard" />
   <java-symbol type="id" name="list_menu_presenter" />
   <java-symbol type="id" name="lock_screen" />
-  <java-symbol type="id" name="login" />
   <java-symbol type="id" name="nine" />
   <java-symbol type="id" name="no_applications_message" />
   <java-symbol type="id" name="ok" />
@@ -1275,57 +1280,14 @@
   <java-symbol type="id" name="option1" />
   <java-symbol type="id" name="option2" />
   <java-symbol type="id" name="option3" />
-  <java-symbol type="id" name="password" />
-  <java-symbol type="id" name="passwordEntry" />
-  <java-symbol type="id" name="pinEntry" />
   <java-symbol type="id" name="right_icon" />
   <java-symbol type="id" name="seven" />
   <java-symbol type="id" name="six" />
   <java-symbol type="id" name="status" />
-  <java-symbol type="id" name="switch_ime_button" />
   <java-symbol type="id" name="three" />
   <java-symbol type="id" name="title_container" />
   <java-symbol type="id" name="two" />
   <java-symbol type="id" name="zero" />
-  <java-symbol type="id" name="keyguard_message_area" />
-  <java-symbol type="id" name="keyguard_click_area" />
-  <java-symbol type="id" name="keyguard_selector_view" />
-  <java-symbol type="id" name="keyguard_pattern_view" />
-  <java-symbol type="id" name="keyguard_password_view" />
-  <java-symbol type="id" name="keyguard_pin_view" />
-  <java-symbol type="id" name="keyguard_face_unlock_view" />
-  <java-symbol type="id" name="keyguard_sim_pin_view" />
-  <java-symbol type="id" name="keyguard_sim_puk_view" />
-  <java-symbol type="id" name="keyguard_account_view" />
-  <java-symbol type="id" name="keyguard_selector_fade_container" />
-  <java-symbol type="id" name="keyguard_widget_pager_delete_target" />
-  <java-symbol type="id" name="keyguard_bouncer_frame" />
-  <java-symbol type="id" name="app_widget_container" />
-  <java-symbol type="id" name="view_flipper" />
-  <java-symbol type="id" name="carrier_text" />
-  <java-symbol type="id" name="emergency_call_button" />
-  <java-symbol type="id" name="keyguard_host_view" />
-  <java-symbol type="id" name="delete_button" />
-  <java-symbol type="id" name="lockPatternView" />
-  <java-symbol type="id" name="forgot_password_button" />
-  <java-symbol type="id" name="glow_pad_view" />
-  <java-symbol type="id" name="delete_button" />
-  <java-symbol type="id" name="keyguard_user_avatar" />
-  <java-symbol type="id" name="keyguard_user_name" />
-  <java-symbol type="id" name="keyguard_transport_control" />
-  <java-symbol type="id" name="keyguard_status_view" />
-  <java-symbol type="id" name="keyguard_status_view_face_palm" />
-  <java-symbol type="id" name="keyguard_users_grid" />
-  <java-symbol type="id" name="clock_text" />
-  <java-symbol type="id" name="clock_view" />
-  <java-symbol type="id" name="keyguard_multi_user_selector" />
-  <java-symbol type="id" name="sliding_layout" />
-  <java-symbol type="id" name="keyguard_add_widget" />
-  <java-symbol type="id" name="keyguard_add_widget_view" />
-  <java-symbol type="id" name="multi_pane_challenge" />
-  <java-symbol type="id" name="keyguard_user_selector" />
-  <java-symbol type="id" name="key_enter" />
-  <java-symbol type="id" name="keyguard_selector_view_frame" />
   <java-symbol type="integer" name="config_carDockRotation" />
   <java-symbol type="integer" name="config_defaultUiModeType" />
   <java-symbol type="integer" name="config_deskDockRotation" />
@@ -1334,18 +1296,8 @@
   <java-symbol type="integer" name="config_lidNavigationAccessibility" />
   <java-symbol type="integer" name="config_lidOpenRotation" />
   <java-symbol type="integer" name="config_longPressOnHomeBehavior" />
-  <java-symbol type="integer" name="kg_security_flip_duration" />
-  <java-symbol type="integer" name="kg_carousel_angle" />
   <java-symbol type="layout" name="global_actions_item" />
   <java-symbol type="layout" name="global_actions_silent_mode" />
-  <java-symbol type="layout" name="keyguard_selector_view" />
-  <java-symbol type="layout" name="keyguard_pattern_view" />
-  <java-symbol type="layout" name="keyguard_password_view" />
-  <java-symbol type="layout" name="keyguard_pin_view" />
-  <java-symbol type="layout" name="keyguard_face_unlock_view" />
-  <java-symbol type="layout" name="keyguard_sim_pin_view" />
-  <java-symbol type="layout" name="keyguard_sim_puk_view" />
-  <java-symbol type="layout" name="keyguard_account_view" />
   <java-symbol type="layout" name="recent_apps_dialog" />
   <java-symbol type="layout" name="screen_action_bar" />
   <java-symbol type="layout" name="screen_custom_title" />
@@ -1354,9 +1306,6 @@
   <java-symbol type="layout" name="screen_simple_overlay_action_mode" />
   <java-symbol type="layout" name="screen_title" />
   <java-symbol type="layout" name="screen_title_icons" />
-  <java-symbol type="layout" name="keyguard_host_view" />
-  <java-symbol type="layout" name="keyguard_transport_control_view" />
-  <java-symbol type="layout" name="keyguard_status_view" />
   <java-symbol type="string" name="system_ui_date_pattern" />
   <java-symbol type="string" name="android_upgrading_title" />
   <java-symbol type="string" name="bugreport_title" />
@@ -1371,82 +1320,13 @@
   <java-symbol type="string" name="global_action_silent_mode_on_status" />
   <java-symbol type="string" name="global_action_toggle_silent_mode" />
   <java-symbol type="string" name="invalidPuk" />
-  <java-symbol type="string" name="keyguard_password_enter_pin_code" />
-  <java-symbol type="string" name="keyguard_password_enter_puk_code" />
-  <java-symbol type="string" name="keyguard_password_wrong_pin_code" />
   <java-symbol type="string" name="lockscreen_carrier_default" />
-  <java-symbol type="string" name="lockscreen_charged" />
-  <java-symbol type="string" name="lockscreen_failed_attempts_almost_at_wipe" />
-  <java-symbol type="string" name="lockscreen_failed_attempts_almost_glogin" />
-  <java-symbol type="string" name="lockscreen_failed_attempts_now_wiping" />
-  <java-symbol type="string" name="lockscreen_forgot_pattern_button_text" />
-  <java-symbol type="string" name="lockscreen_glogin_checking_password" />
-  <java-symbol type="string" name="lockscreen_glogin_forgot_pattern" />
-  <java-symbol type="string" name="lockscreen_glogin_invalid_input" />
-  <java-symbol type="string" name="lockscreen_glogin_too_many_attempts" />
-  <java-symbol type="string" name="lockscreen_instructions_when_pattern_disabled" />
-  <java-symbol type="string" name="lockscreen_low_battery" />
-  <java-symbol type="string" name="lockscreen_missing_sim_instructions" />
-  <java-symbol type="string" name="lockscreen_missing_sim_instructions_long" />
-  <java-symbol type="string" name="lockscreen_missing_sim_message_short" />
-  <java-symbol type="string" name="lockscreen_network_locked_message" />
-  <java-symbol type="string" name="lockscreen_password_wrong" />
-  <java-symbol type="string" name="lockscreen_pattern_instructions" />
-  <java-symbol type="string" name="lockscreen_pattern_wrong" />
-  <java-symbol type="string" name="lockscreen_permanent_disabled_sim_message_short" />
-  <java-symbol type="string" name="lockscreen_permanent_disabled_sim_instructions" />
-  <java-symbol type="string" name="lockscreen_plugged_in" />
-  <java-symbol type="string" name="lockscreen_sim_locked_message" />
-  <java-symbol type="string" name="lockscreen_sim_puk_locked_message" />
-  <java-symbol type="string" name="lockscreen_sim_unlock_progress_dialog_message" />
-  <java-symbol type="string" name="lockscreen_sound_off_label" />
-  <java-symbol type="string" name="lockscreen_sound_on_label" />
-  <java-symbol type="string" name="lockscreen_too_many_failed_attempts_countdown" />
-  <java-symbol type="string" name="lockscreen_too_many_failed_attempts_dialog_message" />
-  <java-symbol type="string" name="lockscreen_too_many_failed_password_attempts_dialog_message" />
-  <java-symbol type="string" name="lockscreen_too_many_failed_pin_attempts_dialog_message" />
-  <java-symbol type="string" name="lockscreen_unlock_label" />
-  <java-symbol type="string" name="status_bar_device_locked" />
   <java-symbol type="style" name="Animation.LockScreen" />
   <java-symbol type="style" name="Theme.Dialog.RecentApplications" />
   <java-symbol type="style" name="Theme.ExpandedMenu" />
   <java-symbol type="style" name="Widget.Button.NumPadKey" />
   <java-symbol type="style" name="TextAppearance.NumPadKey" />
   <java-symbol type="style" name="TextAppearance.NumPadKey.Klondike" />
-  <java-symbol type="string" name="kg_emergency_call_label" />
-  <java-symbol type="string" name="kg_forgot_pattern_button_text" />
-  <java-symbol type="string" name="kg_wrong_pattern" />
-  <java-symbol type="string" name="kg_wrong_password" />
-  <java-symbol type="string" name="kg_wrong_pin" />
-  <java-symbol type="string" name="kg_too_many_failed_attempts_countdown" />
-  <java-symbol type="string" name="kg_pattern_instructions" />
-  <java-symbol type="string" name="kg_sim_pin_instructions" />
-  <java-symbol type="string" name="kg_pin_instructions" />
-  <java-symbol type="string" name="kg_password_instructions" />
-  <java-symbol type="string" name="kg_puk_enter_puk_hint" />
-  <java-symbol type="string" name="kg_puk_enter_pin_hint" />
-  <java-symbol type="string" name="kg_sim_unlock_progress_dialog_message" />
-  <java-symbol type="string" name="kg_password_wrong_pin_code" />
-  <java-symbol type="string" name="kg_invalid_sim_pin_hint" />
-  <java-symbol type="string" name="kg_invalid_sim_puk_hint" />
-  <java-symbol type="string" name="kg_invalid_puk" />
-  <java-symbol type="string" name="kg_login_too_many_attempts" />
-  <java-symbol type="string" name="kg_login_instructions" />
-  <java-symbol type="string" name="kg_login_username_hint" />
-  <java-symbol type="string" name="kg_login_password_hint" />
-  <java-symbol type="string" name="kg_login_submit_button" />
-  <java-symbol type="string" name="kg_login_invalid_input" />
-  <java-symbol type="string" name="kg_login_account_recovery_hint" />
-  <java-symbol type="string" name="kg_login_checking_password" />
-  <java-symbol type="string" name="kg_too_many_failed_pin_attempts_dialog_message" />
-  <java-symbol type="string" name="kg_too_many_failed_pattern_attempts_dialog_message" />
-  <java-symbol type="string" name="kg_too_many_failed_password_attempts_dialog_message" />
-  <java-symbol type="string" name="kg_failed_attempts_almost_at_wipe" />
-  <java-symbol type="string" name="kg_failed_attempts_now_wiping" />
-  <java-symbol type="string" name="kg_failed_attempts_almost_at_login" />
-  <java-symbol type="string" name="kg_enter_confirm_pin_hint" />
-  <java-symbol type="string" name="kg_invalid_confirm_pin_hint" />
-  <java-symbol type="string" name="kg_text_message_separator" />
 
   <!-- From services -->
   <java-symbol type="anim" name="screen_rotate_0_enter" />
@@ -1662,17 +1542,21 @@
   <java-symbol type="string" name="enable_explore_by_touch_warning_title" />
   <java-symbol type="string" name="enable_explore_by_touch_warning_message" />
 
-  <java-symbol type="layout" name="resolver_grid" />
-  <java-symbol type="id" name="resolver_grid" />
+  <java-symbol type="layout" name="resolver_list" />
+  <java-symbol type="id" name="resolver_list" />
   <java-symbol type="id" name="button_once" />
   <java-symbol type="id" name="button_always" />
   <java-symbol type="integer" name="config_maxResolverActivityColumns" />
+  <java-symbol type="array" name="config_notificationScorers" />
 
   <!-- From SystemUI -->
   <java-symbol type="anim" name="push_down_in" />
   <java-symbol type="anim" name="push_down_out" />
   <java-symbol type="anim" name="push_up_in" />
   <java-symbol type="anim" name="push_up_out" />
+  <java-symbol type="anim" name="lock_screen_wallpaper_behind_enter" />
+  <java-symbol type="anim" name="lock_screen_behind_enter" />
+ 
   <java-symbol type="bool" name="config_alwaysUseCdmaRssi" />
   <java-symbol type="dimen" name="status_bar_icon_size" />
   <java-symbol type="dimen" name="system_bar_icon_size" />
@@ -1771,6 +1655,7 @@
   <java-symbol type="bool" name="config_sf_slowBlur" />
   <java-symbol type="drawable" name="ic_volume" />
   <java-symbol type="drawable" name="stat_notify_sim_toolkit" />
+  <java-symbol type="bool" name="config_stkNoAlphaUsrCnf" />
 
   <!-- From maps library -->
   <java-symbol type="array" name="maps_starting_lat_lng" />
@@ -1794,4 +1679,9 @@
   <java-symbol type="attr" name="actionModeWebSearchDrawable" />
   <java-symbol type="string" name="websearch" />
 
+  <!-- From SubtitleView -->
+  <java-symbol type="dimen" name="subtitle_corner_radius" />
+  <java-symbol type="dimen" name="subtitle_shadow_radius" />
+  <java-symbol type="dimen" name="subtitle_shadow_offset" />
+  <java-symbol type="dimen" name="subtitle_outline_width" />
 </resources>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 80f7486..23bd1ca 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -311,6 +311,10 @@
         <item name="ringtonePreferenceStyle">@android:style/Preference.RingtonePreference</item>
         <item name="preferenceLayoutChild">@android:layout/preference_child</item>
         <item name="preferencePanelStyle">@style/PreferencePanel</item>
+        <item name="preferenceHeaderPanelStyle">@style/PreferenceHeaderPanel</item>
+        <item name="preferenceListStyle">@style/PreferenceHeaderList</item>
+        <item name="preferenceFragmentListStyle">@style/PreferenceFragmentList</item>
+        <item name="preferenceFragmentPaddingSide">@dimen/preference_fragment_padding_side</item>
         <item name="detailsElementBackground">@android:drawable/panel_bg_holo_dark</item>
 
         <!-- Search widget styles -->
diff --git a/core/res/res/xml/audio_assets.xml b/core/res/res/xml/audio_assets.xml
index 746dbab..af5798a 100644
--- a/core/res/res/xml/audio_assets.xml
+++ b/core/res/res/xml/audio_assets.xml
@@ -34,5 +34,6 @@
         <asset id="FX_KEYPRESS_SPACEBAR" file="KeypressSpacebar.ogg"/>
         <asset id="FX_KEYPRESS_DELETE" file="KeypressDelete.ogg"/>
         <asset id="FX_KEYPRESS_RETURN" file="KeypressReturn.ogg"/>
+        <asset id="FX_KEYPRESS_INVALID" file="KeypressInvalid.ogg"/>
     </group>
 </audio_assets>
diff --git a/core/tests/ConnectivityManagerTest/AndroidManifest.xml b/core/tests/ConnectivityManagerTest/AndroidManifest.xml
index 54881d5..b76c8be 100644
--- a/core/tests/ConnectivityManagerTest/AndroidManifest.xml
+++ b/core/tests/ConnectivityManagerTest/AndroidManifest.xml
@@ -16,8 +16,7 @@
 
 <!-- package name must be unique so suffix with "tests" so package loader doesn't ignore us -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-  package="com.android.connectivitymanagertest"
-  android:sharedUserId="android.uid.system">
+  package="com.android.connectivitymanagertest">
 
     <!-- We add an application tag here just so that we can indicate that
          this package needs to link against the android.test library,
@@ -80,6 +79,8 @@
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
     <uses-permission android:name="android.permission.WRITE_SETTINGS" />
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+    <!-- This permission is added for API call setAirplaneMode() in ConnectivityManager -->
+    <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />
     <uses-permission android:name="android.permission.DEVICE_POWER" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
index 463e999..a0cb1bb 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
@@ -651,19 +651,6 @@
         } catch (InterruptedException e) {}
     }
 
-    /**
-     * Set airplane mode
-     */
-    public void setAirplaneMode(Context context, boolean enableAM) {
-        //set the airplane mode
-        Settings.Global.putInt(context.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON,
-                enableAM ? 1 : 0);
-        // Post the intent
-        Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
-        intent.putExtra("state", enableAM);
-        context.sendBroadcastAsUser(intent, UserHandle.ALL);
-    }
-
     protected static String convertToQuotedString(String string) {
         return "\"" + string + "\"";
     }
@@ -694,7 +681,7 @@
     //A thread to set the device into airplane mode then turn on wifi.
     Thread setDeviceWifiAndAirplaneThread = new Thread(new Runnable() {
         public void run() {
-            setAirplaneMode(mContext, true);
+            mCM.setAirplaneMode(true);
             connectToWifi(mPowerSsid);
         }
     });
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
index 3111489..729e1d2 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
@@ -62,7 +62,7 @@
         if (Settings.Global.getInt(getInstrumentation().getContext().getContentResolver(),
                 Settings.Global.AIRPLANE_MODE_ON) == 1) {
             log("airplane is not disabled, disable it.");
-            cmActivity.setAirplaneMode(getInstrumentation().getContext(), false);
+            cmActivity.mCM.setAirplaneMode(false);
         }
 
         if (!mWifiOnlyFlag) {
@@ -87,7 +87,7 @@
         if (Settings.Global.getInt(getInstrumentation().getContext().getContentResolver(),
                 Settings.Global.AIRPLANE_MODE_ON) == 1) {
             log("disable airplane mode if it is enabled");
-            cmActivity.setAirplaneMode(getInstrumentation().getContext(), false);
+            cmActivity.mCM.setAirplaneMode(false);
         }
         super.tearDown();
     }
@@ -344,7 +344,7 @@
 
         // Enable airplane mode
         log("Enable airplane mode");
-        cmActivity.setAirplaneMode(getInstrumentation().getContext(), true);
+        cmActivity.mCM.setAirplaneMode(true);
         sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT);
 
         networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
@@ -370,7 +370,7 @@
                 NetworkState.DO_NOTHING, State.DISCONNECTED);
 
         // disable airplane mode
-        cmActivity.setAirplaneMode(getInstrumentation().getContext(), false);
+        cmActivity.mCM.setAirplaneMode(false);
 
         assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
                 ConnectivityManagerTestActivity.LONG_TIMEOUT));
@@ -400,7 +400,7 @@
         assertNotNull("SSID is null", mTestAccessPoint);
         // Eanble airplane mode
         log("Enable airplane mode");
-        cmActivity.setAirplaneMode(getInstrumentation().getContext(), true);
+        cmActivity.mCM.setAirplaneMode(true);
 
         NetworkInfo networkInfo;
         if (!mWifiOnlyFlag) {
@@ -437,7 +437,7 @@
                 assertTrue("state validation failed", false);
             }
         }
-        cmActivity.setAirplaneMode(getInstrumentation().getContext(), false);
+        cmActivity.mCM.setAirplaneMode(false);
     }
 
     // Test case 7: test connectivity while transit from Wifi->AM->Wifi
@@ -463,7 +463,7 @@
         }
 
         // Enable airplane mode without clearing Wifi
-        cmActivity.setAirplaneMode(getInstrumentation().getContext(), true);
+        cmActivity.mCM.setAirplaneMode(true);
 
         assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED,
                 ConnectivityManagerTestActivity.LONG_TIMEOUT));
@@ -481,7 +481,7 @@
                 networkInfo.getState(), NetworkState.TO_CONNECTION, State.CONNECTED);
 
         // Disable airplane mode
-        cmActivity.setAirplaneMode(getInstrumentation().getContext(), false);
+        cmActivity.mCM.setAirplaneMode(false);
 
         assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
                 ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
diff --git a/core/tests/benchmarks/src/android/os/StrictModeBenchmark.java b/core/tests/benchmarks/src/android/os/StrictModeBenchmark.java
new file mode 100644
index 0000000..41af3820
--- /dev/null
+++ b/core/tests/benchmarks/src/android/os/StrictModeBenchmark.java
@@ -0,0 +1,34 @@
+/*
+ * 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.os;
+
+import android.os.StrictMode.ThreadPolicy;
+
+import com.google.caliper.SimpleBenchmark;
+
+public class StrictModeBenchmark extends SimpleBenchmark {
+
+    private ThreadPolicy mOff = new ThreadPolicy.Builder().build();
+    private ThreadPolicy mOn = new ThreadPolicy.Builder().detectAll().build();
+
+    public void timeToggleThreadPolicy(int reps) {
+        for (int i = 0; i < reps; i++) {
+            StrictMode.setThreadPolicy(mOn);
+            StrictMode.setThreadPolicy(mOff);
+        }
+    }
+}
diff --git a/core/tests/coretests/Android.mk b/core/tests/coretests/Android.mk
index 22fa7fc..be55444 100644
--- a/core/tests/coretests/Android.mk
+++ b/core/tests/coretests/Android.mk
@@ -22,7 +22,7 @@
 	$(call all-java-files-under, EnabledTestApp/src)
 
 LOCAL_DX_FLAGS := --core-library
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests android-common frameworks-core-util-lib mockwebserver guava littlemock
+LOCAL_STATIC_JAVA_LIBRARIES := core-tests-support android-common frameworks-core-util-lib mockwebserver guava littlemock
 LOCAL_JAVA_LIBRARIES := android.test.runner conscrypt telephony-common
 LOCAL_PACKAGE_NAME := FrameworksCoreTests
 
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index f8b26bc..a2cc40c 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -94,7 +94,7 @@
     <uses-permission android:name="android.permission.MOVE_PACKAGE" />
     <uses-permission android:name="android.permission.PACKAGE_VERIFICATION_AGENT" />
 
-    <!--os storage test permissions -->
+    <!-- os storage test permissions -->
     <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
     <uses-permission android:name="android.permission.ASEC_ACCESS" />
     <uses-permission android:name="android.permission.ASEC_CREATE" />
@@ -103,6 +103,10 @@
     <uses-permission android:name="android.permission.ASEC_RENAME" />
     <uses-permission android:name="android.permission.SHUTDOWN" />
 
+    <!-- virtual display test permissions -->
+    <uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT" />
+    <uses-permission android:name="android.permission.CAPTURE_SECURE_VIDEO_OUTPUT" />
+
     <!-- accessibility test permissions -->
     <uses-permission android:name="android.permission.RETRIEVE_WINDOW_CONTENT" />
 
diff --git a/core/tests/coretests/src/android/animation/AnimatorSetEventsTest.java b/core/tests/coretests/src/android/animation/AnimatorSetEventsTest.java
index d415e4e..7eb32ee 100644
--- a/core/tests/coretests/src/android/animation/AnimatorSetEventsTest.java
+++ b/core/tests/coretests/src/android/animation/AnimatorSetEventsTest.java
@@ -37,14 +37,12 @@
         button = (Button) getActivity().findViewById(R.id.animatingButton);
         mAnimator = new AnimatorSet();
         ((AnimatorSet)mAnimator).playSequentially(xAnim, yAnim);
-
         super.setUp();
     }
 
     @Override
     protected long getTimeout() {
-        return (xAnim.getDuration() + yAnim.getDuration()) +
-                (xAnim.getStartDelay() + yAnim.getStartDelay()) +
+        return (2 * mAnimator.getDuration()) + (2 * mAnimator.getStartDelay()) +
                 ANIM_DELAY + FUTURE_RELEASE_DELAY;
     }
 
diff --git a/core/tests/coretests/src/android/animation/EventsTest.java b/core/tests/coretests/src/android/animation/EventsTest.java
index 8df711b..28cfe3d 100644
--- a/core/tests/coretests/src/android/animation/EventsTest.java
+++ b/core/tests/coretests/src/android/animation/EventsTest.java
@@ -22,6 +22,7 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
 
 /**
  * Tests for the various lifecycle events of Animators. This abstract class is subclassed by
@@ -42,12 +43,15 @@
     protected static final int ANIM_DELAY = 100;
     protected static final int ANIM_MID_DURATION = ANIM_DURATION / 2;
     protected static final int ANIM_MID_DELAY = ANIM_DELAY / 2;
+    protected static final int ANIM_PAUSE_DURATION = ANIM_DELAY;
+    protected static final int ANIM_PAUSE_DELAY = ANIM_DELAY / 2;
     protected static final int FUTURE_RELEASE_DELAY = 50;
+    protected static final int ANIM_FULL_DURATION_SLOP = 100;
 
     private boolean mStarted;  // tracks whether we've received the onAnimationStart() callback
     protected boolean mRunning;  // tracks whether we've started the animator
-    private boolean mCanceled; // trackes whether we've canceled the animator
-    protected Animator.AnimatorListener mFutureListener; // mechanism for delaying the end of the test
+    private boolean mCanceled; // tracks whether we've canceled the animator
+    protected Animator.AnimatorListener mFutureListener; // mechanism for delaying end of the test
     protected FutureWaiter mFuture; // Mechanism for waiting for the UI test to complete
     private Animator.AnimatorListener mListener; // Listener that handles/tests the events
 
@@ -104,6 +108,48 @@
     };
 
     /**
+     * Pauses the given animator. Used to delay pausing until some later time (after the
+     * animator has started playing).
+     */
+    static class Pauser implements Runnable {
+        Animator mAnim;
+        FutureWaiter mFuture;
+        public Pauser(Animator anim, FutureWaiter future) {
+            mAnim = anim;
+            mFuture = future;
+        }
+        @Override
+        public void run() {
+            try {
+                mAnim.pause();
+            } catch (junit.framework.AssertionFailedError e) {
+                mFuture.setException(new RuntimeException(e));
+            }
+        }
+    };
+
+    /**
+     * Resumes the given animator. Used to delay resuming until some later time (after the
+     * animator has paused for some duration).
+     */
+    static class Resumer implements Runnable {
+        Animator mAnim;
+        FutureWaiter mFuture;
+        public Resumer(Animator anim, FutureWaiter future) {
+            mAnim = anim;
+            mFuture = future;
+        }
+        @Override
+        public void run() {
+            try {
+                mAnim.resume();
+            } catch (junit.framework.AssertionFailedError e) {
+                mFuture.setException(new RuntimeException(e));
+            }
+        }
+    };
+
+    /**
      * Releases the given Future object when the listener's end() event is called. Specifically,
      * it releases it after some further delay, to give the test time to do other things right
      * after an animation ends.
@@ -555,4 +601,114 @@
         mFuture.get(getTimeout(),  TimeUnit.MILLISECONDS);
      }
 
+    /**
+     * Verify that pausing and resuming an animator ends within
+     * the appropriate timeout duration.
+     */
+    @MediumTest
+    public void testPauseResume() throws Exception {
+        mFutureListener = new FutureReleaseListener(mFuture);
+        getActivity().runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    Handler handler = new Handler();
+                    mAnimator.addListener(mFutureListener);
+                    mRunning = true;
+                    mAnimator.start();
+                    handler.postDelayed(new Pauser(mAnimator, mFuture), ANIM_PAUSE_DELAY);
+                    handler.postDelayed(new Resumer(mAnimator, mFuture),
+                            ANIM_PAUSE_DELAY + ANIM_PAUSE_DURATION);
+                } catch (junit.framework.AssertionFailedError e) {
+                    mFuture.setException(new RuntimeException(e));
+                }
+            }
+        });
+        mFuture.get(getTimeout() + ANIM_PAUSE_DURATION, TimeUnit.MILLISECONDS);
+    }
+
+    /**
+     * Verify that pausing and resuming a startDelayed animator ends within
+     * the appropriate timeout duration.
+     */
+    @MediumTest
+    public void testPauseResumeDelayed() throws Exception {
+        mAnimator.setStartDelay(ANIM_DELAY);
+        mFutureListener = new FutureReleaseListener(mFuture);
+        getActivity().runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    Handler handler = new Handler();
+                    mAnimator.addListener(mFutureListener);
+                    mRunning = true;
+                    mAnimator.start();
+                    handler.postDelayed(new Pauser(mAnimator, mFuture), ANIM_PAUSE_DELAY);
+                    handler.postDelayed(new Resumer(mAnimator, mFuture),
+                            ANIM_PAUSE_DELAY + ANIM_PAUSE_DURATION);
+                } catch (junit.framework.AssertionFailedError e) {
+                    mFuture.setException(new RuntimeException(e));
+                }
+            }
+        });
+        mFuture.get(getTimeout() + ANIM_PAUSE_DURATION + ANIM_FULL_DURATION_SLOP,
+                TimeUnit.MILLISECONDS);
+    }
+
+    /**
+     * Verify that pausing an animator without resuming it causes a timeout.
+     */
+    @MediumTest
+    public void testPauseTimeout() throws Exception {
+        mFutureListener = new FutureReleaseListener(mFuture);
+        getActivity().runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    Handler handler = new Handler();
+                    mAnimator.addListener(mFutureListener);
+                    mRunning = true;
+                    mAnimator.start();
+                    handler.postDelayed(new Pauser(mAnimator, mFuture), ANIM_PAUSE_DELAY);
+                } catch (junit.framework.AssertionFailedError e) {
+                    mFuture.setException(new RuntimeException(e));
+                }
+            }
+        });
+        try {
+            mFuture.get(getTimeout() + ANIM_PAUSE_DURATION + ANIM_FULL_DURATION_SLOP,
+                    TimeUnit.MILLISECONDS);
+        } catch (TimeoutException e) {
+            // Expected behavior, swallow the exception
+        }
+    }
+
+    /**
+     * Verify that pausing a startDelayed animator without resuming it causes a timeout.
+     */
+    @MediumTest
+    public void testPauseTimeoutDelayed() throws Exception {
+        mAnimator.setStartDelay(ANIM_DELAY);
+        mFutureListener = new FutureReleaseListener(mFuture);
+        getActivity().runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    Handler handler = new Handler();
+                    mAnimator.addListener(mFutureListener);
+                    mRunning = true;
+                    mAnimator.start();
+                    handler.postDelayed(new Pauser(mAnimator, mFuture), ANIM_PAUSE_DELAY);
+                } catch (junit.framework.AssertionFailedError e) {
+                    mFuture.setException(new RuntimeException(e));
+                }
+            }
+        });
+        try {
+            mFuture.get(getTimeout() + ANIM_PAUSE_DURATION + ANIM_FULL_DURATION_SLOP,
+                    TimeUnit.MILLISECONDS);
+        } catch (TimeoutException e) {
+            // Expected behavior, swallow the exception
+        }
+    }
 }
diff --git a/core/tests/coretests/src/android/database/MatrixCursorTest.java b/core/tests/coretests/src/android/database/MatrixCursorTest.java
index cdab638..aa805dc 100644
--- a/core/tests/coretests/src/android/database/MatrixCursorTest.java
+++ b/core/tests/coretests/src/android/database/MatrixCursorTest.java
@@ -128,6 +128,56 @@
         } catch (IllegalArgumentException e) { /* expected */ }
     }
 
+    public void testRowBuilderOffer() {
+        MatrixCursor cursor = newMatrixCursor();
+
+        cursor.newRow()
+                .add("float", 4.2f)
+                .add("string", "foobar")
+                .add("blob", new byte[] {(byte) 0xaa, (byte) 0x55})
+                .add("lolwat", "kittens");
+
+        cursor.newRow();
+
+        cursor.newRow()
+                .add("string", "zero")
+                .add("string", "one")
+                .add("string", "two")
+                .add("lolwat", "kittens");
+
+        assertTrue(cursor.moveToFirst());
+        assertEquals("foobar", cursor.getString(0));
+        assertEquals(null, cursor.getString(1));
+        assertEquals(0, cursor.getShort(1));
+        assertEquals(0, cursor.getInt(2));
+        assertEquals(0, cursor.getLong(3));
+        assertEquals(4.2f, cursor.getFloat(4));
+        assertEquals(0.0d, cursor.getDouble(5));
+        MoreAsserts.assertEquals(new byte[] {(byte) 0xaa, (byte) 0x55}, cursor.getBlob(6));
+
+        assertTrue(cursor.moveToNext());
+        assertEquals(null, cursor.getString(0));
+        assertEquals(0, cursor.getShort(1));
+        assertEquals(0, cursor.getInt(2));
+        assertEquals(0, cursor.getLong(3));
+        assertEquals(0.0f, cursor.getFloat(4));
+        assertEquals(0.0d, cursor.getDouble(5));
+        assertEquals(null, cursor.getBlob(6));
+
+        assertTrue(cursor.moveToNext());
+        assertEquals("two", cursor.getString(0));
+        assertEquals(0, cursor.getShort(1));
+        assertEquals(0, cursor.getInt(2));
+        assertEquals(0, cursor.getLong(3));
+        assertEquals(0.0f, cursor.getFloat(4));
+        assertEquals(0.0d, cursor.getDouble(5));
+        assertEquals(null, cursor.getBlob(6));
+
+        assertTrue(cursor.isLast());
+        assertFalse(cursor.moveToNext());
+        assertTrue(cursor.isAfterLast());
+    }
+
     static class NonIterableArrayList<T> extends ArrayList<T> {
 
         NonIterableArrayList() {}
diff --git a/core/tests/coretests/src/android/hardware/display/VirtualDisplayTest.java b/core/tests/coretests/src/android/hardware/display/VirtualDisplayTest.java
new file mode 100644
index 0000000..ebecf2e3
--- /dev/null
+++ b/core/tests/coretests/src/android/hardware/display/VirtualDisplayTest.java
@@ -0,0 +1,508 @@
+/*
+ * 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.hardware.display;
+
+import android.app.Presentation;
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.PixelFormat;
+import android.graphics.Point;
+import android.graphics.drawable.ColorDrawable;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.VirtualDisplay;
+import android.media.Image;
+import android.media.ImageReader;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.SystemClock;
+import android.test.AndroidTestCase;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.Display;
+import android.view.Surface;
+import android.view.ViewGroup.LayoutParams;
+import android.view.WindowManager;
+import android.widget.ImageView;
+
+import java.nio.ByteBuffer;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * Tests that applications can create virtual displays and present content on them.
+ *
+ * Contains additional tests that cannot be included in CTS because they require
+ * system permissions.  See also the CTS version of VirtualDisplayTest.
+ */
+public class VirtualDisplayTest extends AndroidTestCase {
+    private static final String TAG = "VirtualDisplayTest";
+
+    private static final String NAME = TAG;
+    private static final int WIDTH = 720;
+    private static final int HEIGHT = 480;
+    private static final int DENSITY = DisplayMetrics.DENSITY_MEDIUM;
+    private static final int TIMEOUT = 10000;
+
+    // Colors that we use as a signal to determine whether some desired content was
+    // drawn.  The colors themselves doesn't matter but we choose them to have with distinct
+    // values for each color channel so as to detect possible RGBA vs. BGRA buffer format issues.
+    // We should only observe RGBA buffers but some graphics drivers might incorrectly
+    // deliver BGRA buffers to virtual displays instead.
+    private static final int BLUEISH = 0xff1122ee;
+    private static final int GREENISH = 0xff33dd44;
+
+    private DisplayManager mDisplayManager;
+    private Handler mHandler;
+    private final Lock mImageReaderLock = new ReentrantLock(true /*fair*/);
+    private ImageReader mImageReader;
+    private Surface mSurface;
+    private ImageListener mImageListener;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mDisplayManager = (DisplayManager)mContext.getSystemService(Context.DISPLAY_SERVICE);
+        mHandler = new Handler(Looper.getMainLooper());
+        mImageListener = new ImageListener();
+
+        mImageReaderLock.lock();
+        try {
+            mImageReader = new ImageReader(WIDTH, HEIGHT, PixelFormat.RGBA_8888, 2);
+            mImageReader.setImageAvailableListener(mImageListener, mHandler);
+            mSurface = mImageReader.getSurface();
+        } finally {
+            mImageReaderLock.unlock();
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+
+        mImageReaderLock.lock();
+        try {
+            mImageReader.close();
+            mImageReader = null;
+            mSurface = null;
+        } finally {
+            mImageReaderLock.unlock();
+        }
+    }
+
+    /**
+     * Ensures that an application can create a private virtual display and show
+     * its own windows on it.
+     */
+    public void testPrivateVirtualDisplay() throws Exception {
+        VirtualDisplay virtualDisplay = mDisplayManager.createVirtualDisplay(NAME,
+                WIDTH, HEIGHT, DENSITY, mSurface, 0);
+        assertNotNull("virtual display must not be null", virtualDisplay);
+
+        Display display = virtualDisplay.getDisplay();
+        try {
+            assertDisplayRegistered(display, Display.FLAG_PRIVATE);
+
+            // Show a private presentation on the display.
+            assertDisplayCanShowPresentation("private presentation window",
+                    display, BLUEISH,
+                    WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION, 0);
+        } finally {
+            virtualDisplay.release();
+        }
+        assertDisplayUnregistered(display);
+    }
+
+    /**
+     * Ensures that an application can create a private presentation virtual display and show
+     * its own windows on it.
+     */
+    public void testPrivatePresentationVirtualDisplay() throws Exception {
+        VirtualDisplay virtualDisplay = mDisplayManager.createVirtualDisplay(NAME,
+                WIDTH, HEIGHT, DENSITY, mSurface,
+                DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION);
+        assertNotNull("virtual display must not be null", virtualDisplay);
+
+        Display display = virtualDisplay.getDisplay();
+        try {
+            assertDisplayRegistered(display, Display.FLAG_PRIVATE | Display.FLAG_PRESENTATION);
+
+            // Show a private presentation on the display.
+            assertDisplayCanShowPresentation("private presentation window",
+                    display, BLUEISH,
+                    WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION, 0);
+        } finally {
+            virtualDisplay.release();
+        }
+        assertDisplayUnregistered(display);
+    }
+
+    /**
+     * Ensures that an application can create a public virtual display and show
+     * its own windows on it.  This test requires the CAPTURE_VIDEO_OUTPUT permission.
+     *
+     * Because this test does not have an activity token, we use the TOAST window
+     * type to create the window.  Another choice might be SYSTEM_ALERT_WINDOW but
+     * that requires a permission.
+     */
+    public void testPublicPresentationVirtualDisplay() throws Exception {
+        VirtualDisplay virtualDisplay = mDisplayManager.createVirtualDisplay(NAME,
+                WIDTH, HEIGHT, DENSITY, mSurface,
+                DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC
+                        | DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION);
+        assertNotNull("virtual display must not be null", virtualDisplay);
+
+        Display display = virtualDisplay.getDisplay();
+        try {
+            assertDisplayRegistered(display, Display.FLAG_PRESENTATION);
+
+            // Mirroring case.
+            // Show a window on the default display.  It should be mirrored to the
+            // virtual display automatically.
+            Display defaultDisplay = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
+            assertDisplayCanShowPresentation("mirrored window",
+                    defaultDisplay, GREENISH,
+                    WindowManager.LayoutParams.TYPE_TOAST, 0);
+
+            // Mirroring case with secure window (but display is not secure).
+            // Show a window on the default display.  It should be replaced with black on
+            // the virtual display.
+            assertDisplayCanShowPresentation("mirrored secure window on non-secure display",
+                    defaultDisplay, Color.BLACK,
+                    WindowManager.LayoutParams.TYPE_TOAST,
+                    WindowManager.LayoutParams.FLAG_SECURE);
+
+            // Presentation case.
+            // Show a normal presentation on the display.
+            assertDisplayCanShowPresentation("presentation window",
+                    display, BLUEISH,
+                    WindowManager.LayoutParams.TYPE_TOAST, 0);
+
+            // Presentation case with secure window (but display is not secure).
+            // Show a normal presentation on the display.  It should be replaced with black.
+            assertDisplayCanShowPresentation("secure presentation window on non-secure display",
+                    display, Color.BLACK,
+                    WindowManager.LayoutParams.TYPE_TOAST,
+                    WindowManager.LayoutParams.FLAG_SECURE);
+        } finally {
+            virtualDisplay.release();
+        }
+        assertDisplayUnregistered(display);
+    }
+
+    /**
+     * Ensures that an application can create a secure public virtual display and show
+     * its own windows on it.  This test requires the CAPTURE_SECURE_VIDEO_OUTPUT permission.
+     *
+     * Because this test does not have an activity token, we use the TOAST window
+     * type to create the window.  Another choice might be SYSTEM_ALERT_WINDOW but
+     * that requires a permission.
+     */
+    public void testSecurePublicPresentationVirtualDisplay() throws Exception {
+        VirtualDisplay virtualDisplay = mDisplayManager.createVirtualDisplay(NAME,
+                WIDTH, HEIGHT, DENSITY, mSurface,
+                DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE
+                        | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC
+                        | DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION);
+        assertNotNull("virtual display must not be null", virtualDisplay);
+
+        Display display = virtualDisplay.getDisplay();
+        try {
+            assertDisplayRegistered(display, Display.FLAG_PRESENTATION | Display.FLAG_SECURE);
+
+            // Mirroring case with secure window (and display is secure).
+            // Show a window on the default display.  It should be mirrored to the
+            // virtual display automatically.
+            Display defaultDisplay = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
+            assertDisplayCanShowPresentation("mirrored secure window on secure display",
+                    defaultDisplay, GREENISH,
+                    WindowManager.LayoutParams.TYPE_TOAST,
+                    WindowManager.LayoutParams.FLAG_SECURE);
+
+            // Presentation case with secure window (and display is secure).
+            // Show a normal presentation on the display.
+            assertDisplayCanShowPresentation("secure presentation window on secure display",
+                    display, BLUEISH,
+                    WindowManager.LayoutParams.TYPE_TOAST,
+                    WindowManager.LayoutParams.FLAG_SECURE);
+        } finally {
+            virtualDisplay.release();
+        }
+        assertDisplayUnregistered(display);
+    }
+
+    private void assertDisplayRegistered(Display display, int flags) {
+        assertNotNull("display object must not be null", display);
+        assertTrue("display must be valid", display.isValid());
+        assertTrue("display id must be unique",
+                display.getDisplayId() != Display.DEFAULT_DISPLAY);
+        assertEquals("display must have correct flags", flags, display.getFlags());
+        assertEquals("display name must match supplied name", NAME, display.getName());
+        Point size = new Point();
+        display.getSize(size);
+        assertEquals("display width must match supplied width", WIDTH, size.x);
+        assertEquals("display height must match supplied height", HEIGHT, size.y);
+        assertEquals("display rotation must be 0",
+                Surface.ROTATION_0, display.getRotation());
+        assertNotNull("display must be registered",
+                findDisplay(mDisplayManager.getDisplays(), NAME));
+
+        if ((flags & Display.FLAG_PRESENTATION) != 0) {
+            assertNotNull("display must be registered as a presentation display",
+                    findDisplay(mDisplayManager.getDisplays(
+                            DisplayManager.DISPLAY_CATEGORY_PRESENTATION), NAME));
+        } else {
+            assertNull("display must not be registered as a presentation display",
+                    findDisplay(mDisplayManager.getDisplays(
+                            DisplayManager.DISPLAY_CATEGORY_PRESENTATION), NAME));
+        }
+    }
+
+    private void assertDisplayUnregistered(Display display) {
+        assertNull("display must no longer be registered after being removed",
+                findDisplay(mDisplayManager.getDisplays(), NAME));
+        assertFalse("display must no longer be valid", display.isValid());
+    }
+
+    private void assertDisplayCanShowPresentation(String message, final Display display,
+            final int color, final int windowType, final int windowFlags) {
+        // At this point, we should not have seen any blue.
+        assertTrue(message + ": display should not show content before window is shown",
+                mImageListener.getColor() != color);
+
+        final TestPresentation[] presentation = new TestPresentation[1];
+        try {
+            // Show the presentation.
+            runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    presentation[0] = new TestPresentation(getContext(), display,
+                            color, windowType, windowFlags);
+                    presentation[0].show();
+                }
+            });
+
+            // Wait for the blue to be seen.
+            assertTrue(message + ": display should show content after window is shown",
+                    mImageListener.waitForColor(color, TIMEOUT));
+        } finally {
+            if (presentation[0] != null) {
+                runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        presentation[0].dismiss();
+                    }
+                });
+            }
+        }
+    }
+
+    private void runOnUiThread(Runnable runnable) {
+        Runnable waiter = new Runnable() {
+            @Override
+            public void run() {
+                synchronized (this) {
+                    notifyAll();
+                }
+            }
+        };
+        synchronized (waiter) {
+            mHandler.post(runnable);
+            mHandler.post(waiter);
+            try {
+                waiter.wait(TIMEOUT);
+            } catch (InterruptedException ex) {
+            }
+        }
+    }
+
+    private Display findDisplay(Display[] displays, String name) {
+        for (int i = 0; i < displays.length; i++) {
+            if (displays[i].getName().equals(name)) {
+                return displays[i];
+            }
+        }
+        return null;
+    }
+
+    private final class TestPresentation extends Presentation {
+        private final int mColor;
+        private final int mWindowType;
+        private final int mWindowFlags;
+
+        public TestPresentation(Context context, Display display,
+                int color, int windowType, int windowFlags) {
+            super(context, display);
+            mColor = color;
+            mWindowType = windowType;
+            mWindowFlags = windowFlags;
+        }
+
+        @Override
+        protected void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+
+            setTitle(TAG);
+            getWindow().setType(mWindowType);
+            getWindow().addFlags(mWindowFlags);
+
+            // Create a solid color image to use as the content of the presentation.
+            ImageView view = new ImageView(getContext());
+            view.setImageDrawable(new ColorDrawable(mColor));
+            view.setLayoutParams(new LayoutParams(
+                    LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
+            setContentView(view);
+        }
+    }
+
+    /**
+     * Watches for an image with a large amount of some particular solid color to be shown.
+     */
+    private final class ImageListener
+            implements ImageReader.OnImageAvailableListener {
+        private int mColor = -1;
+
+        public int getColor() {
+            synchronized (this) {
+                return mColor;
+            }
+        }
+
+        public boolean waitForColor(int color, long timeoutMillis) {
+            long timeoutTime = SystemClock.uptimeMillis() + timeoutMillis;
+            synchronized (this) {
+                while (mColor != color) {
+                    long now = SystemClock.uptimeMillis();
+                    if (now >= timeoutTime) {
+                        return false;
+                    }
+                    try {
+                        wait(timeoutTime - now);
+                    } catch (InterruptedException ex) {
+                    }
+                }
+                return true;
+            }
+        }
+
+        @Override
+        public void onImageAvailable(ImageReader reader) {
+            mImageReaderLock.lock();
+            try {
+                if (reader != mImageReader) {
+                    return;
+                }
+
+                Log.d(TAG, "New image available from virtual display.");
+                Image image = reader.getNextImage();
+                if (image != null) {
+                    try {
+                        // Get the latest buffer.
+                        for (;;) {
+                            Image nextImage = reader.getNextImage();
+                            if (nextImage == null) {
+                                break;
+                            }
+                            reader.releaseImage(image);
+                            image = nextImage;
+                        }
+
+                        // Scan for colors.
+                        int color = scanImage(image);
+                        synchronized (this) {
+                            if (mColor != color) {
+                                mColor = color;
+                                notifyAll();
+                            }
+                        }
+                    } finally {
+                        reader.releaseImage(image);
+                    }
+                }
+            } finally {
+                mImageReaderLock.unlock();
+            }
+        }
+
+        private int scanImage(Image image) {
+            final Image.Plane plane = image.getPlanes()[0];
+            final ByteBuffer buffer = plane.getBuffer();
+            final int width = image.getWidth();
+            final int height = image.getHeight();
+            final int pixelStride = plane.getPixelStride();
+            final int rowStride = plane.getRowStride();
+            final int rowPadding = rowStride - pixelStride * width;
+
+            Log.d(TAG, "- Scanning image: width=" + width + ", height=" + height
+                    + ", pixelStride=" + pixelStride + ", rowStride=" + rowStride);
+
+            int offset = 0;
+            int blackPixels = 0;
+            int bluePixels = 0;
+            int greenPixels = 0;
+            int otherPixels = 0;
+            for (int y = 0; y < height; y++) {
+                for (int x = 0; x < width; x++) {
+                    int pixel = 0;
+                    pixel |= (buffer.get(offset) & 0xff) << 16;     // R
+                    pixel |= (buffer.get(offset + 1) & 0xff) << 8;  // G
+                    pixel |= (buffer.get(offset + 2) & 0xff);       // B
+                    pixel |= (buffer.get(offset + 3) & 0xff) << 24; // A
+                    if (pixel == Color.BLACK || pixel == 0) {
+                        blackPixels += 1;
+                    } else if (pixel == BLUEISH) {
+                        bluePixels += 1;
+                    } else if (pixel == GREENISH) {
+                        greenPixels += 1;
+                    } else {
+                        otherPixels += 1;
+                        if (otherPixels < 10) {
+                            Log.d(TAG, "- Found unexpected color: " + Integer.toHexString(pixel));
+                        }
+                    }
+                    offset += pixelStride;
+                }
+                offset += rowPadding;
+            }
+
+            // Return a color if it represents more than one quarter of the pixels.
+            // We use this threshold in case the display is being letterboxed when
+            // mirroring so there might be large black bars on the sides, which is normal.
+            Log.d(TAG, "- Pixels: " + blackPixels + " black, "
+                    + bluePixels + " blue, "
+                    + greenPixels + " green, "
+                    + otherPixels + " other");
+            final int threshold = width * height / 4;
+            if (bluePixels > threshold) {
+                Log.d(TAG, "- Reporting blue.");
+                return BLUEISH;
+            }
+            if (greenPixels > threshold) {
+                Log.d(TAG, "- Reporting green.");
+                return GREENISH;
+            }
+            if (blackPixels > threshold) {
+                Log.d(TAG, "- Reporting black.");
+                return Color.BLACK;
+            }
+            Log.d(TAG, "- Reporting other.");
+            return -1;
+        }
+    }
+}
+
diff --git a/core/tests/coretests/src/android/net/LinkPropertiesTest.java b/core/tests/coretests/src/android/net/LinkPropertiesTest.java
index d6a7ee2..e63f6b0 100644
--- a/core/tests/coretests/src/android/net/LinkPropertiesTest.java
+++ b/core/tests/coretests/src/android/net/LinkPropertiesTest.java
@@ -25,13 +25,18 @@
 import java.util.ArrayList;
 
 public class LinkPropertiesTest extends TestCase {
-    private static String ADDRV4 = "75.208.6.1";
-    private static String ADDRV6 = "2001:0db8:85a3:0000:0000:8a2e:0370:7334";
-    private static String DNS1 = "75.208.7.1";
-    private static String DNS2 = "69.78.7.1";
-    private static String GATEWAY1 = "75.208.8.1";
-    private static String GATEWAY2 = "69.78.8.1";
+    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 GATEWAY1 = NetworkUtils.numericToInetAddress("75.208.8.1");
+    private static InetAddress GATEWAY2 = NetworkUtils.numericToInetAddress("69.78.8.1");
     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);
 
     public void assertLinkPropertiesEqual(LinkProperties source, LinkProperties target) {
         // Check implementation of equals(), element by element.
@@ -53,6 +58,9 @@
         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));
@@ -76,43 +84,40 @@
             LinkProperties source = new LinkProperties();
             source.setInterfaceName(NAME);
             // set 2 link addresses
-            source.addLinkAddress(new LinkAddress(
-                    NetworkUtils.numericToInetAddress(ADDRV4), 32));
-            source.addLinkAddress(new LinkAddress(
-                    NetworkUtils.numericToInetAddress(ADDRV6), 128));
+            source.addLinkAddress(LINKADDRV4);
+            source.addLinkAddress(LINKADDRV6);
             // set 2 dnses
-            source.addDns(NetworkUtils.numericToInetAddress(DNS1));
-            source.addDns(NetworkUtils.numericToInetAddress(DNS2));
+            source.addDns(DNS1);
+            source.addDns(DNS2);
             // set 2 gateways
-            source.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(GATEWAY1)));
-            source.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(GATEWAY2)));
+            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(new LinkAddress(
-                    NetworkUtils.numericToInetAddress(ADDRV4), 32));
-            target.addLinkAddress(new LinkAddress(
-                    NetworkUtils.numericToInetAddress(ADDRV6), 128));
-            target.addDns(NetworkUtils.numericToInetAddress(DNS1));
-            target.addDns(NetworkUtils.numericToInetAddress(DNS2));
-            target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(GATEWAY1)));
-            target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(GATEWAY2)));
+            target.addLinkAddress(LINKADDRV4);
+            target.addLinkAddress(LINKADDRV6);
+            target.addDns(DNS1);
+            target.addDns(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(new LinkAddress(
-                    NetworkUtils.numericToInetAddress(ADDRV4), 32));
-            target.addLinkAddress(new LinkAddress(
-                    NetworkUtils.numericToInetAddress(ADDRV6), 128));
-            target.addDns(NetworkUtils.numericToInetAddress(DNS1));
-            target.addDns(NetworkUtils.numericToInetAddress(DNS2));
-            target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(GATEWAY1)));
-            target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(GATEWAY2)));
+            target.addLinkAddress(LINKADDRV4);
+            target.addLinkAddress(LINKADDRV6);
+            target.addDns(DNS1);
+            target.addDns(DNS2);
+            target.addRoute(new RouteInfo(GATEWAY1));
+            target.addRoute(new RouteInfo(GATEWAY2));
+            target.setMtu(MTU);
             assertFalse(source.equals(target));
 
             target.clear();
@@ -120,38 +125,48 @@
             // change link addresses
             target.addLinkAddress(new LinkAddress(
                     NetworkUtils.numericToInetAddress("75.208.6.2"), 32));
-            target.addLinkAddress(new LinkAddress(
-                    NetworkUtils.numericToInetAddress(ADDRV6), 128));
-            target.addDns(NetworkUtils.numericToInetAddress(DNS1));
-            target.addDns(NetworkUtils.numericToInetAddress(DNS2));
-            target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(GATEWAY1)));
-            target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(GATEWAY2)));
+            target.addLinkAddress(LINKADDRV6);
+            target.addDns(DNS1);
+            target.addDns(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(new LinkAddress(
-                    NetworkUtils.numericToInetAddress(ADDRV4), 32));
-            target.addLinkAddress(new LinkAddress(
-                    NetworkUtils.numericToInetAddress(ADDRV6), 128));
+            target.addLinkAddress(LINKADDRV4);
+            target.addLinkAddress(LINKADDRV6);
             // change dnses
             target.addDns(NetworkUtils.numericToInetAddress("75.208.7.2"));
-            target.addDns(NetworkUtils.numericToInetAddress(DNS2));
-            target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(GATEWAY1)));
-            target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(GATEWAY2)));
+            target.addDns(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(new LinkAddress(
-                    NetworkUtils.numericToInetAddress(ADDRV4), 32));
-            target.addLinkAddress(new LinkAddress(
-                    NetworkUtils.numericToInetAddress(ADDRV6), 128));
-            target.addDns(NetworkUtils.numericToInetAddress(DNS1));
-            target.addDns(NetworkUtils.numericToInetAddress(DNS2));
+            target.addLinkAddress(LINKADDRV4);
+            target.addLinkAddress(LINKADDRV6);
+            target.addDns(DNS1);
+            target.addDns(DNS2);
             // change gateway
             target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress("75.208.8.2")));
-            target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(GATEWAY2)));
+            target.addRoute(new RouteInfo(GATEWAY2));
+            target.setMtu(MTU);
+            assertFalse(source.equals(target));
+
+            target.clear();
+            target.setInterfaceName(NAME);
+            target.addLinkAddress(LINKADDRV4);
+            target.addLinkAddress(LINKADDRV6);
+            target.addDns(DNS1);
+            target.addDns(DNS2);
+            target.addRoute(new RouteInfo(GATEWAY1));
+            target.addRoute(new RouteInfo(GATEWAY2));
+            // change mtu
+            target.setMtu(1440);
             assertFalse(source.equals(target));
 
         } catch (Exception e) {
@@ -166,28 +181,26 @@
             LinkProperties source = new LinkProperties();
             source.setInterfaceName(NAME);
             // set 2 link addresses
-            source.addLinkAddress(new LinkAddress(
-                    NetworkUtils.numericToInetAddress(ADDRV4), 32));
-            source.addLinkAddress(new LinkAddress(
-                    NetworkUtils.numericToInetAddress(ADDRV6), 128));
+            source.addLinkAddress(LINKADDRV4);
+            source.addLinkAddress(LINKADDRV6);
             // set 2 dnses
-            source.addDns(NetworkUtils.numericToInetAddress(DNS1));
-            source.addDns(NetworkUtils.numericToInetAddress(DNS2));
+            source.addDns(DNS1);
+            source.addDns(DNS2);
             // set 2 gateways
-            source.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(GATEWAY1)));
-            source.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(GATEWAY2)));
+            source.addRoute(new RouteInfo(GATEWAY1));
+            source.addRoute(new RouteInfo(GATEWAY2));
+            source.setMtu(MTU);
 
             LinkProperties target = new LinkProperties();
             // Exchange order
             target.setInterfaceName(NAME);
-            target.addLinkAddress(new LinkAddress(
-                    NetworkUtils.numericToInetAddress(ADDRV6), 128));
-            target.addLinkAddress(new LinkAddress(
-                    NetworkUtils.numericToInetAddress(ADDRV4), 32));
-            target.addDns(NetworkUtils.numericToInetAddress(DNS2));
-            target.addDns(NetworkUtils.numericToInetAddress(DNS1));
-            target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(GATEWAY2)));
-            target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress(GATEWAY1)));
+            target.addLinkAddress(LINKADDRV6);
+            target.addLinkAddress(LINKADDRV4);
+            target.addDns(DNS2);
+            target.addDns(DNS1);
+            target.addRoute(new RouteInfo(GATEWAY2));
+            target.addRoute(new RouteInfo(GATEWAY1));
+            target.setMtu(MTU);
 
             assertLinkPropertiesEqual(source, target);
         } catch (Exception e) {
@@ -200,21 +213,15 @@
         try {
             LinkProperties source = new LinkProperties();
             // set 3 link addresses, eg, [A, A, B]
-            source.addLinkAddress(new LinkAddress(
-                    NetworkUtils.numericToInetAddress(ADDRV4), 32));
-            source.addLinkAddress(new LinkAddress(
-                    NetworkUtils.numericToInetAddress(ADDRV4), 32));
-            source.addLinkAddress(new LinkAddress(
-                    NetworkUtils.numericToInetAddress(ADDRV6), 128));
+            source.addLinkAddress(LINKADDRV4);
+            source.addLinkAddress(LINKADDRV4);
+            source.addLinkAddress(LINKADDRV6);
 
             LinkProperties target = new LinkProperties();
             // set 3 link addresses, eg, [A, B, B]
-            target.addLinkAddress(new LinkAddress(
-                    NetworkUtils.numericToInetAddress(ADDRV4), 32));
-            target.addLinkAddress(new LinkAddress(
-                    NetworkUtils.numericToInetAddress(ADDRV6), 128));
-            target.addLinkAddress(new LinkAddress(
-                    NetworkUtils.numericToInetAddress(ADDRV6), 128));
+            target.addLinkAddress(LINKADDRV4);
+            target.addLinkAddress(LINKADDRV6);
+            target.addLinkAddress(LINKADDRV6);
 
             assertLinkPropertiesEqual(source, target);
         } catch (Exception e) {
@@ -232,7 +239,7 @@
     public void testRouteInterfaces() {
         LinkAddress prefix = new LinkAddress(
             NetworkUtils.numericToInetAddress("2001:db8::"), 32);
-        InetAddress address = NetworkUtils.numericToInetAddress(ADDRV6);
+        InetAddress address = ADDRV6;
 
         // Add a route with no interface to a LinkProperties with no interface. No errors.
         LinkProperties lp = new LinkProperties();
@@ -265,7 +272,7 @@
         assertAllRoutesHaveInterface("wlan0", lp);
 
         // Routes with null interfaces are converted to wlan0.
-        r = RouteInfo.makeHostRoute(NetworkUtils.numericToInetAddress(ADDRV6), null);
+        r = RouteInfo.makeHostRoute(ADDRV6, null);
         lp.addRoute(r);
         assertEquals(3, lp.getRoutes().size());
         assertAllRoutesHaveInterface("wlan0", lp);
@@ -273,28 +280,45 @@
         // Check comparisons work.
         LinkProperties lp2 = new LinkProperties(lp);
         assertAllRoutesHaveInterface("wlan0", lp);
-        assertEquals(0, lp.compareRoutes(lp2).added.size());
-        assertEquals(0, lp.compareRoutes(lp2).removed.size());
+        assertEquals(0, lp.compareAllRoutes(lp2).added.size());
+        assertEquals(0, lp.compareAllRoutes(lp2).removed.size());
 
         lp2.setInterfaceName("p2p0");
         assertAllRoutesHaveInterface("p2p0", lp2);
-        assertEquals(3, lp.compareRoutes(lp2).added.size());
-        assertEquals(3, lp.compareRoutes(lp2).removed.size());
+        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.
@@ -306,5 +330,76 @@
         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));
+    }
+
+    @SmallTest
+    public void testAddressMethods() {
+        LinkProperties lp = new LinkProperties();
+
+        // No addresses.
+        assertFalse(lp.hasIPv4Address());
+        assertFalse(lp.hasIPv6Address());
+
+        // 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.hasIPv6Address());
+        assertFalse(lp.hasIPv4Address());
+        assertFalse(lp.hasIPv6Address());
+        lp.removeStackedLink(stacked);
+        assertFalse(lp.hasIPv4Address());
+        assertFalse(lp.hasIPv6Address());
+
+        // Addresses on the base link.
+        // Check the return values of hasIPvXAddress and ensure the add/remove methods return true
+        // iff something changes.
+        assertTrue(lp.addLinkAddress(LINKADDRV6));
+        assertFalse(lp.hasIPv4Address());
+        assertTrue(lp.hasIPv6Address());
+
+        assertTrue(lp.removeLinkAddress(LINKADDRV6));
+        assertTrue(lp.addLinkAddress(LINKADDRV4));
+        assertTrue(lp.hasIPv4Address());
+        assertFalse(lp.hasIPv6Address());
+
+        assertTrue(lp.addLinkAddress(LINKADDRV6));
+        assertTrue(lp.hasIPv4Address());
+        assertTrue(lp.hasIPv6Address());
+
+        // Adding an address twice has no effect.
+        // Removing an address that's not present has no effect.
+        assertFalse(lp.addLinkAddress(LINKADDRV4));
+        assertTrue(lp.hasIPv4Address());
+        assertTrue(lp.removeLinkAddress(LINKADDRV4));
+        assertFalse(lp.hasIPv4Address());
+        assertFalse(lp.removeLinkAddress(LINKADDRV4));
+    }
+
+    @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));
     }
 }
diff --git a/core/tests/coretests/src/android/webkit/AccessibilityInjectorTest.java b/core/tests/coretests/src/android/webkit/AccessibilityInjectorTest.java
deleted file mode 100644
index 417a85f..0000000
--- a/core/tests/coretests/src/android/webkit/AccessibilityInjectorTest.java
+++ /dev/null
@@ -1,1809 +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.webkit;
-
-import android.accessibilityservice.AccessibilityService;
-import android.accessibilityservice.AccessibilityServiceInfo;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.Intent;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.SystemClock;
-import android.provider.Settings;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.view.KeyEvent;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
-
-/**
- * This is a test for the behavior of the {@link AccessibilityInjector}
- * which is used by {@link WebView} to provide basic accessibility support
- * in case JavaScript is disabled.
- * </p>
- * Note: This test works against the generated {@link AccessibilityEvent}s
- *       to so it also checks if the test for announcing navigation axis and
- *       status messages as appropriate.
- */
-public class AccessibilityInjectorTest
-    extends ActivityInstrumentationTestCase2<AccessibilityInjectorTestActivity> {
-
-    /** The timeout to wait for the expected selection. */
-    private static final long TIMEOUT_WAIT_FOR_SELECTION_STRING = 1000;
-
-    /** The timeout to wait for accessibility and the mock service to be enabled. */
-    private static final long TIMEOUT_ENABLE_ACCESSIBILITY_AND_MOCK_SERVICE = 1000;
-
-    /** The count of tests to detect when to shut down the service. */
-    private static final int TEST_CASE_COUNT = 19;
-
-    /** The meta state for pressed left ALT. */
-    private static final int META_STATE_ALT_LEFT_ON = KeyEvent.META_ALT_ON
-            | KeyEvent.META_ALT_LEFT_ON;
-
-    /** Prefix for the CSS style span appended by WebKit. */
-    private static final String APPLE_SPAN_PREFIX = "<span class=\"Apple-style-span\"";
-
-    /** Suffix for the CSS style span appended by WebKit. */
-    private static final String APPLE_SPAN_SUFFIX = "</span>";
-
-    /** The value for not specified selection string since null is a valid value. */
-    private static final String SELECTION_STRING_UNKNOWN = "Unknown";
-
-    /** Lock for locking the test. */
-    private static final Object sTestLock = new Object();
-
-    /** Key bindings used for testing. */
-    private static final String TEST_KEY_DINDINGS =
-        "0x13=0x01000100;" +
-        "0x14=0x01010100;" +
-        "0x15=0x04000000;" +
-        "0x16=0x04000000;" +
-        "0x200000013=0x03020701:0x03010201:0x03000101:0x03030001:0x03040001:0x03050001:0x03060001;" +
-        "0x200000014=0x03010001:0x03020101:0x03070201:0x03030701:0x03040701:0x03050701:0x03060701;" +
-        "0x200000015=0x03040301:0x03050401:0x03060501:0x03000601:0x03010601:0x03020601:0x03070601;" +
-        "0x200000016=0x03050601:0x03040501:0x03030401:0x03020301:0x03070301:0x03010301:0x03000301;";
-
-    /** Handle to the test for use by the mock service. */
-    private static AccessibilityInjectorTest sInstance;
-
-    /** Flag indicating if the accessibility service is ready to receive events. */
-    private static boolean sIsAccessibilityServiceReady;
-
-    /** The count of executed tests to detect when to toggle accessibility and the service. */
-    private static int sExecutedTestCount;
-
-    /** Worker thread with a handler to perform non test thread processing. */
-    private Worker mWorker;
-
-    /** Handle to the {@link WebView} to load data in. */
-    private WebView mWebView;
-
-    /** Used for caching the default bindings so they can be restored. */
-    private static String sDefaultKeyBindings;
-
-    /** The received selection string for assertion checking. */
-    private static String sReceivedSelectionString = SELECTION_STRING_UNKNOWN;
-
-    public AccessibilityInjectorTest() {
-        super(AccessibilityInjectorTestActivity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mWorker = new Worker();
-        sInstance = this;
-        if (sExecutedTestCount == 0) {
-            // until JUnit4 comes to play with @BeforeTest
-            disableAccessibilityAndMockAccessibilityService();
-            enableAccessibilityAndMockAccessibilityService();
-            injectTestWebContentKeyBindings();
-        }
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        if (mWorker != null) {
-            mWorker.stop();
-        }
-        if (sExecutedTestCount == TEST_CASE_COUNT) {
-            // until JUnit4 comes to play with @AfterTest
-            disableAccessibilityAndMockAccessibilityService();
-            restoreDefaultWebContentKeyBindings();
-        }
-        super.tearDown();
-    }
-
-    /**
-     * Tests navigation by character.
-     */
-    @LargeTest
-    public void testNavigationByCharacter() throws Exception {
-        // a bit ugly but helps detect beginning and end of all tests so accessibility
-        // and the mock service are not toggled on every test (expensive)
-        sExecutedTestCount++;
-
-        String html =
-            "<html>" +
-               "<head>" +
-               "</head>" +
-               "<body>" +
-                   "<p>" +
-                      "a<b>b</b>c" +
-                   "</p>" +
-                   "<p>" +
-                     "d" +
-                   "<p/>" +
-                   "e" +
-               "</body>" +
-             "</html>";
-
-        WebView webView = loadHTML(html);
-
-        // change navigation axis to word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, META_STATE_ALT_LEFT_ON);
-        assertSelectionString("1"); // expect the word navigation axis
-
-        // change navigation axis to character
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, META_STATE_ALT_LEFT_ON);
-        assertSelectionString("0"); // expect the character navigation axis
-
-        // go to the first character
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("a");
-
-        // go to the second character
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<b>b</b>");
-
-        // go to the third character
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("c");
-
-        // go to the fourth character
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("d");
-
-        // go to the fifth character
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("e");
-
-        // try to go past the last character
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString(null);
-
-        // go to the fifth character (reverse)
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("e");
-
-        // go to the fourth character (reverse)
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("d");
-
-        // go to the third character
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("c");
-
-        // go to the second character
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<b>b</b>");
-
-        // go to the first character
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("a");
-
-        // try to go before the first character
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString(null);
-
-        // go to the first character
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("a");
-
-        // go to the second character (reverse again)
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<b>b</b>");
-    }
-
-    /**
-     * Tests navigation by word.
-     */
-    @LargeTest
-    public void testNavigationByWord() throws Exception {
-        // a bit ugly but helps detect beginning and end of all tests so accessibility
-        // and the mock service are not toggled on every test (expensive)
-        sExecutedTestCount++;
-
-        String html =
-            "<html>" +
-               "<head>" +
-               "</head>" +
-               "<body>" +
-                   "<p>" +
-                      "This is <b>a</b> sentence" +
-                   "</p>" +
-                   "<p>" +
-                     " scattered " +
-                     "<p/>" +
-                     " all over " +
-                   "</p>" +
-                   "<div>" +
-                     "<p>the place.</p>" +
-                   "</div>" +
-               "</body>" +
-             "</html>";
-
-        WebView webView = loadHTML(html);
-
-        // change navigation axis to word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, META_STATE_ALT_LEFT_ON);
-        assertSelectionString("1"); // expect the word navigation axis
-
-        // go to the first word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("This");
-
-        // go to the second word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("is");
-
-        // go to the third word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<b>a</b>");
-
-        // go to the fourth word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("sentence");
-
-        // go to the fifth word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("scattered");
-
-        // go to the sixth word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("all");
-
-        // go to the seventh word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("over");
-
-        // go to the eight word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("the");
-
-        // go to the ninth word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("place");
-
-        // NOTE: WebKit selection returns the dot as a word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString(".");
-
-        // try to go past the last word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString(null);
-
-        // go to the last word (reverse)
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("place.");
-
-        // go to the eight word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("the");
-
-        // go to the seventh word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("over");
-
-        // go to the sixth word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("all");
-
-        // go to the fifth word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("scattered");
-
-        // go to the fourth word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("sentence");
-
-        // go to the third word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<b>a</b>");
-
-        // go to the second word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("is");
-
-        // go to the first word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("This");
-
-        // try to go before the first word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString(null);
-
-        // go to the first word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("This");
-
-        // go to the second word (reverse again)
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("is");
-    }
-
-    /**
-     * Tests navigation by sentence.
-     */
-    @LargeTest
-    public void testNavigationBySentence() throws Exception {
-        // a bit ugly but helps detect beginning and end of all tests so accessibility
-        // and the mock service are not toggled on every test (expensive)
-        sExecutedTestCount++;
-
-        String html =
-            "<html>" +
-              "<head>" +
-              "</head>" +
-              "<body>" +
-                "<div>" +
-                  "<p>" +
-                    "This is the first sentence of the first paragraph and has an <b>inline bold tag</b>." +
-                    "This is the second sentence of the first paragraph." +
-                  "</p>" +
-                  "<h1>This is a heading</h1>" +
-                  "<p>" +
-                    "This is the first sentence of the second paragraph." +
-                    "This is the second sentence of the second paragraph." +
-                  "</p>" +
-                "</div>" +
-              "</body>" +
-            "</html>";
-
-        WebView webView = loadHTML(html);
-
-        // Sentence axis is the default
-
-        // go to the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("This is the first sentence of the first paragraph and has an "
-                + "<b>inline bold tag</b>.");
-
-        // go to the second sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("This is the second sentence of the first paragraph.");
-
-        // go to the third sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("This is a heading");
-
-        // go to the fourth sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("This is the first sentence of the second paragraph.");
-
-        // go to the fifth sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("This is the second sentence of the second paragraph.");
-
-        // try to go past the last sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString(null);
-
-        // go to the fifth sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("This is the second sentence of the second paragraph.");
-
-        // go to the fourth sentence (reverse)
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("This is the first sentence of the second paragraph.");
-
-        // go to the third sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("This is a heading");
-
-        // go to the second sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("This is the second sentence of the first paragraph.");
-
-        // go to the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("This is the first sentence of the first paragraph and has an "
-                + "<b>inline bold tag</b>.");
-
-        // try to go before the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString(null);
-
-        // go to the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("This is the first sentence of the first paragraph and has an "
-                + "<b>inline bold tag</b>.");
-
-        // go to the second sentence (reverse again)
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("This is the second sentence of the first paragraph.");
-    }
-
-    /**
-     * Tests navigation by heading.
-     */
-    @LargeTest
-    public void testNavigationByHeading() throws Exception {
-        // a bit ugly but helps detect beginning and end of all tests so accessibility
-        // and the mock service are not toggled on every test (expensive)
-        sExecutedTestCount++;
-
-        String html =
-            "<!DOCTYPE html>" +
-            "<html>" +
-              "<head>" +
-              "</head>" +
-              "<body>" +
-                "<h1>Heading one</h1>" +
-                "<p>" +
-                  "This is some text" +
-                "</p>" +
-                "<h2>Heading two</h2>" +
-                "<p>" +
-                  "This is some text" +
-                "</p>" +
-                "<h3>Heading three</h3>" +
-                "<p>" +
-                  "This is some text" +
-                "</p>" +
-                "<h4>Heading four</h4>" +
-                "<p>" +
-                  "This is some text" +
-                "</p>" +
-                "<h5>Heading five</h5>" +
-                "<p>" +
-                  "This is some text" +
-                "</p>" +
-                "<h6>Heading six</h6>" +
-              "</body>" +
-            "</html>";
-
-        WebView webView = loadHTML(html);
-
-        // change navigation axis to heading
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_RIGHT, META_STATE_ALT_LEFT_ON);
-        assertSelectionString("3"); // expect the heading navigation axis
-
-        // go to the first heading
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<h1>Heading one</h1>");
-
-        // go to the second heading
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<h2>Heading two</h2>");
-
-        // go to the third heading
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<h3>Heading three</h3>");
-
-        // go to the fourth heading
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<h4>Heading four</h4>");
-
-        // go to the fifth heading
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<h5>Heading five</h5>");
-
-        // go to the sixth heading
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<h6>Heading six</h6>");
-
-        // try to go past the last heading
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString(null);
-
-        // go to the fifth heading (reverse)
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<h5>Heading five</h5>");
-
-        // go to the fourth heading
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<h4>Heading four</h4>");
-
-        // go to the third heading
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<h3>Heading three</h3>");
-
-        // go to the second heading
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<h2>Heading two</h2>");
-
-        // go to the first heading
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<h1>Heading one</h1>");
-
-        // try to go before the first heading
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString(null);
-
-        // go to the second heading (reverse again)
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<h2>Heading two</h2>");
-    }
-
-    /**
-     * Tests navigation by sibling.
-     */
-    @LargeTest
-    public void testNavigationBySibing() throws Exception {
-        // a bit ugly but helps detect beginning and end of all tests so accessibility
-        // and the mock service are not toggled on every test (expensive)
-        sExecutedTestCount++;
-
-        String html =
-            "<!DOCTYPE html>" +
-            "<html>" +
-              "<head>" +
-              "</head>" +
-              "<body>" +
-                "<h1>Heading one</h1>" +
-                "<p>" +
-                  "This is some text" +
-                "</p>" +
-                "<div>" +
-                  "<button>Input</button>" +
-                "</div>" +
-              "</body>" +
-            "</html>";
-
-        WebView webView = loadHTML(html);
-
-        // change navigation axis to heading
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_RIGHT, META_STATE_ALT_LEFT_ON);
-        assertSelectionString("3"); // expect the heading navigation axis
-
-        // change navigation axis to sibling
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_RIGHT, META_STATE_ALT_LEFT_ON);
-        assertSelectionString("4"); // expect the sibling navigation axis
-
-        // change navigation axis to parent/first child
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_RIGHT, META_STATE_ALT_LEFT_ON);
-        assertSelectionString("5"); // expect the parent/first child navigation axis
-
-        // go to the first child of the body
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<h1>Heading one</h1>");
-
-        // change navigation axis to sibling
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_LEFT, META_STATE_ALT_LEFT_ON);
-        assertSelectionString("4"); // expect the sibling navigation axis
-
-        // go to the next sibling
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<p>This is some text</p>");
-
-        // go to the next sibling
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<div><button>Input</button></div>");
-
-        // try to go past the last sibling
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString(null);
-
-        // go to the previous sibling (reverse)
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<p>This is some text</p>");
-
-        // go to the previous sibling
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<h1>Heading one</h1>");
-
-        // try to go before the previous sibling
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString(null);
-
-        // go to the next sibling (reverse again)
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<p>This is some text</p>");
-    }
-
-    /**
-     * Tests navigation by parent/first child.
-     */
-    @LargeTest
-    public void testNavigationByParentFirstChild() throws Exception {
-        // a bit ugly but helps detect beginning and end of all tests so accessibility
-        // and the mock service are not toggled on every test (expensive)
-        sExecutedTestCount++;
-
-        String html =
-            "<!DOCTYPE html>" +
-            "<html>" +
-              "<head>" +
-              "</head>" +
-              "<body>" +
-                "<div>" +
-                  "<button>Input</button>" +
-                "</div>" +
-              "</body>" +
-            "</html>";
-
-        WebView webView = loadHTML(html);
-
-        // change navigation axis to document
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_LEFT, META_STATE_ALT_LEFT_ON);
-        assertSelectionString("6"); // expect the document navigation axis
-
-        // change navigation axis to parent/first child
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_LEFT, META_STATE_ALT_LEFT_ON);
-        assertSelectionString("5"); // expect the parent/first child navigation axis
-
-        // go to the first child
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<div><button>Input</button></div>");
-
-        // go to the first child
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<button>Input</button>");
-
-        // try to go to the first child of a leaf element
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString(null);
-
-        // go to the parent (reverse)
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<div><button>Input</button></div>");
-
-        // go to the parent
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<body><div><button>Input</button></div></body>");
-
-        // try to go to the body parent
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString(null);
-
-        // go to the first child (reverse again)
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<div><button>Input</button></div>");
-    }
-
-    /**
-     * Tests navigation by document.
-     */
-    @LargeTest
-    public void testNavigationByDocument() throws Exception {
-        // a bit ugly but helps detect beginning and end of all tests so accessibility
-        // and the mock service are not toggled on every test (expensive)
-        sExecutedTestCount++;
-
-        String html =
-            "<!DOCTYPE html>" +
-            "<html>" +
-              "<head>" +
-              "</head>" +
-              "<body>" +
-                "<button>Click</button>" +
-              "</body>" +
-            "</html>";
-
-        WebView webView = loadHTML(html);
-
-        // change navigation axis to document
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_LEFT, META_STATE_ALT_LEFT_ON);
-        assertSelectionString("6"); // expect the document navigation axis
-
-        // go to the bottom of the document
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("Click");
-
-        // go to the top of the document (reverse)
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<body><button>Click</button></body>");
-
-        // go to the bottom of the document (reverse again)
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("Click");
-    }
-
-    /**
-     * Tests the sync between the text navigation and navigation by DOM elements.
-     */
-    @LargeTest
-    public void testSyncBetweenTextAndDomNodeNavigation() throws Exception {
-        // a bit ugly but helps detect beginning and end of all tests so accessibility
-        // and the mock service are not toggled on every test (expensive)
-        sExecutedTestCount++;
-
-        String html =
-            "<!DOCTYPE html>" +
-            "<html>" +
-              "<head>" +
-              "</head>" +
-              "<body>" +
-                "<p>" +
-                  "First" +
-                "</p>" +
-                "<button>Second</button>" +
-                "<p>" +
-                  "Third" +
-                "</p>" +
-              "</body>" +
-            "</html>";
-
-        WebView webView = loadHTML(html);
-
-        // change navigation axis to word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, META_STATE_ALT_LEFT_ON);
-        assertSelectionString("1"); // expect the word navigation axis
-
-        // go to the first word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("First");
-
-        // change navigation axis to heading
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_RIGHT, META_STATE_ALT_LEFT_ON);
-        assertSelectionString("3"); // expect the heading navigation axis
-
-        // change navigation axis to sibling
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_RIGHT, META_STATE_ALT_LEFT_ON);
-        assertSelectionString("4"); // expect the sibling navigation axis
-
-        // go to the next sibling
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<button>Second</button>");
-
-        // change navigation axis to character
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, META_STATE_ALT_LEFT_ON);
-        assertSelectionString("0"); // expect the character navigation axis
-
-        // change navigation axis to word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, META_STATE_ALT_LEFT_ON);
-        assertSelectionString("1"); // expect the word navigation axis
-
-        // go to the next word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("Third");
-    }
-
-    /**
-     * Tests that the selection does not cross anchor boundaries. This is a
-     * workaround for the asymmetric and inconsistent handling of text with
-     * links by WebKit while traversing by sentence.
-     */
-    @LargeTest
-    public void testEnforceSelectionDoesNotCrossAnchorBoundary1() throws Exception {
-        // a bit ugly but helps detect beginning and end of all tests so accessibility
-        // and the mock service are not toggled on every test (expensive)
-        sExecutedTestCount++;
-
-        String html =
-            "<!DOCTYPE html>" +
-            "<html>" +
-              "<head>" +
-              "</head>" +
-              "<body>" +
-                "<div>First</div>" +
-                "<p>" +
-                  "<a href=\"\">Second</a> Third" +
-                "</p>" +
-              "</body>" +
-            "</html>";
-
-        WebView webView = loadHTML(html);
-
-        // go to the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<div>First</div>");
-
-        // go to the second sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<a href=\"\">Second</a>");
-
-        // go to the third sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("Third");
-
-        // go to past the last sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString(null);
-
-        // go to the third sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("Third");
-
-        // go to the second sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<a href=\"\">Second</a>");
-
-        // go to the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("First");
-
-        // go to before the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString(null);
-
-        // go to the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<div>First</div>");
-    }
-
-    /**
-     * Tests that the selection does not cross anchor boundaries. This is a
-     * workaround for the asymmetric and inconsistent handling of text with
-     * links by WebKit while traversing by sentence.
-     */
-    @LargeTest
-    public void testEnforceSelectionDoesNotCrossAnchorBoundary2() throws Exception {
-        // a bit ugly but helps detect beginning and end of all tests so accessibility
-        // and the mock service are not toggled on every test (expensive)
-        sExecutedTestCount++;
-
-        String html =
-            "<!DOCTYPE html>" +
-            "<html>" +
-              "<head>" +
-              "</head>" +
-              "<body>" +
-                "<div>First</div>" +
-                "<a href=\"#\">Second</a>" +
-                "&nbsp;" +
-                "<a href=\"#\">Third</a>" +
-              "</body>" +
-            "</html>";
-
-        WebView webView = loadHTML(html);
-
-        // go to the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("First");
-
-        // go to the second sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<a href=\"#\">Second</a>");
-
-        // go to the third sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("&nbsp;");
-
-        // go to the fourth sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<a href=\"#\">Third</a>");
-
-        // go to past the last sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString(null);
-
-        // go to the fourth sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<a href=\"#\">Third</a>");
-
-        // go to the third sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("&nbsp;");
-
-        // go to the second sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<a href=\"#\">Second</a>");
-
-        // go to the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("First");
-
-        // go to before the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString(null);
-
-        // go to the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("First");
-    }
-
-    /**
-     * Tests that the selection does not cross anchor boundaries. This is a
-     * workaround for the asymmetric and inconsistent handling of text with
-     * links by WebKit while traversing by sentence.
-     */
-    @LargeTest
-    public void testEnforceSelectionDoesNotCrossAnchorBoundary3() throws Exception {
-        // a bit ugly but helps detect beginning and end of all tests so accessibility
-        // and the mock service are not toggled on every test (expensive)
-        sExecutedTestCount++;
-
-        String html =
-            "<!DOCTYPE html>" +
-            "<html>" +
-              "<head>" +
-              "</head>" +
-              "<body>" +
-                "<div>" +
-                  "First" +
-                "<div>" +
-                "<div>" +
-                  "<a href=\"#\">Second</a>" +
-                "</div>" +
-                "<div>" +
-                  "Third" +
-                "</div>" +
-              "</body>" +
-            "</html>";
-
-        WebView webView = loadHTML(html);
-
-        // go to the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("First");
-
-        // go to the second sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<a href=\"#\">Second</a>");
-
-        // go to the third sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("Third");
-
-        // go to past the last sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString(null);
-
-        // go to the third sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("Third");
-
-        // go to the second sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<a href=\"#\">Second</a>");
-
-        // go to the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("First");
-
-        // go to before the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString(null);
-
-        // go to the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("First");
-    }
-
-    /**
-     * Tests skipping of content with hidden visibility.
-     */
-    @LargeTest
-    public void testSkipVisibilityHidden() throws Exception {
-        // a bit ugly but helps detect beginning and end of all tests so accessibility
-        // and the mock service are not toggled on every test (expensive)
-        sExecutedTestCount++;
-
-        String html =
-            "<!DOCTYPE html>" +
-            "<html>" +
-              "<head>" +
-              "</head>" +
-              "<body>" +
-                "<div>First </div>" +
-                "<div style=\"visibility:hidden;\">Second</div>" +
-                "<div> Third</div>" +
-              "</body>" +
-            "</html>";
-
-        WebView webView = loadHTML(html);
-
-        // change navigation axis to word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, META_STATE_ALT_LEFT_ON);
-        assertSelectionString("1"); // expect the word navigation axis
-
-        // go to the first word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("First");
-
-        // go to the third word (the second is invisible)
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("Third");
-
-        // go to past the last sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString(null);
-
-        // go to the third word (the second is invisible)
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("Third");
-
-        // go to the first word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("First");
-
-        // go to before the first word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString(null);
-
-        // go to the first word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("First");
-    }
-
-    /**
-     * Tests skipping of content with display none.
-     */
-    @LargeTest
-    public void testSkipDisplayNone() throws Exception {
-        // a bit ugly but helps detect beginning and end of all tests so accessibility
-        // and the mock service are not toggled on every test (expensive)
-        sExecutedTestCount++;
-
-        String html =
-            "<!DOCTYPE html>" +
-            "<html>" +
-              "<head>" +
-              "</head>" +
-              "<body>" +
-                "<div>First</div>" +
-                "<div style=\"display: none;\">Second</div>" +
-                "<div>Third</div>" +
-              "</body>" +
-            "</html>";
-
-        WebView webView = loadHTML(html);
-
-        // change navigation axis to word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, META_STATE_ALT_LEFT_ON);
-        assertSelectionString("1"); // expect the word navigation axis
-
-        // go to the first word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("First");
-
-        // go to the third word (the second is invisible)
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("Third");
-
-        // go to past the last sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString(null);
-
-        // go to the third word (the second is invisible)
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("Third");
-
-        // go to the first word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("First");
-
-        // go to before the first word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString(null);
-
-        // go to the first word
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("First");
-    }
-
-    /**
-     * Tests for the selection not getting stuck.
-     *
-     * Note: The selection always proceeds but if it can
-     * be selecting the same content i.e. between the start
-     * and end are contained the same text nodes.
-     */
-    @LargeTest
-    public void testSelectionTextProceed() throws Exception {
-        // a bit ugly but helps detect beginning and end of all tests so accessibility
-        // and the mock service are not toggled on every test (expensive)
-        sExecutedTestCount++;
-
-        String html =
-            "<!DOCTYPE html>" +
-            "<html>" +
-              "<head>" +
-              "</head>" +
-              "<body>" +
-                "<a href=\"#\">First</a>" +
-                "<span><a href=\"#\"><span>Second</span>&nbsp;<small>a</small></a>" +
-                "</span>&nbsp;<a href=\"#\">Third</a>" +
-              "</body>" +
-            "</html>";
-
-        WebView webView = loadHTML(html);
-
-        // go to the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<a href=\"#\">First</a>");
-
-        // go to the second sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<a href=\"#\"><span>Second&nbsp;<small>a</small></a>");
-
-        // go to the third sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("&nbsp;");
-
-        // go to the fourth sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<a href=\"#\">Third</a>");
-
-        // go to past the last sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString(null);
-
-        // go to the third sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<a href=\"#\">Third</a>");
-
-        // NOTE: Here we are a bit asymmetric around whitespace but we can live with it
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("&nbsp;");
-
-        // go to the second sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<a href=\"#\"><span>Second&nbsp;<small>a</small></a>");
-
-        // go to the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<a href=\"#\">First</a>");
-
-        // go to before the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString(null);
-
-        // go to the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<a href=\"#\">First</a>");
-    }
-
-    /**
-     * Tests if input elements are selected rather skipped.
-     */
-    @LargeTest
-    public void testSelectionOfInputElements() throws Exception {
-        // a bit ugly but helps detect beginning and end of all tests so accessibility
-        // and the mock service are not toggled on every test (expensive)
-        sExecutedTestCount++;
-
-        String html =
-            "<!DOCTYPE html>" +
-            "<html>" +
-              "<head>" +
-              "</head>" +
-              "<body>" +
-                "<p>" +
-                  "First" +
-                "</p>" +
-                "<input type=\"text\"/>" +
-                "<p>" +
-                  "Second" +
-                "</p>" +
-              "</body>" +
-            "</html>";
-
-        WebView webView = loadHTML(html);
-
-        // go to the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("First");
-
-        // go to the second sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<input type=\"text\">");
-
-        // go to the third sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("Second");
-
-        // go to past the last sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString(null);
-
-        // go to the third sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("Second");
-
-        // go to the second sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<input type=\"text\">");
-
-        // go to the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("First");
-
-        // go to before the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString(null);
-
-        // go to the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("First");
-    }
-
-    /**
-     * Tests traversing of input controls.
-     */
-    @LargeTest
-    public void testSelectionOfInputElements2() throws Exception {
-        // a bit ugly but helps detect beginning and end of all tests so accessibility
-        // and the mock service are not toggled on every test (expensive)
-        sExecutedTestCount++;
-
-        String html =
-            "<!DOCTYPE html>" +
-            "<html>" +
-              "<head>" +
-              "</head>" +
-              "<body>" +
-                "<div>" +
-                  "First" +
-                  "<input type=\"text\"/>" +
-                  "<span>" +
-                    "<input type=\"text\"/>" +
-                  "</span>" +
-                  "<button type=\"button\">Click Me!</button>" +
-                  "<div>" +
-                    "<input type=\"submit\"/>" +
-                  "</div>" +
-                  "<p>" +
-                    "Second" +
-                  "</p>" +
-                "</div>" +
-              "</body>" +
-            "</html>";
-
-        WebView webView = loadHTML(html);
-
-        // go to the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("First");
-
-        // go to the second sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<input type=\"text\">");
-
-        // go to the third sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<input type=\"text\">");
-
-        // go to the fourth sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<button type=\"button\">Click Me!</button>");
-
-        // go to the fifth sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<input type=\"submit\">");
-
-        // go to the sixth sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("Second");
-
-        // go to past the last sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString(null);
-
-        // go to the sixth sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("Second");
-
-        // go to the fifth sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<input type=\"submit\">");
-
-        // go to the fourth sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<button type=\"button\">Click Me!</button>");
-
-        // go to the third sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<input type=\"text\">");
-
-        // go to the second sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<input type=\"text\">");
-
-        // go to the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("First");
-    }
-
-    /**
-     * Tests traversing of input controls.
-     */
-    @LargeTest
-    public void testSelectionOfInputElements3() throws Exception {
-        // a bit ugly but helps detect beginning and end of all tests so accessibility
-        // and the mock service are not toggled on every test (expensive)
-        sExecutedTestCount++;
-
-        String html =
-            "<!DOCTYPE html>" +
-            "<html>" +
-              "<head>" +
-              "</head>" +
-              "<body>" +
-                "<input type=\"text\"/>" +
-                "<button type=\"button\">Click Me!</button>" +
-                "<select>" +
-                  "<option value=\"volvo\">Volvo</option>" +
-                  "<option value=\"saab\">Saab</option>" +
-                "</select>" +
-              "</body>" +
-            "</html>";
-
-        WebView webView = loadHTML(html);
-
-        // go to the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<input type=\"text\">");
-
-        // go to the second sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<button type=\"button\">Click Me!</button>");
-
-        // go to the third sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<select><option value=\"volvo\">Volvo</option>" +
-                "<option value=\"saab\">Saab</option></select>");
-
-        // go to past the last sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString(null);
-
-        // go to the third sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<select><option value=\"volvo\">Volvo</option>" +
-                "<option value=\"saab\">Saab</option></select>");
-
-        // go to the second sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<button type=\"button\">Click Me!</button>");
-
-        // go to the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<input type=\"text\">");
-
-        // go to before the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString(null);
-
-        // go to the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<input type=\"text\">");
-    }
-
-    /**
-     * Tests traversing of input controls.
-     */
-    @LargeTest
-    public void testSelectionOfInputElements4() throws Exception {
-        // a bit ugly but helps detect beginning and end of all tests so accessibility
-        // and the mock service are not toggled on every test (expensive)
-        sExecutedTestCount++;
-
-        String html =
-            "<!DOCTYPE html>" +
-            "<html>" +
-              "<head>" +
-              "</head>" +
-              "<body>" +
-                "Start" +
-                "<span>" +
-                  "<span>" +
-                    "<input type=\"submit\">" +
-                  "</span>" +
-                "</span>" +
-                "<input type=\"text\" size=\"30\">" +
-                "<span>" +
-                  "<span>" +
-                    "<input type=\"submit\" size=\"30\">" +
-                  "</span>" +
-                "</span>" +
-                "End" +
-              "</body>" +
-            "</html>";
-
-        WebView webView = loadHTML(html);
-
-        // go to the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("Start");
-
-        // go to the second sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<input type=\"submit\">");
-
-        // go to the third sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<input type=\"text\" size=\"30\">");
-
-        // go to the fourth sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<input type=\"submit\" size=\"30\">");
-
-        // go to the fifth sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("End");
-
-        // go to past the last sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString(null);
-
-        // go to the fifth sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("End");
-
-        // go to the fourth sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<input type=\"submit\" size=\"30\">");
-
-        // go to the third sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<input type=\"text\" size=\"30\">");
-
-        // go to the second sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<input type=\"submit\">");
-
-        // go to the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("Start");
-
-        // go to before the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString(null);
-
-        // go to the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("Start");
-    }
-
-    /**
-     * Tests traversing of input controls.
-     */
-    @LargeTest
-    public void testSelectionOfInputElements5() throws Exception {
-        // a bit ugly but helps detect beginning and end of all tests so accessibility
-        // and the mock service are not toggled on every test (expensive)
-        sExecutedTestCount++;
-
-        String html =
-            "<!DOCTYPE html>" +
-            "<html>" +
-              "<head>" +
-              "</head>" +
-              "<body>" +
-                "<div>" +
-                  "First" +
-                  "<input type=\"hidden\">" +
-                  "<input type=\"hidden\">" +
-                  "<input type=\"hidden\">" +
-                  "<input type=\"hidden\">" +
-                  "<input type=\"text\">" +
-                  "<span>" +
-                    "<span>" +
-                      "<input type=\"submit\">" +
-                    "</span>" +
-                  "</span>" +
-                "</div>" +
-              "</body>" +
-              "Second" +
-            "</html>";
-
-        WebView webView = loadHTML(html);
-
-        // go to the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("First");
-
-        // go to the second sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<input type=\"text\">");
-
-        // go to the third sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("<input type=\"submit\">");
-
-        // go to the fourth sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("Second");
-
-        // go to past the last sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString(null);
-
-        // go to the fourth sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("Second");
-
-        // go to the third sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<input type=\"submit\">");
-
-        // go to the second sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("<input type=\"text\">");
-
-        // go to the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString("First");
-
-        // go to before the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
-        assertSelectionString(null);
-
-        // go to the first sentence
-        sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
-        assertSelectionString("First");
-    }
-
-    /**
-     * Enable accessibility and the mock accessibility service.
-     */
-    private void enableAccessibilityAndMockAccessibilityService() {
-        // make sure the manager is instantiated so the system initializes it
-        AccessibilityManager.getInstance(getActivity());
-
-        // enable accessibility and the mock accessibility service
-        Settings.Secure.putInt(getActivity().getContentResolver(),
-                Settings.Secure.ACCESSIBILITY_ENABLED, 1);
-        String enabledServices = new ComponentName(getActivity().getPackageName(),
-                MockAccessibilityService.class.getName()).flattenToShortString();
-        Settings.Secure.putString(getActivity().getContentResolver(),
-                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, enabledServices);
-
-        // poll within a timeout and let be interrupted in case of success
-        long incrementStep = TIMEOUT_ENABLE_ACCESSIBILITY_AND_MOCK_SERVICE / 5;
-        long start = SystemClock.uptimeMillis();
-        while (SystemClock.uptimeMillis() - start < TIMEOUT_ENABLE_ACCESSIBILITY_AND_MOCK_SERVICE &&
-                !sIsAccessibilityServiceReady) {
-            synchronized (sTestLock) {
-                try {
-                    sTestLock.wait(incrementStep);
-                } catch (InterruptedException ie) {
-                    /* ignore */
-                }
-            }
-        }
-
-        if (!sIsAccessibilityServiceReady) {
-            throw new IllegalStateException("MockAccessibilityService not ready. Did you add " +
-                    "tests and forgot to update AccessibilityInjectorTest#TEST_CASE_COUNT?");
-        }
-    }
-
-    @Override
-    protected void scrubClass(Class<?> testCaseClass) {
-        /* do nothing - avoid superclass behavior */
-    }
-
-    /**
-     * Strips the apple span appended by WebKit while generating
-     * the selection markup.
-     *
-     * @param markup The markup.
-     * @return Stripped from apple spans markup.
-     */
-    private static String stripAppleSpanFromMarkup(String markup) {
-        StringBuilder stripped = new StringBuilder(markup);
-        int prefixBegIdx = stripped.indexOf(APPLE_SPAN_PREFIX);
-        while (prefixBegIdx >= 0) {
-            int prefixEndIdx = stripped.indexOf(">", prefixBegIdx) + 1;
-            stripped.replace(prefixBegIdx, prefixEndIdx, "");
-            int suffixBegIdx = stripped.lastIndexOf(APPLE_SPAN_SUFFIX);
-            int suffixEndIdx = suffixBegIdx + APPLE_SPAN_SUFFIX.length();
-            stripped.replace(suffixBegIdx, suffixEndIdx, "");
-            prefixBegIdx = stripped.indexOf(APPLE_SPAN_PREFIX);
-        }
-        return stripped.toString();
-    }
-
-    /**
-     * Disables accessibility and the mock accessibility service.
-     */
-    private void disableAccessibilityAndMockAccessibilityService() {
-        // disable accessibility and the mock accessibility service
-        Settings.Secure.putInt(getActivity().getContentResolver(),
-                Settings.Secure.ACCESSIBILITY_ENABLED, 0);
-        Settings.Secure.putString(getActivity().getContentResolver(),
-                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, "");
-    }
-
-    /**
-     * Asserts the next <code>expectedSelectionString</code> to be received.
-     */
-    private void assertSelectionString(String expectedSelectionString) {
-        assertTrue("MockAccessibilityService not ready", sIsAccessibilityServiceReady);
-
-        long incrementStep = TIMEOUT_WAIT_FOR_SELECTION_STRING / 5;
-        long start = SystemClock.uptimeMillis();
-        while (SystemClock.uptimeMillis() - start < TIMEOUT_WAIT_FOR_SELECTION_STRING &&
-                sReceivedSelectionString == SELECTION_STRING_UNKNOWN) {
-            synchronized (sTestLock) {
-                try {
-                    sTestLock.wait(incrementStep);
-                } catch (InterruptedException ie) {
-                    /* ignore */
-                }
-            }
-        }
-        try {
-            if (sReceivedSelectionString == SELECTION_STRING_UNKNOWN) {
-                fail("No selection string received. Expected: " + expectedSelectionString);
-            }
-            assertEquals(expectedSelectionString, sReceivedSelectionString);
-        } finally {
-            sReceivedSelectionString = SELECTION_STRING_UNKNOWN;
-        }
-    }
-
-    /**
-     * Sends a {@link KeyEvent} (up and down) to the {@link WebView}.
-     *
-     * @param keyCode The event key code.
-     */
-    private void sendKeyEvent(WebView webView, int keyCode, int metaState) {
-        webView.onKeyDown(keyCode, new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, keyCode, 1, metaState));
-        webView.onKeyUp(keyCode, new KeyEvent(0, 0, KeyEvent.ACTION_UP, keyCode, 1, metaState));
-    }
-
-    /**
-     * Loads HTML content in a {@link WebView}.
-     *
-     * @param html The HTML content;
-     * @return The {@link WebView} view.
-     */
-    private WebView loadHTML(final String html) {
-        mWorker.getHandler().post(new Runnable() {
-            public void run() {
-                if (mWebView == null) {
-                    mWebView = getActivity().getWebView();
-                    mWebView.setWebViewClient(new WebViewClient() {
-                        @Override
-                        public void onPageFinished(WebView view, String url) {
-                            mWorker.getHandler().post(new Runnable() {
-                                public void run() {
-                                    synchronized (sTestLock) {
-                                        sTestLock.notifyAll();
-                                    }
-                                }
-                            });
-                        }
-                    });
-                }
-                mWebView.loadData(html, "text/html", null);
-            }
-        });
-        synchronized (sTestLock) {
-            try {
-                sTestLock.wait();
-            } catch (InterruptedException ie) {
-                /* ignore */
-            }
-        }
-        return mWebView;
-    }
-
-    /**
-     * Injects web content key bindings used for testing. This is required
-     * to ensure that this test will be agnostic to changes of the bindings.
-     */
-    private void injectTestWebContentKeyBindings() {
-        ContentResolver contentResolver = getActivity().getContentResolver();
-        sDefaultKeyBindings = Settings.Secure.getString(contentResolver,
-                Settings.Secure.ACCESSIBILITY_WEB_CONTENT_KEY_BINDINGS);
-        Settings.Secure.putString(contentResolver,
-                Settings.Secure.ACCESSIBILITY_WEB_CONTENT_KEY_BINDINGS, TEST_KEY_DINDINGS);
-    }
-
-    /**
-     * Restores the default web content key bindings.
-     */
-    private void restoreDefaultWebContentKeyBindings() {
-        Settings.Secure.putString(getActivity().getContentResolver(),
-                Settings.Secure.ACCESSIBILITY_WEB_CONTENT_KEY_BINDINGS,
-                sDefaultKeyBindings);
-    }
-
-    /**
-     * This is a worker thread responsible for creating the {@link WebView}.
-     */
-    private class Worker implements Runnable {
-        private final Object mWorkerLock = new Object();
-        private Handler mHandler;
-
-       public Worker() {
-            new Thread(this).start();
-            synchronized (mWorkerLock) {
-                while (mHandler == null) {
-                    try {
-                        mWorkerLock.wait();
-                    } catch (InterruptedException ex) {
-                        /* ignore */
-                    }
-                }
-            }
-        }
-
-        public void run() {
-            synchronized (mWorkerLock) {
-                Looper.prepare();
-                mHandler = new Handler();
-                mWorkerLock.notifyAll();
-            }
-            Looper.loop();
-        }
-
-        public Handler getHandler() {
-            return mHandler;
-        }
-
-        public void stop() {
-            mHandler.getLooper().quit();
-        }
-    }
-
-    /**
-     * Mock accessibility service to receive the accessibility events
-     * with the current {@link WebView} selection.
-     */
-    public static class MockAccessibilityService extends AccessibilityService {
-        private boolean mIsServiceInfoSet;
-
-        @Override
-        protected void onServiceConnected() {
-            if (mIsServiceInfoSet) {
-                return;
-            }
-            AccessibilityServiceInfo info = new AccessibilityServiceInfo();
-            info.eventTypes = AccessibilityEvent.TYPE_VIEW_SELECTED;
-            info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
-            setServiceInfo(info);
-            mIsServiceInfoSet = true;
-
-            sIsAccessibilityServiceReady = true;
-
-            if (sInstance == null) {
-                return;
-            }
-            synchronized (sTestLock) {
-                sTestLock.notifyAll();
-            }
-        }
-
-        @Override
-        public void onAccessibilityEvent(AccessibilityEvent event) {
-            if (sInstance == null) {
-                return;
-            }
-            if (!event.getText().isEmpty()) {
-                CharSequence text = event.getText().get(0);
-                if (text != null) {
-                    sReceivedSelectionString = stripAppleSpanFromMarkup(text.toString());
-                } else {
-                    sReceivedSelectionString = null;
-                }
-            }
-            synchronized (sTestLock) {
-                sTestLock.notifyAll();
-            }
-        }
-
-        @Override
-        public void onInterrupt() {
-            /* do nothing */
-        }
-
-        @Override
-        public boolean onUnbind(Intent intent) {
-            sIsAccessibilityServiceReady = false;
-            return false;
-        }
-    }
-}
diff --git a/core/tests/coretests/src/android/webkit/AccessibilityInjectorTestActivity.java b/core/tests/coretests/src/android/webkit/AccessibilityInjectorTestActivity.java
deleted file mode 100644
index 3842df7..0000000
--- a/core/tests/coretests/src/android/webkit/AccessibilityInjectorTestActivity.java
+++ /dev/null
@@ -1,38 +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.webkit;
-
-import com.android.frameworks.coretests.R;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-public class AccessibilityInjectorTestActivity extends Activity {
-
-    private WebView mWebView;
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        setContentView(R.layout.accessibility_injector_test);
-        mWebView = (WebView) findViewById(R.id.webview);
-    }
-
-    public WebView getWebView() {
-        return mWebView;
-    }
-}
diff --git a/core/tests/coretests/src/android/webkit/UrlInterceptRegistryTest.java b/core/tests/coretests/src/android/webkit/UrlInterceptRegistryTest.java
deleted file mode 100644
index 7504449..0000000
--- a/core/tests/coretests/src/android/webkit/UrlInterceptRegistryTest.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.webkit;
-
-import android.test.AndroidTestCase;
-import android.util.Log;
-import android.webkit.CacheManager.CacheResult;
-import android.webkit.PluginData;
-import android.webkit.UrlInterceptHandler;
-
-import java.util.LinkedList;
-import java.util.Map;
-
-public class UrlInterceptRegistryTest extends AndroidTestCase {
-
-    /**
-     * To run these tests: $ mmm
-     * frameworks/base/tests/CoreTests/android && adb remount && adb
-     * sync $ adb shell am instrument -w  -e class \
-     * android.webkit.UrlInterceptRegistryTest \
-     * android.core/android.test.InstrumentationTestRunner
-     */
-
-    private static class MockUrlInterceptHandler implements UrlInterceptHandler {
-        private PluginData mData;
-        private String mUrl;
-
-        public MockUrlInterceptHandler(PluginData data, String url) {
-            mData = data;
-            mUrl = url;
-        }
-
-        public CacheResult service(String url, Map<String, String> headers) {
-            return null;
-        }
-
-        public PluginData getPluginData(String url,
-                                        Map<String,
-                                        String> headers) {
-            if (mUrl.equals(url)) {
-                return mData;
-            }
-
-            return null;
-        }
-    }
-
-    public void testGetPluginData() {
-        PluginData data = new PluginData(null, 0 , null, 200);
-        String url = new String("url1");
-        MockUrlInterceptHandler handler1 =
-                new MockUrlInterceptHandler(data, url);
-
-        data = new PluginData(null, 0 , null, 404);
-        url = new String("url2");
-        MockUrlInterceptHandler handler2 =
-                new MockUrlInterceptHandler(data, url);
-
-        assertTrue(UrlInterceptRegistry.registerHandler(handler1));
-        assertTrue(UrlInterceptRegistry.registerHandler(handler2));
-
-        data = UrlInterceptRegistry.getPluginData("url1", null);
-        assertTrue(data != null);
-        assertTrue(data.getStatusCode() == 200);
-
-        data = UrlInterceptRegistry.getPluginData("url2", null);
-        assertTrue(data != null);
-        assertTrue(data.getStatusCode() == 404);
-
-        assertTrue(UrlInterceptRegistry.unregisterHandler(handler1));
-        assertTrue(UrlInterceptRegistry.unregisterHandler(handler2));
-
-    }
-}
diff --git a/core/tests/coretests/src/android/webkit/WebkitTest.java b/core/tests/coretests/src/android/webkit/WebkitTest.java
deleted file mode 100644
index 4685e3c..0000000
--- a/core/tests/coretests/src/android/webkit/WebkitTest.java
+++ /dev/null
@@ -1,59 +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.webkit;
-
-import android.test.AndroidTestCase;
-import android.text.format.DateFormat;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.util.Log;
-import android.webkit.DateSorter;
-
-import java.util.Calendar;
-import java.util.Date;
-
-public class WebkitTest extends AndroidTestCase {
-
-    private static final String LOGTAG = WebkitTest.class.getName();
-
-    @MediumTest
-    public void testDateSorter() throws Exception {
-        /**
-         * Note: check the logging output manually to test
-         * nothing automated yet, besides object creation
-         */
-        DateSorter dateSorter = new DateSorter(mContext);
-        Date date = new Date();
-
-        for (int i = 0; i < DateSorter.DAY_COUNT; i++) {
-            Log.i(LOGTAG, "Boundary " + i + " " + dateSorter.getBoundary(i));
-            Log.i(LOGTAG, "Label " + i + " " + dateSorter.getLabel(i));
-        }
-
-        Calendar c = Calendar.getInstance();
-        long time = c.getTimeInMillis();
-        int index;
-        Log.i(LOGTAG, "now: " + dateSorter.getIndex(time));
-        for (int i = 0; i < 20; i++) {
-            time -= 8 * 60 * 60 * 1000; // 8 hours
-            date.setTime(time);
-            c.setTime(date);
-            index = dateSorter.getIndex(time);
-            Log.i(LOGTAG, "time: " + DateFormat.format("yyyy/MM/dd HH:mm:ss", c).toString() +
-                    " " + index + " " + dateSorter.getLabel(index));
-        }
-    }
-}
diff --git a/core/tests/coretests/src/android/webkit/ZoomManagerTest.java b/core/tests/coretests/src/android/webkit/ZoomManagerTest.java
deleted file mode 100644
index 7e0e0b2..0000000
--- a/core/tests/coretests/src/android/webkit/ZoomManagerTest.java
+++ /dev/null
@@ -1,128 +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.webkit;
-
-import android.test.AndroidTestCase;
-
-public class ZoomManagerTest extends AndroidTestCase {
-
-    private ZoomManager zoomManager;
-
-    @Override
-    public void setUp() {
-        WebView webView = new WebView(this.getContext());
-        WebViewClassic webViewClassic = WebViewClassic.fromWebView(webView);
-        CallbackProxy callbackProxy = new CallbackProxy(this.getContext(), webViewClassic);
-        zoomManager = new ZoomManager(webViewClassic, callbackProxy);
-
-        zoomManager.init(1.00f);
-    }
-
-    public void testInit() {
-        testInit(0.01f);
-        testInit(1.00f);
-        testInit(1.25f);
-    }
-
-    private void testInit(float density) {
-        zoomManager.init(density);
-        actualScaleTest(density);
-        defaultScaleTest(density);
-        assertEquals(zoomManager.getDefaultMaxZoomScale(), zoomManager.getMaxZoomScale());
-        assertEquals(zoomManager.getDefaultMinZoomScale(), zoomManager.getMinZoomScale());
-        assertEquals(density, zoomManager.getTextWrapScale());
-    }
-
-    public void testUpdateDefaultZoomDensity() {
-        // test the basic case where the actual values are equal to the defaults
-        testUpdateDefaultZoomDensity(0.01f);
-        testUpdateDefaultZoomDensity(1.00f);
-        testUpdateDefaultZoomDensity(1.25f);
-    }
-
-    private void testUpdateDefaultZoomDensity(float density) {
-        zoomManager.updateDefaultZoomDensity(density);
-        defaultScaleTest(density);
-    }
-
-    public void testUpdateDefaultZoomDensityWithSmallMinZoom() {
-        // test the case where the minZoomScale has changed to be < the default
-        float newDefaultScale = 1.50f;
-        float minZoomScale = ZoomManager.DEFAULT_MIN_ZOOM_SCALE_FACTOR * newDefaultScale;
-        WebViewCore.ViewState minViewState = new WebViewCore.ViewState();
-        minViewState.mMinScale = minZoomScale - 0.1f;
-        zoomManager.updateZoomRange(minViewState, 0, 0);
-        zoomManager.updateDefaultZoomDensity(newDefaultScale);
-        defaultScaleTest(newDefaultScale);
-    }
-
-    public void testUpdateDefaultZoomDensityWithLargeMinZoom() {
-        // test the case where the minZoomScale has changed to be > the default
-        float newDefaultScale = 1.50f;
-        float minZoomScale = ZoomManager.DEFAULT_MIN_ZOOM_SCALE_FACTOR * newDefaultScale;
-        WebViewCore.ViewState minViewState = new WebViewCore.ViewState();
-        minViewState.mMinScale = minZoomScale + 0.1f;
-        zoomManager.updateZoomRange(minViewState, 0, 0);
-        zoomManager.updateDefaultZoomDensity(newDefaultScale);
-        defaultScaleTest(newDefaultScale);
-    }
-
-    public void testUpdateDefaultZoomDensityWithSmallMaxZoom() {
-        // test the case where the maxZoomScale has changed to be < the default
-        float newDefaultScale = 1.50f;
-        float maxZoomScale = ZoomManager.DEFAULT_MAX_ZOOM_SCALE_FACTOR * newDefaultScale;
-        WebViewCore.ViewState maxViewState = new WebViewCore.ViewState();
-        maxViewState.mMaxScale = maxZoomScale - 0.1f;
-        zoomManager.updateZoomRange(maxViewState, 0, 0);
-        zoomManager.updateDefaultZoomDensity(newDefaultScale);
-        defaultScaleTest(newDefaultScale);
-    }
-
-    public void testUpdateDefaultZoomDensityWithLargeMaxZoom() {
-        // test the case where the maxZoomScale has changed to be > the default
-        float newDefaultScale = 1.50f;
-        float maxZoomScale = ZoomManager.DEFAULT_MAX_ZOOM_SCALE_FACTOR * newDefaultScale;
-        WebViewCore.ViewState maxViewState = new WebViewCore.ViewState();
-        maxViewState.mMaxScale = maxZoomScale + 0.1f;
-        zoomManager.updateZoomRange(maxViewState, 0, 0);
-        zoomManager.updateDefaultZoomDensity(newDefaultScale);
-        defaultScaleTest(newDefaultScale);
-    }
-
-    public void testComputeScaleWithLimits() {
-        final float maxScale = zoomManager.getMaxZoomScale();
-        final float minScale = zoomManager.getMinZoomScale();
-        assertTrue(maxScale > minScale);
-        assertEquals(maxScale, zoomManager.computeScaleWithLimits(maxScale));
-        assertEquals(maxScale, zoomManager.computeScaleWithLimits(maxScale + .01f));
-        assertEquals(minScale, zoomManager.computeScaleWithLimits(minScale));
-        assertEquals(minScale, zoomManager.computeScaleWithLimits(minScale - .01f));
-    }
-
-    private void actualScaleTest(float actualScale) {
-        assertEquals(actualScale, zoomManager.getScale());
-        assertEquals(1 / actualScale, zoomManager.getInvScale());
-    }
-
-    private void defaultScaleTest(float defaultScale) {
-        final float maxDefault = ZoomManager.DEFAULT_MAX_ZOOM_SCALE_FACTOR * defaultScale;
-        final float minDefault = ZoomManager.DEFAULT_MIN_ZOOM_SCALE_FACTOR * defaultScale;
-        assertEquals(defaultScale, zoomManager.getDefaultScale());
-        assertEquals(1 / defaultScale, zoomManager.getInvDefaultScale());
-        assertEquals(maxDefault, zoomManager.getDefaultMaxZoomScale());
-        assertEquals(minDefault, zoomManager.getDefaultMinZoomScale());
-    }
-}
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 1289971..89d102d 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -54,10 +54,6 @@
         <group gid="inet" />
     </permission>
 
-    <permission name="android.permission.CAMERA" >
-        <group gid="camera" />
-    </permission>
-
     <permission name="android.permission.READ_LOGS" >
         <group gid="log" />
     </permission>
@@ -67,9 +63,16 @@
     </permission>
 
     <permission name="android.permission.WRITE_EXTERNAL_STORAGE" >
+        <group gid="sdcard_r" />
         <group gid="sdcard_rw" />
     </permission>
 
+    <permission name="android.permission.ACCESS_ALL_EXTERNAL_STORAGE" >
+        <group gid="sdcard_r" />
+        <group gid="sdcard_rw" />
+        <group gid="sdcard_all" />
+    </permission>
+
     <permission name="android.permission.WRITE_MEDIA_STORAGE" >
         <group gid="media_rw" />
     </permission>
@@ -123,7 +126,6 @@
          interact with the system. -->
 
     <assign-permission name="android.permission.MODIFY_AUDIO_SETTINGS" uid="media" />
-    <assign-permission name="android.permission.ACCESS_DRM" uid="media" />
     <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="media" />
     <assign-permission name="android.permission.WAKE_LOCK" uid="media" />
     <assign-permission name="android.permission.UPDATE_APP_OPS_STATS" uid="media" />
diff --git a/data/fonts/Android.mk b/data/fonts/Android.mk
index 7f8d5f0..2846e61 100644
--- a/data/fonts/Android.mk
+++ b/data/fonts/Android.mk
@@ -53,22 +53,6 @@
 include $(BUILD_PREBUILT)
 
 include $(CLEAR_VARS)
-LOCAL_MODULE := DroidSansTamil-Regular.ttf
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT)/fonts
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := DroidSansTamil-Bold.ttf
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT)/fonts
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
 LOCAL_MODULE := MTLmr3m.ttf
 LOCAL_SRC_FILES := $(LOCAL_MODULE)
 LOCAL_MODULE_CLASS := ETC
@@ -81,8 +65,6 @@
 	DroidSans.ttf \
 	DroidSans-Bold.ttf \
 	DroidSansEthiopic-Regular.ttf \
-	DroidSansTamil-Regular.ttf \
-	DroidSansTamil-Bold.ttf \
 	MTLmr3m.ttf
 endif  # SMALLER_FONT_FOOTPRINT
 
@@ -153,13 +135,10 @@
     RobotoCondensed-BoldItalic.ttf \
     DroidNaskh-Regular.ttf \
     DroidNaskhUI-Regular.ttf \
-    DroidSansDevanagari-Regular.ttf \
     DroidSansHebrew-Regular.ttf \
     DroidSansHebrew-Bold.ttf \
-    DroidSansThai.ttf \
     DroidSansArmenian.ttf \
-    DroidSansGeorgian.ttf \
-    AndroidEmoji.ttf
+    DroidSansGeorgian.ttf
 
 endif # !MINIMAL_FONT
 
diff --git a/data/fonts/AndroidEmoji.ttf b/data/fonts/AndroidEmoji.ttf
deleted file mode 100644
index 92bf047..0000000
--- a/data/fonts/AndroidEmoji.ttf
+++ /dev/null
Binary files differ
diff --git a/data/fonts/DroidSansDevanagari-Regular.ttf b/data/fonts/DroidSansDevanagari-Regular.ttf
deleted file mode 100644
index a25e0e3..0000000
--- a/data/fonts/DroidSansDevanagari-Regular.ttf
+++ /dev/null
Binary files differ
diff --git a/data/fonts/DroidSansTamil-Bold.ttf b/data/fonts/DroidSansTamil-Bold.ttf
deleted file mode 100644
index 8ad0085..0000000
--- a/data/fonts/DroidSansTamil-Bold.ttf
+++ /dev/null
Binary files differ
diff --git a/data/fonts/DroidSansTamil-Regular.ttf b/data/fonts/DroidSansTamil-Regular.ttf
deleted file mode 100644
index 4b8f536..0000000
--- a/data/fonts/DroidSansTamil-Regular.ttf
+++ /dev/null
Binary files differ
diff --git a/data/fonts/DroidSansThai.ttf b/data/fonts/DroidSansThai.ttf
deleted file mode 100644
index 15b00c2..0000000
--- a/data/fonts/DroidSansThai.ttf
+++ /dev/null
Binary files differ
diff --git a/data/fonts/fallback_fonts.xml b/data/fonts/fallback_fonts.xml
index 16d760c..69db6aa 100644
--- a/data/fonts/fallback_fonts.xml
+++ b/data/fonts/fallback_fonts.xml
@@ -52,7 +52,14 @@
     </family>
     <family>
         <fileset>
-            <file>DroidSansThai.ttf</file>
+            <file variant="elegant">NotoSansThai-Regular.ttf</file>
+            <file variant="elegant">NotoSansThai-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file variant="compact">NotoSansThaiUI-Regular.ttf</file>
+            <file variant="compact">NotoSansThaiUI-Bold.ttf</file>
         </fileset>
     </family>
     <family>
@@ -67,13 +74,26 @@
     </family>
     <family>
         <fileset>
-            <file>DroidSansDevanagari-Regular.ttf</file>
+            <file variant="elegant">NotoSansDevanagari-Regular.ttf</file>
+            <file variant="elegant">NotoSansDevanagari-Bold.ttf</file>
         </fileset>
     </family>
     <family>
         <fileset>
-            <file>DroidSansTamil-Regular.ttf</file>
-            <file>DroidSansTamil-Bold.ttf</file>
+            <file variant="compact">NotoSansDevanagariUI-Regular.ttf</file>
+            <file variant="compact">NotoSansDevanagariUI-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file variant="elegant">NotoSansTamil-Regular.ttf</file>
+            <file variant="elegant">NotoSansTamil-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file variant="compact">NotoSansTamilUI-Regular.ttf</file>
+            <file variant="compact">NotoSansTamilUI-Bold.ttf</file>
         </fileset>
     </family>
     <family>
@@ -126,12 +146,47 @@
     </family>
     <family>
         <fileset>
+            <file variant="elegant">NotoSansKhmer-Regular.ttf</file>
+            <file variant="elegant">NotoSansKhmer-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file variant="compact">NotoSansKhmerUI-Regular.ttf</file>
+            <file variant="compact">NotoSansKhmerUI-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file variant="elegant">NotoSansLao-Regular.ttf</file>
+            <file variant="elegant">NotoSansLao-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file variant="compact">NotoSansLaoUI-Regular.ttf</file>
+            <file variant="compact">NotoSansLaoUI-Bold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
             <file>NanumGothic.ttf</file>
         </fileset>
     </family>
     <family>
         <fileset>
-            <file>AndroidEmoji.ttf</file>
+            <file>Padauk-book.ttf</file>
+            <file>Padauk-bookbold.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>NotoSansSymbols-Regular.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>NotoColorEmoji.ttf</file>
         </fileset>
     </family>
     <family>
diff --git a/data/fonts/fonts.mk b/data/fonts/fonts.mk
index 7c2f955..a677c4f 100644
--- a/data/fonts/fonts.mk
+++ b/data/fonts/fonts.mk
@@ -34,10 +34,8 @@
     RobotoCondensed-BoldItalic.ttf \
     DroidNaskh-Regular.ttf \
     DroidNaskhUI-Regular.ttf \
-    DroidSansDevanagari-Regular.ttf \
     DroidSansHebrew-Regular.ttf \
     DroidSansHebrew-Bold.ttf \
-    DroidSansThai.ttf \
     DroidSerif-Regular.ttf \
     DroidSerif-Bold.ttf \
     DroidSerif-Italic.ttf \
@@ -45,7 +43,6 @@
     DroidSansMono.ttf \
     DroidSansArmenian.ttf \
     DroidSansGeorgian.ttf \
-    AndroidEmoji.ttf \
     Clockopia.ttf \
     AndroidClock.ttf \
     AndroidClock_Highlight.ttf \
diff --git a/data/keyboards/Android.mk b/data/keyboards/Android.mk
index a66a884..898efe8 100644
--- a/data/keyboards/Android.mk
+++ b/data/keyboards/Android.mk
@@ -21,17 +21,21 @@
 # Validate all key maps.
 include $(CLEAR_VARS)
 
-validatekeymaps := $(HOST_OUT_EXECUTABLES)/validatekeymaps$(HOST_EXECUTABLE_SUFFIX)
-files := \
-    $(foreach file,$(keylayouts),frameworks/base/data/keyboards/$(file)) \
-    $(foreach file,$(keycharmaps),frameworks/base/data/keyboards/$(file)) \
-    $(foreach file,$(keyconfigs),frameworks/base/data/keyboards/$(file))
-
 LOCAL_MODULE := validate_framework_keymaps
-LOCAL_MODULE_TAGS := optional
-LOCAL_REQUIRED_MODULES := validatekeymaps
+intermediates := $(call intermediates-dir-for,ETC,$(LOCAL_MODULE),,COMMON)
+LOCAL_BUILT_MODULE := $(intermediates)/stamp
 
-validate_framework_keymaps: $(files)
-	$(hide) $(validatekeymaps) $(files)
+validatekeymaps := $(HOST_OUT_EXECUTABLES)/validatekeymaps$(HOST_EXECUTABLE_SUFFIX)
+$(LOCAL_BUILT_MODULE): PRIVATE_VALIDATEKEYMAPS := $(validatekeymaps)
+$(LOCAL_BUILT_MODULE) : $(framework_keylayouts) $(framework_keycharmaps) $(framework_keyconfigs) | $(validatekeymaps)
+	$(hide) $(PRIVATE_VALIDATEKEYMAPS) $^
+	$(hide) mkdir -p $(dir $@) && touch $@
 
-include $(BUILD_PHONY_PACKAGE)
+# Run validatekeymaps uncondionally for platform build.
+droidcore all_modules : $(LOCAL_BUILT_MODULE)
+
+# Reset temp vars.
+validatekeymaps :=
+framework_keylayouts :=
+framework_keycharmaps :=
+framework_keyconfigs :=
diff --git a/data/keyboards/Generic.kcm b/data/keyboards/Generic.kcm
index 01d22ee..695a74f 100644
--- a/data/keyboards/Generic.kcm
+++ b/data/keyboards/Generic.kcm
@@ -477,128 +477,4 @@
     ctrl:                               fallback MENU
 }
 
-### Gamepad buttons ###
-
-key BUTTON_A {
-    base:                               fallback DPAD_CENTER
-}
-
-key BUTTON_B {
-    base:                               fallback BACK
-}
-
-key BUTTON_C {
-    base:                               fallback DPAD_CENTER
-}
-
-key BUTTON_X {
-    base:                               fallback DPAD_CENTER
-}
-
-key BUTTON_Y {
-    base:                               fallback BACK
-}
-
-key BUTTON_Z {
-    base:                               fallback DPAD_CENTER
-}
-
-key BUTTON_L1 {
-    base:                               none
-}
-
-key BUTTON_R1 {
-    base:                               none
-}
-
-key BUTTON_L2 {
-    base:                               none
-}
-
-key BUTTON_R2 {
-    base:                               none
-}
-
-key BUTTON_THUMBL {
-    base:                               fallback DPAD_CENTER
-}
-
-key BUTTON_THUMBR {
-    base:                               fallback DPAD_CENTER
-}
-
-key BUTTON_START {
-    base:                               fallback DPAD_CENTER
-}
-
-key BUTTON_SELECT {
-    base:                               fallback MENU
-}
-
-key BUTTON_MODE {
-    base:                               fallback MENU
-}
-
-key BUTTON_1 {
-    base:                               fallback DPAD_CENTER
-}
-
-key BUTTON_2 {
-    base:                               fallback DPAD_CENTER
-}
-
-key BUTTON_3 {
-    base:                               fallback DPAD_CENTER
-}
-
-key BUTTON_4 {
-    base:                               fallback DPAD_CENTER
-}
-
-key BUTTON_5 {
-    base:                               fallback DPAD_CENTER
-}
-
-key BUTTON_6 {
-    base:                               fallback DPAD_CENTER
-}
-
-key BUTTON_7 {
-    base:                               fallback DPAD_CENTER
-}
-
-key BUTTON_8 {
-    base:                               fallback DPAD_CENTER
-}
-
-key BUTTON_9 {
-    base:                               fallback DPAD_CENTER
-}
-
-key BUTTON_10 {
-    base:                               fallback DPAD_CENTER
-}
-
-key BUTTON_11 {
-    base:                               fallback DPAD_CENTER
-}
-
-key BUTTON_12 {
-    base:                               fallback DPAD_CENTER
-}
-
-key BUTTON_13 {
-    base:                               fallback DPAD_CENTER
-}
-
-key BUTTON_14 {
-    base:                               fallback DPAD_CENTER
-}
-
-key BUTTON_15 {
-    base:                               fallback DPAD_CENTER
-}
-
-key BUTTON_16 {
-    base:                               fallback DPAD_CENTER
-}
+### Gamepad buttons are handled by the view root ###
diff --git a/data/keyboards/common.mk b/data/keyboards/common.mk
index 6fb633b..d75b691 100644
--- a/data/keyboards/common.mk
+++ b/data/keyboards/common.mk
@@ -15,41 +15,8 @@
 # This is the list of framework provided keylayouts and key character maps to include.
 # Used by Android.mk and keyboards.mk.
 
-keylayouts := \
-    Generic.kl \
-    AVRCP.kl \
-    qwerty.kl \
-    Vendor_045e_Product_028e.kl \
-    Vendor_046d_Product_c216.kl \
-    Vendor_046d_Product_c294.kl \
-    Vendor_046d_Product_c299.kl \
-    Vendor_046d_Product_c532.kl \
-    Vendor_054c_Product_0268.kl \
-    Vendor_05ac_Product_0239.kl \
-    Vendor_22b8_Product_093d.kl \
-    Vendor_0079_Product_0011.kl \
-    Vendor_046d_Product_c219.kl \
-    Vendor_046d_Product_c21f.kl \
-    Vendor_0583_Product_2060.kl \
-    Vendor_1038_Product_1412.kl \
-    Vendor_12bd_Product_d015.kl \
-    Vendor_1689_Product_fd00.kl \
-    Vendor_1689_Product_fd01.kl \
-    Vendor_1689_Product_fe00.kl \
-    Vendor_1bad_Product_f016.kl \
-    Vendor_1bad_Product_f023.kl \
-    Vendor_1bad_Product_f027.kl \
-    Vendor_1bad_Product_f036.kl \
-    Vendor_1d79_Product_0009.kl \
-    Vendor_2378_Product_100a.kl
+framework_keylayouts := $(wildcard $(LOCAL_PATH)/*.kl)
 
-keycharmaps := \
-    Generic.kcm \
-    Virtual.kcm \
-    qwerty.kcm \
-    qwerty2.kcm
+framework_keycharmaps := $(wildcard $(LOCAL_PATH)/*.kcm)
 
-keyconfigs := \
-    qwerty.idc \
-    qwerty2.idc
-
+framework_keyconfigs := $(wildcard $(LOCAL_PATH)/*.idc)
diff --git a/data/keyboards/keyboards.mk b/data/keyboards/keyboards.mk
index c964961..68cbd29 100644
--- a/data/keyboards/keyboards.mk
+++ b/data/keyboards/keyboards.mk
@@ -16,11 +16,11 @@
 
 include $(LOCAL_PATH)/common.mk
 
-PRODUCT_COPY_FILES := $(foreach file,$(keylayouts),\
-    frameworks/base/data/keyboards/$(file):system/usr/keylayout/$(file))
+PRODUCT_COPY_FILES := $(foreach file,$(framework_keylayouts),\
+    $(file):system/usr/keylayout/$(notdir $(file)))
 
-PRODUCT_COPY_FILES += $(foreach file,$(keycharmaps),\
-    frameworks/base/data/keyboards/$(file):system/usr/keychars/$(file))
+PRODUCT_COPY_FILES += $(foreach file,$(framework_keycharmaps),\
+    $(file):system/usr/keychars/$(notdir $(file)))
 
-PRODUCT_COPY_FILES += $(foreach file,$(keyconfigs),\
-    frameworks/base/data/keyboards/$(file):system/usr/idc/$(file))
+PRODUCT_COPY_FILES += $(foreach file,$(framework_keyconfigs),\
+    $(file):system/usr/idc/$(notdir $(file)))
diff --git a/data/sounds/AllAudio.mk b/data/sounds/AllAudio.mk
index 8b03bf7..ed9bea5 100644
--- a/data/sounds/AllAudio.mk
+++ b/data/sounds/AllAudio.mk
@@ -221,6 +221,7 @@
     $(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/KeypressInvalid_120_48k.ogg:system/media/audio/ui/KeypressInvalid.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/Undock.ogg:system/media/audio/ui/Undock.ogg \
diff --git a/data/sounds/AudioPackage10.mk b/data/sounds/AudioPackage10.mk
index 90d8eaa..783e1f8 100644
--- a/data/sounds/AudioPackage10.mk
+++ b/data/sounds/AudioPackage10.mk
@@ -20,6 +20,7 @@
 	$(LOCAL_PATH)/effects/ogg/KeypressStandard_120_48k.ogg:system/media/audio/ui/KeypressStandard.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressSpacebar_120_48k.ogg:system/media/audio/ui/KeypressSpacebar.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/VideoRecord_48k.ogg:system/media/audio/ui/VideoRecord.ogg \
 	$(LOCAL_PATH)/effects/ogg/camera_click_48k.ogg:system/media/audio/ui/camera_click.ogg \
diff --git a/data/sounds/AudioPackage11.mk b/data/sounds/AudioPackage11.mk
index 2897b04..b30be56 100644
--- a/data/sounds/AudioPackage11.mk
+++ b/data/sounds/AudioPackage11.mk
@@ -20,6 +20,7 @@
 	$(LOCAL_PATH)/effects/ogg/KeypressStandard_120_48k.ogg:system/media/audio/ui/KeypressStandard.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressSpacebar_120_48k.ogg:system/media/audio/ui/KeypressSpacebar.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/VideoRecord_48k.ogg:system/media/audio/ui/VideoRecord.ogg \
 	$(LOCAL_PATH)/effects/ogg/camera_click_48k.ogg:system/media/audio/ui/camera_click.ogg \
diff --git a/data/sounds/AudioPackage2.mk b/data/sounds/AudioPackage2.mk
index 1a36cba..ea07acd 100644
--- a/data/sounds/AudioPackage2.mk
+++ b/data/sounds/AudioPackage2.mk
@@ -31,6 +31,7 @@
 	$(LOCAL_PATH)/effects/KeypressStandard.ogg:system/media/audio/ui/KeypressStandard.ogg \
 	$(LOCAL_PATH)/effects/KeypressSpacebar.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
 	$(LOCAL_PATH)/effects/KeypressDelete.ogg:system/media/audio/ui/KeypressDelete.ogg \
+	$(LOCAL_PATH)/effects/ogg/KeypressInvalid.ogg:system/media/audio/ui/KeypressInvalid.ogg \
 	$(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
 	$(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
diff --git a/data/sounds/AudioPackage3.mk b/data/sounds/AudioPackage3.mk
index 146c2e4..a8a3b76 100644
--- a/data/sounds/AudioPackage3.mk
+++ b/data/sounds/AudioPackage3.mk
@@ -31,6 +31,7 @@
 	$(LOCAL_PATH)/effects/KeypressStandard.ogg:system/media/audio/ui/KeypressStandard.ogg \
 	$(LOCAL_PATH)/effects/KeypressSpacebar.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
 	$(LOCAL_PATH)/effects/KeypressDelete.ogg:system/media/audio/ui/KeypressDelete.ogg \
+	$(LOCAL_PATH)/effects/KeypressInvalid.ogg:system/media/audio/ui/KeypressInvalid.ogg \
 	$(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
 	$(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
diff --git a/data/sounds/AudioPackage4.mk b/data/sounds/AudioPackage4.mk
index 712d7aa..bde3ba0 100644
--- a/data/sounds/AudioPackage4.mk
+++ b/data/sounds/AudioPackage4.mk
@@ -36,6 +36,7 @@
 	$(LOCAL_PATH)/effects/KeypressStandard.ogg:system/media/audio/ui/KeypressStandard.ogg \
 	$(LOCAL_PATH)/effects/KeypressSpacebar.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
 	$(LOCAL_PATH)/effects/KeypressDelete.ogg:system/media/audio/ui/KeypressDelete.ogg \
+	$(LOCAL_PATH)/effects/KeypressInvalid.ogg:system/media/audio/ui/KeypressInvalid.ogg \
 	$(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
 	$(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
diff --git a/data/sounds/AudioPackage5.mk b/data/sounds/AudioPackage5.mk
index 5961f06..077335b 100644
--- a/data/sounds/AudioPackage5.mk
+++ b/data/sounds/AudioPackage5.mk
@@ -17,6 +17,7 @@
 	$(LOCAL_PATH)/effects/KeypressStandard.ogg:system/media/audio/ui/KeypressStandard.ogg \
 	$(LOCAL_PATH)/effects/KeypressSpacebar.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
 	$(LOCAL_PATH)/effects/KeypressDelete.ogg:system/media/audio/ui/KeypressDelete.ogg \
+	$(LOCAL_PATH)/effects/KeypressInvalid.ogg:system/media/audio/ui/KeypressInvalid.ogg \
 	$(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
 	$(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
diff --git a/data/sounds/AudioPackage6.mk b/data/sounds/AudioPackage6.mk
index d113a29..2cdd702 100644
--- a/data/sounds/AudioPackage6.mk
+++ b/data/sounds/AudioPackage6.mk
@@ -16,6 +16,7 @@
 	$(LOCAL_PATH)/effects/ogg/KeypressStandard.ogg:system/media/audio/ui/KeypressStandard.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressSpacebar.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressDelete.ogg:system/media/audio/ui/KeypressDelete.ogg \
+	$(LOCAL_PATH)/effects/ogg/KeypressInvalid.ogg:system/media/audio/ui/KeypressInvalid.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
 	$(LOCAL_PATH)/effects/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
diff --git a/data/sounds/AudioPackage7.mk b/data/sounds/AudioPackage7.mk
index 6ae624e..e909235 100644
--- a/data/sounds/AudioPackage7.mk
+++ b/data/sounds/AudioPackage7.mk
@@ -18,6 +18,7 @@
 	$(LOCAL_PATH)/effects/ogg/KeypressStandard_120.ogg:system/media/audio/ui/KeypressStandard.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressSpacebar_120.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressDelete_120.ogg:system/media/audio/ui/KeypressDelete.ogg \
+	$(LOCAL_PATH)/effects/ogg/KeypressInvalid_120.ogg:system/media/audio/ui/KeypressInvalid.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressReturn_120.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
 	$(LOCAL_PATH)/effects/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
diff --git a/data/sounds/AudioPackage7alt.mk b/data/sounds/AudioPackage7alt.mk
index 11409f2..1132fa9 100644
--- a/data/sounds/AudioPackage7alt.mk
+++ b/data/sounds/AudioPackage7alt.mk
@@ -18,6 +18,7 @@
 	$(LOCAL_PATH)/effects/ogg/KeypressStandard_120.ogg:system/media/audio/ui/KeypressStandard.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressSpacebar_120.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressDelete_120.ogg:system/media/audio/ui/KeypressDelete.ogg \
+	$(LOCAL_PATH)/effects/ogg/KeypressInvalid_120.ogg:system/media/audio/ui/KeypressInvalid.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressReturn_120.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
 	$(LOCAL_PATH)/effects/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
diff --git a/data/sounds/AudioPackage8.mk b/data/sounds/AudioPackage8.mk
index 93c43da..49b6154 100644
--- a/data/sounds/AudioPackage8.mk
+++ b/data/sounds/AudioPackage8.mk
@@ -20,6 +20,7 @@
 	$(LOCAL_PATH)/effects/ogg/KeypressStandard_120.ogg:system/media/audio/ui/KeypressStandard.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressSpacebar_120.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressDelete_120.ogg:system/media/audio/ui/KeypressDelete.ogg \
+	$(LOCAL_PATH)/effects/ogg/KeypressInvalid_120.ogg:system/media/audio/ui/KeypressInvalid.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressReturn_120.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
 	$(LOCAL_PATH)/effects/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
diff --git a/data/sounds/AudioPackage9.mk b/data/sounds/AudioPackage9.mk
index 73e4fd3..87b7764 100644
--- a/data/sounds/AudioPackage9.mk
+++ b/data/sounds/AudioPackage9.mk
@@ -20,6 +20,7 @@
 	$(LOCAL_PATH)/effects/ogg/KeypressStandard_120.ogg:system/media/audio/ui/KeypressStandard.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressSpacebar_120.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressDelete_120.ogg:system/media/audio/ui/KeypressDelete.ogg \
+	$(LOCAL_PATH)/effects/ogg/KeypressInvalid_120.ogg:system/media/audio/ui/KeypressInvalid.ogg \
 	$(LOCAL_PATH)/effects/ogg/KeypressReturn_120.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
 	$(LOCAL_PATH)/effects/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
diff --git a/data/sounds/effects/KeypressInvalid.ogg b/data/sounds/effects/KeypressInvalid.ogg
new file mode 100644
index 0000000..24935ad
--- /dev/null
+++ b/data/sounds/effects/KeypressInvalid.ogg
Binary files differ
diff --git a/data/sounds/effects/KeypressInvalid.wav b/data/sounds/effects/KeypressInvalid.wav
new file mode 100644
index 0000000..c4180e35
--- /dev/null
+++ b/data/sounds/effects/KeypressInvalid.wav
Binary files differ
diff --git a/data/sounds/effects/ogg/KeypressInvalid.ogg b/data/sounds/effects/ogg/KeypressInvalid.ogg
new file mode 100644
index 0000000..24935ad
--- /dev/null
+++ b/data/sounds/effects/ogg/KeypressInvalid.ogg
Binary files differ
diff --git a/data/sounds/effects/ogg/KeypressInvalid_120.ogg b/data/sounds/effects/ogg/KeypressInvalid_120.ogg
new file mode 100644
index 0000000..24935ad
--- /dev/null
+++ b/data/sounds/effects/ogg/KeypressInvalid_120.ogg
Binary files differ
diff --git a/data/sounds/effects/ogg/KeypressInvalid_120_48k.ogg b/data/sounds/effects/ogg/KeypressInvalid_120_48k.ogg
new file mode 100644
index 0000000..24935ad
--- /dev/null
+++ b/data/sounds/effects/ogg/KeypressInvalid_120_48k.ogg
Binary files differ
diff --git a/data/videos/VideoPackage1.mk b/data/videos/VideoPackage1.mk
index 0089657..ee3b5ed 100644
--- a/data/videos/VideoPackage1.mk
+++ b/data/videos/VideoPackage1.mk
@@ -19,8 +19,8 @@
 LOCAL_PATH  := frameworks/base/data/videos
 TARGET_PATH := system/media/video
 
-PRODUCT_COPY_FILES += \
-        $(LOCAL_PATH)/AndroidInSpace.240p.mp4:$(TARGET_PATH)/AndroidInSpace.240p.mp4 \
-        $(LOCAL_PATH)/AndroidInSpace.480p.lq.mp4:$(TARGET_PATH)/AndroidInSpace.480p.mp4 \
-        $(LOCAL_PATH)/Sunset.240p.mp4:$(TARGET_PATH)/Sunset.240p.mp4 \
-        $(LOCAL_PATH)/Sunset.480p.lq.mp4:$(TARGET_PATH)/Sunset.480p.mp4
+#PRODUCT_COPY_FILES += \
+#        $(LOCAL_PATH)/AndroidInSpace.240p.mp4:$(TARGET_PATH)/AndroidInSpace.240p.mp4 \
+#        $(LOCAL_PATH)/AndroidInSpace.480p.lq.mp4:$(TARGET_PATH)/AndroidInSpace.480p.mp4 \
+#        $(LOCAL_PATH)/Sunset.240p.mp4:$(TARGET_PATH)/Sunset.240p.mp4 \
+#        $(LOCAL_PATH)/Sunset.480p.lq.mp4:$(TARGET_PATH)/Sunset.480p.mp4
diff --git a/data/videos/VideoPackage2.mk b/data/videos/VideoPackage2.mk
index b53fd9f..f799bea 100644
--- a/data/videos/VideoPackage2.mk
+++ b/data/videos/VideoPackage2.mk
@@ -19,8 +19,8 @@
 LOCAL_PATH  := frameworks/base/data/videos
 TARGET_PATH := system/media/video
 
-PRODUCT_COPY_FILES += \
-        $(LOCAL_PATH)/AndroidInSpace.240p.mp4:$(TARGET_PATH)/AndroidInSpace.240p.mp4 \
-        $(LOCAL_PATH)/AndroidInSpace.480p.mq.mp4:$(TARGET_PATH)/AndroidInSpace.480p.mp4 \
-        $(LOCAL_PATH)/Sunset.240p.mp4:$(TARGET_PATH)/Sunset.240p.mp4 \
-        $(LOCAL_PATH)/Sunset.480p.mq.mp4:$(TARGET_PATH)/Sunset.480p.mp4
+#PRODUCT_COPY_FILES += \
+#        $(LOCAL_PATH)/AndroidInSpace.240p.mp4:$(TARGET_PATH)/AndroidInSpace.240p.mp4 \
+#        $(LOCAL_PATH)/AndroidInSpace.480p.mq.mp4:$(TARGET_PATH)/AndroidInSpace.480p.mp4 \
+#        $(LOCAL_PATH)/Sunset.240p.mp4:$(TARGET_PATH)/Sunset.240p.mp4 \
+#        $(LOCAL_PATH)/Sunset.480p.mq.mp4:$(TARGET_PATH)/Sunset.480p.mp4
diff --git a/graphics/java/android/graphics/Atlas.java b/graphics/java/android/graphics/Atlas.java
new file mode 100644
index 0000000..39a5a53
--- /dev/null
+++ b/graphics/java/android/graphics/Atlas.java
@@ -0,0 +1,441 @@
+/*
+ * 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;
+
+/**
+ * @hide
+ */
+public class Atlas {
+    /**
+     * This flag indicates whether the packing algorithm will attempt
+     * to rotate entries to make them fit better in the atlas.
+     */
+    public static final int FLAG_ALLOW_ROTATIONS = 0x1;
+    /**
+     * This flag indicates whether the packing algorithm should leave
+     * an empty 1 pixel wide border around each bitmap. This border can
+     * be useful if the content of the atlas will be used in OpenGL using
+     * bilinear filtering.
+     */
+    public static final int FLAG_ADD_PADDING = 0x2;
+    /**
+     * Default flags: allow rotations and add padding.
+     */
+    public static final int FLAG_DEFAULTS = FLAG_ADD_PADDING;
+
+    /**
+     * Each type defines a different packing algorithm that can
+     * be used by an {@link Atlas}. The best algorithm to use
+     * will depend on the source dataset and the dimensions of
+     * the atlas.
+     */
+    public enum Type {
+        SliceMinArea,
+        SliceMaxArea,
+        SliceShortAxis,
+        SliceLongAxis
+    }
+
+    /**
+     * Represents a bitmap packed in the atlas. Each entry has a location in
+     * pixels in the atlas and a rotation flag. If the entry was rotated, the
+     * bitmap must be rotated by 90 degrees (in either direction as long as
+     * the origin remains the same) before being rendered into the atlas.
+     */
+    public static class Entry {
+        /**
+         * Location, in pixels, of the bitmap on the X axis in the atlas.
+         */
+        public int x;
+        /**
+         * Location, in pixels, of the bitmap on the Y axis in the atlas.
+         */
+        public int y;
+
+        /**
+         * If true, the bitmap must be rotated 90 degrees in the atlas.
+         */
+        public boolean rotated;
+    }
+
+    private final Policy mPolicy;
+
+    /**
+     * Creates a new atlas with the specified algorithm and dimensions
+     * in pixels. Calling this constructor is equivalent to calling
+     * {@link #Atlas(Atlas.Type, int, int, int)} with {@link #FLAG_DEFAULTS}.
+     *
+     * @param type The algorithm to use to pack rectangles in the atlas
+     * @param width The width of the atlas in pixels
+     * @param height The height of the atlas in pixels
+     *
+     * @see #Atlas(Atlas.Type, int, int, int)
+     */
+    public Atlas(Type type, int width, int height) {
+        this(type, width, height, FLAG_DEFAULTS);
+    }
+
+    /**
+     * Creates a new atlas with the specified algorithm and dimensions
+     * in pixels. A set of flags can also be specified to control the
+     * behavior of the atlas.
+     *
+     * @param type The algorithm to use to pack rectangles in the atlas
+     * @param width The width of the atlas in pixels
+     * @param height The height of the atlas in pixels
+     * @param flags Optional flags to control the behavior of the atlas:
+     *              {@link #FLAG_ADD_PADDING}, {@link #FLAG_ALLOW_ROTATIONS}
+     *
+     * @see #Atlas(Atlas.Type, int, int)
+     */
+    public Atlas(Type type, int width, int height, int flags) {
+        mPolicy = findPolicy(type, width, height, flags);
+    }
+
+    /**
+     * Packs a rectangle of the specified dimensions in this atlas.
+     *
+     * @param width The width of the rectangle to pack in the atlas
+     * @param height The height of the rectangle to pack in the atlas
+     *
+     * @return An {@link Entry} instance if the rectangle was packed in
+     *         the atlas, or null if the rectangle could not fit
+     *
+     * @see #pack(int, int, Atlas.Entry)
+     */
+    public Entry pack(int width, int height) {
+        return pack(width, height, null);
+    }
+
+    /**
+     * Packs a rectangle of the specified dimensions in this atlas.
+     *
+     * @param width The width of the rectangle to pack in the atlas
+     * @param height The height of the rectangle to pack in the atlas
+     * @param entry Out parameter that will be filled in with the location
+     *              and attributes of the packed rectangle, can be null
+     *
+     * @return An {@link Entry} instance if the rectangle was packed in
+     *         the atlas, or null if the rectangle could not fit
+     *
+     * @see #pack(int, int)
+     */
+    public Entry pack(int width, int height, Entry entry) {
+        if (entry == null) entry = new Entry();
+        return mPolicy.pack(width, height, entry);
+    }
+
+    private static Policy findPolicy(Type type, int width, int height, int flags) {
+        switch (type) {
+            case SliceMinArea:
+                return new SlicePolicy(width, height, flags,
+                        new SlicePolicy.MinAreaSplitDecision());
+            case SliceMaxArea:
+                return new SlicePolicy(width, height, flags,
+                        new SlicePolicy.MaxAreaSplitDecision());
+            case SliceShortAxis:
+                return new SlicePolicy(width, height, flags,
+                        new SlicePolicy.ShorterFreeAxisSplitDecision());
+            case SliceLongAxis:
+                return new SlicePolicy(width, height, flags,
+                        new SlicePolicy.LongerFreeAxisSplitDecision());
+        }
+        return null;
+    }
+
+    /**
+     * A policy defines how the atlas performs the packing operation.
+     */
+    private static abstract class Policy {
+        abstract Entry pack(int width, int height, Entry entry);
+    }
+
+    /**
+     * The Slice algorightm divides the remaining empty space either
+     * horizontally or vertically after a bitmap is placed in the atlas.
+     *
+     * NOTE: the algorithm is explained below using a tree but is
+     * implemented using a linked list instead for performance reasons.
+     *
+     * The algorithm starts with a single empty cell covering the entire
+     * atlas:
+     *
+     *  -----------------------
+     * |                       |
+     * |                       |
+     * |                       |
+     * |      Empty space      |
+     * |          (C0)         |
+     * |                       |
+     * |                       |
+     * |                       |
+     *  -----------------------
+     *
+     * The tree of cells looks like this:
+     *
+     * N0(free)
+     *
+     * The algorithm then places a bitmap B1, if possible:
+     *
+     *  -----------------------
+     * |        |              |
+     * |   B1   |              |
+     * |        |              |
+     * |--------               |
+     * |                       |
+     * |                       |
+     * |                       |
+     * |                       |
+     *  -----------------------
+     *
+     *  After placing a bitmap in an empty cell, the algorithm splits
+     *  the remaining space in two new empty cells. The split can occur
+     *  vertically or horizontally (this is controlled by the "split
+     *  decision" parameter of the algorithm.)
+     *
+     *  Here is for the instance the result of a vertical split:
+     *
+     *  -----------------------
+     * |        |              |
+     * |   B1   |              |
+     * |        |              |
+     * |--------|      C2      |
+     * |        |              |
+     * |        |              |
+     * |   C1   |              |
+     * |        |              |
+     *  -----------------------
+     *
+     * The cells tree now looks like this:
+     *
+     *       C0(occupied)
+     *           / \
+     *          /   \
+     *         /     \
+     *        /       \
+     *    C1(free)  C2(free)
+     *
+     * For each bitmap to place in the atlas, the Slice algorithm
+     * will visit the free cells until it finds one where a bitmap can
+     * fit. It will then split the now occupied cell and proceed onto
+     * the next bitmap.
+     */
+    private static class SlicePolicy extends Policy {
+        private final Cell mRoot = new Cell();
+
+        private final SplitDecision mSplitDecision;
+
+        private final boolean mAllowRotation;
+        private final int mPadding;
+
+        /**
+         * A cell represents a sub-rectangle of the atlas. A cell is
+         * a node in a linked list representing the available free
+         * space in the atlas.
+         */
+        private static class Cell {
+            int x;
+            int y;
+
+            int width;
+            int height;
+
+            Cell next;
+
+            @Override
+            public String toString() {
+                return String.format("cell[x=%d y=%d width=%d height=%d", x, y, width, height);
+            }
+        }
+
+        SlicePolicy(int width, int height, int flags, SplitDecision splitDecision) {
+            mAllowRotation = (flags & FLAG_ALLOW_ROTATIONS) != 0;
+            mPadding = (flags & FLAG_ADD_PADDING) != 0 ? 1 : 0;
+
+            // The entire atlas is empty at first, minus padding
+            Cell first = new Cell();
+            first.x = first.y = mPadding;
+            first.width = width - 2 * mPadding;
+            first.height = height - 2 * mPadding;
+
+            mRoot.next = first;
+            mSplitDecision = splitDecision;
+        }
+
+        @Override
+        Entry pack(int width, int height, Entry entry) {
+            Cell cell = mRoot.next;
+            Cell prev = mRoot;
+
+            while (cell != null) {
+                if (insert(cell, prev, width, height, entry)) {
+                    return entry;
+                }
+
+                prev = cell;
+                cell = cell.next;
+            }
+
+            return null;
+        }
+
+        /**
+         * Defines how the remaining empty space should be split up:
+         * vertically or horizontally.
+         */
+        private static interface SplitDecision {
+            /**
+             * Returns true if the remaining space defined by
+             * <code>freeWidth</code> and <code>freeHeight</code>
+             * should be split horizontally.
+             *
+             * @param freeWidth The rectWidth of the free space after packing a rectangle
+             * @param freeHeight The rectHeight of the free space after packing a rectangle
+             * @param rectWidth The rectWidth of the rectangle that was packed in a cell
+             * @param rectHeight The rectHeight of the rectangle that was packed in a cell
+             */
+            boolean splitHorizontal(int freeWidth, int freeHeight,
+                    int rectWidth, int rectHeight);
+        }
+
+        // Splits the free area horizontally to minimize the horizontal section area
+        private static class MinAreaSplitDecision implements SplitDecision {
+            @Override
+            public boolean splitHorizontal(int freeWidth, int freeHeight,
+                    int rectWidth, int rectHeight) {
+                return rectWidth * freeHeight > freeWidth * rectHeight;
+            }
+        }
+
+        // Splits the free area horizontally to maximize the horizontal section area
+        private static class MaxAreaSplitDecision implements SplitDecision {
+            @Override
+            public boolean splitHorizontal(int freeWidth, int freeHeight,
+                    int rectWidth, int rectHeight) {
+                return rectWidth * freeHeight <= freeWidth * rectHeight;
+            }
+        }
+
+        // Splits the free area horizontally if the horizontal axis is shorter
+        private static class ShorterFreeAxisSplitDecision implements SplitDecision {
+            @Override
+            public boolean splitHorizontal(int freeWidth, int freeHeight,
+                    int rectWidth, int rectHeight) {
+                return freeWidth <= freeHeight;
+            }
+        }
+
+        // Splits the free area horizontally if the vertical axis is shorter
+        private static class LongerFreeAxisSplitDecision implements SplitDecision {
+            @Override
+            public boolean splitHorizontal(int freeWidth, int freeHeight,
+                    int rectWidth, int rectHeight) {
+                return freeWidth > freeHeight;
+            }
+        }
+
+        /**
+         * Attempts to pack a rectangle of specified dimensions in the available
+         * empty space.
+         *
+         * @param cell The cell representing free space in which to pack the rectangle
+         * @param prev The previous cell in the free space linked list
+         * @param width The width of the rectangle to pack
+         * @param height The height of the rectangle to pack
+         * @param entry Stores the location of the packged rectangle, if it fits
+         *
+         * @return True if the rectangle was packed in the atlas, false otherwise
+         */
+        @SuppressWarnings("SuspiciousNameCombination")
+        private boolean insert(Cell cell, Cell prev, int width, int height, Entry entry) {
+            boolean rotated = false;
+
+            // If the rectangle doesn't fit we'll try to rotate it
+            // if possible before giving up
+            if (cell.width < width || cell.height < height) {
+                if (mAllowRotation) {
+                    if (cell.width < height || cell.height < width) {
+                        return false;
+                    }
+
+                    // Rotate the rectangle
+                    int temp = width;
+                    width = height;
+                    height = temp;
+                    rotated = true;
+                } else {
+                    return false;
+                }
+            }
+
+            // Remaining free space after packing the rectangle
+            int deltaWidth = cell.width - width;
+            int deltaHeight = cell.height - height;
+
+            // Split the remaining free space into two new cells
+            Cell first = new Cell();
+            Cell second = new Cell();
+
+            first.x = cell.x + width + mPadding;
+            first.y = cell.y;
+            first.width = deltaWidth - mPadding;
+
+            second.x = cell.x;
+            second.y = cell.y + height + mPadding;
+            second.height = deltaHeight - mPadding;
+
+            if (mSplitDecision.splitHorizontal(deltaWidth, deltaHeight,
+                    width, height)) {
+                first.height = height;
+                second.width = cell.width;
+            } else {
+                first.height = cell.height;
+                second.width = width;
+
+                // The order of the cells matters for efficient packing
+                // We want to give priority to the cell chosen by the
+                // split decision heuristic
+                Cell temp = first;
+                first = second;
+                second = temp;
+            }
+
+            // Remove degenerate cases to keep the free list as small as possible
+            if (first.width > 0 && first.height > 0) {
+                prev.next = first;
+                prev = first;
+            }
+
+            if (second.width > 0 && second.height > 0) {
+                prev.next = second;
+                second.next = cell.next;
+            } else {
+                prev.next = cell.next;
+            }
+
+            // The cell is now completely removed from the free list
+            cell.next = null;
+
+            // Return the location and rotation of the packed rectangle
+            entry.x = cell.x;
+            entry.y = cell.y;
+            entry.rotated = rotated;
+
+            return true;
+        }
+    }
+}
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 89abdef..4c7395c 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -46,20 +46,31 @@
     /**
      * Backing buffer for the Bitmap.
      * Made public for quick access from drawing methods -- do NOT modify
-     * from outside this class.
+     * from outside this class
      *
      * @hide
      */
+    @SuppressWarnings("UnusedDeclaration") // native code only
     public byte[] mBuffer;
 
     @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) // Keep to finalize native resources
     private final BitmapFinalizer mFinalizer;
 
     private final boolean mIsMutable;
+
+    /**
+     * Represents whether the Bitmap's content is expected to be pre-multiplied.
+     * Note that isPremultiplied() does not directly return this value, because
+     * isPremultiplied() may never return true for a 565 Bitmap.
+     *
+     * setPremultiplied() does directly set the value so that setConfig() and
+     * setPremultiplied() aren't order dependent, despite being setters.
+     */
+    private boolean mIsPremultiplied;
     private byte[] mNinePatchChunk;   // may be null
     private int[] mLayoutBounds;   // may be null
-    private int mWidth = -1;
-    private int mHeight = -1;
+    private int mWidth;
+    private int mHeight;
     private boolean mRecycled;
 
     // Package-scoped for fast access.
@@ -88,38 +99,26 @@
     }
 
     /**
-     * @noinspection UnusedDeclaration
+     * Private constructor that must received an already allocated native bitmap
+     * int (pointer).
      */
-    /*  Private constructor that must received an already allocated native
-        bitmap int (pointer).
-
-        This can be called from JNI code.
-    */
-    Bitmap(int nativeBitmap, byte[] buffer, boolean isMutable, byte[] ninePatchChunk,
-            int density) {
-        this(nativeBitmap, buffer, isMutable, ninePatchChunk, null, density);
-    }
-
-    /**
-     * @noinspection UnusedDeclaration
-     */
-    /*  Private constructor that must received an already allocated native
-        bitmap int (pointer).
-
-        This can be called from JNI code.
-    */
-    Bitmap(int nativeBitmap, byte[] buffer, boolean isMutable, byte[] ninePatchChunk,
-            int[] layoutBounds, int density) {
+    @SuppressWarnings({"UnusedDeclaration"}) // called from JNI
+    Bitmap(int nativeBitmap, byte[] buffer, int width, int height, int density,
+            boolean isMutable, boolean isPremultiplied,
+            byte[] ninePatchChunk, int[] layoutBounds) {
         if (nativeBitmap == 0) {
             throw new RuntimeException("internal error: native bitmap is 0");
         }
 
+        mWidth = width;
+        mHeight = height;
+        mIsMutable = isMutable;
+        mIsPremultiplied = isPremultiplied;
         mBuffer = buffer;
         // we delete this in our finalizer
         mNativeBitmap = nativeBitmap;
         mFinalizer = new BitmapFinalizer(nativeBitmap);
 
-        mIsMutable = isMutable;
         mNinePatchChunk = ninePatchChunk;
         mLayoutBounds = layoutBounds;
         if (density >= 0) {
@@ -128,6 +127,17 @@
     }
 
     /**
+     * Native bitmap has been reconfigured, so set premult and cached
+     * width/height values
+     */
+    @SuppressWarnings({"UnusedDeclaration"}) // called from JNI
+    void reinit(int width, int height, boolean isPremultiplied) {
+        mWidth = width;
+        mHeight = height;
+        mIsPremultiplied = isPremultiplied;
+    }
+
+    /**
      * <p>Returns the density for this bitmap.</p>
      *
      * <p>The default density is the same density as the current display,
@@ -167,7 +177,98 @@
     public void setDensity(int density) {
         mDensity = density;
     }
-    
+
+    /**
+     * <p>Modifies the bitmap to have a specified width, height, and {@link
+     * Config}, without affecting the underlying allocation backing the bitmap.
+     * Bitmap pixel data is not re-initialized for the new configuration.</p>
+     *
+     * <p>This method can be used to avoid allocating a new bitmap, instead
+     * reusing an existing bitmap's allocation for a new configuration of equal
+     * or lesser size. If the Bitmap's allocation isn't large enough to support
+     * the new configuration, an IllegalArgumentException will be thrown and the
+     * bitmap will not be modified.</p>
+     *
+     * <p>The result of {@link #getByteCount()} will reflect the new configuration,
+     * while {@link #getAllocationByteCount()} will reflect that of the initial
+     * configuration.</p>
+     *
+     * <p>WARNING: This method should NOT be called on a bitmap currently used
+     * by the view system. It does not make guarantees about how the underlying
+     * pixel buffer is remapped to the new config, just that the allocation is
+     * reused. Additionally, the view system does not account for bitmap
+     * properties being modifying during use, e.g. while attached to
+     * drawables.</p>
+     *
+     * @see #setWidth(int)
+     * @see #setHeight(int)
+     * @see #setConfig(Config)
+     */
+    public void reconfigure(int width, int height, Config config) {
+        checkRecycled("Can't call reconfigure() on a recycled bitmap");
+        if (width <= 0 || height <= 0) {
+            throw new IllegalArgumentException("width and height must be > 0");
+        }
+        if (!isMutable()) {
+            throw new IllegalStateException("only mutable bitmaps may be reconfigured");
+        }
+        if (mBuffer == null) {
+            throw new IllegalStateException("native-backed bitmaps may not be reconfigured");
+        }
+
+        nativeReconfigure(mNativeBitmap, width, height, config.nativeInt, mBuffer.length);
+        mWidth = width;
+        mHeight = height;
+    }
+
+    /**
+     * <p>Convenience method for calling {@link #reconfigure(int, int, Config)}
+     * with the current height and config.</p>
+     *
+     * <p>WARNING: this method should not be used on bitmaps currently used by
+     * the view system, see {@link #reconfigure(int, int, Config)} for more
+     * details.</p>
+     *
+     * @see #reconfigure(int, int, Config)
+     * @see #setHeight(int)
+     * @see #setConfig(Config)
+     */
+    public void setWidth(int width) {
+        reconfigure(width, getHeight(), getConfig());
+    }
+
+    /**
+     * <p>Convenience method for calling {@link #reconfigure(int, int, Config)}
+     * with the current width and config.</p>
+     *
+     * <p>WARNING: this method should not be used on bitmaps currently used by
+     * the view system, see {@link #reconfigure(int, int, Config)} for more
+     * details.</p>
+     *
+     * @see #reconfigure(int, int, Config)
+     * @see #setWidth(int)
+     * @see #setConfig(Config)
+     */
+    public void setHeight(int height) {
+        reconfigure(getWidth(), height, getConfig());
+    }
+
+    /**
+     * <p>Convenience method for calling {@link #reconfigure(int, int, Config)}
+     * with the current height and width.</p>
+     *
+     * <p>WARNING: this method should not be used on bitmaps currently used by
+     * the view system, see {@link #reconfigure(int, int, Config)} for more
+     * details.</p>
+     *
+     * @see #reconfigure(int, int, Config)
+     * @see #setWidth(int)
+     * @see #setHeight(int)
+     */
+    public void setConfig(Config config) {
+        reconfigure(getWidth(), getHeight(), config);
+    }
+
     /**
      * Sets the nine patch chunk.
      *
@@ -318,6 +419,10 @@
          * 
          * It is recommended to use {@link #ARGB_8888} instead of this
          * configuration.
+         *
+         * Note: as of {@link android.os.Build.VERSION_CODES#KITKAT},
+         * any bitmap created with this configuration will be created
+         * using {@link #ARGB_8888} instead.
          * 
          * @deprecated Because of the poor quality of this configuration,
          *             it is advised to use {@link #ARGB_8888} instead.
@@ -449,6 +554,7 @@
         checkRecycled("Can't copy a recycled bitmap");
         Bitmap b = nativeCopy(mNativeBitmap, config.nativeInt, isMutable);
         if (b != null) {
+            b.mIsPremultiplied = mIsPremultiplied;
             b.mDensity = mDensity;
         }
         return b;
@@ -457,7 +563,7 @@
     /**
      * Creates a new bitmap, scaled from an existing bitmap, when possible. If the
      * specified width and height are the same as the current width and height of 
-     * the source btimap, the source bitmap is returned and now new bitmap is
+     * the source bitmap, the source bitmap is returned and no new bitmap is
      * created.
      *
      * @param src       The source bitmap.
@@ -465,6 +571,7 @@
      * @param dstHeight The new bitmap's desired height.
      * @param filter    true if the source should be filtered.
      * @return The new scaled bitmap or the source bitmap if no scaling is required.
+     * @throws IllegalArgumentException if width is <= 0, or height is <= 0
      */
     public static Bitmap createScaledBitmap(Bitmap src, int dstWidth, int dstHeight,
             boolean filter) {
@@ -517,6 +624,9 @@
      * @param width    The number of pixels in each row
      * @param height   The number of rows
      * @return A copy of a subset of the source bitmap or the source bitmap itself.
+     * @throws IllegalArgumentException if the x, y, width, height values are
+     *         outside of the dimensions of the source bitmap, or width is <= 0,
+     *         or height is <= 0
      */
     public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height) {
         return createBitmap(source, x, y, width, height, null, false);
@@ -543,7 +653,8 @@
      *                   translation.
      * @return A bitmap that represents the specified subset of source
      * @throws IllegalArgumentException if the x, y, width, height values are
-     *         outside of the dimensions of the source bitmap.
+     *         outside of the dimensions of the source bitmap, or width is <= 0,
+     *         or height is <= 0
      */
     public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height,
             Matrix m, boolean filter) {
@@ -620,6 +731,7 @@
         // The new bitmap was created from a known bitmap source so assume that
         // they use the same density
         bitmap.mDensity = source.mDensity;
+        bitmap.mIsPremultiplied = source.mIsPremultiplied;
         
         canvas.setBitmap(bitmap);
         canvas.drawBitmap(source, srcR, dstR, paint);
@@ -701,12 +813,10 @@
         if (config == Config.ARGB_8888 && !hasAlpha) {
             nativeErase(bm.mNativeBitmap, 0xff000000);
             nativeSetHasAlpha(bm.mNativeBitmap, hasAlpha);
-        } else {
-            // No need to initialize it to zeroes; it is backed by a VM byte array
-            // which is by definition preinitialized to all zeroes.
-            //
-            //nativeErase(bm.mNativeBitmap, 0);
         }
+        // No need to initialize the bitmap to zeroes with other configs;
+        // it is backed by a VM byte array which is by definition preinitialized
+        // to all zeroes.
         return bm;
     }
 
@@ -904,22 +1014,48 @@
      * <p>This method only returns true if {@link #hasAlpha()} returns true.
      * A bitmap with no alpha channel can be used both as a pre-multiplied and
      * as a non pre-multiplied bitmap.</p>
-     * 
+     *
+     * <p>Only pre-multiplied bitmaps may be drawn by the view system or
+     * {@link Canvas}. If a non-pre-multiplied bitmap with an alpha channel is
+     * drawn to a Canvas, a RuntimeException will be thrown.</p>
+     *
      * @return true if the underlying pixels have been pre-multiplied, false
      *         otherwise
+     *
+     * @see Bitmap#setPremultiplied(boolean)
+     * @see BitmapFactory.Options#inPremultiplied
      */
     public final boolean isPremultiplied() {
-        return getConfig() != Config.RGB_565 && hasAlpha();
+        return mIsPremultiplied && getConfig() != Config.RGB_565 && hasAlpha();
+    }
+
+    /**
+     * Sets whether the bitmap should treat its data as pre-multiplied.
+     *
+     * <p>Bitmaps are always treated as pre-multiplied by the view system and
+     * {@link Canvas} for performance reasons. Storing un-pre-multiplied data in
+     * a Bitmap (through {@link #setPixel}, {@link #setPixels}, or {@link
+     * BitmapFactory.Options#inPremultiplied BitmapFactory.Options.inPremultiplied})
+     * can lead to incorrect blending if drawn by the framework.</p>
+     *
+     * <p>This method will not affect the behavior of a bitmap without an alpha
+     * channel, or if {@link #hasAlpha()} returns false.</p>
+     *
+     * @see Bitmap#isPremultiplied()
+     * @see BitmapFactory.Options#inPremultiplied
+     */
+    public final void setPremultiplied(boolean premultiplied) {
+        mIsPremultiplied = premultiplied;
     }
 
     /** Returns the bitmap's width */
     public final int getWidth() {
-        return mWidth == -1 ? mWidth = nativeWidth(mNativeBitmap) : mWidth;
+        return mWidth;
     }
 
     /** Returns the bitmap's height */
     public final int getHeight() {
-        return mHeight == -1 ? mHeight = nativeHeight(mNativeBitmap) : mHeight;
+        return mHeight;
     }
 
     /**
@@ -994,6 +1130,10 @@
      * getPixels() or setPixels(), then the pixels are uniformly treated as
      * 32bit values, packed according to the Color class.
      *
+     * <p>As of {@link android.os.Build.VERSION_CODES#KITKAT}, this method
+     * should not be used to calculate the memory usage of the bitmap. Instead,
+     * see {@link #getAllocationByteCount()}.
+     *
      * @return number of bytes between rows of the native bitmap pixels.
      */
     public final int getRowBytes() {
@@ -1001,7 +1141,11 @@
     }
 
     /**
-     * Returns the number of bytes used to store this bitmap's pixels.
+     * Returns the minimum number of bytes that can be used to store this bitmap's pixels.
+     *
+     * <p>As of {@link android.os.Build.VERSION_CODES#KITKAT}, the result of this method can
+     * no longer be used to determine memory usage of a bitmap. See {@link
+     * #getAllocationByteCount()}.</p>
      */
     public final int getByteCount() {
         // int result permits bitmaps up to 46,340 x 46,340
@@ -1009,6 +1153,24 @@
     }
 
     /**
+     * Returns the size of the allocated memory used to store this bitmap's pixels.
+     *
+     * <p>This can be larger than the result of {@link #getByteCount()} if a bitmap is reused to
+     * decode other bitmaps of smaller size, or by manual reconfiguration. See {@link
+     * #reconfigure(int, int, Config)}, {@link #setWidth(int)}, {@link #setHeight(int)}, {@link
+     * #setConfig(Bitmap.Config)}, and {@link BitmapFactory.Options#inBitmap
+     * BitmapFactory.Options.inBitmap}. If a bitmap is not modified in this way, this value will be
+     * the same as that returned by {@link #getByteCount()}.</p>
+     *
+     * <p>This value will not change over the lifetime of a Bitmap.</p>
+     *
+     * @see #reconfigure(int, int, Config)
+     */
+    public final int getAllocationByteCount() {
+        return mBuffer.length;
+    }
+
+    /**
      * If the bitmap's internal config is in one of the public formats, return
      * that config, otherwise return null.
      */
@@ -1113,7 +1275,7 @@
     public int getPixel(int x, int y) {
         checkRecycled("Can't call getPixel() on a recycled bitmap");
         checkPixelAccess(x, y);
-        return nativeGetPixel(mNativeBitmap, x, y);
+        return nativeGetPixel(mNativeBitmap, x, y, mIsPremultiplied);
     }
 
     /**
@@ -1147,7 +1309,7 @@
         }
         checkPixelsAccess(x, y, width, height, offset, stride, pixels);
         nativeGetPixels(mNativeBitmap, pixels, offset, stride,
-                        x, y, width, height);
+                        x, y, width, height, mIsPremultiplied);
     }
 
     /**
@@ -1227,7 +1389,7 @@
             throw new IllegalStateException();
         }
         checkPixelAccess(x, y);
-        nativeSetPixel(mNativeBitmap, x, y, color);
+        nativeSetPixel(mNativeBitmap, x, y, color, mIsPremultiplied);
     }
 
     /**
@@ -1264,7 +1426,7 @@
         }
         checkPixelsAccess(x, y, width, height, offset, stride, pixels);
         nativeSetPixels(mNativeBitmap, pixels, offset, stride,
-                        x, y, width, height);
+                        x, y, width, height, mIsPremultiplied);
     }
 
     public static final Parcelable.Creator<Bitmap> CREATOR
@@ -1400,31 +1562,32 @@
 
     private static native Bitmap nativeCreate(int[] colors, int offset,
                                               int stride, int width, int height,
-                                            int nativeConfig, boolean mutable);
+                                              int nativeConfig, boolean mutable);
     private static native Bitmap nativeCopy(int srcBitmap, int nativeConfig,
                                             boolean isMutable);
     private static native void nativeDestructor(int nativeBitmap);
     private static native boolean nativeRecycle(int nativeBitmap);
+    private static native void nativeReconfigure(int nativeBitmap, int width, int height,
+                                                 int config, int allocSize);
 
     private static native boolean nativeCompress(int nativeBitmap, int format,
                                             int quality, OutputStream stream,
                                             byte[] tempStorage);
     private static native void nativeErase(int nativeBitmap, int color);
-    private static native int nativeWidth(int nativeBitmap);
-    private static native int nativeHeight(int nativeBitmap);
     private static native int nativeRowBytes(int nativeBitmap);
     private static native int nativeConfig(int nativeBitmap);
 
-    private static native int nativeGetPixel(int nativeBitmap, int x, int y);
+    private static native int nativeGetPixel(int nativeBitmap, int x, int y,
+                                             boolean isPremultiplied);
     private static native void nativeGetPixels(int nativeBitmap, int[] pixels,
-                                               int offset, int stride, int x,
-                                               int y, int width, int height);
+                                               int offset, int stride, int x, int y,
+                                               int width, int height, boolean isPremultiplied);
 
     private static native void nativeSetPixel(int nativeBitmap, int x, int y,
-                                              int color);
+                                              int color, boolean isPremultiplied);
     private static native void nativeSetPixels(int nativeBitmap, int[] colors,
-                                               int offset, int stride, int x,
-                                               int y, int width, int height);
+                                               int offset, int stride, int x, int y,
+                                               int width, int height, boolean isPremultiplied);
     private static native void nativeCopyPixelsToBuffer(int nativeBitmap,
                                                         Buffer dst);
     private static native void nativeCopyPixelsFromBuffer(int nb, Buffer src);
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index f155cd2..23606a1 100644
--- a/graphics/java/android/graphics/BitmapFactory.java
+++ b/graphics/java/android/graphics/BitmapFactory.java
@@ -18,11 +18,11 @@
 
 import android.content.res.AssetManager;
 import android.content.res.Resources;
+import android.os.Trace;
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.util.TypedValue;
 
-import java.io.BufferedInputStream;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
 import java.io.IOException;
@@ -43,28 +43,59 @@
         public Options() {
             inDither = false;
             inScaled = true;
+            inPremultiplied = true;
         }
 
         /**
          * If set, decode methods that take the Options object will attempt to
-         * reuse this bitmap when loading content. If the decode operation cannot
-         * use this bitmap, the decode method will return <code>null</code> and
-         * will throw an IllegalArgumentException. The current implementation
-         * necessitates that the reused bitmap be mutable and of the same size as the
-         * source content. The source content must be in jpeg or png format (whether as
-         * a resource or as a stream). The {@link android.graphics.Bitmap.Config
-         * configuration} of the reused bitmap will override the setting of
-         * {@link #inPreferredConfig}, if set. The reused bitmap will continue to
-         * remain mutable even when decoding a resource which would normally result
-         * in an immutable bitmap.
+         * reuse this bitmap when loading content. If the decode operation
+         * cannot use this bitmap, the decode method will return
+         * <code>null</code> and will throw an IllegalArgumentException. The
+         * current implementation necessitates that the reused bitmap be
+         * mutable, and the resulting reused bitmap will continue to remain
+         * mutable even when decoding a resource which would normally result in
+         * an immutable bitmap.</p>
          *
          * <p>You should still always use the returned Bitmap of the decode
          * method and not assume that reusing the bitmap worked, due to the
          * constraints outlined above and failure situations that can occur.
          * Checking whether the return value matches the value of the inBitmap
-         * set in the Options structure is a way to see if the bitmap was reused,
-         * but in all cases you should use the returned Bitmap to make sure
-         * that you are using the bitmap that was used as the decode destination.</p>
+         * set in the Options structure will indicate if the bitmap was reused,
+         * but in all cases you should use the Bitmap returned by the decoding
+         * function to ensure that you are using the bitmap that was used as the
+         * decode destination.</p>
+         *
+         * <h3>Usage with BitmapFactory</h3>
+         *
+         * <p>As of {@link android.os.Build.VERSION_CODES#KITKAT}, any
+         * mutable bitmap can be reused by {@link BitmapFactory} to decode any
+         * other bitmaps as long as the resulting {@link Bitmap#getByteCount()
+         * byte count} of the decoded bitmap is less than or equal to the {@link
+         * Bitmap#getAllocationByteCount() allocated byte count} of the reused
+         * bitmap. This can be because the intrinsic size is smaller, or its
+         * size post scaling (for density / sample size) is smaller.</p>
+         *
+         * <p class="note">Prior to {@link android.os.Build.VERSION_CODES#KITKAT}
+         * additional constraints apply: The image being decoded (whether as a
+         * resource or as a stream) must be in jpeg or png format. Only equal
+         * sized bitmaps are supported, with {@link #inSampleSize} set to 1.
+         * Additionally, the {@link android.graphics.Bitmap.Config
+         * configuration} of the reused bitmap will override the setting of
+         * {@link #inPreferredConfig}, if set.</p>
+         *
+         * <h3>Usage with BitmapRegionDecoder</h3>
+         *
+         * <p>BitmapRegionDecoder will draw its requested content into the Bitmap
+         * provided, clipping if the output content size (post scaling) is larger
+         * than the provided Bitmap. The provided Bitmap's width, height, and
+         * {@link Bitmap.Config} will not be changed.
+         *
+         * <p class="note">BitmapRegionDecoder support for {@link #inBitmap} was
+         * introduced in {@link android.os.Build.VERSION_CODES#JELLY_BEAN}. All
+         * formats supported by BitmapRegionDecoder support Bitmap reuse via
+         * {@link #inBitmap}.</p>
+         *
+         * @see Bitmap#reconfigure(int,int, android.graphics.Bitmap.Config)
          */
         public Bitmap inBitmap;
 
@@ -108,6 +139,26 @@
         public Bitmap.Config inPreferredConfig = Bitmap.Config.ARGB_8888;
 
         /**
+         * If true (which is the default), the resulting bitmap will have its
+         * color channels pre-multipled by the alpha channel.
+         *
+         * <p>This should NOT be set to false for images to be directly drawn by
+         * the view system or through a {@link Canvas}. The view system and
+         * {@link Canvas} assume all drawn images are pre-multiplied to simplify
+         * draw-time blending, and will throw a RuntimeException when
+         * un-premultiplied are drawn.</p>
+         *
+         * <p>This is likely only useful if you want to manipulate raw encoded
+         * image data, e.g. with RenderScript or custom OpenGL.</p>
+         *
+         * <p>This does not affect bitmaps without an alpha channel.</p>
+         *
+         * @see Bitmap#hasAlpha()
+         * @see Bitmap#isPremultiplied()
+         */
+        public boolean inPremultiplied;
+
+        /**
          * If dither is true, the decoder will attempt to dither the decoded
          * image.
          */
@@ -192,6 +243,9 @@
          * rather than relying on the graphics system scaling it each time it
          * is drawn to a Canvas.
          *
+         * <p>BitmapRegionDecoder ignores this flag, and will not scale output
+         * based on density. (though {@link #inSampleSize} is supported)</p>
+         *
          * <p>This flag is turned on by default and should be turned off if you need
          * a non-scaled version of the bitmap.  Nine-patch bitmaps ignore this
          * flag and are always scaled.
@@ -426,11 +480,21 @@
         if ((offset | length) < 0 || data.length < offset + length) {
             throw new ArrayIndexOutOfBoundsException();
         }
-        Bitmap bm = nativeDecodeByteArray(data, offset, length, opts);
 
-        if (bm == null && opts != null && opts.inBitmap != null) {
-            throw new IllegalArgumentException("Problem decoding into existing bitmap");
+        Bitmap bm;
+
+        Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "decodeBitmap");
+        try {
+            bm = nativeDecodeByteArray(data, offset, length, opts);
+
+            if (bm == null && opts != null && opts.inBitmap != null) {
+                throw new IllegalArgumentException("Problem decoding into existing bitmap");
+            }
+            setDensityFromOptions(bm, opts);
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS);
         }
+
         return bm;
     }
 
@@ -448,6 +512,31 @@
     }
 
     /**
+     * Set the newly decoded bitmap's density based on the Options.
+     */
+    private 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;
+            }
+
+            byte[] np = outputBitmap.getNinePatchChunk();
+            final boolean isNinePatch = np != null && NinePatch.isNinePatchChunk(np);
+            if (opts.inScaled || isNinePatch) {
+                outputBitmap.setDensity(targetDensity);
+            }
+        } else if (opts.inBitmap != null) {
+            // bitmap was reused, ensure density is reset
+            outputBitmap.setDensity(Bitmap.getDefaultDensity());
+        }
+    }
+
+    /**
      * Decode an input stream into a bitmap. If the input stream is null, or
      * cannot be used to decode a bitmap, the function returns null.
      * The stream's position will be where ever it was after the encoded data
@@ -472,123 +561,32 @@
             return null;
         }
 
-        // we need mark/reset to work properly
+        Bitmap bm = null;
 
-        if (!is.markSupported()) {
-            is = new BufferedInputStream(is, DECODE_BUFFER_SIZE);
-        }
-
-        // so we can call reset() if a given codec gives up after reading up to
-        // this many bytes. FIXME: need to find out from the codecs what this
-        // value should be.
-        is.mark(1024);
-
-        Bitmap bm;
-        boolean finish = true;
-
-        if (is instanceof AssetManager.AssetInputStream) {
-            final int asset = ((AssetManager.AssetInputStream) is).getAssetInt();
-
-            if (opts == null || (opts.inScaled && opts.inBitmap == null)) {
-                float scale = 1.0f;
-                int targetDensity = 0;
-                if (opts != null) {
-                    final int density = opts.inDensity;
-                    targetDensity = opts.inTargetDensity;
-                    if (density != 0 && targetDensity != 0) {
-                        scale = targetDensity / (float) density;
-                    }
-                }
-
-                bm = nativeDecodeAsset(asset, outPadding, opts, true, scale);
-                if (bm != null && targetDensity != 0) bm.setDensity(targetDensity);
-
-                finish = false;
-            } else {
+        Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "decodeBitmap");
+        try {
+            if (is instanceof AssetManager.AssetInputStream) {
+                final int asset = ((AssetManager.AssetInputStream) is).getAssetInt();
                 bm = nativeDecodeAsset(asset, outPadding, opts);
-            }
-        } else {
-            // pass some temp storage down to the native code. 1024 is made up,
-            // but should be large enough to avoid too many small calls back
-            // into is.read(...) This number is not related to the value passed
-            // to mark(...) above.
-            byte [] tempStorage = null;
-            if (opts != null) tempStorage = opts.inTempStorage;
-            if (tempStorage == null) tempStorage = new byte[16 * 1024];
-
-            if (opts == null || (opts.inScaled && opts.inBitmap == null)) {
-                float scale = 1.0f;
-                int targetDensity = 0;
-                if (opts != null) {
-                    final int density = opts.inDensity;
-                    targetDensity = opts.inTargetDensity;
-                    if (density != 0 && targetDensity != 0) {
-                        scale = targetDensity / (float) density;
-                    }
-                }
-
-                bm = nativeDecodeStream(is, tempStorage, outPadding, opts, true, scale);
-                if (bm != null && targetDensity != 0) bm.setDensity(targetDensity);
-
-                finish = false;
             } else {
+                byte [] tempStorage = null;
+                if (opts != null) tempStorage = opts.inTempStorage;
+                if (tempStorage == null) tempStorage = new byte[DECODE_BUFFER_SIZE];
                 bm = nativeDecodeStream(is, tempStorage, outPadding, opts);
             }
-        }
 
-        if (bm == null && opts != null && opts.inBitmap != null) {
-            throw new IllegalArgumentException("Problem decoding into existing bitmap");
-        }
-
-        return finish ? finishDecode(bm, outPadding, opts) : bm;
-    }
-
-    private static Bitmap finishDecode(Bitmap bm, Rect outPadding, Options opts) {
-        if (bm == null || opts == null) {
-            return bm;
-        }
-        
-        final int density = opts.inDensity;
-        if (density == 0) {
-            return bm;
-        }
-        
-        bm.setDensity(density);
-        final int targetDensity = opts.inTargetDensity;
-        if (targetDensity == 0 || density == targetDensity || density == opts.inScreenDensity) {
-            return bm;
-        }
-        byte[] np = bm.getNinePatchChunk();
-        int[] lb = bm.getLayoutBounds();
-        final boolean isNinePatch = np != null && NinePatch.isNinePatchChunk(np);
-        if (opts.inScaled || isNinePatch) {
-            float scale = targetDensity / (float) density;
-            if (scale != 1.0f) {
-                final Bitmap oldBitmap = bm;
-                bm = Bitmap.createScaledBitmap(oldBitmap,
-                        Math.max(1, (int) (bm.getWidth() * scale + 0.5f)),
-                        Math.max(1, (int) (bm.getHeight() * scale + 0.5f)), true);
-                if (bm != oldBitmap) oldBitmap.recycle();
-
-                if (isNinePatch) {
-                    np = nativeScaleNinePatch(np, scale, outPadding);
-                    bm.setNinePatchChunk(np);
-                }
-                if (lb != null) {
-                    int[] newLb = new int[lb.length];
-                    for (int i=0; i<lb.length; i++) {
-                        newLb[i] = (int)((lb[i]*scale)+.5f);
-                    }
-                    bm.setLayoutBounds(newLb);
-                }
+            if (bm == null && opts != null && opts.inBitmap != null) {
+                throw new IllegalArgumentException("Problem decoding into existing bitmap");
             }
 
-            bm.setDensity(targetDensity);
+            setDensityFromOptions(bm, opts);
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS);
         }
 
         return bm;
     }
-    
+
     /**
      * Decode an input stream into a bitmap. If the input stream is null, or
      * cannot be used to decode a bitmap, the function returns null.
@@ -614,26 +612,41 @@
      *                   no bitmap is returned (null) then padding is
      *                   unchanged.
      * @param opts null-ok; Options that control downsampling and whether the
-     *             image should be completely decoded, or just is size returned.
+     *             image should be completely decoded, or just its size returned.
      * @return the decoded bitmap, or null
      */
     public static Bitmap decodeFileDescriptor(FileDescriptor fd, Rect outPadding, Options opts) {
-        if (nativeIsSeekable(fd)) {
-            Bitmap bm = nativeDecodeFileDescriptor(fd, outPadding, opts);
+        Bitmap bm;
+
+        Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "decodeFileDescriptor");
+        try {
+            if (nativeIsSeekable(fd)) {
+                bm = nativeDecodeFileDescriptor(fd, outPadding, opts);
+            } else {
+                FileInputStream fis = new FileInputStream(fd);
+                // FIXME: If nativeDecodeStream grabbed the pointer to tempStorage
+                // from Options, this code would not need to be duplicated.
+                byte [] tempStorage = null;
+                if (opts != null) tempStorage = opts.inTempStorage;
+                if (tempStorage == null) tempStorage = new byte[DECODE_BUFFER_SIZE];
+                try {
+                    bm = nativeDecodeStream(fis, tempStorage, outPadding, opts);
+                } finally {
+                    try {
+                        fis.close();
+                    } catch (Throwable t) {/* ignore */}
+                }
+            }
+
             if (bm == null && opts != null && opts.inBitmap != null) {
                 throw new IllegalArgumentException("Problem decoding into existing bitmap");
             }
-            return finishDecode(bm, outPadding, opts);
-        } else {
-            FileInputStream fis = new FileInputStream(fd);
-            try {
-                return decodeStream(fis, outPadding, opts);
-            } finally {
-                try {
-                    fis.close();
-                } catch (Throwable t) {/* ignore */}
-            }
+
+            setDensityFromOptions(bm, opts);
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS);
         }
+        return bm;
     }
 
     /**
@@ -650,15 +663,10 @@
 
     private static native Bitmap nativeDecodeStream(InputStream is, byte[] storage,
             Rect padding, Options opts);
-    private static native Bitmap nativeDecodeStream(InputStream is, byte[] storage,
-            Rect padding, Options opts, boolean applyScale, float scale);
     private static native Bitmap nativeDecodeFileDescriptor(FileDescriptor fd,
             Rect padding, Options opts);
     private static native Bitmap nativeDecodeAsset(int asset, Rect padding, Options opts);
-    private static native Bitmap nativeDecodeAsset(int asset, Rect padding, Options opts,
-            boolean applyScale, float scale);
     private static native Bitmap nativeDecodeByteArray(byte[] data, int offset,
             int length, Options opts);
-    private static native byte[] nativeScaleNinePatch(byte[] chunk, float scale, Rect pad);
     private static native boolean nativeIsSeekable(FileDescriptor fd);
 }
diff --git a/graphics/java/android/graphics/BitmapRegionDecoder.java b/graphics/java/android/graphics/BitmapRegionDecoder.java
index b38d107..3524b25 100644
--- a/graphics/java/android/graphics/BitmapRegionDecoder.java
+++ b/graphics/java/android/graphics/BitmapRegionDecoder.java
@@ -17,7 +17,6 @@
 
 import android.content.res.AssetManager;
 
-import java.io.BufferedInputStream;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
 import java.io.IOException;
@@ -108,12 +107,6 @@
      */
     public static BitmapRegionDecoder newInstance(InputStream is,
             boolean isShareable) throws IOException {
-        // we need mark/reset to work properly in JNI
-
-        if (!is.markSupported()) {
-            is = new BufferedInputStream(is, 16 * 1024);
-        }
-
         if (is instanceof AssetManager.AssetInputStream) {
             return nativeNewInstance(
                     ((AssetManager.AssetInputStream) is).getAssetInt(),
diff --git a/graphics/java/android/graphics/BitmapShader.java b/graphics/java/android/graphics/BitmapShader.java
index f74d0ef..a4f75b9 100644
--- a/graphics/java/android/graphics/BitmapShader.java
+++ b/graphics/java/android/graphics/BitmapShader.java
@@ -28,6 +28,9 @@
     @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
     public final Bitmap mBitmap;
 
+    private TileMode mTileX;
+    private TileMode mTileY;
+
     /**
      * Call this to create a new shader that will draw with a bitmap.
      *
@@ -37,11 +40,23 @@
      */
     public BitmapShader(Bitmap bitmap, TileMode tileX, TileMode tileY) {
         mBitmap = bitmap;
+        mTileX = tileX;
+        mTileY = tileY;
         final int b = bitmap.ni();
         native_instance = nativeCreate(b, tileX.nativeInt, tileY.nativeInt);
         native_shader = nativePostCreate(native_instance, b, tileX.nativeInt, tileY.nativeInt);
     }
 
+    /**
+     * @hide
+     */
+    @Override
+    protected Shader copy() {
+        final BitmapShader copy = new BitmapShader(mBitmap, mTileX, mTileY);
+        copyLocalMatrix(copy);
+        return copy;
+    }
+
     private static native int nativeCreate(int native_bitmap, int shaderTileModeX,
             int shaderTileModeY);
     private static native int nativePostCreate(int native_shader, int native_bitmap,
diff --git a/graphics/java/android/graphics/Camera.java b/graphics/java/android/graphics/Camera.java
index 6f71a2b..9e07bd4 100644
--- a/graphics/java/android/graphics/Camera.java
+++ b/graphics/java/android/graphics/Camera.java
@@ -22,6 +22,8 @@
  * {@link Canvas}.
  */
 public class Camera {
+    private Matrix mMatrix;
+
     /**
      * Creates a new camera, with empty transformations.
      */
@@ -147,7 +149,13 @@
      * @param canvas The Canvas to set the transform matrix onto
      */
     public void applyToCanvas(Canvas canvas) {
-        nativeApplyToCanvas(canvas.mNativeCanvas);
+        if (canvas.isHardwareAccelerated()) {
+            if (mMatrix == null) mMatrix = new Matrix();
+            getMatrix(mMatrix);
+            canvas.concat(mMatrix);
+        } else {
+            nativeApplyToCanvas(canvas.mNativeCanvas);
+        }
     }
 
     public native float dotWithNormal(float dx, float dy, float dz);
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index c851844..d46238f 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -37,12 +37,14 @@
  * Canvas and Drawables</a> developer guide.</p></div>
  */
 public class Canvas {
+
     // assigned in constructors or setBitmap, freed in finalizer
-    int mNativeCanvas;
-    
+    /** @hide */
+    public int mNativeCanvas;
+
     // may be null
     private Bitmap mBitmap;
-    
+
     // optional field set by the caller
     private DrawFilter mDrawFilter;
 
@@ -59,7 +61,7 @@
     protected int mScreenDensity = Bitmap.DENSITY_NONE;
     
     // Used by native code
-    @SuppressWarnings({"UnusedDeclaration"})
+    @SuppressWarnings("UnusedDeclaration")
     private int mSurfaceFormat;
 
     /**
@@ -79,10 +81,9 @@
     private static final int MAXMIMUM_BITMAP_SIZE = 32766;
 
     // This field is used to finalize the native Canvas properly
-    @SuppressWarnings({"UnusedDeclaration"})
     private final CanvasFinalizer mFinalizer;
 
-    private static class CanvasFinalizer {
+    private static final class CanvasFinalizer {
         private int mNativeCanvas;
 
         public CanvasFinalizer(int nativeCanvas) {
@@ -92,13 +93,18 @@
         @Override
         protected void finalize() throws Throwable {
             try {
-                if (mNativeCanvas != 0) {
-                    finalizer(mNativeCanvas);
-                }
+                dispose();
             } finally {
                 super.finalize();
             }
         }
+
+        public void dispose() {
+            if (mNativeCanvas != 0) {
+                finalizer(mNativeCanvas);
+                mNativeCanvas = 0;
+            }
+        }
     }
 
     /**
@@ -108,9 +114,13 @@
      * canvas.
      */
     public Canvas() {
-        // 0 means no native bitmap
-        mNativeCanvas = initRaster(0);
-        mFinalizer = new CanvasFinalizer(mNativeCanvas);
+        if (!isHardwareAccelerated()) {
+            // 0 means no native bitmap
+            mNativeCanvas = initRaster(0);
+            mFinalizer = new CanvasFinalizer(mNativeCanvas);
+        } else {
+            mFinalizer = null;
+        }
     }
 
     /**
@@ -126,19 +136,20 @@
         if (!bitmap.isMutable()) {
             throw new IllegalStateException("Immutable bitmap passed to Canvas constructor");
         }
-        throwIfRecycled(bitmap);
+        throwIfCannotDraw(bitmap);
         mNativeCanvas = initRaster(bitmap.ni());
         mFinalizer = new CanvasFinalizer(mNativeCanvas);
         mBitmap = bitmap;
         mDensity = bitmap.mDensity;
     }
-    
-    Canvas(int nativeCanvas) {
+
+    /** @hide */
+    public Canvas(int nativeCanvas) {
         if (nativeCanvas == 0) {
             throw new IllegalStateException();
         }
         mNativeCanvas = nativeCanvas;
-        mFinalizer = new CanvasFinalizer(nativeCanvas);
+        mFinalizer = new CanvasFinalizer(mNativeCanvas);
         mDensity = Bitmap.getDefaultDensity();
     }
 
@@ -155,7 +166,18 @@
         }
         finalizer(oldCanvas);
     }
-    
+
+    /**
+     * Gets the native canvas pointer.
+     *
+     * @return The native pointer.
+     *
+     * @hide
+     */
+    public int getNativeCanvas() {
+        return mNativeCanvas;
+    }
+
     /**
      * Returns null.
      * 
@@ -203,7 +225,7 @@
             if (!bitmap.isMutable()) {
                 throw new IllegalStateException();
             }
-            throwIfRecycled(bitmap);
+            throwIfCannotDraw(bitmap);
 
             safeCanvasSwap(initRaster(bitmap.ni()), true);
             mDensity = bitmap.mDensity;
@@ -364,8 +386,8 @@
      */
     public int saveLayer(RectF bounds, Paint paint, int saveFlags) {
         return native_saveLayer(mNativeCanvas, bounds,
-                                paint != null ? paint.mNativePaint : 0,
-                                saveFlags);
+                paint != null ? paint.mNativePaint : 0,
+                saveFlags);
     }
     
     /**
@@ -374,8 +396,8 @@
     public int saveLayer(float left, float top, float right, float bottom, Paint paint,
             int saveFlags) {
         return native_saveLayer(mNativeCanvas, left, top, right, bottom,
-                                paint != null ? paint.mNativePaint : 0,
-                                saveFlags);
+                paint != null ? paint.mNativePaint : 0,
+                saveFlags);
     }
 
     /**
@@ -495,12 +517,13 @@
     public native void skew(float sx, float sy);
 
     /**
-     * Preconcat the current matrix with the specified matrix.
+     * Preconcat the current matrix with the specified matrix. If the specified
+     * matrix is null, this method does nothing.
      *
      * @param matrix The matrix to preconcatenate with the current matrix
      */
     public void concat(Matrix matrix) {
-        native_concat(mNativeCanvas, matrix.native_instance);
+        if (matrix != null) native_concat(mNativeCanvas, matrix.native_instance);
     }
     
     /**
@@ -1022,7 +1045,7 @@
             throw new NullPointerException();
         }
         native_drawArc(mNativeCanvas, oval, startAngle, sweepAngle,
-                       useCenter, paint.mNativePaint);
+                useCenter, paint.mNativePaint);
     }
 
     /**
@@ -1052,28 +1075,47 @@
     public void drawPath(Path path, Paint paint) {
         native_drawPath(mNativeCanvas, path.ni(), paint.mNativePaint);
     }
-    
-    private static void throwIfRecycled(Bitmap bitmap) {
+
+    /**
+     * @hide
+     */
+    protected static void throwIfCannotDraw(Bitmap bitmap) {
         if (bitmap.isRecycled()) {
             throw new RuntimeException("Canvas: trying to use a recycled bitmap " + bitmap);
         }
+        if (!bitmap.isPremultiplied() && bitmap.getConfig() == Bitmap.Config.ARGB_8888 &&
+                bitmap.hasAlpha()) {
+            throw new RuntimeException("Canvas: trying to use a non-premultiplied bitmap "
+                    + bitmap);
+        }
     }
 
     /**
      * Draws the specified bitmap as an N-patch (most often, a 9-patches.)
      *
-     * Note: Only supported by hardware accelerated canvas at the moment.
-     *
-     * @param bitmap The bitmap to draw as an N-patch
-     * @param chunks The patches information (matches the native struct Res_png_9patch)
+     * @param patch The ninepatch object to render
      * @param dst The destination rectangle.
      * @param paint The paint to draw the bitmap with. may be null
      * 
      * @hide
      */
-    public void drawPatch(Bitmap bitmap, byte[] chunks, RectF dst, Paint paint) {
-    }    
-    
+    public void drawPatch(NinePatch patch, Rect dst, Paint paint) {
+        patch.drawSoftware(this, dst, paint);
+    }
+
+    /**
+     * Draws the specified bitmap as an N-patch (most often, a 9-patches.)
+     *
+     * @param patch The ninepatch object to render
+     * @param dst The destination rectangle.
+     * @param paint The paint to draw the bitmap with. may be null
+     *
+     * @hide
+     */
+    public void drawPatch(NinePatch patch, RectF dst, Paint paint) {
+        patch.drawSoftware(this, dst, paint);
+    }
+
     /**
      * Draw the specified bitmap, with its top/left corner at (x,y), using
      * the specified paint, transformed by the current matrix.
@@ -1094,7 +1136,7 @@
      * @param paint  The paint used to draw the bitmap (may be null)
      */
     public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) {
-        throwIfRecycled(bitmap);
+        throwIfCannotDraw(bitmap);
         native_drawBitmap(mNativeCanvas, bitmap.ni(), left, top,
                 paint != null ? paint.mNativePaint : 0, mDensity, mScreenDensity, bitmap.mDensity);
     }
@@ -1125,7 +1167,7 @@
         if (dst == null) {
             throw new NullPointerException();
         }
-        throwIfRecycled(bitmap);
+        throwIfCannotDraw(bitmap);
         native_drawBitmap(mNativeCanvas, bitmap.ni(), src, dst,
                           paint != null ? paint.mNativePaint : 0, mScreenDensity, bitmap.mDensity);
     }
@@ -1156,9 +1198,9 @@
         if (dst == null) {
             throw new NullPointerException();
         }
-        throwIfRecycled(bitmap);
+        throwIfCannotDraw(bitmap);
         native_drawBitmap(mNativeCanvas, bitmap.ni(), src, dst,
-                          paint != null ? paint.mNativePaint : 0, mScreenDensity, bitmap.mDensity);
+                paint != null ? paint.mNativePaint : 0, mScreenDensity, bitmap.mDensity);
     }
     
     /**
@@ -1279,8 +1321,8 @@
             checkRange(colors.length, colorOffset, count);
         }
         nativeDrawBitmapMesh(mNativeCanvas, bitmap.ni(), meshWidth, meshHeight,
-                             verts, vertOffset, colors, colorOffset,
-                             paint != null ? paint.mNativePaint : 0);
+                verts, vertOffset, colors, colorOffset,
+                paint != null ? paint.mNativePaint : 0);
     }
 
     public enum VertexMode {
@@ -1342,8 +1384,8 @@
             checkRange(indices.length, indexOffset, indexCount);
         }
         nativeDrawVertices(mNativeCanvas, mode.nativeInt, vertexCount, verts,
-                           vertOffset, texs, texOffset, colors, colorOffset,
-                          indices, indexOffset, indexCount, paint.mNativePaint);
+                vertOffset, texs, texOffset, colors, colorOffset,
+                indices, indexOffset, indexCount, paint.mNativePaint);
     }
     
     /**
@@ -1414,10 +1456,10 @@
         if (text instanceof String || text instanceof SpannedString ||
             text instanceof SpannableString) {
             native_drawText(mNativeCanvas, text.toString(), start, end, x, y,
-                            paint.mBidiFlags, paint.mNativePaint);
+                    paint.mBidiFlags, paint.mNativePaint);
         } else if (text instanceof GraphicsOperations) {
             ((GraphicsOperations) text).drawText(this, start, end, x, y,
-                                                     paint);
+                    paint);
         } else {
             char[] buf = TemporaryBuffer.obtain(end - start);
             TextUtils.getChars(text, start, end, buf, 0);
@@ -1538,7 +1580,7 @@
             throw new IndexOutOfBoundsException();
         }
         native_drawPosText(mNativeCanvas, text, index, count, pos,
-                           paint.mNativePaint);
+                paint.mNativePaint);
     }
 
     /**
@@ -1579,8 +1621,8 @@
             throw new ArrayIndexOutOfBoundsException();
         }
         native_drawTextOnPath(mNativeCanvas, text, index, count,
-                              path.ni(), hOffset, vOffset,
-                              paint.mBidiFlags, paint.mNativePaint);
+                path.ni(), hOffset, vOffset,
+                paint.mBidiFlags, paint.mNativePaint);
     }
 
     /**
@@ -1616,7 +1658,9 @@
      */
     public void drawPicture(Picture picture) {
         picture.endRecording();
-        native_drawPicture(mNativeCanvas, picture.ni());
+        int restoreCount = save();
+        picture.draw(this);
+        restoreToCount(restoreCount);
     }
     
     /**
@@ -1647,6 +1691,15 @@
     }
 
     /**
+     * Releases the resources associated with this canvas.
+     *
+     * @hide
+     */
+    public void release() {
+        mFinalizer.dispose();
+    }
+
+    /**
      * Free up as much memory as possible from private caches (e.g. fonts, images)
      *
      * @hide
@@ -1792,7 +1845,5 @@
                                                      float hOffset, 
                                                      float vOffset, 
                                                      int flags, int paint);
-    private static native void native_drawPicture(int nativeCanvas,
-                                                  int nativePicture);
     private static native void finalizer(int nativeCanvas);
 }
diff --git a/graphics/java/android/graphics/Color.java b/graphics/java/android/graphics/Color.java
index 933948d..8fbedae 100644
--- a/graphics/java/android/graphics/Color.java
+++ b/graphics/java/android/graphics/Color.java
@@ -406,18 +406,18 @@
         sColorNameMap.put("yellow", YELLOW);
         sColorNameMap.put("cyan", CYAN);
         sColorNameMap.put("magenta", MAGENTA);
-        sColorNameMap.put("aqua", 0x00FFFF);
-        sColorNameMap.put("fuchsia", 0xFF00FF);
+        sColorNameMap.put("aqua", 0xFF00FFFF);
+        sColorNameMap.put("fuchsia", 0xFFFF00FF);
         sColorNameMap.put("darkgrey", DKGRAY);
         sColorNameMap.put("grey", GRAY);
         sColorNameMap.put("lightgrey", LTGRAY);
-        sColorNameMap.put("lime", 0x00FF00);
-        sColorNameMap.put("maroon", 0x800000);
-        sColorNameMap.put("navy", 0x000080);
-        sColorNameMap.put("olive", 0x808000);
-        sColorNameMap.put("purple", 0x800080);
-        sColorNameMap.put("silver", 0xC0C0C0);
-        sColorNameMap.put("teal", 0x008080);
+        sColorNameMap.put("lime", 0xFF00FF00);
+        sColorNameMap.put("maroon", 0xFF800000);
+        sColorNameMap.put("navy", 0xFF000080);
+        sColorNameMap.put("olive", 0xFF808000);
+        sColorNameMap.put("purple", 0xFF800080);
+        sColorNameMap.put("silver", 0xFFC0C0C0);
+        sColorNameMap.put("teal", 0xFF008080);
 
     }
 }
diff --git a/graphics/java/android/graphics/ComposeShader.java b/graphics/java/android/graphics/ComposeShader.java
index 241ab17..de0d3d6 100644
--- a/graphics/java/android/graphics/ComposeShader.java
+++ b/graphics/java/android/graphics/ComposeShader.java
@@ -16,10 +16,22 @@
 
 package android.graphics;
 
-/** A subclass of shader that returns the coposition of two other shaders, combined by
+/** A subclass of shader that returns the composition of two other shaders, combined by
     an {@link android.graphics.Xfermode} subclass.
 */
 public class ComposeShader extends Shader {
+
+    private static final int TYPE_XFERMODE = 1;
+    private static final int TYPE_PORTERDUFFMODE = 2;
+
+    /**
+     * Type of the ComposeShader: can be either TYPE_XFERMODE or TYPE_PORTERDUFFMODE
+     */
+    private int mType;
+
+    private Xfermode mXferMode;
+    private PorterDuff.Mode mPorterDuffMode;
+
     /**
      * Hold onto the shaders to avoid GC.
      */
@@ -37,8 +49,10 @@
                         is null, then SRC_OVER is assumed.
     */
     public ComposeShader(Shader shaderA, Shader shaderB, Xfermode mode) {
+        mType = TYPE_XFERMODE;
         mShaderA = shaderA;
         mShaderB = shaderB;
+        mXferMode = mode;
         native_instance = nativeCreate1(shaderA.native_instance, shaderB.native_instance,
                 (mode != null) ? mode.native_instance : 0);
         if (mode instanceof PorterDuffXfermode) {
@@ -59,14 +73,37 @@
         @param mode     The PorterDuff mode that combines the colors from the two shaders.
     */
     public ComposeShader(Shader shaderA, Shader shaderB, PorterDuff.Mode mode) {
+        mType = TYPE_PORTERDUFFMODE;
         mShaderA = shaderA;
         mShaderB = shaderB;
+        mPorterDuffMode = mode;
         native_instance = nativeCreate2(shaderA.native_instance, shaderB.native_instance,
                 mode.nativeInt);
         native_shader = nativePostCreate2(native_instance, shaderA.native_shader,
                 shaderB.native_shader, mode.nativeInt);
     }
 
+    /**
+     * @hide
+     */
+    @Override
+    protected Shader copy() {
+        final ComposeShader copy;
+        switch (mType) {
+            case TYPE_XFERMODE:
+                copy = new ComposeShader(mShaderA.copy(), mShaderB.copy(), mXferMode);
+                break;
+            case TYPE_PORTERDUFFMODE:
+                copy = new ComposeShader(mShaderA.copy(), mShaderB.copy(), mPorterDuffMode);
+                break;
+            default:
+                throw new IllegalArgumentException(
+                        "ComposeShader should be created with either Xfermode or PorterDuffMode");
+        }
+        copyLocalMatrix(copy);
+        return copy;
+    }
+
     private static native int nativeCreate1(int native_shaderA, int native_shaderB,
             int native_mode);
     private static native int nativeCreate2(int native_shaderA, int native_shaderB,
diff --git a/graphics/java/android/graphics/ImageFormat.java b/graphics/java/android/graphics/ImageFormat.java
index f6b747a..e08ed50 100644
--- a/graphics/java/android/graphics/ImageFormat.java
+++ b/graphics/java/android/graphics/ImageFormat.java
@@ -73,6 +73,66 @@
     public static final int YV12 = 0x32315659;
 
     /**
+     * <p>Android Y8 format.</p>
+     *
+     * <p>Y8 is a YUV planar format comprised of a WxH Y plane only, with each pixel
+     * being represented by 8 bits. It is equivalent to just the Y plane from {@link #YV12}
+     * format.</p>
+     *
+     * <p>This format assumes
+     * <ul>
+     * <li>an even width</li>
+     * <li>an even height</li>
+     * <li>a horizontal stride multiple of 16 pixels</li>
+     * </ul>
+     * </p>
+     *
+     * <pre> y_size = stride * height </pre>
+     *
+     * <p>For example, the {@link android.media.Image} object can provide data
+     * in this format from a {@link android.hardware.camera2.CameraDevice}
+     * through a {@link android.media.ImageReader} object if this format is
+     * supported by {@link android.hardware.camera2.CameraDevice}.</p>
+     *
+     * @see android.media.Image
+     * @see android.media.ImageReader
+     * @see android.hardware.camera2.CameraDevice
+     *
+     * @hide
+     */
+    public static final int Y8 = 0x20203859;
+
+    /**
+     * <p>Android Y16 format.</p>
+     *
+     * Y16 is a YUV planar format comprised of a WxH Y plane, with each pixel
+     * being represented by 16 bits. It is just like {@link #Y8}, but has 16
+     * bits per pixel (little endian).</p>
+     *
+     * <p>This format assumes
+     * <ul>
+     * <li>an even width</li>
+     * <li>an even height</li>
+     * <li>a horizontal stride multiple of 16 pixels</li>
+     * </ul>
+     * </p>
+     *
+     * <pre> y_size = stride * height </pre>
+     *
+     * <p>For example, the {@link android.media.Image} object can provide data
+     * in this format from a {@link android.hardware.camera2.CameraDevice}
+     * through a {@link android.media.ImageReader} object if this format is
+     * supported by {@link android.hardware.camera2.CameraDevice}.</p>
+     *
+     * @see android.media.Image
+     * @see android.media.ImageReader
+     * @see android.hardware.camera2.CameraDevice
+     *
+     * @hide
+     */
+    public static final int Y16 = 0x20363159;
+
+    /**
      * YCbCr format, used for video. Whether this format is supported by the
      * camera hardware can be determined by
      * {@link android.hardware.Camera.Parameters#getSupportedPreviewFormats()}.
@@ -100,6 +160,57 @@
     public static final int JPEG = 0x100;
 
     /**
+     * <p>Multi-plane Android YUV format</p>
+     *
+     * <p>This format is a generic YCbCr format, capable of describing any 4:2:0
+     * chroma-subsampled planar or semiplanar buffer (but not fully interleaved),
+     * with 8 bits per color sample.</p>
+     *
+     * <p>Images in this format are always represented by three separate buffers
+     * of data, one for each color plane. Additional information always
+     * accompanies the buffers, describing the row stride and the pixel stride
+     * for each plane.</p>
+     *
+     * <p>The order of planes in the array returned by
+     * {@link android.media.Image#getPlanes() Image#getPlanes()} is guaranteed such that
+     * plane #0 is always Y, plane #1 is always U (Cb), and plane #2 is always V (Cr).</p>
+     *
+     * <p>The Y-plane is guaranteed not to be interleaved with the U/V planes
+     * (in particular, pixel stride is always 1 in
+     * {@link android.media.Image.Plane#getPixelStride() yPlane.getPixelStride()}).</p>
+     *
+     * <p>The U/V planes are guaranteed to have the same row stride and pixel stride
+     * (in particular,
+     * {@link android.media.Image.Plane#getRowStride() uPlane.getRowStride()}
+     * == {@link android.media.Image.Plane#getRowStride() vPlane.getRowStride()} and
+     * {@link android.media.Image.Plane#getPixelStride() uPlane.getPixelStride()}
+     * == {@link android.media.Image.Plane#getPixelStride() vPlane.getPixelStride()};
+     * ).</p>
+     *
+     * <p>For example, the {@link android.media.Image} object can provide data
+     * in this format from a {@link android.hardware.camera2.CameraDevice}
+     * through a {@link android.media.ImageReader} object.</p>
+     *
+     * @see android.media.Image
+     * @see android.media.ImageReader
+     * @see android.hardware.camera2.CameraDevice
+     */
+    public static final int YUV_420_888 = 0x23;
+
+    /**
+     * <p>General raw camera sensor image format, usually representing a
+     * single-channel Bayer-mosaic image. Each pixel color sample is stored with
+     * 16 bits of precision.</p>
+     *
+     * <p>The layout of the color mosaic, the maximum and minimum encoding
+     * values of the raw pixel data, the color space of the image, and all other
+     * needed information to interpret a raw sensor image must be queried from
+     * the {@link android.hardware.camera2.CameraDevice} which produced the
+     * image.</p>
+     */
+    public static final int RAW_SENSOR = 0x20;
+
+    /**
      * Raw bayer format used for images, which is 10 bit precision samples
      * stored in 16 bit words. The filter pattern is RGGB. Whether this format
      * is supported by the camera hardware can be determined by
@@ -127,8 +238,16 @@
                 return 16;
             case YV12:
                 return 12;
+            case Y8:
+                return 8;
+            case Y16:
+                return 16;
             case NV21:
                 return 12;
+            case YUV_420_888:
+                return 12;
+            case RAW_SENSOR:
+                return 16;
             case BAYER_RGGB:
                 return 16;
         }
diff --git a/graphics/java/android/graphics/LinearGradient.java b/graphics/java/android/graphics/LinearGradient.java
index 96a71e3..4c88de3 100644
--- a/graphics/java/android/graphics/LinearGradient.java
+++ b/graphics/java/android/graphics/LinearGradient.java
@@ -17,6 +17,27 @@
 package android.graphics;
 
 public class LinearGradient extends Shader {
+
+    private static final int TYPE_COLORS_AND_POSITIONS = 1;
+    private static final int TYPE_COLOR_START_AND_COLOR_END = 2;
+
+    /**
+     * Type of the LinearGradient: can be either TYPE_COLORS_AND_POSITIONS or
+     * TYPE_COLOR_START_AND_COLOR_END.
+     */
+    private int mType;
+
+    private float mX0;
+    private float mY0;
+    private float mX1;
+    private float mY1;
+    private int[] mColors;
+    private float[] mPositions;
+    private int mColor0;
+    private int mColor1;
+
+    private TileMode mTileMode;
+
 	/**	Create a shader that draws a linear gradient along a line.
         @param x0           The x-coordinate for the start of the gradient line
         @param y0           The y-coordinate for the start of the gradient line
@@ -36,6 +57,14 @@
         if (positions != null && colors.length != positions.length) {
             throw new IllegalArgumentException("color and position arrays must be of equal length");
         }
+        mType = TYPE_COLORS_AND_POSITIONS;
+        mX0 = x0;
+        mY0 = y0;
+        mX1 = x1;
+        mY1 = y1;
+        mColors = colors;
+        mPositions = positions;
+        mTileMode = tile;
         native_instance = nativeCreate1(x0, y0, x1, y1, colors, positions, tile.nativeInt);
         native_shader = nativePostCreate1(native_instance, x0, y0, x1, y1, colors, positions,
                 tile.nativeInt);
@@ -52,12 +81,42 @@
 	*/
 	public LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1,
             TileMode tile) {
+        mType = TYPE_COLOR_START_AND_COLOR_END;
+        mX0 = x0;
+        mY0 = y0;
+        mX1 = x1;
+        mY1 = y1;
+        mColor0 = color0;
+        mColor1 = color1;
+        mTileMode = tile;
         native_instance = nativeCreate2(x0, y0, x1, y1, color0, color1, tile.nativeInt);
         native_shader = nativePostCreate2(native_instance, x0, y0, x1, y1, color0, color1,
                 tile.nativeInt);
     }
 
-	private native int nativeCreate1(float x0, float y0, float x1, float y1,
+    /**
+     * @hide
+     */
+    @Override
+    protected Shader copy() {
+        final LinearGradient copy;
+        switch (mType) {
+            case TYPE_COLORS_AND_POSITIONS:
+                copy = new LinearGradient(mX0, mY0, mX1, mY1, mColors.clone(),
+                        mPositions != null ? mPositions.clone() : null, mTileMode);
+                break;
+            case TYPE_COLOR_START_AND_COLOR_END:
+                copy = new LinearGradient(mX0, mY0, mX1, mY1, mColor0, mColor1, mTileMode);
+                break;
+            default:
+                throw new IllegalArgumentException("LinearGradient should be created with either " +
+                        "colors and positions or start color and end color");
+        }
+        copyLocalMatrix(copy);
+        return copy;
+    }
+
+    private native int nativeCreate1(float x0, float y0, float x1, float y1,
             int colors[], float positions[], int tileMode);
 	private native int nativeCreate2(float x0, float y0, float x1, float y1,
             int color0, int color1, int tileMode);
diff --git a/graphics/java/android/graphics/Matrix.java b/graphics/java/android/graphics/Matrix.java
index a837294..32e0c01 100644
--- a/graphics/java/android/graphics/Matrix.java
+++ b/graphics/java/android/graphics/Matrix.java
@@ -21,9 +21,6 @@
 
 /**
  * The Matrix class holds a 3x3 matrix for transforming coordinates.
- * Matrix does not have a constructor, so it must be explicitly initialized
- * using either reset() - to construct an identity matrix, or one of the set..()
- * functions (e.g. setTranslate, setRotate, etc.).
  */
 public class Matrix {
 
@@ -267,13 +264,23 @@
             native_set(native_instance, src.native_instance);
         }
     }
-    
+
     /** Returns true iff obj is a Matrix and its values equal our values.
     */
+    @Override
     public boolean equals(Object obj) {
-        return obj != null &&
-               obj instanceof Matrix &&
-               native_equals(native_instance, ((Matrix)obj).native_instance);
+        //if (obj == this) return true;     -- NaN value would mean matrix != itself
+        if (!(obj instanceof Matrix)) return false;
+        return native_equals(native_instance, ((Matrix)obj).native_instance);
+    }
+
+    @Override
+    public int hashCode() {
+        // This should generate the hash code by performing some arithmetic operation on all
+        // the matrix elements -- our equals() does an element-by-element comparison, and we
+        // need to ensure that the hash code for two equal objects is the same.  We're not
+        // really using this at the moment, so we take the easy way out.
+        return 44;
     }
 
     /** Set the matrix to identity */
@@ -512,7 +519,7 @@
          */
         END     (3);
 
-        // the native values must match those in SkMatrix.h 
+        // the native values must match those in SkMatrix.h
         ScaleToFit(int nativeInt) {
             this.nativeInt = nativeInt;
         }
@@ -535,7 +542,7 @@
         }
         return native_setRectToRect(native_instance, src, dst, stf.nativeInt);
     }
-    
+
     // private helper to perform range checks on arrays of "points"
     private static void checkPointArrays(float[] src, int srcIndex,
                                          float[] dst, int dstIndex,
@@ -598,7 +605,7 @@
         native_mapPoints(native_instance, dst, dstIndex, src, srcIndex,
                          pointCount, true);
     }
-    
+
     /**
     * Apply this matrix to the array of 2D vectors specified by src, and write
      * the transformed vectors into the array of vectors specified by dst. The
@@ -620,7 +627,7 @@
         native_mapPoints(native_instance, dst, dstIndex, src, srcIndex,
                          vectorCount, false);
     }
-    
+
     /**
      * 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
@@ -713,7 +720,7 @@
     public float mapRadius(float radius) {
         return native_mapRadius(native_instance, radius);
     }
-    
+
     /** Copy 9 values from the matrix into the array.
     */
     public void getValues(float[] values) {
@@ -736,13 +743,14 @@
         native_setValues(native_instance, values);
     }
 
+    @Override
     public String toString() {
         StringBuilder sb = new StringBuilder(64);
         sb.append("Matrix{");
         toShortString(sb);
         sb.append('}');
         return sb.toString();
-                
+
     }
 
     public String toShortString() {
@@ -780,13 +788,18 @@
                 pw.print(values[5]); pw.print("][");
         pw.print(values[6]); pw.print(", "); pw.print(values[7]); pw.print(", ");
                 pw.print(values[8]); pw.print(']');
-                
+
     }
 
+    @Override
     protected void finalize() throws Throwable {
-        finalizer(native_instance);
+        try {
+            finalizer(native_instance);
+        } finally {
+            super.finalize();
+        }
     }
-    
+
     /*package*/ final int ni() {
         return native_instance;
     }
diff --git a/graphics/java/android/graphics/NinePatch.java b/graphics/java/android/graphics/NinePatch.java
index 6de4d84..528d9de 100644
--- a/graphics/java/android/graphics/NinePatch.java
+++ b/graphics/java/android/graphics/NinePatch.java
@@ -18,11 +18,8 @@
 
 
 /**
- * The NinePatch class permits drawing a bitmap in nine sections.
- * The four corners are unscaled; the four edges are scaled in one axis,
- * and the middle is scaled in both axes. Normally, the middle is 
- * transparent so that the patch can provide a selection about a rectangle.
- * Essentially, it allows the creation of custom graphics that will scale the 
+ * The NinePatch class permits drawing a bitmap in nine or more sections.
+ * Essentially, it allows the creation of custom graphics that will scale the
  * way that you define, when content added within the image exceeds the normal
  * bounds of the graphic. For a thorough explanation of a NinePatch image, 
  * read the discussion in the 
@@ -36,24 +33,40 @@
  */
 public class NinePatch {
     private final Bitmap mBitmap;
-    private final byte[] mChunk;
+
+    /**
+     * Used by native code. This pointer is an instance of Res_png_9patch*.
+     *
+     * @hide
+     */
+    public final int mNativeChunk;
+
     private Paint mPaint;
-    private String mSrcName;  // Useful for debugging
-    private final RectF mRect = new RectF();
-    
+    private String mSrcName;
+
+    /**
+     * Create a drawable projection from a bitmap to nine patches.
+     *
+     * @param bitmap The bitmap describing the patches.
+     * @param chunk The 9-patch data chunk describing how the underlying bitmap
+     *              is split apart and drawn.
+     */
+    public NinePatch(Bitmap bitmap, byte[] chunk) {
+        this(bitmap, chunk, null);
+    }
+
     /** 
      * Create a drawable projection from a bitmap to nine patches.
      *
-     * @param bitmap    The bitmap describing the patches.
-     * @param chunk     The 9-patch data chunk describing how the underlying
-     *                  bitmap is split apart and drawn.
-     * @param srcName   The name of the source for the bitmap. Might be null.
+     * @param bitmap The bitmap describing the patches.
+     * @param chunk The 9-patch data chunk describing how the underlying
+     *              bitmap is split apart and drawn.
+     * @param srcName The name of the source for the bitmap. Might be null.
      */
     public NinePatch(Bitmap bitmap, byte[] chunk, String srcName) {
         mBitmap = bitmap;
-        mChunk = chunk;
         mSrcName = srcName;
-        validateNinePatchChunk(mBitmap.ni(), chunk);
+        mNativeChunk = validateNinePatchChunk(mBitmap.ni(), chunk);
     }
 
     /**
@@ -61,69 +74,103 @@
      */
     public NinePatch(NinePatch patch) {
         mBitmap = patch.mBitmap;
-        mChunk = patch.mChunk;
         mSrcName = patch.mSrcName;
         if (patch.mPaint != null) {
             mPaint = new Paint(patch.mPaint);
         }
-        validateNinePatchChunk(mBitmap.ni(), mChunk);
+        // No need to validate the 9patch chunk again, it was done by
+        // the instance we're copying from
+        mNativeChunk = patch.mNativeChunk;
     }
 
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            nativeFinalize(mNativeChunk);
+        } finally {
+            super.finalize();
+        }
+    }
+
+    /**
+     * Returns the name of this NinePatch object if one was specified
+     * when calling the constructor.
+     */
+    public String getName() {
+        return mSrcName;
+    }
+
+    /**
+     * Returns the paint used to draw this NinePatch. The paint can be null.
+     *
+     * @see #setPaint(Paint)
+     * @see #draw(Canvas, Rect)
+     * @see #draw(Canvas, RectF)
+     */
+    public Paint getPaint() {
+        return mPaint;
+    }
+
+    /**
+     * Sets the paint to use when drawing the NinePatch.
+     *
+     * @param p The paint that will be used to draw this NinePatch.
+     *
+     * @see #getPaint()
+     * @see #draw(Canvas, Rect)
+     * @see #draw(Canvas, RectF)
+     */
     public void setPaint(Paint p) {
         mPaint = p;
     }
-    
-    /** 
-     * Draw a bitmap of nine patches.
-     *
-     * @param canvas    A container for the current matrix and clip used to draw the bitmap.
-     * @param location  Where to draw the bitmap.
+
+    /**
+     * Returns the bitmap used to draw this NinePatch.
      */
-    public void draw(Canvas canvas, RectF location) {
-        if (!canvas.isHardwareAccelerated()) {
-            nativeDraw(canvas.mNativeCanvas, location,
-                       mBitmap.ni(), mChunk,
-                       mPaint != null ? mPaint.mNativePaint : 0,
-                       canvas.mDensity, mBitmap.mDensity);
-        } else {
-            canvas.drawPatch(mBitmap, mChunk, location, mPaint);
-        }
+    public Bitmap getBitmap() {
+        return mBitmap;
     }
     
     /** 
-     * Draw a bitmap of nine patches.
+     * Draws the NinePatch. This method will use the paint returned by {@link #getPaint()}.
      *
-     * @param canvas    A container for the current matrix and clip used to draw the bitmap.
-     * @param location  Where to draw the bitmap.
+     * @param canvas A container for the current matrix and clip used to draw the NinePatch.
+     * @param location Where to draw the NinePatch.
      */
-    public void draw(Canvas canvas, Rect location) {
-        if (!canvas.isHardwareAccelerated()) {
-            nativeDraw(canvas.mNativeCanvas, location,
-                        mBitmap.ni(), mChunk,
-                        mPaint != null ? mPaint.mNativePaint : 0,
-                        canvas.mDensity, mBitmap.mDensity);
-        } else {
-            mRect.set(location);
-            canvas.drawPatch(mBitmap, mChunk, mRect, mPaint);
-        }
+    public void draw(Canvas canvas, RectF location) {
+        canvas.drawPatch(this, location, mPaint);
     }
 
     /** 
-     * Draw a bitmap of nine patches.
+     * Draws the NinePatch. This method will use the paint returned by {@link #getPaint()}.
      *
-     * @param canvas    A container for the current matrix and clip used to draw the bitmap.
-     * @param location  Where to draw the bitmap.
-     * @param paint     The Paint to draw through.
+     * @param canvas A container for the current matrix and clip used to draw the NinePatch.
+     * @param location Where to draw the NinePatch.
+     */
+    public void draw(Canvas canvas, Rect location) {
+        canvas.drawPatch(this, location, mPaint);
+    }
+
+    /** 
+     * Draws the NinePatch. This method will ignore the paint returned
+     * by {@link #getPaint()} and use the specified paint instead.
+     *
+     * @param canvas A container for the current matrix and clip used to draw the NinePatch.
+     * @param location Where to draw the NinePatch.
+     * @param paint The Paint to draw through.
      */
     public void draw(Canvas canvas, Rect location, Paint paint) {
-        if (!canvas.isHardwareAccelerated()) {
-            nativeDraw(canvas.mNativeCanvas, location,
-                    mBitmap.ni(), mChunk, paint != null ? paint.mNativePaint : 0,
-                    canvas.mDensity, mBitmap.mDensity);
-        } else {
-            mRect.set(location);
-            canvas.drawPatch(mBitmap, mChunk, mRect, paint);
-        }
+        canvas.drawPatch(this, location, paint);
+    }
+
+    void drawSoftware(Canvas canvas, RectF location, Paint paint) {
+        nativeDraw(canvas.mNativeCanvas, location, mBitmap.ni(), mNativeChunk,
+                paint != null ? paint.mNativePaint : 0, canvas.mDensity, mBitmap.mDensity);
+    }
+
+    void drawSoftware(Canvas canvas, Rect location, Paint paint) {
+        nativeDraw(canvas.mNativeCanvas, location, mBitmap.ni(), mNativeChunk,
+                paint != null ? paint.mNativePaint : 0, canvas.mDensity, mBitmap.mDensity);
     }
 
     /**
@@ -133,33 +180,67 @@
     public int getDensity() {
         return mBitmap.mDensity;
     }
-    
+
+    /**
+     * Returns the intrinsic width, in pixels, of this NinePatch. This is equivalent
+     * to querying the width of the underlying bitmap returned by {@link #getBitmap()}.
+     */
     public int getWidth() {
         return mBitmap.getWidth();
     }
 
+    /**
+     * Returns the intrinsic height, in pixels, of this NinePatch. This is equivalent
+     * to querying the height of the underlying bitmap returned by {@link #getBitmap()}.
+     */
     public int getHeight() {
         return mBitmap.getHeight();
     }
 
+    /**
+     * Indicates whether this NinePatch contains transparent or translucent pixels.
+     * This is equivalent to calling <code>getBitmap().hasAlpha()</code> on this
+     * NinePatch.
+     */
     public final boolean hasAlpha() {
         return mBitmap.hasAlpha();
     }
 
-    public final Region getTransparentRegion(Rect location) {
-        int r = nativeGetTransparentRegion(mBitmap.ni(), mChunk, location);
+    /**
+     * Returns a {@link Region} representing the parts of the NinePatch that are
+     * completely transparent.
+     *
+     * @param bounds The location and size of the NinePatch.
+     *
+     * @return null if the NinePatch has no transparent region to
+     * report, else a {@link Region} holding the parts of the specified bounds
+     * that are transparent.
+     */
+    public final Region getTransparentRegion(Rect bounds) {
+        int r = nativeGetTransparentRegion(mBitmap.ni(), mNativeChunk, bounds);
         return r != 0 ? new Region(r) : null;
     }
-    
+
+    /**
+     * Verifies that the specified byte array is a valid 9-patch data chunk.
+     *
+     * @param chunk A byte array representing a 9-patch data chunk.
+     *
+     * @return True if the specified byte array represents a 9-patch data chunk,
+     *         false otherwise.
+     */
     public native static boolean isNinePatchChunk(byte[] chunk);
 
-    private static native void validateNinePatchChunk(int bitmap, byte[] chunk);
+    /**
+     * Validates the 9-patch chunk and throws an exception if the chunk is invalid.
+     * If validation is successful, this method returns a native Res_png_9patch*
+     * object used by the renderers.
+     */
+    private static native int validateNinePatchChunk(int bitmap, byte[] chunk);
+    private static native void nativeFinalize(int chunk);
     private static native void nativeDraw(int canvas_instance, RectF loc, int bitmap_instance,
-                                          byte[] c, int paint_instance_or_null,
-                                          int destDensity, int srcDensity);
+            int c, int paint_instance_or_null, int destDensity, int srcDensity);
     private static native void nativeDraw(int canvas_instance, Rect loc, int bitmap_instance,
-                                          byte[] c, int paint_instance_or_null,
-                                          int destDensity, int srcDensity);
-    private static native int nativeGetTransparentRegion(
-            int bitmap, byte[] chunk, Rect location);
+            int c, int paint_instance_or_null, int destDensity, int srcDensity);
+    private static native int nativeGetTransparentRegion(int bitmap, int chunk, Rect location);
 }
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 1485d8d..69d9916 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -105,9 +105,17 @@
     public static final int SUBPIXEL_TEXT_FLAG  = 0x80;
     /** bit mask for the flag enabling device kerning for text */
     public static final int DEV_KERN_TEXT_FLAG  = 0x100;
+    /** @hide bit mask for the flag enabling subpixel glyph rendering for text */
+    public static final int LCD_RENDER_TEXT_FLAG = 0x200;
+    /** bit mask for the flag enabling embedded bitmap strikes for text */
+    public static final int EMBEDDED_BITMAP_TEXT_FLAG = 0x400;
+    /** @hide bit mask for the flag forcing freetype's autohinter on for text */
+    public static final int AUTO_HINTING_TEXT_FLAG = 0x800;
+    /** @hide bit mask for the flag enabling vertical rendering for text */
+    public static final int VERTICAL_TEXT_FLAG = 0x1000;
 
     // we use this when we first create a paint
-    static final int DEFAULT_PAINT_FLAGS = DEV_KERN_TEXT_FLAG;
+    static final int DEFAULT_PAINT_FLAGS = DEV_KERN_TEXT_FLAG | EMBEDDED_BITMAP_TEXT_FLAG;
 
     /**
      * Option for {@link #setHinting}: disable hinting.
@@ -421,7 +429,11 @@
         mMaskFilter = paint.mMaskFilter;
         mPathEffect = paint.mPathEffect;
         mRasterizer = paint.mRasterizer;
-        mShader = paint.mShader;
+        if (paint.mShader != null) {
+            mShader = paint.mShader.copy();
+        } else {
+            mShader = null;
+        }
         mTypeface = paint.mTypeface;
         mXfermode = paint.mXfermode;
 
diff --git a/graphics/java/android/graphics/Path.java b/graphics/java/android/graphics/Path.java
index 157c7d1..ef858eb 100644
--- a/graphics/java/android/graphics/Path.java
+++ b/graphics/java/android/graphics/Path.java
@@ -103,21 +103,106 @@
         }
     }
 
-    /** Enum for the ways a path may be filled
-    */
+    /**
+     * The logical operations that can be performed when combining two paths.
+     *
+     * @see #op(Path, android.graphics.Path.Op)
+     * @see #op(Path, Path, android.graphics.Path.Op)
+     */
+    public enum Op {
+        /**
+         * Subtract the second path from the first path.
+         */
+        DIFFERENCE,
+        /**
+         * Intersect the two paths.
+         */
+        INTERSECT,
+        /**
+         * Union (inclusive-or) the two paths.
+         */
+        UNION,
+        /**
+         * Exclusive-or the two paths.
+         */
+        XOR,
+        /**
+         * Subtract the first path from the second path.
+         */
+        REVERSE_DIFFERENCE
+    }
+
+    /**
+     * Set this path to the result of applying the Op to this path and the specified path.
+     * The resulting path will be constructed from non-overlapping contours.
+     * The curve order is reduced where possible so that cubics may be turned
+     * into quadratics, and quadratics maybe turned into lines.
+     *
+     * @param path The second operand (for difference, the subtrahend)
+     *
+     * @return True if operation succeeded, false otherwise and this path remains unmodified.
+     *
+     * @see Op
+     * @see #op(Path, Path, android.graphics.Path.Op)
+     */
+    public boolean op(Path path, Op op) {
+        return op(this, path, op);
+    }
+
+    /**
+     * Set this path to the result of applying the Op to the two specified paths.
+     * The resulting path will be constructed from non-overlapping contours.
+     * The curve order is reduced where possible so that cubics may be turned
+     * into quadratics, and quadratics maybe turned into lines.
+     *
+     * @param path1 The first operand (for difference, the minuend)
+     * @param path2 The second operand (for difference, the subtrahend)
+     *
+     * @return True if operation succeeded, false otherwise and this path remains unmodified.
+     *
+     * @see Op
+     * @see #op(Path, android.graphics.Path.Op)
+     */
+    public boolean op(Path path1, Path path2, Op op) {
+        if (native_op(path1.mNativePath, path2.mNativePath, op.ordinal(), this.mNativePath)) {
+            isSimplePath = false;
+            rects = null;
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Enum for the ways a path may be filled.
+     */
     public enum FillType {
         // these must match the values in SkPath.h
+        /**
+         * Specifies that "inside" is computed by a non-zero sum of signed
+         * edge crossings.
+         */
         WINDING         (0),
+        /**
+         * Specifies that "inside" is computed by an odd number of edge
+         * crossings.
+         */
         EVEN_ODD        (1),
+        /**
+         * Same as {@link #WINDING}, but draws outside of the path, rather than inside.
+         */
         INVERSE_WINDING (2),
+        /**
+         * Same as {@link #EVEN_ODD}, but draws outside of the path, rather than inside.
+         */
         INVERSE_EVEN_ODD(3);
         
         FillType(int ni) {
             nativeInt = ni;
         }
+
         final int nativeInt;
     }
-    
+
     // these must be in the same order as their native values
     static final FillType[] sFillTypeArray = {
         FillType.WINDING,
@@ -644,24 +729,20 @@
     private static native void native_addRect(int nPath, float left, float top,
                                             float right, float bottom, int dir);
     private static native void native_addOval(int nPath, RectF oval, int dir);
-    private static native void native_addCircle(int nPath, float x, float y,
-                                                float radius, int dir);
+    private static native void native_addCircle(int nPath, float x, float y, float radius, int dir);
     private static native void native_addArc(int nPath, RectF oval,
                                             float startAngle, float sweepAngle);
     private static native void native_addRoundRect(int nPath, RectF rect,
                                                    float rx, float ry, int dir);
-    private static native void native_addRoundRect(int nPath, RectF r,
-                                                   float[] radii, int dir);
-    private static native void native_addPath(int nPath, int src, float dx,
-                                              float dy);
+    private static native void native_addRoundRect(int nPath, RectF r, float[] radii, int dir);
+    private static native void native_addPath(int nPath, int src, float dx, float dy);
     private static native void native_addPath(int nPath, int src);
     private static native void native_addPath(int nPath, int src, int matrix);
-    private static native void native_offset(int nPath, float dx, float dy,
-                                             int dst_path);
+    private static native void native_offset(int nPath, float dx, float dy, int dst_path);
     private static native void native_offset(int nPath, float dx, float dy);
     private static native void native_setLastPoint(int nPath, float dx, float dy);
-    private static native void native_transform(int nPath, int matrix,
-                                                int dst_path);
+    private static native void native_transform(int nPath, int matrix, int dst_path);
     private static native void native_transform(int nPath, int matrix);
+    private static native boolean native_op(int path1, int path2, int op, int result);
     private static native void finalizer(int nPath);
 }
diff --git a/graphics/java/android/graphics/PixelFormat.java b/graphics/java/android/graphics/PixelFormat.java
index f7c202f..d96d6d8 100644
--- a/graphics/java/android/graphics/PixelFormat.java
+++ b/graphics/java/android/graphics/PixelFormat.java
@@ -19,16 +19,16 @@
 public class PixelFormat
 {
     /* these constants need to match those in hardware/hardware.h */
-    
+
     public static final int UNKNOWN     = 0;
 
     /** System chooses a format that supports translucency (many alpha bits) */
     public static final int TRANSLUCENT = -3;
 
-    /** 
+    /**
      * System chooses a format that supports transparency
-     * (at least 1 alpha bit) 
-     */    
+     * (at least 1 alpha bit)
+     */
     public static final int TRANSPARENT = -2;
 
     /** System chooses an opaque format (no alpha bits required) */
@@ -43,7 +43,9 @@
     public static final int RGBA_5551   = 6;
     @Deprecated
     public static final int RGBA_4444   = 7;
+    @Deprecated
     public static final int A_8         = 8;
+    @Deprecated
     public static final int L_8         = 9;
     @Deprecated
     public static final int LA_88       = 0xA;
@@ -52,41 +54,71 @@
 
 
     /**
-     * @deprecated use {@link android.graphics.ImageFormat#NV16 
+     * @deprecated use {@link android.graphics.ImageFormat#NV16
      * ImageFormat.NV16} instead.
      */
     @Deprecated
     public static final int YCbCr_422_SP= 0x10;
 
     /**
-     * @deprecated use {@link android.graphics.ImageFormat#NV21 
+     * @deprecated use {@link android.graphics.ImageFormat#NV21
      * ImageFormat.NV21} instead.
      */
     @Deprecated
     public static final int YCbCr_420_SP= 0x11;
 
     /**
-     * @deprecated use {@link android.graphics.ImageFormat#YUY2 
+     * @deprecated use {@link android.graphics.ImageFormat#YUY2
      * ImageFormat.YUY2} instead.
      */
     @Deprecated
     public static final int YCbCr_422_I = 0x14;
 
     /**
-     * @deprecated use {@link android.graphics.ImageFormat#JPEG 
+     * @deprecated use {@link android.graphics.ImageFormat#JPEG
      * ImageFormat.JPEG} instead.
      */
     @Deprecated
     public static final int JPEG        = 0x100;
 
-    /*
-     * We use a class initializer to allow the native code to cache some
-     * field offsets.
-     */
-    native private static void nativeClassInit();
-    static { nativeClassInit(); }
+    public static void getPixelFormatInfo(int format, PixelFormat info) {
+        switch (format) {
+            case RGBA_8888:
+            case RGBX_8888:
+                info.bitsPerPixel = 32;
+                info.bytesPerPixel = 4;
+                break;
+            case RGB_888:
+                info.bitsPerPixel = 24;
+                info.bytesPerPixel = 3;
+                break;
+            case RGB_565:
+            case RGBA_5551:
+            case RGBA_4444:
+            case LA_88:
+                info.bitsPerPixel = 16;
+                info.bytesPerPixel = 2;
+                break;
+            case A_8:
+            case L_8:
+            case RGB_332:
+                info.bitsPerPixel = 8;
+                info.bytesPerPixel = 1;
+                break;
+            case YCbCr_422_SP:
+            case YCbCr_422_I:
+                info.bitsPerPixel = 16;
+                info.bytesPerPixel = 1;
+                break;
+            case YCbCr_420_SP:
+                info.bitsPerPixel = 12;
+                info.bytesPerPixel = 1;
+                break;
+            default:
+                throw new IllegalArgumentException("unkonwon pixel format " + format);
+        }
+    }
 
-    public static native void getPixelFormatInfo(int format, PixelFormat info);
     public static boolean formatHasAlpha(int format) {
         switch (format) {
             case PixelFormat.A_8:
@@ -100,7 +132,7 @@
         }
         return false;
     }
-    
+
     public int  bytesPerPixel;
     public int  bitsPerPixel;
 }
diff --git a/graphics/java/android/graphics/RadialGradient.java b/graphics/java/android/graphics/RadialGradient.java
index 897762c..f011e5c 100644
--- a/graphics/java/android/graphics/RadialGradient.java
+++ b/graphics/java/android/graphics/RadialGradient.java
@@ -18,6 +18,25 @@
 
 public class RadialGradient extends Shader {
 
+    private static final int TYPE_COLORS_AND_POSITIONS = 1;
+    private static final int TYPE_COLOR_CENTER_AND_COLOR_EDGE = 2;
+
+    /**
+     * Type of the RadialGradient: can be either TYPE_COLORS_AND_POSITIONS or
+     * TYPE_COLOR_CENTER_AND_COLOR_EDGE.
+     */
+    private int mType;
+
+    private float mX;
+    private float mY;
+    private float mRadius;
+    private int[] mColors;
+    private float[] mPositions;
+    private int mColor0;
+    private int mColor1;
+
+    private TileMode mTileMode;
+
 	/**	Create a shader that draws a radial gradient given the center and radius.
         @param x        The x-coordinate of the center of the radius
         @param y        The y-coordinate of the center of the radius
@@ -39,6 +58,13 @@
         if (positions != null && colors.length != positions.length) {
             throw new IllegalArgumentException("color and position arrays must be of equal length");
         }
+        mType = TYPE_COLORS_AND_POSITIONS;
+        mX = x;
+        mY = y;
+        mRadius = radius;
+        mColors = colors;
+        mPositions = positions;
+        mTileMode = tile;
         native_instance = nativeCreate1(x, y, radius, colors, positions, tile.nativeInt);
         native_shader = nativePostCreate1(native_instance, x, y, radius, colors, positions,
                 tile.nativeInt);
@@ -57,12 +83,41 @@
         if (radius <= 0) {
             throw new IllegalArgumentException("radius must be > 0");
         }
+        mType = TYPE_COLOR_CENTER_AND_COLOR_EDGE;
+        mX = x;
+        mY = y;
+        mRadius = radius;
+        mColor0 = color0;
+        mColor1 = color1;
+        mTileMode = tile;
         native_instance = nativeCreate2(x, y, radius, color0, color1, tile.nativeInt);
         native_shader = nativePostCreate2(native_instance, x, y, radius, color0, color1,
                 tile.nativeInt);
     }
 
-	private static native int nativeCreate1(float x, float y, float radius,
+    /**
+     * @hide
+     */
+    @Override
+    protected Shader copy() {
+        final RadialGradient copy;
+        switch (mType) {
+            case TYPE_COLORS_AND_POSITIONS:
+                copy = new RadialGradient(mX, mY, mRadius, mColors.clone(),
+                        mPositions != null ? mPositions.clone() : null, mTileMode);
+                break;
+            case TYPE_COLOR_CENTER_AND_COLOR_EDGE:
+                copy = new RadialGradient(mX, mY, mRadius, mColor0, mColor1, mTileMode);
+                break;
+            default:
+                throw new IllegalArgumentException("RadialGradient should be created with either " +
+                        "colors and positions or center color and edge color");
+        }
+        copyLocalMatrix(copy);
+        return copy;
+    }
+
+    private static native int nativeCreate1(float x, float y, float radius,
             int colors[], float positions[], int tileMode);
 	private static native int nativeCreate2(float x, float y, float radius,
             int color0, int color1, int tileMode);
diff --git a/graphics/java/android/graphics/Shader.java b/graphics/java/android/graphics/Shader.java
index 43758e7..afc68d8 100644
--- a/graphics/java/android/graphics/Shader.java
+++ b/graphics/java/android/graphics/Shader.java
@@ -90,6 +90,28 @@
         }
     }
 
+    /**
+     * @hide
+     */
+    protected Shader copy() {
+        final Shader copy = new Shader();
+        copyLocalMatrix(copy);
+        return copy;
+    }
+
+    /**
+     * @hide
+     */
+    protected void copyLocalMatrix(Shader dest) {
+        if (mLocalMatrix != null) {
+            final Matrix lm = new Matrix();
+            getLocalMatrix(lm);
+            dest.setLocalMatrix(lm);
+        } else {
+            dest.setLocalMatrix(null);
+        }
+    }
+
     private static native void nativeDestructor(int native_shader, int native_skiaShader);
     private static native void nativeSetLocalMatrix(int native_shader,
             int native_skiaShader, int matrix_instance);
diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java
index af1a447..b910a24 100644
--- a/graphics/java/android/graphics/SurfaceTexture.java
+++ b/graphics/java/android/graphics/SurfaceTexture.java
@@ -21,6 +21,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.view.Surface;
 
 /**
  * Captures frames from an image stream as an OpenGL ES texture.
@@ -69,6 +70,7 @@
      * These fields are used by native code, do not access or modify.
      */
     private int mSurfaceTexture;
+    private int mBufferQueue;
     private int mFrameAvailableListener;
 
     /**
@@ -79,8 +81,12 @@
     }
 
     /**
-     * Exception thrown when a surface couldn't be created or resized
+     * Exception thrown when a SurfaceTexture couldn't be created or resized.
+     *
+     * @deprecated No longer thrown. {@link Surface.OutOfResourcesException} is used instead.
      */
+    @SuppressWarnings("serial")
+    @Deprecated
     public static class OutOfResourcesException extends Exception {
         public OutOfResourcesException() {
         }
@@ -93,32 +99,32 @@
      * Construct a new SurfaceTexture to stream images to a given OpenGL texture.
      *
      * @param texName the OpenGL texture object name (e.g. generated via glGenTextures)
+     *
+     * @throws OutOfResourcesException If the SurfaceTexture cannot be created.
      */
     public SurfaceTexture(int texName) {
-        this(texName, false);
+        init(texName, false);
     }
 
     /**
      * Construct a new SurfaceTexture to stream images to a given OpenGL texture.
      *
-     * @param texName the OpenGL texture object name (e.g. generated via glGenTextures)
-     * @param allowSynchronousMode whether the SurfaceTexture can run in the synchronous mode.
-     *      When the image stream comes from OpenGL, SurfaceTexture may run in the synchronous
-     *      mode where the producer side may be blocked to avoid skipping frames. To avoid the
-     *      thread block, set allowSynchronousMode to false.
+     * In single buffered mode the application is responsible for serializing access to the image
+     * content buffer. Each time the image content is to be updated, the
+     * {@link #releaseTexImage()} method must be called before the image content producer takes
+     * ownership of the buffer. For example, when producing image content with the NDK
+     * ANativeWindow_lock and ANativeWindow_unlockAndPost functions, {@link #releaseTexImage()}
+     * must be called before each ANativeWindow_lock, or that call will fail. When producing
+     * image content with OpenGL ES, {@link #releaseTexImage()} must be called before the first
+     * OpenGL ES function call each frame.
      *
-     * @hide
+     * @param texName the OpenGL texture object name (e.g. generated via glGenTextures)
+     * @param singleBufferMode whether the SurfaceTexture will be in single buffered mode.
+     *
+     * @throws throws OutOfResourcesException If the SurfaceTexture cannot be created.
      */
-    public SurfaceTexture(int texName, boolean allowSynchronousMode) {
-        Looper looper;
-        if ((looper = Looper.myLooper()) != null) {
-            mEventHandler = new EventHandler(looper);
-        } else if ((looper = Looper.getMainLooper()) != null) {
-            mEventHandler = new EventHandler(looper);
-        } else {
-            mEventHandler = null;
-        }
-        nativeInit(texName, new WeakReference<SurfaceTexture>(this), allowSynchronousMode);
+    public SurfaceTexture(int texName, boolean singleBufferMode) {
+        init(texName, singleBufferMode);
     }
 
     /**
@@ -143,9 +149,9 @@
      * android.view.Surface#lockCanvas} is called.  For OpenGL ES, the EGLSurface should be
      * destroyed (via eglDestroySurface), made not-current (via eglMakeCurrent), and then recreated
      * (via eglCreateWindowSurface) to ensure that the new default size has taken effect.
-     * 
+     *
      * The width and height parameters must be no greater than the minimum of
-     * GL_MAX_VIEWPORT_DIMS and GL_MAX_TEXTURE_SIZE (see 
+     * GL_MAX_VIEWPORT_DIMS and GL_MAX_TEXTURE_SIZE (see
      * {@link javax.microedition.khronos.opengles.GL10#glGetIntegerv glGetIntegerv}).
      * An error due to invalid dimensions might not be reported until
      * updateTexImage() is called.
@@ -164,6 +170,15 @@
     }
 
     /**
+     * Releases the the texture content. This is needed in single buffered mode to allow the image
+     * content producer to take ownership of the image buffer.
+     * For more information see {@link #SurfaceTexture(int, boolean)}.
+     */
+    public void releaseTexImage() {
+        nativeReleaseTexImage();
+    }
+
+    /**
      * Detach the SurfaceTexture from the OpenGL ES context that owns the OpenGL ES texture object.
      * This call must be made with the OpenGL ES context current on the calling thread.  The OpenGL
      * ES texture object will be deleted as a result of this call.  After calling this method all
@@ -261,6 +276,7 @@
         nativeRelease();
     }
 
+    @Override
     protected void finalize() throws Throwable {
         try {
             nativeFinalize();
@@ -299,12 +315,26 @@
         }
     }
 
-    private native void nativeInit(int texName, Object weakSelf, boolean allowSynchronousMode);
+    private void init(int texName, boolean singleBufferMode) throws Surface.OutOfResourcesException {
+        Looper looper;
+        if ((looper = Looper.myLooper()) != null) {
+            mEventHandler = new EventHandler(looper);
+        } else if ((looper = Looper.getMainLooper()) != null) {
+            mEventHandler = new EventHandler(looper);
+        } else {
+            mEventHandler = null;
+        }
+        nativeInit(texName, singleBufferMode, new WeakReference<SurfaceTexture>(this));
+    }
+
+    private native void nativeInit(int texName, boolean singleBufferMode, Object weakSelf)
+            throws Surface.OutOfResourcesException;
     private native void nativeFinalize();
     private native void nativeGetTransformMatrix(float[] mtx);
     private native long nativeGetTimestamp();
     private native void nativeSetDefaultBufferSize(int width, int height);
     private native void nativeUpdateTexImage();
+    private native void nativeReleaseTexImage();
     private native int nativeDetachFromGLContext();
     private native int nativeAttachToGLContext(int texName);
     private native int nativeGetQueuedCount();
diff --git a/graphics/java/android/graphics/SweepGradient.java b/graphics/java/android/graphics/SweepGradient.java
index 2afdd4d..e9cda39 100644
--- a/graphics/java/android/graphics/SweepGradient.java
+++ b/graphics/java/android/graphics/SweepGradient.java
@@ -18,6 +18,22 @@
 
 public class SweepGradient extends Shader {
 
+    private static final int TYPE_COLORS_AND_POSITIONS = 1;
+    private static final int TYPE_COLOR_START_AND_COLOR_END = 2;
+
+    /**
+     * Type of the LinearGradient: can be either TYPE_COLORS_AND_POSITIONS or
+     * TYPE_COLOR_START_AND_COLOR_END.
+     */
+    private int mType;
+
+    private float mCx;
+    private float mCy;
+    private int[] mColors;
+    private float[] mPositions;
+    private int mColor0;
+    private int mColor1;
+
     /**
      * A subclass of Shader that draws a sweep gradient around a center point.
      *
@@ -41,6 +57,11 @@
             throw new IllegalArgumentException(
                         "color and position arrays must be of equal length");
         }
+        mType = TYPE_COLORS_AND_POSITIONS;
+        mCx = cx;
+        mCy = cy;
+        mColors = colors;
+        mPositions = positions;
         native_instance = nativeCreate1(cx, cy, colors, positions);
         native_shader = nativePostCreate1(native_instance, cx, cy, colors, positions);
     }
@@ -54,10 +75,37 @@
      * @param color1   The color to use at the end of the sweep
      */
     public SweepGradient(float cx, float cy, int color0, int color1) {
+        mType = TYPE_COLOR_START_AND_COLOR_END;
+        mCx = cx;
+        mCy = cy;
+        mColor0 = color0;
+        mColor1 = color1;
         native_instance = nativeCreate2(cx, cy, color0, color1);
         native_shader = nativePostCreate2(native_instance, cx, cy, color0, color1);
     }
 
+    /**
+     * @hide
+     */
+    @Override
+    protected Shader copy() {
+        final SweepGradient copy;
+        switch (mType) {
+            case TYPE_COLORS_AND_POSITIONS:
+                copy = new SweepGradient(mCx, mCy, mColors.clone(),
+                        mPositions != null ? mPositions.clone() : null);
+                break;
+            case TYPE_COLOR_START_AND_COLOR_END:
+                copy = new SweepGradient(mCx, mCy, mColor0, mColor1);
+                break;
+            default:
+                throw new IllegalArgumentException("SweepGradient should be created with either " +
+                        "colors and positions or start color and end color");
+        }
+        copyLocalMatrix(copy);
+        return copy;
+    }
+
     private static native int nativeCreate1(float x, float y, int colors[], float positions[]);
     private static native int nativeCreate2(float x, float y, int color0, int color1);
 
diff --git a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
index f0e9723..9accbbc 100644
--- a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
@@ -153,6 +153,11 @@
     }
 
     @Override
+    public int getAlpha() {
+        return mState.mDrawable.getAlpha();
+    }
+
+    @Override
     public void setColorFilter(ColorFilter cf) {
         mState.mDrawable.setColorFilter(cf);
     }
diff --git a/graphics/java/android/graphics/drawable/AnimationDrawable.java b/graphics/java/android/graphics/drawable/AnimationDrawable.java
index 7c7cd01..bde978d 100644
--- a/graphics/java/android/graphics/drawable/AnimationDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimationDrawable.java
@@ -167,7 +167,7 @@
      * @return The Drawable at the specified frame index
      */
     public Drawable getFrame(int index) {
-        return mAnimationState.getChildren()[index];
+        return mAnimationState.getChild(index);
     }
     
     /**
@@ -322,7 +322,7 @@
                 mDurations = orig.mDurations;
                 mOneShot = orig.mOneShot;
             } else {
-                mDurations = new int[getChildren().length];
+                mDurations = new int[getCapacity()];
                 mOneShot = true;
             }
         }
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index a97ed2c..5ceab36 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -23,12 +23,14 @@
 import android.graphics.BitmapShader;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
+import android.graphics.Matrix;
 import android.graphics.Paint;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.graphics.Shader;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
+import android.util.LayoutDirection;
 import android.view.Gravity;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -72,7 +74,10 @@
      // These are scaled to match the target density.
     private int mBitmapWidth;
     private int mBitmapHeight;
-    
+
+    // Mirroring matrix for using with Shaders
+    private Matrix mMirrorMatrix;
+
     /**
      * Create an empty drawable, not dealing with density.
      * @deprecated Use {@link #BitmapDrawable(android.content.res.Resources, android.graphics.Bitmap)}
@@ -399,14 +404,51 @@
     }
 
     @Override
+    public void setAutoMirrored(boolean mirrored) {
+        if (mBitmapState.mAutoMirrored != mirrored) {
+            mBitmapState.mAutoMirrored = mirrored;
+            invalidateSelf();
+        }
+    }
+
+    @Override
+    public final boolean isAutoMirrored() {
+        return mBitmapState.mAutoMirrored;
+    }
+
+    @Override
     public int getChangingConfigurations() {
         return super.getChangingConfigurations() | mBitmapState.mChangingConfigurations;
     }
-    
+
+    private boolean needMirroring() {
+        return isAutoMirrored() && getLayoutDirection() == LayoutDirection.RTL;
+    }
+
+    private void updateMirrorMatrix(float dx) {
+        if (mMirrorMatrix == null) {
+            mMirrorMatrix = new Matrix();
+        }
+        mMirrorMatrix.setTranslate(dx, 0);
+        mMirrorMatrix.preScale(-1.0f, 1.0f);
+    }
+
     @Override
     protected void onBoundsChange(Rect bounds) {
         super.onBoundsChange(bounds);
         mApplyGravity = true;
+        Shader shader = mBitmapState.mPaint.getShader();
+        if (shader != null) {
+            if (needMirroring()) {
+                updateMirrorMatrix(bounds.right - bounds.left);
+                shader.setLocalMatrix(mMirrorMatrix);
+            } else {
+                if (mMirrorMatrix != null) {
+                    mMirrorMatrix = null;
+                    shader.setLocalMatrix(Matrix.IDENTITY_MATRIX);
+                }
+            }
+        }
     }
 
     @Override
@@ -430,6 +472,7 @@
             }
 
             Shader shader = state.mPaint.getShader();
+            final boolean needMirroring = needMirroring();
             if (shader == null) {
                 if (mApplyGravity) {
                     final int layoutDirection = getLayoutDirection();
@@ -437,12 +480,31 @@
                             getBounds(), mDstRect, layoutDirection);
                     mApplyGravity = false;
                 }
+                if (needMirroring) {
+                    canvas.save();
+                    // Mirror the bitmap
+                    canvas.translate(mDstRect.right - mDstRect.left, 0);
+                    canvas.scale(-1.0f, 1.0f);
+                }
                 canvas.drawBitmap(bitmap, null, mDstRect, state.mPaint);
+                if (needMirroring) {
+                    canvas.restore();
+                }
             } else {
                 if (mApplyGravity) {
                     copyBounds(mDstRect);
                     mApplyGravity = false;
                 }
+                if (needMirroring) {
+                    // Mirror the bitmap
+                    updateMirrorMatrix(mDstRect.right - mDstRect.left);
+                    shader.setLocalMatrix(mMirrorMatrix);
+                } else {
+                    if (mMirrorMatrix != null) {
+                        mMirrorMatrix = null;
+                        shader.setLocalMatrix(Matrix.IDENTITY_MATRIX);
+                    }
+                }
                 canvas.drawRect(mDstRect, state.mPaint);
             }
         }
@@ -458,6 +520,11 @@
     }
 
     @Override
+    public int getAlpha() {
+        return mBitmapState.mPaint.getAlpha();
+    }
+
+    @Override
     public void setColorFilter(ColorFilter cf) {
         mBitmapState.mPaint.setColorFilter(cf);
         invalidateSelf();
@@ -500,6 +567,8 @@
         setTargetDensity(r.getDisplayMetrics());
         setMipMap(a.getBoolean(com.android.internal.R.styleable.BitmapDrawable_mipMap,
                 bitmap.hasMipMap()));
+        setAutoMirrored(a.getBoolean(com.android.internal.R.styleable.BitmapDrawable_autoMirrored,
+                false));
 
         final Paint paint = mBitmapState.mPaint;
         paint.setAntiAlias(a.getBoolean(com.android.internal.R.styleable.BitmapDrawable_antialias,
@@ -562,6 +631,7 @@
         Shader.TileMode mTileModeY = null;
         int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
         boolean mRebuildShader;
+        boolean mAutoMirrored;
 
         BitmapState(Bitmap bitmap) {
             mBitmap = bitmap;
@@ -576,6 +646,12 @@
             mTargetDensity = bitmapState.mTargetDensity;
             mPaint = new Paint(bitmapState.mPaint);
             mRebuildShader = bitmapState.mRebuildShader;
+            mAutoMirrored = bitmapState.mAutoMirrored;
+        }
+
+        @Override
+        public Bitmap getBitmap() {
+            return mBitmap;
         }
 
         @Override
diff --git a/graphics/java/android/graphics/drawable/ClipDrawable.java b/graphics/java/android/graphics/drawable/ClipDrawable.java
index eb9f046..2a9a14b 100644
--- a/graphics/java/android/graphics/drawable/ClipDrawable.java
+++ b/graphics/java/android/graphics/drawable/ClipDrawable.java
@@ -158,6 +158,11 @@
     }
 
     @Override
+    public int getAlpha() {
+        return mClipState.mDrawable.getAlpha();
+    }
+
+    @Override
     public void setColorFilter(ColorFilter cf) {
         mClipState.mDrawable.setColorFilter(cf);
     }
diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java
index d11e554..61dd675 100644
--- a/graphics/java/android/graphics/drawable/ColorDrawable.java
+++ b/graphics/java/android/graphics/drawable/ColorDrawable.java
@@ -116,6 +116,7 @@
      *
      * @return A value between 0 and 255.
      */
+    @Override
     public int getAlpha() {
         return mState.mUseColor >>> 24;
     }
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index d5183d5..8135716 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -411,6 +411,17 @@
     public abstract void setAlpha(int alpha);
 
     /**
+     * Gets the current alpha value for the drawable. 0 means fully transparent,
+     * 255 means fully opaque. This method is implemented by
+     * Drawable subclasses and the value returned is specific to how that class treats alpha.
+     * The default return value is 255 if the class does not override this method to return a value
+     * specific to its use of alpha.
+     */
+    public int getAlpha() {
+        return 0xFF;
+    }
+
+    /**
      * Specify an optional colorFilter for the drawable. Pass null to remove
      * any filters.
     */
@@ -561,6 +572,25 @@
     }
 
     /**
+     * Set whether this Drawable is automatically mirrored when its layout direction is RTL
+     * (right-to left). See {@link android.util.LayoutDirection}.
+     *
+     * @param mirrored Set to true if the Drawable should be mirrored, false if not.
+     */
+    public void setAutoMirrored(boolean mirrored) {
+    }
+
+    /**
+     * Tells if this Drawable will be automatically mirrored  when its layout direction is RTL
+     * right-to-left. See {@link android.util.LayoutDirection}.
+     *
+     * @return boolean Returns true if this Drawable will be automatically mirrored.
+     */
+    public boolean isAutoMirrored() {
+        return false;
+    }
+
+    /**
      * Return the opacity/transparency of this Drawable.  The returned value is
      * one of the abstract format constants in
      * {@link android.graphics.PixelFormat}:
@@ -858,10 +888,6 @@
             drawable = new StateListDrawable();
         } else if (name.equals("level-list")) {
             drawable = new LevelListDrawable();
-        /* Probably not doing this.
-        } else if (name.equals("mipmap")) {
-            drawable = new MipmapDrawable();
-        */
         } else if (name.equals("layer-list")) {
             drawable = new LayerDrawable();
         } else if (name.equals("transition")) {
@@ -985,6 +1011,13 @@
          * this drawable (and thus require completely reloading it).
          */
         public abstract int getChangingConfigurations();
+
+        /**
+         * @hide
+         */
+        public Bitmap getBitmap() {
+            return null;
+        }
     }
 
     /**
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index 0f84e86..e350e8d 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -23,6 +23,7 @@
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.os.SystemClock;
+import android.util.SparseArray;
 
 /**
  * A helper class that contains several {@link Drawable}s and selects which one to use.
@@ -76,7 +77,7 @@
                 | mDrawableContainerState.mChangingConfigurations
                 | mDrawableContainerState.mChildrenChangingConfigurations;
     }
-    
+
     @Override
     public boolean getPadding(Rect padding) {
         final Rect r = mDrawableContainerState.getConstantPadding();
@@ -114,6 +115,11 @@
     }
 
     @Override
+    public int getAlpha() {
+        return mAlpha;
+    }
+
+    @Override
     public void setDither(boolean dither) {
         if (mDrawableContainerState.mDither != dither) {
             mDrawableContainerState.mDither = dither;
@@ -132,7 +138,7 @@
             }
         }
     }
-    
+
     /**
      * Change the global fade duration when a new drawable is entering
      * the scene.
@@ -141,7 +147,7 @@
     public void setEnterFadeDuration(int ms) {
         mDrawableContainerState.mEnterFadeDuration = ms;
     }
-    
+
     /**
      * Change the global fade duration when a new drawable is leaving
      * the scene.
@@ -150,7 +156,7 @@
     public void setExitFadeDuration(int ms) {
         mDrawableContainerState.mExitFadeDuration = ms;
     }
-    
+
     @Override
     protected void onBoundsChange(Rect bounds) {
         if (mLastDrawable != null) {
@@ -160,12 +166,25 @@
             mCurrDrawable.setBounds(bounds);
         }
     }
-    
+
     @Override
     public boolean isStateful() {
         return mDrawableContainerState.isStateful();
     }
-    
+
+    @Override
+    public void setAutoMirrored(boolean mirrored) {
+        mDrawableContainerState.mAutoMirrored = mirrored;
+        if (mCurrDrawable != null) {
+            mCurrDrawable.mutate().setAutoMirrored(mDrawableContainerState.mAutoMirrored);
+        }
+    }
+
+    @Override
+    public boolean isAutoMirrored() {
+        return mDrawableContainerState.mAutoMirrored;
+    }
+
     @Override
     public void jumpToCurrentState() {
         boolean changed = false;
@@ -228,7 +247,7 @@
         }
         return mCurrDrawable != null ? mCurrDrawable.getIntrinsicHeight() : -1;
     }
-    
+
     @Override
     public int getMinimumWidth() {
         if (mDrawableContainerState.isConstantSize()) {
@@ -245,18 +264,21 @@
         return mCurrDrawable != null ? mCurrDrawable.getMinimumHeight() : 0;
     }
 
+    @Override
     public void invalidateDrawable(Drawable who) {
         if (who == mCurrDrawable && getCallback() != null) {
             getCallback().invalidateDrawable(this);
         }
     }
 
+    @Override
     public void scheduleDrawable(Drawable who, Runnable what, long when) {
         if (who == mCurrDrawable && getCallback() != null) {
             getCallback().scheduleDrawable(this, what, when);
         }
     }
 
+    @Override
     public void unscheduleDrawable(Drawable who, Runnable what) {
         if (who == mCurrDrawable && getCallback() != null) {
             getCallback().unscheduleDrawable(this, what);
@@ -308,7 +330,7 @@
         }
 
         if (idx >= 0 && idx < mDrawableContainerState.mNumChildren) {
-            Drawable d = mDrawableContainerState.mDrawables[idx];
+            final Drawable d = mDrawableContainerState.getChild(idx);
             mCurrDrawable = d;
             mCurIndex = idx;
             if (d != null) {
@@ -325,6 +347,7 @@
                 d.setLevel(getLevel());
                 d.setBounds(getBounds());
                 d.setLayoutDirection(getLayoutDirection());
+                d.setAutoMirrored(mDrawableContainerState.mAutoMirrored);
             }
         } else {
             mCurrDrawable = null;
@@ -350,7 +373,7 @@
 
         return true;
     }
-    
+
     void animate(boolean schedule) {
         final long now = SystemClock.uptimeMillis();
         boolean animating = false;
@@ -410,11 +433,7 @@
     @Override
     public Drawable mutate() {
         if (!mMutated && super.mutate() == this) {
-            final int N = mDrawableContainerState.getChildCount();
-            final Drawable[] drawables = mDrawableContainerState.getChildren();
-            for (int i = 0; i < N; i++) {
-                if (drawables[i] != null) drawables[i].mutate();
-            }
+            mDrawableContainerState.mutate();
             mMutated = true;
         }
         return this;
@@ -428,90 +447,108 @@
      */
     public abstract static class DrawableContainerState extends ConstantState {
         final DrawableContainer mOwner;
+        final Resources mRes;
 
-        int         mChangingConfigurations;
-        int         mChildrenChangingConfigurations;
-        
-        Drawable[]  mDrawables;
-        int         mNumChildren;
+        SparseArray<ConstantStateFuture> mDrawableFutures;
 
-        boolean     mVariablePadding = false;
-        Rect        mConstantPadding = null;
+        int mChangingConfigurations;
+        int mChildrenChangingConfigurations;
 
-        boolean     mConstantSize = false;
-        boolean     mComputedConstantSize = false;
-        int         mConstantWidth;
-        int         mConstantHeight;
-        int         mConstantMinimumWidth;
-        int         mConstantMinimumHeight;
+        Drawable[] mDrawables;
+        int mNumChildren;
 
-        int         mOpacity;
+        boolean mVariablePadding;
+        boolean mPaddingChecked;
+        Rect mConstantPadding;
 
-        boolean     mHaveStateful = false;
-        boolean     mStateful;
+        boolean mConstantSize;
+        boolean mComputedConstantSize;
+        int mConstantWidth;
+        int mConstantHeight;
+        int mConstantMinimumWidth;
+        int mConstantMinimumHeight;
 
-        boolean     mCheckedConstantState;
-        boolean     mCanConstantState;
+        boolean mCheckedOpacity;
+        int mOpacity;
 
-        boolean     mPaddingChecked = false;
-        
-        boolean     mDither = DEFAULT_DITHER;        
+        boolean mCheckedStateful;
+        boolean mStateful;
 
-        int         mEnterFadeDuration;
-        int         mExitFadeDuration;
+        boolean mCheckedConstantState;
+        boolean mCanConstantState;
+
+        boolean mDither = DEFAULT_DITHER;
+
+        boolean mMutated;
+        int mLayoutDirection;
+
+        int mEnterFadeDuration;
+        int mExitFadeDuration;
+
+        boolean mAutoMirrored;
 
         DrawableContainerState(DrawableContainerState orig, DrawableContainer owner,
                 Resources res) {
             mOwner = owner;
+            mRes = res;
 
             if (orig != null) {
                 mChangingConfigurations = orig.mChangingConfigurations;
                 mChildrenChangingConfigurations = orig.mChildrenChangingConfigurations;
-                
-                final Drawable[] origDr = orig.mDrawables;
 
+                mCheckedConstantState = true;
+                mCanConstantState = true;
+
+                mVariablePadding = orig.mVariablePadding;
+                mConstantSize = orig.mConstantSize;
+                mDither = orig.mDither;
+                mMutated = orig.mMutated;
+                mLayoutDirection = orig.mLayoutDirection;
+                mEnterFadeDuration = orig.mEnterFadeDuration;
+                mExitFadeDuration = orig.mExitFadeDuration;
+                mAutoMirrored = orig.mAutoMirrored;
+
+                // Cloning the following values may require creating futures.
+                mConstantPadding = orig.getConstantPadding();
+                mPaddingChecked = true;
+
+                mConstantWidth = orig.getConstantWidth();
+                mConstantHeight = orig.getConstantHeight();
+                mConstantMinimumWidth = orig.getConstantMinimumWidth();
+                mConstantMinimumHeight = orig.getConstantMinimumHeight();
+                mComputedConstantSize = true;
+
+                mOpacity = orig.getOpacity();
+                mCheckedOpacity = true;
+
+                mStateful = orig.isStateful();
+                mCheckedStateful = true;
+
+                // Postpone cloning children and futures until we're absolutely
+                // sure that we're done computing values for the original state.
+                final Drawable[] origDr = orig.mDrawables;
                 mDrawables = new Drawable[origDr.length];
                 mNumChildren = orig.mNumChildren;
 
+                final SparseArray<ConstantStateFuture> origDf = orig.mDrawableFutures;
+                if (origDf != null) {
+                    mDrawableFutures = origDf.clone();
+                } else {
+                    mDrawableFutures = new SparseArray<ConstantStateFuture>(mNumChildren);
+                }
+
                 final int N = mNumChildren;
-                for (int i=0; i<N; i++) {
-                    if (res != null) {
-                        mDrawables[i] = origDr[i].getConstantState().newDrawable(res);
-                    } else {
-                        mDrawables[i] = origDr[i].getConstantState().newDrawable();
+                for (int i = 0; i < N; i++) {
+                    if (origDr[i] != null) {
+                        mDrawableFutures.put(i, new ConstantStateFuture(origDr[i]));
                     }
-                    mDrawables[i].setCallback(owner);
-                    mDrawables[i].setLayoutDirection(origDr[i].getLayoutDirection());
                 }
-
-                mCheckedConstantState = mCanConstantState = true;
-                mVariablePadding = orig.mVariablePadding;
-                if (orig.mConstantPadding != null) {
-                    mConstantPadding = new Rect(orig.mConstantPadding);
-                }
-                mConstantSize = orig.mConstantSize;
-                mComputedConstantSize = orig.mComputedConstantSize;
-                mConstantWidth = orig.mConstantWidth;
-                mConstantHeight = orig.mConstantHeight;
-                mConstantMinimumWidth = orig.mConstantMinimumWidth;
-                mConstantMinimumHeight = orig.mConstantMinimumHeight;
-                
-                mOpacity = orig.mOpacity;
-                mHaveStateful = orig.mHaveStateful;
-                mStateful = orig.mStateful;
-                
-                mDither = orig.mDither;
-
-                mEnterFadeDuration = orig.mEnterFadeDuration;
-                mExitFadeDuration = orig.mExitFadeDuration;
-
             } else {
                 mDrawables = new Drawable[10];
                 mNumChildren = 0;
-                mCheckedConstantState = mCanConstantState = false;
             }
         }
-        
+
         @Override
         public int getChangingConfigurations() {
             return mChangingConfigurations | mChildrenChangingConfigurations;
@@ -530,7 +567,8 @@
             mDrawables[pos] = dr;
             mNumChildren++;
             mChildrenChangingConfigurations |= dr.getChangingConfigurations();
-            mHaveStateful = false;
+            mCheckedStateful = false;
+            mCheckedOpacity = false;
 
             mConstantPadding = null;
             mPaddingChecked = false;
@@ -539,18 +577,89 @@
             return pos;
         }
 
+        final int getCapacity() {
+            return mDrawables.length;
+        }
+
+        private final void createAllFutures() {
+            if (mDrawableFutures != null) {
+                final int futureCount = mDrawableFutures.size();
+                for (int keyIndex = 0; keyIndex < futureCount; keyIndex++) {
+                    final int index = mDrawableFutures.keyAt(keyIndex);
+                    mDrawables[index] = mDrawableFutures.valueAt(keyIndex).get(this);
+                }
+
+                mDrawableFutures = null;
+            }
+        }
+
         public final int getChildCount() {
             return mNumChildren;
         }
 
+        /*
+         * @deprecated Use {@link #getChild} instead.
+         */
         public final Drawable[] getChildren() {
+            // Create all futures for backwards compatibility.
+            createAllFutures();
+
             return mDrawables;
         }
 
-        /** A boolean value indicating whether to use the maximum padding value of 
-          * all frames in the set (false), or to use the padding value of the frame 
-          * being shown (true). Default value is false. 
-          */
+        public final Drawable getChild(int index) {
+            final Drawable result = mDrawables[index];
+            if (result != null) {
+                return result;
+            }
+
+            // Prepare future drawable if necessary.
+            if (mDrawableFutures != null) {
+                final int keyIndex = mDrawableFutures.indexOfKey(index);
+                if (keyIndex >= 0) {
+                    final Drawable prepared = mDrawableFutures.valueAt(keyIndex).get(this);
+                    mDrawables[index] = prepared;
+                    mDrawableFutures.removeAt(keyIndex);
+                    return prepared;
+                }
+            }
+
+            return null;
+        }
+
+        final void setLayoutDirection(int layoutDirection) {
+            // No need to call createAllFutures, since future drawables will
+            // change layout direction when they are prepared.
+            final int N = mNumChildren;
+            final Drawable[] drawables = mDrawables;
+            for (int i = 0; i < N; i++) {
+                if (drawables[i] != null) {
+                    drawables[i].setLayoutDirection(layoutDirection);
+                }
+            }
+
+            mLayoutDirection = layoutDirection;
+        }
+
+        final void mutate() {
+            // No need to call createAllFutures, since future drawables will
+            // mutate when they are prepared.
+            final int N = mNumChildren;
+            final Drawable[] drawables = mDrawables;
+            for (int i = 0; i < N; i++) {
+                if (drawables[i] != null) {
+                    drawables[i].mutate();
+                }
+            }
+
+            mMutated = true;
+        }
+
+        /**
+         * A boolean value indicating whether to use the maximum padding value
+         * of all frames in the set (false), or to use the padding value of the
+         * frame being shown (true). Default value is false.
+         */
         public final void setVariablePadding(boolean variable) {
             mVariablePadding = variable;
         }
@@ -559,13 +668,16 @@
             if (mVariablePadding) {
                 return null;
             }
-            if (mConstantPadding != null || mPaddingChecked) {
+
+            if ((mConstantPadding != null) || mPaddingChecked) {
                 return mConstantPadding;
             }
 
+            createAllFutures();
+
             Rect r = null;
             final Rect t = new Rect();
-            final int N = getChildCount();
+            final int N = mNumChildren;
             final Drawable[] drawables = mDrawables;
             for (int i = 0; i < N; i++) {
                 if (drawables[i].getPadding(t)) {
@@ -576,6 +688,7 @@
                     if (t.bottom > r.bottom) r.bottom = t.bottom;
                 }
             }
+
             mPaddingChecked = true;
             return (mConstantPadding = r);
         }
@@ -623,12 +736,14 @@
         protected void computeConstantSize() {
             mComputedConstantSize = true;
 
-            final int N = getChildCount();
+            createAllFutures();
+
+            final int N = mNumChildren;
             final Drawable[] drawables = mDrawables;
             mConstantWidth = mConstantHeight = -1;
             mConstantMinimumWidth = mConstantMinimumHeight = 0;
             for (int i = 0; i < N; i++) {
-                Drawable dr = drawables[i];
+                final Drawable dr = drawables[i];
                 int s = dr.getIntrinsicWidth();
                 if (s > mConstantWidth) mConstantWidth = s;
                 s = dr.getIntrinsicHeight();
@@ -657,33 +772,45 @@
         }
 
         public final int getOpacity() {
-            final int N = getChildCount();
+            if (mCheckedOpacity) {
+                return mOpacity;
+            }
+
+            createAllFutures();
+
+            mCheckedOpacity = true;
+
+            final int N = mNumChildren;
             final Drawable[] drawables = mDrawables;
-            int op = N > 0 ? drawables[0].getOpacity() : PixelFormat.TRANSPARENT;
+            int op = (N > 0) ? drawables[0].getOpacity() : PixelFormat.TRANSPARENT;
             for (int i = 1; i < N; i++) {
                 op = Drawable.resolveOpacity(op, drawables[i].getOpacity());
             }
+
             mOpacity = op;
             return op;
         }
 
         public final boolean isStateful() {
-            if (mHaveStateful) {
+            if (mCheckedStateful) {
                 return mStateful;
             }
-            
-            boolean stateful = false;
-            final int N = getChildCount();
+
+            createAllFutures();
+
+            mCheckedStateful = true;
+
+            final int N = mNumChildren;
+            final Drawable[] drawables = mDrawables;
             for (int i = 0; i < N; i++) {
-                if (mDrawables[i].isStateful()) {
-                    stateful = true;
-                    break;
+                if (drawables[i].isStateful()) {
+                    mStateful = true;
+                    return true;
                 }
             }
-            
-            mStateful = stateful;
-            mHaveStateful = true;
-            return stateful;
+
+            mStateful = false;
+            return false;
         }
 
         public void growArray(int oldSize, int newSize) {
@@ -693,24 +820,60 @@
         }
 
         public synchronized boolean canConstantState() {
-            if (!mCheckedConstantState) {
-                mCanConstantState = true;
-                final int N = mNumChildren;
-                for (int i=0; i<N; i++) {
-                    if (mDrawables[i].getConstantState() == null) {
-                        mCanConstantState = false;
-                        break;
-                    }
-                }
-                mCheckedConstantState = true;
+            if (mCheckedConstantState) {
+                return mCanConstantState;
             }
 
-            return mCanConstantState;
+            createAllFutures();
+
+            mCheckedConstantState = true;
+
+            final int N = mNumChildren;
+            final Drawable[] drawables = mDrawables;
+            for (int i = 0; i < N; i++) {
+                if (drawables[i].getConstantState() == null) {
+                    mCanConstantState = false;
+                    return false;
+                }
+            }
+
+            mCanConstantState = true;
+            return true;
+        }
+
+        /**
+         * Class capable of cloning a Drawable from another Drawable's
+         * ConstantState.
+         */
+        private static class ConstantStateFuture {
+            private final ConstantState mConstantState;
+
+            private ConstantStateFuture(Drawable source) {
+                mConstantState = source.getConstantState();
+            }
+
+            /**
+             * Obtains and prepares the Drawable represented by this future.
+             *
+             * @param state the container into which this future will be placed
+             * @return a prepared Drawable
+             */
+            public Drawable get(DrawableContainerState state) {
+                final Drawable result = (state.mRes == null) ?
+                        mConstantState.newDrawable() : mConstantState.newDrawable(state.mRes);
+                result.setLayoutDirection(state.mLayoutDirection);
+                result.setCallback(state.mOwner);
+
+                if (state.mMutated) {
+                    result.mutate();
+                }
+
+                return result;
+            }
         }
     }
 
-    protected void setConstantState(DrawableContainerState state)
-    {
+    protected void setConstantState(DrawableContainerState state) {
         mDrawableContainerState = state;
     }
 }
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index b966bb4..b340777 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -19,6 +19,7 @@
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
+import android.graphics.Color;
 import android.graphics.ColorFilter;
 import android.graphics.DashPathEffect;
 import android.graphics.LinearGradient;
@@ -639,6 +640,11 @@
     }
 
     @Override
+    public int getAlpha() {
+        return mAlpha;
+    }
+
+    @Override
     public void setDither(boolean dither) {
         if (dither != mDither) {
             mDither = dither;
@@ -742,9 +748,6 @@
 
                     mFillPaint.setShader(new LinearGradient(x0, y0, x1, y1,
                             colors, st.mPositions, Shader.TileMode.CLAMP));
-                    if (!mGradientState.mHasSolidColor) {
-                        mFillPaint.setColor(mAlpha << 24);
-                    }
                 } else if (st.mGradient == RADIAL_GRADIENT) {
                     x0 = r.left + (r.right - r.left) * st.mCenterX;
                     y0 = r.top + (r.bottom - r.top) * st.mCenterY;
@@ -754,9 +757,6 @@
                     mFillPaint.setShader(new RadialGradient(x0, y0,
                             level * st.mGradientRadius, colors, null,
                             Shader.TileMode.CLAMP));
-                    if (!mGradientState.mHasSolidColor) {
-                        mFillPaint.setColor(mAlpha << 24);
-                    }
                 } else if (st.mGradient == SWEEP_GRADIENT) {
                     x0 = r.left + (r.right - r.left) * st.mCenterX;
                     y0 = r.top + (r.bottom - r.top) * st.mCenterY;
@@ -787,9 +787,12 @@
 
                     }
                     mFillPaint.setShader(new SweepGradient(x0, y0, tempColors, tempPositions));
-                    if (!mGradientState.mHasSolidColor) {
-                        mFillPaint.setColor(mAlpha << 24);
-                    }
+                }
+
+                // If we don't have a solid color, the alpha channel must be
+                // maxed out so that alpha modulation works correctly.
+                if (!st.mHasSolidColor) {
+                    mFillPaint.setColor(Color.BLACK);
                 }
             }
         }
@@ -1276,6 +1279,9 @@
             // the app is stroking the shape, set the color to the default
             // value of state.mSolidColor
             mFillPaint.setColor(0);
+        } else {
+            // Otherwise, make sure the fill alpha is maxed out.
+            mFillPaint.setColor(Color.BLACK);
         }
         mPadding = state.mPadding;
         if (state.mStrokeWidth >= 0) {
diff --git a/graphics/java/android/graphics/drawable/InsetDrawable.java b/graphics/java/android/graphics/drawable/InsetDrawable.java
index 2576f42e..e3a7e2b 100644
--- a/graphics/java/android/graphics/drawable/InsetDrawable.java
+++ b/graphics/java/android/graphics/drawable/InsetDrawable.java
@@ -192,7 +192,12 @@
     public void setAlpha(int alpha) {
         mInsetState.mDrawable.setAlpha(alpha);
     }
-    
+
+    @Override
+    public int getAlpha() {
+        return mInsetState.mDrawable.getAlpha();
+    }
+
     @Override
     public void setColorFilter(ColorFilter cf) {
         mInsetState.mDrawable.setColorFilter(cf);
@@ -256,6 +261,13 @@
         return this;
     }
 
+    /**
+     * Returns the drawable wrapped by this InsetDrawable. May be null.
+     */
+    public Drawable getDrawable() {
+        return mInsetState.mDrawable;
+    }
+
     final static class InsetState extends ConstantState {
         Drawable mDrawable;
         int mChangingConfigurations;
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index 6b59dba..81cc11b 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -119,6 +119,9 @@
         mOpacityOverride = a.getInt(com.android.internal.R.styleable.LayerDrawable_opacity,
                 PixelFormat.UNKNOWN);
 
+        setAutoMirrored(a.getBoolean(com.android.internal.R.styleable.LayerDrawable_autoMirrored,
+                false));
+
         a.recycle();
 
         final int innerDepth = parser.getDepth() + 1;
@@ -200,6 +203,7 @@
         st.mChildren[i] = childDrawable;
         childDrawable.mId = id;
         childDrawable.mDrawable = layer;
+        childDrawable.mDrawable.setAutoMirrored(isAutoMirrored());
         childDrawable.mInsetL = left;
         childDrawable.mInsetT = top;
         childDrawable.mInsetR = right;
@@ -402,7 +406,18 @@
             array[i].mDrawable.setAlpha(alpha);
         }
     }
-    
+
+    @Override
+    public int getAlpha() {
+        final ChildDrawable[] array = mLayerState.mChildren;
+        if (mLayerState.mNum > 0) {
+            // All layers should have the same alpha set on them - just return the first one
+            return array[0].mDrawable.getAlpha();
+        } else {
+            return super.getAlpha();
+        }
+    }
+
     @Override
     public void setColorFilter(ColorFilter cf) {
         final ChildDrawable[] array = mLayerState.mChildren;
@@ -437,6 +452,21 @@
     }
 
     @Override
+    public void setAutoMirrored(boolean mirrored) {
+        mLayerState.mAutoMirrored = mirrored;
+        final ChildDrawable[] array = mLayerState.mChildren;
+        final int N = mLayerState.mNum;
+        for (int i=0; i<N; i++) {
+            array[i].mDrawable.setAutoMirrored(mirrored);
+        }
+    }
+
+    @Override
+    public boolean isAutoMirrored() {
+        return mLayerState.mAutoMirrored;
+    }
+
+    @Override
     public boolean isStateful() {
         return mLayerState.isStateful();
     }
@@ -619,6 +649,8 @@
         private boolean mCheckedConstantState;
         private boolean mCanConstantState;
 
+        private boolean mAutoMirrored;
+
         LayerState(LayerState orig, LayerDrawable owner, Resources res) {
             if (orig != null) {
                 final ChildDrawable[] origChildDrawable = orig.mChildren;
@@ -652,6 +684,7 @@
                 mHaveStateful = orig.mHaveStateful;
                 mStateful = orig.mStateful;
                 mCheckedConstantState = mCanConstantState = true;
+                mAutoMirrored = orig.mAutoMirrored;
             } else {
                 mNum = 0;
                 mChildren = null;
diff --git a/graphics/java/android/graphics/drawable/LevelListDrawable.java b/graphics/java/android/graphics/drawable/LevelListDrawable.java
index 21be983..872fdce 100644
--- a/graphics/java/android/graphics/drawable/LevelListDrawable.java
+++ b/graphics/java/android/graphics/drawable/LevelListDrawable.java
@@ -164,8 +164,8 @@
                 mLows = orig.mLows;
                 mHighs = orig.mHighs;
             } else {
-                mLows = new int[getChildren().length];
-                mHighs = new int[getChildren().length];
+                mLows = new int[getCapacity()];
+                mHighs = new int[getCapacity()];
             }
         }
 
diff --git a/graphics/java/android/graphics/drawable/MipmapDrawable.java b/graphics/java/android/graphics/drawable/MipmapDrawable.java
deleted file mode 100644
index cd39719..0000000
--- a/graphics/java/android/graphics/drawable/MipmapDrawable.java
+++ /dev/null
@@ -1,312 +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.graphics.drawable;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-
-import java.io.IOException;
-
-/**
- * @hide -- we are probably moving to do MipMaps in another way (more integrated
- * with the resource system).
- *
- * A resource that manages a number of alternate Drawables, and which actually draws the one which
- * size matches the most closely the drawing bounds. Providing several pre-scaled version of the
- * drawable helps minimizing the aliasing artifacts that can be introduced by the scaling.
- *
- * <p>
- * Use {@link #addDrawable(Drawable)} to define the different Drawables that will represent the
- * mipmap levels of this MipmapDrawable. The mipmap Drawable that will actually be used when this
- * MipmapDrawable is drawn is the one which has the smallest intrinsic height greater or equal than
- * the bounds' height. This selection ensures that the best available mipmap level is scaled down to
- * draw this MipmapDrawable.
- * </p>
- *
- * If the bounds' height is larger than the largest mipmap, the largest mipmap will be scaled up.
- * Note that Drawables without intrinsic height (i.e. with a negative value, such as Color) will
- * only be used if no other mipmap Drawable are provided. The Drawables' intrinsic heights should
- * not be changed after the Drawable has been added to this MipmapDrawable.
- *
- * <p>
- * The different mipmaps' parameters (opacity, padding, color filter, gravity...) should typically
- * be similar to ensure a continuous visual appearance when the MipmapDrawable is scaled. The aspect
- * ratio of the different mipmaps should especially be equal.
- * </p>
- *
- * A typical example use of a MipmapDrawable would be for an image which is intended to be scaled at
- * various sizes, and for which one wants to provide pre-scaled versions to precisely control its
- * appearance.
- *
- * <p>
- * The intrinsic size of a MipmapDrawable are inferred from those of the largest mipmap (in terms of
- * {@link Drawable#getIntrinsicHeight()}). On the opposite, its minimum
- * size is defined by the smallest provided mipmap.
- * </p>
-
- * It can be defined in an XML file with the <code>&lt;mipmap></code> element.
- * Each mipmap Drawable is defined in a nested <code>&lt;item></code>. For example:
- * <pre>
- * &lt;mipmap xmlns:android="http://schemas.android.com/apk/res/android">
- *  &lt;item android:drawable="@drawable/my_image_8" />
- *  &lt;item android:drawable="@drawable/my_image_32" />
- *  &lt;item android:drawable="@drawable/my_image_128" />
- * &lt;/mipmap>
- *</pre>
- * <p>
- * With this XML saved into the res/drawable/ folder of the project, it can be referenced as
- * the drawable for an {@link android.widget.ImageView}. Assuming that the heights of the provided
- * drawables are respectively 8, 32 and 128 pixels, the first one will be scaled down when the
- * bounds' height is lower or equal than 8 pixels. The second drawable will then be used up to a
- * height of 32 pixels and the largest drawable will be used for greater heights.
- * </p>
- * @attr ref android.R.styleable#MipmapDrawableItem_drawable
- */
-public class MipmapDrawable extends DrawableContainer {
-    private final MipmapContainerState mMipmapContainerState;
-    private boolean mMutated;
-
-    public MipmapDrawable() {
-        this(null, null);
-    }
-
-    /**
-     * Adds a Drawable to the list of available mipmap Drawables. The Drawable actually used when
-     * this MipmapDrawable is drawn is determined from its bounds.
-     *
-     * This method has no effect if drawable is null.
-     *
-     * @param drawable The Drawable that will be added to list of available mipmap Drawables.
-     */
-
-    public void addDrawable(Drawable drawable) {
-        if (drawable != null) {
-            mMipmapContainerState.addDrawable(drawable);
-            onDrawableAdded();
-        }
-    }
-
-    private void onDrawableAdded() {
-        // selectDrawable assumes that the container content does not change.
-        // When a Drawable is added, the same index can correspond to a new Drawable, and since
-        // selectDrawable has a fast exit case when oldIndex==newIndex, the new drawable could end
-        // up not being used in place of the previous one if they happen to share the same index.
-        // This make sure the new computed index can actually replace the previous one.
-        selectDrawable(-1);
-        onBoundsChange(getBounds());
-    }
-
-    // overrides from Drawable
-
-    @Override
-    protected void onBoundsChange(Rect bounds) {
-        final int index = mMipmapContainerState.indexForBounds(bounds);
-
-        // Will call invalidateSelf() if needed
-        selectDrawable(index);
-
-        super.onBoundsChange(bounds);
-    }
-
-    @Override
-    public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs)
-    throws XmlPullParserException, IOException {
-
-        super.inflate(r, parser, attrs);
-
-        int type;
-
-        final int innerDepth = parser.getDepth() + 1;
-        int depth;
-        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
-                && ((depth = parser.getDepth()) >= innerDepth
-                        || type != XmlPullParser.END_TAG)) {
-            if (type != XmlPullParser.START_TAG) {
-                continue;
-            }
-
-            if (depth > innerDepth || !parser.getName().equals("item")) {
-                continue;
-            }
-
-            TypedArray a = r.obtainAttributes(attrs,
-                    com.android.internal.R.styleable.MipmapDrawableItem);
-
-            int drawableRes = a.getResourceId(
-                    com.android.internal.R.styleable.MipmapDrawableItem_drawable, 0);
-
-            a.recycle();
-
-            Drawable dr;
-            if (drawableRes != 0) {
-                dr = r.getDrawable(drawableRes);
-            } else {
-                while ((type = parser.next()) == XmlPullParser.TEXT) {
-                }
-                if (type != XmlPullParser.START_TAG) {
-                    throw new XmlPullParserException(
-                            parser.getPositionDescription()
-                            + ": <item> tag requires a 'drawable' attribute or "
-                            + "child tag defining a drawable");
-                }
-                dr = Drawable.createFromXmlInner(r, parser, attrs);
-            }
-
-            mMipmapContainerState.addDrawable(dr);
-        }
-
-        onDrawableAdded();
-    }
-
-    @Override
-    public Drawable mutate() {
-        if (!mMutated && super.mutate() == this) {
-            mMipmapContainerState.mMipmapHeights = mMipmapContainerState.mMipmapHeights.clone();
-            mMutated = true;
-        }
-        return this;
-    }
-
-    private final static class MipmapContainerState extends DrawableContainerState {
-        private int[] mMipmapHeights;
-
-        MipmapContainerState(MipmapContainerState orig, MipmapDrawable owner, Resources res) {
-            super(orig, owner, res);
-
-            if (orig != null) {
-                mMipmapHeights = orig.mMipmapHeights;
-            } else {
-                mMipmapHeights = new int[getChildren().length];
-            }
-
-            // Change the default value
-            setConstantSize(true);
-        }
-
-        /**
-         * Returns the index of the child mipmap drawable that will best fit the provided bounds.
-         * This index is determined by comparing bounds' height and children intrinsic heights.
-         * The returned mipmap index is the smallest mipmap which height is greater or equal than
-         * the bounds' height. If the bounds' height is larger than the largest mipmap, the largest
-         * mipmap index is returned.
-         *
-         * @param bounds The bounds of the MipMapDrawable.
-         * @return The index of the child Drawable that will best fit these bounds, or -1 if there
-         * are no children mipmaps.
-         */
-        public int indexForBounds(Rect bounds) {
-            final int boundsHeight = bounds.height();
-            final int N = getChildCount();
-            for (int i = 0; i < N; i++) {
-                if (boundsHeight <= mMipmapHeights[i]) {
-                    return i;
-                }
-            }
-
-            // No mipmap larger than bounds found. Use largest one which will be scaled up.
-            if (N > 0) {
-                return N - 1;
-            }
-            // No Drawable mipmap at all
-            return -1;
-        }
-
-        /**
-         * Adds a Drawable to the list of available mipmap Drawables. This list can be retrieved
-         * using {@link DrawableContainer.DrawableContainerState#getChildren()} and this method
-         * ensures that it is always sorted by increasing {@link Drawable#getIntrinsicHeight()}.
-         *
-         * @param drawable The Drawable that will be added to children list
-         */
-        public void addDrawable(Drawable drawable) {
-            // Insert drawable in last position, correctly resetting cached values and
-            // especially mComputedConstantSize
-            int pos = addChild(drawable);
-
-            // Bubble sort the last drawable to restore the sort by intrinsic height
-            final int drawableHeight = drawable.getIntrinsicHeight();
-
-            while (pos > 0) {
-                final Drawable previousDrawable = mDrawables[pos-1];
-                final int previousIntrinsicHeight = previousDrawable.getIntrinsicHeight();
-
-                if (drawableHeight < previousIntrinsicHeight) {
-                    mDrawables[pos] = previousDrawable;
-                    mMipmapHeights[pos] = previousIntrinsicHeight;
-
-                    mDrawables[pos-1] = drawable;
-                    mMipmapHeights[pos-1] = drawableHeight;
-                    pos--;
-                } else {
-                    break;
-                }
-            }
-        }
-
-        /**
-         * Intrinsic sizes are those of the largest available mipmap.
-         * Minimum sizes are those of the smallest available mipmap.
-         */
-        @Override
-        protected void computeConstantSize() {
-            final int N = getChildCount();
-            if (N > 0) {
-                final Drawable smallestDrawable = mDrawables[0];
-                mConstantMinimumWidth = smallestDrawable.getMinimumWidth();
-                mConstantMinimumHeight = smallestDrawable.getMinimumHeight();
-
-                final Drawable largestDrawable = mDrawables[N-1];
-                mConstantWidth = largestDrawable.getIntrinsicWidth();
-                mConstantHeight = largestDrawable.getIntrinsicHeight();
-            } else {
-                mConstantWidth = mConstantHeight = -1;
-                mConstantMinimumWidth = mConstantMinimumHeight = 0;
-            }
-            mComputedConstantSize = true;
-        }
-
-        @Override
-        public Drawable newDrawable() {
-            return new MipmapDrawable(this, null);
-        }
-
-        @Override
-        public Drawable newDrawable(Resources res) {
-            return new MipmapDrawable(this, res);
-        }
-
-        @Override
-        public void growArray(int oldSize, int newSize) {
-            super.growArray(oldSize, newSize);
-            int[] newInts = new int[newSize];
-            System.arraycopy(mMipmapHeights, 0, newInts, 0, oldSize);
-            mMipmapHeights = newInts;
-        }
-    }
-
-    private MipmapDrawable(MipmapContainerState state, Resources res) {
-        MipmapContainerState as = new MipmapContainerState(state, this, res);
-        mMipmapContainerState = as;
-        setConstantState(as);
-        onDrawableAdded();
-    }
-}
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index a9dc22b..720494b 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -30,6 +30,7 @@
 import android.graphics.Region;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
+import android.util.LayoutDirection;
 import android.util.TypedValue;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -52,7 +53,7 @@
  */
 public class NinePatchDrawable extends Drawable {
     // dithering helps a lot, and is pretty cheap, so default is true
-    private static final boolean DEFAULT_DITHER = true;
+    private static final boolean DEFAULT_DITHER = false;
     private NinePatchState mNinePatchState;
     private NinePatch mNinePatch;
     private Rect mPadding;
@@ -132,6 +133,7 @@
             // lazy allocation of a paint
             setDither(state.mDither);
         }
+        setAutoMirrored(state.mAutoMirrored);
         if (mNinePatch != null) {
             computeBitmapSize();
         }
@@ -197,10 +199,8 @@
             mBitmapHeight = mNinePatch.getHeight();
             mOpticalInsets = mNinePatchState.mOpticalInsets;
         } else {
-            mBitmapWidth = Bitmap.scaleFromDensity(mNinePatch.getWidth(),
-                    sdensity, tdensity);
-            mBitmapHeight = Bitmap.scaleFromDensity(mNinePatch.getHeight(),
-                    sdensity, tdensity);
+            mBitmapWidth = Bitmap.scaleFromDensity(mNinePatch.getWidth(), sdensity, tdensity);
+            mBitmapHeight = Bitmap.scaleFromDensity(mNinePatch.getHeight(), sdensity, tdensity);
             if (mNinePatchState.mPadding != null && mPadding != null) {
                 Rect dest = mPadding;
                 Rect src = mNinePatchState.mPadding;
@@ -218,7 +218,19 @@
 
     @Override
     public void draw(Canvas canvas) {
-        mNinePatch.draw(canvas, getBounds(), mPaint);
+        final Rect bounds = getBounds();
+        final boolean needMirroring = isAutoMirrored() &&
+                getLayoutDirection() == LayoutDirection.RTL;
+        if (needMirroring) {
+            canvas.save();
+            // Mirror the 9patch
+            canvas.translate(bounds.right - bounds.left, 0);
+            canvas.scale(-1.0f, 1.0f);
+        }
+        mNinePatch.draw(canvas, bounds, mPaint);
+        if (needMirroring) {
+            canvas.restore();
+        }
     }
 
     @Override
@@ -251,6 +263,15 @@
     }
 
     @Override
+    public int getAlpha() {
+        if (mPaint == null) {
+            // Fast common case -- normal alpha.
+            return 0xFF;
+        }
+        return getPaint().getAlpha();
+    }
+
+    @Override
     public void setColorFilter(ColorFilter cf) {
         if (mPaint == null && cf == null) {
             // Fast common case -- leave at no color filter.
@@ -262,6 +283,7 @@
 
     @Override
     public void setDither(boolean dither) {
+        //noinspection PointlessBooleanExpression
         if (mPaint == null && dither == DEFAULT_DITHER) {
             // Fast common case -- leave at default dither.
             return;
@@ -271,6 +293,16 @@
     }
 
     @Override
+    public void setAutoMirrored(boolean mirrored) {
+        mNinePatchState.mAutoMirrored = mirrored;
+    }
+
+    @Override
+    public boolean isAutoMirrored() {
+        return mNinePatchState.mAutoMirrored;
+    }
+
+    @Override
     public void setFilterBitmap(boolean filter) {
         getPaint().setFilterBitmap(filter);
         invalidateSelf();
@@ -290,8 +322,7 @@
         }
 
         final boolean dither = a.getBoolean(
-                com.android.internal.R.styleable.NinePatchDrawable_dither,
-                DEFAULT_DITHER);
+                com.android.internal.R.styleable.NinePatchDrawable_dither, DEFAULT_DITHER);
         final BitmapFactory.Options options = new BitmapFactory.Options();
         if (dither) {
             options.inDither = false;
@@ -321,9 +352,11 @@
                     ": <nine-patch> requires a valid 9-patch source image");
         }
 
-        setNinePatchState(new NinePatchState(
-                new NinePatch(bitmap, bitmap.getNinePatchChunk(), "XML 9-patch"),
-                padding, opticalInsets, dither), r);
+        final boolean automirrored = a.getBoolean(
+                com.android.internal.R.styleable.NinePatchDrawable_autoMirrored, false);
+
+        setNinePatchState(new NinePatchState(new NinePatch(bitmap, bitmap.getNinePatchChunk()),
+                padding, opticalInsets, dither, automirrored), r);
         mNinePatchState.mTargetDensity = mTargetDensity;
 
         a.recycle();
@@ -394,39 +427,49 @@
         return this;
     }
 
-    private final static class NinePatchState extends ConstantState {
+    final static class NinePatchState extends ConstantState {
         final NinePatch mNinePatch;
         final Rect mPadding;
         final Insets mOpticalInsets;
         final boolean mDither;
         int mChangingConfigurations;
         int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
+        boolean mAutoMirrored;
 
         NinePatchState(NinePatch ninePatch, Rect padding) {
-            this(ninePatch, padding, new Rect(), DEFAULT_DITHER);
+            this(ninePatch, padding, new Rect(), DEFAULT_DITHER, false);
         }
 
         NinePatchState(NinePatch ninePatch, Rect padding, Rect opticalInsets) {
-            this(ninePatch, padding, opticalInsets, DEFAULT_DITHER);
+            this(ninePatch, padding, opticalInsets, DEFAULT_DITHER, false);
         }
 
-        NinePatchState(NinePatch ninePatch, Rect rect, Rect opticalInsets, boolean dither) {
+        NinePatchState(NinePatch ninePatch, Rect rect, Rect opticalInsets, boolean dither,
+                       boolean autoMirror) {
             mNinePatch = ninePatch;
             mPadding = rect;
             mOpticalInsets = Insets.of(opticalInsets);
             mDither = dither;
+            mAutoMirrored = autoMirror;
         }
 
         // Copy constructor
 
         NinePatchState(NinePatchState state) {
-            mNinePatch = new NinePatch(state.mNinePatch);
+            // Note we don't copy the nine patch because it is immutable.
+            mNinePatch = state.mNinePatch;
             // Note we don't copy the padding because it is immutable.
             mPadding = state.mPadding;
             mOpticalInsets = state.mOpticalInsets;
             mDither = state.mDither;
             mChangingConfigurations = state.mChangingConfigurations;
             mTargetDensity = state.mTargetDensity;
+            mAutoMirrored = state.mAutoMirrored;
+        }
+
+        @Override
+        public Bitmap getBitmap() {
+            return mNinePatch.getBitmap();
         }
 
         @Override
diff --git a/graphics/java/android/graphics/drawable/RotateDrawable.java b/graphics/java/android/graphics/drawable/RotateDrawable.java
index 83d9581..aec3a4b 100644
--- a/graphics/java/android/graphics/drawable/RotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/RotateDrawable.java
@@ -108,6 +108,11 @@
         mState.mDrawable.setAlpha(alpha);
     }
 
+    @Override
+    public int getAlpha() {
+        return mState.mDrawable.getAlpha();
+    }
+
     public void setColorFilter(ColorFilter cf) {
         mState.mDrawable.setColorFilter(cf);
     }
diff --git a/graphics/java/android/graphics/drawable/ScaleDrawable.java b/graphics/java/android/graphics/drawable/ScaleDrawable.java
index 0664214..ec6b2c16 100644
--- a/graphics/java/android/graphics/drawable/ScaleDrawable.java
+++ b/graphics/java/android/graphics/drawable/ScaleDrawable.java
@@ -177,6 +177,11 @@
     }
 
     @Override
+    public int getAlpha() {
+        return mScaleState.mDrawable.getAlpha();
+    }
+
+    @Override
     public void setColorFilter(ColorFilter cf) {
         mScaleState.mDrawable.setColorFilter(cf);
     }
diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java
index 1dbcddb..93f2dc60 100644
--- a/graphics/java/android/graphics/drawable/ShapeDrawable.java
+++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java
@@ -252,7 +252,12 @@
         mShapeState.mAlpha = alpha;
         invalidateSelf();
     }
-    
+
+    @Override
+    public int getAlpha() {
+        return mShapeState.mAlpha;
+    }
+
     @Override
     public void setColorFilter(ColorFilter cf) {
         mShapeState.mPaint.setColorFilter(cf);
diff --git a/graphics/java/android/graphics/drawable/StateListDrawable.java b/graphics/java/android/graphics/drawable/StateListDrawable.java
index f8f3ac9..48d66b7 100644
--- a/graphics/java/android/graphics/drawable/StateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/StateListDrawable.java
@@ -132,6 +132,9 @@
         setDither(a.getBoolean(com.android.internal.R.styleable.StateListDrawable_dither,
                                DEFAULT_DITHER));
 
+        setAutoMirrored(a.getBoolean(
+                com.android.internal.R.styleable.StateListDrawable_autoMirrored, false));
+
         a.recycle();
 
         int type;
@@ -228,7 +231,7 @@
      * @see #getStateSet(int)
      */
     public Drawable getStateDrawable(int index) {
-        return mStateListState.getChildren()[index];
+        return mStateListState.getChild(index);
     }
     
     /**
@@ -264,11 +267,11 @@
     /** @hide */
     @Override
     public void setLayoutDirection(int layoutDirection) {
-        final int numStates = getStateCount();
-        for (int i = 0; i < numStates; i++) {
-            getStateDrawable(i).setLayoutDirection(layoutDirection);
-        }
         super.setLayoutDirection(layoutDirection);
+
+        // Let the container handle setting its own layout direction. Otherwise,
+        // we're accessing potentially unused states.
+        mStateListState.setLayoutDirection(layoutDirection);
     }
 
     static final class StateListState extends DrawableContainerState {
@@ -278,9 +281,9 @@
             super(orig, owner, res);
 
             if (orig != null) {
-                mStateSets = orig.mStateSets;
+                mStateSets = Arrays.copyOf(orig.mStateSets, orig.mStateSets.length);
             } else {
-                mStateSets = new int[getChildren().length][];
+                mStateSets = new int[getCapacity()][];
             }
         }
 
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index b460a4d..dca934f 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -28,6 +28,7 @@
 import android.util.Log;
 import android.util.TypedValue;
 import android.graphics.Canvas;
+import android.os.Trace;
 
 /**
  * <p> This class provides the primary method through which data is passed to
@@ -60,6 +61,7 @@
     Bitmap mBitmap;
     int mUsage;
     Allocation mAdaptedAllocation;
+    int mSize;
 
     boolean mConstrainedLOD;
     boolean mConstrainedFace;
@@ -78,7 +80,7 @@
     int mCurrentCount;
     static HashMap<Integer, Allocation> mAllocationMap =
             new HashMap<Integer, Allocation>();
-    IoInputNotifier mBufferNotifier;
+    OnBufferAvailableListener mBufferNotifier;
 
     /**
      * The usage of the Allocation.  These signal to RenderScript where to place
@@ -269,8 +271,23 @@
         mUsage = usage;
 
         if (t != null) {
+            // TODO: A3D doesn't have Type info during creation, so we can't
+            // calculate the size ahead of time. We can possibly add a method
+            // to update the size in the future if it seems reasonable.
+            mSize = mType.getCount() * mType.getElement().getBytesSize();
             updateCacheInfo(t);
         }
+        try {
+            RenderScript.registerNativeAllocation.invoke(RenderScript.sRuntime, mSize);
+        } catch (Exception e) {
+            Log.e(RenderScript.LOG_TAG, "Couldn't invoke registerNativeAllocation:" + e);
+            throw new RSRuntimeException("Couldn't invoke registerNativeAllocation:" + e);
+        }
+    }
+
+    protected void finalize() throws Throwable {
+        RenderScript.registerNativeFree.invoke(RenderScript.sRuntime, mSize);
+        super.finalize();
     }
 
     private void validateIsInt32() {
@@ -352,6 +369,7 @@
      *
      */
     public void syncAll(int srcLocation) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "syncAll");
         switch (srcLocation) {
         case USAGE_GRAPHICS_TEXTURE:
         case USAGE_SCRIPT:
@@ -372,6 +390,7 @@
         }
         mRS.validate();
         mRS.nAllocationSyncAll(getIDSafe(), srcLocation);
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
     /**
@@ -382,12 +401,14 @@
      *
      */
     public void ioSend() {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "ioSend");
         if ((mUsage & USAGE_IO_OUTPUT) == 0) {
             throw new RSIllegalArgumentException(
                 "Can only send buffer if IO_OUTPUT usage specified.");
         }
         mRS.validate();
         mRS.nAllocationIoSend(getID(mRS));
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
     /**
@@ -404,12 +425,14 @@
      *
      */
     public void ioReceive() {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "ioReceive");
         if ((mUsage & USAGE_IO_INPUT) == 0) {
             throw new RSIllegalArgumentException(
                 "Can only receive if IO_INPUT usage specified.");
         }
         mRS.validate();
         mRS.nAllocationIoReceive(getID(mRS));
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
     /**
@@ -418,6 +441,7 @@
      * @param d Source array.
      */
     public void copyFrom(BaseObj[] d) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
         mRS.validate();
         validateIsObject();
         if (d.length != mCurrentCount) {
@@ -429,6 +453,7 @@
             i[ct] = d[ct].getID(mRS);
         }
         copy1DRangeFromUnchecked(0, mCurrentCount, i);
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
     private void validateBitmapFormat(Bitmap b) {
@@ -494,6 +519,7 @@
      * @param d the source data array
      */
     public void copyFromUnchecked(int[] d) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked");
         mRS.validate();
         if (mCurrentDimZ > 0) {
             copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d);
@@ -502,7 +528,9 @@
         } else {
             copy1DRangeFromUnchecked(0, mCurrentCount, d);
         }
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
+
     /**
      * Copy into this Allocation from an array. This method does not guarantee
      * that the Allocation is compatible with the input buffer; it copies memory
@@ -511,6 +539,7 @@
      * @param d the source data array
      */
     public void copyFromUnchecked(short[] d) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked");
         mRS.validate();
         if (mCurrentDimZ > 0) {
             copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d);
@@ -519,7 +548,9 @@
         } else {
             copy1DRangeFromUnchecked(0, mCurrentCount, d);
         }
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
+
     /**
      * Copy into this Allocation from an array. This method does not guarantee
      * that the Allocation is compatible with the input buffer; it copies memory
@@ -528,6 +559,7 @@
      * @param d the source data array
      */
     public void copyFromUnchecked(byte[] d) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked");
         mRS.validate();
         if (mCurrentDimZ > 0) {
             copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d);
@@ -536,7 +568,9 @@
         } else {
             copy1DRangeFromUnchecked(0, mCurrentCount, d);
         }
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
+
     /**
      * Copy into this Allocation from an array. This method does not guarantee
      * that the Allocation is compatible with the input buffer; it copies memory
@@ -545,6 +579,7 @@
      * @param d the source data array
      */
     public void copyFromUnchecked(float[] d) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked");
         mRS.validate();
         if (mCurrentDimZ > 0) {
             copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d);
@@ -553,8 +588,10 @@
         } else {
             copy1DRangeFromUnchecked(0, mCurrentCount, d);
         }
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
+
     /**
      * Copy into this Allocation from an array.  This variant is type checked
      * and will generate exceptions if the Allocation's {@link
@@ -563,6 +600,7 @@
      * @param d the source data array
      */
     public void copyFrom(int[] d) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
         mRS.validate();
         if (mCurrentDimZ > 0) {
             copy3DRangeFrom(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d);
@@ -571,6 +609,7 @@
         } else {
             copy1DRangeFrom(0, mCurrentCount, d);
         }
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
     /**
@@ -581,6 +620,7 @@
      * @param d the source data array
      */
     public void copyFrom(short[] d) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
         mRS.validate();
         if (mCurrentDimZ > 0) {
             copy3DRangeFrom(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d);
@@ -589,6 +629,7 @@
         } else {
             copy1DRangeFrom(0, mCurrentCount, d);
         }
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
     /**
@@ -599,6 +640,7 @@
      * @param d the source data array
      */
     public void copyFrom(byte[] d) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
         mRS.validate();
         if (mCurrentDimZ > 0) {
             copy3DRangeFrom(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d);
@@ -607,6 +649,7 @@
         } else {
             copy1DRangeFrom(0, mCurrentCount, d);
         }
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
     /**
@@ -617,6 +660,7 @@
      * @param d the source data array
      */
     public void copyFrom(float[] d) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
         mRS.validate();
         if (mCurrentDimZ > 0) {
             copy3DRangeFrom(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d);
@@ -625,6 +669,7 @@
         } else {
             copy1DRangeFrom(0, mCurrentCount, d);
         }
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
     /**
@@ -641,6 +686,7 @@
      * @param b the source bitmap
      */
     public void copyFrom(Bitmap b) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
         mRS.validate();
         if (b.getConfig() == null) {
             Bitmap newBitmap = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ARGB_8888);
@@ -652,6 +698,7 @@
         validateBitmapSize(b);
         validateBitmapFormat(b);
         mRS.nAllocationCopyFromBitmap(getID(mRS), b);
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
     /**
@@ -661,14 +708,15 @@
      * @param a the source allocation
      */
     public void copyFrom(Allocation a) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
         mRS.validate();
         if (!mType.equals(a.getType())) {
             throw new RSIllegalArgumentException("Types of allocations must match.");
         }
         copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, a, 0, 0);
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
-
     /**
      * This is only intended to be used by auto-generated code reflected from
      * the RenderScript script files and should not be used by developers.
@@ -759,10 +807,13 @@
      * @param d the source data array
      */
     public void copy1DRangeFromUnchecked(int off, int count, int[] d) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFromUnchecked");
         int dataSize = mType.mElement.getBytesSize() * count;
         data1DChecks(off, count, d.length * 4, dataSize);
         mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
+
     /**
      * Copy an array into part of this Allocation.  This method does not
      * guarantee that the Allocation is compatible with the input buffer.
@@ -772,10 +823,13 @@
      * @param d the source data array
      */
     public void copy1DRangeFromUnchecked(int off, int count, short[] d) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFromUnchecked");
         int dataSize = mType.mElement.getBytesSize() * count;
         data1DChecks(off, count, d.length * 2, dataSize);
         mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
+
     /**
      * Copy an array into part of this Allocation.  This method does not
      * guarantee that the Allocation is compatible with the input buffer.
@@ -785,10 +839,13 @@
      * @param d the source data array
      */
     public void copy1DRangeFromUnchecked(int off, int count, byte[] d) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFromUnchecked");
         int dataSize = mType.mElement.getBytesSize() * count;
         data1DChecks(off, count, d.length, dataSize);
         mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
+
     /**
      * Copy an array into part of this Allocation.  This method does not
      * guarantee that the Allocation is compatible with the input buffer.
@@ -798,9 +855,11 @@
      * @param d the source data array
      */
     public void copy1DRangeFromUnchecked(int off, int count, float[] d) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFromUnchecked");
         int dataSize = mType.mElement.getBytesSize() * count;
         data1DChecks(off, count, d.length * 4, dataSize);
         mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
     /**
@@ -813,8 +872,10 @@
      * @param d the source data array
      */
     public void copy1DRangeFrom(int off, int count, int[] d) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFrom");
         validateIsInt32();
         copy1DRangeFromUnchecked(off, count, d);
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
     /**
@@ -827,8 +888,10 @@
      * @param d the source data array
      */
     public void copy1DRangeFrom(int off, int count, short[] d) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFrom");
         validateIsInt16();
         copy1DRangeFromUnchecked(off, count, d);
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
     /**
@@ -841,8 +904,10 @@
      * @param d the source data array
      */
     public void copy1DRangeFrom(int off, int count, byte[] d) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFrom");
         validateIsInt8();
         copy1DRangeFromUnchecked(off, count, d);
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
     /**
@@ -855,10 +920,11 @@
      * @param d the source data array.
      */
     public void copy1DRangeFrom(int off, int count, float[] d) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFrom");
         validateIsFloat32();
         copy1DRangeFromUnchecked(off, count, d);
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
-
      /**
      * Copy part of an Allocation into this Allocation.
      *
@@ -869,6 +935,7 @@
      *          be copied.
      */
     public void copy1DRangeFrom(int off, int count, Allocation data, int dataOff) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copy1DRangeFrom");
         mRS.nAllocationData2D(getIDSafe(), off, 0,
                               mSelectedLOD, mSelectedFace.mID,
                               count, 1, data.getID(mRS), dataOff, 0,
@@ -893,34 +960,41 @@
     }
 
     void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, byte[] data) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFromUnchecked");
         mRS.validate();
         validate2DRange(xoff, yoff, w, h);
         mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
                               w, h, data, data.length);
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
     void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, short[] data) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFromUnchecked");
         mRS.validate();
         validate2DRange(xoff, yoff, w, h);
         mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
                               w, h, data, data.length * 2);
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
     void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, int[] data) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFromUnchecked");
         mRS.validate();
         validate2DRange(xoff, yoff, w, h);
         mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
                               w, h, data, data.length * 4);
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
     void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, float[] data) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFromUnchecked");
         mRS.validate();
         validate2DRange(xoff, yoff, w, h);
         mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
                               w, h, data, data.length * 4);
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
-
     /**
      * Copy from an array into a rectangular region in this Allocation.  The
      * array is assumed to be tightly packed.
@@ -932,8 +1006,10 @@
      * @param data to be placed into the Allocation
      */
     public void copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
         validateIsInt8();
         copy2DRangeFromUnchecked(xoff, yoff, w, h, data);
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
     /**
@@ -947,8 +1023,10 @@
      * @param data to be placed into the Allocation
      */
     public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
         validateIsInt16();
         copy2DRangeFromUnchecked(xoff, yoff, w, h, data);
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
     /**
@@ -962,8 +1040,10 @@
      * @param data to be placed into the Allocation
      */
     public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
         validateIsInt32();
         copy2DRangeFromUnchecked(xoff, yoff, w, h, data);
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
     /**
@@ -977,8 +1057,10 @@
      * @param data to be placed into the Allocation
      */
     public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
         validateIsFloat32();
         copy2DRangeFromUnchecked(xoff, yoff, w, h, data);
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
     /**
@@ -995,12 +1077,14 @@
      */
     public void copy2DRangeFrom(int xoff, int yoff, int w, int h,
                                 Allocation data, int dataXoff, int dataYoff) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
         mRS.validate();
         validate2DRange(xoff, yoff, w, h);
         mRS.nAllocationData2D(getIDSafe(), xoff, yoff,
                               mSelectedLOD, mSelectedFace.mID,
                               w, h, data.getID(mRS), dataXoff, dataYoff,
                               data.mSelectedLOD, data.mSelectedFace.mID);
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
     /**
@@ -1013,6 +1097,7 @@
      * @param data the Bitmap to be copied
      */
     public void copy2DRangeFrom(int xoff, int yoff, Bitmap data) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
         mRS.validate();
         if (data.getConfig() == null) {
             Bitmap newBitmap = Bitmap.createBitmap(data.getWidth(), data.getHeight(), Bitmap.Config.ARGB_8888);
@@ -1024,6 +1109,7 @@
         validateBitmapFormat(data);
         validate2DRange(xoff, yoff, data.getWidth(), data.getHeight());
         mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, data);
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
     private void validate3DRange(int xoff, int yoff, int zoff, int w, int h, int d) {
@@ -1166,10 +1252,12 @@
      * @param b The bitmap to be set from the Allocation.
      */
     public void copyTo(Bitmap b) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo");
         mRS.validate();
         validateBitmapFormat(b);
         validateBitmapSize(b);
         mRS.nAllocationCopyToBitmap(getID(mRS), b);
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
     /**
@@ -1180,9 +1268,11 @@
      * @param d The array to be set from the Allocation.
      */
     public void copyTo(byte[] d) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo");
         validateIsInt8();
         mRS.validate();
         mRS.nAllocationRead(getID(mRS), d);
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
     /**
@@ -1193,9 +1283,11 @@
      * @param d The array to be set from the Allocation.
      */
     public void copyTo(short[] d) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo");
         validateIsInt16();
         mRS.validate();
         mRS.nAllocationRead(getID(mRS), d);
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
     /**
@@ -1206,9 +1298,11 @@
      * @param d The array to be set from the Allocation.
      */
     public void copyTo(int[] d) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo");
         validateIsInt32();
         mRS.validate();
         mRS.nAllocationRead(getID(mRS), d);
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
     /**
@@ -1219,9 +1313,11 @@
      * @param d The array to be set from the Allocation.
      */
     public void copyTo(float[] d) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "copyTo");
         validateIsFloat32();
         mRS.validate();
         mRS.nAllocationRead(getID(mRS), d);
+        Trace.traceEnd(RenderScript.TRACE_TAG);
     }
 
     /**
@@ -1271,6 +1367,7 @@
      *              utilized
      */
     static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mips, int usage) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "createTyped");
         rs.validate();
         if (type.getID(rs) == 0) {
             throw new RSInvalidStateException("Bad Type");
@@ -1279,6 +1376,7 @@
         if (id == 0) {
             throw new RSRuntimeException("Allocation creation failed.");
         }
+        Trace.traceEnd(RenderScript.TRACE_TAG);
         return new Allocation(id, rs, type, usage);
     }
 
@@ -1323,6 +1421,7 @@
      */
     static public Allocation createSized(RenderScript rs, Element e,
                                          int count, int usage) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "createSized");
         rs.validate();
         Type.Builder b = new Type.Builder(rs, e);
         b.setX(count);
@@ -1332,6 +1431,7 @@
         if (id == 0) {
             throw new RSRuntimeException("Allocation creation failed.");
         }
+        Trace.traceEnd(RenderScript.TRACE_TAG);
         return new Allocation(id, rs, t, usage);
     }
 
@@ -1391,6 +1491,7 @@
     static public Allocation createFromBitmap(RenderScript rs, Bitmap b,
                                               MipmapControl mips,
                                               int usage) {
+        Trace.traceBegin(RenderScript.TRACE_TAG, "createFromBitmap");
         rs.validate();
 
         // WAR undocumented color formats
@@ -1426,6 +1527,7 @@
         if (id == 0) {
             throw new RSRuntimeException("Load failed.");
         }
+        Trace.traceEnd(RenderScript.TRACE_TAG);
         return new Allocation(id, rs, t, usage);
     }
 
@@ -1739,26 +1841,22 @@
     }
 
     /**
-     * @hide
-     *
      * Interface to handle notification when new buffers are available via
      * {@link #USAGE_IO_INPUT}. An application will receive one notification
      * when a buffer is available. Additional buffers will not trigger new
      * notifications until a buffer is processed.
      */
-    public interface IoInputNotifier {
+    public interface OnBufferAvailableListener {
         public void onBufferAvailable(Allocation a);
     }
 
     /**
-     * @hide
-     *
      * Set a notification handler for {@link #USAGE_IO_INPUT}.
      *
-     * @param callback instance of the IoInputNotifier class to be called
-     *                 when buffer arrive.
+     * @param callback instance of the OnBufferAvailableListener
+     *                 class to be called when buffer arrive.
      */
-    public void setIoInputNotificationHandler(IoInputNotifier callback) {
+    public void setOnBufferAvailableListener(OnBufferAvailableListener callback) {
         synchronized(mAllocationMap) {
             mAllocationMap.put(new Integer(getID(mRS)), this);
             mBufferNotifier = callback;
diff --git a/graphics/java/android/renderscript/Element.java b/graphics/java/android/renderscript/Element.java
index 3838c61..68badfa 100644
--- a/graphics/java/android/renderscript/Element.java
+++ b/graphics/java/android/renderscript/Element.java
@@ -725,6 +725,13 @@
         return rs.mElement_LONG_4;
     }
 
+    public static Element YUV(RenderScript rs) {
+        if (rs.mElement_YUV == null) {
+            rs.mElement_YUV = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_YUV);
+        }
+        return rs.mElement_YUV;
+    }
+
     public static Element MATRIX_4X4(RenderScript rs) {
         if(rs.mElement_MATRIX_4X4 == null) {
             rs.mElement_MATRIX_4X4 = createUser(rs, DataType.MATRIX_4X4);
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 1264adc..7d4a5c4 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -18,6 +18,7 @@
 
 import java.io.File;
 import java.lang.reflect.Field;
+import java.lang.reflect.Method;
 
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
@@ -29,8 +30,8 @@
 import android.os.Process;
 import android.util.Log;
 import android.view.Surface;
-
-
+import android.os.SystemProperties;
+import android.os.Trace;
 
 /**
  * This class provides access to a RenderScript context, which controls RenderScript
@@ -44,6 +45,8 @@
  * </div>
  **/
 public class RenderScript {
+    static final long TRACE_TAG = Trace.TRACE_TAG_RS;
+
     static final String LOG_TAG = "RenderScript_jni";
     static final boolean DEBUG  = false;
     @SuppressWarnings({"UnusedDeclaration", "deprecation"})
@@ -55,20 +58,35 @@
      * We use a class initializer to allow the native code to cache some
      * field offsets.
      */
-    @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
+    @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) // TODO: now used locally; remove?
     static boolean sInitialized;
     native static void _nInit();
 
+    static Object sRuntime;
+    static Method registerNativeAllocation;
+    static Method registerNativeFree;
 
     static {
         sInitialized = false;
-        try {
-            System.loadLibrary("rs_jni");
-            _nInit();
-            sInitialized = true;
-        } catch (UnsatisfiedLinkError e) {
-            Log.e(LOG_TAG, "Error loading RS jni library: " + e);
-            throw new RSRuntimeException("Error loading RS jni library: " + e);
+        if (!SystemProperties.getBoolean("config.disable_renderscript", false)) {
+            try {
+                Class<?> vm_runtime = Class.forName("dalvik.system.VMRuntime");
+                Method get_runtime = vm_runtime.getDeclaredMethod("getRuntime");
+                sRuntime = get_runtime.invoke(null);
+                registerNativeAllocation = vm_runtime.getDeclaredMethod("registerNativeAllocation", Integer.TYPE);
+                registerNativeFree = vm_runtime.getDeclaredMethod("registerNativeFree", Integer.TYPE);
+            } catch (Exception e) {
+                Log.e(LOG_TAG, "Error loading GC methods: " + e);
+                throw new RSRuntimeException("Error loading GC methods: " + e);
+            }
+            try {
+                System.loadLibrary("rs_jni");
+                _nInit();
+                sInitialized = true;
+            } catch (UnsatisfiedLinkError e) {
+                Log.e(LOG_TAG, "Error loading RS jni library: " + e);
+                throw new RSRuntimeException("Error loading RS jni library: " + e);
+            }
         }
     }
 
@@ -92,6 +110,11 @@
      * @param cacheDir A directory the current process can write to
      */
     public static void setupDiskCache(File cacheDir) {
+        if (!sInitialized) {
+            Log.e(LOG_TAG, "RenderScript.setupDiskCache() called when disabled");
+            return;
+        }
+
         // Defer creation of cache path to nScriptCCreate().
         mCacheDir = cacheDir;
     }
@@ -875,6 +898,8 @@
     Element mElement_LONG_3;
     Element mElement_LONG_4;
 
+    Element mElement_YUV;
+
     Element mElement_MATRIX_4X4;
     Element mElement_MATRIX_3X3;
     Element mElement_MATRIX_2X2;
@@ -1137,6 +1162,11 @@
      * @return RenderScript
      */
     public static RenderScript create(Context ctx, int sdkVersion, ContextType ct) {
+        if (!sInitialized) {
+            Log.e(LOG_TAG, "RenderScript.create() called when disabled; someone is likely to crash");
+            return null;
+        }
+
         RenderScript rs = new RenderScript(ctx);
 
         rs.mDev = rs.nDeviceCreate();
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicColorMatrix.java b/graphics/java/android/renderscript/ScriptIntrinsicColorMatrix.java
index 77b9385..32c3d15 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsicColorMatrix.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsicColorMatrix.java
@@ -21,15 +21,27 @@
 /**
  * Intrinsic for applying a color matrix to allocations.
  *
- * This has the same effect as loading each element and
- * converting it to a {@link Element#F32_4}, multiplying the
- * result by the 4x4 color matrix as performed by
- * rsMatrixMultiply() and writing it to the output after
- * conversion back to {@link Element#U8_4}.
+ * If the element type is {@link Element.DataType#UNSIGNED_8},
+ * it is converted to {@link Element.DataType#FLOAT_32} and
+ * normalized from (0-255) to (0-1). If the incoming vector size
+ * is less than four, a {@link Element#F32_4} is created by
+ * filling the missing vector channels with zero. This value is
+ * then multiplied by the 4x4 color matrix as performed by
+ * rsMatrixMultiply(), adding a {@link Element#F32_4}, and then
+ * writing it to the output {@link Allocation}.
+ *
+ * If the ouptut type is unsigned, the value is normalized from
+ * (0-1) to (0-255) and converted. If the output vector size is
+ * less than four, the unused channels are discarded.
+ *
+ * Supported elements types are {@link Element#U8}, {@link
+ * Element#U8_2}, {@link Element#U8_3}, {@link Element#U8_4},
+ * {@link Element#F32}, {@link Element#F32_2}, {@link
+ * Element#F32_3}, and {@link Element#F32_4}.
  **/
 public final class ScriptIntrinsicColorMatrix extends ScriptIntrinsic {
     private final Matrix4f mMatrix = new Matrix4f();
-    private Allocation mInput;
+    private final Float4 mAdd = new Float4();
 
     private ScriptIntrinsicColorMatrix(int id, RenderScript rs) {
         super(id, rs);
@@ -39,18 +51,31 @@
      * Create an intrinsic for applying a color matrix to an
      * allocation.
      *
-     * Supported elements types are {@link Element#U8_4}
-     *
      * @param rs The RenderScript context
-     * @param e Element type for intputs and outputs
+     * @param e Element type for inputs and outputs, As of API 19,
+     *          this parameter is ignored. The Element type check is
+     *          performed in the kernel launch.
+     *
+     * @deprecated Use the single argument version as Element is now
+     *             ignored.
      *
      * @return ScriptIntrinsicColorMatrix
      */
+    @Deprecated
     public static ScriptIntrinsicColorMatrix create(RenderScript rs, Element e) {
-        if (!e.isCompatible(Element.U8_4(rs))) {
-            throw new RSIllegalArgumentException("Unsuported element type.");
-        }
-        int id = rs.nScriptIntrinsicCreate(2, e.getID(rs));
+        return create(rs);
+    }
+
+    /**
+     * Create an intrinsic for applying a color matrix to an
+     * allocation.
+     *
+     * @param rs The RenderScript context
+     *
+     * @return ScriptIntrinsicColorMatrix
+     */
+    public static ScriptIntrinsicColorMatrix create(RenderScript rs) {
+        int id = rs.nScriptIntrinsicCreate(2, 0);
         return new ScriptIntrinsicColorMatrix(id, rs);
 
     }
@@ -84,6 +109,49 @@
     }
 
     /**
+     * Set the value to be added after the color matrix has been
+     * applied. The default value is {0, 0, 0, 0}
+     *
+     * @param f The float4 value to be added.
+     */
+    public void setAdd(Float4 f) {
+        mAdd.x = f.x;
+        mAdd.y = f.y;
+        mAdd.z = f.z;
+        mAdd.w = f.w;
+
+        FieldPacker fp = new FieldPacker(4*4);
+        fp.addF32(f.x);
+        fp.addF32(f.y);
+        fp.addF32(f.z);
+        fp.addF32(f.w);
+        setVar(1, fp);
+    }
+
+    /**
+     * Set the value to be added after the color matrix has been
+     * applied. The default value is {0, 0, 0, 0}
+     *
+     * @param r The red add value.
+     * @param g The green add value.
+     * @param b The blue add value.
+     * @param a The alpha add value.
+     */
+    public void setAdd(float r, float g, float b, float a) {
+        mAdd.x = r;
+        mAdd.y = g;
+        mAdd.z = b;
+        mAdd.w = a;
+
+        FieldPacker fp = new FieldPacker(4*4);
+        fp.addF32(mAdd.x);
+        fp.addF32(mAdd.y);
+        fp.addF32(mAdd.z);
+        fp.addF32(mAdd.w);
+        setVar(1, fp);
+    }
+
+    /**
      * Set a color matrix to convert from RGB to luminance. The alpha channel
      * will be a copy.
      *
@@ -142,13 +210,45 @@
 
 
     /**
-     * Invoke the kernel and apply the matrix to each cell of ain and copy to
-     * aout.
+     * Invoke the kernel and apply the matrix to each cell of input
+     * {@link Allocation} and copy to the output {@link Allocation}.
+     *
+     * If the vector size of the input is less than four, the
+     * remaining components are treated as zero for the matrix
+     * multiply.
+     *
+     * If the output vector size is less than four, the unused
+     * vector components are discarded.
+     *
      *
      * @param ain Input allocation
      * @param aout Output allocation
      */
     public void forEach(Allocation ain, Allocation aout) {
+        if (!ain.getElement().isCompatible(Element.U8(mRS)) &&
+            !ain.getElement().isCompatible(Element.U8_2(mRS)) &&
+            !ain.getElement().isCompatible(Element.U8_3(mRS)) &&
+            !ain.getElement().isCompatible(Element.U8_4(mRS)) &&
+            !ain.getElement().isCompatible(Element.F32(mRS)) &&
+            !ain.getElement().isCompatible(Element.F32_2(mRS)) &&
+            !ain.getElement().isCompatible(Element.F32_3(mRS)) &&
+            !ain.getElement().isCompatible(Element.F32_4(mRS))) {
+
+            throw new RSIllegalArgumentException("Unsuported element type.");
+        }
+
+        if (!aout.getElement().isCompatible(Element.U8(mRS)) &&
+            !aout.getElement().isCompatible(Element.U8_2(mRS)) &&
+            !aout.getElement().isCompatible(Element.U8_3(mRS)) &&
+            !aout.getElement().isCompatible(Element.U8_4(mRS)) &&
+            !aout.getElement().isCompatible(Element.F32(mRS)) &&
+            !aout.getElement().isCompatible(Element.F32_2(mRS)) &&
+            !aout.getElement().isCompatible(Element.F32_3(mRS)) &&
+            !aout.getElement().isCompatible(Element.F32_4(mRS))) {
+
+            throw new RSIllegalArgumentException("Unsuported element type.");
+        }
+
         forEach(0, ain, aout, null);
     }
 
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicConvolve3x3.java b/graphics/java/android/renderscript/ScriptIntrinsicConvolve3x3.java
index c9c54b2..5d3c1d3 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsicConvolve3x3.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsicConvolve3x3.java
@@ -31,7 +31,10 @@
     }
 
     /**
-     * Supported elements types are {@link Element#U8_4}
+     * Supported elements types are {@link Element#U8}, {@link
+     * Element#U8_2}, {@link Element#U8_3}, {@link Element#U8_4},
+     * {@link Element#F32}, {@link Element#F32_2}, {@link
+     * Element#F32_3}, and {@link Element#F32_4}
      *
      * The default coefficients are.
      *
@@ -48,7 +51,14 @@
      */
     public static ScriptIntrinsicConvolve3x3 create(RenderScript rs, Element e) {
         float f[] = { 0, 0, 0, 0, 1, 0, 0, 0, 0};
-        if (!e.isCompatible(Element.U8_4(rs))) {
+        if (!e.isCompatible(Element.U8(rs)) &&
+            !e.isCompatible(Element.U8_2(rs)) &&
+            !e.isCompatible(Element.U8_3(rs)) &&
+            !e.isCompatible(Element.U8_4(rs)) &&
+            !e.isCompatible(Element.F32(rs)) &&
+            !e.isCompatible(Element.F32_2(rs)) &&
+            !e.isCompatible(Element.F32_3(rs)) &&
+            !e.isCompatible(Element.F32_4(rs))) {
             throw new RSIllegalArgumentException("Unsuported element type.");
         }
         int id = rs.nScriptIntrinsicCreate(1, e.getID(rs));
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java b/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java
index c6e1e39..ad09f95 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java
@@ -31,7 +31,10 @@
     }
 
     /**
-     * Supported elements types are {@link Element#U8_4}
+     * Supported elements types are {@link Element#U8}, {@link
+     * Element#U8_2}, {@link Element#U8_3}, {@link Element#U8_4},
+     * {@link Element#F32}, {@link Element#F32_2}, {@link
+     * Element#F32_3}, and {@link Element#F32_4}
      *
      * The default coefficients are.
      * <code>
@@ -48,6 +51,17 @@
      * @return ScriptIntrinsicConvolve5x5
      */
     public static ScriptIntrinsicConvolve5x5 create(RenderScript rs, Element e) {
+        if (!e.isCompatible(Element.U8(rs)) &&
+            !e.isCompatible(Element.U8_2(rs)) &&
+            !e.isCompatible(Element.U8_3(rs)) &&
+            !e.isCompatible(Element.U8_4(rs)) &&
+            !e.isCompatible(Element.F32(rs)) &&
+            !e.isCompatible(Element.F32_2(rs)) &&
+            !e.isCompatible(Element.F32_3(rs)) &&
+            !e.isCompatible(Element.F32_4(rs))) {
+            throw new RSIllegalArgumentException("Unsuported element type.");
+        }
+
         int id = rs.nScriptIntrinsicCreate(4, e.getID(rs));
         return new ScriptIntrinsicConvolve5x5(id, rs);
 
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicHistogram.java b/graphics/java/android/renderscript/ScriptIntrinsicHistogram.java
new file mode 100644
index 0000000..adc2d95
--- /dev/null
+++ b/graphics/java/android/renderscript/ScriptIntrinsicHistogram.java
@@ -0,0 +1,186 @@
+/*
+ * 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.renderscript;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.util.Log;
+
+/**
+ * Intrinsic Histogram filter.
+ *
+ *
+ **/
+public final class ScriptIntrinsicHistogram extends ScriptIntrinsic {
+    private Allocation mOut;
+
+    private ScriptIntrinsicHistogram(int id, RenderScript rs) {
+        super(id, rs);
+    }
+
+    /**
+     * Create an intrinsic for calculating the histogram of an uchar
+     * or uchar4 image.
+     *
+     * Supported elements types are
+     * {@link Element#U8_4}, {@link Element#U8_3},
+     * {@link Element#U8_2}, {@link Element#U8}
+     *
+     * @param rs The RenderScript context
+     * @param e Element type for inputs
+     *
+     * @return ScriptIntrinsicHistogram
+     */
+    public static ScriptIntrinsicHistogram create(RenderScript rs, Element e) {
+        if ((!e.isCompatible(Element.U8_4(rs))) &&
+            (!e.isCompatible(Element.U8_3(rs))) &&
+            (!e.isCompatible(Element.U8_2(rs))) &&
+            (!e.isCompatible(Element.U8(rs)))) {
+            throw new RSIllegalArgumentException("Unsuported element type.");
+        }
+        int id = rs.nScriptIntrinsicCreate(9, e.getID(rs));
+        ScriptIntrinsicHistogram sib = new ScriptIntrinsicHistogram(id, rs);
+        return sib;
+    }
+
+    /**
+     * Process an input buffer and place the histogram into the
+     * output allocation. The output allocation may be a narrower
+     * vector size than the input. In this case the vector size of
+     * the output is used to determine how many of the input
+     * channels are used in the computation. This is useful if you
+     * have an RGBA input buffer but only want the histogram for
+     * RGB.
+     *
+     * 1D and 2D input allocations are supported.
+     *
+     * @param ain The input image
+     */
+    public void forEach(Allocation ain) {
+        if (ain.getType().getElement().getVectorSize() <
+            mOut.getType().getElement().getVectorSize()) {
+
+            throw new RSIllegalArgumentException(
+                "Input vector size must be >= output vector size.");
+        }
+        if (ain.getType().getElement().isCompatible(Element.U8(mRS)) &&
+            ain.getType().getElement().isCompatible(Element.U8_4(mRS))) {
+            throw new RSIllegalArgumentException("Output type must be U32 or I32.");
+        }
+
+        forEach(0, ain, null, null);
+    }
+
+    /**
+     * Set the coefficients used for the RGBA to Luminocity
+     * calculation. The default is {0.299f, 0.587f, 0.114f, 0.f}.
+     *
+     * Coefficients must be >= 0 and sum to 1.0 or less.
+     *
+     * @param r Red coefficient
+     * @param g Green coefficient
+     * @param b Blue coefficient
+     * @param a Alpha coefficient
+     */
+    public void setDotCoefficients(float r, float g, float b, float a) {
+        if ((r < 0.f) || (g < 0.f) || (b < 0.f) || (a < 0.f)) {
+            throw new RSIllegalArgumentException("Coefficient may not be negative.");
+        }
+        if ((r + g + b + a) > 1.f) {
+            throw new RSIllegalArgumentException("Sum of coefficients must be 1.0 or less.");
+        }
+
+        FieldPacker fp = new FieldPacker(16);
+        fp.addF32(r);
+        fp.addF32(g);
+        fp.addF32(b);
+        fp.addF32(a);
+        setVar(0, fp);
+    }
+
+    /**
+     * Set the output of the histogram.  32 bit integer types are
+     * supported.
+     *
+     * @param aout The output allocation
+     */
+    public void setOutput(Allocation aout) {
+        mOut = aout;
+        if (mOut.getType().getElement() != Element.U32(mRS) &&
+            mOut.getType().getElement() != Element.U32_2(mRS) &&
+            mOut.getType().getElement() != Element.U32_3(mRS) &&
+            mOut.getType().getElement() != Element.U32_4(mRS) &&
+            mOut.getType().getElement() != Element.I32(mRS) &&
+            mOut.getType().getElement() != Element.I32_2(mRS) &&
+            mOut.getType().getElement() != Element.I32_3(mRS) &&
+            mOut.getType().getElement() != Element.I32_4(mRS)) {
+
+            throw new RSIllegalArgumentException("Output type must be U32 or I32.");
+        }
+        if ((mOut.getType().getX() != 256) ||
+            (mOut.getType().getY() != 0) ||
+            mOut.getType().hasMipmaps() ||
+            (mOut.getType().getYuv() != 0)) {
+
+            throw new RSIllegalArgumentException("Output must be 1D, 256 elements.");
+        }
+        setVar(1, aout);
+    }
+
+    /**
+     * Process an input buffer and place the histogram into the
+     * output allocation. The dot product of the input channel and
+     * the coefficients from 'setDotCoefficients' are used to
+     * calculate the output values.
+     *
+     * 1D and 2D input allocations are supported.
+     *
+     * @param ain The input image
+     */
+    public void forEach_Dot(Allocation ain) {
+        if (mOut.getType().getElement().getVectorSize() != 1) {
+            throw new RSIllegalArgumentException("Output vector size must be one.");
+        }
+        if (ain.getType().getElement().isCompatible(Element.U8(mRS)) &&
+            ain.getType().getElement().isCompatible(Element.U8_4(mRS))) {
+            throw new RSIllegalArgumentException("Output type must be U32 or I32.");
+        }
+
+        forEach(1, ain, null, null);
+    }
+
+
+
+    /**
+     * Get a KernelID for this intrinsic kernel.
+     *
+     * @return Script.KernelID The KernelID object.
+     */
+    public Script.KernelID getKernelID_Separate() {
+        return createKernelID(0, 3, null, null);
+    }
+
+    /**
+     * Get a FieldID for the input field of this intrinsic.
+     *
+     * @return Script.FieldID The FieldID object.
+     */
+    public Script.FieldID getFieldID_Input() {
+        return createFieldID(1, null);
+    }
+}
+
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicYuvToRGB.java b/graphics/java/android/renderscript/ScriptIntrinsicYuvToRGB.java
index 9b5de9b..845625d 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsicYuvToRGB.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsicYuvToRGB.java
@@ -20,9 +20,9 @@
 /**
  * Intrinsic for converting an Android YUV buffer to RGB.
  *
- * The input allocation is supplied in NV21 format as a U8
- * element type. The output is RGBA, the alpha channel will be
- * set to 255.
+ * The input allocation should be supplied in a supported YUV format
+ * as a YUV element Allocation. The output is RGBA; the alpha channel
+ * will be set to 255.
  */
 public final class ScriptIntrinsicYuvToRGB extends ScriptIntrinsic {
     private Allocation mInput;
diff --git a/graphics/java/android/renderscript/Type.java b/graphics/java/android/renderscript/Type.java
index ef08c29..e023739 100644
--- a/graphics/java/android/renderscript/Type.java
+++ b/graphics/java/android/renderscript/Type.java
@@ -37,10 +37,11 @@
  * faces. LOD and cube map faces are booleans to indicate present or not
  * present. </p>
  *
- * <p>A Type also supports YUV format information to support an {@link
- * android.renderscript.Allocation} in a YUV format. The YUV formats supported
- * are {@link android.graphics.ImageFormat#YV12} and {@link
- * android.graphics.ImageFormat#NV21}.</p>
+ * <p>A Type also supports YUV format information to support an
+ * {@link android.renderscript.Allocation} in a YUV format. The YUV formats
+ * supported are {@link android.graphics.ImageFormat#YV12},
+ * {@link android.graphics.ImageFormat#NV21}, and
+ * {@link android.graphics.ImageFormat#YUV_420_888}</p>
  *
  * <div class="special reference">
  * <h3>Developer Guides</h3>
@@ -284,16 +285,19 @@
         /**
          * Set the YUV layout for a Type.
          *
-         * @param yuvFormat {@link android.graphics.ImageFormat#YV12} or {@link android.graphics.ImageFormat#NV21}
+         * @param yuvFormat {@link android.graphics.ImageFormat#YV12}, {@link android.graphics.ImageFormat#NV21}, or
+         * {@link android.graphics.ImageFormat#YUV_420_888}.
          */
         public Builder setYuvFormat(int yuvFormat) {
             switch (yuvFormat) {
             case android.graphics.ImageFormat.NV21:
             case android.graphics.ImageFormat.YV12:
+            case android.graphics.ImageFormat.YUV_420_888:
                 break;
 
             default:
-                throw new RSIllegalArgumentException("Only NV21 and YV12 are supported..");
+                throw new RSIllegalArgumentException(
+                    "Only ImageFormat.NV21, .YV12, and .YUV_420_888 are supported..");
             }
 
             mYuv = yuvFormat;
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index b9f8713..cbc4e5a 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -27,7 +27,6 @@
 #include <core/SkPixelRef.h>
 #include <core/SkStream.h>
 #include <core/SkTemplates.h>
-#include <images/SkImageDecoder.h>
 
 #include <androidfw/Asset.h>
 #include <androidfw/AssetManager.h>
@@ -185,7 +184,7 @@
 nContextCreate(JNIEnv *_env, jobject _this, jint dev, jint ver, jint sdkVer, jint ct)
 {
     LOG_API("nContextCreate");
-    return (jint)rsContextCreate((RsDevice)dev, ver, sdkVer, (RsContextType)ct, false, false);
+    return (jint)rsContextCreate((RsDevice)dev, ver, sdkVer, (RsContextType)ct, 0);
 }
 
 static jint
diff --git a/graphics/tests/graphicstests/src/android/graphics/drawable/MipmapDrawableTest.java b/graphics/tests/graphicstests/src/android/graphics/drawable/MipmapDrawableTest.java
deleted file mode 100644
index 5fcc3bc..0000000
--- a/graphics/tests/graphicstests/src/android/graphics/drawable/MipmapDrawableTest.java
+++ /dev/null
@@ -1,280 +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.drawable;
-
-import android.graphics.Canvas;
-import android.graphics.ColorFilter;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.MipmapDrawable;
-import android.graphics.drawable.DrawableContainer.DrawableContainerState;
-import android.test.InstrumentationTestCase;
-
-public class MipmapDrawableTest extends InstrumentationTestCase {
-    private MockMipmapDrawable mMipmapDrawable;
-
-    private DrawableContainerState mDrawableContainerState;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mMipmapDrawable = new MockMipmapDrawable();
-        mDrawableContainerState = (DrawableContainerState) mMipmapDrawable.getConstantState();
-    }
-
-    public void testMipmapDrawable() {
-        new MipmapDrawable();
-        // Check the values set in the constructor
-        assertNotNull(new MipmapDrawable().getConstantState());
-        assertTrue(new MockMipmapDrawable().hasCalledOnBoundsChanged());
-    }
-
-    public void testAddDrawable() {
-        assertEquals(0, mDrawableContainerState.getChildCount());
-
-        // nothing happens if drawable is null
-        mMipmapDrawable.reset();
-        mMipmapDrawable.addDrawable(null);
-        assertEquals(0, mDrawableContainerState.getChildCount());
-        assertFalse(mMipmapDrawable.hasCalledOnBoundsChanged());
-
-        mMipmapDrawable.reset();
-        mMipmapDrawable.addDrawable(new MockDrawable());
-        assertEquals(1, mDrawableContainerState.getChildCount());
-        assertTrue(mMipmapDrawable.hasCalledOnBoundsChanged());
-
-        mMipmapDrawable.reset();
-        mMipmapDrawable.addDrawable(new MockDrawable());
-        assertEquals(2, mDrawableContainerState.getChildCount());
-        assertTrue(mMipmapDrawable.hasCalledOnBoundsChanged());
-    }
-
-    public void testSortedByHeight() {
-        Drawable small = new MockDrawable(8);
-        Drawable medium = new MockDrawable(32);
-        Drawable large = new MockDrawable(128);
-
-        mMipmapDrawable.addDrawable(medium);
-        assertSame(medium, mDrawableContainerState.getChildren()[0]);
-
-        mMipmapDrawable.addDrawable(small);
-        assertSame(small, mDrawableContainerState.getChildren()[0]);
-        assertSame(medium, mDrawableContainerState.getChildren()[1]);
-
-        mMipmapDrawable.addDrawable(large);
-        assertSame(small, mDrawableContainerState.getChildren()[0]);
-        assertSame(medium, mDrawableContainerState.getChildren()[1]);
-        assertSame(large, mDrawableContainerState.getChildren()[2]);
-
-        mMipmapDrawable.addDrawable(small);
-        assertSame(small, mDrawableContainerState.getChildren()[0]);
-        assertSame(small, mDrawableContainerState.getChildren()[1]);
-        assertSame(medium, mDrawableContainerState.getChildren()[2]);
-        assertSame(large, mDrawableContainerState.getChildren()[3]);
-
-        mMipmapDrawable.addDrawable(medium);
-        assertSame(small, mDrawableContainerState.getChildren()[0]);
-        assertSame(small, mDrawableContainerState.getChildren()[1]);
-        assertSame(medium, mDrawableContainerState.getChildren()[2]);
-        assertSame(medium, mDrawableContainerState.getChildren()[3]);
-        assertSame(large, mDrawableContainerState.getChildren()[4]);
-
-        mMipmapDrawable.addDrawable(large);
-        assertSame(small, mDrawableContainerState.getChildren()[0]);
-        assertSame(small, mDrawableContainerState.getChildren()[1]);
-        assertSame(medium, mDrawableContainerState.getChildren()[2]);
-        assertSame(medium, mDrawableContainerState.getChildren()[3]);
-        assertSame(large, mDrawableContainerState.getChildren()[4]);
-        assertSame(large, mDrawableContainerState.getChildren()[5]);
-    }
-
-    public void testSetBoundsOneItem() {
-        // the method is not called if same bounds are set
-        mMipmapDrawable.reset();
-        mMipmapDrawable.setBounds(mMipmapDrawable.getBounds());
-        assertFalse(mMipmapDrawable.hasCalledOnBoundsChanged());
-
-        // the method is called if different bounds are set, even without drawables
-        mMipmapDrawable.reset();
-        mMipmapDrawable.setBounds(new Rect(0, 0, 0, mMipmapDrawable.getBounds().height() + 1));
-        assertTrue(mMipmapDrawable.hasCalledOnBoundsChanged());
-
-        // adding an item should check bounds to see if new drawable is more appropriate
-        mMipmapDrawable.reset();
-        Drawable item = new MockDrawable(42);
-        mMipmapDrawable.addDrawable(item);
-        assertTrue(mMipmapDrawable.hasCalledOnBoundsChanged());
-
-        // the method is called if different bounds are set
-        mMipmapDrawable.setBounds(new Rect(0, 0, 0, mMipmapDrawable.getBounds().height() + 1));
-        assertTrue(mMipmapDrawable.hasCalledOnBoundsChanged());
-
-        // check that correct drawable is selected for any size.
-        mMipmapDrawable.setBounds(new Rect(0, 0, 0, item.getIntrinsicHeight() - 1));
-        assertSame(item, mMipmapDrawable.getCurrent());
-
-        mMipmapDrawable.setBounds(new Rect(0, 0, 0, item.getIntrinsicHeight()));
-        assertSame(item, mMipmapDrawable.getCurrent());
-
-        mMipmapDrawable.setBounds(new Rect(0, 0, 0, item.getIntrinsicHeight() + 1));
-        assertSame(item, mMipmapDrawable.getCurrent());
-    }
-
-    public void testSetBounds() {
-        Drawable small = new MockDrawable(8);
-        Drawable medium = new MockDrawable(32);
-        Drawable large = new MockDrawable(128);
-
-        mMipmapDrawable.addDrawable(large);
-        mMipmapDrawable.addDrawable(small);
-        mMipmapDrawable.addDrawable(medium);
-
-        // check that correct drawable is selected.
-        mMipmapDrawable.setBounds(new Rect(0, 0, 0, small.getIntrinsicHeight() - 1));
-        assertSame(small, mMipmapDrawable.getCurrent());
-
-        mMipmapDrawable.setBounds(new Rect(0, 0, 0, small.getIntrinsicHeight()));
-        assertSame(small, mMipmapDrawable.getCurrent());
-
-        mMipmapDrawable.setBounds(new Rect(0, 0, 0, small.getIntrinsicHeight() + 1));
-        assertSame(medium, mMipmapDrawable.getCurrent());
-
-        mMipmapDrawable.setBounds(new Rect(0, 0, 0, medium.getIntrinsicHeight() - 1));
-        assertSame(medium, mMipmapDrawable.getCurrent());
-
-        mMipmapDrawable.setBounds(new Rect(0, 0, 0, medium.getIntrinsicHeight()));
-        assertSame(medium, mMipmapDrawable.getCurrent());
-
-        mMipmapDrawable.setBounds(new Rect(0, 0, 0, medium.getIntrinsicHeight() + 1));
-        assertSame(large, mMipmapDrawable.getCurrent());
-
-        mMipmapDrawable.setBounds(new Rect(0, 0, 0, large.getIntrinsicHeight() - 1));
-        assertSame(large, mMipmapDrawable.getCurrent());
-
-        mMipmapDrawable.setBounds(new Rect(0, 0, 0, large.getIntrinsicHeight()));
-        assertSame(large, mMipmapDrawable.getCurrent());
-
-        mMipmapDrawable.setBounds(new Rect(0, 0, 0, large.getIntrinsicHeight() + 1));
-        assertSame(large, mMipmapDrawable.getCurrent());
-    }
-
-    public void testSizes() {
-        // Check default value with no mipmap defined
-        assertEquals(-1, mMipmapDrawable.getIntrinsicHeight());
-        assertEquals(-1, mMipmapDrawable.getIntrinsicWidth());
-        assertEquals(0, mMipmapDrawable.getMinimumHeight());
-        assertEquals(0, mMipmapDrawable.getMinimumWidth());
-
-        Drawable small = new MockDrawable(8, 4);
-        Drawable medium = new MockDrawable(32, 16);
-        Drawable large = new MockDrawable(128, 64);
-
-        mMipmapDrawable.addDrawable(medium);
-        assertEquals(medium.getIntrinsicHeight(), mMipmapDrawable.getIntrinsicHeight());
-        assertEquals(medium.getMinimumHeight(), mMipmapDrawable.getMinimumHeight());
-
-        mMipmapDrawable.addDrawable(large);
-        assertEquals(large.getIntrinsicHeight(), mMipmapDrawable.getIntrinsicHeight());
-        assertEquals(medium.getMinimumHeight(), mMipmapDrawable.getMinimumHeight());
-
-        mMipmapDrawable.addDrawable(small);
-        assertEquals(large.getIntrinsicHeight(), mMipmapDrawable.getIntrinsicHeight());
-        assertEquals(small.getMinimumHeight(), mMipmapDrawable.getMinimumHeight());
-    }
-
-    public void testReplacementWhenAdded() {
-        Drawable small = new MockDrawable(8);
-        Drawable medium = new MockDrawable(32);
-        Drawable large = new MockDrawable(128);
-
-        // Small bounds, so that the smallest mipmap should always be selected
-        mMipmapDrawable.setBounds(new Rect(0, 0, 0, 0));
-
-        // Providing smaller versions, that should immediately be used as current
-        mMipmapDrawable.addDrawable(large);
-        assertSame(large, mMipmapDrawable.getCurrent());
-
-        mMipmapDrawable.addDrawable(medium);
-        assertSame(medium, mMipmapDrawable.getCurrent());
-
-        mMipmapDrawable.addDrawable(small);
-        assertSame(small, mMipmapDrawable.getCurrent());
-    }
-
-    private class MockMipmapDrawable extends MipmapDrawable {
-        private boolean mHasCalledOnBoundsChanged;
-
-        public boolean hasCalledOnBoundsChanged() {
-            return mHasCalledOnBoundsChanged;
-        }
-
-        public void reset() {
-            mHasCalledOnBoundsChanged = false;
-        }
-
-        @Override
-        protected void onBoundsChange(Rect bounds) {
-            super.onBoundsChange(bounds);
-            mHasCalledOnBoundsChanged = true;
-        }
-    }
-
-    private class MockDrawable extends Drawable {
-        int mIntrinsicHeight;
-        int mMinimumHeight;
-
-        public MockDrawable() {
-            this(0);
-        }
-
-        public MockDrawable(int intrinsicHeight) {
-            this(intrinsicHeight, intrinsicHeight);
-        }
-
-        public MockDrawable(int intrinsicHeight, int minimumHeight) {
-            mIntrinsicHeight = intrinsicHeight;
-            mMinimumHeight = minimumHeight;
-        }
-
-        @Override
-        public void draw(Canvas canvas) {
-        }
-
-        @Override
-        public int getOpacity() {
-            return 0;
-        }
-
-        @Override
-        public void setAlpha(int alpha) {
-        }
-
-        @Override
-        public void setColorFilter(ColorFilter cf) {
-        }
-
-        @Override
-        public int getIntrinsicHeight() {
-            return mIntrinsicHeight;
-        }
-
-        @Override
-        public int getMinimumHeight() {
-            return mMinimumHeight;
-        }
-    }
-}
diff --git a/include/android_runtime/Log.h b/include/android_runtime/Log.h
new file mode 100644
index 0000000..aa6d202
--- /dev/null
+++ b/include/android_runtime/Log.h
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+#ifndef _RUNTIME_ANDROID_LOG_H
+#define _RUNTIME_ANDROID_LOG_H
+
+// This relies on JNIHelp.h
+
+/* Logging macros.
+ *
+ * Logs an exception.  If the exception is omitted or NULL, logs the current exception
+ * from the JNI environment, if any.
+ */
+#define LOG_EX(env, priority, tag, ...) \
+    jniLogException(env, ANDROID_##priority, tag, ##__VA_ARGS__)
+#define LOGV_EX(env, ...) LOG_EX(env, LOG_VERBOSE, LOG_TAG, ##__VA_ARGS__)
+#define LOGD_EX(env, ...) LOG_EX(env, LOG_DEBUG, LOG_TAG, ##__VA_ARGS__)
+#define LOGI_EX(env, ...) LOG_EX(env, LOG_INFO, LOG_TAG, ##__VA_ARGS__)
+#define LOGW_EX(env, ...) LOG_EX(env, LOG_WARN, LOG_TAG, ##__VA_ARGS__)
+#define LOGE_EX(env, ...) LOG_EX(env, LOG_ERROR, LOG_TAG, ##__VA_ARGS__)
+
+#endif // _RUNTIME_ANDROID_LOG_H
diff --git a/include/android_runtime/android_graphics_SurfaceTexture.h b/include/android_runtime/android_graphics_SurfaceTexture.h
index 77ccd2a..c534d4b 100644
--- a/include/android_runtime/android_graphics_SurfaceTexture.h
+++ b/include/android_runtime/android_graphics_SurfaceTexture.h
@@ -24,14 +24,17 @@
 namespace android {
 
 class GLConsumer;
+class IGraphicBufferProducer;
 
-extern sp<ANativeWindow> android_SurfaceTexture_getNativeWindow(
-        JNIEnv* env, jobject thiz);
+extern sp<ANativeWindow> android_SurfaceTexture_getNativeWindow(JNIEnv* env, jobject thiz);
 extern bool android_SurfaceTexture_isInstanceOf(JNIEnv* env, jobject thiz);
 
 /* Gets the underlying GLConsumer from a SurfaceTexture Java object. */
 extern sp<GLConsumer> SurfaceTexture_getSurfaceTexture(JNIEnv* env, jobject thiz);
 
+/* gets the producer end of the SurfaceTexture */
+extern sp<IGraphicBufferProducer> SurfaceTexture_getProducer(JNIEnv* env, jobject thiz);
+
 } // namespace android
 
 #endif // _ANDROID_GRAPHICS_SURFACETEXTURE_H
diff --git a/include/android_runtime/android_view_InputQueue.h b/include/android_runtime/android_view_InputQueue.h
index ba2d02d..ed37b0a 100644
--- a/include/android_runtime/android_view_InputQueue.h
+++ b/include/android_runtime/android_view_InputQueue.h
@@ -17,7 +17,7 @@
 #ifndef _ANDROID_VIEW_INPUTQUEUE_H
 #define _ANDROID_VIEW_INPUTQUEUE_H
 
-#include <androidfw/Input.h>
+#include <input/Input.h>
 #include <utils/Looper.h>
 #include <utils/TypeHelpers.h>
 #include <utils/Vector.h>
diff --git a/include/androidfw/AssetDir.h b/include/androidfw/AssetDir.h
index abf8a35..bd89d7d 100644
--- a/include/androidfw/AssetDir.h
+++ b/include/androidfw/AssetDir.h
@@ -20,10 +20,10 @@
 #ifndef __LIBS_ASSETDIR_H
 #define __LIBS_ASSETDIR_H
 
+#include <androidfw/misc.h>
 #include <utils/String8.h>
 #include <utils/Vector.h>
 #include <utils/SortedVector.h>
-#include <utils/misc.h>
 #include <sys/types.h>
 
 namespace android {
diff --git a/include/androidfw/AssetManager.h b/include/androidfw/AssetManager.h
index d153c31..d95b45e 100644
--- a/include/androidfw/AssetManager.h
+++ b/include/androidfw/AssetManager.h
@@ -22,13 +22,13 @@
 
 #include <androidfw/Asset.h>
 #include <androidfw/AssetDir.h>
+#include <androidfw/ZipFileRO.h>
 #include <utils/KeyedVector.h>
 #include <utils/SortedVector.h>
 #include <utils/String16.h>
 #include <utils/String8.h>
 #include <utils/threads.h>
 #include <utils/Vector.h>
-#include <utils/ZipFileRO.h>
 
 /*
  * Native-app access is via the opaque typedef struct AAssetManager in the C namespace.
diff --git a/include/androidfw/Input.h b/include/androidfw/Input.h
deleted file mode 100644
index 37ab279..0000000
--- a/include/androidfw/Input.h
+++ /dev/null
@@ -1,622 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _ANDROIDFW_INPUT_H
-#define _ANDROIDFW_INPUT_H
-
-/**
- * Native input event structures.
- */
-
-#include <android/input.h>
-#include <utils/Vector.h>
-#include <utils/KeyedVector.h>
-#include <utils/Timers.h>
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-
-#ifdef HAVE_ANDROID_OS
-class SkMatrix;
-#endif
-
-/*
- * Additional private constants not defined in ndk/ui/input.h.
- */
-enum {
-    /* Signifies that the key is being predispatched */
-    AKEY_EVENT_FLAG_PREDISPATCH = 0x20000000,
-
-    /* Private control to determine when an app is tracking a key sequence. */
-    AKEY_EVENT_FLAG_START_TRACKING = 0x40000000,
-
-    /* Key event is inconsistent with previously sent key events. */
-    AKEY_EVENT_FLAG_TAINTED = 0x80000000,
-};
-
-enum {
-    /* Motion event is inconsistent with previously sent motion events. */
-    AMOTION_EVENT_FLAG_TAINTED = 0x80000000,
-};
-
-enum {
-    /* Used when a motion event is not associated with any display.
-     * Typically used for non-pointer events. */
-    ADISPLAY_ID_NONE = -1,
-
-    /* The default display id. */
-    ADISPLAY_ID_DEFAULT = 0,
-};
-
-enum {
-    /*
-     * Indicates that an input device has switches.
-     * This input source flag is hidden from the API because switches are only used by the system
-     * and applications have no way to interact with them.
-     */
-    AINPUT_SOURCE_SWITCH = 0x80000000,
-};
-
-/*
- * SystemUiVisibility constants from View.
- */
-enum {
-    ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE = 0,
-    ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN = 0x00000001,
-};
-
-/*
- * Maximum number of pointers supported per motion event.
- * Smallest number of pointers is 1.
- * (We want at least 10 but some touch controllers obstensibly configured for 10 pointers
- * will occasionally emit 11.  There is not much harm making this constant bigger.)
- */
-#define MAX_POINTERS 16
-
-/*
- * Maximum pointer id value supported in a motion event.
- * Smallest pointer id is 0.
- * (This is limited by our use of BitSet32 to track pointer assignments.)
- */
-#define MAX_POINTER_ID 31
-
-/*
- * Declare a concrete type for the NDK's input event forward declaration.
- */
-struct AInputEvent {
-    virtual ~AInputEvent() { }
-};
-
-/*
- * Declare a concrete type for the NDK's input device forward declaration.
- */
-struct AInputDevice {
-    virtual ~AInputDevice() { }
-};
-
-
-namespace android {
-
-#ifdef HAVE_ANDROID_OS
-class Parcel;
-#endif
-
-/*
- * Flags that flow alongside events in the input dispatch system to help with certain
- * policy decisions such as waking from device sleep.
- *
- * These flags are also defined in frameworks/base/core/java/android/view/WindowManagerPolicy.java.
- */
-enum {
-    /* These flags originate in RawEvents and are generally set in the key map.
-     * NOTE: If you edit these flags, also edit labels in KeycodeLabels.h. */
-
-    POLICY_FLAG_WAKE = 0x00000001,
-    POLICY_FLAG_WAKE_DROPPED = 0x00000002,
-    POLICY_FLAG_SHIFT = 0x00000004,
-    POLICY_FLAG_CAPS_LOCK = 0x00000008,
-    POLICY_FLAG_ALT = 0x00000010,
-    POLICY_FLAG_ALT_GR = 0x00000020,
-    POLICY_FLAG_MENU = 0x00000040,
-    POLICY_FLAG_LAUNCHER = 0x00000080,
-    POLICY_FLAG_VIRTUAL = 0x00000100,
-    POLICY_FLAG_FUNCTION = 0x00000200,
-
-    POLICY_FLAG_RAW_MASK = 0x0000ffff,
-
-    /* These flags are set by the input dispatcher. */
-
-    // Indicates that the input event was injected.
-    POLICY_FLAG_INJECTED = 0x01000000,
-
-    // Indicates that the input event is from a trusted source such as a directly attached
-    // input device or an application with system-wide event injection permission.
-    POLICY_FLAG_TRUSTED = 0x02000000,
-
-    // Indicates that the input event has passed through an input filter.
-    POLICY_FLAG_FILTERED = 0x04000000,
-
-    // Disables automatic key repeating behavior.
-    POLICY_FLAG_DISABLE_KEY_REPEAT = 0x08000000,
-
-    /* These flags are set by the input reader policy as it intercepts each event. */
-
-    // Indicates that the screen was off when the event was received and the event
-    // should wake the device.
-    POLICY_FLAG_WOKE_HERE = 0x10000000,
-
-    // Indicates that the screen was dim when the event was received and the event
-    // should brighten the device.
-    POLICY_FLAG_BRIGHT_HERE = 0x20000000,
-
-    // Indicates that the event should be dispatched to applications.
-    // The input event should still be sent to the InputDispatcher so that it can see all
-    // input events received include those that it will not deliver.
-    POLICY_FLAG_PASS_TO_USER = 0x40000000,
-};
-
-/*
- * Pointer coordinate data.
- */
-struct PointerCoords {
-    enum { MAX_AXES = 14 }; // 14 so that sizeof(PointerCoords) == 64
-
-    // Bitfield of axes that are present in this structure.
-    uint64_t bits;
-
-    // Values of axes that are stored in this structure packed in order by axis id
-    // for each axis that is present in the structure according to 'bits'.
-    float values[MAX_AXES];
-
-    inline void clear() {
-        bits = 0;
-    }
-
-    float getAxisValue(int32_t axis) const;
-    status_t setAxisValue(int32_t axis, float value);
-
-    void scale(float scale);
-
-    inline float getX() const {
-        return getAxisValue(AMOTION_EVENT_AXIS_X);
-    }
-
-    inline float getY() const {
-        return getAxisValue(AMOTION_EVENT_AXIS_Y);
-    }
-
-#ifdef HAVE_ANDROID_OS
-    status_t readFromParcel(Parcel* parcel);
-    status_t writeToParcel(Parcel* parcel) const;
-#endif
-
-    bool operator==(const PointerCoords& other) const;
-    inline bool operator!=(const PointerCoords& other) const {
-        return !(*this == other);
-    }
-
-    void copyFrom(const PointerCoords& other);
-
-private:
-    void tooManyAxes(int axis);
-};
-
-/*
- * Pointer property data.
- */
-struct PointerProperties {
-    // The id of the pointer.
-    int32_t id;
-
-    // The pointer tool type.
-    int32_t toolType;
-
-    inline void clear() {
-        id = -1;
-        toolType = 0;
-    }
-
-    bool operator==(const PointerProperties& other) const;
-    inline bool operator!=(const PointerProperties& other) const {
-        return !(*this == other);
-    }
-
-    void copyFrom(const PointerProperties& other);
-};
-
-/*
- * Input events.
- */
-class InputEvent : public AInputEvent {
-public:
-    virtual ~InputEvent() { }
-
-    virtual int32_t getType() const = 0;
-
-    inline int32_t getDeviceId() const { return mDeviceId; }
-
-    inline int32_t getSource() const { return mSource; }
-
-    inline void setSource(int32_t source) { mSource = source; }
-
-protected:
-    void initialize(int32_t deviceId, int32_t source);
-    void initialize(const InputEvent& from);
-
-    int32_t mDeviceId;
-    int32_t mSource;
-};
-
-/*
- * Key events.
- */
-class KeyEvent : public InputEvent {
-public:
-    virtual ~KeyEvent() { }
-
-    virtual int32_t getType() const { return AINPUT_EVENT_TYPE_KEY; }
-
-    inline int32_t getAction() const { return mAction; }
-
-    inline int32_t getFlags() const { return mFlags; }
-
-    inline void setFlags(int32_t flags) { mFlags = flags; }
-
-    inline int32_t getKeyCode() const { return mKeyCode; }
-
-    inline int32_t getScanCode() const { return mScanCode; }
-
-    inline int32_t getMetaState() const { return mMetaState; }
-
-    inline int32_t getRepeatCount() const { return mRepeatCount; }
-
-    inline nsecs_t getDownTime() const { return mDownTime; }
-
-    inline nsecs_t getEventTime() const { return mEventTime; }
-
-    // Return true if this event may have a default action implementation.
-    static bool hasDefaultAction(int32_t keyCode);
-    bool hasDefaultAction() const;
-
-    // Return true if this event represents a system key.
-    static bool isSystemKey(int32_t keyCode);
-    bool isSystemKey() const;
-    
-    void initialize(
-            int32_t deviceId,
-            int32_t source,
-            int32_t action,
-            int32_t flags,
-            int32_t keyCode,
-            int32_t scanCode,
-            int32_t metaState,
-            int32_t repeatCount,
-            nsecs_t downTime,
-            nsecs_t eventTime);
-    void initialize(const KeyEvent& from);
-
-protected:
-    int32_t mAction;
-    int32_t mFlags;
-    int32_t mKeyCode;
-    int32_t mScanCode;
-    int32_t mMetaState;
-    int32_t mRepeatCount;
-    nsecs_t mDownTime;
-    nsecs_t mEventTime;
-};
-
-/*
- * Motion events.
- */
-class MotionEvent : public InputEvent {
-public:
-    virtual ~MotionEvent() { }
-
-    virtual int32_t getType() const { return AINPUT_EVENT_TYPE_MOTION; }
-
-    inline int32_t getAction() const { return mAction; }
-
-    inline int32_t getActionMasked() const { return mAction & AMOTION_EVENT_ACTION_MASK; }
-
-    inline int32_t getActionIndex() const {
-        return (mAction & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
-                >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
-    }
-
-    inline void setAction(int32_t action) { mAction = action; }
-
-    inline int32_t getFlags() const { return mFlags; }
-
-    inline void setFlags(int32_t flags) { mFlags = flags; }
-
-    inline int32_t getEdgeFlags() const { return mEdgeFlags; }
-
-    inline void setEdgeFlags(int32_t edgeFlags) { mEdgeFlags = edgeFlags; }
-
-    inline int32_t getMetaState() const { return mMetaState; }
-
-    inline void setMetaState(int32_t metaState) { mMetaState = metaState; }
-
-    inline int32_t getButtonState() const { return mButtonState; }
-
-    inline float getXOffset() const { return mXOffset; }
-
-    inline float getYOffset() const { return mYOffset; }
-
-    inline float getXPrecision() const { return mXPrecision; }
-
-    inline float getYPrecision() const { return mYPrecision; }
-
-    inline nsecs_t getDownTime() const { return mDownTime; }
-
-    inline void setDownTime(nsecs_t downTime) { mDownTime = downTime; }
-
-    inline size_t getPointerCount() const { return mPointerProperties.size(); }
-
-    inline const PointerProperties* getPointerProperties(size_t pointerIndex) const {
-        return &mPointerProperties[pointerIndex];
-    }
-
-    inline int32_t getPointerId(size_t pointerIndex) const {
-        return mPointerProperties[pointerIndex].id;
-    }
-
-    inline int32_t getToolType(size_t pointerIndex) const {
-        return mPointerProperties[pointerIndex].toolType;
-    }
-
-    inline nsecs_t getEventTime() const { return mSampleEventTimes[getHistorySize()]; }
-
-    const PointerCoords* getRawPointerCoords(size_t pointerIndex) const;
-
-    float getRawAxisValue(int32_t axis, size_t pointerIndex) const;
-
-    inline float getRawX(size_t pointerIndex) const {
-        return getRawAxisValue(AMOTION_EVENT_AXIS_X, pointerIndex);
-    }
-
-    inline float getRawY(size_t pointerIndex) const {
-        return getRawAxisValue(AMOTION_EVENT_AXIS_Y, pointerIndex);
-    }
-
-    float getAxisValue(int32_t axis, size_t pointerIndex) const;
-
-    inline float getX(size_t pointerIndex) const {
-        return getAxisValue(AMOTION_EVENT_AXIS_X, pointerIndex);
-    }
-
-    inline float getY(size_t pointerIndex) const {
-        return getAxisValue(AMOTION_EVENT_AXIS_Y, pointerIndex);
-    }
-
-    inline float getPressure(size_t pointerIndex) const {
-        return getAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pointerIndex);
-    }
-
-    inline float getSize(size_t pointerIndex) const {
-        return getAxisValue(AMOTION_EVENT_AXIS_SIZE, pointerIndex);
-    }
-
-    inline float getTouchMajor(size_t pointerIndex) const {
-        return getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, pointerIndex);
-    }
-
-    inline float getTouchMinor(size_t pointerIndex) const {
-        return getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, pointerIndex);
-    }
-
-    inline float getToolMajor(size_t pointerIndex) const {
-        return getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, pointerIndex);
-    }
-
-    inline float getToolMinor(size_t pointerIndex) const {
-        return getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, pointerIndex);
-    }
-
-    inline float getOrientation(size_t pointerIndex) const {
-        return getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, pointerIndex);
-    }
-
-    inline size_t getHistorySize() const { return mSampleEventTimes.size() - 1; }
-
-    inline nsecs_t getHistoricalEventTime(size_t historicalIndex) const {
-        return mSampleEventTimes[historicalIndex];
-    }
-
-    const PointerCoords* getHistoricalRawPointerCoords(
-            size_t pointerIndex, size_t historicalIndex) const;
-
-    float getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
-            size_t historicalIndex) const;
-
-    inline float getHistoricalRawX(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalRawAxisValue(
-                AMOTION_EVENT_AXIS_X, pointerIndex, historicalIndex);
-    }
-
-    inline float getHistoricalRawY(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalRawAxisValue(
-                AMOTION_EVENT_AXIS_Y, pointerIndex, historicalIndex);
-    }
-
-    float getHistoricalAxisValue(int32_t axis, size_t pointerIndex, size_t historicalIndex) const;
-
-    inline float getHistoricalX(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalAxisValue(
-                AMOTION_EVENT_AXIS_X, pointerIndex, historicalIndex);
-    }
-
-    inline float getHistoricalY(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalAxisValue(
-                AMOTION_EVENT_AXIS_Y, pointerIndex, historicalIndex);
-    }
-
-    inline float getHistoricalPressure(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalAxisValue(
-                AMOTION_EVENT_AXIS_PRESSURE, pointerIndex, historicalIndex);
-    }
-
-    inline float getHistoricalSize(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalAxisValue(
-                AMOTION_EVENT_AXIS_SIZE, pointerIndex, historicalIndex);
-    }
-
-    inline float getHistoricalTouchMajor(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalAxisValue(
-                AMOTION_EVENT_AXIS_TOUCH_MAJOR, pointerIndex, historicalIndex);
-    }
-
-    inline float getHistoricalTouchMinor(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalAxisValue(
-                AMOTION_EVENT_AXIS_TOUCH_MINOR, pointerIndex, historicalIndex);
-    }
-
-    inline float getHistoricalToolMajor(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalAxisValue(
-                AMOTION_EVENT_AXIS_TOOL_MAJOR, pointerIndex, historicalIndex);
-    }
-
-    inline float getHistoricalToolMinor(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalAxisValue(
-                AMOTION_EVENT_AXIS_TOOL_MINOR, pointerIndex, historicalIndex);
-    }
-
-    inline float getHistoricalOrientation(size_t pointerIndex, size_t historicalIndex) const {
-        return getHistoricalAxisValue(
-                AMOTION_EVENT_AXIS_ORIENTATION, pointerIndex, historicalIndex);
-    }
-
-    ssize_t findPointerIndex(int32_t pointerId) const;
-
-    void initialize(
-            int32_t deviceId,
-            int32_t source,
-            int32_t action,
-            int32_t flags,
-            int32_t edgeFlags,
-            int32_t metaState,
-            int32_t buttonState,
-            float xOffset,
-            float yOffset,
-            float xPrecision,
-            float yPrecision,
-            nsecs_t downTime,
-            nsecs_t eventTime,
-            size_t pointerCount,
-            const PointerProperties* pointerProperties,
-            const PointerCoords* pointerCoords);
-
-    void copyFrom(const MotionEvent* other, bool keepHistory);
-
-    void addSample(
-            nsecs_t eventTime,
-            const PointerCoords* pointerCoords);
-
-    void offsetLocation(float xOffset, float yOffset);
-
-    void scale(float scaleFactor);
-
-#ifdef HAVE_ANDROID_OS
-    void transform(const SkMatrix* matrix);
-
-    status_t readFromParcel(Parcel* parcel);
-    status_t writeToParcel(Parcel* parcel) const;
-#endif
-
-    static bool isTouchEvent(int32_t source, int32_t action);
-    inline bool isTouchEvent() const {
-        return isTouchEvent(mSource, mAction);
-    }
-
-    // Low-level accessors.
-    inline const PointerProperties* getPointerProperties() const {
-        return mPointerProperties.array();
-    }
-    inline const nsecs_t* getSampleEventTimes() const { return mSampleEventTimes.array(); }
-    inline const PointerCoords* getSamplePointerCoords() const {
-            return mSamplePointerCoords.array();
-    }
-
-protected:
-    int32_t mAction;
-    int32_t mFlags;
-    int32_t mEdgeFlags;
-    int32_t mMetaState;
-    int32_t mButtonState;
-    float mXOffset;
-    float mYOffset;
-    float mXPrecision;
-    float mYPrecision;
-    nsecs_t mDownTime;
-    Vector<PointerProperties> mPointerProperties;
-    Vector<nsecs_t> mSampleEventTimes;
-    Vector<PointerCoords> mSamplePointerCoords;
-};
-
-/*
- * Input event factory.
- */
-class InputEventFactoryInterface {
-protected:
-    virtual ~InputEventFactoryInterface() { }
-
-public:
-    InputEventFactoryInterface() { }
-
-    virtual KeyEvent* createKeyEvent() = 0;
-    virtual MotionEvent* createMotionEvent() = 0;
-};
-
-/*
- * A simple input event factory implementation that uses a single preallocated instance
- * of each type of input event that are reused for each request.
- */
-class PreallocatedInputEventFactory : public InputEventFactoryInterface {
-public:
-    PreallocatedInputEventFactory() { }
-    virtual ~PreallocatedInputEventFactory() { }
-
-    virtual KeyEvent* createKeyEvent() { return & mKeyEvent; }
-    virtual MotionEvent* createMotionEvent() { return & mMotionEvent; }
-
-private:
-    KeyEvent mKeyEvent;
-    MotionEvent mMotionEvent;
-};
-
-/*
- * An input event factory implementation that maintains a pool of input events.
- */
-class PooledInputEventFactory : public InputEventFactoryInterface {
-public:
-    PooledInputEventFactory(size_t maxPoolSize = 20);
-    virtual ~PooledInputEventFactory();
-
-    virtual KeyEvent* createKeyEvent();
-    virtual MotionEvent* createMotionEvent();
-
-    void recycle(InputEvent* event);
-
-private:
-    const size_t mMaxPoolSize;
-
-    Vector<KeyEvent*> mKeyEventPool;
-    Vector<MotionEvent*> mMotionEventPool;
-};
-
-} // namespace android
-
-#endif // _ANDROIDFW_INPUT_H
diff --git a/include/androidfw/InputDevice.h b/include/androidfw/InputDevice.h
deleted file mode 100644
index 45dc2db..0000000
--- a/include/androidfw/InputDevice.h
+++ /dev/null
@@ -1,156 +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.
- */
-
-#ifndef _ANDROIDFW_INPUT_DEVICE_H
-#define _ANDROIDFW_INPUT_DEVICE_H
-
-#include <androidfw/Input.h>
-#include <androidfw/KeyCharacterMap.h>
-
-namespace android {
-
-/*
- * Identifies a device.
- */
-struct InputDeviceIdentifier {
-    inline InputDeviceIdentifier() :
-            bus(0), vendor(0), product(0), version(0) {
-    }
-
-    // Information provided by the kernel.
-    String8 name;
-    String8 location;
-    String8 uniqueId;
-    uint16_t bus;
-    uint16_t vendor;
-    uint16_t product;
-    uint16_t version;
-
-    // A composite input device descriptor string that uniquely identifies the device
-    // even across reboots or reconnections.  The value of this field is used by
-    // upper layers of the input system to associate settings with individual devices.
-    // It is hashed from whatever kernel provided information is available.
-    // Ideally, the way this value is computed should not change between Android releases
-    // because that would invalidate persistent settings that rely on it.
-    String8 descriptor;
-};
-
-/*
- * Describes the characteristics and capabilities of an input device.
- */
-class InputDeviceInfo {
-public:
-    InputDeviceInfo();
-    InputDeviceInfo(const InputDeviceInfo& other);
-    ~InputDeviceInfo();
-
-    struct MotionRange {
-        int32_t axis;
-        uint32_t source;
-        float min;
-        float max;
-        float flat;
-        float fuzz;
-        float resolution;
-    };
-
-    void initialize(int32_t id, int32_t generation, const InputDeviceIdentifier& identifier,
-            const String8& alias, bool isExternal);
-
-    inline int32_t getId() const { return mId; }
-    inline int32_t getGeneration() const { return mGeneration; }
-    inline const InputDeviceIdentifier& getIdentifier() const { return mIdentifier; }
-    inline const String8& getAlias() const { return mAlias; }
-    inline const String8& getDisplayName() const {
-        return mAlias.isEmpty() ? mIdentifier.name : mAlias;
-    }
-    inline bool isExternal() const { return mIsExternal; }
-    inline uint32_t getSources() const { return mSources; }
-
-    const MotionRange* getMotionRange(int32_t axis, uint32_t source) const;
-
-    void addSource(uint32_t source);
-    void addMotionRange(int32_t axis, uint32_t source,
-            float min, float max, float flat, float fuzz, float resolution);
-    void addMotionRange(const MotionRange& range);
-
-    inline void setKeyboardType(int32_t keyboardType) { mKeyboardType = keyboardType; }
-    inline int32_t getKeyboardType() const { return mKeyboardType; }
-
-    inline void setKeyCharacterMap(const sp<KeyCharacterMap>& value) {
-        mKeyCharacterMap = value;
-    }
-
-    inline sp<KeyCharacterMap> getKeyCharacterMap() const {
-        return mKeyCharacterMap;
-    }
-
-    inline void setVibrator(bool hasVibrator) { mHasVibrator = hasVibrator; }
-    inline bool hasVibrator() const { return mHasVibrator; }
-
-    inline const Vector<MotionRange>& getMotionRanges() const {
-        return mMotionRanges;
-    }
-
-private:
-    int32_t mId;
-    int32_t mGeneration;
-    InputDeviceIdentifier mIdentifier;
-    String8 mAlias;
-    bool mIsExternal;
-    uint32_t mSources;
-    int32_t mKeyboardType;
-    sp<KeyCharacterMap> mKeyCharacterMap;
-    bool mHasVibrator;
-
-    Vector<MotionRange> mMotionRanges;
-};
-
-/* Types of input device configuration files. */
-enum InputDeviceConfigurationFileType {
-    INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION = 0,     /* .idc file */
-    INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_LAYOUT = 1,        /* .kl file */
-    INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_CHARACTER_MAP = 2, /* .kcm file */
-};
-
-/*
- * Gets the path of an input device configuration file, if one is available.
- * Considers both system provided and user installed configuration files.
- *
- * The device identifier is used to construct several default configuration file
- * names to try based on the device name, vendor, product, and version.
- *
- * Returns an empty string if not found.
- */
-extern String8 getInputDeviceConfigurationFilePathByDeviceIdentifier(
-        const InputDeviceIdentifier& deviceIdentifier,
-        InputDeviceConfigurationFileType type);
-
-/*
- * Gets the path of an input device configuration file, if one is available.
- * Considers both system provided and user installed configuration files.
- *
- * The name is case-sensitive and is used to construct the filename to resolve.
- * All characters except 'a'-'z', 'A'-'Z', '0'-'9', '-', and '_' are replaced by underscores.
- *
- * Returns an empty string if not found.
- */
-extern String8 getInputDeviceConfigurationFilePathByName(
-        const String8& name, InputDeviceConfigurationFileType type);
-
-} // namespace android
-
-#endif // _ANDROIDFW_INPUT_DEVICE_H
diff --git a/include/androidfw/InputTransport.h b/include/androidfw/InputTransport.h
deleted file mode 100644
index 8712995..0000000
--- a/include/androidfw/InputTransport.h
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _ANDROIDFW_INPUT_TRANSPORT_H
-#define _ANDROIDFW_INPUT_TRANSPORT_H
-
-/**
- * Native input transport.
- *
- * The InputChannel provides a mechanism for exchanging InputMessage structures across processes.
- *
- * The InputPublisher and InputConsumer each handle one end-point of an input channel.
- * The InputPublisher is used by the input dispatcher to send events to the application.
- * The InputConsumer is used by the application to receive events from the input dispatcher.
- */
-
-#include <androidfw/Input.h>
-#include <utils/Errors.h>
-#include <utils/Timers.h>
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-#include <utils/Vector.h>
-#include <utils/BitSet.h>
-
-namespace android {
-
-/*
- * Intermediate representation used to send input events and related signals.
- */
-struct InputMessage {
-    enum {
-        TYPE_KEY = 1,
-        TYPE_MOTION = 2,
-        TYPE_FINISHED = 3,
-    };
-
-    struct Header {
-        uint32_t type;
-        uint32_t padding; // 8 byte alignment for the body that follows
-    } header;
-
-    union Body {
-        struct Key {
-            uint32_t seq;
-            nsecs_t eventTime;
-            int32_t deviceId;
-            int32_t source;
-            int32_t action;
-            int32_t flags;
-            int32_t keyCode;
-            int32_t scanCode;
-            int32_t metaState;
-            int32_t repeatCount;
-            nsecs_t downTime;
-
-            inline size_t size() const {
-                return sizeof(Key);
-            }
-        } key;
-
-        struct Motion {
-            uint32_t seq;
-            nsecs_t eventTime;
-            int32_t deviceId;
-            int32_t source;
-            int32_t action;
-            int32_t flags;
-            int32_t metaState;
-            int32_t buttonState;
-            int32_t edgeFlags;
-            nsecs_t downTime;
-            float xOffset;
-            float yOffset;
-            float xPrecision;
-            float yPrecision;
-            size_t pointerCount;
-            struct Pointer {
-                PointerProperties properties;
-                PointerCoords coords;
-            } pointers[MAX_POINTERS];
-
-            int32_t getActionId() const {
-                uint32_t index = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
-                        >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
-                return pointers[index].properties.id;
-            }
-
-            inline size_t size() const {
-                return sizeof(Motion) - sizeof(Pointer) * MAX_POINTERS
-                        + sizeof(Pointer) * pointerCount;
-            }
-        } motion;
-
-        struct Finished {
-            uint32_t seq;
-            bool handled;
-
-            inline size_t size() const {
-                return sizeof(Finished);
-            }
-        } finished;
-    } body;
-
-    bool isValid(size_t actualSize) const;
-    size_t size() const;
-};
-
-/*
- * An input channel consists of a local unix domain socket used to send and receive
- * input messages across processes.  Each channel has a descriptive name for debugging purposes.
- *
- * Each endpoint has its own InputChannel object that specifies its file descriptor.
- *
- * The input channel is closed when all references to it are released.
- */
-class InputChannel : public RefBase {
-protected:
-    virtual ~InputChannel();
-
-public:
-    InputChannel(const String8& name, int fd);
-
-    /* Creates a pair of input channels.
-     *
-     * Returns OK on success.
-     */
-    static status_t openInputChannelPair(const String8& name,
-            sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel);
-
-    inline String8 getName() const { return mName; }
-    inline int getFd() const { return mFd; }
-
-    /* Sends a message to the other endpoint.
-     *
-     * If the channel is full then the message is guaranteed not to have been sent at all.
-     * Try again after the consumer has sent a finished signal indicating that it has
-     * consumed some of the pending messages from the channel.
-     *
-     * Returns OK on success.
-     * Returns WOULD_BLOCK if the channel is full.
-     * Returns DEAD_OBJECT if the channel's peer has been closed.
-     * Other errors probably indicate that the channel is broken.
-     */
-    status_t sendMessage(const InputMessage* msg);
-
-    /* Receives a message sent by the other endpoint.
-     *
-     * If there is no message present, try again after poll() indicates that the fd
-     * is readable.
-     *
-     * Returns OK on success.
-     * Returns WOULD_BLOCK if there is no message present.
-     * Returns DEAD_OBJECT if the channel's peer has been closed.
-     * Other errors probably indicate that the channel is broken.
-     */
-    status_t receiveMessage(InputMessage* msg);
-
-    /* Returns a new object that has a duplicate of this channel's fd. */
-    sp<InputChannel> dup() const;
-
-private:
-    String8 mName;
-    int mFd;
-};
-
-/*
- * Publishes input events to an input channel.
- */
-class InputPublisher {
-public:
-    /* Creates a publisher associated with an input channel. */
-    explicit InputPublisher(const sp<InputChannel>& channel);
-
-    /* Destroys the publisher and releases its input channel. */
-    ~InputPublisher();
-
-    /* Gets the underlying input channel. */
-    inline sp<InputChannel> getChannel() { return mChannel; }
-
-    /* Publishes a key event to the input channel.
-     *
-     * Returns OK on success.
-     * Returns WOULD_BLOCK if the channel is full.
-     * Returns DEAD_OBJECT if the channel's peer has been closed.
-     * Returns BAD_VALUE if seq is 0.
-     * Other errors probably indicate that the channel is broken.
-     */
-    status_t publishKeyEvent(
-            uint32_t seq,
-            int32_t deviceId,
-            int32_t source,
-            int32_t action,
-            int32_t flags,
-            int32_t keyCode,
-            int32_t scanCode,
-            int32_t metaState,
-            int32_t repeatCount,
-            nsecs_t downTime,
-            nsecs_t eventTime);
-
-    /* Publishes a motion event to the input channel.
-     *
-     * Returns OK on success.
-     * Returns WOULD_BLOCK if the channel is full.
-     * Returns DEAD_OBJECT if the channel's peer has been closed.
-     * Returns BAD_VALUE if seq is 0 or if pointerCount is less than 1 or greater than MAX_POINTERS.
-     * Other errors probably indicate that the channel is broken.
-     */
-    status_t publishMotionEvent(
-            uint32_t seq,
-            int32_t deviceId,
-            int32_t source,
-            int32_t action,
-            int32_t flags,
-            int32_t edgeFlags,
-            int32_t metaState,
-            int32_t buttonState,
-            float xOffset,
-            float yOffset,
-            float xPrecision,
-            float yPrecision,
-            nsecs_t downTime,
-            nsecs_t eventTime,
-            size_t pointerCount,
-            const PointerProperties* pointerProperties,
-            const PointerCoords* pointerCoords);
-
-    /* Receives the finished signal from the consumer in reply to the original dispatch signal.
-     * If a signal was received, returns the message sequence number,
-     * and whether the consumer handled the message.
-     *
-     * The returned sequence number is never 0 unless the operation failed.
-     *
-     * Returns OK on success.
-     * Returns WOULD_BLOCK if there is no signal present.
-     * Returns DEAD_OBJECT if the channel's peer has been closed.
-     * Other errors probably indicate that the channel is broken.
-     */
-    status_t receiveFinishedSignal(uint32_t* outSeq, bool* outHandled);
-
-private:
-    sp<InputChannel> mChannel;
-};
-
-/*
- * Consumes input events from an input channel.
- */
-class InputConsumer {
-public:
-    /* Creates a consumer associated with an input channel. */
-    explicit InputConsumer(const sp<InputChannel>& channel);
-
-    /* Destroys the consumer and releases its input channel. */
-    ~InputConsumer();
-
-    /* Gets the underlying input channel. */
-    inline sp<InputChannel> getChannel() { return mChannel; }
-
-    /* Consumes an input event from the input channel and copies its contents into
-     * an InputEvent object created using the specified factory.
-     *
-     * Tries to combine a series of move events into larger batches whenever possible.
-     *
-     * If consumeBatches is false, then defers consuming pending batched events if it
-     * is possible for additional samples to be added to them later.  Call hasPendingBatch()
-     * to determine whether a pending batch is available to be consumed.
-     *
-     * If consumeBatches is true, then events are still batched but they are consumed
-     * immediately as soon as the input channel is exhausted.
-     *
-     * The frameTime parameter specifies the time when the current display frame started
-     * rendering in the CLOCK_MONOTONIC time base, or -1 if unknown.
-     *
-     * The returned sequence number is never 0 unless the operation failed.
-     *
-     * Returns OK on success.
-     * Returns WOULD_BLOCK if there is no event present.
-     * Returns DEAD_OBJECT if the channel's peer has been closed.
-     * Returns NO_MEMORY if the event could not be created.
-     * Other errors probably indicate that the channel is broken.
-     */
-    status_t consume(InputEventFactoryInterface* factory, bool consumeBatches,
-            nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent);
-
-    /* Sends a finished signal to the publisher to inform it that the message
-     * with the specified sequence number has finished being process and whether
-     * the message was handled by the consumer.
-     *
-     * Returns OK on success.
-     * Returns BAD_VALUE if seq is 0.
-     * Other errors probably indicate that the channel is broken.
-     */
-    status_t sendFinishedSignal(uint32_t seq, bool handled);
-
-    /* Returns true if there is a deferred event waiting.
-     *
-     * Should be called after calling consume() to determine whether the consumer
-     * has a deferred event to be processed.  Deferred events are somewhat special in
-     * that they have already been removed from the input channel.  If the input channel
-     * becomes empty, the client may need to do extra work to ensure that it processes
-     * the deferred event despite the fact that the input channel's file descriptor
-     * is not readable.
-     *
-     * One option is simply to call consume() in a loop until it returns WOULD_BLOCK.
-     * This guarantees that all deferred events will be processed.
-     *
-     * Alternately, the caller can call hasDeferredEvent() to determine whether there is
-     * a deferred event waiting and then ensure that its event loop wakes up at least
-     * one more time to consume the deferred event.
-     */
-    bool hasDeferredEvent() const;
-
-    /* Returns true if there is a pending batch.
-     *
-     * Should be called after calling consume() with consumeBatches == false to determine
-     * whether consume() should be called again later on with consumeBatches == true.
-     */
-    bool hasPendingBatch() const;
-
-private:
-    // True if touch resampling is enabled.
-    const bool mResampleTouch;
-
-    // The input channel.
-    sp<InputChannel> mChannel;
-
-    // The current input message.
-    InputMessage mMsg;
-
-    // True if mMsg contains a valid input message that was deferred from the previous
-    // call to consume and that still needs to be handled.
-    bool mMsgDeferred;
-
-    // Batched motion events per device and source.
-    struct Batch {
-        Vector<InputMessage> samples;
-    };
-    Vector<Batch> mBatches;
-
-    // Touch state per device and source, only for sources of class pointer.
-    struct History {
-        nsecs_t eventTime;
-        BitSet32 idBits;
-        int32_t idToIndex[MAX_POINTER_ID + 1];
-        PointerCoords pointers[MAX_POINTERS];
-
-        void initializeFrom(const InputMessage* msg) {
-            eventTime = msg->body.motion.eventTime;
-            idBits.clear();
-            for (size_t i = 0; i < msg->body.motion.pointerCount; i++) {
-                uint32_t id = msg->body.motion.pointers[i].properties.id;
-                idBits.markBit(id);
-                idToIndex[id] = i;
-                pointers[i].copyFrom(msg->body.motion.pointers[i].coords);
-            }
-        }
-
-        const PointerCoords& getPointerById(uint32_t id) const {
-            return pointers[idToIndex[id]];
-        }
-    };
-    struct TouchState {
-        int32_t deviceId;
-        int32_t source;
-        size_t historyCurrent;
-        size_t historySize;
-        History history[2];
-        History lastResample;
-
-        void initialize(int32_t deviceId, int32_t source) {
-            this->deviceId = deviceId;
-            this->source = source;
-            historyCurrent = 0;
-            historySize = 0;
-            lastResample.eventTime = 0;
-            lastResample.idBits.clear();
-        }
-
-        void addHistory(const InputMessage* msg) {
-            historyCurrent ^= 1;
-            if (historySize < 2) {
-                historySize += 1;
-            }
-            history[historyCurrent].initializeFrom(msg);
-        }
-
-        const History* getHistory(size_t index) const {
-            return &history[(historyCurrent + index) & 1];
-        }
-    };
-    Vector<TouchState> mTouchStates;
-
-    // Chain of batched sequence numbers.  When multiple input messages are combined into
-    // a batch, we append a record here that associates the last sequence number in the
-    // batch with the previous one.  When the finished signal is sent, we traverse the
-    // chain to individually finish all input messages that were part of the batch.
-    struct SeqChain {
-        uint32_t seq;   // sequence number of batched input message
-        uint32_t chain; // sequence number of previous batched input message
-    };
-    Vector<SeqChain> mSeqChains;
-
-    status_t consumeBatch(InputEventFactoryInterface* factory,
-            nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent);
-    status_t consumeSamples(InputEventFactoryInterface* factory,
-            Batch& batch, size_t count, uint32_t* outSeq, InputEvent** outEvent);
-
-    void updateTouchState(InputMessage* msg);
-    void rewriteMessage(const TouchState& state, InputMessage* msg);
-    void resampleTouchState(nsecs_t frameTime, MotionEvent* event,
-            const InputMessage *next);
-
-    ssize_t findBatch(int32_t deviceId, int32_t source) const;
-    ssize_t findTouchState(int32_t deviceId, int32_t source) const;
-
-    status_t sendUnchainedFinishedSignal(uint32_t seq, bool handled);
-
-    static void initializeKeyEvent(KeyEvent* event, const InputMessage* msg);
-    static void initializeMotionEvent(MotionEvent* event, const InputMessage* msg);
-    static void addSample(MotionEvent* event, const InputMessage* msg);
-    static bool canAddSample(const Batch& batch, const InputMessage* msg);
-    static ssize_t findSampleNoLaterThan(const Batch& batch, nsecs_t time);
-    static bool shouldResampleTool(int32_t toolType);
-
-    static bool isTouchResamplingEnabled();
-};
-
-} // namespace android
-
-#endif // _ANDROIDFW_INPUT_TRANSPORT_H
diff --git a/include/androidfw/KeyCharacterMap.h b/include/androidfw/KeyCharacterMap.h
deleted file mode 100644
index 06799f9..0000000
--- a/include/androidfw/KeyCharacterMap.h
+++ /dev/null
@@ -1,257 +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.
- */
-
-#ifndef _ANDROIDFW_KEY_CHARACTER_MAP_H
-#define _ANDROIDFW_KEY_CHARACTER_MAP_H
-
-#include <stdint.h>
-
-#if HAVE_ANDROID_OS
-#include <binder/IBinder.h>
-#endif
-
-#include <androidfw/Input.h>
-#include <utils/Errors.h>
-#include <utils/KeyedVector.h>
-#include <utils/Tokenizer.h>
-#include <utils/String8.h>
-#include <utils/Unicode.h>
-#include <utils/RefBase.h>
-
-namespace android {
-
-/**
- * Describes a mapping from Android key codes to characters.
- * Also specifies other functions of the keyboard such as the keyboard type
- * and key modifier semantics.
- *
- * This object is immutable after it has been loaded.
- */
-class KeyCharacterMap : public RefBase {
-public:
-    enum KeyboardType {
-        KEYBOARD_TYPE_UNKNOWN = 0,
-        KEYBOARD_TYPE_NUMERIC = 1,
-        KEYBOARD_TYPE_PREDICTIVE = 2,
-        KEYBOARD_TYPE_ALPHA = 3,
-        KEYBOARD_TYPE_FULL = 4,
-        KEYBOARD_TYPE_SPECIAL_FUNCTION = 5,
-        KEYBOARD_TYPE_OVERLAY = 6,
-    };
-
-    enum Format {
-        // Base keyboard layout, may contain device-specific options, such as "type" declaration.
-        FORMAT_BASE = 0,
-        // Overlay keyboard layout, more restrictive, may be published by applications,
-        // cannot override device-specific options.
-        FORMAT_OVERLAY = 1,
-        // Either base or overlay layout ok.
-        FORMAT_ANY = 2,
-    };
-
-    // Substitute key code and meta state for fallback action.
-    struct FallbackAction {
-        int32_t keyCode;
-        int32_t metaState;
-    };
-
-    /* Loads a key character map from a file. */
-    static status_t load(const String8& filename, Format format, sp<KeyCharacterMap>* outMap);
-
-    /* Loads a key character map from its string contents. */
-    static status_t loadContents(const String8& filename,
-            const char* contents, Format format, sp<KeyCharacterMap>* outMap);
-
-    /* Combines a base key character map and an overlay. */
-    static sp<KeyCharacterMap> combine(const sp<KeyCharacterMap>& base,
-            const sp<KeyCharacterMap>& overlay);
-
-    /* Returns an empty key character map. */
-    static sp<KeyCharacterMap> empty();
-
-    /* Gets the keyboard type. */
-    int32_t getKeyboardType() const;
-
-    /* Gets the primary character for this key as in the label physically printed on it.
-     * Returns 0 if none (eg. for non-printing keys). */
-    char16_t getDisplayLabel(int32_t keyCode) const;
-
-    /* Gets the Unicode character for the number or symbol generated by the key
-     * when the keyboard is used as a dialing pad.
-     * Returns 0 if no number or symbol is generated.
-     */
-    char16_t getNumber(int32_t keyCode) const;
-
-    /* Gets the Unicode character generated by the key and meta key modifiers.
-     * Returns 0 if no character is generated.
-     */
-    char16_t getCharacter(int32_t keyCode, int32_t metaState) const;
-
-    /* Gets the fallback action to use by default if the application does not
-     * handle the specified key.
-     * Returns true if an action was available, false if none.
-     */
-    bool getFallbackAction(int32_t keyCode, int32_t metaState,
-            FallbackAction* outFallbackAction) const;
-
-    /* Gets the first matching Unicode character that can be generated by the key,
-     * preferring the one with the specified meta key modifiers.
-     * Returns 0 if no matching character is generated.
-     */
-    char16_t getMatch(int32_t keyCode, const char16_t* chars,
-            size_t numChars, int32_t metaState) const;
-
-    /* Gets a sequence of key events that could plausibly generate the specified
-     * character sequence.  Returns false if some of the characters cannot be generated.
-     */
-    bool getEvents(int32_t deviceId, const char16_t* chars, size_t numChars,
-            Vector<KeyEvent>& outEvents) const;
-
-    /* Maps a scan code and usage code to a key code, in case this key map overrides
-     * the mapping in some way. */
-    status_t mapKey(int32_t scanCode, int32_t usageCode, int32_t* outKeyCode) const;
-
-#if HAVE_ANDROID_OS
-    /* Reads a key map from a parcel. */
-    static sp<KeyCharacterMap> readFromParcel(Parcel* parcel);
-
-    /* Writes a key map to a parcel. */
-    void writeToParcel(Parcel* parcel) const;
-#endif
-
-protected:
-    virtual ~KeyCharacterMap();
-
-private:
-    struct Behavior {
-        Behavior();
-        Behavior(const Behavior& other);
-
-        /* The next behavior in the list, or NULL if none. */
-        Behavior* next;
-
-        /* The meta key modifiers for this behavior. */
-        int32_t metaState;
-
-        /* The character to insert. */
-        char16_t character;
-
-        /* The fallback keycode if the key is not handled. */
-        int32_t fallbackKeyCode;
-    };
-
-    struct Key {
-        Key();
-        Key(const Key& other);
-        ~Key();
-
-        /* The single character label printed on the key, or 0 if none. */
-        char16_t label;
-
-        /* The number or symbol character generated by the key, or 0 if none. */
-        char16_t number;
-
-        /* The list of key behaviors sorted from most specific to least specific
-         * meta key binding. */
-        Behavior* firstBehavior;
-    };
-
-    class Parser {
-        enum State {
-            STATE_TOP = 0,
-            STATE_KEY = 1,
-        };
-
-        enum {
-            PROPERTY_LABEL = 1,
-            PROPERTY_NUMBER = 2,
-            PROPERTY_META = 3,
-        };
-
-        struct Property {
-            inline Property(int32_t property = 0, int32_t metaState = 0) :
-                    property(property), metaState(metaState) { }
-
-            int32_t property;
-            int32_t metaState;
-        };
-
-        KeyCharacterMap* mMap;
-        Tokenizer* mTokenizer;
-        Format mFormat;
-        State mState;
-        int32_t mKeyCode;
-
-    public:
-        Parser(KeyCharacterMap* map, Tokenizer* tokenizer, Format format);
-        ~Parser();
-        status_t parse();
-
-    private:
-        status_t parseType();
-        status_t parseMap();
-        status_t parseMapKey();
-        status_t parseKey();
-        status_t parseKeyProperty();
-        status_t finishKey(Key* key);
-        status_t parseModifier(const String8& token, int32_t* outMetaState);
-        status_t parseCharacterLiteral(char16_t* outCharacter);
-    };
-
-    static sp<KeyCharacterMap> sEmpty;
-
-    KeyedVector<int32_t, Key*> mKeys;
-    int mType;
-
-    KeyedVector<int32_t, int32_t> mKeysByScanCode;
-    KeyedVector<int32_t, int32_t> mKeysByUsageCode;
-
-    KeyCharacterMap();
-    KeyCharacterMap(const KeyCharacterMap& other);
-
-    bool getKey(int32_t keyCode, const Key** outKey) const;
-    bool getKeyBehavior(int32_t keyCode, int32_t metaState,
-            const Key** outKey, const Behavior** outBehavior) const;
-    static bool matchesMetaState(int32_t eventMetaState, int32_t behaviorMetaState);
-
-    bool findKey(char16_t ch, int32_t* outKeyCode, int32_t* outMetaState) const;
-
-    static status_t load(Tokenizer* tokenizer, Format format, sp<KeyCharacterMap>* outMap);
-
-    static void addKey(Vector<KeyEvent>& outEvents,
-            int32_t deviceId, int32_t keyCode, int32_t metaState, bool down, nsecs_t time);
-    static void addMetaKeys(Vector<KeyEvent>& outEvents,
-            int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
-            int32_t* currentMetaState);
-    static bool addSingleEphemeralMetaKey(Vector<KeyEvent>& outEvents,
-            int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
-            int32_t keyCode, int32_t keyMetaState,
-            int32_t* currentMetaState);
-    static void addDoubleEphemeralMetaKey(Vector<KeyEvent>& outEvents,
-            int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
-            int32_t leftKeyCode, int32_t leftKeyMetaState,
-            int32_t rightKeyCode, int32_t rightKeyMetaState,
-            int32_t eitherKeyMetaState,
-            int32_t* currentMetaState);
-    static void addLockedMetaKey(Vector<KeyEvent>& outEvents,
-            int32_t deviceId, int32_t metaState, nsecs_t time,
-            int32_t keyCode, int32_t keyMetaState,
-            int32_t* currentMetaState);
-};
-
-} // namespace android
-
-#endif // _ANDROIDFW_KEY_CHARACTER_MAP_H
diff --git a/include/androidfw/KeyLayoutMap.h b/include/androidfw/KeyLayoutMap.h
deleted file mode 100644
index e7f22a2..0000000
--- a/include/androidfw/KeyLayoutMap.h
+++ /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.
- */
-
-#ifndef _ANDROIDFW_KEY_LAYOUT_MAP_H
-#define _ANDROIDFW_KEY_LAYOUT_MAP_H
-
-#include <stdint.h>
-#include <utils/Errors.h>
-#include <utils/KeyedVector.h>
-#include <utils/Tokenizer.h>
-#include <utils/RefBase.h>
-
-namespace android {
-
-struct AxisInfo {
-    enum Mode {
-        // Axis value is reported directly.
-        MODE_NORMAL = 0,
-        // Axis value should be inverted before reporting.
-        MODE_INVERT = 1,
-        // Axis value should be split into two axes
-        MODE_SPLIT = 2,
-    };
-
-    // Axis mode.
-    Mode mode;
-
-    // Axis id.
-    // When split, this is the axis used for values smaller than the split position.
-    int32_t axis;
-
-    // When split, this is the axis used for values after higher than the split position.
-    int32_t highAxis;
-
-    // The split value, or 0 if not split.
-    int32_t splitValue;
-
-    // The flat value, or -1 if none.
-    int32_t flatOverride;
-
-    AxisInfo() : mode(MODE_NORMAL), axis(-1), highAxis(-1), splitValue(0), flatOverride(-1) {
-    }
-};
-
-/**
- * Describes a mapping from keyboard scan codes and joystick axes to Android key codes and axes.
- *
- * This object is immutable after it has been loaded.
- */
-class KeyLayoutMap : public RefBase {
-public:
-    static status_t load(const String8& filename, sp<KeyLayoutMap>* outMap);
-
-    status_t mapKey(int32_t scanCode, int32_t usageCode,
-            int32_t* outKeyCode, uint32_t* outFlags) const;
-    status_t findScanCodesForKey(int32_t keyCode, Vector<int32_t>* outScanCodes) const;
-
-    status_t mapAxis(int32_t scanCode, AxisInfo* outAxisInfo) const;
-
-protected:
-    virtual ~KeyLayoutMap();
-
-private:
-    struct Key {
-        int32_t keyCode;
-        uint32_t flags;
-    };
-
-    KeyedVector<int32_t, Key> mKeysByScanCode;
-    KeyedVector<int32_t, Key> mKeysByUsageCode;
-    KeyedVector<int32_t, AxisInfo> mAxes;
-
-    KeyLayoutMap();
-
-    const Key* getKey(int32_t scanCode, int32_t usageCode) const;
-
-    class Parser {
-        KeyLayoutMap* mMap;
-        Tokenizer* mTokenizer;
-
-    public:
-        Parser(KeyLayoutMap* map, Tokenizer* tokenizer);
-        ~Parser();
-        status_t parse();
-
-    private:
-        status_t parseKey();
-        status_t parseAxis();
-    };
-};
-
-} // namespace android
-
-#endif // _ANDROIDFW_KEY_LAYOUT_MAP_H
diff --git a/include/androidfw/Keyboard.h b/include/androidfw/Keyboard.h
deleted file mode 100644
index 6537a8f..0000000
--- a/include/androidfw/Keyboard.h
+++ /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.
- */
-
-#ifndef _ANDROIDFW_KEYBOARD_H
-#define _ANDROIDFW_KEYBOARD_H
-
-#include <androidfw/Input.h>
-#include <androidfw/InputDevice.h>
-#include <utils/Errors.h>
-#include <utils/String8.h>
-#include <utils/PropertyMap.h>
-
-namespace android {
-
-enum {
-    /* Device id of the built in keyboard. */
-    DEVICE_ID_BUILT_IN_KEYBOARD = 0,
-
-    /* Device id of a generic virtual keyboard with a full layout that can be used
-     * to synthesize key events. */
-    DEVICE_ID_VIRTUAL_KEYBOARD = -1,
-};
-
-class KeyLayoutMap;
-class KeyCharacterMap;
-
-/**
- * Loads the key layout map and key character map for a keyboard device.
- */
-class KeyMap {
-public:
-    String8 keyLayoutFile;
-    sp<KeyLayoutMap> keyLayoutMap;
-
-    String8 keyCharacterMapFile;
-    sp<KeyCharacterMap> keyCharacterMap;
-
-    KeyMap();
-    ~KeyMap();
-
-    status_t load(const InputDeviceIdentifier& deviceIdenfier,
-            const PropertyMap* deviceConfiguration);
-
-    inline bool haveKeyLayout() const {
-        return !keyLayoutFile.isEmpty();
-    }
-
-    inline bool haveKeyCharacterMap() const {
-        return !keyCharacterMapFile.isEmpty();
-    }
-
-    inline bool isComplete() const {
-        return haveKeyLayout() && haveKeyCharacterMap();
-    }
-
-private:
-    bool probeKeyMap(const InputDeviceIdentifier& deviceIdentifier, const String8& name);
-    status_t loadKeyLayout(const InputDeviceIdentifier& deviceIdentifier, const String8& name);
-    status_t loadKeyCharacterMap(const InputDeviceIdentifier& deviceIdentifier,
-            const String8& name);
-    String8 getPath(const InputDeviceIdentifier& deviceIdentifier,
-            const String8& name, InputDeviceConfigurationFileType type);
-};
-
-/**
- * Returns true if the keyboard is eligible for use as a built-in keyboard.
- */
-extern bool isEligibleBuiltInKeyboard(const InputDeviceIdentifier& deviceIdentifier,
-        const PropertyMap* deviceConfiguration, const KeyMap* keyMap);
-
-/**
- * Gets a key code by its short form label, eg. "HOME".
- * Returns 0 if unknown.
- */
-extern int32_t getKeyCodeByLabel(const char* label);
-
-/**
- * Gets a key flag by its short form label, eg. "WAKE".
- * Returns 0 if unknown.
- */
-extern uint32_t getKeyFlagByLabel(const char* label);
-
-/**
- * Gets a axis by its short form label, eg. "X".
- * Returns -1 if unknown.
- */
-extern int32_t getAxisByLabel(const char* label);
-
-/**
- * Gets a axis label by its id.
- * Returns NULL if unknown.
- */
-extern const char* getAxisLabel(int32_t axisId);
-
-/**
- * Updates a meta state field when a key is pressed or released.
- */
-extern int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState);
-
-/**
- * Returns true if a key is a meta key like ALT or CAPS_LOCK.
- */
-extern bool isMetaKey(int32_t keyCode);
-
-} // namespace android
-
-#endif // _ANDROIDFW_KEYBOARD_H
diff --git a/include/androidfw/KeycodeLabels.h b/include/androidfw/KeycodeLabels.h
deleted file mode 100644
index 3e12f26..0000000
--- a/include/androidfw/KeycodeLabels.h
+++ /dev/null
@@ -1,321 +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.
- */
-
-#ifndef _ANDROIDFW_KEYCODE_LABELS_H
-#define _ANDROIDFW_KEYCODE_LABELS_H
-
-#include <android/keycodes.h>
-
-struct KeycodeLabel {
-    const char *literal;
-    int value;
-};
-
-static const KeycodeLabel KEYCODES[] = {
-    { "SOFT_LEFT", 1 },
-    { "SOFT_RIGHT", 2 },
-    { "HOME", 3 },
-    { "BACK", 4 },
-    { "CALL", 5 },
-    { "ENDCALL", 6 },
-    { "0", 7 },
-    { "1", 8 },
-    { "2", 9 },
-    { "3", 10 },
-    { "4", 11 },
-    { "5", 12 },
-    { "6", 13 },
-    { "7", 14 },
-    { "8", 15 },
-    { "9", 16 },
-    { "STAR", 17 },
-    { "POUND", 18 },
-    { "DPAD_UP", 19 },
-    { "DPAD_DOWN", 20 },
-    { "DPAD_LEFT", 21 },
-    { "DPAD_RIGHT", 22 },
-    { "DPAD_CENTER", 23 },
-    { "VOLUME_UP", 24 },
-    { "VOLUME_DOWN", 25 },
-    { "POWER", 26 },
-    { "CAMERA", 27 },
-    { "CLEAR", 28 },
-    { "A", 29 },
-    { "B", 30 },
-    { "C", 31 },
-    { "D", 32 },
-    { "E", 33 },
-    { "F", 34 },
-    { "G", 35 },
-    { "H", 36 },
-    { "I", 37 },
-    { "J", 38 },
-    { "K", 39 },
-    { "L", 40 },
-    { "M", 41 },
-    { "N", 42 },
-    { "O", 43 },
-    { "P", 44 },
-    { "Q", 45 },
-    { "R", 46 },
-    { "S", 47 },
-    { "T", 48 },
-    { "U", 49 },
-    { "V", 50 },
-    { "W", 51 },
-    { "X", 52 },
-    { "Y", 53 },
-    { "Z", 54 },
-    { "COMMA", 55 },
-    { "PERIOD", 56 },
-    { "ALT_LEFT", 57 },
-    { "ALT_RIGHT", 58 },
-    { "SHIFT_LEFT", 59 },
-    { "SHIFT_RIGHT", 60 },
-    { "TAB", 61 },
-    { "SPACE", 62 },
-    { "SYM", 63 },
-    { "EXPLORER", 64 },
-    { "ENVELOPE", 65 },
-    { "ENTER", 66 },
-    { "DEL", 67 },
-    { "GRAVE", 68 },
-    { "MINUS", 69 },
-    { "EQUALS", 70 },
-    { "LEFT_BRACKET", 71 },
-    { "RIGHT_BRACKET", 72 },
-    { "BACKSLASH", 73 },
-    { "SEMICOLON", 74 },
-    { "APOSTROPHE", 75 },
-    { "SLASH", 76 },
-    { "AT", 77 },
-    { "NUM", 78 },
-    { "HEADSETHOOK", 79 },
-    { "FOCUS", 80 },
-    { "PLUS", 81 },
-    { "MENU", 82 },
-    { "NOTIFICATION", 83 },
-    { "SEARCH", 84 },
-    { "MEDIA_PLAY_PAUSE", 85 },
-    { "MEDIA_STOP", 86 },
-    { "MEDIA_NEXT", 87 },
-    { "MEDIA_PREVIOUS", 88 },
-    { "MEDIA_REWIND", 89 },
-    { "MEDIA_FAST_FORWARD", 90 },
-    { "MUTE", 91 },
-    { "PAGE_UP", 92 },
-    { "PAGE_DOWN", 93 },
-    { "PICTSYMBOLS", 94 },
-    { "SWITCH_CHARSET", 95 },
-    { "BUTTON_A", 96 },
-    { "BUTTON_B", 97 },
-    { "BUTTON_C", 98 },
-    { "BUTTON_X", 99 },
-    { "BUTTON_Y", 100 },
-    { "BUTTON_Z", 101 },
-    { "BUTTON_L1", 102 },
-    { "BUTTON_R1", 103 },
-    { "BUTTON_L2", 104 },
-    { "BUTTON_R2", 105 },
-    { "BUTTON_THUMBL", 106 },
-    { "BUTTON_THUMBR", 107 },
-    { "BUTTON_START", 108 },
-    { "BUTTON_SELECT", 109 },
-    { "BUTTON_MODE", 110 },
-    { "ESCAPE", 111 },
-    { "FORWARD_DEL", 112 },
-    { "CTRL_LEFT", 113 },
-    { "CTRL_RIGHT", 114 },
-    { "CAPS_LOCK", 115 },
-    { "SCROLL_LOCK", 116 },
-    { "META_LEFT", 117 },
-    { "META_RIGHT", 118 },
-    { "FUNCTION", 119 },
-    { "SYSRQ", 120 },
-    { "BREAK", 121 },
-    { "MOVE_HOME", 122 },
-    { "MOVE_END", 123 },
-    { "INSERT", 124 },
-    { "FORWARD", 125 },
-    { "MEDIA_PLAY", 126 },
-    { "MEDIA_PAUSE", 127 },
-    { "MEDIA_CLOSE", 128 },
-    { "MEDIA_EJECT", 129 },
-    { "MEDIA_RECORD", 130 },
-    { "F1", 131 },
-    { "F2", 132 },
-    { "F3", 133 },
-    { "F4", 134 },
-    { "F5", 135 },
-    { "F6", 136 },
-    { "F7", 137 },
-    { "F8", 138 },
-    { "F9", 139 },
-    { "F10", 140 },
-    { "F11", 141 },
-    { "F12", 142 },
-    { "NUM_LOCK", 143 },
-    { "NUMPAD_0", 144 },
-    { "NUMPAD_1", 145 },
-    { "NUMPAD_2", 146 },
-    { "NUMPAD_3", 147 },
-    { "NUMPAD_4", 148 },
-    { "NUMPAD_5", 149 },
-    { "NUMPAD_6", 150 },
-    { "NUMPAD_7", 151 },
-    { "NUMPAD_8", 152 },
-    { "NUMPAD_9", 153 },
-    { "NUMPAD_DIVIDE", 154 },
-    { "NUMPAD_MULTIPLY", 155 },
-    { "NUMPAD_SUBTRACT", 156 },
-    { "NUMPAD_ADD", 157 },
-    { "NUMPAD_DOT", 158 },
-    { "NUMPAD_COMMA", 159 },
-    { "NUMPAD_ENTER", 160 },
-    { "NUMPAD_EQUALS", 161 },
-    { "NUMPAD_LEFT_PAREN", 162 },
-    { "NUMPAD_RIGHT_PAREN", 163 },
-    { "VOLUME_MUTE", 164 },
-    { "INFO", 165 },
-    { "CHANNEL_UP", 166 },
-    { "CHANNEL_DOWN", 167 },
-    { "ZOOM_IN", 168 },
-    { "ZOOM_OUT", 169 },
-    { "TV", 170 },
-    { "WINDOW", 171 },
-    { "GUIDE", 172 },
-    { "DVR", 173 },
-    { "BOOKMARK", 174 },
-    { "CAPTIONS", 175 },
-    { "SETTINGS", 176 },
-    { "TV_POWER", 177 },
-    { "TV_INPUT", 178 },
-    { "STB_POWER", 179 },
-    { "STB_INPUT", 180 },
-    { "AVR_POWER", 181 },
-    { "AVR_INPUT", 182 },
-    { "PROG_RED", 183 },
-    { "PROG_GREEN", 184 },
-    { "PROG_YELLOW", 185 },
-    { "PROG_BLUE", 186 },
-    { "APP_SWITCH", 187 },
-    { "BUTTON_1", 188 },
-    { "BUTTON_2", 189 },
-    { "BUTTON_3", 190 },
-    { "BUTTON_4", 191 },
-    { "BUTTON_5", 192 },
-    { "BUTTON_6", 193 },
-    { "BUTTON_7", 194 },
-    { "BUTTON_8", 195 },
-    { "BUTTON_9", 196 },
-    { "BUTTON_10", 197 },
-    { "BUTTON_11", 198 },
-    { "BUTTON_12", 199 },
-    { "BUTTON_13", 200 },
-    { "BUTTON_14", 201 },
-    { "BUTTON_15", 202 },
-    { "BUTTON_16", 203 },
-    { "LANGUAGE_SWITCH", 204 },
-    { "MANNER_MODE", 205 },
-    { "3D_MODE", 206 },
-    { "CONTACTS", 207 },
-    { "CALENDAR", 208 },
-    { "MUSIC", 209 },
-    { "CALCULATOR", 210 },
-    { "ZENKAKU_HANKAKU", 211 },
-    { "EISU", 212 },
-    { "MUHENKAN", 213 },
-    { "HENKAN", 214 },
-    { "KATAKANA_HIRAGANA", 215 },
-    { "YEN", 216 },
-    { "RO", 217 },
-    { "KANA", 218 },
-    { "ASSIST", 219 },
-    { "BRIGHTNESS_DOWN", 220 },
-    { "BRIGHTNESS_UP", 221 },
-
-    // NOTE: If you add a new keycode here you must also add it to several other files.
-    //       Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
-
-    { NULL, 0 }
-};
-
-// NOTE: If you edit these flags, also edit policy flags in Input.h.
-static const KeycodeLabel FLAGS[] = {
-    { "WAKE", 0x00000001 },
-    { "WAKE_DROPPED", 0x00000002 },
-    { "SHIFT", 0x00000004 },
-    { "CAPS_LOCK", 0x00000008 },
-    { "ALT", 0x00000010 },
-    { "ALT_GR", 0x00000020 },
-    { "MENU", 0x00000040 },
-    { "LAUNCHER", 0x00000080 },
-    { "VIRTUAL", 0x00000100 },
-    { "FUNCTION", 0x00000200 },
-    { NULL, 0 }
-};
-
-static const KeycodeLabel AXES[] = {
-    { "X", 0 },
-    { "Y", 1 },
-    { "PRESSURE", 2 },
-    { "SIZE", 3 },
-    { "TOUCH_MAJOR", 4 },
-    { "TOUCH_MINOR", 5 },
-    { "TOOL_MAJOR", 6 },
-    { "TOOL_MINOR", 7 },
-    { "ORIENTATION", 8 },
-    { "VSCROLL", 9 },
-    { "HSCROLL", 10 },
-    { "Z", 11 },
-    { "RX", 12 },
-    { "RY", 13 },
-    { "RZ", 14 },
-    { "HAT_X", 15 },
-    { "HAT_Y", 16 },
-    { "LTRIGGER", 17 },
-    { "RTRIGGER", 18 },
-    { "THROTTLE", 19 },
-    { "RUDDER", 20 },
-    { "WHEEL", 21 },
-    { "GAS", 22 },
-    { "BRAKE", 23 },
-    { "DISTANCE", 24 },
-    { "TILT", 25 },
-    { "GENERIC_1", 32 },
-    { "GENERIC_2", 33 },
-    { "GENERIC_3", 34 },
-    { "GENERIC_4", 35 },
-    { "GENERIC_5", 36 },
-    { "GENERIC_6", 37 },
-    { "GENERIC_7", 38 },
-    { "GENERIC_8", 39 },
-    { "GENERIC_9", 40 },
-    { "GENERIC_10", 41 },
-    { "GENERIC_11", 42 },
-    { "GENERIC_12", 43 },
-    { "GENERIC_13", 44 },
-    { "GENERIC_14", 45 },
-    { "GENERIC_15", 46 },
-    { "GENERIC_16", 47 },
-
-    // NOTE: If you add a new axis here you must also add it to several other files.
-    //       Refer to frameworks/base/core/java/android/view/MotionEvent.java for the full list.
-
-    { NULL, -1 }
-};
-
-#endif // _ANDROIDFW_KEYCODE_LABELS_H
diff --git a/include/androidfw/ResourceTypes.h b/include/androidfw/ResourceTypes.h
index 5b45d70..97afa59 100644
--- a/include/androidfw/ResourceTypes.h
+++ b/include/androidfw/ResourceTypes.h
@@ -479,7 +479,7 @@
     const uint32_t*             mEntries;
     const uint32_t*             mEntryStyles;
     const void*                 mStrings;
-    char16_t**                  mCache;
+    char16_t mutable**          mCache;
     uint32_t                    mStringPoolSize;    // number of uint16_t
     const uint32_t*             mStyles;
     uint32_t                    mStylePoolSize;    // number of uint32_t
@@ -678,11 +678,15 @@
     // Returns -1 if no namespace, -2 if idx out of range.
     int32_t getAttributeNamespaceID(size_t idx) const;
     const uint16_t* getAttributeNamespace(size_t idx, size_t* outLen) const;
-    
+
     int32_t getAttributeNameID(size_t idx) const;
     const uint16_t* getAttributeName(size_t idx, size_t* outLen) const;
     uint32_t getAttributeNameResID(size_t idx) const;
-    
+
+    // These will work only if the underlying string pool is UTF-8.
+    const char* getAttributeNamespace8(size_t idx, size_t* outLen) const;
+    const char* getAttributeName8(size_t idx, size_t* outLen) const;
+
     int32_t getAttributeValueStringID(size_t idx) const;
     const uint16_t* getAttributeStringValue(size_t idx, size_t* outLen) const;
     
@@ -1294,12 +1298,14 @@
         const char16_t* package;
         size_t packageLen;
         const char16_t* type;
+        const char* type8;
         size_t typeLen;
         const char16_t* name;
+        const char* name8;
         size_t nameLen;
     };
 
-    bool getResourceName(uint32_t resID, resource_name* outName) const;
+    bool getResourceName(uint32_t resID, bool allowUtf8, resource_name* outName) const;
 
     /**
      * Retrieve the value of a resource.  If the resource is found, returns a
@@ -1553,10 +1559,8 @@
     static bool getIdmapInfo(const void* idmap, size_t size,
                              uint32_t* pOriginalCrc, uint32_t* pOverlayCrc);
 
-#ifndef HAVE_ANDROID_OS
     void print(bool inclValues) const;
     static String8 normalizeForOutput(const char* input);
-#endif
 
 private:
     struct Header;
diff --git a/include/androidfw/VelocityControl.h b/include/androidfw/VelocityControl.h
deleted file mode 100644
index 84e0444..0000000
--- a/include/androidfw/VelocityControl.h
+++ /dev/null
@@ -1,107 +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.
- */
-
-#ifndef _ANDROIDFW_VELOCITY_CONTROL_H
-#define _ANDROIDFW_VELOCITY_CONTROL_H
-
-#include <androidfw/Input.h>
-#include <androidfw/VelocityTracker.h>
-#include <utils/Timers.h>
-
-namespace android {
-
-/*
- * Specifies parameters that govern pointer or wheel acceleration.
- */
-struct VelocityControlParameters {
-    // A scale factor that is multiplied with the raw velocity deltas
-    // prior to applying any other velocity control factors.  The scale
-    // factor should be used to adapt the input device resolution
-    // (eg. counts per inch) to the output device resolution (eg. pixels per inch).
-    //
-    // Must be a positive value.
-    // Default is 1.0 (no scaling).
-    float scale;
-
-    // The scaled speed at which acceleration begins to be applied.
-    // This value establishes the upper bound of a low speed regime for
-    // small precise motions that are performed without any acceleration.
-    //
-    // Must be a non-negative value.
-    // Default is 0.0 (no low threshold).
-    float lowThreshold;
-
-    // The scaled speed at which maximum acceleration is applied.
-    // The difference between highThreshold and lowThreshold controls
-    // the range of speeds over which the acceleration factor is interpolated.
-    // The wider the range, the smoother the acceleration.
-    //
-    // Must be a non-negative value greater than or equal to lowThreshold.
-    // Default is 0.0 (no high threshold).
-    float highThreshold;
-
-    // The acceleration factor.
-    // When the speed is above the low speed threshold, the velocity will scaled
-    // by an interpolated value between 1.0 and this amount.
-    //
-    // Must be a positive greater than or equal to 1.0.
-    // Default is 1.0 (no acceleration).
-    float acceleration;
-
-    VelocityControlParameters() :
-            scale(1.0f), lowThreshold(0.0f), highThreshold(0.0f), acceleration(1.0f) {
-    }
-
-    VelocityControlParameters(float scale, float lowThreshold,
-            float highThreshold, float acceleration) :
-            scale(scale), lowThreshold(lowThreshold),
-            highThreshold(highThreshold), acceleration(acceleration) {
-    }
-};
-
-/*
- * Implements mouse pointer and wheel speed control and acceleration.
- */
-class VelocityControl {
-public:
-    VelocityControl();
-
-    /* Sets the various parameters. */
-    void setParameters(const VelocityControlParameters& parameters);
-
-    /* Resets the current movement counters to zero.
-     * This has the effect of nullifying any acceleration. */
-    void reset();
-
-    /* Translates a raw movement delta into an appropriately
-     * scaled / accelerated delta based on the current velocity. */
-    void move(nsecs_t eventTime, float* deltaX, float* deltaY);
-
-private:
-    // If no movements are received within this amount of time,
-    // we assume the movement has stopped and reset the movement counters.
-    static const nsecs_t STOP_TIME = 500 * 1000000; // 500 ms
-
-    VelocityControlParameters mParameters;
-
-    nsecs_t mLastMovementTime;
-    VelocityTracker::Position mRawPosition;
-    VelocityTracker mVelocityTracker;
-};
-
-} // namespace android
-
-#endif // _ANDROIDFW_VELOCITY_CONTROL_H
diff --git a/include/androidfw/VelocityTracker.h b/include/androidfw/VelocityTracker.h
deleted file mode 100644
index 8c24219..0000000
--- a/include/androidfw/VelocityTracker.h
+++ /dev/null
@@ -1,269 +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.
- */
-
-#ifndef _ANDROIDFW_VELOCITY_TRACKER_H
-#define _ANDROIDFW_VELOCITY_TRACKER_H
-
-#include <androidfw/Input.h>
-#include <utils/Timers.h>
-#include <utils/BitSet.h>
-
-namespace android {
-
-class VelocityTrackerStrategy;
-
-/*
- * Calculates the velocity of pointer movements over time.
- */
-class VelocityTracker {
-public:
-    struct Position {
-        float x, y;
-    };
-
-    struct Estimator {
-        static const size_t MAX_DEGREE = 4;
-
-        // Estimator time base.
-        nsecs_t time;
-
-        // Polynomial coefficients describing motion in X and Y.
-        float xCoeff[MAX_DEGREE + 1], yCoeff[MAX_DEGREE + 1];
-
-        // Polynomial degree (number of coefficients), or zero if no information is
-        // available.
-        uint32_t degree;
-
-        // Confidence (coefficient of determination), between 0 (no fit) and 1 (perfect fit).
-        float confidence;
-
-        inline void clear() {
-            time = 0;
-            degree = 0;
-            confidence = 0;
-            for (size_t i = 0; i <= MAX_DEGREE; i++) {
-                xCoeff[i] = 0;
-                yCoeff[i] = 0;
-            }
-        }
-    };
-
-    // Creates a velocity tracker using the specified strategy.
-    // If strategy is NULL, uses the default strategy for the platform.
-    VelocityTracker(const char* strategy = NULL);
-
-    ~VelocityTracker();
-
-    // Resets the velocity tracker state.
-    void clear();
-
-    // Resets the velocity tracker state for specific pointers.
-    // Call this method when some pointers have changed and may be reusing
-    // an id that was assigned to a different pointer earlier.
-    void clearPointers(BitSet32 idBits);
-
-    // Adds movement information for a set of pointers.
-    // The idBits bitfield specifies the pointer ids of the pointers whose positions
-    // are included in the movement.
-    // The positions array contains position information for each pointer in order by
-    // increasing id.  Its size should be equal to the number of one bits in idBits.
-    void addMovement(nsecs_t eventTime, BitSet32 idBits, const Position* positions);
-
-    // Adds movement information for all pointers in a MotionEvent, including historical samples.
-    void addMovement(const MotionEvent* event);
-
-    // Gets the velocity of the specified pointer id in position units per second.
-    // Returns false and sets the velocity components to zero if there is
-    // insufficient movement information for the pointer.
-    bool getVelocity(uint32_t id, float* outVx, float* outVy) const;
-
-    // Gets an estimator for the recent movements of the specified pointer id.
-    // Returns false and clears the estimator if there is no information available
-    // about the pointer.
-    bool getEstimator(uint32_t id, Estimator* outEstimator) const;
-
-    // Gets the active pointer id, or -1 if none.
-    inline int32_t getActivePointerId() const { return mActivePointerId; }
-
-    // Gets a bitset containing all pointer ids from the most recent movement.
-    inline BitSet32 getCurrentPointerIdBits() const { return mCurrentPointerIdBits; }
-
-private:
-    static const char* DEFAULT_STRATEGY;
-
-    nsecs_t mLastEventTime;
-    BitSet32 mCurrentPointerIdBits;
-    int32_t mActivePointerId;
-    VelocityTrackerStrategy* mStrategy;
-
-    bool configureStrategy(const char* strategy);
-
-    static VelocityTrackerStrategy* createStrategy(const char* strategy);
-};
-
-
-/*
- * Implements a particular velocity tracker algorithm.
- */
-class VelocityTrackerStrategy {
-protected:
-    VelocityTrackerStrategy() { }
-
-public:
-    virtual ~VelocityTrackerStrategy() { }
-
-    virtual void clear() = 0;
-    virtual void clearPointers(BitSet32 idBits) = 0;
-    virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
-            const VelocityTracker::Position* positions) = 0;
-    virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const = 0;
-};
-
-
-/*
- * Velocity tracker algorithm based on least-squares linear regression.
- */
-class LeastSquaresVelocityTrackerStrategy : public VelocityTrackerStrategy {
-public:
-    enum Weighting {
-        // No weights applied.  All data points are equally reliable.
-        WEIGHTING_NONE,
-
-        // Weight by time delta.  Data points clustered together are weighted less.
-        WEIGHTING_DELTA,
-
-        // Weight such that points within a certain horizon are weighed more than those
-        // outside of that horizon.
-        WEIGHTING_CENTRAL,
-
-        // Weight such that points older than a certain amount are weighed less.
-        WEIGHTING_RECENT,
-    };
-
-    // Degree must be no greater than Estimator::MAX_DEGREE.
-    LeastSquaresVelocityTrackerStrategy(uint32_t degree, Weighting weighting = WEIGHTING_NONE);
-    virtual ~LeastSquaresVelocityTrackerStrategy();
-
-    virtual void clear();
-    virtual void clearPointers(BitSet32 idBits);
-    virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
-            const VelocityTracker::Position* positions);
-    virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const;
-
-private:
-    // Sample horizon.
-    // We don't use too much history by default since we want to react to quick
-    // changes in direction.
-    static const nsecs_t HORIZON = 100 * 1000000; // 100 ms
-
-    // Number of samples to keep.
-    static const uint32_t HISTORY_SIZE = 20;
-
-    struct Movement {
-        nsecs_t eventTime;
-        BitSet32 idBits;
-        VelocityTracker::Position positions[MAX_POINTERS];
-
-        inline const VelocityTracker::Position& getPosition(uint32_t id) const {
-            return positions[idBits.getIndexOfBit(id)];
-        }
-    };
-
-    float chooseWeight(uint32_t index) const;
-
-    const uint32_t mDegree;
-    const Weighting mWeighting;
-    uint32_t mIndex;
-    Movement mMovements[HISTORY_SIZE];
-};
-
-
-/*
- * Velocity tracker algorithm that uses an IIR filter.
- */
-class IntegratingVelocityTrackerStrategy : public VelocityTrackerStrategy {
-public:
-    // Degree must be 1 or 2.
-    IntegratingVelocityTrackerStrategy(uint32_t degree);
-    ~IntegratingVelocityTrackerStrategy();
-
-    virtual void clear();
-    virtual void clearPointers(BitSet32 idBits);
-    virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
-            const VelocityTracker::Position* positions);
-    virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const;
-
-private:
-    // Current state estimate for a particular pointer.
-    struct State {
-        nsecs_t updateTime;
-        uint32_t degree;
-
-        float xpos, xvel, xaccel;
-        float ypos, yvel, yaccel;
-    };
-
-    const uint32_t mDegree;
-    BitSet32 mPointerIdBits;
-    State mPointerState[MAX_POINTER_ID + 1];
-
-    void initState(State& state, nsecs_t eventTime, float xpos, float ypos) const;
-    void updateState(State& state, nsecs_t eventTime, float xpos, float ypos) const;
-    void populateEstimator(const State& state, VelocityTracker::Estimator* outEstimator) const;
-};
-
-
-/*
- * Velocity tracker strategy used prior to ICS.
- */
-class LegacyVelocityTrackerStrategy : public VelocityTrackerStrategy {
-public:
-    LegacyVelocityTrackerStrategy();
-    virtual ~LegacyVelocityTrackerStrategy();
-
-    virtual void clear();
-    virtual void clearPointers(BitSet32 idBits);
-    virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
-            const VelocityTracker::Position* positions);
-    virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const;
-
-private:
-    // Oldest sample to consider when calculating the velocity.
-    static const nsecs_t HORIZON = 200 * 1000000; // 100 ms
-
-    // Number of samples to keep.
-    static const uint32_t HISTORY_SIZE = 20;
-
-    // The minimum duration between samples when estimating velocity.
-    static const nsecs_t MIN_DURATION = 10 * 1000000; // 10 ms
-
-    struct Movement {
-        nsecs_t eventTime;
-        BitSet32 idBits;
-        VelocityTracker::Position positions[MAX_POINTERS];
-
-        inline const VelocityTracker::Position& getPosition(uint32_t id) const {
-            return positions[idBits.getIndexOfBit(id)];
-        }
-    };
-
-    uint32_t mIndex;
-    Movement mMovements[HISTORY_SIZE];
-};
-
-} // namespace android
-
-#endif // _ANDROIDFW_VELOCITY_TRACKER_H
diff --git a/include/androidfw/VirtualKeyMap.h b/include/androidfw/VirtualKeyMap.h
deleted file mode 100644
index dd3ad1e9..0000000
--- a/include/androidfw/VirtualKeyMap.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _ANDROIDFW_VIRTUAL_KEY_MAP_H
-#define _ANDROIDFW_VIRTUAL_KEY_MAP_H
-
-#include <stdint.h>
-
-#include <androidfw/Input.h>
-#include <utils/Errors.h>
-#include <utils/KeyedVector.h>
-#include <utils/Tokenizer.h>
-#include <utils/String8.h>
-#include <utils/Unicode.h>
-
-namespace android {
-
-/* Describes a virtual key. */
-struct VirtualKeyDefinition {
-    int32_t scanCode;
-
-    // configured position data, specified in display coords
-    int32_t centerX;
-    int32_t centerY;
-    int32_t width;
-    int32_t height;
-};
-
-
-/**
- * Describes a collection of virtual keys on a touch screen in terms of
- * virtual scan codes and hit rectangles.
- *
- * This object is immutable after it has been loaded.
- */
-class VirtualKeyMap {
-public:
-    ~VirtualKeyMap();
-
-    static status_t load(const String8& filename, VirtualKeyMap** outMap);
-
-    inline const Vector<VirtualKeyDefinition>& getVirtualKeys() const {
-        return mVirtualKeys;
-    }
-
-private:
-    class Parser {
-        VirtualKeyMap* mMap;
-        Tokenizer* mTokenizer;
-
-    public:
-        Parser(VirtualKeyMap* map, Tokenizer* tokenizer);
-        ~Parser();
-        status_t parse();
-
-    private:
-        bool consumeFieldDelimiterAndSkipWhitespace();
-        bool parseNextIntField(int32_t* outValue);
-    };
-
-    Vector<VirtualKeyDefinition> mVirtualKeys;
-
-    VirtualKeyMap();
-};
-
-} // namespace android
-
-#endif // _ANDROIDFW_KEY_CHARACTER_MAP_H
diff --git a/include/androidfw/ZipFileRO.h b/include/androidfw/ZipFileRO.h
new file mode 100644
index 0000000..547e36a
--- /dev/null
+++ b/include/androidfw/ZipFileRO.h
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Read-only access to Zip archives, with minimal heap allocation.
+ *
+ * This is similar to the more-complete ZipFile class, but no attempt
+ * has been made to make them interchangeable.  This class operates under
+ * a very different set of assumptions and constraints.
+ *
+ * One such assumption is that if you're getting file descriptors for
+ * use with this class as a child of a fork() operation, you must be on
+ * a pread() to guarantee correct operation. This is because pread() can
+ * atomically read at a file offset without worrying about a lock around an
+ * lseek() + read() pair.
+ */
+#ifndef __LIBS_ZIPFILERO_H
+#define __LIBS_ZIPFILERO_H
+
+#include <utils/Compat.h>
+#include <utils/Errors.h>
+#include <utils/FileMap.h>
+#include <utils/threads.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+
+namespace android {
+
+/*
+ * Trivial typedef to ensure that ZipEntryRO is not treated as a simple
+ * integer.  We use NULL to indicate an invalid value.
+ */
+typedef void* ZipEntryRO;
+
+/*
+ * Open a Zip archive for reading.
+ *
+ * We want "open" and "find entry by name" to be fast operations, and we
+ * want to use as little memory as possible.  We memory-map the file,
+ * and load a hash table with pointers to the filenames (which aren't
+ * null-terminated).  The other fields are at a fixed offset from the
+ * filename, so we don't need to extract those (but we do need to byte-read
+ * and endian-swap them every time we want them).
+ *
+ * To speed comparisons when doing a lookup by name, we could make the mapping
+ * "private" (copy-on-write) and null-terminate the filenames after verifying
+ * the record structure.  However, this requires a private mapping of
+ * every page that the Central Directory touches.  Easier to tuck a copy
+ * of the string length into the hash table entry.
+ *
+ * NOTE: If this is used on file descriptors inherited from a fork() operation,
+ * you must be on a platform that implements pread() to guarantee correctness
+ * on the shared file descriptors.
+ */
+class ZipFileRO {
+public:
+    ZipFileRO()
+        : mFd(-1), mFileName(NULL), mFileLength(-1),
+          mDirectoryMap(NULL),
+          mNumEntries(-1), mDirectoryOffset(-1),
+          mHashTableSize(-1), mHashTable(NULL)
+        {}
+
+    ~ZipFileRO();
+
+    /*
+     * Open an archive.
+     */
+    status_t open(const char* zipFileName);
+
+    /*
+     * Find an entry, by name.  Returns the entry identifier, or NULL if
+     * not found.
+     *
+     * If two entries have the same name, one will be chosen at semi-random.
+     */
+    ZipEntryRO findEntryByName(const char* fileName) const;
+
+    /*
+     * Return the #of entries in the Zip archive.
+     */
+    int getNumEntries(void) const {
+        return mNumEntries;
+    }
+
+    /*
+     * Return the Nth entry.  Zip file entries are not stored in sorted
+     * order, and updated entries may appear at the end, so anyone walking
+     * the archive needs to avoid making ordering assumptions.  We take
+     * that further by returning the Nth non-empty entry in the hash table
+     * rather than the Nth entry in the archive.
+     *
+     * Valid values are [0..numEntries).
+     *
+     * [This is currently O(n).  If it needs to be fast we can allocate an
+     * additional data structure or provide an iterator interface.]
+     */
+    ZipEntryRO findEntryByIndex(int idx) const;
+
+    /*
+     * Copy the filename into the supplied buffer.  Returns 0 on success,
+     * -1 if "entry" is invalid, or the filename length if it didn't fit.  The
+     * length, and the returned string, include the null-termination.
+     */
+    int getEntryFileName(ZipEntryRO entry, char* buffer, int bufLen) const;
+
+    /*
+     * Get the vital stats for an entry.  Pass in NULL pointers for anything
+     * you don't need.
+     *
+     * "*pOffset" holds the Zip file offset of the entry's data.
+     *
+     * Returns "false" if "entry" is bogus or if the data in the Zip file
+     * appears to be bad.
+     */
+    bool getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
+        size_t* pCompLen, off64_t* pOffset, long* pModWhen, long* pCrc32) const;
+
+    /*
+     * Create a new FileMap object that maps a subset of the archive.  For
+     * an uncompressed entry this effectively provides a pointer to the
+     * actual data, for a compressed entry this provides the input buffer
+     * for inflate().
+     */
+    FileMap* createEntryFileMap(ZipEntryRO entry) const;
+
+    /*
+     * Uncompress the data into a buffer.  Depending on the compression
+     * format, this is either an "inflate" operation or a memcpy.
+     *
+     * Use "uncompLen" from getEntryInfo() to determine the required
+     * buffer size.
+     *
+     * Returns "true" on success.
+     */
+    bool uncompressEntry(ZipEntryRO entry, void* buffer) const;
+
+    /*
+     * Uncompress the data to an open file descriptor.
+     */
+    bool uncompressEntry(ZipEntryRO entry, int fd) const;
+
+    /* Zip compression methods we support */
+    enum {
+        kCompressStored     = 0,        // no compression
+        kCompressDeflated   = 8,        // standard deflate
+    };
+
+    /*
+     * Utility function: uncompress deflated data, buffer to buffer.
+     */
+    static bool inflateBuffer(void* outBuf, const void* inBuf,
+        size_t uncompLen, size_t compLen);
+
+    /*
+     * Utility function: uncompress deflated data, buffer to fd.
+     */
+    static bool inflateBuffer(int fd, const void* inBuf,
+        size_t uncompLen, size_t compLen);
+
+    /*
+     * Utility function to convert ZIP's time format to a timespec struct.
+     */
+    static inline void zipTimeToTimespec(long when, struct tm* timespec) {
+        const long date = when >> 16;
+        timespec->tm_year = ((date >> 9) & 0x7F) + 80; // Zip is years since 1980
+        timespec->tm_mon = (date >> 5) & 0x0F;
+        timespec->tm_mday = date & 0x1F;
+
+        timespec->tm_hour = (when >> 11) & 0x1F;
+        timespec->tm_min = (when >> 5) & 0x3F;
+        timespec->tm_sec = (when & 0x1F) << 1;
+    }
+
+    /*
+     * Some basic functions for raw data manipulation.  "LE" means
+     * Little Endian.
+     */
+    static inline unsigned short get2LE(const unsigned char* buf) {
+        return buf[0] | (buf[1] << 8);
+    }
+    static inline unsigned long get4LE(const unsigned char* buf) {
+        return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
+    }
+
+private:
+    /* these are private and not defined */ 
+    ZipFileRO(const ZipFileRO& src);
+    ZipFileRO& operator=(const ZipFileRO& src);
+
+    /* locate and parse the central directory */
+    bool mapCentralDirectory(void);
+
+    /* parse the archive, prepping internal structures */
+    bool parseZipArchive(void);
+
+    /* add a new entry to the hash table */
+    void addToHash(const char* str, int strLen, unsigned int hash);
+
+    /* compute string hash code */
+    static unsigned int computeHash(const char* str, int len);
+
+    /* convert a ZipEntryRO back to a hash table index */
+    int entryToIndex(const ZipEntryRO entry) const;
+
+    /*
+     * One entry in the hash table.
+     */
+    typedef struct HashEntry {
+        const char*     name;
+        unsigned short  nameLen;
+        //unsigned int    hash;
+    } HashEntry;
+
+    /* open Zip archive */
+    int         mFd;
+
+    /* Lock for handling the file descriptor (seeks, etc) */
+    mutable Mutex mFdLock;
+
+    /* zip file name */
+    char*       mFileName;
+
+    /* length of file */
+    size_t      mFileLength;
+
+    /* mapped file */
+    FileMap*    mDirectoryMap;
+
+    /* number of entries in the Zip archive */
+    int         mNumEntries;
+
+    /* CD directory offset in the Zip archive */
+    off64_t     mDirectoryOffset;
+
+    /*
+     * We know how many entries are in the Zip archive, so we have a
+     * fixed-size hash table.  We probe for an empty slot.
+     */
+    int         mHashTableSize;
+    HashEntry*  mHashTable;
+};
+
+}; // namespace android
+
+#endif /*__LIBS_ZIPFILERO_H*/
diff --git a/include/androidfw/ZipUtils.h b/include/androidfw/ZipUtils.h
new file mode 100644
index 0000000..42c42b6
--- /dev/null
+++ b/include/androidfw/ZipUtils.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Miscellaneous zip/gzip utility functions.
+//
+#ifndef __LIBS_ZIPUTILS_H
+#define __LIBS_ZIPUTILS_H
+
+#include <stdio.h>
+
+namespace android {
+
+/*
+ * Container class for utility functions, primarily for namespace reasons.
+ */
+class ZipUtils {
+public:
+    /*
+     * General utility function for uncompressing "deflate" data from a file
+     * to a buffer.
+     */
+    static bool inflateToBuffer(int fd, void* buf, long uncompressedLen,
+        long compressedLen);
+    static bool inflateToBuffer(FILE* fp, void* buf, long uncompressedLen,
+        long compressedLen);
+
+    /*
+     * Someday we might want to make this generic and handle bzip2 ".bz2"
+     * files too.
+     *
+     * We could declare gzip to be a sub-class of zip that has exactly
+     * one always-compressed entry, but we currently want to treat Zip
+     * and gzip as distinct, so there's no value.
+     *
+     * The zlib library has some gzip utilities, but it has no interface
+     * for extracting the uncompressed length of the file (you do *not*
+     * want to gzseek to the end).
+     *
+     * Pass in a seeked file pointer for the gzip file.  If this is a gzip
+     * file, we set our return values appropriately and return "true" with
+     * the file seeked to the start of the compressed data.
+     */
+    static bool examineGzip(FILE* fp, int* pCompressionMethod,
+        long* pUncompressedLen, long* pCompressedLen, unsigned long* pCRC32);
+
+private:
+    ZipUtils() {}
+    ~ZipUtils() {}
+};
+
+}; // namespace android
+
+#endif /*__LIBS_ZIPUTILS_H*/
diff --git a/include/androidfw/misc.h b/include/androidfw/misc.h
new file mode 100644
index 0000000..5a5a0e2
--- /dev/null
+++ b/include/androidfw/misc.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <sys/types.h>
+
+//
+// Handy utility functions and portability code.
+//
+#ifndef _LIBS_ANDROID_FW_MISC_H
+#define _LIBS_ANDROID_FW_MISC_H
+
+namespace android {
+
+/*
+ * Some utility functions for working with files.  These could be made
+ * part of a "File" class.
+ */
+typedef enum FileType {
+    kFileTypeUnknown = 0,
+    kFileTypeNonexistent,       // i.e. ENOENT
+    kFileTypeRegular,
+    kFileTypeDirectory,
+    kFileTypeCharDev,
+    kFileTypeBlockDev,
+    kFileTypeFifo,
+    kFileTypeSymlink,
+    kFileTypeSocket,
+} FileType;
+/* get the file's type; follows symlinks */
+FileType getFileType(const char* fileName);
+/* get the file's modification date; returns -1 w/errno set on failure */
+time_t getFileModDate(const char* fileName);
+
+}; // namespace android
+
+#endif // _LIBS_ANDROID_FW_MISC_H
diff --git a/keystore/java/android/security/AndroidKeyPairGenerator.java b/keystore/java/android/security/AndroidKeyPairGenerator.java
index 390e732..1ab0aeb 100644
--- a/keystore/java/android/security/AndroidKeyPairGenerator.java
+++ b/keystore/java/android/security/AndroidKeyPairGenerator.java
@@ -18,6 +18,7 @@
 
 import com.android.org.bouncycastle.x509.X509V3CertificateGenerator;
 
+import com.android.org.conscrypt.NativeCrypto;
 import com.android.org.conscrypt.OpenSSLEngine;
 
 import java.security.InvalidAlgorithmParameterException;
@@ -33,7 +34,10 @@
 import java.security.cert.CertificateEncodingException;
 import java.security.cert.X509Certificate;
 import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.DSAParameterSpec;
+import java.security.spec.ECParameterSpec;
 import java.security.spec.InvalidKeySpecException;
+import java.security.spec.RSAKeyGenParameterSpec;
 import java.security.spec.X509EncodedKeySpec;
 
 /**
@@ -87,8 +91,12 @@
 
         Credentials.deleteAllTypesForAlias(mKeyStore, alias);
 
+        final int keyType = KeyStore.getKeyTypeForAlgorithm(mSpec.getKeyType());
+        byte[][] args = getArgsForKeyType(keyType, mSpec.getAlgorithmParameterSpec());
+
         final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + alias;
-        if (!mKeyStore.generate(privateKeyAlias, KeyStore.UID_SELF, mSpec.getFlags())) {
+        if (!mKeyStore.generate(privateKeyAlias, KeyStore.UID_SELF, keyType,
+                mSpec.getKeySize(), mSpec.getFlags(), args)) {
             throw new IllegalStateException("could not generate key in keystore");
         }
 
@@ -104,10 +112,10 @@
 
         final PublicKey pubKey;
         try {
-            final KeyFactory keyFact = KeyFactory.getInstance("RSA");
+            final KeyFactory keyFact = KeyFactory.getInstance(mSpec.getKeyType());
             pubKey = keyFact.generatePublic(new X509EncodedKeySpec(pubKeyBytes));
         } catch (NoSuchAlgorithmException e) {
-            throw new IllegalStateException("Can't instantiate RSA key generator", e);
+            throw new IllegalStateException("Can't instantiate key generator", e);
         } catch (InvalidKeySpecException e) {
             throw new IllegalStateException("keystore returned invalid key encoding", e);
         }
@@ -119,7 +127,7 @@
         certGen.setIssuerDN(mSpec.getSubjectDN());
         certGen.setNotBefore(mSpec.getStartDate());
         certGen.setNotAfter(mSpec.getEndDate());
-        certGen.setSignatureAlgorithm("sha1WithRSA");
+        certGen.setSignatureAlgorithm(getDefaultSignatureAlgorithmForKeyType(mSpec.getKeyType()));
 
         final X509Certificate cert;
         try {
@@ -146,6 +154,37 @@
         return new KeyPair(pubKey, privKey);
     }
 
+    private static String getDefaultSignatureAlgorithmForKeyType(String keyType) {
+        if ("RSA".equalsIgnoreCase(keyType)) {
+            return "sha256WithRSA";
+        } else if ("DSA".equalsIgnoreCase(keyType)) {
+            return "sha1WithDSA";
+        } else if ("EC".equalsIgnoreCase(keyType)) {
+            return "sha256WithECDSA";
+        } else {
+            throw new IllegalArgumentException("Unsupported key type " + keyType);
+        }
+    }
+
+    private static byte[][] getArgsForKeyType(int keyType, AlgorithmParameterSpec spec) {
+        switch (keyType) {
+            case NativeCrypto.EVP_PKEY_RSA:
+                if (spec instanceof RSAKeyGenParameterSpec) {
+                    RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec) spec;
+                    return new byte[][] { rsaSpec.getPublicExponent().toByteArray() };
+                }
+                break;
+            case NativeCrypto.EVP_PKEY_DSA:
+                if (spec instanceof DSAParameterSpec) {
+                    DSAParameterSpec dsaSpec = (DSAParameterSpec) spec;
+                    return new byte[][] { dsaSpec.getG().toByteArray(),
+                            dsaSpec.getP().toByteArray(), dsaSpec.getQ().toByteArray() };
+                }
+                break;
+        }
+        return null;
+    }
+
     @Override
     public void initialize(int keysize, SecureRandom random) {
         throw new IllegalArgumentException("cannot specify keysize with AndroidKeyPairGenerator");
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index 328ac5d..8ad973d 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -34,6 +34,7 @@
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.util.List;
+import java.util.Locale;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.LinkedBlockingQueue;
 
@@ -364,7 +365,8 @@
      * "RSA").
      */
     public static boolean isKeyAlgorithmSupported(String algorithm) {
-        return "RSA".equals(algorithm);
+        final String algUpper = algorithm.toUpperCase(Locale.US);
+        return "DSA".equals(algUpper) || "EC".equals(algUpper) || "RSA".equals(algUpper);
     }
 
     /**
@@ -379,7 +381,7 @@
             return false;
         }
 
-        return KeyStore.getInstance().isHardwareBacked();
+        return KeyStore.getInstance().isHardwareBacked(algorithm);
     }
 
     private static X509Certificate toCertificate(byte[] bytes) {
@@ -443,7 +445,10 @@
             }
             @Override public void onServiceDisconnected(ComponentName name) {}
         };
-        boolean isBound = context.bindService(new Intent(IKeyChainService.class.getName()),
+        Intent intent = new Intent(IKeyChainService.class.getName());
+        ComponentName comp = intent.resolveSystemService(context.getPackageManager(), 0);
+        intent.setComponent(comp);
+        boolean isBound = context.bindService(intent,
                                               keyChainServiceConnection,
                                               Context.BIND_AUTO_CREATE);
         if (!isBound) {
diff --git a/keystore/java/android/security/KeyPairGeneratorSpec.java b/keystore/java/android/security/KeyPairGeneratorSpec.java
index 59f89bc..21d6caa 100644
--- a/keystore/java/android/security/KeyPairGeneratorSpec.java
+++ b/keystore/java/android/security/KeyPairGeneratorSpec.java
@@ -16,13 +16,18 @@
 
 package android.security;
 
+import com.android.org.conscrypt.NativeCrypto;
+
 import android.content.Context;
 import android.text.TextUtils;
 
 import java.math.BigInteger;
+import java.security.NoSuchAlgorithmException;
 import java.security.PrivateKey;
 import java.security.cert.Certificate;
 import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.DSAParameterSpec;
+import java.security.spec.RSAKeyGenParameterSpec;
 import java.util.Date;
 
 import javax.security.auth.x500.X500Principal;
@@ -50,10 +55,35 @@
  * certificate signed by a real Certificate Authority.
  */
 public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
-    private final String mKeystoreAlias;
+    /*
+     * These must be kept in sync with system/security/keystore/defaults.h
+     */
+
+    /* DSA */
+    private static final int DSA_DEFAULT_KEY_SIZE = 1024;
+    private static final int DSA_MIN_KEY_SIZE = 512;
+    private static final int DSA_MAX_KEY_SIZE = 8192;
+
+    /* EC */
+    private static final int EC_DEFAULT_KEY_SIZE = 256;
+    private static final int EC_MIN_KEY_SIZE = 192;
+    private static final int EC_MAX_KEY_SIZE = 521;
+
+    /* RSA */
+    private static final int RSA_DEFAULT_KEY_SIZE = 2048;
+    private static final int RSA_MIN_KEY_SIZE = 512;
+    private static final int RSA_MAX_KEY_SIZE = 8192;
 
     private final Context mContext;
 
+    private final String mKeystoreAlias;
+
+    private final String mKeyType;
+
+    private final int mKeySize;
+
+    private final AlgorithmParameterSpec mSpec;
+
     private final X500Principal mSubjectDN;
 
     private final BigInteger mSerialNumber;
@@ -84,6 +114,9 @@
      * @param context Android context for the activity
      * @param keyStoreAlias name to use for the generated key in the Android
      *            keystore
+     * @param keyType key algorithm to use (RSA, DSA, EC)
+     * @param keySize size of key to generate
+     * @param spec the underlying key type parameters
      * @param subjectDN X.509 v3 Subject Distinguished Name
      * @param serialNumber X509 v3 certificate serial number
      * @param startDate the start of the self-signed certificate validity period
@@ -93,9 +126,9 @@
      *             {@code endDate} is before {@code startDate}.
      * @hide should be built with KeyPairGeneratorSpecBuilder
      */
-    public KeyPairGeneratorSpec(Context context, String keyStoreAlias,
-            X500Principal subjectDN, BigInteger serialNumber, Date startDate, Date endDate,
-            int flags) {
+    public KeyPairGeneratorSpec(Context context, String keyStoreAlias, String keyType, int keySize,
+            AlgorithmParameterSpec spec, X500Principal subjectDN, BigInteger serialNumber,
+            Date startDate, Date endDate, int flags) {
         if (context == null) {
             throw new IllegalArgumentException("context == null");
         } else if (TextUtils.isEmpty(keyStoreAlias)) {
@@ -112,8 +145,18 @@
             throw new IllegalArgumentException("endDate < startDate");
         }
 
+        final int keyTypeInt = KeyStore.getKeyTypeForAlgorithm(keyType);
+        if (keySize == -1) {
+            keySize = getDefaultKeySizeForType(keyTypeInt);
+        }
+        checkCorrectParametersSpec(keyTypeInt, keySize, spec);
+        checkValidKeySize(keyTypeInt, keySize);
+
         mContext = context;
         mKeystoreAlias = keyStoreAlias;
+        mKeyType = keyType;
+        mKeySize = keySize;
+        mSpec = spec;
         mSubjectDN = subjectDN;
         mSerialNumber = serialNumber;
         mStartDate = startDate;
@@ -121,6 +164,64 @@
         mFlags = flags;
     }
 
+    private static int getDefaultKeySizeForType(int keyType) {
+        if (keyType == NativeCrypto.EVP_PKEY_DSA) {
+            return DSA_DEFAULT_KEY_SIZE;
+        } else if (keyType == NativeCrypto.EVP_PKEY_EC) {
+            return EC_DEFAULT_KEY_SIZE;
+        } else if (keyType == NativeCrypto.EVP_PKEY_RSA) {
+            return RSA_DEFAULT_KEY_SIZE;
+        }
+        throw new IllegalArgumentException("Invalid key type " + keyType);
+    }
+
+    private static void checkValidKeySize(int keyType, int keySize) {
+        if (keyType == NativeCrypto.EVP_PKEY_DSA) {
+            if (keySize < DSA_MIN_KEY_SIZE || keySize > DSA_MAX_KEY_SIZE) {
+                throw new IllegalArgumentException("DSA keys must be >= " + DSA_MIN_KEY_SIZE
+                        + " and <= " + DSA_MAX_KEY_SIZE);
+            }
+        } else if (keyType == NativeCrypto.EVP_PKEY_EC) {
+            if (keySize < EC_MIN_KEY_SIZE || keySize > EC_MAX_KEY_SIZE) {
+                throw new IllegalArgumentException("EC keys must be >= " + EC_MIN_KEY_SIZE
+                        + " and <= " + EC_MAX_KEY_SIZE);
+            }
+        } else if (keyType == NativeCrypto.EVP_PKEY_RSA) {
+            if (keySize < RSA_MIN_KEY_SIZE || keySize > RSA_MAX_KEY_SIZE) {
+                throw new IllegalArgumentException("RSA keys must be >= " + RSA_MIN_KEY_SIZE
+                        + " and <= " + RSA_MAX_KEY_SIZE);
+            }
+        } else {
+            throw new IllegalArgumentException("Invalid key type " + keyType);
+        }
+    }
+
+    private static void checkCorrectParametersSpec(int keyType, int keySize,
+            AlgorithmParameterSpec spec) {
+        if (keyType == NativeCrypto.EVP_PKEY_DSA && spec != null) {
+            if (!(spec instanceof DSAParameterSpec)) {
+                throw new IllegalArgumentException("DSA keys must have DSAParameterSpec specified");
+            }
+        } else if (keyType == NativeCrypto.EVP_PKEY_RSA && spec != null) {
+            if (spec instanceof RSAKeyGenParameterSpec) {
+                RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec) spec;
+                if (keySize != -1 && keySize != rsaSpec.getKeysize()) {
+                    throw new IllegalArgumentException("RSA key size must match: " + keySize
+                            + " vs " + rsaSpec.getKeysize());
+                }
+            } else {
+                throw new IllegalArgumentException("RSA may only use RSAKeyGenParameterSpec");
+            }
+        }
+    }
+
+    /**
+     * Gets the Android context used for operations with this instance.
+     */
+    public Context getContext() {
+        return mContext;
+    }
+
     /**
      * Returns the alias that will be used in the {@code java.security.KeyStore}
      * in conjunction with the {@code AndroidKeyStore}.
@@ -130,10 +231,28 @@
     }
 
     /**
-     * Gets the Android context used for operations with this instance.
+     * Returns the key type (e.g., "RSA", "DSA", "EC") specified by this
+     * parameter.
      */
-    public Context getContext() {
-        return mContext;
+    public String getKeyType() {
+        return mKeyType;
+    }
+
+    /**
+     * Returns the key size specified by this parameter. For instance, for RSA
+     * this will return the modulus size and for EC it will return the field
+     * size.
+     */
+    public int getKeySize() {
+        return mKeySize;
+    }
+
+    /**
+     * Returns the {@link AlgorithmParameterSpec} that will be used for creation
+     * of the key pair.
+     */
+    public AlgorithmParameterSpec getAlgorithmParameterSpec() {
+        return mSpec;
     }
 
     /**
@@ -209,6 +328,12 @@
 
         private String mKeystoreAlias;
 
+        private String mKeyType = "RSA";
+
+        private int mKeySize = -1;
+
+        private AlgorithmParameterSpec mSpec;
+
         private X500Principal mSubjectDN;
 
         private BigInteger mSerialNumber;
@@ -246,6 +371,49 @@
         }
 
         /**
+         * Sets the key type (e.g., RSA, DSA, EC) of the keypair to be created.
+         */
+        public Builder setKeyType(String keyType) throws NoSuchAlgorithmException {
+            if (keyType == null) {
+                throw new NullPointerException("keyType == null");
+            } else {
+                try {
+                    KeyStore.getKeyTypeForAlgorithm(keyType);
+                } catch (IllegalArgumentException e) {
+                    throw new NoSuchAlgorithmException("Unsupported key type: " + keyType);
+                }
+            }
+            mKeyType = keyType;
+            return this;
+        }
+
+        /**
+         * Sets the key size for the keypair to be created. For instance, for a
+         * key type of RSA this will set the modulus size and for a key type of
+         * EC it will select a curve with a matching field size.
+         */
+        public Builder setKeySize(int keySize) {
+            if (keySize < 0) {
+                throw new IllegalArgumentException("keySize < 0");
+            }
+            mKeySize = keySize;
+            return this;
+        }
+
+        /**
+         * Sets the underlying key type's parameters. This is required for DSA
+         * where you must set this to an instance of
+         * {@link java.security.spec.DSAParameterSpec}.
+         */
+        public Builder setAlgorithmParameterSpec(AlgorithmParameterSpec spec) {
+            if (spec == null) {
+                throw new NullPointerException("spec == null");
+            }
+            mSpec = spec;
+            return this;
+        }
+
+        /**
          * Sets the subject used for the self-signed certificate of the
          * generated key pair.
          */
@@ -311,8 +479,8 @@
          * @return built instance of {@code KeyPairGeneratorSpec}
          */
         public KeyPairGeneratorSpec build() {
-            return new KeyPairGeneratorSpec(mContext, mKeystoreAlias, mSubjectDN,
-                    mSerialNumber, mStartDate, mEndDate, mFlags);
+            return new KeyPairGeneratorSpec(mContext, mKeystoreAlias, mKeyType, mKeySize, mSpec,
+                    mSubjectDN, mSerialNumber, mStartDate, mEndDate, mFlags);
         }
     }
 }
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index fb5e039..6ac49ee 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -16,10 +16,14 @@
 
 package android.security;
 
+import com.android.org.conscrypt.NativeCrypto;
+
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.util.Log;
 
+import java.util.Locale;
+
 /**
  * @hide This should not be made public in its present form because it
  * assumes that private and secret key bytes are available and would
@@ -64,6 +68,18 @@
         return new KeyStore(keystore);
     }
 
+    static int getKeyTypeForAlgorithm(String keyType) throws IllegalArgumentException {
+        if ("RSA".equalsIgnoreCase(keyType)) {
+            return NativeCrypto.EVP_PKEY_RSA;
+        } else if ("DSA".equalsIgnoreCase(keyType)) {
+            return NativeCrypto.EVP_PKEY_DSA;
+        } else if ("EC".equalsIgnoreCase(keyType)) {
+            return NativeCrypto.EVP_PKEY_EC;
+        } else {
+            throw new IllegalArgumentException("Unsupported key type: " + keyType);
+        }
+    }
+
     public State state() {
         final int ret;
         try {
@@ -188,9 +204,10 @@
         }
     }
 
-    public boolean generate(String key, int uid, int flags) {
+    public boolean generate(String key, int uid, int keyType, int keySize, int flags,
+            byte[][] args) {
         try {
-            return mBinder.generate(key, uid, flags) == NO_ERROR;
+            return mBinder.generate(key, uid, keyType, keySize, flags, args) == NO_ERROR;
         } catch (RemoteException e) {
             Log.w(TAG, "Cannot connect to keystore", e);
             return false;
@@ -291,9 +308,14 @@
         }
     }
 
+    // TODO remove this when it's removed from Settings
     public boolean isHardwareBacked() {
+        return isHardwareBacked("RSA");
+    }
+
+    public boolean isHardwareBacked(String keyType) {
         try {
-            return mBinder.is_hardware_backed() == NO_ERROR;
+            return mBinder.is_hardware_backed(keyType.toUpperCase(Locale.US)) == NO_ERROR;
         } catch (RemoteException e) {
             Log.w(TAG, "Cannot connect to keystore", e);
             return false;
diff --git a/keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java b/keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java
index 1582f74..ea6c43d 100644
--- a/keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java
+++ b/keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java
@@ -27,6 +27,13 @@
 import java.security.cert.Certificate;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
+import java.security.interfaces.DSAParams;
+import java.security.interfaces.DSAPublicKey;
+import java.security.interfaces.ECPublicKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.DSAParameterSpec;
+import java.security.spec.RSAKeyGenParameterSpec;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 
@@ -118,6 +125,8 @@
         mGenerator.initialize(
                 new KeyPairGeneratorSpec.Builder(getContext())
                         .setAlias(TEST_ALIAS_1)
+                        .setKeyType("RSA")
+                        .setKeySize(1024)
                         .setSubject(TEST_DN_1)
                         .setSerialNumber(TEST_SERIAL_1)
                         .setStartDate(NOW)
@@ -142,10 +151,207 @@
         final KeyPair pair = mGenerator.generateKeyPair();
         assertNotNull("The KeyPair returned should not be null", pair);
 
-        assertKeyPairCorrect(pair, TEST_ALIAS_1, TEST_DN_1, TEST_SERIAL_1, NOW, NOW_PLUS_10_YEARS);
+        assertKeyPairCorrect(pair, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_1, TEST_SERIAL_1, NOW,
+                NOW_PLUS_10_YEARS);
     }
 
-    public void testKeyPairGenerator_GenerateKeyPair_Unencrypted_Success() throws Exception {
+    public void testKeyPairGenerator_GenerateKeyPair_DSA_Unencrypted_Success() throws Exception {
+        mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
+                .setAlias(TEST_ALIAS_1)
+                .setKeyType("DSA")
+                .setSubject(TEST_DN_1)
+                .setSerialNumber(TEST_SERIAL_1)
+                .setStartDate(NOW)
+                .setEndDate(NOW_PLUS_10_YEARS)
+                .build());
+
+        final KeyPair pair = mGenerator.generateKeyPair();
+        assertNotNull("The KeyPair returned should not be null", pair);
+
+        assertKeyPairCorrect(pair, TEST_ALIAS_1, "DSA", 1024, null, TEST_DN_1, TEST_SERIAL_1, NOW,
+                NOW_PLUS_10_YEARS);
+    }
+
+    public void testKeyPairGenerator_GenerateKeyPair_DSA_2048_Unencrypted_Success()
+            throws Exception {
+        mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
+                .setAlias(TEST_ALIAS_1)
+                .setKeyType("DSA")
+                .setKeySize(2048)
+                .setSubject(TEST_DN_1)
+                .setSerialNumber(TEST_SERIAL_1)
+                .setStartDate(NOW)
+                .setEndDate(NOW_PLUS_10_YEARS)
+                .build());
+
+        final KeyPair pair = mGenerator.generateKeyPair();
+        assertNotNull("The KeyPair returned should not be null", pair);
+
+        assertKeyPairCorrect(pair, TEST_ALIAS_1, "DSA", 2048, null, TEST_DN_1, TEST_SERIAL_1, NOW,
+                NOW_PLUS_10_YEARS);
+    }
+
+    public void testKeyPairGenerator_GenerateKeyPair_DSA_SpecifiedParams_Unencrypted_Success()
+            throws Exception {
+        /*
+         * generated using: openssl dsaparam -C 2048
+         */
+        BigInteger p = new BigInteger(1, new byte[] {
+                (byte) 0xC0, (byte) 0x3D, (byte) 0x86, (byte) 0x09, (byte) 0xCA, (byte) 0x8C,
+                (byte) 0x37, (byte) 0xCA, (byte) 0xCC, (byte) 0x4A, (byte) 0x81, (byte) 0xBD,
+                (byte) 0xD8, (byte) 0x50, (byte) 0x77, (byte) 0xCD, (byte) 0xDD, (byte) 0x32,
+                (byte) 0x0B, (byte) 0x43, (byte) 0xBF, (byte) 0x42, (byte) 0x06, (byte) 0x5A,
+                (byte) 0x3D, (byte) 0x18, (byte) 0x50, (byte) 0x47, (byte) 0x79, (byte) 0xE1,
+                (byte) 0x5B, (byte) 0x86, (byte) 0x03, (byte) 0xB9, (byte) 0x28, (byte) 0x9C,
+                (byte) 0x18, (byte) 0xA9, (byte) 0xF5, (byte) 0xD6, (byte) 0xF4, (byte) 0x94,
+                (byte) 0x5B, (byte) 0x87, (byte) 0x58, (byte) 0xCA, (byte) 0xB2, (byte) 0x1E,
+                (byte) 0xFC, (byte) 0xED, (byte) 0x37, (byte) 0xC3, (byte) 0x49, (byte) 0xAC,
+                (byte) 0xFA, (byte) 0x46, (byte) 0xDB, (byte) 0x7A, (byte) 0x50, (byte) 0x96,
+                (byte) 0xCF, (byte) 0x52, (byte) 0xD7, (byte) 0x4E, (byte) 0xEB, (byte) 0x26,
+                (byte) 0x41, (byte) 0xA2, (byte) 0x6F, (byte) 0x99, (byte) 0x80, (byte) 0x9F,
+                (byte) 0x0F, (byte) 0x0A, (byte) 0xA8, (byte) 0x0D, (byte) 0xAC, (byte) 0xAB,
+                (byte) 0xEF, (byte) 0x7D, (byte) 0xE7, (byte) 0x4C, (byte) 0xF1, (byte) 0x88,
+                (byte) 0x44, (byte) 0xC9, (byte) 0x17, (byte) 0xD0, (byte) 0xBB, (byte) 0xE2,
+                (byte) 0x01, (byte) 0x8C, (byte) 0xC1, (byte) 0x02, (byte) 0x1D, (byte) 0x3C,
+                (byte) 0x15, (byte) 0xB7, (byte) 0x41, (byte) 0x30, (byte) 0xD8, (byte) 0x11,
+                (byte) 0xBD, (byte) 0x6A, (byte) 0x2A, (byte) 0x0D, (byte) 0x36, (byte) 0x44,
+                (byte) 0x9C, (byte) 0x3F, (byte) 0x32, (byte) 0xE2, (byte) 0x1C, (byte) 0xFB,
+                (byte) 0xE3, (byte) 0xFF, (byte) 0xCC, (byte) 0x1A, (byte) 0x72, (byte) 0x38,
+                (byte) 0x37, (byte) 0x69, (byte) 0x5E, (byte) 0x35, (byte) 0x73, (byte) 0xE1,
+                (byte) 0x1E, (byte) 0x74, (byte) 0x35, (byte) 0x44, (byte) 0x07, (byte) 0xB5,
+                (byte) 0x2F, (byte) 0x0B, (byte) 0x60, (byte) 0xF4, (byte) 0xA9, (byte) 0xE0,
+                (byte) 0x81, (byte) 0xB2, (byte) 0xCD, (byte) 0x8B, (byte) 0x82, (byte) 0x76,
+                (byte) 0x7F, (byte) 0xD4, (byte) 0x17, (byte) 0x32, (byte) 0x86, (byte) 0x98,
+                (byte) 0x7C, (byte) 0x85, (byte) 0x66, (byte) 0xF6, (byte) 0x77, (byte) 0xED,
+                (byte) 0x8B, (byte) 0x1A, (byte) 0x52, (byte) 0x16, (byte) 0xDA, (byte) 0x1C,
+                (byte) 0xA7, (byte) 0x16, (byte) 0x79, (byte) 0x20, (byte) 0x1C, (byte) 0x99,
+                (byte) 0x5F, (byte) 0x12, (byte) 0x66, (byte) 0x15, (byte) 0x9F, (byte) 0xE5,
+                (byte) 0x73, (byte) 0xA9, (byte) 0x61, (byte) 0xBA, (byte) 0xA7, (byte) 0x23,
+                (byte) 0x93, (byte) 0x77, (byte) 0xB5, (byte) 0xF6, (byte) 0xEC, (byte) 0x13,
+                (byte) 0xBF, (byte) 0x95, (byte) 0x60, (byte) 0x78, (byte) 0x84, (byte) 0xE3,
+                (byte) 0x44, (byte) 0xEC, (byte) 0x74, (byte) 0xC2, (byte) 0xCB, (byte) 0xD4,
+                (byte) 0x70, (byte) 0xC5, (byte) 0x7B, (byte) 0xF8, (byte) 0x07, (byte) 0x3B,
+                (byte) 0xEB, (byte) 0x9F, (byte) 0xC9, (byte) 0x7D, (byte) 0xE0, (byte) 0xA5,
+                (byte) 0xBA, (byte) 0x68, (byte) 0x7B, (byte) 0xF4, (byte) 0x70, (byte) 0x40,
+                (byte) 0xAE, (byte) 0xE9, (byte) 0x65, (byte) 0xEE, (byte) 0x5B, (byte) 0x71,
+                (byte) 0x36, (byte) 0x0B, (byte) 0xB0, (byte) 0xA2, (byte) 0x98, (byte) 0x7D,
+                (byte) 0xE3, (byte) 0x24, (byte) 0x95, (byte) 0x2B, (byte) 0xC2, (byte) 0x0A,
+                (byte) 0x78, (byte) 0x3D, (byte) 0xCC, (byte) 0x3A, (byte) 0xEE, (byte) 0xED,
+                (byte) 0x48, (byte) 0xEB, (byte) 0xA3, (byte) 0x78, (byte) 0xA8, (byte) 0x9D,
+                (byte) 0x0A, (byte) 0x8F, (byte) 0x9E, (byte) 0x59, (byte) 0x2C, (byte) 0x44,
+                (byte) 0xB5, (byte) 0xF9, (byte) 0x53, (byte) 0x43,
+        });
+
+        BigInteger q = new BigInteger(1, new byte[] {
+                (byte) 0xA1, (byte) 0x9B, (byte) 0x1D, (byte) 0xC0, (byte) 0xE3, (byte) 0xF6,
+                (byte) 0x4A, (byte) 0x35, (byte) 0xE1, (byte) 0x8A, (byte) 0x43, (byte) 0xC2,
+                (byte) 0x9C, (byte) 0xF9, (byte) 0x52, (byte) 0x8F, (byte) 0x94, (byte) 0xA1,
+                (byte) 0x12, (byte) 0x11, (byte) 0xDB, (byte) 0x9A, (byte) 0xB6, (byte) 0x35,
+                (byte) 0x56, (byte) 0x26, (byte) 0x60, (byte) 0x89, (byte) 0x11, (byte) 0xAC,
+                (byte) 0xA8, (byte) 0xE5,
+        });
+
+        BigInteger g = new BigInteger(1, new byte[] {
+                (byte) 0xA1, (byte) 0x5C, (byte) 0x57, (byte) 0x15, (byte) 0xC3, (byte) 0xD9,
+                (byte) 0xD7, (byte) 0x41, (byte) 0x89, (byte) 0xD6, (byte) 0xB8, (byte) 0x7B,
+                (byte) 0xF3, (byte) 0xE0, (byte) 0xB3, (byte) 0xC5, (byte) 0xD1, (byte) 0xAA,
+                (byte) 0xF9, (byte) 0x55, (byte) 0x48, (byte) 0xF1, (byte) 0xDA, (byte) 0xE8,
+                (byte) 0x6F, (byte) 0x51, (byte) 0x05, (byte) 0xB2, (byte) 0xC9, (byte) 0x64,
+                (byte) 0xDA, (byte) 0x5F, (byte) 0xD4, (byte) 0xAA, (byte) 0xFD, (byte) 0x67,
+                (byte) 0xE0, (byte) 0x10, (byte) 0x2C, (byte) 0x1F, (byte) 0x03, (byte) 0x10,
+                (byte) 0xD4, (byte) 0x4B, (byte) 0x20, (byte) 0x82, (byte) 0x2B, (byte) 0x04,
+                (byte) 0xF9, (byte) 0x09, (byte) 0xAE, (byte) 0x28, (byte) 0x3D, (byte) 0x9B,
+                (byte) 0xFF, (byte) 0x87, (byte) 0x76, (byte) 0xCD, (byte) 0xF0, (byte) 0x11,
+                (byte) 0xB7, (byte) 0xEA, (byte) 0xE6, (byte) 0xCD, (byte) 0x60, (byte) 0xD3,
+                (byte) 0x8C, (byte) 0x74, (byte) 0xD3, (byte) 0x45, (byte) 0x63, (byte) 0x69,
+                (byte) 0x3F, (byte) 0x1D, (byte) 0x31, (byte) 0x25, (byte) 0x49, (byte) 0x97,
+                (byte) 0x4B, (byte) 0x73, (byte) 0x34, (byte) 0x12, (byte) 0x73, (byte) 0x27,
+                (byte) 0x4C, (byte) 0xDA, (byte) 0xF3, (byte) 0x08, (byte) 0xA8, (byte) 0xA9,
+                (byte) 0x27, (byte) 0xE4, (byte) 0xB8, (byte) 0xD6, (byte) 0xB5, (byte) 0xC4,
+                (byte) 0x18, (byte) 0xED, (byte) 0xBD, (byte) 0x6F, (byte) 0xA2, (byte) 0x36,
+                (byte) 0xA2, (byte) 0x9C, (byte) 0x27, (byte) 0x62, (byte) 0x7F, (byte) 0x93,
+                (byte) 0xD7, (byte) 0x52, (byte) 0xA9, (byte) 0x76, (byte) 0x55, (byte) 0x99,
+                (byte) 0x00, (byte) 0x5B, (byte) 0xC2, (byte) 0xB9, (byte) 0x18, (byte) 0xAC,
+                (byte) 0x6B, (byte) 0x83, (byte) 0x0D, (byte) 0xA1, (byte) 0xC5, (byte) 0x01,
+                (byte) 0x1A, (byte) 0xE5, (byte) 0x4D, (byte) 0x2F, (byte) 0xCF, (byte) 0x5D,
+                (byte) 0xB2, (byte) 0xE7, (byte) 0xC7, (byte) 0xCB, (byte) 0x2C, (byte) 0xFF,
+                (byte) 0x51, (byte) 0x1B, (byte) 0x9D, (byte) 0xA4, (byte) 0x05, (byte) 0xEB,
+                (byte) 0x17, (byte) 0xD8, (byte) 0x97, (byte) 0x9D, (byte) 0x0C, (byte) 0x59,
+                (byte) 0x92, (byte) 0x8A, (byte) 0x03, (byte) 0x34, (byte) 0xFD, (byte) 0x16,
+                (byte) 0x0F, (byte) 0x2A, (byte) 0xF9, (byte) 0x7D, (byte) 0xC3, (byte) 0x41,
+                (byte) 0x0D, (byte) 0x06, (byte) 0x5A, (byte) 0x4B, (byte) 0x34, (byte) 0xD5,
+                (byte) 0xF5, (byte) 0x09, (byte) 0x1C, (byte) 0xCE, (byte) 0xA7, (byte) 0x19,
+                (byte) 0x6D, (byte) 0x04, (byte) 0x53, (byte) 0x71, (byte) 0xCC, (byte) 0x84,
+                (byte) 0xA0, (byte) 0xB2, (byte) 0xA0, (byte) 0x68, (byte) 0xA3, (byte) 0x40,
+                (byte) 0xC0, (byte) 0x67, (byte) 0x38, (byte) 0x96, (byte) 0x73, (byte) 0x2E,
+                (byte) 0x8E, (byte) 0x2A, (byte) 0x9D, (byte) 0x56, (byte) 0xE9, (byte) 0xAC,
+                (byte) 0xC7, (byte) 0xEC, (byte) 0x84, (byte) 0x7F, (byte) 0xFC, (byte) 0xE0,
+                (byte) 0x69, (byte) 0x03, (byte) 0x8B, (byte) 0x48, (byte) 0x64, (byte) 0x76,
+                (byte) 0x85, (byte) 0xA5, (byte) 0x10, (byte) 0xD9, (byte) 0x31, (byte) 0xC3,
+                (byte) 0x8B, (byte) 0x07, (byte) 0x48, (byte) 0x62, (byte) 0xF6, (byte) 0x68,
+                (byte) 0xF2, (byte) 0x96, (byte) 0xB2, (byte) 0x18, (byte) 0x5B, (byte) 0xFF,
+                (byte) 0x6D, (byte) 0xD1, (byte) 0x6B, (byte) 0xF5, (byte) 0xFD, (byte) 0x81,
+                (byte) 0xF1, (byte) 0xFD, (byte) 0x04, (byte) 0xF0, (byte) 0x9F, (byte) 0xB7,
+                (byte) 0x08, (byte) 0x95, (byte) 0x57, (byte) 0x48, (byte) 0x07, (byte) 0x00,
+                (byte) 0x52, (byte) 0xEC, (byte) 0x75, (byte) 0x91, (byte) 0x02, (byte) 0x11,
+                (byte) 0xA3, (byte) 0x64, (byte) 0x26, (byte) 0xCA,
+        });
+
+        AlgorithmParameterSpec spec = new DSAParameterSpec(p, q, g);
+        mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
+                .setAlias(TEST_ALIAS_1)
+                .setKeyType("DSA")
+                .setKeySize(2048)
+                .setAlgorithmParameterSpec(spec)
+                .setSubject(TEST_DN_1)
+                .setSerialNumber(TEST_SERIAL_1)
+                .setStartDate(NOW)
+                .setEndDate(NOW_PLUS_10_YEARS)
+                .build());
+
+        final KeyPair pair = mGenerator.generateKeyPair();
+        assertNotNull("The KeyPair returned should not be null", pair);
+
+        assertKeyPairCorrect(pair, TEST_ALIAS_1, "DSA", 2048, spec, TEST_DN_1, TEST_SERIAL_1, NOW,
+                NOW_PLUS_10_YEARS);
+    }
+
+    public void testKeyPairGenerator_GenerateKeyPair_EC_Unencrypted_Success() throws Exception {
+        mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
+                .setAlias(TEST_ALIAS_1)
+                .setKeyType("EC")
+                .setSubject(TEST_DN_1)
+                .setSerialNumber(TEST_SERIAL_1)
+                .setStartDate(NOW)
+                .setEndDate(NOW_PLUS_10_YEARS)
+                .build());
+
+        final KeyPair pair = mGenerator.generateKeyPair();
+        assertNotNull("The KeyPair returned should not be null", pair);
+
+        assertKeyPairCorrect(pair, TEST_ALIAS_1, "EC", 256, null, TEST_DN_1, TEST_SERIAL_1, NOW,
+                NOW_PLUS_10_YEARS);
+    }
+
+    public void testKeyPairGenerator_GenerateKeyPair_EC_P521_Unencrypted_Success() throws Exception {
+        mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
+                .setAlias(TEST_ALIAS_1)
+                .setKeyType("EC")
+                .setKeySize(521)
+                .setSubject(TEST_DN_1)
+                .setSerialNumber(TEST_SERIAL_1)
+                .setStartDate(NOW)
+                .setEndDate(NOW_PLUS_10_YEARS)
+                .build());
+
+        final KeyPair pair = mGenerator.generateKeyPair();
+        assertNotNull("The KeyPair returned should not be null", pair);
+
+        assertKeyPairCorrect(pair, TEST_ALIAS_1, "EC", 521, null, TEST_DN_1, TEST_SERIAL_1, NOW,
+                NOW_PLUS_10_YEARS);
+    }
+
+    public void testKeyPairGenerator_GenerateKeyPair_RSA_Unencrypted_Success() throws Exception {
         mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
                 .setAlias(TEST_ALIAS_1)
                 .setSubject(TEST_DN_1)
@@ -157,7 +363,28 @@
         final KeyPair pair = mGenerator.generateKeyPair();
         assertNotNull("The KeyPair returned should not be null", pair);
 
-        assertKeyPairCorrect(pair, TEST_ALIAS_1, TEST_DN_1, TEST_SERIAL_1, NOW, NOW_PLUS_10_YEARS);
+        assertKeyPairCorrect(pair, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_1, TEST_SERIAL_1, NOW,
+                NOW_PLUS_10_YEARS);
+    }
+
+    public void testKeyPairGenerator_GenerateKeyPair_RSA_WithParams_Unencrypted_Success()
+            throws Exception {
+        AlgorithmParameterSpec spec = new RSAKeyGenParameterSpec(1024, BigInteger.valueOf(3L));
+        mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
+                .setAlias(TEST_ALIAS_1)
+                .setKeySize(1024)
+                .setAlgorithmParameterSpec(spec)
+                .setSubject(TEST_DN_1)
+                .setSerialNumber(TEST_SERIAL_1)
+                .setStartDate(NOW)
+                .setEndDate(NOW_PLUS_10_YEARS)
+                .build());
+
+        final KeyPair pair = mGenerator.generateKeyPair();
+        assertNotNull("The KeyPair returned should not be null", pair);
+
+        assertKeyPairCorrect(pair, TEST_ALIAS_1, "RSA", 1024, spec, TEST_DN_1, TEST_SERIAL_1, NOW,
+                NOW_PLUS_10_YEARS);
     }
 
     public void testKeyPairGenerator_GenerateKeyPair_Replaced_Success() throws Exception {
@@ -172,8 +399,8 @@
                     .build());
             final KeyPair pair1 = mGenerator.generateKeyPair();
             assertNotNull("The KeyPair returned should not be null", pair1);
-            assertKeyPairCorrect(pair1, TEST_ALIAS_1, TEST_DN_1, TEST_SERIAL_1, NOW,
-                    NOW_PLUS_10_YEARS);
+            assertKeyPairCorrect(pair1, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_1, TEST_SERIAL_1,
+                    NOW, NOW_PLUS_10_YEARS);
         }
 
         // Replace the original key
@@ -187,8 +414,8 @@
                     .build());
             final KeyPair pair2 = mGenerator.generateKeyPair();
             assertNotNull("The KeyPair returned should not be null", pair2);
-            assertKeyPairCorrect(pair2, TEST_ALIAS_2, TEST_DN_2, TEST_SERIAL_2, NOW,
-                    NOW_PLUS_10_YEARS);
+            assertKeyPairCorrect(pair2, TEST_ALIAS_2, "RSA", 2048, null, TEST_DN_2, TEST_SERIAL_2,
+                    NOW, NOW_PLUS_10_YEARS);
         }
     }
 
@@ -205,8 +432,8 @@
                     .build());
             final KeyPair pair1 = mGenerator.generateKeyPair();
             assertNotNull("The KeyPair returned should not be null", pair1);
-            assertKeyPairCorrect(pair1, TEST_ALIAS_1, TEST_DN_1, TEST_SERIAL_1, NOW,
-                    NOW_PLUS_10_YEARS);
+            assertKeyPairCorrect(pair1, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_1, TEST_SERIAL_1,
+                    NOW, NOW_PLUS_10_YEARS);
         }
 
         // Attempt to replace previous key
@@ -230,18 +457,45 @@
 
             final KeyPair pair2 = mGenerator.generateKeyPair();
             assertNotNull("The KeyPair returned should not be null", pair2);
-            assertKeyPairCorrect(pair2, TEST_ALIAS_1, TEST_DN_2, TEST_SERIAL_2, NOW,
-                    NOW_PLUS_10_YEARS);
+            assertKeyPairCorrect(pair2, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_2, TEST_SERIAL_2,
+                    NOW, NOW_PLUS_10_YEARS);
         }
     }
 
-    private void assertKeyPairCorrect(KeyPair pair, String alias, X500Principal dn,
-            BigInteger serial, Date start, Date end) throws Exception {
+    private void assertKeyPairCorrect(KeyPair pair, String alias, String keyType, int keySize,
+            AlgorithmParameterSpec spec, X500Principal dn, BigInteger serial, Date start, Date end)
+            throws Exception {
         final PublicKey pubKey = pair.getPublic();
         assertNotNull("The PublicKey for the KeyPair should be not null", pubKey);
+        assertEquals(keyType, pubKey.getAlgorithm());
+
+        if ("DSA".equalsIgnoreCase(keyType)) {
+            DSAPublicKey dsaPubKey = (DSAPublicKey) pubKey;
+            DSAParams actualParams = dsaPubKey.getParams();
+            assertEquals(keySize, (actualParams.getP().bitLength() + 7) & ~7);
+            if (spec != null) {
+                DSAParameterSpec expectedParams = (DSAParameterSpec) spec;
+                assertEquals(expectedParams.getP(), actualParams.getP());
+                assertEquals(expectedParams.getQ(), actualParams.getQ());
+                assertEquals(expectedParams.getG(), actualParams.getG());
+            }
+        } else if ("EC".equalsIgnoreCase(keyType)) {
+            assertEquals("Curve should be what was specified during initialization", keySize,
+                    ((ECPublicKey) pubKey).getParams().getCurve().getField().getFieldSize());
+        } else if ("RSA".equalsIgnoreCase(keyType)) {
+            RSAPublicKey rsaPubKey = (RSAPublicKey) pubKey;
+            assertEquals("Modulus size should be what is specified during initialization",
+                    (keySize + 7) & ~7, (rsaPubKey.getModulus().bitLength() + 7) & ~7);
+            if (spec != null) {
+                RSAKeyGenParameterSpec params = (RSAKeyGenParameterSpec) spec;
+                assertEquals((keySize + 7) & ~7, (params.getKeysize() + 7) & ~7);
+                assertEquals(params.getPublicExponent(), rsaPubKey.getPublicExponent());
+            }
+        }
 
         final PrivateKey privKey = pair.getPrivate();
         assertNotNull("The PrivateKey for the KeyPair should be not null", privKey);
+        assertEquals(keyType, privKey.getAlgorithm());
 
         final byte[] userCertBytes = mAndroidKeyStore.get(Credentials.USER_CERTIFICATE + alias);
         assertNotNull("The user certificate should exist for the generated entry", userCertBytes);
diff --git a/keystore/tests/src/android/security/AndroidKeyStoreTest.java b/keystore/tests/src/android/security/AndroidKeyStoreTest.java
index b7129db..6597d3f 100644
--- a/keystore/tests/src/android/security/AndroidKeyStoreTest.java
+++ b/keystore/tests/src/android/security/AndroidKeyStoreTest.java
@@ -18,7 +18,9 @@
 
 import com.android.org.bouncycastle.x509.X509V3CertificateGenerator;
 
+import com.android.org.conscrypt.NativeCrypto;
 import com.android.org.conscrypt.OpenSSLEngine;
+import com.android.org.conscrypt.OpenSSLKeyHolder;
 
 import android.test.AndroidTestCase;
 
@@ -39,6 +41,10 @@
 import java.security.cert.Certificate;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
+import java.security.interfaces.DSAPrivateKey;
+import java.security.interfaces.DSAPublicKey;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.ECPublicKey;
 import java.security.interfaces.RSAPrivateKey;
 import java.security.spec.InvalidKeySpecException;
 import java.security.spec.PKCS8EncodedKeySpec;
@@ -99,7 +105,7 @@
      *
      * openssl x509 -outform d -in cacert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
      */
-    private static final byte[] FAKE_CA_1 = {
+    private static final byte[] FAKE_RSA_CA_1 = {
             (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0xce, (byte) 0x30, (byte) 0x82,
             (byte) 0x02, (byte) 0x37, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
             (byte) 0x02, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0xe1, (byte) 0x6a,
@@ -228,7 +234,7 @@
      *
      * openssl pkcs8 -topk8 -outform d -in userkey.pem -nocrypt | xxd -i | sed 's/0x/(byte) 0x/g'
      */
-    private static final byte[] FAKE_KEY_1 = new byte[] {
+    private static final byte[] FAKE_RSA_KEY_1 = new byte[] {
             (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x78, (byte) 0x02, (byte) 0x01,
             (byte) 0x00, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
             (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
@@ -342,7 +348,7 @@
      *
      * openssl x509 -outform d -in usercert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
      */
-    private static final byte[] FAKE_USER_1 = new byte[] {
+    private static final byte[] FAKE_RSA_USER_1 = new byte[] {
             (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x95, (byte) 0x30, (byte) 0x82,
             (byte) 0x01, (byte) 0xfe, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
             (byte) 0x02, (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x30, (byte) 0x0d,
@@ -456,6 +462,628 @@
             (byte) 0x08, (byte) 0x41, (byte) 0x0a, (byte) 0xf3, (byte) 0x72
     };
 
+    /*
+     * The keys and certificates below are generated with:
+     *
+     * openssl req -new -x509 -days 3650 -extensions v3_ca -keyout cakey.pem -out cacert.pem
+     * openssl ecparam -name prime256v1 -out ecparam.pem
+     * openssl req -newkey ec:ecparam.pem -keyout userkey.pem -nodes -days 3650 -out userkey.req
+     * mkdir -p demoCA/newcerts
+     * touch demoCA/index.txt
+     * echo "01" > demoCA/serial
+     * openssl ca -out usercert.pem -in userkey.req -cert cacert.pem -keyfile cakey.pem -days 3650
+     */
+
+    /**
+     * Generated from above and converted with:
+     *
+     * openssl x509 -outform d -in cacert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] FAKE_EC_CA_1 = {
+            (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x58, (byte) 0x30, (byte) 0x82,
+            (byte) 0x01, (byte) 0xc1, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
+            (byte) 0x02, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0xe1, (byte) 0xb2,
+            (byte) 0x8c, (byte) 0x04, (byte) 0x95, (byte) 0xeb, (byte) 0x10, (byte) 0xcb,
+            (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
+            (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
+            (byte) 0x05, (byte) 0x05, (byte) 0x00, (byte) 0x30, (byte) 0x45, (byte) 0x31,
+            (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+            (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41, (byte) 0x55,
+            (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06, (byte) 0x03,
+            (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a, (byte) 0x53,
+            (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53, (byte) 0x74,
+            (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x21, (byte) 0x30,
+            (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a,
+            (byte) 0x0c, (byte) 0x18, (byte) 0x49, (byte) 0x6e, (byte) 0x74, (byte) 0x65,
+            (byte) 0x72, (byte) 0x6e, (byte) 0x65, (byte) 0x74, (byte) 0x20, (byte) 0x57,
+            (byte) 0x69, (byte) 0x64, (byte) 0x67, (byte) 0x69, (byte) 0x74, (byte) 0x73,
+            (byte) 0x20, (byte) 0x50, (byte) 0x74, (byte) 0x79, (byte) 0x20, (byte) 0x4c,
+            (byte) 0x74, (byte) 0x64, (byte) 0x30, (byte) 0x1e, (byte) 0x17, (byte) 0x0d,
+            (byte) 0x31, (byte) 0x33, (byte) 0x30, (byte) 0x38, (byte) 0x32, (byte) 0x37,
+            (byte) 0x31, (byte) 0x36, (byte) 0x32, (byte) 0x38, (byte) 0x32, (byte) 0x38,
+            (byte) 0x5a, (byte) 0x17, (byte) 0x0d, (byte) 0x32, (byte) 0x33, (byte) 0x30,
+            (byte) 0x38, (byte) 0x32, (byte) 0x35, (byte) 0x31, (byte) 0x36, (byte) 0x32,
+            (byte) 0x38, (byte) 0x32, (byte) 0x38, (byte) 0x5a, (byte) 0x30, (byte) 0x45,
+            (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03,
+            (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41,
+            (byte) 0x55, (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06,
+            (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a,
+            (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53,
+            (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x21,
+            (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
+            (byte) 0x0a, (byte) 0x0c, (byte) 0x18, (byte) 0x49, (byte) 0x6e, (byte) 0x74,
+            (byte) 0x65, (byte) 0x72, (byte) 0x6e, (byte) 0x65, (byte) 0x74, (byte) 0x20,
+            (byte) 0x57, (byte) 0x69, (byte) 0x64, (byte) 0x67, (byte) 0x69, (byte) 0x74,
+            (byte) 0x73, (byte) 0x20, (byte) 0x50, (byte) 0x74, (byte) 0x79, (byte) 0x20,
+            (byte) 0x4c, (byte) 0x74, (byte) 0x64, (byte) 0x30, (byte) 0x81, (byte) 0x9f,
+            (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
+            (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
+            (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x81, (byte) 0x8d,
+            (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0x89, (byte) 0x02, (byte) 0x81,
+            (byte) 0x81, (byte) 0x00, (byte) 0xb5, (byte) 0xf6, (byte) 0x08, (byte) 0x0f,
+            (byte) 0xc4, (byte) 0x4d, (byte) 0xe4, (byte) 0x0d, (byte) 0x34, (byte) 0x1d,
+            (byte) 0xe2, (byte) 0x23, (byte) 0x18, (byte) 0x63, (byte) 0x03, (byte) 0xf7,
+            (byte) 0x14, (byte) 0x0e, (byte) 0x98, (byte) 0xcd, (byte) 0x45, (byte) 0x1f,
+            (byte) 0xfe, (byte) 0xfb, (byte) 0x09, (byte) 0x3f, (byte) 0x5d, (byte) 0x36,
+            (byte) 0x3b, (byte) 0x0f, (byte) 0xf9, (byte) 0x5e, (byte) 0x86, (byte) 0x56,
+            (byte) 0x64, (byte) 0xd7, (byte) 0x3f, (byte) 0xae, (byte) 0x33, (byte) 0x09,
+            (byte) 0xd3, (byte) 0xdd, (byte) 0x06, (byte) 0x17, (byte) 0x26, (byte) 0xdc,
+            (byte) 0xa2, (byte) 0x8c, (byte) 0x3c, (byte) 0x65, (byte) 0xed, (byte) 0x03,
+            (byte) 0x82, (byte) 0x78, (byte) 0x9b, (byte) 0xee, (byte) 0xe3, (byte) 0x98,
+            (byte) 0x58, (byte) 0xe1, (byte) 0xf1, (byte) 0xa0, (byte) 0x85, (byte) 0xae,
+            (byte) 0x63, (byte) 0x84, (byte) 0x41, (byte) 0x46, (byte) 0xa7, (byte) 0x4f,
+            (byte) 0xdc, (byte) 0xbb, (byte) 0x1c, (byte) 0x6e, (byte) 0xec, (byte) 0x7b,
+            (byte) 0xd5, (byte) 0xab, (byte) 0x3d, (byte) 0x6a, (byte) 0x05, (byte) 0x58,
+            (byte) 0x0f, (byte) 0x9b, (byte) 0x6a, (byte) 0x67, (byte) 0x4b, (byte) 0xe9,
+            (byte) 0x2a, (byte) 0x6d, (byte) 0x96, (byte) 0x11, (byte) 0x53, (byte) 0x95,
+            (byte) 0x78, (byte) 0xaa, (byte) 0xd1, (byte) 0x91, (byte) 0x4a, (byte) 0xf8,
+            (byte) 0x54, (byte) 0x52, (byte) 0x6d, (byte) 0xb9, (byte) 0xca, (byte) 0x74,
+            (byte) 0x81, (byte) 0xf8, (byte) 0x99, (byte) 0x64, (byte) 0xd1, (byte) 0x4f,
+            (byte) 0x01, (byte) 0x38, (byte) 0x4f, (byte) 0x08, (byte) 0x5c, (byte) 0x31,
+            (byte) 0xcb, (byte) 0x7c, (byte) 0x5c, (byte) 0x78, (byte) 0x5d, (byte) 0x47,
+            (byte) 0xd9, (byte) 0xf0, (byte) 0x1a, (byte) 0xeb, (byte) 0x02, (byte) 0x03,
+            (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xa3, (byte) 0x50, (byte) 0x30,
+            (byte) 0x4e, (byte) 0x30, (byte) 0x1d, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+            (byte) 0x1d, (byte) 0x0e, (byte) 0x04, (byte) 0x16, (byte) 0x04, (byte) 0x14,
+            (byte) 0x5f, (byte) 0x5b, (byte) 0x5e, (byte) 0xac, (byte) 0x29, (byte) 0xfa,
+            (byte) 0xa1, (byte) 0x9f, (byte) 0x9e, (byte) 0xad, (byte) 0x46, (byte) 0xe1,
+            (byte) 0xbc, (byte) 0x20, (byte) 0x72, (byte) 0xcf, (byte) 0x4a, (byte) 0xd4,
+            (byte) 0xfa, (byte) 0xe3, (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03,
+            (byte) 0x55, (byte) 0x1d, (byte) 0x23, (byte) 0x04, (byte) 0x18, (byte) 0x30,
+            (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0x5f, (byte) 0x5b, (byte) 0x5e,
+            (byte) 0xac, (byte) 0x29, (byte) 0xfa, (byte) 0xa1, (byte) 0x9f, (byte) 0x9e,
+            (byte) 0xad, (byte) 0x46, (byte) 0xe1, (byte) 0xbc, (byte) 0x20, (byte) 0x72,
+            (byte) 0xcf, (byte) 0x4a, (byte) 0xd4, (byte) 0xfa, (byte) 0xe3, (byte) 0x30,
+            (byte) 0x0c, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x13,
+            (byte) 0x04, (byte) 0x05, (byte) 0x30, (byte) 0x03, (byte) 0x01, (byte) 0x01,
+            (byte) 0xff, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
+            (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
+            (byte) 0x01, (byte) 0x05, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x81,
+            (byte) 0x81, (byte) 0x00, (byte) 0xa1, (byte) 0x4a, (byte) 0xe6, (byte) 0xfc,
+            (byte) 0x7f, (byte) 0x17, (byte) 0xaa, (byte) 0x65, (byte) 0x4a, (byte) 0x34,
+            (byte) 0xde, (byte) 0x69, (byte) 0x67, (byte) 0x54, (byte) 0x4d, (byte) 0xa2,
+            (byte) 0xc2, (byte) 0x98, (byte) 0x02, (byte) 0x43, (byte) 0x6a, (byte) 0x0e,
+            (byte) 0x0b, (byte) 0x7f, (byte) 0xa4, (byte) 0x46, (byte) 0xaf, (byte) 0xa4,
+            (byte) 0x65, (byte) 0xa0, (byte) 0xdb, (byte) 0xf1, (byte) 0x5b, (byte) 0xd5,
+            (byte) 0x09, (byte) 0xbc, (byte) 0xee, (byte) 0x37, (byte) 0x51, (byte) 0x19,
+            (byte) 0x36, (byte) 0xc0, (byte) 0x90, (byte) 0xd3, (byte) 0x5f, (byte) 0xf3,
+            (byte) 0x4f, (byte) 0xb9, (byte) 0x08, (byte) 0x45, (byte) 0x0e, (byte) 0x01,
+            (byte) 0x8a, (byte) 0x95, (byte) 0xef, (byte) 0x92, (byte) 0x95, (byte) 0x33,
+            (byte) 0x78, (byte) 0xdd, (byte) 0x90, (byte) 0xbb, (byte) 0xf3, (byte) 0x06,
+            (byte) 0x75, (byte) 0xd0, (byte) 0x66, (byte) 0xe6, (byte) 0xd0, (byte) 0x18,
+            (byte) 0x6e, (byte) 0xeb, (byte) 0x1c, (byte) 0x52, (byte) 0xc3, (byte) 0x2e,
+            (byte) 0x57, (byte) 0x7d, (byte) 0xa9, (byte) 0x03, (byte) 0xdb, (byte) 0xf4,
+            (byte) 0x57, (byte) 0x5f, (byte) 0x6c, (byte) 0x7e, (byte) 0x00, (byte) 0x0d,
+            (byte) 0x8f, (byte) 0xe8, (byte) 0x91, (byte) 0xf7, (byte) 0xae, (byte) 0x24,
+            (byte) 0x35, (byte) 0x07, (byte) 0xb5, (byte) 0x48, (byte) 0x2d, (byte) 0x36,
+            (byte) 0x30, (byte) 0x5d, (byte) 0xe9, (byte) 0x49, (byte) 0x2d, (byte) 0xd1,
+            (byte) 0x5d, (byte) 0xc5, (byte) 0xf4, (byte) 0x33, (byte) 0x77, (byte) 0x3c,
+            (byte) 0x71, (byte) 0xad, (byte) 0x90, (byte) 0x65, (byte) 0xa9, (byte) 0xc1,
+            (byte) 0x0b, (byte) 0x5c, (byte) 0x62, (byte) 0x55, (byte) 0x50, (byte) 0x6f,
+            (byte) 0x9b, (byte) 0xc9, (byte) 0x0d, (byte) 0xee
+    };
+
+    /**
+     * Generated from above and converted with:
+     *
+     * openssl pkcs8 -topk8 -outform d -in userkey.pem -nocrypt | xxd -i | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] FAKE_EC_KEY_1 = new byte[] {
+            (byte) 0x30, (byte) 0x81, (byte) 0x87, (byte) 0x02, (byte) 0x01, (byte) 0x00,
+            (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x07, (byte) 0x2a, (byte) 0x86,
+            (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x02, (byte) 0x01, (byte) 0x06,
+            (byte) 0x08, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x3d,
+            (byte) 0x03, (byte) 0x01, (byte) 0x07, (byte) 0x04, (byte) 0x6d, (byte) 0x30,
+            (byte) 0x6b, (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x04, (byte) 0x20,
+            (byte) 0x3a, (byte) 0x8a, (byte) 0x02, (byte) 0xdc, (byte) 0xde, (byte) 0x70,
+            (byte) 0x84, (byte) 0x45, (byte) 0x34, (byte) 0xaf, (byte) 0xbd, (byte) 0xd5,
+            (byte) 0x02, (byte) 0x17, (byte) 0x69, (byte) 0x90, (byte) 0x65, (byte) 0x1e,
+            (byte) 0x87, (byte) 0xf1, (byte) 0x3d, (byte) 0x17, (byte) 0xb6, (byte) 0xf4,
+            (byte) 0x31, (byte) 0x94, (byte) 0x86, (byte) 0x76, (byte) 0x55, (byte) 0xf7,
+            (byte) 0xcc, (byte) 0xba, (byte) 0xa1, (byte) 0x44, (byte) 0x03, (byte) 0x42,
+            (byte) 0x00, (byte) 0x04, (byte) 0xd9, (byte) 0xcf, (byte) 0xe7, (byte) 0x9b,
+            (byte) 0x23, (byte) 0xc8, (byte) 0xa3, (byte) 0xb8, (byte) 0x33, (byte) 0x14,
+            (byte) 0xa4, (byte) 0x4d, (byte) 0x75, (byte) 0x90, (byte) 0xf3, (byte) 0xcd,
+            (byte) 0x43, (byte) 0xe5, (byte) 0x1b, (byte) 0x05, (byte) 0x1d, (byte) 0xf3,
+            (byte) 0xd0, (byte) 0xa3, (byte) 0xb7, (byte) 0x32, (byte) 0x5f, (byte) 0x79,
+            (byte) 0xdc, (byte) 0x88, (byte) 0xb8, (byte) 0x4d, (byte) 0xb3, (byte) 0xd1,
+            (byte) 0x6d, (byte) 0xf7, (byte) 0x75, (byte) 0xf3, (byte) 0xbf, (byte) 0x50,
+            (byte) 0xa1, (byte) 0xbc, (byte) 0x03, (byte) 0x64, (byte) 0x22, (byte) 0xe6,
+            (byte) 0x1a, (byte) 0xa1, (byte) 0xe1, (byte) 0x06, (byte) 0x68, (byte) 0x3b,
+            (byte) 0xbc, (byte) 0x9f, (byte) 0xd3, (byte) 0xae, (byte) 0x77, (byte) 0x5e,
+            (byte) 0x88, (byte) 0x0c, (byte) 0x5e, (byte) 0x0c, (byte) 0xb2, (byte) 0x38
+    };
+
+    /**
+     * Generated from above and converted with:
+     *
+     * openssl x509 -outform d -in usercert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] FAKE_EC_USER_1 = new byte[] {
+            (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x51, (byte) 0x30, (byte) 0x82,
+            (byte) 0x01, (byte) 0xba, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
+            (byte) 0x02, (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x30, (byte) 0x0d,
+            (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86,
+            (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x05,
+            (byte) 0x00, (byte) 0x30, (byte) 0x45, (byte) 0x31, (byte) 0x0b, (byte) 0x30,
+            (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06,
+            (byte) 0x13, (byte) 0x02, (byte) 0x41, (byte) 0x55, (byte) 0x31, (byte) 0x13,
+            (byte) 0x30, (byte) 0x11, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
+            (byte) 0x08, (byte) 0x0c, (byte) 0x0a, (byte) 0x53, (byte) 0x6f, (byte) 0x6d,
+            (byte) 0x65, (byte) 0x2d, (byte) 0x53, (byte) 0x74, (byte) 0x61, (byte) 0x74,
+            (byte) 0x65, (byte) 0x31, (byte) 0x21, (byte) 0x30, (byte) 0x1f, (byte) 0x06,
+            (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x18,
+            (byte) 0x49, (byte) 0x6e, (byte) 0x74, (byte) 0x65, (byte) 0x72, (byte) 0x6e,
+            (byte) 0x65, (byte) 0x74, (byte) 0x20, (byte) 0x57, (byte) 0x69, (byte) 0x64,
+            (byte) 0x67, (byte) 0x69, (byte) 0x74, (byte) 0x73, (byte) 0x20, (byte) 0x50,
+            (byte) 0x74, (byte) 0x79, (byte) 0x20, (byte) 0x4c, (byte) 0x74, (byte) 0x64,
+            (byte) 0x30, (byte) 0x1e, (byte) 0x17, (byte) 0x0d, (byte) 0x31, (byte) 0x33,
+            (byte) 0x30, (byte) 0x38, (byte) 0x32, (byte) 0x37, (byte) 0x31, (byte) 0x36,
+            (byte) 0x33, (byte) 0x30, (byte) 0x30, (byte) 0x38, (byte) 0x5a, (byte) 0x17,
+            (byte) 0x0d, (byte) 0x32, (byte) 0x33, (byte) 0x30, (byte) 0x38, (byte) 0x32,
+            (byte) 0x35, (byte) 0x31, (byte) 0x36, (byte) 0x33, (byte) 0x30, (byte) 0x30,
+            (byte) 0x38, (byte) 0x5a, (byte) 0x30, (byte) 0x62, (byte) 0x31, (byte) 0x0b,
+            (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
+            (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41, (byte) 0x55, (byte) 0x31,
+            (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+            (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a, (byte) 0x53, (byte) 0x6f,
+            (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53, (byte) 0x74, (byte) 0x61,
+            (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x21, (byte) 0x30, (byte) 0x1f,
+            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c,
+            (byte) 0x18, (byte) 0x49, (byte) 0x6e, (byte) 0x74, (byte) 0x65, (byte) 0x72,
+            (byte) 0x6e, (byte) 0x65, (byte) 0x74, (byte) 0x20, (byte) 0x57, (byte) 0x69,
+            (byte) 0x64, (byte) 0x67, (byte) 0x69, (byte) 0x74, (byte) 0x73, (byte) 0x20,
+            (byte) 0x50, (byte) 0x74, (byte) 0x79, (byte) 0x20, (byte) 0x4c, (byte) 0x74,
+            (byte) 0x64, (byte) 0x31, (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06,
+            (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x12,
+            (byte) 0x73, (byte) 0x65, (byte) 0x72, (byte) 0x76, (byte) 0x65, (byte) 0x72,
+            (byte) 0x2e, (byte) 0x65, (byte) 0x78, (byte) 0x61, (byte) 0x6d, (byte) 0x70,
+            (byte) 0x6c, (byte) 0x65, (byte) 0x2e, (byte) 0x63, (byte) 0x6f, (byte) 0x6d,
+            (byte) 0x30, (byte) 0x59, (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x07,
+            (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x02,
+            (byte) 0x01, (byte) 0x06, (byte) 0x08, (byte) 0x2a, (byte) 0x86, (byte) 0x48,
+            (byte) 0xce, (byte) 0x3d, (byte) 0x03, (byte) 0x01, (byte) 0x07, (byte) 0x03,
+            (byte) 0x42, (byte) 0x00, (byte) 0x04, (byte) 0xd9, (byte) 0xcf, (byte) 0xe7,
+            (byte) 0x9b, (byte) 0x23, (byte) 0xc8, (byte) 0xa3, (byte) 0xb8, (byte) 0x33,
+            (byte) 0x14, (byte) 0xa4, (byte) 0x4d, (byte) 0x75, (byte) 0x90, (byte) 0xf3,
+            (byte) 0xcd, (byte) 0x43, (byte) 0xe5, (byte) 0x1b, (byte) 0x05, (byte) 0x1d,
+            (byte) 0xf3, (byte) 0xd0, (byte) 0xa3, (byte) 0xb7, (byte) 0x32, (byte) 0x5f,
+            (byte) 0x79, (byte) 0xdc, (byte) 0x88, (byte) 0xb8, (byte) 0x4d, (byte) 0xb3,
+            (byte) 0xd1, (byte) 0x6d, (byte) 0xf7, (byte) 0x75, (byte) 0xf3, (byte) 0xbf,
+            (byte) 0x50, (byte) 0xa1, (byte) 0xbc, (byte) 0x03, (byte) 0x64, (byte) 0x22,
+            (byte) 0xe6, (byte) 0x1a, (byte) 0xa1, (byte) 0xe1, (byte) 0x06, (byte) 0x68,
+            (byte) 0x3b, (byte) 0xbc, (byte) 0x9f, (byte) 0xd3, (byte) 0xae, (byte) 0x77,
+            (byte) 0x5e, (byte) 0x88, (byte) 0x0c, (byte) 0x5e, (byte) 0x0c, (byte) 0xb2,
+            (byte) 0x38, (byte) 0xa3, (byte) 0x7b, (byte) 0x30, (byte) 0x79, (byte) 0x30,
+            (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x13,
+            (byte) 0x04, (byte) 0x02, (byte) 0x30, (byte) 0x00, (byte) 0x30, (byte) 0x2c,
+            (byte) 0x06, (byte) 0x09, (byte) 0x60, (byte) 0x86, (byte) 0x48, (byte) 0x01,
+            (byte) 0x86, (byte) 0xf8, (byte) 0x42, (byte) 0x01, (byte) 0x0d, (byte) 0x04,
+            (byte) 0x1f, (byte) 0x16, (byte) 0x1d, (byte) 0x4f, (byte) 0x70, (byte) 0x65,
+            (byte) 0x6e, (byte) 0x53, (byte) 0x53, (byte) 0x4c, (byte) 0x20, (byte) 0x47,
+            (byte) 0x65, (byte) 0x6e, (byte) 0x65, (byte) 0x72, (byte) 0x61, (byte) 0x74,
+            (byte) 0x65, (byte) 0x64, (byte) 0x20, (byte) 0x43, (byte) 0x65, (byte) 0x72,
+            (byte) 0x74, (byte) 0x69, (byte) 0x66, (byte) 0x69, (byte) 0x63, (byte) 0x61,
+            (byte) 0x74, (byte) 0x65, (byte) 0x30, (byte) 0x1d, (byte) 0x06, (byte) 0x03,
+            (byte) 0x55, (byte) 0x1d, (byte) 0x0e, (byte) 0x04, (byte) 0x16, (byte) 0x04,
+            (byte) 0x14, (byte) 0xd5, (byte) 0xc4, (byte) 0x72, (byte) 0xbd, (byte) 0xd2,
+            (byte) 0x4e, (byte) 0x90, (byte) 0x1b, (byte) 0x14, (byte) 0x32, (byte) 0xdb,
+            (byte) 0x03, (byte) 0xae, (byte) 0xfa, (byte) 0x27, (byte) 0x7d, (byte) 0x8d,
+            (byte) 0xe4, (byte) 0x80, (byte) 0x58, (byte) 0x30, (byte) 0x1f, (byte) 0x06,
+            (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x23, (byte) 0x04, (byte) 0x18,
+            (byte) 0x30, (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0x5f, (byte) 0x5b,
+            (byte) 0x5e, (byte) 0xac, (byte) 0x29, (byte) 0xfa, (byte) 0xa1, (byte) 0x9f,
+            (byte) 0x9e, (byte) 0xad, (byte) 0x46, (byte) 0xe1, (byte) 0xbc, (byte) 0x20,
+            (byte) 0x72, (byte) 0xcf, (byte) 0x4a, (byte) 0xd4, (byte) 0xfa, (byte) 0xe3,
+            (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
+            (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
+            (byte) 0x05, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x81, (byte) 0x81,
+            (byte) 0x00, (byte) 0x43, (byte) 0x99, (byte) 0x9f, (byte) 0x67, (byte) 0x08,
+            (byte) 0x43, (byte) 0xd5, (byte) 0x6b, (byte) 0x6f, (byte) 0xd7, (byte) 0x05,
+            (byte) 0xd6, (byte) 0x75, (byte) 0x34, (byte) 0x30, (byte) 0xca, (byte) 0x20,
+            (byte) 0x47, (byte) 0x61, (byte) 0xa1, (byte) 0x89, (byte) 0xb6, (byte) 0xf1,
+            (byte) 0x49, (byte) 0x7b, (byte) 0xd9, (byte) 0xb9, (byte) 0xe8, (byte) 0x1e,
+            (byte) 0x29, (byte) 0x74, (byte) 0x0a, (byte) 0x67, (byte) 0xc0, (byte) 0x7d,
+            (byte) 0xb8, (byte) 0xe6, (byte) 0x39, (byte) 0xa8, (byte) 0x5e, (byte) 0xc3,
+            (byte) 0xb0, (byte) 0xa1, (byte) 0x30, (byte) 0x6a, (byte) 0x1f, (byte) 0x1d,
+            (byte) 0xfc, (byte) 0x11, (byte) 0x59, (byte) 0x0b, (byte) 0xb9, (byte) 0xad,
+            (byte) 0x3a, (byte) 0x4e, (byte) 0x50, (byte) 0x0a, (byte) 0x61, (byte) 0xdb,
+            (byte) 0x75, (byte) 0x6b, (byte) 0xe5, (byte) 0x3f, (byte) 0x8d, (byte) 0xde,
+            (byte) 0x28, (byte) 0x68, (byte) 0xb1, (byte) 0x29, (byte) 0x9a, (byte) 0x18,
+            (byte) 0x8a, (byte) 0xfc, (byte) 0x3f, (byte) 0x13, (byte) 0x93, (byte) 0x29,
+            (byte) 0xed, (byte) 0x22, (byte) 0x7c, (byte) 0xb4, (byte) 0x50, (byte) 0xd5,
+            (byte) 0x4d, (byte) 0x32, (byte) 0x4d, (byte) 0x42, (byte) 0x2b, (byte) 0x29,
+            (byte) 0x97, (byte) 0x86, (byte) 0xc0, (byte) 0x01, (byte) 0x00, (byte) 0x25,
+            (byte) 0xf6, (byte) 0xd3, (byte) 0x2a, (byte) 0xd8, (byte) 0xda, (byte) 0x13,
+            (byte) 0x94, (byte) 0x12, (byte) 0x78, (byte) 0x14, (byte) 0x0b, (byte) 0x51,
+            (byte) 0xc0, (byte) 0x45, (byte) 0xb4, (byte) 0x02, (byte) 0x37, (byte) 0x98,
+            (byte) 0x42, (byte) 0x3c, (byte) 0xcb, (byte) 0x2e, (byte) 0xe4, (byte) 0x38,
+            (byte) 0x69, (byte) 0x1b, (byte) 0x72, (byte) 0xf0, (byte) 0xaa, (byte) 0x89,
+            (byte) 0x7e, (byte) 0xde, (byte) 0xb2
+    };
+
+    /*
+     * The keys and certificates below are generated with:
+     *
+     * openssl req -new -x509 -days 3650 -extensions v3_ca -keyout cakey.pem -out cacert.pem
+     * openssl dsaparam -out dsaparam.pem 1024
+     * openssl req -newkey dsa:dsaparam.pem -keyout userkey.pem -nodes -days 3650 -out userkey.req
+     * mkdir -p demoCA/newcerts
+     * touch demoCA/index.txt
+     * echo "01" > demoCA/serial
+     * openssl ca -out usercert.pem -in userkey.req -cert cacert.pem -keyfile cakey.pem -days 3650
+     */
+
+    /**
+     * Generated from above and converted with:
+     *
+     * openssl x509 -outform d -in cacert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] FAKE_DSA_CA_1 = new byte[] {
+            (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x8a, (byte) 0x30, (byte) 0x82,
+            (byte) 0x01, (byte) 0xf3, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
+            (byte) 0x02, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0x87, (byte) 0xc0,
+            (byte) 0x68, (byte) 0x7f, (byte) 0x42, (byte) 0x92, (byte) 0x0b, (byte) 0x7a,
+            (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
+            (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
+            (byte) 0x05, (byte) 0x05, (byte) 0x00, (byte) 0x30, (byte) 0x5e, (byte) 0x31,
+            (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+            (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41, (byte) 0x55,
+            (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06, (byte) 0x03,
+            (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a, (byte) 0x53,
+            (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53, (byte) 0x74,
+            (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x21, (byte) 0x30,
+            (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a,
+            (byte) 0x0c, (byte) 0x18, (byte) 0x49, (byte) 0x6e, (byte) 0x74, (byte) 0x65,
+            (byte) 0x72, (byte) 0x6e, (byte) 0x65, (byte) 0x74, (byte) 0x20, (byte) 0x57,
+            (byte) 0x69, (byte) 0x64, (byte) 0x67, (byte) 0x69, (byte) 0x74, (byte) 0x73,
+            (byte) 0x20, (byte) 0x50, (byte) 0x74, (byte) 0x79, (byte) 0x20, (byte) 0x4c,
+            (byte) 0x74, (byte) 0x64, (byte) 0x31, (byte) 0x17, (byte) 0x30, (byte) 0x15,
+            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c,
+            (byte) 0x0e, (byte) 0x63, (byte) 0x61, (byte) 0x2e, (byte) 0x65, (byte) 0x78,
+            (byte) 0x61, (byte) 0x6d, (byte) 0x70, (byte) 0x6c, (byte) 0x65, (byte) 0x2e,
+            (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30, (byte) 0x1e, (byte) 0x17,
+            (byte) 0x0d, (byte) 0x31, (byte) 0x33, (byte) 0x30, (byte) 0x38, (byte) 0x32,
+            (byte) 0x37, (byte) 0x32, (byte) 0x33, (byte) 0x33, (byte) 0x31, (byte) 0x32,
+            (byte) 0x39, (byte) 0x5a, (byte) 0x17, (byte) 0x0d, (byte) 0x32, (byte) 0x33,
+            (byte) 0x30, (byte) 0x38, (byte) 0x32, (byte) 0x35, (byte) 0x32, (byte) 0x33,
+            (byte) 0x33, (byte) 0x31, (byte) 0x32, (byte) 0x39, (byte) 0x5a, (byte) 0x30,
+            (byte) 0x5e, (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06,
+            (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02,
+            (byte) 0x41, (byte) 0x55, (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11,
+            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c,
+            (byte) 0x0a, (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d,
+            (byte) 0x53, (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x31,
+            (byte) 0x21, (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+            (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x18, (byte) 0x49, (byte) 0x6e,
+            (byte) 0x74, (byte) 0x65, (byte) 0x72, (byte) 0x6e, (byte) 0x65, (byte) 0x74,
+            (byte) 0x20, (byte) 0x57, (byte) 0x69, (byte) 0x64, (byte) 0x67, (byte) 0x69,
+            (byte) 0x74, (byte) 0x73, (byte) 0x20, (byte) 0x50, (byte) 0x74, (byte) 0x79,
+            (byte) 0x20, (byte) 0x4c, (byte) 0x74, (byte) 0x64, (byte) 0x31, (byte) 0x17,
+            (byte) 0x30, (byte) 0x15, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
+            (byte) 0x03, (byte) 0x0c, (byte) 0x0e, (byte) 0x63, (byte) 0x61, (byte) 0x2e,
+            (byte) 0x65, (byte) 0x78, (byte) 0x61, (byte) 0x6d, (byte) 0x70, (byte) 0x6c,
+            (byte) 0x65, (byte) 0x2e, (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30,
+            (byte) 0x81, (byte) 0x9f, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09,
+            (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d,
+            (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x03,
+            (byte) 0x81, (byte) 0x8d, (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0x89,
+            (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xa4, (byte) 0xc7,
+            (byte) 0x06, (byte) 0xba, (byte) 0xdf, (byte) 0x2b, (byte) 0xee, (byte) 0xd2,
+            (byte) 0xb9, (byte) 0xe4, (byte) 0x52, (byte) 0x21, (byte) 0x68, (byte) 0x2b,
+            (byte) 0x83, (byte) 0xdf, (byte) 0xe3, (byte) 0x9c, (byte) 0x08, (byte) 0x73,
+            (byte) 0xdd, (byte) 0x90, (byte) 0xea, (byte) 0x97, (byte) 0x0c, (byte) 0x96,
+            (byte) 0x20, (byte) 0xb1, (byte) 0xee, (byte) 0x11, (byte) 0xd5, (byte) 0xd4,
+            (byte) 0x7c, (byte) 0x44, (byte) 0x96, (byte) 0x2e, (byte) 0x6e, (byte) 0xa2,
+            (byte) 0xb2, (byte) 0xa3, (byte) 0x4b, (byte) 0x0f, (byte) 0x32, (byte) 0x90,
+            (byte) 0xaf, (byte) 0x5c, (byte) 0x6f, (byte) 0x00, (byte) 0x88, (byte) 0x45,
+            (byte) 0x4e, (byte) 0x9b, (byte) 0x26, (byte) 0xc1, (byte) 0x94, (byte) 0x3c,
+            (byte) 0xfe, (byte) 0x10, (byte) 0xbd, (byte) 0xda, (byte) 0xf2, (byte) 0x8d,
+            (byte) 0x03, (byte) 0x52, (byte) 0x32, (byte) 0x11, (byte) 0xff, (byte) 0xf6,
+            (byte) 0xf9, (byte) 0x6e, (byte) 0x8f, (byte) 0x0f, (byte) 0xc8, (byte) 0x0a,
+            (byte) 0x48, (byte) 0x39, (byte) 0x33, (byte) 0xb9, (byte) 0x0c, (byte) 0xb3,
+            (byte) 0x2b, (byte) 0xab, (byte) 0x7d, (byte) 0x79, (byte) 0x6f, (byte) 0x57,
+            (byte) 0x5b, (byte) 0xb8, (byte) 0x84, (byte) 0xb6, (byte) 0xcc, (byte) 0xe8,
+            (byte) 0x30, (byte) 0x78, (byte) 0xff, (byte) 0x92, (byte) 0xe5, (byte) 0x43,
+            (byte) 0x2e, (byte) 0xef, (byte) 0x66, (byte) 0x98, (byte) 0xb4, (byte) 0xfe,
+            (byte) 0xa2, (byte) 0x40, (byte) 0xf2, (byte) 0x1f, (byte) 0xd0, (byte) 0x86,
+            (byte) 0x16, (byte) 0xc8, (byte) 0x45, (byte) 0xc4, (byte) 0x52, (byte) 0xcb,
+            (byte) 0x31, (byte) 0x5c, (byte) 0x9f, (byte) 0x32, (byte) 0x3b, (byte) 0xf7,
+            (byte) 0x19, (byte) 0x08, (byte) 0xc7, (byte) 0x00, (byte) 0x21, (byte) 0x7d,
+            (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xa3,
+            (byte) 0x50, (byte) 0x30, (byte) 0x4e, (byte) 0x30, (byte) 0x1d, (byte) 0x06,
+            (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e, (byte) 0x04, (byte) 0x16,
+            (byte) 0x04, (byte) 0x14, (byte) 0x47, (byte) 0x82, (byte) 0xa3, (byte) 0xf1,
+            (byte) 0xc2, (byte) 0x7e, (byte) 0x3a, (byte) 0xde, (byte) 0x4f, (byte) 0x30,
+            (byte) 0x4c, (byte) 0x7f, (byte) 0x72, (byte) 0x81, (byte) 0x15, (byte) 0x32,
+            (byte) 0xda, (byte) 0x7f, (byte) 0x58, (byte) 0x18, (byte) 0x30, (byte) 0x1f,
+            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x23, (byte) 0x04,
+            (byte) 0x18, (byte) 0x30, (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0x47,
+            (byte) 0x82, (byte) 0xa3, (byte) 0xf1, (byte) 0xc2, (byte) 0x7e, (byte) 0x3a,
+            (byte) 0xde, (byte) 0x4f, (byte) 0x30, (byte) 0x4c, (byte) 0x7f, (byte) 0x72,
+            (byte) 0x81, (byte) 0x15, (byte) 0x32, (byte) 0xda, (byte) 0x7f, (byte) 0x58,
+            (byte) 0x18, (byte) 0x30, (byte) 0x0c, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+            (byte) 0x1d, (byte) 0x13, (byte) 0x04, (byte) 0x05, (byte) 0x30, (byte) 0x03,
+            (byte) 0x01, (byte) 0x01, (byte) 0xff, (byte) 0x30, (byte) 0x0d, (byte) 0x06,
+            (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7,
+            (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x05, (byte) 0x00,
+            (byte) 0x03, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0x08, (byte) 0x7f,
+            (byte) 0x6a, (byte) 0x48, (byte) 0x90, (byte) 0x7b, (byte) 0x9b, (byte) 0x72,
+            (byte) 0x13, (byte) 0xa7, (byte) 0xef, (byte) 0x6b, (byte) 0x0b, (byte) 0x59,
+            (byte) 0xe5, (byte) 0x49, (byte) 0x72, (byte) 0x3a, (byte) 0xc8, (byte) 0x84,
+            (byte) 0xcc, (byte) 0x23, (byte) 0x18, (byte) 0x4c, (byte) 0xec, (byte) 0xc7,
+            (byte) 0xef, (byte) 0xcb, (byte) 0xa7, (byte) 0xbe, (byte) 0xe4, (byte) 0xef,
+            (byte) 0x8f, (byte) 0xc6, (byte) 0x06, (byte) 0x8c, (byte) 0xc0, (byte) 0xe4,
+            (byte) 0x2f, (byte) 0x2a, (byte) 0xc0, (byte) 0x35, (byte) 0x7d, (byte) 0x5e,
+            (byte) 0x19, (byte) 0x29, (byte) 0x8c, (byte) 0xb9, (byte) 0xf1, (byte) 0x1e,
+            (byte) 0xaf, (byte) 0x82, (byte) 0xd8, (byte) 0xe3, (byte) 0x88, (byte) 0xe1,
+            (byte) 0x31, (byte) 0xc8, (byte) 0x82, (byte) 0x1f, (byte) 0x83, (byte) 0xa9,
+            (byte) 0xde, (byte) 0xfe, (byte) 0x4b, (byte) 0xe2, (byte) 0x78, (byte) 0x64,
+            (byte) 0xed, (byte) 0xa4, (byte) 0x7b, (byte) 0xee, (byte) 0x8d, (byte) 0x71,
+            (byte) 0x1b, (byte) 0x44, (byte) 0xe6, (byte) 0xb7, (byte) 0xe8, (byte) 0xc5,
+            (byte) 0x9a, (byte) 0x93, (byte) 0x92, (byte) 0x6f, (byte) 0x6f, (byte) 0xdb,
+            (byte) 0xbd, (byte) 0xd7, (byte) 0x03, (byte) 0x85, (byte) 0xa9, (byte) 0x5f,
+            (byte) 0x53, (byte) 0x5f, (byte) 0x5d, (byte) 0x30, (byte) 0xc6, (byte) 0xd9,
+            (byte) 0xce, (byte) 0x34, (byte) 0xa8, (byte) 0xbe, (byte) 0x31, (byte) 0x47,
+            (byte) 0x1c, (byte) 0xa4, (byte) 0x7f, (byte) 0xc0, (byte) 0x2c, (byte) 0xbc,
+            (byte) 0xfe, (byte) 0x1a, (byte) 0x31, (byte) 0xd8, (byte) 0x77, (byte) 0x4d,
+            (byte) 0xfc, (byte) 0x45, (byte) 0x84, (byte) 0xfc, (byte) 0x45, (byte) 0x12,
+            (byte) 0xab, (byte) 0x50, (byte) 0xe4, (byte) 0x45, (byte) 0xe5, (byte) 0x11
+    };
+
+    /**
+     * Generated from above and converted with: openssl pkcs8 -topk8 -outform d
+     * -in userkey.pem -nocrypt | xxd -i | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] FAKE_DSA_KEY_1 = new byte[] {
+            (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x4c, (byte) 0x02, (byte) 0x01,
+            (byte) 0x00, (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x2c, (byte) 0x06,
+            (byte) 0x07, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x38,
+            (byte) 0x04, (byte) 0x01, (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x1f,
+            (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xb3, (byte) 0x23,
+            (byte) 0xf7, (byte) 0x86, (byte) 0xbd, (byte) 0x3b, (byte) 0x86, (byte) 0xcc,
+            (byte) 0xc3, (byte) 0x91, (byte) 0xc0, (byte) 0x30, (byte) 0x32, (byte) 0x02,
+            (byte) 0x47, (byte) 0x35, (byte) 0x01, (byte) 0xef, (byte) 0xee, (byte) 0x98,
+            (byte) 0x13, (byte) 0x56, (byte) 0x49, (byte) 0x47, (byte) 0xb5, (byte) 0x20,
+            (byte) 0xa8, (byte) 0x60, (byte) 0xcb, (byte) 0xc0, (byte) 0xd5, (byte) 0x77,
+            (byte) 0xc1, (byte) 0x69, (byte) 0xcd, (byte) 0x18, (byte) 0x34, (byte) 0x92,
+            (byte) 0xf2, (byte) 0x6a, (byte) 0x2a, (byte) 0x10, (byte) 0x59, (byte) 0x1c,
+            (byte) 0x91, (byte) 0x20, (byte) 0x51, (byte) 0xca, (byte) 0x37, (byte) 0xb2,
+            (byte) 0x87, (byte) 0xa6, (byte) 0x8a, (byte) 0x02, (byte) 0xfd, (byte) 0x45,
+            (byte) 0x46, (byte) 0xf9, (byte) 0x76, (byte) 0xb1, (byte) 0x35, (byte) 0x38,
+            (byte) 0x8d, (byte) 0xff, (byte) 0x4c, (byte) 0x5d, (byte) 0x75, (byte) 0x8f,
+            (byte) 0x66, (byte) 0x15, (byte) 0x7d, (byte) 0x7b, (byte) 0xda, (byte) 0xdb,
+            (byte) 0x57, (byte) 0x39, (byte) 0xff, (byte) 0x91, (byte) 0x3f, (byte) 0xdd,
+            (byte) 0xe2, (byte) 0xb4, (byte) 0x22, (byte) 0x60, (byte) 0x4c, (byte) 0x32,
+            (byte) 0x3b, (byte) 0x9d, (byte) 0x34, (byte) 0x9f, (byte) 0xb9, (byte) 0x5d,
+            (byte) 0x75, (byte) 0xb9, (byte) 0xd3, (byte) 0x7f, (byte) 0x11, (byte) 0xba,
+            (byte) 0xb7, (byte) 0xc8, (byte) 0x32, (byte) 0xc6, (byte) 0xce, (byte) 0x71,
+            (byte) 0x91, (byte) 0xd3, (byte) 0x32, (byte) 0xaf, (byte) 0x4d, (byte) 0x7e,
+            (byte) 0x7c, (byte) 0x15, (byte) 0xf7, (byte) 0x71, (byte) 0x2c, (byte) 0x52,
+            (byte) 0x65, (byte) 0x4d, (byte) 0xa9, (byte) 0x81, (byte) 0x25, (byte) 0x35,
+            (byte) 0xce, (byte) 0x0b, (byte) 0x5b, (byte) 0x56, (byte) 0xfe, (byte) 0xf1,
+            (byte) 0x02, (byte) 0x15, (byte) 0x00, (byte) 0xeb, (byte) 0x4e, (byte) 0x7f,
+            (byte) 0x7a, (byte) 0x31, (byte) 0xb3, (byte) 0x7d, (byte) 0x8d, (byte) 0xb2,
+            (byte) 0xf7, (byte) 0xaf, (byte) 0xad, (byte) 0xb1, (byte) 0x42, (byte) 0x92,
+            (byte) 0xf3, (byte) 0x6c, (byte) 0xe4, (byte) 0xed, (byte) 0x8b, (byte) 0x02,
+            (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0x81, (byte) 0xc8, (byte) 0x36,
+            (byte) 0x48, (byte) 0xdb, (byte) 0x71, (byte) 0x2b, (byte) 0x91, (byte) 0xce,
+            (byte) 0x6d, (byte) 0xbc, (byte) 0xb8, (byte) 0xf9, (byte) 0xcb, (byte) 0x50,
+            (byte) 0x91, (byte) 0x10, (byte) 0x8a, (byte) 0xf8, (byte) 0x37, (byte) 0x50,
+            (byte) 0xda, (byte) 0x4f, (byte) 0xc8, (byte) 0x4d, (byte) 0x73, (byte) 0xcb,
+            (byte) 0x4d, (byte) 0xb0, (byte) 0x19, (byte) 0x54, (byte) 0x5a, (byte) 0xf3,
+            (byte) 0x6c, (byte) 0xc9, (byte) 0xd8, (byte) 0x96, (byte) 0xd9, (byte) 0xb0,
+            (byte) 0x54, (byte) 0x7e, (byte) 0x7d, (byte) 0xe2, (byte) 0x58, (byte) 0x0e,
+            (byte) 0x5f, (byte) 0xc0, (byte) 0xce, (byte) 0xb9, (byte) 0x5c, (byte) 0xe3,
+            (byte) 0xd3, (byte) 0xdf, (byte) 0xcf, (byte) 0x45, (byte) 0x74, (byte) 0xfb,
+            (byte) 0xe6, (byte) 0x20, (byte) 0xe7, (byte) 0xfc, (byte) 0x0f, (byte) 0xca,
+            (byte) 0xdb, (byte) 0xc0, (byte) 0x0b, (byte) 0xe1, (byte) 0x5a, (byte) 0x16,
+            (byte) 0x1d, (byte) 0xb3, (byte) 0x2e, (byte) 0xe5, (byte) 0x5f, (byte) 0x89,
+            (byte) 0x17, (byte) 0x73, (byte) 0x50, (byte) 0xd1, (byte) 0x4a, (byte) 0x60,
+            (byte) 0xb7, (byte) 0xaa, (byte) 0xf0, (byte) 0xc7, (byte) 0xc5, (byte) 0x03,
+            (byte) 0x4e, (byte) 0x36, (byte) 0x51, (byte) 0x9e, (byte) 0x2f, (byte) 0xfa,
+            (byte) 0xf3, (byte) 0xd6, (byte) 0x58, (byte) 0x14, (byte) 0x02, (byte) 0xb4,
+            (byte) 0x41, (byte) 0xd6, (byte) 0x72, (byte) 0x6f, (byte) 0x58, (byte) 0x5b,
+            (byte) 0x2d, (byte) 0x23, (byte) 0xc0, (byte) 0x75, (byte) 0x4f, (byte) 0x39,
+            (byte) 0xa8, (byte) 0x6a, (byte) 0xdf, (byte) 0x79, (byte) 0x21, (byte) 0xf2,
+            (byte) 0x77, (byte) 0x91, (byte) 0x3f, (byte) 0x1c, (byte) 0x4d, (byte) 0x48,
+            (byte) 0x78, (byte) 0xcd, (byte) 0xed, (byte) 0x79, (byte) 0x23, (byte) 0x04,
+            (byte) 0x17, (byte) 0x02, (byte) 0x15, (byte) 0x00, (byte) 0xc7, (byte) 0xe7,
+            (byte) 0xe2, (byte) 0x6b, (byte) 0x14, (byte) 0xe6, (byte) 0x31, (byte) 0x12,
+            (byte) 0xb2, (byte) 0x1e, (byte) 0xd4, (byte) 0xf2, (byte) 0x9b, (byte) 0x2c,
+            (byte) 0xf6, (byte) 0x54, (byte) 0x4c, (byte) 0x12, (byte) 0xe8, (byte) 0x22
+    };
+
+    /**
+     * Generated from above and converted with: openssl x509 -outform d -in
+     * usercert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] FAKE_DSA_USER_1 = new byte[] {
+            (byte) 0x30, (byte) 0x82, (byte) 0x03, (byte) 0xca, (byte) 0x30, (byte) 0x82,
+            (byte) 0x03, (byte) 0x33, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
+            (byte) 0x02, (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x30, (byte) 0x0d,
+            (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86,
+            (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x05,
+            (byte) 0x00, (byte) 0x30, (byte) 0x5e, (byte) 0x31, (byte) 0x0b, (byte) 0x30,
+            (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06,
+            (byte) 0x13, (byte) 0x02, (byte) 0x41, (byte) 0x55, (byte) 0x31, (byte) 0x13,
+            (byte) 0x30, (byte) 0x11, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
+            (byte) 0x08, (byte) 0x0c, (byte) 0x0a, (byte) 0x53, (byte) 0x6f, (byte) 0x6d,
+            (byte) 0x65, (byte) 0x2d, (byte) 0x53, (byte) 0x74, (byte) 0x61, (byte) 0x74,
+            (byte) 0x65, (byte) 0x31, (byte) 0x21, (byte) 0x30, (byte) 0x1f, (byte) 0x06,
+            (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x18,
+            (byte) 0x49, (byte) 0x6e, (byte) 0x74, (byte) 0x65, (byte) 0x72, (byte) 0x6e,
+            (byte) 0x65, (byte) 0x74, (byte) 0x20, (byte) 0x57, (byte) 0x69, (byte) 0x64,
+            (byte) 0x67, (byte) 0x69, (byte) 0x74, (byte) 0x73, (byte) 0x20, (byte) 0x50,
+            (byte) 0x74, (byte) 0x79, (byte) 0x20, (byte) 0x4c, (byte) 0x74, (byte) 0x64,
+            (byte) 0x31, (byte) 0x17, (byte) 0x30, (byte) 0x15, (byte) 0x06, (byte) 0x03,
+            (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x0e, (byte) 0x63,
+            (byte) 0x61, (byte) 0x2e, (byte) 0x65, (byte) 0x78, (byte) 0x61, (byte) 0x6d,
+            (byte) 0x70, (byte) 0x6c, (byte) 0x65, (byte) 0x2e, (byte) 0x63, (byte) 0x6f,
+            (byte) 0x6d, (byte) 0x30, (byte) 0x1e, (byte) 0x17, (byte) 0x0d, (byte) 0x31,
+            (byte) 0x33, (byte) 0x30, (byte) 0x38, (byte) 0x32, (byte) 0x37, (byte) 0x32,
+            (byte) 0x33, (byte) 0x33, (byte) 0x34, (byte) 0x32, (byte) 0x32, (byte) 0x5a,
+            (byte) 0x17, (byte) 0x0d, (byte) 0x32, (byte) 0x33, (byte) 0x30, (byte) 0x38,
+            (byte) 0x32, (byte) 0x35, (byte) 0x32, (byte) 0x33, (byte) 0x33, (byte) 0x34,
+            (byte) 0x32, (byte) 0x32, (byte) 0x5a, (byte) 0x30, (byte) 0x62, (byte) 0x31,
+            (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+            (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41, (byte) 0x55,
+            (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06, (byte) 0x03,
+            (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a, (byte) 0x53,
+            (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53, (byte) 0x74,
+            (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x21, (byte) 0x30,
+            (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a,
+            (byte) 0x0c, (byte) 0x18, (byte) 0x49, (byte) 0x6e, (byte) 0x74, (byte) 0x65,
+            (byte) 0x72, (byte) 0x6e, (byte) 0x65, (byte) 0x74, (byte) 0x20, (byte) 0x57,
+            (byte) 0x69, (byte) 0x64, (byte) 0x67, (byte) 0x69, (byte) 0x74, (byte) 0x73,
+            (byte) 0x20, (byte) 0x50, (byte) 0x74, (byte) 0x79, (byte) 0x20, (byte) 0x4c,
+            (byte) 0x74, (byte) 0x64, (byte) 0x31, (byte) 0x1b, (byte) 0x30, (byte) 0x19,
+            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c,
+            (byte) 0x12, (byte) 0x73, (byte) 0x65, (byte) 0x72, (byte) 0x76, (byte) 0x65,
+            (byte) 0x72, (byte) 0x2e, (byte) 0x65, (byte) 0x78, (byte) 0x61, (byte) 0x6d,
+            (byte) 0x70, (byte) 0x6c, (byte) 0x65, (byte) 0x2e, (byte) 0x63, (byte) 0x6f,
+            (byte) 0x6d, (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0xb7, (byte) 0x30,
+            (byte) 0x82, (byte) 0x01, (byte) 0x2c, (byte) 0x06, (byte) 0x07, (byte) 0x2a,
+            (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x38, (byte) 0x04, (byte) 0x01,
+            (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x1f, (byte) 0x02, (byte) 0x81,
+            (byte) 0x81, (byte) 0x00, (byte) 0xb3, (byte) 0x23, (byte) 0xf7, (byte) 0x86,
+            (byte) 0xbd, (byte) 0x3b, (byte) 0x86, (byte) 0xcc, (byte) 0xc3, (byte) 0x91,
+            (byte) 0xc0, (byte) 0x30, (byte) 0x32, (byte) 0x02, (byte) 0x47, (byte) 0x35,
+            (byte) 0x01, (byte) 0xef, (byte) 0xee, (byte) 0x98, (byte) 0x13, (byte) 0x56,
+            (byte) 0x49, (byte) 0x47, (byte) 0xb5, (byte) 0x20, (byte) 0xa8, (byte) 0x60,
+            (byte) 0xcb, (byte) 0xc0, (byte) 0xd5, (byte) 0x77, (byte) 0xc1, (byte) 0x69,
+            (byte) 0xcd, (byte) 0x18, (byte) 0x34, (byte) 0x92, (byte) 0xf2, (byte) 0x6a,
+            (byte) 0x2a, (byte) 0x10, (byte) 0x59, (byte) 0x1c, (byte) 0x91, (byte) 0x20,
+            (byte) 0x51, (byte) 0xca, (byte) 0x37, (byte) 0xb2, (byte) 0x87, (byte) 0xa6,
+            (byte) 0x8a, (byte) 0x02, (byte) 0xfd, (byte) 0x45, (byte) 0x46, (byte) 0xf9,
+            (byte) 0x76, (byte) 0xb1, (byte) 0x35, (byte) 0x38, (byte) 0x8d, (byte) 0xff,
+            (byte) 0x4c, (byte) 0x5d, (byte) 0x75, (byte) 0x8f, (byte) 0x66, (byte) 0x15,
+            (byte) 0x7d, (byte) 0x7b, (byte) 0xda, (byte) 0xdb, (byte) 0x57, (byte) 0x39,
+            (byte) 0xff, (byte) 0x91, (byte) 0x3f, (byte) 0xdd, (byte) 0xe2, (byte) 0xb4,
+            (byte) 0x22, (byte) 0x60, (byte) 0x4c, (byte) 0x32, (byte) 0x3b, (byte) 0x9d,
+            (byte) 0x34, (byte) 0x9f, (byte) 0xb9, (byte) 0x5d, (byte) 0x75, (byte) 0xb9,
+            (byte) 0xd3, (byte) 0x7f, (byte) 0x11, (byte) 0xba, (byte) 0xb7, (byte) 0xc8,
+            (byte) 0x32, (byte) 0xc6, (byte) 0xce, (byte) 0x71, (byte) 0x91, (byte) 0xd3,
+            (byte) 0x32, (byte) 0xaf, (byte) 0x4d, (byte) 0x7e, (byte) 0x7c, (byte) 0x15,
+            (byte) 0xf7, (byte) 0x71, (byte) 0x2c, (byte) 0x52, (byte) 0x65, (byte) 0x4d,
+            (byte) 0xa9, (byte) 0x81, (byte) 0x25, (byte) 0x35, (byte) 0xce, (byte) 0x0b,
+            (byte) 0x5b, (byte) 0x56, (byte) 0xfe, (byte) 0xf1, (byte) 0x02, (byte) 0x15,
+            (byte) 0x00, (byte) 0xeb, (byte) 0x4e, (byte) 0x7f, (byte) 0x7a, (byte) 0x31,
+            (byte) 0xb3, (byte) 0x7d, (byte) 0x8d, (byte) 0xb2, (byte) 0xf7, (byte) 0xaf,
+            (byte) 0xad, (byte) 0xb1, (byte) 0x42, (byte) 0x92, (byte) 0xf3, (byte) 0x6c,
+            (byte) 0xe4, (byte) 0xed, (byte) 0x8b, (byte) 0x02, (byte) 0x81, (byte) 0x81,
+            (byte) 0x00, (byte) 0x81, (byte) 0xc8, (byte) 0x36, (byte) 0x48, (byte) 0xdb,
+            (byte) 0x71, (byte) 0x2b, (byte) 0x91, (byte) 0xce, (byte) 0x6d, (byte) 0xbc,
+            (byte) 0xb8, (byte) 0xf9, (byte) 0xcb, (byte) 0x50, (byte) 0x91, (byte) 0x10,
+            (byte) 0x8a, (byte) 0xf8, (byte) 0x37, (byte) 0x50, (byte) 0xda, (byte) 0x4f,
+            (byte) 0xc8, (byte) 0x4d, (byte) 0x73, (byte) 0xcb, (byte) 0x4d, (byte) 0xb0,
+            (byte) 0x19, (byte) 0x54, (byte) 0x5a, (byte) 0xf3, (byte) 0x6c, (byte) 0xc9,
+            (byte) 0xd8, (byte) 0x96, (byte) 0xd9, (byte) 0xb0, (byte) 0x54, (byte) 0x7e,
+            (byte) 0x7d, (byte) 0xe2, (byte) 0x58, (byte) 0x0e, (byte) 0x5f, (byte) 0xc0,
+            (byte) 0xce, (byte) 0xb9, (byte) 0x5c, (byte) 0xe3, (byte) 0xd3, (byte) 0xdf,
+            (byte) 0xcf, (byte) 0x45, (byte) 0x74, (byte) 0xfb, (byte) 0xe6, (byte) 0x20,
+            (byte) 0xe7, (byte) 0xfc, (byte) 0x0f, (byte) 0xca, (byte) 0xdb, (byte) 0xc0,
+            (byte) 0x0b, (byte) 0xe1, (byte) 0x5a, (byte) 0x16, (byte) 0x1d, (byte) 0xb3,
+            (byte) 0x2e, (byte) 0xe5, (byte) 0x5f, (byte) 0x89, (byte) 0x17, (byte) 0x73,
+            (byte) 0x50, (byte) 0xd1, (byte) 0x4a, (byte) 0x60, (byte) 0xb7, (byte) 0xaa,
+            (byte) 0xf0, (byte) 0xc7, (byte) 0xc5, (byte) 0x03, (byte) 0x4e, (byte) 0x36,
+            (byte) 0x51, (byte) 0x9e, (byte) 0x2f, (byte) 0xfa, (byte) 0xf3, (byte) 0xd6,
+            (byte) 0x58, (byte) 0x14, (byte) 0x02, (byte) 0xb4, (byte) 0x41, (byte) 0xd6,
+            (byte) 0x72, (byte) 0x6f, (byte) 0x58, (byte) 0x5b, (byte) 0x2d, (byte) 0x23,
+            (byte) 0xc0, (byte) 0x75, (byte) 0x4f, (byte) 0x39, (byte) 0xa8, (byte) 0x6a,
+            (byte) 0xdf, (byte) 0x79, (byte) 0x21, (byte) 0xf2, (byte) 0x77, (byte) 0x91,
+            (byte) 0x3f, (byte) 0x1c, (byte) 0x4d, (byte) 0x48, (byte) 0x78, (byte) 0xcd,
+            (byte) 0xed, (byte) 0x79, (byte) 0x23, (byte) 0x03, (byte) 0x81, (byte) 0x84,
+            (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x1a, (byte) 0x50,
+            (byte) 0x9d, (byte) 0x3e, (byte) 0xa1, (byte) 0x6c, (byte) 0x99, (byte) 0x35,
+            (byte) 0x36, (byte) 0x26, (byte) 0x22, (byte) 0x6b, (byte) 0x47, (byte) 0x45,
+            (byte) 0x80, (byte) 0x5b, (byte) 0xd5, (byte) 0xc1, (byte) 0xc5, (byte) 0x70,
+            (byte) 0x75, (byte) 0x55, (byte) 0x66, (byte) 0x33, (byte) 0x1d, (byte) 0xae,
+            (byte) 0xd0, (byte) 0x01, (byte) 0x64, (byte) 0x8b, (byte) 0xae, (byte) 0x9d,
+            (byte) 0x66, (byte) 0x58, (byte) 0xf9, (byte) 0x42, (byte) 0x74, (byte) 0x3a,
+            (byte) 0x32, (byte) 0xc7, (byte) 0x7f, (byte) 0x25, (byte) 0x64, (byte) 0x7d,
+            (byte) 0x08, (byte) 0x26, (byte) 0xbf, (byte) 0x21, (byte) 0x3a, (byte) 0x84,
+            (byte) 0xcc, (byte) 0x2c, (byte) 0x66, (byte) 0x7d, (byte) 0xc7, (byte) 0xd6,
+            (byte) 0xb1, (byte) 0x69, (byte) 0x57, (byte) 0x67, (byte) 0x52, (byte) 0x73,
+            (byte) 0x3f, (byte) 0x79, (byte) 0x60, (byte) 0xaa, (byte) 0xf4, (byte) 0x8a,
+            (byte) 0x48, (byte) 0x42, (byte) 0x46, (byte) 0x41, (byte) 0xd0, (byte) 0x50,
+            (byte) 0x9b, (byte) 0xa2, (byte) 0x4e, (byte) 0xa5, (byte) 0x88, (byte) 0x10,
+            (byte) 0xf7, (byte) 0x61, (byte) 0xa2, (byte) 0xfa, (byte) 0x8d, (byte) 0xa6,
+            (byte) 0x13, (byte) 0x9e, (byte) 0x36, (byte) 0x86, (byte) 0x62, (byte) 0xf0,
+            (byte) 0x97, (byte) 0xef, (byte) 0x11, (byte) 0xc6, (byte) 0x35, (byte) 0xd3,
+            (byte) 0x79, (byte) 0x30, (byte) 0xde, (byte) 0xf2, (byte) 0x7f, (byte) 0x7a,
+            (byte) 0x3c, (byte) 0x03, (byte) 0xa3, (byte) 0xc5, (byte) 0xbc, (byte) 0xb1,
+            (byte) 0xbc, (byte) 0x2f, (byte) 0x10, (byte) 0xf4, (byte) 0x51, (byte) 0x89,
+            (byte) 0xe2, (byte) 0xaf, (byte) 0xf7, (byte) 0x61, (byte) 0x1a, (byte) 0xf0,
+            (byte) 0x87, (byte) 0x5e, (byte) 0xa5, (byte) 0x02, (byte) 0xd2, (byte) 0xe4,
+            (byte) 0xa3, (byte) 0x7b, (byte) 0x30, (byte) 0x79, (byte) 0x30, (byte) 0x09,
+            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x13, (byte) 0x04,
+            (byte) 0x02, (byte) 0x30, (byte) 0x00, (byte) 0x30, (byte) 0x2c, (byte) 0x06,
+            (byte) 0x09, (byte) 0x60, (byte) 0x86, (byte) 0x48, (byte) 0x01, (byte) 0x86,
+            (byte) 0xf8, (byte) 0x42, (byte) 0x01, (byte) 0x0d, (byte) 0x04, (byte) 0x1f,
+            (byte) 0x16, (byte) 0x1d, (byte) 0x4f, (byte) 0x70, (byte) 0x65, (byte) 0x6e,
+            (byte) 0x53, (byte) 0x53, (byte) 0x4c, (byte) 0x20, (byte) 0x47, (byte) 0x65,
+            (byte) 0x6e, (byte) 0x65, (byte) 0x72, (byte) 0x61, (byte) 0x74, (byte) 0x65,
+            (byte) 0x64, (byte) 0x20, (byte) 0x43, (byte) 0x65, (byte) 0x72, (byte) 0x74,
+            (byte) 0x69, (byte) 0x66, (byte) 0x69, (byte) 0x63, (byte) 0x61, (byte) 0x74,
+            (byte) 0x65, (byte) 0x30, (byte) 0x1d, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+            (byte) 0x1d, (byte) 0x0e, (byte) 0x04, (byte) 0x16, (byte) 0x04, (byte) 0x14,
+            (byte) 0xd1, (byte) 0x6c, (byte) 0x36, (byte) 0x36, (byte) 0x61, (byte) 0x6c,
+            (byte) 0xf6, (byte) 0x90, (byte) 0x82, (byte) 0x82, (byte) 0x87, (byte) 0x93,
+            (byte) 0xbe, (byte) 0x99, (byte) 0x60, (byte) 0x1b, (byte) 0x03, (byte) 0x58,
+            (byte) 0x36, (byte) 0x63, (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03,
+            (byte) 0x55, (byte) 0x1d, (byte) 0x23, (byte) 0x04, (byte) 0x18, (byte) 0x30,
+            (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0x47, (byte) 0x82, (byte) 0xa3,
+            (byte) 0xf1, (byte) 0xc2, (byte) 0x7e, (byte) 0x3a, (byte) 0xde, (byte) 0x4f,
+            (byte) 0x30, (byte) 0x4c, (byte) 0x7f, (byte) 0x72, (byte) 0x81, (byte) 0x15,
+            (byte) 0x32, (byte) 0xda, (byte) 0x7f, (byte) 0x58, (byte) 0x18, (byte) 0x30,
+            (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48,
+            (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x05,
+            (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x81, (byte) 0x81, (byte) 0x00,
+            (byte) 0x81, (byte) 0xde, (byte) 0x20, (byte) 0xa1, (byte) 0xb2, (byte) 0x50,
+            (byte) 0x03, (byte) 0xcd, (byte) 0x90, (byte) 0x4f, (byte) 0x2b, (byte) 0x47,
+            (byte) 0x1d, (byte) 0xac, (byte) 0x6e, (byte) 0xb4, (byte) 0xc7, (byte) 0x14,
+            (byte) 0xc6, (byte) 0x4f, (byte) 0x45, (byte) 0xaf, (byte) 0x81, (byte) 0x5d,
+            (byte) 0x5a, (byte) 0x31, (byte) 0xff, (byte) 0x9c, (byte) 0x4d, (byte) 0xdc,
+            (byte) 0x9e, (byte) 0x36, (byte) 0x9f, (byte) 0x9b, (byte) 0xb1, (byte) 0xc9,
+            (byte) 0x50, (byte) 0xa3, (byte) 0xf6, (byte) 0x9c, (byte) 0x68, (byte) 0x6f,
+            (byte) 0x68, (byte) 0xd9, (byte) 0x56, (byte) 0x1b, (byte) 0xe5, (byte) 0x1b,
+            (byte) 0x41, (byte) 0xd4, (byte) 0xcc, (byte) 0xb6, (byte) 0x37, (byte) 0xd5,
+            (byte) 0x69, (byte) 0x6b, (byte) 0x39, (byte) 0xaf, (byte) 0xc6, (byte) 0xb8,
+            (byte) 0x39, (byte) 0x76, (byte) 0xe3, (byte) 0xf7, (byte) 0x97, (byte) 0x74,
+            (byte) 0x31, (byte) 0xc4, (byte) 0x2d, (byte) 0xb7, (byte) 0x9a, (byte) 0xa4,
+            (byte) 0xfa, (byte) 0x9f, (byte) 0xa8, (byte) 0xe3, (byte) 0x41, (byte) 0xda,
+            (byte) 0x2f, (byte) 0x0c, (byte) 0x9d, (byte) 0x83, (byte) 0xdc, (byte) 0x86,
+            (byte) 0x1f, (byte) 0x5c, (byte) 0x0f, (byte) 0x87, (byte) 0x05, (byte) 0xc9,
+            (byte) 0xb0, (byte) 0x63, (byte) 0xca, (byte) 0x9b, (byte) 0xdb, (byte) 0xe6,
+            (byte) 0x3c, (byte) 0xe9, (byte) 0x23, (byte) 0x9e, (byte) 0x23, (byte) 0x44,
+            (byte) 0x1d, (byte) 0x5b, (byte) 0x60, (byte) 0x66, (byte) 0xb6, (byte) 0x72,
+            (byte) 0x8c, (byte) 0x87, (byte) 0x86, (byte) 0xe8, (byte) 0xdb, (byte) 0x29,
+            (byte) 0x67, (byte) 0x9c, (byte) 0x33, (byte) 0x5c, (byte) 0x39, (byte) 0xf1,
+            (byte) 0xb5, (byte) 0x9b, (byte) 0xb8, (byte) 0xe1, (byte) 0x42, (byte) 0x51,
+            (byte) 0xed, (byte) 0x2c
+    };
+
     /**
      * The amount of time to allow before and after expected time for variance
      * in timing tests.
@@ -505,11 +1133,12 @@
         assertAliases(new String[] {});
 
         assertTrue(mAndroidKeyStore.generate(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
+                KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED,
+                null));
 
         assertAliases(new String[] { TEST_ALIAS_1 });
 
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_CA_1,
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_RSA_CA_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
 
         assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2 });
@@ -533,11 +1162,12 @@
         assertAliases(new String[] {});
 
         assertTrue(mAndroidKeyStore.generate(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
+                KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED,
+                null));
 
         assertTrue("Should contain generated private key", mKeyStore.containsAlias(TEST_ALIAS_1));
 
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_CA_1,
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_RSA_CA_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
 
         assertTrue("Should contain added CA certificate", mKeyStore.containsAlias(TEST_ALIAS_2));
@@ -551,7 +1181,7 @@
 
         mKeyStore.load(null, null);
 
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_CA_1,
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_RSA_CA_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
 
         assertTrue("Should contain added CA certificate", mKeyStore.containsAlias(TEST_ALIAS_2));
@@ -572,18 +1202,18 @@
 
         // TEST_ALIAS_1
         assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                FAKE_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1,
+                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
+        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1,
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
 
         // TEST_ALIAS_2
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_CA_1,
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_RSA_CA_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
 
         // TEST_ALIAS_3
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_3, FAKE_CA_1,
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_3, FAKE_RSA_CA_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
 
         assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2, TEST_ALIAS_3 });
@@ -617,10 +1247,10 @@
 
         // TEST_ALIAS_1
         assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                FAKE_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1,
+                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
+        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1,
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
 
         // Should not throw when a non-existent entry is requested for delete.
@@ -632,7 +1262,7 @@
 
         mKeyStore.load(null, null);
 
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1,
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
 
         assertAliases(new String[] { TEST_ALIAS_1 });
@@ -645,7 +1275,7 @@
         assertNotNull("Retrieved certificate should not be null", retrieved);
 
         CertificateFactory f = CertificateFactory.getInstance("X.509");
-        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
 
         assertEquals("Actual and retrieved certificates should be the same", actual, retrieved);
     }
@@ -664,11 +1294,11 @@
 
         mKeyStore.load(null, null);
 
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1,
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
 
         CertificateFactory f = CertificateFactory.getInstance("X.509");
-        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
 
         assertEquals("Stored certificate alias should be found", TEST_ALIAS_1,
                 mKeyStore.getCertificateAlias(actual));
@@ -681,14 +1311,14 @@
         mKeyStore.load(null, null);
 
         assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                FAKE_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1,
+                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
+        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1,
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
 
         CertificateFactory f = CertificateFactory.getInstance("X.509");
-        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
+        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
 
         assertEquals("Stored certificate alias should be found", TEST_ALIAS_1,
                 mKeyStore.getCertificateAlias(actual));
@@ -701,19 +1331,19 @@
         mKeyStore.load(null, null);
 
         // Insert TrustedCertificateEntry with CA name
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_CA_1,
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_RSA_CA_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
 
         // Insert PrivateKeyEntry that uses the same CA
         assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                FAKE_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1,
+                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
+        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1,
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
 
         CertificateFactory f = CertificateFactory.getInstance("X.509");
-        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
 
         assertEquals("Stored certificate alias should be found", TEST_ALIAS_2,
                 mKeyStore.getCertificateAlias(actual));
@@ -726,7 +1356,7 @@
         mKeyStore.load(null, null);
 
         CertificateFactory f = CertificateFactory.getInstance("X.509");
-        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
 
         assertNull("Stored certificate alias should not be found",
                 mKeyStore.getCertificateAlias(actual));
@@ -737,11 +1367,11 @@
 
         mKeyStore.load(null, null);
 
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1,
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
 
         CertificateFactory f = CertificateFactory.getInstance("X.509");
-        Certificate userCert = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
+        Certificate userCert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
 
         assertNull("Stored certificate alias should be found",
                 mKeyStore.getCertificateAlias(userCert));
@@ -753,16 +1383,16 @@
         mKeyStore.load(null, null);
 
         assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                FAKE_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1,
+                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
+        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1,
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
 
         CertificateFactory cf = CertificateFactory.getInstance("X.509");
         Certificate[] expected = new Certificate[2];
-        expected[0] = cf.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
-        expected[1] = cf.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+        expected[0] = cf.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
+        expected[1] = cf.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
 
         Certificate[] actual = mKeyStore.getCertificateChain(TEST_ALIAS_1);
 
@@ -792,10 +1422,10 @@
         mKeyStore.load(null, null);
 
         assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                FAKE_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1,
+                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
+        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1,
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
 
         Date now = new Date();
@@ -812,10 +1442,10 @@
         mKeyStore.load(null, null);
 
         assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                FAKE_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1,
+                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
+        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_NONE));
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1,
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_NONE));
 
         Date now = new Date();
@@ -833,7 +1463,7 @@
 
         mKeyStore.load(null, null);
 
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1,
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
 
         Date now = new Date();
@@ -853,10 +1483,10 @@
         mKeyStore.load(null, null);
 
         assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                FAKE_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1,
+                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
+        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1,
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
 
         Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
@@ -866,17 +1496,18 @@
 
         PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;
 
-        assertPrivateKeyEntryEquals(keyEntry, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
+        assertPrivateKeyEntryEquals(keyEntry, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
+                FAKE_RSA_CA_1);
     }
 
-    public void testKeyStore_GetEntry_NullParams_Unencrypted_Success() throws Exception {
+    public void testKeyStore_GetEntry_DSA_NullParams_Unencrypted_Success() throws Exception {
         mKeyStore.load(null, null);
 
         assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                FAKE_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1,
-                KeyStore.UID_SELF, KeyStore.FLAG_NONE));
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1,
+                FAKE_DSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
+        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1,
+                FAKE_DSA_USER_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_DSA_CA_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_NONE));
 
         Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
@@ -886,13 +1517,54 @@
 
         PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;
 
-        assertPrivateKeyEntryEquals(keyEntry, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
+        assertPrivateKeyEntryEquals(keyEntry, "DSA", FAKE_DSA_KEY_1, FAKE_DSA_USER_1, FAKE_DSA_CA_1);
+    }
+
+    public void testKeyStore_GetEntry_EC_NullParams_Unencrypted_Success() throws Exception {
+        mKeyStore.load(null, null);
+
+        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
+                FAKE_EC_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
+        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1,
+                FAKE_EC_USER_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_EC_CA_1,
+                KeyStore.UID_SELF, KeyStore.FLAG_NONE));
+
+        Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
+        assertNotNull("Entry should exist", entry);
+
+        assertTrue("Should be a PrivateKeyEntry", entry instanceof PrivateKeyEntry);
+
+        PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;
+
+        assertPrivateKeyEntryEquals(keyEntry, "EC", FAKE_EC_KEY_1, FAKE_EC_USER_1, FAKE_EC_CA_1);
+    }
+
+    public void testKeyStore_GetEntry_RSA_NullParams_Unencrypted_Success() throws Exception {
+        mKeyStore.load(null, null);
+
+        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
+                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
+        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1,
+                FAKE_RSA_USER_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
+                KeyStore.UID_SELF, KeyStore.FLAG_NONE));
+
+        Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
+        assertNotNull("Entry should exist", entry);
+
+        assertTrue("Should be a PrivateKeyEntry", entry instanceof PrivateKeyEntry);
+
+        PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;
+
+        assertPrivateKeyEntryEquals(keyEntry, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
+                FAKE_RSA_CA_1);
     }
 
     @SuppressWarnings("unchecked")
-    private void assertPrivateKeyEntryEquals(PrivateKeyEntry keyEntry, byte[] key, byte[] cert,
-            byte[] ca) throws Exception {
-        KeyFactory keyFact = KeyFactory.getInstance("RSA");
+    private void assertPrivateKeyEntryEquals(PrivateKeyEntry keyEntry, String keyType, byte[] key,
+            byte[] cert, byte[] ca) throws Exception {
+        KeyFactory keyFact = KeyFactory.getInstance(keyType);
         PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(key));
 
         CertificateFactory certFact = CertificateFactory.getInstance("X.509");
@@ -911,9 +1583,19 @@
 
     private void assertPrivateKeyEntryEquals(PrivateKeyEntry keyEntry, PrivateKey expectedKey,
             Certificate expectedCert, Collection<Certificate> expectedChain) throws Exception {
-        assertEquals("Returned PrivateKey should be what we inserted",
-                ((RSAPrivateKey) expectedKey).getModulus(),
-                ((RSAPrivateKey) keyEntry.getPrivateKey()).getModulus());
+        if (expectedKey instanceof DSAPrivateKey) {
+            assertEquals("Returned PrivateKey should be what we inserted",
+                    ((DSAPrivateKey) expectedKey).getParams(),
+                    ((DSAPublicKey) keyEntry.getCertificate().getPublicKey()).getParams());
+        } else if (expectedKey instanceof ECPrivateKey) {
+            assertEquals("Returned PrivateKey should be what we inserted",
+                    ((ECPrivateKey) expectedKey).getParams().getCurve(),
+                    ((ECPublicKey) keyEntry.getCertificate().getPublicKey()).getParams().getCurve());
+        } else if (expectedKey instanceof RSAPrivateKey) {
+            assertEquals("Returned PrivateKey should be what we inserted",
+                    ((RSAPrivateKey) expectedKey).getModulus(),
+                    ((RSAPrivateKey) keyEntry.getPrivateKey()).getModulus());
+        }
 
         assertEquals("Returned Certificate should be what we inserted", expectedCert,
                 keyEntry.getCertificate());
@@ -956,10 +1638,10 @@
         mKeyStore.load(null, null);
 
         assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                FAKE_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1,
+                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
+        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1,
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
 
         Key key = mKeyStore.getKey(TEST_ALIAS_1, null);
@@ -970,7 +1652,7 @@
         RSAPrivateKey actualKey = (RSAPrivateKey) key;
 
         KeyFactory keyFact = KeyFactory.getInstance("RSA");
-        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
+        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
 
         assertEquals("Inserted key should be same as retrieved key",
                 ((RSAPrivateKey) expectedKey).getModulus(), actualKey.getModulus());
@@ -980,10 +1662,10 @@
         mKeyStore.load(null, null);
 
         assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                FAKE_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1,
+                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
+        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_NONE));
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1,
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_NONE));
 
         Key key = mKeyStore.getKey(TEST_ALIAS_1, null);
@@ -994,7 +1676,7 @@
         RSAPrivateKey actualKey = (RSAPrivateKey) key;
 
         KeyFactory keyFact = KeyFactory.getInstance("RSA");
-        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
+        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
 
         assertEquals("Inserted key should be same as retrieved key",
                 ((RSAPrivateKey) expectedKey).getModulus(), actualKey.getModulus());
@@ -1005,7 +1687,7 @@
 
         mKeyStore.load(null, null);
 
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1,
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
 
         assertNull("Certificate entries should return null", mKeyStore.getKey(TEST_ALIAS_1, null));
@@ -1035,7 +1717,7 @@
         setupPassword();
         mKeyStore.load(null, null);
 
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1,
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
 
         assertTrue("Should return true for CA certificate",
@@ -1047,10 +1729,10 @@
         mKeyStore.load(null, null);
 
         assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                FAKE_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1,
+                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
+        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1,
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
 
         assertFalse("Should return false for PrivateKeyEntry",
@@ -1077,10 +1759,10 @@
         mKeyStore.load(null, null);
 
         assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                FAKE_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1,
+                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
+        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1,
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
 
         assertTrue("Should return true for PrivateKeyEntry", mKeyStore.isKeyEntry(TEST_ALIAS_1));
@@ -1090,7 +1772,7 @@
         setupPassword();
         mKeyStore.load(null, null);
 
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1,
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
 
         assertFalse("Should return false for CA certificate", mKeyStore.isKeyEntry(TEST_ALIAS_1));
@@ -1106,7 +1788,7 @@
 
     public void testKeyStore_SetCertificate_CA_Encrypted_Success() throws Exception {
         final CertificateFactory f = CertificateFactory.getInstance("X.509");
-        final Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+        final Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
 
         setupPassword();
         mKeyStore.load(null, null);
@@ -1124,13 +1806,13 @@
         setupPassword();
         mKeyStore.load(null, null);
 
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1,
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
 
         assertAliases(new String[] { TEST_ALIAS_1 });
 
         final CertificateFactory f = CertificateFactory.getInstance("X.509");
-        final Certificate cert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+        final Certificate cert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
 
         // TODO have separate FAKE_CA for second test
         mKeyStore.setCertificateEntry(TEST_ALIAS_1, cert);
@@ -1143,16 +1825,16 @@
         mKeyStore.load(null, null);
 
         assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
-                FAKE_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1,
+                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
+        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1,
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
 
         assertAliases(new String[] { TEST_ALIAS_1 });
 
         final CertificateFactory f = CertificateFactory.getInstance("X.509");
-        final Certificate cert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+        final Certificate cert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
 
         try {
             mKeyStore.setCertificateEntry(TEST_ALIAS_1, cert);
@@ -1166,13 +1848,13 @@
         mKeyStore.load(null, null);
 
         KeyFactory keyFact = KeyFactory.getInstance("RSA");
-        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
+        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
 
         final CertificateFactory f = CertificateFactory.getInstance("X.509");
 
         final Certificate[] expectedChain = new Certificate[2];
-        expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
-        expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+        expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
+        expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
 
         PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);
 
@@ -1186,20 +1868,74 @@
 
         PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
 
-        assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
+        assertPrivateKeyEntryEquals(actual, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1, FAKE_RSA_CA_1);
     }
 
-    public void testKeyStore_SetEntry_PrivateKeyEntry_Unencrypted_Success() throws Exception {
+    public void testKeyStore_SetEntry_PrivateKeyEntry_DSA_Unencrypted_Success() throws Exception {
+        mKeyStore.load(null, null);
+
+        KeyFactory keyFact = KeyFactory.getInstance("DSA");
+        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_DSA_KEY_1));
+
+        final CertificateFactory f = CertificateFactory.getInstance("X.509");
+
+        final Certificate[] expectedChain = new Certificate[2];
+        expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_DSA_USER_1));
+        expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_DSA_CA_1));
+
+        PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);
+
+        mKeyStore.setEntry(TEST_ALIAS_1, expected, null);
+
+        Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
+        assertNotNull("Retrieved entry should exist", actualEntry);
+
+        assertTrue("Retrieved entry should be of type PrivateKeyEntry",
+                actualEntry instanceof PrivateKeyEntry);
+
+        PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
+
+        assertPrivateKeyEntryEquals(actual, "DSA", FAKE_DSA_KEY_1, FAKE_DSA_USER_1, FAKE_DSA_CA_1);
+    }
+
+    public void testKeyStore_SetEntry_PrivateKeyEntry_EC_Unencrypted_Success() throws Exception {
+        mKeyStore.load(null, null);
+
+        KeyFactory keyFact = KeyFactory.getInstance("EC");
+        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_EC_KEY_1));
+
+        final CertificateFactory f = CertificateFactory.getInstance("X.509");
+
+        final Certificate[] expectedChain = new Certificate[2];
+        expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_EC_USER_1));
+        expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_EC_CA_1));
+
+        PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);
+
+        mKeyStore.setEntry(TEST_ALIAS_1, expected, null);
+
+        Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
+        assertNotNull("Retrieved entry should exist", actualEntry);
+
+        assertTrue("Retrieved entry should be of type PrivateKeyEntry",
+                actualEntry instanceof PrivateKeyEntry);
+
+        PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
+
+        assertPrivateKeyEntryEquals(actual, "EC", FAKE_EC_KEY_1, FAKE_EC_USER_1, FAKE_EC_CA_1);
+    }
+
+    public void testKeyStore_SetEntry_PrivateKeyEntry_RSA_Unencrypted_Success() throws Exception {
         mKeyStore.load(null, null);
 
         KeyFactory keyFact = KeyFactory.getInstance("RSA");
-        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
+        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
 
         final CertificateFactory f = CertificateFactory.getInstance("X.509");
 
         final Certificate[] expectedChain = new Certificate[2];
-        expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
-        expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+        expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
+        expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
 
         PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);
 
@@ -1213,20 +1949,20 @@
 
         PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
 
-        assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
+        assertPrivateKeyEntryEquals(actual, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1, FAKE_RSA_CA_1);
     }
 
     public void testKeyStore_SetEntry_PrivateKeyEntry_Params_Unencrypted_Failure() throws Exception {
         mKeyStore.load(null, null);
 
         KeyFactory keyFact = KeyFactory.getInstance("RSA");
-        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
+        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
 
         final CertificateFactory f = CertificateFactory.getInstance("X.509");
 
         final Certificate[] expectedChain = new Certificate[2];
-        expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
-        expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+        expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
+        expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
 
         PrivateKeyEntry entry = new PrivateKeyEntry(expectedKey, expectedChain);
 
@@ -1253,11 +1989,11 @@
 
         // Start with PrivateKeyEntry
         {
-            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
+            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
 
             final Certificate[] expectedChain = new Certificate[2];
-            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
-            expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
+            expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
 
             PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);
 
@@ -1271,17 +2007,18 @@
 
             PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
 
-            assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
+            assertPrivateKeyEntryEquals(actual, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
+                    FAKE_RSA_CA_1);
         }
 
         // TODO make entirely new test vector for the overwrite
         // Replace with PrivateKeyEntry
         {
-            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
+            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
 
             final Certificate[] expectedChain = new Certificate[2];
-            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
-            expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
+            expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
 
             PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);
 
@@ -1295,7 +2032,8 @@
 
             PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
 
-            assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
+            assertPrivateKeyEntryEquals(actual, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
+                    FAKE_RSA_CA_1);
         }
     }
 
@@ -1308,7 +2046,7 @@
 
         // Start with TrustedCertificateEntry
         {
-            final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+            final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
 
             TrustedCertificateEntry expectedCertEntry = new TrustedCertificateEntry(caCert);
             mKeyStore.setEntry(TEST_ALIAS_1, expectedCertEntry, null);
@@ -1326,10 +2064,10 @@
         // Replace with PrivateKeyEntry
         {
             KeyFactory keyFact = KeyFactory.getInstance("RSA");
-            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
+            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
             final Certificate[] expectedChain = new Certificate[2];
-            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
-            expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
+            expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
 
             PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);
 
@@ -1341,7 +2079,8 @@
                     actualEntry instanceof PrivateKeyEntry);
 
             PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
-            assertPrivateKeyEntryEquals(actualPrivEntry, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
+            assertPrivateKeyEntryEquals(actualPrivEntry, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
+                    FAKE_RSA_CA_1);
         }
     }
 
@@ -1352,14 +2091,14 @@
 
         final CertificateFactory f = CertificateFactory.getInstance("X.509");
 
-        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
 
         // Start with PrivateKeyEntry
         {
             KeyFactory keyFact = KeyFactory.getInstance("RSA");
-            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
+            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
             final Certificate[] expectedChain = new Certificate[2];
-            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
+            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
             expectedChain[1] = caCert;
 
             PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);
@@ -1372,7 +2111,8 @@
                     actualEntry instanceof PrivateKeyEntry);
 
             PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
-            assertPrivateKeyEntryEquals(actualPrivEntry, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
+            assertPrivateKeyEntryEquals(actualPrivEntry, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
+                    FAKE_RSA_CA_1);
         }
 
         // Replace with TrustedCertificateEntry
@@ -1400,14 +2140,14 @@
 
         final CertificateFactory f = CertificateFactory.getInstance("X.509");
 
-        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
 
         // Start with PrivateKeyEntry
         {
             KeyFactory keyFact = KeyFactory.getInstance("RSA");
-            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
+            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
             final Certificate[] expectedChain = new Certificate[2];
-            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
+            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
             expectedChain[1] = caCert;
 
             PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);
@@ -1420,15 +2160,16 @@
                     actualEntry instanceof PrivateKeyEntry);
 
             PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
-            assertPrivateKeyEntryEquals(actualPrivEntry, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
+            assertPrivateKeyEntryEquals(actualPrivEntry, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
+                    FAKE_RSA_CA_1);
         }
 
         // Replace with PrivateKeyEntry that has no chain
         {
             KeyFactory keyFact = KeyFactory.getInstance("RSA");
-            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
+            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
             final Certificate[] expectedChain = new Certificate[1];
-            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
+            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
 
             PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);
 
@@ -1440,7 +2181,8 @@
                     actualEntry instanceof PrivateKeyEntry);
 
             PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
-            assertPrivateKeyEntryEquals(actualPrivEntry, FAKE_KEY_1, FAKE_USER_1, null);
+            assertPrivateKeyEntryEquals(actualPrivEntry, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
+                    null);
         }
     }
 
@@ -1453,7 +2195,7 @@
 
         // Insert TrustedCertificateEntry
         {
-            final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+            final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
 
             TrustedCertificateEntry expectedCertEntry = new TrustedCertificateEntry(caCert);
             mKeyStore.setEntry(TEST_ALIAS_1, expectedCertEntry, null);
@@ -1471,7 +2213,7 @@
         // Replace with TrustedCertificateEntry of USER
         {
             final Certificate userCert = f
-                    .generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
+                    .generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
 
             TrustedCertificateEntry expectedUserEntry = new TrustedCertificateEntry(userCert);
             mKeyStore.setEntry(TEST_ALIAS_1, expectedUserEntry, null);
@@ -1493,12 +2235,12 @@
 
         final CertificateFactory f = CertificateFactory.getInstance("X.509");
 
-        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
 
         KeyFactory keyFact = KeyFactory.getInstance("RSA");
-        PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
+        PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
         final Certificate[] chain = new Certificate[2];
-        chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
+        chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
         chain[1] = caCert;
 
         try {
@@ -1514,12 +2256,12 @@
 
         final CertificateFactory f = CertificateFactory.getInstance("X.509");
 
-        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
 
         KeyFactory keyFact = KeyFactory.getInstance("RSA");
-        PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
+        PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
         final Certificate[] chain = new Certificate[2];
-        chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
+        chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
         chain[1] = caCert;
 
         mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, null, chain);
@@ -1532,7 +2274,7 @@
 
         PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
 
-        assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
+        assertPrivateKeyEntryEquals(actual, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1, FAKE_RSA_CA_1);
     }
 
     public void testKeyStore_SetKeyEntry_Replaced_Encrypted_Success() throws Exception {
@@ -1541,14 +2283,14 @@
 
         final CertificateFactory f = CertificateFactory.getInstance("X.509");
 
-        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));
 
         // Insert initial key
         {
             KeyFactory keyFact = KeyFactory.getInstance("RSA");
-            PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
+            PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
             final Certificate[] chain = new Certificate[2];
-            chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
+            chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
             chain[1] = caCert;
 
             mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, null, chain);
@@ -1561,16 +2303,17 @@
 
             PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
 
-            assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
+            assertPrivateKeyEntryEquals(actual, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
+                    FAKE_RSA_CA_1);
         }
 
         // TODO make a separate key
         // Replace key
         {
             KeyFactory keyFact = KeyFactory.getInstance("RSA");
-            PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
+            PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
             final Certificate[] chain = new Certificate[2];
-            chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
+            chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
             chain[1] = caCert;
 
             mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, null, chain);
@@ -1583,7 +2326,8 @@
 
             PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
 
-            assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
+            assertPrivateKeyEntryEquals(actual, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
+                    FAKE_RSA_CA_1);
         }
     }
 
@@ -1635,7 +2379,7 @@
         {
             final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
             assertTrue(mAndroidKeyStore.generate(privateKeyAlias, KeyStore.UID_SELF,
-                    KeyStore.FLAG_ENCRYPTED));
+                    NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED, null));
 
             Key key = mKeyStore.getKey(TEST_ALIAS_1, null);
 
@@ -1691,7 +2435,7 @@
         {
             final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
             assertTrue(mAndroidKeyStore.generate(privateKeyAlias, KeyStore.UID_SELF,
-                    KeyStore.FLAG_ENCRYPTED));
+                    NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED, null));
 
             X509Certificate cert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_1,
                     TEST_SERIAL_1, TEST_DN_1, NOW, NOW_PLUS_10_YEARS);
@@ -1704,7 +2448,7 @@
         {
             final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_2;
             assertTrue(mAndroidKeyStore.generate(privateKeyAlias, KeyStore.UID_SELF,
-                    KeyStore.FLAG_ENCRYPTED));
+                    NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED, null));
 
             X509Certificate cert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_2,
                     TEST_SERIAL_2, TEST_DN_2, NOW, NOW_PLUS_10_YEARS);
@@ -1736,7 +2480,8 @@
         {
             final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
             assertTrue(mAndroidKeyStore.generate(privateKeyAlias,
-                    android.security.KeyStore.UID_SELF, android.security.KeyStore.FLAG_NONE));
+                    android.security.KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA, 1024,
+                    android.security.KeyStore.FLAG_NONE, null));
 
             X509Certificate cert =
                     generateCertificate(mAndroidKeyStore, TEST_ALIAS_1, TEST_SERIAL_1, TEST_DN_1,
@@ -1774,20 +2519,21 @@
         setupPassword();
         mKeyStore.load(null, null);
 
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1,
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
 
         assertEquals("The keystore size should match expected", 1, mKeyStore.size());
         assertAliases(new String[] { TEST_ALIAS_1 });
 
-        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_CA_1,
+        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_RSA_CA_1,
                 KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
 
         assertEquals("The keystore size should match expected", 2, mKeyStore.size());
         assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2 });
 
         assertTrue(mAndroidKeyStore.generate(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_3,
-                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
+                KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED,
+                null));
 
         assertEquals("The keystore size should match expected", 3, mKeyStore.size());
         assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2, TEST_ALIAS_3 });
@@ -1854,7 +2600,8 @@
     private void setupKey() throws Exception {
         final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
         assertTrue(mAndroidKeyStore
-                .generate(privateKeyAlias, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
+                .generate(privateKeyAlias, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA, 1024,
+                        KeyStore.FLAG_ENCRYPTED, null));
 
         X509Certificate cert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_1, TEST_SERIAL_1,
                 TEST_DN_1, NOW, NOW_PLUS_10_YEARS);
diff --git a/keystore/tests/src/android/security/KeyPairGeneratorSpecTest.java b/keystore/tests/src/android/security/KeyPairGeneratorSpecTest.java
index 113d730..bc8dd13 100644
--- a/keystore/tests/src/android/security/KeyPairGeneratorSpecTest.java
+++ b/keystore/tests/src/android/security/KeyPairGeneratorSpecTest.java
@@ -40,13 +40,17 @@
 
     public void testConstructor_Success() throws Exception {
         KeyPairGeneratorSpec spec =
-                new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, TEST_DN_1, SERIAL_1,
-                        NOW, NOW_PLUS_10_YEARS, 0);
+                new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1,
+                        SERIAL_1, NOW, NOW_PLUS_10_YEARS, 0);
 
         assertEquals("Context should be the one specified", getContext(), spec.getContext());
 
         assertEquals("Alias should be the one specified", TEST_ALIAS_1, spec.getKeystoreAlias());
 
+        assertEquals("Key algorithm should be the one specified", "RSA", spec.getKeyType());
+
+        assertEquals("Key size should be the one specified", 1024, spec.getKeySize());
+
         assertEquals("subjectDN should be the one specified", TEST_DN_1, spec.getSubjectDN());
 
         assertEquals("startDate should be the one specified", NOW, spec.getStartDate());
@@ -57,6 +61,8 @@
     public void testBuilder_Success() throws Exception {
         KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(getContext())
                 .setAlias(TEST_ALIAS_1)
+                .setKeyType("RSA")
+                .setKeySize(1024)
                 .setSubject(TEST_DN_1)
                 .setSerialNumber(SERIAL_1)
                 .setStartDate(NOW)
@@ -68,6 +74,10 @@
 
         assertEquals("Alias should be the one specified", TEST_ALIAS_1, spec.getKeystoreAlias());
 
+        assertEquals("Key algorithm should be the one specified", "RSA", spec.getKeyType());
+
+        assertEquals("Key size should be the one specified", 1024, spec.getKeySize());
+
         assertEquals("subjectDN should be the one specified", TEST_DN_1, spec.getSubjectDN());
 
         assertEquals("startDate should be the one specified", NOW, spec.getStartDate());
@@ -79,7 +89,7 @@
 
     public void testConstructor_NullContext_Failure() throws Exception {
         try {
-            new KeyPairGeneratorSpec(null, TEST_ALIAS_1, TEST_DN_1, SERIAL_1, NOW,
+            new KeyPairGeneratorSpec(null, TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, SERIAL_1, NOW,
                     NOW_PLUS_10_YEARS, 0);
             fail("Should throw IllegalArgumentException when context is null");
         } catch (IllegalArgumentException success) {
@@ -88,7 +98,7 @@
 
     public void testConstructor_NullKeystoreAlias_Failure() throws Exception {
         try {
-            new KeyPairGeneratorSpec(getContext(), null, TEST_DN_1, SERIAL_1, NOW,
+            new KeyPairGeneratorSpec(getContext(), null, "RSA", 1024, null, TEST_DN_1, SERIAL_1, NOW,
                     NOW_PLUS_10_YEARS, 0);
             fail("Should throw IllegalArgumentException when keystoreAlias is null");
         } catch (IllegalArgumentException success) {
@@ -97,7 +107,7 @@
 
     public void testConstructor_NullSubjectDN_Failure() throws Exception {
         try {
-            new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, null, SERIAL_1, NOW,
+            new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, null, SERIAL_1, NOW,
                     NOW_PLUS_10_YEARS, 0);
             fail("Should throw IllegalArgumentException when subjectDN is null");
         } catch (IllegalArgumentException success) {
@@ -106,7 +116,7 @@
 
     public void testConstructor_NullSerial_Failure() throws Exception {
         try {
-            new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, TEST_DN_1, null, NOW,
+            new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, null, NOW,
                     NOW_PLUS_10_YEARS, 0);
             fail("Should throw IllegalArgumentException when startDate is null");
         } catch (IllegalArgumentException success) {
@@ -115,8 +125,8 @@
 
     public void testConstructor_NullStartDate_Failure() throws Exception {
         try {
-            new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, TEST_DN_1, SERIAL_1, null,
-                    NOW_PLUS_10_YEARS, 0);
+            new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, SERIAL_1,
+                    null, NOW_PLUS_10_YEARS, 0);
             fail("Should throw IllegalArgumentException when startDate is null");
         } catch (IllegalArgumentException success) {
         }
@@ -124,8 +134,8 @@
 
     public void testConstructor_NullEndDate_Failure() throws Exception {
         try {
-            new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, TEST_DN_1, SERIAL_1, NOW,
-                    null, 0);
+            new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, SERIAL_1,
+                    NOW, null, 0);
             fail("Should throw IllegalArgumentException when keystoreAlias is null");
         } catch (IllegalArgumentException success) {
         }
@@ -133,7 +143,7 @@
 
     public void testConstructor_EndBeforeStart_Failure() throws Exception {
         try {
-            new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, TEST_DN_1, SERIAL_1,
+            new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, SERIAL_1,
                     NOW_PLUS_10_YEARS, NOW, 0);
             fail("Should throw IllegalArgumentException when end is before start");
         } catch (IllegalArgumentException success) {
diff --git a/keystore/tests/src/android/security/KeyStoreTest.java b/keystore/tests/src/android/security/KeyStoreTest.java
index 9bf88d3..7a142cc 100644
--- a/keystore/tests/src/android/security/KeyStoreTest.java
+++ b/keystore/tests/src/android/security/KeyStoreTest.java
@@ -22,6 +22,7 @@
 import android.test.ActivityUnitTestCase;
 import android.test.AssertionFailedError;
 import android.test.suitebuilder.annotation.MediumTest;
+import com.android.org.conscrypt.NativeCrypto;
 import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
 import java.util.Date;
@@ -347,21 +348,24 @@
 
     public void testGenerate_NotInitialized_Fail() throws Exception {
         assertFalse("Should fail when keystore is not initialized",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
+                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+                        1024, KeyStore.FLAG_ENCRYPTED, null));
     }
 
     public void testGenerate_Locked_Fail() throws Exception {
         mKeyStore.password(TEST_PASSWD);
         mKeyStore.lock();
         assertFalse("Should fail when keystore is locked",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
+                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+                        1024, KeyStore.FLAG_ENCRYPTED, null));
     }
 
     public void testGenerate_Success() throws Exception {
         assertTrue(mKeyStore.password(TEST_PASSWD));
 
         assertTrue("Should be able to generate key when unlocked",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
+                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+                        1024, KeyStore.FLAG_ENCRYPTED, null));
         assertTrue(mKeyStore.contains(TEST_KEYNAME));
         assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
     }
@@ -370,7 +374,8 @@
         assertTrue(mKeyStore.password(TEST_PASSWD));
 
         assertTrue("Should be able to generate key when unlocked",
-                mKeyStore.generate(TEST_KEYNAME, Process.WIFI_UID, KeyStore.FLAG_ENCRYPTED));
+                mKeyStore.generate(TEST_KEYNAME, Process.WIFI_UID, NativeCrypto.EVP_PKEY_RSA,
+                        1024, KeyStore.FLAG_ENCRYPTED, null));
         assertTrue(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
         assertFalse(mKeyStore.contains(TEST_KEYNAME));
     }
@@ -378,7 +383,8 @@
     public void testGenerate_ungrantedUid_Bluetooth_Failure() throws Exception {
         assertTrue(mKeyStore.password(TEST_PASSWD));
 
-        assertFalse(mKeyStore.generate(TEST_KEYNAME, Process.BLUETOOTH_UID, KeyStore.FLAG_ENCRYPTED));
+        assertFalse(mKeyStore.generate(TEST_KEYNAME, Process.BLUETOOTH_UID,
+                    NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED, null));
         assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
         assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
         assertFalse(mKeyStore.contains(TEST_KEYNAME));
@@ -424,7 +430,8 @@
     public void testSign_Success() throws Exception {
         mKeyStore.password(TEST_PASSWD);
 
-        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
+        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+                    1024, KeyStore.FLAG_ENCRYPTED, null));
         assertTrue(mKeyStore.contains(TEST_KEYNAME));
         final byte[] signature = mKeyStore.sign(TEST_KEYNAME, TEST_DATA);
 
@@ -434,7 +441,8 @@
     public void testVerify_Success() throws Exception {
         mKeyStore.password(TEST_PASSWD);
 
-        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
+        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+                    1024, KeyStore.FLAG_ENCRYPTED, null));
         assertTrue(mKeyStore.contains(TEST_KEYNAME));
         final byte[] signature = mKeyStore.sign(TEST_KEYNAME, TEST_DATA);
 
@@ -461,7 +469,8 @@
                 mKeyStore.password(TEST_PASSWD));
 
         assertTrue("Should be able to generate key for testcase",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
+                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+                        1024, KeyStore.FLAG_ENCRYPTED, null));
 
         assertTrue("Should be able to grant key to other user",
                 mKeyStore.grant(TEST_KEYNAME, 0));
@@ -494,7 +503,8 @@
                 mKeyStore.password(TEST_PASSWD));
 
         assertTrue("Should be able to generate key for testcase",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
+                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+                        1024, KeyStore.FLAG_ENCRYPTED, null));
 
         assertTrue("Should be able to grant key to other user",
                 mKeyStore.grant(TEST_KEYNAME, 0));
@@ -527,7 +537,8 @@
                 mKeyStore.password(TEST_PASSWD));
 
         assertTrue("Should be able to generate key for testcase",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
+                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+                        1024, KeyStore.FLAG_ENCRYPTED, null));
 
         assertFalse("Should not be able to revoke not existent grant",
                 mKeyStore.ungrant(TEST_KEYNAME, 0));
@@ -538,7 +549,8 @@
                 mKeyStore.password(TEST_PASSWD));
 
         assertTrue("Should be able to generate key for testcase",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
+                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+                        1024, KeyStore.FLAG_ENCRYPTED, null));
 
         assertTrue("Should be able to grant key to other user",
                 mKeyStore.grant(TEST_KEYNAME, 0));
@@ -555,7 +567,8 @@
                 mKeyStore.password(TEST_PASSWD));
 
         assertTrue("Should be able to generate key for testcase",
-                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
+                mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+                        1024, KeyStore.FLAG_ENCRYPTED, null));
 
         assertTrue("Should be able to grant key to other user",
                 mKeyStore.grant(TEST_KEYNAME, 0));
@@ -575,7 +588,8 @@
 
         assertFalse(mKeyStore.contains(TEST_KEYNAME));
 
-        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
+        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+                    1024, KeyStore.FLAG_ENCRYPTED, null));
 
         assertTrue(mKeyStore.contains(TEST_KEYNAME));
         assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.WIFI_UID));
@@ -613,7 +627,8 @@
 
         assertFalse(mKeyStore.contains(TEST_KEYNAME));
 
-        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
+        assertTrue(mKeyStore.generate(TEST_KEYNAME, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA,
+                    1024, KeyStore.FLAG_ENCRYPTED, null));
 
         assertTrue(mKeyStore.contains(TEST_KEYNAME));
         assertFalse(mKeyStore.contains(TEST_KEYNAME, Process.BLUETOOTH_UID));
diff --git a/libs/androidfw/Android.mk b/libs/androidfw/Android.mk
index 3ed75a2..d80612b 100644
--- a/libs/androidfw/Android.mk
+++ b/libs/androidfw/Android.mk
@@ -14,47 +14,47 @@
 
 LOCAL_PATH:= $(call my-dir)
 
-# libandroidfw is partially built for the host (used by build time keymap validation tool)
+# libandroidfw is partially built for the host (used by obbtool and others)
 # These files are common to host and target builds.
 
-# formerly in libutils
-commonUtilsSources:= \
+commonSources := \
     Asset.cpp \
     AssetDir.cpp \
     AssetManager.cpp \
+    misc.cpp \
     ObbFile.cpp \
     ResourceTypes.cpp \
-    StreamingZipInflater.cpp
+    StreamingZipInflater.cpp \
+    ZipFileRO.cpp \
+    ZipUtils.cpp
 
-# formerly in libui
-commonUiSources:= \
-    Input.cpp \
-    InputDevice.cpp \
-    Keyboard.cpp \
-    KeyCharacterMap.cpp \
-    KeyLayoutMap.cpp \
-    VelocityControl.cpp \
-    VelocityTracker.cpp \
-    VirtualKeyMap.cpp
+deviceSources := \
+    $(commonSources) \
+    BackupData.cpp \
+    BackupHelpers.cpp \
+    CursorWindow.cpp
 
-commonSources:= \
-	$(commonUtilsSources) \
-	$(commonUiSources)
+hostSources := \
+    $(commonSources)
 
 # For the host
 # =====================================================
 
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES:= $(commonSources)
+LOCAL_SRC_FILES:= $(hostSources)
 
 LOCAL_MODULE:= libandroidfw
 
 LOCAL_MODULE_TAGS := optional
 
+LOCAL_CFLAGS += -DSTATIC_ANDROIDFW_FOR_TOOLS
+
 LOCAL_C_INCLUDES := \
 	external/zlib
 
+LOCAL_STATIC_LIBRARIES := liblog
+
 include $(BUILD_HOST_STATIC_LIBRARY)
 
 
@@ -63,23 +63,16 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES:= \
-	$(commonSources) \
-	BackupData.cpp \
-	BackupHelpers.cpp \
-    CursorWindow.cpp \
-	InputTransport.cpp
+LOCAL_SRC_FILES:= $(deviceSources)
 
 LOCAL_SHARED_LIBRARIES := \
+	libbinder \
 	liblog \
 	libcutils \
 	libutils \
-	libbinder \
-	libskia \
 	libz
 
 LOCAL_C_INCLUDES := \
-    external/skia/include/core \
     external/icu4c/common \
 	external/zlib
 
@@ -90,20 +83,6 @@
 include $(BUILD_SHARED_LIBRARY)
 
 
-ifeq ($(TARGET_OS),linux)
-include $(CLEAR_VARS)
-LOCAL_C_INCLUDES += \
-	external/skia/include/core \
-	external/zlib \
-	external/icu4c/common \
-	bionic/libc/private
-LOCAL_LDLIBS := -lrt -ldl -lpthread
-LOCAL_MODULE := libandroidfw
-LOCAL_SRC_FILES := $(commonUtilsSources) BackupData.cpp BackupHelpers.cpp
-include $(BUILD_STATIC_LIBRARY)
-endif
-
-
 # Include subdirectory makefiles
 # ============================================================
 
diff --git a/libs/androidfw/Asset.cpp b/libs/androidfw/Asset.cpp
index fd5b3e4..cb7628d 100644
--- a/libs/androidfw/Asset.cpp
+++ b/libs/androidfw/Asset.cpp
@@ -23,11 +23,11 @@
 
 #include <androidfw/Asset.h>
 #include <androidfw/StreamingZipInflater.h>
+#include <androidfw/ZipFileRO.h>
+#include <androidfw/ZipUtils.h>
 #include <utils/Atomic.h>
 #include <utils/FileMap.h>
 #include <utils/Log.h>
-#include <utils/ZipFileRO.h>
-#include <utils/ZipUtils.h>
 #include <utils/threads.h>
 
 #include <assert.h>
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
index b08c36b..6667daf 100644
--- a/libs/androidfw/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -25,14 +25,15 @@
 #include <androidfw/Asset.h>
 #include <androidfw/AssetDir.h>
 #include <androidfw/AssetManager.h>
+#include <androidfw/misc.h>
 #include <androidfw/ResourceTypes.h>
+#include <androidfw/ZipFileRO.h>
 #include <utils/Atomic.h>
 #include <utils/Log.h>
 #include <utils/String8.h>
 #include <utils/String8.h>
 #include <utils/threads.h>
 #include <utils/Timers.h>
-#include <utils/ZipFileRO.h>
 #ifdef HAVE_ANDROID_OS
 #include <cutils/trace.h>
 #endif
diff --git a/libs/androidfw/CursorWindow.cpp b/libs/androidfw/CursorWindow.cpp
index 047a4c8..0f54edb 100644
--- a/libs/androidfw/CursorWindow.cpp
+++ b/libs/androidfw/CursorWindow.cpp
@@ -17,8 +17,9 @@
 #undef LOG_TAG
 #define LOG_TAG "CursorWindow"
 
-#include <utils/Log.h>
 #include <androidfw/CursorWindow.h>
+#include <binder/Parcel.h>
+#include <utils/Log.h>
 
 #include <cutils/ashmem.h>
 #include <sys/mman.h>
diff --git a/libs/androidfw/Input.cpp b/libs/androidfw/Input.cpp
deleted file mode 100644
index eca692a..0000000
--- a/libs/androidfw/Input.cpp
+++ /dev/null
@@ -1,634 +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.
- */
-
-#define LOG_TAG "Input"
-//#define LOG_NDEBUG 0
-
-#include <math.h>
-#include <limits.h>
-
-#include <androidfw/Input.h>
-
-#ifdef HAVE_ANDROID_OS
-#include <binder/Parcel.h>
-
-#include "SkPoint.h"
-#include "SkMatrix.h"
-#include "SkScalar.h"
-#endif
-
-namespace android {
-
-// --- InputEvent ---
-
-void InputEvent::initialize(int32_t deviceId, int32_t source) {
-    mDeviceId = deviceId;
-    mSource = source;
-}
-
-void InputEvent::initialize(const InputEvent& from) {
-    mDeviceId = from.mDeviceId;
-    mSource = from.mSource;
-}
-
-// --- KeyEvent ---
-
-bool KeyEvent::hasDefaultAction(int32_t keyCode) {
-    switch (keyCode) {
-        case AKEYCODE_HOME:
-        case AKEYCODE_BACK:
-        case AKEYCODE_CALL:
-        case AKEYCODE_ENDCALL:
-        case AKEYCODE_VOLUME_UP:
-        case AKEYCODE_VOLUME_DOWN:
-        case AKEYCODE_VOLUME_MUTE:
-        case AKEYCODE_POWER:
-        case AKEYCODE_CAMERA:
-        case AKEYCODE_HEADSETHOOK:
-        case AKEYCODE_MENU:
-        case AKEYCODE_NOTIFICATION:
-        case AKEYCODE_FOCUS:
-        case AKEYCODE_SEARCH:
-        case AKEYCODE_MEDIA_PLAY:
-        case AKEYCODE_MEDIA_PAUSE:
-        case AKEYCODE_MEDIA_PLAY_PAUSE:
-        case AKEYCODE_MEDIA_STOP:
-        case AKEYCODE_MEDIA_NEXT:
-        case AKEYCODE_MEDIA_PREVIOUS:
-        case AKEYCODE_MEDIA_REWIND:
-        case AKEYCODE_MEDIA_RECORD:
-        case AKEYCODE_MEDIA_FAST_FORWARD:
-        case AKEYCODE_MUTE:
-        case AKEYCODE_BRIGHTNESS_DOWN:
-        case AKEYCODE_BRIGHTNESS_UP:
-            return true;
-    }
-    
-    return false;
-}
-
-bool KeyEvent::hasDefaultAction() const {
-    return hasDefaultAction(getKeyCode());
-}
-
-bool KeyEvent::isSystemKey(int32_t keyCode) {
-    switch (keyCode) {
-        case AKEYCODE_MENU:
-        case AKEYCODE_SOFT_RIGHT:
-        case AKEYCODE_HOME:
-        case AKEYCODE_BACK:
-        case AKEYCODE_CALL:
-        case AKEYCODE_ENDCALL:
-        case AKEYCODE_VOLUME_UP:
-        case AKEYCODE_VOLUME_DOWN:
-        case AKEYCODE_VOLUME_MUTE:
-        case AKEYCODE_MUTE:
-        case AKEYCODE_POWER:
-        case AKEYCODE_HEADSETHOOK:
-        case AKEYCODE_MEDIA_PLAY:
-        case AKEYCODE_MEDIA_PAUSE:
-        case AKEYCODE_MEDIA_PLAY_PAUSE:
-        case AKEYCODE_MEDIA_STOP:
-        case AKEYCODE_MEDIA_NEXT:
-        case AKEYCODE_MEDIA_PREVIOUS:
-        case AKEYCODE_MEDIA_REWIND:
-        case AKEYCODE_MEDIA_RECORD:
-        case AKEYCODE_MEDIA_FAST_FORWARD:
-        case AKEYCODE_CAMERA:
-        case AKEYCODE_FOCUS:
-        case AKEYCODE_SEARCH:
-        case AKEYCODE_BRIGHTNESS_DOWN:
-        case AKEYCODE_BRIGHTNESS_UP:
-            return true;
-    }
-    
-    return false;
-}
-
-bool KeyEvent::isSystemKey() const {
-    return isSystemKey(getKeyCode());
-}
-
-void KeyEvent::initialize(
-        int32_t deviceId,
-        int32_t source,
-        int32_t action,
-        int32_t flags,
-        int32_t keyCode,
-        int32_t scanCode,
-        int32_t metaState,
-        int32_t repeatCount,
-        nsecs_t downTime,
-        nsecs_t eventTime) {
-    InputEvent::initialize(deviceId, source);
-    mAction = action;
-    mFlags = flags;
-    mKeyCode = keyCode;
-    mScanCode = scanCode;
-    mMetaState = metaState;
-    mRepeatCount = repeatCount;
-    mDownTime = downTime;
-    mEventTime = eventTime;
-}
-
-void KeyEvent::initialize(const KeyEvent& from) {
-    InputEvent::initialize(from);
-    mAction = from.mAction;
-    mFlags = from.mFlags;
-    mKeyCode = from.mKeyCode;
-    mScanCode = from.mScanCode;
-    mMetaState = from.mMetaState;
-    mRepeatCount = from.mRepeatCount;
-    mDownTime = from.mDownTime;
-    mEventTime = from.mEventTime;
-}
-
-
-// --- PointerCoords ---
-
-float PointerCoords::getAxisValue(int32_t axis) const {
-    if (axis < 0 || axis > 63) {
-        return 0;
-    }
-
-    uint64_t axisBit = 1LL << axis;
-    if (!(bits & axisBit)) {
-        return 0;
-    }
-    uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
-    return values[index];
-}
-
-status_t PointerCoords::setAxisValue(int32_t axis, float value) {
-    if (axis < 0 || axis > 63) {
-        return NAME_NOT_FOUND;
-    }
-
-    uint64_t axisBit = 1LL << axis;
-    uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
-    if (!(bits & axisBit)) {
-        if (value == 0) {
-            return OK; // axes with value 0 do not need to be stored
-        }
-        uint32_t count = __builtin_popcountll(bits);
-        if (count >= MAX_AXES) {
-            tooManyAxes(axis);
-            return NO_MEMORY;
-        }
-        bits |= axisBit;
-        for (uint32_t i = count; i > index; i--) {
-            values[i] = values[i - 1];
-        }
-    }
-    values[index] = value;
-    return OK;
-}
-
-static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
-    float value = c.getAxisValue(axis);
-    if (value != 0) {
-        c.setAxisValue(axis, value * scaleFactor);
-    }
-}
-
-void PointerCoords::scale(float scaleFactor) {
-    // No need to scale pressure or size since they are normalized.
-    // No need to scale orientation since it is meaningless to do so.
-    scaleAxisValue(*this, AMOTION_EVENT_AXIS_X, scaleFactor);
-    scaleAxisValue(*this, AMOTION_EVENT_AXIS_Y, scaleFactor);
-    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MAJOR, scaleFactor);
-    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MINOR, scaleFactor);
-    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MAJOR, scaleFactor);
-    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, scaleFactor);
-}
-
-#ifdef HAVE_ANDROID_OS
-status_t PointerCoords::readFromParcel(Parcel* parcel) {
-    bits = parcel->readInt64();
-
-    uint32_t count = __builtin_popcountll(bits);
-    if (count > MAX_AXES) {
-        return BAD_VALUE;
-    }
-
-    for (uint32_t i = 0; i < count; i++) {
-        values[i] = parcel->readFloat();
-    }
-    return OK;
-}
-
-status_t PointerCoords::writeToParcel(Parcel* parcel) const {
-    parcel->writeInt64(bits);
-
-    uint32_t count = __builtin_popcountll(bits);
-    for (uint32_t i = 0; i < count; i++) {
-        parcel->writeFloat(values[i]);
-    }
-    return OK;
-}
-#endif
-
-void PointerCoords::tooManyAxes(int axis) {
-    ALOGW("Could not set value for axis %d because the PointerCoords structure is full and "
-            "cannot contain more than %d axis values.", axis, int(MAX_AXES));
-}
-
-bool PointerCoords::operator==(const PointerCoords& other) const {
-    if (bits != other.bits) {
-        return false;
-    }
-    uint32_t count = __builtin_popcountll(bits);
-    for (uint32_t i = 0; i < count; i++) {
-        if (values[i] != other.values[i]) {
-            return false;
-        }
-    }
-    return true;
-}
-
-void PointerCoords::copyFrom(const PointerCoords& other) {
-    bits = other.bits;
-    uint32_t count = __builtin_popcountll(bits);
-    for (uint32_t i = 0; i < count; i++) {
-        values[i] = other.values[i];
-    }
-}
-
-
-// --- PointerProperties ---
-
-bool PointerProperties::operator==(const PointerProperties& other) const {
-    return id == other.id
-            && toolType == other.toolType;
-}
-
-void PointerProperties::copyFrom(const PointerProperties& other) {
-    id = other.id;
-    toolType = other.toolType;
-}
-
-
-// --- MotionEvent ---
-
-void MotionEvent::initialize(
-        int32_t deviceId,
-        int32_t source,
-        int32_t action,
-        int32_t flags,
-        int32_t edgeFlags,
-        int32_t metaState,
-        int32_t buttonState,
-        float xOffset,
-        float yOffset,
-        float xPrecision,
-        float yPrecision,
-        nsecs_t downTime,
-        nsecs_t eventTime,
-        size_t pointerCount,
-        const PointerProperties* pointerProperties,
-        const PointerCoords* pointerCoords) {
-    InputEvent::initialize(deviceId, source);
-    mAction = action;
-    mFlags = flags;
-    mEdgeFlags = edgeFlags;
-    mMetaState = metaState;
-    mButtonState = buttonState;
-    mXOffset = xOffset;
-    mYOffset = yOffset;
-    mXPrecision = xPrecision;
-    mYPrecision = yPrecision;
-    mDownTime = downTime;
-    mPointerProperties.clear();
-    mPointerProperties.appendArray(pointerProperties, pointerCount);
-    mSampleEventTimes.clear();
-    mSamplePointerCoords.clear();
-    addSample(eventTime, pointerCoords);
-}
-
-void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
-    InputEvent::initialize(other->mDeviceId, other->mSource);
-    mAction = other->mAction;
-    mFlags = other->mFlags;
-    mEdgeFlags = other->mEdgeFlags;
-    mMetaState = other->mMetaState;
-    mButtonState = other->mButtonState;
-    mXOffset = other->mXOffset;
-    mYOffset = other->mYOffset;
-    mXPrecision = other->mXPrecision;
-    mYPrecision = other->mYPrecision;
-    mDownTime = other->mDownTime;
-    mPointerProperties = other->mPointerProperties;
-
-    if (keepHistory) {
-        mSampleEventTimes = other->mSampleEventTimes;
-        mSamplePointerCoords = other->mSamplePointerCoords;
-    } else {
-        mSampleEventTimes.clear();
-        mSampleEventTimes.push(other->getEventTime());
-        mSamplePointerCoords.clear();
-        size_t pointerCount = other->getPointerCount();
-        size_t historySize = other->getHistorySize();
-        mSamplePointerCoords.appendArray(other->mSamplePointerCoords.array()
-                + (historySize * pointerCount), pointerCount);
-    }
-}
-
-void MotionEvent::addSample(
-        int64_t eventTime,
-        const PointerCoords* pointerCoords) {
-    mSampleEventTimes.push(eventTime);
-    mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
-}
-
-const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
-    return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
-}
-
-float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
-    return getRawPointerCoords(pointerIndex)->getAxisValue(axis);
-}
-
-float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
-    float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);
-    switch (axis) {
-    case AMOTION_EVENT_AXIS_X:
-        return value + mXOffset;
-    case AMOTION_EVENT_AXIS_Y:
-        return value + mYOffset;
-    }
-    return value;
-}
-
-const PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
-        size_t pointerIndex, size_t historicalIndex) const {
-    return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
-}
-
-float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
-        size_t historicalIndex) const {
-    return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
-}
-
-float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
-        size_t historicalIndex) const {
-    float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
-    switch (axis) {
-    case AMOTION_EVENT_AXIS_X:
-        return value + mXOffset;
-    case AMOTION_EVENT_AXIS_Y:
-        return value + mYOffset;
-    }
-    return value;
-}
-
-ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
-    size_t pointerCount = mPointerProperties.size();
-    for (size_t i = 0; i < pointerCount; i++) {
-        if (mPointerProperties.itemAt(i).id == pointerId) {
-            return i;
-        }
-    }
-    return -1;
-}
-
-void MotionEvent::offsetLocation(float xOffset, float yOffset) {
-    mXOffset += xOffset;
-    mYOffset += yOffset;
-}
-
-void MotionEvent::scale(float scaleFactor) {
-    mXOffset *= scaleFactor;
-    mYOffset *= scaleFactor;
-    mXPrecision *= scaleFactor;
-    mYPrecision *= scaleFactor;
-
-    size_t numSamples = mSamplePointerCoords.size();
-    for (size_t i = 0; i < numSamples; i++) {
-        mSamplePointerCoords.editItemAt(i).scale(scaleFactor);
-    }
-}
-
-#ifdef HAVE_ANDROID_OS
-static inline float transformAngle(const SkMatrix* matrix, float angleRadians) {
-    // Construct and transform a vector oriented at the specified clockwise angle from vertical.
-    // Coordinate system: down is increasing Y, right is increasing X.
-    SkPoint vector;
-    vector.fX = SkFloatToScalar(sinf(angleRadians));
-    vector.fY = SkFloatToScalar(-cosf(angleRadians));
-    matrix->mapVectors(& vector, 1);
-
-    // Derive the transformed vector's clockwise angle from vertical.
-    float result = atan2f(SkScalarToFloat(vector.fX), SkScalarToFloat(-vector.fY));
-    if (result < - M_PI_2) {
-        result += M_PI;
-    } else if (result > M_PI_2) {
-        result -= M_PI;
-    }
-    return result;
-}
-
-void MotionEvent::transform(const SkMatrix* matrix) {
-    float oldXOffset = mXOffset;
-    float oldYOffset = mYOffset;
-
-    // The tricky part of this implementation is to preserve the value of
-    // rawX and rawY.  So we apply the transformation to the first point
-    // then derive an appropriate new X/Y offset that will preserve rawX and rawY.
-    SkPoint point;
-    float rawX = getRawX(0);
-    float rawY = getRawY(0);
-    matrix->mapXY(SkFloatToScalar(rawX + oldXOffset), SkFloatToScalar(rawY + oldYOffset),
-            & point);
-    float newX = SkScalarToFloat(point.fX);
-    float newY = SkScalarToFloat(point.fY);
-    float newXOffset = newX - rawX;
-    float newYOffset = newY - rawY;
-
-    mXOffset = newXOffset;
-    mYOffset = newYOffset;
-
-    // Apply the transformation to all samples.
-    size_t numSamples = mSamplePointerCoords.size();
-    for (size_t i = 0; i < numSamples; i++) {
-        PointerCoords& c = mSamplePointerCoords.editItemAt(i);
-        float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) + oldXOffset;
-        float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) + oldYOffset;
-        matrix->mapXY(SkFloatToScalar(x), SkFloatToScalar(y), &point);
-        c.setAxisValue(AMOTION_EVENT_AXIS_X, SkScalarToFloat(point.fX) - newXOffset);
-        c.setAxisValue(AMOTION_EVENT_AXIS_Y, SkScalarToFloat(point.fY) - newYOffset);
-
-        float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
-        c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, transformAngle(matrix, orientation));
-    }
-}
-
-status_t MotionEvent::readFromParcel(Parcel* parcel) {
-    size_t pointerCount = parcel->readInt32();
-    size_t sampleCount = parcel->readInt32();
-    if (pointerCount == 0 || pointerCount > MAX_POINTERS || sampleCount == 0) {
-        return BAD_VALUE;
-    }
-
-    mDeviceId = parcel->readInt32();
-    mSource = parcel->readInt32();
-    mAction = parcel->readInt32();
-    mFlags = parcel->readInt32();
-    mEdgeFlags = parcel->readInt32();
-    mMetaState = parcel->readInt32();
-    mButtonState = parcel->readInt32();
-    mXOffset = parcel->readFloat();
-    mYOffset = parcel->readFloat();
-    mXPrecision = parcel->readFloat();
-    mYPrecision = parcel->readFloat();
-    mDownTime = parcel->readInt64();
-
-    mPointerProperties.clear();
-    mPointerProperties.setCapacity(pointerCount);
-    mSampleEventTimes.clear();
-    mSampleEventTimes.setCapacity(sampleCount);
-    mSamplePointerCoords.clear();
-    mSamplePointerCoords.setCapacity(sampleCount * pointerCount);
-
-    for (size_t i = 0; i < pointerCount; i++) {
-        mPointerProperties.push();
-        PointerProperties& properties = mPointerProperties.editTop();
-        properties.id = parcel->readInt32();
-        properties.toolType = parcel->readInt32();
-    }
-
-    while (sampleCount-- > 0) {
-        mSampleEventTimes.push(parcel->readInt64());
-        for (size_t i = 0; i < pointerCount; i++) {
-            mSamplePointerCoords.push();
-            status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel);
-            if (status) {
-                return status;
-            }
-        }
-    }
-    return OK;
-}
-
-status_t MotionEvent::writeToParcel(Parcel* parcel) const {
-    size_t pointerCount = mPointerProperties.size();
-    size_t sampleCount = mSampleEventTimes.size();
-
-    parcel->writeInt32(pointerCount);
-    parcel->writeInt32(sampleCount);
-
-    parcel->writeInt32(mDeviceId);
-    parcel->writeInt32(mSource);
-    parcel->writeInt32(mAction);
-    parcel->writeInt32(mFlags);
-    parcel->writeInt32(mEdgeFlags);
-    parcel->writeInt32(mMetaState);
-    parcel->writeInt32(mButtonState);
-    parcel->writeFloat(mXOffset);
-    parcel->writeFloat(mYOffset);
-    parcel->writeFloat(mXPrecision);
-    parcel->writeFloat(mYPrecision);
-    parcel->writeInt64(mDownTime);
-
-    for (size_t i = 0; i < pointerCount; i++) {
-        const PointerProperties& properties = mPointerProperties.itemAt(i);
-        parcel->writeInt32(properties.id);
-        parcel->writeInt32(properties.toolType);
-    }
-
-    const PointerCoords* pc = mSamplePointerCoords.array();
-    for (size_t h = 0; h < sampleCount; h++) {
-        parcel->writeInt64(mSampleEventTimes.itemAt(h));
-        for (size_t i = 0; i < pointerCount; i++) {
-            status_t status = (pc++)->writeToParcel(parcel);
-            if (status) {
-                return status;
-            }
-        }
-    }
-    return OK;
-}
-#endif
-
-bool MotionEvent::isTouchEvent(int32_t source, int32_t action) {
-    if (source & AINPUT_SOURCE_CLASS_POINTER) {
-        // Specifically excludes HOVER_MOVE and SCROLL.
-        switch (action & AMOTION_EVENT_ACTION_MASK) {
-        case AMOTION_EVENT_ACTION_DOWN:
-        case AMOTION_EVENT_ACTION_MOVE:
-        case AMOTION_EVENT_ACTION_UP:
-        case AMOTION_EVENT_ACTION_POINTER_DOWN:
-        case AMOTION_EVENT_ACTION_POINTER_UP:
-        case AMOTION_EVENT_ACTION_CANCEL:
-        case AMOTION_EVENT_ACTION_OUTSIDE:
-            return true;
-        }
-    }
-    return false;
-}
-
-
-// --- PooledInputEventFactory ---
-
-PooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) :
-        mMaxPoolSize(maxPoolSize) {
-}
-
-PooledInputEventFactory::~PooledInputEventFactory() {
-    for (size_t i = 0; i < mKeyEventPool.size(); i++) {
-        delete mKeyEventPool.itemAt(i);
-    }
-    for (size_t i = 0; i < mMotionEventPool.size(); i++) {
-        delete mMotionEventPool.itemAt(i);
-    }
-}
-
-KeyEvent* PooledInputEventFactory::createKeyEvent() {
-    if (!mKeyEventPool.isEmpty()) {
-        KeyEvent* event = mKeyEventPool.top();
-        mKeyEventPool.pop();
-        return event;
-    }
-    return new KeyEvent();
-}
-
-MotionEvent* PooledInputEventFactory::createMotionEvent() {
-    if (!mMotionEventPool.isEmpty()) {
-        MotionEvent* event = mMotionEventPool.top();
-        mMotionEventPool.pop();
-        return event;
-    }
-    return new MotionEvent();
-}
-
-void PooledInputEventFactory::recycle(InputEvent* event) {
-    switch (event->getType()) {
-    case AINPUT_EVENT_TYPE_KEY:
-        if (mKeyEventPool.size() < mMaxPoolSize) {
-            mKeyEventPool.push(static_cast<KeyEvent*>(event));
-            return;
-        }
-        break;
-    case AINPUT_EVENT_TYPE_MOTION:
-        if (mMotionEventPool.size() < mMaxPoolSize) {
-            mMotionEventPool.push(static_cast<MotionEvent*>(event));
-            return;
-        }
-        break;
-    }
-    delete event;
-}
-
-} // namespace android
diff --git a/libs/androidfw/InputDevice.cpp b/libs/androidfw/InputDevice.cpp
deleted file mode 100644
index f742052..0000000
--- a/libs/androidfw/InputDevice.cpp
+++ /dev/null
@@ -1,184 +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.
- */
-
-#define LOG_TAG "InputDevice"
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <ctype.h>
-
-#include <androidfw/InputDevice.h>
-
-namespace android {
-
-static const char* CONFIGURATION_FILE_DIR[] = {
-        "idc/",
-        "keylayout/",
-        "keychars/",
-};
-
-static const char* CONFIGURATION_FILE_EXTENSION[] = {
-        ".idc",
-        ".kl",
-        ".kcm",
-};
-
-static bool isValidNameChar(char ch) {
-    return isascii(ch) && (isdigit(ch) || isalpha(ch) || ch == '-' || ch == '_');
-}
-
-static void appendInputDeviceConfigurationFileRelativePath(String8& path,
-        const String8& name, InputDeviceConfigurationFileType type) {
-    path.append(CONFIGURATION_FILE_DIR[type]);
-    for (size_t i = 0; i < name.length(); i++) {
-        char ch = name[i];
-        if (!isValidNameChar(ch)) {
-            ch = '_';
-        }
-        path.append(&ch, 1);
-    }
-    path.append(CONFIGURATION_FILE_EXTENSION[type]);
-}
-
-String8 getInputDeviceConfigurationFilePathByDeviceIdentifier(
-        const InputDeviceIdentifier& deviceIdentifier,
-        InputDeviceConfigurationFileType type) {
-    if (deviceIdentifier.vendor !=0 && deviceIdentifier.product != 0) {
-        if (deviceIdentifier.version != 0) {
-            // Try vendor product version.
-            String8 versionPath(getInputDeviceConfigurationFilePathByName(
-                    String8::format("Vendor_%04x_Product_%04x_Version_%04x",
-                            deviceIdentifier.vendor, deviceIdentifier.product,
-                            deviceIdentifier.version),
-                    type));
-            if (!versionPath.isEmpty()) {
-                return versionPath;
-            }
-        }
-
-        // Try vendor product.
-        String8 productPath(getInputDeviceConfigurationFilePathByName(
-                String8::format("Vendor_%04x_Product_%04x",
-                        deviceIdentifier.vendor, deviceIdentifier.product),
-                type));
-        if (!productPath.isEmpty()) {
-            return productPath;
-        }
-    }
-
-    // Try device name.
-    return getInputDeviceConfigurationFilePathByName(deviceIdentifier.name, type);
-}
-
-String8 getInputDeviceConfigurationFilePathByName(
-        const String8& name, InputDeviceConfigurationFileType type) {
-    // Search system repository.
-    String8 path;
-    path.setTo(getenv("ANDROID_ROOT"));
-    path.append("/usr/");
-    appendInputDeviceConfigurationFileRelativePath(path, name, type);
-#if DEBUG_PROBE
-    ALOGD("Probing for system provided input device configuration file: path='%s'", path.string());
-#endif
-    if (!access(path.string(), R_OK)) {
-#if DEBUG_PROBE
-        ALOGD("Found");
-#endif
-        return path;
-    }
-
-    // Search user repository.
-    // TODO Should only look here if not in safe mode.
-    path.setTo(getenv("ANDROID_DATA"));
-    path.append("/system/devices/");
-    appendInputDeviceConfigurationFileRelativePath(path, name, type);
-#if DEBUG_PROBE
-    ALOGD("Probing for system user input device configuration file: path='%s'", path.string());
-#endif
-    if (!access(path.string(), R_OK)) {
-#if DEBUG_PROBE
-        ALOGD("Found");
-#endif
-        return path;
-    }
-
-    // Not found.
-#if DEBUG_PROBE
-    ALOGD("Probe failed to find input device configuration file: name='%s', type=%d",
-            name.string(), type);
-#endif
-    return String8();
-}
-
-
-// --- InputDeviceInfo ---
-
-InputDeviceInfo::InputDeviceInfo() {
-    initialize(-1, -1, InputDeviceIdentifier(), String8(), false);
-}
-
-InputDeviceInfo::InputDeviceInfo(const InputDeviceInfo& other) :
-        mId(other.mId), mGeneration(other.mGeneration), mIdentifier(other.mIdentifier),
-        mAlias(other.mAlias), mIsExternal(other.mIsExternal), mSources(other.mSources),
-        mKeyboardType(other.mKeyboardType),
-        mKeyCharacterMap(other.mKeyCharacterMap),
-        mHasVibrator(other.mHasVibrator),
-        mMotionRanges(other.mMotionRanges) {
-}
-
-InputDeviceInfo::~InputDeviceInfo() {
-}
-
-void InputDeviceInfo::initialize(int32_t id, int32_t generation,
-        const InputDeviceIdentifier& identifier, const String8& alias, bool isExternal) {
-    mId = id;
-    mGeneration = generation;
-    mIdentifier = identifier;
-    mAlias = alias;
-    mIsExternal = isExternal;
-    mSources = 0;
-    mKeyboardType = AINPUT_KEYBOARD_TYPE_NONE;
-    mHasVibrator = false;
-    mMotionRanges.clear();
-}
-
-const InputDeviceInfo::MotionRange* InputDeviceInfo::getMotionRange(
-        int32_t axis, uint32_t source) const {
-    size_t numRanges = mMotionRanges.size();
-    for (size_t i = 0; i < numRanges; i++) {
-        const MotionRange& range = mMotionRanges.itemAt(i);
-        if (range.axis == axis && range.source == source) {
-            return &range;
-        }
-    }
-    return NULL;
-}
-
-void InputDeviceInfo::addSource(uint32_t source) {
-    mSources |= source;
-}
-
-void InputDeviceInfo::addMotionRange(int32_t axis, uint32_t source, float min, float max,
-        float flat, float fuzz, float resolution) {
-    MotionRange range = { axis, source, min, max, flat, fuzz, resolution };
-    mMotionRanges.add(range);
-}
-
-void InputDeviceInfo::addMotionRange(const MotionRange& range) {
-    mMotionRanges.add(range);
-}
-
-} // namespace android
diff --git a/libs/androidfw/InputTransport.cpp b/libs/androidfw/InputTransport.cpp
deleted file mode 100644
index 498389ea..0000000
--- a/libs/androidfw/InputTransport.cpp
+++ /dev/null
@@ -1,957 +0,0 @@
-//
-// Copyright 2010 The Android Open Source Project
-//
-// Provides a shared memory transport for input events.
-//
-#define LOG_TAG "InputTransport"
-
-//#define LOG_NDEBUG 0
-
-// Log debug messages about channel messages (send message, receive message)
-#define DEBUG_CHANNEL_MESSAGES 0
-
-// Log debug messages whenever InputChannel objects are created/destroyed
-#define DEBUG_CHANNEL_LIFECYCLE 0
-
-// Log debug messages about transport actions
-#define DEBUG_TRANSPORT_ACTIONS 0
-
-// Log debug messages about touch event resampling
-#define DEBUG_RESAMPLING 0
-
-
-#include <cutils/log.h>
-#include <cutils/properties.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <androidfw/InputTransport.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <math.h>
-
-
-namespace android {
-
-// Socket buffer size.  The default is typically about 128KB, which is much larger than
-// we really need.  So we make it smaller.  It just needs to be big enough to hold
-// a few dozen large multi-finger motion events in the case where an application gets
-// behind processing touches.
-static const size_t SOCKET_BUFFER_SIZE = 32 * 1024;
-
-// Nanoseconds per milliseconds.
-static const nsecs_t NANOS_PER_MS = 1000000;
-
-// Latency added during resampling.  A few milliseconds doesn't hurt much but
-// reduces the impact of mispredicted touch positions.
-static const nsecs_t RESAMPLE_LATENCY = 5 * NANOS_PER_MS;
-
-// Minimum time difference between consecutive samples before attempting to resample.
-static const nsecs_t RESAMPLE_MIN_DELTA = 2 * NANOS_PER_MS;
-
-// Maximum time to predict forward from the last known state, to avoid predicting too
-// far into the future.  This time is further bounded by 50% of the last time delta.
-static const nsecs_t RESAMPLE_MAX_PREDICTION = 8 * NANOS_PER_MS;
-
-template<typename T>
-inline static T min(const T& a, const T& b) {
-    return a < b ? a : b;
-}
-
-inline static float lerp(float a, float b, float alpha) {
-    return a + alpha * (b - a);
-}
-
-// --- InputMessage ---
-
-bool InputMessage::isValid(size_t actualSize) const {
-    if (size() == actualSize) {
-        switch (header.type) {
-        case TYPE_KEY:
-            return true;
-        case TYPE_MOTION:
-            return body.motion.pointerCount > 0
-                    && body.motion.pointerCount <= MAX_POINTERS;
-        case TYPE_FINISHED:
-            return true;
-        }
-    }
-    return false;
-}
-
-size_t InputMessage::size() const {
-    switch (header.type) {
-    case TYPE_KEY:
-        return sizeof(Header) + body.key.size();
-    case TYPE_MOTION:
-        return sizeof(Header) + body.motion.size();
-    case TYPE_FINISHED:
-        return sizeof(Header) + body.finished.size();
-    }
-    return sizeof(Header);
-}
-
-
-// --- InputChannel ---
-
-InputChannel::InputChannel(const String8& name, int fd) :
-        mName(name), mFd(fd) {
-#if DEBUG_CHANNEL_LIFECYCLE
-    ALOGD("Input channel constructed: name='%s', fd=%d",
-            mName.string(), fd);
-#endif
-
-    int result = fcntl(mFd, F_SETFL, O_NONBLOCK);
-    LOG_ALWAYS_FATAL_IF(result != 0, "channel '%s' ~ Could not make socket "
-            "non-blocking.  errno=%d", mName.string(), errno);
-}
-
-InputChannel::~InputChannel() {
-#if DEBUG_CHANNEL_LIFECYCLE
-    ALOGD("Input channel destroyed: name='%s', fd=%d",
-            mName.string(), mFd);
-#endif
-
-    ::close(mFd);
-}
-
-status_t InputChannel::openInputChannelPair(const String8& name,
-        sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel) {
-    int sockets[2];
-    if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets)) {
-        status_t result = -errno;
-        ALOGE("channel '%s' ~ Could not create socket pair.  errno=%d",
-                name.string(), errno);
-        outServerChannel.clear();
-        outClientChannel.clear();
-        return result;
-    }
-
-    int bufferSize = SOCKET_BUFFER_SIZE;
-    setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
-    setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
-    setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
-    setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
-
-    String8 serverChannelName = name;
-    serverChannelName.append(" (server)");
-    outServerChannel = new InputChannel(serverChannelName, sockets[0]);
-
-    String8 clientChannelName = name;
-    clientChannelName.append(" (client)");
-    outClientChannel = new InputChannel(clientChannelName, sockets[1]);
-    return OK;
-}
-
-status_t InputChannel::sendMessage(const InputMessage* msg) {
-    size_t msgLength = msg->size();
-    ssize_t nWrite;
-    do {
-        nWrite = ::send(mFd, msg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
-    } while (nWrite == -1 && errno == EINTR);
-
-    if (nWrite < 0) {
-        int error = errno;
-#if DEBUG_CHANNEL_MESSAGES
-        ALOGD("channel '%s' ~ error sending message of type %d, errno=%d", mName.string(),
-                msg->header.type, error);
-#endif
-        if (error == EAGAIN || error == EWOULDBLOCK) {
-            return WOULD_BLOCK;
-        }
-        if (error == EPIPE || error == ENOTCONN) {
-            return DEAD_OBJECT;
-        }
-        return -error;
-    }
-
-    if (size_t(nWrite) != msgLength) {
-#if DEBUG_CHANNEL_MESSAGES
-        ALOGD("channel '%s' ~ error sending message type %d, send was incomplete",
-                mName.string(), msg->header.type);
-#endif
-        return DEAD_OBJECT;
-    }
-
-#if DEBUG_CHANNEL_MESSAGES
-    ALOGD("channel '%s' ~ sent message of type %d", mName.string(), msg->header.type);
-#endif
-    return OK;
-}
-
-status_t InputChannel::receiveMessage(InputMessage* msg) {
-    ssize_t nRead;
-    do {
-        nRead = ::recv(mFd, msg, sizeof(InputMessage), MSG_DONTWAIT);
-    } while (nRead == -1 && errno == EINTR);
-
-    if (nRead < 0) {
-        int error = errno;
-#if DEBUG_CHANNEL_MESSAGES
-        ALOGD("channel '%s' ~ receive message failed, errno=%d", mName.string(), errno);
-#endif
-        if (error == EAGAIN || error == EWOULDBLOCK) {
-            return WOULD_BLOCK;
-        }
-        if (error == EPIPE || error == ENOTCONN) {
-            return DEAD_OBJECT;
-        }
-        return -error;
-    }
-
-    if (nRead == 0) { // check for EOF
-#if DEBUG_CHANNEL_MESSAGES
-        ALOGD("channel '%s' ~ receive message failed because peer was closed", mName.string());
-#endif
-        return DEAD_OBJECT;
-    }
-
-    if (!msg->isValid(nRead)) {
-#if DEBUG_CHANNEL_MESSAGES
-        ALOGD("channel '%s' ~ received invalid message", mName.string());
-#endif
-        return BAD_VALUE;
-    }
-
-#if DEBUG_CHANNEL_MESSAGES
-    ALOGD("channel '%s' ~ received message of type %d", mName.string(), msg->header.type);
-#endif
-    return OK;
-}
-
-sp<InputChannel> InputChannel::dup() const {
-    int fd = ::dup(getFd());
-    return fd >= 0 ? new InputChannel(getName(), fd) : NULL;
-}
-
-
-// --- InputPublisher ---
-
-InputPublisher::InputPublisher(const sp<InputChannel>& channel) :
-        mChannel(channel) {
-}
-
-InputPublisher::~InputPublisher() {
-}
-
-status_t InputPublisher::publishKeyEvent(
-        uint32_t seq,
-        int32_t deviceId,
-        int32_t source,
-        int32_t action,
-        int32_t flags,
-        int32_t keyCode,
-        int32_t scanCode,
-        int32_t metaState,
-        int32_t repeatCount,
-        nsecs_t downTime,
-        nsecs_t eventTime) {
-#if DEBUG_TRANSPORT_ACTIONS
-    ALOGD("channel '%s' publisher ~ publishKeyEvent: seq=%u, deviceId=%d, source=0x%x, "
-            "action=0x%x, flags=0x%x, keyCode=%d, scanCode=%d, metaState=0x%x, repeatCount=%d,"
-            "downTime=%lld, eventTime=%lld",
-            mChannel->getName().string(), seq,
-            deviceId, source, action, flags, keyCode, scanCode, metaState, repeatCount,
-            downTime, eventTime);
-#endif
-
-    if (!seq) {
-        ALOGE("Attempted to publish a key event with sequence number 0.");
-        return BAD_VALUE;
-    }
-
-    InputMessage msg;
-    msg.header.type = InputMessage::TYPE_KEY;
-    msg.body.key.seq = seq;
-    msg.body.key.deviceId = deviceId;
-    msg.body.key.source = source;
-    msg.body.key.action = action;
-    msg.body.key.flags = flags;
-    msg.body.key.keyCode = keyCode;
-    msg.body.key.scanCode = scanCode;
-    msg.body.key.metaState = metaState;
-    msg.body.key.repeatCount = repeatCount;
-    msg.body.key.downTime = downTime;
-    msg.body.key.eventTime = eventTime;
-    return mChannel->sendMessage(&msg);
-}
-
-status_t InputPublisher::publishMotionEvent(
-        uint32_t seq,
-        int32_t deviceId,
-        int32_t source,
-        int32_t action,
-        int32_t flags,
-        int32_t edgeFlags,
-        int32_t metaState,
-        int32_t buttonState,
-        float xOffset,
-        float yOffset,
-        float xPrecision,
-        float yPrecision,
-        nsecs_t downTime,
-        nsecs_t eventTime,
-        size_t pointerCount,
-        const PointerProperties* pointerProperties,
-        const PointerCoords* pointerCoords) {
-#if DEBUG_TRANSPORT_ACTIONS
-    ALOGD("channel '%s' publisher ~ publishMotionEvent: seq=%u, deviceId=%d, source=0x%x, "
-            "action=0x%x, flags=0x%x, edgeFlags=0x%x, metaState=0x%x, buttonState=0x%x, "
-            "xOffset=%f, yOffset=%f, "
-            "xPrecision=%f, yPrecision=%f, downTime=%lld, eventTime=%lld, "
-            "pointerCount=%d",
-            mChannel->getName().string(), seq,
-            deviceId, source, action, flags, edgeFlags, metaState, buttonState,
-            xOffset, yOffset, xPrecision, yPrecision, downTime, eventTime, pointerCount);
-#endif
-
-    if (!seq) {
-        ALOGE("Attempted to publish a motion event with sequence number 0.");
-        return BAD_VALUE;
-    }
-
-    if (pointerCount > MAX_POINTERS || pointerCount < 1) {
-        ALOGE("channel '%s' publisher ~ Invalid number of pointers provided: %d.",
-                mChannel->getName().string(), pointerCount);
-        return BAD_VALUE;
-    }
-
-    InputMessage msg;
-    msg.header.type = InputMessage::TYPE_MOTION;
-    msg.body.motion.seq = seq;
-    msg.body.motion.deviceId = deviceId;
-    msg.body.motion.source = source;
-    msg.body.motion.action = action;
-    msg.body.motion.flags = flags;
-    msg.body.motion.edgeFlags = edgeFlags;
-    msg.body.motion.metaState = metaState;
-    msg.body.motion.buttonState = buttonState;
-    msg.body.motion.xOffset = xOffset;
-    msg.body.motion.yOffset = yOffset;
-    msg.body.motion.xPrecision = xPrecision;
-    msg.body.motion.yPrecision = yPrecision;
-    msg.body.motion.downTime = downTime;
-    msg.body.motion.eventTime = eventTime;
-    msg.body.motion.pointerCount = pointerCount;
-    for (size_t i = 0; i < pointerCount; i++) {
-        msg.body.motion.pointers[i].properties.copyFrom(pointerProperties[i]);
-        msg.body.motion.pointers[i].coords.copyFrom(pointerCoords[i]);
-    }
-    return mChannel->sendMessage(&msg);
-}
-
-status_t InputPublisher::receiveFinishedSignal(uint32_t* outSeq, bool* outHandled) {
-#if DEBUG_TRANSPORT_ACTIONS
-    ALOGD("channel '%s' publisher ~ receiveFinishedSignal",
-            mChannel->getName().string());
-#endif
-
-    InputMessage msg;
-    status_t result = mChannel->receiveMessage(&msg);
-    if (result) {
-        *outSeq = 0;
-        *outHandled = false;
-        return result;
-    }
-    if (msg.header.type != InputMessage::TYPE_FINISHED) {
-        ALOGE("channel '%s' publisher ~ Received unexpected message of type %d from consumer",
-                mChannel->getName().string(), msg.header.type);
-        return UNKNOWN_ERROR;
-    }
-    *outSeq = msg.body.finished.seq;
-    *outHandled = msg.body.finished.handled;
-    return OK;
-}
-
-// --- InputConsumer ---
-
-InputConsumer::InputConsumer(const sp<InputChannel>& channel) :
-        mResampleTouch(isTouchResamplingEnabled()),
-        mChannel(channel), mMsgDeferred(false) {
-}
-
-InputConsumer::~InputConsumer() {
-}
-
-bool InputConsumer::isTouchResamplingEnabled() {
-    char value[PROPERTY_VALUE_MAX];
-    int length = property_get("debug.inputconsumer.resample", value, NULL);
-    if (length > 0) {
-        if (!strcmp("0", value)) {
-            return false;
-        }
-        if (strcmp("1", value)) {
-            ALOGD("Unrecognized property value for 'debug.inputconsumer.resample'.  "
-                    "Use '1' or '0'.");
-        }
-    }
-    return true;
-}
-
-status_t InputConsumer::consume(InputEventFactoryInterface* factory,
-        bool consumeBatches, nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) {
-#if DEBUG_TRANSPORT_ACTIONS
-    ALOGD("channel '%s' consumer ~ consume: consumeBatches=%s, frameTime=%lld",
-            mChannel->getName().string(), consumeBatches ? "true" : "false", frameTime);
-#endif
-
-    *outSeq = 0;
-    *outEvent = NULL;
-
-    // Fetch the next input message.
-    // Loop until an event can be returned or no additional events are received.
-    while (!*outEvent) {
-        if (mMsgDeferred) {
-            // mMsg contains a valid input message from the previous call to consume
-            // that has not yet been processed.
-            mMsgDeferred = false;
-        } else {
-            // Receive a fresh message.
-            status_t result = mChannel->receiveMessage(&mMsg);
-            if (result) {
-                // Consume the next batched event unless batches are being held for later.
-                if (consumeBatches || result != WOULD_BLOCK) {
-                    result = consumeBatch(factory, frameTime, outSeq, outEvent);
-                    if (*outEvent) {
-#if DEBUG_TRANSPORT_ACTIONS
-                        ALOGD("channel '%s' consumer ~ consumed batch event, seq=%u",
-                                mChannel->getName().string(), *outSeq);
-#endif
-                        break;
-                    }
-                }
-                return result;
-            }
-        }
-
-        switch (mMsg.header.type) {
-        case InputMessage::TYPE_KEY: {
-            KeyEvent* keyEvent = factory->createKeyEvent();
-            if (!keyEvent) return NO_MEMORY;
-
-            initializeKeyEvent(keyEvent, &mMsg);
-            *outSeq = mMsg.body.key.seq;
-            *outEvent = keyEvent;
-#if DEBUG_TRANSPORT_ACTIONS
-            ALOGD("channel '%s' consumer ~ consumed key event, seq=%u",
-                    mChannel->getName().string(), *outSeq);
-#endif
-            break;
-        }
-
-        case AINPUT_EVENT_TYPE_MOTION: {
-            ssize_t batchIndex = findBatch(mMsg.body.motion.deviceId, mMsg.body.motion.source);
-            if (batchIndex >= 0) {
-                Batch& batch = mBatches.editItemAt(batchIndex);
-                if (canAddSample(batch, &mMsg)) {
-                    batch.samples.push(mMsg);
-#if DEBUG_TRANSPORT_ACTIONS
-                    ALOGD("channel '%s' consumer ~ appended to batch event",
-                            mChannel->getName().string());
-#endif
-                    break;
-                } else {
-                    // We cannot append to the batch in progress, so we need to consume
-                    // the previous batch right now and defer the new message until later.
-                    mMsgDeferred = true;
-                    status_t result = consumeSamples(factory,
-                            batch, batch.samples.size(), outSeq, outEvent);
-                    mBatches.removeAt(batchIndex);
-                    if (result) {
-                        return result;
-                    }
-#if DEBUG_TRANSPORT_ACTIONS
-                    ALOGD("channel '%s' consumer ~ consumed batch event and "
-                            "deferred current event, seq=%u",
-                            mChannel->getName().string(), *outSeq);
-#endif
-                    break;
-                }
-            }
-
-            // Start a new batch if needed.
-            if (mMsg.body.motion.action == AMOTION_EVENT_ACTION_MOVE
-                    || mMsg.body.motion.action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
-                mBatches.push();
-                Batch& batch = mBatches.editTop();
-                batch.samples.push(mMsg);
-#if DEBUG_TRANSPORT_ACTIONS
-                ALOGD("channel '%s' consumer ~ started batch event",
-                        mChannel->getName().string());
-#endif
-                break;
-            }
-
-            MotionEvent* motionEvent = factory->createMotionEvent();
-            if (! motionEvent) return NO_MEMORY;
-
-            updateTouchState(&mMsg);
-            initializeMotionEvent(motionEvent, &mMsg);
-            *outSeq = mMsg.body.motion.seq;
-            *outEvent = motionEvent;
-#if DEBUG_TRANSPORT_ACTIONS
-            ALOGD("channel '%s' consumer ~ consumed motion event, seq=%u",
-                    mChannel->getName().string(), *outSeq);
-#endif
-            break;
-        }
-
-        default:
-            ALOGE("channel '%s' consumer ~ Received unexpected message of type %d",
-                    mChannel->getName().string(), mMsg.header.type);
-            return UNKNOWN_ERROR;
-        }
-    }
-    return OK;
-}
-
-status_t InputConsumer::consumeBatch(InputEventFactoryInterface* factory,
-        nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) {
-    status_t result;
-    for (size_t i = mBatches.size(); i-- > 0; ) {
-        Batch& batch = mBatches.editItemAt(i);
-        if (frameTime < 0) {
-            result = consumeSamples(factory, batch, batch.samples.size(),
-                    outSeq, outEvent);
-            mBatches.removeAt(i);
-            return result;
-        }
-
-        nsecs_t sampleTime = frameTime - RESAMPLE_LATENCY;
-        ssize_t split = findSampleNoLaterThan(batch, sampleTime);
-        if (split < 0) {
-            continue;
-        }
-
-        result = consumeSamples(factory, batch, split + 1, outSeq, outEvent);
-        const InputMessage* next;
-        if (batch.samples.isEmpty()) {
-            mBatches.removeAt(i);
-            next = NULL;
-        } else {
-            next = &batch.samples.itemAt(0);
-        }
-        if (!result) {
-            resampleTouchState(sampleTime, static_cast<MotionEvent*>(*outEvent), next);
-        }
-        return result;
-    }
-
-    return WOULD_BLOCK;
-}
-
-status_t InputConsumer::consumeSamples(InputEventFactoryInterface* factory,
-        Batch& batch, size_t count, uint32_t* outSeq, InputEvent** outEvent) {
-    MotionEvent* motionEvent = factory->createMotionEvent();
-    if (! motionEvent) return NO_MEMORY;
-
-    uint32_t chain = 0;
-    for (size_t i = 0; i < count; i++) {
-        InputMessage& msg = batch.samples.editItemAt(i);
-        updateTouchState(&msg);
-        if (i) {
-            SeqChain seqChain;
-            seqChain.seq = msg.body.motion.seq;
-            seqChain.chain = chain;
-            mSeqChains.push(seqChain);
-            addSample(motionEvent, &msg);
-        } else {
-            initializeMotionEvent(motionEvent, &msg);
-        }
-        chain = msg.body.motion.seq;
-    }
-    batch.samples.removeItemsAt(0, count);
-
-    *outSeq = chain;
-    *outEvent = motionEvent;
-    return OK;
-}
-
-void InputConsumer::updateTouchState(InputMessage* msg) {
-    if (!mResampleTouch ||
-            !(msg->body.motion.source & AINPUT_SOURCE_CLASS_POINTER)) {
-        return;
-    }
-
-    int32_t deviceId = msg->body.motion.deviceId;
-    int32_t source = msg->body.motion.source;
-    nsecs_t eventTime = msg->body.motion.eventTime;
-
-    // Update the touch state history to incorporate the new input message.
-    // If the message is in the past relative to the most recently produced resampled
-    // touch, then use the resampled time and coordinates instead.
-    switch (msg->body.motion.action & AMOTION_EVENT_ACTION_MASK) {
-    case AMOTION_EVENT_ACTION_DOWN: {
-        ssize_t index = findTouchState(deviceId, source);
-        if (index < 0) {
-            mTouchStates.push();
-            index = mTouchStates.size() - 1;
-        }
-        TouchState& touchState = mTouchStates.editItemAt(index);
-        touchState.initialize(deviceId, source);
-        touchState.addHistory(msg);
-        break;
-    }
-
-    case AMOTION_EVENT_ACTION_MOVE: {
-        ssize_t index = findTouchState(deviceId, source);
-        if (index >= 0) {
-            TouchState& touchState = mTouchStates.editItemAt(index);
-            touchState.addHistory(msg);
-            if (eventTime < touchState.lastResample.eventTime) {
-                rewriteMessage(touchState, msg);
-            } else {
-                touchState.lastResample.idBits.clear();
-            }
-        }
-        break;
-    }
-
-    case AMOTION_EVENT_ACTION_POINTER_DOWN: {
-        ssize_t index = findTouchState(deviceId, source);
-        if (index >= 0) {
-            TouchState& touchState = mTouchStates.editItemAt(index);
-            touchState.lastResample.idBits.clearBit(msg->body.motion.getActionId());
-            rewriteMessage(touchState, msg);
-        }
-        break;
-    }
-
-    case AMOTION_EVENT_ACTION_POINTER_UP: {
-        ssize_t index = findTouchState(deviceId, source);
-        if (index >= 0) {
-            TouchState& touchState = mTouchStates.editItemAt(index);
-            rewriteMessage(touchState, msg);
-            touchState.lastResample.idBits.clearBit(msg->body.motion.getActionId());
-        }
-        break;
-    }
-
-    case AMOTION_EVENT_ACTION_SCROLL: {
-        ssize_t index = findTouchState(deviceId, source);
-        if (index >= 0) {
-            const TouchState& touchState = mTouchStates.itemAt(index);
-            rewriteMessage(touchState, msg);
-        }
-        break;
-    }
-
-    case AMOTION_EVENT_ACTION_UP:
-    case AMOTION_EVENT_ACTION_CANCEL: {
-        ssize_t index = findTouchState(deviceId, source);
-        if (index >= 0) {
-            const TouchState& touchState = mTouchStates.itemAt(index);
-            rewriteMessage(touchState, msg);
-            mTouchStates.removeAt(index);
-        }
-        break;
-    }
-    }
-}
-
-void InputConsumer::rewriteMessage(const TouchState& state, InputMessage* msg) {
-    for (size_t i = 0; i < msg->body.motion.pointerCount; i++) {
-        uint32_t id = msg->body.motion.pointers[i].properties.id;
-        if (state.lastResample.idBits.hasBit(id)) {
-            PointerCoords& msgCoords = msg->body.motion.pointers[i].coords;
-            const PointerCoords& resampleCoords = state.lastResample.getPointerById(id);
-#if DEBUG_RESAMPLING
-            ALOGD("[%d] - rewrite (%0.3f, %0.3f), old (%0.3f, %0.3f)", id,
-                    resampleCoords.getAxisValue(AMOTION_EVENT_AXIS_X),
-                    resampleCoords.getAxisValue(AMOTION_EVENT_AXIS_Y),
-                    msgCoords.getAxisValue(AMOTION_EVENT_AXIS_X),
-                    msgCoords.getAxisValue(AMOTION_EVENT_AXIS_Y));
-#endif
-            msgCoords.setAxisValue(AMOTION_EVENT_AXIS_X, resampleCoords.getX());
-            msgCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, resampleCoords.getY());
-        }
-    }
-}
-
-void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event,
-    const InputMessage* next) {
-    if (!mResampleTouch
-            || !(event->getSource() & AINPUT_SOURCE_CLASS_POINTER)
-            || event->getAction() != AMOTION_EVENT_ACTION_MOVE) {
-        return;
-    }
-
-    ssize_t index = findTouchState(event->getDeviceId(), event->getSource());
-    if (index < 0) {
-#if DEBUG_RESAMPLING
-        ALOGD("Not resampled, no touch state for device.");
-#endif
-        return;
-    }
-
-    TouchState& touchState = mTouchStates.editItemAt(index);
-    if (touchState.historySize < 1) {
-#if DEBUG_RESAMPLING
-        ALOGD("Not resampled, no history for device.");
-#endif
-        return;
-    }
-
-    // Ensure that the current sample has all of the pointers that need to be reported.
-    const History* current = touchState.getHistory(0);
-    size_t pointerCount = event->getPointerCount();
-    for (size_t i = 0; i < pointerCount; i++) {
-        uint32_t id = event->getPointerId(i);
-        if (!current->idBits.hasBit(id)) {
-#if DEBUG_RESAMPLING
-            ALOGD("Not resampled, missing id %d", id);
-#endif
-            return;
-        }
-    }
-
-    // Find the data to use for resampling.
-    const History* other;
-    History future;
-    float alpha;
-    if (next) {
-        // Interpolate between current sample and future sample.
-        // So current->eventTime <= sampleTime <= future.eventTime.
-        future.initializeFrom(next);
-        other = &future;
-        nsecs_t delta = future.eventTime - current->eventTime;
-        if (delta < RESAMPLE_MIN_DELTA) {
-#if DEBUG_RESAMPLING
-            ALOGD("Not resampled, delta time is %lld ns.", delta);
-#endif
-            return;
-        }
-        alpha = float(sampleTime - current->eventTime) / delta;
-    } else if (touchState.historySize >= 2) {
-        // Extrapolate future sample using current sample and past sample.
-        // So other->eventTime <= current->eventTime <= sampleTime.
-        other = touchState.getHistory(1);
-        nsecs_t delta = current->eventTime - other->eventTime;
-        if (delta < RESAMPLE_MIN_DELTA) {
-#if DEBUG_RESAMPLING
-            ALOGD("Not resampled, delta time is %lld ns.", delta);
-#endif
-            return;
-        }
-        nsecs_t maxPredict = current->eventTime + min(delta / 2, RESAMPLE_MAX_PREDICTION);
-        if (sampleTime > maxPredict) {
-#if DEBUG_RESAMPLING
-            ALOGD("Sample time is too far in the future, adjusting prediction "
-                    "from %lld to %lld ns.",
-                    sampleTime - current->eventTime, maxPredict - current->eventTime);
-#endif
-            sampleTime = maxPredict;
-        }
-        alpha = float(current->eventTime - sampleTime) / delta;
-    } else {
-#if DEBUG_RESAMPLING
-        ALOGD("Not resampled, insufficient data.");
-#endif
-        return;
-    }
-
-    // Resample touch coordinates.
-    touchState.lastResample.eventTime = sampleTime;
-    touchState.lastResample.idBits.clear();
-    for (size_t i = 0; i < pointerCount; i++) {
-        uint32_t id = event->getPointerId(i);
-        touchState.lastResample.idToIndex[id] = i;
-        touchState.lastResample.idBits.markBit(id);
-        PointerCoords& resampledCoords = touchState.lastResample.pointers[i];
-        const PointerCoords& currentCoords = current->getPointerById(id);
-        if (other->idBits.hasBit(id)
-                && shouldResampleTool(event->getToolType(i))) {
-            const PointerCoords& otherCoords = other->getPointerById(id);
-            resampledCoords.copyFrom(currentCoords);
-            resampledCoords.setAxisValue(AMOTION_EVENT_AXIS_X,
-                    lerp(currentCoords.getX(), otherCoords.getX(), alpha));
-            resampledCoords.setAxisValue(AMOTION_EVENT_AXIS_Y,
-                    lerp(currentCoords.getY(), otherCoords.getY(), alpha));
-#if DEBUG_RESAMPLING
-            ALOGD("[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f), "
-                    "other (%0.3f, %0.3f), alpha %0.3f",
-                    id, resampledCoords.getX(), resampledCoords.getY(),
-                    currentCoords.getX(), currentCoords.getY(),
-                    otherCoords.getX(), otherCoords.getY(),
-                    alpha);
-#endif
-        } else {
-            resampledCoords.copyFrom(currentCoords);
-#if DEBUG_RESAMPLING
-            ALOGD("[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f)",
-                    id, resampledCoords.getX(), resampledCoords.getY(),
-                    currentCoords.getX(), currentCoords.getY());
-#endif
-        }
-    }
-
-    event->addSample(sampleTime, touchState.lastResample.pointers);
-}
-
-bool InputConsumer::shouldResampleTool(int32_t toolType) {
-    return toolType == AMOTION_EVENT_TOOL_TYPE_FINGER
-            || toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
-}
-
-status_t InputConsumer::sendFinishedSignal(uint32_t seq, bool handled) {
-#if DEBUG_TRANSPORT_ACTIONS
-    ALOGD("channel '%s' consumer ~ sendFinishedSignal: seq=%u, handled=%s",
-            mChannel->getName().string(), seq, handled ? "true" : "false");
-#endif
-
-    if (!seq) {
-        ALOGE("Attempted to send a finished signal with sequence number 0.");
-        return BAD_VALUE;
-    }
-
-    // Send finished signals for the batch sequence chain first.
-    size_t seqChainCount = mSeqChains.size();
-    if (seqChainCount) {
-        uint32_t currentSeq = seq;
-        uint32_t chainSeqs[seqChainCount];
-        size_t chainIndex = 0;
-        for (size_t i = seqChainCount; i-- > 0; ) {
-             const SeqChain& seqChain = mSeqChains.itemAt(i);
-             if (seqChain.seq == currentSeq) {
-                 currentSeq = seqChain.chain;
-                 chainSeqs[chainIndex++] = currentSeq;
-                 mSeqChains.removeAt(i);
-             }
-        }
-        status_t status = OK;
-        while (!status && chainIndex-- > 0) {
-            status = sendUnchainedFinishedSignal(chainSeqs[chainIndex], handled);
-        }
-        if (status) {
-            // An error occurred so at least one signal was not sent, reconstruct the chain.
-            do {
-                SeqChain seqChain;
-                seqChain.seq = chainIndex != 0 ? chainSeqs[chainIndex - 1] : seq;
-                seqChain.chain = chainSeqs[chainIndex];
-                mSeqChains.push(seqChain);
-            } while (chainIndex-- > 0);
-            return status;
-        }
-    }
-
-    // Send finished signal for the last message in the batch.
-    return sendUnchainedFinishedSignal(seq, handled);
-}
-
-status_t InputConsumer::sendUnchainedFinishedSignal(uint32_t seq, bool handled) {
-    InputMessage msg;
-    msg.header.type = InputMessage::TYPE_FINISHED;
-    msg.body.finished.seq = seq;
-    msg.body.finished.handled = handled;
-    return mChannel->sendMessage(&msg);
-}
-
-bool InputConsumer::hasDeferredEvent() const {
-    return mMsgDeferred;
-}
-
-bool InputConsumer::hasPendingBatch() const {
-    return !mBatches.isEmpty();
-}
-
-ssize_t InputConsumer::findBatch(int32_t deviceId, int32_t source) const {
-    for (size_t i = 0; i < mBatches.size(); i++) {
-        const Batch& batch = mBatches.itemAt(i);
-        const InputMessage& head = batch.samples.itemAt(0);
-        if (head.body.motion.deviceId == deviceId && head.body.motion.source == source) {
-            return i;
-        }
-    }
-    return -1;
-}
-
-ssize_t InputConsumer::findTouchState(int32_t deviceId, int32_t source) const {
-    for (size_t i = 0; i < mTouchStates.size(); i++) {
-        const TouchState& touchState = mTouchStates.itemAt(i);
-        if (touchState.deviceId == deviceId && touchState.source == source) {
-            return i;
-        }
-    }
-    return -1;
-}
-
-void InputConsumer::initializeKeyEvent(KeyEvent* event, const InputMessage* msg) {
-    event->initialize(
-            msg->body.key.deviceId,
-            msg->body.key.source,
-            msg->body.key.action,
-            msg->body.key.flags,
-            msg->body.key.keyCode,
-            msg->body.key.scanCode,
-            msg->body.key.metaState,
-            msg->body.key.repeatCount,
-            msg->body.key.downTime,
-            msg->body.key.eventTime);
-}
-
-void InputConsumer::initializeMotionEvent(MotionEvent* event, const InputMessage* msg) {
-    size_t pointerCount = msg->body.motion.pointerCount;
-    PointerProperties pointerProperties[pointerCount];
-    PointerCoords pointerCoords[pointerCount];
-    for (size_t i = 0; i < pointerCount; i++) {
-        pointerProperties[i].copyFrom(msg->body.motion.pointers[i].properties);
-        pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
-    }
-
-    event->initialize(
-            msg->body.motion.deviceId,
-            msg->body.motion.source,
-            msg->body.motion.action,
-            msg->body.motion.flags,
-            msg->body.motion.edgeFlags,
-            msg->body.motion.metaState,
-            msg->body.motion.buttonState,
-            msg->body.motion.xOffset,
-            msg->body.motion.yOffset,
-            msg->body.motion.xPrecision,
-            msg->body.motion.yPrecision,
-            msg->body.motion.downTime,
-            msg->body.motion.eventTime,
-            pointerCount,
-            pointerProperties,
-            pointerCoords);
-}
-
-void InputConsumer::addSample(MotionEvent* event, const InputMessage* msg) {
-    size_t pointerCount = msg->body.motion.pointerCount;
-    PointerCoords pointerCoords[pointerCount];
-    for (size_t i = 0; i < pointerCount; i++) {
-        pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
-    }
-
-    event->setMetaState(event->getMetaState() | msg->body.motion.metaState);
-    event->addSample(msg->body.motion.eventTime, pointerCoords);
-}
-
-bool InputConsumer::canAddSample(const Batch& batch, const InputMessage *msg) {
-    const InputMessage& head = batch.samples.itemAt(0);
-    size_t pointerCount = msg->body.motion.pointerCount;
-    if (head.body.motion.pointerCount != pointerCount
-            || head.body.motion.action != msg->body.motion.action) {
-        return false;
-    }
-    for (size_t i = 0; i < pointerCount; i++) {
-        if (head.body.motion.pointers[i].properties
-                != msg->body.motion.pointers[i].properties) {
-            return false;
-        }
-    }
-    return true;
-}
-
-ssize_t InputConsumer::findSampleNoLaterThan(const Batch& batch, nsecs_t time) {
-    size_t numSamples = batch.samples.size();
-    size_t index = 0;
-    while (index < numSamples
-            && batch.samples.itemAt(index).body.motion.eventTime <= time) {
-        index += 1;
-    }
-    return ssize_t(index) - 1;
-}
-
-} // namespace android
diff --git a/libs/androidfw/KeyCharacterMap.cpp b/libs/androidfw/KeyCharacterMap.cpp
deleted file mode 100644
index 36cb6e1..0000000
--- a/libs/androidfw/KeyCharacterMap.cpp
+++ /dev/null
@@ -1,1153 +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.
- */
-
-#define LOG_TAG "KeyCharacterMap"
-
-#include <stdlib.h>
-#include <string.h>
-#include <android/keycodes.h>
-#include <androidfw/Keyboard.h>
-#include <androidfw/KeyCharacterMap.h>
-
-#if HAVE_ANDROID_OS
-#include <binder/Parcel.h>
-#endif
-
-#include <utils/Log.h>
-#include <utils/Errors.h>
-#include <utils/Tokenizer.h>
-#include <utils/Timers.h>
-
-// Enables debug output for the parser.
-#define DEBUG_PARSER 0
-
-// Enables debug output for parser performance.
-#define DEBUG_PARSER_PERFORMANCE 0
-
-// Enables debug output for mapping.
-#define DEBUG_MAPPING 0
-
-
-namespace android {
-
-static const char* WHITESPACE = " \t\r";
-static const char* WHITESPACE_OR_PROPERTY_DELIMITER = " \t\r,:";
-
-struct Modifier {
-    const char* label;
-    int32_t metaState;
-};
-static const Modifier modifiers[] = {
-        { "shift", AMETA_SHIFT_ON },
-        { "lshift", AMETA_SHIFT_LEFT_ON },
-        { "rshift", AMETA_SHIFT_RIGHT_ON },
-        { "alt", AMETA_ALT_ON },
-        { "lalt", AMETA_ALT_LEFT_ON },
-        { "ralt", AMETA_ALT_RIGHT_ON },
-        { "ctrl", AMETA_CTRL_ON },
-        { "lctrl", AMETA_CTRL_LEFT_ON },
-        { "rctrl", AMETA_CTRL_RIGHT_ON },
-        { "meta", AMETA_META_ON },
-        { "lmeta", AMETA_META_LEFT_ON },
-        { "rmeta", AMETA_META_RIGHT_ON },
-        { "sym", AMETA_SYM_ON },
-        { "fn", AMETA_FUNCTION_ON },
-        { "capslock", AMETA_CAPS_LOCK_ON },
-        { "numlock", AMETA_NUM_LOCK_ON },
-        { "scrolllock", AMETA_SCROLL_LOCK_ON },
-};
-
-#if DEBUG_MAPPING
-static String8 toString(const char16_t* chars, size_t numChars) {
-    String8 result;
-    for (size_t i = 0; i < numChars; i++) {
-        result.appendFormat(i == 0 ? "%d" : ", %d", chars[i]);
-    }
-    return result;
-}
-#endif
-
-
-// --- KeyCharacterMap ---
-
-sp<KeyCharacterMap> KeyCharacterMap::sEmpty = new KeyCharacterMap();
-
-KeyCharacterMap::KeyCharacterMap() :
-    mType(KEYBOARD_TYPE_UNKNOWN) {
-}
-
-KeyCharacterMap::KeyCharacterMap(const KeyCharacterMap& other) :
-    RefBase(), mType(other.mType), mKeysByScanCode(other.mKeysByScanCode),
-    mKeysByUsageCode(other.mKeysByUsageCode) {
-    for (size_t i = 0; i < other.mKeys.size(); i++) {
-        mKeys.add(other.mKeys.keyAt(i), new Key(*other.mKeys.valueAt(i)));
-    }
-}
-
-KeyCharacterMap::~KeyCharacterMap() {
-    for (size_t i = 0; i < mKeys.size(); i++) {
-        Key* key = mKeys.editValueAt(i);
-        delete key;
-    }
-}
-
-status_t KeyCharacterMap::load(const String8& filename,
-        Format format, sp<KeyCharacterMap>* outMap) {
-    outMap->clear();
-
-    Tokenizer* tokenizer;
-    status_t status = Tokenizer::open(filename, &tokenizer);
-    if (status) {
-        ALOGE("Error %d opening key character map file %s.", status, filename.string());
-    } else {
-        status = load(tokenizer, format, outMap);
-        delete tokenizer;
-    }
-    return status;
-}
-
-status_t KeyCharacterMap::loadContents(const String8& filename, const char* contents,
-        Format format, sp<KeyCharacterMap>* outMap) {
-    outMap->clear();
-
-    Tokenizer* tokenizer;
-    status_t status = Tokenizer::fromContents(filename, contents, &tokenizer);
-    if (status) {
-        ALOGE("Error %d opening key character map.", status);
-    } else {
-        status = load(tokenizer, format, outMap);
-        delete tokenizer;
-    }
-    return status;
-}
-
-status_t KeyCharacterMap::load(Tokenizer* tokenizer,
-        Format format, sp<KeyCharacterMap>* outMap) {
-    status_t status = OK;
-    sp<KeyCharacterMap> map = new KeyCharacterMap();
-    if (!map.get()) {
-        ALOGE("Error allocating key character map.");
-        status = NO_MEMORY;
-    } else {
-#if DEBUG_PARSER_PERFORMANCE
-        nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
-#endif
-        Parser parser(map.get(), tokenizer, format);
-        status = parser.parse();
-#if DEBUG_PARSER_PERFORMANCE
-        nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
-        ALOGD("Parsed key character map file '%s' %d lines in %0.3fms.",
-                tokenizer->getFilename().string(), tokenizer->getLineNumber(),
-                elapsedTime / 1000000.0);
-#endif
-        if (!status) {
-            *outMap = map;
-        }
-    }
-    return status;
-}
-
-sp<KeyCharacterMap> KeyCharacterMap::combine(const sp<KeyCharacterMap>& base,
-        const sp<KeyCharacterMap>& overlay) {
-    if (overlay == NULL) {
-        return base;
-    }
-    if (base == NULL) {
-        return overlay;
-    }
-
-    sp<KeyCharacterMap> map = new KeyCharacterMap(*base.get());
-    for (size_t i = 0; i < overlay->mKeys.size(); i++) {
-        int32_t keyCode = overlay->mKeys.keyAt(i);
-        Key* key = overlay->mKeys.valueAt(i);
-        ssize_t oldIndex = map->mKeys.indexOfKey(keyCode);
-        if (oldIndex >= 0) {
-            delete map->mKeys.valueAt(oldIndex);
-            map->mKeys.editValueAt(oldIndex) = new Key(*key);
-        } else {
-            map->mKeys.add(keyCode, new Key(*key));
-        }
-    }
-
-    for (size_t i = 0; i < overlay->mKeysByScanCode.size(); i++) {
-        map->mKeysByScanCode.replaceValueFor(overlay->mKeysByScanCode.keyAt(i),
-                overlay->mKeysByScanCode.valueAt(i));
-    }
-
-    for (size_t i = 0; i < overlay->mKeysByUsageCode.size(); i++) {
-        map->mKeysByUsageCode.replaceValueFor(overlay->mKeysByUsageCode.keyAt(i),
-                overlay->mKeysByUsageCode.valueAt(i));
-    }
-    return map;
-}
-
-sp<KeyCharacterMap> KeyCharacterMap::empty() {
-    return sEmpty;
-}
-
-int32_t KeyCharacterMap::getKeyboardType() const {
-    return mType;
-}
-
-char16_t KeyCharacterMap::getDisplayLabel(int32_t keyCode) const {
-    char16_t result = 0;
-    const Key* key;
-    if (getKey(keyCode, &key)) {
-        result = key->label;
-    }
-#if DEBUG_MAPPING
-    ALOGD("getDisplayLabel: keyCode=%d ~ Result %d.", keyCode, result);
-#endif
-    return result;
-}
-
-char16_t KeyCharacterMap::getNumber(int32_t keyCode) const {
-    char16_t result = 0;
-    const Key* key;
-    if (getKey(keyCode, &key)) {
-        result = key->number;
-    }
-#if DEBUG_MAPPING
-    ALOGD("getNumber: keyCode=%d ~ Result %d.", keyCode, result);
-#endif
-    return result;
-}
-
-char16_t KeyCharacterMap::getCharacter(int32_t keyCode, int32_t metaState) const {
-    char16_t result = 0;
-    const Key* key;
-    const Behavior* behavior;
-    if (getKeyBehavior(keyCode, metaState, &key, &behavior)) {
-        result = behavior->character;
-    }
-#if DEBUG_MAPPING
-    ALOGD("getCharacter: keyCode=%d, metaState=0x%08x ~ Result %d.", keyCode, metaState, result);
-#endif
-    return result;
-}
-
-bool KeyCharacterMap::getFallbackAction(int32_t keyCode, int32_t metaState,
-        FallbackAction* outFallbackAction) const {
-    outFallbackAction->keyCode = 0;
-    outFallbackAction->metaState = 0;
-
-    bool result = false;
-    const Key* key;
-    const Behavior* behavior;
-    if (getKeyBehavior(keyCode, metaState, &key, &behavior)) {
-        if (behavior->fallbackKeyCode) {
-            outFallbackAction->keyCode = behavior->fallbackKeyCode;
-            outFallbackAction->metaState = metaState & ~behavior->metaState;
-            result = true;
-        }
-    }
-#if DEBUG_MAPPING
-    ALOGD("getFallbackKeyCode: keyCode=%d, metaState=0x%08x ~ Result %s, "
-            "fallback keyCode=%d, fallback metaState=0x%08x.",
-            keyCode, metaState, result ? "true" : "false",
-            outFallbackAction->keyCode, outFallbackAction->metaState);
-#endif
-    return result;
-}
-
-char16_t KeyCharacterMap::getMatch(int32_t keyCode, const char16_t* chars, size_t numChars,
-        int32_t metaState) const {
-    char16_t result = 0;
-    const Key* key;
-    if (getKey(keyCode, &key)) {
-        // Try to find the most general behavior that maps to this character.
-        // For example, the base key behavior will usually be last in the list.
-        // However, if we find a perfect meta state match for one behavior then use that one.
-        for (const Behavior* behavior = key->firstBehavior; behavior; behavior = behavior->next) {
-            if (behavior->character) {
-                for (size_t i = 0; i < numChars; i++) {
-                    if (behavior->character == chars[i]) {
-                        result = behavior->character;
-                        if ((behavior->metaState & metaState) == behavior->metaState) {
-                            goto ExactMatch;
-                        }
-                        break;
-                    }
-                }
-            }
-        }
-    ExactMatch: ;
-    }
-#if DEBUG_MAPPING
-    ALOGD("getMatch: keyCode=%d, chars=[%s], metaState=0x%08x ~ Result %d.",
-            keyCode, toString(chars, numChars).string(), metaState, result);
-#endif
-    return result;
-}
-
-bool KeyCharacterMap::getEvents(int32_t deviceId, const char16_t* chars, size_t numChars,
-        Vector<KeyEvent>& outEvents) const {
-    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
-
-    for (size_t i = 0; i < numChars; i++) {
-        int32_t keyCode, metaState;
-        char16_t ch = chars[i];
-        if (!findKey(ch, &keyCode, &metaState)) {
-#if DEBUG_MAPPING
-            ALOGD("getEvents: deviceId=%d, chars=[%s] ~ Failed to find mapping for character %d.",
-                    deviceId, toString(chars, numChars).string(), ch);
-#endif
-            return false;
-        }
-
-        int32_t currentMetaState = 0;
-        addMetaKeys(outEvents, deviceId, metaState, true, now, &currentMetaState);
-        addKey(outEvents, deviceId, keyCode, currentMetaState, true, now);
-        addKey(outEvents, deviceId, keyCode, currentMetaState, false, now);
-        addMetaKeys(outEvents, deviceId, metaState, false, now, &currentMetaState);
-    }
-#if DEBUG_MAPPING
-    ALOGD("getEvents: deviceId=%d, chars=[%s] ~ Generated %d events.",
-            deviceId, toString(chars, numChars).string(), int32_t(outEvents.size()));
-    for (size_t i = 0; i < outEvents.size(); i++) {
-        ALOGD("  Key: keyCode=%d, metaState=0x%08x, %s.",
-                outEvents[i].getKeyCode(), outEvents[i].getMetaState(),
-                outEvents[i].getAction() == AKEY_EVENT_ACTION_DOWN ? "down" : "up");
-    }
-#endif
-    return true;
-}
-
-status_t KeyCharacterMap::mapKey(int32_t scanCode, int32_t usageCode, int32_t* outKeyCode) const {
-    if (usageCode) {
-        ssize_t index = mKeysByUsageCode.indexOfKey(usageCode);
-        if (index >= 0) {
-#if DEBUG_MAPPING
-    ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.",
-            scanCode, usageCode, *outKeyCode);
-#endif
-            *outKeyCode = mKeysByUsageCode.valueAt(index);
-            return OK;
-        }
-    }
-    if (scanCode) {
-        ssize_t index = mKeysByScanCode.indexOfKey(scanCode);
-        if (index >= 0) {
-#if DEBUG_MAPPING
-    ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.",
-            scanCode, usageCode, *outKeyCode);
-#endif
-            *outKeyCode = mKeysByScanCode.valueAt(index);
-            return OK;
-        }
-    }
-
-#if DEBUG_MAPPING
-        ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Failed.", scanCode, usageCode);
-#endif
-    *outKeyCode = AKEYCODE_UNKNOWN;
-    return NAME_NOT_FOUND;
-}
-
-bool KeyCharacterMap::getKey(int32_t keyCode, const Key** outKey) const {
-    ssize_t index = mKeys.indexOfKey(keyCode);
-    if (index >= 0) {
-        *outKey = mKeys.valueAt(index);
-        return true;
-    }
-    return false;
-}
-
-bool KeyCharacterMap::getKeyBehavior(int32_t keyCode, int32_t metaState,
-        const Key** outKey, const Behavior** outBehavior) const {
-    const Key* key;
-    if (getKey(keyCode, &key)) {
-        const Behavior* behavior = key->firstBehavior;
-        while (behavior) {
-            if (matchesMetaState(metaState, behavior->metaState)) {
-                *outKey = key;
-                *outBehavior = behavior;
-                return true;
-            }
-            behavior = behavior->next;
-        }
-    }
-    return false;
-}
-
-bool KeyCharacterMap::matchesMetaState(int32_t eventMetaState, int32_t behaviorMetaState) {
-    // Behavior must have at least the set of meta states specified.
-    // And if the key event has CTRL, ALT or META then the behavior must exactly
-    // match those, taking into account that a behavior can specify that it handles
-    // one, both or either of a left/right modifier pair.
-    if ((eventMetaState & behaviorMetaState) == behaviorMetaState) {
-        const int32_t EXACT_META_STATES =
-                AMETA_CTRL_ON | AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON
-                | AMETA_ALT_ON | AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON
-                | AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON;
-        int32_t unmatchedMetaState = eventMetaState & ~behaviorMetaState & EXACT_META_STATES;
-        if (behaviorMetaState & AMETA_CTRL_ON) {
-            unmatchedMetaState &= ~(AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON);
-        } else if (behaviorMetaState & (AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON)) {
-            unmatchedMetaState &= ~AMETA_CTRL_ON;
-        }
-        if (behaviorMetaState & AMETA_ALT_ON) {
-            unmatchedMetaState &= ~(AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON);
-        } else if (behaviorMetaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) {
-            unmatchedMetaState &= ~AMETA_ALT_ON;
-        }
-        if (behaviorMetaState & AMETA_META_ON) {
-            unmatchedMetaState &= ~(AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
-        } else if (behaviorMetaState & (AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON)) {
-            unmatchedMetaState &= ~AMETA_META_ON;
-        }
-        return !unmatchedMetaState;
-    }
-    return false;
-}
-
-bool KeyCharacterMap::findKey(char16_t ch, int32_t* outKeyCode, int32_t* outMetaState) const {
-    if (!ch) {
-        return false;
-    }
-
-    for (size_t i = 0; i < mKeys.size(); i++) {
-        const Key* key = mKeys.valueAt(i);
-
-        // Try to find the most general behavior that maps to this character.
-        // For example, the base key behavior will usually be last in the list.
-        const Behavior* found = NULL;
-        for (const Behavior* behavior = key->firstBehavior; behavior; behavior = behavior->next) {
-            if (behavior->character == ch) {
-                found = behavior;
-            }
-        }
-        if (found) {
-            *outKeyCode = mKeys.keyAt(i);
-            *outMetaState = found->metaState;
-            return true;
-        }
-    }
-    return false;
-}
-
-void KeyCharacterMap::addKey(Vector<KeyEvent>& outEvents,
-        int32_t deviceId, int32_t keyCode, int32_t metaState, bool down, nsecs_t time) {
-    outEvents.push();
-    KeyEvent& event = outEvents.editTop();
-    event.initialize(deviceId, AINPUT_SOURCE_KEYBOARD,
-            down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
-            0, keyCode, 0, metaState, 0, time, time);
-}
-
-void KeyCharacterMap::addMetaKeys(Vector<KeyEvent>& outEvents,
-        int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
-        int32_t* currentMetaState) {
-    // Add and remove meta keys symmetrically.
-    if (down) {
-        addLockedMetaKey(outEvents, deviceId, metaState, time,
-                AKEYCODE_CAPS_LOCK, AMETA_CAPS_LOCK_ON, currentMetaState);
-        addLockedMetaKey(outEvents, deviceId, metaState, time,
-                AKEYCODE_NUM_LOCK, AMETA_NUM_LOCK_ON, currentMetaState);
-        addLockedMetaKey(outEvents, deviceId, metaState, time,
-                AKEYCODE_SCROLL_LOCK, AMETA_SCROLL_LOCK_ON, currentMetaState);
-
-        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
-                AKEYCODE_SHIFT_LEFT, AMETA_SHIFT_LEFT_ON,
-                AKEYCODE_SHIFT_RIGHT, AMETA_SHIFT_RIGHT_ON,
-                AMETA_SHIFT_ON, currentMetaState);
-        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
-                AKEYCODE_ALT_LEFT, AMETA_ALT_LEFT_ON,
-                AKEYCODE_ALT_RIGHT, AMETA_ALT_RIGHT_ON,
-                AMETA_ALT_ON, currentMetaState);
-        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
-                AKEYCODE_CTRL_LEFT, AMETA_CTRL_LEFT_ON,
-                AKEYCODE_CTRL_RIGHT, AMETA_CTRL_RIGHT_ON,
-                AMETA_CTRL_ON, currentMetaState);
-        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
-                AKEYCODE_META_LEFT, AMETA_META_LEFT_ON,
-                AKEYCODE_META_RIGHT, AMETA_META_RIGHT_ON,
-                AMETA_META_ON, currentMetaState);
-
-        addSingleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
-                AKEYCODE_SYM, AMETA_SYM_ON, currentMetaState);
-        addSingleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
-                AKEYCODE_FUNCTION, AMETA_FUNCTION_ON, currentMetaState);
-    } else {
-        addSingleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
-                AKEYCODE_FUNCTION, AMETA_FUNCTION_ON, currentMetaState);
-        addSingleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
-                AKEYCODE_SYM, AMETA_SYM_ON, currentMetaState);
-
-        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
-                AKEYCODE_META_LEFT, AMETA_META_LEFT_ON,
-                AKEYCODE_META_RIGHT, AMETA_META_RIGHT_ON,
-                AMETA_META_ON, currentMetaState);
-        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
-                AKEYCODE_CTRL_LEFT, AMETA_CTRL_LEFT_ON,
-                AKEYCODE_CTRL_RIGHT, AMETA_CTRL_RIGHT_ON,
-                AMETA_CTRL_ON, currentMetaState);
-        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
-                AKEYCODE_ALT_LEFT, AMETA_ALT_LEFT_ON,
-                AKEYCODE_ALT_RIGHT, AMETA_ALT_RIGHT_ON,
-                AMETA_ALT_ON, currentMetaState);
-        addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
-                AKEYCODE_SHIFT_LEFT, AMETA_SHIFT_LEFT_ON,
-                AKEYCODE_SHIFT_RIGHT, AMETA_SHIFT_RIGHT_ON,
-                AMETA_SHIFT_ON, currentMetaState);
-
-        addLockedMetaKey(outEvents, deviceId, metaState, time,
-                AKEYCODE_SCROLL_LOCK, AMETA_SCROLL_LOCK_ON, currentMetaState);
-        addLockedMetaKey(outEvents, deviceId, metaState, time,
-                AKEYCODE_NUM_LOCK, AMETA_NUM_LOCK_ON, currentMetaState);
-        addLockedMetaKey(outEvents, deviceId, metaState, time,
-                AKEYCODE_CAPS_LOCK, AMETA_CAPS_LOCK_ON, currentMetaState);
-    }
-}
-
-bool KeyCharacterMap::addSingleEphemeralMetaKey(Vector<KeyEvent>& outEvents,
-        int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
-        int32_t keyCode, int32_t keyMetaState,
-        int32_t* currentMetaState) {
-    if ((metaState & keyMetaState) == keyMetaState) {
-        *currentMetaState = updateMetaState(keyCode, down, *currentMetaState);
-        addKey(outEvents, deviceId, keyCode, *currentMetaState, down, time);
-        return true;
-    }
-    return false;
-}
-
-void KeyCharacterMap::addDoubleEphemeralMetaKey(Vector<KeyEvent>& outEvents,
-        int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
-        int32_t leftKeyCode, int32_t leftKeyMetaState,
-        int32_t rightKeyCode, int32_t rightKeyMetaState,
-        int32_t eitherKeyMetaState,
-        int32_t* currentMetaState) {
-    bool specific = false;
-    specific |= addSingleEphemeralMetaKey(outEvents, deviceId, metaState, down, time,
-            leftKeyCode, leftKeyMetaState, currentMetaState);
-    specific |= addSingleEphemeralMetaKey(outEvents, deviceId, metaState, down, time,
-            rightKeyCode, rightKeyMetaState, currentMetaState);
-
-    if (!specific) {
-        addSingleEphemeralMetaKey(outEvents, deviceId, metaState, down, time,
-                leftKeyCode, eitherKeyMetaState, currentMetaState);
-    }
-}
-
-void KeyCharacterMap::addLockedMetaKey(Vector<KeyEvent>& outEvents,
-        int32_t deviceId, int32_t metaState, nsecs_t time,
-        int32_t keyCode, int32_t keyMetaState,
-        int32_t* currentMetaState) {
-    if ((metaState & keyMetaState) == keyMetaState) {
-        *currentMetaState = updateMetaState(keyCode, true, *currentMetaState);
-        addKey(outEvents, deviceId, keyCode, *currentMetaState, true, time);
-        *currentMetaState = updateMetaState(keyCode, false, *currentMetaState);
-        addKey(outEvents, deviceId, keyCode, *currentMetaState, false, time);
-    }
-}
-
-#if HAVE_ANDROID_OS
-sp<KeyCharacterMap> KeyCharacterMap::readFromParcel(Parcel* parcel) {
-    sp<KeyCharacterMap> map = new KeyCharacterMap();
-    map->mType = parcel->readInt32();
-    size_t numKeys = parcel->readInt32();
-    if (parcel->errorCheck()) {
-        return NULL;
-    }
-
-    for (size_t i = 0; i < numKeys; i++) {
-        int32_t keyCode = parcel->readInt32();
-        char16_t label = parcel->readInt32();
-        char16_t number = parcel->readInt32();
-        if (parcel->errorCheck()) {
-            return NULL;
-        }
-
-        Key* key = new Key();
-        key->label = label;
-        key->number = number;
-        map->mKeys.add(keyCode, key);
-
-        Behavior* lastBehavior = NULL;
-        while (parcel->readInt32()) {
-            int32_t metaState = parcel->readInt32();
-            char16_t character = parcel->readInt32();
-            int32_t fallbackKeyCode = parcel->readInt32();
-            if (parcel->errorCheck()) {
-                return NULL;
-            }
-
-            Behavior* behavior = new Behavior();
-            behavior->metaState = metaState;
-            behavior->character = character;
-            behavior->fallbackKeyCode = fallbackKeyCode;
-            if (lastBehavior) {
-                lastBehavior->next = behavior;
-            } else {
-                key->firstBehavior = behavior;
-            }
-            lastBehavior = behavior;
-        }
-
-        if (parcel->errorCheck()) {
-            return NULL;
-        }
-    }
-    return map;
-}
-
-void KeyCharacterMap::writeToParcel(Parcel* parcel) const {
-    parcel->writeInt32(mType);
-
-    size_t numKeys = mKeys.size();
-    parcel->writeInt32(numKeys);
-    for (size_t i = 0; i < numKeys; i++) {
-        int32_t keyCode = mKeys.keyAt(i);
-        const Key* key = mKeys.valueAt(i);
-        parcel->writeInt32(keyCode);
-        parcel->writeInt32(key->label);
-        parcel->writeInt32(key->number);
-        for (const Behavior* behavior = key->firstBehavior; behavior != NULL;
-                behavior = behavior->next) {
-            parcel->writeInt32(1);
-            parcel->writeInt32(behavior->metaState);
-            parcel->writeInt32(behavior->character);
-            parcel->writeInt32(behavior->fallbackKeyCode);
-        }
-        parcel->writeInt32(0);
-    }
-}
-#endif
-
-
-// --- KeyCharacterMap::Key ---
-
-KeyCharacterMap::Key::Key() :
-        label(0), number(0), firstBehavior(NULL) {
-}
-
-KeyCharacterMap::Key::Key(const Key& other) :
-        label(other.label), number(other.number),
-        firstBehavior(other.firstBehavior ? new Behavior(*other.firstBehavior) : NULL) {
-}
-
-KeyCharacterMap::Key::~Key() {
-    Behavior* behavior = firstBehavior;
-    while (behavior) {
-        Behavior* next = behavior->next;
-        delete behavior;
-        behavior = next;
-    }
-}
-
-
-// --- KeyCharacterMap::Behavior ---
-
-KeyCharacterMap::Behavior::Behavior() :
-        next(NULL), metaState(0), character(0), fallbackKeyCode(0) {
-}
-
-KeyCharacterMap::Behavior::Behavior(const Behavior& other) :
-        next(other.next ? new Behavior(*other.next) : NULL),
-        metaState(other.metaState), character(other.character),
-        fallbackKeyCode(other.fallbackKeyCode) {
-}
-
-
-// --- KeyCharacterMap::Parser ---
-
-KeyCharacterMap::Parser::Parser(KeyCharacterMap* map, Tokenizer* tokenizer, Format format) :
-        mMap(map), mTokenizer(tokenizer), mFormat(format), mState(STATE_TOP) {
-}
-
-KeyCharacterMap::Parser::~Parser() {
-}
-
-status_t KeyCharacterMap::Parser::parse() {
-    while (!mTokenizer->isEof()) {
-#if DEBUG_PARSER
-        ALOGD("Parsing %s: '%s'.", mTokenizer->getLocation().string(),
-                mTokenizer->peekRemainderOfLine().string());
-#endif
-
-        mTokenizer->skipDelimiters(WHITESPACE);
-
-        if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
-            switch (mState) {
-            case STATE_TOP: {
-                String8 keywordToken = mTokenizer->nextToken(WHITESPACE);
-                if (keywordToken == "type") {
-                    mTokenizer->skipDelimiters(WHITESPACE);
-                    status_t status = parseType();
-                    if (status) return status;
-                } else if (keywordToken == "map") {
-                    mTokenizer->skipDelimiters(WHITESPACE);
-                    status_t status = parseMap();
-                    if (status) return status;
-                } else if (keywordToken == "key") {
-                    mTokenizer->skipDelimiters(WHITESPACE);
-                    status_t status = parseKey();
-                    if (status) return status;
-                } else {
-                    ALOGE("%s: Expected keyword, got '%s'.", mTokenizer->getLocation().string(),
-                            keywordToken.string());
-                    return BAD_VALUE;
-                }
-                break;
-            }
-
-            case STATE_KEY: {
-                status_t status = parseKeyProperty();
-                if (status) return status;
-                break;
-            }
-            }
-
-            mTokenizer->skipDelimiters(WHITESPACE);
-            if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
-                ALOGE("%s: Expected end of line or trailing comment, got '%s'.",
-                        mTokenizer->getLocation().string(),
-                        mTokenizer->peekRemainderOfLine().string());
-                return BAD_VALUE;
-            }
-        }
-
-        mTokenizer->nextLine();
-    }
-
-    if (mState != STATE_TOP) {
-        ALOGE("%s: Unterminated key description at end of file.",
-                mTokenizer->getLocation().string());
-        return BAD_VALUE;
-    }
-
-    if (mMap->mType == KEYBOARD_TYPE_UNKNOWN) {
-        ALOGE("%s: Keyboard layout missing required keyboard 'type' declaration.",
-                mTokenizer->getLocation().string());
-        return BAD_VALUE;
-    }
-
-    if (mFormat == FORMAT_BASE) {
-        if (mMap->mType == KEYBOARD_TYPE_OVERLAY) {
-            ALOGE("%s: Base keyboard layout must specify a keyboard 'type' other than 'OVERLAY'.",
-                    mTokenizer->getLocation().string());
-            return BAD_VALUE;
-        }
-    } else if (mFormat == FORMAT_OVERLAY) {
-        if (mMap->mType != KEYBOARD_TYPE_OVERLAY) {
-            ALOGE("%s: Overlay keyboard layout missing required keyboard "
-                    "'type OVERLAY' declaration.",
-                    mTokenizer->getLocation().string());
-            return BAD_VALUE;
-        }
-    }
-
-    return NO_ERROR;
-}
-
-status_t KeyCharacterMap::Parser::parseType() {
-    if (mMap->mType != KEYBOARD_TYPE_UNKNOWN) {
-        ALOGE("%s: Duplicate keyboard 'type' declaration.",
-                mTokenizer->getLocation().string());
-        return BAD_VALUE;
-    }
-
-    KeyboardType type;
-    String8 typeToken = mTokenizer->nextToken(WHITESPACE);
-    if (typeToken == "NUMERIC") {
-        type = KEYBOARD_TYPE_NUMERIC;
-    } else if (typeToken == "PREDICTIVE") {
-        type = KEYBOARD_TYPE_PREDICTIVE;
-    } else if (typeToken == "ALPHA") {
-        type = KEYBOARD_TYPE_ALPHA;
-    } else if (typeToken == "FULL") {
-        type = KEYBOARD_TYPE_FULL;
-    } else if (typeToken == "SPECIAL_FUNCTION") {
-        type = KEYBOARD_TYPE_SPECIAL_FUNCTION;
-    } else if (typeToken == "OVERLAY") {
-        type = KEYBOARD_TYPE_OVERLAY;
-    } else {
-        ALOGE("%s: Expected keyboard type label, got '%s'.", mTokenizer->getLocation().string(),
-                typeToken.string());
-        return BAD_VALUE;
-    }
-
-#if DEBUG_PARSER
-    ALOGD("Parsed type: type=%d.", type);
-#endif
-    mMap->mType = type;
-    return NO_ERROR;
-}
-
-status_t KeyCharacterMap::Parser::parseMap() {
-    String8 keywordToken = mTokenizer->nextToken(WHITESPACE);
-    if (keywordToken == "key") {
-        mTokenizer->skipDelimiters(WHITESPACE);
-        return parseMapKey();
-    }
-    ALOGE("%s: Expected keyword after 'map', got '%s'.", mTokenizer->getLocation().string(),
-            keywordToken.string());
-    return BAD_VALUE;
-}
-
-status_t KeyCharacterMap::Parser::parseMapKey() {
-    String8 codeToken = mTokenizer->nextToken(WHITESPACE);
-    bool mapUsage = false;
-    if (codeToken == "usage") {
-        mapUsage = true;
-        mTokenizer->skipDelimiters(WHITESPACE);
-        codeToken = mTokenizer->nextToken(WHITESPACE);
-    }
-
-    char* end;
-    int32_t code = int32_t(strtol(codeToken.string(), &end, 0));
-    if (*end) {
-        ALOGE("%s: Expected key %s number, got '%s'.", mTokenizer->getLocation().string(),
-                mapUsage ? "usage" : "scan code", codeToken.string());
-        return BAD_VALUE;
-    }
-    KeyedVector<int32_t, int32_t>& map =
-            mapUsage ? mMap->mKeysByUsageCode : mMap->mKeysByScanCode;
-    if (map.indexOfKey(code) >= 0) {
-        ALOGE("%s: Duplicate entry for key %s '%s'.", mTokenizer->getLocation().string(),
-                mapUsage ? "usage" : "scan code", codeToken.string());
-        return BAD_VALUE;
-    }
-
-    mTokenizer->skipDelimiters(WHITESPACE);
-    String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE);
-    int32_t keyCode = getKeyCodeByLabel(keyCodeToken.string());
-    if (!keyCode) {
-        ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(),
-                keyCodeToken.string());
-        return BAD_VALUE;
-    }
-
-#if DEBUG_PARSER
-    ALOGD("Parsed map key %s: code=%d, keyCode=%d.",
-            mapUsage ? "usage" : "scan code", code, keyCode);
-#endif
-    map.add(code, keyCode);
-    return NO_ERROR;
-}
-
-status_t KeyCharacterMap::Parser::parseKey() {
-    String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE);
-    int32_t keyCode = getKeyCodeByLabel(keyCodeToken.string());
-    if (!keyCode) {
-        ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(),
-                keyCodeToken.string());
-        return BAD_VALUE;
-    }
-    if (mMap->mKeys.indexOfKey(keyCode) >= 0) {
-        ALOGE("%s: Duplicate entry for key code '%s'.", mTokenizer->getLocation().string(),
-                keyCodeToken.string());
-        return BAD_VALUE;
-    }
-
-    mTokenizer->skipDelimiters(WHITESPACE);
-    String8 openBraceToken = mTokenizer->nextToken(WHITESPACE);
-    if (openBraceToken != "{") {
-        ALOGE("%s: Expected '{' after key code label, got '%s'.",
-                mTokenizer->getLocation().string(), openBraceToken.string());
-        return BAD_VALUE;
-    }
-
-#if DEBUG_PARSER
-    ALOGD("Parsed beginning of key: keyCode=%d.", keyCode);
-#endif
-    mKeyCode = keyCode;
-    mMap->mKeys.add(keyCode, new Key());
-    mState = STATE_KEY;
-    return NO_ERROR;
-}
-
-status_t KeyCharacterMap::Parser::parseKeyProperty() {
-    Key* key = mMap->mKeys.valueFor(mKeyCode);
-    String8 token = mTokenizer->nextToken(WHITESPACE_OR_PROPERTY_DELIMITER);
-    if (token == "}") {
-        mState = STATE_TOP;
-        return finishKey(key);
-    }
-
-    Vector<Property> properties;
-
-    // Parse all comma-delimited property names up to the first colon.
-    for (;;) {
-        if (token == "label") {
-            properties.add(Property(PROPERTY_LABEL));
-        } else if (token == "number") {
-            properties.add(Property(PROPERTY_NUMBER));
-        } else {
-            int32_t metaState;
-            status_t status = parseModifier(token, &metaState);
-            if (status) {
-                ALOGE("%s: Expected a property name or modifier, got '%s'.",
-                        mTokenizer->getLocation().string(), token.string());
-                return status;
-            }
-            properties.add(Property(PROPERTY_META, metaState));
-        }
-
-        mTokenizer->skipDelimiters(WHITESPACE);
-        if (!mTokenizer->isEol()) {
-            char ch = mTokenizer->nextChar();
-            if (ch == ':') {
-                break;
-            } else if (ch == ',') {
-                mTokenizer->skipDelimiters(WHITESPACE);
-                token = mTokenizer->nextToken(WHITESPACE_OR_PROPERTY_DELIMITER);
-                continue;
-            }
-        }
-
-        ALOGE("%s: Expected ',' or ':' after property name.",
-                mTokenizer->getLocation().string());
-        return BAD_VALUE;
-    }
-
-    // Parse behavior after the colon.
-    mTokenizer->skipDelimiters(WHITESPACE);
-
-    Behavior behavior;
-    bool haveCharacter = false;
-    bool haveFallback = false;
-
-    do {
-        char ch = mTokenizer->peekChar();
-        if (ch == '\'') {
-            char16_t character;
-            status_t status = parseCharacterLiteral(&character);
-            if (status || !character) {
-                ALOGE("%s: Invalid character literal for key.",
-                        mTokenizer->getLocation().string());
-                return BAD_VALUE;
-            }
-            if (haveCharacter) {
-                ALOGE("%s: Cannot combine multiple character literals or 'none'.",
-                        mTokenizer->getLocation().string());
-                return BAD_VALUE;
-            }
-            behavior.character = character;
-            haveCharacter = true;
-        } else {
-            token = mTokenizer->nextToken(WHITESPACE);
-            if (token == "none") {
-                if (haveCharacter) {
-                    ALOGE("%s: Cannot combine multiple character literals or 'none'.",
-                            mTokenizer->getLocation().string());
-                    return BAD_VALUE;
-                }
-                haveCharacter = true;
-            } else if (token == "fallback") {
-                mTokenizer->skipDelimiters(WHITESPACE);
-                token = mTokenizer->nextToken(WHITESPACE);
-                int32_t keyCode = getKeyCodeByLabel(token.string());
-                if (!keyCode) {
-                    ALOGE("%s: Invalid key code label for fallback behavior, got '%s'.",
-                            mTokenizer->getLocation().string(),
-                            token.string());
-                    return BAD_VALUE;
-                }
-                if (haveFallback) {
-                    ALOGE("%s: Cannot combine multiple fallback key codes.",
-                            mTokenizer->getLocation().string());
-                    return BAD_VALUE;
-                }
-                behavior.fallbackKeyCode = keyCode;
-                haveFallback = true;
-            } else {
-                ALOGE("%s: Expected a key behavior after ':'.",
-                        mTokenizer->getLocation().string());
-                return BAD_VALUE;
-            }
-        }
-
-        mTokenizer->skipDelimiters(WHITESPACE);
-    } while (!mTokenizer->isEol() && mTokenizer->peekChar() != '#');
-
-    // Add the behavior.
-    for (size_t i = 0; i < properties.size(); i++) {
-        const Property& property = properties.itemAt(i);
-        switch (property.property) {
-        case PROPERTY_LABEL:
-            if (key->label) {
-                ALOGE("%s: Duplicate label for key.",
-                        mTokenizer->getLocation().string());
-                return BAD_VALUE;
-            }
-            key->label = behavior.character;
-#if DEBUG_PARSER
-            ALOGD("Parsed key label: keyCode=%d, label=%d.", mKeyCode, key->label);
-#endif
-            break;
-        case PROPERTY_NUMBER:
-            if (key->number) {
-                ALOGE("%s: Duplicate number for key.",
-                        mTokenizer->getLocation().string());
-                return BAD_VALUE;
-            }
-            key->number = behavior.character;
-#if DEBUG_PARSER
-            ALOGD("Parsed key number: keyCode=%d, number=%d.", mKeyCode, key->number);
-#endif
-            break;
-        case PROPERTY_META: {
-            for (Behavior* b = key->firstBehavior; b; b = b->next) {
-                if (b->metaState == property.metaState) {
-                    ALOGE("%s: Duplicate key behavior for modifier.",
-                            mTokenizer->getLocation().string());
-                    return BAD_VALUE;
-                }
-            }
-            Behavior* newBehavior = new Behavior(behavior);
-            newBehavior->metaState = property.metaState;
-            newBehavior->next = key->firstBehavior;
-            key->firstBehavior = newBehavior;
-#if DEBUG_PARSER
-            ALOGD("Parsed key meta: keyCode=%d, meta=0x%x, char=%d, fallback=%d.", mKeyCode,
-                    newBehavior->metaState, newBehavior->character, newBehavior->fallbackKeyCode);
-#endif
-            break;
-        }
-        }
-    }
-    return NO_ERROR;
-}
-
-status_t KeyCharacterMap::Parser::finishKey(Key* key) {
-    // Fill in default number property.
-    if (!key->number) {
-        char16_t digit = 0;
-        char16_t symbol = 0;
-        for (Behavior* b = key->firstBehavior; b; b = b->next) {
-            char16_t ch = b->character;
-            if (ch) {
-                if (ch >= '0' && ch <= '9') {
-                    digit = ch;
-                } else if (ch == '(' || ch == ')' || ch == '#' || ch == '*'
-                        || ch == '-' || ch == '+' || ch == ',' || ch == '.'
-                        || ch == '\'' || ch == ':' || ch == ';' || ch == '/') {
-                    symbol = ch;
-                }
-            }
-        }
-        key->number = digit ? digit : symbol;
-    }
-    return NO_ERROR;
-}
-
-status_t KeyCharacterMap::Parser::parseModifier(const String8& token, int32_t* outMetaState) {
-    if (token == "base") {
-        *outMetaState = 0;
-        return NO_ERROR;
-    }
-
-    int32_t combinedMeta = 0;
-
-    const char* str = token.string();
-    const char* start = str;
-    for (const char* cur = str; ; cur++) {
-        char ch = *cur;
-        if (ch == '+' || ch == '\0') {
-            size_t len = cur - start;
-            int32_t metaState = 0;
-            for (size_t i = 0; i < sizeof(modifiers) / sizeof(Modifier); i++) {
-                if (strlen(modifiers[i].label) == len
-                        && strncmp(modifiers[i].label, start, len) == 0) {
-                    metaState = modifiers[i].metaState;
-                    break;
-                }
-            }
-            if (!metaState) {
-                return BAD_VALUE;
-            }
-            if (combinedMeta & metaState) {
-                ALOGE("%s: Duplicate modifier combination '%s'.",
-                        mTokenizer->getLocation().string(), token.string());
-                return BAD_VALUE;
-            }
-
-            combinedMeta |= metaState;
-            start = cur + 1;
-
-            if (ch == '\0') {
-                break;
-            }
-        }
-    }
-    *outMetaState = combinedMeta;
-    return NO_ERROR;
-}
-
-status_t KeyCharacterMap::Parser::parseCharacterLiteral(char16_t* outCharacter) {
-    char ch = mTokenizer->nextChar();
-    if (ch != '\'') {
-        goto Error;
-    }
-
-    ch = mTokenizer->nextChar();
-    if (ch == '\\') {
-        // Escape sequence.
-        ch = mTokenizer->nextChar();
-        if (ch == 'n') {
-            *outCharacter = '\n';
-        } else if (ch == 't') {
-            *outCharacter = '\t';
-        } else if (ch == '\\') {
-            *outCharacter = '\\';
-        } else if (ch == '\'') {
-            *outCharacter = '\'';
-        } else if (ch == '"') {
-            *outCharacter = '"';
-        } else if (ch == 'u') {
-            *outCharacter = 0;
-            for (int i = 0; i < 4; i++) {
-                ch = mTokenizer->nextChar();
-                int digit;
-                if (ch >= '0' && ch <= '9') {
-                    digit = ch - '0';
-                } else if (ch >= 'A' && ch <= 'F') {
-                    digit = ch - 'A' + 10;
-                } else if (ch >= 'a' && ch <= 'f') {
-                    digit = ch - 'a' + 10;
-                } else {
-                    goto Error;
-                }
-                *outCharacter = (*outCharacter << 4) | digit;
-            }
-        } else {
-            goto Error;
-        }
-    } else if (ch >= 32 && ch <= 126 && ch != '\'') {
-        // ASCII literal character.
-        *outCharacter = ch;
-    } else {
-        goto Error;
-    }
-
-    ch = mTokenizer->nextChar();
-    if (ch != '\'') {
-        goto Error;
-    }
-
-    // Ensure that we consumed the entire token.
-    if (mTokenizer->nextToken(WHITESPACE).isEmpty()) {
-        return NO_ERROR;
-    }
-
-Error:
-    ALOGE("%s: Malformed character literal.", mTokenizer->getLocation().string());
-    return BAD_VALUE;
-}
-
-} // namespace android
diff --git a/libs/androidfw/KeyLayoutMap.cpp b/libs/androidfw/KeyLayoutMap.cpp
deleted file mode 100644
index ae14f23..0000000
--- a/libs/androidfw/KeyLayoutMap.cpp
+++ /dev/null
@@ -1,366 +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.
- */
-
-#define LOG_TAG "KeyLayoutMap"
-
-#include <stdlib.h>
-#include <android/keycodes.h>
-#include <androidfw/Keyboard.h>
-#include <androidfw/KeyLayoutMap.h>
-#include <utils/Log.h>
-#include <utils/Errors.h>
-#include <utils/Tokenizer.h>
-#include <utils/Timers.h>
-
-// Enables debug output for the parser.
-#define DEBUG_PARSER 0
-
-// Enables debug output for parser performance.
-#define DEBUG_PARSER_PERFORMANCE 0
-
-// Enables debug output for mapping.
-#define DEBUG_MAPPING 0
-
-
-namespace android {
-
-static const char* WHITESPACE = " \t\r";
-
-// --- KeyLayoutMap ---
-
-KeyLayoutMap::KeyLayoutMap() {
-}
-
-KeyLayoutMap::~KeyLayoutMap() {
-}
-
-status_t KeyLayoutMap::load(const String8& filename, sp<KeyLayoutMap>* outMap) {
-    outMap->clear();
-
-    Tokenizer* tokenizer;
-    status_t status = Tokenizer::open(filename, &tokenizer);
-    if (status) {
-        ALOGE("Error %d opening key layout map file %s.", status, filename.string());
-    } else {
-        sp<KeyLayoutMap> map = new KeyLayoutMap();
-        if (!map.get()) {
-            ALOGE("Error allocating key layout map.");
-            status = NO_MEMORY;
-        } else {
-#if DEBUG_PARSER_PERFORMANCE
-            nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
-#endif
-            Parser parser(map.get(), tokenizer);
-            status = parser.parse();
-#if DEBUG_PARSER_PERFORMANCE
-            nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
-            ALOGD("Parsed key layout map file '%s' %d lines in %0.3fms.",
-                    tokenizer->getFilename().string(), tokenizer->getLineNumber(),
-                    elapsedTime / 1000000.0);
-#endif
-            if (!status) {
-                *outMap = map;
-            }
-        }
-        delete tokenizer;
-    }
-    return status;
-}
-
-status_t KeyLayoutMap::mapKey(int32_t scanCode, int32_t usageCode,
-        int32_t* outKeyCode, uint32_t* outFlags) const {
-    const Key* key = getKey(scanCode, usageCode);
-    if (!key) {
-#if DEBUG_MAPPING
-        ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Failed.", scanCode, usageCode);
-#endif
-        *outKeyCode = AKEYCODE_UNKNOWN;
-        *outFlags = 0;
-        return NAME_NOT_FOUND;
-    }
-
-    *outKeyCode = key->keyCode;
-    *outFlags = key->flags;
-
-#if DEBUG_MAPPING
-    ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d, outFlags=0x%08x.",
-            scanCode, usageCode, *outKeyCode, *outFlags);
-#endif
-    return NO_ERROR;
-}
-
-const KeyLayoutMap::Key* KeyLayoutMap::getKey(int32_t scanCode, int32_t usageCode) const {
-    if (usageCode) {
-        ssize_t index = mKeysByUsageCode.indexOfKey(usageCode);
-        if (index >= 0) {
-            return &mKeysByUsageCode.valueAt(index);
-        }
-    }
-    if (scanCode) {
-        ssize_t index = mKeysByScanCode.indexOfKey(scanCode);
-        if (index >= 0) {
-            return &mKeysByScanCode.valueAt(index);
-        }
-    }
-    return NULL;
-}
-
-status_t KeyLayoutMap::findScanCodesForKey(int32_t keyCode, Vector<int32_t>* outScanCodes) const {
-    const size_t N = mKeysByScanCode.size();
-    for (size_t i=0; i<N; i++) {
-        if (mKeysByScanCode.valueAt(i).keyCode == keyCode) {
-            outScanCodes->add(mKeysByScanCode.keyAt(i));
-        }
-    }
-    return NO_ERROR;
-}
-
-status_t KeyLayoutMap::mapAxis(int32_t scanCode, AxisInfo* outAxisInfo) const {
-    ssize_t index = mAxes.indexOfKey(scanCode);
-    if (index < 0) {
-#if DEBUG_MAPPING
-        ALOGD("mapAxis: scanCode=%d ~ Failed.", scanCode);
-#endif
-        return NAME_NOT_FOUND;
-    }
-
-    *outAxisInfo = mAxes.valueAt(index);
-
-#if DEBUG_MAPPING
-    ALOGD("mapAxis: scanCode=%d ~ Result mode=%d, axis=%d, highAxis=%d, "
-            "splitValue=%d, flatOverride=%d.",
-            scanCode,
-            outAxisInfo->mode, outAxisInfo->axis, outAxisInfo->highAxis,
-            outAxisInfo->splitValue, outAxisInfo->flatOverride);
-#endif
-    return NO_ERROR;
-}
-
-
-// --- KeyLayoutMap::Parser ---
-
-KeyLayoutMap::Parser::Parser(KeyLayoutMap* map, Tokenizer* tokenizer) :
-        mMap(map), mTokenizer(tokenizer) {
-}
-
-KeyLayoutMap::Parser::~Parser() {
-}
-
-status_t KeyLayoutMap::Parser::parse() {
-    while (!mTokenizer->isEof()) {
-#if DEBUG_PARSER
-        ALOGD("Parsing %s: '%s'.", mTokenizer->getLocation().string(),
-                mTokenizer->peekRemainderOfLine().string());
-#endif
-
-        mTokenizer->skipDelimiters(WHITESPACE);
-
-        if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
-            String8 keywordToken = mTokenizer->nextToken(WHITESPACE);
-            if (keywordToken == "key") {
-                mTokenizer->skipDelimiters(WHITESPACE);
-                status_t status = parseKey();
-                if (status) return status;
-            } else if (keywordToken == "axis") {
-                mTokenizer->skipDelimiters(WHITESPACE);
-                status_t status = parseAxis();
-                if (status) return status;
-            } else {
-                ALOGE("%s: Expected keyword, got '%s'.", mTokenizer->getLocation().string(),
-                        keywordToken.string());
-                return BAD_VALUE;
-            }
-
-            mTokenizer->skipDelimiters(WHITESPACE);
-            if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
-                ALOGE("%s: Expected end of line or trailing comment, got '%s'.",
-                        mTokenizer->getLocation().string(),
-                        mTokenizer->peekRemainderOfLine().string());
-                return BAD_VALUE;
-            }
-        }
-
-        mTokenizer->nextLine();
-    }
-    return NO_ERROR;
-}
-
-status_t KeyLayoutMap::Parser::parseKey() {
-    String8 codeToken = mTokenizer->nextToken(WHITESPACE);
-    bool mapUsage = false;
-    if (codeToken == "usage") {
-        mapUsage = true;
-        mTokenizer->skipDelimiters(WHITESPACE);
-        codeToken = mTokenizer->nextToken(WHITESPACE);
-    }
-
-    char* end;
-    int32_t code = int32_t(strtol(codeToken.string(), &end, 0));
-    if (*end) {
-        ALOGE("%s: Expected key %s number, got '%s'.", mTokenizer->getLocation().string(),
-                mapUsage ? "usage" : "scan code", codeToken.string());
-        return BAD_VALUE;
-    }
-    KeyedVector<int32_t, Key>& map =
-            mapUsage ? mMap->mKeysByUsageCode : mMap->mKeysByScanCode;
-    if (map.indexOfKey(code) >= 0) {
-        ALOGE("%s: Duplicate entry for key %s '%s'.", mTokenizer->getLocation().string(),
-                mapUsage ? "usage" : "scan code", codeToken.string());
-        return BAD_VALUE;
-    }
-
-    mTokenizer->skipDelimiters(WHITESPACE);
-    String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE);
-    int32_t keyCode = getKeyCodeByLabel(keyCodeToken.string());
-    if (!keyCode) {
-        ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(),
-                keyCodeToken.string());
-        return BAD_VALUE;
-    }
-
-    uint32_t flags = 0;
-    for (;;) {
-        mTokenizer->skipDelimiters(WHITESPACE);
-        if (mTokenizer->isEol() || mTokenizer->peekChar() == '#') break;
-
-        String8 flagToken = mTokenizer->nextToken(WHITESPACE);
-        uint32_t flag = getKeyFlagByLabel(flagToken.string());
-        if (!flag) {
-            ALOGE("%s: Expected key flag label, got '%s'.", mTokenizer->getLocation().string(),
-                    flagToken.string());
-            return BAD_VALUE;
-        }
-        if (flags & flag) {
-            ALOGE("%s: Duplicate key flag '%s'.", mTokenizer->getLocation().string(),
-                    flagToken.string());
-            return BAD_VALUE;
-        }
-        flags |= flag;
-    }
-
-#if DEBUG_PARSER
-    ALOGD("Parsed key %s: code=%d, keyCode=%d, flags=0x%08x.",
-            mapUsage ? "usage" : "scan code", code, keyCode, flags);
-#endif
-    Key key;
-    key.keyCode = keyCode;
-    key.flags = flags;
-    map.add(code, key);
-    return NO_ERROR;
-}
-
-status_t KeyLayoutMap::Parser::parseAxis() {
-    String8 scanCodeToken = mTokenizer->nextToken(WHITESPACE);
-    char* end;
-    int32_t scanCode = int32_t(strtol(scanCodeToken.string(), &end, 0));
-    if (*end) {
-        ALOGE("%s: Expected axis scan code number, got '%s'.", mTokenizer->getLocation().string(),
-                scanCodeToken.string());
-        return BAD_VALUE;
-    }
-    if (mMap->mAxes.indexOfKey(scanCode) >= 0) {
-        ALOGE("%s: Duplicate entry for axis scan code '%s'.", mTokenizer->getLocation().string(),
-                scanCodeToken.string());
-        return BAD_VALUE;
-    }
-
-    AxisInfo axisInfo;
-
-    mTokenizer->skipDelimiters(WHITESPACE);
-    String8 token = mTokenizer->nextToken(WHITESPACE);
-    if (token == "invert") {
-        axisInfo.mode = AxisInfo::MODE_INVERT;
-
-        mTokenizer->skipDelimiters(WHITESPACE);
-        String8 axisToken = mTokenizer->nextToken(WHITESPACE);
-        axisInfo.axis = getAxisByLabel(axisToken.string());
-        if (axisInfo.axis < 0) {
-            ALOGE("%s: Expected inverted axis label, got '%s'.",
-                    mTokenizer->getLocation().string(), axisToken.string());
-            return BAD_VALUE;
-        }
-    } else if (token == "split") {
-        axisInfo.mode = AxisInfo::MODE_SPLIT;
-
-        mTokenizer->skipDelimiters(WHITESPACE);
-        String8 splitToken = mTokenizer->nextToken(WHITESPACE);
-        axisInfo.splitValue = int32_t(strtol(splitToken.string(), &end, 0));
-        if (*end) {
-            ALOGE("%s: Expected split value, got '%s'.",
-                    mTokenizer->getLocation().string(), splitToken.string());
-            return BAD_VALUE;
-        }
-
-        mTokenizer->skipDelimiters(WHITESPACE);
-        String8 lowAxisToken = mTokenizer->nextToken(WHITESPACE);
-        axisInfo.axis = getAxisByLabel(lowAxisToken.string());
-        if (axisInfo.axis < 0) {
-            ALOGE("%s: Expected low axis label, got '%s'.",
-                    mTokenizer->getLocation().string(), lowAxisToken.string());
-            return BAD_VALUE;
-        }
-
-        mTokenizer->skipDelimiters(WHITESPACE);
-        String8 highAxisToken = mTokenizer->nextToken(WHITESPACE);
-        axisInfo.highAxis = getAxisByLabel(highAxisToken.string());
-        if (axisInfo.highAxis < 0) {
-            ALOGE("%s: Expected high axis label, got '%s'.",
-                    mTokenizer->getLocation().string(), highAxisToken.string());
-            return BAD_VALUE;
-        }
-    } else {
-        axisInfo.axis = getAxisByLabel(token.string());
-        if (axisInfo.axis < 0) {
-            ALOGE("%s: Expected axis label, 'split' or 'invert', got '%s'.",
-                    mTokenizer->getLocation().string(), token.string());
-            return BAD_VALUE;
-        }
-    }
-
-    for (;;) {
-        mTokenizer->skipDelimiters(WHITESPACE);
-        if (mTokenizer->isEol() || mTokenizer->peekChar() == '#') {
-            break;
-        }
-        String8 keywordToken = mTokenizer->nextToken(WHITESPACE);
-        if (keywordToken == "flat") {
-            mTokenizer->skipDelimiters(WHITESPACE);
-            String8 flatToken = mTokenizer->nextToken(WHITESPACE);
-            axisInfo.flatOverride = int32_t(strtol(flatToken.string(), &end, 0));
-            if (*end) {
-                ALOGE("%s: Expected flat value, got '%s'.",
-                        mTokenizer->getLocation().string(), flatToken.string());
-                return BAD_VALUE;
-            }
-        } else {
-            ALOGE("%s: Expected keyword 'flat', got '%s'.",
-                    mTokenizer->getLocation().string(), keywordToken.string());
-            return BAD_VALUE;
-        }
-    }
-
-#if DEBUG_PARSER
-    ALOGD("Parsed axis: scanCode=%d, mode=%d, axis=%d, highAxis=%d, "
-            "splitValue=%d, flatOverride=%d.",
-            scanCode,
-            axisInfo.mode, axisInfo.axis, axisInfo.highAxis,
-            axisInfo.splitValue, axisInfo.flatOverride);
-#endif
-    mMap->mAxes.add(scanCode, axisInfo);
-    return NO_ERROR;
-}
-
-};
diff --git a/libs/androidfw/Keyboard.cpp b/libs/androidfw/Keyboard.cpp
deleted file mode 100644
index 4ddbeab..0000000
--- a/libs/androidfw/Keyboard.cpp
+++ /dev/null
@@ -1,298 +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.
- */
-
-#define LOG_TAG "Keyboard"
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <limits.h>
-
-#include <androidfw/Keyboard.h>
-#include <androidfw/KeycodeLabels.h>
-#include <androidfw/KeyLayoutMap.h>
-#include <androidfw/KeyCharacterMap.h>
-#include <androidfw/InputDevice.h>
-#include <utils/Errors.h>
-#include <utils/Log.h>
-#include <cutils/properties.h>
-
-namespace android {
-
-// --- KeyMap ---
-
-KeyMap::KeyMap() {
-}
-
-KeyMap::~KeyMap() {
-}
-
-status_t KeyMap::load(const InputDeviceIdentifier& deviceIdenfifier,
-        const PropertyMap* deviceConfiguration) {
-    // Use the configured key layout if available.
-    if (deviceConfiguration) {
-        String8 keyLayoutName;
-        if (deviceConfiguration->tryGetProperty(String8("keyboard.layout"),
-                keyLayoutName)) {
-            status_t status = loadKeyLayout(deviceIdenfifier, keyLayoutName);
-            if (status == NAME_NOT_FOUND) {
-                ALOGE("Configuration for keyboard device '%s' requested keyboard layout '%s' but "
-                        "it was not found.",
-                        deviceIdenfifier.name.string(), keyLayoutName.string());
-            }
-        }
-
-        String8 keyCharacterMapName;
-        if (deviceConfiguration->tryGetProperty(String8("keyboard.characterMap"),
-                keyCharacterMapName)) {
-            status_t status = loadKeyCharacterMap(deviceIdenfifier, keyCharacterMapName);
-            if (status == NAME_NOT_FOUND) {
-                ALOGE("Configuration for keyboard device '%s' requested keyboard character "
-                        "map '%s' but it was not found.",
-                        deviceIdenfifier.name.string(), keyLayoutName.string());
-            }
-        }
-
-        if (isComplete()) {
-            return OK;
-        }
-    }
-
-    // Try searching by device identifier.
-    if (probeKeyMap(deviceIdenfifier, String8::empty())) {
-        return OK;
-    }
-
-    // Fall back on the Generic key map.
-    // TODO Apply some additional heuristics here to figure out what kind of
-    //      generic key map to use (US English, etc.) for typical external keyboards.
-    if (probeKeyMap(deviceIdenfifier, String8("Generic"))) {
-        return OK;
-    }
-
-    // Try the Virtual key map as a last resort.
-    if (probeKeyMap(deviceIdenfifier, String8("Virtual"))) {
-        return OK;
-    }
-
-    // Give up!
-    ALOGE("Could not determine key map for device '%s' and no default key maps were found!",
-            deviceIdenfifier.name.string());
-    return NAME_NOT_FOUND;
-}
-
-bool KeyMap::probeKeyMap(const InputDeviceIdentifier& deviceIdentifier,
-        const String8& keyMapName) {
-    if (!haveKeyLayout()) {
-        loadKeyLayout(deviceIdentifier, keyMapName);
-    }
-    if (!haveKeyCharacterMap()) {
-        loadKeyCharacterMap(deviceIdentifier, keyMapName);
-    }
-    return isComplete();
-}
-
-status_t KeyMap::loadKeyLayout(const InputDeviceIdentifier& deviceIdentifier,
-        const String8& name) {
-    String8 path(getPath(deviceIdentifier, name,
-            INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_LAYOUT));
-    if (path.isEmpty()) {
-        return NAME_NOT_FOUND;
-    }
-
-    status_t status = KeyLayoutMap::load(path, &keyLayoutMap);
-    if (status) {
-        return status;
-    }
-
-    keyLayoutFile.setTo(path);
-    return OK;
-}
-
-status_t KeyMap::loadKeyCharacterMap(const InputDeviceIdentifier& deviceIdentifier,
-        const String8& name) {
-    String8 path(getPath(deviceIdentifier, name,
-            INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_CHARACTER_MAP));
-    if (path.isEmpty()) {
-        return NAME_NOT_FOUND;
-    }
-
-    status_t status = KeyCharacterMap::load(path,
-            KeyCharacterMap::FORMAT_BASE, &keyCharacterMap);
-    if (status) {
-        return status;
-    }
-
-    keyCharacterMapFile.setTo(path);
-    return OK;
-}
-
-String8 KeyMap::getPath(const InputDeviceIdentifier& deviceIdentifier,
-        const String8& name, InputDeviceConfigurationFileType type) {
-    return name.isEmpty()
-            ? getInputDeviceConfigurationFilePathByDeviceIdentifier(deviceIdentifier, type)
-            : getInputDeviceConfigurationFilePathByName(name, type);
-}
-
-
-// --- Global functions ---
-
-bool isEligibleBuiltInKeyboard(const InputDeviceIdentifier& deviceIdentifier,
-        const PropertyMap* deviceConfiguration, const KeyMap* keyMap) {
-    if (!keyMap->haveKeyCharacterMap()
-            || keyMap->keyCharacterMap->getKeyboardType()
-                    == KeyCharacterMap::KEYBOARD_TYPE_SPECIAL_FUNCTION) {
-        return false;
-    }
-
-    if (deviceConfiguration) {
-        bool builtIn = false;
-        if (deviceConfiguration->tryGetProperty(String8("keyboard.builtIn"), builtIn)
-                && builtIn) {
-            return true;
-        }
-    }
-
-    return strstr(deviceIdentifier.name.string(), "-keypad");
-}
-
-static int lookupValueByLabel(const char* literal, const KeycodeLabel *list) {
-    while (list->literal) {
-        if (strcmp(literal, list->literal) == 0) {
-            return list->value;
-        }
-        list++;
-    }
-    return list->value;
-}
-
-static const char* lookupLabelByValue(int value, const KeycodeLabel *list) {
-    while (list->literal) {
-        if (list->value == value) {
-            return list->literal;
-        }
-        list++;
-    }
-    return NULL;
-}
-
-int32_t getKeyCodeByLabel(const char* label) {
-    return int32_t(lookupValueByLabel(label, KEYCODES));
-}
-
-uint32_t getKeyFlagByLabel(const char* label) {
-    return uint32_t(lookupValueByLabel(label, FLAGS));
-}
-
-int32_t getAxisByLabel(const char* label) {
-    return int32_t(lookupValueByLabel(label, AXES));
-}
-
-const char* getAxisLabel(int32_t axisId) {
-    return lookupLabelByValue(axisId, AXES);
-}
-
-static int32_t setEphemeralMetaState(int32_t mask, bool down, int32_t oldMetaState) {
-    int32_t newMetaState;
-    if (down) {
-        newMetaState = oldMetaState | mask;
-    } else {
-        newMetaState = oldMetaState &
-                ~(mask | AMETA_ALT_ON | AMETA_SHIFT_ON | AMETA_CTRL_ON | AMETA_META_ON);
-    }
-
-    if (newMetaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) {
-        newMetaState |= AMETA_ALT_ON;
-    }
-
-    if (newMetaState & (AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON)) {
-        newMetaState |= AMETA_SHIFT_ON;
-    }
-
-    if (newMetaState & (AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON)) {
-        newMetaState |= AMETA_CTRL_ON;
-    }
-
-    if (newMetaState & (AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON)) {
-        newMetaState |= AMETA_META_ON;
-    }
-    return newMetaState;
-}
-
-static int32_t toggleLockedMetaState(int32_t mask, bool down, int32_t oldMetaState) {
-    if (down) {
-        return oldMetaState;
-    } else {
-        return oldMetaState ^ mask;
-    }
-}
-
-int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState) {
-    int32_t mask;
-    switch (keyCode) {
-    case AKEYCODE_ALT_LEFT:
-        return setEphemeralMetaState(AMETA_ALT_LEFT_ON, down, oldMetaState);
-    case AKEYCODE_ALT_RIGHT:
-        return setEphemeralMetaState(AMETA_ALT_RIGHT_ON, down, oldMetaState);
-    case AKEYCODE_SHIFT_LEFT:
-        return setEphemeralMetaState(AMETA_SHIFT_LEFT_ON, down, oldMetaState);
-    case AKEYCODE_SHIFT_RIGHT:
-        return setEphemeralMetaState(AMETA_SHIFT_RIGHT_ON, down, oldMetaState);
-    case AKEYCODE_SYM:
-        return setEphemeralMetaState(AMETA_SYM_ON, down, oldMetaState);
-    case AKEYCODE_FUNCTION:
-        return setEphemeralMetaState(AMETA_FUNCTION_ON, down, oldMetaState);
-    case AKEYCODE_CTRL_LEFT:
-        return setEphemeralMetaState(AMETA_CTRL_LEFT_ON, down, oldMetaState);
-    case AKEYCODE_CTRL_RIGHT:
-        return setEphemeralMetaState(AMETA_CTRL_RIGHT_ON, down, oldMetaState);
-    case AKEYCODE_META_LEFT:
-        return setEphemeralMetaState(AMETA_META_LEFT_ON, down, oldMetaState);
-    case AKEYCODE_META_RIGHT:
-        return setEphemeralMetaState(AMETA_META_RIGHT_ON, down, oldMetaState);
-    case AKEYCODE_CAPS_LOCK:
-        return toggleLockedMetaState(AMETA_CAPS_LOCK_ON, down, oldMetaState);
-    case AKEYCODE_NUM_LOCK:
-        return toggleLockedMetaState(AMETA_NUM_LOCK_ON, down, oldMetaState);
-    case AKEYCODE_SCROLL_LOCK:
-        return toggleLockedMetaState(AMETA_SCROLL_LOCK_ON, down, oldMetaState);
-    default:
-        return oldMetaState;
-    }
-}
-
-bool isMetaKey(int32_t keyCode) {
-    switch (keyCode) {
-    case AKEYCODE_ALT_LEFT:
-    case AKEYCODE_ALT_RIGHT:
-    case AKEYCODE_SHIFT_LEFT:
-    case AKEYCODE_SHIFT_RIGHT:
-    case AKEYCODE_SYM:
-    case AKEYCODE_FUNCTION:
-    case AKEYCODE_CTRL_LEFT:
-    case AKEYCODE_CTRL_RIGHT:
-    case AKEYCODE_META_LEFT:
-    case AKEYCODE_META_RIGHT:
-    case AKEYCODE_CAPS_LOCK:
-    case AKEYCODE_NUM_LOCK:
-    case AKEYCODE_SCROLL_LOCK:
-        return true;
-    default:
-        return false;
-    }
-}
-
-
-} // namespace android
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index a730065..1cc3563 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -24,7 +24,6 @@
 #include <utils/Log.h>
 #include <utils/String16.h>
 #include <utils/String8.h>
-#include <utils/TextOutput.h>
 
 #include <stdlib.h>
 #include <string.h>
@@ -36,7 +35,7 @@
 #define INT32_MAX ((int32_t)(2147483647))
 #endif
 
-#define POOL_NOISY(x) //x
+#define STRING_POOL_NOISY(x) //x
 #define XML_NOISY(x) //x
 #define TABLE_NOISY(x) //x
 #define TABLE_GETENTRY(x) //x
@@ -379,7 +378,6 @@
         size_t charSize;
         if (mHeader->flags&ResStringPool_header::UTF8_FLAG) {
             charSize = sizeof(uint8_t);
-            mCache = (char16_t**)calloc(mHeader->stringCount, sizeof(char16_t**));
         } else {
             charSize = sizeof(char16_t);
         }
@@ -594,6 +592,23 @@
                 if ((uint32_t)(u8str+u8len-strings) < mStringPoolSize) {
                     AutoMutex lock(mDecodeLock);
 
+                    if (mCache == NULL) {
+#ifndef HAVE_ANDROID_OS
+                        STRING_POOL_NOISY(ALOGI("CREATING STRING CACHE OF %d bytes",
+                                mHeader->stringCount*sizeof(char16_t**)));
+#else
+                        // We do not want to be in this case when actually running Android.
+                        ALOGW("CREATING STRING CACHE OF %d bytes",
+                                mHeader->stringCount*sizeof(char16_t**));
+#endif
+                        mCache = (char16_t**)calloc(mHeader->stringCount, sizeof(char16_t**));
+                        if (mCache == NULL) {
+                            ALOGW("No memory trying to allocate decode cache table of %d bytes\n",
+                                    (int)(mHeader->stringCount*sizeof(char16_t**)));
+                            return NULL;
+                        }
+                    }
+
                     if (mCache[idx] != NULL) {
                         return mCache[idx];
                     }
@@ -613,6 +628,7 @@
                         return NULL;
                     }
 
+                    STRING_POOL_NOISY(ALOGI("Caching UTF8 string: %s", u8str));
                     utf8_to_utf16(u8str, u8len, u16str);
                     mCache[idx] = u16str;
                     return u16str;
@@ -634,20 +650,20 @@
 const char* ResStringPool::string8At(size_t idx, size_t* outLen) const
 {
     if (mError == NO_ERROR && idx < mHeader->stringCount) {
-        const bool isUTF8 = (mHeader->flags&ResStringPool_header::UTF8_FLAG) != 0;
-        const uint32_t off = mEntries[idx]/(isUTF8?sizeof(char):sizeof(char16_t));
+        if ((mHeader->flags&ResStringPool_header::UTF8_FLAG) == 0) {
+            return NULL;
+        }
+        const uint32_t off = mEntries[idx]/sizeof(char);
         if (off < (mStringPoolSize-1)) {
-            if (isUTF8) {
-                const uint8_t* strings = (uint8_t*)mStrings;
-                const uint8_t* str = strings+off;
-                *outLen = decodeLength(&str);
-                size_t encLen = decodeLength(&str);
-                if ((uint32_t)(str+encLen-strings) < mStringPoolSize) {
-                    return (const char*)str;
-                } else {
-                    ALOGW("Bad string block: string #%d extends to %d, past end at %d\n",
-                            (int)idx, (int)(str+encLen-strings), (int)mStringPoolSize);
-                }
+            const uint8_t* strings = (uint8_t*)mStrings;
+            const uint8_t* str = strings+off;
+            *outLen = decodeLength(&str);
+            size_t encLen = decodeLength(&str);
+            if ((uint32_t)(str+encLen-strings) < mStringPoolSize) {
+                return (const char*)str;
+            } else {
+                ALOGW("Bad string block: string #%d extends to %d, past end at %d\n",
+                        (int)idx, (int)(str+encLen-strings), (int)mStringPoolSize);
             }
         } else {
             ALOGW("Bad string block: string #%d entry is at %d, past end at %d\n",
@@ -696,45 +712,104 @@
 
     size_t len;
 
-    // TODO optimize searching for UTF-8 strings taking into account
-    // the cache fill to determine when to convert the searched-for
-    // string key to UTF-8.
+    if ((mHeader->flags&ResStringPool_header::UTF8_FLAG) != 0) {
+        STRING_POOL_NOISY(ALOGI("indexOfString UTF-8: %s", String8(str, strLen).string()));
 
-    if (mHeader->flags&ResStringPool_header::SORTED_FLAG) {
-        // Do a binary search for the string...
-        ssize_t l = 0;
-        ssize_t h = mHeader->stringCount-1;
+        // The string pool contains UTF 8 strings; we don't want to cause
+        // temporary UTF-16 strings to be created as we search.
+        if (mHeader->flags&ResStringPool_header::SORTED_FLAG) {
+            // Do a binary search for the string...  this is a little tricky,
+            // because the strings are sorted with strzcmp16().  So to match
+            // the ordering, we need to convert strings in the pool to UTF-16.
+            // But we don't want to hit the cache, so instead we will have a
+            // local temporary allocation for the conversions.
+            char16_t* convBuffer = (char16_t*)malloc(strLen+4);
+            ssize_t l = 0;
+            ssize_t h = mHeader->stringCount-1;
 
-        ssize_t mid;
-        while (l <= h) {
-            mid = l + (h - l)/2;
-            const char16_t* s = stringAt(mid, &len);
-            int c = s ? strzcmp16(s, len, str, strLen) : -1;
-            POOL_NOISY(printf("Looking for %s, at %s, cmp=%d, l/mid/h=%d/%d/%d\n",
-                         String8(str).string(),
-                         String8(s).string(),
-                         c, (int)l, (int)mid, (int)h));
-            if (c == 0) {
-                return mid;
-            } else if (c < 0) {
-                l = mid + 1;
-            } else {
-                h = mid - 1;
+            ssize_t mid;
+            while (l <= h) {
+                mid = l + (h - l)/2;
+                const uint8_t* s = (const uint8_t*)string8At(mid, &len);
+                int c;
+                if (s != NULL) {
+                    char16_t* end = utf8_to_utf16_n(s, len, convBuffer, strLen+3);
+                    *end = 0;
+                    c = strzcmp16(convBuffer, end-convBuffer, str, strLen);
+                } else {
+                    c = -1;
+                }
+                STRING_POOL_NOISY(ALOGI("Looking at %s, cmp=%d, l/mid/h=%d/%d/%d\n",
+                             (const char*)s, c, (int)l, (int)mid, (int)h));
+                if (c == 0) {
+                    STRING_POOL_NOISY(ALOGI("MATCH!"));
+                    free(convBuffer);
+                    return mid;
+                } else if (c < 0) {
+                    l = mid + 1;
+                } else {
+                    h = mid - 1;
+                }
+            }
+            free(convBuffer);
+        } else {
+            // It is unusual to get the ID from an unsorted string block...
+            // most often this happens because we want to get IDs for style
+            // span tags; since those always appear at the end of the string
+            // block, start searching at the back.
+            String8 str8(str, strLen);
+            const size_t str8Len = str8.size();
+            for (int i=mHeader->stringCount-1; i>=0; i--) {
+                const char* s = string8At(i, &len);
+                STRING_POOL_NOISY(ALOGI("Looking at %s, i=%d\n",
+                             String8(s).string(),
+                             i));
+                if (s && str8Len == len && memcmp(s, str8.string(), str8Len) == 0) {
+                    STRING_POOL_NOISY(ALOGI("MATCH!"));
+                    return i;
+                }
             }
         }
+
     } else {
-        // It is unusual to get the ID from an unsorted string block...
-        // most often this happens because we want to get IDs for style
-        // span tags; since those always appear at the end of the string
-        // block, start searching at the back.
-        for (int i=mHeader->stringCount-1; i>=0; i--) {
-            const char16_t* s = stringAt(i, &len);
-            POOL_NOISY(printf("Looking for %s, at %s, i=%d\n",
-                         String8(str, strLen).string(),
-                         String8(s).string(),
-                         i));
-            if (s && strzcmp16(s, len, str, strLen) == 0) {
-                return i;
+        STRING_POOL_NOISY(ALOGI("indexOfString UTF-16: %s", String8(str, strLen).string()));
+
+        if (mHeader->flags&ResStringPool_header::SORTED_FLAG) {
+            // Do a binary search for the string...
+            ssize_t l = 0;
+            ssize_t h = mHeader->stringCount-1;
+
+            ssize_t mid;
+            while (l <= h) {
+                mid = l + (h - l)/2;
+                const char16_t* s = stringAt(mid, &len);
+                int c = s ? strzcmp16(s, len, str, strLen) : -1;
+                STRING_POOL_NOISY(ALOGI("Looking at %s, cmp=%d, l/mid/h=%d/%d/%d\n",
+                             String8(s).string(),
+                             c, (int)l, (int)mid, (int)h));
+                if (c == 0) {
+                    STRING_POOL_NOISY(ALOGI("MATCH!"));
+                    return mid;
+                } else if (c < 0) {
+                    l = mid + 1;
+                } else {
+                    h = mid - 1;
+                }
+            }
+        } else {
+            // It is unusual to get the ID from an unsorted string block...
+            // most often this happens because we want to get IDs for style
+            // span tags; since those always appear at the end of the string
+            // block, start searching at the back.
+            for (int i=mHeader->stringCount-1; i>=0; i--) {
+                const char16_t* s = stringAt(i, &len);
+                STRING_POOL_NOISY(ALOGI("Looking at %s, i=%d\n",
+                             String8(s).string(),
+                             i));
+                if (s && strLen == len && strzcmp16(s, len, str, strLen) == 0) {
+                    STRING_POOL_NOISY(ALOGI("MATCH!"));
+                    return i;
+                }
             }
         }
     }
@@ -937,6 +1012,14 @@
     return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
 }
 
+const char* ResXMLParser::getAttributeNamespace8(size_t idx, size_t* outLen) const
+{
+    int32_t id = getAttributeNamespaceID(idx);
+    //printf("attribute namespace=%d  idx=%d  event=%p\n", id, idx, mEventCode);
+    //XML_NOISY(printf("getAttributeNamespace 0x%x=0x%x\n", idx, id));
+    return id >= 0 ? mTree.mStrings.string8At(id, outLen) : NULL;
+}
+
 int32_t ResXMLParser::getAttributeNameID(size_t idx) const
 {
     if (mEventCode == START_TAG) {
@@ -960,6 +1043,14 @@
     return id >= 0 ? mTree.mStrings.stringAt(id, outLen) : NULL;
 }
 
+const char* ResXMLParser::getAttributeName8(size_t idx, size_t* outLen) const
+{
+    int32_t id = getAttributeNameID(idx);
+    //printf("attribute name=%d  idx=%d  event=%p\n", id, idx, mEventCode);
+    //XML_NOISY(printf("getAttributeName 0x%x=0x%x\n", idx, id));
+    return id >= 0 ? mTree.mStrings.string8At(id, outLen) : NULL;
+}
+
 uint32_t ResXMLParser::getAttributeNameResID(size_t idx) const
 {
     int32_t id = getAttributeNameID(idx);
@@ -1049,22 +1140,67 @@
                                        const char16_t* attr, size_t attrLen) const
 {
     if (mEventCode == START_TAG) {
+        if (attr == NULL) {
+            return NAME_NOT_FOUND;
+        }
         const size_t N = getAttributeCount();
-        for (size_t i=0; i<N; i++) {
-            size_t curNsLen, curAttrLen;
-            const char16_t* curNs = getAttributeNamespace(i, &curNsLen);
-            const char16_t* curAttr = getAttributeName(i, &curAttrLen);
-            //printf("%d: ns=%p attr=%p curNs=%p curAttr=%p\n",
-            //       i, ns, attr, curNs, curAttr);
-            //printf(" --> attr=%s, curAttr=%s\n",
-            //       String8(attr).string(), String8(curAttr).string());
-            if (attr && curAttr && (strzcmp16(attr, attrLen, curAttr, curAttrLen) == 0)) {
-                if (ns == NULL) {
-                    if (curNs == NULL) return i;
-                } else if (curNs != NULL) {
-                    //printf(" --> ns=%s, curNs=%s\n",
-                    //       String8(ns).string(), String8(curNs).string());
-                    if (strzcmp16(ns, nsLen, curNs, curNsLen) == 0) return i;
+        if (mTree.mStrings.isUTF8()) {
+            String8 ns8, attr8;
+            if (ns != NULL) {
+                ns8 = String8(ns, nsLen);
+            }
+            attr8 = String8(attr, attrLen);
+            STRING_POOL_NOISY(ALOGI("indexOfAttribute UTF8 %s (%d) / %s (%d)", ns8.string(), nsLen,
+                    attr8.string(), attrLen));
+            for (size_t i=0; i<N; i++) {
+                size_t curNsLen = 0, curAttrLen = 0;
+                const char* curNs = getAttributeNamespace8(i, &curNsLen);
+                const char* curAttr = getAttributeName8(i, &curAttrLen);
+                STRING_POOL_NOISY(ALOGI("  curNs=%s (%d), curAttr=%s (%d)", curNs, curNsLen,
+                        curAttr, curAttrLen));
+                if (curAttr != NULL && curNsLen == nsLen && curAttrLen == attrLen
+                        && memcmp(attr8.string(), curAttr, attrLen) == 0) {
+                    if (ns == NULL) {
+                        if (curNs == NULL) {
+                            STRING_POOL_NOISY(ALOGI("  FOUND!"));
+                            return i;
+                        }
+                    } else if (curNs != NULL) {
+                        //printf(" --> ns=%s, curNs=%s\n",
+                        //       String8(ns).string(), String8(curNs).string());
+                        if (memcmp(ns8.string(), curNs, nsLen) == 0) {
+                            STRING_POOL_NOISY(ALOGI("  FOUND!"));
+                            return i;
+                        }
+                    }
+                }
+            }
+        } else {
+            STRING_POOL_NOISY(ALOGI("indexOfAttribute UTF16 %s (%d) / %s (%d)",
+                    String8(ns, nsLen).string(), nsLen,
+                    String8(attr, attrLen).string(), attrLen));
+            for (size_t i=0; i<N; i++) {
+                size_t curNsLen = 0, curAttrLen = 0;
+                const char16_t* curNs = getAttributeNamespace(i, &curNsLen);
+                const char16_t* curAttr = getAttributeName(i, &curAttrLen);
+                STRING_POOL_NOISY(ALOGI("  curNs=%s (%d), curAttr=%s (%d)",
+                        String8(curNs, curNsLen).string(), curNsLen,
+                        String8(curAttr, curAttrLen).string(), curAttrLen));
+                if (curAttr != NULL && curNsLen == nsLen && curAttrLen == attrLen
+                        && (memcmp(attr, curAttr, attrLen*sizeof(char16_t)) == 0)) {
+                    if (ns == NULL) {
+                        if (curNs == NULL) {
+                            STRING_POOL_NOISY(ALOGI("  FOUND!"));
+                            return i;
+                        }
+                    } else if (curNs != NULL) {
+                        //printf(" --> ns=%s, curNs=%s\n",
+                        //       String8(ns).string(), String8(curNs).string());
+                        if (memcmp(ns, curNs, nsLen*sizeof(char16_t)) == 0) {
+                            STRING_POOL_NOISY(ALOGI("  FOUND!"));
+                            return i;
+                        }
+                    }
                 }
             }
         }
@@ -2941,7 +3077,7 @@
     mHeaders.clear();
 }
 
-bool ResTable::getResourceName(uint32_t resID, resource_name* outName) const
+bool ResTable::getResourceName(uint32_t resID, bool allowUtf8, resource_name* outName) const
 {
     if (mError != NO_ERROR) {
         return false;
@@ -2981,13 +3117,28 @@
 
         outName->package = grp->name.string();
         outName->packageLen = grp->name.size();
-        outName->type = grp->basePackage->typeStrings.stringAt(t, &outName->typeLen);
-        outName->name = grp->basePackage->keyStrings.stringAt(
-            dtohl(entry->key.index), &outName->nameLen);
-
-        // If we have a bad index for some reason, we should abort.
-        if (outName->type == NULL || outName->name == NULL) {
-            return false;
+        if (allowUtf8) {
+            outName->type8 = grp->basePackage->typeStrings.string8At(t, &outName->typeLen);
+            outName->name8 = grp->basePackage->keyStrings.string8At(
+                dtohl(entry->key.index), &outName->nameLen);
+        } else {
+            outName->type8 = NULL;
+            outName->name8 = NULL;
+        }
+        if (outName->type8 == NULL) {
+            outName->type = grp->basePackage->typeStrings.stringAt(t, &outName->typeLen);
+            // If we have a bad index for some reason, we should abort.
+            if (outName->type == NULL) {
+                return false;
+            }
+        }
+        if (outName->name8 == NULL) {
+            outName->name = grp->basePackage->keyStrings.stringAt(
+                dtohl(entry->key.index), &outName->nameLen);
+            // If we have a bad index for some reason, we should abort.
+            if (outName->name == NULL) {
+                return false;
+            }
         }
 
         return true;
@@ -4486,7 +4637,7 @@
             while (cnt > 0) {
                 if (!Res_INTERNALID(bag->map.name.ident)) {
                     //printf("Trying attr #%08x\n", bag->map.name.ident);
-                    if (getResourceName(bag->map.name.ident, &rname)) {
+                    if (getResourceName(bag->map.name.ident, false, &rname)) {
                         #if 0
                         printf("Matching %s against %s (0x%08x)\n",
                                String8(s, len).string(),
@@ -4539,7 +4690,7 @@
                 for (i=0; i<cnt; i++, bagi++) {
                     if (!Res_INTERNALID(bagi->map.name.ident)) {
                         //printf("Trying attr #%08x\n", bagi->map.name.ident);
-                        if (getResourceName(bagi->map.name.ident, &rname)) {
+                        if (getResourceName(bagi->map.name.ident, false, &rname)) {
                             #if 0
                             printf("Matching %s against %s (0x%08x)\n",
                                    String8(start,pos-start).string(),
@@ -5217,7 +5368,7 @@
                 | (0x00ff0000 & ((typeIndex+1)<<16))
                 | (0x0000ffff & (entryIndex));
             resource_name resName;
-            if (!this->getResourceName(resID, &resName)) {
+            if (!this->getResourceName(resID, true, &resName)) {
                 ALOGW("idmap: resource 0x%08x has spec but lacks values, skipping\n", resID);
                 // add dummy value, or trimming leading/trailing zeroes later will fail
                 vector.push(0);
@@ -5324,13 +5475,12 @@
 }
 
 
-#ifndef HAVE_ANDROID_OS
 #define CHAR16_TO_CSTR(c16, len) (String8(String16(c16,len)).string())
 
 #define CHAR16_ARRAY_EQ(constant, var, len) \
         ((len == (sizeof(constant)/sizeof(constant[0]))) && (0 == memcmp((var), (constant), (len))))
 
-void print_complex(uint32_t complex, bool isFraction)
+static void print_complex(uint32_t complex, bool isFraction)
 {
     const float MANTISSA_MULT =
         1.0f / (1<<Res_value::COMPLEX_MANTISSA_SHIFT);
@@ -5485,12 +5635,23 @@
                                     | (0x00ff0000 & ((typeIndex+1)<<16))
                                     | (0x0000ffff & (entryIndex));
                         resource_name resName;
-                        if (this->getResourceName(resID, &resName)) {
+                        if (this->getResourceName(resID, true, &resName)) {
+                            String8 type8;
+                            String8 name8;
+                            if (resName.type8 != NULL) {
+                                type8 = String8(resName.type8, resName.typeLen);
+                            } else {
+                                type8 = String8(resName.type, resName.typeLen);
+                            }
+                            if (resName.name8 != NULL) {
+                                name8 = String8(resName.name8, resName.nameLen);
+                            } else {
+                                name8 = String8(resName.name, resName.nameLen);
+                            }
                             printf("      spec resource 0x%08x %s:%s/%s: flags=0x%08x\n",
                                 resID,
                                 CHAR16_TO_CSTR(resName.package, resName.packageLen),
-                                CHAR16_TO_CSTR(resName.type, resName.typeLen),
-                                CHAR16_TO_CSTR(resName.name, resName.nameLen),
+                                type8.string(), name8.string(),
                                 dtohl(typeConfigs->typeSpecFlags[entryIndex]));
                         } else {
                             printf("      INVALID TYPE CONFIG FOR RESOURCE 0x%08x\n", resID);
@@ -5533,11 +5694,22 @@
                                     | (0x00ff0000 & ((typeIndex+1)<<16))
                                     | (0x0000ffff & (entryIndex));
                         resource_name resName;
-                        if (this->getResourceName(resID, &resName)) {
+                        if (this->getResourceName(resID, true, &resName)) {
+                            String8 type8;
+                            String8 name8;
+                            if (resName.type8 != NULL) {
+                                type8 = String8(resName.type8, resName.typeLen);
+                            } else {
+                                type8 = String8(resName.type, resName.typeLen);
+                            }
+                            if (resName.name8 != NULL) {
+                                name8 = String8(resName.name8, resName.nameLen);
+                            } else {
+                                name8 = String8(resName.name, resName.nameLen);
+                            }
                             printf("        resource 0x%08x %s:%s/%s: ", resID,
                                     CHAR16_TO_CSTR(resName.package, resName.packageLen),
-                                    CHAR16_TO_CSTR(resName.type, resName.typeLen),
-                                    CHAR16_TO_CSTR(resName.name, resName.nameLen));
+                                    type8.string(), name8.string());
                         } else {
                             printf("        INVALID RESOURCE 0x%08x: ", resID);
                         }
@@ -5621,6 +5793,4 @@
     }
 }
 
-#endif // HAVE_ANDROID_OS
-
 }   // namespace android
diff --git a/libs/androidfw/VelocityControl.cpp b/libs/androidfw/VelocityControl.cpp
deleted file mode 100644
index cde2b76..0000000
--- a/libs/androidfw/VelocityControl.cpp
+++ /dev/null
@@ -1,110 +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.
- */
-
-#define LOG_TAG "VelocityControl"
-//#define LOG_NDEBUG 0
-
-// Log debug messages about acceleration.
-#define DEBUG_ACCELERATION 0
-
-#include <math.h>
-#include <limits.h>
-
-#include <androidfw/VelocityControl.h>
-#include <utils/BitSet.h>
-#include <utils/Timers.h>
-
-namespace android {
-
-// --- VelocityControl ---
-
-const nsecs_t VelocityControl::STOP_TIME;
-
-VelocityControl::VelocityControl() {
-    reset();
-}
-
-void VelocityControl::setParameters(const VelocityControlParameters& parameters) {
-    mParameters = parameters;
-    reset();
-}
-
-void VelocityControl::reset() {
-    mLastMovementTime = LLONG_MIN;
-    mRawPosition.x = 0;
-    mRawPosition.y = 0;
-    mVelocityTracker.clear();
-}
-
-void VelocityControl::move(nsecs_t eventTime, float* deltaX, float* deltaY) {
-    if ((deltaX && *deltaX) || (deltaY && *deltaY)) {
-        if (eventTime >= mLastMovementTime + STOP_TIME) {
-#if DEBUG_ACCELERATION
-            ALOGD("VelocityControl: stopped, last movement was %0.3fms ago",
-                    (eventTime - mLastMovementTime) * 0.000001f);
-#endif
-            reset();
-        }
-
-        mLastMovementTime = eventTime;
-        if (deltaX) {
-            mRawPosition.x += *deltaX;
-        }
-        if (deltaY) {
-            mRawPosition.y += *deltaY;
-        }
-        mVelocityTracker.addMovement(eventTime, BitSet32(BitSet32::valueForBit(0)), &mRawPosition);
-
-        float vx, vy;
-        float scale = mParameters.scale;
-        if (mVelocityTracker.getVelocity(0, &vx, &vy)) {
-            float speed = hypotf(vx, vy) * scale;
-            if (speed >= mParameters.highThreshold) {
-                // Apply full acceleration above the high speed threshold.
-                scale *= mParameters.acceleration;
-            } else if (speed > mParameters.lowThreshold) {
-                // Linearly interpolate the acceleration to apply between the low and high
-                // speed thresholds.
-                scale *= 1 + (speed - mParameters.lowThreshold)
-                        / (mParameters.highThreshold - mParameters.lowThreshold)
-                        * (mParameters.acceleration - 1);
-            }
-
-#if DEBUG_ACCELERATION
-            ALOGD("VelocityControl(%0.3f, %0.3f, %0.3f, %0.3f): "
-                    "vx=%0.3f, vy=%0.3f, speed=%0.3f, accel=%0.3f",
-                    mParameters.scale, mParameters.lowThreshold, mParameters.highThreshold,
-                    mParameters.acceleration,
-                    vx, vy, speed, scale / mParameters.scale);
-#endif
-        } else {
-#if DEBUG_ACCELERATION
-            ALOGD("VelocityControl(%0.3f, %0.3f, %0.3f, %0.3f): unknown velocity",
-                    mParameters.scale, mParameters.lowThreshold, mParameters.highThreshold,
-                    mParameters.acceleration);
-#endif
-        }
-
-        if (deltaX) {
-            *deltaX *= scale;
-        }
-        if (deltaY) {
-            *deltaY *= scale;
-        }
-    }
-}
-
-} // namespace android
diff --git a/libs/androidfw/VelocityTracker.cpp b/libs/androidfw/VelocityTracker.cpp
deleted file mode 100644
index f48ec62..0000000
--- a/libs/androidfw/VelocityTracker.cpp
+++ /dev/null
@@ -1,928 +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.
- */
-
-#define LOG_TAG "VelocityTracker"
-//#define LOG_NDEBUG 0
-
-// Log debug messages about velocity tracking.
-#define DEBUG_VELOCITY 0
-
-// Log debug messages about the progress of the algorithm itself.
-#define DEBUG_STRATEGY 0
-
-#include <math.h>
-#include <limits.h>
-
-#include <androidfw/VelocityTracker.h>
-#include <utils/BitSet.h>
-#include <utils/String8.h>
-#include <utils/Timers.h>
-
-#include <cutils/properties.h>
-
-namespace android {
-
-// Nanoseconds per milliseconds.
-static const nsecs_t NANOS_PER_MS = 1000000;
-
-// Threshold for determining that a pointer has stopped moving.
-// Some input devices do not send ACTION_MOVE events in the case where a pointer has
-// stopped.  We need to detect this case so that we can accurately predict the
-// velocity after the pointer starts moving again.
-static const nsecs_t ASSUME_POINTER_STOPPED_TIME = 40 * NANOS_PER_MS;
-
-
-static float vectorDot(const float* a, const float* b, uint32_t m) {
-    float r = 0;
-    while (m--) {
-        r += *(a++) * *(b++);
-    }
-    return r;
-}
-
-static float vectorNorm(const float* a, uint32_t m) {
-    float r = 0;
-    while (m--) {
-        float t = *(a++);
-        r += t * t;
-    }
-    return sqrtf(r);
-}
-
-#if DEBUG_STRATEGY || DEBUG_VELOCITY
-static String8 vectorToString(const float* a, uint32_t m) {
-    String8 str;
-    str.append("[");
-    while (m--) {
-        str.appendFormat(" %f", *(a++));
-        if (m) {
-            str.append(",");
-        }
-    }
-    str.append(" ]");
-    return str;
-}
-
-static String8 matrixToString(const float* a, uint32_t m, uint32_t n, bool rowMajor) {
-    String8 str;
-    str.append("[");
-    for (size_t i = 0; i < m; i++) {
-        if (i) {
-            str.append(",");
-        }
-        str.append(" [");
-        for (size_t j = 0; j < n; j++) {
-            if (j) {
-                str.append(",");
-            }
-            str.appendFormat(" %f", a[rowMajor ? i * n + j : j * m + i]);
-        }
-        str.append(" ]");
-    }
-    str.append(" ]");
-    return str;
-}
-#endif
-
-
-// --- VelocityTracker ---
-
-// The default velocity tracker strategy.
-// Although other strategies are available for testing and comparison purposes,
-// this is the strategy that applications will actually use.  Be very careful
-// when adjusting the default strategy because it can dramatically affect
-// (often in a bad way) the user experience.
-const char* VelocityTracker::DEFAULT_STRATEGY = "lsq2";
-
-VelocityTracker::VelocityTracker(const char* strategy) :
-        mLastEventTime(0), mCurrentPointerIdBits(0), mActivePointerId(-1) {
-    char value[PROPERTY_VALUE_MAX];
-
-    // Allow the default strategy to be overridden using a system property for debugging.
-    if (!strategy) {
-        int length = property_get("debug.velocitytracker.strategy", value, NULL);
-        if (length > 0) {
-            strategy = value;
-        } else {
-            strategy = DEFAULT_STRATEGY;
-        }
-    }
-
-    // Configure the strategy.
-    if (!configureStrategy(strategy)) {
-        ALOGD("Unrecognized velocity tracker strategy name '%s'.", strategy);
-        if (!configureStrategy(DEFAULT_STRATEGY)) {
-            LOG_ALWAYS_FATAL("Could not create the default velocity tracker strategy '%s'!",
-                    strategy);
-        }
-    }
-}
-
-VelocityTracker::~VelocityTracker() {
-    delete mStrategy;
-}
-
-bool VelocityTracker::configureStrategy(const char* strategy) {
-    mStrategy = createStrategy(strategy);
-    return mStrategy != NULL;
-}
-
-VelocityTrackerStrategy* VelocityTracker::createStrategy(const char* strategy) {
-    if (!strcmp("lsq1", strategy)) {
-        // 1st order least squares.  Quality: POOR.
-        // Frequently underfits the touch data especially when the finger accelerates
-        // or changes direction.  Often underestimates velocity.  The direction
-        // is overly influenced by historical touch points.
-        return new LeastSquaresVelocityTrackerStrategy(1);
-    }
-    if (!strcmp("lsq2", strategy)) {
-        // 2nd order least squares.  Quality: VERY GOOD.
-        // Pretty much ideal, but can be confused by certain kinds of touch data,
-        // particularly if the panel has a tendency to generate delayed,
-        // duplicate or jittery touch coordinates when the finger is released.
-        return new LeastSquaresVelocityTrackerStrategy(2);
-    }
-    if (!strcmp("lsq3", strategy)) {
-        // 3rd order least squares.  Quality: UNUSABLE.
-        // Frequently overfits the touch data yielding wildly divergent estimates
-        // of the velocity when the finger is released.
-        return new LeastSquaresVelocityTrackerStrategy(3);
-    }
-    if (!strcmp("wlsq2-delta", strategy)) {
-        // 2nd order weighted least squares, delta weighting.  Quality: EXPERIMENTAL
-        return new LeastSquaresVelocityTrackerStrategy(2,
-                LeastSquaresVelocityTrackerStrategy::WEIGHTING_DELTA);
-    }
-    if (!strcmp("wlsq2-central", strategy)) {
-        // 2nd order weighted least squares, central weighting.  Quality: EXPERIMENTAL
-        return new LeastSquaresVelocityTrackerStrategy(2,
-                LeastSquaresVelocityTrackerStrategy::WEIGHTING_CENTRAL);
-    }
-    if (!strcmp("wlsq2-recent", strategy)) {
-        // 2nd order weighted least squares, recent weighting.  Quality: EXPERIMENTAL
-        return new LeastSquaresVelocityTrackerStrategy(2,
-                LeastSquaresVelocityTrackerStrategy::WEIGHTING_RECENT);
-    }
-    if (!strcmp("int1", strategy)) {
-        // 1st order integrating filter.  Quality: GOOD.
-        // Not as good as 'lsq2' because it cannot estimate acceleration but it is
-        // more tolerant of errors.  Like 'lsq1', this strategy tends to underestimate
-        // the velocity of a fling but this strategy tends to respond to changes in
-        // direction more quickly and accurately.
-        return new IntegratingVelocityTrackerStrategy(1);
-    }
-    if (!strcmp("int2", strategy)) {
-        // 2nd order integrating filter.  Quality: EXPERIMENTAL.
-        // For comparison purposes only.  Unlike 'int1' this strategy can compensate
-        // for acceleration but it typically overestimates the effect.
-        return new IntegratingVelocityTrackerStrategy(2);
-    }
-    if (!strcmp("legacy", strategy)) {
-        // Legacy velocity tracker algorithm.  Quality: POOR.
-        // For comparison purposes only.  This algorithm is strongly influenced by
-        // old data points, consistently underestimates velocity and takes a very long
-        // time to adjust to changes in direction.
-        return new LegacyVelocityTrackerStrategy();
-    }
-    return NULL;
-}
-
-void VelocityTracker::clear() {
-    mCurrentPointerIdBits.clear();
-    mActivePointerId = -1;
-
-    mStrategy->clear();
-}
-
-void VelocityTracker::clearPointers(BitSet32 idBits) {
-    BitSet32 remainingIdBits(mCurrentPointerIdBits.value & ~idBits.value);
-    mCurrentPointerIdBits = remainingIdBits;
-
-    if (mActivePointerId >= 0 && idBits.hasBit(mActivePointerId)) {
-        mActivePointerId = !remainingIdBits.isEmpty() ? remainingIdBits.firstMarkedBit() : -1;
-    }
-
-    mStrategy->clearPointers(idBits);
-}
-
-void VelocityTracker::addMovement(nsecs_t eventTime, BitSet32 idBits, const Position* positions) {
-    while (idBits.count() > MAX_POINTERS) {
-        idBits.clearLastMarkedBit();
-    }
-
-    if ((mCurrentPointerIdBits.value & idBits.value)
-            && eventTime >= mLastEventTime + ASSUME_POINTER_STOPPED_TIME) {
-#if DEBUG_VELOCITY
-        ALOGD("VelocityTracker: stopped for %0.3f ms, clearing state.",
-                (eventTime - mLastEventTime) * 0.000001f);
-#endif
-        // We have not received any movements for too long.  Assume that all pointers
-        // have stopped.
-        mStrategy->clear();
-    }
-    mLastEventTime = eventTime;
-
-    mCurrentPointerIdBits = idBits;
-    if (mActivePointerId < 0 || !idBits.hasBit(mActivePointerId)) {
-        mActivePointerId = idBits.isEmpty() ? -1 : idBits.firstMarkedBit();
-    }
-
-    mStrategy->addMovement(eventTime, idBits, positions);
-
-#if DEBUG_VELOCITY
-    ALOGD("VelocityTracker: addMovement eventTime=%lld, idBits=0x%08x, activePointerId=%d",
-            eventTime, idBits.value, mActivePointerId);
-    for (BitSet32 iterBits(idBits); !iterBits.isEmpty(); ) {
-        uint32_t id = iterBits.firstMarkedBit();
-        uint32_t index = idBits.getIndexOfBit(id);
-        iterBits.clearBit(id);
-        Estimator estimator;
-        getEstimator(id, &estimator);
-        ALOGD("  %d: position (%0.3f, %0.3f), "
-                "estimator (degree=%d, xCoeff=%s, yCoeff=%s, confidence=%f)",
-                id, positions[index].x, positions[index].y,
-                int(estimator.degree),
-                vectorToString(estimator.xCoeff, estimator.degree + 1).string(),
-                vectorToString(estimator.yCoeff, estimator.degree + 1).string(),
-                estimator.confidence);
-    }
-#endif
-}
-
-void VelocityTracker::addMovement(const MotionEvent* event) {
-    int32_t actionMasked = event->getActionMasked();
-
-    switch (actionMasked) {
-    case AMOTION_EVENT_ACTION_DOWN:
-    case AMOTION_EVENT_ACTION_HOVER_ENTER:
-        // Clear all pointers on down before adding the new movement.
-        clear();
-        break;
-    case AMOTION_EVENT_ACTION_POINTER_DOWN: {
-        // Start a new movement trace for a pointer that just went down.
-        // We do this on down instead of on up because the client may want to query the
-        // final velocity for a pointer that just went up.
-        BitSet32 downIdBits;
-        downIdBits.markBit(event->getPointerId(event->getActionIndex()));
-        clearPointers(downIdBits);
-        break;
-    }
-    case AMOTION_EVENT_ACTION_MOVE:
-    case AMOTION_EVENT_ACTION_HOVER_MOVE:
-        break;
-    default:
-        // Ignore all other actions because they do not convey any new information about
-        // pointer movement.  We also want to preserve the last known velocity of the pointers.
-        // Note that ACTION_UP and ACTION_POINTER_UP always report the last known position
-        // of the pointers that went up.  ACTION_POINTER_UP does include the new position of
-        // pointers that remained down but we will also receive an ACTION_MOVE with this
-        // information if any of them actually moved.  Since we don't know how many pointers
-        // will be going up at once it makes sense to just wait for the following ACTION_MOVE
-        // before adding the movement.
-        return;
-    }
-
-    size_t pointerCount = event->getPointerCount();
-    if (pointerCount > MAX_POINTERS) {
-        pointerCount = MAX_POINTERS;
-    }
-
-    BitSet32 idBits;
-    for (size_t i = 0; i < pointerCount; i++) {
-        idBits.markBit(event->getPointerId(i));
-    }
-
-    uint32_t pointerIndex[MAX_POINTERS];
-    for (size_t i = 0; i < pointerCount; i++) {
-        pointerIndex[i] = idBits.getIndexOfBit(event->getPointerId(i));
-    }
-
-    nsecs_t eventTime;
-    Position positions[pointerCount];
-
-    size_t historySize = event->getHistorySize();
-    for (size_t h = 0; h < historySize; h++) {
-        eventTime = event->getHistoricalEventTime(h);
-        for (size_t i = 0; i < pointerCount; i++) {
-            uint32_t index = pointerIndex[i];
-            positions[index].x = event->getHistoricalX(i, h);
-            positions[index].y = event->getHistoricalY(i, h);
-        }
-        addMovement(eventTime, idBits, positions);
-    }
-
-    eventTime = event->getEventTime();
-    for (size_t i = 0; i < pointerCount; i++) {
-        uint32_t index = pointerIndex[i];
-        positions[index].x = event->getX(i);
-        positions[index].y = event->getY(i);
-    }
-    addMovement(eventTime, idBits, positions);
-}
-
-bool VelocityTracker::getVelocity(uint32_t id, float* outVx, float* outVy) const {
-    Estimator estimator;
-    if (getEstimator(id, &estimator) && estimator.degree >= 1) {
-        *outVx = estimator.xCoeff[1];
-        *outVy = estimator.yCoeff[1];
-        return true;
-    }
-    *outVx = 0;
-    *outVy = 0;
-    return false;
-}
-
-bool VelocityTracker::getEstimator(uint32_t id, Estimator* outEstimator) const {
-    return mStrategy->getEstimator(id, outEstimator);
-}
-
-
-// --- LeastSquaresVelocityTrackerStrategy ---
-
-const nsecs_t LeastSquaresVelocityTrackerStrategy::HORIZON;
-const uint32_t LeastSquaresVelocityTrackerStrategy::HISTORY_SIZE;
-
-LeastSquaresVelocityTrackerStrategy::LeastSquaresVelocityTrackerStrategy(
-        uint32_t degree, Weighting weighting) :
-        mDegree(degree), mWeighting(weighting) {
-    clear();
-}
-
-LeastSquaresVelocityTrackerStrategy::~LeastSquaresVelocityTrackerStrategy() {
-}
-
-void LeastSquaresVelocityTrackerStrategy::clear() {
-    mIndex = 0;
-    mMovements[0].idBits.clear();
-}
-
-void LeastSquaresVelocityTrackerStrategy::clearPointers(BitSet32 idBits) {
-    BitSet32 remainingIdBits(mMovements[mIndex].idBits.value & ~idBits.value);
-    mMovements[mIndex].idBits = remainingIdBits;
-}
-
-void LeastSquaresVelocityTrackerStrategy::addMovement(nsecs_t eventTime, BitSet32 idBits,
-        const VelocityTracker::Position* positions) {
-    if (++mIndex == HISTORY_SIZE) {
-        mIndex = 0;
-    }
-
-    Movement& movement = mMovements[mIndex];
-    movement.eventTime = eventTime;
-    movement.idBits = idBits;
-    uint32_t count = idBits.count();
-    for (uint32_t i = 0; i < count; i++) {
-        movement.positions[i] = positions[i];
-    }
-}
-
-/**
- * Solves a linear least squares problem to obtain a N degree polynomial that fits
- * the specified input data as nearly as possible.
- *
- * Returns true if a solution is found, false otherwise.
- *
- * The input consists of two vectors of data points X and Y with indices 0..m-1
- * along with a weight vector W of the same size.
- *
- * The output is a vector B with indices 0..n that describes a polynomial
- * that fits the data, such the sum of W[i] * W[i] * abs(Y[i] - (B[0] + B[1] X[i]
- * + B[2] X[i]^2 ... B[n] X[i]^n)) for all i between 0 and m-1 is minimized.
- *
- * Accordingly, the weight vector W should be initialized by the caller with the
- * reciprocal square root of the variance of the error in each input data point.
- * In other words, an ideal choice for W would be W[i] = 1 / var(Y[i]) = 1 / stddev(Y[i]).
- * The weights express the relative importance of each data point.  If the weights are
- * all 1, then the data points are considered to be of equal importance when fitting
- * the polynomial.  It is a good idea to choose weights that diminish the importance
- * of data points that may have higher than usual error margins.
- *
- * Errors among data points are assumed to be independent.  W is represented here
- * as a vector although in the literature it is typically taken to be a diagonal matrix.
- *
- * That is to say, the function that generated the input data can be approximated
- * by y(x) ~= B[0] + B[1] x + B[2] x^2 + ... + B[n] x^n.
- *
- * The coefficient of determination (R^2) is also returned to describe the goodness
- * of fit of the model for the given data.  It is a value between 0 and 1, where 1
- * indicates perfect correspondence.
- *
- * This function first expands the X vector to a m by n matrix A such that
- * A[i][0] = 1, A[i][1] = X[i], A[i][2] = X[i]^2, ..., A[i][n] = X[i]^n, then
- * multiplies it by w[i]./
- *
- * Then it calculates the QR decomposition of A yielding an m by m orthonormal matrix Q
- * and an m by n upper triangular matrix R.  Because R is upper triangular (lower
- * part is all zeroes), we can simplify the decomposition into an m by n matrix
- * Q1 and a n by n matrix R1 such that A = Q1 R1.
- *
- * Finally we solve the system of linear equations given by R1 B = (Qtranspose W Y)
- * to find B.
- *
- * For efficiency, we lay out A and Q column-wise in memory because we frequently
- * operate on the column vectors.  Conversely, we lay out R row-wise.
- *
- * http://en.wikipedia.org/wiki/Numerical_methods_for_linear_least_squares
- * http://en.wikipedia.org/wiki/Gram-Schmidt
- */
-static bool solveLeastSquares(const float* x, const float* y,
-        const float* w, uint32_t m, uint32_t n, float* outB, float* outDet) {
-#if DEBUG_STRATEGY
-    ALOGD("solveLeastSquares: m=%d, n=%d, x=%s, y=%s, w=%s", int(m), int(n),
-            vectorToString(x, m).string(), vectorToString(y, m).string(),
-            vectorToString(w, m).string());
-#endif
-
-    // Expand the X vector to a matrix A, pre-multiplied by the weights.
-    float a[n][m]; // column-major order
-    for (uint32_t h = 0; h < m; h++) {
-        a[0][h] = w[h];
-        for (uint32_t i = 1; i < n; i++) {
-            a[i][h] = a[i - 1][h] * x[h];
-        }
-    }
-#if DEBUG_STRATEGY
-    ALOGD("  - a=%s", matrixToString(&a[0][0], m, n, false /*rowMajor*/).string());
-#endif
-
-    // Apply the Gram-Schmidt process to A to obtain its QR decomposition.
-    float q[n][m]; // orthonormal basis, column-major order
-    float r[n][n]; // upper triangular matrix, row-major order
-    for (uint32_t j = 0; j < n; j++) {
-        for (uint32_t h = 0; h < m; h++) {
-            q[j][h] = a[j][h];
-        }
-        for (uint32_t i = 0; i < j; i++) {
-            float dot = vectorDot(&q[j][0], &q[i][0], m);
-            for (uint32_t h = 0; h < m; h++) {
-                q[j][h] -= dot * q[i][h];
-            }
-        }
-
-        float norm = vectorNorm(&q[j][0], m);
-        if (norm < 0.000001f) {
-            // vectors are linearly dependent or zero so no solution
-#if DEBUG_STRATEGY
-            ALOGD("  - no solution, norm=%f", norm);
-#endif
-            return false;
-        }
-
-        float invNorm = 1.0f / norm;
-        for (uint32_t h = 0; h < m; h++) {
-            q[j][h] *= invNorm;
-        }
-        for (uint32_t i = 0; i < n; i++) {
-            r[j][i] = i < j ? 0 : vectorDot(&q[j][0], &a[i][0], m);
-        }
-    }
-#if DEBUG_STRATEGY
-    ALOGD("  - q=%s", matrixToString(&q[0][0], m, n, false /*rowMajor*/).string());
-    ALOGD("  - r=%s", matrixToString(&r[0][0], n, n, true /*rowMajor*/).string());
-
-    // calculate QR, if we factored A correctly then QR should equal A
-    float qr[n][m];
-    for (uint32_t h = 0; h < m; h++) {
-        for (uint32_t i = 0; i < n; i++) {
-            qr[i][h] = 0;
-            for (uint32_t j = 0; j < n; j++) {
-                qr[i][h] += q[j][h] * r[j][i];
-            }
-        }
-    }
-    ALOGD("  - qr=%s", matrixToString(&qr[0][0], m, n, false /*rowMajor*/).string());
-#endif
-
-    // Solve R B = Qt W Y to find B.  This is easy because R is upper triangular.
-    // We just work from bottom-right to top-left calculating B's coefficients.
-    float wy[m];
-    for (uint32_t h = 0; h < m; h++) {
-        wy[h] = y[h] * w[h];
-    }
-    for (uint32_t i = n; i-- != 0; ) {
-        outB[i] = vectorDot(&q[i][0], wy, m);
-        for (uint32_t j = n - 1; j > i; j--) {
-            outB[i] -= r[i][j] * outB[j];
-        }
-        outB[i] /= r[i][i];
-    }
-#if DEBUG_STRATEGY
-    ALOGD("  - b=%s", vectorToString(outB, n).string());
-#endif
-
-    // Calculate the coefficient of determination as 1 - (SSerr / SStot) where
-    // SSerr is the residual sum of squares (variance of the error),
-    // and SStot is the total sum of squares (variance of the data) where each
-    // has been weighted.
-    float ymean = 0;
-    for (uint32_t h = 0; h < m; h++) {
-        ymean += y[h];
-    }
-    ymean /= m;
-
-    float sserr = 0;
-    float sstot = 0;
-    for (uint32_t h = 0; h < m; h++) {
-        float err = y[h] - outB[0];
-        float term = 1;
-        for (uint32_t i = 1; i < n; i++) {
-            term *= x[h];
-            err -= term * outB[i];
-        }
-        sserr += w[h] * w[h] * err * err;
-        float var = y[h] - ymean;
-        sstot += w[h] * w[h] * var * var;
-    }
-    *outDet = sstot > 0.000001f ? 1.0f - (sserr / sstot) : 1;
-#if DEBUG_STRATEGY
-    ALOGD("  - sserr=%f", sserr);
-    ALOGD("  - sstot=%f", sstot);
-    ALOGD("  - det=%f", *outDet);
-#endif
-    return true;
-}
-
-bool LeastSquaresVelocityTrackerStrategy::getEstimator(uint32_t id,
-        VelocityTracker::Estimator* outEstimator) const {
-    outEstimator->clear();
-
-    // Iterate over movement samples in reverse time order and collect samples.
-    float x[HISTORY_SIZE];
-    float y[HISTORY_SIZE];
-    float w[HISTORY_SIZE];
-    float time[HISTORY_SIZE];
-    uint32_t m = 0;
-    uint32_t index = mIndex;
-    const Movement& newestMovement = mMovements[mIndex];
-    do {
-        const Movement& movement = mMovements[index];
-        if (!movement.idBits.hasBit(id)) {
-            break;
-        }
-
-        nsecs_t age = newestMovement.eventTime - movement.eventTime;
-        if (age > HORIZON) {
-            break;
-        }
-
-        const VelocityTracker::Position& position = movement.getPosition(id);
-        x[m] = position.x;
-        y[m] = position.y;
-        w[m] = chooseWeight(index);
-        time[m] = -age * 0.000000001f;
-        index = (index == 0 ? HISTORY_SIZE : index) - 1;
-    } while (++m < HISTORY_SIZE);
-
-    if (m == 0) {
-        return false; // no data
-    }
-
-    // Calculate a least squares polynomial fit.
-    uint32_t degree = mDegree;
-    if (degree > m - 1) {
-        degree = m - 1;
-    }
-    if (degree >= 1) {
-        float xdet, ydet;
-        uint32_t n = degree + 1;
-        if (solveLeastSquares(time, x, w, m, n, outEstimator->xCoeff, &xdet)
-                && solveLeastSquares(time, y, w, m, n, outEstimator->yCoeff, &ydet)) {
-            outEstimator->time = newestMovement.eventTime;
-            outEstimator->degree = degree;
-            outEstimator->confidence = xdet * ydet;
-#if DEBUG_STRATEGY
-            ALOGD("estimate: degree=%d, xCoeff=%s, yCoeff=%s, confidence=%f",
-                    int(outEstimator->degree),
-                    vectorToString(outEstimator->xCoeff, n).string(),
-                    vectorToString(outEstimator->yCoeff, n).string(),
-                    outEstimator->confidence);
-#endif
-            return true;
-        }
-    }
-
-    // No velocity data available for this pointer, but we do have its current position.
-    outEstimator->xCoeff[0] = x[0];
-    outEstimator->yCoeff[0] = y[0];
-    outEstimator->time = newestMovement.eventTime;
-    outEstimator->degree = 0;
-    outEstimator->confidence = 1;
-    return true;
-}
-
-float LeastSquaresVelocityTrackerStrategy::chooseWeight(uint32_t index) const {
-    switch (mWeighting) {
-    case WEIGHTING_DELTA: {
-        // Weight points based on how much time elapsed between them and the next
-        // point so that points that "cover" a shorter time span are weighed less.
-        //   delta  0ms: 0.5
-        //   delta 10ms: 1.0
-        if (index == mIndex) {
-            return 1.0f;
-        }
-        uint32_t nextIndex = (index + 1) % HISTORY_SIZE;
-        float deltaMillis = (mMovements[nextIndex].eventTime- mMovements[index].eventTime)
-                * 0.000001f;
-        if (deltaMillis < 0) {
-            return 0.5f;
-        }
-        if (deltaMillis < 10) {
-            return 0.5f + deltaMillis * 0.05;
-        }
-        return 1.0f;
-    }
-
-    case WEIGHTING_CENTRAL: {
-        // Weight points based on their age, weighing very recent and very old points less.
-        //   age  0ms: 0.5
-        //   age 10ms: 1.0
-        //   age 50ms: 1.0
-        //   age 60ms: 0.5
-        float ageMillis = (mMovements[mIndex].eventTime - mMovements[index].eventTime)
-                * 0.000001f;
-        if (ageMillis < 0) {
-            return 0.5f;
-        }
-        if (ageMillis < 10) {
-            return 0.5f + ageMillis * 0.05;
-        }
-        if (ageMillis < 50) {
-            return 1.0f;
-        }
-        if (ageMillis < 60) {
-            return 0.5f + (60 - ageMillis) * 0.05;
-        }
-        return 0.5f;
-    }
-
-    case WEIGHTING_RECENT: {
-        // Weight points based on their age, weighing older points less.
-        //   age   0ms: 1.0
-        //   age  50ms: 1.0
-        //   age 100ms: 0.5
-        float ageMillis = (mMovements[mIndex].eventTime - mMovements[index].eventTime)
-                * 0.000001f;
-        if (ageMillis < 50) {
-            return 1.0f;
-        }
-        if (ageMillis < 100) {
-            return 0.5f + (100 - ageMillis) * 0.01f;
-        }
-        return 0.5f;
-    }
-
-    case WEIGHTING_NONE:
-    default:
-        return 1.0f;
-    }
-}
-
-
-// --- IntegratingVelocityTrackerStrategy ---
-
-IntegratingVelocityTrackerStrategy::IntegratingVelocityTrackerStrategy(uint32_t degree) :
-        mDegree(degree) {
-}
-
-IntegratingVelocityTrackerStrategy::~IntegratingVelocityTrackerStrategy() {
-}
-
-void IntegratingVelocityTrackerStrategy::clear() {
-    mPointerIdBits.clear();
-}
-
-void IntegratingVelocityTrackerStrategy::clearPointers(BitSet32 idBits) {
-    mPointerIdBits.value &= ~idBits.value;
-}
-
-void IntegratingVelocityTrackerStrategy::addMovement(nsecs_t eventTime, BitSet32 idBits,
-        const VelocityTracker::Position* positions) {
-    uint32_t index = 0;
-    for (BitSet32 iterIdBits(idBits); !iterIdBits.isEmpty();) {
-        uint32_t id = iterIdBits.clearFirstMarkedBit();
-        State& state = mPointerState[id];
-        const VelocityTracker::Position& position = positions[index++];
-        if (mPointerIdBits.hasBit(id)) {
-            updateState(state, eventTime, position.x, position.y);
-        } else {
-            initState(state, eventTime, position.x, position.y);
-        }
-    }
-
-    mPointerIdBits = idBits;
-}
-
-bool IntegratingVelocityTrackerStrategy::getEstimator(uint32_t id,
-        VelocityTracker::Estimator* outEstimator) const {
-    outEstimator->clear();
-
-    if (mPointerIdBits.hasBit(id)) {
-        const State& state = mPointerState[id];
-        populateEstimator(state, outEstimator);
-        return true;
-    }
-
-    return false;
-}
-
-void IntegratingVelocityTrackerStrategy::initState(State& state,
-        nsecs_t eventTime, float xpos, float ypos) const {
-    state.updateTime = eventTime;
-    state.degree = 0;
-
-    state.xpos = xpos;
-    state.xvel = 0;
-    state.xaccel = 0;
-    state.ypos = ypos;
-    state.yvel = 0;
-    state.yaccel = 0;
-}
-
-void IntegratingVelocityTrackerStrategy::updateState(State& state,
-        nsecs_t eventTime, float xpos, float ypos) const {
-    const nsecs_t MIN_TIME_DELTA = 2 * NANOS_PER_MS;
-    const float FILTER_TIME_CONSTANT = 0.010f; // 10 milliseconds
-
-    if (eventTime <= state.updateTime + MIN_TIME_DELTA) {
-        return;
-    }
-
-    float dt = (eventTime - state.updateTime) * 0.000000001f;
-    state.updateTime = eventTime;
-
-    float xvel = (xpos - state.xpos) / dt;
-    float yvel = (ypos - state.ypos) / dt;
-    if (state.degree == 0) {
-        state.xvel = xvel;
-        state.yvel = yvel;
-        state.degree = 1;
-    } else {
-        float alpha = dt / (FILTER_TIME_CONSTANT + dt);
-        if (mDegree == 1) {
-            state.xvel += (xvel - state.xvel) * alpha;
-            state.yvel += (yvel - state.yvel) * alpha;
-        } else {
-            float xaccel = (xvel - state.xvel) / dt;
-            float yaccel = (yvel - state.yvel) / dt;
-            if (state.degree == 1) {
-                state.xaccel = xaccel;
-                state.yaccel = yaccel;
-                state.degree = 2;
-            } else {
-                state.xaccel += (xaccel - state.xaccel) * alpha;
-                state.yaccel += (yaccel - state.yaccel) * alpha;
-            }
-            state.xvel += (state.xaccel * dt) * alpha;
-            state.yvel += (state.yaccel * dt) * alpha;
-        }
-    }
-    state.xpos = xpos;
-    state.ypos = ypos;
-}
-
-void IntegratingVelocityTrackerStrategy::populateEstimator(const State& state,
-        VelocityTracker::Estimator* outEstimator) const {
-    outEstimator->time = state.updateTime;
-    outEstimator->confidence = 1.0f;
-    outEstimator->degree = state.degree;
-    outEstimator->xCoeff[0] = state.xpos;
-    outEstimator->xCoeff[1] = state.xvel;
-    outEstimator->xCoeff[2] = state.xaccel / 2;
-    outEstimator->yCoeff[0] = state.ypos;
-    outEstimator->yCoeff[1] = state.yvel;
-    outEstimator->yCoeff[2] = state.yaccel / 2;
-}
-
-
-// --- LegacyVelocityTrackerStrategy ---
-
-const nsecs_t LegacyVelocityTrackerStrategy::HORIZON;
-const uint32_t LegacyVelocityTrackerStrategy::HISTORY_SIZE;
-const nsecs_t LegacyVelocityTrackerStrategy::MIN_DURATION;
-
-LegacyVelocityTrackerStrategy::LegacyVelocityTrackerStrategy() {
-    clear();
-}
-
-LegacyVelocityTrackerStrategy::~LegacyVelocityTrackerStrategy() {
-}
-
-void LegacyVelocityTrackerStrategy::clear() {
-    mIndex = 0;
-    mMovements[0].idBits.clear();
-}
-
-void LegacyVelocityTrackerStrategy::clearPointers(BitSet32 idBits) {
-    BitSet32 remainingIdBits(mMovements[mIndex].idBits.value & ~idBits.value);
-    mMovements[mIndex].idBits = remainingIdBits;
-}
-
-void LegacyVelocityTrackerStrategy::addMovement(nsecs_t eventTime, BitSet32 idBits,
-        const VelocityTracker::Position* positions) {
-    if (++mIndex == HISTORY_SIZE) {
-        mIndex = 0;
-    }
-
-    Movement& movement = mMovements[mIndex];
-    movement.eventTime = eventTime;
-    movement.idBits = idBits;
-    uint32_t count = idBits.count();
-    for (uint32_t i = 0; i < count; i++) {
-        movement.positions[i] = positions[i];
-    }
-}
-
-bool LegacyVelocityTrackerStrategy::getEstimator(uint32_t id,
-        VelocityTracker::Estimator* outEstimator) const {
-    outEstimator->clear();
-
-    const Movement& newestMovement = mMovements[mIndex];
-    if (!newestMovement.idBits.hasBit(id)) {
-        return false; // no data
-    }
-
-    // Find the oldest sample that contains the pointer and that is not older than HORIZON.
-    nsecs_t minTime = newestMovement.eventTime - HORIZON;
-    uint32_t oldestIndex = mIndex;
-    uint32_t numTouches = 1;
-    do {
-        uint32_t nextOldestIndex = (oldestIndex == 0 ? HISTORY_SIZE : oldestIndex) - 1;
-        const Movement& nextOldestMovement = mMovements[nextOldestIndex];
-        if (!nextOldestMovement.idBits.hasBit(id)
-                || nextOldestMovement.eventTime < minTime) {
-            break;
-        }
-        oldestIndex = nextOldestIndex;
-    } while (++numTouches < HISTORY_SIZE);
-
-    // Calculate an exponentially weighted moving average of the velocity estimate
-    // at different points in time measured relative to the oldest sample.
-    // This is essentially an IIR filter.  Newer samples are weighted more heavily
-    // than older samples.  Samples at equal time points are weighted more or less
-    // equally.
-    //
-    // One tricky problem is that the sample data may be poorly conditioned.
-    // Sometimes samples arrive very close together in time which can cause us to
-    // overestimate the velocity at that time point.  Most samples might be measured
-    // 16ms apart but some consecutive samples could be only 0.5sm apart because
-    // the hardware or driver reports them irregularly or in bursts.
-    float accumVx = 0;
-    float accumVy = 0;
-    uint32_t index = oldestIndex;
-    uint32_t samplesUsed = 0;
-    const Movement& oldestMovement = mMovements[oldestIndex];
-    const VelocityTracker::Position& oldestPosition = oldestMovement.getPosition(id);
-    nsecs_t lastDuration = 0;
-
-    while (numTouches-- > 1) {
-        if (++index == HISTORY_SIZE) {
-            index = 0;
-        }
-        const Movement& movement = mMovements[index];
-        nsecs_t duration = movement.eventTime - oldestMovement.eventTime;
-
-        // If the duration between samples is small, we may significantly overestimate
-        // the velocity.  Consequently, we impose a minimum duration constraint on the
-        // samples that we include in the calculation.
-        if (duration >= MIN_DURATION) {
-            const VelocityTracker::Position& position = movement.getPosition(id);
-            float scale = 1000000000.0f / duration; // one over time delta in seconds
-            float vx = (position.x - oldestPosition.x) * scale;
-            float vy = (position.y - oldestPosition.y) * scale;
-            accumVx = (accumVx * lastDuration + vx * duration) / (duration + lastDuration);
-            accumVy = (accumVy * lastDuration + vy * duration) / (duration + lastDuration);
-            lastDuration = duration;
-            samplesUsed += 1;
-        }
-    }
-
-    // Report velocity.
-    const VelocityTracker::Position& newestPosition = newestMovement.getPosition(id);
-    outEstimator->time = newestMovement.eventTime;
-    outEstimator->confidence = 1;
-    outEstimator->xCoeff[0] = newestPosition.x;
-    outEstimator->yCoeff[0] = newestPosition.y;
-    if (samplesUsed) {
-        outEstimator->xCoeff[1] = accumVx;
-        outEstimator->yCoeff[1] = accumVy;
-        outEstimator->degree = 1;
-    } else {
-        outEstimator->degree = 0;
-    }
-    return true;
-}
-
-} // namespace android
diff --git a/libs/androidfw/VirtualKeyMap.cpp b/libs/androidfw/VirtualKeyMap.cpp
deleted file mode 100644
index 2ba1673..0000000
--- a/libs/androidfw/VirtualKeyMap.cpp
+++ /dev/null
@@ -1,171 +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.
- */
-
-#define LOG_TAG "VirtualKeyMap"
-
-#include <stdlib.h>
-#include <string.h>
-#include <androidfw/VirtualKeyMap.h>
-#include <utils/Log.h>
-#include <utils/Errors.h>
-#include <utils/Tokenizer.h>
-#include <utils/Timers.h>
-
-// Enables debug output for the parser.
-#define DEBUG_PARSER 0
-
-// Enables debug output for parser performance.
-#define DEBUG_PARSER_PERFORMANCE 0
-
-
-namespace android {
-
-static const char* WHITESPACE = " \t\r";
-static const char* WHITESPACE_OR_FIELD_DELIMITER = " \t\r:";
-
-
-// --- VirtualKeyMap ---
-
-VirtualKeyMap::VirtualKeyMap() {
-}
-
-VirtualKeyMap::~VirtualKeyMap() {
-}
-
-status_t VirtualKeyMap::load(const String8& filename, VirtualKeyMap** outMap) {
-    *outMap = NULL;
-
-    Tokenizer* tokenizer;
-    status_t status = Tokenizer::open(filename, &tokenizer);
-    if (status) {
-        ALOGE("Error %d opening virtual key map file %s.", status, filename.string());
-    } else {
-        VirtualKeyMap* map = new VirtualKeyMap();
-        if (!map) {
-            ALOGE("Error allocating virtual key map.");
-            status = NO_MEMORY;
-        } else {
-#if DEBUG_PARSER_PERFORMANCE
-            nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
-#endif
-            Parser parser(map, tokenizer);
-            status = parser.parse();
-#if DEBUG_PARSER_PERFORMANCE
-            nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
-            ALOGD("Parsed key character map file '%s' %d lines in %0.3fms.",
-                    tokenizer->getFilename().string(), tokenizer->getLineNumber(),
-                    elapsedTime / 1000000.0);
-#endif
-            if (status) {
-                delete map;
-            } else {
-                *outMap = map;
-            }
-        }
-        delete tokenizer;
-    }
-    return status;
-}
-
-
-// --- VirtualKeyMap::Parser ---
-
-VirtualKeyMap::Parser::Parser(VirtualKeyMap* map, Tokenizer* tokenizer) :
-        mMap(map), mTokenizer(tokenizer) {
-}
-
-VirtualKeyMap::Parser::~Parser() {
-}
-
-status_t VirtualKeyMap::Parser::parse() {
-    while (!mTokenizer->isEof()) {
-#if DEBUG_PARSER
-        ALOGD("Parsing %s: '%s'.", mTokenizer->getLocation().string(),
-                mTokenizer->peekRemainderOfLine().string());
-#endif
-
-        mTokenizer->skipDelimiters(WHITESPACE);
-
-        if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
-            // Multiple keys can appear on one line or they can be broken up across multiple lines.
-            do {
-                String8 token = mTokenizer->nextToken(WHITESPACE_OR_FIELD_DELIMITER);
-                if (token != "0x01") {
-                    ALOGE("%s: Unknown virtual key type, expected 0x01.",
-                          mTokenizer->getLocation().string());
-                    return BAD_VALUE;
-                }
-
-                VirtualKeyDefinition defn;
-                bool success = parseNextIntField(&defn.scanCode)
-                        && parseNextIntField(&defn.centerX)
-                        && parseNextIntField(&defn.centerY)
-                        && parseNextIntField(&defn.width)
-                        && parseNextIntField(&defn.height);
-                if (!success) {
-                    ALOGE("%s: Expected 5 colon-delimited integers in virtual key definition.",
-                          mTokenizer->getLocation().string());
-                    return BAD_VALUE;
-                }
-
-#if DEBUG_PARSER
-                ALOGD("Parsed virtual key: scanCode=%d, centerX=%d, centerY=%d, "
-                        "width=%d, height=%d",
-                        defn.scanCode, defn.centerX, defn.centerY, defn.width, defn.height);
-#endif
-                mMap->mVirtualKeys.push(defn);
-            } while (consumeFieldDelimiterAndSkipWhitespace());
-
-            if (!mTokenizer->isEol()) {
-                ALOGE("%s: Expected end of line, got '%s'.",
-                        mTokenizer->getLocation().string(),
-                        mTokenizer->peekRemainderOfLine().string());
-                return BAD_VALUE;
-            }
-        }
-
-        mTokenizer->nextLine();
-    }
-
-    return NO_ERROR;
-}
-
-bool VirtualKeyMap::Parser::consumeFieldDelimiterAndSkipWhitespace() {
-    mTokenizer->skipDelimiters(WHITESPACE);
-    if (mTokenizer->peekChar() == ':') {
-        mTokenizer->nextChar();
-        mTokenizer->skipDelimiters(WHITESPACE);
-        return true;
-    }
-    return false;
-}
-
-bool VirtualKeyMap::Parser::parseNextIntField(int32_t* outValue) {
-    if (!consumeFieldDelimiterAndSkipWhitespace()) {
-        return false;
-    }
-
-    String8 token = mTokenizer->nextToken(WHITESPACE_OR_FIELD_DELIMITER);
-    char* end;
-    *outValue = strtol(token.string(), &end, 0);
-    if (token.isEmpty() || *end != '\0') {
-        ALOGE("Expected an integer, got '%s'.", token.string());
-        return false;
-    }
-    return true;
-}
-
-} // namespace android
diff --git a/libs/androidfw/ZipFileRO.cpp b/libs/androidfw/ZipFileRO.cpp
new file mode 100644
index 0000000..ec5f95c
--- /dev/null
+++ b/libs/androidfw/ZipFileRO.cpp
@@ -0,0 +1,995 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Read-only access to Zip archives, with minimal heap allocation.
+//
+#define LOG_TAG "zipro"
+//#define LOG_NDEBUG 0
+#include <androidfw/ZipFileRO.h>
+#include <utils/Log.h>
+#include <utils/Compat.h>
+#include <utils/misc.h>
+#include <utils/threads.h>
+
+#include <zlib.h>
+
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <assert.h>
+#include <unistd.h>
+
+/*
+ * We must open binary files using open(path, ... | O_BINARY) under Windows.
+ * Otherwise strange read errors will happen.
+ */
+#ifndef O_BINARY
+#  define O_BINARY  0
+#endif
+
+using namespace android;
+
+/*
+ * Zip file constants.
+ */
+#define kEOCDSignature       0x06054b50
+#define kEOCDLen             22
+#define kEOCDDiskNumber      4               // number of the current disk
+#define kEOCDDiskNumberForCD 6               // disk number with the Central Directory
+#define kEOCDNumEntries      8               // offset to #of entries in file
+#define kEOCDTotalNumEntries 10              // offset to total #of entries in spanned archives
+#define kEOCDSize            12              // size of the central directory
+#define kEOCDFileOffset      16              // offset to central directory
+#define kEOCDCommentSize     20              // offset to the length of the file comment
+
+#define kMaxCommentLen       65535           // longest possible in ushort
+#define kMaxEOCDSearch       (kMaxCommentLen + kEOCDLen)
+
+#define kLFHSignature        0x04034b50
+#define kLFHLen              30              // excluding variable-len fields
+#define kLFHGPBFlags          6              // offset to GPB flags
+#define kLFHNameLen          26              // offset to filename length
+#define kLFHExtraLen         28              // offset to extra length
+
+#define kCDESignature        0x02014b50
+#define kCDELen              46              // excluding variable-len fields
+#define kCDEGPBFlags          8              // offset to GPB flags
+#define kCDEMethod           10              // offset to compression method
+#define kCDEModWhen          12              // offset to modification timestamp
+#define kCDECRC              16              // offset to entry CRC
+#define kCDECompLen          20              // offset to compressed length
+#define kCDEUncompLen        24              // offset to uncompressed length
+#define kCDENameLen          28              // offset to filename length
+#define kCDEExtraLen         30              // offset to extra length
+#define kCDECommentLen       32              // offset to comment length
+#define kCDELocalOffset      42              // offset to local hdr
+
+/* General Purpose Bit Flag */
+#define kGPFEncryptedFlag    (1 << 0)
+#define kGPFUnsupportedMask  (kGPFEncryptedFlag)
+
+/*
+ * The values we return for ZipEntryRO use 0 as an invalid value, so we
+ * want to adjust the hash table index by a fixed amount.  Using a large
+ * value helps insure that people don't mix & match arguments, e.g. to
+ * findEntryByIndex().
+ */
+#define kZipEntryAdj        10000
+
+ZipFileRO::~ZipFileRO() {
+    free(mHashTable);
+    if (mDirectoryMap)
+        mDirectoryMap->release();
+    if (mFd >= 0)
+        TEMP_FAILURE_RETRY(close(mFd));
+    if (mFileName)
+        free(mFileName);
+}
+
+/*
+ * Convert a ZipEntryRO to a hash table index, verifying that it's in a
+ * valid range.
+ */
+int ZipFileRO::entryToIndex(const ZipEntryRO entry) const
+{
+    long ent = ((intptr_t) entry) - kZipEntryAdj;
+    if (ent < 0 || ent >= mHashTableSize || mHashTable[ent].name == NULL) {
+        ALOGW("Invalid ZipEntryRO %p (%ld)\n", entry, ent);
+        return -1;
+    }
+    return ent;
+}
+
+
+/*
+ * Open the specified file read-only.  We memory-map the entire thing and
+ * close the file before returning.
+ */
+status_t ZipFileRO::open(const char* zipFileName)
+{
+    int fd = -1;
+
+    assert(mDirectoryMap == NULL);
+
+    /*
+     * Open and map the specified file.
+     */
+    fd = TEMP_FAILURE_RETRY(::open(zipFileName, O_RDONLY | O_BINARY));
+    if (fd < 0) {
+        ALOGW("Unable to open zip '%s': %s\n", zipFileName, strerror(errno));
+        return NAME_NOT_FOUND;
+    }
+
+    mFileLength = lseek64(fd, 0, SEEK_END);
+    if (mFileLength < kEOCDLen) {
+        TEMP_FAILURE_RETRY(close(fd));
+        return UNKNOWN_ERROR;
+    }
+
+    if (mFileName != NULL) {
+        free(mFileName);
+    }
+    mFileName = strdup(zipFileName);
+
+    mFd = fd;
+
+    /*
+     * Find the Central Directory and store its size and number of entries.
+     */
+    if (!mapCentralDirectory()) {
+        goto bail;
+    }
+
+    /*
+     * Verify Central Directory and create data structures for fast access.
+     */
+    if (!parseZipArchive()) {
+        goto bail;
+    }
+
+    return OK;
+
+bail:
+    free(mFileName);
+    mFileName = NULL;
+    TEMP_FAILURE_RETRY(close(fd));
+    return UNKNOWN_ERROR;
+}
+
+/*
+ * Parse the Zip archive, verifying its contents and initializing internal
+ * data structures.
+ */
+bool ZipFileRO::mapCentralDirectory(void)
+{
+    ssize_t readAmount = kMaxEOCDSearch;
+    if (readAmount > (ssize_t) mFileLength)
+        readAmount = mFileLength;
+
+    if (readAmount < kEOCDSize) {
+        ALOGW("File too short to be a zip file");
+        return false;
+    }
+
+    unsigned char* scanBuf = (unsigned char*) malloc(readAmount);
+    if (scanBuf == NULL) {
+        ALOGW("couldn't allocate scanBuf: %s", strerror(errno));
+        free(scanBuf);
+        return false;
+    }
+
+    /*
+     * Make sure this is a Zip archive.
+     */
+    if (lseek64(mFd, 0, SEEK_SET) != 0) {
+        ALOGW("seek to start failed: %s", strerror(errno));
+        free(scanBuf);
+        return false;
+    }
+
+    ssize_t actual = TEMP_FAILURE_RETRY(read(mFd, scanBuf, sizeof(int32_t)));
+    if (actual != (ssize_t) sizeof(int32_t)) {
+        ALOGI("couldn't read first signature from zip archive: %s", strerror(errno));
+        free(scanBuf);
+        return false;
+    }
+
+    unsigned int header = get4LE(scanBuf);
+    if (header != kLFHSignature) {
+        ALOGV("Not a Zip archive (found 0x%08x)\n", header);
+        free(scanBuf);
+        return false;
+    }
+
+    /*
+     * Perform the traditional EOCD snipe hunt.
+     *
+     * We're searching for the End of Central Directory magic number,
+     * which appears at the start of the EOCD block.  It's followed by
+     * 18 bytes of EOCD stuff and up to 64KB of archive comment.  We
+     * need to read the last part of the file into a buffer, dig through
+     * it to find the magic number, parse some values out, and use those
+     * to determine the extent of the CD.
+     *
+     * We start by pulling in the last part of the file.
+     */
+    off64_t searchStart = mFileLength - readAmount;
+
+    if (lseek64(mFd, searchStart, SEEK_SET) != searchStart) {
+        ALOGW("seek %ld failed: %s\n",  (long) searchStart, strerror(errno));
+        free(scanBuf);
+        return false;
+    }
+    actual = TEMP_FAILURE_RETRY(read(mFd, scanBuf, readAmount));
+    if (actual != (ssize_t) readAmount) {
+        ALOGW("Zip: read " ZD ", expected " ZD ". Failed: %s\n",
+            (ZD_TYPE) actual, (ZD_TYPE) readAmount, strerror(errno));
+        free(scanBuf);
+        return false;
+    }
+
+    /*
+     * Scan backward for the EOCD magic.  In an archive without a trailing
+     * comment, we'll find it on the first try.  (We may want to consider
+     * doing an initial minimal read; if we don't find it, retry with a
+     * second read as above.)
+     */
+    int i;
+    for (i = readAmount - kEOCDLen; i >= 0; i--) {
+        if (scanBuf[i] == 0x50 && get4LE(&scanBuf[i]) == kEOCDSignature) {
+            ALOGV("+++ Found EOCD at buf+%d\n", i);
+            break;
+        }
+    }
+    if (i < 0) {
+        ALOGD("Zip: EOCD not found, %s is not zip\n", mFileName);
+        free(scanBuf);
+        return false;
+    }
+
+    off64_t eocdOffset = searchStart + i;
+    const unsigned char* eocdPtr = scanBuf + i;
+
+    assert(eocdOffset < mFileLength);
+
+    /*
+     * Grab the CD offset and size, and the number of entries in the
+     * archive. After that, we can release our EOCD hunt buffer.
+     */
+    unsigned int diskNumber = get2LE(eocdPtr + kEOCDDiskNumber);
+    unsigned int diskWithCentralDir = get2LE(eocdPtr + kEOCDDiskNumberForCD);
+    unsigned int numEntries = get2LE(eocdPtr + kEOCDNumEntries);
+    unsigned int totalNumEntries = get2LE(eocdPtr + kEOCDTotalNumEntries);
+    unsigned int centralDirSize = get4LE(eocdPtr + kEOCDSize);
+    unsigned int centralDirOffset = get4LE(eocdPtr + kEOCDFileOffset);
+    unsigned int commentSize = get2LE(eocdPtr + kEOCDCommentSize);
+    free(scanBuf);
+
+    // Verify that they look reasonable.
+    if ((long long) centralDirOffset + (long long) centralDirSize > (long long) eocdOffset) {
+        ALOGW("bad offsets (dir %ld, size %u, eocd %ld)\n",
+            (long) centralDirOffset, centralDirSize, (long) eocdOffset);
+        return false;
+    }
+    if (numEntries == 0) {
+        ALOGW("empty archive?\n");
+        return false;
+    } else if (numEntries != totalNumEntries || diskNumber != 0 || diskWithCentralDir != 0) {
+        ALOGW("spanned archives not supported");
+        return false;
+    }
+
+    // Check to see if comment is a sane size
+    if ((commentSize > (mFileLength - kEOCDLen))
+            || (eocdOffset > (mFileLength - kEOCDLen) - commentSize)) {
+        ALOGW("comment size runs off end of file");
+        return false;
+    }
+
+    ALOGV("+++ numEntries=%d dirSize=%d dirOffset=%d\n",
+        numEntries, centralDirSize, centralDirOffset);
+
+    mDirectoryMap = new FileMap();
+    if (mDirectoryMap == NULL) {
+        ALOGW("Unable to create directory map: %s", strerror(errno));
+        return false;
+    }
+
+    if (!mDirectoryMap->create(mFileName, mFd, centralDirOffset, centralDirSize, true)) {
+        ALOGW("Unable to map '%s' (" ZD " to " ZD "): %s\n", mFileName,
+                (ZD_TYPE) centralDirOffset, (ZD_TYPE) (centralDirOffset + centralDirSize), strerror(errno));
+        return false;
+    }
+
+    mNumEntries = numEntries;
+    mDirectoryOffset = centralDirOffset;
+
+    return true;
+}
+
+
+/*
+ * Round up to the next highest power of 2.
+ *
+ * Found on http://graphics.stanford.edu/~seander/bithacks.html.
+ */
+static unsigned int roundUpPower2(unsigned int val)
+{
+    val--;
+    val |= val >> 1;
+    val |= val >> 2;
+    val |= val >> 4;
+    val |= val >> 8;
+    val |= val >> 16;
+    val++;
+
+    return val;
+}
+
+bool ZipFileRO::parseZipArchive(void)
+{
+    bool result = false;
+    const unsigned char* cdPtr = (const unsigned char*) mDirectoryMap->getDataPtr();
+    size_t cdLength = mDirectoryMap->getDataLength();
+    int numEntries = mNumEntries;
+
+    /*
+     * Create hash table.  We have a minimum 75% load factor, possibly as
+     * low as 50% after we round off to a power of 2.
+     */
+    mHashTableSize = roundUpPower2(1 + (numEntries * 4) / 3);
+    mHashTable = (HashEntry*) calloc(mHashTableSize, sizeof(HashEntry));
+
+    /*
+     * Walk through the central directory, adding entries to the hash
+     * table.
+     */
+    const unsigned char* ptr = cdPtr;
+    for (int i = 0; i < numEntries; i++) {
+        if (get4LE(ptr) != kCDESignature) {
+            ALOGW("Missed a central dir sig (at %d)\n", i);
+            goto bail;
+        }
+        if (ptr + kCDELen > cdPtr + cdLength) {
+            ALOGW("Ran off the end (at %d)\n", i);
+            goto bail;
+        }
+
+        long localHdrOffset = (long) get4LE(ptr + kCDELocalOffset);
+        if (localHdrOffset >= mDirectoryOffset) {
+            ALOGW("bad LFH offset %ld at entry %d\n", localHdrOffset, i);
+            goto bail;
+        }
+
+        unsigned int gpbf = get2LE(ptr + kCDEGPBFlags);
+        if ((gpbf & kGPFUnsupportedMask) != 0) {
+            ALOGW("Invalid General Purpose Bit Flag: %d", gpbf);
+            goto bail;
+        }
+
+        unsigned int nameLen = get2LE(ptr + kCDENameLen);
+        unsigned int extraLen = get2LE(ptr + kCDEExtraLen);
+        unsigned int commentLen = get2LE(ptr + kCDECommentLen);
+
+        const char *name = (const char *) ptr + kCDELen;
+
+        /* Check name for NULL characters */
+        if (memchr(name, 0, nameLen) != NULL) {
+            ALOGW("Filename contains NUL byte");
+            goto bail;
+        }
+
+        /* add the CDE filename to the hash table */
+        unsigned int hash = computeHash(name, nameLen);
+        addToHash(name, nameLen, hash);
+
+        /* We don't care about the comment or extra data. */
+        ptr += kCDELen + nameLen + extraLen + commentLen;
+        if ((size_t)(ptr - cdPtr) > cdLength) {
+            ALOGW("bad CD advance (%d vs " ZD ") at entry %d\n",
+                (int) (ptr - cdPtr), (ZD_TYPE) cdLength, i);
+            goto bail;
+        }
+    }
+    ALOGV("+++ zip good scan %d entries\n", numEntries);
+    result = true;
+
+bail:
+    return result;
+}
+
+/*
+ * Simple string hash function for non-null-terminated strings.
+ */
+/*static*/ unsigned int ZipFileRO::computeHash(const char* str, int len)
+{
+    unsigned int hash = 0;
+
+    while (len--)
+        hash = hash * 31 + *str++;
+
+    return hash;
+}
+
+/*
+ * Add a new entry to the hash table.
+ */
+void ZipFileRO::addToHash(const char* str, int strLen, unsigned int hash)
+{
+    int ent = hash & (mHashTableSize-1);
+
+    /*
+     * We over-allocate the table, so we're guaranteed to find an empty slot.
+     */
+    while (mHashTable[ent].name != NULL)
+        ent = (ent + 1) & (mHashTableSize-1);
+
+    mHashTable[ent].name = str;
+    mHashTable[ent].nameLen = strLen;
+}
+
+/*
+ * Find a matching entry.
+ *
+ * Returns NULL if not found.
+ */
+ZipEntryRO ZipFileRO::findEntryByName(const char* fileName) const
+{
+    /*
+     * If the ZipFileRO instance is not initialized, the entry number will
+     * end up being garbage since mHashTableSize is -1.
+     */
+    if (mHashTableSize <= 0) {
+        return NULL;
+    }
+
+    int nameLen = strlen(fileName);
+    unsigned int hash = computeHash(fileName, nameLen);
+    int ent = hash & (mHashTableSize-1);
+
+    while (mHashTable[ent].name != NULL) {
+        if (mHashTable[ent].nameLen == nameLen &&
+            memcmp(mHashTable[ent].name, fileName, nameLen) == 0)
+        {
+            /* match */
+            return (ZipEntryRO)(long)(ent + kZipEntryAdj);
+        }
+
+        ent = (ent + 1) & (mHashTableSize-1);
+    }
+
+    return NULL;
+}
+
+/*
+ * Find the Nth entry.
+ *
+ * This currently involves walking through the sparse hash table, counting
+ * non-empty entries.  If we need to speed this up we can either allocate
+ * a parallel lookup table or (perhaps better) provide an iterator interface.
+ */
+ZipEntryRO ZipFileRO::findEntryByIndex(int idx) const
+{
+    if (idx < 0 || idx >= mNumEntries) {
+        ALOGW("Invalid index %d\n", idx);
+        return NULL;
+    }
+
+    for (int ent = 0; ent < mHashTableSize; ent++) {
+        if (mHashTable[ent].name != NULL) {
+            if (idx-- == 0)
+                return (ZipEntryRO) (intptr_t)(ent + kZipEntryAdj);
+        }
+    }
+
+    return NULL;
+}
+
+/*
+ * Get the useful fields from the zip entry.
+ *
+ * Returns "false" if the offsets to the fields or the contents of the fields
+ * appear to be bogus.
+ */
+bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
+    size_t* pCompLen, off64_t* pOffset, long* pModWhen, long* pCrc32) const
+{
+    bool ret = false;
+
+    const int ent = entryToIndex(entry);
+    if (ent < 0) {
+        ALOGW("cannot find entry");
+        return false;
+    }
+
+    HashEntry hashEntry = mHashTable[ent];
+
+    /*
+     * Recover the start of the central directory entry from the filename
+     * pointer.  The filename is the first entry past the fixed-size data,
+     * so we can just subtract back from that.
+     */
+    const unsigned char* ptr = (const unsigned char*) hashEntry.name;
+    off64_t cdOffset = mDirectoryOffset;
+
+    ptr -= kCDELen;
+
+    int method = get2LE(ptr + kCDEMethod);
+    if (pMethod != NULL)
+        *pMethod = method;
+
+    if (pModWhen != NULL)
+        *pModWhen = get4LE(ptr + kCDEModWhen);
+    if (pCrc32 != NULL)
+        *pCrc32 = get4LE(ptr + kCDECRC);
+
+    size_t compLen = get4LE(ptr + kCDECompLen);
+    if (pCompLen != NULL)
+        *pCompLen = compLen;
+    size_t uncompLen = get4LE(ptr + kCDEUncompLen);
+    if (pUncompLen != NULL)
+        *pUncompLen = uncompLen;
+
+    /*
+     * If requested, determine the offset of the start of the data.  All we
+     * have is the offset to the Local File Header, which is variable size,
+     * so we have to read the contents of the struct to figure out where
+     * the actual data starts.
+     *
+     * We also need to make sure that the lengths are not so large that
+     * somebody trying to map the compressed or uncompressed data runs
+     * off the end of the mapped region.
+     *
+     * Note we don't verify compLen/uncompLen if they don't request the
+     * dataOffset, because dataOffset is expensive to determine.  However,
+     * if they don't have the file offset, they're not likely to be doing
+     * anything with the contents.
+     */
+    if (pOffset != NULL) {
+        long localHdrOffset = get4LE(ptr + kCDELocalOffset);
+        if (localHdrOffset + kLFHLen >= cdOffset) {
+            ALOGE("ERROR: bad local hdr offset in zip\n");
+            return false;
+        }
+
+        unsigned char lfhBuf[kLFHLen];
+
+#ifdef HAVE_PREAD
+        /*
+         * This file descriptor might be from zygote's preloaded assets,
+         * so we need to do an pread64() instead of a lseek64() + read() to
+         * guarantee atomicity across the processes with the shared file
+         * descriptors.
+         */
+        ssize_t actual =
+                TEMP_FAILURE_RETRY(pread64(mFd, lfhBuf, sizeof(lfhBuf), localHdrOffset));
+
+        if (actual != sizeof(lfhBuf)) {
+            ALOGW("failed reading lfh from offset %ld\n", localHdrOffset);
+            return false;
+        }
+
+        if (get4LE(lfhBuf) != kLFHSignature) {
+            ALOGW("didn't find signature at start of lfh; wanted: offset=%ld data=0x%08x; "
+                    "got: data=0x%08lx\n",
+                    localHdrOffset, kLFHSignature, get4LE(lfhBuf));
+            return false;
+        }
+#else /* HAVE_PREAD */
+        /*
+         * For hosts don't have pread64() we cannot guarantee atomic reads from
+         * an offset in a file. Android should never run on those platforms.
+         * File descriptors inherited from a fork() share file offsets and
+         * there would be nothing to protect from two different processes
+         * calling lseek64() concurrently.
+         */
+
+        {
+            AutoMutex _l(mFdLock);
+
+            if (lseek64(mFd, localHdrOffset, SEEK_SET) != localHdrOffset) {
+                ALOGW("failed seeking to lfh at offset %ld\n", localHdrOffset);
+                return false;
+            }
+
+            ssize_t actual =
+                    TEMP_FAILURE_RETRY(read(mFd, lfhBuf, sizeof(lfhBuf)));
+            if (actual != sizeof(lfhBuf)) {
+                ALOGW("failed reading lfh from offset %ld\n", localHdrOffset);
+                return false;
+            }
+
+            if (get4LE(lfhBuf) != kLFHSignature) {
+                off64_t actualOffset = lseek64(mFd, 0, SEEK_CUR);
+                ALOGW("didn't find signature at start of lfh; wanted: offset=%ld data=0x%08x; "
+                        "got: offset=" ZD " data=0x%08lx\n",
+                        localHdrOffset, kLFHSignature, (ZD_TYPE) actualOffset, get4LE(lfhBuf));
+                return false;
+            }
+        }
+#endif /* HAVE_PREAD */
+
+        unsigned int gpbf = get2LE(lfhBuf + kLFHGPBFlags);
+        if ((gpbf & kGPFUnsupportedMask) != 0) {
+            ALOGW("Invalid General Purpose Bit Flag: %d", gpbf);
+            return false;
+        }
+
+        off64_t dataOffset = localHdrOffset + kLFHLen
+            + get2LE(lfhBuf + kLFHNameLen) + get2LE(lfhBuf + kLFHExtraLen);
+        if (dataOffset >= cdOffset) {
+            ALOGW("bad data offset %ld in zip\n", (long) dataOffset);
+            return false;
+        }
+
+        /* check lengths */
+        if ((dataOffset >= cdOffset) || (compLen > (cdOffset - dataOffset))) {
+            ALOGW("bad compressed length in zip (%ld + " ZD " > %ld)\n",
+                (long) dataOffset, (ZD_TYPE) compLen, (long) cdOffset);
+            return false;
+        }
+
+        if (method == kCompressStored &&
+            ((dataOffset >= cdOffset) ||
+             (uncompLen > (cdOffset - dataOffset))))
+        {
+            ALOGE("ERROR: bad uncompressed length in zip (%ld + " ZD " > %ld)\n",
+                (long) dataOffset, (ZD_TYPE) uncompLen, (long) cdOffset);
+            return false;
+        }
+
+        *pOffset = dataOffset;
+    }
+
+    return true;
+}
+
+/*
+ * Copy the entry's filename to the buffer.
+ */
+int ZipFileRO::getEntryFileName(ZipEntryRO entry, char* buffer, int bufLen)
+    const
+{
+    int ent = entryToIndex(entry);
+    if (ent < 0)
+        return -1;
+
+    int nameLen = mHashTable[ent].nameLen;
+    if (bufLen < nameLen+1)
+        return nameLen+1;
+
+    memcpy(buffer, mHashTable[ent].name, nameLen);
+    buffer[nameLen] = '\0';
+    return 0;
+}
+
+/*
+ * Create a new FileMap object that spans the data in "entry".
+ */
+FileMap* ZipFileRO::createEntryFileMap(ZipEntryRO entry) const
+{
+    /*
+     * TODO: the efficient way to do this is to modify FileMap to allow
+     * sub-regions of a file to be mapped.  A reference-counting scheme
+     * can manage the base memory mapping.  For now, we just create a brand
+     * new mapping off of the Zip archive file descriptor.
+     */
+
+    FileMap* newMap;
+    int method;
+    size_t uncompLen;
+    size_t compLen;
+    off64_t offset;
+
+    if (!getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL)) {
+        return NULL;
+    }
+
+    size_t actualLen;
+    if (method == kCompressStored) {
+        actualLen = uncompLen;
+    } else {
+        actualLen = compLen;
+    }
+
+    newMap = new FileMap();
+    if (!newMap->create(mFileName, mFd, offset, actualLen, true)) {
+        newMap->release();
+        return NULL;
+    }
+
+    return newMap;
+}
+
+/*
+ * Uncompress an entry, in its entirety, into the provided output buffer.
+ *
+ * This doesn't verify the data's CRC, which might be useful for
+ * uncompressed data.  The caller should be able to manage it.
+ */
+bool ZipFileRO::uncompressEntry(ZipEntryRO entry, void* buffer) const
+{
+    const size_t kSequentialMin = 32768;
+    bool result = false;
+    int ent = entryToIndex(entry);
+    if (ent < 0) {
+        return false;
+    }
+
+    int method;
+    size_t uncompLen, compLen;
+    off64_t offset;
+    const unsigned char* ptr;
+    FileMap *file;
+
+    if (!getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL)) {
+        goto bail;
+    }
+
+    file = createEntryFileMap(entry);
+    if (file == NULL) {
+        goto bail;
+    }
+
+    ptr = (const unsigned char*) file->getDataPtr();
+
+    /*
+     * Experiment with madvise hint.  When we want to uncompress a file,
+     * we pull some stuff out of the central dir entry and then hit a
+     * bunch of compressed or uncompressed data sequentially.  The CDE
+     * visit will cause a limited amount of read-ahead because it's at
+     * the end of the file.  We could end up doing lots of extra disk
+     * access if the file we're prying open is small.  Bottom line is we
+     * probably don't want to turn MADV_SEQUENTIAL on and leave it on.
+     *
+     * So, if the compressed size of the file is above a certain minimum
+     * size, temporarily boost the read-ahead in the hope that the extra
+     * pair of system calls are negated by a reduction in page faults.
+     */
+    if (compLen > kSequentialMin)
+        file->advise(FileMap::SEQUENTIAL);
+
+    if (method == kCompressStored) {
+        memcpy(buffer, ptr, uncompLen);
+    } else {
+        if (!inflateBuffer(buffer, ptr, uncompLen, compLen))
+            goto unmap;
+    }
+
+    if (compLen > kSequentialMin)
+        file->advise(FileMap::NORMAL);
+
+    result = true;
+
+unmap:
+    file->release();
+bail:
+    return result;
+}
+
+/*
+ * Uncompress an entry, in its entirety, to an open file descriptor.
+ *
+ * This doesn't verify the data's CRC, but probably should.
+ */
+bool ZipFileRO::uncompressEntry(ZipEntryRO entry, int fd) const
+{
+    bool result = false;
+    int ent = entryToIndex(entry);
+    if (ent < 0) {
+        return false;
+    }
+
+    int method;
+    size_t uncompLen, compLen;
+    off64_t offset;
+    const unsigned char* ptr;
+    FileMap *file;
+
+    if (!getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL)) {
+        goto bail;
+    }
+
+    file = createEntryFileMap(entry);
+    if (file == NULL) {
+        goto bail;
+    }
+
+    ptr = (const unsigned char*) file->getDataPtr();
+
+    if (method == kCompressStored) {
+        ssize_t actual = TEMP_FAILURE_RETRY(write(fd, ptr, uncompLen));
+        if (actual < 0) {
+            ALOGE("Write failed: %s\n", strerror(errno));
+            goto unmap;
+        } else if ((size_t) actual != uncompLen) {
+            ALOGE("Partial write during uncompress (" ZD " of " ZD ")\n",
+                (ZD_TYPE) actual, (ZD_TYPE) uncompLen);
+            goto unmap;
+        } else {
+            ALOGI("+++ successful write\n");
+        }
+    } else {
+        if (!inflateBuffer(fd, ptr, uncompLen, compLen)) {
+            goto unmap;
+        }
+    }
+
+    result = true;
+
+unmap:
+    file->release();
+bail:
+    return result;
+}
+
+/*
+ * Uncompress "deflate" data from one buffer to another.
+ */
+/*static*/ bool ZipFileRO::inflateBuffer(void* outBuf, const void* inBuf,
+    size_t uncompLen, size_t compLen)
+{
+    bool result = false;
+    z_stream zstream;
+    int zerr;
+
+    /*
+     * Initialize the zlib stream struct.
+     */
+    memset(&zstream, 0, sizeof(zstream));
+    zstream.zalloc = Z_NULL;
+    zstream.zfree = Z_NULL;
+    zstream.opaque = Z_NULL;
+    zstream.next_in = (Bytef*)inBuf;
+    zstream.avail_in = compLen;
+    zstream.next_out = (Bytef*) outBuf;
+    zstream.avail_out = uncompLen;
+    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;
+    }
+
+    /*
+     * Expand data.
+     */
+    zerr = inflate(&zstream, Z_FINISH);
+    if (zerr != Z_STREAM_END) {
+        ALOGW("Zip inflate failed, zerr=%d (nIn=%p aIn=%u nOut=%p aOut=%u)\n",
+            zerr, zstream.next_in, zstream.avail_in,
+            zstream.next_out, zstream.avail_out);
+        goto z_bail;
+    }
+
+    /* paranoia */
+    if (zstream.total_out != uncompLen) {
+        ALOGW("Size mismatch on inflated file (%ld vs " ZD ")\n",
+            zstream.total_out, (ZD_TYPE) uncompLen);
+        goto z_bail;
+    }
+
+    result = true;
+
+z_bail:
+    inflateEnd(&zstream);        /* free up any allocated structures */
+
+bail:
+    return result;
+}
+
+/*
+ * Uncompress "deflate" data from one buffer to an open file descriptor.
+ */
+/*static*/ bool ZipFileRO::inflateBuffer(int fd, const void* inBuf,
+    size_t uncompLen, size_t compLen)
+{
+    bool result = false;
+    const size_t kWriteBufSize = 32768;
+    unsigned char writeBuf[kWriteBufSize];
+    z_stream zstream;
+    int zerr;
+
+    /*
+     * Initialize the zlib stream struct.
+     */
+    memset(&zstream, 0, sizeof(zstream));
+    zstream.zalloc = Z_NULL;
+    zstream.zfree = Z_NULL;
+    zstream.opaque = Z_NULL;
+    zstream.next_in = (Bytef*)inBuf;
+    zstream.avail_in = compLen;
+    zstream.next_out = (Bytef*) writeBuf;
+    zstream.avail_out = sizeof(writeBuf);
+    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;
+    }
+
+    /*
+     * Loop while we have more to do.
+     */
+    do {
+        /*
+         * Expand data.
+         */
+        zerr = inflate(&zstream, Z_NO_FLUSH);
+        if (zerr != Z_OK && zerr != Z_STREAM_END) {
+            ALOGW("zlib inflate: zerr=%d (nIn=%p aIn=%u nOut=%p aOut=%u)\n",
+                zerr, zstream.next_in, zstream.avail_in,
+                zstream.next_out, zstream.avail_out);
+            goto z_bail;
+        }
+
+        /* write when we're full or when we're done */
+        if (zstream.avail_out == 0 ||
+            (zerr == Z_STREAM_END && zstream.avail_out != sizeof(writeBuf)))
+        {
+            long writeSize = zstream.next_out - writeBuf;
+            int cc = TEMP_FAILURE_RETRY(write(fd, writeBuf, writeSize));
+            if (cc < 0) {
+                ALOGW("write failed in inflate: %s", strerror(errno));
+                goto z_bail;
+            } else if (cc != (int) writeSize) {
+                ALOGW("write failed in inflate (%d vs %ld)", cc, writeSize);
+                goto z_bail;
+            }
+
+            zstream.next_out = writeBuf;
+            zstream.avail_out = sizeof(writeBuf);
+        }
+    } while (zerr == Z_OK);
+
+    assert(zerr == Z_STREAM_END);       /* other errors should've been caught */
+
+    /* paranoia */
+    if (zstream.total_out != uncompLen) {
+        ALOGW("Size mismatch on inflated file (%ld vs " ZD ")\n",
+            zstream.total_out, (ZD_TYPE) uncompLen);
+        goto z_bail;
+    }
+
+    result = true;
+
+z_bail:
+    inflateEnd(&zstream);        /* free up any allocated structures */
+
+bail:
+    return result;
+}
diff --git a/libs/androidfw/ZipUtils.cpp b/libs/androidfw/ZipUtils.cpp
new file mode 100644
index 0000000..997eb7d
--- /dev/null
+++ b/libs/androidfw/ZipUtils.cpp
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Misc zip/gzip utility functions.
+//
+
+#define LOG_TAG "ziputil"
+
+#include <androidfw/ZipUtils.h>
+#include <androidfw/ZipFileRO.h>
+#include <utils/Log.h>
+#include <utils/Compat.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include <zlib.h>
+
+using namespace android;
+
+/*
+ * Utility function that expands zip/gzip "deflate" compressed data
+ * into a buffer.
+ *
+ * "fd" is an open file positioned at the start of the "deflate" data
+ * "buf" must hold at least "uncompressedLen" bytes.
+ */
+/*static*/ bool ZipUtils::inflateToBuffer(int fd, void* buf,
+    long uncompressedLen, long compressedLen)
+{
+    bool result = false;
+	const unsigned long kReadBufSize = 32768;
+	unsigned char* readBuf = NULL;
+    z_stream zstream;
+    int zerr;
+    unsigned long compRemaining;
+
+    assert(uncompressedLen >= 0);
+    assert(compressedLen >= 0);
+
+	readBuf = new unsigned char[kReadBufSize];
+	if (readBuf == NULL)
+        goto bail;
+    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;
+    }
+
+    /*
+     * 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);
+
+            int cc = TEMP_FAILURE_RETRY(read(fd, readBuf, getSize));
+            if (cc < 0) {
+                ALOGW("inflate read failed: %s", strerror(errno));
+            } else if (cc != (int) getSize) {
+                ALOGW("inflate read failed (%d vs %ld)", cc, getSize);
+                goto z_bail;
+            }
+
+            compRemaining -= getSize;
+
+            zstream.next_in = readBuf;
+            zstream.avail_in = getSize;
+        }
+
+        /* 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;
+        }
+
+		/* 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;
+    }
+
+    // success!
+    result = true;
+
+z_bail:
+    inflateEnd(&zstream);        /* free up any allocated structures */
+
+bail:
+	delete[] readBuf;
+    return result;
+}
+
+/*
+ * 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*/ bool ZipUtils::inflateToBuffer(FILE* fp, void* buf,
+    long uncompressedLen, long compressedLen)
+{
+    bool result = false;
+	const unsigned long kReadBufSize = 32768;
+	unsigned char* readBuf = NULL;
+    z_stream zstream;
+    int zerr;
+    unsigned long compRemaining;
+
+    assert(uncompressedLen >= 0);
+    assert(compressedLen >= 0);
+
+	readBuf = new unsigned char[kReadBufSize];
+	if (readBuf == NULL)
+        goto bail;
+    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;
+    }
+
+    /*
+     * 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);
+
+            int cc = fread(readBuf, 1, getSize, fp);
+            if (cc != (int) getSize) {
+                ALOGD("inflate read failed (%d vs %ld)\n",
+                    cc, getSize);
+                goto z_bail;
+            }
+
+            compRemaining -= getSize;
+
+            zstream.next_in = readBuf;
+            zstream.avail_in = getSize;
+        }
+
+        /* 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;
+        }
+
+		/* 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;
+    }
+
+    // success!
+    result = true;
+
+z_bail:
+    inflateEnd(&zstream);        /* free up any allocated structures */
+
+bail:
+	delete[] readBuf;
+    return result;
+}
+
+/*
+ * Look at the contents of a gzip archive.  We want to know where the
+ * data starts, and how long it will be after it is uncompressed.
+ *
+ * We expect to find the CRC and length as the last 8 bytes on the file.
+ * This is a pretty reasonable thing to expect for locally-compressed
+ * files, but there's a small chance that some extra padding got thrown
+ * on (the man page talks about compressed data written to tape).  We
+ * don't currently deal with that here.  If "gzip -l" whines, we're going
+ * to fail too.
+ *
+ * On exit, "fp" is pointing at the start of the compressed data.
+ */
+/*static*/ bool ZipUtils::examineGzip(FILE* fp, int* pCompressionMethod,
+    long* pUncompressedLen, long* pCompressedLen, unsigned long* pCRC32)
+{
+    enum {  // flags
+        FTEXT       = 0x01,
+        FHCRC       = 0x02,
+        FEXTRA      = 0x04,
+        FNAME       = 0x08,
+        FCOMMENT    = 0x10,
+    };
+    int ic;
+    int method, flags;
+    int i;
+
+    ic = getc(fp);
+    if (ic != 0x1f || getc(fp) != 0x8b)
+        return false;       // not gzip
+    method = getc(fp);
+    flags = getc(fp);
+
+    /* quick sanity checks */
+    if (method == EOF || flags == EOF)
+        return false;
+    if (method != ZipFileRO::kCompressDeflated)
+        return false;
+
+    /* skip over 4 bytes of mod time, 1 byte XFL, 1 byte OS */
+    for (i = 0; i < 6; i++)
+        (void) getc(fp);
+    /* consume "extra" field, if present */
+    if ((flags & FEXTRA) != 0) {
+        int len;
+
+        len = getc(fp);
+        len |= getc(fp) << 8;
+        while (len-- && getc(fp) != EOF)
+            ;
+    }
+    /* consume filename, if present */
+    if ((flags & FNAME) != 0) {
+        do {
+            ic = getc(fp);
+        } while (ic != 0 && ic != EOF);
+    }
+    /* consume comment, if present */
+    if ((flags & FCOMMENT) != 0) {
+        do {
+            ic = getc(fp);
+        } while (ic != 0 && ic != EOF);
+    }
+    /* consume 16-bit header CRC, if present */
+    if ((flags & FHCRC) != 0) {
+        (void) getc(fp);
+        (void) getc(fp);
+    }
+
+    if (feof(fp) || ferror(fp))
+        return false;
+
+    /* seek to the end; CRC and length are in the last 8 bytes */
+    long curPosn = ftell(fp);
+    unsigned char buf[8];
+    fseek(fp, -8, SEEK_END);
+    *pCompressedLen = ftell(fp) - curPosn;
+
+    if (fread(buf, 1, 8, fp) != 8)
+        return false;
+    /* seek back to start of compressed data */
+    fseek(fp, curPosn, SEEK_SET);
+
+    *pCompressionMethod = method;
+    *pCRC32 = ZipFileRO::get4LE(&buf[0]);
+    *pUncompressedLen = ZipFileRO::get4LE(&buf[4]);
+
+    return true;
+}
diff --git a/libs/androidfw/misc.cpp b/libs/androidfw/misc.cpp
new file mode 100644
index 0000000..29686ef
--- /dev/null
+++ b/libs/androidfw/misc.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "misc"
+
+//
+// Miscellaneous utility functions.
+//
+#include <androidfw/misc.h>
+
+#include <sys/stat.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+
+using namespace android;
+
+namespace android {
+
+/*
+ * Get a file's type.
+ */
+FileType getFileType(const char* fileName)
+{
+    struct stat sb;
+
+    if (stat(fileName, &sb) < 0) {
+        if (errno == ENOENT || errno == ENOTDIR)
+            return kFileTypeNonexistent;
+        else {
+            fprintf(stderr, "getFileType got errno=%d on '%s'\n",
+                errno, fileName);
+            return kFileTypeUnknown;
+        }
+    } else {
+        if (S_ISREG(sb.st_mode))
+            return kFileTypeRegular;
+        else if (S_ISDIR(sb.st_mode))
+            return kFileTypeDirectory;
+        else if (S_ISCHR(sb.st_mode))
+            return kFileTypeCharDev;
+        else if (S_ISBLK(sb.st_mode))
+            return kFileTypeBlockDev;
+        else if (S_ISFIFO(sb.st_mode))
+            return kFileTypeFifo;
+#ifdef HAVE_SYMLINKS
+        else if (S_ISLNK(sb.st_mode))
+            return kFileTypeSymlink;
+        else if (S_ISSOCK(sb.st_mode))
+            return kFileTypeSocket;
+#endif
+        else
+            return kFileTypeUnknown;
+    }
+}
+
+/*
+ * Get a file's modification date.
+ */
+time_t getFileModDate(const char* fileName)
+{
+    struct stat sb;
+
+    if (stat(fileName, &sb) < 0)
+        return (time_t) -1;
+
+    return sb.st_mtime;
+}
+
+}; // namespace android
diff --git a/libs/androidfw/tests/Android.mk b/libs/androidfw/tests/Android.mk
index 4ae23ec..0522212 100644
--- a/libs/androidfw/tests/Android.mk
+++ b/libs/androidfw/tests/Android.mk
@@ -4,19 +4,15 @@
 
 # Build the unit tests.
 test_src_files := \
-    InputChannel_test.cpp \
-    InputEvent_test.cpp \
-    InputPublisherAndConsumer_test.cpp \
-    ObbFile_test.cpp
+    ObbFile_test.cpp \
+    ZipFileRO_test.cpp
 
 shared_libraries := \
     libandroidfw \
     libcutils \
     libutils \
-    libbinder \
     libui \
-    libstlport \
-    libskia
+    libstlport
 
 static_libraries := \
     libgtest \
diff --git a/libs/androidfw/tests/InputChannel_test.cpp b/libs/androidfw/tests/InputChannel_test.cpp
deleted file mode 100644
index 7fff8af..0000000
--- a/libs/androidfw/tests/InputChannel_test.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <androidfw/InputTransport.h>
-#include <utils/Timers.h>
-#include <utils/StopWatch.h>
-#include <utils/StrongPointer.h>
-#include <gtest/gtest.h>
-#include <unistd.h>
-#include <time.h>
-#include <errno.h>
-
-#include "TestHelpers.h"
-
-namespace android {
-
-class InputChannelTest : public testing::Test {
-protected:
-    virtual void SetUp() { }
-    virtual void TearDown() { }
-};
-
-
-TEST_F(InputChannelTest, ConstructorAndDestructor_TakesOwnershipOfFileDescriptors) {
-    // Our purpose here is to verify that the input channel destructor closes the
-    // file descriptor provided to it.  One easy way is to provide it with one end
-    // of a pipe and to check for EPIPE on the other end after the channel is destroyed.
-    Pipe pipe;
-
-    sp<InputChannel> inputChannel = new InputChannel(String8("channel name"), pipe.sendFd);
-
-    EXPECT_STREQ("channel name", inputChannel->getName().string())
-            << "channel should have provided name";
-    EXPECT_EQ(pipe.sendFd, inputChannel->getFd())
-            << "channel should have provided fd";
-
-    inputChannel.clear(); // destroys input channel
-
-    EXPECT_EQ(-EPIPE, pipe.readSignal())
-            << "channel should have closed fd when destroyed";
-
-    // clean up fds of Pipe endpoints that were closed so we don't try to close them again
-    pipe.sendFd = -1;
-}
-
-TEST_F(InputChannelTest, OpenInputChannelPair_ReturnsAPairOfConnectedChannels) {
-    sp<InputChannel> serverChannel, clientChannel;
-
-    status_t result = InputChannel::openInputChannelPair(String8("channel name"),
-            serverChannel, clientChannel);
-
-    ASSERT_EQ(OK, result)
-            << "should have successfully opened a channel pair";
-
-    // Name
-    EXPECT_STREQ("channel name (server)", serverChannel->getName().string())
-            << "server channel should have suffixed name";
-    EXPECT_STREQ("channel name (client)", clientChannel->getName().string())
-            << "client channel should have suffixed name";
-
-    // Server->Client communication
-    InputMessage serverMsg;
-    memset(&serverMsg, 0, sizeof(InputMessage));
-    serverMsg.header.type = InputMessage::TYPE_KEY;
-    serverMsg.body.key.action = AKEY_EVENT_ACTION_DOWN;
-    EXPECT_EQ(OK, serverChannel->sendMessage(&serverMsg))
-            << "server channel should be able to send message to client channel";
-
-    InputMessage clientMsg;
-    EXPECT_EQ(OK, clientChannel->receiveMessage(&clientMsg))
-            << "client channel should be able to receive message from server channel";
-    EXPECT_EQ(serverMsg.header.type, clientMsg.header.type)
-            << "client channel should receive the correct message from server channel";
-    EXPECT_EQ(serverMsg.body.key.action, clientMsg.body.key.action)
-            << "client channel should receive the correct message from server channel";
-
-    // Client->Server communication
-    InputMessage clientReply;
-    memset(&clientReply, 0, sizeof(InputMessage));
-    clientReply.header.type = InputMessage::TYPE_FINISHED;
-    clientReply.body.finished.seq = 0x11223344;
-    clientReply.body.finished.handled = true;
-    EXPECT_EQ(OK, clientChannel->sendMessage(&clientReply))
-            << "client channel should be able to send message to server channel";
-
-    InputMessage serverReply;
-    EXPECT_EQ(OK, serverChannel->receiveMessage(&serverReply))
-            << "server channel should be able to receive message from client channel";
-    EXPECT_EQ(clientReply.header.type, serverReply.header.type)
-            << "server channel should receive the correct message from client channel";
-    EXPECT_EQ(clientReply.body.finished.seq, serverReply.body.finished.seq)
-            << "server channel should receive the correct message from client channel";
-    EXPECT_EQ(clientReply.body.finished.handled, serverReply.body.finished.handled)
-            << "server channel should receive the correct message from client channel";
-}
-
-TEST_F(InputChannelTest, ReceiveSignal_WhenNoSignalPresent_ReturnsAnError) {
-    sp<InputChannel> serverChannel, clientChannel;
-
-    status_t result = InputChannel::openInputChannelPair(String8("channel name"),
-            serverChannel, clientChannel);
-
-    ASSERT_EQ(OK, result)
-            << "should have successfully opened a channel pair";
-
-    InputMessage msg;
-    EXPECT_EQ(WOULD_BLOCK, clientChannel->receiveMessage(&msg))
-            << "receiveMessage should have returned WOULD_BLOCK";
-}
-
-TEST_F(InputChannelTest, ReceiveSignal_WhenPeerClosed_ReturnsAnError) {
-    sp<InputChannel> serverChannel, clientChannel;
-
-    status_t result = InputChannel::openInputChannelPair(String8("channel name"),
-            serverChannel, clientChannel);
-
-    ASSERT_EQ(OK, result)
-            << "should have successfully opened a channel pair";
-
-    serverChannel.clear(); // close server channel
-
-    InputMessage msg;
-    EXPECT_EQ(DEAD_OBJECT, clientChannel->receiveMessage(&msg))
-            << "receiveMessage should have returned DEAD_OBJECT";
-}
-
-TEST_F(InputChannelTest, SendSignal_WhenPeerClosed_ReturnsAnError) {
-    sp<InputChannel> serverChannel, clientChannel;
-
-    status_t result = InputChannel::openInputChannelPair(String8("channel name"),
-            serverChannel, clientChannel);
-
-    ASSERT_EQ(OK, result)
-            << "should have successfully opened a channel pair";
-
-    serverChannel.clear(); // close server channel
-
-    InputMessage msg;
-    msg.header.type = InputMessage::TYPE_KEY;
-    EXPECT_EQ(DEAD_OBJECT, clientChannel->sendMessage(&msg))
-            << "sendMessage should have returned DEAD_OBJECT";
-}
-
-
-} // namespace android
diff --git a/libs/androidfw/tests/InputEvent_test.cpp b/libs/androidfw/tests/InputEvent_test.cpp
deleted file mode 100644
index e9164d1..0000000
--- a/libs/androidfw/tests/InputEvent_test.cpp
+++ /dev/null
@@ -1,581 +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.
- */
-
-#include <androidfw/Input.h>
-#include <gtest/gtest.h>
-#include <binder/Parcel.h>
-
-#include <math.h>
-#include <core/SkMatrix.h>
-
-namespace android {
-
-class BaseTest : public testing::Test {
-protected:
-    virtual void SetUp() { }
-    virtual void TearDown() { }
-};
-
-// --- PointerCoordsTest ---
-
-class PointerCoordsTest : public BaseTest {
-};
-
-TEST_F(PointerCoordsTest, ClearSetsBitsToZero) {
-    PointerCoords coords;
-    coords.clear();
-
-    ASSERT_EQ(0ULL, coords.bits);
-}
-
-TEST_F(PointerCoordsTest, AxisValues) {
-    float* valuePtr;
-    PointerCoords coords;
-    coords.clear();
-
-    // Check invariants when no axes are present.
-    ASSERT_EQ(0, coords.getAxisValue(0))
-            << "getAxisValue should return zero because axis is not present";
-    ASSERT_EQ(0, coords.getAxisValue(1))
-            << "getAxisValue should return zero because axis is not present";
-
-    // Set first axis.
-    ASSERT_EQ(OK, coords.setAxisValue(1, 5));
-    ASSERT_EQ(0x00000002ULL, coords.bits);
-    ASSERT_EQ(5, coords.values[0]);
-
-    ASSERT_EQ(0, coords.getAxisValue(0))
-            << "getAxisValue should return zero because axis is not present";
-    ASSERT_EQ(5, coords.getAxisValue(1))
-            << "getAxisValue should return value of axis";
-
-    // Set an axis with a higher id than all others.  (appending value at the end)
-    ASSERT_EQ(OK, coords.setAxisValue(3, 2));
-    ASSERT_EQ(0x0000000aULL, coords.bits);
-    ASSERT_EQ(5, coords.values[0]);
-    ASSERT_EQ(2, coords.values[1]);
-
-    ASSERT_EQ(0, coords.getAxisValue(0))
-            << "getAxisValue should return zero because axis is not present";
-    ASSERT_EQ(5, coords.getAxisValue(1))
-            << "getAxisValue should return value of axis";
-    ASSERT_EQ(0, coords.getAxisValue(2))
-            << "getAxisValue should return zero because axis is not present";
-    ASSERT_EQ(2, coords.getAxisValue(3))
-            << "getAxisValue should return value of axis";
-
-    // Set an axis with an id lower than all others.  (prepending value at beginning)
-    ASSERT_EQ(OK, coords.setAxisValue(0, 4));
-    ASSERT_EQ(0x0000000bULL, coords.bits);
-    ASSERT_EQ(4, coords.values[0]);
-    ASSERT_EQ(5, coords.values[1]);
-    ASSERT_EQ(2, coords.values[2]);
-
-    ASSERT_EQ(4, coords.getAxisValue(0))
-            << "getAxisValue should return value of axis";
-    ASSERT_EQ(5, coords.getAxisValue(1))
-            << "getAxisValue should return value of axis";
-    ASSERT_EQ(0, coords.getAxisValue(2))
-            << "getAxisValue should return zero because axis is not present";
-    ASSERT_EQ(2, coords.getAxisValue(3))
-            << "getAxisValue should return value of axis";
-
-    // Set an axis with an id between the others.  (inserting value in the middle)
-    ASSERT_EQ(OK, coords.setAxisValue(2, 1));
-    ASSERT_EQ(0x0000000fULL, coords.bits);
-    ASSERT_EQ(4, coords.values[0]);
-    ASSERT_EQ(5, coords.values[1]);
-    ASSERT_EQ(1, coords.values[2]);
-    ASSERT_EQ(2, coords.values[3]);
-
-    ASSERT_EQ(4, coords.getAxisValue(0))
-            << "getAxisValue should return value of axis";
-    ASSERT_EQ(5, coords.getAxisValue(1))
-            << "getAxisValue should return value of axis";
-    ASSERT_EQ(1, coords.getAxisValue(2))
-            << "getAxisValue should return value of axis";
-    ASSERT_EQ(2, coords.getAxisValue(3))
-            << "getAxisValue should return value of axis";
-
-    // Set an existing axis value in place.
-    ASSERT_EQ(OK, coords.setAxisValue(1, 6));
-    ASSERT_EQ(0x0000000fULL, coords.bits);
-    ASSERT_EQ(4, coords.values[0]);
-    ASSERT_EQ(6, coords.values[1]);
-    ASSERT_EQ(1, coords.values[2]);
-    ASSERT_EQ(2, coords.values[3]);
-
-    ASSERT_EQ(4, coords.getAxisValue(0))
-            << "getAxisValue should return value of axis";
-    ASSERT_EQ(6, coords.getAxisValue(1))
-            << "getAxisValue should return value of axis";
-    ASSERT_EQ(1, coords.getAxisValue(2))
-            << "getAxisValue should return value of axis";
-    ASSERT_EQ(2, coords.getAxisValue(3))
-            << "getAxisValue should return value of axis";
-
-    // Set maximum number of axes.
-    for (size_t axis = 4; axis < PointerCoords::MAX_AXES; axis++) {
-        ASSERT_EQ(OK, coords.setAxisValue(axis, axis));
-    }
-    ASSERT_EQ(PointerCoords::MAX_AXES, __builtin_popcountll(coords.bits));
-
-    // Try to set one more axis beyond maximum number.
-    // Ensure bits are unchanged.
-    ASSERT_EQ(NO_MEMORY, coords.setAxisValue(PointerCoords::MAX_AXES, 100));
-    ASSERT_EQ(PointerCoords::MAX_AXES, __builtin_popcountll(coords.bits));
-}
-
-TEST_F(PointerCoordsTest, Parcel) {
-    Parcel parcel;
-
-    PointerCoords inCoords;
-    inCoords.clear();
-    PointerCoords outCoords;
-
-    // Round trip with empty coords.
-    inCoords.writeToParcel(&parcel);
-    parcel.setDataPosition(0);
-    outCoords.readFromParcel(&parcel);
-
-    ASSERT_EQ(0ULL, outCoords.bits);
-
-    // Round trip with some values.
-    parcel.freeData();
-    inCoords.setAxisValue(2, 5);
-    inCoords.setAxisValue(5, 8);
-
-    inCoords.writeToParcel(&parcel);
-    parcel.setDataPosition(0);
-    outCoords.readFromParcel(&parcel);
-
-    ASSERT_EQ(outCoords.bits, inCoords.bits);
-    ASSERT_EQ(outCoords.values[0], inCoords.values[0]);
-    ASSERT_EQ(outCoords.values[1], inCoords.values[1]);
-}
-
-
-// --- KeyEventTest ---
-
-class KeyEventTest : public BaseTest {
-};
-
-TEST_F(KeyEventTest, Properties) {
-    KeyEvent event;
-
-    // Initialize and get properties.
-    const nsecs_t ARBITRARY_DOWN_TIME = 1;
-    const nsecs_t ARBITRARY_EVENT_TIME = 2;
-    event.initialize(2, AINPUT_SOURCE_GAMEPAD, AKEY_EVENT_ACTION_DOWN,
-            AKEY_EVENT_FLAG_FROM_SYSTEM, AKEYCODE_BUTTON_X, 121,
-            AMETA_ALT_ON, 1, ARBITRARY_DOWN_TIME, ARBITRARY_EVENT_TIME);
-
-    ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, event.getType());
-    ASSERT_EQ(2, event.getDeviceId());
-    ASSERT_EQ(AINPUT_SOURCE_GAMEPAD, event.getSource());
-    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, event.getAction());
-    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, event.getFlags());
-    ASSERT_EQ(AKEYCODE_BUTTON_X, event.getKeyCode());
-    ASSERT_EQ(121, event.getScanCode());
-    ASSERT_EQ(AMETA_ALT_ON, event.getMetaState());
-    ASSERT_EQ(1, event.getRepeatCount());
-    ASSERT_EQ(ARBITRARY_DOWN_TIME, event.getDownTime());
-    ASSERT_EQ(ARBITRARY_EVENT_TIME, event.getEventTime());
-
-    // Set source.
-    event.setSource(AINPUT_SOURCE_JOYSTICK);
-    ASSERT_EQ(AINPUT_SOURCE_JOYSTICK, event.getSource());
-}
-
-
-// --- MotionEventTest ---
-
-class MotionEventTest : public BaseTest {
-protected:
-    static const nsecs_t ARBITRARY_DOWN_TIME;
-    static const nsecs_t ARBITRARY_EVENT_TIME;
-    static const float X_OFFSET;
-    static const float Y_OFFSET;
-
-    void initializeEventWithHistory(MotionEvent* event);
-    void assertEqualsEventWithHistory(const MotionEvent* event);
-};
-
-const nsecs_t MotionEventTest::ARBITRARY_DOWN_TIME = 1;
-const nsecs_t MotionEventTest::ARBITRARY_EVENT_TIME = 2;
-const float MotionEventTest::X_OFFSET = 1.0f;
-const float MotionEventTest::Y_OFFSET = 1.1f;
-
-void MotionEventTest::initializeEventWithHistory(MotionEvent* event) {
-    PointerProperties pointerProperties[2];
-    pointerProperties[0].clear();
-    pointerProperties[0].id = 1;
-    pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
-    pointerProperties[1].clear();
-    pointerProperties[1].id = 2;
-    pointerProperties[1].toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
-
-    PointerCoords pointerCoords[2];
-    pointerCoords[0].clear();
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 10);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 11);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 12);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 13);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 14);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 15);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 16);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 17);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 18);
-    pointerCoords[1].clear();
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_X, 20);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, 21);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 22);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 23);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 24);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 25);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 26);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 27);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 28);
-    event->initialize(2, AINPUT_SOURCE_TOUCHSCREEN, AMOTION_EVENT_ACTION_MOVE,
-            AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED,
-            AMOTION_EVENT_EDGE_FLAG_TOP, AMETA_ALT_ON, AMOTION_EVENT_BUTTON_PRIMARY,
-            X_OFFSET, Y_OFFSET, 2.0f, 2.1f,
-            ARBITRARY_DOWN_TIME, ARBITRARY_EVENT_TIME,
-            2, pointerProperties, pointerCoords);
-
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 110);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 111);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 112);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 113);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 114);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 115);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 116);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 117);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 118);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_X, 120);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, 121);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 122);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 123);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 124);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 125);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 126);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 127);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 128);
-    event->addSample(ARBITRARY_EVENT_TIME + 1, pointerCoords);
-
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 210);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 211);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 212);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 213);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 214);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 215);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 216);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 217);
-    pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 218);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_X, 220);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, 221);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 222);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 223);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 224);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 225);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 226);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 227);
-    pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 228);
-    event->addSample(ARBITRARY_EVENT_TIME + 2, pointerCoords);
-}
-
-void MotionEventTest::assertEqualsEventWithHistory(const MotionEvent* event) {
-    // Check properties.
-    ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, event->getType());
-    ASSERT_EQ(2, event->getDeviceId());
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, event->getSource());
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, event->getAction());
-    ASSERT_EQ(AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED, event->getFlags());
-    ASSERT_EQ(AMOTION_EVENT_EDGE_FLAG_TOP, event->getEdgeFlags());
-    ASSERT_EQ(AMETA_ALT_ON, event->getMetaState());
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, event->getButtonState());
-    ASSERT_EQ(X_OFFSET, event->getXOffset());
-    ASSERT_EQ(Y_OFFSET, event->getYOffset());
-    ASSERT_EQ(2.0f, event->getXPrecision());
-    ASSERT_EQ(2.1f, event->getYPrecision());
-    ASSERT_EQ(ARBITRARY_DOWN_TIME, event->getDownTime());
-
-    ASSERT_EQ(2U, event->getPointerCount());
-    ASSERT_EQ(1, event->getPointerId(0));
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, event->getToolType(0));
-    ASSERT_EQ(2, event->getPointerId(1));
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, event->getToolType(1));
-
-    ASSERT_EQ(2U, event->getHistorySize());
-
-    // Check data.
-    ASSERT_EQ(ARBITRARY_EVENT_TIME, event->getHistoricalEventTime(0));
-    ASSERT_EQ(ARBITRARY_EVENT_TIME + 1, event->getHistoricalEventTime(1));
-    ASSERT_EQ(ARBITRARY_EVENT_TIME + 2, event->getEventTime());
-
-    ASSERT_EQ(11, event->getHistoricalRawPointerCoords(0, 0)->
-            getAxisValue(AMOTION_EVENT_AXIS_Y));
-    ASSERT_EQ(21, event->getHistoricalRawPointerCoords(1, 0)->
-            getAxisValue(AMOTION_EVENT_AXIS_Y));
-    ASSERT_EQ(111, event->getHistoricalRawPointerCoords(0, 1)->
-            getAxisValue(AMOTION_EVENT_AXIS_Y));
-    ASSERT_EQ(121, event->getHistoricalRawPointerCoords(1, 1)->
-            getAxisValue(AMOTION_EVENT_AXIS_Y));
-    ASSERT_EQ(211, event->getRawPointerCoords(0)->
-            getAxisValue(AMOTION_EVENT_AXIS_Y));
-    ASSERT_EQ(221, event->getRawPointerCoords(1)->
-            getAxisValue(AMOTION_EVENT_AXIS_Y));
-
-    ASSERT_EQ(11, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 0, 0));
-    ASSERT_EQ(21, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 1, 0));
-    ASSERT_EQ(111, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 0, 1));
-    ASSERT_EQ(121, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 1, 1));
-    ASSERT_EQ(211, event->getRawAxisValue(AMOTION_EVENT_AXIS_Y, 0));
-    ASSERT_EQ(221, event->getRawAxisValue(AMOTION_EVENT_AXIS_Y, 1));
-
-    ASSERT_EQ(10, event->getHistoricalRawX(0, 0));
-    ASSERT_EQ(20, event->getHistoricalRawX(1, 0));
-    ASSERT_EQ(110, event->getHistoricalRawX(0, 1));
-    ASSERT_EQ(120, event->getHistoricalRawX(1, 1));
-    ASSERT_EQ(210, event->getRawX(0));
-    ASSERT_EQ(220, event->getRawX(1));
-
-    ASSERT_EQ(11, event->getHistoricalRawY(0, 0));
-    ASSERT_EQ(21, event->getHistoricalRawY(1, 0));
-    ASSERT_EQ(111, event->getHistoricalRawY(0, 1));
-    ASSERT_EQ(121, event->getHistoricalRawY(1, 1));
-    ASSERT_EQ(211, event->getRawY(0));
-    ASSERT_EQ(221, event->getRawY(1));
-
-    ASSERT_EQ(X_OFFSET + 10, event->getHistoricalX(0, 0));
-    ASSERT_EQ(X_OFFSET + 20, event->getHistoricalX(1, 0));
-    ASSERT_EQ(X_OFFSET + 110, event->getHistoricalX(0, 1));
-    ASSERT_EQ(X_OFFSET + 120, event->getHistoricalX(1, 1));
-    ASSERT_EQ(X_OFFSET + 210, event->getX(0));
-    ASSERT_EQ(X_OFFSET + 220, event->getX(1));
-
-    ASSERT_EQ(Y_OFFSET + 11, event->getHistoricalY(0, 0));
-    ASSERT_EQ(Y_OFFSET + 21, event->getHistoricalY(1, 0));
-    ASSERT_EQ(Y_OFFSET + 111, event->getHistoricalY(0, 1));
-    ASSERT_EQ(Y_OFFSET + 121, event->getHistoricalY(1, 1));
-    ASSERT_EQ(Y_OFFSET + 211, event->getY(0));
-    ASSERT_EQ(Y_OFFSET + 221, event->getY(1));
-
-    ASSERT_EQ(12, event->getHistoricalPressure(0, 0));
-    ASSERT_EQ(22, event->getHistoricalPressure(1, 0));
-    ASSERT_EQ(112, event->getHistoricalPressure(0, 1));
-    ASSERT_EQ(122, event->getHistoricalPressure(1, 1));
-    ASSERT_EQ(212, event->getPressure(0));
-    ASSERT_EQ(222, event->getPressure(1));
-
-    ASSERT_EQ(13, event->getHistoricalSize(0, 0));
-    ASSERT_EQ(23, event->getHistoricalSize(1, 0));
-    ASSERT_EQ(113, event->getHistoricalSize(0, 1));
-    ASSERT_EQ(123, event->getHistoricalSize(1, 1));
-    ASSERT_EQ(213, event->getSize(0));
-    ASSERT_EQ(223, event->getSize(1));
-
-    ASSERT_EQ(14, event->getHistoricalTouchMajor(0, 0));
-    ASSERT_EQ(24, event->getHistoricalTouchMajor(1, 0));
-    ASSERT_EQ(114, event->getHistoricalTouchMajor(0, 1));
-    ASSERT_EQ(124, event->getHistoricalTouchMajor(1, 1));
-    ASSERT_EQ(214, event->getTouchMajor(0));
-    ASSERT_EQ(224, event->getTouchMajor(1));
-
-    ASSERT_EQ(15, event->getHistoricalTouchMinor(0, 0));
-    ASSERT_EQ(25, event->getHistoricalTouchMinor(1, 0));
-    ASSERT_EQ(115, event->getHistoricalTouchMinor(0, 1));
-    ASSERT_EQ(125, event->getHistoricalTouchMinor(1, 1));
-    ASSERT_EQ(215, event->getTouchMinor(0));
-    ASSERT_EQ(225, event->getTouchMinor(1));
-
-    ASSERT_EQ(16, event->getHistoricalToolMajor(0, 0));
-    ASSERT_EQ(26, event->getHistoricalToolMajor(1, 0));
-    ASSERT_EQ(116, event->getHistoricalToolMajor(0, 1));
-    ASSERT_EQ(126, event->getHistoricalToolMajor(1, 1));
-    ASSERT_EQ(216, event->getToolMajor(0));
-    ASSERT_EQ(226, event->getToolMajor(1));
-
-    ASSERT_EQ(17, event->getHistoricalToolMinor(0, 0));
-    ASSERT_EQ(27, event->getHistoricalToolMinor(1, 0));
-    ASSERT_EQ(117, event->getHistoricalToolMinor(0, 1));
-    ASSERT_EQ(127, event->getHistoricalToolMinor(1, 1));
-    ASSERT_EQ(217, event->getToolMinor(0));
-    ASSERT_EQ(227, event->getToolMinor(1));
-
-    ASSERT_EQ(18, event->getHistoricalOrientation(0, 0));
-    ASSERT_EQ(28, event->getHistoricalOrientation(1, 0));
-    ASSERT_EQ(118, event->getHistoricalOrientation(0, 1));
-    ASSERT_EQ(128, event->getHistoricalOrientation(1, 1));
-    ASSERT_EQ(218, event->getOrientation(0));
-    ASSERT_EQ(228, event->getOrientation(1));
-}
-
-TEST_F(MotionEventTest, Properties) {
-    MotionEvent event;
-
-    // Initialize, add samples and check properties.
-    initializeEventWithHistory(&event);
-    ASSERT_NO_FATAL_FAILURE(assertEqualsEventWithHistory(&event));
-
-    // Set source.
-    event.setSource(AINPUT_SOURCE_JOYSTICK);
-    ASSERT_EQ(AINPUT_SOURCE_JOYSTICK, event.getSource());
-
-    // Set action.
-    event.setAction(AMOTION_EVENT_ACTION_CANCEL);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, event.getAction());
-
-    // Set meta state.
-    event.setMetaState(AMETA_CTRL_ON);
-    ASSERT_EQ(AMETA_CTRL_ON, event.getMetaState());
-}
-
-TEST_F(MotionEventTest, CopyFrom_KeepHistory) {
-    MotionEvent event;
-    initializeEventWithHistory(&event);
-
-    MotionEvent copy;
-    copy.copyFrom(&event, true /*keepHistory*/);
-
-    ASSERT_NO_FATAL_FAILURE(assertEqualsEventWithHistory(&event));
-}
-
-TEST_F(MotionEventTest, CopyFrom_DoNotKeepHistory) {
-    MotionEvent event;
-    initializeEventWithHistory(&event);
-
-    MotionEvent copy;
-    copy.copyFrom(&event, false /*keepHistory*/);
-
-    ASSERT_EQ(event.getPointerCount(), copy.getPointerCount());
-    ASSERT_EQ(0U, copy.getHistorySize());
-
-    ASSERT_EQ(event.getPointerId(0), copy.getPointerId(0));
-    ASSERT_EQ(event.getPointerId(1), copy.getPointerId(1));
-
-    ASSERT_EQ(event.getEventTime(), copy.getEventTime());
-
-    ASSERT_EQ(event.getX(0), copy.getX(0));
-}
-
-TEST_F(MotionEventTest, OffsetLocation) {
-    MotionEvent event;
-    initializeEventWithHistory(&event);
-
-    event.offsetLocation(5.0f, -2.0f);
-
-    ASSERT_EQ(X_OFFSET + 5.0f, event.getXOffset());
-    ASSERT_EQ(Y_OFFSET - 2.0f, event.getYOffset());
-}
-
-TEST_F(MotionEventTest, Scale) {
-    MotionEvent event;
-    initializeEventWithHistory(&event);
-
-    event.scale(2.0f);
-
-    ASSERT_EQ(X_OFFSET * 2, event.getXOffset());
-    ASSERT_EQ(Y_OFFSET * 2, event.getYOffset());
-
-    ASSERT_EQ(210 * 2, event.getRawX(0));
-    ASSERT_EQ(211 * 2, event.getRawY(0));
-    ASSERT_EQ((X_OFFSET + 210) * 2, event.getX(0));
-    ASSERT_EQ((Y_OFFSET + 211) * 2, event.getY(0));
-    ASSERT_EQ(212, event.getPressure(0));
-    ASSERT_EQ(213, event.getSize(0));
-    ASSERT_EQ(214 * 2, event.getTouchMajor(0));
-    ASSERT_EQ(215 * 2, event.getTouchMinor(0));
-    ASSERT_EQ(216 * 2, event.getToolMajor(0));
-    ASSERT_EQ(217 * 2, event.getToolMinor(0));
-    ASSERT_EQ(218, event.getOrientation(0));
-}
-
-TEST_F(MotionEventTest, Parcel) {
-    Parcel parcel;
-
-    MotionEvent inEvent;
-    initializeEventWithHistory(&inEvent);
-    MotionEvent outEvent;
-
-    // Round trip.
-    inEvent.writeToParcel(&parcel);
-    parcel.setDataPosition(0);
-    outEvent.readFromParcel(&parcel);
-
-    ASSERT_NO_FATAL_FAILURE(assertEqualsEventWithHistory(&outEvent));
-}
-
-TEST_F(MotionEventTest, Transform) {
-    // Generate some points on a circle.
-    // Each point 'i' is a point on a circle of radius ROTATION centered at (3,2) at an angle
-    // of ARC * i degrees clockwise relative to the Y axis.
-    // The geometrical representation is irrelevant to the test, it's just easy to generate
-    // and check rotation.  We set the orientation to the same angle.
-    // Coordinate system: down is increasing Y, right is increasing X.
-    const float PI_180 = float(M_PI / 180);
-    const float RADIUS = 10;
-    const float ARC = 36;
-    const float ROTATION = ARC * 2;
-
-    const size_t pointerCount = 11;
-    PointerProperties pointerProperties[pointerCount];
-    PointerCoords pointerCoords[pointerCount];
-    for (size_t i = 0; i < pointerCount; i++) {
-        float angle = float(i * ARC * PI_180);
-        pointerProperties[i].clear();
-        pointerProperties[i].id = i;
-        pointerCoords[i].clear();
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, sinf(angle) * RADIUS + 3);
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, -cosf(angle) * RADIUS + 2);
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, angle);
-    }
-    MotionEvent event;
-    event.initialize(0, 0, AMOTION_EVENT_ACTION_MOVE, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, pointerCount, pointerProperties, pointerCoords);
-    float originalRawX = 0 + 3;
-    float originalRawY = -RADIUS + 2;
-
-    // Check original raw X and Y assumption.
-    ASSERT_NEAR(originalRawX, event.getRawX(0), 0.001);
-    ASSERT_NEAR(originalRawY, event.getRawY(0), 0.001);
-
-    // Now translate the motion event so the circle's origin is at (0,0).
-    event.offsetLocation(-3, -2);
-
-    // Offsetting the location should preserve the raw X and Y of the first point.
-    ASSERT_NEAR(originalRawX, event.getRawX(0), 0.001);
-    ASSERT_NEAR(originalRawY, event.getRawY(0), 0.001);
-
-    // Apply a rotation about the origin by ROTATION degrees clockwise.
-    SkMatrix matrix;
-    matrix.setRotate(ROTATION);
-    event.transform(&matrix);
-
-    // Check the points.
-    for (size_t i = 0; i < pointerCount; i++) {
-        float angle = float((i * ARC + ROTATION) * PI_180);
-        ASSERT_NEAR(sinf(angle) * RADIUS, event.getX(i), 0.001);
-        ASSERT_NEAR(-cosf(angle) * RADIUS, event.getY(i), 0.001);
-        ASSERT_NEAR(tanf(angle), tanf(event.getOrientation(i)), 0.1);
-    }
-
-    // Applying the transformation should preserve the raw X and Y of the first point.
-    ASSERT_NEAR(originalRawX, event.getRawX(0), 0.001);
-    ASSERT_NEAR(originalRawY, event.getRawY(0), 0.001);
-}
-
-} // namespace android
diff --git a/libs/androidfw/tests/InputPublisherAndConsumer_test.cpp b/libs/androidfw/tests/InputPublisherAndConsumer_test.cpp
deleted file mode 100644
index f45774b..0000000
--- a/libs/androidfw/tests/InputPublisherAndConsumer_test.cpp
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <androidfw/InputTransport.h>
-#include <utils/Timers.h>
-#include <utils/StopWatch.h>
-#include <gtest/gtest.h>
-#include <unistd.h>
-#include <time.h>
-#include <sys/mman.h>
-#include <cutils/ashmem.h>
-
-#include "TestHelpers.h"
-
-namespace android {
-
-class InputPublisherAndConsumerTest : public testing::Test {
-protected:
-    sp<InputChannel> serverChannel, clientChannel;
-    InputPublisher* mPublisher;
-    InputConsumer* mConsumer;
-    PreallocatedInputEventFactory mEventFactory;
-
-    virtual void SetUp() {
-        status_t result = InputChannel::openInputChannelPair(String8("channel name"),
-                serverChannel, clientChannel);
-
-        mPublisher = new InputPublisher(serverChannel);
-        mConsumer = new InputConsumer(clientChannel);
-    }
-
-    virtual void TearDown() {
-        if (mPublisher) {
-            delete mPublisher;
-            mPublisher = NULL;
-        }
-
-        if (mConsumer) {
-            delete mConsumer;
-            mConsumer = NULL;
-        }
-
-        serverChannel.clear();
-        clientChannel.clear();
-    }
-
-    void PublishAndConsumeKeyEvent();
-    void PublishAndConsumeMotionEvent();
-};
-
-TEST_F(InputPublisherAndConsumerTest, GetChannel_ReturnsTheChannel) {
-    EXPECT_EQ(serverChannel.get(), mPublisher->getChannel().get());
-    EXPECT_EQ(clientChannel.get(), mConsumer->getChannel().get());
-}
-
-void InputPublisherAndConsumerTest::PublishAndConsumeKeyEvent() {
-    status_t status;
-
-    const uint32_t seq = 15;
-    const int32_t deviceId = 1;
-    const int32_t source = AINPUT_SOURCE_KEYBOARD;
-    const int32_t action = AKEY_EVENT_ACTION_DOWN;
-    const int32_t flags = AKEY_EVENT_FLAG_FROM_SYSTEM;
-    const int32_t keyCode = AKEYCODE_ENTER;
-    const int32_t scanCode = 13;
-    const int32_t metaState = AMETA_ALT_LEFT_ON | AMETA_ALT_ON;
-    const int32_t repeatCount = 1;
-    const nsecs_t downTime = 3;
-    const nsecs_t eventTime = 4;
-
-    status = mPublisher->publishKeyEvent(seq, deviceId, source, action, flags,
-            keyCode, scanCode, metaState, repeatCount, downTime, eventTime);
-    ASSERT_EQ(OK, status)
-            << "publisher publishKeyEvent should return OK";
-
-    uint32_t consumeSeq;
-    InputEvent* event;
-    status = mConsumer->consume(&mEventFactory, true /*consumeBatches*/, -1, &consumeSeq, &event);
-    ASSERT_EQ(OK, status)
-            << "consumer consume should return OK";
-
-    ASSERT_TRUE(event != NULL)
-            << "consumer should have returned non-NULL event";
-    ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, event->getType())
-            << "consumer should have returned a key event";
-
-    KeyEvent* keyEvent = static_cast<KeyEvent*>(event);
-    EXPECT_EQ(seq, consumeSeq);
-    EXPECT_EQ(deviceId, keyEvent->getDeviceId());
-    EXPECT_EQ(source, keyEvent->getSource());
-    EXPECT_EQ(action, keyEvent->getAction());
-    EXPECT_EQ(flags, keyEvent->getFlags());
-    EXPECT_EQ(keyCode, keyEvent->getKeyCode());
-    EXPECT_EQ(scanCode, keyEvent->getScanCode());
-    EXPECT_EQ(metaState, keyEvent->getMetaState());
-    EXPECT_EQ(repeatCount, keyEvent->getRepeatCount());
-    EXPECT_EQ(downTime, keyEvent->getDownTime());
-    EXPECT_EQ(eventTime, keyEvent->getEventTime());
-
-    status = mConsumer->sendFinishedSignal(seq, true);
-    ASSERT_EQ(OK, status)
-            << "consumer sendFinishedSignal should return OK";
-
-    uint32_t finishedSeq = 0;
-    bool handled = false;
-    status = mPublisher->receiveFinishedSignal(&finishedSeq, &handled);
-    ASSERT_EQ(OK, status)
-            << "publisher receiveFinishedSignal should return OK";
-    ASSERT_EQ(seq, finishedSeq)
-            << "publisher receiveFinishedSignal should have returned the original sequence number";
-    ASSERT_TRUE(handled)
-            << "publisher receiveFinishedSignal should have set handled to consumer's reply";
-}
-
-void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent() {
-    status_t status;
-
-    const uint32_t seq = 15;
-    const int32_t deviceId = 1;
-    const int32_t source = AINPUT_SOURCE_TOUCHSCREEN;
-    const int32_t action = AMOTION_EVENT_ACTION_MOVE;
-    const int32_t flags = AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
-    const int32_t edgeFlags = AMOTION_EVENT_EDGE_FLAG_TOP;
-    const int32_t metaState = AMETA_ALT_LEFT_ON | AMETA_ALT_ON;
-    const int32_t buttonState = AMOTION_EVENT_BUTTON_PRIMARY;
-    const float xOffset = -10;
-    const float yOffset = -20;
-    const float xPrecision = 0.25;
-    const float yPrecision = 0.5;
-    const nsecs_t downTime = 3;
-    const size_t pointerCount = 3;
-    const nsecs_t eventTime = 4;
-    PointerProperties pointerProperties[pointerCount];
-    PointerCoords pointerCoords[pointerCount];
-    for (size_t i = 0; i < pointerCount; i++) {
-        pointerProperties[i].clear();
-        pointerProperties[i].id = (i + 2) % pointerCount;
-        pointerProperties[i].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
-
-        pointerCoords[i].clear();
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, 100 * i);
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, 200 * i);
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 0.5 * i);
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 0.7 * i);
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 1.5 * i);
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 1.7 * i);
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 2.5 * i);
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 2.7 * i);
-        pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 3.5 * i);
-    }
-
-    status = mPublisher->publishMotionEvent(seq, deviceId, source, action, flags, edgeFlags,
-            metaState, buttonState, xOffset, yOffset, xPrecision, yPrecision,
-            downTime, eventTime, pointerCount,
-            pointerProperties, pointerCoords);
-    ASSERT_EQ(OK, status)
-            << "publisher publishMotionEvent should return OK";
-
-    uint32_t consumeSeq;
-    InputEvent* event;
-    status = mConsumer->consume(&mEventFactory, true /*consumeBatches*/, -1, &consumeSeq, &event);
-    ASSERT_EQ(OK, status)
-            << "consumer consume should return OK";
-
-    ASSERT_TRUE(event != NULL)
-            << "consumer should have returned non-NULL event";
-    ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, event->getType())
-            << "consumer should have returned a motion event";
-
-    MotionEvent* motionEvent = static_cast<MotionEvent*>(event);
-    EXPECT_EQ(seq, consumeSeq);
-    EXPECT_EQ(deviceId, motionEvent->getDeviceId());
-    EXPECT_EQ(source, motionEvent->getSource());
-    EXPECT_EQ(action, motionEvent->getAction());
-    EXPECT_EQ(flags, motionEvent->getFlags());
-    EXPECT_EQ(edgeFlags, motionEvent->getEdgeFlags());
-    EXPECT_EQ(metaState, motionEvent->getMetaState());
-    EXPECT_EQ(buttonState, motionEvent->getButtonState());
-    EXPECT_EQ(xPrecision, motionEvent->getXPrecision());
-    EXPECT_EQ(yPrecision, motionEvent->getYPrecision());
-    EXPECT_EQ(downTime, motionEvent->getDownTime());
-    EXPECT_EQ(eventTime, motionEvent->getEventTime());
-    EXPECT_EQ(pointerCount, motionEvent->getPointerCount());
-    EXPECT_EQ(0U, motionEvent->getHistorySize());
-
-    for (size_t i = 0; i < pointerCount; i++) {
-        SCOPED_TRACE(i);
-        EXPECT_EQ(pointerProperties[i].id, motionEvent->getPointerId(i));
-        EXPECT_EQ(pointerProperties[i].toolType, motionEvent->getToolType(i));
-
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
-                motionEvent->getRawX(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
-                motionEvent->getRawY(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X) + xOffset,
-                motionEvent->getX(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y) + yOffset,
-                motionEvent->getY(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
-                motionEvent->getPressure(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
-                motionEvent->getSize(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
-                motionEvent->getTouchMajor(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
-                motionEvent->getTouchMinor(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
-                motionEvent->getToolMajor(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
-                motionEvent->getToolMinor(i));
-        EXPECT_EQ(pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION),
-                motionEvent->getOrientation(i));
-    }
-
-    status = mConsumer->sendFinishedSignal(seq, false);
-    ASSERT_EQ(OK, status)
-            << "consumer sendFinishedSignal should return OK";
-
-    uint32_t finishedSeq = 0;
-    bool handled = true;
-    status = mPublisher->receiveFinishedSignal(&finishedSeq, &handled);
-    ASSERT_EQ(OK, status)
-            << "publisher receiveFinishedSignal should return OK";
-    ASSERT_EQ(seq, finishedSeq)
-            << "publisher receiveFinishedSignal should have returned the original sequence number";
-    ASSERT_FALSE(handled)
-            << "publisher receiveFinishedSignal should have set handled to consumer's reply";
-}
-
-TEST_F(InputPublisherAndConsumerTest, PublishKeyEvent_EndToEnd) {
-    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeKeyEvent());
-}
-
-TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_EndToEnd) {
-    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent());
-}
-
-TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_WhenPointerCountLessThan1_ReturnsError) {
-    status_t status;
-    const size_t pointerCount = 0;
-    PointerProperties pointerProperties[pointerCount];
-    PointerCoords pointerCoords[pointerCount];
-
-    status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            pointerCount, pointerProperties, pointerCoords);
-    ASSERT_EQ(BAD_VALUE, status)
-            << "publisher publishMotionEvent should return BAD_VALUE";
-}
-
-TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_WhenPointerCountGreaterThanMax_ReturnsError) {
-    status_t status;
-    const size_t pointerCount = MAX_POINTERS + 1;
-    PointerProperties pointerProperties[pointerCount];
-    PointerCoords pointerCoords[pointerCount];
-    for (size_t i = 0; i < pointerCount; i++) {
-        pointerProperties[i].clear();
-        pointerCoords[i].clear();
-    }
-
-    status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            pointerCount, pointerProperties, pointerCoords);
-    ASSERT_EQ(BAD_VALUE, status)
-            << "publisher publishMotionEvent should return BAD_VALUE";
-}
-
-TEST_F(InputPublisherAndConsumerTest, PublishMultipleEvents_EndToEnd) {
-    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent());
-    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeKeyEvent());
-    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent());
-    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent());
-    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeKeyEvent());
-}
-
-} // namespace android
diff --git a/libs/androidfw/tests/TestHelpers.h b/libs/androidfw/tests/TestHelpers.h
deleted file mode 100644
index d8e985e..0000000
--- a/libs/androidfw/tests/TestHelpers.h
+++ /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.
- */
-
-#ifndef TESTHELPERS_H
-#define TESTHELPERS_H
-
-#include <utils/threads.h>
-
-namespace android {
-
-class Pipe {
-public:
-    int sendFd;
-    int receiveFd;
-
-    Pipe() {
-        int fds[2];
-        ::pipe(fds);
-
-        receiveFd = fds[0];
-        sendFd = fds[1];
-    }
-
-    ~Pipe() {
-        if (sendFd != -1) {
-            ::close(sendFd);
-        }
-
-        if (receiveFd != -1) {
-            ::close(receiveFd);
-        }
-    }
-
-    status_t writeSignal() {
-        ssize_t nWritten = ::write(sendFd, "*", 1);
-        return nWritten == 1 ? 0 : -errno;
-    }
-
-    status_t readSignal() {
-        char buf[1];
-        ssize_t nRead = ::read(receiveFd, buf, 1);
-        return nRead == 1 ? 0 : nRead == 0 ? -EPIPE : -errno;
-    }
-};
-
-class DelayedTask : public Thread {
-    int mDelayMillis;
-
-public:
-    DelayedTask(int delayMillis) : mDelayMillis(delayMillis) { }
-
-protected:
-    virtual ~DelayedTask() { }
-
-    virtual void doTask() = 0;
-
-    virtual bool threadLoop() {
-        usleep(mDelayMillis * 1000);
-        doTask();
-        return false;
-    }
-};
-
-} // namespace android
-
-#endif // TESTHELPERS_H
diff --git a/libs/androidfw/tests/ZipFileRO_test.cpp b/libs/androidfw/tests/ZipFileRO_test.cpp
new file mode 100644
index 0000000..cb9c721
--- /dev/null
+++ b/libs/androidfw/tests/ZipFileRO_test.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ZipFileRO_test"
+#include <utils/Log.h>
+#include <androidfw/ZipFileRO.h>
+
+#include <gtest/gtest.h>
+
+#include <fcntl.h>
+#include <string.h>
+
+namespace android {
+
+class ZipFileROTest : public testing::Test {
+protected:
+    virtual void SetUp() {
+    }
+
+    virtual void TearDown() {
+    }
+};
+
+TEST_F(ZipFileROTest, ZipTimeConvertSuccess) {
+    struct tm t;
+
+    // 2011-06-29 14:40:40
+    long when = 0x3EDD7514;
+
+    ZipFileRO::zipTimeToTimespec(when, &t);
+
+    EXPECT_EQ(2011, t.tm_year + 1900)
+            << "Year was improperly converted.";
+
+    EXPECT_EQ(6, t.tm_mon)
+            << "Month was improperly converted.";
+
+    EXPECT_EQ(29, t.tm_mday)
+            << "Day was improperly converted.";
+
+    EXPECT_EQ(14, t.tm_hour)
+            << "Hour was improperly converted.";
+
+    EXPECT_EQ(40, t.tm_min)
+            << "Minute was improperly converted.";
+
+    EXPECT_EQ(40, t.tm_sec)
+            << "Second was improperly converted.";
+}
+
+}
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index a630ea1..411c133 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -10,6 +10,7 @@
 		thread/TaskManager.cpp \
 		font/CacheTexture.cpp \
 		font/Font.cpp \
+		AssetAtlas.cpp \
 		FontRenderer.cpp \
 		GammaFontRenderer.cpp \
 		Caches.cpp \
@@ -21,6 +22,7 @@
 		Extensions.cpp \
 		FboCache.cpp \
 		GradientCache.cpp \
+		Image.cpp \
 		Layer.cpp \
 		LayerCache.cpp \
 		LayerRenderer.cpp \
@@ -39,6 +41,7 @@
 		SkiaShader.cpp \
 		Snapshot.cpp \
 		Stencil.cpp \
+		Texture.cpp \
 		TextureCache.cpp \
 		TextDropShadowCache.cpp
 
@@ -52,17 +55,26 @@
 		external/skia/include/images \
 		external/skia/src/core \
 		external/skia/src/ports \
-		external/skia/include/utils \
-		$(intermediates) \
-		frameworks/rs/cpp \
-		frameworks/rs
+		external/skia/include/utils
 
-	LOCAL_CFLAGS += -DUSE_OPENGL_RENDERER -DGL_GLEXT_PROTOTYPES
+	LOCAL_CFLAGS += -DUSE_OPENGL_RENDERER -DEGL_EGLEXT_PROTOTYPES -DGL_GLEXT_PROTOTYPES
 	LOCAL_MODULE_CLASS := SHARED_LIBRARIES
-	LOCAL_SHARED_LIBRARIES := liblog libcutils libutils libGLESv2 libskia libui libRS libRScpp
+	LOCAL_SHARED_LIBRARIES := liblog libcutils libutils libEGL libGLESv2 libskia libui
 	LOCAL_MODULE := libhwui
 	LOCAL_MODULE_TAGS := optional
 
+	ifneq (false,$(ANDROID_ENABLE_RENDERSCRIPT))
+		LOCAL_CFLAGS += -DANDROID_ENABLE_RENDERSCRIPT
+		LOCAL_SHARED_LIBRARIES += libRS libRScpp libstlport
+		LOCAL_C_INCLUDES += \
+			$(intermediates) \
+			frameworks/rs/cpp \
+			frameworks/rs \
+			external/stlport/stlport \
+			bionic/ \
+			bionic/libstdc++/include
+	endif
+
 	ifndef HWUI_COMPILE_SYMBOLS
 		LOCAL_CFLAGS += -fvisibility=hidden
 	endif
diff --git a/libs/hwui/AssetAtlas.cpp b/libs/hwui/AssetAtlas.cpp
new file mode 100644
index 0000000..eb8bb9f
--- /dev/null
+++ b/libs/hwui/AssetAtlas.cpp
@@ -0,0 +1,142 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "OpenGLRenderer"
+
+#include "AssetAtlas.h"
+#include "Caches.h"
+
+#include <GLES2/gl2ext.h>
+
+namespace android {
+namespace uirenderer {
+
+///////////////////////////////////////////////////////////////////////////////
+// Lifecycle
+///////////////////////////////////////////////////////////////////////////////
+
+void AssetAtlas::init(sp<GraphicBuffer> buffer, int* map, int count) {
+    if (mImage) {
+        return;
+    }
+
+    mImage = new Image(buffer);
+
+    if (mImage->getTexture()) {
+        Caches& caches = Caches::getInstance();
+
+        mTexture = new Texture(caches);
+        mTexture->id = mImage->getTexture();
+        mTexture->width = buffer->getWidth();
+        mTexture->height = buffer->getHeight();
+
+        createEntries(caches, map, count);
+    } else {
+        ALOGW("Could not create atlas image");
+
+        delete mImage;
+        mImage = NULL;
+        mTexture = NULL;
+    }
+
+    mGenerationId++;
+}
+
+void AssetAtlas::terminate() {
+    if (mImage) {
+        delete mImage;
+        mImage = NULL;
+
+        delete mTexture;
+        mTexture = NULL;
+
+        for (size_t i = 0; i < mEntries.size(); i++) {
+            delete mEntries.valueAt(i);
+        }
+        mEntries.clear();
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Entries
+///////////////////////////////////////////////////////////////////////////////
+
+AssetAtlas::Entry* AssetAtlas::getEntry(SkBitmap* const bitmap) const {
+    ssize_t index = mEntries.indexOfKey(bitmap);
+    return index >= 0 ? mEntries.valueAt(index) : NULL;
+}
+
+Texture* AssetAtlas::getEntryTexture(SkBitmap* const bitmap) const {
+    ssize_t index = mEntries.indexOfKey(bitmap);
+    return index >= 0 ? mEntries.valueAt(index)->texture : NULL;
+}
+
+/**
+ * Delegates changes to wrapping and filtering to the base atlas texture
+ * instead of applying the changes to the virtual textures.
+ */
+struct DelegateTexture: public Texture {
+    DelegateTexture(Caches& caches, Texture* delegate): Texture(caches), mDelegate(delegate) { }
+
+    virtual void setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture = false,
+            bool force = false, GLenum renderTarget = GL_TEXTURE_2D) {
+        mDelegate->setWrapST(wrapS, wrapT, bindTexture, force, renderTarget);
+    }
+
+    virtual void setFilterMinMag(GLenum min, GLenum mag, bool bindTexture = false,
+            bool force = false, GLenum renderTarget = GL_TEXTURE_2D) {
+        mDelegate->setFilterMinMag(min, mag, bindTexture, force, renderTarget);
+    }
+
+private:
+    Texture* const mDelegate;
+}; // struct DelegateTexture
+
+/**
+ * TODO: This method does not take the rotation flag into account
+ */
+void AssetAtlas::createEntries(Caches& caches, int* map, int count) {
+    const float width = float(mTexture->width);
+    const float height = float(mTexture->height);
+
+    for (int i = 0; i < count; ) {
+        SkBitmap* bitmap = (SkBitmap*) map[i++];
+        int x = map[i++];
+        int y = map[i++];
+        bool rotated = map[i++] > 0;
+
+        // Bitmaps should never be null, we're just extra paranoid
+        if (!bitmap) continue;
+
+        const UvMapper mapper(
+                x / width, (x + bitmap->width()) / width,
+                y / height, (y + bitmap->height()) / height);
+
+        Texture* texture = new DelegateTexture(caches, mTexture);
+        texture->id = mTexture->id;
+        texture->blend = !bitmap->isOpaque();
+        texture->width = bitmap->width();
+        texture->height = bitmap->height();
+
+        Entry* entry = new Entry(bitmap, x, y, rotated, texture, mapper, *this);
+        texture->uvMapper = &entry->uvMapper;
+
+        mEntries.add(entry->bitmap, entry);
+    }
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/AssetAtlas.h b/libs/hwui/AssetAtlas.h
new file mode 100644
index 0000000..a28efc6
--- /dev/null
+++ b/libs/hwui/AssetAtlas.h
@@ -0,0 +1,195 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HWUI_ASSET_ATLAS_H
+#define ANDROID_HWUI_ASSET_ATLAS_H
+
+#include <GLES2/gl2.h>
+
+#include <ui/GraphicBuffer.h>
+
+#include <utils/KeyedVector.h>
+
+#include <cutils/compiler.h>
+
+#include <SkBitmap.h>
+
+#include "Image.h"
+#include "Texture.h"
+#include "UvMapper.h"
+
+namespace android {
+namespace uirenderer {
+
+class Caches;
+
+/**
+ * An asset atlas holds a collection of framework bitmaps in a single OpenGL
+ * texture. Each bitmap is associated with a location, defined in pixels,
+ * inside the atlas. The atlas is generated by the framework and bound as
+ * an external texture using the EGLImageKHR extension.
+ */
+class AssetAtlas {
+public:
+    /**
+     * Entry representing the position and rotation of a
+     * bitmap inside the atlas.
+     */
+    struct Entry {
+        /**
+         * The bitmap that generated this atlas entry.
+         */
+        SkBitmap* bitmap;
+
+        /**
+         * Location of the bitmap inside the atlas, in pixels.
+         */
+        int x;
+        int y;
+
+        /**
+         * If set, the bitmap is rotated 90 degrees (clockwise)
+         * inside the atlas.
+         */
+        bool rotated;
+
+        /*
+         * A "virtual texture" object that represents the texture
+         * this entry belongs to. This texture should never be
+         * modified.
+         */
+        Texture* texture;
+
+        /**
+         * Maps texture coordinates in the [0..1] range into the
+         * correct range to sample this entry from the atlas.
+         */
+        const UvMapper uvMapper;
+
+        /**
+         * Atlas this entry belongs to.
+         */
+        const AssetAtlas& atlas;
+
+        /**
+         * Unique identifier used to merge bitmaps and 9-patches stored
+         * in the atlas.
+         */
+        const void* getMergeId() const {
+            return texture->blend ? &atlas.mBlendKey : &atlas.mOpaqueKey;
+        }
+
+    private:
+        Entry(SkBitmap* bitmap, int x, int y, bool rotated,
+                Texture* texture, const UvMapper& mapper, const AssetAtlas& atlas):
+                bitmap(bitmap), x(x), y(y), rotated(rotated),
+                texture(texture), uvMapper(mapper), atlas(atlas) {
+        }
+
+        ~Entry() {
+            delete texture;
+        }
+
+        friend class AssetAtlas;
+    };
+
+    AssetAtlas(): mTexture(NULL), mImage(NULL), mGenerationId(0),
+            mBlendKey(true), mOpaqueKey(false) { }
+    ~AssetAtlas() { terminate(); }
+
+    /**
+     * Initializes the atlas with the specified buffer and
+     * map. The buffer is a gralloc'd texture that will be
+     * used as an EGLImage. The map is a list of SkBitmap*
+     * and their (x, y) positions as well as their rotation
+     * flags.
+     *
+     * This method returns immediately if the atlas is already
+     * initialized. To re-initialize the atlas, you must
+     * first call terminate().
+     */
+    ANDROID_API void init(sp<GraphicBuffer> buffer, int* map, int count);
+
+    /**
+     * Destroys the atlas texture. This object can be
+     * re-initialized after calling this method.
+     *
+     * After calling this method, the width, height
+     * and texture are set to 0.
+     */
+    ANDROID_API void terminate();
+
+    /**
+     * Returns the width of this atlas in pixels.
+     * Can return 0 if the atlas is not initialized.
+     */
+    uint32_t getWidth() const {
+        return mTexture ? mTexture->width : 0;
+    }
+
+    /**
+     * Returns the height of this atlas in pixels.
+     * Can return 0 if the atlas is not initialized.
+     */
+    uint32_t getHeight() const {
+        return mTexture ? mTexture->height : 0;
+    }
+
+    /**
+     * Returns the OpenGL name of the texture backing this atlas.
+     * Can return 0 if the atlas is not initialized.
+     */
+    GLuint getTexture() const {
+        return mTexture ? mTexture->id : 0;
+    }
+
+    /**
+     * Returns the entry in the atlas associated with the specified
+     * bitmap. If the bitmap is not in the atlas, return NULL.
+     */
+    Entry* getEntry(SkBitmap* const bitmap) const;
+
+    /**
+     * Returns the texture for the atlas entry associated with the
+     * specified bitmap. If the bitmap is not in the atlas, return NULL.
+     */
+    Texture* getEntryTexture(SkBitmap* const bitmap) const;
+
+    /**
+     * Returns the current generation id of the atlas.
+     */
+    uint32_t getGenerationId() const {
+        return mGenerationId;
+    }
+
+private:
+    void createEntries(Caches& caches, int* map, int count);
+
+    Texture* mTexture;
+    Image* mImage;
+
+    uint32_t mGenerationId;
+
+    const bool mBlendKey;
+    const bool mOpaqueKey;
+
+    KeyedVector<SkBitmap*, Entry*> mEntries;
+}; // class AssetAtlas
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_HWUI_ASSET_ATLAS_H
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index a381a68..f8d3589 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -47,19 +47,21 @@
 // Constructors/destructor
 ///////////////////////////////////////////////////////////////////////////////
 
-Caches::Caches(): Singleton<Caches>(), mExtensions(Extensions::getInstance()), mInitialized(false) {
+Caches::Caches(): Singleton<Caches>(),
+        mExtensions(Extensions::getInstance()), mInitialized(false) {
     init();
     initFont();
     initConstraints();
     initProperties();
+    initStaticProperties();
     initExtensions();
 
     mDebugLevel = readDebugLevel();
     ALOGD("Enabling debug mode %d", mDebugLevel);
 }
 
-void Caches::init() {
-    if (mInitialized) return;
+bool Caches::init() {
+    if (mInitialized) return false;
 
     glGenBuffers(1, &meshBuffer);
     glBindBuffer(GL_ARRAY_BUFFER, meshBuffer);
@@ -82,6 +84,7 @@
     mTextureUnit = 0;
 
     mRegionMesh = NULL;
+    mMeshIndices = 0;
 
     blend = false;
     lastSrcMode = GL_ZERO;
@@ -94,7 +97,13 @@
     debugOverdraw = false;
     debugStencilClip = kStencilHide;
 
+    patchCache.init(*this);
+
     mInitialized = true;
+
+    resetBoundTextures();
+
+    return true;
 }
 
 void Caches::initFont() {
@@ -132,6 +141,18 @@
     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
 }
 
+void Caches::initStaticProperties() {
+    gpuPixelBuffersEnabled = false;
+
+    // OpenGL ES 3.0+ specific features
+    if (mExtensions.hasPixelBufferObjects()) {
+        char property[PROPERTY_VALUE_MAX];
+        if (property_get(PROPERTY_ENABLE_GPU_PIXEL_BUFFERS, property, "true") > 0) {
+            gpuPixelBuffersEnabled = !strcmp(property, "true");
+        }
+    }
+}
+
 bool Caches::initProperties() {
     bool prevDebugLayersUpdates = debugLayersUpdates;
     bool prevDebugOverdraw = debugOverdraw;
@@ -145,11 +166,16 @@
         debugLayersUpdates = false;
     }
 
+    debugOverdraw = false;
     if (property_get(PROPERTY_DEBUG_OVERDRAW, property, NULL) > 0) {
         INIT_LOGD("  Overdraw debug enabled: %s", property);
-        debugOverdraw = !strcmp(property, "true");
-    } else {
-        debugOverdraw = false;
+        if (!strcmp(property, "show")) {
+            debugOverdraw = true;
+            mOverdrawDebugColorSet = kColorSet_Default;
+        } else if (!strcmp(property, "show_deuteranomaly")) {
+            debugOverdraw = true;
+            mOverdrawDebugColorSet = kColorSet_Deuteranomaly;
+        }
     }
 
     // See Properties.h for valid values
@@ -191,8 +217,9 @@
     glDeleteBuffers(1, &meshBuffer);
     mCurrentBuffer = 0;
 
-    glDeleteBuffers(1, &mRegionMeshIndices);
+    glDeleteBuffers(1, &mMeshIndices);
     delete[] mRegionMesh;
+    mMeshIndices = 0;
     mRegionMesh = NULL;
 
     fboCache.clear();
@@ -200,6 +227,12 @@
     programCache.clear();
     currentProgram = NULL;
 
+    assetAtlas.terminate();
+
+    patchCache.clear();
+
+    clearGarbage();
+
     mInitialized = false;
 }
 
@@ -207,6 +240,16 @@
 // Debug
 ///////////////////////////////////////////////////////////////////////////////
 
+uint32_t Caches::getOverdrawColor(uint32_t amount) const {
+    static uint32_t sOverdrawColors[2][4] = {
+            { 0x2f0000ff, 0x2f00ff00, 0x3fff0000, 0x7fff0000 },
+            { 0x2f0000ff, 0x4fffff00, 0x5fff8ad8, 0x7fff0000 }
+    };
+    if (amount < 1) amount = 1;
+    if (amount > 4) amount = 4;
+    return sOverdrawColors[mOverdrawDebugColorSet][amount - 1];
+}
+
 void Caches::dumpMemoryUsage() {
     String8 stringLog;
     dumpMemoryUsage(stringLog);
@@ -227,15 +270,19 @@
             pathCache.getSize(), pathCache.getMaxSize());
     log.appendFormat("  TextDropShadowCache  %8d / %8d\n", dropShadowCache.getSize(),
             dropShadowCache.getMaxSize());
+    log.appendFormat("  PatchCache           %8d / %8d\n",
+            patchCache.getSize(), patchCache.getMaxSize());
     for (uint32_t i = 0; i < fontRenderer->getFontRendererCount(); i++) {
-        const uint32_t size = fontRenderer->getFontRendererSize(i);
-        log.appendFormat("  FontRenderer %d       %8d / %8d\n", i, size, size);
+        const uint32_t sizeA8 = fontRenderer->getFontRendererSize(i, GL_ALPHA);
+        const uint32_t sizeRGBA = fontRenderer->getFontRendererSize(i, GL_RGBA);
+        log.appendFormat("  FontRenderer %d A8    %8d / %8d\n", i, sizeA8, sizeA8);
+        log.appendFormat("  FontRenderer %d RGBA  %8d / %8d\n", i, sizeRGBA, sizeRGBA);
+        log.appendFormat("  FontRenderer %d total %8d / %8d\n", i, sizeA8 + sizeRGBA,
+                sizeA8 + sizeRGBA);
     }
     log.appendFormat("Other:\n");
     log.appendFormat("  FboCache             %8d / %8d\n",
             fboCache.getSize(), fboCache.getMaxSize());
-    log.appendFormat("  PatchCache           %8d / %8d\n",
-            patchCache.getSize(), patchCache.getMaxSize());
 
     uint32_t total = 0;
     total += textureCache.getSize();
@@ -244,8 +291,10 @@
     total += gradientCache.getSize();
     total += pathCache.getSize();
     total += dropShadowCache.getSize();
+    total += patchCache.getSize();
     for (uint32_t i = 0; i < fontRenderer->getFontRendererCount(); i++) {
-        total += fontRenderer->getFontRendererSize(i);
+        total += fontRenderer->getFontRendererSize(i, GL_ALPHA);
+        total += fontRenderer->getFontRendererSize(i, GL_RGBA);
     }
 
     log.appendFormat("Total memory usage:\n");
@@ -259,6 +308,7 @@
 void Caches::clearGarbage() {
     textureCache.clearGarbage();
     pathCache.clearGarbage();
+    patchCache.clearGarbage();
 
     Vector<DisplayList*> displayLists;
     Vector<Layer*> layers;
@@ -298,6 +348,11 @@
 void Caches::flush(FlushMode mode) {
     FLUSH_LOGD("Flushing caches (mode %d)", mode);
 
+    // We must stop tasks before clearing caches
+    if (mode > kFlushMode_Layers) {
+        tasks.stop();
+    }
+
     switch (mode) {
         case kFlushMode_Full:
             textureCache.clear();
@@ -305,13 +360,13 @@
             dropShadowCache.clear();
             gradientCache.clear();
             fontRenderer->clear();
+            fboCache.clear();
             dither.clear();
             // fall through
         case kFlushMode_Moderate:
             fontRenderer->flush();
             textureCache.flush();
             pathCache.clear();
-            tasks.stop();
             // fall through
         case kFlushMode_Layers:
             layerCache.clear();
@@ -357,6 +412,32 @@
     return false;
 }
 
+bool Caches::bindIndicesBuffer() {
+    if (!mMeshIndices) {
+        uint16_t* regionIndices = new uint16_t[gMaxNumberOfQuads * 6];
+        for (uint32_t i = 0; i < gMaxNumberOfQuads; i++) {
+            uint16_t quad = i * 4;
+            int index = i * 6;
+            regionIndices[index    ] = quad;       // top-left
+            regionIndices[index + 1] = quad + 1;   // top-right
+            regionIndices[index + 2] = quad + 2;   // bottom-left
+            regionIndices[index + 3] = quad + 2;   // bottom-left
+            regionIndices[index + 4] = quad + 1;   // top-right
+            regionIndices[index + 5] = quad + 3;   // bottom-right
+        }
+
+        glGenBuffers(1, &mMeshIndices);
+        bool force = bindIndicesBuffer(mMeshIndices);
+        glBufferData(GL_ELEMENT_ARRAY_BUFFER, gMaxNumberOfQuads * 6 * sizeof(uint16_t),
+                regionIndices, GL_STATIC_DRAW);
+
+        delete[] regionIndices;
+        return force;
+    }
+
+    return bindIndicesBuffer(mMeshIndices);
+}
+
 bool Caches::unbindIndicesBuffer() {
     if (mCurrentIndicesBuffer) {
         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
@@ -441,6 +522,50 @@
     }
 }
 
+void Caches::resetActiveTexture() {
+    mTextureUnit = -1;
+}
+
+void Caches::bindTexture(GLuint texture) {
+    if (mBoundTextures[mTextureUnit] != texture) {
+        glBindTexture(GL_TEXTURE_2D, texture);
+        mBoundTextures[mTextureUnit] = texture;
+    }
+}
+
+void Caches::bindTexture(GLenum target, GLuint texture) {
+    if (mBoundTextures[mTextureUnit] != texture) {
+        glBindTexture(target, texture);
+        mBoundTextures[mTextureUnit] = texture;
+    }
+}
+
+void Caches::deleteTexture(GLuint texture) {
+    // When glDeleteTextures() is called on a currently bound texture,
+    // OpenGL ES specifies that the texture is then considered unbound
+    // Consider the following series of calls:
+    //
+    // glGenTextures -> creates texture name 2
+    // glBindTexture(2)
+    // glDeleteTextures(2) -> 2 is now unbound
+    // glGenTextures -> can return 2 again
+    //
+    // If we don't call glBindTexture(2) after the second glGenTextures
+    // call, any texture operation will be performed on the default
+    // texture (name=0)
+
+    for (int i = 0; i < REQUIRED_TEXTURE_UNITS_COUNT; i++) {
+        if (mBoundTextures[i] == texture) {
+            mBoundTextures[i] = 0;
+        }
+    }
+    glDeleteTextures(1, &texture);
+}
+
+void Caches::resetBoundTextures() {
+    memset(mBoundTextures, 0, REQUIRED_TEXTURE_UNITS_COUNT * sizeof(GLuint));
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 // Scissor
 ///////////////////////////////////////////////////////////////////////////////
@@ -545,28 +670,7 @@
 TextureVertex* Caches::getRegionMesh() {
     // Create the mesh, 2 triangles and 4 vertices per rectangle in the region
     if (!mRegionMesh) {
-        mRegionMesh = new TextureVertex[REGION_MESH_QUAD_COUNT * 4];
-
-        uint16_t* regionIndices = new uint16_t[REGION_MESH_QUAD_COUNT * 6];
-        for (int i = 0; i < REGION_MESH_QUAD_COUNT; i++) {
-            uint16_t quad = i * 4;
-            int index = i * 6;
-            regionIndices[index    ] = quad;       // top-left
-            regionIndices[index + 1] = quad + 1;   // top-right
-            regionIndices[index + 2] = quad + 2;   // bottom-left
-            regionIndices[index + 3] = quad + 2;   // bottom-left
-            regionIndices[index + 4] = quad + 1;   // top-right
-            regionIndices[index + 5] = quad + 3;   // bottom-right
-        }
-
-        glGenBuffers(1, &mRegionMeshIndices);
-        bindIndicesBuffer(mRegionMeshIndices);
-        glBufferData(GL_ELEMENT_ARRAY_BUFFER, REGION_MESH_QUAD_COUNT * 6 * sizeof(uint16_t),
-                regionIndices, GL_STATIC_DRAW);
-
-        delete[] regionIndices;
-    } else {
-        bindIndicesBuffer(mRegionMeshIndices);
+        mRegionMesh = new TextureVertex[gMaxNumberOfQuads * 4];
     }
 
     return mRegionMesh;
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 91b938b..282aee9 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -21,13 +21,18 @@
     #define LOG_TAG "OpenGLRenderer"
 #endif
 
+#include <GLES3/gl3.h>
+
+#include <utils/KeyedVector.h>
 #include <utils/Singleton.h>
+#include <utils/Vector.h>
 
 #include <cutils/compiler.h>
 
 #include "thread/TaskProcessor.h"
 #include "thread/TaskManager.h"
 
+#include "AssetAtlas.h"
 #include "FontRenderer.h"
 #include "GammaFontRenderer.h"
 #include "TextureCache.h"
@@ -50,9 +55,11 @@
 // Globals
 ///////////////////////////////////////////////////////////////////////////////
 
+// GL ES 2.0 defines that at least 16 texture units must be supported
 #define REQUIRED_TEXTURE_UNITS_COUNT 3
 
-#define REGION_MESH_QUAD_COUNT 512
+// Maximum number of quads that pre-allocated meshes can draw
+static const uint32_t gMaxNumberOfQuads = 2048;
 
 // Generates simple and textured vertices
 #define FV(x, y, u, v) { { x, y }, { u, v } }
@@ -74,6 +81,7 @@
 static const GLsizei gVertexAALengthOffset = 3 * sizeof(float);
 static const GLsizei gMeshCount = 4;
 
+// Must define as many texture units as specified by REQUIRED_TEXTURE_UNITS_COUNT
 static const GLenum gTextureUnits[] = {
     GL_TEXTURE0,
     GL_TEXTURE1,
@@ -113,7 +121,7 @@
     /**
      * Initialize caches.
      */
-    void init();
+    bool init();
 
     /**
      * Initialize global system properties.
@@ -142,6 +150,12 @@
     }
 
     /**
+     * Returns a non-premultiplied ARGB color for the specified
+     * amount of overdraw (1 for 1x, 2 for 2x, etc.)
+     */
+    uint32_t getOverdrawColor(uint32_t amount) const;
+
+    /**
      * Call this on each frame to ensure that garbage is deleted from
      * GPU memory.
      */
@@ -172,6 +186,11 @@
      */
     bool unbindMeshBuffer();
 
+    /**
+     * Binds a global indices buffer that can draw up to
+     * gMaxNumberOfQuads quads.
+     */
+    bool bindIndicesBuffer();
     bool bindIndicesBuffer(const GLuint buffer);
     bool unbindIndicesBuffer();
 
@@ -213,6 +232,38 @@
     void activeTexture(GLuint textureUnit);
 
     /**
+     * Invalidate the cached value of the active texture unit.
+     */
+    void resetActiveTexture();
+
+    /**
+     * Binds the specified texture as a GL_TEXTURE_2D texture.
+     * All texture bindings must be performed with this method or
+     * bindTexture(GLenum, GLuint).
+     */
+    void bindTexture(GLuint texture);
+
+    /**
+     * Binds the specified texture with the specified render target.
+     * All texture bindings must be performed with this method or
+     * bindTexture(GLuint).
+     */
+    void bindTexture(GLenum target, GLuint texture);
+
+    /**
+     * Deletes the specified texture and clears it from the cache
+     * of bound textures.
+     * All textures must be deleted using this method.
+     */
+    void deleteTexture(GLuint texture);
+
+    /**
+     * Signals that the cache of bound textures should be cleared.
+     * Other users of the context may have altered which textures are bound.
+     */
+    void resetBoundTextures();
+
+    /**
      * Sets the scissor for the current surface.
      */
     bool setScissor(GLint x, GLint y, GLint width, GLint height);
@@ -290,6 +341,10 @@
     Dither dither;
     Stencil stencil;
 
+    AssetAtlas assetAtlas;
+
+    bool gpuPixelBuffersEnabled;
+
     // Debug methods
     PFNGLINSERTEVENTMARKEREXTPROC eventMark;
     PFNGLPUSHGROUPMARKEREXTPROC startMark;
@@ -299,9 +354,15 @@
     PFNGLGETOBJECTLABELEXTPROC getLabel;
 
 private:
+    enum OverdrawColorSet {
+        kColorSet_Default = 0,
+        kColorSet_Deuteranomaly
+    };
+
     void initFont();
     void initExtensions();
     void initConstraints();
+    void initStaticProperties();
 
     static void eventMarkNull(GLsizei length, const GLchar* marker) { }
     static void startMarkNull(GLsizei length, const GLchar* marker) { }
@@ -336,7 +397,9 @@
 
     // Used to render layers
     TextureVertex* mRegionMesh;
-    GLuint mRegionMeshIndices;
+
+    // Global index buffer
+    GLuint mMeshIndices;
 
     mutable Mutex mGarbageLock;
     Vector<Layer*> mLayerGarbage;
@@ -346,6 +409,10 @@
     bool mInitialized;
 
     uint32_t mFunctorsCount;
+
+    GLuint mBoundTextures[REQUIRED_TEXTURE_UNITS_COUNT];
+
+    OverdrawColorSet mOverdrawDebugColorSet;
 }; // class Caches
 
 }; // namespace uirenderer
diff --git a/libs/hwui/Debug.h b/libs/hwui/Debug.h
index 790c4f4..786f12a 100644
--- a/libs/hwui/Debug.h
+++ b/libs/hwui/Debug.h
@@ -53,8 +53,6 @@
 
 // Turn on to display debug info about 9patch objects
 #define DEBUG_PATCHES 0
-// Turn on to "explode" 9patch objects
-#define DEBUG_EXPLODE_PATCHES 0
 // Turn on to display vertex and tex coords data about 9patch objects
 // This flag requires DEBUG_PATCHES to be turned on
 #define DEBUG_PATCHES_VERTICES 0
diff --git a/libs/hwui/DeferredDisplayList.cpp b/libs/hwui/DeferredDisplayList.cpp
index 9323a3a..c0b77c7 100644
--- a/libs/hwui/DeferredDisplayList.cpp
+++ b/libs/hwui/DeferredDisplayList.cpp
@@ -20,6 +20,8 @@
 #include <SkCanvas.h>
 
 #include <utils/Trace.h>
+#include <ui/Rect.h>
+#include <ui/Region.h>
 
 #include "Caches.h"
 #include "Debug.h"
@@ -51,32 +53,36 @@
 public:
     virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int index) = 0;
     virtual ~Batch() {}
+    virtual bool purelyDrawBatch() { return false; }
+    virtual bool coversBounds(const Rect& bounds) { return false; }
 };
 
 class DrawBatch : public Batch {
 public:
-    DrawBatch(int batchId, mergeid_t mergeId) : mBatchId(batchId), mMergeId(mergeId) {
+    DrawBatch(const DeferInfo& deferInfo) : mAllOpsOpaque(true),
+            mBatchId(deferInfo.batchId), mMergeId(deferInfo.mergeId) {
         mOps.clear();
     }
 
     virtual ~DrawBatch() { mOps.clear(); }
 
-    void add(DrawOp* op) {
+    virtual void add(DrawOp* op, const DeferredDisplayState* state, bool opaqueOverBounds) {
         // NOTE: ignore empty bounds special case, since we don't merge across those ops
-        mBounds.unionWith(op->state.mBounds);
-        mOps.add(op);
+        mBounds.unionWith(state->mBounds);
+        mAllOpsOpaque &= opaqueOverBounds;
+        mOps.add(OpStatePair(op, state));
     }
 
-    bool intersects(Rect& rect) {
+    bool intersects(const Rect& rect) {
         if (!rect.intersects(mBounds)) return false;
 
         for (unsigned int i = 0; i < mOps.size(); i++) {
-            if (rect.intersects(mOps[i]->state.mBounds)) {
+            if (rect.intersects(mOps[i].state->mBounds)) {
 #if DEBUG_DEFER
-                DEFER_LOGD("op intersects with op %p with bounds %f %f %f %f:", mOps[i],
-                        mOps[i]->state.mBounds.left, mOps[i]->state.mBounds.top,
-                        mOps[i]->state.mBounds.right, mOps[i]->state.mBounds.bottom);
-                mOps[i]->output(2);
+                DEFER_LOGD("op intersects with op %p with bounds %f %f %f %f:", mOps[i].op,
+                        mOps[i].state->mBounds.left, mOps[i].state->mBounds.top,
+                        mOps[i].state->mBounds.right, mOps[i].state->mBounds.bottom);
+                mOps[i].op->output(2);
 #endif
                 return true;
             }
@@ -85,15 +91,15 @@
     }
 
     virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int index) {
-        DEFER_LOGD("%d  replaying DrawingBatch %p, with %d ops (batch id %x, merge id %p)",
-                index, this, mOps.size(), mOps[0]->getBatchId(), mOps[0]->getMergeId());
+        DEFER_LOGD("%d  replaying DrawBatch %p, with %d ops (batch id %x, merge id %p)",
+                index, this, mOps.size(), getBatchId(), getMergeId());
 
         status_t status = DrawGlInfo::kStatusDone;
         DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
         for (unsigned int i = 0; i < mOps.size(); i++) {
-            DrawOp* op = mOps[i];
-
-            renderer.restoreDisplayState(op->state);
+            DrawOp* op = mOps[i].op;
+            const DeferredDisplayState* state = mOps[i].state;
+            renderer.restoreDisplayState(*state);
 
 #if DEBUG_DISPLAY_LIST_OPS_AS_EVENTS
             renderer.eventMark(op->name());
@@ -102,7 +108,7 @@
             status |= op->applyDraw(renderer, dirty);
 
 #if DEBUG_MERGE_BEHAVIOR
-            Rect& bounds = mOps[i]->state.mBounds;
+            const Rect& bounds = state->mBounds;
             int batchColor = 0x1f000000;
             if (getBatchId() & 0x1) batchColor |= 0x0000ff;
             if (getBatchId() & 0x2) batchColor |= 0x00ff00;
@@ -114,14 +120,28 @@
         return status;
     }
 
+    virtual bool purelyDrawBatch() { return true; }
+
+    virtual bool coversBounds(const Rect& bounds) {
+        if (CC_LIKELY(!mAllOpsOpaque || !mBounds.contains(bounds) || count() == 1)) return false;
+
+        Region uncovered(android::Rect(bounds.left, bounds.top, bounds.right, bounds.bottom));
+        for (unsigned int i = 0; i < mOps.size(); i++) {
+            const Rect &r = mOps[i].state->mBounds;
+            uncovered.subtractSelf(android::Rect(r.left, r.top, r.right, r.bottom));
+        }
+        return uncovered.isEmpty();
+    }
+
     inline int getBatchId() const { return mBatchId; }
     inline mergeid_t getMergeId() const { return mMergeId; }
     inline int count() const { return mOps.size(); }
 
 protected:
-    Vector<DrawOp*> mOps;
-    Rect mBounds;
+    Vector<OpStatePair> mOps;
+    Rect mBounds; // union of bounds of contained ops
 private:
+    bool mAllOpsOpaque;
     int mBatchId;
     mergeid_t mMergeId;
 };
@@ -132,39 +152,77 @@
 
 class MergingDrawBatch : public DrawBatch {
 public:
-    MergingDrawBatch(int batchId, mergeid_t mergeId) : DrawBatch(batchId, mergeId) {}
+    MergingDrawBatch(DeferInfo& deferInfo, int width, int height) :
+            DrawBatch(deferInfo), mClipRect(width, height),
+            mClipSideFlags(kClipSide_None) {}
+
+    /*
+     * Helper for determining if a new op can merge with a MergingDrawBatch based on their bounds
+     * and clip side flags. Positive bounds delta means new bounds fit in old.
+     */
+    static inline bool checkSide(const int currentFlags, const int newFlags, const int side,
+            float boundsDelta) {
+        bool currentClipExists = currentFlags & side;
+        bool newClipExists = newFlags & side;
+
+        // if current is clipped, we must be able to fit new bounds in current
+        if (boundsDelta > 0 && currentClipExists) return false;
+
+        // if new is clipped, we must be able to fit current bounds in new
+        if (boundsDelta < 0 && newClipExists) return false;
+
+        return true;
+    }
 
     /*
      * Checks if a (mergeable) op can be merged into this batch
      *
      * If true, the op's multiDraw must be guaranteed to handle both ops simultaneously, so it is
      * important to consider all paint attributes used in the draw calls in deciding both a) if an
-     * op tries to merge at all, and b) if the op
+     * op tries to merge at all, and b) if the op can merge with another set of ops
      *
      * False positives can lead to information from the paints of subsequent merged operations being
      * dropped, so we make simplifying qualifications on the ops that can merge, per op type.
      */
-    bool canMergeWith(DrawOp* op) {
-        if (!op->state.mMatrix.isPureTranslate()) return false;
-
+    bool canMergeWith(const DrawOp* op, const DeferredDisplayState* state) {
         bool isTextBatch = getBatchId() == DeferredDisplayList::kOpBatch_Text ||
                 getBatchId() == DeferredDisplayList::kOpBatch_ColorText;
 
         // Overlapping other operations is only allowed for text without shadow. For other ops,
         // multiDraw isn't guaranteed to overdraw correctly
-        if (!isTextBatch || op->state.mDrawModifiers.mHasShadow) {
-            if (intersects(op->state.mBounds)) return false;
+        if (!isTextBatch || state->mDrawModifiers.mHasShadow) {
+            if (intersects(state->mBounds)) return false;
+        }
+        const DeferredDisplayState* lhs = state;
+        const DeferredDisplayState* rhs = mOps[0].state;
+
+        if (NEQ_FALPHA(lhs->mAlpha, rhs->mAlpha)) return false;
+
+        /* Clipping compatibility check
+         *
+         * Exploits the fact that if a op or batch is clipped on a side, its bounds will equal its
+         * clip for that side.
+         */
+        const int currentFlags = mClipSideFlags;
+        const int newFlags = state->mClipSideFlags;
+        if (currentFlags != kClipSide_None || newFlags != kClipSide_None) {
+            const Rect& opBounds = state->mBounds;
+            float boundsDelta = mBounds.left - opBounds.left;
+            if (!checkSide(currentFlags, newFlags, kClipSide_Left, boundsDelta)) return false;
+            boundsDelta = mBounds.top - opBounds.top;
+            if (!checkSide(currentFlags, newFlags, kClipSide_Top, boundsDelta)) return false;
+
+            // right and bottom delta calculation reversed to account for direction
+            boundsDelta = opBounds.right - mBounds.right;
+            if (!checkSide(currentFlags, newFlags, kClipSide_Right, boundsDelta)) return false;
+            boundsDelta = opBounds.bottom - mBounds.bottom;
+            if (!checkSide(currentFlags, newFlags, kClipSide_Bottom, boundsDelta)) return false;
         }
 
-        const DeferredDisplayState& lhs = op->state;
-        const DeferredDisplayState& rhs = mOps[0]->state;
-
-        if (NEQ_FALPHA(lhs.mAlpha, rhs.mAlpha)) return false;
-
         // if paints are equal, then modifiers + paint attribs don't need to be compared
-        if (op->mPaint == mOps[0]->mPaint) return true;
+        if (op->mPaint == mOps[0].op->mPaint) return true;
 
-        if (op->getPaintAlpha() != mOps[0]->getPaintAlpha()) return false;
+        if (op->getPaintAlpha() != mOps[0].op->getPaintAlpha()) return false;
 
         /* Draw Modifiers compatibility check
          *
@@ -178,9 +236,8 @@
          *
          * These ignore cases prevent us from simply memcmp'ing the drawModifiers
          */
-
-        const DrawModifiers& lhsMod = lhs.mDrawModifiers;
-        const DrawModifiers& rhsMod = rhs.mDrawModifiers;
+        const DrawModifiers& lhsMod = lhs->mDrawModifiers;
+        const DrawModifiers& rhsMod = rhs->mDrawModifiers;
         if (lhsMod.mShader != rhsMod.mShader) return false;
         if (lhsMod.mColorFilter != rhsMod.mColorFilter) return false;
 
@@ -192,14 +249,29 @@
         return true;
     }
 
+    virtual void add(DrawOp* op, const DeferredDisplayState* state, bool opaqueOverBounds) {
+        DrawBatch::add(op, state, opaqueOverBounds);
+
+        const int newClipSideFlags = state->mClipSideFlags;
+        mClipSideFlags |= newClipSideFlags;
+        if (newClipSideFlags & kClipSide_Left) mClipRect.left = state->mClip.left;
+        if (newClipSideFlags & kClipSide_Top) mClipRect.top = state->mClip.top;
+        if (newClipSideFlags & kClipSide_Right) mClipRect.right = state->mClip.right;
+        if (newClipSideFlags & kClipSide_Bottom) mClipRect.bottom = state->mClip.bottom;
+    }
+
     virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int index) {
-        DEFER_LOGD("%d  replaying DrawingBatch %p, with %d ops (batch id %x, merge id %p)",
-                index, this, mOps.size(), getBatchId(), getMergeId());
+        DEFER_LOGD("%d  replaying MergingDrawBatch %p, with %d ops,"
+                " clip flags %x (batch id %x, merge id %p)",
+                index, this, mOps.size(), mClipSideFlags, getBatchId(), getMergeId());
         if (mOps.size() == 1) {
-            return DrawBatch::replay(renderer, dirty, false);
+            return DrawBatch::replay(renderer, dirty, -1);
         }
 
-        DrawOp* op = mOps[0];
+        // clipping in the merged case is done ahead of time since all ops share the clip (if any)
+        renderer.setupMergedMultiDraw(mClipSideFlags ? &mClipRect : NULL);
+
+        DrawOp* op = mOps[0].op;
         DisplayListLogBuffer& buffer = DisplayListLogBuffer::getInstance();
         buffer.writeCommand(0, "multiDraw");
         buffer.writeCommand(1, op->name());
@@ -211,16 +283,25 @@
 #endif
         return status;
     }
+
+private:
+    /*
+     * Contains the effective clip rect shared by all merged ops. Initialized to the layer viewport,
+     * it will shrink if an op must be clipped on a certain side. The clipped sides are reflected in
+     * mClipSideFlags.
+     */
+    Rect mClipRect;
+    int mClipSideFlags;
 };
 
 class StateOpBatch : public Batch {
 public:
     // creates a single operation batch
-    StateOpBatch(StateOp* op) : mOp(op) {}
+    StateOpBatch(const StateOp* op, const DeferredDisplayState* state) : mOp(op), mState(state) {}
 
     virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int index) {
         DEFER_LOGD("replaying state op batch %p", this);
-        renderer.restoreDisplayState(mOp->state);
+        renderer.restoreDisplayState(*mState);
 
         // use invalid save count because it won't be used at flush time - RestoreToCountOp is the
         // only one to use it, and we don't use that class at flush time, instead calling
@@ -232,16 +313,18 @@
 
 private:
     const StateOp* mOp;
+    const DeferredDisplayState* mState;
 };
 
 class RestoreToCountBatch : public Batch {
 public:
-    RestoreToCountBatch(StateOp* op, int restoreCount) : mOp(op), mRestoreCount(restoreCount) {}
+    RestoreToCountBatch(const StateOp* op, const DeferredDisplayState* state, int restoreCount) :
+            mOp(op), mState(state), mRestoreCount(restoreCount) {}
 
     virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int index) {
         DEFER_LOGD("batch %p restoring to count %d", this, mRestoreCount);
 
-        renderer.restoreDisplayState(mOp->state);
+        renderer.restoreDisplayState(*mState);
         renderer.restoreToCount(mRestoreCount);
         return DrawGlInfo::kStatusDone;
     }
@@ -249,6 +332,8 @@
 private:
     // we use the state storage for the RestoreToCountOp, but don't replay the op itself
     const StateOp* mOp;
+    const DeferredDisplayState* mState;
+
     /*
      * The count used here represents the flush() time saveCount. This is as opposed to the
      * DisplayList record time, or defer() time values (which are RestoreToCountOp's mCount, and
@@ -294,6 +379,7 @@
     mBatches.clear();
     mSaveStack.clear();
     mEarliestBatchIndex = 0;
+    mEarliestUnclearedIndex = 0;
 }
 
 /////////////////////////////////////////////////////////////////////////////////
@@ -398,22 +484,45 @@
 }
 
 void DeferredDisplayList::addDrawOp(OpenGLRenderer& renderer, DrawOp* op) {
-    if (renderer.storeDisplayState(op->state, getDrawOpDeferFlags())) {
+    /* 1: op calculates local bounds */
+    DeferredDisplayState* const state = createState();
+    if (op->getLocalBounds(renderer.getDrawModifiers(), state->mBounds)) {
+        if (state->mBounds.isEmpty()) {
+            // valid empty bounds, don't bother deferring
+            tryRecycleState(state);
+            return;
+        }
+    } else {
+        state->mBounds.setEmpty();
+    }
+
+    /* 2: renderer calculates global bounds + stores state */
+    if (renderer.storeDisplayState(*state, getDrawOpDeferFlags())) {
+        tryRecycleState(state);
         return; // quick rejected
     }
 
-    int batchId = kOpBatch_None;
-    mergeid_t mergeId = (mergeid_t) -1;
-    bool mergeable = op->onDefer(renderer, &batchId, &mergeId);
+    /* 3: ask op for defer info, given renderer state */
+    DeferInfo deferInfo;
+    op->onDefer(renderer, deferInfo, *state);
 
     // complex clip has a complex set of expectations on the renderer state - for now, avoid taking
     // the merge path in those cases
-    mergeable &= !recordingComplexClip();
+    deferInfo.mergeable &= !recordingComplexClip();
+    deferInfo.opaqueOverBounds &= !recordingComplexClip() && mSaveStack.isEmpty();
+
+    if (CC_LIKELY(mAvoidOverdraw) && mBatches.size() &&
+            state->mClipSideFlags != kClipSide_ConservativeFull &&
+            deferInfo.opaqueOverBounds && state->mBounds.contains(mBounds)) {
+        // avoid overdraw by resetting drawing state + discarding drawing ops
+        discardDrawingBatches(mBatches.size() - 1);
+        resetBatchingState();
+    }
 
     if (CC_UNLIKELY(renderer.getCaches().drawReorderDisabled)) {
         // TODO: elegant way to reuse batches?
-        DrawBatch* b = new DrawBatch(batchId, mergeId);
-        b->add(op);
+        DrawBatch* b = new DrawBatch(deferInfo);
+        b->add(op, state, deferInfo.opaqueOverBounds);
         mBatches.add(b);
         return;
     }
@@ -425,10 +534,10 @@
     // (eventually, should be similar shader)
     int insertBatchIndex = mBatches.size();
     if (!mBatches.isEmpty()) {
-        if (op->state.mBounds.isEmpty()) {
+        if (state->mBounds.isEmpty()) {
             // don't know the bounds for op, so add to last batch and start from scratch on next op
-            DrawBatch* b = new DrawBatch(batchId, mergeId);
-            b->add(op);
+            DrawBatch* b = new DrawBatch(deferInfo);
+            b->add(op, state, deferInfo.opaqueOverBounds);
             mBatches.add(b);
             resetBatchingState();
 #if DEBUG_DEFER
@@ -438,19 +547,19 @@
             return;
         }
 
-        if (mergeable) {
+        if (deferInfo.mergeable) {
             // Try to merge with any existing batch with same mergeId.
-            if (mMergingBatches[batchId].get(mergeId, targetBatch)) {
-                if (!((MergingDrawBatch*) targetBatch)->canMergeWith(op)) {
+            if (mMergingBatches[deferInfo.batchId].get(deferInfo.mergeId, targetBatch)) {
+                if (!((MergingDrawBatch*) targetBatch)->canMergeWith(op, state)) {
                     targetBatch = NULL;
                 }
             }
         } else {
             // join with similar, non-merging batch
-            targetBatch = (DrawBatch*)mBatchLookup[batchId];
+            targetBatch = (DrawBatch*)mBatchLookup[deferInfo.batchId];
         }
 
-        if (targetBatch || mergeable) {
+        if (targetBatch || deferInfo.mergeable) {
             // iterate back toward target to see if anything drawn since should overlap the new op
             // if no target, merging ops still interate to find similar batch to insert after
             for (int i = mBatches.size() - 1; i >= mEarliestBatchIndex; i--) {
@@ -459,19 +568,19 @@
                 if (overBatch == targetBatch) break;
 
                 // TODO: also consider shader shared between batch types
-                if (batchId == overBatch->getBatchId()) {
+                if (deferInfo.batchId == overBatch->getBatchId()) {
                     insertBatchIndex = i + 1;
                     if (!targetBatch) break; // found insert position, quit
                 }
 
-                if (overBatch->intersects(op->state.mBounds)) {
+                if (overBatch->intersects(state->mBounds)) {
                     // NOTE: it may be possible to optimize for special cases where two operations
                     // of the same batch/paint could swap order, such as with a non-mergeable
                     // (clipped) and a mergeable text operation
                     targetBatch = NULL;
 #if DEBUG_DEFER
-                    DEFER_LOGD("op couldn't join batch %d, was intersected by batch %d",
-                            targetIndex, i);
+                    DEFER_LOGD("op couldn't join batch %p, was intersected by batch %d",
+                            targetBatch, i);
                     op->output(2);
 #endif
                     break;
@@ -481,27 +590,30 @@
     }
 
     if (!targetBatch) {
-        if (mergeable) {
-            targetBatch = new MergingDrawBatch(batchId, mergeId);
-            mMergingBatches[batchId].put(mergeId, targetBatch);
+        if (deferInfo.mergeable) {
+            targetBatch = new MergingDrawBatch(deferInfo,
+                    renderer.getViewportWidth(), renderer.getViewportHeight());
+            mMergingBatches[deferInfo.batchId].put(deferInfo.mergeId, targetBatch);
         } else {
-            targetBatch = new DrawBatch(batchId, mergeId);
-            mBatchLookup[batchId] = targetBatch;
-            DEFER_LOGD("creating Batch %p, bid %x, at %d",
-                    targetBatch, batchId, insertBatchIndex);
+            targetBatch = new DrawBatch(deferInfo);
+            mBatchLookup[deferInfo.batchId] = targetBatch;
         }
 
+        DEFER_LOGD("creating %singBatch %p, bid %x, at %d",
+                deferInfo.mergeable ? "Merg" : "Draw",
+                targetBatch, deferInfo.batchId, insertBatchIndex);
         mBatches.insertAt(targetBatch, insertBatchIndex);
     }
 
-    targetBatch->add(op);
+    targetBatch->add(op, state, deferInfo.opaqueOverBounds);
 }
 
 void DeferredDisplayList::storeStateOpBarrier(OpenGLRenderer& renderer, StateOp* op) {
     DEFER_LOGD("%p adding state op barrier at pos %d", this, mBatches.size());
 
-    renderer.storeDisplayState(op->state, getStateOpDeferFlags());
-    mBatches.add(new StateOpBatch(op));
+    DeferredDisplayState* state = createState();
+    renderer.storeDisplayState(*state, getStateOpDeferFlags());
+    mBatches.add(new StateOpBatch(op, state));
     resetBatchingState();
 }
 
@@ -512,8 +624,9 @@
 
     // store displayState for the restore operation, as it may be associated with a saveLayer that
     // doesn't have kClip_SaveFlag set
-    renderer.storeDisplayState(op->state, getStateOpDeferFlags());
-    mBatches.add(new RestoreToCountBatch(op, newSaveCount));
+    DeferredDisplayState* state = createState();
+    renderer.storeDisplayState(*state, getStateOpDeferFlags());
+    mBatches.add(new RestoreToCountBatch(op, state, newSaveCount));
     resetBatchingState();
 }
 
@@ -526,7 +639,9 @@
     status_t status = DrawGlInfo::kStatusDone;
 
     for (unsigned int i = 0; i < batchList.size(); i++) {
-        status |= batchList[i]->replay(renderer, dirty, i);
+        if (batchList[i]) {
+            status |= batchList[i]->replay(renderer, dirty, i);
+        }
     }
     DEFER_LOGD("--flushed, drew %d batches", batchList.size());
     return status;
@@ -548,6 +663,13 @@
     DrawModifiers restoreDrawModifiers = renderer.getDrawModifiers();
     renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
 
+    if (CC_LIKELY(mAvoidOverdraw)) {
+        for (unsigned int i = 1; i < mBatches.size(); i++) {
+            if (mBatches[i] && mBatches[i]->coversBounds(mBounds)) {
+                discardDrawingBatches(i - 1);
+            }
+        }
+    }
     // NOTE: depth of the save stack at this point, before playback, should be reflected in
     // FLUSH_SAVE_STACK_DEPTH, so that save/restores match up correctly
     status |= replayBatchList(mBatches, renderer, dirty);
@@ -560,5 +682,17 @@
     return status;
 }
 
+void DeferredDisplayList::discardDrawingBatches(const unsigned int maxIndex) {
+    for (unsigned int i = mEarliestUnclearedIndex; i <= maxIndex; i++) {
+        // leave deferred state ops alone for simplicity (empty save restore pairs may now exist)
+        if (mBatches[i] && mBatches[i]->purelyDrawBatch()) {
+            DrawBatch* b = (DrawBatch*) mBatches[i];
+            delete mBatches[i];
+            mBatches.replaceAt(NULL, i);
+        }
+    }
+    mEarliestUnclearedIndex = maxIndex + 1;
+}
+
 }; // namespace uirenderer
 }; // namespace android
diff --git a/libs/hwui/DeferredDisplayList.h b/libs/hwui/DeferredDisplayList.h
index 9782c1c..3dcbd0b 100644
--- a/libs/hwui/DeferredDisplayList.h
+++ b/libs/hwui/DeferredDisplayList.h
@@ -18,11 +18,13 @@
 #define ANDROID_HWUI_DEFERRED_DISPLAY_LIST_H
 
 #include <utils/Errors.h>
+#include <utils/LinearAllocator.h>
 #include <utils/Vector.h>
+#include <utils/TinyHashMap.h>
 
 #include "Matrix.h"
+#include "OpenGLRenderer.h"
 #include "Rect.h"
-#include "utils/TinyHashMap.h"
 
 class SkBitmap;
 
@@ -34,18 +36,56 @@
 class SaveOp;
 class SaveLayerOp;
 class StateOp;
+
+class DeferredDisplayState;
 class OpenGLRenderer;
 
 class Batch;
 class DrawBatch;
 class MergingDrawBatch;
 
-typedef void* mergeid_t;
+typedef const void* mergeid_t;
+
+class DeferredDisplayState {
+public:
+    /** static void* operator new(size_t size); PURPOSELY OMITTED **/
+    static void* operator new(size_t size, LinearAllocator& allocator) {
+        return allocator.alloc(size);
+    }
+
+    // global op bounds, mapped by mMatrix to be in screen space coordinates, clipped
+    Rect mBounds;
+
+    // the below are set and used by the OpenGLRenderer at record and deferred playback
+    bool mClipValid;
+    Rect mClip;
+    int mClipSideFlags; // specifies which sides of the bounds are clipped, unclipped if cleared
+    bool mClipped;
+    mat4 mMatrix;
+    DrawModifiers mDrawModifiers;
+    float mAlpha;
+};
+
+class OpStatePair {
+public:
+    OpStatePair()
+            : op(NULL), state(NULL) {}
+    OpStatePair(DrawOp* newOp, const DeferredDisplayState* newState)
+            : op(newOp), state(newState) {}
+    OpStatePair(const OpStatePair& other)
+            : op(other.op), state(other.state) {}
+    DrawOp* op;
+    const DeferredDisplayState* state;
+};
 
 class DeferredDisplayList {
 public:
-    DeferredDisplayList() { clear(); }
+    DeferredDisplayList(const Rect& bounds, bool avoidOverdraw = true) :
+            mBounds(bounds), mAvoidOverdraw(avoidOverdraw) {
+        clear();
+    }
     ~DeferredDisplayList() { clear(); }
+    void reset(const Rect& bounds) { mBounds.set(bounds); }
 
     enum OpBatchId {
         kOpBatch_None = 0, // Don't batch
@@ -75,11 +115,19 @@
 
     /**
      * Add a draw op into the DeferredDisplayList, reordering as needed (for performance) if
-     * disallowReorder is false, respecting draw order when overlaps occur
+     * disallowReorder is false, respecting draw order when overlaps occur.
      */
     void addDrawOp(OpenGLRenderer& renderer, DrawOp* op);
 
 private:
+    DeferredDisplayState* createState() {
+        return new (mAllocator) DeferredDisplayState();
+    }
+
+    void tryRecycleState(DeferredDisplayState* state) {
+        mAllocator.rewindIfLastAlloc(state, sizeof(DeferredDisplayState));
+    }
+
     /**
      * Resets the batching back-pointers, creating a barrier in the operation stream so that no ops
      * added in the future will be inserted into a batch that already exist.
@@ -96,6 +144,12 @@
     int getStateOpDeferFlags() const;
     int getDrawOpDeferFlags() const;
 
+    void discardDrawingBatches(const unsigned int maxIndex);
+
+    // layer space bounds of rendering
+    Rect mBounds;
+    const bool mAvoidOverdraw;
+
     /**
      * At defer time, stores the *defer time* savecount of save/saveLayer ops that were deferred, so
      * that when an associated restoreToCount is deferred, it can be recorded as a
@@ -112,12 +166,35 @@
     // Points to the index after the most recent barrier
     int mEarliestBatchIndex;
 
+    // Points to the first index that may contain a pure drawing batch
+    int mEarliestUnclearedIndex;
+
     /**
      * Maps the mergeid_t returned by an op's getMergeId() to the most recently seen
      * MergingDrawBatch of that id. These ids are unique per draw type and guaranteed to not
      * collide, which avoids the need to resolve mergeid collisions.
      */
     TinyHashMap<mergeid_t, DrawBatch*> mMergingBatches[kOpBatch_Count];
+
+    LinearAllocator mAllocator;
+};
+
+/**
+ * Struct containing information that instructs the defer
+ */
+struct DeferInfo {
+public:
+    DeferInfo() :
+            batchId(DeferredDisplayList::kOpBatch_None),
+            mergeId((mergeid_t) -1),
+            mergeable(false),
+            opaqueOverBounds(false) {
+    };
+
+    int batchId;
+    mergeid_t mergeId;
+    bool mergeable;
+    bool opaqueOverBounds; // opaque over bounds in DeferredDisplayState - can skip ops below
 };
 
 }; // namespace uirenderer
diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp
index 1cbd531..bb6526e 100644
--- a/libs/hwui/DisplayList.cpp
+++ b/libs/hwui/DisplayList.cpp
@@ -44,13 +44,14 @@
 }
 
 DisplayList::DisplayList(const DisplayListRenderer& recorder) :
-    mTransformMatrix(NULL), mTransformCamera(NULL), mTransformMatrix3D(NULL),
+    mDestroyed(false), mTransformMatrix(NULL), mTransformCamera(NULL), mTransformMatrix3D(NULL),
     mStaticMatrix(NULL), mAnimationMatrix(NULL) {
 
     initFromDisplayListRenderer(recorder);
 }
 
 DisplayList::~DisplayList() {
+    mDestroyed = true;
     clearResources();
 }
 
@@ -63,7 +64,6 @@
 
 void DisplayList::clearResources() {
     mDisplayListData = NULL;
-    mSize = 0; // TODO: shouldn't be needed, WAR possible use after delete
 
     mClipRectOp = NULL;
     mSaveLayerOp = NULL;
@@ -100,6 +100,10 @@
         caches.resourceCache.decrementRefcountLocked(mFilterResources.itemAt(i));
     }
 
+    for (size_t i = 0; i < mPatchResources.size(); i++) {
+        caches.resourceCache.decrementRefcountLocked(mPatchResources.itemAt(i));
+    }
+
     for (size_t i = 0; i < mShaders.size(); i++) {
         caches.resourceCache.decrementRefcountLocked(mShaders.itemAt(i));
         caches.resourceCache.destructorLocked(mShaders.itemAt(i));
@@ -134,6 +138,7 @@
     mBitmapResources.clear();
     mOwnedBitmapResources.clear();
     mFilterResources.clear();
+    mPatchResources.clear();
     mShaders.clear();
     mSourcePaths.clear();
     mPaints.clear();
@@ -169,6 +174,10 @@
     mSaveLayerOp = new (alloc) SaveLayerOp();
     mSaveOp = new (alloc) SaveOp();
     mRestoreToCountOp = new (alloc) RestoreToCountOp();
+    if (CC_UNLIKELY(!mSaveOp)) { // temporary debug logging
+        ALOGW("Error: %s's SaveOp not allocated, size %d", getName(), mSize);
+        CRASH();
+    }
 
     mFunctorCount = recorder.getFunctorCount();
 
@@ -197,6 +206,13 @@
         caches.resourceCache.incrementRefcountLocked(resource);
     }
 
+    const Vector<Res_png_9patch*>& patchResources = recorder.getPatchResources();
+    for (size_t i = 0; i < patchResources.size(); i++) {
+        Res_png_9patch* resource = patchResources.itemAt(i);
+        mPatchResources.add(resource);
+        caches.resourceCache.incrementRefcountLocked(resource);
+    }
+
     const Vector<SkiaShader*>& shaders = recorder.getShaders();
     for (size_t i = 0; i < shaders.size(); i++) {
         SkiaShader* resource = shaders.itemAt(i);
@@ -342,7 +358,7 @@
     }
     if (mAnimationMatrix) {
         ALOGD("%*sConcatMatrix (animation) %p: " MATRIX_STRING,
-                level * 2, "", mAnimationMatrix, MATRIX_ARGS(mStaticMatrix));
+                level * 2, "", mAnimationMatrix, MATRIX_ARGS(mAnimationMatrix));
     }
     if (mMatrixFlags != 0) {
         if (mMatrixFlags == TRANSLATION) {
@@ -352,6 +368,8 @@
                     level * 2, "", mTransformMatrix, MATRIX_ARGS(mTransformMatrix));
         }
     }
+
+    bool clipToBoundsNeeded = mCaching ? false : mClipToBounds;
     if (mAlpha < 1) {
         if (mCaching) {
             ALOGD("%*sSetOverrideLayerAlpha %.2f", level * 2, "", mAlpha);
@@ -359,15 +377,16 @@
             ALOGD("%*sScaleAlpha %.2f", level * 2, "", mAlpha);
         } else {
             int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
-            if (mClipToBounds) {
+            if (clipToBoundsNeeded) {
                 flags |= SkCanvas::kClipToLayer_SaveFlag;
+                clipToBoundsNeeded = false; // clipping done by save layer
             }
             ALOGD("%*sSaveLayerAlpha %.2f, %.2f, %.2f, %.2f, %d, 0x%x", level * 2, "",
                     (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop,
                     (int)(mAlpha * 255), flags);
         }
     }
-    if (mClipToBounds && !mCaching) {
+    if (clipToBoundsNeeded) {
         ALOGD("%*sClipRect %.2f, %.2f, %.2f, %.2f", level * 2, "", 0.0f, 0.0f,
                 (float) mRight - mLeft, (float) mBottom - mTop);
     }
@@ -402,6 +421,7 @@
             renderer.concatMatrix(mTransformMatrix);
         }
     }
+    bool clipToBoundsNeeded = mCaching ? false : mClipToBounds;
     if (mAlpha < 1) {
         if (mCaching) {
             renderer.setOverrideLayerAlpha(mAlpha);
@@ -412,15 +432,16 @@
             // have to pass it into this call. In fact, this information might be in the
             // location/size info that we store with the new native transform data.
             int saveFlags = SkCanvas::kHasAlphaLayer_SaveFlag;
-            if (mClipToBounds) {
+            if (clipToBoundsNeeded) {
                 saveFlags |= SkCanvas::kClipToLayer_SaveFlag;
+                clipToBoundsNeeded = false; // clipping done by saveLayer
             }
             handler(mSaveLayerOp->reinit(0, 0, mRight - mLeft, mBottom - mTop,
                     mAlpha * 255, SkXfermode::kSrcOver_Mode, saveFlags), PROPERTY_SAVECOUNT,
                     mClipToBounds);
         }
     }
-    if (mClipToBounds && !mCaching) {
+    if (clipToBoundsNeeded) {
         handler(mClipRectOp->reinit(0, 0, mRight - mLeft, mBottom - mTop, SkRegion::kIntersect_Op),
                 PROPERTY_SAVECOUNT, mClipToBounds);
     }
@@ -480,7 +501,11 @@
  */
 template <class T>
 void DisplayList::iterate(OpenGLRenderer& renderer, T& handler, const int level) {
-    if (mSize == 0 || mAlpha <= 0 || CC_UNLIKELY(!mSaveOp)) { // TODO: shouldn't need mSaveOp check
+    if (CC_UNLIKELY(mDestroyed)) { // temporary debug logging
+        ALOGW("Error: %s is drawing after destruction, size %d", getName(), mSize);
+        CRASH();
+    }
+    if (mSize == 0 || mAlpha <= 0) {
         DISPLAY_LIST_LOGD("%*sEmpty display list (%p, %s)", level * 2, "", this, mName.string());
         return;
     }
@@ -514,6 +539,10 @@
     for (unsigned int i = 0; i < mDisplayListData->displayListOps.size(); i++) {
         DisplayListOp *op = mDisplayListData->displayListOps[i];
 
+#if DEBUG_DISPLAY_LIST
+        op->output(level + 1);
+#endif
+
         logBuffer.writeCommand(level, op->name());
         handler(op, saveCount, mClipToBounds);
     }
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h
index 5f84329..1cd5f1c 100644
--- a/libs/hwui/DisplayList.h
+++ b/libs/hwui/DisplayList.h
@@ -26,13 +26,15 @@
 
 #include <private/hwui/DrawGlInfo.h>
 
+#include <utils/LinearAllocator.h>
 #include <utils/RefBase.h>
 #include <utils/SortedVector.h>
 #include <utils/String8.h>
 #include <utils/Vector.h>
+
 #include <cutils/compiler.h>
 
-#include "utils/LinearAllocator.h"
+#include <androidfw/ResourceTypes.h>
 
 #include "Debug.h"
 
@@ -111,7 +113,6 @@
 
     void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false);
 
-
     void defer(DeferStateStruct& deferStruct, const int level);
     void replay(ReplayStateStruct& replayStruct, const int level);
 
@@ -129,7 +130,12 @@
 
     void setName(const char* name) {
         if (name) {
-            mName.setTo(name);
+            char* lastPeriod = strrchr(name, '.');
+            if (lastPeriod) {
+                mName.setTo(lastPeriod + 1);
+            } else {
+                mName.setTo(name);
+            }
         }
     }
 
@@ -479,6 +485,7 @@
     Vector<SkBitmap*> mBitmapResources;
     Vector<SkBitmap*> mOwnedBitmapResources;
     Vector<SkiaColorFilter*> mFilterResources;
+    Vector<Res_png_9patch*> mPatchResources;
 
     Vector<SkPaint*> mPaints;
     Vector<SkPath*> mPaths;
@@ -496,6 +503,7 @@
     uint32_t mFunctorCount;
 
     String8 mName;
+    bool mDestroyed; // used for debugging crash, TODO: remove once invalid state crash fixed
 
     // View properties
     bool mClipToBounds;
@@ -525,11 +533,11 @@
      * an alpha causes a SaveLayerAlpha to occur). These operations point into mDisplayListData's
      * allocation, or null if uninitialized.
      *
-     * These are initialized (via friend constructors) when a displayList is issued in either replay
-     * or deferred mode. If replaying, the ops are not used until the next frame. If deferring, the
-     * ops may be stored in the DeferredDisplayList to be played back a second time.
+     * These are initialized (via friend re-constructors) when a displayList is issued in either
+     * replay or deferred mode. If replaying, the ops are not used until the next frame. If
+     * deferring, the ops may be stored in the DeferredDisplayList to be played back a second time.
      *
-     * They should be used at most once per frame (one call to iterate)
+     * They should be used at most once per frame (one call to 'iterate') to avoid overwriting data
      */
     ClipRectOp* mClipRectOp;
     SaveLayerOp* mSaveLayerOp;
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index a0290e3..a17942e 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -26,26 +26,19 @@
 #include <private/hwui/DrawGlInfo.h>
 
 #include "OpenGLRenderer.h"
+#include "AssetAtlas.h"
 #include "DeferredDisplayList.h"
 #include "DisplayListRenderer.h"
+#include "UvMapper.h"
 #include "utils/LinearAllocator.h"
 
 #define CRASH() do { \
-    *(int *)(uintptr_t)0xbbadbeef = 0; \
+    *(int *)(uintptr_t) 0xbbadbeef = 0; \
     ((void(*)())0)(); /* More reliable, but doesn't say BBADBEEF */ \
 } while(false)
 
-#define MATRIX_STRING "[%.2f %.2f %.2f] [%.2f %.2f %.2f] [%.2f %.2f %.2f]"
-#define MATRIX_ARGS(m) \
-    m->get(0), m->get(1), m->get(2), \
-    m->get(3), m->get(4), m->get(5), \
-    m->get(6), m->get(7), m->get(8)
-#define RECT_STRING "%.2f %.2f %.2f %.2f"
-#define RECT_ARGS(r) \
-    r.left, r.top, r.right, r.bottom
-
 // Use OP_LOG for logging with arglist, OP_LOGS if just printing char*
-#define OP_LOGS(s) OP_LOG("%s", s)
+#define OP_LOGS(s) OP_LOG("%s", (s))
 #define OP_LOG(s, ...) ALOGD( "%*s" s, level * 2, "", __VA_ARGS__ )
 
 namespace android {
@@ -84,20 +77,11 @@
     virtual void replay(ReplayStateStruct& replayStruct, int saveCount, int level,
             bool useQuickReject) = 0;
 
-    virtual void output(int level, uint32_t logFlags = 0) = 0;
+    virtual void output(int level, uint32_t logFlags = 0) const = 0;
 
     // NOTE: it would be nice to declare constants and overriding the implementation in each op to
     // point at the constants, but that seems to require a .cpp file
     virtual const char* name() = 0;
-
-    /**
-     * Stores the relevant canvas state of the object between deferral and replay (if the canvas
-     * state supports being stored) See OpenGLRenderer::simpleClipAndState()
-     *
-     * TODO: don't reserve space for StateOps that won't be deferred
-     */
-    DeferredDisplayState state;
-
 };
 
 class StateOp : public DisplayListOp {
@@ -136,11 +120,6 @@
             return;
         }
 
-        if (!getLocalBounds(state.mBounds)) {
-            // empty bounds signify bounds can't be calculated
-            state.mBounds.setEmpty();
-        }
-
         deferStruct.mDeferredList.addDrawOp(deferStruct.mRenderer, this);
     }
 
@@ -163,16 +142,16 @@
      * reducing which operations are tagged as mergeable.
      */
     virtual status_t multiDraw(OpenGLRenderer& renderer, Rect& dirty,
-            const Vector<DrawOp*>& ops, const Rect& bounds) {
+            const Vector<OpStatePair>& ops, const Rect& bounds) {
         status_t status = DrawGlInfo::kStatusDone;
         for (unsigned int i = 0; i < ops.size(); i++) {
-            renderer.restoreDisplayState(ops[i]->state);
-            status |= ops[i]->applyDraw(renderer, dirty);
+            renderer.restoreDisplayState(*(ops[i].state), true);
+            status |= ops[i].op->applyDraw(renderer, dirty);
         }
         return status;
     }
 
-    /*
+    /**
      * When this method is invoked the state field is initialized to have the
      * final rendering state. We can thus use it to process data as it will be
      * used at draw time.
@@ -180,21 +159,25 @@
      * Additionally, this method allows subclasses to provide defer-time preferences for batching
      * and merging.
      *
-     * Return true if the op can merge with others of its kind (such subclasses should implement
-     * multiDraw)
+     * if a subclass can set deferInfo.mergeable to true, it should implement multiDraw()
      */
-    virtual bool onDefer(OpenGLRenderer& renderer, int* batchId, mergeid_t* mergeId) {
+    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
+            const DeferredDisplayState& state) {}
+
+    /**
+     * Query the conservative, local bounds (unmapped) bounds of the op.
+     *
+     * returns true if bounds exist
+     */
+    virtual bool getLocalBounds(const DrawModifiers& drawModifiers, Rect& localBounds) {
         return false;
     }
 
-    // returns true if bounds exist
-    virtual bool getLocalBounds(Rect& localBounds) { return false; }
-
     // TODO: better refine localbounds usage
     void setQuickRejected(bool quickRejected) { mQuickRejected = quickRejected; }
     bool getQuickRejected() { return mQuickRejected; }
 
-    inline int getPaintAlpha() {
+    inline int getPaintAlpha() const {
         return OpenGLRenderer::getAlphaDirect(mPaint);
     }
 
@@ -209,6 +192,23 @@
         return renderer.filterPaint(mPaint);
     }
 
+    // Helper method for determining op opaqueness. Assumes op fills its bounds in local
+    // coordinates, and that paint's alpha is used
+    inline bool isOpaqueOverBounds(const DeferredDisplayState& state) {
+        // ensure that local bounds cover mapped bounds
+        if (!state.mMatrix.isSimple()) return false;
+
+        // check state/paint for transparency
+        if (state.mDrawModifiers.mShader ||
+                state.mAlpha != 1.0f ||
+                (mPaint && mPaint->getAlpha() != 0xFF)) return false;
+
+        SkXfermode::Mode mode = OpenGLRenderer::getXfermodeDirect(mPaint);
+        return (mode == SkXfermode::kSrcOver_Mode ||
+                mode == SkXfermode::kSrc_Mode);
+
+    }
+
     SkPaint* mPaint; // should be accessed via getPaint() when applying
     bool mQuickRejected;
 };
@@ -218,6 +218,9 @@
     DrawBoundedOp(float left, float top, float right, float bottom, SkPaint* paint)
             : DrawOp(paint), mLocalBounds(left, top, right, bottom) {}
 
+    DrawBoundedOp(const Rect& localBounds, SkPaint* paint)
+            : DrawOp(paint), mLocalBounds(localBounds) {}
+
     // Calculates bounds as smallest rect encompassing all points
     // NOTE: requires at least 1 vertex, and doesn't account for stroke size (should be handled in
     // subclass' constructor)
@@ -232,24 +235,20 @@
     }
 
     // default empty constructor for bounds, to be overridden in child constructor body
-    DrawBoundedOp(SkPaint* paint)
-            : DrawOp(paint) {}
+    DrawBoundedOp(SkPaint* paint): DrawOp(paint) { }
 
-    bool getLocalBounds(Rect& localBounds) {
+    bool getLocalBounds(const DrawModifiers& drawModifiers, Rect& localBounds) {
         localBounds.set(mLocalBounds);
+        if (drawModifiers.mHasShadow) {
+            // TODO: inspect paint's looper directly
+            Rect shadow(mLocalBounds);
+            shadow.translate(drawModifiers.mShadowDx, drawModifiers.mShadowDy);
+            shadow.outset(drawModifiers.mShadowRadius);
+            localBounds.unionWith(shadow);
+        }
         return true;
     }
 
-    bool mergeAllowed() {
-        if (!state.mMatrix.isPureTranslate()) return false;
-
-        // checks that we're unclipped, and srcover
-        const Rect& opBounds = state.mBounds;
-        return fabs(opBounds.getWidth() - mLocalBounds.getWidth()) < 0.1 &&
-                fabs(opBounds.getHeight() - mLocalBounds.getHeight()) < 0.1 &&
-                (OpenGLRenderer::getXfermodeDirect(mPaint) == SkXfermode::kSrcOver_Mode);
-    }
-
 protected:
     Rect mLocalBounds; // displayed area in LOCAL coord. doesn't incorporate stroke, so check paint
 };
@@ -275,7 +274,7 @@
         renderer.save(mFlags);
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("Save flags %x", mFlags);
     }
 
@@ -309,7 +308,7 @@
         renderer.restoreToCount(saveCount + mCount);
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("Restore to count %d", mCount);
     }
 
@@ -348,7 +347,7 @@
         renderer.saveLayer(mArea.left, mArea.top, mArea.right, mArea.bottom, mAlpha, mMode, mFlags);
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("SaveLayer%s of area " RECT_STRING,
                 (isSaveLayerAlpha() ? "Alpha" : ""),RECT_ARGS(mArea));
     }
@@ -369,7 +368,7 @@
         return this;
     }
 
-    bool isSaveLayerAlpha() { return mAlpha < 255 && mMode == SkXfermode::kSrcOver_Mode; }
+    bool isSaveLayerAlpha() const { return mAlpha < 255 && mMode == SkXfermode::kSrcOver_Mode; }
     Rect mArea;
     int mAlpha;
     SkXfermode::Mode mMode;
@@ -385,7 +384,7 @@
         renderer.translate(mDx, mDy);
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("Translate by %f %f", mDx, mDy);
     }
 
@@ -405,7 +404,7 @@
         renderer.rotate(mDegrees);
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("Rotate by %f degrees", mDegrees);
     }
 
@@ -424,7 +423,7 @@
         renderer.scale(mSx, mSy);
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("Scale by %f %f", mSx, mSy);
     }
 
@@ -444,7 +443,7 @@
         renderer.skew(mSx, mSy);
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("Skew by %f %f", mSx, mSy);
     }
 
@@ -464,8 +463,12 @@
         renderer.setMatrix(mMatrix);
     }
 
-    virtual void output(int level, uint32_t logFlags) {
-        OP_LOG("SetMatrix " MATRIX_STRING, MATRIX_ARGS(mMatrix));
+    virtual void output(int level, uint32_t logFlags) const {
+        if (mMatrix) {
+            OP_LOG("SetMatrix " MATRIX_STRING, MATRIX_ARGS(mMatrix));
+        } else {
+            OP_LOGS("SetMatrix (reset)");
+        }
     }
 
     virtual const char* name() { return "SetMatrix"; }
@@ -483,7 +486,7 @@
         renderer.concatMatrix(mMatrix);
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("ConcatMatrix " MATRIX_STRING, MATRIX_ARGS(mMatrix));
     }
 
@@ -527,7 +530,7 @@
         renderer.clipRect(mArea.left, mArea.top, mArea.right, mArea.bottom, mOp);
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("ClipRect " RECT_STRING, RECT_ARGS(mArea));
     }
 
@@ -556,7 +559,7 @@
         renderer.clipPath(mPath, mOp);
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         SkRect bounds = mPath->getBounds();
         OP_LOG("ClipPath bounds " RECT_STRING,
                 bounds.left(), bounds.top(), bounds.right(), bounds.bottom());
@@ -577,7 +580,7 @@
         renderer.clipRegion(mRegion, mOp);
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         SkIRect bounds = mRegion->getBounds();
         OP_LOG("ClipRegion bounds %d %d %d %d",
                 bounds.left(), bounds.top(), bounds.right(), bounds.bottom());
@@ -587,7 +590,6 @@
 
 private:
     SkRegion* mRegion;
-    SkRegion::Op mOp;
 };
 
 class ResetShaderOp : public StateOp {
@@ -596,7 +598,7 @@
         renderer.resetShader();
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOGS("ResetShader");
     }
 
@@ -611,7 +613,7 @@
         renderer.setupShader(mShader);
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("SetupShader, shader %p", mShader);
     }
 
@@ -627,7 +629,7 @@
         renderer.resetColorFilter();
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOGS("ResetColorFilter");
     }
 
@@ -643,7 +645,7 @@
         renderer.setupColorFilter(mColorFilter);
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("SetupColorFilter, filter %p", mColorFilter);
     }
 
@@ -659,7 +661,7 @@
         renderer.resetShadow();
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOGS("ResetShadow");
     }
 
@@ -675,7 +677,7 @@
         renderer.setupShadow(mRadius, mDx, mDy, mColor);
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("SetupShadow, radius %f, %f, %f, color %#x", mRadius, mDx, mDy, mColor);
     }
 
@@ -694,7 +696,7 @@
         renderer.resetPaintFilter();
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOGS("ResetPaintFilter");
     }
 
@@ -710,7 +712,7 @@
         renderer.setupPaintFilter(mClearBits, mSetBits);
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("SetupPaintFilter, clear %#x, set %#x", mClearBits, mSetBits);
     }
 
@@ -721,7 +723,6 @@
     int mSetBits;
 };
 
-
 ///////////////////////////////////////////////////////////////////////////////
 // DRAW OPERATIONS - these are operations that can draw to the canvas's device
 ///////////////////////////////////////////////////////////////////////////////
@@ -729,34 +730,63 @@
 class DrawBitmapOp : public DrawBoundedOp {
 public:
     DrawBitmapOp(SkBitmap* bitmap, float left, float top, SkPaint* paint)
-            : DrawBoundedOp(left, top, left + bitmap->width(), top + bitmap->height(),
-                    paint),
-            mBitmap(bitmap) {}
+            : DrawBoundedOp(left, top, left + bitmap->width(), top + bitmap->height(), paint),
+            mBitmap(bitmap), mAtlas(Caches::getInstance().assetAtlas) {
+        mEntry = mAtlas.getEntry(bitmap);
+        if (mEntry) {
+            mEntryGenerationId = mAtlas.getGenerationId();
+            mUvMapper = mEntry->uvMapper;
+        }
+    }
 
     virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
         return renderer.drawBitmap(mBitmap, mLocalBounds.left, mLocalBounds.top,
                 getPaint(renderer));
     }
 
+    AssetAtlas::Entry* getAtlasEntry() {
+        // The atlas entry is stale, let's get a new one
+        if (mEntry && mEntryGenerationId != mAtlas.getGenerationId()) {
+            mEntryGenerationId = mAtlas.getGenerationId();
+            mEntry = mAtlas.getEntry(mBitmap);
+            mUvMapper = mEntry->uvMapper;
+        }
+        return mEntry;
+    }
+
 #define SET_TEXTURE(ptr, posRect, offsetRect, texCoordsRect, xDim, yDim) \
     TextureVertex::set(ptr++, posRect.xDim - offsetRect.left, posRect.yDim - offsetRect.top, \
             texCoordsRect.xDim, texCoordsRect.yDim)
 
+    /**
+     * This multi-draw operation builds a mesh on the stack by generating a quad
+     * for each bitmap in the batch. This method is also responsible for dirtying
+     * the current layer, if any.
+     */
     virtual status_t multiDraw(OpenGLRenderer& renderer, Rect& dirty,
-            const Vector<DrawOp*>& ops, const Rect& bounds) {
-        renderer.restoreDisplayState(state, true); // restore all but the clip
-        renderer.setFullScreenClip(); // ensure merged ops aren't clipped
+            const Vector<OpStatePair>& ops, const Rect& bounds) {
+        const DeferredDisplayState& firstState = *(ops[0].state);
+        renderer.restoreDisplayState(firstState, true); // restore all but the clip
+
         TextureVertex vertices[6 * ops.size()];
         TextureVertex* vertex = &vertices[0];
 
-        // TODO: manually handle rect clip for bitmaps by adjusting texCoords per op, and allowing
-        // them to be merged in getBatchId()
-        const Rect texCoords(0, 0, 1, 1);
+        const bool hasLayer = renderer.hasLayer();
+        bool transformed = false;
 
-        const float width = mBitmap->width();
-        const float height = mBitmap->height();
+        // TODO: manually handle rect clip for bitmaps by adjusting texCoords per op,
+        // and allowing them to be merged in getBatchId()
         for (unsigned int i = 0; i < ops.size(); i++) {
-            const Rect& opBounds = ops[i]->state.mBounds;
+            const DeferredDisplayState& state = *(ops[i].state);
+            const Rect& opBounds = state.mBounds;
+            // When we reach multiDraw(), the matrix can be either
+            // pureTranslate or simple (translate and/or scale).
+            // If the matrix is not pureTranslate, then we have a scale
+            if (state.mMatrix.isPureTranslate()) transformed = true;
+
+            Rect texCoords(0, 0, 1, 1);
+            ((DrawBitmapOp*) ops[i].op)->mUvMapper.map(texCoords);
+
             SET_TEXTURE(vertex, opBounds, bounds, texCoords, left, top);
             SET_TEXTURE(vertex, opBounds, bounds, texCoords, right, top);
             SET_TEXTURE(vertex, opBounds, bounds, texCoords, left, bottom);
@@ -764,29 +794,42 @@
             SET_TEXTURE(vertex, opBounds, bounds, texCoords, left, bottom);
             SET_TEXTURE(vertex, opBounds, bounds, texCoords, right, top);
             SET_TEXTURE(vertex, opBounds, bounds, texCoords, right, bottom);
+
+            if (hasLayer) {
+                renderer.dirtyLayer(opBounds.left, opBounds.top, opBounds.right, opBounds.bottom);
+            }
         }
 
-        return renderer.drawBitmaps(mBitmap, ops.size(), &vertices[0], bounds, mPaint);
+        return renderer.drawBitmaps(mBitmap, mEntry, ops.size(), &vertices[0],
+                transformed, bounds, mPaint);
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("Draw bitmap %p at %f %f", mBitmap, mLocalBounds.left, mLocalBounds.top);
     }
 
     virtual const char* name() { return "DrawBitmap"; }
 
-    virtual bool onDefer(OpenGLRenderer& renderer, int* batchId, mergeid_t* mergeId) {
-        *batchId = DeferredDisplayList::kOpBatch_Bitmap;
-        *mergeId = (mergeid_t)mBitmap;
+    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
+            const DeferredDisplayState& state) {
+        deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap;
+        deferInfo.mergeId = getAtlasEntry() ? (mergeid_t) mEntry->getMergeId() : (mergeid_t) mBitmap;
 
-        // don't merge A8 bitmaps - the paint's color isn't compared by mergeId, or in
-        // MergingDrawBatch::canMergeWith
-        return mergeAllowed() && (mBitmap->getConfig() != SkBitmap::kA8_Config);
+        // Don't merge A8 bitmaps - the paint's color isn't compared by mergeId, or in
+        // MergingDrawBatch::canMergeWith()
+        // TODO: support clipped bitmaps by handling them in SET_TEXTURE
+        deferInfo.mergeable = state.mMatrix.isSimple() && !state.mClipSideFlags &&
+                OpenGLRenderer::getXfermodeDirect(mPaint) == SkXfermode::kSrcOver_Mode &&
+                (mBitmap->getConfig() != SkBitmap::kA8_Config);
     }
 
     const SkBitmap* bitmap() { return mBitmap; }
 protected:
     SkBitmap* mBitmap;
+    const AssetAtlas& mAtlas;
+    uint32_t mEntryGenerationId;
+    AssetAtlas::Entry* mEntry;
+    UvMapper mUvMapper;
 };
 
 class DrawBitmapMatrixOp : public DrawBoundedOp {
@@ -802,15 +845,15 @@
         return renderer.drawBitmap(mBitmap, mMatrix, getPaint(renderer));
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("Draw bitmap %p matrix " MATRIX_STRING, mBitmap, MATRIX_ARGS(mMatrix));
     }
 
     virtual const char* name() { return "DrawBitmapMatrix"; }
 
-    virtual bool onDefer(OpenGLRenderer& renderer, int* batchId, mergeid_t* mergeId) {
-        *batchId = DeferredDisplayList::kOpBatch_Bitmap;
-        return false;
+    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
+            const DeferredDisplayState& state) {
+        deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap;
     }
 
 private:
@@ -831,16 +874,16 @@
                 getPaint(renderer));
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("Draw bitmap %p src="RECT_STRING", dst="RECT_STRING,
                 mBitmap, RECT_ARGS(mSrc), RECT_ARGS(mLocalBounds));
     }
 
     virtual const char* name() { return "DrawBitmapRect"; }
 
-    virtual bool onDefer(OpenGLRenderer& renderer, int* batchId, mergeid_t* mergeId) {
-        *batchId = DeferredDisplayList::kOpBatch_Bitmap;
-        return false;
+    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
+            const DeferredDisplayState& state) {
+        deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap;
     }
 
 private:
@@ -858,15 +901,15 @@
                 mLocalBounds.top, getPaint(renderer));
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("Draw bitmap %p", mBitmap);
     }
 
     virtual const char* name() { return "DrawBitmapData"; }
 
-    virtual bool onDefer(OpenGLRenderer& renderer, int* batchId, mergeid_t* mergeId) {
-        *batchId = DeferredDisplayList::kOpBatch_Bitmap;
-        return false;
+    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
+            const DeferredDisplayState& state) {
+        deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap;
     }
 };
 
@@ -883,15 +926,15 @@
                 mVertices, mColors, getPaint(renderer));
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("Draw bitmap %p mesh %d x %d", mBitmap, mMeshWidth, mMeshHeight);
     }
 
     virtual const char* name() { return "DrawBitmapMesh"; }
 
-    virtual bool onDefer(OpenGLRenderer& renderer, int* batchId, mergeid_t* mergeId) {
-        *batchId = DeferredDisplayList::kOpBatch_Bitmap;
-        return false;
+    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
+            const DeferredDisplayState& state) {
+        deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap;
     }
 
 private:
@@ -904,45 +947,148 @@
 
 class DrawPatchOp : public DrawBoundedOp {
 public:
-    DrawPatchOp(SkBitmap* bitmap, const int32_t* xDivs,
-            const int32_t* yDivs, const uint32_t* colors, uint32_t width, uint32_t height,
-            int8_t numColors, float left, float top, float right, float bottom,
-            int alpha, SkXfermode::Mode mode)
-            : DrawBoundedOp(left, top, right, bottom, 0),
-            mBitmap(bitmap), mxDivs(xDivs), myDivs(yDivs),
-            mColors(colors), mxDivsCount(width), myDivsCount(height),
-            mNumColors(numColors), mAlpha(alpha), mMode(mode) {};
+    DrawPatchOp(SkBitmap* bitmap, Res_png_9patch* patch,
+            float left, float top, float right, float bottom, SkPaint* paint)
+            : DrawBoundedOp(left, top, right, bottom, paint),
+            mBitmap(bitmap), mPatch(patch), mGenerationId(0), mMesh(NULL),
+            mAtlas(Caches::getInstance().assetAtlas) {
+        mEntry = mAtlas.getEntry(bitmap);
+        if (mEntry) {
+            mEntryGenerationId = mAtlas.getGenerationId();
+        }
+    };
 
-    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
-        // NOTE: not calling the virtual method, which takes a paint
-        return renderer.drawPatch(mBitmap, mxDivs, myDivs, mColors,
-                mxDivsCount, myDivsCount, mNumColors,
-                mLocalBounds.left, mLocalBounds.top,
-                mLocalBounds.right, mLocalBounds.bottom, mAlpha, mMode);
+    AssetAtlas::Entry* getAtlasEntry() {
+        // The atlas entry is stale, let's get a new one
+        if (mEntry && mEntryGenerationId != mAtlas.getGenerationId()) {
+            mEntryGenerationId = mAtlas.getGenerationId();
+            mEntry = mAtlas.getEntry(mBitmap);
+        }
+        return mEntry;
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    const Patch* getMesh(OpenGLRenderer& renderer) {
+        if (!mMesh || renderer.getCaches().patchCache.getGenerationId() != mGenerationId) {
+            PatchCache& cache = renderer.getCaches().patchCache;
+            mMesh = cache.get(getAtlasEntry(), mBitmap->width(), mBitmap->height(),
+                    mLocalBounds.getWidth(), mLocalBounds.getHeight(), mPatch);
+            mGenerationId = cache.getGenerationId();
+        }
+        return mMesh;
+    }
+
+    /**
+     * This multi-draw operation builds an indexed mesh on the stack by copying
+     * and transforming the vertices of each 9-patch in the batch. This method
+     * is also responsible for dirtying the current layer, if any.
+     */
+    virtual status_t multiDraw(OpenGLRenderer& renderer, Rect& dirty,
+            const Vector<OpStatePair>& ops, const Rect& bounds) {
+        const DeferredDisplayState& firstState = *(ops[0].state);
+        renderer.restoreDisplayState(firstState, true); // restore all but the clip
+
+        // Batches will usually contain a small number of items so it's
+        // worth performing a first iteration to count the exact number
+        // of vertices we need in the new mesh
+        uint32_t totalVertices = 0;
+        for (unsigned int i = 0; i < ops.size(); i++) {
+            totalVertices += ((DrawPatchOp*) ops[i].op)->getMesh(renderer)->verticesCount;
+        }
+
+        const bool hasLayer = renderer.hasLayer();
+
+        uint32_t indexCount = 0;
+
+        TextureVertex vertices[totalVertices];
+        TextureVertex* vertex = &vertices[0];
+
+        // Create a mesh that contains the transformed vertices for all the
+        // 9-patch objects that are part of the batch. Note that onDefer()
+        // enforces ops drawn by this function to have a pure translate or
+        // identity matrix
+        for (unsigned int i = 0; i < ops.size(); i++) {
+            DrawPatchOp* patchOp = (DrawPatchOp*) ops[i].op;
+            const DeferredDisplayState* state = ops[i].state;
+            const Patch* opMesh = patchOp->getMesh(renderer);
+            uint32_t vertexCount = opMesh->verticesCount;
+            if (vertexCount == 0) continue;
+
+            // We use the bounds to know where to translate our vertices
+            // Using patchOp->state.mBounds wouldn't work because these
+            // bounds are clipped
+            const float tx = (int) floorf(state->mMatrix.getTranslateX() +
+                    patchOp->mLocalBounds.left + 0.5f);
+            const float ty = (int) floorf(state->mMatrix.getTranslateY() +
+                    patchOp->mLocalBounds.top + 0.5f);
+
+            // Copy & transform all the vertices for the current operation
+            TextureVertex* opVertices = opMesh->vertices;
+            for (uint32_t j = 0; j < vertexCount; j++, opVertices++) {
+                TextureVertex::set(vertex++,
+                        opVertices->position[0] + tx, opVertices->position[1] + ty,
+                        opVertices->texture[0], opVertices->texture[1]);
+            }
+
+            // Dirty the current layer if possible. When the 9-patch does not
+            // contain empty quads we can take a shortcut and simply set the
+            // dirty rect to the object's bounds.
+            if (hasLayer) {
+                if (!opMesh->hasEmptyQuads) {
+                    renderer.dirtyLayer(tx, ty,
+                            tx + patchOp->mLocalBounds.getWidth(),
+                            ty + patchOp->mLocalBounds.getHeight());
+                } else {
+                    const size_t count = opMesh->quads.size();
+                    for (size_t i = 0; i < count; i++) {
+                        const Rect& quadBounds = opMesh->quads[i];
+                        const float x = tx + quadBounds.left;
+                        const float y = ty + quadBounds.top;
+                        renderer.dirtyLayer(x, y,
+                                x + quadBounds.getWidth(), y + quadBounds.getHeight());
+                    }
+                }
+            }
+
+            indexCount += opMesh->indexCount;
+        }
+
+        return renderer.drawPatches(mBitmap, getAtlasEntry(),
+                &vertices[0], indexCount, getPaint(renderer));
+    }
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
+        // We're not calling the public variant of drawPatch() here
+        // This method won't perform the quickReject() since we've already done it at this point
+        return renderer.drawPatch(mBitmap, getMesh(renderer), getAtlasEntry(),
+                mLocalBounds.left, mLocalBounds.top, mLocalBounds.right, mLocalBounds.bottom,
+                getPaint(renderer));
+    }
+
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("Draw patch "RECT_STRING, RECT_ARGS(mLocalBounds));
     }
 
     virtual const char* name() { return "DrawPatch"; }
 
-    virtual bool onDefer(OpenGLRenderer& renderer, int* batchId, mergeid_t* mergeId) {
-        *batchId = DeferredDisplayList::kOpBatch_Patch;
-        *mergeId = (mergeid_t)mBitmap;
-        return true;
+    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
+            const DeferredDisplayState& state) {
+        deferInfo.batchId = DeferredDisplayList::kOpBatch_Patch;
+        deferInfo.mergeId = getAtlasEntry() ? (mergeid_t) mEntry->getMergeId() : (mergeid_t) mBitmap;
+        deferInfo.mergeable = state.mMatrix.isPureTranslate() &&
+                OpenGLRenderer::getXfermodeDirect(mPaint) == SkXfermode::kSrcOver_Mode;
+        deferInfo.opaqueOverBounds = isOpaqueOverBounds(state) && mBitmap->isOpaque();
     }
 
 private:
     SkBitmap* mBitmap;
-    const int32_t* mxDivs;
-    const int32_t* myDivs;
-    const uint32_t* mColors;
-    uint32_t mxDivsCount;
-    uint32_t myDivsCount;
-    int8_t mNumColors;
-    int mAlpha;
-    SkXfermode::Mode mMode;
+    Res_png_9patch* mPatch;
+
+    uint32_t mGenerationId;
+    const Patch* mMesh;
+
+    const AssetAtlas& mAtlas;
+    uint32_t mEntryGenerationId;
+    AssetAtlas::Entry* mEntry;
 };
 
 class DrawColorOp : public DrawOp {
@@ -954,7 +1100,7 @@
         return renderer.drawColor(mColor, mMode);
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("Draw color %#x, mode %d", mColor, mMode);
     }
 
@@ -970,7 +1116,7 @@
     DrawStrokableOp(float left, float top, float right, float bottom, SkPaint* paint)
             : DrawBoundedOp(left, top, right, bottom, paint) {};
 
-    bool getLocalBounds(Rect& localBounds) {
+    bool getLocalBounds(const DrawModifiers& drawModifiers, Rect& localBounds) {
         localBounds.set(mLocalBounds);
         if (mPaint && mPaint->getStyle() != SkPaint::kFill_Style) {
             localBounds.outset(strokeWidthOutset());
@@ -978,15 +1124,15 @@
         return true;
     }
 
-    virtual bool onDefer(OpenGLRenderer& renderer, int* batchId, mergeid_t* mergeId) {
+    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
+            const DeferredDisplayState& state) {
         if (mPaint->getPathEffect()) {
-            *batchId = DeferredDisplayList::kOpBatch_AlphaMaskTexture;
+            deferInfo.batchId = DeferredDisplayList::kOpBatch_AlphaMaskTexture;
         } else {
-            *batchId = mPaint->isAntiAlias() ?
+            deferInfo.batchId = mPaint->isAntiAlias() ?
                     DeferredDisplayList::kOpBatch_AlphaVertices :
                     DeferredDisplayList::kOpBatch_Vertices;
         }
-        return false;
     }
 };
 
@@ -1000,10 +1146,17 @@
                 mLocalBounds.right, mLocalBounds.bottom, getPaint(renderer));
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("Draw Rect "RECT_STRING, RECT_ARGS(mLocalBounds));
     }
 
+    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
+            const DeferredDisplayState& state) {
+        DrawStrokableOp::onDefer(renderer, deferInfo, state);
+        deferInfo.opaqueOverBounds = isOpaqueOverBounds(state) &&
+                mPaint->getStyle() == SkPaint::kFill_Style;
+    }
+
     virtual const char* name() { return "DrawRect"; }
 };
 
@@ -1017,15 +1170,15 @@
         return renderer.drawRects(mRects, mCount, getPaint(renderer));
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("Draw Rects count %d", mCount);
     }
 
     virtual const char* name() { return "DrawRects"; }
 
-    virtual bool onDefer(OpenGLRenderer& renderer, int* batchId, mergeid_t* mergeId) {
-        *batchId = DeferredDisplayList::kOpBatch_Vertices;
-        return false;
+    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
+            const DeferredDisplayState& state) {
+        deferInfo.batchId = DeferredDisplayList::kOpBatch_Vertices;
     }
 
 private:
@@ -1044,7 +1197,7 @@
                 mLocalBounds.right, mLocalBounds.bottom, mRx, mRy, getPaint(renderer));
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("Draw RoundRect "RECT_STRING", rx %f, ry %f", RECT_ARGS(mLocalBounds), mRx, mRy);
     }
 
@@ -1065,7 +1218,7 @@
         return renderer.drawCircle(mX, mY, mRadius, getPaint(renderer));
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("Draw Circle x %f, y %f, r %f", mX, mY, mRadius);
     }
 
@@ -1087,7 +1240,7 @@
                 mLocalBounds.right, mLocalBounds.bottom, getPaint(renderer));
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("Draw Oval "RECT_STRING, RECT_ARGS(mLocalBounds));
     }
 
@@ -1107,7 +1260,7 @@
                 mStartAngle, mSweepAngle, mUseCenter, getPaint(renderer));
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("Draw Arc "RECT_STRING", start %f, sweep %f, useCenter %d",
                 RECT_ARGS(mLocalBounds), mStartAngle, mSweepAngle, mUseCenter);
     }
@@ -1136,15 +1289,15 @@
         return renderer.drawPath(mPath, getPaint(renderer));
     }
 
-    virtual bool onDefer(OpenGLRenderer& renderer, int* batchId, mergeid_t* mergeId) {
+    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
+            const DeferredDisplayState& state) {
         SkPaint* paint = getPaint(renderer);
         renderer.getCaches().pathCache.precache(mPath, paint);
 
-        *batchId = DeferredDisplayList::kOpBatch_AlphaMaskTexture;
-        return false;
+        deferInfo.batchId = DeferredDisplayList::kOpBatch_AlphaMaskTexture;
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("Draw Path %p in "RECT_STRING, mPath, RECT_ARGS(mLocalBounds));
     }
 
@@ -1166,17 +1319,17 @@
         return renderer.drawLines(mPoints, mCount, getPaint(renderer));
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("Draw Lines count %d", mCount);
     }
 
     virtual const char* name() { return "DrawLines"; }
 
-    virtual bool onDefer(OpenGLRenderer& renderer, int* batchId, mergeid_t* mergeId) {
-        *batchId = mPaint->isAntiAlias() ?
+    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
+            const DeferredDisplayState& state) {
+        deferInfo.batchId = mPaint->isAntiAlias() ?
                 DeferredDisplayList::kOpBatch_AlphaVertices :
                 DeferredDisplayList::kOpBatch_Vertices;
-        return false;
     }
 
 protected:
@@ -1193,7 +1346,7 @@
         return renderer.drawPoints(mPoints, mCount, getPaint(renderer));
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("Draw Points count %d", mCount);
     }
 
@@ -1205,20 +1358,19 @@
     DrawSomeTextOp(const char* text, int bytesCount, int count, SkPaint* paint)
             : DrawOp(paint), mText(text), mBytesCount(bytesCount), mCount(count) {};
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("Draw some text, %d bytes", mBytesCount);
     }
 
-    virtual bool onDefer(OpenGLRenderer& renderer, int* batchId, mergeid_t* mergeId) {
+    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
+            const DeferredDisplayState& state) {
         SkPaint* paint = getPaint(renderer);
         FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(paint);
         fontRenderer.precache(paint, mText, mCount, mat4::identity());
 
-        *batchId = mPaint->getColor() == 0xff000000 ?
+        deferInfo.batchId = mPaint->getColor() == 0xff000000 ?
                 DeferredDisplayList::kOpBatch_Text :
                 DeferredDisplayList::kOpBatch_ColorText;
-
-        return false;
     }
 
 protected:
@@ -1270,27 +1422,14 @@
 class DrawTextOp : public DrawBoundedOp {
 public:
     DrawTextOp(const char* text, int bytesCount, int count, float x, float y,
-            const float* positions, SkPaint* paint, float length)
-            : DrawBoundedOp(paint), mText(text), mBytesCount(bytesCount), mCount(count),
-            mX(x), mY(y), mPositions(positions), mLength(length) {
-        // duplicates bounds calculation from OpenGLRenderer::drawText, but doesn't alter mX
-        SkPaint::FontMetrics metrics;
-        paint->getFontMetrics(&metrics, 0.0f);
-        switch (paint->getTextAlign()) {
-        case SkPaint::kCenter_Align:
-            x -= length / 2.0f;
-            break;
-        case SkPaint::kRight_Align:
-            x -= length;
-            break;
-        default:
-            break;
-        }
-        mLocalBounds.set(x, mY + metrics.fTop, x + length, mY + metrics.fBottom);
+            const float* positions, SkPaint* paint, float totalAdvance, const Rect& bounds)
+            : DrawBoundedOp(bounds, paint), mText(text), mBytesCount(bytesCount), mCount(count),
+            mX(x), mY(y), mPositions(positions), mTotalAdvance(totalAdvance) {
         memset(&mPrecacheTransform.data[0], 0xff, 16 * sizeof(float));
     }
 
-    virtual bool onDefer(OpenGLRenderer& renderer, int* batchId, mergeid_t* mergeId) {
+    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
+            const DeferredDisplayState& state) {
         SkPaint* paint = getPaint(renderer);
         FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(paint);
         const mat4& transform = renderer.findBestFontTransform(state.mMatrix);
@@ -1298,39 +1437,45 @@
             fontRenderer.precache(paint, mText, mCount, transform);
             mPrecacheTransform = transform;
         }
-        *batchId = mPaint->getColor() == 0xff000000 ?
+        deferInfo.batchId = mPaint->getColor() == 0xff000000 ?
                 DeferredDisplayList::kOpBatch_Text :
                 DeferredDisplayList::kOpBatch_ColorText;
 
-        *mergeId = (mergeid_t)mPaint->getColor();
+        deferInfo.mergeId = (mergeid_t)mPaint->getColor();
 
         // don't merge decorated text - the decorations won't draw in order
         bool noDecorations = !(mPaint->getFlags() & (SkPaint::kUnderlineText_Flag |
                         SkPaint::kStrikeThruText_Flag));
-        return mergeAllowed() && noDecorations;
+        deferInfo.mergeable = state.mMatrix.isPureTranslate() && noDecorations &&
+                OpenGLRenderer::getXfermodeDirect(mPaint) == SkXfermode::kSrcOver_Mode;
     }
 
     virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
+        Rect bounds;
+        getLocalBounds(renderer.getDrawModifiers(), bounds);
         return renderer.drawText(mText, mBytesCount, mCount, mX, mY,
-                mPositions, getPaint(renderer), mLength);
+                mPositions, getPaint(renderer), mTotalAdvance, bounds);
     }
 
     virtual status_t multiDraw(OpenGLRenderer& renderer, Rect& dirty,
-            const Vector<DrawOp*>& ops, const Rect& bounds) {
+            const Vector<OpStatePair>& ops, const Rect& bounds) {
         status_t status = DrawGlInfo::kStatusDone;
-        renderer.setFullScreenClip(); // ensure merged ops aren't clipped
         for (unsigned int i = 0; i < ops.size(); i++) {
+            const DeferredDisplayState& state = *(ops[i].state);
             DrawOpMode drawOpMode = (i == ops.size() - 1) ? kDrawOpMode_Flush : kDrawOpMode_Defer;
-            renderer.restoreDisplayState(ops[i]->state, true); // restore all but the clip
+            renderer.restoreDisplayState(state, true); // restore all but the clip
 
-            DrawTextOp& op = *((DrawTextOp*)ops[i]);
+            DrawTextOp& op = *((DrawTextOp*)ops[i].op);
+            // quickReject() will not occure in drawText() so we can use mLocalBounds
+            // directly, we do not need to account for shadow by calling getLocalBounds()
             status |= renderer.drawText(op.mText, op.mBytesCount, op.mCount, op.mX, op.mY,
-                    op.mPositions, op.getPaint(renderer), op.mLength, drawOpMode);
+                    op.mPositions, op.getPaint(renderer), op.mTotalAdvance, op.mLocalBounds,
+                    drawOpMode);
         }
         return status;
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("Draw Text of count %d, bytes %d", mCount, mBytesCount);
     }
 
@@ -1343,7 +1488,7 @@
     float mX;
     float mY;
     const float* mPositions;
-    float mLength;
+    float mTotalAdvance;
     mat4 mPrecacheTransform;
 };
 
@@ -1363,7 +1508,7 @@
         return ret;
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("Draw Functor %p", mFunctor);
     }
 
@@ -1397,7 +1542,7 @@
         return DrawGlInfo::kStatusDone;
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("Draw Display List %p, flags %#x", mDisplayList, mFlags);
         if (mDisplayList && (logFlags & kOpLogFlag_Recurse)) {
             mDisplayList->output(level + 1);
@@ -1420,7 +1565,7 @@
         return renderer.drawLayer(mLayer, mX, mY);
     }
 
-    virtual void output(int level, uint32_t logFlags) {
+    virtual void output(int level, uint32_t logFlags) const {
         OP_LOG("Draw Layer %p at %f %f", mLayer, mX, mY);
     }
 
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 876c38a..8866029 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -57,6 +57,10 @@
         mCaches.resourceCache.decrementRefcountLocked(mFilterResources.itemAt(i));
     }
 
+    for (size_t i = 0; i < mPatchResources.size(); i++) {
+        mCaches.resourceCache.decrementRefcountLocked(mPatchResources.itemAt(i));
+    }
+
     for (size_t i = 0; i < mShaders.size(); i++) {
         mCaches.resourceCache.decrementRefcountLocked(mShaders.itemAt(i));
     }
@@ -74,6 +78,7 @@
     mBitmapResources.clear();
     mOwnedBitmapResources.clear();
     mFilterResources.clear();
+    mPatchResources.clear();
     mSourcePaths.clear();
 
     mShaders.clear();
@@ -313,20 +318,13 @@
     return DrawGlInfo::kStatusDone;
 }
 
-status_t DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs,
-        const int32_t* yDivs, const uint32_t* colors, uint32_t width, uint32_t height,
-        int8_t numColors, float left, float top, float right, float bottom, SkPaint* paint) {
-    int alpha;
-    SkXfermode::Mode mode;
-    OpenGLRenderer::getAlphaAndModeDirect(paint, &alpha, &mode);
-
+status_t DisplayListRenderer::drawPatch(SkBitmap* bitmap, Res_png_9patch* patch,
+        float left, float top, float right, float bottom, SkPaint* paint) {
     bitmap = refBitmap(bitmap);
-    xDivs = refBuffer<int>(xDivs, width);
-    yDivs = refBuffer<int>(yDivs, height);
-    colors = refBuffer<uint32_t>(colors, numColors);
+    patch = refPatch(patch);
+    paint = refPaint(paint);
 
-    addDrawOp(new (alloc()) DrawPatchOp(bitmap, xDivs, yDivs, colors, width, height, numColors,
-                    left, top, right, bottom, alpha, mode));
+    addDrawOp(new (alloc()) DrawPatchOp(bitmap, patch, left, top, right, bottom, paint));
     return DrawGlInfo::kStatusDone;
 }
 
@@ -423,17 +421,16 @@
 
 status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
         float x, float y, const float* positions, SkPaint* paint,
-        float length, DrawOpMode drawOpMode) {
+        float totalAdvance, const Rect& bounds, DrawOpMode drawOpMode) {
 
     if (!text || count <= 0) return DrawGlInfo::kStatusDone;
 
-    if (length < 0.0f) length = paint->measureText(text, bytesCount);
-
     text = refText(text, bytesCount);
     positions = refBuffer<float>(positions, count * 2);
     paint = refPaint(paint);
 
-    DrawOp* op = new (alloc()) DrawTextOp(text, bytesCount, count, x, y, positions, paint, length);
+    DrawOp* op = new (alloc()) DrawTextOp(text, bytesCount, count,
+            x, y, positions, paint, totalAdvance, bounds);
     addDrawOp(op);
     return DrawGlInfo::kStatusDone;
 }
@@ -467,10 +464,12 @@
 
 void DisplayListRenderer::resetShadow() {
     addStateOp(new (alloc()) ResetShadowOp());
+    OpenGLRenderer::resetShadow();
 }
 
 void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) {
     addStateOp(new (alloc()) SetupShadowOp(radius, dx, dy, color));
+    OpenGLRenderer::setupShadow(radius, dx, dy, color);
 }
 
 void DisplayListRenderer::resetPaintFilter() {
@@ -506,11 +505,12 @@
 
 void DisplayListRenderer::addDrawOp(DrawOp* op) {
     Rect localBounds;
-    if (op->getLocalBounds(localBounds)) {
+    if (op->getLocalBounds(mDrawModifiers, localBounds)) {
         bool rejected = quickRejectNoScissor(localBounds.left, localBounds.top,
                 localBounds.right, localBounds.bottom);
         op->setQuickRejected(rejected);
     }
+
     mHasDrawOps = true;
     addOpInternal(op);
 }
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 75abad6..d233150 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -103,8 +103,7 @@
     virtual status_t drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint);
     virtual status_t drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
             float* vertices, int* colors, SkPaint* paint);
-    virtual status_t drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
-            const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
+    virtual status_t drawPatch(SkBitmap* bitmap, Res_png_9patch* patch,
             float left, float top, float right, float bottom, SkPaint* paint);
     virtual status_t drawColor(int color, SkXfermode::Mode mode);
     virtual status_t drawRect(float left, float top, float right, float bottom, SkPaint* paint);
@@ -122,7 +121,8 @@
     virtual status_t drawPosText(const char* text, int bytesCount, int count,
             const float* positions, SkPaint* paint);
     virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y,
-            const float* positions, SkPaint* paint, float length, DrawOpMode drawOpMode);
+            const float* positions, SkPaint* paint, float totalAdvance, const Rect& bounds,
+            DrawOpMode drawOpMode);
 
     virtual status_t drawRects(const float* rects, int count, SkPaint* paint);
 
@@ -156,6 +156,10 @@
         return mFilterResources;
     }
 
+    const Vector<Res_png_9patch*>& getPatchResources() const {
+        return mPatchResources;
+    }
+
     const Vector<SkiaShader*>& getShaders() const {
         return mShaders;
     }
@@ -265,11 +269,14 @@
     }
 
     inline SkMatrix* refMatrix(SkMatrix* matrix) {
-        // Copying the matrix is cheap and prevents against the user changing the original
-        // matrix before the operation that uses it
-        SkMatrix* copy = new SkMatrix(*matrix);
-        mMatrices.add(copy);
-        return copy;
+        if (matrix) {
+            // Copying the matrix is cheap and prevents against the user changing
+            // the original matrix before the operation that uses it
+            SkMatrix* copy = new SkMatrix(*matrix);
+            mMatrices.add(copy);
+            return copy;
+        }
+        return matrix;
     }
 
     inline Layer* refLayer(Layer* layer) {
@@ -315,9 +322,16 @@
         return colorFilter;
     }
 
+    inline Res_png_9patch* refPatch(Res_png_9patch* patch) {
+        mPatchResources.add(patch);
+        mCaches.resourceCache.incrementRefcount(patch);
+        return patch;
+    }
+
     Vector<SkBitmap*> mBitmapResources;
     Vector<SkBitmap*> mOwnedBitmapResources;
     Vector<SkiaColorFilter*> mFilterResources;
+    Vector<Res_png_9patch*> mPatchResources;
 
     Vector<SkPaint*> mPaints;
     DefaultKeyedVector<SkPaint*, SkPaint*> mPaintMap;
diff --git a/libs/hwui/Dither.cpp b/libs/hwui/Dither.cpp
index 19b3849..77006a4 100644
--- a/libs/hwui/Dither.cpp
+++ b/libs/hwui/Dither.cpp
@@ -24,12 +24,15 @@
 // Lifecycle
 ///////////////////////////////////////////////////////////////////////////////
 
+Dither::Dither(): mCaches(NULL), mInitialized(false), mDitherTexture(0) {
+}
+
 void Dither::bindDitherTexture() {
     if (!mInitialized) {
-        bool useFloatTexture = Extensions::getInstance().getMajorGlVersion() >= 3;
+        bool useFloatTexture = Extensions::getInstance().hasFloatTextures();
 
         glGenTextures(1, &mDitherTexture);
-        glBindTexture(GL_TEXTURE_2D, mDitherTexture);
+        mCaches->bindTexture(mDitherTexture);
 
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -68,13 +71,13 @@
 
         mInitialized = true;
     } else {
-        glBindTexture(GL_TEXTURE_2D, mDitherTexture);
+        mCaches->bindTexture(mDitherTexture);
     }
 }
 
 void Dither::clear() {
     if (mInitialized) {
-        glDeleteTextures(1, &mDitherTexture);
+        mCaches->deleteTexture(mDitherTexture);
         mInitialized = false;
     }
 }
@@ -84,8 +87,10 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 void Dither::setupProgram(Program* program, GLuint* textureUnit) {
+    if (!mCaches) mCaches = &Caches::getInstance();
+
     GLuint textureSlot = (*textureUnit)++;
-    Caches::getInstance().activeTexture(textureSlot);
+    mCaches->activeTexture(textureSlot);
 
     bindDitherTexture();
 
diff --git a/libs/hwui/Dither.h b/libs/hwui/Dither.h
index 4d1f921..546236be 100644
--- a/libs/hwui/Dither.h
+++ b/libs/hwui/Dither.h
@@ -24,9 +24,7 @@
 namespace android {
 namespace uirenderer {
 
-///////////////////////////////////////////////////////////////////////////////
-// Defines
-///////////////////////////////////////////////////////////////////////////////
+class Caches;
 
 // Must be a power of two
 #define DITHER_KERNEL_SIZE 4
@@ -39,7 +37,7 @@
  */
 class Dither {
 public:
-    Dither(): mInitialized(false), mDitherTexture(0) { }
+    Dither();
 
     void clear();
     void setupProgram(Program* program, GLuint* textureUnit);
@@ -47,6 +45,7 @@
 private:
     void bindDitherTexture();
 
+    Caches* mCaches;
     bool mInitialized;
     GLuint mDitherTexture;
 };
diff --git a/libs/hwui/Extensions.cpp b/libs/hwui/Extensions.cpp
index 51aec8d..84e7e65 100644
--- a/libs/hwui/Extensions.cpp
+++ b/libs/hwui/Extensions.cpp
@@ -14,8 +14,19 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "OpenGLRenderer"
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include <utils/Log.h>
+
 #include "Debug.h"
 #include "Extensions.h"
+#include "Properties.h"
 
 namespace android {
 
@@ -40,33 +51,28 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 Extensions::Extensions(): Singleton<Extensions>() {
-    const char* buffer = (const char*) glGetString(GL_EXTENSIONS);
-    const char* current = buffer;
-    const char* head = current;
-    EXT_LOGD("Available GL extensions:");
-    do {
-        head = strchr(current, ' ');
-        String8 s(current, head ? head - current : strlen(current));
-        if (s.length()) {
-            mExtensionList.add(s);
-            EXT_LOGD("  %s", s.string());
-        }
-        current = head + 1;
-    } while (head);
+    // Query GL extensions
+    findExtensions((const char*) glGetString(GL_EXTENSIONS), mGlExtensionList);
+    mHasNPot = hasGlExtension("GL_OES_texture_npot");
+    mHasFramebufferFetch = hasGlExtension("GL_NV_shader_framebuffer_fetch");
+    mHasDiscardFramebuffer = hasGlExtension("GL_EXT_discard_framebuffer");
+    mHasDebugMarker = hasGlExtension("GL_EXT_debug_marker");
+    mHasDebugLabel = hasGlExtension("GL_EXT_debug_label");
+    mHasTiledRendering = hasGlExtension("GL_QCOM_tiled_rendering");
+    mHas1BitStencil = hasGlExtension("GL_OES_stencil1");
+    mHas4BitStencil = hasGlExtension("GL_OES_stencil4");
 
-    mHasNPot = hasExtension("GL_OES_texture_npot");
-    mHasFramebufferFetch = hasExtension("GL_NV_shader_framebuffer_fetch");
-    mHasDiscardFramebuffer = hasExtension("GL_EXT_discard_framebuffer");
-    mHasDebugMarker = hasExtension("GL_EXT_debug_marker");
-    mHasDebugLabel = hasExtension("GL_EXT_debug_label");
-    mHasTiledRendering = hasExtension("GL_QCOM_tiled_rendering");
-    mHas1BitStencil = hasExtension("GL_OES_stencil1");
-    mHas4BitStencil = hasExtension("GL_OES_stencil4");
+    // Query EGL extensions
+    findExtensions(eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS), mEglExtensionList);
 
-    mExtensions = strdup(buffer);
+    char property[PROPERTY_VALUE_MAX];
+    if (property_get(PROPERTY_DEBUG_NV_PROFILING, property, NULL) > 0) {
+        mHasNvSystemTime = !strcmp(property, "true") && hasEglExtension("EGL_NV_system_time");
+    } else {
+        mHasNvSystemTime = false;
+    }
 
     const char* version = (const char*) glGetString(GL_VERSION);
-    mVersion = strdup(version);
 
     // Section 6.1.5 of the OpenGL ES specification indicates the GL version
     // string strictly follows this format:
@@ -80,7 +86,7 @@
     // or more digits. The release number and vendor specific information are
     // optional."
 
-    if (sscanf(version, "OpenGL ES %d.%d", &mVersionMajor, &mVersionMinor) !=2) {
+    if (sscanf(version, "OpenGL ES %d.%d", &mVersionMajor, &mVersionMinor) != 2) {
         // If we cannot parse the version number, assume OpenGL ES 2.0
         mVersionMajor = 2;
         mVersionMinor = 0;
@@ -88,22 +94,41 @@
 }
 
 Extensions::~Extensions() {
-   free(mExtensions);
-   free(mVersion);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 // Methods
 ///////////////////////////////////////////////////////////////////////////////
 
-bool Extensions::hasExtension(const char* extension) const {
+bool Extensions::hasGlExtension(const char* extension) const {
    const String8 s(extension);
-   return mExtensionList.indexOf(s) >= 0;
+   return mGlExtensionList.indexOf(s) >= 0;
+}
+
+bool Extensions::hasEglExtension(const char* extension) const {
+   const String8 s(extension);
+   return mEglExtensionList.indexOf(s) >= 0;
+}
+
+void Extensions::findExtensions(const char* extensions, SortedVector<String8>& list) const {
+    const char* current = extensions;
+    const char* head = current;
+    EXT_LOGD("Available extensions:");
+    do {
+        head = strchr(current, ' ');
+        String8 s(current, head ? head - current : strlen(current));
+        if (s.length()) {
+            list.add(s);
+            EXT_LOGD("  %s", s.string());
+        }
+        current = head + 1;
+    } while (head);
 }
 
 void Extensions::dump() const {
-   ALOGD("%s", mVersion);
-   ALOGD("Supported extensions:\n%s", mExtensions);
+   ALOGD("%s", (const char*) glGetString(GL_VERSION));
+   ALOGD("Supported GL extensions:\n%s", (const char*) glGetString(GL_EXTENSIONS));
+   ALOGD("Supported EGL extensions:\n%s", eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS));
 }
 
 }; // namespace uirenderer
diff --git a/libs/hwui/Extensions.h b/libs/hwui/Extensions.h
index 54a3987..5e574a6 100644
--- a/libs/hwui/Extensions.h
+++ b/libs/hwui/Extensions.h
@@ -17,13 +17,12 @@
 #ifndef ANDROID_HWUI_EXTENSIONS_H
 #define ANDROID_HWUI_EXTENSIONS_H
 
+#include <cutils/compiler.h>
+
 #include <utils/Singleton.h>
 #include <utils/SortedVector.h>
 #include <utils/String8.h>
 
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
 namespace android {
 namespace uirenderer {
 
@@ -31,11 +30,8 @@
 // Classes
 ///////////////////////////////////////////////////////////////////////////////
 
-class Extensions: public Singleton<Extensions> {
+class ANDROID_API Extensions: public Singleton<Extensions> {
 public:
-    Extensions();
-    ~Extensions();
-
     inline bool hasNPot() const { return mHasNPot; }
     inline bool hasFramebufferFetch() const { return mHasFramebufferFetch; }
     inline bool hasDiscardFramebuffer() const { return mHasDiscardFramebuffer; }
@@ -44,21 +40,30 @@
     inline bool hasTiledRendering() const { return mHasTiledRendering; }
     inline bool has1BitStencil() const { return mHas1BitStencil; }
     inline bool has4BitStencil() const { return mHas4BitStencil; }
+    inline bool hasNvSystemTime() const { return mHasNvSystemTime; }
+
+    inline bool hasPixelBufferObjects() const { return mVersionMajor >= 3; }
+    inline bool hasOcclusionQueries() const { return mVersionMajor >= 3; }
+    inline bool hasFloatTextures() const { return mVersionMajor >= 3; }
 
     inline int getMajorGlVersion() const { return mVersionMajor; }
     inline int getMinorGlVersion() const { return mVersionMinor; }
 
-    bool hasExtension(const char* extension) const;
+    bool hasGlExtension(const char* extension) const;
+    bool hasEglExtension(const char* extension) const;
 
     void dump() const;
 
 private:
+    Extensions();
+    ~Extensions();
+
+    void findExtensions(const char* extensions, SortedVector<String8>& list) const;
+
     friend class Singleton<Extensions>;
 
-    SortedVector<String8> mExtensionList;
-
-    char* mExtensions;
-    char* mVersion;
+    SortedVector<String8> mGlExtensionList;
+    SortedVector<String8> mEglExtensionList;
 
     bool mHasNPot;
     bool mHasFramebufferFetch;
@@ -68,6 +73,7 @@
     bool mHasTiledRendering;
     bool mHas1BitStencil;
     bool mHas4BitStencil;
+    bool mHasNvSystemTime;
 
     int mVersionMajor;
     int mVersionMinor;
diff --git a/libs/hwui/Fence.h b/libs/hwui/Fence.h
new file mode 100644
index 0000000..f175e98
--- /dev/null
+++ b/libs/hwui/Fence.h
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HWUI_FENCE_H
+#define ANDROID_HWUI_FENCE_H
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+namespace android {
+namespace uirenderer {
+
+/**
+ * Creating a Fence instance inserts a new sync fence in the OpenGL
+ * commands stream. The caller can then wait for the fence to be signaled
+ * by calling the wait method.
+ */
+class Fence {
+public:
+    enum {
+        /**
+         * Default timeout in nano-seconds for wait()
+         */
+        kDefaultTimeout = 1000000000
+    };
+
+    /**
+     * Inserts a new sync fence in the OpenGL commands stream.
+     */
+    Fence() {
+        mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+        if (mDisplay != EGL_NO_DISPLAY) {
+            mFence = eglCreateSyncKHR(mDisplay, EGL_SYNC_FENCE_KHR, NULL);
+        } else {
+            mFence = EGL_NO_SYNC_KHR;
+        }
+    }
+
+    /**
+     * Destroys the fence. Any caller waiting on the fence will be
+     * signaled immediately.
+     */
+    ~Fence() {
+        if (mFence != EGL_NO_SYNC_KHR) {
+            eglDestroySyncKHR(mDisplay, mFence);
+        }
+    }
+
+    /**
+     * Blocks the calling thread until this fence is signaled, or until
+     * <timeout> nanoseconds have passed.
+     *
+     * Returns true if waiting for the fence was successful, false if
+     * a timeout or an error occurred.
+     */
+    bool wait(EGLTimeKHR timeout = kDefaultTimeout) {
+        EGLint waitStatus = eglClientWaitSyncKHR(mDisplay, mFence,
+                EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, timeout);
+        if (waitStatus == EGL_FALSE) {
+            ALOGW("Failed to wait for the fence %#x", eglGetError());
+        }
+        return waitStatus == EGL_CONDITION_SATISFIED_KHR;
+    }
+
+private:
+    EGLDisplay mDisplay;
+    EGLSyncKHR mFence;
+
+}; // class Fence
+
+/**
+ * An AutoFence creates a Fence instance and waits for the fence
+ * to be signaled when the AutoFence is destroyed. This is useful
+ * to automatically wait for a series of OpenGL commands to be
+ * executed. For example:
+ *
+ * void drawAndWait() {
+ *     glDrawElements();
+ *     AutoFence fence;
+ * }
+ */
+class AutoFence {
+public:
+    AutoFence(EGLTimeKHR timeout = Fence::kDefaultTimeout): mTimeout(timeout) {
+    }
+
+    ~AutoFence() {
+        mFence.wait(mTimeout);
+    }
+
+private:
+    EGLTimeKHR mTimeout;
+    Fence mFence;
+
+}; // class AutoFence
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_HWUI_FENCE_H
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 543cfa2..7e99a5f 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -21,10 +21,11 @@
 
 #include <cutils/properties.h>
 
-#include <utils/Functor.h>
 #include <utils/Log.h>
 
+#ifdef ANDROID_ENABLE_RENDERSCRIPT
 #include <RenderScript.h>
+#endif
 
 #include "utils/Blur.h"
 #include "utils/Timing.h"
@@ -33,6 +34,7 @@
 #include "Debug.h"
 #include "Extensions.h"
 #include "FontRenderer.h"
+#include "OpenGLRenderer.h"
 #include "PixelBuffer.h"
 #include "Rect.h"
 
@@ -43,6 +45,52 @@
 #define RS_MIN_INPUT_CUTOFF 10000
 
 ///////////////////////////////////////////////////////////////////////////////
+// TextSetupFunctor
+///////////////////////////////////////////////////////////////////////////////
+status_t TextSetupFunctor::operator ()(int what, void* data) {
+    Data* typedData = reinterpret_cast<Data*>(data);
+    GLenum glyphFormat = typedData ? typedData->glyphFormat : GL_ALPHA;
+
+    renderer->setupDraw();
+    renderer->setupDrawTextGamma(paint);
+    renderer->setupDrawDirtyRegionsDisabled();
+    renderer->setupDrawWithTexture(glyphFormat == GL_ALPHA);
+    switch (glyphFormat) {
+        case GL_ALPHA: {
+            renderer->setupDrawAlpha8Color(paint->getColor(), alpha);
+            break;
+        }
+        case GL_RGBA: {
+            float floatAlpha = alpha / 255.0f;
+            renderer->setupDrawColor(floatAlpha, floatAlpha, floatAlpha, floatAlpha);
+            break;
+        }
+        default: {
+#if DEBUG_FONT_RENDERER
+            ALOGD("TextSetupFunctor: called with unknown glyph format %x", glyphFormat);
+#endif
+            break;
+        }
+    }
+    renderer->setupDrawColorFilter();
+    renderer->setupDrawShader();
+    renderer->setupDrawBlending(true, mode);
+    renderer->setupDrawProgram();
+    renderer->setupDrawModelView(x, y, x, y, pureTranslate, true);
+    // Calling setupDrawTexture with the name 0 will enable the
+    // uv attributes and increase the texture unit count
+    // texture binding will be performed by the font renderer as
+    // needed
+    renderer->setupDrawTexture(0);
+    renderer->setupDrawPureColorUniforms();
+    renderer->setupDrawColorFilterUniforms();
+    renderer->setupDrawShaderUniforms(pureTranslate);
+    renderer->setupDrawTextGammaUniforms();
+
+    return NO_ERROR;
+}
+
+///////////////////////////////////////////////////////////////////////////////
 // FontRenderer
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -62,8 +110,6 @@
 
     mLinearFiltering = false;
 
-    mIndexBufferID = 0;
-
     mSmallCacheWidth = DEFAULT_TEXT_SMALL_CACHE_WIDTH;
     mSmallCacheHeight = DEFAULT_TEXT_SMALL_CACHE_HEIGHT;
     mLargeCacheWidth = DEFAULT_TEXT_LARGE_CACHE_WIDTH;
@@ -103,17 +149,16 @@
     sLogFontRendererCreate = false;
 }
 
-FontRenderer::~FontRenderer() {
-    for (uint32_t i = 0; i < mCacheTextures.size(); i++) {
-        delete mCacheTextures[i];
+void clearCacheTextures(Vector<CacheTexture*>& cacheTextures) {
+    for (uint32_t i = 0; i < cacheTextures.size(); i++) {
+        delete cacheTextures[i];
     }
-    mCacheTextures.clear();
+    cacheTextures.clear();
+}
 
-    if (mInitialized) {
-        // Unbinding the buffer shouldn't be necessary but it crashes with some drivers
-        Caches::getInstance().unbindIndicesBuffer();
-        glDeleteBuffers(1, &mIndexBufferID);
-    }
+FontRenderer::~FontRenderer() {
+    clearCacheTextures(mACacheTextures);
+    clearCacheTextures(mRGBACacheTextures);
 
     LruCache<Font::FontDescription, Font*>::Iterator it(mActiveFonts);
     while (it.next()) {
@@ -130,15 +175,19 @@
         it.value()->invalidateTextureCache();
     }
 
-    for (uint32_t i = 0; i < mCacheTextures.size(); i++) {
-        mCacheTextures[i]->init();
+    for (uint32_t i = 0; i < mACacheTextures.size(); i++) {
+        mACacheTextures[i]->init();
+    }
+
+    for (uint32_t i = 0; i < mRGBACacheTextures.size(); i++) {
+        mRGBACacheTextures[i]->init();
     }
 }
 
-void FontRenderer::flushLargeCaches() {
+void FontRenderer::flushLargeCaches(Vector<CacheTexture*>& cacheTextures) {
     // Start from 1; don't deallocate smallest/default texture
-    for (uint32_t i = 1; i < mCacheTextures.size(); i++) {
-        CacheTexture* cacheTexture = mCacheTextures[i];
+    for (uint32_t i = 1; i < cacheTextures.size(); i++) {
+        CacheTexture* cacheTexture = cacheTextures[i];
         if (cacheTexture->getPixelBuffer()) {
             cacheTexture->init();
             LruCache<Font::FontDescription, Font*>::Iterator it(mActiveFonts);
@@ -150,11 +199,16 @@
     }
 }
 
-CacheTexture* FontRenderer::cacheBitmapInTexture(const SkGlyph& glyph,
-        uint32_t* startX, uint32_t* startY) {
-    for (uint32_t i = 0; i < mCacheTextures.size(); i++) {
-        if (mCacheTextures[i]->fitBitmap(glyph, startX, startY)) {
-            return mCacheTextures[i];
+void FontRenderer::flushLargeCaches() {
+    flushLargeCaches(mACacheTextures);
+    flushLargeCaches(mRGBACacheTextures);
+}
+
+CacheTexture* FontRenderer::cacheBitmapInTexture(Vector<CacheTexture*>& cacheTextures,
+        const SkGlyph& glyph, uint32_t* startX, uint32_t* startY) {
+    for (uint32_t i = 0; i < cacheTextures.size(); i++) {
+        if (cacheTextures[i]->fitBitmap(glyph, startX, startY)) {
+            return cacheTextures[i];
         }
     }
     // Could not fit glyph into current cache textures
@@ -175,9 +229,27 @@
 
     cachedGlyph->mIsValid = false;
 
+    // choose an appropriate cache texture list for this glyph format
+    SkMask::Format format = static_cast<SkMask::Format>(glyph.fMaskFormat);
+    Vector<CacheTexture*>* cacheTextures = NULL;
+    switch (format) {
+        case SkMask::kA8_Format:
+        case SkMask::kBW_Format:
+            cacheTextures = &mACacheTextures;
+            break;
+        case SkMask::kARGB32_Format:
+            cacheTextures = &mRGBACacheTextures;
+            break;
+        default:
+#if DEBUG_FONT_RENDERER
+            ALOGD("getCacheTexturesForFormat: unknown SkMask format %x", format);
+#endif
+        return;
+    }
+
     // If the glyph is too tall, don't cache it
     if (glyph.fHeight + TEXTURE_BORDER_SIZE * 2 >
-                mCacheTextures[mCacheTextures.size() - 1]->getHeight()) {
+                (*cacheTextures)[cacheTextures->size() - 1]->getHeight()) {
         ALOGE("Font size too large to fit in cache. width, height = %i, %i",
                 (int) glyph.fWidth, (int) glyph.fHeight);
         return;
@@ -187,14 +259,14 @@
     uint32_t startX = 0;
     uint32_t startY = 0;
 
-    CacheTexture* cacheTexture = cacheBitmapInTexture(glyph, &startX, &startY);
+    CacheTexture* cacheTexture = cacheBitmapInTexture(*cacheTextures, glyph, &startX, &startY);
 
     if (!cacheTexture) {
         if (!precaching) {
             // If the new glyph didn't fit and we are not just trying to precache it,
             // clear out the cache and try again
             flushAllAndInvalidate();
-            cacheTexture = cacheBitmapInTexture(glyph, &startX, &startY);
+            cacheTexture = cacheBitmapInTexture(*cacheTextures, glyph, &startX, &startY);
         }
 
         if (!cacheTexture) {
@@ -222,24 +294,21 @@
         cacheTexture->allocateMesh();
     }
 
-    // Tells us whether the glyphs is B&W (1 bit per pixel)
-    // or anti-aliased (8 bits per pixel)
-    SkMask::Format format = static_cast<SkMask::Format>(glyph.fMaskFormat);
-
     uint8_t* cacheBuffer = cacheTexture->getPixelBuffer()->map();
-    uint32_t cacheX = 0, bX = 0, cacheY = 0, bY = 0;
+    uint8_t* bitmapBuffer = (uint8_t*) glyph.fImage;
+    int srcStride = glyph.rowBytes();
 
     // Copy the glyph image, taking the mask format into account
-    uint8_t* bitmapBuffer = (uint8_t*) glyph.fImage;
-    int stride = glyph.rowBytes();
-
-    uint32_t row = (startY - TEXTURE_BORDER_SIZE) * cacheWidth + startX - TEXTURE_BORDER_SIZE;
-    memset(&cacheBuffer[row], 0, glyph.fWidth + 2 * TEXTURE_BORDER_SIZE);
-
     switch (format) {
         case SkMask::kA8_Format: {
+            uint32_t cacheX = 0, bX = 0, cacheY = 0, bY = 0;
+            uint32_t row = (startY - TEXTURE_BORDER_SIZE) * cacheWidth + startX
+                    - TEXTURE_BORDER_SIZE;
+            // write leading border line
+            memset(&cacheBuffer[row], 0, glyph.fWidth + 2 * TEXTURE_BORDER_SIZE);
+            // write glyph data
             if (mGammaTable) {
-                for (cacheY = startY, bY = 0; cacheY < endY; cacheY++, bY += stride) {
+                for (cacheY = startY, bY = 0; cacheY < endY; cacheY++, bY += srcStride) {
                     row = cacheY * cacheWidth;
                     cacheBuffer[row + startX - TEXTURE_BORDER_SIZE] = 0;
                     for (cacheX = startX, bX = 0; cacheX < endX; cacheX++, bX++) {
@@ -249,21 +318,55 @@
                     cacheBuffer[row + endX + TEXTURE_BORDER_SIZE - 1] = 0;
                 }
             } else {
-                for (cacheY = startY, bY = 0; cacheY < endY; cacheY++, bY += stride) {
+                for (cacheY = startY, bY = 0; cacheY < endY; cacheY++, bY += srcStride) {
                     row = cacheY * cacheWidth;
                     memcpy(&cacheBuffer[row + startX], &bitmapBuffer[bY], glyph.fWidth);
                     cacheBuffer[row + startX - TEXTURE_BORDER_SIZE] = 0;
                     cacheBuffer[row + endX + TEXTURE_BORDER_SIZE - 1] = 0;
                 }
             }
+            // write trailing border line
+            row = (endY + TEXTURE_BORDER_SIZE - 1) * cacheWidth + startX - TEXTURE_BORDER_SIZE;
+            memset(&cacheBuffer[row], 0, glyph.fWidth + 2 * TEXTURE_BORDER_SIZE);
+            break;
+        }
+        case SkMask::kARGB32_Format: {
+            // prep data lengths
+            const size_t formatSize = PixelBuffer::formatSize(GL_RGBA);
+            const size_t borderSize = formatSize * TEXTURE_BORDER_SIZE;
+            size_t rowSize = formatSize * glyph.fWidth;
+            // prep advances
+            size_t dstStride = formatSize * cacheWidth;
+            // prep indices
+            // - we actually start one row early, and then increment before first copy
+            uint8_t* src = &bitmapBuffer[0 - srcStride];
+            uint8_t* dst = &cacheBuffer[cacheTexture->getOffset(startX, startY - 1)];
+            uint8_t* dstEnd = &cacheBuffer[cacheTexture->getOffset(startX, endY - 1)];
+            uint8_t* dstL = dst - borderSize;
+            uint8_t* dstR = dst + rowSize;
+            // write leading border line
+            memset(dstL, 0, rowSize + 2 * borderSize);
+            // write glyph data
+            while (dst < dstEnd) {
+                memset(dstL += dstStride, 0, borderSize); // leading border column
+                memcpy(dst += dstStride, src += srcStride, rowSize); // glyph data
+                memset(dstR += dstStride, 0, borderSize); // trailing border column
+            }
+            // write trailing border line
+            memset(dstL, 0, rowSize + 2 * borderSize);
             break;
         }
         case SkMask::kBW_Format: {
+            uint32_t cacheX = 0, bX = 0, cacheY = 0, bY = 0;
+            uint32_t row = (startY - TEXTURE_BORDER_SIZE) * cacheWidth + startX
+                    - TEXTURE_BORDER_SIZE;
             static const uint8_t COLORS[2] = { 0, 255 };
-
+            // write leading border line
+            memset(&cacheBuffer[row], 0, glyph.fWidth + 2 * TEXTURE_BORDER_SIZE);
+            // write glyph data
             for (cacheY = startY; cacheY < endY; cacheY++) {
                 cacheX = startX;
-                int rowBytes = stride;
+                int rowBytes = srcStride;
                 uint8_t* buffer = bitmapBuffer;
 
                 row = cacheY * cacheWidth;
@@ -276,23 +379,24 @@
                 }
                 cacheBuffer[row + endX + TEXTURE_BORDER_SIZE - 1] = 0;
 
-                bitmapBuffer += stride;
+                bitmapBuffer += srcStride;
             }
+            // write trailing border line
+            row = (endY + TEXTURE_BORDER_SIZE - 1) * cacheWidth + startX - TEXTURE_BORDER_SIZE;
+            memset(&cacheBuffer[row], 0, glyph.fWidth + 2 * TEXTURE_BORDER_SIZE);
             break;
         }
         default:
-            ALOGW("Unkown glyph format: 0x%x", format);
+            ALOGW("Unknown glyph format: 0x%x", format);
             break;
     }
 
-    row = (endY + TEXTURE_BORDER_SIZE - 1) * cacheWidth + startX - TEXTURE_BORDER_SIZE;
-    memset(&cacheBuffer[row], 0, glyph.fWidth + 2 * TEXTURE_BORDER_SIZE);
-
     cachedGlyph->mIsValid = true;
 }
 
-CacheTexture* FontRenderer::createCacheTexture(int width, int height, bool allocate) {
-    CacheTexture* cacheTexture = new CacheTexture(width, height, gMaxNumberOfQuads);
+CacheTexture* FontRenderer::createCacheTexture(int width, int height, GLenum format,
+        bool allocate) {
+    CacheTexture* cacheTexture = new CacheTexture(width, height, format, gMaxNumberOfQuads);
 
     if (allocate) {
         Caches::getInstance().activeTexture(0);
@@ -304,44 +408,23 @@
 }
 
 void FontRenderer::initTextTexture() {
-    for (uint32_t i = 0; i < mCacheTextures.size(); i++) {
-        delete mCacheTextures[i];
-    }
-    mCacheTextures.clear();
+    clearCacheTextures(mACacheTextures);
+    clearCacheTextures(mRGBACacheTextures);
 
     mUploadTexture = false;
-    mCacheTextures.push(createCacheTexture(mSmallCacheWidth, mSmallCacheHeight, true));
-    mCacheTextures.push(createCacheTexture(mLargeCacheWidth, mLargeCacheHeight >> 1, false));
-    mCacheTextures.push(createCacheTexture(mLargeCacheWidth, mLargeCacheHeight >> 1, false));
-    mCacheTextures.push(createCacheTexture(mLargeCacheWidth, mLargeCacheHeight, false));
-    mCurrentCacheTexture = mCacheTextures[0];
-}
-
-// Avoid having to reallocate memory and render quad by quad
-void FontRenderer::initVertexArrayBuffers() {
-    uint32_t numIndices = gMaxNumberOfQuads * 6;
-    uint32_t indexBufferSizeBytes = numIndices * sizeof(uint16_t);
-    uint16_t* indexBufferData = (uint16_t*) malloc(indexBufferSizeBytes);
-
-    // Four verts, two triangles , six indices per quad
-    for (uint32_t i = 0; i < gMaxNumberOfQuads; i++) {
-        int i6 = i * 6;
-        int i4 = i * 4;
-
-        indexBufferData[i6 + 0] = i4 + 0;
-        indexBufferData[i6 + 1] = i4 + 1;
-        indexBufferData[i6 + 2] = i4 + 2;
-
-        indexBufferData[i6 + 3] = i4 + 0;
-        indexBufferData[i6 + 4] = i4 + 2;
-        indexBufferData[i6 + 5] = i4 + 3;
-    }
-
-    glGenBuffers(1, &mIndexBufferID);
-    Caches::getInstance().bindIndicesBuffer(mIndexBufferID);
-    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexBufferSizeBytes, indexBufferData, GL_STATIC_DRAW);
-
-    free(indexBufferData);
+    mACacheTextures.push(createCacheTexture(mSmallCacheWidth, mSmallCacheHeight,
+            GL_ALPHA, true));
+    mACacheTextures.push(createCacheTexture(mLargeCacheWidth, mLargeCacheHeight >> 1,
+            GL_ALPHA, false));
+    mACacheTextures.push(createCacheTexture(mLargeCacheWidth, mLargeCacheHeight >> 1,
+            GL_ALPHA, false));
+    mACacheTextures.push(createCacheTexture(mLargeCacheWidth, mLargeCacheHeight,
+            GL_ALPHA, false));
+    mRGBACacheTextures.push(createCacheTexture(mSmallCacheWidth, mSmallCacheHeight,
+            GL_RGBA, false));
+    mRGBACacheTextures.push(createCacheTexture(mLargeCacheWidth, mLargeCacheHeight >> 1,
+            GL_RGBA, false));
+    mCurrentCacheTexture = mACacheTextures[0];
 }
 
 // We don't want to allocate anything unless we actually draw text
@@ -351,11 +434,28 @@
     }
 
     initTextTexture();
-    initVertexArrayBuffers();
 
     mInitialized = true;
 }
 
+void checkTextureUpdateForCache(Caches& caches, Vector<CacheTexture*>& cacheTextures,
+        bool& resetPixelStore, GLuint& lastTextureId) {
+    for (uint32_t i = 0; i < cacheTextures.size(); i++) {
+        CacheTexture* cacheTexture = cacheTextures[i];
+        if (cacheTexture->isDirty() && cacheTexture->getPixelBuffer()) {
+            if (cacheTexture->getTextureId() != lastTextureId) {
+                lastTextureId = cacheTexture->getTextureId();
+                caches.activeTexture(0);
+                caches.bindTexture(lastTextureId);
+            }
+
+            if (cacheTexture->upload()) {
+                resetPixelStore = true;
+            }
+        }
+    }
+}
+
 void FontRenderer::checkTextureUpdate() {
     if (!mUploadTexture) {
         return;
@@ -368,25 +468,8 @@
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 
     // Iterate over all the cache textures and see which ones need to be updated
-    for (uint32_t i = 0; i < mCacheTextures.size(); i++) {
-        CacheTexture* cacheTexture = mCacheTextures[i];
-        if (cacheTexture->isDirty() && cacheTexture->getPixelBuffer()) {
-            if (cacheTexture->getTextureId() != lastTextureId) {
-                lastTextureId = cacheTexture->getTextureId();
-                caches.activeTexture(0);
-                glBindTexture(GL_TEXTURE_2D, lastTextureId);
-            }
-
-            if (cacheTexture->upload()) {
-                resetPixelStore = true;
-            }
-
-#if DEBUG_FONT_RENDERER
-            ALOGD("glTexSubimage for cacheTexture %d: x, y, width height = %d, %d, %d, %d",
-                    i, x, y, width, height);
-#endif
-        }
-    }
+    checkTextureUpdateForCache(caches, mACacheTextures, resetPixelStore, lastTextureId);
+    checkTextureUpdateForCache(caches, mRGBACacheTextures, resetPixelStore, lastTextureId);
 
     // Unbind any PBO we might have used to update textures
     caches.unbindPixelBuffer();
@@ -400,21 +483,21 @@
     mUploadTexture = false;
 }
 
-void FontRenderer::issueDrawCommand() {
+void FontRenderer::issueDrawCommand(Vector<CacheTexture*>& cacheTextures) {
+    Caches& caches = Caches::getInstance();
     bool first = true;
     bool force = false;
-
-    GLuint lastId = 0;
-    Caches& caches = Caches::getInstance();
-
-    for (uint32_t i = 0; i < mCacheTextures.size(); i++) {
-        CacheTexture* texture = mCacheTextures[i];
+    for (uint32_t i = 0; i < cacheTextures.size(); i++) {
+        CacheTexture* texture = cacheTextures[i];
         if (texture->canDraw()) {
             if (first) {
-                if (mFunctor) (*mFunctor)(0, NULL);
+                if (mFunctor) {
+                    TextSetupFunctor::Data functorData(texture->getFormat());
+                    (*mFunctor)(0, &functorData);
+                }
 
                 checkTextureUpdate();
-                caches.bindIndicesBuffer(mIndexBufferID);
+                caches.bindIndicesBuffer();
 
                 if (!mDrawn) {
                     // If returns true, a VBO was bound and we must
@@ -427,7 +510,7 @@
                 first = false;
             }
 
-            glBindTexture(GL_TEXTURE_2D, texture->getTextureId());
+            caches.bindTexture(texture->getTextureId());
             texture->setLinearFiltering(mLinearFiltering, false);
 
             TextureVertex* mesh = texture->mesh();
@@ -441,6 +524,11 @@
             texture->resetMesh();
         }
     }
+}
+
+void FontRenderer::issueDrawCommand() {
+    issueDrawCommand(mACacheTextures);
+    issueDrawCommand(mRGBACacheTextures);
 
     mDrawn = true;
 }
@@ -532,13 +620,18 @@
         return image;
     }
 
+#ifdef ANDROID_ENABLE_RENDERSCRIPT
     // Align buffers for renderscript usage
     if (paddedWidth & (RS_CPU_ALLOCATION_ALIGNMENT - 1)) {
         paddedWidth += RS_CPU_ALLOCATION_ALIGNMENT - paddedWidth % RS_CPU_ALLOCATION_ALIGNMENT;
     }
-
     int size = paddedWidth * paddedHeight;
     uint8_t* dataBuffer = (uint8_t*) memalign(RS_CPU_ALLOCATION_ALIGNMENT, size);
+#else
+    int size = paddedWidth * paddedHeight;
+    uint8_t* dataBuffer = (uint8_t*) malloc(size);
+#endif
+
     memset(dataBuffer, 0, size);
 
     int penX = radius - bounds.left;
@@ -611,13 +704,13 @@
 
 bool FontRenderer::renderTextOnPath(SkPaint* paint, const Rect* clip, const char *text,
         uint32_t startIndex, uint32_t len, int numGlyphs, SkPath* path,
-        float hOffset, float vOffset, Rect* bounds) {
+        float hOffset, float vOffset, Rect* bounds, Functor* functor) {
     if (!mCurrentFont) {
         ALOGE("No font set");
         return false;
     }
 
-    initRender(clip, bounds, NULL);
+    initRender(clip, bounds, functor);
     mCurrentFont->render(paint, text, startIndex, len, numGlyphs, path, hOffset, vOffset);
     finishRender();
 
@@ -633,49 +726,55 @@
 }
 
 void FontRenderer::blurImage(uint8_t** image, int32_t width, int32_t height, int32_t radius) {
-    if (width * height * radius < RS_MIN_INPUT_CUTOFF) {
-        float *gaussian = new float[2 * radius + 1];
-        Blur::generateGaussianWeights(gaussian, radius);
+#ifdef ANDROID_ENABLE_RENDERSCRIPT
+    if (width * height * radius >= RS_MIN_INPUT_CUTOFF) {
+        uint8_t* outImage = (uint8_t*) memalign(RS_CPU_ALLOCATION_ALIGNMENT, width * height);
 
-        uint8_t* scratch = new uint8_t[width * height];
-        Blur::horizontal(gaussian, radius, *image, scratch, width, height);
-        Blur::vertical(gaussian, radius, scratch, *image, width, height);
+        if (mRs == 0) {
+            mRs = new RSC::RS();
+            if (!mRs->init(RSC::RS_INIT_LOW_LATENCY | RSC::RS_INIT_SYNCHRONOUS)) {
+                ALOGE("blur RS failed to init");
+            }
 
-        delete[] gaussian;
-        delete[] scratch;
-        return;
-    }
-
-    uint8_t* outImage = (uint8_t*) memalign(RS_CPU_ALLOCATION_ALIGNMENT, width * height);
-
-    if (mRs.get() == 0) {
-        mRs = new RSC::RS();
-        if (!mRs->init(true, true)) {
-            ALOGE("blur RS failed to init");
+            mRsElement = RSC::Element::A_8(mRs);
+            mRsScript = RSC::ScriptIntrinsicBlur::create(mRs, mRsElement);
         }
 
-        mRsElement = RSC::Element::A_8(mRs);
-        mRsScript = new RSC::ScriptIntrinsicBlur(mRs, mRsElement);
+        RSC::sp<const RSC::Type> t = RSC::Type::create(mRs, mRsElement, width, height, 0);
+        RSC::sp<RSC::Allocation> ain = RSC::Allocation::createTyped(mRs, t,
+                RS_ALLOCATION_MIPMAP_NONE, RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_SHARED,
+                *image);
+        RSC::sp<RSC::Allocation> aout = RSC::Allocation::createTyped(mRs, t,
+                RS_ALLOCATION_MIPMAP_NONE, RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_SHARED,
+                outImage);
+
+        mRsScript->setRadius(radius);
+        mRsScript->setInput(ain);
+        mRsScript->forEach(aout);
+
+        // replace the original image's pointer, avoiding a copy back to the original buffer
+        free(*image);
+        *image = outImage;
+
+        return;
     }
+#endif
 
-    sp<const RSC::Type> t = RSC::Type::create(mRs, mRsElement, width, height, 0);
-    sp<RSC::Allocation> ain = RSC::Allocation::createTyped(mRs, t, RS_ALLOCATION_MIPMAP_NONE,
-            RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_SHARED, *image);
-    sp<RSC::Allocation> aout = RSC::Allocation::createTyped(mRs, t, RS_ALLOCATION_MIPMAP_NONE,
-            RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_SHARED, outImage);
+    float *gaussian = new float[2 * radius + 1];
+    Blur::generateGaussianWeights(gaussian, radius);
 
-    mRsScript->setRadius(radius);
-    mRsScript->blur(ain, aout);
+    uint8_t* scratch = new uint8_t[width * height];
+    Blur::horizontal(gaussian, radius, *image, scratch, width, height);
+    Blur::vertical(gaussian, radius, scratch, *image, width, height);
 
-    // replace the original image's pointer, avoiding a copy back to the original buffer
-    free(*image);
-    *image = outImage;
+    delete[] gaussian;
+    delete[] scratch;
 }
 
-uint32_t FontRenderer::getCacheSize() const {
+static uint32_t calculateCacheSize(const Vector<CacheTexture*>& cacheTextures) {
     uint32_t size = 0;
-    for (uint32_t i = 0; i < mCacheTextures.size(); i++) {
-        CacheTexture* cacheTexture = mCacheTextures[i];
+    for (uint32_t i = 0; i < cacheTextures.size(); i++) {
+        CacheTexture* cacheTexture = cacheTextures[i];
         if (cacheTexture && cacheTexture->getPixelBuffer()) {
             size += cacheTexture->getPixelBuffer()->getSize();
         }
@@ -683,5 +782,19 @@
     return size;
 }
 
+uint32_t FontRenderer::getCacheSize(GLenum format) const {
+    switch (format) {
+        case GL_ALPHA: {
+            return calculateCacheSize(mACacheTextures);
+        }
+        case GL_RGBA: {
+            return calculateCacheSize(mRGBACacheTextures);
+        }
+        default: {
+            return 0;
+        }
+    }
+}
+
 }; // namespace uirenderer
 }; // namespace android
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index 307a1d9..aa7e776 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -17,8 +17,10 @@
 #ifndef ANDROID_HWUI_FONT_RENDERER_H
 #define ANDROID_HWUI_FONT_RENDERER_H
 
+#include <utils/Functor.h>
 #include <utils/LruCache.h>
 #include <utils/Vector.h>
+#include <utils/StrongPointer.h>
 
 #include <SkPaint.h>
 
@@ -32,19 +34,55 @@
 #include "Matrix.h"
 #include "Properties.h"
 
+#ifdef ANDROID_ENABLE_RENDERSCRIPT
+#include "RenderScript.h"
 namespace RSC {
     class Element;
     class RS;
     class ScriptIntrinsicBlur;
+    class sp;
 }
+#endif
 
 class Functor;
 
 namespace android {
 namespace uirenderer {
 
+class OpenGLRenderer;
+
 ///////////////////////////////////////////////////////////////////////////////
-// Renderer
+// TextSetupFunctor
+///////////////////////////////////////////////////////////////////////////////
+class TextSetupFunctor: public Functor {
+public:
+    struct Data {
+        Data(GLenum glyphFormat) : glyphFormat(glyphFormat) {
+        }
+
+        GLenum glyphFormat;
+    };
+
+    TextSetupFunctor(OpenGLRenderer* renderer, float x, float y, bool pureTranslate,
+            int alpha, SkXfermode::Mode mode, SkPaint* paint): Functor(),
+            renderer(renderer), x(x), y(y), pureTranslate(pureTranslate),
+            alpha(alpha), mode(mode), paint(paint) {
+    }
+    ~TextSetupFunctor() { }
+
+    status_t operator ()(int what, void* data);
+
+    OpenGLRenderer* renderer;
+    float x;
+    float y;
+    bool pureTranslate;
+    int alpha;
+    SkXfermode::Mode mode;
+    SkPaint* paint;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// FontRenderer
 ///////////////////////////////////////////////////////////////////////////////
 
 class FontRenderer {
@@ -52,6 +90,7 @@
     FontRenderer();
     ~FontRenderer();
 
+    void flushLargeCaches(Vector<CacheTexture*>& cacheTextures);
     void flushLargeCaches();
 
     void setGammaTable(const uint8_t* gammaTable) {
@@ -70,7 +109,8 @@
 
     // bounds is an out parameter
     bool renderTextOnPath(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
-            uint32_t len, int numGlyphs, SkPath* path, float hOffset, float vOffset, Rect* bounds);
+            uint32_t len, int numGlyphs, SkPath* path, float hOffset, float vOffset, Rect* bounds,
+            Functor* functor);
 
     struct DropShadow {
         DropShadow() { };
@@ -97,30 +137,29 @@
         mLinearFiltering = linearFiltering;
     }
 
-    uint32_t getCacheSize() const;
+    uint32_t getCacheSize(GLenum format) const;
 
 private:
     friend class Font;
 
-    static const uint32_t gMaxNumberOfQuads = 2048;
-
     const uint8_t* mGammaTable;
 
     void allocateTextureMemory(CacheTexture* cacheTexture);
     void deallocateTextureMemory(CacheTexture* cacheTexture);
     void initTextTexture();
-    CacheTexture* createCacheTexture(int width, int height, bool allocate);
+    CacheTexture* createCacheTexture(int width, int height, GLenum format, bool allocate);
     void cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyph,
             uint32_t *retOriginX, uint32_t *retOriginY, bool precaching);
-    CacheTexture* cacheBitmapInTexture(const SkGlyph& glyph, uint32_t* startX, uint32_t* startY);
+    CacheTexture* cacheBitmapInTexture(Vector<CacheTexture*>& cacheTextures, const SkGlyph& glyph,
+            uint32_t* startX, uint32_t* startY);
 
     void flushAllAndInvalidate();
-    void initVertexArrayBuffers();
 
     void checkInit();
     void initRender(const Rect* clip, Rect* bounds, Functor* functor);
     void finishRender();
 
+    void issueDrawCommand(Vector<CacheTexture*>& cacheTextures);
     void issueDrawCommand();
     void appendMeshQuadNoClip(float x1, float y1, float u1, float v1,
             float x2, float y2, float u2, float v2,
@@ -148,7 +187,8 @@
     uint32_t mLargeCacheWidth;
     uint32_t mLargeCacheHeight;
 
-    Vector<CacheTexture*> mCacheTextures;
+    Vector<CacheTexture*> mACacheTextures;
+    Vector<CacheTexture*> mRGBACacheTextures;
 
     Font* mCurrentFont;
     LruCache<Font::FontDescription, Font*> mActiveFonts;
@@ -157,8 +197,6 @@
 
     bool mUploadTexture;
 
-    uint32_t mIndexBufferID;
-
     Functor* mFunctor;
     const Rect* mClip;
     Rect* mBounds;
@@ -168,10 +206,12 @@
 
     bool mLinearFiltering;
 
+#ifdef ANDROID_ENABLE_RENDERSCRIPT
     // RS constructs
-    sp<RSC::RS> mRs;
-    sp<const RSC::Element> mRsElement;
-    sp<RSC::ScriptIntrinsicBlur> mRsScript;
+    RSC::sp<RSC::RS> mRs;
+    RSC::sp<const RSC::Element> mRsElement;
+    RSC::sp<RSC::ScriptIntrinsicBlur> mRsScript;
+#endif
 
     static void computeGaussianWeights(float* weights, int32_t radius);
     static void horizontalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest,
diff --git a/libs/hwui/GammaFontRenderer.h b/libs/hwui/GammaFontRenderer.h
index bbfa66d..46cfd04 100644
--- a/libs/hwui/GammaFontRenderer.h
+++ b/libs/hwui/GammaFontRenderer.h
@@ -35,7 +35,7 @@
     virtual FontRenderer& getFontRenderer(const SkPaint* paint) = 0;
 
     virtual uint32_t getFontRendererCount() const = 0;
-    virtual uint32_t getFontRendererSize(uint32_t fontRenderer) const = 0;
+    virtual uint32_t getFontRendererSize(uint32_t fontRenderer, GLenum format) const = 0;
 
     virtual void describe(ProgramDescription& description, const SkPaint* paint) const = 0;
     virtual void setupProgram(ProgramDescription& description, Program* program) const = 0;
@@ -81,8 +81,8 @@
         return 1;
     }
 
-    uint32_t getFontRendererSize(uint32_t fontRenderer) const {
-        return mRenderer ? mRenderer->getCacheSize() : 0;
+    uint32_t getFontRendererSize(uint32_t fontRenderer, GLenum format) const {
+        return mRenderer ? mRenderer->getCacheSize(format) : 0;
     }
 
     void describe(ProgramDescription& description, const SkPaint* paint) const;
@@ -128,8 +128,8 @@
         return 1;
     }
 
-    uint32_t getFontRendererSize(uint32_t fontRenderer) const {
-        return mRenderer ? mRenderer->getCacheSize() : 0;
+    uint32_t getFontRendererSize(uint32_t fontRenderer, GLenum format) const {
+        return mRenderer ? mRenderer->getCacheSize(format) : 0;
     }
 
     void describe(ProgramDescription& description, const SkPaint* paint) const {
@@ -162,13 +162,13 @@
         return kGammaCount;
     }
 
-    uint32_t getFontRendererSize(uint32_t fontRenderer) const {
+    uint32_t getFontRendererSize(uint32_t fontRenderer, GLenum format) const {
         if (fontRenderer >= kGammaCount) return 0;
 
         FontRenderer* renderer = mRenderers[fontRenderer];
         if (!renderer) return 0;
 
-        return renderer->getCacheSize();
+        return renderer->getCacheSize(format);
     }
 
     void describe(ProgramDescription& description, const SkPaint* paint) const {
diff --git a/libs/hwui/GradientCache.cpp b/libs/hwui/GradientCache.cpp
index 507ed95..0916942 100644
--- a/libs/hwui/GradientCache.cpp
+++ b/libs/hwui/GradientCache.cpp
@@ -78,7 +78,7 @@
     mCache.setOnEntryRemovedListener(this);
 
     const Extensions& extensions = Extensions::getInstance();
-    mUseFloatTexture = extensions.getMajorGlVersion() >= 3;
+    mUseFloatTexture = extensions.hasFloatTextures();
     mHasNpot = extensions.hasNPot();
 }
 
@@ -120,7 +120,7 @@
         const uint32_t size = texture->width * texture->height * bytesPerPixel();
         mSize -= size;
 
-        glDeleteTextures(1, &texture->id);
+        texture->deleteTexture();
         delete texture;
     }
 }
@@ -173,7 +173,7 @@
     GradientInfo info;
     getGradientInfo(colors, count, info);
 
-    Texture* texture = new Texture;
+    Texture* texture = new Texture();
     texture->width = info.width;
     texture->height = 2;
     texture->blend = info.hasAlpha;
@@ -286,7 +286,7 @@
     memcpy(pixels + rowBytes, pixels, rowBytes);
 
     glGenTextures(1, &texture->id);
-    glBindTexture(GL_TEXTURE_2D, texture->id);
+    Caches::getInstance().bindTexture(texture->id);
     glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
 
     if (mUseFloatTexture) {
diff --git a/libs/hwui/Image.cpp b/libs/hwui/Image.cpp
new file mode 100644
index 0000000..edf3930
--- /dev/null
+++ b/libs/hwui/Image.cpp
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "OpenGLRenderer"
+
+#include <utils/Log.h>
+
+#include "Caches.h"
+#include "Image.h"
+
+namespace android {
+namespace uirenderer {
+
+Image::Image(sp<GraphicBuffer> buffer) {
+    // Create the EGLImage object that maps the GraphicBuffer
+    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    EGLClientBuffer clientBuffer = (EGLClientBuffer) buffer->getNativeBuffer();
+    EGLint attrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
+
+    mImage = eglCreateImageKHR(display, EGL_NO_CONTEXT,
+            EGL_NATIVE_BUFFER_ANDROID, clientBuffer, attrs);
+
+    if (mImage == EGL_NO_IMAGE_KHR) {
+        ALOGW("Error creating image (%#x)", eglGetError());
+        mTexture = 0;
+    } else {
+        // Create a 2D texture to sample from the EGLImage
+        glGenTextures(1, &mTexture);
+        Caches::getInstance().bindTexture(mTexture);
+        glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, mImage);
+
+        GLenum status = GL_NO_ERROR;
+        while ((status = glGetError()) != GL_NO_ERROR) {
+            ALOGW("Error creating image (%#x)", status);
+        }
+    }
+}
+
+Image::~Image() {
+    if (mImage != EGL_NO_IMAGE_KHR) {
+        eglDestroyImageKHR(eglGetDisplay(EGL_DEFAULT_DISPLAY), mImage);
+        mImage = EGL_NO_IMAGE_KHR;
+
+        Caches::getInstance().deleteTexture(mTexture);
+        mTexture = 0;
+    }
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/Image.h b/libs/hwui/Image.h
new file mode 100644
index 0000000..2514535
--- /dev/null
+++ b/libs/hwui/Image.h
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HWUI_IMAGE_H
+#define ANDROID_HWUI_IMAGE_H
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <ui/GraphicBuffer.h>
+
+namespace android {
+namespace uirenderer {
+
+/**
+ * A simple wrapper that creates an EGLImage and a texture for a GraphicBuffer.
+ */
+class Image {
+public:
+    /**
+     * Creates a new image from the specified graphic buffer. If the image
+     * cannot be created, getTexture() will return 0 and getImage() will
+     * return EGL_NO_IMAGE_KHR.
+     */
+    Image(sp<GraphicBuffer> buffer);
+    ~Image();
+
+    /**
+     * Returns the name of the GL texture that can be used to sample
+     * from this image.
+     */
+    GLuint getTexture() const {
+        return mTexture;
+    }
+
+    /**
+     * Returns the name of the EGL image represented by this object.
+     */
+    EGLImageKHR getImage() const {
+        return mImage;
+    }
+
+private:
+    GLuint mTexture;
+    EGLImageKHR mImage;
+}; // class Image
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_HWUI_IMAGE_H
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index 4adad05..bd371a3 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -28,9 +28,9 @@
 namespace android {
 namespace uirenderer {
 
-Layer::Layer(const uint32_t layerWidth, const uint32_t layerHeight) {
+Layer::Layer(const uint32_t layerWidth, const uint32_t layerHeight):
+        caches(Caches::getInstance()), texture(caches) {
     mesh = NULL;
-    meshIndices = NULL;
     meshElementCount = 0;
     cacheable = true;
     dirty = false;
@@ -47,16 +47,15 @@
     debugDrawUpdate = false;
     hasDrawnSinceUpdate = false;
     deferredList = NULL;
-    Caches::getInstance().resourceCache.incrementRefcount(this);
+    caches.resourceCache.incrementRefcount(this);
 }
 
 Layer::~Layer() {
-    if (colorFilter) Caches::getInstance().resourceCache.decrementRefcount(colorFilter);
+    if (colorFilter) caches.resourceCache.decrementRefcount(colorFilter);
     removeFbo();
     deleteTexture();
 
     delete[] mesh;
-    delete[] meshIndices;
     delete deferredList;
 }
 
@@ -76,7 +75,7 @@
         return true;
     }
 
-    const uint32_t maxTextureSize = Caches::getInstance().maxTextureSize;
+    const uint32_t maxTextureSize = caches.maxTextureSize;
     if (desiredWidth > maxTextureSize || desiredHeight > maxTextureSize) {
         ALOGW("Layer exceeds max. dimensions supported by the GPU (%dx%d, max=%dx%d)",
                 desiredWidth, desiredHeight, maxTextureSize, maxTextureSize);
@@ -89,7 +88,7 @@
     setSize(desiredWidth, desiredHeight);
 
     if (fbo) {
-        Caches::getInstance().activeTexture(0);
+        caches.activeTexture(0);
         bindTexture();
         allocateTexture();
 
@@ -120,14 +119,14 @@
         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
         if (fbo != previousFbo) glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
 
-        Caches::getInstance().renderBufferCache.put(stencil);
+        caches.renderBufferCache.put(stencil);
         stencil = NULL;
     }
 
     if (fbo) {
         if (flush) LayerRenderer::flushLayer(this);
         // If put fails the cache will delete the FBO
-        Caches::getInstance().fboCache.put(fbo);
+        caches.fboCache.put(fbo);
         fbo = 0;
     }
 }
@@ -138,21 +137,55 @@
 
 void Layer::setColorFilter(SkiaColorFilter* filter) {
     if (colorFilter) {
-        Caches::getInstance().resourceCache.decrementRefcount(colorFilter);
+        caches.resourceCache.decrementRefcount(colorFilter);
     }
     colorFilter = filter;
     if (colorFilter) {
-        Caches::getInstance().resourceCache.incrementRefcount(colorFilter);
+        caches.resourceCache.incrementRefcount(colorFilter);
+    }
+}
+
+void Layer::bindTexture() const {
+    if (texture.id) {
+        caches.bindTexture(renderTarget, texture.id);
+    }
+}
+
+void Layer::bindStencilRenderBuffer() const {
+    if (stencil) {
+        stencil->bind();
+    }
+}
+
+void Layer::generateTexture() {
+    if (!texture.id) {
+        glGenTextures(1, &texture.id);
+    }
+}
+
+void Layer::deleteTexture() {
+    if (texture.id) {
+        texture.deleteTexture();
+        texture.id = 0;
+    }
+}
+
+void Layer::clearTexture() {
+    texture.id = 0;
+}
+
+void Layer::allocateTexture() {
+#if DEBUG_LAYERS
+    ALOGD("  Allocate layer: %dx%d", getWidth(), getHeight());
+#endif
+    if (texture.id) {
+        glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+        glTexImage2D(renderTarget, 0, GL_RGBA, getWidth(), getHeight(), 0,
+                GL_RGBA, GL_UNSIGNED_BYTE, NULL);
     }
 }
 
 void Layer::defer() {
-    if (!deferredList) {
-        deferredList = new DeferredDisplayList;
-    }
-    DeferStateStruct deferredState(*deferredList, *renderer,
-            DisplayList::kReplayFlag_ClipChildren);
-
     const float width = layer.getWidth();
     const float height = layer.getHeight();
 
@@ -161,6 +194,14 @@
         dirtyRect.set(0, 0, width, height);
     }
 
+    if (deferredList) {
+        deferredList->reset(dirtyRect);
+    } else {
+        deferredList = new DeferredDisplayList(dirtyRect);
+    }
+    DeferStateStruct deferredState(*deferredList, *renderer,
+            DisplayList::kReplayFlag_ClipChildren);
+
     renderer->initViewport(width, height);
     renderer->setupFrameState(dirtyRect.left, dirtyRect.top,
             dirtyRect.right, dirtyRect.bottom, !isBlend());
@@ -170,8 +211,19 @@
     deferredUpdateScheduled = false;
 }
 
-void Layer::flush() {
+void Layer::cancelDefer() {
+    renderer = NULL;
+    displayList = NULL;
+    deferredUpdateScheduled = false;
     if (deferredList) {
+        delete deferredList;
+        deferredList = NULL;
+    }
+}
+
+void Layer::flush() {
+    // renderer is checked as layer may be destroyed/put in layer cache with flush scheduled
+    if (deferredList && renderer) {
         renderer->setViewport(layer.getWidth(), layer.getHeight());
         renderer->prepareDirty(dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom,
                 !isBlend());
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 7186603..b70042f 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -40,6 +40,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 // Forward declarations
+class Caches;
 class OpenGLRenderer;
 class DisplayList;
 class DeferredDisplayList;
@@ -221,50 +222,19 @@
 
     ANDROID_API void setColorFilter(SkiaColorFilter* filter);
 
-    inline void bindTexture() const {
-        if (texture.id) {
-            glBindTexture(renderTarget, texture.id);
-        }
-    }
+    void bindStencilRenderBuffer() const;
 
-    inline void bindStencilRenderBuffer() const {
-        if (stencil) {
-            stencil->bind();
-        }
-    }
-
-    inline void generateTexture() {
-        if (!texture.id) {
-            glGenTextures(1, &texture.id);
-        }
-    }
-
-    inline void deleteTexture() {
-        if (texture.id) {
-            glDeleteTextures(1, &texture.id);
-            texture.id = 0;
-        }
-    }
+    void bindTexture() const;
+    void generateTexture();
+    void allocateTexture();
+    void deleteTexture();
 
     /**
      * When the caller frees the texture itself, the caller
      * must call this method to tell this layer that it lost
      * the texture.
      */
-    void clearTexture() {
-        texture.id = 0;
-    }
-
-    inline void allocateTexture() {
-#if DEBUG_LAYERS
-        ALOGD("  Allocate layer: %dx%d", getWidth(), getHeight());
-#endif
-        if (texture.id) {
-            glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
-            glTexImage2D(renderTarget, 0, GL_RGBA, getWidth(), getHeight(), 0,
-                    GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-        }
-    }
+    ANDROID_API void clearTexture();
 
     inline mat4& getTexTransform() {
         return texTransform;
@@ -275,6 +245,7 @@
     }
 
     void defer();
+    void cancelDefer();
     void flush();
     void render();
 
@@ -306,7 +277,6 @@
      * If the layer can be rendered as a mesh, this is non-null.
      */
     TextureVertex* mesh;
-    uint16_t* meshIndices;
     GLsizei meshElementCount;
 
     /**
@@ -320,6 +290,8 @@
     bool hasDrawnSinceUpdate;
 
 private:
+    Caches& caches;
+
     /**
      * Name of the FBO used to render the layer. If the name is 0
      * this layer is not backed by an FBO, but a simple texture.
diff --git a/libs/hwui/LayerCache.cpp b/libs/hwui/LayerCache.cpp
index a0709af..6be0146 100644
--- a/libs/hwui/LayerCache.cpp
+++ b/libs/hwui/LayerCache.cpp
@@ -155,9 +155,7 @@
                     victim->layer.getHeight());
         }
 
-        layer->deferredUpdateScheduled = false;
-        layer->renderer = NULL;
-        layer->displayList = NULL;
+        layer->cancelDefer();
 
         LayerEntry entry(layer);
 
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index 3e55fff..f8076cc 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -130,10 +130,7 @@
     if (mLayer->region.isRect() || mLayer->region.isEmpty()) {
         if (mLayer->mesh) {
             delete[] mLayer->mesh;
-            delete[] mLayer->meshIndices;
-
             mLayer->mesh = NULL;
-            mLayer->meshIndices = NULL;
             mLayer->meshElementCount = 0;
         }
 
@@ -154,17 +151,11 @@
 
     if (mLayer->mesh && mLayer->meshElementCount < elementCount) {
         delete[] mLayer->mesh;
-        delete[] mLayer->meshIndices;
-
         mLayer->mesh = NULL;
-        mLayer->meshIndices = NULL;
     }
 
-    bool rebuildIndices = false;
     if (!mLayer->mesh) {
         mLayer->mesh = new TextureVertex[count * 4];
-        mLayer->meshIndices = new uint16_t[elementCount];
-        rebuildIndices = true;
     }
     mLayer->meshElementCount = elementCount;
 
@@ -173,7 +164,6 @@
     const float height = mLayer->layer.getHeight();
 
     TextureVertex* mesh = mLayer->mesh;
-    uint16_t* indices = mLayer->meshIndices;
 
     for (size_t i = 0; i < count; i++) {
         const android::Rect* r = &rects[i];
@@ -187,17 +177,6 @@
         TextureVertex::set(mesh++, r->right, r->top, u2, v1);
         TextureVertex::set(mesh++, r->left, r->bottom, u1, v2);
         TextureVertex::set(mesh++, r->right, r->bottom, u2, v2);
-
-        if (rebuildIndices) {
-            uint16_t quad = i * 4;
-            int index = i * 6;
-            indices[index    ] = quad;       // top-left
-            indices[index + 1] = quad + 1;   // top-right
-            indices[index + 2] = quad + 2;   // bottom-left
-            indices[index + 3] = quad + 2;   // bottom-left
-            indices[index + 4] = quad + 1;   // top-right
-            indices[index + 5] = quad + 3;   // bottom-right
-        }
     }
 }
 
@@ -436,7 +415,7 @@
         if ((error = glGetError()) != GL_NO_ERROR) goto error;
 
         caches.activeTexture(0);
-        glBindTexture(GL_TEXTURE_2D, texture);
+        caches.bindTexture(texture);
 
         glPixelStorei(GL_PACK_ALIGNMENT, bitmap->bytesPerPixel());
 
@@ -467,7 +446,7 @@
             mat4 texTransform(layer->getTexTransform());
 
             mat4 invert;
-            invert.translate(0.0f, 1.0f, 0.0f);
+            invert.translate(0.0f, 1.0f);
             invert.scale(1.0f, -1.0f, 1.0f);
             layer->getTexTransform().multiply(invert);
 
@@ -498,7 +477,7 @@
         glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
         layer->setAlpha(alpha, mode);
         layer->setFbo(previousLayerFbo);
-        glDeleteTextures(1, &texture);
+        caches.deleteTexture(texture);
         caches.fboCache.put(fbo);
         glViewport(previousViewport[0], previousViewport[1],
                 previousViewport[2], previousViewport[3]);
diff --git a/libs/hwui/Matrix.cpp b/libs/hwui/Matrix.cpp
index 6a5ea51..65e7eae 100644
--- a/libs/hwui/Matrix.cpp
+++ b/libs/hwui/Matrix.cpp
@@ -72,7 +72,7 @@
     return fabs(f) <= EPSILON;
 }
 
-uint32_t Matrix4::getType() const {
+uint8_t Matrix4::getType() const {
     if (mType & kTypeUnknown) {
         mType = kTypeIdentity;
 
@@ -114,7 +114,7 @@
     return mType;
 }
 
-uint32_t Matrix4::getGeometryType() const {
+uint8_t Matrix4::getGeometryType() const {
     return getType() & sGeometryMask;
 }
 
@@ -127,7 +127,7 @@
 }
 
 bool Matrix4::isPureTranslate() const {
-    return getGeometryType() == kTypeTranslate;
+    return getGeometryType() <= kTypeTranslate;
 }
 
 bool Matrix4::isSimple() const {
diff --git a/libs/hwui/Matrix.h b/libs/hwui/Matrix.h
index 75e280c..5116203 100644
--- a/libs/hwui/Matrix.h
+++ b/libs/hwui/Matrix.h
@@ -26,6 +26,12 @@
 namespace android {
 namespace uirenderer {
 
+#define MATRIX_STRING "[%.2f %.2f %.2f] [%.2f %.2f %.2f] [%.2f %.2f %.2f]"
+#define MATRIX_ARGS(m) \
+    (m)->get(0), (m)->get(1), (m)->get(2), \
+    (m)->get(3), (m)->get(4), (m)->get(5), \
+    (m)->get(6), (m)->get(7), (m)->get(8)
+
 ///////////////////////////////////////////////////////////////////////////////
 // Classes
 ///////////////////////////////////////////////////////////////////////////////
@@ -118,7 +124,7 @@
 
     void loadOrtho(float left, float right, float bottom, float top, float near, float far);
 
-    uint32_t getType() const;
+    uint8_t getType() const;
 
     void multiply(const Matrix4& v) {
         Matrix4 u;
@@ -128,10 +134,27 @@
 
     void multiply(float v);
 
-    void translate(float x, float y, float z) {
-        Matrix4 u;
-        u.loadTranslate(x, y, z);
-        multiply(u);
+    void translate(float x, float y) {
+        if ((getType() & sGeometryMask) <= kTypeTranslate) {
+            data[kTranslateX] += x;
+            data[kTranslateY] += y;
+        } else {
+            // Doing a translation will only affect the translate bit of the type
+            // Save the type
+            uint8_t type = mType;
+
+            Matrix4 u;
+            u.loadTranslate(x, y, 0.0f);
+            multiply(u);
+
+            // Restore the type and fix the translate bit
+            mType = type;
+            if (data[kTranslateX] != 0.0f || data[kTranslateY] != 0.0f) {
+                mType |= kTypeTranslate;
+            } else {
+                mType &= ~kTypeTranslate;
+            }
+        }
     }
 
     void scale(float sx, float sy, float sz) {
@@ -179,7 +202,7 @@
     static const Matrix4& identity();
 
 private:
-    mutable uint32_t mType;
+    mutable uint8_t mType;
 
     inline float get(int i, int j) const {
         return data[i * 4 + j];
@@ -189,7 +212,7 @@
         data[i * 4 + j] = v;
     }
 
-    uint32_t getGeometryType() const;
+    uint8_t getGeometryType() const;
 
 }; // class Matrix4
 
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 7735819..2066f69 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -21,7 +21,6 @@
 #include <sys/types.h>
 
 #include <SkCanvas.h>
-#include <SkPathMeasure.h>
 #include <SkTypeface.h>
 
 #include <utils/Log.h>
@@ -34,6 +33,7 @@
 #include "OpenGLRenderer.h"
 #include "DeferredDisplayList.h"
 #include "DisplayListRenderer.h"
+#include "Fence.h"
 #include "PathTessellator.h"
 #include "Properties.h"
 #include "Vector.h"
@@ -107,6 +107,15 @@
 };
 
 ///////////////////////////////////////////////////////////////////////////////
+// Functions
+///////////////////////////////////////////////////////////////////////////////
+
+template<typename T>
+static inline T min(T a, T b) {
+    return a < b ? a : b;
+}
+
+///////////////////////////////////////////////////////////////////////////////
 // Constructors/destructor
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -120,6 +129,7 @@
 
     mFirstSnapshot = new Snapshot;
     mFrameStarted = false;
+    mCountOverdraw = false;
 
     mScissorOptimizationDisabled = false;
 }
@@ -222,6 +232,7 @@
 
 status_t OpenGLRenderer::prepareDirty(float left, float top,
         float right, float bottom, bool opaque) {
+
     setupFrameState(left, top, right, bottom, opaque);
 
     // Layer renderers will start the frame immediately
@@ -253,7 +264,7 @@
 }
 
 status_t OpenGLRenderer::clear(float left, float top, float right, float bottom, bool opaque) {
-    if (!opaque) {
+    if (!opaque || mCountOverdraw) {
         mCaches.enableScissor();
         mCaches.setScissor(left, mSnapshot->height - bottom, right - left, bottom - top);
         glClear(GL_COLOR_BUFFER_BIT);
@@ -335,6 +346,10 @@
 #endif
     }
 
+    if (mCountOverdraw) {
+        countOverdraw();
+    }
+
     mFrameStarted = false;
 }
 
@@ -345,6 +360,7 @@
             mCaches.currentProgram = NULL;
         }
     }
+    mCaches.resetActiveTexture();
     mCaches.unbindMeshBuffer();
     mCaches.unbindIndicesBuffer();
     mCaches.resetVertexPointers();
@@ -366,6 +382,7 @@
     dirtyClip();
 
     mCaches.activeTexture(0);
+    mCaches.resetBoundTextures();
 
     mCaches.blend = true;
     glEnable(GL_BLEND);
@@ -432,13 +449,8 @@
 status_t OpenGLRenderer::callDrawGLFunction(Functor* functor, Rect& dirty) {
     if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone;
 
-    interrupt();
     detachFunctor(functor);
 
-    mCaches.enableScissor();
-    if (mDirtyClip) {
-        setScissorFromClip();
-    }
 
     Rect clip(*mSnapshot->clipRect);
     clip.snapToPixelBoundaries();
@@ -459,7 +471,18 @@
     info.height = getSnapshot()->height;
     getSnapshot()->transform->copyTo(&info.transform[0]);
 
-    status_t result = (*functor)(DrawGlInfo::kModeDraw, &info) | DrawGlInfo::kStatusDrew;
+    bool dirtyClip = mDirtyClip;
+    // setup GL state for functor
+    if (mDirtyClip) {
+        setStencilFromClip(); // can issue draws, so must precede enableScissor()/interrupt()
+    }
+    if (mCaches.enableScissor() || dirtyClip) {
+        setScissorFromClip();
+    }
+    interrupt();
+
+    // call functor immediately after GL state setup
+    status_t result = (*functor)(DrawGlInfo::kModeDraw, &info);
 
     if (result != DrawGlInfo::kStatusDone) {
         Rect localDirty(info.dirtyLeft, info.dirtyTop, info.dirtyRight, info.dirtyBottom);
@@ -471,7 +494,7 @@
     }
 
     resume();
-    return result;
+    return result | DrawGlInfo::kStatusDrew;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -512,18 +535,41 @@
         mCaches.setScissor(clip->left, mFirstSnapshot->height - clip->bottom,
                 clip->right - clip->left, clip->bottom - clip->top);
 
+        // 1x overdraw
         mCaches.stencil.enableDebugTest(2);
-        drawColor(0x2f0000ff, SkXfermode::kSrcOver_Mode);
+        drawColor(mCaches.getOverdrawColor(1), SkXfermode::kSrcOver_Mode);
+
+        // 2x overdraw
         mCaches.stencil.enableDebugTest(3);
-        drawColor(0x2f00ff00, SkXfermode::kSrcOver_Mode);
+        drawColor(mCaches.getOverdrawColor(2), SkXfermode::kSrcOver_Mode);
+
+        // 3x overdraw
         mCaches.stencil.enableDebugTest(4);
-        drawColor(0x3fff0000, SkXfermode::kSrcOver_Mode);
+        drawColor(mCaches.getOverdrawColor(3), SkXfermode::kSrcOver_Mode);
+
+        // 4x overdraw and higher
         mCaches.stencil.enableDebugTest(4, true);
-        drawColor(0x7fff0000, SkXfermode::kSrcOver_Mode);
+        drawColor(mCaches.getOverdrawColor(4), SkXfermode::kSrcOver_Mode);
+
         mCaches.stencil.disable();
     }
 }
 
+void OpenGLRenderer::countOverdraw() {
+    size_t count = mWidth * mHeight;
+    uint32_t* buffer = new uint32_t[count];
+    glReadPixels(0, 0, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, &buffer[0]);
+
+    size_t total = 0;
+    for (size_t i = 0; i < count; i++) {
+        total += buffer[i] & 0xff;
+    }
+
+    mOverdraw = total / float(count);
+
+    delete[] buffer;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 // Layers
 ///////////////////////////////////////////////////////////////////////////////
@@ -531,6 +577,8 @@
 bool OpenGLRenderer::updateLayer(Layer* layer, bool inFrame) {
     if (layer->deferredUpdateScheduled && layer->renderer &&
             layer->displayList && layer->displayList->isRenderable()) {
+        ATRACE_CALL();
+
         Rect& dirty = layer->dirtyRect;
 
         if (inFrame) {
@@ -598,8 +646,11 @@
             sprintf(layerName, "Layer #%d", i);
             startMark(layerName);
 
+            ATRACE_BEGIN("flushLayer");
             Layer* layer = mLayerUpdates.itemAt(i);
             layer->flush();
+            ATRACE_END();
+
             mCaches.resourceCache.decrementRefcount(layer);
 
             endMark();
@@ -628,6 +679,18 @@
     }
 }
 
+void OpenGLRenderer::cancelLayerUpdate(Layer* layer) {
+    if (layer) {
+        for (int i = mLayerUpdates.size() - 1; i >= 0; i--) {
+            if (mLayerUpdates.itemAt(i) == layer) {
+                mLayerUpdates.removeAt(i);
+                mCaches.resourceCache.decrementRefcount(layer);
+                break;
+            }
+        }
+    }
+}
+
 void OpenGLRenderer::clearLayerUpdates() {
     size_t count = mLayerUpdates.size();
     if (count > 0) {
@@ -640,6 +703,14 @@
     }
 }
 
+void OpenGLRenderer::flushLayerUpdates() {
+    syncState();
+    updateLayers();
+    flushLayers();
+    // Wait for all the layer updates to be executed
+    AutoFence fence;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 // State management
 ///////////////////////////////////////////////////////////////////////////////
@@ -780,6 +851,7 @@
         if (!mSnapshot->isIgnored()) {
             mSnapshot->resetTransform(-bounds.left, -bounds.top, 0.0f);
             mSnapshot->resetClip(clip.left, clip.top, clip.right, clip.bottom);
+            mSnapshot->viewport.set(0.0f, 0.0f, bounds.getWidth(), bounds.getHeight());
         }
     }
 
@@ -961,6 +1033,10 @@
     const Rect& rect = layer->layer;
     const bool fboLayer = current->flags & Snapshot::kFlagIsFboLayer;
 
+    bool clipRequired = false;
+    quickRejectNoScissor(rect, &clipRequired); // safely ignore return, should never be rejected
+    mCaches.setScissorEnabled(mScissorOptimizationDisabled || clipRequired);
+
     if (fboLayer) {
         endTiling();
 
@@ -1013,7 +1089,7 @@
 }
 
 void OpenGLRenderer::drawTextureLayer(Layer* layer, const Rect& rect) {
-    float alpha = layer->getAlpha() / 255.0f * mSnapshot->alpha;
+    float alpha = getLayerAlpha(layer);
 
     setupDraw();
     if (layer->getRenderTarget() == GL_TEXTURE_2D) {
@@ -1049,8 +1125,6 @@
     setupDrawMesh(&mMeshVertices[0].position[0], &mMeshVertices[0].texture[0]);
 
     glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
-
-    finishDrawTexture();
 }
 
 void OpenGLRenderer::composeLayerRect(Layer* layer, const Rect& rect, bool swap) {
@@ -1119,8 +1193,6 @@
         return;
     }
 
-    // TODO: See LayerRenderer.cpp::generateMesh() for important
-    //       information about this implementation
     if (CC_LIKELY(!layer->region.isEmpty())) {
         size_t count;
         const android::Rect* rects;
@@ -1143,7 +1215,7 @@
         // after we setup drawing in case we need to mess with the
         // stencil buffer in setupDraw()
         TextureVertex* mesh = mCaches.getRegionMesh();
-        GLsizei numQuads = 0;
+        uint32_t numQuads = 0;
 
         setupDrawWithTexture();
         setupDrawColor(alpha, alpha, alpha, alpha);
@@ -1182,7 +1254,7 @@
 
             numQuads++;
 
-            if (numQuads >= REGION_MESH_QUAD_COUNT) {
+            if (numQuads >= gMaxNumberOfQuads) {
                 DRAW_DOUBLE_STENCIL(glDrawElements(GL_TRIANGLES, numQuads * 6,
                                 GL_UNSIGNED_SHORT, NULL));
                 numQuads = 0;
@@ -1195,8 +1267,6 @@
                             GL_UNSIGNED_SHORT, NULL));
         }
 
-        finishDrawTexture();
-
 #if DEBUG_LAYERS_AS_REGIONS
         drawRegionRects(layer->region);
 #endif
@@ -1233,7 +1303,6 @@
 
 void OpenGLRenderer::drawRegionRects(const SkRegion& region, int color,
         SkXfermode::Mode mode, bool dirty) {
-    int count = 0;
     Vector<float> rects;
 
     SkRegion::Iterator it(region);
@@ -1243,11 +1312,10 @@
         rects.push(r.fTop);
         rects.push(r.fRight);
         rects.push(r.fBottom);
-        count += 4;
         it.next();
     }
 
-    drawColorRects(rects.array(), count, color, mode, true, dirty, false);
+    drawColorRects(rects.array(), rects.size(), color, mode, true, dirty, false);
 }
 
 void OpenGLRenderer::dirtyLayer(const float left, const float top,
@@ -1277,6 +1345,21 @@
     }
 }
 
+void OpenGLRenderer::drawIndexedQuads(Vertex* mesh, GLsizei quadsCount) {
+    GLsizei elementsCount = quadsCount * 6;
+    while (elementsCount > 0) {
+        GLsizei drawCount = min(elementsCount, (GLsizei) gMaxNumberOfQuads * 6);
+
+        setupDrawIndexedVertices(&mesh[0].position[0]);
+        glDrawElements(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, NULL);
+
+        elementsCount -= drawCount;
+        // Though there are 4 vertices in a quad, we use 6 indices per
+        // quad to draw with GL_TRIANGLES
+        mesh += (drawCount / 6) * 4;
+    }
+}
+
 void OpenGLRenderer::clearLayerRegions() {
     const size_t count = mLayers.size();
     if (count == 0) return;
@@ -1291,17 +1374,15 @@
         // is likely different so we need to disable clipping here
         bool scissorChanged = mCaches.disableScissor();
 
-        Vertex mesh[count * 6];
+        Vertex mesh[count * 4];
         Vertex* vertex = mesh;
 
         for (uint32_t i = 0; i < count; i++) {
             Rect* bounds = mLayers.itemAt(i);
 
-            Vertex::set(vertex++, bounds->left, bounds->bottom);
             Vertex::set(vertex++, bounds->left, bounds->top);
             Vertex::set(vertex++, bounds->right, bounds->top);
             Vertex::set(vertex++, bounds->left, bounds->bottom);
-            Vertex::set(vertex++, bounds->right, bounds->top);
             Vertex::set(vertex++, bounds->right, bounds->bottom);
 
             delete bounds;
@@ -1317,9 +1398,8 @@
         setupDrawProgram();
         setupDrawPureColorUniforms();
         setupDrawModelViewTranslate(0.0f, 0.0f, 0.0f, 0.0f, true);
-        setupDrawVertices(&mesh[0].position[0]);
 
-        glDrawArrays(GL_TRIANGLES, 0, count * 6);
+        drawIndexedQuads(&mesh[0], count);
 
         if (scissorChanged) mCaches.enableScissor();
     } else {
@@ -1342,11 +1422,30 @@
         // state has bounds initialized in local coordinates
         if (!state.mBounds.isEmpty()) {
             currentMatrix.mapRect(state.mBounds);
-            if (!state.mBounds.intersect(currentClip)) {
+            Rect clippedBounds(state.mBounds);
+            // NOTE: if we ever want to use this clipping info to drive whether the scissor
+            // is used, it should more closely duplicate the quickReject logic (in how it uses
+            // snapToPixelBoundaries)
+
+            if(!clippedBounds.intersect(currentClip)) {
                 // quick rejected
                 return true;
             }
+
+            state.mClipSideFlags = kClipSide_None;
+            if (!currentClip.contains(state.mBounds)) {
+                int& flags = state.mClipSideFlags;
+                // op partially clipped, so record which sides are clipped for clip-aware merging
+                if (currentClip.left > state.mBounds.left) flags |= kClipSide_Left;
+                if (currentClip.top > state.mBounds.top) flags |= kClipSide_Top;
+                if (currentClip.right < state.mBounds.right) flags |= kClipSide_Right;
+                if (currentClip.bottom < state.mBounds.bottom) flags |= kClipSide_Bottom;
+            }
+            state.mBounds.set(clippedBounds);
         } else {
+            // Empty bounds implies size unknown. Label op as conservatively clipped to disable
+            // overdraw avoidance (since we don't know what it overlaps)
+            state.mClipSideFlags = kClipSide_ConservativeFull;
             state.mBounds.set(currentClip);
         }
     }
@@ -1370,14 +1469,27 @@
     mSnapshot->alpha = state.mAlpha;
 
     if (state.mClipValid && !skipClipRestore) {
-        mSnapshot->setClip(state.mClip.left, state.mClip.top, state.mClip.right, state.mClip.bottom);
+        mSnapshot->setClip(state.mClip.left, state.mClip.top,
+                state.mClip.right, state.mClip.bottom);
         dirtyClip();
     }
 }
 
-void OpenGLRenderer::setFullScreenClip() {
-    mSnapshot->setClip(0, 0, mWidth, mHeight);
+/**
+ * Merged multidraw (such as in drawText and drawBitmaps rely on the fact that no clipping is done
+ * in the draw path. Instead, clipping is done ahead of time - either as a single clip rect (when at
+ * least one op is clipped), or disabled entirely (because no merged op is clipped)
+ *
+ * This method should be called when restoreDisplayState() won't be restoring the clip
+ */
+void OpenGLRenderer::setupMergedMultiDraw(const Rect* clipRect) {
+    if (clipRect != NULL) {
+        mSnapshot->setClip(clipRect->left, clipRect->top, clipRect->right, clipRect->bottom);
+    } else {
+        mSnapshot->setClip(0, 0, mWidth, mHeight);
+    }
     dirtyClip();
+    mCaches.setScissorEnabled(clipRect != NULL || mScissorOptimizationDisabled);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1385,7 +1497,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 void OpenGLRenderer::translate(float dx, float dy) {
-    currentTransform().translate(dx, dy, 0.0f);
+    currentTransform().translate(dx, dy);
 }
 
 void OpenGLRenderer::rotate(float degrees) {
@@ -1508,65 +1620,56 @@
     return mSnapshot->getLocalClip();
 }
 
-bool OpenGLRenderer::quickRejectNoScissor(float left, float top, float right, float bottom) {
-    if (mSnapshot->isIgnored()) {
-        return true;
-    }
-
-    Rect r(left, top, right, bottom);
-    currentTransform().mapRect(r);
-    r.snapToPixelBoundaries();
-
-    Rect clipRect(*mSnapshot->clipRect);
-    clipRect.snapToPixelBoundaries();
-
-    return !clipRect.intersects(r);
-}
-
 bool OpenGLRenderer::quickRejectNoScissor(float left, float top, float right, float bottom,
-        Rect& transformed, Rect& clip) {
-    if (mSnapshot->isIgnored()) {
-        return true;
-    }
-
-    transformed.set(left, top, right, bottom);
-    currentTransform().mapRect(transformed);
-    transformed.snapToPixelBoundaries();
-
-    clip.set(*mSnapshot->clipRect);
-    clip.snapToPixelBoundaries();
-
-    return !clip.intersects(transformed);
-}
-
-bool OpenGLRenderer::quickRejectPreStroke(float left, float top, float right, float bottom,
-        SkPaint* paint) {
-    if (paint->getStyle() != SkPaint::kFill_Style) {
-        float outset = paint->getStrokeWidth() * 0.5f;
-        return quickReject(left - outset, top - outset, right + outset, bottom + outset);
-    } else {
-        return quickReject(left, top, right, bottom);
-    }
-}
-
-bool OpenGLRenderer::quickReject(float left, float top, float right, float bottom) {
+        bool snapOut, bool* clipRequired) {
     if (mSnapshot->isIgnored() || bottom <= top || right <= left) {
         return true;
     }
 
     Rect r(left, top, right, bottom);
     currentTransform().mapRect(r);
-    r.snapToPixelBoundaries();
+
+    if (snapOut) {
+        // snapOut is generally used to account for 1 pixel ramp (in window coordinates)
+        // outside of the provided rect boundaries in tessellated AA geometry
+        r.snapOutToPixelBoundaries();
+    } else {
+        r.snapToPixelBoundaries();
+    }
 
     Rect clipRect(*mSnapshot->clipRect);
     clipRect.snapToPixelBoundaries();
 
-    bool rejected = !clipRect.intersects(r);
-    if (!isDeferred() && !rejected) {
-        mCaches.setScissorEnabled(mScissorOptimizationDisabled || !clipRect.contains(r));
+    if (!clipRect.intersects(r)) return true;
+
+    if (clipRequired) *clipRequired = !clipRect.contains(r);
+    return false;
+}
+
+bool OpenGLRenderer::quickRejectPreStroke(float left, float top, float right, float bottom,
+        SkPaint* paint) {
+    // AA geometry will likely have a ramp around it (not accounted for in local bounds). Snap out
+    // the final mapped rect to ensure correct clipping behavior for the ramp.
+    bool snapOut = paint->isAntiAlias();
+
+    if (paint->getStyle() != SkPaint::kFill_Style) {
+        float outset = paint->getStrokeWidth() * 0.5f;
+        return quickReject(left - outset, top - outset, right + outset, bottom + outset, snapOut);
+    } else {
+        return quickReject(left, top, right, bottom, snapOut);
+    }
+}
+
+bool OpenGLRenderer::quickReject(float left, float top, float right, float bottom, bool snapOut) {
+    bool clipRequired = false;
+    if (quickRejectNoScissor(left, top, right, bottom, snapOut, &clipRequired)) {
+        return true;
     }
 
-    return rejected;
+    if (!isDeferred()) {
+        mCaches.setScissorEnabled(mScissorOptimizationDisabled || clipRequired);
+    }
+    return false;
 }
 
 void OpenGLRenderer::debugClip() {
@@ -1589,7 +1692,7 @@
     SkPath path;
     path.addRect(left, top, right, bottom);
 
-    return clipPath(&path, op);
+    return OpenGLRenderer::clipPath(&path, op);
 }
 
 bool OpenGLRenderer::clipPath(SkPath* path, SkRegion::Op op) {
@@ -1600,11 +1703,15 @@
     path->transform(transform, &transformed);
 
     SkRegion clip;
-    if (!mSnapshot->clipRegion->isEmpty()) {
-        clip.setRegion(*mSnapshot->clipRegion);
+    if (!mSnapshot->previous->clipRegion->isEmpty()) {
+        clip.setRegion(*mSnapshot->previous->clipRegion);
     } else {
-        Rect* bounds = mSnapshot->clipRect;
-        clip.setRect(bounds->left, bounds->top, bounds->right, bounds->bottom);
+        if (mSnapshot->previous == mFirstSnapshot) {
+            clip.setRect(0, 0, mWidth, mHeight);
+        } else {
+            Rect* bounds = mSnapshot->previous->clipRect;
+            clip.setRect(bounds->left, bounds->top, bounds->right, bounds->bottom);
+        }
     }
 
     SkRegion region;
@@ -1659,6 +1766,8 @@
     mDescription.hasDebugHighlight = !mCaches.debugOverdraw &&
             mCaches.debugStencilClip == Caches::kStencilShowHighlight &&
             mCaches.stencil.isTestEnabled();
+
+    mDescription.emulateStencil = mCountOverdraw;
 }
 
 void OpenGLRenderer::setupDrawWithTexture(bool isAlpha8) {
@@ -1684,11 +1793,6 @@
     mDescription.isAA = true;
 }
 
-void OpenGLRenderer::setupDrawPoint(float pointSize) {
-    mDescription.isPoint = true;
-    mDescription.pointSize = pointSize;
-}
-
 void OpenGLRenderer::setupDrawColor(int color, int alpha) {
     mColorA = alpha / 255.0f;
     mColorR = mColorA * ((color >> 16) & 0xFF) / 255.0f;
@@ -1803,11 +1907,6 @@
     }
 }
 
-void OpenGLRenderer::setupDrawPointUniforms() {
-    int slot = mCaches.currentProgram->getUniform("pointSize");
-    glUniform1f(slot, mDescription.pointSize);
-}
-
 void OpenGLRenderer::setupDrawColorUniforms() {
     if ((mColorSet && !mDrawModifiers.mShader) || (mDrawModifiers.mShader && mSetShaderColor)) {
         mCaches.currentProgram->setColor(mColorR, mColorG, mColorB, mColorA);
@@ -1876,7 +1975,7 @@
 
 void OpenGLRenderer::setupDrawMesh(GLvoid* vertices, GLvoid* texCoords, GLuint vbo) {
     bool force = false;
-    if (!vertices) {
+    if (!vertices || vbo) {
         force = mCaches.bindMeshBuffer(vbo == 0 ? mCaches.meshBuffer : vbo);
     } else {
         force = mCaches.unbindMeshBuffer();
@@ -1907,21 +2006,28 @@
     mCaches.unbindIndicesBuffer();
 }
 
-void OpenGLRenderer::setupDrawMeshIndices(GLvoid* vertices, GLvoid* texCoords) {
-    bool force = mCaches.unbindMeshBuffer();
+void OpenGLRenderer::setupDrawMeshIndices(GLvoid* vertices, GLvoid* texCoords, GLuint vbo) {
+    bool force = false;
+    // If vbo is != 0 we want to treat the vertices parameter as an offset inside
+    // a VBO. However, if vertices is set to NULL and vbo == 0 then we want to
+    // use the default VBO found in Caches
+    if (!vertices || vbo) {
+        force = mCaches.bindMeshBuffer(vbo == 0 ? mCaches.meshBuffer : vbo);
+    } else {
+        force = mCaches.unbindMeshBuffer();
+    }
+    mCaches.bindIndicesBuffer();
+
     mCaches.bindPositionVertexPointer(force, vertices);
     if (mCaches.currentProgram->texCoords >= 0) {
         mCaches.bindTexCoordsVertexPointer(force, texCoords);
     }
 }
 
-void OpenGLRenderer::setupDrawVertices(GLvoid* vertices) {
+void OpenGLRenderer::setupDrawIndexedVertices(GLvoid* vertices) {
     bool force = mCaches.unbindMeshBuffer();
+    mCaches.bindIndicesBuffer();
     mCaches.bindPositionVertexPointer(force, vertices, gVertexStride);
-    mCaches.unbindIndicesBuffer();
-}
-
-void OpenGLRenderer::finishDrawTexture() {
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1941,7 +2047,8 @@
             return status | replayStruct.mDrawGlStatus;
         }
 
-        DeferredDisplayList deferredList;
+        bool avoidOverdraw = !mCaches.debugOverdraw && !mCountOverdraw; // shh, don't tell devs!
+        DeferredDisplayList deferredList(*(mSnapshot->clipRect), avoidOverdraw);
         DeferStateStruct deferStruct(deferredList, *this, replayFlags);
         displayList->defer(deferStruct, 0);
 
@@ -1983,20 +2090,24 @@
         texture->setFilter(FILTER(paint), true);
     }
 
+    // No need to check for a UV mapper on the texture object, only ARGB_8888
+    // bitmaps get packed in the atlas
     drawAlpha8TextureMesh(x, y, x + texture->width, y + texture->height, texture->id,
-            paint != NULL, color, alpha, mode, (GLvoid*) NULL,
-            (GLvoid*) gMeshTextureOffset, GL_TRIANGLE_STRIP, gMeshCount, ignoreTransform);
+            paint != NULL, color, alpha, mode, (GLvoid*) NULL, (GLvoid*) gMeshTextureOffset,
+            GL_TRIANGLE_STRIP, gMeshCount, ignoreTransform);
 }
 
-status_t OpenGLRenderer::drawBitmaps(SkBitmap* bitmap, int bitmapCount, TextureVertex* vertices,
-        const Rect& bounds, SkPaint* paint) {
-
-    // merged draw operations don't need scissor, but clip should still be valid
-    mCaches.setScissorEnabled(mScissorOptimizationDisabled);
-
+/**
+ * Important note: this method is intended to draw batches of bitmaps and
+ * will not set the scissor enable or dirty the current layer, if any.
+ * The caller is responsible for properly dirtying the current layer.
+ */
+status_t OpenGLRenderer::drawBitmaps(SkBitmap* bitmap, AssetAtlas::Entry* entry, int bitmapCount,
+        TextureVertex* vertices, bool transformed, const Rect& bounds, SkPaint* paint) {
     mCaches.activeTexture(0);
-    Texture* texture = mCaches.textureCache.get(bitmap);
+    Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap);
     if (!texture) return DrawGlInfo::kStatusDone;
+
     const AutoTexture autoCleanup(texture);
 
     int alpha;
@@ -2004,7 +2115,7 @@
     getAlphaAndMode(paint, &alpha, &mode);
 
     texture->setWrap(GL_CLAMP_TO_EDGE, true);
-    texture->setFilter(GL_NEAREST, true); // merged ops are always pure-translation for now
+    texture->setFilter(transformed ? FILTER(paint) : GL_NEAREST, true);
 
     const float x = (int) floorf(bounds.left + 0.5f);
     const float y = (int) floorf(bounds.top + 0.5f);
@@ -2013,12 +2124,12 @@
         drawAlpha8TextureMesh(x, y, x + bounds.getWidth(), y + bounds.getHeight(),
                 texture->id, paint != NULL, color, alpha, mode,
                 &vertices[0].position[0], &vertices[0].texture[0],
-                GL_TRIANGLES, bitmapCount * 6, true, true);
+                GL_TRIANGLES, bitmapCount * 6, true, true, false);
     } else {
         drawTextureMesh(x, y, x + bounds.getWidth(), y + bounds.getHeight(),
                 texture->id, alpha / 255.0f, mode, texture->blend,
                 &vertices[0].position[0], &vertices[0].texture[0],
-                GL_TRIANGLES, bitmapCount * 6, false, true, 0, true);
+                GL_TRIANGLES, bitmapCount * 6, false, true, 0, true, false);
     }
 
     return DrawGlInfo::kStatusDrew;
@@ -2033,7 +2144,7 @@
     }
 
     mCaches.activeTexture(0);
-    Texture* texture = mCaches.textureCache.get(bitmap);
+    Texture* texture = getTexture(bitmap);
     if (!texture) return DrawGlInfo::kStatusDone;
     const AutoTexture autoCleanup(texture);
 
@@ -2056,7 +2167,7 @@
     }
 
     mCaches.activeTexture(0);
-    Texture* texture = mCaches.textureCache.get(bitmap);
+    Texture* texture = getTexture(bitmap);
     if (!texture) return DrawGlInfo::kStatusDone;
     const AutoTexture autoCleanup(texture);
 
@@ -2101,6 +2212,9 @@
         return DrawGlInfo::kStatusDone;
     }
 
+    // TODO: use quickReject on bounds from vertices
+    mCaches.enableScissor();
+
     float left = FLT_MAX;
     float top = FLT_MAX;
     float right = FLT_MIN;
@@ -2119,6 +2233,10 @@
         cleanupColors = true;
     }
 
+    mCaches.activeTexture(0);
+    Texture* texture = mCaches.assetAtlas.getEntryTexture(bitmap);
+    const UvMapper& mapper(getMapper(texture));
+
     for (int32_t y = 0; y < meshHeight; y++) {
         for (int32_t x = 0; x < meshWidth; x++) {
             uint32_t i = (y * (meshWidth + 1) + x) * 2;
@@ -2128,6 +2246,8 @@
             float v1 = float(y) / meshHeight;
             float v2 = float(y + 1) / meshHeight;
 
+            mapper.map(u1, v1, u2, v2);
+
             int ax = i + (meshWidth + 1) * 2;
             int ay = ax + 1;
             int bx = i;
@@ -2157,11 +2277,12 @@
         return DrawGlInfo::kStatusDone;
     }
 
-    mCaches.activeTexture(0);
-    Texture* texture = mCaches.textureCache.get(bitmap);
     if (!texture) {
-        if (cleanupColors) delete[] colors;
-        return DrawGlInfo::kStatusDone;
+        texture = mCaches.textureCache.get(bitmap);
+        if (!texture) {
+            if (cleanupColors) delete[] colors;
+            return DrawGlInfo::kStatusDone;
+        }
     }
     const AutoTexture autoCleanup(texture);
 
@@ -2193,8 +2314,6 @@
 
     glDrawArrays(GL_TRIANGLES, 0, count);
 
-    finishDrawTexture();
-
     int slot = mCaches.currentProgram->getAttrib("colors");
     if (slot >= 0) {
         glDisableVertexAttribArray(slot);
@@ -2214,17 +2333,19 @@
     }
 
     mCaches.activeTexture(0);
-    Texture* texture = mCaches.textureCache.get(bitmap);
+    Texture* texture = getTexture(bitmap);
     if (!texture) return DrawGlInfo::kStatusDone;
     const AutoTexture autoCleanup(texture);
 
     const float width = texture->width;
     const float height = texture->height;
 
-    const float u1 = fmax(0.0f, srcLeft / width);
-    const float v1 = fmax(0.0f, srcTop / height);
-    const float u2 = fmin(1.0f, srcRight / width);
-    const float v2 = fmin(1.0f, srcBottom / height);
+    float u1 = fmax(0.0f, srcLeft / width);
+    float v1 = fmax(0.0f, srcTop / height);
+    float u2 = fmin(1.0f, srcRight / width);
+    float v2 = fmin(1.0f, srcBottom / height);
+
+    getMapper(texture).map(u1, v1, u2, v2);
 
     mCaches.unbindMeshBuffer();
     resetDrawTextureTexCoords(u1, v1, u2, v2);
@@ -2295,37 +2416,38 @@
     return DrawGlInfo::kStatusDrew;
 }
 
-status_t OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
-        const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
+status_t OpenGLRenderer::drawPatch(SkBitmap* bitmap, Res_png_9patch* patch,
         float left, float top, float right, float bottom, SkPaint* paint) {
-    int alpha;
-    SkXfermode::Mode mode;
-    getAlphaAndMode(paint, &alpha, &mode);
-
-    return drawPatch(bitmap, xDivs, yDivs, colors, width, height, numColors,
-            left, top, right, bottom, alpha, mode);
-}
-
-status_t OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
-        const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
-        float left, float top, float right, float bottom, int alpha, SkXfermode::Mode mode) {
     if (quickReject(left, top, right, bottom)) {
         return DrawGlInfo::kStatusDone;
     }
 
-    alpha *= mSnapshot->alpha;
+    AssetAtlas::Entry* entry = mCaches.assetAtlas.getEntry(bitmap);
+    const Patch* mesh = mCaches.patchCache.get(entry, bitmap->width(), bitmap->height(),
+            right - left, bottom - top, patch);
 
-    const Patch* mesh = mCaches.patchCache.get(bitmap->width(), bitmap->height(),
-            right - left, bottom - top, xDivs, yDivs, colors, width, height, numColors);
+    return drawPatch(bitmap, mesh, entry, left, top, right, bottom, paint);
+}
+
+status_t OpenGLRenderer::drawPatch(SkBitmap* bitmap, const Patch* mesh, AssetAtlas::Entry* entry,
+        float left, float top, float right, float bottom, SkPaint* paint) {
+    if (quickReject(left, top, right, bottom)) {
+        return DrawGlInfo::kStatusDone;
+    }
 
     if (CC_LIKELY(mesh && mesh->verticesCount > 0)) {
         mCaches.activeTexture(0);
-        Texture* texture = mCaches.textureCache.get(bitmap);
+        Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap);
         if (!texture) return DrawGlInfo::kStatusDone;
         const AutoTexture autoCleanup(texture);
+
         texture->setWrap(GL_CLAMP_TO_EDGE, true);
         texture->setFilter(GL_LINEAR, true);
 
+        int alpha;
+        SkXfermode::Mode mode;
+        getAlphaAndMode(paint, &alpha, &mode);
+
         const bool pureTranslate = currentTransform().isPureTranslate();
         // Mark the current layer dirty where we are going to draw the patch
         if (hasLayer() && mesh->hasEmptyQuads) {
@@ -2349,24 +2471,52 @@
             const float x = (int) floorf(left + currentTransform().getTranslateX() + 0.5f);
             const float y = (int) floorf(top + currentTransform().getTranslateY() + 0.5f);
 
-            drawTextureMesh(x, y, x + right - left, y + bottom - top, texture->id, alpha / 255.0f,
-                    mode, texture->blend, (GLvoid*) 0, (GLvoid*) gMeshTextureOffset,
-                    GL_TRIANGLES, mesh->verticesCount, false, true, mesh->meshBuffer,
-                    true, !mesh->hasEmptyQuads);
+            right = x + right - left;
+            bottom = y + bottom - top;
+            drawIndexedTextureMesh(x, y, right, bottom, texture->id, alpha / 255.0f,
+                    mode, texture->blend, (GLvoid*) mesh->offset, (GLvoid*) mesh->textureOffset,
+                    GL_TRIANGLES, mesh->indexCount, false, true,
+                    mCaches.patchCache.getMeshBuffer(), true, !mesh->hasEmptyQuads);
         } else {
-            drawTextureMesh(left, top, right, bottom, texture->id, alpha / 255.0f,
-                    mode, texture->blend, (GLvoid*) 0, (GLvoid*) gMeshTextureOffset,
-                    GL_TRIANGLES, mesh->verticesCount, false, false, mesh->meshBuffer,
-                    true, !mesh->hasEmptyQuads);
+            drawIndexedTextureMesh(left, top, right, bottom, texture->id, alpha / 255.0f,
+                    mode, texture->blend, (GLvoid*) mesh->offset, (GLvoid*) mesh->textureOffset,
+                    GL_TRIANGLES, mesh->indexCount, false, false,
+                    mCaches.patchCache.getMeshBuffer(), true, !mesh->hasEmptyQuads);
         }
     }
 
     return DrawGlInfo::kStatusDrew;
 }
 
+/**
+ * Important note: this method is intended to draw batches of 9-patch objects and
+ * will not set the scissor enable or dirty the current layer, if any.
+ * The caller is responsible for properly dirtying the current layer.
+ */
+status_t OpenGLRenderer::drawPatches(SkBitmap* bitmap, AssetAtlas::Entry* entry,
+        TextureVertex* vertices, uint32_t indexCount, SkPaint* paint) {
+    mCaches.activeTexture(0);
+    Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap);
+    if (!texture) return DrawGlInfo::kStatusDone;
+    const AutoTexture autoCleanup(texture);
+
+    texture->setWrap(GL_CLAMP_TO_EDGE, true);
+    texture->setFilter(GL_LINEAR, true);
+
+    int alpha;
+    SkXfermode::Mode mode;
+    getAlphaAndMode(paint, &alpha, &mode);
+
+    drawIndexedTextureMesh(0.0f, 0.0f, 1.0f, 1.0f, texture->id, alpha / 255.0f,
+            mode, texture->blend, &vertices[0].position[0], &vertices[0].texture[0],
+            GL_TRIANGLES, indexCount, false, true, 0, true, false);
+
+    return DrawGlInfo::kStatusDrew;
+}
+
 status_t OpenGLRenderer::drawVertexBuffer(const VertexBuffer& vertexBuffer, SkPaint* paint,
         bool useOffset) {
-    if (!vertexBuffer.getSize()) {
+    if (!vertexBuffer.getVertexCount()) {
         // no vertices to draw
         return DrawGlInfo::kStatusDone;
     }
@@ -2404,7 +2554,7 @@
         glVertexAttribPointer(alphaSlot, 1, GL_FLOAT, GL_FALSE, gAlphaVertexStride, alphaCoords);
     }
 
-    glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexBuffer.getSize());
+    glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexBuffer.getVertexCount());
 
     if (isAA) {
         glDisableVertexAttribArray(alphaSlot);
@@ -2467,65 +2617,22 @@
 }
 
 status_t OpenGLRenderer::drawPoints(float* points, int count, SkPaint* paint) {
-    if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone;
+    if (mSnapshot->isIgnored() || count < 2) return DrawGlInfo::kStatusDone;
 
-    // TODO: The paint's cap style defines whether the points are square or circular
-    // TODO: Handle AA for round points
+    count &= ~0x1; // round down to nearest two
 
-    // A stroke width of 0 has a special meaning in Skia:
-    // it draws an unscaled 1px point
-    float strokeWidth = paint->getStrokeWidth();
-    const bool isHairLine = paint->getStrokeWidth() == 0.0f;
-    if (isHairLine) {
-        // Now that we know it's hairline, we can set the effective width, to be used later
-        strokeWidth = 1.0f;
-    }
-    const float halfWidth = strokeWidth / 2;
+    VertexBuffer buffer;
+    SkRect bounds;
+    PathTessellator::tessellatePoints(points, count, paint, mSnapshot->transform, bounds, buffer);
 
-    int alpha;
-    SkXfermode::Mode mode;
-    getAlphaAndMode(paint, &alpha, &mode);
-
-    int verticesCount = count >> 1;
-    int generatedVerticesCount = 0;
-
-    TextureVertex pointsData[verticesCount];
-    TextureVertex* vertex = &pointsData[0];
-
-    // TODO: We should optimize this method to not generate vertices for points
-    // that lie outside of the clip.
-    mCaches.enableScissor();
-
-    setupDraw();
-    setupDrawNoTexture();
-    setupDrawPoint(strokeWidth);
-    setupDrawColor(paint->getColor(), alpha);
-    setupDrawColorFilter();
-    setupDrawShader();
-    setupDrawBlending(mode);
-    setupDrawProgram();
-    setupDrawModelViewIdentity(true);
-    setupDrawColorUniforms();
-    setupDrawColorFilterUniforms();
-    setupDrawPointUniforms();
-    setupDrawShaderIdentityUniforms();
-    setupDrawMesh(vertex);
-
-    for (int i = 0; i < count; i += 2) {
-        TextureVertex::set(vertex++, points[i], points[i + 1], 0.0f, 0.0f);
-        generatedVerticesCount++;
-
-        float left = points[i] - halfWidth;
-        float right = points[i] + halfWidth;
-        float top = points[i + 1] - halfWidth;
-        float bottom = points [i + 1] + halfWidth;
-
-        dirtyLayer(left, top, right, bottom, currentTransform());
+    if (quickReject(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom)) {
+        return DrawGlInfo::kStatusDone;
     }
 
-    glDrawArrays(GL_POINTS, 0, generatedVerticesCount);
+    dirtyLayer(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, currentTransform());
 
-    return DrawGlInfo::kStatusDrew;
+    bool useOffset = !paint->isAntiAlias();
+    return drawVertexBuffer(buffer, paint, useOffset);
 }
 
 status_t OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
@@ -2741,48 +2848,6 @@
     return alpha == 0.0f && getXfermode(paint->getXfermode()) == SkXfermode::kSrcOver_Mode;
 }
 
-class TextSetupFunctor: public Functor {
-public:
-    TextSetupFunctor(OpenGLRenderer& renderer, float x, float y, bool pureTranslate,
-            int alpha, SkXfermode::Mode mode, SkPaint* paint): Functor(),
-            renderer(renderer), x(x), y(y), pureTranslate(pureTranslate),
-            alpha(alpha), mode(mode), paint(paint) {
-    }
-    ~TextSetupFunctor() { }
-
-    status_t operator ()(int what, void* data) {
-        renderer.setupDraw();
-        renderer.setupDrawTextGamma(paint);
-        renderer.setupDrawDirtyRegionsDisabled();
-        renderer.setupDrawWithTexture(true);
-        renderer.setupDrawAlpha8Color(paint->getColor(), alpha);
-        renderer.setupDrawColorFilter();
-        renderer.setupDrawShader();
-        renderer.setupDrawBlending(true, mode);
-        renderer.setupDrawProgram();
-        renderer.setupDrawModelView(x, y, x, y, pureTranslate, true);
-        // Calling setupDrawTexture with the name 0 will enable the
-        // uv attributes and increase the texture unit count
-        // texture binding will be performed by the font renderer as
-        // needed
-        renderer.setupDrawTexture(0);
-        renderer.setupDrawPureColorUniforms();
-        renderer.setupDrawColorFilterUniforms();
-        renderer.setupDrawShaderUniforms(pureTranslate);
-        renderer.setupDrawTextGammaUniforms();
-
-        return NO_ERROR;
-    }
-
-    OpenGLRenderer& renderer;
-    float x;
-    float y;
-    bool pureTranslate;
-    int alpha;
-    SkXfermode::Mode mode;
-    SkPaint* paint;
-};
-
 status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count,
         const float* positions, SkPaint* paint) {
     if (text == NULL || count == 0 || mSnapshot->isIgnored() || canSkipText(paint)) {
@@ -2794,6 +2859,8 @@
         return DrawGlInfo::kStatusDone;
     }
 
+    mCaches.enableScissor();
+
     float x = 0.0f;
     float y = 0.0f;
     const bool pureTranslate = currentTransform().isPureTranslate();
@@ -2826,7 +2893,7 @@
 
     const bool hasActiveLayer = hasLayer();
 
-    TextSetupFunctor functor(*this, x, y, pureTranslate, alpha, mode, paint);
+    TextSetupFunctor functor(this, x, y, pureTranslate, alpha, mode, paint);
     if (fontRenderer.renderPosText(paint, clip, text, 0, bytesCount, count, x, y,
             positions, hasActiveLayer ? &bounds : NULL, &functor)) {
         if (hasActiveLayer) {
@@ -2856,36 +2923,17 @@
     return fontTransform;
 }
 
-status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
-        float x, float y, const float* positions, SkPaint* paint, float length,
+status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count, float x, float y,
+        const float* positions, SkPaint* paint, float totalAdvance, const Rect& bounds,
         DrawOpMode drawOpMode) {
 
-    if (drawOpMode == kDrawOpMode_Immediate &&
-            (text == NULL || count == 0 || mSnapshot->isIgnored() || canSkipText(paint))) {
-        return DrawGlInfo::kStatusDone;
-    }
-
-    if (length < 0.0f) length = paint->measureText(text, bytesCount);
-    switch (paint->getTextAlign()) {
-        case SkPaint::kCenter_Align:
-            x -= length / 2.0f;
-            break;
-        case SkPaint::kRight_Align:
-            x -= length;
-            break;
-        default:
-            break;
-    }
-
-    SkPaint::FontMetrics metrics;
-    paint->getFontMetrics(&metrics, 0.0f);
     if (drawOpMode == kDrawOpMode_Immediate) {
-        if (quickReject(x, y + metrics.fTop, x + length, y + metrics.fBottom)) {
+        // The checks for corner-case ignorable text and quick rejection is only done for immediate
+        // drawing as ops from DeferredDisplayList are already filtered for these
+        if (text == NULL || count == 0 || mSnapshot->isIgnored() || canSkipText(paint) ||
+                quickReject(bounds)) {
             return DrawGlInfo::kStatusDone;
         }
-    } else {
-        // merged draw operations don't need scissor, but clip should still be valid
-        mCaches.setScissorEnabled(mScissorOptimizationDisabled);
     }
 
     const float oldX = x;
@@ -2933,10 +2981,10 @@
 
     // TODO: Implement better clipping for scaled/rotated text
     const Rect* clip = !pureTranslate ? NULL : mSnapshot->clipRect;
-    Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
+    Rect layerBounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
 
     bool status;
-    TextSetupFunctor functor(*this, x, y, pureTranslate, alpha, mode, paint);
+    TextSetupFunctor functor(this, x, y, pureTranslate, alpha, mode, paint);
 
     // don't call issuedrawcommand, do it at end of batch
     bool forceFinish = (drawOpMode != kDrawOpMode_Defer);
@@ -2944,20 +2992,20 @@
         SkPaint paintCopy(*paint);
         paintCopy.setTextAlign(SkPaint::kLeft_Align);
         status = fontRenderer.renderPosText(&paintCopy, clip, text, 0, bytesCount, count, x, y,
-                positions, hasActiveLayer ? &bounds : NULL, &functor, forceFinish);
+                positions, hasActiveLayer ? &layerBounds : NULL, &functor, forceFinish);
     } else {
         status = fontRenderer.renderPosText(paint, clip, text, 0, bytesCount, count, x, y,
-                positions, hasActiveLayer ? &bounds : NULL, &functor, forceFinish);
+                positions, hasActiveLayer ? &layerBounds : NULL, &functor, forceFinish);
     }
 
     if ((status || drawOpMode != kDrawOpMode_Immediate) && hasActiveLayer) {
         if (!pureTranslate) {
-            transform.mapRect(bounds);
+            transform.mapRect(layerBounds);
         }
-        dirtyLayerUnchecked(bounds, getRegion());
+        dirtyLayerUnchecked(layerBounds, getRegion());
     }
 
-    drawTextDecorations(text, bytesCount, length, oldX, oldY, paint);
+    drawTextDecorations(text, bytesCount, totalAdvance, oldX, oldY, paint);
 
     return DrawGlInfo::kStatusDrew;
 }
@@ -2968,6 +3016,9 @@
         return DrawGlInfo::kStatusDone;
     }
 
+    // TODO: avoid scissor by calculating maximum bounds using path bounds + font metrics
+    mCaches.enableScissor();
+
     FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint);
     fontRenderer.setFont(paint, mat4::identity());
     fontRenderer.setTextureFiltering(true);
@@ -2975,26 +3026,7 @@
     int alpha;
     SkXfermode::Mode mode;
     getAlphaAndMode(paint, &alpha, &mode);
-
-    setupDraw();
-    setupDrawTextGamma(paint);
-    setupDrawDirtyRegionsDisabled();
-    setupDrawWithTexture(true);
-    setupDrawAlpha8Color(paint->getColor(), alpha);
-    setupDrawColorFilter();
-    setupDrawShader();
-    setupDrawBlending(true, mode);
-    setupDrawProgram();
-    setupDrawModelView(0.0f, 0.0f, 0.0f, 0.0f, false, true);
-    // Calling setupDrawTexture with the name 0 will enable the
-    // uv attributes and increase the texture unit count
-    // texture binding will be performed by the font renderer as
-    // needed
-    setupDrawTexture(0);
-    setupDrawPureColorUniforms();
-    setupDrawColorFilterUniforms();
-    setupDrawShaderUniforms(false);
-    setupDrawTextGammaUniforms();
+    TextSetupFunctor functor(this, 0.0f, 0.0f, false, alpha, mode, paint);
 
     const Rect* clip = &mSnapshot->getLocalClip();
     Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
@@ -3002,7 +3034,7 @@
     const bool hasActiveLayer = hasLayer();
 
     if (fontRenderer.renderTextOnPath(paint, clip, text, 0, bytesCount, count, path,
-            hOffset, vOffset, hasActiveLayer ? &bounds : NULL)) {
+            hOffset, vOffset, hasActiveLayer ? &bounds : NULL, &functor)) {
         if (hasActiveLayer) {
             currentTransform().mapRect(bounds);
             dirtyLayerUnchecked(bounds, getRegion());
@@ -3043,10 +3075,9 @@
         }
     }
 
-    Rect transformed;
-    Rect clip;
+    bool clipRequired = false;
     const bool rejected = quickRejectNoScissor(x, y,
-            x + layer->layer.getWidth(), y + layer->layer.getHeight(), transformed, clip);
+            x + layer->layer.getWidth(), y + layer->layer.getHeight(), false, &clipRequired);
 
     if (rejected) {
         if (transform && !transform->isIdentity()) {
@@ -3057,7 +3088,7 @@
 
     updateLayer(layer, true);
 
-    mCaches.setScissorEnabled(mScissorOptimizationDisabled || !clip.contains(transformed));
+    mCaches.setScissorEnabled(mScissorOptimizationDisabled || clipRequired);
     mCaches.activeTexture(0);
 
     if (CC_LIKELY(!layer->region.isEmpty())) {
@@ -3090,13 +3121,22 @@
                 setupDrawModelViewTranslate(x, y,
                         x + layer->layer.getWidth(), y + layer->layer.getHeight());
             }
-            setupDrawMesh(&layer->mesh[0].position[0], &layer->mesh[0].texture[0]);
 
-            DRAW_DOUBLE_STENCIL_IF(!layer->hasDrawnSinceUpdate,
-                    glDrawElements(GL_TRIANGLES, layer->meshElementCount,
-                            GL_UNSIGNED_SHORT, layer->meshIndices));
+            TextureVertex* mesh = &layer->mesh[0];
+            GLsizei elementsCount = layer->meshElementCount;
 
-            finishDrawTexture();
+            while (elementsCount > 0) {
+                GLsizei drawCount = min(elementsCount, (GLsizei) gMaxNumberOfQuads * 6);
+
+                setupDrawMeshIndices(&mesh[0].position[0], &mesh[0].texture[0]);
+                DRAW_DOUBLE_STENCIL_IF(!layer->hasDrawnSinceUpdate,
+                        glDrawElements(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, NULL));
+
+                elementsCount -= drawCount;
+                // Though there are 4 vertices in a quad, we use 6 indices per
+                // quad to draw with GL_TRIANGLES
+                mesh += (drawCount / 6) * 4;
+            }
 
 #if DEBUG_LAYERS_AS_REGIONS
             drawRegionRects(layer->region);
@@ -3131,7 +3171,7 @@
 void OpenGLRenderer::setupShader(SkiaShader* shader) {
     mDrawModifiers.mShader = shader;
     if (mDrawModifiers.mShader) {
-        mDrawModifiers.mShader->set(&mCaches.textureCache, &mCaches.gradientCache);
+        mDrawModifiers.mShader->setCaches(mCaches);
     }
 }
 
@@ -3199,6 +3239,14 @@
 // Drawing implementation
 ///////////////////////////////////////////////////////////////////////////////
 
+Texture* OpenGLRenderer::getTexture(SkBitmap* bitmap) {
+    Texture* texture = mCaches.assetAtlas.getEntryTexture(bitmap);
+    if (!texture) {
+        return mCaches.textureCache.get(bitmap);
+    }
+    return texture;
+}
+
 void OpenGLRenderer::drawPathTexture(const PathTexture* texture,
         float x, float y, SkPaint* paint) {
     if (quickReject(x, y, x + texture->width, y + texture->height)) {
@@ -3224,8 +3272,6 @@
     setupDrawMesh(NULL, (GLvoid*) gMeshTextureOffset);
 
     glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
-
-    finishDrawTexture();
 }
 
 // Same values used by Skia
@@ -3233,17 +3279,12 @@
 #define kStdUnderline_Offset    (1.0f / 9.0f)
 #define kStdUnderline_Thickness (1.0f / 18.0f)
 
-void OpenGLRenderer::drawTextDecorations(const char* text, int bytesCount, float length,
+void OpenGLRenderer::drawTextDecorations(const char* text, int bytesCount, float underlineWidth,
         float x, float y, SkPaint* paint) {
     // Handle underline and strike-through
     uint32_t flags = paint->getFlags();
     if (flags & (SkPaint::kUnderlineText_Flag | SkPaint::kStrikeThruText_Flag)) {
         SkPaint paintCopy(*paint);
-        float underlineWidth = length;
-        // If length is > 0.0f, we already measured the text for the text alignment
-        if (length <= 0.0f) {
-            underlineWidth = paintCopy.measureText(text, bytesCount);
-        }
 
         if (CC_LIKELY(underlineWidth > 0.0f)) {
             const float textSize = paintCopy.getTextSize();
@@ -3309,8 +3350,7 @@
     float right = FLT_MIN;
     float bottom = FLT_MIN;
 
-    int vertexCount = 0;
-    Vertex mesh[count * 6];
+    Vertex mesh[count];
     Vertex* vertex = mesh;
 
     for (int index = 0; index < count; index += 4) {
@@ -3319,15 +3359,11 @@
         float r = rects[index + 2];
         float b = rects[index + 3];
 
-        Vertex::set(vertex++, l, b);
         Vertex::set(vertex++, l, t);
         Vertex::set(vertex++, r, t);
         Vertex::set(vertex++, l, b);
-        Vertex::set(vertex++, r, t);
         Vertex::set(vertex++, r, b);
 
-        vertexCount += 6;
-
         left = fminf(left, l);
         top = fminf(top, t);
         right = fmaxf(right, r);
@@ -3350,13 +3386,12 @@
     setupDrawColorUniforms();
     setupDrawShaderUniforms();
     setupDrawColorFilterUniforms();
-    setupDrawVertices((GLvoid*) &mesh[0].position[0]);
 
     if (dirty && hasLayer()) {
         dirtyLayer(left, top, right, bottom, currentTransform());
     }
 
-    glDrawArrays(GL_TRIANGLES, 0, vertexCount);
+    drawIndexedQuads(&mesh[0], count / 4);
 
     return DrawGlInfo::kStatusDrew;
 }
@@ -3392,19 +3427,35 @@
 
     texture->setWrap(GL_CLAMP_TO_EDGE, true);
 
+    GLvoid* vertices = (GLvoid*) NULL;
+    GLvoid* texCoords = (GLvoid*) gMeshTextureOffset;
+
+    if (texture->uvMapper) {
+        vertices = &mMeshVertices[0].position[0];
+        texCoords = &mMeshVertices[0].texture[0];
+
+        Rect uvs(0.0f, 0.0f, 1.0f, 1.0f);
+        texture->uvMapper->map(uvs);
+
+        resetDrawTextureTexCoords(uvs.left, uvs.top, uvs.right, uvs.bottom);
+    }
+
     if (CC_LIKELY(currentTransform().isPureTranslate())) {
         const float x = (int) floorf(left + currentTransform().getTranslateX() + 0.5f);
         const float y = (int) floorf(top + currentTransform().getTranslateY() + 0.5f);
 
         texture->setFilter(GL_NEAREST, true);
         drawTextureMesh(x, y, x + texture->width, y + texture->height, texture->id,
-                alpha / 255.0f, mode, texture->blend, (GLvoid*) NULL,
-                (GLvoid*) gMeshTextureOffset, GL_TRIANGLE_STRIP, gMeshCount, false, true);
+                alpha / 255.0f, mode, texture->blend, vertices, texCoords,
+                GL_TRIANGLE_STRIP, gMeshCount, false, true);
     } else {
         texture->setFilter(FILTER(paint), true);
         drawTextureMesh(left, top, right, bottom, texture->id, alpha / 255.0f, mode,
-                texture->blend, (GLvoid*) NULL, (GLvoid*) gMeshTextureOffset,
-                GL_TRIANGLE_STRIP, gMeshCount);
+                texture->blend, vertices, texCoords, GL_TRIANGLE_STRIP, gMeshCount);
+    }
+
+    if (texture->uvMapper) {
+        resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f);
     }
 }
 
@@ -3437,8 +3488,31 @@
     setupDrawMesh(vertices, texCoords, vbo);
 
     glDrawArrays(drawMode, 0, elementsCount);
+}
 
-    finishDrawTexture();
+void OpenGLRenderer::drawIndexedTextureMesh(float left, float top, float right, float bottom,
+        GLuint texture, float alpha, SkXfermode::Mode mode, bool blend,
+        GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
+        bool swapSrcDst, bool ignoreTransform, GLuint vbo, bool ignoreScale, bool dirty) {
+
+    setupDraw();
+    setupDrawWithTexture();
+    setupDrawColor(alpha, alpha, alpha, alpha);
+    setupDrawColorFilter();
+    setupDrawBlending(blend, mode, swapSrcDst);
+    setupDrawProgram();
+    if (!dirty) setupDrawDirtyRegionsDisabled();
+    if (!ignoreScale) {
+        setupDrawModelView(left, top, right, bottom, ignoreTransform);
+    } else {
+        setupDrawModelViewTranslate(left, top, right, bottom, ignoreTransform);
+    }
+    setupDrawTexture(texture);
+    setupDrawPureColorUniforms();
+    setupDrawColorFilterUniforms();
+    setupDrawMeshIndices(vertices, texCoords, vbo);
+
+    glDrawElements(drawMode, elementsCount, GL_UNSIGNED_SHORT, NULL);
 }
 
 void OpenGLRenderer::drawAlpha8TextureMesh(float left, float top, float right, float bottom,
@@ -3468,12 +3542,23 @@
     setupDrawMesh(vertices, texCoords);
 
     glDrawArrays(drawMode, 0, elementsCount);
-
-    finishDrawTexture();
 }
 
 void OpenGLRenderer::chooseBlending(bool blend, SkXfermode::Mode mode,
         ProgramDescription& description, bool swapSrcDst) {
+    if (mCountOverdraw) {
+        if (!mCaches.blend) glEnable(GL_BLEND);
+        if (mCaches.lastSrcMode != GL_ONE || mCaches.lastDstMode != GL_ONE) {
+            glBlendFunc(GL_ONE, GL_ONE);
+        }
+
+        mCaches.blend = true;
+        mCaches.lastSrcMode = GL_ONE;
+        mCaches.lastDstMode = GL_ONE;
+
+        return;
+    }
+
     blend = blend || mode != SkXfermode::kSrcOver_Mode;
 
     if (blend) {
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index a0ad888..f74df97 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -34,6 +34,8 @@
 
 #include <cutils/compiler.h>
 
+#include <androidfw/ResourceTypes.h>
+
 #include "Debug.h"
 #include "Extensions.h"
 #include "Matrix.h"
@@ -43,12 +45,21 @@
 #include "Vertex.h"
 #include "SkiaShader.h"
 #include "SkiaColorFilter.h"
+#include "UvMapper.h"
 #include "Caches.h"
 
 namespace android {
 namespace uirenderer {
 
 struct DrawModifiers {
+    DrawModifiers() {
+        reset();
+    }
+
+    void reset() {
+        memset(this, 0, sizeof(DrawModifiers));
+    }
+
     SkiaShader* mShader;
     SkiaColorFilter* mColorFilter;
     float mOverrideLayerAlpha;
@@ -77,21 +88,21 @@
     kDrawOpMode_Flush
 };
 
-struct DeferredDisplayState {
-    Rect mBounds; // global op bounds, mapped by mMatrix to be in screen space coordinates, clipped.
-
-    // the below are set and used by the OpenGLRenderer at record and deferred playback
-    bool mClipValid;
-    Rect mClip;
-    mat4 mMatrix;
-    DrawModifiers mDrawModifiers;
-    float mAlpha;
+enum ClipSideFlags {
+    kClipSide_None = 0x0,
+    kClipSide_Left = 0x1,
+    kClipSide_Top = 0x2,
+    kClipSide_Right = 0x4,
+    kClipSide_Bottom = 0x8,
+    kClipSide_Full = 0xF,
+    kClipSide_ConservativeFull = 0x1F
 };
 
 ///////////////////////////////////////////////////////////////////////////////
 // Renderer
 ///////////////////////////////////////////////////////////////////////////////
 
+class DeferredDisplayState;
 class DisplayList;
 class TextSetupFunctor;
 class VertexBuffer;
@@ -188,13 +199,23 @@
      */
     virtual void resume();
 
+    ANDROID_API void setCountOverdrawEnabled(bool enabled) {
+        mCountOverdraw = enabled;
+    }
+
+    ANDROID_API float getOverdraw() {
+        return mCountOverdraw ? mOverdraw : 0.0f;
+    }
+
     ANDROID_API status_t invokeFunctors(Rect& dirty);
     ANDROID_API void detachFunctor(Functor* functor);
     ANDROID_API void attachFunctor(Functor* functor);
     virtual status_t callDrawGLFunction(Functor* functor, Rect& dirty);
 
     ANDROID_API void pushLayerUpdate(Layer* layer);
+    ANDROID_API void cancelLayerUpdate(Layer* layer);
     ANDROID_API void clearLayerUpdates();
+    ANDROID_API void flushLayerUpdates();
 
     ANDROID_API int getSaveCount() const;
     virtual int save(int flags);
@@ -228,8 +249,32 @@
     virtual void concatMatrix(SkMatrix* matrix);
 
     ANDROID_API const Rect& getClipBounds();
-    ANDROID_API bool quickReject(float left, float top, float right, float bottom);
-    bool quickRejectNoScissor(float left, float top, float right, float bottom);
+
+    /**
+     * Performs a quick reject but adjust the bounds to account for stroke width if necessary,
+     * and handling snapOut for AA geometry.
+     */
+    bool quickRejectPreStroke(float left, float top, float right, float bottom, SkPaint* paint);
+
+    /**
+     * Returns false and sets scissor based upon bounds if drawing won't be clipped out
+     */
+    bool quickReject(float left, float top, float right, float bottom, bool snapOut = false);
+    bool quickReject(const Rect& bounds) {
+        return quickReject(bounds.left, bounds.top, bounds.right, bounds.bottom);
+    }
+
+    /**
+     * Same as quickReject, without the scissor, instead returning clipRequired through pointer.
+     * clipRequired will be only set if not rejected
+     */
+    ANDROID_API bool quickRejectNoScissor(float left, float top, float right, float bottom,
+            bool snapOut = false, bool* clipRequired = NULL);
+    bool quickRejectNoScissor(const Rect& bounds, bool* clipRequired = NULL) {
+        return quickRejectNoScissor(bounds.left, bounds.top, bounds.right, bounds.bottom,
+                clipRequired);
+    }
+
     virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
     virtual bool clipPath(SkPath* path, SkRegion::Op op);
     virtual bool clipRegion(SkRegion* region, SkRegion::Op op);
@@ -239,8 +284,8 @@
     virtual void outputDisplayList(DisplayList* displayList);
     virtual status_t drawLayer(Layer* layer, float x, float y);
     virtual status_t drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
-    status_t drawBitmaps(SkBitmap* bitmap, int bitmapCount, TextureVertex* vertices,
-            const Rect& bounds, SkPaint* paint);
+    status_t drawBitmaps(SkBitmap* bitmap, AssetAtlas::Entry* entry, int bitmapCount,
+            TextureVertex* vertices, bool transformed, const Rect& bounds, SkPaint* paint);
     virtual status_t drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
     virtual status_t drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
             float srcRight, float srcBottom, float dstLeft, float dstTop,
@@ -248,12 +293,12 @@
     virtual status_t drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint);
     virtual status_t drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
             float* vertices, int* colors, SkPaint* paint);
-    virtual status_t drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
-            const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
+    status_t drawPatches(SkBitmap* bitmap, AssetAtlas::Entry* entry,
+            TextureVertex* vertices, uint32_t indexCount, SkPaint* paint);
+    virtual status_t drawPatch(SkBitmap* bitmap, Res_png_9patch* patch,
             float left, float top, float right, float bottom, SkPaint* paint);
-    status_t drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
-            const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
-            float left, float top, float right, float bottom, int alpha, SkXfermode::Mode mode);
+    status_t drawPatch(SkBitmap* bitmap, const Patch* mesh, AssetAtlas::Entry* entry,
+            float left, float top, float right, float bottom, SkPaint* paint);
     virtual status_t drawColor(int color, SkXfermode::Mode mode);
     virtual status_t drawRect(float left, float top, float right, float bottom, SkPaint* paint);
     virtual status_t drawRoundRect(float left, float top, float right, float bottom,
@@ -270,7 +315,7 @@
     virtual status_t drawPosText(const char* text, int bytesCount, int count,
             const float* positions, SkPaint* paint);
     virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y,
-            const float* positions, SkPaint* paint, float length = -1.0f,
+            const float* positions, SkPaint* paint, float totalAdvance, const Rect& bounds,
             DrawOpMode drawOpMode = kDrawOpMode_Immediate);
     virtual status_t drawRects(const float* rects, int count, SkPaint* paint);
 
@@ -291,9 +336,15 @@
 
     SkPaint* filterPaint(SkPaint* paint);
 
+    /**
+     * Store the current display state (most importantly, the current clip and transform), and
+     * additionally map the state's bounds from local to window coordinates.
+     *
+     * Returns true if quick-rejected
+     */
     bool storeDisplayState(DeferredDisplayState& state, int stateDeferFlags);
     void restoreDisplayState(const DeferredDisplayState& state, bool skipClipRestore = false);
-    void setFullScreenClip();
+    void setupMergedMultiDraw(const Rect* clipRect);
 
     const DrawModifiers& getDrawModifiers() { return mDrawModifiers; }
     void setDrawModifiers(const DrawModifiers& drawModifiers) { mDrawModifiers = drawModifiers; }
@@ -311,6 +362,9 @@
         return mSnapshot->clipRegion->isEmpty();
     }
 
+    int getViewportWidth() { return getSnapshot()->viewport.getWidth(); }
+    int getViewportHeight() { return getSnapshot()->viewport.getHeight(); }
+
     /**
      * Scales the alpha on the current snapshot. This alpha value will be modulated
      * with other alpha values when drawing primitives.
@@ -356,7 +410,7 @@
         return getXfermode(paint->getXfermode());
     }
 
-    static inline int getAlphaDirect(SkPaint* paint) {
+    static inline int getAlphaDirect(const SkPaint* paint) {
         if (!paint) return 255;
         return paint->getAlpha();
     }
@@ -579,18 +633,6 @@
     void setStencilFromClip();
 
     /**
-     * Performs a quick reject but does not affect the scissor. Returns
-     * the transformed rect to test and the current clip.
-     */
-    bool quickRejectNoScissor(float left, float top, float right, float bottom,
-            Rect& transformed, Rect& clip);
-
-    /**
-     * Performs a quick reject but adjust the bounds to account for stroke width if necessary
-     */
-    bool quickRejectPreStroke(float left, float top, float right, float bottom, SkPaint* paint);
-
-    /**
      * Given the local bounds of the layer, calculates ...
      */
     void calculateLayerBoundsAndClip(Rect& bounds, Rect& clip, bool fboLayer);
@@ -798,22 +840,35 @@
             bool swapSrcDst = false, bool ignoreTransform = false, GLuint vbo = 0,
             bool ignoreScale = false, bool dirty = true);
 
+    void drawIndexedTextureMesh(float left, float top, float right, float bottom, GLuint texture,
+            float alpha, SkXfermode::Mode mode, bool blend,
+            GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
+            bool swapSrcDst = false, bool ignoreTransform = false, GLuint vbo = 0,
+            bool ignoreScale = false, bool dirty = true);
+
     void drawAlpha8TextureMesh(float left, float top, float right, float bottom,
             GLuint texture, bool hasColor, int color, int alpha, SkXfermode::Mode mode,
             GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
             bool ignoreTransform, bool ignoreScale = false, bool dirty = true);
 
     /**
+     * Draws the specified list of vertices as quads using indexed GL_TRIANGLES.
+     * If the number of vertices to draw exceeds the number of indices we have
+     * pre-allocated, this method will generate several glDrawElements() calls.
+     */
+    void drawIndexedQuads(Vertex* mesh, GLsizei quadsCount);
+
+    /**
      * Draws text underline and strike-through if needed.
      *
      * @param text The text to decor
      * @param bytesCount The number of bytes in the text
-     * @param length The length in pixels of the text, can be <= 0.0f to force a measurement
+     * @param totalAdvance The total advance in pixels, defines underline/strikethrough length
      * @param x The x coordinate where the text will be drawn
      * @param y The y coordinate where the text will be drawn
      * @param paint The paint to draw the text with
      */
-    void drawTextDecorations(const char* text, int bytesCount, float length,
+    void drawTextDecorations(const char* text, int bytesCount, float totalAdvance,
             float x, float y, SkPaint* paint);
 
    /**
@@ -868,7 +923,7 @@
      * prior to calling this method.
      */
     inline void bindTexture(GLuint texture) {
-        glBindTexture(GL_TEXTURE_2D, texture);
+        mCaches.bindTexture(texture);
     }
 
     /**
@@ -876,7 +931,7 @@
      * prior to calling this method.
      */
     inline void bindExternalTexture(GLuint texture) {
-        glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture);
+        mCaches.bindTexture(GL_TEXTURE_EXTERNAL_OES, texture);
     }
 
     /**
@@ -911,7 +966,6 @@
     void setupDrawWithExternalTexture();
     void setupDrawNoTexture();
     void setupDrawAA();
-    void setupDrawPoint(float pointSize);
     void setupDrawColor(int color, int alpha);
     void setupDrawColor(float r, float g, float b, float a);
     void setupDrawAlpha8Color(int color, int alpha);
@@ -929,7 +983,6 @@
             bool ignoreTransform = false, bool ignoreModelView = false);
     void setupDrawModelViewTranslate(float left, float top, float right, float bottom,
             bool ignoreTransform = false);
-    void setupDrawPointUniforms();
     void setupDrawColorUniforms();
     void setupDrawPureColorUniforms();
     void setupDrawShaderIdentityUniforms();
@@ -943,9 +996,8 @@
     void setupDrawTextGammaUniforms();
     void setupDrawMesh(GLvoid* vertices, GLvoid* texCoords = NULL, GLuint vbo = 0);
     void setupDrawMesh(GLvoid* vertices, GLvoid* texCoords, GLvoid* colors);
-    void setupDrawMeshIndices(GLvoid* vertices, GLvoid* texCoords);
-    void setupDrawVertices(GLvoid* vertices);
-    void finishDrawTexture();
+    void setupDrawMeshIndices(GLvoid* vertices, GLvoid* texCoords, GLuint vbo = 0);
+    void setupDrawIndexedVertices(GLvoid* vertices);
     void accountForClear(SkXfermode::Mode mode);
 
     bool updateLayer(Layer* layer, bool inFrame);
@@ -973,6 +1025,7 @@
 
     void debugOverdraw(bool enable, bool clear);
     void renderOverdraw();
+    void countOverdraw();
 
     /**
      * Should be invoked every time the glScissor is modified.
@@ -985,6 +1038,17 @@
         return *mSnapshot->transform;
     }
 
+    inline const UvMapper& getMapper(const Texture* texture) {
+        return texture && texture->uvMapper ? *texture->uvMapper : mUvMapper;
+    }
+
+    /**
+     * Returns a texture object for the specified bitmap. The texture can
+     * come from the texture cache or an atlas. If this method returns
+     * NULL, the texture could not be found and/or allocated.
+     */
+    Texture* getTexture(SkBitmap* bitmap);
+
     // Dimensions of the drawing surface
     int mWidth, mHeight;
 
@@ -1010,6 +1074,9 @@
     // Used to draw textured quads
     TextureVertex mMeshVertices[4];
 
+    // Default UV mapper
+    const UvMapper mUvMapper;
+
     // shader, filters, and shadow
     DrawModifiers mDrawModifiers;
     SkPaint mFilteredPaint;
@@ -1050,12 +1117,19 @@
     // No-ops start/endTiling when set
     bool mSuppressTiling;
 
+    // If true, this renderer will setup drawing to emulate
+    // an increment stencil buffer in the color buffer
+    bool mCountOverdraw;
+    float mOverdraw;
+
     // Optional name of the renderer
     String8 mName;
 
     friend class DisplayListRenderer;
     friend class Layer;
     friend class TextSetupFunctor;
+    friend class DrawBitmapOp;
+    friend class DrawPatchOp;
 
 }; // class OpenGLRenderer
 
diff --git a/libs/hwui/Patch.cpp b/libs/hwui/Patch.cpp
index 45c619e..9b023f9 100644
--- a/libs/hwui/Patch.cpp
+++ b/libs/hwui/Patch.cpp
@@ -20,9 +20,10 @@
 
 #include <utils/Log.h>
 
-#include "Patch.h"
 #include "Caches.h"
+#include "Patch.h"
 #include "Properties.h"
+#include "UvMapper.h"
 
 namespace android {
 namespace uirenderer {
@@ -31,90 +32,58 @@
 // Constructors/destructor
 ///////////////////////////////////////////////////////////////////////////////
 
-Patch::Patch(const uint32_t xCount, const uint32_t yCount, const int8_t emptyQuads):
-        mXCount(xCount), mYCount(yCount), mEmptyQuads(emptyQuads) {
-    // Initialized with the maximum number of vertices we will need
-    // 2 triangles per patch, 3 vertices per triangle
-    uint32_t maxVertices = ((xCount + 1) * (yCount + 1) - emptyQuads) * 2 * 3;
-    mVertices = new TextureVertex[maxVertices];
-    mAllocatedVerticesCount = 0;
-
-    verticesCount = 0;
-    hasEmptyQuads = emptyQuads > 0;
-
-    mColorKey = 0;
-    mXDivs = new int32_t[mXCount];
-    mYDivs = new int32_t[mYCount];
-
-    PATCH_LOGD("    patch: xCount = %d, yCount = %d, emptyQuads = %d, max vertices = %d",
-            xCount, yCount, emptyQuads, maxVertices);
-
-    glGenBuffers(1, &meshBuffer);
+Patch::Patch(): vertices(NULL), verticesCount(0), indexCount(0), hasEmptyQuads(false) {
 }
 
 Patch::~Patch() {
-    delete[] mVertices;
-    delete[] mXDivs;
-    delete[] mYDivs;
-    glDeleteBuffers(1, &meshBuffer);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Patch management
-///////////////////////////////////////////////////////////////////////////////
-
-void Patch::copy(const int32_t* xDivs, const int32_t* yDivs) {
-    memcpy(mXDivs, xDivs, mXCount * sizeof(int32_t));
-    memcpy(mYDivs, yDivs, mYCount * sizeof(int32_t));
-}
-
-void Patch::updateColorKey(const uint32_t colorKey) {
-    mColorKey = colorKey;
-}
-
-bool Patch::matches(const int32_t* xDivs, const int32_t* yDivs,
-        const uint32_t colorKey, const int8_t emptyQuads) {
-
-    bool matches = true;
-
-    if (mEmptyQuads != emptyQuads) {
-        mEmptyQuads = emptyQuads;
-        hasEmptyQuads = emptyQuads > 0;
-        matches = false;
-    }
-
-    if (mColorKey != colorKey) {
-        updateColorKey(colorKey);
-        matches = false;
-    }
-
-    if (memcmp(mXDivs, xDivs, mXCount * sizeof(int32_t))) {
-        memcpy(mXDivs, xDivs, mXCount * sizeof(int32_t));
-        matches = false;
-    }
-
-    if (memcmp(mYDivs, yDivs, mYCount * sizeof(int32_t))) {
-        memcpy(mYDivs, yDivs, mYCount * sizeof(int32_t));
-        matches = false;
-    }
-
-    return matches;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 // Vertices management
 ///////////////////////////////////////////////////////////////////////////////
 
-void Patch::updateVertices(const float bitmapWidth, const float bitmapHeight,
-        float left, float top, float right, float bottom) {
-    if (hasEmptyQuads) quads.clear();
+uint32_t Patch::getSize() const {
+    return verticesCount * sizeof(TextureVertex);
+}
 
-    // Reset the vertices count here, we will count exactly how many
-    // vertices we actually need when generating the quads
-    verticesCount = 0;
+TextureVertex* Patch::createMesh(const float bitmapWidth, const float bitmapHeight,
+        float width, float height, const Res_png_9patch* patch) {
+    UvMapper mapper;
+    return createMesh(bitmapWidth, bitmapHeight, width, height, mapper, patch);
+}
 
-    const uint32_t xStretchCount = (mXCount + 1) >> 1;
-    const uint32_t yStretchCount = (mYCount + 1) >> 1;
+TextureVertex* Patch::createMesh(const float bitmapWidth, const float bitmapHeight,
+        float width, float height, const UvMapper& mapper, const Res_png_9patch* patch) {
+    if (vertices) return vertices;
+
+    int8_t emptyQuads = 0;
+    mColors = patch->colors;
+
+    const int8_t numColors = patch->numColors;
+    if (uint8_t(numColors) < sizeof(uint32_t) * 4) {
+        for (int8_t i = 0; i < numColors; i++) {
+            if (mColors[i] == 0x0) {
+                emptyQuads++;
+            }
+        }
+    }
+
+    hasEmptyQuads = emptyQuads > 0;
+
+    uint32_t xCount = patch->numXDivs;
+    uint32_t yCount = patch->numYDivs;
+
+    uint32_t maxVertices = ((xCount + 1) * (yCount + 1) - emptyQuads) * 4;
+    if (maxVertices == 0) return NULL;
+
+    TextureVertex* tempVertices = new TextureVertex[maxVertices];
+    TextureVertex* vertex = tempVertices;
+
+    const int32_t* xDivs = patch->xDivs;
+    const int32_t* yDivs = patch->yDivs;
+
+    const uint32_t xStretchCount = (xCount + 1) >> 1;
+    const uint32_t yStretchCount = (yCount + 1) >> 1;
 
     float stretchX = 0.0f;
     float stretchY = 0.0f;
@@ -124,29 +93,28 @@
 
     if (xStretchCount > 0) {
         uint32_t stretchSize = 0;
-        for (uint32_t i = 1; i < mXCount; i += 2) {
-            stretchSize += mXDivs[i] - mXDivs[i - 1];
+        for (uint32_t i = 1; i < xCount; i += 2) {
+            stretchSize += xDivs[i] - xDivs[i - 1];
         }
         const float xStretchTex = stretchSize;
         const float fixed = bitmapWidth - stretchSize;
-        const float xStretch = fmaxf(right - left - fixed, 0.0f);
+        const float xStretch = fmaxf(width - fixed, 0.0f);
         stretchX = xStretch / xStretchTex;
-        rescaleX = fixed == 0.0f ? 0.0f : fminf(fmaxf(right - left, 0.0f) / fixed, 1.0f);
+        rescaleX = fixed == 0.0f ? 0.0f : fminf(fmaxf(width, 0.0f) / fixed, 1.0f);
     }
 
     if (yStretchCount > 0) {
         uint32_t stretchSize = 0;
-        for (uint32_t i = 1; i < mYCount; i += 2) {
-            stretchSize += mYDivs[i] - mYDivs[i - 1];
+        for (uint32_t i = 1; i < yCount; i += 2) {
+            stretchSize += yDivs[i] - yDivs[i - 1];
         }
         const float yStretchTex = stretchSize;
         const float fixed = bitmapHeight - stretchSize;
-        const float yStretch = fmaxf(bottom - top - fixed, 0.0f);
+        const float yStretch = fmaxf(height - fixed, 0.0f);
         stretchY = yStretch / yStretchTex;
-        rescaleY = fixed == 0.0f ? 0.0f : fminf(fmaxf(bottom - top, 0.0f) / fixed, 1.0f);
+        rescaleY = fixed == 0.0f ? 0.0f : fminf(fmaxf(height, 0.0f) / fixed, 1.0f);
     }
 
-    TextureVertex* vertex = mVertices;
     uint32_t quadCount = 0;
 
     float previousStepY = 0.0f;
@@ -155,8 +123,10 @@
     float y2 = 0.0f;
     float v1 = 0.0f;
 
-    for (uint32_t i = 0; i < mYCount; i++) {
-        float stepY = mYDivs[i];
+    mUvMapper = mapper;
+
+    for (uint32_t i = 0; i < yCount; i++) {
+        float stepY = yDivs[i];
         const float segment = stepY - previousStepY;
 
         if (i & 1) {
@@ -170,15 +140,8 @@
         v1 += vOffset / bitmapHeight;
 
         if (stepY > 0.0f) {
-#if DEBUG_EXPLODE_PATCHES
-            y1 += i * EXPLODE_GAP;
-            y2 += i * EXPLODE_GAP;
-#endif
-            generateRow(vertex, y1, y2, v1, v2, stretchX, rescaleX, right - left,
-                    bitmapWidth, quadCount);
-#if DEBUG_EXPLODE_PATCHES
-            y2 -= i * EXPLODE_GAP;
-#endif
+            generateRow(xDivs, xCount, vertex, y1, y2, v1, v2, stretchX, rescaleX,
+                    width, bitmapWidth, quadCount);
         }
 
         y1 = y2;
@@ -188,34 +151,25 @@
     }
 
     if (previousStepY != bitmapHeight) {
-        y2 = bottom - top;
-#if DEBUG_EXPLODE_PATCHES
-        y1 += mYCount * EXPLODE_GAP;
-        y2 += mYCount * EXPLODE_GAP;
-#endif
-        generateRow(vertex, y1, y2, v1, 1.0f, stretchX, rescaleX, right - left,
-                bitmapWidth, quadCount);
+        y2 = height;
+        generateRow(xDivs, xCount, vertex, y1, y2, v1, 1.0f, stretchX, rescaleX,
+                width, bitmapWidth, quadCount);
     }
 
-    if (verticesCount > 0) {
-        Caches& caches = Caches::getInstance();
-        caches.bindMeshBuffer(meshBuffer);
-        if (mAllocatedVerticesCount < verticesCount) {
-            glBufferData(GL_ARRAY_BUFFER, sizeof(TextureVertex) * verticesCount,
-                    mVertices, GL_DYNAMIC_DRAW);
-            mAllocatedVerticesCount = verticesCount;
-        } else {
-            glBufferSubData(GL_ARRAY_BUFFER, 0,
-                    sizeof(TextureVertex) * verticesCount, mVertices);
-        }
-        caches.resetVertexPointers();
+    if (verticesCount == maxVertices) {
+        vertices = tempVertices;
+    } else {
+        vertices = new TextureVertex[verticesCount];
+        memcpy(vertices, tempVertices, verticesCount * sizeof(TextureVertex));
+        delete[] tempVertices;
     }
 
-    PATCH_LOGD("    patch: new vertices count = %d", verticesCount);
+    return vertices;
 }
 
-void Patch::generateRow(TextureVertex*& vertex, float y1, float y2, float v1, float v2,
-        float stretchX, float rescaleX, float width, float bitmapWidth, uint32_t& quadCount) {
+void Patch::generateRow(const int32_t* xDivs, uint32_t xCount, TextureVertex*& vertex,
+        float y1, float y2, float v1, float v2, float stretchX, float rescaleX,
+        float width, float bitmapWidth, uint32_t& quadCount) {
     float previousStepX = 0.0f;
 
     float x1 = 0.0f;
@@ -223,8 +177,8 @@
     float u1 = 0.0f;
 
     // Generate the row quad by quad
-    for (uint32_t i = 0; i < mXCount; i++) {
-        float stepX = mXDivs[i];
+    for (uint32_t i = 0; i < xCount; i++) {
+        float stepX = xDivs[i];
         const float segment = stepX - previousStepX;
 
         if (i & 1) {
@@ -238,14 +192,7 @@
         u1 += uOffset / bitmapWidth;
 
         if (stepX > 0.0f) {
-#if DEBUG_EXPLODE_PATCHES
-            x1 += i * EXPLODE_GAP;
-            x2 += i * EXPLODE_GAP;
-#endif
             generateQuad(vertex, x1, y1, x2, y2, u1, v1, u2, v2, quadCount);
-#if DEBUG_EXPLODE_PATCHES
-            x2 -= i * EXPLODE_GAP;
-#endif
         }
 
         x1 = x2;
@@ -256,10 +203,6 @@
 
     if (previousStepX != bitmapWidth) {
         x2 = width;
-#if DEBUG_EXPLODE_PATCHES
-        x1 += mXCount * EXPLODE_GAP;
-        x2 += mXCount * EXPLODE_GAP;
-#endif
         generateQuad(vertex, x1, y1, x2, y2, u1, v1, 1.0f, v2, quadCount);
     }
 }
@@ -275,11 +218,11 @@
     if (y2 < 0.0f) y2 = 0.0f;
 
     // Skip degenerate and transparent (empty) quads
-    if (((mColorKey >> oldQuadCount) & 0x1) || x1 >= x2 || y1 >= y2) {
+    if ((mColors[oldQuadCount] == 0) || x1 >= x2 || y1 >= y2) {
 #if DEBUG_PATCHES_EMPTY_VERTICES
         PATCH_LOGD("    quad %d (empty)", oldQuadCount);
-        PATCH_LOGD("        left,  top    = %.2f, %.2f\t\tu1, v1 = %.4f, %.4f", x1, y1, u1, v1);
-        PATCH_LOGD("        right, bottom = %.2f, %.2f\t\tu2, v2 = %.4f, %.4f", x2, y2, u2, v2);
+        PATCH_LOGD("        left,  top    = %.2f, %.2f\t\tu1, v1 = %.8f, %.8f", x1, y1, u1, v1);
+        PATCH_LOGD("        right, bottom = %.2f, %.2f\t\tu2, v2 = %.8f, %.8f", x2, y2, u2, v2);
 #endif
         return;
     }
@@ -290,23 +233,20 @@
         quads.add(bounds);
     }
 
-    // Left triangle
+    mUvMapper.map(u1, v1, u2, v2);
+
     TextureVertex::set(vertex++, x1, y1, u1, v1);
     TextureVertex::set(vertex++, x2, y1, u2, v1);
     TextureVertex::set(vertex++, x1, y2, u1, v2);
-
-    // Right triangle
-    TextureVertex::set(vertex++, x1, y2, u1, v2);
-    TextureVertex::set(vertex++, x2, y1, u2, v1);
     TextureVertex::set(vertex++, x2, y2, u2, v2);
 
-    // A quad is made of 2 triangles, 6 vertices
-    verticesCount += 6;
+    verticesCount += 4;
+    indexCount += 6;
 
 #if DEBUG_PATCHES_VERTICES
     PATCH_LOGD("    quad %d", oldQuadCount);
-    PATCH_LOGD("        left,  top    = %.2f, %.2f\t\tu1, v1 = %.4f, %.4f", x1, y1, u1, v1);
-    PATCH_LOGD("        right, bottom = %.2f, %.2f\t\tu2, v2 = %.4f, %.4f", x2, y2, u2, v2);
+    PATCH_LOGD("        left,  top    = %.2f, %.2f\t\tu1, v1 = %.8f, %.8f", x1, y1, u1, v1);
+    PATCH_LOGD("        right, bottom = %.2f, %.2f\t\tu2, v2 = %.8f, %.8f", x2, y2, u2, v2);
 #endif
 }
 
diff --git a/libs/hwui/Patch.h b/libs/hwui/Patch.h
index ee7bf70..763a785 100644
--- a/libs/hwui/Patch.h
+++ b/libs/hwui/Patch.h
@@ -23,62 +23,51 @@
 
 #include <utils/Vector.h>
 
+#include <androidfw/ResourceTypes.h>
+
 #include "Rect.h"
+#include "UvMapper.h"
 #include "Vertex.h"
 
 namespace android {
 namespace uirenderer {
 
 ///////////////////////////////////////////////////////////////////////////////
-// Defines
-///////////////////////////////////////////////////////////////////////////////
-
-#define EXPLODE_GAP 4
-
-///////////////////////////////////////////////////////////////////////////////
 // 9-patch structures
 ///////////////////////////////////////////////////////////////////////////////
 
-/**
- * An OpenGL patch. This contains an array of vertices and an array of
- * indices to render the vertices.
- */
 struct Patch {
-    Patch(const uint32_t xCount, const uint32_t yCount, const int8_t emptyQuads);
+    Patch();
     ~Patch();
 
-    void updateVertices(const float bitmapWidth, const float bitmapHeight,
-            float left, float top, float right, float bottom);
+    /**
+     * Returns the size of this patch's mesh in bytes.
+     */
+    uint32_t getSize() const;
 
-    void updateColorKey(const uint32_t colorKey);
-    void copy(const int32_t* xDivs, const int32_t* yDivs);
-    bool matches(const int32_t* xDivs, const int32_t* yDivs,
-            const uint32_t colorKey, const int8_t emptyQuads);
-
-    GLuint meshBuffer;
+    TextureVertex* vertices;
     uint32_t verticesCount;
+    uint32_t indexCount;
     bool hasEmptyQuads;
     Vector<Rect> quads;
 
+    GLintptr offset;
+    GLintptr textureOffset;
+
+    TextureVertex* createMesh(const float bitmapWidth, const float bitmapHeight,
+            float width, float height, const Res_png_9patch* patch);
+    TextureVertex* createMesh(const float bitmapWidth, const float bitmapHeight,
+            float width, float height, const UvMapper& mapper, const Res_png_9patch* patch);
+
 private:
-    TextureVertex* mVertices;
-    uint32_t mAllocatedVerticesCount;
-
-    int32_t* mXDivs;
-    int32_t* mYDivs;
-    uint32_t mColorKey;
-
-    uint32_t mXCount;
-    uint32_t mYCount;
-    int8_t mEmptyQuads;
-
-    void generateRow(TextureVertex*& vertex, float y1, float y2,
-            float v1, float v2, float stretchX, float rescaleX,
+    void generateRow(const int32_t* xDivs, uint32_t xCount, TextureVertex*& vertex,
+            float y1, float y2, float v1, float v2, float stretchX, float rescaleX,
             float width, float bitmapWidth, uint32_t& quadCount);
-    void generateQuad(TextureVertex*& vertex,
-            float x1, float y1, float x2, float y2,
-            float u1, float v1, float u2, float v2,
-            uint32_t& quadCount);
+    void generateQuad(TextureVertex*& vertex, float x1, float y1, float x2, float y2,
+            float u1, float v1, float u2, float v2, uint32_t& quadCount);
+
+    uint32_t* mColors;
+    UvMapper mUvMapper;
 }; // struct Patch
 
 }; // namespace uirenderer
diff --git a/libs/hwui/PatchCache.cpp b/libs/hwui/PatchCache.cpp
index 62e38d3..dc0d98c 100644
--- a/libs/hwui/PatchCache.cpp
+++ b/libs/hwui/PatchCache.cpp
@@ -16,8 +16,10 @@
 
 #define LOG_TAG "OpenGLRenderer"
 
+#include <utils/JenkinsHash.h>
 #include <utils/Log.h>
 
+#include "Caches.h"
 #include "PatchCache.h"
 #include "Properties.h"
 
@@ -28,111 +30,243 @@
 // Constructors/destructor
 ///////////////////////////////////////////////////////////////////////////////
 
-PatchCache::PatchCache(): mMaxEntries(DEFAULT_PATCH_CACHE_SIZE) {
-}
-
-PatchCache::PatchCache(uint32_t maxEntries): mMaxEntries(maxEntries) {
+PatchCache::PatchCache():
+        mSize(0), mCache(LruCache<PatchDescription, Patch*>::kUnlimitedCapacity),
+        mMeshBuffer(0), mFreeBlocks(NULL), mGenerationId(0) {
+    char property[PROPERTY_VALUE_MAX];
+    if (property_get(PROPERTY_PATCH_CACHE_SIZE, property, NULL) > 0) {
+        INIT_LOGD("  Setting patch cache size to %skB", property);
+        mMaxSize = KB(atoi(property));
+    } else {
+        INIT_LOGD("  Using default patch cache size of %.2fkB", DEFAULT_PATCH_CACHE_SIZE);
+        mMaxSize = KB(DEFAULT_PATCH_CACHE_SIZE);
+    }
 }
 
 PatchCache::~PatchCache() {
     clear();
 }
 
+void PatchCache::init(Caches& caches) {
+    bool created = false;
+    if (!mMeshBuffer) {
+        glGenBuffers(1, &mMeshBuffer);
+        created = true;
+    }
+
+    caches.bindMeshBuffer(mMeshBuffer);
+    caches.resetVertexPointers();
+
+    if (created) {
+        createVertexBuffer();
+    }
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 // Caching
 ///////////////////////////////////////////////////////////////////////////////
 
-int PatchCache::PatchDescription::compare(
-        const PatchCache::PatchDescription& lhs, const PatchCache::PatchDescription& rhs) {
-    int deltaInt = lhs.bitmapWidth - rhs.bitmapWidth;
-    if (deltaInt != 0) return deltaInt;
+hash_t PatchCache::PatchDescription::hash() const {
+    uint32_t hash = JenkinsHashMix(0, android::hash_type(mPatch));
+    hash = JenkinsHashMix(hash, mBitmapWidth);
+    hash = JenkinsHashMix(hash, mBitmapHeight);
+    hash = JenkinsHashMix(hash, mPixelWidth);
+    hash = JenkinsHashMix(hash, mPixelHeight);
+    return JenkinsHashWhiten(hash);
+}
 
-    deltaInt = lhs.bitmapHeight - rhs.bitmapHeight;
-    if (deltaInt != 0) return deltaInt;
-
-    if (lhs.pixelWidth < rhs.pixelWidth) return -1;
-    if (lhs.pixelWidth > rhs.pixelWidth) return +1;
-
-    if (lhs.pixelHeight < rhs.pixelHeight) return -1;
-    if (lhs.pixelHeight > rhs.pixelHeight) return +1;
-
-    deltaInt = lhs.xCount - rhs.xCount;
-    if (deltaInt != 0) return deltaInt;
-
-    deltaInt = lhs.yCount - rhs.yCount;
-    if (deltaInt != 0) return deltaInt;
-
-    deltaInt = lhs.emptyCount - rhs.emptyCount;
-    if (deltaInt != 0) return deltaInt;
-
-    deltaInt = lhs.colorKey - rhs.colorKey;
-    if (deltaInt != 0) return deltaInt;
-
-    return 0;
+int PatchCache::PatchDescription::compare(const PatchCache::PatchDescription& lhs,
+            const PatchCache::PatchDescription& rhs) {
+    return memcmp(&lhs, &rhs, sizeof(PatchDescription));
 }
 
 void PatchCache::clear() {
-    size_t count = mCache.size();
-    for (size_t i = 0; i < count; i++) {
-        delete mCache.valueAt(i);
+    clearCache();
+
+    if (mMeshBuffer) {
+        Caches::getInstance().unbindMeshBuffer();
+        glDeleteBuffers(1, &mMeshBuffer);
+        mMeshBuffer = 0;
+        mSize = 0;
     }
-    mCache.clear();
 }
 
-Patch* PatchCache::get(const uint32_t bitmapWidth, const uint32_t bitmapHeight,
-        const float pixelWidth, const float pixelHeight,
-        const int32_t* xDivs, const int32_t* yDivs, const uint32_t* colors,
-        const uint32_t width, const uint32_t height, const int8_t numColors) {
+void PatchCache::clearCache() {
+    LruCache<PatchDescription, Patch*>::Iterator i(mCache);
+    while (i.next()) {
+        delete i.value();
+    }
+    mCache.clear();
 
-    int8_t transparentQuads = 0;
-    uint32_t colorKey = 0;
+    BufferBlock* block = mFreeBlocks;
+    while (block) {
+        BufferBlock* next = block->next;
+        delete block;
+        block = next;
+    }
+    mFreeBlocks = NULL;
+}
 
-    if (uint8_t(numColors) < sizeof(uint32_t) * 4) {
-        for (int8_t i = 0; i < numColors; i++) {
-            if (colors[i] == 0x0) {
-                transparentQuads++;
-                colorKey |= 0x1 << i;
-            }
+void PatchCache::remove(Vector<patch_pair_t>& patchesToRemove, Res_png_9patch* patch) {
+    LruCache<PatchDescription, Patch*>::Iterator i(mCache);
+    while (i.next()) {
+        const PatchDescription& key = i.key();
+        if (key.getPatch() == patch) {
+            patchesToRemove.push(patch_pair_t(&key, i.value()));
         }
     }
+}
 
-    // If the 9patch is made of only transparent quads
-    if (transparentQuads == int8_t((width + 1) * (height + 1))) {
-        return NULL;
+void PatchCache::removeDeferred(Res_png_9patch* patch) {
+    Mutex::Autolock _l(mLock);
+    mGarbage.push(patch);
+}
+
+void PatchCache::clearGarbage() {
+    Vector<patch_pair_t> patchesToRemove;
+
+    { // scope for the mutex
+        Mutex::Autolock _l(mLock);
+        size_t count = mGarbage.size();
+        for (size_t i = 0; i < count; i++) {
+            remove(patchesToRemove, mGarbage[i]);
+        }
+        mGarbage.clear();
     }
 
-    const PatchDescription description(bitmapWidth, bitmapHeight,
-            pixelWidth, pixelHeight, width, height, transparentQuads, colorKey);
+    // TODO: We could sort patchesToRemove by offset to merge
+    // adjacent free blocks
+    for (size_t i = 0; i < patchesToRemove.size(); i++) {
+        const patch_pair_t& pair = patchesToRemove[i];
 
-    ssize_t index = mCache.indexOfKey(description);
-    Patch* mesh = NULL;
-    if (index >= 0) {
-        mesh = mCache.valueAt(index);
+        // Add a new free block to the list
+        const Patch* patch = pair.getSecond();
+        BufferBlock* block = new BufferBlock(patch->offset, patch->getSize());
+        block->next = mFreeBlocks;
+        mFreeBlocks = block;
+
+        mSize -= patch->getSize();
+
+        mCache.remove(*pair.getFirst());
     }
 
+#if DEBUG_PATCHES
+    if (patchesToRemove.size() > 0) {
+        dumpFreeBlocks("Removed garbage");
+    }
+#endif
+}
+
+void PatchCache::createVertexBuffer() {
+    glBufferData(GL_ARRAY_BUFFER, mMaxSize, NULL, GL_DYNAMIC_DRAW);
+    mSize = 0;
+    mFreeBlocks = new BufferBlock(0, mMaxSize);
+    mGenerationId++;
+}
+
+/**
+ * Sets the mesh's offsets and copies its associated vertices into
+ * the mesh buffer (VBO).
+ */
+void PatchCache::setupMesh(Patch* newMesh, TextureVertex* vertices) {
+    // This call ensures the VBO exists and that it is bound
+    init(Caches::getInstance());
+
+    // If we're running out of space, let's clear the entire cache
+    uint32_t size = newMesh->getSize();
+    if (mSize + size > mMaxSize) {
+        clearCache();
+        createVertexBuffer();
+    }
+
+    // Find a block where we can fit the mesh
+    BufferBlock* previous = NULL;
+    BufferBlock* block = mFreeBlocks;
+    while (block) {
+        // The mesh fits
+        if (block->size >= size) {
+            break;
+        }
+        previous = block;
+        block = block->next;
+    }
+
+    // We have enough space left in the buffer, but it's
+    // too fragmented, let's clear the cache
+    if (!block) {
+        clearCache();
+        createVertexBuffer();
+        previous = NULL;
+        block = mFreeBlocks;
+    }
+
+    // Copy the 9patch mesh in the VBO
+    newMesh->offset = (GLintptr) (block->offset);
+    newMesh->textureOffset = newMesh->offset + gMeshTextureOffset;
+    glBufferSubData(GL_ARRAY_BUFFER, newMesh->offset, size, vertices);
+
+    // Remove the block since we've used it entirely
+    if (block->size == size) {
+        if (previous) {
+            previous->next = block->next;
+        } else {
+            mFreeBlocks = block->next;
+        }
+    } else {
+        // Resize the block now that it's occupied
+        block->offset += size;
+        block->size -= size;
+    }
+
+    mSize += size;
+}
+
+const Patch* PatchCache::get(const AssetAtlas::Entry* entry,
+        const uint32_t bitmapWidth, const uint32_t bitmapHeight,
+        const float pixelWidth, const float pixelHeight, const Res_png_9patch* patch) {
+
+    const PatchDescription description(bitmapWidth, bitmapHeight, pixelWidth, pixelHeight, patch);
+    const Patch* mesh = mCache.get(description);
+
     if (!mesh) {
-        PATCH_LOGD("New patch mesh "
-                "xCount=%d yCount=%d, w=%.2f h=%.2f, bw=%.2f bh=%.2f",
-                width, height, pixelWidth, pixelHeight, bitmapWidth, bitmapHeight);
+        Patch* newMesh = new Patch();
+        TextureVertex* vertices;
 
-        mesh = new Patch(width, height, transparentQuads);
-        mesh->updateColorKey(colorKey);
-        mesh->copy(xDivs, yDivs);
-        mesh->updateVertices(bitmapWidth, bitmapHeight, 0.0f, 0.0f, pixelWidth, pixelHeight);
-
-        if (mCache.size() >= mMaxEntries) {
-            delete mCache.valueAt(mCache.size() - 1);
-            mCache.removeItemsAt(mCache.size() - 1, 1);
+        if (entry) {
+            // An atlas entry has a UV mapper
+            vertices = newMesh->createMesh(bitmapWidth, bitmapHeight,
+                    pixelWidth, pixelHeight, entry->uvMapper, patch);
+        } else {
+            vertices = newMesh->createMesh(bitmapWidth, bitmapHeight,
+                    pixelWidth, pixelHeight, patch);
         }
 
-        mCache.add(description, mesh);
-    } else if (!mesh->matches(xDivs, yDivs, colorKey, transparentQuads)) {
-        PATCH_LOGD("Patch mesh does not match, refreshing vertices");
-        mesh->updateVertices(bitmapWidth, bitmapHeight, 0.0f, 0.0f, pixelWidth, pixelHeight);
+        if (vertices) {
+            setupMesh(newMesh, vertices);
+        }
+
+#if DEBUG_PATCHES
+        dumpFreeBlocks("Adding patch");
+#endif
+
+        mCache.put(description, newMesh);
+        return newMesh;
     }
 
     return mesh;
 }
 
+#if DEBUG_PATCHES
+void PatchCache::dumpFreeBlocks(const char* prefix) {
+    String8 dump;
+    BufferBlock* block = mFreeBlocks;
+    while (block) {
+        dump.appendFormat("->(%d, %d)", block->offset, block->size);
+        block = block->next;
+    }
+    ALOGD("%s: Free blocks%s", prefix, dump.string());
+}
+#endif
+
 }; // namespace uirenderer
 }; // namespace android
diff --git a/libs/hwui/PatchCache.h b/libs/hwui/PatchCache.h
index 0822cba..9f2c9a5 100644
--- a/libs/hwui/PatchCache.h
+++ b/libs/hwui/PatchCache.h
@@ -17,10 +17,16 @@
 #ifndef ANDROID_HWUI_PATCH_CACHE_H
 #define ANDROID_HWUI_PATCH_CACHE_H
 
-#include <utils/KeyedVector.h>
+#include <GLES2/gl2.h>
 
+#include <utils/LruCache.h>
+
+#include <androidfw/ResourceTypes.h>
+
+#include "AssetAtlas.h"
 #include "Debug.h"
 #include "Patch.h"
+#include "utils/Pair.h"
 
 namespace android {
 namespace uirenderer {
@@ -40,45 +46,64 @@
 // Cache
 ///////////////////////////////////////////////////////////////////////////////
 
+class Caches;
+
 class PatchCache {
 public:
     PatchCache();
-    PatchCache(uint32_t maxCapacity);
     ~PatchCache();
+    void init(Caches& caches);
 
-    Patch* get(const uint32_t bitmapWidth, const uint32_t bitmapHeight,
-            const float pixelWidth, const float pixelHeight,
-            const int32_t* xDivs, const int32_t* yDivs, const uint32_t* colors,
-            const uint32_t width, const uint32_t height, const int8_t numColors);
+    const Patch* get(const AssetAtlas::Entry* entry,
+            const uint32_t bitmapWidth, const uint32_t bitmapHeight,
+            const float pixelWidth, const float pixelHeight, const Res_png_9patch* patch);
     void clear();
 
     uint32_t getSize() const {
-        return mCache.size();
+        return mSize;
     }
 
     uint32_t getMaxSize() const {
-        return mMaxEntries;
+        return mMaxSize;
     }
 
-private:
+    GLuint getMeshBuffer() const {
+        return mMeshBuffer;
+    }
+
+    uint32_t getGenerationId() const {
+        return mGenerationId;
+    }
+
     /**
-     * Description of a patch.
+     * Removes the entries associated with the specified 9-patch. This is meant
+     * to be called from threads that are not the EGL context thread (GC thread
+     * on the VM side for instance.)
      */
+    void removeDeferred(Res_png_9patch* patch);
+
+    /**
+     * Process deferred removals.
+     */
+    void clearGarbage();
+
+
+private:
     struct PatchDescription {
-        PatchDescription(): bitmapWidth(0), bitmapHeight(0), pixelWidth(0), pixelHeight(0),
-                xCount(0), yCount(0), emptyCount(0), colorKey(0) {
+        PatchDescription(): mPatch(NULL), mBitmapWidth(0), mBitmapHeight(0),
+                mPixelWidth(0), mPixelHeight(0) {
         }
 
         PatchDescription(const uint32_t bitmapWidth, const uint32_t bitmapHeight,
-                const float pixelWidth, const float pixelHeight,
-                const uint32_t xCount, const uint32_t yCount,
-                const int8_t emptyCount, const uint32_t colorKey):
-                bitmapWidth(bitmapWidth), bitmapHeight(bitmapHeight),
-                pixelWidth(pixelWidth), pixelHeight(pixelHeight),
-                xCount(xCount), yCount(yCount),
-                emptyCount(emptyCount), colorKey(colorKey) {
+                const float pixelWidth, const float pixelHeight, const Res_png_9patch* patch):
+                mPatch(patch), mBitmapWidth(bitmapWidth), mBitmapHeight(bitmapHeight),
+                mPixelWidth(pixelWidth), mPixelHeight(pixelHeight) {
         }
 
+        hash_t hash() const;
+
+        const Res_png_9patch* getPatch() const { return mPatch; }
+
         static int compare(const PatchDescription& lhs, const PatchDescription& rhs);
 
         bool operator==(const PatchDescription& other) const {
@@ -99,21 +124,63 @@
             return PatchDescription::compare(lhs, rhs);
         }
 
+        friend inline hash_t hash_type(const PatchDescription& entry) {
+            return entry.hash();
+        }
+
     private:
-        uint32_t bitmapWidth;
-        uint32_t bitmapHeight;
-        float pixelWidth;
-        float pixelHeight;
-        uint32_t xCount;
-        uint32_t yCount;
-        int8_t emptyCount;
-        uint32_t colorKey;
+        const Res_png_9patch* mPatch;
+        uint32_t mBitmapWidth;
+        uint32_t mBitmapHeight;
+        float mPixelWidth;
+        float mPixelHeight;
 
     }; // struct PatchDescription
 
-    uint32_t mMaxEntries;
-    KeyedVector<PatchDescription, Patch*> mCache;
+    /**
+     * A buffer block represents an empty range in the mesh buffer
+     * that can be used to store vertices.
+     *
+     * The patch cache maintains a linked-list of buffer blocks
+     * to track available regions of memory in the VBO.
+     */
+    struct BufferBlock {
+        BufferBlock(uint32_t offset, uint32_t size): offset(offset), size(size), next(NULL) {
+        }
 
+        uint32_t offset;
+        uint32_t size;
+
+        BufferBlock* next;
+    }; // struct BufferBlock
+
+    typedef Pair<const PatchDescription*, Patch*> patch_pair_t;
+
+    void clearCache();
+    void createVertexBuffer();
+
+    void setupMesh(Patch* newMesh, TextureVertex* vertices);
+
+    void remove(Vector<patch_pair_t>& patchesToRemove, Res_png_9patch* patch);
+
+#if DEBUG_PATCHES
+    void dumpFreeBlocks(const char* prefix);
+#endif
+
+    uint32_t mMaxSize;
+    uint32_t mSize;
+
+    LruCache<PatchDescription, Patch*> mCache;
+
+    GLuint mMeshBuffer;
+    // First available free block inside the mesh buffer
+    BufferBlock* mFreeBlocks;
+
+    uint32_t mGenerationId;
+
+    // Garbage tracking, required to handle GC events on the VM side
+    Vector<Res_png_9patch*> mGarbage;
+    mutable Mutex mLock;
 }; // class PatchCache
 
 }; // namespace uirenderer
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
index fdb10e2..5df6408 100644
--- a/libs/hwui/PathCache.cpp
+++ b/libs/hwui/PathCache.cpp
@@ -139,7 +139,7 @@
 
 static PathTexture* createTexture(float left, float top, float offset,
         uint32_t width, uint32_t height, uint32_t id) {
-    PathTexture* texture = new PathTexture();
+    PathTexture* texture = new PathTexture(Caches::getInstance());
     texture->left = left;
     texture->top = top;
     texture->offset = offset;
@@ -214,7 +214,22 @@
 void PathCache::removeTexture(PathTexture* texture) {
     if (texture) {
         const uint32_t size = texture->width * texture->height;
-        mSize -= size;
+
+        // If there is a pending task we must wait for it to return
+        // before attempting our cleanup
+        const sp<Task<SkBitmap*> >& task = texture->task();
+        if (task != NULL) {
+            SkBitmap* bitmap = task->getResult();
+            texture->clearTask();
+        } else {
+            // If there is a pending task, the path was not added
+            // to the cache and the size wasn't increased
+            if (size > mSize) {
+                ALOGE("Removing path texture of size %d will leave "
+                        "the cache in an inconsistent state", size);
+            }
+            mSize -= size;
+        }
 
         PATH_LOGD("PathCache::delete name, size, mSize = %d, %d, %d",
                 texture->id, size, mSize);
@@ -223,7 +238,7 @@
         }
 
         if (texture->id) {
-            glDeleteTextures(1, &texture->id);
+            Caches::getInstance().deleteTexture(texture->id);
         }
         delete texture;
     }
@@ -283,6 +298,11 @@
             mCache.put(entry, texture);
         }
     } else {
+        // It's okay to add a texture that's bigger than the cache since
+        // we'll trim the cache later when addToCache is set to false
+        if (!addToCache) {
+            mSize += size;
+        }
         texture->cleanup = true;
     }
 }
@@ -300,7 +320,7 @@
 
     glGenTextures(1, &texture->id);
 
-    glBindTexture(GL_TEXTURE_2D, texture->id);
+    Caches::getInstance().bindTexture(texture->id);
     // Textures are Alpha8
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 
@@ -350,8 +370,7 @@
 // Paths
 ///////////////////////////////////////////////////////////////////////////////
 
-void PathCache::remove(const path_pair_t& pair) {
-    Vector<PathDescription> pathsToRemove;
+void PathCache::remove(Vector<PathDescription>& pathsToRemove, const path_pair_t& pair) {
     LruCache<PathDescription, PathTexture*>::Iterator i(mCache);
 
     while (i.next()) {
@@ -362,10 +381,6 @@
             pathsToRemove.push(key);
         }
     }
-
-    for (size_t i = 0; i < pathsToRemove.size(); i++) {
-        mCache.remove(pathsToRemove.itemAt(i));
-    }
 }
 
 void PathCache::removeDeferred(SkPath* path) {
@@ -374,12 +389,20 @@
 }
 
 void PathCache::clearGarbage() {
-    Mutex::Autolock l(mLock);
-    size_t count = mGarbage.size();
-    for (size_t i = 0; i < count; i++) {
-        remove(mGarbage.itemAt(i));
+    Vector<PathDescription> pathsToRemove;
+
+    { // scope for the mutex
+        Mutex::Autolock l(mLock);
+        size_t count = mGarbage.size();
+        for (size_t i = 0; i < count; i++) {
+            remove(pathsToRemove, mGarbage.itemAt(i));
+        }
+        mGarbage.clear();
     }
-    mGarbage.clear();
+
+    for (size_t i = 0; i < pathsToRemove.size(); i++) {
+        mCache.remove(pathsToRemove.itemAt(i));
+    }
 }
 
 /**
diff --git a/libs/hwui/PathCache.h b/libs/hwui/PathCache.h
index dd1f996..16d20a8 100644
--- a/libs/hwui/PathCache.h
+++ b/libs/hwui/PathCache.h
@@ -58,7 +58,7 @@
  * Alpha texture used to represent a path.
  */
 struct PathTexture: public Texture {
-    PathTexture(): Texture() {
+    PathTexture(Caches& caches): Texture(caches) {
     }
 
     ~PathTexture() {
@@ -269,7 +269,7 @@
      * Removes an entry.
      * The pair must define first=path, second=sourcePath
      */
-    void remove(const path_pair_t& pair);
+    void remove(Vector<PathDescription>& pathsToRemove, const path_pair_t& pair);
 
     /**
      * Ensures there is enough space in the cache for a texture of the specified
diff --git a/libs/hwui/PathTessellator.cpp b/libs/hwui/PathTessellator.cpp
index 0879b1b..3970913 100644
--- a/libs/hwui/PathTessellator.cpp
+++ b/libs/hwui/PathTessellator.cpp
@@ -66,11 +66,11 @@
     }
 }
 
-inline void copyVertex(Vertex* destPtr, const Vertex* srcPtr) {
+inline static void copyVertex(Vertex* destPtr, const Vertex* srcPtr) {
     Vertex::set(destPtr, srcPtr->position[0], srcPtr->position[1]);
 }
 
-inline void copyAlphaVertex(AlphaVertex* destPtr, const AlphaVertex* srcPtr) {
+inline static void copyAlphaVertex(AlphaVertex* destPtr, const AlphaVertex* srcPtr) {
     AlphaVertex::set(destPtr, srcPtr->position[0], srcPtr->position[1], srcPtr->alpha);
 }
 
@@ -84,7 +84,7 @@
  *
  * NOTE: assumes angles between normals 90 degrees or less
  */
-inline vec2 totalOffsetFromNormals(const vec2& normalA, const vec2& normalB) {
+inline static vec2 totalOffsetFromNormals(const vec2& normalA, const vec2& normalB) {
     return (normalA + normalB) / (1 + fabs(normalA.dot(normalB)));
 }
 
@@ -224,6 +224,20 @@
     DEBUG_DUMP_BUFFER();
 }
 
+static inline void storeBeginEnd(const PaintInfo& paintInfo, const Vertex& center,
+        const vec2& normal, Vertex* buffer, int& currentIndex, bool begin) {
+    vec2 strokeOffset = normal;
+    paintInfo.scaleOffsetForStrokeWidth(strokeOffset);
+
+    vec2 referencePoint(center.position[0], center.position[1]);
+    if (paintInfo.cap == SkPaint::kSquare_Cap) {
+        referencePoint += vec2(-strokeOffset.y, strokeOffset.x) * (begin ? -1 : 1);
+    }
+
+    Vertex::set(&buffer[currentIndex++], referencePoint + strokeOffset);
+    Vertex::set(&buffer[currentIndex++], referencePoint - strokeOffset);
+}
+
 /**
  * Fills a vertexBuffer with non-alpha vertices similar to getStrokeVerticesFromPerimeter, except:
  *
@@ -235,19 +249,17 @@
         const Vector<Vertex>& vertices, VertexBuffer& vertexBuffer) {
     const int extra = paintInfo.capExtraDivisions();
     const int allocSize = (vertices.size() + extra) * 2;
-
     Vertex* buffer = vertexBuffer.alloc<Vertex>(allocSize);
 
+    const int lastIndex = vertices.size() - 1;
     if (extra > 0) {
         // tessellate both round caps
-        const int last = vertices.size() - 1;
         float beginTheta = atan2(
-                - (vertices[0].position[0] - vertices[1].position[0]),
-                vertices[0].position[1] - vertices[1].position[1]);
+                    - (vertices[0].position[0] - vertices[1].position[0]),
+                    vertices[0].position[1] - vertices[1].position[1]);
         float endTheta = atan2(
-                - (vertices[last].position[0] - vertices[last - 1].position[0]),
-                vertices[last].position[1] - vertices[last - 1].position[1]);
-
+                    - (vertices[lastIndex].position[0] - vertices[lastIndex - 1].position[0]),
+                    vertices[lastIndex].position[1] - vertices[lastIndex - 1].position[1]);
         const float dTheta = PI / (extra + 1);
         const float radialScale = 2.0f / (1 + cos(dTheta));
 
@@ -270,56 +282,45 @@
             vec2 endRadialOffset(cos(endTheta), sin(endTheta));
             paintInfo.scaleOffsetForStrokeWidth(endRadialOffset);
             Vertex::set(&buffer[allocSize - 1 - capOffset],
-                    vertices[last].position[0] + endRadialOffset.x,
-                    vertices[last].position[1] + endRadialOffset.y);
+                    vertices[lastIndex].position[0] + endRadialOffset.x,
+                    vertices[lastIndex].position[1] + endRadialOffset.y);
         }
     }
 
     int currentIndex = extra;
-    const Vertex* current = &(vertices[0]);
-    vec2 lastNormal;
-    for (unsigned int i = 0; i < vertices.size() - 1; i++) {
+    const Vertex* last = &(vertices[0]);
+    const Vertex* current = &(vertices[1]);
+    vec2 lastNormal(current->position[1] - last->position[1],
+                last->position[0] - current->position[0]);
+    lastNormal.normalize();
+
+    storeBeginEnd(paintInfo, vertices[0], lastNormal, buffer, currentIndex, true);
+
+    for (unsigned int i = 1; i < vertices.size() - 1; i++) {
         const Vertex* next = &(vertices[i + 1]);
         vec2 nextNormal(next->position[1] - current->position[1],
                 current->position[0] - next->position[0]);
         nextNormal.normalize();
 
-        vec2 totalOffset;
-        if (i == 0) {
-            totalOffset = nextNormal;
-        } else {
-            totalOffset = totalOffsetFromNormals(lastNormal, nextNormal);
-        }
-        paintInfo.scaleOffsetForStrokeWidth(totalOffset);
+        vec2 strokeOffset  = totalOffsetFromNormals(lastNormal, nextNormal);
+        paintInfo.scaleOffsetForStrokeWidth(strokeOffset);
 
-        Vertex::set(&buffer[currentIndex++],
-                current->position[0] + totalOffset.x,
-                current->position[1] + totalOffset.y);
-
-        Vertex::set(&buffer[currentIndex++],
-                current->position[0] - totalOffset.x,
-                current->position[1] - totalOffset.y);
+        vec2 center(current->position[0], current->position[1]);
+        Vertex::set(&buffer[currentIndex++], center + strokeOffset);
+        Vertex::set(&buffer[currentIndex++], center - strokeOffset);
 
         current = next;
         lastNormal = nextNormal;
     }
 
-    vec2 totalOffset = lastNormal;
-    paintInfo.scaleOffsetForStrokeWidth(totalOffset);
-
-    Vertex::set(&buffer[currentIndex++],
-            current->position[0] + totalOffset.x,
-            current->position[1] + totalOffset.y);
-    Vertex::set(&buffer[currentIndex++],
-            current->position[0] - totalOffset.x,
-            current->position[1] - totalOffset.y);
+    storeBeginEnd(paintInfo, vertices[lastIndex], lastNormal, buffer, currentIndex, false);
 
     DEBUG_DUMP_BUFFER();
 }
 
 /**
  * Populates a vertexBuffer with AlphaVertices to create an anti-aliased fill shape tessellation
- * 
+ *
  * 1 - create the AA perimeter of unit width, by zig-zagging at each point around the perimeter of
  * the shape (using 2 * perimeter.size() vertices)
  *
@@ -389,7 +390,7 @@
  * For explanation of constants and general methodoloyg, see comments for
  * getStrokeVerticesFromUnclosedVerticesAA() below.
  */
-inline void storeCapAA(const PaintInfo& paintInfo, const Vector<Vertex>& vertices,
+inline static void storeCapAA(const PaintInfo& paintInfo, const Vector<Vertex>& vertices,
         AlphaVertex* buffer, bool isFirst, vec2 normal, int offset) {
     const int extra = paintInfo.capExtraDivisions();
     const int extraOffset = (extra + 1) / 2;
@@ -772,11 +773,67 @@
     }
 }
 
+static void expandRectToCoverVertex(SkRect& rect, float x, float y) {
+    rect.fLeft = fminf(rect.fLeft, x);
+    rect.fTop = fminf(rect.fTop, y);
+    rect.fRight = fmaxf(rect.fRight, x);
+    rect.fBottom = fmaxf(rect.fBottom, y);
+}
 static void expandRectToCoverVertex(SkRect& rect, const Vertex& vertex) {
-    rect.fLeft = fminf(rect.fLeft, vertex.position[0]);
-    rect.fTop = fminf(rect.fTop, vertex.position[1]);
-    rect.fRight = fmaxf(rect.fRight, vertex.position[0]);
-    rect.fBottom = fmaxf(rect.fBottom, vertex.position[1]);
+    expandRectToCoverVertex(rect, vertex.position[0], vertex.position[1]);
+}
+
+template <class TYPE>
+static void instanceVertices(VertexBuffer& srcBuffer, VertexBuffer& dstBuffer,
+        const float* points, int count, SkRect& bounds) {
+    bounds.set(points[0], points[1], points[0], points[1]);
+
+    int numPoints = count / 2;
+    int verticesPerPoint = srcBuffer.getVertexCount();
+    dstBuffer.alloc<TYPE>(numPoints * verticesPerPoint + (numPoints - 1) * 2);
+
+    for (int i = 0; i < count; i += 2) {
+        expandRectToCoverVertex(bounds, points[i + 0], points[i + 1]);
+        dstBuffer.copyInto<TYPE>(srcBuffer, points[i + 0], points[i + 1]);
+    }
+    dstBuffer.createDegenerateSeparators<TYPE>(verticesPerPoint);
+}
+
+void PathTessellator::tessellatePoints(const float* points, int count, SkPaint* paint,
+        const mat4* transform, SkRect& bounds, VertexBuffer& vertexBuffer) {
+    const PaintInfo paintInfo(paint, transform);
+
+    // determine point shape
+    SkPath path;
+    float radius = paintInfo.halfStrokeWidth;
+    if (radius == 0.0f) radius = 0.25f;
+
+    if (paintInfo.cap == SkPaint::kRound_Cap) {
+        path.addCircle(0, 0, radius);
+    } else {
+        path.addRect(-radius, -radius, radius, radius);
+    }
+
+    // calculate outline
+    Vector<Vertex> outlineVertices;
+    approximatePathOutlineVertices(path, true,
+            paintInfo.inverseScaleX * paintInfo.inverseScaleX,
+            paintInfo.inverseScaleY * paintInfo.inverseScaleY, outlineVertices);
+
+    if (!outlineVertices.size()) return;
+
+    // tessellate, then duplicate outline across points
+    int numPoints = count / 2;
+    VertexBuffer tempBuffer;
+    if (!paintInfo.isAA) {
+        getFillVerticesFromPerimeter(outlineVertices, tempBuffer);
+        instanceVertices<Vertex>(tempBuffer, vertexBuffer, points, count, bounds);
+    } else {
+        getFillVerticesFromPerimeterAA(paintInfo, outlineVertices, tempBuffer);
+        instanceVertices<AlphaVertex>(tempBuffer, vertexBuffer, points, count, bounds);
+    }
+
+    expandBoundsForStroke(bounds, paint, true); // force-expand bounds to incorporate stroke
 }
 
 void PathTessellator::tessellateLines(const float* points, int count, SkPaint* paint,
diff --git a/libs/hwui/PathTessellator.h b/libs/hwui/PathTessellator.h
index 596d49d..85797fc 100644
--- a/libs/hwui/PathTessellator.h
+++ b/libs/hwui/PathTessellator.h
@@ -30,7 +30,7 @@
 public:
     VertexBuffer():
         mBuffer(0),
-        mSize(0),
+        mVertexCount(0),
         mCleanupMethod(NULL)
     {}
 
@@ -44,30 +44,42 @@
        multiple regions within a single VertexBuffer, such as with PathTessellator::tesselateLines()
      */
     template <class TYPE>
-    TYPE* alloc(int size) {
-        if (mSize) {
+    TYPE* alloc(int vertexCount) {
+        if (mVertexCount) {
             TYPE* reallocBuffer = (TYPE*)mReallocBuffer;
             // already have allocated the buffer, re-allocate space within
             if (mReallocBuffer != mBuffer) {
                 // not first re-allocation, leave space for degenerate triangles to separate strips
                 reallocBuffer += 2;
             }
-            mReallocBuffer = reallocBuffer + size;
+            mReallocBuffer = reallocBuffer + vertexCount;
             return reallocBuffer;
         }
-        mSize = size;
-        mReallocBuffer = mBuffer = (void*)new TYPE[size];
+        mVertexCount = vertexCount;
+        mReallocBuffer = mBuffer = (void*)new TYPE[vertexCount];
         mCleanupMethod = &(cleanup<TYPE>);
 
         return (TYPE*)mBuffer;
     }
 
-    void* getBuffer() const { return mBuffer; }
-    unsigned int getSize() const { return mSize; }
+    template <class TYPE>
+    void copyInto(const VertexBuffer& srcBuffer, float xOffset, float yOffset) {
+        int verticesToCopy = srcBuffer.getVertexCount();
+
+        TYPE* dst = alloc<TYPE>(verticesToCopy);
+        TYPE* src = (TYPE*)srcBuffer.getBuffer();
+
+        for (int i = 0; i < verticesToCopy; i++) {
+            TYPE::copyWithOffset(&dst[i], src[i], xOffset, yOffset);
+        }
+    }
+
+    void* getBuffer() const { return mBuffer; } // shouldn't be const, since not a const ptr?
+    unsigned int getVertexCount() const { return mVertexCount; }
 
     template <class TYPE>
     void createDegenerateSeparators(int allocSize) {
-        TYPE* end = (TYPE*)mBuffer + mSize;
+        TYPE* end = (TYPE*)mBuffer + mVertexCount;
         for (TYPE* degen = (TYPE*)mBuffer + allocSize; degen < end; degen += 2 + allocSize) {
             memcpy(degen, degen - 1, sizeof(TYPE));
             memcpy(degen + 1, degen + 2, sizeof(TYPE));
@@ -81,7 +93,7 @@
     }
 
     void* mBuffer;
-    unsigned int mSize;
+    unsigned int mVertexCount;
 
     void* mReallocBuffer; // used for multi-allocation
 
@@ -95,6 +107,9 @@
     static void tessellatePath(const SkPath& path, const SkPaint* paint,
             const mat4 *transform, VertexBuffer& vertexBuffer);
 
+    static void tessellatePoints(const float* points, int count, SkPaint* paint,
+            const mat4* transform, SkRect& bounds, VertexBuffer& vertexBuffer);
+
     static void tessellateLines(const float* points, int count, SkPaint* paint,
             const mat4* transform, SkRect& bounds, VertexBuffer& vertexBuffer);
 
diff --git a/libs/hwui/PixelBuffer.cpp b/libs/hwui/PixelBuffer.cpp
index 8280370..36e89c6 100644
--- a/libs/hwui/PixelBuffer.cpp
+++ b/libs/hwui/PixelBuffer.cpp
@@ -19,6 +19,7 @@
 #include <utils/Log.h>
 
 #include "Caches.h"
+#include "Debug.h"
 #include "Extensions.h"
 #include "PixelBuffer.h"
 #include "Properties.h"
@@ -113,6 +114,14 @@
     if (mAccessMode == kAccessMode_None) {
         mCaches.bindPixelBuffer(mBuffer);
         mMappedPointer = (uint8_t*) glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, getSize(), mode);
+#if DEBUG_OPENGL
+        if (!mMappedPointer) {
+            GLenum status = GL_NO_ERROR;
+            while ((status = glGetError()) != GL_NO_ERROR) {
+                ALOGE("Could not map GPU pixel buffer: 0x%x", status);
+            }
+        }
+#endif
         mAccessMode = mode;
     }
 
@@ -123,7 +132,10 @@
     if (mAccessMode != kAccessMode_None) {
         if (mMappedPointer) {
             mCaches.bindPixelBuffer(mBuffer);
-            glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
+            GLboolean status = glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
+            if (status == GL_FALSE) {
+                ALOGE("Corrupted GPU pixel buffer");
+            }
         }
         mAccessMode = kAccessMode_None;
         mMappedPointer = NULL;
@@ -147,14 +159,8 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 PixelBuffer* PixelBuffer::create(GLenum format, uint32_t width, uint32_t height, BufferType type) {
-    bool gpuBuffer = type == kBufferType_Auto && Extensions::getInstance().getMajorGlVersion() >= 3;
-    if (gpuBuffer) {
-        char property[PROPERTY_VALUE_MAX];
-        if (property_get(PROPERTY_ENABLE_GPU_PIXEL_BUFFERS, property, "false") > 0) {
-            if (!strcmp(property, "true")) {
-                return new GpuPixelBuffer(format, width, height);
-            }
-        }
+    if (type == kBufferType_Auto && Caches::getInstance().gpuPixelBuffersEnabled) {
+        return new GpuPixelBuffer(format, width, height);
     }
     return new CpuPixelBuffer(format, width, height);
 }
diff --git a/libs/hwui/PixelBuffer.h b/libs/hwui/PixelBuffer.h
index 32d5417..9725a61 100644
--- a/libs/hwui/PixelBuffer.h
+++ b/libs/hwui/PixelBuffer.h
@@ -112,13 +112,25 @@
     virtual uint8_t* getMappedPointer() const = 0;
 
     /**
-     * Upload the specified rectangle of this pixe buffer as a
+     * Upload the specified rectangle of this pixel buffer as a
      * GL_TEXTURE_2D texture. Calling this method will trigger
      * an unmap() if necessary.
      */
     virtual void upload(uint32_t x, uint32_t y, uint32_t width, uint32_t height, int offset) = 0;
 
     /**
+     * Upload the specified rectangle of this pixel buffer as a
+     * GL_TEXTURE_2D texture. Calling this method will trigger
+     * an unmap() if necessary.
+     *
+     * This is a convenience function provided to save callers the
+     * trouble of computing the offset parameter.
+     */
+    void upload(uint32_t x, uint32_t y, uint32_t width, uint32_t height) {
+        upload(x, y, width, height, getOffset(x, y));
+    }
+
+    /**
      * Returns the width of the render buffer in pixels.
      */
     uint32_t getWidth() const {
@@ -140,6 +152,13 @@
     }
 
     /**
+     * Returns the offset of a pixel in this pixel buffer, in bytes.
+     */
+    uint32_t getOffset(uint32_t x, uint32_t y) const {
+        return (y * mWidth + x) * formatSize(mFormat);
+    }
+
+    /**
      * Returns the number of bytes per pixel in the specified format.
      *
      * Supported formats:
diff --git a/libs/hwui/Program.cpp b/libs/hwui/Program.cpp
index 14a2376..9e4670e 100644
--- a/libs/hwui/Program.cpp
+++ b/libs/hwui/Program.cpp
@@ -15,6 +15,9 @@
  */
 
 #define LOG_TAG "OpenGLRenderer"
+#define ATRACE_TAG ATRACE_TAG_VIEW
+
+#include <utils/Trace.h>
 
 #include "Program.h"
 
@@ -25,7 +28,6 @@
 // Base program
 ///////////////////////////////////////////////////////////////////////////////
 
-// TODO: Program instance should be created from a factory method
 Program::Program(const ProgramDescription& description, const char* vertex, const char* fragment) {
     mInitialized = false;
     mHasColorUniform = false;
@@ -50,7 +52,9 @@
                 texCoords = -1;
             }
 
+            ATRACE_BEGIN("linkProgram");
             glLinkProgram(mProgramId);
+            ATRACE_END();
 
             GLint status;
             glGetProgramiv(mProgramId, GL_LINK_STATUS, &status);
@@ -87,6 +91,9 @@
 
 Program::~Program() {
     if (mInitialized) {
+        // This would ideally happen after linking the program
+        // but Tegra drivers, especially when perfhud is enabled,
+        // sometimes crash if we do so
         glDetachShader(mProgramId, mVertexShader);
         glDetachShader(mProgramId, mFragmentShader);
 
@@ -132,6 +139,8 @@
 }
 
 GLuint Program::buildShader(const char* source, GLenum type) {
+    ATRACE_CALL();
+
     GLuint shader = glCreateShader(type);
     glShaderSource(shader, 1, &source, 0);
     glCompileShader(shader);
@@ -153,20 +162,24 @@
 
 void Program::set(const mat4& projectionMatrix, const mat4& modelViewMatrix,
         const mat4& transformMatrix, bool offset) {
-    mat4 p(projectionMatrix);
-    if (offset) {
-        // offset screenspace xy by an amount that compensates for typical precision
-        // issues in GPU hardware that tends to paint hor/vert lines in pixels shifted
-        // up and to the left.
-        // This offset value is based on an assumption that some hardware may use as
-        // little as 12.4 precision, so we offset by slightly more than 1/16.
-        p.translate(.065, .065, 0);
+    if (projectionMatrix != mProjection) {
+        if (CC_LIKELY(!offset)) {
+            glUniformMatrix4fv(projection, 1, GL_FALSE, &projectionMatrix.data[0]);
+        } else {
+            mat4 p(projectionMatrix);
+            // offset screenspace xy by an amount that compensates for typical precision
+            // issues in GPU hardware that tends to paint hor/vert lines in pixels shifted
+            // up and to the left.
+            // This offset value is based on an assumption that some hardware may use as
+            // little as 12.4 precision, so we offset by slightly more than 1/16.
+            p.translate(.065, .065);
+            glUniformMatrix4fv(projection, 1, GL_FALSE, &p.data[0]);
+        }
+        mProjection = projectionMatrix;
     }
 
     mat4 t(transformMatrix);
     t.multiply(modelViewMatrix);
-
-    glUniformMatrix4fv(projection, 1, GL_FALSE, &p.data[0]);
     glUniformMatrix4fv(transform, 1, GL_FALSE, &t.data[0]);
 }
 
diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h
index e8b6d47..4f94afc 100644
--- a/libs/hwui/Program.h
+++ b/libs/hwui/Program.h
@@ -68,23 +68,22 @@
 #define PROGRAM_BITMAP_WRAPS_SHIFT 9
 #define PROGRAM_BITMAP_WRAPT_SHIFT 11
 
-#define PROGRAM_GRADIENT_TYPE_SHIFT 33
+#define PROGRAM_GRADIENT_TYPE_SHIFT 33 // 2 bits for gradient type
 #define PROGRAM_MODULATE_SHIFT 35
 
-#define PROGRAM_IS_POINT_SHIFT 36
+#define PROGRAM_HAS_AA_SHIFT 36
 
-#define PROGRAM_HAS_AA_SHIFT 37
+#define PROGRAM_HAS_EXTERNAL_TEXTURE_SHIFT 37
+#define PROGRAM_HAS_TEXTURE_TRANSFORM_SHIFT 38
 
-#define PROGRAM_HAS_EXTERNAL_TEXTURE_SHIFT 38
-#define PROGRAM_HAS_TEXTURE_TRANSFORM_SHIFT 39
+#define PROGRAM_HAS_GAMMA_CORRECTION 39
 
-#define PROGRAM_HAS_GAMMA_CORRECTION 40
+#define PROGRAM_IS_SIMPLE_GRADIENT 40
 
-#define PROGRAM_IS_SIMPLE_GRADIENT 41
+#define PROGRAM_HAS_COLORS 41
 
-#define PROGRAM_HAS_COLORS 42
-
-#define PROGRAM_HAS_DEBUG_HIGHLIGHT 43
+#define PROGRAM_HAS_DEBUG_HIGHLIGHT 42
+#define PROGRAM_EMULATE_STENCIL 43
 
 ///////////////////////////////////////////////////////////////////////////////
 // Types
@@ -156,13 +155,11 @@
     SkXfermode::Mode framebufferMode;
     bool swapSrcDst;
 
-    bool isPoint;
-    float pointSize;
-
     bool hasGammaCorrection;
     float gamma;
 
     bool hasDebugHighlight;
+    bool emulateStencil;
 
     /**
      * Resets this description. All fields are reset back to the default
@@ -199,9 +196,6 @@
         framebufferMode = SkXfermode::kClear_Mode;
         swapSrcDst = false;
 
-        isPoint = false;
-        pointSize = 0.0f;
-
         hasGammaCorrection = false;
         gamma = 2.2f;
 
@@ -267,7 +261,6 @@
         key |= (framebufferMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_FRAMEBUFFER_SHIFT;
         if (swapSrcDst) key |= PROGRAM_KEY_SWAP_SRC_DST;
         if (modulate) key |= programid(0x1) << PROGRAM_MODULATE_SHIFT;
-        if (isPoint) key |= programid(0x1) << PROGRAM_IS_POINT_SHIFT;
         if (isAA) key |= programid(0x1) << PROGRAM_HAS_AA_SHIFT;
         if (hasExternalTexture) key |= programid(0x1) << PROGRAM_HAS_EXTERNAL_TEXTURE_SHIFT;
         if (hasTextureTransform) key |= programid(0x1) << PROGRAM_HAS_TEXTURE_TRANSFORM_SHIFT;
@@ -275,6 +268,7 @@
         if (isSimpleGradient) key |= programid(0x1) << PROGRAM_IS_SIMPLE_GRADIENT;
         if (hasColors) key |= programid(0x1) << PROGRAM_HAS_COLORS;
         if (hasDebugHighlight) key |= programid(0x1) << PROGRAM_HAS_DEBUG_HIGHLIGHT;
+        if (emulateStencil) key |= programid(0x1) << PROGRAM_EMULATE_STENCIL;
         return key;
     }
 
@@ -430,10 +424,13 @@
     bool mUse;
     bool mInitialized;
 
+    // Uniforms caching
     bool mHasColorUniform;
     int mColorUniform;
 
     bool mHasSampler;
+
+    mat4 mProjection;
 }; // class Program
 
 }; // namespace uirenderer
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index 8eb85e5..a5ce6f6 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -53,8 +53,6 @@
 const char* gVS_Header_Uniforms =
         "uniform mat4 projection;\n" \
         "uniform mat4 transform;\n";
-const char* gVS_Header_Uniforms_IsPoint =
-        "uniform mediump float pointSize;\n";
 const char* gVS_Header_Uniforms_HasGradient =
         "uniform mat4 screenSpace;\n";
 const char* gVS_Header_Uniforms_HasBitmap =
@@ -68,8 +66,6 @@
         "varying float alpha;\n";
 const char* gVS_Header_Varyings_HasBitmap =
         "varying highp vec2 outBitmapTexCoords;\n";
-const char* gVS_Header_Varyings_PointHasBitmap =
-        "varying highp vec2 outPointBitmapTexCoords;\n";
 const char* gVS_Header_Varyings_HasGradient[6] = {
         // Linear
         "varying highp vec2 linear;\n"
@@ -118,12 +114,8 @@
 };
 const char* gVS_Main_OutBitmapTexCoords =
         "    outBitmapTexCoords = (textureTransform * position).xy * textureDimension;\n";
-const char* gVS_Main_OutPointBitmapTexCoords =
-        "    outPointBitmapTexCoords = (textureTransform * position).xy * textureDimension;\n";
 const char* gVS_Main_Position =
         "    gl_Position = projection * transform * position;\n";
-const char* gVS_Main_PointSize =
-        "    gl_PointSize = pointSize;\n";
 const char* gVS_Main_AAVertexShape =
         "    alpha = vtxAlpha;\n";
 const char* gVS_Footer =
@@ -141,9 +133,6 @@
         "precision mediump float;\n\n";
 const char* gFS_Uniforms_Color =
         "uniform vec4 color;\n";
-const char* gFS_Header_Uniforms_PointHasBitmap =
-        "uniform vec2 textureDimension;\n"
-        "uniform float pointSize;\n";
 const char* gFS_Uniforms_TextureSampler =
         "uniform sampler2D baseSampler;\n";
 const char* gFS_Uniforms_ExternalTextureSampler =
@@ -178,10 +167,6 @@
         "\nvoid main(void) {\n"
         "    lowp vec4 fragColor;\n";
 
-const char* gFS_Main_PointBitmapTexCoords =
-        "    highp vec2 outBitmapTexCoords = outPointBitmapTexCoords + "
-        "((gl_PointCoord - vec2(0.5, 0.5)) * textureDimension * vec2(pointSize, pointSize));\n";
-
 const char* gFS_Main_Dither[2] = {
         // ES 2.0
         "texture2D(ditherSampler, ditherTexCoords).a * " STR(DITHER_KERNEL_SIZE_INV_SQUARE),
@@ -342,6 +327,12 @@
 };
 const char* gFS_Main_DebugHighlight =
         "    gl_FragColor.rgb = vec3(0.0, gl_FragColor.a, 0.0);\n";
+const char* gFS_Main_EmulateStencil =
+        "    gl_FragColor.rgba = vec4(1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0, 1.0);\n"
+        "    return;\n"
+        "    /*\n";
+const char* gFS_Footer_EmulateStencil =
+        "    */\n";
 const char* gFS_Footer =
         "}\n\n";
 
@@ -478,9 +469,6 @@
     if (description.hasBitmap) {
         shader.append(gVS_Header_Uniforms_HasBitmap);
     }
-    if (description.isPoint) {
-        shader.append(gVS_Header_Uniforms_IsPoint);
-    }
     // Varyings
     if (description.hasTexture || description.hasExternalTexture) {
         shader.append(gVS_Header_Varyings_HasTexture);
@@ -495,9 +483,7 @@
         shader.append(gVS_Header_Varyings_HasGradient[gradientIndex(description)]);
     }
     if (description.hasBitmap) {
-        shader.append(description.isPoint ?
-                gVS_Header_Varyings_PointHasBitmap :
-                gVS_Header_Varyings_HasBitmap);
+        shader.append(gVS_Header_Varyings_HasBitmap);
     }
 
     // Begin the shader
@@ -514,12 +500,7 @@
             shader.append(gVS_Main_OutColors);
         }
         if (description.hasBitmap) {
-            shader.append(description.isPoint ?
-                    gVS_Main_OutPointBitmapTexCoords :
-                    gVS_Main_OutBitmapTexCoords);
-        }
-        if (description.isPoint) {
-            shader.append(gVS_Main_PointSize);
+            shader.append(gVS_Main_OutBitmapTexCoords);
         }
         // Output transformed position
         shader.append(gVS_Main_Position);
@@ -570,9 +551,7 @@
         shader.append(gVS_Header_Varyings_HasGradient[gradientIndex(description)]);
     }
     if (description.hasBitmap) {
-        shader.append(description.isPoint ?
-                gVS_Header_Varyings_PointHasBitmap :
-                gVS_Header_Varyings_HasBitmap);
+        shader.append(gVS_Header_Varyings_HasBitmap);
     }
 
     // Uniforms
@@ -593,9 +572,6 @@
         shader.appendFormat(gFS_Uniforms_GradientSampler[description.isSimpleGradient],
                 gFS_Uniforms_Dither);
     }
-    if (description.hasBitmap && description.isPoint) {
-        shader.append(gFS_Header_Uniforms_PointHasBitmap);
-    }
     if (description.hasGammaCorrection) {
         shader.append(gFS_Uniforms_Gamma);
     }
@@ -603,7 +579,7 @@
     // Optimization for common cases
     if (!description.isAA && !blendFramebuffer && !description.hasColors &&
             description.colorOp == ProgramDescription::kColorNone &&
-            !description.isPoint && !description.hasDebugHighlight) {
+            !description.hasDebugHighlight && !description.emulateStencil) {
         bool fast = false;
 
         const bool noShader = !description.hasGradient && !description.hasBitmap;
@@ -683,6 +659,9 @@
 
     // Begin the shader
     shader.append(gFS_Main); {
+        if (description.emulateStencil) {
+            shader.append(gFS_Main_EmulateStencil);
+        }
         // Stores the result in fragColor directly
         if (description.hasTexture || description.hasExternalTexture) {
             if (description.hasAlpha8Texture) {
@@ -703,9 +682,6 @@
             shader.appendFormat(gFS_Main_AddDitherToGradient, gFS_Main_Dither[mHasES3]);
         }
         if (description.hasBitmap) {
-            if (description.isPoint) {
-                shader.append(gFS_Main_PointBitmapTexCoords);
-            }
             if (!description.isBitmapNpot) {
                 shader.append(gFS_Main_FetchBitmap);
             } else {
@@ -757,6 +733,9 @@
             shader.append(gFS_Main_DebugHighlight);
         }
     }
+    if (description.emulateStencil) {
+        shader.append(gFS_Footer_EmulateStencil);
+    }
     // End the shader
     shader.append(gFS_Footer);
 
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 6eea00c..20b8f2f 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -70,10 +70,23 @@
 #define PROPERTY_DEBUG_LAYERS_UPDATES "debug.hwui.show_layers_updates"
 
 /**
- * Used to enable/disable overdraw debugging. The accepted values are
- * "true" and "false". The default value is "false".
+ * Used to enable/disable overdraw debugging.
+ *
+ * The accepted values are
+ * "show", to show overdraw
+ * "show_deuteranomaly", to show overdraw if you suffer from Deuteranomaly
+ * "count", to show an overdraw counter
+ * "false", to disable overdraw debugging
+ *
+ * The default value is "false".
  */
-#define PROPERTY_DEBUG_OVERDRAW "debug.hwui.show_overdraw"
+#define PROPERTY_DEBUG_OVERDRAW "debug.hwui.overdraw"
+
+/**
+ * Used to enable/disable PerfHUD ES profiling. The accepted values
+ * are "true" and "false". The default value is "false".
+ */
+#define PROPERTY_DEBUG_NV_PROFILING "debug.hwui.nv_profiling"
 
 /**
  * Used to enable/disable non-rectangular clipping debugging.
@@ -123,9 +136,9 @@
 
 /**
  * Indicates whether PBOs can be used to back pixel buffers.
- * Accepted values are "true" and "false".
+ * Accepted values are "true" and "false". Default is true.
  */
-#define PROPERTY_ENABLE_GPU_PIXEL_BUFFERS "hwui.use_gpu_pixel_buffers"
+#define PROPERTY_ENABLE_GPU_PIXEL_BUFFERS "ro.hwui.use_gpu_pixel_buffers"
 
 // These properties are defined in mega-bytes
 #define PROPERTY_TEXTURE_CACHE_SIZE "ro.hwui.texture_cache_size"
@@ -133,6 +146,7 @@
 #define PROPERTY_RENDER_BUFFER_CACHE_SIZE "ro.hwui.r_buffer_cache_size"
 #define PROPERTY_GRADIENT_CACHE_SIZE "ro.hwui.gradient_cache_size"
 #define PROPERTY_PATH_CACHE_SIZE "ro.hwui.path_cache_size"
+#define PROPERTY_PATCH_CACHE_SIZE "ro.hwui.patch_cache_size"
 #define PROPERTY_DROP_SHADOW_CACHE_SIZE "ro.hwui.drop_shadow_cache_size"
 #define PROPERTY_FBO_CACHE_SIZE "ro.hwui.fbo_cache_size"
 
@@ -178,7 +192,7 @@
 #define DEFAULT_LAYER_CACHE_SIZE 16.0f
 #define DEFAULT_RENDER_BUFFER_CACHE_SIZE 2.0f
 #define DEFAULT_PATH_CACHE_SIZE 10.0f
-#define DEFAULT_PATCH_CACHE_SIZE 512
+#define DEFAULT_PATCH_CACHE_SIZE 128 // in kB
 #define DEFAULT_GRADIENT_CACHE_SIZE 0.5f
 #define DEFAULT_DROP_SHADOW_CACHE_SIZE 2.0f
 #define DEFAULT_FBO_CACHE_SIZE 16
@@ -195,6 +209,8 @@
 
 // Converts a number of mega-bytes into bytes
 #define MB(s) s * 1024 * 1024
+// Converts a number of kilo-bytes into bytes
+#define KB(s) s * 1024
 
 static DebugLevel readDebugLevel() {
     char property[PROPERTY_VALUE_MAX];
diff --git a/libs/hwui/Query.h b/libs/hwui/Query.h
new file mode 100644
index 0000000..e25b16b
--- /dev/null
+++ b/libs/hwui/Query.h
@@ -0,0 +1,152 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HWUI_QUERY_H
+#define ANDROID_HWUI_QUERY_H
+
+#include <GLES3/gl3.h>
+
+#include "Extensions.h"
+
+namespace android {
+namespace uirenderer {
+
+/**
+ * A Query instance can be used to perform occlusion queries. If the device
+ * does not support occlusion queries, the result of a query will always be
+ * 0 and the result will always be marked available.
+ *
+ * To run an occlusion query successfully, you must start end end the query:
+ *
+ * Query query;
+ * query.begin();
+ * // execute OpenGL calls
+ * query.end();
+ * GLuint result = query.getResult();
+ */
+class Query {
+public:
+    /**
+     * Possible query targets.
+     */
+    enum Target {
+        /**
+         * Indicates if any sample passed the depth & stencil tests.
+         */
+        kTargetSamples = GL_ANY_SAMPLES_PASSED,
+        /**
+         * Indicates if any sample passed the depth & stencil tests.
+         * The implementation may choose to use a less precise version
+         * of the test, potentially resulting in false positives.
+         */
+        kTargetConservativeSamples = GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
+    };
+
+    /**
+     * Creates a new query with the specified target. The default
+     * target is kTargetSamples (of GL_ANY_SAMPLES_PASSED in OpenGL.)
+     */
+    Query(Target target = kTargetSamples): mActive(false), mTarget(target),
+            mCanQuery(Extensions::getInstance().hasOcclusionQueries()),
+            mQuery(0) {
+    }
+
+    ~Query() {
+        if (mQuery) {
+            glDeleteQueries(1, &mQuery);
+        }
+    }
+
+    /**
+     * Begins the query. If the query has already begun or if the device
+     * does not support occlusion queries, calling this method as no effect.
+     * After calling this method successfully, the query is marked active.
+     */
+    void begin() {
+        if (!mActive && mCanQuery) {
+            if (!mQuery) {
+                glGenQueries(1, &mQuery);
+            }
+
+            glBeginQuery(mTarget, mQuery);
+            mActive = true;
+        }
+    }
+
+    /**
+     * Ends the query. If the query has already begun or if the device
+     * does not support occlusion queries, calling this method as no effect.
+     * After calling this method successfully, the query is marked inactive.
+     */
+    void end() {
+        if (mQuery && mActive) {
+            glEndQuery(mTarget);
+            mActive = false;
+        }
+    }
+
+    /**
+     * Returns true if the query is active, false otherwise.
+     */
+    bool isActive() {
+        return mActive;
+    }
+
+    /**
+     * Returns true if the result of the query is available,
+     * false otherwise. Calling getResult() before the result
+     * is available may result in the calling thread being blocked.
+     * If the device does not support queries, this method always
+     * returns true.
+     */
+    bool isResultAvailable() {
+        if (!mQuery) return true;
+
+        GLuint result;
+        glGetQueryObjectuiv(mQuery, GL_QUERY_RESULT_AVAILABLE, &result);
+        return result == GL_TRUE;
+    }
+
+    /**
+     * Returns the result of the query. If the device does not
+     * support queries this method will return 0.
+     *
+     * Calling this method implicitely calls end() if the query
+     * is currently active.
+     */
+    GLuint getResult() {
+        if (!mQuery) return 0;
+
+        end();
+
+        GLuint result;
+        glGetQueryObjectuiv(mQuery, GL_QUERY_RESULT, &result);
+        return result;
+    }
+
+
+private:
+    bool mActive;
+    GLenum mTarget;
+    bool mCanQuery;
+    GLuint mQuery;
+
+}; // class Query
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_HWUI_QUERY_H
diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h
index f50ac3c..7605307 100644
--- a/libs/hwui/Rect.h
+++ b/libs/hwui/Rect.h
@@ -24,6 +24,10 @@
 namespace android {
 namespace uirenderer {
 
+#define RECT_STRING "%7.2f %7.2f %7.2f %7.2f"
+#define RECT_ARGS(r) \
+    (r).left, (r).top, (r).right, (r).bottom
+
 ///////////////////////////////////////////////////////////////////////////////
 // Structs
 ///////////////////////////////////////////////////////////////////////////////
@@ -125,11 +129,11 @@
         return intersect(r.left, r.top, r.right, r.bottom);
     }
 
-    inline bool contains(float l, float t, float r, float b) {
+    inline bool contains(float l, float t, float r, float b) const {
         return l >= left && t >= top && r <= right && b <= bottom;
     }
 
-    inline bool contains(const Rect& r) {
+    inline bool contains(const Rect& r) const {
         return contains(r.left, r.top, r.right, r.bottom);
     }
 
@@ -166,6 +170,20 @@
         bottom += delta;
     }
 
+    /**
+     * Similar to snapToPixelBoundaries, but used for AA geometry with a ramp perimeter.
+     *
+     * We inset the data by a fudge factor of slightly over 1/16 (similar to when drawing non-AA
+     * lines) before rounding out so that insignificant amounts of ramp geometry (esp. from rounding
+     * errors) are ignored.
+     */
+    void snapOutToPixelBoundaries() {
+        left = floorf(left + 0.065f);
+        top = floorf(top + 0.065f);
+        right = ceilf(right - 0.065f);
+        bottom = ceilf(bottom - 0.065f);
+    }
+
     void snapToPixelBoundaries() {
         left = floorf(left + 0.5f);
         top = floorf(top + 0.5f);
diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp
index 347bd78..3f77021 100644
--- a/libs/hwui/ResourceCache.cpp
+++ b/libs/hwui/ResourceCache.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "OpenGLRenderer"
+
 #include <SkPixelRef.h>
 #include "ResourceCache.h"
 #include "Caches.h"
@@ -60,7 +62,7 @@
 }
 
 void ResourceCache::incrementRefcount(SkBitmap* bitmapResource) {
-    SkSafeRef(bitmapResource->pixelRef());
+    bitmapResource->pixelRef()->globalRef();
     SkSafeRef(bitmapResource->getColorTable());
     incrementRefcount((void*) bitmapResource, kBitmap);
 }
@@ -79,6 +81,10 @@
     incrementRefcount((void*) filterResource, kColorFilter);
 }
 
+void ResourceCache::incrementRefcount(Res_png_9patch* patchResource) {
+    incrementRefcount((void*) patchResource, kNinePatch);
+}
+
 void ResourceCache::incrementRefcount(Layer* layerResource) {
     incrementRefcount((void*) layerResource, kLayer);
 }
@@ -94,7 +100,7 @@
 }
 
 void ResourceCache::incrementRefcountLocked(SkBitmap* bitmapResource) {
-    SkSafeRef(bitmapResource->pixelRef());
+    bitmapResource->pixelRef()->globalRef();
     SkSafeRef(bitmapResource->getColorTable());
     incrementRefcountLocked((void*) bitmapResource, kBitmap);
 }
@@ -113,6 +119,10 @@
     incrementRefcountLocked((void*) filterResource, kColorFilter);
 }
 
+void ResourceCache::incrementRefcountLocked(Res_png_9patch* patchResource) {
+    incrementRefcountLocked((void*) patchResource, kNinePatch);
+}
+
 void ResourceCache::incrementRefcountLocked(Layer* layerResource) {
     incrementRefcountLocked((void*) layerResource, kLayer);
 }
@@ -123,7 +133,7 @@
 }
 
 void ResourceCache::decrementRefcount(SkBitmap* bitmapResource) {
-    SkSafeUnref(bitmapResource->pixelRef());
+    bitmapResource->pixelRef()->globalUnref();
     SkSafeUnref(bitmapResource->getColorTable());
     decrementRefcount((void*) bitmapResource);
 }
@@ -142,6 +152,10 @@
     decrementRefcount((void*) filterResource);
 }
 
+void ResourceCache::decrementRefcount(Res_png_9patch* patchResource) {
+    decrementRefcount((void*) patchResource);
+}
+
 void ResourceCache::decrementRefcount(Layer* layerResource) {
     decrementRefcount((void*) layerResource);
 }
@@ -160,7 +174,7 @@
 }
 
 void ResourceCache::decrementRefcountLocked(SkBitmap* bitmapResource) {
-    SkSafeUnref(bitmapResource->pixelRef());
+    bitmapResource->pixelRef()->globalUnref();
     SkSafeUnref(bitmapResource->getColorTable());
     decrementRefcountLocked((void*) bitmapResource);
 }
@@ -179,6 +193,10 @@
     decrementRefcountLocked((void*) filterResource);
 }
 
+void ResourceCache::decrementRefcountLocked(Res_png_9patch* patchResource) {
+    decrementRefcountLocked((void*) patchResource);
+}
+
 void ResourceCache::decrementRefcountLocked(Layer* layerResource) {
     decrementRefcountLocked((void*) layerResource);
 }
@@ -265,6 +283,30 @@
     }
 }
 
+void ResourceCache::destructor(Res_png_9patch* resource) {
+    Mutex::Autolock _l(mLock);
+    destructorLocked(resource);
+}
+
+void ResourceCache::destructorLocked(Res_png_9patch* resource) {
+    ssize_t index = mCache->indexOfKey(resource);
+    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
+    if (ref == NULL) {
+        if (Caches::hasInstance()) {
+            Caches::getInstance().patchCache.removeDeferred(resource);
+        }
+        // If we're not tracking this resource, just delete it
+        // A Res_png_9patch is actually an array of byte that's larger
+        // than sizeof(Res_png_9patch). It must be freed as an array.
+        delete[] (int8_t*) resource;
+        return;
+    }
+    ref->destroyed = true;
+    if (ref->refCount == 0) {
+        deleteResourceReferenceLocked(resource, ref);
+    }
+}
+
 /**
  * Return value indicates whether resource was actually recycled, which happens when RefCnt
  * reaches 0.
@@ -335,6 +377,16 @@
                 delete filter;
             }
             break;
+            case kNinePatch: {
+                if (Caches::hasInstance()) {
+                    Caches::getInstance().patchCache.removeDeferred((Res_png_9patch*) resource);
+                }
+                // A Res_png_9patch is actually an array of byte that's larger
+                // than sizeof(Res_png_9patch). It must be freed as an array.
+                int8_t* patch = (int8_t*) resource;
+                delete[] patch;
+            }
+            break;
             case kLayer: {
                 Layer* layer = (Layer*) resource;
                 Caches::getInstance().deleteLayerDeferred(layer);
diff --git a/libs/hwui/ResourceCache.h b/libs/hwui/ResourceCache.h
index ab493e5..ea0c1b5 100644
--- a/libs/hwui/ResourceCache.h
+++ b/libs/hwui/ResourceCache.h
@@ -22,7 +22,11 @@
 #include <SkBitmap.h>
 #include <SkiaColorFilter.h>
 #include <SkiaShader.h>
+
 #include <utils/KeyedVector.h>
+
+#include <androidfw/ResourceTypes.h>
+
 #include "Layer.h"
 
 namespace android {
@@ -35,6 +39,7 @@
     kBitmap,
     kShader,
     kColorFilter,
+    kNinePatch,
     kPath,
     kLayer
 };
@@ -69,35 +74,41 @@
     void incrementRefcount(SkBitmap* resource);
     void incrementRefcount(SkiaShader* resource);
     void incrementRefcount(SkiaColorFilter* resource);
+    void incrementRefcount(Res_png_9patch* resource);
     void incrementRefcount(Layer* resource);
 
     void incrementRefcountLocked(SkPath* resource);
     void incrementRefcountLocked(SkBitmap* resource);
     void incrementRefcountLocked(SkiaShader* resource);
     void incrementRefcountLocked(SkiaColorFilter* resource);
+    void incrementRefcountLocked(Res_png_9patch* resource);
     void incrementRefcountLocked(Layer* resource);
 
     void decrementRefcount(SkBitmap* resource);
     void decrementRefcount(SkPath* resource);
     void decrementRefcount(SkiaShader* resource);
     void decrementRefcount(SkiaColorFilter* resource);
+    void decrementRefcount(Res_png_9patch* resource);
     void decrementRefcount(Layer* resource);
 
     void decrementRefcountLocked(SkBitmap* resource);
     void decrementRefcountLocked(SkPath* resource);
     void decrementRefcountLocked(SkiaShader* resource);
     void decrementRefcountLocked(SkiaColorFilter* resource);
+    void decrementRefcountLocked(Res_png_9patch* resource);
     void decrementRefcountLocked(Layer* resource);
 
     void destructor(SkPath* resource);
     void destructor(SkBitmap* resource);
     void destructor(SkiaShader* resource);
     void destructor(SkiaColorFilter* resource);
+    void destructor(Res_png_9patch* resource);
 
     void destructorLocked(SkPath* resource);
     void destructorLocked(SkBitmap* resource);
     void destructorLocked(SkiaShader* resource);
     void destructorLocked(SkiaColorFilter* resource);
+    void destructorLocked(Res_png_9patch* resource);
 
     bool recycle(SkBitmap* resource);
     bool recycleLocked(SkBitmap* resource);
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index c38eedb..797ed10 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -69,9 +69,13 @@
     mGenerationId = shader.mGenerationId;
 }
 
+SkiaShader::SkiaShader(): mCaches(NULL) {
+}
+
 SkiaShader::SkiaShader(Type type, SkShader* key, SkShader::TileMode tileX,
         SkShader::TileMode tileY, SkMatrix* matrix, bool blend):
-        mType(type), mKey(key), mTileX(tileX), mTileY(tileY), mBlend(blend) {
+        mType(type), mKey(key), mTileX(tileX), mTileY(tileY), mBlend(blend),
+        mCaches(NULL) {
     setMatrix(matrix);
     mGenerationId = 0;
 }
@@ -87,7 +91,7 @@
 }
 
 void SkiaShader::bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT) {
-    glBindTexture(GL_TEXTURE_2D, texture->id);
+    mCaches->bindTexture(texture->id);
     texture->setWrapST(wrapS, wrapT);
 }
 
@@ -114,7 +118,7 @@
 }
 
 void SkiaBitmapShader::describe(ProgramDescription& description, const Extensions& extensions) {
-    Texture* texture = mTextureCache->get(mBitmap);
+    Texture* texture = mCaches->textureCache.get(mBitmap);
     if (!texture) return;
     mTexture = texture;
 
@@ -229,7 +233,7 @@
         GLuint textureSlot = (*textureUnit)++;
         Caches::getInstance().activeTexture(textureSlot);
 
-        Texture* texture = mGradientCache->get(mColors, mPositions, mCount);
+        Texture* texture = mCaches->gradientCache.get(mColors, mPositions, mCount);
 
         // Uniforms
         bindTexture(texture, gTileModes[mTileX], gTileModes[mTileY]);
@@ -349,7 +353,7 @@
         GLuint textureSlot = (*textureUnit)++;
         Caches::getInstance().activeTexture(textureSlot);
 
-        Texture* texture = mGradientCache->get(mColors, mPositions, mCount);
+        Texture* texture = mCaches->gradientCache.get(mColors, mPositions, mCount);
 
         // Uniforms
         bindTexture(texture, gTileModes[mTileX], gTileModes[mTileY]);
@@ -359,7 +363,7 @@
        bindUniformColor(program->getUniform("endColor"), mColors[1]);
     }
 
-    Caches::getInstance().dither.setupProgram(program, textureUnit);
+    mCaches->dither.setupProgram(program, textureUnit);
 
     mat4 screenSpace;
     computeScreenSpaceMatrix(screenSpace, modelView);
@@ -394,12 +398,6 @@
     return copy;
 }
 
-void SkiaComposeShader::set(TextureCache* textureCache, GradientCache* gradientCache) {
-    SkiaShader::set(textureCache, gradientCache);
-    mFirst->set(textureCache, gradientCache);
-    mSecond->set(textureCache, gradientCache);
-}
-
 void SkiaComposeShader::describe(ProgramDescription& description, const Extensions& extensions) {
     mFirst->describe(description, extensions);
     mSecond->describe(description, extensions);
diff --git a/libs/hwui/SkiaShader.h b/libs/hwui/SkiaShader.h
index bc12b0d..a63431c 100644
--- a/libs/hwui/SkiaShader.h
+++ b/libs/hwui/SkiaShader.h
@@ -33,6 +33,8 @@
 namespace android {
 namespace uirenderer {
 
+class Caches;
+
 ///////////////////////////////////////////////////////////////////////////////
 // Base shader
 ///////////////////////////////////////////////////////////////////////////////
@@ -77,9 +79,8 @@
         return mType;
     }
 
-    virtual void set(TextureCache* textureCache, GradientCache* gradientCache) {
-        mTextureCache = textureCache;
-        mGradientCache = gradientCache;
+    virtual void setCaches(Caches& caches) {
+        mCaches = &caches;
     }
 
     uint32_t getGenerationId() {
@@ -103,8 +104,7 @@
     void computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView);
 
 protected:
-    SkiaShader() {
-    }
+    SkiaShader();
 
     /**
      * The appropriate texture unit must have been activated prior to invoking
@@ -118,8 +118,7 @@
     SkShader::TileMode mTileY;
     bool mBlend;
 
-    TextureCache* mTextureCache;
-    GradientCache* mGradientCache;
+    Caches* mCaches;
 
     mat4 mUnitMatrix;
     mat4 mShaderMatrix;
@@ -229,7 +228,11 @@
     ~SkiaComposeShader();
     SkiaShader* copy();
 
-    void set(TextureCache* textureCache, GradientCache* gradientCache);
+    void setCaches(Caches& caches) {
+        SkiaShader::setCaches(caches);
+        mFirst->setCaches(caches);
+        mSecond->setCaches(caches);
+    }
 
     void describe(ProgramDescription& description, const Extensions& extensions);
     void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
diff --git a/libs/hwui/Stencil.cpp b/libs/hwui/Stencil.cpp
index ba2e6f2..2764523 100644
--- a/libs/hwui/Stencil.cpp
+++ b/libs/hwui/Stencil.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include "Debug.h"
 #include "Extensions.h"
 #include "Properties.h"
 #include "Stencil.h"
diff --git a/libs/hwui/TextDropShadowCache.cpp b/libs/hwui/TextDropShadowCache.cpp
index 6976eaa..0b2c130 100644
--- a/libs/hwui/TextDropShadowCache.cpp
+++ b/libs/hwui/TextDropShadowCache.cpp
@@ -18,6 +18,7 @@
 
 #include <utils/JenkinsHash.h>
 
+#include "Caches.h"
 #include "Debug.h"
 #include "TextDropShadowCache.h"
 #include "Properties.h"
@@ -154,7 +155,7 @@
             ALOGD("Shadow texture deleted, size = %d", texture->bitmapSize);
         }
 
-        glDeleteTextures(1, &texture->id);
+        texture->deleteTexture();
         delete texture;
     }
 }
@@ -182,7 +183,9 @@
             return NULL;
         }
 
-        texture = new ShadowTexture;
+        Caches& caches = Caches::getInstance();
+
+        texture = new ShadowTexture(caches);
         texture->left = shadow.penX;
         texture->top = shadow.penY;
         texture->width = shadow.width;
@@ -202,7 +205,7 @@
 
         glGenTextures(1, &texture->id);
 
-        glBindTexture(GL_TEXTURE_2D, texture->id);
+        caches.bindTexture(texture->id);
         // Textures are Alpha8
         glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 
diff --git a/libs/hwui/TextDropShadowCache.h b/libs/hwui/TextDropShadowCache.h
index 0bed72b6..04d7357 100644
--- a/libs/hwui/TextDropShadowCache.h
+++ b/libs/hwui/TextDropShadowCache.h
@@ -30,6 +30,8 @@
 namespace android {
 namespace uirenderer {
 
+class Caches;
+
 struct ShadowText {
     ShadowText(): len(0), radius(0.0f), textSize(0.0f), typeface(NULL),
             flags(0), italicStyle(0.0f), scaleX(0), text(NULL), positions(NULL) {
@@ -114,7 +116,7 @@
  * Alpha texture used to represent a shadow.
  */
 struct ShadowTexture: public Texture {
-    ShadowTexture(): Texture() {
+    ShadowTexture(Caches& caches): Texture(caches) {
     }
 
     float left;
diff --git a/libs/hwui/Texture.cpp b/libs/hwui/Texture.cpp
new file mode 100644
index 0000000..7923ce7
--- /dev/null
+++ b/libs/hwui/Texture.cpp
@@ -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.
+ */
+
+#define LOG_TAG "OpenGLRenderer"
+
+#include <utils/Log.h>
+
+#include "Caches.h"
+#include "Texture.h"
+
+namespace android {
+namespace uirenderer {
+
+Texture::Texture(): id(0), generation(0), blend(false), width(0), height(0),
+        cleanup(false), bitmapSize(0), mipMap(false), uvMapper(NULL),
+        mWrapS(GL_CLAMP_TO_EDGE), mWrapT(GL_CLAMP_TO_EDGE),
+        mMinFilter(GL_NEAREST), mMagFilter(GL_NEAREST),
+        mFirstFilter(true), mFirstWrap(true), mCaches(Caches::getInstance()) {
+}
+
+Texture::Texture(Caches& caches): id(0), generation(0), blend(false), width(0), height(0),
+        cleanup(false), bitmapSize(0), mipMap(false), uvMapper(NULL),
+        mWrapS(GL_CLAMP_TO_EDGE), mWrapT(GL_CLAMP_TO_EDGE),
+        mMinFilter(GL_NEAREST), mMagFilter(GL_NEAREST),
+        mFirstFilter(true), mFirstWrap(true), mCaches(caches) {
+}
+
+void Texture::setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture, bool force,
+        GLenum renderTarget) {
+
+    if (mFirstWrap || force || wrapS != mWrapS || wrapT != mWrapT) {
+        mFirstWrap = false;
+
+        mWrapS = wrapS;
+        mWrapT = wrapT;
+
+        if (bindTexture) {
+            mCaches.bindTexture(renderTarget, id);
+        }
+
+        glTexParameteri(renderTarget, GL_TEXTURE_WRAP_S, wrapS);
+        glTexParameteri(renderTarget, GL_TEXTURE_WRAP_T, wrapT);
+    }
+}
+
+void Texture::setFilterMinMag(GLenum min, GLenum mag, bool bindTexture, bool force,
+        GLenum renderTarget) {
+
+    if (mFirstFilter || force || min != mMinFilter || mag != mMagFilter) {
+        mFirstFilter = false;
+
+        mMinFilter = min;
+        mMagFilter = mag;
+
+        if (bindTexture) {
+            mCaches.bindTexture(renderTarget, id);
+        }
+
+        if (mipMap && min == GL_LINEAR) min = GL_LINEAR_MIPMAP_LINEAR;
+
+        glTexParameteri(renderTarget, GL_TEXTURE_MIN_FILTER, min);
+        glTexParameteri(renderTarget, GL_TEXTURE_MAG_FILTER, mag);
+    }
+}
+
+void Texture::deleteTexture() const {
+    mCaches.deleteTexture(id);
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h
index 8d88bdc..d48ec59 100644
--- a/libs/hwui/Texture.h
+++ b/libs/hwui/Texture.h
@@ -22,75 +22,39 @@
 namespace android {
 namespace uirenderer {
 
+class Caches;
+class UvMapper;
+
 /**
  * Represents an OpenGL texture.
  */
-struct Texture {
-    Texture() {
-        cleanup = false;
-        bitmapSize = 0;
+class Texture {
+public:
+    Texture();
+    Texture(Caches& caches);
 
-        wrapS = GL_CLAMP_TO_EDGE;
-        wrapT = GL_CLAMP_TO_EDGE;
+    virtual ~Texture() { }
 
-        minFilter = GL_NEAREST;
-        magFilter = GL_NEAREST;
-
-        mipMap = false;
-
-        firstFilter = true;
-        firstWrap = true;
-
-        id = 0;
-    }
-
-    void setWrap(GLenum wrap, bool bindTexture = false, bool force = false,
+    inline void setWrap(GLenum wrap, bool bindTexture = false, bool force = false,
                 GLenum renderTarget = GL_TEXTURE_2D) {
         setWrapST(wrap, wrap, bindTexture, force, renderTarget);
     }
 
-    void setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture = false, bool force = false,
-            GLenum renderTarget = GL_TEXTURE_2D) {
+    virtual void setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture = false,
+            bool force = false, GLenum renderTarget = GL_TEXTURE_2D);
 
-        if (firstWrap || force || wrapS != this->wrapS || wrapT != this->wrapT) {
-            firstWrap = false;
-
-            this->wrapS = wrapS;
-            this->wrapT = wrapT;
-
-            if (bindTexture) {
-                glBindTexture(renderTarget, id);
-            }
-
-            glTexParameteri(renderTarget, GL_TEXTURE_WRAP_S, wrapS);
-            glTexParameteri(renderTarget, GL_TEXTURE_WRAP_T, wrapT);
-        }
-    }
-
-    void setFilter(GLenum filter, bool bindTexture = false, bool force = false,
+    inline void setFilter(GLenum filter, bool bindTexture = false, bool force = false,
                 GLenum renderTarget = GL_TEXTURE_2D) {
         setFilterMinMag(filter, filter, bindTexture, force, renderTarget);
     }
 
-    void setFilterMinMag(GLenum min, GLenum mag, bool bindTexture = false, bool force = false,
-            GLenum renderTarget = GL_TEXTURE_2D) {
+    virtual void setFilterMinMag(GLenum min, GLenum mag, bool bindTexture = false,
+            bool force = false, GLenum renderTarget = GL_TEXTURE_2D);
 
-        if (firstFilter || force || min != minFilter || mag != magFilter) {
-            firstFilter = false;
-
-            minFilter = min;
-            magFilter = mag;
-
-            if (bindTexture) {
-                glBindTexture(renderTarget, id);
-            }
-
-            if (mipMap && min == GL_LINEAR) min = GL_LINEAR_MIPMAP_LINEAR;
-
-            glTexParameteri(renderTarget, GL_TEXTURE_MIN_FILTER, min);
-            glTexParameteri(renderTarget, GL_TEXTURE_MAG_FILTER, mag);
-        }
-    }
+    /**
+     * Convenience method to call glDeleteTextures() on this texture's id.
+     */
+    void deleteTexture() const;
 
     /**
      * Name of the texture.
@@ -125,21 +89,28 @@
      */
     bool mipMap;
 
+    /**
+     * Optional, pointer to a texture coordinates mapper.
+     */
+    const UvMapper* uvMapper;
+
 private:
     /**
      * Last wrap modes set on this texture. Defaults to GL_CLAMP_TO_EDGE.
      */
-    GLenum wrapS;
-    GLenum wrapT;
+    GLenum mWrapS;
+    GLenum mWrapT;
 
     /**
      * Last filters set on this texture. Defaults to GL_NEAREST.
      */
-    GLenum minFilter;
-    GLenum magFilter;
+    GLenum mMinFilter;
+    GLenum mMagFilter;
 
-    bool firstFilter;
-    bool firstWrap;
+    bool mFirstFilter;
+    bool mFirstWrap;
+
+    Caches& mCaches;
 }; // struct Texture
 
 class AutoTexture {
@@ -147,7 +118,7 @@
     AutoTexture(const Texture* texture): mTexture(texture) { }
     ~AutoTexture() {
         if (mTexture && mTexture->cleanup) {
-            glDeleteTextures(1, &mTexture->id);
+            mTexture->deleteTexture();
             delete mTexture;
         }
     }
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index 2378eb5..a63cac6 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -112,7 +112,7 @@
         if (mDebugEnabled) {
             ALOGD("Texture deleted, size = %d", texture->bitmapSize);
         }
-        glDeleteTextures(1, &texture->id);
+        texture->deleteTexture();
         delete texture;
     }
 }
@@ -139,7 +139,7 @@
             }
         }
 
-        texture = new Texture;
+        texture = new Texture();
         texture->bitmapSize = size;
         generateTexture(bitmap, texture, false);
 
@@ -162,7 +162,7 @@
 }
 
 Texture* TextureCache::getTransient(SkBitmap* bitmap) {
-    Texture* texture = new Texture;
+    Texture* texture = new Texture();
     texture->bitmapSize = bitmap->rowBytes() * bitmap->height();
     texture->cleanup = true;
 
@@ -235,7 +235,7 @@
     texture->width = bitmap->width();
     texture->height = bitmap->height();
 
-    glBindTexture(GL_TEXTURE_2D, texture->id);
+    Caches::getInstance().bindTexture(texture->id);
 
     switch (bitmap->getConfig()) {
     case SkBitmap::kA8_Config:
diff --git a/libs/hwui/UvMapper.h b/libs/hwui/UvMapper.h
new file mode 100644
index 0000000..70428d2
--- /dev/null
+++ b/libs/hwui/UvMapper.h
@@ -0,0 +1,133 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HWUI_UV_MAPPER_H
+#define ANDROID_HWUI_UV_MAPPER_H
+
+#include "Rect.h"
+
+namespace android {
+namespace uirenderer {
+
+/**
+ * This class can be used to map UV coordinates from the [0..1]
+ * range to other arbitrary ranges. All the methods below assume
+ * that the input values lie in the [0..1] range already.
+ */
+class UvMapper {
+public:
+    /**
+     * Using this constructor is equivalent to not using any mapping at all.
+     * UV coordinates in the [0..1] range remain in the [0..1] range.
+     */
+    UvMapper(): mIdentity(true), mMinU(0.0f), mMaxU(1.0f), mMinV(0.0f), mMaxV(1.0f) {
+    }
+
+    /**
+     * Creates a new mapper with the specified ranges for U and V coordinates.
+     * The parameter minU must be < maxU and minV must be < maxV.
+     */
+    UvMapper(float minU, float maxU, float minV, float maxV):
+        mMinU(minU), mMaxU(maxU), mMinV(minV), mMaxV(maxV) {
+        checkIdentity();
+    }
+
+    /**
+     * Returns true if calling the map*() methods has no effect (that is,
+     * texture coordinates remain in the 0..1 range.)
+     */
+    bool isIdentity() const {
+        return mIdentity;
+    }
+
+    /**
+     * Changes the U and V mapping ranges.
+     * The parameter minU must be < maxU and minV must be < maxV.
+     */
+    void setMapping(float minU, float maxU, float minV, float maxV) {
+        mMinU = minU;
+        mMaxU = maxU;
+        mMinV = minV;
+        mMaxV = maxV;
+        checkIdentity();
+    }
+
+    /**
+     * Maps a single value in the U range.
+     */
+    void mapU(float& u) const {
+        if (!mIdentity) u = lerp(mMinU, mMaxU, u);
+    }
+
+    /**
+     * Maps a single value in the V range.
+     */
+    void mapV(float& v) const {
+        if (!mIdentity) v = lerp(mMinV, mMaxV, v);
+    }
+
+    /**
+     * Maps the specified rectangle in place. This method assumes:
+     * - left = min. U
+     * - top = min. V
+     * - right = max. U
+     * - bottom = max. V
+     */
+    void map(Rect& texCoords) const {
+        if (!mIdentity) {
+            texCoords.left = lerp(mMinU, mMaxU, texCoords.left);
+            texCoords.right = lerp(mMinU, mMaxU, texCoords.right);
+            texCoords.top = lerp(mMinV, mMaxV, texCoords.top);
+            texCoords.bottom = lerp(mMinV, mMaxV, texCoords.bottom);
+        }
+    }
+
+    /**
+     * Maps the specified UV coordinates in place.
+     */
+    void map(float& u1, float& v1, float& u2, float& v2) const {
+        if (!mIdentity) {
+            u1 = lerp(mMinU, mMaxU, u1);
+            u2 = lerp(mMinU, mMaxU, u2);
+            v1 = lerp(mMinV, mMaxV, v1);
+            v2 = lerp(mMinV, mMaxV, v2);
+        }
+    }
+
+    void dump() const {
+        ALOGD("mapper[minU=%.2f maxU=%.2f minV=%.2f maxV=%.2f]", mMinU, mMaxU, mMinV, mMaxV);
+    }
+
+private:
+    static float lerp(float start, float stop, float amount) {
+        return start + (stop - start) * amount;
+    }
+
+    void checkIdentity() {
+        mIdentity = mMinU == 0.0f && mMaxU == 1.0f && mMinV == 0.0f && mMaxV == 1.0f;
+    }
+
+    bool mIdentity;
+    float mMinU;
+    float mMaxU;
+    float mMinV;
+    float mMaxV;
+};
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_HWUI_UV_MAPPER_H
diff --git a/libs/hwui/Vertex.h b/libs/hwui/Vertex.h
index 523120e..c06762f 100644
--- a/libs/hwui/Vertex.h
+++ b/libs/hwui/Vertex.h
@@ -17,6 +17,8 @@
 #ifndef ANDROID_HWUI_VERTEX_H
 #define ANDROID_HWUI_VERTEX_H
 
+#include "Vector.h"
+
 namespace android {
 namespace uirenderer {
 
@@ -30,6 +32,15 @@
         vertex[0].position[0] = x;
         vertex[0].position[1] = y;
     }
+
+    static inline void set(Vertex* vertex, vec2 val) {
+        set(vertex, val.x, val.y);
+    }
+
+    static inline void copyWithOffset(Vertex* vertex, const Vertex& src, float x, float y) {
+        set(vertex, src.position[0] + x, src.position[1] + y);
+    }
+
 }; // struct Vertex
 
 /**
@@ -81,6 +92,12 @@
         vertex[0].alpha = alpha;
     }
 
+    static inline void copyWithOffset(AlphaVertex* vertex, const AlphaVertex& src,
+            float x, float y) {
+        Vertex::set(vertex, src.position[0] + x, src.position[1] + y);
+        vertex[0].alpha = src.alpha;
+    }
+
     static inline void setColor(AlphaVertex* vertex, float alpha) {
         vertex[0].alpha = alpha;
     }
diff --git a/libs/hwui/font/CacheTexture.cpp b/libs/hwui/font/CacheTexture.cpp
index 6c5267d..cbed3e4 100644
--- a/libs/hwui/font/CacheTexture.cpp
+++ b/libs/hwui/font/CacheTexture.cpp
@@ -17,6 +17,7 @@
 #include <SkGlyph.h>
 
 #include "CacheTexture.h"
+#include "../Caches.h"
 #include "../Debug.h"
 #include "../Extensions.h"
 #include "../PixelBuffer.h"
@@ -107,10 +108,11 @@
 // CacheTexture
 ///////////////////////////////////////////////////////////////////////////////
 
-CacheTexture::CacheTexture(uint16_t width, uint16_t height, uint32_t maxQuadCount) :
-            mTexture(NULL), mTextureId(0), mWidth(width), mHeight(height),
+CacheTexture::CacheTexture(uint16_t width, uint16_t height, GLenum format, uint32_t maxQuadCount) :
+            mTexture(NULL), mTextureId(0), mWidth(width), mHeight(height), mFormat(format),
             mLinearFiltering(false), mDirty(false), mNumGlyphs(0),
-            mMesh(NULL), mCurrentQuad(0), mMaxQuadCount(maxQuadCount) {
+            mMesh(NULL), mCurrentQuad(0), mMaxQuadCount(maxQuadCount),
+            mCaches(Caches::getInstance()) {
     mCacheBlocks = new CacheBlock(TEXTURE_BORDER_SIZE, TEXTURE_BORDER_SIZE,
             mWidth - TEXTURE_BORDER_SIZE, mHeight - TEXTURE_BORDER_SIZE, true);
 
@@ -154,7 +156,7 @@
         mTexture = NULL;
     }
     if (mTextureId) {
-        glDeleteTextures(1, &mTextureId);
+        mCaches.deleteTexture(mTextureId);
         mTextureId = 0;
     }
     mDirty = false;
@@ -166,7 +168,7 @@
        mLinearFiltering = linearFiltering;
 
        const GLenum filtering = linearFiltering ? GL_LINEAR : GL_NEAREST;
-       if (bind) glBindTexture(GL_TEXTURE_2D, getTextureId());
+       if (bind) mCaches.bindTexture(getTextureId());
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
    }
@@ -180,17 +182,17 @@
 
 void CacheTexture::allocateTexture() {
     if (!mTexture) {
-        mTexture = PixelBuffer::create(GL_ALPHA, mWidth, mHeight);
+        mTexture = PixelBuffer::create(mFormat, mWidth, mHeight);
     }
 
     if (!mTextureId) {
         glGenTextures(1, &mTextureId);
 
-        glBindTexture(GL_TEXTURE_2D, mTextureId);
+        mCaches.bindTexture(mTextureId);
         glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
         // Initialize texture dimensions
-        glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, mWidth, mHeight, 0,
-                GL_ALPHA, GL_UNSIGNED_BYTE, 0);
+        glTexImage2D(GL_TEXTURE_2D, 0, mFormat, mWidth, mHeight, 0,
+                mFormat, GL_UNSIGNED_BYTE, 0);
 
         const GLenum filtering = getLinearFiltering() ? GL_LINEAR : GL_NEAREST;
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
@@ -215,8 +217,7 @@
         glPixelStorei(GL_UNPACK_ROW_LENGTH, mWidth);
     }
 
-    mTexture->upload(x, y, width, height, y * mWidth + x);
-
+    mTexture->upload(x, y, width, height);
     setDirty(false);
 
     return mHasES3;
@@ -230,6 +231,32 @@
 }
 
 bool CacheTexture::fitBitmap(const SkGlyph& glyph, uint32_t* retOriginX, uint32_t* retOriginY) {
+    switch (glyph.fMaskFormat) {
+        case SkMask::kA8_Format:
+        case SkMask::kBW_Format:
+            if (mFormat != GL_ALPHA) {
+#if DEBUG_FONT_RENDERER
+                ALOGD("fitBitmap: texture format %x is inappropriate for monochromatic glyphs",
+                        mFormat);
+#endif
+                return false;
+            }
+            break;
+        case SkMask::kARGB32_Format:
+            if (mFormat != GL_RGBA) {
+#if DEBUG_FONT_RENDERER
+                ALOGD("fitBitmap: texture format %x is inappropriate for colour glyphs", mFormat);
+#endif
+                return false;
+            }
+            break;
+        default:
+#if DEBUG_FONT_RENDERER
+            ALOGD("fitBitmap: unknown glyph format %x encountered", glyph.fMaskFormat);
+#endif
+            return false;
+    }
+
     if (glyph.fHeight + TEXTURE_BORDER_SIZE * 2 > mHeight) {
         return false;
     }
diff --git a/libs/hwui/font/CacheTexture.h b/libs/hwui/font/CacheTexture.h
index ddcc836..028b611 100644
--- a/libs/hwui/font/CacheTexture.h
+++ b/libs/hwui/font/CacheTexture.h
@@ -24,13 +24,14 @@
 #include <utils/Log.h>
 
 #include "FontUtil.h"
+#include "../PixelBuffer.h"
 #include "../Rect.h"
 #include "../Vertex.h"
 
 namespace android {
 namespace uirenderer {
 
-class PixelBuffer;
+class Caches;
 
 /**
  * CacheBlock is a node in a linked list of current free space areas in a CacheTexture.
@@ -73,7 +74,7 @@
 
 class CacheTexture {
 public:
-    CacheTexture(uint16_t width, uint16_t height, uint32_t maxQuadCount);
+    CacheTexture(uint16_t width, uint16_t height, GLenum format, uint32_t maxQuadCount);
     ~CacheTexture();
 
     void reset();
@@ -99,6 +100,14 @@
         return mHeight;
     }
 
+    inline GLenum getFormat() const {
+        return mFormat;
+    }
+
+    inline uint32_t getOffset(uint16_t x, uint16_t y) const {
+        return (y * mWidth + x) * PixelBuffer::formatSize(mFormat);
+    }
+
     inline const Rect* getDirtyRect() const {
         return &mDirtyRect;
     }
@@ -150,9 +159,9 @@
             float x3, float y3, float u3, float v3,
             float x4, float y4, float u4, float v4) {
         TextureVertex* mesh = mMesh + mCurrentQuad * 4;
-        TextureVertex::set(mesh++, x1, y1, u1, v1);
         TextureVertex::set(mesh++, x2, y2, u2, v2);
         TextureVertex::set(mesh++, x3, y3, u3, v3);
+        TextureVertex::set(mesh++, x1, y1, u1, v1);
         TextureVertex::set(mesh++, x4, y4, u4, v4);
         mCurrentQuad++;
     }
@@ -172,15 +181,17 @@
     GLuint mTextureId;
     uint16_t mWidth;
     uint16_t mHeight;
+    GLenum mFormat;
     bool mLinearFiltering;
     bool mDirty;
     uint16_t mNumGlyphs;
     TextureVertex* mMesh;
     uint32_t mCurrentQuad;
     uint32_t mMaxQuadCount;
+    Caches& mCaches;
     CacheBlock* mCacheBlocks;
-    Rect mDirtyRect;
     bool mHasES3;
+    Rect mDirtyRect;
 };
 
 }; // namespace uirenderer
diff --git a/libs/hwui/font/Font.cpp b/libs/hwui/font/Font.cpp
index 011cfc1..18983d8 100644
--- a/libs/hwui/font/Font.cpp
+++ b/libs/hwui/font/Font.cpp
@@ -55,6 +55,7 @@
     mStyle = paint->getStyle();
     mStrokeWidth = paint->getStrokeWidth();
     mAntiAliasing = paint->isAntiAlias();
+    mHinting = paint->getHinting();
     mLookupTransform.reset();
     mLookupTransform[SkMatrix::kMScaleX] = roundf(fmaxf(1.0f, matrix[mat4::kScaleX]));
     mLookupTransform[SkMatrix::kMScaleY] = roundf(fmaxf(1.0f, matrix[mat4::kScaleY]));
@@ -80,6 +81,7 @@
     hash = JenkinsHashMix(hash, android::hash_type(mStyle));
     hash = JenkinsHashMix(hash, android::hash_type(mStrokeWidth));
     hash = JenkinsHashMix(hash, int(mAntiAliasing));
+    hash = JenkinsHashMix(hash, android::hash_type(mHinting));
     hash = JenkinsHashMix(hash, android::hash_type(mLookupTransform[SkMatrix::kMScaleX]));
     hash = JenkinsHashMix(hash, android::hash_type(mLookupTransform[SkMatrix::kMScaleY]));
     return JenkinsHashWhiten(hash);
@@ -111,6 +113,9 @@
     deltaInt = int(lhs.mAntiAliasing) - int(rhs.mAntiAliasing);
     if (deltaInt != 0) return deltaInt;
 
+    deltaInt = int(lhs.mHinting) - int(rhs.mHinting);
+    if (deltaInt != 0) return deltaInt;
+
     if (lhs.mLookupTransform[SkMatrix::kMScaleX] <
             rhs.mLookupTransform[SkMatrix::kMScaleX]) return -1;
     if (lhs.mLookupTransform[SkMatrix::kMScaleX] >
diff --git a/libs/hwui/font/Font.h b/libs/hwui/font/Font.h
index 52cca1c..9e7ec2d 100644
--- a/libs/hwui/font/Font.h
+++ b/libs/hwui/font/Font.h
@@ -69,6 +69,7 @@
         uint8_t mStyle;
         float mStrokeWidth;
         bool mAntiAliasing;
+        uint8_t mHinting;
         SkMatrix mLookupTransform;
         SkMatrix mInverseLookupTransform;
     };
diff --git a/libs/hwui/font/FontUtil.h b/libs/hwui/font/FontUtil.h
index f758666..cdcb23c 100644
--- a/libs/hwui/font/FontUtil.h
+++ b/libs/hwui/font/FontUtil.h
@@ -31,6 +31,9 @@
 #define DEFAULT_TEXT_LARGE_CACHE_HEIGHT 512
 
 #define TEXTURE_BORDER_SIZE 1
+#if TEXTURE_BORDER_SIZE != 1
+# error TEXTURE_BORDER_SIZE other than 1 is not currently supported
+#endif
 
 #define CACHE_BLOCK_ROUNDING_SIZE 4
 
diff --git a/libs/hwui/thread/TaskManager.cpp b/libs/hwui/thread/TaskManager.cpp
index c8bfd9c..189895c 100644
--- a/libs/hwui/thread/TaskManager.cpp
+++ b/libs/hwui/thread/TaskManager.cpp
@@ -29,7 +29,7 @@
 
 TaskManager::TaskManager() {
     // Get the number of available CPUs. This value does not change over time.
-    int cpuCount = sysconf(_SC_NPROCESSORS_ONLN);
+    int cpuCount = sysconf(_SC_NPROCESSORS_CONF);
 
     for (int i = 0; i < cpuCount / 2; i++) {
         String8 name;
diff --git a/libs/hwui/thread/TaskManager.h b/libs/hwui/thread/TaskManager.h
index 477314b..f2a216f 100644
--- a/libs/hwui/thread/TaskManager.h
+++ b/libs/hwui/thread/TaskManager.h
@@ -43,7 +43,7 @@
     /**
      * Returns true if this task  manager can run tasks,
      * false otherwise. This method will typically return
-     * true on a single CPU core device.
+     * false on a single CPU core device.
      */
     bool canRunTasks() const;
 
diff --git a/location/Android.mk b/location/Android.mk
index 12db2f7..feeb8ce 100644
--- a/location/Android.mk
+++ b/location/Android.mk
@@ -14,6 +14,4 @@
 
 LOCAL_PATH := $(call my-dir)
 
-ifeq ($(TARGET_BUILD_APPS),)
 include $(call all-makefiles-under, $(LOCAL_PATH))
-endif
diff --git a/location/java/android/location/FusedBatchOptions.aidl b/location/java/android/location/FusedBatchOptions.aidl
new file mode 100644
index 0000000..94cb6e1
--- /dev/null
+++ b/location/java/android/location/FusedBatchOptions.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.location;
+
+parcelable FusedBatchOptions;
\ No newline at end of file
diff --git a/location/java/android/location/FusedBatchOptions.java b/location/java/android/location/FusedBatchOptions.java
new file mode 100644
index 0000000..623d707
--- /dev/null
+++ b/location/java/android/location/FusedBatchOptions.java
@@ -0,0 +1,135 @@
+/*
+ * 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.location;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A data class representing a set of options to configure batching sessions.
+ * @hide
+ */
+public class FusedBatchOptions implements Parcelable {
+    private volatile long mPeriodInNS = 0;
+    private volatile int mSourcesToUse = 0;
+    private volatile int mFlags = 0;
+
+    // the default value is set to request fixes at no cost
+    private volatile double mMaxPowerAllocationInMW = 0;
+
+    /*
+     * Getters and setters for properties needed to hold the options.
+     */
+    public void setMaxPowerAllocationInMW(double value) {
+        mMaxPowerAllocationInMW = value;
+    }
+
+    public double getMaxPowerAllocationInMW() {
+        return mMaxPowerAllocationInMW;
+    }
+
+    public void setPeriodInNS(long value) {
+        mPeriodInNS = value;
+    }
+
+    public long getPeriodInNS() {
+        return mPeriodInNS;
+    }
+
+    public void setSourceToUse(int source) {
+        mSourcesToUse |= source;
+    }
+
+    public void resetSourceToUse(int source) {
+        mSourcesToUse &= ~source;
+    }
+
+    public boolean isSourceToUseSet(int source) {
+        return (mSourcesToUse & source) != 0;
+    }
+
+    public int getSourcesToUse() {
+        return mSourcesToUse;
+    }
+
+    public void setFlag(int flag) {
+        mFlags |= flag;
+    }
+
+    public void resetFlag(int flag) {
+        mFlags &= ~flag;
+    }
+
+    public boolean isFlagSet(int flag) {
+        return (mFlags & flag) != 0;
+    }
+
+    public int getFlags() {
+        return mFlags;
+    }
+
+    /**
+     * Definition of enum flag sets needed by this class.
+     * Such values need to be kept in sync with the ones in fused_location.h
+     */
+    public static final class SourceTechnologies {
+        public static int GNSS = 1<<0;
+        public static int WIFI = 1<<1;
+        public static int SENSORS = 1<<2;
+        public static int CELL = 1<<3;
+        public static int BLUETOOTH = 1<<4;
+    }
+
+    public static final class BatchFlags {
+        public static int WAKEUP_ON_FIFO_FULL = 1<<0;
+        public static int CALLBACK_ON_LOCATION_FIX = 1<<1;
+    }
+
+    /*
+     * Method definitions to support Parcelable operations.
+     */
+    public static final Parcelable.Creator<FusedBatchOptions> CREATOR =
+            new Parcelable.Creator<FusedBatchOptions>() {
+        @Override
+        public FusedBatchOptions createFromParcel(Parcel parcel) {
+            FusedBatchOptions options = new FusedBatchOptions();
+            options.setMaxPowerAllocationInMW(parcel.readDouble());
+            options.setPeriodInNS(parcel.readLong());
+            options.setSourceToUse(parcel.readInt());
+            options.setFlag(parcel.readInt());
+            return options;
+        }
+
+        @Override
+        public FusedBatchOptions[] newArray(int size) {
+            return new FusedBatchOptions[size];
+        }
+    };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeDouble(mMaxPowerAllocationInMW);
+        parcel.writeLong(mPeriodInNS);
+        parcel.writeInt(mSourcesToUse);
+        parcel.writeInt(mFlags);
+    }
+}
diff --git a/location/java/android/location/IFusedGeofenceHardware.aidl b/location/java/android/location/IFusedGeofenceHardware.aidl
new file mode 100644
index 0000000..d8c3585
--- /dev/null
+++ b/location/java/android/location/IFusedGeofenceHardware.aidl
@@ -0,0 +1,93 @@
+/*
+ * 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/license/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+package android.location;
+
+import android.hardware.location.GeofenceHardwareRequestParcelable;
+
+/**
+ * Fused Geofence Hardware interface.
+ *
+ * <p>This interface is the basic set of supported functionality by Fused Hardware modules that offer
+ * Geofencing capabilities.
+ *
+ * All operations are asynchronous and the status codes can be obtained via a set of callbacks.
+ *
+ * @hide
+ */
+interface IFusedGeofenceHardware {
+    /**
+     * Flags if the interface functionality is supported by the platform.
+     *
+     * @return true if the functionality is supported, false otherwise.
+     */
+    boolean isSupported();
+
+    /**
+     * Adds a given list of geofences to the system.
+     *
+     * @param geofenceRequestsArray    The list of geofences to add.
+     */
+    void addGeofences(in GeofenceHardwareRequestParcelable[] geofenceRequestsArray);
+
+    /**
+     * Removes a give list of geofences from the system.
+     *
+     * @param geofences     The list of geofences to remove.
+     */
+    void removeGeofences(in int[] geofenceIds);
+
+    /**
+     * Pauses monitoring a particular geofence.
+     * 
+     * @param geofenceId    The geofence to pause monitoring.
+     */
+    void pauseMonitoringGeofence(in int geofenceId);
+
+    /**
+     * Resumes monitoring a particular geofence.
+     *
+     * @param geofenceid            The geofence to resume monitoring.
+     * @param transitionsToMonitor  The transitions to monitor upon resume.
+     *
+     * Remarks: keep naming of geofence request options consistent with the naming used in
+     *          GeofenceHardwareRequest
+     */
+    void resumeMonitoringGeofence(in int geofenceId, in int monitorTransitions);
+
+    /**
+     * Modifies the request options if a geofence that is already known by the
+     * system.
+     *  
+     * @param geofenceId                    The geofence to modify.
+     * @param lastTransition                The last known transition state of
+     *                                      the geofence.
+     * @param monitorTransitions            The set of transitions to monitor.
+     * @param notificationResponsiveness    The notification responsivness needed.
+     * @param unknownTimer                  The time span associated with the.
+     * @param sourcesToUse                  The source technologies to use.
+     *
+     * Remarks: keep the options as separate fields to be able to leverage the class
+     * GeofenceHardwareRequest without any changes
+     */
+    void modifyGeofenceOptions(
+            in int geofenceId,
+            in int lastTransition,
+            in int monitorTransitions,
+            in int notificationResponsiveness,
+            in int unknownTimer,
+            in int sourcesToUse);
+}
diff --git a/location/java/android/location/IFusedProvider.aidl b/location/java/android/location/IFusedProvider.aidl
new file mode 100644
index 0000000..8870d2a
--- /dev/null
+++ b/location/java/android/location/IFusedProvider.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.location;
+
+import android.hardware.location.IFusedLocationHardware;
+
+/**
+ * Interface definition for Location providers that require FLP services.
+ * @hide
+ */
+interface IFusedProvider {
+    /**
+     * Provides access to a FusedLocationHardware instance needed for the provider to work.
+     *
+     * @param instance      The FusedLocationHardware available for the provider to use.
+     */
+    void onFusedLocationHardwareChange(in IFusedLocationHardware instance);
+}
\ No newline at end of file
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 989178a..ccb4304 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -152,12 +152,25 @@
 
     /**
      * Broadcast intent action when the configured location providers
-     * change.
+     * change. For use with {@link #isProviderEnabled(String)}. If you're interacting with the
+     * {@link android.provider.Settings.Secure#LOCATION_MODE} API, use {@link #MODE_CHANGED_ACTION}
+     * instead.
      */
     public static final String PROVIDERS_CHANGED_ACTION =
         "android.location.PROVIDERS_CHANGED";
 
     /**
+     * Broadcast intent action when {@link android.provider.Settings.Secure#LOCATION_MODE} changes.
+     * For use with the {@link android.provider.Settings.Secure#LOCATION_MODE} API.
+     * If you're interacting with {@link #isProviderEnabled(String)}, use
+     * {@link #PROVIDERS_CHANGED_ACTION} instead.
+     *
+     * In the future, there may be mode changes that do not result in
+     * {@link #PROVIDERS_CHANGED_ACTION} broadcasts.
+     */
+    public static final String MODE_CHANGED_ACTION = "android.location.MODE_CHANGED";
+
+    /**
      * Broadcast intent action indicating that the GPS has either started or
      * stopped receiving GPS fixes. An intent extra provides this state as a
      * boolean, where {@code true} means that the GPS is actively receiving fixes.
@@ -177,6 +190,17 @@
      */
     public static final String EXTRA_GPS_ENABLED = "enabled";
 
+    /**
+     * Broadcast intent action indicating that a high power location requests
+     * has either started or stopped being active.  The current state of
+     * active location requests should be read from AppOpsManager using
+     * {@code OP_MONITOR_HIGH_POWER_LOCATION}.
+     *
+     * @hide
+     */
+    public static final String HIGH_POWER_REQUEST_CHANGE_ACTION =
+        "android.location.HIGH_POWER_REQUEST_CHANGE";
+
     // Map from LocationListeners to their associated ListenerTransport objects
     private HashMap<LocationListener,ListenerTransport> mListeners =
         new HashMap<LocationListener,ListenerTransport>();
@@ -1075,8 +1099,13 @@
      * <p>If the user has enabled this provider in the Settings menu, true
      * is returned otherwise false is returned
      *
+     * <p>Callers should instead use
+     * {@link android.provider.Settings.Secure#LOCATION_MODE}
+     * unless they depend on provider-specific APIs such as
+     * {@link #requestLocationUpdates(String, long, float, LocationListener)}.
+     *
      * @param provider the name of the provider
-     * @return true if the provider is enabled
+     * @return true if the provider exists and is enabled
      *
      * @throws IllegalArgumentException if provider is null
      * @throws SecurityException if no suitable permission is present
diff --git a/location/java/android/location/LocationRequest.java b/location/java/android/location/LocationRequest.java
index 68f540b..c9162fe 100644
--- a/location/java/android/location/LocationRequest.java
+++ b/location/java/android/location/LocationRequest.java
@@ -19,6 +19,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.SystemClock;
+import android.os.WorkSource;
 import android.util.TimeUtils;
 
 
@@ -145,6 +146,8 @@
     private long mExpireAt = Long.MAX_VALUE;  // no expiry
     private int mNumUpdates = Integer.MAX_VALUE;  // no expiry
     private float mSmallestDisplacement = 0.0f;    // meters
+    private WorkSource mWorkSource = null;
+    private boolean mHideFromAppOps = false; // True if this request shouldn't be counted by AppOps
 
     private String mProvider = LocationManager.FUSED_PROVIDER;  // for deprecated APIs that explicitly request a provider
 
@@ -233,6 +236,8 @@
         mNumUpdates = src.mNumUpdates;
         mSmallestDisplacement = src.mSmallestDisplacement;
         mProvider = src.mProvider;
+        mWorkSource = src.mWorkSource;
+        mHideFromAppOps = src.mHideFromAppOps;
     }
 
     /**
@@ -493,6 +498,48 @@
         return mSmallestDisplacement;
     }
 
+    /**
+     * Sets the WorkSource to use for power blaming of this location request.
+     *
+     * <p>No permissions are required to make this call, however the LocationManager
+     * will throw a SecurityException when requesting location updates if the caller
+     * doesn't have the {@link android.Manifest.permission#UPDATE_DEVICE_STATS} permission.
+     *
+     * @param workSource WorkSource defining power blame for this location request.
+     * @hide
+     */
+    public void setWorkSource(WorkSource workSource) {
+        mWorkSource = workSource;
+    }
+
+    /** @hide */
+    public WorkSource getWorkSource() {
+        return mWorkSource;
+    }
+
+    /**
+     * Sets whether or not this location request should be hidden from AppOps.
+     *
+     * <p>Hiding a location request from AppOps will remove user visibility in the UI as to this
+     * request's existence.  It does not affect power blaming in the Battery page.
+     *
+     * <p>No permissions are required to make this call, however the LocationManager
+     * will throw a SecurityException when requesting location updates if the caller
+     * doesn't have the {@link android.Manifest.permission#UPDATE_APP_OPS_STATS} permission.
+     *
+     * @param hideFromAppOps If true AppOps won't keep track of this location request.
+     * @see android.app.AppOpsManager
+     * @hide
+     */
+    public void setHideFromAppOps(boolean hideFromAppOps) {
+        mHideFromAppOps = hideFromAppOps;
+    }
+
+    /** @hide */
+    public boolean getHideFromAppOps() {
+        return mHideFromAppOps;
+    }
+
     private static void checkInterval(long millis) {
         if (millis < 0) {
             throw new IllegalArgumentException("invalid interval: " + millis);
@@ -536,8 +583,11 @@
             request.setExpireAt(in.readLong());
             request.setNumUpdates(in.readInt());
             request.setSmallestDisplacement(in.readFloat());
+            request.setHideFromAppOps(in.readInt() != 0);
             String provider = in.readString();
             if (provider != null) request.setProvider(provider);
+            WorkSource workSource = in.readParcelable(null);
+            if (workSource != null) request.setWorkSource(workSource);
             return request;
         }
         @Override
@@ -559,7 +609,9 @@
         parcel.writeLong(mExpireAt);
         parcel.writeInt(mNumUpdates);
         parcel.writeFloat(mSmallestDisplacement);
+        parcel.writeInt(mHideFromAppOps ? 1 : 0);
         parcel.writeString(mProvider);
+        parcel.writeParcelable(mWorkSource, 0);
     }
 
     /** @hide */
diff --git a/location/java/android/location/SettingInjectorService.java b/location/java/android/location/SettingInjectorService.java
new file mode 100644
index 0000000..9f321f3
--- /dev/null
+++ b/location/java/android/location/SettingInjectorService.java
@@ -0,0 +1,238 @@
+/*
+ * 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.location;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * Dynamically specifies the summary (subtitle) and enabled status of a preference injected into
+ * the list of app settings displayed by the system settings app
+ * <p/>
+ * For use only by apps that are included in the system image, for preferences that affect multiple
+ * apps. Location settings that apply only to one app should be shown within that app,
+ * rather than in the system settings.
+ * <p/>
+ * To add a preference to the list, a subclass of {@link SettingInjectorService} must be declared in
+ * the manifest as so:
+ *
+ * <pre>
+ *     &lt;service android:name="com.example.android.injector.MyInjectorService" &gt;
+ *         &lt;intent-filter&gt;
+ *             &lt;action android:name="android.location.SettingInjectorService" /&gt;
+ *         &lt;/intent-filter&gt;
+ *
+ *         &lt;meta-data
+ *             android:name="android.location.SettingInjectorService"
+ *             android:resource="@xml/my_injected_location_setting" /&gt;
+ *     &lt;/service&gt;
+ * </pre>
+ * The resource file specifies the static data for the setting:
+ * <pre>
+ *     &lt;injected-location-setting xmlns:android="http://schemas.android.com/apk/res/android"
+ *         android:title="@string/injected_setting_title"
+ *         android:icon="@drawable/ic_acme_corp"
+ *         android:settingsActivity="com.example.android.injector.MySettingActivity"
+ *     /&gt;
+ * </pre>
+ * Here:
+ * <ul>
+ *     <li>title: The {@link android.preference.Preference#getTitle()} value. The title should make
+ *     it clear which apps are affected by the setting, typically by including the name of the
+ *     developer. For example, "Acme Corp. ads preferences." </li>
+ *
+ *     <li>icon: The {@link android.preference.Preference#getIcon()} value. Typically this will be a
+ *     generic icon for the developer rather than the icon for an individual app.</li>
+ *
+ *     <li>settingsActivity: the activity which is launched to allow the user to modify the setting
+ *     value.  The activity must be in the same package as the subclass of
+ *     {@link SettingInjectorService}. The activity should use your own branding to help emphasize
+ *     to the user that it is not part of the system settings.</li>
+ * </ul>
+ *
+ * To ensure a good user experience, your {@link android.app.Application#onCreate()},
+ * {@link #onGetSummary()}, and {@link #onGetEnabled()} methods must all be fast. If any are slow,
+ * it can delay the display of settings values for other apps as well. Note further that all are
+ * called on your app's UI thread.
+ * <p/>
+ * For compactness, only one copy of a given setting should be injected. If each account has a
+ * distinct value for the setting, then the {@link #onGetSummary()} value should represent a summary
+ * of the state across all of the accounts and {@code settingsActivity} should display the value for
+ * each account.
+ */
+public abstract class SettingInjectorService extends Service {
+
+    private static final String TAG = "SettingInjectorService";
+
+    /**
+     * Intent action that must be declared in the manifest for the subclass. Used to start the
+     * service to read the dynamic status for the setting.
+     */
+    public static final String ACTION_SERVICE_INTENT = "android.location.SettingInjectorService";
+
+    /**
+     * Name of the meta-data tag used to specify the resource file that includes the settings
+     * attributes.
+     */
+    public static final String META_DATA_NAME = "android.location.SettingInjectorService";
+
+    /**
+     * Name of the XML tag that includes the attributes for the setting.
+     */
+    public static final String ATTRIBUTES_NAME = "injected-location-setting";
+
+    /**
+     * Intent action a client should broadcast when the value of one of its injected settings has
+     * changed, so that the setting can be updated in the UI.
+     */
+    public static final String ACTION_INJECTED_SETTING_CHANGED =
+            "android.location.InjectedSettingChanged";
+
+    /**
+     * Name of the bundle key for the string specifying the summary for the setting (e.g., "ON" or
+     * "OFF").
+     *
+     * @hide
+     */
+    public static final String SUMMARY_KEY = "summary";
+
+    /**
+     * Name of the bundle key for the string specifying whether the setting is currently enabled.
+     *
+     * @hide
+     */
+    public static final String ENABLED_KEY = "enabled";
+
+    /**
+     * Name of the intent key used to specify the messenger
+     *
+     * @hide
+     */
+    public static final String MESSENGER_KEY = "messenger";
+
+    private final String mName;
+
+    /**
+     * Constructor.
+     *
+     * @param name used to identify your subclass in log messages
+     */
+    public SettingInjectorService(String name) {
+        mName = name;
+    }
+
+    @Override
+    public final IBinder onBind(Intent intent) {
+        return null;
+    }
+
+    @Override
+    public final void onStart(Intent intent, int startId) {
+        super.onStart(intent, startId);
+    }
+
+    @Override
+    public final int onStartCommand(Intent intent, int flags, int startId) {
+        onHandleIntent(intent);
+        stopSelf(startId);
+        return START_NOT_STICKY;
+    }
+
+    private void onHandleIntent(Intent intent) {
+
+        String summary;
+        try {
+            summary = onGetSummary();
+        } catch (RuntimeException e) {
+            // Exception. Send status anyway, so that settings injector can immediately start
+            // loading the status of the next setting.
+            sendStatus(intent, null, true);
+            throw e;
+        }
+
+        boolean enabled;
+        try {
+            enabled = onGetEnabled();
+        } catch (RuntimeException e) {
+            // Exception. Send status anyway, so that settings injector can immediately start
+            // loading the status of the next setting.
+            sendStatus(intent, summary, true);
+            throw e;
+        }
+
+        sendStatus(intent, summary, enabled);
+    }
+
+    /**
+     * Send the summary and enabled values back to the caller via the messenger encoded in the
+     * intent.
+     */
+    private void sendStatus(Intent intent, String summary, boolean enabled) {
+        Message message = Message.obtain();
+        Bundle bundle = new Bundle();
+        bundle.putString(SUMMARY_KEY, summary);
+        bundle.putBoolean(ENABLED_KEY, enabled);
+        message.setData(bundle);
+
+        if (Log.isLoggable(TAG, Log.DEBUG)) {
+            Log.d(TAG, mName + ": received " + intent + ", summary=" + summary
+                    + ", enabled=" + enabled + ", sending message: " + message);
+        }
+
+        Messenger messenger = intent.getParcelableExtra(MESSENGER_KEY);
+        try {
+            messenger.send(message);
+        } catch (RemoteException e) {
+            Log.e(TAG, mName + ": sending dynamic status failed", e);
+        }
+    }
+
+    /**
+     * Returns the {@link android.preference.Preference#getSummary()} value (allowed to be null or
+     * empty). Should not perform unpredictably-long operations such as network access--see the
+     * running-time comments in the class-level javadoc.
+     *
+     * @return the {@link android.preference.Preference#getSummary()} value
+     */
+    protected abstract String onGetSummary();
+
+    /**
+     * Returns the {@link android.preference.Preference#isEnabled()} value. Should not perform
+     * unpredictably-long operations such as network access--see the running-time comments in the
+     * class-level javadoc.
+     * <p/>
+     * Note that to prevent churn in the settings list, there is no support for dynamically choosing
+     * to hide a setting. Instead you should have this method return false, which will disable the
+     * setting and its link to your setting activity. One reason why you might choose to do this is
+     * if {@link android.provider.Settings.Secure#LOCATION_MODE} is {@link
+     * android.provider.Settings.Secure#LOCATION_MODE_OFF}.
+     * <p/>
+     * It is possible that the user may click on the setting before this method returns, so your
+     * settings activity must handle the case where it is invoked even though the setting is
+     * disabled. The simplest approach may be to simply call {@link android.app.Activity#finish()}
+     * when disabled.
+     *
+     * @return the {@link android.preference.Preference#isEnabled()} value
+     */
+    protected abstract boolean onGetEnabled();
+}
diff --git a/location/lib/java/com/android/location/provider/FusedLocationHardware.java b/location/lib/java/com/android/location/provider/FusedLocationHardware.java
new file mode 100644
index 0000000..bc5a8a1
--- /dev/null
+++ b/location/lib/java/com/android/location/provider/FusedLocationHardware.java
@@ -0,0 +1,280 @@
+/*
+ * 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.location.provider;
+
+import android.hardware.location.IFusedLocationHardware;
+import android.hardware.location.IFusedLocationHardwareSink;
+
+import android.location.Location;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Class that exposes IFusedLocationHardware functionality to unbundled services.
+ */
+public final class FusedLocationHardware {
+    private final String TAG = "FusedLocationHardware";
+
+    private IFusedLocationHardware mLocationHardware;
+
+    // the list uses a copy-on-write pattern to update its contents
+    HashMap<FusedLocationHardwareSink, DispatcherHandler> mSinkList =
+            new HashMap<FusedLocationHardwareSink, DispatcherHandler>();
+
+    private IFusedLocationHardwareSink mInternalSink = new IFusedLocationHardwareSink.Stub() {
+        @Override
+        public void onLocationAvailable(Location[] locations) {
+            dispatchLocations(locations);
+        }
+
+        @Override
+        public void onDiagnosticDataAvailable(String data) {
+            dispatchDiagnosticData(data);
+        }
+    };
+
+    /**
+     * @hide
+     */
+    public FusedLocationHardware(IFusedLocationHardware locationHardware) {
+        mLocationHardware = locationHardware;
+    }
+
+    /*
+     * Methods to provide a Facade for IFusedLocationHardware
+     */
+    public void registerSink(FusedLocationHardwareSink sink, Looper looper) {
+        if(sink == null || looper == null) {
+            throw new IllegalArgumentException("Parameter sink and looper cannot be null.");
+        }
+
+        boolean registerSink;
+        synchronized (mSinkList) {
+            // register only on first insertion
+            registerSink = mSinkList.size() == 0;
+            // guarantee uniqueness
+            if(mSinkList.containsKey(sink)) {
+                return;
+            }
+
+            HashMap<FusedLocationHardwareSink, DispatcherHandler> newSinkList =
+                    new HashMap<FusedLocationHardwareSink, DispatcherHandler>(mSinkList);
+            newSinkList.put(sink, new DispatcherHandler(looper));
+            mSinkList = newSinkList;
+        }
+
+        if(registerSink) {
+            try {
+                mLocationHardware.registerSink(mInternalSink);
+            } catch(RemoteException e) {
+                Log.e(TAG, "RemoteException at registerSink");
+            }
+        }
+    }
+
+    public void unregisterSink(FusedLocationHardwareSink sink) {
+        if(sink == null) {
+            throw new IllegalArgumentException("Parameter sink cannot be null.");
+        }
+
+        boolean unregisterSink;
+        synchronized(mSinkList) {
+            if(!mSinkList.containsKey(sink)) {
+                //done
+                return;
+            }
+
+            HashMap<FusedLocationHardwareSink, DispatcherHandler> newSinkList =
+                    new HashMap<FusedLocationHardwareSink, DispatcherHandler>(mSinkList);
+            newSinkList.remove(sink);
+            //unregister after the last sink
+            unregisterSink = newSinkList.size() == 0;
+
+            mSinkList = newSinkList;
+        }
+
+        if(unregisterSink) {
+            try {
+                mLocationHardware.unregisterSink(mInternalSink);
+            } catch(RemoteException e) {
+                Log.e(TAG, "RemoteException at unregisterSink");
+            }
+        }
+    }
+
+    public int getSupportedBatchSize() {
+        try {
+            return mLocationHardware.getSupportedBatchSize();
+        } catch(RemoteException e) {
+            Log.e(TAG, "RemoteException at getSupportedBatchSize");
+            return 0;
+        }
+    }
+
+    public void startBatching(int id, GmsFusedBatchOptions batchOptions) {
+        try {
+            mLocationHardware.startBatching(id, batchOptions.getParcelableOptions());
+        } catch(RemoteException e) {
+            Log.e(TAG, "RemoteException at startBatching");
+        }
+    }
+
+    public void stopBatching(int id) {
+        try {
+            mLocationHardware.stopBatching(id);
+        } catch(RemoteException e) {
+            Log.e(TAG, "RemoteException at stopBatching");
+        }
+    }
+
+    public void updateBatchingOptions(int id, GmsFusedBatchOptions batchOptions) {
+        try {
+            mLocationHardware.updateBatchingOptions(id, batchOptions.getParcelableOptions());
+        } catch(RemoteException e) {
+            Log.e(TAG, "RemoteException at updateBatchingOptions");
+        }
+    }
+
+    public void requestBatchOfLocations(int batchSizeRequest) {
+        try {
+            mLocationHardware.requestBatchOfLocations(batchSizeRequest);
+        } catch(RemoteException e) {
+            Log.e(TAG, "RemoteException at requestBatchOfLocations");
+        }
+    }
+
+    public boolean supportsDiagnosticDataInjection() {
+        try {
+            return mLocationHardware.supportsDiagnosticDataInjection();
+        } catch(RemoteException e) {
+            Log.e(TAG, "RemoteException at supportsDiagnisticDataInjection");
+            return false;
+        }
+    }
+
+    public void injectDiagnosticData(String data) {
+        try {
+            mLocationHardware.injectDiagnosticData(data);
+        } catch(RemoteException e) {
+            Log.e(TAG, "RemoteException at injectDiagnosticData");
+        }
+    }
+
+    public boolean supportsDeviceContextInjection() {
+        try {
+            return mLocationHardware.supportsDeviceContextInjection();
+        } catch(RemoteException e) {
+            Log.e(TAG, "RemoteException at supportsDeviceContextInjection");
+            return false;
+        }
+    }
+
+    public void injectDeviceContext(int deviceEnabledContext) {
+        try {
+            mLocationHardware.injectDeviceContext(deviceEnabledContext);
+        } catch(RemoteException e) {
+            Log.e(TAG, "RemoteException at injectDeviceContext");
+        }
+    }
+
+    /*
+     * Helper methods and classes
+     */
+    private class DispatcherHandler extends Handler {
+        public static final int DISPATCH_LOCATION = 1;
+        public static final int DISPATCH_DIAGNOSTIC_DATA = 2;
+
+        public DispatcherHandler(Looper looper) {
+            super(looper, null /*callback*/ , true /*async*/);
+        }
+
+        @Override
+        public void handleMessage(Message message) {
+            MessageCommand command = (MessageCommand) message.obj;
+            switch(message.what) {
+                case DISPATCH_LOCATION:
+                    command.dispatchLocation();
+                    break;
+                case DISPATCH_DIAGNOSTIC_DATA:
+                    command.dispatchDiagnosticData();
+                default:
+                    Log.e(TAG, "Invalid dispatch message");
+                    break;
+            }
+        }
+    }
+
+    private class MessageCommand {
+        private final FusedLocationHardwareSink mSink;
+        private final Location[] mLocations;
+        private final String mData;
+
+        public MessageCommand(
+                FusedLocationHardwareSink sink,
+                Location[] locations,
+                String data) {
+            mSink = sink;
+            mLocations = locations;
+            mData = data;
+        }
+
+        public void dispatchLocation() {
+            mSink.onLocationAvailable(mLocations);
+        }
+
+        public void dispatchDiagnosticData() {
+            mSink.onDiagnosticDataAvailable(mData);
+        }
+    }
+
+    private void dispatchLocations(Location[] locations) {
+        HashMap<FusedLocationHardwareSink, DispatcherHandler> sinks;
+        synchronized (mSinkList) {
+            sinks = mSinkList;
+        }
+
+        for(Map.Entry<FusedLocationHardwareSink, DispatcherHandler> entry : sinks.entrySet()) {
+            Message message = Message.obtain(
+                    entry.getValue(),
+                    DispatcherHandler.DISPATCH_LOCATION,
+                    new MessageCommand(entry.getKey(), locations, null /*data*/));
+            message.sendToTarget();
+        }
+    }
+
+    private void dispatchDiagnosticData(String data) {
+        HashMap<FusedLocationHardwareSink, DispatcherHandler> sinks;
+        synchronized(mSinkList) {
+            sinks = mSinkList;
+        }
+
+        for(Map.Entry<FusedLocationHardwareSink, DispatcherHandler> entry : sinks.entrySet()) {
+            Message message = Message.obtain(
+                    entry.getValue(),
+                    DispatcherHandler.DISPATCH_DIAGNOSTIC_DATA,
+                    new MessageCommand(entry.getKey(), null /*locations*/, data));
+            message.sendToTarget();
+        }
+    }
+}
diff --git a/location/lib/java/com/android/location/provider/FusedLocationHardwareSink.java b/location/lib/java/com/android/location/provider/FusedLocationHardwareSink.java
new file mode 100644
index 0000000..2c39fa8
--- /dev/null
+++ b/location/lib/java/com/android/location/provider/FusedLocationHardwareSink.java
@@ -0,0 +1,30 @@
+/*
+ * 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.location.provider;
+
+import android.location.Location;
+
+/**
+ * Base class for sinks to interact with FusedLocationHardware.
+ */
+public abstract class FusedLocationHardwareSink {
+    /*
+     * Methods to provide a facade for IFusedLocationHardware
+     */
+    public abstract void onLocationAvailable(Location[] locations);
+    public abstract void onDiagnosticDataAvailable(String data);
+}
\ No newline at end of file
diff --git a/location/lib/java/com/android/location/provider/FusedProvider.java b/location/lib/java/com/android/location/provider/FusedProvider.java
new file mode 100644
index 0000000..c966ade
--- /dev/null
+++ b/location/lib/java/com/android/location/provider/FusedProvider.java
@@ -0,0 +1,57 @@
+/*
+ * 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.location.provider;
+
+import android.hardware.location.IFusedLocationHardware;
+import android.location.IFusedProvider;
+import android.os.IBinder;
+
+/**
+ * Base class for Fused providers implemented as unbundled services.
+ *
+ * <p>Fused providers can be implemented as services and return the result of
+ * {@link com.android.location.provider.FusedProvider#getBinder()} in its getBinder() method.
+ *
+ * <p>IMPORTANT: This class is effectively a public API for unbundled applications, and must remain
+ * API stable. See README.txt in the root of this package for more information.
+ */
+public abstract class FusedProvider {
+    private IFusedProvider.Stub mProvider = new IFusedProvider.Stub() {
+        @Override
+        public void onFusedLocationHardwareChange(IFusedLocationHardware instance) {
+            setFusedLocationHardware(new FusedLocationHardware(instance));
+        }
+    };
+
+    /**
+     * Gets the Binder associated with the provider.
+     * This is intended to be used for the onBind() method of a service that implements a fused
+     * service.
+     *
+     * @return The IBinder instance associated with the provider.
+     */
+    public IBinder getBinder() {
+        return mProvider;
+    }
+
+    /**
+     * Sets the FusedLocationHardware instance in the provider..
+     * @param value     The instance to set. This can be null in cases where the service connection
+     *                  is disconnected.
+     */
+    public abstract void setFusedLocationHardware(FusedLocationHardware value);
+}
diff --git a/location/lib/java/com/android/location/provider/GmsFusedBatchOptions.java b/location/lib/java/com/android/location/provider/GmsFusedBatchOptions.java
new file mode 100644
index 0000000..fd3f402
--- /dev/null
+++ b/location/lib/java/com/android/location/provider/GmsFusedBatchOptions.java
@@ -0,0 +1,106 @@
+/*
+ * 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.location.provider;
+
+import android.location.FusedBatchOptions;
+
+/**
+ * Class that exposes FusedBatchOptions to the GmsCore .
+ */
+public class GmsFusedBatchOptions {
+    private FusedBatchOptions mOptions = new FusedBatchOptions();
+
+    /*
+     * Methods that provide a facade for properties in FusedBatchOptions.
+     */
+    public void setMaxPowerAllocationInMW(double value) {
+        mOptions.setMaxPowerAllocationInMW(value);
+    }
+
+    public double getMaxPowerAllocationInMW() {
+        return mOptions.getMaxPowerAllocationInMW();
+    }
+
+    public void setPeriodInNS(long value) {
+        mOptions.setPeriodInNS(value);
+    }
+
+    public long getPeriodInNS() {
+        return mOptions.getPeriodInNS();
+    }
+
+    public void setSourceToUse(int source) {
+        mOptions.setSourceToUse(source);
+    }
+
+    public void resetSourceToUse(int source) {
+        mOptions.resetSourceToUse(source);
+    }
+
+    public boolean isSourceToUseSet(int source) {
+        return mOptions.isSourceToUseSet(source);
+    }
+
+    public int getSourcesToUse() {
+        return mOptions.getSourcesToUse();
+    }
+
+    public void setFlag(int flag) {
+        mOptions.setFlag(flag);
+    }
+
+    public void resetFlag(int flag) {
+        mOptions.resetFlag(flag);
+    }
+
+    public boolean isFlagSet(int flag) {
+        return mOptions.isFlagSet(flag);
+    }
+
+    public int getFlags() {
+        return mOptions.getFlags();
+    }
+
+    /**
+     * Definition of enum flag sets needed by this class.
+     * Such values need to be kept in sync with the ones in fused_location.h
+     */
+
+    public static final class SourceTechnologies {
+        public static int GNSS = 1<<0;
+        public static int WIFI = 1<<1;
+        public static int SENSORS = 1<<2;
+        public static int CELL = 1<<3;
+        public static int BLUETOOTH = 1<<4;
+    }
+
+    public static final class BatchFlags {
+        public static int WAKEUP_ON_FIFO_FULL = 1<<0;
+        public static int CALLBACK_ON_LOCATION_FIX = 1<<1;
+    }
+
+    /*
+     * Method definitions for internal use.
+     */
+
+    /*
+     * @hide
+     */
+    public FusedBatchOptions getParcelableOptions() {
+        return mOptions;
+    }
+}
diff --git a/location/lib/java/com/android/location/provider/LocationProviderBase.java b/location/lib/java/com/android/location/provider/LocationProviderBase.java
index 8a5a739..150c289 100644
--- a/location/lib/java/com/android/location/provider/LocationProviderBase.java
+++ b/location/lib/java/com/android/location/provider/LocationProviderBase.java
@@ -35,6 +35,7 @@
 import com.android.internal.location.ILocationProvider;
 import com.android.internal.location.ProviderProperties;
 import com.android.internal.location.ProviderRequest;
+import com.android.internal.util.FastPrintWriter;
 
 /**
  * Base class for location providers implemented as unbundled services.
@@ -106,7 +107,7 @@
         }
         @Override
         public void dump(FileDescriptor fd, String[] args) {
-            PrintWriter pw = new PrintWriter(new FileOutputStream(fd));
+            PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd));
             onDump(fd, pw, args);
             pw.flush();
         }
diff --git a/media/java/android/drm/mobile1/DrmConstraintInfo.java b/media/java/android/drm/mobile1/DrmConstraintInfo.java
deleted file mode 100644
index 50ae8bd..0000000
--- a/media/java/android/drm/mobile1/DrmConstraintInfo.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.drm.mobile1;
-
-import java.util.Date;
-
-/**
- * This class provides interfaces to access the DRM constraint.
- */
-public class DrmConstraintInfo {
-    /**
-     * The constraint of count.
-     */
-    private int count;
-
-    /**
-     * The constraint of start date.
-     */
-    private long startDate;
-
-    /**
-     * The constraint of end date.
-     */
-    private long endDate;
-
-    /**
-     * The constraint of interval.
-     */
-    private long interval;
-
-    /**
-     * Construct the DrmConstraint.
-     */
-    DrmConstraintInfo() {
-        count = -1;
-        startDate = -1;
-        endDate = -1;
-        interval = -1;
-    }
-
-    /**
-     * Get the count constraint.
-     *
-     * @return the count or -1 if no limit.
-     */
-    public int getCount() {
-        return count;
-    }
-
-    /**
-     * Get the start date constraint.
-     *
-     * @return the start date or null if no limit.
-     */
-    public Date getStartDate() {
-        if (startDate == -1)
-            return null;
-
-        return new Date(startDate);
-    }
-
-    /**
-     * Get the end date constraint.
-     *
-     * @return the end date or null if no limit.
-     */
-    public Date getEndDate() {
-        if (endDate == -1)
-            return null;
-
-        return new Date(endDate);
-    }
-
-    /**
-     * Get the Interval constraint.
-     *
-     * @return the interval or -1 if no limit.
-     */
-    public long getInterval() {
-        return interval;
-    }
-}
diff --git a/media/java/android/drm/mobile1/DrmException.java b/media/java/android/drm/mobile1/DrmException.java
deleted file mode 100644
index 7b06c92..0000000
--- a/media/java/android/drm/mobile1/DrmException.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.drm.mobile1;
-
-import java.io.IOException;
-
-/**
- * A DrmException is thrown to report errors specific to handle DRM content and rights.
- */
-public class DrmException extends Exception
-{
-    // TODO: add more specific DRM error codes.
-    
-    private DrmException() {
-    }
-    
-    public DrmException(String message) {
-        super(message);
-    }
-}
diff --git a/media/java/android/drm/mobile1/DrmRawContent.java b/media/java/android/drm/mobile1/DrmRawContent.java
deleted file mode 100644
index 046b84a..0000000
--- a/media/java/android/drm/mobile1/DrmRawContent.java
+++ /dev/null
@@ -1,464 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.drm.mobile1;
-
-import java.io.*;
-
-/**
- * This class provides interfaces to access the DRM raw content.
- */
-public class DrmRawContent {
-    /**
-     * The "application/vnd.oma.drm.message" mime type.
-     */
-    public static final String DRM_MIMETYPE_MESSAGE_STRING = "application/vnd.oma.drm.message";
-
-    /**
-     * The "application/vnd.oma.drm.content" mime type.
-     */
-    public static final String DRM_MIMETYPE_CONTENT_STRING = "application/vnd.oma.drm.content";
-
-    /**
-     * The DRM delivery type: Forward-Lock
-     */
-    public static final int DRM_FORWARD_LOCK = 1;
-
-    /**
-     * The DRM delivery type: Combined Delivery
-     */
-    public static final int DRM_COMBINED_DELIVERY = 2;
-
-    /**
-     * The DRM delivery type: Separate Delivery
-     */
-    public static final int DRM_SEPARATE_DELIVERY = 3;
-
-    /**
-     * The DRM delivery type: Separate Delivery in DRM message
-     */
-    public static final int DRM_SEPARATE_DELIVERY_DM = 4;
-
-    /**
-     * The DRM media content length is unknown currently
-     */
-    public static final int DRM_UNKNOWN_DATA_LEN = -1;
-
-
-    /**
-     * The id of "application/vnd.oma.drm.message" mime type.
-     */
-    private static final int DRM_MIMETYPE_MESSAGE = 1;
-
-    /**
-     * The id of "application/vnd.oma.drm.content" mime type.
-     */
-    private static final int DRM_MIMETYPE_CONTENT = 2;
-
-    /**
-     * Successful operation.
-     */
-    private static final int JNI_DRM_SUCCESS = 0;
-
-    /**
-     * General failure.
-     */
-    private static final int JNI_DRM_FAILURE = -1;
-
-    /**
-     * Indicates the end of the DRM content is reached.
-     */
-    private static final int JNI_DRM_EOF = -2;
-
-    /**
-     * The media content length is unknown from native method
-     */
-    private static final int JNI_DRM_UNKNOWN_DATA_LEN = -3;
-
-    /**
-     * The member to save the original InputStream data.
-     */
-    private BufferedInputStream inData;
-
-    /**
-     * The member to save the original InputStream data length.
-     */
-    private int inDataLen;
-
-    /**
-     * The unique id to this DRM content. It will be initialized
-     * in constructor by native method. And it will not be changed
-     * after initialization.
-     */
-    private int id;
-
-    /**
-     * The rights issuer address of this DRM object.
-     */
-    private String rightsIssuer;
-
-    /**
-     * The media content type of this DRM object.
-     */
-    private String mediaType;
-
-    /**
-     * The delivery method type of this DRM object.
-     */
-    private int rawType;
-
-
-    /**
-     * Construct a DrmRawContent object.
-     *
-     * @param inRawdata     object of DRM raw data stream.
-     * @param len           the length of raw data can be read.
-     * @param mimeTypeStr   the mime type of the DRM content.
-     */
-    public DrmRawContent(InputStream inRawdata, int len, String mimeTypeStr) throws DrmException, IOException {
-        int mimeType;
-
-        id = -1;
-        inData = new BufferedInputStream(inRawdata, 1024);
-        inDataLen = len;
-
-        if (DRM_MIMETYPE_MESSAGE_STRING.equals(mimeTypeStr))
-            mimeType = DRM_MIMETYPE_MESSAGE;
-        else if (DRM_MIMETYPE_CONTENT_STRING.equals(mimeTypeStr))
-            mimeType = DRM_MIMETYPE_CONTENT;
-        else
-            throw new IllegalArgumentException("mimeType must be DRM_MIMETYPE_MESSAGE or DRM_MIMETYPE_CONTENT");
-
-        if (len <= 0)
-            throw new IllegalArgumentException("len must be > 0");
-
-        /* call native method to initialize this DRM content */
-        id = nativeConstructDrmContent(inData, inDataLen, mimeType);
-
-        if (JNI_DRM_FAILURE == id)
-            throw new DrmException("nativeConstructDrmContent() returned JNI_DRM_FAILURE");
-
-        /* init the rights issuer field. */
-        rightsIssuer = nativeGetRightsAddress();
-
-        /* init the raw content type. */
-        rawType = nativeGetDeliveryMethod();
-        if (JNI_DRM_FAILURE == rawType)
-            throw new DrmException("nativeGetDeliveryMethod() returned JNI_DRM_FAILURE");
-
-        /* init the media content type. */
-        mediaType = nativeGetContentType();
-        if (null == mediaType)
-            throw new DrmException("nativeGetContentType() returned null");
-    }
-
-    /**
-     * Get rights address from raw Seperate Delivery content.
-     *
-     * @return the string of the rights issuer address,
-     *         or null if no rights issuer.
-     */
-    public String getRightsAddress() {
-        return rightsIssuer;
-    }
-
-    /**
-     * Get the type of the raw DRM content.
-     *
-     * @return one of the following delivery type of this DRM content:
-     *              #DRM_FORWARD_LOCK
-     *              #DRM_COMBINED_DELIVERY
-     *              #DRM_SEPARATE_DELIVERY
-     *              #DRM_SEPARATE_DELIVERY_DM
-     */
-    public int getRawType() {
-        return rawType;
-    }
-
-    /**
-     * Get one InputStream object to read decrypted content.
-     *
-     * @param rights        the rights object contain decrypted key.
-     *
-     * @return the InputStream object of decrypted media content.
-     */
-    public InputStream getContentInputStream(DrmRights rights) {
-        if (null == rights)
-            throw new NullPointerException();
-
-        return new DrmInputStream(rights);
-    }
-
-    /**
-     * Get the type of the decrypted media content.
-     *
-     * @return the decrypted media content type of this DRM content.
-     */
-    public String getContentType() {
-        return mediaType;
-    }
-
-    /**
-     * Get the length of the decrypted media content.
-     *
-     * @param rights        the rights object contain decrypted key.
-     *
-     * @return the length of the decrypted media content.
-     *         #DRM_UNKNOWN_DATA_LEN if the length is unknown currently.
-     */
-    public int getContentLength(DrmRights rights) throws DrmException {
-        /**
-         * Because currently the media object associate with rights object
-         * has been handled in native logic, so here it is not need to deal
-         * the rights. But for the apps, it is mandatory for user to get
-         * the rights object before get the media content length.
-         */
-        if (null == rights)
-            throw new NullPointerException();
-
-        int mediaLen = nativeGetContentLength();
-
-        if (JNI_DRM_FAILURE == mediaLen)
-            throw new DrmException("nativeGetContentLength() returned JNI_DRM_FAILURE");
-
-        if (JNI_DRM_UNKNOWN_DATA_LEN == mediaLen)
-            return DRM_UNKNOWN_DATA_LEN;
-
-        return mediaLen;
-    }
-
-    /**
-     * This class provide a InputStream to the DRM media content.
-     */
-    class DrmInputStream extends InputStream
-    {
-        /**
-         * The flag to indicate whether this stream is closed or not.
-         */
-        private boolean isClosed;
-
-        /**
-         * The offset of this DRM content to be reset.
-         */
-        private int offset;
-
-        /**
-         * A byte of data to be readed.
-         */
-        private byte[] b;
-
-        /**
-         * Construct a DrmInputStream instance.
-         */
-        public DrmInputStream(DrmRights rights) {
-            /**
-             * Because currently the media object associate with rights object
-             * has been handled in native logic, so here it is not need to deal
-             * the rights. But for the apps, it is mandatory for user to get
-             * the rights object before get the media content data.
-             */
-
-            isClosed = false;
-            offset = 0;
-            b = new byte[1];
-        }
-
-        /* Non-javadoc
-         * @see java.io.InputStream#available()
-         */
-        public int available() throws IOException {
-            /* call native method to get this DRM decrypted media content length */
-            int len = nativeGetContentLength();
-
-            if (JNI_DRM_FAILURE == len)
-                throw new IOException();
-
-            /* if the length is unknown, just return 0 for available value */
-            if (JNI_DRM_UNKNOWN_DATA_LEN == len)
-                return 0;
-
-            int availableLen = len - offset;
-            if (availableLen < 0)
-                throw new IOException();
-
-            return availableLen;
-        }
-
-        /* Non-javadoc
-         * @see java.io.InputStream#read()
-         */
-        public int read() throws IOException {
-            int res;
-
-            res = read(b, 0, 1);
-
-            if (-1 == res)
-                return -1;
-
-            return b[0] & 0xff;
-        }
-
-        /* Non-javadoc
-         * @see java.io.InputStream#read(byte)
-         */
-        public int read(byte[] b) throws IOException {
-            return read(b, 0, b.length);
-        }
-
-        /* Non-javadoc
-         * @see java.io.InputStream#read(byte, int, int)
-         */
-        public int read(byte[] b, int off, int len) throws IOException {
-            if (null == b)
-                throw new NullPointerException();
-            if (off < 0 || len < 0 || off + len > b.length)
-                throw new IndexOutOfBoundsException();
-            if (true == isClosed)
-                throw new IOException();
-
-            if (0 == len)
-                return 0;
-
-            len = nativeReadContent(b, off, len, offset);
-
-            if (JNI_DRM_FAILURE == len)
-                throw new IOException();
-            else if (JNI_DRM_EOF == len)
-                return -1;
-
-            offset += len;
-
-            return len;
-        }
-
-        /* Non-javadoc
-         * @see java.io.InputStream#markSupported()
-         */
-        public boolean markSupported() {
-            return false;
-        }
-
-        /* Non-javadoc
-         * @see java.io.InputStream#mark(int)
-         */
-        public void mark(int readlimit) {
-        }
-
-        /* Non-javadoc
-         * @see java.io.InputStream#reset()
-         */
-        public void reset() throws IOException {
-            throw new IOException();
-        }
-
-        /* Non-javadoc
-         * @see java.io.InputStream#skip()
-         */
-        public long skip(long n) throws IOException {
-            return 0;
-        }
-
-        /* Non-javadoc
-         * @see java.io.InputStream#close()
-         */
-        public void close() {
-            isClosed = true;
-        }
-    }
-
-    /**
-     * native method: construct a DRM content according the mime type.
-     *
-     * @param data      input DRM content data to be parsed.
-     * @param len       the length of the data.
-     * @param mimeType  the mime type of this DRM content. the value of this field includes:
-     *                      #DRM_MIMETYPE_MESSAGE
-     *                      #DRM_MIMETYPE_CONTENT
-     *
-     * @return #the id of the DRM content if succeed.
-     *         #JNI_DRM_FAILURE if fail.
-     */
-    private native int nativeConstructDrmContent(InputStream data, int len, int mimeType);
-
-    /**
-     * native method: get this DRM content rights issuer.
-     *
-     * @return the address of rights issuer if in case of separate delivery.
-     *         null if not separete delivery, or otherwise.
-     */
-    private native String nativeGetRightsAddress();
-
-    /**
-     * native method: get this DRM content delivery type.
-     *
-     * @return the delivery method, the value may be one of the following:
-     *              #DRM_FORWARD_LOCK
-     *              #DRM_COMBINED_DELIVERY
-     *              #DRM_SEPARATE_DELIVERY
-     *              #DRM_SEPARATE_DELIVERY_DM
-     *         #JNI_DRM_FAILURE if fail.
-     */
-    private native int nativeGetDeliveryMethod();
-
-    /**
-     * native method: get a piece of media content data.
-     *
-     * @param buf       the buffer to save DRM media content data.
-     * @param bufOff    the offset of the buffer to start to save data.
-     * @param len       the number of byte to read.
-     * @param mediaOff  the offset of the media content data to start to read.
-     *
-     * @return the length of the media content data has been read.
-     *         #JNI_DRM_EOF if reach to end of the media content.
-     *         #JNI_DRM_FAILURE if fail.
-     */
-    private native int nativeReadContent(byte[] buf, int bufOff, int len, int mediaOff);
-
-    /**
-     * native method: get this DRM content type.
-     *
-     * @return the decrypted media content type.
-     *         null if fail.
-     */
-    private native String nativeGetContentType();
-
-    /**
-     * native method: get this DRM decrypted media content length.
-     *
-     * @return the length of decrypted media content.
-     *         #JNI_DRM_FAILURE if fail.
-     *         #JNI_DRM_UNKNOWN_DATA_LEN if the length is unknown currently.
-     */
-    private native int nativeGetContentLength();
-
-    /**
-     * The finalizer of the DRMRawContent. Do some cleanup.
-     */
-    protected native void finalize();
-
-
-    /**
-     * Load the shared library to link the native methods.
-     */
-    static {
-        try {
-            System.loadLibrary("drm1_jni");
-        }
-        catch (UnsatisfiedLinkError ule) {
-            System.err.println("WARNING: Could not load libdrm1_jni.so");
-        }
-    }
-}
diff --git a/media/java/android/drm/mobile1/DrmRights.java b/media/java/android/drm/mobile1/DrmRights.java
deleted file mode 100644
index bcccb6a..0000000
--- a/media/java/android/drm/mobile1/DrmRights.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.drm.mobile1;
-
-/**
- * This class provides interfaces to access the DRM rights.
- */
-public class DrmRights {
-    /**
-     * The DRM permission of play.
-     */
-    public static final int DRM_PERMISSION_PLAY = 1;
-
-    /**
-     * The DRM permission of display.
-     */
-    public static final int DRM_PERMISSION_DISPLAY = 2;
-
-    /**
-     * The DRM permission of execute.
-     */
-    public static final int DRM_PERMISSION_EXECUTE = 3;
-
-    /**
-     * The DRM permission of print.
-     */
-    public static final int DRM_PERMISSION_PRINT = 4;
-
-    /**
-     * Successful operation.
-     */
-    private static final int JNI_DRM_SUCCESS = 0;
-
-    /**
-     * General failure.
-     */
-    private static final int JNI_DRM_FAILURE = -1;
-
-    /**
-     * The uid of this rights object.
-     */
-    private String roId = "";
-
-
-    /**
-     * Construct the DrmRights.
-     */
-    public DrmRights() {
-    }
-
-    /**
-     * Get the constraint of the given permission on this rights object.
-     *
-     * @param permission    the given permission.
-     *
-     * @return a DrmConstraint instance.
-     */
-    public DrmConstraintInfo getConstraint(int permission) {
-        DrmConstraintInfo c = new DrmConstraintInfo();
-
-        /* call native method to get latest constraint information */
-        int res = nativeGetConstraintInfo(permission, c);
-
-        if (JNI_DRM_FAILURE == res)
-            return null;
-
-        return c;
-    }
-
-    /**
-     * Consume the rights of the given permission.
-     *
-     * @param permission    the given permission.
-     *
-     * @return true if consume success.
-     *         false if consume failure.
-     */
-    public boolean consumeRights(int permission) {
-        /* call native method to consume and update rights */
-        int res = nativeConsumeRights(permission);
-
-        if (JNI_DRM_FAILURE == res)
-            return false;
-
-        return true;
-    }
-
-
-    /**
-     * native method: get the constraint information of the given permission.
-     *
-     * @param permission    the given permission.
-     * @param constraint    the instance of constraint.
-     *
-     * @return #JNI_DRM_SUCCESS if succeed.
-     *         #JNI_DRM_FAILURE if fail.
-     */
-    private native int nativeGetConstraintInfo(int permission, DrmConstraintInfo constraint);
-
-    /**
-     * native method: consume the rights of the given permission.
-     *
-     * @param permission    the given permission.
-     *
-     * @return #JNI_DRM_SUCCESS if succeed.
-     *         #JNI_DRM_FAILURE if fail.
-     */
-    private native int nativeConsumeRights(int permission);
-
-
-    /**
-     * Load the shared library to link the native methods.
-     */
-    static {
-        try {
-            System.loadLibrary("drm1_jni");
-        }
-        catch (UnsatisfiedLinkError ule) {
-            System.err.println("WARNING: Could not load libdrm1_jni.so");
-        }
-    }
-}
diff --git a/media/java/android/drm/mobile1/DrmRightsManager.java b/media/java/android/drm/mobile1/DrmRightsManager.java
deleted file mode 100644
index 1bc36ec..0000000
--- a/media/java/android/drm/mobile1/DrmRightsManager.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.drm.mobile1;
-
-import java.io.*;
-import java.util.*;
-
-/**
- * This class provides interfaces to access the DRM right manager.
- */
-public class DrmRightsManager {
-    /**
-     * The "application/vnd.oma.drm.rights+xml" mime type.
-     */
-    public static final String DRM_MIMETYPE_RIGHTS_XML_STRING = "application/vnd.oma.drm.rights+xml";
-
-    /**
-     * The "application/vnd.oma.drm.rights+wbxml" mime type.
-     */
-    public static final String DRM_MIMETYPE_RIGHTS_WBXML_STRING = "application/vnd.oma.drm.rights+wbxml";
-
-    /**
-     * The id of "application/vnd.oma.drm.rights+xml" mime type.
-     */
-    private static final int DRM_MIMETYPE_RIGHTS_XML = 3;
-
-    /**
-     * The id of "application/vnd.oma.drm.rights+wbxml" mime type.
-     */
-    private static final int DRM_MIMETYPE_RIGHTS_WBXML = 4;
-
-    /**
-     * The id of "application/vnd.oma.drm.message" mime type.
-     */
-    private static final int DRM_MIMETYPE_MESSAGE = 1;
-
-    /**
-     * Successful operation.
-     */
-    private static final int JNI_DRM_SUCCESS = 0;
-
-    /**
-     * General failure.
-     */
-    private static final int JNI_DRM_FAILURE = -1;
-
-    /**
-     * The instance of the rights manager.
-     */
-    private static DrmRightsManager singleton = null;
-
-
-    /**
-     * Construct a DrmRightsManager
-     */
-    protected DrmRightsManager() {
-    }
-
-    /**
-     * Get the DrmRightsManager instance.
-     *
-     * @return the instance of DrmRightsManager.
-     */
-    public static synchronized DrmRightsManager getInstance() {
-        if (singleton == null) {
-            singleton = new DrmRightsManager();
-        }
-
-        return singleton;
-    }
-
-    /**
-     * Install one DRM rights and return one instance of DrmRights.
-     *
-     * @param rightsData    raw rights data.
-     * @param mimeTypeStr   the mime type of the rights object.
-     *
-     * @return the instance of the installed DrmRights.
-     */
-    public synchronized DrmRights installRights(InputStream rightsData, int len, String mimeTypeStr) throws DrmException, IOException {
-        int mimeType = 0;
-
-        if (DRM_MIMETYPE_RIGHTS_XML_STRING.equals(mimeTypeStr))
-            mimeType = DRM_MIMETYPE_RIGHTS_XML;
-        else if (DRM_MIMETYPE_RIGHTS_WBXML_STRING.equals(mimeTypeStr))
-            mimeType = DRM_MIMETYPE_RIGHTS_WBXML;
-        else if (DrmRawContent.DRM_MIMETYPE_MESSAGE_STRING.equals(mimeTypeStr))
-            mimeType = DRM_MIMETYPE_MESSAGE;
-        else
-            throw new IllegalArgumentException("mimeType must be DRM_MIMETYPE_RIGHTS_XML or DRM_MIMETYPE_RIGHTS_WBXML or DRM_MIMETYPE_MESSAGE");
-
-        if (len <= 0)
-            return null;
-
-        DrmRights rights = new DrmRights();
-
-        /* call native method to install this rights object. */
-        int res = nativeInstallDrmRights(rightsData, len, mimeType, rights);
-
-        if (JNI_DRM_FAILURE == res)
-            throw new DrmException("nativeInstallDrmRights() returned JNI_DRM_FAILURE");
-
-        return rights;
-    }
-
-    /**
-     * Query DRM rights of specified DRM raw content.
-     *
-     * @param content       raw content object.
-     *
-     * @return the instance of DrmRights, or null if there is no rights.
-     */
-    public synchronized DrmRights queryRights(DrmRawContent content) {
-        DrmRights rights = new DrmRights();
-
-        /* call native method to query the rights */
-        int res = nativeQueryRights(content, rights);
-
-        if (JNI_DRM_FAILURE == res)
-            return null;
-
-        return rights;
-    }
-
-    /**
-     * Get the list of all DRM rights saved in local client.
-     *
-     * @return the list of all the rights object.
-     */
-    public synchronized List getRightsList() {
-        List rightsList = new ArrayList();
-
-        /* call native method to get how many rights object in current agent */
-        int num = nativeGetNumOfRights();
-
-        if (JNI_DRM_FAILURE == num)
-            return null;
-
-        if (num > 0) {
-            DrmRights[] rightsArray = new DrmRights[num];
-            int i;
-
-            for (i = 0; i < num; i++)
-                rightsArray[i] = new DrmRights();
-
-            /* call native method to get all the rights information */
-            num = nativeGetRightsList(rightsArray, num);
-
-            if (JNI_DRM_FAILURE == num)
-                return null;
-
-            /* add all rights informations to ArrayList */
-            for (i = 0; i < num; i++)
-                rightsList.add(rightsArray[i]);
-        }
-
-        return rightsList;
-    }
-
-    /**
-     * Delete the specified DRM rights object.
-     *
-     * @param rights    the specified rights object to be deleted.
-     */
-    public synchronized void deleteRights(DrmRights rights) {
-        /* call native method to delete the specified rights object */
-        int res = nativeDeleteRights(rights);
-
-        if (JNI_DRM_FAILURE == res)
-            return;
-    }
-
-
-    /**
-     * native method: install rights object to local client.
-     *
-     * @param data      input DRM rights object data to be installed.
-     * @param len       the length of the data.
-     * @param mimeType  the mime type of this DRM rights object. the value of this field includes:
-     *                      #DRM_MIMETYPE_RIGHTS_XML
-     *                      #DRM_MIMETYPE_RIGHTS_WBXML
-     * @parma rights    the instance of DRMRights to be filled.
-     *
-     * @return #JNI_DRM_SUCCESS if succeed.
-     *         #JNI_DRM_FAILURE if fail.
-     */
-    private native int nativeInstallDrmRights(InputStream data, int len, int mimeType, DrmRights rights);
-
-    /**
-     * native method: query the given DRM content's rights object.
-     *
-     * @param content   the given DRM content.
-     * @param rights    the instance of rights to set if have.
-     *
-     * @return #JNI_DRM_SUCCESS if succeed.
-     *         #JNI_DRM_FAILURE if fail.
-     */
-    private native int nativeQueryRights(DrmRawContent content, DrmRights rights);
-
-    /**
-     * native method: get how many rights object in current DRM agent.
-     *
-     * @return the number of the rights object.
-     *         #JNI_DRM_FAILURE if fail.
-     */
-    private native int nativeGetNumOfRights();
-
-    /**
-     * native method: get all the rights object in current local agent.
-     *
-     * @param rights    the array instance of rights object.
-     * @param numRights how many rights can be saved.
-     *
-     * @return the number of the rights object has been gotten.
-     *         #JNI_DRM_FAILURE if fail.
-     */
-    private native int nativeGetRightsList(DrmRights[] rights, int numRights);
-
-    /**
-     * native method: delete a specified rights object.
-     *
-     * @param rights    the specified rights object to be deleted.
-     *
-     * @return #JNI_DRM_SUCCESS if succeed.
-     *         #JNI_DRM_FAILURE if fail.
-     */
-    private native int nativeDeleteRights(DrmRights rights);
-
-
-    /**
-     * Load the shared library to link the native methods.
-     */
-    static {
-        try {
-            System.loadLibrary("drm1_jni");
-        }
-        catch (UnsatisfiedLinkError ule) {
-            System.err.println("WARNING: Could not load libdrm1_jni.so");
-        }
-    }
-}
diff --git a/media/java/android/drm/mobile1/package.html b/media/java/android/drm/mobile1/package.html
deleted file mode 100644
index 1c9bf9d..0000000
--- a/media/java/android/drm/mobile1/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<html>
-<body>
-    {@hide}
-</body>
-</html>
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 93ab401..845baaf 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -551,9 +551,10 @@
         IAudioService service = getService();
         try {
             if (mUseMasterVolume) {
-                service.adjustMasterVolume(direction, flags);
+                service.adjustMasterVolume(direction, flags, mContext.getOpPackageName());
             } else {
-                service.adjustStreamVolume(streamType, direction, flags);
+                service.adjustStreamVolume(streamType, direction, flags,
+                        mContext.getOpPackageName());
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Dead object in adjustStreamVolume", e);
@@ -581,9 +582,9 @@
         IAudioService service = getService();
         try {
             if (mUseMasterVolume) {
-                service.adjustMasterVolume(direction, flags);
+                service.adjustMasterVolume(direction, flags, mContext.getOpPackageName());
             } else {
-                service.adjustVolume(direction, flags);
+                service.adjustVolume(direction, flags, mContext.getOpPackageName());
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Dead object in adjustVolume", e);
@@ -611,9 +612,10 @@
         IAudioService service = getService();
         try {
             if (mUseMasterVolume) {
-                service.adjustMasterVolume(direction, flags);
+                service.adjustMasterVolume(direction, flags, mContext.getOpPackageName());
             } else {
-                service.adjustSuggestedStreamVolume(direction, suggestedStreamType, flags);
+                service.adjustSuggestedStreamVolume(direction, suggestedStreamType, flags,
+                        mContext.getOpPackageName());
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Dead object in adjustSuggestedStreamVolume", e);
@@ -632,7 +634,7 @@
     public void adjustMasterVolume(int steps, int flags) {
         IAudioService service = getService();
         try {
-            service.adjustMasterVolume(steps, flags);
+            service.adjustMasterVolume(steps, flags, mContext.getOpPackageName());
         } catch (RemoteException e) {
             Log.e(TAG, "Dead object in adjustMasterVolume", e);
         }
@@ -784,9 +786,9 @@
         IAudioService service = getService();
         try {
             if (mUseMasterVolume) {
-                service.setMasterVolume(index, flags);
+                service.setMasterVolume(index, flags, mContext.getOpPackageName());
             } else {
-                service.setStreamVolume(streamType, index, flags);
+                service.setStreamVolume(streamType, index, flags, mContext.getOpPackageName());
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Dead object in setStreamVolume", e);
@@ -843,16 +845,16 @@
      * Sets the volume index for master volume.
      *
      * @param index The volume index to set. See
-     *            {@link #getMasterMaxVolume(int)} for the largest valid value.
+     *            {@link #getMasterMaxVolume()} for the largest valid value.
      * @param flags One or more flags.
-     * @see #getMasterMaxVolume(int)
-     * @see #getMasterVolume(int)
+     * @see #getMasterMaxVolume()
+     * @see #getMasterVolume()
      * @hide
      */
     public void setMasterVolume(int index, int flags) {
         IAudioService service = getService();
         try {
-            service.setMasterVolume(index, flags);
+            service.setMasterVolume(index, flags, mContext.getOpPackageName());
         } catch (RemoteException e) {
             Log.e(TAG, "Dead object in setMasterVolume", e);
         }
@@ -1314,19 +1316,6 @@
     }
 
     /**
-     * @hide
-     * Signals whether remote submix audio rerouting is enabled.
-     */
-    public void setRemoteSubmixOn(boolean on, int address) {
-        IAudioService service = getService();
-        try {
-            service.setRemoteSubmixOn(on, address);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Dead object in setRemoteSubmixOn", e);
-        }
-    }
-
-    /**
      * Sets audio routing to the wired headset on or off.
      *
      * @param on set <var>true</var> to route audio to/from wired
@@ -1543,12 +1532,18 @@
 
     /**
      * @hide
-     * Checks whether speech recognition is active
-     * @return true if a recording with source {@link MediaRecorder.AudioSource#VOICE_RECOGNITION}
-     *    is underway.
+     * Checks whether the current audio focus is exclusive.
+     * @return true if the top of the audio focus stack requested focus
+     *     with {@link #AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE}
      */
-    public boolean isSpeechRecognitionActive() {
-        return AudioSystem.isSourceActive(MediaRecorder.AudioSource.VOICE_RECOGNITION);
+    public boolean isAudioFocusExclusive() {
+        IAudioService service = getService();
+        try {
+            return service.getCurrentAudioFocus() == AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE;
+        } catch (RemoteException e) {
+            Log.e(TAG, "Dead object in isAudioFocusExclusive()", e);
+            return false;
+        }
     }
 
     /**
@@ -1563,7 +1558,8 @@
         }
         IAudioService service = getService();
         try {
-            service.adjustLocalOrRemoteStreamVolume(streamType, direction);
+            service.adjustLocalOrRemoteStreamVolume(streamType, direction,
+                    mContext.getOpPackageName());
         } catch (RemoteException e) {
             Log.e(TAG, "Dead object in adjustLocalOrRemoteStreamVolume", e);
         }
@@ -1582,7 +1578,7 @@
      */
     /**
      * @hide
-     * @deprecated Use {@link #setPrameters(String)} instead
+     * @deprecated Use {@link #setParameters(String)} instead
      */
     @Deprecated public void setParameter(String key, String value) {
         setParameters(key+"="+value);
@@ -1656,10 +1652,16 @@
      * @see #playSoundEffect(int)
      */
     public static final int FX_KEYPRESS_RETURN = 8;
+
+    /**
+     * Invalid keypress sound
+     * @see #playSoundEffect(int)
+     */
+    public static final int FX_KEYPRESS_INVALID = 9;
     /**
      * @hide Number of sound effects
      */
-    public static final int NUM_SOUND_EFFECTS = 9;
+    public static final int NUM_SOUND_EFFECTS = 10;
 
     /**
      * Plays a sound effect (Key clicks, lid open/close...)
@@ -1673,6 +1675,7 @@
      *            {@link #FX_KEYPRESS_SPACEBAR},
      *            {@link #FX_KEYPRESS_DELETE},
      *            {@link #FX_KEYPRESS_RETURN},
+     *            {@link #FX_KEYPRESS_INVALID},
      * NOTE: This version uses the UI settings to determine
      * whether sounds are heard or not.
      */
@@ -1705,6 +1708,7 @@
      *            {@link #FX_KEYPRESS_SPACEBAR},
      *            {@link #FX_KEYPRESS_DELETE},
      *            {@link #FX_KEYPRESS_RETURN},
+     *            {@link #FX_KEYPRESS_INVALID},
      * @param volume Sound effect volume.
      * The volume value is a raw scalar so UI controls should be scaled logarithmically.
      * If a volume of -1 is specified, the AudioManager.STREAM_MUSIC stream volume minus 3dB will be used.
@@ -1760,6 +1764,12 @@
     }
 
     /**
+     * @hide
+     * Used to indicate no audio focus has been gained or lost.
+     */
+    public static final int AUDIOFOCUS_NONE = 0;
+
+    /**
      * Used to indicate a gain of audio focus, or a request of audio focus, of unknown duration.
      * @see OnAudioFocusChangeListener#onAudioFocusChange(int)
      * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int)
@@ -1784,6 +1794,15 @@
      */
     public static final int AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK = 3;
     /**
+     * Used to indicate a temporary request of audio focus, anticipated to last a short
+     * amount of time, during which no other applications, or system components, should play
+     * anything. Examples of exclusive and transient audio focus requests are voice
+     * memo recording and speech recognition, during which the system shouldn't play any
+     * notifications, and media playback should have paused.
+     * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int)
+     */
+    public static final int AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE = 4;
+    /**
      * Used to indicate a loss of audio focus of unknown duration.
      * @see OnAudioFocusChangeListener#onAudioFocusChange(int)
      */
@@ -1947,14 +1966,17 @@
      *      for the playback of driving directions, or notifications sounds.
      *      Use {@link #AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK} to indicate also that it's ok for
      *      the previous focus owner to keep playing if it ducks its audio output.
+     *      Alternatively use {@link #AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE} for a temporary request
+     *      that benefits from the system not playing disruptive sounds like notifications, for
+     *      usecases such as voice memo recording, or speech recognition.
      *      Use {@link #AUDIOFOCUS_GAIN} for a focus request of unknown duration such
      *      as the playback of a song or a video.
      *  @return {@link #AUDIOFOCUS_REQUEST_FAILED} or {@link #AUDIOFOCUS_REQUEST_GRANTED}
      */
     public int requestAudioFocus(OnAudioFocusChangeListener l, int streamType, int durationHint) {
         int status = AUDIOFOCUS_REQUEST_FAILED;
-        if ((durationHint < AUDIOFOCUS_GAIN) || (durationHint > AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK))
-        {
+        if ((durationHint < AUDIOFOCUS_GAIN) ||
+                (durationHint > AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE)) {
             Log.e(TAG, "Invalid duration hint, audio focus request denied");
             return status;
         }
@@ -1964,7 +1986,7 @@
         try {
             status = service.requestAudioFocus(streamType, durationHint, mICallBack,
                     mAudioFocusDispatcher, getIdForAudioFocusListener(l),
-                    mContext.getPackageName() /* package name */);
+                    mContext.getOpPackageName() /* package name */);
         } catch (RemoteException e) {
             Log.e(TAG, "Can't call requestAudioFocus() on AudioService due to "+e);
         }
@@ -1985,8 +2007,8 @@
         IAudioService service = getService();
         try {
             service.requestAudioFocus(streamType, durationHint, mICallBack, null,
-                    AudioService.IN_VOICE_COMM_FOCUS_ID,
-                    "system" /* dump-friendly package name */);
+                    MediaFocusControl.IN_VOICE_COMM_FOCUS_ID,
+                    mContext.getOpPackageName());
         } catch (RemoteException e) {
             Log.e(TAG, "Can't call requestAudioFocusForCall() on AudioService due to "+e);
         }
@@ -2001,7 +2023,7 @@
     public void abandonAudioFocusForCall() {
         IAudioService service = getService();
         try {
-            service.abandonAudioFocus(null, AudioService.IN_VOICE_COMM_FOCUS_ID);
+            service.abandonAudioFocus(null, MediaFocusControl.IN_VOICE_COMM_FOCUS_ID);
         } catch (RemoteException e) {
             Log.e(TAG, "Can't call abandonAudioFocusForCall() on AudioService due to "+e);
         }
@@ -2328,6 +2350,24 @@
     }
 
     /**
+     * @hide
+     * Notify the user of a RemoteControlClient that it should update its metadata
+     * @param generationId the RemoteControlClient generation counter for which this request is
+     *         issued. Requests for an older generation than current one will be ignored.
+     * @param key the metadata key for which a new value exists
+     * @param value the new metadata value
+     */
+    public void updateRemoteControlClientMetadata(int generationId, int key, long value) {
+        IAudioService service = getService();
+        try {
+            service.updateRemoteControlClientMetadata(generationId, key, value);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Dead object in updateRemoteControlClientMetadata("+ generationId + ", "
+                    + key +", " + value + ")", e);
+        }
+    }
+
+    /**
      *  @hide
      *  Reload audio settings. This method is called by Settings backup
      *  agent when audio settings are restored and causes the AudioService
@@ -2342,6 +2382,35 @@
         }
     }
 
+    /**
+     * @hide
+     * Notifies AudioService that it is connected to an A2DP device that supports absolute volume,
+     * so that AudioService can send volume change events to the A2DP device, rather than handling
+     * them.
+     */
+    public void avrcpSupportsAbsoluteVolume(String address, boolean support) {
+        IAudioService service = getService();
+        try {
+            service.avrcpSupportsAbsoluteVolume(address, support);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Dead object in avrcpSupportsAbsoluteVolume", e);
+        }
+    }
+
+    /**
+     * @hide
+     * Notifies AudioService of the volume set on the A2DP device as a callback, so AudioService
+     * is able to update the UI.
+     */
+    public void avrcpUpdateVolume(int oldVolume, int volume) {
+        IAudioService service = getService();
+        try {
+            service.avrcpUpdateVolume(oldVolume, volume);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Dead object in avrcpUpdateVolume", e);
+        }
+    }
+
      /**
       * {@hide}
       */
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 5383d08..f49ef2e 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -17,8 +17,6 @@
 package android.media;
 
 import java.lang.ref.WeakReference;
-import java.lang.IllegalArgumentException;
-import java.lang.IllegalStateException;
 import java.nio.ByteBuffer;
 
 import android.os.Handler;
@@ -89,7 +87,7 @@
     private static final int AUDIORECORD_ERROR_SETUP_NATIVEINITFAILED    = -20;
 
     // Events:
-    // to keep in sync with frameworks/base/include/media/AudioRecord.h
+    // to keep in sync with frameworks/av/include/media/AudioRecord.h
     /**
      * Event id denotes when record head has reached a previously set marker.
      */
@@ -99,7 +97,7 @@
      */
     private static final int NATIVE_EVENT_NEW_POS = 3;
 
-    private final static String TAG = "AudioRecord-Java";
+    private final static String TAG = "android.media.AudioRecord";
 
 
     //---------------------------------------------------------
@@ -124,29 +122,25 @@
     /**
      * The audio data sampling rate in Hz.
      */
-    private int mSampleRate = 22050;
+    private int mSampleRate;
     /**
      * The number of input audio channels (1 is mono, 2 is stereo)
      */
-    private int mChannelCount = 1;
+    private int mChannelCount;
     /**
      * The audio channel mask
      */
-    private int mChannels = AudioFormat.CHANNEL_IN_MONO;
-    /**
-     * The current audio channel configuration
-     */
-    private int mChannelConfiguration = AudioFormat.CHANNEL_IN_MONO;
+    private int mChannelMask;
     /**
      * The encoding of the audio samples.
      * @see AudioFormat#ENCODING_PCM_8BIT
      * @see AudioFormat#ENCODING_PCM_16BIT
      */
-    private int mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
+    private int mAudioFormat;
     /**
      * Where the audio data is recorded from.
      */
-    private int mRecordSource = MediaRecorder.AudioSource.DEFAULT;
+    private int mRecordSource;
     /**
      * Indicates the state of the AudioRecord instance.
      */
@@ -214,7 +208,6 @@
     public AudioRecord(int audioSource, int sampleRateInHz, int channelConfig, int audioFormat,
             int bufferSizeInBytes)
     throws IllegalArgumentException {
-        mState = STATE_UNINITIALIZED;
         mRecordingState = RECORDSTATE_STOPPED;
 
         // remember which looper is associated with the AudioRecord instanciation
@@ -232,7 +225,7 @@
         //TODO: update native initialization when information about hardware init failure
         //      due to capture device already open is available.
         int initResult = native_setup( new WeakReference<AudioRecord>(this),
-                mRecordSource, mSampleRate, mChannels, mAudioFormat, mNativeBufferSizeInBytes,
+                mRecordSource, mSampleRate, mChannelMask, mAudioFormat, mNativeBufferSizeInBytes,
                 session);
         if (initResult != SUCCESS) {
             loge("Error code "+initResult+" when initializing native AudioRecord object.");
@@ -250,7 +243,7 @@
     // postconditions:
     //    mRecordSource is valid
     //    mChannelCount is valid
-    //    mChannels is valid
+    //    mChannelMask is valid
     //    mAudioFormat is valid
     //    mSampleRate is valid
     private void audioParamCheck(int audioSource, int sampleRateInHz,
@@ -259,46 +252,40 @@
         //--------------
         // audio source
         if ( (audioSource < MediaRecorder.AudioSource.DEFAULT) ||
-             (audioSource > MediaRecorder.getAudioSourceMax()) )  {
-            throw (new IllegalArgumentException("Invalid audio source."));
-        } else {
-            mRecordSource = audioSource;
+             ((audioSource > MediaRecorder.getAudioSourceMax()) &&
+              (audioSource != MediaRecorder.AudioSource.HOTWORD)) )  {
+            throw new IllegalArgumentException("Invalid audio source.");
         }
+        mRecordSource = audioSource;
 
         //--------------
         // sample rate
         if ( (sampleRateInHz < 4000) || (sampleRateInHz > 48000) ) {
-            throw (new IllegalArgumentException(sampleRateInHz
-                    + "Hz is not a supported sample rate."));
-        } else {
-            mSampleRate = sampleRateInHz;
+            throw new IllegalArgumentException(sampleRateInHz
+                    + "Hz is not a supported sample rate.");
         }
+        mSampleRate = sampleRateInHz;
 
         //--------------
         // channel config
-        mChannelConfiguration = channelConfig;
-
         switch (channelConfig) {
         case AudioFormat.CHANNEL_IN_DEFAULT: // AudioFormat.CHANNEL_CONFIGURATION_DEFAULT
         case AudioFormat.CHANNEL_IN_MONO:
         case AudioFormat.CHANNEL_CONFIGURATION_MONO:
             mChannelCount = 1;
-            mChannels = AudioFormat.CHANNEL_IN_MONO;
+            mChannelMask = AudioFormat.CHANNEL_IN_MONO;
             break;
         case AudioFormat.CHANNEL_IN_STEREO:
         case AudioFormat.CHANNEL_CONFIGURATION_STEREO:
             mChannelCount = 2;
-            mChannels = AudioFormat.CHANNEL_IN_STEREO;
+            mChannelMask = AudioFormat.CHANNEL_IN_STEREO;
             break;
         case (AudioFormat.CHANNEL_IN_FRONT | AudioFormat.CHANNEL_IN_BACK):
             mChannelCount = 2;
-            mChannels = channelConfig;
+            mChannelMask = channelConfig;
             break;
         default:
-            mChannelCount = 0;
-            mChannels = AudioFormat.CHANNEL_INVALID;
-            mChannelConfiguration = AudioFormat.CHANNEL_INVALID;
-            throw (new IllegalArgumentException("Unsupported channel configuration."));
+            throw new IllegalArgumentException("Unsupported channel configuration.");
         }
 
         //--------------
@@ -312,9 +299,8 @@
             mAudioFormat = audioFormat;
             break;
         default:
-            mAudioFormat = AudioFormat.ENCODING_INVALID;
-        throw (new IllegalArgumentException("Unsupported sample encoding."
-                + " Should be ENCODING_PCM_8BIT or ENCODING_PCM_16BIT."));
+            throw new IllegalArgumentException("Unsupported sample encoding."
+                    + " Should be ENCODING_PCM_8BIT or ENCODING_PCM_16BIT.");
         }
     }
 
@@ -331,7 +317,7 @@
         int frameSizeInBytes = mChannelCount
             * (mAudioFormat == AudioFormat.ENCODING_PCM_8BIT ? 1 : 2);
         if ((audioBufferSize % frameSizeInBytes != 0) || (audioBufferSize < 1)) {
-            throw (new IllegalArgumentException("Invalid audio buffer size."));
+            throw new IllegalArgumentException("Invalid audio buffer size.");
         }
 
         mNativeBufferSizeInBytes = audioBufferSize;
@@ -393,7 +379,7 @@
      * and {@link AudioFormat#CHANNEL_IN_STEREO}.
      */
     public int getChannelConfiguration() {
-        return mChannelConfiguration;
+        return mChannelMask;
     }
 
     /**
@@ -421,7 +407,9 @@
      * @see AudioRecord#RECORDSTATE_RECORDING
      */
     public int getRecordingState() {
-        return mRecordingState;
+        synchronized (mRecordingStateLock) {
+            return mRecordingState;
+        }
     }
 
     /**
@@ -440,10 +428,12 @@
 
     /**
      * Returns the minimum buffer size required for the successful creation of an AudioRecord
-     * object.
+     * object, in byte units.
      * Note that this size doesn't guarantee a smooth recording under load, and higher values
      * should be chosen according to the expected frequency at which the AudioRecord instance
      * will be polled for new data.
+     * See {@link #AudioRecord(int, int, int, int, int)} for more information on valid
+     * configuration values.
      * @param sampleRateInHz the sample rate expressed in Hertz.
      * @param channelConfig describes the configuration of the audio channels.
      *   See {@link AudioFormat#CHANNEL_IN_MONO} and
@@ -453,10 +443,9 @@
      * @return {@link #ERROR_BAD_VALUE} if the recording parameters are not supported by the
      *  hardware, or an invalid parameter was passed,
      *  or {@link #ERROR} if the implementation was unable to query the hardware for its
-     *  output properties,
+     *  input properties,
      *   or the minimum buffer size expressed in bytes.
-     * @see #AudioRecord(int, int, int, int, int) for more information on valid
-     *   configuration values.
+     * @see #AudioRecord(int, int, int, int, int)
      */
     static public int getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat) {
         int channelCount = 0;
@@ -474,21 +463,21 @@
         case AudioFormat.CHANNEL_INVALID:
         default:
             loge("getMinBufferSize(): Invalid channel configuration.");
-            return AudioRecord.ERROR_BAD_VALUE;
+            return ERROR_BAD_VALUE;
         }
 
         // PCM_8BIT is not supported at the moment
         if (audioFormat != AudioFormat.ENCODING_PCM_16BIT) {
             loge("getMinBufferSize(): Invalid audio format.");
-            return AudioRecord.ERROR_BAD_VALUE;
+            return ERROR_BAD_VALUE;
         }
 
         int size = native_get_min_buff_size(sampleRateInHz, channelCount, audioFormat);
         if (size == 0) {
-            return AudioRecord.ERROR_BAD_VALUE;
+            return ERROR_BAD_VALUE;
         }
         else if (size == -1) {
-            return AudioRecord.ERROR;
+            return ERROR;
         }
         else {
             return size;
@@ -514,8 +503,8 @@
     public void startRecording()
     throws IllegalStateException {
         if (mState != STATE_INITIALIZED) {
-            throw(new IllegalStateException("startRecording() called on an "
-                    +"uninitialized AudioRecord."));
+            throw new IllegalStateException("startRecording() called on an "
+                    + "uninitialized AudioRecord.");
         }
 
         // start recording
@@ -536,8 +525,8 @@
     public void startRecording(MediaSyncEvent syncEvent)
     throws IllegalStateException {
         if (mState != STATE_INITIALIZED) {
-            throw(new IllegalStateException("startRecording() called on an "
-                    +"uninitialized AudioRecord."));
+            throw new IllegalStateException("startRecording() called on an "
+                    + "uninitialized AudioRecord.");
         }
 
         // start recording
@@ -555,7 +544,7 @@
     public void stop()
     throws IllegalStateException {
         if (mState != STATE_INITIALIZED) {
-            throw(new IllegalStateException("stop() called on an uninitialized AudioRecord."));
+            throw new IllegalStateException("stop() called on an uninitialized AudioRecord.");
         }
 
         // stop recording
@@ -585,6 +574,7 @@
         }
 
         if ( (audioData == null) || (offsetInBytes < 0 ) || (sizeInBytes < 0)
+                || (offsetInBytes + sizeInBytes < 0)  // detect integer overflow
                 || (offsetInBytes + sizeInBytes > audioData.length)) {
             return ERROR_BAD_VALUE;
         }
@@ -609,6 +599,7 @@
         }
 
         if ( (audioData == null) || (offsetInShorts < 0 ) || (sizeInShorts < 0)
+                || (offsetInShorts + sizeInShorts < 0)  // detect integer overflow
                 || (offsetInShorts + sizeInShorts > audioData.length)) {
             return ERROR_BAD_VALUE;
         }
@@ -692,6 +683,9 @@
      *  {@link #ERROR_INVALID_OPERATION}
      */
     public int setNotificationMarkerPosition(int markerInFrames) {
+        if (mState == STATE_UNINITIALIZED) {
+            return ERROR_INVALID_OPERATION;
+        }
         return native_set_marker_pos(markerInFrames);
     }
 
@@ -700,10 +694,14 @@
      * Sets the period at which the listener is called, if set with
      * {@link #setRecordPositionUpdateListener(OnRecordPositionUpdateListener)} or
      * {@link #setRecordPositionUpdateListener(OnRecordPositionUpdateListener, Handler)}.
+     * It is possible for notifications to be lost if the period is too small.
      * @param periodInFrames update period expressed in frames
      * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_INVALID_OPERATION}
      */
     public int setPositionNotificationPeriod(int periodInFrames) {
+        if (mState == STATE_UNINITIALIZED) {
+            return ERROR_INVALID_OPERATION;
+        }
         return native_set_pos_update_period(periodInFrames);
     }
 
@@ -769,9 +767,8 @@
                 }
                 break;
             default:
-                Log.e(TAG, "[ android.media.AudioRecord.NativeEventHandler ] " +
-                        "Unknown event type: " + msg.what);
-            break;
+                loge("Unknown native event type: " + msg.what);
+                break;
             }
         }
     };
@@ -837,11 +834,11 @@
     //------------------
 
     private static void logd(String msg) {
-        Log.d(TAG, "[ android.media.AudioRecord ] " + msg);
+        Log.d(TAG, msg);
     }
 
     private static void loge(String msg) {
-        Log.e(TAG, "[ android.media.AudioRecord ] " + msg);
+        Log.e(TAG, msg);
     }
 
 }
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index aa91200..b72551a 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -22,11 +22,12 @@
 import static android.media.AudioManager.RINGER_MODE_VIBRATE;
 
 import android.app.Activity;
+import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
+import android.app.AppOpsManager;
 import android.app.KeyguardManager;
 import android.app.PendingIntent;
 import android.app.PendingIntent.CanceledException;
-import android.app.PendingIntent.OnFinished;
 import android.bluetooth.BluetoothA2dp;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothClass;
@@ -105,7 +106,7 @@
  *
  * @hide
  */
-public class AudioService extends IAudioService.Stub implements OnFinished {
+public class AudioService extends IAudioService.Stub {
 
     private static final String TAG = "AudioService";
 
@@ -117,9 +118,10 @@
     /** How long to delay before persisting a change in volume/ringer mode. */
     private static final int PERSIST_DELAY = 500;
 
-    private Context mContext;
-    private ContentResolver mContentResolver;
-    private boolean mVoiceCapable;
+    private final Context mContext;
+    private final ContentResolver mContentResolver;
+    private final AppOpsManager mAppOps;
+    private final boolean mVoiceCapable;
 
     /** The UI */
     private VolumePanel mVolumePanel;
@@ -138,39 +140,28 @@
     private static final int MSG_PERSIST_MASTER_VOLUME = 2;
     private static final int MSG_PERSIST_RINGER_MODE = 3;
     private static final int MSG_MEDIA_SERVER_DIED = 4;
-    private static final int MSG_MEDIA_SERVER_STARTED = 5;
-    private static final int MSG_PLAY_SOUND_EFFECT = 6;
-    private static final int MSG_BTA2DP_DOCK_TIMEOUT = 7;
-    private static final int MSG_LOAD_SOUND_EFFECTS = 8;
-    private static final int MSG_SET_FORCE_USE = 9;
-    private static final int MSG_PERSIST_MEDIABUTTONRECEIVER = 10;
-    private static final int MSG_BT_HEADSET_CNCT_FAILED = 11;
-    private static final int MSG_RCDISPLAY_CLEAR = 12;
-    private static final int MSG_RCDISPLAY_UPDATE = 13;
-    private static final int MSG_SET_ALL_VOLUMES = 14;
-    private static final int MSG_PERSIST_MASTER_VOLUME_MUTE = 15;
-    private static final int MSG_REPORT_NEW_ROUTES = 16;
-    private static final int MSG_REEVALUATE_REMOTE = 17;
-    private static final int MSG_RCC_NEW_PLAYBACK_INFO = 18;
-    private static final int MSG_RCC_NEW_VOLUME_OBS = 19;
-    private static final int MSG_SET_FORCE_BT_A2DP_USE = 20;
+    private static final int MSG_PLAY_SOUND_EFFECT = 5;
+    private static final int MSG_BTA2DP_DOCK_TIMEOUT = 6;
+    private static final int MSG_LOAD_SOUND_EFFECTS = 7;
+    private static final int MSG_SET_FORCE_USE = 8;
+    private static final int MSG_BT_HEADSET_CNCT_FAILED = 9;
+    private static final int MSG_SET_ALL_VOLUMES = 10;
+    private static final int MSG_PERSIST_MASTER_VOLUME_MUTE = 11;
+    private static final int MSG_REPORT_NEW_ROUTES = 12;
+    private static final int MSG_SET_FORCE_BT_A2DP_USE = 13;
+    private static final int MSG_CHECK_MUSIC_ACTIVE = 14;
+    private static final int MSG_BROADCAST_AUDIO_BECOMING_NOISY = 15;
+    private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME = 16;
+    private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED = 17;
+    private static final int MSG_PERSIST_SAFE_VOLUME_STATE = 18;
+    private static final int MSG_BROADCAST_BT_CONNECTION_STATE = 19;
+    private static final int MSG_UNLOAD_SOUND_EFFECTS = 20;
     // start of messages handled under wakelock
     //   these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(),
     //   and not with sendMsg(..., ..., SENDMSG_QUEUE, ...)
-    private static final int MSG_SET_WIRED_DEVICE_CONNECTION_STATE = 21;
-    private static final int MSG_SET_A2DP_CONNECTION_STATE = 22;
+    private static final int MSG_SET_WIRED_DEVICE_CONNECTION_STATE = 100;
+    private static final int MSG_SET_A2DP_CONNECTION_STATE = 101;
     // end of messages handled under wakelock
-    private static final int MSG_SET_RSX_CONNECTION_STATE = 23; // change remote submix connection
-    private static final int MSG_CHECK_MUSIC_ACTIVE = 24;
-    private static final int MSG_BROADCAST_AUDIO_BECOMING_NOISY = 25;
-    private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME = 26;
-    private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED = 27;
-    private static final int MSG_PERSIST_SAFE_VOLUME_STATE = 28;
-    private static final int MSG_PROMOTE_RCC = 29;
-    private static final int MSG_BROADCAST_BT_CONNECTION_STATE = 30;
-    private static final int MSG_UNLOAD_SOUND_EFFECTS = 31;
-    private static final int MSG_RCC_NEW_PLAYBACK_STATE = 32;
-    private static final int MSG_RCC_SEEK_REQUEST = 33;
 
     private static final int BTA2DP_DOCK_TIMEOUT_MILLIS = 8000;
     // Timeout for connection to bluetooth headset service
@@ -184,12 +175,10 @@
     private VolumeStreamState[] mStreamStates;
     private SettingsObserver mSettingsObserver;
 
-    private int mMode;
+    private int mMode = AudioSystem.MODE_NORMAL;
     // protects mRingerMode
     private final Object mSettingsLock = new Object();
 
-    private boolean mMediaServerOk;
-
     private SoundPool mSoundPool;
     private final Object mSoundEffectsLock = new Object();
     private static final int NUM_SOUNDPOOL_CHANNELS = 4;
@@ -211,7 +200,7 @@
     private final int[][] SOUND_EFFECT_FILES_MAP = new int[AudioManager.NUM_SOUND_EFFECTS][2];
 
    /** @hide Maximum volume index values for audio streams */
-    private final int[] MAX_STREAM_VOLUME = new int[] {
+    private static final int[] MAX_STREAM_VOLUME = new int[] {
         5,  // STREAM_VOICE_CALL
         7,  // STREAM_SYSTEM
         7,  // STREAM_RING
@@ -257,6 +246,23 @@
     };
     private int[] mStreamVolumeAlias;
 
+    /**
+     * Map AudioSystem.STREAM_* constants to app ops.  This should be used
+     * after mapping through mStreamVolumeAlias.
+     */
+    private static final int[] STEAM_VOLUME_OPS = new int[] {
+        AppOpsManager.OP_AUDIO_VOICE_VOLUME,            // STREAM_VOICE_CALL
+        AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_SYSTEM
+        AppOpsManager.OP_AUDIO_RING_VOLUME,             // STREAM_RING
+        AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_MUSIC
+        AppOpsManager.OP_AUDIO_ALARM_VOLUME,            // STREAM_ALARM
+        AppOpsManager.OP_AUDIO_NOTIFICATION_VOLUME,     // STREAM_NOTIFICATION
+        AppOpsManager.OP_AUDIO_BLUETOOTH_VOLUME,        // STREAM_BLUETOOTH_SCO
+        AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_SYSTEM_ENFORCED
+        AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_DTMF
+        AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_TTS
+    };
+
     private final boolean mUseFixedVolume;
 
     // stream names used by dumpStreamStates()
@@ -277,23 +283,13 @@
         public void onError(int error) {
             switch (error) {
             case AudioSystem.AUDIO_STATUS_SERVER_DIED:
-                if (mMediaServerOk) {
-                    sendMsg(mAudioHandler, MSG_MEDIA_SERVER_DIED, SENDMSG_NOOP, 0, 0,
-                            null, 1500);
-                    mMediaServerOk = false;
-                }
-                break;
-            case AudioSystem.AUDIO_STATUS_OK:
-                if (!mMediaServerOk) {
-                    sendMsg(mAudioHandler, MSG_MEDIA_SERVER_STARTED, SENDMSG_NOOP, 0, 0,
-                            null, 0);
-                    mMediaServerOk = true;
-                }
+                sendMsg(mAudioHandler, MSG_MEDIA_SERVER_DIED,
+                        SENDMSG_NOOP, 0, 0, null, 0);
                 break;
             default:
                 break;
             }
-       }
+        }
     };
 
     /**
@@ -326,9 +322,6 @@
     // Broadcast receiver for device connections intent broadcasts
     private final BroadcastReceiver mReceiver = new AudioServiceBroadcastReceiver();
 
-    // Used to alter media button redirection when the phone is ringing.
-    private boolean mIsRinging = false;
-
     // Devices currently connected
     private final HashMap <Integer, String> mConnectedDevices = new HashMap <Integer, String>();
 
@@ -449,6 +442,16 @@
     // and used later when/if disableSafeMediaVolume() is called.
     private StreamVolumeCommand mPendingVolumeCommand;
 
+    private PowerManager.WakeLock mAudioEventWakeLock;
+
+    private final MediaFocusControl mMediaFocusControl;
+
+    // Reference to BluetoothA2dp to query for AbsoluteVolume.
+    private BluetoothA2dp mA2dp;
+    private final Object mA2dpAvrcpLock = new Object();
+    // If absolute volume is supported in AVRCP device
+    private boolean mAvrcpAbsVolSupported = false;
+
     ///////////////////////////////////////////////////////////////////////////
     // Construction
     ///////////////////////////////////////////////////////////////////////////
@@ -457,11 +460,12 @@
     public AudioService(Context context) {
         mContext = context;
         mContentResolver = context.getContentResolver();
+        mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
         mVoiceCapable = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_voice_capable);
 
         PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
-        mMediaEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleMediaEvent");
+        mAudioEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleAudioEvent");
 
         Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
         mHasVibrator = vibrator == null ? false : vibrator.hasVibrator();
@@ -475,11 +479,15 @@
                 com.android.internal.R.integer.config_soundEffectVolumeDb);
 
         mVolumePanel = new VolumePanel(context, this);
-        mMode = AudioSystem.MODE_NORMAL;
         mForcedUseForComm = AudioSystem.FORCE_NONE;
 
         createAudioSystemThread();
 
+        mMediaFocusControl = new MediaFocusControl(mAudioHandler.getLooper(),
+                mContext, /*VolumeController*/ mVolumePanel, this);
+
+        AudioSystem.setErrorCallback(mAudioSystemCallback);
+
         boolean cameraSoundForced = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_camera_sound_forced);
         mCameraSoundForced = new Boolean(cameraSoundForced);
@@ -508,15 +516,13 @@
         updateStreamVolumeAlias(false /*updateVolumes*/);
         createStreamStates();
 
-        mMediaServerOk = true;
+        readAndSetLowRamDevice();
 
         // Call setRingerModeInt() to apply correct mute
         // state on streams affected by ringer mode.
         mRingerModeMutedStreams = 0;
         setRingerModeInt(getRingerMode(), false);
 
-        AudioSystem.setErrorCallback(mAudioSystemCallback);
-
         // Register for device connection intent broadcasts.
         IntentFilter intentFilter =
                 new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
@@ -548,20 +554,6 @@
 
         context.registerReceiver(mReceiver, intentFilter);
 
-        // Register for package removal intent broadcasts for media button receiver persistence
-        IntentFilter pkgFilter = new IntentFilter();
-        pkgFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
-        pkgFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
-        pkgFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
-        pkgFilter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED);
-        pkgFilter.addDataScheme("package");
-        context.registerReceiver(mReceiver, pkgFilter);
-
-        // Register for phone state monitoring
-        TelephonyManager tmgr = (TelephonyManager)
-                context.getSystemService(Context.TELEPHONY_SERVICE);
-        tmgr.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
-
         mUseMasterVolume = context.getResources().getBoolean(
                 com.android.internal.R.bool.config_useMasterVolume);
         restoreMasterVolume();
@@ -569,11 +561,6 @@
         mMasterVolumeRamp = context.getResources().getIntArray(
                 com.android.internal.R.array.config_masterVolumeRamp);
 
-        mMainRemote = new RemotePlaybackState(-1, MAX_STREAM_VOLUME[AudioManager.STREAM_MUSIC],
-                MAX_STREAM_VOLUME[AudioManager.STREAM_MUSIC]);
-        mHasRemotePlayback = false;
-        mMainRemoteIsActive = false;
-        postReevaluateRemote();
     }
 
     private void createAudioSystemThread() {
@@ -775,7 +762,7 @@
         broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION);
 
         // Restore the default media button receiver from the system settings
-        restoreMediaButtonReceiver();
+        mMediaFocusControl.restoreMediaButtonReceiver();
     }
 
     private int rescaleIndex(int index, int srcStream, int dstStream) {
@@ -787,23 +774,26 @@
     ///////////////////////////////////////////////////////////////////////////
 
     /** @see AudioManager#adjustVolume(int, int) */
-    public void adjustVolume(int direction, int flags) {
-        adjustSuggestedStreamVolume(direction, AudioManager.USE_DEFAULT_STREAM_TYPE, flags);
+    public void adjustVolume(int direction, int flags, String callingPackage) {
+        adjustSuggestedStreamVolume(direction, AudioManager.USE_DEFAULT_STREAM_TYPE, flags,
+                callingPackage);
     }
 
     /** @see AudioManager#adjustLocalOrRemoteStreamVolume(int, int) with current assumption
      *  on streamType: fixed to STREAM_MUSIC */
-    public void adjustLocalOrRemoteStreamVolume(int streamType, int direction) {
+    public void adjustLocalOrRemoteStreamVolume(int streamType, int direction,
+            String callingPackage) {
         if (DEBUG_VOL) Log.d(TAG, "adjustLocalOrRemoteStreamVolume(dir="+direction+")");
-        if (checkUpdateRemoteStateIfActive(AudioSystem.STREAM_MUSIC)) {
-            adjustRemoteVolume(AudioSystem.STREAM_MUSIC, direction, 0);
+        if (mMediaFocusControl.checkUpdateRemoteStateIfActive(AudioSystem.STREAM_MUSIC)) {
+            mMediaFocusControl.adjustRemoteVolume(AudioSystem.STREAM_MUSIC, direction, 0);
         } else if (AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0)) {
-            adjustStreamVolume(AudioSystem.STREAM_MUSIC, direction, 0);
+            adjustStreamVolume(AudioSystem.STREAM_MUSIC, direction, 0, callingPackage);
         }
     }
 
     /** @see AudioManager#adjustVolume(int, int) */
-    public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags) {
+    public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags,
+            String callingPackage) {
         if (DEBUG_VOL) Log.d(TAG, "adjustSuggestedStreamVolume() stream="+suggestedStreamType);
         int streamType;
         if (mVolumeControlStream != -1) {
@@ -824,14 +814,15 @@
             // don't play sounds for remote
             flags &= ~(AudioManager.FLAG_PLAY_SOUND|AudioManager.FLAG_FIXED_VOLUME);
             //if (DEBUG_VOL) Log.i(TAG, "Need to adjust remote volume: calling adjustRemoteVolume()");
-            adjustRemoteVolume(AudioSystem.STREAM_MUSIC, direction, flags);
+            mMediaFocusControl.adjustRemoteVolume(AudioSystem.STREAM_MUSIC, direction, flags);
         } else {
-            adjustStreamVolume(streamType, direction, flags);
+            adjustStreamVolume(streamType, direction, flags, callingPackage);
         }
     }
 
     /** @see AudioManager#adjustStreamVolume(int, int, int) */
-    public void adjustStreamVolume(int streamType, int direction, int flags) {
+    public void adjustStreamVolume(int streamType, int direction, int flags,
+            String callingPackage) {
         if (mUseFixedVolume) {
             return;
         }
@@ -852,6 +843,11 @@
         boolean adjustVolume = true;
         int step;
 
+        if (mAppOps.noteOp(STEAM_VOLUME_OPS[streamTypeAlias], Binder.getCallingUid(),
+                callingPackage) != AppOpsManager.MODE_ALLOWED) {
+            return;
+        }
+
         // reset any pending volume command
         synchronized (mSafeMediaVolumeState) {
             mPendingVolumeCommand = null;
@@ -896,6 +892,15 @@
         int oldIndex = mStreamStates[streamType].getIndex(device);
 
         if (adjustVolume && (direction != AudioManager.ADJUST_SAME)) {
+            // Check if volume update should be send to AVRCP
+            synchronized (mA2dpAvrcpLock) {
+                if (mA2dp != null && mAvrcpAbsVolSupported) {
+                    mA2dp.adjustAvrcpAbsoluteVolume(direction);
+                    return;
+                    // No need to send volume update, because we will update the volume with a
+                    // callback from Avrcp.
+                }
+            }
             if ((direction == AudioManager.ADJUST_RAISE) &&
                     !checkSafeMediaVolume(streamTypeAlias, aliasIndex + step, device)) {
                 Log.e(TAG, "adjustStreamVolume() safe volume index = "+oldIndex);
@@ -917,7 +922,7 @@
     }
 
     /** @see AudioManager#adjustMasterVolume(int, int) */
-    public void adjustMasterVolume(int steps, int flags) {
+    public void adjustMasterVolume(int steps, int flags, String callingPackage) {
         if (mUseFixedVolume) {
             return;
         }
@@ -932,7 +937,7 @@
         }
 
         //Log.d(TAG, "adjustMasterVolume volume: " + volume + " steps: " + steps);
-        setMasterVolume(volume, flags);
+        setMasterVolume(volume, flags, callingPackage);
     }
 
     // StreamVolumeCommand contains the information needed to defer the process of
@@ -968,27 +973,42 @@
     }
 
     /** @see AudioManager#setStreamVolume(int, int, int) */
-    public void setStreamVolume(int streamType, int index, int flags) {
+    public void setStreamVolume(int streamType, int index, int flags, String callingPackage) {
         if (mUseFixedVolume) {
             return;
         }
 
         ensureValidStreamType(streamType);
-        VolumeStreamState streamState = mStreamStates[mStreamVolumeAlias[streamType]];
+        int streamTypeAlias = mStreamVolumeAlias[streamType];
+        VolumeStreamState streamState = mStreamStates[streamTypeAlias];
 
         final int device = getDeviceForStream(streamType);
         int oldIndex;
 
+        if (mAppOps.noteOp(STEAM_VOLUME_OPS[streamTypeAlias], Binder.getCallingUid(),
+                callingPackage) != AppOpsManager.MODE_ALLOWED) {
+            return;
+        }
+
         synchronized (mSafeMediaVolumeState) {
             // reset any pending volume command
             mPendingVolumeCommand = null;
 
             oldIndex = streamState.getIndex(device);
 
-            index = rescaleIndex(index * 10, streamType, mStreamVolumeAlias[streamType]);
+            index = rescaleIndex(index * 10, streamType, streamTypeAlias);
+
+            synchronized (mA2dpAvrcpLock) {
+                if (mA2dp != null && mAvrcpAbsVolSupported) {
+                    mA2dp.setAvrcpAbsoluteVolume(index);
+                    return;
+                    // No need to send volume update, because we will update the volume with a
+                    // callback from Avrcp.
+                }
+            }
 
             flags &= ~AudioManager.FLAG_FIXED_VOLUME;
-            if ((mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) &&
+            if ((streamTypeAlias == AudioSystem.STREAM_MUSIC) &&
                     ((device & mFixedVolumeDevices) != 0)) {
                 flags |= AudioManager.FLAG_FIXED_VOLUME;
 
@@ -1003,7 +1023,7 @@
                 }
             }
 
-            if (!checkSafeMediaVolume(mStreamVolumeAlias[streamType], index, device)) {
+            if (!checkSafeMediaVolume(streamTypeAlias, index, device)) {
                 mVolumePanel.postDisplaySafeVolumeWarning(flags);
                 mPendingVolumeCommand = new StreamVolumeCommand(
                                                     streamType, index, flags, device);
@@ -1239,6 +1259,10 @@
         return AudioSystem.getMasterMute();
     }
 
+    protected static int getMaxStreamVolume(int streamType) {
+        return MAX_STREAM_VOLUME[streamType];
+    }
+
     /** @see AudioManager#getStreamVolume(int) */
     public int getStreamVolume(int streamType) {
         ensureValidStreamType(streamType);
@@ -1261,11 +1285,16 @@
         return getLastAudibleMasterVolume();
     }
 
-    public void setMasterVolume(int volume, int flags) {
+    public void setMasterVolume(int volume, int flags, String callingPackage) {
         if (mUseFixedVolume) {
             return;
         }
 
+        if (mAppOps.noteOp(AppOpsManager.OP_AUDIO_MASTER_VOLUME, Binder.getCallingUid(),
+                callingPackage) != AppOpsManager.MODE_ALLOWED) {
+            return;
+        }
+
         if (volume < 0) {
             volume = 0;
         } else if (volume > MAX_MASTER_VOLUME) {
@@ -1883,7 +1912,16 @@
         if (!checkAudioSettingsPermission("setSpeakerphoneOn()")) {
             return;
         }
-        mForcedUseForComm = on ? AudioSystem.FORCE_SPEAKER : AudioSystem.FORCE_NONE;
+
+        if (on) {
+            if (mForcedUseForComm == AudioSystem.FORCE_BT_SCO) {
+                    sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE,
+                            AudioSystem.FOR_RECORD, AudioSystem.FORCE_NONE, null, 0);
+            }
+            mForcedUseForComm = AudioSystem.FORCE_SPEAKER;
+        } else if (mForcedUseForComm == AudioSystem.FORCE_SPEAKER){
+            mForcedUseForComm = AudioSystem.FORCE_NONE;
+        }
 
         sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE,
                 AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, null, 0);
@@ -1899,7 +1937,12 @@
         if (!checkAudioSettingsPermission("setBluetoothScoOn()")) {
             return;
         }
-        mForcedUseForComm = on ? AudioSystem.FORCE_BT_SCO : AudioSystem.FORCE_NONE;
+
+        if (on) {
+            mForcedUseForComm = AudioSystem.FORCE_BT_SCO;
+        } else if (mForcedUseForComm == AudioSystem.FORCE_BT_SCO) {
+            mForcedUseForComm = AudioSystem.FORCE_NONE;
+        }
 
         sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE,
                 AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, null, 0);
@@ -2248,21 +2291,23 @@
             List<BluetoothDevice> deviceList;
             switch(profile) {
             case BluetoothProfile.A2DP:
-                BluetoothA2dp a2dp = (BluetoothA2dp) proxy;
-                deviceList = a2dp.getConnectedDevices();
-                if (deviceList.size() > 0) {
-                    btDevice = deviceList.get(0);
-                    synchronized (mConnectedDevices) {
-                        int state = a2dp.getConnectionState(btDevice);
-                        int delay = checkSendBecomingNoisyIntent(
-                                                AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
-                                                (state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0);
-                        queueMsgUnderWakeLock(mAudioHandler,
-                                MSG_SET_A2DP_CONNECTION_STATE,
-                                state,
-                                0,
-                                btDevice,
-                                delay);
+                synchronized (mA2dpAvrcpLock) {
+                    mA2dp = (BluetoothA2dp) proxy;
+                    deviceList = mA2dp.getConnectedDevices();
+                    if (deviceList.size() > 0) {
+                        btDevice = deviceList.get(0);
+                        synchronized (mConnectedDevices) {
+                            int state = mA2dp.getConnectionState(btDevice);
+                            int delay = checkSendBecomingNoisyIntent(
+                                                    AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
+                                                    (state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0);
+                            queueMsgUnderWakeLock(mAudioHandler,
+                                    MSG_SET_A2DP_CONNECTION_STATE,
+                                    state,
+                                    0,
+                                    btDevice,
+                                    delay);
+                        }
                     }
                 }
                 break;
@@ -2324,10 +2369,13 @@
         public void onServiceDisconnected(int profile) {
             switch(profile) {
             case BluetoothProfile.A2DP:
-                synchronized (mConnectedDevices) {
-                    if (mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP)) {
-                        makeA2dpDeviceUnavailableNow(
-                                mConnectedDevices.get(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP));
+                synchronized (mA2dpAvrcpLock) {
+                    mA2dp = null;
+                    synchronized (mConnectedDevices) {
+                        if (mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP)) {
+                            makeA2dpDeviceUnavailableNow(
+                                    mConnectedDevices.get(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP));
+                        }
                     }
                 }
                 break;
@@ -2344,26 +2392,6 @@
         }
     };
 
-    /** see AudioManager.setRemoteSubmixOn(boolean on) */
-    public void setRemoteSubmixOn(boolean on, int address) {
-        sendMsg(mAudioHandler, MSG_SET_RSX_CONNECTION_STATE,
-                SENDMSG_REPLACE /* replace with QUEUE when multiple addresses are supported */,
-                on ? 1 : 0 /*arg1*/,
-                address /*arg2*/,
-                null/*obj*/, 0/*delay*/);
-    }
-
-    private void onSetRsxConnectionState(int available, int address) {
-        AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_REMOTE_SUBMIX,
-                available == 1 ?
-                        AudioSystem.DEVICE_STATE_AVAILABLE : AudioSystem.DEVICE_STATE_UNAVAILABLE,
-                String.valueOf(address) /*device_address*/);
-        AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX,
-                available == 1 ?
-                        AudioSystem.DEVICE_STATE_AVAILABLE : AudioSystem.DEVICE_STATE_UNAVAILABLE,
-                String.valueOf(address) /*device_address*/);
-    }
-
     private void onCheckMusicActive() {
         synchronized (mSafeMediaVolumeState) {
             if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_INACTIVE) {
@@ -2557,7 +2585,7 @@
             } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
                 // Having the suggested stream be USE_DEFAULT_STREAM_TYPE is how remote control
                 // volume can have priority over STREAM_MUSIC
-                if (checkUpdateRemoteStateIfActive(AudioSystem.STREAM_MUSIC)) {
+                if (mMediaFocusControl.checkUpdateRemoteStateIfActive(AudioSystem.STREAM_MUSIC)) {
                     if (DEBUG_VOL)
                         Log.v(TAG, "getActiveStreamType: Forcing STREAM_REMOTE_MUSIC");
                     return STREAM_REMOTE_MUSIC;
@@ -2597,7 +2625,7 @@
                 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION");
                 return AudioSystem.STREAM_NOTIFICATION;
             } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
-                if (checkUpdateRemoteStateIfActive(AudioSystem.STREAM_MUSIC)) {
+                if (mMediaFocusControl.checkUpdateRemoteStateIfActive(AudioSystem.STREAM_MUSIC)) {
                     // Having the suggested stream be USE_DEFAULT_STREAM_TYPE is how remote control
                     // volume can have priority over STREAM_MUSIC
                     if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_REMOTE_MUSIC");
@@ -2641,7 +2669,7 @@
      */
     private void queueMsgUnderWakeLock(Handler handler, int msg,
             int arg1, int arg2, Object obj, int delay) {
-        mMediaEventWakeLock.acquire();
+        mAudioEventWakeLock.acquire();
         sendMsg(handler, msg, SENDMSG_QUEUE, arg1, arg2, obj, delay);
     }
 
@@ -3339,13 +3367,6 @@
             }
         }
 
-        private void onHandlePersistMediaButtonReceiver(ComponentName receiver) {
-            Settings.System.putStringForUser(mContentResolver,
-                                             Settings.System.MEDIA_BUTTON_RECEIVER,
-                                             receiver == null ? "" : receiver.flattenToString(),
-                                             UserHandle.USER_CURRENT);
-        }
-
         private void cleanupPlayer(MediaPlayer mp) {
             if (mp != null) {
                 try {
@@ -3411,24 +3432,22 @@
                     break;
 
                 case MSG_MEDIA_SERVER_DIED:
-                    if (!mMediaServerOk) {
+                    if (AudioSystem.checkAudioFlinger() != AudioSystem.AUDIO_STATUS_OK) {
                         Log.e(TAG, "Media server died.");
-                        // Force creation of new IAudioFlinger interface so that we are notified
-                        // when new media_server process is back to life.
-                        AudioSystem.setErrorCallback(mAudioSystemCallback);
                         sendMsg(mAudioHandler, MSG_MEDIA_SERVER_DIED, SENDMSG_NOOP, 0, 0,
                                 null, 500);
+                        break;
                     }
-                    break;
-
-                case MSG_MEDIA_SERVER_STARTED:
                     Log.e(TAG, "Media server started.");
+
                     // indicate to audio HAL that we start the reconfiguration phase after a media
                     // server crash
-                    // Note that MSG_MEDIA_SERVER_STARTED message is only received when the media server
+                    // Note that we only execute this when the media server
                     // process restarts after a crash, not the first time it is started.
                     AudioSystem.setParameters("restarting=true");
 
+                    readAndSetLowRamDevice();
+
                     // Restore device connection states
                     synchronized (mConnectedDevices) {
                         Set set = mConnectedDevices.entrySet();
@@ -3522,31 +3541,18 @@
                     setForceUse(msg.arg1, msg.arg2);
                     break;
 
-                case MSG_PERSIST_MEDIABUTTONRECEIVER:
-                    onHandlePersistMediaButtonReceiver( (ComponentName) msg.obj );
-                    break;
-
-                case MSG_RCDISPLAY_CLEAR:
-                    onRcDisplayClear();
-                    break;
-
-                case MSG_RCDISPLAY_UPDATE:
-                    // msg.obj is guaranteed to be non null
-                    onRcDisplayUpdate( (RemoteControlStackEntry) msg.obj, msg.arg1);
-                    break;
-
                 case MSG_BT_HEADSET_CNCT_FAILED:
                     resetBluetoothSco();
                     break;
 
                 case MSG_SET_WIRED_DEVICE_CONNECTION_STATE:
                     onSetWiredDeviceConnectionState(msg.arg1, msg.arg2, (String)msg.obj);
-                    mMediaEventWakeLock.release();
+                    mAudioEventWakeLock.release();
                     break;
 
                 case MSG_SET_A2DP_CONNECTION_STATE:
                     onSetA2dpConnectionState((BluetoothDevice)msg.obj, msg.arg1);
-                    mMediaEventWakeLock.release();
+                    mAudioEventWakeLock.release();
                     break;
 
                 case MSG_REPORT_NEW_ROUTES: {
@@ -3569,30 +3575,6 @@
                     break;
                 }
 
-                case MSG_REEVALUATE_REMOTE:
-                    onReevaluateRemote();
-                    break;
-
-                case MSG_RCC_NEW_PLAYBACK_INFO:
-                    onNewPlaybackInfoForRcc(msg.arg1 /* rccId */, msg.arg2 /* key */,
-                            ((Integer)msg.obj).intValue() /* value */);
-                    break;
-                case MSG_RCC_NEW_VOLUME_OBS:
-                    onRegisterVolumeObserverForRcc(msg.arg1 /* rccId */,
-                            (IRemoteVolumeObserver)msg.obj /* rvo */);
-                    break;
-                case MSG_RCC_NEW_PLAYBACK_STATE:
-                    onNewPlaybackStateForRcc(msg.arg1 /* rccId */, msg.arg2 /* state */,
-                            (RccPlaybackState)msg.obj /* newState */);
-                    break;
-                case MSG_RCC_SEEK_REQUEST:
-                    onSetRemoteControlClientPlaybackPosition(msg.arg1 /* generationId */,
-                            ((Long)msg.obj).longValue() /* timeMs */);
-
-                case MSG_SET_RSX_CONNECTION_STATE:
-                    onSetRsxConnectionState(msg.arg1/*available*/, msg.arg2/*address*/);
-                    break;
-
                 case MSG_CHECK_MUSIC_ACTIVE:
                     onCheckMusicActive();
                     break;
@@ -3609,10 +3591,6 @@
                     onPersistSafeVolumeState(msg.arg1);
                     break;
 
-                case MSG_PROMOTE_RCC:
-                    onPromoteRcc(msg.arg1);
-                    break;
-
                 case MSG_BROADCAST_BT_CONNECTION_STATE:
                     onBroadcastScoConnectionState(msg.arg1);
                     break;
@@ -3719,6 +3697,7 @@
 
     private void onSetA2dpConnectionState(BluetoothDevice btDevice, int state)
     {
+        if (DEBUG_VOL) Log.d(TAG, "onSetA2dpConnectionState btDevice="+btDevice+" state="+state);
         if (btDevice == null) {
             return;
         }
@@ -3726,6 +3705,20 @@
         if (!BluetoothAdapter.checkBluetoothAddress(address)) {
             address = "";
         }
+
+        // Disable absolute volume, if device is disconnected
+        synchronized (mA2dpAvrcpLock) {
+            if (state == BluetoothProfile.STATE_DISCONNECTED && mAvrcpAbsVolSupported) {
+                mAvrcpAbsVolSupported = false;
+                sendMsg(mAudioHandler,
+                        MSG_SET_DEVICE_VOLUME,
+                        SENDMSG_QUEUE,
+                        getDeviceForStream(AudioSystem.STREAM_MUSIC),
+                        0,
+                        mStreamStates[AudioSystem.STREAM_MUSIC],
+                        0);
+            }
+        }
         synchronized (mConnectedDevices) {
             boolean isConnected =
                 (mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) &&
@@ -3776,6 +3769,31 @@
         }
     }
 
+    public void avrcpSupportsAbsoluteVolume(String address, boolean support) {
+        // address is not used for now, but may be used when multiple a2dp devices are supported
+        synchronized (mA2dpAvrcpLock) {
+            mAvrcpAbsVolSupported = support;
+            if (support) {
+                VolumeStreamState streamState = mStreamStates[AudioSystem.STREAM_MUSIC];
+                int device = getDeviceForStream(AudioSystem.STREAM_MUSIC);
+                streamState.setIndex(streamState.getMaxIndex(), device);
+                sendMsg(mAudioHandler,
+                        MSG_SET_DEVICE_VOLUME,
+                        SENDMSG_QUEUE,
+                        device,
+                        0,
+                        streamState,
+                        0);
+            }
+        }
+    }
+
+    public void avrcpUpdateVolume(int oldVolume, int volume) {
+        mStreamStates[AudioSystem.STREAM_MUSIC].
+                        setIndex(volume, getDeviceForStream(AudioSystem.STREAM_MUSIC));
+        sendVolumeUpdate(AudioSystem.STREAM_MUSIC, oldVolume, volume, AudioManager.FLAG_SHOW_UI);
+    }
+
     private boolean handleDeviceConnection(boolean connected, int device, String params) {
         synchronized (mConnectedDevices) {
             boolean isConnected = (mConnectedDevices.containsKey(device) &&
@@ -4090,21 +4108,6 @@
                         0,
                         null,
                         SAFE_VOLUME_CONFIGURE_TIMEOUT_MS);
-            } else if (action.equals(Intent.ACTION_PACKAGE_REMOVED)
-                    || action.equals(Intent.ACTION_PACKAGE_DATA_CLEARED)) {
-                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
-                    // a package is being removed, not replaced
-                    String packageName = intent.getData().getSchemeSpecificPart();
-                    if (packageName != null) {
-                        cleanupMediaButtonReceiverForPackage(packageName, true);
-                    }
-                }
-            } else if (action.equals(Intent.ACTION_PACKAGE_ADDED)
-                    || action.equals(Intent.ACTION_PACKAGE_CHANGED)) {
-                String packageName = intent.getData().getSchemeSpecificPart();
-                if (packageName != null) {
-                    cleanupMediaButtonReceiverForPackage(packageName, false);
-                }
             } else if (action.equals(Intent.ACTION_SCREEN_ON)) {
                 AudioSystem.setParameters("screen_state=on");
             } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
@@ -4121,7 +4124,7 @@
                         null,
                         0);
                 // the current audio focus owner is no longer valid
-                discardAudioFocusOwner();
+                mMediaFocusControl.discardAudioFocusOwner();
 
                 // load volume settings for new user
                 readAudioSettings(true /*userSwitch*/);
@@ -4137,2204 +4140,110 @@
     }
 
     //==========================================================================================
-    // AudioFocus
+    // RemoteControlDisplay / RemoteControlClient / Remote info
     //==========================================================================================
-
-    /* constant to identify focus stack entry that is used to hold the focus while the phone
-     * is ringing or during a call. Used by com.android.internal.telephony.CallManager when
-     * entering and exiting calls.
-     */
-    public final static String IN_VOICE_COMM_FOCUS_ID = "AudioFocus_For_Phone_Ring_And_Calls";
-
-    private final static Object mAudioFocusLock = new Object();
-
-    private final static Object mRingingLock = new Object();
-
-    private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
-        @Override
-        public void onCallStateChanged(int state, String incomingNumber) {
-            if (state == TelephonyManager.CALL_STATE_RINGING) {
-                //Log.v(TAG, " CALL_STATE_RINGING");
-                synchronized(mRingingLock) {
-                    mIsRinging = true;
-                }
-            } else if ((state == TelephonyManager.CALL_STATE_OFFHOOK)
-                    || (state == TelephonyManager.CALL_STATE_IDLE)) {
-                synchronized(mRingingLock) {
-                    mIsRinging = false;
-                }
-            }
-        }
-    };
-
-    /**
-     * Discard the current audio focus owner.
-     * Notify top of audio focus stack that it lost focus (regardless of possibility to reassign
-     * focus), remove it from the stack, and clear the remote control display.
-     */
-    private void discardAudioFocusOwner() {
-        synchronized(mAudioFocusLock) {
-            if (!mFocusStack.empty() && (mFocusStack.peek().mFocusDispatcher != null)) {
-                // notify the current focus owner it lost focus after removing it from stack
-                FocusStackEntry focusOwner = mFocusStack.pop();
-                try {
-                    focusOwner.mFocusDispatcher.dispatchAudioFocusChange(
-                            AudioManager.AUDIOFOCUS_LOSS, focusOwner.mClientId);
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Failure to signal loss of audio focus due to "+ e);
-                    e.printStackTrace();
-                }
-                focusOwner.unlinkToDeath();
-                // clear RCD
-                synchronized(mRCStack) {
-                    clearRemoteControlDisplay_syncAfRcs();
-                }
-            }
-        }
-    }
-
-    private void notifyTopOfAudioFocusStack() {
-        // notify the top of the stack it gained focus
-        if (!mFocusStack.empty() && (mFocusStack.peek().mFocusDispatcher != null)) {
-            if (canReassignAudioFocus()) {
-                try {
-                    mFocusStack.peek().mFocusDispatcher.dispatchAudioFocusChange(
-                            AudioManager.AUDIOFOCUS_GAIN, mFocusStack.peek().mClientId);
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Failure to signal gain of audio control focus due to "+ e);
-                    e.printStackTrace();
-                }
-            }
-        }
-    }
-
-    private static class FocusStackEntry {
-        public int mStreamType = -1;// no stream type
-        public IAudioFocusDispatcher mFocusDispatcher = null;
-        public IBinder mSourceRef = null;
-        public String mClientId;
-        public int mFocusChangeType;
-        public AudioFocusDeathHandler mHandler;
-        public String mPackageName;
-        public int mCallingUid;
-
-        public FocusStackEntry() {
-        }
-
-        public FocusStackEntry(int streamType, int duration,
-                IAudioFocusDispatcher afl, IBinder source, String id, AudioFocusDeathHandler hdlr,
-                String pn, int uid) {
-            mStreamType = streamType;
-            mFocusDispatcher = afl;
-            mSourceRef = source;
-            mClientId = id;
-            mFocusChangeType = duration;
-            mHandler = hdlr;
-            mPackageName = pn;
-            mCallingUid = uid;
-        }
-
-        public void unlinkToDeath() {
-            try {
-                if (mSourceRef != null && mHandler != null) {
-                    mSourceRef.unlinkToDeath(mHandler, 0);
-                    mHandler = null;
-                }
-            } catch (java.util.NoSuchElementException e) {
-                Log.e(TAG, "Encountered " + e + " in FocusStackEntry.unlinkToDeath()");
-            }
-        }
-
-        @Override
-        protected void finalize() throws Throwable {
-            unlinkToDeath(); // unlink exception handled inside method
-            super.finalize();
-        }
-    }
-
-    private final Stack<FocusStackEntry> mFocusStack = new Stack<FocusStackEntry>();
-
-    /**
-     * Helper function:
-     * Display in the log the current entries in the audio focus stack
-     */
-    private void dumpFocusStack(PrintWriter pw) {
-        pw.println("\nAudio Focus stack entries (last is top of stack):");
-        synchronized(mAudioFocusLock) {
-            Iterator<FocusStackEntry> stackIterator = mFocusStack.iterator();
-            while(stackIterator.hasNext()) {
-                FocusStackEntry fse = stackIterator.next();
-                pw.println("  source:" + fse.mSourceRef
-                        + " -- pack: " + fse.mPackageName
-                        + " -- client: " + fse.mClientId
-                        + " -- duration: " + fse.mFocusChangeType
-                        + " -- uid: " + fse.mCallingUid
-                        + " -- stream: " + fse.mStreamType);
-            }
-        }
-    }
-
-    /**
-     * Helper function:
-     * Called synchronized on mAudioFocusLock
-     * Remove a focus listener from the focus stack.
-     * @param clientToRemove the focus listener
-     * @param signal if true and the listener was at the top of the focus stack, i.e. it was holding
-     *   focus, notify the next item in the stack it gained focus.
-     */
-    private void removeFocusStackEntry(String clientToRemove, boolean signal) {
-        // is the current top of the focus stack abandoning focus? (because of request, not death)
-        if (!mFocusStack.empty() && mFocusStack.peek().mClientId.equals(clientToRemove))
-        {
-            //Log.i(TAG, "   removeFocusStackEntry() removing top of stack");
-            FocusStackEntry fse = mFocusStack.pop();
-            fse.unlinkToDeath();
-            if (signal) {
-                // notify the new top of the stack it gained focus
-                notifyTopOfAudioFocusStack();
-                // there's a new top of the stack, let the remote control know
-                synchronized(mRCStack) {
-                    checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
-                }
-            }
-        } else {
-            // focus is abandoned by a client that's not at the top of the stack,
-            // no need to update focus.
-            // (using an iterator on the stack so we can safely remove an entry after having
-            //  evaluated it, traversal order doesn't matter here)
-            Iterator<FocusStackEntry> stackIterator = mFocusStack.iterator();
-            while(stackIterator.hasNext()) {
-                FocusStackEntry fse = (FocusStackEntry)stackIterator.next();
-                if(fse.mClientId.equals(clientToRemove)) {
-                    Log.i(TAG, " AudioFocus  abandonAudioFocus(): removing entry for "
-                            + fse.mClientId);
-                    stackIterator.remove();
-                    fse.unlinkToDeath();
-                }
-            }
-        }
-    }
-
-    /**
-     * Helper function:
-     * Called synchronized on mAudioFocusLock
-     * Remove focus listeners from the focus stack for a particular client when it has died.
-     */
-    private void removeFocusStackEntryForClient(IBinder cb) {
-        // is the owner of the audio focus part of the client to remove?
-        boolean isTopOfStackForClientToRemove = !mFocusStack.isEmpty() &&
-                mFocusStack.peek().mSourceRef.equals(cb);
-        // (using an iterator on the stack so we can safely remove an entry after having
-        //  evaluated it, traversal order doesn't matter here)
-        Iterator<FocusStackEntry> stackIterator = mFocusStack.iterator();
-        while(stackIterator.hasNext()) {
-            FocusStackEntry fse = (FocusStackEntry)stackIterator.next();
-            if(fse.mSourceRef.equals(cb)) {
-                Log.i(TAG, " AudioFocus  abandonAudioFocus(): removing entry for "
-                        + fse.mClientId);
-                stackIterator.remove();
-                // the client just died, no need to unlink to its death
-            }
-        }
-        if (isTopOfStackForClientToRemove) {
-            // we removed an entry at the top of the stack:
-            //  notify the new top of the stack it gained focus.
-            notifyTopOfAudioFocusStack();
-            // there's a new top of the stack, let the remote control know
-            synchronized(mRCStack) {
-                checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
-            }
-        }
-    }
-
-    /**
-     * Helper function:
-     * Returns true if the system is in a state where the focus can be reevaluated, false otherwise.
-     */
-    private boolean canReassignAudioFocus() {
-        // focus requests are rejected during a phone call or when the phone is ringing
-        // this is equivalent to IN_VOICE_COMM_FOCUS_ID having the focus
-        if (!mFocusStack.isEmpty() && IN_VOICE_COMM_FOCUS_ID.equals(mFocusStack.peek().mClientId)) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Inner class to monitor audio focus client deaths, and remove them from the audio focus
-     * stack if necessary.
-     */
-    private class AudioFocusDeathHandler implements IBinder.DeathRecipient {
-        private IBinder mCb; // To be notified of client's death
-
-        AudioFocusDeathHandler(IBinder cb) {
-            mCb = cb;
-        }
-
-        public void binderDied() {
-            synchronized(mAudioFocusLock) {
-                Log.w(TAG, "  AudioFocus   audio focus client died");
-                removeFocusStackEntryForClient(mCb);
-            }
-        }
-
-        public IBinder getBinder() {
-            return mCb;
-        }
-    }
-
-
-    /** @see AudioManager#requestAudioFocus(AudioManager.OnAudioFocusChangeListener, int, int)  */
-    public int requestAudioFocus(int mainStreamType, int focusChangeHint, IBinder cb,
-            IAudioFocusDispatcher fd, String clientId, String callingPackageName) {
-        Log.i(TAG, " AudioFocus  requestAudioFocus() from " + clientId);
-        // the main stream type for the audio focus request is currently not used. It may
-        // potentially be used to handle multiple stream type-dependent audio focuses.
-
-        // we need a valid binder callback for clients
-        if (!cb.pingBinder()) {
-            Log.e(TAG, " AudioFocus DOA client for requestAudioFocus(), aborting.");
-            return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
-        }
-
-        synchronized(mAudioFocusLock) {
-            if (!canReassignAudioFocus()) {
-                return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
-            }
-
-            // handle the potential premature death of the new holder of the focus
-            // (premature death == death before abandoning focus)
-            // Register for client death notification
-            AudioFocusDeathHandler afdh = new AudioFocusDeathHandler(cb);
-            try {
-                cb.linkToDeath(afdh, 0);
-            } catch (RemoteException e) {
-                // client has already died!
-                Log.w(TAG, "AudioFocus  requestAudioFocus() could not link to "+cb+" binder death");
-                return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
-            }
-
-            if (!mFocusStack.empty() && mFocusStack.peek().mClientId.equals(clientId)) {
-                // if focus is already owned by this client and the reason for acquiring the focus
-                // hasn't changed, don't do anything
-                if (mFocusStack.peek().mFocusChangeType == focusChangeHint) {
-                    // unlink death handler so it can be gc'ed.
-                    // linkToDeath() creates a JNI global reference preventing collection.
-                    cb.unlinkToDeath(afdh, 0);
-                    return AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
-                }
-                // the reason for the audio focus request has changed: remove the current top of
-                // stack and respond as if we had a new focus owner
-                FocusStackEntry fse = mFocusStack.pop();
-                fse.unlinkToDeath();
-            }
-
-            // notify current top of stack it is losing focus
-            if (!mFocusStack.empty() && (mFocusStack.peek().mFocusDispatcher != null)) {
-                try {
-                    mFocusStack.peek().mFocusDispatcher.dispatchAudioFocusChange(
-                            -1 * focusChangeHint, // loss and gain codes are inverse of each other
-                            mFocusStack.peek().mClientId);
-                } catch (RemoteException e) {
-                    Log.e(TAG, " Failure to signal loss of focus due to "+ e);
-                    e.printStackTrace();
-                }
-            }
-
-            // focus requester might already be somewhere below in the stack, remove it
-            removeFocusStackEntry(clientId, false /* signal */);
-
-            // push focus requester at the top of the audio focus stack
-            mFocusStack.push(new FocusStackEntry(mainStreamType, focusChangeHint, fd, cb,
-                    clientId, afdh, callingPackageName, Binder.getCallingUid()));
-
-            // there's a new top of the stack, let the remote control know
-            synchronized(mRCStack) {
-                checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
-            }
-        }//synchronized(mAudioFocusLock)
-
-        return AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
-    }
-
-    /** @see AudioManager#abandonAudioFocus(AudioManager.OnAudioFocusChangeListener)  */
-    public int abandonAudioFocus(IAudioFocusDispatcher fl, String clientId) {
-        Log.i(TAG, " AudioFocus  abandonAudioFocus() from " + clientId);
-        try {
-            // this will take care of notifying the new focus owner if needed
-            synchronized(mAudioFocusLock) {
-                removeFocusStackEntry(clientId, true);
-            }
-        } catch (java.util.ConcurrentModificationException cme) {
-            // Catching this exception here is temporary. It is here just to prevent
-            // a crash seen when the "Silent" notification is played. This is believed to be fixed
-            // but this try catch block is left just to be safe.
-            Log.e(TAG, "FATAL EXCEPTION AudioFocus  abandonAudioFocus() caused " + cme);
-            cme.printStackTrace();
-        }
-
-        return AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
-    }
-
-
-    public void unregisterAudioFocusClient(String clientId) {
-        synchronized(mAudioFocusLock) {
-            removeFocusStackEntry(clientId, false);
-        }
-    }
-
-
-    //==========================================================================================
-    // RemoteControl
-    //==========================================================================================
-    public void dispatchMediaKeyEvent(KeyEvent keyEvent) {
-        filterMediaKeyEvent(keyEvent, false /*needWakeLock*/);
-    }
-
-    public void dispatchMediaKeyEventUnderWakelock(KeyEvent keyEvent) {
-        filterMediaKeyEvent(keyEvent, true /*needWakeLock*/);
-    }
-
-    private void filterMediaKeyEvent(KeyEvent keyEvent, boolean needWakeLock) {
-        // sanity check on the incoming key event
-        if (!isValidMediaKeyEvent(keyEvent)) {
-            Log.e(TAG, "not dispatching invalid media key event " + keyEvent);
-            return;
-        }
-        // event filtering for telephony
-        synchronized(mRingingLock) {
-            synchronized(mRCStack) {
-                if ((mMediaReceiverForCalls != null) &&
-                        (mIsRinging || (getMode() == AudioSystem.MODE_IN_CALL))) {
-                    dispatchMediaKeyEventForCalls(keyEvent, needWakeLock);
-                    return;
-                }
-            }
-        }
-        // event filtering based on voice-based interactions
-        if (isValidVoiceInputKeyCode(keyEvent.getKeyCode())) {
-            filterVoiceInputKeyEvent(keyEvent, needWakeLock);
-        } else {
-            dispatchMediaKeyEvent(keyEvent, needWakeLock);
-        }
-    }
-
-    /**
-     * Handles the dispatching of the media button events to the telephony package.
-     * Precondition: mMediaReceiverForCalls != null
-     * @param keyEvent a non-null KeyEvent whose key code is one of the supported media buttons
-     * @param needWakeLock true if a PARTIAL_WAKE_LOCK needs to be held while this key event
-     *     is dispatched.
-     */
-    private void dispatchMediaKeyEventForCalls(KeyEvent keyEvent, boolean needWakeLock) {
-        Intent keyIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
-        keyIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
-        keyIntent.setPackage(mMediaReceiverForCalls.getPackageName());
-        if (needWakeLock) {
-            mMediaEventWakeLock.acquire();
-            keyIntent.putExtra(EXTRA_WAKELOCK_ACQUIRED, WAKELOCK_RELEASE_ON_FINISHED);
-        }
-        final long ident = Binder.clearCallingIdentity();
-        try {
-            mContext.sendOrderedBroadcastAsUser(keyIntent, UserHandle.ALL,
-                    null, mKeyEventDone, mAudioHandler, Activity.RESULT_OK, null, null);
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
-    }
-
-    /**
-     * Handles the dispatching of the media button events to one of the registered listeners,
-     * or if there was none, broadcast an ACTION_MEDIA_BUTTON intent to the rest of the system.
-     * @param keyEvent a non-null KeyEvent whose key code is one of the supported media buttons
-     * @param needWakeLock true if a PARTIAL_WAKE_LOCK needs to be held while this key event
-     *     is dispatched.
-     */
-    private void dispatchMediaKeyEvent(KeyEvent keyEvent, boolean needWakeLock) {
-        if (needWakeLock) {
-            mMediaEventWakeLock.acquire();
-        }
-        Intent keyIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
-        keyIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
-        synchronized(mRCStack) {
-            if (!mRCStack.empty()) {
-                // send the intent that was registered by the client
-                try {
-                    mRCStack.peek().mMediaIntent.send(mContext,
-                            needWakeLock ? WAKELOCK_RELEASE_ON_FINISHED : 0 /*code*/,
-                            keyIntent, AudioService.this, mAudioHandler);
-                } catch (CanceledException e) {
-                    Log.e(TAG, "Error sending pending intent " + mRCStack.peek());
-                    e.printStackTrace();
-                }
-            } else {
-                // legacy behavior when nobody registered their media button event receiver
-                //    through AudioManager
-                if (needWakeLock) {
-                    keyIntent.putExtra(EXTRA_WAKELOCK_ACQUIRED, WAKELOCK_RELEASE_ON_FINISHED);
-                }
-                final long ident = Binder.clearCallingIdentity();
-                try {
-                    mContext.sendOrderedBroadcastAsUser(keyIntent, UserHandle.ALL,
-                            null, mKeyEventDone,
-                            mAudioHandler, Activity.RESULT_OK, null, null);
-                } finally {
-                    Binder.restoreCallingIdentity(ident);
-                }
-            }
-        }
-    }
-
-    /**
-     * The different actions performed in response to a voice button key event.
-     */
-    private final static int VOICEBUTTON_ACTION_DISCARD_CURRENT_KEY_PRESS = 1;
-    private final static int VOICEBUTTON_ACTION_START_VOICE_INPUT = 2;
-    private final static int VOICEBUTTON_ACTION_SIMULATE_KEY_PRESS = 3;
-
-    private final Object mVoiceEventLock = new Object();
-    private boolean mVoiceButtonDown;
-    private boolean mVoiceButtonHandled;
-
-    /**
-     * Filter key events that may be used for voice-based interactions
-     * @param keyEvent a non-null KeyEvent whose key code is that of one of the supported
-     *    media buttons that can be used to trigger voice-based interactions.
-     * @param needWakeLock true if a PARTIAL_WAKE_LOCK needs to be held while this key event
-     *     is dispatched.
-     */
-    private void filterVoiceInputKeyEvent(KeyEvent keyEvent, boolean needWakeLock) {
-        if (DEBUG_RC) {
-            Log.v(TAG, "voice input key event: " + keyEvent + ", needWakeLock=" + needWakeLock);
-        }
-
-        int voiceButtonAction = VOICEBUTTON_ACTION_DISCARD_CURRENT_KEY_PRESS;
-        int keyAction = keyEvent.getAction();
-        synchronized (mVoiceEventLock) {
-            if (keyAction == KeyEvent.ACTION_DOWN) {
-                if (keyEvent.getRepeatCount() == 0) {
-                    // initial down
-                    mVoiceButtonDown = true;
-                    mVoiceButtonHandled = false;
-                } else if (mVoiceButtonDown && !mVoiceButtonHandled
-                        && (keyEvent.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
-                    // long-press, start voice-based interactions
-                    mVoiceButtonHandled = true;
-                    voiceButtonAction = VOICEBUTTON_ACTION_START_VOICE_INPUT;
-                }
-            } else if (keyAction == KeyEvent.ACTION_UP) {
-                if (mVoiceButtonDown) {
-                    // voice button up
-                    mVoiceButtonDown = false;
-                    if (!mVoiceButtonHandled && !keyEvent.isCanceled()) {
-                        voiceButtonAction = VOICEBUTTON_ACTION_SIMULATE_KEY_PRESS;
-                    }
-                }
-            }
-        }//synchronized (mVoiceEventLock)
-
-        // take action after media button event filtering for voice-based interactions
-        switch (voiceButtonAction) {
-            case VOICEBUTTON_ACTION_DISCARD_CURRENT_KEY_PRESS:
-                if (DEBUG_RC) Log.v(TAG, "   ignore key event");
-                break;
-            case VOICEBUTTON_ACTION_START_VOICE_INPUT:
-                if (DEBUG_RC) Log.v(TAG, "   start voice-based interactions");
-                // then start the voice-based interactions
-                startVoiceBasedInteractions(needWakeLock);
-                break;
-            case VOICEBUTTON_ACTION_SIMULATE_KEY_PRESS:
-                if (DEBUG_RC) Log.v(TAG, "   send simulated key event, wakelock=" + needWakeLock);
-                sendSimulatedMediaButtonEvent(keyEvent, needWakeLock);
-                break;
-        }
-    }
-
-    private void sendSimulatedMediaButtonEvent(KeyEvent originalKeyEvent, boolean needWakeLock) {
-        // send DOWN event
-        KeyEvent keyEvent = KeyEvent.changeAction(originalKeyEvent, KeyEvent.ACTION_DOWN);
-        dispatchMediaKeyEvent(keyEvent, needWakeLock);
-        // send UP event
-        keyEvent = KeyEvent.changeAction(originalKeyEvent, KeyEvent.ACTION_UP);
-        dispatchMediaKeyEvent(keyEvent, needWakeLock);
-
-    }
-
-
-    private static boolean isValidMediaKeyEvent(KeyEvent keyEvent) {
-        if (keyEvent == null) {
-            return false;
-        }
-        final int keyCode = keyEvent.getKeyCode();
-        switch (keyCode) {
-            case KeyEvent.KEYCODE_MUTE:
-            case KeyEvent.KEYCODE_HEADSETHOOK:
-            case KeyEvent.KEYCODE_MEDIA_PLAY:
-            case KeyEvent.KEYCODE_MEDIA_PAUSE:
-            case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
-            case KeyEvent.KEYCODE_MEDIA_STOP:
-            case KeyEvent.KEYCODE_MEDIA_NEXT:
-            case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
-            case KeyEvent.KEYCODE_MEDIA_REWIND:
-            case KeyEvent.KEYCODE_MEDIA_RECORD:
-            case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
-            case KeyEvent.KEYCODE_MEDIA_CLOSE:
-            case KeyEvent.KEYCODE_MEDIA_EJECT:
-                break;
-            default:
-                return false;
-        }
-        return true;
-    }
-
-    /**
-     * Checks whether the given key code is one that can trigger the launch of voice-based
-     *   interactions.
-     * @param keyCode the key code associated with the key event
-     * @return true if the key is one of the supported voice-based interaction triggers
-     */
-    private static boolean isValidVoiceInputKeyCode(int keyCode) {
-        if (keyCode == KeyEvent.KEYCODE_HEADSETHOOK) {
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    /**
-     * Tell the system to start voice-based interactions / voice commands
-     */
-    private void startVoiceBasedInteractions(boolean needWakeLock) {
-        Intent voiceIntent = null;
-        // select which type of search to launch:
-        // - screen on and device unlocked: action is ACTION_WEB_SEARCH
-        // - device locked or screen off: action is ACTION_VOICE_SEARCH_HANDS_FREE
-        //    with EXTRA_SECURE set to true if the device is securely locked
-        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
-        boolean isLocked = mKeyguardManager != null && mKeyguardManager.isKeyguardLocked();
-        if (!isLocked && pm.isScreenOn()) {
-            voiceIntent = new Intent(android.speech.RecognizerIntent.ACTION_WEB_SEARCH);
-            Log.i(TAG, "voice-based interactions: about to use ACTION_WEB_SEARCH");
-        } else {
-            voiceIntent = new Intent(RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE);
-            voiceIntent.putExtra(RecognizerIntent.EXTRA_SECURE,
-                    isLocked && mKeyguardManager.isKeyguardSecure());
-            Log.i(TAG, "voice-based interactions: about to use ACTION_VOICE_SEARCH_HANDS_FREE");
-        }
-        // start the search activity
-        if (needWakeLock) {
-            mMediaEventWakeLock.acquire();
-        }
-        try {
-            if (voiceIntent != null) {
-                voiceIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                        | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-                mContext.startActivity(voiceIntent);
-            }
-        } catch (ActivityNotFoundException e) {
-            Log.w(TAG, "No activity for search: " + e);
-        } finally {
-            if (needWakeLock) {
-                mMediaEventWakeLock.release();
-            }
-        }
-    }
-
-    private PowerManager.WakeLock mMediaEventWakeLock;
-
-    private static final int WAKELOCK_RELEASE_ON_FINISHED = 1980; //magic number
-
-    // only set when wakelock was acquired, no need to check value when received
-    private static final String EXTRA_WAKELOCK_ACQUIRED =
-            "android.media.AudioService.WAKELOCK_ACQUIRED";
-
-    public void onSendFinished(PendingIntent pendingIntent, Intent intent,
-            int resultCode, String resultData, Bundle resultExtras) {
-        if (resultCode == WAKELOCK_RELEASE_ON_FINISHED) {
-            mMediaEventWakeLock.release();
-        }
-    }
-
-    BroadcastReceiver mKeyEventDone = new BroadcastReceiver() {
-        public void onReceive(Context context, Intent intent) {
-            if (intent == null) {
-                return;
-            }
-            Bundle extras = intent.getExtras();
-            if (extras == null) {
-                return;
-            }
-            if (extras.containsKey(EXTRA_WAKELOCK_ACQUIRED)) {
-                mMediaEventWakeLock.release();
-            }
-        }
-    };
-
-    /**
-     * Synchronization on mCurrentRcLock always inside a block synchronized on mRCStack
-     */
-    private final Object mCurrentRcLock = new Object();
-    /**
-     * The one remote control client which will receive a request for display information.
-     * This object may be null.
-     * Access protected by mCurrentRcLock.
-     */
-    private IRemoteControlClient mCurrentRcClient = null;
-
-    private final static int RC_INFO_NONE = 0;
-    private final static int RC_INFO_ALL =
-        RemoteControlClient.FLAG_INFORMATION_REQUEST_ALBUM_ART |
-        RemoteControlClient.FLAG_INFORMATION_REQUEST_KEY_MEDIA |
-        RemoteControlClient.FLAG_INFORMATION_REQUEST_METADATA |
-        RemoteControlClient.FLAG_INFORMATION_REQUEST_PLAYSTATE;
-
-    /**
-     * A monotonically increasing generation counter for mCurrentRcClient.
-     * Only accessed with a lock on mCurrentRcLock.
-     * No value wrap-around issues as we only act on equal values.
-     */
-    private int mCurrentRcClientGen = 0;
-
-    /**
-     * Inner class to monitor remote control client deaths, and remove the client for the
-     * remote control stack if necessary.
-     */
-    private class RcClientDeathHandler implements IBinder.DeathRecipient {
-        final private IBinder mCb; // To be notified of client's death
-        final private PendingIntent mMediaIntent;
-
-        RcClientDeathHandler(IBinder cb, PendingIntent pi) {
-            mCb = cb;
-            mMediaIntent = pi;
-        }
-
-        public void binderDied() {
-            Log.w(TAG, "  RemoteControlClient died");
-            // remote control client died, make sure the displays don't use it anymore
-            //  by setting its remote control client to null
-            registerRemoteControlClient(mMediaIntent, null/*rcClient*/, null/*ignored*/);
-            // the dead client was maybe handling remote playback, reevaluate
-            postReevaluateRemote();
-        }
-
-        public IBinder getBinder() {
-            return mCb;
-        }
-    }
-
-    /**
-     * A global counter for RemoteControlClient identifiers
-     */
-    private static int sLastRccId = 0;
-
-    private class RemotePlaybackState {
-        int mRccId;
-        int mVolume;
-        int mVolumeMax;
-        int mVolumeHandling;
-
-        private RemotePlaybackState(int id, int vol, int volMax) {
-            mRccId = id;
-            mVolume = vol;
-            mVolumeMax = volMax;
-            mVolumeHandling = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME_HANDLING;
-        }
-    }
-
-    /**
-     * Internal cache for the playback information of the RemoteControlClient whose volume gets to
-     * be controlled by the volume keys ("main"), so we don't have to iterate over the RC stack
-     * every time we need this info.
-     */
-    private RemotePlaybackState mMainRemote;
-    /**
-     * Indicates whether the "main" RemoteControlClient is considered active.
-     * Use synchronized on mMainRemote.
-     */
-    private boolean mMainRemoteIsActive;
-    /**
-     * Indicates whether there is remote playback going on. True even if there is no "active"
-     * remote playback (mMainRemoteIsActive is false), but a RemoteControlClient has declared it
-     * handles remote playback.
-     * Use synchronized on mMainRemote.
-     */
-    private boolean mHasRemotePlayback;
-
-    private static class RccPlaybackState {
-        public int mState;
-        public long mPositionMs;
-        public float mSpeed;
-
-        public RccPlaybackState(int state, long positionMs, float speed) {
-            mState = state;
-            mPositionMs = positionMs;
-            mSpeed = speed;
-        }
-
-        public void reset() {
-            mState = RemoteControlClient.PLAYSTATE_STOPPED;
-            mPositionMs = RemoteControlClient.PLAYBACK_POSITION_INVALID;
-            mSpeed = RemoteControlClient.PLAYBACK_SPEED_1X;
-        }
-
-        @Override
-        public String toString() {
-            return stateToString() + ", "
-                    + ((mPositionMs == RemoteControlClient.PLAYBACK_POSITION_INVALID) ?
-                            "PLAYBACK_POSITION_INVALID ," : String.valueOf(mPositionMs)) + "ms ,"
-                    + mSpeed + "X";
-        }
-
-        private String stateToString() {
-            switch (mState) {
-                case RemoteControlClient.PLAYSTATE_NONE:
-                    return "PLAYSTATE_NONE";
-                case RemoteControlClient.PLAYSTATE_STOPPED:
-                    return "PLAYSTATE_STOPPED";
-                case RemoteControlClient.PLAYSTATE_PAUSED:
-                    return "PLAYSTATE_PAUSED";
-                case RemoteControlClient.PLAYSTATE_PLAYING:
-                    return "PLAYSTATE_PLAYING";
-                case RemoteControlClient.PLAYSTATE_FAST_FORWARDING:
-                    return "PLAYSTATE_FAST_FORWARDING";
-                case RemoteControlClient.PLAYSTATE_REWINDING:
-                    return "PLAYSTATE_REWINDING";
-                case RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS:
-                    return "PLAYSTATE_SKIPPING_FORWARDS";
-                case RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS:
-                    return "PLAYSTATE_SKIPPING_BACKWARDS";
-                case RemoteControlClient.PLAYSTATE_BUFFERING:
-                    return "PLAYSTATE_BUFFERING";
-                case RemoteControlClient.PLAYSTATE_ERROR:
-                    return "PLAYSTATE_ERROR";
-                default:
-                    return "[invalid playstate]";
-            }
-        }
-    }
-
-    private static class RemoteControlStackEntry implements DeathRecipient {
-        public int mRccId = RemoteControlClient.RCSE_ID_UNREGISTERED;
-        final public AudioService mService;
-        /**
-         * The target for the ACTION_MEDIA_BUTTON events.
-         * Always non null.
-         */
-        final public PendingIntent mMediaIntent;
-        /**
-         * The registered media button event receiver.
-         * Always non null.
-         */
-        final public ComponentName mReceiverComponent;
-        public IBinder mToken;
-        public String mCallingPackageName;
-        public int mCallingUid;
-        /**
-         * Provides access to the information to display on the remote control.
-         * May be null (when a media button event receiver is registered,
-         *     but no remote control client has been registered) */
-        public IRemoteControlClient mRcClient;
-        public RcClientDeathHandler mRcClientDeathHandler;
-        /**
-         * Information only used for non-local playback
-         */
-        public int mPlaybackType;
-        public int mPlaybackVolume;
-        public int mPlaybackVolumeMax;
-        public int mPlaybackVolumeHandling;
-        public int mPlaybackStream;
-        public RccPlaybackState mPlaybackState;
-        public IRemoteVolumeObserver mRemoteVolumeObs;
-
-        public void resetPlaybackInfo() {
-            mPlaybackType = RemoteControlClient.PLAYBACK_TYPE_LOCAL;
-            mPlaybackVolume = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME;
-            mPlaybackVolumeMax = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME;
-            mPlaybackVolumeHandling = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME_HANDLING;
-            mPlaybackStream = AudioManager.STREAM_MUSIC;
-            mPlaybackState.reset();
-            mRemoteVolumeObs = null;
-        }
-
-        /** precondition: mediaIntent != null */
-        public RemoteControlStackEntry(AudioService service, PendingIntent mediaIntent,
-                ComponentName eventReceiver, IBinder token) {
-            mService = service;
-            mMediaIntent = mediaIntent;
-            mReceiverComponent = eventReceiver;
-            mToken = token;
-            mCallingUid = -1;
-            mRcClient = null;
-            mRccId = ++sLastRccId;
-            mPlaybackState = new RccPlaybackState(
-                    RemoteControlClient.PLAYSTATE_STOPPED,
-                    RemoteControlClient.PLAYBACK_POSITION_INVALID,
-                    RemoteControlClient.PLAYBACK_SPEED_1X);
-
-            resetPlaybackInfo();
-            if (mToken != null) {
-                try {
-                    mToken.linkToDeath(this, 0);
-                } catch (RemoteException e) {
-                    mService.mAudioHandler.post(new Runnable() {
-                        @Override public void run() {
-                            mService.unregisterMediaButtonIntent(mMediaIntent);
-                        }
-                    });
-                }
-            }
-        }
-
-        public void unlinkToRcClientDeath() {
-            if ((mRcClientDeathHandler != null) && (mRcClientDeathHandler.mCb != null)) {
-                try {
-                    mRcClientDeathHandler.mCb.unlinkToDeath(mRcClientDeathHandler, 0);
-                    mRcClientDeathHandler = null;
-                } catch (java.util.NoSuchElementException e) {
-                    // not much we can do here
-                    Log.e(TAG, "Encountered " + e + " in unlinkToRcClientDeath()");
-                    e.printStackTrace();
-                }
-            }
-        }
-
-        public void destroy() {
-            unlinkToRcClientDeath();
-            if (mToken != null) {
-                mToken.unlinkToDeath(this, 0);
-                mToken = null;
-            }
-        }
-
-        @Override
-        public void binderDied() {
-            mService.unregisterMediaButtonIntent(mMediaIntent);
-        }
-
-        @Override
-        protected void finalize() throws Throwable {
-            destroy(); // unlink exception handled inside method
-            super.finalize();
-        }
-    }
-
-    /**
-     *  The stack of remote control event receivers.
-     *  Code sections and methods that modify the remote control event receiver stack are
-     *  synchronized on mRCStack, but also BEFORE on mFocusLock as any change in either
-     *  stack, audio focus or RC, can lead to a change in the remote control display
-     */
-    private final Stack<RemoteControlStackEntry> mRCStack = new Stack<RemoteControlStackEntry>();
-
-    /**
-     * The component the telephony package can register so telephony calls have priority to
-     * handle media button events
-     */
-    private ComponentName mMediaReceiverForCalls = null;
-
-    /**
-     * Helper function:
-     * Display in the log the current entries in the remote control focus stack
-     */
-    private void dumpRCStack(PrintWriter pw) {
-        pw.println("\nRemote Control stack entries (last is top of stack):");
-        synchronized(mRCStack) {
-            Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
-            while(stackIterator.hasNext()) {
-                RemoteControlStackEntry rcse = stackIterator.next();
-                pw.println("  pi: " + rcse.mMediaIntent +
-                        " -- pack: " + rcse.mCallingPackageName +
-                        "  -- ercvr: " + rcse.mReceiverComponent +
-                        "  -- client: " + rcse.mRcClient +
-                        "  -- uid: " + rcse.mCallingUid +
-                        "  -- type: " + rcse.mPlaybackType +
-                        "  state: " + rcse.mPlaybackState);
-            }
-        }
-    }
-
-    /**
-     * Helper function:
-     * Display in the log the current entries in the remote control stack, focusing
-     * on RemoteControlClient data
-     */
-    private void dumpRCCStack(PrintWriter pw) {
-        pw.println("\nRemote Control Client stack entries (last is top of stack):");
-        synchronized(mRCStack) {
-            Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
-            while(stackIterator.hasNext()) {
-                RemoteControlStackEntry rcse = stackIterator.next();
-                pw.println("  uid: " + rcse.mCallingUid +
-                        "  -- id: " + rcse.mRccId +
-                        "  -- type: " + rcse.mPlaybackType +
-                        "  -- state: " + rcse.mPlaybackState +
-                        "  -- vol handling: " + rcse.mPlaybackVolumeHandling +
-                        "  -- vol: " + rcse.mPlaybackVolume +
-                        "  -- volMax: " + rcse.mPlaybackVolumeMax +
-                        "  -- volObs: " + rcse.mRemoteVolumeObs);
-            }
-            synchronized(mCurrentRcLock) {
-                pw.println("\nCurrent remote control generation ID = " + mCurrentRcClientGen);
-            }
-        }
-        synchronized (mMainRemote) {
-            pw.println("\nRemote Volume State:");
-            pw.println("  has remote: " + mHasRemotePlayback);
-            pw.println("  is remote active: " + mMainRemoteIsActive);
-            pw.println("  rccId: " + mMainRemote.mRccId);
-            pw.println("  volume handling: "
-                    + ((mMainRemote.mVolumeHandling == RemoteControlClient.PLAYBACK_VOLUME_FIXED) ?
-                            "PLAYBACK_VOLUME_FIXED(0)" : "PLAYBACK_VOLUME_VARIABLE(1)"));
-            pw.println("  volume: " + mMainRemote.mVolume);
-            pw.println("  volume steps: " + mMainRemote.mVolumeMax);
-        }
-    }
-
-    /**
-     * Helper function:
-     * Display in the log the current entries in the list of remote control displays
-     */
-    private void dumpRCDList(PrintWriter pw) {
-        pw.println("\nRemote Control Display list entries:");
-        synchronized(mRCStack) {
-            final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
-            while (displayIterator.hasNext()) {
-                final DisplayInfoForServer di = (DisplayInfoForServer) displayIterator.next();
-                pw.println("  IRCD: " + di.mRcDisplay +
-                        "  -- w:" + di.mArtworkExpectedWidth +
-                        "  -- h:" + di.mArtworkExpectedHeight+
-                        "  -- wantsPosSync:" + di.mWantsPositionSync);
-            }
-        }
-    }
-
-    /**
-     * Helper function:
-     * Remove any entry in the remote control stack that has the same package name as packageName
-     * Pre-condition: packageName != null
-     */
-    private void cleanupMediaButtonReceiverForPackage(String packageName, boolean removeAll) {
-        synchronized(mRCStack) {
-            if (mRCStack.empty()) {
-                return;
-            } else {
-                final PackageManager pm = mContext.getPackageManager();
-                RemoteControlStackEntry oldTop = mRCStack.peek();
-                Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
-                // iterate over the stack entries
-                // (using an iterator on the stack so we can safely remove an entry after having
-                //  evaluated it, traversal order doesn't matter here)
-                while(stackIterator.hasNext()) {
-                    RemoteControlStackEntry rcse = (RemoteControlStackEntry)stackIterator.next();
-                    if (removeAll && packageName.equals(rcse.mMediaIntent.getCreatorPackage())) {
-                        // a stack entry is from the package being removed, remove it from the stack
-                        stackIterator.remove();
-                        rcse.destroy();
-                    } else if (rcse.mReceiverComponent != null) {
-                        try {
-                            // Check to see if this receiver still exists.
-                            pm.getReceiverInfo(rcse.mReceiverComponent, 0);
-                        } catch (PackageManager.NameNotFoundException e) {
-                            // Not found -- remove it!
-                            stackIterator.remove();
-                            rcse.destroy();
-                        }
-                    }
-                }
-                if (mRCStack.empty()) {
-                    // no saved media button receiver
-                    mAudioHandler.sendMessage(
-                            mAudioHandler.obtainMessage(MSG_PERSIST_MEDIABUTTONRECEIVER, 0, 0,
-                                    null));
-                } else if (oldTop != mRCStack.peek()) {
-                    // the top of the stack has changed, save it in the system settings
-                    // by posting a message to persist it; only do this however if it has
-                    // a concrete component name (is not a transient registration)
-                    RemoteControlStackEntry rcse = mRCStack.peek();
-                    if (rcse.mReceiverComponent != null) {
-                        mAudioHandler.sendMessage(
-                                mAudioHandler.obtainMessage(MSG_PERSIST_MEDIABUTTONRECEIVER, 0, 0,
-                                        rcse.mReceiverComponent));
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Helper function:
-     * Restore remote control receiver from the system settings.
-     */
-    private void restoreMediaButtonReceiver() {
-        String receiverName = Settings.System.getStringForUser(mContentResolver,
-                Settings.System.MEDIA_BUTTON_RECEIVER, UserHandle.USER_CURRENT);
-        if ((null != receiverName) && !receiverName.isEmpty()) {
-            ComponentName eventReceiver = ComponentName.unflattenFromString(receiverName);
-            if (eventReceiver == null) {
-                // an invalid name was persisted
-                return;
-            }
-            // construct a PendingIntent targeted to the restored component name
-            // for the media button and register it
-            Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
-            //     the associated intent will be handled by the component being registered
-            mediaButtonIntent.setComponent(eventReceiver);
-            PendingIntent pi = PendingIntent.getBroadcast(mContext,
-                    0/*requestCode, ignored*/, mediaButtonIntent, 0/*flags*/);
-            registerMediaButtonIntent(pi, eventReceiver, null);
-        }
-    }
-
-    /**
-     * Helper function:
-     * Set the new remote control receiver at the top of the RC focus stack.
-     * Called synchronized on mAudioFocusLock, then mRCStack
-     * precondition: mediaIntent != null
-     */
-    private void pushMediaButtonReceiver_syncAfRcs(PendingIntent mediaIntent, ComponentName target,
-            IBinder token) {
-        // already at top of stack?
-        if (!mRCStack.empty() && mRCStack.peek().mMediaIntent.equals(mediaIntent)) {
-            return;
-        }
-        RemoteControlStackEntry rcse = null;
-        boolean wasInsideStack = false;
-        try {
-            for (int index = mRCStack.size()-1; index >= 0; index--) {
-                rcse = mRCStack.elementAt(index);
-                if(rcse.mMediaIntent.equals(mediaIntent)) {
-                    // ok to remove element while traversing the stack since we're leaving the loop
-                    mRCStack.removeElementAt(index);
-                    wasInsideStack = true;
-                    break;
-                }
-            }
-        } catch (ArrayIndexOutOfBoundsException e) {
-            // not expected to happen, indicates improper concurrent modification
-            Log.e(TAG, "Wrong index accessing media button stack, lock error? ", e);
-        }
-        if (!wasInsideStack) {
-            rcse = new RemoteControlStackEntry(this, mediaIntent, target, token);
-        }
-        mRCStack.push(rcse); // rcse is never null
-
-        // post message to persist the default media button receiver
-        if (target != null) {
-            mAudioHandler.sendMessage( mAudioHandler.obtainMessage(
-                    MSG_PERSIST_MEDIABUTTONRECEIVER, 0, 0, target/*obj*/) );
-        }
-    }
-
-    /**
-     * Helper function:
-     * Remove the remote control receiver from the RC focus stack.
-     * Called synchronized on mAudioFocusLock, then mRCStack
-     * precondition: pi != null
-     */
-    private void removeMediaButtonReceiver_syncAfRcs(PendingIntent pi) {
-        try {
-            for (int index = mRCStack.size()-1; index >= 0; index--) {
-                final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
-                if (rcse.mMediaIntent.equals(pi)) {
-                    rcse.destroy();
-                    // ok to remove element while traversing the stack since we're leaving the loop
-                    mRCStack.removeElementAt(index);
-                    break;
-                }
-            }
-        } catch (ArrayIndexOutOfBoundsException e) {
-            // not expected to happen, indicates improper concurrent modification
-            Log.e(TAG, "Wrong index accessing media button stack, lock error? ", e);
-        }
-    }
-
-    /**
-     * Helper function:
-     * Called synchronized on mRCStack
-     */
-    private boolean isCurrentRcController(PendingIntent pi) {
-        if (!mRCStack.empty() && mRCStack.peek().mMediaIntent.equals(pi)) {
-            return true;
-        }
-        return false;
-    }
-
-    //==========================================================================================
-    // Remote control display / client
-    //==========================================================================================
-    /**
-     * Update the remote control displays with the new "focused" client generation
-     */
-    private void setNewRcClientOnDisplays_syncRcsCurrc(int newClientGeneration,
-            PendingIntent newMediaIntent, boolean clearing) {
-        synchronized(mRCStack) {
-            if (mRcDisplays.size() > 0) {
-                final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
-                while (displayIterator.hasNext()) {
-                    final DisplayInfoForServer di = displayIterator.next();
-                    try {
-                        di.mRcDisplay.setCurrentClientId(
-                                newClientGeneration, newMediaIntent, clearing);
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Dead display in setNewRcClientOnDisplays_syncRcsCurrc()",e);
-                        di.release();
-                        displayIterator.remove();
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Update the remote control clients with the new "focused" client generation
-     */
-    private void setNewRcClientGenerationOnClients_syncRcsCurrc(int newClientGeneration) {
-        // (using an iterator on the stack so we can safely remove an entry if needed,
-        //  traversal order doesn't matter here as we update all entries)
-        Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
-        while(stackIterator.hasNext()) {
-            RemoteControlStackEntry se = stackIterator.next();
-            if ((se != null) && (se.mRcClient != null)) {
-                try {
-                    se.mRcClient.setCurrentClientGenerationId(newClientGeneration);
-                } catch (RemoteException e) {
-                    Log.w(TAG, "Dead client in setNewRcClientGenerationOnClients_syncRcsCurrc()",e);
-                    stackIterator.remove();
-                    se.unlinkToRcClientDeath();
-                }
-            }
-        }
-    }
-
-    /**
-     * Update the displays and clients with the new "focused" client generation and name
-     * @param newClientGeneration the new generation value matching a client update
-     * @param newMediaIntent the media button event receiver associated with the client.
-     *    May be null, which implies there is no registered media button event receiver.
-     * @param clearing true if the new client generation value maps to a remote control update
-     *    where the display should be cleared.
-     */
-    private void setNewRcClient_syncRcsCurrc(int newClientGeneration,
-            PendingIntent newMediaIntent, boolean clearing) {
-        // send the new valid client generation ID to all displays
-        setNewRcClientOnDisplays_syncRcsCurrc(newClientGeneration, newMediaIntent, clearing);
-        // send the new valid client generation ID to all clients
-        setNewRcClientGenerationOnClients_syncRcsCurrc(newClientGeneration);
-    }
-
-    /**
-     * Called when processing MSG_RCDISPLAY_CLEAR event
-     */
-    private void onRcDisplayClear() {
-        if (DEBUG_RC) Log.i(TAG, "Clear remote control display");
-
-        synchronized(mRCStack) {
-            synchronized(mCurrentRcLock) {
-                mCurrentRcClientGen++;
-                // synchronously update the displays and clients with the new client generation
-                setNewRcClient_syncRcsCurrc(mCurrentRcClientGen,
-                        null /*newMediaIntent*/, true /*clearing*/);
-            }
-        }
-    }
-
-    /**
-     * Called when processing MSG_RCDISPLAY_UPDATE event
-     */
-    private void onRcDisplayUpdate(RemoteControlStackEntry rcse, int flags /* USED ?*/) {
-        synchronized(mRCStack) {
-            synchronized(mCurrentRcLock) {
-                if ((mCurrentRcClient != null) && (mCurrentRcClient.equals(rcse.mRcClient))) {
-                    if (DEBUG_RC) Log.i(TAG, "Display/update remote control ");
-
-                    mCurrentRcClientGen++;
-                    // synchronously update the displays and clients with
-                    //      the new client generation
-                    setNewRcClient_syncRcsCurrc(mCurrentRcClientGen,
-                            rcse.mMediaIntent /*newMediaIntent*/,
-                            false /*clearing*/);
-
-                    // tell the current client that it needs to send info
-                    try {
-                        mCurrentRcClient.onInformationRequested(mCurrentRcClientGen, flags);
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Current valid remote client is dead: "+e);
-                        mCurrentRcClient = null;
-                    }
-                } else {
-                    // the remote control display owner has changed between the
-                    // the message to update the display was sent, and the time it
-                    // gets to be processed (now)
-                }
-            }
-        }
-    }
-
-
-    /**
-     * Helper function:
-     * Called synchronized on mRCStack
-     */
-    private void clearRemoteControlDisplay_syncAfRcs() {
-        synchronized(mCurrentRcLock) {
-            mCurrentRcClient = null;
-        }
-        // will cause onRcDisplayClear() to be called in AudioService's handler thread
-        mAudioHandler.sendMessage( mAudioHandler.obtainMessage(MSG_RCDISPLAY_CLEAR) );
-    }
-
-    /**
-     * Helper function for code readability: only to be called from
-     *    checkUpdateRemoteControlDisplay_syncAfRcs() which checks the preconditions for
-     *    this method.
-     * Preconditions:
-     *    - called synchronized mAudioFocusLock then on mRCStack
-     *    - mRCStack.isEmpty() is false
-     */
-    private void updateRemoteControlDisplay_syncAfRcs(int infoChangedFlags) {
-        RemoteControlStackEntry rcse = mRCStack.peek();
-        int infoFlagsAboutToBeUsed = infoChangedFlags;
-        // this is where we enforce opt-in for information display on the remote controls
-        //   with the new AudioManager.registerRemoteControlClient() API
-        if (rcse.mRcClient == null) {
-            //Log.w(TAG, "Can't update remote control display with null remote control client");
-            clearRemoteControlDisplay_syncAfRcs();
-            return;
-        }
-        synchronized(mCurrentRcLock) {
-            if (!rcse.mRcClient.equals(mCurrentRcClient)) {
-                // new RC client, assume every type of information shall be queried
-                infoFlagsAboutToBeUsed = RC_INFO_ALL;
-            }
-            mCurrentRcClient = rcse.mRcClient;
-        }
-        // will cause onRcDisplayUpdate() to be called in AudioService's handler thread
-        mAudioHandler.sendMessage( mAudioHandler.obtainMessage(MSG_RCDISPLAY_UPDATE,
-                infoFlagsAboutToBeUsed /* arg1 */, 0, rcse /* obj, != null */) );
-    }
-
-    /**
-     * Helper function:
-     * Called synchronized on mAudioFocusLock, then mRCStack
-     * Check whether the remote control display should be updated, triggers the update if required
-     * @param infoChangedFlags the flags corresponding to the remote control client information
-     *     that has changed, if applicable (checking for the update conditions might trigger a
-     *     clear, rather than an update event).
-     */
-    private void checkUpdateRemoteControlDisplay_syncAfRcs(int infoChangedFlags) {
-        // determine whether the remote control display should be refreshed
-        // if either stack is empty, there is a mismatch, so clear the RC display
-        if (mRCStack.isEmpty() || mFocusStack.isEmpty()) {
-            clearRemoteControlDisplay_syncAfRcs();
-            return;
-        }
-
-        // determine which entry in the AudioFocus stack to consider, and compare against the
-        // top of the stack for the media button event receivers : simply using the top of the
-        // stack would make the entry disappear from the RemoteControlDisplay in conditions such as
-        // notifications playing during music playback.
-        // Crawl the AudioFocus stack from the top until an entry is found with the following
-        // characteristics:
-        // - focus gain on STREAM_MUSIC stream
-        // - non-transient focus gain on a stream other than music
-        FocusStackEntry af = null;
-        try {
-            for (int index = mFocusStack.size()-1; index >= 0; index--) {
-                FocusStackEntry fse = mFocusStack.elementAt(index);
-                if ((fse.mStreamType == AudioManager.STREAM_MUSIC)
-                        || (fse.mFocusChangeType == AudioManager.AUDIOFOCUS_GAIN)) {
-                    af = fse;
-                    break;
-                }
-            }
-        } catch (ArrayIndexOutOfBoundsException e) {
-            Log.e(TAG, "Wrong index accessing audio focus stack when updating RCD: " + e);
-            af = null;
-        }
-        if (af == null) {
-            clearRemoteControlDisplay_syncAfRcs();
-            return;
-        }
-
-        // if the audio focus and RC owners belong to different packages, there is a mismatch, clear
-        if ((mRCStack.peek().mCallingPackageName != null)
-                && (af.mPackageName != null)
-                && !(mRCStack.peek().mCallingPackageName.compareTo(
-                        af.mPackageName) == 0)) {
-            clearRemoteControlDisplay_syncAfRcs();
-            return;
-        }
-        // if the audio focus didn't originate from the same Uid as the one in which the remote
-        //   control information will be retrieved, clear
-        if (mRCStack.peek().mCallingUid != af.mCallingUid) {
-            clearRemoteControlDisplay_syncAfRcs();
-            return;
-        }
-
-        // refresh conditions were verified: update the remote controls
-        // ok to call: synchronized mAudioFocusLock then on mRCStack, mRCStack is not empty
-        updateRemoteControlDisplay_syncAfRcs(infoChangedFlags);
-    }
-
-    /**
-     * Helper function:
-     * Post a message to asynchronously move the media button event receiver associated with the
-     * given remote control client ID to the top of the remote control stack
-     * @param rccId
-     */
-    private void postPromoteRcc(int rccId) {
-        sendMsg(mAudioHandler, MSG_PROMOTE_RCC, SENDMSG_REPLACE,
-                rccId /*arg1*/, 0, null, 0/*delay*/);
-    }
-
-    private void onPromoteRcc(int rccId) {
-        if (DEBUG_RC) { Log.d(TAG, "Promoting RCC " + rccId); }
-        synchronized(mAudioFocusLock) {
-            synchronized(mRCStack) {
-                // ignore if given RCC ID is already at top of remote control stack
-                if (!mRCStack.isEmpty() && (mRCStack.peek().mRccId == rccId)) {
-                    return;
-                }
-                int indexToPromote = -1;
-                try {
-                    for (int index = mRCStack.size()-1; index >= 0; index--) {
-                        final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
-                        if (rcse.mRccId == rccId) {
-                            indexToPromote = index;
-                            break;
-                        }
-                    }
-                    if (indexToPromote >= 0) {
-                        if (DEBUG_RC) { Log.d(TAG, "  moving RCC from index " + indexToPromote
-                                + " to " + (mRCStack.size()-1)); }
-                        final RemoteControlStackEntry rcse = mRCStack.remove(indexToPromote);
-                        mRCStack.push(rcse);
-                        // the RC stack changed, reevaluate the display
-                        checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
-                    }
-                } catch (ArrayIndexOutOfBoundsException e) {
-                    // not expected to happen, indicates improper concurrent modification
-                    Log.e(TAG, "Wrong index accessing RC stack, lock error? ", e);
-                }
-            }//synchronized(mRCStack)
-        }//synchronized(mAudioFocusLock)
-    }
-
-    /**
-     * see AudioManager.registerMediaButtonIntent(PendingIntent pi, ComponentName c)
-     * precondition: mediaIntent != null
-     */
-    public void registerMediaButtonIntent(PendingIntent mediaIntent, ComponentName eventReceiver,
-            IBinder token) {
-        Log.i(TAG, "  Remote Control   registerMediaButtonIntent() for " + mediaIntent);
-
-        synchronized(mAudioFocusLock) {
-            synchronized(mRCStack) {
-                pushMediaButtonReceiver_syncAfRcs(mediaIntent, eventReceiver, token);
-                // new RC client, assume every type of information shall be queried
-                checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
-            }
-        }
-    }
-
-    /**
-     * see AudioManager.unregisterMediaButtonIntent(PendingIntent mediaIntent)
-     * precondition: mediaIntent != null, eventReceiver != null
-     */
-    public void unregisterMediaButtonIntent(PendingIntent mediaIntent)
-    {
-        Log.i(TAG, "  Remote Control   unregisterMediaButtonIntent() for " + mediaIntent);
-
-        synchronized(mAudioFocusLock) {
-            synchronized(mRCStack) {
-                boolean topOfStackWillChange = isCurrentRcController(mediaIntent);
-                removeMediaButtonReceiver_syncAfRcs(mediaIntent);
-                if (topOfStackWillChange) {
-                    // current RC client will change, assume every type of info needs to be queried
-                    checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
-                }
-            }
-        }
-    }
-
-    /**
-     * see AudioManager.registerMediaButtonEventReceiverForCalls(ComponentName c)
-     * precondition: c != null
-     */
-    public void registerMediaButtonEventReceiverForCalls(ComponentName c) {
-        if (mContext.checkCallingPermission("android.permission.MODIFY_PHONE_STATE")
-                != PackageManager.PERMISSION_GRANTED) {
-            Log.e(TAG, "Invalid permissions to register media button receiver for calls");
-            return;
-        }
-        synchronized(mRCStack) {
-            mMediaReceiverForCalls = c;
-        }
-    }
-
-    /**
-     * see AudioManager.unregisterMediaButtonEventReceiverForCalls()
-     */
-    public void unregisterMediaButtonEventReceiverForCalls() {
-        if (mContext.checkCallingPermission("android.permission.MODIFY_PHONE_STATE")
-                != PackageManager.PERMISSION_GRANTED) {
-            Log.e(TAG, "Invalid permissions to unregister media button receiver for calls");
-            return;
-        }
-        synchronized(mRCStack) {
-            mMediaReceiverForCalls = null;
-        }
-    }
-
-    /**
-     * see AudioManager.registerRemoteControlClient(ComponentName eventReceiver, ...)
-     * @return the unique ID of the RemoteControlStackEntry associated with the RemoteControlClient
-     * Note: using this method with rcClient == null is a way to "disable" the IRemoteControlClient
-     *     without modifying the RC stack, but while still causing the display to refresh (will
-     *     become blank as a result of this)
-     */
-    public int registerRemoteControlClient(PendingIntent mediaIntent,
-            IRemoteControlClient rcClient, String callingPackageName) {
-        if (DEBUG_RC) Log.i(TAG, "Register remote control client rcClient="+rcClient);
-        int rccId = RemoteControlClient.RCSE_ID_UNREGISTERED;
-        synchronized(mAudioFocusLock) {
-            synchronized(mRCStack) {
-                // store the new display information
-                try {
-                    for (int index = mRCStack.size()-1; index >= 0; index--) {
-                        final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
-                        if(rcse.mMediaIntent.equals(mediaIntent)) {
-                            // already had a remote control client?
-                            if (rcse.mRcClientDeathHandler != null) {
-                                // stop monitoring the old client's death
-                                rcse.unlinkToRcClientDeath();
-                            }
-                            // save the new remote control client
-                            rcse.mRcClient = rcClient;
-                            rcse.mCallingPackageName = callingPackageName;
-                            rcse.mCallingUid = Binder.getCallingUid();
-                            if (rcClient == null) {
-                                // here rcse.mRcClientDeathHandler is null;
-                                rcse.resetPlaybackInfo();
-                                break;
-                            }
-                            rccId = rcse.mRccId;
-
-                            // there is a new (non-null) client:
-                            // 1/ give the new client the displays (if any)
-                            if (mRcDisplays.size() > 0) {
-                                plugRemoteControlDisplaysIntoClient_syncRcStack(rcse.mRcClient);
-                            }
-                            // 2/ monitor the new client's death
-                            IBinder b = rcse.mRcClient.asBinder();
-                            RcClientDeathHandler rcdh =
-                                    new RcClientDeathHandler(b, rcse.mMediaIntent);
-                            try {
-                                b.linkToDeath(rcdh, 0);
-                            } catch (RemoteException e) {
-                                // remote control client is DOA, disqualify it
-                                Log.w(TAG, "registerRemoteControlClient() has a dead client " + b);
-                                rcse.mRcClient = null;
-                            }
-                            rcse.mRcClientDeathHandler = rcdh;
-                            break;
-                        }
-                    }//for
-                } catch (ArrayIndexOutOfBoundsException e) {
-                    // not expected to happen, indicates improper concurrent modification
-                    Log.e(TAG, "Wrong index accessing RC stack, lock error? ", e);
-                }
-
-                // if the eventReceiver is at the top of the stack
-                // then check for potential refresh of the remote controls
-                if (isCurrentRcController(mediaIntent)) {
-                    checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
-                }
-            }//synchronized(mRCStack)
-        }//synchronized(mAudioFocusLock)
-        return rccId;
-    }
-
-    /**
-     * see AudioManager.unregisterRemoteControlClient(PendingIntent pi, ...)
-     * rcClient is guaranteed non-null
-     */
-    public void unregisterRemoteControlClient(PendingIntent mediaIntent,
-            IRemoteControlClient rcClient) {
-        if (DEBUG_RC) Log.i(TAG, "Unregister remote control client rcClient="+rcClient);
-        synchronized(mAudioFocusLock) {
-            synchronized(mRCStack) {
-                boolean topRccChange = false;
-                try {
-                    for (int index = mRCStack.size()-1; index >= 0; index--) {
-                        final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
-                        if ((rcse.mMediaIntent.equals(mediaIntent))
-                                && rcClient.equals(rcse.mRcClient)) {
-                            // we found the IRemoteControlClient to unregister
-                            // stop monitoring its death
-                            rcse.unlinkToRcClientDeath();
-                            // reset the client-related fields
-                            rcse.mRcClient = null;
-                            rcse.mCallingPackageName = null;
-                            topRccChange = (index == mRCStack.size()-1);
-                            // there can only be one matching RCC in the RC stack, we're done
-                            break;
-                        }
-                    }
-                } catch (ArrayIndexOutOfBoundsException e) {
-                    // not expected to happen, indicates improper concurrent modification
-                    Log.e(TAG, "Wrong index accessing RC stack, lock error? ", e);
-                }
-                if (topRccChange) {
-                    // no more RCC for the RCD, check for potential refresh of the remote controls
-                    checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
-                }
-            }
-        }
-    }
-
-
-    /**
-     * A class to encapsulate all the information about a remote control display.
-     * After instanciation, init() must always be called before the object is added in the list
-     * of displays.
-     * Before being removed from the list of displays, release() must always be called (otherwise
-     * it will leak death handlers).
-     */
-    private class DisplayInfoForServer implements IBinder.DeathRecipient {
-        /** may never be null */
-        private IRemoteControlDisplay mRcDisplay;
-        private IBinder mRcDisplayBinder;
-        private int mArtworkExpectedWidth = -1;
-        private int mArtworkExpectedHeight = -1;
-        private boolean mWantsPositionSync = false;
-
-        public DisplayInfoForServer(IRemoteControlDisplay rcd, int w, int h) {
-            if (DEBUG_RC) Log.i(TAG, "new DisplayInfoForServer for " + rcd + " w=" + w + " h=" + h);
-            mRcDisplay = rcd;
-            mRcDisplayBinder = rcd.asBinder();
-            mArtworkExpectedWidth = w;
-            mArtworkExpectedHeight = h;
-        }
-
-        public boolean init() {
-            try {
-                mRcDisplayBinder.linkToDeath(this, 0);
-            } catch (RemoteException e) {
-                // remote control display is DOA, disqualify it
-                Log.w(TAG, "registerRemoteControlDisplay() has a dead client " + mRcDisplayBinder);
-                return false;
-            }
-            return true;
-        }
-
-        public void release() {
-            try {
-                mRcDisplayBinder.unlinkToDeath(this, 0);
-            } catch (java.util.NoSuchElementException e) {
-                // not much we can do here, the display should have been unregistered anyway
-                Log.e(TAG, "Error in DisplaInfoForServer.relase()", e);
-            }
-        }
-
-        public void binderDied() {
-            synchronized(mRCStack) {
-                Log.w(TAG, "RemoteControl: display " + mRcDisplay + " died");
-                // remove the display from the list
-                final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
-                while (displayIterator.hasNext()) {
-                    final DisplayInfoForServer di = (DisplayInfoForServer) displayIterator.next();
-                    if (di.mRcDisplay == mRcDisplay) {
-                        if (DEBUG_RC) Log.w(TAG, " RCD removed from list");
-                        displayIterator.remove();
-                        return;
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * The remote control displays.
-     * Access synchronized on mRCStack
-     */
-    private ArrayList<DisplayInfoForServer> mRcDisplays = new ArrayList<DisplayInfoForServer>(1);
-
-    /**
-     * Plug each registered display into the specified client
-     * @param rcc, guaranteed non null
-     */
-    private void plugRemoteControlDisplaysIntoClient_syncRcStack(IRemoteControlClient rcc) {
-        final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
-        while (displayIterator.hasNext()) {
-            final DisplayInfoForServer di = (DisplayInfoForServer) displayIterator.next();
-            try {
-                rcc.plugRemoteControlDisplay(di.mRcDisplay, di.mArtworkExpectedWidth,
-                        di.mArtworkExpectedHeight);
-                if (di.mWantsPositionSync) {
-                    rcc.setWantsSyncForDisplay(di.mRcDisplay, true);
-                }
-            } catch (RemoteException e) {
-                Log.e(TAG, "Error connecting RCD to RCC in RCC registration",e);
-            }
-        }
-    }
-
-    /**
-     * Is the remote control display interface already registered
-     * @param rcd
-     * @return true if the IRemoteControlDisplay is already in the list of displays
-     */
-    private boolean rcDisplayIsPluggedIn_syncRcStack(IRemoteControlDisplay rcd) {
-        final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
-        while (displayIterator.hasNext()) {
-            final DisplayInfoForServer di = (DisplayInfoForServer) displayIterator.next();
-            if (di.mRcDisplay.asBinder().equals(rcd.asBinder())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Register an IRemoteControlDisplay.
-     * Notify all IRemoteControlClient of the new display and cause the RemoteControlClient
-     * at the top of the stack to update the new display with its information.
-     * @see android.media.IAudioService#registerRemoteControlDisplay(android.media.IRemoteControlDisplay, int, int)
-     * @param rcd the IRemoteControlDisplay to register. No effect if null.
-     * @param w the maximum width of the expected bitmap. Negative or zero values indicate this
-     *   display doesn't need to receive artwork.
-     * @param h the maximum height of the expected bitmap. Negative or zero values indicate this
-     *   display doesn't need to receive artwork.
-     */
     public void registerRemoteControlDisplay(IRemoteControlDisplay rcd, int w, int h) {
-        if (DEBUG_RC) Log.d(TAG, ">>> registerRemoteControlDisplay("+rcd+")");
-        synchronized(mAudioFocusLock) {
-            synchronized(mRCStack) {
-                if ((rcd == null) || rcDisplayIsPluggedIn_syncRcStack(rcd)) {
-                    return;
-                }
-                DisplayInfoForServer di = new DisplayInfoForServer(rcd, w, h);
-                if (!di.init()) {
-                    if (DEBUG_RC) Log.e(TAG, " error registering RCD");
-                    return;
-                }
-                // add RCD to list of displays
-                mRcDisplays.add(di);
-
-                // let all the remote control clients know there is a new display (so the remote
-                //   control stack traversal order doesn't matter).
-                Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
-                while(stackIterator.hasNext()) {
-                    RemoteControlStackEntry rcse = stackIterator.next();
-                    if(rcse.mRcClient != null) {
-                        try {
-                            rcse.mRcClient.plugRemoteControlDisplay(rcd, w, h);
-                        } catch (RemoteException e) {
-                            Log.e(TAG, "Error connecting RCD to client: ", e);
-                        }
-                    }
-                }
-
-                // we have a new display, of which all the clients are now aware: have it be updated
-                checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
-            }
-        }
+        mMediaFocusControl.registerRemoteControlDisplay(rcd, w, h);
     }
 
-    /**
-     * Unregister an IRemoteControlDisplay.
-     * No effect if the IRemoteControlDisplay hasn't been successfully registered.
-     * @see android.media.IAudioService#unregisterRemoteControlDisplay(android.media.IRemoteControlDisplay)
-     * @param rcd the IRemoteControlDisplay to unregister. No effect if null.
-     */
     public void unregisterRemoteControlDisplay(IRemoteControlDisplay rcd) {
-        if (DEBUG_RC) Log.d(TAG, "<<< unregisterRemoteControlDisplay("+rcd+")");
-        synchronized(mRCStack) {
-            if (rcd == null) {
-                return;
-            }
-
-            boolean displayWasPluggedIn = false;
-            final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
-            while (displayIterator.hasNext() && !displayWasPluggedIn) {
-                final DisplayInfoForServer di = (DisplayInfoForServer) displayIterator.next();
-                if (di.mRcDisplay.asBinder().equals(rcd.asBinder())) {
-                    displayWasPluggedIn = true;
-                    di.release();
-                    displayIterator.remove();
-                }
-            }
-
-            if (displayWasPluggedIn) {
-                // disconnect this remote control display from all the clients, so the remote
-                //   control stack traversal order doesn't matter
-                final Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
-                while(stackIterator.hasNext()) {
-                    final RemoteControlStackEntry rcse = stackIterator.next();
-                    if(rcse.mRcClient != null) {
-                        try {
-                            rcse.mRcClient.unplugRemoteControlDisplay(rcd);
-                        } catch (RemoteException e) {
-                            Log.e(TAG, "Error disconnecting remote control display to client: ", e);
-                        }
-                    }
-                }
-            } else {
-                if (DEBUG_RC) Log.w(TAG, "  trying to unregister unregistered RCD");
-            }
-        }
+        mMediaFocusControl.unregisterRemoteControlDisplay(rcd);
     }
 
-    /**
-     * Update the size of the artwork used by an IRemoteControlDisplay.
-     * @see android.media.IAudioService#remoteControlDisplayUsesBitmapSize(android.media.IRemoteControlDisplay, int, int)
-     * @param rcd the IRemoteControlDisplay with the new artwork size requirement
-     * @param w the maximum width of the expected bitmap. Negative or zero values indicate this
-     *   display doesn't need to receive artwork.
-     * @param h the maximum height of the expected bitmap. Negative or zero values indicate this
-     *   display doesn't need to receive artwork.
-     */
     public void remoteControlDisplayUsesBitmapSize(IRemoteControlDisplay rcd, int w, int h) {
-        synchronized(mRCStack) {
-            final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
-            boolean artworkSizeUpdate = false;
-            while (displayIterator.hasNext() && !artworkSizeUpdate) {
-                final DisplayInfoForServer di = (DisplayInfoForServer) displayIterator.next();
-                if (di.mRcDisplay.asBinder().equals(rcd.asBinder())) {
-                    if ((di.mArtworkExpectedWidth != w) || (di.mArtworkExpectedHeight != h)) {
-                        di.mArtworkExpectedWidth = w;
-                        di.mArtworkExpectedHeight = h;
-                        artworkSizeUpdate = true;
-                    }
-                }
-            }
-            if (artworkSizeUpdate) {
-                // RCD is currently plugged in and its artwork size has changed, notify all RCCs,
-                // stack traversal order doesn't matter
-                final Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
-                while(stackIterator.hasNext()) {
-                    final RemoteControlStackEntry rcse = stackIterator.next();
-                    if(rcse.mRcClient != null) {
-                        try {
-                            rcse.mRcClient.setBitmapSizeForDisplay(rcd, w, h);
-                        } catch (RemoteException e) {
-                            Log.e(TAG, "Error setting bitmap size for RCD on RCC: ", e);
-                        }
-                    }
-                }
-            }
-        }
+        mMediaFocusControl.remoteControlDisplayUsesBitmapSize(rcd, w, h);
     }
 
-    /**
-     * Controls whether a remote control display needs periodic checks of the RemoteControlClient
-     * playback position to verify that the estimated position has not drifted from the actual
-     * position. By default the check is not performed.
-     * The IRemoteControlDisplay must have been previously registered for this to have any effect.
-     * @param rcd the IRemoteControlDisplay for which the anti-drift mechanism will be enabled
-     *     or disabled. Not null.
-     * @param wantsSync if true, RemoteControlClient instances which expose their playback position
-     *     to the framework will regularly compare the estimated playback position with the actual
-     *     position, and will update the IRemoteControlDisplay implementation whenever a drift is
-     *     detected.
-     */
     public void remoteControlDisplayWantsPlaybackPositionSync(IRemoteControlDisplay rcd,
             boolean wantsSync) {
-        synchronized(mRCStack) {
-            boolean rcdRegistered = false;
-            // store the information about this display
-            // (display stack traversal order doesn't matter).
-            final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
-            while (displayIterator.hasNext()) {
-                final DisplayInfoForServer di = (DisplayInfoForServer) displayIterator.next();
-                if (di.mRcDisplay.asBinder().equals(rcd.asBinder())) {
-                    di.mWantsPositionSync = wantsSync;
-                    rcdRegistered = true;
-                    break;
-                }
-            }
-            if (!rcdRegistered) {
-                return;
-            }
-            // notify all current RemoteControlClients
-            // (stack traversal order doesn't matter as we notify all RCCs)
-            final Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
-            while (stackIterator.hasNext()) {
-                final RemoteControlStackEntry rcse = stackIterator.next();
-                if (rcse.mRcClient != null) {
-                    try {
-                        rcse.mRcClient.setWantsSyncForDisplay(rcd, wantsSync);
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Error setting position sync flag for RCD on RCC: ", e);
-                    }
-                }
-            }
-        }
+        mMediaFocusControl.remoteControlDisplayWantsPlaybackPositionSync(rcd, wantsSync);
+    }
+
+    public void registerMediaButtonEventReceiverForCalls(ComponentName c) {
+        mMediaFocusControl.registerMediaButtonEventReceiverForCalls(c);
+    }
+
+    public void unregisterMediaButtonEventReceiverForCalls() {
+        mMediaFocusControl.unregisterMediaButtonEventReceiverForCalls();
+    }
+
+    public void registerMediaButtonIntent(PendingIntent pi, ComponentName c, IBinder token) {
+        mMediaFocusControl.registerMediaButtonIntent(pi, c, token);
+    }
+
+    public void unregisterMediaButtonIntent(PendingIntent pi) {
+        mMediaFocusControl.unregisterMediaButtonIntent(pi);
+    }
+
+    public int registerRemoteControlClient(PendingIntent mediaIntent,
+            IRemoteControlClient rcClient, String callingPckg) {
+        return mMediaFocusControl.registerRemoteControlClient(mediaIntent, rcClient, callingPckg);
+    }
+
+    public void unregisterRemoteControlClient(PendingIntent mediaIntent,
+            IRemoteControlClient rcClient) {
+        mMediaFocusControl.unregisterRemoteControlClient(mediaIntent, rcClient);
     }
 
     public void setRemoteControlClientPlaybackPosition(int generationId, long timeMs) {
-        // ignore position change requests if invalid generation ID
-        synchronized(mRCStack) {
-            synchronized(mCurrentRcLock) {
-                if (mCurrentRcClientGen != generationId) {
-                    return;
-                }
-            }
-        }
-        // discard any unprocessed seek request in the message queue, and replace with latest
-        sendMsg(mAudioHandler, MSG_RCC_SEEK_REQUEST, SENDMSG_REPLACE, generationId /* arg1 */,
-                0 /* arg2 ignored*/, new Long(timeMs) /* obj */, 0 /* delay */);
+        mMediaFocusControl.setRemoteControlClientPlaybackPosition(generationId, timeMs);
     }
 
-    public void onSetRemoteControlClientPlaybackPosition(int generationId, long timeMs) {
-        if(DEBUG_RC) Log.d(TAG, "onSetRemoteControlClientPlaybackPosition(genId=" + generationId +
-                ", timeMs=" + timeMs + ")");
-        synchronized(mRCStack) {
-            synchronized(mCurrentRcLock) {
-                if ((mCurrentRcClient != null) && (mCurrentRcClientGen == generationId)) {
-                    // tell the current client to seek to the requested location
-                    try {
-                        mCurrentRcClient.seekTo(generationId, timeMs);
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Current valid remote client is dead: "+e);
-                        mCurrentRcClient = null;
-                    }
-                }
-            }
-        }
-    }
-
-    public void setPlaybackInfoForRcc(int rccId, int what, int value) {
-        sendMsg(mAudioHandler, MSG_RCC_NEW_PLAYBACK_INFO, SENDMSG_QUEUE,
-                rccId /* arg1 */, what /* arg2 */, Integer.valueOf(value) /* obj */, 0 /* delay */);
-    }
-
-    // handler for MSG_RCC_NEW_PLAYBACK_INFO
-    private void onNewPlaybackInfoForRcc(int rccId, int key, int value) {
-        if(DEBUG_RC) Log.d(TAG, "onNewPlaybackInfoForRcc(id=" + rccId +
-                ", what=" + key + ",val=" + value + ")");
-        synchronized(mRCStack) {
-            // iterating from top of stack as playback information changes are more likely
-            //   on entries at the top of the remote control stack
-            try {
-                for (int index = mRCStack.size()-1; index >= 0; index--) {
-                    final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
-                    if (rcse.mRccId == rccId) {
-                        switch (key) {
-                            case RemoteControlClient.PLAYBACKINFO_PLAYBACK_TYPE:
-                                rcse.mPlaybackType = value;
-                                postReevaluateRemote();
-                                break;
-                            case RemoteControlClient.PLAYBACKINFO_VOLUME:
-                                rcse.mPlaybackVolume = value;
-                                synchronized (mMainRemote) {
-                                    if (rccId == mMainRemote.mRccId) {
-                                        mMainRemote.mVolume = value;
-                                        mVolumePanel.postHasNewRemotePlaybackInfo();
-                                    }
-                                }
-                                break;
-                            case RemoteControlClient.PLAYBACKINFO_VOLUME_MAX:
-                                rcse.mPlaybackVolumeMax = value;
-                                synchronized (mMainRemote) {
-                                    if (rccId == mMainRemote.mRccId) {
-                                        mMainRemote.mVolumeMax = value;
-                                        mVolumePanel.postHasNewRemotePlaybackInfo();
-                                    }
-                                }
-                                break;
-                            case RemoteControlClient.PLAYBACKINFO_VOLUME_HANDLING:
-                                rcse.mPlaybackVolumeHandling = value;
-                                synchronized (mMainRemote) {
-                                    if (rccId == mMainRemote.mRccId) {
-                                        mMainRemote.mVolumeHandling = value;
-                                        mVolumePanel.postHasNewRemotePlaybackInfo();
-                                    }
-                                }
-                                break;
-                            case RemoteControlClient.PLAYBACKINFO_USES_STREAM:
-                                rcse.mPlaybackStream = value;
-                                break;
-                            default:
-                                Log.e(TAG, "unhandled key " + key + " for RCC " + rccId);
-                                break;
-                        }
-                        return;
-                    }
-                }//for
-            } catch (ArrayIndexOutOfBoundsException e) {
-                // not expected to happen, indicates improper concurrent modification
-                Log.e(TAG, "Wrong index mRCStack on onNewPlaybackInfoForRcc, lock error? ", e);
-            }
-        }
-    }
-
-    public void setPlaybackStateForRcc(int rccId, int state, long timeMs, float speed) {
-        sendMsg(mAudioHandler, MSG_RCC_NEW_PLAYBACK_STATE, SENDMSG_QUEUE,
-                rccId /* arg1 */, state /* arg2 */,
-                new RccPlaybackState(state, timeMs, speed) /* obj */, 0 /* delay */);
-    }
-
-    public void onNewPlaybackStateForRcc(int rccId, int state, RccPlaybackState newState) {
-        if(DEBUG_RC) Log.d(TAG, "onNewPlaybackStateForRcc(id=" + rccId + ", state=" + state
-                + ", time=" + newState.mPositionMs + ", speed=" + newState.mSpeed + ")");
-        synchronized(mRCStack) {
-            // iterating from top of stack as playback information changes are more likely
-            //   on entries at the top of the remote control stack
-            try {
-                for (int index = mRCStack.size()-1; index >= 0; index--) {
-                    final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
-                    if (rcse.mRccId == rccId) {
-                        rcse.mPlaybackState = newState;
-                        synchronized (mMainRemote) {
-                            if (rccId == mMainRemote.mRccId) {
-                                mMainRemoteIsActive = isPlaystateActive(state);
-                                postReevaluateRemote();
-                            }
-                        }
-                        // an RCC moving to a "playing" state should become the media button
-                        //   event receiver so it can be controlled, without requiring the
-                        //   app to re-register its receiver
-                        if (isPlaystateActive(state)) {
-                            postPromoteRcc(rccId);
-                        }
-                    }
-                }//for
-            } catch (ArrayIndexOutOfBoundsException e) {
-                // not expected to happen, indicates improper concurrent modification
-                Log.e(TAG, "Wrong index on mRCStack in onNewPlaybackStateForRcc, lock error? ", e);
-            }
-        }
+    public void updateRemoteControlClientMetadata(int generationId, int key, long value) {
+        mMediaFocusControl.updateRemoteControlClientMetadata(generationId, key, value);
     }
 
     public void registerRemoteVolumeObserverForRcc(int rccId, IRemoteVolumeObserver rvo) {
-        sendMsg(mAudioHandler, MSG_RCC_NEW_VOLUME_OBS, SENDMSG_QUEUE,
-                rccId /* arg1 */, 0, rvo /* obj */, 0 /* delay */);
-    }
-
-    // handler for MSG_RCC_NEW_VOLUME_OBS
-    private void onRegisterVolumeObserverForRcc(int rccId, IRemoteVolumeObserver rvo) {
-        synchronized(mRCStack) {
-            // The stack traversal order doesn't matter because there is only one stack entry
-            //  with this RCC ID, but the matching ID is more likely at the top of the stack, so
-            //  start iterating from the top.
-            try {
-                for (int index = mRCStack.size()-1; index >= 0; index--) {
-                    final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
-                    if (rcse.mRccId == rccId) {
-                        rcse.mRemoteVolumeObs = rvo;
-                        break;
-                    }
-                }
-            } catch (ArrayIndexOutOfBoundsException e) {
-                // not expected to happen, indicates improper concurrent modification
-                Log.e(TAG, "Wrong index accessing media button stack, lock error? ", e);
-            }
-        }
-    }
-
-    /**
-     * Checks if a remote client is active on the supplied stream type. Update the remote stream
-     * volume state if found and playing
-     * @param streamType
-     * @return false if no remote playing is currently playing
-     */
-    private boolean checkUpdateRemoteStateIfActive(int streamType) {
-        synchronized(mRCStack) {
-            // iterating from top of stack as active playback is more likely on entries at the top
-            try {
-                for (int index = mRCStack.size()-1; index >= 0; index--) {
-                    final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
-                    if ((rcse.mPlaybackType == RemoteControlClient.PLAYBACK_TYPE_REMOTE)
-                            && isPlaystateActive(rcse.mPlaybackState.mState)
-                            && (rcse.mPlaybackStream == streamType)) {
-                        if (DEBUG_RC) Log.d(TAG, "remote playback active on stream " + streamType
-                                + ", vol =" + rcse.mPlaybackVolume);
-                        synchronized (mMainRemote) {
-                            mMainRemote.mRccId = rcse.mRccId;
-                            mMainRemote.mVolume = rcse.mPlaybackVolume;
-                            mMainRemote.mVolumeMax = rcse.mPlaybackVolumeMax;
-                            mMainRemote.mVolumeHandling = rcse.mPlaybackVolumeHandling;
-                            mMainRemoteIsActive = true;
-                        }
-                        return true;
-                    }
-                }
-            } catch (ArrayIndexOutOfBoundsException e) {
-                // not expected to happen, indicates improper concurrent modification
-                Log.e(TAG, "Wrong index accessing RC stack, lock error? ", e);
-            }
-        }
-        synchronized (mMainRemote) {
-            mMainRemoteIsActive = false;
-        }
-        return false;
-    }
-
-    /**
-     * Returns true if the given playback state is considered "active", i.e. it describes a state
-     * where playback is happening, or about to
-     * @param playState the playback state to evaluate
-     * @return true if active, false otherwise (inactive or unknown)
-     */
-    private static boolean isPlaystateActive(int playState) {
-        switch (playState) {
-            case RemoteControlClient.PLAYSTATE_PLAYING:
-            case RemoteControlClient.PLAYSTATE_BUFFERING:
-            case RemoteControlClient.PLAYSTATE_FAST_FORWARDING:
-            case RemoteControlClient.PLAYSTATE_REWINDING:
-            case RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS:
-            case RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS:
-                return true;
-            default:
-                return false;
-        }
-    }
-
-    private void adjustRemoteVolume(int streamType, int direction, int flags) {
-        int rccId = RemoteControlClient.RCSE_ID_UNREGISTERED;
-        boolean volFixed = false;
-        synchronized (mMainRemote) {
-            if (!mMainRemoteIsActive) {
-                if (DEBUG_VOL) Log.w(TAG, "adjustRemoteVolume didn't find an active client");
-                return;
-            }
-            rccId = mMainRemote.mRccId;
-            volFixed = (mMainRemote.mVolumeHandling ==
-                    RemoteControlClient.PLAYBACK_VOLUME_FIXED);
-        }
-        // unlike "local" stream volumes, we can't compute the new volume based on the direction,
-        // we can only notify the remote that volume needs to be updated, and we'll get an async'
-        // update through setPlaybackInfoForRcc()
-        if (!volFixed) {
-            sendVolumeUpdateToRemote(rccId, direction);
-        }
-
-        // fire up the UI
-        mVolumePanel.postRemoteVolumeChanged(streamType, flags);
-    }
-
-    private void sendVolumeUpdateToRemote(int rccId, int direction) {
-        if (DEBUG_VOL) { Log.d(TAG, "sendVolumeUpdateToRemote(rccId="+rccId+" , dir="+direction); }
-        if (direction == 0) {
-            // only handling discrete events
-            return;
-        }
-        IRemoteVolumeObserver rvo = null;
-        synchronized (mRCStack) {
-            // The stack traversal order doesn't matter because there is only one stack entry
-            //  with this RCC ID, but the matching ID is more likely at the top of the stack, so
-            //  start iterating from the top.
-            try {
-                for (int index = mRCStack.size()-1; index >= 0; index--) {
-                    final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
-                    //FIXME OPTIMIZE store this info in mMainRemote so we don't have to iterate?
-                    if (rcse.mRccId == rccId) {
-                        rvo = rcse.mRemoteVolumeObs;
-                        break;
-                    }
-                }
-            } catch (ArrayIndexOutOfBoundsException e) {
-                // not expected to happen, indicates improper concurrent modification
-                Log.e(TAG, "Wrong index accessing media button stack, lock error? ", e);
-            }
-        }
-        if (rvo != null) {
-            try {
-                rvo.dispatchRemoteVolumeUpdate(direction, -1);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Error dispatching relative volume update", e);
-            }
-        }
-    }
-
-    public int getRemoteStreamMaxVolume() {
-        synchronized (mMainRemote) {
-            if (mMainRemote.mRccId == RemoteControlClient.RCSE_ID_UNREGISTERED) {
-                return 0;
-            }
-            return mMainRemote.mVolumeMax;
-        }
+        mMediaFocusControl.registerRemoteVolumeObserverForRcc(rccId, rvo);
     }
 
     public int getRemoteStreamVolume() {
-        synchronized (mMainRemote) {
-            if (mMainRemote.mRccId == RemoteControlClient.RCSE_ID_UNREGISTERED) {
-                return 0;
-            }
-            return mMainRemote.mVolume;
-        }
+        return mMediaFocusControl.getRemoteStreamVolume();
     }
 
-    public void setRemoteStreamVolume(int vol) {
-        if (DEBUG_VOL) { Log.d(TAG, "setRemoteStreamVolume(vol="+vol+")"); }
-        int rccId = RemoteControlClient.RCSE_ID_UNREGISTERED;
-        synchronized (mMainRemote) {
-            if (mMainRemote.mRccId == RemoteControlClient.RCSE_ID_UNREGISTERED) {
-                return;
-            }
-            rccId = mMainRemote.mRccId;
-        }
-        IRemoteVolumeObserver rvo = null;
-        synchronized (mRCStack) {
-            // The stack traversal order doesn't matter because there is only one stack entry
-            //  with this RCC ID, but the matching ID is more likely at the top of the stack, so
-            //  start iterating from the top.
-            try {
-                for (int index = mRCStack.size()-1; index >= 0; index--) {
-                    final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
-                    //FIXME OPTIMIZE store this info in mMainRemote so we don't have to iterate?
-                    if (rcse.mRccId == rccId) {
-                        rvo = rcse.mRemoteVolumeObs;
-                        break;
-                    }
-                }
-            } catch (ArrayIndexOutOfBoundsException e) {
-                // not expected to happen, indicates improper concurrent modification
-                Log.e(TAG, "Wrong index accessing media button stack, lock error? ", e);
-            }
-        }
-        if (rvo != null) {
-            try {
-                rvo.dispatchRemoteVolumeUpdate(0, vol);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Error dispatching absolute volume update", e);
-            }
-        }
+    public int getRemoteStreamMaxVolume() {
+        return mMediaFocusControl.getRemoteStreamMaxVolume();
     }
 
-    /**
-     * Call to make AudioService reevaluate whether it's in a mode where remote players should
-     * have their volume controlled. In this implementation this is only to reset whether
-     * VolumePanel should display remote volumes
-     */
-    private void postReevaluateRemote() {
-        sendMsg(mAudioHandler, MSG_REEVALUATE_REMOTE, SENDMSG_QUEUE, 0, 0, null, 0);
+    public void setRemoteStreamVolume(int index) {
+        mMediaFocusControl.setRemoteStreamVolume(index);
     }
 
-    private void onReevaluateRemote() {
-        if (DEBUG_VOL) { Log.w(TAG, "onReevaluateRemote()"); }
-        // is there a registered RemoteControlClient that is handling remote playback
-        boolean hasRemotePlayback = false;
-        synchronized (mRCStack) {
-            // iteration stops when PLAYBACK_TYPE_REMOTE is found, so remote control stack
-            //   traversal order doesn't matter
-            Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
-            while(stackIterator.hasNext()) {
-                RemoteControlStackEntry rcse = stackIterator.next();
-                if (rcse.mPlaybackType == RemoteControlClient.PLAYBACK_TYPE_REMOTE) {
-                    hasRemotePlayback = true;
-                    break;
-                }
-            }
-        }
-        synchronized (mMainRemote) {
-            if (mHasRemotePlayback != hasRemotePlayback) {
-                mHasRemotePlayback = hasRemotePlayback;
-                mVolumePanel.postRemoteSliderVisibility(hasRemotePlayback);
-            }
-        }
+    public void setPlaybackStateForRcc(int rccId, int state, long timeMs, float speed) {
+        mMediaFocusControl.setPlaybackStateForRcc(rccId, state, timeMs, speed);
+    }
+
+    public void setPlaybackInfoForRcc(int rccId, int what, int value) {
+        mMediaFocusControl.setPlaybackInfoForRcc(rccId, what, value);
+    }
+
+    public void dispatchMediaKeyEvent(KeyEvent keyEvent) {
+        mMediaFocusControl.dispatchMediaKeyEvent(keyEvent);
+    }
+
+    public void dispatchMediaKeyEventUnderWakelock(KeyEvent keyEvent) {
+        mMediaFocusControl.dispatchMediaKeyEventUnderWakelock(keyEvent);
+    }
+
+    //==========================================================================================
+    // Audio Focus
+    //==========================================================================================
+    public int requestAudioFocus(int mainStreamType, int durationHint, IBinder cb,
+            IAudioFocusDispatcher fd, String clientId, String callingPackageName) {
+        return mMediaFocusControl.requestAudioFocus(mainStreamType, durationHint, cb, fd,
+                clientId, callingPackageName);
+    }
+
+    public int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId) {
+        return mMediaFocusControl.abandonAudioFocus(fd, clientId);
+    }
+
+    public void unregisterAudioFocusClient(String clientId) {
+        mMediaFocusControl.unregisterAudioFocusClient(clientId);
+    }
+
+    public int getCurrentAudioFocus() {
+        return mMediaFocusControl.getCurrentAudioFocus();
     }
 
     //==========================================================================================
@@ -6638,14 +4547,20 @@
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
 
-        dumpFocusStack(pw);
-        dumpRCStack(pw);
-        dumpRCCStack(pw);
-        dumpRCDList(pw);
+        mMediaFocusControl.dump(pw);
         dumpStreamStates(pw);
         dumpRingerMode(pw);
         pw.println("\nAudio routes:");
         pw.print("  mMainType=0x"); pw.println(Integer.toHexString(mCurAudioRoutes.mMainType));
         pw.print("  mBluetoothName="); pw.println(mCurAudioRoutes.mBluetoothName);
     }
+
+    // Inform AudioFlinger of our device's low RAM attribute
+    private static void readAndSetLowRamDevice()
+    {
+        int status = AudioSystem.setLowRamDevice(ActivityManager.isLowRamDeviceStatic());
+        if (status != 0) {
+            Log.w(TAG, "AudioFlinger informed of device's low RAM attribute; status " + status);
+        }
+    }
 }
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index d42bfd4..661b0fd 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -177,12 +177,10 @@
     {
         synchronized (AudioSystem.class) {
             mErrorCallback = cb;
+            if (cb != null) {
+                cb.onError(checkAudioFlinger());
+            }
         }
-        // Calling a method on AudioFlinger here makes sure that we bind to IAudioFlinger
-        // binder interface death. Not doing that would result in not being notified of
-        // media_server process death if no other method is called on AudioSystem that reaches
-        // to AudioFlinger.
-        isMicrophoneMuted();
     }
 
     private static void errorCallbackFromNative(int error)
@@ -403,4 +401,6 @@
     public static native int getPrimaryOutputFrameCount();
     public static native int getOutputLatency(int stream);
 
+    public static native int setLowRamDevice(boolean isLowRamDevice);
+    public static native int checkAudioFlinger();
 }
diff --git a/media/java/android/media/AudioTimestamp.java b/media/java/android/media/AudioTimestamp.java
new file mode 100644
index 0000000..965ba85
--- /dev/null
+++ b/media/java/android/media/AudioTimestamp.java
@@ -0,0 +1,44 @@
+/*
+ * 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.media;
+
+/**
+ * Structure that groups a position in frame units relative to an assumed audio stream,
+ * together with the estimated time when that frame was presented or is committed to be
+ * presented.
+ * In the case of audio output, "present" means that audio produced on device
+ * is detectable by an external observer off device.
+ * The time is based on the implementation's best effort, using whatever knowledge
+ * is available to the system, but cannot account for any delay unknown to the implementation.
+ *
+ * @see AudioTrack#getTimestamp
+ */
+public final class AudioTimestamp
+{
+    /**
+     * Position in frames relative to start of an assumed audio stream.
+     * The low-order 32 bits of position is in wrapping frame units similar to
+     * {@link AudioTrack#getPlaybackHeadPosition}.
+     */
+    public long framePosition;
+
+    /**
+     * The estimated time when frame was presented or is committed to be presented,
+     * in the same units and timebase as {@link java.lang.System#nanoTime}.
+     */
+    public long nanoTime;
+}
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 9768a78..78a37c5 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -26,7 +26,7 @@
 
 /**
  * The AudioTrack class manages and plays a single audio resource for Java applications.
- * It allows streaming PCM audio buffers to the audio hardware for playback. This is
+ * It allows streaming of PCM audio buffers to the audio sink for playback. This is
  * achieved by "pushing" the data to the AudioTrack object using one of the
  *  {@link #write(byte[], int, int)} and {@link #write(short[], int, int)} methods.
  *
@@ -53,8 +53,10 @@
  * can play before running out of data.<br>
  * For an AudioTrack using the static mode, this size is the maximum size of the sound that can
  * be played from it.<br>
- * For the streaming mode, data will be written to the hardware in chunks of
+ * For the streaming mode, data will be written to the audio sink in chunks of
  * sizes less than or equal to the total buffer size.
+ *
+ * AudioTrack is not final and thus permits subclasses, but such use is not recommended.
  */
 public class AudioTrack
 {
@@ -130,7 +132,7 @@
     private static final int ERROR_NATIVESETUP_NATIVEINITFAILED    = -20;
 
     // Events:
-    // to keep in sync with frameworks/base/include/media/AudioTrack.h
+    // to keep in sync with frameworks/av/include/media/AudioTrack.h
     /**
      * Event id denotes when playback head has reached a previously set marker.
      */
@@ -159,11 +161,12 @@
      */
     private final Object mPlayStateLock = new Object();
     /**
-     * Size of the native audio buffer.
+     * Sizes of the native audio buffer.
      */
     private int mNativeBufferSizeInBytes = 0;
+    private int mNativeBufferSizeInFrames = 0;
     /**
-     * Handler for marker events coming from the native code.
+     * Handler for events coming from the native code.
      */
     private NativeEventHandlerDelegate mEventHandlerDelegate;
     /**
@@ -171,7 +174,7 @@
      */
     private final Looper mInitializationLooper;
     /**
-     * The audio data sampling rate in Hz.
+     * The audio data source sampling rate in Hz.
      */
     private int mSampleRate; // initialized by all constructors
     /**
@@ -192,7 +195,7 @@
      */
     private int mStreamType = AudioManager.STREAM_MUSIC;
     /**
-     * The way audio is consumed by the hardware, streaming or static.
+     * The way audio is consumed by the audio sink, streaming or static.
      */
     private int mDataLoadMode = MODE_STREAM;
     /**
@@ -236,17 +239,20 @@
      *   {@link AudioManager#STREAM_VOICE_CALL}, {@link AudioManager#STREAM_SYSTEM},
      *   {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_MUSIC},
      *   {@link AudioManager#STREAM_ALARM}, and {@link AudioManager#STREAM_NOTIFICATION}.
-     * @param sampleRateInHz the sample rate expressed in Hertz.
+     * @param sampleRateInHz the initial source sample rate expressed in Hz.
      * @param channelConfig describes the configuration of the audio channels.
      *   See {@link AudioFormat#CHANNEL_OUT_MONO} and
      *   {@link AudioFormat#CHANNEL_OUT_STEREO}
      * @param audioFormat the format in which the audio data is represented.
      *   See {@link AudioFormat#ENCODING_PCM_16BIT} and
      *   {@link AudioFormat#ENCODING_PCM_8BIT}
-     * @param bufferSizeInBytes the total size (in bytes) of the buffer where audio data is read
-     *   from for playback. If using the AudioTrack in streaming mode, you can write data into
-     *   this buffer in smaller chunks than this size. If using the AudioTrack in static mode,
-     *   this is the maximum size of the sound that will be played for this instance.
+     * @param bufferSizeInBytes the total size (in bytes) of the internal buffer where audio data is
+     *   read from for playback.
+     *   If track's creation mode is {@link #MODE_STREAM}, you can write data into
+     *   this buffer in chunks less than or equal to this size, and it is typical to use
+     *   chunks of 1/2 of the total size to permit double-buffering.
+     *   If the track's creation mode is {@link #MODE_STATIC},
+     *   this is the maximum length sample, or audio clip, that can be played by this instance.
      *   See {@link #getMinBufferSize(int, int, int)} to determine the minimum required buffer size
      *   for the successful creation of an AudioTrack instance in streaming mode. Using values
      *   smaller than getMinBufferSize() will result in an initialization failure.
@@ -257,7 +263,7 @@
             int bufferSizeInBytes, int mode)
     throws IllegalArgumentException {
         this(streamType, sampleRateInHz, channelConfig, audioFormat,
-                bufferSizeInBytes, mode, 0);
+                bufferSizeInBytes, mode, 0 /*session*/);
     }
 
     /**
@@ -267,7 +273,7 @@
      * is provided when creating an AudioEffect, this effect will be applied only to audio tracks
      * and media players in the same session and not to the output mix.
      * When an AudioTrack is created without specifying a session, it will create its own session
-     * which can be retreived by calling the {@link #getAudioSessionId()} method.
+     * which can be retrieved by calling the {@link #getAudioSessionId()} method.
      * If a non-zero session ID is provided, this AudioTrack will share effects attached to this
      * session
      * with all other media players or audio tracks in the same session, otherwise a new session
@@ -276,7 +282,7 @@
      *   {@link AudioManager#STREAM_VOICE_CALL}, {@link AudioManager#STREAM_SYSTEM},
      *   {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_MUSIC},
      *   {@link AudioManager#STREAM_ALARM}, and {@link AudioManager#STREAM_NOTIFICATION}.
-     * @param sampleRateInHz the sample rate expressed in Hertz.
+     * @param sampleRateInHz the initial source sample rate expressed in Hz.
      * @param channelConfig describes the configuration of the audio channels.
      *   See {@link AudioFormat#CHANNEL_OUT_MONO} and
      *   {@link AudioFormat#CHANNEL_OUT_STEREO}
@@ -365,18 +371,16 @@
            && (streamType != AudioManager.STREAM_BLUETOOTH_SCO)
            && (streamType != AudioManager.STREAM_DTMF)) {
             throw new IllegalArgumentException("Invalid stream type.");
-        } else {
-            mStreamType = streamType;
         }
+        mStreamType = streamType;
 
         //--------------
         // sample rate, note these values are subject to change
         if ( (sampleRateInHz < 4000) || (sampleRateInHz > 48000) ) {
             throw new IllegalArgumentException(sampleRateInHz
                     + "Hz is not a supported sample rate.");
-        } else {
-            mSampleRate = sampleRateInHz;
         }
+        mSampleRate = sampleRateInHz;
 
         //--------------
         // channel config
@@ -397,14 +401,10 @@
         default:
             if (!isMultichannelConfigSupported(channelConfig)) {
                 // input channel configuration features unsupported channels
-                mChannelCount = 0;
-                mChannels = AudioFormat.CHANNEL_INVALID;
-                mChannelConfiguration = AudioFormat.CHANNEL_INVALID;
                 throw new IllegalArgumentException("Unsupported channel configuration.");
-            } else {
-                mChannels = channelConfig;
-                mChannelCount = Integer.bitCount(channelConfig);
             }
+            mChannels = channelConfig;
+            mChannelCount = Integer.bitCount(channelConfig);
         }
 
         //--------------
@@ -418,7 +418,6 @@
             mAudioFormat = audioFormat;
             break;
         default:
-            mAudioFormat = AudioFormat.ENCODING_INVALID;
             throw new IllegalArgumentException("Unsupported sample encoding."
                 + " Should be ENCODING_PCM_8BIT or ENCODING_PCM_16BIT.");
         }
@@ -427,9 +426,8 @@
         // audio load mode
         if ( (mode != MODE_STREAM) && (mode != MODE_STATIC) ) {
             throw new IllegalArgumentException("Invalid mode.");
-        } else {
-            mDataLoadMode = mode;
         }
+        mDataLoadMode = mode;
     }
 
     /**
@@ -464,7 +462,7 @@
     }
 
 
-    // Convenience method for the contructor's audio buffer size check.
+    // Convenience method for the constructor's audio buffer size check.
     // preconditions:
     //    mChannelCount is valid
     //    mAudioFormat is valid
@@ -480,6 +478,7 @@
         }
 
         mNativeBufferSizeInBytes = audioBufferSize;
+        mNativeBufferSizeInFrames = audioBufferSize / frameSizeInBytes;
     }
 
 
@@ -559,7 +558,6 @@
 
     /**
      * Returns the configured channel configuration.
-
      * See {@link AudioFormat#CHANNEL_OUT_MONO}
      * and {@link AudioFormat#CHANNEL_OUT_STEREO}.
      */
@@ -577,8 +575,7 @@
     /**
      * Returns the state of the AudioTrack instance. This is useful after the
      * AudioTrack instance has been created to check if it was initialized
-     * properly. This ensures that the appropriate hardware resources have been
-     * acquired.
+     * properly. This ensures that the appropriate resources have been acquired.
      * @see #STATE_INITIALIZED
      * @see #STATE_NO_STATIC_DATA
      * @see #STATE_UNINITIALIZED
@@ -600,14 +597,26 @@
     }
 
     /**
-     *  Returns the native frame count used by the hardware.
+     *  Returns the "native frame count", derived from the bufferSizeInBytes specified at
+     *  creation time and converted to frame units.
+     *  If track's creation mode is {@link #MODE_STATIC},
+     *  it is equal to the specified bufferSizeInBytes converted to frame units.
+     *  If track's creation mode is {@link #MODE_STREAM},
+     *  it is typically greater than or equal to the specified bufferSizeInBytes converted to frame
+     *  units; it may be rounded up to a larger value if needed by the target device implementation.
+     *  @deprecated Only accessible by subclasses, which are not recommended for AudioTrack.
+     *  See {@link AudioManager#getProperty(String)} for key
+     *  {@link AudioManager#PROPERTY_OUTPUT_FRAMES_PER_BUFFER}.
      */
+    @Deprecated
     protected int getNativeFrameCount() {
         return native_get_native_frame_count();
     }
 
     /**
      * Returns marker position expressed in frames.
+     * @return marker position in wrapping frame units similar to {@link #getPlaybackHeadPosition},
+     * or zero if marker is disabled.
      */
     public int getNotificationMarkerPosition() {
         return native_get_marker_pos();
@@ -615,13 +624,19 @@
 
     /**
      * Returns the notification update period expressed in frames.
+     * Zero means that no position update notifications are being delivered.
      */
     public int getPositionNotificationPeriod() {
         return native_get_pos_update_period();
     }
 
     /**
-     * Returns the playback head position expressed in frames
+     * Returns the playback head position expressed in frames.
+     * Though the "int" type is signed 32-bits, the value should be reinterpreted as if it is
+     * unsigned 32-bits.  That is, the next position after 0x7FFFFFFF is (int) 0x80000000.
+     * This is a continuously advancing counter.  It will wrap (overflow) periodically,
+     * for example approximately once every 27:03:11 hours:minutes:seconds at 44.1 kHz.
+     * It is reset to zero by flush(), reload(), and stop().
      */
     public int getPlaybackHeadPosition() {
         return native_get_position();
@@ -640,7 +655,7 @@
     }
 
     /**
-     *  Returns the hardware output sample rate
+     *  Returns the output sample rate in Hz for the specified stream type.
      */
     static public int getNativeOutputSampleRate(int streamType) {
         return native_get_output_sample_rate(streamType);
@@ -651,7 +666,10 @@
      * object to be created in the {@link #MODE_STREAM} mode. Note that this size doesn't
      * guarantee a smooth playback under load, and higher values should be chosen according to
      * the expected frequency at which the buffer will be refilled with additional data to play.
-     * @param sampleRateInHz the sample rate expressed in Hertz.
+     * For example, if you intend to dynamically set the source sample rate of an AudioTrack
+     * to a higher value than the initial source sample rate, be sure to configure the buffer size
+     * based on the highest planned sample rate.
+     * @param sampleRateInHz the source sample rate expressed in Hz.
      * @param channelConfig describes the configuration of the audio channels.
      *   See {@link AudioFormat#CHANNEL_OUT_MONO} and
      *   {@link AudioFormat#CHANNEL_OUT_STEREO}
@@ -659,8 +677,7 @@
      *   See {@link AudioFormat#ENCODING_PCM_16BIT} and
      *   {@link AudioFormat#ENCODING_PCM_8BIT}
      * @return {@link #ERROR_BAD_VALUE} if an invalid parameter was passed,
-     *   or {@link #ERROR} if the implementation was unable to query the hardware for its output
-     *     properties,
+     *   or {@link #ERROR} if unable to query for output properties,
      *   or the minimum buffer size expressed in bytes.
      */
     static public int getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat) {
@@ -715,6 +732,45 @@
         return mSessionId;
     }
 
+   /**
+    * Poll for a timestamp on demand.
+    *
+    * Use if you need to get the most recent timestamp outside of the event callback handler.
+    * Calling this method too often may be inefficient;
+    * if you need a high-resolution mapping between frame position and presentation time,
+    * consider implementing that at application level, based on low-resolution timestamps.
+    * The audio data at the returned position may either already have been
+    * presented, or may have not yet been presented but is committed to be presented.
+    * It is not possible to request the time corresponding to a particular position,
+    * or to request the (fractional) position corresponding to a particular time.
+    * If you need such features, consider implementing them at application level.
+    *
+    * @param timestamp a reference to a non-null AudioTimestamp instance allocated
+    *        and owned by caller.
+    * @return true if a timestamp is available, or false if no timestamp is available.
+    *         If a timestamp if available,
+    *         the AudioTimestamp instance is filled in with a position in frame units, together
+    *         with the estimated time when that frame was presented or is committed to
+    *         be presented.
+    *         In the case that no timestamp is available, any supplied instance is left unaltered.
+    */
+    public boolean getTimestamp(AudioTimestamp timestamp)
+    {
+        if (timestamp == null) {
+            throw new IllegalArgumentException();
+        }
+        // It's unfortunate, but we have to either create garbage every time or use synchronized
+        long[] longArray = new long[2];
+        int ret = native_get_timestamp(longArray);
+        if (ret != SUCCESS) {
+            return false;
+        }
+        timestamp.framePosition = longArray[0];
+        timestamp.nanoTime = longArray[1];
+        return true;
+    }
+
+
     //--------------------------------------------------------------------------
     // Initialization / configuration
     //--------------------
@@ -793,10 +849,13 @@
 
     /**
      * Sets the playback sample rate for this track. This sets the sampling rate at which
-     * the audio data will be consumed and played back, not the original sampling rate of the
-     * content. Setting it to half the sample rate of the content will cause the playback to
-     * last twice as long, but will also result in a negative pitch shift.
-     * The valid sample rate range is from 1Hz to twice the value returned by
+     * the audio data will be consumed and played back
+     * (as set by the sampleRateInHz parameter in the
+     * {@link #AudioTrack(int, int, int, int, int, int)} constructor),
+     * not the original sampling rate of the
+     * content. For example, setting it to half the sample rate of the content will cause the
+     * playback to last twice as long, but will also result in a pitch shift down by one octave.
+     * The valid sample rate range is from 1 Hz to twice the value returned by
      * {@link #getNativeOutputSampleRate(int)}.
      * @param sampleRateInHz the sample rate expressed in Hz
      * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
@@ -814,8 +873,11 @@
 
 
     /**
-     * Sets the position of the notification marker.
-     * @param markerInFrames marker in frames
+     * Sets the position of the notification marker.  At most one marker can be active.
+     * @param markerInFrames marker position in wrapping frame units similar to
+     * {@link #getPlaybackHeadPosition}, or zero to disable the marker.
+     * To set a marker at a position which would appear as zero due to wraparound,
+     * a workaround is to use a non-zero position near zero, such as -1 or 1.
      * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
      *  {@link #ERROR_INVALID_OPERATION}
      */
@@ -845,6 +907,8 @@
      * The track must be stopped or paused for the position to be changed,
      * and must use the {@link #MODE_STATIC} mode.
      * @param positionInFrames playback head position expressed in frames
+     * Zero corresponds to start of buffer.
+     * The position must not be greater than the buffer size in frames, or negative.
      * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
      *    {@link #ERROR_INVALID_OPERATION}
      */
@@ -853,18 +917,28 @@
                 getPlayState() == PLAYSTATE_PLAYING) {
             return ERROR_INVALID_OPERATION;
         }
+        if (!(0 <= positionInFrames && positionInFrames <= mNativeBufferSizeInFrames)) {
+            return ERROR_BAD_VALUE;
+        }
         return native_set_position(positionInFrames);
     }
 
     /**
      * Sets the loop points and the loop count. The loop can be infinite.
      * Similarly to setPlaybackHeadPosition,
-     * the track must be stopped or paused for the position to be changed,
+     * the track must be stopped or paused for the loop points to be changed,
      * and must use the {@link #MODE_STATIC} mode.
      * @param startInFrames loop start marker expressed in frames
+     * Zero corresponds to start of buffer.
+     * The start marker must not be greater than or equal to the buffer size in frames, or negative.
      * @param endInFrames loop end marker expressed in frames
+     * The total buffer size in frames corresponds to end of buffer.
+     * The end marker must not be greater than the buffer size in frames.
+     * For looping, the end marker must not be less than or equal to the start marker,
+     * but to disable looping
+     * it is permitted for start marker, end marker, and loop count to all be 0.
      * @param loopCount the number of times the loop is looped.
-     *    A value of -1 means infinite looping.
+     *    A value of -1 means infinite looping, and 0 disables looping.
      * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
      *    {@link #ERROR_INVALID_OPERATION}
      */
@@ -873,14 +947,23 @@
                 getPlayState() == PLAYSTATE_PLAYING) {
             return ERROR_INVALID_OPERATION;
         }
+        if (loopCount == 0) {
+            ;   // explicitly allowed as an exception to the loop region range check
+        } else if (!(0 <= startInFrames && startInFrames < mNativeBufferSizeInFrames &&
+                startInFrames < endInFrames && endInFrames <= mNativeBufferSizeInFrames)) {
+            return ERROR_BAD_VALUE;
+        }
         return native_set_loop(startInFrames, endInFrames, loopCount);
     }
 
     /**
-     * Sets the initialization state of the instance. To be used in an AudioTrack subclass
-     * constructor to set a subclass-specific post-initialization state.
+     * Sets the initialization state of the instance. This method was originally intended to be used
+     * in an AudioTrack subclass constructor to set a subclass-specific post-initialization state.
+     * However, subclasses of AudioTrack are no longer recommended, so this method is obsolete.
      * @param state the state of the AudioTrack instance
+     * @deprecated Only accessible by subclasses, which are not recommended for AudioTrack.
      */
+    @Deprecated
     protected void setState(int state) {
         mState = state;
     }
@@ -891,6 +974,7 @@
     //--------------------
     /**
      * Starts playing an AudioTrack.
+     * If track's creation mode is {@link #MODE_STATIC}, you must have called write() prior.
      *
      * @throws IllegalStateException
      */
@@ -955,7 +1039,8 @@
 
     /**
      * Flushes the audio data currently queued for playback. Any data that has
-     * not been played back will be discarded.
+     * not been played back will be discarded.  No-op if not stopped or paused,
+     * or if the track's creation mode is not {@link #MODE_STREAM}.
      */
     public void flush() {
         if (mState == STATE_INITIALIZED) {
@@ -966,11 +1051,13 @@
     }
 
     /**
-     * Writes the audio data to the audio hardware for playback. Will block until
-     * all data has been written to the audio mixer.
+     * Writes the audio data to the audio sink for playback (streaming mode),
+     * or copies audio data for later playback (static buffer mode).
+     * In streaming mode, will block until all data has been written to the audio sink.
+     * In static buffer mode, copies the data to the buffer starting at offset 0.
      * Note that the actual playback of this data might occur after this function
      * returns. This function is thread safe with respect to {@link #stop} calls,
-     * in which case all of the specified data might not be written to the mixer.
+     * in which case all of the specified data might not be written to the audio sink.
      *
      * @param audioData the array that holds the data to play.
      * @param offsetInBytes the offset expressed in bytes in audioData where the data to play
@@ -1007,16 +1094,18 @@
 
 
     /**
-     * Writes the audio data to the audio hardware for playback. Will block until
-     * all data has been written to the audio mixer.
+     * Writes the audio data to the audio sink for playback (streaming mode),
+     * or copies audio data for later playback (static buffer mode).
+     * In streaming mode, will block until all data has been written to the audio sink.
+     * In static buffer mode, copies the data to the buffer starting at offset 0.
      * Note that the actual playback of this data might occur after this function
      * returns. This function is thread safe with respect to {@link #stop} calls,
-     * in which case all of the specified data might not be written to the mixer.
+     * in which case all of the specified data might not be written to the audio sink.
      *
      * @param audioData the array that holds the data to play.
      * @param offsetInShorts the offset expressed in shorts in audioData where the data to play
      *     starts.
-     * @param sizeInShorts the number of bytes to read in audioData after the offset.
+     * @param sizeInShorts the number of shorts to read in audioData after the offset.
      * @return the number of shorts that were written or {@link #ERROR_INVALID_OPERATION}
       *    if the object wasn't properly initialized, or {@link #ERROR_BAD_VALUE} if
       *    the parameters don't resolve to valid data and indexes.
@@ -1049,8 +1138,8 @@
 
     /**
      * Notifies the native resource to reuse the audio data already loaded in the native
-     * layer. This call is only valid with AudioTrack instances that don't use the streaming
-     * model.
+     * layer, that is to rewind to start of buffer.
+     * The track's creation mode must be {@link #MODE_STATIC}.
      * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
      *  {@link #ERROR_INVALID_OPERATION}
      */
@@ -1091,8 +1180,9 @@
 
     /**
      * Sets the send level of the audio track to the attached auxiliary effect
-     * {@link #attachAuxEffect(int)}. The level value range is 0 to 1.0.
-     * <p>By default the send level is 0, so even if an effect is attached to the player
+     * {@link #attachAuxEffect(int)}.  The level value range is 0.0f to 1.0f.
+     * Values are clamped to the (0.0f, 1.0f) interval if outside this range.
+     * <p>By default the send level is 0.0f, so even if an effect is attached to the player
      * this method must be called for the effect to be applied.
      * <p>Note that the passed level value is a raw scalar. UI controls should be scaled
      * logarithmically: the gain applied by audio framework ranges from -72dB to 0dB,
@@ -1270,6 +1360,11 @@
 
     private native final int native_get_latency();
 
+    // longArray must be a non-null array of length >= 2
+    // [0] is assigned the frame position
+    // [1] is assigned the time in CLOCK_MONOTONIC nanoseconds
+    private native final int native_get_timestamp(long[] longArray);
+
     private native final int native_set_loop(int start, int end, int loopCount);
 
     static private native final int native_get_output_sample_rate(int streamType);
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index 4cd3e37..20eb356 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -291,6 +291,20 @@
     }
 
     /**
+     * Returns the offset and length of thumbnail inside the JPEG file, or
+     * {@code null} if there is no thumbnail.
+     *
+     * @return two-element array, the offset in the first value, and length in
+     *         the second, or {@code null} if no thumbnail was found.
+     * @hide
+     */
+    public long[] getThumbnailRange() {
+        synchronized (sLock) {
+            return getThumbnailRangeNative(mFilename);
+        }
+    }
+
+    /**
      * Stores the latitude and longitude value in a float array. The first element is
      * the latitude, and the second element is the longitude. Returns false if the
      * Exif tags are not available.
@@ -416,4 +430,6 @@
     private native void commitChangesNative(String fileName);
 
     private native byte[] getThumbnailNative(String fileName);
+
+    private native long[] getThumbnailRangeNative(String fileName);
 }
diff --git a/media/java/android/media/FocusRequester.java b/media/java/android/media/FocusRequester.java
new file mode 100644
index 0000000..9a39994
--- /dev/null
+++ b/media/java/android/media/FocusRequester.java
@@ -0,0 +1,244 @@
+/*
+ * 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.media;
+
+import android.media.MediaFocusControl.AudioFocusDeathHandler;
+import android.os.IBinder;
+import android.util.Log;
+
+import java.io.PrintWriter;
+
+/**
+ * @hide
+ * Class to handle all the information about a user of audio focus. The lifecycle of each
+ * instance is managed by android.media.MediaFocusControl, from its addition to the audio focus
+ * stack to its release.
+ */
+class FocusRequester {
+
+    // on purpose not using this classe's name, as it will only be used from MediaFocusControl
+    private static final String TAG = "MediaFocusControl";
+    private static final boolean DEBUG = false;
+
+    private AudioFocusDeathHandler mDeathHandler;
+    private final IAudioFocusDispatcher mFocusDispatcher; // may be null
+    private final IBinder mSourceRef;
+    private final String mClientId;
+    private final String mPackageName;
+    private final int mCallingUid;
+    /**
+     * the audio focus gain request that caused the addition of this object in the focus stack.
+     */
+    private final int mFocusGainRequest;
+    /**
+     * the audio focus loss received my mFocusDispatcher, is AudioManager.AUDIOFOCUS_NONE if
+     *  it never lost focus.
+     */
+    private int mFocusLossReceived;
+    /**
+     * the stream type associated with the focus request
+     */
+    private final int mStreamType;
+
+    FocusRequester(int streamType, int focusRequest,
+            IAudioFocusDispatcher afl, IBinder source, String id, AudioFocusDeathHandler hdlr,
+            String pn, int uid) {
+        mStreamType = streamType;
+        mFocusDispatcher = afl;
+        mSourceRef = source;
+        mClientId = id;
+        mDeathHandler = hdlr;
+        mPackageName = pn;
+        mCallingUid = uid;
+        mFocusGainRequest = focusRequest;
+        mFocusLossReceived = AudioManager.AUDIOFOCUS_NONE;
+    }
+
+
+    boolean hasSameClient(String otherClient) {
+        try {
+            return mClientId.compareTo(otherClient) == 0;
+        } catch (NullPointerException e) {
+            return false;
+        }
+    }
+
+    boolean hasSameBinder(IBinder ib) {
+        return (mSourceRef != null) && mSourceRef.equals(ib);
+    }
+
+    boolean hasSamePackage(String pack) {
+        try {
+            return mPackageName.compareTo(pack) == 0;
+        } catch (NullPointerException e) {
+            return false;
+        }
+    }
+
+    boolean hasSameUid(int uid) {
+        return mCallingUid == uid;
+    }
+
+
+    int getGainRequest() {
+        return mFocusGainRequest;
+    }
+
+    int getStreamType() {
+        return mStreamType;
+    }
+
+
+    private static String focusChangeToString(int focus) {
+        switch(focus) {
+            case AudioManager.AUDIOFOCUS_NONE:
+                return "none";
+            case AudioManager.AUDIOFOCUS_GAIN:
+                return "GAIN";
+            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT:
+                return "GAIN_TRANSIENT";
+            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:
+                return "GAIN_TRANSIENT_MAY_DUCK";
+            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE:
+                return "GAIN_TRANSIENT_EXCLUSIVE";
+            case AudioManager.AUDIOFOCUS_LOSS:
+                return "LOSS";
+            case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
+                return "LOSS_TRANSIENT";
+            case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
+                return "LOSS_TRANSIENT_CAN_DUCK";
+            default:
+                return "[invalid focus change" + focus + "]";
+        }
+    }
+
+    private String focusGainToString() {
+        return focusChangeToString(mFocusGainRequest);
+    }
+
+    private String focusLossToString() {
+        return focusChangeToString(mFocusLossReceived);
+    }
+
+    void dump(PrintWriter pw) {
+        pw.println("  source:" + mSourceRef
+                + " -- pack: " + mPackageName
+                + " -- client: " + mClientId
+                + " -- gain: " + focusGainToString()
+                + " -- loss: " + focusLossToString()
+                + " -- uid: " + mCallingUid
+                + " -- stream: " + mStreamType);
+    }
+
+
+    void release() {
+        try {
+            if (mSourceRef != null && mDeathHandler != null) {
+                mSourceRef.unlinkToDeath(mDeathHandler, 0);
+                mDeathHandler = null;
+            }
+        } catch (java.util.NoSuchElementException e) {
+            Log.e(TAG, "FocusRequester.release() hit ", e);
+        }
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        release();
+        super.finalize();
+    }
+
+    /**
+     * For a given audio focus gain request, return the audio focus loss type that will result
+     * from it, taking into account any previous focus loss.
+     * @param gainRequest
+     * @return the audio focus loss type that matches the gain request
+     */
+    private int focusLossForGainRequest(int gainRequest) {
+        switch(gainRequest) {
+            case AudioManager.AUDIOFOCUS_GAIN:
+                switch(mFocusLossReceived) {
+                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
+                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
+                    case AudioManager.AUDIOFOCUS_LOSS:
+                    case AudioManager.AUDIOFOCUS_NONE:
+                        return AudioManager.AUDIOFOCUS_LOSS;
+                }
+            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE:
+            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT:
+                switch(mFocusLossReceived) {
+                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
+                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
+                    case AudioManager.AUDIOFOCUS_NONE:
+                        return AudioManager.AUDIOFOCUS_LOSS_TRANSIENT;
+                    case AudioManager.AUDIOFOCUS_LOSS:
+                        return AudioManager.AUDIOFOCUS_LOSS;
+                }
+            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:
+                switch(mFocusLossReceived) {
+                    case AudioManager.AUDIOFOCUS_NONE:
+                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
+                        return AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK;
+                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
+                        return AudioManager.AUDIOFOCUS_LOSS_TRANSIENT;
+                    case AudioManager.AUDIOFOCUS_LOSS:
+                        return AudioManager.AUDIOFOCUS_LOSS;
+                }
+            default:
+                Log.e(TAG, "focusLossForGainRequest() for invalid focus request "+ gainRequest);
+                        return AudioManager.AUDIOFOCUS_NONE;
+        }
+    }
+
+    void handleExternalFocusGain(int focusGain) {
+        int focusLoss = focusLossForGainRequest(focusGain);
+        handleFocusLoss(focusLoss);
+    }
+
+    void handleFocusGain(int focusGain) {
+        try {
+            if (mFocusDispatcher != null) {
+                if (DEBUG) {
+                    Log.v(TAG, "dispatching " + focusChangeToString(focusGain) + " to "
+                        + mClientId);
+                }
+                mFocusDispatcher.dispatchAudioFocusChange(focusGain, mClientId);
+            }
+            mFocusLossReceived = AudioManager.AUDIOFOCUS_NONE;
+        } catch (android.os.RemoteException e) {
+            Log.e(TAG, "Failure to signal gain of audio focus due to: ", e);
+        }
+    }
+
+    void handleFocusLoss(int focusLoss) {
+        try {
+            if (focusLoss != mFocusLossReceived) {
+                if (mFocusDispatcher != null) {
+                    if (DEBUG) {
+                        Log.v(TAG, "dispatching " + focusChangeToString(focusLoss) + " to "
+                            + mClientId);
+                    }
+                    mFocusDispatcher.dispatchAudioFocusChange(focusLoss, mClientId);
+                }
+                mFocusLossReceived = focusLoss;
+            }
+        } catch (android.os.RemoteException e) {
+            Log.e(TAG, "Failure to signal loss of audio focus due to:", e);
+        }
+    }
+
+}
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index fda8c1b..fe060f8 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -33,25 +33,27 @@
  * {@hide}
  */
 interface IAudioService {
-    
-    void adjustVolume(int direction, int flags);
 
-    oneway void adjustLocalOrRemoteStreamVolume(int streamType, int direction);
+    void adjustVolume(int direction, int flags, String callingPackage);
 
-    void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags);
+    oneway void adjustLocalOrRemoteStreamVolume(int streamType, int direction,
+            String callingPackage);
 
-    void adjustStreamVolume(int streamType, int direction, int flags);
+    void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags,
+            String callingPackage);
 
-    void adjustMasterVolume(int direction, int flags);
+    void adjustStreamVolume(int streamType, int direction, int flags, String callingPackage);
 
-    void setStreamVolume(int streamType, int index, int flags);
+    void adjustMasterVolume(int direction, int flags, String callingPackage);
+
+    void setStreamVolume(int streamType, int index, int flags, String callingPackage);
 
     oneway void setRemoteStreamVolume(int index);
 
-    void setMasterVolume(int index, int flags);
-    
+    void setMasterVolume(int index, int flags, String callingPackage);
+
     void setStreamSolo(int streamType, boolean state, IBinder cb);
-   	
+
     void setStreamMute(int streamType, boolean state, IBinder cb);
 
     boolean isStreamMute(int streamType);
@@ -67,19 +69,19 @@
     int getStreamMaxVolume(int streamType);
 
     int getMasterMaxVolume();
-    
+
     int getLastAudibleStreamVolume(int streamType);
 
     int getLastAudibleMasterVolume();
 
     void setRingerMode(int ringerMode);
-    
+
     int getRingerMode();
 
     void setVibrateSetting(int vibrateType, int vibrateSetting);
-    
+
     int getVibrateSetting(int vibrateType);
-    
+
     boolean shouldVibrate(int vibrateType);
 
     void setMode(int mode, IBinder cb);
@@ -87,15 +89,19 @@
     int getMode();
 
     oneway void playSoundEffect(int effectType);
-  
+
     oneway void playSoundEffectVolume(int effectType, float volume);
 
     boolean loadSoundEffects();
-  
+
     oneway void unloadSoundEffects();
 
     oneway void reloadAudioSettings();
 
+    oneway void avrcpSupportsAbsoluteVolume(String address, boolean support);
+
+    oneway void avrcpUpdateVolume(int oldVolume, int volume);
+
     void setSpeakerphoneOn(boolean on);
 
     boolean isSpeakerphoneOn();
@@ -108,15 +114,15 @@
 
     boolean isBluetoothA2dpOn();
 
-    oneway void setRemoteSubmixOn(boolean on, int address);
+    int requestAudioFocus(int mainStreamType, int durationHint, IBinder cb,
+            IAudioFocusDispatcher fd, String clientId, String callingPackageName);
 
-    int requestAudioFocus(int mainStreamType, int durationHint, IBinder cb, IAudioFocusDispatcher l,
-            String clientId, String callingPackageName);
+    int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId);
 
-    int abandonAudioFocus(IAudioFocusDispatcher l, String clientId);
-    
     void unregisterAudioFocusClient(String clientId);
 
+    int getCurrentAudioFocus();
+
     oneway void dispatchMediaKeyEvent(in KeyEvent keyEvent);
     void dispatchMediaKeyEventUnderWakelock(in KeyEvent keyEvent);
 
@@ -173,6 +179,14 @@
      * @param timeMs the time in ms to seek to, must be positive.
      */
      void setRemoteControlClientPlaybackPosition(int generationId, long timeMs);
+     /**
+      * Notify the user of a RemoteControlClient that it should update its metadata
+      * @param generationId the RemoteControlClient generation counter for which this request is
+      *         issued. Requests for an older generation than current one will be ignored.
+      * @param key the metadata key for which a new value exists
+      * @param value the new metadata value
+      */
+     void updateRemoteControlClientMetadata(int generationId, int key, long value);
 
     /**
      * Do not use directly, use instead
diff --git a/media/java/android/media/IRemoteControlClient.aidl b/media/java/android/media/IRemoteControlClient.aidl
index 2236129..dd729b4 100644
--- a/media/java/android/media/IRemoteControlClient.aidl
+++ b/media/java/android/media/IRemoteControlClient.aidl
@@ -49,4 +49,5 @@
     void setBitmapSizeForDisplay(IRemoteControlDisplay rcd, int w, int h);
     void setWantsSyncForDisplay(IRemoteControlDisplay rcd, boolean wantsSync);
     void seekTo(int clientGeneration, long timeMs);
+    void updateMetadata(int clientGeneration, int key, long value);
 }
\ No newline at end of file
diff --git a/media/java/android/media/Image.java b/media/java/android/media/Image.java
new file mode 100644
index 0000000..9f442f5
--- /dev/null
+++ b/media/java/android/media/Image.java
@@ -0,0 +1,162 @@
+/*
+ * 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.media;
+
+import android.graphics.ImageFormat;
+import java.nio.ByteBuffer;
+import java.lang.AutoCloseable;
+
+/**
+ * <p>A single complete image buffer to use with a media source such as a
+ * {@link MediaCodec} or a
+ * {@link android.hardware.camera2.CameraDevice}.</p>
+ *
+ * <p>This class allows for efficient direct application access to the pixel
+ * data of the Image through one or more
+ * {@link java.nio.ByteBuffer ByteBuffers}. Each buffer is encapsulated in a
+ * {@link Plane} that describes the layout of the pixel data in that plane. Due
+ * to this direct access, and unlike the {@link android.graphics.Bitmap} class,
+ * Images are not directly usable as as UI resources.</p>
+ *
+ * <p>Since Images are often directly produced or consumed by hardware
+ * components, they are a limited resource shared across the system, and should
+ * be closed as soon as they are no longer needed.</p>
+ *
+ * <p>For example, when using the {@link ImageReader} class to read out Images
+ * from various media sources, not closing old Image objects will prevent the
+ * availability of new Images once
+ * {@link ImageReader#getMaxImages the maximum outstanding image count} is
+ * reached.</p>
+ *
+ * @see ImageReader
+ */
+public interface Image extends AutoCloseable {
+    /**
+     * Get the format for this image. This format determines the number of
+     * ByteBuffers needed to represent the image, and the general layout of the
+     * pixel data in each in ByteBuffer.
+     *
+     * The format is one of the values from
+     * {@link android.graphics.ImageFormat}. The mapping between the formats and
+     * the planes is as follows:
+     *
+     * <table>
+     * <tr>
+     *   <th>Format</th>
+     *   <th>Plane count</th>
+     *   <th>Layout details</th>
+     * </tr>
+     * <tr>
+     *   <td>{@link android.graphics.ImageFormat#JPEG}</td>
+     *   <td>1</td>
+     *   <td>Compressed data, so row and pixel strides are 0. To uncompress, use
+     *      {@link android.graphics.BitmapFactory#decodeByteArray}.</td>
+     * </tr>
+     * <tr>
+     *   <td>{@link android.graphics.ImageFormat#YUV_420_888}</td>
+     *   <td>3</td>
+     *   <td>A luminance plane followed by the Cb and Cr chroma planes.
+     *     The chroma planes have half the width and height of the luminance
+     *     plane (4:2:0 subsampling). Each pixel sample in each plane has 8 bits.
+     *     Each plane has its own row stride and pixel stride.</td>
+     * </tr>
+     * <tr>
+     *   <td>{@link android.graphics.ImageFormat#RAW_SENSOR}</td>
+     *   <td>1</td>
+     *   <td>A single plane of raw sensor image data, with 16 bits per color
+     *     sample. The details of the layout need to be queried from the source of
+     *     the raw sensor data, such as
+     *     {@link android.hardware.camera2.CameraDevice}.
+     *   </td>
+     * </tr>
+     * </table>
+     *
+     * @see android.graphics.ImageFormat
+     */
+    public int getFormat();
+
+    /**
+     * The width of the image in pixels. For formats where some color channels
+     * are subsampled, this is the width of the largest-resolution plane.
+     */
+    public int getWidth();
+
+    /**
+     * The height of the image in pixels. For formats where some color channels
+     * are subsampled, this is the height of the largest-resolution plane.
+     */
+    public int getHeight();
+
+    /**
+     * Get the timestamp associated with this frame. The timestamp is measured
+     * in nanoseconds, and is monotonically increasing. However, the zero point
+     * and whether the timestamp can be compared against other sources of time
+     * or images depend on the source of this image.
+     */
+    public long getTimestamp();
+
+    /**
+     * Get the array of pixel planes for this Image. The number of planes is
+     * determined by the format of the Image.
+     */
+    public Plane[] getPlanes();
+
+    /**
+     * Free up this frame for reuse. After calling this method, calling any
+     * methods on this Image will result in an IllegalStateException, and
+     * attempting to read from ByteBuffers returned by an earlier
+     * {@code Plane#getBuffer} call will have undefined behavior.
+     */
+    public void close();
+
+    /**
+     * <p>A single color plane of image data.</p>
+     *
+     * <p>The number and meaning of the planes in an Image are determined by the
+     * format of the Image.</p>
+     *
+     * <p>Once the Image has been closed, any access to the the plane's
+     * ByteBuffer will fail.</p>
+     *
+     * @see #getFormat
+     */
+    public interface Plane {
+        /**
+         * <p>The row stride for this color plane, in bytes.
+         *
+         * <p>This is the distance between the start of two consecutive rows of
+         * pixels in the image.</p>
+         */
+        public int getRowStride();
+        /**
+         * <p>The distance between adjacent pixel samples, in bytes.</p>
+         *
+         * <p>This is the distance between two consecutive pixel values in a row
+         * of pixels. It may be larger than the size of a single pixel to
+         * account for interleaved image data or padded formats.</p>
+         */
+        public int getPixelStride();
+        /**
+         * <p>Get a set of direct {@link java.nio.ByteBuffer byte buffers}
+         * containing the frame data.</p>
+         *
+         * @return the byte buffer containing the image data for this plane.
+         */
+        public ByteBuffer getBuffer();
+    }
+
+}
diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java
new file mode 100644
index 0000000..b14a899
--- /dev/null
+++ b/media/java/android/media/ImageReader.java
@@ -0,0 +1,493 @@
+/*
+ * 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.media;
+
+import android.graphics.ImageFormat;
+import android.graphics.PixelFormat;
+import android.os.Handler;
+import android.os.Looper;
+import android.view.Surface;
+
+import java.lang.ref.WeakReference;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * <p>The ImageReader class allows direct application access to image data
+ * rendered into a {@link android.view.Surface}</p>
+ *
+ * <p>Several Android media API classes accept Surface objects as targets to
+ * render to, including {@link MediaPlayer}, {@link MediaCodec},
+ * {@link android.hardware.camera2.CameraDevice}, and
+ * {@link android.renderscript.Allocation RenderScript Allocations}. The image
+ * sizes and formats that can be used with each source vary, and should be
+ * checked in the documentation for the specific API.</p>
+ *
+ * <p>The image data is encapsulated in {@link Image} objects, and multiple such
+ * objects can be accessed at the same time, up to the number specified by the
+ * {@code maxImages} constructor parameter. New images sent to an ImageReader
+ * through its Surface are queued until accessed through the
+ * {@link #getNextImage} call. Due to memory limits, an image source will
+ * eventually stall or drop Images in trying to render to the Surface if the
+ * ImageReader does not obtain and release Images at a rate equal to the
+ * production rate.</p>
+ */
+public final class ImageReader implements AutoCloseable {
+
+    /**
+     * <p>Create a new reader for images of the desired size and format.</p>
+     *
+     * <p>The maxImages parameter determines the maximum number of {@link Image}
+     * objects that can be be acquired from the ImageReader
+     * simultaneously. Requesting more buffers will use up more memory, so it is
+     * important to use only the minimum number necessary for the use case.</p>
+     *
+     * <p>The valid sizes and formats depend on the source of the image
+     * data.</p>
+     *
+     * @param width the width in pixels of the Images that this reader will
+     * produce.
+     * @param height the height in pixels of the Images that this reader will
+     * produce.
+     * @param format the format of the Image that this reader will produce. This
+     * must be one of the {@link android.graphics.ImageFormat} or
+     * {@link android.graphics.PixelFormat} constants.
+     * @param maxImages the maximum number of images the user will want to
+     * access simultaneously. This should be as small as possible to limit
+     * memory use. Once maxImages Images are obtained by the user, one of them
+     * has to be released before a new Image will become available for access
+     * through getNextImage(). Must be greater than 0.
+     *
+     * @see Image
+     */
+    public ImageReader(int width, int height, int format, int maxImages) {
+        mWidth = width;
+        mHeight = height;
+        mFormat = format;
+        mMaxImages = maxImages;
+
+        if (width < 1 || height < 1) {
+            throw new IllegalArgumentException(
+                "The image dimensions must be positive");
+        }
+        if (mMaxImages < 1) {
+            throw new IllegalArgumentException(
+                "Maximum outstanding image count must be at least 1");
+        }
+
+        mNumPlanes = getNumPlanesFromFormat();
+
+        nativeInit(new WeakReference<ImageReader>(this), width, height, format, maxImages);
+
+        mSurface = nativeGetSurface();
+    }
+
+    public int getWidth() {
+        return mWidth;
+    }
+
+    public int getHeight() {
+        return mHeight;
+    }
+
+    public int getImageFormat() {
+        return mFormat;
+    }
+
+    public int getMaxImages() {
+        return mMaxImages;
+    }
+
+    /**
+     * <p>Get a Surface that can be used to produce Images for this
+     * ImageReader.</p>
+     *
+     * <p>Until valid image data is rendered into this Surface, the
+     * {@link #getNextImage} method will return {@code null}. Only one source
+     * can be producing data into this Surface at the same time, although the
+     * same Surface can be reused with a different API once the first source is
+     * disconnected from the Surface.</p>
+     *
+     * @return A Surface to use for a drawing target for various APIs.
+     */
+    public Surface getSurface() {
+        return mSurface;
+    }
+
+    /**
+     * <p>
+     * Get the next Image from the ImageReader's queue. Returns {@code null} if
+     * no new image is available.
+     * </p>
+     * <p>
+     * This operation will fail by throwing an
+     * {@link Surface.OutOfResourcesException OutOfResourcesException} if too
+     * many images have been acquired with {@link #getNextImage}. In particular
+     * a sequence of {@link #getNextImage} calls greater than {@link #getMaxImages}
+     * without calling {@link Image#close} or {@link #releaseImage} in-between
+     * will exhaust the underlying queue. At such a time,
+     * {@link Surface.OutOfResourcesException OutOfResourcesException} will be
+     * thrown until more images are released with {@link Image#close} or
+     * {@link #releaseImage}.
+     * </p>
+     *
+     * @return a new frame of image data, or {@code null} if no image data is
+     *         available.
+     * @throws Surface.OutOfResourcesException if too many images are currently
+     *         acquired
+     */
+    public Image getNextImage() {
+        SurfaceImage si = new SurfaceImage();
+        if (nativeImageSetup(si)) {
+            // create SurfacePlane objects
+            si.createSurfacePlanes();
+            si.setImageValid(true);
+            return si;
+        }
+        return null;
+    }
+
+    /**
+     * <p>Return the frame to the ImageReader for reuse.</p>
+     */
+    public void releaseImage(Image i) {
+        if (! (i instanceof SurfaceImage) ) {
+            throw new IllegalArgumentException(
+                "This image was not produced by an ImageReader");
+        }
+        SurfaceImage si = (SurfaceImage) i;
+        if (si.getReader() != this) {
+            throw new IllegalArgumentException(
+                "This image was not produced by this ImageReader");
+        }
+
+        si.clearSurfacePlanes();
+        nativeReleaseImage(i);
+        si.setImageValid(false);
+    }
+
+    /**
+     * Register a listener to be invoked when a new image becomes available
+     * from the ImageReader.
+     * @param listener the listener that will be run
+     * @param handler The handler on which the listener should be invoked, or null
+     * if the listener should be invoked on the calling thread's looper.
+     *
+     * @throws IllegalArgumentException if no handler specified and the calling thread has no looper
+     */
+   public void setImageAvailableListener(OnImageAvailableListener listener, Handler handler) {
+        mImageListener = listener;
+
+        Looper looper;
+        mHandler = handler;
+        if (listener != null && mHandler == null) {
+            if ((looper = Looper.myLooper()) != null) {
+                mHandler = new Handler();
+            } else {
+                throw new IllegalArgumentException(
+                        "Looper doesn't exist in the calling thread");
+            }
+        }
+    }
+
+    /**
+     * Callback interface for being notified that a new image is available.
+     * The onImageAvailable is called per image basis, that is, callback fires for every new frame
+     * available from ImageReader.
+     */
+    public interface OnImageAvailableListener {
+        /**
+         * Callback that is called when a new image is available from ImageReader.
+         * @param reader the ImageReader the callback is associated with.
+         * @see ImageReader
+         * @see Image
+         */
+        void onImageAvailable(ImageReader reader);
+    }
+
+    /**
+     * Free up all the resources associated with this ImageReader. After
+     * Calling this method, this ImageReader can not be used. calling
+     * any methods on this ImageReader and Images previously provided by {@link #getNextImage}
+     * will result in an IllegalStateException, and attempting to read from
+     * ByteBuffers returned by an earlier {@code Plane#getBuffer} call will
+     * have undefined behavior.
+     */
+    @Override
+    public void close() {
+        nativeClose();
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            close();
+        } finally {
+            super.finalize();
+        }
+    }
+
+    /**
+     * Only a subset of the formats defined in {@link android.graphics.ImageFormat} and
+     * {@link android.graphics.PixelFormat} are supported by ImageReader. When reading RGB
+     * data from a surface, the formats defined in {@link android.graphics.PixelFormat}
+     * can be used, when reading YUV, JPEG or raw sensor data ( for example, from camera
+     *  or video decoder), formats from {@link android.graphics.ImageFormat} are used.
+     */
+    private int getNumPlanesFromFormat() {
+        switch (mFormat) {
+            case ImageFormat.YV12:
+            case ImageFormat.YUV_420_888:
+            case ImageFormat.NV21:
+                return 3;
+            case ImageFormat.NV16:
+                return 2;
+            case PixelFormat.RGB_565:
+            case PixelFormat.RGBA_8888:
+            case PixelFormat.RGBX_8888:
+            case PixelFormat.RGB_888:
+            case ImageFormat.JPEG:
+            case ImageFormat.YUY2:
+            case ImageFormat.Y8:
+            case ImageFormat.Y16:
+            case ImageFormat.RAW_SENSOR:
+                return 1;
+            default:
+                throw new UnsupportedOperationException(
+                        String.format("Invalid format specified %d", mFormat));
+        }
+    }
+
+    /**
+     * Called from Native code when an Event happens.
+     */
+    private static void postEventFromNative(Object selfRef) {
+        @SuppressWarnings("unchecked")
+        WeakReference<ImageReader> weakSelf = (WeakReference<ImageReader>)selfRef;
+        final ImageReader ir = weakSelf.get();
+        if (ir == null) {
+            return;
+        }
+
+        if (ir.mHandler != null && ir.mImageListener != null) {
+            ir.mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    ir.mImageListener.onImageAvailable(ir);
+                }
+              });
+        }
+    }
+
+    private final int mWidth;
+    private final int mHeight;
+    private final int mFormat;
+    private final int mMaxImages;
+    private final int mNumPlanes;
+    private final Surface mSurface;
+
+    private Handler mHandler;
+    private OnImageAvailableListener mImageListener;
+
+    /**
+     * This field is used by native code, do not access or modify.
+     */
+    private long mNativeContext;
+
+    private class SurfaceImage implements android.media.Image {
+        public SurfaceImage() {
+            mIsImageValid = false;
+        }
+
+        @Override
+        public void close() {
+            if (mIsImageValid) {
+                ImageReader.this.releaseImage(this);
+            }
+        }
+
+        public ImageReader getReader() {
+            return ImageReader.this;
+        }
+
+        @Override
+        public int getFormat() {
+            if (mIsImageValid) {
+                return ImageReader.this.mFormat;
+            } else {
+                throw new IllegalStateException("Image is already released");
+            }
+        }
+
+        @Override
+        public int getWidth() {
+            if (mIsImageValid) {
+                return ImageReader.this.mWidth;
+            } else {
+                throw new IllegalStateException("Image is already released");
+            }
+        }
+
+        @Override
+        public int getHeight() {
+            if (mIsImageValid) {
+                return ImageReader.this.mHeight;
+            } else {
+                throw new IllegalStateException("Image is already released");
+            }
+        }
+
+        @Override
+        public long getTimestamp() {
+            if (mIsImageValid) {
+                return mTimestamp;
+            } else {
+                throw new IllegalStateException("Image is already released");
+            }
+        }
+
+        @Override
+        public Plane[] getPlanes() {
+            if (mIsImageValid) {
+                // Shallow copy is fine.
+                return mPlanes.clone();
+            } else {
+                throw new IllegalStateException("Image is already released");
+            }
+        }
+
+        @Override
+        protected final void finalize() throws Throwable {
+            try {
+                close();
+            } finally {
+                super.finalize();
+            }
+        }
+
+        private void setImageValid(boolean isValid) {
+            mIsImageValid = isValid;
+        }
+
+        private boolean isImageValid() {
+            return mIsImageValid;
+        }
+
+        private void clearSurfacePlanes() {
+            if (mIsImageValid) {
+                for (int i = 0; i < mPlanes.length; i++) {
+                    if (mPlanes[i] != null) {
+                        mPlanes[i].clearBuffer();
+                        mPlanes[i] = null;
+                    }
+                }
+            }
+        }
+
+        private void createSurfacePlanes() {
+            mPlanes = new SurfacePlane[ImageReader.this.mNumPlanes];
+            for (int i = 0; i < ImageReader.this.mNumPlanes; i++) {
+                mPlanes[i] = nativeCreatePlane(i);
+            }
+        }
+        private class SurfacePlane implements android.media.Image.Plane {
+            // SurfacePlane instance is created by native code when a new SurfaceImage is created
+            private SurfacePlane(int index, int rowStride, int pixelStride) {
+                mIndex = index;
+                mRowStride = rowStride;
+                mPixelStride = pixelStride;
+            }
+
+            @Override
+            public ByteBuffer getBuffer() {
+                if (SurfaceImage.this.isImageValid() == false) {
+                    throw new IllegalStateException("Image is already released");
+                }
+                if (mBuffer != null) {
+                    return mBuffer;
+                } else {
+                    mBuffer = SurfaceImage.this.nativeImageGetBuffer(mIndex);
+                    // Set the byteBuffer order according to host endianness (native order),
+                    // otherwise, the byteBuffer order defaults to ByteOrder.BIG_ENDIAN.
+                    return mBuffer.order(ByteOrder.nativeOrder());
+                }
+            }
+
+            @Override
+            public int getPixelStride() {
+                if (SurfaceImage.this.isImageValid()) {
+                    return mPixelStride;
+                } else {
+                    throw new IllegalStateException("Image is already released");
+                }
+            }
+
+            @Override
+            public int getRowStride() {
+                if (SurfaceImage.this.isImageValid()) {
+                    return mRowStride;
+                } else {
+                    throw new IllegalStateException("Image is already released");
+                }
+            }
+
+            private void clearBuffer() {
+                mBuffer = null;
+            }
+
+            final private int mIndex;
+            final private int mPixelStride;
+            final private int mRowStride;
+
+            private ByteBuffer mBuffer;
+        }
+
+        /**
+         * This field is used to keep track of native object and used by native code only.
+         * Don't modify.
+         */
+        private long mLockedBuffer;
+
+        /**
+         * This field is set by native code during nativeImageSetup().
+         */
+        private long mTimestamp;
+
+        private SurfacePlane[] mPlanes;
+        private boolean mIsImageValid;
+
+        private synchronized native ByteBuffer nativeImageGetBuffer(int idx);
+        private synchronized native SurfacePlane nativeCreatePlane(int idx);
+    }
+
+    private synchronized native void nativeInit(Object weakSelf, int w, int h,
+                                                    int fmt, int maxImgs);
+    private synchronized native void nativeClose();
+    private synchronized native void nativeReleaseImage(Image i);
+    private synchronized native Surface nativeGetSurface();
+    private synchronized native boolean nativeImageSetup(Image i);
+
+    /*
+     * We use a class initializer to allow the native code to cache some
+     * field offsets.
+     */
+    private static native void nativeClassInit();
+    static {
+        System.loadLibrary("media_jni");
+        nativeClassInit();
+    }
+}
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index d703642c..1250cbc 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -164,7 +164,8 @@
      *
      * The following is a partial list of defined mime types and their semantics:
      * <ul>
-     * <li>"video/x-vnd.on2.vp8" - VPX video (i.e. video in .webm)
+     * <li>"video/x-vnd.on2.vp8" - VP8 video (i.e. video in .webm)
+     * <li>"video/x-vnd.on2.vp9" - VP9 video (i.e. video in .webm)
      * <li>"video/avc" - H.264/AVC video
      * <li>"video/mp4v-es" - MPEG4 video
      * <li>"video/3gpp" - H.263 video
@@ -293,12 +294,36 @@
      */
     public native final void flush();
 
+    /**
+     * Thrown when a crypto error occurs while queueing a secure input buffer.
+     */
     public final static class CryptoException extends RuntimeException {
         public CryptoException(int errorCode, String detailMessage) {
             super(detailMessage);
             mErrorCode = errorCode;
         }
 
+        /**
+         * This indicates that no key has been set to perform the requested
+         * decrypt operation.
+         */
+        public static final int ERROR_NO_KEY = 1;
+
+        /**
+         * This indicates that the key used for decryption is no longer
+         * valid due to license term expiration.
+         */
+        public static final int ERROR_KEY_EXPIRED = 2;
+
+        /**
+         * This indicates that a required crypto resource was not able to be
+         * allocated while attempting the requested operation.
+         */
+        public static final int ERROR_RESOURCE_BUSY = 3;
+
+        /**
+         * Retrieve the error code associated with a CryptoException
+         */
         public int getErrorCode() {
             return mErrorCode;
         }
@@ -430,6 +455,9 @@
      * @param presentationTimeUs The time at which this buffer should be rendered.
      * @param flags A bitmask of flags {@link #BUFFER_FLAG_SYNC_FRAME},
      *              {@link #BUFFER_FLAG_CODEC_CONFIG} or {@link #BUFFER_FLAG_END_OF_STREAM}.
+     * @throws CryptoException if an error occurs while attempting to decrypt the buffer.
+     *              An error code associated with the exception helps identify the
+     *              reason for the failure.
      */
     public native final void queueSecureInputBuffer(
             int index,
@@ -545,6 +573,52 @@
     public native final String getName();
 
     /**
+     * Change a video encoder's target bitrate on the fly. The value is an
+     * Integer object containing the new bitrate in bps.
+     */
+    public static final String PARAMETER_KEY_VIDEO_BITRATE = "videoBitrate";
+
+    /**
+     * Temporarily suspend/resume encoding of input data. While suspended
+     * input data is effectively discarded instead of being fed into the
+     * encoder. This parameter really only makes sense to use with an encoder
+     * in "surface-input" mode, as the client code has no control over the
+     * input-side of the encoder in that case.
+     * The value is an Integer object containing the value 1 to suspend
+     * or the value 0 to resume.
+     */
+    public static final String PARAMETER_KEY_SUSPEND = "drop-input-frames";
+
+    /**
+     * Request that the encoder produce a sync frame "soon".
+     * Provide an Integer with the value 0.
+     */
+    public static final String PARAMETER_KEY_REQUEST_SYNC_FRAME = "request-sync";
+
+    /**
+     * Communicate additional parameter changes to the component instance.
+     */
+    public final void setParameters(Map<String, Object> params) {
+        if (params == null) {
+            return;
+        }
+
+        String[] keys = new String[params.size()];
+        Object[] values = new Object[params.size()];
+
+        int i = 0;
+        for (Map.Entry<String, Object> entry: params.entrySet()) {
+            keys[i] = entry.getKey();
+            values[i] = entry.getValue();
+            ++i;
+        }
+
+        setParameters(keys, values);
+    }
+
+    private native final void setParameters(String[] keys, Object[] values);
+
+    /**
      * Get the codec info. If the codec was created by createDecoderByType
      * or createEncoderByType, what component is chosen is not known beforehand,
      * and thus the caller does not have the MediaCodecInfo.
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index aeed7d4..90c12c6 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -72,7 +72,8 @@
     /**
      * Encapsulates the capabilities of a given codec component.
      * For example, what profile/level combinations it supports and what colorspaces
-     * it is capable of providing the decoded data in.
+     * it is capable of providing the decoded data in, as well as some
+     * codec-type specific capability flags.
      * <p>You can get an instance for a given {@link MediaCodecInfo} object with
      * {@link MediaCodecInfo#getCapabilitiesForType getCapabilitiesForType()}, passing a MIME type.
      */
@@ -139,6 +140,24 @@
          * OMX_COLOR_FORMATTYPE.
          */
         public int[] colorFormats;
+
+        private final static int FLAG_SupportsAdaptivePlayback       = (1 << 0);
+        private int flags;
+
+        /**
+         * <b>video decoder only</b>: codec supports seamless resolution changes.
+         */
+        public final static String FEATURE_AdaptivePlayback       = "adaptive-playback";
+
+        /**
+         * Query codec feature capabilities.
+         */
+        public final boolean isFeatureSupported(String name) {
+            if (name.equals(FEATURE_AdaptivePlayback)) {
+                return (flags & FLAG_SupportsAdaptivePlayback) != 0;
+            }
+            return false;
+        }
     };
 
     /**
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index 7677d8a1..6b278d4 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -108,7 +108,19 @@
      * @param uuid The UUID of the crypto scheme.
      */
     public static final boolean isCryptoSchemeSupported(UUID uuid) {
-        return isCryptoSchemeSupportedNative(getByteArrayFromUUID(uuid));
+        return isCryptoSchemeSupportedNative(getByteArrayFromUUID(uuid), null);
+    }
+
+    /**
+     * Query if the given scheme identified by its UUID is supported on
+     * this device, and whether the drm plugin is able to handle the
+     * media container format specified by mimeType.
+     * @param uuid The UUID of the crypto scheme.
+     * @param mimeType The MIME type of the media container, e.g. "video/mp4"
+     *   or "video/webm"
+     */
+    public static final boolean isCryptoSchemeSupported(UUID uuid, String mimeType) {
+        return isCryptoSchemeSupportedNative(getByteArrayFromUUID(uuid), mimeType);
     }
 
     private static final byte[] getByteArrayFromUUID(UUID uuid) {
@@ -124,7 +136,8 @@
         return uuidBytes;
     }
 
-    private static final native boolean isCryptoSchemeSupportedNative(byte[] uuid);
+    private static final native boolean isCryptoSchemeSupportedNative(byte[] uuid,
+                                                                      String mimeType);
 
     /**
      * Instantiate a MediaDrm object
@@ -273,6 +286,7 @@
      * Open a new session with the MediaDrm object.  A session ID is returned.
      *
      * @throws NotProvisionedException if provisioning is needed
+     * @throws ResourceBusyException if required resources are in use
      */
     public native byte[] openSession() throws NotProvisionedException;
 
@@ -379,6 +393,7 @@
      * reprovisioning is required
      * @throws DeniedByServerException if the response indicates that the
      * server rejected the request
+     * @throws ResourceBusyException if required resources are in use
      */
     public native byte[] provideKeyResponse(byte[] scope, byte[] response)
         throws NotProvisionedException, DeniedByServerException;
diff --git a/media/java/android/media/MediaFocusControl.java b/media/java/android/media/MediaFocusControl.java
new file mode 100644
index 0000000..ab686e6
--- /dev/null
+++ b/media/java/android/media/MediaFocusControl.java
@@ -0,0 +1,2445 @@
+/*
+ * 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.media;
+
+import android.app.Activity;
+import android.app.AppOpsManager;
+import android.app.KeyguardManager;
+import android.app.PendingIntent;
+import android.app.PendingIntent.CanceledException;
+import android.app.PendingIntent.OnFinished;
+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.PackageManager;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.IBinder.DeathRecipient;
+import android.provider.Settings;
+import android.speech.RecognizerIntent;
+import android.telephony.PhoneStateListener;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+import android.view.KeyEvent;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Stack;
+
+/**
+ * @hide
+ *
+ */
+public class MediaFocusControl implements OnFinished {
+
+    private static final String TAG = "MediaFocusControl";
+
+    /** Debug remote control client/display feature */
+    protected static final boolean DEBUG_RC = false;
+    /** Debug volumes */
+    protected static final boolean DEBUG_VOL = false;
+
+    /** Used to alter media button redirection when the phone is ringing. */
+    private boolean mIsRinging = false;
+
+    private final PowerManager.WakeLock mMediaEventWakeLock;
+    private final MediaEventHandler mEventHandler;
+    private final Context mContext;
+    private final ContentResolver mContentResolver;
+    private final VolumeController mVolumeController;
+    private final BroadcastReceiver mReceiver = new PackageIntentsReceiver();
+    private final AppOpsManager mAppOps;
+    private final KeyguardManager mKeyguardManager;
+    private final AudioService mAudioService;
+
+    protected MediaFocusControl(Looper looper, Context cntxt,
+            VolumeController volumeCtrl, AudioService as) {
+        mEventHandler = new MediaEventHandler(looper);
+        mContext = cntxt;
+        mContentResolver = mContext.getContentResolver();
+        mVolumeController = volumeCtrl;
+        mAudioService = as;
+
+        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
+        mMediaEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleMediaEvent");
+        mMainRemote = new RemotePlaybackState(-1,
+                AudioService.getMaxStreamVolume(AudioManager.STREAM_MUSIC),
+                AudioService.getMaxStreamVolume(AudioManager.STREAM_MUSIC));
+
+        // Register for phone state monitoring
+        TelephonyManager tmgr = (TelephonyManager)
+                mContext.getSystemService(Context.TELEPHONY_SERVICE);
+        tmgr.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
+
+        // Register for package addition/removal/change intent broadcasts
+        //    for media button receiver persistence
+        IntentFilter pkgFilter = new IntentFilter();
+        pkgFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+        pkgFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
+        pkgFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+        pkgFilter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED);
+        pkgFilter.addDataScheme("package");
+        mContext.registerReceiver(mReceiver, pkgFilter);
+
+        mAppOps = (AppOpsManager)mContext.getSystemService(Context.APP_OPS_SERVICE);
+        mKeyguardManager =
+                (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
+
+        mHasRemotePlayback = false;
+        mMainRemoteIsActive = false;
+        postReevaluateRemote();
+    }
+
+    protected void dump(PrintWriter pw) {
+        dumpFocusStack(pw);
+        dumpRCStack(pw);
+        dumpRCCStack(pw);
+        dumpRCDList(pw);
+    }
+
+    //==========================================================================================
+    // Internal event handling
+    //==========================================================================================
+
+    // event handler messages
+    private static final int MSG_PERSIST_MEDIABUTTONRECEIVER = 0;
+    private static final int MSG_RCDISPLAY_CLEAR = 1;
+    private static final int MSG_RCDISPLAY_UPDATE = 2;
+    private static final int MSG_REEVALUATE_REMOTE = 3;
+    private static final int MSG_RCC_NEW_PLAYBACK_INFO = 4;
+    private static final int MSG_RCC_NEW_VOLUME_OBS = 5;
+    private static final int MSG_PROMOTE_RCC = 6;
+    private static final int MSG_RCC_NEW_PLAYBACK_STATE = 7;
+    private static final int MSG_RCC_SEEK_REQUEST = 8;
+    private static final int MSG_RCC_UPDATE_METADATA_LONG = 9;
+
+    // sendMsg() flags
+    /** If the msg is already queued, replace it with this one. */
+    private static final int SENDMSG_REPLACE = 0;
+    /** If the msg is already queued, ignore this one and leave the old. */
+    private static final int SENDMSG_NOOP = 1;
+    /** If the msg is already queued, queue this one and leave the old. */
+    private static final int SENDMSG_QUEUE = 2;
+
+    private static void sendMsg(Handler handler, int msg,
+            int existingMsgPolicy, int arg1, int arg2, Object obj, int delay) {
+
+        if (existingMsgPolicy == SENDMSG_REPLACE) {
+            handler.removeMessages(msg);
+        } else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) {
+            return;
+        }
+
+        handler.sendMessageDelayed(handler.obtainMessage(msg, arg1, arg2, obj), delay);
+    }
+
+    private class MediaEventHandler extends Handler {
+        MediaEventHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch(msg.what) {
+                case MSG_PERSIST_MEDIABUTTONRECEIVER:
+                    onHandlePersistMediaButtonReceiver( (ComponentName) msg.obj );
+                    break;
+
+                case MSG_RCDISPLAY_CLEAR:
+                    onRcDisplayClear();
+                    break;
+
+                case MSG_RCDISPLAY_UPDATE:
+                    // msg.obj is guaranteed to be non null
+                    onRcDisplayUpdate( (RemoteControlStackEntry) msg.obj, msg.arg1);
+                    break;
+
+                case MSG_REEVALUATE_REMOTE:
+                    onReevaluateRemote();
+                    break;
+
+                case MSG_RCC_NEW_PLAYBACK_INFO:
+                    onNewPlaybackInfoForRcc(msg.arg1 /* rccId */, msg.arg2 /* key */,
+                            ((Integer)msg.obj).intValue() /* value */);
+                    break;
+
+                case MSG_RCC_NEW_VOLUME_OBS:
+                    onRegisterVolumeObserverForRcc(msg.arg1 /* rccId */,
+                            (IRemoteVolumeObserver)msg.obj /* rvo */);
+                    break;
+
+                case MSG_RCC_NEW_PLAYBACK_STATE:
+                    onNewPlaybackStateForRcc(msg.arg1 /* rccId */,
+                            msg.arg2 /* state */,
+                            (RccPlaybackState)msg.obj /* newState */);
+                    break;
+
+                case MSG_RCC_SEEK_REQUEST:
+                    onSetRemoteControlClientPlaybackPosition(
+                            msg.arg1 /* generationId */, ((Long)msg.obj).longValue() /* timeMs */);
+                    break;
+
+                case MSG_RCC_UPDATE_METADATA_LONG:
+                    onUpdateRemoteControlClientMetadataLong(msg.arg1 /*genId*/, msg.arg2 /*key*/,
+                            ((Long)msg.obj).longValue() /* value */);
+                    break;
+
+                case MSG_PROMOTE_RCC:
+                    onPromoteRcc(msg.arg1);
+                    break;
+            }
+        }
+    }
+
+
+    //==========================================================================================
+    // AudioFocus
+    //==========================================================================================
+
+    /* constant to identify focus stack entry that is used to hold the focus while the phone
+     * is ringing or during a call. Used by com.android.internal.telephony.CallManager when
+     * entering and exiting calls.
+     */
+    protected final static String IN_VOICE_COMM_FOCUS_ID = "AudioFocus_For_Phone_Ring_And_Calls";
+
+    private final static Object mAudioFocusLock = new Object();
+
+    private final static Object mRingingLock = new Object();
+
+    private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
+        @Override
+        public void onCallStateChanged(int state, String incomingNumber) {
+            if (state == TelephonyManager.CALL_STATE_RINGING) {
+                //Log.v(TAG, " CALL_STATE_RINGING");
+                synchronized(mRingingLock) {
+                    mIsRinging = true;
+                }
+            } else if ((state == TelephonyManager.CALL_STATE_OFFHOOK)
+                    || (state == TelephonyManager.CALL_STATE_IDLE)) {
+                synchronized(mRingingLock) {
+                    mIsRinging = false;
+                }
+            }
+        }
+    };
+
+    /**
+     * Discard the current audio focus owner.
+     * Notify top of audio focus stack that it lost focus (regardless of possibility to reassign
+     * focus), remove it from the stack, and clear the remote control display.
+     */
+    protected void discardAudioFocusOwner() {
+        synchronized(mAudioFocusLock) {
+            if (!mFocusStack.empty()) {
+                // notify the current focus owner it lost focus after removing it from stack
+                final FocusRequester exFocusOwner = mFocusStack.pop();
+                exFocusOwner.handleFocusLoss(AudioManager.AUDIOFOCUS_LOSS);
+                exFocusOwner.release();
+                // clear RCD
+                synchronized(mRCStack) {
+                    clearRemoteControlDisplay_syncAfRcs();
+                }
+            }
+        }
+    }
+
+    private void notifyTopOfAudioFocusStack() {
+        // notify the top of the stack it gained focus
+        if (!mFocusStack.empty()) {
+            if (canReassignAudioFocus()) {
+                mFocusStack.peek().handleFocusGain(AudioManager.AUDIOFOCUS_GAIN);
+            }
+        }
+    }
+
+    /**
+     * Focus is requested, propagate the associated loss throughout the stack.
+     * @param focusGain the new focus gain that will later be added at the top of the stack
+     */
+    private void propagateFocusLossFromGain_syncAf(int focusGain) {
+        // going through the audio focus stack to signal new focus, traversing order doesn't
+        // matter as all entries respond to the same external focus gain
+        Iterator<FocusRequester> stackIterator = mFocusStack.iterator();
+        while(stackIterator.hasNext()) {
+            stackIterator.next().handleExternalFocusGain(focusGain);
+        }
+    }
+
+    private final Stack<FocusRequester> mFocusStack = new Stack<FocusRequester>();
+
+    /**
+     * Helper function:
+     * Display in the log the current entries in the audio focus stack
+     */
+    private void dumpFocusStack(PrintWriter pw) {
+        pw.println("\nAudio Focus stack entries (last is top of stack):");
+        synchronized(mAudioFocusLock) {
+            Iterator<FocusRequester> stackIterator = mFocusStack.iterator();
+            while(stackIterator.hasNext()) {
+                stackIterator.next().dump(pw);
+            }
+        }
+    }
+
+    /**
+     * Helper function:
+     * Called synchronized on mAudioFocusLock
+     * Remove a focus listener from the focus stack.
+     * @param clientToRemove the focus listener
+     * @param signal if true and the listener was at the top of the focus stack, i.e. it was holding
+     *   focus, notify the next item in the stack it gained focus.
+     */
+    private void removeFocusStackEntry(String clientToRemove, boolean signal) {
+        // is the current top of the focus stack abandoning focus? (because of request, not death)
+        if (!mFocusStack.empty() && mFocusStack.peek().hasSameClient(clientToRemove))
+        {
+            //Log.i(TAG, "   removeFocusStackEntry() removing top of stack");
+            FocusRequester fr = mFocusStack.pop();
+            fr.release();
+            if (signal) {
+                // notify the new top of the stack it gained focus
+                notifyTopOfAudioFocusStack();
+                // there's a new top of the stack, let the remote control know
+                synchronized(mRCStack) {
+                    checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
+                }
+            }
+        } else {
+            // focus is abandoned by a client that's not at the top of the stack,
+            // no need to update focus.
+            // (using an iterator on the stack so we can safely remove an entry after having
+            //  evaluated it, traversal order doesn't matter here)
+            Iterator<FocusRequester> stackIterator = mFocusStack.iterator();
+            while(stackIterator.hasNext()) {
+                FocusRequester fr = (FocusRequester)stackIterator.next();
+                if(fr.hasSameClient(clientToRemove)) {
+                    Log.i(TAG, "AudioFocus  removeFocusStackEntry(): removing entry for "
+                            + clientToRemove);
+                    stackIterator.remove();
+                    fr.release();
+                }
+            }
+        }
+    }
+
+    /**
+     * Helper function:
+     * Called synchronized on mAudioFocusLock
+     * Remove focus listeners from the focus stack for a particular client when it has died.
+     */
+    private void removeFocusStackEntryForClient(IBinder cb) {
+        // is the owner of the audio focus part of the client to remove?
+        boolean isTopOfStackForClientToRemove = !mFocusStack.isEmpty() &&
+                mFocusStack.peek().hasSameBinder(cb);
+        // (using an iterator on the stack so we can safely remove an entry after having
+        //  evaluated it, traversal order doesn't matter here)
+        Iterator<FocusRequester> stackIterator = mFocusStack.iterator();
+        while(stackIterator.hasNext()) {
+            FocusRequester fr = (FocusRequester)stackIterator.next();
+            if(fr.hasSameBinder(cb)) {
+                Log.i(TAG, "AudioFocus  removeFocusStackEntry(): removing entry for " + cb);
+                stackIterator.remove();
+                // the client just died, no need to unlink to its death
+            }
+        }
+        if (isTopOfStackForClientToRemove) {
+            // we removed an entry at the top of the stack:
+            //  notify the new top of the stack it gained focus.
+            notifyTopOfAudioFocusStack();
+            // there's a new top of the stack, let the remote control know
+            synchronized(mRCStack) {
+                checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
+            }
+        }
+    }
+
+    /**
+     * Helper function:
+     * Returns true if the system is in a state where the focus can be reevaluated, false otherwise.
+     */
+    private boolean canReassignAudioFocus() {
+        // focus requests are rejected during a phone call or when the phone is ringing
+        // this is equivalent to IN_VOICE_COMM_FOCUS_ID having the focus
+        if (!mFocusStack.isEmpty() && mFocusStack.peek().hasSameClient(IN_VOICE_COMM_FOCUS_ID)) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Inner class to monitor audio focus client deaths, and remove them from the audio focus
+     * stack if necessary.
+     */
+    protected class AudioFocusDeathHandler implements IBinder.DeathRecipient {
+        private IBinder mCb; // To be notified of client's death
+
+        AudioFocusDeathHandler(IBinder cb) {
+            mCb = cb;
+        }
+
+        public void binderDied() {
+            synchronized(mAudioFocusLock) {
+                Log.w(TAG, "  AudioFocus   audio focus client died");
+                removeFocusStackEntryForClient(mCb);
+            }
+        }
+
+        public IBinder getBinder() {
+            return mCb;
+        }
+    }
+
+    protected int getCurrentAudioFocus() {
+        synchronized(mAudioFocusLock) {
+            if (mFocusStack.empty()) {
+                return AudioManager.AUDIOFOCUS_NONE;
+            } else {
+                return mFocusStack.peek().getGainRequest();
+            }
+        }
+    }
+
+    /** @see AudioManager#requestAudioFocus(AudioManager.OnAudioFocusChangeListener, int, int)  */
+    protected int requestAudioFocus(int mainStreamType, int focusChangeHint, IBinder cb,
+            IAudioFocusDispatcher fd, String clientId, String callingPackageName) {
+        Log.i(TAG, " AudioFocus  requestAudioFocus() from " + clientId);
+        // we need a valid binder callback for clients
+        if (!cb.pingBinder()) {
+            Log.e(TAG, " AudioFocus DOA client for requestAudioFocus(), aborting.");
+            return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
+        }
+
+        if (mAppOps.noteOp(AppOpsManager.OP_TAKE_AUDIO_FOCUS, Binder.getCallingUid(),
+                callingPackageName) != AppOpsManager.MODE_ALLOWED) {
+            return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
+        }
+
+        synchronized(mAudioFocusLock) {
+            if (!canReassignAudioFocus()) {
+                return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
+            }
+
+            // handle the potential premature death of the new holder of the focus
+            // (premature death == death before abandoning focus)
+            // Register for client death notification
+            AudioFocusDeathHandler afdh = new AudioFocusDeathHandler(cb);
+            try {
+                cb.linkToDeath(afdh, 0);
+            } catch (RemoteException e) {
+                // client has already died!
+                Log.w(TAG, "AudioFocus  requestAudioFocus() could not link to "+cb+" binder death");
+                return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
+            }
+
+            if (!mFocusStack.empty() && mFocusStack.peek().hasSameClient(clientId)) {
+                // if focus is already owned by this client and the reason for acquiring the focus
+                // hasn't changed, don't do anything
+                if (mFocusStack.peek().getGainRequest() == focusChangeHint) {
+                    // unlink death handler so it can be gc'ed.
+                    // linkToDeath() creates a JNI global reference preventing collection.
+                    cb.unlinkToDeath(afdh, 0);
+                    return AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
+                }
+                // the reason for the audio focus request has changed: remove the current top of
+                // stack and respond as if we had a new focus owner
+                FocusRequester fr = mFocusStack.pop();
+                fr.release();
+            }
+
+            // focus requester might already be somewhere below in the stack, remove it
+            removeFocusStackEntry(clientId, false /* signal */);
+
+            // propagate the focus change through the stack
+            if (!mFocusStack.empty()) {
+                propagateFocusLossFromGain_syncAf(focusChangeHint);
+            }
+
+            // push focus requester at the top of the audio focus stack
+            mFocusStack.push(new FocusRequester(mainStreamType, focusChangeHint, fd, cb,
+                    clientId, afdh, callingPackageName, Binder.getCallingUid()));
+
+            // there's a new top of the stack, let the remote control know
+            synchronized(mRCStack) {
+                checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
+            }
+        }//synchronized(mAudioFocusLock)
+
+        return AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
+    }
+
+    /** @see AudioManager#abandonAudioFocus(AudioManager.OnAudioFocusChangeListener)  */
+    protected int abandonAudioFocus(IAudioFocusDispatcher fl, String clientId) {
+        Log.i(TAG, " AudioFocus  abandonAudioFocus() from " + clientId);
+        try {
+            // this will take care of notifying the new focus owner if needed
+            synchronized(mAudioFocusLock) {
+                removeFocusStackEntry(clientId, true /*signal*/);
+            }
+        } catch (java.util.ConcurrentModificationException cme) {
+            // Catching this exception here is temporary. It is here just to prevent
+            // a crash seen when the "Silent" notification is played. This is believed to be fixed
+            // but this try catch block is left just to be safe.
+            Log.e(TAG, "FATAL EXCEPTION AudioFocus  abandonAudioFocus() caused " + cme);
+            cme.printStackTrace();
+        }
+
+        return AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
+    }
+
+
+    protected void unregisterAudioFocusClient(String clientId) {
+        synchronized(mAudioFocusLock) {
+            removeFocusStackEntry(clientId, false);
+        }
+    }
+
+
+    //==========================================================================================
+    // RemoteControl
+    //==========================================================================================
+    protected void dispatchMediaKeyEvent(KeyEvent keyEvent) {
+        filterMediaKeyEvent(keyEvent, false /*needWakeLock*/);
+    }
+
+    protected void dispatchMediaKeyEventUnderWakelock(KeyEvent keyEvent) {
+        filterMediaKeyEvent(keyEvent, true /*needWakeLock*/);
+    }
+
+    private void filterMediaKeyEvent(KeyEvent keyEvent, boolean needWakeLock) {
+        // sanity check on the incoming key event
+        if (!isValidMediaKeyEvent(keyEvent)) {
+            Log.e(TAG, "not dispatching invalid media key event " + keyEvent);
+            return;
+        }
+        // event filtering for telephony
+        synchronized(mRingingLock) {
+            synchronized(mRCStack) {
+                if ((mMediaReceiverForCalls != null) &&
+                        (mIsRinging || (mAudioService.getMode() == AudioSystem.MODE_IN_CALL))) {
+                    dispatchMediaKeyEventForCalls(keyEvent, needWakeLock);
+                    return;
+                }
+            }
+        }
+        // event filtering based on voice-based interactions
+        if (isValidVoiceInputKeyCode(keyEvent.getKeyCode())) {
+            filterVoiceInputKeyEvent(keyEvent, needWakeLock);
+        } else {
+            dispatchMediaKeyEvent(keyEvent, needWakeLock);
+        }
+    }
+
+    /**
+     * Handles the dispatching of the media button events to the telephony package.
+     * Precondition: mMediaReceiverForCalls != null
+     * @param keyEvent a non-null KeyEvent whose key code is one of the supported media buttons
+     * @param needWakeLock true if a PARTIAL_WAKE_LOCK needs to be held while this key event
+     *     is dispatched.
+     */
+    private void dispatchMediaKeyEventForCalls(KeyEvent keyEvent, boolean needWakeLock) {
+        Intent keyIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
+        keyIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
+        keyIntent.setPackage(mMediaReceiverForCalls.getPackageName());
+        if (needWakeLock) {
+            mMediaEventWakeLock.acquire();
+            keyIntent.putExtra(EXTRA_WAKELOCK_ACQUIRED, WAKELOCK_RELEASE_ON_FINISHED);
+        }
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            mContext.sendOrderedBroadcastAsUser(keyIntent, UserHandle.ALL,
+                    null, mKeyEventDone, mEventHandler, Activity.RESULT_OK, null, null);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    /**
+     * Handles the dispatching of the media button events to one of the registered listeners,
+     * or if there was none, broadcast an ACTION_MEDIA_BUTTON intent to the rest of the system.
+     * @param keyEvent a non-null KeyEvent whose key code is one of the supported media buttons
+     * @param needWakeLock true if a PARTIAL_WAKE_LOCK needs to be held while this key event
+     *     is dispatched.
+     */
+    private void dispatchMediaKeyEvent(KeyEvent keyEvent, boolean needWakeLock) {
+        if (needWakeLock) {
+            mMediaEventWakeLock.acquire();
+        }
+        Intent keyIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
+        keyIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
+        synchronized(mRCStack) {
+            if (!mRCStack.empty()) {
+                // send the intent that was registered by the client
+                try {
+                    mRCStack.peek().mMediaIntent.send(mContext,
+                            needWakeLock ? WAKELOCK_RELEASE_ON_FINISHED : 0 /*code*/,
+                            keyIntent, this, mEventHandler);
+                } catch (CanceledException e) {
+                    Log.e(TAG, "Error sending pending intent " + mRCStack.peek());
+                    e.printStackTrace();
+                }
+            } else {
+                // legacy behavior when nobody registered their media button event receiver
+                //    through AudioManager
+                if (needWakeLock) {
+                    keyIntent.putExtra(EXTRA_WAKELOCK_ACQUIRED, WAKELOCK_RELEASE_ON_FINISHED);
+                }
+                final long ident = Binder.clearCallingIdentity();
+                try {
+                    mContext.sendOrderedBroadcastAsUser(keyIntent, UserHandle.ALL,
+                            null, mKeyEventDone,
+                            mEventHandler, Activity.RESULT_OK, null, null);
+                } finally {
+                    Binder.restoreCallingIdentity(ident);
+                }
+            }
+        }
+    }
+
+    /**
+     * The different actions performed in response to a voice button key event.
+     */
+    private final static int VOICEBUTTON_ACTION_DISCARD_CURRENT_KEY_PRESS = 1;
+    private final static int VOICEBUTTON_ACTION_START_VOICE_INPUT = 2;
+    private final static int VOICEBUTTON_ACTION_SIMULATE_KEY_PRESS = 3;
+
+    private final Object mVoiceEventLock = new Object();
+    private boolean mVoiceButtonDown;
+    private boolean mVoiceButtonHandled;
+
+    /**
+     * Filter key events that may be used for voice-based interactions
+     * @param keyEvent a non-null KeyEvent whose key code is that of one of the supported
+     *    media buttons that can be used to trigger voice-based interactions.
+     * @param needWakeLock true if a PARTIAL_WAKE_LOCK needs to be held while this key event
+     *     is dispatched.
+     */
+    private void filterVoiceInputKeyEvent(KeyEvent keyEvent, boolean needWakeLock) {
+        if (DEBUG_RC) {
+            Log.v(TAG, "voice input key event: " + keyEvent + ", needWakeLock=" + needWakeLock);
+        }
+
+        int voiceButtonAction = VOICEBUTTON_ACTION_DISCARD_CURRENT_KEY_PRESS;
+        int keyAction = keyEvent.getAction();
+        synchronized (mVoiceEventLock) {
+            if (keyAction == KeyEvent.ACTION_DOWN) {
+                if (keyEvent.getRepeatCount() == 0) {
+                    // initial down
+                    mVoiceButtonDown = true;
+                    mVoiceButtonHandled = false;
+                } else if (mVoiceButtonDown && !mVoiceButtonHandled
+                        && (keyEvent.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
+                    // long-press, start voice-based interactions
+                    mVoiceButtonHandled = true;
+                    voiceButtonAction = VOICEBUTTON_ACTION_START_VOICE_INPUT;
+                }
+            } else if (keyAction == KeyEvent.ACTION_UP) {
+                if (mVoiceButtonDown) {
+                    // voice button up
+                    mVoiceButtonDown = false;
+                    if (!mVoiceButtonHandled && !keyEvent.isCanceled()) {
+                        voiceButtonAction = VOICEBUTTON_ACTION_SIMULATE_KEY_PRESS;
+                    }
+                }
+            }
+        }//synchronized (mVoiceEventLock)
+
+        // take action after media button event filtering for voice-based interactions
+        switch (voiceButtonAction) {
+            case VOICEBUTTON_ACTION_DISCARD_CURRENT_KEY_PRESS:
+                if (DEBUG_RC) Log.v(TAG, "   ignore key event");
+                break;
+            case VOICEBUTTON_ACTION_START_VOICE_INPUT:
+                if (DEBUG_RC) Log.v(TAG, "   start voice-based interactions");
+                // then start the voice-based interactions
+                startVoiceBasedInteractions(needWakeLock);
+                break;
+            case VOICEBUTTON_ACTION_SIMULATE_KEY_PRESS:
+                if (DEBUG_RC) Log.v(TAG, "   send simulated key event, wakelock=" + needWakeLock);
+                sendSimulatedMediaButtonEvent(keyEvent, needWakeLock);
+                break;
+        }
+    }
+
+    private void sendSimulatedMediaButtonEvent(KeyEvent originalKeyEvent, boolean needWakeLock) {
+        // send DOWN event
+        KeyEvent keyEvent = KeyEvent.changeAction(originalKeyEvent, KeyEvent.ACTION_DOWN);
+        dispatchMediaKeyEvent(keyEvent, needWakeLock);
+        // send UP event
+        keyEvent = KeyEvent.changeAction(originalKeyEvent, KeyEvent.ACTION_UP);
+        dispatchMediaKeyEvent(keyEvent, needWakeLock);
+
+    }
+
+    private class PackageIntentsReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(Intent.ACTION_PACKAGE_REMOVED)
+                    || action.equals(Intent.ACTION_PACKAGE_DATA_CLEARED)) {
+                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
+                    // a package is being removed, not replaced
+                    String packageName = intent.getData().getSchemeSpecificPart();
+                    if (packageName != null) {
+                        cleanupMediaButtonReceiverForPackage(packageName, true);
+                    }
+                }
+            } else if (action.equals(Intent.ACTION_PACKAGE_ADDED)
+                    || action.equals(Intent.ACTION_PACKAGE_CHANGED)) {
+                String packageName = intent.getData().getSchemeSpecificPart();
+                if (packageName != null) {
+                    cleanupMediaButtonReceiverForPackage(packageName, false);
+                }
+            }
+        }
+    }
+
+    private static boolean isValidMediaKeyEvent(KeyEvent keyEvent) {
+        if (keyEvent == null) {
+            return false;
+        }
+        final int keyCode = keyEvent.getKeyCode();
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_MUTE:
+            case KeyEvent.KEYCODE_HEADSETHOOK:
+            case KeyEvent.KEYCODE_MEDIA_PLAY:
+            case KeyEvent.KEYCODE_MEDIA_PAUSE:
+            case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
+            case KeyEvent.KEYCODE_MEDIA_STOP:
+            case KeyEvent.KEYCODE_MEDIA_NEXT:
+            case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
+            case KeyEvent.KEYCODE_MEDIA_REWIND:
+            case KeyEvent.KEYCODE_MEDIA_RECORD:
+            case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
+            case KeyEvent.KEYCODE_MEDIA_CLOSE:
+            case KeyEvent.KEYCODE_MEDIA_EJECT:
+            case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK:
+                break;
+            default:
+                return false;
+        }
+        return true;
+    }
+
+    /**
+     * Checks whether the given key code is one that can trigger the launch of voice-based
+     *   interactions.
+     * @param keyCode the key code associated with the key event
+     * @return true if the key is one of the supported voice-based interaction triggers
+     */
+    private static boolean isValidVoiceInputKeyCode(int keyCode) {
+        if (keyCode == KeyEvent.KEYCODE_HEADSETHOOK) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Tell the system to start voice-based interactions / voice commands
+     */
+    private void startVoiceBasedInteractions(boolean needWakeLock) {
+        Intent voiceIntent = null;
+        // select which type of search to launch:
+        // - screen on and device unlocked: action is ACTION_WEB_SEARCH
+        // - device locked or screen off: action is ACTION_VOICE_SEARCH_HANDS_FREE
+        //    with EXTRA_SECURE set to true if the device is securely locked
+        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
+        boolean isLocked = mKeyguardManager != null && mKeyguardManager.isKeyguardLocked();
+        if (!isLocked && pm.isScreenOn()) {
+            voiceIntent = new Intent(android.speech.RecognizerIntent.ACTION_WEB_SEARCH);
+            Log.i(TAG, "voice-based interactions: about to use ACTION_WEB_SEARCH");
+        } else {
+            voiceIntent = new Intent(RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE);
+            voiceIntent.putExtra(RecognizerIntent.EXTRA_SECURE,
+                    isLocked && mKeyguardManager.isKeyguardSecure());
+            Log.i(TAG, "voice-based interactions: about to use ACTION_VOICE_SEARCH_HANDS_FREE");
+        }
+        // start the search activity
+        if (needWakeLock) {
+            mMediaEventWakeLock.acquire();
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            if (voiceIntent != null) {
+                voiceIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                        | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+                mContext.startActivityAsUser(voiceIntent, UserHandle.CURRENT);
+            }
+        } catch (ActivityNotFoundException e) {
+            Log.w(TAG, "No activity for search: " + e);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+            if (needWakeLock) {
+                mMediaEventWakeLock.release();
+            }
+        }
+    }
+
+    private static final int WAKELOCK_RELEASE_ON_FINISHED = 1980; //magic number
+
+    // only set when wakelock was acquired, no need to check value when received
+    private static final String EXTRA_WAKELOCK_ACQUIRED =
+            "android.media.AudioService.WAKELOCK_ACQUIRED";
+
+    public void onSendFinished(PendingIntent pendingIntent, Intent intent,
+            int resultCode, String resultData, Bundle resultExtras) {
+        if (resultCode == WAKELOCK_RELEASE_ON_FINISHED) {
+            mMediaEventWakeLock.release();
+        }
+    }
+
+    BroadcastReceiver mKeyEventDone = new BroadcastReceiver() {
+        public void onReceive(Context context, Intent intent) {
+            if (intent == null) {
+                return;
+            }
+            Bundle extras = intent.getExtras();
+            if (extras == null) {
+                return;
+            }
+            if (extras.containsKey(EXTRA_WAKELOCK_ACQUIRED)) {
+                mMediaEventWakeLock.release();
+            }
+        }
+    };
+
+    /**
+     * Synchronization on mCurrentRcLock always inside a block synchronized on mRCStack
+     */
+    private final Object mCurrentRcLock = new Object();
+    /**
+     * The one remote control client which will receive a request for display information.
+     * This object may be null.
+     * Access protected by mCurrentRcLock.
+     */
+    private IRemoteControlClient mCurrentRcClient = null;
+
+    private final static int RC_INFO_NONE = 0;
+    private final static int RC_INFO_ALL =
+        RemoteControlClient.FLAG_INFORMATION_REQUEST_ALBUM_ART |
+        RemoteControlClient.FLAG_INFORMATION_REQUEST_KEY_MEDIA |
+        RemoteControlClient.FLAG_INFORMATION_REQUEST_METADATA |
+        RemoteControlClient.FLAG_INFORMATION_REQUEST_PLAYSTATE;
+
+    /**
+     * A monotonically increasing generation counter for mCurrentRcClient.
+     * Only accessed with a lock on mCurrentRcLock.
+     * No value wrap-around issues as we only act on equal values.
+     */
+    private int mCurrentRcClientGen = 0;
+
+    /**
+     * Inner class to monitor remote control client deaths, and remove the client for the
+     * remote control stack if necessary.
+     */
+    private class RcClientDeathHandler implements IBinder.DeathRecipient {
+        final private IBinder mCb; // To be notified of client's death
+        final private PendingIntent mMediaIntent;
+
+        RcClientDeathHandler(IBinder cb, PendingIntent pi) {
+            mCb = cb;
+            mMediaIntent = pi;
+        }
+
+        public void binderDied() {
+            Log.w(TAG, "  RemoteControlClient died");
+            // remote control client died, make sure the displays don't use it anymore
+            //  by setting its remote control client to null
+            registerRemoteControlClient(mMediaIntent, null/*rcClient*/, null/*ignored*/);
+            // the dead client was maybe handling remote playback, reevaluate
+            postReevaluateRemote();
+        }
+
+        public IBinder getBinder() {
+            return mCb;
+        }
+    }
+
+    /**
+     * A global counter for RemoteControlClient identifiers
+     */
+    private static int sLastRccId = 0;
+
+    private class RemotePlaybackState {
+        int mRccId;
+        int mVolume;
+        int mVolumeMax;
+        int mVolumeHandling;
+
+        private RemotePlaybackState(int id, int vol, int volMax) {
+            mRccId = id;
+            mVolume = vol;
+            mVolumeMax = volMax;
+            mVolumeHandling = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME_HANDLING;
+        }
+    }
+
+    /**
+     * Internal cache for the playback information of the RemoteControlClient whose volume gets to
+     * be controlled by the volume keys ("main"), so we don't have to iterate over the RC stack
+     * every time we need this info.
+     */
+    private RemotePlaybackState mMainRemote;
+    /**
+     * Indicates whether the "main" RemoteControlClient is considered active.
+     * Use synchronized on mMainRemote.
+     */
+    private boolean mMainRemoteIsActive;
+    /**
+     * Indicates whether there is remote playback going on. True even if there is no "active"
+     * remote playback (mMainRemoteIsActive is false), but a RemoteControlClient has declared it
+     * handles remote playback.
+     * Use synchronized on mMainRemote.
+     */
+    private boolean mHasRemotePlayback;
+
+    private static class RccPlaybackState {
+        public int mState;
+        public long mPositionMs;
+        public float mSpeed;
+
+        public RccPlaybackState(int state, long positionMs, float speed) {
+            mState = state;
+            mPositionMs = positionMs;
+            mSpeed = speed;
+        }
+
+        public void reset() {
+            mState = RemoteControlClient.PLAYSTATE_STOPPED;
+            mPositionMs = RemoteControlClient.PLAYBACK_POSITION_INVALID;
+            mSpeed = RemoteControlClient.PLAYBACK_SPEED_1X;
+        }
+
+        @Override
+        public String toString() {
+            return stateToString() + ", " + posToString() + ", " + mSpeed + "X";
+        }
+
+        private String posToString() {
+            if (mPositionMs == RemoteControlClient.PLAYBACK_POSITION_INVALID) {
+                return "PLAYBACK_POSITION_INVALID";
+            } else if (mPositionMs == RemoteControlClient.PLAYBACK_POSITION_ALWAYS_UNKNOWN) {
+                return "PLAYBACK_POSITION_ALWAYS_UNKNOWN";
+            } else {
+                return (String.valueOf(mPositionMs) + "ms");
+            }
+        }
+
+        private String stateToString() {
+            switch (mState) {
+                case RemoteControlClient.PLAYSTATE_NONE:
+                    return "PLAYSTATE_NONE";
+                case RemoteControlClient.PLAYSTATE_STOPPED:
+                    return "PLAYSTATE_STOPPED";
+                case RemoteControlClient.PLAYSTATE_PAUSED:
+                    return "PLAYSTATE_PAUSED";
+                case RemoteControlClient.PLAYSTATE_PLAYING:
+                    return "PLAYSTATE_PLAYING";
+                case RemoteControlClient.PLAYSTATE_FAST_FORWARDING:
+                    return "PLAYSTATE_FAST_FORWARDING";
+                case RemoteControlClient.PLAYSTATE_REWINDING:
+                    return "PLAYSTATE_REWINDING";
+                case RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS:
+                    return "PLAYSTATE_SKIPPING_FORWARDS";
+                case RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS:
+                    return "PLAYSTATE_SKIPPING_BACKWARDS";
+                case RemoteControlClient.PLAYSTATE_BUFFERING:
+                    return "PLAYSTATE_BUFFERING";
+                case RemoteControlClient.PLAYSTATE_ERROR:
+                    return "PLAYSTATE_ERROR";
+                default:
+                    return "[invalid playstate]";
+            }
+        }
+    }
+
+    protected static class RemoteControlStackEntry implements DeathRecipient {
+        public int mRccId = RemoteControlClient.RCSE_ID_UNREGISTERED;
+        final public MediaFocusControl mController;
+        /**
+         * The target for the ACTION_MEDIA_BUTTON events.
+         * Always non null.
+         */
+        final public PendingIntent mMediaIntent;
+        /**
+         * The registered media button event receiver.
+         * Always non null.
+         */
+        final public ComponentName mReceiverComponent;
+        public IBinder mToken;
+        public String mCallingPackageName;
+        public int mCallingUid;
+        /**
+         * Provides access to the information to display on the remote control.
+         * May be null (when a media button event receiver is registered,
+         *     but no remote control client has been registered) */
+        public IRemoteControlClient mRcClient;
+        public RcClientDeathHandler mRcClientDeathHandler;
+        /**
+         * Information only used for non-local playback
+         */
+        public int mPlaybackType;
+        public int mPlaybackVolume;
+        public int mPlaybackVolumeMax;
+        public int mPlaybackVolumeHandling;
+        public int mPlaybackStream;
+        public RccPlaybackState mPlaybackState;
+        public IRemoteVolumeObserver mRemoteVolumeObs;
+
+        public void resetPlaybackInfo() {
+            mPlaybackType = RemoteControlClient.PLAYBACK_TYPE_LOCAL;
+            mPlaybackVolume = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME;
+            mPlaybackVolumeMax = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME;
+            mPlaybackVolumeHandling = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME_HANDLING;
+            mPlaybackStream = AudioManager.STREAM_MUSIC;
+            mPlaybackState.reset();
+            mRemoteVolumeObs = null;
+        }
+
+        /** precondition: mediaIntent != null */
+        public RemoteControlStackEntry(MediaFocusControl controller, PendingIntent mediaIntent,
+                ComponentName eventReceiver, IBinder token) {
+            mController = controller;
+            mMediaIntent = mediaIntent;
+            mReceiverComponent = eventReceiver;
+            mToken = token;
+            mCallingUid = -1;
+            mRcClient = null;
+            mRccId = ++sLastRccId;
+            mPlaybackState = new RccPlaybackState(
+                    RemoteControlClient.PLAYSTATE_STOPPED,
+                    RemoteControlClient.PLAYBACK_POSITION_INVALID,
+                    RemoteControlClient.PLAYBACK_SPEED_1X);
+
+            resetPlaybackInfo();
+            if (mToken != null) {
+                try {
+                    mToken.linkToDeath(this, 0);
+                } catch (RemoteException e) {
+                    mController.mEventHandler.post(new Runnable() {
+                        @Override public void run() {
+                            mController.unregisterMediaButtonIntent(mMediaIntent);
+                        }
+                    });
+                }
+            }
+        }
+
+        public void unlinkToRcClientDeath() {
+            if ((mRcClientDeathHandler != null) && (mRcClientDeathHandler.mCb != null)) {
+                try {
+                    mRcClientDeathHandler.mCb.unlinkToDeath(mRcClientDeathHandler, 0);
+                    mRcClientDeathHandler = null;
+                } catch (java.util.NoSuchElementException e) {
+                    // not much we can do here
+                    Log.e(TAG, "Encountered " + e + " in unlinkToRcClientDeath()");
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        public void destroy() {
+            unlinkToRcClientDeath();
+            if (mToken != null) {
+                mToken.unlinkToDeath(this, 0);
+                mToken = null;
+            }
+        }
+
+        @Override
+        public void binderDied() {
+            mController.unregisterMediaButtonIntent(mMediaIntent);
+        }
+
+        @Override
+        protected void finalize() throws Throwable {
+            destroy(); // unlink exception handled inside method
+            super.finalize();
+        }
+    }
+
+    /**
+     *  The stack of remote control event receivers.
+     *  Code sections and methods that modify the remote control event receiver stack are
+     *  synchronized on mRCStack, but also BEFORE on mFocusLock as any change in either
+     *  stack, audio focus or RC, can lead to a change in the remote control display
+     */
+    private final Stack<RemoteControlStackEntry> mRCStack = new Stack<RemoteControlStackEntry>();
+
+    /**
+     * The component the telephony package can register so telephony calls have priority to
+     * handle media button events
+     */
+    private ComponentName mMediaReceiverForCalls = null;
+
+    /**
+     * Helper function:
+     * Display in the log the current entries in the remote control focus stack
+     */
+    private void dumpRCStack(PrintWriter pw) {
+        pw.println("\nRemote Control stack entries (last is top of stack):");
+        synchronized(mRCStack) {
+            Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
+            while(stackIterator.hasNext()) {
+                RemoteControlStackEntry rcse = stackIterator.next();
+                pw.println("  pi: " + rcse.mMediaIntent +
+                        " -- pack: " + rcse.mCallingPackageName +
+                        "  -- ercvr: " + rcse.mReceiverComponent +
+                        "  -- client: " + rcse.mRcClient +
+                        "  -- uid: " + rcse.mCallingUid +
+                        "  -- type: " + rcse.mPlaybackType +
+                        "  state: " + rcse.mPlaybackState);
+            }
+        }
+    }
+
+    /**
+     * Helper function:
+     * Display in the log the current entries in the remote control stack, focusing
+     * on RemoteControlClient data
+     */
+    private void dumpRCCStack(PrintWriter pw) {
+        pw.println("\nRemote Control Client stack entries (last is top of stack):");
+        synchronized(mRCStack) {
+            Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
+            while(stackIterator.hasNext()) {
+                RemoteControlStackEntry rcse = stackIterator.next();
+                pw.println("  uid: " + rcse.mCallingUid +
+                        "  -- id: " + rcse.mRccId +
+                        "  -- type: " + rcse.mPlaybackType +
+                        "  -- state: " + rcse.mPlaybackState +
+                        "  -- vol handling: " + rcse.mPlaybackVolumeHandling +
+                        "  -- vol: " + rcse.mPlaybackVolume +
+                        "  -- volMax: " + rcse.mPlaybackVolumeMax +
+                        "  -- volObs: " + rcse.mRemoteVolumeObs);
+            }
+            synchronized(mCurrentRcLock) {
+                pw.println("\nCurrent remote control generation ID = " + mCurrentRcClientGen);
+            }
+        }
+        synchronized (mMainRemote) {
+            pw.println("\nRemote Volume State:");
+            pw.println("  has remote: " + mHasRemotePlayback);
+            pw.println("  is remote active: " + mMainRemoteIsActive);
+            pw.println("  rccId: " + mMainRemote.mRccId);
+            pw.println("  volume handling: "
+                    + ((mMainRemote.mVolumeHandling == RemoteControlClient.PLAYBACK_VOLUME_FIXED) ?
+                            "PLAYBACK_VOLUME_FIXED(0)" : "PLAYBACK_VOLUME_VARIABLE(1)"));
+            pw.println("  volume: " + mMainRemote.mVolume);
+            pw.println("  volume steps: " + mMainRemote.mVolumeMax);
+        }
+    }
+
+    /**
+     * Helper function:
+     * Display in the log the current entries in the list of remote control displays
+     */
+    private void dumpRCDList(PrintWriter pw) {
+        pw.println("\nRemote Control Display list entries:");
+        synchronized(mRCStack) {
+            final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
+            while (displayIterator.hasNext()) {
+                final DisplayInfoForServer di = (DisplayInfoForServer) displayIterator.next();
+                pw.println("  IRCD: " + di.mRcDisplay +
+                        "  -- w:" + di.mArtworkExpectedWidth +
+                        "  -- h:" + di.mArtworkExpectedHeight+
+                        "  -- wantsPosSync:" + di.mWantsPositionSync);
+            }
+        }
+    }
+
+    /**
+     * Helper function:
+     * Remove any entry in the remote control stack that has the same package name as packageName
+     * Pre-condition: packageName != null
+     */
+    private void cleanupMediaButtonReceiverForPackage(String packageName, boolean removeAll) {
+        synchronized(mRCStack) {
+            if (mRCStack.empty()) {
+                return;
+            } else {
+                final PackageManager pm = mContext.getPackageManager();
+                RemoteControlStackEntry oldTop = mRCStack.peek();
+                Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
+                // iterate over the stack entries
+                // (using an iterator on the stack so we can safely remove an entry after having
+                //  evaluated it, traversal order doesn't matter here)
+                while(stackIterator.hasNext()) {
+                    RemoteControlStackEntry rcse = (RemoteControlStackEntry)stackIterator.next();
+                    if (removeAll && packageName.equals(rcse.mMediaIntent.getCreatorPackage())) {
+                        // a stack entry is from the package being removed, remove it from the stack
+                        stackIterator.remove();
+                        rcse.destroy();
+                    } else if (rcse.mReceiverComponent != null) {
+                        try {
+                            // Check to see if this receiver still exists.
+                            pm.getReceiverInfo(rcse.mReceiverComponent, 0);
+                        } catch (PackageManager.NameNotFoundException e) {
+                            // Not found -- remove it!
+                            stackIterator.remove();
+                            rcse.destroy();
+                        }
+                    }
+                }
+                if (mRCStack.empty()) {
+                    // no saved media button receiver
+                    mEventHandler.sendMessage(
+                            mEventHandler.obtainMessage(MSG_PERSIST_MEDIABUTTONRECEIVER, 0, 0,
+                                    null));
+                } else if (oldTop != mRCStack.peek()) {
+                    // the top of the stack has changed, save it in the system settings
+                    // by posting a message to persist it; only do this however if it has
+                    // a concrete component name (is not a transient registration)
+                    RemoteControlStackEntry rcse = mRCStack.peek();
+                    if (rcse.mReceiverComponent != null) {
+                        mEventHandler.sendMessage(
+                                mEventHandler.obtainMessage(MSG_PERSIST_MEDIABUTTONRECEIVER, 0, 0,
+                                        rcse.mReceiverComponent));
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Helper function:
+     * Restore remote control receiver from the system settings.
+     */
+    protected void restoreMediaButtonReceiver() {
+        String receiverName = Settings.System.getStringForUser(mContentResolver,
+                Settings.System.MEDIA_BUTTON_RECEIVER, UserHandle.USER_CURRENT);
+        if ((null != receiverName) && !receiverName.isEmpty()) {
+            ComponentName eventReceiver = ComponentName.unflattenFromString(receiverName);
+            if (eventReceiver == null) {
+                // an invalid name was persisted
+                return;
+            }
+            // construct a PendingIntent targeted to the restored component name
+            // for the media button and register it
+            Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
+            //     the associated intent will be handled by the component being registered
+            mediaButtonIntent.setComponent(eventReceiver);
+            PendingIntent pi = PendingIntent.getBroadcast(mContext,
+                    0/*requestCode, ignored*/, mediaButtonIntent, 0/*flags*/);
+            registerMediaButtonIntent(pi, eventReceiver, null);
+        }
+    }
+
+    /**
+     * Helper function:
+     * Set the new remote control receiver at the top of the RC focus stack.
+     * Called synchronized on mAudioFocusLock, then mRCStack
+     * precondition: mediaIntent != null
+     */
+    private void pushMediaButtonReceiver_syncAfRcs(PendingIntent mediaIntent, ComponentName target,
+            IBinder token) {
+        // already at top of stack?
+        if (!mRCStack.empty() && mRCStack.peek().mMediaIntent.equals(mediaIntent)) {
+            return;
+        }
+        if (mAppOps.noteOp(AppOpsManager.OP_TAKE_MEDIA_BUTTONS, Binder.getCallingUid(),
+                mediaIntent.getCreatorPackage()) != AppOpsManager.MODE_ALLOWED) {
+            return;
+        }
+        RemoteControlStackEntry rcse = null;
+        boolean wasInsideStack = false;
+        try {
+            for (int index = mRCStack.size()-1; index >= 0; index--) {
+                rcse = mRCStack.elementAt(index);
+                if(rcse.mMediaIntent.equals(mediaIntent)) {
+                    // ok to remove element while traversing the stack since we're leaving the loop
+                    mRCStack.removeElementAt(index);
+                    wasInsideStack = true;
+                    break;
+                }
+            }
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // not expected to happen, indicates improper concurrent modification
+            Log.e(TAG, "Wrong index accessing media button stack, lock error? ", e);
+        }
+        if (!wasInsideStack) {
+            rcse = new RemoteControlStackEntry(this, mediaIntent, target, token);
+        }
+        mRCStack.push(rcse); // rcse is never null
+
+        // post message to persist the default media button receiver
+        if (target != null) {
+            mEventHandler.sendMessage( mEventHandler.obtainMessage(
+                    MSG_PERSIST_MEDIABUTTONRECEIVER, 0, 0, target/*obj*/) );
+        }
+    }
+
+    /**
+     * Helper function:
+     * Remove the remote control receiver from the RC focus stack.
+     * Called synchronized on mAudioFocusLock, then mRCStack
+     * precondition: pi != null
+     */
+    private void removeMediaButtonReceiver_syncAfRcs(PendingIntent pi) {
+        try {
+            for (int index = mRCStack.size()-1; index >= 0; index--) {
+                final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
+                if (rcse.mMediaIntent.equals(pi)) {
+                    rcse.destroy();
+                    // ok to remove element while traversing the stack since we're leaving the loop
+                    mRCStack.removeElementAt(index);
+                    break;
+                }
+            }
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // not expected to happen, indicates improper concurrent modification
+            Log.e(TAG, "Wrong index accessing media button stack, lock error? ", e);
+        }
+    }
+
+    /**
+     * Helper function:
+     * Called synchronized on mRCStack
+     */
+    private boolean isCurrentRcController(PendingIntent pi) {
+        if (!mRCStack.empty() && mRCStack.peek().mMediaIntent.equals(pi)) {
+            return true;
+        }
+        return false;
+    }
+
+    private void onHandlePersistMediaButtonReceiver(ComponentName receiver) {
+        Settings.System.putStringForUser(mContentResolver,
+                                         Settings.System.MEDIA_BUTTON_RECEIVER,
+                                         receiver == null ? "" : receiver.flattenToString(),
+                                         UserHandle.USER_CURRENT);
+    }
+
+    //==========================================================================================
+    // Remote control display / client
+    //==========================================================================================
+    /**
+     * Update the remote control displays with the new "focused" client generation
+     */
+    private void setNewRcClientOnDisplays_syncRcsCurrc(int newClientGeneration,
+            PendingIntent newMediaIntent, boolean clearing) {
+        synchronized(mRCStack) {
+            if (mRcDisplays.size() > 0) {
+                final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
+                while (displayIterator.hasNext()) {
+                    final DisplayInfoForServer di = displayIterator.next();
+                    try {
+                        di.mRcDisplay.setCurrentClientId(
+                                newClientGeneration, newMediaIntent, clearing);
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "Dead display in setNewRcClientOnDisplays_syncRcsCurrc()",e);
+                        di.release();
+                        displayIterator.remove();
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Update the remote control clients with the new "focused" client generation
+     */
+    private void setNewRcClientGenerationOnClients_syncRcsCurrc(int newClientGeneration) {
+        // (using an iterator on the stack so we can safely remove an entry if needed,
+        //  traversal order doesn't matter here as we update all entries)
+        Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
+        while(stackIterator.hasNext()) {
+            RemoteControlStackEntry se = stackIterator.next();
+            if ((se != null) && (se.mRcClient != null)) {
+                try {
+                    se.mRcClient.setCurrentClientGenerationId(newClientGeneration);
+                } catch (RemoteException e) {
+                    Log.w(TAG, "Dead client in setNewRcClientGenerationOnClients_syncRcsCurrc()",e);
+                    stackIterator.remove();
+                    se.unlinkToRcClientDeath();
+                }
+            }
+        }
+    }
+
+    /**
+     * Update the displays and clients with the new "focused" client generation and name
+     * @param newClientGeneration the new generation value matching a client update
+     * @param newMediaIntent the media button event receiver associated with the client.
+     *    May be null, which implies there is no registered media button event receiver.
+     * @param clearing true if the new client generation value maps to a remote control update
+     *    where the display should be cleared.
+     */
+    private void setNewRcClient_syncRcsCurrc(int newClientGeneration,
+            PendingIntent newMediaIntent, boolean clearing) {
+        // send the new valid client generation ID to all displays
+        setNewRcClientOnDisplays_syncRcsCurrc(newClientGeneration, newMediaIntent, clearing);
+        // send the new valid client generation ID to all clients
+        setNewRcClientGenerationOnClients_syncRcsCurrc(newClientGeneration);
+    }
+
+    /**
+     * Called when processing MSG_RCDISPLAY_CLEAR event
+     */
+    private void onRcDisplayClear() {
+        if (DEBUG_RC) Log.i(TAG, "Clear remote control display");
+
+        synchronized(mRCStack) {
+            synchronized(mCurrentRcLock) {
+                mCurrentRcClientGen++;
+                // synchronously update the displays and clients with the new client generation
+                setNewRcClient_syncRcsCurrc(mCurrentRcClientGen,
+                        null /*newMediaIntent*/, true /*clearing*/);
+            }
+        }
+    }
+
+    /**
+     * Called when processing MSG_RCDISPLAY_UPDATE event
+     */
+    private void onRcDisplayUpdate(RemoteControlStackEntry rcse, int flags /* USED ?*/) {
+        synchronized(mRCStack) {
+            synchronized(mCurrentRcLock) {
+                if ((mCurrentRcClient != null) && (mCurrentRcClient.equals(rcse.mRcClient))) {
+                    if (DEBUG_RC) Log.i(TAG, "Display/update remote control ");
+
+                    mCurrentRcClientGen++;
+                    // synchronously update the displays and clients with
+                    //      the new client generation
+                    setNewRcClient_syncRcsCurrc(mCurrentRcClientGen,
+                            rcse.mMediaIntent /*newMediaIntent*/,
+                            false /*clearing*/);
+
+                    // tell the current client that it needs to send info
+                    try {
+                        mCurrentRcClient.onInformationRequested(mCurrentRcClientGen, flags);
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "Current valid remote client is dead: "+e);
+                        mCurrentRcClient = null;
+                    }
+                } else {
+                    // the remote control display owner has changed between the
+                    // the message to update the display was sent, and the time it
+                    // gets to be processed (now)
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Helper function:
+     * Called synchronized on mRCStack
+     */
+    private void clearRemoteControlDisplay_syncAfRcs() {
+        synchronized(mCurrentRcLock) {
+            mCurrentRcClient = null;
+        }
+        // will cause onRcDisplayClear() to be called in AudioService's handler thread
+        mEventHandler.sendMessage( mEventHandler.obtainMessage(MSG_RCDISPLAY_CLEAR) );
+    }
+
+    /**
+     * Helper function for code readability: only to be called from
+     *    checkUpdateRemoteControlDisplay_syncAfRcs() which checks the preconditions for
+     *    this method.
+     * Preconditions:
+     *    - called synchronized mAudioFocusLock then on mRCStack
+     *    - mRCStack.isEmpty() is false
+     */
+    private void updateRemoteControlDisplay_syncAfRcs(int infoChangedFlags) {
+        RemoteControlStackEntry rcse = mRCStack.peek();
+        int infoFlagsAboutToBeUsed = infoChangedFlags;
+        // this is where we enforce opt-in for information display on the remote controls
+        //   with the new AudioManager.registerRemoteControlClient() API
+        if (rcse.mRcClient == null) {
+            //Log.w(TAG, "Can't update remote control display with null remote control client");
+            clearRemoteControlDisplay_syncAfRcs();
+            return;
+        }
+        synchronized(mCurrentRcLock) {
+            if (!rcse.mRcClient.equals(mCurrentRcClient)) {
+                // new RC client, assume every type of information shall be queried
+                infoFlagsAboutToBeUsed = RC_INFO_ALL;
+            }
+            mCurrentRcClient = rcse.mRcClient;
+        }
+        // will cause onRcDisplayUpdate() to be called in AudioService's handler thread
+        mEventHandler.sendMessage( mEventHandler.obtainMessage(MSG_RCDISPLAY_UPDATE,
+                infoFlagsAboutToBeUsed /* arg1 */, 0, rcse /* obj, != null */) );
+    }
+
+    /**
+     * Helper function:
+     * Called synchronized on mAudioFocusLock, then mRCStack
+     * Check whether the remote control display should be updated, triggers the update if required
+     * @param infoChangedFlags the flags corresponding to the remote control client information
+     *     that has changed, if applicable (checking for the update conditions might trigger a
+     *     clear, rather than an update event).
+     */
+    private void checkUpdateRemoteControlDisplay_syncAfRcs(int infoChangedFlags) {
+        // determine whether the remote control display should be refreshed
+        // if either stack is empty, there is a mismatch, so clear the RC display
+        if (mRCStack.isEmpty() || mFocusStack.isEmpty()) {
+            clearRemoteControlDisplay_syncAfRcs();
+            return;
+        }
+
+        // determine which entry in the AudioFocus stack to consider, and compare against the
+        // top of the stack for the media button event receivers : simply using the top of the
+        // stack would make the entry disappear from the RemoteControlDisplay in conditions such as
+        // notifications playing during music playback.
+        // Crawl the AudioFocus stack from the top until an entry is found with the following
+        // characteristics:
+        // - focus gain on STREAM_MUSIC stream
+        // - non-transient focus gain on a stream other than music
+        FocusRequester af = null;
+        try {
+            for (int index = mFocusStack.size()-1; index >= 0; index--) {
+                FocusRequester fr = mFocusStack.elementAt(index);
+                if ((fr.getStreamType() == AudioManager.STREAM_MUSIC)
+                        || (fr.getGainRequest() == AudioManager.AUDIOFOCUS_GAIN)) {
+                    af = fr;
+                    break;
+                }
+            }
+        } catch (ArrayIndexOutOfBoundsException e) {
+            Log.e(TAG, "Wrong index accessing audio focus stack when updating RCD: " + e);
+            af = null;
+        }
+        if (af == null) {
+            clearRemoteControlDisplay_syncAfRcs();
+            return;
+        }
+
+        // if the audio focus and RC owners belong to different packages, there is a mismatch, clear
+        if (!af.hasSamePackage(mRCStack.peek().mCallingPackageName)) {
+            clearRemoteControlDisplay_syncAfRcs();
+            return;
+        }
+        // if the audio focus didn't originate from the same Uid as the one in which the remote
+        //   control information will be retrieved, clear
+        if (!af.hasSameUid(mRCStack.peek().mCallingUid)) {
+            clearRemoteControlDisplay_syncAfRcs();
+            return;
+        }
+
+        // refresh conditions were verified: update the remote controls
+        // ok to call: synchronized mAudioFocusLock then on mRCStack, mRCStack is not empty
+        updateRemoteControlDisplay_syncAfRcs(infoChangedFlags);
+    }
+
+    /**
+     * Helper function:
+     * Post a message to asynchronously move the media button event receiver associated with the
+     * given remote control client ID to the top of the remote control stack
+     * @param rccId
+     */
+    private void postPromoteRcc(int rccId) {
+        sendMsg(mEventHandler, MSG_PROMOTE_RCC, SENDMSG_REPLACE,
+                rccId /*arg1*/, 0, null, 0/*delay*/);
+    }
+
+    private void onPromoteRcc(int rccId) {
+        if (DEBUG_RC) { Log.d(TAG, "Promoting RCC " + rccId); }
+        synchronized(mAudioFocusLock) {
+            synchronized(mRCStack) {
+                // ignore if given RCC ID is already at top of remote control stack
+                if (!mRCStack.isEmpty() && (mRCStack.peek().mRccId == rccId)) {
+                    return;
+                }
+                int indexToPromote = -1;
+                try {
+                    for (int index = mRCStack.size()-1; index >= 0; index--) {
+                        final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
+                        if (rcse.mRccId == rccId) {
+                            indexToPromote = index;
+                            break;
+                        }
+                    }
+                    if (indexToPromote >= 0) {
+                        if (DEBUG_RC) { Log.d(TAG, "  moving RCC from index " + indexToPromote
+                                + " to " + (mRCStack.size()-1)); }
+                        final RemoteControlStackEntry rcse = mRCStack.remove(indexToPromote);
+                        mRCStack.push(rcse);
+                        // the RC stack changed, reevaluate the display
+                        checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
+                    }
+                } catch (ArrayIndexOutOfBoundsException e) {
+                    // not expected to happen, indicates improper concurrent modification
+                    Log.e(TAG, "Wrong index accessing RC stack, lock error? ", e);
+                }
+            }//synchronized(mRCStack)
+        }//synchronized(mAudioFocusLock)
+    }
+
+    /**
+     * see AudioManager.registerMediaButtonIntent(PendingIntent pi, ComponentName c)
+     * precondition: mediaIntent != null
+     */
+    protected void registerMediaButtonIntent(PendingIntent mediaIntent, ComponentName eventReceiver,
+            IBinder token) {
+        Log.i(TAG, "  Remote Control   registerMediaButtonIntent() for " + mediaIntent);
+
+        synchronized(mAudioFocusLock) {
+            synchronized(mRCStack) {
+                pushMediaButtonReceiver_syncAfRcs(mediaIntent, eventReceiver, token);
+                // new RC client, assume every type of information shall be queried
+                checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
+            }
+        }
+    }
+
+    /**
+     * see AudioManager.unregisterMediaButtonIntent(PendingIntent mediaIntent)
+     * precondition: mediaIntent != null, eventReceiver != null
+     */
+    protected void unregisterMediaButtonIntent(PendingIntent mediaIntent)
+    {
+        Log.i(TAG, "  Remote Control   unregisterMediaButtonIntent() for " + mediaIntent);
+
+        synchronized(mAudioFocusLock) {
+            synchronized(mRCStack) {
+                boolean topOfStackWillChange = isCurrentRcController(mediaIntent);
+                removeMediaButtonReceiver_syncAfRcs(mediaIntent);
+                if (topOfStackWillChange) {
+                    // current RC client will change, assume every type of info needs to be queried
+                    checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
+                }
+            }
+        }
+    }
+
+    /**
+     * see AudioManager.registerMediaButtonEventReceiverForCalls(ComponentName c)
+     * precondition: c != null
+     */
+    protected void registerMediaButtonEventReceiverForCalls(ComponentName c) {
+        if (mContext.checkCallingPermission("android.permission.MODIFY_PHONE_STATE")
+                != PackageManager.PERMISSION_GRANTED) {
+            Log.e(TAG, "Invalid permissions to register media button receiver for calls");
+            return;
+        }
+        synchronized(mRCStack) {
+            mMediaReceiverForCalls = c;
+        }
+    }
+
+    /**
+     * see AudioManager.unregisterMediaButtonEventReceiverForCalls()
+     */
+    protected void unregisterMediaButtonEventReceiverForCalls() {
+        if (mContext.checkCallingPermission("android.permission.MODIFY_PHONE_STATE")
+                != PackageManager.PERMISSION_GRANTED) {
+            Log.e(TAG, "Invalid permissions to unregister media button receiver for calls");
+            return;
+        }
+        synchronized(mRCStack) {
+            mMediaReceiverForCalls = null;
+        }
+    }
+
+    /**
+     * see AudioManager.registerRemoteControlClient(ComponentName eventReceiver, ...)
+     * @return the unique ID of the RemoteControlStackEntry associated with the RemoteControlClient
+     * Note: using this method with rcClient == null is a way to "disable" the IRemoteControlClient
+     *     without modifying the RC stack, but while still causing the display to refresh (will
+     *     become blank as a result of this)
+     */
+    protected int registerRemoteControlClient(PendingIntent mediaIntent,
+            IRemoteControlClient rcClient, String callingPackageName) {
+        if (DEBUG_RC) Log.i(TAG, "Register remote control client rcClient="+rcClient);
+        int rccId = RemoteControlClient.RCSE_ID_UNREGISTERED;
+        synchronized(mAudioFocusLock) {
+            synchronized(mRCStack) {
+                // store the new display information
+                try {
+                    for (int index = mRCStack.size()-1; index >= 0; index--) {
+                        final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
+                        if(rcse.mMediaIntent.equals(mediaIntent)) {
+                            // already had a remote control client?
+                            if (rcse.mRcClientDeathHandler != null) {
+                                // stop monitoring the old client's death
+                                rcse.unlinkToRcClientDeath();
+                            }
+                            // save the new remote control client
+                            rcse.mRcClient = rcClient;
+                            rcse.mCallingPackageName = callingPackageName;
+                            rcse.mCallingUid = Binder.getCallingUid();
+                            if (rcClient == null) {
+                                // here rcse.mRcClientDeathHandler is null;
+                                rcse.resetPlaybackInfo();
+                                break;
+                            }
+                            rccId = rcse.mRccId;
+
+                            // there is a new (non-null) client:
+                            // 1/ give the new client the displays (if any)
+                            if (mRcDisplays.size() > 0) {
+                                plugRemoteControlDisplaysIntoClient_syncRcStack(rcse.mRcClient);
+                            }
+                            // 2/ monitor the new client's death
+                            IBinder b = rcse.mRcClient.asBinder();
+                            RcClientDeathHandler rcdh =
+                                    new RcClientDeathHandler(b, rcse.mMediaIntent);
+                            try {
+                                b.linkToDeath(rcdh, 0);
+                            } catch (RemoteException e) {
+                                // remote control client is DOA, disqualify it
+                                Log.w(TAG, "registerRemoteControlClient() has a dead client " + b);
+                                rcse.mRcClient = null;
+                            }
+                            rcse.mRcClientDeathHandler = rcdh;
+                            break;
+                        }
+                    }//for
+                } catch (ArrayIndexOutOfBoundsException e) {
+                    // not expected to happen, indicates improper concurrent modification
+                    Log.e(TAG, "Wrong index accessing RC stack, lock error? ", e);
+                }
+
+                // if the eventReceiver is at the top of the stack
+                // then check for potential refresh of the remote controls
+                if (isCurrentRcController(mediaIntent)) {
+                    checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
+                }
+            }//synchronized(mRCStack)
+        }//synchronized(mAudioFocusLock)
+        return rccId;
+    }
+
+    /**
+     * see AudioManager.unregisterRemoteControlClient(PendingIntent pi, ...)
+     * rcClient is guaranteed non-null
+     */
+    protected void unregisterRemoteControlClient(PendingIntent mediaIntent,
+            IRemoteControlClient rcClient) {
+        if (DEBUG_RC) Log.i(TAG, "Unregister remote control client rcClient="+rcClient);
+        synchronized(mAudioFocusLock) {
+            synchronized(mRCStack) {
+                boolean topRccChange = false;
+                try {
+                    for (int index = mRCStack.size()-1; index >= 0; index--) {
+                        final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
+                        if ((rcse.mMediaIntent.equals(mediaIntent))
+                                && rcClient.equals(rcse.mRcClient)) {
+                            // we found the IRemoteControlClient to unregister
+                            // stop monitoring its death
+                            rcse.unlinkToRcClientDeath();
+                            // reset the client-related fields
+                            rcse.mRcClient = null;
+                            rcse.mCallingPackageName = null;
+                            topRccChange = (index == mRCStack.size()-1);
+                            // there can only be one matching RCC in the RC stack, we're done
+                            break;
+                        }
+                    }
+                } catch (ArrayIndexOutOfBoundsException e) {
+                    // not expected to happen, indicates improper concurrent modification
+                    Log.e(TAG, "Wrong index accessing RC stack, lock error? ", e);
+                }
+                if (topRccChange) {
+                    // no more RCC for the RCD, check for potential refresh of the remote controls
+                    checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
+                }
+            }
+        }
+    }
+
+
+    /**
+     * A class to encapsulate all the information about a remote control display.
+     * After instanciation, init() must always be called before the object is added in the list
+     * of displays.
+     * Before being removed from the list of displays, release() must always be called (otherwise
+     * it will leak death handlers).
+     */
+    private class DisplayInfoForServer implements IBinder.DeathRecipient {
+        /** may never be null */
+        private IRemoteControlDisplay mRcDisplay;
+        private IBinder mRcDisplayBinder;
+        private int mArtworkExpectedWidth = -1;
+        private int mArtworkExpectedHeight = -1;
+        private boolean mWantsPositionSync = false;
+
+        public DisplayInfoForServer(IRemoteControlDisplay rcd, int w, int h) {
+            if (DEBUG_RC) Log.i(TAG, "new DisplayInfoForServer for " + rcd + " w=" + w + " h=" + h);
+            mRcDisplay = rcd;
+            mRcDisplayBinder = rcd.asBinder();
+            mArtworkExpectedWidth = w;
+            mArtworkExpectedHeight = h;
+        }
+
+        public boolean init() {
+            try {
+                mRcDisplayBinder.linkToDeath(this, 0);
+            } catch (RemoteException e) {
+                // remote control display is DOA, disqualify it
+                Log.w(TAG, "registerRemoteControlDisplay() has a dead client " + mRcDisplayBinder);
+                return false;
+            }
+            return true;
+        }
+
+        public void release() {
+            try {
+                mRcDisplayBinder.unlinkToDeath(this, 0);
+            } catch (java.util.NoSuchElementException e) {
+                // not much we can do here, the display should have been unregistered anyway
+                Log.e(TAG, "Error in DisplaInfoForServer.relase()", e);
+            }
+        }
+
+        public void binderDied() {
+            synchronized(mRCStack) {
+                Log.w(TAG, "RemoteControl: display " + mRcDisplay + " died");
+                // remove the display from the list
+                final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
+                while (displayIterator.hasNext()) {
+                    final DisplayInfoForServer di = (DisplayInfoForServer) displayIterator.next();
+                    if (di.mRcDisplay == mRcDisplay) {
+                        if (DEBUG_RC) Log.w(TAG, " RCD removed from list");
+                        displayIterator.remove();
+                        return;
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * The remote control displays.
+     * Access synchronized on mRCStack
+     */
+    private ArrayList<DisplayInfoForServer> mRcDisplays = new ArrayList<DisplayInfoForServer>(1);
+
+    /**
+     * Plug each registered display into the specified client
+     * @param rcc, guaranteed non null
+     */
+    private void plugRemoteControlDisplaysIntoClient_syncRcStack(IRemoteControlClient rcc) {
+        final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
+        while (displayIterator.hasNext()) {
+            final DisplayInfoForServer di = (DisplayInfoForServer) displayIterator.next();
+            try {
+                rcc.plugRemoteControlDisplay(di.mRcDisplay, di.mArtworkExpectedWidth,
+                        di.mArtworkExpectedHeight);
+                if (di.mWantsPositionSync) {
+                    rcc.setWantsSyncForDisplay(di.mRcDisplay, true);
+                }
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error connecting RCD to RCC in RCC registration",e);
+            }
+        }
+    }
+
+    /**
+     * Is the remote control display interface already registered
+     * @param rcd
+     * @return true if the IRemoteControlDisplay is already in the list of displays
+     */
+    private boolean rcDisplayIsPluggedIn_syncRcStack(IRemoteControlDisplay rcd) {
+        final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
+        while (displayIterator.hasNext()) {
+            final DisplayInfoForServer di = (DisplayInfoForServer) displayIterator.next();
+            if (di.mRcDisplay.asBinder().equals(rcd.asBinder())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Register an IRemoteControlDisplay.
+     * Notify all IRemoteControlClient of the new display and cause the RemoteControlClient
+     * at the top of the stack to update the new display with its information.
+     * @see android.media.IAudioService#registerRemoteControlDisplay(android.media.IRemoteControlDisplay, int, int)
+     * @param rcd the IRemoteControlDisplay to register. No effect if null.
+     * @param w the maximum width of the expected bitmap. Negative or zero values indicate this
+     *   display doesn't need to receive artwork.
+     * @param h the maximum height of the expected bitmap. Negative or zero values indicate this
+     *   display doesn't need to receive artwork.
+     */
+    protected void registerRemoteControlDisplay(IRemoteControlDisplay rcd, int w, int h) {
+        if (DEBUG_RC) Log.d(TAG, ">>> registerRemoteControlDisplay("+rcd+")");
+        synchronized(mAudioFocusLock) {
+            synchronized(mRCStack) {
+                if ((rcd == null) || rcDisplayIsPluggedIn_syncRcStack(rcd)) {
+                    return;
+                }
+                DisplayInfoForServer di = new DisplayInfoForServer(rcd, w, h);
+                if (!di.init()) {
+                    if (DEBUG_RC) Log.e(TAG, " error registering RCD");
+                    return;
+                }
+                // add RCD to list of displays
+                mRcDisplays.add(di);
+
+                // let all the remote control clients know there is a new display (so the remote
+                //   control stack traversal order doesn't matter).
+                Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
+                while(stackIterator.hasNext()) {
+                    RemoteControlStackEntry rcse = stackIterator.next();
+                    if(rcse.mRcClient != null) {
+                        try {
+                            rcse.mRcClient.plugRemoteControlDisplay(rcd, w, h);
+                        } catch (RemoteException e) {
+                            Log.e(TAG, "Error connecting RCD to client: ", e);
+                        }
+                    }
+                }
+
+                // we have a new display, of which all the clients are now aware: have it be updated
+                checkUpdateRemoteControlDisplay_syncAfRcs(RC_INFO_ALL);
+            }
+        }
+    }
+
+    /**
+     * Unregister an IRemoteControlDisplay.
+     * No effect if the IRemoteControlDisplay hasn't been successfully registered.
+     * @see android.media.IAudioService#unregisterRemoteControlDisplay(android.media.IRemoteControlDisplay)
+     * @param rcd the IRemoteControlDisplay to unregister. No effect if null.
+     */
+    protected void unregisterRemoteControlDisplay(IRemoteControlDisplay rcd) {
+        if (DEBUG_RC) Log.d(TAG, "<<< unregisterRemoteControlDisplay("+rcd+")");
+        synchronized(mRCStack) {
+            if (rcd == null) {
+                return;
+            }
+
+            boolean displayWasPluggedIn = false;
+            final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
+            while (displayIterator.hasNext() && !displayWasPluggedIn) {
+                final DisplayInfoForServer di = (DisplayInfoForServer) displayIterator.next();
+                if (di.mRcDisplay.asBinder().equals(rcd.asBinder())) {
+                    displayWasPluggedIn = true;
+                    di.release();
+                    displayIterator.remove();
+                }
+            }
+
+            if (displayWasPluggedIn) {
+                // disconnect this remote control display from all the clients, so the remote
+                //   control stack traversal order doesn't matter
+                final Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
+                while(stackIterator.hasNext()) {
+                    final RemoteControlStackEntry rcse = stackIterator.next();
+                    if(rcse.mRcClient != null) {
+                        try {
+                            rcse.mRcClient.unplugRemoteControlDisplay(rcd);
+                        } catch (RemoteException e) {
+                            Log.e(TAG, "Error disconnecting remote control display to client: ", e);
+                        }
+                    }
+                }
+            } else {
+                if (DEBUG_RC) Log.w(TAG, "  trying to unregister unregistered RCD");
+            }
+        }
+    }
+
+    /**
+     * Update the size of the artwork used by an IRemoteControlDisplay.
+     * @see android.media.IAudioService#remoteControlDisplayUsesBitmapSize(android.media.IRemoteControlDisplay, int, int)
+     * @param rcd the IRemoteControlDisplay with the new artwork size requirement
+     * @param w the maximum width of the expected bitmap. Negative or zero values indicate this
+     *   display doesn't need to receive artwork.
+     * @param h the maximum height of the expected bitmap. Negative or zero values indicate this
+     *   display doesn't need to receive artwork.
+     */
+    protected void remoteControlDisplayUsesBitmapSize(IRemoteControlDisplay rcd, int w, int h) {
+        synchronized(mRCStack) {
+            final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
+            boolean artworkSizeUpdate = false;
+            while (displayIterator.hasNext() && !artworkSizeUpdate) {
+                final DisplayInfoForServer di = (DisplayInfoForServer) displayIterator.next();
+                if (di.mRcDisplay.asBinder().equals(rcd.asBinder())) {
+                    if ((di.mArtworkExpectedWidth != w) || (di.mArtworkExpectedHeight != h)) {
+                        di.mArtworkExpectedWidth = w;
+                        di.mArtworkExpectedHeight = h;
+                        artworkSizeUpdate = true;
+                    }
+                }
+            }
+            if (artworkSizeUpdate) {
+                // RCD is currently plugged in and its artwork size has changed, notify all RCCs,
+                // stack traversal order doesn't matter
+                final Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
+                while(stackIterator.hasNext()) {
+                    final RemoteControlStackEntry rcse = stackIterator.next();
+                    if(rcse.mRcClient != null) {
+                        try {
+                            rcse.mRcClient.setBitmapSizeForDisplay(rcd, w, h);
+                        } catch (RemoteException e) {
+                            Log.e(TAG, "Error setting bitmap size for RCD on RCC: ", e);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Controls whether a remote control display needs periodic checks of the RemoteControlClient
+     * playback position to verify that the estimated position has not drifted from the actual
+     * position. By default the check is not performed.
+     * The IRemoteControlDisplay must have been previously registered for this to have any effect.
+     * @param rcd the IRemoteControlDisplay for which the anti-drift mechanism will be enabled
+     *     or disabled. Not null.
+     * @param wantsSync if true, RemoteControlClient instances which expose their playback position
+     *     to the framework will regularly compare the estimated playback position with the actual
+     *     position, and will update the IRemoteControlDisplay implementation whenever a drift is
+     *     detected.
+     */
+    protected void remoteControlDisplayWantsPlaybackPositionSync(IRemoteControlDisplay rcd,
+            boolean wantsSync) {
+        synchronized(mRCStack) {
+            boolean rcdRegistered = false;
+            // store the information about this display
+            // (display stack traversal order doesn't matter).
+            final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
+            while (displayIterator.hasNext()) {
+                final DisplayInfoForServer di = (DisplayInfoForServer) displayIterator.next();
+                if (di.mRcDisplay.asBinder().equals(rcd.asBinder())) {
+                    di.mWantsPositionSync = wantsSync;
+                    rcdRegistered = true;
+                    break;
+                }
+            }
+            if (!rcdRegistered) {
+                return;
+            }
+            // notify all current RemoteControlClients
+            // (stack traversal order doesn't matter as we notify all RCCs)
+            final Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
+            while (stackIterator.hasNext()) {
+                final RemoteControlStackEntry rcse = stackIterator.next();
+                if (rcse.mRcClient != null) {
+                    try {
+                        rcse.mRcClient.setWantsSyncForDisplay(rcd, wantsSync);
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "Error setting position sync flag for RCD on RCC: ", e);
+                    }
+                }
+            }
+        }
+    }
+
+    protected void setRemoteControlClientPlaybackPosition(int generationId, long timeMs) {
+        // ignore position change requests if invalid generation ID
+        synchronized(mRCStack) {
+            synchronized(mCurrentRcLock) {
+                if (mCurrentRcClientGen != generationId) {
+                    return;
+                }
+            }
+        }
+        // discard any unprocessed seek request in the message queue, and replace with latest
+        sendMsg(mEventHandler, MSG_RCC_SEEK_REQUEST, SENDMSG_REPLACE, generationId /* arg1 */,
+                0 /* arg2 ignored*/, new Long(timeMs) /* obj */, 0 /* delay */);
+    }
+
+    private void onSetRemoteControlClientPlaybackPosition(int generationId, long timeMs) {
+        if(DEBUG_RC) Log.d(TAG, "onSetRemoteControlClientPlaybackPosition(genId=" + generationId +
+                ", timeMs=" + timeMs + ")");
+        synchronized(mRCStack) {
+            synchronized(mCurrentRcLock) {
+                if ((mCurrentRcClient != null) && (mCurrentRcClientGen == generationId)) {
+                    // tell the current client to seek to the requested location
+                    try {
+                        mCurrentRcClient.seekTo(generationId, timeMs);
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "Current valid remote client is dead: "+e);
+                        mCurrentRcClient = null;
+                    }
+                }
+            }
+        }
+    }
+
+    protected void updateRemoteControlClientMetadata(int genId, int key, long value) {
+        sendMsg(mEventHandler, MSG_RCC_UPDATE_METADATA_LONG, SENDMSG_QUEUE,
+                genId /* arg1 */, key /* arg2 */, Long.valueOf(value) /* obj */, 0 /* delay */);
+    }
+
+    private void onUpdateRemoteControlClientMetadataLong(int genId, int key, long value) {
+        if(DEBUG_RC) Log.d(TAG, "onUpdateRemoteControlClientMetadataLong(genId=" + genId +
+                ", what=" + key + ",val=" + value + ")");
+        synchronized(mRCStack) {
+            synchronized(mCurrentRcLock) {
+                if ((mCurrentRcClient != null) && (mCurrentRcClientGen == genId)) {
+                    try {
+                        switch (key) {
+                            case RemoteControlClient.MetadataEditor.LONG_KEY_RATING_BY_USER:
+                                mCurrentRcClient.updateMetadata(genId, key, value);
+                                break;
+                            default:
+                                Log.e(TAG, "unhandled metadata key " + key + " update for RCC "
+                                        + genId);
+                                break;
+                        }
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "Current valid remote client is dead", e);
+                        mCurrentRcClient = null;
+                    }
+                }
+            }
+        }
+    }
+
+    protected void setPlaybackInfoForRcc(int rccId, int what, int value) {
+        sendMsg(mEventHandler, MSG_RCC_NEW_PLAYBACK_INFO, SENDMSG_QUEUE,
+                rccId /* arg1 */, what /* arg2 */, Integer.valueOf(value) /* obj */, 0 /* delay */);
+    }
+
+    // handler for MSG_RCC_NEW_PLAYBACK_INFO
+    private void onNewPlaybackInfoForRcc(int rccId, int key, int value) {
+        if(DEBUG_RC) Log.d(TAG, "onNewPlaybackInfoForRcc(id=" + rccId +
+                ", what=" + key + ",val=" + value + ")");
+        synchronized(mRCStack) {
+            // iterating from top of stack as playback information changes are more likely
+            //   on entries at the top of the remote control stack
+            try {
+                for (int index = mRCStack.size()-1; index >= 0; index--) {
+                    final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
+                    if (rcse.mRccId == rccId) {
+                        switch (key) {
+                            case RemoteControlClient.PLAYBACKINFO_PLAYBACK_TYPE:
+                                rcse.mPlaybackType = value;
+                                postReevaluateRemote();
+                                break;
+                            case RemoteControlClient.PLAYBACKINFO_VOLUME:
+                                rcse.mPlaybackVolume = value;
+                                synchronized (mMainRemote) {
+                                    if (rccId == mMainRemote.mRccId) {
+                                        mMainRemote.mVolume = value;
+                                        mVolumeController.postHasNewRemotePlaybackInfo();
+                                    }
+                                }
+                                break;
+                            case RemoteControlClient.PLAYBACKINFO_VOLUME_MAX:
+                                rcse.mPlaybackVolumeMax = value;
+                                synchronized (mMainRemote) {
+                                    if (rccId == mMainRemote.mRccId) {
+                                        mMainRemote.mVolumeMax = value;
+                                        mVolumeController.postHasNewRemotePlaybackInfo();
+                                    }
+                                }
+                                break;
+                            case RemoteControlClient.PLAYBACKINFO_VOLUME_HANDLING:
+                                rcse.mPlaybackVolumeHandling = value;
+                                synchronized (mMainRemote) {
+                                    if (rccId == mMainRemote.mRccId) {
+                                        mMainRemote.mVolumeHandling = value;
+                                        mVolumeController.postHasNewRemotePlaybackInfo();
+                                    }
+                                }
+                                break;
+                            case RemoteControlClient.PLAYBACKINFO_USES_STREAM:
+                                rcse.mPlaybackStream = value;
+                                break;
+                            default:
+                                Log.e(TAG, "unhandled key " + key + " for RCC " + rccId);
+                                break;
+                        }
+                        return;
+                    }
+                }//for
+            } catch (ArrayIndexOutOfBoundsException e) {
+                // not expected to happen, indicates improper concurrent modification
+                Log.e(TAG, "Wrong index mRCStack on onNewPlaybackInfoForRcc, lock error? ", e);
+            }
+        }
+    }
+
+    protected void setPlaybackStateForRcc(int rccId, int state, long timeMs, float speed) {
+        sendMsg(mEventHandler, MSG_RCC_NEW_PLAYBACK_STATE, SENDMSG_QUEUE,
+                rccId /* arg1 */, state /* arg2 */,
+                new RccPlaybackState(state, timeMs, speed) /* obj */, 0 /* delay */);
+    }
+
+    private void onNewPlaybackStateForRcc(int rccId, int state, RccPlaybackState newState) {
+        if(DEBUG_RC) Log.d(TAG, "onNewPlaybackStateForRcc(id=" + rccId + ", state=" + state
+                + ", time=" + newState.mPositionMs + ", speed=" + newState.mSpeed + ")");
+        synchronized(mRCStack) {
+            // iterating from top of stack as playback information changes are more likely
+            //   on entries at the top of the remote control stack
+            try {
+                for (int index = mRCStack.size()-1; index >= 0; index--) {
+                    final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
+                    if (rcse.mRccId == rccId) {
+                        rcse.mPlaybackState = newState;
+                        synchronized (mMainRemote) {
+                            if (rccId == mMainRemote.mRccId) {
+                                mMainRemoteIsActive = isPlaystateActive(state);
+                                postReevaluateRemote();
+                            }
+                        }
+                        // an RCC moving to a "playing" state should become the media button
+                        //   event receiver so it can be controlled, without requiring the
+                        //   app to re-register its receiver
+                        if (isPlaystateActive(state)) {
+                            postPromoteRcc(rccId);
+                        }
+                    }
+                }//for
+            } catch (ArrayIndexOutOfBoundsException e) {
+                // not expected to happen, indicates improper concurrent modification
+                Log.e(TAG, "Wrong index on mRCStack in onNewPlaybackStateForRcc, lock error? ", e);
+            }
+        }
+    }
+
+    protected void registerRemoteVolumeObserverForRcc(int rccId, IRemoteVolumeObserver rvo) {
+        sendMsg(mEventHandler, MSG_RCC_NEW_VOLUME_OBS, SENDMSG_QUEUE,
+                rccId /* arg1 */, 0, rvo /* obj */, 0 /* delay */);
+    }
+
+    // handler for MSG_RCC_NEW_VOLUME_OBS
+    private void onRegisterVolumeObserverForRcc(int rccId, IRemoteVolumeObserver rvo) {
+        synchronized(mRCStack) {
+            // The stack traversal order doesn't matter because there is only one stack entry
+            //  with this RCC ID, but the matching ID is more likely at the top of the stack, so
+            //  start iterating from the top.
+            try {
+                for (int index = mRCStack.size()-1; index >= 0; index--) {
+                    final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
+                    if (rcse.mRccId == rccId) {
+                        rcse.mRemoteVolumeObs = rvo;
+                        break;
+                    }
+                }
+            } catch (ArrayIndexOutOfBoundsException e) {
+                // not expected to happen, indicates improper concurrent modification
+                Log.e(TAG, "Wrong index accessing media button stack, lock error? ", e);
+            }
+        }
+    }
+
+    /**
+     * Checks if a remote client is active on the supplied stream type. Update the remote stream
+     * volume state if found and playing
+     * @param streamType
+     * @return false if no remote playing is currently playing
+     */
+    protected boolean checkUpdateRemoteStateIfActive(int streamType) {
+        synchronized(mRCStack) {
+            // iterating from top of stack as active playback is more likely on entries at the top
+            try {
+                for (int index = mRCStack.size()-1; index >= 0; index--) {
+                    final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
+                    if ((rcse.mPlaybackType == RemoteControlClient.PLAYBACK_TYPE_REMOTE)
+                            && isPlaystateActive(rcse.mPlaybackState.mState)
+                            && (rcse.mPlaybackStream == streamType)) {
+                        if (DEBUG_RC) Log.d(TAG, "remote playback active on stream " + streamType
+                                + ", vol =" + rcse.mPlaybackVolume);
+                        synchronized (mMainRemote) {
+                            mMainRemote.mRccId = rcse.mRccId;
+                            mMainRemote.mVolume = rcse.mPlaybackVolume;
+                            mMainRemote.mVolumeMax = rcse.mPlaybackVolumeMax;
+                            mMainRemote.mVolumeHandling = rcse.mPlaybackVolumeHandling;
+                            mMainRemoteIsActive = true;
+                        }
+                        return true;
+                    }
+                }
+            } catch (ArrayIndexOutOfBoundsException e) {
+                // not expected to happen, indicates improper concurrent modification
+                Log.e(TAG, "Wrong index accessing RC stack, lock error? ", e);
+            }
+        }
+        synchronized (mMainRemote) {
+            mMainRemoteIsActive = false;
+        }
+        return false;
+    }
+
+    /**
+     * Returns true if the given playback state is considered "active", i.e. it describes a state
+     * where playback is happening, or about to
+     * @param playState the playback state to evaluate
+     * @return true if active, false otherwise (inactive or unknown)
+     */
+    private static boolean isPlaystateActive(int playState) {
+        switch (playState) {
+            case RemoteControlClient.PLAYSTATE_PLAYING:
+            case RemoteControlClient.PLAYSTATE_BUFFERING:
+            case RemoteControlClient.PLAYSTATE_FAST_FORWARDING:
+            case RemoteControlClient.PLAYSTATE_REWINDING:
+            case RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS:
+            case RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    protected void adjustRemoteVolume(int streamType, int direction, int flags) {
+        int rccId = RemoteControlClient.RCSE_ID_UNREGISTERED;
+        boolean volFixed = false;
+        synchronized (mMainRemote) {
+            if (!mMainRemoteIsActive) {
+                if (DEBUG_VOL) Log.w(TAG, "adjustRemoteVolume didn't find an active client");
+                return;
+            }
+            rccId = mMainRemote.mRccId;
+            volFixed = (mMainRemote.mVolumeHandling ==
+                    RemoteControlClient.PLAYBACK_VOLUME_FIXED);
+        }
+        // unlike "local" stream volumes, we can't compute the new volume based on the direction,
+        // we can only notify the remote that volume needs to be updated, and we'll get an async'
+        // update through setPlaybackInfoForRcc()
+        if (!volFixed) {
+            sendVolumeUpdateToRemote(rccId, direction);
+        }
+
+        // fire up the UI
+        mVolumeController.postRemoteVolumeChanged(streamType, flags);
+    }
+
+    private void sendVolumeUpdateToRemote(int rccId, int direction) {
+        if (DEBUG_VOL) { Log.d(TAG, "sendVolumeUpdateToRemote(rccId="+rccId+" , dir="+direction); }
+        if (direction == 0) {
+            // only handling discrete events
+            return;
+        }
+        IRemoteVolumeObserver rvo = null;
+        synchronized (mRCStack) {
+            // The stack traversal order doesn't matter because there is only one stack entry
+            //  with this RCC ID, but the matching ID is more likely at the top of the stack, so
+            //  start iterating from the top.
+            try {
+                for (int index = mRCStack.size()-1; index >= 0; index--) {
+                    final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
+                    //FIXME OPTIMIZE store this info in mMainRemote so we don't have to iterate?
+                    if (rcse.mRccId == rccId) {
+                        rvo = rcse.mRemoteVolumeObs;
+                        break;
+                    }
+                }
+            } catch (ArrayIndexOutOfBoundsException e) {
+                // not expected to happen, indicates improper concurrent modification
+                Log.e(TAG, "Wrong index accessing media button stack, lock error? ", e);
+            }
+        }
+        if (rvo != null) {
+            try {
+                rvo.dispatchRemoteVolumeUpdate(direction, -1);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error dispatching relative volume update", e);
+            }
+        }
+    }
+
+    protected int getRemoteStreamMaxVolume() {
+        synchronized (mMainRemote) {
+            if (mMainRemote.mRccId == RemoteControlClient.RCSE_ID_UNREGISTERED) {
+                return 0;
+            }
+            return mMainRemote.mVolumeMax;
+        }
+    }
+
+    protected int getRemoteStreamVolume() {
+        synchronized (mMainRemote) {
+            if (mMainRemote.mRccId == RemoteControlClient.RCSE_ID_UNREGISTERED) {
+                return 0;
+            }
+            return mMainRemote.mVolume;
+        }
+    }
+
+    protected void setRemoteStreamVolume(int vol) {
+        if (DEBUG_VOL) { Log.d(TAG, "setRemoteStreamVolume(vol="+vol+")"); }
+        int rccId = RemoteControlClient.RCSE_ID_UNREGISTERED;
+        synchronized (mMainRemote) {
+            if (mMainRemote.mRccId == RemoteControlClient.RCSE_ID_UNREGISTERED) {
+                return;
+            }
+            rccId = mMainRemote.mRccId;
+        }
+        IRemoteVolumeObserver rvo = null;
+        synchronized (mRCStack) {
+            // The stack traversal order doesn't matter because there is only one stack entry
+            //  with this RCC ID, but the matching ID is more likely at the top of the stack, so
+            //  start iterating from the top.
+            try {
+                for (int index = mRCStack.size()-1; index >= 0; index--) {
+                    final RemoteControlStackEntry rcse = mRCStack.elementAt(index);
+                    //FIXME OPTIMIZE store this info in mMainRemote so we don't have to iterate?
+                    if (rcse.mRccId == rccId) {
+                        rvo = rcse.mRemoteVolumeObs;
+                        break;
+                    }
+                }
+            } catch (ArrayIndexOutOfBoundsException e) {
+                // not expected to happen, indicates improper concurrent modification
+                Log.e(TAG, "Wrong index accessing media button stack, lock error? ", e);
+            }
+        }
+        if (rvo != null) {
+            try {
+                rvo.dispatchRemoteVolumeUpdate(0, vol);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error dispatching absolute volume update", e);
+            }
+        }
+    }
+
+    /**
+     * Call to make AudioService reevaluate whether it's in a mode where remote players should
+     * have their volume controlled. In this implementation this is only to reset whether
+     * VolumePanel should display remote volumes
+     */
+    private void postReevaluateRemote() {
+        sendMsg(mEventHandler, MSG_REEVALUATE_REMOTE, SENDMSG_QUEUE, 0, 0, null, 0);
+    }
+
+    private void onReevaluateRemote() {
+        if (DEBUG_VOL) { Log.w(TAG, "onReevaluateRemote()"); }
+        // is there a registered RemoteControlClient that is handling remote playback
+        boolean hasRemotePlayback = false;
+        synchronized (mRCStack) {
+            // iteration stops when PLAYBACK_TYPE_REMOTE is found, so remote control stack
+            //   traversal order doesn't matter
+            Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
+            while(stackIterator.hasNext()) {
+                RemoteControlStackEntry rcse = stackIterator.next();
+                if (rcse.mPlaybackType == RemoteControlClient.PLAYBACK_TYPE_REMOTE) {
+                    hasRemotePlayback = true;
+                    break;
+                }
+            }
+        }
+        synchronized (mMainRemote) {
+            if (mHasRemotePlayback != hasRemotePlayback) {
+                mHasRemotePlayback = hasRemotePlayback;
+                mVolumeController.postRemoteSliderVisibility(hasRemotePlayback);
+            }
+        }
+    }
+
+}
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index 3fbaf69..16ae43d 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -26,7 +26,7 @@
  *
  * The format of the media data is specified as string/value pairs.
  *
- * Keys common to all formats, <b>all keys not marked optional are mandatory</b>:
+ * Keys common to all audio/video formats, <b>all keys not marked optional are mandatory</b>:
  *
  * <table>
  * <tr><th>Name</th><th>Value Type</th><th>Description</th></tr>
@@ -44,7 +44,19 @@
  *         for encoders, readable in the output format of decoders</b></td></tr>
  * <tr><td>{@link #KEY_FRAME_RATE}</td><td>Integer or Float</td><td><b>encoder-only</b></td></tr>
  * <tr><td>{@link #KEY_I_FRAME_INTERVAL}</td><td>Integer</td><td><b>encoder-only</b></td></tr>
+ * <tr><td>{@link #KEY_MAX_WIDTH}</td><td>Integer</td><td><b>decoder-only</b>, optional, max-resolution width</td></tr>
+ * <tr><td>{@link #KEY_MAX_HEIGHT}</td><td>Integer</td><td><b>decoder-only</b>, optional, max-resolution height</td></tr>
+ * <tr><td>{@link #KEY_REPEAT_PREVIOUS_FRAME_AFTER}</td><td>Long</td><td><b>video encoder in surface-mode only</b></td></tr>
+ * <tr><td>{@link #KEY_PUSH_BLANK_BUFFERS_ON_STOP}</td><td>Integer(1)</td><td><b>video decoder rendering to a surface only</b></td></tr>
  * </table>
+ * Specify both {@link #KEY_MAX_WIDTH} and {@link #KEY_MAX_HEIGHT} to enable
+ * adaptive playback (seamless resolution change) for a video decoder that
+ * supports it ({@link MediaCodecInfo.CodecCapabilities#FEATURE_AdaptivePlayback}).
+ * The values are used as hints for the codec: they are the maximum expected
+ * resolution to prepare for.  Depending on codec support, preparing for larger
+ * maximum resolution may require more memory even if that resolution is never
+ * reached.  These fields have no effect for codecs that do not support adaptive
+ * playback.<br /><br />
  *
  * Audio formats have the following keys:
  * <table>
@@ -57,6 +69,11 @@
  * <tr><td>{@link #KEY_FLAC_COMPRESSION_LEVEL}</td><td>Integer</td><td><b>encoder-only</b>, optional, if content is FLAC audio, specifies the desired compression level.</td></tr>
  * </table>
  *
+ * Subtitle formats have the following keys:
+ * <table>
+ * <tr><td>{@link #KEY_MIME}</td><td>String</td><td>The type of the format.</td></tr>
+ * <tr><td>{@link #KEY_LANGUAGE}</td><td>String</td><td>The language of the content.</td></tr>
+ * </table>
  */
 public final class MediaFormat {
     private Map<String, Object> mMap;
@@ -68,6 +85,12 @@
     public static final String KEY_MIME = "mime";
 
     /**
+     * A key describing the language of the content.
+     * The associated value is a string.
+     */
+    public static final String KEY_LANGUAGE = "language";
+
+    /**
      * A key describing the sample rate of an audio format.
      * The associated value is an integer
      */
@@ -91,6 +114,20 @@
      */
     public static final String KEY_HEIGHT = "height";
 
+    /**
+     * A key describing the maximum expected width of the content in a video
+     * decoder format, in case there are resolution changes in the video content.
+     * The associated value is an integer
+     */
+    public static final String KEY_MAX_WIDTH = "max-width";
+
+    /**
+     * A key describing the maximum expected height of the content in a video
+     * decoder format, in case there are resolution changes in the video content.
+     * The associated value is an integer
+     */
+    public static final String KEY_MAX_HEIGHT = "max-height";
+
     /** A key describing the maximum size in bytes of a buffer of data
      * described by this MediaFormat.
      * The associated value is an integer
@@ -132,6 +169,24 @@
     public static final String KEY_SLICE_HEIGHT = "slice-height";
 
     /**
+     * Applies only when configuring a video encoder in "surface-input" mode.
+     * The associated value is a long and gives the time in microseconds
+     * after which the frame previously submitted to the encoder will be
+     * repeated (once) if no new frame became available since.
+     */
+    public static final String KEY_REPEAT_PREVIOUS_FRAME_AFTER
+        = "repeat-previous-frame-after";
+
+    /**
+     * If specified when configuring a video decoder rendering to a surface,
+     * causes the decoder to output "blank", i.e. black frames to the surface
+     * when stopped to clear out any previously displayed contents.
+     * The associated value is an integer of value 1.
+     */
+    public static final String KEY_PUSH_BLANK_BUFFERS_ON_STOP
+        = "push-blank-buffers-on-shutdown";
+
+    /**
      * A key describing the duration (in microseconds) of the content.
      * The associated value is a long.
      */
@@ -166,6 +221,28 @@
      */
     public static final String KEY_FLAC_COMPRESSION_LEVEL = "flac-compression-level";
 
+    /**
+     * A key for boolean AUTOSELECT field. Tracks with AUTOSELECT=true are
+     * considered when automatically selecting a track without specific user
+     * choice (as defined by HLS).
+     * @hide
+     */
+    public static final String KEY_AUTOSELECT = "autoselect";
+
+    /**
+     * A key for boolean DEFAULT field. The track with DEFAULT=true is selected
+     * in the absence of a specific user choice (as defined by HLS).
+     * @hide
+     */
+    public static final String KEY_DEFAULT = "default";
+
+    /**
+     * A key for boolean FORCED field for subtitle tracks. True if it is a
+     * forced subtitle track.
+     * @hide
+     */
+    public static final String KEY_FORCED = "forced";
+
     /* package private */ MediaFormat(Map<String, Object> map) {
         mMap = map;
     }
@@ -196,6 +273,20 @@
     }
 
     /**
+     * Returns the value of an integer key, or the default value if the
+     * key is missing or is for another type value.
+     * @hide
+     */
+    public final int getInteger(String name, int defaultValue) {
+        try {
+            return getInteger(name);
+        }
+        catch (NullPointerException  e) { /* no such field */ }
+        catch (ClassCastException e) { /* field of different type */ }
+        return defaultValue;
+    }
+
+    /**
      * Returns the value of a long key.
      */
     public final long getLong(String name) {
@@ -277,6 +368,23 @@
     }
 
     /**
+     * Creates a minimal subtitle format.
+     * @param mime The mime type of the content.
+     * @param language The language of the content.  Specify "und" if language
+     *        information is only included in the content (similarly, if there
+     *        are multiple language tracks in the content.)
+     */
+    public static final MediaFormat createSubtitleFormat(
+            String mime,
+            String language) {
+        MediaFormat format = new MediaFormat();
+        format.setString(KEY_MIME, mime);
+        format.setString(KEY_LANGUAGE, language);
+
+        return format;
+    }
+
+    /**
      * Creates a minimal video format.
      * @param mime The mime type of the content.
      * @param width The width of the content (in pixels)
diff --git a/media/java/android/media/MediaMuxer.java b/media/java/android/media/MediaMuxer.java
index 774964e..65a9308 100644
--- a/media/java/android/media/MediaMuxer.java
+++ b/media/java/android/media/MediaMuxer.java
@@ -92,6 +92,7 @@
             Object[] values);
     private static native void nativeSetOrientationHint(int nativeObject,
             int degrees);
+    private static native void nativeSetLocation(int nativeObject, int latitude, int longitude);
     private static native void nativeWriteSampleData(int nativeObject,
             int trackIndex, ByteBuffer byteBuf,
             int offset, int size, long presentationTimeUs, int flags);
@@ -165,6 +166,41 @@
     }
 
     /**
+     * Set and store the geodata (latitude and longitude) in the output file.
+     * This method should be called before {@link #start}. The geodata is stored
+     * in udta box if the output format is
+     * {@link OutputFormat#MUXER_OUTPUT_MPEG_4}, and is ignored for other output
+     * formats. The geodata is stored according to ISO-6709 standard.
+     *
+     * @param latitude Latitude in degrees. Its value must be in the range [-90,
+     * 90].
+     * @param longitude Longitude in degrees. Its value must be in the range
+     * [-180, 180].
+     * @throws IllegalArgumentException If the given latitude or longitude is out
+     * of range.
+     * @throws IllegalStateException If this method is called after {@link #start}.
+     */
+    public void setLocation(float latitude, float longitude) {
+        int latitudex10000  = (int) (latitude * 10000 + 0.5);
+        int longitudex10000 = (int) (longitude * 10000 + 0.5);
+
+        if (latitudex10000 > 900000 || latitudex10000 < -900000) {
+            String msg = "Latitude: " + latitude + " out of range.";
+            throw new IllegalArgumentException(msg);
+        }
+        if (longitudex10000 > 1800000 || longitudex10000 < -1800000) {
+            String msg = "Longitude: " + longitude + " out of range";
+            throw new IllegalArgumentException(msg);
+        }
+
+        if (mState == MUXER_STATE_INITIALIZED && mNativeObject != 0) {
+            nativeSetLocation(mNativeObject, latitudex10000, longitudex10000);
+        } else {
+            throw new IllegalStateException("Can't set location due to wrong state.");
+        }
+    }
+
+    /**
      * Starts the muxer.
      * <p>Make sure this is called after {@link #addTrack} and before
      * {@link #writeSampleData}.</p>
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index b729640..7acf8af 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -26,11 +26,13 @@
 import android.net.ProxyProperties;
 import android.net.Uri;
 import android.os.Handler;
+import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.Message;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.ParcelFileDescriptor;
+import android.os.Process;
 import android.os.PowerManager;
 import android.util.Log;
 import android.view.Surface;
@@ -38,14 +40,23 @@
 import android.graphics.Bitmap;
 import android.graphics.SurfaceTexture;
 import android.media.AudioManager;
+import android.media.MediaFormat;
+import android.media.MediaTimeProvider;
+import android.media.MediaTimeProvider.OnMediaTimeListener;
+import android.media.SubtitleController;
+import android.media.SubtitleData;
 
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.InputStream;
+import java.lang.Runnable;
 import java.net.InetSocketAddress;
 import java.util.Map;
+import java.util.Scanner;
 import java.util.Set;
+import java.util.Vector;
 import java.lang.ref.WeakReference;
 
 /**
@@ -515,7 +526,7 @@
  * thread by default has a Looper running).
  *
  */
-public class MediaPlayer
+public class MediaPlayer implements SubtitleController.Listener
 {
     /**
        Constant to retrieve only the new metadata since the last
@@ -588,6 +599,11 @@
             mEventHandler = null;
         }
 
+        mTimeProvider = new TimeProvider(this);
+        mOutOfBandSubtitleTracks = new Vector<SubtitleTrack>();
+        mOpenSubtitleSources = new Vector<InputStream>();
+        mInbandSubtitleTracks = new SubtitleTrack[0];
+
         /* Native setup requires a weak reference to our object.
          * It's easier to create it here than in C++.
          */
@@ -639,7 +655,6 @@
      *
      * @param reply Output parcel with the data returned by the
      * native player.
-     *
      * {@hide}
      */
     public void invoke(Parcel request, Parcel reply) {
@@ -1336,6 +1351,11 @@
         mOnInfoListener = null;
         mOnVideoSizeChangedListener = null;
         mOnTimedTextListener = null;
+        if (mTimeProvider != null) {
+            mTimeProvider.close();
+            mTimeProvider = null;
+        }
+        mOnSubtitleDataListener = null;
         _release();
     }
 
@@ -1347,10 +1367,32 @@
      * data source and calling prepare().
      */
     public void reset() {
+        mSelectedSubtitleTrackIndex = -1;
+        synchronized(mOpenSubtitleSources) {
+            for (final InputStream is: mOpenSubtitleSources) {
+                try {
+                    is.close();
+                } catch (IOException e) {
+                }
+            }
+            mOpenSubtitleSources.clear();
+        }
+        mOutOfBandSubtitleTracks.clear();
+        mInbandSubtitleTracks = new SubtitleTrack[0];
+        if (mSubtitleController != null) {
+            mSubtitleController.reset();
+        }
+        if (mTimeProvider != null) {
+            mTimeProvider.close();
+            mTimeProvider = null;
+        }
+
         stayAwake(false);
         _reset();
         // make sure none of the listeners get called anymore
-        mEventHandler.removeCallbacksAndMessages(null);
+        if (mEventHandler != null) {
+            mEventHandler.removeCallbacksAndMessages(null);
+        }
 
         disableProxyListener();
     }
@@ -1410,13 +1452,6 @@
     }
 
     /**
-     * Currently not implemented, returns null.
-     * @deprecated
-     * @hide
-     */
-    public native Bitmap getFrameAt(int msec) throws IllegalStateException;
-
-    /**
      * Sets the audio session ID.
      *
      * @param sessionId the audio session ID.
@@ -1458,100 +1493,6 @@
      */
     public native void attachAuxEffect(int effectId);
 
-    /* Do not change these values (starting with KEY_PARAMETER) without updating
-     * their counterparts in include/media/mediaplayer.h!
-     */
-
-    // There are currently no defined keys usable from Java with get*Parameter.
-    // But if any keys are defined, the order must be kept in sync with include/media/mediaplayer.h.
-    // private static final int KEY_PARAMETER_... = ...;
-
-    /**
-     * Sets the parameter indicated by key.
-     * @param key key indicates the parameter to be set.
-     * @param value value of the parameter to be set.
-     * @return true if the parameter is set successfully, false otherwise
-     * {@hide}
-     */
-    public native boolean setParameter(int key, Parcel value);
-
-    /**
-     * Sets the parameter indicated by key.
-     * @param key key indicates the parameter to be set.
-     * @param value value of the parameter to be set.
-     * @return true if the parameter is set successfully, false otherwise
-     * {@hide}
-     */
-    public boolean setParameter(int key, String value) {
-        Parcel p = Parcel.obtain();
-        p.writeString(value);
-        boolean ret = setParameter(key, p);
-        p.recycle();
-        return ret;
-    }
-
-    /**
-     * Sets the parameter indicated by key.
-     * @param key key indicates the parameter to be set.
-     * @param value value of the parameter to be set.
-     * @return true if the parameter is set successfully, false otherwise
-     * {@hide}
-     */
-    public boolean setParameter(int key, int value) {
-        Parcel p = Parcel.obtain();
-        p.writeInt(value);
-        boolean ret = setParameter(key, p);
-        p.recycle();
-        return ret;
-    }
-
-    /*
-     * Gets the value of the parameter indicated by key.
-     * @param key key indicates the parameter to get.
-     * @param reply value of the parameter to get.
-     */
-    private native void getParameter(int key, Parcel reply);
-
-    /**
-     * Gets the value of the parameter indicated by key.
-     * The caller is responsible for recycling the returned parcel.
-     * @param key key indicates the parameter to get.
-     * @return value of the parameter.
-     * {@hide}
-     */
-    public Parcel getParcelParameter(int key) {
-        Parcel p = Parcel.obtain();
-        getParameter(key, p);
-        return p;
-    }
-
-    /**
-     * Gets the value of the parameter indicated by key.
-     * @param key key indicates the parameter to get.
-     * @return value of the parameter.
-     * {@hide}
-     */
-    public String getStringParameter(int key) {
-        Parcel p = Parcel.obtain();
-        getParameter(key, p);
-        String ret = p.readString();
-        p.recycle();
-        return ret;
-    }
-
-    /**
-     * Gets the value of the parameter indicated by key.
-     * @param key key indicates the parameter to get.
-     * @return value of the parameter.
-     * {@hide}
-     */
-    public int getIntParameter(int key) {
-        Parcel p = Parcel.obtain();
-        getParameter(key, p);
-        int ret = p.readInt();
-        p.recycle();
-        return ret;
-    }
 
     /**
      * Sets the send level of the player to the attached auxiliary effect
@@ -1628,20 +1569,56 @@
          * ISO-639-2 language code, "und", is returned.
          */
         public String getLanguage() {
-            return mLanguage;
+            String language = mFormat.getString(MediaFormat.KEY_LANGUAGE);
+            return language == null ? "und" : language;
+        }
+
+        /**
+         * Gets the {@link MediaFormat} of the track.  If the format is
+         * unknown or could not be determined, null is returned.
+         */
+        public MediaFormat getFormat() {
+            if (mTrackType == MEDIA_TRACK_TYPE_TIMEDTEXT
+                    || mTrackType == MEDIA_TRACK_TYPE_SUBTITLE) {
+                return mFormat;
+            }
+            return null;
         }
 
         public static final int MEDIA_TRACK_TYPE_UNKNOWN = 0;
         public static final int MEDIA_TRACK_TYPE_VIDEO = 1;
         public static final int MEDIA_TRACK_TYPE_AUDIO = 2;
         public static final int MEDIA_TRACK_TYPE_TIMEDTEXT = 3;
+        /** @hide */
+        public static final int MEDIA_TRACK_TYPE_SUBTITLE = 4;
 
         final int mTrackType;
-        final String mLanguage;
+        final MediaFormat mFormat;
 
         TrackInfo(Parcel in) {
             mTrackType = in.readInt();
-            mLanguage = in.readString();
+            // TODO: parcel in the full MediaFormat
+            String language = in.readString();
+
+            if (mTrackType == MEDIA_TRACK_TYPE_TIMEDTEXT) {
+                mFormat = MediaFormat.createSubtitleFormat(
+                    MEDIA_MIMETYPE_TEXT_SUBRIP, language);
+            } else if (mTrackType == MEDIA_TRACK_TYPE_SUBTITLE) {
+                mFormat = MediaFormat.createSubtitleFormat(
+                    MEDIA_MIMETYPE_TEXT_VTT, language);
+                mFormat.setInteger(MediaFormat.KEY_AUTOSELECT, in.readInt());
+                mFormat.setInteger(MediaFormat.KEY_DEFAULT, in.readInt());
+                mFormat.setInteger(MediaFormat.KEY_FORCED, in.readInt());
+            } else {
+                mFormat = new MediaFormat();
+                mFormat.setString(MediaFormat.KEY_LANGUAGE, language);
+            }
+        }
+
+        /** @hide */
+        TrackInfo(int type, MediaFormat format) {
+            mTrackType = type;
+            mFormat = format;
         }
 
         /**
@@ -1658,7 +1635,13 @@
         @Override
         public void writeToParcel(Parcel dest, int flags) {
             dest.writeInt(mTrackType);
-            dest.writeString(mLanguage);
+            dest.writeString(getLanguage());
+
+            if (mTrackType == MEDIA_TRACK_TYPE_SUBTITLE) {
+                dest.writeInt(mFormat.getInteger(MediaFormat.KEY_AUTOSELECT));
+                dest.writeInt(mFormat.getInteger(MediaFormat.KEY_DEFAULT));
+                dest.writeInt(mFormat.getInteger(MediaFormat.KEY_FORCED));
+            }
         }
 
         /**
@@ -1688,6 +1671,19 @@
      * @throws IllegalStateException if it is called in an invalid state.
      */
     public TrackInfo[] getTrackInfo() throws IllegalStateException {
+        TrackInfo trackInfo[] = getInbandTrackInfo();
+        // add out-of-band tracks
+        TrackInfo allTrackInfo[] = new TrackInfo[trackInfo.length + mOutOfBandSubtitleTracks.size()];
+        System.arraycopy(trackInfo, 0, allTrackInfo, 0, trackInfo.length);
+        int i = trackInfo.length;
+        for (SubtitleTrack track: mOutOfBandSubtitleTracks) {
+            allTrackInfo[i] = new TrackInfo(TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE, track.getFormat());
+            ++i;
+        }
+        return allTrackInfo;
+    }
+
+    private TrackInfo[] getInbandTrackInfo() throws IllegalStateException {
         Parcel request = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         try {
@@ -1710,6 +1706,12 @@
      */
     public static final String MEDIA_MIMETYPE_TEXT_SUBRIP = "application/x-subrip";
 
+    /**
+     * MIME type for WebVTT subtitle data.
+     * @hide
+     */
+    public static final String MEDIA_MIMETYPE_TEXT_VTT = "text/vtt";
+
     /*
      * A helper function to check if the mime type is supported by media framework.
      */
@@ -1720,6 +1722,140 @@
         return false;
     }
 
+    private SubtitleController mSubtitleController;
+
+    /** @hide */
+    public void setSubtitleAnchor(
+            SubtitleController controller,
+            SubtitleController.Anchor anchor) {
+        // TODO: create SubtitleController in MediaPlayer
+        mSubtitleController = controller;
+        mSubtitleController.setAnchor(anchor);
+    }
+
+    private SubtitleTrack[] mInbandSubtitleTracks;
+    private int mSelectedSubtitleTrackIndex = -1;
+    private Vector<SubtitleTrack> mOutOfBandSubtitleTracks;
+    private Vector<InputStream> mOpenSubtitleSources;
+
+    private OnSubtitleDataListener mSubtitleDataListener = new OnSubtitleDataListener() {
+        @Override
+        public void onSubtitleData(MediaPlayer mp, SubtitleData data) {
+            int index = data.getTrackIndex();
+            if (index >= mInbandSubtitleTracks.length) {
+                return;
+            }
+            SubtitleTrack track = mInbandSubtitleTracks[index];
+            if (track != null) {
+                try {
+                    long runID = data.getStartTimeUs() + 1;
+                    // TODO: move conversion into track
+                    track.onData(new String(data.getData(), "UTF-8"), true /* eos */, runID);
+                    track.setRunDiscardTimeMs(
+                            runID,
+                            (data.getStartTimeUs() + data.getDurationUs()) / 1000);
+                } catch (java.io.UnsupportedEncodingException e) {
+                    Log.w(TAG, "subtitle data for track " + index + " is not UTF-8 encoded: " + e);
+                }
+            }
+        }
+    };
+
+    /** @hide */
+    @Override
+    public void onSubtitleTrackSelected(SubtitleTrack track) {
+        if (mSelectedSubtitleTrackIndex >= 0) {
+            deselectTrack(mSelectedSubtitleTrackIndex);
+        }
+        mSelectedSubtitleTrackIndex = -1;
+        setOnSubtitleDataListener(null);
+        for (int i = 0; i < mInbandSubtitleTracks.length; i++) {
+            if (mInbandSubtitleTracks[i] == track) {
+                Log.v(TAG, "Selecting subtitle track " + i);
+                selectTrack(i);
+                mSelectedSubtitleTrackIndex = i;
+                setOnSubtitleDataListener(mSubtitleDataListener);
+                break;
+            }
+        }
+        // no need to select out-of-band tracks
+    }
+
+    /** @hide */
+    public void addSubtitleSource(InputStream is, MediaFormat format)
+            throws IllegalStateException
+    {
+        final InputStream fIs = is;
+        final MediaFormat fFormat = format;
+
+        // Ensure all input streams are closed.  It is also a handy
+        // way to implement timeouts in the future.
+        synchronized(mOpenSubtitleSources) {
+            mOpenSubtitleSources.add(is);
+        }
+
+        // process each subtitle in its own thread
+        final HandlerThread thread = new HandlerThread("SubtitleReadThread",
+              Process.THREAD_PRIORITY_BACKGROUND + Process.THREAD_PRIORITY_MORE_FAVORABLE);
+        thread.start();
+        Handler handler = new Handler(thread.getLooper());
+        handler.post(new Runnable() {
+            private int addTrack() {
+                if (fIs == null || mSubtitleController == null) {
+                    return MEDIA_INFO_UNSUPPORTED_SUBTITLE;
+                }
+
+                SubtitleTrack track = mSubtitleController.addTrack(fFormat);
+                if (track == null) {
+                    return MEDIA_INFO_UNSUPPORTED_SUBTITLE;
+                }
+
+                // TODO: do the conversion in the subtitle track
+                Scanner scanner = new Scanner(fIs, "UTF-8");
+                String contents = scanner.useDelimiter("\\A").next();
+                synchronized(mOpenSubtitleSources) {
+                    mOpenSubtitleSources.remove(fIs);
+                }
+                scanner.close();
+                mOutOfBandSubtitleTracks.add(track);
+                track.onData(contents, true /* eos */, ~0 /* runID: keep forever */);
+                return MEDIA_INFO_EXTERNAL_METADATA_UPDATE;
+            }
+
+            public void run() {
+                int res = addTrack();
+                if (mEventHandler != null) {
+                    Message m = mEventHandler.obtainMessage(MEDIA_INFO, res, 0, null);
+                    mEventHandler.sendMessage(m);
+                }
+                thread.getLooper().quitSafely();
+            }
+        });
+    }
+
+    private void scanInternalSubtitleTracks() {
+        if (mSubtitleController == null) {
+            Log.e(TAG, "Should have subtitle controller already set");
+            return;
+        }
+
+        TrackInfo[] tracks = getInbandTrackInfo();
+        SubtitleTrack[] inbandTracks = new SubtitleTrack[tracks.length];
+        for (int i=0; i < tracks.length; i++) {
+            if (tracks[i].getTrackType() == TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) {
+                if (i < mInbandSubtitleTracks.length) {
+                    inbandTracks[i] = mInbandSubtitleTracks[i];
+                } else {
+                    SubtitleTrack track = mSubtitleController.addTrack(
+                            tracks[i].getFormat());
+                    inbandTracks[i] = track;
+                }
+            }
+        }
+        mInbandSubtitleTracks = inbandTracks;
+        mSubtitleController.selectDefaultTrack();
+    }
+
     /* TODO: Limit the total number of external timed text source to a reasonable number.
      */
     /**
@@ -1910,6 +2046,13 @@
 
     private void selectOrDeselectTrack(int index, boolean select)
             throws IllegalStateException {
+        // ignore out-of-band tracks
+        TrackInfo[] trackInfo = getInbandTrackInfo();
+        if (index >= trackInfo.length &&
+                index < trackInfo.length + mOutOfBandSubtitleTracks.size()) {
+            return;
+        }
+
         Parcel request = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         try {
@@ -1990,9 +2133,23 @@
     private static final int MEDIA_BUFFERING_UPDATE = 3;
     private static final int MEDIA_SEEK_COMPLETE = 4;
     private static final int MEDIA_SET_VIDEO_SIZE = 5;
+    private static final int MEDIA_STARTED = 6;
+    private static final int MEDIA_PAUSED = 7;
+    private static final int MEDIA_STOPPED = 8;
     private static final int MEDIA_TIMED_TEXT = 99;
     private static final int MEDIA_ERROR = 100;
     private static final int MEDIA_INFO = 200;
+    private static final int MEDIA_SUBTITLE_DATA = 201;
+
+    private TimeProvider mTimeProvider;
+
+    /** @hide */
+    public MediaTimeProvider getMediaTimeProvider() {
+        if (mTimeProvider == null) {
+            mTimeProvider = new TimeProvider(this);
+        }
+        return mTimeProvider;
+    }
 
     private class EventHandler extends Handler
     {
@@ -2011,6 +2168,7 @@
             }
             switch(msg.what) {
             case MEDIA_PREPARED:
+                scanInternalSubtitleTracks();
                 if (mOnPreparedListener != null)
                     mOnPreparedListener.onPrepared(mMediaPlayer);
                 return;
@@ -2021,14 +2179,31 @@
                 stayAwake(false);
                 return;
 
+            case MEDIA_STOPPED:
+                if (mTimeProvider != null) {
+                    mTimeProvider.onStopped();
+                }
+                break;
+
+            case MEDIA_STARTED:
+            case MEDIA_PAUSED:
+                if (mTimeProvider != null) {
+                    mTimeProvider.onPaused(msg.what == MEDIA_PAUSED);
+                }
+                break;
+
             case MEDIA_BUFFERING_UPDATE:
                 if (mOnBufferingUpdateListener != null)
                     mOnBufferingUpdateListener.onBufferingUpdate(mMediaPlayer, msg.arg1);
                 return;
 
             case MEDIA_SEEK_COMPLETE:
-              if (mOnSeekCompleteListener != null)
+              if (mOnSeekCompleteListener != null) {
                   mOnSeekCompleteListener.onSeekComplete(mMediaPlayer);
+              }
+              if (mTimeProvider != null) {
+                  mTimeProvider.onSeekComplete(mMediaPlayer);
+              }
               return;
 
             case MEDIA_SET_VIDEO_SIZE:
@@ -2049,9 +2224,21 @@
                 return;
 
             case MEDIA_INFO:
-                if (msg.arg1 != MEDIA_INFO_VIDEO_TRACK_LAGGING) {
+                switch (msg.arg1) {
+                case MEDIA_INFO_VIDEO_TRACK_LAGGING:
                     Log.i(TAG, "Info (" + msg.arg1 + "," + msg.arg2 + ")");
+                    break;
+                case MEDIA_INFO_METADATA_UPDATE:
+                    scanInternalSubtitleTracks();
+                    // fall through
+
+                case MEDIA_INFO_EXTERNAL_METADATA_UPDATE:
+                    msg.arg1 = MEDIA_INFO_METADATA_UPDATE;
+                    // update default track selection
+                    mSubtitleController.selectDefaultTrack();
+                    break;
                 }
+
                 if (mOnInfoListener != null) {
                     mOnInfoListener.onInfo(mMediaPlayer, msg.arg1, msg.arg2);
                 }
@@ -2072,6 +2259,18 @@
                 }
                 return;
 
+            case MEDIA_SUBTITLE_DATA:
+                if (mOnSubtitleDataListener == null) {
+                    return;
+                }
+                if (msg.obj instanceof Parcel) {
+                    Parcel parcel = (Parcel) msg.obj;
+                    SubtitleData data = new SubtitleData(parcel);
+                    parcel.recycle();
+                    mOnSubtitleDataListener.onSubtitleData(mMediaPlayer, data);
+                }
+                return;
+
             case MEDIA_NOP: // interface test message - ignore
                 break;
 
@@ -2283,6 +2482,30 @@
 
     private OnTimedTextListener mOnTimedTextListener;
 
+    /**
+     * Interface definition of a callback to be invoked when a
+     * track has data available.
+     *
+     * @hide
+     */
+    public interface OnSubtitleDataListener
+    {
+        public void onSubtitleData(MediaPlayer mp, SubtitleData data);
+    }
+
+    /**
+     * Register a callback to be invoked when a track has data available.
+     *
+     * @param listener the callback that will be run
+     *
+     * @hide
+     */
+    public void setOnSubtitleDataListener(OnSubtitleDataListener listener)
+    {
+        mOnSubtitleDataListener = listener;
+    }
+
+    private OnSubtitleDataListener mOnSubtitleDataListener;
 
     /* Do not change these values without updating their counterparts
      * in include/media/mediaplayer.h!
@@ -2414,6 +2637,12 @@
      */
     public static final int MEDIA_INFO_METADATA_UPDATE = 802;
 
+    /** A new set of external-only metadata is available.  Used by
+     *  JAVA framework to avoid triggering track scanning.
+     * @hide
+     */
+    public static final int MEDIA_INFO_EXTERNAL_METADATA_UPDATE = 803;
+
     /** Failed to handle timed text track properly.
      * @see android.media.MediaPlayer.OnInfoListener
      *
@@ -2421,6 +2650,16 @@
      */
     public static final int MEDIA_INFO_TIMED_TEXT_ERROR = 900;
 
+    /** Subtitle track was not supported by the media framework.
+     * @see android.media.MediaPlayer.OnInfoListener
+     */
+    public static final int MEDIA_INFO_UNSUPPORTED_SUBTITLE = 901;
+
+    /** Reading the subtitle track takes too long.
+     * @see android.media.MediaPlayer.OnInfoListener
+     */
+    public static final int MEDIA_INFO_SUBTITLE_TIMED_OUT = 902;
+
     /**
      * Interface definition of a callback to be invoked to communicate some
      * info and/or warning about the media or its playback.
@@ -2441,6 +2680,8 @@
          * <li>{@link #MEDIA_INFO_BAD_INTERLEAVING}
          * <li>{@link #MEDIA_INFO_NOT_SEEKABLE}
          * <li>{@link #MEDIA_INFO_METADATA_UPDATE}
+         * <li>{@link #MEDIA_INFO_UNSUPPORTED_SUBTITLE}
+         * <li>{@link #MEDIA_INFO_SUBTITLE_TIMED_OUT}
          * </ul>
          * @param extra an extra code, specific to the info. Typically
          * implementation dependent.
@@ -2523,4 +2764,373 @@
     }
 
     private native void updateProxyConfig(ProxyProperties props);
+
+    /** @hide */
+    static class TimeProvider implements MediaPlayer.OnSeekCompleteListener,
+            MediaTimeProvider {
+        private static final String TAG = "MTP";
+        private static final long MAX_NS_WITHOUT_POSITION_CHECK = 5000000000L;
+        private static final long MAX_EARLY_CALLBACK_US = 1000;
+        private static final long TIME_ADJUSTMENT_RATE = 2;  /* meaning 1/2 */
+        private long mLastTimeUs = 0;
+        private MediaPlayer mPlayer;
+        private boolean mPaused = true;
+        private boolean mStopped = true;
+        private long mLastReportedTime;
+        private long mTimeAdjustment;
+        // since we are expecting only a handful listeners per stream, there is
+        // no need for log(N) search performance
+        private MediaTimeProvider.OnMediaTimeListener mListeners[];
+        private long mTimes[];
+        private long mLastNanoTime;
+        private Handler mEventHandler;
+        private boolean mRefresh = false;
+        private boolean mPausing = false;
+        private static final int NOTIFY = 1;
+        private static final int NOTIFY_TIME = 0;
+        private static final int REFRESH_AND_NOTIFY_TIME = 1;
+        private static final int NOTIFY_STOP = 2;
+        private static final int NOTIFY_SEEK = 3;
+        private HandlerThread mHandlerThread;
+
+        /** @hide */
+        public boolean DEBUG = false;
+
+        public TimeProvider(MediaPlayer mp) {
+            mPlayer = mp;
+            try {
+                getCurrentTimeUs(true, false);
+            } catch (IllegalStateException e) {
+                // we assume starting position
+                mRefresh = true;
+            }
+
+            Looper looper;
+            if ((looper = Looper.myLooper()) == null &&
+                (looper = Looper.getMainLooper()) == null) {
+                // Create our own looper here in case MP was created without one
+                mHandlerThread = new HandlerThread("MediaPlayerMTPEventThread",
+                      Process.THREAD_PRIORITY_FOREGROUND);
+                mHandlerThread.start();
+                looper = mHandlerThread.getLooper();
+            }
+            mEventHandler = new EventHandler(looper);
+
+            mListeners = new MediaTimeProvider.OnMediaTimeListener[0];
+            mTimes = new long[0];
+            mLastTimeUs = 0;
+            mTimeAdjustment = 0;
+        }
+
+        private void scheduleNotification(int type, long delayUs) {
+            if (DEBUG) Log.v(TAG, "scheduleNotification " + type + " in " + delayUs);
+            mEventHandler.removeMessages(NOTIFY);
+            Message msg = mEventHandler.obtainMessage(NOTIFY, type, 0);
+            mEventHandler.sendMessageDelayed(msg, (int) (delayUs / 1000));
+        }
+
+        /** @hide */
+        public void close() {
+            mEventHandler.removeMessages(NOTIFY);
+            if (mHandlerThread != null) {
+                mHandlerThread.quitSafely();
+                mHandlerThread = null;
+            }
+        }
+
+        /** @hide */
+        protected void finalize() {
+            if (mHandlerThread != null) {
+                mHandlerThread.quitSafely();
+            }
+        }
+
+        /** @hide */
+        public void onPaused(boolean paused) {
+            synchronized(this) {
+                if (DEBUG) Log.d(TAG, "onPaused: " + paused);
+                if (mStopped) { // handle as seek if we were stopped
+                    mStopped = false;
+                    scheduleNotification(NOTIFY_SEEK, 0 /* delay */);
+                } else {
+                    mPausing = paused;  // special handling if player disappeared
+                    scheduleNotification(REFRESH_AND_NOTIFY_TIME, 0 /* delay */);
+                }
+            }
+        }
+
+        /** @hide */
+        public void onStopped() {
+            synchronized(this) {
+                if (DEBUG) Log.d(TAG, "onStopped");
+                mPaused = true;
+                mStopped = true;
+                scheduleNotification(NOTIFY_STOP, 0 /* delay */);
+            }
+        }
+
+        /** @hide */
+        @Override
+        public void onSeekComplete(MediaPlayer mp) {
+            synchronized(this) {
+                mStopped = false;
+                scheduleNotification(NOTIFY_SEEK, 0 /* delay */);
+            }
+        }
+
+        /** @hide */
+        public void onNewPlayer() {
+            if (mRefresh) {
+                synchronized(this) {
+                    scheduleNotification(NOTIFY_SEEK, 0 /* delay */);
+                }
+            }
+        }
+
+        private synchronized void notifySeek() {
+            try {
+                long timeUs = getCurrentTimeUs(true, false);
+                if (DEBUG) Log.d(TAG, "onSeekComplete at " + timeUs);
+
+                for (MediaTimeProvider.OnMediaTimeListener listener: mListeners) {
+                    if (listener == null) {
+                        break;
+                    }
+                    listener.onSeek(timeUs);
+                }
+            } catch (IllegalStateException e) {
+                // we should not be there, but at least signal pause
+                if (DEBUG) Log.d(TAG, "onSeekComplete but no player");
+                mPausing = true;  // special handling if player disappeared
+                notifyTimedEvent(false /* refreshTime */);
+            }
+        }
+
+        private synchronized void notifyStop() {
+            for (MediaTimeProvider.OnMediaTimeListener listener: mListeners) {
+                if (listener == null) {
+                    break;
+                }
+                listener.onStop();
+            }
+        }
+
+        private int registerListener(MediaTimeProvider.OnMediaTimeListener listener) {
+            int i = 0;
+            for (; i < mListeners.length; i++) {
+                if (mListeners[i] == listener || mListeners[i] == null) {
+                    break;
+                }
+            }
+
+            // new listener
+            if (i >= mListeners.length) {
+                MediaTimeProvider.OnMediaTimeListener[] newListeners =
+                    new MediaTimeProvider.OnMediaTimeListener[i + 1];
+                long[] newTimes = new long[i + 1];
+                System.arraycopy(mListeners, 0, newListeners, 0, mListeners.length);
+                System.arraycopy(mTimes, 0, newTimes, 0, mTimes.length);
+                mListeners = newListeners;
+                mTimes = newTimes;
+            }
+
+            if (mListeners[i] == null) {
+                mListeners[i] = listener;
+                mTimes[i] = MediaTimeProvider.NO_TIME;
+            }
+            return i;
+        }
+
+        public void notifyAt(
+                long timeUs, MediaTimeProvider.OnMediaTimeListener listener) {
+            synchronized(this) {
+                if (DEBUG) Log.d(TAG, "notifyAt " + timeUs);
+                mTimes[registerListener(listener)] = timeUs;
+                scheduleNotification(NOTIFY_TIME, 0 /* delay */);
+            }
+        }
+
+        public void scheduleUpdate(MediaTimeProvider.OnMediaTimeListener listener) {
+            synchronized(this) {
+                if (DEBUG) Log.d(TAG, "scheduleUpdate");
+                int i = registerListener(listener);
+
+                if (mStopped) {
+                    scheduleNotification(NOTIFY_STOP, 0 /* delay */);
+                } else {
+                    mTimes[i] = 0;
+                    scheduleNotification(NOTIFY_TIME, 0 /* delay */);
+                }
+            }
+        }
+
+        public void cancelNotifications(
+                MediaTimeProvider.OnMediaTimeListener listener) {
+            synchronized(this) {
+                int i = 0;
+                for (; i < mListeners.length; i++) {
+                    if (mListeners[i] == listener) {
+                        System.arraycopy(mListeners, i + 1,
+                                mListeners, i, mListeners.length - i - 1);
+                        System.arraycopy(mTimes, i + 1,
+                                mTimes, i, mTimes.length - i - 1);
+                        mListeners[mListeners.length - 1] = null;
+                        mTimes[mTimes.length - 1] = NO_TIME;
+                        break;
+                    } else if (mListeners[i] == null) {
+                        break;
+                    }
+                }
+
+                scheduleNotification(NOTIFY_TIME, 0 /* delay */);
+            }
+        }
+
+        private synchronized void notifyTimedEvent(boolean refreshTime) {
+            // figure out next callback
+            long nowUs;
+            try {
+                nowUs = getCurrentTimeUs(refreshTime, true);
+            } catch (IllegalStateException e) {
+                // assume we paused until new player arrives
+                mRefresh = true;
+                mPausing = true; // this ensures that call succeeds
+                nowUs = getCurrentTimeUs(refreshTime, true);
+            }
+            long nextTimeUs = nowUs;
+
+            if (DEBUG) {
+                StringBuilder sb = new StringBuilder();
+                sb.append("notifyTimedEvent(").append(mLastTimeUs).append(" -> ")
+                        .append(nowUs).append(") from {");
+                boolean first = true;
+                for (long time: mTimes) {
+                    if (time == NO_TIME) {
+                        continue;
+                    }
+                    if (!first) sb.append(", ");
+                    sb.append(time);
+                    first = false;
+                }
+                sb.append("}");
+                Log.d(TAG, sb.toString());
+            }
+
+            Vector<MediaTimeProvider.OnMediaTimeListener> activatedListeners =
+                new Vector<MediaTimeProvider.OnMediaTimeListener>();
+            for (int ix = 0; ix < mTimes.length; ix++) {
+                if (mListeners[ix] == null) {
+                    break;
+                }
+                if (mTimes[ix] <= NO_TIME) {
+                    // ignore, unless we were stopped
+                } else if (mTimes[ix] <= nowUs + MAX_EARLY_CALLBACK_US) {
+                    activatedListeners.add(mListeners[ix]);
+                    if (DEBUG) Log.d(TAG, "removed");
+                    mTimes[ix] = NO_TIME;
+                } else if (nextTimeUs == nowUs || mTimes[ix] < nextTimeUs) {
+                    nextTimeUs = mTimes[ix];
+                }
+            }
+
+            if (nextTimeUs > nowUs && !mPaused) {
+                // schedule callback at nextTimeUs
+                if (DEBUG) Log.d(TAG, "scheduling for " + nextTimeUs + " and " + nowUs);
+                scheduleNotification(NOTIFY_TIME, nextTimeUs - nowUs);
+            } else {
+                mEventHandler.removeMessages(NOTIFY);
+                // no more callbacks
+            }
+
+            for (MediaTimeProvider.OnMediaTimeListener listener: activatedListeners) {
+                listener.onTimedEvent(nowUs);
+            }
+        }
+
+        private long getEstimatedTime(long nanoTime, boolean monotonic) {
+            if (mPaused) {
+                mLastReportedTime = mLastTimeUs + mTimeAdjustment;
+            } else {
+                long timeSinceRead = (nanoTime - mLastNanoTime) / 1000;
+                mLastReportedTime = mLastTimeUs + timeSinceRead;
+                if (mTimeAdjustment > 0) {
+                    long adjustment =
+                        mTimeAdjustment - timeSinceRead / TIME_ADJUSTMENT_RATE;
+                    if (adjustment <= 0) {
+                        mTimeAdjustment = 0;
+                    } else {
+                        mLastReportedTime += adjustment;
+                    }
+                }
+            }
+            return mLastReportedTime;
+        }
+
+        public long getCurrentTimeUs(boolean refreshTime, boolean monotonic)
+                throws IllegalStateException {
+            synchronized (this) {
+                // we always refresh the time when the paused-state changes, because
+                // we expect to have received the pause-change event delayed.
+                if (mPaused && !refreshTime) {
+                    return mLastReportedTime;
+                }
+
+                long nanoTime = System.nanoTime();
+                if (refreshTime ||
+                        nanoTime >= mLastNanoTime + MAX_NS_WITHOUT_POSITION_CHECK) {
+                    try {
+                        mLastTimeUs = mPlayer.getCurrentPosition() * 1000;
+                        mPaused = !mPlayer.isPlaying();
+                        if (DEBUG) Log.v(TAG, (mPaused ? "paused" : "playing") + " at " + mLastTimeUs);
+                    } catch (IllegalStateException e) {
+                        if (mPausing) {
+                            // if we were pausing, get last estimated timestamp
+                            mPausing = false;
+                            getEstimatedTime(nanoTime, monotonic);
+                            mPaused = true;
+                            if (DEBUG) Log.d(TAG, "illegal state, but pausing: estimating at " + mLastReportedTime);
+                            return mLastReportedTime;
+                        }
+                        // TODO get time when prepared
+                        throw e;
+                    }
+                    mLastNanoTime = nanoTime;
+                    if (monotonic && mLastTimeUs < mLastReportedTime) {
+                        /* have to adjust time */
+                        mTimeAdjustment = mLastReportedTime - mLastTimeUs;
+                    } else {
+                        mTimeAdjustment = 0;
+                    }
+                }
+
+                return getEstimatedTime(nanoTime, monotonic);
+            }
+        }
+
+        private class EventHandler extends Handler {
+            public EventHandler(Looper looper) {
+                super(looper);
+            }
+
+            @Override
+            public void handleMessage(Message msg) {
+                if (msg.what == NOTIFY) {
+                    switch (msg.arg1) {
+                    case NOTIFY_TIME:
+                        notifyTimedEvent(false /* refreshTime */);
+                        break;
+                    case REFRESH_AND_NOTIFY_TIME:
+                        notifyTimedEvent(true /* refreshTime */);
+                        break;
+                    case NOTIFY_STOP:
+                        notifyStop();
+                        break;
+                    case NOTIFY_SEEK:
+                        notifySeek();
+                        break;
+                    }
+                }
+            }
+        }
+    }
 }
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 3e688db..8dcbd6b 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -179,6 +179,40 @@
          *  is applied.
          */
         public static final int VOICE_COMMUNICATION = 7;
+
+        /**
+         * Audio source for a submix of audio streams to be presented remotely.
+         * <p>
+         * An application can use this audio source to capture a mix of audio streams
+         * that should be transmitted to a remote receiver such as a Wifi display.
+         * While recording is active, these audio streams are redirected to the remote
+         * submix instead of being played on the device speaker or headset.
+         * </p><p>
+         * Certain streams are excluded from the remote submix, including
+         * {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_ALARM},
+         * and {@link AudioManager#STREAM_NOTIFICATION}.  These streams will continue
+         * to be presented locally as usual.
+         * </p><p>
+         * Capturing the remote submix audio requires the
+         * {@link android.Manifest.permission#CAPTURE_AUDIO_OUTPUT} permission.
+         * This permission is reserved for use by system components and is not available to
+         * third-party applications.
+         * </p>
+         */
+        public static final int REMOTE_SUBMIX = 8;
+
+        /**
+         * Audio source for preemptible, low-priority software hotword detection
+         * It presents the same gain and pre processing tuning as {@link #VOICE_RECOGNITION}.
+         * <p>
+         * An application should use this audio source when it wishes to do
+         * always-on software hotword detection, while gracefully giving in to any other application
+         * that might want to read from the microphone.
+         * </p>
+         * This is a hidden audio source.
+         * @hide
+         */
+        protected static final int HOTWORD = 1999;
     }
 
     /**
@@ -294,7 +328,7 @@
      * @see android.media.MediaRecorder.AudioSource
      */
     public static final int getAudioSourceMax() {
-        return AudioSource.VOICE_COMMUNICATION;
+        return AudioSource.REMOTE_SUBMIX;
     }
 
     /**
diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index 5c58503..9a79c94 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -16,6 +16,7 @@
 
 package android.media;
 
+import android.app.ActivityThread;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -653,7 +654,13 @@
             if (info == sStatic.mSelectedRoute) {
                 // Removing the currently selected route? Select the default before we remove it.
                 // TODO: Be smarter about the route types here; this selects for all valid.
-                selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_USER, sStatic.mDefaultAudioVideo);
+                if (info != sStatic.mBluetoothA2dpRoute && sStatic.mBluetoothA2dpRoute != null) {
+                    selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_USER,
+                            sStatic.mBluetoothA2dpRoute);
+                } else {
+                    selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_USER,
+                            sStatic.mDefaultAudioVideo);
+                }
             }
             if (!found) {
                 sStatic.mCategories.remove(removingCat);
@@ -875,44 +882,45 @@
         boolean wantScan = false;
         boolean blockScan = false;
         WifiDisplay[] oldDisplays = oldStatus != null ?
-                oldStatus.getRememberedDisplays() : WifiDisplay.EMPTY_ARRAY;
+                oldStatus.getDisplays() : WifiDisplay.EMPTY_ARRAY;
         WifiDisplay[] newDisplays;
-        WifiDisplay[] availableDisplays;
         WifiDisplay activeDisplay;
 
         if (newStatus.getFeatureState() == WifiDisplayStatus.FEATURE_STATE_ON) {
-            newDisplays = newStatus.getRememberedDisplays();
-            availableDisplays = newStatus.getAvailableDisplays();
+            newDisplays = newStatus.getDisplays();
             activeDisplay = newStatus.getActiveDisplay();
         } else {
-            newDisplays = availableDisplays = WifiDisplay.EMPTY_ARRAY;
+            newDisplays = WifiDisplay.EMPTY_ARRAY;
             activeDisplay = null;
         }
 
         for (int i = 0; i < newDisplays.length; i++) {
             final WifiDisplay d = newDisplays[i];
-            final boolean available = findMatchingDisplay(d, availableDisplays) != null;
-            RouteInfo route = findWifiDisplayRoute(d);
-            if (route == null) {
-                route = makeWifiDisplayRoute(d, available);
-                addRouteStatic(route);
-                wantScan = true;
-            } else {
-                updateWifiDisplayRoute(route, d, available, newStatus);
-            }
-            if (d.equals(activeDisplay)) {
-                selectRouteStatic(route.getSupportedTypes(), route);
+            if (d.isRemembered()) {
+                RouteInfo route = findWifiDisplayRoute(d);
+                if (route == null) {
+                    route = makeWifiDisplayRoute(d, newStatus);
+                    addRouteStatic(route);
+                    wantScan = true;
+                } else {
+                    updateWifiDisplayRoute(route, d, newStatus);
+                }
+                if (d.equals(activeDisplay)) {
+                    selectRouteStatic(route.getSupportedTypes(), route);
 
-                // Don't scan if we're already connected to a wifi display,
-                // the scanning process can cause a hiccup with some configurations.
-                blockScan = true;
+                    // Don't scan if we're already connected to a wifi display,
+                    // the scanning process can cause a hiccup with some configurations.
+                    blockScan = true;
+                }
             }
         }
         for (int i = 0; i < oldDisplays.length; i++) {
             final WifiDisplay d = oldDisplays[i];
-            final WifiDisplay newDisplay = findMatchingDisplay(d, newDisplays);
-            if (newDisplay == null) {
-                removeRoute(findWifiDisplayRoute(d));
+            if (d.isRemembered()) {
+                final WifiDisplay newDisplay = findMatchingDisplay(d, newDisplays);
+                if (newDisplay == null || !newDisplay.isRemembered()) {
+                    removeRoute(findWifiDisplayRoute(d));
+                }
             }
         }
 
@@ -923,42 +931,20 @@
         sStatic.mLastKnownWifiDisplayStatus = newStatus;
     }
 
-    static RouteInfo makeWifiDisplayRoute(WifiDisplay display, boolean available) {
-        final RouteInfo newRoute = new RouteInfo(sStatic.mSystemCategory);
-        newRoute.mDeviceAddress = display.getDeviceAddress();
-        newRoute.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_LIVE_VIDEO;
-        newRoute.mVolumeHandling = RouteInfo.PLAYBACK_VOLUME_FIXED;
-        newRoute.mPlaybackType = RouteInfo.PLAYBACK_TYPE_REMOTE;
-
-        newRoute.setStatusCode(available ?
-                RouteInfo.STATUS_AVAILABLE : RouteInfo.STATUS_CONNECTING);
-        newRoute.mEnabled = available;
-
-        newRoute.mName = display.getFriendlyDisplayName();
-        newRoute.mDescription = sStatic.mResources.getText(
-                com.android.internal.R.string.wireless_display_route_description);
-
-        newRoute.mPresentationDisplay = choosePresentationDisplayForRoute(newRoute,
-                sStatic.getAllPresentationDisplays());
-        return newRoute;
-    }
-
-    private static void updateWifiDisplayRoute(RouteInfo route, WifiDisplay display,
-            boolean available, WifiDisplayStatus wifiDisplayStatus) {
-        final boolean isScanning =
-                wifiDisplayStatus.getScanState() == WifiDisplayStatus.SCAN_STATE_SCANNING;
-
-        boolean changed = false;
+    static int getWifiDisplayStatusCode(WifiDisplay d, WifiDisplayStatus wfdStatus) {
         int newStatus = RouteInfo.STATUS_NONE;
 
-        if (available) {
-            newStatus = isScanning ? RouteInfo.STATUS_SCANNING : RouteInfo.STATUS_AVAILABLE;
+        if (wfdStatus.getScanState() == WifiDisplayStatus.SCAN_STATE_SCANNING) {
+            newStatus = RouteInfo.STATUS_SCANNING;
+        } else if (d.isAvailable()) {
+            newStatus = d.canConnect() ?
+                    RouteInfo.STATUS_AVAILABLE: RouteInfo.STATUS_IN_USE;
         } else {
             newStatus = RouteInfo.STATUS_NOT_AVAILABLE;
         }
 
-        if (display.equals(wifiDisplayStatus.getActiveDisplay())) {
-            final int activeState = wifiDisplayStatus.getActiveDisplayState();
+        if (d.equals(wfdStatus.getActiveDisplay())) {
+            final int activeState = wfdStatus.getActiveDisplayState();
             switch (activeState) {
                 case WifiDisplayStatus.DISPLAY_STATE_CONNECTED:
                     newStatus = RouteInfo.STATUS_NONE;
@@ -972,22 +958,51 @@
             }
         }
 
+        return newStatus;
+    }
+
+    static boolean isWifiDisplayEnabled(WifiDisplay d, WifiDisplayStatus wfdStatus) {
+        return d.isAvailable() && (d.canConnect() || d.equals(wfdStatus.getActiveDisplay()));
+    }
+
+    static RouteInfo makeWifiDisplayRoute(WifiDisplay display, WifiDisplayStatus wfdStatus) {
+        final RouteInfo newRoute = new RouteInfo(sStatic.mSystemCategory);
+        newRoute.mDeviceAddress = display.getDeviceAddress();
+        newRoute.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_LIVE_VIDEO;
+        newRoute.mVolumeHandling = RouteInfo.PLAYBACK_VOLUME_FIXED;
+        newRoute.mPlaybackType = RouteInfo.PLAYBACK_TYPE_REMOTE;
+
+        newRoute.setStatusCode(getWifiDisplayStatusCode(display, wfdStatus));
+        newRoute.mEnabled = isWifiDisplayEnabled(display, wfdStatus);
+        newRoute.mName = display.getFriendlyDisplayName();
+        newRoute.mDescription = sStatic.mResources.getText(
+                com.android.internal.R.string.wireless_display_route_description);
+
+        newRoute.mPresentationDisplay = choosePresentationDisplayForRoute(newRoute,
+                sStatic.getAllPresentationDisplays());
+        return newRoute;
+    }
+
+    private static void updateWifiDisplayRoute(
+            RouteInfo route, WifiDisplay display, WifiDisplayStatus wfdStatus) {
+        boolean changed = false;
         final String newName = display.getFriendlyDisplayName();
         if (!route.getName().equals(newName)) {
             route.mName = newName;
             changed = true;
         }
 
-        changed |= route.mEnabled != available;
-        route.mEnabled = available;
+        boolean enabled = isWifiDisplayEnabled(display, wfdStatus);
+        changed |= route.mEnabled != enabled;
+        route.mEnabled = enabled;
 
-        changed |= route.setStatusCode(newStatus);
+        changed |= route.setStatusCode(getWifiDisplayStatusCode(display, wfdStatus));
 
         if (changed) {
             dispatchRouteChanged(route);
         }
 
-        if (!available && route == sStatic.mSelectedRoute) {
+        if (!enabled && route == sStatic.mSelectedRoute) {
             // Oops, no longer available. Reselect the default.
             final RouteInfo defaultRoute = sStatic.mDefaultAudioVideo;
             selectRouteStatic(defaultRoute.getSupportedTypes(), defaultRoute);
@@ -1068,6 +1083,7 @@
         /** @hide */ public static final int STATUS_CONNECTING = 2;
         /** @hide */ public static final int STATUS_AVAILABLE = 3;
         /** @hide */ public static final int STATUS_NOT_AVAILABLE = 4;
+        /** @hide */ public static final int STATUS_IN_USE = 5;
 
         private Object mTag;
 
@@ -1179,6 +1195,9 @@
                     case STATUS_NOT_AVAILABLE:
                         resId = com.android.internal.R.string.media_route_status_not_available;
                         break;
+                    case STATUS_IN_USE:
+                        resId = com.android.internal.R.string.media_route_status_in_use;
+                        break;
                 }
                 mStatus = resId != 0 ? sStatic.mResources.getText(resId) : null;
                 return true;
@@ -1292,7 +1311,8 @@
         public void requestSetVolume(int volume) {
             if (mPlaybackType == PLAYBACK_TYPE_LOCAL) {
                 try {
-                    sStatic.mAudioService.setStreamVolume(mPlaybackStream, volume, 0);
+                    sStatic.mAudioService.setStreamVolume(mPlaybackStream, volume, 0,
+                            ActivityThread.currentPackageName());
                 } catch (RemoteException e) {
                     Log.e(TAG, "Error setting local stream volume", e);
                 }
@@ -1312,7 +1332,8 @@
                 try {
                     final int volume =
                             Math.max(0, Math.min(getVolume() + direction, getVolumeMax()));
-                    sStatic.mAudioService.setStreamVolume(mPlaybackStream, volume, 0);
+                    sStatic.mAudioService.setStreamVolume(mPlaybackStream, volume, 0,
+                            ActivityThread.currentPackageName());
                 } catch (RemoteException e) {
                     Log.e(TAG, "Error setting local stream volume", e);
                 }
diff --git a/media/java/android/media/MediaScannerConnection.java b/media/java/android/media/MediaScannerConnection.java
index 21b6e14..273eb64 100644
--- a/media/java/android/media/MediaScannerConnection.java
+++ b/media/java/android/media/MediaScannerConnection.java
@@ -113,6 +113,9 @@
         synchronized (this) {
             if (!mConnected) {
                 Intent intent = new Intent(IMediaScannerService.class.getName());
+                intent.setComponent(
+                        new ComponentName("com.android.providers.media",
+                                "com.android.providers.media.MediaScannerService"));
                 mContext.bindService(intent, this, Context.BIND_AUTO_CREATE);
                 mConnected = true;
             }
diff --git a/media/java/android/media/MediaTimeProvider.java b/media/java/android/media/MediaTimeProvider.java
new file mode 100644
index 0000000..fe37712
--- /dev/null
+++ b/media/java/android/media/MediaTimeProvider.java
@@ -0,0 +1,90 @@
+/*
+ * 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.media;
+
+/** @hide */
+public interface MediaTimeProvider {
+    // we do not allow negative media time
+    /**
+     * Presentation time value if no timed event notification is requested.
+     */
+    public final static long NO_TIME = -1;
+
+    /**
+     * Cancels all previous notification request from this listener if any.  It
+     * registers the listener to get seek and stop notifications.  If timeUs is
+     * not negative, it also registers the listener for a timed event
+     * notification when the presentation time reaches (becomes greater) than
+     * the value specified.  This happens immediately if the current media time
+     * is larger than or equal to timeUs.
+     *
+     * @param timeUs presentation time to get timed event callback at (or
+     *               {@link #NO_TIME})
+     */
+    public void notifyAt(long timeUs, OnMediaTimeListener listener);
+
+    /**
+     * Cancels all previous notification request from this listener if any.  It
+     * registers the listener to get seek and stop notifications.  If the media
+     * is stopped, the listener will immediately receive a stop notification.
+     * Otherwise, it will receive a timed event notificaton.
+     */
+    public void scheduleUpdate(OnMediaTimeListener listener);
+
+    /**
+     * Cancels all previous notification request from this listener if any.
+     */
+    public void cancelNotifications(OnMediaTimeListener listener);
+
+    /**
+     * Get the current presentation time.
+     *
+     * @param precise   Whether getting a precise time is important. This is
+     *                  more costly.
+     * @param monotonic Whether returned time should be monotonic: that is,
+     *                  greater than or equal to the last returned time.  Don't
+     *                  always set this to true.  E.g. this has undesired
+     *                  consequences if the media is seeked between calls.
+     * @throws IllegalStateException if the media is not initialized
+     */
+    public long getCurrentTimeUs(boolean precise, boolean monotonic)
+            throws IllegalStateException;
+
+    /** @hide */
+    public static interface OnMediaTimeListener {
+        /**
+         * Called when the registered time was reached naturally.
+         *
+         * @param timeUs current media time
+         */
+        void onTimedEvent(long timeUs);
+
+        /**
+         * Called when the media time changed due to seeking.
+         *
+         * @param timeUs current media time
+         */
+        void onSeek(long timeUs);
+
+        /**
+         * Called when the playback stopped.  This is not called on pause, only
+         * on full stop, at which point there is no further current media time.
+         */
+        void onStop();
+    }
+}
+
diff --git a/media/java/android/media/RemoteControlClient.java b/media/java/android/media/RemoteControlClient.java
index 7379438..58f5d55 100644
--- a/media/java/android/media/RemoteControlClient.java
+++ b/media/java/android/media/RemoteControlClient.java
@@ -293,6 +293,17 @@
      * @see #setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener)
      */
     public final static int FLAG_KEY_MEDIA_POSITION_UPDATE = 1 << 8;
+    /**
+     * Flag indicating a RemoteControlClient supports ratings.
+     * This flag must be set in order for components that display the RemoteControlClient
+     * information, to display ratings information, and, if ratings are declared editable
+     * (by calling {@link MetadataEditor#addEditableKey(int)} with the
+     * {@link MetadataEditor#LONG_KEY_RATING_BY_USER} key), it will enable the user to rate
+     * the media, with values being received through the interface set with
+     * {@link #setMetadataUpdateListener(OnMetadataUpdateListener)}.
+     * @see #setTransportControlFlags(int)
+     */
+    public final static int FLAG_KEY_MEDIA_RATING = 1 << 9;
 
     /**
      * @hide
@@ -389,7 +400,11 @@
     private static final int[] METADATA_KEYS_TYPE_LONG = {
         MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER,
         MediaMetadataRetriever.METADATA_KEY_DISC_NUMBER,
-        MediaMetadataRetriever.METADATA_KEY_DURATION };
+        MediaMetadataRetriever.METADATA_KEY_DURATION,
+        MediaMetadataRetriever.METADATA_KEY_YEAR,
+        MetadataEditor.LONG_KEY_RATING_TYPE,
+        MetadataEditor.LONG_KEY_RATING_BY_OTHERS,
+        MetadataEditor.LONG_KEY_RATING_BY_USER};
 
     /**
      * Class used to modify metadata in a {@link RemoteControlClient} object.
@@ -401,6 +416,10 @@
      */
     public class MetadataEditor {
         /**
+         * Mask of editable keys.
+         */
+        private long mEditableKeys;
+        /**
          * @hide
          */
         protected boolean mMetadataChanged;
@@ -432,6 +451,70 @@
          */
         public final static int BITMAP_KEY_ARTWORK = 100;
         /**
+         * The metadata key qualifying the content rating.
+         * The value associated with this key may be: {@link #RATING_HEART},
+         * {@link #RATING_THUMB_UP_DOWN}, or a non-null positive integer expressing a maximum
+         * number of "stars" for the rating, for which a typical value is 3 or 5.
+         */
+        public final static int LONG_KEY_RATING_TYPE = 101;
+        /**
+         * The metadata key for the content's average rating, not the user's rating.
+         * The value associated with this key may be: an integer value between 0 and 100,
+         * or {@link #RATING_NOT_RATED} to express that no average rating is available.
+         * <p></p>
+         * Note that a rating value up to 100 is not incompatible with a rating type using up
+         * to 5 stars for instance, as the average may be an non-integer number of stars.
+         * <p></p>
+         * When the rating type is:
+         * <ul>
+         * <li>{@link #RATING_HEART}, a rating of 51 to 100 means "heart selected",</li>
+         * <li>{@link #RATING_THUMB_UP_DOWN}, a rating of 0 to 50 means "thumb down",
+         *     51 to 100 means "thumb up"</li>
+         * <li>a non-null positive integer, the rating value is mapped to the number of stars, e.g.
+         *     with a maximum of 5 stars, a rating of 0 maps to 0 stars, 1 to 20 maps to 1 star,
+         *     21 to 40 maps to 2 stars, etc.</li>
+         * </ul>
+         * @see #LONG_KEY_RATING_BY_USER
+         */
+        public final static int LONG_KEY_RATING_BY_OTHERS = 102;
+
+        // editable keys
+        /**
+         * @hide
+         * Editable key mask
+         */
+        public final static int KEY_EDITABLE_MASK = 0x1FFFFFFF;
+        /**
+         * The metadata key for the content's user rating.
+         * The value associated with this key may be: an integer value between 0 and 100,
+         * or {@link #RATING_NOT_RATED} to express that the user hasn't rated this content.
+         * Rules for the interpretation of the rating value according to the rating style are
+         * the same as for {@link #LONG_KEY_RATING_BY_OTHERS}.
+         * This key can be flagged as "editable" (with {@link #addEditableKey(int)}) to enable
+         * receiving user rating values through the
+         * {@link android.media.RemoteControlClient.OnMetadataUpdateListener} interface.
+         */
+        public final static int LONG_KEY_RATING_BY_USER = 0x10000001;
+
+        /**
+         * A rating style with a single degree of rating, "heart" vs "no heart". Can be used to
+         * indicate the content referred to is a favorite (or not).
+         * @see #LONG_KEY_RATING_TYPE
+         */
+        public final static long RATING_HEART = -1;
+        /**
+         * A rating style for "thumb up" vs "thumb down".
+         * @see #LONG_KEY_RATING_TYPE
+         */
+        public final static long RATING_THUMB_UP_DOWN = -2;
+        /**
+         * A rating value indicating no rating is available.
+         * @see #LONG_KEY_RATING_BY_OTHERS
+         * @see #LONG_KEY_RATING_BY_USER
+         */
+        public final static long RATING_NOT_RATED = -101;
+
+        /**
          * @hide
          * TODO(jmtrivi) have lockscreen and music move to the new key name
          */
@@ -481,7 +564,9 @@
          *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_DISC_NUMBER},
          *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_DURATION} (with a value
          *      expressed in milliseconds),
-         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_YEAR}.
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_YEAR},
+         *      {@link #LONG_KEY_RATING_BY_OTHERS}, {@link #LONG_KEY_RATING_BY_USER},
+         *      {@link #LONG_KEY_RATING_TYPE}.
          * @param value The long value for the given key
          * @return Returns a reference to the same MetadataEditor object, so you can chain put
          *      calls together.
@@ -528,6 +613,8 @@
         /**
          * Clears all the metadata that has been set since the MetadataEditor instance was
          *     created with {@link RemoteControlClient#editMetadata(boolean)}.
+         * Note that clearing the metadata doesn't reset the editable keys
+         * (use {@link #clearEditableKeys()} instead).
          */
         public synchronized void clear() {
             if (mApplied) {
@@ -539,6 +626,42 @@
         }
 
         /**
+         * Flag the given key as being editable.
+         * This will declare the metadata field as eligible to be updated, with new values
+         * received through the {@link RemoteControlClient.OnMetadataUpdateListener} interface.
+         * @param key the type of metadata that can be edited. The supported key is
+         *     {@link #LONG_KEY_RATING_BY_USER}.
+         */
+        public synchronized void addEditableKey(int key) {
+            if (mApplied) {
+                Log.e(TAG, "Can't change editable keys of a previously applied MetadataEditor");
+                return;
+            }
+            // only one editable key at the moment, so we're not wasting memory on an array
+            // of editable keys to check the validity of the key, just hardcode the supported key.
+            if (key == MetadataEditor.LONG_KEY_RATING_BY_USER) {
+                mEditableKeys |= (MetadataEditor.KEY_EDITABLE_MASK & key);
+                mMetadataChanged = true;
+            } else {
+                Log.e(TAG, "Metadata key " + key + " cannot be edited");
+            }
+        }
+
+        /**
+         * Causes all metadata fields to be read-only.
+         */
+        public synchronized void clearEditableKeys() {
+            if (mApplied) {
+                Log.e(TAG, "Can't clear editable keys of a previously applied MetadataEditor");
+                return;
+            }
+            if (mEditableKeys != 0) {
+                mEditableKeys = 0;
+                mMetadataChanged = true;
+            }
+        }
+
+        /**
          * Associates all the metadata that has been set since the MetadataEditor instance was
          *     created with {@link RemoteControlClient#editMetadata(boolean)}, or since
          *     {@link #clear()} was called, with the RemoteControlClient. Once "applied",
@@ -552,6 +675,8 @@
             synchronized(mCacheLock) {
                 // assign the edited data
                 mMetadata = new Bundle(mEditorMetadata);
+                // add the information about editable keys
+                mMetadata.putLong(String.valueOf(KEY_EDITABLE_MASK), mEditableKeys);
                 if ((mOriginalArtwork != null) && (!mOriginalArtwork.equals(mEditorArtwork))) {
                     mOriginalArtwork.recycle();
                 }
@@ -585,6 +710,7 @@
             editor.mEditorArtwork = null;
             editor.mMetadataChanged = true;
             editor.mArtworkChanged = true;
+            editor.mEditableKeys = 0;
         } else {
             editor.mEditorMetadata = new Bundle(mMetadata);
             editor.mEditorArtwork = mOriginalArtwork;
@@ -739,7 +865,8 @@
      *      {@link #FLAG_KEY_MEDIA_STOP},
      *      {@link #FLAG_KEY_MEDIA_FAST_FORWARD},
      *      {@link #FLAG_KEY_MEDIA_NEXT},
-     *      {@link #FLAG_KEY_MEDIA_POSITION_UPDATE}
+     *      {@link #FLAG_KEY_MEDIA_POSITION_UPDATE},
+     *      {@link #FLAG_KEY_MEDIA_RATING}.
      */
     public void setTransportControlFlags(int transportControlFlags) {
         synchronized(mCacheLock) {
@@ -752,6 +879,48 @@
     }
 
     /**
+     * Interface definition for a callback to be invoked when one of the metadata values has
+     * been updated.
+     */
+    public interface OnMetadataUpdateListener  {
+        /**
+         * Called on the implementer to notify that the metadata field for the given key has
+         * been updated to the new value of type <code>long</long>.
+         * @param key the identifier of the updated metadata field of type <code>long</long>.
+         * @param newValue the new <code>long</long> value for the key
+         */
+        void onMetadataUpdateLong(int key, long newValue);
+        /**
+         * Called on the implementer to notify that the metadata field for the given key has
+         * been updated to the new <code>String</long>.
+         * @param key the identifier of the updated metadata field of type <code>String</long>.
+         * @param newValue the new <code>String</long> value for the key
+         */
+        void onMetadataUpdateString(int key, String newValue);
+        /**
+         * Called on the implementer to notify that the metadata field for the given key has
+         * been updated to the new {@link android.graphics.Bitmap}.
+         * @param key the identifier of the updated metadata field of type
+         *     {@link android.graphics.Bitmap}.
+         * @param newValue the new {@link android.graphics.Bitmap} for the key
+         */
+        void onMetadataUpdateBitmap(int key, Bitmap newValue);
+    }
+
+    /**
+     * Sets the listener to be called whenever the metadata is updated.
+     * New metadata values will be received in the same thread as the one in which
+     * RemoteControlClient was created.
+     * @param l the metadata update listener
+     */
+    public void setMetadataUpdateListener(OnMetadataUpdateListener l) {
+        synchronized(mCacheLock) {
+            mMetadataUpdateListener = l;
+        }
+    }
+
+
+    /**
      * Interface definition for a callback to be invoked when the media playback position is
      * requested to be updated.
      * @see RemoteControlClient#FLAG_KEY_MEDIA_POSITION_UPDATE
@@ -1023,6 +1192,11 @@
      */
     private OnGetPlaybackPositionListener mPositionProvider;
     /**
+     * Listener registered by user of RemoteControlClient to receive edit changes to metadata
+     * it exposes.
+     */
+    private OnMetadataUpdateListener mMetadataUpdateListener;
+    /**
      * The current remote control client generation ID across the system, as known by this object
      */
     private int mCurrentClientGenId = -1;
@@ -1163,6 +1337,15 @@
                         new Long(timeMs)));
             }
         }
+
+        public void updateMetadata(int generationId, int key, long value) {
+            // only post messages, we can't block here
+            if (mEventHandler != null) {
+                mEventHandler.sendMessage(mEventHandler.obtainMessage(
+                        MSG_UPDATE_METADATA_LONG, generationId /* arg1 */, key /* arg2*/,
+                        new Long(value)));
+            }
+        }
     };
 
     /**
@@ -1206,6 +1389,7 @@
     private final static int MSG_SEEK_TO = 10;
     private final static int MSG_POSITION_DRIFT_CHECK = 11;
     private final static int MSG_DISPLAY_WANTS_POS_SYNC = 12;
+    private final static int MSG_UPDATE_METADATA_LONG = 13;
 
     private class EventHandler extends Handler {
         public EventHandler(RemoteControlClient rcc, Looper looper) {
@@ -1259,6 +1443,9 @@
                 case MSG_DISPLAY_WANTS_POS_SYNC:
                     onDisplayWantsSync((IRemoteControlDisplay)msg.obj, msg.arg1 == 1);
                     break;
+                case MSG_UPDATE_METADATA_LONG:
+                    onUpdateMetadata(msg.arg1, msg.arg2, ((Long)msg.obj).longValue());
+                    break;
                 default:
                     Log.e(TAG, "Unknown event " + msg.what + " in RemoteControlClient handler");
             }
@@ -1538,6 +1725,14 @@
         }
     }
 
+    private void onUpdateMetadata(int generationId, int key, long value) {
+        synchronized (mCacheLock) {
+            if ((mCurrentClientGenId == generationId) && (mMetadataUpdateListener != null)) {
+                mMetadataUpdateListener.onMetadataUpdateLong(key, value);
+            }
+        }
+    }
+
     //===========================================================
     // Internal utilities
 
diff --git a/media/java/android/media/RemoteDisplay.java b/media/java/android/media/RemoteDisplay.java
index b463d26..7afce1a 100644
--- a/media/java/android/media/RemoteDisplay.java
+++ b/media/java/android/media/RemoteDisplay.java
@@ -42,6 +42,8 @@
 
     private native int nativeListen(String iface);
     private native void nativeDispose(int ptr);
+    private native void nativePause(int ptr);
+    private native void nativeResume(int ptr);
 
     private RemoteDisplay(Listener listener, Handler handler) {
         mListener = listener;
@@ -87,6 +89,14 @@
         dispose(false);
     }
 
+    public void pause() {
+        nativePause(mPtr);
+    }
+
+    public void resume() {
+        nativeResume(mPtr);
+    }
+
     private void dispose(boolean finalized) {
         if (mPtr != 0) {
             if (mGuard != null) {
@@ -113,11 +123,11 @@
 
     // Called from native.
     private void notifyDisplayConnected(final Surface surface,
-            final int width, final int height, final int flags) {
+            final int width, final int height, final int flags, final int session) {
         mHandler.post(new Runnable() {
             @Override
             public void run() {
-                mListener.onDisplayConnected(surface, width, height, flags);
+                mListener.onDisplayConnected(surface, width, height, flags, session);
             }
         });
     }
@@ -146,7 +156,8 @@
      * Listener invoked when the remote display connection changes state.
      */
     public interface Listener {
-        void onDisplayConnected(Surface surface, int width, int height, int flags);
+        void onDisplayConnected(Surface surface,
+                int width, int height, int flags, int session);
         void onDisplayDisconnected();
         void onDisplayError(int error);
     }
diff --git a/media/java/android/media/ResourceBusyException.java b/media/java/android/media/ResourceBusyException.java
new file mode 100644
index 0000000..a5abe21
--- /dev/null
+++ b/media/java/android/media/ResourceBusyException.java
@@ -0,0 +1,27 @@
+/*
+ * 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.media;
+
+/**
+ * Exception thrown when an operation on a MediaDrm object is attempted
+ * and hardware resources are not available, due to being in use.
+ */
+public final class ResourceBusyException extends MediaDrmException {
+    public ResourceBusyException(String detailMessage) {
+        super(detailMessage);
+    }
+}
diff --git a/media/java/android/media/Ringtone.java b/media/java/android/media/Ringtone.java
index ebbfad9..c335e55 100644
--- a/media/java/android/media/Ringtone.java
+++ b/media/java/android/media/Ringtone.java
@@ -24,7 +24,6 @@
 import android.net.Uri;
 import android.os.Binder;
 import android.os.RemoteException;
-import android.provider.DrmStore;
 import android.provider.MediaStore;
 import android.provider.Settings;
 import android.util.Log;
@@ -50,12 +49,6 @@
         MediaStore.Audio.Media.TITLE
     };
 
-    private static final String[] DRM_COLUMNS = new String[] {
-        DrmStore.Audio._ID,
-        DrmStore.Audio.DATA,
-        DrmStore.Audio.TITLE
-    };
-
     private final Context mContext;
     private final AudioManager mAudioManager;
     private final boolean mAllowRemote;
@@ -101,8 +94,8 @@
     }
 
     /**
-     * Returns a human-presentable title for ringtone. Looks in media and DRM
-     * content providers. If not in either, uses the filename
+     * Returns a human-presentable title for ringtone. Looks in media
+     * content provider. If not in either, uses the filename
      * 
      * @param context A context used for querying. 
      */
@@ -131,9 +124,7 @@
                 }
             } else {
                 try {
-                    if (DrmStore.AUTHORITY.equals(authority)) {
-                        cursor = res.query(uri, DRM_COLUMNS, null, null, null);
-                    } else if (MediaStore.AUTHORITY.equals(authority)) {
+                    if (MediaStore.AUTHORITY.equals(authority)) {
                         cursor = res.query(uri, MEDIA_COLUMNS, null, null, null);
                     }
                 } catch (SecurityException e) {
diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java
index 5e18bfa..8e4004b 100644
--- a/media/java/android/media/RingtoneManager.java
+++ b/media/java/android/media/RingtoneManager.java
@@ -27,7 +27,6 @@
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.Environment;
-import android.provider.DrmStore;
 import android.provider.MediaStore;
 import android.provider.Settings;
 import android.provider.Settings.System;
@@ -85,7 +84,6 @@
      * {@link #EXTRA_RINGTONE_SHOW_DEFAULT},
      * {@link #EXTRA_RINGTONE_SHOW_SILENT}, {@link #EXTRA_RINGTONE_TYPE},
      * {@link #EXTRA_RINGTONE_DEFAULT_URI}, {@link #EXTRA_RINGTONE_TITLE},
-     * {@link #EXTRA_RINGTONE_INCLUDE_DRM}.
      * <p>
      * Output: {@link #EXTRA_RINGTONE_PICKED_URI}.
      */
@@ -113,7 +111,9 @@
 
     /**
      * Given to the ringtone picker as a boolean. Whether to include DRM ringtones.
+     * @deprecated DRM ringtones are no longer supported
      */
+    @Deprecated
     public static final String EXTRA_RINGTONE_INCLUDE_DRM =
             "android.intent.extra.ringtone.INCLUDE_DRM";
     
@@ -183,12 +183,6 @@
         MediaStore.Audio.Media.TITLE_KEY
     };
 
-    private static final String[] DRM_COLUMNS = new String[] {
-        DrmStore.Audio._ID, DrmStore.Audio.TITLE,
-        "\"" + DrmStore.Audio.CONTENT_URI + "\"",
-        DrmStore.Audio.TITLE + " AS " + MediaStore.Audio.Media.TITLE_KEY
-    };
-
     private static final String[] MEDIA_COLUMNS = new String[] {
         MediaStore.Audio.Media._ID, MediaStore.Audio.Media.TITLE,
         "\"" + MediaStore.Audio.Media.EXTERNAL_CONTENT_URI + "\"",
@@ -228,8 +222,6 @@
     
     private boolean mStopPreviousRingtone = true;
     private Ringtone mPreviousRingtone;
-
-    private boolean mIncludeDrm;
     
     /**
      * Constructs a RingtoneManager. This constructor is recommended as its
@@ -328,18 +320,26 @@
      * 
      * @return Whether DRM ringtones will be included.
      * @see #setIncludeDrm(boolean)
+     * Obsolete - always returns false
+     * @deprecated DRM ringtones are no longer supported
      */
+    @Deprecated
     public boolean getIncludeDrm() {
-        return mIncludeDrm;
+        return false;
     }
 
     /**
      * Sets whether to include DRM ringtones.
      * 
      * @param includeDrm Whether to include DRM ringtones.
+     * Obsolete - no longer has any effect
+     * @deprecated DRM ringtones are no longer supported
      */
+    @Deprecated
     public void setIncludeDrm(boolean includeDrm) {
-        mIncludeDrm = includeDrm;
+        if (includeDrm) {
+            Log.w(TAG, "setIncludeDrm no longer supported");
+        }
     }
 
     /**
@@ -363,10 +363,9 @@
         }
         
         final Cursor internalCursor = getInternalRingtones();
-        final Cursor drmCursor = mIncludeDrm ? getDrmRingtones() : null;
         final Cursor mediaCursor = getMediaRingtones();
              
-        return mCursor = new SortCursor(new Cursor[] { internalCursor, drmCursor, mediaCursor },
+        return mCursor = new SortCursor(new Cursor[] { internalCursor, mediaCursor },
                 MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
     }
 
@@ -462,10 +461,6 @@
             uri = getValidRingtoneUriFromCursorAndClose(context, rm.getMediaRingtones());
         }
         
-        if (uri == null) {
-            uri = getValidRingtoneUriFromCursorAndClose(context, rm.getDrmRingtones());
-        }
-        
         return uri;
     }
     
@@ -487,16 +482,9 @@
     private Cursor getInternalRingtones() {
         return query(
                 MediaStore.Audio.Media.INTERNAL_CONTENT_URI, INTERNAL_COLUMNS,
-                constructBooleanTrueWhereClause(mFilterColumns, mIncludeDrm),
+                constructBooleanTrueWhereClause(mFilterColumns),
                 null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
     }
-    
-    private Cursor getDrmRingtones() {
-        // DRM store does not have any columns to use for filtering 
-        return query(
-                DrmStore.Audio.CONTENT_URI, DRM_COLUMNS,
-                null, null, DrmStore.Audio.TITLE);
-    }
 
     private Cursor getMediaRingtones() {
          // Get the external media cursor. First check to see if it is mounted.
@@ -506,7 +494,7 @@
                     status.equals(Environment.MEDIA_MOUNTED_READ_ONLY))
                 ? query(
                     MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, MEDIA_COLUMNS,
-                    constructBooleanTrueWhereClause(mFilterColumns, mIncludeDrm), null,
+                    constructBooleanTrueWhereClause(mFilterColumns), null,
                     MediaStore.Audio.Media.DEFAULT_SORT_ORDER)
                 : null;
     }
@@ -536,7 +524,7 @@
      * @param columns The columns that must be true.
      * @return The where clause.
      */
-    private static String constructBooleanTrueWhereClause(List<String> columns, boolean includeDrm) {
+    private static String constructBooleanTrueWhereClause(List<String> columns) {
         
         if (columns == null) return null;
         
@@ -554,15 +542,6 @@
 
         sb.append(")");
 
-        if (!includeDrm) {
-            // If not DRM files should be shown, the where clause
-            // will be something like "(is_notification=1) and is_drm=0"
-            sb.append(" and ");
-            sb.append(MediaStore.MediaColumns.IS_DRM);
-            sb.append("=0");
-        }
-
-
         return sb.toString();
     }
     
diff --git a/media/java/android/media/SoundPool.java b/media/java/android/media/SoundPool.java
index 587af47..5127479 100644
--- a/media/java/android/media/SoundPool.java
+++ b/media/java/android/media/SoundPool.java
@@ -16,19 +16,21 @@
 
 package android.media;
 
-import android.util.AndroidRuntimeException;
-import android.util.Log;
 import java.io.File;
 import java.io.FileDescriptor;
-import android.os.ParcelFileDescriptor;
+import java.io.IOException;
 import java.lang.ref.WeakReference;
+
 import android.content.Context;
 import android.content.res.AssetFileDescriptor;
-import java.io.IOException;
-
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.os.ParcelFileDescriptor;
+import android.os.SystemProperties;
+import android.util.AndroidRuntimeException;
+import android.util.Log;
+
 
 /**
  * The SoundPool class manages and plays audio resources for applications.
@@ -102,24 +104,8 @@
  * another level, a new SoundPool is created, sounds are loaded, and play
  * resumes.</p>
  */
-public class SoundPool
-{
-    static { System.loadLibrary("soundpool"); }
-
-    private final static String TAG = "SoundPool";
-    private final static boolean DEBUG = false;
-
-    private int mNativeContext; // accessed by native methods
-
-    private EventHandler mEventHandler;
-    private OnLoadCompleteListener mOnLoadCompleteListener;
-
-    private final Object mLock;
-
-    // SoundPool messages
-    //
-    // must match SoundPool.h
-    private static final int SAMPLE_LOADED = 1;
+public class SoundPool {
+    private final SoundPoolDelegate mImpl;
 
     /**
      * Constructor. Constructs a SoundPool object with the following
@@ -135,12 +121,11 @@
      * @return a SoundPool object, or null if creation failed
      */
     public SoundPool(int maxStreams, int streamType, int srcQuality) {
-
-        // do native setup
-        if (native_setup(new WeakReference(this), maxStreams, streamType, srcQuality) != 0) {
-            throw new RuntimeException("Native setup failed");
+        if (SystemProperties.getBoolean("config.disable_media", false)) {
+            mImpl = new SoundPoolStub();
+        } else {
+            mImpl = new SoundPoolImpl(this, maxStreams, streamType, srcQuality);
         }
-        mLock = new Object();
     }
 
     /**
@@ -151,25 +136,8 @@
      *                 a value of 1 for future compatibility.
      * @return a sound ID. This value can be used to play or unload the sound.
      */
-    public int load(String path, int priority)
-    {
-        // pass network streams to player
-        if (path.startsWith("http:"))
-            return _load(path, priority);
-
-        // try local path
-        int id = 0;
-        try {
-            File f = new File(path);
-            ParcelFileDescriptor fd = ParcelFileDescriptor.open(f, ParcelFileDescriptor.MODE_READ_ONLY);
-            if (fd != null) {
-                id = _load(fd.getFileDescriptor(), 0, f.length(), priority);
-                fd.close();
-            }
-        } catch (java.io.IOException e) {
-            Log.e(TAG, "error loading " + path);
-        }
-        return id;
+    public int load(String path, int priority) {
+        return mImpl.load(path, priority);
     }
 
     /**
@@ -188,17 +156,7 @@
      * @return a sound ID. This value can be used to play or unload the sound.
      */
     public int load(Context context, int resId, int priority) {
-        AssetFileDescriptor afd = context.getResources().openRawResourceFd(resId);
-        int id = 0;
-        if (afd != null) {
-            id = _load(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength(), priority);
-            try {
-                afd.close();
-            } catch (java.io.IOException ex) {
-                //Log.d(TAG, "close failed:", ex);
-            }
-        }
-        return id;
+        return mImpl.load(context, resId, priority);
     }
 
     /**
@@ -210,15 +168,7 @@
      * @return a sound ID. This value can be used to play or unload the sound.
      */
     public int load(AssetFileDescriptor afd, int priority) {
-        if (afd != null) {
-            long len = afd.getLength();
-            if (len < 0) {
-                throw new AndroidRuntimeException("no length for fd");
-            }
-            return _load(afd.getFileDescriptor(), afd.getStartOffset(), len, priority);
-        } else {
-            return 0;
-        }
+        return mImpl.load(afd, priority);
     }
 
     /**
@@ -236,13 +186,9 @@
      * @return a sound ID. This value can be used to play or unload the sound.
      */
     public int load(FileDescriptor fd, long offset, long length, int priority) {
-        return _load(fd, offset, length, priority);
+        return mImpl.load(fd, offset, length, priority);
     }
 
-    private native final int _load(String uri, int priority);
-
-    private native final int _load(FileDescriptor fd, long offset, long length, int priority);
-
     /**
      * Unload a sound from a sound ID.
      *
@@ -253,7 +199,9 @@
      * @param soundID a soundID returned by the load() function
      * @return true if just unloaded, false if previously unloaded
      */
-    public native final boolean unload(int soundID);
+    public final boolean unload(int soundID) {
+        return mImpl.unload(soundID);
+    }
 
     /**
      * Play a sound from a sound ID.
@@ -279,8 +227,11 @@
      * @param rate playback rate (1.0 = normal playback, range 0.5 to 2.0)
      * @return non-zero streamID if successful, zero if failed
      */
-    public native final int play(int soundID, float leftVolume, float rightVolume,
-            int priority, int loop, float rate);
+    public final int play(int soundID, float leftVolume, float rightVolume,
+            int priority, int loop, float rate) {
+        return mImpl.play(
+            soundID, leftVolume, rightVolume, priority, loop, rate);
+    }
 
     /**
      * Pause a playback stream.
@@ -293,7 +244,9 @@
      *
      * @param streamID a streamID returned by the play() function
      */
-    public native final void pause(int streamID);
+    public final void pause(int streamID) {
+        mImpl.pause(streamID);
+    }
 
     /**
      * Resume a playback stream.
@@ -305,7 +258,9 @@
      *
      * @param streamID a streamID returned by the play() function
      */
-    public native final void resume(int streamID);
+    public final void resume(int streamID) {
+        mImpl.resume(streamID);
+    }
 
     /**
      * Pause all active streams.
@@ -315,7 +270,9 @@
      * are playing. It also sets a flag so that any streams that
      * are playing can be resumed by calling autoResume().
      */
-    public native final void autoPause();
+    public final void autoPause() {
+        mImpl.autoPause();
+    }
 
     /**
      * Resume all previously active streams.
@@ -323,7 +280,9 @@
      * Automatically resumes all streams that were paused in previous
      * calls to autoPause().
      */
-    public native final void autoResume();
+    public final void autoResume() {
+        mImpl.autoResume();
+    }
 
     /**
      * Stop a playback stream.
@@ -336,7 +295,9 @@
      *
      * @param streamID a streamID returned by the play() function
      */
-    public native final void stop(int streamID);
+    public final void stop(int streamID) {
+        mImpl.stop(streamID);
+    }
 
     /**
      * Set stream volume.
@@ -350,8 +311,10 @@
      * @param leftVolume left volume value (range = 0.0 to 1.0)
      * @param rightVolume right volume value (range = 0.0 to 1.0)
      */
-    public native final void setVolume(int streamID,
-            float leftVolume, float rightVolume);
+    public final void setVolume(int streamID,
+            float leftVolume, float rightVolume) {
+        mImpl.setVolume(streamID, leftVolume, rightVolume);
+    }
 
     /**
      * Similar, except set volume of all channels to same value.
@@ -371,7 +334,9 @@
      *
      * @param streamID a streamID returned by the play() function
      */
-    public native final void setPriority(int streamID, int priority);
+    public final void setPriority(int streamID, int priority) {
+        mImpl.setPriority(streamID, priority);
+    }
 
     /**
      * Set loop mode.
@@ -384,7 +349,9 @@
      * @param streamID a streamID returned by the play() function
      * @param loop loop mode (0 = no loop, -1 = loop forever)
      */
-    public native final void setLoop(int streamID, int loop);
+    public final void setLoop(int streamID, int loop) {
+        mImpl.setLoop(streamID, loop);
+    }
 
     /**
      * Change playback rate.
@@ -398,14 +365,11 @@
      * @param streamID a streamID returned by the play() function
      * @param rate playback rate (1.0 = normal playback, range 0.5 to 2.0)
      */
-    public native final void setRate(int streamID, float rate);
+    public final void setRate(int streamID, float rate) {
+        mImpl.setRate(streamID, rate);
+    }
 
-    /**
-     * Interface definition for a callback to be invoked when all the
-     * sounds are loaded.
-     */
-    public interface OnLoadCompleteListener
-    {
+    public interface OnLoadCompleteListener {
         /**
          * Called when a sound has completed loading.
          *
@@ -419,64 +383,8 @@
     /**
      * Sets the callback hook for the OnLoadCompleteListener.
      */
-    public void setOnLoadCompleteListener(OnLoadCompleteListener listener)
-    {
-        synchronized(mLock) {
-            if (listener != null) {
-                // setup message handler
-                Looper looper;
-                if ((looper = Looper.myLooper()) != null) {
-                    mEventHandler = new EventHandler(this, looper);
-                } else if ((looper = Looper.getMainLooper()) != null) {
-                    mEventHandler = new EventHandler(this, looper);
-                } else {
-                    mEventHandler = null;
-                }
-            } else {
-                mEventHandler = null;
-            }
-            mOnLoadCompleteListener = listener;
-        }
-    }
-
-    private class EventHandler extends Handler
-    {
-        private SoundPool mSoundPool;
-
-        public EventHandler(SoundPool soundPool, Looper looper) {
-            super(looper);
-            mSoundPool = soundPool;
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch(msg.what) {
-            case SAMPLE_LOADED:
-                if (DEBUG) Log.d(TAG, "Sample " + msg.arg1 + " loaded");
-                synchronized(mLock) {
-                    if (mOnLoadCompleteListener != null) {
-                        mOnLoadCompleteListener.onLoadComplete(mSoundPool, msg.arg1, msg.arg2);
-                    }
-                }
-                break;
-            default:
-                Log.e(TAG, "Unknown message type " + msg.what);
-                return;
-            }
-        }
-    }
-
-    // post event from native code to message handler
-    private static void postEventFromNative(Object weakRef, int msg, int arg1, int arg2, Object obj)
-    {
-        SoundPool soundPool = (SoundPool)((WeakReference)weakRef).get();
-        if (soundPool == null)
-            return;
-
-        if (soundPool.mEventHandler != null) {
-            Message m = soundPool.mEventHandler.obtainMessage(msg, arg1, arg2, obj);
-            soundPool.mEventHandler.sendMessage(m);
-        }
+    public void setOnLoadCompleteListener(OnLoadCompleteListener listener) {
+        mImpl.setOnLoadCompleteListener(listener);
     }
 
     /**
@@ -486,9 +394,286 @@
      * object. The SoundPool can no longer be used and the reference
      * should be set to null.
      */
-    public native final void release();
+    public final void release() {
+        mImpl.release();
+    }
 
-    private native final int native_setup(Object weakRef, int maxStreams, int streamType, int srcQuality);
+    /**
+     * Interface for SoundPool implementations.
+     * SoundPool is statically referenced and unconditionally called from all
+     * over the framework, so we can't simply omit the class or make it throw
+     * runtime exceptions, as doing so would break the framework. Instead we
+     * now select either a real or no-op impl object based on whether media is
+     * enabled.
+     *
+     * @hide
+     */
+    /* package */ interface SoundPoolDelegate {
+        public int load(String path, int priority);
+        public int load(Context context, int resId, int priority);
+        public int load(AssetFileDescriptor afd, int priority);
+        public int load(
+                FileDescriptor fd, long offset, long length, int priority);
+        public boolean unload(int soundID);
+        public int play(
+                int soundID, float leftVolume, float rightVolume,
+                int priority, int loop, float rate);
+        public void pause(int streamID);
+        public void resume(int streamID);
+        public void autoPause();
+        public void autoResume();
+        public void stop(int streamID);
+        public void setVolume(int streamID, float leftVolume, float rightVolume);
+        public void setVolume(int streamID, float volume);
+        public void setPriority(int streamID, int priority);
+        public void setLoop(int streamID, int loop);
+        public void setRate(int streamID, float rate);
+        public void setOnLoadCompleteListener(OnLoadCompleteListener listener);
+        public void release();
+    }
 
-    protected void finalize() { release(); }
+
+    /**
+     * Real implementation of the delegate interface. This was formerly the
+     * body of SoundPool itself.
+     */
+    /* package */ static class SoundPoolImpl implements SoundPoolDelegate {
+        static { System.loadLibrary("soundpool"); }
+
+        private final static String TAG = "SoundPool";
+        private final static boolean DEBUG = false;
+
+        private int mNativeContext; // accessed by native methods
+
+        private EventHandler mEventHandler;
+        private SoundPool.OnLoadCompleteListener mOnLoadCompleteListener;
+        private SoundPool mProxy;
+
+        private final Object mLock;
+
+        // SoundPool messages
+        //
+        // must match SoundPool.h
+        private static final int SAMPLE_LOADED = 1;
+
+        public SoundPoolImpl(SoundPool proxy, int maxStreams, int streamType, int srcQuality) {
+
+            // do native setup
+            if (native_setup(new WeakReference(this), maxStreams, streamType, srcQuality) != 0) {
+                throw new RuntimeException("Native setup failed");
+            }
+            mLock = new Object();
+            mProxy = proxy;
+        }
+
+        public int load(String path, int priority)
+        {
+            // pass network streams to player
+            if (path.startsWith("http:"))
+                return _load(path, priority);
+
+            // try local path
+            int id = 0;
+            try {
+                File f = new File(path);
+                ParcelFileDescriptor fd = ParcelFileDescriptor.open(f, ParcelFileDescriptor.MODE_READ_ONLY);
+                if (fd != null) {
+                    id = _load(fd.getFileDescriptor(), 0, f.length(), priority);
+                    fd.close();
+                }
+            } catch (java.io.IOException e) {
+                Log.e(TAG, "error loading " + path);
+            }
+            return id;
+        }
+
+        public int load(Context context, int resId, int priority) {
+            AssetFileDescriptor afd = context.getResources().openRawResourceFd(resId);
+            int id = 0;
+            if (afd != null) {
+                id = _load(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength(), priority);
+                try {
+                    afd.close();
+                } catch (java.io.IOException ex) {
+                    //Log.d(TAG, "close failed:", ex);
+                }
+            }
+            return id;
+        }
+
+        public int load(AssetFileDescriptor afd, int priority) {
+            if (afd != null) {
+                long len = afd.getLength();
+                if (len < 0) {
+                    throw new AndroidRuntimeException("no length for fd");
+                }
+                return _load(afd.getFileDescriptor(), afd.getStartOffset(), len, priority);
+            } else {
+                return 0;
+            }
+        }
+
+        public int load(FileDescriptor fd, long offset, long length, int priority) {
+            return _load(fd, offset, length, priority);
+        }
+
+        private native final int _load(String uri, int priority);
+
+        private native final int _load(FileDescriptor fd, long offset, long length, int priority);
+
+        public native final boolean unload(int soundID);
+
+        public native final int play(int soundID, float leftVolume, float rightVolume,
+                int priority, int loop, float rate);
+
+        public native final void pause(int streamID);
+
+        public native final void resume(int streamID);
+
+        public native final void autoPause();
+
+        public native final void autoResume();
+
+        public native final void stop(int streamID);
+
+        public native final void setVolume(int streamID,
+                float leftVolume, float rightVolume);
+
+        public void setVolume(int streamID, float volume) {
+            setVolume(streamID, volume, volume);
+        }
+
+        public native final void setPriority(int streamID, int priority);
+
+        public native final void setLoop(int streamID, int loop);
+
+        public native final void setRate(int streamID, float rate);
+
+        public void setOnLoadCompleteListener(SoundPool.OnLoadCompleteListener listener)
+        {
+            synchronized(mLock) {
+                if (listener != null) {
+                    // setup message handler
+                    Looper looper;
+                    if ((looper = Looper.myLooper()) != null) {
+                        mEventHandler = new EventHandler(mProxy, looper);
+                    } else if ((looper = Looper.getMainLooper()) != null) {
+                        mEventHandler = new EventHandler(mProxy, looper);
+                    } else {
+                        mEventHandler = null;
+                    }
+                } else {
+                    mEventHandler = null;
+                }
+                mOnLoadCompleteListener = listener;
+            }
+        }
+
+        private class EventHandler extends Handler
+        {
+            private SoundPool mSoundPool;
+
+            public EventHandler(SoundPool soundPool, Looper looper) {
+                super(looper);
+                mSoundPool = soundPool;
+            }
+
+            @Override
+            public void handleMessage(Message msg) {
+                switch(msg.what) {
+                case SAMPLE_LOADED:
+                    if (DEBUG) Log.d(TAG, "Sample " + msg.arg1 + " loaded");
+                    synchronized(mLock) {
+                        if (mOnLoadCompleteListener != null) {
+                            mOnLoadCompleteListener.onLoadComplete(mSoundPool, msg.arg1, msg.arg2);
+                        }
+                    }
+                    break;
+                default:
+                    Log.e(TAG, "Unknown message type " + msg.what);
+                    return;
+                }
+            }
+        }
+
+        // post event from native code to message handler
+        private static void postEventFromNative(Object weakRef, int msg, int arg1, int arg2, Object obj)
+        {
+            SoundPoolImpl soundPoolImpl = (SoundPoolImpl)((WeakReference)weakRef).get();
+            if (soundPoolImpl == null)
+                return;
+
+            if (soundPoolImpl.mEventHandler != null) {
+                Message m = soundPoolImpl.mEventHandler.obtainMessage(msg, arg1, arg2, obj);
+                soundPoolImpl.mEventHandler.sendMessage(m);
+            }
+        }
+
+        public native final void release();
+
+        private native final int native_setup(Object weakRef, int maxStreams, int streamType, int srcQuality);
+
+        protected void finalize() { release(); }
+    }
+
+    /**
+     * No-op implementation of SoundPool.
+     * Used when media is disabled by the system.
+     * @hide
+     */
+    /* package */ static class SoundPoolStub implements SoundPoolDelegate {
+        public SoundPoolStub() { }
+
+        public int load(String path, int priority) {
+            return 0;
+        }
+
+        public int load(Context context, int resId, int priority) {
+            return 0;
+        }
+
+        public int load(AssetFileDescriptor afd, int priority) {
+            return 0;
+        }
+
+        public int load(FileDescriptor fd, long offset, long length, int priority) {
+            return 0;
+        }
+
+        public final boolean unload(int soundID) {
+            return true;
+        }
+
+        public final int play(int soundID, float leftVolume, float rightVolume,
+                int priority, int loop, float rate) {
+            return 0;
+        }
+
+        public final void pause(int streamID) { }
+
+        public final void resume(int streamID) { }
+
+        public final void autoPause() { }
+
+        public final void autoResume() { }
+
+        public final void stop(int streamID) { }
+
+        public final void setVolume(int streamID,
+                float leftVolume, float rightVolume) { }
+
+        public void setVolume(int streamID, float volume) {
+        }
+
+        public final void setPriority(int streamID, int priority) { }
+
+        public final void setLoop(int streamID, int loop) { }
+
+        public final void setRate(int streamID, float rate) { }
+
+        public void setOnLoadCompleteListener(SoundPool.OnLoadCompleteListener listener) {
+        }
+
+        public final void release() { }
+    }
 }
diff --git a/media/java/android/media/SubtitleController.java b/media/java/android/media/SubtitleController.java
new file mode 100644
index 0000000..e83c5ba
--- /dev/null
+++ b/media/java/android/media/SubtitleController.java
@@ -0,0 +1,308 @@
+/*
+ * 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.media;
+
+import java.util.Locale;
+import java.util.Vector;
+
+import android.content.Context;
+import android.media.SubtitleTrack.RenderingWidget;
+import android.view.accessibility.CaptioningManager;
+
+/**
+ * The subtitle controller provides the architecture to display subtitles for a
+ * media source.  It allows specifying which tracks to display, on which anchor
+ * to display them, and also allows adding external, out-of-band subtitle tracks.
+ *
+ * @hide
+ */
+public class SubtitleController {
+    private MediaTimeProvider mTimeProvider;
+    private Vector<Renderer> mRenderers;
+    private Vector<SubtitleTrack> mTracks;
+    private SubtitleTrack mSelectedTrack;
+    private boolean mShowing;
+    private CaptioningManager mCaptioningManager;
+
+    /**
+     * Creates a subtitle controller for a media playback object that implements
+     * the MediaTimeProvider interface.
+     *
+     * @param timeProvider
+     */
+    public SubtitleController(
+            Context context,
+            MediaTimeProvider timeProvider,
+            Listener listener) {
+        mTimeProvider = timeProvider;
+        mListener = listener;
+
+        mRenderers = new Vector<Renderer>();
+        mShowing = false;
+        mTracks = new Vector<SubtitleTrack>();
+        mCaptioningManager =
+            (CaptioningManager)context.getSystemService(Context.CAPTIONING_SERVICE);
+    }
+
+    /**
+     * @return the available subtitle tracks for this media. These include
+     * the tracks found by {@link MediaPlayer} as well as any tracks added
+     * manually via {@link #addTrack}.
+     */
+    public SubtitleTrack[] getTracks() {
+        SubtitleTrack[] tracks = new SubtitleTrack[mTracks.size()];
+        mTracks.toArray(tracks);
+        return tracks;
+    }
+
+    /**
+     * @return the currently selected subtitle track
+     */
+    public SubtitleTrack getSelectedTrack() {
+        return mSelectedTrack;
+    }
+
+    private RenderingWidget getRenderingWidget() {
+        if (mSelectedTrack == null) {
+            return null;
+        }
+        return mSelectedTrack.getRenderingWidget();
+    }
+
+    /**
+     * Selects a subtitle track.  As a result, this track will receive
+     * in-band data from the {@link MediaPlayer}.  However, this does
+     * not change the subtitle visibility.
+     *
+     * @param track The subtitle track to select.  This must be one of the
+     *              tracks in {@link #getTracks}.
+     * @return true if the track was successfully selected.
+     */
+    public boolean selectTrack(SubtitleTrack track) {
+        if (track != null && !mTracks.contains(track)) {
+            return false;
+        }
+        mTrackIsExplicit = true;
+        if (mSelectedTrack == track) {
+            return true;
+        }
+
+        if (mSelectedTrack != null) {
+            mSelectedTrack.hide();
+            mSelectedTrack.setTimeProvider(null);
+        }
+
+        mSelectedTrack = track;
+        mAnchor.setSubtitleWidget(getRenderingWidget());
+
+        if (mSelectedTrack != null) {
+            mSelectedTrack.setTimeProvider(mTimeProvider);
+            mSelectedTrack.show();
+        }
+
+        if (mListener != null) {
+            mListener.onSubtitleTrackSelected(track);
+        }
+        return true;
+    }
+
+    /**
+     * @return the default subtitle track based on system preferences, or null,
+     * if no such track exists in this manager.
+     */
+    public SubtitleTrack getDefaultTrack() {
+        Locale locale = mCaptioningManager.getLocale();
+
+        for (SubtitleTrack track: mTracks) {
+            MediaFormat format = track.getFormat();
+            String language = format.getString(MediaFormat.KEY_LANGUAGE);
+            // TODO: select track with best renderer.  For now, we select first
+            // track with local's language or first track if locale has none
+            if (locale == null ||
+                locale.getLanguage().equals("") ||
+                locale.getISO3Language().equals(language) ||
+                locale.getLanguage().equals(language)) {
+                return track;
+            }
+        }
+        return null;
+    }
+
+    private boolean mTrackIsExplicit = false;
+    private boolean mVisibilityIsExplicit = false;
+
+    /** @hide */
+    public void selectDefaultTrack() {
+        if (mTrackIsExplicit) {
+            return;
+        }
+
+        SubtitleTrack track = getDefaultTrack();
+        if (track != null) {
+            selectTrack(track);
+            mTrackIsExplicit = false;
+            if (!mVisibilityIsExplicit) {
+                if (mCaptioningManager.isEnabled()) {
+                    show();
+                } else {
+                    hide();
+                }
+                mVisibilityIsExplicit = false;
+            }
+        }
+    }
+
+    /** @hide */
+    public void reset() {
+        hide();
+        selectTrack(null);
+        mTracks.clear();
+        mTrackIsExplicit = false;
+        mVisibilityIsExplicit = false;
+    }
+
+    /**
+     * Adds a new, external subtitle track to the manager.
+     *
+     * @param format the format of the track that will include at least
+     *               the MIME type {@link MediaFormat@KEY_MIME}.
+     * @return the created {@link SubtitleTrack} object
+     */
+    public SubtitleTrack addTrack(MediaFormat format) {
+        for (Renderer renderer: mRenderers) {
+            if (renderer.supports(format)) {
+                SubtitleTrack track = renderer.createTrack(format);
+                if (track != null) {
+                    mTracks.add(track);
+                    return track;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Show the selected (or default) subtitle track.
+     */
+    public void show() {
+        mShowing = true;
+        mVisibilityIsExplicit = true;
+        if (mSelectedTrack != null) {
+            mSelectedTrack.show();
+        }
+    }
+
+    /**
+     * Hide the selected (or default) subtitle track.
+     */
+    public void hide() {
+        mVisibilityIsExplicit = true;
+        if (mSelectedTrack != null) {
+            mSelectedTrack.hide();
+        }
+        mShowing = false;
+    }
+
+    /**
+     * Interface for supporting a single or multiple subtitle types in {@link
+     * MediaPlayer}.
+     */
+    public abstract static class Renderer {
+        /**
+         * Called by {@link MediaPlayer}'s {@link SubtitleController} when a new
+         * subtitle track is detected, to see if it should use this object to
+         * parse and display this subtitle track.
+         *
+         * @param format the format of the track that will include at least
+         *               the MIME type {@link MediaFormat@KEY_MIME}.
+         *
+         * @return true if and only if the track format is supported by this
+         * renderer
+         */
+        public abstract boolean supports(MediaFormat format);
+
+        /**
+         * Called by {@link MediaPlayer}'s {@link SubtitleController} for each
+         * subtitle track that was detected and is supported by this object to
+         * create a {@link SubtitleTrack} object.  This object will be created
+         * for each track that was found.  If the track is selected for display,
+         * this object will be used to parse and display the track data.
+         *
+         * @param format the format of the track that will include at least
+         *               the MIME type {@link MediaFormat@KEY_MIME}.
+         * @return a {@link SubtitleTrack} object that will be used to parse
+         * and render the subtitle track.
+         */
+        public abstract SubtitleTrack createTrack(MediaFormat format);
+    }
+
+    /**
+     * Add support for a subtitle format in {@link MediaPlayer}.
+     *
+     * @param renderer a {@link SubtitleController.Renderer} object that adds
+     *                 support for a subtitle format.
+     */
+    public void registerRenderer(Renderer renderer) {
+        // TODO how to get available renderers in the system
+        if (!mRenderers.contains(renderer)) {
+            // TODO should added renderers override existing ones (to allow replacing?)
+            mRenderers.add(renderer);
+        }
+    }
+
+    /**
+     * Subtitle anchor, an object that is able to display a subtitle renderer,
+     * e.g. a VideoView.
+     */
+    public interface Anchor {
+        /**
+         * Anchor should use the supplied subtitle rendering widget, or
+         * none if it is null.
+         * @hide
+         */
+        public void setSubtitleWidget(RenderingWidget subtitleWidget);
+    }
+
+    private Anchor mAnchor;
+
+    /** @hide */
+    public void setAnchor(Anchor anchor) {
+        if (mAnchor == anchor) {
+            return;
+        }
+
+        if (mAnchor != null) {
+            mAnchor.setSubtitleWidget(null);
+        }
+        mAnchor = anchor;
+        if (mAnchor != null) {
+            mAnchor.setSubtitleWidget(getRenderingWidget());
+        }
+    }
+
+    public interface Listener {
+        /**
+         * Called when a subtitle track has been selected.
+         *
+         * @param track selected subtitle track or null
+         * @hide
+         */
+        public void onSubtitleTrackSelected(SubtitleTrack track);
+    }
+
+    private Listener mListener;
+}
diff --git a/media/java/android/media/SubtitleData.java b/media/java/android/media/SubtitleData.java
new file mode 100644
index 0000000..f552e82
--- /dev/null
+++ b/media/java/android/media/SubtitleData.java
@@ -0,0 +1,88 @@
+/*
+ * 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.media;
+
+import android.os.Parcel;
+import android.util.Log;
+
+/**
+ * @hide
+ *
+ * Class to hold the subtitle track's data, including:
+ * <ul>
+ * <li> Track index</li>
+ * <li> Start time (in microseconds) of the data</li>
+ * <li> Duration (in microseconds) of the data</li>
+ * <li> A byte-array of the data</li>
+ * </ul>
+ *
+ * <p> To receive the subtitle data, applications need to do the following:
+ *
+ * <ul>
+ * <li> Select a track of type MEDIA_TRACK_TYPE_SUBTITLE with {@link MediaPlayer.selectTrack(int)</li>
+ * <li> Implement the {@link MediaPlayer.OnSubtitleDataListener} interface</li>
+ * <li> Register the {@link MediaPlayer.OnSubtitleDataListener} callback on a MediaPlayer object</li>
+ * </ul>
+ *
+ * @see android.media.MediaPlayer
+ */
+public final class SubtitleData
+{
+    private static final String TAG = "SubtitleData";
+
+    private int mTrackIndex;
+    private long mStartTimeUs;
+    private long mDurationUs;
+    private byte[] mData;
+
+    public SubtitleData(Parcel parcel) {
+        if (!parseParcel(parcel)) {
+            throw new IllegalArgumentException("parseParcel() fails");
+        }
+    }
+
+    public int getTrackIndex() {
+        return mTrackIndex;
+    }
+
+    public long getStartTimeUs() {
+        return mStartTimeUs;
+    }
+
+    public long getDurationUs() {
+        return mDurationUs;
+    }
+
+    public byte[] getData() {
+        return mData;
+    }
+
+    private boolean parseParcel(Parcel parcel) {
+        parcel.setDataPosition(0);
+        if (parcel.dataAvail() == 0) {
+            return false;
+        }
+
+        mTrackIndex = parcel.readInt();
+        mStartTimeUs = parcel.readLong();
+        mDurationUs = parcel.readLong();
+        mData = new byte[parcel.readInt()];
+        parcel.readByteArray(mData);
+
+        return true;
+    }
+}
diff --git a/media/java/android/media/SubtitleTrack.java b/media/java/android/media/SubtitleTrack.java
new file mode 100644
index 0000000..cb689af
--- /dev/null
+++ b/media/java/android/media/SubtitleTrack.java
@@ -0,0 +1,705 @@
+/*
+ * 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.media;
+
+import android.graphics.Canvas;
+import android.os.Handler;
+import android.util.Log;
+import android.util.LongSparseArray;
+import android.util.Pair;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.Vector;
+
+/**
+ * A subtitle track abstract base class that is responsible for parsing and displaying
+ * an instance of a particular type of subtitle.
+ *
+ * @hide
+ */
+public abstract class SubtitleTrack implements MediaTimeProvider.OnMediaTimeListener {
+    private static final String TAG = "SubtitleTrack";
+    private long mLastUpdateTimeMs;
+    private long mLastTimeMs;
+
+    private Runnable mRunnable;
+
+    /** @hide TODO private */
+    final protected LongSparseArray<Run> mRunsByEndTime = new LongSparseArray<Run>();
+    /** @hide TODO private */
+    final protected LongSparseArray<Run> mRunsByID = new LongSparseArray<Run>();
+
+    /** @hide TODO private */
+    protected CueList mCues;
+    /** @hide TODO private */
+    final protected Vector<Cue> mActiveCues = new Vector<Cue>();
+    /** @hide */
+    protected boolean mVisible;
+
+    /** @hide */
+    public boolean DEBUG = false;
+
+    /** @hide */
+    protected Handler mHandler = new Handler();
+
+    private MediaFormat mFormat;
+
+    public SubtitleTrack(MediaFormat format) {
+        mFormat = format;
+        mCues = new CueList();
+        clearActiveCues();
+        mLastTimeMs = -1;
+    }
+
+    /** @hide */
+    public MediaFormat getFormat() {
+        return mFormat;
+    }
+
+    private long mNextScheduledTimeMs = -1;
+
+    /**
+     * Called when there is input data for the subtitle track.  The
+     * complete subtitle for a track can include multiple whole units
+     * (runs).  Each of these units can have multiple sections.  The
+     * contents of a run are submitted in sequential order, with eos
+     * indicating the last section of the run.  Calls from different
+     * runs must not be intermixed.
+     *
+     * @param data
+     * @param eos true if this is the last section of the run.
+     * @param runID mostly-unique ID for this run of data.  Subtitle cues
+     *              with runID of 0 are discarded immediately after
+     *              display.  Cues with runID of ~0 are discarded
+     *              only at the deletion of the track object.  Cues
+     *              with other runID-s are discarded at the end of the
+     *              run, which defaults to the latest timestamp of
+     *              any of its cues (with this runID).
+     *
+     * TODO use ByteBuffer
+     */
+    public abstract void onData(String data, boolean eos, long runID);
+
+    /**
+     * Called when adding the subtitle rendering widget to the view hierarchy,
+     * as well as when showing or hiding the subtitle track, or when the video
+     * surface position has changed.
+     *
+     * @return the widget that renders this subtitle track. For most renderers
+     *         there should be a single shared instance that is used for all
+     *         tracks supported by that renderer, as at most one subtitle track
+     *         is visible at one time.
+     */
+    public abstract RenderingWidget getRenderingWidget();
+
+    /**
+     * Called when the active cues have changed, and the contents of the subtitle
+     * view should be updated.
+     *
+     * @hide
+     */
+    public abstract void updateView(Vector<Cue> activeCues);
+
+    /** @hide */
+    protected synchronized void updateActiveCues(boolean rebuild, long timeMs) {
+        // out-of-order times mean seeking or new active cues being added
+        // (during their own timespan)
+        if (rebuild || mLastUpdateTimeMs > timeMs) {
+            clearActiveCues();
+        }
+
+        for(Iterator<Pair<Long, Cue> > it =
+                mCues.entriesBetween(mLastUpdateTimeMs, timeMs).iterator(); it.hasNext(); ) {
+            Pair<Long, Cue> event = it.next();
+            Cue cue = event.second;
+
+            if (cue.mEndTimeMs == event.first) {
+                // remove past cues
+                if (DEBUG) Log.v(TAG, "Removing " + cue);
+                mActiveCues.remove(cue);
+                if (cue.mRunID == 0) {
+                    it.remove();
+                }
+            } else if (cue.mStartTimeMs == event.first) {
+                // add new cues
+                // TRICKY: this will happen in start order
+                if (DEBUG) Log.v(TAG, "Adding " + cue);
+                if (cue.mInnerTimesMs != null) {
+                    cue.onTime(timeMs);
+                }
+                mActiveCues.add(cue);
+            } else if (cue.mInnerTimesMs != null) {
+                // cue is modified
+                cue.onTime(timeMs);
+            }
+        }
+
+        /* complete any runs */
+        while (mRunsByEndTime.size() > 0 &&
+               mRunsByEndTime.keyAt(0) <= timeMs) {
+            removeRunsByEndTimeIndex(0); // removes element
+        }
+        mLastUpdateTimeMs = timeMs;
+    }
+
+    private void removeRunsByEndTimeIndex(int ix) {
+        Run run = mRunsByEndTime.valueAt(ix);
+        while (run != null) {
+            Cue cue = run.mFirstCue;
+            while (cue != null) {
+                mCues.remove(cue);
+                Cue nextCue = cue.mNextInRun;
+                cue.mNextInRun = null;
+                cue = nextCue;
+            }
+            mRunsByID.remove(run.mRunID);
+            Run nextRun = run.mNextRunAtEndTimeMs;
+            run.mPrevRunAtEndTimeMs = null;
+            run.mNextRunAtEndTimeMs = null;
+            run = nextRun;
+        }
+        mRunsByEndTime.removeAt(ix);
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        /* remove all cues (untangle all cross-links) */
+        int size = mRunsByEndTime.size();
+        for(int ix = size - 1; ix >= 0; ix--) {
+            removeRunsByEndTimeIndex(ix);
+        }
+
+        super.finalize();
+    }
+
+    private synchronized void takeTime(long timeMs) {
+        mLastTimeMs = timeMs;
+    }
+
+    /** @hide */
+    protected synchronized void clearActiveCues() {
+        if (DEBUG) Log.v(TAG, "Clearing " + mActiveCues.size() + " active cues");
+        mActiveCues.clear();
+        mLastUpdateTimeMs = -1;
+    }
+
+    /** @hide */
+    public void scheduleTimedEvents() {
+        /* get times for the next event */
+        if (mTimeProvider != null) {
+            mNextScheduledTimeMs = mCues.nextTimeAfter(mLastTimeMs);
+            if (DEBUG) Log.d(TAG, "sched @" + mNextScheduledTimeMs + " after " + mLastTimeMs);
+            mTimeProvider.notifyAt(
+                    mNextScheduledTimeMs >= 0 ?
+                        (mNextScheduledTimeMs * 1000) : MediaTimeProvider.NO_TIME,
+                    this);
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void onTimedEvent(long timeUs) {
+        if (DEBUG) Log.d(TAG, "onTimedEvent " + timeUs);
+        synchronized (this) {
+            long timeMs = timeUs / 1000;
+            updateActiveCues(false, timeMs);
+            takeTime(timeMs);
+        }
+        updateView(mActiveCues);
+        scheduleTimedEvents();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void onSeek(long timeUs) {
+        if (DEBUG) Log.d(TAG, "onSeek " + timeUs);
+        synchronized (this) {
+            long timeMs = timeUs / 1000;
+            updateActiveCues(true, timeMs);
+            takeTime(timeMs);
+        }
+        updateView(mActiveCues);
+        scheduleTimedEvents();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void onStop() {
+        synchronized (this) {
+            if (DEBUG) Log.d(TAG, "onStop");
+            clearActiveCues();
+            mLastTimeMs = -1;
+        }
+        updateView(mActiveCues);
+        mNextScheduledTimeMs = -1;
+        mTimeProvider.notifyAt(MediaTimeProvider.NO_TIME, this);
+    }
+
+    /** @hide */
+    protected MediaTimeProvider mTimeProvider;
+
+    /** @hide */
+    public void show() {
+        if (mVisible) {
+            return;
+        }
+
+        mVisible = true;
+        getRenderingWidget().setVisible(true);
+        if (mTimeProvider != null) {
+            mTimeProvider.scheduleUpdate(this);
+        }
+    }
+
+    /** @hide */
+    public void hide() {
+        if (!mVisible) {
+            return;
+        }
+
+        if (mTimeProvider != null) {
+            mTimeProvider.cancelNotifications(this);
+        }
+        getRenderingWidget().setVisible(false);
+        mVisible = false;
+    }
+
+    /** @hide */
+    protected synchronized boolean addCue(Cue cue) {
+        mCues.add(cue);
+
+        if (cue.mRunID != 0) {
+            Run run = mRunsByID.get(cue.mRunID);
+            if (run == null) {
+                run = new Run();
+                mRunsByID.put(cue.mRunID, run);
+                run.mEndTimeMs = cue.mEndTimeMs;
+            } else if (run.mEndTimeMs < cue.mEndTimeMs) {
+                run.mEndTimeMs = cue.mEndTimeMs;
+            }
+
+            // link-up cues in the same run
+            cue.mNextInRun = run.mFirstCue;
+            run.mFirstCue = cue;
+        }
+
+        // if a cue is added that should be visible, need to refresh view
+        long nowMs = -1;
+        if (mTimeProvider != null) {
+            try {
+                nowMs = mTimeProvider.getCurrentTimeUs(
+                        false /* precise */, true /* monotonic */) / 1000;
+            } catch (IllegalStateException e) {
+                // handle as it we are not playing
+            }
+        }
+
+        if (DEBUG) Log.v(TAG, "mVisible=" + mVisible + ", " +
+                cue.mStartTimeMs + " <= " + nowMs + ", " +
+                cue.mEndTimeMs + " >= " + mLastTimeMs);
+
+        if (mVisible &&
+                cue.mStartTimeMs <= nowMs &&
+                // we don't trust nowMs, so check any cue since last callback
+                cue.mEndTimeMs >= mLastTimeMs) {
+            if (mRunnable != null) {
+                mHandler.removeCallbacks(mRunnable);
+            }
+            final SubtitleTrack track = this;
+            final long thenMs = nowMs;
+            mRunnable = new Runnable() {
+                @Override
+                public void run() {
+                    // even with synchronized, it is possible that we are going
+                    // to do multiple updates as the runnable could be already
+                    // running.
+                    synchronized (track) {
+                        mRunnable = null;
+                        updateActiveCues(true, thenMs);
+                        updateView(mActiveCues);
+                    }
+                }
+            };
+            // delay update so we don't update view on every cue.  TODO why 10?
+            if (mHandler.postDelayed(mRunnable, 10 /* delay */)) {
+                if (DEBUG) Log.v(TAG, "scheduling update");
+            } else {
+                if (DEBUG) Log.w(TAG, "failed to schedule subtitle view update");
+            }
+            return true;
+        }
+
+        if (mVisible &&
+                cue.mEndTimeMs >= mLastTimeMs &&
+                (cue.mStartTimeMs < mNextScheduledTimeMs ||
+                 mNextScheduledTimeMs < 0)) {
+            scheduleTimedEvents();
+        }
+
+        return false;
+    }
+
+    /** @hide */
+    public void setTimeProvider(MediaTimeProvider timeProvider) {
+        if (mTimeProvider == timeProvider) {
+            return;
+        }
+        if (mTimeProvider != null) {
+            mTimeProvider.cancelNotifications(this);
+        }
+        mTimeProvider = timeProvider;
+        if (mTimeProvider != null) {
+            mTimeProvider.scheduleUpdate(this);
+        }
+    }
+
+
+    /** @hide */
+    static class CueList {
+        private static final String TAG = "CueList";
+        // simplistic, inefficient implementation
+        private SortedMap<Long, Vector<Cue> > mCues;
+        public boolean DEBUG = false;
+
+        private boolean addEvent(Cue cue, long timeMs) {
+            Vector<Cue> cues = mCues.get(timeMs);
+            if (cues == null) {
+                cues = new Vector<Cue>(2);
+                mCues.put(timeMs, cues);
+            } else if (cues.contains(cue)) {
+                // do not duplicate cues
+                return false;
+            }
+
+            cues.add(cue);
+            return true;
+        }
+
+        private void removeEvent(Cue cue, long timeMs) {
+            Vector<Cue> cues = mCues.get(timeMs);
+            if (cues != null) {
+                cues.remove(cue);
+                if (cues.size() == 0) {
+                    mCues.remove(timeMs);
+                }
+            }
+        }
+
+        public void add(Cue cue) {
+            // ignore non-positive-duration cues
+            if (cue.mStartTimeMs >= cue.mEndTimeMs)
+                return;
+
+            if (!addEvent(cue, cue.mStartTimeMs)) {
+                return;
+            }
+
+            long lastTimeMs = cue.mStartTimeMs;
+            if (cue.mInnerTimesMs != null) {
+                for (long timeMs: cue.mInnerTimesMs) {
+                    if (timeMs > lastTimeMs && timeMs < cue.mEndTimeMs) {
+                        addEvent(cue, timeMs);
+                        lastTimeMs = timeMs;
+                    }
+                }
+            }
+
+            addEvent(cue, cue.mEndTimeMs);
+        }
+
+        public void remove(Cue cue) {
+            removeEvent(cue, cue.mStartTimeMs);
+            if (cue.mInnerTimesMs != null) {
+                for (long timeMs: cue.mInnerTimesMs) {
+                    removeEvent(cue, timeMs);
+                }
+            }
+            removeEvent(cue, cue.mEndTimeMs);
+        }
+
+        public Iterable<Pair<Long, Cue>> entriesBetween(
+                final long lastTimeMs, final long timeMs) {
+            return new Iterable<Pair<Long, Cue> >() {
+                @Override
+                public Iterator<Pair<Long, Cue> > iterator() {
+                    if (DEBUG) Log.d(TAG, "slice (" + lastTimeMs + ", " + timeMs + "]=");
+                    try {
+                        return new EntryIterator(
+                                mCues.subMap(lastTimeMs + 1, timeMs + 1));
+                    } catch(IllegalArgumentException e) {
+                        return new EntryIterator(null);
+                    }
+                }
+            };
+        }
+
+        public long nextTimeAfter(long timeMs) {
+            SortedMap<Long, Vector<Cue>> tail = null;
+            try {
+                tail = mCues.tailMap(timeMs + 1);
+                if (tail != null) {
+                    return tail.firstKey();
+                } else {
+                    return -1;
+                }
+            } catch(IllegalArgumentException e) {
+                return -1;
+            } catch(NoSuchElementException e) {
+                return -1;
+            }
+        }
+
+        class EntryIterator implements Iterator<Pair<Long, Cue> > {
+            @Override
+            public boolean hasNext() {
+                return !mDone;
+            }
+
+            @Override
+            public Pair<Long, Cue> next() {
+                if (mDone) {
+                    throw new NoSuchElementException("");
+                }
+                mLastEntry = new Pair<Long, Cue>(
+                        mCurrentTimeMs, mListIterator.next());
+                mLastListIterator = mListIterator;
+                if (!mListIterator.hasNext()) {
+                    nextKey();
+                }
+                return mLastEntry;
+            }
+
+            @Override
+            public void remove() {
+                // only allow removing end tags
+                if (mLastListIterator == null ||
+                        mLastEntry.second.mEndTimeMs != mLastEntry.first) {
+                    throw new IllegalStateException("");
+                }
+
+                // remove end-cue
+                mLastListIterator.remove();
+                mLastListIterator = null;
+                if (mCues.get(mLastEntry.first).size() == 0) {
+                    mCues.remove(mLastEntry.first);
+                }
+
+                // remove rest of the cues
+                Cue cue = mLastEntry.second;
+                removeEvent(cue, cue.mStartTimeMs);
+                if (cue.mInnerTimesMs != null) {
+                    for (long timeMs: cue.mInnerTimesMs) {
+                        removeEvent(cue, timeMs);
+                    }
+                }
+            }
+
+            public EntryIterator(SortedMap<Long, Vector<Cue> > cues) {
+                if (DEBUG) Log.v(TAG, cues + "");
+                mRemainingCues = cues;
+                mLastListIterator = null;
+                nextKey();
+            }
+
+            private void nextKey() {
+                do {
+                    try {
+                        if (mRemainingCues == null) {
+                            throw new NoSuchElementException("");
+                        }
+                        mCurrentTimeMs = mRemainingCues.firstKey();
+                        mListIterator =
+                            mRemainingCues.get(mCurrentTimeMs).iterator();
+                        try {
+                            mRemainingCues =
+                                mRemainingCues.tailMap(mCurrentTimeMs + 1);
+                        } catch (IllegalArgumentException e) {
+                            mRemainingCues = null;
+                        }
+                        mDone = false;
+                    } catch (NoSuchElementException e) {
+                        mDone = true;
+                        mRemainingCues = null;
+                        mListIterator = null;
+                        return;
+                    }
+                } while (!mListIterator.hasNext());
+            }
+
+            private long mCurrentTimeMs;
+            private Iterator<Cue> mListIterator;
+            private boolean mDone;
+            private SortedMap<Long, Vector<Cue> > mRemainingCues;
+            private Iterator<Cue> mLastListIterator;
+            private Pair<Long,Cue> mLastEntry;
+        }
+
+        CueList() {
+            mCues = new TreeMap<Long, Vector<Cue>>();
+        }
+    }
+
+    /** @hide */
+    public static class Cue {
+        public long mStartTimeMs;
+        public long mEndTimeMs;
+        public long[] mInnerTimesMs;
+        public long mRunID;
+
+        /** @hide */
+        public Cue mNextInRun;
+
+        public void onTime(long timeMs) { }
+    }
+
+    /** @hide update mRunsByEndTime (with default end time) */
+    protected void finishedRun(long runID) {
+        if (runID != 0 && runID != ~0) {
+            Run run = mRunsByID.get(runID);
+            if (run != null) {
+                run.storeByEndTimeMs(mRunsByEndTime);
+            }
+        }
+    }
+
+    /** @hide update mRunsByEndTime with given end time */
+    public void setRunDiscardTimeMs(long runID, long timeMs) {
+        if (runID != 0 && runID != ~0) {
+            Run run = mRunsByID.get(runID);
+            if (run != null) {
+                run.mEndTimeMs = timeMs;
+                run.storeByEndTimeMs(mRunsByEndTime);
+            }
+        }
+    }
+
+    /** @hide */
+    private static class Run {
+        public Cue mFirstCue;
+        public Run mNextRunAtEndTimeMs;
+        public Run mPrevRunAtEndTimeMs;
+        public long mEndTimeMs = -1;
+        public long mRunID = 0;
+        private long mStoredEndTimeMs = -1;
+
+        public void storeByEndTimeMs(LongSparseArray<Run> runsByEndTime) {
+            // remove old value if any
+            int ix = runsByEndTime.indexOfKey(mStoredEndTimeMs);
+            if (ix >= 0) {
+                if (mPrevRunAtEndTimeMs == null) {
+                    assert(this == runsByEndTime.valueAt(ix));
+                    if (mNextRunAtEndTimeMs == null) {
+                        runsByEndTime.removeAt(ix);
+                    } else {
+                        runsByEndTime.setValueAt(ix, mNextRunAtEndTimeMs);
+                    }
+                }
+                removeAtEndTimeMs();
+            }
+
+            // add new value
+            if (mEndTimeMs >= 0) {
+                mPrevRunAtEndTimeMs = null;
+                mNextRunAtEndTimeMs = runsByEndTime.get(mEndTimeMs);
+                if (mNextRunAtEndTimeMs != null) {
+                    mNextRunAtEndTimeMs.mPrevRunAtEndTimeMs = this;
+                }
+                runsByEndTime.put(mEndTimeMs, this);
+                mStoredEndTimeMs = mEndTimeMs;
+            }
+        }
+
+        public void removeAtEndTimeMs() {
+            Run prev = mPrevRunAtEndTimeMs;
+
+            if (mPrevRunAtEndTimeMs != null) {
+                mPrevRunAtEndTimeMs.mNextRunAtEndTimeMs = mNextRunAtEndTimeMs;
+                mPrevRunAtEndTimeMs = null;
+            }
+            if (mNextRunAtEndTimeMs != null) {
+                mNextRunAtEndTimeMs.mPrevRunAtEndTimeMs = prev;
+                mNextRunAtEndTimeMs = null;
+            }
+        }
+    }
+
+    /**
+     * Interface for rendering subtitles onto a Canvas.
+     */
+    public interface RenderingWidget {
+        /**
+         * Sets the widget's callback, which is used to send updates when the
+         * rendered data has changed.
+         *
+         * @param callback update callback
+         */
+        public void setOnChangedListener(OnChangedListener callback);
+
+        /**
+         * Sets the widget's size.
+         *
+         * @param width width in pixels
+         * @param height height in pixels
+         */
+        public void setSize(int width, int height);
+
+        /**
+         * Sets whether the widget should draw subtitles.
+         *
+         * @param visible true if subtitles should be drawn, false otherwise
+         */
+        public void setVisible(boolean visible);
+
+        /**
+         * Renders subtitles onto a {@link Canvas}.
+         *
+         * @param c canvas on which to render subtitles
+         */
+        public void draw(Canvas c);
+
+        /**
+         * Called when the widget is attached to a window.
+         */
+        public void onAttachedToWindow();
+
+        /**
+         * Called when the widget is detached from a window.
+         */
+        public void onDetachedFromWindow();
+
+        /**
+         * Callback used to send updates about changes to rendering data.
+         */
+        public interface OnChangedListener {
+            /**
+             * Called when the rendering data has changed.
+             *
+             * @param renderingWidget the widget whose data has changed
+             */
+            public void onChanged(RenderingWidget renderingWidget);
+        }
+    }
+}
diff --git a/media/java/android/media/VolumeController.java b/media/java/android/media/VolumeController.java
new file mode 100644
index 0000000..2d12bf2
--- /dev/null
+++ b/media/java/android/media/VolumeController.java
@@ -0,0 +1,29 @@
+/*
+ * 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.media;
+
+/**
+ * @hide
+ */
+public interface VolumeController {
+
+    public void postHasNewRemotePlaybackInfo();
+
+    public void postRemoteVolumeChanged(int streamType, int flags);
+
+    public void postRemoteSliderVisibility(boolean visible);
+}
diff --git a/media/java/android/media/WebVttRenderer.java b/media/java/android/media/WebVttRenderer.java
new file mode 100644
index 0000000..74773a8
--- /dev/null
+++ b/media/java/android/media/WebVttRenderer.java
@@ -0,0 +1,1822 @@
+/*
+ * 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.media;
+
+import android.content.Context;
+import android.text.SpannableStringBuilder;
+import android.util.ArrayMap;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.accessibility.CaptioningManager;
+import android.view.accessibility.CaptioningManager.CaptionStyle;
+import android.view.accessibility.CaptioningManager.CaptioningChangeListener;
+import android.widget.LinearLayout;
+
+import com.android.internal.widget.SubtitleView;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+
+/** @hide */
+public class WebVttRenderer extends SubtitleController.Renderer {
+    private final Context mContext;
+
+    private WebVttRenderingWidget mRenderingWidget;
+
+    public WebVttRenderer(Context context) {
+        mContext = context;
+    }
+
+    @Override
+    public boolean supports(MediaFormat format) {
+        if (format.containsKey(MediaFormat.KEY_MIME)) {
+            return format.getString(MediaFormat.KEY_MIME).equals("text/vtt");
+        }
+        return false;
+    }
+
+    @Override
+    public SubtitleTrack createTrack(MediaFormat format) {
+        if (mRenderingWidget == null) {
+            mRenderingWidget = new WebVttRenderingWidget(mContext);
+        }
+
+        return new WebVttTrack(mRenderingWidget, format);
+    }
+}
+
+/** @hide */
+class TextTrackCueSpan {
+    long mTimestampMs;
+    boolean mEnabled;
+    String mText;
+    TextTrackCueSpan(String text, long timestamp) {
+        mTimestampMs = timestamp;
+        mText = text;
+        // spans with timestamp will be enabled by Cue.onTime
+        mEnabled = (mTimestampMs < 0);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof TextTrackCueSpan)) {
+            return false;
+        }
+        TextTrackCueSpan span = (TextTrackCueSpan) o;
+        return mTimestampMs == span.mTimestampMs &&
+                mText.equals(span.mText);
+    }
+}
+
+/**
+ * @hide
+ *
+ * Extract all text without style, but with timestamp spans.
+ */
+class UnstyledTextExtractor implements Tokenizer.OnTokenListener {
+    StringBuilder mLine = new StringBuilder();
+    Vector<TextTrackCueSpan[]> mLines = new Vector<TextTrackCueSpan[]>();
+    Vector<TextTrackCueSpan> mCurrentLine = new Vector<TextTrackCueSpan>();
+    long mLastTimestamp;
+
+    UnstyledTextExtractor() {
+        init();
+    }
+
+    private void init() {
+        mLine.delete(0, mLine.length());
+        mLines.clear();
+        mCurrentLine.clear();
+        mLastTimestamp = -1;
+    }
+
+    @Override
+    public void onData(String s) {
+        mLine.append(s);
+    }
+
+    @Override
+    public void onStart(String tag, String[] classes, String annotation) { }
+
+    @Override
+    public void onEnd(String tag) { }
+
+    @Override
+    public void onTimeStamp(long timestampMs) {
+        // finish any prior span
+        if (mLine.length() > 0 && timestampMs != mLastTimestamp) {
+            mCurrentLine.add(
+                    new TextTrackCueSpan(mLine.toString(), mLastTimestamp));
+            mLine.delete(0, mLine.length());
+        }
+        mLastTimestamp = timestampMs;
+    }
+
+    @Override
+    public void onLineEnd() {
+        // finish any pending span
+        if (mLine.length() > 0) {
+            mCurrentLine.add(
+                    new TextTrackCueSpan(mLine.toString(), mLastTimestamp));
+            mLine.delete(0, mLine.length());
+        }
+
+        TextTrackCueSpan[] spans = new TextTrackCueSpan[mCurrentLine.size()];
+        mCurrentLine.toArray(spans);
+        mCurrentLine.clear();
+        mLines.add(spans);
+    }
+
+    public TextTrackCueSpan[][] getText() {
+        // for politeness, finish last cue-line if it ends abruptly
+        if (mLine.length() > 0 || mCurrentLine.size() > 0) {
+            onLineEnd();
+        }
+        TextTrackCueSpan[][] lines = new TextTrackCueSpan[mLines.size()][];
+        mLines.toArray(lines);
+        init();
+        return lines;
+    }
+}
+
+/**
+ * @hide
+ *
+ * Tokenizer tokenizes the WebVTT Cue Text into tags and data
+ */
+class Tokenizer {
+    private static final String TAG = "Tokenizer";
+    private TokenizerPhase mPhase;
+    private TokenizerPhase mDataTokenizer;
+    private TokenizerPhase mTagTokenizer;
+
+    private OnTokenListener mListener;
+    private String mLine;
+    private int mHandledLen;
+
+    interface TokenizerPhase {
+        TokenizerPhase start();
+        void tokenize();
+    }
+
+    class DataTokenizer implements TokenizerPhase {
+        // includes both WebVTT data && escape state
+        private StringBuilder mData;
+
+        public TokenizerPhase start() {
+            mData = new StringBuilder();
+            return this;
+        }
+
+        private boolean replaceEscape(String escape, String replacement, int pos) {
+            if (mLine.startsWith(escape, pos)) {
+                mData.append(mLine.substring(mHandledLen, pos));
+                mData.append(replacement);
+                mHandledLen = pos + escape.length();
+                pos = mHandledLen - 1;
+                return true;
+            }
+            return false;
+        }
+
+        @Override
+        public void tokenize() {
+            int end = mLine.length();
+            for (int pos = mHandledLen; pos < mLine.length(); pos++) {
+                if (mLine.charAt(pos) == '&') {
+                    if (replaceEscape("&amp;", "&", pos) ||
+                            replaceEscape("&lt;", "<", pos) ||
+                            replaceEscape("&gt;", ">", pos) ||
+                            replaceEscape("&lrm;", "\u200e", pos) ||
+                            replaceEscape("&rlm;", "\u200f", pos) ||
+                            replaceEscape("&nbsp;", "\u00a0", pos)) {
+                        continue;
+                    }
+                } else if (mLine.charAt(pos) == '<') {
+                    end = pos;
+                    mPhase = mTagTokenizer.start();
+                    break;
+                }
+            }
+            mData.append(mLine.substring(mHandledLen, end));
+            // yield mData
+            mListener.onData(mData.toString());
+            mData.delete(0, mData.length());
+            mHandledLen = end;
+        }
+    }
+
+    class TagTokenizer implements TokenizerPhase {
+        private boolean mAtAnnotation;
+        private String mName, mAnnotation;
+
+        public TokenizerPhase start() {
+            mName = mAnnotation = "";
+            mAtAnnotation = false;
+            return this;
+        }
+
+        @Override
+        public void tokenize() {
+            if (!mAtAnnotation)
+                mHandledLen++;
+            if (mHandledLen < mLine.length()) {
+                String[] parts;
+                /**
+                 * Collect annotations and end-tags to closing >.  Collect tag
+                 * name to closing bracket or next white-space.
+                 */
+                if (mAtAnnotation || mLine.charAt(mHandledLen) == '/') {
+                    parts = mLine.substring(mHandledLen).split(">");
+                } else {
+                    parts = mLine.substring(mHandledLen).split("[\t\f >]");
+                }
+                String part = mLine.substring(
+                            mHandledLen, mHandledLen + parts[0].length());
+                mHandledLen += parts[0].length();
+
+                if (mAtAnnotation) {
+                    mAnnotation += " " + part;
+                } else {
+                    mName = part;
+                }
+            }
+
+            mAtAnnotation = true;
+
+            if (mHandledLen < mLine.length() && mLine.charAt(mHandledLen) == '>') {
+                yield_tag();
+                mPhase = mDataTokenizer.start();
+                mHandledLen++;
+            }
+        }
+
+        private void yield_tag() {
+            if (mName.startsWith("/")) {
+                mListener.onEnd(mName.substring(1));
+            } else if (mName.length() > 0 && Character.isDigit(mName.charAt(0))) {
+                // timestamp
+                try {
+                    long timestampMs = WebVttParser.parseTimestampMs(mName);
+                    mListener.onTimeStamp(timestampMs);
+                } catch (NumberFormatException e) {
+                    Log.d(TAG, "invalid timestamp tag: <" + mName + ">");
+                }
+            } else {
+                mAnnotation = mAnnotation.replaceAll("\\s+", " ");
+                if (mAnnotation.startsWith(" ")) {
+                    mAnnotation = mAnnotation.substring(1);
+                }
+                if (mAnnotation.endsWith(" ")) {
+                    mAnnotation = mAnnotation.substring(0, mAnnotation.length() - 1);
+                }
+
+                String[] classes = null;
+                int dotAt = mName.indexOf('.');
+                if (dotAt >= 0) {
+                    classes = mName.substring(dotAt + 1).split("\\.");
+                    mName = mName.substring(0, dotAt);
+                }
+                mListener.onStart(mName, classes, mAnnotation);
+            }
+        }
+    }
+
+    Tokenizer(OnTokenListener listener) {
+        mDataTokenizer = new DataTokenizer();
+        mTagTokenizer = new TagTokenizer();
+        reset();
+        mListener = listener;
+    }
+
+    void reset() {
+        mPhase = mDataTokenizer.start();
+    }
+
+    void tokenize(String s) {
+        mHandledLen = 0;
+        mLine = s;
+        while (mHandledLen < mLine.length()) {
+            mPhase.tokenize();
+        }
+        /* we are finished with a line unless we are in the middle of a tag */
+        if (!(mPhase instanceof TagTokenizer)) {
+            // yield END-OF-LINE
+            mListener.onLineEnd();
+        }
+    }
+
+    interface OnTokenListener {
+        void onData(String s);
+        void onStart(String tag, String[] classes, String annotation);
+        void onEnd(String tag);
+        void onTimeStamp(long timestampMs);
+        void onLineEnd();
+    }
+}
+
+/** @hide */
+class TextTrackRegion {
+    final static int SCROLL_VALUE_NONE      = 300;
+    final static int SCROLL_VALUE_SCROLL_UP = 301;
+
+    String mId;
+    float mWidth;
+    int mLines;
+    float mAnchorPointX, mAnchorPointY;
+    float mViewportAnchorPointX, mViewportAnchorPointY;
+    int mScrollValue;
+
+    TextTrackRegion() {
+        mId = "";
+        mWidth = 100;
+        mLines = 3;
+        mAnchorPointX = mViewportAnchorPointX = 0.f;
+        mAnchorPointY = mViewportAnchorPointY = 100.f;
+        mScrollValue = SCROLL_VALUE_NONE;
+    }
+
+    public String toString() {
+        StringBuilder res = new StringBuilder(" {id:\"").append(mId)
+            .append("\", width:").append(mWidth)
+            .append(", lines:").append(mLines)
+            .append(", anchorPoint:(").append(mAnchorPointX)
+            .append(", ").append(mAnchorPointY)
+            .append("), viewportAnchorPoints:").append(mViewportAnchorPointX)
+            .append(", ").append(mViewportAnchorPointY)
+            .append("), scrollValue:")
+            .append(mScrollValue == SCROLL_VALUE_NONE ? "none" :
+                    mScrollValue == SCROLL_VALUE_SCROLL_UP ? "scroll_up" :
+                    "INVALID")
+            .append("}");
+        return res.toString();
+    }
+}
+
+/** @hide */
+class TextTrackCue extends SubtitleTrack.Cue {
+    final static int WRITING_DIRECTION_HORIZONTAL  = 100;
+    final static int WRITING_DIRECTION_VERTICAL_RL = 101;
+    final static int WRITING_DIRECTION_VERTICAL_LR = 102;
+
+    final static int ALIGNMENT_MIDDLE = 200;
+    final static int ALIGNMENT_START  = 201;
+    final static int ALIGNMENT_END    = 202;
+    final static int ALIGNMENT_LEFT   = 203;
+    final static int ALIGNMENT_RIGHT  = 204;
+    private static final String TAG = "TTCue";
+
+    String  mId;
+    boolean mPauseOnExit;
+    int     mWritingDirection;
+    String  mRegionId;
+    boolean mSnapToLines;
+    Integer mLinePosition;  // null means AUTO
+    boolean mAutoLinePosition;
+    int     mTextPosition;
+    int     mSize;
+    int     mAlignment;
+    // Vector<String> mText;
+    String[] mStrings;
+    TextTrackCueSpan[][] mLines;
+    TextTrackRegion mRegion;
+
+    TextTrackCue() {
+        mId = "";
+        mPauseOnExit = false;
+        mWritingDirection = WRITING_DIRECTION_HORIZONTAL;
+        mRegionId = "";
+        mSnapToLines = true;
+        mLinePosition = null /* AUTO */;
+        mTextPosition = 50;
+        mSize = 100;
+        mAlignment = ALIGNMENT_MIDDLE;
+        mLines = null;
+        mRegion = null;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof TextTrackCue)) {
+            return false;
+        }
+        if (this == o) {
+            return true;
+        }
+
+        try {
+            TextTrackCue cue = (TextTrackCue) o;
+            boolean res = mId.equals(cue.mId) &&
+                    mPauseOnExit == cue.mPauseOnExit &&
+                    mWritingDirection == cue.mWritingDirection &&
+                    mRegionId.equals(cue.mRegionId) &&
+                    mSnapToLines == cue.mSnapToLines &&
+                    mAutoLinePosition == cue.mAutoLinePosition &&
+                    (mAutoLinePosition || mLinePosition == cue.mLinePosition) &&
+                    mTextPosition == cue.mTextPosition &&
+                    mSize == cue.mSize &&
+                    mAlignment == cue.mAlignment &&
+                    mLines.length == cue.mLines.length;
+            if (res == true) {
+                for (int line = 0; line < mLines.length; line++) {
+                    if (!Arrays.equals(mLines[line], cue.mLines[line])) {
+                        return false;
+                    }
+                }
+            }
+            return res;
+        } catch(IncompatibleClassChangeError e) {
+            return false;
+        }
+    }
+
+    public StringBuilder appendStringsToBuilder(StringBuilder builder) {
+        if (mStrings == null) {
+            builder.append("null");
+        } else {
+            builder.append("[");
+            boolean first = true;
+            for (String s: mStrings) {
+                if (!first) {
+                    builder.append(", ");
+                }
+                if (s == null) {
+                    builder.append("null");
+                } else {
+                    builder.append("\"");
+                    builder.append(s);
+                    builder.append("\"");
+                }
+                first = false;
+            }
+            builder.append("]");
+        }
+        return builder;
+    }
+
+    public StringBuilder appendLinesToBuilder(StringBuilder builder) {
+        if (mLines == null) {
+            builder.append("null");
+        } else {
+            builder.append("[");
+            boolean first = true;
+            for (TextTrackCueSpan[] spans: mLines) {
+                if (!first) {
+                    builder.append(", ");
+                }
+                if (spans == null) {
+                    builder.append("null");
+                } else {
+                    builder.append("\"");
+                    boolean innerFirst = true;
+                    long lastTimestamp = -1;
+                    for (TextTrackCueSpan span: spans) {
+                        if (!innerFirst) {
+                            builder.append(" ");
+                        }
+                        if (span.mTimestampMs != lastTimestamp) {
+                            builder.append("<")
+                                    .append(WebVttParser.timeToString(
+                                            span.mTimestampMs))
+                                    .append(">");
+                            lastTimestamp = span.mTimestampMs;
+                        }
+                        builder.append(span.mText);
+                        innerFirst = false;
+                    }
+                    builder.append("\"");
+                }
+                first = false;
+            }
+            builder.append("]");
+        }
+        return builder;
+    }
+
+    public String toString() {
+        StringBuilder res = new StringBuilder();
+
+        res.append(WebVttParser.timeToString(mStartTimeMs))
+                .append(" --> ").append(WebVttParser.timeToString(mEndTimeMs))
+                .append(" {id:\"").append(mId)
+                .append("\", pauseOnExit:").append(mPauseOnExit)
+                .append(", direction:")
+                .append(mWritingDirection == WRITING_DIRECTION_HORIZONTAL ? "horizontal" :
+                        mWritingDirection == WRITING_DIRECTION_VERTICAL_LR ? "vertical_lr" :
+                        mWritingDirection == WRITING_DIRECTION_VERTICAL_RL ? "vertical_rl" :
+                        "INVALID")
+                .append(", regionId:\"").append(mRegionId)
+                .append("\", snapToLines:").append(mSnapToLines)
+                .append(", linePosition:").append(mAutoLinePosition ? "auto" :
+                                                  mLinePosition)
+                .append(", textPosition:").append(mTextPosition)
+                .append(", size:").append(mSize)
+                .append(", alignment:")
+                .append(mAlignment == ALIGNMENT_END ? "end" :
+                        mAlignment == ALIGNMENT_LEFT ? "left" :
+                        mAlignment == ALIGNMENT_MIDDLE ? "middle" :
+                        mAlignment == ALIGNMENT_RIGHT ? "right" :
+                        mAlignment == ALIGNMENT_START ? "start" : "INVALID")
+                .append(", text:");
+        appendStringsToBuilder(res).append("}");
+        return res.toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return toString().hashCode();
+    }
+
+    @Override
+    public void onTime(long timeMs) {
+        for (TextTrackCueSpan[] line: mLines) {
+            for (TextTrackCueSpan span: line) {
+                span.mEnabled = timeMs >= span.mTimestampMs;
+            }
+        }
+    }
+}
+
+/** @hide */
+class WebVttParser {
+    private static final String TAG = "WebVttParser";
+    private Phase mPhase;
+    private TextTrackCue mCue;
+    private Vector<String> mCueTexts;
+    private WebVttCueListener mListener;
+    private String mBuffer;
+
+    WebVttParser(WebVttCueListener listener) {
+        mPhase = mParseStart;
+        mBuffer = "";   /* mBuffer contains up to 1 incomplete line */
+        mListener = listener;
+        mCueTexts = new Vector<String>();
+    }
+
+    /* parsePercentageString */
+    public static float parseFloatPercentage(String s)
+            throws NumberFormatException {
+        if (!s.endsWith("%")) {
+            throw new NumberFormatException("does not end in %");
+        }
+        s = s.substring(0, s.length() - 1);
+        // parseFloat allows an exponent or a sign
+        if (s.matches(".*[^0-9.].*")) {
+            throw new NumberFormatException("contains an invalid character");
+        }
+
+        try {
+            float value = Float.parseFloat(s);
+            if (value < 0.0f || value > 100.0f) {
+                throw new NumberFormatException("is out of range");
+            }
+            return value;
+        } catch (NumberFormatException e) {
+            throw new NumberFormatException("is not a number");
+        }
+    }
+
+    public static int parseIntPercentage(String s) throws NumberFormatException {
+        if (!s.endsWith("%")) {
+            throw new NumberFormatException("does not end in %");
+        }
+        s = s.substring(0, s.length() - 1);
+        // parseInt allows "-0" that returns 0, so check for non-digits
+        if (s.matches(".*[^0-9].*")) {
+            throw new NumberFormatException("contains an invalid character");
+        }
+
+        try {
+            int value = Integer.parseInt(s);
+            if (value < 0 || value > 100) {
+                throw new NumberFormatException("is out of range");
+            }
+            return value;
+        } catch (NumberFormatException e) {
+            throw new NumberFormatException("is not a number");
+        }
+    }
+
+    public static long parseTimestampMs(String s) throws NumberFormatException {
+        if (!s.matches("(\\d+:)?[0-5]\\d:[0-5]\\d\\.\\d{3}")) {
+            throw new NumberFormatException("has invalid format");
+        }
+
+        String[] parts = s.split("\\.", 2);
+        long value = 0;
+        for (String group: parts[0].split(":")) {
+            value = value * 60 + Long.parseLong(group);
+        }
+        return value * 1000 + Long.parseLong(parts[1]);
+    }
+
+    public static String timeToString(long timeMs) {
+        return String.format("%d:%02d:%02d.%03d",
+                timeMs / 3600000, (timeMs / 60000) % 60,
+                (timeMs / 1000) % 60, timeMs % 1000);
+    }
+
+    public void parse(String s) {
+        boolean trailingCR = false;
+        mBuffer = (mBuffer + s.replace("\0", "\ufffd")).replace("\r\n", "\n");
+
+        /* keep trailing '\r' in case matching '\n' arrives in next packet */
+        if (mBuffer.endsWith("\r")) {
+            trailingCR = true;
+            mBuffer = mBuffer.substring(0, mBuffer.length() - 1);
+        }
+
+        String[] lines = mBuffer.split("[\r\n]");
+        for (int i = 0; i < lines.length - 1; i++) {
+            mPhase.parse(lines[i]);
+        }
+
+        mBuffer = lines[lines.length - 1];
+        if (trailingCR)
+            mBuffer += "\r";
+    }
+
+    public void eos() {
+        if (mBuffer.endsWith("\r")) {
+            mBuffer = mBuffer.substring(0, mBuffer.length() - 1);
+        }
+
+        mPhase.parse(mBuffer);
+        mBuffer = "";
+
+        yieldCue();
+        mPhase = mParseStart;
+    }
+
+    public void yieldCue() {
+        if (mCue != null && mCueTexts.size() > 0) {
+            mCue.mStrings = new String[mCueTexts.size()];
+            mCueTexts.toArray(mCue.mStrings);
+            mCueTexts.clear();
+            mListener.onCueParsed(mCue);
+        }
+        mCue = null;
+    }
+
+    interface Phase {
+        void parse(String line);
+    }
+
+    final private Phase mSkipRest = new Phase() {
+        @Override
+        public void parse(String line) { }
+    };
+
+    final private Phase mParseStart = new Phase() { // 5-9
+        @Override
+        public void parse(String line) {
+            if (!line.equals("WEBVTT") &&
+                    !line.startsWith("WEBVTT ") &&
+                    !line.startsWith("WEBVTT\t")) {
+                log_warning("Not a WEBVTT header", line);
+                mPhase = mSkipRest;
+            } else {
+                mPhase = mParseHeader;
+            }
+        }
+    };
+
+    final private Phase mParseHeader = new Phase() { // 10-13
+        TextTrackRegion parseRegion(String s) {
+            TextTrackRegion region = new TextTrackRegion();
+            for (String setting: s.split(" +")) {
+                int equalAt = setting.indexOf('=');
+                if (equalAt <= 0 || equalAt == setting.length() - 1) {
+                    continue;
+                }
+
+                String name = setting.substring(0, equalAt);
+                String value = setting.substring(equalAt + 1);
+                if (name.equals("id")) {
+                    region.mId = value;
+                } else if (name.equals("width")) {
+                    try {
+                        region.mWidth = parseFloatPercentage(value);
+                    } catch (NumberFormatException e) {
+                        log_warning("region setting", name,
+                                "has invalid value", e.getMessage(), value);
+                    }
+                } else if (name.equals("lines")) {
+                    try {
+                        int lines = Integer.parseInt(value);
+                        if (lines >= 0) {
+                            region.mLines = lines;
+                        } else {
+                            log_warning("region setting", name, "is negative", value);
+                        }
+                    } catch (NumberFormatException e) {
+                        log_warning("region setting", name, "is not numeric", value);
+                    }
+                } else if (name.equals("regionanchor") ||
+                           name.equals("viewportanchor")) {
+                    int commaAt = value.indexOf(",");
+                    if (commaAt < 0) {
+                        log_warning("region setting", name, "contains no comma", value);
+                        continue;
+                    }
+
+                    String anchorX = value.substring(0, commaAt);
+                    String anchorY = value.substring(commaAt + 1);
+                    float x, y;
+
+                    try {
+                        x = parseFloatPercentage(anchorX);
+                    } catch (NumberFormatException e) {
+                        log_warning("region setting", name,
+                                "has invalid x component", e.getMessage(), anchorX);
+                        continue;
+                    }
+                    try {
+                        y = parseFloatPercentage(anchorY);
+                    } catch (NumberFormatException e) {
+                        log_warning("region setting", name,
+                                "has invalid y component", e.getMessage(), anchorY);
+                        continue;
+                    }
+
+                    if (name.charAt(0) == 'r') {
+                        region.mAnchorPointX = x;
+                        region.mAnchorPointY = y;
+                    } else {
+                        region.mViewportAnchorPointX = x;
+                        region.mViewportAnchorPointY = y;
+                    }
+                } else if (name.equals("scroll")) {
+                    if (value.equals("up")) {
+                        region.mScrollValue =
+                            TextTrackRegion.SCROLL_VALUE_SCROLL_UP;
+                    } else {
+                        log_warning("region setting", name, "has invalid value", value);
+                    }
+                }
+            }
+            return region;
+        }
+
+        @Override
+        public void parse(String line)  {
+            if (line.length() == 0) {
+                mPhase = mParseCueId;
+            } else if (line.contains("-->")) {
+                mPhase = mParseCueTime;
+                mPhase.parse(line);
+            } else {
+                int colonAt = line.indexOf(':');
+                if (colonAt <= 0 || colonAt >= line.length() - 1) {
+                    log_warning("meta data header has invalid format", line);
+                }
+                String name = line.substring(0, colonAt);
+                String value = line.substring(colonAt + 1);
+
+                if (name.equals("Region")) {
+                    TextTrackRegion region = parseRegion(value);
+                    mListener.onRegionParsed(region);
+                }
+            }
+        }
+    };
+
+    final private Phase mParseCueId = new Phase() {
+        @Override
+        public void parse(String line) {
+            if (line.length() == 0) {
+                return;
+            }
+
+            assert(mCue == null);
+
+            if (line.equals("NOTE") || line.startsWith("NOTE ")) {
+                mPhase = mParseCueText;
+            }
+
+            mCue = new TextTrackCue();
+            mCueTexts.clear();
+
+            mPhase = mParseCueTime;
+            if (line.contains("-->")) {
+                mPhase.parse(line);
+            } else {
+                mCue.mId = line;
+            }
+        }
+    };
+
+    final private Phase mParseCueTime = new Phase() {
+        @Override
+        public void parse(String line) {
+            int arrowAt = line.indexOf("-->");
+            if (arrowAt < 0) {
+                mCue = null;
+                mPhase = mParseCueId;
+                return;
+            }
+
+            String start = line.substring(0, arrowAt).trim();
+            // convert only initial and first other white-space to space
+            String rest = line.substring(arrowAt + 3)
+                    .replaceFirst("^\\s+", "").replaceFirst("\\s+", " ");
+            int spaceAt = rest.indexOf(' ');
+            String end = spaceAt > 0 ? rest.substring(0, spaceAt) : rest;
+            rest = spaceAt > 0 ? rest.substring(spaceAt + 1) : "";
+
+            mCue.mStartTimeMs = parseTimestampMs(start);
+            mCue.mEndTimeMs = parseTimestampMs(end);
+            for (String setting: rest.split(" +")) {
+                int colonAt = setting.indexOf(':');
+                if (colonAt <= 0 || colonAt == setting.length() - 1) {
+                    continue;
+                }
+                String name = setting.substring(0, colonAt);
+                String value = setting.substring(colonAt + 1);
+
+                if (name.equals("region")) {
+                    mCue.mRegionId = value;
+                } else if (name.equals("vertical")) {
+                    if (value.equals("rl")) {
+                        mCue.mWritingDirection =
+                            TextTrackCue.WRITING_DIRECTION_VERTICAL_RL;
+                    } else if (value.equals("lr")) {
+                        mCue.mWritingDirection =
+                            TextTrackCue.WRITING_DIRECTION_VERTICAL_LR;
+                    } else {
+                        log_warning("cue setting", name, "has invalid value", value);
+                    }
+                } else if (name.equals("line")) {
+                    try {
+                        int linePosition;
+                        /* TRICKY: we know that there are no spaces in value */
+                        assert(value.indexOf(' ') < 0);
+                        if (value.endsWith("%")) {
+                            linePosition = Integer.parseInt(
+                                    value.substring(0, value.length() - 1));
+                            if (linePosition < 0 || linePosition > 100) {
+                                log_warning("cue setting", name, "is out of range", value);
+                                continue;
+                            }
+                            mCue.mSnapToLines = false;
+                            mCue.mLinePosition = linePosition;
+                        } else {
+                            mCue.mSnapToLines = true;
+                            mCue.mLinePosition = Integer.parseInt(value);
+                        }
+                    } catch (NumberFormatException e) {
+                        log_warning("cue setting", name,
+                               "is not numeric or percentage", value);
+                    }
+                } else if (name.equals("position")) {
+                    try {
+                        mCue.mTextPosition = parseIntPercentage(value);
+                    } catch (NumberFormatException e) {
+                        log_warning("cue setting", name,
+                               "is not numeric or percentage", value);
+                    }
+                } else if (name.equals("size")) {
+                    try {
+                        mCue.mSize = parseIntPercentage(value);
+                    } catch (NumberFormatException e) {
+                        log_warning("cue setting", name,
+                               "is not numeric or percentage", value);
+                    }
+                } else if (name.equals("align")) {
+                    if (value.equals("start")) {
+                        mCue.mAlignment = TextTrackCue.ALIGNMENT_START;
+                    } else if (value.equals("middle")) {
+                        mCue.mAlignment = TextTrackCue.ALIGNMENT_MIDDLE;
+                    } else if (value.equals("end")) {
+                        mCue.mAlignment = TextTrackCue.ALIGNMENT_END;
+                    } else if (value.equals("left")) {
+                        mCue.mAlignment = TextTrackCue.ALIGNMENT_LEFT;
+                    } else if (value.equals("right")) {
+                        mCue.mAlignment = TextTrackCue.ALIGNMENT_RIGHT;
+                    } else {
+                        log_warning("cue setting", name, "has invalid value", value);
+                        continue;
+                    }
+                }
+            }
+
+            if (mCue.mLinePosition != null ||
+                    mCue.mSize != 100 ||
+                    (mCue.mWritingDirection !=
+                        TextTrackCue.WRITING_DIRECTION_HORIZONTAL)) {
+                mCue.mRegionId = "";
+            }
+
+            mPhase = mParseCueText;
+        }
+    };
+
+    /* also used for notes */
+    final private Phase mParseCueText = new Phase() {
+        @Override
+        public void parse(String line) {
+            if (line.length() == 0) {
+                yieldCue();
+                mPhase = mParseCueId;
+                return;
+            } else if (mCue != null) {
+                mCueTexts.add(line);
+            }
+        }
+    };
+
+    private void log_warning(
+            String nameType, String name, String message,
+            String subMessage, String value) {
+        Log.w(this.getClass().getName(), nameType + " '" + name + "' " +
+                message + " ('" + value + "' " + subMessage + ")");
+    }
+
+    private void log_warning(
+            String nameType, String name, String message, String value) {
+        Log.w(this.getClass().getName(), nameType + " '" + name + "' " +
+                message + " ('" + value + "')");
+    }
+
+    private void log_warning(String message, String value) {
+        Log.w(this.getClass().getName(), message + " ('" + value + "')");
+    }
+}
+
+/** @hide */
+interface WebVttCueListener {
+    void onCueParsed(TextTrackCue cue);
+    void onRegionParsed(TextTrackRegion region);
+}
+
+/** @hide */
+class WebVttTrack extends SubtitleTrack implements WebVttCueListener {
+    private static final String TAG = "WebVttTrack";
+
+    private final WebVttParser mParser = new WebVttParser(this);
+    private final UnstyledTextExtractor mExtractor =
+        new UnstyledTextExtractor();
+    private final Tokenizer mTokenizer = new Tokenizer(mExtractor);
+    private final Vector<Long> mTimestamps = new Vector<Long>();
+    private final WebVttRenderingWidget mRenderingWidget;
+
+    private final Map<String, TextTrackRegion> mRegions =
+        new HashMap<String, TextTrackRegion>();
+    private Long mCurrentRunID;
+
+    WebVttTrack(WebVttRenderingWidget renderingWidget, MediaFormat format) {
+        super(format);
+
+        mRenderingWidget = renderingWidget;
+    }
+
+    @Override
+    public WebVttRenderingWidget getRenderingWidget() {
+        return mRenderingWidget;
+    }
+
+    @Override
+    public void onData(String data, boolean eos, long runID) {
+        // implement intermixing restriction for WebVTT only for now
+        synchronized(mParser) {
+            if (mCurrentRunID != null && runID != mCurrentRunID) {
+                throw new IllegalStateException(
+                        "Run #" + mCurrentRunID +
+                        " in progress.  Cannot process run #" + runID);
+            }
+            mCurrentRunID = runID;
+            mParser.parse(data);
+            if (eos) {
+                finishedRun(runID);
+                mParser.eos();
+                mRegions.clear();
+                mCurrentRunID = null;
+            }
+        }
+    }
+
+    @Override
+    public void onCueParsed(TextTrackCue cue) {
+        synchronized (mParser) {
+            // resolve region
+            if (cue.mRegionId.length() != 0) {
+                cue.mRegion = mRegions.get(cue.mRegionId);
+            }
+
+            if (DEBUG) Log.v(TAG, "adding cue " + cue);
+
+            // tokenize text track string-lines into lines of spans
+            mTokenizer.reset();
+            for (String s: cue.mStrings) {
+                mTokenizer.tokenize(s);
+            }
+            cue.mLines = mExtractor.getText();
+            if (DEBUG) Log.v(TAG, cue.appendLinesToBuilder(
+                    cue.appendStringsToBuilder(
+                        new StringBuilder()).append(" simplified to: "))
+                            .toString());
+
+            // extract inner timestamps
+            for (TextTrackCueSpan[] line: cue.mLines) {
+                for (TextTrackCueSpan span: line) {
+                    if (span.mTimestampMs > cue.mStartTimeMs &&
+                            span.mTimestampMs < cue.mEndTimeMs &&
+                            !mTimestamps.contains(span.mTimestampMs)) {
+                        mTimestamps.add(span.mTimestampMs);
+                    }
+                }
+            }
+
+            if (mTimestamps.size() > 0) {
+                cue.mInnerTimesMs = new long[mTimestamps.size()];
+                for (int ix=0; ix < mTimestamps.size(); ++ix) {
+                    cue.mInnerTimesMs[ix] = mTimestamps.get(ix);
+                }
+                mTimestamps.clear();
+            } else {
+                cue.mInnerTimesMs = null;
+            }
+
+            cue.mRunID = mCurrentRunID;
+        }
+
+        addCue(cue);
+    }
+
+    @Override
+    public void onRegionParsed(TextTrackRegion region) {
+        synchronized(mParser) {
+            mRegions.put(region.mId, region);
+        }
+    }
+
+    @Override
+    public void updateView(Vector<SubtitleTrack.Cue> activeCues) {
+        if (!mVisible) {
+            // don't keep the state if we are not visible
+            return;
+        }
+
+        if (DEBUG && mTimeProvider != null) {
+            try {
+                Log.d(TAG, "at " +
+                        (mTimeProvider.getCurrentTimeUs(false, true) / 1000) +
+                        " ms the active cues are:");
+            } catch (IllegalStateException e) {
+                Log.d(TAG, "at (illegal state) the active cues are:");
+            }
+        }
+
+        mRenderingWidget.setActiveCues(activeCues);
+    }
+}
+
+/**
+ * Widget capable of rendering WebVTT captions.
+ *
+ * @hide
+ */
+class WebVttRenderingWidget extends ViewGroup implements SubtitleTrack.RenderingWidget {
+    private static final boolean DEBUG = false;
+    private static final int DEBUG_REGION_BACKGROUND = 0x800000FF;
+    private static final int DEBUG_CUE_BACKGROUND = 0x80FF0000;
+
+    /** WebVtt specifies line height as 5.3% of the viewport height. */
+    private static final float LINE_HEIGHT_RATIO = 0.0533f;
+
+    /** Map of active regions, used to determine enter/exit. */
+    private final ArrayMap<TextTrackRegion, RegionLayout> mRegionBoxes =
+            new ArrayMap<TextTrackRegion, RegionLayout>();
+
+    /** Map of active cues, used to determine enter/exit. */
+    private final ArrayMap<TextTrackCue, CueLayout> mCueBoxes =
+            new ArrayMap<TextTrackCue, CueLayout>();
+
+    /** Captioning manager, used to obtain and track caption properties. */
+    private final CaptioningManager mManager;
+
+    /** Callback for rendering changes. */
+    private OnChangedListener mListener;
+
+    /** Current caption style. */
+    private CaptionStyle mCaptionStyle;
+
+    /** Current font size, computed from font scaling factor and height. */
+    private float mFontSize;
+
+    /** Whether a caption style change listener is registered. */
+    private boolean mHasChangeListener;
+
+    public WebVttRenderingWidget(Context context) {
+        this(context, null);
+    }
+
+    public WebVttRenderingWidget(Context context, AttributeSet attrs) {
+        this(context, null, 0);
+    }
+
+    public WebVttRenderingWidget(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        // Cannot render text over video when layer type is hardware.
+        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
+
+        mManager = (CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE);
+        mCaptionStyle = mManager.getUserStyle();
+        mFontSize = mManager.getFontScale() * getHeight() * LINE_HEIGHT_RATIO;
+    }
+
+    @Override
+    public void setSize(int width, int height) {
+        final int widthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
+        final int heightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
+
+        measure(widthSpec, heightSpec);
+        layout(0, 0, width, height);
+    }
+
+    @Override
+    public void onAttachedToWindow() {
+        super.onAttachedToWindow();
+
+        manageChangeListener();
+    }
+
+    @Override
+    public void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+
+        manageChangeListener();
+    }
+
+    @Override
+    public void setOnChangedListener(OnChangedListener listener) {
+        mListener = listener;
+    }
+
+    @Override
+    public void setVisible(boolean visible) {
+        if (visible) {
+            setVisibility(View.VISIBLE);
+        } else {
+            setVisibility(View.GONE);
+        }
+
+        manageChangeListener();
+    }
+
+    /**
+     * Manages whether this renderer is listening for caption style changes.
+     */
+    private void manageChangeListener() {
+        final boolean needsListener = isAttachedToWindow() && getVisibility() == View.VISIBLE;
+        if (mHasChangeListener != needsListener) {
+            mHasChangeListener = needsListener;
+
+            if (needsListener) {
+                mManager.addCaptioningChangeListener(mCaptioningListener);
+
+                final CaptionStyle captionStyle = mManager.getUserStyle();
+                final float fontSize = mManager.getFontScale() * getHeight() * LINE_HEIGHT_RATIO;
+                setCaptionStyle(captionStyle, fontSize);
+            } else {
+                mManager.removeCaptioningChangeListener(mCaptioningListener);
+            }
+        }
+    }
+
+    public void setActiveCues(Vector<SubtitleTrack.Cue> activeCues) {
+        final Context context = getContext();
+        final CaptionStyle captionStyle = mCaptionStyle;
+        final float fontSize = mFontSize;
+
+        prepForPrune();
+
+        // Ensure we have all necessary cue and region boxes.
+        final int count = activeCues.size();
+        for (int i = 0; i < count; i++) {
+            final TextTrackCue cue = (TextTrackCue) activeCues.get(i);
+            final TextTrackRegion region = cue.mRegion;
+            if (region != null) {
+                RegionLayout regionBox = mRegionBoxes.get(region);
+                if (regionBox == null) {
+                    regionBox = new RegionLayout(context, region, captionStyle, fontSize);
+                    mRegionBoxes.put(region, regionBox);
+                    addView(regionBox, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+                }
+                regionBox.put(cue);
+            } else {
+                CueLayout cueBox = mCueBoxes.get(cue);
+                if (cueBox == null) {
+                    cueBox = new CueLayout(context, cue, captionStyle, fontSize);
+                    mCueBoxes.put(cue, cueBox);
+                    addView(cueBox, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+                }
+                cueBox.update();
+                cueBox.setOrder(i);
+            }
+        }
+
+        prune();
+
+        // Force measurement and layout.
+        final int width = getWidth();
+        final int height = getHeight();
+        setSize(width, height);
+
+        if (mListener != null) {
+            mListener.onChanged(this);
+        }
+    }
+
+    private void setCaptionStyle(CaptionStyle captionStyle, float fontSize) {
+        mCaptionStyle = captionStyle;
+        mFontSize = fontSize;
+
+        final int cueCount = mCueBoxes.size();
+        for (int i = 0; i < cueCount; i++) {
+            final CueLayout cueBox = mCueBoxes.valueAt(i);
+            cueBox.setCaptionStyle(captionStyle, fontSize);
+        }
+
+        final int regionCount = mRegionBoxes.size();
+        for (int i = 0; i < regionCount; i++) {
+            final RegionLayout regionBox = mRegionBoxes.valueAt(i);
+            regionBox.setCaptionStyle(captionStyle, fontSize);
+        }
+    }
+
+    /**
+     * Remove inactive cues and regions.
+     */
+    private void prune() {
+        int regionCount = mRegionBoxes.size();
+        for (int i = 0; i < regionCount; i++) {
+            final RegionLayout regionBox = mRegionBoxes.valueAt(i);
+            if (regionBox.prune()) {
+                removeView(regionBox);
+                mRegionBoxes.removeAt(i);
+                regionCount--;
+                i--;
+            }
+        }
+
+        int cueCount = mCueBoxes.size();
+        for (int i = 0; i < cueCount; i++) {
+            final CueLayout cueBox = mCueBoxes.valueAt(i);
+            if (!cueBox.isActive()) {
+                removeView(cueBox);
+                mCueBoxes.removeAt(i);
+                cueCount--;
+                i--;
+            }
+        }
+    }
+
+    /**
+     * Reset active cues and regions.
+     */
+    private void prepForPrune() {
+        final int regionCount = mRegionBoxes.size();
+        for (int i = 0; i < regionCount; i++) {
+            final RegionLayout regionBox = mRegionBoxes.valueAt(i);
+            regionBox.prepForPrune();
+        }
+
+        final int cueCount = mCueBoxes.size();
+        for (int i = 0; i < cueCount; i++) {
+            final CueLayout cueBox = mCueBoxes.valueAt(i);
+            cueBox.prepForPrune();
+        }
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+        final int regionCount = mRegionBoxes.size();
+        for (int i = 0; i < regionCount; i++) {
+            final RegionLayout regionBox = mRegionBoxes.valueAt(i);
+            regionBox.measureForParent(widthMeasureSpec, heightMeasureSpec);
+        }
+
+        final int cueCount = mCueBoxes.size();
+        for (int i = 0; i < cueCount; i++) {
+            final CueLayout cueBox = mCueBoxes.valueAt(i);
+            cueBox.measureForParent(widthMeasureSpec, heightMeasureSpec);
+        }
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        final int viewportWidth = r - l;
+        final int viewportHeight = b - t;
+
+        setCaptionStyle(mCaptionStyle,
+                mManager.getFontScale() * LINE_HEIGHT_RATIO * viewportHeight);
+
+        final int regionCount = mRegionBoxes.size();
+        for (int i = 0; i < regionCount; i++) {
+            final RegionLayout regionBox = mRegionBoxes.valueAt(i);
+            layoutRegion(viewportWidth, viewportHeight, regionBox);
+        }
+
+        final int cueCount = mCueBoxes.size();
+        for (int i = 0; i < cueCount; i++) {
+            final CueLayout cueBox = mCueBoxes.valueAt(i);
+            layoutCue(viewportWidth, viewportHeight, cueBox);
+        }
+    }
+
+    /**
+     * Lays out a region within the viewport. The region handles layout for
+     * contained cues.
+     */
+    private void layoutRegion(
+            int viewportWidth, int viewportHeight,
+            RegionLayout regionBox) {
+        final TextTrackRegion region = regionBox.getRegion();
+        final int regionHeight = regionBox.getMeasuredHeight();
+        final int regionWidth = regionBox.getMeasuredWidth();
+
+        // TODO: Account for region anchor point.
+        final float x = region.mViewportAnchorPointX;
+        final float y = region.mViewportAnchorPointY;
+        final int left = (int) (x * (viewportWidth - regionWidth) / 100);
+        final int top = (int) (y * (viewportHeight - regionHeight) / 100);
+
+        regionBox.layout(left, top, left + regionWidth, top + regionHeight);
+    }
+
+    /**
+     * Lays out a cue within the viewport.
+     */
+    private void layoutCue(
+            int viewportWidth, int viewportHeight, CueLayout cueBox) {
+        final TextTrackCue cue = cueBox.getCue();
+        final int direction = getLayoutDirection();
+        final int absAlignment = resolveCueAlignment(direction, cue.mAlignment);
+        final boolean cueSnapToLines = cue.mSnapToLines;
+
+        int size = 100 * cueBox.getMeasuredWidth() / viewportWidth;
+
+        // Determine raw x-position.
+        int xPosition;
+        switch (absAlignment) {
+            case TextTrackCue.ALIGNMENT_LEFT:
+                xPosition = cue.mTextPosition;
+                break;
+            case TextTrackCue.ALIGNMENT_RIGHT:
+                xPosition = cue.mTextPosition - size;
+                break;
+            case TextTrackCue.ALIGNMENT_MIDDLE:
+            default:
+                xPosition = cue.mTextPosition - size / 2;
+                break;
+        }
+
+        // Adjust x-position for layout.
+        if (direction == LAYOUT_DIRECTION_RTL) {
+            xPosition = 100 - xPosition;
+        }
+
+        // If the text track cue snap-to-lines flag is set, adjust
+        // x-position and size for padding. This is equivalent to placing the
+        // cue within the title-safe area.
+        if (cueSnapToLines) {
+            final int paddingLeft = 100 * getPaddingLeft() / viewportWidth;
+            final int paddingRight = 100 * getPaddingRight() / viewportWidth;
+            if (xPosition < paddingLeft && xPosition + size > paddingLeft) {
+                xPosition += paddingLeft;
+                size -= paddingLeft;
+            }
+            final float rightEdge = 100 - paddingRight;
+            if (xPosition < rightEdge && xPosition + size > rightEdge) {
+                size -= paddingRight;
+            }
+        }
+
+        // Compute absolute left position and width.
+        final int left = xPosition * viewportWidth / 100;
+        final int width = size * viewportWidth / 100;
+
+        // Determine initial y-position.
+        final int yPosition = calculateLinePosition(cueBox);
+
+        // Compute absolute final top position and height.
+        final int height = cueBox.getMeasuredHeight();
+        final int top;
+        if (yPosition < 0) {
+            // TODO: This needs to use the actual height of prior boxes.
+            top = viewportHeight + yPosition * height;
+        } else {
+            top = yPosition * (viewportHeight - height) / 100;
+        }
+
+        // Layout cue in final position.
+        cueBox.layout(left, top, left + width, top + height);
+    }
+
+    /**
+     * Calculates the line position for a cue.
+     * <p>
+     * If the resulting position is negative, it represents a bottom-aligned
+     * position relative to the number of active cues. Otherwise, it represents
+     * a percentage [0-100] of the viewport height.
+     */
+    private int calculateLinePosition(CueLayout cueBox) {
+        final TextTrackCue cue = cueBox.getCue();
+        final Integer linePosition = cue.mLinePosition;
+        final boolean snapToLines = cue.mSnapToLines;
+        final boolean autoPosition = (linePosition == null);
+
+        if (!snapToLines && !autoPosition && (linePosition < 0 || linePosition > 100)) {
+            // Invalid line position defaults to 100.
+            return 100;
+        } else if (!autoPosition) {
+            // Use the valid, supplied line position.
+            return linePosition;
+        } else if (!snapToLines) {
+            // Automatic, non-snapped line position defaults to 100.
+            return 100;
+        } else {
+            // Automatic snapped line position uses active cue order.
+            return -(cueBox.mOrder + 1);
+        }
+    }
+
+    /**
+     * Resolves cue alignment according to the specified layout direction.
+     */
+    private static int resolveCueAlignment(int layoutDirection, int alignment) {
+        switch (alignment) {
+            case TextTrackCue.ALIGNMENT_START:
+                return layoutDirection == View.LAYOUT_DIRECTION_LTR ?
+                        TextTrackCue.ALIGNMENT_LEFT : TextTrackCue.ALIGNMENT_RIGHT;
+            case TextTrackCue.ALIGNMENT_END:
+                return layoutDirection == View.LAYOUT_DIRECTION_LTR ?
+                        TextTrackCue.ALIGNMENT_RIGHT : TextTrackCue.ALIGNMENT_LEFT;
+        }
+        return alignment;
+    }
+
+    private final CaptioningChangeListener mCaptioningListener = new CaptioningChangeListener() {
+        @Override
+        public void onFontScaleChanged(float fontScale) {
+            final float fontSize = fontScale * getHeight() * LINE_HEIGHT_RATIO;
+            setCaptionStyle(mCaptionStyle, fontSize);
+        }
+
+        @Override
+        public void onUserStyleChanged(CaptionStyle userStyle) {
+            setCaptionStyle(userStyle, mFontSize);
+        }
+    };
+
+    /**
+     * A text track region represents a portion of the video viewport and
+     * provides a rendering area for text track cues.
+     */
+    private static class RegionLayout extends LinearLayout {
+        private final ArrayList<CueLayout> mRegionCueBoxes = new ArrayList<CueLayout>();
+        private final TextTrackRegion mRegion;
+
+        private CaptionStyle mCaptionStyle;
+        private float mFontSize;
+
+        public RegionLayout(Context context, TextTrackRegion region, CaptionStyle captionStyle,
+                float fontSize) {
+            super(context);
+
+            mRegion = region;
+            mCaptionStyle = captionStyle;
+            mFontSize = fontSize;
+
+            // TODO: Add support for vertical text
+            setOrientation(VERTICAL);
+
+            if (DEBUG) {
+                setBackgroundColor(DEBUG_REGION_BACKGROUND);
+            }
+        }
+
+        public void setCaptionStyle(CaptionStyle captionStyle, float fontSize) {
+            mCaptionStyle = captionStyle;
+            mFontSize = fontSize;
+
+            final int cueCount = mRegionCueBoxes.size();
+            for (int i = 0; i < cueCount; i++) {
+                final CueLayout cueBox = mRegionCueBoxes.get(i);
+                cueBox.setCaptionStyle(captionStyle, fontSize);
+            }
+        }
+
+        /**
+         * Performs the parent's measurement responsibilities, then
+         * automatically performs its own measurement.
+         */
+        public void measureForParent(int widthMeasureSpec, int heightMeasureSpec) {
+            final TextTrackRegion region = mRegion;
+            final int specWidth = MeasureSpec.getSize(widthMeasureSpec);
+            final int specHeight = MeasureSpec.getSize(heightMeasureSpec);
+            final int width = (int) region.mWidth;
+
+            // Determine the absolute maximum region size as the requested size.
+            final int size = width * specWidth / 100;
+
+            widthMeasureSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.AT_MOST);
+            heightMeasureSpec = MeasureSpec.makeMeasureSpec(specHeight, MeasureSpec.AT_MOST);
+            measure(widthMeasureSpec, heightMeasureSpec);
+        }
+
+        /**
+         * Prepares this region for pruning by setting all tracks as inactive.
+         * <p>
+         * Tracks that are added or updated using {@link #put(TextTrackCue)}
+         * after this calling this method will be marked as active.
+         */
+        public void prepForPrune() {
+            final int cueCount = mRegionCueBoxes.size();
+            for (int i = 0; i < cueCount; i++) {
+                final CueLayout cueBox = mRegionCueBoxes.get(i);
+                cueBox.prepForPrune();
+            }
+        }
+
+        /**
+         * Adds a {@link TextTrackCue} to this region. If the track had already
+         * been added, updates its active state.
+         *
+         * @param cue
+         */
+        public void put(TextTrackCue cue) {
+            final int cueCount = mRegionCueBoxes.size();
+            for (int i = 0; i < cueCount; i++) {
+                final CueLayout cueBox = mRegionCueBoxes.get(i);
+                if (cueBox.getCue() == cue) {
+                    cueBox.update();
+                    return;
+                }
+            }
+
+            final CueLayout cueBox = new CueLayout(getContext(), cue, mCaptionStyle, mFontSize);
+            addView(cueBox, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+
+            if (getChildCount() > mRegion.mLines) {
+                removeViewAt(0);
+            }
+        }
+
+        /**
+         * Remove all inactive tracks from this region.
+         *
+         * @return true if this region is empty and should be pruned
+         */
+        public boolean prune() {
+            int cueCount = mRegionCueBoxes.size();
+            for (int i = 0; i < cueCount; i++) {
+                final CueLayout cueBox = mRegionCueBoxes.get(i);
+                if (!cueBox.isActive()) {
+                    mRegionCueBoxes.remove(i);
+                    removeView(cueBox);
+                    cueCount--;
+                    i--;
+                }
+            }
+
+            return mRegionCueBoxes.isEmpty();
+        }
+
+        /**
+         * @return the region data backing this layout
+         */
+        public TextTrackRegion getRegion() {
+            return mRegion;
+        }
+    }
+
+    /**
+     * A text track cue is the unit of time-sensitive data in a text track,
+     * corresponding for instance for subtitles and captions to the text that
+     * appears at a particular time and disappears at another time.
+     * <p>
+     * A single cue may contain multiple {@link SpanLayout}s, each representing a
+     * single line of text.
+     */
+    private static class CueLayout extends LinearLayout {
+        public final TextTrackCue mCue;
+
+        private CaptionStyle mCaptionStyle;
+        private float mFontSize;
+
+        private boolean mActive;
+        private int mOrder;
+
+        public CueLayout(
+                Context context, TextTrackCue cue, CaptionStyle captionStyle, float fontSize) {
+            super(context);
+
+            mCue = cue;
+            mCaptionStyle = captionStyle;
+            mFontSize = fontSize;
+
+            // TODO: Add support for vertical text.
+            final boolean horizontal = cue.mWritingDirection
+                    == TextTrackCue.WRITING_DIRECTION_HORIZONTAL;
+            setOrientation(horizontal ? VERTICAL : HORIZONTAL);
+
+            switch (cue.mAlignment) {
+                case TextTrackCue.ALIGNMENT_END:
+                    setGravity(Gravity.END);
+                    break;
+                case TextTrackCue.ALIGNMENT_LEFT:
+                    setGravity(Gravity.LEFT);
+                    break;
+                case TextTrackCue.ALIGNMENT_MIDDLE:
+                    setGravity(horizontal
+                            ? Gravity.CENTER_HORIZONTAL : Gravity.CENTER_VERTICAL);
+                    break;
+                case TextTrackCue.ALIGNMENT_RIGHT:
+                    setGravity(Gravity.RIGHT);
+                    break;
+                case TextTrackCue.ALIGNMENT_START:
+                    setGravity(Gravity.START);
+                    break;
+            }
+
+            if (DEBUG) {
+                setBackgroundColor(DEBUG_CUE_BACKGROUND);
+            }
+
+            update();
+        }
+
+        public void setCaptionStyle(CaptionStyle style, float fontSize) {
+            mCaptionStyle = style;
+            mFontSize = fontSize;
+
+            final int n = getChildCount();
+            for (int i = 0; i < n; i++) {
+                final View child = getChildAt(i);
+                if (child instanceof SpanLayout) {
+                    ((SpanLayout) child).setCaptionStyle(style, fontSize);
+                }
+            }
+        }
+
+        public void prepForPrune() {
+            mActive = false;
+        }
+
+        public void update() {
+            mActive = true;
+
+            removeAllViews();
+
+            final CaptionStyle captionStyle = mCaptionStyle;
+            final float fontSize = mFontSize;
+            final TextTrackCueSpan[][] lines = mCue.mLines;
+            final int lineCount = lines.length;
+            for (int i = 0; i < lineCount; i++) {
+                final SpanLayout lineBox = new SpanLayout(getContext(), lines[i]);
+                lineBox.setCaptionStyle(captionStyle, fontSize);
+
+                addView(lineBox, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+            }
+        }
+
+        @Override
+        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        }
+
+        /**
+         * Performs the parent's measurement responsibilities, then
+         * automatically performs its own measurement.
+         */
+        public void measureForParent(int widthMeasureSpec, int heightMeasureSpec) {
+            final TextTrackCue cue = mCue;
+            final int specWidth = MeasureSpec.getSize(widthMeasureSpec);
+            final int specHeight = MeasureSpec.getSize(heightMeasureSpec);
+            final int direction = getLayoutDirection();
+            final int absAlignment = resolveCueAlignment(direction, cue.mAlignment);
+
+            // Determine the maximum size of cue based on its starting position
+            // and the direction in which it grows.
+            final int maximumSize;
+            switch (absAlignment) {
+                case TextTrackCue.ALIGNMENT_LEFT:
+                    maximumSize = 100 - cue.mTextPosition;
+                    break;
+                case TextTrackCue.ALIGNMENT_RIGHT:
+                    maximumSize = cue.mTextPosition;
+                    break;
+                case TextTrackCue.ALIGNMENT_MIDDLE:
+                    if (cue.mTextPosition <= 50) {
+                        maximumSize = cue.mTextPosition * 2;
+                    } else {
+                        maximumSize = (100 - cue.mTextPosition) * 2;
+                    }
+                    break;
+                default:
+                    maximumSize = 0;
+            }
+
+            // Determine absolute maximum cue size as the smaller of the
+            // requested size and the maximum theoretical size.
+            final int size = Math.min(cue.mSize, maximumSize) * specWidth / 100;
+            widthMeasureSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.AT_MOST);
+            heightMeasureSpec = MeasureSpec.makeMeasureSpec(specHeight, MeasureSpec.AT_MOST);
+            measure(widthMeasureSpec, heightMeasureSpec);
+        }
+
+        /**
+         * Sets the order of this cue in the list of active cues.
+         *
+         * @param order the order of this cue in the list of active cues
+         */
+        public void setOrder(int order) {
+            mOrder = order;
+        }
+
+        /**
+         * @return whether this cue is marked as active
+         */
+        public boolean isActive() {
+            return mActive;
+        }
+
+        /**
+         * @return the cue data backing this layout
+         */
+        public TextTrackCue getCue() {
+            return mCue;
+        }
+    }
+
+    /**
+     * A text track line represents a single line of text within a cue.
+     * <p>
+     * A single line may contain multiple spans, each representing a section of
+     * text that may be enabled or disabled at a particular time.
+     */
+    private static class SpanLayout extends SubtitleView {
+        private final SpannableStringBuilder mBuilder = new SpannableStringBuilder();
+        private final TextTrackCueSpan[] mSpans;
+
+        public SpanLayout(Context context, TextTrackCueSpan[] spans) {
+            super(context);
+
+            mSpans = spans;
+
+            update();
+        }
+
+        public void update() {
+            final SpannableStringBuilder builder = mBuilder;
+            final TextTrackCueSpan[] spans = mSpans;
+
+            builder.clear();
+            builder.clearSpans();
+
+            final int spanCount = spans.length;
+            for (int i = 0; i < spanCount; i++) {
+                final TextTrackCueSpan span = spans[i];
+                if (span.mEnabled) {
+                    builder.append(spans[i].mText);
+                }
+            }
+
+            setText(builder);
+        }
+
+        public void setCaptionStyle(CaptionStyle captionStyle, float fontSize) {
+            setBackgroundColor(captionStyle.backgroundColor);
+            setForegroundColor(captionStyle.foregroundColor);
+            setEdgeColor(captionStyle.edgeColor);
+            setEdgeType(captionStyle.edgeType);
+            setTypeface(captionStyle.getTypeface());
+            setTextSize(fontSize);
+        }
+    }
+}
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index 416a2a1..63a61e2 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -2,6 +2,7 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
+    android_media_ImageReader.cpp \
     android_media_MediaCrypto.cpp \
     android_media_MediaCodec.cpp \
     android_media_MediaCodecList.cpp \
@@ -56,6 +57,8 @@
     frameworks/av/media/libstagefright/codecs/amrnb/common/include \
     frameworks/av/media/mtp \
     frameworks/native/include/media/openmax \
+    $(call include-path-for, libhardware)/hardware \
+    system/media/camera/include \
     $(PV_INCLUDES) \
     $(JNI_H_INCLUDE) \
     $(call include-path-for, corecg graphics)
diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp
new file mode 100644
index 0000000..94f20bc
--- /dev/null
+++ b/media/jni/android_media_ImageReader.cpp
@@ -0,0 +1,877 @@
+/*
+ * Copyright 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ImageReader_JNI"
+#include <utils/Log.h>
+#include <utils/misc.h>
+#include <utils/List.h>
+#include <utils/String8.h>
+
+#include <cstdio>
+
+#include <gui/CpuConsumer.h>
+#include <gui/Surface.h>
+#include <camera3.h>
+
+#include <android_runtime/AndroidRuntime.h>
+#include <android_runtime/android_view_Surface.h>
+
+#include <jni.h>
+#include <JNIHelp.h>
+
+#define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) )
+
+#define ANDROID_MEDIA_IMAGEREADER_CTX_JNI_ID       "mNativeContext"
+#define ANDROID_MEDIA_SURFACEIMAGE_BUFFER_JNI_ID   "mLockedBuffer"
+#define ANDROID_MEDIA_SURFACEIMAGE_TS_JNI_ID       "mTimestamp"
+
+// ----------------------------------------------------------------------------
+
+using namespace android;
+
+static const char* const OutOfResourcesException =
+    "android/view/Surface$OutOfResourcesException";
+
+enum {
+    IMAGE_READER_MAX_NUM_PLANES = 3,
+};
+
+static struct {
+    jfieldID mNativeContext;
+    jmethodID postEventFromNative;
+} gImageReaderClassInfo;
+
+static struct {
+    jfieldID mLockedBuffer;
+    jfieldID mTimestamp;
+} gSurfaceImageClassInfo;
+
+static struct {
+    jclass clazz;
+    jmethodID ctor;
+} gSurfacePlaneClassInfo;
+
+// ----------------------------------------------------------------------------
+
+class JNIImageReaderContext : public CpuConsumer::FrameAvailableListener
+{
+public:
+    JNIImageReaderContext(JNIEnv* env, jobject weakThiz, jclass clazz, int maxImages);
+
+    virtual ~JNIImageReaderContext();
+
+    virtual void onFrameAvailable();
+
+    CpuConsumer::LockedBuffer* getLockedBuffer();
+
+    void returnLockedBuffer(CpuConsumer::LockedBuffer* buffer);
+
+    void setCpuConsumer(const sp<CpuConsumer>& consumer) { mConsumer = consumer; }
+    CpuConsumer* getCpuConsumer() { return mConsumer.get(); }
+
+    void setBufferQueue(const sp<BufferQueue>& bq) { mBufferQueue = bq; }
+    BufferQueue* getBufferQueue() { return mBufferQueue.get(); }
+
+    void setBufferFormat(int format) { mFormat = format; }
+    int getBufferFormat() { return mFormat; }
+
+    void setBufferWidth(int width) { mWidth = width; }
+    int getBufferWidth() { return mWidth; }
+
+    void setBufferHeight(int height) { mHeight = height; }
+    int getBufferHeight() { return mHeight; }
+
+private:
+    static JNIEnv* getJNIEnv(bool* needsDetach);
+    static void detachJNI();
+
+    List<CpuConsumer::LockedBuffer*> mBuffers;
+    sp<CpuConsumer> mConsumer;
+    sp<BufferQueue> mBufferQueue;
+    jobject mWeakThiz;
+    jclass mClazz;
+    int mFormat;
+    int mWidth;
+    int mHeight;
+};
+
+JNIImageReaderContext::JNIImageReaderContext(JNIEnv* env,
+        jobject weakThiz, jclass clazz, int maxImages) :
+    mWeakThiz(env->NewGlobalRef(weakThiz)),
+    mClazz((jclass)env->NewGlobalRef(clazz)) {
+    for (int i = 0; i < maxImages; i++) {
+        CpuConsumer::LockedBuffer *buffer = new CpuConsumer::LockedBuffer;
+        mBuffers.push_back(buffer);
+    }
+}
+
+JNIEnv* JNIImageReaderContext::getJNIEnv(bool* needsDetach) {
+    LOG_ALWAYS_FATAL_IF(needsDetach == NULL, "needsDetach is null!!!");
+    *needsDetach = false;
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    if (env == NULL) {
+        JavaVMAttachArgs args = {JNI_VERSION_1_4, NULL, NULL};
+        JavaVM* vm = AndroidRuntime::getJavaVM();
+        int result = vm->AttachCurrentThread(&env, (void*) &args);
+        if (result != JNI_OK) {
+            ALOGE("thread attach failed: %#x", result);
+            return NULL;
+        }
+        *needsDetach = true;
+    }
+    return env;
+}
+
+void JNIImageReaderContext::detachJNI() {
+    JavaVM* vm = AndroidRuntime::getJavaVM();
+    int result = vm->DetachCurrentThread();
+    if (result != JNI_OK) {
+        ALOGE("thread detach failed: %#x", result);
+    }
+}
+
+CpuConsumer::LockedBuffer* JNIImageReaderContext::getLockedBuffer() {
+    if (mBuffers.empty()) {
+        return NULL;
+    }
+    // Return a LockedBuffer pointer and remove it from the list
+    List<CpuConsumer::LockedBuffer*>::iterator it = mBuffers.begin();
+    CpuConsumer::LockedBuffer* buffer = *it;
+    mBuffers.erase(it);
+    return buffer;
+}
+
+void JNIImageReaderContext::returnLockedBuffer(CpuConsumer::LockedBuffer* buffer) {
+    mBuffers.push_back(buffer);
+}
+
+JNIImageReaderContext::~JNIImageReaderContext() {
+    bool needsDetach = false;
+    JNIEnv* env = getJNIEnv(&needsDetach);
+    if (env != NULL) {
+        env->DeleteGlobalRef(mWeakThiz);
+        env->DeleteGlobalRef(mClazz);
+    } else {
+        ALOGW("leaking JNI object references");
+    }
+    if (needsDetach) {
+        detachJNI();
+    }
+
+    // Delete LockedBuffers
+    for (List<CpuConsumer::LockedBuffer *>::iterator it = mBuffers.begin();
+            it != mBuffers.end(); it++) {
+        delete *it;
+    }
+    mBuffers.clear();
+    mConsumer.clear();
+}
+
+void JNIImageReaderContext::onFrameAvailable()
+{
+    ALOGV("%s: frame available", __FUNCTION__);
+    bool needsDetach = false;
+    JNIEnv* env = getJNIEnv(&needsDetach);
+    if (env != NULL) {
+        env->CallStaticVoidMethod(mClazz, gImageReaderClassInfo.postEventFromNative, mWeakThiz);
+    } else {
+        ALOGW("onFrameAvailable event will not posted");
+    }
+    if (needsDetach) {
+        detachJNI();
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+extern "C" {
+
+static JNIImageReaderContext* ImageReader_getContext(JNIEnv* env, jobject thiz)
+{
+    JNIImageReaderContext *ctx;
+    ctx = reinterpret_cast<JNIImageReaderContext *>
+              (env->GetLongField(thiz, gImageReaderClassInfo.mNativeContext));
+    return ctx;
+}
+
+static CpuConsumer* ImageReader_getCpuConsumer(JNIEnv* env, jobject thiz)
+{
+    ALOGV("%s:", __FUNCTION__);
+    JNIImageReaderContext* const ctx = ImageReader_getContext(env, thiz);
+    if (ctx == NULL) {
+        jniThrowRuntimeException(env, "ImageReaderContext is not initialized");
+        return NULL;
+    }
+    return ctx->getCpuConsumer();
+}
+
+static BufferQueue* ImageReader_getBufferQueue(JNIEnv* env, jobject thiz)
+{
+    ALOGV("%s:", __FUNCTION__);
+    JNIImageReaderContext* const ctx = ImageReader_getContext(env, thiz);
+    if (ctx == NULL) {
+        jniThrowRuntimeException(env, "ImageReaderContext is not initialized");
+        return NULL;
+    }
+    return ctx->getBufferQueue();
+}
+
+static void ImageReader_setNativeContext(JNIEnv* env,
+        jobject thiz, sp<JNIImageReaderContext> ctx)
+{
+    ALOGV("%s:", __FUNCTION__);
+    JNIImageReaderContext* const p = ImageReader_getContext(env, thiz);
+    if (ctx != 0) {
+        ctx->incStrong((void*)ImageReader_setNativeContext);
+    }
+    if (p) {
+        p->decStrong((void*)ImageReader_setNativeContext);
+    }
+    env->SetLongField(thiz, gImageReaderClassInfo.mNativeContext,
+            reinterpret_cast<jlong>(ctx.get()));
+}
+
+static CpuConsumer::LockedBuffer* Image_getLockedBuffer(JNIEnv* env, jobject image)
+{
+    return reinterpret_cast<CpuConsumer::LockedBuffer*>(
+            env->GetLongField(image, gSurfaceImageClassInfo.mLockedBuffer));
+}
+
+static void Image_setBuffer(JNIEnv* env, jobject thiz,
+        const CpuConsumer::LockedBuffer* buffer)
+{
+    env->SetLongField(thiz, gSurfaceImageClassInfo.mLockedBuffer, reinterpret_cast<jlong>(buffer));
+}
+
+// Some formats like JPEG defined with different values between android.graphics.ImageFormat and
+// graphics.h, need convert to the one defined in graphics.h here.
+static int Image_getPixelFormat(JNIEnv* env, int format)
+{
+    int jpegFormat, rawSensorFormat;
+    jfieldID fid;
+
+    ALOGV("%s: format = 0x%x", __FUNCTION__, format);
+
+    jclass imageFormatClazz = env->FindClass("android/graphics/ImageFormat");
+    ALOG_ASSERT(imageFormatClazz != NULL);
+
+    fid = env->GetStaticFieldID(imageFormatClazz, "JPEG", "I");
+    jpegFormat = env->GetStaticIntField(imageFormatClazz, fid);
+    fid = env->GetStaticFieldID(imageFormatClazz, "RAW_SENSOR", "I");
+    rawSensorFormat = env->GetStaticIntField(imageFormatClazz, fid);
+
+    // Translate the JPEG to BLOB for camera purpose, an add more if more mismatch is found.
+    if (format == jpegFormat) {
+        format = HAL_PIXEL_FORMAT_BLOB;
+    }
+    // Same thing for RAW_SENSOR format
+    if (format == rawSensorFormat) {
+        format = HAL_PIXEL_FORMAT_RAW_SENSOR;
+    }
+
+    return format;
+}
+
+static uint32_t Image_getJpegSize(CpuConsumer::LockedBuffer* buffer)
+{
+    ALOG_ASSERT(buffer != NULL, "Input buffer is NULL!!!");
+    uint32_t size = 0;
+    uint32_t width = buffer->width;
+    uint8_t* jpegBuffer = buffer->data;
+
+    // First check for JPEG transport header at the end of the buffer
+    uint8_t* header = jpegBuffer + (width - sizeof(struct camera3_jpeg_blob));
+    struct camera3_jpeg_blob *blob = (struct camera3_jpeg_blob*)(header);
+    if (blob->jpeg_blob_id == CAMERA3_JPEG_BLOB_ID) {
+        size = blob->jpeg_size;
+        ALOGV("%s: Jpeg size = %d", __FUNCTION__, size);
+    }
+
+    // failed to find size, default to whole buffer
+    if (size == 0) {
+        size = width;
+    }
+
+    return size;
+}
+
+static void Image_getLockedBufferInfo(JNIEnv* env, CpuConsumer::LockedBuffer* buffer, int idx,
+                                uint8_t **base, uint32_t *size)
+{
+    ALOG_ASSERT(buffer != NULL, "Input buffer is NULL!!!");
+    ALOG_ASSERT(base != NULL, "base is NULL!!!");
+    ALOG_ASSERT(size != NULL, "size is NULL!!!");
+    ALOG_ASSERT((idx < IMAGE_READER_MAX_NUM_PLANES) && (idx >= 0));
+
+    ALOGV("%s: buffer: %p", __FUNCTION__, buffer);
+
+    uint32_t dataSize, ySize, cSize, cStride;
+    uint8_t *cb, *cr;
+    uint8_t *pData = NULL;
+    int bytesPerPixel = 0;
+
+    dataSize = ySize = cSize = cStride = 0;
+    int32_t fmt = buffer->format;
+    switch (fmt) {
+        case HAL_PIXEL_FORMAT_YCbCr_420_888:
+            pData =
+                (idx == 0) ?
+                    buffer->data :
+                (idx == 1) ?
+                    buffer->dataCb :
+                buffer->dataCr;
+            if (idx == 0) {
+                dataSize = buffer->stride * buffer->height;
+            } else {
+                dataSize = buffer->chromaStride * buffer->height / 2;
+            }
+            break;
+        // NV21
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+            cr = buffer->data + (buffer->stride * buffer->height);
+            cb = cr + 1;
+            ySize = buffer->width * buffer->height;
+            cSize = buffer->width * buffer->height / 2;
+
+            pData =
+                (idx == 0) ?
+                    buffer->data :
+                (idx == 1) ?
+                    cb:
+                cr;
+
+            dataSize = (idx == 0) ? ySize : cSize;
+            break;
+        case HAL_PIXEL_FORMAT_YV12:
+            // Y and C stride need to be 16 pixel aligned.
+            LOG_ALWAYS_FATAL_IF(buffer->stride % 16,
+                                "Stride is not 16 pixel aligned %d", buffer->stride);
+
+            ySize = buffer->stride * buffer->height;
+            cStride = ALIGN(buffer->stride / 2, 16);
+            cr = buffer->data + ySize;
+            cSize = cStride * buffer->height / 2;
+            cb = cr + cSize;
+
+            pData =
+                (idx == 0) ?
+                    buffer->data :
+                (idx == 1) ?
+                    cb :
+                cr;
+            dataSize = (idx == 0) ? ySize : cSize;
+            break;
+        case HAL_PIXEL_FORMAT_Y8:
+            // Single plane, 8bpp.
+            ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+
+            pData = buffer->data;
+            dataSize = buffer->stride * buffer->height;
+            break;
+        case HAL_PIXEL_FORMAT_Y16:
+            // Single plane, 16bpp, strides are specified in pixels, not in bytes
+            ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+
+            pData = buffer->data;
+            dataSize = buffer->stride * buffer->height * 2;
+            break;
+        case HAL_PIXEL_FORMAT_BLOB:
+            // Used for JPEG data, height must be 1, width == size, single plane.
+            ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+            ALOG_ASSERT(buffer->height == 1, "JPEG should has height value %d", buffer->height);
+
+            pData = buffer->data;
+            dataSize = Image_getJpegSize(buffer);
+            break;
+        case HAL_PIXEL_FORMAT_RAW_SENSOR:
+            // Single plane 16bpp bayer data.
+            ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+            pData = buffer->data;
+            dataSize = buffer->width * 2 * buffer->height;
+            break;
+        case HAL_PIXEL_FORMAT_RGBA_8888:
+        case HAL_PIXEL_FORMAT_RGBX_8888:
+            // Single plane, 32bpp.
+            bytesPerPixel = 4;
+            ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+            pData = buffer->data;
+            dataSize = buffer->stride * buffer->height * bytesPerPixel;
+            break;
+        case HAL_PIXEL_FORMAT_RGB_565:
+            // Single plane, 16bpp.
+            bytesPerPixel = 2;
+            ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+            pData = buffer->data;
+            dataSize = buffer->stride * buffer->height * bytesPerPixel;
+            break;
+        case HAL_PIXEL_FORMAT_RGB_888:
+            // Single plane, 24bpp.
+            bytesPerPixel = 3;
+            ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+            pData = buffer->data;
+            dataSize = buffer->stride * buffer->height * bytesPerPixel;
+            break;
+        default:
+            jniThrowExceptionFmt(env, "java/lang/UnsupportedOperationException",
+                                 "Pixel format: 0x%x is unsupported", fmt);
+            break;
+    }
+
+    *base = pData;
+    *size = dataSize;
+}
+
+static jint Image_imageGetPixelStride(JNIEnv* env, CpuConsumer::LockedBuffer* buffer, int idx)
+{
+    ALOGV("%s: buffer index: %d", __FUNCTION__, idx);
+    ALOG_ASSERT((idx < IMAGE_READER_MAX_NUM_PLANES) && (idx >= 0), "Index is out of range:%d", idx);
+
+    int pixelStride = 0;
+    ALOG_ASSERT(buffer != NULL, "buffer is NULL");
+
+    int32_t fmt = buffer->format;
+    switch (fmt) {
+        case HAL_PIXEL_FORMAT_YCbCr_420_888:
+            pixelStride = (idx == 0) ? 1 : buffer->chromaStep;
+            break;
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+            pixelStride = (idx == 0) ? 1 : 2;
+            break;
+        case HAL_PIXEL_FORMAT_Y8:
+            // Single plane 8bpp data.
+            ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+            pixelStride;
+            break;
+        case HAL_PIXEL_FORMAT_YV12:
+            pixelStride = 1;
+            break;
+        case HAL_PIXEL_FORMAT_BLOB:
+            // Used for JPEG data, single plane, row and pixel strides are 0
+            ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+            pixelStride = 0;
+            break;
+        case HAL_PIXEL_FORMAT_Y16:
+        case HAL_PIXEL_FORMAT_RAW_SENSOR:
+        case HAL_PIXEL_FORMAT_RGB_565:
+            // Single plane 16bpp data.
+            ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+            pixelStride = 2;
+            break;
+        case HAL_PIXEL_FORMAT_RGBA_8888:
+        case HAL_PIXEL_FORMAT_RGBX_8888:
+            ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+            pixelStride = 4;
+            break;
+        case HAL_PIXEL_FORMAT_RGB_888:
+            // Single plane, 24bpp.
+            ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+            pixelStride = 3;
+            break;
+        default:
+            jniThrowExceptionFmt(env, "java/lang/UnsupportedOperationException",
+                                 "Pixel format: 0x%x is unsupported", fmt);
+            break;
+    }
+
+    return pixelStride;
+}
+
+static jint Image_imageGetRowStride(JNIEnv* env, CpuConsumer::LockedBuffer* buffer, int idx)
+{
+    ALOGV("%s: buffer index: %d", __FUNCTION__, idx);
+    ALOG_ASSERT((idx < IMAGE_READER_MAX_NUM_PLANES) && (idx >= 0));
+
+    int rowStride = 0;
+    ALOG_ASSERT(buffer != NULL, "buffer is NULL");
+
+    int32_t fmt = buffer->format;
+
+    switch (fmt) {
+        case HAL_PIXEL_FORMAT_YCbCr_420_888:
+            rowStride = (idx == 0) ? buffer->stride : buffer->chromaStride;
+            break;
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+            rowStride = buffer->width;
+            break;
+        case HAL_PIXEL_FORMAT_YV12:
+            LOG_ALWAYS_FATAL_IF(buffer->stride % 16,
+                                "Stride is not 16 pixel aligned %d", buffer->stride);
+            rowStride = (idx == 0) ? buffer->stride : ALIGN(buffer->stride / 2, 16);
+            break;
+        case HAL_PIXEL_FORMAT_BLOB:
+            // Used for JPEG data, single plane, row and pixel strides are 0
+            ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+            rowStride = 0;
+            break;
+        case HAL_PIXEL_FORMAT_Y8:
+            ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+            LOG_ALWAYS_FATAL_IF(buffer->stride % 16,
+                                "Stride is not 16 pixel aligned %d", buffer->stride);
+            rowStride = buffer->stride;
+            break;
+        case HAL_PIXEL_FORMAT_Y16:
+        case HAL_PIXEL_FORMAT_RAW_SENSOR:
+            // In native side, strides are specified in pixels, not in bytes.
+            // Single plane 16bpp bayer data. even width/height,
+            // row stride multiple of 16 pixels (32 bytes)
+            ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+            LOG_ALWAYS_FATAL_IF(buffer->stride % 16,
+                                "Stride is not 16 pixel aligned %d", buffer->stride);
+            rowStride = buffer->stride * 2;
+            break;
+        case HAL_PIXEL_FORMAT_RGB_565:
+            ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+            rowStride = buffer->stride * 2;
+            break;
+        case HAL_PIXEL_FORMAT_RGBA_8888:
+        case HAL_PIXEL_FORMAT_RGBX_8888:
+            ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+            rowStride = buffer->stride * 4;
+            break;
+        case HAL_PIXEL_FORMAT_RGB_888:
+            // Single plane, 24bpp.
+            ALOG_ASSERT(idx == 0, "Wrong index: %d", idx);
+            rowStride = buffer->stride * 3;
+            break;
+        default:
+            ALOGE("%s Pixel format: 0x%x is unsupported", __FUNCTION__, fmt);
+            jniThrowException(env, "java/lang/UnsupportedOperationException",
+                              "unsupported buffer format");
+          break;
+    }
+
+    return rowStride;
+}
+
+// ----------------------------------------------------------------------------
+
+static void ImageReader_classInit(JNIEnv* env, jclass clazz)
+{
+    ALOGV("%s:", __FUNCTION__);
+
+    jclass imageClazz = env->FindClass("android/media/ImageReader$SurfaceImage");
+    LOG_ALWAYS_FATAL_IF(imageClazz == NULL,
+                        "can't find android/graphics/ImageReader$SurfaceImage");
+    gSurfaceImageClassInfo.mLockedBuffer = env->GetFieldID(
+            imageClazz, ANDROID_MEDIA_SURFACEIMAGE_BUFFER_JNI_ID, "J");
+    LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mLockedBuffer == NULL,
+                        "can't find android/graphics/ImageReader.%s",
+                        ANDROID_MEDIA_SURFACEIMAGE_BUFFER_JNI_ID);
+
+    gSurfaceImageClassInfo.mTimestamp = env->GetFieldID(
+            imageClazz, ANDROID_MEDIA_SURFACEIMAGE_TS_JNI_ID, "J");
+    LOG_ALWAYS_FATAL_IF(gSurfaceImageClassInfo.mTimestamp == NULL,
+                        "can't find android/graphics/ImageReader.%s",
+                        ANDROID_MEDIA_SURFACEIMAGE_TS_JNI_ID);
+
+    gImageReaderClassInfo.mNativeContext = env->GetFieldID(
+            clazz, ANDROID_MEDIA_IMAGEREADER_CTX_JNI_ID, "J");
+    LOG_ALWAYS_FATAL_IF(gImageReaderClassInfo.mNativeContext == NULL,
+                        "can't find android/graphics/ImageReader.%s",
+                          ANDROID_MEDIA_IMAGEREADER_CTX_JNI_ID);
+
+    gImageReaderClassInfo.postEventFromNative = env->GetStaticMethodID(
+            clazz, "postEventFromNative", "(Ljava/lang/Object;)V");
+    LOG_ALWAYS_FATAL_IF(gImageReaderClassInfo.postEventFromNative == NULL,
+                        "can't find android/graphics/ImageReader.postEventFromNative");
+
+    jclass planeClazz = env->FindClass("android/media/ImageReader$SurfaceImage$SurfacePlane");
+    LOG_ALWAYS_FATAL_IF(planeClazz == NULL, "Can not find SurfacePlane class");
+    // FindClass only gives a local reference of jclass object.
+    gSurfacePlaneClassInfo.clazz = (jclass) env->NewGlobalRef(planeClazz);
+    gSurfacePlaneClassInfo.ctor = env->GetMethodID(gSurfacePlaneClassInfo.clazz, "<init>",
+            "(Landroid/media/ImageReader$SurfaceImage;III)V");
+    LOG_ALWAYS_FATAL_IF(gSurfacePlaneClassInfo.ctor == NULL,
+            "Can not find SurfacePlane constructor");
+}
+
+static void ImageReader_init(JNIEnv* env, jobject thiz, jobject weakThiz,
+                             jint width, jint height, jint format, jint maxImages)
+{
+    status_t res;
+    int nativeFormat;
+
+    ALOGV("%s: width:%d, height: %d, format: 0x%x, maxImages:%d",
+          __FUNCTION__, width, height, format, maxImages);
+
+    nativeFormat = Image_getPixelFormat(env, format);
+
+    sp<BufferQueue> bq = new BufferQueue();
+    sp<CpuConsumer> consumer = new CpuConsumer(bq, maxImages,
+                                               /*controlledByApp*/true);
+    // TODO: throw dvm exOutOfMemoryError?
+    if (consumer == NULL) {
+        jniThrowRuntimeException(env, "Failed to allocate native CpuConsumer");
+        return;
+    }
+
+    jclass clazz = env->GetObjectClass(thiz);
+    if (clazz == NULL) {
+        jniThrowRuntimeException(env, "Can't find android/graphics/ImageReader");
+        return;
+    }
+    sp<JNIImageReaderContext> ctx(new JNIImageReaderContext(env, weakThiz, clazz, maxImages));
+    ctx->setCpuConsumer(consumer);
+    ctx->setBufferQueue(bq);
+    consumer->setFrameAvailableListener(ctx);
+    ImageReader_setNativeContext(env, thiz, ctx);
+    ctx->setBufferFormat(nativeFormat);
+    ctx->setBufferWidth(width);
+    ctx->setBufferHeight(height);
+
+    // Set the width/height/format to the CpuConsumer
+    res = consumer->setDefaultBufferSize(width, height);
+    if (res != OK) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                          "Failed to set CpuConsumer buffer size");
+        return;
+    }
+    res = consumer->setDefaultBufferFormat(nativeFormat);
+    if (res != OK) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                          "Failed to set CpuConsumer buffer format");
+    }
+}
+
+static void ImageReader_close(JNIEnv* env, jobject thiz)
+{
+    ALOGV("%s:", __FUNCTION__);
+
+    JNIImageReaderContext* const ctx = ImageReader_getContext(env, thiz);
+    if (ctx == NULL) {
+        // ImageReader is already closed.
+        return;
+    }
+
+    CpuConsumer* consumer = ImageReader_getCpuConsumer(env, thiz);
+    if (consumer != NULL) {
+        consumer->abandon();
+        consumer->setFrameAvailableListener(NULL);
+    }
+    ImageReader_setNativeContext(env, thiz, NULL);
+}
+
+static void ImageReader_imageRelease(JNIEnv* env, jobject thiz, jobject image)
+{
+    ALOGV("%s:", __FUNCTION__);
+    JNIImageReaderContext* ctx = ImageReader_getContext(env, thiz);
+    if (ctx == NULL) {
+        ALOGW("ImageReader#close called before Image#close, consider calling Image#close first");
+        return;
+    }
+
+    CpuConsumer* consumer = ctx->getCpuConsumer();
+    CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, image);
+    if (!buffer) {
+        ALOGW("Image already released!!!");
+        return;
+    }
+    consumer->unlockBuffer(*buffer);
+    Image_setBuffer(env, image, NULL);
+    ctx->returnLockedBuffer(buffer);
+}
+
+static jboolean ImageReader_imageSetup(JNIEnv* env, jobject thiz,
+                                             jobject image)
+{
+    ALOGV("%s:", __FUNCTION__);
+    JNIImageReaderContext* ctx = ImageReader_getContext(env, thiz);
+    if (ctx == NULL) {
+        jniThrowRuntimeException(env, "ImageReaderContext is not initialized");
+        return false;
+    }
+
+    CpuConsumer* consumer = ctx->getCpuConsumer();
+    CpuConsumer::LockedBuffer* buffer = ctx->getLockedBuffer();
+    if (buffer == NULL) {
+        ALOGW("Unable to acquire a lockedBuffer, very likely client tries to lock more than"
+            " maxImages buffers");
+        jniThrowException(env, OutOfResourcesException,
+                  "Too many outstanding images, close existing images"
+                  " to be able to acquire more.");
+        return false;
+    }
+    status_t res = consumer->lockNextBuffer(buffer);
+    if (res != NO_ERROR) {
+        if (res != BAD_VALUE /*no buffers*/) {
+            if (res == NOT_ENOUGH_DATA) {
+                jniThrowException(env, OutOfResourcesException,
+                          "Too many outstanding images, close existing images"
+                          " to be able to acquire more.");
+            } else {
+                ALOGE("%s Fail to lockNextBuffer with error: %d ",
+                      __FUNCTION__, res);
+                jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
+                          "Unknown error (%d) when we tried to lock buffer.",
+                          res);
+            }
+        }
+        return false;
+    }
+
+    // Check if the left-top corner of the crop rect is origin, we currently assume this point is
+    // zero, will revist this once this assumption turns out problematic.
+    Point lt = buffer->crop.leftTop();
+    if (lt.x != 0 || lt.y != 0) {
+        ALOGE("crop left: %d, top = %d", lt.x, lt.y);
+        jniThrowException(env, "java/lang/UnsupportedOperationException",
+                          "crop left top corner need to at origin");
+        return false;
+    }
+
+    // Check if the producer buffer configurations match what ImageReader configured.
+    // We want to fail for the very first image because this case is too bad.
+    int outputWidth = buffer->width;
+    int outputHeight = buffer->height;
+
+    // Correct width/height when crop is set.
+    if (buffer->crop.getWidth() > 0) {
+        outputWidth = buffer->crop.getWidth() + 1;
+    }
+    if (buffer->crop.getHeight() > 0) {
+        outputHeight = buffer->crop.getHeight() + 1;
+    }
+
+    int imageReaderWidth = ctx->getBufferWidth();
+    int imageReaderHeight = ctx->getBufferHeight();
+    if ((buffer->format != HAL_PIXEL_FORMAT_BLOB) &&
+            (imageReaderWidth != outputWidth || imageReaderHeight > outputHeight)) {
+        /**
+         * For video decoder, the buffer height is actually the vertical stride,
+         * which is always >= actual image height. For future, decoder need provide
+         * right crop rectangle to CpuConsumer to indicate the actual image height,
+         * see bug 9563986. After this bug is fixed, we can enforce the height equal
+         * check. Right now, only make sure buffer height is no less than ImageReader
+         * height.
+         */
+        jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
+                "Producer buffer size: %dx%d, doesn't match ImageReader configured size: %dx%d",
+                outputWidth, outputHeight, imageReaderWidth, imageReaderHeight);
+    }
+
+    if (ctx->getBufferFormat() != buffer->format) {
+        // Return the buffer to the queue.
+        consumer->unlockBuffer(*buffer);
+        ctx->returnLockedBuffer(buffer);
+
+        // Throw exception
+        ALOGE("Producer output buffer format: 0x%x, ImageReader configured format: 0x%x",
+              buffer->format, ctx->getBufferFormat());
+        String8 msg;
+        msg.appendFormat("The producer output buffer format 0x%x doesn't "
+                "match the ImageReader's configured buffer format 0x%x.",
+                buffer->format, ctx->getBufferFormat());
+        jniThrowException(env, "java/lang/UnsupportedOperationException",
+                msg.string());
+        return false;
+    }
+    // Set SurfaceImage instance member variables
+    Image_setBuffer(env, image, buffer);
+    env->SetLongField(image, gSurfaceImageClassInfo.mTimestamp,
+            static_cast<jlong>(buffer->timestamp));
+
+    return true;
+}
+
+static jobject ImageReader_getSurface(JNIEnv* env, jobject thiz)
+{
+    ALOGV("%s: ", __FUNCTION__);
+
+    BufferQueue* bq = ImageReader_getBufferQueue(env, thiz);
+    if (bq == NULL) {
+        jniThrowRuntimeException(env, "CpuConsumer is uninitialized");
+        return NULL;
+    }
+
+    // Wrap the IGBP in a Java-language Surface.
+    return android_view_Surface_createFromIGraphicBufferProducer(env, bq);
+}
+
+static jobject Image_createSurfacePlane(JNIEnv* env, jobject thiz, int idx)
+{
+    int rowStride, pixelStride;
+    ALOGV("%s: buffer index: %d", __FUNCTION__, idx);
+
+    CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, thiz);
+
+    ALOG_ASSERT(buffer != NULL);
+    if (buffer == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException", "Image was released");
+    }
+    rowStride = Image_imageGetRowStride(env, buffer, idx);
+    pixelStride = Image_imageGetPixelStride(env, buffer, idx);
+
+    jobject surfPlaneObj = env->NewObject(gSurfacePlaneClassInfo.clazz,
+            gSurfacePlaneClassInfo.ctor, thiz, idx, rowStride, pixelStride);
+
+    return surfPlaneObj;
+}
+
+static jobject Image_getByteBuffer(JNIEnv* env, jobject thiz, int idx)
+{
+    uint8_t *base = NULL;
+    uint32_t size = 0;
+    jobject byteBuffer;
+
+    ALOGV("%s: buffer index: %d", __FUNCTION__, idx);
+
+    CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, thiz);
+
+    if (buffer == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException", "Image was released");
+    }
+
+    // Create byteBuffer from native buffer
+    Image_getLockedBufferInfo(env, buffer, idx, &base, &size);
+    byteBuffer = env->NewDirectByteBuffer(base, size);
+    // TODO: throw dvm exOutOfMemoryError?
+    if ((byteBuffer == NULL) && (env->ExceptionCheck() == false)) {
+        jniThrowException(env, "java/lang/IllegalStateException", "Failed to allocate ByteBuffer");
+    }
+
+    return byteBuffer;
+}
+
+} // extern "C"
+
+// ----------------------------------------------------------------------------
+
+static JNINativeMethod gImageReaderMethods[] = {
+    {"nativeClassInit",        "()V",                        (void*)ImageReader_classInit },
+    {"nativeInit",             "(Ljava/lang/Object;IIII)V",  (void*)ImageReader_init },
+    {"nativeClose",            "()V",                        (void*)ImageReader_close },
+    {"nativeReleaseImage",     "(Landroid/media/Image;)V",   (void*)ImageReader_imageRelease },
+    {"nativeImageSetup",       "(Landroid/media/Image;)Z",    (void*)ImageReader_imageSetup },
+    {"nativeGetSurface",       "()Landroid/view/Surface;",   (void*)ImageReader_getSurface },
+};
+
+static JNINativeMethod gImageMethods[] = {
+    {"nativeImageGetBuffer",   "(I)Ljava/nio/ByteBuffer;",   (void*)Image_getByteBuffer },
+    {"nativeCreatePlane",      "(I)Landroid/media/ImageReader$SurfaceImage$SurfacePlane;",
+                                                             (void*)Image_createSurfacePlane },
+};
+
+int register_android_media_ImageReader(JNIEnv *env) {
+
+    int ret1 = AndroidRuntime::registerNativeMethods(env,
+                   "android/media/ImageReader", gImageReaderMethods, NELEM(gImageReaderMethods));
+
+    int ret2 = AndroidRuntime::registerNativeMethods(env,
+                   "android/media/ImageReader$SurfaceImage", gImageMethods, NELEM(gImageMethods));
+
+    return (ret1 || ret2);
+}
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index cd1d9ce..a859506 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -38,6 +38,8 @@
 #include <media/stagefright/foundation/AString.h>
 #include <media/stagefright/MediaErrors.h>
 
+#include <nativehelper/ScopedLocalRef.h>
+
 #include <system/window.h>
 
 namespace android {
@@ -49,9 +51,14 @@
     DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED     = -3,
 };
 
+struct CryptoErrorCodes {
+    jint cryptoErrorNoKey;
+    jint cryptoErrorKeyExpired;
+    jint cryptoErrorResourceBusy;
+} gCryptoErrorCodes;
+
 struct fields_t {
     jfieldID context;
-
     jfieldID cryptoInfoNumSubSamplesID;
     jfieldID cryptoInfoNumBytesOfClearDataID;
     jfieldID cryptoInfoNumBytesOfEncryptedDataID;
@@ -81,7 +88,7 @@
     mLooper->start(
             false,      // runOnCallingThread
             false,       // canCallJava
-            PRIORITY_DEFAULT);
+            PRIORITY_FOREGROUND);
 
     if (nameIsType) {
         mCodec = MediaCodec::CreateByType(mLooper, name, encoder);
@@ -181,9 +188,10 @@
         return err;
     }
 
-    jclass clazz = env->FindClass("android/media/MediaCodec$BufferInfo");
+    ScopedLocalRef<jclass> clazz(
+            env, env->FindClass("android/media/MediaCodec$BufferInfo"));
 
-    jmethodID method = env->GetMethodID(clazz, "set", "(IIJI)V");
+    jmethodID method = env->GetMethodID(clazz.get(), "set", "(IIJI)V");
     env->CallVoidMethod(bufferInfo, method, offset, size, timeUs, flags);
 
     return OK;
@@ -222,29 +230,33 @@
         return err;
     }
 
-    jclass byteBufferClass = env->FindClass("java/nio/ByteBuffer");
-    CHECK(byteBufferClass != NULL);
+    ScopedLocalRef<jclass> byteBufferClass(
+            env, env->FindClass("java/nio/ByteBuffer"));
+
+    CHECK(byteBufferClass.get() != NULL);
 
     jmethodID orderID = env->GetMethodID(
-            byteBufferClass,
+            byteBufferClass.get(),
             "order",
             "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;");
 
     CHECK(orderID != NULL);
 
-    jclass byteOrderClass = env->FindClass("java/nio/ByteOrder");
-    CHECK(byteOrderClass != NULL);
+    ScopedLocalRef<jclass> byteOrderClass(
+            env, env->FindClass("java/nio/ByteOrder"));
+
+    CHECK(byteOrderClass.get() != NULL);
 
     jmethodID nativeOrderID = env->GetStaticMethodID(
-            byteOrderClass, "nativeOrder", "()Ljava/nio/ByteOrder;");
+            byteOrderClass.get(), "nativeOrder", "()Ljava/nio/ByteOrder;");
     CHECK(nativeOrderID != NULL);
 
     jobject nativeByteOrderObj =
-        env->CallStaticObjectMethod(byteOrderClass, nativeOrderID);
+        env->CallStaticObjectMethod(byteOrderClass.get(), nativeOrderID);
     CHECK(nativeByteOrderObj != NULL);
 
     *bufArray = (jobjectArray)env->NewObjectArray(
-            buffers.size(), byteBufferClass, NULL);
+            buffers.size(), byteBufferClass.get(), NULL);
     if (*bufArray == NULL) {
         env->DeleteLocalRef(nativeByteOrderObj);
         return NO_MEMORY;
@@ -298,6 +310,10 @@
     return OK;
 }
 
+status_t JMediaCodec::setParameters(const sp<AMessage> &msg) {
+    return mCodec->setParameters(msg);
+}
+
 void JMediaCodec::setVideoScalingMode(int mode) {
     if (mSurfaceTextureClient != NULL) {
         native_window_set_scaling_mode(mSurfaceTextureClient.get(), mode);
@@ -333,26 +349,41 @@
 }
 
 static void throwCryptoException(JNIEnv *env, status_t err, const char *msg) {
-    jclass clazz = env->FindClass("android/media/MediaCodec$CryptoException");
-    CHECK(clazz != NULL);
+    ScopedLocalRef<jclass> clazz(
+            env, env->FindClass("android/media/MediaCodec$CryptoException"));
+    CHECK(clazz.get() != NULL);
 
     jmethodID constructID =
-        env->GetMethodID(clazz, "<init>", "(ILjava/lang/String;)V");
+        env->GetMethodID(clazz.get(), "<init>", "(ILjava/lang/String;)V");
     CHECK(constructID != NULL);
 
     jstring msgObj = env->NewStringUTF(msg != NULL ? msg : "Unknown Error");
 
+    /* translate OS errors to Java API CryptoException errorCodes */
+    switch (err) {
+        case ERROR_DRM_NO_LICENSE:
+            err = gCryptoErrorCodes.cryptoErrorNoKey;
+            break;
+        case ERROR_DRM_LICENSE_EXPIRED:
+            err = gCryptoErrorCodes.cryptoErrorKeyExpired;
+            break;
+        case ERROR_DRM_RESOURCE_BUSY:
+            err = gCryptoErrorCodes.cryptoErrorResourceBusy;
+            break;
+        default:
+            break;
+    }
+
     jthrowable exception =
-        (jthrowable)env->NewObject(clazz, constructID, err, msgObj);
+        (jthrowable)env->NewObject(clazz.get(), constructID, err, msgObj);
 
     env->Throw(exception);
 }
 
 static jint throwExceptionAsNecessary(
         JNIEnv *env, status_t err, const char *msg = NULL) {
-    if (err >= ERROR_DRM_WV_VENDOR_MIN && err <= ERROR_DRM_WV_VENDOR_MAX) {
+    if (err >= ERROR_DRM_VENDOR_MIN && err <= ERROR_DRM_VENDOR_MAX) {
         // We'll throw our custom MediaCodec.CryptoException
-
         throwCryptoException(env, err, msg);
         return 0;
     }
@@ -370,6 +401,12 @@
         case INFO_OUTPUT_BUFFERS_CHANGED:
             return DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED;
 
+        case ERROR_DRM_NO_LICENSE:
+        case ERROR_DRM_LICENSE_EXPIRED:
+        case ERROR_DRM_RESOURCE_BUSY:
+            throwCryptoException(env, err, msg);
+            break;
+
         default:
         {
             jniThrowException(env, "java/lang/IllegalStateException", msg);
@@ -804,6 +841,27 @@
     return NULL;
 }
 
+static void android_media_MediaCodec_setParameters(
+        JNIEnv *env, jobject thiz, jobjectArray keys, jobjectArray vals) {
+    ALOGV("android_media_MediaCodec_setParameters");
+
+    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
+
+    if (codec == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException", NULL);
+        return;
+    }
+
+    sp<AMessage> params;
+    status_t err = ConvertKeyValueArraysToMessage(env, keys, vals, &params);
+
+    if (err == OK) {
+        err = codec->setParameters(params);
+    }
+
+    throwExceptionAsNecessary(env, err);
+}
+
 static void android_media_MediaCodec_setVideoScalingMode(
         JNIEnv *env, jobject thiz, jint mode) {
     sp<JMediaCodec> codec = getMediaCodec(env, thiz);
@@ -823,35 +881,55 @@
 }
 
 static void android_media_MediaCodec_native_init(JNIEnv *env) {
-    jclass clazz = env->FindClass("android/media/MediaCodec");
-    CHECK(clazz != NULL);
+    ScopedLocalRef<jclass> clazz(
+            env, env->FindClass("android/media/MediaCodec"));
+    CHECK(clazz.get() != NULL);
 
-    gFields.context = env->GetFieldID(clazz, "mNativeContext", "I");
+    gFields.context = env->GetFieldID(clazz.get(), "mNativeContext", "I");
     CHECK(gFields.context != NULL);
 
-    clazz = env->FindClass("android/media/MediaCodec$CryptoInfo");
-    CHECK(clazz != NULL);
+    clazz.reset(env->FindClass("android/media/MediaCodec$CryptoInfo"));
+    CHECK(clazz.get() != NULL);
 
     gFields.cryptoInfoNumSubSamplesID =
-        env->GetFieldID(clazz, "numSubSamples", "I");
+        env->GetFieldID(clazz.get(), "numSubSamples", "I");
     CHECK(gFields.cryptoInfoNumSubSamplesID != NULL);
 
     gFields.cryptoInfoNumBytesOfClearDataID =
-        env->GetFieldID(clazz, "numBytesOfClearData", "[I");
+        env->GetFieldID(clazz.get(), "numBytesOfClearData", "[I");
     CHECK(gFields.cryptoInfoNumBytesOfClearDataID != NULL);
 
     gFields.cryptoInfoNumBytesOfEncryptedDataID =
-        env->GetFieldID(clazz, "numBytesOfEncryptedData", "[I");
+        env->GetFieldID(clazz.get(), "numBytesOfEncryptedData", "[I");
     CHECK(gFields.cryptoInfoNumBytesOfEncryptedDataID != NULL);
 
-    gFields.cryptoInfoKeyID = env->GetFieldID(clazz, "key", "[B");
+    gFields.cryptoInfoKeyID = env->GetFieldID(clazz.get(), "key", "[B");
     CHECK(gFields.cryptoInfoKeyID != NULL);
 
-    gFields.cryptoInfoIVID = env->GetFieldID(clazz, "iv", "[B");
+    gFields.cryptoInfoIVID = env->GetFieldID(clazz.get(), "iv", "[B");
     CHECK(gFields.cryptoInfoIVID != NULL);
 
-    gFields.cryptoInfoModeID = env->GetFieldID(clazz, "mode", "I");
+    gFields.cryptoInfoModeID = env->GetFieldID(clazz.get(), "mode", "I");
     CHECK(gFields.cryptoInfoModeID != NULL);
+
+    clazz.reset(env->FindClass("android/media/MediaCodec$CryptoException"));
+    CHECK(clazz.get() != NULL);
+
+    jfieldID field;
+    field = env->GetStaticFieldID(clazz.get(), "ERROR_NO_KEY", "I");
+    CHECK(field != NULL);
+    gCryptoErrorCodes.cryptoErrorNoKey =
+        env->GetStaticIntField(clazz.get(), field);
+
+    field = env->GetStaticFieldID(clazz.get(), "ERROR_KEY_EXPIRED", "I");
+    CHECK(field != NULL);
+    gCryptoErrorCodes.cryptoErrorKeyExpired =
+        env->GetStaticIntField(clazz.get(), field);
+
+    field = env->GetStaticFieldID(clazz.get(), "ERROR_RESOURCE_BUSY", "I");
+    CHECK(field != NULL);
+    gCryptoErrorCodes.cryptoErrorResourceBusy =
+        env->GetStaticIntField(clazz.get(), field);
 }
 
 static void android_media_MediaCodec_native_setup(
@@ -933,6 +1011,9 @@
     { "getName", "()Ljava/lang/String;",
       (void *)android_media_MediaCodec_getName },
 
+    { "setParameters", "([Ljava/lang/String;[Ljava/lang/Object;)V",
+      (void *)android_media_MediaCodec_setParameters },
+
     { "setVideoScalingMode", "(I)V",
       (void *)android_media_MediaCodec_setVideoScalingMode },
 
diff --git a/media/jni/android_media_MediaCodec.h b/media/jni/android_media_MediaCodec.h
index 282d2c5..2fbbd72 100644
--- a/media/jni/android_media_MediaCodec.h
+++ b/media/jni/android_media_MediaCodec.h
@@ -87,6 +87,8 @@
 
     status_t getName(JNIEnv *env, jstring *name) const;
 
+    status_t setParameters(const sp<AMessage> &params);
+
     void setVideoScalingMode(int mode);
 
 protected:
diff --git a/media/jni/android_media_MediaCodecList.cpp b/media/jni/android_media_MediaCodecList.cpp
index 04430ec..caa594e 100644
--- a/media/jni/android_media_MediaCodecList.cpp
+++ b/media/jni/android_media_MediaCodecList.cpp
@@ -110,10 +110,11 @@
 
     Vector<MediaCodecList::ProfileLevel> profileLevels;
     Vector<uint32_t> colorFormats;
+    uint32_t flags;
 
     status_t err =
         MediaCodecList::getInstance()->getCodecCapabilities(
-                index, typeStr, &profileLevels, &colorFormats);
+                index, typeStr, &profileLevels, &colorFormats, &flags);
 
     env->ReleaseStringUTFChars(type, typeStr);
     typeStr = NULL;
@@ -127,6 +128,9 @@
         env->FindClass("android/media/MediaCodecInfo$CodecCapabilities");
     CHECK(capsClazz != NULL);
 
+    jfieldID flagsField =
+        env->GetFieldID(capsClazz, "flags", "I");
+
     jobject caps = env->AllocObject(capsClazz);
 
     jclass profileLevelClazz =
@@ -163,6 +167,8 @@
 
     env->SetObjectField(caps, profileLevelsField, profileLevelArray);
 
+    env->SetIntField(caps, flagsField, flags);
+
     env->DeleteLocalRef(profileLevelArray);
     profileLevelArray = NULL;
 
diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp
index 7799ca4..bbb74d25b 100644
--- a/media/jni/android_media_MediaDrm.cpp
+++ b/media/jni/android_media_MediaDrm.cpp
@@ -21,6 +21,7 @@
 #include "android_media_MediaDrm.h"
 
 #include "android_runtime/AndroidRuntime.h"
+#include "android_runtime/Log.h"
 #include "android_os_Parcel.h"
 #include "jni.h"
 #include "JNIHelp.h"
@@ -242,6 +243,9 @@
     } else if (err == ERROR_DRM_NOT_PROVISIONED) {
         jniThrowException(env, "android/media/NotProvisionedException", msg);
         return true;
+    } else if (err == ERROR_DRM_RESOURCE_BUSY) {
+        jniThrowException(env, "android/media/ResourceBusyException", msg);
+        return true;
     } else if (err == ERROR_DRM_DEVICE_REVOKED) {
         jniThrowException(env, "android/media/DeniedByServerException", msg);
         return true;
@@ -345,14 +349,14 @@
 
 
 // static
-bool JDrm::IsCryptoSchemeSupported(const uint8_t uuid[16]) {
+bool JDrm::IsCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
     sp<IDrm> drm = MakeDrm();
 
     if (drm == NULL) {
         return false;
     }
 
-    return drm->isCryptoSchemeSupported(uuid);
+    return drm->isCryptoSchemeSupported(uuid, mimeType);
 }
 
 status_t JDrm::initCheck() const {
@@ -608,7 +612,7 @@
 }
 
 static jboolean android_media_MediaDrm_isCryptoSchemeSupportedNative(
-        JNIEnv *env, jobject thiz, jbyteArray uuidObj) {
+    JNIEnv *env, jobject thiz, jbyteArray uuidObj, jstring jmimeType) {
 
     if (uuidObj == NULL) {
         jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
@@ -625,7 +629,12 @@
         return false;
     }
 
-    return JDrm::IsCryptoSchemeSupported(uuid.array());
+    String8 mimeType;
+    if (jmimeType != NULL) {
+        mimeType = JStringToString8(env, jmimeType);
+    }
+
+    return JDrm::IsCryptoSchemeSupported(uuid.array(), mimeType);
 }
 
 static jbyteArray android_media_MediaDrm_openSession(
@@ -750,7 +759,9 @@
 
     status_t err = drm->provideKeyResponse(sessionId, response, keySetId);
 
-    throwExceptionAsNecessary(env, err, "Failed to handle key response");
+    if (throwExceptionAsNecessary(env, err, "Failed to handle key response")) {
+        return NULL;
+    }
     return VectorToJByteArray(env, keySetId);
 }
 
@@ -1101,7 +1112,9 @@
 
     status_t err = drm->encrypt(sessionId, keyId, input, iv, output);
 
-    throwExceptionAsNecessary(env, err, "Failed to encrypt");
+    if (throwExceptionAsNecessary(env, err, "Failed to encrypt")) {
+        return NULL;
+    }
 
     return VectorToJByteArray(env, output);
 }
@@ -1129,7 +1142,9 @@
     Vector<uint8_t> output;
 
     status_t err = drm->decrypt(sessionId, keyId, input, iv, output);
-    throwExceptionAsNecessary(env, err, "Failed to decrypt");
+    if (throwExceptionAsNecessary(env, err, "Failed to decrypt")) {
+        return NULL;
+    }
 
     return VectorToJByteArray(env, output);
 }
@@ -1157,7 +1172,9 @@
 
     status_t err = drm->sign(sessionId, keyId, message, signature);
 
-    throwExceptionAsNecessary(env, err, "Failed to sign");
+    if (throwExceptionAsNecessary(env, err, "Failed to sign")) {
+        return NULL;
+    }
 
     return VectorToJByteArray(env, signature);
 }
@@ -1201,7 +1218,7 @@
     { "native_finalize", "()V",
       (void *)android_media_MediaDrm_native_finalize },
 
-    { "isCryptoSchemeSupportedNative", "([B)Z",
+    { "isCryptoSchemeSupportedNative", "([BLjava/lang/String;)Z",
       (void *)android_media_MediaDrm_isCryptoSchemeSupportedNative },
 
     { "openSession", "()[B",
diff --git a/media/jni/android_media_MediaDrm.h b/media/jni/android_media_MediaDrm.h
index 9b3917f..620ad28 100644
--- a/media/jni/android_media_MediaDrm.h
+++ b/media/jni/android_media_MediaDrm.h
@@ -37,7 +37,7 @@
 };
 
 struct JDrm : public BnDrmClient {
-    static bool IsCryptoSchemeSupported(const uint8_t uuid[16]);
+    static bool IsCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType);
 
     JDrm(JNIEnv *env, jobject thiz, const uint8_t uuid[16]);
 
diff --git a/media/jni/android_media_MediaExtractor.cpp b/media/jni/android_media_MediaExtractor.cpp
index 1704d5c..1ac45d4 100644
--- a/media/jni/android_media_MediaExtractor.cpp
+++ b/media/jni/android_media_MediaExtractor.cpp
@@ -22,6 +22,7 @@
 
 #include "android_media_Utils.h"
 #include "android_runtime/AndroidRuntime.h"
+#include "android_runtime/Log.h"
 #include "jni.h"
 #include "JNIHelp.h"
 
diff --git a/media/jni/android_media_MediaMuxer.cpp b/media/jni/android_media_MediaMuxer.cpp
index 7517e85..457b956 100644
--- a/media/jni/android_media_MediaMuxer.cpp
+++ b/media/jni/android_media_MediaMuxer.cpp
@@ -164,6 +164,18 @@
 
 }
 
+static void android_media_MediaMuxer_setLocation(
+        JNIEnv *env, jclass clazz, jint nativeObject, jint latitude, jint longitude) {
+    MediaMuxer* muxer = reinterpret_cast<MediaMuxer *>(nativeObject);
+
+    status_t res = muxer->setLocation(latitude, longitude);
+    if (res != OK) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                          "Failed to set location");
+        return;
+    }
+}
+
 static void android_media_MediaMuxer_start(JNIEnv *env, jclass clazz,
                                            jint nativeObject) {
     sp<MediaMuxer> muxer(reinterpret_cast<MediaMuxer *>(nativeObject));
@@ -216,6 +228,9 @@
     { "nativeSetOrientationHint", "(II)V",
         (void *)android_media_MediaMuxer_setOrientationHint},
 
+    { "nativeSetLocation", "(III)V",
+        (void *)android_media_MediaMuxer_setLocation},
+
     { "nativeStart", "(I)V", (void *)android_media_MediaMuxer_start},
 
     { "nativeWriteSampleData", "(IILjava/nio/ByteBuffer;IIJI)V",
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 7c607ea..d134667 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -31,6 +31,7 @@
 #include "JNIHelp.h"
 #include "android_runtime/AndroidRuntime.h"
 #include "android_runtime/android_view_Surface.h"
+#include "android_runtime/Log.h"
 #include "utils/Errors.h"  // for status_t
 #include "utils/KeyedVector.h"
 #include "utils/String8.h"
@@ -525,14 +526,6 @@
     process_media_player_call( env, thiz, mp->setVolume(leftVolume, rightVolume), NULL, NULL );
 }
 
-// FIXME: deprecated
-static jobject
-android_media_MediaPlayer_getFrameAt(JNIEnv *env, jobject thiz, jint msec)
-{
-    return NULL;
-}
-
-
 // Sends the request and reply parcels to the media player via the
 // binder interface.
 static jint
@@ -781,39 +774,6 @@
     return ret;
 }
 
-static jboolean
-android_media_MediaPlayer_setParameter(JNIEnv *env, jobject thiz, jint key, jobject java_request)
-{
-    ALOGV("setParameter: key %d", key);
-    sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL ) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return false;
-    }
-
-    Parcel *request = parcelForJavaObject(env, java_request);
-    status_t err = mp->setParameter(key, *request);
-    if (err == OK) {
-        return true;
-    } else {
-        return false;
-    }
-}
-
-static void
-android_media_MediaPlayer_getParameter(JNIEnv *env, jobject thiz, jint key, jobject java_reply)
-{
-    ALOGV("getParameter: key %d", key);
-    sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL ) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return;
-    }
-
-    Parcel *reply = parcelForJavaObject(env, java_reply);
-    process_media_player_call(env, thiz, mp->getParameter(key, reply), NULL, NULL );
-}
-
 static void
 android_media_MediaPlayer_setNextMediaPlayer(JNIEnv *env, jobject thiz, jobject java_player)
 {
@@ -912,7 +872,6 @@
     {"setLooping",          "(Z)V",                             (void *)android_media_MediaPlayer_setLooping},
     {"isLooping",           "()Z",                              (void *)android_media_MediaPlayer_isLooping},
     {"setVolume",           "(FF)V",                            (void *)android_media_MediaPlayer_setVolume},
-    {"getFrameAt",          "(I)Landroid/graphics/Bitmap;",     (void *)android_media_MediaPlayer_getFrameAt},
     {"native_invoke",       "(Landroid/os/Parcel;Landroid/os/Parcel;)I",(void *)android_media_MediaPlayer_invoke},
     {"native_setMetadataFilter", "(Landroid/os/Parcel;)I",      (void *)android_media_MediaPlayer_setMetadataFilter},
     {"native_getMetadata", "(ZZLandroid/os/Parcel;)Z",          (void *)android_media_MediaPlayer_getMetadata},
@@ -924,8 +883,6 @@
     {"setAuxEffectSendLevel", "(F)V",                           (void *)android_media_MediaPlayer_setAuxEffectSendLevel},
     {"attachAuxEffect",     "(I)V",                             (void *)android_media_MediaPlayer_attachAuxEffect},
     {"native_pullBatteryData", "(Landroid/os/Parcel;)I",        (void *)android_media_MediaPlayer_pullBatteryData},
-    {"setParameter",        "(ILandroid/os/Parcel;)Z",          (void *)android_media_MediaPlayer_setParameter},
-    {"getParameter",        "(ILandroid/os/Parcel;)V",          (void *)android_media_MediaPlayer_getParameter},
     {"native_setRetransmitEndpoint", "(Ljava/lang/String;I)I",  (void *)android_media_MediaPlayer_setRetransmitEndpoint},
     {"setNextMediaPlayer",  "(Landroid/media/MediaPlayer;)V",   (void *)android_media_MediaPlayer_setNextMediaPlayer},
     {"updateProxyConfig", "(Landroid/net/ProxyProperties;)V", (void *)android_media_MediaPlayer_updateProxyConfig},
@@ -940,6 +897,7 @@
                 "android/media/MediaPlayer", gMethods, NELEM(gMethods));
 }
 
+extern int register_android_media_ImageReader(JNIEnv *env);
 extern int register_android_media_Crypto(JNIEnv *env);
 extern int register_android_media_Drm(JNIEnv *env);
 extern int register_android_media_MediaCodec(JNIEnv *env);
@@ -967,6 +925,11 @@
     }
     assert(env != NULL);
 
+    if (register_android_media_ImageReader(env) < 0) {
+        ALOGE("ERROR: ImageReader native registration failed");
+        goto bail;
+    }
+
     if (register_android_media_MediaPlayer(env) < 0) {
         ALOGE("ERROR: MediaPlayer native registration failed\n");
         goto bail;
diff --git a/media/jni/android_media_MediaScanner.cpp b/media/jni/android_media_MediaScanner.cpp
index 5d27966..4e3d14e 100644
--- a/media/jni/android_media_MediaScanner.cpp
+++ b/media/jni/android_media_MediaScanner.cpp
@@ -25,6 +25,7 @@
 #include "jni.h"
 #include "JNIHelp.h"
 #include "android_runtime/AndroidRuntime.h"
+#include "android_runtime/Log.h"
 
 using namespace android;
 
diff --git a/media/jni/android_media_Utils.cpp b/media/jni/android_media_Utils.cpp
index e35ace3..54c5e9b 100644
--- a/media/jni/android_media_Utils.cpp
+++ b/media/jni/android_media_Utils.cpp
@@ -24,6 +24,8 @@
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/AMessage.h>
 
+#include <nativehelper/ScopedLocalRef.h>
+
 namespace android {
 
 bool ConvertKeyValueArraysToKeyedVector(
@@ -76,33 +78,35 @@
 }
 
 static jobject makeIntegerObject(JNIEnv *env, int32_t value) {
-    jclass clazz = env->FindClass("java/lang/Integer");
-    CHECK(clazz != NULL);
+    ScopedLocalRef<jclass> clazz(env, env->FindClass("java/lang/Integer"));
+    CHECK(clazz.get() != NULL);
 
-    jmethodID integerConstructID = env->GetMethodID(clazz, "<init>", "(I)V");
+    jmethodID integerConstructID =
+        env->GetMethodID(clazz.get(), "<init>", "(I)V");
     CHECK(integerConstructID != NULL);
 
-    return env->NewObject(clazz, integerConstructID, value);
+    return env->NewObject(clazz.get(), integerConstructID, value);
 }
 
 static jobject makeLongObject(JNIEnv *env, int64_t value) {
-    jclass clazz = env->FindClass("java/lang/Long");
-    CHECK(clazz != NULL);
+    ScopedLocalRef<jclass> clazz(env, env->FindClass("java/lang/Long"));
+    CHECK(clazz.get() != NULL);
 
-    jmethodID longConstructID = env->GetMethodID(clazz, "<init>", "(J)V");
+    jmethodID longConstructID = env->GetMethodID(clazz.get(), "<init>", "(J)V");
     CHECK(longConstructID != NULL);
 
-    return env->NewObject(clazz, longConstructID, value);
+    return env->NewObject(clazz.get(), longConstructID, value);
 }
 
 static jobject makeFloatObject(JNIEnv *env, float value) {
-    jclass clazz = env->FindClass("java/lang/Float");
-    CHECK(clazz != NULL);
+    ScopedLocalRef<jclass> clazz(env, env->FindClass("java/lang/Float"));
+    CHECK(clazz.get() != NULL);
 
-    jmethodID floatConstructID = env->GetMethodID(clazz, "<init>", "(F)V");
+    jmethodID floatConstructID =
+        env->GetMethodID(clazz.get(), "<init>", "(F)V");
     CHECK(floatConstructID != NULL);
 
-    return env->NewObject(clazz, floatConstructID, value);
+    return env->NewObject(clazz.get(), floatConstructID, value);
 }
 
 static jobject makeByteBufferObject(
@@ -110,15 +114,16 @@
     jbyteArray byteArrayObj = env->NewByteArray(size);
     env->SetByteArrayRegion(byteArrayObj, 0, size, (const jbyte *)data);
 
-    jclass clazz = env->FindClass("java/nio/ByteBuffer");
-    CHECK(clazz != NULL);
+    ScopedLocalRef<jclass> clazz(env, env->FindClass("java/nio/ByteBuffer"));
+    CHECK(clazz.get() != NULL);
 
     jmethodID byteBufWrapID =
-        env->GetStaticMethodID(clazz, "wrap", "([B)Ljava/nio/ByteBuffer;");
+        env->GetStaticMethodID(
+                clazz.get(), "wrap", "([B)Ljava/nio/ByteBuffer;");
     CHECK(byteBufWrapID != NULL);
 
     jobject byteBufObj = env->CallStaticObjectMethod(
-            clazz, byteBufWrapID, byteArrayObj);
+            clazz.get(), byteBufWrapID, byteArrayObj);
 
     env->DeleteLocalRef(byteArrayObj); byteArrayObj = NULL;
 
@@ -140,14 +145,15 @@
 
 status_t ConvertMessageToMap(
         JNIEnv *env, const sp<AMessage> &msg, jobject *map) {
-    jclass hashMapClazz = env->FindClass("java/util/HashMap");
+    ScopedLocalRef<jclass> hashMapClazz(
+            env, env->FindClass("java/util/HashMap"));
 
-    if (hashMapClazz == NULL) {
+    if (hashMapClazz.get() == NULL) {
         return -EINVAL;
     }
 
     jmethodID hashMapConstructID =
-        env->GetMethodID(hashMapClazz, "<init>", "()V");
+        env->GetMethodID(hashMapClazz.get(), "<init>", "()V");
 
     if (hashMapConstructID == NULL) {
         return -EINVAL;
@@ -155,7 +161,7 @@
 
     jmethodID hashMapPutID =
         env->GetMethodID(
-                hashMapClazz,
+                hashMapClazz.get(),
                 "put",
                 "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
 
@@ -163,7 +169,7 @@
         return -EINVAL;
     }
 
-    jobject hashMap = env->NewObject(hashMapClazz, hashMapConstructID);
+    jobject hashMap = env->NewObject(hashMapClazz.get(), hashMapConstructID);
 
     for (size_t i = 0; i < msg->countEntries(); ++i) {
         AMessage::Type valueType;
@@ -276,17 +282,16 @@
 status_t ConvertKeyValueArraysToMessage(
         JNIEnv *env, jobjectArray keys, jobjectArray values,
         sp<AMessage> *out) {
-    jclass stringClass = env->FindClass("java/lang/String");
-    CHECK(stringClass != NULL);
-
-    jclass integerClass = env->FindClass("java/lang/Integer");
-    CHECK(integerClass != NULL);
-
-    jclass floatClass = env->FindClass("java/lang/Float");
-    CHECK(floatClass != NULL);
-
-    jclass byteBufClass = env->FindClass("java/nio/ByteBuffer");
-    CHECK(byteBufClass != NULL);
+    ScopedLocalRef<jclass> stringClass(env, env->FindClass("java/lang/String"));
+    CHECK(stringClass.get() != NULL);
+    ScopedLocalRef<jclass> integerClass(env, env->FindClass("java/lang/Integer"));
+    CHECK(integerClass.get() != NULL);
+    ScopedLocalRef<jclass> longClass(env, env->FindClass("java/lang/Long"));
+    CHECK(longClass.get() != NULL);
+    ScopedLocalRef<jclass> floatClass(env, env->FindClass("java/lang/Float"));
+    CHECK(floatClass.get() != NULL);
+    ScopedLocalRef<jclass> byteBufClass(env, env->FindClass("java/nio/ByteBuffer"));
+    CHECK(byteBufClass.get() != NULL);
 
     sp<AMessage> msg = new AMessage;
 
@@ -309,7 +314,7 @@
     for (jsize i = 0; i < numEntries; ++i) {
         jobject keyObj = env->GetObjectArrayElement(keys, i);
 
-        if (!env->IsInstanceOf(keyObj, stringClass)) {
+        if (!env->IsInstanceOf(keyObj, stringClass.get())) {
             return -EINVAL;
         }
 
@@ -326,7 +331,7 @@
 
         jobject valueObj = env->GetObjectArrayElement(values, i);
 
-        if (env->IsInstanceOf(valueObj, stringClass)) {
+        if (env->IsInstanceOf(valueObj, stringClass.get())) {
             const char *value = env->GetStringUTFChars((jstring)valueObj, NULL);
 
             if (value == NULL) {
@@ -337,29 +342,37 @@
 
             env->ReleaseStringUTFChars((jstring)valueObj, value);
             value = NULL;
-        } else if (env->IsInstanceOf(valueObj, integerClass)) {
+        } else if (env->IsInstanceOf(valueObj, integerClass.get())) {
             jmethodID intValueID =
-                env->GetMethodID(integerClass, "intValue", "()I");
+                env->GetMethodID(integerClass.get(), "intValue", "()I");
             CHECK(intValueID != NULL);
 
             jint value = env->CallIntMethod(valueObj, intValueID);
 
             msg->setInt32(key.c_str(), value);
-        } else if (env->IsInstanceOf(valueObj, floatClass)) {
+        } else if (env->IsInstanceOf(valueObj, longClass.get())) {
+            jmethodID longValueID =
+                env->GetMethodID(longClass.get(), "longValue", "()J");
+            CHECK(longValueID != NULL);
+
+            jlong value = env->CallLongMethod(valueObj, longValueID);
+
+            msg->setInt64(key.c_str(), value);
+        } else if (env->IsInstanceOf(valueObj, floatClass.get())) {
             jmethodID floatValueID =
-                env->GetMethodID(floatClass, "floatValue", "()F");
+                env->GetMethodID(floatClass.get(), "floatValue", "()F");
             CHECK(floatValueID != NULL);
 
             jfloat value = env->CallFloatMethod(valueObj, floatValueID);
 
             msg->setFloat(key.c_str(), value);
-        } else if (env->IsInstanceOf(valueObj, byteBufClass)) {
+        } else if (env->IsInstanceOf(valueObj, byteBufClass.get())) {
             jmethodID positionID =
-                env->GetMethodID(byteBufClass, "position", "()I");
+                env->GetMethodID(byteBufClass.get(), "position", "()I");
             CHECK(positionID != NULL);
 
             jmethodID limitID =
-                env->GetMethodID(byteBufClass, "limit", "()I");
+                env->GetMethodID(byteBufClass.get(), "limit", "()I");
             CHECK(limitID != NULL);
 
             jint position = env->CallIntMethod(valueObj, positionID);
@@ -375,7 +388,7 @@
                        buffer->size());
             } else {
                 jmethodID arrayID =
-                    env->GetMethodID(byteBufClass, "array", "()[B");
+                    env->GetMethodID(byteBufClass.get(), "array", "()[B");
                 CHECK(arrayID != NULL);
 
                 jbyteArray byteArray =
diff --git a/media/jni/android_mtp_MtpDatabase.cpp b/media/jni/android_mtp_MtpDatabase.cpp
index fbd5d21..77c7966 100644
--- a/media/jni/android_mtp_MtpDatabase.cpp
+++ b/media/jni/android_mtp_MtpDatabase.cpp
@@ -26,6 +26,7 @@
 #include "jni.h"
 #include "JNIHelp.h"
 #include "android_runtime/AndroidRuntime.h"
+#include "android_runtime/Log.h"
 
 #include "MtpDatabase.h"
 #include "MtpDataPacket.h"
diff --git a/media/jni/android_mtp_MtpDevice.cpp b/media/jni/android_mtp_MtpDevice.cpp
index 113784e..b61b66c 100644
--- a/media/jni/android_mtp_MtpDevice.cpp
+++ b/media/jni/android_mtp_MtpDevice.cpp
@@ -28,6 +28,7 @@
 #include "jni.h"
 #include "JNIHelp.h"
 #include "android_runtime/AndroidRuntime.h"
+#include "android_runtime/Log.h"
 #include "private/android_filesystem_config.h"
 
 #include "MtpTypes.h"
diff --git a/media/jni/mediaeditor/VideoEditorClasses.cpp b/media/jni/mediaeditor/VideoEditorClasses.cpp
index 4982a47..d8099dd 100644
--- a/media/jni/mediaeditor/VideoEditorClasses.cpp
+++ b/media/jni/mediaeditor/VideoEditorClasses.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "VideoEditorClasses"
 
 #include <VideoEditorClasses.h>
 #include <VideoEditorJava.h>
diff --git a/media/jni/mediaeditor/VideoEditorJava.cpp b/media/jni/mediaeditor/VideoEditorJava.cpp
index bcf9099..fde0fb5 100644
--- a/media/jni/mediaeditor/VideoEditorJava.cpp
+++ b/media/jni/mediaeditor/VideoEditorJava.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "VideoEditorJava"
+
 #include <VideoEditorClasses.h>
 #include <VideoEditorJava.h>
 #include <VideoEditorLogging.h>
diff --git a/media/jni/mediaeditor/VideoEditorLogging.h b/media/jni/mediaeditor/VideoEditorLogging.h
index 479d8b6..1f1228a 100644
--- a/media/jni/mediaeditor/VideoEditorLogging.h
+++ b/media/jni/mediaeditor/VideoEditorLogging.h
@@ -17,6 +17,16 @@
 #ifndef VIDEO_EDITOR_LOGGING_H
 #define VIDEO_EDITOR_LOGGING_H
 
+#ifndef LOG_TAG
+#error "No LOG_TAG defined!"
+#endif
+
+/*
+ * This file is used as a proxy for cutils/log.h.  Include cutils/log.h here to
+ * avoid relying on import ordering.
+ */
+#include <cutils/log.h>
+
 //#define VIDEOEDIT_LOGGING_ENABLED
 
 #define VIDEOEDIT_LOG_INDENTATION                       (3)
diff --git a/media/jni/mediaeditor/VideoEditorOsal.cpp b/media/jni/mediaeditor/VideoEditorOsal.cpp
index a8c08ac..c12b1f5 100644
--- a/media/jni/mediaeditor/VideoEditorOsal.cpp
+++ b/media/jni/mediaeditor/VideoEditorOsal.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "VideoEditorOsal"
+
 #include <VideoEditorJava.h>
 #include <VideoEditorLogging.h>
 #include <VideoEditorOsal.h>
diff --git a/media/jni/mediaeditor/VideoEditorPropertiesMain.cpp b/media/jni/mediaeditor/VideoEditorPropertiesMain.cpp
index c8fb263..2f8e357 100644
--- a/media/jni/mediaeditor/VideoEditorPropertiesMain.cpp
+++ b/media/jni/mediaeditor/VideoEditorPropertiesMain.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "VideoEditorPropertiesMain"
+
 #include <dlfcn.h>
 #include <stdio.h>
 #include <unistd.h>
diff --git a/media/jni/soundpool/Android.mk b/media/jni/soundpool/Android.mk
index 5835b9f..ed8d7c1 100644
--- a/media/jni/soundpool/Android.mk
+++ b/media/jni/soundpool/Android.mk
@@ -2,7 +2,7 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
-	android_media_SoundPool.cpp
+	android_media_SoundPool_SoundPoolImpl.cpp
 
 LOCAL_SHARED_LIBRARIES := \
 	liblog \
diff --git a/media/jni/soundpool/android_media_SoundPool.cpp b/media/jni/soundpool/android_media_SoundPool.cpp
deleted file mode 100644
index 9658856..0000000
--- a/media/jni/soundpool/android_media_SoundPool.cpp
+++ /dev/null
@@ -1,327 +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.
- */
-
-#include <stdio.h>
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "SoundPool-JNI"
-
-#include <utils/Log.h>
-#include <nativehelper/jni.h>
-#include <nativehelper/JNIHelp.h>
-#include <android_runtime/AndroidRuntime.h>
-#include <media/SoundPool.h>
-
-using namespace android;
-
-static struct fields_t {
-    jfieldID    mNativeContext;
-    jmethodID   mPostEvent;
-    jclass      mSoundPoolClass;
-} fields;
-
-static inline SoundPool* MusterSoundPool(JNIEnv *env, jobject thiz) {
-    return (SoundPool*)env->GetIntField(thiz, fields.mNativeContext);
-}
-
-// ----------------------------------------------------------------------------
-static int
-android_media_SoundPool_load_URL(JNIEnv *env, jobject thiz, jstring path, jint priority)
-{
-    ALOGV("android_media_SoundPool_load_URL");
-    SoundPool *ap = MusterSoundPool(env, thiz);
-    if (path == NULL) {
-        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
-        return 0;
-    }
-    const char* s = env->GetStringUTFChars(path, NULL);
-    int id = ap->load(s, priority);
-    env->ReleaseStringUTFChars(path, s);
-    return id;
-}
-
-static int
-android_media_SoundPool_load_FD(JNIEnv *env, jobject thiz, jobject fileDescriptor,
-        jlong offset, jlong length, jint priority)
-{
-    ALOGV("android_media_SoundPool_load_FD");
-    SoundPool *ap = MusterSoundPool(env, thiz);
-    if (ap == NULL) return 0;
-    return ap->load(jniGetFDFromFileDescriptor(env, fileDescriptor),
-            int64_t(offset), int64_t(length), int(priority));
-}
-
-static bool
-android_media_SoundPool_unload(JNIEnv *env, jobject thiz, jint sampleID) {
-    ALOGV("android_media_SoundPool_unload\n");
-    SoundPool *ap = MusterSoundPool(env, thiz);
-    if (ap == NULL) return 0;
-    return ap->unload(sampleID);
-}
-
-static int
-android_media_SoundPool_play(JNIEnv *env, jobject thiz, jint sampleID,
-        jfloat leftVolume, jfloat rightVolume, jint priority, jint loop,
-        jfloat rate)
-{
-    ALOGV("android_media_SoundPool_play\n");
-    SoundPool *ap = MusterSoundPool(env, thiz);
-    if (ap == NULL) return 0;
-    return ap->play(sampleID, leftVolume, rightVolume, priority, loop, rate);
-}
-
-static void
-android_media_SoundPool_pause(JNIEnv *env, jobject thiz, jint channelID)
-{
-    ALOGV("android_media_SoundPool_pause");
-    SoundPool *ap = MusterSoundPool(env, thiz);
-    if (ap == NULL) return;
-    ap->pause(channelID);
-}
-
-static void
-android_media_SoundPool_resume(JNIEnv *env, jobject thiz, jint channelID)
-{
-    ALOGV("android_media_SoundPool_resume");
-    SoundPool *ap = MusterSoundPool(env, thiz);
-    if (ap == NULL) return;
-    ap->resume(channelID);
-}
-
-static void
-android_media_SoundPool_autoPause(JNIEnv *env, jobject thiz)
-{
-    ALOGV("android_media_SoundPool_autoPause");
-    SoundPool *ap = MusterSoundPool(env, thiz);
-    if (ap == NULL) return;
-    ap->autoPause();
-}
-
-static void
-android_media_SoundPool_autoResume(JNIEnv *env, jobject thiz)
-{
-    ALOGV("android_media_SoundPool_autoResume");
-    SoundPool *ap = MusterSoundPool(env, thiz);
-    if (ap == NULL) return;
-    ap->autoResume();
-}
-
-static void
-android_media_SoundPool_stop(JNIEnv *env, jobject thiz, jint channelID)
-{
-    ALOGV("android_media_SoundPool_stop");
-    SoundPool *ap = MusterSoundPool(env, thiz);
-    if (ap == NULL) return;
-    ap->stop(channelID);
-}
-
-static void
-android_media_SoundPool_setVolume(JNIEnv *env, jobject thiz, jint channelID,
-        float leftVolume, float rightVolume)
-{
-    ALOGV("android_media_SoundPool_setVolume");
-    SoundPool *ap = MusterSoundPool(env, thiz);
-    if (ap == NULL) return;
-    ap->setVolume(channelID, leftVolume, rightVolume);
-}
-
-static void
-android_media_SoundPool_setPriority(JNIEnv *env, jobject thiz, jint channelID,
-        int priority)
-{
-    ALOGV("android_media_SoundPool_setPriority");
-    SoundPool *ap = MusterSoundPool(env, thiz);
-    if (ap == NULL) return;
-    ap->setPriority(channelID, priority);
-}
-
-static void
-android_media_SoundPool_setLoop(JNIEnv *env, jobject thiz, jint channelID,
-        int loop)
-{
-    ALOGV("android_media_SoundPool_setLoop");
-    SoundPool *ap = MusterSoundPool(env, thiz);
-    if (ap == NULL) return;
-    ap->setLoop(channelID, loop);
-}
-
-static void
-android_media_SoundPool_setRate(JNIEnv *env, jobject thiz, jint channelID,
-        float rate)
-{
-    ALOGV("android_media_SoundPool_setRate");
-    SoundPool *ap = MusterSoundPool(env, thiz);
-    if (ap == NULL) return;
-    ap->setRate(channelID, rate);
-}
-
-static void android_media_callback(SoundPoolEvent event, SoundPool* soundPool, void* user)
-{
-    ALOGV("callback: (%d, %d, %d, %p, %p)", event.mMsg, event.mArg1, event.mArg2, soundPool, user);
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
-    env->CallStaticVoidMethod(fields.mSoundPoolClass, fields.mPostEvent, user, event.mMsg, event.mArg1, event.mArg2, NULL);
-}
-
-static jint
-android_media_SoundPool_native_setup(JNIEnv *env, jobject thiz, jobject weakRef, jint maxChannels, jint streamType, jint srcQuality)
-{
-    ALOGV("android_media_SoundPool_native_setup");
-    SoundPool *ap = new SoundPool(maxChannels, (audio_stream_type_t) streamType, srcQuality);
-    if (ap == NULL) {
-        return -1;
-    }
-
-    // save pointer to SoundPool C++ object in opaque field in Java object
-    env->SetIntField(thiz, fields.mNativeContext, (int)ap);
-
-    // set callback with weak reference
-    jobject globalWeakRef = env->NewGlobalRef(weakRef);
-    ap->setCallback(android_media_callback, globalWeakRef);
-    return 0;
-}
-
-static void
-android_media_SoundPool_release(JNIEnv *env, jobject thiz)
-{
-    ALOGV("android_media_SoundPool_release");
-    SoundPool *ap = MusterSoundPool(env, thiz);
-    if (ap != NULL) {
-
-        // release weak reference
-        jobject weakRef = (jobject) ap->getUserData();
-        if (weakRef != NULL) {
-            env->DeleteGlobalRef(weakRef);
-        }
-
-        // clear callback and native context
-        ap->setCallback(NULL, NULL);
-        env->SetIntField(thiz, fields.mNativeContext, 0);
-        delete ap;
-    }
-}
-
-// ----------------------------------------------------------------------------
-
-// Dalvik VM type signatures
-static JNINativeMethod gMethods[] = {
-    {   "_load",
-        "(Ljava/lang/String;I)I",
-        (void *)android_media_SoundPool_load_URL
-    },
-    {   "_load",
-        "(Ljava/io/FileDescriptor;JJI)I",
-        (void *)android_media_SoundPool_load_FD
-    },
-    {   "unload",
-        "(I)Z",
-        (void *)android_media_SoundPool_unload
-    },
-    {   "play",
-        "(IFFIIF)I",
-        (void *)android_media_SoundPool_play
-    },
-    {   "pause",
-        "(I)V",
-        (void *)android_media_SoundPool_pause
-    },
-    {   "resume",
-        "(I)V",
-        (void *)android_media_SoundPool_resume
-    },
-    {   "autoPause",
-        "()V",
-        (void *)android_media_SoundPool_autoPause
-    },
-    {   "autoResume",
-        "()V",
-        (void *)android_media_SoundPool_autoResume
-    },
-    {   "stop",
-        "(I)V",
-        (void *)android_media_SoundPool_stop
-    },
-    {   "setVolume",
-        "(IFF)V",
-        (void *)android_media_SoundPool_setVolume
-    },
-    {   "setPriority",
-        "(II)V",
-        (void *)android_media_SoundPool_setPriority
-    },
-    {   "setLoop",
-        "(II)V",
-        (void *)android_media_SoundPool_setLoop
-    },
-    {   "setRate",
-        "(IF)V",
-        (void *)android_media_SoundPool_setRate
-    },
-    {   "native_setup",
-        "(Ljava/lang/Object;III)I",
-        (void*)android_media_SoundPool_native_setup
-    },
-    {   "release",
-        "()V",
-        (void*)android_media_SoundPool_release
-    }
-};
-
-static const char* const kClassPathName = "android/media/SoundPool";
-
-jint JNI_OnLoad(JavaVM* vm, void* reserved)
-{
-    JNIEnv* env = NULL;
-    jint result = -1;
-    jclass clazz;
-
-    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
-        ALOGE("ERROR: GetEnv failed\n");
-        goto bail;
-    }
-    assert(env != NULL);
-
-    clazz = env->FindClass(kClassPathName);
-    if (clazz == NULL) {
-        ALOGE("Can't find %s", kClassPathName);
-        goto bail;
-    }
-
-    fields.mNativeContext = env->GetFieldID(clazz, "mNativeContext", "I");
-    if (fields.mNativeContext == NULL) {
-        ALOGE("Can't find SoundPool.mNativeContext");
-        goto bail;
-    }
-
-    fields.mPostEvent = env->GetStaticMethodID(clazz, "postEventFromNative",
-                                               "(Ljava/lang/Object;IIILjava/lang/Object;)V");
-    if (fields.mPostEvent == NULL) {
-        ALOGE("Can't find android/media/SoundPool.postEventFromNative");
-        goto bail;
-    }
-
-    // create a reference to class. Technically, we're leaking this reference
-    // since it's a static object.
-    fields.mSoundPoolClass = (jclass) env->NewGlobalRef(clazz);
-
-    if (AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods)) < 0)
-        goto bail;
-
-    /* success -- return valid version number */
-    result = JNI_VERSION_1_4;
-
-bail:
-    return result;
-}
diff --git a/media/jni/soundpool/android_media_SoundPool_SoundPoolImpl.cpp b/media/jni/soundpool/android_media_SoundPool_SoundPoolImpl.cpp
new file mode 100644
index 0000000..2604850
--- /dev/null
+++ b/media/jni/soundpool/android_media_SoundPool_SoundPoolImpl.cpp
@@ -0,0 +1,327 @@
+/*
+ * 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.
+ */
+
+#include <stdio.h>
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "SoundPool-JNI"
+
+#include <utils/Log.h>
+#include <nativehelper/jni.h>
+#include <nativehelper/JNIHelp.h>
+#include <android_runtime/AndroidRuntime.h>
+#include <media/SoundPool.h>
+
+using namespace android;
+
+static struct fields_t {
+    jfieldID    mNativeContext;
+    jmethodID   mPostEvent;
+    jclass      mSoundPoolClass;
+} fields;
+
+static inline SoundPool* MusterSoundPool(JNIEnv *env, jobject thiz) {
+    return (SoundPool*)env->GetIntField(thiz, fields.mNativeContext);
+}
+
+// ----------------------------------------------------------------------------
+static int
+android_media_SoundPool_SoundPoolImpl_load_URL(JNIEnv *env, jobject thiz, jstring path, jint priority)
+{
+    ALOGV("android_media_SoundPool_SoundPoolImpl_load_URL");
+    SoundPool *ap = MusterSoundPool(env, thiz);
+    if (path == NULL) {
+        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+        return 0;
+    }
+    const char* s = env->GetStringUTFChars(path, NULL);
+    int id = ap->load(s, priority);
+    env->ReleaseStringUTFChars(path, s);
+    return id;
+}
+
+static int
+android_media_SoundPool_SoundPoolImpl_load_FD(JNIEnv *env, jobject thiz, jobject fileDescriptor,
+        jlong offset, jlong length, jint priority)
+{
+    ALOGV("android_media_SoundPool_SoundPoolImpl_load_FD");
+    SoundPool *ap = MusterSoundPool(env, thiz);
+    if (ap == NULL) return 0;
+    return ap->load(jniGetFDFromFileDescriptor(env, fileDescriptor),
+            int64_t(offset), int64_t(length), int(priority));
+}
+
+static bool
+android_media_SoundPool_SoundPoolImpl_unload(JNIEnv *env, jobject thiz, jint sampleID) {
+    ALOGV("android_media_SoundPool_SoundPoolImpl_unload\n");
+    SoundPool *ap = MusterSoundPool(env, thiz);
+    if (ap == NULL) return 0;
+    return ap->unload(sampleID);
+}
+
+static int
+android_media_SoundPool_SoundPoolImpl_play(JNIEnv *env, jobject thiz, jint sampleID,
+        jfloat leftVolume, jfloat rightVolume, jint priority, jint loop,
+        jfloat rate)
+{
+    ALOGV("android_media_SoundPool_SoundPoolImpl_play\n");
+    SoundPool *ap = MusterSoundPool(env, thiz);
+    if (ap == NULL) return 0;
+    return ap->play(sampleID, leftVolume, rightVolume, priority, loop, rate);
+}
+
+static void
+android_media_SoundPool_SoundPoolImpl_pause(JNIEnv *env, jobject thiz, jint channelID)
+{
+    ALOGV("android_media_SoundPool_SoundPoolImpl_pause");
+    SoundPool *ap = MusterSoundPool(env, thiz);
+    if (ap == NULL) return;
+    ap->pause(channelID);
+}
+
+static void
+android_media_SoundPool_SoundPoolImpl_resume(JNIEnv *env, jobject thiz, jint channelID)
+{
+    ALOGV("android_media_SoundPool_SoundPoolImpl_resume");
+    SoundPool *ap = MusterSoundPool(env, thiz);
+    if (ap == NULL) return;
+    ap->resume(channelID);
+}
+
+static void
+android_media_SoundPool_SoundPoolImpl_autoPause(JNIEnv *env, jobject thiz)
+{
+    ALOGV("android_media_SoundPool_SoundPoolImpl_autoPause");
+    SoundPool *ap = MusterSoundPool(env, thiz);
+    if (ap == NULL) return;
+    ap->autoPause();
+}
+
+static void
+android_media_SoundPool_SoundPoolImpl_autoResume(JNIEnv *env, jobject thiz)
+{
+    ALOGV("android_media_SoundPool_SoundPoolImpl_autoResume");
+    SoundPool *ap = MusterSoundPool(env, thiz);
+    if (ap == NULL) return;
+    ap->autoResume();
+}
+
+static void
+android_media_SoundPool_SoundPoolImpl_stop(JNIEnv *env, jobject thiz, jint channelID)
+{
+    ALOGV("android_media_SoundPool_SoundPoolImpl_stop");
+    SoundPool *ap = MusterSoundPool(env, thiz);
+    if (ap == NULL) return;
+    ap->stop(channelID);
+}
+
+static void
+android_media_SoundPool_SoundPoolImpl_setVolume(JNIEnv *env, jobject thiz, jint channelID,
+        float leftVolume, float rightVolume)
+{
+    ALOGV("android_media_SoundPool_SoundPoolImpl_setVolume");
+    SoundPool *ap = MusterSoundPool(env, thiz);
+    if (ap == NULL) return;
+    ap->setVolume(channelID, leftVolume, rightVolume);
+}
+
+static void
+android_media_SoundPool_SoundPoolImpl_setPriority(JNIEnv *env, jobject thiz, jint channelID,
+        int priority)
+{
+    ALOGV("android_media_SoundPool_SoundPoolImpl_setPriority");
+    SoundPool *ap = MusterSoundPool(env, thiz);
+    if (ap == NULL) return;
+    ap->setPriority(channelID, priority);
+}
+
+static void
+android_media_SoundPool_SoundPoolImpl_setLoop(JNIEnv *env, jobject thiz, jint channelID,
+        int loop)
+{
+    ALOGV("android_media_SoundPool_SoundPoolImpl_setLoop");
+    SoundPool *ap = MusterSoundPool(env, thiz);
+    if (ap == NULL) return;
+    ap->setLoop(channelID, loop);
+}
+
+static void
+android_media_SoundPool_SoundPoolImpl_setRate(JNIEnv *env, jobject thiz, jint channelID,
+        float rate)
+{
+    ALOGV("android_media_SoundPool_SoundPoolImpl_setRate");
+    SoundPool *ap = MusterSoundPool(env, thiz);
+    if (ap == NULL) return;
+    ap->setRate(channelID, rate);
+}
+
+static void android_media_callback(SoundPoolEvent event, SoundPool* soundPool, void* user)
+{
+    ALOGV("callback: (%d, %d, %d, %p, %p)", event.mMsg, event.mArg1, event.mArg2, soundPool, user);
+    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    env->CallStaticVoidMethod(fields.mSoundPoolClass, fields.mPostEvent, user, event.mMsg, event.mArg1, event.mArg2, NULL);
+}
+
+static jint
+android_media_SoundPool_SoundPoolImpl_native_setup(JNIEnv *env, jobject thiz, jobject weakRef, jint maxChannels, jint streamType, jint srcQuality)
+{
+    ALOGV("android_media_SoundPool_SoundPoolImpl_native_setup");
+    SoundPool *ap = new SoundPool(maxChannels, (audio_stream_type_t) streamType, srcQuality);
+    if (ap == NULL) {
+        return -1;
+    }
+
+    // save pointer to SoundPool C++ object in opaque field in Java object
+    env->SetIntField(thiz, fields.mNativeContext, (int)ap);
+
+    // set callback with weak reference
+    jobject globalWeakRef = env->NewGlobalRef(weakRef);
+    ap->setCallback(android_media_callback, globalWeakRef);
+    return 0;
+}
+
+static void
+android_media_SoundPool_SoundPoolImpl_release(JNIEnv *env, jobject thiz)
+{
+    ALOGV("android_media_SoundPool_SoundPoolImpl_release");
+    SoundPool *ap = MusterSoundPool(env, thiz);
+    if (ap != NULL) {
+
+        // release weak reference
+        jobject weakRef = (jobject) ap->getUserData();
+        if (weakRef != NULL) {
+            env->DeleteGlobalRef(weakRef);
+        }
+
+        // clear callback and native context
+        ap->setCallback(NULL, NULL);
+        env->SetIntField(thiz, fields.mNativeContext, 0);
+        delete ap;
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+// Dalvik VM type signatures
+static JNINativeMethod gMethods[] = {
+    {   "_load",
+        "(Ljava/lang/String;I)I",
+        (void *)android_media_SoundPool_SoundPoolImpl_load_URL
+    },
+    {   "_load",
+        "(Ljava/io/FileDescriptor;JJI)I",
+        (void *)android_media_SoundPool_SoundPoolImpl_load_FD
+    },
+    {   "unload",
+        "(I)Z",
+        (void *)android_media_SoundPool_SoundPoolImpl_unload
+    },
+    {   "play",
+        "(IFFIIF)I",
+        (void *)android_media_SoundPool_SoundPoolImpl_play
+    },
+    {   "pause",
+        "(I)V",
+        (void *)android_media_SoundPool_SoundPoolImpl_pause
+    },
+    {   "resume",
+        "(I)V",
+        (void *)android_media_SoundPool_SoundPoolImpl_resume
+    },
+    {   "autoPause",
+        "()V",
+        (void *)android_media_SoundPool_SoundPoolImpl_autoPause
+    },
+    {   "autoResume",
+        "()V",
+        (void *)android_media_SoundPool_SoundPoolImpl_autoResume
+    },
+    {   "stop",
+        "(I)V",
+        (void *)android_media_SoundPool_SoundPoolImpl_stop
+    },
+    {   "setVolume",
+        "(IFF)V",
+        (void *)android_media_SoundPool_SoundPoolImpl_setVolume
+    },
+    {   "setPriority",
+        "(II)V",
+        (void *)android_media_SoundPool_SoundPoolImpl_setPriority
+    },
+    {   "setLoop",
+        "(II)V",
+        (void *)android_media_SoundPool_SoundPoolImpl_setLoop
+    },
+    {   "setRate",
+        "(IF)V",
+        (void *)android_media_SoundPool_SoundPoolImpl_setRate
+    },
+    {   "native_setup",
+        "(Ljava/lang/Object;III)I",
+        (void*)android_media_SoundPool_SoundPoolImpl_native_setup
+    },
+    {   "release",
+        "()V",
+        (void*)android_media_SoundPool_SoundPoolImpl_release
+    }
+};
+
+static const char* const kClassPathName = "android/media/SoundPool$SoundPoolImpl";
+
+jint JNI_OnLoad(JavaVM* vm, void* reserved)
+{
+    JNIEnv* env = NULL;
+    jint result = -1;
+    jclass clazz;
+
+    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
+        ALOGE("ERROR: GetEnv failed\n");
+        goto bail;
+    }
+    assert(env != NULL);
+
+    clazz = env->FindClass(kClassPathName);
+    if (clazz == NULL) {
+        ALOGE("Can't find %s", kClassPathName);
+        goto bail;
+    }
+
+    fields.mNativeContext = env->GetFieldID(clazz, "mNativeContext", "I");
+    if (fields.mNativeContext == NULL) {
+        ALOGE("Can't find SoundPoolImpl.mNativeContext");
+        goto bail;
+    }
+
+    fields.mPostEvent = env->GetStaticMethodID(clazz, "postEventFromNative",
+                                               "(Ljava/lang/Object;IIILjava/lang/Object;)V");
+    if (fields.mPostEvent == NULL) {
+        ALOGE("Can't find android/media/SoundPoolImpl.postEventFromNative");
+        goto bail;
+    }
+
+    // create a reference to class. Technically, we're leaking this reference
+    // since it's a static object.
+    fields.mSoundPoolClass = (jclass) env->NewGlobalRef(clazz);
+
+    if (AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods)) < 0)
+        goto bail;
+
+    /* success -- return valid version number */
+    result = JNI_VERSION_1_4;
+
+bail:
+    return result;
+}
diff --git a/media/libdrm/Android.mk b/media/libdrm/Android.mk
deleted file mode 100644
index 5053e7d..0000000
--- a/media/libdrm/Android.mk
+++ /dev/null
@@ -1 +0,0 @@
-include $(call all-subdir-makefiles)
diff --git a/media/libdrm/MODULE_LICENSE_APACHE2 b/media/libdrm/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/media/libdrm/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/media/libdrm/NOTICE b/media/libdrm/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/media/libdrm/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
-   Copyright (c) 2005-2008, The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
diff --git a/media/libdrm/mobile1/Android.mk b/media/libdrm/mobile1/Android.mk
deleted file mode 100644
index 7356f46..0000000
--- a/media/libdrm/mobile1/Android.mk
+++ /dev/null
@@ -1,83 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-# ---------------------------------------
-# First project
-# 
-# Build DRM1 core library
-#
-# Output: libdrm1.so
-# ---------------------------------------
-include $(CLEAR_VARS)
-
-ifeq ($(TARGET_ARCH), arm)
-LOCAL_DRM_CFLAG = -DDRM_DEVICE_ARCH_ARM
-endif
-
-ifeq ($(TARGET_ARCH), x86)
-LOCAL_DRM_CFLAG = -DDRM_DEVICE_ARCH_X86
-endif
-
-# DRM 1.0 core source files
-LOCAL_SRC_FILES :=                  \
-    src/objmng/drm_decoder.c        \
-    src/objmng/drm_file.c           \
-    src/objmng/drm_i18n.c           \
-    src/objmng/drm_time.c           \
-    src/objmng/drm_api.c            \
-    src/objmng/drm_rights_manager.c \
-    src/parser/parser_dcf.c         \
-    src/parser/parser_dm.c          \
-    src/parser/parser_rel.c         \
-    src/xml/xml_tinyparser.c
-
-# Header files path
-LOCAL_C_INCLUDES :=                 \
-    $(LOCAL_PATH)/include           \
-    $(LOCAL_PATH)/include/objmng    \
-    $(LOCAL_PATH)/include/parser    \
-    $(LOCAL_PATH)/include/xml       \
-    external/openssl/include        \
-    $(call include-path-for, system-core)/cutils
-
-LOCAL_CFLAGS := $(LOCAL_DRM_CFLAG)
-
-LOCAL_SHARED_LIBRARIES :=   \
-    libutils                \
-    libcutils               \
-    liblog                  \
-    libcrypto
-
-LOCAL_MODULE := libdrm1
-
-include $(BUILD_SHARED_LIBRARY)
-
-# ---------------------------------------
-# Second project
-# 
-# Build DRM1 Java Native Interface(JNI) library
-#
-# Output: libdrm1_jni.so
-# ------------------------------------------------
-include $(CLEAR_VARS)
-
-# Source files of DRM1 Java Native Interfaces
-LOCAL_SRC_FILES :=      \
-    src/jni/drm1_jni.c
-
-# Header files path
-LOCAL_C_INCLUDES :=         \
-    $(LOCAL_PATH)/include   \
-    $(LOCAL_PATH)/include/parser \
-    $(JNI_H_INCLUDE)    \
-    $(call include-path-for, system-core)/cutils
-
-
-LOCAL_SHARED_LIBRARIES := libdrm1 \
-    libnativehelper               \
-    libutils                      \
-    libcutils                     \
-    liblog
-
-LOCAL_MODULE := libdrm1_jni
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libdrm/mobile1/include/drm_common_types.h b/media/libdrm/mobile1/include/drm_common_types.h
deleted file mode 100644
index c6bea61..0000000
--- a/media/libdrm/mobile1/include/drm_common_types.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __COMMON_TYPES_H__
-#define __COMMON_TYPES_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <assert.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#define Trace(...)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __COMMON_TYPES_H__ */
diff --git a/media/libdrm/mobile1/include/jni/drm1_jni.h b/media/libdrm/mobile1/include/jni/drm1_jni.h
deleted file mode 100644
index 64e78ad..0000000
--- a/media/libdrm/mobile1/include/jni/drm1_jni.h
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __DRM1_JNI_H__
-#define __DRM1_JNI_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include <jni.h>
-/* Header for class android_drm_mobile1_DrmRawContent */
-
-#undef android_drm_mobile1_DrmRawContent_DRM_FORWARD_LOCK
-#define android_drm_mobile1_DrmRawContent_DRM_FORWARD_LOCK 1L
-#undef android_drm_mobile1_DrmRawContent_DRM_COMBINED_DELIVERY
-#define android_drm_mobile1_DrmRawContent_DRM_COMBINED_DELIVERY 2L
-#undef android_drm_mobile1_DrmRawContent_DRM_SEPARATE_DELIVERY
-#define android_drm_mobile1_DrmRawContent_DRM_SEPARATE_DELIVERY 3L
-#undef android_drm_mobile1_DrmRawContent_DRM_SEPARATE_DELIVERY_DM
-#define android_drm_mobile1_DrmRawContent_DRM_SEPARATE_DELIVERY_DM 4L
-#undef android_drm_mobile1_DrmRawContent_DRM_MIMETYPE_MESSAGE
-#define android_drm_mobile1_DrmRawContent_DRM_MIMETYPE_MESSAGE 1L
-#undef android_drm_mobile1_DrmRawContent_DRM_MIMETYPE_CONTENT
-#define android_drm_mobile1_DrmRawContent_DRM_MIMETYPE_CONTENT 2L
-#undef android_drm_mobile1_DrmRawContent_JNI_DRM_SUCCESS
-#define android_drm_mobile1_DrmRawContent_JNI_DRM_SUCCESS 0L
-#undef android_drm_mobile1_DrmRawContent_JNI_DRM_FAILURE
-#define android_drm_mobile1_DrmRawContent_JNI_DRM_FAILURE -1L
-#undef android_drm_mobile1_DrmRawContent_JNI_DRM_EOF
-#define android_drm_mobile1_DrmRawContent_JNI_DRM_EOF -2L
-#undef android_drm_mobile1_DrmRawContent_JNI_DRM_UNKNOWN_DATA_LEN
-#define android_drm_mobile1_DrmRawContent_JNI_DRM_UNKNOWN_DATA_LEN -3L
-/*
- * Class:     android_drm_mobile1_DrmRawContent
- * Method:    nativeConstructDrmContent
- * Signature: (Ljava/io/InputStream;II)I
- */
-JNIEXPORT jint JNICALL Java_android_drm_mobile1_DrmRawContent_nativeConstructDrmContent
-  (JNIEnv *, jobject, jobject, jint, jint);
-
-/*
- * Class:     android_drm_mobile1_DrmRawContent
- * Method:    nativeGetRightsAddress
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL Java_android_drm_mobile1_DrmRawContent_nativeGetRightsAddress
-  (JNIEnv *, jobject);
-
-/*
- * Class:     android_drm_mobile1_DrmRawContent
- * Method:    nativeGetDeliveryMethod
- * Signature: ()I
- */
-JNIEXPORT jint JNICALL Java_android_drm_mobile1_DrmRawContent_nativeGetDeliveryMethod
-  (JNIEnv *, jobject);
-
-/*
- * Class:     android_drm_mobile1_DrmRawContent
- * Method:    nativeReadPieceOfContent
- * Signature: ([BIII)I
- */
-JNIEXPORT jint JNICALL Java_android_drm_mobile1_DrmRawContent_nativeReadContent
-  (JNIEnv *, jobject, jbyteArray, jint, jint, jint);
-
-/*
- * Class:     android_drm_mobile1_DrmRawContent
- * Method:    nativeGetContentType
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL Java_android_drm_mobile1_DrmRawContent_nativeGetContentType
-  (JNIEnv *, jobject);
-
-/*
- * Class:     android_drm_mobile1_DrmRawContent
- * Method:    nativeGetContentLength
- * Signature: ()I
- */
-JNIEXPORT jint JNICALL Java_android_drm_mobile1_DrmRawContent_nativeGetContentLength
-  (JNIEnv *, jobject);
-
-/*
- * Class:     android_drm_mobile1_DrmRawContent
- * Method:    finalize
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_android_drm_mobile1_DrmRawContent_finalize
-  (JNIEnv *, jobject);
-
-/* Header for class android_drm_mobile1_DrmRights */
-
-#undef android_drm_mobile1_DrmRights_DRM_PERMISSION_PLAY
-#define android_drm_mobile1_DrmRights_DRM_PERMISSION_PLAY 1L
-#undef android_drm_mobile1_DrmRights_DRM_PERMISSION_DISPLAY
-#define android_drm_mobile1_DrmRights_DRM_PERMISSION_DISPLAY 2L
-#undef android_drm_mobile1_DrmRights_DRM_PERMISSION_EXECUTE
-#define android_drm_mobile1_DrmRights_DRM_PERMISSION_EXECUTE 3L
-#undef android_drm_mobile1_DrmRights_DRM_PERMISSION_PRINT
-#define android_drm_mobile1_DrmRights_DRM_PERMISSION_PRINT 4L
-#undef android_drm_mobile1_DrmRights_DRM_CONSUME_RIGHTS_SUCCESS
-#define android_drm_mobile1_DrmRights_DRM_CONSUME_RIGHTS_SUCCESS 0L
-#undef android_drm_mobile1_DrmRights_DRM_CONSUME_RIGHTS_FAILURE
-#define android_drm_mobile1_DrmRights_DRM_CONSUME_RIGHTS_FAILURE -1L
-#undef android_drm_mobile1_DrmRights_JNI_DRM_SUCCESS
-#define android_drm_mobile1_DrmRights_JNI_DRM_SUCCESS 0L
-#undef android_drm_mobile1_DrmRights_JNI_DRM_FAILURE
-#define android_drm_mobile1_DrmRights_JNI_DRM_FAILURE -1L
-/*
- * Class:     android_drm_mobile1_DrmRights
- * Method:    nativeGetConstraintInfo
- * Signature: (ILandroid/drm/mobile1/DrmConstraintInfo;)I
- */
-JNIEXPORT jint JNICALL Java_android_drm_mobile1_DrmRights_nativeGetConstraintInfo
-  (JNIEnv *, jobject, jint, jobject);
-
-/*
- * Class:     android_drm_mobile1_DrmRights
- * Method:    nativeConsumeRights
- * Signature: (I)I
- */
-JNIEXPORT jint JNICALL Java_android_drm_mobile1_DrmRights_nativeConsumeRights
-  (JNIEnv *, jobject, jint);
-
-/* Header for class android_drm_mobile1_DrmRightsManager */
-
-#undef android_drm_mobile1_DrmRightsManager_DRM_MIMETYPE_RIGHTS_XML
-#define android_drm_mobile1_DrmRightsManager_DRM_MIMETYPE_RIGHTS_XML 3L
-#undef android_drm_mobile1_DrmRightsManager_DRM_MIMETYPE_RIGHTS_WBXML
-#define android_drm_mobile1_DrmRightsManager_DRM_MIMETYPE_RIGHTS_WBXML 4L
-#undef android_drm_mobile1_DrmRightsManager_DRM_MIMETYPE_MESSAGE
-#define android_drm_mobile1_DrmRightsManager_DRM_MIMETYPE_MESSAGE 1L
-#undef android_drm_mobile1_DrmRightsManager_JNI_DRM_SUCCESS
-#define android_drm_mobile1_DrmRightsManager_JNI_DRM_SUCCESS 0L
-#undef android_drm_mobile1_DrmRightsManager_JNI_DRM_FAILURE
-#define android_drm_mobile1_DrmRightsManager_JNI_DRM_FAILURE -1L
-/* Inaccessible static: singleton */
-/*
- * Class:     android_drm_mobile1_DrmRightsManager
- * Method:    nativeInstallDrmRights
- * Signature: (Ljava/io/InputStream;IILandroid/drm/mobile1/DrmRights;)I
- */
-JNIEXPORT jint JNICALL Java_android_drm_mobile1_DrmRightsManager_nativeInstallDrmRights
-  (JNIEnv *, jobject, jobject, jint, jint, jobject);
-
-/*
- * Class:     android_drm_mobile1_DrmRightsManager
- * Method:    nativeQueryRights
- * Signature: (Landroid/drm/mobile1/DrmRawContent;Landroid/drm/mobile1/DrmRights;)I
- */
-JNIEXPORT jint JNICALL Java_android_drm_mobile1_DrmRightsManager_nativeQueryRights
-  (JNIEnv *, jobject, jobject, jobject);
-
-/*
- * Class:     android_drm_mobile1_DrmRightsManager
- * Method:    nativeGetRightsNumber
- * Signature: ()I
- */
-JNIEXPORT jint JNICALL Java_android_drm_mobile1_DrmRightsManager_nativeGetNumOfRights
-  (JNIEnv *, jobject);
-
-/*
- * Class:     android_drm_mobile1_DrmRightsManager
- * Method:    nativeGetRightsList
- * Signature: ([Landroid/drm/mobile1/DrmRights;I)I
- */
-JNIEXPORT jint JNICALL Java_android_drm_mobile1_DrmRightsManager_nativeGetRightsList
-  (JNIEnv *, jobject, jobjectArray, jint);
-
-/*
- * Class:     android_drm_mobile1_DrmRightsManager
- * Method:    nativeDeleteRights
- * Signature: (Landroid/drm/mobile1/DrmRights;)I
- */
-JNIEXPORT jint JNICALL Java_android_drm_mobile1_DrmRightsManager_nativeDeleteRights
-  (JNIEnv *, jobject, jobject);
-
-/**
- * DRM return value defines
- */
-#define JNI_DRM_SUCCESS \
-    android_drm_mobile1_DrmRawContent_JNI_DRM_SUCCESS   /**< Successful operation */
-#define JNI_DRM_FAILURE \
-    android_drm_mobile1_DrmRawContent_JNI_DRM_FAILURE   /**< General failure */
-#define JNI_DRM_EOF \
-    android_drm_mobile1_DrmRawContent_JNI_DRM_EOF       /**< Indicates the end of the DRM content is reached */
-#define JNI_DRM_UNKNOWN_DATA_LEN \
-    android_drm_mobile1_DrmRawContent_JNI_DRM_UNKNOWN_DATA_LEN  /**< Indicates the data length is unknown */
-
-/**
- * DRM MIME type defines
- */
-#define JNI_DRM_MIMETYPE_MESSAGE \
-    android_drm_mobile1_DrmRawContent_DRM_MIMETYPE_MESSAGE          /**< The "application/vnd.oma.drm.message" MIME type */
-#define JNI_DRM_MIMETYPE_CONTENT \
-    android_drm_mobile1_DrmRawContent_DRM_MIMETYPE_CONTENT          /**< The "application/vnd.oma.drm.content" MIME type */
-#define JNI_DRM_MIMETYPE_RIGHTS_XML \
-    android_drm_mobile1_DrmRightsManager_DRM_MIMETYPE_RIGHTS_XML    /**< The "application/vnd.oma.drm.rights+xml" MIME type */
-#define JNI_DRM_MIMETYPE_RIGHTS_WBXML \
-    android_drm_mobile1_DrmRightsManager_DRM_MIMETYPE_RIGHTS_WBXML  /**< The "application/vnd.oma.drm.rights+wbxml" MIME type */
-
-/**
- * DRM permission defines
- */
-#define JNI_DRM_PERMISSION_PLAY \
-    android_drm_mobile1_DrmRights_DRM_PERMISSION_PLAY       /**< The permission to play */
-#define JNI_DRM_PERMISSION_DISPLAY \
-    android_drm_mobile1_DrmRights_DRM_PERMISSION_DISPLAY    /**< The permission to display */
-#define JNI_DRM_PERMISSION_EXECUTE \
-    android_drm_mobile1_DrmRights_DRM_PERMISSION_EXECUTE    /**< The permission to execute */
-#define JNI_DRM_PERMISSION_PRINT \
-    android_drm_mobile1_DrmRights_DRM_PERMISSION_PRINT      /**< The permission to print */
-
-/**
- * DRM delivery type defines
- */
-#define JNI_DRM_FORWARD_LOCK \
-    android_drm_mobile1_DrmRawContent_DRM_FORWARD_LOCK          /**< forward lock */
-#define JNI_DRM_COMBINED_DELIVERY \
-    android_drm_mobile1_DrmRawContent_DRM_COMBINED_DELIVERY     /**< combined delivery */
-#define JNI_DRM_SEPARATE_DELIVERY \
-    android_drm_mobile1_DrmRawContent_DRM_SEPARATE_DELIVERY     /**< separate delivery */
-#define JNI_DRM_SEPARATE_DELIVERY_DM \
-    android_drm_mobile1_DrmRawContent_DRM_SEPARATE_DELIVERY_DM  /**< separate delivery DRM message */
-#ifdef __cplusplus
-}
-#endif
-#endif /* __DRM1_JNI_H__ */
-
diff --git a/media/libdrm/mobile1/include/objmng/drm_decoder.h b/media/libdrm/mobile1/include/objmng/drm_decoder.h
deleted file mode 100644
index a769c81..0000000
--- a/media/libdrm/mobile1/include/objmng/drm_decoder.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file drm_decoder.h
- *
- * provide service to decode base64 data.
- *
- * <!-- #interface list begin -->
- * \section drm decoder interface
- * - drm_decodeBase64()
- * <!-- #interface list end -->
- */
-
-#ifndef __DRM_DECODER_H__
-#define __DRM_DECODER_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <drm_common_types.h>
-
-/**
- * Decode base64
- * \param dest          dest buffer to save decode base64 data
- * \param destLen       dest buffer length
- * \param src           source data to be decoded
- * \param srcLen        source buffer length, and when return, give out how many bytes has been decoded
- * \return
- *        -when success, return a positive integer of dest buffer length,
- *                       if input dest buffer is NULL or destLen is 0,
- *                       return dest buffer length that user should allocate to save decoding data
- *        -when failed, return -1
- */
-int32_t drm_decodeBase64(uint8_t * dest, int32_t destLen, uint8_t * src, int32_t * srcLen);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __DRM_DECODER_H__ */
diff --git a/media/libdrm/mobile1/include/objmng/drm_file.h b/media/libdrm/mobile1/include/objmng/drm_file.h
deleted file mode 100644
index b94ddd0..0000000
--- a/media/libdrm/mobile1/include/objmng/drm_file.h
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-/**
- * File Porting Layer.
- */
-#ifndef __DRM_FILE_H__
-#define __DRM_FILE_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <drm_common_types.h>
-
-/** Type value of a regular file or file name. */
-#define DRM_FILE_ISREG 1
-/** Type value of a directory or directory name. */
-#define DRM_FILE_ISDIR 2
-/** Type value of a filter name */
-#define DRM_FILE_ISFILTER 3
-
-
-/** Return code that indicates successful completion of an operation. */
-#define DRM_FILE_SUCCESS 0
-/** Indicates that an operation failed. */
-#define DRM_FILE_FAILURE -1
-/** Indicates that the a DRM_file_read() call reached the end of the file. */
-#define DRM_FILE_EOF -2
-
-
-/** Open for read access. */
-#define DRM_FILE_MODE_READ 1
-/** Open for write access. */
-#define DRM_FILE_MODE_WRITE 2
-
-
-#ifndef MAX_FILENAME_LEN
-/** Maximum number of characters that a filename may have. By default assumes
- *  that the entry results of DRM_file_listNextEntry() are returned in the async state
- *  buffer, after the #DRM_file_result_s, and calculates the maximum name
- *  from that.
- */
-#define MAX_FILENAME_LEN 1024
-#endif
-
-
-/**
- * Performs one-time initialization of the File System (FS).
- * This function is called once during the lifetime of an application,
- * and before any call to <code>DRM_file_*</code> functions by this application.
- * When several applications are using the file interface, this function may be called
- * several times, once per application.
- *
- * @return #DRM_FILE_SUCCESS, #DRM_FILE_FAILURE.
- */
-int32_t DRM_file_startup(void);
-
-/**
- * Returns the length of a file (by name, opened or unopened).
- *
- * @param name Name of the file, UCS-2 encoded.
- * @param nameChars Number characters encoded in name.
- * asynchronous operation returns #DRM_FILE_WOULDBLOCK.
- * @return #DRM_FILE_WOULDBLOCK, #DRM_FILE_FAILURE or the file length.
- */
-int32_t DRM_file_getFileLength(const uint16_t* name,
-                               int32_t nameChars);
-
-/**
- * Initializes a list iteration session.
- *
- * @param prefix Prefix that must be matched, UCS-2 encoded. *
- * @param prefixChars Number characters encoded in prefix.
- * @param session List session identifier.
- * @param iteration List iteration identifier.
- *
- * @return #DRM_FILE_WOULDBLOCK, #DRM_FILE_SUCCESS, #DRM_FILE_FAILURE.
- */
-int32_t DRM_file_listOpen(const uint16_t* prefix,
-                          int32_t prefixChars,
-                          int32_t* session,
-                          int32_t* iteration);
-
-/**
- * Used to fetch a list of file names that match a given name prefix.
- *
- * @param prefix See DRM_file_listOpen(). This does not change during the
- * iteration session.
- * @param prefixChars See DRM_file_listOpen(). This does not change during
- * the iteration session.
- * @param entry Buffer parameter to return the next file name that matches the
- * #prefix parameter, if any, when the function returns a positive number of
- * characters.
- * @param entryBytes Size of entry in bytes.
- * @param session See DRM_file_listOpen().
- * @param iteration See DRM_file_listOpen().
- * @return #DRM_FILE_WOULDBLOCK, #DRM_FILE_FAILURE or the number of
- * characters encoded in entry. Returns 0 when the end of the list is reached.
- */
-int32_t DRM_file_listNextEntry(const uint16_t* prefix,
-                               int32_t prefixChars,
-                               uint16_t* entry,
-                               int32_t entryBytes,
-                               int32_t* session,
-                               int32_t* iteration);
-
-/**
- * Ends a list iteration session. Notifies the implementation
- * that the list session is over and that any session resources
- * can be released.
- *
- * @param session See DRM_file_listOpen().
- * @param iteration See DRM_file_listOpen().
- * @return #DRM_FILE_WOULDBLOCK, #DRM_FILE_SUCCESS, #DRM_FILE_FAILURE.
- */
-int32_t DRM_file_listClose(int32_t session, int32_t iteration);
-
-/**
- * Renames a file, given its old name. The file or directory is renamed
- * immediately on the actual file system upon invocation of this method.
- * Any open handles on the file specified by oldName become invalid after
- * this method has been called.
- *
- * @param oldName Current file name (unopened), UCS-2 encoded.
- * @param oldNameChars Number of characters encoded on oldName.
- * @param newName New name for the file (unopened), UCS-2 encoded.
- * @param newNameChars Number of characters encoded on newName.
- * @return #DRM_FILE_WOULDBLOCK, #DRM_FILE_SUCCESS, #DRM_FILE_FAILURE. In particular,
- * #DRM_FILE_FAILURE if a file or directory already exists with the new name.
- */
-int32_t DRM_file_rename(const uint16_t* oldName,
-                        int32_t oldNameChars,
-                        const uint16_t* newName,
-                        int32_t newNameChars);
-
-/**
- * Tests if a file exists given its name.
- *
- * @param name Name of the file, UCS-2 encoded.
- * @param nameChars Number of characters encoded in name.
- * @return #DRM_FILE_WOULDBLOCK, #DRM_FILE_ISREG, #DRM_FILE_ISDIR, #DRM_FILE_FAILURE. If name
- * exists, returns #DRM_FILE_ISREG if it is a regular file and #DRM_FILE_ISDIR if it is a directory.
- * Returns #DRM_FILE_FAILURE in all other cases, including those where name exists but is neither
- * a regular file nor a directory. Platforms that do not support directories MUST NOT return
- * #DRM_FILE_ISDIR.
- */
-int32_t DRM_file_exists(const uint16_t* name,
-                        int32_t nameChars);
-
-/**
- * Opens a file with the given name and returns its file handle.
- *
- * @param name Name of the file, UCS-2 encoded.
- * @param nameChars Number of characters encoded in name.
- * @param mode Any combination of the #DRM_FILE_MODE_READ and
- * #DRM_FILE_MODE_WRITE flags. If the file does not exist and mode contains the
- * #DRM_FILE_MODE_WRITE flag, then the file is automatically created. If the
- * file exists and the mode contains the #DRM_FILE_MODE_WRITE flag, the file is
- * opened so it can be modified, but the data is not modified by the open call.
- * In all cases the current position is set to the start of the file.
- * The following table shows how to map the mode semantics above to UNIX
- * fopen-style modes.  For brevity in the table, R=#DRM_FILE_MODE_READ,
- * W=#DRM_FILE_MODE_WRITE, E=File exists:
- * <table>
- * <tr><td>RW</td><td>E</td><td>Maps-to</td></tr>
- * <tr><td>00</td><td>0</td><td>Return #DRM_FILE_FAILURE</td></tr>
- * <tr><td>00</td><td>1</td><td>Return #DRM_FILE_FAILURE</td></tr>
- * <tr><td>01</td><td>0</td><td>Use fopen mode "w"</td></tr>
- * <tr><td>01</td><td>1</td><td>Use fopen mode "a" and fseek to the start</td></tr>
- * <tr><td>10</td><td>0</td><td>Return #DRM_FILE_FAILURE</td></tr>
- * <tr><td>10</td><td>1</td><td>Use fopen mode "r"</td></tr>
- * <tr><td>11</td><td>0</td><td>Use fopen mode "w+"</td></tr>
- * <tr><td>11</td><td>1</td><td>Use fopen mode "r+"</td></tr>
- * </table>
- * @param handle Pointer where the result handle value is placed when the function
- * is called synchronously.
- * @return #DRM_FILE_WOULDBLOCK, #DRM_FILE_SUCCESS, #DRM_FILE_FAILURE.
- */
-int32_t DRM_file_open(const uint16_t* name,
-                      int32_t nameChars,
-                      int32_t mode,
-                      int32_t* handle);
-
-/**
- * Deletes a file given its name, UCS-2 encoded. The file or directory is
- * deleted immediately on the actual file system upon invocation of this
- * method. Any open handles on the file specified by name become invalid
- * after this method has been called.
- *
- * If the port needs to ensure that a specific application does not exceed a given storage
- * space quota, then the bytes freed by the deletion must be added to the available space for
- * that application.
- *
- * @param name Name of the file, UCS-2 encoded.
- * @param nameChars Number of characters encoded in name.
- * @return #DRM_FILE_WOULDBLOCK, #DRM_FILE_SUCCESS, #DRM_FILE_FAILURE.
- */
-int32_t DRM_file_delete(const uint16_t* name,
-                        int32_t nameChars);
-
-/**
- * Read bytes from a file at the current position to a buffer. Afterwards the
- * new file position is the byte after the last byte read.
- * DRM_FILE_FAILURE is returned if the handle is invalid (e.g., as a
- * consquence of DRM_file_delete, DRM_file_rename, or DRM_file_close).
- *
- * @param handle File handle as returned by DRM_file_open().
- * @param dst Buffer where the data is to be copied.
- * @param length Number of bytes to be copied.
- * @return #DRM_FILE_WOULDBLOCK, #DRM_FILE_SUCCESS, #DRM_FILE_FAILURE, #DRM_FILE_EOF
- *         or the number of bytes that were read, i.e. in the range 0..length.
- */
-int32_t DRM_file_read(int32_t handle,
-                      uint8_t* dst,
-                      int32_t length);
-
-/**
- * Write bytes from a buffer to the file at the current position.  If the
- * current position + number of bytes written > current size of the file,
- * then the file is grown.  Afterwards the new file position is the byte
- * after the last byte written.
- * DRM_FILE_FAILURE is returned if the handle is invalid (e.g., as a
- * consquence of DRM_file_delete, DRM_file_rename, or DRM_file_close).
- *
- * @param handle File handle as returned by DRM_file_open().
- * @param src Buffer that contains the bytes to be written.
- * @param length Number of bytes to be written.
- * If the port needs to ensure that a specific application does not exceed a given storage
- * space quota, the implementation must make sure the call does not violate that invariant.
- * @return #DRM_FILE_WOULDBLOCK, #DRM_FILE_FAILURE or the number of bytes
- *         that were written. This number must be in the range 0..length.
- *         Returns #DRM_FILE_FAILURE when storage is full or exceeds quota.
- */
-int32_t DRM_file_write(int32_t handle,
-                       const uint8_t* src,
-                       int32_t length);
-
-/**
- * Closes a file.
- * DRM_FILE_SUCCESS is returned if the handle is invalid (e.g., as a
- * consquence of DRM_file_delete or DRM_file_rename).
- *
- * @param handle File handle as returned by DRM_file_open().
- * @return #DRM_FILE_WOULDBLOCK, #DRM_FILE_SUCCESS, #DRM_FILE_FAILURE.
- */
-int32_t DRM_file_close(int32_t handle);
-
-/**
- * Sets the current position in an opened file.
- * DRM_FILE_FAILURE is returned if the handle is invalid (e.g., as a
- * consquence of DRM_file_delete, DRM_file_rename, or DRM_file_close).
- *
- * @param handle File handle as returned by DRM_file_open().
- * @param value The new current position of the file. If value is greater
- * than the length of the file then the file should be extended. The contents
- * of the newly extended portion of the file is undefined.
- * If the port needs to ensure that a specific application does not exceed a given storage
- * space quota, the implementation must make sure the call does not violate that invariant.
- * @return #DRM_FILE_WOULDBLOCK, #DRM_FILE_SUCCESS, #DRM_FILE_FAILURE.
- *         Returns #DRM_FILE_FAILURE when storage is full or exceeds quota.
- */
-int32_t DRM_file_setPosition(int32_t handle, int32_t value);
-
-/**
- * Creates a directory with the assigned name and full file permissions on
- * the file system. The full path to the new directory must already exist.
- * The directory is created immediately on the actual file system upon
- * invocation of this method.
- *
- * @param name Name of the directory, UCS-2 encoded.
- * @param nameChars Number of characters encoded in name.
- * @return #DRM_FILE_WOULDBLOCK, #DRM_FILE_SUCCESS, #DRM_FILE_FAILURE.
- */
-int32_t DRM_file_mkdir(const uint16_t* name,
-                       int32_t nameChars);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __DRM_FILE_H__ */
diff --git a/media/libdrm/mobile1/include/objmng/drm_i18n.h b/media/libdrm/mobile1/include/objmng/drm_i18n.h
deleted file mode 100644
index 7487e9b..0000000
--- a/media/libdrm/mobile1/include/objmng/drm_i18n.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#ifndef __DRM_I18N_H__
-#define __DRM_I18N_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <drm_common_types.h>
-
-/**
- * @name Charset value defines
- * @ingroup i18n
- *
- * Charset value defines
- * see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/unicode_81rn.asp
- */
-typedef enum {
-    DRM_CHARSET_GBK        = 936,      /** Simplified Chinese GBK (CP936) */
-    DRM_CHARSET_GB2312     = 20936,    /** Simplified Chinese GB2312 (CP936) */
-    DRM_CHARSET_BIG5       = 950,      /** BIG5 (CP950) */
-    DRM_CHARSET_LATIN1     = 28591,    /** ISO 8859-1, Latin 1 */
-    DRM_CHARSET_LATIN2     = 28592,    /** ISO 8859-2, Latin 2 */
-    DRM_CHARSET_LATIN3     = 28593,    /** ISO 8859-3, Latin 3 */
-    DRM_CHARSET_LATIN4     = 28594,    /** ISO 8859-4, Latin 4 */
-    DRM_CHARSET_CYRILLIC   = 28595,    /** ISO 8859-5, Cyrillic */
-    DRM_CHARSET_ARABIC     = 28596,    /** ISO 8859-6, Arabic */
-    DRM_CHARSET_GREEK      = 28597,    /** ISO 8859-7, Greek */
-    DRM_CHARSET_HEBREW     = 28598,    /** ISO 8859-8, Hebrew */
-    DRM_CHARSET_LATIN5     = 28599,    /** ISO 8859-9, Latin 5 */
-    DRM_CHARSET_LATIN6     = 865,      /** ISO 8859-10, Latin 6 (not sure here) */
-    DRM_CHARSET_THAI       = 874,      /** ISO 8859-11, Thai */
-    DRM_CHARSET_LATIN7     = 1257,     /** ISO 8859-13, Latin 7 (not sure here) */
-    DRM_CHARSET_LATIN8     = 38598,    /** ISO 8859-14, Latin 8 (not sure here) */
-    DRM_CHARSET_LATIN9     = 28605,    /** ISO 8859-15, Latin 9 */
-    DRM_CHARSET_LATIN10    = 28606,    /** ISO 8859-16, Latin 10 */
-    DRM_CHARSET_UTF8       = 65001,    /** UTF-8 */
-    DRM_CHARSET_UTF16LE    = 1200,     /** UTF-16 LE */
-    DRM_CHARSET_UTF16BE    = 1201,     /** UTF-16 BE */
-    DRM_CHARSET_HINDI      = 57002,    /** Hindi/Mac Devanagari */
-    DRM_CHARSET_UNSUPPORTED = -1
-} DRM_Charset_t;
-
-/**
- * Convert multibyte string of specified charset to unicode string.
- * Note NO terminating '\0' will be appended to the output unicode string.
- *
- * @param charset Charset of the multibyte string.
- * @param mbs Multibyte string to be converted.
- * @param mbsLen Number of the bytes (in mbs) to be converted.
- * @param wcsBuf Buffer for the converted unicode characters.
- *               If wcsBuf is NULL, the function returns the number of unicode
- *               characters required for the buffer.
- * @param bufSizeInWideChar The size (in wide char) of wcsBuf
- * @param bytesConsumed The number of bytes in mbs that have been successfully
- *                      converted. The value of *bytesConsumed is undefined
- *                      if wcsBuf is NULL.
- *
- * @return Number of the successfully converted unicode characters if wcsBuf
- *         is not NULL. If wcsBuf is NULL, returns required unicode buffer
- *         size. -1 for unrecoverable errors.
- */
-int32_t DRM_i18n_mbsToWcs(DRM_Charset_t charset,
-        const uint8_t *mbs, int32_t mbsLen,
-        uint16_t *wcsBuf, int32_t bufSizeInWideChar,
-        int32_t *bytesConsumed);
-
-/**
- * Convert unicode string to multibyte string with specified charset.
- * Note NO terminating '\0' will be appended to the output multibyte string.
- *
- * @param charset Charset of the multibyte string to be converted to.
- * @param wcs     Unicode string to be converted.
- * @param wcsLen  Number of the unicode characters (in wcs) to be converted.
- * @param mbsBuf  Buffer for converted multibyte characters.
- *                If mbsBuf is NULL, the function returns the number of bytes
- *                required for the buffer.
- * @param bufSizeInByte The size (in byte) of mbsBuf.
- *
- * @return Number of the successfully converted bytes.
- */
-int32_t DRM_i18n_wcsToMbs(DRM_Charset_t charset,
-        const uint16_t *wcs, int32_t wcsLen,
-        uint8_t *mbsBuf, int32_t bufSizeInByte);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/media/libdrm/mobile1/include/objmng/drm_inner.h b/media/libdrm/mobile1/include/objmng/drm_inner.h
deleted file mode 100644
index 55234f8..0000000
--- a/media/libdrm/mobile1/include/objmng/drm_inner.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __DRM_INNER_H__
-#define __DRM_INNER_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <drm_common_types.h>
-
-#define INT_2_YMD_HMS(year, mon, day, date, hour, min, sec, time) do{\
-    year = date / 10000;\
-    mon = date % 10000 / 100;\
-    day = date %100;\
-    hour = time / 10000;\
-    min = time % 10000 / 100;\
-    sec = time % 100;\
-}while(0)
-
-/**
- * Define the max malloc length for a DRM.
- */
-#define DRM_MAX_MALLOC_LEN          (50 * 1024) /* 50K */
-
-#define DRM_ONE_AES_BLOCK_LEN       16
-#define DRM_TWO_AES_BLOCK_LEN       32
-
-typedef struct _T_DRM_DM_Binary_Node {
-    uint8_t boundary[256];
-} T_DRM_DM_Binary_Node;
-
-typedef struct _T_DRM_DM_Base64_Node {
-    uint8_t boundary[256];
-    uint8_t b64DecodeData[4];
-    int32_t b64DecodeDataLen;
-} T_DRM_DM_Base64_Node;
-
-typedef struct _T_DRM_Dcf_Node {
-    uint8_t rightsIssuer[256];
-    int32_t encContentLength;
-    uint8_t aesDecData[16];
-    int32_t aesDecDataLen;
-    int32_t aesDecDataOff;
-    uint8_t aesBackupBuf[16];
-    int32_t bAesBackupBuf;
-} T_DRM_Dcf_Node;
-
-typedef struct _T_DRM_Session_Node {
-    int32_t sessionId;
-    int32_t inputHandle;
-    int32_t mimeType;
-    int32_t (*getInputDataLengthFunc)(int32_t inputHandle);
-    int32_t (*readInputDataFunc)(int32_t inputHandle, uint8_t* buf, int32_t bufLen);
-    int32_t (*seekInputDataFunc)(int32_t inputHandle, int32_t offset);
-    int32_t deliveryMethod;
-    int32_t transferEncoding;
-    uint8_t contentType[64];
-    int32_t contentLength;
-    int32_t contentOffset;
-    uint8_t contentID[256];
-    uint8_t* rawContent;
-    int32_t rawContentLen;
-    int32_t bEndData;
-    uint8_t* readBuf;
-    int32_t readBufLen;
-    int32_t readBufOff;
-    void* infoStruct;
-    struct _T_DRM_Session_Node* next;
-} T_DRM_Session_Node;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __DRM_INNER_H__ */
diff --git a/media/libdrm/mobile1/include/objmng/drm_rights_manager.h b/media/libdrm/mobile1/include/objmng/drm_rights_manager.h
deleted file mode 100644
index d81e7a1..0000000
--- a/media/libdrm/mobile1/include/objmng/drm_rights_manager.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __DRM_RIGHTS_MANAGER_H__
-#define __DRM_RIGHTS_MANAGER_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <openssl/aes.h>
-#include <drm_common_types.h>
-#include <parser_rel.h>
-
-#ifdef DRM_DEVICE_ARCH_ARM
-#define ANDROID_DRM_CORE_PATH   "/data/drm/rights/"
-#define DRM_UID_FILE_PATH       "/data/drm/rights/uid.txt"
-#else
-#define ANDROID_DRM_CORE_PATH   "/home/user/golf/esmertec/device/out/debug/host/linux-x86/product/sim/data/data/com.android.drm.mobile1/"
-#define DRM_UID_FILE_PATH       "/home/user/golf/esmertec/device/out/debug/host/linux-x86/product/sim/data/data/com.android.drm.mobile1/uid.txt"
-#endif
-
-#define EXTENSION_NAME_INFO     ".info"
-
-#define GET_ID      1
-#define GET_UID     2
-
-#define GET_ROAMOUNT        1
-#define GET_ALL_RO          2
-#define SAVE_ALL_RO         3
-#define GET_A_RO            4
-#define SAVE_A_RO           5
-
-/**
- * Get the id or uid from the "uid.txt" file.
- *
- * \param Uid       The content id for a specially DRM object.
- * \param id        The id number managed by DRM engine for a specially DRM object.
- * \param option    The option to get id or uid, the value includes: GET_ID, GET_UID.
- *
- * \return
- *      -TRUE, if the operation successfully.
- *      -FALSE, if the operation failed.
- */
-int32_t drm_readFromUidTxt(uint8_t* Uid, int32_t* id, int32_t option);
-
-/**
- * Save or read the rights information on the "id.info" file.
- *
- * \param id        The id number managed by DRM engine for a specially DRM object.
- * \param Ro        The rights structure to save the rights information.
- * \param RoAmount  The number of rights for this DRM object.
- * \param option    The option include: GET_ROAMOUNT, GET_ALL_RO, SAVE_ALL_RO, GET_A_RO, SAVE_A_RO.
- *
- * \return
- *      -TRUE, if the operation successfully.
- *      -FALSE, if the operation failed.
- */
-int32_t drm_writeOrReadInfo(int32_t id, T_DRM_Rights* Ro, int32_t* RoAmount, int32_t option);
-
-/**
- * Append a rights information to DRM engine storage.
- *
- * \param Ro        The rights structure to save the rights information.
- *
- * return
- *      -TRUE, if the operation successfully.
- *      -FALSE, if the operation failed.
- */
-int32_t drm_appendRightsInfo(T_DRM_Rights* rights);
-
-/**
- * Get the mex id number from the "uid.txt" file.
- *
- * \return
- *      -an integer to indicate the max id number.
- *      -(-1), if the operation failed.
- */
-int32_t drm_getMaxIdFromUidTxt();
-
-/**
- * Remove the "id.info" file if all the rights for this DRM object has been deleted.
- *
- * \param id        The id number managed by DRM engine for a specially DRM object.
- *
- * \return
- *      -TRUE, if the operation successfully.
- *      -FALSE, if the operation failed.
- */
-int32_t drm_removeIdInfoFile(int32_t id);
-
-/**
- * Update the "uid.txt" file when delete the rights object.
- *
- * \param id        The id number managed by DRM engine for a specially DRM object.
- *
- * \return
- *      -TRUE, if the operation successfully.
- *      -FALSE, if the operation failed.
- */
-int32_t drm_updateUidTxtWhenDelete(int32_t id);
-
-/**
- * Get the CEK according the given content id.
- *
- * \param uid       The content id for a specially DRM object.
- * \param KeyValue  The buffer to save the CEK.
- *
- * \return
- *      -TRUE, if the operation successfully.
- *      -FALSE, if the operation failed.
- */
-int32_t drm_getKey(uint8_t* uid, uint8_t* KeyValue);
-
-/**
- * Discard the padding bytes in DCF decrypted data.
- *
- * \param decryptedBuf      The aes decrypted data buffer to be scanned.
- * \param decryptedBufLen   The length of the buffer. And save the output result.
- *
- * \return
- *      -0
- */
-void drm_discardPaddingByte(uint8_t *decryptedBuf, int32_t *decryptedBufLen);
-
-/**
- * Decrypt the media data according the CEK.
- *
- * \param Buffer    The buffer to decrypted and also used to save the output data.
- * \param BufferLen The length of the buffer data and also save the output data length.
- * \param key       The structure of the CEK.
- *
- * \return
- *      -0
- */
-int32_t drm_aesDecBuffer(uint8_t * Buffer, int32_t * BufferLen, AES_KEY *key);
-
-/**
- * Update the DCF data length according the CEK.
- *
- * \param pDcfLastData  The last several byte for the DCF.
- * \param keyValue  The CEK of the DRM content.
- * \param moreBytes Output the more bytes for discarded.
- *
- * \return
- *      -TRUE, if the operation successfully.
- *      -FALSE, if the operation failed.
- */
-int32_t drm_updateDcfDataLen(uint8_t* pDcfLastData, uint8_t* keyValue, int32_t* moreBytes);
-
-/**
- * Check and update the rights for a specially DRM content.
- *
- * \param id        The id number managed by DRM engine for a specially DRM object.
- * \param permission    The permission to be check and updated.
- *
- * \return
- *      -DRM_SUCCESS, if there is a valid rights and update it successfully.
- *      -DRM_NO_RIGHTS, if there is no rights for this content.
- *      -DRM_RIGHTS_PENDING, if the rights is pending.
- *      -DRM_RIGHTS_EXPIRED, if the rights has expired.
- *      -DRM_RIGHTS_FAILURE, if there is some other error occur.
- */
-int32_t drm_checkRoAndUpdate(int32_t id, int32_t permission);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __DRM_RIGHTS_MANAGER_H__ */
diff --git a/media/libdrm/mobile1/include/objmng/drm_time.h b/media/libdrm/mobile1/include/objmng/drm_time.h
deleted file mode 100644
index 9b013e6..0000000
--- a/media/libdrm/mobile1/include/objmng/drm_time.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-/**
- * @file
- * Time Porting Layer
- *
- * Basic support functions that are needed by time.
- *
- * <!-- #interface list begin -->
- * \section drm_time Interface
- * - DRM_time_getElapsedSecondsFrom1970()
- * - DRM_time_sleep()
- * - DRM_time_getSysTime()
- * <!-- #interface list end -->
- */
-
-#ifndef __DRM_TIME_H__
-#define __DRM_TIME_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <time.h>
-#include <drm_common_types.h>
-
-/** the time format */
-typedef struct __db_system_time_
-{
-    uint16_t year;
-    uint16_t month;
-    uint16_t day;
-    uint16_t hour;
-    uint16_t min;
-    uint16_t sec;
-} T_DB_TIME_SysTime;
-
-/**
- * Get the system time.it's up to UTC
- * \return Return the time in elapsed seconds.
- */
-uint32_t DRM_time_getElapsedSecondsFrom1970(void);
-
-/**
- * Suspend the execution of the current thread for a specified interval
- * \param ms suspended time by millisecond
- */
-void DRM_time_sleep(uint32_t ms);
-
-/**
- * function: get current system time
- * \param  time_ptr[OUT]  the system time got
- * \attention
- *    time_ptr must not be NULL
- */
-void DRM_time_getSysTime(T_DB_TIME_SysTime *time_ptr);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __DRM_TIME_H__ */
diff --git a/media/libdrm/mobile1/include/objmng/svc_drm.h b/media/libdrm/mobile1/include/objmng/svc_drm.h
deleted file mode 100644
index 789343f..0000000
--- a/media/libdrm/mobile1/include/objmng/svc_drm.h
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __SVC_DRM_NEW_H__
-#define __SVC_DRM_NEW_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <drm_common_types.h>
-
-/**
- * Define the mime type of DRM data.
- */
-#define TYPE_DRM_MESSAGE            0x48    /**< The mime type is "application/vnd.oma.drm.message" */
-#define TYPE_DRM_CONTENT            0x49    /**< The mime type is "application/vnd.oma.drm.content" */
-#define TYPE_DRM_RIGHTS_XML         0x4a    /**< The mime type is "application/vnd.oma.drm.rights+xml" */
-#define TYPE_DRM_RIGHTS_WBXML       0x4b    /**< The mime type is "application/vnd.oma.drm.rights+wbxml" */
-#define TYPE_DRM_UNKNOWN            0xff    /**< The mime type is unknown */
-
-/**
- * Define the delivery methods.
- */
-#define FORWARD_LOCK                1       /**< Forward_lock */
-#define COMBINED_DELIVERY           2       /**< Combined delivery */
-#define SEPARATE_DELIVERY           3       /**< Separate delivery */
-#define SEPARATE_DELIVERY_FL        4       /**< Separate delivery but DCF is forward-lock */
-
-/**
- * Define the permissions.
- */
-#define DRM_PERMISSION_PLAY         0x01    /**< Play */
-#define DRM_PERMISSION_DISPLAY      0x02    /**< Display */
-#define DRM_PERMISSION_EXECUTE      0x04    /**< Execute */
-#define DRM_PERMISSION_PRINT        0x08    /**< Print */
-#define DRM_PERMISSION_FORWARD      0x10    /**< Forward */
-
-/**
- * Define the constraints.
- */
-#define DRM_NO_CONSTRAINT           0x80    /**< Indicate have no constraint, it can use freely */
-#define DRM_END_TIME_CONSTRAINT     0x08    /**< Indicate have end time constraint */
-#define DRM_INTERVAL_CONSTRAINT     0x04    /**< Indicate have interval constraint */
-#define DRM_COUNT_CONSTRAINT        0x02    /**< Indicate have count constraint */
-#define DRM_START_TIME_CONSTRAINT   0x01    /**< Indicate have start time constraint */
-#define DRM_NO_PERMISSION           0x00    /**< Indicate no rights */
-
-/**
- * Define the return values for those interface.
- */
-#define DRM_SUCCESS                 0
-#define DRM_FAILURE                 -1
-#define DRM_MEDIA_EOF               -2
-#define DRM_RIGHTS_DATA_INVALID     -3
-#define DRM_MEDIA_DATA_INVALID      -4
-#define DRM_SESSION_NOT_OPENED      -5
-#define DRM_NO_RIGHTS               -6
-#define DRM_NOT_SD_METHOD           -7
-#define DRM_RIGHTS_PENDING          -8
-#define DRM_RIGHTS_EXPIRED          -9
-#define DRM_UNKNOWN_DATA_LEN        -10
-
-/**
- * The input DRM data structure, include DM, DCF, DR, DRC.
- */
-typedef struct _T_DRM_Input_Data {
-    /**
-     * The handle of the input DRM data.
-     */
-    int32_t inputHandle;
-
-    /**
-     * The mime type of the DRM data, if the mime type set to unknown, DRM engine
-     * will try to scan the input data to confirm the mime type, but we must say that
-     * the scan and check of mime type is not strictly precise.
-     */
-    int32_t mimeType;
-
-    /**
-     * The function to get input data length, this function should be implement by out module,
-     * and DRM engine will call-back it.
-     *
-     * \param inputHandle   The handle of the DRM data.
-     *
-     * \return
-     *      -A positive integer indicate the length of input data.
-     *      -0, if some error occurred.
-     */
-    int32_t (*getInputDataLength)(int32_t inputHandle);
-
-    /**
-     * The function to read the input data, this function should be implement by out module,
-     * and DRM engine will call-back it.
-     *
-     * \param inputHandle   The handle of the DRM data.
-     * \param buf       The buffer mallocced by DRM engine to save the data.
-     * \param bufLen    The length of the buffer.
-     *
-     * \return
-     *      -A positive integer indicate the actually length of byte has been read.
-     *      -0, if some error occurred.
-     *      -(-1), if reach to the end of the data.
-     */
-    int32_t (*readInputData)(int32_t inputHandle, uint8_t* buf, int32_t bufLen);
-
-    /**
-     * The function to seek the current file pointer, this function should be implement by out module,
-     * and DRM engine will call-back it.
-     *
-     * \param inputHandle   The handle of the DRM data.
-     * \param offset    The offset from the start position to be seek.
-     *
-     * \return
-     *      -0, if seek operation success.
-     *      -(-1), if seek operation fail.
-     */
-    int32_t (*seekInputData)(int32_t inputHandle, int32_t offset);
-} T_DRM_Input_Data;
-
-/**
- * The constraint structure.
- */
-typedef struct _T_DRM_Constraint_Info {
-    uint8_t indicator;          /**< Whether there is a right */
-    uint8_t unUsed[3];
-    int32_t count;              /**< The constraint of count */
-    int32_t startDate;          /**< The constraint of start date */
-    int32_t startTime;          /**< The constraint of start time */
-    int32_t endDate;            /**< The constraint of end date */
-    int32_t endTime;            /**< The constraint of end time */
-    int32_t intervalDate;       /**< The constraint of interval date */
-    int32_t intervalTime;       /**< The constraint of interval time */
-} T_DRM_Constraint_Info;
-
-/**
- * The rights permission and constraint information structure.
- */
-typedef struct _T_DRM_Rights_Info {
-    uint8_t roId[256];                     /**< The unique id for a specially rights object */
-    T_DRM_Constraint_Info playRights;       /**< Constraint of play */
-    T_DRM_Constraint_Info displayRights;    /**< Constraint of display */
-    T_DRM_Constraint_Info executeRights;    /**< Constraint of execute */
-    T_DRM_Constraint_Info printRights;      /**< Constraint of print */
-} T_DRM_Rights_Info;
-
-/**
- * The list node of the Rights information structure.
- */
-typedef struct _T_DRM_Rights_Info_Node {
-    T_DRM_Rights_Info roInfo;
-    struct _T_DRM_Rights_Info_Node *next;
-} T_DRM_Rights_Info_Node;
-
-/**
- * Install a rights object to DRM engine, include the rights in Combined Delivery cases.
- * Because all the rights object is managed by DRM engine, so every incoming rights object
- * must be install to the engine first, or the DRM engine will not recognize it.
- *
- * \param data      The rights object data or Combined Delivery case data.
- * \param pRightsInfo   The structure to save this rights information.
- *
- * \return
- *      -DRM_SUCCESS, when install successfully.
- *      -DRM_RIGHTS_DATA_INVALID, when the input rights data is invalid.
- *      -DRM_FAILURE, when some other error occur.
- */
-int32_t SVC_drm_installRights(T_DRM_Input_Data data, T_DRM_Rights_Info* pRightsInfo);
-
-/**
- * Open a session for a special DRM object, it will parse the input DRM data, and then user
- * can try to get information for this DRM object, or try to use it if the rights is valid.
- *
- * \param data      The DRM object data, DM or DCF.
- *
- * \return
- *      -A handle for this opened DRM object session.
- *      -DRM_MEDIA_DATA_INVALID, when the input DRM object data is invalid.
- *      -DRM_FAILURE, when some other error occurred.
- */
-int32_t SVC_drm_openSession(T_DRM_Input_Data data);
-
-/**
- * Get the delivery method of the DRM object.
- *
- * \param session   The handle for this DRM object session.
- *
- * \return
- *      -The delivery method of this DRM object, include: FORWARD_LOCK, COMBINED_DELIVERY, SEPARATE_DELIVERY, SEPARATE_DELIVERY_FL.
- *      -DRM_FAILURE, when some other error occurred.
- */
-int32_t SVC_drm_getDeliveryMethod(int32_t session);
-
-/**
- * Get DRM object media object content type.
- *
- * \param session   The handle for this DRM object session.
- * \param mediaType The buffer to save the media type string, 64 bytes is enough.
- *
- * \return
- *      -DRM_SUCCESS, when get the media object content type successfully.
- *      -DRM_SESSION_NOT_OPENED, when the session is not opened or has been closed.
- *      -DRM_FAILURE, when some other error occured.
- */
-int32_t SVC_drm_getContentType(int32_t session, uint8_t* mediaType);
-
-/**
- * Check whether a specific DRM object has the specific permission rights or not.
- *
- * \param session   The handle for this DRM object session.
- * \param permission    Specify the permission to be checked.
- *
- * \return
- *      -DRM_SUCCESS, when it has the rights for the permission.
- *      -DRM_SESSION_NOT_OPENED, when the session is not opened or has been closed.
- *      -DRM_NO_RIGHTS, when it has no rights.
- *      -DRM_RIGHTS_PENDING, when it has the rights, but currently it is pending.
- *      -DRM_RIGHTS_EXPIRED, when the rights has expired.
- *      -DRM_FAILURE, when some other error occured.
- */
-int32_t SVC_drm_checkRights(int32_t session, int32_t permission);
-
-/**
- * Consume the rights when try to use the DRM object.
- *
- * \param session   The handle for this DRM object session.
- * \param permission    Specify the permission to be checked.
- *
- * \return
- *      -DRM_SUCCESS, when consume rights successfully.
- *      -DRM_SESSION_NOT_OPENED, when the session is not opened or has been closed.
- *      -DRM_NO_RIGHTS, when it has no rights.
- *      -DRM_RIGHTS_PENDING, when it has the rights, but currently it is pending.
- *      -DRM_RIGHTS_EXPIRED, when the rights has expired.
- *      -DRM_FAILURE, when some other error occured.
- */
-int32_t SVC_drm_consumeRights(int32_t session, int32_t permission);
-
-/**
- * Get DRM media object content data length.
- *
- * \param session   The handle for this DRM object session.
- *
- * \return
- *      -A positive integer indicate the length of the media object content data.
- *      -DRM_SESSION_NOT_OPENED, when the session is not opened or has been closed.
- *      -DRM_NO_RIGHTS, when the rights object is not existed.
- *      -DRM_UNKNOWN_DATA_LEN, when DRM object media data length is unknown in case of DCF has no rights.
- *      -DRM_FAILURE, when some other error occured.
- */
-int32_t SVC_drm_getContentLength(int32_t session);
-
-/**
- * Get DRM media object content data. Support get the data piece by piece if the content is too large.
- *
- * \param session   The handle for this DRM object session.
- * \param offset    The offset to start to get content.
- * \param mediaBuf  The buffer to save media object data.
- * \param mediaBufLen   The length of the buffer.
- *
- * \return
- *      -A positive integer indicate the actually length of the data has been got.
- *      -DRM_SESSION_NOT_OPENED, when the session is not opened or has been closed.
- *      -DRM_NO_RIGHTS, when the rights object is not existed.
- *      -DRM_MEDIA_EOF, when reach to the end of the media data.
- *      -DRM_FAILURE, when some other error occured.
- */
-int32_t SVC_drm_getContent(int32_t session, int32_t offset, uint8_t* mediaBuf, int32_t mediaBufLen);
-
-/**
- * Get the rights issuer address, this interface is specially for Separate Delivery method.
- *
- * \param session   The handle for this DRM object session.
- * \param rightsIssuer  The buffer to save rights issuer, 256 bytes are enough.
- *
- * \return
- *      -DRM_SUCCESS, when get the rights issuer successfully.
- *      -DRM_SESSION_NOT_OPENED, when the session is not opened or has been closed.
- *      -DRM_NOT_SD_METHOD, when it is not a Separate Delivery DRM object.
- *      -DRM_FAILURE, when some other error occured.
- */
-int32_t SVC_drm_getRightsIssuer(int32_t session, uint8_t* rightsIssuer);
-
-/**
- * Get DRM object constraint informations.
- *
- * \param session   The handle for this DRM object session.
- * \param rights    The structue to save the rights object information.
- *
- * \return
- *      -DRM_SUCCESS, when get the rights information successfully.
- *      -DRM_SESSION_NOT_OPENED, when the session is not opened or has been closed.
- *      -DRM_NO_RIGHTS, when this DRM object has not rights.
- *      -DRM_FAILURE, when some other error occured.
- */
-int32_t SVC_drm_getRightsInfo(int32_t session, T_DRM_Rights_Info* rights);
-
-/**
- * Close the opened session, after closed, the handle become invalid.
- *
- * \param session   The handle for this DRM object session.
- *
- * \return
- *      -DRM_SUCCESS, when close operation success.
- *      -DRM_SESSION_NOT_OPENED, when the session is not opened or has been closed.
- *      -DRM_FAILURE, when some other error occured.
- */
-int32_t SVC_drm_closeSession(int32_t session);
-
-/**
- * Check and update the given rights according the given permission.
- *
- * \param contentID The unique id of the rights object.
- * \param permission    The permission to be updated.
- *
- * \return
- *      -DRM_SUCCESS, when update operation success.
- *      -DRM_NO_RIGHTS, when it has no rights.
- *      -DRM_RIGHTS_PENDING, when it has the rights, but currently it is pending.
- *      -DRM_RIGHTS_EXPIRED, when the rights has expired.
- *      -DRM_FAILURE, when some other error occured.
- */
-int32_t SVC_drm_updateRights(uint8_t* contentID, int32_t permission);
-
-/**
- * Scan all the rights object in current DRM engine, and get all their information.
- *
- * \param ppRightsInfo  The pointer to the list structure to save rights info.
- *
- * \return
- *      -DRM_SUCCESS, when get information successfully.
- *      -DRM_FAILURE, when some other error occured.
- */
-int32_t SVC_drm_viewAllRights(T_DRM_Rights_Info_Node **ppRightsInfo);
-
-/**
- * Free the allocated memory when call "SVC_drm_viewAllRights".
- *
- * \param pRightsHeader The header pointer of the list to be free.
- *
- * \return
- *      -DRM_SUCCESS, when free operation successfully.
- *      -DRM_FAILURE, when some other error occured.
- */
-int32_t SVC_drm_freeRightsInfoList(T_DRM_Rights_Info_Node *pRightsHeader);
-
-/**
- * Delete a specify rights.
- *
- * \param roId      The unique id of the rights.
- *
- * \return
- *      -DRM_SUCCESS, when free operation successfully.
- *      -DRM_NO_RIGHTS, when there is not this rights object.
- *      -DRM_FAILURE, when some other error occured.
- */
-int32_t SVC_drm_deleteRights(uint8_t* roId);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __SVC_DRM_NEW_H__ */
diff --git a/media/libdrm/mobile1/include/parser/parser_dcf.h b/media/libdrm/mobile1/include/parser/parser_dcf.h
deleted file mode 100644
index c63a195..0000000
--- a/media/libdrm/mobile1/include/parser/parser_dcf.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __PARSER_DCF_H__
-#define __PARSER_DCF_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <drm_common_types.h>
-
-#define MAX_ENCRYPTION_METHOD_LEN                            64
-#define MAX_RIGHTS_ISSUER_LEN                                256
-#define MAX_CONTENT_NAME_LEN                                 64
-#define MAX_CONTENT_DESCRIPTION_LEN                          256
-#define MAX_CONTENT_VENDOR_LEN                               256
-#define MAX_ICON_URI_LEN                                     256
-#define MAX_CONTENT_TYPE_LEN                                 64
-#define MAX_CONTENT_URI_LEN                                  256
-
-#define HEADER_ENCRYPTION_METHOD                             "Encryption-Method: "
-#define HEADER_RIGHTS_ISSUER                                 "Rights-Issuer: "
-#define HEADER_CONTENT_NAME                                  "Content-Name: "
-#define HEADER_CONTENT_DESCRIPTION                           "Content-Description: "
-#define HEADER_CONTENT_VENDOR                                "Content-Vendor: "
-#define HEADER_ICON_URI                                      "Icon-Uri: "
-
-#define HEADER_ENCRYPTION_METHOD_LEN                         19
-#define HEADER_RIGHTS_ISSUER_LEN                             15
-#define HEADER_CONTENT_NAME_LEN                              14
-#define HEADER_CONTENT_DESCRIPTION_LEN                       21
-#define HEADER_CONTENT_VENDOR_LEN                            16
-#define HEADER_ICON_URI_LEN                                  10
-
-#define UINT_VAR_FLAG                                        0x80
-#define UINT_VAR_DATA                                        0x7F
-#define MAX_UINT_VAR_BYTE                                    5
-#define DRM_UINT_VAR_ERR                                     -1
-
-typedef struct _T_DRM_DCF_Info {
-    uint8_t Version;
-    uint8_t ContentTypeLen;                                  /**< Length of the ContentType field */
-    uint8_t ContentURILen;                                   /**< Length of the ContentURI field */
-    uint8_t unUsed;
-    uint8_t ContentType[MAX_CONTENT_TYPE_LEN];               /**< The MIME media type of the plaintext data */
-    uint8_t ContentURI[MAX_CONTENT_URI_LEN];                 /**< The unique identifier of this content object */
-    int32_t HeadersLen;                                      /**< Length of the Headers field */
-    int32_t EncryptedDataLen;                                /**< Length of the encrypted data field */
-    int32_t DecryptedDataLen;                                /**< Length of the decrypted data field */
-    uint8_t Encryption_Method[MAX_ENCRYPTION_METHOD_LEN];    /**< Encryption method */
-    uint8_t Rights_Issuer[MAX_RIGHTS_ISSUER_LEN];            /**< Rights issuer */
-    uint8_t Content_Name[MAX_CONTENT_NAME_LEN];              /**< Content name */
-    uint8_t ContentDescription[MAX_CONTENT_DESCRIPTION_LEN]; /**< Content description */
-    uint8_t ContentVendor[MAX_CONTENT_VENDOR_LEN];           /**< Content vendor */
-    uint8_t Icon_URI[MAX_ICON_URI_LEN];                      /**< Icon URI */
-} T_DRM_DCF_Info;
-
-/**
- * Parse the DRM content format data
- *
- * \param buffer            (in)Input the DCF format data
- * \param bufferLen         (in)The input buffer length
- * \param pDcfInfo          (out)A structure pointer which contain information of DCF headers
- * \param ppEncryptedData   (out)The location of encrypted data
- *
- * \return
- *      -TRUE, when success
- *      -FALSE, when failed
- */
-int32_t drm_dcfParser(uint8_t *buffer, int32_t bufferLen, T_DRM_DCF_Info *pDcfInfo,
-                      uint8_t **ppEncryptedData);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __PARSER_DCF_H__ */
diff --git a/media/libdrm/mobile1/include/parser/parser_dm.h b/media/libdrm/mobile1/include/parser/parser_dm.h
deleted file mode 100644
index ec8b6b2..0000000
--- a/media/libdrm/mobile1/include/parser/parser_dm.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __PARSER_DM_H__
-#define __PARSER_DM_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <drm_common_types.h>
-
-#define MAX_CONTENT_TYPE_LEN                                64
-#define MAX_CONTENT_ID                                      256
-#define MAX_CONTENT_BOUNDARY_LEN                            256
-#define MAX_RIGHTS_ISSUER_LEN                               256
-
-#define DRM_MIME_TYPE_RIGHTS_XML                            "application/vnd.oma.drm.rights+xml"
-#define DRM_MIME_TYPE_CONTENT                               "application/vnd.oma.drm.content"
-
-#define HEADERS_TRANSFER_CODING                             "Content-Transfer-Encoding:"
-#define HEADERS_CONTENT_TYPE                                "Content-Type:"
-#define HEADERS_CONTENT_ID                                  "Content-ID:"
-
-#define TRANSFER_CODING_TYPE_7BIT                           "7bit"
-#define TRANSFER_CODING_TYPE_8BIT                           "8bit"
-#define TRANSFER_CODING_TYPE_BINARY                         "binary"
-#define TRANSFER_CODING_TYPE_BASE64                         "base64"
-
-#define DRM_UID_TYPE_FORWORD_LOCK                           "forwardlock"
-#define DRM_NEW_LINE_CRLF                                   "\r\n"
-
-#define HEADERS_TRANSFER_CODING_LEN                         26
-#define HEADERS_CONTENT_TYPE_LEN                            13
-#define HEADERS_CONTENT_ID_LEN                              11
-
-#define DRM_MESSAGE_CODING_7BIT                             0  /* default */
-#define DRM_MESSAGE_CODING_8BIT                             1
-#define DRM_MESSAGE_CODING_BINARY                           2
-#define DRM_MESSAGE_CODING_BASE64                           3
-
-#define DRM_B64_DEC_BLOCK                                   3
-#define DRM_B64_ENC_BLOCK                                   4
-
-typedef struct _T_DRM_DM_Info {
-    uint8_t contentType[MAX_CONTENT_TYPE_LEN];  /**< Content type */
-    uint8_t contentID[MAX_CONTENT_ID];          /**< Content ID */
-    uint8_t boundary[MAX_CONTENT_BOUNDARY_LEN]; /**< DRM message's boundary */
-    uint8_t deliveryType;                       /**< The Delivery type */
-    uint8_t transferEncoding;                   /**< Transfer encoding type */
-    int32_t contentOffset;                      /**< The offset of the media content from the original DRM data */
-    int32_t contentLen;                         /**< The length of the media content */
-    int32_t rightsOffset;                       /**< The offset of the rights object in case of combined delivery */
-    int32_t rightsLen;                          /**< The length of the rights object in case of combined delivery */
-    uint8_t rightsIssuer[MAX_RIGHTS_ISSUER_LEN];/**< The rights issuer address in case of separate delivery */
-} T_DRM_DM_Info;
-
-/**
- * Search the string in a limited length.
- *
- * \param str           The original string
- * \param strSearch     The sub-string to be searched
- * \param len           The length limited
- *
- * \return
- *      -NULL, when there is not the searched string in length
- *      -The pointer of this sub-string
- */
-const uint8_t* drm_strnstr(const uint8_t* str, const uint8_t* strSearch, int32_t len);
-
-/**
- * Parse the DRM message format data.
- *
- * \param buffer        (in)Input the DRM message format data
- * \param bufferLen     (in)The input buffer length
- * \param pDmInfo       (out)A structure pointer which contain information of DRM message headers
- *
- * \return
- *      -TRUE, when success
- *      -FALSE, when failed
- */
-int32_t drm_parseDM(const uint8_t* buffer, int32_t bufferLen, T_DRM_DM_Info* pDmInfo);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __PARSER_DM_H__ */
diff --git a/media/libdrm/mobile1/include/parser/parser_rel.h b/media/libdrm/mobile1/include/parser/parser_rel.h
deleted file mode 100644
index 8def199..0000000
--- a/media/libdrm/mobile1/include/parser/parser_rel.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __PARSER_REL_H__
-#define __PARSER_REL_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <drm_common_types.h>
-
-#define WRITE_RO_FLAG(whoIsAble, boolValue, Indicator, RIGHTS) do{\
-    whoIsAble = boolValue;\
-    Indicator |= RIGHTS;\
-}while(0)
-
-#define CHECK_VALIDITY(ret) do{\
-    if(ret == NULL){\
-        if(XML_ERROR_NO_SUCH_NODE != xml_errno)\
-            return FALSE;\
-    }\
-    else\
-    {\
-        if(XML_ERROR_OK != xml_errno)\
-            return FALSE;\
-    }\
-}while(0)
-
-#define YMD_HMS_2_INT(year, mon, day, date, hour, min, sec, time) do{\
-    date = year * 10000 + mon * 100 + day;\
-    time = hour * 10000 + min * 100 + sec;\
-}while(0)
-
-#define DRM_UID_LEN         256
-#define DRM_KEY_LEN         16
-
-#define XML_DOM_PARSER
-
-typedef struct _T_DRM_DATETIME {
-    int32_t date; /**< year * 10000 + mon *100 + day */
-    int32_t time; /**< hour * 10000 + min *100 + sec */
-} T_DRM_DATETIME;
-
-typedef struct _T_DRM_Rights_Constraint {
-    uint8_t Indicator;          /**< Indicate which is constrainted, the first one indicate 0001, second one indicate 0010 */
-    uint8_t unUsed[3];
-    int32_t Count;              /**< The times that can be used */
-    T_DRM_DATETIME StartTime;   /**< The starting time */
-    T_DRM_DATETIME EndTime;     /**< The ending time */
-    T_DRM_DATETIME Interval;    /**< The interval time */
-} T_DRM_Rights_Constraint;
-
-typedef struct _T_DRM_Rights {
-    uint8_t Version[8];                         /**< Version number */
-    uint8_t uid[256];                           /**< record the rights object name */
-    uint8_t KeyValue[16];                       /**< Decode base64 */
-    int32_t bIsPlayable;                        /**< Is playable */
-    int32_t bIsDisplayable;                     /**< Is displayable */
-    int32_t bIsExecuteable;                     /**< Is executeable */
-    int32_t bIsPrintable;                       /**< Is printable */
-    T_DRM_Rights_Constraint PlayConstraint;     /**< Play constraint */
-    T_DRM_Rights_Constraint DisplayConstraint;  /**< Display constraint */
-    T_DRM_Rights_Constraint ExecuteConstraint;  /**< Execute constraint */
-    T_DRM_Rights_Constraint PrintConstraint;    /**< Print constraint */
-} T_DRM_Rights;
-
-/**
- * Input year and month, return how many days that month have
- * \param year          (in)Input the year
- * \param month         (in)Input the month
- * \return
- *      -A positive integer, which is how many days that month have
- *      -When wrong input, return -1
- */
-int32_t drm_monthDays(int32_t year, int32_t month);
-
-/**
- * Check whether the date and time is valid.
- * \param year          year of the date
- * \param month         month of the date
- * \param day           day of the date
- * \param hour          hour of the time
- * \param min           minute of the time
- * \param sec           second of the time
- * \return
- *      -when it is a valid time, return 0
- *      -when it is a invalid time, return -1
- */
-int32_t drm_checkDate(int32_t year, int32_t month, int32_t day, int32_t hour, int32_t min, int32_t sec);
-
-/**
- * Parse the rights object include xml format and wbxml format data
- *
- * \param buffer        (in)Input the DRM rights object data
- * \param bufferLen     (in)The buffer length
- * \param format        (in)Which format, xml or wbxml
- * \param pRights       (out)A structure pointer which save the rights information
- *
- * \return
- *      -TRUE, when success
- *      -FALSE, when failed
- */
-int32_t drm_relParser(uint8_t* buffer, int32_t bufferLen, int32_t Format, T_DRM_Rights* pRights);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __PARSER_REL_H__ */
diff --git a/media/libdrm/mobile1/include/xml/wbxml_tinyparser.h b/media/libdrm/mobile1/include/xml/wbxml_tinyparser.h
deleted file mode 100644
index 1c40467..0000000
--- a/media/libdrm/mobile1/include/xml/wbxml_tinyparser.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __WBXML_TINYPARSER_H__
-#define __WBXML_TINYPARSER_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <drm_common_types.h>
-
-#define REL_TAG_RIGHTS                                       0x05
-#define REL_TAG_CONTEXT                                      0x06
-#define REL_TAG_VERSION                                      0x07
-#define REL_TAG_UID                                          0x08
-#define REL_TAG_AGREEMENT                                    0x09
-#define REL_TAG_ASSET                                        0x0A
-#define REL_TAG_KEYINFO                                      0x0B
-#define REL_TAG_KEYVALUE                                     0x0C
-#define REL_TAG_PERMISSION                                   0x0D
-#define REL_TAG_PLAY                                         0x0E
-#define REL_TAG_DISPLAY                                      0x0F
-#define REL_TAG_EXECUTE                                      0x10
-#define REL_TAG_PRINT                                        0x11
-#define REL_TAG_CONSTRAINT                                   0x12
-#define REL_TAG_COUNT                                        0x13
-#define REL_TAG_DATETIME                                     0x14
-#define REL_TAG_START                                        0x15
-#define REL_TAG_END                                          0x16
-#define REL_TAG_INTERVAL                                     0x17
-
-#define REL_CHECK_WBXML_HEADER(x) ((x != NULL) && (x[0] == 0x03) && (x[1] == 0x0E) && (x[2] == 0x6A))
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __WBXML_TINYPARSER_H__ */
diff --git a/media/libdrm/mobile1/include/xml/xml_tinyParser.h b/media/libdrm/mobile1/include/xml/xml_tinyParser.h
deleted file mode 100644
index 4ad65b8..0000000
--- a/media/libdrm/mobile1/include/xml/xml_tinyParser.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __XML_TINYPARSER_H__
-#define __XML_TINYPARSER_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <drm_common_types.h>
-
-#define XML_DOM_PARSER
-#define WBXML_DOM_PARSER
-#define XML_DOM_CHECK_ENDTAG
-#define XML_ENABLE_ERRNO
-#define WBXML_OLD_VERSION /* for drm only */
-
-#ifdef DEBUG_MODE
-void XML_PrintMallocInfo();
-#endif /* DEBUG_MODE */
-
-#define XML_TRUE                                             1
-#define XML_FALSE                                            0
-#define XML_EOF                                              0
-#define XML_TAG_START                                        0
-#define XML_TAG_END                                          1
-#define XML_TAG_SELF                                         2
-
-#define XML_MAX_PROPERTY_LEN                                 256
-#define XML_MAX_ATTR_NAME_LEN                                256
-#define XML_MAX_ATTR_VALUE_LEN                               256
-#define XML_MAX_VALUE_LEN                                    256
-
-#define XML_ERROR_OK                                         0
-#define XML_ERROR_BUFFER_NULL                                -1
-#define XML_ERROR_ATTR_NAME                                  -2
-#define XML_ERROR_ATTR_MISSED_EQUAL                          -3
-#define XML_ERROR_PROPERTY_NAME                              -4
-#define XML_ERROR_ATTR_VALUE                                 -5
-#define XML_ERROR_ENDTAG                                     -6
-#define XML_ERROR_NO_SUCH_NODE                               -7
-#define XML_ERROR_PROPERTY_END                               -8
-#define XML_ERROR_VALUE                                      -9
-#define XML_ERROR_NO_START_TAG                               -14
-#define XML_ERROR_NOVALUE                                    -15
-
-#define WBXML_ERROR_MISSED_CONTENT                           -10
-#define WBXML_ERROR_MBUINT32                                 -11
-#define WBXML_ERROR_MISSED_STARTTAG                          -12
-#define WBXML_ERROR_MISSED_ENDTAG                            -13
-
-#ifdef XML_ENABLE_ERRNO
-extern int32_t xml_errno;
-#define XML_ERROR(x) do { xml_errno = x; } while (0)
-#else  /* XML_ENABLE_ERRNO */
-#define XML_ERROR
-#endif /* XML_ENABLE_ERRNO */
-
-#ifdef XML_DOM_PARSER
-uint8_t *XML_DOM_getNode(uint8_t *buffer, const uint8_t *const node);
-uint8_t *XML_DOM_getNodeValue(uint8_t *buffer, uint8_t *node,
-                           uint8_t **value, int32_t *valueLen);
-
-uint8_t *XML_DOM_getValue(uint8_t *buffer, uint8_t **pValue, int32_t *valueLen);
-uint8_t *XML_DOM_getAttr(uint8_t *buffer, uint8_t **pName, int32_t *nameLen,
-                      uint8_t **pValue, int32_t *valueLen);
-
-uint8_t *XML_DOM_getNextNode(uint8_t *buffer, uint8_t **pNodeName,
-                          int32_t *nodenameLen);
-
-uint8_t *XML_DOM_getTag(uint8_t *buffer, int32_t *tagLen, int32_t *tagType);
-#endif /* XML_DOM_PARSER */
-
-#ifdef WBXML_DOM_PARSER
-
-#define WBXML_WITH_ATTR                                      0x80
-#define WBXML_WITH_CONTENT                                   0x40
-#define WBXML_ATTR_END                                       0x01
-#define WBXML_CONTENT_END                                    0x01
-
-#define WBXML_SWITCH_PAGE                                    0x00
-#define WBXML_STR_I                                          0x03
-#define WBXML_END                                            0x00
-#define WBXML_OPAUE                                          0xC3
-#define WBXML_STR_T                                          0x83
-#define WBXML_OPAQUE                                         0xC3
-
-#define WBXML_GET_TAG(x) ((x) & 0x3F) /* get 6-digits */
-#define WBXML_HAS_ATTR(x) ((x) & WBXML_WITH_ATTR)
-#define WBXML_HAS_CONTENT(x) ((x) & WBXML_WITH_CONTENT)
-
-typedef struct _WBXML {
-    uint8_t version;
-    uint8_t unUsed[3];
-    uint32_t publicid;
-    uint32_t charset;
-    int32_t strTableLen;
-    uint8_t *strTable;
-    uint8_t *Content;
-    uint8_t *End;
-    uint8_t *curPtr;
-    int32_t depth;
-} WBXML;
-
-typedef int32_t XML_BOOL;
-
-#ifdef WBXML_OLD_VERSION
-uint8_t *WBXML_DOM_getNode(uint8_t *buffer, int32_t bufferLen,
-                                 uint8_t *node);
-uint8_t *WBXML_DOM_getNodeValue(uint8_t *buffer, int32_t bufferLen,
-                                      uint8_t *node,
-                                      uint8_t **value,
-                                      int32_t *valueLen);
-#endif /* WBXML_OLD_VERSION */
-
-XML_BOOL WBXML_DOM_Init(WBXML * pWbxml, uint8_t *buffer,
-                        int32_t bufferLen);
-XML_BOOL WBXML_DOM_Eof(WBXML * pWbxml);
-uint8_t WBXML_DOM_GetTag(WBXML * pWbxml);
-uint8_t WBXML_DOM_GetChar(WBXML * pWbxml);
-uint8_t WBXML_DOM_GetUIntVar(WBXML * pWbxml);
-void WBXML_DOM_Rewind(WBXML * pWbxml);
-void WBXML_DOM_Seek(WBXML * pWbxml, int32_t offset);
-int32_t WBXML_GetUintVar(const uint8_t *const buffer, int32_t *len);
-
-#endif /* WBXML_DOM_PARSER */
-
-#ifdef XML_TREE_STRUCTURE
-
-typedef struct _XML_TREE_ATTR XML_TREE_ATTR;
-struct _XML_TREE_ATTR {
-    uint8_t name[XML_MAX_ATTR_VALUE_LEN];
-    uint8_t value[XML_MAX_ATTR_VALUE_LEN];
-    XML_TREE_ATTR *next;
-};
-
-typedef struct _XML_TREE XML_TREE;
-struct _XML_TREE {
-    uint8_t tag[XML_MAX_PROPERTY_LEN];
-    uint8_t value[XML_MAX_VALUE_LEN];
-    XML_TREE_ATTR *attr;
-    XML_TREE_ATTR *last_attr;
-    XML_TREE *brother;
-    XML_TREE *last_brother;
-    XML_TREE *child;
-};
-
-XML_TREE *XML_makeTree(uint8_t **buf);
-void XML_freeTree(XML_TREE * pTree);
-
-#endif /* XML_TREE_STRUCTURE */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __XML_TINYPARSER_H__ */
diff --git a/media/libdrm/mobile1/src/jni/drm1_jni.c b/media/libdrm/mobile1/src/jni/drm1_jni.c
deleted file mode 100644
index 11353a7..0000000
--- a/media/libdrm/mobile1/src/jni/drm1_jni.c
+++ /dev/null
@@ -1,1166 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file drm1_jni.c
- *
- * This file implement the Java Native Interface
- * for supporting OMA DRM 1.0
- */
-
-#include <jni/drm1_jni.h>
-#include <objmng/svc_drm.h>
-#include "log.h"
-#include "JNIHelp.h"
-
-
-#define MS_PER_SECOND 1000                  /* Milliseconds per second */
-#define MS_PER_MINUTE 60 * MS_PER_SECOND    /* Milliseconds per minute */
-#define MS_PER_HOUR   60 * MS_PER_MINUTE    /* Milliseconds per hour */
-#define MS_PER_DAY    24 * MS_PER_HOUR      /* Milliseconds per day */
-
-#define SECONDS_PER_MINUTE 60                       /* Seconds per minute*/
-#define SECONDS_PER_HOUR   60 * SECONDS_PER_MINUTE  /* Seconds per hour */
-#define SECONDS_PER_DAY    24 * SECONDS_PER_HOUR    /* Seconds per day */
-
-#define DAY_PER_MONTH 30                    /* Days per month */
-#define DAY_PER_YEAR  365                   /* Days per year */
-
-/** Nonzero if 'y' is a leap year, else zero. */
-#define leap(y) (((y) % 4 == 0 && (y) % 100 != 0) || (y) % 400 == 0)
-
-/** Number of leap years from 1970 to 'y' (not including 'y' itself). */
-#define nleap(y) (((y) - 1969) / 4 - ((y) - 1901) / 100 + ((y) - 1601) / 400)
-
-/** Accumulated number of days from 01-Jan up to start of current month. */
-static const int32_t ydays[] = {
-    0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
-};
-
-#define int64_const(s)          (s)
-#define int64_add(dst, s1, s2)  ((void)((dst) = (s1) + (s2)))
-#define int64_mul(dst, s1, s2)  ((void)((dst) = (int64_t)(s1) * (int64_t)(s2)))
-
-/**
- * DRM data structure
- */
-typedef struct _DrmData {
-    /**
-     * The id of the DRM content.
-     */
-    int32_t id;
-
-    /**
-     * The pointer of JNI interface.
-     */
-    JNIEnv* env;
-
-    /**
-     * The pointer of DRM raw content InputStream object.
-     */
-    jobject* pInData;
-
-    /**
-     * The len of the InputStream object.
-     */
-    int32_t len;
-
-    /**
-     * The next DRM data.
-     */
-    struct _DrmData *next;
-} DrmData;
-
-/** The table to hold all the DRM data. */
-static DrmData *drmTable = NULL;
-
-/**
- * Allocate a new item of DrmData.
- *
- * \return a pointer to a DrmData item if allocate successfully,
- *         otherwise return NULL
- */
-static DrmData * newItem(void)
-{
-    DrmData *d = (DrmData *)malloc(sizeof(DrmData));
-
-    if (d != NULL) {
-        d->id = -1;
-        d->next = NULL;
-    }
-
-    return d;
-}
-
-/**
- * Free the memory of the specified DrmData item <code>d</code>.
- *
- * \param d - a pointer to DrmData
- */
-static void freeItem(DrmData *d)
-{
-    assert(d != NULL);
-
-    free(d);
-}
-
-/**
- * Insert a DrmData item with given <code>name</code> into the head of
- * the DrmData list.
- *
- * @param d - the pointer of the JNI interface
- * @param pInData - the pointer of the DRM content InputStream object.
- *
- * @return <code>JNI_DRM_SUCCESS</code> if insert successfully, otherwise
- *         return <code>JNI_DRM_FAILURE</code>
- */
-static int32_t addItem(DrmData* d)
-{
-    if (NULL == d)
-        return JNI_DRM_FAILURE;
-
-    if (NULL == drmTable) {
-        drmTable = d;
-        return JNI_DRM_SUCCESS;
-    }
-
-    d->next = drmTable;
-    drmTable = d;
-
-    return JNI_DRM_SUCCESS;
-}
-
-/**
- * Get the item from the DrmData list by the specified <code>
- * id</code>.
- *
- * @param p - the pointer of the DRM content InputStream object.
- *
- * @return a pointer to the DrmData item if find it successfuly,
- *         otherwise return NULL
- */
-static DrmData * getItem(int32_t id)
-{
-    DrmData *d;
-
-    if (NULL == drmTable)
-        return NULL;
-
-    for (d = drmTable; d != NULL; d = d->next) {
-        if (id == d->id)
-            return d;
-    }
-
-    return NULL;
-}
-
-/**
- * Remove the specified DrmData item <code>d</code>.
- *
- * @param p - the pointer of the DRM content InputStream object.
- *
- * @return <code>JNI_DRM_SUCCESS</code> if remove successfuly,
- *         otherwise return <code>JNI_DRM_FAILURE</code>
- */
-static int32_t removeItem(int32_t id)
-{
-    DrmData *curItem, *preItem, *dstItem;
-
-    if (NULL == drmTable)
-        return JNI_DRM_FAILURE;
-
-    preItem = NULL;
-    for (curItem = drmTable; curItem != NULL; curItem = curItem->next) {
-        if (id == curItem->id) {
-            if (curItem == drmTable)
-                drmTable = curItem->next;
-            else
-                preItem->next = curItem->next;
-
-            freeItem(curItem);
-
-            return JNI_DRM_SUCCESS;
-        }
-
-        preItem = curItem;
-    }
-
-    return JNI_DRM_FAILURE;
-}
-
-
-static int32_t getInputStreamDataLength(int32_t handle)
-{
-    JNIEnv* env;
-    jobject* pInputStream;
-    int32_t len;
-    DrmData* p;
-    jclass cls;
-    jmethodID mid;
-
-    p = (DrmData *)handle;
-
-    if (NULL == p)
-        return 0;
-
-    env = p->env;
-    pInputStream = p->pInData;
-    len = p->len;
-
-    if (NULL == env || p->len <= 0 || NULL == pInputStream)
-        return 0;
-
-    /* check the original InputStream is available or not */
-    cls = (*env)->GetObjectClass(env, *pInputStream);
-    mid = (*env)->GetMethodID(env, cls, "available", "()I");
-    (*env)->DeleteLocalRef(env, cls);
-
-    if (NULL == mid)
-        return 0;
-
-    if (0 > (*env)->CallIntMethod(env, *pInputStream, mid))
-        return 0;
-
-    return len;
-}
-
-static int32_t readInputStreamData(int32_t handle, uint8_t* buf, int32_t bufLen)
-{
-    JNIEnv* env;
-    jobject* pInputStream;
-    int32_t len;
-    DrmData* p;
-    jclass cls;
-    jmethodID mid;
-    jbyteArray tmp;
-    int tmpLen;
-    jbyte* pNativeBuf;
-
-    p = (DrmData *)handle;
-
-    if (NULL == p || NULL == buf || bufLen <- 0)
-        return 0;
-
-    env = p->env;
-    pInputStream = p->pInData;
-    len = p->len;
-
-    if (NULL == env || p->len <= 0 || NULL == pInputStream)
-        return 0;
-
-    cls = (*env)->GetObjectClass(env, *pInputStream);
-    mid = (*env)->GetMethodID(env, cls, "read", "([BII)I");
-    tmp = (*env)->NewByteArray(env, bufLen);
-    bufLen = (*env)->CallIntMethod(env, *pInputStream, mid, tmp, 0, bufLen);
-
-    (*env)->DeleteLocalRef(env, cls);
-
-    if (-1 == bufLen)
-        return -1;
-
-    pNativeBuf = (*env)->GetByteArrayElements(env, tmp, NULL);
-    memcpy(buf, pNativeBuf, bufLen);
-    (*env)->ReleaseByteArrayElements(env, tmp, pNativeBuf, 0);
-    (*env)->DeleteLocalRef(env, tmp);
-
-    return bufLen;
-}
-
-static const T_DRM_Rights_Info_Node *searchRightsObject(const jbyte* roId, const T_DRM_Rights_Info_Node* pRightsList)
-{
-    const T_DRM_Rights_Info_Node *pTmp;
-
-    if (NULL == roId || NULL == pRightsList)
-        return NULL;
-
-    pTmp = pRightsList;
-
-    while (NULL != pTmp) {
-        if(0 == strcmp((char *)roId, (char *)pTmp->roInfo.roId))
-            break;
-        pTmp = pTmp->next;
-    }
-
-    return pTmp;
-}
-
-/**
- * Returns the difference in seconds between the given GMT time
- * and 1970-01-01 00:00:00 GMT.
- *
- * \param year the year (since 1970)
- * \param month the month (1 - 12)
- * \param day the day (1 - 31)
- * \param hour the hour (0 - 23)
- * \param minute the minute (0 - 59)
- * \param second the second (0 - 59)
- *
- * \return the difference in seconds between the given GMT time
- *         and 1970-01-01 00:00:00 GMT.
- */
-static int64_t mkgmtime(
-        uint32_t year, uint32_t month, uint32_t day,
-        uint32_t hour, uint32_t minute, uint32_t second)
-{
-    int64_t result;
-
-    /*
-     * FIXME: It does not check whether the specified days
-     *        is valid based on the specified months.
-     */
-    assert(year >= 1970
-            && month > 0 && month <= 12
-            && day > 0 && day <= 31
-            && hour < 24 && minute < 60
-            && second < 60);
-
-    /* Set 'day' to the number of days into the year. */
-    day += ydays[month - 1] + (month > 2 && leap (year)) - 1;
-
-    /* Now calculate 'day' to the number of days since Jan 1, 1970. */
-    day = day + 365 * (year - 1970) + nleap(year);
-
-    int64_mul(result, int64_const(day), int64_const(SECONDS_PER_DAY));
-    int64_add(result, result, int64_const(
-        SECONDS_PER_HOUR * hour + SECONDS_PER_MINUTE * minute + second));
-
-    return result;
-}
-
-/**
- * Compute the milliseconds by the specified <code>date</code>
- * and <code>time</code>.
- *
- * @param date - the specified date,
- *               <code>date = year * 10000 + month * 100 + day</code>
- * @param time - the specified time,
- *               <code>time = hour * 10000 + minute * 100 + second</code>
- *
- * @return the related milliseconds
- */
-static int64_t computeTime(int32_t date, int32_t time)
-{
-    int32_t year, month, day, hour, minute, second;
-
-    year = date / 10000;
-    month = (date / 100) % 100;
-    day = date % 100;
-    hour = time / 10000;
-    minute = (time / 100) % 100;
-    second = time % 100;
-
-    /* Adjust the invalid parameters. */
-    if (year < 1970) year = 1970;
-    if (month < 1) month = 1;
-    if (month > 12) month = 12;
-    if (day < 1) day = 1;
-    if (day > 31) day = 31;
-    if (hour < 0) hour = 0;
-    if (hour > 23) hour = 23;
-    if (minute < 0) minute = 0;
-    if (minute > 59) minute = 59;
-    if (second < 0) second = 0;
-    if (second > 59) second = 59;
-
-    return mkgmtime(year, month, day, hour, minute, second) * 1000;
-}
-
-/**
- * Compute the milliseconds by the specified <code>date</code>
- * and <code>time</code>.
- * Note that here we always treat 1 year as 365 days and 1 month as 30 days
- * that is not precise. But it should not be a problem since OMA DRM 2.0
- * already restricts the interval representation to be day-based,
- * i.e. there will not be an interval with year or month any more in the
- * future.
- *
- * @param date - the specified date,
- *               <code>date = year * 10000 + month * 100 + day</code>
- * @param time - the specified time,
- *               <code>time = hour * 10000 + minute * 100 + second</code>
- *
- * @return the related milliseconds
- */
-static int64_t computeInterval(int32_t date, int32_t time)
-{
-    int32_t year, month, day, hour, minute, second;
-    int64_t milliseconds;
-
-    year = date / 10000;
-    month = (date / 100) % 100;
-    day = date % 100;
-    hour = time / 10000;
-    minute = (time / 100) % 100;
-    second = time % 100;
-
-    /* milliseconds = ((((year * 365 + month * 30 + day) * 24
-     *                + hour) * 60 + minute) * 60 + second) * 1000;
-     */
-    int64_mul(milliseconds,
-        int64_const(year * DAY_PER_YEAR + month * DAY_PER_MONTH + day),
-        int64_const(MS_PER_DAY));
-    int64_add(milliseconds, milliseconds,
-        int64_const(hour * MS_PER_HOUR + minute * MS_PER_MINUTE +
-            second * MS_PER_SECOND));
-
-    return milliseconds;
-}
-
-static jint getObjectIntField(JNIEnv * env, jobject obj, const char *name, jint * value)
-{
-    jclass clazz;
-    jfieldID field;
-
-    clazz = (*env)->GetObjectClass(env, obj);
-    if (NULL == clazz)
-        return JNI_DRM_FAILURE;
-
-    field = (*env)->GetFieldID(env, clazz, name, "I");
-    (*env)->DeleteLocalRef(env, clazz);
-
-    if (NULL == field)
-        return JNI_DRM_FAILURE;
-
-    *value = (*env)->GetIntField(env, obj, field);
-
-    return JNI_DRM_SUCCESS;
-}
-
-static jint setObjectIntField(JNIEnv * env, jobject obj, const char *name, jint value)
-{
-    jclass clazz;
-    jfieldID field;
-
-    clazz = (*env)->GetObjectClass(env, obj);
-    if (NULL == clazz)
-        return JNI_DRM_FAILURE;
-
-    field = (*env)->GetFieldID(env, clazz, name, "I");
-    (*env)->DeleteLocalRef(env, clazz);
-
-    if (NULL == field)
-        return JNI_DRM_FAILURE;
-
-    (*env)->SetIntField(env, obj, field, value);
-
-    return JNI_DRM_SUCCESS;
-}
-
-static jint setObjectLongField(JNIEnv * env, jobject obj, const char *name, jlong value)
-{
-    jclass clazz;
-    jfieldID field;
-
-    clazz = (*env)->GetObjectClass(env, obj);
-    if (NULL == clazz)
-        return JNI_DRM_FAILURE;
-
-    field = (*env)->GetFieldID(env, clazz, name, "J");
-    (*env)->DeleteLocalRef(env, clazz);
-
-    if (NULL == field)
-        return JNI_DRM_FAILURE;
-
-    (*env)->SetLongField(env, obj, field, value);
-
-    return JNI_DRM_SUCCESS;
-}
-
-static jint setConstraintFields(JNIEnv * env, jobject constraint, T_DRM_Constraint_Info * pConstraint)
-{
-    /* if no this permission */
-    if (pConstraint->indicator == (uint8_t)DRM_NO_RIGHTS) {
-        if (JNI_DRM_FAILURE == setObjectIntField(env, constraint, "count", 0))
-            return JNI_DRM_FAILURE;
-
-        return JNI_DRM_SUCCESS;
-    }
-
-    /* set count field */
-    if (pConstraint->indicator & DRM_COUNT_CONSTRAINT) {
-        if (JNI_DRM_FAILURE == setObjectIntField(env, constraint, "count", pConstraint->count))
-            return JNI_DRM_FAILURE;
-    }
-
-    /* set start time field */
-    if (pConstraint->indicator & DRM_START_TIME_CONSTRAINT) {
-        int64_t startTime;
-
-        startTime = computeTime(pConstraint->startDate, pConstraint->startTime);
-
-        if (JNI_DRM_FAILURE == setObjectLongField(env, constraint, "startDate", startTime))
-            return JNI_DRM_FAILURE;
-    }
-
-    /* set end time field */
-    if (pConstraint->indicator & DRM_END_TIME_CONSTRAINT) {
-        int64_t endTime;
-
-        endTime = computeTime(pConstraint->endDate, pConstraint->endTime);
-
-        if (JNI_DRM_FAILURE == setObjectLongField(env, constraint, "endDate", endTime))
-            return JNI_DRM_FAILURE;
-    }
-
-    /* set interval field */
-    if (pConstraint->indicator & DRM_INTERVAL_CONSTRAINT) {
-        int64_t interval;
-
-        interval = computeInterval(pConstraint->intervalDate, pConstraint->intervalTime);
-
-        if (JNI_DRM_FAILURE == setObjectLongField(env, constraint, "interval", interval))
-            return JNI_DRM_FAILURE;
-    }
-
-    return JNI_DRM_SUCCESS;
-}
-
-static jint setRightsFields(JNIEnv * env, jobject rights, T_DRM_Rights_Info* pRoInfo)
-{
-    jclass clazz;
-    jfieldID field;
-    jstring str;
-    jint index;
-
-    clazz = (*env)->GetObjectClass(env, rights);
-    if (NULL == clazz)
-        return JNI_DRM_FAILURE;
-
-    /* set roId field */
-    field = (*env)->GetFieldID(env, clazz, "roId", "Ljava/lang/String;");
-    (*env)->DeleteLocalRef(env, clazz);
-
-    if (NULL == field)
-        return JNI_DRM_FAILURE;
-
-    str = (*env)->NewStringUTF(env, (char *)pRoInfo->roId);
-    if (NULL == str)
-        return JNI_DRM_FAILURE;
-
-    (*env)->SetObjectField(env, rights, field, str);
-    (*env)->DeleteLocalRef(env, str);
-
-    return JNI_DRM_SUCCESS;
-}
-
-/* native interface */
-JNIEXPORT jint JNICALL
-Java_android_drm_mobile1_DrmRawContent_nativeConstructDrmContent
-  (JNIEnv * env, jobject rawContent, jobject data, jint len, jint mimeType)
-{
-    int32_t id;
-    T_DRM_Input_Data inData;
-    DrmData* drmInData;
-
-    switch (mimeType) {
-    case JNI_DRM_MIMETYPE_MESSAGE:
-        mimeType = TYPE_DRM_MESSAGE;
-        break;
-    case JNI_DRM_MIMETYPE_CONTENT:
-        mimeType = TYPE_DRM_CONTENT;
-        break;
-    default:
-        return JNI_DRM_FAILURE;
-    }
-
-    drmInData = newItem();
-    if (NULL == drmInData)
-        return JNI_DRM_FAILURE;
-
-    drmInData->env = env;
-    drmInData->pInData = &data;
-    drmInData->len = len;
-
-    if (JNI_DRM_FAILURE == addItem(drmInData))
-        return JNI_DRM_FAILURE;
-
-    inData.inputHandle = (int32_t)drmInData;
-    inData.mimeType = mimeType;
-    inData.getInputDataLength = getInputStreamDataLength;
-    inData.readInputData = readInputStreamData;
-
-    id = SVC_drm_openSession(inData);
-    if (id < 0)
-        return JNI_DRM_FAILURE;
-
-    drmInData->id = id;
-
-    return id;
-}
-
-/* native interface */
-JNIEXPORT jstring JNICALL
-Java_android_drm_mobile1_DrmRawContent_nativeGetRightsAddress
-  (JNIEnv * env, jobject rawContent)
-{
-    jint id;
-    uint8_t rightsIssuer[256] = {0};
-    jstring str = NULL;
-
-    if (JNI_DRM_FAILURE == getObjectIntField(env, rawContent, "id", &id))
-        return NULL;
-
-    if (DRM_SUCCESS == SVC_drm_getRightsIssuer(id, rightsIssuer))
-        str = (*env)->NewStringUTF(env, (char *)rightsIssuer);
-
-    return str;
-}
-
-/* native interface */
-JNIEXPORT jint JNICALL
-Java_android_drm_mobile1_DrmRawContent_nativeGetDeliveryMethod
-  (JNIEnv * env, jobject rawContent)
-{
-    jint id;
-    int32_t res;
-
-    if (JNI_DRM_FAILURE == getObjectIntField(env, rawContent, "id", &id))
-        return JNI_DRM_FAILURE;
-
-    res = SVC_drm_getDeliveryMethod(id);
-
-    switch (res) {
-    case FORWARD_LOCK:
-        return JNI_DRM_FORWARD_LOCK;
-    case COMBINED_DELIVERY:
-        return JNI_DRM_COMBINED_DELIVERY;
-    case SEPARATE_DELIVERY:
-        return JNI_DRM_SEPARATE_DELIVERY;
-    case SEPARATE_DELIVERY_FL:
-        return JNI_DRM_SEPARATE_DELIVERY_DM;
-    default:
-        return JNI_DRM_FAILURE;
-    }
-}
-
-/* native interface */
-JNIEXPORT jint JNICALL
-Java_android_drm_mobile1_DrmRawContent_nativeReadContent
-  (JNIEnv * env, jobject rawContent, jbyteArray buf, jint bufOff, jint len, jint mediaOff)
-{
-    jint id;
-    jbyte *nativeBuf;
-    jclass cls;
-    jmethodID mid;
-    DrmData* p;
-    jobject inputStream;
-    jfieldID field;
-
-    if (NULL == buf) {
-        jniThrowNullPointerException(env, "b == null");
-        return JNI_DRM_FAILURE;
-    }
-
-    if (len < 0 || bufOff < 0 || len + bufOff > (*env)->GetArrayLength(env, buf)) {
-        jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
-        return JNI_DRM_FAILURE;
-    }
-
-    if (mediaOff < 0 || len == 0)
-        return JNI_DRM_FAILURE;
-
-    if (JNI_DRM_FAILURE == getObjectIntField(env, rawContent, "id", &id))
-        return JNI_DRM_FAILURE;
-
-    p = getItem(id);
-    if (NULL == p)
-        return JNI_DRM_FAILURE;
-
-    cls = (*env)->GetObjectClass(env, rawContent);
-    if (NULL == cls)
-        return JNI_DRM_FAILURE;
-
-    field = (*env)->GetFieldID(env, cls, "inData", "Ljava/io/BufferedInputStream;");
-    (*env)->DeleteLocalRef(env, cls);
-
-    if (NULL == field)
-        return JNI_DRM_FAILURE;
-
-    inputStream = (*env)->GetObjectField(env, rawContent, field);
-
-    p->env = env;
-    p->pInData = &inputStream;
-
-    nativeBuf = (*env)->GetByteArrayElements(env, buf, NULL);
-
-    len = SVC_drm_getContent(id, mediaOff, (uint8_t *)nativeBuf + bufOff, len);
-
-    (*env)->ReleaseByteArrayElements(env, buf, nativeBuf, 0);
-
-    if (DRM_MEDIA_EOF == len)
-        return JNI_DRM_EOF;
-    if (len <= 0)
-        return JNI_DRM_FAILURE;
-
-    return len;
-}
-
-/* native interface */
-JNIEXPORT jstring JNICALL
-Java_android_drm_mobile1_DrmRawContent_nativeGetContentType
-  (JNIEnv * env, jobject rawContent)
-{
-    jint id;
-    uint8_t contentType[64] = {0};
-    jstring str = NULL;
-
-    if (JNI_DRM_FAILURE == getObjectIntField(env, rawContent, "id", &id))
-        return NULL;
-
-    if (DRM_SUCCESS == SVC_drm_getContentType(id, contentType))
-        str = (*env)->NewStringUTF(env, (char *)contentType);
-
-    return str;
-}
-
-/* native interface */
-JNIEXPORT jint JNICALL
-Java_android_drm_mobile1_DrmRawContent_nativeGetContentLength
-  (JNIEnv * env, jobject rawContent)
-{
-    jint id;
-    int32_t len;
-
-    if (JNI_DRM_FAILURE == getObjectIntField(env, rawContent, "id", &id))
-        return JNI_DRM_FAILURE;
-
-    len = SVC_drm_getContentLength(id);
-
-    if (DRM_UNKNOWN_DATA_LEN == len)
-        return JNI_DRM_UNKNOWN_DATA_LEN;
-
-    if (0 > len)
-        return JNI_DRM_FAILURE;
-
-    return len;
-}
-
-/* native interface */
-JNIEXPORT void JNICALL
-Java_android_drm_mobile1_DrmRawContent_finalize
-  (JNIEnv * env, jobject rawContent)
-{
-    jint id;
-
-    if (JNI_DRM_FAILURE == getObjectIntField(env, rawContent, "id", &id))
-        return;
-
-    removeItem(id);
-
-    SVC_drm_closeSession(id);
-}
-
-/* native interface */
-JNIEXPORT jint JNICALL
-Java_android_drm_mobile1_DrmRights_nativeGetConstraintInfo
-  (JNIEnv * env, jobject rights, jint permission, jobject constraint)
-{
-    jclass clazz;
-    jfieldID field;
-    jstring str;
-    uint8_t *nativeStr;
-    T_DRM_Rights_Info_Node *pRightsList;
-    T_DRM_Rights_Info_Node *pCurNode;
-    T_DRM_Constraint_Info *pConstraint;
-
-    clazz = (*env)->GetObjectClass(env, rights);
-    if (NULL == clazz)
-        return JNI_DRM_FAILURE;
-
-    field = (*env)->GetFieldID(env, clazz, "roId", "Ljava/lang/String;");
-    (*env)->DeleteLocalRef(env, clazz);
-
-    if (NULL == field)
-        return JNI_DRM_FAILURE;
-
-    str = (*env)->GetObjectField(env, rights, field);
-
-    nativeStr = (uint8_t *)(*env)->GetStringUTFChars(env, str, NULL);
-    if (NULL == nativeStr)
-        return JNI_DRM_FAILURE;
-
-    /* this means forward-lock rights */
-    if (0 == strcmp((char *)nativeStr, "ForwardLock")) {
-        (*env)->ReleaseStringUTFChars(env, str, (char *)nativeStr);
-        return JNI_DRM_SUCCESS;
-    }
-
-    if (DRM_FAILURE == SVC_drm_viewAllRights(&pRightsList)) {
-        (*env)->ReleaseStringUTFChars(env, str, (char *)nativeStr);
-        return JNI_DRM_FAILURE;
-    }
-
-    pCurNode = searchRightsObject((jbyte *)nativeStr, pRightsList);
-    if (NULL == pCurNode) {
-        (*env)->ReleaseStringUTFChars(env, str, (char *)nativeStr);
-        SVC_drm_freeRightsInfoList(pRightsList);
-        return JNI_DRM_FAILURE;
-    }
-    (*env)->ReleaseStringUTFChars(env, str, (char *)nativeStr);
-
-    switch (permission) {
-    case JNI_DRM_PERMISSION_PLAY:
-        pConstraint = &(pCurNode->roInfo.playRights);
-        break;
-    case JNI_DRM_PERMISSION_DISPLAY:
-        pConstraint = &(pCurNode->roInfo.displayRights);
-        break;
-    case JNI_DRM_PERMISSION_EXECUTE:
-        pConstraint = &(pCurNode->roInfo.executeRights);
-        break;
-    case JNI_DRM_PERMISSION_PRINT:
-        pConstraint = &(pCurNode->roInfo.printRights);
-        break;
-    default:
-        SVC_drm_freeRightsInfoList(pRightsList);
-        return JNI_DRM_FAILURE;
-    }
-
-    /* set constraint field */
-    if (JNI_DRM_FAILURE == setConstraintFields(env, constraint, pConstraint)) {
-        SVC_drm_freeRightsInfoList(pRightsList);
-        return JNI_DRM_FAILURE;
-    }
-
-    SVC_drm_freeRightsInfoList(pRightsList);
-
-    return JNI_DRM_SUCCESS;
-}
-
-/* native interface */
-JNIEXPORT jint JNICALL
-Java_android_drm_mobile1_DrmRights_nativeConsumeRights
-  (JNIEnv * env, jobject rights, jint permission)
-{
-    jclass clazz;
-    jfieldID field;
-    jstring str;
-    uint8_t *nativeStr;
-    int32_t id;
-
-    switch (permission) {
-    case JNI_DRM_PERMISSION_PLAY:
-        permission = DRM_PERMISSION_PLAY;
-        break;
-    case JNI_DRM_PERMISSION_DISPLAY:
-        permission = DRM_PERMISSION_DISPLAY;
-        break;
-    case JNI_DRM_PERMISSION_EXECUTE:
-        permission = DRM_PERMISSION_EXECUTE;
-        break;
-    case JNI_DRM_PERMISSION_PRINT:
-        permission = DRM_PERMISSION_PRINT;
-        break;
-    default:
-        return JNI_DRM_FAILURE;
-    }
-
-    clazz = (*env)->GetObjectClass(env, rights);
-    if (NULL == clazz)
-        return JNI_DRM_FAILURE;
-
-    field = (*env)->GetFieldID(env, clazz, "roId", "Ljava/lang/String;");
-    (*env)->DeleteLocalRef(env, clazz);
-
-    if (NULL == field)
-        return JNI_DRM_FAILURE;
-
-    str = (*env)->GetObjectField(env, rights, field);
-
-    nativeStr = (uint8_t *)(*env)->GetStringUTFChars(env, str, NULL);
-    if (NULL == nativeStr)
-        return JNI_DRM_FAILURE;
-
-    if (0 == strcmp("ForwardLock", (char *)nativeStr)) {
-        (*env)->ReleaseStringUTFChars(env, str, (char *)nativeStr);
-        return JNI_DRM_SUCCESS;
-    }
-
-    if (DRM_SUCCESS != SVC_drm_updateRights(nativeStr, permission)) {
-        (*env)->ReleaseStringUTFChars(env, str, (char *)nativeStr);
-        return JNI_DRM_FAILURE;
-    }
-
-    (*env)->ReleaseStringUTFChars(env, str, (char *)nativeStr);
-
-    return JNI_DRM_SUCCESS;
-}
-
-/* native interface */
-JNIEXPORT jint JNICALL
-Java_android_drm_mobile1_DrmRightsManager_nativeInstallDrmRights
-  (JNIEnv * env, jobject rightsManager, jobject data, jint len, jint mimeType, jobject rights)
-{
-    int32_t id;
-    T_DRM_Input_Data inData;
-    DrmData* drmInData;
-    jclass cls;
-    jmethodID mid;
-    T_DRM_Rights_Info rightsInfo;
-
-    switch (mimeType) {
-    case JNI_DRM_MIMETYPE_RIGHTS_XML:
-        mimeType = TYPE_DRM_RIGHTS_XML;
-        break;
-    case JNI_DRM_MIMETYPE_RIGHTS_WBXML:
-        mimeType = TYPE_DRM_RIGHTS_WBXML;
-        break;
-    case JNI_DRM_MIMETYPE_MESSAGE:
-        mimeType = TYPE_DRM_MESSAGE;
-        break;
-    default:
-        return JNI_DRM_FAILURE;
-    }
-
-    drmInData = newItem();
-    if (NULL == drmInData)
-        return JNI_DRM_FAILURE;
-
-    drmInData->env = env;
-    drmInData->pInData = &data;
-    drmInData->len = len;
-
-    inData.inputHandle = (int32_t)drmInData;
-    inData.mimeType = mimeType;
-    inData.getInputDataLength = getInputStreamDataLength;
-    inData.readInputData = readInputStreamData;
-
-    memset(&rightsInfo, 0, sizeof(T_DRM_Rights_Info));
-    if (DRM_FAILURE == SVC_drm_installRights(inData, &rightsInfo))
-        return JNI_DRM_FAILURE;
-
-    freeItem(drmInData);
-
-    return setRightsFields(env, rights, &rightsInfo);
-}
-
-/* native interface */
-JNIEXPORT jint JNICALL
-Java_android_drm_mobile1_DrmRightsManager_nativeQueryRights
-  (JNIEnv * env, jobject rightsManager, jobject rawContent, jobject rights)
-{
-    jint id;
-    T_DRM_Rights_Info rightsInfo;
-
-    if (JNI_DRM_FAILURE == getObjectIntField(env, rawContent, "id", &id))
-        return JNI_DRM_FAILURE;
-
-    memset(&rightsInfo, 0, sizeof(T_DRM_Rights_Info));
-    if (DRM_SUCCESS != SVC_drm_getRightsInfo(id, &rightsInfo))
-        return JNI_DRM_FAILURE;
-
-    return setRightsFields(env, rights, &rightsInfo);
-}
-
-/* native interface */
-JNIEXPORT jint JNICALL
-Java_android_drm_mobile1_DrmRightsManager_nativeGetNumOfRights
-  (JNIEnv * env, jobject rightsManager)
-{
-    T_DRM_Rights_Info_Node *pRightsList;
-    T_DRM_Rights_Info_Node *pCurNode;
-    int32_t num = 0;
-
-    if (DRM_FAILURE == SVC_drm_viewAllRights(&pRightsList))
-        return JNI_DRM_FAILURE;
-
-    pCurNode = pRightsList;
-    while (pCurNode != NULL) {
-        num++;
-        pCurNode = pCurNode->next;
-    }
-
-    SVC_drm_freeRightsInfoList(pRightsList);
-
-    return num;
-}
-
-/* native interface */
-JNIEXPORT jint JNICALL
-Java_android_drm_mobile1_DrmRightsManager_nativeGetRightsList
-  (JNIEnv * env, jobject rightsManager, jobjectArray rightsArray, jint num)
-{
-    T_DRM_Rights_Info_Node *pRightsList;
-    T_DRM_Rights_Info_Node *pCurNode;
-    int32_t index;
-
-    if (DRM_FAILURE == SVC_drm_viewAllRights(&pRightsList))
-        return JNI_DRM_FAILURE;
-
-    pCurNode = pRightsList;
-    for (index = 0; NULL != pCurNode; index++) {
-        jobject rights = (*env)->GetObjectArrayElement(env, rightsArray, index);
-        if (NULL == rights)
-            break;
-
-        if (JNI_DRM_FAILURE == setRightsFields(env, rights, &(pCurNode->roInfo)))
-            break;
-
-        (*env)->SetObjectArrayElement(env, rightsArray, index, rights);
-
-        pCurNode = pCurNode->next;
-    }
-
-    SVC_drm_freeRightsInfoList(pRightsList);
-
-    return index;
-}
-
-/* native interface */
-JNIEXPORT jint JNICALL
-Java_android_drm_mobile1_DrmRightsManager_nativeDeleteRights
-  (JNIEnv * env, jobject rightsManager, jobject rights)
-{
-    jclass clazz;
-    jfieldID field;
-    jstring str;
-    uint8_t *nativeStr;
-
-    clazz = (*env)->GetObjectClass(env, rights);
-    if (NULL == clazz)
-        return JNI_DRM_FAILURE;
-
-    field = (*env)->GetFieldID(env, clazz, "roId", "Ljava/lang/String;");
-    if (NULL == field)
-        return JNI_DRM_FAILURE;
-
-    str = (*env)->GetObjectField(env, rights, field);
-
-    nativeStr = (uint8_t *)(*env)->GetStringUTFChars(env, str, NULL);
-    if (NULL == nativeStr)
-        return JNI_DRM_FAILURE;
-
-    if (0 == strcmp("ForwardLock", (char *)nativeStr))
-        return JNI_DRM_SUCCESS;
-
-    if (DRM_SUCCESS != SVC_drm_deleteRights(nativeStr)) {
-        (*env)->ReleaseStringUTFChars(env, str, (char *)nativeStr);
-        return JNI_DRM_FAILURE;
-    }
-
-    (*env)->ReleaseStringUTFChars(env, str, (char *)nativeStr);
-    return JNI_DRM_SUCCESS;
-}
-
-/*
- * Table of methods associated with the DrmRawContent class.
- */
-static JNINativeMethod gDrmRawContentMethods[] = {
-    /* name, signature, funcPtr */
-    {"nativeConstructDrmContent", "(Ljava/io/InputStream;II)I",
-        (void*)Java_android_drm_mobile1_DrmRawContent_nativeConstructDrmContent},
-    {"nativeGetRightsAddress", "()Ljava/lang/String;",
-        (void*)Java_android_drm_mobile1_DrmRawContent_nativeGetRightsAddress},
-    {"nativeGetDeliveryMethod", "()I",
-        (void*)Java_android_drm_mobile1_DrmRawContent_nativeGetDeliveryMethod},
-    {"nativeReadContent", "([BIII)I",
-        (void*)Java_android_drm_mobile1_DrmRawContent_nativeReadContent},
-    {"nativeGetContentType", "()Ljava/lang/String;",
-        (void*)Java_android_drm_mobile1_DrmRawContent_nativeGetContentType},
-    {"nativeGetContentLength", "()I",
-        (void*)Java_android_drm_mobile1_DrmRawContent_nativeGetContentLength},
-    {"finalize", "()V",
-        (void*)Java_android_drm_mobile1_DrmRawContent_finalize},
-};
-
-/*
- * Table of methods associated with the DrmRights class.
- */
-static JNINativeMethod gDrmRightsMethods[] = {
-    /* name, signature, funcPtr */
-    {"nativeGetConstraintInfo", "(ILandroid/drm/mobile1/DrmConstraintInfo;)I",
-        (void*)Java_android_drm_mobile1_DrmRights_nativeGetConstraintInfo},
-    {"nativeConsumeRights", "(I)I",
-        (void*)Java_android_drm_mobile1_DrmRights_nativeConsumeRights},
-};
-
-/*
- * Table of methods associated with the DrmRightsManager class.
- */
-static JNINativeMethod gDrmRightsManagerMethods[] = {
-    /* name, signature, funcPtr */
-    {"nativeInstallDrmRights", "(Ljava/io/InputStream;IILandroid/drm/mobile1/DrmRights;)I",
-        (void*)Java_android_drm_mobile1_DrmRightsManager_nativeInstallDrmRights},
-    {"nativeQueryRights", "(Landroid/drm/mobile1/DrmRawContent;Landroid/drm/mobile1/DrmRights;)I",
-        (void*)Java_android_drm_mobile1_DrmRightsManager_nativeQueryRights},
-    {"nativeGetNumOfRights", "()I",
-        (void*)Java_android_drm_mobile1_DrmRightsManager_nativeGetNumOfRights},
-    {"nativeGetRightsList", "([Landroid/drm/mobile1/DrmRights;I)I",
-        (void*)Java_android_drm_mobile1_DrmRightsManager_nativeGetRightsList},
-    {"nativeDeleteRights", "(Landroid/drm/mobile1/DrmRights;)I",
-        (void*)Java_android_drm_mobile1_DrmRightsManager_nativeDeleteRights},
-};
-
-/*
- * Register several native methods for one class.
- */
-static int registerNativeMethods(JNIEnv* env, const char* className,
-    JNINativeMethod* gMethods, int numMethods)
-{
-    jclass clazz;
-
-    clazz = (*env)->FindClass(env, className);
-    if (clazz == NULL)
-        return JNI_FALSE;
-
-    if ((*env)->RegisterNatives(env, clazz, gMethods, numMethods) < 0)
-        return JNI_FALSE;
-
-    return JNI_TRUE;
-}
-
-/*
- * Register native methods for all classes we know about.
- */
-static int registerNatives(JNIEnv* env)
-{
-    if (!registerNativeMethods(env, "android/drm/mobile1/DrmRawContent",
-            gDrmRawContentMethods, sizeof(gDrmRawContentMethods) / sizeof(gDrmRawContentMethods[0])))
-        return JNI_FALSE;
-
-    if (!registerNativeMethods(env, "android/drm/mobile1/DrmRights",
-            gDrmRightsMethods, sizeof(gDrmRightsMethods) / sizeof(gDrmRightsMethods[0])))
-        return JNI_FALSE;
-
-    if (!registerNativeMethods(env, "android/drm/mobile1/DrmRightsManager",
-            gDrmRightsManagerMethods, sizeof(gDrmRightsManagerMethods) / sizeof(gDrmRightsManagerMethods[0])))
-        return JNI_FALSE;
-
-    return JNI_TRUE;
-}
-
-jint JNI_OnLoad(JavaVM* vm, void* reserved)
-{
-    JNIEnv* env = NULL;
-    jint result = -1;
-
-    printf("Entering JNI_OnLoad\n");
-
-    if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK)
-        goto bail;
-
-    assert(env != NULL);
-
-    if (!registerNatives(env))
-        goto bail;
-
-    /* success -- return valid version number */
-    result = JNI_VERSION_1_4;
-
-bail:
-    printf("Leaving JNI_OnLoad (result=0x%x)\n", result);
-    return result;
-}
diff --git a/media/libdrm/mobile1/src/objmng/drm_api.c b/media/libdrm/mobile1/src/objmng/drm_api.c
deleted file mode 100644
index 232d9f4..0000000
--- a/media/libdrm/mobile1/src/objmng/drm_api.c
+++ /dev/null
@@ -1,1943 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <svc_drm.h>
-#include <drm_inner.h>
-#include <parser_dm.h>
-#include <parser_dcf.h>
-#include <parser_rel.h>
-#include <drm_rights_manager.h>
-#include <drm_time.h>
-#include <drm_decoder.h>
-#include "log.h"
-
-/**
- * Current id.
- */
-static int32_t curID = 0;
-
-/**
- * The header pointer for the session list.
- */
-static T_DRM_Session_Node* sessionTable = NULL;
-
-/**
- * New a session.
- */
-static T_DRM_Session_Node* newSession(T_DRM_Input_Data data)
-{
-    T_DRM_Session_Node* s = (T_DRM_Session_Node *)malloc(sizeof(T_DRM_Session_Node));
-
-    if (NULL != s) {
-        memset(s, 0, sizeof(T_DRM_Session_Node));
-
-        s->sessionId = curID++;
-        s->inputHandle = data.inputHandle;
-        s->mimeType = data.mimeType;
-        s->getInputDataLengthFunc = data.getInputDataLength;
-        s->readInputDataFunc = data.readInputData;
-        s->seekInputDataFunc = data.seekInputData;
-    }
-
-    return s;
-}
-
-/**
- * Free a session.
- */
-static void freeSession(T_DRM_Session_Node* s)
-{
-    if (NULL == s)
-        return;
-
-    if (NULL != s->rawContent)
-        free(s->rawContent);
-
-    if (NULL != s->readBuf)
-        free(s->readBuf);
-
-    if (NULL != s->infoStruct)
-        free(s->infoStruct);
-
-    free(s);
-}
-
-/**
- * Add a session to list.
- */
-static int32_t addSession(T_DRM_Session_Node* s)
-{
-    if (NULL == s)
-        return -1;
-
-    s->next = sessionTable;
-    sessionTable = s;
-
-    return s->sessionId;
-}
-
-/**
- * Get a session from the list.
- */
-static T_DRM_Session_Node* getSession(int32_t sessionId)
-{
-    T_DRM_Session_Node* s;
-
-    if (sessionId < 0 || NULL == sessionTable)
-        return NULL;
-
-    for (s = sessionTable; s != NULL; s = s->next) {
-        if (sessionId == s->sessionId)
-            return s;
-    }
-
-    return NULL;
-}
-
-/**
- * Remove a session from the list.
- */
-static void removeSession(int32_t sessionId)
-{
-    T_DRM_Session_Node *curS, *preS;
-
-    if (sessionId < 0 || NULL == sessionTable)
-        return;
-
-    if (sessionId == sessionTable->sessionId) {
-        curS = sessionTable;
-        sessionTable = curS->next;
-        freeSession(curS);
-        return;
-    }
-
-    for (preS = sessionTable; preS->next != NULL; preS = preS->next) {
-        if (preS->next->sessionId == sessionId)
-            curS = preS->next;
-    }
-
-    if (NULL == preS->next)
-        return;
-
-    preS->next = curS->next;
-    freeSession(curS);
-}
-
-/**
- * Try to identify the mimetype according the input DRM data.
- */
-static int32_t getMimeType(const uint8_t *buf, int32_t bufLen)
-{
-    const uint8_t *p;
-
-    if (NULL == buf || bufLen <= 0)
-        return TYPE_DRM_UNKNOWN;
-
-    p = buf;
-
-    /* check if it is DRM Content Format, only check the first field of Version, it must be "0x01" */
-    if (0x01 == *p)
-        return TYPE_DRM_CONTENT;
-
-    /* check if it is DRM Message, only check the first two bytes, it must be the start flag of boundary: "--" */
-    if (bufLen >= 2 && '-' == *p && '-' == *(p + 1))
-        return TYPE_DRM_MESSAGE;
-
-    /* check if it is DRM Rights XML format, only check the first several bytes, it must be: "<o-ex:rights" */
-    if (bufLen >= 12 && 0 == strncmp("<o-ex:rights", (char *)p, 12))
-        return TYPE_DRM_RIGHTS_XML;
-
-    /* check if it is DRM Rights WBXML format, only check the first two bytes, it must be: 0x03, 0x0e */
-    if (bufLen >= 2 && 0x03 == *p && 0x0e == *(p + 1))
-        return TYPE_DRM_RIGHTS_WBXML;
-
-    return TYPE_DRM_UNKNOWN;
-}
-
-static int32_t drm_skipCRLFinB64(const uint8_t* b64Data, int32_t len)
-{
-    const uint8_t* p;
-    int32_t skipLen = 0;
-
-    if (NULL == b64Data || len <= 0)
-        return -1;
-
-    p = b64Data;
-    while (p - b64Data < len) {
-        if ('\r' == *p || '\n'== *p)
-            skipLen++;
-        p++;
-    }
-
-    return skipLen;
-}
-
-static int32_t drm_scanEndBoundary(const uint8_t* pBuf, int32_t len, uint8_t* const boundary)
-{
-    const uint8_t* p;
-    int32_t leftLen;
-    int32_t boundaryLen;
-
-    if (NULL == pBuf || len <=0 || NULL == boundary)
-        return -1;
-
-    p = pBuf;
-    boundaryLen = strlen((char *)boundary) + 2; /* 2 means: '\r' and '\n' */
-    leftLen = len - (p - pBuf);
-    while (leftLen > 0) {
-        if (NULL == (p = memchr(p, '\r', leftLen)))
-            break;
-
-        leftLen = len - (p - pBuf);
-        if (leftLen < boundaryLen)
-            return -2; /* here means may be the boundary has been split */
-
-        if (('\n' == *(p + 1)) && (0 == memcmp(p + 2, boundary, strlen((char *)boundary))))
-            return p - pBuf; /* find the boundary here */
-
-        p++;
-        leftLen--;
-    }
-
-    return len; /* no boundary found */
-}
-
-static int32_t drm_getLicenseInfo(T_DRM_Rights* pRights, T_DRM_Rights_Info* licenseInfo)
-{
-    if (NULL != licenseInfo && NULL != pRights) {
-        strcpy((char *)licenseInfo->roId, (char *)pRights->uid);
-
-        if (1 == pRights->bIsDisplayable) {
-            licenseInfo->displayRights.indicator = pRights->DisplayConstraint.Indicator;
-            licenseInfo->displayRights.count =
-                pRights->DisplayConstraint.Count;
-            licenseInfo->displayRights.startDate =
-                pRights->DisplayConstraint.StartTime.date;
-            licenseInfo->displayRights.startTime =
-                pRights->DisplayConstraint.StartTime.time;
-            licenseInfo->displayRights.endDate =
-                pRights->DisplayConstraint.EndTime.date;
-            licenseInfo->displayRights.endTime =
-                pRights->DisplayConstraint.EndTime.time;
-            licenseInfo->displayRights.intervalDate =
-                pRights->DisplayConstraint.Interval.date;
-            licenseInfo->displayRights.intervalTime =
-                pRights->DisplayConstraint.Interval.time;
-        }
-        if (1 == pRights->bIsPlayable) {
-            licenseInfo->playRights.indicator = pRights->PlayConstraint.Indicator;
-            licenseInfo->playRights.count = pRights->PlayConstraint.Count;
-            licenseInfo->playRights.startDate =
-                pRights->PlayConstraint.StartTime.date;
-            licenseInfo->playRights.startTime =
-                pRights->PlayConstraint.StartTime.time;
-            licenseInfo->playRights.endDate =
-                pRights->PlayConstraint.EndTime.date;
-            licenseInfo->playRights.endTime =
-                pRights->PlayConstraint.EndTime.time;
-            licenseInfo->playRights.intervalDate =
-                pRights->PlayConstraint.Interval.date;
-            licenseInfo->playRights.intervalTime =
-                pRights->PlayConstraint.Interval.time;
-        }
-        if (1 == pRights->bIsExecuteable) {
-            licenseInfo->executeRights.indicator = pRights->ExecuteConstraint.Indicator;
-            licenseInfo->executeRights.count =
-                pRights->ExecuteConstraint.Count;
-            licenseInfo->executeRights.startDate =
-                pRights->ExecuteConstraint.StartTime.date;
-            licenseInfo->executeRights.startTime =
-                pRights->ExecuteConstraint.StartTime.time;
-            licenseInfo->executeRights.endDate =
-                pRights->ExecuteConstraint.EndTime.date;
-            licenseInfo->executeRights.endTime =
-                pRights->ExecuteConstraint.EndTime.time;
-            licenseInfo->executeRights.intervalDate =
-                pRights->ExecuteConstraint.Interval.date;
-            licenseInfo->executeRights.intervalTime =
-                pRights->ExecuteConstraint.Interval.time;
-        }
-        if (1 == pRights->bIsPrintable) {
-            licenseInfo->printRights.indicator = pRights->PrintConstraint.Indicator;
-            licenseInfo->printRights.count =
-                pRights->PrintConstraint.Count;
-            licenseInfo->printRights.startDate =
-                pRights->PrintConstraint.StartTime.date;
-            licenseInfo->printRights.startTime =
-                pRights->PrintConstraint.StartTime.time;
-            licenseInfo->printRights.endDate =
-                pRights->PrintConstraint.EndTime.date;
-            licenseInfo->printRights.endTime =
-                pRights->PrintConstraint.EndTime.time;
-            licenseInfo->printRights.intervalDate =
-                pRights->PrintConstraint.Interval.date;
-            licenseInfo->printRights.intervalTime =
-                pRights->PrintConstraint.Interval.time;
-        }
-        return TRUE;
-    }
-    return FALSE;
-}
-
-static int32_t drm_addRightsNodeToList(T_DRM_Rights_Info_Node **ppRightsHeader,
-                                       T_DRM_Rights_Info_Node *pInputRightsNode)
-{
-    T_DRM_Rights_Info_Node *pRightsNode;
-
-    if (NULL == ppRightsHeader || NULL == pInputRightsNode)
-        return FALSE;
-
-    pRightsNode = (T_DRM_Rights_Info_Node *)malloc(sizeof(T_DRM_Rights_Info_Node));
-    if (NULL == pRightsNode)
-        return FALSE;
-
-    memcpy(pRightsNode, pInputRightsNode, sizeof(T_DRM_Rights_Info_Node));
-    pRightsNode->next = NULL;
-
-    /* this means it is the first node */
-    if (NULL == *ppRightsHeader)
-        *ppRightsHeader = pRightsNode;
-    else {
-        T_DRM_Rights_Info_Node *pTmp;
-
-        pTmp = *ppRightsHeader;
-        while (NULL != pTmp->next)
-            pTmp = pTmp->next;
-
-        pTmp->next = pRightsNode;
-    }
-    return TRUE;
-}
-
-static int32_t drm_startConsumeRights(int32_t * bIsXXable,
-                                      T_DRM_Rights_Constraint * XXConstraint,
-                                      int32_t * writeFlag)
-{
-    T_DB_TIME_SysTime curDateTime;
-    T_DRM_DATETIME CurrentTime;
-    uint8_t countFlag = 0;
-
-    memset(&CurrentTime, 0, sizeof(T_DRM_DATETIME));
-
-    if (NULL == bIsXXable || 0 == *bIsXXable || NULL == XXConstraint || NULL == writeFlag)
-        return DRM_FAILURE;
-
-    if (0 != (uint8_t)(XXConstraint->Indicator & DRM_NO_CONSTRAINT)) /* Have utter right? */
-        return DRM_SUCCESS;
-
-    *bIsXXable = 0; /* Assume have invalid rights at first */
-    *writeFlag = 0;
-
-    if (0 != (XXConstraint->Indicator & (DRM_START_TIME_CONSTRAINT | DRM_END_TIME_CONSTRAINT | DRM_INTERVAL_CONSTRAINT))) {
-        DRM_time_getSysTime(&curDateTime);
-
-        if (-1 == drm_checkDate(curDateTime.year, curDateTime.month, curDateTime.day,
-                                curDateTime.hour, curDateTime.min, curDateTime.sec))
-            return DRM_FAILURE;
-
-        YMD_HMS_2_INT(curDateTime.year, curDateTime.month, curDateTime.day,
-                      CurrentTime.date, curDateTime.hour, curDateTime.min,
-                      curDateTime.sec, CurrentTime.time);
-    }
-
-    if (0 != (uint8_t)(XXConstraint->Indicator & DRM_COUNT_CONSTRAINT)) { /* Have count restrict? */
-        *writeFlag = 1;
-        /* If it has only one time for use, after use this function, we will delete this rights */
-        if (XXConstraint->Count <= 0) {
-            XXConstraint->Indicator &= ~DRM_COUNT_CONSTRAINT;
-            return DRM_RIGHTS_EXPIRED;
-        }
-
-        if (XXConstraint->Count-- <= 1) {
-            XXConstraint->Indicator &= ~DRM_COUNT_CONSTRAINT;
-            countFlag = 1;
-        }
-    }
-
-    if (0 != (uint8_t)(XXConstraint->Indicator & DRM_START_TIME_CONSTRAINT)) {
-        if (XXConstraint->StartTime.date > CurrentTime.date ||
-            (XXConstraint->StartTime.date == CurrentTime.date &&
-             XXConstraint->StartTime.time >= CurrentTime.time)) {
-            *bIsXXable = 1;
-            return DRM_RIGHTS_PENDING;
-        }
-    }
-
-    if (0 != (uint8_t)(XXConstraint->Indicator & DRM_END_TIME_CONSTRAINT)) { /* Have end time restrict? */
-        if (XXConstraint->EndTime.date < CurrentTime.date ||
-            (XXConstraint->EndTime.date == CurrentTime.date &&
-             XXConstraint->EndTime.time <= CurrentTime.time)) {
-            *writeFlag = 1;
-            XXConstraint->Indicator &= ~DRM_END_TIME_CONSTRAINT;
-            return DRM_RIGHTS_EXPIRED;
-        }
-    }
-
-    if (0 != (uint8_t)(XXConstraint->Indicator & DRM_INTERVAL_CONSTRAINT)) { /* Have interval time restrict? */
-        int32_t year, mon, day, hour, min, sec, date, time;
-        int32_t ret;
-
-        XXConstraint->Indicator |= DRM_END_TIME_CONSTRAINT;
-        XXConstraint->Indicator &= ~DRM_INTERVAL_CONSTRAINT; /* Write off interval right */
-        *writeFlag = 1;
-
-        if (XXConstraint->Interval.date == 0
-            && XXConstraint->Interval.time == 0) {
-            return DRM_RIGHTS_EXPIRED;
-        }
-        date = CurrentTime.date + XXConstraint->Interval.date;
-        time = CurrentTime.time + XXConstraint->Interval.time;
-        INT_2_YMD_HMS(year, mon, day, date, hour, min, sec, time);
-
-        if (sec > 59) {
-            min += sec / 60;
-            sec %= 60;
-        }
-        if (min > 59) {
-            hour += min / 60;
-            min %= 60;
-        }
-        if (hour > 23) {
-            day += hour / 24;
-            hour %= 24;
-        }
-        if (day > 31) {
-            mon += day / 31;
-            day %= 31;
-        }
-        if (mon > 12) {
-            year += mon / 12;
-            mon %= 12;
-        }
-        if (day > (ret = drm_monthDays(year, mon))) {
-            day -= ret;
-            mon++;
-            if (mon > 12) {
-                mon -= 12;
-                year++;
-            }
-        }
-        YMD_HMS_2_INT(year, mon, day, XXConstraint->EndTime.date, hour,
-                      min, sec, XXConstraint->EndTime.time);
-    }
-
-    if (1 != countFlag)
-        *bIsXXable = 1; /* Can go here ,so  right must be valid */
-    return DRM_SUCCESS;
-}
-
-static int32_t drm_startCheckRights(int32_t * bIsXXable,
-                                    T_DRM_Rights_Constraint * XXConstraint)
-{
-    T_DB_TIME_SysTime curDateTime;
-    T_DRM_DATETIME CurrentTime;
-
-    memset(&CurrentTime, 0, sizeof(T_DRM_DATETIME));
-
-    if (NULL == bIsXXable || 0 == *bIsXXable || NULL == XXConstraint)
-        return DRM_FAILURE;
-
-    if (0 != (uint8_t)(XXConstraint->Indicator & DRM_NO_CONSTRAINT)) /* Have utter right? */
-        return DRM_SUCCESS;
-
-    *bIsXXable = 0; /* Assume have invalid rights at first */
-
-    if (0 != (XXConstraint->Indicator & (DRM_START_TIME_CONSTRAINT | DRM_END_TIME_CONSTRAINT))) {
-        DRM_time_getSysTime(&curDateTime);
-
-        if (-1 == drm_checkDate(curDateTime.year, curDateTime.month, curDateTime.day,
-                                curDateTime.hour, curDateTime.min, curDateTime.sec))
-            return DRM_FAILURE;
-
-        YMD_HMS_2_INT(curDateTime.year, curDateTime.month, curDateTime.day,
-                      CurrentTime.date, curDateTime.hour, curDateTime.min,
-                      curDateTime.sec, CurrentTime.time);
-    }
-
-    if (0 != (uint8_t)(XXConstraint->Indicator & DRM_COUNT_CONSTRAINT)) { /* Have count restrict? */
-        if (XXConstraint->Count <= 0) {
-            XXConstraint->Indicator &= ~DRM_COUNT_CONSTRAINT;
-            return DRM_RIGHTS_EXPIRED;
-        }
-    }
-
-    if (0 != (uint8_t)(XXConstraint->Indicator & DRM_START_TIME_CONSTRAINT)) {
-        if (XXConstraint->StartTime.date > CurrentTime.date ||
-            (XXConstraint->StartTime.date == CurrentTime.date &&
-             XXConstraint->StartTime.time >= CurrentTime.time)) {
-            *bIsXXable = 1;
-            return DRM_RIGHTS_PENDING;
-        }
-    }
-
-    if (0 != (uint8_t)(XXConstraint->Indicator & DRM_END_TIME_CONSTRAINT)) { /* Have end time restrict? */
-        if (XXConstraint->EndTime.date < CurrentTime.date ||
-            (XXConstraint->EndTime.date == CurrentTime.date &&
-             XXConstraint->EndTime.time <= CurrentTime.time)) {
-            XXConstraint->Indicator &= ~DRM_END_TIME_CONSTRAINT;
-            return DRM_RIGHTS_EXPIRED;
-        }
-    }
-
-    if (0 != (uint8_t)(XXConstraint->Indicator & DRM_INTERVAL_CONSTRAINT)) { /* Have interval time restrict? */
-        if (XXConstraint->Interval.date == 0 && XXConstraint->Interval.time == 0) {
-            XXConstraint->Indicator &= ~DRM_INTERVAL_CONSTRAINT;
-            return DRM_RIGHTS_EXPIRED;
-        }
-    }
-
-    *bIsXXable = 1;
-    return DRM_SUCCESS;
-}
-
-int32_t drm_checkRoAndUpdate(int32_t id, int32_t permission)
-{
-    int32_t writeFlag = 0;
-    int32_t roAmount;
-    int32_t validRoAmount = 0;
-    int32_t flag = DRM_FAILURE;
-    int32_t i, j;
-    T_DRM_Rights *pRo;
-    T_DRM_Rights *pCurRo;
-    int32_t * pNumOfPriority;
-    int32_t iNum;
-    T_DRM_Rights_Constraint * pCurConstraint;
-    T_DRM_Rights_Constraint * pCompareConstraint;
-    int priority[8] = {1, 2, 4, 3, 8, 6, 7, 5};
-
-    if (FALSE == drm_writeOrReadInfo(id, NULL, &roAmount, GET_ROAMOUNT))
-        return DRM_FAILURE;
-
-    validRoAmount = roAmount;
-    if (roAmount < 1)
-        return DRM_NO_RIGHTS;
-
-    pRo = malloc(roAmount * sizeof(T_DRM_Rights));
-    pCurRo = pRo;
-    if (NULL == pRo)
-        return DRM_FAILURE;
-
-    if (FALSE == drm_writeOrReadInfo(id, pRo, &roAmount, GET_ALL_RO)) {
-        free(pRo);
-        return DRM_FAILURE;
-    }
-
-    /** check the right priority */
-    pNumOfPriority = malloc(sizeof(int32_t) * roAmount);
-    for(i = 0; i < roAmount; i++) {
-        iNum = roAmount - 1;
-        for(j = 0; j < roAmount; j++) {
-            if(i == j)
-                continue;
-            switch(permission) {
-            case DRM_PERMISSION_PLAY:
-                pCurConstraint = &pRo[i].PlayConstraint;
-                pCompareConstraint = &pRo[j].PlayConstraint;
-                break;
-            case DRM_PERMISSION_DISPLAY:
-                pCurConstraint = &pRo[i].DisplayConstraint;
-                pCompareConstraint = &pRo[j].DisplayConstraint;
-                break;
-            case DRM_PERMISSION_EXECUTE:
-                pCurConstraint = &pRo[i].ExecuteConstraint;
-                pCompareConstraint = &pRo[j].ExecuteConstraint;
-                break;
-            case DRM_PERMISSION_PRINT:
-                pCurConstraint = &pRo[i].PrintConstraint;
-                pCompareConstraint = &pRo[j].PrintConstraint;
-                break;
-            default:
-                free(pRo);
-                free(pNumOfPriority);
-                return DRM_FAILURE;
-            }
-
-            /**get priority by Indicator*/
-            if(0 == (pCurConstraint->Indicator & DRM_NO_CONSTRAINT) &&
-                0 == (pCompareConstraint->Indicator & DRM_NO_CONSTRAINT)) {
-                    int num1, num2;
-                    num1 = (pCurConstraint->Indicator & 0x0e) >> 1;
-                    num2 = (pCompareConstraint->Indicator & 0x0e) >> 1;
-                    if(priority[num1] > priority[num2]) {
-                        iNum--;
-                        continue;
-                    } else if(priority[pCurConstraint->Indicator] < priority[pCompareConstraint->Indicator])
-                        continue;
-            } else if(pCurConstraint->Indicator > pCompareConstraint->Indicator) {
-                iNum--;
-                continue;
-            } else if(pCurConstraint->Indicator < pCompareConstraint->Indicator)
-                continue;
-
-            if(0 != (pCurConstraint->Indicator & DRM_END_TIME_CONSTRAINT)) {
-                if(pCurConstraint->EndTime.date < pCompareConstraint->EndTime.date) {
-                    iNum--;
-                    continue;
-                } else if(pCurConstraint->EndTime.date > pCompareConstraint->EndTime.date)
-                    continue;
-
-                if(pCurConstraint->EndTime.time < pCompareConstraint->EndTime.time) {
-                    iNum--;
-                    continue;
-                } else if(pCurConstraint->EndTime.date > pCompareConstraint->EndTime.date)
-                    continue;
-            }
-
-            if(0 != (pCurConstraint->Indicator & DRM_INTERVAL_CONSTRAINT)) {
-                if(pCurConstraint->Interval.date < pCompareConstraint->Interval.date) {
-                    iNum--;
-                    continue;
-                } else if(pCurConstraint->Interval.date > pCompareConstraint->Interval.date)
-                    continue;
-
-                if(pCurConstraint->Interval.time < pCompareConstraint->Interval.time) {
-                    iNum--;
-                    continue;
-                } else if(pCurConstraint->Interval.time > pCompareConstraint->Interval.time)
-                    continue;
-            }
-
-            if(0 != (pCurConstraint->Indicator & DRM_COUNT_CONSTRAINT)) {
-                if(pCurConstraint->Count < pCompareConstraint->Count) {
-                    iNum--;
-                    continue;
-                } else if(pCurConstraint->Count > pCompareConstraint->Count)
-                    continue;
-            }
-
-            if(i < j)
-                iNum--;
-        }
-        pNumOfPriority[iNum] = i;
-    }
-
-    for (i = 0; i < validRoAmount; i++) {
-        /** check the right priority */
-        if (pNumOfPriority[i] >= validRoAmount)
-            break;
-
-        pCurRo = pRo + pNumOfPriority[i];
-
-        switch (permission) {
-        case DRM_PERMISSION_PLAY:
-            flag =
-                drm_startConsumeRights(&pCurRo->bIsPlayable,
-                                       &pCurRo->PlayConstraint, &writeFlag);
-            break;
-        case DRM_PERMISSION_DISPLAY:
-            flag =
-                drm_startConsumeRights(&pCurRo->bIsDisplayable,
-                                       &pCurRo->DisplayConstraint,
-                                       &writeFlag);
-            break;
-        case DRM_PERMISSION_EXECUTE:
-            flag =
-                drm_startConsumeRights(&pCurRo->bIsExecuteable,
-                                       &pCurRo->ExecuteConstraint,
-                                       &writeFlag);
-            break;
-        case DRM_PERMISSION_PRINT:
-            flag =
-                drm_startConsumeRights(&pCurRo->bIsPrintable,
-                                       &pCurRo->PrintConstraint, &writeFlag);
-            break;
-        default:
-            free(pNumOfPriority);
-            free(pRo);
-            return DRM_FAILURE;
-        }
-
-        /* Here confirm the valid RO amount and set the writeFlag */
-        if (0 == pCurRo->bIsPlayable && 0 == pCurRo->bIsDisplayable &&
-            0 == pCurRo->bIsExecuteable && 0 == pCurRo->bIsPrintable) {
-            int32_t iCurPri;
-
-            /** refresh the right priority */
-            iCurPri = pNumOfPriority[i];
-            for(j = i; j < validRoAmount - 1; j++)
-                pNumOfPriority[j] = pNumOfPriority[j + 1];
-
-            if(iCurPri != validRoAmount - 1) {
-                memcpy(pCurRo, pRo + validRoAmount - 1,
-                    sizeof(T_DRM_Rights));
-                for(j = 0; j < validRoAmount -1; j++) {
-                    if(validRoAmount - 1 == pNumOfPriority[j])
-                        pNumOfPriority[j] = iCurPri;
-                }
-            }
-
-            /* Here means it is not the last one RO, so the invalid RO should be deleted */
-            writeFlag = 1;
-            validRoAmount--; /* If current right is invalid */
-            i--;
-        }
-
-        /* If the flag is TRUE, this means: we have found a valid RO, so break, no need to check other RO */
-        if (DRM_SUCCESS == flag)
-            break;
-    }
-
-    if (1 == writeFlag) {
-        /* Delete the *.info first */
-        //drm_removeIdInfoFile(id);
-
-        if (FALSE == drm_writeOrReadInfo(id, pRo, &validRoAmount, SAVE_ALL_RO))
-            flag = DRM_FAILURE;
-    }
-
-    free(pNumOfPriority);
-    free(pRo);
-    return flag;
-}
-
-
-/* see svc_drm.h */
-int32_t SVC_drm_installRights(T_DRM_Input_Data data, T_DRM_Rights_Info* pRightsInfo)
-{
-    uint8_t *buf;
-    int32_t dataLen, bufLen;
-    T_DRM_Rights rights;
-
-    if (0 == data.inputHandle)
-        return DRM_RIGHTS_DATA_INVALID;
-
-    /* Get input rights data length */
-    dataLen = data.getInputDataLength(data.inputHandle);
-    if (dataLen <= 0)
-        return DRM_RIGHTS_DATA_INVALID;
-
-    /* Check if the length is larger than DRM max malloc length */
-    if (dataLen > DRM_MAX_MALLOC_LEN)
-        bufLen = DRM_MAX_MALLOC_LEN;
-    else
-        bufLen = dataLen;
-
-    buf = (uint8_t *)malloc(bufLen);
-    if (NULL == buf)
-        return DRM_FAILURE;
-
-    /* Read input data to buffer */
-    if (0 >= data.readInputData(data.inputHandle, buf, bufLen)) {
-        free(buf);
-        return DRM_RIGHTS_DATA_INVALID;
-    }
-
-    /* if the input mime type is unknown, DRM engine will try to recognize it. */
-    if (TYPE_DRM_UNKNOWN == data.mimeType)
-        data.mimeType = getMimeType(buf, bufLen);
-
-    switch(data.mimeType) {
-    case TYPE_DRM_MESSAGE: /* in case of Combined Delivery, extract the rights part to install */
-        {
-            T_DRM_DM_Info dmInfo;
-
-            memset(&dmInfo, 0, sizeof(T_DRM_DM_Info));
-            if (FALSE == drm_parseDM(buf, bufLen, &dmInfo)) {
-                free(buf);
-                return DRM_RIGHTS_DATA_INVALID;
-            }
-
-            /* if it is not Combined Delivery, it can not use to "SVC_drm_installRights" */
-            if (COMBINED_DELIVERY != dmInfo.deliveryType || dmInfo.rightsOffset <= 0 || dmInfo.rightsLen <= 0) {
-                free(buf);
-                return DRM_RIGHTS_DATA_INVALID;
-            }
-
-            memset(&rights, 0, sizeof(T_DRM_Rights));
-            if (FALSE == drm_relParser(buf + dmInfo.rightsOffset, dmInfo.rightsLen, TYPE_DRM_RIGHTS_XML, &rights)) {
-                free(buf);
-                return DRM_RIGHTS_DATA_INVALID;
-            }
-        }
-        break;
-    case TYPE_DRM_RIGHTS_XML:
-    case TYPE_DRM_RIGHTS_WBXML:
-        memset(&rights, 0, sizeof(T_DRM_Rights));
-        if (FALSE == drm_relParser(buf, bufLen, data.mimeType, &rights)) {
-            free(buf);
-            return DRM_RIGHTS_DATA_INVALID;
-        }
-        break;
-    case TYPE_DRM_CONTENT: /* DCF should not using "SVC_drm_installRights", it should be used to open a session. */
-    case TYPE_DRM_UNKNOWN:
-    default:
-        free(buf);
-        return DRM_MEDIA_DATA_INVALID;
-    }
-
-    free(buf);
-
-    /* append the rights information to DRM engine storage */
-    if (FALSE == drm_appendRightsInfo(&rights))
-        return DRM_FAILURE;
-
-    memset(pRightsInfo, 0, sizeof(T_DRM_Rights_Info));
-    drm_getLicenseInfo(&rights, pRightsInfo);
-
-    return DRM_SUCCESS;
-}
-
-/* see svc_drm.h */
-int32_t SVC_drm_openSession(T_DRM_Input_Data data)
-{
-    int32_t session;
-    int32_t dataLen;
-    T_DRM_Session_Node* s;
-
-    if (0 == data.inputHandle)
-        return DRM_MEDIA_DATA_INVALID;
-
-    /* Get input data length */
-    dataLen = data.getInputDataLength(data.inputHandle);
-    if (dataLen <= 0)
-        return DRM_MEDIA_DATA_INVALID;
-
-    s = newSession(data);
-    if (NULL == s)
-        return DRM_FAILURE;
-
-    /* Check if the length is larger than DRM max malloc length */
-    if (dataLen > DRM_MAX_MALLOC_LEN)
-        s->rawContentLen = DRM_MAX_MALLOC_LEN;
-    else
-        s->rawContentLen = dataLen;
-
-    s->rawContent = (uint8_t *)malloc(s->rawContentLen);
-    if (NULL == s->rawContent)
-        return DRM_FAILURE;
-
-    /* Read input data to buffer */
-    if (0 >= data.readInputData(data.inputHandle, s->rawContent, s->rawContentLen)) {
-        freeSession(s);
-        return DRM_MEDIA_DATA_INVALID;
-    }
-
-    /* if the input mime type is unknown, DRM engine will try to recognize it. */
-    if (TYPE_DRM_UNKNOWN == data.mimeType)
-        data.mimeType = getMimeType(s->rawContent, s->rawContentLen);
-
-    switch(data.mimeType) {
-    case TYPE_DRM_MESSAGE:
-        {
-            T_DRM_DM_Info dmInfo;
-
-            memset(&dmInfo, 0, sizeof(T_DRM_DM_Info));
-            if (FALSE == drm_parseDM(s->rawContent, s->rawContentLen, &dmInfo)) {
-                freeSession(s);
-                return DRM_MEDIA_DATA_INVALID;
-            }
-
-            s->deliveryMethod = dmInfo.deliveryType;
-
-            if (SEPARATE_DELIVERY_FL == s->deliveryMethod)
-                s->contentLength = DRM_UNKNOWN_DATA_LEN;
-            else
-                s->contentLength = dmInfo.contentLen;
-
-            s->transferEncoding = dmInfo.transferEncoding;
-            s->contentOffset = dmInfo.contentOffset;
-            s->bEndData = FALSE;
-            strcpy((char *)s->contentType, (char *)dmInfo.contentType);
-            strcpy((char *)s->contentID, (char *)dmInfo.contentID);
-
-            if (SEPARATE_DELIVERY_FL == s->deliveryMethod) {
-                s->infoStruct = (T_DRM_Dcf_Node *)malloc(sizeof(T_DRM_Dcf_Node));
-                if (NULL == s->infoStruct)
-                    return DRM_FAILURE;
-                memset(s->infoStruct, 0, sizeof(T_DRM_Dcf_Node));
-
-                ((T_DRM_Dcf_Node *)(s->infoStruct))->encContentLength = dmInfo.contentLen;
-                strcpy((char *)((T_DRM_Dcf_Node *)(s->infoStruct))->rightsIssuer, (char *)dmInfo.rightsIssuer);
-                break;
-            }
-
-            if (DRM_MESSAGE_CODING_BASE64 == s->transferEncoding) {
-                s->infoStruct = (T_DRM_DM_Base64_Node *)malloc(sizeof(T_DRM_DM_Base64_Node));
-                if (NULL == s->infoStruct)
-                    return DRM_FAILURE;
-                memset(s->infoStruct, 0, sizeof(T_DRM_DM_Base64_Node));
-
-                strcpy((char *)((T_DRM_DM_Base64_Node *)(s->infoStruct))->boundary, (char *)dmInfo.boundary);
-            } else {
-                s->infoStruct = (T_DRM_DM_Binary_Node *)malloc(sizeof(T_DRM_DM_Binary_Node));
-                if (NULL == s->infoStruct)
-                    return DRM_FAILURE;
-                memset(s->infoStruct, 0, sizeof(T_DRM_DM_Binary_Node));
-
-                strcpy((char *)((T_DRM_DM_Binary_Node *)(s->infoStruct))->boundary, (char *)dmInfo.boundary);
-            }
-
-
-            if (DRM_MESSAGE_CODING_BASE64 == s->transferEncoding) {
-                if (s->contentLength > 0) {
-                    int32_t encLen, decLen;
-
-                    encLen = s->contentLength;
-                    decLen = encLen / DRM_B64_ENC_BLOCK * DRM_B64_DEC_BLOCK;
-
-                    decLen = drm_decodeBase64(s->rawContent, decLen, s->rawContent + s->contentOffset, &encLen);
-                    s->contentLength = decLen;
-                } else {
-                    int32_t encLen = DRM_MAX_MALLOC_LEN - s->contentOffset, decLen;
-                    int32_t skipLen, needBytes, i;
-                    uint8_t *pStart;
-                    int32_t res, bFoundBoundary = FALSE;
-
-                    pStart = s->rawContent + s->contentOffset;
-                    if (-1 == (skipLen = drm_skipCRLFinB64(pStart, encLen))) {
-                        freeSession(s);
-                        return DRM_FAILURE;
-                    }
-
-                    needBytes = DRM_B64_ENC_BLOCK - ((encLen - skipLen) % DRM_B64_ENC_BLOCK);
-                    if (needBytes < DRM_B64_ENC_BLOCK) {
-                        s->rawContent = (uint8_t *)realloc(s->rawContent, DRM_MAX_MALLOC_LEN + needBytes);
-                        if (NULL == s->rawContent) {
-                            freeSession(s);
-                            return DRM_FAILURE;
-                        }
-
-                        i = 0;
-                        while (i < needBytes) {
-                            if (-1 != data.readInputData(data.inputHandle, s->rawContent + DRM_MAX_MALLOC_LEN + i, 1)) {
-                                if ('\r' == *(s->rawContent + DRM_MAX_MALLOC_LEN + i) || '\n' == *(s->rawContent + DRM_MAX_MALLOC_LEN + i))
-                                    continue;
-                                i++;
-                            } else
-                                break;
-                        }
-                        encLen += i;
-                    }
-
-                    res = drm_scanEndBoundary(pStart, encLen, ((T_DRM_DM_Base64_Node *)(s->infoStruct))->boundary);
-                    if (-1 == res) {
-                        freeSession(s);
-                        return DRM_FAILURE;
-                    }
-                    if (-2 == res) { /* may be there is a boundary */
-                        int32_t boundaryLen, leftLen, readBytes;
-                        char* pTmp = memrchr(pStart, '\r', encLen);
-
-                        if (NULL == pTmp) {
-                            freeSession(s);
-                            return DRM_FAILURE; /* conflict */
-                        }
-                        boundaryLen = strlen((char *)((T_DRM_DM_Base64_Node *)(s->infoStruct))->boundary) + 2; /* 2 means: '\r''\n' */
-                        s->readBuf = (uint8_t *)malloc(boundaryLen);
-                        if (NULL == s->readBuf) {
-                            freeSession(s);
-                            return DRM_FAILURE;
-                        }
-                        s->readBufOff = encLen - ((uint8_t *)pTmp - pStart);
-                        s->readBufLen = boundaryLen - s->readBufOff;
-                        memcpy(s->readBuf, pTmp, s->readBufOff);
-                        readBytes = data.readInputData(data.inputHandle, s->readBuf + s->readBufOff, s->readBufLen);
-                        if (-1 == readBytes || readBytes < s->readBufLen) {
-                            freeSession(s);
-                            return DRM_MEDIA_DATA_INVALID;
-                        }
-
-                        if (0 == drm_scanEndBoundary(s->readBuf, boundaryLen, ((T_DRM_DM_Base64_Node *)(s->infoStruct))->boundary)) {
-                            encLen = (uint8_t *)pTmp - pStart; /* yes, it is the end boundary */
-                            bFoundBoundary = TRUE;
-                        }
-                    } else {
-                        if (res >= 0 && res < encLen) {
-                            encLen = res;
-                            bFoundBoundary = TRUE;
-                        }
-                    }
-
-                    decLen = encLen / DRM_B64_ENC_BLOCK * DRM_B64_DEC_BLOCK;
-                    decLen = drm_decodeBase64(s->rawContent, decLen, s->rawContent + s->contentOffset, &encLen);
-                    ((T_DRM_DM_Base64_Node *)(s->infoStruct))->b64DecodeDataLen = decLen;
-                    if (bFoundBoundary)
-                        s->contentLength = decLen;
-                }
-            } else {
-                /* binary data */
-                if (DRM_UNKNOWN_DATA_LEN == s->contentLength) {
-                    /* try to check whether there is boundary may be split */
-                    int32_t res, binContentLen;
-                    uint8_t* pStart;
-                    int32_t bFoundBoundary = FALSE;
-
-                    pStart = s->rawContent + s->contentOffset;
-                    binContentLen = s->rawContentLen - s->contentOffset;
-                    res = drm_scanEndBoundary(pStart, binContentLen, ((T_DRM_DM_Binary_Node *)(s->infoStruct))->boundary);
-
-                    if (-1 == res) {
-                        freeSession(s);
-                        return DRM_FAILURE;
-                    }
-
-                    if (-2 == res) { /* may be the boundary is split */
-                        int32_t boundaryLen, leftLen, readBytes;
-                        char* pTmp = memrchr(pStart, '\r', binContentLen);
-
-                        if (NULL == pTmp) {
-                            freeSession(s);
-                            return DRM_FAILURE; /* conflict */
-                        }
-
-                        boundaryLen = strlen((char *)((T_DRM_DM_Binary_Node *)(s->infoStruct))->boundary) + 2; /* 2 means: '\r''\n' */
-                        s->readBuf = (uint8_t *)malloc(boundaryLen);
-                        if (NULL == s->readBuf) {
-                            freeSession(s);
-                            return DRM_FAILURE;
-                        }
-                        s->readBufOff = binContentLen - ((uint8_t *)pTmp - pStart);
-                        s->readBufLen = boundaryLen - s->readBufOff;
-                        memcpy(s->readBuf, pTmp, s->readBufOff);
-                        readBytes = data.readInputData(data.inputHandle, s->readBuf + s->readBufOff, s->readBufLen);
-                        if (-1 == readBytes || readBytes < s->readBufLen) {
-                            freeSession(s);
-                            return DRM_MEDIA_DATA_INVALID;
-                        }
-
-                        if (0 == drm_scanEndBoundary(s->readBuf, boundaryLen, ((T_DRM_DM_Binary_Node *)(s->infoStruct))->boundary)) {
-                            binContentLen = (uint8_t *)pTmp - pStart; /* yes, it is the end boundary */
-                            bFoundBoundary = TRUE;
-                        }
-                    } else {
-                        if (res >= 0 && res < binContentLen) {
-                            binContentLen = res;
-                            bFoundBoundary = TRUE;
-                        }
-                    }
-
-                    if (bFoundBoundary)
-                        s->contentLength = binContentLen;
-                }
-            }
-        }
-        break;
-    case TYPE_DRM_CONTENT:
-        {
-            T_DRM_DCF_Info dcfInfo;
-            uint8_t* pEncData = NULL;
-
-            memset(&dcfInfo, 0, sizeof(T_DRM_DCF_Info));
-            if (FALSE == drm_dcfParser(s->rawContent, s->rawContentLen, &dcfInfo, &pEncData)) {
-                freeSession(s);
-                return DRM_MEDIA_DATA_INVALID;
-            }
-
-            s->infoStruct = (T_DRM_Dcf_Node *)malloc(sizeof(T_DRM_Dcf_Node));
-            if (NULL == s->infoStruct)
-                return DRM_FAILURE;
-            memset(s->infoStruct, 0, sizeof(T_DRM_Dcf_Node));
-
-            s->deliveryMethod = SEPARATE_DELIVERY;
-            s->contentLength = dcfInfo.DecryptedDataLen;
-            ((T_DRM_Dcf_Node *)(s->infoStruct))->encContentLength = dcfInfo.EncryptedDataLen;
-            s->contentOffset = pEncData - s->rawContent;
-            strcpy((char *)s->contentType, (char *)dcfInfo.ContentType);
-            strcpy((char *)s->contentID, (char *)dcfInfo.ContentURI);
-            strcpy((char *)((T_DRM_Dcf_Node *)(s->infoStruct))->rightsIssuer, (char *)dcfInfo.Rights_Issuer);
-        }
-        break;
-    case TYPE_DRM_RIGHTS_XML:   /* rights object should using "SVC_drm_installRights", it can not open a session */
-    case TYPE_DRM_RIGHTS_WBXML: /* rights object should using "SVC_drm_installRights", it can not open a session */
-    case TYPE_DRM_UNKNOWN:
-    default:
-        freeSession(s);
-        return DRM_MEDIA_DATA_INVALID;
-    }
-
-    if ((SEPARATE_DELIVERY_FL == s->deliveryMethod || SEPARATE_DELIVERY == s->deliveryMethod) &&
-        s->contentOffset + ((T_DRM_Dcf_Node *)(s->infoStruct))->encContentLength <= DRM_MAX_MALLOC_LEN) {
-        uint8_t keyValue[DRM_KEY_LEN];
-        uint8_t lastDcfBuf[DRM_TWO_AES_BLOCK_LEN];
-        int32_t seekPos, moreBytes;
-
-        if (TRUE == drm_getKey(s->contentID, keyValue)) {
-            seekPos = s->contentOffset + ((T_DRM_Dcf_Node *)(s->infoStruct))->encContentLength - DRM_TWO_AES_BLOCK_LEN;
-            memcpy(lastDcfBuf, s->rawContent + seekPos, DRM_TWO_AES_BLOCK_LEN);
-
-            if (TRUE == drm_updateDcfDataLen(lastDcfBuf, keyValue, &moreBytes)) {
-                s->contentLength = ((T_DRM_Dcf_Node *)(s->infoStruct))->encContentLength;
-                s->contentLength -= moreBytes;
-            }
-        }
-    }
-
-    session = addSession(s);
-    if (-1 == session)
-        return DRM_FAILURE;
-
-    return session;
-}
-
-/* see svc_drm.h */
-int32_t SVC_drm_getDeliveryMethod(int32_t session)
-{
-    T_DRM_Session_Node* s;
-
-    if (session < 0)
-        return DRM_FAILURE;
-
-    s = getSession(session);
-    if (NULL == s)
-        return DRM_SESSION_NOT_OPENED;
-
-    return s->deliveryMethod;
-}
-
-/* see svc_drm.h */
-int32_t SVC_drm_getContentType(int32_t session, uint8_t* mediaType)
-{
-    T_DRM_Session_Node* s;
-
-    if (session < 0 || NULL == mediaType)
-        return DRM_FAILURE;
-
-    s = getSession(session);
-    if (NULL == s)
-        return DRM_SESSION_NOT_OPENED;
-
-    strcpy((char *)mediaType, (char *)s->contentType);
-
-    return DRM_SUCCESS;
-}
-
-/* see svc_drm.h */
-int32_t SVC_drm_checkRights(int32_t session, int32_t permission)
-{
-    T_DRM_Session_Node* s;
-    int32_t id;
-    T_DRM_Rights *pRo, *pCurRo;
-    int32_t roAmount;
-    int32_t i;
-    int32_t res = DRM_FAILURE;
-
-    if (session < 0)
-        return DRM_FAILURE;
-
-    s = getSession(session);
-    if (NULL == s)
-        return DRM_SESSION_NOT_OPENED;
-
-    /* if it is Forward-Lock cases, check it and return directly */
-    if (FORWARD_LOCK == s->deliveryMethod) {
-        if (DRM_PERMISSION_PLAY == permission ||
-            DRM_PERMISSION_DISPLAY == permission ||
-            DRM_PERMISSION_EXECUTE == permission ||
-            DRM_PERMISSION_PRINT == permission)
-            return DRM_SUCCESS;
-
-        return DRM_FAILURE;
-    }
-
-    /* if try to forward, only DCF can be forwarded */
-    if (DRM_PERMISSION_FORWARD == permission) {
-        if (SEPARATE_DELIVERY == s->deliveryMethod)
-            return DRM_SUCCESS;
-
-        return DRM_FAILURE;
-    }
-
-    /* The following will check CD or SD other permissions */
-    if (FALSE == drm_readFromUidTxt(s->contentID, &id, GET_ID))
-        return DRM_FAILURE;
-
-    drm_writeOrReadInfo(id, NULL, &roAmount, GET_ROAMOUNT);
-    if (roAmount <= 0)
-        return DRM_FAILURE;
-
-    pRo = malloc(roAmount * sizeof(T_DRM_Rights));
-    if (NULL == pRo)
-        return DRM_FAILURE;
-
-    drm_writeOrReadInfo(id, pRo, &roAmount, GET_ALL_RO);
-
-    pCurRo = pRo;
-    for (i = 0; i < roAmount; i++) {
-        switch (permission) {
-        case DRM_PERMISSION_PLAY:
-            res = drm_startCheckRights(&(pCurRo->bIsPlayable), &(pCurRo->PlayConstraint));
-            break;
-        case DRM_PERMISSION_DISPLAY:
-            res = drm_startCheckRights(&(pCurRo->bIsDisplayable), &(pCurRo->DisplayConstraint));
-            break;
-        case DRM_PERMISSION_EXECUTE:
-            res = drm_startCheckRights(&(pCurRo->bIsExecuteable), &(pCurRo->ExecuteConstraint));
-            break;
-        case DRM_PERMISSION_PRINT:
-            res = drm_startCheckRights(&(pCurRo->bIsPrintable), &(pCurRo->PrintConstraint));
-            break;
-        default:
-            free(pRo);
-            return DRM_FAILURE;
-        }
-
-        if (DRM_SUCCESS == res) {
-            free(pRo);
-            return DRM_SUCCESS;
-        }
-        pCurRo++;
-    }
-
-    free(pRo);
-    return res;
-}
-
-/* see svc_drm.h */
-int32_t SVC_drm_consumeRights(int32_t session, int32_t permission)
-{
-    T_DRM_Session_Node* s;
-    int32_t id;
-
-    if (session < 0)
-        return DRM_FAILURE;
-
-    s = getSession(session);
-    if (NULL == s)
-        return DRM_SESSION_NOT_OPENED;
-
-    if (DRM_PERMISSION_FORWARD == permission) {
-        if (SEPARATE_DELIVERY == s->deliveryMethod)
-            return DRM_SUCCESS;
-
-        return DRM_FAILURE;
-    }
-
-    if (FORWARD_LOCK == s->deliveryMethod) /* Forwardlock type have utter rights */
-        return DRM_SUCCESS;
-
-    if (FALSE == drm_readFromUidTxt(s->contentID, &id, GET_ID))
-        return DRM_FAILURE;
-
-    return drm_checkRoAndUpdate(id, permission);
-}
-
-/* see svc_drm.h */
-int32_t SVC_drm_getContentLength(int32_t session)
-{
-    T_DRM_Session_Node* s;
-
-    if (session < 0)
-        return DRM_FAILURE;
-
-    s = getSession(session);
-    if (NULL == s)
-        return DRM_SESSION_NOT_OPENED;
-
-    if (DRM_UNKNOWN_DATA_LEN == s->contentLength && s->contentOffset + ((T_DRM_Dcf_Node *)(s->infoStruct))->encContentLength <= DRM_MAX_MALLOC_LEN &&
-        (SEPARATE_DELIVERY == s->deliveryMethod || SEPARATE_DELIVERY_FL == s->deliveryMethod)) {
-        uint8_t keyValue[DRM_KEY_LEN];
-        uint8_t lastDcfBuf[DRM_TWO_AES_BLOCK_LEN];
-        int32_t seekPos, moreBytes;
-
-        if (TRUE == drm_getKey(s->contentID, keyValue)) {
-            seekPos = s->contentOffset + ((T_DRM_Dcf_Node *)(s->infoStruct))->encContentLength - DRM_TWO_AES_BLOCK_LEN;
-            memcpy(lastDcfBuf, s->rawContent + seekPos, DRM_TWO_AES_BLOCK_LEN);
-
-            if (TRUE == drm_updateDcfDataLen(lastDcfBuf, keyValue, &moreBytes)) {
-                s->contentLength = ((T_DRM_Dcf_Node *)(s->infoStruct))->encContentLength;
-                s->contentLength -= moreBytes;
-            }
-        }
-    }
-
-    return s->contentLength;
-}
-
-static int32_t drm_readAesData(uint8_t* buf, T_DRM_Session_Node* s, int32_t aesStart, int32_t bufLen)
-{
-    if (NULL == buf || NULL == s || aesStart < 0 || bufLen < 0)
-        return -1;
-
-    if (aesStart - s->contentOffset + bufLen > ((T_DRM_Dcf_Node *)(s->infoStruct))->encContentLength)
-        return -2;
-
-    if (aesStart < DRM_MAX_MALLOC_LEN) {
-        if (aesStart + bufLen <= DRM_MAX_MALLOC_LEN) { /* read from buffer */
-            memcpy(buf, s->rawContent + aesStart, bufLen);
-            return bufLen;
-        } else { /* first read from buffer and then from InputStream */
-            int32_t point = DRM_MAX_MALLOC_LEN - aesStart;
-            int32_t res;
-
-            if (((T_DRM_Dcf_Node *)(s->infoStruct))->bAesBackupBuf) {
-                memcpy(buf, ((T_DRM_Dcf_Node *)(s->infoStruct))->aesBackupBuf, DRM_ONE_AES_BLOCK_LEN);
-                res = s->readInputDataFunc(s->inputHandle, buf + DRM_ONE_AES_BLOCK_LEN, DRM_ONE_AES_BLOCK_LEN);
-                if (0 == res || -1 == res)
-                    return -1;
-
-                res += DRM_ONE_AES_BLOCK_LEN;
-            } else {
-                memcpy(buf, s->rawContent + aesStart, point);
-                res = s->readInputDataFunc(s->inputHandle, buf + point, bufLen - point);
-                if (0 == res || -1 == res)
-                    return -1;
-
-                res += point;
-            }
-
-            memcpy(((T_DRM_Dcf_Node *)(s->infoStruct))->aesBackupBuf, buf + DRM_ONE_AES_BLOCK_LEN, DRM_ONE_AES_BLOCK_LEN);
-            ((T_DRM_Dcf_Node *)(s->infoStruct))->bAesBackupBuf = TRUE;
-
-            return res;
-        }
-    } else { /* read from InputStream */
-        int32_t res;
-
-        memcpy(buf, ((T_DRM_Dcf_Node *)(s->infoStruct))->aesBackupBuf, DRM_ONE_AES_BLOCK_LEN);
-        res = s->readInputDataFunc(s->inputHandle, buf + DRM_ONE_AES_BLOCK_LEN, DRM_ONE_AES_BLOCK_LEN);
-
-        if (0 == res || -1 == res)
-            return -1;
-
-        memcpy(((T_DRM_Dcf_Node *)(s->infoStruct))->aesBackupBuf, buf + DRM_ONE_AES_BLOCK_LEN, DRM_ONE_AES_BLOCK_LEN);
-
-        return DRM_ONE_AES_BLOCK_LEN + res;
-    }
-}
-
-static int32_t drm_readContentFromBuf(T_DRM_Session_Node* s, int32_t offset, uint8_t* mediaBuf, int32_t mediaBufLen)
-{
-    int32_t readBytes;
-
-    if (offset > s->contentLength)
-        return DRM_FAILURE;
-
-    if (offset == s->contentLength)
-        return DRM_MEDIA_EOF;
-
-    if (offset + mediaBufLen > s->contentLength)
-        readBytes = s->contentLength - offset;
-    else
-        readBytes = mediaBufLen;
-
-    if (DRM_MESSAGE_CODING_BASE64 == s->transferEncoding)
-        memcpy(mediaBuf, s->rawContent + offset, readBytes);
-    else
-        memcpy(mediaBuf, s->rawContent + s->contentOffset + offset, readBytes);
-
-    return readBytes;
-}
-
-static int32_t drm_readB64ContentFromInputStream(T_DRM_Session_Node* s, int32_t offset, uint8_t* mediaBuf, int32_t mediaBufLen)
-{
-    uint8_t encBuf[DRM_B64_ENC_BLOCK], decBuf[DRM_B64_DEC_BLOCK];
-    int32_t encLen, decLen;
-    int32_t i, j, piece, leftLen, firstBytes;
-    int32_t readBytes = 0;
-
-    if (offset < ((T_DRM_DM_Base64_Node *)(s->infoStruct))->b64DecodeDataLen) {
-        readBytes = ((T_DRM_DM_Base64_Node *)(s->infoStruct))->b64DecodeDataLen - offset;
-        memcpy(mediaBuf, s->rawContent + offset, readBytes);
-    } else {
-        if (s->bEndData)
-            return DRM_MEDIA_EOF;
-
-        firstBytes = offset % DRM_B64_DEC_BLOCK;
-        if (firstBytes > 0) {
-            if (DRM_B64_DEC_BLOCK - firstBytes >= mediaBufLen) {
-                readBytes = mediaBufLen;
-                memcpy(mediaBuf, ((T_DRM_DM_Base64_Node *)(s->infoStruct))->b64DecodeData + firstBytes, readBytes);
-                return readBytes;
-            }
-
-            readBytes = DRM_B64_DEC_BLOCK - firstBytes;
-            memcpy(mediaBuf, ((T_DRM_DM_Base64_Node *)(s->infoStruct))->b64DecodeData + firstBytes, readBytes);
-        }
-    }
-
-    leftLen = mediaBufLen - readBytes;
-    encLen = (leftLen - 1) / DRM_B64_DEC_BLOCK * DRM_B64_ENC_BLOCK + DRM_B64_ENC_BLOCK;
-    piece = encLen / DRM_B64_ENC_BLOCK;
-
-    for (i = 0; i < piece; i++) {
-        j = 0;
-        while (j < DRM_B64_ENC_BLOCK) {
-            if (NULL != s->readBuf && s->readBufLen > 0) { /* read from backup buffer */
-                *(encBuf + j) = s->readBuf[s->readBufOff];
-                s->readBufOff++;
-                s->readBufLen--;
-            } else { /* read from InputStream */
-                if (0 == s->readInputDataFunc(s->inputHandle, encBuf + j, 1))
-                    return DRM_MEDIA_DATA_INVALID;
-            }
-
-            if ('\r' == *(encBuf + j) || '\n' == *(encBuf + j))
-                continue; /* skip CRLF */
-
-            if ('-' == *(encBuf + j)) {
-                int32_t k, len;
-
-                /* invalid base64 data, it comes to end boundary */
-                if (0 != j)
-                    return DRM_MEDIA_DATA_INVALID;
-
-                /* check whether it is really the boundary */
-                len = strlen((char *)((T_DRM_DM_Base64_Node *)(s->infoStruct))->boundary);
-                if (NULL == s->readBuf) {
-                    s->readBuf = (uint8_t *)malloc(len);
-                    if (NULL == s->readBuf)
-                        return DRM_FAILURE;
-                }
-
-                s->readBuf[0] = '-';
-                for (k = 0; k < len - 1; k++) {
-                    if (NULL != s->readBuf && s->readBufLen > 0) { /* read from backup buffer */
-                        *(s->readBuf + k + 1) = s->readBuf[s->readBufOff];
-                        s->readBufOff++;
-                        s->readBufLen--;
-                    } else { /* read from InputStream */
-                        if (-1 == s->readInputDataFunc(s->inputHandle, s->readBuf + k + 1, 1))
-                            return DRM_MEDIA_DATA_INVALID;
-                    }
-                }
-                if (0 == memcmp(s->readBuf, ((T_DRM_DM_Base64_Node *)(s->infoStruct))->boundary, len))
-                    s->bEndData = TRUE;
-                else
-                    return DRM_MEDIA_DATA_INVALID;
-
-                break;
-            }
-            j++;
-        }
-
-        if (TRUE == s->bEndData) { /* it means come to the end of base64 data */
-            if (0 == readBytes)
-                return DRM_MEDIA_EOF;
-
-            break;
-        }
-
-        encLen = DRM_B64_ENC_BLOCK;
-        decLen = DRM_B64_DEC_BLOCK;
-        if (-1 == (decLen = drm_decodeBase64(decBuf, decLen, encBuf, &encLen)))
-            return DRM_MEDIA_DATA_INVALID;
-
-        if (leftLen >= decLen) {
-            memcpy(mediaBuf + readBytes, decBuf, decLen);
-            readBytes += decLen;
-            leftLen -= decLen;
-        } else {
-            if (leftLen > 0) {
-                memcpy(mediaBuf + readBytes, decBuf, leftLen);
-                readBytes += leftLen;
-            }
-            break;
-        }
-    }
-    memcpy(((T_DRM_DM_Base64_Node *)(s->infoStruct))->b64DecodeData, decBuf, DRM_B64_DEC_BLOCK);
-
-    return readBytes;
-}
-
-static int32_t drm_readBase64Content(T_DRM_Session_Node* s, int32_t offset, uint8_t* mediaBuf, int32_t mediaBufLen)
-{
-    int32_t readBytes;
-
-    /* when the content length has been well-known */
-    if (s->contentLength >= 0)
-        readBytes = drm_readContentFromBuf(s, offset, mediaBuf, mediaBufLen);
-    else /* else when the content length has not been well-known yet */
-        if (offset < ((T_DRM_DM_Base64_Node *)(s->infoStruct))->b64DecodeDataLen)
-            if (offset + mediaBufLen <= ((T_DRM_DM_Base64_Node *)(s->infoStruct))->b64DecodeDataLen) {
-                readBytes = mediaBufLen;
-                memcpy(mediaBuf, s->rawContent + offset, readBytes);
-            } else
-                readBytes = drm_readB64ContentFromInputStream(s, offset, mediaBuf, mediaBufLen);
-        else
-            readBytes = drm_readB64ContentFromInputStream(s, offset, mediaBuf, mediaBufLen);
-
-    return readBytes;
-}
-
-static int32_t drm_readBinaryContentFromInputStream(T_DRM_Session_Node* s, int32_t offset, uint8_t* mediaBuf, int32_t mediaBufLen)
-{
-    int32_t res = 0, readBytes = 0;
-    int32_t leftLen;
-
-    if (s->contentOffset + offset < DRM_MAX_MALLOC_LEN) {
-        readBytes = DRM_MAX_MALLOC_LEN - s->contentOffset - offset;
-        memcpy(mediaBuf, s->rawContent + s->contentOffset + offset, readBytes);
-    } else
-        if (s->bEndData)
-            return DRM_MEDIA_EOF;
-
-    leftLen = mediaBufLen - readBytes;
-
-    if (NULL != s->readBuf && s->readBufLen > 0) { /* read from backup buffer */
-        if (leftLen <= s->readBufLen) {
-            memcpy(mediaBuf + readBytes, s->readBuf + s->readBufOff, leftLen);
-            s->readBufOff += leftLen;
-            s->readBufLen -= leftLen;
-            readBytes += leftLen;
-            leftLen = 0;
-        } else {
-            memcpy(mediaBuf + readBytes, s->readBuf + s->readBufOff, s->readBufLen);
-            s->readBufOff += s->readBufLen;
-            leftLen -= s->readBufLen;
-            readBytes += s->readBufLen;
-            s->readBufLen = 0;
-        }
-    }
-
-    if (leftLen > 0) {
-        res = s->readInputDataFunc(s->inputHandle, mediaBuf + readBytes, mediaBufLen - readBytes);
-        if (-1 == res)
-            return DRM_MEDIA_DATA_INVALID;
-    }
-
-    readBytes += res;
-    res = drm_scanEndBoundary(mediaBuf, readBytes, ((T_DRM_DM_Binary_Node *)(s->infoStruct))->boundary);
-    if (-1 == res)
-        return DRM_MEDIA_DATA_INVALID;
-    if (-2 == res) { /* may be the boundary is split */
-        int32_t boundaryLen, len, off, k;
-        char* pTmp = memrchr(mediaBuf, '\r', readBytes);
-
-        if (NULL == pTmp)
-            return DRM_FAILURE; /* conflict */
-
-        boundaryLen = strlen((char *)((T_DRM_DM_Binary_Node *)(s->infoStruct))->boundary) + 2; /* 2 means: '\r''\n' */
-        if (NULL == s->readBuf) {
-            s->readBuf = (uint8_t *)malloc(boundaryLen);
-            if (NULL == s->readBuf)
-                return DRM_FAILURE;
-        }
-
-        off = readBytes - ((uint8_t *)pTmp - mediaBuf);
-        len = boundaryLen - off;
-        memcpy(s->readBuf, pTmp, off);
-        for (k = 0; k < boundaryLen - off; k++) {
-            if (NULL != s->readBuf && s->readBufLen > 0) { /* read from backup buffer */
-                *(s->readBuf + k + off) = s->readBuf[s->readBufOff];
-                s->readBufOff++;
-                s->readBufLen--;
-            } else { /* read from InputStream */
-                if (-1 == s->readInputDataFunc(s->inputHandle, s->readBuf + k + off, 1))
-                    return DRM_MEDIA_DATA_INVALID;
-            }
-        }
-        s->readBufOff = off;
-        s->readBufLen = len;
-
-        if (0 == drm_scanEndBoundary(s->readBuf, boundaryLen, ((T_DRM_DM_Binary_Node *)(s->infoStruct))->boundary)) {
-            readBytes = (uint8_t *)pTmp - mediaBuf; /* yes, it is the end boundary */
-            s->bEndData = TRUE;
-        }
-    } else {
-        if (res >= 0 && res < readBytes) {
-            readBytes = res;
-            s->bEndData = TRUE;
-        }
-    }
-
-    if (s->bEndData) {
-        if (0 == readBytes)
-            return DRM_MEDIA_EOF;
-    }
-
-    return readBytes;
-}
-
-static int32_t drm_readBinaryContent(T_DRM_Session_Node* s, int32_t offset, uint8_t* mediaBuf, int32_t mediaBufLen)
-{
-    int32_t readBytes;
-
-    if (s->contentLength >= 0)
-        readBytes = drm_readContentFromBuf(s, offset, mediaBuf, mediaBufLen);
-    else /* else when the content length has not been well-known yet */
-        if (s->contentOffset + offset < DRM_MAX_MALLOC_LEN)
-            if (s->contentOffset + offset + mediaBufLen <= DRM_MAX_MALLOC_LEN) {
-                readBytes = mediaBufLen;
-                memcpy(mediaBuf, s->rawContent + s->contentOffset + offset, readBytes);
-            } else
-                readBytes = drm_readBinaryContentFromInputStream(s, offset, mediaBuf, mediaBufLen);
-        else
-            readBytes = drm_readBinaryContentFromInputStream(s, offset, mediaBuf, mediaBufLen);
-
-    return readBytes;
-}
-
-static int32_t drm_readAesContent(T_DRM_Session_Node* s, int32_t offset, uint8_t* mediaBuf, int32_t mediaBufLen)
-{
-    uint8_t keyValue[DRM_KEY_LEN];
-    uint8_t buf[DRM_TWO_AES_BLOCK_LEN];
-    int32_t readBytes = 0;
-    int32_t bufLen, piece, i, copyBytes, leftBytes;
-    int32_t aesStart, mediaStart, mediaBufOff;
-    AES_KEY key;
-
-    if (FALSE == drm_getKey(s->contentID, keyValue))
-        return DRM_NO_RIGHTS;
-
-    /* when the content length has been well-known */
-    if (s->contentLength > 0) {
-        if (offset > s->contentLength)
-            return DRM_FAILURE;
-
-        if (offset == s->contentLength)
-            return DRM_MEDIA_EOF;
-
-        if (offset + mediaBufLen > s->contentLength)
-            readBytes = s->contentLength - offset;
-        else
-            readBytes = mediaBufLen;
-
-        aesStart = s->contentOffset + (offset / DRM_ONE_AES_BLOCK_LEN * DRM_ONE_AES_BLOCK_LEN);
-        piece = (offset + readBytes - 1) / DRM_ONE_AES_BLOCK_LEN - offset / DRM_ONE_AES_BLOCK_LEN + 2;
-        mediaStart = offset % DRM_ONE_AES_BLOCK_LEN;
-
-        AES_set_decrypt_key(keyValue, DRM_KEY_LEN * 8, &key);
-        mediaBufOff = 0;
-        leftBytes = readBytes;
-
-        for (i = 0; i < piece - 1; i++) {
-            memcpy(buf, s->rawContent + aesStart + i * DRM_ONE_AES_BLOCK_LEN, DRM_TWO_AES_BLOCK_LEN);
-            bufLen = DRM_TWO_AES_BLOCK_LEN;
-
-            if (drm_aesDecBuffer(buf, &bufLen, &key) < 0)
-                return DRM_MEDIA_DATA_INVALID;
-
-            if (0 != i)
-                mediaStart = 0;
-
-            if (bufLen - mediaStart <= leftBytes)
-                copyBytes = bufLen - mediaStart;
-            else
-                copyBytes = leftBytes;
-
-            memcpy(mediaBuf + mediaBufOff, buf + mediaStart, copyBytes);
-            leftBytes -= copyBytes;
-            mediaBufOff += copyBytes;
-        }
-    } else {
-        int32_t res;
-
-        if (s->bEndData)
-            return DRM_MEDIA_EOF;
-
-        if (((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataLen > ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataOff) {
-            if (mediaBufLen < ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataLen - ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataOff)
-                copyBytes = mediaBufLen;
-            else
-                copyBytes = ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataLen - ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataOff;
-
-            memcpy(mediaBuf, ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecData + ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataOff, copyBytes);
-            ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataOff += copyBytes;
-            readBytes += copyBytes;
-        }
-
-        leftBytes = mediaBufLen - readBytes;
-        if (0 == leftBytes)
-            return readBytes;
-        if (leftBytes < 0)
-            return DRM_FAILURE;
-
-        offset += readBytes;
-        aesStart = s->contentOffset + (offset / DRM_ONE_AES_BLOCK_LEN * DRM_ONE_AES_BLOCK_LEN);
-        piece = (offset + leftBytes - 1) / DRM_ONE_AES_BLOCK_LEN - offset / DRM_ONE_AES_BLOCK_LEN + 2;
-        mediaBufOff = readBytes;
-
-        AES_set_decrypt_key(keyValue, DRM_KEY_LEN * 8, &key);
-
-        for (i = 0; i < piece - 1; i++) {
-            if (-1 == (res = drm_readAesData(buf, s, aesStart, DRM_TWO_AES_BLOCK_LEN)))
-                return DRM_MEDIA_DATA_INVALID;
-
-            if (-2 == res)
-                break;
-
-            bufLen = DRM_TWO_AES_BLOCK_LEN;
-            aesStart += DRM_ONE_AES_BLOCK_LEN;
-
-            if (drm_aesDecBuffer(buf, &bufLen, &key) < 0)
-                return DRM_MEDIA_DATA_INVALID;
-
-            drm_discardPaddingByte(buf, &bufLen);
-
-            if (bufLen <= leftBytes)
-                copyBytes = bufLen;
-            else
-                copyBytes = leftBytes;
-
-            memcpy(mediaBuf + mediaBufOff, buf, copyBytes);
-            leftBytes -= copyBytes;
-            mediaBufOff += copyBytes;
-            readBytes += copyBytes;
-        }
-
-        memcpy(((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecData, buf, DRM_ONE_AES_BLOCK_LEN);
-        ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataLen = bufLen;
-        ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataOff = copyBytes;
-
-        if (aesStart - s->contentOffset > ((T_DRM_Dcf_Node *)(s->infoStruct))->encContentLength - DRM_TWO_AES_BLOCK_LEN && ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataOff == ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataLen) {
-            s->bEndData = TRUE;
-            if (0 == readBytes)
-                return DRM_MEDIA_EOF;
-        }
-    }
-
-    return readBytes;
-}
-
-/* see svc_drm.h */
-int32_t SVC_drm_getContent(int32_t session, int32_t offset, uint8_t* mediaBuf, int32_t mediaBufLen)
-{
-    T_DRM_Session_Node* s;
-    int32_t readBytes;
-
-    if (session < 0 || offset < 0 || NULL == mediaBuf || mediaBufLen <= 0)
-        return DRM_FAILURE;
-
-    s = getSession(session);
-    if (NULL == s)
-        return DRM_SESSION_NOT_OPENED;
-
-    if (0 >= s->getInputDataLengthFunc(s->inputHandle))
-        return DRM_MEDIA_DATA_INVALID;
-
-    switch(s->deliveryMethod) {
-    case FORWARD_LOCK:
-    case COMBINED_DELIVERY:
-        if (DRM_MESSAGE_CODING_BASE64 == s->transferEncoding)
-            readBytes = drm_readBase64Content(s, offset, mediaBuf, mediaBufLen);
-        else /* binary */
-            readBytes = drm_readBinaryContent(s, offset, mediaBuf, mediaBufLen);
-        break;
-    case SEPARATE_DELIVERY:
-    case SEPARATE_DELIVERY_FL:
-        readBytes = drm_readAesContent(s, offset, mediaBuf, mediaBufLen);
-        break;
-    default:
-        return DRM_FAILURE;
-    }
-
-    return readBytes;
-}
-
-/* see svc_drm.h */
-int32_t SVC_drm_getRightsIssuer(int32_t session, uint8_t* rightsIssuer)
-{
-    T_DRM_Session_Node* s;
-
-    if (session < 0 || NULL == rightsIssuer)
-        return DRM_FAILURE;
-
-    s = getSession(session);
-    if (NULL == s)
-        return DRM_SESSION_NOT_OPENED;
-
-    if (SEPARATE_DELIVERY == s->deliveryMethod || SEPARATE_DELIVERY_FL == s->deliveryMethod) {
-        strcpy((char *)rightsIssuer, (char *)((T_DRM_Dcf_Node *)(s->infoStruct))->rightsIssuer);
-        return DRM_SUCCESS;
-    }
-
-    return DRM_NOT_SD_METHOD;
-}
-
-/* see svc_drm.h */
-int32_t SVC_drm_getRightsInfo(int32_t session, T_DRM_Rights_Info* rights)
-{
-    T_DRM_Session_Node* s;
-    T_DRM_Rights rightsInfo;
-    int32_t roAmount, id;
-
-    if (session < 0 || NULL == rights)
-        return DRM_FAILURE;
-
-    s = getSession(session);
-    if (NULL == s)
-        return DRM_SESSION_NOT_OPENED;
-
-    if (FORWARD_LOCK == s->deliveryMethod) {
-        strcpy((char *)rights->roId, "ForwardLock");
-        rights->displayRights.indicator = DRM_NO_CONSTRAINT;
-        rights->playRights.indicator = DRM_NO_CONSTRAINT;
-        rights->executeRights.indicator = DRM_NO_CONSTRAINT;
-        rights->printRights.indicator = DRM_NO_CONSTRAINT;
-        return DRM_SUCCESS;
-    }
-
-    if (FALSE == drm_readFromUidTxt(s->contentID, &id, GET_ID))
-        return DRM_NO_RIGHTS;
-
-    if (FALSE == drm_writeOrReadInfo(id, NULL, &roAmount, GET_ROAMOUNT))
-        return DRM_FAILURE;
-
-    if (roAmount < 0)
-        return DRM_NO_RIGHTS;
-
-    /* some rights has been installed, but now there is no valid rights */
-    if (0 == roAmount) {
-        strcpy((char *)rights->roId, s->contentID);
-        rights->displayRights.indicator = DRM_NO_PERMISSION;
-        rights->playRights.indicator = DRM_NO_PERMISSION;
-        rights->executeRights.indicator = DRM_NO_PERMISSION;
-        rights->printRights.indicator = DRM_NO_PERMISSION;
-        return DRM_SUCCESS;
-    }
-
-    roAmount = 1;
-    memset(&rightsInfo, 0, sizeof(T_DRM_Rights));
-    if (FALSE == drm_writeOrReadInfo(id, &rightsInfo, &roAmount, GET_A_RO))
-        return DRM_FAILURE;
-
-    memset(rights, 0, sizeof(T_DRM_Rights_Info));
-    drm_getLicenseInfo(&rightsInfo, rights);
-    return DRM_SUCCESS;
-}
-
-/* see svc_drm.h */
-int32_t SVC_drm_closeSession(int32_t session)
-{
-    if (session < 0)
-        return DRM_FAILURE;
-
-    if (NULL == getSession(session))
-        return DRM_SESSION_NOT_OPENED;
-
-    removeSession(session);
-
-    return DRM_SUCCESS;
-}
-
-/* see svc_drm.h */
-int32_t SVC_drm_updateRights(uint8_t* contentID, int32_t permission)
-{
-    int32_t id;
-
-    if (NULL == contentID)
-        return DRM_FAILURE;
-
-    if (FALSE == drm_readFromUidTxt(contentID, &id, GET_ID))
-        return DRM_FAILURE;
-
-    return drm_checkRoAndUpdate(id, permission);
-}
-
-/* see svc_drm.h */
-int32_t SVC_drm_viewAllRights(T_DRM_Rights_Info_Node **ppRightsInfo)
-{
-    T_DRM_Rights_Info_Node rightsNode;
-    int32_t maxId, id, roAmount, j;
-    T_DRM_Rights rights;
-
-    memset(&rights, 0, sizeof(T_DRM_Rights));
-
-    if (NULL == ppRightsInfo)
-        return DRM_FAILURE;
-
-    *ppRightsInfo = NULL;
-
-    maxId = drm_getMaxIdFromUidTxt();
-    if (-1 == maxId)
-        return DRM_FAILURE;
-
-    for (id = 1; id <= maxId; id++) {
-        drm_writeOrReadInfo(id, NULL, &roAmount, GET_ROAMOUNT);
-        if (roAmount <= 0) /* this means there is not any rights */
-            continue;
-
-        for (j = 1; j <= roAmount; j++) {
-            if (FALSE == drm_writeOrReadInfo(id, &rights, &j, GET_A_RO))
-                continue;
-
-            memset(&rightsNode, 0, sizeof(T_DRM_Rights_Info_Node));
-
-            drm_getLicenseInfo(&rights, &(rightsNode.roInfo));
-
-            if (FALSE == drm_addRightsNodeToList(ppRightsInfo, &rightsNode))
-                continue;
-        }
-    }
-    return DRM_SUCCESS;
-}
-
-/* see svc_drm.h */
-int32_t SVC_drm_freeRightsInfoList(T_DRM_Rights_Info_Node *pRightsHeader)
-{
-    T_DRM_Rights_Info_Node *pNode, *pTmp;
-
-    if (NULL == pRightsHeader)
-        return DRM_FAILURE;
-
-    pNode = pRightsHeader;
-
-    while (NULL != pNode) {
-        pTmp = pNode;
-        pNode = pNode->next;
-        free(pTmp);
-    }
-    return DRM_SUCCESS;
-}
-
-/* see svc_drm.h */
-int32_t SVC_drm_deleteRights(uint8_t* roId)
-{
-    int32_t maxId, id, roAmount, j;
-    T_DRM_Rights rights;
-
-    memset(&rights, 0, sizeof(T_DRM_Rights));
-
-    if (NULL == roId)
-        return DRM_FAILURE;
-
-    maxId = drm_getMaxIdFromUidTxt();
-    if (-1 == maxId)
-        return DRM_NO_RIGHTS;
-
-    for (id = 1; id <= maxId; id++) {
-        drm_writeOrReadInfo(id, NULL, &roAmount, GET_ROAMOUNT);
-        if (roAmount <= 0) /* this means there is not any rights */
-            continue;
-
-        for (j = 1; j <= roAmount; j++) {
-            if (FALSE == drm_writeOrReadInfo(id, &rights, &j, GET_A_RO))
-                continue;
-
-            /* here find the RO which will be deleted */
-            if (0 == strcmp((char *)rights.uid, (char *)roId)) {
-                T_DRM_Rights *pAllRights;
-
-                pAllRights = (T_DRM_Rights *)malloc(roAmount * sizeof(T_DRM_Rights));
-                if (NULL == pAllRights)
-                    return DRM_FAILURE;
-
-                drm_writeOrReadInfo(id, pAllRights, &roAmount, GET_ALL_RO);
-                roAmount--;
-                if (0 == roAmount) { /* this means it is the last one rights */
-                    drm_removeIdInfoFile(id); /* delete the id.info file first */
-                    drm_updateUidTxtWhenDelete(id); /* update uid.txt file */
-                    free(pAllRights);
-                    return DRM_SUCCESS;
-                } else /* using the last one rights instead of the deleted one */
-                    memcpy(pAllRights + (j - 1), pAllRights + roAmount, sizeof(T_DRM_Rights));
-
-                /* delete the id.info file first */
-//                drm_removeIdInfoFile(id);
-
-                if (FALSE == drm_writeOrReadInfo(id, pAllRights, &roAmount, SAVE_ALL_RO)) {
-                    free(pAllRights);
-                    return DRM_FAILURE;
-                }
-
-                free(pAllRights);
-                return DRM_SUCCESS;
-            }
-        }
-    }
-
-    return DRM_FAILURE;
-}
diff --git a/media/libdrm/mobile1/src/objmng/drm_decoder.c b/media/libdrm/mobile1/src/objmng/drm_decoder.c
deleted file mode 100644
index 82c7efb..0000000
--- a/media/libdrm/mobile1/src/objmng/drm_decoder.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <objmng/drm_decoder.h>
-
-/* global variables */
-static const uint8_t * base64_alphabet = (const uint8_t *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-#define SKIP_CRLF(p) while('\r' == *(p) || '\n' == *(p)) \
-                         p++
-
-static int8_t get_alphabet_index(int8_t ch)
-{
-    uint8_t * tmp;
-
-    if ('=' == ch)
-        return 64;
-
-    tmp = (uint8_t *)strchr((const char *)base64_alphabet, ch);
-    if (NULL == tmp)
-        return -1;
-
-    return (int8_t)(tmp - base64_alphabet);
-}
-
-/* See drm_decoder.h */
-int32_t drm_decodeBase64(uint8_t * dest, int32_t destLen, uint8_t * src, int32_t * srcLen)
-{
-    int32_t maxDestSize, i, maxGroup;
-    uint8_t *pDest, *pSrc;
-    int8_t tpChar;
-
-    if (NULL == src || NULL == srcLen || *srcLen <= 0 || destLen < 0)
-        return -1;
-
-    maxDestSize = (*srcLen) * 3/4;
-    if (NULL == dest || 0 == destLen)
-        return maxDestSize;
-
-    if (destLen < maxDestSize)
-        maxDestSize = destLen;
-    maxGroup = maxDestSize/3;
-
-    pDest = dest;   /* start to decode src to dest */
-    pSrc = src;
-    for (i = 0; i < maxGroup && *srcLen - (pSrc - src) >= 4; i++) {
-        SKIP_CRLF(pSrc);
-        if (pSrc - src >= *srcLen)
-            break;
-        tpChar = get_alphabet_index(*pSrc);       /* to first byte */
-        if (-1 == tpChar || 64 == tpChar)
-            return -1;
-        pDest[0] = tpChar << 2;
-        pSrc++;
-        SKIP_CRLF(pSrc);
-        tpChar = get_alphabet_index(*pSrc);
-        if (-1 == tpChar || 64 == tpChar)
-            return -1;
-        pDest[0] |= (tpChar >> 4);
-        pDest[1] = tpChar << 4;                     /* to second byte */
-        pSrc++;
-        SKIP_CRLF(pSrc);
-        tpChar = get_alphabet_index(*pSrc);
-        if (-1 == tpChar)
-            return -1;
-        if (64 == tpChar)           /* end */
-            return pDest - dest + 1;
-        pDest[1] |= (tpChar >> 2);
-        pDest[2] = tpChar << 6;                     /* to third byte */
-        pSrc++;
-        SKIP_CRLF(pSrc);
-        tpChar = get_alphabet_index(*pSrc);
-        if (-1 == tpChar)
-            return -1;
-        if (64 == tpChar)           /* end */
-            return pDest - dest + 2;
-        pDest[2] |= tpChar;
-        pDest += 3;
-        pSrc++;
-    }
-    *srcLen = pSrc - src;
-    return pDest - dest;
-}
diff --git a/media/libdrm/mobile1/src/objmng/drm_file.c b/media/libdrm/mobile1/src/objmng/drm_file.c
deleted file mode 100644
index e6c303e..0000000
--- a/media/libdrm/mobile1/src/objmng/drm_file.c
+++ /dev/null
@@ -1,694 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <objmng/drm_file.h>
-
-#include <unistd.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <errno.h>
-#include <string.h>
-
-/**
- * Fails on zaurus?
- #define DEVICE_FILESYSTEM
-*/
-#define DEFAULT_TOTAL_SPACE (4L * 1024L * 1024L) /* 4 Meg. */
-
-#ifndef DEVICE_FILESYSTEM
-/* Store the total space on FS VM can use. */
-static int32_t totalSpace;
-/* how many remain space can VM use. */
-static int32_t availableSize;
-#endif
-
-extern char* getStorageRoot(void);
-
-static char tmpPathBuf1[MAX_FILENAME_LEN];
-static char tmpPathBuf2[MAX_FILENAME_LEN];
-
-static int32_t
-convertFilename(const uint16_t *strData, int32_t strLength, char *buffer);
-
-static int calcDirSize(char *path, int len, uint8_t includeSubdirs);
-
-#ifndef DEVICE_FILESYSTEM
-static void initFsVariables(void);
-#endif
-
-/**
- * Convert a Java string into a nul terminated ascii string to pass to posix
- * @param strData    first character of name
- * @param strLength  number of characters in name
- * @param buffer Buffer to store terminated string in (at least MAXPATHLEN)
- * @return Length of filename in characters (excl. nul), or -1 on failure.
- */
-static int32_t
-convertFilename(const uint16_t *strData, int32_t strLength, char *buffer)
-{
-    int idx;
-
-    if (strLength >= (MAXPATHLEN-1))
-    {
-        Trace("convertFilename '%.*S' too long", strLength, strData);
-        return -1;
-    }
-
-    for (idx = 0; idx < strLength; ++idx)
-        *buffer++ = (char)*strData++;
-
-    *buffer = 0;
-    return strLength;
-}
-
-
-/**
- * Perform a stat() call on the given filename.
- * Helper for getFileLength and exists
- * @param name unicode name
- * @param nameLen number of unicode characters in name
- * @param sbuf stat buffer
- * @return TRUE on success, FALSE on failure
- */
-static int32_t
-getFileStat(const uint16_t *name, int32_t nameLen, struct stat *sbuf)
-{
-    Trace("getFileStat: %.*S", nameLen, name);
-
-    if (convertFilename(name, nameLen, tmpPathBuf1) <= 0)
-    {
-        Trace("getFileStat: bad filename");
-    }
-    else if (stat(tmpPathBuf1, sbuf) != 0)
-    {
-        Trace("getFileStat %s: stat() errno=%d", tmpPathBuf1, errno);
-    }
-    else /* Successful */
-    {
-        return TRUE;
-    }
-
-    return FALSE;
-}
-
-#ifndef DEVICE_FILESYSTEM
-/**
- * initial the variables like totalSpace, availableSize...
- */
-static void initFsVariables(void)
-{
-    totalSpace = DEFAULT_TOTAL_SPACE;
-
-    availableSize = totalSpace;
-}
-#endif /* DEVICE_FILESYSTEM */
-
-/**
- * calculate the size of everything inside path pointed directory
- * this function will use path pointed buffer to store some extra info
- * so param len is needed.
- * @param path    the directory path need to calculate
- * @param len   length of the path buffer, not the path string length
- * @param includeSubdirs  also calculate all the subdirs in path holds?
- * @return the calculated size, DRM_FILE_FAILURE on failure.
- */
-static int calcDirSize(char *path, int len, uint8_t includeSubdirs)
-{
-    struct dirent *ent;
-    struct stat stat_buf;
-
-    DIR *dir = NULL;
-    int size = 0;
-    int exists = -1;
-    int dirPathLen = strlen(path);
-
-    /* Ensure space for wildcard */
-    if((dirPathLen + 2) >= MAXPATHLEN || (dirPathLen + 2) >= len)
-    {
-        return DRM_FILE_FAILURE;
-    }
-
-    if(path[dirPathLen - 1] != '/')
-    {
-        path[dirPathLen++] = '/';
-        path[dirPathLen] = '\0';
-    }
-
-    dir = opendir(path);
-    if (dir == NULL)
-    {
-        return DRM_FILE_FAILURE;
-    }
-
-    while ((ent = readdir(dir)) != NULL )
-    {
-        if (strcmp(ent->d_name, ".") == 0 ||
-                strcmp(ent->d_name, "..") == 0)
-        {
-            continue;
-        }
-
-        path[dirPathLen] = '\0';
-        if ((int)(strlen(ent->d_name) + dirPathLen + 1) < len)
-        {
-            strcat(path, ent->d_name);
-        }
-        else
-        {
-            continue;
-        }
-
-        exists = stat(path, &stat_buf);
-        if (exists != -1)
-        {
-            /* exclude the storage occupied by directory itself */
-            if (stat_buf.st_mode & S_IFDIR)
-            {
-                if(includeSubdirs)
-                {
-                    /* calculate the size recursively */
-                    int ret;
-                    ret = calcDirSize(path, len, includeSubdirs);
-                    /* ignore failure in subdirs */
-                    if( DRM_FILE_FAILURE != ret )
-                    {
-                        size += ret;
-                    }
-                }
-            }
-            else
-            {
-                size += stat_buf.st_size;
-            }
-        }
-    }
-
-    closedir(dir);
-    return size;
-}
-
-/* see drm_file.h */
-int32_t DRM_file_startup(void)
-{
-    Trace("DRM_file_startup");
-
-#ifndef DEVICE_FILESYSTEM
-    availableSize = -1;
-
-    initFsVariables();
-#endif
-
-    return DRM_FILE_SUCCESS;    /* Nothing to do */
-}
-
-/* see drm_file.h */
-int32_t
-DRM_file_listOpen(const uint16_t *prefix,
-                    int32_t prefixLen,
-                    int32_t* session,
-                    int32_t* iteration)
-{
-    Trace("DRM_file_listOpen: %.*S", prefixLen, prefix);
-
-    if (convertFilename(prefix, prefixLen, tmpPathBuf1) <= 0)
-    {
-        Trace("DRM_file_listOpen: bad filename");
-    }
-    else
-    {
-        DIR *dir;
-
-        /* find the last /, and store the offset to the leaf prefix in
-         * *iteration
-         */
-
-        char *sep = strrchr(tmpPathBuf1, '/');
-        /* Root "/" is a leaf */
-        if (sep == NULL || ((sep != NULL) && (sep == tmpPathBuf1)))
-        {
-            *iteration = prefixLen;
-
-#ifdef TRACE_ON
-            sep = " <empty>"; /* trace will show sep+1 */
-#endif
-        }
-        else
-        {
-            *iteration = sep - tmpPathBuf1 + 1;
-            *sep = 0;
-        }
-
-        dir = opendir(tmpPathBuf1);
-
-        if (dir == NULL)
-        {
-            Trace("DRM_file_listOpen: opendir %s: errno=%d", tmpPathBuf1, errno);
-        }
-        else
-        {
-            Trace("DRM_file_listOpen: dir %s, filter %s", tmpPathBuf1, sep+1);
-            *session = (int32_t)dir;
-            return DRM_FILE_SUCCESS;
-        }
-    }
-
-    return DRM_FILE_FAILURE;
-}
-
-/* see drm_file.h */
-int32_t
-DRM_file_listNextEntry(const uint16_t *prefix, int32_t prefixLen,
-                       uint16_t* entry, int32_t entrySize,
-                       int32_t *session, int32_t* iteration)
-{
-    struct dirent *ent;
-
-    /* We stored the offset of the leaf part of the prefix (if any)
-     * in *iteration
-     */
-    const uint16_t* strData   = prefix + *iteration;
-    int32_t   strLength = prefixLen - *iteration;
-
-    /* entrySize is bytes for some reason. Convert to ucs chars */
-    entrySize /= 2;
-
-    /* Now we want to filter for files which start with the (possibly empty)
-     * sequence at strData. We have to return fully-qualified filenames,
-     * which means *iteration characters from prefix, plus the
-     * leaf name.
-     */
-
-    while ( (ent = readdir((DIR *)*session)) != NULL)
-    {
-        int len = strlen(ent->d_name);
-
-        if ( (len + *iteration) > entrySize)
-        {
-            Trace("DRM_file_listNextEntry: %s too long", ent->d_name);
-        }
-        else if (strcmp(ent->d_name, ".") != 0 &&
-                 strcmp(ent->d_name, "..") != 0)
-        {
-            int idx;
-            struct stat sinfo;
-
-            /* check against the filter */
-
-            for (idx = 0; idx < strLength; ++idx)
-            {
-                if (ent->d_name[idx] != strData[idx])
-                    goto next_name;
-            }
-
-            Trace("DRM_file_listNextEntry: matched %s", ent->d_name);
-
-            /* Now generate the fully-qualified name */
-
-            for (idx = 0; idx < *iteration; ++idx)
-                entry[idx] = prefix[idx];
-
-            for (idx = 0; idx < len; ++idx)
-                entry[*iteration + idx] = (unsigned char)ent->d_name[idx];
-
-            /*add "/" at the end of a DIR file entry*/
-            if (getFileStat(entry, idx + *iteration, &sinfo)){
-                if (S_ISDIR(sinfo.st_mode) &&
-                        (idx + 1 + *iteration) < entrySize) {
-                    entry[*iteration + idx] = '/';
-                    ++idx;
-                }
-            }
-            else
-            {
-                Trace("DRM_file_listNextEntry: stat FAILURE on %.*S",
-                      idx + *iteration, entry);
-            }
-            Trace("DRM_file_listNextEntry: got %.*S", idx + *iteration, entry);
-
-            return idx + *iteration;
-        }
-
-    next_name:
-        Trace("DRM_file_listNextEntry: rejected %s", ent->d_name);
-    }
-
-    Trace("DRM_file_listNextEntry: end of list");
-    return 0;
-}
-
-/* see drm_file.h */
-int32_t
-DRM_file_listClose(int32_t session, int32_t iteration)
-{
-    closedir( (DIR *)session);
-    return DRM_FILE_SUCCESS;
-}
-
-/* see drm_file.h */
-int32_t
-DRM_file_getFileLength(const uint16_t *name, int32_t nameLen)
-{
-    struct stat sbuf;
-
-    if (getFileStat(name, nameLen, &sbuf))
-    {
-        if (sbuf.st_size >= INT32_MAX)
-        {
-            Trace("DRM_file_getFileLength: file too big");
-        }
-        else /* Successful */
-        {
-            Trace("DRM_file_getFileLength: %.*S -> %d",
-                                         nameLen, name, (int32_t)sbuf.st_size);
-            return (int32_t)sbuf.st_size;
-        }
-    }
-
-    return DRM_FILE_FAILURE;
-}
-
-/* see drm_file.h */
-int32_t
-DRM_file_delete(const uint16_t *name, int32_t nameLen)
-{
-    Trace("DRM_file_delete: %.*S", nameLen, name);
-
-    if (convertFilename(name, nameLen, tmpPathBuf1) <= 0)
-    {
-        Trace("DRM_file_delete: bad filename");
-        return DRM_FILE_FAILURE;
-    }
-    else
-    {
-       struct stat sinfo;
-       if (stat(tmpPathBuf1, &sinfo) != 0){
-           Trace("DRM_file_delete: stat failed, errno=%d", errno);
-           return DRM_FILE_FAILURE;
-       }
-#ifndef DEVICE_FILESYSTEM
-       if (S_ISDIR(sinfo.st_mode)){
-            /* it's a dir */
-            if (rmdir(tmpPathBuf1) != 0){
-                Trace("DRM_file_delete: dir remove failed, errno=%d", errno);
-                return DRM_FILE_FAILURE;
-            }
-            else
-            {
-                return DRM_FILE_SUCCESS;
-            }
-        }
-#endif
-        /* it's a file */
-        if (unlink(tmpPathBuf1) != 0)
-        {
-            Trace("DRM_file_delete: file remove failed, errno=%d", errno);
-            return DRM_FILE_FAILURE;
-        }
-        else
-        {
-#ifndef DEVICE_FILESYSTEM
-            availableSize += sinfo.st_size;
-#endif
-            return DRM_FILE_SUCCESS;
-        }
-    }
-    return DRM_FILE_FAILURE;
-}
-
-/* see drm_file.h */
-int32_t
-DRM_file_rename(const uint16_t *oldName, int32_t oldNameLen,
-                const uint16_t *newName, int32_t newNameLen)
-{
-    Trace("DRM_file_rename %.*S -> %.*S",
-                                    oldNameLen, oldName, newNameLen, newName);
-    if (DRM_file_exists(newName, newNameLen) != DRM_FILE_FAILURE)
-    {
-        Trace("DRM_file_rename: filename:%s exist",newName);
-        return DRM_FILE_FAILURE;
-    }
-
-    if (convertFilename(oldName, oldNameLen, tmpPathBuf1) <= 0 ||
-        convertFilename(newName, newNameLen, tmpPathBuf2) <= 0)
-    {
-        Trace("DRM_file_rename: bad filename");
-    }
-    else if (rename(tmpPathBuf1, tmpPathBuf2) != 0)
-    {
-         Trace("DRM_file_rename: failed errno=%d", errno);
-    }
-    else /* Success */
-    {
-        return DRM_FILE_SUCCESS;
-    }
-
-    return DRM_FILE_FAILURE;
-}
-
-/* see drm_file.h */
-int32_t
-DRM_file_exists(const uint16_t *name, int32_t nameLen)
-{
-    struct stat sbuf;
-
-    Trace("DRM_file_exists: %.*S", nameLen, name);
-
-    /*remove trailing "/" separators, except the first "/" standing for root*/
-    while ((nameLen > 1) && (name[nameLen -1] == '/'))
-       --nameLen;
-
-    if (getFileStat(name, nameLen, &sbuf))
-    {
-        Trace("DRM_file_exists: stat returns mode 0x%x", sbuf.st_mode);
-
-        if (S_ISDIR(sbuf.st_mode))
-            return DRM_FILE_ISDIR;
-        if (S_ISREG(sbuf.st_mode))
-            return DRM_FILE_ISREG;
-    }
-
-    return DRM_FILE_FAILURE;
-}
-
-/* see drm_file.h */
-int32_t
-DRM_file_open(const uint16_t *name, int32_t nameLen, int32_t mode,
-                      int32_t* handle)
-{
-    int res;
-
-#if DRM_FILE_MODE_READ != 1 || DRM_FILE_MODE_WRITE != 2
-#error constants changed
-#endif
-
-    /* Convert DRM file modes to posix modes */
-    static const int modes[4] =
-    { 0,
-      O_RDONLY,
-      O_WRONLY | O_CREAT,
-      O_RDWR | O_CREAT
-    };
-
-    Trace("DRM_file_open %.*S mode 0x%x", nameLen, name, mode);
-
-    assert((mode & ~(DRM_FILE_MODE_READ|DRM_FILE_MODE_WRITE)) == 0);
-
-    if (convertFilename(name, nameLen, tmpPathBuf1) <= 0)
-    {
-        Trace("DRM_file_open: bad filename");
-        return DRM_FILE_FAILURE;
-    }
-
-    if ((res = open(tmpPathBuf1, modes[mode], 0777)) == -1)
-    {
-        Trace("DRM_file_open: open failed errno=%d", errno);
-        return DRM_FILE_FAILURE;
-    }
-
-    Trace("DRM_file_open: open '%s; returned %d", tmpPathBuf1, res);
-    *handle = res;
-
-    return DRM_FILE_SUCCESS;
-}
-
-/* see drm_file.h */
-int32_t
-DRM_file_read(int32_t handle, uint8_t* dst, int32_t length)
-{
-    int n;
-
-    assert(length > 0);
-
-    /* TODO: Make dst a void *? */
-
-    n = read((int)handle, dst, (size_t)length);
-    if (n > 0)
-    {
-        Trace("DRM_file_read handle=%d read %d bytes", handle, n);
-        return n;
-    }
-    else if (n == 0)
-    {
-        Trace("DRM_file_read read EOF: handle=%d", handle);
-        return DRM_FILE_EOF;
-    }
-    else
-    {
-        Trace("DRM_file_read failed handle=%d, errno=%d", handle, errno);
-        return DRM_FILE_FAILURE;
-    }
-}
-
-/* see drm_file.h */
-int32_t
-DRM_file_write(int32_t handle, const uint8_t* src, int32_t length)
-{
-    /* TODO: Make dst a void *? */
-    int n;
-#ifndef DEVICE_FILESYSTEM
-    int delta;
-    off_t prevPos;
-    struct stat sbuf;
-    int prevFileSize;
-#endif
-
-    assert(length >= 0);
-
-#ifndef DEVICE_FILESYSTEM
-    if ( -1 == fstat((int)handle, &sbuf) )
-    {
-        Trace("DRM_file_write: fstat error %d", errno);
-        return DRM_FILE_FAILURE;
-    }
-    prevFileSize = (int)(sbuf.st_size);
-    prevPos = lseek( (int)handle, 0, SEEK_CUR);
-    if ( (off_t)-1 == prevPos )
-    {
-        Trace("DRM_file_write: get current pos error %d", errno);
-        return DRM_FILE_FAILURE;
-    }
-    delta = (int)prevPos + length - prevFileSize;
-    if (delta > availableSize)
-    {
-        Trace("DRM_file_write: not enough size!");
-        return DRM_FILE_FAILURE;
-    }
-#endif
-    n = write((int)handle, src, (size_t)length);
-    if (n < 0)
-    {
-        Trace("DRM_file_write failed errno=%d", errno);
-        return DRM_FILE_FAILURE;
-    }
-#ifndef DEVICE_FILESYSTEM
-    delta = prevPos + n - prevFileSize;
-
-    if ( delta > 0 )
-    {
-        availableSize -= delta;
-    }
-#endif
-    Trace("DRM_file_write handle=%d wrote %d/%d bytes", handle, n, length);
-
-    return n;
-}
-
-/* see drm_file.h */
-int32_t DRM_file_close(int32_t handle)
-{
-    if (close((int)handle) == 0)
-    {
-        Trace("DRM_file_close handle=%d success", handle);
-        return DRM_FILE_SUCCESS;
-    }
-
-    Trace("DRM_file_close handle=%d failed", handle);
-    return DRM_FILE_FAILURE;
-}
-
-/* see drm_file.h */
-int32_t
-DRM_file_setPosition(int32_t handle, int32_t value)
-{
-#ifndef DEVICE_FILESYSTEM
-    struct stat sbuf;
-#endif
-    off_t newPos;
-
-    if (value < 0)
-    {
-        Trace("DRM_file_setPosition: handle=%d negative value (%d)",
-            handle, value);
-        return DRM_FILE_FAILURE;
-    }
-
-#ifndef DEVICE_FILESYSTEM
-    if ( fstat((int)handle, &sbuf) == -1 )
-    {
-        Trace("DRM_file_setPosition: fstat fail errno=%d", errno);
-        return DRM_FILE_FAILURE;
-    }
-
-    if ( ((off_t)value > sbuf.st_size) &&
-         (availableSize < (value - (int)(sbuf.st_size))) )
-    {
-        Trace("DRM_file_setPosition: not enough space");
-        return DRM_FILE_FAILURE;
-    }
-#endif
-
-    newPos = lseek( (int)handle, (off_t)value, SEEK_SET);
-    if ( newPos == (off_t)-1 )
-    {
-        Trace("DRM_file_setPosition: seek failed: errno=%d", errno);
-    }
-    else
-    {
-#ifndef DEVICE_FILESYSTEM
-        if ( newPos > sbuf.st_size )
-        {
-            availableSize -= (int)(newPos - sbuf.st_size);
-        }
-#endif
-        return DRM_FILE_SUCCESS;
-    }
-
-    return DRM_FILE_FAILURE;
-}
-
-/* see drm_file.h */
-int32_t
-DRM_file_mkdir(const uint16_t* name, int32_t nameChars)
-{
-    Trace("DRM_file_mkdir started!..");
-
-    if (convertFilename(name, nameChars, tmpPathBuf1) <= 0)
-    {
-        Trace("DRM_file_mkdir: bad filename");
-        return DRM_FILE_FAILURE;
-    }
-
-    if (mkdir(tmpPathBuf1,0777) != 0)
-    {
-        Trace("DRM_file_mkdir failed!errno=%d",errno);
-        return DRM_FILE_FAILURE;
-    }
-
-    return DRM_FILE_SUCCESS;
-}
diff --git a/media/libdrm/mobile1/src/objmng/drm_i18n.c b/media/libdrm/mobile1/src/objmng/drm_i18n.c
deleted file mode 100644
index b1118a9..0000000
--- a/media/libdrm/mobile1/src/objmng/drm_i18n.c
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <objmng/drm_i18n.h>
-
-#define IS_GB2312_HIGH_BYTE(c)  ((c) >= 0xA1 && (c) <= 0xF7)
-#define IS_GB2312_LOW_BYTE(c)   ((c) >= 0xA1 && (c) <= 0xFE)
-#define IS_GBK_HIGH_BYTE(c)     ((c) >= 0x81 && (c) <= 0xFE)
-#define IS_GBK_LOW_BYTE(c)      ((c) >= 0x40 && (c) <= 0xFE && (c) != 0x7F)
-#define IS_BIG5_HIGH_BYTE(c)    ((c) >= 0xA1 && (c) <= 0xF9)
-#define IS_BIG5_LOW_BYTE(c)     (((c) >= 0x40 && (c) <= 0x7E) \
-                                 || ((c) >= 0xA1 && (c) <= 0xFE))
-#define IS_ASCII(c)             ((c) <= 127)
-
-#define INVALID_UNICODE         0xFFFD
-
-#define I18N_LATIN1_SUPPORT
-#define I18N_UTF8_UTF16_SUPPORT
-
-
-/**
- * Simply convert ISO 8859-1 (latin1) to unicode
- */
-static int32_t latin1ToWcs(const uint8_t *mbs, int32_t mbsLen,
-        uint16_t *wcsBuf, int32_t bufSizeInWideChar,
-        int32_t *bytesConsumed);
-
-/**
- * Convert one unicode char to ISO 8859-1 (latin1) byte
- */
-static int32_t wcToLatin1(uint16_t wc, uint8_t * mbs, int32_t bufSize);
-
-/**
- * Convert UTF-8 to unicode
- */
-static int32_t utf8ToWcs(const uint8_t *mbs, int32_t mbsLen,
-        uint16_t *wcsBuf, int32_t bufSizeInWideChar,
-        int32_t *bytesConsumed);
-
-/**
- * Convert one unicode char to UTF-8 bytes
- */
-static int32_t wcToUtf8(uint16_t wc, uint8_t * mbs, int32_t bufSize);
-
-/**
- * Convert UTF-16 BE to unicode
- */
-static int32_t utf16beToWcs(const uint8_t *mbs, int32_t mbsLen,
-        uint16_t *wcsBuf, int32_t bufSizeInWideChar,
-        int32_t *bytesConsumed);
-
-/**
- * Convert one unicode char to UTF-16 BE bytes
- */
-static int32_t wcToUtf16be(uint16_t wc, uint8_t * mbs, int32_t bufSize);
-
-/**
- * Convert UTF-16 LE to unicode
- */
-static int32_t utf16leToWcs(const uint8_t *mbs, int32_t mbsLen,
-        uint16_t *wcsBuf, int32_t bufSizeInWideChar,
-        int32_t *bytesConsumed);
-
-/**
- * Convert one unicode char to UTF-16 LE bytes
- */
-static int32_t wcToUtf16le(uint16_t wc, uint8_t * mbs, int32_t bufSize);
-
-/*
- * see drm_i18n.h
- */
-int32_t DRM_i18n_mbsToWcs(DRM_Charset_t charset,
-        const uint8_t *mbs, int32_t mbsLen,
-        uint16_t *wcsBuf, int32_t bufSizeInWideChar,
-        int32_t *bytesConsumed)
-{
-    switch (charset)
-    {
-#ifdef I18N_GB2312_SUPPORT
-        case DRM_CHARSET_GB2312:
-            return gb2312ToWcs(mbs, mbsLen, wcsBuf, bufSizeInWideChar, bytesConsumed);
-#endif
-#ifdef I18N_GBK_SUPPORT
-        case DRM_CHARSET_GBK:
-            return gbkToWcs(mbs, mbsLen, wcsBuf, bufSizeInWideChar, bytesConsumed);
-#endif
-#ifdef I18N_BIG5_SUPPORT
-        case DRM_CHARSET_BIG5:
-            return big5ToWcs(mbs, mbsLen, wcsBuf, bufSizeInWideChar, bytesConsumed);
-#endif
-#ifdef I18N_LATIN1_SUPPORT
-        case DRM_CHARSET_LATIN1:
-            return latin1ToWcs(mbs, mbsLen, wcsBuf, bufSizeInWideChar, bytesConsumed);
-#endif
-#ifdef I18N_ISO8859X_SUPPORT
-        case DRM_CHARSET_LATIN2:
-        case DRM_CHARSET_LATIN3:
-        case DRM_CHARSET_LATIN4:
-        case DRM_CHARSET_CYRILLIC:
-        case DRM_CHARSET_ARABIC:
-        case DRM_CHARSET_GREEK:
-        case DRM_CHARSET_HEBREW:
-        case DRM_CHARSET_LATIN5:
-        case DRM_CHARSET_LATIN6:
-        case DRM_CHARSET_THAI:
-        case DRM_CHARSET_LATIN7:
-        case DRM_CHARSET_LATIN8:
-        case DRM_CHARSET_LATIN9:
-        case DRM_CHARSET_LATIN10:
-            return iso8859xToWcs(charset, mbs, mbsLen, wcsBuf, bufSizeInWideChar, bytesConsumed);
-#endif
-#ifdef I18N_UTF8_UTF16_SUPPORT
-        case DRM_CHARSET_UTF8:
-            return utf8ToWcs(mbs, mbsLen, wcsBuf, bufSizeInWideChar, bytesConsumed);
-        case DRM_CHARSET_UTF16BE:
-            return utf16beToWcs(mbs, mbsLen, wcsBuf, bufSizeInWideChar, bytesConsumed);
-        case DRM_CHARSET_UTF16LE:
-            return utf16leToWcs(mbs, mbsLen, wcsBuf, bufSizeInWideChar, bytesConsumed);
-#endif
-        default:
-            return -1;
-    }
-}
-
-/*
- * see drm_i18n.h
- */
-int32_t DRM_i18n_wcsToMbs(DRM_Charset_t charset,
-        const uint16_t *wcs, int32_t wcsLen,
-        uint8_t *mbsBuf, int32_t bufSizeInByte)
-{
-    int32_t (* wcToMbFunc)(uint16_t, uint8_t *, int32_t);
-    int32_t charIndex = 0;
-    int32_t numMultiBytes = 0;
-
-    switch (charset)
-    {
-#ifdef I18N_LATIN1_SUPPORT
-        case DRM_CHARSET_LATIN1:
-            wcToMbFunc = wcToLatin1;
-            break;
-#endif
-#ifdef I18N_UTF8_UTF16_SUPPORT
-        case DRM_CHARSET_UTF8:
-            wcToMbFunc = wcToUtf8;
-            break;
-        case DRM_CHARSET_UTF16BE:
-            wcToMbFunc = wcToUtf16be;
-            break;
-        case DRM_CHARSET_UTF16LE:
-            wcToMbFunc = wcToUtf16le;
-            break;
-#endif
-#ifdef I18N_ISO8859X_SUPPORT
-        case DRM_CHARSET_LATIN2:
-        case DRM_CHARSET_LATIN3:
-        case DRM_CHARSET_LATIN4:
-        case DRM_CHARSET_CYRILLIC:
-        case DRM_CHARSET_ARABIC:
-        case DRM_CHARSET_GREEK:
-        case DRM_CHARSET_HEBREW:
-        case DRM_CHARSET_LATIN5:
-        case DRM_CHARSET_LATIN6:
-        case DRM_CHARSET_THAI:
-        case DRM_CHARSET_LATIN7:
-        case DRM_CHARSET_LATIN8:
-        case DRM_CHARSET_LATIN9:
-        case DRM_CHARSET_LATIN10:
-            return wcsToIso8859x(charset, wcs, wcsLen, mbsBuf, bufSizeInByte);
-#endif
-        default:
-            return -1;
-    }
-
-    if (mbsBuf) {
-        while (numMultiBytes < bufSizeInByte && charIndex < wcsLen) {
-            /* TODO: handle surrogate pair values here */
-            int32_t mbLen = wcToMbFunc(wcs[charIndex],
-                    &mbsBuf[numMultiBytes], bufSizeInByte - numMultiBytes);
-
-            if (numMultiBytes + mbLen > bufSizeInByte) {
-                /* Insufficient buffer. Don't update numMultiBytes */
-                break;
-            }
-            charIndex++;
-            numMultiBytes += mbLen;
-        }
-    } else {
-        while (charIndex < wcsLen) {
-            /* TODO: handle surrogate pair values here */
-            numMultiBytes += wcToMbFunc(wcs[charIndex], NULL, 0);
-            charIndex++;
-        }
-    }
-
-    return numMultiBytes;
-}
-
-
-#ifdef I18N_LATIN1_SUPPORT
-
-int32_t latin1ToWcs(const uint8_t *mbs, int32_t mbsLen,
-        uint16_t *wcsBuf, int32_t bufSizeInWideChar,
-        int32_t *bytesConsumed)
-{
-    int32_t charsToConvert;
-    int32_t len;
-
-    if (wcsBuf == NULL) {
-        return mbsLen;
-    }
-
-    len = charsToConvert = mbsLen > bufSizeInWideChar ? bufSizeInWideChar : mbsLen;
-    if (len < 0)
-        return 0;
-    while (len--) {
-        *wcsBuf++ = *mbs++;
-    }
-
-    if (bytesConsumed)
-        *bytesConsumed = charsToConvert;
-
-    return charsToConvert;
-}
-
-int32_t wcToLatin1(uint16_t wc, uint8_t * mbs, int32_t bufSize)
-{
-    uint8_t ch;
-
-    if (wc < 0x100) {
-        ch = (uint8_t)(wc & 0xff);
-    } else {
-        ch = '?';
-    }
-    if (mbs && bufSize > 0)
-        *mbs = ch;
-    return 1;
-}
-
-#endif /* I18N_LATIN1_SUPPORT */
-
-#ifdef I18N_UTF8_UTF16_SUPPORT
-
-int32_t utf8ToWcs(const uint8_t *mbs, int32_t mbsLen,
-        uint16_t *wcsBuf, int32_t bufSizeInWideChar,
-        int32_t *bytesConsumed)
-{
-    int32_t charsConverted = 0;
-    int32_t i = 0;
-    int32_t wideChar;
-
-    if (wcsBuf == NULL) {
-        /* No conversion but we're still going to calculate bytesConsumed */
-        bufSizeInWideChar = mbsLen * 2;
-    }
-
-    while((i < mbsLen) && (charsConverted < bufSizeInWideChar)) {
-        uint8_t ch = mbs[i];
-        uint8_t ch2, ch3, ch4;
-
-        wideChar = -1;
-
-        if(IS_ASCII(ch)) {
-            wideChar = ch;
-            i++;
-        } else if ((ch & 0xc0) == 0xc0) {
-            int utfStart = i;
-            if ((ch & 0xe0) == 0xc0) {
-                /* 2 byte sequence */
-                if (i + 1 < mbsLen && ((ch2 = mbs[i + 1]) & 0xc0) == 0x80) {
-                    wideChar = (uint16_t)(((ch & 0x1F) << 6) | (ch2 & 0x3F));
-                    i += 2;
-                } else {
-                    /* skip incomplete sequence */
-                    i++;
-                }
-            } else if ((ch & 0xf0) == 0xe0) {
-                /* 3 byte sequence */
-                if (i + 2 < mbsLen
-                        && ((ch2 = mbs[i + 1]) & 0xc0) == 0x80
-                        && ((ch3 = mbs[i + 2]) & 0xc0) == 0x80) {
-                    wideChar = (uint16_t)(((ch & 0x0F) << 12) | ((ch2 & 0x3F) << 6) | (ch3 & 0x3F));
-                    i += 3;
-                } else {
-                    /* skip incomplete sequence (up to 2 bytes) */
-                    i++;
-                    if (i < mbsLen && (mbs[i] & 0xc0) == 0x80)
-                        i++;
-                }
-            } else if ((ch & 0xf8) == 0xf0) {
-                /* 4 byte sequence */
-                if (i + 3 < mbsLen
-                        && ((ch2 = mbs[i + 1]) & 0xc0) == 0x80
-                        && ((ch3 = mbs[i + 2]) & 0xc0) == 0x80
-                        && ((ch4 = mbs[i + 3]) & 0xc0) == 0x80) {
-                    /* FIXME: we do NOT support U+10000 - U+10FFFF for now.
-                     *        leave it as 0xFFFD. */
-                    wideChar = INVALID_UNICODE;
-                    i += 4;
-                } else {
-                    /* skip incomplete sequence (up to 3 bytes) */
-                    i++;
-                    if (i < mbsLen && (mbs[i] & 0xc0) == 0x80) {
-                        i++;
-                        if (i < mbsLen && (mbs[i] & 0xc0) == 0x80) {
-                            i++;
-                        }
-                    }
-                }
-            } else {
-                /* invalid */
-                i++;
-            }
-            if (i >= mbsLen && wideChar == -1) {
-                /* Possible incomplete UTF-8 sequence at the end of mbs.
-                 * Leave it to the caller.
-                 */
-                i = utfStart;
-                break;
-            }
-        } else {
-            /* invalid */
-            i++;
-        }
-        if(wcsBuf) {
-            if (wideChar == -1)
-                wideChar = INVALID_UNICODE;
-            wcsBuf[charsConverted] = (uint16_t)wideChar;
-        }
-        charsConverted++;
-    }
-
-    if (bytesConsumed)
-        *bytesConsumed = i;
-
-    return charsConverted;
-}
-
-int32_t wcToUtf8(uint16_t wc, uint8_t * mbs, int32_t bufSize)
-{
-    if (wc <= 0x7f) {
-        if (mbs && (bufSize >= 1)) {
-            *mbs = (uint8_t)wc;
-        }
-        return 1;
-    } else if (wc <= 0x7ff) {
-        if (mbs && (bufSize >= 2)) {
-            *mbs++ = (uint8_t)((wc >> 6) | 0xc0);
-            *mbs = (uint8_t)((wc & 0x3f) | 0x80);
-        }
-        return 2;
-    } else {
-        if (mbs && (bufSize >= 3)) {
-            *mbs++ = (uint8_t)((wc >> 12) | 0xe0);
-            *mbs++ = (uint8_t)(((wc >> 6) & 0x3f)| 0x80);
-            *mbs = (uint8_t)((wc & 0x3f) | 0x80);
-        }
-        return 3;
-    }
-}
-
-int32_t utf16beToWcs(const uint8_t *mbs, int32_t mbsLen,
-        uint16_t *wcsBuf, int32_t bufSizeInWideChar,
-        int32_t *bytesConsumed)
-{
-    int32_t charsToConvert;
-    int32_t len;
-
-    if (wcsBuf == NULL) {
-        return mbsLen / 2;
-    }
-
-    len = charsToConvert = (mbsLen / 2) > bufSizeInWideChar ? bufSizeInWideChar : (mbsLen / 2);
-    while (len--) {
-        /* TODO: handle surrogate pair values */
-        *wcsBuf++ = (uint16_t)((*mbs << 8) | *(mbs + 1));
-        mbs += 2;
-    }
-
-    if (bytesConsumed)
-        *bytesConsumed = charsToConvert * 2;
-
-    return charsToConvert;
-}
-
-int32_t wcToUtf16be(uint16_t wc, uint8_t * mbs, int32_t bufSize)
-{
-    if (mbs && bufSize >= 2) {
-        /* TODO: handle surrogate pair values */
-        *mbs = (uint8_t)(wc >> 8);
-        *(mbs + 1) = (uint8_t)(wc & 0xff);
-    }
-    return 2;
-}
-
-int32_t utf16leToWcs(const uint8_t *mbs, int32_t mbsLen,
-        uint16_t *wcsBuf, int32_t bufSizeInWideChar,
-        int32_t *bytesConsumed)
-{
-    int32_t charsToConvert;
-    int32_t len;
-
-    if (wcsBuf == NULL) {
-        return mbsLen / 2;
-    }
-
-    len = charsToConvert = (mbsLen / 2) > bufSizeInWideChar ? bufSizeInWideChar : (mbsLen / 2);
-    while (len--) {
-        /* TODO: handle surrogate pair values */
-        *wcsBuf++ = (uint16_t)(*mbs | (*(mbs + 1) << 8));
-        mbs += 2;
-    }
-
-    if (bytesConsumed)
-        *bytesConsumed = charsToConvert * 2;
-
-    return charsToConvert;
-}
-
-int32_t wcToUtf16le(uint16_t wc, uint8_t * mbs, int32_t bufSize)
-{
-    if (mbs && bufSize >= 2) {
-        /* TODO: handle surrogate pair values */
-        *mbs = (uint8_t)(wc & 0xff);
-        *(mbs + 1) = (uint8_t)(wc >> 8);
-    }
-    return 2;
-}
-
-#endif /* I18N_UTF8_UTF16_SUPPORT */
-
diff --git a/media/libdrm/mobile1/src/objmng/drm_rights_manager.c b/media/libdrm/mobile1/src/objmng/drm_rights_manager.c
deleted file mode 100644
index df22327..0000000
--- a/media/libdrm/mobile1/src/objmng/drm_rights_manager.c
+++ /dev/null
@@ -1,688 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <drm_rights_manager.h>
-#include <drm_inner.h>
-#include <drm_file.h>
-#include <drm_i18n.h>
-
-static int32_t drm_getString(uint8_t* string, int32_t len, int32_t handle)
-{
-    int32_t i;
-
-    for (i = 0; i < len; i++) {
-        if (DRM_FILE_FAILURE == DRM_file_read(handle, &string[i], 1))
-            return FALSE;
-        if (string[i] == '\n') {
-            string[i + 1] = '\0';
-            break;
-        }
-    }
-    return TRUE;
-}
-
-static int32_t drm_putString(uint8_t* string, int32_t handle)
-{
-    int32_t i = 0;
-
-    for (i = 0;; i++) {
-        if (string[i] == '\0')
-            break;
-        if (DRM_FILE_FAILURE == DRM_file_write(handle, &string[i], 1))
-            return FALSE;
-    }
-    return TRUE;
-}
-
-static int32_t drm_writeToUidTxt(uint8_t* Uid, int32_t* id)
-{
-    int32_t length;
-    int32_t i;
-    uint8_t idStr[8];
-    int32_t idMax;
-    uint8_t(*uidStr)[256];
-    uint16_t nameUcs2[MAX_FILENAME_LEN];
-    int32_t nameLen;
-    int32_t bytesConsumed;
-    int32_t handle;
-    int32_t fileRes;
-
-    if (*id < 1)
-        return FALSE;
-
-    /* convert in ucs2 */
-    nameLen = strlen(DRM_UID_FILE_PATH);
-    nameLen = DRM_i18n_mbsToWcs(DRM_CHARSET_UTF8,
-                        (uint8_t *)DRM_UID_FILE_PATH,
-                        nameLen,
-                        nameUcs2,
-                        MAX_FILENAME_LEN,
-                        &bytesConsumed);
-    fileRes = DRM_file_open(nameUcs2,
-                        nameLen,
-                        DRM_FILE_MODE_READ,
-                        &handle);
-    if (DRM_FILE_SUCCESS != fileRes) {
-        DRM_file_open(nameUcs2,
-                        nameLen,
-                        DRM_FILE_MODE_WRITE,
-                        &handle);
-        DRM_file_write(handle, (uint8_t *)"0\n", 2);
-        DRM_file_close(handle);
-        DRM_file_open(nameUcs2,
-                        nameLen,
-                        DRM_FILE_MODE_READ,
-                        &handle);
-    }
-
-    if (!drm_getString(idStr, 8, handle)) {
-        DRM_file_close(handle);
-        return FALSE;
-    }
-    idMax = atoi((char *)idStr);
-
-    if (idMax < *id)
-        uidStr = malloc((idMax + 1) * 256);
-    else
-        uidStr = malloc(idMax * 256);
-
-    for (i = 0; i < idMax; i++) {
-        if (!drm_getString(uidStr[i], 256, handle)) {
-            DRM_file_close(handle);
-            free(uidStr);
-            return FALSE;
-        }
-    }
-    length = strlen((char *)Uid);
-    strcpy((char *)uidStr[*id - 1], (char *)Uid);
-    uidStr[*id - 1][length] = '\n';
-    uidStr[*id - 1][length + 1] = '\0';
-    if (idMax < (*id))
-        idMax++;
-    DRM_file_close(handle);
-
-    DRM_file_open(nameUcs2,
-                    nameLen,
-                    DRM_FILE_MODE_WRITE,
-                    &handle);
-    sprintf((char *)idStr, "%d", idMax);
-
-    if (!drm_putString(idStr, handle)) {
-        DRM_file_close(handle);
-        free(uidStr);
-        return FALSE;
-    }
-    if (DRM_FILE_FAILURE == DRM_file_write(handle, (uint8_t *)"\n", 1)) {
-        DRM_file_close(handle);
-        free(uidStr);
-        return FALSE;
-    }
-    for (i = 0; i < idMax; i++) {
-        if (!drm_putString(uidStr[i], handle)) {
-            DRM_file_close(handle);
-            free(uidStr);
-            return FALSE;
-        }
-    }
-    if (DRM_FILE_FAILURE == DRM_file_write(handle, (uint8_t *)"\n", 1)) {
-        DRM_file_close(handle);
-        free(uidStr);
-        return FALSE;
-    }
-    DRM_file_close(handle);
-    free(uidStr);
-    return TRUE;
-}
-
-/* See objmng_files.h */
-int32_t drm_readFromUidTxt(uint8_t* Uid, int32_t* id, int32_t option)
-{
-    int32_t i;
-    uint8_t p[256] = { 0 };
-    uint8_t idStr[8];
-    int32_t idMax = 0;
-    uint16_t nameUcs2[MAX_FILENAME_LEN];
-    int32_t nameLen = 0;
-    int32_t bytesConsumed;
-    int32_t handle;
-    int32_t fileRes;
-
-    if (NULL == id || NULL == Uid)
-        return FALSE;
-
-    DRM_file_startup();
-
-    /* convert in ucs2 */
-    nameLen = strlen(DRM_UID_FILE_PATH);
-    nameLen = DRM_i18n_mbsToWcs(DRM_CHARSET_UTF8,
-                        (uint8_t *)DRM_UID_FILE_PATH,
-                        nameLen,
-                        nameUcs2,
-                        MAX_FILENAME_LEN,
-                        &bytesConsumed);
-    fileRes = DRM_file_open(nameUcs2,
-                        nameLen,
-                        DRM_FILE_MODE_READ,
-                        &handle);
-    if (DRM_FILE_SUCCESS != fileRes) {
-        DRM_file_open(nameUcs2,
-                        nameLen,
-                        DRM_FILE_MODE_WRITE,
-                        &handle);
-        DRM_file_write(handle, (uint8_t *)"0\n", 2);
-        DRM_file_close(handle);
-        DRM_file_open(nameUcs2,
-                        nameLen,
-                        DRM_FILE_MODE_READ,
-                        &handle);
-    }
-
-    if (!drm_getString(idStr, 8, handle)) {
-        DRM_file_close(handle);
-        return FALSE;
-    }
-    idMax = atoi((char *)idStr);
-
-    if (option == GET_UID) {
-        if (*id < 1 || *id > idMax) {
-            DRM_file_close(handle);
-            return FALSE;
-        }
-        for (i = 1; i <= *id; i++) {
-            if (!drm_getString(Uid, 256, handle)) {
-                DRM_file_close(handle);
-                return FALSE;
-            }
-        }
-        DRM_file_close(handle);
-        return TRUE;
-    }
-    if (option == GET_ID) {
-        *id = -1;
-        for (i = 1; i <= idMax; i++) {
-            if (!drm_getString(p, 256, handle)) {
-                DRM_file_close(handle);
-                return FALSE;
-            }
-            if (strstr((char *)p, (char *)Uid) != NULL
-                && strlen((char *)p) == strlen((char *)Uid) + 1) {
-                *id = i;
-                DRM_file_close(handle);
-                return TRUE;
-            }
-            if ((*id == -1) && (strlen((char *)p) < 3))
-                *id = i;
-        }
-        if (*id != -1) {
-            DRM_file_close(handle);
-            return FALSE;
-        }
-        *id = idMax + 1;
-        DRM_file_close(handle);
-        return FALSE;
-    }
-    DRM_file_close(handle);
-    return FALSE;
-}
-
-static int32_t drm_acquireId(uint8_t* uid, int32_t* id)
-{
-    if (TRUE == drm_readFromUidTxt(uid, id, GET_ID))
-        return TRUE;
-
-    drm_writeToUidTxt(uid, id);
-
-    return FALSE; /* The Uid is not exit, then return FALSE indicate it */
-}
-
-int32_t drm_writeOrReadInfo(int32_t id, T_DRM_Rights* Ro, int32_t* RoAmount, int32_t option)
-{
-    uint8_t fullname[MAX_FILENAME_LEN] = {0};
-    int32_t tmpRoAmount;
-    uint16_t nameUcs2[MAX_FILENAME_LEN];
-    int32_t nameLen = 0;
-    int32_t bytesConsumed;
-    int32_t handle;
-    int32_t fileRes;
-
-    sprintf((char *)fullname, ANDROID_DRM_CORE_PATH"%d"EXTENSION_NAME_INFO, id);
-
-    /* convert in ucs2 */
-    nameLen = strlen((char *)fullname);
-    nameLen = DRM_i18n_mbsToWcs(DRM_CHARSET_UTF8,
-                        fullname,
-                        nameLen,
-                        nameUcs2,
-                        MAX_FILENAME_LEN,
-                        &bytesConsumed);
-    fileRes = DRM_file_open(nameUcs2,
-                            nameLen,
-                            DRM_FILE_MODE_READ,
-                            &handle);
-    if (DRM_FILE_SUCCESS != fileRes) {
-        if (GET_ALL_RO == option || GET_A_RO == option)
-            return FALSE;
-
-        if (GET_ROAMOUNT == option) {
-            *RoAmount = -1;
-            return TRUE;
-        }
-    }
-
-    DRM_file_close(handle);
-    DRM_file_open(nameUcs2,
-                nameLen,
-                DRM_FILE_MODE_READ | DRM_FILE_MODE_WRITE,
-                &handle);
-
-    switch(option) {
-    case GET_ROAMOUNT:
-        if (DRM_FILE_FAILURE == DRM_file_read(handle, (uint8_t*)RoAmount, sizeof(int32_t))) {
-            DRM_file_close(handle);
-            return FALSE;
-        }
-        break;
-    case GET_ALL_RO:
-        DRM_file_setPosition(handle, sizeof(int32_t));
-
-        if (DRM_FILE_FAILURE == DRM_file_read(handle, (uint8_t*)Ro, (*RoAmount) * sizeof(T_DRM_Rights))) {
-            DRM_file_close(handle);
-            return FALSE;
-        }
-        break;
-    case SAVE_ALL_RO:
-        if (DRM_FILE_FAILURE == DRM_file_write(handle, (uint8_t*)RoAmount, sizeof(int32_t))) {
-            DRM_file_close(handle);
-            return FALSE;
-        }
-
-        if (NULL != Ro && *RoAmount >= 1) {
-            if (DRM_FILE_FAILURE == DRM_file_write(handle, (uint8_t*) Ro, (*RoAmount) * sizeof(T_DRM_Rights))) {
-                DRM_file_close(handle);
-                return FALSE;
-            }
-        }
-        break;
-    case GET_A_RO:
-        DRM_file_setPosition(handle, sizeof(int32_t) + (*RoAmount - 1) * sizeof(T_DRM_Rights));
-
-        if (DRM_FILE_FAILURE == DRM_file_read(handle, (uint8_t*)Ro, sizeof(T_DRM_Rights))) {
-            DRM_file_close(handle);
-            return FALSE;
-        }
-        break;
-    case SAVE_A_RO:
-        DRM_file_setPosition(handle, sizeof(int32_t) + (*RoAmount - 1) * sizeof(T_DRM_Rights));
-
-        if (DRM_FILE_FAILURE == DRM_file_write(handle, (uint8_t*)Ro, sizeof(T_DRM_Rights))) {
-            DRM_file_close(handle);
-            return FALSE;
-        }
-
-        DRM_file_setPosition(handle, 0);
-        if (DRM_FILE_FAILURE == DRM_file_read(handle, (uint8_t*)&tmpRoAmount, sizeof(int32_t))) {
-            DRM_file_close(handle);
-            return FALSE;
-        }
-        if (tmpRoAmount < *RoAmount) {
-            DRM_file_setPosition(handle, 0);
-            DRM_file_write(handle, (uint8_t*)RoAmount, sizeof(int32_t));
-        }
-        break;
-    default:
-        DRM_file_close(handle);
-        return FALSE;
-    }
-
-    DRM_file_close(handle);
-    return TRUE;
-}
-
-int32_t drm_appendRightsInfo(T_DRM_Rights* rights)
-{
-    int32_t id;
-    int32_t roAmount;
-
-    if (NULL == rights)
-        return FALSE;
-
-    drm_acquireId(rights->uid, &id);
-
-    if (FALSE == drm_writeOrReadInfo(id, NULL, &roAmount, GET_ROAMOUNT))
-        return FALSE;
-
-    if (-1 == roAmount)
-        roAmount = 0;
-
-    /* The RO amount increase */
-    roAmount++;
-
-    /* Save the rights information */
-    if (FALSE == drm_writeOrReadInfo(id, rights, &roAmount, SAVE_A_RO))
-        return FALSE;
-
-    return TRUE;
-}
-
-int32_t drm_getMaxIdFromUidTxt()
-{
-    uint8_t idStr[8];
-    int32_t idMax = 0;
-    uint16_t nameUcs2[MAX_FILENAME_LEN] = {0};
-    int32_t nameLen = 0;
-    int32_t bytesConsumed;
-    int32_t handle;
-    int32_t fileRes;
-
-    /* convert in ucs2 */
-    nameLen = strlen(DRM_UID_FILE_PATH);
-    nameLen = DRM_i18n_mbsToWcs(DRM_CHARSET_UTF8,
-                        (uint8_t *)DRM_UID_FILE_PATH,
-                        nameLen,
-                        nameUcs2,
-                        MAX_FILENAME_LEN,
-                        &bytesConsumed);
-    fileRes = DRM_file_open(nameUcs2,
-                        nameLen,
-                        DRM_FILE_MODE_READ,
-                        &handle);
-
-    /* this means the uid.txt file is not exist, so there is not any DRM object */
-    if (DRM_FILE_SUCCESS != fileRes)
-        return 0;
-
-    if (!drm_getString(idStr, 8, handle)) {
-        DRM_file_close(handle);
-        return -1;
-    }
-    DRM_file_close(handle);
-
-    idMax = atoi((char *)idStr);
-    return idMax;
-}
-
-int32_t drm_removeIdInfoFile(int32_t id)
-{
-    uint8_t filename[MAX_FILENAME_LEN] = {0};
-    uint16_t nameUcs2[MAX_FILENAME_LEN];
-    int32_t nameLen = 0;
-    int32_t bytesConsumed;
-
-    if (id <= 0)
-        return FALSE;
-
-    sprintf((char *)filename, ANDROID_DRM_CORE_PATH"%d"EXTENSION_NAME_INFO, id);
-
-    /* convert in ucs2 */
-    nameLen = strlen((char *)filename);
-    nameLen = DRM_i18n_mbsToWcs(DRM_CHARSET_UTF8,
-                        filename,
-                        nameLen,
-                        nameUcs2,
-                        MAX_FILENAME_LEN,
-                        &bytesConsumed);
-    if (DRM_FILE_SUCCESS != DRM_file_delete(nameUcs2, nameLen))
-        return FALSE;
-
-    return TRUE;
-}
-
-int32_t drm_updateUidTxtWhenDelete(int32_t id)
-{
-    uint16_t nameUcs2[MAX_FILENAME_LEN];
-    int32_t nameLen = 0;
-    int32_t bytesConsumed;
-    int32_t handle;
-    int32_t fileRes;
-    int32_t bufferLen;
-    uint8_t *buffer;
-    uint8_t idStr[8];
-    int32_t idMax;
-
-    if (id <= 0)
-        return FALSE;
-
-    nameLen = strlen(DRM_UID_FILE_PATH);
-    nameLen = DRM_i18n_mbsToWcs(DRM_CHARSET_UTF8,
-                        (uint8_t *)DRM_UID_FILE_PATH,
-                        nameLen,
-                        nameUcs2,
-                        MAX_FILENAME_LEN,
-                        &bytesConsumed);
-    bufferLen = DRM_file_getFileLength(nameUcs2, nameLen);
-    if (bufferLen <= 0)
-        return FALSE;
-
-    buffer = (uint8_t *)malloc(bufferLen);
-    if (NULL == buffer)
-        return FALSE;
-
-    fileRes = DRM_file_open(nameUcs2,
-                            nameLen,
-                            DRM_FILE_MODE_READ,
-                            &handle);
-    if (DRM_FILE_SUCCESS != fileRes) {
-        free(buffer);
-        return FALSE;
-    }
-
-    drm_getString(idStr, 8, handle);
-    idMax = atoi((char *)idStr);
-
-    bufferLen -= strlen((char *)idStr);
-    fileRes = DRM_file_read(handle, buffer, bufferLen);
-    buffer[bufferLen] = '\0';
-    DRM_file_close(handle);
-
-    /* handle this buffer */
-    {
-        uint8_t *pStart, *pEnd;
-        int32_t i, movLen;
-
-        pStart = buffer;
-        pEnd = pStart;
-        for (i = 0; i < id; i++) {
-            if (pEnd != pStart)
-                pStart = ++pEnd;
-            while ('\n' != *pEnd)
-                pEnd++;
-            if (pStart == pEnd)
-                pStart--;
-        }
-        movLen = bufferLen - (pEnd - buffer);
-        memmove(pStart, pEnd, movLen);
-        bufferLen -= (pEnd - pStart);
-    }
-
-    if (DRM_FILE_SUCCESS != DRM_file_delete(nameUcs2, nameLen)) {
-        free(buffer);
-        return FALSE;
-    }
-
-    fileRes = DRM_file_open(nameUcs2,
-        nameLen,
-        DRM_FILE_MODE_WRITE,
-        &handle);
-    if (DRM_FILE_SUCCESS != fileRes) {
-        free(buffer);
-        return FALSE;
-    }
-    sprintf((char *)idStr, "%d", idMax);
-    drm_putString(idStr, handle);
-    DRM_file_write(handle, (uint8_t*)"\n", 1);
-    DRM_file_write(handle, buffer, bufferLen);
-    free(buffer);
-    DRM_file_close(handle);
-    return TRUE;
-}
-
-int32_t drm_getKey(uint8_t* uid, uint8_t* KeyValue)
-{
-    T_DRM_Rights ro;
-    int32_t id, roAmount;
-
-    if (NULL == uid || NULL == KeyValue)
-        return FALSE;
-
-    if (FALSE == drm_readFromUidTxt(uid, &id, GET_ID))
-        return FALSE;
-
-    if (FALSE == drm_writeOrReadInfo(id, NULL, &roAmount, GET_ROAMOUNT))
-        return FALSE;
-
-    if (roAmount <= 0)
-        return FALSE;
-
-    memset(&ro, 0, sizeof(T_DRM_Rights));
-    roAmount = 1;
-    if (FALSE == drm_writeOrReadInfo(id, &ro, &roAmount, GET_A_RO))
-        return FALSE;
-
-    memcpy(KeyValue, ro.KeyValue, DRM_KEY_LEN);
-    return TRUE;
-}
-
-void drm_discardPaddingByte(uint8_t *decryptedBuf, int32_t *decryptedBufLen)
-{
-    int32_t tmpLen = *decryptedBufLen;
-    int32_t i;
-
-    if (NULL == decryptedBuf || *decryptedBufLen < 0)
-        return;
-
-    /* Check whether the last several bytes are padding or not */
-    for (i = 1; i < decryptedBuf[tmpLen - 1]; i++) {
-        if (decryptedBuf[tmpLen - 1 - i] != decryptedBuf[tmpLen - 1])
-            break; /* Not the padding bytes */
-    }
-    if (i == decryptedBuf[tmpLen - 1]) /* They are padding bytes */
-        *decryptedBufLen = tmpLen - i;
-    return;
-}
-
-int32_t drm_aesDecBuffer(uint8_t * Buffer, int32_t * BufferLen, AES_KEY *key)
-{
-    uint8_t dbuf[3 * DRM_ONE_AES_BLOCK_LEN], buf[DRM_ONE_AES_BLOCK_LEN];
-    uint64_t i, len, wlen = DRM_ONE_AES_BLOCK_LEN, curLen, restLen;
-    uint8_t *pTarget, *pTargetHead;
-
-    pTargetHead = Buffer;
-    pTarget = Buffer;
-    curLen = 0;
-    restLen = *BufferLen;
-
-    if (restLen > 2 * DRM_ONE_AES_BLOCK_LEN) {
-        len = 2 * DRM_ONE_AES_BLOCK_LEN;
-    } else {
-        len = restLen;
-    }
-    memcpy(dbuf, Buffer, (size_t)len);
-    restLen -= len;
-    Buffer += len;
-
-    if (len < 2 * DRM_ONE_AES_BLOCK_LEN) { /* The original file is less than one block in length */
-        len -= DRM_ONE_AES_BLOCK_LEN;
-        /* Decrypt from position len to position len + DRM_ONE_AES_BLOCK_LEN */
-        AES_decrypt((dbuf + len), (dbuf + len), key);
-
-        /* Undo the CBC chaining */
-        for (i = 0; i < len; ++i)
-            dbuf[i] ^= dbuf[i + DRM_ONE_AES_BLOCK_LEN];
-
-        /* Output the decrypted bytes */
-        memcpy(pTarget, dbuf, (size_t)len);
-        pTarget += len;
-    } else {
-        uint8_t *b1 = dbuf, *b2 = b1 + DRM_ONE_AES_BLOCK_LEN, *b3 = b2 + DRM_ONE_AES_BLOCK_LEN, *bt;
-
-        for (;;) { /* While some ciphertext remains, prepare to decrypt block b2 */
-            /* Read in the next block to see if ciphertext stealing is needed */
-            b3 = Buffer;
-            if (restLen > DRM_ONE_AES_BLOCK_LEN) {
-                len = DRM_ONE_AES_BLOCK_LEN;
-            } else {
-                len = restLen;
-            }
-            restLen -= len;
-            Buffer += len;
-
-            /* Decrypt the b2 block */
-            AES_decrypt((uint8_t *)b2, buf, key);
-
-            if (len == 0 || len == DRM_ONE_AES_BLOCK_LEN) { /* No ciphertext stealing */
-                /* Unchain CBC using the previous ciphertext block in b1 */
-                for (i = 0; i < DRM_ONE_AES_BLOCK_LEN; ++i)
-                    buf[i] ^= b1[i];
-            } else { /* Partial last block - use ciphertext stealing */
-                wlen = len;
-                /* Produce last 'len' bytes of plaintext by xoring with */
-                /* The lowest 'len' bytes of next block b3 - C[N-1] */
-                for (i = 0; i < len; ++i)
-                    buf[i] ^= b3[i];
-
-                /* Reconstruct the C[N-1] block in b3 by adding in the */
-                /* Last (DRM_ONE_AES_BLOCK_LEN - len) bytes of C[N-2] in b2 */
-                for (i = len; i < DRM_ONE_AES_BLOCK_LEN; ++i)
-                    b3[i] = buf[i];
-
-                /* Decrypt the C[N-1] block in b3 */
-                AES_decrypt((uint8_t *)b3, (uint8_t *)b3, key);
-
-                /* Produce the last but one plaintext block by xoring with */
-                /* The last but two ciphertext block */
-                for (i = 0; i < DRM_ONE_AES_BLOCK_LEN; ++i)
-                    b3[i] ^= b1[i];
-
-                /* Write decrypted plaintext blocks */
-                memcpy(pTarget, b3, DRM_ONE_AES_BLOCK_LEN);
-                pTarget += DRM_ONE_AES_BLOCK_LEN;
-            }
-
-            /* Write the decrypted plaintext block */
-            memcpy(pTarget, buf, (size_t)wlen);
-            pTarget += wlen;
-
-            if (len != DRM_ONE_AES_BLOCK_LEN) {
-                *BufferLen = pTarget - pTargetHead;
-                return 0;
-            }
-
-            /* Advance the buffer pointers */
-            bt = b1, b1 = b2, b2 = b3, b3 = bt;
-        }
-    }
-    return 0;
-}
-
-int32_t drm_updateDcfDataLen(uint8_t* pDcfLastData, uint8_t* keyValue, int32_t* moreBytes)
-{
-    AES_KEY key;
-    int32_t len = DRM_TWO_AES_BLOCK_LEN;
-
-    if (NULL == pDcfLastData || NULL == keyValue)
-        return FALSE;
-
-    AES_set_decrypt_key(keyValue, DRM_KEY_LEN * 8, &key);
-
-    if (drm_aesDecBuffer(pDcfLastData, &len, &key) < 0)
-        return FALSE;
-
-    drm_discardPaddingByte(pDcfLastData, &len);
-
-    *moreBytes = DRM_TWO_AES_BLOCK_LEN - len;
-
-    return TRUE;
-}
diff --git a/media/libdrm/mobile1/src/objmng/drm_time.c b/media/libdrm/mobile1/src/objmng/drm_time.c
deleted file mode 100644
index fceb4952..0000000
--- a/media/libdrm/mobile1/src/objmng/drm_time.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file
- * DRM 1.0 Reference Port: linux implementation of drm_time.c.
- */
-
-#include <objmng/drm_time.h>
-#include <unistd.h>
-
-/* See drm_time.h */
-uint32_t DRM_time_getElapsedSecondsFrom1970(void)
-{
-    return time(NULL);
-}
-
-/* See drm_time.h */
-void DRM_time_sleep(uint32_t ms)
-{
-    usleep(ms * 1000);
-}
-
-/* See drm_time.h */
-void DRM_time_getSysTime(T_DB_TIME_SysTime *time_ptr)
-{
-    time_t t;
-    struct tm *tm_t;
-
-    time(&t);
-    tm_t = gmtime(&t);
-
-    time_ptr->year = tm_t->tm_year + 1900;
-    time_ptr->month = tm_t->tm_mon + 1;
-    time_ptr->day = tm_t->tm_mday;
-    time_ptr->hour = tm_t->tm_hour;
-    time_ptr->min = tm_t->tm_min;
-    time_ptr->sec = tm_t->tm_sec;
-}
diff --git a/media/libdrm/mobile1/src/parser/parser_dcf.c b/media/libdrm/mobile1/src/parser/parser_dcf.c
deleted file mode 100644
index 3eac120..0000000
--- a/media/libdrm/mobile1/src/parser/parser_dcf.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <parser_dcf.h>
-#include <svc_drm.h>
-
-static int32_t drm_parseUintVar(uint8_t * buffer, uint8_t * len)
-{
-    int32_t i;
-    int32_t byteLen;
-    int32_t sum;
-
-    if (NULL == buffer)
-        return DRM_UINT_VAR_ERR;
-
-    byteLen = 0;
-    while ((buffer[byteLen] & UINT_VAR_FLAG) > 0 && byteLen < MAX_UINT_VAR_BYTE) /* UINT_VAR_FLAG == 0x80 */
-        byteLen++;
-
-    if (byteLen >= MAX_UINT_VAR_BYTE) /* MAX_UINT_VAR_BYTE == 5 */
-        return DRM_UINT_VAR_ERR; /* The var int is too large, and that is impossible */
-
-    *len = (uint8_t)(byteLen + 1);
-    sum = buffer[byteLen];
-    for (i = byteLen - 1; i >= 0; i--)
-        sum += ((buffer[i] & UINT_VAR_DATA) << 7 * (byteLen - i)); /* UINT_VAR_DATA == 0x7F */
-
-    return sum;
-}
-
-/* See parser_dcf.h */
-int32_t drm_dcfParser(uint8_t *buffer, int32_t bufferLen, T_DRM_DCF_Info *pDcfInfo,
-                      uint8_t **ppEncryptedData)
-{
-    uint8_t *tmpBuf;
-    uint8_t *pStart, *pEnd;
-    uint8_t *pHeader, *pData;
-    uint8_t varLen;
-
-    if (NULL == buffer || bufferLen <= 0 || NULL == pDcfInfo)
-        return FALSE;
-
-    tmpBuf = buffer;
-    /* 1. Parse the version, content-type and content-url */
-    pDcfInfo->Version = *(tmpBuf++);
-    if (0x01 != pDcfInfo->Version) /* Because it is OMA DRM v1.0, the vension must be 1 */
-        return FALSE;
-
-    pDcfInfo->ContentTypeLen = *(tmpBuf++);
-    if (pDcfInfo->ContentTypeLen >= MAX_CONTENT_TYPE_LEN)
-        return FALSE;
-
-    pDcfInfo->ContentURILen = *(tmpBuf++);
-    if (pDcfInfo->ContentURILen >= MAX_CONTENT_URI_LEN)
-        return FALSE;
-
-    strncpy((char *)pDcfInfo->ContentType, (char *)tmpBuf, pDcfInfo->ContentTypeLen);
-    pDcfInfo->ContentType[MAX_CONTENT_TYPE_LEN - 1] = 0;
-    tmpBuf += pDcfInfo->ContentTypeLen;
-    strncpy((char *)pDcfInfo->ContentURI, (char *)tmpBuf, pDcfInfo->ContentURILen);
-    pDcfInfo->ContentURI[MAX_CONTENT_URI_LEN - 1] = 0;
-    tmpBuf += pDcfInfo->ContentURILen;
-
-    /* 2. Get the headers length and data length */
-    pDcfInfo->HeadersLen = drm_parseUintVar(tmpBuf, &varLen);
-    if (DRM_UINT_VAR_ERR == pDcfInfo->HeadersLen)
-        return FALSE;
-    tmpBuf += varLen;
-    pDcfInfo->DecryptedDataLen = DRM_UNKNOWN_DATA_LEN;
-    pDcfInfo->EncryptedDataLen = drm_parseUintVar(tmpBuf, &varLen);
-    if (DRM_UINT_VAR_ERR == pDcfInfo->EncryptedDataLen)
-        return FALSE;
-    tmpBuf += varLen;
-    pHeader = tmpBuf;
-    tmpBuf += pDcfInfo->HeadersLen;
-    pData = tmpBuf;
-
-    /* 3. Parse the headers */
-    pStart = pHeader;
-    while (pStart < pData) {
-        pEnd = pStart;
-        while ('\r' != *pEnd && pEnd < pData)
-            pEnd++;
-
-        if (0 == strncmp((char *)pStart, HEADER_ENCRYPTION_METHOD, HEADER_ENCRYPTION_METHOD_LEN)) {
-            if ((pEnd - pStart - HEADER_ENCRYPTION_METHOD_LEN) >= MAX_ENCRYPTION_METHOD_LEN)
-                return FALSE;
-            strncpy((char *)pDcfInfo->Encryption_Method,
-                         (char *)(pStart + HEADER_ENCRYPTION_METHOD_LEN),
-                         pEnd - pStart - HEADER_ENCRYPTION_METHOD_LEN);
-            pDcfInfo->Encryption_Method[MAX_ENCRYPTION_METHOD_LEN - 1] = 0;
-        } else if (0 == strncmp((char *)pStart, HEADER_RIGHTS_ISSUER, HEADER_RIGHTS_ISSUER_LEN)) {
-            if ((pEnd - pStart - HEADER_RIGHTS_ISSUER_LEN) >= MAX_RIGHTS_ISSUER_LEN)
-                return FALSE;
-            strncpy((char *)pDcfInfo->Rights_Issuer,
-                         (char *)(pStart + HEADER_RIGHTS_ISSUER_LEN),
-                         pEnd - pStart - HEADER_RIGHTS_ISSUER_LEN);
-            pDcfInfo->Rights_Issuer[MAX_RIGHTS_ISSUER_LEN - 1] = 0;
-        } else if (0 == strncmp((char *)pStart, HEADER_CONTENT_NAME, HEADER_CONTENT_NAME_LEN)) {
-            if ((pEnd - pStart - HEADER_CONTENT_NAME_LEN) >= MAX_CONTENT_NAME_LEN)
-                return FALSE;
-            strncpy((char *)pDcfInfo->Content_Name,
-                         (char *)(pStart + HEADER_CONTENT_NAME_LEN),
-                         pEnd - pStart - HEADER_CONTENT_NAME_LEN);
-            pDcfInfo->Content_Name[MAX_CONTENT_NAME_LEN - 1] = 0;
-        } else if (0 == strncmp((char *)pStart, HEADER_CONTENT_DESCRIPTION, HEADER_CONTENT_DESCRIPTION_LEN)) {
-            if ((pEnd - pStart - HEADER_CONTENT_DESCRIPTION_LEN) >= MAX_CONTENT_DESCRIPTION_LEN)
-                return FALSE;
-            strncpy((char *)pDcfInfo->ContentDescription,
-                         (char *)(pStart + HEADER_CONTENT_DESCRIPTION_LEN),
-                         pEnd - pStart - HEADER_CONTENT_DESCRIPTION_LEN);
-            pDcfInfo->ContentDescription[MAX_CONTENT_DESCRIPTION_LEN - 1] = 0;
-        } else if (0 == strncmp((char *)pStart, HEADER_CONTENT_VENDOR, HEADER_CONTENT_VENDOR_LEN)) {
-            if ((pEnd - pStart - HEADER_CONTENT_VENDOR_LEN) >= MAX_CONTENT_VENDOR_LEN)
-                return FALSE;
-            strncpy((char *)pDcfInfo->ContentVendor,
-                         (char *)(pStart + HEADER_CONTENT_VENDOR_LEN),
-                         pEnd - pStart - HEADER_CONTENT_VENDOR_LEN);
-            pDcfInfo->ContentVendor[MAX_CONTENT_VENDOR_LEN - 1] = 0;
-        } else if (0 == strncmp((char *)pStart, HEADER_ICON_URI, HEADER_ICON_URI_LEN)) {
-            if ((pEnd - pStart - HEADER_ICON_URI_LEN) >= MAX_ICON_URI_LEN)
-                return FALSE;
-            strncpy((char *)pDcfInfo->Icon_URI,
-                         (char *)(pStart + HEADER_ICON_URI_LEN),
-                         pEnd - pStart - HEADER_ICON_URI_LEN);
-            pDcfInfo->Icon_URI[MAX_ICON_URI_LEN - 1] = 0;
-        }
-
-        if ('\n' == *(pEnd + 1))
-            pStart = pEnd + 2;  /* Two bytes: a '\r' and a '\n' */
-        else
-            pStart = pEnd + 1;
-    }
-
-    /* 4. Give out the location of encrypted data */
-    if (NULL != ppEncryptedData)
-        *ppEncryptedData = pData;
-
-    return TRUE;
-}
diff --git a/media/libdrm/mobile1/src/parser/parser_dm.c b/media/libdrm/mobile1/src/parser/parser_dm.c
deleted file mode 100644
index 4b4a2da..0000000
--- a/media/libdrm/mobile1/src/parser/parser_dm.c
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <parser_dm.h>
-#include <parser_dcf.h>
-#include <svc_drm.h>
-#include "log.h"
-
-#define DRM_SKIP_SPACE_TAB(p) while( (*(p) == ' ') || (*(p) == '\t') ) \
-                                  p++
-
-typedef enum _DM_PARSE_STATUS {
-    DM_PARSE_START,
-    DM_PARSING_RIGHTS,
-    DM_PARSING_CONTENT,
-    DM_PARSE_END
-} DM_PARSE_STATUS;
-
-static int drm_strnicmp(const uint8_t* s1, const uint8_t* s2, int32_t n)
-{
-    if (n < 0 || NULL == s1 || NULL == s2)
-        return -1;
-
-    if (n == 0)
-        return 0;
-
-    while (n-- != 0 && tolower(*s1) == tolower(*s2))
-    {
-        if (n == 0 || *s1 == '\0' || *s2 == '\0')
-            break;
-        s1++;
-        s2++;
-    }
-
-    return tolower(*s1) - tolower(*s2);
-}
-
-const uint8_t * drm_strnstr(const uint8_t * str, const uint8_t * strSearch, int32_t len)
-{
-    int32_t i, stringLen;
-
-    if (NULL == str || NULL == strSearch || len <= 0)
-        return NULL;
-
-    stringLen = strlen((char *)strSearch);
-    for (i = 0; i < len - stringLen + 1; i++) {
-        if (str[i] == *strSearch && 0 == memcmp(str + i, strSearch, stringLen))
-            return str + i;
-    }
-    return NULL;
-}
-
-/* See parser_dm.h */
-int32_t drm_parseDM(const uint8_t *buffer, int32_t bufferLen, T_DRM_DM_Info *pDmInfo)
-{
-    const uint8_t *pStart = NULL, *pEnd = NULL;
-    const uint8_t *pBufferEnd;
-    int32_t contentLen, leftLen;
-    DM_PARSE_STATUS status = DM_PARSE_START;
-    int32_t boundaryLen;
-
-    if (NULL == buffer || bufferLen <= 0 || NULL == pDmInfo)
-        return FALSE;
-
-    /* Find the end of the input buffer */
-    pBufferEnd = buffer + bufferLen;
-    leftLen = bufferLen;
-
-    /* Find out the boundary */
-    pStart = drm_strnstr(buffer, (uint8_t *)"--", bufferLen);
-    if (NULL == pStart)
-        return FALSE; /* No boundary error */
-    pEnd = pStart;
-
-    /* Record the boundary */
-    pEnd = drm_strnstr(pStart, (uint8_t *)DRM_NEW_LINE_CRLF, leftLen);
-    /* if can not find the CRLF, return FALSE */
-    if (NULL == pEnd)
-        return FALSE;
-    if ((pEnd - pStart) >= MAX_CONTENT_BOUNDARY_LEN)
-        return FALSE;
-    strncpy((char *)pDmInfo->boundary, (char *)pStart, pEnd - pStart);
-    pDmInfo->boundary[MAX_CONTENT_BOUNDARY_LEN - 1] = 0;
-    boundaryLen = strlen((char *)pDmInfo->boundary) + 2; /* 2 means: '\r' and '\n' */
-
-    pEnd += 2; /* skip the '\r' and '\n' */
-    pStart = pEnd;
-    leftLen = pBufferEnd - pStart;
-    do {
-        pDmInfo->transferEncoding = DRM_MESSAGE_CODING_7BIT; /* According RFC2045 chapter 6.1, the default value should be 7bit.*/
-        strcpy((char *)pDmInfo->contentType, "text/plain");  /* According RFC2045 chapter 5.2, the default value should be "text/plain". */
-
-        /* Deal the header information */
-        while ((('\r' != *pStart) || ('\n' != *(pStart + 1))) && pStart < pBufferEnd) {
-            pEnd = drm_strnstr(pStart, (uint8_t *)DRM_NEW_LINE_CRLF, leftLen);
-            if (NULL == pEnd)
-                return FALSE;
-
-            if (0 != pDmInfo->deliveryType) { /* This means the delivery type has been confirmed */
-                if (0 == strncmp((char *)pStart, HEADERS_TRANSFER_CODING, HEADERS_TRANSFER_CODING_LEN)) {
-                    pStart += HEADERS_TRANSFER_CODING_LEN;
-                    DRM_SKIP_SPACE_TAB(pStart);
-
-                    if (0 == strncmp((char *)pStart, TRANSFER_CODING_TYPE_7BIT, pEnd - pStart))
-                        pDmInfo->transferEncoding = DRM_MESSAGE_CODING_7BIT;
-                    else if (0 == strncmp((char *)pStart, TRANSFER_CODING_TYPE_8BIT, pEnd - pStart))
-                        pDmInfo->transferEncoding = DRM_MESSAGE_CODING_8BIT;
-                    else if (0 == strncmp((char *)pStart, TRANSFER_CODING_TYPE_BINARY, pEnd - pStart))
-                        pDmInfo->transferEncoding = DRM_MESSAGE_CODING_BINARY;
-                    else if (0 == strncmp((char *)pStart, TRANSFER_CODING_TYPE_BASE64, pEnd - pStart))
-                        pDmInfo->transferEncoding = DRM_MESSAGE_CODING_BASE64;
-                    else
-                        return FALSE; /* Unknown transferCoding error */
-                } else if (0 == drm_strnicmp(pStart, (uint8_t *)HEADERS_CONTENT_TYPE, HEADERS_CONTENT_TYPE_LEN)) {
-                    pStart += HEADERS_CONTENT_TYPE_LEN;
-                    DRM_SKIP_SPACE_TAB(pStart);
-
-                    if (pEnd - pStart > 0) {
-                        if ((pEnd - pStart) >= MAX_CONTENT_TYPE_LEN)
-                            return FALSE;
-                        strncpy((char *)pDmInfo->contentType, (char *)pStart, pEnd - pStart);
-                        pDmInfo->contentType[pEnd - pStart] = '\0';
-                    }
-                } else if (0 == drm_strnicmp(pStart, (uint8_t *)HEADERS_CONTENT_ID, HEADERS_CONTENT_ID_LEN)) {
-                    uint8_t tmpBuf[MAX_CONTENT_ID] = {0};
-                    uint8_t *pTmp;
-
-                    pStart += HEADERS_CONTENT_ID_LEN;
-                    DRM_SKIP_SPACE_TAB(pStart);
-
-                    /* error: more than one content id */
-                    if(drm_strnstr(pStart, (uint8_t*)HEADERS_CONTENT_ID, pBufferEnd - pStart)){
-                        ALOGD("drm_dmParser: error: more than one content id\r\n");
-                        return FALSE;
-                    }
-
-                    status = DM_PARSING_CONTENT; /* can go here means that the rights object has been parsed. */
-
-                    /* Change the format from <...> to cid:... */
-                    if (NULL != (pTmp = (uint8_t *)memchr((char *)pStart, '<', pEnd - pStart))) {
-                        if ((pEnd - pTmp - 1) >= (int) sizeof(tmpBuf))
-                            return FALSE;
-                        strncpy((char *)tmpBuf, (char *)(pTmp + 1), pEnd - pTmp - 1);
-                        tmpBuf[MAX_CONTENT_ID - 1] = 0;
-
-                        if (NULL != (pTmp = (uint8_t *)memchr((char *)tmpBuf, '>', pEnd - pTmp - 1))) {
-                            *pTmp = '\0';
-
-                            memset(pDmInfo->contentID, 0, MAX_CONTENT_ID);
-                            snprintf((char *)pDmInfo->contentID, MAX_CONTENT_ID, "%s%s", "cid:", (int8_t *)tmpBuf);
-                        }
-                    }
-                }
-            } else { /* First confirm delivery type, Forward_Lock, Combined Delivery or Separate Delivery */
-                if (0 == drm_strnicmp(pStart, (uint8_t *)HEADERS_CONTENT_TYPE, HEADERS_CONTENT_TYPE_LEN)) {
-                    pStart += HEADERS_CONTENT_TYPE_LEN;
-                    DRM_SKIP_SPACE_TAB(pStart);
-
-                    if (pEnd - pStart > 0) {
-                        strncpy((char *)pDmInfo->contentType, (char *)pStart, pEnd - pStart);
-                        pDmInfo->contentType[pEnd - pStart] = '\0';
-                    }
-
-                    if (0 == strcmp((char *)pDmInfo->contentType, DRM_MIME_TYPE_RIGHTS_XML)) {
-                        pDmInfo->deliveryType = COMBINED_DELIVERY;
-                        status = DM_PARSING_RIGHTS;
-                    }
-                    else if (0 == strcmp((char *)pDmInfo->contentType, DRM_MIME_TYPE_CONTENT)) {
-                        pDmInfo->deliveryType = SEPARATE_DELIVERY_FL;
-                        status = DM_PARSING_CONTENT;
-                    }
-                    else if (0 == pDmInfo->deliveryType) {
-                        pDmInfo->deliveryType = FORWARD_LOCK;
-                        status = DM_PARSING_CONTENT;
-                    }
-                }
-            }
-            pEnd += 2; /* skip the '\r' and '\n' */
-            pStart = pEnd;
-            leftLen = pBufferEnd - pStart;
-        }
-        pStart += 2; /* skip the second CRLF: "\r\n" */
-        pEnd = pStart;
-
-        /* Deal the content part, including rel or real content */
-        while (leftLen > 0) {
-            if (NULL == (pEnd = memchr(pEnd, '\r', leftLen))) {
-                pEnd = pBufferEnd;
-                break; /* no boundary found */
-            }
-
-            leftLen = pBufferEnd - pEnd;
-            if (leftLen < boundaryLen) {
-                pEnd = pBufferEnd;
-                break; /* here means may be the boundary has been split */
-            }
-
-            if (('\n' == *(pEnd + 1)) && (0 == memcmp(pEnd + 2, pDmInfo->boundary, strlen((char *)pDmInfo->boundary))))
-                break; /* find the boundary here */
-
-            pEnd++;
-            leftLen--;
-        }
-
-        if (pEnd >= pBufferEnd)
-            contentLen = DRM_UNKNOWN_DATA_LEN;
-        else
-            contentLen = pEnd - pStart;
-
-        switch(pDmInfo->deliveryType) {
-        case FORWARD_LOCK:
-            pDmInfo->contentLen = contentLen;
-            pDmInfo->contentOffset = pStart - buffer;
-            status = DM_PARSE_END;
-            break;
-        case COMBINED_DELIVERY:
-            if (DM_PARSING_RIGHTS == status) {
-                pDmInfo->rightsLen = contentLen;
-                pDmInfo->rightsOffset = pStart - buffer;
-            } else {
-                pDmInfo->contentLen = contentLen;
-                pDmInfo->contentOffset = pStart - buffer;
-                status = DM_PARSE_END;
-            }
-            break;
-        case SEPARATE_DELIVERY_FL:
-            {
-                T_DRM_DCF_Info dcfInfo;
-                uint8_t* pEncData = NULL;
-
-                memset(&dcfInfo, 0, sizeof(T_DRM_DCF_Info));
-                if (DRM_UNKNOWN_DATA_LEN == contentLen)
-                    contentLen = pEnd - pStart;
-                if (FALSE == drm_dcfParser(pStart, contentLen, &dcfInfo, &pEncData))
-                    return FALSE;
-
-                pDmInfo->contentLen = dcfInfo.EncryptedDataLen;
-                pDmInfo->contentOffset = pEncData - buffer;
-                strcpy((char *)pDmInfo->contentType, (char *)dcfInfo.ContentType);
-                strcpy((char *)pDmInfo->contentID, (char *)dcfInfo.ContentURI);
-                strcpy((char *)pDmInfo->rightsIssuer, (char *)dcfInfo.Rights_Issuer);
-                status = DM_PARSE_END;
-            }
-            break;
-        default:
-            return FALSE;
-        }
-
-        if (DM_PARSING_RIGHTS == status) {
-            /* Here means the rights object data has been completed, boundary must exist */
-            leftLen = pBufferEnd - pEnd;
-            pStart = drm_strnstr(pEnd, pDmInfo->boundary, leftLen);
-            if (NULL == pStart)
-                return FALSE;
-            leftLen = pBufferEnd - pStart;
-            pEnd = drm_strnstr(pStart, (uint8_t *)DRM_NEW_LINE_CRLF, leftLen);
-            if (NULL == pEnd)
-                return FALSE; /* only rights object, no media object, error */
-
-            pEnd += 2; /* skip the "\r\n" */
-            pStart = pEnd;
-        }
-    } while (DM_PARSE_END != status);
-
-    return TRUE;
-}
diff --git a/media/libdrm/mobile1/src/parser/parser_rel.c b/media/libdrm/mobile1/src/parser/parser_rel.c
deleted file mode 100644
index 537fa9ce..0000000
--- a/media/libdrm/mobile1/src/parser/parser_rel.c
+++ /dev/null
@@ -1,663 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <parser_rel.h>
-#include <parser_dm.h>
-#include <xml_tinyParser.h>
-#include <wbxml_tinyparser.h>
-#include <drm_decoder.h>
-#include <svc_drm.h>
-
-/* See parser_rel.h */
-int32_t drm_monthDays(int32_t year, int32_t month)
-{
-    switch (month) {
-    case 1:
-    case 3:
-    case 5:
-    case 7:
-    case 8:
-    case 10:
-    case 12:
-        return 31;
-    case 4:
-    case 6:
-    case 9:
-    case 11:
-        return 30;
-    case 2:
-        if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0))
-            return 29;
-        else
-            return 28;
-    default:
-        return -1;
-    }
-}
-
-int32_t drm_checkDate(int32_t year, int32_t month, int32_t day,
-                      int32_t hour, int32_t min, int32_t sec)
-{
-    if (month >= 1 && month <= 12 &&
-        day >= 1 && day <= drm_monthDays(year, month) &&
-        hour >= 0 && hour <= 23 &&
-        min >= 0 && min <= 59 && sec >= 0 && sec <= 59)
-        return 0;
-    else
-        return -1;
-}
-
-static int32_t drm_getStartEndTime(uint8_t * pValue, int32_t valueLen,
-                                   T_DRM_DATETIME * dateTime)
-{
-    int32_t year, mon, day, hour, min, sec;
-    uint8_t pTmp[64] = {0};
-
-    strncpy((char *)pTmp, (char *)pValue, valueLen);
-    {
-        uint8_t * pHead = pTmp;
-        uint8_t * pEnd = NULL;
-        uint8_t tmpByte;
-
-        /** get year */
-        pEnd = (uint8_t *)strstr((char *)pHead, "-");
-        if(NULL == pEnd)
-            return FALSE;
-        tmpByte = *pEnd;
-        *pEnd = '\0';
-        year = atoi((char *)pHead);
-        pHead = pEnd + 1;
-        *pEnd = tmpByte;
-
-        /** get month */
-        pEnd = (uint8_t *)strstr((char *)pHead, "-");
-        if(NULL == pEnd)
-            return FALSE;
-        tmpByte = *pEnd;
-        *pEnd = '\0';
-        mon = atoi((char *)pHead);
-        pHead = pEnd + 1;
-        *pEnd = tmpByte;
-
-        /** get day */
-        pEnd = (uint8_t *)strstr((char *)pHead, "T");
-        if(NULL == pEnd)
-            return FALSE;
-        tmpByte = *pEnd;
-        *pEnd = '\0';
-        day = atoi((char *)pHead);
-        pHead = pEnd + 1;
-        *pEnd = tmpByte;
-
-        /** get hour */
-        pEnd = (uint8_t *)strstr((char *)pHead, ":");
-        if(NULL == pEnd)
-            return FALSE;
-        tmpByte = *pEnd;
-        *pEnd = '\0';
-        hour = atoi((char *)pHead);
-        pHead = pEnd + 1;
-        *pEnd = tmpByte;
-
-        /** get minute */
-        pEnd = (uint8_t *)strstr((char *)pHead, ":");
-        if(NULL == pEnd)
-            return FALSE;
-        tmpByte = *pEnd;
-        *pEnd = '\0';
-        min = atoi((char *)pHead);
-        pHead = pEnd + 1;
-        *pEnd = tmpByte;
-
-        /** get second */
-        sec = atoi((char *)pHead);
-    }
-    if (0 != drm_checkDate(year, mon, day, hour, min, sec))
-        return FALSE;
-
-    YMD_HMS_2_INT(year, mon, day, dateTime->date, hour, min, sec,
-                  dateTime->time);
-    return TRUE;
-}
-
-static int32_t drm_checkWhetherHasUnknowConstraint(uint8_t* drm_constrain)
-{
-    char* begin_constrain = "<o-ex:constraint>";
-    char* end_constrain = "</o-ex:constraint>";
-    char* constrain_begin = strstr((char*)drm_constrain,begin_constrain);
-    char* constrain_end = strstr((char*)drm_constrain,end_constrain);
-    uint32_t constrain_len = 0;
-
-    if(NULL == constrain_begin)
-        return FALSE;
-
-    if(NULL == constrain_end)
-        return TRUE;
-
-    /* compute valid characters length */
-    {
-        uint32_t constrain_begin_len = strlen(begin_constrain);
-        char* cur_pos = constrain_begin + constrain_begin_len;
-
-        constrain_len = (constrain_end - constrain_begin) - constrain_begin_len;
-
-        while(cur_pos < constrain_end){
-            if(isspace(*cur_pos))
-                constrain_len--;
-
-            cur_pos++;
-        }
-    }
-
-    /* check all constraints */
-    {
-        #define DRM_ALL_CONSTRAINT_COUNT 5
-
-        int32_t i = 0;
-        int32_t has_datetime = FALSE;
-        int32_t has_start_or_end = FALSE;
-
-        char* all_vaild_constraints[DRM_ALL_CONSTRAINT_COUNT][2] = {
-            {"<o-dd:count>","</o-dd:count>"},
-            {"<o-dd:interval>","</o-dd:interval>"},
-            {"<o-dd:datetime>","</o-dd:datetime>"},
-            {"<o-dd:start>","</o-dd:start>"},
-            {"<o-dd:end>","</o-dd:end>"}
-        };
-
-        for(i = 0; i < DRM_ALL_CONSTRAINT_COUNT; i++){
-            char*start = strstr((char*)drm_constrain,all_vaild_constraints[i][0]);
-
-            if(start && (start < constrain_end)){
-                char* end = strstr((char*)drm_constrain,all_vaild_constraints[i][1]);
-
-                if(end && (end < constrain_end)){
-                    if(0 == strncmp(all_vaild_constraints[i][0],"<o-dd:datetime>",strlen("<o-dd:datetime>"))){
-                        constrain_len -= strlen(all_vaild_constraints[i][0]);
-                        constrain_len -= strlen(all_vaild_constraints[i][1]);
-
-                        if(0 == constrain_len)
-                            return TRUE;
-
-                        has_datetime = TRUE;
-                        continue;
-                    }
-
-                    if((0 == strncmp(all_vaild_constraints[i][0],"<o-dd:start>",strlen("<o-dd:start>")))
-                        || (0 == strncmp(all_vaild_constraints[i][0],"<o-dd:end>",strlen("<o-dd:end>")))){
-                        if(FALSE == has_datetime)
-                            return TRUE;
-                        else
-                            has_start_or_end = TRUE;
-                    }
-
-                    constrain_len -= (end - start);
-                    constrain_len -= strlen(all_vaild_constraints[i][1]);
-
-                    if(0 == constrain_len)
-                        if(has_datetime != has_start_or_end)
-                            return TRUE;
-                        else
-                            return FALSE;
-                }
-                else
-                    return TRUE;
-            }
-        }
-
-        if(has_datetime != has_start_or_end)
-            return TRUE;
-
-        if(constrain_len)
-            return TRUE;
-        else
-            return FALSE;
-    }
-}
-
-static int32_t drm_getRightValue(uint8_t * buffer, int32_t bufferLen,
-                                 T_DRM_Rights * ro, uint8_t * operation,
-                                 uint8_t oper_char)
-{
-    uint8_t *pBuf, *pValue;
-    uint8_t sProperty[256];
-    int32_t valueLen;
-    int32_t year, mon, day, hour, min, sec;
-    T_DRM_Rights_Constraint *pConstraint;
-    int32_t *bIsAble;
-    uint8_t *ret = NULL;
-    int32_t flag = 0;
-
-    if (operation == NULL) {
-        switch (oper_char) {
-        case REL_TAG_PLAY:
-            pConstraint = &(ro->PlayConstraint);
-            bIsAble = &(ro->bIsPlayable);
-            break;
-        case REL_TAG_DISPLAY:
-            pConstraint = &(ro->DisplayConstraint);
-            bIsAble = &(ro->bIsDisplayable);
-            break;
-        case REL_TAG_EXECUTE:
-            pConstraint = &(ro->ExecuteConstraint);
-            bIsAble = &(ro->bIsExecuteable);
-            break;
-        case REL_TAG_PRINT:
-            pConstraint = &(ro->PrintConstraint);
-            bIsAble = &(ro->bIsPrintable);
-            break;
-        default:
-            return FALSE; /* The input parm is err */
-        }
-    } else {
-        if (strcmp((char *)operation, "play") == 0) {
-            pConstraint = &(ro->PlayConstraint);
-            bIsAble = &(ro->bIsPlayable);
-        } else if (strcmp((char *)operation, "display") == 0) {
-            pConstraint = &(ro->DisplayConstraint);
-            bIsAble = &(ro->bIsDisplayable);
-        } else if (strcmp((char *)operation, "execute") == 0) {
-            pConstraint = &(ro->ExecuteConstraint);
-            bIsAble = &(ro->bIsExecuteable);
-        } else if (strcmp((char *)operation, "print") == 0) {
-            pConstraint = &(ro->PrintConstraint);
-            bIsAble = &(ro->bIsPrintable);
-        } else
-            return FALSE; /* The input parm is err */
-    }
-
-    if (operation == NULL) {
-        sprintf((char *)sProperty, "%c%c%c%c", REL_TAG_RIGHTS,
-                     REL_TAG_AGREEMENT, REL_TAG_PERMISSION, oper_char);
-        ret = WBXML_DOM_getNode(buffer, bufferLen, sProperty);
-    } else {
-        sprintf((char *)sProperty,
-                     "o-ex:rights\\o-ex:agreement\\o-ex:permission\\o-dd:%s",
-                     operation);
-        ret = XML_DOM_getNode(buffer, sProperty);
-    }
-    CHECK_VALIDITY(ret);
-    if (NULL == ret)
-        return TRUE;
-    WRITE_RO_FLAG(*bIsAble, 1, pConstraint->Indicator, DRM_NO_CONSTRAINT); /* If exit first assume have utter rights */
-    flag = 1;
-
-    if (operation == NULL) { /* If father element node is not exit then return */
-        sprintf((char *)sProperty, "%c%c%c%c%c", REL_TAG_RIGHTS,
-                     REL_TAG_AGREEMENT, REL_TAG_PERMISSION, oper_char,
-                     REL_TAG_CONSTRAINT);
-        ret = WBXML_DOM_getNode(buffer, bufferLen, sProperty);
-    } else {
-        sprintf((char *)sProperty,
-                     "o-ex:rights\\o-ex:agreement\\o-ex:permission\\o-dd:%s\\o-ex:constraint",
-                     operation);
-        ret = XML_DOM_getNode(buffer, sProperty);
-    }
-
-    CHECK_VALIDITY(ret);
-    if (ret == NULL)
-        return TRUE;
-
-    if(TRUE == drm_checkWhetherHasUnknowConstraint(ret))
-        return FALSE;
-
-    *bIsAble = 0;
-    pConstraint->Indicator = DRM_NO_PERMISSION; /* If exit constraint assume have no rights */
-    flag = 2;
-
-    if (operation == NULL) {
-        sprintf((char *)sProperty, "%c%c%c%c%c%c", REL_TAG_RIGHTS,
-                     REL_TAG_AGREEMENT, REL_TAG_PERMISSION, oper_char,
-                     REL_TAG_CONSTRAINT, REL_TAG_INTERVAL);
-        pBuf =
-            WBXML_DOM_getNodeValue(buffer, bufferLen, sProperty, (uint8_t **)&pValue,
-                                   &valueLen);
-    } else {
-        sprintf((char *)sProperty,
-                     "o-ex:rights\\o-ex:agreement\\o-ex:permission\\o-dd:%s\\o-ex:constraint\\o-dd:interval",
-                     operation);
-        pBuf = XML_DOM_getNodeValue(buffer, sProperty, &pValue, &valueLen);
-    }
-    CHECK_VALIDITY(pBuf);
-    if (pBuf) { /* If interval element exit then get the value */
-        uint8_t pTmp[64] = {0};
-
-        strncpy((char *)pTmp, (char *)pValue, valueLen);
-        {
-            uint8_t * pHead = pTmp + 1;
-            uint8_t * pEnd = NULL;
-            uint8_t tmpChar;
-
-            /** get year */
-            pEnd = (uint8_t *)strstr((char *)pHead, "Y");
-            if(NULL == pEnd)
-                return FALSE;
-            tmpChar = *pEnd;
-            *pEnd = '\0';
-            year = atoi((char *)pHead);
-            pHead = pEnd + 1;
-            *pEnd = tmpChar;
-
-            /** get month */
-            pEnd = (uint8_t *)strstr((char *)pHead, "M");
-            if(NULL == pEnd)
-                return FALSE;
-            tmpChar = *pEnd;
-            *pEnd = '\0';
-            mon = atoi((char *)pHead);
-            pHead = pEnd + 1;
-            *pEnd = tmpChar;
-
-            /** get day */
-            pEnd = (uint8_t *)strstr((char *)pHead, "D");
-            if(NULL == pEnd)
-                return FALSE;
-            tmpChar = *pEnd;
-            *pEnd = '\0';
-            day = atoi((char *)pHead);
-            pHead = pEnd + 2;
-            *pEnd = tmpChar;
-
-            /** get hour */
-            pEnd = (uint8_t *)strstr((char *)pHead, "H");
-            if(NULL == pEnd)
-                return FALSE;
-            tmpChar = *pEnd;
-            *pEnd = '\0';
-            hour = atoi((char *)pHead);
-            pHead = pEnd + 1;
-            *pEnd = tmpChar;
-
-            /** get minute */
-            pEnd = (uint8_t *)strstr((char *)pHead, "M");
-            if(NULL == pEnd)
-                return FALSE;
-            tmpChar = *pEnd;
-            *pEnd = '\0';
-            min = atoi((char *)pHead);
-            pHead = pEnd + 1;
-            *pEnd = tmpChar;
-
-            /** get second */
-            pEnd = (uint8_t *)strstr((char *)pHead, "S");
-            if(NULL == pEnd)
-                return FALSE;
-            tmpChar = *pEnd;
-            *pEnd = '\0';
-            sec = atoi((char *)pHead);
-            pHead = pEnd + 1;
-            *pEnd = tmpChar;
-        }
-
-        if (year < 0 || mon < 0 || day < 0 || hour < 0
-            || min < 0 || sec < 0)
-            return FALSE;
-        YMD_HMS_2_INT(year, mon, day, pConstraint->Interval.date, hour,
-                      min, sec, pConstraint->Interval.time);
-        WRITE_RO_FLAG(*bIsAble, 1, pConstraint->Indicator,
-                      DRM_INTERVAL_CONSTRAINT);
-        flag = 3;
-    }
-
-    if (operation == NULL) {
-        sprintf((char *)sProperty, "%c%c%c%c%c%c", REL_TAG_RIGHTS,
-                     REL_TAG_AGREEMENT, REL_TAG_PERMISSION, oper_char,
-                     REL_TAG_CONSTRAINT, REL_TAG_COUNT);
-        pBuf =
-            WBXML_DOM_getNodeValue(buffer, bufferLen, sProperty, (uint8_t **)&pValue,
-                                   &valueLen);
-    } else {
-        sprintf((char *)sProperty,
-                     "o-ex:rights\\o-ex:agreement\\o-ex:permission\\o-dd:%s\\o-ex:constraint\\o-dd:count",
-                     operation);
-        pBuf = XML_DOM_getNodeValue(buffer, sProperty, &pValue, &valueLen);
-    }
-    CHECK_VALIDITY(pBuf);
-    if (pBuf) { /* If count element exit the  get the value */
-        uint8_t pTmp[16] = {0};
-        int32_t i;
-
-        for (i = 0; i < valueLen; i++) { /* Check the count format */
-            if (0 == isdigit(*(pValue + i)))
-                return FALSE;
-        }
-
-        strncpy((char *)pTmp, (char *)pValue, valueLen);
-        pConstraint->Count = atoi((char *)pTmp);
-
-    if(0 == pConstraint->Count)
-    {
-      WRITE_RO_FLAG(*bIsAble, 0, pConstraint->Indicator, DRM_NO_PERMISSION);
-    }
-    else if( pConstraint->Count > 0)
-    {
-      WRITE_RO_FLAG(*bIsAble, 1, pConstraint->Indicator, DRM_COUNT_CONSTRAINT);
-    }
-    else  /* < 0 */
-    {
-       return FALSE;
-    }
-
-        flag = 3;
-    }
-
-    if (operation == NULL) {
-        sprintf((char *)sProperty, "%c%c%c%c%c%c%c", REL_TAG_RIGHTS,
-                     REL_TAG_AGREEMENT, REL_TAG_PERMISSION, oper_char,
-                     REL_TAG_CONSTRAINT, REL_TAG_DATETIME, REL_TAG_START);
-        pBuf =
-            WBXML_DOM_getNodeValue(buffer, bufferLen, sProperty, (uint8_t **)&pValue,
-                                   &valueLen);
-    } else {
-        sprintf((char *)sProperty,
-                     "o-ex:rights\\o-ex:agreement\\o-ex:permission\\o-dd:%s\\o-ex:constraint\\o-dd:datetime\\o-dd:start",
-                     operation);
-        pBuf = XML_DOM_getNodeValue(buffer, sProperty, &pValue, &valueLen);
-    }
-    CHECK_VALIDITY(pBuf);
-    if (pBuf) { /* If start element exit then get the value */
-        if (FALSE ==
-            drm_getStartEndTime(pValue, valueLen, &pConstraint->StartTime))
-            return FALSE;
-        WRITE_RO_FLAG(*bIsAble, 1, pConstraint->Indicator, DRM_START_TIME_CONSTRAINT);
-        flag = 3;
-    }
-
-    if (operation == NULL) {
-        sprintf((char *)sProperty, "%c%c%c%c%c%c%c", REL_TAG_RIGHTS,
-                     REL_TAG_AGREEMENT, REL_TAG_PERMISSION, oper_char,
-                     REL_TAG_CONSTRAINT, REL_TAG_DATETIME, REL_TAG_END);
-        pBuf =
-            WBXML_DOM_getNodeValue(buffer, bufferLen, sProperty, (uint8_t **)&pValue,
-                                   &valueLen);
-    } else {
-        sprintf((char *)sProperty,
-                     "o-ex:rights\\o-ex:agreement\\o-ex:permission\\o-dd:%s\\o-ex:constraint\\o-dd:datetime\\o-dd:end",
-                     operation);
-        pBuf = XML_DOM_getNodeValue(buffer, sProperty, &pValue, &valueLen);
-    }
-    CHECK_VALIDITY(pBuf);
-    if (pBuf) {
-        if (FALSE ==
-            drm_getStartEndTime(pValue, valueLen, &pConstraint->EndTime))
-            return FALSE;
-        WRITE_RO_FLAG(*bIsAble, 1, pConstraint->Indicator, DRM_END_TIME_CONSTRAINT);
-        flag = 3;
-    }
-
-    if (2 == flag)
-        WRITE_RO_FLAG(*bIsAble, 1, pConstraint->Indicator, DRM_NO_CONSTRAINT); /* If exit first assume have utter rights */
-    return TRUE;
-}
-
-/* See parser_rel.h */
-int32_t drm_relParser(uint8_t* buffer, int32_t bufferLen, int32_t Format, T_DRM_Rights* pRights)
-{
-    uint8_t *pBuf, *pValue;
-    uint8_t sProperty[256];
-    int32_t valueLen;
-
-    if (TYPE_DRM_RIGHTS_WBXML != Format && TYPE_DRM_RIGHTS_XML != Format) /* It is not the support parse format */
-        return FALSE;
-
-    if (TYPE_DRM_RIGHTS_XML == Format) {
-        /* Check whether it is a CD, and parse it using TYPE_DRM_RIGHTS_XML */
-        if (NULL != drm_strnstr(buffer, (uint8_t *)HEADERS_CONTENT_ID, bufferLen))
-            return FALSE;
-
-        pBuf =
-            XML_DOM_getNodeValue(buffer,
-                                 (uint8_t *)"o-ex:rights\\o-ex:context\\o-dd:version",
-                                 &pValue, &valueLen);
-        CHECK_VALIDITY(pBuf);
-
-        if (pBuf) {
-            if (valueLen > 8) /* Check version lenth */
-                return FALSE;
-
-           /* error version */
-           if(strncmp(pValue,"1.0",valueLen))
-                return FALSE;
-
-            strncpy((char *)pRights->Version, (char *)pValue, valueLen);
-        } else
-            return FALSE;
-
-        /* this means there is more than one version label in rights */
-        if(strstr((char*)pBuf, "<o-dd:version>"))
-            return FALSE;
-
-        pBuf =
-            XML_DOM_getNodeValue(buffer,
-                                 (uint8_t *)"o-ex:rights\\o-ex:agreement\\o-ex:asset\\ds:KeyInfo\\ds:KeyValue",
-                                 &pValue, &valueLen);
-        CHECK_VALIDITY(pBuf);
-        if (pBuf) { /* Get keyvalue */
-            int32_t keyLen;
-
-            if (24 != valueLen)
-                return FALSE;
-
-            keyLen = drm_decodeBase64(NULL, 0, pValue, &valueLen);
-            if (keyLen < 0)
-                return FALSE;
-
-            if (DRM_KEY_LEN != drm_decodeBase64(pRights->KeyValue, keyLen, pValue, &valueLen))
-                return FALSE;
-        }
-
-        pBuf =
-            XML_DOM_getNodeValue(buffer,
-                                 (uint8_t *)"o-ex:rights\\o-ex:agreement\\o-ex:asset\\o-ex:context\\o-dd:uid",
-                                 &pValue, &valueLen);
-        CHECK_VALIDITY(pBuf);
-        if (pBuf) {
-            if (valueLen > DRM_UID_LEN)
-                return FALSE;
-            strncpy((char *)pRights->uid, (char *)pValue, valueLen);
-            pRights->uid[valueLen] = '\0';
-        } else
-            return FALSE;
-
-        /* this means there is more than one uid label in rights */
-        if(strstr((char*)pBuf, "<o-dd:uid>"))
-            return FALSE;
-
-        if (FALSE ==
-            drm_getRightValue(buffer, bufferLen, pRights, (uint8_t *)"play", 0))
-            return FALSE;
-
-        if (FALSE ==
-            drm_getRightValue(buffer, bufferLen, pRights, (uint8_t *)"display", 0))
-            return FALSE;
-
-        if (FALSE ==
-            drm_getRightValue(buffer, bufferLen, pRights, (uint8_t *)"execute", 0))
-            return FALSE;
-
-        if (FALSE ==
-            drm_getRightValue(buffer, bufferLen, pRights, (uint8_t *)"print", 0))
-            return FALSE;
-    } else if (TYPE_DRM_RIGHTS_WBXML == Format) {
-        if (!REL_CHECK_WBXML_HEADER(buffer))
-            return FALSE;
-
-        sprintf((char *)sProperty, "%c%c%c", REL_TAG_RIGHTS, REL_TAG_CONTEXT,
-                     REL_TAG_VERSION);
-        pBuf =
-            WBXML_DOM_getNodeValue(buffer, bufferLen, sProperty, (uint8_t **)&pValue,
-                                   &valueLen);
-        CHECK_VALIDITY(pBuf);
-
-        if (pBuf) {
-            if (valueLen > 8) /* Check version lenth */
-                return FALSE;
-            strncpy((char *)pRights->Version, (char *)pValue, valueLen);
-        } else
-            return FALSE;
-
-        sprintf((char *)sProperty, "%c%c%c%c%c",
-                     REL_TAG_RIGHTS, REL_TAG_AGREEMENT, REL_TAG_ASSET,
-                     REL_TAG_KEYINFO, REL_TAG_KEYVALUE);
-        pBuf =
-            WBXML_DOM_getNodeValue(buffer, bufferLen, sProperty, (uint8_t **)&pValue,
-                                   &valueLen);
-        CHECK_VALIDITY(pBuf);
-        if (pBuf) {
-            if (DRM_KEY_LEN != valueLen)
-                return FALSE;
-            memcpy(pRights->KeyValue, pValue, DRM_KEY_LEN);
-            memset(pValue, 0, DRM_KEY_LEN); /* Clean the KeyValue */
-        }
-
-        sprintf((char *)sProperty, "%c%c%c%c%c",
-                     REL_TAG_RIGHTS, REL_TAG_AGREEMENT, REL_TAG_ASSET,
-                     REL_TAG_CONTEXT, REL_TAG_UID);
-        pBuf =
-            WBXML_DOM_getNodeValue(buffer, bufferLen, sProperty, (uint8_t **)&pValue,
-                                   &valueLen);
-        CHECK_VALIDITY(pBuf);
-        if (pBuf) {
-            if (valueLen > DRM_UID_LEN)
-                return FALSE;
-            strncpy((char *)pRights->uid, (char *)pValue, valueLen);
-            pRights->uid[valueLen] = '\0';
-        } else
-            return FALSE;
-
-        if (FALSE ==
-            drm_getRightValue(buffer, bufferLen, pRights, NULL,
-                              REL_TAG_PLAY))
-            return FALSE;
-
-        if (FALSE ==
-            drm_getRightValue(buffer, bufferLen, pRights, NULL,
-                              REL_TAG_DISPLAY))
-            return FALSE;
-
-        if (FALSE ==
-            drm_getRightValue(buffer, bufferLen, pRights, NULL,
-                              REL_TAG_EXECUTE))
-            return FALSE;
-
-        if (FALSE ==
-            drm_getRightValue(buffer, bufferLen, pRights, NULL,
-                              REL_TAG_PRINT))
-            return FALSE;
-    }
-
-    return TRUE;
-}
diff --git a/media/libdrm/mobile1/src/xml/xml_tinyparser.c b/media/libdrm/mobile1/src/xml/xml_tinyparser.c
deleted file mode 100644
index 7580312..0000000
--- a/media/libdrm/mobile1/src/xml/xml_tinyparser.c
+++ /dev/null
@@ -1,834 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <xml/xml_tinyParser.h>
-
-int32_t xml_errno;
-
-#ifdef XML_DOM_PARSER
-
-#define XML_IS_WHITESPACE(x) ((x) == '\t' || (x) == '\n' || (x) == ' ' || (x) == '\r')
-#define XML_IS_NAMECHAR(ch) (isalpha(ch) || isdigit(ch) || ch ==':' || \
-                             ch == '_' || ch == '-' || ch =='.')
-
-static uint8_t *xml_ignore_blank(uint8_t *buffer)
-{
-    if (NULL == buffer)
-        return NULL;
-
-    while (XML_IS_WHITESPACE(*buffer))
-        buffer++;
-
-    return buffer;
-}
-
-static uint8_t *xml_goto_tagend(uint8_t *buffer)
-{
-    int32_t nameLen, valueLen;
-    uint8_t *name, *value;
-
-    if (NULL == buffer)
-        return NULL;
-
-    /* Ignore the start-tag */
-    if (*buffer == '<') {
-        buffer++;
-        while (buffer != NULL && XML_IS_NAMECHAR(*buffer))
-            buffer++;
-        if (NULL == buffer)
-            return NULL;
-    }
-
-    do {
-        if (NULL == (buffer = xml_ignore_blank(buffer)))
-            return NULL;
-
-        if (*buffer == '>' || (*buffer == '/' && *(buffer + 1) == '>'))
-            return buffer;
-
-        if (NULL ==
-            XML_DOM_getAttr(buffer, &name, &nameLen, &value, &valueLen))
-            return NULL;
-
-        buffer = value + valueLen + 1;
-    } while (*buffer != '\0');
-
-    return NULL;
-}
-
-static uint8_t *xml_match_tag(uint8_t *buffer)
-{
-    int32_t tagLen, tagType, bal;
-
-    if (NULL == buffer)
-        return NULL;
-
-    bal = 0;
-    do {
-        if (NULL == (buffer = XML_DOM_getTag(buffer, &tagLen, &tagType)))
-            return NULL;
-
-        switch (tagType) {
-        case XML_TAG_SELF:
-        case XML_TAG_START:
-            if (NULL == (buffer = xml_goto_tagend(buffer + tagLen + 1)))
-                return NULL;
-            if (strncmp((char *)buffer, "/>", 2) == 0) {
-                buffer += 2;
-            } else {
-                bal++;
-            }
-            break;
-
-        case XML_TAG_END:
-            if (bal <= 0)
-                return NULL;
-            buffer = buffer + tagLen + 2;
-            bal--;
-            break;
-        }
-    } while (bal != 0);
-
-    return buffer;
-}
-
-uint8_t *XML_DOM_getAttr(uint8_t *buffer, uint8_t **pName, int32_t *nameLen,
-                      uint8_t **pValue, int32_t *valueLen)
-{
-    uint8_t charQuoted;
-
-    if (NULL == buffer) {
-        XML_ERROR(XML_ERROR_BUFFER_NULL);
-        return NULL;
-    }
-
-    /* Ignore the tag */
-    if (*buffer == '<') {
-        buffer++;
-        /* Ignore the STag */
-        while (buffer != NULL && XML_IS_NAMECHAR(*buffer))
-            buffer++;
-        if (NULL == buffer)
-            return NULL;
-    }
-
-    if (NULL == (buffer = xml_ignore_blank(buffer))) {
-        XML_ERROR(XML_ERROR_BUFFER_NULL);
-        return NULL;
-    }
-
-    /* Name */
-    *pName = buffer;
-    while (buffer != NULL && XML_IS_NAMECHAR(*buffer))
-        buffer++;
-    if (NULL == buffer) {
-        XML_ERROR(XML_ERROR_ATTR_NAME);
-        return NULL;
-    }
-    *nameLen = buffer - *pName;
-    if (*nameLen <= 0) {
-        XML_ERROR(XML_ERROR_ATTR_NAME);
-        return NULL;
-    }
-
-    /* '=' */
-    buffer = xml_ignore_blank(buffer);
-    if (NULL == buffer || *buffer != '=') {
-        XML_ERROR(XML_ERROR_ATTR_MISSED_EQUAL);
-        return NULL;
-    }
-
-    /* Value */
-    buffer++;
-    buffer = xml_ignore_blank(buffer);
-    if (NULL == buffer || (*buffer != '"' && *buffer != '\'')) {
-        XML_ERROR(XML_ERROR_ATTR_VALUE);
-        return NULL;
-    }
-    charQuoted = *buffer++;
-    *pValue = buffer;
-    while (*buffer != '\0' && *buffer != charQuoted)
-        buffer++;
-    if (*buffer != charQuoted) {
-        XML_ERROR(XML_ERROR_ATTR_VALUE);
-        return NULL;
-    }
-    *valueLen = buffer - *pValue;
-
-    XML_ERROR(XML_ERROR_OK);
-
-    return buffer + 1;
-}
-
-uint8_t *XML_DOM_getValue(uint8_t *buffer, uint8_t **pValue, int32_t *valueLen)
-{
-    uint8_t *pEnd;
-
-    if (NULL == buffer) {
-        XML_ERROR(XML_ERROR_BUFFER_NULL);
-        return NULL;
-    }
-
-    /* Ignore the STag */
-    if (*buffer == '<') {
-        buffer++;
-        /* If it's an end_tag, no value should be returned */
-        if (*buffer == '/') {
-            *valueLen = 0;
-            XML_ERROR(XML_ERROR_NOVALUE);
-            return NULL;
-        }
-
-        while (buffer != NULL && XML_IS_NAMECHAR(*buffer))
-            buffer++;
-        if (NULL == buffer) {
-            XML_ERROR(XML_ERROR_BUFFER_NULL);
-            return NULL;
-        }
-
-        if (NULL == (buffer = xml_goto_tagend(buffer))) {
-            XML_ERROR(XML_ERROR_PROPERTY_END);
-            return NULL;
-        }
-    }
-
-    /* <test/> node found */
-    if (*buffer == '/') {
-        if (*(buffer + 1) != '>') {
-            XML_ERROR(XML_ERROR_PROPERTY_END);
-            return NULL;
-        }
-        XML_ERROR(XML_ERROR_OK);
-        *valueLen = 0;
-        return buffer;
-    }
-
-    if (*buffer == '>')
-        buffer++;
-
-    if (NULL == (buffer = xml_ignore_blank(buffer))) {
-        XML_ERROR(XML_ERROR_BUFFER_NULL);
-        return NULL;
-    }
-
-    /* the following is a tag instead of the value */
-    if (*buffer == '<') { /* nono value, such as <test></test> */
-        buffer++;
-        if (*buffer != '/') {
-            XML_ERROR(XML_ERROR_ENDTAG);
-            return NULL;
-        }
-        *valueLen = 0;
-        XML_ERROR(XML_ERROR_OK);
-        return NULL;
-    }
-
-    *pValue = buffer;
-    pEnd = NULL;
-    while (*buffer != '\0' && *buffer != '<') {
-        if (!XML_IS_WHITESPACE(*buffer))
-            pEnd = buffer;
-        buffer++;
-    }
-    if (*buffer != '<' || pEnd == NULL) {
-        XML_ERROR(XML_ERROR_VALUE);
-        return NULL;
-    }
-
-    *valueLen = pEnd - *pValue + 1;
-
-    buffer++;
-    if (*buffer != '/') {
-        XML_ERROR(XML_ERROR_ENDTAG);
-        return NULL;
-    }
-
-    XML_ERROR(XML_ERROR_OK);
-
-    return buffer - 1;
-}
-
-uint8_t *XML_DOM_getTag(uint8_t *buffer, int32_t *tagLen, int32_t *tagType)
-{
-    uint8_t *pStart;
-
-    /* WARNING: <!-- --> comment is not supported in this verison */
-    if (NULL == buffer) {
-        XML_ERROR(XML_ERROR_BUFFER_NULL);
-        return NULL;
-    }
-
-    do {
-        while (*buffer != '<') {
-            if (*buffer == '\0') {
-                XML_ERROR(XML_ERROR_BUFFER_NULL);
-                return NULL;
-            }
-
-            if (*buffer == '\"' || *buffer == '\'') {
-                uint8_t charQuoted = *buffer;
-                buffer++;
-                while (*buffer != '\0' && *buffer != charQuoted)
-                    buffer++;
-                if (*buffer == '\0') {
-                    XML_ERROR(XML_ERROR_BUFFER_NULL);
-                    return NULL;
-                }
-            }
-            buffer++;
-        }
-        buffer++;
-    } while (*buffer == '!' || *buffer == '?');
-
-    pStart = buffer - 1;
-
-    if (*buffer == '/') {
-        buffer++;
-        *tagType = XML_TAG_END;
-    } else {
-        /* check here if it is self-end-tag */
-        uint8_t *pCheck = xml_goto_tagend(pStart);
-        if (pCheck == NULL) {
-            XML_ERROR(XML_ERROR_PROPERTY_END);
-            return NULL;
-        }
-
-        if (*pCheck == '>')
-            *tagType = XML_TAG_START;
-        else if (strncmp((char *)pCheck, "/>", 2) == 0)
-            *tagType = XML_TAG_SELF;
-        else {
-            XML_ERROR(XML_ERROR_PROPERTY_END);
-            return NULL;
-        }
-    }
-
-    while (buffer != NULL && XML_IS_NAMECHAR(*buffer))
-        buffer++;
-    if (NULL == buffer) {
-        XML_ERROR(XML_ERROR_BUFFER_NULL);
-        return NULL;
-    }
-
-    if (*tagType == XML_TAG_END)
-        *tagLen = buffer - pStart - 2;
-    else
-        *tagLen = buffer - pStart - 1;
-
-    XML_ERROR(XML_ERROR_OK);
-
-    return pStart;
-}
-
-uint8_t *XML_DOM_getNode(uint8_t *buffer, const uint8_t *const node)
-{
-    uint8_t *pStart;
-    uint8_t buf[XML_MAX_PROPERTY_LEN + 2];
-    uint8_t *nodeStr = buf;
-    uint8_t *retPtr = NULL;
-    int32_t tagLen, tagType;
-    uint8_t *lastNode = (uint8_t *)"";
-
-    if (NULL == buffer) {
-        XML_ERROR(XML_ERROR_BUFFER_NULL);
-        return NULL;
-    }
-
-    strncpy((char *)nodeStr, (char *)node, XML_MAX_PROPERTY_LEN);
-    strcat((char *)nodeStr, "\\");
-    pStart = (uint8_t *)strchr((char *)nodeStr, '\\');
-
-    while (pStart != NULL) {
-        *pStart = '\0';
-
-        /* get the first start_tag from buffer */
-        if (NULL == (buffer = XML_DOM_getTag(buffer, &tagLen, &tagType))) {
-            XML_ERROR(XML_ERROR_NO_SUCH_NODE);
-            return NULL;
-        }
-
-        if (tagType == XML_TAG_END) {
-            if (0 ==
-                strncmp((char *)lastNode, (char *)(buffer + 2), strlen((char *)lastNode)))
-                XML_ERROR(XML_ERROR_NO_SUCH_NODE);
-            else
-                XML_ERROR(XML_ERROR_NO_START_TAG);
-            return NULL;
-        }
-
-        /* wrong node, contiue to fetch the next node */
-        if ((int32_t) strlen((char *)nodeStr) != tagLen
-            || strncmp((char *)nodeStr, (char *)(buffer + 1), tagLen) != 0) {
-            /* we should ignore all the middle code */
-            buffer = xml_match_tag(buffer);
-            continue;
-        }
-
-        retPtr = buffer;        /* retPtr starts with '<xxx>' */
-        buffer += (tagLen + 1);
-
-        if (tagType == XML_TAG_SELF) {
-            nodeStr = pStart + 1;
-            break;
-        }
-
-        lastNode = nodeStr;
-        nodeStr = pStart + 1;
-        pStart = (uint8_t *)strchr((char *)nodeStr, '\\');
-    }
-
-    /* Check 5: nodeStr should be empty here */
-    if (*nodeStr != '\0') {
-        XML_ERROR(XML_ERROR_NO_SUCH_NODE);
-        return NULL;
-    }
-
-    XML_ERROR(XML_ERROR_OK);
-
-    return retPtr;
-}
-
-uint8_t *XML_DOM_getNodeValue(uint8_t *buffer, uint8_t *node,
-                           uint8_t **value, int32_t *valueLen)
-{
-    uint8_t *pStart;
-    uint8_t *lastTag;
-
-    if (NULL == node || NULL == buffer) {
-        XML_ERROR(XML_ERROR_BUFFER_NULL);
-        return NULL;
-    }
-
-    lastTag = node + strlen((char *)node) - 1;
-    while (lastTag >= node && *lastTag != '\\')
-        lastTag--;
-    lastTag++;
-
-    if (NULL == (pStart = XML_DOM_getNode(buffer, node)))
-        return NULL;
-
-    pStart += (strlen((char *)lastTag) + 1);
-
-    if (NULL == (pStart = xml_goto_tagend(pStart))) {
-        XML_ERROR(XML_ERROR_PROPERTY_END);
-        return NULL;
-    }
-
-    if (NULL == (pStart = XML_DOM_getValue(pStart, value, valueLen)))
-        return NULL;
-
-    /* Check the end tag */
-#ifdef XML_DOM_CHECK_ENDTAG
-    if (strncmp((char *)pStart, "/>", 2) == 0) {
-
-    } else if (strncmp((char *)lastTag, (char *)(pStart + 2), strlen((char *)lastTag)) !=
-               0) {
-        XML_ERROR(XML_ERROR_ENDTAG);
-        return NULL;
-    }
-#endif
-
-    XML_ERROR(XML_ERROR_OK);
-
-    return *value;
-}
-
-uint8_t *XML_DOM_getNextNode(uint8_t *buffer, uint8_t **pNodeName, int32_t *nodenameLen)
-{
-    int32_t tagType;
-
-    if (NULL == buffer)
-        return NULL;
-
-    do {
-        if (NULL ==
-            (buffer = XML_DOM_getTag(buffer + 1, nodenameLen, &tagType))) {
-            XML_ERROR(XML_ERROR_NO_SUCH_NODE);
-            return NULL;
-        }
-    } while (tagType == XML_TAG_END);
-
-    *pNodeName = buffer + 1;
-
-    XML_ERROR(XML_ERROR_OK);
-
-    return buffer;
-}
-
-#endif /* XML_DOM_PARSER */
-
-#ifdef WBXML_DOM_PARSER
-
-#ifdef WBXML_OLD_VERSION
-uint8_t *WBXML_DOM_getNode(uint8_t *buffer, int32_t bufferLen,
-                                 uint8_t *node)
-{
-    int32_t i = 0, j = 0;
-
-    if (NULL == buffer || node == NULL) {
-        XML_ERROR(XML_ERROR_BUFFER_NULL);
-        return NULL;
-    }
-
-    while (i < bufferLen) {
-        if (WBXML_GET_TAG(buffer[i]) == WBXML_GET_TAG(node[j])) {
-            j++;
-            if (node[j] == '\0')
-                break;
-
-            /* Check if there is the content(it should have content) */
-            if (!WBXML_HAS_CONTENT(buffer[i])) {
-                /*XML_ERROR(WBXML_ERROR_MISSED_CONTENT); */
-                XML_ERROR(XML_ERROR_NO_SUCH_NODE);
-                return NULL;
-            }
-
-            /* Ignore the attrib filed */
-            if (WBXML_HAS_ATTR(buffer[i])) {
-                while (i < bufferLen && buffer[i] != WBXML_ATTR_END)
-                    i++;
-                if (i >= bufferLen)
-                    break;
-            }
-        }
-        i++;
-
-        /* Ignore the content filed */
-        if (buffer[i] == WBXML_STR_I) {
-            while (i < bufferLen && buffer[i] != WBXML_END)
-                i++;
-            if (i >= bufferLen)
-                break;
-            i++;
-        }
-    }
-
-    if (i >= bufferLen) {
-        XML_ERROR(XML_ERROR_NO_SUCH_NODE);
-        return NULL;
-    }
-
-    XML_ERROR(XML_ERROR_OK);
-
-    return buffer + i + 1;
-}
-
-uint8_t *WBXML_DOM_getNodeValue(uint8_t *buffer, int32_t bufferLen,
-                                      uint8_t *node,
-                                      uint8_t **value, int32_t *valueLen)
-{
-    int32_t i;
-    uint8_t *pEnd;
-
-    *value = NULL;
-    *valueLen = 0;
-
-    pEnd = buffer + bufferLen;
-    buffer = WBXML_DOM_getNode(buffer, bufferLen, node);
-    if (NULL == buffer) {
-        XML_ERROR(XML_ERROR_NO_SUCH_NODE);
-        return NULL;
-    }
-
-    if (*buffer == WBXML_OPAUE) {
-        buffer++;
-        *valueLen = WBXML_GetUintVar(buffer, &i);
-        if (*valueLen < 0) {
-            XML_ERROR(WBXML_ERROR_MBUINT32);
-            return NULL;
-        }
-        buffer += i;
-        *value = buffer;
-        return *value;
-    }
-
-    if (*buffer != WBXML_STR_I) {
-        XML_ERROR(WBXML_ERROR_MISSED_STARTTAG);
-        return NULL;
-    }
-
-    buffer++;
-
-    i = 0;
-    while ((buffer + i) < pEnd && buffer[i] != WBXML_END)
-        i++;
-
-    if (buffer[i] != WBXML_END) {
-        XML_ERROR(WBXML_ERROR_MISSED_ENDTAG);
-        return NULL;
-    }
-
-    *value = buffer;
-    *valueLen = i;
-    XML_ERROR(XML_ERROR_OK);
-
-    return *value;
-}
-#endif /* WBXML_OLD_VERSION */
-
-#define MAX_UINT_VAR_BYTE                                    4
-#define UINTVAR_INVALID                                      -1
-int32_t WBXML_GetUintVar(const uint8_t *const buffer, int32_t *len)
-{
-    int32_t i, byteLen;
-    int32_t sum;
-
-    byteLen = 0;
-    while ((buffer[byteLen] & 0x80) > 0 && byteLen < MAX_UINT_VAR_BYTE)
-        byteLen++;
-
-    if (byteLen > MAX_UINT_VAR_BYTE)
-        return UINTVAR_INVALID;
-
-    *len = byteLen + 1;
-    sum = buffer[byteLen];
-    for (i = byteLen - 1; i >= 0; i--)
-        sum += ((buffer[i] & 0x7F) << 7 * (byteLen - i));
-
-    return sum;
-}
-
-XML_BOOL WBXML_DOM_Init(WBXML * pWbxml, uint8_t *buffer,
-                        int32_t bufferLen)
-{
-    int32_t num, len;
-
-    pWbxml->End = buffer + bufferLen;
-    pWbxml->version = *buffer++;
-    if (UINTVAR_INVALID == (num = WBXML_GetUintVar(buffer, &len)))
-        return XML_FALSE;
-    buffer += len;
-    pWbxml->publicid = num;
-    if (UINTVAR_INVALID == (num = WBXML_GetUintVar(buffer, &len)))
-        return XML_FALSE;
-    buffer += len;
-    pWbxml->charset = num;
-    if (UINTVAR_INVALID == (num = WBXML_GetUintVar(buffer, &len)))
-        return XML_FALSE;
-    buffer += len;
-    pWbxml->strTable = buffer;
-    pWbxml->strTableLen = num;
-    buffer += num;
-    pWbxml->curPtr = pWbxml->Content = buffer;
-    pWbxml->depth = 0;
-
-    return XML_TRUE;
-}
-
-void WBXML_DOM_Rewind(WBXML * pWbxml)
-{
-    pWbxml->curPtr = pWbxml->Content;
-}
-
-XML_BOOL WBXML_DOM_Eof(WBXML * pWbxml)
-{
-    if (pWbxml->curPtr > pWbxml->End)
-        return XML_TRUE;
-
-    return XML_FALSE;
-}
-
-uint8_t WBXML_DOM_GetTag(WBXML * pWbxml)
-{
-    uint8_t tagChar;
-
-    if (pWbxml->curPtr > pWbxml->End)
-        return XML_EOF;
-
-    tagChar = *pWbxml->curPtr;
-    pWbxml->curPtr++;
-
-    if (WBXML_GET_TAG(tagChar) == WBXML_CONTENT_END)
-        pWbxml->depth--;
-    else
-        pWbxml->depth++;
-
-    return tagChar;
-}
-
-uint8_t WBXML_DOM_GetChar(WBXML * pWbxml)
-{
-    return *pWbxml->curPtr++;
-}
-
-void WBXML_DOM_Seek(WBXML * pWbxml, int32_t offset)
-{
-    pWbxml->curPtr += offset;
-}
-
-uint8_t WBXML_DOM_GetUIntVar(WBXML * pWbxml)
-{
-    int32_t num, len;
-
-    num = WBXML_GetUintVar(pWbxml->curPtr, &len);
-    pWbxml->curPtr += len;
-
-    return (uint8_t)num;
-}
-
-#ifdef XML_TREE_STRUCTURE
-
-#ifdef DEBUG_MODE
-static int32_t malloc_times = 0;
-static int32_t free_times = 0;
-void XML_PrintMallocInfo()
-{
-    printf("====XML_PrintMallocInfo====\n");
-    printf(" Total malloc times:%d\n", malloc_times);
-    printf(" Total free   times:%d\n", free_times);
-    printf("===========================\n");
-}
-#endif
-
-void *xml_malloc(int32_t size)
-{
-#ifdef DEBUG_MODE
-    malloc_times++;
-#endif
-    return malloc(size);
-}
-
-void xml_free(void *buffer)
-{
-#ifdef DEBUG_MODE
-    free_times++;
-#endif
-    free(buffer);
-}
-
-XML_TREE *xml_tree_fillnode(uint8_t **buf, int32_t tagLen)
-{
-    XML_TREE *Tree;
-    uint8_t *pAttr, *pName, *pValue;
-    int32_t nameLen, valueLen;
-    uint8_t *buffer = *buf;
-
-    if (NULL == (Tree = (XML_TREE *) xml_malloc(sizeof(XML_TREE))))
-        return NULL;
-    memset(Tree, 0, sizeof(XML_TREE));
-
-    strncpy((char *)Tree->tag, (char *)++buffer, tagLen);
-    buffer += tagLen;
-    pAttr = buffer;
-
-    /* attribute */
-    while (NULL !=
-           (pAttr =
-            XML_DOM_getAttr(pAttr, &pName, &nameLen, &pValue,
-                            &valueLen))) {
-        XML_TREE_ATTR *attr;
-        if (NULL ==
-            (attr = (XML_TREE_ATTR *) xml_malloc(sizeof(XML_TREE_ATTR))))
-            return NULL;
-        memset(attr, 0, sizeof(XML_TREE_ATTR));
-        strncpy((char *)attr->name, (char *)pName, nameLen);
-        strncpy((char *)attr->value, (char *)pValue, valueLen);
-        buffer = pValue + valueLen + 1;
-
-        if (NULL != Tree->attr) // no attribute now
-            Tree->last_attr->next = attr;
-        else
-            Tree->attr = attr;
-        Tree->last_attr = attr;
-    }
-
-    /* value */
-    pAttr = XML_DOM_getValue(buffer, &pValue, &valueLen);
-    if (pAttr != NULL && valueLen > 0) {
-        strncpy((char *)Tree->value, (char *)pValue, valueLen);
-        buffer = pValue + valueLen;
-    }
-
-    *buf = buffer;
-    return Tree;
-}
-
-XML_TREE *XML_makeTree(uint8_t **buf)
-{
-    uint8_t *pBuf;
-    int32_t valueLen, tagType;
-    uint8_t *buffer = *buf;
-    XML_TREE *TreeHead = NULL;
-
-    if (NULL == (buffer = XML_DOM_getTag(buffer, &valueLen, &tagType)))
-        return NULL;
-    if (XML_TAG_END == tagType)
-        return NULL;
-    if (NULL == (TreeHead = xml_tree_fillnode(&buffer, valueLen)))
-        return NULL;
-    if (XML_TAG_SELF == tagType) {
-        *buf = buffer;
-        return TreeHead;
-    }
-
-    do {
-        if (NULL == (pBuf = XML_DOM_getTag(buffer, &valueLen, &tagType)))
-            return NULL;
-
-        switch (tagType) {
-        case XML_TAG_SELF:
-        case XML_TAG_START:
-            if (NULL == TreeHead->child)
-                TreeHead->child = XML_makeTree(&buffer);
-            else if (NULL == TreeHead->child->last_brother) {
-                TreeHead->child->brother = XML_makeTree(&buffer);
-                TreeHead->child->last_brother = TreeHead->child->brother;
-            } else {
-                TreeHead->child->last_brother->brother =
-                    XML_makeTree(&buffer);
-                TreeHead->child->last_brother =
-                    TreeHead->child->last_brother->brother;
-            }
-            break;
-        case XML_TAG_END:
-            *buf = pBuf;
-            return TreeHead;
-        }
-        buffer++;
-    } while (1);
-}
-
-void XML_freeTree(XML_TREE * pTree)
-{
-    XML_TREE *p, *pNext;
-    XML_TREE_ATTR *pa, *lastpa;
-
-    if (NULL == pTree)
-        return;
-
-    p = pTree->brother;
-    while (NULL != p) {
-        pNext = p->brother;
-        p->brother = NULL;
-        XML_freeTree(p);
-        p = pNext;
-    }
-
-    if (NULL != pTree->child)
-        XML_freeTree(pTree->child);
-
-    pa = pTree->attr;
-    while (NULL != pa) {
-        lastpa = pa;
-        pa = pa->next;
-        xml_free(lastpa);
-    }
-    xml_free(pTree);
-}
-
-#endif /* XML_TREE_STRUCTURE */
-
-#endif /* WBXML_DOM_PARSER */
diff --git a/media/mca/filterfw/native/core/gl_env.cpp b/media/mca/filterfw/native/core/gl_env.cpp
index 73768fe..84dad8c 100644
--- a/media/mca/filterfw/native/core/gl_env.cpp
+++ b/media/mca/filterfw/native/core/gl_env.cpp
@@ -26,6 +26,8 @@
 #include <string>
 #include <EGL/eglext.h>
 
+#include <gui/GLConsumer.h>
+
 namespace android {
 namespace filterfw {
 
@@ -160,9 +162,9 @@
   }
 
   // Create dummy surface using a GLConsumer
-  surfaceTexture_ = new GLConsumer(0);
-  window_ = new Surface(static_cast<sp<IGraphicBufferProducer> >(
-          surfaceTexture_->getBufferQueue()));
+  sp<BufferQueue> bq = new BufferQueue();
+  surfaceTexture_ = new GLConsumer(bq, 0);
+  window_ = new Surface(static_cast<sp<IGraphicBufferProducer> >(bq));
 
   surfaces_[0] = SurfaceWindowPair(eglCreateWindowSurface(display(), config, window_.get(), NULL), NULL);
   if (CheckEGLError("eglCreateWindowSurface")) return false;
diff --git a/media/mca/filterfw/native/core/gl_env.h b/media/mca/filterfw/native/core/gl_env.h
index 81e1e9d..a709638 100644
--- a/media/mca/filterfw/native/core/gl_env.h
+++ b/media/mca/filterfw/native/core/gl_env.h
@@ -31,6 +31,9 @@
 #include <gui/Surface.h>
 
 namespace android {
+
+class GLConsumer;
+
 namespace filterfw {
 
 class ShaderProgram;
diff --git a/media/tests/MediaFrameworkTest/Android.mk b/media/tests/MediaFrameworkTest/Android.mk
index c9afa19..1e6b2e7 100644
--- a/media/tests/MediaFrameworkTest/Android.mk
+++ b/media/tests/MediaFrameworkTest/Android.mk
@@ -7,7 +7,7 @@
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
-LOCAL_STATIC_JAVA_LIBRARIES := easymocklib
+LOCAL_STATIC_JAVA_LIBRARIES := easymocklib mockito-target
 
 LOCAL_PACKAGE_NAME := mediaframeworktest
 
diff --git a/media/tests/MediaFrameworkTest/AndroidManifest.xml b/media/tests/MediaFrameworkTest/AndroidManifest.xml
index b698705..91ee2c6 100644
--- a/media/tests/MediaFrameworkTest/AndroidManifest.xml
+++ b/media/tests/MediaFrameworkTest/AndroidManifest.xml
@@ -71,4 +71,9 @@
          android:label="Media Power tests InstrumentationRunner">
      </instrumentation>
 
+    <instrumentation android:name=".MediaFrameworkIntegrationTestRunner"
+         android:targetPackage="com.android.mediaframeworktest"
+         android:label="MediaFramework integration tests InstrumentationRunner">
+     </instrumentation>
+
 </manifest>
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkIntegrationTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkIntegrationTestRunner.java
new file mode 100644
index 0000000..7751fcc
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkIntegrationTestRunner.java
@@ -0,0 +1,72 @@
+/*
+ * 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.mediaframeworktest;
+
+import android.os.Bundle;
+import android.test.InstrumentationTestRunner;
+import android.test.InstrumentationTestSuite;
+import android.util.Log;
+
+import com.android.mediaframeworktest.integration.CameraBinderTest;
+import com.android.mediaframeworktest.integration.CameraDeviceBinderTest;
+
+import junit.framework.TestSuite;
+
+/**
+ * Instrumentation Test Runner for all media framework integration tests.
+ *
+ * Running all tests:
+ *
+ * adb shell am instrument -w com.android.mediaframeworktest/.MediaFrameworkIntegrationTestRunner
+ */
+
+public class MediaFrameworkIntegrationTestRunner extends InstrumentationTestRunner {
+
+    private static final String TAG = "MediaFrameworkIntegrationTestRunner";
+
+    public static int mCameraId = 0;
+
+    @Override
+    public TestSuite getAllTests() {
+        TestSuite suite = new InstrumentationTestSuite(this);
+        suite.addTestSuite(CameraBinderTest.class);
+        suite.addTestSuite(CameraDeviceBinderTest.class);
+        return suite;
+    }
+
+    @Override
+    public ClassLoader getLoader() {
+        return MediaFrameworkIntegrationTestRunner.class.getClassLoader();
+    }
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        String cameraId = (String) icicle.get("camera_id");
+        if (cameraId != null) {
+            try {
+                Log.v(TAG,
+                        String.format("Reading camera_id from icicle: '%s'", cameraId));
+                mCameraId = Integer.parseInt(cameraId);
+            }
+            catch (NumberFormatException e) {
+                Log.e(TAG, String.format("Failed to convert camera_id to integer"));
+            }
+        }
+    }
+}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java
index 92ac9eb..cbb6642 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java
@@ -50,7 +50,7 @@
  * Running all tests:
  *
  * adb shell am instrument \
- *   -w com.android.smstests.MediaPlayerInstrumentationTestRunner
+ *  -w com.android.mediaframeworktest/.MediaFrameworkTestRunner
  */
 
 public class MediaFrameworkTestRunner extends InstrumentationTestRunner {
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkUnitTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkUnitTestRunner.java
index 62af3f3..ecdc287 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkUnitTestRunner.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkUnitTestRunner.java
@@ -48,6 +48,7 @@
         addMediaRecorderStateUnitTests(suite);
         addMediaPlayerStateUnitTests(suite);
         addMediaScannerUnitTests(suite);
+        addCameraUnitTests(suite);
         return suite;
     }
 
@@ -56,6 +57,14 @@
         return MediaFrameworkUnitTestRunner.class.getClassLoader();
     }
 
+    private void addCameraUnitTests(TestSuite suite) {
+        suite.addTestSuite(CameraUtilsDecoratorTest.class);
+        suite.addTestSuite(CameraUtilsRuntimeExceptionTest.class);
+        suite.addTestSuite(CameraUtilsUncheckedThrowTest.class);
+        suite.addTestSuite(CameraUtilsBinderDecoratorTest.class);
+        suite.addTestSuite(CameraMetadataTest.class);
+    }
+
     // Running all unit tests checking the state machine may be time-consuming.
     private void addMediaMetadataRetrieverStateUnitTests(TestSuite suite) {
         suite.addTestSuite(MediaMetadataRetrieverTest.class);
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CameraTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CameraTest.java
index 2f864d7..7f23ba5 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CameraTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CameraTest.java
@@ -36,7 +36,12 @@
 
 /**
  * Junit / Instrumentation test case for the camera api
- 
+ *
+ * To run only tests in this class:
+ *
+ * adb shell am instrument \
+ *   -e class com.android.mediaframeworktest.functional.CameraTest \
+ *   -w  com.android.mediaframeworktest/.MediaFrameworkTestRunner
  */  
 public class CameraTest extends ActivityInstrumentationTestCase<MediaFrameworkTest> {    
     private String TAG = "CameraTest";
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
new file mode 100644
index 0000000..1b7faec
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
@@ -0,0 +1,228 @@
+/*
+ * 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.mediaframeworktest.integration;
+
+import android.hardware.CameraInfo;
+import android.hardware.ICamera;
+import android.hardware.ICameraClient;
+import android.hardware.ICameraServiceListener;
+import android.hardware.IProCameraCallbacks;
+import android.hardware.IProCameraUser;
+import android.hardware.camera2.CameraMetadata;
+import android.hardware.camera2.ICameraDeviceCallbacks;
+import android.hardware.camera2.ICameraDeviceUser;
+import android.hardware.camera2.impl.CameraMetadataNative;
+import android.hardware.camera2.utils.BinderHolder;
+import android.hardware.camera2.utils.CameraBinderDecorator;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Log;
+
+/**
+ * <p>
+ * Junit / Instrumentation test case for the camera2 api
+ * </p>
+ * <p>
+ * To run only tests in this class:
+ * </p>
+ *
+ * <pre>
+ * adb shell am instrument \
+ *   -e class com.android.mediaframeworktest.integration.CameraBinderTest \
+ *   -w com.android.mediaframeworktest/.MediaFrameworkIntegrationTestRunner
+ * </pre>
+ */
+public class CameraBinderTest extends AndroidTestCase {
+    static String TAG = "CameraBinderTest";
+
+    protected CameraBinderTestUtils mUtils;
+
+    public CameraBinderTest() {
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mUtils = new CameraBinderTestUtils(getContext());
+    }
+
+    @SmallTest
+    public void testNumberOfCameras() throws Exception {
+
+        int numCameras = mUtils.getCameraService().getNumberOfCameras();
+        assertTrue("At least this many cameras: " + mUtils.getGuessedNumCameras(),
+                numCameras >= mUtils.getGuessedNumCameras());
+        Log.v(TAG, "Number of cameras " + numCameras);
+    }
+
+    @SmallTest
+    public void testCameraInfo() throws Exception {
+        for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
+
+            CameraInfo info = new CameraInfo();
+            info.info.facing = -1;
+            info.info.orientation = -1;
+
+            assertTrue(
+                    "Camera service returned info for camera " + cameraId,
+                    mUtils.getCameraService().getCameraInfo(cameraId, info) ==
+                    CameraBinderTestUtils.NO_ERROR);
+            assertTrue("Facing was not set for camera " + cameraId, info.info.facing != -1);
+            assertTrue("Orientation was not set for camera " + cameraId,
+                    info.info.orientation != -1);
+
+            Log.v(TAG, "Camera " + cameraId + " info: facing " + info.info.facing
+                    + ", orientation " + info.info.orientation);
+        }
+    }
+
+    static abstract class DummyBase extends Binder implements android.os.IInterface {
+        @Override
+        public IBinder asBinder() {
+            return this;
+        }
+    }
+
+    static class DummyCameraClient extends DummyBase implements ICameraClient {
+    }
+
+    @SmallTest
+    public void testConnect() throws Exception {
+        for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
+
+            ICameraClient dummyCallbacks = new DummyCameraClient();
+
+            String clientPackageName = getContext().getPackageName();
+
+            BinderHolder holder = new BinderHolder();
+            CameraBinderDecorator.newInstance(mUtils.getCameraService())
+                    .connect(dummyCallbacks, cameraId, clientPackageName,
+                    CameraBinderTestUtils.USE_CALLING_UID, holder);
+            ICamera cameraUser = ICamera.Stub.asInterface(holder.getBinder());
+            assertNotNull(String.format("Camera %s was null", cameraId), cameraUser);
+
+            Log.v(TAG, String.format("Camera %s connected", cameraId));
+
+            cameraUser.disconnect();
+        }
+    }
+
+    static class DummyProCameraCallbacks extends DummyBase implements IProCameraCallbacks {
+    }
+
+    @SmallTest
+    public void testConnectPro() throws Exception {
+        for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
+
+            IProCameraCallbacks dummyCallbacks = new DummyProCameraCallbacks();
+
+            String clientPackageName = getContext().getPackageName();
+
+            BinderHolder holder = new BinderHolder();
+            CameraBinderDecorator.newInstance(mUtils.getCameraService())
+                    .connectPro(dummyCallbacks, cameraId,
+                    clientPackageName, CameraBinderTestUtils.USE_CALLING_UID, holder);
+            IProCameraUser cameraUser = IProCameraUser.Stub.asInterface(holder.getBinder());
+            assertNotNull(String.format("Camera %s was null", cameraId), cameraUser);
+
+            Log.v(TAG, String.format("Camera %s connected", cameraId));
+
+            cameraUser.disconnect();
+        }
+    }
+
+    static class DummyCameraDeviceCallbacks extends ICameraDeviceCallbacks.Stub {
+
+        @Override
+        public void notifyCallback(int msgType, int ext1, int ext2) throws RemoteException {
+        }
+
+        @Override
+        public void onResultReceived(int frameId, CameraMetadataNative result) throws RemoteException {
+        }
+    }
+
+    @SmallTest
+    public void testConnectDevice() throws Exception {
+        for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
+
+            ICameraDeviceCallbacks dummyCallbacks = new DummyCameraDeviceCallbacks();
+
+            String clientPackageName = getContext().getPackageName();
+
+            BinderHolder holder = new BinderHolder();
+            CameraBinderDecorator.newInstance(mUtils.getCameraService())
+                    .connectDevice(dummyCallbacks, cameraId,
+                    clientPackageName, CameraBinderTestUtils.USE_CALLING_UID, holder);
+            ICameraDeviceUser cameraUser = ICameraDeviceUser.Stub.asInterface(holder.getBinder());
+            assertNotNull(String.format("Camera %s was null", cameraId), cameraUser);
+
+            Log.v(TAG, String.format("Camera %s connected", cameraId));
+
+            cameraUser.disconnect();
+        }
+    }
+
+    static class DummyCameraServiceListener extends ICameraServiceListener.Stub {
+        @Override
+        public void onStatusChanged(int status, int cameraId)
+                throws RemoteException {
+            Log.v(TAG, String.format("Camera %d has status changed to 0x%x", cameraId, status));
+        }
+    }
+
+    /**
+     * <pre>
+     * adb shell am instrument \
+     *   -e class 'com.android.mediaframeworktest.integration.CameraBinderTest#testAddRemoveListeners' \
+     *   -w com.android.mediaframeworktest/.MediaFrameworkIntegrationTestRunner
+     * </pre>
+     */
+    @SmallTest
+    public void testAddRemoveListeners() throws Exception {
+        for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
+
+            ICameraServiceListener listener = new DummyCameraServiceListener();
+
+            assertTrue(
+                    "Listener was removed before added",
+                    mUtils.getCameraService().removeListener(listener) ==
+                    CameraBinderTestUtils.BAD_VALUE);
+
+            assertTrue("Listener was not added",
+                    mUtils.getCameraService().addListener(listener) ==
+                    CameraBinderTestUtils.NO_ERROR);
+            assertTrue(
+                    "Listener was wrongly added again",
+                    mUtils.getCameraService().addListener(listener) ==
+                    CameraBinderTestUtils.ALREADY_EXISTS);
+
+            assertTrue(
+                    "Listener was not removed",
+                    mUtils.getCameraService().removeListener(listener) ==
+                    CameraBinderTestUtils.NO_ERROR);
+            assertTrue(
+                    "Listener was wrongly removed again",
+                    mUtils.getCameraService().removeListener(listener) ==
+                    CameraBinderTestUtils.BAD_VALUE);
+        }
+    }
+}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTestUtils.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTestUtils.java
new file mode 100644
index 0000000..1be2a62
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTestUtils.java
@@ -0,0 +1,93 @@
+
+package com.android.mediaframeworktest.integration;
+
+import static org.junit.Assert.assertNotNull;
+
+import android.content.Context;
+import android.content.pm.FeatureInfo;
+import android.content.pm.PackageManager;
+import android.hardware.ICameraService;
+import android.os.IBinder;
+import android.os.ServiceManager;
+import android.util.Log;
+
+public class CameraBinderTestUtils {
+    private final ICameraService mCameraService;
+    private int mGuessedNumCameras;
+
+    static final String CAMERA_SERVICE_BINDER_NAME = "media.camera";
+
+    protected static final int USE_CALLING_UID = -1;
+    protected static final int BAD_VALUE = -22;
+    protected static final int INVALID_OPERATION = -38;
+    protected static final int ALREADY_EXISTS = -17;
+    public static final int NO_ERROR = 0;
+    private final Context mContext;
+
+    public CameraBinderTestUtils(Context context) {
+
+        mContext = context;
+
+        guessNumCameras();
+
+        IBinder cameraServiceBinder = ServiceManager
+                .getService(CameraBinderTestUtils.CAMERA_SERVICE_BINDER_NAME);
+        assertNotNull("Camera service IBinder should not be null", cameraServiceBinder);
+
+        this.mCameraService = ICameraService.Stub.asInterface(cameraServiceBinder);
+        assertNotNull("Camera service should not be null", getCameraService());
+    }
+
+    private void guessNumCameras() {
+
+        /**
+         * Why do we need this? This way we have no dependency on getNumCameras
+         * actually working. On most systems there are only 0, 1, or 2 cameras,
+         * and this covers that 'usual case'. On other systems there might be 3+
+         * cameras, but this will at least check the first 2.
+         */
+        this.mGuessedNumCameras = 0;
+
+        // Front facing camera
+        if (CameraBinderTestUtils.isFeatureAvailable(mContext,
+                PackageManager.FEATURE_CAMERA_FRONT)) {
+            this.mGuessedNumCameras = getGuessedNumCameras() + 1;
+        }
+
+        // Back facing camera
+        if (CameraBinderTestUtils.isFeatureAvailable(mContext,
+                PackageManager.FEATURE_CAMERA)) {
+            this.mGuessedNumCameras = getGuessedNumCameras() + 1;
+        }
+
+        // Any facing camera
+        if (getGuessedNumCameras() == 0
+                && CameraBinderTestUtils.isFeatureAvailable(mContext,
+                        PackageManager.FEATURE_CAMERA_ANY)) {
+            this.mGuessedNumCameras = getGuessedNumCameras() + 1;
+        }
+
+        Log.v(CameraBinderTest.TAG, "Guessing there are at least " + getGuessedNumCameras()
+                + " cameras");
+    }
+
+    final static public boolean isFeatureAvailable(Context context, String feature) {
+        final PackageManager packageManager = context.getPackageManager();
+        final FeatureInfo[] featuresList = packageManager.getSystemAvailableFeatures();
+        for (FeatureInfo f : featuresList) {
+            if (f.name != null && f.name.equals(feature)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    ICameraService getCameraService() {
+        return mCameraService;
+    }
+
+    int getGuessedNumCameras() {
+        return mGuessedNumCameras;
+    }
+}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
new file mode 100644
index 0000000..56d73c0
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
@@ -0,0 +1,339 @@
+/*
+ * 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.mediaframeworktest.integration;
+
+import android.graphics.SurfaceTexture;
+import android.hardware.camera2.CameraMetadata;
+import android.hardware.camera2.CameraProperties;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.ICameraDeviceCallbacks;
+import android.hardware.camera2.ICameraDeviceUser;
+import android.hardware.camera2.impl.CameraMetadataNative;
+import android.hardware.camera2.utils.BinderHolder;
+import android.os.RemoteException;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Log;
+import android.view.Surface;
+
+import static android.hardware.camera2.CameraDevice.TEMPLATE_PREVIEW;
+
+import com.android.mediaframeworktest.MediaFrameworkIntegrationTestRunner;
+
+import org.mockito.ArgumentMatcher;
+import static org.mockito.Mockito.*;
+
+public class CameraDeviceBinderTest extends AndroidTestCase {
+    private static String TAG = "CameraDeviceBinderTest";
+    // Number of streaming callbacks need to check.
+    private static int NUM_CALLBACKS_CHECKED = 10;
+    // Wait for capture result timeout value: 1500ms
+    private final static int WAIT_FOR_COMPLETE_TIMEOUT_MS = 1500;
+
+    private int mCameraId;
+    private ICameraDeviceUser mCameraUser;
+    private CameraBinderTestUtils mUtils;
+    private ICameraDeviceCallbacks.Stub mMockCb;
+    private Surface mSurface;
+    // Need hold a Surfacetexture reference during a test execution, otherwise,
+    // it could be GCed during a test, which causes camera run into bad state.
+    private SurfaceTexture mSurfaceTexture;
+
+    public CameraDeviceBinderTest() {
+    }
+
+    public class DummyCameraDeviceCallbacks extends ICameraDeviceCallbacks.Stub {
+
+        @Override
+        public void notifyCallback(int msgType, int ext1, int ext2) throws RemoteException {
+        }
+
+        @Override
+        public void onResultReceived(int frameId, CameraMetadataNative result) throws RemoteException {
+        }
+    }
+
+    class IsMetadataNotEmpty extends ArgumentMatcher<CameraMetadataNative> {
+        public boolean matches(Object obj) {
+            return !((CameraMetadataNative) obj).isEmpty();
+        }
+     }
+
+    private void createDefaultSurface() {
+        mSurfaceTexture = new SurfaceTexture(/* ignored */0);
+        mSurfaceTexture.setDefaultBufferSize(640, 480);
+        mSurface = new Surface(mSurfaceTexture);
+    }
+
+    private CaptureRequest.Builder createDefaultBuilder(boolean needStream) throws Exception {
+        CameraMetadataNative metadata = new CameraMetadataNative();
+        assertTrue(metadata.isEmpty());
+
+        int status = mCameraUser.createDefaultRequest(TEMPLATE_PREVIEW, /* out */metadata);
+        assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+        assertFalse(metadata.isEmpty());
+
+        CaptureRequest.Builder request = new CaptureRequest.Builder(metadata);
+        assertFalse(request.isEmpty());
+        assertFalse(metadata.isEmpty());
+        if (needStream) {
+            int streamId = mCameraUser.createStream(/* ignored */10, /* ignored */20,
+                    /* ignored */30, mSurface);
+            assertEquals(0, streamId);
+            request.addTarget(mSurface);
+        }
+        return request;
+    }
+
+    private int submitCameraRequest(CaptureRequest request, boolean streaming) throws Exception {
+        int requestId = mCameraUser.submitRequest(request, streaming);
+        assertTrue("Request IDs should be non-negative", requestId >= 0);
+        return requestId;
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        /**
+         * Workaround for mockito and JB-MR2 incompatibility
+         *
+         * Avoid java.lang.IllegalArgumentException: dexcache == null
+         * https://code.google.com/p/dexmaker/issues/detail?id=2
+         */
+        System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString());
+        mUtils = new CameraBinderTestUtils(getContext());
+
+        // This cannot be set in the constructor, since the onCreate isn't
+        // called yet
+        mCameraId = MediaFrameworkIntegrationTestRunner.mCameraId;
+
+        ICameraDeviceCallbacks.Stub dummyCallbacks = new DummyCameraDeviceCallbacks();
+
+        String clientPackageName = getContext().getPackageName();
+
+        mMockCb = spy(dummyCallbacks);
+
+        BinderHolder holder = new BinderHolder();
+        mUtils.getCameraService().connectDevice(mMockCb, mCameraId,
+                clientPackageName, CameraBinderTestUtils.USE_CALLING_UID, holder);
+        mCameraUser = ICameraDeviceUser.Stub.asInterface(holder.getBinder());
+        assertNotNull(String.format("Camera %s was null", mCameraId), mCameraUser);
+        createDefaultSurface();
+
+        Log.v(TAG, String.format("Camera %s connected", mCameraId));
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mCameraUser.disconnect();
+        mCameraUser = null;
+        mSurface.release();
+        mSurfaceTexture.release();
+    }
+
+    @SmallTest
+    public void testCreateDefaultRequest() throws Exception {
+        CameraMetadataNative metadata = new CameraMetadataNative();
+        assertTrue(metadata.isEmpty());
+
+        int status = mCameraUser.createDefaultRequest(TEMPLATE_PREVIEW, /* out */metadata);
+        assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+        assertFalse(metadata.isEmpty());
+
+    }
+
+    @SmallTest
+    public void testCreateStream() throws Exception {
+        int streamId = mCameraUser.createStream(/* ignored */10, /* ignored */20, /* ignored */30,
+                mSurface);
+        assertEquals(0, streamId);
+
+        assertEquals(CameraBinderTestUtils.ALREADY_EXISTS,
+                mCameraUser.createStream(/* ignored */0, /* ignored */0, /* ignored */0, mSurface));
+
+        assertEquals(CameraBinderTestUtils.NO_ERROR, mCameraUser.deleteStream(streamId));
+    }
+
+    @SmallTest
+    public void testDeleteInvalidStream() throws Exception {
+        assertEquals(CameraBinderTestUtils.BAD_VALUE, mCameraUser.deleteStream(-1));
+        assertEquals(CameraBinderTestUtils.BAD_VALUE, mCameraUser.deleteStream(0));
+        assertEquals(CameraBinderTestUtils.BAD_VALUE, mCameraUser.deleteStream(1));
+        assertEquals(CameraBinderTestUtils.BAD_VALUE, mCameraUser.deleteStream(0xC0FFEE));
+    }
+
+    @SmallTest
+    public void testCreateStreamTwo() throws Exception {
+
+        // Create first stream
+        int streamId = mCameraUser.createStream(/* ignored */0, /* ignored */0, /* ignored */0,
+                mSurface);
+        assertEquals(0, streamId);
+
+        assertEquals(CameraBinderTestUtils.ALREADY_EXISTS,
+                mCameraUser.createStream(/* ignored */0, /* ignored */0, /* ignored */0, mSurface));
+
+        // Create second stream with a different surface.
+        SurfaceTexture surfaceTexture = new SurfaceTexture(/* ignored */0);
+        surfaceTexture.setDefaultBufferSize(640, 480);
+        Surface surface2 = new Surface(surfaceTexture);
+
+        int streamId2 = mCameraUser.createStream(/* ignored */0, /* ignored */0, /* ignored */0,
+                surface2);
+        assertEquals(1, streamId2);
+
+        // Clean up streams
+        assertEquals(CameraBinderTestUtils.NO_ERROR, mCameraUser.deleteStream(streamId));
+        assertEquals(CameraBinderTestUtils.NO_ERROR, mCameraUser.deleteStream(streamId2));
+    }
+
+    @SmallTest
+    public void testSubmitBadRequest() throws Exception {
+
+        CaptureRequest.Builder builder = createDefaultBuilder(/* needStream */false);
+        CaptureRequest request1 = builder.build();
+        int status = mCameraUser.submitRequest(request1, /* streaming */false);
+        assertEquals("Expected submitRequest to return BAD_VALUE " +
+                "since we had 0 surface targets set.", CameraBinderTestUtils.BAD_VALUE, status);
+
+        builder.addTarget(mSurface);
+        CaptureRequest request2 = builder.build();
+        status = mCameraUser.submitRequest(request2, /* streaming */false);
+        assertEquals("Expected submitRequest to return BAD_VALUE since " +
+                "the target surface wasn't registered with createStream.",
+                CameraBinderTestUtils.BAD_VALUE, status);
+    }
+
+    @SmallTest
+    public void testSubmitGoodRequest() throws Exception {
+
+        CaptureRequest.Builder builder = createDefaultBuilder(/* needStream */true);
+        CaptureRequest request = builder.build();
+
+        // Submit valid request twice.
+        int requestId1 = submitCameraRequest(request, /* streaming */false);
+        int requestId2 = submitCameraRequest(request, /* streaming */false);
+        assertNotSame("Request IDs should be unique for multiple requests", requestId1, requestId2);
+
+    }
+
+    @SmallTest
+    public void testSubmitStreamingRequest() throws Exception {
+
+        CaptureRequest.Builder builder = createDefaultBuilder(/* needStream */true);
+
+        CaptureRequest request = builder.build();
+
+        // Submit valid request once (non-streaming), and another time
+        // (streaming)
+        int requestId1 = submitCameraRequest(request, /* streaming */false);
+
+        int requestIdStreaming = submitCameraRequest(request, /* streaming */true);
+        assertNotSame("Request IDs should be unique for multiple requests", requestId1,
+                requestIdStreaming);
+
+        int status = mCameraUser.cancelRequest(-1);
+        assertEquals("Invalid request IDs should not be cancellable",
+                CameraBinderTestUtils.BAD_VALUE, status);
+
+        status = mCameraUser.cancelRequest(requestId1);
+        assertEquals("Non-streaming request IDs should not be cancellable",
+                CameraBinderTestUtils.BAD_VALUE, status);
+
+        status = mCameraUser.cancelRequest(requestIdStreaming);
+        assertEquals("Streaming request IDs should be cancellable", CameraBinderTestUtils.NO_ERROR,
+                status);
+
+    }
+
+    @SmallTest
+    public void testCameraInfo() throws RemoteException {
+        CameraMetadataNative info = new CameraMetadataNative();
+
+        int status = mCameraUser.getCameraInfo(/*out*/info);
+        assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+
+        assertFalse(info.isEmpty());
+        assertNotNull(info.get(CameraProperties.SCALER_AVAILABLE_FORMATS));
+    }
+
+    @SmallTest
+    public void testWaitUntilIdle() throws Exception {
+        CaptureRequest.Builder builder = createDefaultBuilder(/* needStream */true);
+        int requestIdStreaming = submitCameraRequest(builder.build(), /* streaming */true);
+
+        // Test Bad case first: waitUntilIdle when there is active repeating request
+        int status = mCameraUser.waitUntilIdle();
+        assertEquals("waitUntilIdle is invalid operation when there is active repeating request",
+            CameraBinderTestUtils.INVALID_OPERATION, status);
+
+        // Test good case, waitUntilIdle when there is no active repeating request
+        status = mCameraUser.cancelRequest(requestIdStreaming);
+        assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+        status = mCameraUser.waitUntilIdle();
+        assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+    }
+
+    @SmallTest
+    public void testCaptureResultCallbacks() throws Exception {
+        IsMetadataNotEmpty matcher = new IsMetadataNotEmpty();
+        CaptureRequest request = createDefaultBuilder(/* needStream */true).build();
+
+        // Test both single request and streaming request.
+        int requestId1 = submitCameraRequest(request, /* streaming */false);
+        verify(mMockCb, timeout(WAIT_FOR_COMPLETE_TIMEOUT_MS).times(1)).onResultReceived(
+                eq(requestId1),
+                argThat(matcher));
+
+        int streamingId = submitCameraRequest(request, /* streaming */true);
+        verify(mMockCb, timeout(WAIT_FOR_COMPLETE_TIMEOUT_MS).atLeast(NUM_CALLBACKS_CHECKED))
+                .onResultReceived(
+                        eq(streamingId),
+                        argThat(matcher));
+    }
+
+    @SmallTest
+    public void testFlush() throws Exception {
+        int status;
+
+        // Initial flush should work
+        status = mCameraUser.flush();
+        assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+
+        // Then set up a stream
+        CaptureRequest request = createDefaultBuilder(/* needStream */true).build();
+
+        // Flush should still be a no-op, really
+        status = mCameraUser.flush();
+        assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+
+        // Submit a few capture requests
+        int requestId1 = submitCameraRequest(request, /* streaming */false);
+        int requestId2 = submitCameraRequest(request, /* streaming */false);
+        int requestId3 = submitCameraRequest(request, /* streaming */false);
+        int requestId4 = submitCameraRequest(request, /* streaming */false);
+        int requestId5 = submitCameraRequest(request, /* streaming */false);
+
+        // Then flush
+        status = mCameraUser.flush();
+        assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+
+        // TODO: When errors are hooked up, count that errors + successful
+        // requests equal to 5.
+    }
+}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
index 074bfe4..2d26ac7 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
@@ -86,9 +86,9 @@
     private Writer mProcMemWriter;
     private Writer mMemWriter;
 
-    private CamcorderProfile mCamcorderProfile = CamcorderProfile.get(CAMERA_ID);
-    private int mVideoWidth = mCamcorderProfile.videoFrameWidth;
-    private int mVideoHeight = mCamcorderProfile.videoFrameHeight;
+    private CamcorderProfile mCamcorderProfile;
+    private int mVideoWidth;
+    private int mVideoHeight;
 
     Camera mCamera;
 
@@ -99,6 +99,12 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
+        //Check if the device support the camcorder
+        CamcorderProfile mCamcorderProfile = CamcorderProfile.get(CAMERA_ID);
+        if (mCamcorderProfile != null) {
+            mVideoWidth = mCamcorderProfile.videoFrameWidth;
+            mVideoHeight = mCamcorderProfile.videoFrameHeight;
+        }
         //Insert a 2 second before launching the test activity. This is
         //the workaround for the race condition of requesting the updated surface.
         Thread.sleep(2000);
@@ -332,7 +338,7 @@
         // USER     PID   PPID  VSIZE  RSS     WCHAN    PC         NAME
         // media     131   1     13676  4796  ffffffff 400b1bd0 S media.log
         // media     219   131   37768  6892  ffffffff 400b236c S /system/bin/mediaserver
-        String memusage = poList[2].concat("\n");
+        String memusage = poList[poList.length-1].concat("\n");
         return memusage;
     }
 
@@ -410,59 +416,65 @@
     // Test case 4: Capture the memory usage after every 20 video only recorded
     @LargeTest
     public void testH263RecordVideoOnlyMemoryUsage() throws Exception {
-        boolean memoryResult = false;
-        mStartPid = getMediaserverPid();
-        int frameRate = MediaProfileReader.getMaxFrameRateForCodec(MediaRecorder.VideoEncoder.H263);
-        assertTrue("H263 video recording frame rate", frameRate != -1);
-        for (int i = 0; i < NUM_STRESS_LOOP; i++) {
-            assertTrue(stressVideoRecord(frameRate, mVideoWidth, mVideoHeight,
-                    MediaRecorder.VideoEncoder.H263, MediaRecorder.OutputFormat.MPEG_4,
-                    MediaNames.RECORDED_VIDEO_3GP, true));
-            getMemoryWriteToLog(i);
-            writeProcmemInfo();
+        if (mCamcorderProfile != null) {
+            boolean memoryResult = false;
+            mStartPid = getMediaserverPid();
+            int frameRate = MediaProfileReader
+                    .getMaxFrameRateForCodec(MediaRecorder.VideoEncoder.H263);
+            assertTrue("H263 video recording frame rate", frameRate != -1);
+            for (int i = 0; i < NUM_STRESS_LOOP; i++) {
+                assertTrue(stressVideoRecord(frameRate, mVideoWidth, mVideoHeight,
+                        MediaRecorder.VideoEncoder.H263, MediaRecorder.OutputFormat.MPEG_4,
+                        MediaNames.RECORDED_VIDEO_3GP, true));
+                getMemoryWriteToLog(i);
+                writeProcmemInfo();
+            }
+            memoryResult = validateMemoryResult(mStartPid, mStartMemory, ENCODER_LIMIT);
+            assertTrue("H263 record only memory test", memoryResult);
         }
-        memoryResult = validateMemoryResult(mStartPid, mStartMemory, ENCODER_LIMIT);
-        assertTrue("H263 record only memory test", memoryResult);
     }
 
     // Test case 5: Capture the memory usage after every 20 video only recorded
     @LargeTest
     public void testMpeg4RecordVideoOnlyMemoryUsage() throws Exception {
-        boolean memoryResult = false;
-
-        mStartPid = getMediaserverPid();
-        int frameRate = MediaProfileReader.getMaxFrameRateForCodec
-                (MediaRecorder.VideoEncoder.MPEG_4_SP);
-        assertTrue("MPEG4 video recording frame rate", frameRate != -1);
-        for (int i = 0; i < NUM_STRESS_LOOP; i++) {
-            assertTrue(stressVideoRecord(frameRate, mVideoWidth, mVideoHeight,
-                    MediaRecorder.VideoEncoder.MPEG_4_SP, MediaRecorder.OutputFormat.MPEG_4,
-                    MediaNames.RECORDED_VIDEO_3GP, true));
-            getMemoryWriteToLog(i);
-            writeProcmemInfo();
+        if (mCamcorderProfile != null) {
+            boolean memoryResult = false;
+            mStartPid = getMediaserverPid();
+            int frameRate = MediaProfileReader.getMaxFrameRateForCodec
+                    (MediaRecorder.VideoEncoder.MPEG_4_SP);
+            assertTrue("MPEG4 video recording frame rate", frameRate != -1);
+            for (int i = 0; i < NUM_STRESS_LOOP; i++) {
+                assertTrue(stressVideoRecord(frameRate, mVideoWidth, mVideoHeight,
+                        MediaRecorder.VideoEncoder.MPEG_4_SP, MediaRecorder.OutputFormat.MPEG_4,
+                        MediaNames.RECORDED_VIDEO_3GP, true));
+                getMemoryWriteToLog(i);
+                writeProcmemInfo();
+            }
+            memoryResult = validateMemoryResult(mStartPid, mStartMemory, ENCODER_LIMIT);
+            assertTrue("mpeg4 record only memory test", memoryResult);
         }
-        memoryResult = validateMemoryResult(mStartPid, mStartMemory, ENCODER_LIMIT);
-        assertTrue("mpeg4 record only memory test", memoryResult);
     }
 
     // Test case 6: Capture the memory usage after every 20 video and audio
     // recorded
     @LargeTest
     public void testRecordVideoAudioMemoryUsage() throws Exception {
-        boolean memoryResult = false;
-
-        mStartPid = getMediaserverPid();
-        int frameRate = MediaProfileReader.getMaxFrameRateForCodec(MediaRecorder.VideoEncoder.H263);
-        assertTrue("H263 video recording frame rate", frameRate != -1);
-        for (int i = 0; i < NUM_STRESS_LOOP; i++) {
-            assertTrue(stressVideoRecord(frameRate, mVideoWidth, mVideoHeight,
-                    MediaRecorder.VideoEncoder.H263, MediaRecorder.OutputFormat.MPEG_4,
-                    MediaNames.RECORDED_VIDEO_3GP, false));
-            getMemoryWriteToLog(i);
-            writeProcmemInfo();
+        if (mCamcorderProfile != null) {
+            boolean memoryResult = false;
+            mStartPid = getMediaserverPid();
+            int frameRate = MediaProfileReader
+                    .getMaxFrameRateForCodec(MediaRecorder.VideoEncoder.H263);
+            assertTrue("H263 video recording frame rate", frameRate != -1);
+            for (int i = 0; i < NUM_STRESS_LOOP; i++) {
+                assertTrue(stressVideoRecord(frameRate, mVideoWidth, mVideoHeight,
+                        MediaRecorder.VideoEncoder.H263, MediaRecorder.OutputFormat.MPEG_4,
+                        MediaNames.RECORDED_VIDEO_3GP, false));
+                getMemoryWriteToLog(i);
+                writeProcmemInfo();
+            }
+            memoryResult = validateMemoryResult(mStartPid, mStartMemory, ENCODER_LIMIT);
+            assertTrue("H263 audio video record memory test", memoryResult);
         }
-        memoryResult = validateMemoryResult(mStartPid, mStartMemory, ENCODER_LIMIT);
-        assertTrue("H263 audio video record memory test", memoryResult);
     }
 
     // Test case 7: Capture the memory usage after every 20 audio only recorded
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java
new file mode 100644
index 0000000..874e078
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java
@@ -0,0 +1,526 @@
+/*
+ * 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.mediaframeworktest.unit;
+
+import android.os.Parcel;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.graphics.ImageFormat;
+import android.graphics.Rect;
+import android.hardware.camera2.CameraMetadata;
+import android.hardware.camera2.Rational;
+import android.hardware.camera2.Size;
+import android.hardware.camera2.impl.CameraMetadataNative;
+
+import static android.hardware.camera2.impl.CameraMetadataNative.*;
+
+import java.lang.reflect.Array;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.IntBuffer;
+
+import static org.junit.Assert.assertArrayEquals;
+
+/**
+ * <pre>
+ * adb shell am instrument \
+ *      -e class 'com.android.mediaframeworktest.unit.CameraMetadataTest' \
+ *      -w com.android.mediaframeworktest/.MediaFrameworkUnitTestRunner
+ * </pre>
+ */
+public class CameraMetadataTest extends junit.framework.TestCase {
+
+    CameraMetadataNative mMetadata;
+    Parcel mParcel;
+
+    // Sections
+    static final int ANDROID_COLOR_CORRECTION = 0;
+    static final int ANDROID_CONTROL = 1;
+
+    // Section starts
+    static final int ANDROID_COLOR_CORRECTION_START = ANDROID_COLOR_CORRECTION << 16;
+    static final int ANDROID_CONTROL_START = ANDROID_CONTROL << 16;
+
+    // Tags
+    static final int ANDROID_COLOR_CORRECTION_MODE = ANDROID_COLOR_CORRECTION_START;
+    static final int ANDROID_COLOR_CORRECTION_TRANSFORM = ANDROID_COLOR_CORRECTION_START + 1;
+
+    static final int ANDROID_CONTROL_AE_ANTIBANDING_MODE = ANDROID_CONTROL_START;
+    static final int ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION = ANDROID_CONTROL_START + 1;
+
+    @Override
+    public void setUp() {
+        mMetadata = new CameraMetadataNative();
+        mParcel = Parcel.obtain();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        mMetadata = null;
+
+        mParcel.recycle();
+        mParcel = null;
+    }
+
+    @SmallTest
+    public void testNew() {
+        assertEquals(0, mMetadata.getEntryCount());
+        assertTrue(mMetadata.isEmpty());
+    }
+
+    @SmallTest
+    public void testGetTagFromKey() {
+
+        // Test success
+
+        assertEquals(ANDROID_COLOR_CORRECTION_MODE,
+                CameraMetadataNative.getTag("android.colorCorrection.mode"));
+        assertEquals(ANDROID_COLOR_CORRECTION_TRANSFORM,
+                CameraMetadataNative.getTag("android.colorCorrection.transform"));
+        assertEquals(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
+                CameraMetadataNative.getTag("android.control.aeAntibandingMode"));
+        assertEquals(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
+                CameraMetadataNative.getTag("android.control.aeExposureCompensation"));
+
+        // Test failures
+
+        try {
+            CameraMetadataNative.getTag(null);
+            fail("A null key should throw NPE");
+        } catch(NullPointerException e) {
+        }
+
+        try {
+            CameraMetadataNative.getTag("android.control");
+            fail("A section name only should not be a valid key");
+        } catch(IllegalArgumentException e) {
+        }
+
+        try {
+            CameraMetadataNative.getTag("android.control.thisTagNameIsFakeAndDoesNotExist");
+            fail("A valid section with an invalid tag name should not be a valid key");
+        } catch(IllegalArgumentException e) {
+        }
+
+        try {
+            CameraMetadataNative.getTag("android");
+            fail("A namespace name only should not be a valid key");
+        } catch(IllegalArgumentException e) {
+        }
+
+        try {
+            CameraMetadataNative.getTag("this.key.is.definitely.invalid");
+            fail("A completely fake key name should not be valid");
+        } catch(IllegalArgumentException e) {
+        }
+    }
+
+    @SmallTest
+    public void testGetTypeFromTag() {
+        assertEquals(TYPE_BYTE, CameraMetadataNative.getNativeType(ANDROID_COLOR_CORRECTION_MODE));
+        assertEquals(TYPE_FLOAT, CameraMetadataNative.getNativeType(ANDROID_COLOR_CORRECTION_TRANSFORM));
+        assertEquals(TYPE_BYTE, CameraMetadataNative.getNativeType(ANDROID_CONTROL_AE_ANTIBANDING_MODE));
+        assertEquals(TYPE_INT32,
+                CameraMetadataNative.getNativeType(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION));
+
+        try {
+            CameraMetadataNative.getNativeType(0xDEADF00D);
+            fail("No type should exist for invalid tag 0xDEADF00D");
+        } catch(IllegalArgumentException e) {
+        }
+    }
+
+    @SmallTest
+    public void testReadWriteValues() {
+        final byte ANDROID_COLOR_CORRECTION_MODE_HIGH_QUALITY = 2;
+        byte[] valueResult;
+
+        assertEquals(0, mMetadata.getEntryCount());
+        assertEquals(true, mMetadata.isEmpty());
+
+        //
+        // android.colorCorrection.mode (single enum byte)
+        //
+
+        assertEquals(null, mMetadata.readValues(ANDROID_COLOR_CORRECTION_MODE));
+
+        // Write/read null values
+        mMetadata.writeValues(ANDROID_COLOR_CORRECTION_MODE, null);
+        assertEquals(null, mMetadata.readValues(ANDROID_COLOR_CORRECTION_MODE));
+
+        // Write 0 values
+        mMetadata.writeValues(ANDROID_COLOR_CORRECTION_MODE, new byte[] {});
+
+        // Read 0 values
+        valueResult = mMetadata.readValues(ANDROID_COLOR_CORRECTION_MODE);
+        assertNotNull(valueResult);
+        assertEquals(0, valueResult.length);
+
+        assertEquals(1, mMetadata.getEntryCount());
+        assertEquals(false, mMetadata.isEmpty());
+
+        // Write 1 value
+        mMetadata.writeValues(ANDROID_COLOR_CORRECTION_MODE, new byte[] {
+            ANDROID_COLOR_CORRECTION_MODE_HIGH_QUALITY
+        });
+
+        // Read 1 value
+        valueResult = mMetadata.readValues(ANDROID_COLOR_CORRECTION_MODE);
+        assertNotNull(valueResult);
+        assertEquals(1, valueResult.length);
+        assertEquals(ANDROID_COLOR_CORRECTION_MODE_HIGH_QUALITY, valueResult[0]);
+
+        assertEquals(1, mMetadata.getEntryCount());
+        assertEquals(false, mMetadata.isEmpty());
+
+        //
+        // android.colorCorrection.transform (3x3 matrix)
+        //
+
+        final float[] transformMatrix = new float[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+        byte[] transformMatrixAsByteArray = new byte[transformMatrix.length * 4];
+        ByteBuffer transformMatrixByteBuffer =
+                ByteBuffer.wrap(transformMatrixAsByteArray).order(ByteOrder.nativeOrder());
+        for (float f : transformMatrix)
+            transformMatrixByteBuffer.putFloat(f);
+
+        // Read
+        assertNull(mMetadata.readValues(ANDROID_COLOR_CORRECTION_TRANSFORM));
+        mMetadata.writeValues(ANDROID_COLOR_CORRECTION_TRANSFORM, transformMatrixAsByteArray);
+
+        // Write
+        assertArrayEquals(transformMatrixAsByteArray,
+                mMetadata.readValues(ANDROID_COLOR_CORRECTION_TRANSFORM));
+
+        assertEquals(2, mMetadata.getEntryCount());
+        assertEquals(false, mMetadata.isEmpty());
+
+        // Erase
+        mMetadata.writeValues(ANDROID_COLOR_CORRECTION_TRANSFORM, null);
+        assertNull(mMetadata.readValues(ANDROID_COLOR_CORRECTION_TRANSFORM));
+        assertEquals(1, mMetadata.getEntryCount());
+    }
+
+    private static <T> void assertArrayEquals(T expected, T actual) {
+        assertEquals(Array.getLength(expected), Array.getLength(actual));
+
+        int len = Array.getLength(expected);
+        for (int i = 0; i < len; ++i) {
+            assertEquals(Array.get(expected, i), Array.get(actual, i));
+        }
+    }
+
+    private <T> void checkKeyGetAndSet(String keyStr, Class<T> type, T value) {
+        assertFalse("Use checkKeyGetAndSetArray to compare array Keys", type.isArray());
+
+        Key<T> key = new Key<T>(keyStr, type);
+        assertNull(mMetadata.get(key));
+        mMetadata.set(key, null);
+        assertNull(mMetadata.get(key));
+        mMetadata.set(key, value);
+
+        T actual = mMetadata.get(key);
+        assertEquals(value, actual);
+    }
+
+    private <T> void checkKeyGetAndSetArray(String keyStr, Class<T> type, T value) {
+        assertTrue(type.isArray());
+
+        Key<T> key = new Key<T>(keyStr, type);
+        assertNull(mMetadata.get(key));
+        mMetadata.set(key, value);
+        assertArrayEquals(value, mMetadata.get(key));
+    }
+
+    @SmallTest
+    public void testReadWritePrimitive() {
+        // int32 (single)
+        checkKeyGetAndSet("android.control.aeExposureCompensation", Integer.TYPE, 0xC0FFEE);
+
+        // byte (single)
+        checkKeyGetAndSet("android.flash.maxEnergy", Byte.TYPE, (byte)6);
+
+        // int64 (single)
+        checkKeyGetAndSet("android.flash.firingTime", Long.TYPE, 0xABCD12345678FFFFL);
+
+        // float (single)
+        checkKeyGetAndSet("android.lens.aperture", Float.TYPE, Float.MAX_VALUE);
+
+        // double (single) -- technically double x 3, but we fake it
+        checkKeyGetAndSet("android.jpeg.gpsCoordinates", Double.TYPE, Double.MAX_VALUE);
+
+        // rational (single)
+        checkKeyGetAndSet("android.sensor.baseGainFactor", Rational.class, new Rational(1, 2));
+
+        /**
+         * Weirder cases, that don't map 1:1 with the native types
+         */
+
+        // bool (single) -- with TYPE_BYTE
+        checkKeyGetAndSet("android.control.aeLock", Boolean.TYPE, true);
+
+        // integer (single) -- with TYPE_BYTE
+        checkKeyGetAndSet("android.control.aePrecaptureTrigger", Integer.TYPE, 6);
+    }
+
+    @SmallTest
+    public void testReadWritePrimitiveArray() {
+        // int32 (n)
+        checkKeyGetAndSetArray("android.sensor.info.availableSensitivities", int[].class,
+                new int[] {
+                        0xC0FFEE, 0xDEADF00D
+                });
+
+        // byte (n)
+        checkKeyGetAndSetArray("android.statistics.faceScores", byte[].class, new byte[] {
+                1, 2, 3, 4
+        });
+
+        // int64 (n)
+        checkKeyGetAndSetArray("android.scaler.availableProcessedMinDurations", long[].class,
+                new long[] {
+                        0xABCD12345678FFFFL, 0x1234ABCD5678FFFFL, 0xFFFF12345678ABCDL
+                });
+
+        // float (n)
+        checkKeyGetAndSetArray("android.lens.info.availableApertures", float[].class,
+                new float[] {
+                        Float.MAX_VALUE, Float.MIN_NORMAL, Float.MIN_VALUE
+                });
+
+        // double (n) -- in particular double x 3
+        checkKeyGetAndSetArray("android.jpeg.gpsCoordinates", double[].class,
+                new double[] {
+                        Double.MAX_VALUE, Double.MIN_NORMAL, Double.MIN_VALUE
+                });
+
+        // rational (n) -- in particular rational x 9
+        checkKeyGetAndSetArray("android.sensor.calibrationTransform1", Rational[].class,
+                new Rational[] {
+                        new Rational(1, 2), new Rational(3, 4), new Rational(5, 6),
+                        new Rational(7, 8), new Rational(9, 10), new Rational(10, 11),
+                        new Rational(12, 13), new Rational(14, 15), new Rational(15, 16)
+                });
+
+        /**
+         * Weirder cases, that don't map 1:1 with the native types
+         */
+
+        // bool (n) -- with TYPE_BYTE
+        checkKeyGetAndSetArray("android.control.aeLock", boolean[].class, new boolean[] {
+                true, false, true
+        });
+
+
+        // integer (n) -- with TYPE_BYTE
+        checkKeyGetAndSetArray("android.control.aeAvailableModes", int[].class, new int[] {
+            1, 2, 3, 4
+        });
+    }
+
+    private enum ColorCorrectionMode {
+        TRANSFORM_MATRIX,
+        FAST,
+        HIGH_QUALITY
+    }
+
+    private enum AeAntibandingMode {
+        OFF,
+        _50HZ,
+        _60HZ,
+        AUTO
+    }
+
+    // TODO: special values for the enum.
+    private enum AvailableFormat {
+        RAW_SENSOR,
+        YV12,
+        YCrCb_420_SP,
+        IMPLEMENTATION_DEFINED,
+        YCbCr_420_888,
+        BLOB
+    }
+
+    @SmallTest
+    public void testReadWriteEnum() {
+        // byte (single)
+        checkKeyGetAndSet("android.colorCorrection.mode", ColorCorrectionMode.class,
+                ColorCorrectionMode.HIGH_QUALITY);
+
+        // byte (single)
+        checkKeyGetAndSet("android.control.aeAntibandingMode", AeAntibandingMode.class,
+                AeAntibandingMode.AUTO);
+
+        // byte (n)
+        checkKeyGetAndSetArray("android.control.aeAvailableAntibandingModes",
+                AeAntibandingMode[].class, new AeAntibandingMode[] {
+                        AeAntibandingMode.OFF, AeAntibandingMode._50HZ, AeAntibandingMode._60HZ,
+                        AeAntibandingMode.AUTO
+                });
+
+        /**
+         * Stranger cases that don't use byte enums
+         */
+        // int (n)
+        checkKeyGetAndSetArray("android.scaler.availableFormats", AvailableFormat[].class,
+                new AvailableFormat[] {
+                        AvailableFormat.RAW_SENSOR,
+                        AvailableFormat.YV12,
+                        AvailableFormat.IMPLEMENTATION_DEFINED
+                });
+
+    }
+
+    @SmallTest
+    public void testReadWriteEnumWithCustomValues() {
+        CameraMetadataNative.registerEnumValues(AeAntibandingMode.class, new int[] {
+            0,
+            10,
+            20,
+            30
+        });
+
+        // byte (single)
+        checkKeyGetAndSet("android.control.aeAntibandingMode", AeAntibandingMode.class,
+                AeAntibandingMode.AUTO);
+
+        // byte (n)
+        checkKeyGetAndSetArray("android.control.aeAvailableAntibandingModes",
+                AeAntibandingMode[].class, new AeAntibandingMode[] {
+                        AeAntibandingMode.OFF, AeAntibandingMode._50HZ, AeAntibandingMode._60HZ,
+                        AeAntibandingMode.AUTO
+                });
+
+        Key<AeAntibandingMode[]> aeAntibandingModeKey =
+                new Key<AeAntibandingMode[]>("android.control.aeAvailableAntibandingModes",
+                        AeAntibandingMode[].class);
+        byte[] aeAntibandingModeValues = mMetadata.readValues(CameraMetadataNative
+                .getTag("android.control.aeAvailableAntibandingModes"));
+        byte[] expectedValues = new byte[] { 0, 10, 20, 30 };
+        assertArrayEquals(expectedValues, aeAntibandingModeValues);
+
+
+        /**
+         * Stranger cases that don't use byte enums
+         */
+        // int (n)
+        CameraMetadataNative.registerEnumValues(AvailableFormat.class, new int[] {
+            0x20,
+            0x32315659,
+            0x11,
+            0x22,
+            0x23,
+            0x21,
+        });
+
+        checkKeyGetAndSetArray("android.scaler.availableFormats", AvailableFormat[].class,
+                new AvailableFormat[] {
+                        AvailableFormat.RAW_SENSOR,
+                        AvailableFormat.YV12,
+                        AvailableFormat.IMPLEMENTATION_DEFINED,
+                        AvailableFormat.YCbCr_420_888
+                });
+
+        Key<AeAntibandingMode> availableFormatsKey =
+                new Key<AeAntibandingMode>("android.scaler.availableFormats",
+                        AeAntibandingMode.class);
+        byte[] availableFormatValues = mMetadata.readValues(CameraMetadataNative
+                .getTag(availableFormatsKey.getName()));
+
+        int[] expectedIntValues = new int[] {
+                0x20,
+                0x32315659,
+                0x22,
+                0x23
+        };
+
+        ByteBuffer bf = ByteBuffer.wrap(availableFormatValues).order(ByteOrder.nativeOrder());
+
+        assertEquals(expectedIntValues.length * 4, availableFormatValues.length);
+        for (int i = 0; i < expectedIntValues.length; ++i) {
+            assertEquals(expectedIntValues[i], bf.getInt());
+        }
+    }
+
+    @SmallTest
+    public void testReadWriteSize() {
+        // int32 x n
+        checkKeyGetAndSet("android.jpeg.thumbnailSize", Size.class, new Size(123, 456));
+
+        // int32 x 2 x n
+        checkKeyGetAndSetArray("android.scaler.availableJpegSizes", Size[].class, new Size[] {
+            new Size(123, 456),
+            new Size(0xDEAD, 0xF00D),
+            new Size(0xF00, 0xB00)
+        });
+    }
+
+    @SmallTest
+    public void testReadWriteRectangle() {
+        // int32 x n
+        checkKeyGetAndSet("android.scaler.cropRegion", Rect.class, new Rect(10, 11, 1280, 1024));
+
+        // int32 x 2 x n
+        checkKeyGetAndSetArray("android.statistics.faceRectangles", Rect[].class, new Rect[] {
+            new Rect(110, 111, 11280, 11024),
+            new Rect(210, 111, 21280, 21024),
+            new Rect(310, 111, 31280, 31024)
+        });
+    }
+
+    @SmallTest
+    public void testReadWriteString() {
+        // (byte) string
+        Key<String> gpsProcessingMethodKey =
+                new Key<String>("android.jpeg.gpsProcessingMethod", String.class);
+
+        String helloWorld = new String("HelloWorld");
+        byte[] helloWorldBytes = new byte[] {
+                'H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd', '\0' };
+
+        mMetadata.set(gpsProcessingMethodKey, helloWorld);
+
+        String actual = mMetadata.get(gpsProcessingMethodKey);
+        assertEquals(helloWorld, actual);
+
+        byte[] actualBytes = mMetadata.readValues(getTag(gpsProcessingMethodKey.getName()));
+        assertArrayEquals(helloWorldBytes, actualBytes);
+
+        // Does not yet test as a string[] since we don't support that in native code.
+
+        // (byte) string
+        Key<String[]> gpsProcessingMethodKeyArray =
+                new Key<String[]>("android.jpeg.gpsProcessingMethod", String[].class);
+
+        String[] gpsStrings = new String[] { "HelloWorld", "FooBar", "Shazbot" };
+        byte[] gpsBytes = new byte[] {
+                'H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd', '\0',
+                'F', 'o', 'o', 'B', 'a', 'r', '\0',
+                'S', 'h', 'a', 'z', 'b', 'o', 't', '\0'};
+
+        mMetadata.set(gpsProcessingMethodKeyArray, gpsStrings);
+
+        String[] actualArray = mMetadata.get(gpsProcessingMethodKeyArray);
+        assertArrayEquals(gpsStrings, actualArray);
+
+        byte[] actualBytes2 = mMetadata.readValues(getTag(gpsProcessingMethodKeyArray.getName()));
+        assertArrayEquals(gpsBytes, actualBytes2);
+    }
+
+    <T> void compareGeneric(T expected, T actual) {
+        assertEquals(expected, actual);
+    }
+}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsBinderDecoratorTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsBinderDecoratorTest.java
new file mode 100644
index 0000000..727af78
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsBinderDecoratorTest.java
@@ -0,0 +1,172 @@
+/*
+ * 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.mediaframeworktest.unit;
+
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.utils.CameraBinderDecorator;
+import android.hardware.camera2.utils.CameraRuntimeException;
+import android.os.DeadObjectException;
+import android.os.RemoteException;
+import android.os.TransactionTooLargeException;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import static org.mockito.Mockito.*;
+import static android.hardware.camera2.utils.CameraBinderDecorator.*;
+import static android.hardware.camera2.CameraAccessException.*;
+
+import junit.framework.Assert;
+
+public class CameraUtilsBinderDecoratorTest extends junit.framework.TestCase {
+
+    private interface ICameraBinderStereotype {
+
+        double doNothing();
+
+        // int is a 'status_t'
+        int doSomethingPositive();
+
+        int doSomethingNoError();
+
+        int doSomethingPermissionDenied();
+
+        int doSomethingAlreadyExists();
+
+        int doSomethingBadValue();
+
+        int doSomethingDeadObject() throws CameraRuntimeException;
+
+        int doSomethingBadPolicy() throws CameraRuntimeException;
+
+        int doSomethingDeviceBusy() throws CameraRuntimeException;
+
+        int doSomethingNoSuchDevice() throws CameraRuntimeException;
+
+        int doSomethingUnknownErrorCode();
+
+        int doSomethingThrowDeadObjectException() throws RemoteException;
+
+        int doSomethingThrowTransactionTooLargeException() throws RemoteException;
+    }
+
+    private static final double SOME_ARBITRARY_DOUBLE = 1.0;
+    private static final int SOME_ARBITRARY_POSITIVE_INT = 5;
+    private static final int SOME_ARBITRARY_NEGATIVE_INT = -0xC0FFEE;
+
+    @SmallTest
+    public void testStereotypes() {
+
+        ICameraBinderStereotype mock = mock(ICameraBinderStereotype.class);
+        try {
+            when(mock.doNothing()).thenReturn(SOME_ARBITRARY_DOUBLE);
+            when(mock.doSomethingPositive()).thenReturn(SOME_ARBITRARY_POSITIVE_INT);
+            when(mock.doSomethingNoError()).thenReturn(NO_ERROR);
+            when(mock.doSomethingPermissionDenied()).thenReturn(PERMISSION_DENIED);
+            when(mock.doSomethingAlreadyExists()).thenReturn(ALREADY_EXISTS);
+            when(mock.doSomethingBadValue()).thenReturn(BAD_VALUE);
+            when(mock.doSomethingDeadObject()).thenReturn(DEAD_OBJECT);
+            when(mock.doSomethingBadPolicy()).thenReturn(EACCES);
+            when(mock.doSomethingDeviceBusy()).thenReturn(EBUSY);
+            when(mock.doSomethingNoSuchDevice()).thenReturn(ENODEV);
+            when(mock.doSomethingUnknownErrorCode()).thenReturn(SOME_ARBITRARY_NEGATIVE_INT);
+            when(mock.doSomethingThrowDeadObjectException()).thenThrow(new DeadObjectException());
+            when(mock.doSomethingThrowTransactionTooLargeException()).thenThrow(
+                    new TransactionTooLargeException());
+        } catch (RemoteException e) {
+            Assert.fail("Unreachable");
+        }
+
+        ICameraBinderStereotype decoratedMock = CameraBinderDecorator.newInstance(mock);
+
+        // ignored by decorator because return type is double, not int
+        assertEquals(SOME_ARBITRARY_DOUBLE, decoratedMock.doNothing());
+
+        // pass through for positive values
+        assertEquals(SOME_ARBITRARY_POSITIVE_INT, decoratedMock.doSomethingPositive());
+
+        // pass through NO_ERROR
+        assertEquals(NO_ERROR, decoratedMock.doSomethingNoError());
+
+        try {
+            decoratedMock.doSomethingPermissionDenied();
+            Assert.fail("Should've thrown SecurityException");
+        } catch (SecurityException e) {
+        }
+
+        assertEquals(ALREADY_EXISTS, decoratedMock.doSomethingAlreadyExists());
+
+        try {
+            decoratedMock.doSomethingBadValue();
+            Assert.fail("Should've thrown IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+        }
+
+        try {
+            decoratedMock.doSomethingDeadObject();
+            Assert.fail("Should've thrown CameraRuntimeException");
+        } catch (CameraRuntimeException e) {
+            assertEquals(CAMERA_DISCONNECTED, e.getReason());
+        }
+
+        try {
+            decoratedMock.doSomethingBadPolicy();
+            Assert.fail("Should've thrown CameraRuntimeException");
+        } catch (CameraRuntimeException e) {
+            assertEquals(CAMERA_DISABLED, e.getReason());
+        }
+
+        try {
+            decoratedMock.doSomethingDeviceBusy();
+            Assert.fail("Should've thrown CameraRuntimeException");
+        } catch (CameraRuntimeException e) {
+            assertEquals(CAMERA_IN_USE, e.getReason());
+        }
+
+        try {
+            decoratedMock.doSomethingNoSuchDevice();
+            Assert.fail("Should've thrown CameraRuntimeException");
+        } catch (CameraRuntimeException e) {
+            assertEquals(CAMERA_DISCONNECTED, e.getReason());
+        }
+
+        try {
+            decoratedMock.doSomethingUnknownErrorCode();
+            Assert.fail("Should've thrown UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+            assertEquals(String.format("Unknown error %d",
+                    SOME_ARBITRARY_NEGATIVE_INT), e.getMessage());
+        }
+
+        try {
+            decoratedMock.doSomethingThrowDeadObjectException();
+            Assert.fail("Should've thrown CameraRuntimeException");
+        } catch (CameraRuntimeException e) {
+            assertEquals(CAMERA_DISCONNECTED, e.getReason());
+        } catch (RemoteException e) {
+            Assert.fail("Should not throw a DeadObjectException directly, but rethrow");
+        }
+
+        try {
+            decoratedMock.doSomethingThrowTransactionTooLargeException();
+            Assert.fail("Should've thrown UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+            assertTrue(e.getCause() instanceof TransactionTooLargeException);
+        } catch (RemoteException e) {
+            Assert.fail("Should not throw a TransactionTooLargeException directly, but rethrow");
+        }
+    }
+
+}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsDecoratorTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsDecoratorTest.java
new file mode 100644
index 0000000..c3b6006
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsDecoratorTest.java
@@ -0,0 +1,171 @@
+/*
+ * 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.mediaframeworktest.unit;
+
+import android.test.suitebuilder.annotation.SmallTest;
+import android.hardware.camera2.utils.*;
+import android.hardware.camera2.utils.Decorator.DecoratorListener;
+
+import junit.framework.Assert;
+
+import java.lang.reflect.Method;
+
+/**
+ * adb shell am instrument -e class 'com.android.mediaframeworktest.unit.CameraUtilsDecoratorTest' \
+ *      -w com.android.mediaframeworktest/.MediaFrameworkUnitTestRunner
+ */
+public class CameraUtilsDecoratorTest extends junit.framework.TestCase {
+    private DummyListener mDummyListener;
+    private DummyInterface mIface;
+
+    @Override
+    public void setUp() {
+        mDummyListener = new DummyListener();
+        mIface = Decorator.newInstance(new DummyImpl(), mDummyListener);
+    }
+
+    interface DummyInterface {
+        int addValues(int x, int y, int z);
+
+        void raiseException() throws Exception;
+
+        void raiseUnsupportedOperationException() throws UnsupportedOperationException;
+    }
+
+    class DummyImpl implements DummyInterface {
+        @Override
+        public int addValues(int x, int y, int z) {
+            return x + y + z;
+        }
+
+        @Override
+        public void raiseException() throws Exception {
+            throw new Exception("Test exception");
+        }
+
+        @Override
+        public void raiseUnsupportedOperationException() throws UnsupportedOperationException {
+            throw new UnsupportedOperationException("Test exception");
+        }
+    }
+
+    class DummyListener implements DecoratorListener {
+
+        public boolean beforeCalled = false;
+        public boolean afterCalled = false;
+        public boolean catchCalled = false;
+        public boolean finallyCalled = false;
+        public Object resultValue = null;
+
+        public boolean raiseException = false;
+
+        @Override
+        public void onBeforeInvocation(Method m, Object[] args) {
+            beforeCalled = true;
+        }
+
+        @Override
+        public void onAfterInvocation(Method m, Object[] args, Object result) {
+            afterCalled = true;
+            resultValue = result;
+
+            if (raiseException) {
+                throw new UnsupportedOperationException("Test exception");
+            }
+        }
+
+        @Override
+        public boolean onCatchException(Method m, Object[] args, Throwable t) {
+            catchCalled = true;
+            return false;
+        }
+
+        @Override
+        public void onFinally(Method m, Object[] args) {
+            finallyCalled = true;
+        }
+
+    };
+
+    @SmallTest
+    public void testDecorator() {
+
+        // TODO rewrite this using mocks
+
+        assertTrue(mIface.addValues(1, 2, 3) == 6);
+        assertTrue(mDummyListener.beforeCalled);
+        assertTrue(mDummyListener.afterCalled);
+
+        int resultValue = (Integer)mDummyListener.resultValue;
+        assertTrue(resultValue == 6);
+        assertTrue(mDummyListener.finallyCalled);
+        assertFalse(mDummyListener.catchCalled);
+    }
+
+    @SmallTest
+    public void testDecoratorExceptions() {
+
+        boolean gotExceptions = false;
+        try {
+            mIface.raiseException();
+        } catch (Exception e) {
+            gotExceptions = true;
+            assertTrue(e.getMessage() == "Test exception");
+        }
+        assertTrue(gotExceptions);
+        assertTrue(mDummyListener.beforeCalled);
+        assertFalse(mDummyListener.afterCalled);
+        assertTrue(mDummyListener.catchCalled);
+        assertTrue(mDummyListener.finallyCalled);
+    }
+
+    @SmallTest
+    public void testDecoratorUnsupportedOperationException() {
+
+        boolean gotExceptions = false;
+        try {
+            mIface.raiseUnsupportedOperationException();
+        } catch (UnsupportedOperationException e) {
+            gotExceptions = true;
+            assertTrue(e.getMessage() == "Test exception");
+        }
+        assertTrue(gotExceptions);
+        assertTrue(mDummyListener.beforeCalled);
+        assertFalse(mDummyListener.afterCalled);
+        assertTrue(mDummyListener.catchCalled);
+        assertTrue(mDummyListener.finallyCalled);
+    }
+
+    @SmallTest
+    public void testDecoratorRaisesException() {
+
+        boolean gotExceptions = false;
+        try {
+            mDummyListener.raiseException = true;
+            mIface.addValues(1, 2, 3);
+            Assert.fail("unreachable");
+        } catch (UnsupportedOperationException e) {
+            gotExceptions = true;
+            assertTrue(e.getMessage() == "Test exception");
+        }
+        assertTrue(gotExceptions);
+        assertTrue(mDummyListener.beforeCalled);
+        assertTrue(mDummyListener.afterCalled);
+        assertFalse(mDummyListener.catchCalled);
+        assertTrue(mDummyListener.finallyCalled);
+    }
+}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsRuntimeExceptionTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsRuntimeExceptionTest.java
new file mode 100644
index 0000000..02c9f2a
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsRuntimeExceptionTest.java
@@ -0,0 +1,77 @@
+/*
+ * 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.mediaframeworktest.unit;
+
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.utils.CameraRuntimeException;
+import android.hardware.camera2.utils.UncheckedThrow;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import junit.framework.Assert;
+
+public class CameraUtilsRuntimeExceptionTest extends junit.framework.TestCase {
+
+    @SmallTest
+    public void testCameraRuntimeException1() {
+        try {
+            CameraRuntimeException runtimeExc = new CameraRuntimeException(12345);
+            throw runtimeExc.asChecked();
+        } catch (CameraAccessException e) {
+            assertEquals(12345, e.getReason());
+            assertNull(e.getMessage());
+            assertNull(e.getCause());
+        }
+    }
+
+    @SmallTest
+    public void testCameraRuntimeException2() {
+        try {
+            CameraRuntimeException runtimeExc = new CameraRuntimeException(12345, "Hello");
+            throw runtimeExc.asChecked();
+        } catch (CameraAccessException e) {
+            assertEquals(12345, e.getReason());
+            assertEquals("Hello", e.getMessage());
+            assertNull(e.getCause());
+        }
+    }
+
+    @SmallTest
+    public void testCameraRuntimeException3() {
+        Throwable cause = new IllegalStateException("For great justice");
+        try {
+            CameraRuntimeException runtimeExc = new CameraRuntimeException(12345, cause);
+            throw runtimeExc.asChecked();
+        } catch (CameraAccessException e) {
+            assertEquals(12345, e.getReason());
+            assertNull(e.getMessage());
+            assertEquals(cause, e.getCause());
+        }
+    }
+
+    @SmallTest
+    public void testCameraRuntimeException4() {
+        Throwable cause = new IllegalStateException("For great justice");
+        try {
+            CameraRuntimeException runtimeExc = new CameraRuntimeException(12345, "Hello", cause);
+            throw runtimeExc.asChecked();
+        } catch (CameraAccessException e) {
+            assertEquals(12345, e.getReason());
+            assertEquals("Hello", e.getMessage());
+            assertEquals(cause, e.getCause());
+        }
+    }
+}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsUncheckedThrowTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsUncheckedThrowTest.java
new file mode 100644
index 0000000..b648763
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsUncheckedThrowTest.java
@@ -0,0 +1,40 @@
+/*
+ * 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.mediaframeworktest.unit;
+
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.utils.UncheckedThrow;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import junit.framework.Assert;
+
+public class CameraUtilsUncheckedThrowTest extends junit.framework.TestCase {
+
+    private void fakeNeverThrowsCameraAccess() throws CameraAccessException {
+    }
+
+    @SmallTest
+    public void testUncheckedThrow() {
+        try {
+            UncheckedThrow.throwAnyException(new CameraAccessException(
+                    CameraAccessException.CAMERA_DISCONNECTED));
+            Assert.fail("unreachable");
+            fakeNeverThrowsCameraAccess();
+        } catch (CameraAccessException e) {
+        }
+    }
+}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java
new file mode 100644
index 0000000..9621f92
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java
@@ -0,0 +1,151 @@
+/*
+ * 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.mediaframeworktest.unit;
+
+import android.test.suitebuilder.annotation.SmallTest;
+import android.hardware.camera2.Rational;
+
+/**
+ * <pre>
+ * adb shell am instrument \
+ *      -e class 'com.android.mediaframeworktest.unit.RationalTest' \
+ *      -w com.android.mediaframeworktest/.MediaFrameworkUnitTestRunner
+ * </pre>
+ */
+public class RationalTest extends junit.framework.TestCase {
+    @SmallTest
+    public void testConstructor() {
+
+        // Simple case
+        Rational r = new Rational(1, 2);
+        assertEquals(1, r.getNumerator());
+        assertEquals(2, r.getDenominator());
+
+        // Denominator negative
+        r = new Rational(-1, 2);
+        assertEquals(-1, r.getNumerator());
+        assertEquals(2, r.getDenominator());
+
+        // Numerator negative
+        r = new Rational(1, -2);
+        assertEquals(-1, r.getNumerator());
+        assertEquals(2, r.getDenominator());
+
+        // Both negative
+        r = new Rational(-1, -2);
+        assertEquals(1, r.getNumerator());
+        assertEquals(2, r.getDenominator());
+
+        // Infinity.
+        r = new Rational(1, 0);
+        assertEquals(0, r.getNumerator());
+        assertEquals(0, r.getDenominator());
+
+        // Negative infinity.
+        r = new Rational(-1, 0);
+        assertEquals(0, r.getNumerator());
+        assertEquals(0, r.getDenominator());
+
+        // NaN.
+        r = new Rational(0, 0);
+        assertEquals(0, r.getNumerator());
+        assertEquals(0, r.getDenominator());
+    }
+
+    @SmallTest
+    public void testGcd() {
+        Rational r = new Rational(1, 2);
+        assertEquals(1, r.gcd());
+
+        Rational twoThirds = new Rational(2, 3);
+        assertEquals(1, twoThirds.gcd());
+
+        Rational moreComplicated2 = new Rational(5*78, 7*78);
+        assertEquals(78, moreComplicated2.gcd());
+
+        Rational oneHalf = new Rational(-1, 2);
+        assertEquals(1, oneHalf.gcd());
+
+        twoThirds = new Rational(-2, 3);
+        assertEquals(1, twoThirds.gcd());
+    }
+
+    @SmallTest
+    public void testEquals() {
+        Rational r = new Rational(1, 2);
+        assertEquals(1, r.getNumerator());
+        assertEquals(2, r.getDenominator());
+
+        assertEquals(r, r);
+        assertFalse(r.equals(null));
+        assertFalse(r.equals(new Object()));
+
+        Rational twoThirds = new Rational(2, 3);
+        assertFalse(r.equals(twoThirds));
+        assertFalse(twoThirds.equals(r));
+
+        Rational fourSixths = new Rational(4, 6);
+        assertEquals(twoThirds, fourSixths);
+        assertEquals(fourSixths, twoThirds);
+
+        Rational moreComplicated = new Rational(5*6*7*8*9, 1*2*3*4*5);
+        Rational moreComplicated2 = new Rational(5*6*7*8*9*78, 1*2*3*4*5*78);
+        assertEquals(moreComplicated, moreComplicated2);
+        assertEquals(moreComplicated2, moreComplicated);
+
+        // Ensure negatives are fine
+        twoThirds = new Rational(-2, 3);
+        fourSixths = new Rational(-4, 6);
+        assertEquals(twoThirds, fourSixths);
+        assertEquals(fourSixths, twoThirds);
+
+        moreComplicated = new Rational(-5*6*7*8*9, 1*2*3*4*5);
+        moreComplicated2 = new Rational(-5*6*7*8*9*78, 1*2*3*4*5*78);
+        assertEquals(moreComplicated, moreComplicated2);
+        assertEquals(moreComplicated2, moreComplicated);
+
+        Rational nan = new Rational(0, 0);
+        Rational nan2 = new Rational(0, 0);
+        assertTrue(nan.equals(nan));
+        assertTrue(nan.equals(nan2));
+        assertTrue(nan2.equals(nan));
+        assertFalse(nan.equals(r));
+        assertFalse(r.equals(nan));
+
+        // Infinities of the same sign are equal.
+        Rational posInf = new Rational(1, 0);
+        Rational posInf2 = new Rational(2, 0);
+        Rational negInf = new Rational(-1, 0);
+        Rational negInf2 = new Rational(-2, 0);
+        assertEquals(posInf, posInf);
+        assertEquals(negInf, negInf);
+        assertEquals(posInf, posInf2);
+        assertEquals(negInf, negInf2);
+
+        // Infinities aren't equal to anything else.
+        assertFalse(posInf.equals(negInf));
+        assertFalse(negInf.equals(posInf));
+        assertFalse(negInf.equals(r));
+        assertFalse(posInf.equals(r));
+        assertFalse(r.equals(negInf));
+        assertFalse(r.equals(posInf));
+        assertFalse(posInf.equals(nan));
+        assertFalse(negInf.equals(nan));
+        assertFalse(nan.equals(posInf));
+        assertFalse(nan.equals(negInf));
+    }
+}
diff --git a/media/tests/ScoAudioTest/src/com/android/scoaudiotest/ScoAudioTest.java b/media/tests/ScoAudioTest/src/com/android/scoaudiotest/ScoAudioTest.java
index fe3929d..0304640 100644
--- a/media/tests/ScoAudioTest/src/com/android/scoaudiotest/ScoAudioTest.java
+++ b/media/tests/ScoAudioTest/src/com/android/scoaudiotest/ScoAudioTest.java
@@ -429,7 +429,7 @@
                     mMediaRecorder.start();
                     mState = 1;
                 } catch (Exception e) {
-                    Log.e(TAG, "Could start MediaRecorder: " + e.toString());
+                    Log.e(TAG, "Could start MediaRecorder: ", e);
                     mMediaRecorder.release();
                     mMediaRecorder = null;
                     mState = 0;
@@ -439,7 +439,7 @@
                     mMediaRecorder.stop();
                     mMediaRecorder.reset();
                 } catch (Exception e) {
-                    Log.e(TAG, "Could not stop MediaRecorder: " + e.toString());
+                    Log.e(TAG, "Could not stop MediaRecorder: ", e);
                     mMediaRecorder.release();
                     mMediaRecorder = null;
                 } finally {
@@ -466,7 +466,7 @@
                 mMediaRecorder.prepare();
             }
             catch (Exception e) {
-                Log.e(TAG, "Could not prepare MediaRecorder: " + e.toString());
+                Log.e(TAG, "Could not prepare MediaRecorder: ", e);
                 mMediaRecorder.release();
                 mMediaRecorder = null;
             }
@@ -475,9 +475,14 @@
         @Override
         public void stop() {
             if (mMediaRecorder != null) {
-                mMediaRecorder.stop();
-                mMediaRecorder.release();
-                mMediaRecorder = null;
+                try {
+                    mMediaRecorder.stop();
+                } catch (Exception e) {
+                    Log.e(TAG, "Could not stop MediaRecorder: ", e);
+                } finally {
+                    mMediaRecorder.release();
+                    mMediaRecorder = null;
+                }
             }
             updatePlayPauseButton();
         }
diff --git a/native/android/Android.mk b/native/android/Android.mk
index 207cc4b..cda38e0 100644
--- a/native/android/Android.mk
+++ b/native/android/Android.mk
@@ -20,6 +20,7 @@
     liblog \
     libcutils \
     libandroidfw \
+    libinput \
     libutils \
     libbinder \
     libui \
diff --git a/native/android/input.cpp b/native/android/input.cpp
index f6ea576..e9d08b4 100644
--- a/native/android/input.cpp
+++ b/native/android/input.cpp
@@ -18,8 +18,8 @@
 #include <utils/Log.h>
 
 #include <android/input.h>
-#include <androidfw/Input.h>
-#include <androidfw/InputTransport.h>
+#include <input/Input.h>
+#include <input/InputTransport.h>
 #include <utils/Looper.h>
 #include <utils/RefBase.h>
 #include <utils/Vector.h>
diff --git a/nfc-extras/Android.mk b/nfc-extras/Android.mk
index 131d898..330e2d4 100644
--- a/nfc-extras/Android.mk
+++ b/nfc-extras/Android.mk
@@ -9,6 +9,3 @@
 LOCAL_MODULE:= com.android.nfc_extras
 
 include $(BUILD_JAVA_LIBRARY)
-
-# put the classes.jar, with full class files instead of classes.dex inside, into the dist directory
-$(call dist-for-goals, droidcore, $(full_classes_jar):com.android.nfc_extras.jar)
diff --git a/obex/javax/obex/ClientOperation.java b/obex/javax/obex/ClientOperation.java
index 05b498c..0c65283 100644
--- a/obex/javax/obex/ClientOperation.java
+++ b/obex/javax/obex/ClientOperation.java
@@ -121,6 +121,13 @@
                     (header).mAuthResp.length);
 
         }
+
+        if ((header).mConnectionID != null) {
+            mRequestHeader.mConnectionID = new byte[4];
+            System.arraycopy((header).mConnectionID, 0, mRequestHeader.mConnectionID, 0,
+                    4);
+
+        }
     }
 
     /**
@@ -420,7 +427,7 @@
                 //split the headerArray
                 end = ObexHelper.findHeaderEnd(headerArray, start, mMaxPacketSize
                         - ObexHelper.BASE_PACKET_LENGTH);
-                // can not split 
+                // can not split
                 if (end == -1) {
                     mOperationDone = true;
                     abort();
@@ -521,7 +528,7 @@
             return false;
         }
 
-        // send all of the output data in 0x48, 
+        // send all of the output data in 0x48,
         // send 0x49 with empty body
         if ((mPrivateOutput != null) && (mPrivateOutput.size() > 0))
             returnValue = true;
@@ -723,4 +730,7 @@
             }
         }
     }
+
+    public void noBodyHeader(){
+    }
 }
diff --git a/obex/javax/obex/HeaderSet.java b/obex/javax/obex/HeaderSet.java
index b89b707..2b3066f 100644
--- a/obex/javax/obex/HeaderSet.java
+++ b/obex/javax/obex/HeaderSet.java
@@ -464,6 +464,8 @@
                 return mHttpHeader;
             case WHO:
                 return mWho;
+            case CONNECTION_ID:
+                return mConnectionID;
             case OBJECT_CLASS:
                 return mObjectClass;
             case APPLICATION_PARAMETER:
diff --git a/obex/javax/obex/Operation.java b/obex/javax/obex/Operation.java
index 25656ed..5b4d5ac 100644
--- a/obex/javax/obex/Operation.java
+++ b/obex/javax/obex/Operation.java
@@ -178,4 +178,6 @@
     void close() throws IOException;
 
     int getMaxPacketSize();
+
+    public void noBodyHeader();
 }
diff --git a/obex/javax/obex/ServerOperation.java b/obex/javax/obex/ServerOperation.java
index d1476d2..fc441e0 100644
--- a/obex/javax/obex/ServerOperation.java
+++ b/obex/javax/obex/ServerOperation.java
@@ -88,6 +88,8 @@
 
     private boolean mHasBody;
 
+    private boolean mSendBodyHeader = true;
+
     /**
      * Creates new ServerOperation
      * @param p the parent that created this object
@@ -364,24 +366,33 @@
                  * (End of Body) otherwise, we need to send 0x48 (Body)
                  */
                 if ((finalBitSet) || (mPrivateOutput.isClosed())) {
-                    out.write(0x49);
+                    if(mSendBodyHeader == true) {
+                        out.write(0x49);
+                        bodyLength += 3;
+                        out.write((byte)(bodyLength >> 8));
+                        out.write((byte)bodyLength);
+                        out.write(body);
+                    }
                 } else {
+                    if(mSendBodyHeader == true) {
                     out.write(0x48);
+                    bodyLength += 3;
+                    out.write((byte)(bodyLength >> 8));
+                    out.write((byte)bodyLength);
+                    out.write(body);
+                    }
                 }
 
-                bodyLength += 3;
-                out.write((byte)(bodyLength >> 8));
-                out.write((byte)bodyLength);
-                out.write(body);
             }
         }
 
         if ((finalBitSet) && (type == ResponseCodes.OBEX_HTTP_OK) && (orginalBodyLength <= 0)) {
-            out.write(0x49);
-            orginalBodyLength = 3;
-            out.write((byte)(orginalBodyLength >> 8));
-            out.write((byte)orginalBodyLength);
-
+            if(mSendBodyHeader == true) {
+                out.write(0x49);
+                orginalBodyLength = 3;
+                out.write((byte)(orginalBodyLength >> 8));
+                out.write((byte)orginalBodyLength);
+            }
         }
 
         mResponseSize = 3;
@@ -711,4 +722,8 @@
     public void streamClosed(boolean inStream) throws IOException {
 
     }
+
+    public void noBodyHeader(){
+        mSendBodyHeader = false;
+    }
 }
diff --git a/obex/javax/obex/ServerSession.java b/obex/javax/obex/ServerSession.java
index a4b9759..f1b9a0d 100644
--- a/obex/javax/obex/ServerSession.java
+++ b/obex/javax/obex/ServerSession.java
@@ -256,6 +256,10 @@
     public void sendResponse(int code, byte[] header) throws IOException {
         int totalLength = 3;
         byte[] data = null;
+        OutputStream op = mOutput;
+        if (op == null) {
+            return;
+        }
 
         if (header != null) {
             totalLength += header.length;
@@ -270,8 +274,8 @@
             data[1] = (byte)0x00;
             data[2] = (byte)totalLength;
         }
-        mOutput.write(data);
-        mOutput.flush();
+        op.write(data);
+        op.flush();
     }
 
     /**
diff --git a/opengl/java/android/opengl/EGL14.java b/opengl/java/android/opengl/EGL14.java
index cd53c17..b93557d 100644
--- a/opengl/java/android/opengl/EGL14.java
+++ b/opengl/java/android/opengl/EGL14.java
@@ -1,5 +1,4 @@
 /*
-**
 ** Copyright 2012, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/opengl/java/android/opengl/EGLConfig.java b/opengl/java/android/opengl/EGLConfig.java
index d457c9f..a7a6bbb 100644
--- a/opengl/java/android/opengl/EGLConfig.java
+++ b/opengl/java/android/opengl/EGLConfig.java
@@ -29,7 +29,7 @@
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
+        if (!(o instanceof EGLConfig)) return false;
 
         EGLConfig that = (EGLConfig) o;
         return getHandle() == that.getHandle();
diff --git a/opengl/java/android/opengl/EGLContext.java b/opengl/java/android/opengl/EGLContext.java
index 41b8ef1..c93bd6e 100644
--- a/opengl/java/android/opengl/EGLContext.java
+++ b/opengl/java/android/opengl/EGLContext.java
@@ -29,7 +29,7 @@
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
+        if (!(o instanceof EGLContext)) return false;
 
         EGLContext that = (EGLContext) o;
         return getHandle() == that.getHandle();
diff --git a/opengl/java/android/opengl/EGLDisplay.java b/opengl/java/android/opengl/EGLDisplay.java
index 17d1a64..5b8043a 100644
--- a/opengl/java/android/opengl/EGLDisplay.java
+++ b/opengl/java/android/opengl/EGLDisplay.java
@@ -29,7 +29,7 @@
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
+        if (!(o instanceof EGLDisplay)) return false;
 
         EGLDisplay that = (EGLDisplay) o;
         return getHandle() == that.getHandle();
diff --git a/opengl/java/android/opengl/EGLExt.java b/opengl/java/android/opengl/EGLExt.java
index 2e0363d1..b74b5fb 100644
--- a/opengl/java/android/opengl/EGLExt.java
+++ b/opengl/java/android/opengl/EGLExt.java
@@ -1,5 +1,4 @@
 /*
-**
 ** Copyright 2013, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/opengl/java/android/opengl/EGLSurface.java b/opengl/java/android/opengl/EGLSurface.java
index 65bec4f..c379dc9 100644
--- a/opengl/java/android/opengl/EGLSurface.java
+++ b/opengl/java/android/opengl/EGLSurface.java
@@ -29,7 +29,7 @@
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
+        if (!(o instanceof EGLSurface)) return false;
 
         EGLSurface that = (EGLSurface) o;
         return getHandle() == that.getHandle();
diff --git a/opengl/java/android/opengl/Matrix.java b/opengl/java/android/opengl/Matrix.java
index 72128ac..ce3f57e 100644
--- a/opengl/java/android/opengl/Matrix.java
+++ b/opengl/java/android/opengl/Matrix.java
@@ -19,24 +19,21 @@
 /**
  * Matrix math utilities. These methods operate on OpenGL ES format
  * matrices and vectors stored in float arrays.
- *
+ * <p>
  * Matrices are 4 x 4 column-vector matrices stored in column-major
  * order:
  * <pre>
  *  m[offset +  0] m[offset +  4] m[offset +  8] m[offset + 12]
  *  m[offset +  1] m[offset +  5] m[offset +  9] m[offset + 13]
  *  m[offset +  2] m[offset +  6] m[offset + 10] m[offset + 14]
- *  m[offset +  3] m[offset +  7] m[offset + 11] m[offset + 15]
- * </pre>
+ *  m[offset +  3] m[offset +  7] m[offset + 11] m[offset + 15]</pre>
  *
- * Vectors are 4 row x 1 column column-vectors stored in order:
+ * Vectors are 4 x 1 column vectors stored in order:
  * <pre>
  * v[offset + 0]
  * v[offset + 1]
  * v[offset + 2]
- * v[offset + 3]
- * </pre>
- *
+ * v[offset + 3]</pre>
  */
 public class Matrix {
 
@@ -44,12 +41,18 @@
     private final static float[] sTemp = new float[32];
 
     /**
-     * Multiply two 4x4 matrices together and store the result in a third 4x4
+     * @deprecated All methods are static, do not instantiate this class.
+     */
+    @Deprecated
+    public Matrix() {}
+
+    /**
+     * Multiplies two 4x4 matrices together and stores the result in a third 4x4
      * matrix. In matrix notation: result = lhs x rhs. Due to the way
      * matrix multiplication works, the result matrix will have the same
      * effect as first multiplying by the rhs matrix, then multiplying by
      * the lhs matrix. This is the opposite of what you might expect.
-     *
+     * <p>
      * The same float array may be passed for result, lhs, and/or rhs. However,
      * the result element values are undefined if the result elements overlap
      * either the lhs or rhs elements.
@@ -70,9 +73,9 @@
             float[] lhs, int lhsOffset, float[] rhs, int rhsOffset);
 
     /**
-     * Multiply a 4 element vector by a 4x4 matrix and store the result in a 4
-     * element column vector. In matrix notation: result = lhs x rhs
-     *
+     * Multiplies a 4 element vector by a 4x4 matrix and stores the result in a
+     * 4-element column vector. In matrix notation: result = lhs x rhs
+     * <p>
      * The same float array may be passed for resultVec, lhsMat, and/or rhsVec.
      * However, the resultVec element values are undefined if the resultVec
      * elements overlap either the lhsMat or rhsVec elements.
@@ -97,12 +100,14 @@
 
     /**
      * Transposes a 4 x 4 matrix.
+     * <p>
+     * mTrans and m must not overlap.
      *
-     * @param mTrans the array that holds the output inverted matrix
-     * @param mTransOffset an offset into mInv where the inverted matrix is
+     * @param mTrans the array that holds the output transposed matrix
+     * @param mTransOffset an offset into mTrans where the transposed matrix is
      *        stored.
      * @param m the input array
-     * @param mOffset an offset into m where the matrix is stored.
+     * @param mOffset an offset into m where the input matrix is stored.
      */
     public static void transposeM(float[] mTrans, int mTransOffset, float[] m,
             int mOffset) {
@@ -117,12 +122,14 @@
 
     /**
      * Inverts a 4 x 4 matrix.
+     * <p>
+     * mInv and m must not overlap.
      *
      * @param mInv the array that holds the output inverted matrix
      * @param mInvOffset an offset into mInv where the inverted matrix is
      *        stored.
      * @param m the input array
-     * @param mOffset an offset into m where the matrix is stored.
+     * @param mOffset an offset into m where the input matrix is stored.
      * @return true if the matrix could be inverted, false if it could not.
      */
     public static boolean invertM(float[] mInv, int mInvOffset, float[] m,
@@ -301,10 +308,11 @@
 
 
     /**
-     * Define a projection matrix in terms of six clip planes
-     * @param m the float array that holds the perspective matrix
+     * Defines a projection matrix in terms of six clip planes.
+     *
+     * @param m the float array that holds the output perspective matrix
      * @param offset the offset into float array m where the perspective
-     * matrix data is written
+     *        matrix data is written
      * @param left
      * @param right
      * @param bottom
@@ -358,11 +366,12 @@
     }
 
     /**
-     * Define a projection matrix in terms of a field of view angle, an
-     * aspect ratio, and z clip planes
+     * Defines a projection matrix in terms of a field of view angle, an
+     * aspect ratio, and z clip planes.
+     *
      * @param m the float array that holds the perspective matrix
      * @param offset the offset into float array m where the perspective
-     * matrix data is written
+     *        matrix data is written
      * @param fovy field of view in y direction, in degrees
      * @param aspect width to height aspect ratio of the viewport
      * @param zNear
@@ -395,7 +404,7 @@
     }
 
     /**
-     * Computes the length of a vector
+     * Computes the length of a vector.
      *
      * @param x x coordinate of a vector
      * @param y y coordinate of a vector
@@ -408,6 +417,7 @@
 
     /**
      * Sets matrix m to the identity matrix.
+     *
      * @param sm returns the result
      * @param smOffset index into sm where the result matrix starts
      */
@@ -421,7 +431,10 @@
     }
 
     /**
-     * Scales matrix  m by x, y, and z, putting the result in sm
+     * Scales matrix m by x, y, and z, putting the result in sm.
+     * <p>
+     * m and sm must not overlap.
+     *
      * @param sm returns the result
      * @param smOffset index into sm where the result matrix starts
      * @param m source matrix
@@ -444,7 +457,8 @@
     }
 
     /**
-     * Scales matrix m in place by sx, sy, and sz
+     * Scales matrix m in place by sx, sy, and sz.
+     *
      * @param m matrix to scale
      * @param mOffset index into m where the matrix starts
      * @param x scale factor x
@@ -462,7 +476,10 @@
     }
 
     /**
-     * Translates matrix m by x, y, and z, putting the result in tm
+     * Translates matrix m by x, y, and z, putting the result in tm.
+     * <p>
+     * m and tm must not overlap.
+     *
      * @param tm returns the result
      * @param tmOffset index into sm where the result matrix starts
      * @param m source matrix
@@ -487,6 +504,7 @@
 
     /**
      * Translates matrix m by x, y, and z in place.
+     *
      * @param m matrix
      * @param mOffset index into m where the matrix starts
      * @param x translation factor x
@@ -503,15 +521,18 @@
     }
 
     /**
-     * Rotates matrix m by angle a (in degrees) around the axis (x, y, z)
+     * Rotates matrix m by angle a (in degrees) around the axis (x, y, z).
+     * <p>
+     * m and rm must not overlap.
+     *
      * @param rm returns the result
      * @param rmOffset index into rm where the result matrix starts
      * @param m source matrix
      * @param mOffset index into m where the source matrix starts
      * @param a angle to rotate in degrees
-     * @param x scale factor x
-     * @param y scale factor y
-     * @param z scale factor z
+     * @param x X axis component
+     * @param y Y axis component
+     * @param z Z axis component
      */
     public static void rotateM(float[] rm, int rmOffset,
             float[] m, int mOffset,
@@ -524,13 +545,14 @@
 
     /**
      * Rotates matrix m in place by angle a (in degrees)
-     * around the axis (x, y, z)
+     * around the axis (x, y, z).
+     *
      * @param m source matrix
      * @param mOffset index into m where the matrix starts
      * @param a angle to rotate in degrees
-     * @param x scale factor x
-     * @param y scale factor y
-     * @param z scale factor z
+     * @param x X axis component
+     * @param y Y axis component
+     * @param z Z axis component
      */
     public static void rotateM(float[] m, int mOffset,
             float a, float x, float y, float z) {
@@ -542,13 +564,18 @@
     }
 
     /**
-     * Rotates matrix m by angle a (in degrees) around the axis (x, y, z)
+     * Creates a matrix for rotation by angle a (in degrees)
+     * around the axis (x, y, z).
+     * <p>
+     * An optimized path will be used for rotation about a major axis
+     * (e.g. x=1.0f y=0.0f z=0.0f).
+     *
      * @param rm returns the result
      * @param rmOffset index into rm where the result matrix starts
      * @param a angle to rotate in degrees
-     * @param x scale factor x
-     * @param y scale factor y
-     * @param z scale factor z
+     * @param x X axis component
+     * @param y Y axis component
+     * @param z Z axis component
      */
     public static void setRotateM(float[] rm, int rmOffset,
             float a, float x, float y, float z) {
@@ -608,7 +635,8 @@
     }
 
     /**
-     * Converts Euler angles to a rotation matrix
+     * Converts Euler angles to a rotation matrix.
+     *
      * @param rm returns the result
      * @param rmOffset index into rm where the result matrix starts
      * @param x angle of rotation, in degrees
@@ -651,7 +679,7 @@
     }
 
     /**
-     * Define a viewing transformation in terms of an eye point, a center of
+     * Defines a viewing transformation in terms of an eye point, a center of
      * view, and an up vector.
      *
      * @param rm returns the result
diff --git a/packages/BackupRestoreConfirmation/Android.mk b/packages/BackupRestoreConfirmation/Android.mk
index e775b44..b84c07f 100644
--- a/packages/BackupRestoreConfirmation/Android.mk
+++ b/packages/BackupRestoreConfirmation/Android.mk
@@ -23,6 +23,7 @@
 
 LOCAL_PACKAGE_NAME := BackupRestoreConfirmation
 LOCAL_CERTIFICATE := platform
+LOCAL_PRIVILEGED_MODULE := true
 
 include $(BUILD_PACKAGE)
 
diff --git a/packages/BackupRestoreConfirmation/res/values-af/strings.xml b/packages/BackupRestoreConfirmation/res/values-af/strings.xml
index fadd125..0bf54cf 100644
--- a/packages/BackupRestoreConfirmation/res/values-af/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-af/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Volledige rugsteun"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Volledige herstel"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"\'n Volledige rugsteun van al die data na \'n rekenaar is aangevra. Wil jy dit toelaat? "\n\n"As jy nie self die rugsteun versoek het nie, moenie toelaat dat die aksie voortgaan nie."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"\'n Volledige rugsteun van al die data na \'n rekenaar is aangevra. Wil jy dit toelaat? \n\nAs jy nie self die rugsteun versoek het nie, moenie toelaat dat die aksie voortgaan nie."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Rugsteun my data"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Moenie rugsteun nie"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"\'n Volle teruglaai van alle data van \'n gekoppelde rekenaar is versoek. Wil jy dit toelaat? "\n\n" As jy nie die teruglaai self versoek het nie, moenie die aksie toelaat nie. Dit sal enige data tans op die toestel vervang!"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"\'n Volle teruglaai van alle data van \'n gekoppelde rekenaar is versoek. Wil jy dit toelaat? \n\n As jy nie die teruglaai self versoek het nie, moenie die aksie toelaat nie. Dit sal enige data tans op die toestel vervang!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Laai my data terug"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Moenie herstel nie"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Voer asseblief jou huidige rugsteunwagwoord hieronder in:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-am/strings.xml b/packages/BackupRestoreConfirmation/res/values-am/strings.xml
index 512d917..ec5b9631 100644
--- a/packages/BackupRestoreConfirmation/res/values-am/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-am/strings.xml
@@ -18,10 +18,10 @@
     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>
diff --git a/packages/BackupRestoreConfirmation/res/values-ar/strings.xml b/packages/BackupRestoreConfirmation/res/values-ar/strings.xml
index 2e9ec40..6a6edd9 100644
--- a/packages/BackupRestoreConfirmation/res/values-ar/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-ar/strings.xml
@@ -18,10 +18,10 @@
     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>
diff --git a/packages/BackupRestoreConfirmation/res/values-be/strings.xml b/packages/BackupRestoreConfirmation/res/values-be/strings.xml
index 4836125..188041a 100644
--- a/packages/BackupRestoreConfirmation/res/values-be/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-be/strings.xml
@@ -18,10 +18,10 @@
     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"Калі вы самі не запытвалі рэзервовае капiяванне, спынiце аперацыю."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Было прапанавана поўнае рэзервовае капіяванне ўсіх дадзеных на падлучаным настольным кампутары. Дазволіць гэта?\n\nКалі вы самі не запытвалі рэзервовае капiяванне, спынiце аперацыю."</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-bg/strings.xml b/packages/BackupRestoreConfirmation/res/values-bg/strings.xml
index a431bf7..c332774 100644
--- a/packages/BackupRestoreConfirmation/res/values-bg/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-bg/strings.xml
@@ -18,10 +18,10 @@
     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>
diff --git a/packages/BackupRestoreConfirmation/res/values-ca/strings.xml b/packages/BackupRestoreConfirmation/res/values-ca/strings.xml
index 32cfefc..359df47 100644
--- a/packages/BackupRestoreConfirmation/res/values-ca/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-ca/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Còpia de seguretat completa"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Restaura completament"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"S\'ha sol·licitat una còpia de seguretat completa de totes les dades a un equip de sobretaula connectat. Vols permetre que això passi?"\n" "\n"Si no has sol·licitat la còpia de seguretat tu mateix, no permetis que continuï l\'operació."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"S\'ha sol·licitat una còpia de seguretat completa de totes les dades a un equip de sobretaula connectat. Vols permetre que això passi?\n \nSi no has sol·licitat la còpia de seguretat tu mateix, no permetis que continuï l\'operació."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Còpia de seguretat de dades"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"No en facis una còpia de seguretat"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"S\'ha sol·licitat una restauració completa de totes les dades d\'un equip d\'escriptori connectat. Vols permetre que això passi?"\n" "\n"Si no has sol·licitat la restauració tu mateix, no permetis que continuï l\'operació. Això reemplaçarà les dades que hi hagi actualment a l\'equip."</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"S\'ha sol·licitat una restauració completa de totes les dades d\'un equip d\'escriptori connectat. Vols permetre que això passi?\n \nSi no has sol·licitat la restauració tu mateix, no permetis que continuï l\'operació. Això reemplaçarà les dades que hi hagi actualment a l\'equip."</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Restaura les meves dades"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"No ho restauris"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Introdueix la teva contrasenya actual de còpia de seguretat a continuació:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-cs/strings.xml b/packages/BackupRestoreConfirmation/res/values-cs/strings.xml
index 0732cd8..c46916b 100644
--- a/packages/BackupRestoreConfirmation/res/values-cs/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-cs/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Úplná záloha"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Úplné obnovení"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"Obdrželi jsme požadavek na úplnou zálohu všech dat do připojeného počítače. Chcete tuto akci povolit? "\n\n"Pokud jste o zálohu nežádali, operaci nepovolujte."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Obdrželi jsme požadavek na úplnou zálohu všech dat do připojeného počítače. Chcete tuto akci povolit? \n\nPokud jste o zálohu nežádali, operaci nepovolujte."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Zálohovat data"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Nezálohovat"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"Obdrželi jsme žádost o úplné obnovení všech dat z připojeného počítače. Chcete tuto akci povolit?"\n\n"Pokud jste o obnovení nepožádali, operaci nepovolujte. Tato akce nahradí veškerá data v zařízení."</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Obdrželi jsme žádost o úplné obnovení všech dat z připojeného počítače. Chcete tuto akci povolit?\n\nPokud jste o obnovení nepožádali, operaci nepovolujte. Tato akce nahradí veškerá data v zařízení."</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Obnovit moje data"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Neobnovovat"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Zadejte prosím aktuální heslo pro zálohy níže:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-da/strings.xml b/packages/BackupRestoreConfirmation/res/values-da/strings.xml
index b3756d9..0a84c30 100644
--- a/packages/BackupRestoreConfirmation/res/values-da/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-da/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Fuld sikkerhedskopiering"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Fuld genoprettelse"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"Der er anmodet om en fuld sikkerhedskopiering af alle data til en tilsluttet stationær computer. Vil du tillade dette?"\n\n"Hvis du ikke har anmodet om sikkerhedskopiering, skal du ikke tillade denne handling."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Der er anmodet om en fuld sikkerhedskopiering af alle data til en tilsluttet stationær computer. Vil du tillade dette?\n\nHvis du ikke har anmodet om sikkerhedskopiering, skal du ikke tillade denne handling."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Sikkerhedskopier mine data"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Undlad at sikkerhedskopiere"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"Der er anmodet om en fuld sikkerhedskopiering af alle data til en tilsluttet stationær computer. Vil du tillade dette?"\n\n"Hvis du ikke har anmodet om sikkerhedskopiering, skal du ikke tillade denne handling."</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Der er anmodet om en fuld sikkerhedskopiering af alle data til en tilsluttet stationær computer. Vil du tillade dette?\n\nHvis du ikke har anmodet om sikkerhedskopiering, skal du ikke tillade denne handling."</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Gendan mine data"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Gendan ikke"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Indtast din aktuelle adgangskode til sikkerhedskopiering nedenfor:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-de/strings.xml b/packages/BackupRestoreConfirmation/res/values-de/strings.xml
index a8f2d13..91a1dff 100644
--- a/packages/BackupRestoreConfirmation/res/values-de/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-de/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Vollständige Sicherung"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Vollständige Wiederherstellung"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"Es wurde eine vollständige Sicherung sämtlicher Daten auf einen verbundenen Desktop-Computer angefordert. Möchten Sie dies zulassen?"\n\n"Wenn Sie die Sicherung nicht selbst angefordert haben, sollten Sie dem Vorgang nicht zustimmen."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Es wurde eine vollständige Sicherung sämtlicher Daten auf einen verbundenen Desktop-Computer angefordert. Möchten Sie dies zulassen?\n\nWenn Sie die Sicherung nicht selbst angefordert haben, sollten Sie dem Vorgang nicht zustimmen."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Meine Daten sichern"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Nicht sichern"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"Es wurde eine vollständige Wiederherstellung aller Daten von einem verbundenen Desktop-Computer angefordert. Möchten Sie dies zulassen?"\n\n"Wenn Sie die Wiederherstellung nicht selbst angefordert haben, sollten Sie dem Vorgang nicht zustimmen. Dadurch werden alle zurzeit auf dem Gerät befindlichen Daten ersetzt!"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Es wurde eine vollständige Wiederherstellung aller Daten von einem verbundenen Desktop-Computer angefordert. Möchten Sie dies zulassen?\n\nWenn Sie die Wiederherstellung nicht selbst angefordert haben, sollten Sie dem Vorgang nicht zustimmen. Dadurch werden alle zurzeit auf dem Gerät befindlichen Daten ersetzt!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Meine Daten wiederherstellen"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Nicht wiederherstellen"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Geben Sie Ihr aktuelles Sicherungspasswort unten ein:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-el/strings.xml b/packages/BackupRestoreConfirmation/res/values-el/strings.xml
index 13a78cb..cd325ef 100644
--- a/packages/BackupRestoreConfirmation/res/values-el/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-el/strings.xml
@@ -18,10 +18,10 @@
     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>
diff --git a/packages/BackupRestoreConfirmation/res/values-en-rGB/strings.xml b/packages/BackupRestoreConfirmation/res/values-en-rGB/strings.xml
index 7b94e2e..d096d98 100644
--- a/packages/BackupRestoreConfirmation/res/values-en-rGB/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-en-rGB/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Full backup"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Full restoration"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"A full backup of all data to a connected desktop computer has been requested. Do you want to allow this to happen?"\n\n"If you did not request the backup yourself, do not allow the operation to proceed."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"A full backup of all data to a connected desktop computer has been requested. Do you want to allow this to happen?\n\nIf you did not request the backup yourself, do not allow the operation to proceed."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Back up my data"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Do not back up"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"A full restore of all data from a connected desktop computer has been requested. Do you want to allow this to happen?"\n\n"If you did not request the restore yourself, do not allow the operation to proceed. This will replace any data currently on the device!"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"A full restore of all data from a connected desktop computer has been requested. Do you want to allow this to happen?\n\nIf you did not request the restore yourself, do not allow the operation to proceed. This will replace any data currently on the device!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Restore my data"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Do not restore"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Please enter your current backup password below:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-en-rIN/strings.xml b/packages/BackupRestoreConfirmation/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..d096d98
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-en-rIN/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<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">"Full backup"</string>
+    <string name="restore_confirm_title" msgid="5469365809567486602">"Full restoration"</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"A full backup of all data to a connected desktop computer has been requested. Do you want to allow this to happen?\n\nIf you did not request the backup yourself, do not allow the operation to proceed."</string>
+    <string name="allow_backup_button_label" msgid="4217228747769644068">"Back up my data"</string>
+    <string name="deny_backup_button_label" msgid="6009119115581097708">"Do not back up"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"A full restore of all data from a connected desktop computer has been requested. Do you want to allow this to happen?\n\nIf you did not request the restore yourself, do not allow the operation to proceed. This will replace any data currently on the device!"</string>
+    <string name="allow_restore_button_label" msgid="3081286752277127827">"Restore my data"</string>
+    <string name="deny_restore_button_label" msgid="1724367334453104378">"Do not restore"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"Please enter your current backup password below:"</string>
+    <string name="device_encryption_restore_text" msgid="1570864916855208992">"Please enter your device encryption password below."</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"Please enter your device encryption password below. This will also be used to encrypt the backup archive."</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"Please enter a password to use for encrypting the full backup data. If this is left blank, your current backup password will be used:"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"If you wish to encrypt the full backup data, enter a password below:"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"If the restore data is encrypted, please enter the password below:"</string>
+    <string name="toast_backup_started" msgid="550354281452756121">"Backup starting..."</string>
+    <string name="toast_backup_ended" msgid="3818080769548726424">"Backup finished"</string>
+    <string name="toast_restore_started" msgid="7881679218971277385">"Restoration starting..."</string>
+    <string name="toast_restore_ended" msgid="1764041639199696132">"Restoration ended"</string>
+    <string name="toast_timeout" msgid="5276598587087626877">"Operation timed out"</string>
+</resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-es-rUS/strings.xml b/packages/BackupRestoreConfirmation/res/values-es-rUS/strings.xml
index 21afa31..13ce1da 100644
--- a/packages/BackupRestoreConfirmation/res/values-es-rUS/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-es-rUS/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Realización de la copia de seguridad completa"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Restauración completa"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"Se ha solicitado una copia de seguridad completa de todos los datos en una computadora de escritorio conectada. ¿Deseas permitirla?"\n\n"Si tú no has solicitado la copia de seguridad, no permitas que se realice la operación."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Se ha solicitado una copia de seguridad completa de todos los datos en una computadora de escritorio conectada. ¿Deseas permitirla?\n\nSi tú no has solicitado la copia de seguridad, no permitas que se realice la operación."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Copia de seguridad de mis datos"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"No realizar una copia de seguridad"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"Se ha solicitado una restauración completa de todos los datos de una computadora de escritorio conectada. ¿Deseas permitirla?"\n\n"Si tú no has solicitado la restauración, no permitas que se realice la operación. Esto reemplazaría los datos actuales del dispositivo."</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Se ha solicitado una restauración completa de todos los datos de una computadora de escritorio conectada. ¿Deseas permitirla?\n\nSi tú no has solicitado la restauración, no permitas que se realice la operación. Esto reemplazaría los datos actuales del dispositivo."</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Restaurar mis datos"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"No restaurar"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Introduce tu contraseña actual de copia de seguridad a continuación:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-es/strings.xml b/packages/BackupRestoreConfirmation/res/values-es/strings.xml
index ef97e3c..7ce3990 100644
--- a/packages/BackupRestoreConfirmation/res/values-es/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-es/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Copia de seguridad completa"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Restauración completa"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"Se ha solicitado una copia de seguridad completa de todos los datos en un ordenador conectado. ¿Quieres permitir la copia de seguridad?"\n\n"No debes permitir la copia de seguridad si no has realizado tú la solicitud."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Se ha solicitado una copia de seguridad completa de todos los datos en un ordenador conectado. ¿Quieres permitir la copia de seguridad?\n\nNo debes permitir la copia de seguridad si no has realizado tú la solicitud."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Copia de seguridad de datos"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"No hacer copia de seguridad"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"Se ha solicitado una restauración completa de todos los datos desde un ordenador conectado. ¿Quieres permitir la restauración?"\n\n"No debes permitir la restauración si no has realizado tú la solicitud. Se sustituirán los datos actuales del dispositivo."</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Se ha solicitado una restauración completa de todos los datos desde un ordenador conectado. ¿Quieres permitir la restauración?\n\nNo debes permitir la restauración si no has realizado tú la solicitud. Se sustituirán los datos actuales del dispositivo."</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Restaurar mis datos"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"No restaurar"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Introduce a continuación la contraseña actual de copia de seguridad:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-et-rEE/strings.xml b/packages/BackupRestoreConfirmation/res/values-et-rEE/strings.xml
new file mode 100644
index 0000000..0f5fde2
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-et-rEE/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<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">"Täielik varundus"</string>
+    <string name="restore_confirm_title" msgid="5469365809567486602">"Täielik taastamine"</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Taotleti kõikide andmete varundamist ühendatud lauaarvutist. Kas soovite seda lubada?\n\nKui te ei taotlenud varundust, siis ärge lubage toimingut jätkata."</string>
+    <string name="allow_backup_button_label" msgid="4217228747769644068">"Varunda mu andmed"</string>
+    <string name="deny_backup_button_label" msgid="6009119115581097708">"Ära varunda"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Taotletud on kõikide andmete taastamist ühendatud lauaarvutist. Kas soovite seda lubada?\n\nKui te ei taotlenud taastamist, siis ärge lubage toimingut jätkata. See asendab kõik praegu seadmes olevad andmed."</string>
+    <string name="allow_restore_button_label" msgid="3081286752277127827">"Taasta mu andmed"</string>
+    <string name="deny_restore_button_label" msgid="1724367334453104378">"Ära taasta"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"Sisestage allpool praegune varunduse parool:"</string>
+    <string name="device_encryption_restore_text" msgid="1570864916855208992">"Sisestage allpool oma seadme krüpteerimise parool."</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"Sisestage allpool oma seadme krüpteerimise parool. Seda kasutatakse ka varukoopiate arhiivi krüpteerimiseks."</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"Sisestage parool kõikide varundatud andmete krüpteerimise jaoks. Kui jätate selle tühjaks, siis kasutatakse teie praegust varunduse parooli:"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"Kui soovite kõik varundusandmed krüpteerida, siis sisestage allpool parool:"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"Kui taasteandmed on krüpteeritud, siis sisestage allpool parool."</string>
+    <string name="toast_backup_started" msgid="550354281452756121">"Algab varundamine ..."</string>
+    <string name="toast_backup_ended" msgid="3818080769548726424">"Varundamine jõudis lõpule"</string>
+    <string name="toast_restore_started" msgid="7881679218971277385">"Algab taastamine ..."</string>
+    <string name="toast_restore_ended" msgid="1764041639199696132">"Taastamine jõudis lõpule"</string>
+    <string name="toast_timeout" msgid="5276598587087626877">"Toiming aegus"</string>
+</resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-et/strings.xml b/packages/BackupRestoreConfirmation/res/values-et/strings.xml
index 5a5c454..0f5fde2 100644
--- a/packages/BackupRestoreConfirmation/res/values-et/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-et/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Täielik varundus"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Täielik taastamine"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"Taotleti kõikide andmete varundamist ühendatud lauaarvutist. Kas soovite seda lubada?"\n\n"Kui te ei taotlenud varundust, siis ärge lubage toimingut jätkata."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Taotleti kõikide andmete varundamist ühendatud lauaarvutist. Kas soovite seda lubada?\n\nKui te ei taotlenud varundust, siis ärge lubage toimingut jätkata."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Varunda mu andmed"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Ära varunda"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"Taotletud on kõikide andmete taastamist ühendatud lauaarvutist. Kas soovite seda lubada?"\n\n"Kui te ei taotlenud taastamist, siis ärge lubage toimingut jätkata. See asendab kõik praegu seadmes olevad andmed."</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Taotletud on kõikide andmete taastamist ühendatud lauaarvutist. Kas soovite seda lubada?\n\nKui te ei taotlenud taastamist, siis ärge lubage toimingut jätkata. See asendab kõik praegu seadmes olevad andmed."</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Taasta mu andmed"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Ära taasta"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Sisestage allpool praegune varunduse parool:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-fa/strings.xml b/packages/BackupRestoreConfirmation/res/values-fa/strings.xml
index 4349444..8b20954 100644
--- a/packages/BackupRestoreConfirmation/res/values-fa/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-fa/strings.xml
@@ -18,10 +18,10 @@
     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>
diff --git a/packages/BackupRestoreConfirmation/res/values-fi/strings.xml b/packages/BackupRestoreConfirmation/res/values-fi/strings.xml
index 80da29b..88aaaa5 100644
--- a/packages/BackupRestoreConfirmation/res/values-fi/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-fi/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Täysi varmuuskopiointi"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Täysi palautus"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"Kytketyn tietokoneen kaikista tiedoista on pyydetty täydellistä varmuuskopiota. Haluatko sallia tämän?"\n\n"Jos et ole itse pyytänyt varmuuskopiota, älä salli toimintoa."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Kytketyn tietokoneen kaikista tiedoista on pyydetty täydellistä varmuuskopiota. Haluatko sallia tämän?\n\nJos et ole itse pyytänyt varmuuskopiota, älä salli toimintoa."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Varmuuskopioi omat tiedot"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Älä varmuuskopioi"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"Täydellinen varmuuskopio kytketyn tietokoneen kaikista tiedoista on pyydetty. Haluatko sallia tämän?"\n\n"Jos et ole itse pyytänyt varmuuskopiota, älä salli toimintoa. Tämä korvaa laitteesi kaikki nykyiset tiedot!"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Täydellinen varmuuskopio kytketyn tietokoneen kaikista tiedoista on pyydetty. Haluatko sallia tämän?\n\nJos et ole itse pyytänyt varmuuskopiota, älä salli toimintoa. Tämä korvaa laitteesi kaikki nykyiset tiedot!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Palauta omat tiedot"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Älä palauta"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Kirjoita nykyinen varmuuskopioinnin salasana alla:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-fr-rCA/strings.xml b/packages/BackupRestoreConfirmation/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..8a70fb5
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-fr-rCA/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<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">"Sauvegarde complète"</string>
+    <string name="restore_confirm_title" msgid="5469365809567486602">"Restauration complète"</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Vous avez demandé une sauvegarde complète de l\'ensemble des données vers un ordinateur de bureau connecté. Voulez-vous l\'autoriser?\n\nSi vous n\'avez pas demandé la sauvegarde vous-même, n\'autorisez pas la poursuite de l\'opération."</string>
+    <string name="allow_backup_button_label" msgid="4217228747769644068">"Sauvegarder mes données"</string>
+    <string name="deny_backup_button_label" msgid="6009119115581097708">"Ne pas sauvegarder"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Vous avez demandé une restauration complète de l\'ensemble des données à partir d\'un ordinateur de bureau connecté. Voulez-vous l\'autoriser?\n\nSi vous n\'avez pas demandé vous-même la restauration, n\'autorisez pas sa poursuite. Cette opération remplacera toutes les données actuellement sur l\'appareil!"</string>
+    <string name="allow_restore_button_label" msgid="3081286752277127827">"Restaurer mes données"</string>
+    <string name="deny_restore_button_label" msgid="1724367334453104378">"Ne pas restaurer"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"Veuillez saisir votre mot de passe de sauvegarde actuel ci-dessous :"</string>
+    <string name="device_encryption_restore_text" msgid="1570864916855208992">"Veuillez saisir le mot de passe de chiffrement de l\'appareil ci-dessous."</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"Veuillez saisir le mot de passe de chiffrement de l\'appareil ci-dessous. Il permettra également de chiffrer les archives de sauvegarde."</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"Veuillez saisir un mot de passe à utiliser pour chiffrer les données de sauvegarde complète. Si ce champ n\'est pas renseigné, votre mot de passe de sauvegarde actuel sera utilisé :"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"Si vous souhaitez chiffrer l\'ensemble des données de sauvegarde, veuillez saisir un mot de passe ci-dessous :"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"Si les données de restauration sont chiffrées, veuillez saisir le mot de passe ci-dessous :"</string>
+    <string name="toast_backup_started" msgid="550354281452756121">"Démarrage de la sauvegarde…"</string>
+    <string name="toast_backup_ended" msgid="3818080769548726424">"Sauvegarde terminée."</string>
+    <string name="toast_restore_started" msgid="7881679218971277385">"Démarrage de la restauration…"</string>
+    <string name="toast_restore_ended" msgid="1764041639199696132">"Restauration terminée."</string>
+    <string name="toast_timeout" msgid="5276598587087626877">"L\'opération a expiré."</string>
+</resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-fr/strings.xml b/packages/BackupRestoreConfirmation/res/values-fr/strings.xml
index 9af37b0..897d8d1 100644
--- a/packages/BackupRestoreConfirmation/res/values-fr/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-fr/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Sauvegarde complète"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Restauration complète"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"Vous avez demandé une sauvegarde complète de l\'ensemble des données vers un ordinateur de bureau connecté. Voulez-vous l\'autoriser ?"\n\n"Si vous n\'avez pas demandé la sauvegarde vous-même, n\'autorisez pas la poursuite de l\'opération."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Vous avez demandé une sauvegarde complète de l\'ensemble des données vers un ordinateur de bureau connecté. Voulez-vous l\'autoriser ?\n\nSi vous n\'avez pas demandé la sauvegarde vous-même, n\'autorisez pas la poursuite de l\'opération."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Sauvegarder mes données"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Ne pas sauvegarder"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"Vous avez demandé une restauration complète de l\'ensemble des données à partir d\'un ordinateur de bureau connecté. Voulez-vous l\'autoriser ?"\n\n"Si vous n\'avez pas demandé vous-même la restauration, n\'autorisez pas sa poursuite. Cette opération remplacera toutes les données actuellement sur l\'appareil !"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Vous avez demandé une restauration complète de l\'ensemble des données à partir d\'un ordinateur de bureau connecté. Voulez-vous l\'autoriser ?\n\nSi vous n\'avez pas demandé vous-même la restauration, n\'autorisez pas sa poursuite. Cette opération remplacera toutes les données actuellement sur l\'appareil !"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Restaurer mes données"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Ne pas restaurer"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Veuillez saisir votre mot de passe de sauvegarde actuel ci-dessous :"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-hi/strings.xml b/packages/BackupRestoreConfirmation/res/values-hi/strings.xml
index 1495f8e..0b29804 100644
--- a/packages/BackupRestoreConfirmation/res/values-hi/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-hi/strings.xml
@@ -16,22 +16,22 @@
 
 <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="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="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="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="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_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-hr/strings.xml b/packages/BackupRestoreConfirmation/res/values-hr/strings.xml
index c5c4ce9..3451103 100644
--- a/packages/BackupRestoreConfirmation/res/values-hr/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-hr/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Puna sigurnosna kopija"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Potpuno vraćanje"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"Zatražena je potpuna sigurnosna kopija svih podataka na povezano stolno računalo. Želite li to dozvoliti?"\n\n"Ako niste vi zatražili sigurnosnu kopiju, ne dozvolite nastavak te radnje."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Zatražena je potpuna sigurnosna kopija svih podataka na povezano stolno računalo. Želite li to dozvoliti?\n\nAko niste vi zatražili sigurnosnu kopiju, ne dozvolite nastavak te radnje."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Izradi sigurnosnu kopiju mojih podataka"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Ne radi sigurnosnu kopiju"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"Zatraženo je potpuno vraćanje svih podataka s povezanog stolnog računala. Želite li to dozvoliti?"\n\n"Ako niste sami zatražili vraćanje, ne dozvolite nastavak radnje. To će zamijeniti sve podatke koji se trenutačno nalaze na uređaju!"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Zatraženo je potpuno vraćanje svih podataka s povezanog stolnog računala. Želite li to dozvoliti?\n\nAko niste sami zatražili vraćanje, ne dozvolite nastavak radnje. To će zamijeniti sve podatke koji se trenutačno nalaze na uređaju!"</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">"U nastavku unesite trenutačnu zaporku za sigurnosnu kopiju:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-hu/strings.xml b/packages/BackupRestoreConfirmation/res/values-hu/strings.xml
index c2901c1..73d9a63 100644
--- a/packages/BackupRestoreConfirmation/res/values-hu/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-hu/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Teljes biztonsági mentés"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Teljes helyreállítás"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"Kérés érkezett az összes adat biztonsági mentésére egy csatlakoztatott asztali számítógépre. Engedélyezi, hogy ez megtörténjen?"\n\n"Ha nem Ön kérte a mentést, ne engedélyezze a művelet folytatását."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Kérés érkezett az összes adat biztonsági mentésére egy csatlakoztatott asztali számítógépre. Engedélyezi, hogy ez megtörténjen?\n\nHa nem Ön kérte a mentést, ne engedélyezze a művelet folytatását."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Adatok biztonsági mentése"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Ne mentsen"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"Kérés érkezett egy csatlakoztatott asztali számítógép összes adatának teljes helyreállítására. Engedélyezi, hogy ez megtörténjen?"\n\n"Ha nem Ön kérte a visszaállítást, ne engedélyezze a művelet folytatását. Ez az eszközön lévő összes jelenlegi adatot felülírja!"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Kérés érkezett egy csatlakoztatott asztali számítógép összes adatának teljes helyreállítására. Engedélyezi, hogy ez megtörténjen?\n\nHa nem Ön kérte a visszaállítást, ne engedélyezze a művelet folytatását. Ez az eszközön lévő összes jelenlegi adatot felülírja!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Adatok visszaállítása"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Ne állítsa vissza"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Kérjük, adja meg a jelenlegi biztonsági jelszót alább:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-hy-rAM/strings.xml b/packages/BackupRestoreConfirmation/res/values-hy-rAM/strings.xml
new file mode 100644
index 0000000..4db9080
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-hy-rAM/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<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="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Եթե վերականգնումը ինքներդ չեք հայցել, թուjլ մի տվեք, որ գործողությունը շարունակվի: Դա կփոխարինի ներկայում հեռախոսի մեջ գտնվող ցանկացած տվյալ:"</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="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>
+</resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-in/strings.xml b/packages/BackupRestoreConfirmation/res/values-in/strings.xml
index 3fb6d6b..f2d6ad5 100644
--- a/packages/BackupRestoreConfirmation/res/values-in/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-in/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Pencadangan sepenuhnya"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Pemulihan sepenuhnya"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"Cadangan lengkap semua data ke komputer yang tersambung telah diminta. Apakah Anda ingin mengizinkan hal ini dilakukan?"\n\n"Jika Anda tidak meminta pencadangan ini, jangan izinkan operasi dilanjutkan."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Cadangan lengkap semua data ke komputer yang tersambung telah diminta. Apakah Anda ingin mengizinkan hal ini dilakukan?\n\nJika Anda tidak meminta pencadangan ini, jangan izinkan operasi dilanjutkan."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Cadangkan data saya"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Jangan mencadangkan"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"Pemulihan lengkap semua data dari komputer desktop yang tersambung telah diminta. Apakah Anda ingin mengizinkan hal ini?"\n\n"Jika Anda tidak meminta pemulihan ini, jangan izinkan operasi dilanjutkan. Operasi ini akan mengganti data apa pun yang saat ini ada dalam perangkat!"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Pemulihan lengkap semua data dari komputer desktop yang tersambung telah diminta. Apakah Anda ingin mengizinkan hal ini?\n\nJika Anda tidak meminta pemulihan ini, jangan izinkan operasi dilanjutkan. Operasi ini akan mengganti data apa pun yang saat ini ada dalam perangkat!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Memulihkan data saya"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Jangan pulihkan"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Masukkan sandi cadangan Anda saat ini di bawah:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-it/strings.xml b/packages/BackupRestoreConfirmation/res/values-it/strings.xml
index 9442ae3..a9e8ae4 100644
--- a/packages/BackupRestoreConfirmation/res/values-it/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-it/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Backup completo"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Ripristino totale"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"È stato richiesto un backup completo di tutti i dati su un computer desktop connesso. Consentire l\'operazione?"\n\n"Se non hai richiesto il backup, non consentire all\'operazione di procedere."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"È stato richiesto un backup completo di tutti i dati su un computer desktop connesso. Consentire l\'operazione?\n\nSe non hai richiesto il backup, non consentire all\'operazione di procedere."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Effettua backup dei miei dati"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Non eseguire il backup"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"È stato richiesto un ripristino completo di tutti i dati da un computer desktop connesso. Consentire questa operazione?"\n\n"Se non hai richiesto il ripristino, non consentire all\'operazione di procedere. Questa operazione sostituirà tutti i dati attualmente presenti sul dispositivo."</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"È stato richiesto un ripristino completo di tutti i dati da un computer desktop connesso. Consentire questa operazione?\n\nSe non hai richiesto il ripristino, non consentire all\'operazione di procedere. Questa operazione sostituirà tutti i dati attualmente presenti sul dispositivo."</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Ripristina i miei dati"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Non ripristinare"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Inserisci la tua password di backup corrente di seguito:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-iw/strings.xml b/packages/BackupRestoreConfirmation/res/values-iw/strings.xml
index a41944a..395c39e 100644
--- a/packages/BackupRestoreConfirmation/res/values-iw/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-iw/strings.xml
@@ -18,10 +18,10 @@
     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>
diff --git a/packages/BackupRestoreConfirmation/res/values-ja/strings.xml b/packages/BackupRestoreConfirmation/res/values-ja/strings.xml
index 98916c5..6859b35 100644
--- a/packages/BackupRestoreConfirmation/res/values-ja/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-ja/strings.xml
@@ -18,10 +18,10 @@
     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>
diff --git a/packages/BackupRestoreConfirmation/res/values-ka-rGE/strings.xml b/packages/BackupRestoreConfirmation/res/values-ka-rGE/strings.xml
new file mode 100644
index 0000000..9c6f67e
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-ka-rGE/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<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="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="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="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>
+</resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-km-rKH/strings.xml b/packages/BackupRestoreConfirmation/res/values-km-rKH/strings.xml
new file mode 100644
index 0000000..956fdd7
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-km-rKH/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<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="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="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="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>
+</resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-ko/strings.xml b/packages/BackupRestoreConfirmation/res/values-ko/strings.xml
index 4137058..23c8662 100644
--- a/packages/BackupRestoreConfirmation/res/values-ko/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-ko/strings.xml
@@ -18,10 +18,10 @@
     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>
diff --git a/packages/BackupRestoreConfirmation/res/values-lo-rLA/strings.xml b/packages/BackupRestoreConfirmation/res/values-lo-rLA/strings.xml
new file mode 100644
index 0000000..fb28502
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-lo-rLA/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<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="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="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="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>
+</resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-lt/strings.xml b/packages/BackupRestoreConfirmation/res/values-lt/strings.xml
index 4e9efc5..44e67de 100644
--- a/packages/BackupRestoreConfirmation/res/values-lt/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-lt/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Visos atsarginės kopijos kūrimas"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Visas atkūrimas"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"Prijungtame staliniame kompiuteryje pageidauta sukurti visų duomenų atsarginę kopiją. Ar norite, kad tai būtų atlikta?"\n\n"Jei patys atsarginės kopijos kurti neprašėte, neleiskite pradėti operacijos."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Prijungtame staliniame kompiuteryje pageidauta sukurti visų duomenų atsarginę kopiją. Ar norite, kad tai būtų atlikta?\n\nJei patys atsarginės kopijos kurti neprašėte, neleiskite pradėti operacijos."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Kurti atsarginę duomenų kopiją"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Nekurti atsarginės kopijos"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"Pateikta visų staliniame kompiuteryje saugomų duomenų visiško atkūrimo užklausa. Ar norite, kad tai būtų atlikta?"\n\n"Jei patys atkurti neprašėte, neleiskite pradėti operacijos. Kitaip bus pakeisti visi dabar įrenginyje saugomi duomenys!"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Pateikta visų staliniame kompiuteryje saugomų duomenų visiško atkūrimo užklausa. Ar norite, kad tai būtų atlikta?\n\nJei patys atkurti neprašėte, neleiskite pradėti operacijos. Kitaip bus pakeisti visi dabar įrenginyje saugomi duomenys!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Atkurti mano duomenis"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Neatkurti"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Toliau įveskite dabartinį atsarginės kopijos slaptažodį:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-lv/strings.xml b/packages/BackupRestoreConfirmation/res/values-lv/strings.xml
index b8ce24b..c58d6fd 100644
--- a/packages/BackupRestoreConfirmation/res/values-lv/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-lv/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Pilna dublēšana"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Pilna atjaunošana"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"Ir pieprasīta visu datu pilnīga dublēšana savienotā galda datorā. Vai vēlaties to atļaut?"\n\n"Ja neesat pieprasījis dublēšanu, neatļaujiet turpināt šo darbību."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Ir pieprasīta visu datu pilnīga dublēšana savienotā galda datorā. Vai vēlaties to atļaut?\n\nJa neesat pieprasījis dublēšanu, neatļaujiet turpināt šo darbību."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Dublēt manus datus"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Neveidot dublējumu"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"Ir pieprasīta visu savienotā galda datora datu pilnīga atjaunošana. Vai vēlaties to atļaut?"\n\n"Ja neesat pieprasījis atjaunošanu, neatļaujiet turpināt šo darbību. Tās rezultātā tiks aizstāti visi pašreiz ierīcē esošie dati!"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Ir pieprasīta visu savienotā galda datora datu pilnīga atjaunošana. Vai vēlaties to atļaut?\n\nJa neesat pieprasījis atjaunošanu, neatļaujiet turpināt šo darbību. Tās rezultātā tiks aizstāti visi pašreiz ierīcē esošie dati!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Atjaunot manus datus"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Neatjaunot"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Lūdzu, tālāk ievadiet pašreizējo dublējuma paroli:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-mn-rMN/strings.xml b/packages/BackupRestoreConfirmation/res/values-mn-rMN/strings.xml
new file mode 100644
index 0000000..b2738c0
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-mn-rMN/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<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="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="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="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>
+</resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-ms-rMY/strings.xml b/packages/BackupRestoreConfirmation/res/values-ms-rMY/strings.xml
new file mode 100644
index 0000000..65a9ede
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-ms-rMY/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<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">"Sandaran penuh"</string>
+    <string name="restore_confirm_title" msgid="5469365809567486602">"Pemulihan penuh"</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Sandaran lengkap bagi semua data ke komputer meja yang bersambung telah diminta. Adakah anda mahu membenarkan ini berlaku?\n\nJika anda tidak meminta sandaran ini sendiri, jangan benarkan operasi diteruskan."</string>
+    <string name="allow_backup_button_label" msgid="4217228747769644068">"Sandarkan data saya"</string>
+    <string name="deny_backup_button_label" msgid="6009119115581097708">"Jangan buat sandaran"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Pemulihan penuh semua data dari komputer meja yang bersambung telah diminta. Adakah anda mahu membenarkan ini berlaku?\n\nJika anda tidak meminta pemulihan ini sendiri, jangan benarkan operasi ini diteruskan. Ini akan menggantikan sebarang data semasa pada peranti!"</string>
+    <string name="allow_restore_button_label" msgid="3081286752277127827">"Pulihkan data saya"</string>
+    <string name="deny_restore_button_label" msgid="1724367334453104378">"Jangan kembalikan"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"Sila masukkan kata laluan sandaran semasa anda di bawah:"</string>
+    <string name="device_encryption_restore_text" msgid="1570864916855208992">"Sila masukkan kata laluan penyulitan peranti anda di bawah."</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"Sila masukkan kata laluan penyulitan peranti anda di bawah. Ini juga akan digunakan untuk menyulitkan arkib sandaran."</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"Sila masukkan kata laluan yang hendak digunakan untuk menyulitkan data sandaran lengkap. Jika dibiarkan kosong, kata laluan sandaran semasa anda akan digunakan:"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"Jika anda ingin menyulitkan data sandaran lengkap, masukkan kata laluan di bawah:"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"Jika pemulihan data disulitkan, sila masukkan kata laluan di bawah:"</string>
+    <string name="toast_backup_started" msgid="550354281452756121">"Sandaran bermula..."</string>
+    <string name="toast_backup_ended" msgid="3818080769548726424">"Sandaran selesai"</string>
+    <string name="toast_restore_started" msgid="7881679218971277385">"Pemulihan bermula..."</string>
+    <string name="toast_restore_ended" msgid="1764041639199696132">"Pemulihan berakhir"</string>
+    <string name="toast_timeout" msgid="5276598587087626877">"Operasi tamat masa"</string>
+</resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-ms/strings.xml b/packages/BackupRestoreConfirmation/res/values-ms/strings.xml
index bcfa615..65a9ede 100644
--- a/packages/BackupRestoreConfirmation/res/values-ms/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-ms/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Sandaran penuh"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Pemulihan penuh"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"Sandaran lengkap bagi semua data ke komputer meja yang bersambung telah diminta. Adakah anda mahu membenarkan ini berlaku?"\n\n"Jika anda tidak meminta sandaran ini sendiri, jangan benarkan operasi diteruskan."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Sandaran lengkap bagi semua data ke komputer meja yang bersambung telah diminta. Adakah anda mahu membenarkan ini berlaku?\n\nJika anda tidak meminta sandaran ini sendiri, jangan benarkan operasi diteruskan."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Sandarkan data saya"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Jangan buat sandaran"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"Pemulihan penuh semua data dari komputer meja yang bersambung telah diminta. Adakah anda mahu membenarkan ini berlaku?"\n\n"Jika anda tidak meminta pemulihan ini sendiri, jangan benarkan operasi ini diteruskan. Ini akan menggantikan sebarang data semasa pada peranti!"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Pemulihan penuh semua data dari komputer meja yang bersambung telah diminta. Adakah anda mahu membenarkan ini berlaku?\n\nJika anda tidak meminta pemulihan ini sendiri, jangan benarkan operasi ini diteruskan. Ini akan menggantikan sebarang data semasa pada peranti!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Pulihkan data saya"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Jangan kembalikan"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Sila masukkan kata laluan sandaran semasa anda di bawah:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-nb/strings.xml b/packages/BackupRestoreConfirmation/res/values-nb/strings.xml
index a93c081..d43ec2f 100644
--- a/packages/BackupRestoreConfirmation/res/values-nb/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-nb/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Fullstendig sikkerhetskopi"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Fullstendig gjenoppretting"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"En full sikkerhetskopi av alle dataene til en tilkoblet datamaskin er forespurt. Vil du tillate dette?"\n\n"Hvis du ikke har bedt om sikkerhetskopieringen selv, må du ikke tillate at operasjonen fortsetter."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"En full sikkerhetskopi av alle dataene til en tilkoblet datamaskin er forespurt. Vil du tillate dette?\n\nHvis du ikke har bedt om sikkerhetskopieringen selv, må du ikke tillate at operasjonen fortsetter."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Sikkerhetskopier dataene mine"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Ikke sikkerhetskopiér"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"En full gjenoppretting av alle data fra en tilkoblet datamaskin er forespurt. Vil du tillate dette?"\n\n"Hvis du ikke har bedt om gjenopprettingen selv, må du ikke la operasjonen fortsette. Handlingen vil erstatte alle dataene som ligger på enheten!"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"En full gjenoppretting av alle data fra en tilkoblet datamaskin er forespurt. Vil du tillate dette?\n\nHvis du ikke har bedt om gjenopprettingen selv, må du ikke la operasjonen fortsette. Handlingen vil erstatte alle dataene som ligger på enheten!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Gjenopprett dataene mine"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Ikke gjenopprett"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Skriv inn ditt nåværende passord for sikkerhetskopiering nedenfor:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-nl/strings.xml b/packages/BackupRestoreConfirmation/res/values-nl/strings.xml
index d525429..1bf73e9 100644
--- a/packages/BackupRestoreConfirmation/res/values-nl/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-nl/strings.xml
@@ -18,17 +18,17 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Volledige back-up"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Volledig herstel"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"Er is een volledige back-up van alle gegevens naar een verbonden desktopcomputer aangevraagd. Wilt u dit toestaan?"\n\n"Als u de back-up zelf niet heeft aangevraagd, moet u niet toestaan dat de bewerking wordt uitgevoerd."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Er is een volledige back-up van alle gegevens naar een verbonden desktopcomputer aangevraagd. Wilt u dit toestaan?\n\nAls u de back-up zelf niet heeft aangevraagd, moet u niet toestaan dat de bewerking wordt uitgevoerd."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Back-up maken van mijn gegevens"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Geen back-up maken"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"Er is volledig herstel van alle gegevens van een verbonden desktopcomputer aangevraagd. Wilt u dit toestaan?"\n\n"Als u het herstel zelf niet heeft aangevraagd, moet u niet toestaan dat de bewerking wordt uitgevoerd. Bij herstel worden alle gegevens op het apparaat vervangen."</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Er is volledig herstel van alle gegevens van een verbonden desktopcomputer aangevraagd. Wilt u dit toestaan?\n\nAls u het herstel zelf niet heeft aangevraagd, moet u niet toestaan dat de bewerking wordt uitgevoerd. Bij herstel worden alle gegevens op het apparaat vervangen."</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Mijn gegevens herstellen"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Niet herstellen"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Geef hieronder uw huidige back-upwachtwoord op:"</string>
     <string name="device_encryption_restore_text" msgid="1570864916855208992">"Geef hieronder uw wachtwoord voor apparaatcodering op."</string>
-    <string name="device_encryption_backup_text" msgid="5866590762672844664">"Geef hieronder uw wachtwoord voor apparaatcodering op. Dit wordt ook gebruikt om het back-uparchief te coderen."</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"Geef hieronder uw wachtwoord voor apparaatversleuteling op. Dit wordt ook gebruikt om het back-uparchief te versleutelen."</string>
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Geef een wachtwoord op dat u wilt gebruiken voor het coderen van de gegevens van de volledige back-up. Als u dit leeg laat, wordt uw huidige back-upwachtwoord gebruikt:"</string>
-    <string name="backup_enc_password_optional" msgid="1350137345907579306">"Als u de gegevens van de volledige back-up wilt coderen, geeft u daarvoor hieronder een wachtwoord op:"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"Als u de gegevens van de volledige back-up wilt versleutelen, geeft u daarvoor hieronder een wachtwoord op:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Als deze herstelgegevens zijn gecodeerd, geeft u hieronder het wachtwoord op:"</string>
     <string name="toast_backup_started" msgid="550354281452756121">"Back-up starten..."</string>
     <string name="toast_backup_ended" msgid="3818080769548726424">"Back-up voltooid"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-pl/strings.xml b/packages/BackupRestoreConfirmation/res/values-pl/strings.xml
index 1a70bb0..122b5df 100644
--- a/packages/BackupRestoreConfirmation/res/values-pl/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-pl/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Pełna kopia zapasowa"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Pełne przywracanie"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"Zażądano wykonania pełnej kopii zapasowej wszystkich danych na podłączonym komputerze stacjonarnym. Czy chcesz na to zezwolić?"\n\n"Jeśli żądanie utworzenia kopii zapasowej nie pochodzi od Ciebie, nie zezwalaj na kontynuowanie tej operacji."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Zażądano wykonania pełnej kopii zapasowej wszystkich danych na podłączonym komputerze stacjonarnym. Czy chcesz na to zezwolić?\n\nJeśli żądanie utworzenia kopii zapasowej nie pochodzi od Ciebie, nie zezwalaj na kontynuowanie tej operacji."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Utwórz kopię zapasową danych"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Nie twórz kopii zapasowej"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"Zażądano pełnego przywrócenia wszystkich danych z połączonego komputera stacjonarnego. Czy chcesz na to zezwolić?"\n\n"Jeśli żądanie przywrócenia nie pochodzi od Ciebie, nie zezwalaj na kontynuowanie tej operacji. Spowoduje to zastąpienie wszelkich danych znajdujących się aktualnie w urządzeniu."</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Zażądano pełnego przywrócenia wszystkich danych z połączonego komputera stacjonarnego. Czy chcesz na to zezwolić?\n\nJeśli żądanie przywrócenia nie pochodzi od Ciebie, nie zezwalaj na kontynuowanie tej operacji. Spowoduje to zastąpienie wszelkich danych znajdujących się aktualnie w urządzeniu."</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Przywróć moje dane"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Nie przywracaj"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Wpisz poniżej aktualne hasło kopii zapasowej:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-pt-rPT/strings.xml b/packages/BackupRestoreConfirmation/res/values-pt-rPT/strings.xml
index a486f54..477d423 100644
--- a/packages/BackupRestoreConfirmation/res/values-pt-rPT/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-pt-rPT/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Cópia de segurança completa"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Restauro completo"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"Foi solicitada uma cópia de segurança completa de todos os dados para um computador. Pretende permitir esta operação?"\n\n"Caso não tenha solicitado a cópia de segurança, não permita que a operação prossiga."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Foi solicitada uma cópia de segurança completa de todos os dados para um computador. Pretende permitir esta operação?\n\nCaso não tenha solicitado a cópia de segurança, não permita que a operação prossiga."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Fazer cópia de seg. dos dados"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Não efetuar cópia de seg."</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"Foi solicitado um restauro completo de todos os dados a partir de um computador. Pretende permitir esta operação?"\n\n"Caso não tenha solicitado o restauro, não permita que a operação prossiga. Isto substituirá os dados existentes no equipamento!"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Foi solicitado um restauro completo de todos os dados a partir de um computador. Pretende permitir esta operação?\n\nCaso não tenha solicitado o restauro, não permita que a operação prossiga. Isto substituirá os dados existentes no equipamento!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Restaurar os meus dados"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Não restaurar"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Introduza a palavra-passe de cópia de segurança atual abaixo:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-pt/strings.xml b/packages/BackupRestoreConfirmation/res/values-pt/strings.xml
index 99fd2e1..a56b31ca 100644
--- a/packages/BackupRestoreConfirmation/res/values-pt/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-pt/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Backup completo"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Restauração completa"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"Foi solicitado um backup completo de todos os dados para um computador conectado. Deseja permitir que isso aconteça?"\n\n"Caso você não tenha solicitado o backup, não permita que a operação prossiga."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Foi solicitado um backup completo de todos os dados para um computador conectado. Deseja permitir que isso aconteça?\n\nCaso você não tenha solicitado o backup, não permita que a operação prossiga."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Fazer backup de meus dados"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Não fazer backup"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"Foi solicitada uma restauração completa de todos os dados de um computador conectado. Deseja permitir que isso ocorra?"\n\n"Caso você não tenha solicitado a restauração, não permita que a operação prossiga. Isso substituirá todos os dados existentes no dispositivo!"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Foi solicitada uma restauração completa de todos os dados de um computador conectado. Deseja permitir que isso ocorra?\n\nCaso você não tenha solicitado a restauração, não permita que a operação prossiga. Isso substituirá todos os dados existentes no dispositivo!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Restaurar meus dados"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Não restaurar"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Digite sua senha de backup atual abaixo:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-ro/strings.xml b/packages/BackupRestoreConfirmation/res/values-ro/strings.xml
index 4c49bf8..839edbb 100644
--- a/packages/BackupRestoreConfirmation/res/values-ro/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-ro/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Copiere de rezervă completă"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Restabilire completă"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"S-a solicitat crearea unei copii de rezervă complete a tuturor datelor pe un computer desktop conectat. Doriţi să permiteţi acest lucru?"\n\n"Dacă nu aţi solicitat dvs. copierea de rezervă, nu permiteţi ca operaţiunea să continue."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"S-a solicitat crearea unei copii de rezervă complete a tuturor datelor pe un computer desktop conectat. Doriţi să permiteţi acest lucru?\n\nDacă nu aţi solicitat dvs. copierea de rezervă, nu permiteţi ca operaţiunea să continue."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Creaţi copii de rezervă pentru datele dvs."</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Nu creaţi copii de rezervă"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"S-a solicitat o restabilire completă a tuturor datelor de pe un computer desktop conectat. Doriţi să permiteţi acest lucru?"\n\n"Dacă nu dvs. aţi solicitat această restabilire, nu permiteţi continuarea operaţiunii. Acest proces va înlocui toate datele existente în prezent pe dispozitiv!"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"S-a solicitat o restabilire completă a tuturor datelor de pe un computer desktop conectat. Doriţi să permiteţi acest lucru?\n\nDacă nu dvs. aţi solicitat această restabilire, nu permiteţi continuarea operaţiunii. Acest proces va înlocui toate datele existente în prezent pe dispozitiv!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Restabiliţi datele dvs."</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Nu restabiliţi"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Introduceţi mai jos parola actuală pentru copia de rezervă:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-ru/strings.xml b/packages/BackupRestoreConfirmation/res/values-ru/strings.xml
index 0dbba05..f516493 100644
--- a/packages/BackupRestoreConfirmation/res/values-ru/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-ru/strings.xml
@@ -18,10 +18,10 @@
     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>
diff --git a/packages/BackupRestoreConfirmation/res/values-sk/strings.xml b/packages/BackupRestoreConfirmation/res/values-sk/strings.xml
index b432165..21e21b5 100644
--- a/packages/BackupRestoreConfirmation/res/values-sk/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-sk/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Úplná záloha"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Úplné obnovenie"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"Bola vyžiadaná úplná záloha všetkých dát do pripojeného počítača. Chcete túto akciu povoliť?"\n\n"Ak ste zálohu nevyžiadali vy, túto operáciu nepovoľujte."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Bola vyžiadaná úplná záloha všetkých dát do pripojeného počítača. Chcete túto akciu povoliť?\n\nAk ste zálohu nevyžiadali vy, túto operáciu nepovoľujte."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Zálohovať údaje"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Nezálohovať"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"Z pripojeného počítača bolo vyžiadané úplné obnovenie všetkých údajov. Chcete túto akciu povoliť?"\n\n"Ak ste toto obnovenie nevyžiadali vy, túto operáciu nepovoľujte. Táto akcia nahradí všetky údaje v zariadení."</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Z pripojeného počítača bolo vyžiadané úplné obnovenie všetkých údajov. Chcete túto akciu povoliť?\n\nAk ste toto obnovenie nevyžiadali vy, túto operáciu nepovoľujte. Táto akcia nahradí všetky údaje v zariadení."</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Obnoviť údaje"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Neobnoviť"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Zadajte svoje aktuálne heslo pre zálohu nižšie:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-sl/strings.xml b/packages/BackupRestoreConfirmation/res/values-sl/strings.xml
index 5df0449..17d4d80 100644
--- a/packages/BackupRestoreConfirmation/res/values-sl/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-sl/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Polna varnostna kopija"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Popolna obnova"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"Zahtevano je popolno varnostno kopiranje vseh podatkov v povezanem računalniku. Ali želite to dovoliti?"\n\n"Če varnostnega kopiranja niste zahtevali, ne dovolite nadaljevanja postopka."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Zahtevano je popolno varnostno kopiranje vseh podatkov v povezanem računalniku. Ali želite to dovoliti?\n\nČe varnostnega kopiranja niste zahtevali, ne dovolite nadaljevanja postopka."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Varnostno kopiraj moje podatke"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Brez varnostnega kopiranja"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"Zahtevana je popolna obnovitev vseh podatkov iz povezanega računalnika. Ali želite to dovoliti?"\n\n"Če niste zahtevali obnovitve, ne dovolite nadaljevanja postopka. Sicer bodo zamenjani vsi podatki, trenutno shranjeni v napravi."</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Zahtevana je popolna obnovitev vseh podatkov iz povezanega računalnika. Ali želite to dovoliti?\n\nČe niste zahtevali obnovitve, ne dovolite nadaljevanja postopka. Sicer bodo zamenjani vsi podatki, trenutno shranjeni v napravi."</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Obnovi moje podatke"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Ne obnovi"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Spodaj vnesite trenutno geslo za varnostno kopiranje:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-sr/strings.xml b/packages/BackupRestoreConfirmation/res/values-sr/strings.xml
index 0a5859e..82cb85f 100644
--- a/packages/BackupRestoreConfirmation/res/values-sr/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-sr/strings.xml
@@ -18,10 +18,10 @@
     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>
diff --git a/packages/BackupRestoreConfirmation/res/values-sv/strings.xml b/packages/BackupRestoreConfirmation/res/values-sv/strings.xml
index 167fce3..a2ef430 100644
--- a/packages/BackupRestoreConfirmation/res/values-sv/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-sv/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Fullständig säkerhetskopiering"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Fullständig återställning"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"En fullständig säkerhetskopia av alla data till en ansluten dator har begärts. Vill du tillåta detta?"\n\n"Om du inte själv begärde säkerhetskopian ska du inte tillåta detta."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"En fullständig säkerhetskopia av alla data till en ansluten dator har begärts. Vill du tillåta detta?\n\nOm du inte själv begärde säkerhetskopian ska du inte tillåta detta."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Säkerhetskopiera mina data"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Säkerhetskopiera inte"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"En fullständig återställning av alla data från en ansluten dator har begärts. Vill du tillåta detta? "\n" "\n" Om du inte själv har begärt återställningen ska du inte tillåta den. Alla data som finns på enheten kommer då att ersättas!"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"En fullständig återställning av alla data från en ansluten dator har begärts. Vill du tillåta detta? \n \n Om du inte själv har begärt återställningen ska du inte tillåta den. Alla data som finns på enheten kommer då att ersättas!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Återställ mina data"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Återställ inte"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Ange det aktuella lösenordet för säkerhetskopian nedan:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-sw/strings.xml b/packages/BackupRestoreConfirmation/res/values-sw/strings.xml
index 493c168..619a6db 100644
--- a/packages/BackupRestoreConfirmation/res/values-sw/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-sw/strings.xml
@@ -17,11 +17,11 @@
 <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">"Kuhifadhi kikamilifu"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Kurejeza kamili"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"Chelezo kamili la data iliyounganishwa kwenye eneo kazi la kompyuta limeombwa. Unataka kuruhusu hii kutendeka?"\n\n" Ikiwa hukuomba chelezo mwenyewe, usikubali uendeshaji kuendelea."</string>
-    <string name="allow_backup_button_label" msgid="4217228747769644068">"Cheleza data yangu"</string>
+    <string name="restore_confirm_title" msgid="5469365809567486602">"Kurejesha kila kitu"</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Chelezo kamili la data iliyounganishwa kwenye eneo kazi la kompyuta limeombwa. Unataka kuruhusu hii kutendeka?\n\n Ikiwa hukuomba chelezo mwenyewe, usikubali uendeshaji kuendelea."</string>
+    <string name="allow_backup_button_label" msgid="4217228747769644068">"Hifadhi nakala ya data yangu"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Usicheleze"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"Kurejesha kamili kwa data nzima kutoka kwa eneo kazi la kompyuta lililounganishwa limeombwa. Unataka kuruhusu hii kutendeka?"\n\n" Ikiwa hukuweza kurejesha upya mwenyewe, usiruhusu uendeshaji huu kuendelea. Hii itaweka upya data yoyote iliyo kwenye kifaa hiki sasa!"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Kurejesha kamili kwa data nzima kutoka kwa eneo kazi la kompyuta lililounganishwa limeombwa. Unataka kuruhusu hii kutendeka?\n\n Ikiwa hukuweza kurejesha upya mwenyewe, usiruhusu uendeshaji huu kuendelea. Hii itaweka upya data yoyote iliyo kwenye kifaa hiki sasa!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Rejesha upya data yangu"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Usirejeshe upya"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Tafadhali ingiza nenosiri lako la chelezo hapo chini:"</string>
@@ -32,7 +32,7 @@
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Ikiwa data iliyorejeshwa upya, tafadhali ingiza nenosiri lililo hapo chini:"</string>
     <string name="toast_backup_started" msgid="550354281452756121">"Inaanza kuhifadhi..."</string>
     <string name="toast_backup_ended" msgid="3818080769548726424">"Imemaliza kuhifadhi"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Inaanza kurejeza..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"Kurejeza kumekamilika"</string>
+    <string name="toast_restore_started" msgid="7881679218971277385">"Inaanza kurejesha..."</string>
+    <string name="toast_restore_ended" msgid="1764041639199696132">"Kurejesha kumekamilika"</string>
     <string name="toast_timeout" msgid="5276598587087626877">"Muda wa uendeshaji umeisha"</string>
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-th/strings.xml b/packages/BackupRestoreConfirmation/res/values-th/strings.xml
index 2d08620..c0543a0 100644
--- a/packages/BackupRestoreConfirmation/res/values-th/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-th/strings.xml
@@ -18,10 +18,10 @@
     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>
diff --git a/packages/BackupRestoreConfirmation/res/values-tl/strings.xml b/packages/BackupRestoreConfirmation/res/values-tl/strings.xml
index 97662b5..5c564ba 100644
--- a/packages/BackupRestoreConfirmation/res/values-tl/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-tl/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Ganap na pag-backup"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Ganap na pagpapanumbalik"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"Hiniling ang isang buong pag-backup ng lahat ng data sa isang nakakonektang desktop computer. Gusto mo ba itong payagang maganap? "\n\n"Kung hindi ikaw mismo ang humiling ng pag-backup, huwag payagang magpatuloy ang pagpapatakbo."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Hiniling ang isang buong pag-backup ng lahat ng data sa isang nakakonektang desktop computer. Gusto mo ba itong payagang maganap? \n\nKung hindi ikaw mismo ang humiling ng pag-backup, huwag payagang magpatuloy ang pagpapatakbo."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"I-back up ang aking data"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Huwag i-back up"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"Hiniling ang isang buong pagpapanumbalik ng lahat ng data mula sa isang nakakonektang desktop computer. Gusto mo ba itong payagang maganap?"\n\n"Kung hindi ikaw mismo ang humiling ng pagpapanumbalik, huwag payagang magpatuloy ang pagpapatakbo. Papalitan nito ang anumang data na kasalukuyang nasa device!"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Hiniling ang isang buong pagpapanumbalik ng lahat ng data mula sa isang nakakonektang desktop computer. Gusto mo ba itong payagang maganap?\n\nKung hindi ikaw mismo ang humiling ng pagpapanumbalik, huwag payagang magpatuloy ang pagpapatakbo. Papalitan nito ang anumang data na kasalukuyang nasa device!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Ipanumbalik ang aking data"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Huwag ipanumbalik"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Pakilagay ang iyong kasalukuyang backup na password sa ibaba:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-tr/strings.xml b/packages/BackupRestoreConfirmation/res/values-tr/strings.xml
index 62b9f4b..591be7c 100644
--- a/packages/BackupRestoreConfirmation/res/values-tr/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-tr/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Tam yedekleme"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Tam geri yükleme"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"Tüm verilerin bağlı bir masaüstü bilgisayara tam olarak yedeklenmesi için istekte bulunuldu?"\n\n"Yedekleme isteğinde siz bulunmadıysanız, işlemin devam etmesine izin vermeyin."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Tüm verilerin bağlı bir masaüstü bilgisayara tam olarak yedeklenmesi için istekte bulunuldu?\n\nYedekleme isteğinde siz bulunmadıysanız, işlemin devam etmesine izin vermeyin."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Verilerimi yedekle"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Yedekleme"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"Tüm verilerin, bağlı bir masaüstü bilgisayardan tam olarak geri yüklenmesi için istekte bulunuldu. Bu işleme izin vermek istiyor musunuz?"\n\n"Geri yükleme isteğinde siz bulunmadıysanız, işlemin ilerlemesine izin vermeyin. Bu işlem, cihazınızdaki tüm verileri silip üzerine yazar!"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Tüm verilerin, bağlı bir masaüstü bilgisayardan tam olarak geri yüklenmesi için istekte bulunuldu. Bu işleme izin vermek istiyor musunuz?\n\nGeri yükleme isteğinde siz bulunmadıysanız, işlemin ilerlemesine izin vermeyin. Bu işlem, cihazınızdaki tüm verileri silip üzerine yazar!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Verilerimi geri yükle"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Geri yükleme"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Lütfen mevcut yedekleme şifrenizi aşağıya girin:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-uk/strings.xml b/packages/BackupRestoreConfirmation/res/values-uk/strings.xml
index f3dfa1c..b4ddef1 100644
--- a/packages/BackupRestoreConfirmation/res/values-uk/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-uk/strings.xml
@@ -18,10 +18,10 @@
     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>
diff --git a/packages/BackupRestoreConfirmation/res/values-vi/strings.xml b/packages/BackupRestoreConfirmation/res/values-vi/strings.xml
index ac34a993..69e8f9c 100644
--- a/packages/BackupRestoreConfirmation/res/values-vi/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-vi/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Sao lưu hoàn toàn"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Khôi phục hoàn toàn"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"Đã yêu cầu sao lưu đầy đủ toàn bộ dữ liệu tới máy tính được kết nối. Bạn có muốn cho phép điều này xảy ra không?"\n\n"Nếu không phải bản thân bạn yêu cầu sao lưu, đừng cho phép thao tác này tiếp tục."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Đã yêu cầu sao lưu đầy đủ toàn bộ dữ liệu tới máy tính được kết nối. Bạn có muốn cho phép điều này xảy ra không?\n\nNếu không phải bản thân bạn yêu cầu sao lưu, đừng cho phép thao tác này tiếp tục."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Sao lưu dữ liệu của tôi"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Không sao lưu"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"Đã yêu cầu khôi phục đầy đủ toàn bộ dữ liệu từ máy tính được kết nối. Bạn có muốn cho phép điều này xảy ra không?"\n\n"Nếu không phải bản thân bạn yêu cầu khôi phục, đừng cho phép thao tác này tiếp tục. Thao tác này sẽ thay thế mọi dữ liệu hiện tại trên thiết bị!"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Đã yêu cầu khôi phục đầy đủ toàn bộ dữ liệu từ máy tính được kết nối. Bạn có muốn cho phép điều này xảy ra không?\n\nNếu không phải bản thân bạn yêu cầu khôi phục, đừng cho phép thao tác này tiếp tục. Thao tác này sẽ thay thế mọi dữ liệu hiện tại trên thiết bị!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Khôi phục dữ liệu của tôi"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Không khôi phục"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Vui lòng nhập mật khẩu sao lưu hiện tại của bạn bên dưới:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-zh-rCN/strings.xml b/packages/BackupRestoreConfirmation/res/values-zh-rCN/strings.xml
index 5f3ca05..b2764fb 100644
--- a/packages/BackupRestoreConfirmation/res/values-zh-rCN/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-zh-rCN/strings.xml
@@ -18,10 +18,10 @@
     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>
diff --git a/packages/BackupRestoreConfirmation/res/values-zh-rHK/strings.xml b/packages/BackupRestoreConfirmation/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..d3bcd6e
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-zh-rHK/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<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="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="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="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>
+</resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-zh-rTW/strings.xml b/packages/BackupRestoreConfirmation/res/values-zh-rTW/strings.xml
index 5afb226..4da6114 100644
--- a/packages/BackupRestoreConfirmation/res/values-zh-rTW/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-zh-rTW/strings.xml
@@ -18,10 +18,10 @@
     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>
diff --git a/packages/BackupRestoreConfirmation/res/values-zu/strings.xml b/packages/BackupRestoreConfirmation/res/values-zu/strings.xml
index 241bd37..955b26f 100644
--- a/packages/BackupRestoreConfirmation/res/values-zu/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-zu/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Ukulondolozwa okuphelele"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Ukubuyisela okuphelele"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"Kucelwe ukwesekelwa ngokulondoloza okuphelele kwayo yonke imininingo ekwi-desktop yekhompuyutha exhunyiwe. Angifuni ukuvumel alokhu ukuthi kwenzeke?"\n\n"Uma kuwukuthi awuzange ucele ukuthi kwesekelwe ngokulondoloza wena uqobo lwakho, ungavumeli ukuthi lolu hlelo luqhubekele phambili."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Kucelwe ukwesekelwa ngokulondoloza okuphelele kwayo yonke imininingo ekwi-desktop yekhompuyutha exhunyiwe. Angifuni ukuvumel alokhu ukuthi kwenzeke?\n\nUma kuwukuthi awuzange ucele ukuthi kwesekelwe ngokulondoloza wena uqobo lwakho, ungavumeli ukuthi lolu hlelo luqhubekele phambili."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Sekela ngokulondoloza imininingo yami"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Ungenzi isipele"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"Kucelwe ukubuyiselwa esimweni okuphelele kwayo yonke imininingo yakho kwi-desktop yekhompuyutha exhunyiswe. Ngabe ufuna ukuvumela lokhu ukuthi kwenzeke?"\n\n"Uma ungazange ucele ukuthi lokhu kwenzeke wena uqobo, ungavumeli lokhu ukuthi kuqhubekele phambili. Lokhu kuzothatha indawo yayo yonke imininingo ekhona njengamanje kwi-device!"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Kucelwe ukubuyiselwa esimweni okuphelele kwayo yonke imininingo yakho kwi-desktop yekhompuyutha exhunyiswe. Ngabe ufuna ukuvumela lokhu ukuthi kwenzeke?\n\nUma ungazange ucele ukuthi lokhu kwenzeke wena uqobo, ungavumeli lokhu ukuthi kuqhubekele phambili. Lokhu kuzothatha indawo yayo yonke imininingo ekhona njengamanje kwi-device!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Buyisela esimweni imininingo yami"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Ungabuyiseli esimweni"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Sicela ufake iphasiwedi yakho yamanje yokwenza isipele ngezansi:"</string>
@@ -29,7 +29,7 @@
     <string name="device_encryption_backup_text" msgid="5866590762672844664">"Uyacelwa ukuba ufake iphasiwedi efakwe kudivayisi yakho ngezansi. lokhu kuzosetshenziswa ukufaka kusilondoloza sokusiza lapho kudingeka."</string>
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Sicela ufake iphasiwedi ezosetshenziselwa ukubhala ngokufihlekileyo imininingo eyesekwe ngokulondoloza. Uma lokhu kushiywe kungabhalwe lutho, kuzosetshenziswa iphasiwedi yokweseka ngokulondoloza yamanje:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Uma ufuna ukufaka ikhowudi kwimininingo yonke eyesekelwe ngokulondoloza faka i-passowrd engezansi:"</string>
-    <string name="restore_enc_password_text" msgid="6140898525580710823">"Uma insiza yokubuyiselwa esimweni kwmininingo ibhalwe ngokufihlekileyo, sicela ufake iphasiwedi engezansi:"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"Uma uhlelo lokusebenza yokubuyiselwa esimweni kwmininingo ibhalwe ngokufihlekileyo, sicela ufake iphasiwedi engezansi:"</string>
     <string name="toast_backup_started" msgid="550354281452756121">"Ukulondoloza kuyaqala..."</string>
     <string name="toast_backup_ended" msgid="3818080769548726424">"Ukulondoloza kuphelile"</string>
     <string name="toast_restore_started" msgid="7881679218971277385">"Ukubuyisa kuyaqala..."</string>
diff --git a/packages/DefaultContainerService/Android.mk b/packages/DefaultContainerService/Android.mk
index 56b8005..9961168 100644
--- a/packages/DefaultContainerService/Android.mk
+++ b/packages/DefaultContainerService/Android.mk
@@ -11,6 +11,8 @@
 
 LOCAL_CERTIFICATE := platform
 
+LOCAL_PRIVILEGED_MODULE := true
+
 include $(BUILD_PACKAGE)
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/DefaultContainerService/res/values-en-rIN/strings.xml b/packages/DefaultContainerService/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..216d715
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-en-rIN/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="service_name" msgid="4841491635055379553">"Package Access Helper"</string>
+</resources>
diff --git a/packages/DefaultContainerService/res/values-et-rEE/strings.xml b/packages/DefaultContainerService/res/values-et-rEE/strings.xml
new file mode 100644
index 0000000..216d715
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-et-rEE/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="service_name" msgid="4841491635055379553">"Package Access Helper"</string>
+</resources>
diff --git a/packages/DefaultContainerService/res/values-fr-rCA/strings.xml b/packages/DefaultContainerService/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..69c4e99
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-fr-rCA/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="service_name" msgid="4841491635055379553">"Aide accès au paquet"</string>
+</resources>
diff --git a/packages/DefaultContainerService/res/values-hy-rAM/strings.xml b/packages/DefaultContainerService/res/values-hy-rAM/strings.xml
new file mode 100644
index 0000000..1e2f587
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-hy-rAM/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns: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>
+</resources>
diff --git a/packages/DefaultContainerService/res/values-ka-rGE/strings.xml b/packages/DefaultContainerService/res/values-ka-rGE/strings.xml
new file mode 100644
index 0000000..216d715
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-ka-rGE/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="service_name" msgid="4841491635055379553">"Package Access Helper"</string>
+</resources>
diff --git a/packages/DefaultContainerService/res/values-km-rKH/strings.xml b/packages/DefaultContainerService/res/values-km-rKH/strings.xml
new file mode 100644
index 0000000..1006d56
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-km-rKH/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns: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>
+</resources>
diff --git a/packages/DefaultContainerService/res/values-lo-rLA/strings.xml b/packages/DefaultContainerService/res/values-lo-rLA/strings.xml
new file mode 100644
index 0000000..216d715
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-lo-rLA/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="service_name" msgid="4841491635055379553">"Package Access Helper"</string>
+</resources>
diff --git a/packages/DefaultContainerService/res/values-mn-rMN/strings.xml b/packages/DefaultContainerService/res/values-mn-rMN/strings.xml
new file mode 100644
index 0000000..d9fe647
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-mn-rMN/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns: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>
+</resources>
diff --git a/packages/DefaultContainerService/res/values-ms-rMY/strings.xml b/packages/DefaultContainerService/res/values-ms-rMY/strings.xml
new file mode 100644
index 0000000..77d7927
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-ms-rMY/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="service_name" msgid="4841491635055379553">"Pembantu Akses Pakej"</string>
+</resources>
diff --git a/packages/DefaultContainerService/res/values-zh-rHK/strings.xml b/packages/DefaultContainerService/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..9a43509
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-zh-rHK/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns: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>
+</resources>
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index d3bd197..6e34bbb 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -146,6 +146,8 @@
                 Slog.e(TAG, "Could not copy URI " + packageURI.toString() + " Security: "
                                 + e.getMessage());
                 return PackageManager.INSTALL_FAILED_INVALID_APK;
+            } finally {
+                IoUtils.closeQuietly(autoOut);
             }
         }
 
@@ -293,10 +295,10 @@
             try {
                 while ((item = pm.nextPackageToClean(item)) != null) {
                     final UserEnvironment userEnv = new UserEnvironment(item.userId);
-                    eraseFiles(userEnv.getExternalStorageAppDataDirectory(item.packageName));
-                    eraseFiles(userEnv.getExternalStorageAppMediaDirectory(item.packageName));
+                    eraseFiles(userEnv.buildExternalStorageAppDataDirs(item.packageName));
+                    eraseFiles(userEnv.buildExternalStorageAppMediaDirs(item.packageName));
                     if (item.andCode) {
-                        eraseFiles(userEnv.getExternalStorageAppObbDirectory(item.packageName));
+                        eraseFiles(userEnv.buildExternalStorageAppObbDirs(item.packageName));
                     }
                 }
             } catch (RemoteException e) {
@@ -304,6 +306,12 @@
         }
     }
 
+    void eraseFiles(File[] paths) {
+        for (File path : paths) {
+            eraseFiles(path);
+        }
+    }
+
     void eraseFiles(File path) {
         if (path.isDirectory()) {
             String[] files = path.list();
diff --git a/packages/DocumentsUI/Android.mk b/packages/DocumentsUI/Android.mk
new file mode 100644
index 0000000..2f97809
--- /dev/null
+++ b/packages/DocumentsUI/Android.mk
@@ -0,0 +1,13 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 guava
+
+LOCAL_PACKAGE_NAME := DocumentsUI
+LOCAL_CERTIFICATE := platform
+
+include $(BUILD_PACKAGE)
diff --git a/packages/DocumentsUI/AndroidManifest.xml b/packages/DocumentsUI/AndroidManifest.xml
new file mode 100644
index 0000000..1ef7bff
--- /dev/null
+++ b/packages/DocumentsUI/AndroidManifest.xml
@@ -0,0 +1,68 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.documentsui">
+
+    <uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
+
+    <application
+        android:name=".DocumentsApplication"
+        android:label="@string/app_label"
+        android:supportsRtl="true">
+
+        <!-- TODO: allow rotation when state saving is in better shape -->
+        <activity
+            android:name=".DocumentsActivity"
+            android:theme="@style/Theme">
+            <intent-filter android:priority="100">
+                <action android:name="android.intent.action.OPEN_DOCUMENT" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.OPENABLE" />
+                <data android:mimeType="*/*" />
+            </intent-filter>
+            <intent-filter android:priority="100">
+                <action android:name="android.intent.action.CREATE_DOCUMENT" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.OPENABLE" />
+                <data android:mimeType="*/*" />
+            </intent-filter>
+            <intent-filter android:priority="100">
+                <action android:name="android.intent.action.GET_CONTENT" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.OPENABLE" />
+                <data android:mimeType="*/*" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.provider.action.MANAGE_ROOT" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:mimeType="vnd.android.document/root" />
+            </intent-filter>
+        </activity>
+
+        <activity
+            android:name=".SettingsActivity"
+            android:label="@string/menu_settings"
+            android:theme="@android:style/Theme.Holo.Light.DialogWhenLarge"
+            android:exported="false" />
+
+        <provider
+            android:name=".RecentsProvider"
+            android:authorities="com.android.documentsui.recents"
+            android:exported="false" />
+
+        <receiver android:name=".DocumentChangedReceiver">
+            <intent-filter>
+                <action android:name="android.provider.action.DOCUMENT_CHANGED" />
+                <data android:mimeType="vnd.android.cursor.dir/root" />
+                <data android:mimeType="vnd.android.cursor.item/root" />
+            </intent-filter>
+        </receiver>
+
+        <!-- TODO: remove when we have real clients -->
+        <activity android:name=".TestActivity" android:enabled="false">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_breadcrumb_arrow.png b/packages/DocumentsUI/res/drawable-hdpi/ic_breadcrumb_arrow.png
new file mode 100644
index 0000000..8a170b0
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_breadcrumb_arrow.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_cab_accept.png b/packages/DocumentsUI/res/drawable-hdpi/ic_cab_accept.png
new file mode 100644
index 0000000..a7726e7
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_cab_accept.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_cab_cancel.png b/packages/DocumentsUI/res/drawable-hdpi/ic_cab_cancel.png
new file mode 100644
index 0000000..658a6dd
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_cab_cancel.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_cab_select_item.png b/packages/DocumentsUI/res/drawable-hdpi/ic_cab_select_item.png
new file mode 100644
index 0000000..57b3069
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_cab_select_item.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_dialog_alert.png b/packages/DocumentsUI/res/drawable-hdpi/ic_dialog_alert.png
new file mode 100644
index 0000000..40b4326
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_dialog_alert.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_apk.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_apk.png
new file mode 100644
index 0000000..36fccad
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_apk.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_audio.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_audio.png
new file mode 100644
index 0000000..3aba859
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_audio.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_certificate.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_certificate.png
new file mode 100644
index 0000000..778f9ba
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_certificate.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_codes.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_codes.png
new file mode 100644
index 0000000..65b03d1
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_codes.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_compressed.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_compressed.png
new file mode 100644
index 0000000..e9719b8
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_compressed.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_contact.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_contact.png
new file mode 100644
index 0000000..4b2107c
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_contact.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_event.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_event.png
new file mode 100644
index 0000000..9ca3b35
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_event.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_font.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_font.png
new file mode 100644
index 0000000..dc3bebc
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_font.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_image.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_image.png
new file mode 100644
index 0000000..69afe06
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_image.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_pdf.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_pdf.png
new file mode 100644
index 0000000..c86b92d
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_pdf.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_presentation.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_presentation.png
new file mode 100644
index 0000000..9b9729b
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_presentation.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_spreadsheet.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_spreadsheet.png
new file mode 100644
index 0000000..ab917cef
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_spreadsheet.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_text.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_text.png
new file mode 100644
index 0000000..9b96b2f
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_text.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_doc_video.png b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_video.png
new file mode 100644
index 0000000..89a0d37
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_doc_video.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_drawer.png b/packages/DocumentsUI/res/drawable-hdpi/ic_drawer.png
new file mode 100644
index 0000000..ff7b1de
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_drawer.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_drawer_shadow.9.png b/packages/DocumentsUI/res/drawable-hdpi/ic_drawer_shadow.9.png
new file mode 100644
index 0000000..594ce69
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_drawer_shadow.9.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_drawer_shadow_tablet.9.png b/packages/DocumentsUI/res/drawable-hdpi/ic_drawer_shadow_tablet.9.png
new file mode 100644
index 0000000..6ee47a9
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_drawer_shadow_tablet.9.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_grid_card_background.9.png b/packages/DocumentsUI/res/drawable-hdpi/ic_grid_card_background.9.png
new file mode 100644
index 0000000..8797e94
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_grid_card_background.9.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_grid_gradient_bg.9.png b/packages/DocumentsUI/res/drawable-hdpi/ic_grid_gradient_bg.9.png
new file mode 100644
index 0000000..4b9eeb0
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_grid_gradient_bg.9.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_copy.png b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_copy.png
new file mode 100644
index 0000000..85b60ac
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_copy.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_delete.png b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_delete.png
new file mode 100644
index 0000000..3a039e0
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_delete.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_disconnect.png b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_disconnect.png
new file mode 100644
index 0000000..164d2de
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_disconnect.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_new_folder.png b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_new_folder.png
new file mode 100644
index 0000000..06adf31
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_new_folder.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_rename.png b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_rename.png
new file mode 100644
index 0000000..e8b000c
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_rename.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_search.png b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_search.png
new file mode 100644
index 0000000..a5ed309
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_search.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_settings.png b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_settings.png
new file mode 100644
index 0000000..2406366
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_settings.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_share.png b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_share.png
new file mode 100644
index 0000000..61b7099
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_share.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_sortby.png b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_sortby.png
new file mode 100644
index 0000000..05df3d7
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_sortby.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_undo.png b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_undo.png
new file mode 100644
index 0000000..6ac9dc1
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_undo.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_view_grid.png b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_view_grid.png
new file mode 100644
index 0000000..0779f5c
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_view_grid.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_menu_view_list.png b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_view_list.png
new file mode 100644
index 0000000..ab7e5cb
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_menu_view_list.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_open.png b/packages/DocumentsUI/res/drawable-hdpi/ic_open.png
new file mode 100644
index 0000000..17f4a41
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_open.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_root_download.png b/packages/DocumentsUI/res/drawable-hdpi/ic_root_download.png
new file mode 100644
index 0000000..baf5810
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_root_download.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_root_folder.png b/packages/DocumentsUI/res/drawable-hdpi/ic_root_folder.png
new file mode 100644
index 0000000..4ee96b9
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_root_folder.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_root_recent.png b/packages/DocumentsUI/res/drawable-hdpi/ic_root_recent.png
new file mode 100644
index 0000000..5374e27
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_root_recent.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_root_sdcard.png b/packages/DocumentsUI/res/drawable-hdpi/ic_root_sdcard.png
new file mode 100644
index 0000000..caf58030
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_root_sdcard.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_root_usb.png b/packages/DocumentsUI/res/drawable-hdpi/ic_root_usb.png
new file mode 100644
index 0000000..cfa69f1
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_root_usb.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_subdirectory_arrow.png b/packages/DocumentsUI/res/drawable-hdpi/ic_subdirectory_arrow.png
new file mode 100644
index 0000000..f5c5f18
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-hdpi/ic_subdirectory_arrow.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_breadcrumb_arrow.png b/packages/DocumentsUI/res/drawable-mdpi/ic_breadcrumb_arrow.png
new file mode 100644
index 0000000..623d9db
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_breadcrumb_arrow.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_cab_accept.png b/packages/DocumentsUI/res/drawable-mdpi/ic_cab_accept.png
new file mode 100644
index 0000000..11779bb
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_cab_accept.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_cab_cancel.png b/packages/DocumentsUI/res/drawable-mdpi/ic_cab_cancel.png
new file mode 100644
index 0000000..bebd803
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_cab_cancel.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_cab_select_item.png b/packages/DocumentsUI/res/drawable-mdpi/ic_cab_select_item.png
new file mode 100644
index 0000000..af2412f
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_cab_select_item.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_dialog_alert.png b/packages/DocumentsUI/res/drawable-mdpi/ic_dialog_alert.png
new file mode 100644
index 0000000..b092ea0
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_dialog_alert.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_apk.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_apk.png
new file mode 100644
index 0000000..1c6f8d1
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_apk.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_audio.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_audio.png
new file mode 100644
index 0000000..40cdc76
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_audio.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_certificate.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_certificate.png
new file mode 100644
index 0000000..94339f4
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_certificate.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_codes.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_codes.png
new file mode 100644
index 0000000..a84490c
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_codes.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_compressed.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_compressed.png
new file mode 100644
index 0000000..f827d6d
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_compressed.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_contact.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_contact.png
new file mode 100644
index 0000000..33f1367
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_contact.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_event.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_event.png
new file mode 100644
index 0000000..6597785
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_event.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_font.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_font.png
new file mode 100644
index 0000000..8b1cded
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_font.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_image.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_image.png
new file mode 100644
index 0000000..0217430
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_image.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_pdf.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_pdf.png
new file mode 100644
index 0000000..ff51096
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_pdf.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_presentation.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_presentation.png
new file mode 100644
index 0000000..0860552
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_presentation.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_spreadsheet.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_spreadsheet.png
new file mode 100644
index 0000000..7431e83
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_spreadsheet.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_text.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_text.png
new file mode 100644
index 0000000..c540a80
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_text.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_doc_video.png b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_video.png
new file mode 100644
index 0000000..ab0222a
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_doc_video.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_drawer_shadow.9.png b/packages/DocumentsUI/res/drawable-mdpi/ic_drawer_shadow.9.png
new file mode 100644
index 0000000..99a30269
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_drawer_shadow.9.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_drawer_shadow_tablet.9.png b/packages/DocumentsUI/res/drawable-mdpi/ic_drawer_shadow_tablet.9.png
new file mode 100644
index 0000000..b85d70b
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_drawer_shadow_tablet.9.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_grid_card_background.9.png b/packages/DocumentsUI/res/drawable-mdpi/ic_grid_card_background.9.png
new file mode 100644
index 0000000..d632b58
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_grid_card_background.9.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_grid_gradient_bg.9.png b/packages/DocumentsUI/res/drawable-mdpi/ic_grid_gradient_bg.9.png
new file mode 100644
index 0000000..792b269
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_grid_gradient_bg.9.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_menu_copy.png b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_copy.png
new file mode 100644
index 0000000..ea1ea52
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_copy.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_menu_delete.png b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_delete.png
new file mode 100644
index 0000000..9992321
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_delete.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_menu_disconnect.png b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_disconnect.png
new file mode 100644
index 0000000..cb09782
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_disconnect.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_menu_new_folder.png b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_new_folder.png
new file mode 100644
index 0000000..65dfaa6
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_new_folder.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_menu_rename.png b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_rename.png
new file mode 100644
index 0000000..a56b776
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_rename.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_menu_search.png b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_search.png
new file mode 100644
index 0000000..4e44240
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_search.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_menu_settings.png b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_settings.png
new file mode 100644
index 0000000..67f8e4d
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_settings.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_menu_share.png b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_share.png
new file mode 100644
index 0000000..ecd5a17
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_share.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_menu_sortby.png b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_sortby.png
new file mode 100644
index 0000000..549a381
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_sortby.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_menu_undo.png b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_undo.png
new file mode 100644
index 0000000..43b7220
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_undo.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_menu_view_grid.png b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_view_grid.png
new file mode 100644
index 0000000..0e40d89
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_view_grid.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_menu_view_list.png b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_view_list.png
new file mode 100644
index 0000000..d0c1717
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_menu_view_list.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_open.png b/packages/DocumentsUI/res/drawable-mdpi/ic_open.png
new file mode 100644
index 0000000..56cfa49
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_open.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_root_download.png b/packages/DocumentsUI/res/drawable-mdpi/ic_root_download.png
new file mode 100644
index 0000000..60ebeef
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_root_download.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_root_folder.png b/packages/DocumentsUI/res/drawable-mdpi/ic_root_folder.png
new file mode 100644
index 0000000..944de5b
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_root_folder.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_root_recent.png b/packages/DocumentsUI/res/drawable-mdpi/ic_root_recent.png
new file mode 100644
index 0000000..45f7e0b
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_root_recent.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_root_sdcard.png b/packages/DocumentsUI/res/drawable-mdpi/ic_root_sdcard.png
new file mode 100644
index 0000000..3b065f3
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_root_sdcard.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_root_usb.png b/packages/DocumentsUI/res/drawable-mdpi/ic_root_usb.png
new file mode 100644
index 0000000..fb83d5d
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_root_usb.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_subdirectory_arrow.png b/packages/DocumentsUI/res/drawable-mdpi/ic_subdirectory_arrow.png
new file mode 100644
index 0000000..276f00d
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-mdpi/ic_subdirectory_arrow.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_breadcrumb_arrow.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_breadcrumb_arrow.png
new file mode 100644
index 0000000..9109320
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_breadcrumb_arrow.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_cab_accept.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_cab_accept.png
new file mode 100644
index 0000000..89e580b
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_cab_accept.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_cab_cancel.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_cab_cancel.png
new file mode 100644
index 0000000..d35b802
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_cab_cancel.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_cab_select_item.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_cab_select_item.png
new file mode 100644
index 0000000..254cb18
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_cab_select_item.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_dialog_alert.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_dialog_alert.png
new file mode 100644
index 0000000..d824bb0
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_dialog_alert.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_apk.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_apk.png
new file mode 100644
index 0000000..baded5e
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_apk.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_audio.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_audio.png
new file mode 100644
index 0000000..908aafb
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_audio.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_certificate.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_certificate.png
new file mode 100644
index 0000000..1c3dee4
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_certificate.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_codes.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_codes.png
new file mode 100644
index 0000000..a068209
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_codes.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_compressed.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_compressed.png
new file mode 100644
index 0000000..af0e36d
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_compressed.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_contact.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_contact.png
new file mode 100644
index 0000000..e6833dc
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_contact.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_event.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_event.png
new file mode 100644
index 0000000..ff67036
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_event.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_font.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_font.png
new file mode 100644
index 0000000..aaca230
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_font.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_image.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_image.png
new file mode 100644
index 0000000..5221393
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_image.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_pdf.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_pdf.png
new file mode 100644
index 0000000..518e591
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_pdf.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_presentation.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_presentation.png
new file mode 100644
index 0000000..5c4edf6
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_presentation.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_spreadsheet.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_spreadsheet.png
new file mode 100644
index 0000000..d10dcf7
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_spreadsheet.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_text.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_text.png
new file mode 100644
index 0000000..f15cdfb
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_text.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_video.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_video.png
new file mode 100644
index 0000000..f751be7
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_doc_video.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_drawer_shadow.9.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_drawer_shadow.9.png
new file mode 100644
index 0000000..96acf35
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_drawer_shadow.9.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_drawer_shadow_tablet.9.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_drawer_shadow_tablet.9.png
new file mode 100644
index 0000000..d21193a
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_drawer_shadow_tablet.9.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_grid_card_background.9.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_grid_card_background.9.png
new file mode 100644
index 0000000..2655912
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_grid_card_background.9.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_grid_gradient_bg.9.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_grid_gradient_bg.9.png
new file mode 100644
index 0000000..450a486
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_grid_gradient_bg.9.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_copy.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_copy.png
new file mode 100644
index 0000000..946e450
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_copy.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_delete.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_delete.png
new file mode 100644
index 0000000..7ab538f
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_delete.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_disconnect.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_disconnect.png
new file mode 100644
index 0000000..904672a
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_disconnect.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_new_folder.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_new_folder.png
new file mode 100644
index 0000000..4af42d4
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_new_folder.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_rename.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_rename.png
new file mode 100644
index 0000000..b63b70c
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_rename.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_search.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_search.png
new file mode 100644
index 0000000..9dd1938
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_search.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_settings.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_settings.png
new file mode 100644
index 0000000..bba370e9
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_settings.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_share.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_share.png
new file mode 100644
index 0000000..bdd8e20
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_share.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_sortby.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_sortby.png
new file mode 100644
index 0000000..a23bee4
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_sortby.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_undo.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_undo.png
new file mode 100644
index 0000000..34a0e33
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_undo.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_view_grid.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_view_grid.png
new file mode 100644
index 0000000..c955fc3
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_view_grid.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_view_list.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_view_list.png
new file mode 100644
index 0000000..a23c73a
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_menu_view_list.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_open.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_open.png
new file mode 100644
index 0000000..b64d8f1
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_open.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_root_download.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_root_download.png
new file mode 100644
index 0000000..f66739d
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_root_download.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_root_folder.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_root_folder.png
new file mode 100644
index 0000000..4d5564c
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_root_folder.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_root_recent.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_root_recent.png
new file mode 100644
index 0000000..7e24377
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_root_recent.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_root_sdcard.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_root_sdcard.png
new file mode 100644
index 0000000..0ce9f9f
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_root_sdcard.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_root_usb.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_root_usb.png
new file mode 100644
index 0000000..dde7586
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_root_usb.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_subdirectory_arrow.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_subdirectory_arrow.png
new file mode 100644
index 0000000..7f3364d
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xhdpi/ic_subdirectory_arrow.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_breadcrumb_arrow.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_breadcrumb_arrow.png
new file mode 100644
index 0000000..06681e3
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_breadcrumb_arrow.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_cab_accept.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_cab_accept.png
new file mode 100644
index 0000000..ac88818
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_cab_accept.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_cab_cancel.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_cab_cancel.png
new file mode 100644
index 0000000..88356c7
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_cab_cancel.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_cab_select_item.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_cab_select_item.png
new file mode 100644
index 0000000..75658db
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_cab_select_item.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_dialog_alert.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_dialog_alert.png
new file mode 100644
index 0000000..887b1b5
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_dialog_alert.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_apk.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_apk.png
new file mode 100644
index 0000000..4eaf6ce
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_apk.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_audio.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_audio.png
new file mode 100644
index 0000000..3659f4a
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_audio.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_certificate.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_certificate.png
new file mode 100644
index 0000000..68e619e
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_certificate.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_codes.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_codes.png
new file mode 100644
index 0000000..0ec4e86
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_codes.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_compressed.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_compressed.png
new file mode 100644
index 0000000..bf49d78
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_compressed.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_contact.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_contact.png
new file mode 100644
index 0000000..bdd99d6
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_contact.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_event.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_event.png
new file mode 100644
index 0000000..77a0fae
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_event.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_font.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_font.png
new file mode 100644
index 0000000..30d2c4c
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_font.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_image.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_image.png
new file mode 100644
index 0000000..5991968
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_image.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_pdf.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_pdf.png
new file mode 100644
index 0000000..dd94dda
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_pdf.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_presentation.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_presentation.png
new file mode 100644
index 0000000..c09d6ab
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_presentation.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_spreadsheet.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_spreadsheet.png
new file mode 100644
index 0000000..2170e66
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_spreadsheet.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_text.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_text.png
new file mode 100644
index 0000000..84960b9
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_text.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_video.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_video.png
new file mode 100644
index 0000000..42d8ec1
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_doc_video.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_drawer_shadow.9.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_drawer_shadow.9.png
new file mode 100644
index 0000000..97fd9d6
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_drawer_shadow.9.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_drawer_shadow_tablet.9.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_drawer_shadow_tablet.9.png
new file mode 100644
index 0000000..3c95790
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_drawer_shadow_tablet.9.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_grid_card_background.9.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_grid_card_background.9.png
new file mode 100644
index 0000000..7bbaf9d
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_grid_card_background.9.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_grid_gradient_bg.9.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_grid_gradient_bg.9.png
new file mode 100644
index 0000000..988c856
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_grid_gradient_bg.9.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_copy.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_copy.png
new file mode 100644
index 0000000..2a0cfc2
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_copy.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_delete.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_delete.png
new file mode 100644
index 0000000..f4dca7f
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_delete.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_disconnect.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_disconnect.png
new file mode 100644
index 0000000..676d0f7
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_disconnect.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_new_folder.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_new_folder.png
new file mode 100644
index 0000000..fb40707
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_new_folder.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_rename.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_rename.png
new file mode 100644
index 0000000..140abba
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_rename.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_search.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_search.png
new file mode 100644
index 0000000..6079806
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_search.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_settings.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_settings.png
new file mode 100644
index 0000000..ecd7de1
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_settings.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_share.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_share.png
new file mode 100644
index 0000000..0a3ac2e
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_share.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_sortby.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_sortby.png
new file mode 100644
index 0000000..358f97a
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_sortby.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_undo.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_undo.png
new file mode 100644
index 0000000..fd0a194
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_undo.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_view_grid.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_view_grid.png
new file mode 100644
index 0000000..11ec8da
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_view_grid.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_view_list.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_view_list.png
new file mode 100644
index 0000000..ed3b0c5
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_menu_view_list.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_open.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_open.png
new file mode 100644
index 0000000..b467962
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_open.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_download.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_download.png
new file mode 100644
index 0000000..f22a94a
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_download.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_folder.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_folder.png
new file mode 100644
index 0000000..077c851
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_folder.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_recent.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_recent.png
new file mode 100644
index 0000000..09cac0e
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_recent.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_sdcard.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_sdcard.png
new file mode 100644
index 0000000..5349252
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_sdcard.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_usb.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_usb.png
new file mode 100644
index 0000000..6deafc7
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_root_usb.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_subdirectory_arrow.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_subdirectory_arrow.png
new file mode 100644
index 0000000..8710c68
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable-xxhdpi/ic_subdirectory_arrow.png
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable/item_background.xml b/packages/DocumentsUI/res/drawable/item_background.xml
new file mode 100644
index 0000000..7447aa8
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable/item_background.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item android:state_enabled="false" android:state_selected="true" android:drawable="@*android:drawable/list_selector_disabled_holo_light" />
+    <item android:state_enabled="false" android:state_focused="true"  android:drawable="@*android:drawable/list_selector_disabled_holo_light" />
+    <item android:state_enabled="false" android:state_pressed="true"  android:drawable="@*android:drawable/list_selector_disabled_holo_light" />
+
+    <item android:state_activated="true" android:state_pressed="true" android:drawable="@*android:drawable/list_activated_holo" />
+    <item android:state_activated="true" android:drawable="@*android:drawable/list_activated_holo" />
+
+    <item android:state_focused="true" android:drawable="@*android:drawable/list_focused_holo" />
+    <item android:state_selected="true" android:drawable="@*android:drawable/list_focused_holo" />
+
+    <item android:state_pressed="true" android:state_focused="true" android:drawable="@*android:drawable/list_selector_background_transition_holo_light" />
+    <item android:state_pressed="true" android:drawable="@*android:drawable/list_selector_background_transition_holo_light" />
+
+    <item android:drawable="@android:color/transparent" />
+
+</selector>
diff --git a/packages/DocumentsUI/res/drawable/item_doc_grid.xml b/packages/DocumentsUI/res/drawable/item_doc_grid.xml
new file mode 100644
index 0000000..3f036f7
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable/item_doc_grid.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@drawable/ic_grid_card_background" />
+</selector>
diff --git a/packages/DocumentsUI/res/drawable/item_root.xml b/packages/DocumentsUI/res/drawable/item_root.xml
new file mode 100644
index 0000000..6f201cc
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable/item_root.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true" android:drawable="@color/item_root_activated" />
+    <item android:state_activated="true" android:drawable="@color/item_root_activated" />
+    <item android:state_focused="true" android:drawable="@color/item_root_activated" />
+    <item android:drawable="@android:color/transparent" />
+</selector>
diff --git a/packages/DocumentsUI/res/layout-sw720dp-land/item_doc_list.xml b/packages/DocumentsUI/res/layout-sw720dp-land/item_doc_list.xml
new file mode 100644
index 0000000..3bea166
--- /dev/null
+++ b/packages/DocumentsUI/res/layout-sw720dp-land/item_doc_list.xml
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@drawable/item_background"
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:paddingTop="8dip"
+    android:paddingBottom="8dip"
+    android:orientation="horizontal">
+
+    <FrameLayout
+        android:id="@android:id/icon"
+        android:layout_width="@dimen/icon_size"
+        android:layout_height="@dimen/icon_size"
+        android:layout_marginStart="12dp"
+        android:layout_marginEnd="20dp"
+        android:layout_gravity="center_vertical">
+
+        <ImageView
+            android:id="@+id/icon_mime"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:scaleType="centerInside"
+            android:contentDescription="@null" />
+
+        <ImageView
+            android:id="@+id/icon_thumb"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:scaleType="centerCrop"
+            android:contentDescription="@null" />
+
+    </FrameLayout>
+
+    <LinearLayout
+        android:layout_width="0dip"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:layout_gravity="center_vertical"
+        android:orientation="horizontal">
+
+        <TextView
+            android:id="@android:id/title"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="0.5"
+            android:layout_marginEnd="12dp"
+            android:singleLine="true"
+            android:ellipsize="marquee"
+            android:textAlignment="viewStart"
+            style="@style/TextAppearance.Medium" />
+
+        <ImageView
+            android:id="@android:id/icon1"
+            android:layout_width="@dimen/root_icon_size"
+            android:layout_height="@dimen/root_icon_size"
+            android:layout_marginEnd="8dp"
+            android:scaleType="centerInside"
+            android:contentDescription="@null" />
+
+        <TextView
+            android:id="@android:id/summary"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="0.25"
+            android:layout_marginEnd="12dp"
+            android:singleLine="true"
+            android:ellipsize="marquee"
+            android:textAlignment="viewStart"
+            style="@style/TextAppearance.Small" />
+
+        <TextView
+            android:id="@+id/size"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="0.125"
+            android:layout_marginEnd="12dp"
+            android:minWidth="70dp"
+            android:singleLine="true"
+            android:ellipsize="marquee"
+            android:textAlignment="viewEnd"
+            style="@style/TextAppearance.Small" />
+
+        <TextView
+            android:id="@+id/date"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="0.125"
+            android:layout_marginEnd="12dp"
+            android:minWidth="70dp"
+            android:singleLine="true"
+            android:ellipsize="marquee"
+            android:textAlignment="viewEnd"
+            style="@style/TextAppearance.Small" />
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/packages/DocumentsUI/res/layout-sw720dp/activity.xml b/packages/DocumentsUI/res/layout-sw720dp/activity.xml
new file mode 100644
index 0000000..584a44d
--- /dev/null
+++ b/packages/DocumentsUI/res/layout-sw720dp/activity.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="horizontal">
+
+    <FrameLayout
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:id="@+id/dialog_roots">
+
+        <FrameLayout
+            android:id="@+id/container_roots"
+            android:layout_width="250dp"
+            android:layout_height="match_parent" />
+
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:layout_gravity="end"
+            android:scaleType="fitXY"
+            android:src="@drawable/ic_drawer_shadow_tablet" />
+
+    </FrameLayout>
+
+    <LinearLayout
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:orientation="vertical">
+
+        <FrameLayout
+            android:id="@+id/container_directory"
+            android:layout_width="match_parent"
+            android:layout_height="0dip"
+            android:layout_weight="1" />
+
+        <FrameLayout
+            android:id="@+id/container_save"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/packages/DocumentsUI/res/layout/activity.xml b/packages/DocumentsUI/res/layout/activity.xml
new file mode 100644
index 0000000..ff28e41
--- /dev/null
+++ b/packages/DocumentsUI/res/layout/activity.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/drawer_layout"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+
+        <FrameLayout
+            android:id="@+id/container_directory"
+            android:layout_width="match_parent"
+            android:layout_height="0dip"
+            android:layout_weight="1" />
+
+        <FrameLayout
+            android:id="@+id/container_save"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+
+    </LinearLayout>
+
+    <FrameLayout
+        android:id="@+id/container_roots"
+        android:layout_width="250dp"
+        android:layout_height="match_parent"
+        android:layout_gravity="start"
+        android:background="#fff" />
+
+</android.support.v4.widget.DrawerLayout>
diff --git a/packages/DocumentsUI/res/layout/dialog_create_dir.xml b/packages/DocumentsUI/res/layout/dialog_create_dir.xml
new file mode 100644
index 0000000..54e26b4
--- /dev/null
+++ b/packages/DocumentsUI/res/layout/dialog_create_dir.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:padding="?android:attr/listPreferredItemPaddingEnd">
+
+    <EditText
+        android:id="@android:id/text1"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" />
+
+</FrameLayout>
diff --git a/packages/DocumentsUI/res/layout/fragment_backend.xml b/packages/DocumentsUI/res/layout/fragment_backend.xml
new file mode 100644
index 0000000..2648de2
--- /dev/null
+++ b/packages/DocumentsUI/res/layout/fragment_backend.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <GridView
+        android:id="@+id/grid"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:listSelector="@android:color/transparent"
+        android:paddingTop="?android:attr/listPreferredItemPaddingStart"
+        android:paddingStart="?android:attr/listPreferredItemPaddingStart" />
+
+</FrameLayout>
diff --git a/packages/DocumentsUI/res/layout/fragment_directory.xml b/packages/DocumentsUI/res/layout/fragment_directory.xml
new file mode 100644
index 0000000..b4138a5
--- /dev/null
+++ b/packages/DocumentsUI/res/layout/fragment_directory.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <TextView
+        android:id="@android:id/empty"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:gravity="center"
+        android:text="@string/empty"
+        android:visibility="gone"
+        style="@style/TextAppearance.Medium" />
+
+    <ListView
+        android:id="@+id/list"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:listSelector="@android:color/transparent" />
+
+    <GridView
+        android:id="@+id/grid"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:listSelector="@android:color/transparent"
+        android:visibility="gone" />
+
+</FrameLayout>
diff --git a/packages/DocumentsUI/res/layout/fragment_roots.xml b/packages/DocumentsUI/res/layout/fragment_roots.xml
new file mode 100644
index 0000000..09782d9
--- /dev/null
+++ b/packages/DocumentsUI/res/layout/fragment_roots.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<ListView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@android:id/list"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:divider="@null" />
diff --git a/packages/DocumentsUI/res/layout/fragment_save.xml b/packages/DocumentsUI/res/layout/fragment_save.xml
new file mode 100644
index 0000000..49038bc
--- /dev/null
+++ b/packages/DocumentsUI/res/layout/fragment_save.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="horizontal"
+    android:gravity="center_vertical"
+    android:background="@color/chip"
+    android:minHeight="?android:attr/listPreferredItemHeightSmall">
+
+    <ImageView
+        android:id="@android:id/icon"
+        android:layout_width="24dp"
+        android:layout_height="24dp"
+        android:layout_marginStart="8dp"
+        android:layout_marginEnd="8dp"
+        android:scaleType="centerInside"
+        android:contentDescription="@null" />
+
+    <EditText
+        android:id="@android:id/title"
+        android:layout_width="0dip"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:singleLine="true"
+        android:selectAllOnFocus="true" />
+
+    <Button
+        android:id="@android:id/button1"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:background="?android:attr/selectableItemBackground"
+        android:text="@string/menu_save"
+        android:textAllCaps="true"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:padding="8dp" />
+
+</LinearLayout>
diff --git a/packages/DocumentsUI/res/layout/item_doc_grid.xml b/packages/DocumentsUI/res/layout/item_doc_grid.xml
new file mode 100644
index 0000000..b745bb9
--- /dev/null
+++ b/packages/DocumentsUI/res/layout/item_doc_grid.xml
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="@dimen/grid_height"
+    android:background="@drawable/item_doc_grid"
+    android:foreground="@drawable/item_background">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:paddingBottom="6dp"
+        android:orientation="vertical">
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="0dip"
+            android:layout_weight="1"
+            android:layout_marginBottom="6dp"
+            android:background="#fff">
+
+            <FrameLayout
+                android:id="@android:id/icon"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent">
+
+                <ImageView
+                    android:id="@+id/icon_mime"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:scaleType="centerInside"
+                    android:contentDescription="@null" />
+
+                <ImageView
+                    android:id="@+id/icon_thumb"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:scaleType="centerCrop"
+                    android:contentDescription="@null" />
+
+            </FrameLayout>
+
+            <ImageView
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:scaleType="fitXY"
+                android:src="@drawable/ic_grid_gradient_bg"
+                android:contentDescription="@null" />
+
+        </FrameLayout>
+
+        <LinearLayout
+            android:id="@+id/line1"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+            android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
+
+            <TextView
+                android:id="@android:id/title"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:singleLine="true"
+                android:ellipsize="marquee"
+                android:textAlignment="viewStart"
+                style="@style/TextAppearance.Medium" />
+
+            <ImageView
+                android:id="@android:id/icon1"
+                android:layout_width="@dimen/root_icon_size"
+                android:layout_height="@dimen/root_icon_size"
+                android:layout_marginStart="8dip"
+                android:scaleType="centerInside"
+                android:contentDescription="@null" />
+
+        </LinearLayout>
+
+        <LinearLayout
+            android:id="@+id/line2"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+            android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
+
+            <TextView
+                android:id="@+id/date"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical"
+                android:minWidth="80dp"
+                android:singleLine="true"
+                android:ellipsize="marquee"
+                android:textAlignment="viewStart"
+                style="@style/TextAppearance.Small" />
+
+            <TextView
+                android:id="@+id/size"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical"
+                android:layout_marginStart="8dp"
+                android:minWidth="80dp"
+                android:singleLine="true"
+                android:ellipsize="marquee"
+                android:textAlignment="viewStart"
+                style="@style/TextAppearance.Small" />
+
+            <Space
+                android:layout_width="0dp"
+                android:layout_height="0dp"
+                android:layout_weight="1" />
+
+            <ImageView
+                android:id="@android:id/icon2"
+                android:layout_width="@dimen/root_icon_size"
+                android:layout_height="@dimen/root_icon_size"
+                android:layout_marginStart="8dip"
+                android:scaleType="centerInside"
+                android:contentDescription="@null"
+                android:visibility="gone" />
+
+        </LinearLayout>
+
+    </LinearLayout>
+
+</FrameLayout>
diff --git a/packages/DocumentsUI/res/layout/item_doc_list.xml b/packages/DocumentsUI/res/layout/item_doc_list.xml
new file mode 100644
index 0000000..84fda9d
--- /dev/null
+++ b/packages/DocumentsUI/res/layout/item_doc_list.xml
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@drawable/item_background"
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:paddingTop="8dip"
+    android:paddingBottom="8dip"
+    android:orientation="horizontal">
+
+    <FrameLayout
+        android:id="@android:id/icon"
+        android:layout_width="@dimen/icon_size"
+        android:layout_height="@dimen/icon_size"
+        android:layout_marginStart="12dp"
+        android:layout_marginEnd="20dp"
+        android:layout_gravity="center_vertical">
+
+        <ImageView
+            android:id="@+id/icon_mime"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:scaleType="centerInside"
+            android:contentDescription="@null" />
+
+        <ImageView
+            android:id="@+id/icon_thumb"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:scaleType="centerCrop"
+            android:contentDescription="@null" />
+
+    </FrameLayout>
+
+    <LinearLayout
+        android:layout_width="0dip"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:layout_gravity="center_vertical"
+        android:orientation="vertical">
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+
+            <TextView
+                android:id="@android:id/title"
+                android:layout_width="0dip"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:singleLine="true"
+                android:ellipsize="marquee"
+                android:textAlignment="viewStart"
+                style="@style/TextAppearance.Medium" />
+
+            <ImageView
+                android:id="@android:id/icon1"
+                android:layout_width="@dimen/root_icon_size"
+                android:layout_height="@dimen/root_icon_size"
+                android:layout_marginStart="8dip"
+                android:scaleType="centerInside"
+                android:contentDescription="@null" />
+
+        </LinearLayout>
+
+        <LinearLayout
+            android:id="@+id/line2"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+
+            <TextView
+                android:id="@+id/date"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical"
+                android:minWidth="70dp"
+                android:singleLine="true"
+                android:ellipsize="marquee"
+                android:textAlignment="viewStart"
+                style="@style/TextAppearance.Small" />
+
+            <TextView
+                android:id="@+id/size"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical"
+                android:minWidth="70dp"
+                android:layout_marginStart="8dp"
+                android:singleLine="true"
+                android:ellipsize="marquee"
+                android:textAlignment="viewStart"
+                style="@style/TextAppearance.Small" />
+
+            <TextView
+                android:id="@android:id/summary"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:layout_gravity="center_vertical"
+                android:layout_marginStart="8dp"
+                android:singleLine="true"
+                android:ellipsize="marquee"
+                android:textAlignment="viewStart"
+                style="@style/TextAppearance.Small" />
+
+        </LinearLayout>
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/packages/DocumentsUI/res/layout/item_loading_grid.xml b/packages/DocumentsUI/res/layout/item_loading_grid.xml
new file mode 100644
index 0000000..21be137
--- /dev/null
+++ b/packages/DocumentsUI/res/layout/item_loading_grid.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="@dimen/grid_height"
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:paddingTop="8dip"
+    android:paddingBottom="8dip"
+    android:orientation="horizontal">
+
+    <ProgressBar
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:indeterminate="true"
+        style="?android:attr/progressBarStyle" />
+
+</FrameLayout>
diff --git a/packages/DocumentsUI/res/layout/item_loading_list.xml b/packages/DocumentsUI/res/layout/item_loading_list.xml
new file mode 100644
index 0000000..7da71e3
--- /dev/null
+++ b/packages/DocumentsUI/res/layout/item_loading_list.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<FrameLayout 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:paddingTop="8dip"
+    android:paddingBottom="8dip"
+    android:orientation="horizontal">
+
+    <ProgressBar
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:indeterminate="true"
+        style="?android:attr/progressBarStyle" />
+
+</FrameLayout>
diff --git a/packages/DocumentsUI/res/layout/item_message_grid.xml b/packages/DocumentsUI/res/layout/item_message_grid.xml
new file mode 100644
index 0000000..b3bdd28
--- /dev/null
+++ b/packages/DocumentsUI/res/layout/item_message_grid.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="@dimen/grid_height"
+    android:paddingTop="?android:attr/listPreferredItemPaddingStart"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:paddingBottom="?android:attr/listPreferredItemPaddingEnd"
+    android:foreground="@drawable/item_background">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical"
+        android:gravity="center">
+
+        <ImageView
+            android:id="@android:id/icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:contentDescription="@null" />
+
+        <TextView
+            android:id="@android:id/title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:maxLines="4"
+            android:ellipsize="end"
+            android:paddingTop="6dp"
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:textAlignment="viewStart" />
+
+    </LinearLayout>
+
+</FrameLayout>
diff --git a/packages/DocumentsUI/res/layout/item_message_list.xml b/packages/DocumentsUI/res/layout/item_message_list.xml
new file mode 100644
index 0000000..ffda98c
--- /dev/null
+++ b/packages/DocumentsUI/res/layout/item_message_list.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@drawable/item_background"
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:paddingTop="8dip"
+    android:paddingBottom="8dip"
+    android:orientation="horizontal">
+
+    <ImageView
+        android:id="@android:id/icon"
+        android:layout_width="@android:dimen/app_icon_size"
+        android:layout_height="@android:dimen/app_icon_size"
+        android:layout_marginEnd="8dip"
+        android:layout_gravity="center_vertical"
+        android:scaleType="centerInside"
+        android:contentDescription="@null" />
+
+    <TextView
+        android:id="@android:id/title"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical"
+        android:maxLines="2"
+        android:ellipsize="end"
+        android:textAlignment="viewStart"
+        android:textAppearance="?android:attr/textAppearanceSmall" />
+
+</LinearLayout>
diff --git a/packages/DocumentsUI/res/layout/item_root.xml b/packages/DocumentsUI/res/layout/item_root.xml
new file mode 100644
index 0000000..98d78da
--- /dev/null
+++ b/packages/DocumentsUI/res/layout/item_root.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:minHeight="?android:attr/listPreferredItemHeightSmall"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:gravity="center_vertical"
+    android:orientation="horizontal"
+    android:background="@drawable/item_root">
+
+    <ImageView
+        android:id="@android:id/icon"
+        android:layout_width="@dimen/icon_size"
+        android:layout_height="@dimen/icon_size"
+        android:layout_marginEnd="8dip"
+        android:scaleType="centerInside"
+        android:contentDescription="@null" />
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+
+        <TextView
+            android:id="@android:id/title"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:singleLine="true"
+            android:ellipsize="marquee"
+            android:textAlignment="viewStart"
+            style="@style/TextAppearance.Medium" />
+
+        <TextView
+            android:id="@android:id/summary"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:singleLine="true"
+            android:ellipsize="marquee"
+            android:textAlignment="viewStart"
+            style="@style/TextAppearance.Small" />
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/packages/DocumentsUI/res/layout/item_root_header.xml b/packages/DocumentsUI/res/layout/item_root_header.xml
new file mode 100644
index 0000000..6b9857d
--- /dev/null
+++ b/packages/DocumentsUI/res/layout/item_root_header.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:paddingTop="12dp">
+
+    <TextView
+        android:id="@android:id/title"
+        android:textColor="?android:attr/textColorTertiary"
+        style="?android:attr/listSeparatorTextViewStyle" />
+
+</FrameLayout>
diff --git a/packages/DocumentsUI/res/layout/item_title.xml b/packages/DocumentsUI/res/layout/item_title.xml
new file mode 100644
index 0000000..7eb100a
--- /dev/null
+++ b/packages/DocumentsUI/res/layout/item_title.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:minHeight="?android:attr/listPreferredItemHeightSmall"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:gravity="center_vertical"
+    android:orientation="horizontal">
+
+    <ImageView
+        android:id="@+id/subdir"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:scaleType="centerInside"
+        android:visibility="gone"
+        android:src="@drawable/ic_subdirectory_arrow"
+        android:contentDescription="@null" />
+
+    <TextView
+        android:id="@android:id/title"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:singleLine="true"
+        android:ellipsize="marquee"
+        android:textAlignment="viewStart"
+        style="@style/TextAppearance.Medium" />
+
+</LinearLayout>
diff --git a/packages/DocumentsUI/res/menu/activity.xml b/packages/DocumentsUI/res/menu/activity.xml
new file mode 100644
index 0000000..d995376
--- /dev/null
+++ b/packages/DocumentsUI/res/menu/activity.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item
+        android:id="@+id/menu_create_dir"
+        android:title="@string/menu_create_dir"
+        android:icon="@drawable/ic_menu_new_folder"
+        android:showAsAction="always" />
+    <item
+        android:id="@+id/menu_search"
+        android:title="@string/menu_search"
+        android:icon="@drawable/ic_menu_search"
+        android:showAsAction="always|collapseActionView"
+        android:actionViewClass="android.widget.SearchView"
+        android:imeOptions="actionSearch" />
+    <item
+        android:id="@+id/menu_sort"
+        android:title="@string/menu_sort"
+        android:icon="@drawable/ic_menu_sortby"
+        android:showAsAction="always">
+        <menu>
+            <item
+                android:id="@+id/menu_sort_name"
+                android:title="@string/sort_name" />
+            <item
+                android:id="@+id/menu_sort_date"
+                android:title="@string/sort_date" />
+            <item
+                android:id="@+id/menu_sort_size"
+                android:title="@string/sort_size" />
+        </menu>
+    </item>
+    <item
+        android:id="@+id/menu_grid"
+        android:title="@string/menu_grid"
+        android:icon="@drawable/ic_menu_view_grid"
+        android:showAsAction="never" />
+    <item
+        android:id="@+id/menu_list"
+        android:title="@string/menu_list"
+        android:icon="@drawable/ic_menu_view_list"
+        android:showAsAction="never" />
+    <item
+        android:id="@+id/menu_settings"
+        android:title="@string/menu_settings"
+        android:icon="@drawable/ic_menu_settings"
+        android:showAsAction="never" />
+</menu>
diff --git a/packages/DocumentsUI/res/menu/mode_directory.xml b/packages/DocumentsUI/res/menu/mode_directory.xml
new file mode 100644
index 0000000..0a3645f
--- /dev/null
+++ b/packages/DocumentsUI/res/menu/mode_directory.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item
+        android:id="@+id/menu_open"
+        android:title="@string/menu_open"
+        android:showAsAction="always" />
+    <item
+        android:id="@+id/menu_share"
+        android:icon="@drawable/ic_menu_share"
+        android:title="@string/menu_share"
+        android:showAsAction="always" />
+    <item
+        android:id="@+id/menu_delete"
+        android:icon="@drawable/ic_menu_delete"
+        android:title="@string/menu_delete"
+        android:showAsAction="always" />
+</menu>
diff --git a/packages/DocumentsUI/res/values-af/strings.xml b/packages/DocumentsUI/res/values-af/strings.xml
new file mode 100644
index 0000000..2bac95c
--- /dev/null
+++ b/packages/DocumentsUI/res/values-af/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Dokumente"</string>
+    <string name="title_open" msgid="4353228937663917801">"Maak oop vanaf"</string>
+    <string name="title_save" msgid="2433679664882857999">"Stoor na"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Skep vouer"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Roosteraansig"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Lysaansig"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Sorteer volgens"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Soek"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Instellings"</string>
+    <string name="menu_open" msgid="432922957274920903">"Maak oop"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Stoor"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Deel"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Vee uit"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> gekies"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Volgens naam"</string>
+    <string name="sort_date" msgid="586080032956151448">"Volgens datum gewysig"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Volgens grootte"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Wys wortels"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Versteek wortels"</string>
+    <string name="save_error" msgid="6167009778003223664">"Kon nie dokument stoor nie"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Onlangs"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> gratis"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Kortpaaie"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Toestelle"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Nog programme"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Wys gevorderde toestelle"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Wys lêergrootte"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Wys toestelgrootte"</string>
+    <string name="empty" msgid="7858882803708117596">"Geen items nie"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Kan lêer nie oopmaak nie"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Kan sommige dokumente nie uitvee nie"</string>
+    <string name="share_via" msgid="8966594246261344259">"Deel via"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-am/strings.xml b/packages/DocumentsUI/res/values-am/strings.xml
new file mode 100644
index 0000000..70fab08
--- /dev/null
+++ b/packages/DocumentsUI/res/values-am/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"ሰነዶች"</string>
+    <string name="title_open" msgid="4353228937663917801">"ክፈት ከ"</string>
+    <string name="title_save" msgid="2433679664882857999">"አስቀምጥ ወደ"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"አቃፊ ፍጠር"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"የፍርግርግ እይታ"</string>
+    <string name="menu_list" msgid="7279285939892417279">"የዝርዝር እይታ"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"ደርድር በ"</string>
+    <string name="menu_search" msgid="3816712084502856974">"ፈልግ"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"ቅንብሮች"</string>
+    <string name="menu_open" msgid="432922957274920903">"ክፈት"</string>
+    <string name="menu_save" msgid="2394743337684426338">"አስቀምጥ"</string>
+    <string name="menu_share" msgid="3075149983979628146">"አጋራ"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"ሰርዝ"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> ተመርጠዋል"</string>
+    <string name="sort_name" msgid="9183560467917256779">"በስም"</string>
+    <string name="sort_date" msgid="586080032956151448">"በተለወጠበት ቀን"</string>
+    <string name="sort_size" msgid="3350681319735474741">"በመጠን"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"ስሮችን አሳይ"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"ስሮችን ደብቅ"</string>
+    <string name="save_error" msgid="6167009778003223664">"ሰነድ ማስቀመጥ አልተሳካም"</string>
+    <string name="root_recent" msgid="4470053704320518133">"የቅርብ ጊዜ"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ነፃ"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"አቋራጮች"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"መሣሪያዎች"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"ተጨማሪ መተግበሪያዎች"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"የላቁ መሳሪያዎችን አሳይ"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"የፋይል መጠን አሳይ"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"የመሳሪያ መጠን አሳይ"</string>
+    <string name="empty" msgid="7858882803708117596">"ምንም ንጥሎች የሉም"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"ፋይል መክፈት አይቻልም"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"አንዳንድ ሰነዶችን መሰረዝ አልተቻለም"</string>
+    <string name="share_via" msgid="8966594246261344259">"በሚከተለው በኩል ያጋሩ"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-ar/strings.xml b/packages/DocumentsUI/res/values-ar/strings.xml
new file mode 100644
index 0000000..20a9990
--- /dev/null
+++ b/packages/DocumentsUI/res/values-ar/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"مستندات"</string>
+    <string name="title_open" msgid="4353228937663917801">"فتح من"</string>
+    <string name="title_save" msgid="2433679664882857999">"حفظ في"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"إنشاء مجلد"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"عرض الشبكة"</string>
+    <string name="menu_list" msgid="7279285939892417279">"عرض القائمة"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"ترتيب بحسب"</string>
+    <string name="menu_search" msgid="3816712084502856974">"بحث"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"الإعدادات"</string>
+    <string name="menu_open" msgid="432922957274920903">"فتح"</string>
+    <string name="menu_save" msgid="2394743337684426338">"حفظ"</string>
+    <string name="menu_share" msgid="3075149983979628146">"مشاركة"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"حذف"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"تم تحديد <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+    <string name="sort_name" msgid="9183560467917256779">"بحسب الاسم"</string>
+    <string name="sort_date" msgid="586080032956151448">"بحسب تاريخ التعديل"</string>
+    <string name="sort_size" msgid="3350681319735474741">"بحسب الحجم"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"عرض الجذور"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"إخفاء الجذور"</string>
+    <string name="save_error" msgid="6167009778003223664">"أخفق حفظ المستند"</string>
+    <string name="root_recent" msgid="4470053704320518133">"الأخيرة"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> خالية"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"اختصارات"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"أجهزة"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"المزيد من التطبيقات"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"عرض الأجهزة المتقدمة"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"عرض حجم الملف"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"عرض حجم الجهاز"</string>
+    <string name="empty" msgid="7858882803708117596">"ليس هناك أي عناصر"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"لا يمكن فتح الملف"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"تعذر حذف بعض المستندات"</string>
+    <string name="share_via" msgid="8966594246261344259">"مشاركة عبر"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-az-rAZ/strings.xml b/packages/DocumentsUI/res/values-az-rAZ/strings.xml
new file mode 100644
index 0000000..1374982
--- /dev/null
+++ b/packages/DocumentsUI/res/values-az-rAZ/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Sənədlər"</string>
+    <string name="title_open" msgid="4353228937663917801">"Vasitəsilə açın"</string>
+    <string name="title_save" msgid="2433679664882857999">"buraya saxlayın"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Qovluq yaradın"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Torlu görünüş"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Siyahı görünüşü"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Bunlardan biri üzrə sırala"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Axtarış"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Ayarlar"</string>
+    <string name="menu_open" msgid="432922957274920903">"Açın"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Yadda saxlayın"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Paylaşın"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Sil"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> seçilmiş"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Ad üzrə"</string>
+    <string name="sort_date" msgid="586080032956151448">"Tarix üzrə dəyişmiş"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Ölçü üzrə"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Kökləri göstərin"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Kökləri gizlədin"</string>
+    <string name="save_error" msgid="6167009778003223664">"Sənədi yadda saxlaya bilmədi"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Son"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ödənişsiz"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Qısa yollar"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Cihazlar"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Daha çox tətbiq"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Qabaqcıl cihazları görüntüləyin"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Fayl ölçüsünü görüntüləyin"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Cihaz ölçüsünü görüntüləyin"</string>
+    <string name="empty" msgid="7858882803708117596">"Element yoxdur"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Faylı aça bilmir"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Bəzi sənədləri silə bilmir"</string>
+    <string name="share_via" msgid="8966594246261344259">"Bunun vasitəsilə paylaş:"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-az/strings.xml b/packages/DocumentsUI/res/values-az/strings.xml
new file mode 100644
index 0000000..806118b
--- /dev/null
+++ b/packages/DocumentsUI/res/values-az/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Sənədlər"</string>
+    <string name="title_open" msgid="4353228937663917801">"Vasitəsilə açın"</string>
+    <string name="title_save" msgid="2433679664882857999">"buraya saxlayın"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Qovluq yaradın"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Torlu görünüş"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Siyahı görünüşü"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Bunlardan biri üzrə sırala"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Axtarış"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Ayarlar"</string>
+    <string name="menu_open" msgid="432922957274920903">"Açın"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Yadda saxlayın"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Paylaşın"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Sil"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> seçilmiş"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Ad üzrə"</string>
+    <string name="sort_date" msgid="586080032956151448">"Tarix üzrə dəyişmiş"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Ölçü üzrə"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Kökləri göstərin"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Kökləri gizlədin"</string>
+    <string name="save_error" msgid="6167009778003223664">"Sənədi yadda saxlaya bilmədi"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Son"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ödənişsiz"</string>
+    <string name="root_type_service" msgid="2857362700576006694">"Xidmətlər"</string>
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Qısa yollar"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Cihazlar"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Daha çox tətbiq"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Qabaqcıl cihazları görüntüləyin"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Fayl ölçüsünü görüntüləyin"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Cihaz ölçüsünü görüntüləyin"</string>
+    <string name="empty" msgid="7858882803708117596">"Element yoxdur"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Faylı aça bilmir"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Bəzi sənədləri silə bilmir"</string>
+    <string name="more" msgid="7117420986529297171">"Daha çox"</string>
+    <string name="loading" msgid="7933681260296021180">"Yüklənir…"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-bg/strings.xml b/packages/DocumentsUI/res/values-bg/strings.xml
new file mode 100644
index 0000000..11bc3ed
--- /dev/null
+++ b/packages/DocumentsUI/res/values-bg/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Документи"</string>
+    <string name="title_open" msgid="4353228937663917801">"Отваряне от"</string>
+    <string name="title_save" msgid="2433679664882857999">"Запазване в/ъв"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Създаване на папка"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Изглед в мрежа"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Списъчен изглед"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Сортиране по"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Търсене"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Настройки"</string>
+    <string name="menu_open" msgid="432922957274920903">"Отваряне"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Запазване"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Споделяне"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Изтриване"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"Избрахте <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+    <string name="sort_name" msgid="9183560467917256779">"По име"</string>
+    <string name="sort_date" msgid="586080032956151448">"По дата на промяната"</string>
+    <string name="sort_size" msgid="3350681319735474741">"По размер"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Показване на основните елементи"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Скриване на основните елементи"</string>
+    <string name="save_error" msgid="6167009778003223664">"Запазването на документа не бе успешно"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Скорошно"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"Свободно: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Преки пътища"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Устройства"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Още приложения"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Показване на устройствата с разширени функции"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Показване на файловия размер"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Показване на размера на устройството"</string>
+    <string name="empty" msgid="7858882803708117596">"Няма елементи"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Файлът не може да се отвори"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Някои документи не могат да бъдат изтрити"</string>
+    <string name="share_via" msgid="8966594246261344259">"Споделяне чрез"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-ca/strings.xml b/packages/DocumentsUI/res/values-ca/strings.xml
new file mode 100644
index 0000000..d8f0c07
--- /dev/null
+++ b/packages/DocumentsUI/res/values-ca/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Documents"</string>
+    <string name="title_open" msgid="4353228937663917801">"Obre des de"</string>
+    <string name="title_save" msgid="2433679664882857999">"Desa a"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Crea una carpeta"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Visualització de quadrícula"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Visualització de llista"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Ordena per"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Cerca"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Configuració"</string>
+    <string name="menu_open" msgid="432922957274920903">"Obre"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Desa"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Comparteix"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Suprimeix"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"Seleccionats: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Per nom"</string>
+    <string name="sort_date" msgid="586080032956151448">"Per data de modificació"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Per mida"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Mostra les arrels"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Amaga les arrels"</string>
+    <string name="save_error" msgid="6167009778003223664">"No s\'ha pogut desar el document."</string>
+    <string name="root_recent" msgid="4470053704320518133">"Recent"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> lliures"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Dreceres"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Dispositius"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Més aplicacions"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Mostra els dispositius avançats"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Mostra la mida del fitxer"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Mostra la mida del dispositiu"</string>
+    <string name="empty" msgid="7858882803708117596">"Sense elements"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"No es pot obrir el fitxer."</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"No es poden suprimir alguns documents."</string>
+    <string name="share_via" msgid="8966594246261344259">"Comparteix mitjançant"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-cs/strings.xml b/packages/DocumentsUI/res/values-cs/strings.xml
new file mode 100644
index 0000000..5d736de
--- /dev/null
+++ b/packages/DocumentsUI/res/values-cs/strings.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Dokumenty"</string>
+    <string name="title_open" msgid="4353228937663917801">"Otevřít z"</string>
+    <string name="title_save" msgid="2433679664882857999">"Uložit do"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Vytvořit složku"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Mřížka"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Seznam"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Řadit podle"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Hledat"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Nastavení"</string>
+    <string name="menu_open" msgid="432922957274920903">"Otevřít"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Uložit"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Sdílet"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Smazat"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"Vybráno: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Podle názvu"</string>
+    <string name="sort_date" msgid="586080032956151448">"Podle data úpravy"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Podle velikosti"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Zobrazit kořeny"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Skrýt kořeny"</string>
+    <string name="save_error" msgid="6167009778003223664">"Uložení dokumentu se nezdařilo"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Poslední"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"Volný prostor: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <string name="root_type_service" msgid="2178854894416775409">"Služby úložiště"</string>
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Klávesové zkratky"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Zařízení"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Další aplikace"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Zobrazit pokročilá zařízení"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Zobrazit velikost souboru"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Zobrazit velikost zařízení"</string>
+    <string name="empty" msgid="7858882803708117596">"Žádné položky"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Soubor nelze otevřít"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Některé dokumenty nelze smazat"</string>
+    <string name="share_via" msgid="8966594246261344259">"Sdílet pomocí"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-da/strings.xml b/packages/DocumentsUI/res/values-da/strings.xml
new file mode 100644
index 0000000..0b1026a
--- /dev/null
+++ b/packages/DocumentsUI/res/values-da/strings.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Dokumenter"</string>
+    <string name="title_open" msgid="4353228937663917801">"Åbn fra"</string>
+    <string name="title_save" msgid="2433679664882857999">"Gem på"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Opret mappe"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Gittervisning"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Listevisning"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Sortér efter"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Søg"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Indstillinger"</string>
+    <string name="menu_open" msgid="432922957274920903">"Åbn"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Gem"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Del"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Slet"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> er valgt"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Efter navn"</string>
+    <string name="sort_date" msgid="586080032956151448">"Efter ændringsdato"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Efter størrelse"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Vis rødder"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Skjul rødder"</string>
+    <string name="save_error" msgid="6167009778003223664">"Dokumentet kunne ikke gemmes"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Seneste"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ledig plads"</string>
+    <string name="root_type_service" msgid="2178854894416775409">"Lagringstjenester"</string>
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Genveje"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Enheder"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Flere apps"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Vis avancerede enheder"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Vis filstørrelse"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Vis enhedens størrelse"</string>
+    <string name="empty" msgid="7858882803708117596">"Ingen elementer"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Filen kan ikke åbnes"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Nogle dokumenter kan ikke slettes"</string>
+    <string name="share_via" msgid="8966594246261344259">"Del via"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-de/strings.xml b/packages/DocumentsUI/res/values-de/strings.xml
new file mode 100644
index 0000000..9c23c7e
--- /dev/null
+++ b/packages/DocumentsUI/res/values-de/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Dokumente"</string>
+    <string name="title_open" msgid="4353228937663917801">"Öffnen von"</string>
+    <string name="title_save" msgid="2433679664882857999">"Speichern unter"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Ordner erstellen"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Rasteransicht"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Listenansicht"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Sortieren nach"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Suchen"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Einstellungen"</string>
+    <string name="menu_open" msgid="432922957274920903">"Öffnen"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Speichern"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Teilen"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Löschen"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> ausgewählt"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Nach Name"</string>
+    <string name="sort_date" msgid="586080032956151448">"Nach Änderungsdatum"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Nach Größe"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Root-Verzeichnis anzeigen"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Root-Verzeichnis ausblenden"</string>
+    <string name="save_error" msgid="6167009778003223664">"Dokument konnte nicht gespeichert werden."</string>
+    <string name="root_recent" msgid="4470053704320518133">"Letzte"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> verfügbar"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Verknüpfungen"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Geräte"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Weitere Apps"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Erweiterte Geräte anzeigen"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Dateigröße anzeigen"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Geräteabmessungen anzeigen"</string>
+    <string name="empty" msgid="7858882803708117596">"Keine Elemente"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Datei kann nicht geöffnet werden."</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Einige Dokumente konnten nicht gelöscht werden."</string>
+    <string name="share_via" msgid="8966594246261344259">"Teilen über"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-el/strings.xml b/packages/DocumentsUI/res/values-el/strings.xml
new file mode 100644
index 0000000..35eabfb
--- /dev/null
+++ b/packages/DocumentsUI/res/values-el/strings.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Έγγραφα"</string>
+    <string name="title_open" msgid="4353228937663917801">"Άνοιγμα από"</string>
+    <string name="title_save" msgid="2433679664882857999">"Αποθήκευση σε"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Δημιουργία φακέλου"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Προβολή πλέγματος"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Προβολή λίστας"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Ταξινόμηση κατά"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Αναζήτηση"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Ρυθμίσεις"</string>
+    <string name="menu_open" msgid="432922957274920903">"Άνοιγμα"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Αποθήκευση"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Κοινή χρήση"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Διαγραφή"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"Επιλέχθηκαν <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Κατά όνομα"</string>
+    <string name="sort_date" msgid="586080032956151448">"Κατά ημερομηνία τροποποίησης"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Κατά μέγεθος"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Εμφάνιση ρίζας"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Απόκρυψη ρίζας"</string>
+    <string name="save_error" msgid="6167009778003223664">"Αποτυχία αποθήκευσης του εγγράφου"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Πρόσφατα"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ελεύθερα"</string>
+    <string name="root_type_service" msgid="2178854894416775409">"Υπηρεσίες αποθήκευσης"</string>
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Συντομεύσεις"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Συσκευές"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Περισσότερες εφαρμογές"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Εμφάνιση προηγμένων συσκευών"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Εμφάνιση μεγέθους αρχείου"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Εμφάνιση μεγέθους συσκευής"</string>
+    <string name="empty" msgid="7858882803708117596">"Δεν υπάρχουν στοιχεία"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Δεν είναι δυνατό το άνοιγμα του αρχείου"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Δεν είναι δυνατή η διαγραφή ορισμένων εγγράφων"</string>
+    <string name="share_via" msgid="8966594246261344259">"Κοινή χρήση μέσω"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-en-rGB/strings.xml b/packages/DocumentsUI/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..15be21d
--- /dev/null
+++ b/packages/DocumentsUI/res/values-en-rGB/strings.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Documents"</string>
+    <string name="title_open" msgid="4353228937663917801">"Open from"</string>
+    <string name="title_save" msgid="2433679664882857999">"Save to"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Create folder"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Grid view"</string>
+    <string name="menu_list" msgid="7279285939892417279">"List view"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Sort by"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Search"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Settings"</string>
+    <string name="menu_open" msgid="432922957274920903">"Open"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Save"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Share"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Delete"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> selected"</string>
+    <string name="sort_name" msgid="9183560467917256779">"By name"</string>
+    <string name="sort_date" msgid="586080032956151448">"By date modified"</string>
+    <string name="sort_size" msgid="3350681319735474741">"By size"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Show roots"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Hide roots"</string>
+    <string name="save_error" msgid="6167009778003223664">"Failed to save document"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Recent"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> free"</string>
+    <string name="root_type_service" msgid="2178854894416775409">"Storage services"</string>
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Shortcuts"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Devices"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"More apps"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Display advanced devices"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Display file size"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Display device size"</string>
+    <string name="empty" msgid="7858882803708117596">"No items"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Cannot open file"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Unable to delete some documents"</string>
+    <string name="share_via" msgid="8966594246261344259">"Share via"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-en-rIN/strings.xml b/packages/DocumentsUI/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..15be21d
--- /dev/null
+++ b/packages/DocumentsUI/res/values-en-rIN/strings.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Documents"</string>
+    <string name="title_open" msgid="4353228937663917801">"Open from"</string>
+    <string name="title_save" msgid="2433679664882857999">"Save to"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Create folder"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Grid view"</string>
+    <string name="menu_list" msgid="7279285939892417279">"List view"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Sort by"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Search"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Settings"</string>
+    <string name="menu_open" msgid="432922957274920903">"Open"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Save"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Share"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Delete"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> selected"</string>
+    <string name="sort_name" msgid="9183560467917256779">"By name"</string>
+    <string name="sort_date" msgid="586080032956151448">"By date modified"</string>
+    <string name="sort_size" msgid="3350681319735474741">"By size"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Show roots"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Hide roots"</string>
+    <string name="save_error" msgid="6167009778003223664">"Failed to save document"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Recent"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> free"</string>
+    <string name="root_type_service" msgid="2178854894416775409">"Storage services"</string>
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Shortcuts"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Devices"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"More apps"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Display advanced devices"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Display file size"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Display device size"</string>
+    <string name="empty" msgid="7858882803708117596">"No items"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Cannot open file"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Unable to delete some documents"</string>
+    <string name="share_via" msgid="8966594246261344259">"Share via"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-es-rUS/strings.xml b/packages/DocumentsUI/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..3b4b870
--- /dev/null
+++ b/packages/DocumentsUI/res/values-es-rUS/strings.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Documentos"</string>
+    <string name="title_open" msgid="4353228937663917801">"Abrir desde"</string>
+    <string name="title_save" msgid="2433679664882857999">"Guardar en"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Crear carpeta"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Vista de cuadrícula"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Vista de lista"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Ordenar por"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Buscar"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Configuración"</string>
+    <string name="menu_open" msgid="432922957274920903">"Abrir"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Guardar"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Compartir"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Eliminar"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> seleccionado(s)"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Por nombre"</string>
+    <string name="sort_date" msgid="586080032956151448">"Por fecha de modificación"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Por tamaño"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Mostrar raíces"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Ocultar raíces"</string>
+    <string name="save_error" msgid="6167009778003223664">"Error al guardar el documento"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Recientes"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> de espacio libre"</string>
+    <string name="root_type_service" msgid="2178854894416775409">"Almacenamiento"</string>
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Accesos directos"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Dispositivos"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Más aplicaciones"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Mostrar dispositivos avanzados"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Mostrar tamaño del archivo"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Mostrar tamaño del dispositivo"</string>
+    <string name="empty" msgid="7858882803708117596">"Sin elementos"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"No se puede abrir el archivo."</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"No es posible eliminar algunos documentos."</string>
+    <string name="share_via" msgid="8966594246261344259">"Compartir mediante"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-es/strings.xml b/packages/DocumentsUI/res/values-es/strings.xml
new file mode 100644
index 0000000..3fe73f9
--- /dev/null
+++ b/packages/DocumentsUI/res/values-es/strings.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Documentos"</string>
+    <string name="title_open" msgid="4353228937663917801">"Abrir desde"</string>
+    <string name="title_save" msgid="2433679664882857999">"Guardar en"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Crear carpeta"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Vista de cuadrícula"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Vista de lista"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Ordenar por"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Buscar"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Ajustes"</string>
+    <string name="menu_open" msgid="432922957274920903">"Abrir"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Guardar"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Compartir"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Eliminar"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"Seleccionado: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Por nombre"</string>
+    <string name="sort_date" msgid="586080032956151448">"Por fecha de modificación"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Por tamaño"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Mostrar raíces"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Ocultar raíces"</string>
+    <string name="save_error" msgid="6167009778003223664">"Error al guardar documento"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Reciente"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> de espacio libre"</string>
+    <string name="root_type_service" msgid="2178854894416775409">"Servicios almacenamiento"</string>
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Accesos directos"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Dispositivos"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Más aplicaciones"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Mostrar dispositivos avanzados"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Mostrar tamaño del archivo"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Mostrar tamaño del dispositivo"</string>
+    <string name="empty" msgid="7858882803708117596">"Sin elementos"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Error al abrir el archivo"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"No es posible eliminar algunos documentos"</string>
+    <string name="share_via" msgid="8966594246261344259">"Compartir a través de"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-et-rEE/strings.xml b/packages/DocumentsUI/res/values-et-rEE/strings.xml
new file mode 100644
index 0000000..2544b2d
--- /dev/null
+++ b/packages/DocumentsUI/res/values-et-rEE/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Dokumendid"</string>
+    <string name="title_open" msgid="4353228937663917801">"Ava:"</string>
+    <string name="title_save" msgid="2433679664882857999">"Salvesta:"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Loo kaust"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Ruudustikkuva"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Loendikuva"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Sortimisalus:"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Otsing"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Seaded"</string>
+    <string name="menu_open" msgid="432922957274920903">"Ava"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Salvesta"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Jaga"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Kustuta"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> on valitud"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Nime järgi"</string>
+    <string name="sort_date" msgid="586080032956151448">"Muutmiskuupäeva järgi"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Suuruse järgi"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Kuva juured"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Peida juured"</string>
+    <string name="save_error" msgid="6167009778003223664">"Dokumendi salvestamine ebaõnnestus"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Hiljutised"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> on vaba"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Otseteed"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Seadmed"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Rohkem rakendusi"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Kuva tippseadmed"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Kuva faili suurus"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Kuva seadme suurus"</string>
+    <string name="empty" msgid="7858882803708117596">"Üksusi ei ole"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Faili ei saa avada"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Mõnda dokumenti ei õnnestu kustutada"</string>
+    <string name="share_via" msgid="8966594246261344259">"Jagage teenusega"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-fa/strings.xml b/packages/DocumentsUI/res/values-fa/strings.xml
new file mode 100644
index 0000000..29b9ccf
--- /dev/null
+++ b/packages/DocumentsUI/res/values-fa/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"اسناد"</string>
+    <string name="title_open" msgid="4353228937663917801">"باز کردن از"</string>
+    <string name="title_save" msgid="2433679664882857999">"ذخیره در"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"ایجاد پوشه"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"نمای جدولی"</string>
+    <string name="menu_list" msgid="7279285939892417279">"نمای فهرست‌وار"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"مرتب‌سازی بر اساس"</string>
+    <string name="menu_search" msgid="3816712084502856974">"جستجو"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"تنظیمات"</string>
+    <string name="menu_open" msgid="432922957274920903">"باز کردن"</string>
+    <string name="menu_save" msgid="2394743337684426338">"ذخیره"</string>
+    <string name="menu_share" msgid="3075149983979628146">"اشتراک‌گذاری"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"حذف"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> انتخاب شد"</string>
+    <string name="sort_name" msgid="9183560467917256779">"بر اساس نام"</string>
+    <string name="sort_date" msgid="586080032956151448">"بر اساس تاریخ اصلاح"</string>
+    <string name="sort_size" msgid="3350681319735474741">"بر اساس اندازه"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"نمایش ریشه‌ها"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"پنهان کردن ریشه‌ها"</string>
+    <string name="save_error" msgid="6167009778003223664">"ذخیره سند انجام نشد"</string>
+    <string name="root_recent" msgid="4470053704320518133">"اخیر"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> آزاد"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"میانبرها"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"دستگاه‌ها"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"برنامه‌های بیشتر"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"نمایش دستگاه‌های پیشرفته"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"نمایش اندازه فایل"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"نمایش اندازه صفحه نمایش"</string>
+    <string name="empty" msgid="7858882803708117596">"موردی موجود نیست"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"فایل باز نمی‌شود"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"برخی از اسناد حذف نمی‌شوند"</string>
+    <string name="share_via" msgid="8966594246261344259">"اشتراک‌گذاری از طریق"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-fi/strings.xml b/packages/DocumentsUI/res/values-fi/strings.xml
new file mode 100644
index 0000000..b51a506
--- /dev/null
+++ b/packages/DocumentsUI/res/values-fi/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Asiakirjat"</string>
+    <string name="title_open" msgid="4353228937663917801">"Avoinna alkaen"</string>
+    <string name="title_save" msgid="2433679664882857999">"Tallenna kohteeseen"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Luo kansio"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Ruudukkonäkymä"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Luettelonäkymä"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Lajitteluperuste"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Haku"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Asetukset"</string>
+    <string name="menu_open" msgid="432922957274920903">"Avaa"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Tallenna"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Jaa"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Poista"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> valittua"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Nimen mukaan"</string>
+    <string name="sort_date" msgid="586080032956151448">"Muokkauspäivän mukaan"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Koon mukaan"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Näytä juuret"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Piilota juuret"</string>
+    <string name="save_error" msgid="6167009778003223664">"Asiakirjan tallennus epäonnistui"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Viimeisimmät"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> vapaana"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Pikakuvakkeet"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Laitteet"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Lisää sovelluksia"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Näytä kehittyneet laitteet"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Näytä tiedoston koko"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Näytä laitteen koko"</string>
+    <string name="empty" msgid="7858882803708117596">"Ei kohteita"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Tiedostoa ei voi avata"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Joitakin asiakirjoja ei voi poistaa"</string>
+    <string name="share_via" msgid="8966594246261344259">"Jaa sovelluksessa"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-fr-rCA/strings.xml b/packages/DocumentsUI/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..3364866
--- /dev/null
+++ b/packages/DocumentsUI/res/values-fr-rCA/strings.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Documents"</string>
+    <string name="title_open" msgid="4353228937663917801">"Ouvert à partir de"</string>
+    <string name="title_save" msgid="2433679664882857999">"Enregistrer dans"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Créer un dossier"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Grille"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Liste"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Trier par"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Rechercher"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Paramètres"</string>
+    <string name="menu_open" msgid="432922957274920903">"Ouvrir"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Enregistrer"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Partager"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Supprimer"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> sélectionné(s)"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Par nom"</string>
+    <string name="sort_date" msgid="586080032956151448">"Par date de modification"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Par taille"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Afficher les racines"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Masquer les racines"</string>
+    <string name="save_error" msgid="6167009778003223664">"Échec de l\'enregistrement du document"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Récents"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> disponible"</string>
+    <string name="root_type_service" msgid="2178854894416775409">"Services de stockage"</string>
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Raccourcis"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Appareils"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Plus d\'applications"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Afficher les appareils avancés"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Afficher la taille du fichier"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Taille de l\'écran de l\'appareil"</string>
+    <string name="empty" msgid="7858882803708117596">"Aucun élément"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Impossible d\'ouvrir le fichier"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Impossible de supprimer certains documents"</string>
+    <string name="share_via" msgid="8966594246261344259">"Partager par"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-fr/strings.xml b/packages/DocumentsUI/res/values-fr/strings.xml
new file mode 100644
index 0000000..be7b9a6
--- /dev/null
+++ b/packages/DocumentsUI/res/values-fr/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Documents"</string>
+    <string name="title_open" msgid="4353228937663917801">"Ouvrir sous"</string>
+    <string name="title_save" msgid="2433679664882857999">"Enregistrer sous"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Créer un dossier"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Grille"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Liste"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Trier par"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Rechercher"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Paramètres"</string>
+    <string name="menu_open" msgid="432922957274920903">"Ouvrir"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Enregistrer"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Partager"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Supprimer"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> élément(s) sélectionné(s)"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Par nom"</string>
+    <string name="sort_date" msgid="586080032956151448">"Par date de modification"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Par taille"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Afficher les répertoires racines"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Masquer les répertoires racines"</string>
+    <string name="save_error" msgid="6167009778003223664">"Échec de l\'enregistrement du document."</string>
+    <string name="root_recent" msgid="4470053704320518133">"Récents"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"Espace disponible : <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Raccourcis"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Appareils"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Autres applications"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Afficher les appareils avancés"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Afficher la taille des fichiers"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Afficher la capacité de stockage des appareils"</string>
+    <string name="empty" msgid="7858882803708117596">"Aucun élément"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Impossible d\'ouvrir le fichier."</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Impossible de supprimer certains documents."</string>
+    <string name="share_via" msgid="8966594246261344259">"Partager via"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-hi/strings.xml b/packages/DocumentsUI/res/values-hi/strings.xml
new file mode 100644
index 0000000..08b3135
--- /dev/null
+++ b/packages/DocumentsUI/res/values-hi/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"दस्तावेज़"</string>
+    <string name="title_open" msgid="4353228937663917801">"यहां से खोलें"</string>
+    <string name="title_save" msgid="2433679664882857999">"यहां सहेजें"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"फ़ोल्डर बनाएं"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"ग्रिड दृश्य"</string>
+    <string name="menu_list" msgid="7279285939892417279">"सूची दृश्य"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"इससे क्रमित करें"</string>
+    <string name="menu_search" msgid="3816712084502856974">"खोजें"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"सेटिंग"</string>
+    <string name="menu_open" msgid="432922957274920903">"खोलें"</string>
+    <string name="menu_save" msgid="2394743337684426338">"सहेजें"</string>
+    <string name="menu_share" msgid="3075149983979628146">"साझा करें"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"हटाएं"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> चयनित"</string>
+    <string name="sort_name" msgid="9183560467917256779">"नाम के अनुसार"</string>
+    <string name="sort_date" msgid="586080032956151448">"बदलाव के दिनांक के अनुसार"</string>
+    <string name="sort_size" msgid="3350681319735474741">"आकार के अनुसार"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"रूट दिखाएं"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"रूट छिपाएं"</string>
+    <string name="save_error" msgid="6167009778003223664">"दस्तावेज़ सहेजने में विफल रहा"</string>
+    <string name="root_recent" msgid="4470053704320518133">"हाल ही के"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> रिक्त"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"शॉर्टकट"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"उपकरण"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"अधिक एप्स"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"उन्नत उपकरणों को दिखाएं"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"फ़ाइल का आकार दिखाएं"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"उपकरण का आकार दिखाएं"</string>
+    <string name="empty" msgid="7858882803708117596">"कोई आइटम नहीं"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"फ़ाइल नहीं खोली जा सकती"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"कुछ दस्तावेज़ों को हटाने में अक्षम"</string>
+    <string name="share_via" msgid="8966594246261344259">"इसके द्वारा साझा करें"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-hr/strings.xml b/packages/DocumentsUI/res/values-hr/strings.xml
new file mode 100644
index 0000000..e2722ac
--- /dev/null
+++ b/packages/DocumentsUI/res/values-hr/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Dokumenti"</string>
+    <string name="title_open" msgid="4353228937663917801">"Otvori iz"</string>
+    <string name="title_save" msgid="2433679664882857999">"Spremi u"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Izradi mapu"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Prikaz rešetke"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Prikaz popisa"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Poredano po"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Pretraživanje"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Postavke"</string>
+    <string name="menu_open" msgid="432922957274920903">"Otvaranje"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Spremi"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Dijeli"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Izbriši"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"Odabrano: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Po korisniku"</string>
+    <string name="sort_date" msgid="586080032956151448">"Po datumu izmjene"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Po veličini"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Prikaži korijene"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Sakrij korijene"</string>
+    <string name="save_error" msgid="6167009778003223664">"Nije uspjelo spremanje dokumenta"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Nedavno"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> besplatno"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Prečaci"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Uređaji"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Više aplikacija"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Prikaži napredne uređaje"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Prikaži veličinu datoteke"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Prikaži veličinu uređaja"</string>
+    <string name="empty" msgid="7858882803708117596">"Nema stavki"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Datoteku nije moguće otvoriti"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Nije moguće izbrisati neke dokumente"</string>
+    <string name="share_via" msgid="8966594246261344259">"Dijeli putem"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-hu/strings.xml b/packages/DocumentsUI/res/values-hu/strings.xml
new file mode 100644
index 0000000..f1f450a
--- /dev/null
+++ b/packages/DocumentsUI/res/values-hu/strings.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Dokumentumok"</string>
+    <string name="title_open" msgid="4353228937663917801">"Megnyitás innen"</string>
+    <string name="title_save" msgid="2433679664882857999">"Mentés ide"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Mappa létrehozása"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Rács"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Lista"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Rendezés"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Keresés"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Beállítások"</string>
+    <string name="menu_open" msgid="432922957274920903">"Megnyitás"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Mentés"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Megosztás"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Törlés"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> kiválasztva"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Név szerint"</string>
+    <string name="sort_date" msgid="586080032956151448">"Módosítás dátuma szerint"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Méret szerint"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Gyökérszint megjelenítése"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Gyökérszint elrejtése"</string>
+    <string name="save_error" msgid="6167009778003223664">"Nem sikerült menteni a dokumentumot"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Legutóbbiak"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> szabad"</string>
+    <string name="root_type_service" msgid="2178854894416775409">"Tárhelyszolgáltatások"</string>
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Parancsikonok"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Eszközök"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"További alkalmazások"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Speciális eszközök megjelenítése"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Fájlméret megjelenítése"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Eszközméret megjelenítése"</string>
+    <string name="empty" msgid="7858882803708117596">"Nincsenek elemek"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"A fájlt nem lehet megnyitni"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Néhány dokumentumot nem lehet törölni"</string>
+    <string name="share_via" msgid="8966594246261344259">"Megosztás itt:"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-hy-rAM/strings.xml b/packages/DocumentsUI/res/values-hy-rAM/strings.xml
new file mode 100644
index 0000000..a2698b5
--- /dev/null
+++ b/packages/DocumentsUI/res/values-hy-rAM/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Փաստաթղթեր"</string>
+    <string name="title_open" msgid="4353228937663917801">"Բացել այստեղից"</string>
+    <string name="title_save" msgid="2433679664882857999">"Պահել այստեղ"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Ստեղծել թղթապանակ"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Ցանցային տեսք"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Ցուցակի տեսք"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Դասավորել ըստ"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Որոնել"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Կարգավորումներ"</string>
+    <string name="menu_open" msgid="432922957274920903">"Բացել"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Պահել"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Համօգտագործել"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Ջնջել"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> ընտրված"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Ըստ անվան"</string>
+    <string name="sort_date" msgid="586080032956151448">"Ըստ փոփոխման ամսաթվի"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Ըստ չափի"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Ցույց տալ արմատները"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Թաքցնել արմատները"</string>
+    <string name="save_error" msgid="6167009778003223664">"Չհաջողվեց պահել փաստաթուղթը"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Վերջին"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ազատ է"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Դյուրանցումներ"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Սարքեր"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Հավելյալ ծրագրեր"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Ցուցադրել ընդլայնված սարքերը"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Ցուցադրել ֆայլի չափը"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Ցուցադրել սարքի չափը"</string>
+    <string name="empty" msgid="7858882803708117596">"Տարրեր չկան"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Հնարավոր չէ բացել ֆայլը"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Անհնար է ջնջել որոշ փաստաթղթեր"</string>
+    <string name="share_via" msgid="8966594246261344259">"Տարածել"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-in/strings.xml b/packages/DocumentsUI/res/values-in/strings.xml
new file mode 100644
index 0000000..83f6b02
--- /dev/null
+++ b/packages/DocumentsUI/res/values-in/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Dokumen"</string>
+    <string name="title_open" msgid="4353228937663917801">"Buka dari"</string>
+    <string name="title_save" msgid="2433679664882857999">"Simpan ke"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Buat folder"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Tampilan kisi"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Tampilan daftar"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Sortir menurut"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Telusuri"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Setelan"</string>
+    <string name="menu_open" msgid="432922957274920903">"Buka"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Simpan"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Bagikan"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Hapus"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> dipilih"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Menurut nama"</string>
+    <string name="sort_date" msgid="586080032956151448">"Menurut tanggal diubah"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Menurut ukuran"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Tampilkan akar"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Sembunyikan akar"</string>
+    <string name="save_error" msgid="6167009778003223664">"Gagal menyimpan dokumen"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Terkini"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> bebas"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Pintasan"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Perangkat"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Aplikasi lain"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Tampilkan perangkat lanjutan"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Tampilkan ukuran file"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Tampilkan ukuran perangkat"</string>
+    <string name="empty" msgid="7858882803708117596">"Tidak ada item"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Tidak dapat membuka file"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Tidak dapat menghapus beberapa dokumen"</string>
+    <string name="share_via" msgid="8966594246261344259">"Bagikan melalui"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-it/strings.xml b/packages/DocumentsUI/res/values-it/strings.xml
new file mode 100644
index 0000000..bb1a1d0
--- /dev/null
+++ b/packages/DocumentsUI/res/values-it/strings.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Documenti"</string>
+    <string name="title_open" msgid="4353228937663917801">"Apri da"</string>
+    <string name="title_save" msgid="2433679664882857999">"Salva in"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Crea cartella"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Visualizzazione griglia"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Visualizzazione elenco"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Ordina per"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Cerca"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Impostazioni"</string>
+    <string name="menu_open" msgid="432922957274920903">"Apri"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Salva"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Condividi"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Elimina"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> selezionati"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Per nome"</string>
+    <string name="sort_date" msgid="586080032956151448">"Per data di modifica"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Per dimensioni"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Mostra nodi principali"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Nascondi nodi principali"</string>
+    <string name="save_error" msgid="6167009778003223664">"Impossibile salvare il documento"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Recente"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> liberi"</string>
+    <string name="root_type_service" msgid="2178854894416775409">"Servizi di archiviazione"</string>
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Scorciatoie"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Dispositivi"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Altre app"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Visualizza dispositivi avanzati"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Visualizza dimensioni file"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Visualizza dimensioni dispositivi"</string>
+    <string name="empty" msgid="7858882803708117596">"Nessun articolo"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Impossibile aprire il file"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Impossibile eliminare alcuni documenti"</string>
+    <string name="share_via" msgid="8966594246261344259">"Condividi via"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-iw/strings.xml b/packages/DocumentsUI/res/values-iw/strings.xml
new file mode 100644
index 0000000..8323b1d
--- /dev/null
+++ b/packages/DocumentsUI/res/values-iw/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"מסמכים"</string>
+    <string name="title_open" msgid="4353228937663917801">"פתח מ-"</string>
+    <string name="title_save" msgid="2433679664882857999">"שמור ב-"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"צור תיקיה"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"תצוגת רשת"</string>
+    <string name="menu_list" msgid="7279285939892417279">"תצוגת רשימה"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"מיין לפי"</string>
+    <string name="menu_search" msgid="3816712084502856974">"חפש"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"הגדרות"</string>
+    <string name="menu_open" msgid="432922957274920903">"פתח"</string>
+    <string name="menu_save" msgid="2394743337684426338">"שמור"</string>
+    <string name="menu_share" msgid="3075149983979628146">"שתף"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"מחק"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> נבחרו"</string>
+    <string name="sort_name" msgid="9183560467917256779">"לפי שם"</string>
+    <string name="sort_date" msgid="586080032956151448">"לפי תאריך שינוי"</string>
+    <string name="sort_size" msgid="3350681319735474741">"לפי גודל"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"הצג שורשים"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"הסתר שורשים"</string>
+    <string name="save_error" msgid="6167009778003223664">"שמירת המסמך נכשלה"</string>
+    <string name="root_recent" msgid="4470053704320518133">"מהזמן האחרון"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> של שטח פנוי"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"קיצורי דרך"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"מכשירים"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"עוד אפליקציות"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"הצג מכשירים מתקדמים"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"הצג את גודל הקובץ"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"הצג את גודל המכשיר"</string>
+    <string name="empty" msgid="7858882803708117596">"אין פריטים"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"לא ניתן לפתוח את הקובץ"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"לא ניתן למחוק חלק מהמסמכים"</string>
+    <string name="share_via" msgid="8966594246261344259">"שתף באמצעות"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-ja/strings.xml b/packages/DocumentsUI/res/values-ja/strings.xml
new file mode 100644
index 0000000..2b4d487
--- /dev/null
+++ b/packages/DocumentsUI/res/values-ja/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"ドキュメント"</string>
+    <string name="title_open" msgid="4353228937663917801">"次から開く:"</string>
+    <string name="title_save" msgid="2433679664882857999">"次に保存:"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"フォルダを作成"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"グリッド表示"</string>
+    <string name="menu_list" msgid="7279285939892417279">"リスト表示"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"並べ替え"</string>
+    <string name="menu_search" msgid="3816712084502856974">"検索"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"設定"</string>
+    <string name="menu_open" msgid="432922957274920903">"開く"</string>
+    <string name="menu_save" msgid="2394743337684426338">"保存"</string>
+    <string name="menu_share" msgid="3075149983979628146">"共有"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"削除"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g>件選択済み"</string>
+    <string name="sort_name" msgid="9183560467917256779">"名前順"</string>
+    <string name="sort_date" msgid="586080032956151448">"更新日順"</string>
+    <string name="sort_size" msgid="3350681319735474741">"サイズ順"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"ルートを表示する"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"ルートを非表示にする"</string>
+    <string name="save_error" msgid="6167009778003223664">"ドキュメントを保存できませんでした"</string>
+    <string name="root_recent" msgid="4470053704320518133">"最近"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"空き容量: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"ショートカット"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"端末"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"その他のアプリ"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"端末の詳細設定を表示"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"ファイルのサイズを表示"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"端末のサイズを表示"</string>
+    <string name="empty" msgid="7858882803708117596">"アイテムがありません"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"ファイルを開けません"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"一部のドキュメントを削除できません"</string>
+    <string name="share_via" msgid="8966594246261344259">"共有ツール"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-ka-rGE/strings.xml b/packages/DocumentsUI/res/values-ka-rGE/strings.xml
new file mode 100644
index 0000000..e97202a
--- /dev/null
+++ b/packages/DocumentsUI/res/values-ka-rGE/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"დოკუმენტები"</string>
+    <string name="title_open" msgid="4353228937663917801">"გახსნა აქედან:"</string>
+    <string name="title_save" msgid="2433679664882857999">"შენახვა აქ:"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"საქაღალდის შექმნა"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"ბადის ხედი"</string>
+    <string name="menu_list" msgid="7279285939892417279">"სიის ხედი"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"სორტირება:"</string>
+    <string name="menu_search" msgid="3816712084502856974">"ძიება"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"პარამეტრები"</string>
+    <string name="menu_open" msgid="432922957274920903">"გახსნა"</string>
+    <string name="menu_save" msgid="2394743337684426338">"შენახვა"</string>
+    <string name="menu_share" msgid="3075149983979628146">"გაზიარება"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"წაშლა"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> მონიშნული"</string>
+    <string name="sort_name" msgid="9183560467917256779">"სახელით"</string>
+    <string name="sort_date" msgid="586080032956151448">"ცვლილების თარიღით"</string>
+    <string name="sort_size" msgid="3350681319735474741">"ზომით"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"ფესვების ჩვენება"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"ფესვების დამალვა"</string>
+    <string name="save_error" msgid="6167009778003223664">"დოკუმენტის შენახვა ვერ მოხერხდა"</string>
+    <string name="root_recent" msgid="4470053704320518133">"ბოლო"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> თავისუფალია"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"მალსახმობები"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"მოწყობილობები"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"მეტი აპები"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"კომპლექსური მოწყობილობების ჩვენება"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"ფაილის ზომის ჩვენება"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"მოწყობილობის ზომის ჩვენება"</string>
+    <string name="empty" msgid="7858882803708117596">"ერთეულები არ არის"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"ფაილის გახსნა ვერ ხერხდება"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"ზოგიერთი დოკუმენტის წაშლა ვერ ხერხდება"</string>
+    <string name="share_via" msgid="8966594246261344259">"გაზიარება:"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-km-rKH/strings.xml b/packages/DocumentsUI/res/values-km-rKH/strings.xml
new file mode 100644
index 0000000..63b6a27
--- /dev/null
+++ b/packages/DocumentsUI/res/values-km-rKH/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"ឯកសារ"</string>
+    <string name="title_open" msgid="4353228937663917801">"បើក​ពី"</string>
+    <string name="title_save" msgid="2433679664882857999">"រក្សា​ទុក​ទៅ"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"បង្កើត​ថត"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"ទិដ្ឋភាព​ក្រឡា"</string>
+    <string name="menu_list" msgid="7279285939892417279">"ទិដ្ឋភាព​បញ្ជី"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"តម្រៀប​តាម"</string>
+    <string name="menu_search" msgid="3816712084502856974">"ស្វែងរក"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"ការ​កំណត់"</string>
+    <string name="menu_open" msgid="432922957274920903">"បើក"</string>
+    <string name="menu_save" msgid="2394743337684426338">"រក្សាទុក"</string>
+    <string name="menu_share" msgid="3075149983979628146">"ចែករំលែក"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"លុប"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"បាន​ជ្រើស <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+    <string name="sort_name" msgid="9183560467917256779">"តាម​ឈ្មោះ"</string>
+    <string name="sort_date" msgid="586080032956151448">"តាម​កាលបរិច្ឆេទ​បាន​កែប្រែ"</string>
+    <string name="sort_size" msgid="3350681319735474741">"តាម​​ទំហំ"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"បង្ហាញ roots"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"លាក់ roots"</string>
+    <string name="save_error" msgid="6167009778003223664">"បាន​បរាជ័យ​ក្នុង​ការ​រក្សា​ទុក​ឯកសារ"</string>
+    <string name="root_recent" msgid="4470053704320518133">"ថ្មីៗ"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"ទំនេរ <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"ផ្លូវកាត់"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"ឧបករណ៍"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"កម្ម​វិធី​​ច្រើន​ទៀត"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"បង្ហាញ​ឧបករណ៍​កម្រិត​ខ្ពស់"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"បង្ហាញ​ទំហំ​ឯកសារ"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"បង្ហាញ​ទំហំ​ឧបករណ៍"</string>
+    <string name="empty" msgid="7858882803708117596">"គ្មានធាតុ"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"មិន​អាច​បើក​ឯកសារ"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"មិន​អាច​លុប​ឯកសារ​មួយ​ចំនួន"</string>
+    <string name="share_via" msgid="8966594246261344259">"ចែករំលែក​តាម"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-ko/strings.xml b/packages/DocumentsUI/res/values-ko/strings.xml
new file mode 100644
index 0000000..2f578eb
--- /dev/null
+++ b/packages/DocumentsUI/res/values-ko/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"문서"</string>
+    <string name="title_open" msgid="4353228937663917801">"열기:"</string>
+    <string name="title_save" msgid="2433679664882857999">"저장 위치:"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"폴더 만들기"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"바둑판식 보기"</string>
+    <string name="menu_list" msgid="7279285939892417279">"목록 보기"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"정렬 기준"</string>
+    <string name="menu_search" msgid="3816712084502856974">"검색"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"설정"</string>
+    <string name="menu_open" msgid="432922957274920903">"열기"</string>
+    <string name="menu_save" msgid="2394743337684426338">"저장"</string>
+    <string name="menu_share" msgid="3075149983979628146">"공유"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"삭제"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g>개 선택됨"</string>
+    <string name="sort_name" msgid="9183560467917256779">"이름순"</string>
+    <string name="sort_date" msgid="586080032956151448">"수정된 날짜순"</string>
+    <string name="sort_size" msgid="3350681319735474741">"크기순"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"루트 표시"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"루트 숨기기"</string>
+    <string name="save_error" msgid="6167009778003223664">"문서 저장 실패"</string>
+    <string name="root_recent" msgid="4470053704320518133">"최근"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> 남음"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"바로가기"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"기기"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"앱 더보기"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"고급 기기 표시"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"파일 크기 표시"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"기기 크기 표시"</string>
+    <string name="empty" msgid="7858882803708117596">"항목 없음"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"파일을 열 수 없음"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"일부 문서를 삭제할 수 없음"</string>
+    <string name="share_via" msgid="8966594246261344259">"공유 방법"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-lo-rLA/strings.xml b/packages/DocumentsUI/res/values-lo-rLA/strings.xml
new file mode 100644
index 0000000..ef05df4
--- /dev/null
+++ b/packages/DocumentsUI/res/values-lo-rLA/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"ເອ​ກະ​ສານ"</string>
+    <string name="title_open" msgid="4353228937663917801">"ເປີດ​ຈາກ"</string>
+    <string name="title_save" msgid="2433679664882857999">"ບັນທຶກໄປທີ່"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"ສ້າງໂຟນເດີ"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"ມຸມມອງແບບຊ່ອງ"</string>
+    <string name="menu_list" msgid="7279285939892417279">"ມຸມມອງແບບລາຍຊື່"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"ຮຽງລຳດັບຕາມ"</string>
+    <string name="menu_search" msgid="3816712084502856974">"ຊອກຫາ"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"ການຕັ້ງຄ່າ"</string>
+    <string name="menu_open" msgid="432922957274920903">"ເປີດ"</string>
+    <string name="menu_save" msgid="2394743337684426338">"ບັນທຶກ"</string>
+    <string name="menu_share" msgid="3075149983979628146">"ແບ່ງປັນ"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"ລຶບ"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"ເລືອກແລ້ວ <xliff:g id="COUNT">%1$d</xliff:g> ລາຍການ"</string>
+    <string name="sort_name" msgid="9183560467917256779">"ຕາມຊື່"</string>
+    <string name="sort_date" msgid="586080032956151448">"ຕາມວັນທີທີ່ແກ້ໄຂ"</string>
+    <string name="sort_size" msgid="3350681319735474741">"ຕາມຂະໜາດ"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"ສະແດງ roots"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"ເຊື່ອງ roots"</string>
+    <string name="save_error" msgid="6167009778003223664">"ການບັນທຶກເອກະສານລົ້ມເຫລວ"</string>
+    <string name="root_recent" msgid="4470053704320518133">"ຫາກໍໃຊ້"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"ຟຣີ <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"ທາງລັດ"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"ອຸປະກອນ"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"ແອັບຯອື່ນໆ"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"ສະແດງອຸປະກອນຂັ້ນສູງ"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"ສະແດງຂະໜາດໄຟລ໌"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"ສະແດງຂະໜາດອຸປະກອນ"</string>
+    <string name="empty" msgid="7858882803708117596">"ບໍ່ມີລາຍການ"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"ບໍ່ສາມດາເປີດໄຟລ໌ໄດ້"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"ບໍ່ສາມາດລຶບບາງເອກະສານໄດ້"</string>
+    <string name="share_via" msgid="8966594246261344259">"ແບ່ງປັນຜ່ານ"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-lt/strings.xml b/packages/DocumentsUI/res/values-lt/strings.xml
new file mode 100644
index 0000000..799fc19
--- /dev/null
+++ b/packages/DocumentsUI/res/values-lt/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Dokumentai"</string>
+    <string name="title_open" msgid="4353228937663917801">"Atidaryti iš"</string>
+    <string name="title_save" msgid="2433679664882857999">"Išsaugoti į"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Kurti aplanką"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Tinklelio rodinys"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Sąrašo rodinys"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Rūšiuoti pagal"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Ieškoti"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Nustatymai"</string>
+    <string name="menu_open" msgid="432922957274920903">"Atidaryti"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Išsaugoti"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Bendrinti"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Ištrinti"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"Pasirinkta: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Pagal pavadinimą"</string>
+    <string name="sort_date" msgid="586080032956151448">"Pagal keitimo datą"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Pagal dydį"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Rodyti šaknis"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Slėpti šaknis"</string>
+    <string name="save_error" msgid="6167009778003223664">"Nepavyko išsaugoti dokumento"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Naujausi"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"Laisvos vietos: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Spartieji klavišai"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Įrenginiai"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Daugiau programų"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Rodyti išplėstinius įrenginius"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Rodyti failo dydį"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Rodyti įrenginio dydį"</string>
+    <string name="empty" msgid="7858882803708117596">"Nėra elementų"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Nepavyksta atidaryti failo"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Nepavyko ištrinti kai kurių dokumentų"</string>
+    <string name="share_via" msgid="8966594246261344259">"Bendrinti naudojant"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-lv/strings.xml b/packages/DocumentsUI/res/values-lv/strings.xml
new file mode 100644
index 0000000..e9c72d5
--- /dev/null
+++ b/packages/DocumentsUI/res/values-lv/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Dokumenti"</string>
+    <string name="title_open" msgid="4353228937663917801">"Atvēršana no:"</string>
+    <string name="title_save" msgid="2433679664882857999">"Saglabāšana:"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Izveidot mapi"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Režģis"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Saraksts"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Kārtot pēc"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Meklēt"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Iestatījumi"</string>
+    <string name="menu_open" msgid="432922957274920903">"Atvērt"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Saglabāt"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Kopīgot"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Dzēst"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"Atlasīts: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Pēc nosaukuma"</string>
+    <string name="sort_date" msgid="586080032956151448">"Pēc pārveidošanas datuma"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Pēc lieluma"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Rādīt saknes"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Slēpt saknes"</string>
+    <string name="save_error" msgid="6167009778003223664">"Neizdevās saglabāt dokumentu."</string>
+    <string name="root_recent" msgid="4470053704320518133">"Pēdējie"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"Brīva vieta: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Saīsnes"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Ierīces"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Vairāk lietotņu"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Attēlot papildu ierīces"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Attēlot faila lielumu"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Attēlot ierīces izmēru"</string>
+    <string name="empty" msgid="7858882803708117596">"Nav vienumu"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Nevar atvērt failu."</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Nevar dzēst dažus dokumentus."</string>
+    <string name="share_via" msgid="8966594246261344259">"Kopīgot, izmantojot"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-mn-rMN/strings.xml b/packages/DocumentsUI/res/values-mn-rMN/strings.xml
new file mode 100644
index 0000000..76d1a20
--- /dev/null
+++ b/packages/DocumentsUI/res/values-mn-rMN/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Документүүд"</string>
+    <string name="title_open" msgid="4353228937663917801">"Нээх"</string>
+    <string name="title_save" msgid="2433679664882857999">"Хадгалах"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Фолдер үүсгэх"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Эгнүүлж харах"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Жагсааж харах"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Эрэмбэлэх"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Хайх"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Тохиргоо"</string>
+    <string name="menu_open" msgid="432922957274920903">"Нээх"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Хадгалах"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Хуваалцах"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Устгах"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> сонгогдсон"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Нэрээр"</string>
+    <string name="sort_date" msgid="586080032956151448">"Өөрчлөгдсөн огноогоор"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Хэмжээгээр"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Язгуурыг харуулах"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Язгуурыг нууцлах"</string>
+    <string name="save_error" msgid="6167009778003223664">"Документыг хадгалж чадсангүй"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Саяхны"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> чөлөөтэй"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Товчлол"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Төхөөрөмжүүд"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Өөр апп-ууд"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Дэвшилтэт төхөөрөмжүүдийг харуулах"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Файлын хэмжээг харуулах"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Төхөөрөмжийн хэмжээг харуулах"</string>
+    <string name="empty" msgid="7858882803708117596">"Хоосон"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Файлыг нээх боломжгүй"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Зарим документуудыг устгах боломжгүй"</string>
+    <string name="share_via" msgid="8966594246261344259">"Дараахаар дамжуулан хуваалцах"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-mn/strings.xml b/packages/DocumentsUI/res/values-mn/strings.xml
new file mode 100644
index 0000000..66637b8
--- /dev/null
+++ b/packages/DocumentsUI/res/values-mn/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Документүүд"</string>
+    <string name="title_open" msgid="4353228937663917801">"Нээх"</string>
+    <string name="title_save" msgid="2433679664882857999">"Хадгалах"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Фолдер үүсгэх"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Эгнүүлж харах"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Жагсааж харах"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Эрэмбэлэх"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Хайх"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Тохиргоо"</string>
+    <string name="menu_open" msgid="432922957274920903">"Нээх"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Хадгалах"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Хуваалцах"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Устгах"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> сонгогдсон"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Нэрээр"</string>
+    <string name="sort_date" msgid="586080032956151448">"Өөрчлөгдсөн огноогоор"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Хэмжээгээр"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Язгуурыг харуулах"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Язгуурыг нууцлах"</string>
+    <string name="save_error" msgid="6167009778003223664">"Документыг хадгалж чадсангүй"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Саяхны"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> чөлөөтэй"</string>
+    <string name="root_type_service" msgid="2857362700576006694">"Үйлчилгээнүүд"</string>
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Товчлол"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Төхөөрөмжүүд"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Өөр апп-ууд"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Дэвшилтэт төхөөрөмжүүдийг харуулах"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Файлын хэмжээг харуулах"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Төхөөрөмжийн хэмжээг харуулах"</string>
+    <string name="empty" msgid="7858882803708117596">"Хоосон"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Файлыг нээх боломжгүй"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Зарим документуудыг устгах боломжгүй"</string>
+    <string name="more" msgid="7117420986529297171">"Цааш"</string>
+    <string name="loading" msgid="7933681260296021180">"Ачааллаж байна..."</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-ms-rMY/strings.xml b/packages/DocumentsUI/res/values-ms-rMY/strings.xml
new file mode 100644
index 0000000..04ecb1f
--- /dev/null
+++ b/packages/DocumentsUI/res/values-ms-rMY/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Dokumen"</string>
+    <string name="title_open" msgid="4353228937663917801">"Buka dari"</string>
+    <string name="title_save" msgid="2433679664882857999">"Simpan ke"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Buat folder"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Paparan grid"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Paparan senarai"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Isih mengikut"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Cari"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Tetapan"</string>
+    <string name="menu_open" msgid="432922957274920903">"Buka"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Simpan"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Kongsi"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Padam"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> dipilih"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Mengikut nama"</string>
+    <string name="sort_date" msgid="586080032956151448">"Diubah suai mengikut tarikh"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Mengikut saiz"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Tunjukkan akar"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Sembunyikan akar"</string>
+    <string name="save_error" msgid="6167009778003223664">"Gagal menyimpan dokumen"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Terbaharu"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> kosong"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Pintasan"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Peranti"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Lebih banyak apl"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Paparkan peranti terperinci"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Paparkan saiz fail"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Paparkan saiz peranti"</string>
+    <string name="empty" msgid="7858882803708117596">"Tiada item"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Tidak dapat membuka fail"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Tidak dapat memadam beberapa dokumen"</string>
+    <string name="share_via" msgid="8966594246261344259">"Kongsi melalui"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-nb/strings.xml b/packages/DocumentsUI/res/values-nb/strings.xml
new file mode 100644
index 0000000..41661c3
--- /dev/null
+++ b/packages/DocumentsUI/res/values-nb/strings.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Dokumenter"</string>
+    <string name="title_open" msgid="4353228937663917801">"Åpne fra"</string>
+    <string name="title_save" msgid="2433679664882857999">"Lagre i"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Opprett en mappe"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Rutenettvisning"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Listevisning"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Sortér etter"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Søk"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Innstillinger"</string>
+    <string name="menu_open" msgid="432922957274920903">"Åpne"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Lagre"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Del"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Slett"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> valgt"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Etter navn"</string>
+    <string name="sort_date" msgid="586080032956151448">"«Etter dato» endret"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Etter størrelse"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Vis røtter"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Skjul røtter"</string>
+    <string name="save_error" msgid="6167009778003223664">"Kunne ikke lagre dokumentet"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Siste"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> gratis"</string>
+    <string name="root_type_service" msgid="2178854894416775409">"Lagringstjenester"</string>
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Snarveier"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Enheter"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Flere apper"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Vis avanserte enheter"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Vis filstørrelse"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Vis enhetsstørrelse"</string>
+    <string name="empty" msgid="7858882803708117596">"Ingen elementer"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Kan ikke åpne filen"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Enkelte dokumenter kunne ikke slettes"</string>
+    <string name="share_via" msgid="8966594246261344259">"Del via"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-ne-rNP/strings.xml b/packages/DocumentsUI/res/values-ne-rNP/strings.xml
new file mode 100644
index 0000000..d2606df
--- /dev/null
+++ b/packages/DocumentsUI/res/values-ne-rNP/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"कागजातहरू"</string>
+    <string name="title_open" msgid="4353228937663917801">"यसबाट खोल्नुहोस्"</string>
+    <string name="title_save" msgid="2433679664882857999">"यसमा सुरक्षित गर्नुहोस्"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"फोल्डर सिर्जना गर्नुहोस्"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"ग्रिड दृश्य"</string>
+    <string name="menu_list" msgid="7279285939892417279">"सूची दृश्य"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"यसद्वारा क्रमवद्घ गर्नुहोस्"</string>
+    <string name="menu_search" msgid="3816712084502856974">"खोज्नुहोस्"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"सेटिङहरू"</string>
+    <string name="menu_open" msgid="432922957274920903">"खोल्नुहोस्"</string>
+    <string name="menu_save" msgid="2394743337684426338">"सुरक्षित गर्नुहोस्"</string>
+    <string name="menu_share" msgid="3075149983979628146">"साझेदारी गर्नुहोस्"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"मेटाउनुहोस्"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> चयन गरियो"</string>
+    <string name="sort_name" msgid="9183560467917256779">"नाम अनुसार"</string>
+    <string name="sort_date" msgid="586080032956151448">"परिमार्जित मिति अनुसार"</string>
+    <string name="sort_size" msgid="3350681319735474741">"आकार अनुसार"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"मूलहरू देखाउनुहोस्"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"मूलहरू लुकाउनुहोस्"</string>
+    <string name="save_error" msgid="6167009778003223664">"कागजात सुरक्षित गर्न विफल भयो"</string>
+    <string name="root_recent" msgid="4470053704320518133">"हालैको"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> खाली"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"सर्टकटहरू"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"उपकरणहरू"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"थप अनुप्रयोगहरू"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"उन्नत उपकरणहरू प्रदर्शन गर्नुहोस्"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"फाइल आकार प्रदर्शन गर्नुहोस्"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"उपकरण आकार प्रदर्शन गर्नुहोस्"</string>
+    <string name="empty" msgid="7858882803708117596">"कुनै वस्तु छैन।"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"फाइल खोल्न सक्दैन"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"केही कागजातहरू मेट्न असमर्थ छ"</string>
+    <string name="share_via" msgid="8966594246261344259">"माध्यमबाट साझेदारी गर्नुहोस्"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-nl/strings.xml b/packages/DocumentsUI/res/values-nl/strings.xml
new file mode 100644
index 0000000..464a510
--- /dev/null
+++ b/packages/DocumentsUI/res/values-nl/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Documenten"</string>
+    <string name="title_open" msgid="4353228937663917801">"Openen vanuit"</string>
+    <string name="title_save" msgid="2433679664882857999">"Opslaan in"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Map maken"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Rasterweergave"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Lijstweergave"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Sorteren op"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Zoeken"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Instellingen"</string>
+    <string name="menu_open" msgid="432922957274920903">"Openen"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Opslaan"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Delen"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Verwijderen"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> geselecteerd"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Op naam"</string>
+    <string name="sort_date" msgid="586080032956151448">"Op aanpassingsdatum"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Op grootte"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Roots weergeven"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Roots verbergen"</string>
+    <string name="save_error" msgid="6167009778003223664">"Kan document niet opslaan"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Recent"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> vrij"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Sneltoetsen"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Apparaten"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Meer apps"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Geavanceerde apparaten weergeven"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Bestandsgrootte weergeven"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Apparaatgrootte weergeven"</string>
+    <string name="empty" msgid="7858882803708117596">"Geen items"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Kan bestand niet openen"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Kan bepaalde documenten niet verwijderen"</string>
+    <string name="share_via" msgid="8966594246261344259">"Delen via"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-pl/strings.xml b/packages/DocumentsUI/res/values-pl/strings.xml
new file mode 100644
index 0000000..e690fa4
--- /dev/null
+++ b/packages/DocumentsUI/res/values-pl/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Dokumenty"</string>
+    <string name="title_open" msgid="4353228937663917801">"Otwórz z"</string>
+    <string name="title_save" msgid="2433679664882857999">"Zapisz w"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Utwórz folder"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Widok siatki"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Widok listy"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Sortuj według"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Szukaj"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Ustawienia"</string>
+    <string name="menu_open" msgid="432922957274920903">"Otwórz"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Zapisz"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Udostępnij"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Usuń"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"Wybrano: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Według nazwy"</string>
+    <string name="sort_date" msgid="586080032956151448">"Według daty edycji"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Według rozmiaru"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Pokaż elementy główne"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Ukryj elementy główne"</string>
+    <string name="save_error" msgid="6167009778003223664">"Nie udało się zapisać dokumentu"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Ostatnie"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> wolne"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Skróty"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Urządzenia"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Więcej aplikacji"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Wyświetl urządzenia zaawansowane"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Wyświetl rozmiar pliku"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Wyświetl rozmiar urządzenia"</string>
+    <string name="empty" msgid="7858882803708117596">"Brak elementów"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Nie można otworzyć pliku"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Nie można usunąć niektórych dokumentów"</string>
+    <string name="share_via" msgid="8966594246261344259">"Udostępnij przez"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-pt-rPT/strings.xml b/packages/DocumentsUI/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..42efd0d
--- /dev/null
+++ b/packages/DocumentsUI/res/values-pt-rPT/strings.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Documentos"</string>
+    <string name="title_open" msgid="4353228937663917801">"Abrir de"</string>
+    <string name="title_save" msgid="2433679664882857999">"Guardar em"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Criar pasta"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Vista de grelha"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Vista de lista"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Ordenar por"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Pesquisar"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Definições"</string>
+    <string name="menu_open" msgid="432922957274920903">"Abrir"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Guardar"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Partilhar"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Eliminar"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> selecionado(s)"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Por nome"</string>
+    <string name="sort_date" msgid="586080032956151448">"Por data de modificação"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Por tamanho"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Mostrar raízes"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Ocultar raízes"</string>
+    <string name="save_error" msgid="6167009778003223664">"Falha ao guardar o documento"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Recentes"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> espaço livre"</string>
+    <string name="root_type_service" msgid="2178854894416775409">"Serv. de armazenamento"</string>
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Atalhos"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Dispositivos"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Mais aplicações"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Apresentar dispositivos avançados"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Apresentar tamanho do ficheiro"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Apresentar tamanho do dispositivo"</string>
+    <string name="empty" msgid="7858882803708117596">"Sem itens"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Não é possível abrir o ficheiro"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Não é possível eliminar alguns documentos"</string>
+    <string name="share_via" msgid="8966594246261344259">"Partilhar através de"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-pt/strings.xml b/packages/DocumentsUI/res/values-pt/strings.xml
new file mode 100644
index 0000000..d4fb0a7
--- /dev/null
+++ b/packages/DocumentsUI/res/values-pt/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Documentos"</string>
+    <string name="title_open" msgid="4353228937663917801">"Abrir de"</string>
+    <string name="title_save" msgid="2433679664882857999">"Salvar em"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Criar pasta"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Visualização em grade"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Visualização em lista"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Classificar por"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Pesquisar"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Configurações"</string>
+    <string name="menu_open" msgid="432922957274920903">"Abrir"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Salvar"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Compartilhar"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Excluir"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> selecionados"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Por nome"</string>
+    <string name="sort_date" msgid="586080032956151448">"Por data de modificação"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Por tamanho"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Mostrar raízes"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Ocultar raízes"</string>
+    <string name="save_error" msgid="6167009778003223664">"Falha ao salvar o documento"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Recentes"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> livres"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Atalhos"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Dispositivos"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Mais aplicativos"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Mostrar dispositivos avançados"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Mostrar tamanho do arquivo"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Mostrar tamanho do dispositivo"</string>
+    <string name="empty" msgid="7858882803708117596">"Nenhum item"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Não é possível abrir o arquivo"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Não foi possível excluir alguns documentos"</string>
+    <string name="share_via" msgid="8966594246261344259">"Compartilhar via"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-ro/strings.xml b/packages/DocumentsUI/res/values-ro/strings.xml
new file mode 100644
index 0000000..3e4a94a
--- /dev/null
+++ b/packages/DocumentsUI/res/values-ro/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Documente"</string>
+    <string name="title_open" msgid="4353228937663917801">"Deschideți din"</string>
+    <string name="title_save" msgid="2433679664882857999">"Salvați în"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Creați un dosar"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Afișare tip grilă"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Afișare tip listă"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Sortați după"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Căutați"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Setări"</string>
+    <string name="menu_open" msgid="432922957274920903">"Deschideți"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Salvați"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Distribuiți"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Ștergeți"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> selectate"</string>
+    <string name="sort_name" msgid="9183560467917256779">"După nume"</string>
+    <string name="sort_date" msgid="586080032956151448">"După data modificării"</string>
+    <string name="sort_size" msgid="3350681319735474741">"După dimensiune"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Afișați directoarele rădăcină"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Ascundeți directoarele rădăcină"</string>
+    <string name="save_error" msgid="6167009778003223664">"Salvarea documentului nu a reușit"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Recente"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> spațiu liber"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Comenzi rapide"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Dispozitive"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Alte aplicații"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Afișați dispozitive avansate"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Afișați dimensiunile fișierelor"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Afișați capacitatea de stocare a dispozitivelor"</string>
+    <string name="empty" msgid="7858882803708117596">"Nu există elemente"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Fișierul nu poate fi deschis"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Unele documente nu au putut fi șterse"</string>
+    <string name="share_via" msgid="8966594246261344259">"Distribuiți prin"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-ru/strings.xml b/packages/DocumentsUI/res/values-ru/strings.xml
new file mode 100644
index 0000000..b2ec07d
--- /dev/null
+++ b/packages/DocumentsUI/res/values-ru/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Документы"</string>
+    <string name="title_open" msgid="4353228937663917801">"Открыть"</string>
+    <string name="title_save" msgid="2433679664882857999">"Сохранить"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Новая папка"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Таблица"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Список"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Сортировать"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Поиск"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Настройки"</string>
+    <string name="menu_open" msgid="432922957274920903">"Открыть"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Сохранить"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Поделиться"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Удалить"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"Выбрано: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+    <string name="sort_name" msgid="9183560467917256779">"По названию"</string>
+    <string name="sort_date" msgid="586080032956151448">"По дате изменения"</string>
+    <string name="sort_size" msgid="3350681319735474741">"По размеру"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Показать"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Скрыть"</string>
+    <string name="save_error" msgid="6167009778003223664">"Не удалось сохранить документ"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Недавние"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"Свободно <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Ярлыки"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Устройства"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Другие приложения"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Показать другие устройства"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Показать размер файла"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Показать размер устройства"</string>
+    <string name="empty" msgid="7858882803708117596">"Ничего нет"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Не удалось открыть файл"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Не удалось удалить некоторые документы"</string>
+    <string name="share_via" msgid="8966594246261344259">"Поделиться"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-si-rLK/strings.xml b/packages/DocumentsUI/res/values-si-rLK/strings.xml
new file mode 100644
index 0000000..6263b82
--- /dev/null
+++ b/packages/DocumentsUI/res/values-si-rLK/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"ලේඛන"</string>
+    <string name="title_open" msgid="4353228937663917801">"විවෘත වන්නේ"</string>
+    <string name="title_save" msgid="2433679664882857999">"සුරකින්නේ"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"ෆෝල්ඩරයක් සාදන්න"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"ජාල පෙනුම"</string>
+    <string name="menu_list" msgid="7279285939892417279">"ලැයිස්තු පෙනුම"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"අනුපිළිවෙලට සකසා ඇත්තේ"</string>
+    <string name="menu_search" msgid="3816712084502856974">"සෙවීම"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"සැකසීම්"</string>
+    <string name="menu_open" msgid="432922957274920903">"විවෘත කරන්න"</string>
+    <string name="menu_save" msgid="2394743337684426338">"සුරකින්න"</string>
+    <string name="menu_share" msgid="3075149983979628146">"බෙදාගන්න"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"මකන්න"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> ක් තෝරාගන්නා ලදි"</string>
+    <string name="sort_name" msgid="9183560467917256779">"නමින්"</string>
+    <string name="sort_date" msgid="586080032956151448">"වෙනස් කරන ලද දිනයෙන්"</string>
+    <string name="sort_size" msgid="3350681319735474741">"ප්‍රමාණය මගින්"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"මුල් පෙන්වන්න"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"මුල් සඟවන්න"</string>
+    <string name="save_error" msgid="6167009778003223664">"ලේඛනය සුරැකීමට අපොහොසත් විය"</string>
+    <string name="root_recent" msgid="4470053704320518133">"මෑත"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ඉතිරියි"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"කෙටිමං"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"උපාංග"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"තවත් යෙදුම්"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"උසස් උපාංග දර්ශනය කරන්න"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"ගොනු ප්‍රමාණය දර්ශනය කරන්න"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"උපාංග ප්‍රමාණය දර්ශනය කරන්න"</string>
+    <string name="empty" msgid="7858882803708117596">"අයිතම නැත"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"ගොනුව විවෘත කළ නොහැක"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"සමහර ලේඛන මැකීමට නොහැකි විය"</string>
+    <string name="share_via" msgid="8966594246261344259">"හරහා බෙදාගන්න"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-sk/strings.xml b/packages/DocumentsUI/res/values-sk/strings.xml
new file mode 100644
index 0000000..772d595
--- /dev/null
+++ b/packages/DocumentsUI/res/values-sk/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Dokumenty"</string>
+    <string name="title_open" msgid="4353228937663917801">"Otvoriť z"</string>
+    <string name="title_save" msgid="2433679664882857999">"Uložiť do"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Vytvoriť priečinok"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Zobrazenie mriežky"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Zobrazenie zoznamu"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Zoradiť podľa"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Hľadať"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Nastavenia"</string>
+    <string name="menu_open" msgid="432922957274920903">"Otvoriť"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Uložiť"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Zdieľať"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Odstrániť"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"Vybraté: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Podľa názvu"</string>
+    <string name="sort_date" msgid="586080032956151448">"Podľa dátumu zmeny"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Podľa veľkosti"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Zobraziť korene"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Skryť korene"</string>
+    <string name="save_error" msgid="6167009778003223664">"Dokument sa nepodarilo uložiť"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Nedávne"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"Voľné: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Skratky"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Zariadenia"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Ďalšie aplikácie"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Zobraziť rozšírené zariadenia"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Zobraziť veľkosť súboru"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Zobraziť veľkosť zariadenia"</string>
+    <string name="empty" msgid="7858882803708117596">"Žiadne položky"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Súbor sa nepodarilo otvoriť"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Niektoré dokumenty sa nepodarilo odstrániť"</string>
+    <string name="share_via" msgid="8966594246261344259">"Zdieľať pomocou"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-sl/strings.xml b/packages/DocumentsUI/res/values-sl/strings.xml
new file mode 100644
index 0000000..d64e504
--- /dev/null
+++ b/packages/DocumentsUI/res/values-sl/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Dokumenti"</string>
+    <string name="title_open" msgid="4353228937663917801">"Odpiranje iz"</string>
+    <string name="title_save" msgid="2433679664882857999">"Shranjevanje v"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Ustvarjanje mape"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Mrežni pogled"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Pogled seznama"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Razvrsti glede na"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Iskanje"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Nastavitve"</string>
+    <string name="menu_open" msgid="432922957274920903">"Odpri"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Shrani"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Skupna raba"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Izbriši"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"Št. izbranih: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Po imenu"</string>
+    <string name="sort_date" msgid="586080032956151448">"Po datumu spremembe"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Po velikosti"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Pokaži korene"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Skrij korene"</string>
+    <string name="save_error" msgid="6167009778003223664">"Dokumenta ni bilo mogoče shraniti"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Nedavno"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"Prosto: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Bližnjice"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Naprave"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Več aplikacij"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Prikaz naprednih naprav"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Prikaz velikosti datoteke"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Prikaz velikosti naprave"</string>
+    <string name="empty" msgid="7858882803708117596">"Ni elementov"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Datoteke ni mogoče odpreti"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Nekaterih dokumentov ni mogoče izbrisati"</string>
+    <string name="share_via" msgid="8966594246261344259">"Deli z drugimi prek"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-sr/strings.xml b/packages/DocumentsUI/res/values-sr/strings.xml
new file mode 100644
index 0000000..897e712
--- /dev/null
+++ b/packages/DocumentsUI/res/values-sr/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Документи"</string>
+    <string name="title_open" msgid="4353228937663917801">"Отвори са"</string>
+    <string name="title_save" msgid="2433679664882857999">"Сачувај у"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Направи директоријум"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Приказ мреже"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Приказ листе"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Сортирај према"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Претражи"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Подешавања"</string>
+    <string name="menu_open" msgid="432922957274920903">"Отвори"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Сачувај"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Дели"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Избриши"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"Изабрано је <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Према имену"</string>
+    <string name="sort_date" msgid="586080032956151448">"Према датуму измене"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Према величини"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Прикажи основне елементе"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Сакриј основне елементе"</string>
+    <string name="save_error" msgid="6167009778003223664">"Чување документа није успело"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Недавно"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"Слободно је <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Пречице"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Уређаји"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Још апликација"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Прикажи напредне уређаје"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Прикажи величину датотеке"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Прикажи величину уређаја"</string>
+    <string name="empty" msgid="7858882803708117596">"Нема ставки"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Није могуће отворити датотеку"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Није могуће избрисати неке документе"</string>
+    <string name="share_via" msgid="8966594246261344259">"Делите преко"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-sv/strings.xml b/packages/DocumentsUI/res/values-sv/strings.xml
new file mode 100644
index 0000000..7e2a5bb
--- /dev/null
+++ b/packages/DocumentsUI/res/values-sv/strings.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Dokument"</string>
+    <string name="title_open" msgid="4353228937663917801">"Öppna från"</string>
+    <string name="title_save" msgid="2433679664882857999">"Spara till"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Skapa mapp"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Rutnätsvy"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Listvy"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Sortera efter"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Sök"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Inställningar"</string>
+    <string name="menu_open" msgid="432922957274920903">"Öppna"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Spara"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Dela"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Ta bort"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"Har valt <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Efter namn"</string>
+    <string name="sort_date" msgid="586080032956151448">"Efter ändringsdatum"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Efter storlek"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Visa rötter"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Dölj rötter"</string>
+    <string name="save_error" msgid="6167009778003223664">"Det gick inte att spara dokumentet"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Senaste"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ledigt"</string>
+    <string name="root_type_service" msgid="2178854894416775409">"Lagringstjänster"</string>
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Genvägar"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Enheter"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Fler appar"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Visa avancerade enheter"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Visa filstorlek"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Bildskärmsstorlek"</string>
+    <string name="empty" msgid="7858882803708117596">"Inga objekt"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Det går inte att öppna filen"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Det gick inte att ta bort vissa dokument"</string>
+    <string name="share_via" msgid="8966594246261344259">"Dela via"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-sw/strings.xml b/packages/DocumentsUI/res/values-sw/strings.xml
new file mode 100644
index 0000000..c911fa4
--- /dev/null
+++ b/packages/DocumentsUI/res/values-sw/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Hati"</string>
+    <string name="title_open" msgid="4353228937663917801">"Fungua kutoka"</string>
+    <string name="title_save" msgid="2433679664882857999">"Hifadhi kwenye"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Unda folda"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Mwonekano gridi"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Mwonekano orodha"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Panga kwa"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Utafutaji"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Mipangilio"</string>
+    <string name="menu_open" msgid="432922957274920903">"Fungua"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Hifadhi"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Shiriki"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Futa"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> zimechaguliwa"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Kwa jina"</string>
+    <string name="sort_date" msgid="586080032956151448">"Kwa tarehe viliporekebishwa"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Kwa ukubwa"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Onyesha usuli"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Ficha usuli"</string>
+    <string name="save_error" msgid="6167009778003223664">"Imeshindwa kuhifadhi hati"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Hivi karibuni"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> bila malipo"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Njia za mkato"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Vifaa"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Programu zaidi"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Onyesha vifaa mahiri"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Onyesha ukubwa wa faili"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Onyesha ukubwa wa kifaa"</string>
+    <string name="empty" msgid="7858882803708117596">"Hakuna vipengee"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Haiwezi kufungua faili"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Imeshindwa kufuta baadhi ya hati"</string>
+    <string name="share_via" msgid="8966594246261344259">"Shiriki kupitia"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-sw720dp-land/dimens.xml b/packages/DocumentsUI/res/values-sw720dp-land/dimens.xml
new file mode 100644
index 0000000..961608c
--- /dev/null
+++ b/packages/DocumentsUI/res/values-sw720dp-land/dimens.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <bool name="always_show_summary">true</bool>
+</resources>
diff --git a/packages/DocumentsUI/res/values-sw720dp/dimens.xml b/packages/DocumentsUI/res/values-sw720dp/dimens.xml
new file mode 100644
index 0000000..3be243a
--- /dev/null
+++ b/packages/DocumentsUI/res/values-sw720dp/dimens.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <bool name="show_as_dialog">true</bool>
+
+    <item type="dimen" name="dialog_width">85%</item>
+    <item type="dimen" name="dialog_height">90%</item>
+</resources>
diff --git a/packages/DocumentsUI/res/values-sw720dp/styles.xml b/packages/DocumentsUI/res/values-sw720dp/styles.xml
new file mode 100644
index 0000000..4ff1c60
--- /dev/null
+++ b/packages/DocumentsUI/res/values-sw720dp/styles.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+    <style name="Theme" parent="@android:style/Theme.Holo.Light">
+        <item name="android:windowBackground">@*android:drawable/dialog_full_holo_light</item>
+        <item name="android:colorBackgroundCacheHint">@null</item>
+        <item name="android:windowIsTranslucent">true</item>
+    </style>
+</resources>
diff --git a/packages/DocumentsUI/res/values-th/strings.xml b/packages/DocumentsUI/res/values-th/strings.xml
new file mode 100644
index 0000000..1a25f8a
--- /dev/null
+++ b/packages/DocumentsUI/res/values-th/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"เอกสาร"</string>
+    <string name="title_open" msgid="4353228937663917801">"เปิดจาก"</string>
+    <string name="title_save" msgid="2433679664882857999">"บันทึกไปยัง"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"สร้างโฟลเดอร์"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"มุมมองตาราง"</string>
+    <string name="menu_list" msgid="7279285939892417279">"มุมมองรายการ"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"จัดเรียงตาม"</string>
+    <string name="menu_search" msgid="3816712084502856974">"ค้นหา"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"การตั้งค่า"</string>
+    <string name="menu_open" msgid="432922957274920903">"เปิด"</string>
+    <string name="menu_save" msgid="2394743337684426338">"บันทึก"</string>
+    <string name="menu_share" msgid="3075149983979628146">"แชร์"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"ลบ"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"เลือกไว้ <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+    <string name="sort_name" msgid="9183560467917256779">"ตามชื่อ"</string>
+    <string name="sort_date" msgid="586080032956151448">"ตามวันที่ที่ปรับเปลี่ยน"</string>
+    <string name="sort_size" msgid="3350681319735474741">"ตามขนาด"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"แสดงราก"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"ซ่อนราก"</string>
+    <string name="save_error" msgid="6167009778003223664">"การบันทึกเอกสารล้มเหลว"</string>
+    <string name="root_recent" msgid="4470053704320518133">"ล่าสุด"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"ว่าง <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"ทางลัด"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"อุปกรณ์"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"แอปเพิ่มเติม"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"แสดงอุปกรณ์ขั้นสูง"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"แสดงขนาดของไฟล์"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"แสดงขนาดของอุปกรณ์"</string>
+    <string name="empty" msgid="7858882803708117596">"ไม่มีรายการ"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"ไม่สามารถเปิดไฟล์ได้"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"ไม่สามารถลบเอกสารบางรายการ"</string>
+    <string name="share_via" msgid="8966594246261344259">"แชร์ผ่าน"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-tl/strings.xml b/packages/DocumentsUI/res/values-tl/strings.xml
new file mode 100644
index 0000000..20a93cd
--- /dev/null
+++ b/packages/DocumentsUI/res/values-tl/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Mga Dokumento"</string>
+    <string name="title_open" msgid="4353228937663917801">"Buksan mula sa"</string>
+    <string name="title_save" msgid="2433679664882857999">"I-save sa"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Gumawa ng folder"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"View ng grid"</string>
+    <string name="menu_list" msgid="7279285939892417279">"View ng listahan"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Pag-uri-uriin ayon sa"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Maghanap"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Mga Setting"</string>
+    <string name="menu_open" msgid="432922957274920903">"Buksan"</string>
+    <string name="menu_save" msgid="2394743337684426338">"I-save"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Ibahagi"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Tanggalin"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> ang pinili"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Ayon sa pangalan"</string>
+    <string name="sort_date" msgid="586080032956151448">"Ayon sa petsa ng pagbago"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Ayon sa laki"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Ipakita ang mga root"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Itago ang mga root"</string>
+    <string name="save_error" msgid="6167009778003223664">"Hindi na-save ang dokumento"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Kamakailan"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ang libre"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Mga Shortcut"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Mga Device"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Higit pang apps"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Ipakita ang mga advanced na device"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Ipakita ang laki ng file"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Ipakita ang laki ng device"</string>
+    <string name="empty" msgid="7858882803708117596">"Walang mga item"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Hindi mabuksan ang file"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Hindi matanggal ang ilang dokumento"</string>
+    <string name="share_via" msgid="8966594246261344259">"Ibahagi sa pamamagitan ng"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-tr/strings.xml b/packages/DocumentsUI/res/values-tr/strings.xml
new file mode 100644
index 0000000..f7b0f2c
--- /dev/null
+++ b/packages/DocumentsUI/res/values-tr/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Dokümanlar"</string>
+    <string name="title_open" msgid="4353228937663917801">"Şuradan aç:"</string>
+    <string name="title_save" msgid="2433679664882857999">"Şuraya kaydet:"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Klasör oluştur"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Tablo görünümü"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Liste görünümü"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Sıralama ölçütü"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Ara"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Ayarlar"</string>
+    <string name="menu_open" msgid="432922957274920903">"Aç"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Kaydet"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Paylaş"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Sil"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> tane seçildi"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Ada göre"</string>
+    <string name="sort_date" msgid="586080032956151448">"Değişiklik tarihine göre"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Boyuta göre"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Kökleri göster"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Kökleri sakla"</string>
+    <string name="save_error" msgid="6167009778003223664">"Doküman kaydedilemedi"</string>
+    <string name="root_recent" msgid="4470053704320518133">"En son"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> boş"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Kısayollar"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Cihazlar"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Diğer uygulamalar"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Gelişmiş cihazları göster"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Dosya boyutunu göster"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Cihaz boyutunu göster"</string>
+    <string name="empty" msgid="7858882803708117596">"Öğe yok"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Dosya açılamıyor"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Bazı dokümanlar silinemiyor"</string>
+    <string name="share_via" msgid="8966594246261344259">"Şunu kullanarak paylaş:"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-uk/strings.xml b/packages/DocumentsUI/res/values-uk/strings.xml
new file mode 100644
index 0000000..f49e04c
--- /dev/null
+++ b/packages/DocumentsUI/res/values-uk/strings.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Документи"</string>
+    <string name="title_open" msgid="4353228937663917801">"Відкрити в"</string>
+    <string name="title_save" msgid="2433679664882857999">"Зберегти в"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Створити папку"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Режим таблиці"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Режим списку"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Параметри сортування"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Пошук"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Налаштування"</string>
+    <string name="menu_open" msgid="432922957274920903">"Відкрити"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Зберегти"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Поділитися"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Видалити"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"Вибрано <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+    <string name="sort_name" msgid="9183560467917256779">"За назвою"</string>
+    <string name="sort_date" msgid="586080032956151448">"За датою змінення"</string>
+    <string name="sort_size" msgid="3350681319735474741">"За розміром"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Показати кореневі каталоги"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Сховати кореневі каталоги"</string>
+    <string name="save_error" msgid="6167009778003223664">"Не вдалося зберегти документ"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Останні"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> вільного місця"</string>
+    <string name="root_type_service" msgid="2178854894416775409">"Онлайн-сховища"</string>
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Ярлики"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Пристрої"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Інші програми"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Показати покращені пристрої"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Показати розмір файлу"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Показати розмір пристрою"</string>
+    <string name="empty" msgid="7858882803708117596">"Немає елементів"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Не вдалося відкрити файл"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Не вдалося видалити деякі документи"</string>
+    <string name="share_via" msgid="8966594246261344259">"Надіслати через"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-vi/strings.xml b/packages/DocumentsUI/res/values-vi/strings.xml
new file mode 100644
index 0000000..4993b9b
--- /dev/null
+++ b/packages/DocumentsUI/res/values-vi/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Tài liệu"</string>
+    <string name="title_open" msgid="4353228937663917801">"Mở từ"</string>
+    <string name="title_save" msgid="2433679664882857999">"Lưu vào"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Tạo thư mục"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Chế độ xem lưới"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Chế độ xem danh sách"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Sắp xếp theo"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Tìm kiếm"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Cài đặt"</string>
+    <string name="menu_open" msgid="432922957274920903">"Mở"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Lưu"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Chia sẻ"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Xóa"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"Đã chọn <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Theo tên"</string>
+    <string name="sort_date" msgid="586080032956151448">"Theo ngày sửa đổi"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Theo kích thước"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Hiển thị gốc"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Ẩn gốc"</string>
+    <string name="save_error" msgid="6167009778003223664">"Không lưu tài liệu được"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Gần đây"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> còn trống"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Lối tắt"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Thiết bị"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Các ứng dụng khác"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Hiển thị các thiết bị nâng cao"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Hiển thị kích thước tệp"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Hiển thị kích thước thiết bị"</string>
+    <string name="empty" msgid="7858882803708117596">"Không có mục nào"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Không thể mở tệp"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Không thể xóa một số tài liệu"</string>
+    <string name="share_via" msgid="8966594246261344259">"Chia sẻ qua"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-zh-rCN/strings.xml b/packages/DocumentsUI/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..8c662cc
--- /dev/null
+++ b/packages/DocumentsUI/res/values-zh-rCN/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"文档"</string>
+    <string name="title_open" msgid="4353228937663917801">"打开文件"</string>
+    <string name="title_save" msgid="2433679664882857999">"保存文件"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"新建文件夹"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"网格视图"</string>
+    <string name="menu_list" msgid="7279285939892417279">"列表视图"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"排序依据"</string>
+    <string name="menu_search" msgid="3816712084502856974">"搜索"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"设置"</string>
+    <string name="menu_open" msgid="432922957274920903">"打开"</string>
+    <string name="menu_save" msgid="2394743337684426338">"保存"</string>
+    <string name="menu_share" msgid="3075149983979628146">"分享"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"删除"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"已选择<xliff:g id="COUNT">%1$d</xliff:g>项"</string>
+    <string name="sort_name" msgid="9183560467917256779">"按名称"</string>
+    <string name="sort_date" msgid="586080032956151448">"按修改日期"</string>
+    <string name="sort_size" msgid="3350681319735474741">"按大小"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"显示根目录"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"隐藏根目录"</string>
+    <string name="save_error" msgid="6167009778003223664">"无法保存文档"</string>
+    <string name="root_recent" msgid="4470053704320518133">"最近"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"可用空间:<xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"捷径"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"设备"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"更多应用"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"显示高级设备"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"显示文件大小"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"显示设备大小"</string>
+    <string name="empty" msgid="7858882803708117596">"无任何文件"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"无法打开文件"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"无法删除部分文档"</string>
+    <string name="share_via" msgid="8966594246261344259">"分享方式"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-zh-rHK/strings.xml b/packages/DocumentsUI/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..a08f6dc
--- /dev/null
+++ b/packages/DocumentsUI/res/values-zh-rHK/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"文件"</string>
+    <string name="title_open" msgid="4353228937663917801">"開啟自"</string>
+    <string name="title_save" msgid="2433679664882857999">"儲存至"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"建立資料夾"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"格狀檢視"</string>
+    <string name="menu_list" msgid="7279285939892417279">"清單檢視"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"排序方式"</string>
+    <string name="menu_search" msgid="3816712084502856974">"搜尋"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"設定"</string>
+    <string name="menu_open" msgid="432922957274920903">"開啟"</string>
+    <string name="menu_save" msgid="2394743337684426338">"儲存"</string>
+    <string name="menu_share" msgid="3075149983979628146">"分享"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"刪除"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"已選取 <xliff:g id="COUNT">%1$d</xliff:g> 個"</string>
+    <string name="sort_name" msgid="9183560467917256779">"按名稱"</string>
+    <string name="sort_date" msgid="586080032956151448">"按修改日期"</string>
+    <string name="sort_size" msgid="3350681319735474741">"按大小"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"顯示根目錄"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"隱藏根目錄"</string>
+    <string name="save_error" msgid="6167009778003223664">"無法儲存文件"</string>
+    <string name="root_recent" msgid="4470053704320518133">"近期用過"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"可用空間:<xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"捷徑"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"裝置"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"更多應用程式"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"顯示進階裝置"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"顯示檔案大小"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"顯示裝置大小"</string>
+    <string name="empty" msgid="7858882803708117596">"沒有項目"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"無法開啟檔案"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"無法刪除部分文件"</string>
+    <string name="share_via" msgid="8966594246261344259">"分享方式:"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-zh-rTW/strings.xml b/packages/DocumentsUI/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..d49d789
--- /dev/null
+++ b/packages/DocumentsUI/res/values-zh-rTW/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"文件"</string>
+    <string name="title_open" msgid="4353228937663917801">"開啟工具"</string>
+    <string name="title_save" msgid="2433679664882857999">"儲存至"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"建立資料夾"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"格狀檢視"</string>
+    <string name="menu_list" msgid="7279285939892417279">"清單檢視"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"排序依據"</string>
+    <string name="menu_search" msgid="3816712084502856974">"搜尋"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"設定"</string>
+    <string name="menu_open" msgid="432922957274920903">"開啟"</string>
+    <string name="menu_save" msgid="2394743337684426338">"儲存"</string>
+    <string name="menu_share" msgid="3075149983979628146">"共用"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"刪除"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"已選取 <xliff:g id="COUNT">%1$d</xliff:g> 個項目"</string>
+    <string name="sort_name" msgid="9183560467917256779">"依名稱"</string>
+    <string name="sort_date" msgid="586080032956151448">"依修改日期"</string>
+    <string name="sort_size" msgid="3350681319735474741">"依大小"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"顯示根目錄"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"隱藏根目錄"</string>
+    <string name="save_error" msgid="6167009778003223664">"無法儲存文件"</string>
+    <string name="root_recent" msgid="4470053704320518133">"最近使用過的項目"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"可用空間:<xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"捷徑"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"裝置"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"更多應用程式"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"顯示進階裝置"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"顯示檔案大小"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"顯示裝置大小"</string>
+    <string name="empty" msgid="7858882803708117596">"沒有項目"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"無法開啟檔案"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"無法刪除部分文件"</string>
+    <string name="share_via" msgid="8966594246261344259">"分享方式:"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values-zu/strings.xml b/packages/DocumentsUI/res/values-zu/strings.xml
new file mode 100644
index 0000000..fa3a93e
--- /dev/null
+++ b/packages/DocumentsUI/res/values-zu/strings.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="2783841764617238354">"Amadokhumenti"</string>
+    <string name="title_open" msgid="4353228937663917801">"Vula kusuka ku-"</string>
+    <string name="title_save" msgid="2433679664882857999">"Londoloza ku-"</string>
+    <string name="menu_create_dir" msgid="5947289605844398389">"Dala ifolda"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Ukubuka kwegridi"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Ukubuka uhlu"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Hlunga nge-"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Sesha"</string>
+    <string name="menu_settings" msgid="6008033148948428823">"Izilungiselelo"</string>
+    <string name="menu_open" msgid="432922957274920903">"Vula"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Londoloza"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Yabelana"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Susa"</string>
+    <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> okukhethiwe"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Ngegama"</string>
+    <string name="sort_date" msgid="586080032956151448">"Kuguqulwe ngedethi"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Ngosayizi"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Bonisa izimpande"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Fihla izimpande"</string>
+    <string name="save_error" msgid="6167009778003223664">"Yehlulekile ukulondoloza idokhumenti"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Okwakamuva"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> okhululekile"</string>
+    <!-- no translation found for root_type_service (2178854894416775409) -->
+    <skip />
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Izinqamuleli"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Amadivayisi"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Izinhlelo zokusebenza eziningi"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Bonisa amadivayisi aphakeme"</string>
+    <string name="pref_file_size" msgid="2826879315743961459">"Bonisa usayizi wefayela"</string>
+    <string name="pref_device_size" msgid="3542106883278997222">"Bonisa usayizi wedivayisi"</string>
+    <string name="empty" msgid="7858882803708117596">"Azikho izinto"</string>
+    <string name="toast_no_application" msgid="1339885974067891667">"Ayikwazi ukuvula ifayela"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Ayikwazi ukususa amanye amadokhumenti"</string>
+    <string name="share_via" msgid="8966594246261344259">"Yabelana nge-"</string>
+</resources>
diff --git a/packages/DocumentsUI/res/values/colors.xml b/packages/DocumentsUI/res/values/colors.xml
new file mode 100644
index 0000000..6d62759
--- /dev/null
+++ b/packages/DocumentsUI/res/values/colors.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <color name="chip">#ddd</color>
+    <color name="item_root_activated">#cccccc</color>
+</resources>
diff --git a/packages/DocumentsUI/res/values/dimens.xml b/packages/DocumentsUI/res/values/dimens.xml
new file mode 100644
index 0000000..25b0f84
--- /dev/null
+++ b/packages/DocumentsUI/res/values/dimens.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <dimen name="icon_size">32dp</dimen>
+    <dimen name="root_icon_size">24dp</dimen>
+    <dimen name="grid_width">180dp</dimen>
+    <dimen name="grid_height">180dp</dimen>
+
+    <bool name="show_as_dialog">false</bool>
+    <bool name="always_show_summary">false</bool>
+</resources>
diff --git a/packages/DocumentsUI/res/values/strings.xml b/packages/DocumentsUI/res/values/strings.xml
new file mode 100644
index 0000000..682ae4a
--- /dev/null
+++ b/packages/DocumentsUI/res/values/strings.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Title of the documents application [CHAR LIMIT=32] -->
+    <string name="app_label">Documents</string>
+
+    <!-- Action bar title prompting user to choose a location to open a document from [CHAR LIMIT=32] -->
+    <string name="title_open">Open from</string>
+    <!-- Action bar title prompting user to choose a location to save a document to [CHAR LIMIT=32] -->
+    <string name="title_save">Save to</string>
+
+    <!-- Menu item that creates a new directory/folder at the current location [CHAR LIMIT=24] -->
+    <string name="menu_create_dir">Create folder</string>
+    <!-- Menu item that switches view to show documents as a large-format grid of thumbnails [CHAR LIMIT=24] -->
+    <string name="menu_grid">Grid view</string>
+    <!-- Menu item that switches view to show documents as a list [CHAR LIMIT=24] -->
+    <string name="menu_list">List view</string>
+    <!-- Menu item that switches the criteria with which documents are sorted [CHAR LIMIT=24] -->
+    <string name="menu_sort">Sort by</string>
+    <!-- Menu item that enters a mode to search for documents [CHAR LIMIT=24] -->
+    <string name="menu_search">Search</string>
+    <!-- Menu item that enters activity to change settings [CHAR LIMIT=24] -->
+    <string name="menu_settings">Settings</string>
+
+    <!-- Menu item title that opens the selected documents [CHAR LIMIT=24] -->
+    <string name="menu_open">Open</string>
+    <!-- Menu item title that saves the current document [CHAR LIMIT=24] -->
+    <string name="menu_save">Save</string>
+    <!-- Menu item title that shares the selected documents [CHAR LIMIT=24] -->
+    <string name="menu_share">Share</string>
+    <!-- Menu item title that deletes the selected documents [CHAR LIMIT=24] -->
+    <string name="menu_delete">Delete</string>
+
+    <!-- Action mode title summarizing the number of documents selected [CHAR LIMIT=32] -->
+    <string name="mode_selected_count"><xliff:g id="count" example="3">%1$d</xliff:g> selected</string>
+
+    <!-- Mode that sorts documents by their display name alphabetically [CHAR LIMIT=24] -->
+    <string name="sort_name">By name</string>
+    <!-- Mode that sorts documents by their last modified time in descending order; most recent first [CHAR LIMIT=24] -->
+    <string name="sort_date">By date modified</string>
+    <!-- Mode that sorts documents by their file size in descending order; largest first [CHAR LIMIT=24] -->
+    <string name="sort_size">By size</string>
+
+    <!-- Accessibility title to open the drawer showing all roots where documents can be stored [CHAR LIMIT=32] -->
+    <string name="drawer_open">Show roots</string>
+    <!-- Accessibility title to close the drawer showing all roots where documents can be stored [CHAR LIMIT=32] -->
+    <string name="drawer_close">Hide roots</string>
+
+    <!-- Toast shown when saving a document failed with an error [CHAR LIMIT=48] -->
+    <string name="save_error">Failed to save document</string>
+
+    <!-- Title of storage root location that contains recently modified or used documents [CHAR LIMIT=24] -->
+    <string name="root_recent">Recent</string>
+    <!-- Subtitle of storage root indicating the total free space available, in bytes [CHAR LIMIT=24] -->
+    <string name="root_available_bytes"><xliff:g id="size" example="3GB">%1$s</xliff:g> free</string>
+
+    <!-- Header title for list of storage roots that contains cloud services [CHAR LIMIT=24] -->
+    <string name="root_type_service">Storage services</string>
+    <!-- Header title for list of storage roots that contains shortcuts to documents that may be available elsewhere [CHAR LIMIT=24] -->
+    <string name="root_type_shortcut">Shortcuts</string>
+    <!-- Header title for list of storage roots that contains physical devices [CHAR LIMIT=24] -->
+    <string name="root_type_device">Devices</string>
+    <!-- Header title for list of additional apps that can provide documents [CHAR LIMIT=24] -->
+    <string name="root_type_apps">More apps</string>
+
+    <!-- Title for setting that will show all advanced storage devices [CHAR LIMIT=32] -->
+    <string name="pref_advanced_devices">Display advanced devices</string>
+    <!-- Title for setting that will show file sizes for all documents [CHAR LIMIT=32] -->
+    <string name="pref_file_size">Display file size</string>
+    <string name="pref_device_size">Display device size</string>
+
+    <!-- Text shown when a directory of documents is empty [CHAR LIMIT=24] -->
+    <string name="empty">No items</string>
+
+    <!-- Toast shown when no app can be found to open the selected document [CHAR LIMIT=48] -->
+    <string name="toast_no_application">Can\'t open file</string>
+    <!-- Toast shown when some of the selected documents failed to be deleted [CHAR LIMIT=48] -->
+    <string name="toast_failed_delete">Unable to delete some documents</string>
+
+    <!-- Title of dialog when prompting user to select an app to share documents with [CHAR LIMIT=32] -->
+    <string name="share_via">Share via</string>
+
+</resources>
diff --git a/packages/DocumentsUI/res/values/styles.xml b/packages/DocumentsUI/res/values/styles.xml
new file mode 100644
index 0000000..945e7ae
--- /dev/null
+++ b/packages/DocumentsUI/res/values/styles.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+    <style name="TextAppearance" />
+
+    <style name="TextAppearance.Medium">
+        <item name="android:textAppearance">?android:attr/textAppearanceMedium</item>
+        <item name="android:textColor">?android:attr/textColorSecondary</item>
+    </style>
+
+    <style name="TextAppearance.Small">
+        <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
+        <item name="android:textColor">?android:attr/textColorTertiary</item>
+    </style>
+
+    <!-- Normally just a redirection, but this is used to make ourselves a
+         dialog on large tablets -->
+    <style name="Theme" parent="@android:style/Theme.Holo.Light" />
+</resources>
diff --git a/packages/DocumentsUI/res/xml/preferences.xml b/packages/DocumentsUI/res/xml/preferences.xml
new file mode 100644
index 0000000..5589ff1
--- /dev/null
+++ b/packages/DocumentsUI/res/xml/preferences.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+    <CheckBoxPreference
+        android:title="@string/pref_advanced_devices"
+        android:defaultValue="false"
+        android:key="advancedDevices" />
+    <CheckBoxPreference
+        android:title="@string/pref_file_size"
+        android:defaultValue="false"
+        android:key="fileSize" />
+</PreferenceScreen>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/ColumnAdapter.java b/packages/DocumentsUI/src/com/android/documentsui/ColumnAdapter.java
new file mode 100644
index 0000000..092b5db
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/ColumnAdapter.java
@@ -0,0 +1,139 @@
+/*
+ * 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.documentsui;
+
+import android.database.DataSetObserver;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.LinearLayout;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * Adapter that wraps an existing adapter, presenting its contents in multiple
+ * equally-sized horizontal columns.
+ */
+public class ColumnAdapter extends BaseAdapter {
+    private final ListAdapter mWrapped;
+    private final OnItemClickListener mListener;
+
+    private int mColumns = 1;
+
+    public interface OnItemClickListener {
+        public void onItemClick(ListAdapter adapter, int position);
+    }
+
+    public ColumnAdapter(ListAdapter wrapped, OnItemClickListener listener) {
+        mWrapped = Preconditions.checkNotNull(wrapped);
+        mListener = Preconditions.checkNotNull(listener);
+
+        if (!wrapped.areAllItemsEnabled()) {
+            throw new IllegalStateException("All items must be enabled");
+        }
+        if (wrapped.getViewTypeCount() > 1) {
+            throw new IllegalStateException("All items must be identical");
+        }
+    }
+
+    public static void prepare(ListView list) {
+        list.setItemsCanFocus(true);
+    }
+
+    public void setColumns(int columns) {
+        mColumns = columns;
+        notifyDataSetChanged();
+    }
+
+    private View.OnClickListener mItemListener = new View.OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            final int position = (Integer) v.getTag();
+            mListener.onItemClick(mWrapped, position);
+        }
+    };
+
+    @Override
+    public int getCount() {
+        return (mWrapped.getCount() + mColumns - 1) / mColumns;
+    }
+
+    @Override
+    public Object getItem(int position) {
+        return position;
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return position;
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        if (convertView == null) {
+            convertView = new LinearLayout(parent.getContext());
+        }
+
+        final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
+                0, LinearLayout.LayoutParams.WRAP_CONTENT);
+        params.weight = 1f / mColumns;
+
+        final LinearLayout row = (LinearLayout) convertView;
+        final int first = position * mColumns;
+        final int last = mWrapped.getCount() - 1;
+
+        for (int i = 0; i < mColumns; i++) {
+            View convertItem = null;
+            if (i < row.getChildCount()) {
+                convertItem = row.getChildAt(i);
+            }
+
+            final int pos = first + i;
+            final int validPos = Math.min(pos, last);
+            final View item = mWrapped.getView(validPos, convertItem, row);
+            item.setTag(validPos);
+            item.setOnClickListener(mItemListener);
+            item.setFocusable(true);
+
+            if (pos == validPos) {
+                item.setVisibility(View.VISIBLE);
+            } else {
+                item.setVisibility(View.INVISIBLE);
+            }
+
+            if (convertItem == null) {
+                row.addView(item, params);
+            }
+        }
+
+        return convertView;
+    }
+
+    @Override
+    public void registerDataSetObserver(DataSetObserver observer) {
+        super.registerDataSetObserver(observer);
+        mWrapped.registerDataSetObserver(observer);
+    }
+
+    @Override
+    public void unregisterDataSetObserver(DataSetObserver observer) {
+        super.unregisterDataSetObserver(observer);
+        mWrapped.unregisterDataSetObserver(observer);
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
new file mode 100644
index 0000000..d8e60aa
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
@@ -0,0 +1,87 @@
+/*
+ * 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.documentsui;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.FragmentManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.DocumentsContract;
+import android.provider.DocumentsContract.Document;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.Toast;
+
+import com.android.documentsui.model.DocumentInfo;
+
+/**
+ * Dialog to create a new directory.
+ */
+public class CreateDirectoryFragment extends DialogFragment {
+    private static final String TAG_CREATE_DIRECTORY = "create_directory";
+
+    public static void show(FragmentManager fm) {
+        final CreateDirectoryFragment dialog = new CreateDirectoryFragment();
+        dialog.show(fm, TAG_CREATE_DIRECTORY);
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        final Context context = getActivity();
+        final ContentResolver resolver = context.getContentResolver();
+
+        final AlertDialog.Builder builder = new AlertDialog.Builder(context);
+        final LayoutInflater dialogInflater = LayoutInflater.from(builder.getContext());
+
+        final View view = dialogInflater.inflate(R.layout.dialog_create_dir, null, false);
+        final EditText text1 = (EditText) view.findViewById(android.R.id.text1);
+
+        builder.setTitle(R.string.menu_create_dir);
+        builder.setView(view);
+
+        builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
+            @Override
+            public void onClick(DialogInterface dialog, int which) {
+                final String displayName = text1.getText().toString();
+
+                final DocumentsActivity activity = (DocumentsActivity) getActivity();
+                final DocumentInfo cwd = activity.getCurrentDirectory();
+
+                try {
+                    final Uri childUri = DocumentsContract.createDocument(
+                            resolver, cwd.derivedUri, Document.MIME_TYPE_DIR, displayName);
+
+                    // Navigate into newly created child
+                    final DocumentInfo childDoc = DocumentInfo.fromUri(resolver, childUri);
+                    activity.onDocumentPicked(childDoc);
+                } catch (Exception e) {
+                    Toast.makeText(context, R.string.save_error, Toast.LENGTH_SHORT).show();
+                }
+            }
+        });
+        builder.setNegativeButton(android.R.string.cancel, null);
+
+        return builder.create();
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
new file mode 100644
index 0000000..198927c
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
@@ -0,0 +1,997 @@
+/*
+ * 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.documentsui;
+
+import static com.android.documentsui.DocumentsActivity.TAG;
+import static com.android.documentsui.DocumentsActivity.State.ACTION_MANAGE;
+import static com.android.documentsui.DocumentsActivity.State.MODE_GRID;
+import static com.android.documentsui.DocumentsActivity.State.MODE_LIST;
+import static com.android.documentsui.DocumentsActivity.State.MODE_UNKNOWN;
+import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_UNKNOWN;
+import static com.android.documentsui.model.DocumentInfo.getCursorInt;
+import static com.android.documentsui.model.DocumentInfo.getCursorLong;
+import static com.android.documentsui.model.DocumentInfo.getCursorString;
+
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.app.FragmentTransaction;
+import android.app.LoaderManager.LoaderCallbacks;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.content.Loader;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.Point;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.CancellationSignal;
+import android.provider.DocumentsContract;
+import android.provider.DocumentsContract.Document;
+import android.text.format.DateUtils;
+import android.text.format.Formatter;
+import android.text.format.Time;
+import android.util.Log;
+import android.util.SparseBooleanArray;
+import android.view.ActionMode;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AbsListView;
+import android.widget.AbsListView.MultiChoiceModeListener;
+import android.widget.AbsListView.RecyclerListener;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.BaseAdapter;
+import android.widget.GridView;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.android.documentsui.DocumentsActivity.State;
+import com.android.documentsui.RecentsProvider.StateColumns;
+import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.model.RootInfo;
+import com.android.internal.util.Predicate;
+import com.google.android.collect.Lists;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Display the documents inside a single directory.
+ */
+public class DirectoryFragment extends Fragment {
+
+    private View mEmptyView;
+    private ListView mListView;
+    private GridView mGridView;
+
+    private AbsListView mCurrentView;
+
+    private Predicate<DocumentInfo> mFilter;
+
+    public static final int TYPE_NORMAL = 1;
+    public static final int TYPE_SEARCH = 2;
+    public static final int TYPE_RECENT_OPEN = 3;
+
+    private int mType = TYPE_NORMAL;
+
+    private int mLastMode = MODE_UNKNOWN;
+    private int mLastSortOrder = SORT_ORDER_UNKNOWN;
+    private boolean mLastShowSize = false;
+
+    private boolean mHideGridTitles = false;
+
+    private Point mThumbSize;
+
+    private DocumentsAdapter mAdapter;
+    private LoaderCallbacks<DirectoryResult> mCallbacks;
+
+    private static final String EXTRA_TYPE = "type";
+    private static final String EXTRA_ROOT = "root";
+    private static final String EXTRA_DOC = "doc";
+    private static final String EXTRA_QUERY = "query";
+
+    private static AtomicInteger sLoaderId = new AtomicInteger(4000);
+
+    private final int mLoaderId = sLoaderId.incrementAndGet();
+
+    public static void showNormal(FragmentManager fm, RootInfo root, DocumentInfo doc) {
+        show(fm, TYPE_NORMAL, root, doc, null);
+    }
+
+    public static void showSearch(FragmentManager fm, RootInfo root, String query) {
+        show(fm, TYPE_SEARCH, root, null, query);
+    }
+
+    public static void showRecentsOpen(FragmentManager fm) {
+        show(fm, TYPE_RECENT_OPEN, null, null, null);
+    }
+
+    private static void show(
+            FragmentManager fm, int type, RootInfo root, DocumentInfo doc, String query) {
+        final Bundle args = new Bundle();
+        args.putInt(EXTRA_TYPE, type);
+        args.putParcelable(EXTRA_ROOT, root);
+        args.putParcelable(EXTRA_DOC, doc);
+        args.putString(EXTRA_QUERY, query);
+
+        final DirectoryFragment fragment = new DirectoryFragment();
+        fragment.setArguments(args);
+
+        final FragmentTransaction ft = fm.beginTransaction();
+        ft.replace(R.id.container_directory, fragment);
+        ft.commitAllowingStateLoss();
+    }
+
+    public static DirectoryFragment get(FragmentManager fm) {
+        // TODO: deal with multiple directories shown at once
+        return (DirectoryFragment) fm.findFragmentById(R.id.container_directory);
+    }
+
+    @Override
+    public View onCreateView(
+            LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        final Context context = inflater.getContext();
+        final View view = inflater.inflate(R.layout.fragment_directory, container, false);
+
+        mEmptyView = view.findViewById(android.R.id.empty);
+
+        mListView = (ListView) view.findViewById(R.id.list);
+        mListView.setOnItemClickListener(mItemListener);
+        mListView.setMultiChoiceModeListener(mMultiListener);
+        mListView.setRecyclerListener(mRecycleListener);
+
+        mGridView = (GridView) view.findViewById(R.id.grid);
+        mGridView.setOnItemClickListener(mItemListener);
+        mGridView.setMultiChoiceModeListener(mMultiListener);
+        mGridView.setRecyclerListener(mRecycleListener);
+
+        return view;
+    }
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+
+        final Context context = getActivity();
+        final State state = getDisplayState(DirectoryFragment.this);
+
+        final RootInfo root = getArguments().getParcelable(EXTRA_ROOT);
+        final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC);
+
+        mAdapter = new DocumentsAdapter();
+        mType = getArguments().getInt(EXTRA_TYPE);
+
+        if (mType == TYPE_RECENT_OPEN) {
+            // Hide titles when showing recents for picking images/videos
+            mHideGridTitles = MimePredicate.mimeMatches(
+                    MimePredicate.VISUAL_MIMES, state.acceptMimes);
+        } else {
+            mHideGridTitles = (doc != null) && doc.isGridTitlesHidden();
+        }
+
+        mCallbacks = new LoaderCallbacks<DirectoryResult>() {
+            @Override
+            public Loader<DirectoryResult> onCreateLoader(int id, Bundle args) {
+                final String query = getArguments().getString(EXTRA_QUERY);
+
+                Uri contentsUri;
+                switch (mType) {
+                    case TYPE_NORMAL:
+                        contentsUri = DocumentsContract.buildChildDocumentsUri(
+                                doc.authority, doc.documentId);
+                        if (state.action == ACTION_MANAGE) {
+                            contentsUri = DocumentsContract.setManageMode(contentsUri);
+                        }
+                        return new DirectoryLoader(
+                                context, mType, root, doc, contentsUri, state.userSortOrder);
+                    case TYPE_SEARCH:
+                        contentsUri = DocumentsContract.buildSearchDocumentsUri(
+                                root.authority, root.rootId, query);
+                        if (state.action == ACTION_MANAGE) {
+                            contentsUri = DocumentsContract.setManageMode(contentsUri);
+                        }
+                        return new DirectoryLoader(
+                                context, mType, root, doc, contentsUri, state.userSortOrder);
+                    case TYPE_RECENT_OPEN:
+                        final RootsCache roots = DocumentsApplication.getRootsCache(context);
+                        final List<RootInfo> matchingRoots = roots.getMatchingRoots(state);
+                        return new RecentLoader(context, matchingRoots, state.acceptMimes);
+                    default:
+                        throw new IllegalStateException("Unknown type " + mType);
+                }
+            }
+
+            @Override
+            public void onLoadFinished(Loader<DirectoryResult> loader, DirectoryResult result) {
+                if (!isAdded()) return;
+
+                mAdapter.swapCursor(result.cursor);
+
+                // Push latest state up to UI
+                // TODO: if mode change was racing with us, don't overwrite it
+                if (result.mode != MODE_UNKNOWN) {
+                    state.derivedMode = result.mode;
+                }
+                state.derivedSortOrder = result.sortOrder;
+                ((DocumentsActivity) context).onStateChanged();
+
+                updateDisplayState();
+
+                if (mLastSortOrder != state.derivedSortOrder) {
+                    mLastSortOrder = state.derivedSortOrder;
+                    mListView.smoothScrollToPosition(0);
+                    mGridView.smoothScrollToPosition(0);
+                }
+            }
+
+            @Override
+            public void onLoaderReset(Loader<DirectoryResult> loader) {
+                mAdapter.swapCursor(null);
+            }
+        };
+
+        // Kick off loader at least once
+        getLoaderManager().restartLoader(mLoaderId, null, mCallbacks);
+
+        updateDisplayState();
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        updateDisplayState();
+    }
+
+    public void onUserSortOrderChanged() {
+        // Sort order change always triggers reload; we'll trigger state change
+        // on the flip side.
+        getLoaderManager().restartLoader(mLoaderId, null, mCallbacks);
+    }
+
+    public void onUserModeChanged() {
+        final ContentResolver resolver = getActivity().getContentResolver();
+        final State state = getDisplayState(this);
+
+        final RootInfo root = getArguments().getParcelable(EXTRA_ROOT);
+        final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC);
+
+        if (root != null && doc != null) {
+            final Uri stateUri = RecentsProvider.buildState(
+                    root.authority, root.rootId, doc.documentId);
+            final ContentValues values = new ContentValues();
+            values.put(StateColumns.MODE, state.userMode);
+
+            new AsyncTask<Void, Void, Void>() {
+                @Override
+                protected Void doInBackground(Void... params) {
+                    resolver.insert(stateUri, values);
+                    return null;
+                }
+            }.execute();
+        }
+
+        // Mode change is just visual change; no need to kick loader, and
+        // deliver change event immediately.
+        state.derivedMode = state.userMode;
+        ((DocumentsActivity) getActivity()).onStateChanged();
+
+        updateDisplayState();
+    }
+
+    private void updateDisplayState() {
+        final State state = getDisplayState(this);
+
+        mFilter = new MimePredicate(state.acceptMimes);
+
+        if (mLastMode == state.derivedMode && mLastShowSize == state.showSize) return;
+        mLastMode = state.derivedMode;
+        mLastShowSize = state.showSize;
+
+        mListView.setVisibility(state.derivedMode == MODE_LIST ? View.VISIBLE : View.GONE);
+        mGridView.setVisibility(state.derivedMode == MODE_GRID ? View.VISIBLE : View.GONE);
+
+        final int choiceMode;
+        if (state.allowMultiple) {
+            choiceMode = ListView.CHOICE_MODE_MULTIPLE_MODAL;
+        } else {
+            choiceMode = ListView.CHOICE_MODE_NONE;
+        }
+
+        final int thumbSize;
+        if (state.derivedMode == MODE_GRID) {
+            thumbSize = getResources().getDimensionPixelSize(R.dimen.grid_width);
+            mListView.setAdapter(null);
+            mListView.setChoiceMode(ListView.CHOICE_MODE_NONE);
+            mGridView.setAdapter(mAdapter);
+            mGridView.setColumnWidth(getResources().getDimensionPixelSize(R.dimen.grid_width));
+            mGridView.setNumColumns(GridView.AUTO_FIT);
+            mGridView.setChoiceMode(choiceMode);
+            mCurrentView = mGridView;
+        } else if (state.derivedMode == MODE_LIST) {
+            thumbSize = getResources().getDimensionPixelSize(R.dimen.icon_size);
+            mGridView.setAdapter(null);
+            mGridView.setChoiceMode(ListView.CHOICE_MODE_NONE);
+            mListView.setAdapter(mAdapter);
+            mListView.setChoiceMode(choiceMode);
+            mCurrentView = mListView;
+        } else {
+            throw new IllegalStateException("Unknown state " + state.derivedMode);
+        }
+
+        mThumbSize = new Point(thumbSize, thumbSize);
+    }
+
+    private OnItemClickListener mItemListener = new OnItemClickListener() {
+        @Override
+        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+            final Cursor cursor = mAdapter.getItem(position);
+            if (cursor != null) {
+                final DocumentInfo doc = DocumentInfo.fromDirectoryCursor(cursor);
+                if (mFilter.apply(doc)) {
+                    ((DocumentsActivity) getActivity()).onDocumentPicked(doc);
+                }
+            }
+        }
+    };
+
+    private MultiChoiceModeListener mMultiListener = new MultiChoiceModeListener() {
+        @Override
+        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+            mode.getMenuInflater().inflate(R.menu.mode_directory, menu);
+            return true;
+        }
+
+        @Override
+        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+            final State state = getDisplayState(DirectoryFragment.this);
+
+            final MenuItem open = menu.findItem(R.id.menu_open);
+            final MenuItem share = menu.findItem(R.id.menu_share);
+            final MenuItem delete = menu.findItem(R.id.menu_delete);
+
+            final boolean manageMode = state.action == ACTION_MANAGE;
+            open.setVisible(!manageMode);
+            share.setVisible(manageMode);
+            delete.setVisible(manageMode);
+
+            return true;
+        }
+
+        @Override
+        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+            final SparseBooleanArray checked = mCurrentView.getCheckedItemPositions();
+            final ArrayList<DocumentInfo> docs = Lists.newArrayList();
+            final int size = checked.size();
+            for (int i = 0; i < size; i++) {
+                if (checked.valueAt(i)) {
+                    final Cursor cursor = mAdapter.getItem(checked.keyAt(i));
+                    final DocumentInfo doc = DocumentInfo.fromDirectoryCursor(cursor);
+                    docs.add(doc);
+                }
+            }
+
+            final int id = item.getItemId();
+            if (id == R.id.menu_open) {
+                DocumentsActivity.get(DirectoryFragment.this).onDocumentsPicked(docs);
+                mode.finish();
+                return true;
+
+            } else if (id == R.id.menu_share) {
+                onShareDocuments(docs);
+                mode.finish();
+                return true;
+
+            } else if (id == R.id.menu_delete) {
+                onDeleteDocuments(docs);
+                mode.finish();
+                return true;
+
+            } else {
+                return false;
+            }
+        }
+
+        @Override
+        public void onDestroyActionMode(ActionMode mode) {
+            // ignored
+        }
+
+        @Override
+        public void onItemCheckedStateChanged(
+                ActionMode mode, int position, long id, boolean checked) {
+            if (checked) {
+                // Directories and footer items cannot be checked
+                boolean valid = false;
+
+                final Cursor cursor = mAdapter.getItem(position);
+                if (cursor != null) {
+                    final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
+
+                    // Only valid if non-directory matches filter
+                    final State state = getDisplayState(DirectoryFragment.this);
+                    valid = !Document.MIME_TYPE_DIR.equals(docMimeType)
+                            && MimePredicate.mimeMatches(state.acceptMimes, docMimeType);
+                }
+
+                if (!valid) {
+                    mCurrentView.setItemChecked(position, false);
+                }
+            }
+
+            mode.setTitle(getResources()
+                    .getString(R.string.mode_selected_count, mCurrentView.getCheckedItemCount()));
+        }
+    };
+
+    private RecyclerListener mRecycleListener = new RecyclerListener() {
+        @Override
+        public void onMovedToScrapHeap(View view) {
+            final ImageView iconThumb = (ImageView) view.findViewById(R.id.icon_thumb);
+            if (iconThumb != null) {
+                final ThumbnailAsyncTask oldTask = (ThumbnailAsyncTask) iconThumb.getTag();
+                if (oldTask != null) {
+                    oldTask.reallyCancel();
+                    iconThumb.setTag(null);
+                }
+            }
+        }
+    };
+
+    private void onShareDocuments(List<DocumentInfo> docs) {
+        Intent intent;
+        if (docs.size() == 1) {
+            final DocumentInfo doc = docs.get(0);
+
+            intent = new Intent(Intent.ACTION_SEND);
+            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+            intent.addCategory(Intent.CATEGORY_DEFAULT);
+            intent.setType(doc.mimeType);
+            intent.putExtra(Intent.EXTRA_STREAM, doc.derivedUri);
+
+        } else if (docs.size() > 1) {
+            intent = new Intent(Intent.ACTION_SEND_MULTIPLE);
+            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+            intent.addCategory(Intent.CATEGORY_DEFAULT);
+
+            final ArrayList<String> mimeTypes = Lists.newArrayList();
+            final ArrayList<Uri> uris = Lists.newArrayList();
+            for (DocumentInfo doc : docs) {
+                mimeTypes.add(doc.mimeType);
+                uris.add(doc.derivedUri);
+            }
+
+            intent.setType(findCommonMimeType(mimeTypes));
+            intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
+
+        } else {
+            return;
+        }
+
+        intent = Intent.createChooser(intent, getActivity().getText(R.string.share_via));
+        startActivity(intent);
+    }
+
+    private void onDeleteDocuments(List<DocumentInfo> docs) {
+        final Context context = getActivity();
+        final ContentResolver resolver = context.getContentResolver();
+
+        boolean hadTrouble = false;
+        for (DocumentInfo doc : docs) {
+            if (!doc.isDeleteSupported()) {
+                Log.w(TAG, "Skipping " + doc);
+                hadTrouble = true;
+                continue;
+            }
+
+            if (!DocumentsContract.deleteDocument(resolver, doc.derivedUri)) {
+                Log.w(TAG, "Failed to delete " + doc);
+                hadTrouble = true;
+            }
+        }
+
+        if (hadTrouble) {
+            Toast.makeText(context, R.string.toast_failed_delete, Toast.LENGTH_SHORT).show();
+        }
+    }
+
+    private static State getDisplayState(Fragment fragment) {
+        return ((DocumentsActivity) fragment.getActivity()).getDisplayState();
+    }
+
+    private static abstract class Footer {
+        private final int mItemViewType;
+
+        public Footer(int itemViewType) {
+            mItemViewType = itemViewType;
+        }
+
+        public abstract View getView(View convertView, ViewGroup parent);
+
+        public int getItemViewType() {
+            return mItemViewType;
+        }
+    }
+
+    private class LoadingFooter extends Footer {
+        public LoadingFooter() {
+            super(1);
+        }
+
+        @Override
+        public View getView(View convertView, ViewGroup parent) {
+            final Context context = parent.getContext();
+            final State state = getDisplayState(DirectoryFragment.this);
+
+            if (convertView == null) {
+                final LayoutInflater inflater = LayoutInflater.from(context);
+                if (state.derivedMode == MODE_LIST) {
+                    convertView = inflater.inflate(R.layout.item_loading_list, parent, false);
+                } else if (state.derivedMode == MODE_GRID) {
+                    convertView = inflater.inflate(R.layout.item_loading_grid, parent, false);
+                } else {
+                    throw new IllegalStateException();
+                }
+            }
+
+            return convertView;
+        }
+    }
+
+    private class MessageFooter extends Footer {
+        private final int mIcon;
+        private final String mMessage;
+
+        public MessageFooter(int itemViewType, int icon, String message) {
+            super(itemViewType);
+            mIcon = icon;
+            mMessage = message;
+        }
+
+        @Override
+        public View getView(View convertView, ViewGroup parent) {
+            final Context context = parent.getContext();
+            final State state = getDisplayState(DirectoryFragment.this);
+
+            if (convertView == null) {
+                final LayoutInflater inflater = LayoutInflater.from(context);
+                if (state.derivedMode == MODE_LIST) {
+                    convertView = inflater.inflate(R.layout.item_message_list, parent, false);
+                } else if (state.derivedMode == MODE_GRID) {
+                    convertView = inflater.inflate(R.layout.item_message_grid, parent, false);
+                } else {
+                    throw new IllegalStateException();
+                }
+            }
+
+            final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon);
+            final TextView title = (TextView) convertView.findViewById(android.R.id.title);
+            icon.setImageResource(mIcon);
+            title.setText(mMessage);
+            return convertView;
+        }
+    }
+
+    private class DocumentsAdapter extends BaseAdapter {
+        private Cursor mCursor;
+        private int mCursorCount;
+
+        private List<Footer> mFooters = Lists.newArrayList();
+
+        public void swapCursor(Cursor cursor) {
+            mCursor = cursor;
+            mCursorCount = cursor != null ? cursor.getCount() : 0;
+
+            mFooters.clear();
+
+            final Bundle extras = cursor != null ? cursor.getExtras() : null;
+            if (extras != null) {
+                final String info = extras.getString(DocumentsContract.EXTRA_INFO);
+                if (info != null) {
+                    mFooters.add(new MessageFooter(2, R.drawable.ic_dialog_alert, info));
+                }
+                final String error = extras.getString(DocumentsContract.EXTRA_ERROR);
+                if (error != null) {
+                    mFooters.add(new MessageFooter(3, R.drawable.ic_dialog_alert, error));
+                }
+                if (extras.getBoolean(DocumentsContract.EXTRA_LOADING, false)) {
+                    mFooters.add(new LoadingFooter());
+                }
+            }
+
+            if (isEmpty()) {
+                mEmptyView.setVisibility(View.VISIBLE);
+            } else {
+                mEmptyView.setVisibility(View.GONE);
+            }
+
+            notifyDataSetChanged();
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            if (position < mCursorCount) {
+                return getDocumentView(position, convertView, parent);
+            } else {
+                position -= mCursorCount;
+                convertView = mFooters.get(position).getView(convertView, parent);
+                // Only the view itself is disabled; contents inside shouldn't
+                // be dimmed.
+                convertView.setEnabled(false);
+                return convertView;
+            }
+        }
+
+        private View getDocumentView(int position, View convertView, ViewGroup parent) {
+            final Context context = parent.getContext();
+            final State state = getDisplayState(DirectoryFragment.this);
+
+            final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC);
+
+            final RootsCache roots = DocumentsApplication.getRootsCache(context);
+            final ThumbnailCache thumbs = DocumentsApplication.getThumbnailsCache(
+                    context, mThumbSize);
+
+            if (convertView == null) {
+                final LayoutInflater inflater = LayoutInflater.from(context);
+                if (state.derivedMode == MODE_LIST) {
+                    convertView = inflater.inflate(R.layout.item_doc_list, parent, false);
+                } else if (state.derivedMode == MODE_GRID) {
+                    convertView = inflater.inflate(R.layout.item_doc_grid, parent, false);
+                } else {
+                    throw new IllegalStateException();
+                }
+            }
+
+            final Cursor cursor = getItem(position);
+
+            final String docAuthority = getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY);
+            final String docRootId = getCursorString(cursor, RootCursorWrapper.COLUMN_ROOT_ID);
+            final String docId = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID);
+            final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
+            final String docDisplayName = getCursorString(cursor, Document.COLUMN_DISPLAY_NAME);
+            final long docLastModified = getCursorLong(cursor, Document.COLUMN_LAST_MODIFIED);
+            final int docIcon = getCursorInt(cursor, Document.COLUMN_ICON);
+            final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
+            final String docSummary = getCursorString(cursor, Document.COLUMN_SUMMARY);
+            final long docSize = getCursorLong(cursor, Document.COLUMN_SIZE);
+
+            final View line1 = convertView.findViewById(R.id.line1);
+            final View line2 = convertView.findViewById(R.id.line2);
+
+            final View icon = convertView.findViewById(android.R.id.icon);
+            final ImageView iconMime = (ImageView) convertView.findViewById(R.id.icon_mime);
+            final ImageView iconThumb = (ImageView) convertView.findViewById(R.id.icon_thumb);
+            final TextView title = (TextView) convertView.findViewById(android.R.id.title);
+            final ImageView icon1 = (ImageView) convertView.findViewById(android.R.id.icon1);
+            final ImageView icon2 = (ImageView) convertView.findViewById(android.R.id.icon2);
+            final TextView summary = (TextView) convertView.findViewById(android.R.id.summary);
+            final TextView date = (TextView) convertView.findViewById(R.id.date);
+            final TextView size = (TextView) convertView.findViewById(R.id.size);
+
+            final ThumbnailAsyncTask oldTask = (ThumbnailAsyncTask) iconThumb.getTag();
+            if (oldTask != null) {
+                oldTask.reallyCancel();
+                iconThumb.setTag(null);
+            }
+
+            iconMime.animate().cancel();
+            iconThumb.animate().cancel();
+
+            final boolean supportsThumbnail = (docFlags & Document.FLAG_SUPPORTS_THUMBNAIL) != 0;
+            final boolean allowThumbnail = (state.derivedMode == MODE_GRID)
+                    || MimePredicate.mimeMatches(MimePredicate.VISUAL_MIMES, docMimeType);
+            final boolean showThumbnail = supportsThumbnail && allowThumbnail;
+
+            boolean cacheHit = false;
+            if (showThumbnail) {
+                final Uri uri = DocumentsContract.buildDocumentUri(docAuthority, docId);
+                final Bitmap cachedResult = thumbs.get(uri);
+                if (cachedResult != null) {
+                    iconThumb.setImageBitmap(cachedResult);
+                    cacheHit = true;
+                } else {
+                    iconThumb.setImageDrawable(null);
+                    final ThumbnailAsyncTask task = new ThumbnailAsyncTask(
+                            uri, iconMime, iconThumb, mThumbSize);
+                    iconThumb.setTag(task);
+                    task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+                }
+            }
+
+            // Always throw MIME icon into place, even when a thumbnail is being
+            // loaded in background.
+            if (cacheHit) {
+                iconMime.setAlpha(0f);
+                iconThumb.setAlpha(1f);
+            } else {
+                iconMime.setAlpha(1f);
+                iconThumb.setAlpha(0f);
+                if (docIcon != 0) {
+                    iconMime.setImageDrawable(
+                            IconUtils.loadPackageIcon(context, docAuthority, docIcon));
+                } else {
+                    iconMime.setImageDrawable(IconUtils.loadMimeIcon(context, docMimeType));
+                }
+            }
+
+            boolean hasLine1 = false;
+            boolean hasLine2 = false;
+
+            final boolean hideTitle = (state.derivedMode == MODE_GRID) && mHideGridTitles;
+            if (!hideTitle) {
+                title.setText(docDisplayName);
+                hasLine1 = true;
+            }
+
+            Drawable iconDrawable = null;
+            if (mType == TYPE_RECENT_OPEN) {
+                final RootInfo root = roots.getRoot(docAuthority, docRootId);
+                iconDrawable = root.loadIcon(context);
+
+                if (summary != null) {
+                    final boolean alwaysShowSummary = getResources()
+                            .getBoolean(R.bool.always_show_summary);
+                    if (alwaysShowSummary) {
+                        summary.setText(root.getDirectoryString());
+                        summary.setVisibility(View.VISIBLE);
+                        hasLine2 = true;
+                    } else {
+                        if (iconDrawable != null && roots.isIconUnique(root)) {
+                            // No summary needed if icon speaks for itself
+                            summary.setVisibility(View.INVISIBLE);
+                        } else {
+                            summary.setText(root.getDirectoryString());
+                            summary.setVisibility(View.VISIBLE);
+                            summary.setTextAlignment(TextView.TEXT_ALIGNMENT_TEXT_END);
+                            hasLine2 = true;
+                        }
+                    }
+                }
+            } else {
+                // Directories showing thumbnails in grid mode get a little icon
+                // hint to remind user they're a directory.
+                if (Document.MIME_TYPE_DIR.equals(docMimeType) && state.derivedMode == MODE_GRID
+                        && showThumbnail) {
+                    iconDrawable = context.getResources().getDrawable(R.drawable.ic_root_folder);
+                }
+
+                if (summary != null) {
+                    if (docSummary != null) {
+                        summary.setText(docSummary);
+                        summary.setVisibility(View.VISIBLE);
+                        hasLine2 = true;
+                    } else {
+                        summary.setVisibility(View.INVISIBLE);
+                    }
+                }
+            }
+
+            if (icon1 != null) icon1.setVisibility(View.GONE);
+            if (icon2 != null) icon2.setVisibility(View.GONE);
+
+            if (iconDrawable != null) {
+                if (hasLine1) {
+                    icon1.setVisibility(View.VISIBLE);
+                    icon1.setImageDrawable(iconDrawable);
+                } else {
+                    icon2.setVisibility(View.VISIBLE);
+                    icon2.setImageDrawable(iconDrawable);
+                }
+            }
+
+            if (docLastModified == -1) {
+                date.setText(null);
+            } else {
+                date.setText(formatTime(context, docLastModified));
+                hasLine2 = true;
+            }
+
+            if (state.showSize) {
+                size.setVisibility(View.VISIBLE);
+                if (Document.MIME_TYPE_DIR.equals(docMimeType) || docSize == -1) {
+                    size.setText(null);
+                } else {
+                    size.setText(Formatter.formatFileSize(context, docSize));
+                    hasLine2 = true;
+                }
+            } else {
+                size.setVisibility(View.GONE);
+            }
+
+            if (line1 != null) {
+                line1.setVisibility(hasLine1 ? View.VISIBLE : View.GONE);
+            }
+            if (line2 != null) {
+                line2.setVisibility(hasLine2 ? View.VISIBLE : View.GONE);
+            }
+
+            final boolean enabled = Document.MIME_TYPE_DIR.equals(docMimeType)
+                    || MimePredicate.mimeMatches(state.acceptMimes, docMimeType);
+            if (enabled) {
+                setEnabledRecursive(convertView, true);
+                icon.setAlpha(1f);
+                if (icon1 != null) icon1.setAlpha(1f);
+                if (icon2 != null) icon2.setAlpha(1f);
+            } else {
+                setEnabledRecursive(convertView, false);
+                icon.setAlpha(0.5f);
+                if (icon1 != null) icon1.setAlpha(0.5f);
+                if (icon2 != null) icon2.setAlpha(0.5f);
+            }
+
+            return convertView;
+        }
+
+        @Override
+        public int getCount() {
+            return mCursorCount + mFooters.size();
+        }
+
+        @Override
+        public Cursor getItem(int position) {
+            if (position < mCursorCount) {
+                mCursor.moveToPosition(position);
+                return mCursor;
+            } else {
+                return null;
+            }
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return position;
+        }
+
+        @Override
+        public int getViewTypeCount() {
+            return 4;
+        }
+
+        @Override
+        public int getItemViewType(int position) {
+            if (position < mCursorCount) {
+                return 0;
+            } else {
+                position -= mCursorCount;
+                return mFooters.get(position).getItemViewType();
+            }
+        }
+    }
+
+    private static class ThumbnailAsyncTask extends AsyncTask<Uri, Void, Bitmap> {
+        private final Uri mUri;
+        private final ImageView mIconMime;
+        private final ImageView mIconThumb;
+        private final Point mThumbSize;
+        private final CancellationSignal mSignal;
+
+        public ThumbnailAsyncTask(
+                Uri uri, ImageView iconMime, ImageView iconThumb, Point thumbSize) {
+            mUri = uri;
+            mIconMime = iconMime;
+            mIconThumb = iconThumb;
+            mThumbSize = thumbSize;
+            mSignal = new CancellationSignal();
+        }
+
+        public void reallyCancel() {
+            cancel(false);
+            mSignal.cancel();
+        }
+
+        @Override
+        protected Bitmap doInBackground(Uri... params) {
+            final Context context = mIconThumb.getContext();
+
+            Bitmap result = null;
+            try {
+                // TODO: switch to using unstable provider
+                result = DocumentsContract.getDocumentThumbnail(
+                        context.getContentResolver(), mUri, mThumbSize, mSignal);
+                if (result != null) {
+                    final ThumbnailCache thumbs = DocumentsApplication.getThumbnailsCache(
+                            context, mThumbSize);
+                    thumbs.put(mUri, result);
+                }
+            } catch (Exception e) {
+                Log.w(TAG, "Failed to load thumbnail: " + e);
+            }
+            return result;
+        }
+
+        @Override
+        protected void onPostExecute(Bitmap result) {
+            if (mIconThumb.getTag() == this && result != null) {
+                mIconThumb.setTag(null);
+                mIconThumb.setImageBitmap(result);
+
+                mIconMime.setAlpha(1f);
+                mIconMime.animate().alpha(0f).start();
+                mIconThumb.setAlpha(0f);
+                mIconThumb.animate().alpha(1f).start();
+            }
+        }
+    }
+
+    private static String formatTime(Context context, long when) {
+        // TODO: DateUtils should make this easier
+        Time then = new Time();
+        then.set(when);
+        Time now = new Time();
+        now.setToNow();
+
+        int flags = DateUtils.FORMAT_NO_NOON | DateUtils.FORMAT_NO_MIDNIGHT
+                | DateUtils.FORMAT_ABBREV_ALL;
+
+        if (then.year != now.year) {
+            flags |= DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_SHOW_DATE;
+        } else if (then.yearDay != now.yearDay) {
+            flags |= DateUtils.FORMAT_SHOW_DATE;
+        } else {
+            flags |= DateUtils.FORMAT_SHOW_TIME;
+        }
+
+        return DateUtils.formatDateTime(context, when, flags);
+    }
+
+    private String findCommonMimeType(List<String> mimeTypes) {
+        String[] commonType = mimeTypes.get(0).split("/");
+        if (commonType.length != 2) {
+            return "*/*";
+        }
+
+        for (int i = 1; i < mimeTypes.size(); i++) {
+            String[] type = mimeTypes.get(i).split("/");
+            if (type.length != 2) continue;
+
+            if (!commonType[1].equals(type[1])) {
+                commonType[1] = "*";
+            }
+
+            if (!commonType[0].equals(type[0])) {
+                commonType[0] = "*";
+                commonType[1] = "*";
+                break;
+            }
+        }
+
+        return commonType[0] + "/" + commonType[1];
+    }
+
+    private void setEnabledRecursive(View v, boolean enabled) {
+        if (v == null) return;
+        if (v.isEnabled() == enabled) return;
+        v.setEnabled(enabled);
+
+        if (v instanceof ViewGroup) {
+            final ViewGroup vg = (ViewGroup) v;
+            for (int i = vg.getChildCount() - 1; i >= 0; i--) {
+                setEnabledRecursive(vg.getChildAt(i), enabled);
+            }
+        }
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java
new file mode 100644
index 0000000..8627ecf
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java
@@ -0,0 +1,262 @@
+/*
+ * 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.documentsui;
+
+import static com.android.documentsui.DocumentsActivity.TAG;
+import static com.android.documentsui.DocumentsActivity.State.MODE_UNKNOWN;
+import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_DISPLAY_NAME;
+import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_LAST_MODIFIED;
+import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_SIZE;
+import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_UNKNOWN;
+import static com.android.documentsui.model.DocumentInfo.getCursorInt;
+
+import android.content.AsyncTaskLoader;
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.CancellationSignal;
+import android.os.OperationCanceledException;
+import android.provider.DocumentsContract;
+import android.provider.DocumentsContract.Document;
+import android.util.Log;
+
+import com.android.documentsui.DocumentsActivity.State;
+import com.android.documentsui.RecentsProvider.StateColumns;
+import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.model.RootInfo;
+
+import libcore.io.IoUtils;
+
+import java.io.FileNotFoundException;
+
+class DirectoryResult implements AutoCloseable {
+    ContentProviderClient client;
+    Cursor cursor;
+    Exception exception;
+
+    int mode = MODE_UNKNOWN;
+    int sortOrder = SORT_ORDER_UNKNOWN;
+
+    @Override
+    public void close() {
+        IoUtils.closeQuietly(cursor);
+        ContentProviderClient.closeQuietly(client);
+        cursor = null;
+        client = null;
+    }
+}
+
+public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> {
+    private final ForceLoadContentObserver mObserver = new ForceLoadContentObserver();
+
+    private final int mType;
+    private final RootInfo mRoot;
+    private DocumentInfo mDoc;
+    private final Uri mUri;
+    private final int mUserSortOrder;
+
+    private CancellationSignal mSignal;
+    private DirectoryResult mResult;
+
+    public DirectoryLoader(Context context, int type, RootInfo root, DocumentInfo doc, Uri uri,
+            int userSortOrder) {
+        super(context);
+        mType = type;
+        mRoot = root;
+        mDoc = doc;
+        mUri = uri;
+        mUserSortOrder = userSortOrder;
+    }
+
+    @Override
+    public final DirectoryResult loadInBackground() {
+        synchronized (this) {
+            if (isLoadInBackgroundCanceled()) {
+                throw new OperationCanceledException();
+            }
+            mSignal = new CancellationSignal();
+        }
+
+        final ContentResolver resolver = getContext().getContentResolver();
+        final String authority = mUri.getAuthority();
+
+        final DirectoryResult result = new DirectoryResult();
+
+        int userMode = State.MODE_UNKNOWN;
+
+        // Use default document when searching
+        if (mType == DirectoryFragment.TYPE_SEARCH) {
+            final Uri docUri = DocumentsContract.buildDocumentUri(
+                    mRoot.authority, mRoot.documentId);
+            try {
+                mDoc = DocumentInfo.fromUri(resolver, docUri);
+            } catch (FileNotFoundException e) {
+                Log.w(TAG, "Failed to query", e);
+                result.exception = e;
+                return result;
+            }
+        }
+
+        // Pick up any custom modes requested by user
+        Cursor cursor = null;
+        try {
+            final Uri stateUri = RecentsProvider.buildState(
+                    mRoot.authority, mRoot.rootId, mDoc.documentId);
+            cursor = resolver.query(stateUri, null, null, null, null);
+            if (cursor.moveToFirst()) {
+                userMode = getCursorInt(cursor, StateColumns.MODE);
+            }
+        } finally {
+            IoUtils.closeQuietly(cursor);
+        }
+
+        if (userMode != State.MODE_UNKNOWN) {
+            result.mode = userMode;
+        } else {
+            if ((mDoc.flags & Document.FLAG_DIR_PREFERS_GRID) != 0) {
+                result.mode = State.MODE_GRID;
+            } else {
+                result.mode = State.MODE_LIST;
+            }
+        }
+
+        if (mUserSortOrder != State.SORT_ORDER_UNKNOWN) {
+            result.sortOrder = mUserSortOrder;
+        } else {
+            if ((mDoc.flags & Document.FLAG_DIR_PREFERS_LAST_MODIFIED) != 0) {
+                result.sortOrder = State.SORT_ORDER_LAST_MODIFIED;
+            } else {
+                result.sortOrder = State.SORT_ORDER_DISPLAY_NAME;
+            }
+        }
+
+        // Search always uses ranking from provider
+        if (mType == DirectoryFragment.TYPE_SEARCH) {
+            result.sortOrder = State.SORT_ORDER_UNKNOWN;
+        }
+
+        Log.d(TAG, "userMode=" + userMode + ", userSortOrder=" + mUserSortOrder + " --> mode="
+                + result.mode + ", sortOrder=" + result.sortOrder);
+
+        try {
+            result.client = resolver.acquireUnstableContentProviderClient(authority);
+            cursor = result.client.query(
+                    mUri, null, null, null, getQuerySortOrder(result.sortOrder), mSignal);
+            cursor.registerContentObserver(mObserver);
+
+            cursor = new RootCursorWrapper(mUri.getAuthority(), mRoot.rootId, cursor, -1);
+
+            if (mType == DirectoryFragment.TYPE_SEARCH) {
+                // Filter directories out of search results, for now
+                cursor = new FilteringCursorWrapper(cursor, null, new String[] {
+                        Document.MIME_TYPE_DIR });
+            } else {
+                // Normal directories should have sorting applied
+                cursor = new SortingCursorWrapper(cursor, result.sortOrder);
+            }
+
+            result.cursor = cursor;
+        } catch (Exception e) {
+            Log.w(TAG, "Failed to query", e);
+            result.exception = e;
+            ContentProviderClient.closeQuietly(result.client);
+        } finally {
+            synchronized (this) {
+                mSignal = null;
+            }
+        }
+
+        return result;
+    }
+
+    @Override
+    public void cancelLoadInBackground() {
+        super.cancelLoadInBackground();
+
+        synchronized (this) {
+            if (mSignal != null) {
+                mSignal.cancel();
+            }
+        }
+    }
+
+    @Override
+    public void deliverResult(DirectoryResult result) {
+        if (isReset()) {
+            IoUtils.closeQuietly(result);
+            return;
+        }
+        DirectoryResult oldResult = mResult;
+        mResult = result;
+
+        if (isStarted()) {
+            super.deliverResult(result);
+        }
+
+        if (oldResult != null && oldResult != result) {
+            IoUtils.closeQuietly(oldResult);
+        }
+    }
+
+    @Override
+    protected void onStartLoading() {
+        if (mResult != null) {
+            deliverResult(mResult);
+        }
+        if (takeContentChanged() || mResult == null) {
+            forceLoad();
+        }
+    }
+
+    @Override
+    protected void onStopLoading() {
+        cancelLoad();
+    }
+
+    @Override
+    public void onCanceled(DirectoryResult result) {
+        IoUtils.closeQuietly(result);
+    }
+
+    @Override
+    protected void onReset() {
+        super.onReset();
+
+        // Ensure the loader is stopped
+        onStopLoading();
+
+        IoUtils.closeQuietly(mResult);
+        mResult = null;
+
+        getContext().getContentResolver().unregisterContentObserver(mObserver);
+    }
+
+    public static String getQuerySortOrder(int sortOrder) {
+        switch (sortOrder) {
+            case SORT_ORDER_DISPLAY_NAME:
+                return Document.COLUMN_DISPLAY_NAME + " ASC";
+            case SORT_ORDER_LAST_MODIFIED:
+                return Document.COLUMN_LAST_MODIFIED + " DESC";
+            case SORT_ORDER_SIZE:
+                return Document.COLUMN_SIZE + " DESC";
+            default:
+                return null;
+        }
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentChangedReceiver.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentChangedReceiver.java
new file mode 100644
index 0000000..54f62ef
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentChangedReceiver.java
@@ -0,0 +1,36 @@
+/*
+ * 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.documentsui;
+
+import static com.android.documentsui.DocumentsActivity.TAG;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+/**
+ * Handles changes which invalidate cached data.
+ */
+public class DocumentChangedReceiver extends BroadcastReceiver {
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        Log.d(TAG, "Regenerating roots cache");
+        DocumentsApplication.getRootsCache(context).update();
+        // TODO: invalidate cached data in recents provider
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
new file mode 100644
index 0000000..f6cb481
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
@@ -0,0 +1,997 @@
+/*
+ * 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.documentsui;
+
+import static com.android.documentsui.DocumentsActivity.State.ACTION_CREATE;
+import static com.android.documentsui.DocumentsActivity.State.ACTION_GET_CONTENT;
+import static com.android.documentsui.DocumentsActivity.State.ACTION_MANAGE;
+import static com.android.documentsui.DocumentsActivity.State.ACTION_OPEN;
+import static com.android.documentsui.DocumentsActivity.State.MODE_GRID;
+import static com.android.documentsui.DocumentsActivity.State.MODE_LIST;
+
+import android.app.ActionBar;
+import android.app.ActionBar.OnNavigationListener;
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.content.ActivityNotFoundException;
+import android.content.ClipData;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Intent;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.graphics.Point;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.InsetDrawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.provider.DocumentsContract;
+import android.provider.DocumentsContract.Root;
+import android.support.v4.app.ActionBarDrawerToggle;
+import android.support.v4.view.GravityCompat;
+import android.support.v4.widget.DrawerLayout;
+import android.support.v4.widget.DrawerLayout.DrawerListener;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.MenuItem.OnActionExpandListener;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.OnTouchListener;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.SearchView;
+import android.widget.SearchView.OnQueryTextListener;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.android.documentsui.RecentsProvider.RecentColumns;
+import com.android.documentsui.RecentsProvider.ResumeColumns;
+import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.model.DocumentStack;
+import com.android.documentsui.model.DurableUtils;
+import com.android.documentsui.model.RootInfo;
+
+import libcore.io.IoUtils;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+
+public class DocumentsActivity extends Activity {
+    public static final String TAG = "Documents";
+
+    private static final String EXTRA_STATE = "state";
+
+    private boolean mShowAsDialog;
+
+    private SearchView mSearchView;
+
+    private DrawerLayout mDrawerLayout;
+    private ActionBarDrawerToggle mDrawerToggle;
+    private View mRootsContainer;
+
+    private boolean mIgnoreNextNavigation;
+    private boolean mIgnoreNextClose;
+    private boolean mIgnoreNextCollapse;
+
+    private RootsCache mRoots;
+    private State mState;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        mRoots = DocumentsApplication.getRootsCache(this);
+
+        setResult(Activity.RESULT_CANCELED);
+        setContentView(R.layout.activity);
+
+        final Resources res = getResources();
+        mShowAsDialog = res.getBoolean(R.bool.show_as_dialog);
+
+        if (mShowAsDialog) {
+            // backgroundDimAmount from theme isn't applied; do it manually
+            final WindowManager.LayoutParams a = getWindow().getAttributes();
+            a.dimAmount = 0.6f;
+            getWindow().setAttributes(a);
+
+            getWindow().setFlags(0, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
+            getWindow().setFlags(~0, WindowManager.LayoutParams.FLAG_DIM_BEHIND);
+
+            // Inset ourselves to look like a dialog
+            final Point size = new Point();
+            getWindowManager().getDefaultDisplay().getSize(size);
+
+            final int width = (int) res.getFraction(R.dimen.dialog_width, size.x, size.x);
+            final int height = (int) res.getFraction(R.dimen.dialog_height, size.y, size.y);
+            final int insetX = (size.x - width) / 2;
+            final int insetY = (size.y - height) / 2;
+
+            final Drawable before = getWindow().getDecorView().getBackground();
+            final Drawable after = new InsetDrawable(before, insetX, insetY, insetX, insetY);
+            getWindow().getDecorView().setBackground(after);
+
+            // Dismiss when touch down in the dimmed inset area
+            getWindow().getDecorView().setOnTouchListener(new OnTouchListener() {
+                @Override
+                public boolean onTouch(View v, MotionEvent event) {
+                    if (event.getAction() == MotionEvent.ACTION_DOWN) {
+                        final float x = event.getX();
+                        final float y = event.getY();
+                        if (x < insetX || x > v.getWidth() - insetX || y < insetY
+                                || y > v.getHeight() - insetY) {
+                            finish();
+                            return true;
+                        }
+                    }
+                    return false;
+                }
+            });
+
+        } else {
+            // Non-dialog means we have a drawer
+            mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
+
+            mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
+                    R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close);
+
+            mDrawerLayout.setDrawerListener(mDrawerListener);
+            mDrawerLayout.setDrawerShadow(R.drawable.ic_drawer_shadow, GravityCompat.START);
+
+            mRootsContainer = findViewById(R.id.container_roots);
+        }
+
+        if (icicle != null) {
+            mState = icicle.getParcelable(EXTRA_STATE);
+        } else {
+            buildDefaultState();
+        }
+
+        // Hide roots when we're managing a specific root
+        if (mState.action == ACTION_MANAGE) {
+            if (mShowAsDialog) {
+                findViewById(R.id.dialog_roots).setVisibility(View.GONE);
+            } else {
+                mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
+            }
+        }
+
+        if (mState.action == ACTION_CREATE) {
+            final String mimeType = getIntent().getType();
+            final String title = getIntent().getStringExtra(Intent.EXTRA_TITLE);
+            SaveFragment.show(getFragmentManager(), mimeType, title);
+        }
+
+        if (mState.action == ACTION_GET_CONTENT) {
+            final Intent moreApps = new Intent(getIntent());
+            moreApps.setComponent(null);
+            moreApps.setPackage(null);
+            RootsFragment.show(getFragmentManager(), moreApps);
+        } else if (mState.action == ACTION_OPEN || mState.action == ACTION_CREATE) {
+            RootsFragment.show(getFragmentManager(), null);
+        }
+
+        onCurrentDirectoryChanged();
+    }
+
+    private void buildDefaultState() {
+        mState = new State();
+
+        final Intent intent = getIntent();
+        final String action = intent.getAction();
+        if (Intent.ACTION_OPEN_DOCUMENT.equals(action)) {
+            mState.action = ACTION_OPEN;
+        } else if (Intent.ACTION_CREATE_DOCUMENT.equals(action)) {
+            mState.action = ACTION_CREATE;
+        } else if (Intent.ACTION_GET_CONTENT.equals(action)) {
+            mState.action = ACTION_GET_CONTENT;
+        } else if (DocumentsContract.ACTION_MANAGE_ROOT.equals(action)) {
+            mState.action = ACTION_MANAGE;
+        }
+
+        if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT) {
+            mState.allowMultiple = intent.getBooleanExtra(
+                    Intent.EXTRA_ALLOW_MULTIPLE, false);
+        }
+
+        if (mState.action == ACTION_MANAGE) {
+            mState.acceptMimes = new String[] { "*/*" };
+            mState.allowMultiple = true;
+        } else if (intent.hasExtra(Intent.EXTRA_MIME_TYPES)) {
+            mState.acceptMimes = intent.getStringArrayExtra(Intent.EXTRA_MIME_TYPES);
+        } else {
+            mState.acceptMimes = new String[] { intent.getType() };
+        }
+
+        mState.localOnly = intent.getBooleanExtra(Intent.EXTRA_LOCAL_ONLY, false);
+        mState.showAdvanced = SettingsActivity.getDisplayAdvancedDevices(this);
+
+        if (mState.action == ACTION_MANAGE) {
+            final Uri uri = intent.getData();
+            final String rootId = DocumentsContract.getRootId(uri);
+            final RootInfo root = mRoots.getRoot(uri.getAuthority(), rootId);
+            if (root != null) {
+                onRootPicked(root, true);
+            } else {
+                Log.w(TAG, "Failed to find root: " + uri);
+                finish();
+            }
+
+        } else {
+            // Restore last stack for calling package
+            // TODO: move into async loader
+            boolean restoredStack = false;
+            final String packageName = getCallingPackage();
+            final Cursor cursor = getContentResolver()
+                    .query(RecentsProvider.buildResume(packageName), null, null, null, null);
+            try {
+                if (cursor.moveToFirst()) {
+                    final byte[] rawStack = cursor.getBlob(
+                            cursor.getColumnIndex(ResumeColumns.STACK));
+                    DurableUtils.readFromArray(rawStack, mState.stack);
+                    restoredStack = true;
+                }
+            } catch (IOException e) {
+                Log.w(TAG, "Failed to resume", e);
+            } finally {
+                IoUtils.closeQuietly(cursor);
+            }
+
+            // If restored root isn't valid, fall back to recents
+            final RootInfo root = getCurrentRoot();
+            final List<RootInfo> matchingRoots = mRoots.getMatchingRoots(mState);
+            if (!matchingRoots.contains(root)) {
+                mState.stack.reset();
+                restoredStack = false;
+            }
+
+            // Only open drawer when not restoring stack, and when not showing
+            // visual content.
+            if (!restoredStack
+                    && !MimePredicate.mimeMatches(MimePredicate.VISUAL_MIMES, mState.acceptMimes)) {
+                setRootsDrawerOpen(true);
+            }
+        }
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+
+        if (mState.action == ACTION_MANAGE) {
+            mState.showSize = true;
+        } else {
+            mState.showSize = SettingsActivity.getDisplayFileSize(this);
+        }
+    }
+
+    private DrawerListener mDrawerListener = new DrawerListener() {
+        @Override
+        public void onDrawerSlide(View drawerView, float slideOffset) {
+            mDrawerToggle.onDrawerSlide(drawerView, slideOffset);
+        }
+
+        @Override
+        public void onDrawerOpened(View drawerView) {
+            mDrawerToggle.onDrawerOpened(drawerView);
+            updateActionBar();
+            invalidateOptionsMenu();
+        }
+
+        @Override
+        public void onDrawerClosed(View drawerView) {
+            mDrawerToggle.onDrawerClosed(drawerView);
+            updateActionBar();
+            invalidateOptionsMenu();
+        }
+
+        @Override
+        public void onDrawerStateChanged(int newState) {
+            mDrawerToggle.onDrawerStateChanged(newState);
+        }
+    };
+
+    @Override
+    protected void onPostCreate(Bundle savedInstanceState) {
+        super.onPostCreate(savedInstanceState);
+        if (mDrawerToggle != null) {
+            mDrawerToggle.syncState();
+        }
+    }
+
+    public void setRootsDrawerOpen(boolean open) {
+        if (!mShowAsDialog) {
+            if (open) {
+                mDrawerLayout.openDrawer(mRootsContainer);
+            } else {
+                mDrawerLayout.closeDrawer(mRootsContainer);
+            }
+        }
+    }
+
+    private boolean isRootsDrawerOpen() {
+        if (mShowAsDialog) {
+            return false;
+        } else {
+            return mDrawerLayout.isDrawerOpen(mRootsContainer);
+        }
+    }
+
+    public void updateActionBar() {
+        final ActionBar actionBar = getActionBar();
+
+        actionBar.setDisplayShowHomeEnabled(true);
+
+        final boolean showIndicator = !mShowAsDialog && (mState.action != ACTION_MANAGE);
+        actionBar.setDisplayHomeAsUpEnabled(showIndicator);
+        if (mDrawerToggle != null) {
+            mDrawerToggle.setDrawerIndicatorEnabled(showIndicator);
+        }
+
+        if (isRootsDrawerOpen()) {
+            actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
+            actionBar.setIcon(new ColorDrawable());
+
+            if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT) {
+                actionBar.setTitle(R.string.title_open);
+            } else if (mState.action == ACTION_CREATE) {
+                actionBar.setTitle(R.string.title_save);
+            }
+        } else {
+            final RootInfo root = getCurrentRoot();
+            actionBar.setIcon(root != null ? root.loadIcon(this) : null);
+
+            if (mState.stack.size() <= 1) {
+                actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
+                actionBar.setTitle(root.title);
+            } else {
+                mIgnoreNextNavigation = true;
+                actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
+                actionBar.setTitle(null);
+                actionBar.setListNavigationCallbacks(mStackAdapter, mStackListener);
+                actionBar.setSelectedNavigationItem(mStackAdapter.getCount() - 1);
+            }
+        }
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+        getMenuInflater().inflate(R.menu.activity, menu);
+
+        // Actions are always visible when showing as dialog
+        if (mShowAsDialog) {
+            for (int i = 0; i < menu.size(); i++) {
+                menu.getItem(i).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
+            }
+        }
+
+        final MenuItem searchMenu = menu.findItem(R.id.menu_search);
+        mSearchView = (SearchView) searchMenu.getActionView();
+        mSearchView.setOnQueryTextListener(new OnQueryTextListener() {
+            @Override
+            public boolean onQueryTextSubmit(String query) {
+                mState.currentSearch = query;
+                mSearchView.clearFocus();
+                onCurrentDirectoryChanged();
+                return true;
+            }
+
+            @Override
+            public boolean onQueryTextChange(String newText) {
+                return false;
+            }
+        });
+
+        searchMenu.setOnActionExpandListener(new OnActionExpandListener() {
+            @Override
+            public boolean onMenuItemActionExpand(MenuItem item) {
+                return true;
+            }
+
+            @Override
+            public boolean onMenuItemActionCollapse(MenuItem item) {
+                if (mIgnoreNextCollapse) {
+                    mIgnoreNextCollapse = false;
+                    return true;
+                }
+
+                mState.currentSearch = null;
+                onCurrentDirectoryChanged();
+                return true;
+            }
+        });
+
+        mSearchView.setOnCloseListener(new SearchView.OnCloseListener() {
+            @Override
+            public boolean onClose() {
+                if (mIgnoreNextClose) {
+                    mIgnoreNextClose = false;
+                    return false;
+                }
+
+                mState.currentSearch = null;
+                onCurrentDirectoryChanged();
+                return false;
+            }
+        });
+
+        return true;
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        super.onPrepareOptionsMenu(menu);
+
+        final FragmentManager fm = getFragmentManager();
+
+        final RootInfo root = getCurrentRoot();
+        final DocumentInfo cwd = getCurrentDirectory();
+
+        final MenuItem createDir = menu.findItem(R.id.menu_create_dir);
+        final MenuItem search = menu.findItem(R.id.menu_search);
+        final MenuItem sort = menu.findItem(R.id.menu_sort);
+        final MenuItem sortSize = menu.findItem(R.id.menu_sort_size);
+        final MenuItem grid = menu.findItem(R.id.menu_grid);
+        final MenuItem list = menu.findItem(R.id.menu_list);
+        final MenuItem settings = menu.findItem(R.id.menu_settings);
+
+        // Open drawer means we hide most actions
+        if (isRootsDrawerOpen()) {
+            createDir.setVisible(false);
+            search.setVisible(false);
+            sort.setVisible(false);
+            grid.setVisible(false);
+            list.setVisible(false);
+            mIgnoreNextCollapse = true;
+            search.collapseActionView();
+            return true;
+        }
+
+        sort.setVisible(cwd != null);
+        grid.setVisible(mState.derivedMode != MODE_GRID);
+        list.setVisible(mState.derivedMode != MODE_LIST);
+
+        if (mState.currentSearch != null) {
+            // Search uses backend ranking; no sorting
+            sort.setVisible(false);
+
+            search.expandActionView();
+
+            mSearchView.setIconified(false);
+            mSearchView.clearFocus();
+            mSearchView.setQuery(mState.currentSearch, false);
+        } else {
+            mIgnoreNextClose = true;
+            mSearchView.setIconified(true);
+            mSearchView.clearFocus();
+
+            mIgnoreNextCollapse = true;
+            search.collapseActionView();
+        }
+
+        // Only sort by size when visible
+        sortSize.setVisible(mState.showSize);
+
+        final boolean searchVisible;
+        if (mState.action == ACTION_CREATE) {
+            createDir.setVisible(cwd != null && cwd.isCreateSupported());
+            searchVisible = false;
+
+            // No display options in recent directories
+            if (cwd == null) {
+                grid.setVisible(false);
+                list.setVisible(false);
+            }
+
+            SaveFragment.get(fm).setSaveEnabled(cwd != null && cwd.isCreateSupported());
+        } else {
+            createDir.setVisible(false);
+
+            searchVisible = root != null
+                    && ((root.flags & Root.FLAG_SUPPORTS_SEARCH) != 0);
+        }
+
+        // TODO: close any search in-progress when hiding
+        search.setVisible(searchVisible);
+
+        settings.setVisible(mState.action != ACTION_MANAGE);
+
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        if (mDrawerToggle != null && mDrawerToggle.onOptionsItemSelected(item)) {
+            return true;
+        }
+
+        final int id = item.getItemId();
+        if (id == android.R.id.home) {
+            onBackPressed();
+            return true;
+        } else if (id == R.id.menu_create_dir) {
+            CreateDirectoryFragment.show(getFragmentManager());
+            return true;
+        } else if (id == R.id.menu_search) {
+            return false;
+        } else if (id == R.id.menu_sort_name) {
+            setUserSortOrder(State.SORT_ORDER_DISPLAY_NAME);
+            return true;
+        } else if (id == R.id.menu_sort_date) {
+            setUserSortOrder(State.SORT_ORDER_LAST_MODIFIED);
+            return true;
+        } else if (id == R.id.menu_sort_size) {
+            setUserSortOrder(State.SORT_ORDER_SIZE);
+            return true;
+        } else if (id == R.id.menu_grid) {
+            setUserMode(State.MODE_GRID);
+            return true;
+        } else if (id == R.id.menu_list) {
+            setUserMode(State.MODE_LIST);
+            return true;
+        } else if (id == R.id.menu_settings) {
+            startActivity(new Intent(this, SettingsActivity.class));
+            return true;
+        } else {
+            return super.onOptionsItemSelected(item);
+        }
+    }
+
+    /**
+     * Update UI to reflect internal state changes not from user.
+     */
+    public void onStateChanged() {
+        invalidateOptionsMenu();
+    }
+
+    /**
+     * Set state sort order based on explicit user action.
+     */
+    private void setUserSortOrder(int sortOrder) {
+        mState.userSortOrder = sortOrder;
+        DirectoryFragment.get(getFragmentManager()).onUserSortOrderChanged();
+    }
+
+    /**
+     * Set state mode based on explicit user action.
+     */
+    private void setUserMode(int mode) {
+        mState.userMode = mode;
+        DirectoryFragment.get(getFragmentManager()).onUserModeChanged();
+    }
+
+    @Override
+    public void onBackPressed() {
+        if (!mState.stackTouched) {
+            super.onBackPressed();
+            return;
+        }
+
+        final int size = mState.stack.size();
+        if (size > 1) {
+            mState.stack.pop();
+            onCurrentDirectoryChanged();
+        } else if (size == 1 && !isRootsDrawerOpen()) {
+            // TODO: open root drawer once we can capture back key
+            super.onBackPressed();
+        } else {
+            super.onBackPressed();
+        }
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle state) {
+        super.onSaveInstanceState(state);
+        state.putParcelable(EXTRA_STATE, mState);
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Bundle state) {
+        super.onRestoreInstanceState(state);
+        updateActionBar();
+    }
+
+    private BaseAdapter mStackAdapter = new BaseAdapter() {
+        @Override
+        public int getCount() {
+            return mState.stack.size();
+        }
+
+        @Override
+        public DocumentInfo getItem(int position) {
+            return mState.stack.get(mState.stack.size() - position - 1);
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return position;
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            if (convertView == null) {
+                convertView = LayoutInflater.from(parent.getContext())
+                        .inflate(R.layout.item_title, parent, false);
+            }
+
+            final TextView title = (TextView) convertView.findViewById(android.R.id.title);
+            final DocumentInfo doc = getItem(position);
+
+            if (position == 0) {
+                final RootInfo root = getCurrentRoot();
+                title.setText(root.title);
+            } else {
+                title.setText(doc.displayName);
+            }
+
+            // No padding when shown in actionbar
+            convertView.setPadding(0, 0, 0, 0);
+            return convertView;
+        }
+
+        @Override
+        public View getDropDownView(int position, View convertView, ViewGroup parent) {
+            if (convertView == null) {
+                convertView = LayoutInflater.from(parent.getContext())
+                        .inflate(R.layout.item_title, parent, false);
+            }
+
+            final ImageView subdir = (ImageView) convertView.findViewById(R.id.subdir);
+            final TextView title = (TextView) convertView.findViewById(android.R.id.title);
+            final DocumentInfo doc = getItem(position);
+
+            if (position == 0) {
+                final RootInfo root = getCurrentRoot();
+                title.setText(root.title);
+                subdir.setVisibility(View.GONE);
+            } else {
+                title.setText(doc.displayName);
+                subdir.setVisibility(View.VISIBLE);
+            }
+
+            return convertView;
+        }
+    };
+
+    private OnNavigationListener mStackListener = new OnNavigationListener() {
+        @Override
+        public boolean onNavigationItemSelected(int itemPosition, long itemId) {
+            if (mIgnoreNextNavigation) {
+                mIgnoreNextNavigation = false;
+                return false;
+            }
+
+            while (mState.stack.size() > itemPosition + 1) {
+                mState.stackTouched = true;
+                mState.stack.pop();
+            }
+            onCurrentDirectoryChanged();
+            return true;
+        }
+    };
+
+    public RootInfo getCurrentRoot() {
+        if (mState.stack.root != null) {
+            return mState.stack.root;
+        } else {
+            return mRoots.getRecentsRoot();
+        }
+    }
+
+    public DocumentInfo getCurrentDirectory() {
+        return mState.stack.peek();
+    }
+
+    public State getDisplayState() {
+        return mState;
+    }
+
+    private void onCurrentDirectoryChanged() {
+        final FragmentManager fm = getFragmentManager();
+        final RootInfo root = getCurrentRoot();
+        final DocumentInfo cwd = getCurrentDirectory();
+
+        if (cwd == null) {
+            // No directory means recents
+            if (mState.action == ACTION_CREATE) {
+                RecentsCreateFragment.show(fm);
+            } else {
+                DirectoryFragment.showRecentsOpen(fm);
+
+                // Start recents in relevant mode
+                final boolean acceptImages = MimePredicate.mimeMatches(
+                        "image/*", mState.acceptMimes);
+                mState.userMode = acceptImages ? MODE_GRID : MODE_LIST;
+                mState.derivedMode = mState.userMode;
+            }
+        } else {
+            if (mState.currentSearch != null) {
+                // Ongoing search
+                DirectoryFragment.showSearch(fm, root, mState.currentSearch);
+            } else {
+                // Normal boring directory
+                DirectoryFragment.showNormal(fm, root, cwd);
+            }
+        }
+
+        // Forget any replacement target
+        if (mState.action == ACTION_CREATE) {
+            final SaveFragment save = SaveFragment.get(fm);
+            if (save != null) {
+                save.setReplaceTarget(null);
+            }
+        }
+
+        final RootsFragment roots = RootsFragment.get(fm);
+        if (roots != null) {
+            roots.onCurrentRootChanged();
+        }
+
+        updateActionBar();
+        invalidateOptionsMenu();
+        dumpStack();
+    }
+
+    public void onStackPicked(DocumentStack stack) {
+        mState.stack = stack;
+        mState.stackTouched = true;
+        onCurrentDirectoryChanged();
+    }
+
+    public void onRootPicked(RootInfo root, boolean closeDrawer) {
+        // Clear entire backstack and start in new root
+        mState.stack.root = root;
+        mState.stack.clear();
+        mState.stackTouched = true;
+
+        if (!mRoots.isRecentsRoot(root)) {
+            try {
+                final Uri uri = DocumentsContract.buildDocumentUri(root.authority, root.documentId);
+                onDocumentPicked(DocumentInfo.fromUri(getContentResolver(), uri));
+            } catch (FileNotFoundException e) {
+            }
+        } else {
+            onCurrentDirectoryChanged();
+        }
+
+        if (closeDrawer) {
+            setRootsDrawerOpen(false);
+        }
+    }
+
+    public void onAppPicked(ResolveInfo info) {
+        final Intent intent = new Intent(getIntent());
+        intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
+        intent.setComponent(new ComponentName(
+                info.activityInfo.applicationInfo.packageName, info.activityInfo.name));
+        startActivity(intent);
+        finish();
+    }
+
+    public void onDocumentPicked(DocumentInfo doc) {
+        final FragmentManager fm = getFragmentManager();
+        if (doc.isDirectory()) {
+            mState.stack.push(doc);
+            mState.stackTouched = true;
+            onCurrentDirectoryChanged();
+        } else if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT) {
+            // Explicit file picked, return
+            onFinished(doc.derivedUri);
+        } else if (mState.action == ACTION_CREATE) {
+            // Replace selected file
+            SaveFragment.get(fm).setReplaceTarget(doc);
+        } else if (mState.action == ACTION_MANAGE) {
+            // First try managing the document; we expect manager to filter
+            // based on authority, so we don't grant.
+            final Intent manage = new Intent(DocumentsContract.ACTION_MANAGE_DOCUMENT);
+            manage.setData(doc.derivedUri);
+
+            try {
+                startActivity(manage);
+            } catch (ActivityNotFoundException ex) {
+                // Fall back to viewing
+                final Intent view = new Intent(Intent.ACTION_VIEW);
+                view.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+                view.setData(doc.derivedUri);
+
+                try {
+                    startActivity(view);
+                } catch (ActivityNotFoundException ex2) {
+                    Toast.makeText(this, R.string.toast_no_application, Toast.LENGTH_SHORT).show();
+                }
+            }
+        }
+    }
+
+    public void onDocumentsPicked(List<DocumentInfo> docs) {
+        if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT) {
+            final int size = docs.size();
+            final Uri[] uris = new Uri[size];
+            for (int i = 0; i < size; i++) {
+                uris[i] = docs.get(i).derivedUri;
+            }
+            onFinished(uris);
+        }
+    }
+
+    public void onSaveRequested(DocumentInfo replaceTarget) {
+        onFinished(replaceTarget.derivedUri);
+    }
+
+    public void onSaveRequested(String mimeType, String displayName) {
+        final DocumentInfo cwd = getCurrentDirectory();
+
+        final Uri childUri = DocumentsContract.createDocument(
+                getContentResolver(), cwd.derivedUri, mimeType, displayName);
+        if (childUri != null) {
+            onFinished(childUri);
+        } else {
+            Toast.makeText(this, R.string.save_error, Toast.LENGTH_SHORT).show();
+        }
+    }
+
+    private void onFinished(Uri... uris) {
+        Log.d(TAG, "onFinished() " + Arrays.toString(uris));
+
+        final ContentResolver resolver = getContentResolver();
+        final ContentValues values = new ContentValues();
+
+        final byte[] rawStack = DurableUtils.writeToArrayOrNull(mState.stack);
+        if (mState.action == ACTION_CREATE) {
+            // Remember stack for last create
+            values.clear();
+            values.put(RecentColumns.STACK, rawStack);
+            resolver.insert(RecentsProvider.buildRecent(), values);
+        }
+
+        // Remember location for next app launch
+        final String packageName = getCallingPackage();
+        values.clear();
+        values.put(ResumeColumns.STACK, rawStack);
+        resolver.insert(RecentsProvider.buildResume(packageName), values);
+
+        final Intent intent = new Intent();
+        if (uris.length == 1) {
+            intent.setData(uris[0]);
+        } else if (uris.length > 1) {
+            final ClipData clipData = new ClipData(
+                    null, mState.acceptMimes, new ClipData.Item(uris[0]));
+            for (int i = 1; i < uris.length; i++) {
+                clipData.addItem(new ClipData.Item(uris[i]));
+            }
+            intent.setClipData(clipData);
+        }
+
+        if (mState.action == ACTION_GET_CONTENT) {
+            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+        } else {
+            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
+                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+                    | Intent.FLAG_PERSIST_GRANT_URI_PERMISSION);
+        }
+
+        setResult(Activity.RESULT_OK, intent);
+        finish();
+    }
+
+    public static class State implements android.os.Parcelable {
+        public int action;
+        public String[] acceptMimes;
+
+        /** Explicit user choice */
+        public int userMode = MODE_UNKNOWN;
+        /** Derived after loader */
+        public int derivedMode = MODE_LIST;
+
+        /** Explicit user choice */
+        public int userSortOrder = SORT_ORDER_UNKNOWN;
+        /** Derived after loader */
+        public int derivedSortOrder = SORT_ORDER_DISPLAY_NAME;
+
+        public boolean allowMultiple = false;
+        public boolean showSize = false;
+        public boolean localOnly = false;
+        public boolean showAdvanced = false;
+        public boolean stackTouched = false;
+
+        /** Current user navigation stack; empty implies recents. */
+        public DocumentStack stack = new DocumentStack();
+        /** Currently active search, overriding any stack. */
+        public String currentSearch;
+
+        public static final int ACTION_OPEN = 1;
+        public static final int ACTION_CREATE = 2;
+        public static final int ACTION_GET_CONTENT = 3;
+        public static final int ACTION_MANAGE = 4;
+
+        public static final int MODE_UNKNOWN = 0;
+        public static final int MODE_LIST = 1;
+        public static final int MODE_GRID = 2;
+
+        public static final int SORT_ORDER_UNKNOWN = 0;
+        public static final int SORT_ORDER_DISPLAY_NAME = 1;
+        public static final int SORT_ORDER_LAST_MODIFIED = 2;
+        public static final int SORT_ORDER_SIZE = 3;
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel out, int flags) {
+            out.writeInt(action);
+            out.writeInt(userMode);
+            out.writeStringArray(acceptMimes);
+            out.writeInt(userSortOrder);
+            out.writeInt(allowMultiple ? 1 : 0);
+            out.writeInt(showSize ? 1 : 0);
+            out.writeInt(localOnly ? 1 : 0);
+            out.writeInt(showAdvanced ? 1 : 0);
+            out.writeInt(stackTouched ? 1 : 0);
+            DurableUtils.writeToParcel(out, stack);
+            out.writeString(currentSearch);
+        }
+
+        public static final Creator<State> CREATOR = new Creator<State>() {
+            @Override
+            public State createFromParcel(Parcel in) {
+                final State state = new State();
+                state.action = in.readInt();
+                state.userMode = in.readInt();
+                state.acceptMimes = in.readStringArray();
+                state.userSortOrder = in.readInt();
+                state.allowMultiple = in.readInt() != 0;
+                state.showSize = in.readInt() != 0;
+                state.localOnly = in.readInt() != 0;
+                state.showAdvanced = in.readInt() != 0;
+                state.stackTouched = in.readInt() != 0;
+                DurableUtils.readFromParcel(in, state.stack);
+                state.currentSearch = in.readString();
+                return state;
+            }
+
+            @Override
+            public State[] newArray(int size) {
+                return new State[size];
+            }
+        };
+    }
+
+    private void dumpStack() {
+        Log.d(TAG, "Current stack: ");
+        Log.d(TAG, " * " + mState.stack.root);
+        for (DocumentInfo doc : mState.stack) {
+            Log.d(TAG, " +-- " + doc);
+        }
+    }
+
+    public static DocumentsActivity get(Fragment fragment) {
+        return (DocumentsActivity) fragment.getActivity();
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsApplication.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsApplication.java
new file mode 100644
index 0000000..180ddef
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsApplication.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 com.android.documentsui;
+
+import android.app.ActivityManager;
+import android.app.Application;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.graphics.Point;
+
+public class DocumentsApplication extends Application {
+    private RootsCache mRoots;
+    private Point mThumbnailsSize;
+    private ThumbnailCache mThumbnails;
+
+    public static RootsCache getRootsCache(Context context) {
+        return ((DocumentsApplication) context.getApplicationContext()).mRoots;
+    }
+
+    public static ThumbnailCache getThumbnailsCache(Context context, Point size) {
+        final DocumentsApplication app = (DocumentsApplication) context.getApplicationContext();
+        final ThumbnailCache thumbnails = app.mThumbnails;
+        if (!size.equals(app.mThumbnailsSize)) {
+            thumbnails.evictAll();
+            app.mThumbnailsSize = size;
+        }
+        return thumbnails;
+    }
+
+    @Override
+    public void onCreate() {
+        final ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
+        final int memoryClassBytes = am.getMemoryClass() * 1024 * 1024;
+
+        mRoots = new RootsCache(this);
+        mThumbnails = new ThumbnailCache(memoryClassBytes / 4);
+
+        final IntentFilter packageFilter = new IntentFilter();
+        packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
+        packageFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+        packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+        packageFilter.addDataScheme("package");
+        registerReceiver(mCacheReceiver, packageFilter);
+
+        final IntentFilter localeFilter = new IntentFilter();
+        localeFilter.addAction(Intent.ACTION_LOCALE_CHANGED);
+        registerReceiver(mCacheReceiver, localeFilter);
+    }
+
+    @Override
+    public void onTrimMemory(int level) {
+        super.onTrimMemory(level);
+
+        if (level >= TRIM_MEMORY_MODERATE) {
+            mThumbnails.evictAll();
+        } else if (level >= TRIM_MEMORY_BACKGROUND) {
+            mThumbnails.trimToSize(mThumbnails.size() / 2);
+        }
+    }
+
+    private BroadcastReceiver mCacheReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            // TODO: narrow changed/removed to only packages that have backends
+            mRoots.update();
+        }
+    };
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/FilteringCursorWrapper.java b/packages/DocumentsUI/src/com/android/documentsui/FilteringCursorWrapper.java
new file mode 100644
index 0000000..5f56963
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/FilteringCursorWrapper.java
@@ -0,0 +1,126 @@
+/*
+ * 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.documentsui;
+
+import static com.android.documentsui.DocumentsActivity.TAG;
+
+import android.database.AbstractCursor;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.provider.DocumentsContract.Document;
+import android.util.Log;
+
+/**
+ * Cursor wrapper that filters MIME types not matching given list.
+ */
+public class FilteringCursorWrapper extends AbstractCursor {
+    private final Cursor mCursor;
+
+    private final int[] mPosition;
+    private int mCount;
+
+    public FilteringCursorWrapper(Cursor cursor, String[] acceptMimes) {
+        this(cursor, acceptMimes, null);
+    }
+
+    public FilteringCursorWrapper(Cursor cursor, String[] acceptMimes, String[] rejectMimes) {
+        mCursor = cursor;
+
+        final int count = cursor.getCount();
+        mPosition = new int[count];
+
+        cursor.moveToPosition(-1);
+        while (cursor.moveToNext()) {
+            final String mimeType = cursor.getString(
+                    cursor.getColumnIndex(Document.COLUMN_MIME_TYPE));
+            if (rejectMimes != null && MimePredicate.mimeMatches(rejectMimes, mimeType)) {
+                continue;
+            }
+            if (MimePredicate.mimeMatches(acceptMimes, mimeType)) {
+                mPosition[mCount++] = cursor.getPosition();
+            }
+        }
+
+        Log.d(TAG, "Before filtering " + cursor.getCount() + ", after " + mCount);
+    }
+
+    @Override
+    public Bundle getExtras() {
+        return mCursor.getExtras();
+    }
+
+    @Override
+    public void close() {
+        super.close();
+        mCursor.close();
+    }
+
+    @Override
+    public boolean onMove(int oldPosition, int newPosition) {
+        return mCursor.moveToPosition(mPosition[newPosition]);
+    }
+
+    @Override
+    public String[] getColumnNames() {
+        return mCursor.getColumnNames();
+    }
+
+    @Override
+    public int getCount() {
+        return mCount;
+    }
+
+    @Override
+    public double getDouble(int column) {
+        return mCursor.getDouble(column);
+    }
+
+    @Override
+    public float getFloat(int column) {
+        return mCursor.getFloat(column);
+    }
+
+    @Override
+    public int getInt(int column) {
+        return mCursor.getInt(column);
+    }
+
+    @Override
+    public long getLong(int column) {
+        return mCursor.getLong(column);
+    }
+
+    @Override
+    public short getShort(int column) {
+        return mCursor.getShort(column);
+    }
+
+    @Override
+    public String getString(int column) {
+        return mCursor.getString(column);
+    }
+
+    @Override
+    public int getType(int column) {
+        return mCursor.getType(column);
+    }
+
+    @Override
+    public boolean isNull(int column) {
+        return mCursor.isNull(column);
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java b/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java
new file mode 100644
index 0000000..5caf9ba
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java
@@ -0,0 +1,243 @@
+/*
+ * 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.documentsui;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.ProviderInfo;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.provider.DocumentsContract.Document;
+
+import com.google.android.collect.Maps;
+
+import java.util.HashMap;
+
+public class IconUtils {
+
+    private static HashMap<String, Integer> sMimeIcons = Maps.newHashMap();
+
+    private static void add(String mimeType, int resId) {
+        if (sMimeIcons.put(mimeType, resId) != null) {
+            throw new RuntimeException(mimeType + " already registered!");
+        }
+    }
+
+    static {
+        int icon;
+
+        // Package
+        icon = R.drawable.ic_doc_apk;
+        add("application/vnd.android.package-archive", icon);
+
+        // Audio
+        icon = R.drawable.ic_doc_audio;
+        add("application/ogg", icon);
+        add("application/x-flac", icon);
+
+        // Certificate
+        icon = R.drawable.ic_doc_certificate;
+        add("application/pgp-keys", icon);
+        add("application/pgp-signature", icon);
+        add("application/x-pkcs12", icon);
+        add("application/x-pkcs7-certreqresp", icon);
+        add("application/x-pkcs7-crl", icon);
+        add("application/x-x509-ca-cert", icon);
+        add("application/x-x509-user-cert", icon);
+        add("application/x-pkcs7-certificates", icon);
+        add("application/x-pkcs7-mime", icon);
+        add("application/x-pkcs7-signature", icon);
+
+        // Source code
+        icon = R.drawable.ic_doc_codes;
+        add("application/rdf+xml", icon);
+        add("application/rss+xml", icon);
+        add("application/x-object", icon);
+        add("application/xhtml+xml", icon);
+        add("text/css", icon);
+        add("text/html", icon);
+        add("text/xml", icon);
+        add("text/x-c++hdr", icon);
+        add("text/x-c++src", icon);
+        add("text/x-chdr", icon);
+        add("text/x-csrc", icon);
+        add("text/x-dsrc", icon);
+        add("text/x-csh", icon);
+        add("text/x-haskell", icon);
+        add("text/x-java", icon);
+        add("text/x-literate-haskell", icon);
+        add("text/x-pascal", icon);
+        add("text/x-tcl", icon);
+        add("text/x-tex", icon);
+        add("application/x-latex", icon);
+        add("application/x-texinfo", icon);
+        add("application/atom+xml", icon);
+        add("application/ecmascript", icon);
+        add("application/json", icon);
+        add("application/javascript", icon);
+        add("application/xml", icon);
+        add("text/javascript", icon);
+        add("application/x-javascript", icon);
+
+        // Compressed
+        icon = R.drawable.ic_doc_compressed;
+        add("application/mac-binhex40", icon);
+        add("application/rar", icon);
+        add("application/zip", icon);
+        add("application/x-apple-diskimage", icon);
+        add("application/x-debian-package", icon);
+        add("application/x-gtar", icon);
+        add("application/x-iso9660-image", icon);
+        add("application/x-lha", icon);
+        add("application/x-lzh", icon);
+        add("application/x-lzx", icon);
+        add("application/x-stuffit", icon);
+        add("application/x-tar", icon);
+        add("application/x-webarchive", icon);
+        add("application/x-webarchive-xml", icon);
+        add("application/gzip", icon);
+        add("application/x-7z-compressed", icon);
+        add("application/x-deb", icon);
+        add("application/x-rar-compressed", icon);
+
+        // Contact
+        icon = R.drawable.ic_doc_contact;
+        add("text/x-vcard", icon);
+        add("text/vcard", icon);
+
+        // Event
+        icon = R.drawable.ic_doc_event;
+        add("text/calendar", icon);
+        add("text/x-vcalendar", icon);
+
+        // Font
+        icon = R.drawable.ic_doc_font;
+        add("application/x-font", icon);
+        add("application/font-woff", icon);
+        add("application/x-font-woff", icon);
+        add("application/x-font-ttf", icon);
+
+        // Image
+        icon = R.drawable.ic_doc_image;
+        add("application/vnd.oasis.opendocument.graphics", icon);
+        add("application/vnd.oasis.opendocument.graphics-template", icon);
+        add("application/vnd.oasis.opendocument.image", icon);
+        add("application/vnd.stardivision.draw", icon);
+        add("application/vnd.sun.xml.draw", icon);
+        add("application/vnd.sun.xml.draw.template", icon);
+
+        // PDF
+        icon = R.drawable.ic_doc_pdf;
+        add("application/pdf", icon);
+
+        // Presentation
+        icon = R.drawable.ic_doc_presentation;
+        add("application/vnd.ms-powerpoint", icon);
+        add("application/vnd.openxmlformats-officedocument.presentationml.presentation", icon);
+        add("application/vnd.openxmlformats-officedocument.presentationml.template", icon);
+        add("application/vnd.openxmlformats-officedocument.presentationml.slideshow", icon);
+        add("application/vnd.stardivision.impress", icon);
+        add("application/vnd.sun.xml.impress", icon);
+        add("application/vnd.sun.xml.impress.template", icon);
+        add("application/x-kpresenter", icon);
+        add("application/vnd.oasis.opendocument.presentation", icon);
+
+        // Spreadsheet
+        icon = R.drawable.ic_doc_spreadsheet;
+        add("application/vnd.oasis.opendocument.spreadsheet", icon);
+        add("application/vnd.oasis.opendocument.spreadsheet-template", icon);
+        add("application/vnd.ms-excel", icon);
+        add("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", icon);
+        add("application/vnd.openxmlformats-officedocument.spreadsheetml.template", icon);
+        add("application/vnd.stardivision.calc", icon);
+        add("application/vnd.sun.xml.calc", icon);
+        add("application/vnd.sun.xml.calc.template", icon);
+        add("application/x-kspread", icon);
+
+        // Text
+        icon = R.drawable.ic_doc_text;
+        add("application/vnd.oasis.opendocument.text", icon);
+        add("application/vnd.oasis.opendocument.text-master", icon);
+        add("application/vnd.oasis.opendocument.text-template", icon);
+        add("application/vnd.oasis.opendocument.text-web", icon);
+        add("application/msword", icon);
+        add("application/vnd.openxmlformats-officedocument.wordprocessingml.document", icon);
+        add("application/vnd.openxmlformats-officedocument.wordprocessingml.template", icon);
+        add("application/vnd.stardivision.writer", icon);
+        add("application/vnd.stardivision.writer-global", icon);
+        add("application/vnd.sun.xml.writer", icon);
+        add("application/vnd.sun.xml.writer.global", icon);
+        add("application/vnd.sun.xml.writer.template", icon);
+        add("application/x-abiword", icon);
+        add("application/x-kword", icon);
+
+        // Video
+        icon = R.drawable.ic_doc_video;
+        add("application/x-quicktimeplayer", icon);
+        add("application/x-shockwave-flash", icon);
+    }
+
+    public static Drawable loadPackageIcon(Context context, String authority, int icon) {
+        if (icon != 0) {
+            if (authority != null) {
+                final PackageManager pm = context.getPackageManager();
+                final ProviderInfo info = pm.resolveContentProvider(authority, 0);
+                if (info != null) {
+                    return pm.getDrawable(info.packageName, icon, info.applicationInfo);
+                }
+            } else {
+                return context.getResources().getDrawable(icon);
+            }
+        }
+        return null;
+    }
+
+    public static Drawable loadMimeIcon(Context context, String mimeType) {
+        final Resources res = context.getResources();
+
+        if (Document.MIME_TYPE_DIR.equals(mimeType)) {
+            // TODO: return a mipmap, since this is used for grid
+            return res.getDrawable(R.drawable.ic_root_folder);
+        }
+
+        // Look for exact match first
+        Integer resId = sMimeIcons.get(mimeType);
+        if (resId != null) {
+            return res.getDrawable(resId);
+        }
+
+        if (mimeType == null) {
+            // TODO: generic icon?
+            return null;
+        }
+
+        // Otherwise look for partial match
+        final String typeOnly = mimeType.split("/")[0];
+        if ("audio".equals(typeOnly)) {
+            return res.getDrawable(R.drawable.ic_doc_audio);
+        } else if ("image".equals(typeOnly)) {
+            return res.getDrawable(R.drawable.ic_doc_image);
+        } else if ("text".equals(typeOnly)) {
+            return res.getDrawable(R.drawable.ic_doc_text);
+        } else if ("video".equals(typeOnly)) {
+            return res.getDrawable(R.drawable.ic_doc_video);
+        } else {
+            // TODO: generic icon?
+            return null;
+        }
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/MimePredicate.java b/packages/DocumentsUI/src/com/android/documentsui/MimePredicate.java
new file mode 100644
index 0000000..2d96876
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/MimePredicate.java
@@ -0,0 +1,95 @@
+/*
+ * 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.documentsui;
+
+import com.android.documentsui.model.DocumentInfo;
+import com.android.internal.util.Predicate;
+
+public class MimePredicate implements Predicate<DocumentInfo> {
+    private final String[] mFilters;
+
+    /**
+     * MIME types that are visual in nature. For example, they should always be
+     * shown as thumbnails in list mode.
+     */
+    public static final String[] VISUAL_MIMES = new String[] { "image/*", "video/*" };
+
+    public MimePredicate(String[] filters) {
+        mFilters = filters;
+    }
+
+    @Override
+    public boolean apply(DocumentInfo doc) {
+        if (doc.isDirectory()) {
+            return true;
+        }
+        if (mimeMatches(mFilters, doc.mimeType)) {
+            return true;
+        }
+        return false;
+    }
+
+    public static boolean mimeMatches(String[] filters, String[] tests) {
+        if (tests == null) {
+            return false;
+        }
+        for (String test : tests) {
+            if (mimeMatches(filters, test)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public static boolean mimeMatches(String filter, String[] tests) {
+        if (tests == null) {
+            return true;
+        }
+        for (String test : tests) {
+            if (mimeMatches(filter, test)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public static boolean mimeMatches(String[] filters, String test) {
+        if (filters == null) {
+            return true;
+        }
+        for (String filter : filters) {
+            if (mimeMatches(filter, test)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public static boolean mimeMatches(String filter, String test) {
+        if (filter == null || "*/*".equals(filter)) {
+            return true;
+        } else if (test == null) {
+            return false;
+        } else if (filter.equals(test)) {
+            return true;
+        } else if (filter.endsWith("/*")) {
+            return filter.regionMatches(0, test, 0, filter.indexOf('/'));
+        } else {
+            return false;
+        }
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RecentLoader.java b/packages/DocumentsUI/src/com/android/documentsui/RecentLoader.java
new file mode 100644
index 0000000..1912010
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/RecentLoader.java
@@ -0,0 +1,263 @@
+/*
+ * 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.documentsui;
+
+import static com.android.documentsui.DocumentsActivity.TAG;
+import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_LAST_MODIFIED;
+
+import android.content.AsyncTaskLoader;
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.MergeCursor;
+import android.net.Uri;
+import android.provider.DocumentsContract;
+import android.provider.DocumentsContract.Document;
+import android.provider.DocumentsContract.Root;
+import android.util.Log;
+
+import com.android.documentsui.DocumentsActivity.State;
+import com.android.documentsui.model.RootInfo;
+import com.google.android.collect.Maps;
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.AbstractFuture;
+
+import libcore.io.IoUtils;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+public class RecentLoader extends AsyncTaskLoader<DirectoryResult> {
+
+    public static final int MAX_OUTSTANDING_RECENTS = 2;
+
+    /**
+     * Time to wait for first pass to complete before returning partial results.
+     */
+    public static final int MAX_FIRST_PASS_WAIT_MILLIS = 500;
+
+    /**
+     * Maximum documents from a single root.
+     */
+    public static final int MAX_DOCS_FROM_ROOT = 24;
+
+    private static final ExecutorService sExecutor = buildExecutor();
+
+    /**
+     * Create a bounded thread pool for fetching recents; it creates threads as
+     * needed (up to maximum) and reclaims them when finished.
+     */
+    private static ExecutorService buildExecutor() {
+        // Create a bounded thread pool for fetching recents; it creates
+        // threads as needed (up to maximum) and reclaims them when finished.
+        final ThreadPoolExecutor executor = new ThreadPoolExecutor(
+                MAX_OUTSTANDING_RECENTS, MAX_OUTSTANDING_RECENTS, 10, TimeUnit.SECONDS,
+                new LinkedBlockingQueue<Runnable>());
+        executor.allowCoreThreadTimeOut(true);
+        return executor;
+    }
+
+    private final List<RootInfo> mRoots;
+    private final String[] mAcceptMimes;
+
+    private final HashMap<RootInfo, RecentTask> mTasks = Maps.newHashMap();
+
+    private final int mSortOrder = State.SORT_ORDER_LAST_MODIFIED;
+
+    private CountDownLatch mFirstPassLatch;
+    private volatile boolean mFirstPassDone;
+
+    private DirectoryResult mResult;
+
+    // TODO: create better transfer of ownership around cursor to ensure its
+    // closed in all edge cases.
+
+    public class RecentTask extends AbstractFuture<Cursor> implements Runnable, Closeable {
+        public final String authority;
+        public final String rootId;
+
+        private Cursor mWithRoot;
+
+        public RecentTask(String authority, String rootId) {
+            this.authority = authority;
+            this.rootId = rootId;
+        }
+
+        @Override
+        public void run() {
+            if (isCancelled()) return;
+
+            final ContentResolver resolver = getContext().getContentResolver();
+            final ContentProviderClient client = resolver.acquireUnstableContentProviderClient(
+                    authority);
+            try {
+                final Uri uri = DocumentsContract.buildRecentDocumentsUri(authority, rootId);
+                final Cursor cursor = client.query(
+                        uri, null, null, null, DirectoryLoader.getQuerySortOrder(mSortOrder));
+                mWithRoot = new RootCursorWrapper(authority, rootId, cursor, MAX_DOCS_FROM_ROOT);
+                set(mWithRoot);
+
+                mFirstPassLatch.countDown();
+                if (mFirstPassDone) {
+                    onContentChanged();
+                }
+
+            } catch (Exception e) {
+                setException(e);
+            } finally {
+                ContentProviderClient.closeQuietly(client);
+            }
+        }
+
+        @Override
+        public void close() throws IOException {
+            IoUtils.closeQuietly(mWithRoot);
+        }
+    }
+
+    public RecentLoader(Context context, List<RootInfo> roots, String[] acceptMimes) {
+        super(context);
+        mRoots = roots;
+        mAcceptMimes = acceptMimes;
+    }
+
+    @Override
+    public DirectoryResult loadInBackground() {
+        if (mFirstPassLatch == null) {
+            // First time through we kick off all the recent tasks, and wait
+            // around to see if everyone finishes quickly.
+
+            for (RootInfo root : mRoots) {
+                if ((root.flags & Root.FLAG_SUPPORTS_RECENTS) != 0) {
+                    final RecentTask task = new RecentTask(root.authority, root.rootId);
+                    mTasks.put(root, task);
+                }
+            }
+
+            mFirstPassLatch = new CountDownLatch(mTasks.size());
+            for (RecentTask task : mTasks.values()) {
+                sExecutor.execute(task);
+            }
+
+            try {
+                mFirstPassLatch.await(MAX_FIRST_PASS_WAIT_MILLIS, TimeUnit.MILLISECONDS);
+                mFirstPassDone = true;
+            } catch (InterruptedException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        // Collect all finished tasks
+        List<Cursor> cursors = Lists.newArrayList();
+        for (RecentTask task : mTasks.values()) {
+            if (task.isDone()) {
+                try {
+                    final Cursor cursor = task.get();
+                    final FilteringCursorWrapper filtered = new FilteringCursorWrapper(
+                            cursor, mAcceptMimes, new String[] { Document.MIME_TYPE_DIR }) {
+                        @Override
+                        public void close() {
+                            // Ignored, since we manage cursor lifecycle internally
+                        }
+                    };
+                    cursors.add(filtered);
+                } catch (InterruptedException e) {
+                    throw new RuntimeException(e);
+                } catch (ExecutionException e) {
+                    Log.w(TAG, "Failed to load " + task.authority + ", " + task.rootId, e);
+                }
+            }
+        }
+
+        final DirectoryResult result = new DirectoryResult();
+        result.sortOrder = SORT_ORDER_LAST_MODIFIED;
+
+        if (cursors.size() > 0) {
+            final MergeCursor merged = new MergeCursor(cursors.toArray(new Cursor[cursors.size()]));
+            final SortingCursorWrapper sorted = new SortingCursorWrapper(merged, result.sortOrder);
+            result.cursor = sorted;
+        }
+        return result;
+    }
+
+    @Override
+    public void cancelLoadInBackground() {
+        super.cancelLoadInBackground();
+    }
+
+    @Override
+    public void deliverResult(DirectoryResult result) {
+        if (isReset()) {
+            IoUtils.closeQuietly(result);
+            return;
+        }
+        DirectoryResult oldResult = mResult;
+        mResult = result;
+
+        if (isStarted()) {
+            super.deliverResult(result);
+        }
+
+        if (oldResult != null && oldResult != result) {
+            IoUtils.closeQuietly(oldResult);
+        }
+    }
+
+    @Override
+    protected void onStartLoading() {
+        if (mResult != null) {
+            deliverResult(mResult);
+        }
+        if (takeContentChanged() || mResult == null) {
+            forceLoad();
+        }
+    }
+
+    @Override
+    protected void onStopLoading() {
+        cancelLoad();
+    }
+
+    @Override
+    public void onCanceled(DirectoryResult result) {
+        IoUtils.closeQuietly(result);
+    }
+
+    @Override
+    protected void onReset() {
+        super.onReset();
+
+        // Ensure the loader is stopped
+        onStopLoading();
+
+        for (RecentTask task : mTasks.values()) {
+            IoUtils.closeQuietly(task);
+        }
+
+        IoUtils.closeQuietly(mResult);
+        mResult = null;
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java b/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java
new file mode 100644
index 0000000..140373b
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java
@@ -0,0 +1,235 @@
+/*
+ * 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.documentsui;
+
+import static com.android.documentsui.DocumentsActivity.TAG;
+
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.app.FragmentTransaction;
+import android.app.LoaderManager.LoaderCallbacks;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Loader;
+import android.database.Cursor;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.CancellationSignal;
+import android.text.Spannable;
+import android.text.SpannableStringBuilder;
+import android.text.TextUtils.TruncateAt;
+import android.text.style.ImageSpan;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.android.documentsui.RecentsProvider.RecentColumns;
+import com.android.documentsui.model.DocumentStack;
+import com.google.android.collect.Lists;
+
+import libcore.io.IoUtils;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Display directories where recent creates took place.
+ */
+public class RecentsCreateFragment extends Fragment {
+
+    private ListView mListView;
+
+    private DocumentStackAdapter mAdapter;
+    private LoaderCallbacks<List<DocumentStack>> mCallbacks;
+
+    private static final int LOADER_RECENTS = 3;
+
+    public static void show(FragmentManager fm) {
+        final RecentsCreateFragment fragment = new RecentsCreateFragment();
+        final FragmentTransaction ft = fm.beginTransaction();
+        ft.replace(R.id.container_directory, fragment);
+        ft.commitAllowingStateLoss();
+    }
+
+    @Override
+    public View onCreateView(
+            LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        final Context context = inflater.getContext();
+
+        final View view = inflater.inflate(R.layout.fragment_directory, container, false);
+
+        mListView = (ListView) view.findViewById(R.id.list);
+        mListView.setOnItemClickListener(mItemListener);
+
+        mAdapter = new DocumentStackAdapter();
+        mListView.setAdapter(mAdapter);
+
+        mCallbacks = new LoaderCallbacks<List<DocumentStack>>() {
+            @Override
+            public Loader<List<DocumentStack>> onCreateLoader(int id, Bundle args) {
+                return new RecentsCreateLoader(context);
+            }
+
+            @Override
+            public void onLoadFinished(
+                    Loader<List<DocumentStack>> loader, List<DocumentStack> data) {
+                mAdapter.swapStacks(data);
+            }
+
+            @Override
+            public void onLoaderReset(Loader<List<DocumentStack>> loader) {
+                mAdapter.swapStacks(null);
+            }
+        };
+
+        return view;
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        getLoaderManager().restartLoader(LOADER_RECENTS, getArguments(), mCallbacks);
+    }
+
+    @Override
+    public void onStop() {
+        super.onStop();
+        getLoaderManager().destroyLoader(LOADER_RECENTS);
+    }
+
+    private OnItemClickListener mItemListener = new OnItemClickListener() {
+        @Override
+        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+            final DocumentStack stack = mAdapter.getItem(position);
+            ((DocumentsActivity) getActivity()).onStackPicked(stack);
+        }
+    };
+
+    public static class RecentsCreateLoader extends UriDerivativeLoader<Uri, List<DocumentStack>> {
+        public RecentsCreateLoader(Context context) {
+            super(context, RecentsProvider.buildRecent());
+        }
+
+        @Override
+        public List<DocumentStack> loadInBackground(Uri uri, CancellationSignal signal) {
+            final ArrayList<DocumentStack> result = Lists.newArrayList();
+
+            final ContentResolver resolver = getContext().getContentResolver();
+            final Cursor cursor = resolver.query(
+                    uri, null, null, null, RecentColumns.TIMESTAMP + " DESC", signal);
+            try {
+                while (cursor != null && cursor.moveToNext()) {
+                    final byte[] rawStack = cursor.getBlob(
+                            cursor.getColumnIndex(RecentColumns.STACK));
+                    try {
+                        final DocumentStack stack = new DocumentStack();
+                        stack.read(new DataInputStream(new ByteArrayInputStream(rawStack)));
+                        result.add(stack);
+                    } catch (IOException e) {
+                        Log.w(TAG, "Failed to resolve stack: " + e);
+                    }
+                }
+            } finally {
+                IoUtils.closeQuietly(cursor);
+            }
+
+            return result;
+        }
+    }
+
+    private class DocumentStackAdapter extends BaseAdapter {
+        private List<DocumentStack> mStacks;
+
+        public DocumentStackAdapter() {
+        }
+
+        public void swapStacks(List<DocumentStack> stacks) {
+            mStacks = stacks;
+            notifyDataSetChanged();
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            final Context context = parent.getContext();
+            final RootsCache roots = DocumentsApplication.getRootsCache(context);
+
+            if (convertView == null) {
+                final LayoutInflater inflater = LayoutInflater.from(context);
+                convertView = inflater.inflate(R.layout.item_doc_list, parent, false);
+            }
+
+            final ImageView iconMime = (ImageView) convertView.findViewById(R.id.icon_mime);
+            final TextView title = (TextView) convertView.findViewById(android.R.id.title);
+            final View line2 = convertView.findViewById(R.id.line2);
+
+            final DocumentStack stack = getItem(position);
+            iconMime.setImageDrawable(stack.root.loadIcon(context));
+
+            final Drawable crumb = context.getResources()
+                    .getDrawable(R.drawable.ic_breadcrumb_arrow);
+            crumb.setBounds(0, 0, crumb.getIntrinsicWidth(), crumb.getIntrinsicHeight());
+
+            final SpannableStringBuilder builder = new SpannableStringBuilder();
+            builder.append(stack.root.title);
+            appendDrawable(builder, crumb);
+            for (int i = stack.size() - 2; i >= 0; i--) {
+                builder.append(stack.get(i).displayName);
+                if (i > 0) {
+                    appendDrawable(builder, crumb);
+                }
+            }
+            title.setText(builder);
+            title.setEllipsize(TruncateAt.MIDDLE);
+
+            line2.setVisibility(View.GONE);
+
+            return convertView;
+        }
+
+        @Override
+        public int getCount() {
+            return mStacks != null ? mStacks.size() : 0;
+        }
+
+        @Override
+        public DocumentStack getItem(int position) {
+            return mStacks.get(position);
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return getItem(position).hashCode();
+        }
+    }
+
+    private static void appendDrawable(SpannableStringBuilder b, Drawable d) {
+        final int length = b.length();
+        b.append("\u232a");
+        b.setSpan(new ImageSpan(d), length, b.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RecentsProvider.java b/packages/DocumentsUI/src/com/android/documentsui/RecentsProvider.java
new file mode 100644
index 0000000..af79c93
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/RecentsProvider.java
@@ -0,0 +1,223 @@
+/*
+ * 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.documentsui;
+
+import android.content.ContentProvider;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.net.Uri;
+import android.provider.DocumentsContract.Document;
+import android.provider.DocumentsContract.Root;
+import android.text.format.DateUtils;
+import android.util.Log;
+
+public class RecentsProvider extends ContentProvider {
+    private static final String TAG = "RecentsProvider";
+
+    public static final long MAX_HISTORY_IN_MILLIS = DateUtils.DAY_IN_MILLIS * 45;
+
+    private static final String AUTHORITY = "com.android.documentsui.recents";
+
+    private static final UriMatcher sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+
+    private static final int URI_RECENT = 1;
+    private static final int URI_STATE = 2;
+    private static final int URI_RESUME = 3;
+
+    static {
+        sMatcher.addURI(AUTHORITY, "recent", URI_RECENT);
+        // state/authority/rootId/docId
+        sMatcher.addURI(AUTHORITY, "state/*/*/*", URI_STATE);
+        // resume/packageName
+        sMatcher.addURI(AUTHORITY, "resume/*", URI_RESUME);
+    }
+
+    public static final String TABLE_RECENT = "recent";
+    public static final String TABLE_STATE = "state";
+    public static final String TABLE_RESUME = "resume";
+
+    public static class RecentColumns {
+        public static final String STACK = "stack";
+        public static final String TIMESTAMP = "timestamp";
+    }
+
+    public static class StateColumns {
+        public static final String AUTHORITY = "authority";
+        public static final String ROOT_ID = Root.COLUMN_ROOT_ID;
+        public static final String DOCUMENT_ID = Document.COLUMN_DOCUMENT_ID;
+        public static final String MODE = "mode";
+        public static final String SORT_ORDER = "sortOrder";
+    }
+
+    public static class ResumeColumns {
+        public static final String PACKAGE_NAME = "package_name";
+        public static final String STACK = "stack";
+        public static final String TIMESTAMP = "timestamp";
+    }
+
+    public static Uri buildRecent() {
+        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
+                .authority(AUTHORITY).appendPath("recent").build();
+    }
+
+    public static Uri buildState(String authority, String rootId, String documentId) {
+        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(AUTHORITY)
+                .appendPath("state").appendPath(authority).appendPath(rootId).appendPath(documentId)
+                .build();
+    }
+
+    public static Uri buildResume(String packageName) {
+        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
+                .authority(AUTHORITY).appendPath("resume").appendPath(packageName).build();
+    }
+
+    private DatabaseHelper mHelper;
+
+    private static class DatabaseHelper extends SQLiteOpenHelper {
+        private static final String DB_NAME = "recents.db";
+
+        private static final int VERSION_INIT = 1;
+        private static final int VERSION_AS_BLOB = 3;
+
+        public DatabaseHelper(Context context) {
+            super(context, DB_NAME, null, VERSION_AS_BLOB);
+        }
+
+        @Override
+        public void onCreate(SQLiteDatabase db) {
+
+            db.execSQL("CREATE TABLE " + TABLE_RECENT + " (" +
+                    RecentColumns.STACK + " BLOB PRIMARY KEY ON CONFLICT REPLACE," +
+                    RecentColumns.TIMESTAMP + " INTEGER" +
+                    ")");
+
+            db.execSQL("CREATE TABLE " + TABLE_STATE + " (" +
+                    StateColumns.AUTHORITY + " TEXT," +
+                    StateColumns.ROOT_ID + " TEXT," +
+                    StateColumns.DOCUMENT_ID + " TEXT," +
+                    StateColumns.MODE + " INTEGER," +
+                    StateColumns.SORT_ORDER + " INTEGER," +
+                    "PRIMARY KEY (" + StateColumns.AUTHORITY + ", " + StateColumns.ROOT_ID + ", "
+                    + StateColumns.DOCUMENT_ID + ")" +
+                    ")");
+
+            db.execSQL("CREATE TABLE " + TABLE_RESUME + " (" +
+                    ResumeColumns.PACKAGE_NAME + " TEXT PRIMARY KEY ON CONFLICT REPLACE," +
+                    ResumeColumns.STACK + " BLOB," +
+                    ResumeColumns.TIMESTAMP + " INTEGER" +
+                    ")");
+        }
+
+        @Override
+        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+            Log.w(TAG, "Upgrading database; wiping app data");
+            db.execSQL("DROP TABLE IF EXISTS " + TABLE_RECENT);
+            db.execSQL("DROP TABLE IF EXISTS " + TABLE_STATE);
+            db.execSQL("DROP TABLE IF EXISTS " + TABLE_RESUME);
+            onCreate(db);
+        }
+    }
+
+    @Override
+    public boolean onCreate() {
+        mHelper = new DatabaseHelper(getContext());
+        return true;
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+            String sortOrder) {
+        final SQLiteDatabase db = mHelper.getReadableDatabase();
+        switch (sMatcher.match(uri)) {
+            case URI_RECENT:
+                final long cutoff = System.currentTimeMillis() - MAX_HISTORY_IN_MILLIS;
+                return db.query(TABLE_RECENT, projection, RecentColumns.TIMESTAMP + ">" + cutoff,
+                        null, null, null, sortOrder);
+            case URI_STATE:
+                final String authority = uri.getPathSegments().get(1);
+                final String rootId = uri.getPathSegments().get(2);
+                final String documentId = uri.getPathSegments().get(3);
+                return db.query(TABLE_STATE, projection, StateColumns.AUTHORITY + "=? AND "
+                        + StateColumns.ROOT_ID + "=? AND " + StateColumns.DOCUMENT_ID + "=?",
+                        new String[] { authority, rootId, documentId }, null, null, sortOrder);
+            case URI_RESUME:
+                final String packageName = uri.getPathSegments().get(1);
+                return db.query(TABLE_RESUME, projection, ResumeColumns.PACKAGE_NAME + "=?",
+                        new String[] { packageName }, null, null, sortOrder);
+            default:
+                throw new UnsupportedOperationException("Unsupported Uri " + uri);
+        }
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        return null;
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        final SQLiteDatabase db = mHelper.getWritableDatabase();
+        switch (sMatcher.match(uri)) {
+            case URI_RECENT:
+                values.put(RecentColumns.TIMESTAMP, System.currentTimeMillis());
+                db.insert(TABLE_RECENT, null, values);
+                final long cutoff = System.currentTimeMillis() - MAX_HISTORY_IN_MILLIS;
+                db.delete(TABLE_RECENT, RecentColumns.TIMESTAMP + "<" + cutoff, null);
+                return uri;
+            case URI_STATE:
+                final String authority = uri.getPathSegments().get(1);
+                final String rootId = uri.getPathSegments().get(2);
+                final String documentId = uri.getPathSegments().get(3);
+
+                final ContentValues key = new ContentValues();
+                key.put(StateColumns.AUTHORITY, authority);
+                key.put(StateColumns.ROOT_ID, rootId);
+                key.put(StateColumns.DOCUMENT_ID, documentId);
+
+                // Ensure that row exists, then update with changed values
+                db.insertWithOnConflict(TABLE_STATE, null, key, SQLiteDatabase.CONFLICT_IGNORE);
+                db.update(TABLE_STATE, values, StateColumns.AUTHORITY + "=? AND "
+                        + StateColumns.ROOT_ID + "=? AND " + StateColumns.DOCUMENT_ID + "=?",
+                        new String[] { authority, rootId, documentId });
+
+                return uri;
+            case URI_RESUME:
+                final String packageName = uri.getPathSegments().get(1);
+                values.put(ResumeColumns.PACKAGE_NAME, packageName);
+                values.put(ResumeColumns.TIMESTAMP, System.currentTimeMillis());
+                db.insert(TABLE_RESUME, null, values);
+                return uri;
+            default:
+                throw new UnsupportedOperationException("Unsupported Uri " + uri);
+        }
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        throw new UnsupportedOperationException("Unsupported Uri " + uri);
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        throw new UnsupportedOperationException("Unsupported Uri " + uri);
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootCursorWrapper.java b/packages/DocumentsUI/src/com/android/documentsui/RootCursorWrapper.java
new file mode 100644
index 0000000..0b58218
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootCursorWrapper.java
@@ -0,0 +1,137 @@
+/*
+ * 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.documentsui;
+
+import android.database.AbstractCursor;
+import android.database.Cursor;
+import android.os.Bundle;
+
+/**
+ * Cursor wrapper that adds columns to identify which root a document came from.
+ */
+public class RootCursorWrapper extends AbstractCursor {
+    private final String mAuthority;
+    private final String mRootId;
+
+    private final Cursor mCursor;
+    private final int mCount;
+
+    private final String[] mColumnNames;
+
+    private final int mAuthorityIndex;
+    private final int mRootIdIndex;
+
+    public static final String COLUMN_AUTHORITY = "android:authority";
+    public static final String COLUMN_ROOT_ID = "android:rootId";
+
+    public RootCursorWrapper(String authority, String rootId, Cursor cursor, int maxCount) {
+        mAuthority = authority;
+        mRootId = rootId;
+        mCursor = cursor;
+
+        final int count = cursor.getCount();
+        if (maxCount > 0 && count > maxCount) {
+            mCount = maxCount;
+        } else {
+            mCount = count;
+        }
+
+        if (cursor.getColumnIndex(COLUMN_AUTHORITY) != -1
+                || cursor.getColumnIndex(COLUMN_ROOT_ID) != -1) {
+            throw new IllegalArgumentException("Cursor contains internal columns!");
+        }
+        final String[] before = cursor.getColumnNames();
+        mColumnNames = new String[before.length + 2];
+        System.arraycopy(before, 0, mColumnNames, 0, before.length);
+        mAuthorityIndex = before.length;
+        mRootIdIndex = before.length + 1;
+        mColumnNames[mAuthorityIndex] = COLUMN_AUTHORITY;
+        mColumnNames[mRootIdIndex] = COLUMN_ROOT_ID;
+    }
+
+    @Override
+    public Bundle getExtras() {
+        return mCursor.getExtras();
+    }
+
+    @Override
+    public void close() {
+        super.close();
+        mCursor.close();
+    }
+
+    @Override
+    public boolean onMove(int oldPosition, int newPosition) {
+        return mCursor.moveToPosition(newPosition);
+    }
+
+    @Override
+    public String[] getColumnNames() {
+        return mColumnNames;
+    }
+
+    @Override
+    public int getCount() {
+        return mCount;
+    }
+
+    @Override
+    public double getDouble(int column) {
+        return mCursor.getDouble(column);
+    }
+
+    @Override
+    public float getFloat(int column) {
+        return mCursor.getFloat(column);
+    }
+
+    @Override
+    public int getInt(int column) {
+        return mCursor.getInt(column);
+    }
+
+    @Override
+    public long getLong(int column) {
+        return mCursor.getLong(column);
+    }
+
+    @Override
+    public short getShort(int column) {
+        return mCursor.getShort(column);
+    }
+
+    @Override
+    public String getString(int column) {
+        if (column == mAuthorityIndex) {
+            return mAuthority;
+        } else if (column == mRootIdIndex) {
+            return mRootId;
+        } else {
+            return mCursor.getString(column);
+        }
+    }
+
+    @Override
+    public int getType(int column) {
+        return mCursor.getType(column);
+    }
+
+    @Override
+    public boolean isNull(int column) {
+        return mCursor.isNull(column);
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
new file mode 100644
index 0000000..9b54948
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
@@ -0,0 +1,204 @@
+/*
+ * 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.documentsui;
+
+import static com.android.documentsui.DocumentsActivity.TAG;
+
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.ProviderInfo;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.DocumentsContract;
+import android.provider.DocumentsContract.Root;
+import android.util.Log;
+
+import com.android.documentsui.DocumentsActivity.State;
+import com.android.documentsui.model.RootInfo;
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Objects;
+import com.google.android.collect.Lists;
+
+import libcore.io.IoUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Cache of known storage backends and their roots.
+ */
+public class RootsCache {
+
+    // TODO: cache roots in local provider to avoid spinning up backends
+    // TODO: root updates should trigger UI refresh
+
+    private static final boolean RECENTS_ENABLED = true;
+
+    private final Context mContext;
+
+    public List<RootInfo> mRoots = Lists.newArrayList();
+
+    private RootInfo mRecentsRoot;
+
+    public RootsCache(Context context) {
+        mContext = context;
+        update();
+    }
+
+    /**
+     * Gather roots from all known storage providers.
+     */
+    @GuardedBy("ActivityThread")
+    public void update() {
+        mRoots.clear();
+
+        if (RECENTS_ENABLED) {
+            // Create special root for recents
+            final RootInfo root = new RootInfo();
+            root.rootType = Root.ROOT_TYPE_SHORTCUT;
+            root.icon = R.drawable.ic_root_recent;
+            root.flags = Root.FLAG_LOCAL_ONLY | Root.FLAG_SUPPORTS_CREATE;
+            root.title = mContext.getString(R.string.root_recent);
+            root.availableBytes = -1;
+
+            mRoots.add(root);
+            mRecentsRoot = root;
+        }
+
+        // Query for other storage backends
+        final ContentResolver resolver = mContext.getContentResolver();
+        final PackageManager pm = mContext.getPackageManager();
+        final List<ProviderInfo> providers = pm.queryContentProviders(
+                null, -1, PackageManager.GET_META_DATA);
+        for (ProviderInfo info : providers) {
+            if (info.metaData != null && info.metaData.containsKey(
+                    DocumentsContract.META_DATA_DOCUMENT_PROVIDER)) {
+
+                // TODO: populate roots on background thread, and cache results
+                final Uri rootsUri = DocumentsContract.buildRootsUri(info.authority);
+                final ContentProviderClient client = resolver
+                        .acquireUnstableContentProviderClient(info.authority);
+                Cursor cursor = null;
+                try {
+                    cursor = client.query(rootsUri, null, null, null, null);
+                    while (cursor.moveToNext()) {
+                        final RootInfo root = RootInfo.fromRootsCursor(info.authority, cursor);
+                        mRoots.add(root);
+                    }
+                } catch (Exception e) {
+                    Log.w(TAG, "Failed to load some roots from " + info.authority + ": " + e);
+                } finally {
+                    IoUtils.closeQuietly(cursor);
+                    ContentProviderClient.closeQuietly(client);
+                }
+            }
+        }
+
+        Log.d(TAG, "Update found " + mRoots.size() + " roots");
+    }
+
+    @Deprecated
+    public RootInfo findRoot(Uri uri) {
+        final String authority = uri.getAuthority();
+        final String docId = DocumentsContract.getDocumentId(uri);
+        for (RootInfo root : mRoots) {
+            if (Objects.equal(root.authority, authority) && Objects.equal(root.documentId, docId)) {
+                return root;
+            }
+        }
+        return null;
+    }
+
+    @GuardedBy("ActivityThread")
+    public RootInfo getRoot(String authority, String rootId) {
+        for (RootInfo root : mRoots) {
+            if (Objects.equal(root.authority, authority) && Objects.equal(root.rootId, rootId)) {
+                return root;
+            }
+        }
+        return null;
+    }
+
+    @GuardedBy("ActivityThread")
+    public boolean isIconUnique(RootInfo root) {
+        final int rootIcon = root.derivedIcon != 0 ? root.derivedIcon : root.icon;
+        for (RootInfo test : mRoots) {
+            if (Objects.equal(test.authority, root.authority)) {
+                if (Objects.equal(test.rootId, root.rootId)) {
+                    continue;
+                }
+                final int testIcon = test.derivedIcon != 0 ? test.derivedIcon : test.icon;
+                if (testIcon == rootIcon) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    @GuardedBy("ActivityThread")
+    public RootInfo getRecentsRoot() {
+        return mRecentsRoot;
+    }
+
+    @GuardedBy("ActivityThread")
+    public boolean isRecentsRoot(RootInfo root) {
+        return mRecentsRoot == root;
+    }
+
+    @GuardedBy("ActivityThread")
+    public List<RootInfo> getRoots() {
+        return mRoots;
+    }
+
+    @GuardedBy("ActivityThread")
+    public List<RootInfo> getMatchingRoots(State state) {
+        return getMatchingRoots(mRoots, state);
+    }
+
+    public static List<RootInfo> getMatchingRoots(List<RootInfo> roots, State state) {
+        ArrayList<RootInfo> matching = Lists.newArrayList();
+        for (RootInfo root : roots) {
+            final boolean supportsCreate = (root.flags & Root.FLAG_SUPPORTS_CREATE) != 0;
+            final boolean advanced = (root.flags & Root.FLAG_ADVANCED) != 0;
+            final boolean localOnly = (root.flags & Root.FLAG_LOCAL_ONLY) != 0;
+            final boolean empty = (root.flags & Root.FLAG_EMPTY) != 0;
+
+            // Exclude read-only devices when creating
+            if (state.action == State.ACTION_CREATE && !supportsCreate) continue;
+            // Exclude advanced devices when not requested
+            if (!state.showAdvanced && advanced) continue;
+            // Exclude non-local devices when local only
+            if (state.localOnly && !localOnly) continue;
+            // Only show empty roots when creating
+            if (state.action != State.ACTION_CREATE && empty) continue;
+
+            // Only include roots that serve requested content
+            final boolean overlap =
+                    MimePredicate.mimeMatches(root.derivedMimeTypes, state.acceptMimes) ||
+                    MimePredicate.mimeMatches(state.acceptMimes, root.derivedMimeTypes);
+            if (!overlap) {
+                continue;
+            }
+
+            matching.add(root);
+        }
+        return matching;
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
new file mode 100644
index 0000000..908729c
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
@@ -0,0 +1,302 @@
+/*
+ * 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.documentsui;
+
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.app.FragmentTransaction;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.provider.DocumentsContract.Root;
+import android.text.TextUtils;
+import android.text.format.Formatter;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.Space;
+import android.widget.TextView;
+
+import com.android.documentsui.DocumentsActivity.State;
+import com.android.documentsui.SectionedListAdapter.SectionAdapter;
+import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.model.RootInfo;
+import com.android.internal.util.Objects;
+
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * Display list of known storage backend roots.
+ */
+public class RootsFragment extends Fragment {
+
+    private ListView mList;
+    private SectionedRootsAdapter mAdapter;
+
+    private static final String EXTRA_INCLUDE_APPS = "includeApps";
+
+    public static void show(FragmentManager fm, Intent includeApps) {
+        final Bundle args = new Bundle();
+        args.putParcelable(EXTRA_INCLUDE_APPS, includeApps);
+
+        final RootsFragment fragment = new RootsFragment();
+        fragment.setArguments(args);
+
+        final FragmentTransaction ft = fm.beginTransaction();
+        ft.replace(R.id.container_roots, fragment);
+        ft.commitAllowingStateLoss();
+    }
+
+    public static RootsFragment get(FragmentManager fm) {
+        return (RootsFragment) fm.findFragmentById(R.id.container_roots);
+    }
+
+    @Override
+    public View onCreateView(
+            LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        final Context context = inflater.getContext();
+
+        final View view = inflater.inflate(R.layout.fragment_roots, container, false);
+        mList = (ListView) view.findViewById(android.R.id.list);
+        mList.setOnItemClickListener(mItemListener);
+        mList.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+
+        return view;
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        updateRootsAdapter();
+    }
+
+    private void updateRootsAdapter() {
+        final Context context = getActivity();
+
+        final State state = ((DocumentsActivity) context).getDisplayState();
+        state.showAdvanced = SettingsActivity.getDisplayAdvancedDevices(context);
+
+        final RootsCache roots = DocumentsApplication.getRootsCache(context);
+        final List<RootInfo> matchingRoots = roots.getMatchingRoots(state);
+        final Intent includeApps = getArguments().getParcelable(EXTRA_INCLUDE_APPS);
+
+        mAdapter = new SectionedRootsAdapter(context, matchingRoots, includeApps);
+        mList.setAdapter(mAdapter);
+
+        onCurrentRootChanged();
+    }
+
+    public void onCurrentRootChanged() {
+        if (mAdapter == null) return;
+
+        final RootInfo root = ((DocumentsActivity) getActivity()).getCurrentRoot();
+        for (int i = 0; i < mAdapter.getCount(); i++) {
+            final Object item = mAdapter.getItem(i);
+            if (Objects.equal(item, root)) {
+                mList.setItemChecked(i, true);
+                return;
+            }
+        }
+    }
+
+    private OnItemClickListener mItemListener = new OnItemClickListener() {
+        @Override
+        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+            final DocumentsActivity activity = DocumentsActivity.get(RootsFragment.this);
+            final Object item = mAdapter.getItem(position);
+            if (item instanceof RootInfo) {
+                activity.onRootPicked((RootInfo) item, true);
+            } else if (item instanceof ResolveInfo) {
+                activity.onAppPicked((ResolveInfo) item);
+            } else {
+                throw new IllegalStateException("Unknown root: " + item);
+            }
+        }
+    };
+
+    private static class RootsAdapter extends ArrayAdapter<RootInfo> implements SectionAdapter {
+        public RootsAdapter(Context context) {
+            super(context, 0);
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            final Context context = parent.getContext();
+            if (convertView == null) {
+                convertView = LayoutInflater.from(context)
+                        .inflate(R.layout.item_root, parent, false);
+            }
+
+            final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon);
+            final TextView title = (TextView) convertView.findViewById(android.R.id.title);
+            final TextView summary = (TextView) convertView.findViewById(android.R.id.summary);
+
+            final RootInfo root = getItem(position);
+            icon.setImageDrawable(root.loadIcon(context));
+            title.setText(root.title);
+
+            // Device summary is always available space
+            final String summaryText;
+            if (root.rootType == Root.ROOT_TYPE_DEVICE && root.availableBytes >= 0) {
+                summaryText = context.getString(R.string.root_available_bytes,
+                        Formatter.formatFileSize(context, root.availableBytes));
+            } else {
+                summaryText = root.summary;
+            }
+
+            summary.setText(summaryText);
+            summary.setVisibility(TextUtils.isEmpty(summaryText) ? View.GONE : View.VISIBLE);
+
+            return convertView;
+        }
+
+        @Override
+        public View getHeaderView(View convertView, ViewGroup parent) {
+            if (convertView == null) {
+                convertView = new Space(parent.getContext());
+            }
+            return convertView;
+        }
+    }
+
+    private static class AppsAdapter extends ArrayAdapter<ResolveInfo> implements SectionAdapter {
+        public AppsAdapter(Context context) {
+            super(context, 0);
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            final Context context = parent.getContext();
+            final PackageManager pm = context.getPackageManager();
+            if (convertView == null) {
+                convertView = LayoutInflater.from(context)
+                        .inflate(R.layout.item_root, parent, false);
+            }
+
+            final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon);
+            final TextView title = (TextView) convertView.findViewById(android.R.id.title);
+            final TextView summary = (TextView) convertView.findViewById(android.R.id.summary);
+
+            final ResolveInfo info = getItem(position);
+            icon.setImageDrawable(info.loadIcon(pm));
+            title.setText(info.loadLabel(pm));
+
+            // TODO: match existing summary behavior from disambig dialog
+            summary.setVisibility(View.GONE);
+
+            return convertView;
+        }
+
+        @Override
+        public View getHeaderView(View convertView, ViewGroup parent) {
+            if (convertView == null) {
+                convertView = LayoutInflater.from(parent.getContext())
+                        .inflate(R.layout.item_root_header, parent, false);
+            }
+
+            final TextView title = (TextView) convertView.findViewById(android.R.id.title);
+            title.setText(R.string.root_type_apps);
+
+            return convertView;
+        }
+    }
+
+    private static class SectionedRootsAdapter extends SectionedListAdapter {
+        private final RootsAdapter mServices;
+        private final RootsAdapter mShortcuts;
+        private final RootsAdapter mDevices;
+        private final AppsAdapter mApps;
+
+        public SectionedRootsAdapter(Context context, List<RootInfo> roots, Intent includeApps) {
+            mServices = new RootsAdapter(context);
+            mShortcuts = new RootsAdapter(context);
+            mDevices = new RootsAdapter(context);
+            mApps = new AppsAdapter(context);
+
+            for (RootInfo root : roots) {
+                switch (root.rootType) {
+                    case Root.ROOT_TYPE_SERVICE:
+                        mServices.add(root);
+                        break;
+                    case Root.ROOT_TYPE_SHORTCUT:
+                        mShortcuts.add(root);
+                        break;
+                    case Root.ROOT_TYPE_DEVICE:
+                        mDevices.add(root);
+                        break;
+                }
+            }
+
+            if (includeApps != null) {
+                final PackageManager pm = context.getPackageManager();
+                final List<ResolveInfo> infos = pm.queryIntentActivities(
+                        includeApps, PackageManager.MATCH_DEFAULT_ONLY);
+
+                // Omit ourselves from the list
+                for (ResolveInfo info : infos) {
+                    if (!context.getPackageName().equals(info.activityInfo.packageName)) {
+                        mApps.add(info);
+                    }
+                }
+            }
+
+            final RootComparator comp = new RootComparator();
+            mServices.sort(comp);
+            mShortcuts.sort(comp);
+            mDevices.sort(comp);
+
+            if (mShortcuts.getCount() > 0) {
+                addSection(mShortcuts);
+            }
+            if (mDevices.getCount() > 0) {
+                addSection(mDevices);
+            }
+            if (mServices.getCount() > 0) {
+                addSection(mServices);
+            }
+            if (mApps.getCount() > 0) {
+                addSection(mApps);
+            }
+        }
+    }
+
+    public static class RootComparator implements Comparator<RootInfo> {
+        @Override
+        public int compare(RootInfo lhs, RootInfo rhs) {
+            if (lhs.authority == null) {
+                return -1;
+            } else if (rhs.authority == null) {
+                return 1;
+            }
+
+            final int score = DocumentInfo.compareToIgnoreCaseNullable(lhs.title, rhs.title);
+            if (score != 0) {
+                return score;
+            } else {
+                return DocumentInfo.compareToIgnoreCaseNullable(lhs.summary, rhs.summary);
+            }
+        }
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/SaveFragment.java b/packages/DocumentsUI/src/com/android/documentsui/SaveFragment.java
new file mode 100644
index 0000000..dc5b64a
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/SaveFragment.java
@@ -0,0 +1,144 @@
+/*
+ * 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.documentsui;
+
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.app.FragmentTransaction;
+import android.content.Context;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ImageView;
+
+import com.android.documentsui.model.DocumentInfo;
+
+/**
+ * Display document title editor and save button.
+ */
+public class SaveFragment extends Fragment {
+    public static final String TAG = "SaveFragment";
+
+    private DocumentInfo mReplaceTarget;
+    private EditText mDisplayName;
+    private Button mSave;
+    private boolean mIgnoreNextEdit;
+
+    private static final String EXTRA_MIME_TYPE = "mime_type";
+    private static final String EXTRA_DISPLAY_NAME = "display_name";
+
+    public static void show(FragmentManager fm, String mimeType, String displayName) {
+        final Bundle args = new Bundle();
+        args.putString(EXTRA_MIME_TYPE, mimeType);
+        args.putString(EXTRA_DISPLAY_NAME, displayName);
+
+        final SaveFragment fragment = new SaveFragment();
+        fragment.setArguments(args);
+
+        final FragmentTransaction ft = fm.beginTransaction();
+        ft.replace(R.id.container_save, fragment, TAG);
+        ft.commitAllowingStateLoss();
+    }
+
+    public static SaveFragment get(FragmentManager fm) {
+        return (SaveFragment) fm.findFragmentByTag(TAG);
+    }
+
+    @Override
+    public View onCreateView(
+            LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        final Context context = inflater.getContext();
+        final RootsCache roots = DocumentsApplication.getRootsCache(context);
+
+        final View view = inflater.inflate(R.layout.fragment_save, container, false);
+
+        final ImageView icon = (ImageView) view.findViewById(android.R.id.icon);
+        icon.setImageDrawable(
+                IconUtils.loadMimeIcon(context, getArguments().getString(EXTRA_MIME_TYPE)));
+
+        mDisplayName = (EditText) view.findViewById(android.R.id.title);
+        mDisplayName.addTextChangedListener(mDisplayNameWatcher);
+        mDisplayName.setText(getArguments().getString(EXTRA_DISPLAY_NAME));
+
+        mSave = (Button) view.findViewById(android.R.id.button1);
+        mSave.setOnClickListener(mSaveListener);
+        mSave.setEnabled(false);
+
+        return view;
+    }
+
+    private TextWatcher mDisplayNameWatcher = new TextWatcher() {
+        @Override
+        public void onTextChanged(CharSequence s, int start, int before, int count) {
+            if (mIgnoreNextEdit) {
+                mIgnoreNextEdit = false;
+            } else {
+                Log.d(TAG, "onTextChanged!");
+                mReplaceTarget = null;
+            }
+        }
+
+        @Override
+        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+            // ignored
+        }
+
+        @Override
+        public void afterTextChanged(Editable s) {
+            // ignored
+        }
+    };
+
+    private View.OnClickListener mSaveListener = new View.OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            final DocumentsActivity activity = DocumentsActivity.get(SaveFragment.this);
+            if (mReplaceTarget != null) {
+                activity.onSaveRequested(mReplaceTarget);
+            } else {
+                final String mimeType = getArguments().getString(EXTRA_MIME_TYPE);
+                final String displayName = mDisplayName.getText().toString();
+                activity.onSaveRequested(mimeType, displayName);
+            }
+        }
+    };
+
+    /**
+     * Set given document as target for in-place writing if user hits save
+     * without changing the filename. Can be set to {@code null} if user
+     * navigates outside the target directory.
+     */
+    public void setReplaceTarget(DocumentInfo replaceTarget) {
+        mReplaceTarget = replaceTarget;
+
+        if (mReplaceTarget != null) {
+            getArguments().putString(EXTRA_DISPLAY_NAME, replaceTarget.displayName);
+            mIgnoreNextEdit = true;
+            mDisplayName.setText(replaceTarget.displayName);
+        }
+    }
+
+    public void setSaveEnabled(boolean enabled) {
+        mSave.setEnabled(enabled);
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/SectionedListAdapter.java b/packages/DocumentsUI/src/com/android/documentsui/SectionedListAdapter.java
new file mode 100644
index 0000000..088e3fa
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/SectionedListAdapter.java
@@ -0,0 +1,166 @@
+/*
+ * 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.documentsui;
+
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.BaseAdapter;
+import android.widget.ListAdapter;
+
+import com.google.android.collect.Lists;
+
+import java.util.ArrayList;
+
+/**
+ * Adapter that combines multiple adapters as sections, asking each section to
+ * provide a header, and correctly handling item types across child adapters.
+ */
+public class SectionedListAdapter extends BaseAdapter {
+    private ArrayList<SectionAdapter> mSections = Lists.newArrayList();
+
+    public interface SectionAdapter extends ListAdapter {
+        public View getHeaderView(View convertView, ViewGroup parent);
+    }
+
+    public void clearSections() {
+        mSections.clear();
+        notifyDataSetChanged();
+    }
+
+    /**
+     * After mutating sections, you <em>must</em>
+     * {@link AdapterView#setAdapter(android.widget.Adapter)} to correctly
+     * recount view types.
+     */
+    public void addSection(SectionAdapter adapter) {
+        mSections.add(adapter);
+        notifyDataSetChanged();
+    }
+
+    @Override
+    public int getCount() {
+        int count = 0;
+        final int size = mSections.size();
+        for (int i = 0; i < size; i++) {
+            count += mSections.get(i).getCount() + 1;
+        }
+        return count;
+    }
+
+    @Override
+    public Object getItem(int position) {
+        final int size = mSections.size();
+        for (int i = 0; i < size; i++) {
+            final SectionAdapter section = mSections.get(i);
+            final int sectionSize = section.getCount() + 1;
+
+            // Check if position inside this section
+            if (position == 0) {
+                return section;
+            } else if (position < sectionSize) {
+                return section.getItem(position - 1);
+            }
+
+            // Otherwise jump into next section
+            position -= sectionSize;
+        }
+        throw new IllegalStateException("Unknown position " + position);
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return position;
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        final int size = mSections.size();
+        for (int i = 0; i < size; i++) {
+            final SectionAdapter section = mSections.get(i);
+            final int sectionSize = section.getCount() + 1;
+
+            // Check if position inside this section
+            if (position == 0) {
+                return section.getHeaderView(convertView, parent);
+            } else if (position < sectionSize) {
+                return section.getView(position - 1, convertView, parent);
+            }
+
+            // Otherwise jump into next section
+            position -= sectionSize;
+        }
+        throw new IllegalStateException("Unknown position " + position);
+    }
+
+    @Override
+    public boolean areAllItemsEnabled() {
+        return false;
+    }
+
+    @Override
+    public boolean isEnabled(int position) {
+        final int size = mSections.size();
+        for (int i = 0; i < size; i++) {
+            final SectionAdapter section = mSections.get(i);
+            final int sectionSize = section.getCount() + 1;
+
+            // Check if position inside this section
+            if (position == 0) {
+                return false;
+            } else if (position < sectionSize) {
+                return section.isEnabled(position - 1);
+            }
+
+            // Otherwise jump into next section
+            position -= sectionSize;
+        }
+        throw new IllegalStateException("Unknown position " + position);
+    }
+
+    @Override
+    public int getItemViewType(int position) {
+        int type = 1;
+        final int size = mSections.size();
+        for (int i = 0; i < size; i++) {
+            final SectionAdapter section = mSections.get(i);
+            final int sectionSize = section.getCount() + 1;
+
+            // Check if position inside this section
+            if (position == 0) {
+                return 0;
+            } else if (position < sectionSize) {
+                return type + section.getItemViewType(position - 1);
+            }
+
+            // Otherwise jump into next section
+            position -= sectionSize;
+            type += section.getViewTypeCount();
+        }
+        throw new IllegalStateException("Unknown position " + position);
+    }
+
+    @Override
+    public int getViewTypeCount() {
+        int count = 1;
+        final int size = mSections.size();
+        for (int i = 0; i < size; i++) {
+            count += mSections.get(i).getViewTypeCount();
+        }
+        return count;
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/SettingsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/SettingsActivity.java
new file mode 100644
index 0000000..a85f6a9
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/SettingsActivity.java
@@ -0,0 +1,60 @@
+/*
+ * 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.documentsui;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceManager;
+
+public class SettingsActivity extends Activity {
+    private static final String KEY_ADVANCED_DEVICES = "advancedDevices";
+    private static final String KEY_FILE_SIZE = "fileSize";
+
+    public static boolean getDisplayAdvancedDevices(Context context) {
+        return PreferenceManager.getDefaultSharedPreferences(context)
+                .getBoolean(KEY_ADVANCED_DEVICES, false);
+    }
+
+    public static boolean getDisplayFileSize(Context context) {
+        return PreferenceManager.getDefaultSharedPreferences(context)
+                .getBoolean(KEY_FILE_SIZE, false);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        getFragmentManager()
+                .beginTransaction().replace(android.R.id.content, new SettingsFragment()).commit();
+
+        final ActionBar bar = getActionBar();
+        if (bar != null) {
+            bar.setDisplayShowHomeEnabled(false);
+        }
+    }
+
+    public static class SettingsFragment extends PreferenceFragment {
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            addPreferencesFromResource(R.xml.preferences);
+        }
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/SortingCursorWrapper.java b/packages/DocumentsUI/src/com/android/documentsui/SortingCursorWrapper.java
new file mode 100644
index 0000000..19ad2e2
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/SortingCursorWrapper.java
@@ -0,0 +1,262 @@
+/*
+ * 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.documentsui;
+
+import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_DISPLAY_NAME;
+import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_LAST_MODIFIED;
+import static com.android.documentsui.DocumentsActivity.State.SORT_ORDER_SIZE;
+
+import android.database.AbstractCursor;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.provider.DocumentsContract.Document;
+
+/**
+ * Cursor wrapper that presents a sorted view of the underlying cursor. Handles
+ * common {@link Document} sorting modes, such as ordering directories first.
+ */
+public class SortingCursorWrapper extends AbstractCursor {
+    private final Cursor mCursor;
+
+    private final int[] mPosition;
+    private final String[] mValueString;
+    private final long[] mValueLong;
+
+    public SortingCursorWrapper(Cursor cursor, int sortOrder) {
+        mCursor = cursor;
+
+        final int count = cursor.getCount();
+        mPosition = new int[count];
+        switch (sortOrder) {
+            case SORT_ORDER_DISPLAY_NAME:
+                mValueString = new String[count];
+                mValueLong = null;
+                break;
+            case SORT_ORDER_LAST_MODIFIED:
+            case SORT_ORDER_SIZE:
+                mValueString = null;
+                mValueLong = new long[count];
+                break;
+            default:
+                throw new IllegalArgumentException();
+        }
+
+        cursor.moveToPosition(-1);
+        for (int i = 0; i < count; i++) {
+            cursor.moveToNext();
+            mPosition[i] = i;
+
+            switch (sortOrder) {
+                case SORT_ORDER_DISPLAY_NAME:
+                    final String mimeType = cursor.getString(
+                            cursor.getColumnIndex(Document.COLUMN_MIME_TYPE));
+                    final String displayName = cursor.getString(
+                            cursor.getColumnIndex(Document.COLUMN_DISPLAY_NAME));
+                    if (Document.MIME_TYPE_DIR.equals(mimeType)) {
+                        mValueString[i] = '\001' + displayName;
+                    } else {
+                        mValueString[i] = displayName;
+                    }
+                    break;
+                case SORT_ORDER_LAST_MODIFIED:
+                    mValueLong[i] = cursor.getLong(
+                            cursor.getColumnIndex(Document.COLUMN_LAST_MODIFIED));
+                    break;
+                case SORT_ORDER_SIZE:
+                    mValueLong[i] = cursor.getLong(cursor.getColumnIndex(Document.COLUMN_SIZE));
+                    break;
+            }
+        }
+
+        switch (sortOrder) {
+            case SORT_ORDER_DISPLAY_NAME:
+                synchronized (SortingCursorWrapper.class) {
+
+                    binarySort(mPosition, mValueString);
+                }
+                break;
+            case SORT_ORDER_LAST_MODIFIED:
+            case SORT_ORDER_SIZE:
+                binarySort(mPosition, mValueLong);
+                break;
+        }
+    }
+
+    @Override
+    public Bundle getExtras() {
+        return mCursor.getExtras();
+    }
+
+    @Override
+    public void close() {
+        super.close();
+        mCursor.close();
+    }
+
+    @Override
+    public boolean onMove(int oldPosition, int newPosition) {
+        return mCursor.moveToPosition(mPosition[newPosition]);
+    }
+
+    @Override
+    public String[] getColumnNames() {
+        return mCursor.getColumnNames();
+    }
+
+    @Override
+    public int getCount() {
+        return mCursor.getCount();
+    }
+
+    @Override
+    public double getDouble(int column) {
+        return mCursor.getDouble(column);
+    }
+
+    @Override
+    public float getFloat(int column) {
+        return mCursor.getFloat(column);
+    }
+
+    @Override
+    public int getInt(int column) {
+        return mCursor.getInt(column);
+    }
+
+    @Override
+    public long getLong(int column) {
+        return mCursor.getLong(column);
+    }
+
+    @Override
+    public short getShort(int column) {
+        return mCursor.getShort(column);
+    }
+
+    @Override
+    public String getString(int column) {
+        return mCursor.getString(column);
+    }
+
+    @Override
+    public int getType(int column) {
+        return mCursor.getType(column);
+    }
+
+    @Override
+    public boolean isNull(int column) {
+        return mCursor.isNull(column);
+    }
+
+    /**
+     * Borrowed from TimSort.binarySort(), but modified to sort two column
+     * dataset.
+     */
+    private static void binarySort(int[] position, String[] value) {
+        final int count = position.length;
+        for (int start = 1; start < count; start++) {
+            final int pivotPosition = position[start];
+            final String pivotValue = value[start];
+
+            int left = 0;
+            int right = start;
+
+            while (left < right) {
+                int mid = (left + right) >>> 1;
+
+                final String lhs = pivotValue;
+                final String rhs = value[mid];
+                final int compare;
+                if (lhs == null) {
+                    compare = -1;
+                } else if (rhs == null) {
+                    compare = 1;
+                } else {
+                    compare = lhs.compareToIgnoreCase(rhs);
+                }
+
+                if (compare < 0) {
+                    right = mid;
+                } else {
+                    left = mid + 1;
+                }
+            }
+
+            int n = start - left;
+            switch (n) {
+                case 2:
+                    position[left + 2] = position[left + 1];
+                    value[left + 2] = value[left + 1];
+                case 1:
+                    position[left + 1] = position[left];
+                    value[left + 1] = value[left];
+                    break;
+                default:
+                    System.arraycopy(position, left, position, left + 1, n);
+                    System.arraycopy(value, left, value, left + 1, n);
+            }
+
+            position[left] = pivotPosition;
+            value[left] = pivotValue;
+        }
+    }
+
+    /**
+     * Borrowed from TimSort.binarySort(), but modified to sort two column
+     * dataset.
+     */
+    private static void binarySort(int[] position, long[] value) {
+        final int count = position.length;
+        for (int start = 1; start < count; start++) {
+            final int pivotPosition = position[start];
+            final long pivotValue = value[start];
+
+            int left = 0;
+            int right = start;
+
+            while (left < right) {
+                int mid = (left + right) >>> 1;
+
+                final long lhs = pivotValue;
+                final long rhs = value[mid];
+                final int compare = Long.compare(lhs, rhs);
+                if (compare > 0) {
+                    right = mid;
+                } else {
+                    left = mid + 1;
+                }
+            }
+
+            int n = start - left;
+            switch (n) {
+                case 2:
+                    position[left + 2] = position[left + 1];
+                    value[left + 2] = value[left + 1];
+                case 1:
+                    position[left + 1] = position[left];
+                    value[left + 1] = value[left];
+                    break;
+                default:
+                    System.arraycopy(position, left, position, left + 1, n);
+                    System.arraycopy(value, left, value, left + 1, n);
+            }
+
+            position[left] = pivotPosition;
+            value[left] = pivotValue;
+        }
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/TestActivity.java b/packages/DocumentsUI/src/com/android/documentsui/TestActivity.java
new file mode 100644
index 0000000..7b7c3d5
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/TestActivity.java
@@ -0,0 +1,226 @@
+/*
+ * 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.documentsui;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import libcore.io.IoUtils;
+import libcore.io.Streams;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+public class TestActivity extends Activity {
+    private static final String TAG = "TestActivity";
+
+    private static final int CODE_READ = 42;
+    private static final int CODE_WRITE = 43;
+
+    private TextView mResult;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        final Context context = this;
+
+        final LinearLayout view = new LinearLayout(context);
+        view.setOrientation(LinearLayout.VERTICAL);
+
+        final CheckBox multiple = new CheckBox(context);
+        multiple.setText("ALLOW_MULTIPLE");
+        view.addView(multiple);
+        final CheckBox localOnly = new CheckBox(context);
+        localOnly.setText("LOCAL_ONLY");
+        view.addView(localOnly);
+
+        Button button;
+        button = new Button(context);
+        button.setText("OPEN_DOC */*");
+        button.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
+                intent.addCategory(Intent.CATEGORY_OPENABLE);
+                intent.setType("*/*");
+                if (multiple.isChecked()) {
+                    intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
+                }
+                if (localOnly.isChecked()) {
+                    intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
+                }
+                startActivityForResult(intent, CODE_READ);
+            }
+        });
+        view.addView(button);
+
+        button = new Button(context);
+        button.setText("OPEN_DOC image/*");
+        button.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
+                intent.addCategory(Intent.CATEGORY_OPENABLE);
+                intent.setType("image/*");
+                if (multiple.isChecked()) {
+                    intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
+                }
+                if (localOnly.isChecked()) {
+                    intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
+                }
+                startActivityForResult(intent, CODE_READ);
+            }
+        });
+        view.addView(button);
+
+        button = new Button(context);
+        button.setText("OPEN_DOC audio/ogg");
+        button.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
+                intent.addCategory(Intent.CATEGORY_OPENABLE);
+                intent.setType("audio/ogg");
+                if (multiple.isChecked()) {
+                    intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
+                }
+                if (localOnly.isChecked()) {
+                    intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
+                }
+                startActivityForResult(intent, CODE_READ);
+            }
+        });
+        view.addView(button);
+
+        button = new Button(context);
+        button.setText("OPEN_DOC text/plain, application/msword");
+        button.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
+                intent.addCategory(Intent.CATEGORY_OPENABLE);
+                intent.setType("*/*");
+                intent.putExtra(Intent.EXTRA_MIME_TYPES, new String[] {
+                        "text/plain", "application/msword" });
+                if (multiple.isChecked()) {
+                    intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
+                }
+                if (localOnly.isChecked()) {
+                    intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
+                }
+                startActivityForResult(intent, CODE_READ);
+            }
+        });
+        view.addView(button);
+
+        button = new Button(context);
+        button.setText("CREATE_DOC text/plain");
+        button.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
+                intent.addCategory(Intent.CATEGORY_OPENABLE);
+                intent.setType("text/plain");
+                intent.putExtra(Intent.EXTRA_TITLE, "foobar.txt");
+                if (localOnly.isChecked()) {
+                    intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
+                }
+                startActivityForResult(intent, CODE_WRITE);
+            }
+        });
+        view.addView(button);
+
+        button = new Button(context);
+        button.setText("GET_CONTENT */*");
+        button.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
+                intent.addCategory(Intent.CATEGORY_OPENABLE);
+                intent.setType("*/*");
+                if (multiple.isChecked()) {
+                    intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
+                }
+                if (localOnly.isChecked()) {
+                    intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
+                }
+                startActivityForResult(Intent.createChooser(intent, "Kittens!"), CODE_READ);
+            }
+        });
+        view.addView(button);
+
+        mResult = new TextView(context);
+        view.addView(mResult);
+
+        setContentView(view);
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        mResult.setText(null);
+        String result = "resultCode=" + resultCode + ", data=" + String.valueOf(data);
+
+        if (requestCode == CODE_READ) {
+            final Uri uri = data != null ? data.getData() : null;
+            if (uri != null) {
+                InputStream is = null;
+                try {
+                    is = getContentResolver().openInputStream(uri);
+                    final int length = Streams.readFullyNoClose(is).length;
+                    result += "; read length=" + length;
+                } catch (Exception e) {
+                    result += "; ERROR";
+                    Log.w(TAG, "Failed to read " + uri, e);
+                } finally {
+                    IoUtils.closeQuietly(is);
+                }
+            } else {
+                result += "no uri?";
+            }
+        } else if (requestCode == CODE_WRITE) {
+            final Uri uri = data != null ? data.getData() : null;
+            if (uri != null) {
+                OutputStream os = null;
+                try {
+                    os = getContentResolver().openOutputStream(uri);
+                    os.write("THE COMPLETE WORKS OF SHAKESPEARE".getBytes());
+                } catch (Exception e) {
+                    result += "; ERROR";
+                    Log.w(TAG, "Failed to write " + uri, e);
+                } finally {
+                    IoUtils.closeQuietly(os);
+                }
+            } else {
+                result += "no uri?";
+            }
+        }
+
+        Log.d(TAG, result);
+        mResult.setText(result);
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/ThumbnailCache.java b/packages/DocumentsUI/src/com/android/documentsui/ThumbnailCache.java
new file mode 100644
index 0000000..ad7cbf6
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/ThumbnailCache.java
@@ -0,0 +1,32 @@
+/*
+ * 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.documentsui;
+
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.util.LruCache;
+
+public class ThumbnailCache extends LruCache<Uri, Bitmap> {
+    public ThumbnailCache(int maxSizeBytes) {
+        super(maxSizeBytes);
+    }
+
+    @Override
+    protected int sizeOf(Uri key, Bitmap value) {
+        return value.getByteCount();
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/UriDerivativeLoader.java b/packages/DocumentsUI/src/com/android/documentsui/UriDerivativeLoader.java
new file mode 100644
index 0000000..1a5bb0c
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/UriDerivativeLoader.java
@@ -0,0 +1,135 @@
+/*
+ * 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.documentsui;
+
+import android.content.AsyncTaskLoader;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.os.CancellationSignal;
+import android.os.OperationCanceledException;
+
+/**
+ * Loader that derives its data from a Uri. Watches for {@link ContentObserver}
+ * changes while started, manages {@link CancellationSignal}, and caches
+ * returned results.
+ */
+public abstract class UriDerivativeLoader<P, R> extends AsyncTaskLoader<R> {
+    final ForceLoadContentObserver mObserver;
+
+    private final P mParam;
+
+    private R mResult;
+    private CancellationSignal mCancellationSignal;
+
+    @Override
+    public final R loadInBackground() {
+        synchronized (this) {
+            if (isLoadInBackgroundCanceled()) {
+                throw new OperationCanceledException();
+            }
+            mCancellationSignal = new CancellationSignal();
+        }
+        try {
+            return loadInBackground(mParam, mCancellationSignal);
+        } finally {
+            synchronized (this) {
+                mCancellationSignal = null;
+            }
+        }
+    }
+
+    public abstract R loadInBackground(P param, CancellationSignal signal);
+
+    @Override
+    public void cancelLoadInBackground() {
+        super.cancelLoadInBackground();
+
+        synchronized (this) {
+            if (mCancellationSignal != null) {
+                mCancellationSignal.cancel();
+            }
+        }
+    }
+
+    @Override
+    public void deliverResult(R result) {
+        if (isReset()) {
+            closeQuietly(result);
+            return;
+        }
+        R oldResult = mResult;
+        mResult = result;
+
+        if (isStarted()) {
+            super.deliverResult(result);
+        }
+
+        if (oldResult != null && oldResult != result) {
+            closeQuietly(oldResult);
+        }
+    }
+
+    public UriDerivativeLoader(Context context, P param) {
+        super(context);
+        mObserver = new ForceLoadContentObserver();
+        mParam = param;
+    }
+
+    @Override
+    protected void onStartLoading() {
+        if (mResult != null) {
+            deliverResult(mResult);
+        }
+        if (takeContentChanged() || mResult == null) {
+            forceLoad();
+        }
+    }
+
+    @Override
+    protected void onStopLoading() {
+        cancelLoad();
+    }
+
+    @Override
+    public void onCanceled(R result) {
+        closeQuietly(result);
+    }
+
+    @Override
+    protected void onReset() {
+        super.onReset();
+
+        // Ensure the loader is stopped
+        onStopLoading();
+
+        closeQuietly(mResult);
+        mResult = null;
+
+        getContext().getContentResolver().unregisterContentObserver(mObserver);
+    }
+
+    private void closeQuietly(R result) {
+        if (result instanceof AutoCloseable) {
+            try {
+                ((AutoCloseable) result).close();
+            } catch (RuntimeException rethrown) {
+                throw rethrown;
+            } catch (Exception ignored) {
+            }
+        }
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
new file mode 100644
index 0000000..681cc9b
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
@@ -0,0 +1,254 @@
+/*
+ * 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.documentsui.model;
+
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.provider.DocumentsContract;
+import android.provider.DocumentsContract.Document;
+
+import com.android.documentsui.RootCursorWrapper;
+
+import libcore.io.IoUtils;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.ProtocolException;
+
+/**
+ * Representation of a {@link Document}.
+ */
+public class DocumentInfo implements Durable, Parcelable {
+    private static final int VERSION_INIT = 1;
+    private static final int VERSION_SPLIT_URI = 2;
+
+    public String authority;
+    public String documentId;
+    public String mimeType;
+    public String displayName;
+    public long lastModified;
+    public int flags;
+    public String summary;
+    public long size;
+    public int icon;
+
+    /** Derived fields that aren't persisted */
+    public Uri derivedUri;
+
+    public DocumentInfo() {
+        reset();
+    }
+
+    @Override
+    public void reset() {
+        authority = null;
+        documentId = null;
+        mimeType = null;
+        displayName = null;
+        lastModified = -1;
+        flags = 0;
+        summary = null;
+        size = -1;
+        icon = 0;
+
+        derivedUri = null;
+    }
+
+    @Override
+    public void read(DataInputStream in) throws IOException {
+        final int version = in.readInt();
+        switch (version) {
+            case VERSION_INIT:
+                throw new ProtocolException("Ignored upgrade");
+            case VERSION_SPLIT_URI:
+                authority = DurableUtils.readNullableString(in);
+                documentId = DurableUtils.readNullableString(in);
+                mimeType = DurableUtils.readNullableString(in);
+                displayName = DurableUtils.readNullableString(in);
+                lastModified = in.readLong();
+                flags = in.readInt();
+                summary = DurableUtils.readNullableString(in);
+                size = in.readLong();
+                icon = in.readInt();
+                deriveFields();
+                break;
+            default:
+                throw new ProtocolException("Unknown version " + version);
+        }
+    }
+
+    @Override
+    public void write(DataOutputStream out) throws IOException {
+        out.writeInt(VERSION_SPLIT_URI);
+        DurableUtils.writeNullableString(out, authority);
+        DurableUtils.writeNullableString(out, documentId);
+        DurableUtils.writeNullableString(out, mimeType);
+        DurableUtils.writeNullableString(out, displayName);
+        out.writeLong(lastModified);
+        out.writeInt(flags);
+        DurableUtils.writeNullableString(out, summary);
+        out.writeLong(size);
+        out.writeInt(icon);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        DurableUtils.writeToParcel(dest, this);
+    }
+
+    public static final Creator<DocumentInfo> CREATOR = new Creator<DocumentInfo>() {
+        @Override
+        public DocumentInfo createFromParcel(Parcel in) {
+            final DocumentInfo doc = new DocumentInfo();
+            DurableUtils.readFromParcel(in, doc);
+            return doc;
+        }
+
+        @Override
+        public DocumentInfo[] newArray(int size) {
+            return new DocumentInfo[size];
+        }
+    };
+
+    public static DocumentInfo fromDirectoryCursor(Cursor cursor) {
+        final String authority = getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY);
+        return fromCursor(cursor, authority);
+    }
+
+    public static DocumentInfo fromCursor(Cursor cursor, String authority) {
+        final DocumentInfo doc = new DocumentInfo();
+        doc.authority = authority;
+        doc.documentId = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID);
+        doc.mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
+        doc.documentId = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID);
+        doc.mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
+        doc.displayName = getCursorString(cursor, Document.COLUMN_DISPLAY_NAME);
+        doc.lastModified = getCursorLong(cursor, Document.COLUMN_LAST_MODIFIED);
+        doc.flags = getCursorInt(cursor, Document.COLUMN_FLAGS);
+        doc.summary = getCursorString(cursor, Document.COLUMN_SUMMARY);
+        doc.size = getCursorLong(cursor, Document.COLUMN_SIZE);
+        doc.icon = getCursorInt(cursor, Document.COLUMN_ICON);
+        doc.deriveFields();
+        return doc;
+    }
+
+    public static DocumentInfo fromUri(ContentResolver resolver, Uri uri) throws FileNotFoundException {
+        final ContentProviderClient client = resolver.acquireUnstableContentProviderClient(
+                uri.getAuthority());
+        Cursor cursor = null;
+        try {
+            cursor = client.query(uri, null, null, null, null);
+            if (!cursor.moveToFirst()) {
+                throw new FileNotFoundException("Missing details for " + uri);
+            }
+            return fromCursor(cursor, uri.getAuthority());
+        } catch (Throwable t) {
+            throw asFileNotFoundException(t);
+        } finally {
+            IoUtils.closeQuietly(cursor);
+            ContentProviderClient.closeQuietly(client);
+        }
+    }
+
+    private void deriveFields() {
+        derivedUri = DocumentsContract.buildDocumentUri(authority, documentId);
+    }
+
+    @Override
+    public String toString() {
+        return "Document{name=" + displayName + ", docId=" + documentId + "}";
+    }
+
+    public boolean isCreateSupported() {
+        return (flags & Document.FLAG_DIR_SUPPORTS_CREATE) != 0;
+    }
+
+    public boolean isThumbnailSupported() {
+        return (flags & Document.FLAG_SUPPORTS_THUMBNAIL) != 0;
+    }
+
+    public boolean isDirectory() {
+        return Document.MIME_TYPE_DIR.equals(mimeType);
+    }
+
+    public boolean isGridPreferred() {
+        return (flags & Document.FLAG_DIR_PREFERS_GRID) != 0;
+    }
+
+    public boolean isDeleteSupported() {
+        return (flags & Document.FLAG_SUPPORTS_DELETE) != 0;
+    }
+
+    public boolean isGridTitlesHidden() {
+        return (flags & Document.FLAG_DIR_HIDE_GRID_TITLES) != 0;
+    }
+
+    public static String getCursorString(Cursor cursor, String columnName) {
+        final int index = cursor.getColumnIndex(columnName);
+        return (index != -1) ? cursor.getString(index) : null;
+    }
+
+    /**
+     * Missing or null values are returned as -1.
+     */
+    public static long getCursorLong(Cursor cursor, String columnName) {
+        final int index = cursor.getColumnIndex(columnName);
+        if (index == -1) return -1;
+        final String value = cursor.getString(index);
+        if (value == null) return -1;
+        try {
+            return Long.parseLong(value);
+        } catch (NumberFormatException e) {
+            return -1;
+        }
+    }
+
+    /**
+     * Missing or null values are returned as 0.
+     */
+    public static int getCursorInt(Cursor cursor, String columnName) {
+        final int index = cursor.getColumnIndex(columnName);
+        return (index != -1) ? cursor.getInt(index) : 0;
+    }
+
+    public static FileNotFoundException asFileNotFoundException(Throwable t)
+            throws FileNotFoundException {
+        if (t instanceof FileNotFoundException) {
+            throw (FileNotFoundException) t;
+        }
+        final FileNotFoundException fnfe = new FileNotFoundException(t.getMessage());
+        fnfe.initCause(t);
+        throw fnfe;
+    }
+
+    public static int compareToIgnoreCaseNullable(String lhs, String rhs) {
+        if (lhs == null) return -1;
+        if (rhs == null) return 1;
+        return lhs.compareToIgnoreCase(rhs);
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentStack.java b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentStack.java
new file mode 100644
index 0000000..2541440
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentStack.java
@@ -0,0 +1,94 @@
+/*
+ * 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.documentsui.model;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.ProtocolException;
+import java.util.LinkedList;
+
+/**
+ * Representation of a stack of {@link DocumentInfo}, usually the result of a
+ * user-driven traversal.
+ */
+public class DocumentStack extends LinkedList<DocumentInfo> implements Durable {
+    private static final int VERSION_INIT = 1;
+    private static final int VERSION_ADD_ROOT = 2;
+
+    public RootInfo root;
+
+    public String getTitle() {
+        if (size() == 1 && root != null) {
+            return root.title;
+        } else if (size() > 1) {
+            return peek().displayName;
+        } else {
+            return null;
+        }
+    }
+
+    public boolean isRecents() {
+        return size() == 0;
+    }
+
+    @Override
+    public void reset() {
+        clear();
+        root = null;
+    }
+
+    @Override
+    public void read(DataInputStream in) throws IOException {
+        final int version = in.readInt();
+        switch (version) {
+            case VERSION_INIT:
+                throw new ProtocolException("Ignored upgrade");
+            case VERSION_ADD_ROOT:
+                if (in.readBoolean()) {
+                    root = new RootInfo();
+                    root.read(in);
+                }
+                final int size = in.readInt();
+                for (int i = 0; i < size; i++) {
+                    final DocumentInfo doc = new DocumentInfo();
+                    doc.read(in);
+                    add(doc);
+                }
+                break;
+            default:
+                throw new ProtocolException("Unknown version " + version);
+        }
+    }
+
+    @Override
+    public void write(DataOutputStream out) throws IOException {
+        out.writeInt(VERSION_ADD_ROOT);
+        if (root != null) {
+            out.writeBoolean(true);
+            root.write(out);
+        } else {
+            out.writeBoolean(false);
+        }
+        final int size = size();
+        out.writeInt(size);
+        for (int i = 0; i < size; i++) {
+            final DocumentInfo doc = get(i);
+            doc.write(out);
+        }
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/Durable.java b/packages/DocumentsUI/src/com/android/documentsui/model/Durable.java
new file mode 100644
index 0000000..01633ed
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/Durable.java
@@ -0,0 +1,27 @@
+/*
+ * 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.documentsui.model;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public interface Durable {
+    public void reset();
+    public void read(DataInputStream in) throws IOException;
+    public void write(DataOutputStream out) throws IOException;
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/DurableUtils.java b/packages/DocumentsUI/src/com/android/documentsui/model/DurableUtils.java
new file mode 100644
index 0000000..214fb14
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/DurableUtils.java
@@ -0,0 +1,100 @@
+/*
+ * 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.documentsui.model;
+
+import static com.android.documentsui.DocumentsActivity.TAG;
+
+import android.os.BadParcelableException;
+import android.os.Parcel;
+import android.util.Log;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class DurableUtils {
+    public static <D extends Durable> byte[] writeToArray(D d) throws IOException {
+        final ByteArrayOutputStream out = new ByteArrayOutputStream();
+        d.write(new DataOutputStream(out));
+        return out.toByteArray();
+    }
+
+    public static <D extends Durable> D readFromArray(byte[] data, D d) throws IOException {
+        final ByteArrayInputStream in = new ByteArrayInputStream(data);
+        d.reset();
+        try {
+            d.read(new DataInputStream(in));
+        } catch (IOException e) {
+            d.reset();
+            throw e;
+        }
+        return d;
+    }
+
+    public static <D extends Durable> byte[] writeToArrayOrNull(D d) {
+        try {
+            return writeToArray(d);
+        } catch (IOException e) {
+            Log.w(TAG, "Failed to write", e);
+            return null;
+        }
+    }
+
+    public static <D extends Durable> D readFromArrayOrNull(byte[] data, D d) {
+        try {
+            return readFromArray(data, d);
+        } catch (IOException e) {
+            Log.w(TAG, "Failed to read", e);
+            return null;
+        }
+    }
+
+    public static <D extends Durable> void writeToParcel(Parcel parcel, D d) {
+        try {
+            parcel.writeByteArray(writeToArray(d));
+        } catch (IOException e) {
+            throw new BadParcelableException(e);
+        }
+    }
+
+    public static <D extends Durable> D readFromParcel(Parcel parcel, D d) {
+        try {
+            return readFromArray(parcel.createByteArray(), d);
+        } catch (IOException e) {
+            throw new BadParcelableException(e);
+        }
+    }
+
+    public static void writeNullableString(DataOutputStream out, String value) throws IOException {
+        if (value != null) {
+            out.write(1);
+            out.writeUTF(value);
+        } else {
+            out.write(0);
+        }
+    }
+
+    public static String readNullableString(DataInputStream in) throws IOException {
+        if (in.read() != 0) {
+            return in.readUTF();
+        } else {
+            return null;
+        }
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java b/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
new file mode 100644
index 0000000..1afc80a
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
@@ -0,0 +1,215 @@
+/*
+ * 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.documentsui.model;
+
+import static com.android.documentsui.model.DocumentInfo.getCursorInt;
+import static com.android.documentsui.model.DocumentInfo.getCursorLong;
+import static com.android.documentsui.model.DocumentInfo.getCursorString;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.graphics.drawable.Drawable;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.provider.DocumentsContract.Root;
+import android.text.TextUtils;
+
+import com.android.documentsui.IconUtils;
+import com.android.documentsui.R;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.ProtocolException;
+import java.util.Objects;
+
+/**
+ * Representation of a {@link Root}.
+ */
+public class RootInfo implements Durable, Parcelable {
+    private static final int VERSION_INIT = 1;
+
+    public String authority;
+    public String rootId;
+    public int rootType;
+    public int flags;
+    public int icon;
+    public String title;
+    public String summary;
+    public String documentId;
+    public long availableBytes;
+    public String mimeTypes;
+
+    /** Derived fields that aren't persisted */
+    public String[] derivedMimeTypes;
+    public int derivedIcon;
+
+    public RootInfo() {
+        reset();
+    }
+
+    @Override
+    public void reset() {
+        authority = null;
+        rootId = null;
+        rootType = 0;
+        flags = 0;
+        icon = 0;
+        title = null;
+        summary = null;
+        documentId = null;
+        availableBytes = -1;
+        mimeTypes = null;
+
+        derivedMimeTypes = null;
+        derivedIcon = 0;
+    }
+
+    @Override
+    public void read(DataInputStream in) throws IOException {
+        final int version = in.readInt();
+        switch (version) {
+            case VERSION_INIT:
+                authority = DurableUtils.readNullableString(in);
+                rootId = DurableUtils.readNullableString(in);
+                rootType = in.readInt();
+                flags = in.readInt();
+                icon = in.readInt();
+                title = DurableUtils.readNullableString(in);
+                summary = DurableUtils.readNullableString(in);
+                documentId = DurableUtils.readNullableString(in);
+                availableBytes = in.readLong();
+                mimeTypes = DurableUtils.readNullableString(in);
+                deriveFields();
+                break;
+            default:
+                throw new ProtocolException("Unknown version " + version);
+        }
+    }
+
+    @Override
+    public void write(DataOutputStream out) throws IOException {
+        out.writeInt(VERSION_INIT);
+        DurableUtils.writeNullableString(out, authority);
+        DurableUtils.writeNullableString(out, rootId);
+        out.writeInt(rootType);
+        out.writeInt(flags);
+        out.writeInt(icon);
+        DurableUtils.writeNullableString(out, title);
+        DurableUtils.writeNullableString(out, summary);
+        DurableUtils.writeNullableString(out, documentId);
+        out.writeLong(availableBytes);
+        DurableUtils.writeNullableString(out, mimeTypes);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        DurableUtils.writeToParcel(dest, this);
+    }
+
+    public static final Creator<RootInfo> CREATOR = new Creator<RootInfo>() {
+        @Override
+        public RootInfo createFromParcel(Parcel in) {
+            final RootInfo root = new RootInfo();
+            DurableUtils.readFromParcel(in, root);
+            return root;
+        }
+
+        @Override
+        public RootInfo[] newArray(int size) {
+            return new RootInfo[size];
+        }
+    };
+
+    public static RootInfo fromRootsCursor(String authority, Cursor cursor) {
+        final RootInfo root = new RootInfo();
+        root.authority = authority;
+        root.rootId = getCursorString(cursor, Root.COLUMN_ROOT_ID);
+        root.rootType = getCursorInt(cursor, Root.COLUMN_ROOT_TYPE);
+        root.flags = getCursorInt(cursor, Root.COLUMN_FLAGS);
+        root.icon = getCursorInt(cursor, Root.COLUMN_ICON);
+        root.title = getCursorString(cursor, Root.COLUMN_TITLE);
+        root.summary = getCursorString(cursor, Root.COLUMN_SUMMARY);
+        root.documentId = getCursorString(cursor, Root.COLUMN_DOCUMENT_ID);
+        root.availableBytes = getCursorLong(cursor, Root.COLUMN_AVAILABLE_BYTES);
+        root.mimeTypes = getCursorString(cursor, Root.COLUMN_MIME_TYPES);
+        root.deriveFields();
+        return root;
+    }
+
+    private void deriveFields() {
+        derivedMimeTypes = (mimeTypes != null) ? mimeTypes.split("\n") : null;
+
+        // TODO: remove these special case icons
+        if ("com.android.externalstorage.documents".equals(authority)) {
+            if ("documents".equals(rootId)) {
+                derivedIcon = R.drawable.ic_doc_text;
+            } else {
+                derivedIcon = R.drawable.ic_root_sdcard;
+            }
+        }
+        if ("com.android.providers.downloads.documents".equals(authority)) {
+            derivedIcon = R.drawable.ic_root_download;
+        }
+        if ("com.android.providers.media.documents".equals(authority)) {
+            if ("images_root".equals(rootId)) {
+                derivedIcon = R.drawable.ic_doc_image;
+            } else if ("videos_root".equals(rootId)) {
+                derivedIcon = R.drawable.ic_doc_video;
+            } else if ("audio_root".equals(rootId)) {
+                derivedIcon = R.drawable.ic_doc_audio;
+            }
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "Root{title=" + title + ", rootId=" + rootId + "}";
+    }
+
+    public Drawable loadIcon(Context context) {
+        if (derivedIcon != 0) {
+            return context.getResources().getDrawable(derivedIcon);
+        } else {
+            return IconUtils.loadPackageIcon(context, authority, icon);
+        }
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o instanceof RootInfo) {
+            final RootInfo root = (RootInfo) o;
+            return Objects.equals(authority, root.authority) && Objects.equals(rootId, root.rootId);
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(authority, rootId);
+    }
+
+    public String getDirectoryString() {
+        return !TextUtils.isEmpty(summary) ? summary : title;
+    }
+}
diff --git a/packages/DocumentsUI/tests/Android.mk b/packages/DocumentsUI/tests/Android.mk
new file mode 100644
index 0000000..fdf4fab
--- /dev/null
+++ b/packages/DocumentsUI/tests/Android.mk
@@ -0,0 +1,16 @@
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_PACKAGE_NAME := DocumentsUITests
+LOCAL_INSTRUMENTATION_FOR := DocumentsUI
+
+LOCAL_CERTIFICATE := platform
+
+include $(BUILD_PACKAGE)
diff --git a/packages/DocumentsUI/tests/AndroidManifest.xml b/packages/DocumentsUI/tests/AndroidManifest.xml
new file mode 100644
index 0000000..81a2889
--- /dev/null
+++ b/packages/DocumentsUI/tests/AndroidManifest.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.documentsui.tests">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.test.InstrumentationTestRunner"
+        android:targetPackage="com.android.documentsui"
+        android:label="Tests for DocumentsUI" />
+
+</manifest>
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/RootsCacheTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/RootsCacheTest.java
new file mode 100644
index 0000000..cdb6b33
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/RootsCacheTest.java
@@ -0,0 +1,123 @@
+/*
+ * 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.documentsui;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.documentsui.DocumentsActivity.State;
+import com.android.documentsui.model.RootInfo;
+import com.google.android.collect.Lists;
+
+import java.util.List;
+
+@SmallTest
+public class RootsCacheTest extends AndroidTestCase {
+
+    private static RootInfo buildForMimeTypes(String... mimeTypes) {
+        final RootInfo root = new RootInfo();
+        root.derivedMimeTypes = mimeTypes;
+        return root;
+    }
+
+    private RootInfo mNull = new RootInfo();
+    private RootInfo mEmpty = buildForMimeTypes();
+    private RootInfo mWild = buildForMimeTypes("*/*");
+    private RootInfo mImages = buildForMimeTypes("image/*");
+    private RootInfo mAudio = buildForMimeTypes("audio/*", "application/ogg", "application/x-flac");
+    private RootInfo mDocs = buildForMimeTypes("application/msword", "application/vnd.ms-excel");
+    private RootInfo mMalformed1 = buildForMimeTypes("meow");
+    private RootInfo mMalformed2 = buildForMimeTypes("*/meow");
+
+    private List<RootInfo> mRoots = Lists.newArrayList(
+            mNull, mWild, mEmpty, mImages, mAudio, mDocs, mMalformed1, mMalformed2);
+
+    private State mState;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mState = new State();
+        mState.action = State.ACTION_OPEN;
+        mState.showAdvanced = true;
+        mState.localOnly = false;
+    }
+
+    public void testMatchingRootsEverything() throws Exception {
+        mState.acceptMimes = new String[] { "*/*" };
+        assertContainsExactly(
+                Lists.newArrayList(mNull, mWild, mImages, mAudio, mDocs, mMalformed1, mMalformed2),
+                RootsCache.getMatchingRoots(mRoots, mState));
+    }
+
+    public void testMatchingRootsPngOrWild() throws Exception {
+        mState.acceptMimes = new String[] { "image/png", "*/*" };
+        assertContainsExactly(
+                Lists.newArrayList(mNull, mWild, mImages, mAudio, mDocs, mMalformed1, mMalformed2),
+                RootsCache.getMatchingRoots(mRoots, mState));
+    }
+
+    public void testMatchingRootsAudioWild() throws Exception {
+        mState.acceptMimes = new String[] { "audio/*" };
+        assertContainsExactly(
+                Lists.newArrayList(mNull, mWild, mAudio),
+                RootsCache.getMatchingRoots(mRoots, mState));
+    }
+
+    public void testMatchingRootsAudioWildOrImageWild() throws Exception {
+        mState.acceptMimes = new String[] { "audio/*", "image/*" };
+        assertContainsExactly(
+                Lists.newArrayList(mNull, mWild, mAudio, mImages),
+                RootsCache.getMatchingRoots(mRoots, mState));
+    }
+
+    public void testMatchingRootsAudioSpecific() throws Exception {
+        mState.acceptMimes = new String[] { "audio/mpeg" };
+        assertContainsExactly(
+                Lists.newArrayList(mNull, mWild, mAudio),
+                RootsCache.getMatchingRoots(mRoots, mState));
+    }
+
+    public void testMatchingRootsDocument() throws Exception {
+        mState.acceptMimes = new String[] { "application/msword" };
+        assertContainsExactly(
+                Lists.newArrayList(mNull, mWild, mDocs),
+                RootsCache.getMatchingRoots(mRoots, mState));
+    }
+
+    public void testMatchingRootsApplication() throws Exception {
+        mState.acceptMimes = new String[] { "application/*" };
+        assertContainsExactly(
+                Lists.newArrayList(mNull, mWild, mAudio, mDocs),
+                RootsCache.getMatchingRoots(mRoots, mState));
+    }
+
+    public void testMatchingRootsFlacOrPng() throws Exception {
+        mState.acceptMimes = new String[] { "application/x-flac", "image/png" };
+        assertContainsExactly(
+                Lists.newArrayList(mNull, mWild, mAudio, mImages),
+                RootsCache.getMatchingRoots(mRoots, mState));
+    }
+
+    private static void assertContainsExactly(List<?> expected, List<?> actual) {
+        assertEquals(expected.size(), actual.size());
+        for (Object o : expected) {
+            assertTrue(actual.contains(o));
+        }
+    }
+}
diff --git a/packages/ExternalStorageProvider/Android.mk b/packages/ExternalStorageProvider/Android.mk
new file mode 100644
index 0000000..db825ff4
--- /dev/null
+++ b/packages/ExternalStorageProvider/Android.mk
@@ -0,0 +1,12 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := ExternalStorageProvider
+LOCAL_CERTIFICATE := platform
+LOCAL_PRIVILEGED_MODULE := true
+
+include $(BUILD_PACKAGE)
diff --git a/packages/ExternalStorageProvider/AndroidManifest.xml b/packages/ExternalStorageProvider/AndroidManifest.xml
new file mode 100644
index 0000000..7094efc
--- /dev/null
+++ b/packages/ExternalStorageProvider/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.externalstorage">
+
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+    <application android:label="@string/app_label">
+        <provider
+            android:name=".ExternalStorageProvider"
+            android:authorities="com.android.externalstorage.documents"
+            android:grantUriPermissions="true"
+            android:exported="true"
+            android:permission="android.permission.MANAGE_DOCUMENTS">
+            <meta-data
+                android:name="android.content.DOCUMENT_PROVIDER"
+                android:value="true" />
+        </provider>
+
+        <!-- TODO: find a better place for tests to live -->
+        <provider
+            android:name=".TestDocumentsProvider"
+            android:authorities="com.example.documents"
+            android:grantUriPermissions="true"
+            android:exported="true"
+            android:permission="android.permission.MANAGE_DOCUMENTS"
+            android:enabled="false">
+            <meta-data
+                android:name="android.content.DOCUMENT_PROVIDER"
+                android:value="true" />
+        </provider>
+    </application>
+</manifest>
diff --git a/packages/ExternalStorageProvider/res/values-af/strings.xml b/packages/ExternalStorageProvider/res/values-af/strings.xml
new file mode 100644
index 0000000..2076934
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-af/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Eksterne berging"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Interne berging"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-am/strings.xml b/packages/ExternalStorageProvider/res/values-am/strings.xml
new file mode 100644
index 0000000..e646909
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-am/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="root_internal_storage" msgid="827844243068584127">"ውስጣዊ ማከማቻ"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-ar/strings.xml b/packages/ExternalStorageProvider/res/values-ar/strings.xml
new file mode 100644
index 0000000..9c4b496
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-ar/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="root_internal_storage" msgid="827844243068584127">"وحدة تخزين داخلية"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-az/strings.xml b/packages/ExternalStorageProvider/res/values-az/strings.xml
new file mode 100644
index 0000000..a6a79ca8
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-az/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Xarici Yaddaş"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Daxili yaddaş"</string>
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-bg/strings.xml b/packages/ExternalStorageProvider/res/values-bg/strings.xml
new file mode 100644
index 0000000..f3b4dac
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-bg/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="root_internal_storage" msgid="827844243068584127">"Вътрешно хранилище"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-ca/strings.xml b/packages/ExternalStorageProvider/res/values-ca/strings.xml
new file mode 100644
index 0000000..7c0ad8b
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-ca/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Emmagatzematge extern"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Emmagatzematge intern"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-cs/strings.xml b/packages/ExternalStorageProvider/res/values-cs/strings.xml
new file mode 100644
index 0000000..353cb6c
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-cs/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Externí úložiště"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Interní úložiště"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-da/strings.xml b/packages/ExternalStorageProvider/res/values-da/strings.xml
new file mode 100644
index 0000000..2ced56e
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-da/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Ekstern lagring"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Intern lagring"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-de/strings.xml b/packages/ExternalStorageProvider/res/values-de/strings.xml
new file mode 100644
index 0000000..8d8e3a6
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-de/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Externer Speicher"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Interner Speicher"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-el/strings.xml b/packages/ExternalStorageProvider/res/values-el/strings.xml
new file mode 100644
index 0000000..9720b3d
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-el/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="root_internal_storage" msgid="827844243068584127">"Εσωτερικός αποθηκευτικός χώρος"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-en-rGB/strings.xml b/packages/ExternalStorageProvider/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..f88eb9e
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-en-rGB/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"External Storage"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Internal storage"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Documents"</string>
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-en-rIN/strings.xml b/packages/ExternalStorageProvider/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..f88eb9e
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-en-rIN/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"External Storage"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Internal storage"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Documents"</string>
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-es-rUS/strings.xml b/packages/ExternalStorageProvider/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..7285a34
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-es-rUS/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Almacenamiento externo"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Almacenamiento interno"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-es/strings.xml b/packages/ExternalStorageProvider/res/values-es/strings.xml
new file mode 100644
index 0000000..7285a34
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-es/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Almacenamiento externo"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Almacenamiento interno"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-et-rEE/strings.xml b/packages/ExternalStorageProvider/res/values-et-rEE/strings.xml
new file mode 100644
index 0000000..19357cc
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-et-rEE/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Väline talletusruum"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Sisemine salvestusruum"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-fa/strings.xml b/packages/ExternalStorageProvider/res/values-fa/strings.xml
new file mode 100644
index 0000000..f61e5cb
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-fa/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="root_internal_storage" msgid="827844243068584127">"حافظهٔ داخلی"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-fi/strings.xml b/packages/ExternalStorageProvider/res/values-fi/strings.xml
new file mode 100644
index 0000000..a674b49
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-fi/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Ulkoinen tallennustila"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Sisäinen tallennustila"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-fr-rCA/strings.xml b/packages/ExternalStorageProvider/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..294bd69
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-fr-rCA/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Stockage externe"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Mémoire de stockage interne"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-fr/strings.xml b/packages/ExternalStorageProvider/res/values-fr/strings.xml
new file mode 100644
index 0000000..294bd69
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-fr/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Stockage externe"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Mémoire de stockage interne"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-hi/strings.xml b/packages/ExternalStorageProvider/res/values-hi/strings.xml
new file mode 100644
index 0000000..72b4788
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-hi/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="root_internal_storage" msgid="827844243068584127">"मोबाइल संग्रहण"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-hr/strings.xml b/packages/ExternalStorageProvider/res/values-hr/strings.xml
new file mode 100644
index 0000000..c2d049e
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-hr/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Vanjska pohrana"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Unutarnja pohrana"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-hu/strings.xml b/packages/ExternalStorageProvider/res/values-hu/strings.xml
new file mode 100644
index 0000000..bc581e2
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-hu/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Külső tárhely"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Belső tárhely"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-hy-rAM/strings.xml b/packages/ExternalStorageProvider/res/values-hy-rAM/strings.xml
new file mode 100644
index 0000000..5360124
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-hy-rAM/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="root_internal_storage" msgid="827844243068584127">"Ներքին պահոց"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Փաստաթղթեր"</string>
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-in/strings.xml b/packages/ExternalStorageProvider/res/values-in/strings.xml
new file mode 100644
index 0000000..553e656
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-in/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Penyimpanan Eksternal"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Penyimpanan internal"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-it/strings.xml b/packages/ExternalStorageProvider/res/values-it/strings.xml
new file mode 100644
index 0000000..c1bd54c
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-it/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Archivio esterno"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Memoria interna"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-iw/strings.xml b/packages/ExternalStorageProvider/res/values-iw/strings.xml
new file mode 100644
index 0000000..ca3da87
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-iw/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="root_internal_storage" msgid="827844243068584127">"אחסון פנימי"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-ja/strings.xml b/packages/ExternalStorageProvider/res/values-ja/strings.xml
new file mode 100644
index 0000000..6c204eb
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-ja/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="root_internal_storage" msgid="827844243068584127">"内部ストレージ"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-ka-rGE/strings.xml b/packages/ExternalStorageProvider/res/values-ka-rGE/strings.xml
new file mode 100644
index 0000000..18920e6
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-ka-rGE/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="root_internal_storage" msgid="827844243068584127">"შიდა მეხსიერება"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-km-rKH/strings.xml b/packages/ExternalStorageProvider/res/values-km-rKH/strings.xml
new file mode 100644
index 0000000..77ba762
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-km-rKH/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="root_internal_storage" msgid="827844243068584127">"ឧបករណ៍​ផ្ទុក​ខាង​ក្នុង"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-ko/strings.xml b/packages/ExternalStorageProvider/res/values-ko/strings.xml
new file mode 100644
index 0000000..4be48bf
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-ko/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="root_internal_storage" msgid="827844243068584127">"내부 저장소"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-lo-rLA/strings.xml b/packages/ExternalStorageProvider/res/values-lo-rLA/strings.xml
new file mode 100644
index 0000000..cecd9f5
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-lo-rLA/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="root_internal_storage" msgid="827844243068584127">"ບ່ອນຈັດເກັບຂໍ້ມູນພາຍໃນ"</string>
+    <string name="root_documents" msgid="4051252304075469250">"ເອ​ກະ​ສານ"</string>
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-lt/strings.xml b/packages/ExternalStorageProvider/res/values-lt/strings.xml
new file mode 100644
index 0000000..d6842b5
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-lt/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Išorinė atmintinė"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Vidinė atmintinė"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-lv/strings.xml b/packages/ExternalStorageProvider/res/values-lv/strings.xml
new file mode 100644
index 0000000..c906087
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-lv/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Ārējā krātuve"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Iekšējā atmiņa"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-mn-rMN/strings.xml b/packages/ExternalStorageProvider/res/values-mn-rMN/strings.xml
new file mode 100644
index 0000000..8319af8
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-mn-rMN/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="root_internal_storage" msgid="827844243068584127">"Дотоод сан"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-mn/strings.xml b/packages/ExternalStorageProvider/res/values-mn/strings.xml
new file mode 100644
index 0000000..0193cdb
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-mn/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="root_internal_storage" msgid="827844243068584127">"Дотоод сан"</string>
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-ms-rMY/strings.xml b/packages/ExternalStorageProvider/res/values-ms-rMY/strings.xml
new file mode 100644
index 0000000..e8c6011
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-ms-rMY/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Storan Luaran"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Storan dalaman"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-nb/strings.xml b/packages/ExternalStorageProvider/res/values-nb/strings.xml
new file mode 100644
index 0000000..2ced56e
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-nb/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Ekstern lagring"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Intern lagring"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-ne-rNP/strings.xml b/packages/ExternalStorageProvider/res/values-ne-rNP/strings.xml
new file mode 100644
index 0000000..8a9454e
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-ne-rNP/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="root_internal_storage" msgid="827844243068584127">"आन्तरिक भण्डारण"</string>
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-nl/strings.xml b/packages/ExternalStorageProvider/res/values-nl/strings.xml
new file mode 100644
index 0000000..843679f
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-nl/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Externe opslag"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Interne opslag"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-pl/strings.xml b/packages/ExternalStorageProvider/res/values-pl/strings.xml
new file mode 100644
index 0000000..a166793
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-pl/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Pamięć zewnętrzna"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Pamięć wewnętrzna"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-pt-rPT/strings.xml b/packages/ExternalStorageProvider/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..eec824f
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-pt-rPT/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Armazenamento externo"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Armazenamento interno"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-pt/strings.xml b/packages/ExternalStorageProvider/res/values-pt/strings.xml
new file mode 100644
index 0000000..eec824f
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-pt/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Armazenamento externo"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Armazenamento interno"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-ro/strings.xml b/packages/ExternalStorageProvider/res/values-ro/strings.xml
new file mode 100644
index 0000000..16b963b
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-ro/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Stocare externă"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Stocare internă"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-ru/strings.xml b/packages/ExternalStorageProvider/res/values-ru/strings.xml
new file mode 100644
index 0000000..3dee3b6
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-ru/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="root_internal_storage" msgid="827844243068584127">"Внутренняя память"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-si-rLK/strings.xml b/packages/ExternalStorageProvider/res/values-si-rLK/strings.xml
new file mode 100644
index 0000000..de3f3e8
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-si-rLK/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="root_internal_storage" msgid="827844243068584127">"අභ්‍යන්තර ආචයනය"</string>
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-sk/strings.xml b/packages/ExternalStorageProvider/res/values-sk/strings.xml
new file mode 100644
index 0000000..73e4552
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-sk/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Externý ukladací priestor"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Interný ukladací priestor"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-sl/strings.xml b/packages/ExternalStorageProvider/res/values-sl/strings.xml
new file mode 100644
index 0000000..5f7ddd2
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-sl/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Zunanja shramba"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Notranja shramba"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-sr/strings.xml b/packages/ExternalStorageProvider/res/values-sr/strings.xml
new file mode 100644
index 0000000..987f848
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-sr/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="root_internal_storage" msgid="827844243068584127">"Интерна меморија"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-sv/strings.xml b/packages/ExternalStorageProvider/res/values-sv/strings.xml
new file mode 100644
index 0000000..1837096
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-sv/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Extern lagring"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Intern lagring"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-sw/strings.xml b/packages/ExternalStorageProvider/res/values-sw/strings.xml
new file mode 100644
index 0000000..0495a31
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-sw/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Hifadhi ya Nje"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Hifadhi ya ndani"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-th/strings.xml b/packages/ExternalStorageProvider/res/values-th/strings.xml
new file mode 100644
index 0000000..3a24f7d
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-th/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="root_internal_storage" msgid="827844243068584127">"ที่จัดเก็บข้อมูลภายใน"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-tl/strings.xml b/packages/ExternalStorageProvider/res/values-tl/strings.xml
new file mode 100644
index 0000000..2687129
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-tl/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"External Storage"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Internal storage"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-tr/strings.xml b/packages/ExternalStorageProvider/res/values-tr/strings.xml
new file mode 100644
index 0000000..ff3f68a
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-tr/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Harici Depolama"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Dahili depolama"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-uk/strings.xml b/packages/ExternalStorageProvider/res/values-uk/strings.xml
new file mode 100644
index 0000000..d993be8
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-uk/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="root_internal_storage" msgid="827844243068584127">"Внутрішня пам’ять"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-vi/strings.xml b/packages/ExternalStorageProvider/res/values-vi/strings.xml
new file mode 100644
index 0000000..7713ade
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-vi/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Bộ nhớ ngoài"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Bộ nhớ trong"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-zh-rCN/strings.xml b/packages/ExternalStorageProvider/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..0550c50
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-zh-rCN/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="root_internal_storage" msgid="827844243068584127">"内部存储空间"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-zh-rHK/strings.xml b/packages/ExternalStorageProvider/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..df52d38
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-zh-rHK/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="root_internal_storage" msgid="827844243068584127">"內部儲存空間"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-zh-rTW/strings.xml b/packages/ExternalStorageProvider/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..df52d38
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-zh-rTW/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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="root_internal_storage" msgid="827844243068584127">"內部儲存空間"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values-zu/strings.xml b/packages/ExternalStorageProvider/res/values-zu/strings.xml
new file mode 100644
index 0000000..dcaefc5
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-zu/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Isitoreji sangaphandle"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Isitoreji sangaphakathi"</string>
+    <!-- no translation found for root_documents (4051252304075469250) -->
+    <skip />
+</resources>
diff --git a/packages/ExternalStorageProvider/res/values/strings.xml b/packages/ExternalStorageProvider/res/values/strings.xml
new file mode 100644
index 0000000..f1c1ade
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <!-- Title of the external storage application [CHAR LIMIT=32] -->
+    <string name="app_label">External Storage</string>
+
+    <!-- Title for documents backend that offers internal storage. [CHAR LIMIT=24] -->
+    <string name="root_internal_storage">Internal storage</string>
+    <!-- Title for documents backend that offers documents. [CHAR LIMIT=24] -->
+    <string name="root_documents">Documents</string>
+</resources>
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
new file mode 100644
index 0000000..3e2cd15
--- /dev/null
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -0,0 +1,373 @@
+/*
+ * 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.externalstorage;
+
+import android.content.ContentResolver;
+import android.content.res.AssetFileDescriptor;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.database.MatrixCursor.RowBuilder;
+import android.graphics.Point;
+import android.media.ExifInterface;
+import android.os.CancellationSignal;
+import android.os.Environment;
+import android.os.ParcelFileDescriptor;
+import android.provider.DocumentsContract.Document;
+import android.provider.DocumentsContract.Root;
+import android.provider.DocumentsProvider;
+import android.webkit.MimeTypeMap;
+
+import com.google.android.collect.Lists;
+import com.google.android.collect.Maps;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+
+public class ExternalStorageProvider extends DocumentsProvider {
+    private static final String TAG = "ExternalStorage";
+
+    // docId format: root:path/to/file
+
+    private static final String[] DEFAULT_ROOT_PROJECTION = new String[] {
+            Root.COLUMN_ROOT_ID, Root.COLUMN_ROOT_TYPE, Root.COLUMN_FLAGS, Root.COLUMN_ICON,
+            Root.COLUMN_TITLE, Root.COLUMN_SUMMARY, Root.COLUMN_DOCUMENT_ID,
+            Root.COLUMN_AVAILABLE_BYTES,
+    };
+
+    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,
+    };
+
+    private static class RootInfo {
+        public String rootId;
+        public int rootType;
+        public int flags;
+        public String title;
+        public String docId;
+    }
+
+    private ArrayList<RootInfo> mRoots;
+    private HashMap<String, RootInfo> mIdToRoot;
+    private HashMap<String, File> mIdToPath;
+
+    @Override
+    public boolean onCreate() {
+        mRoots = Lists.newArrayList();
+        mIdToRoot = Maps.newHashMap();
+        mIdToPath = Maps.newHashMap();
+
+        // TODO: support multiple storage devices
+
+        try {
+            final String rootId = "primary";
+            final File path = Environment.getExternalStorageDirectory();
+            mIdToPath.put(rootId, path);
+
+            final RootInfo root = new RootInfo();
+            root.rootId = rootId;
+            root.rootType = Root.ROOT_TYPE_DEVICE;
+            root.flags = Root.FLAG_SUPPORTS_CREATE | Root.FLAG_LOCAL_ONLY | Root.FLAG_ADVANCED
+                    | Root.FLAG_SUPPORTS_SEARCH;
+            root.title = getContext().getString(R.string.root_internal_storage);
+            root.docId = getDocIdForFile(path);
+            mRoots.add(root);
+            mIdToRoot.put(rootId, root);
+        } catch (FileNotFoundException e) {
+            throw new IllegalStateException(e);
+        }
+
+        try {
+            final String rootId = "documents";
+            final File path = Environment.getExternalStoragePublicDirectory(
+                    Environment.DIRECTORY_DOCUMENTS);
+            mIdToPath.put(rootId, path);
+
+            final RootInfo root = new RootInfo();
+            root.rootId = rootId;
+            root.rootType = Root.ROOT_TYPE_SHORTCUT;
+            root.flags = Root.FLAG_SUPPORTS_CREATE | Root.FLAG_LOCAL_ONLY
+                    | Root.FLAG_SUPPORTS_SEARCH;
+            root.title = getContext().getString(R.string.root_documents);
+            root.docId = getDocIdForFile(path);
+            mRoots.add(root);
+            mIdToRoot.put(rootId, root);
+        } catch (FileNotFoundException e) {
+            throw new IllegalStateException(e);
+        }
+
+        return true;
+    }
+
+    private static String[] resolveRootProjection(String[] projection) {
+        return projection != null ? projection : DEFAULT_ROOT_PROJECTION;
+    }
+
+    private static String[] resolveDocumentProjection(String[] projection) {
+        return projection != null ? projection : DEFAULT_DOCUMENT_PROJECTION;
+    }
+
+    private String getDocIdForFile(File file) throws FileNotFoundException {
+        String path = file.getAbsolutePath();
+
+        // Find the most-specific root path
+        Map.Entry<String, File> mostSpecific = null;
+        for (Map.Entry<String, File> root : mIdToPath.entrySet()) {
+            final String rootPath = root.getValue().getPath();
+            if (path.startsWith(rootPath) && (mostSpecific == null
+                    || rootPath.length() > mostSpecific.getValue().getPath().length())) {
+                mostSpecific = root;
+            }
+        }
+
+        if (mostSpecific == null) {
+            throw new FileNotFoundException("Failed to find root that contains " + path);
+        }
+
+        // Start at first char of path under root
+        final String rootPath = mostSpecific.getValue().getPath();
+        if (rootPath.equals(path)) {
+            path = "";
+        } else if (rootPath.endsWith("/")) {
+            path = path.substring(rootPath.length());
+        } else {
+            path = path.substring(rootPath.length() + 1);
+        }
+
+        return mostSpecific.getKey() + ':' + path;
+    }
+
+    private File getFileForDocId(String docId) throws FileNotFoundException {
+        final int splitIndex = docId.indexOf(':', 1);
+        final String tag = docId.substring(0, splitIndex);
+        final String path = docId.substring(splitIndex + 1);
+
+        File target = mIdToPath.get(tag);
+        if (target == null) {
+            throw new FileNotFoundException("No root for " + tag);
+        }
+        if (!target.exists()) {
+            target.mkdirs();
+        }
+        target = new File(target, path);
+        if (!target.exists()) {
+            throw new FileNotFoundException("Missing file for " + docId + " at " + target);
+        }
+        return target;
+    }
+
+    private void includeFile(MatrixCursor result, String docId, File file)
+            throws FileNotFoundException {
+        if (docId == null) {
+            docId = getDocIdForFile(file);
+        } else {
+            file = getFileForDocId(docId);
+        }
+
+        int flags = 0;
+
+        if (file.isDirectory() && file.canWrite()) {
+            flags |= Document.FLAG_DIR_SUPPORTS_CREATE;
+        }
+        if (file.canWrite()) {
+            flags |= Document.FLAG_SUPPORTS_WRITE;
+            flags |= Document.FLAG_SUPPORTS_DELETE;
+        }
+
+        final String displayName = file.getName();
+        final String mimeType = getTypeForFile(file);
+        if (mimeType.startsWith("image/")) {
+            flags |= Document.FLAG_SUPPORTS_THUMBNAIL;
+        }
+
+        final RowBuilder row = result.newRow();
+        row.add(Document.COLUMN_DOCUMENT_ID, docId);
+        row.add(Document.COLUMN_DISPLAY_NAME, displayName);
+        row.add(Document.COLUMN_SIZE, file.length());
+        row.add(Document.COLUMN_MIME_TYPE, mimeType);
+        row.add(Document.COLUMN_LAST_MODIFIED, file.lastModified());
+        row.add(Document.COLUMN_FLAGS, flags);
+    }
+
+    @Override
+    public Cursor queryRoots(String[] projection) throws FileNotFoundException {
+        final MatrixCursor result = new MatrixCursor(resolveRootProjection(projection));
+        for (String rootId : mIdToPath.keySet()) {
+            final RootInfo root = mIdToRoot.get(rootId);
+            final File path = mIdToPath.get(rootId);
+
+            final RowBuilder row = result.newRow();
+            row.add(Root.COLUMN_ROOT_ID, root.rootId);
+            row.add(Root.COLUMN_ROOT_TYPE, root.rootType);
+            row.add(Root.COLUMN_FLAGS, root.flags);
+            row.add(Root.COLUMN_TITLE, root.title);
+            row.add(Root.COLUMN_DOCUMENT_ID, root.docId);
+            row.add(Root.COLUMN_AVAILABLE_BYTES, path.getFreeSpace());
+        }
+        return result;
+    }
+
+    @Override
+    public String createDocument(String docId, String mimeType, String displayName)
+            throws FileNotFoundException {
+        final File parent = getFileForDocId(docId);
+        displayName = validateDisplayName(mimeType, displayName);
+
+        final File file = new File(parent, displayName);
+        if (Document.MIME_TYPE_DIR.equals(mimeType)) {
+            if (!file.mkdir()) {
+                throw new IllegalStateException("Failed to mkdir " + file);
+            }
+        } else {
+            try {
+                if (!file.createNewFile()) {
+                    throw new IllegalStateException("Failed to touch " + file);
+                }
+            } catch (IOException e) {
+                throw new IllegalStateException("Failed to touch " + file + ": " + e);
+            }
+        }
+        return getDocIdForFile(file);
+    }
+
+    @Override
+    public void deleteDocument(String docId) throws FileNotFoundException {
+        final File file = getFileForDocId(docId);
+        if (!file.delete()) {
+            throw new IllegalStateException("Failed to delete " + file);
+        }
+    }
+
+    @Override
+    public Cursor queryDocument(String documentId, String[] projection)
+            throws FileNotFoundException {
+        final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection));
+        includeFile(result, documentId, null);
+        return result;
+    }
+
+    @Override
+    public Cursor queryChildDocuments(
+            String parentDocumentId, String[] projection, String sortOrder)
+            throws FileNotFoundException {
+        final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection));
+        final File parent = getFileForDocId(parentDocumentId);
+        for (File file : parent.listFiles()) {
+            includeFile(result, null, file);
+        }
+        return result;
+    }
+
+    @Override
+    public Cursor querySearchDocuments(String rootId, String query, String[] projection)
+            throws FileNotFoundException {
+        final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection));
+        final File parent = mIdToPath.get(rootId);
+
+        final LinkedList<File> pending = new LinkedList<File>();
+        pending.add(parent);
+        while (!pending.isEmpty() && result.getCount() < 24) {
+            final File file = pending.removeFirst();
+            if (file.isDirectory()) {
+                for (File child : file.listFiles()) {
+                    pending.add(child);
+                }
+            }
+            if (file.getName().toLowerCase().contains(query)) {
+                includeFile(result, null, file);
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public String getDocumentType(String documentId) throws FileNotFoundException {
+        final File file = getFileForDocId(documentId);
+        return getTypeForFile(file);
+    }
+
+    @Override
+    public ParcelFileDescriptor openDocument(
+            String documentId, String mode, CancellationSignal signal)
+            throws FileNotFoundException {
+        final File file = getFileForDocId(documentId);
+        return ParcelFileDescriptor.open(file, ContentResolver.modeToMode(null, mode));
+    }
+
+    @Override
+    public AssetFileDescriptor openDocumentThumbnail(
+            String documentId, Point sizeHint, CancellationSignal signal)
+            throws FileNotFoundException {
+        final File file = getFileForDocId(documentId);
+        final ParcelFileDescriptor pfd = ParcelFileDescriptor.open(
+                file, ParcelFileDescriptor.MODE_READ_ONLY);
+
+        try {
+            final ExifInterface exif = new ExifInterface(file.getAbsolutePath());
+            final long[] thumb = exif.getThumbnailRange();
+            if (thumb != null) {
+                return new AssetFileDescriptor(pfd, thumb[0], thumb[1]);
+            }
+        } catch (IOException e) {
+        }
+
+        return new AssetFileDescriptor(pfd, 0, AssetFileDescriptor.UNKNOWN_LENGTH);
+    }
+
+    private static String getTypeForFile(File file) {
+        if (file.isDirectory()) {
+            return Document.MIME_TYPE_DIR;
+        } else {
+            return getTypeForName(file.getName());
+        }
+    }
+
+    private static String getTypeForName(String name) {
+        final int lastDot = name.lastIndexOf('.');
+        if (lastDot >= 0) {
+            final String extension = name.substring(lastDot + 1);
+            final String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
+            if (mime != null) {
+                return mime;
+            }
+        }
+
+        return "application/octet-stream";
+    }
+
+    private static String validateDisplayName(String mimeType, String displayName) {
+        if (Document.MIME_TYPE_DIR.equals(mimeType)) {
+            return displayName;
+        } else {
+            // Try appending meaningful extension if needed
+            if (!mimeType.equals(getTypeForName(displayName))) {
+                final String extension = MimeTypeMap.getSingleton()
+                        .getExtensionFromMimeType(mimeType);
+                if (extension != null) {
+                    displayName += "." + extension;
+                }
+            }
+
+            return displayName;
+        }
+    }
+}
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/TestDocumentsProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/TestDocumentsProvider.java
new file mode 100644
index 0000000..a917e3f
--- /dev/null
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/TestDocumentsProvider.java
@@ -0,0 +1,301 @@
+/*
+ * 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.externalstorage;
+
+import android.content.ContentResolver;
+import android.content.res.AssetFileDescriptor;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.database.MatrixCursor.RowBuilder;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.CompressFormat;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Point;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.CancellationSignal;
+import android.os.ParcelFileDescriptor;
+import android.os.SystemClock;
+import android.provider.DocumentsContract;
+import android.provider.DocumentsContract.Document;
+import android.provider.DocumentsContract.Root;
+import android.provider.DocumentsProvider;
+import android.util.Log;
+
+import libcore.io.IoUtils;
+import libcore.io.Streams;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.lang.ref.WeakReference;
+
+public class TestDocumentsProvider extends DocumentsProvider {
+    private static final String TAG = "TestDocuments";
+
+    private static final boolean CRASH_ROOTS = false;
+    private static final boolean CRASH_DOCUMENT = false;
+
+    private static final String MY_ROOT_ID = "myRoot";
+    private static final String MY_DOC_ID = "myDoc";
+    private static final String MY_DOC_NULL = "myNull";
+
+    private static final String[] DEFAULT_ROOT_PROJECTION = new String[] {
+            Root.COLUMN_ROOT_ID, Root.COLUMN_ROOT_TYPE, Root.COLUMN_FLAGS, Root.COLUMN_ICON,
+            Root.COLUMN_TITLE, Root.COLUMN_SUMMARY, Root.COLUMN_DOCUMENT_ID,
+            Root.COLUMN_AVAILABLE_BYTES,
+    };
+
+    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,
+    };
+
+    private static String[] resolveRootProjection(String[] projection) {
+        return projection != null ? projection : DEFAULT_ROOT_PROJECTION;
+    }
+
+    private static String[] resolveDocumentProjection(String[] projection) {
+        return projection != null ? projection : DEFAULT_DOCUMENT_PROJECTION;
+    }
+
+    @Override
+    public Cursor queryRoots(String[] projection) throws FileNotFoundException {
+        if (CRASH_ROOTS) System.exit(12);
+
+        final MatrixCursor result = new MatrixCursor(resolveRootProjection(projection));
+        final RowBuilder row = result.newRow();
+        row.add(Root.COLUMN_ROOT_ID, MY_ROOT_ID);
+        row.add(Root.COLUMN_ROOT_TYPE, Root.ROOT_TYPE_SERVICE);
+        row.add(Root.COLUMN_FLAGS, Root.FLAG_SUPPORTS_RECENTS);
+        row.add(Root.COLUMN_TITLE, "_Test title which is really long");
+        row.add(Root.COLUMN_SUMMARY, "_Summary which is also super long text");
+        row.add(Root.COLUMN_DOCUMENT_ID, MY_DOC_ID);
+        row.add(Root.COLUMN_AVAILABLE_BYTES, 1024);
+        return result;
+    }
+
+    @Override
+    public Cursor queryDocument(String documentId, String[] projection)
+            throws FileNotFoundException {
+        if (CRASH_DOCUMENT) System.exit(12);
+
+        final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection));
+        includeFile(result, documentId, 0);
+        return result;
+    }
+
+    /**
+     * Holds any outstanding or finished "network" fetching.
+     */
+    private WeakReference<CloudTask> mTask;
+
+    private static class CloudTask implements Runnable {
+
+        private final ContentResolver mResolver;
+        private final Uri mNotifyUri;
+
+        private volatile boolean mFinished;
+
+        public CloudTask(ContentResolver resolver, Uri notifyUri) {
+            mResolver = resolver;
+            mNotifyUri = notifyUri;
+        }
+
+        @Override
+        public void run() {
+            // Pretend to do some network
+            Log.d(TAG, hashCode() + ": pretending to do some network!");
+            SystemClock.sleep(2000);
+            Log.d(TAG, hashCode() + ": network done!");
+
+            mFinished = true;
+
+            // Tell anyone remotely they should requery
+            mResolver.notifyChange(mNotifyUri, null, false);
+        }
+
+        public boolean includeIfFinished(MatrixCursor result) {
+            Log.d(TAG, hashCode() + ": includeIfFinished() found " + mFinished);
+            if (mFinished) {
+                includeFile(result, "_networkfile1", 0);
+                includeFile(result, "_networkfile2", 0);
+                includeFile(result, "_networkfile3", 0);
+                includeFile(result, "_networkfile4", 0);
+                includeFile(result, "_networkfile5", 0);
+                includeFile(result, "_networkfile6", 0);
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    private static class CloudCursor extends MatrixCursor {
+        public Object keepAlive;
+        public final Bundle extras = new Bundle();
+
+        public CloudCursor(String[] columnNames) {
+            super(columnNames);
+        }
+
+        @Override
+        public Bundle getExtras() {
+            return extras;
+        }
+    }
+
+    @Override
+    public Cursor queryChildDocuments(
+            String parentDocumentId, String[] projection, String sortOrder)
+            throws FileNotFoundException {
+
+        final ContentResolver resolver = getContext().getContentResolver();
+        final Uri notifyUri = DocumentsContract.buildDocumentUri(
+                "com.example.documents", parentDocumentId);
+
+        CloudCursor result = new CloudCursor(resolveDocumentProjection(projection));
+        result.setNotificationUri(resolver, notifyUri);
+
+        // Always include local results
+        includeFile(result, MY_DOC_NULL, 0);
+        includeFile(result, "localfile1", 0);
+        includeFile(result, "localfile2", Document.FLAG_SUPPORTS_THUMBNAIL);
+        includeFile(result, "localfile3", 0);
+        includeFile(result, "localfile4", 0);
+
+        synchronized (this) {
+            // Try picking up an existing network fetch
+            CloudTask task = mTask != null ? mTask.get() : null;
+            if (task == null) {
+                Log.d(TAG, "No network task found; starting!");
+                task = new CloudTask(resolver, notifyUri);
+                mTask = new WeakReference<CloudTask>(task);
+                new Thread(task).start();
+
+                // Aggressively try freeing weak reference above
+                new Thread() {
+                    @Override
+                    public void run() {
+                        while (mTask.get() != null) {
+                            SystemClock.sleep(200);
+                            System.gc();
+                            System.runFinalization();
+                        }
+                        Log.d(TAG, "AHA! THE CLOUD TASK WAS GC'ED!");
+                    }
+                }.start();
+            }
+
+            // Blend in cloud results if ready
+            if (task.includeIfFinished(result)) {
+                result.extras.putString(DocumentsContract.EXTRA_INFO,
+                        "Everything Went Better Than Expected and this message is quite "
+                                + "long and verbose and maybe even too long");
+                result.extras.putString(DocumentsContract.EXTRA_ERROR,
+                        "But then again, maybe our server ran into an error, which means "
+                                + "we're going to have a bad time");
+            } else {
+                result.extras.putBoolean(DocumentsContract.EXTRA_LOADING, true);
+            }
+
+            // Tie the network fetch to the cursor GC lifetime
+            result.keepAlive = task;
+
+            return result;
+        }
+    }
+
+    @Override
+    public Cursor queryRecentDocuments(String rootId, String[] projection)
+            throws FileNotFoundException {
+        // Pretend to take a super long time to respond
+        SystemClock.sleep(3000);
+
+        final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection));
+        includeFile(
+                result, "It was /worth/ the_wait for?the file:with the&incredibly long name", 0);
+        return result;
+    }
+
+    @Override
+    public ParcelFileDescriptor openDocument(String docId, String mode, CancellationSignal signal)
+            throws FileNotFoundException {
+        throw new FileNotFoundException();
+    }
+
+    @Override
+    public AssetFileDescriptor openDocumentThumbnail(
+            String docId, Point sizeHint, CancellationSignal signal) throws FileNotFoundException {
+        final Bitmap bitmap = Bitmap.createBitmap(32, 32, Bitmap.Config.ARGB_8888);
+        final Canvas canvas = new Canvas(bitmap);
+        final Paint paint = new Paint();
+        paint.setColor(Color.BLUE);
+        canvas.drawColor(Color.RED);
+        canvas.drawLine(0, 0, 32, 32, paint);
+
+        final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        bitmap.compress(CompressFormat.JPEG, 50, bos);
+
+        final ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+        try {
+            final ParcelFileDescriptor[] fds = ParcelFileDescriptor.createReliablePipe();
+            new AsyncTask<Object, Object, Object>() {
+                @Override
+                protected Object doInBackground(Object... params) {
+                    final FileOutputStream fos = new FileOutputStream(fds[1].getFileDescriptor());
+                    try {
+                        Streams.copy(bis, fos);
+                    } catch (IOException e) {
+                        throw new RuntimeException(e);
+                    }
+                    IoUtils.closeQuietly(fds[1]);
+                    return null;
+                }
+            }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+            return new AssetFileDescriptor(fds[0], 0, AssetFileDescriptor.UNKNOWN_LENGTH);
+        } catch (IOException e) {
+            throw new FileNotFoundException(e.getMessage());
+        }
+    }
+
+    @Override
+    public boolean onCreate() {
+        return true;
+    }
+
+    private static void includeFile(MatrixCursor result, String docId, int flags) {
+        final RowBuilder row = result.newRow();
+        row.add(Document.COLUMN_DOCUMENT_ID, docId);
+        row.add(Document.COLUMN_DISPLAY_NAME, docId);
+        row.add(Document.COLUMN_LAST_MODIFIED, System.currentTimeMillis());
+        row.add(Document.COLUMN_FLAGS, flags);
+
+        if (MY_DOC_ID.equals(docId)) {
+            row.add(Document.COLUMN_MIME_TYPE, Document.MIME_TYPE_DIR);
+        } else if (MY_DOC_NULL.equals(docId)) {
+            // No MIME type
+        } else {
+            row.add(Document.COLUMN_MIME_TYPE, "application/octet-stream");
+        }
+    }
+}
diff --git a/packages/FusedLocation/Android.mk b/packages/FusedLocation/Android.mk
index 318782f..7406eaf4 100644
--- a/packages/FusedLocation/Android.mk
+++ b/packages/FusedLocation/Android.mk
@@ -23,5 +23,6 @@
 
 LOCAL_PACKAGE_NAME := FusedLocation
 LOCAL_CERTIFICATE := platform
+LOCAL_PRIVILEGED_MODULE := true
 
 include $(BUILD_PACKAGE)
diff --git a/packages/InputDevices/Android.mk b/packages/InputDevices/Android.mk
index 37f2428..f537022 100644
--- a/packages/InputDevices/Android.mk
+++ b/packages/InputDevices/Android.mk
@@ -23,20 +23,27 @@
 
 LOCAL_PACKAGE_NAME := InputDevices
 LOCAL_CERTIFICATE := platform
+LOCAL_PRIVILEGED_MODULE := true
 
 include $(BUILD_PACKAGE)
 
 # Validate all key maps.
 include $(CLEAR_VARS)
 
-validatekeymaps := $(HOST_OUT_EXECUTABLES)/validatekeymaps$(HOST_EXECUTABLE_SUFFIX)
-files := frameworks/base/packages/InputDevices/res/raw/*.kcm
-
 LOCAL_MODULE := validate_input_devices_keymaps
-LOCAL_MODULE_TAGS := optional
-LOCAL_REQUIRED_MODULES := validatekeymaps
+intermediates := $(call intermediates-dir-for,ETC,$(LOCAL_MODULE),,COMMON)
+LOCAL_BUILT_MODULE := $(intermediates)/stamp
 
-validate_input_devices_keymaps: $(files)
-	$(hide) $(validatekeymaps) $(files)
+validatekeymaps := $(HOST_OUT_EXECUTABLES)/validatekeymaps$(HOST_EXECUTABLE_SUFFIX)
+input_devices_keymaps := $(wildcard $(LOCAL_PATH)/res/raw/*.kcm)
+$(LOCAL_BUILT_MODULE): PRIVATE_VALIDATEKEYMAPS := $(validatekeymaps)
+$(LOCAL_BUILT_MODULE) : $(input_devices_keymaps) | $(validatekeymaps)
+	$(hide) $(PRIVATE_VALIDATEKEYMAPS) $^
+	$(hide) mkdir -p $(dir $@) && touch $@
 
-include $(BUILD_PHONY_PACKAGE)
+# Run validatekeymaps unconditionally for platform build.
+droidcore all_modules : $(LOCAL_BUILT_MODULE)
+
+# Reset temp vars.
+validatekeymaps :=
+input_devices_keymaps :=
diff --git a/packages/Keyguard/Android.mk b/packages/Keyguard/Android.mk
new file mode 100644
index 0000000..f6f441d
--- /dev/null
+++ b/packages/Keyguard/Android.mk
@@ -0,0 +1,33 @@
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-subdir-Iaidl-files)
+
+LOCAL_JAVA_LIBRARIES := services
+
+LOCAL_PACKAGE_NAME := Keyguard
+
+LOCAL_CERTIFICATE := platform
+
+LOCAL_PRIVILEGED_MODULE := true
+
+LOCAL_PROGUARD_FLAG_FILES := proguard.flags
+
+include $(BUILD_PACKAGE)
+
+#include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/Keyguard/AndroidManifest.xml b/packages/Keyguard/AndroidManifest.xml
new file mode 100644
index 0000000..7d77c48
--- /dev/null
+++ b/packages/Keyguard/AndroidManifest.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.keyguard"
+    android:sharedUserId="android.uid.systemui"
+    coreApp="true">
+    <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="17"/>
+    <uses-permission android:name="android.permission.VIBRATE" />
+    <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
+    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
+    <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.STATUS_BAR" />
+    <uses-permission android:name="android.permission.DEVICE_POWER" />
+    <uses-permission android:name="android.permission.MANAGE_USERS" />
+    <uses-permission android:name="android.permission.MANAGE_APP_TOKENS" />
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+    <uses-permission android:name="android.permission.BIND_APPWIDGET" />
+    <uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW" />
+    <uses-permission android:name="android.permission.BIND_DEVICE_ADMIN" />
+    <uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" />
+
+    <application android:label="@string/app_name"
+        android:process="com.android.systemui"
+        android:persistent="true" >
+
+        <service android:name=".KeyguardService"
+            android:exported="true" />
+
+    </application>
+</manifest>
diff --git a/packages/Keyguard/NOTICE b/packages/Keyguard/NOTICE
new file mode 100644
index 0000000..33ff961
--- /dev/null
+++ b/packages/Keyguard/NOTICE
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2005-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.
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/packages/Keyguard/proguard.flags b/packages/Keyguard/proguard.flags
new file mode 100644
index 0000000..fb74b64
--- /dev/null
+++ b/packages/Keyguard/proguard.flags
@@ -0,0 +1,27 @@
+-keep public class * {
+  public void setBackgroundAlpha(float);
+  public float getBackgroundAlpha();
+  public void setContentAlpha(float);
+  public float getContentAlpha();
+  public void setAlpha(float);
+  public float getAlpha();
+  public void setAlpha(int);
+  public int getAlpha();
+  public void setRotationX(float);
+  public float getRotationX();
+  public void setRotationY(float);
+  public float getRotationY();
+  public void setPivotX(float);
+  public float getPivotX();
+  public void setPivotY(float);
+  public float getPivotY();
+  public void setScaleX(float);
+  public float getScaleX();
+  public void setScaleY(float);
+  public float getScaleY();
+  public void setTranslationX(float);
+  public float getTranslationX();
+  public void setTranslationY(float);
+  public float getTranslationY();
+}
+
diff --git a/core/res/res/anim/keyguard_action_assist_enter.xml b/packages/Keyguard/res/anim/keyguard_action_assist_enter.xml
similarity index 100%
rename from core/res/res/anim/keyguard_action_assist_enter.xml
rename to packages/Keyguard/res/anim/keyguard_action_assist_enter.xml
diff --git a/core/res/res/anim/keyguard_action_assist_exit.xml b/packages/Keyguard/res/anim/keyguard_action_assist_exit.xml
similarity index 100%
rename from core/res/res/anim/keyguard_action_assist_exit.xml
rename to packages/Keyguard/res/anim/keyguard_action_assist_exit.xml
diff --git a/core/res/res/anim/keyguard_security_animate_in.xml b/packages/Keyguard/res/anim/keyguard_security_animate_in.xml
similarity index 100%
rename from core/res/res/anim/keyguard_security_animate_in.xml
rename to packages/Keyguard/res/anim/keyguard_security_animate_in.xml
diff --git a/core/res/res/anim/keyguard_security_animate_out.xml b/packages/Keyguard/res/anim/keyguard_security_animate_out.xml
similarity index 100%
rename from core/res/res/anim/keyguard_security_animate_out.xml
rename to packages/Keyguard/res/anim/keyguard_security_animate_out.xml
diff --git a/packages/Keyguard/res/anim/keyguard_security_fade_in.xml b/packages/Keyguard/res/anim/keyguard_security_fade_in.xml
new file mode 100644
index 0000000..c66c604
--- /dev/null
+++ b/packages/Keyguard/res/anim/keyguard_security_fade_in.xml
@@ -0,0 +1,22 @@
+<?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.
+-->
+
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+    android:interpolator="@android:interpolator/decelerate_quad"
+    android:fromAlpha="0.0" android:toAlpha="1.0"
+    android:duration="@integer/kg_security_fade_duration" />
+
+
diff --git a/packages/Keyguard/res/anim/keyguard_security_fade_out.xml b/packages/Keyguard/res/anim/keyguard_security_fade_out.xml
new file mode 100644
index 0000000..6465b35
--- /dev/null
+++ b/packages/Keyguard/res/anim/keyguard_security_fade_out.xml
@@ -0,0 +1,21 @@
+<?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.
+-->
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+    android:interpolator="@android:interpolator/accelerate_quad"
+    android:fromAlpha="1.0"
+    android:toAlpha="0.0"
+    android:duration="@integer/kg_security_fade_duration"
+/>
diff --git a/packages/Keyguard/res/anim/lock_screen_enter.xml b/packages/Keyguard/res/anim/lock_screen_enter.xml
new file mode 100644
index 0000000..4344cf9
--- /dev/null
+++ b/packages/Keyguard/res/anim/lock_screen_enter.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:interpolator="@android:interpolator/accelerate_cubic">
+    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+        android:duration="@integer/config_activityDefaultDur" />
+</set>
diff --git a/packages/Keyguard/res/anim/lock_screen_exit.xml b/packages/Keyguard/res/anim/lock_screen_exit.xml
new file mode 100644
index 0000000..c75b3cc
--- /dev/null
+++ b/packages/Keyguard/res/anim/lock_screen_exit.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    android:zAdjustment="top"
+    android:shareInterpolator="false">
+    <scale
+        android:fromXScale="1.0" android:toXScale="1.10"
+        android:fromYScale="1.0" android:toYScale="1.10"
+        android:pivotX="50%p" android:pivotY="50%p"
+        android:fillEnabled="true" android:fillAfter="true"
+        android:interpolator="@android:interpolator/accelerate_quint"
+        android:duration="@android:integer/config_shortAnimTime" />
+    <alpha
+        android:fromAlpha="1.0" android:toAlpha="0"
+        android:fillEnabled="true" android:fillAfter="true"
+        android:interpolator="@android:interpolator/accelerate_quad"
+        android:duration="@android:integer/config_shortAnimTime"/>
+</set>
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_action_assist_generic_activated.png b/packages/Keyguard/res/drawable-hdpi/ic_action_assist_generic_activated.png
new file mode 100644
index 0000000..c0e2098
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_action_assist_generic_activated.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_action_assist_generic_normal.png b/packages/Keyguard/res/drawable-hdpi/ic_action_assist_generic_normal.png
new file mode 100644
index 0000000..a852e2c
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_action_assist_generic_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_facial_backup.png b/packages/Keyguard/res/drawable-hdpi/ic_facial_backup.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_facial_backup.png
rename to packages/Keyguard/res/drawable-hdpi/ic_facial_backup.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_input_delete.png b/packages/Keyguard/res/drawable-hdpi/ic_input_delete.png
new file mode 100644
index 0000000..5d638bd
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_input_delete.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_alarm.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_alarm.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_lockscreen_alarm.png
rename to packages/Keyguard/res/drawable-hdpi/ic_lockscreen_alarm.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_camera_activated.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_camera_activated.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_lockscreen_camera_activated.png
rename to packages/Keyguard/res/drawable-hdpi/ic_lockscreen_camera_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_camera_normal.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_camera_normal.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_lockscreen_camera_normal.png
rename to packages/Keyguard/res/drawable-hdpi/ic_lockscreen_camera_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_emergencycall_normal.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_emergencycall_normal.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_lockscreen_emergencycall_normal.png
rename to packages/Keyguard/res/drawable-hdpi/ic_lockscreen_emergencycall_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_emergencycall_pressed.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_emergencycall_pressed.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_lockscreen_emergencycall_pressed.png
rename to packages/Keyguard/res/drawable-hdpi/ic_lockscreen_emergencycall_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_forgotpassword_normal.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_forgotpassword_normal.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_lockscreen_forgotpassword_normal.png
rename to packages/Keyguard/res/drawable-hdpi/ic_lockscreen_forgotpassword_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_forgotpassword_pressed.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_forgotpassword_pressed.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_lockscreen_forgotpassword_pressed.png
rename to packages/Keyguard/res/drawable-hdpi/ic_lockscreen_forgotpassword_pressed.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_glowdot.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_glowdot.png
new file mode 100644
index 0000000..983c45e
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_glowdot.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_google_activated.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_google_activated.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_lockscreen_google_activated.png
rename to packages/Keyguard/res/drawable-hdpi/ic_lockscreen_google_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_google_focused.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_google_focused.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_lockscreen_google_focused.png
rename to packages/Keyguard/res/drawable-hdpi/ic_lockscreen_google_focused.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_google_normal.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_google_normal.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_lockscreen_google_normal.png
rename to packages/Keyguard/res/drawable-hdpi/ic_lockscreen_google_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_handle_normal.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_handle_normal.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_lockscreen_handle_normal.png
rename to packages/Keyguard/res/drawable-hdpi/ic_lockscreen_handle_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_handle_pressed.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_handle_pressed.png
new file mode 100644
index 0000000..58a5f16
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_handle_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_ime.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_ime.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_lockscreen_ime.png
rename to packages/Keyguard/res/drawable-hdpi/ic_lockscreen_ime.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_lock_normal.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_lock_normal.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_lockscreen_lock_normal.png
rename to packages/Keyguard/res/drawable-hdpi/ic_lockscreen_lock_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_lock_pressed.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_lock_pressed.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_lockscreen_lock_pressed.png
rename to packages/Keyguard/res/drawable-hdpi/ic_lockscreen_lock_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_player_background.9.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_player_background.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_lockscreen_player_background.9.png
rename to packages/Keyguard/res/drawable-hdpi/ic_lockscreen_player_background.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_search_activated.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_search_activated.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_lockscreen_search_activated.png
rename to packages/Keyguard/res/drawable-hdpi/ic_lockscreen_search_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_search_normal.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_search_normal.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_lockscreen_search_normal.png
rename to packages/Keyguard/res/drawable-hdpi/ic_lockscreen_search_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_silent_activated.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_silent_activated.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_lockscreen_silent_activated.png
rename to packages/Keyguard/res/drawable-hdpi/ic_lockscreen_silent_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_silent_focused.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_silent_focused.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_lockscreen_silent_focused.png
rename to packages/Keyguard/res/drawable-hdpi/ic_lockscreen_silent_focused.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_silent_normal.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_silent_normal.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_lockscreen_silent_normal.png
rename to packages/Keyguard/res/drawable-hdpi/ic_lockscreen_silent_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_sim.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_sim.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_lockscreen_sim.png
rename to packages/Keyguard/res/drawable-hdpi/ic_lockscreen_sim.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_soundon_activated.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_soundon_activated.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_lockscreen_soundon_activated.png
rename to packages/Keyguard/res/drawable-hdpi/ic_lockscreen_soundon_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_soundon_focused.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_soundon_focused.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_lockscreen_soundon_focused.png
rename to packages/Keyguard/res/drawable-hdpi/ic_lockscreen_soundon_focused.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_soundon_normal.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_soundon_normal.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_lockscreen_soundon_normal.png
rename to packages/Keyguard/res/drawable-hdpi/ic_lockscreen_soundon_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_unlock_activated.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_unlock_activated.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_lockscreen_unlock_activated.png
rename to packages/Keyguard/res/drawable-hdpi/ic_lockscreen_unlock_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_unlock_normal.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_unlock_normal.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_lockscreen_unlock_normal.png
rename to packages/Keyguard/res/drawable-hdpi/ic_lockscreen_unlock_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_media_next.png b/packages/Keyguard/res/drawable-hdpi/ic_media_next.png
new file mode 100644
index 0000000..6e27b81
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_media_next.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_media_play.png b/packages/Keyguard/res/drawable-hdpi/ic_media_play.png
new file mode 100644
index 0000000..2746d17
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_media_play.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_media_previous.png b/packages/Keyguard/res/drawable-hdpi/ic_media_previous.png
new file mode 100644
index 0000000..85b3766
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_media_previous.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/intro_bg.png b/packages/Keyguard/res/drawable-hdpi/intro_bg.png
similarity index 100%
rename from core/res/res/drawable-hdpi/intro_bg.png
rename to packages/Keyguard/res/drawable-hdpi/intro_bg.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/kg_add_widget.png b/packages/Keyguard/res/drawable-hdpi/kg_add_widget.png
new file mode 100644
index 0000000..7456705
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/kg_add_widget.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/kg_add_widget_disabled.png b/packages/Keyguard/res/drawable-hdpi/kg_add_widget_disabled.png
similarity index 100%
rename from core/res/res/drawable-hdpi/kg_add_widget_disabled.png
rename to packages/Keyguard/res/drawable-hdpi/kg_add_widget_disabled.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/kg_add_widget_pressed.png b/packages/Keyguard/res/drawable-hdpi/kg_add_widget_pressed.png
similarity index 100%
rename from core/res/res/drawable-hdpi/kg_add_widget_pressed.png
rename to packages/Keyguard/res/drawable-hdpi/kg_add_widget_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/kg_bouncer_bg_white.9.png b/packages/Keyguard/res/drawable-hdpi/kg_bouncer_bg_white.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/kg_bouncer_bg_white.9.png
rename to packages/Keyguard/res/drawable-hdpi/kg_bouncer_bg_white.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/kg_security_grip.9.png b/packages/Keyguard/res/drawable-hdpi/kg_security_grip.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/kg_security_grip.9.png
rename to packages/Keyguard/res/drawable-hdpi/kg_security_grip.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/kg_security_lock.png b/packages/Keyguard/res/drawable-hdpi/kg_security_lock.png
similarity index 100%
rename from core/res/res/drawable-hdpi/kg_security_lock.png
rename to packages/Keyguard/res/drawable-hdpi/kg_security_lock.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/kg_security_lock_focused.png b/packages/Keyguard/res/drawable-hdpi/kg_security_lock_focused.png
new file mode 100644
index 0000000..9a82799
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/kg_security_lock_focused.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/kg_security_lock_normal.png b/packages/Keyguard/res/drawable-hdpi/kg_security_lock_normal.png
new file mode 100644
index 0000000..d608707
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/kg_security_lock_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/kg_security_lock_pressed.png b/packages/Keyguard/res/drawable-hdpi/kg_security_lock_pressed.png
new file mode 100644
index 0000000..7ca995d
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/kg_security_lock_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/kg_widget_bg_padded.9.png b/packages/Keyguard/res/drawable-hdpi/kg_widget_bg_padded.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/kg_widget_bg_padded.9.png
rename to packages/Keyguard/res/drawable-hdpi/kg_widget_bg_padded.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/kg_widget_delete_drop_target.png b/packages/Keyguard/res/drawable-hdpi/kg_widget_delete_drop_target.png
similarity index 100%
rename from core/res/res/drawable-hdpi/kg_widget_delete_drop_target.png
rename to packages/Keyguard/res/drawable-hdpi/kg_widget_delete_drop_target.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/lockscreen_protection_pattern.png b/packages/Keyguard/res/drawable-hdpi/lockscreen_protection_pattern.png
similarity index 100%
rename from core/res/res/drawable-hdpi/lockscreen_protection_pattern.png
rename to packages/Keyguard/res/drawable-hdpi/lockscreen_protection_pattern.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/sym_keyboard_return_holo.png b/packages/Keyguard/res/drawable-hdpi/sym_keyboard_return_holo.png
similarity index 100%
rename from core/res/res/drawable-hdpi/sym_keyboard_return_holo.png
rename to packages/Keyguard/res/drawable-hdpi/sym_keyboard_return_holo.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-ldpi/ic_input_delete.png b/packages/Keyguard/res/drawable-ldpi/ic_input_delete.png
new file mode 100644
index 0000000..d7eff17
--- /dev/null
+++ b/packages/Keyguard/res/drawable-ldpi/ic_input_delete.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-ldpi/ic_media_next.png b/packages/Keyguard/res/drawable-ldpi/ic_media_next.png
new file mode 100644
index 0000000..99927fd
--- /dev/null
+++ b/packages/Keyguard/res/drawable-ldpi/ic_media_next.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-ldpi/ic_media_play.png b/packages/Keyguard/res/drawable-ldpi/ic_media_play.png
new file mode 100644
index 0000000..e7c1972
--- /dev/null
+++ b/packages/Keyguard/res/drawable-ldpi/ic_media_play.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-ldpi/ic_media_previous.png b/packages/Keyguard/res/drawable-ldpi/ic_media_previous.png
new file mode 100644
index 0000000..df04322
--- /dev/null
+++ b/packages/Keyguard/res/drawable-ldpi/ic_media_previous.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_action_assist_generic_activated.png b/packages/Keyguard/res/drawable-mdpi/ic_action_assist_generic_activated.png
new file mode 100644
index 0000000..f88f7e1
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_action_assist_generic_activated.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_action_assist_generic_normal.png b/packages/Keyguard/res/drawable-mdpi/ic_action_assist_generic_normal.png
new file mode 100644
index 0000000..7426994
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_action_assist_generic_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_facial_backup.png b/packages/Keyguard/res/drawable-mdpi/ic_facial_backup.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_facial_backup.png
rename to packages/Keyguard/res/drawable-mdpi/ic_facial_backup.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_input_delete.png b/packages/Keyguard/res/drawable-mdpi/ic_input_delete.png
new file mode 100644
index 0000000..47c8708
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_input_delete.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_alarm.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_alarm.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_lockscreen_alarm.png
rename to packages/Keyguard/res/drawable-mdpi/ic_lockscreen_alarm.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_camera_activated.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_camera_activated.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_lockscreen_camera_activated.png
rename to packages/Keyguard/res/drawable-mdpi/ic_lockscreen_camera_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_camera_normal.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_camera_normal.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_lockscreen_camera_normal.png
rename to packages/Keyguard/res/drawable-mdpi/ic_lockscreen_camera_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_emergencycall_normal.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_emergencycall_normal.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_lockscreen_emergencycall_normal.png
rename to packages/Keyguard/res/drawable-mdpi/ic_lockscreen_emergencycall_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_emergencycall_pressed.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_emergencycall_pressed.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_lockscreen_emergencycall_pressed.png
rename to packages/Keyguard/res/drawable-mdpi/ic_lockscreen_emergencycall_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_forgotpassword_normal.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_forgotpassword_normal.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_lockscreen_forgotpassword_normal.png
rename to packages/Keyguard/res/drawable-mdpi/ic_lockscreen_forgotpassword_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_forgotpassword_pressed.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_forgotpassword_pressed.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_lockscreen_forgotpassword_pressed.png
rename to packages/Keyguard/res/drawable-mdpi/ic_lockscreen_forgotpassword_pressed.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_glowdot.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_glowdot.png
new file mode 100644
index 0000000..056c3f17
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_glowdot.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_google_activated.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_google_activated.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_lockscreen_google_activated.png
rename to packages/Keyguard/res/drawable-mdpi/ic_lockscreen_google_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_google_focused.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_google_focused.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_lockscreen_google_focused.png
rename to packages/Keyguard/res/drawable-mdpi/ic_lockscreen_google_focused.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_google_normal.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_google_normal.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_lockscreen_google_normal.png
rename to packages/Keyguard/res/drawable-mdpi/ic_lockscreen_google_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_handle_normal.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_handle_normal.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_lockscreen_handle_normal.png
rename to packages/Keyguard/res/drawable-mdpi/ic_lockscreen_handle_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_handle_pressed.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_handle_pressed.png
new file mode 100644
index 0000000..0187a02
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_handle_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_ime.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_ime.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_lockscreen_ime.png
rename to packages/Keyguard/res/drawable-mdpi/ic_lockscreen_ime.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_lock_normal.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_lock_normal.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_lockscreen_lock_normal.png
rename to packages/Keyguard/res/drawable-mdpi/ic_lockscreen_lock_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_lock_pressed.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_lock_pressed.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_lockscreen_lock_pressed.png
rename to packages/Keyguard/res/drawable-mdpi/ic_lockscreen_lock_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_player_background.9.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_player_background.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_lockscreen_player_background.9.png
rename to packages/Keyguard/res/drawable-mdpi/ic_lockscreen_player_background.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_search_activated.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_search_activated.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_lockscreen_search_activated.png
rename to packages/Keyguard/res/drawable-mdpi/ic_lockscreen_search_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_search_normal.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_search_normal.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_lockscreen_search_normal.png
rename to packages/Keyguard/res/drawable-mdpi/ic_lockscreen_search_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_silent_activated.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_silent_activated.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_lockscreen_silent_activated.png
rename to packages/Keyguard/res/drawable-mdpi/ic_lockscreen_silent_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_silent_focused.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_silent_focused.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_lockscreen_silent_focused.png
rename to packages/Keyguard/res/drawable-mdpi/ic_lockscreen_silent_focused.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_silent_normal.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_silent_normal.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_lockscreen_silent_normal.png
rename to packages/Keyguard/res/drawable-mdpi/ic_lockscreen_silent_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_sim.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_sim.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_lockscreen_sim.png
rename to packages/Keyguard/res/drawable-mdpi/ic_lockscreen_sim.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_soundon_activated.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_soundon_activated.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_lockscreen_soundon_activated.png
rename to packages/Keyguard/res/drawable-mdpi/ic_lockscreen_soundon_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_soundon_focused.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_soundon_focused.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_lockscreen_soundon_focused.png
rename to packages/Keyguard/res/drawable-mdpi/ic_lockscreen_soundon_focused.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_soundon_normal.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_soundon_normal.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_lockscreen_soundon_normal.png
rename to packages/Keyguard/res/drawable-mdpi/ic_lockscreen_soundon_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_unlock_activated.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_unlock_activated.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_lockscreen_unlock_activated.png
rename to packages/Keyguard/res/drawable-mdpi/ic_lockscreen_unlock_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_unlock_normal.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_unlock_normal.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_lockscreen_unlock_normal.png
rename to packages/Keyguard/res/drawable-mdpi/ic_lockscreen_unlock_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_media_next.png b/packages/Keyguard/res/drawable-mdpi/ic_media_next.png
new file mode 100644
index 0000000..fcd73d9
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_media_next.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_media_play.png b/packages/Keyguard/res/drawable-mdpi/ic_media_play.png
new file mode 100644
index 0000000..7966bbc
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_media_play.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_media_previous.png b/packages/Keyguard/res/drawable-mdpi/ic_media_previous.png
new file mode 100644
index 0000000..b653d05
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_media_previous.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/intro_bg.png b/packages/Keyguard/res/drawable-mdpi/intro_bg.png
similarity index 100%
rename from core/res/res/drawable-mdpi/intro_bg.png
rename to packages/Keyguard/res/drawable-mdpi/intro_bg.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/kg_add_widget.png b/packages/Keyguard/res/drawable-mdpi/kg_add_widget.png
new file mode 100644
index 0000000..1cab0d9
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/kg_add_widget.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_add_widget_disabled.png b/packages/Keyguard/res/drawable-mdpi/kg_add_widget_disabled.png
similarity index 100%
rename from core/res/res/drawable-mdpi/kg_add_widget_disabled.png
rename to packages/Keyguard/res/drawable-mdpi/kg_add_widget_disabled.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_add_widget_pressed.png b/packages/Keyguard/res/drawable-mdpi/kg_add_widget_pressed.png
similarity index 100%
rename from core/res/res/drawable-mdpi/kg_add_widget_pressed.png
rename to packages/Keyguard/res/drawable-mdpi/kg_add_widget_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_bouncer_bg_white.9.png b/packages/Keyguard/res/drawable-mdpi/kg_bouncer_bg_white.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/kg_bouncer_bg_white.9.png
rename to packages/Keyguard/res/drawable-mdpi/kg_bouncer_bg_white.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_security_grip.9.png b/packages/Keyguard/res/drawable-mdpi/kg_security_grip.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/kg_security_grip.9.png
rename to packages/Keyguard/res/drawable-mdpi/kg_security_grip.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_security_lock.png b/packages/Keyguard/res/drawable-mdpi/kg_security_lock.png
similarity index 100%
rename from core/res/res/drawable-mdpi/kg_security_lock.png
rename to packages/Keyguard/res/drawable-mdpi/kg_security_lock.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/kg_security_lock_focused.png b/packages/Keyguard/res/drawable-mdpi/kg_security_lock_focused.png
new file mode 100644
index 0000000..c3608f9
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/kg_security_lock_focused.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/kg_security_lock_normal.png b/packages/Keyguard/res/drawable-mdpi/kg_security_lock_normal.png
new file mode 100644
index 0000000..7957c79
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/kg_security_lock_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/kg_security_lock_pressed.png b/packages/Keyguard/res/drawable-mdpi/kg_security_lock_pressed.png
new file mode 100644
index 0000000..41715f5
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/kg_security_lock_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_widget_bg_padded.9.png b/packages/Keyguard/res/drawable-mdpi/kg_widget_bg_padded.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/kg_widget_bg_padded.9.png
rename to packages/Keyguard/res/drawable-mdpi/kg_widget_bg_padded.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_widget_delete_drop_target.png b/packages/Keyguard/res/drawable-mdpi/kg_widget_delete_drop_target.png
similarity index 100%
rename from core/res/res/drawable-mdpi/kg_widget_delete_drop_target.png
rename to packages/Keyguard/res/drawable-mdpi/kg_widget_delete_drop_target.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/lockscreen_protection_pattern.png b/packages/Keyguard/res/drawable-mdpi/lockscreen_protection_pattern.png
similarity index 100%
rename from core/res/res/drawable-mdpi/lockscreen_protection_pattern.png
rename to packages/Keyguard/res/drawable-mdpi/lockscreen_protection_pattern.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_keyboard_return_holo.png b/packages/Keyguard/res/drawable-mdpi/sym_keyboard_return_holo.png
similarity index 100%
rename from core/res/res/drawable-mdpi/sym_keyboard_return_holo.png
rename to packages/Keyguard/res/drawable-mdpi/sym_keyboard_return_holo.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-hdpi/ic_lockscreen_handle_normal.png b/packages/Keyguard/res/drawable-sw600dp-hdpi/ic_lockscreen_handle_normal.png
similarity index 100%
rename from core/res/res/drawable-sw600dp-hdpi/ic_lockscreen_handle_normal.png
rename to packages/Keyguard/res/drawable-sw600dp-hdpi/ic_lockscreen_handle_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-sw600dp-hdpi/ic_lockscreen_handle_pressed.png b/packages/Keyguard/res/drawable-sw600dp-hdpi/ic_lockscreen_handle_pressed.png
new file mode 100644
index 0000000..728fc67
--- /dev/null
+++ b/packages/Keyguard/res/drawable-sw600dp-hdpi/ic_lockscreen_handle_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-mdpi/ic_lockscreen_handle_normal.png b/packages/Keyguard/res/drawable-sw600dp-mdpi/ic_lockscreen_handle_normal.png
similarity index 100%
rename from core/res/res/drawable-sw600dp-mdpi/ic_lockscreen_handle_normal.png
rename to packages/Keyguard/res/drawable-sw600dp-mdpi/ic_lockscreen_handle_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-sw600dp-mdpi/ic_lockscreen_handle_pressed.png b/packages/Keyguard/res/drawable-sw600dp-mdpi/ic_lockscreen_handle_pressed.png
new file mode 100644
index 0000000..c7da024
--- /dev/null
+++ b/packages/Keyguard/res/drawable-sw600dp-mdpi/ic_lockscreen_handle_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-xhdpi/ic_lockscreen_handle_normal.png b/packages/Keyguard/res/drawable-sw600dp-xhdpi/ic_lockscreen_handle_normal.png
similarity index 100%
rename from core/res/res/drawable-sw600dp-xhdpi/ic_lockscreen_handle_normal.png
rename to packages/Keyguard/res/drawable-sw600dp-xhdpi/ic_lockscreen_handle_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-sw600dp-xhdpi/ic_lockscreen_handle_pressed.png b/packages/Keyguard/res/drawable-sw600dp-xhdpi/ic_lockscreen_handle_pressed.png
new file mode 100644
index 0000000..534c10b
--- /dev/null
+++ b/packages/Keyguard/res/drawable-sw600dp-xhdpi/ic_lockscreen_handle_pressed.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_action_assist_generic_activated.png b/packages/Keyguard/res/drawable-xhdpi/ic_action_assist_generic_activated.png
new file mode 100644
index 0000000..500b157
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_action_assist_generic_activated.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_action_assist_generic_normal.png b/packages/Keyguard/res/drawable-xhdpi/ic_action_assist_generic_normal.png
new file mode 100644
index 0000000..d0e4cf3
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_action_assist_generic_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_facial_backup.png b/packages/Keyguard/res/drawable-xhdpi/ic_facial_backup.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_facial_backup.png
rename to packages/Keyguard/res/drawable-xhdpi/ic_facial_backup.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_input_delete.png b/packages/Keyguard/res/drawable-xhdpi/ic_input_delete.png
new file mode 100644
index 0000000..8b822d9
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_input_delete.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_alarm.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_alarm.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_lockscreen_alarm.png
rename to packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_alarm.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_camera_activated.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_camera_activated.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_lockscreen_camera_activated.png
rename to packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_camera_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_camera_normal.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_camera_normal.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_lockscreen_camera_normal.png
rename to packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_camera_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_emergencycall_normal.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_emergencycall_normal.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_lockscreen_emergencycall_normal.png
rename to packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_emergencycall_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_emergencycall_pressed.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_emergencycall_pressed.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_lockscreen_emergencycall_pressed.png
rename to packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_emergencycall_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_forgotpassword_normal.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_forgotpassword_normal.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_lockscreen_forgotpassword_normal.png
rename to packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_forgotpassword_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_forgotpassword_pressed.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_forgotpassword_pressed.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_lockscreen_forgotpassword_pressed.png
rename to packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_forgotpassword_pressed.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_glowdot.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_glowdot.png
new file mode 100644
index 0000000..cbd039a
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_glowdot.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_google_activated.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_google_activated.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_lockscreen_google_activated.png
rename to packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_google_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_google_focused.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_google_focused.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_lockscreen_google_focused.png
rename to packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_google_focused.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_google_normal.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_google_normal.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_lockscreen_google_normal.png
rename to packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_google_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_handle_normal.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_handle_normal.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_lockscreen_handle_normal.png
rename to packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_handle_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_handle_pressed.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_handle_pressed.png
new file mode 100644
index 0000000..2d28009
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_handle_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_ime.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_ime.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_lockscreen_ime.png
rename to packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_ime.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_lock_normal.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_lock_normal.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_lockscreen_lock_normal.png
rename to packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_lock_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_lock_pressed.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_lock_pressed.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_lockscreen_lock_pressed.png
rename to packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_lock_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_player_background.9.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_player_background.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_lockscreen_player_background.9.png
rename to packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_player_background.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_silent_activated.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_silent_activated.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_lockscreen_silent_activated.png
rename to packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_silent_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_silent_focused.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_silent_focused.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_lockscreen_silent_focused.png
rename to packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_silent_focused.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_silent_normal.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_silent_normal.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_lockscreen_silent_normal.png
rename to packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_silent_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_sim.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_sim.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_lockscreen_sim.png
rename to packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_sim.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_soundon_activated.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_soundon_activated.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_lockscreen_soundon_activated.png
rename to packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_soundon_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_soundon_focused.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_soundon_focused.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_lockscreen_soundon_focused.png
rename to packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_soundon_focused.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_soundon_normal.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_soundon_normal.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_lockscreen_soundon_normal.png
rename to packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_soundon_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_unlock_activated.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_unlock_activated.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_lockscreen_unlock_activated.png
rename to packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_unlock_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_unlock_normal.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_unlock_normal.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_lockscreen_unlock_normal.png
rename to packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_unlock_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_media_next.png b/packages/Keyguard/res/drawable-xhdpi/ic_media_next.png
new file mode 100644
index 0000000..4def965
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_media_next.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_media_play.png b/packages/Keyguard/res/drawable-xhdpi/ic_media_play.png
new file mode 100644
index 0000000..ccfef18
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_media_play.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_media_previous.png b/packages/Keyguard/res/drawable-xhdpi/ic_media_previous.png
new file mode 100644
index 0000000..c4472ae
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_media_previous.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/intro_bg.png b/packages/Keyguard/res/drawable-xhdpi/intro_bg.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/intro_bg.png
rename to packages/Keyguard/res/drawable-xhdpi/intro_bg.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/kg_add_widget.png b/packages/Keyguard/res/drawable-xhdpi/kg_add_widget.png
new file mode 100644
index 0000000..d71905f
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/kg_add_widget.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_add_widget_disabled.png b/packages/Keyguard/res/drawable-xhdpi/kg_add_widget_disabled.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/kg_add_widget_disabled.png
rename to packages/Keyguard/res/drawable-xhdpi/kg_add_widget_disabled.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_add_widget_pressed.png b/packages/Keyguard/res/drawable-xhdpi/kg_add_widget_pressed.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/kg_add_widget_pressed.png
rename to packages/Keyguard/res/drawable-xhdpi/kg_add_widget_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_bouncer_bg_white.9.png b/packages/Keyguard/res/drawable-xhdpi/kg_bouncer_bg_white.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/kg_bouncer_bg_white.9.png
rename to packages/Keyguard/res/drawable-xhdpi/kg_bouncer_bg_white.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_security_grip.9.png b/packages/Keyguard/res/drawable-xhdpi/kg_security_grip.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/kg_security_grip.9.png
rename to packages/Keyguard/res/drawable-xhdpi/kg_security_grip.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_security_lock.png b/packages/Keyguard/res/drawable-xhdpi/kg_security_lock.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/kg_security_lock.png
rename to packages/Keyguard/res/drawable-xhdpi/kg_security_lock.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/kg_security_lock_focused.png b/packages/Keyguard/res/drawable-xhdpi/kg_security_lock_focused.png
new file mode 100644
index 0000000..db22016
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/kg_security_lock_focused.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/kg_security_lock_normal.png b/packages/Keyguard/res/drawable-xhdpi/kg_security_lock_normal.png
new file mode 100644
index 0000000..17ebb5f
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/kg_security_lock_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/kg_security_lock_pressed.png b/packages/Keyguard/res/drawable-xhdpi/kg_security_lock_pressed.png
new file mode 100644
index 0000000..186b6ff
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/kg_security_lock_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_widget_bg_padded.9.png b/packages/Keyguard/res/drawable-xhdpi/kg_widget_bg_padded.9.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/kg_widget_bg_padded.9.png
rename to packages/Keyguard/res/drawable-xhdpi/kg_widget_bg_padded.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_widget_delete_drop_target.png b/packages/Keyguard/res/drawable-xhdpi/kg_widget_delete_drop_target.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/kg_widget_delete_drop_target.png
rename to packages/Keyguard/res/drawable-xhdpi/kg_widget_delete_drop_target.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/lockscreen_protection_pattern.png b/packages/Keyguard/res/drawable-xhdpi/lockscreen_protection_pattern.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/lockscreen_protection_pattern.png
rename to packages/Keyguard/res/drawable-xhdpi/lockscreen_protection_pattern.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/sym_keyboard_return_holo.png b/packages/Keyguard/res/drawable-xhdpi/sym_keyboard_return_holo.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/sym_keyboard_return_holo.png
rename to packages/Keyguard/res/drawable-xhdpi/sym_keyboard_return_holo.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable/ic_action_assist_generic.xml b/packages/Keyguard/res/drawable/ic_action_assist_generic.xml
new file mode 100644
index 0000000..60f5d5d
--- /dev/null
+++ b/packages/Keyguard/res/drawable/ic_action_assist_generic.xml
@@ -0,0 +1,36 @@
+<?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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item
+        android:state_enabled="true"
+        android:state_active="false"
+        android:state_focused="false"
+        android:drawable="@drawable/ic_action_assist_generic_normal" />
+
+    <item
+        android:state_enabled="true"
+        android:state_active="true"
+        android:state_focused="false"
+        android:drawable="@drawable/ic_action_assist_generic_activated" />
+
+    <item
+        android:state_enabled="true"
+        android:state_active="false"
+        android:state_focused="true"
+        android:drawable="@drawable/ic_action_assist_generic_activated" />
+
+</selector>
diff --git a/core/res/res/drawable/ic_lockscreen_camera.xml b/packages/Keyguard/res/drawable/ic_lockscreen_camera.xml
similarity index 100%
rename from core/res/res/drawable/ic_lockscreen_camera.xml
rename to packages/Keyguard/res/drawable/ic_lockscreen_camera.xml
diff --git a/core/res/res/drawable/ic_lockscreen_handle.xml b/packages/Keyguard/res/drawable/ic_lockscreen_handle.xml
similarity index 100%
rename from core/res/res/drawable/ic_lockscreen_handle.xml
rename to packages/Keyguard/res/drawable/ic_lockscreen_handle.xml
diff --git a/packages/Keyguard/res/drawable/ic_lockscreen_outerring.xml b/packages/Keyguard/res/drawable/ic_lockscreen_outerring.xml
new file mode 100644
index 0000000..75bea70
--- /dev/null
+++ b/packages/Keyguard/res/drawable/ic_lockscreen_outerring.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="oval"
+    >
+    <size android:height="@dimen/keyguard_lockscreen_outerring_diameter"
+          android:width="@dimen/keyguard_lockscreen_outerring_diameter" />
+    <solid android:color="#00000000" />
+    <stroke android:color="#1affffff" android:width="2dp" />
+</shape>
diff --git a/core/res/res/drawable/ic_lockscreen_silent.xml b/packages/Keyguard/res/drawable/ic_lockscreen_silent.xml
similarity index 100%
rename from core/res/res/drawable/ic_lockscreen_silent.xml
rename to packages/Keyguard/res/drawable/ic_lockscreen_silent.xml
diff --git a/core/res/res/drawable/ic_lockscreen_soundon.xml b/packages/Keyguard/res/drawable/ic_lockscreen_soundon.xml
similarity index 100%
rename from core/res/res/drawable/ic_lockscreen_soundon.xml
rename to packages/Keyguard/res/drawable/ic_lockscreen_soundon.xml
diff --git a/core/res/res/drawable/ic_lockscreen_unlock.xml b/packages/Keyguard/res/drawable/ic_lockscreen_unlock.xml
similarity index 100%
rename from core/res/res/drawable/ic_lockscreen_unlock.xml
rename to packages/Keyguard/res/drawable/ic_lockscreen_unlock.xml
diff --git a/core/res/res/drawable/ic_lockscreen_unlock_phantom.xml b/packages/Keyguard/res/drawable/ic_lockscreen_unlock_phantom.xml
similarity index 100%
rename from core/res/res/drawable/ic_lockscreen_unlock_phantom.xml
rename to packages/Keyguard/res/drawable/ic_lockscreen_unlock_phantom.xml
diff --git a/core/res/res/drawable/keyguard_add_widget_button.xml b/packages/Keyguard/res/drawable/keyguard_add_widget_button.xml
similarity index 100%
rename from core/res/res/drawable/keyguard_add_widget_button.xml
rename to packages/Keyguard/res/drawable/keyguard_add_widget_button.xml
diff --git a/core/res/res/drawable/keyguard_expand_challenge_handle.xml b/packages/Keyguard/res/drawable/keyguard_expand_challenge_handle.xml
similarity index 100%
rename from core/res/res/drawable/keyguard_expand_challenge_handle.xml
rename to packages/Keyguard/res/drawable/keyguard_expand_challenge_handle.xml
diff --git a/core/res/res/drawable/lockscreen_emergency_button.xml b/packages/Keyguard/res/drawable/lockscreen_emergency_button.xml
similarity index 100%
rename from core/res/res/drawable/lockscreen_emergency_button.xml
rename to packages/Keyguard/res/drawable/lockscreen_emergency_button.xml
diff --git a/core/res/res/drawable/lockscreen_forgot_password_button.xml b/packages/Keyguard/res/drawable/lockscreen_forgot_password_button.xml
similarity index 100%
rename from core/res/res/drawable/lockscreen_forgot_password_button.xml
rename to packages/Keyguard/res/drawable/lockscreen_forgot_password_button.xml
diff --git a/packages/Keyguard/res/layout-land/keyguard_host_view.xml b/packages/Keyguard/res/layout-land/keyguard_host_view.xml
new file mode 100644
index 0000000..eeb9ee7
--- /dev/null
+++ b/packages/Keyguard/res/layout-land/keyguard_host_view.xml
@@ -0,0 +1,81 @@
+<?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.
+*/
+-->
+
+<!-- This is the host view that generally contains two sub views: the widget view
+    and the security view. -->
+<com.android.keyguard.KeyguardHostView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    android:id="@+id/keyguard_host_view"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="horizontal">
+
+    <com.android.keyguard.MultiPaneChallengeLayout
+        android:id="@+id/multi_pane_challenge"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="horizontal"
+        android:clipChildren="false">
+
+        <include layout="@layout/keyguard_widget_remove_drop_target"
+            android:id="@+id/keyguard_widget_pager_delete_target"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="top|center_horizontal"
+            androidprv:layout_childType="pageDeleteDropTarget" />
+
+        <include layout="@layout/keyguard_widget_pager"
+            android:id="@+id/app_widget_container"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            androidprv:layout_centerWithinArea="0.55"
+            androidprv:layout_childType="widget"
+            androidprv:layout_maxWidth="480dp"
+            androidprv:layout_maxHeight="480dp" />
+        <include layout="@layout/keyguard_multi_user_selector"/>
+
+        <View android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              androidprv:layout_childType="scrim"
+              android:background="#99000000" />
+
+        <com.android.keyguard.KeyguardSecurityContainer
+            android:id="@+id/keyguard_security_container"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            androidprv:layout_childType="challenge"
+            androidprv:layout_centerWithinArea="0.55">
+            <com.android.keyguard.KeyguardSecurityViewFlipper
+                android:id="@+id/view_flipper"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:clipChildren="false"
+                android:clipToPadding="false"
+                android:paddingLeft="@dimen/keyguard_security_view_margin"
+                android:paddingTop="@dimen/keyguard_security_view_margin"
+                android:paddingRight="@dimen/keyguard_security_view_margin"
+                android:paddingBottom="@dimen/keyguard_security_view_margin"
+                android:gravity="center">
+            </com.android.keyguard.KeyguardSecurityViewFlipper>
+        </com.android.keyguard.KeyguardSecurityContainer>
+
+    </com.android.keyguard.MultiPaneChallengeLayout>
+</com.android.keyguard.KeyguardHostView>
+
diff --git a/core/res/res/layout-land/keyguard_status_area.xml b/packages/Keyguard/res/layout-land/keyguard_status_area.xml
similarity index 100%
rename from core/res/res/layout-land/keyguard_status_area.xml
rename to packages/Keyguard/res/layout-land/keyguard_status_area.xml
diff --git a/packages/Keyguard/res/layout-land/keyguard_widget_pager.xml b/packages/Keyguard/res/layout-land/keyguard_widget_pager.xml
new file mode 100644
index 0000000..da31065
--- /dev/null
+++ b/packages/Keyguard/res/layout-land/keyguard_widget_pager.xml
@@ -0,0 +1,30 @@
+<?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.
+*/
+-->
+
+<!-- This is the selector widget that allows the user to select an action. -->
+<com.android.keyguard.KeyguardWidgetCarousel
+    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:paddingLeft="25dp"
+    android:paddingRight="25dp"
+    android:paddingTop="25dp"
+    android:paddingBottom="25dp"
+    android:clipToPadding="false"
+    androidprv:pageSpacing="10dp">
+</com.android.keyguard.KeyguardWidgetCarousel>
diff --git a/packages/Keyguard/res/layout-port/keyguard_host_view.xml b/packages/Keyguard/res/layout-port/keyguard_host_view.xml
new file mode 100644
index 0000000..8498dcf
--- /dev/null
+++ b/packages/Keyguard/res/layout-port/keyguard_host_view.xml
@@ -0,0 +1,94 @@
+<?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.
+*/
+-->
+
+<!-- This is the host view that generally contains two sub views: the widget view
+    and the security view. -->
+<com.android.keyguard.KeyguardHostView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    android:id="@+id/keyguard_host_view"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:gravity="center_horizontal"
+    android:orientation="vertical">
+
+    <com.android.keyguard.SlidingChallengeLayout
+        android:id="@+id/sliding_layout"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            androidprv:layout_childType="pageDeleteDropTarget">
+            <include layout="@layout/keyguard_widget_remove_drop_target"
+                android:id="@+id/keyguard_widget_pager_delete_target"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="top|center_horizontal" />
+        </FrameLayout>
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            androidprv:layout_childType="widgets">
+            <include layout="@layout/keyguard_widget_pager"
+                android:id="@+id/app_widget_container"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_gravity="center"/>
+        </FrameLayout>
+
+        <View android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              androidprv:layout_childType="scrim"
+              android:background="#99000000" />
+
+        <com.android.keyguard.KeyguardSecurityContainer
+            android:id="@+id/keyguard_security_container"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            androidprv:layout_maxHeight="@dimen/keyguard_security_height"
+            androidprv:layout_childType="challenge"
+            android:padding="0dp"
+            android:gravity="bottom|center_horizontal">
+            <com.android.keyguard.KeyguardSecurityViewFlipper
+                android:id="@+id/view_flipper"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:clipChildren="false"
+                android:clipToPadding="false"
+                android:paddingTop="@dimen/keyguard_security_view_margin"
+                android:gravity="center">
+            </com.android.keyguard.KeyguardSecurityViewFlipper>
+        </com.android.keyguard.KeyguardSecurityContainer>
+
+        <ImageButton
+              android:layout_width="match_parent"
+              android:layout_height="@dimen/kg_widget_pager_bottom_padding"
+              androidprv:layout_childType="expandChallengeHandle"
+              android:focusable="true"
+              android:background="@null"
+              android:src="@drawable/keyguard_expand_challenge_handle"
+              android:scaleType="center"
+              android:contentDescription="@string/keyguard_accessibility_expand_lock_area" />
+
+    </com.android.keyguard.SlidingChallengeLayout>
+</com.android.keyguard.KeyguardHostView>
+
diff --git a/core/res/res/layout-port/keyguard_status_area.xml b/packages/Keyguard/res/layout-port/keyguard_status_area.xml
similarity index 100%
rename from core/res/res/layout-port/keyguard_status_area.xml
rename to packages/Keyguard/res/layout-port/keyguard_status_area.xml
diff --git a/packages/Keyguard/res/layout-port/keyguard_widget_pager.xml b/packages/Keyguard/res/layout-port/keyguard_widget_pager.xml
new file mode 100644
index 0000000..d0a07ca
--- /dev/null
+++ b/packages/Keyguard/res/layout-port/keyguard_widget_pager.xml
@@ -0,0 +1,31 @@
+<?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.
+*/
+-->
+
+<!-- This is the selector widget that allows the user to select an action. -->
+<com.android.keyguard.KeyguardWidgetPager
+    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/app_widget_container"
+    android:paddingLeft="25dp"
+    android:paddingRight="25dp"
+    android:paddingTop="25dp"
+    android:paddingBottom="@dimen/kg_widget_pager_bottom_padding"
+    android:clipToPadding="false"
+    androidprv:pageSpacing="10dp">
+</com.android.keyguard.KeyguardWidgetPager>
diff --git a/packages/Keyguard/res/layout-sw600dp-port/keyguard_host_view.xml b/packages/Keyguard/res/layout-sw600dp-port/keyguard_host_view.xml
new file mode 100644
index 0000000..77bc9b5
--- /dev/null
+++ b/packages/Keyguard/res/layout-sw600dp-port/keyguard_host_view.xml
@@ -0,0 +1,82 @@
+<?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.
+*/
+-->
+
+<!-- This is the host view that generally contains two sub views: the widget view
+    and the security view. -->
+<com.android.keyguard.KeyguardHostView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    android:id="@+id/keyguard_host_view"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="horizontal">
+
+    <com.android.keyguard.MultiPaneChallengeLayout
+        android:id="@+id/multi_pane_challenge"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:clipChildren="false"
+        android:orientation="vertical">
+
+        <include layout="@layout/keyguard_widget_remove_drop_target"
+            android:id="@+id/keyguard_widget_pager_delete_target"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="top|center_horizontal"
+            androidprv:layout_childType="pageDeleteDropTarget" />
+
+        <include layout="@layout/keyguard_widget_pager"
+            android:id="@+id/app_widget_container"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            androidprv:layout_centerWithinArea="0.5"
+            androidprv:layout_childType="widget"
+            androidprv:layout_maxWidth="480dp"
+            androidprv:layout_maxHeight="480dp" />
+
+        <include layout="@layout/keyguard_multi_user_selector"/>
+
+        <View android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              androidprv:layout_childType="scrim"
+              android:background="#99000000" />
+
+        <com.android.keyguard.KeyguardSecurityContainer
+            android:id="@+id/keyguard_security_container"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            androidprv:layout_centerWithinArea="0.5"
+            androidprv:layout_childType="challenge"
+            android:layout_gravity="center_horizontal|bottom">
+            <com.android.keyguard.KeyguardSecurityViewFlipper
+                android:id="@+id/view_flipper"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:clipChildren="false"
+                android:clipToPadding="false"
+                android:paddingLeft="@dimen/keyguard_security_view_margin"
+                android:paddingTop="@dimen/keyguard_security_view_margin"
+                android:paddingRight="@dimen/keyguard_security_view_margin"
+                android:paddingBottom="@dimen/keyguard_security_view_margin"
+                android:gravity="center">
+            </com.android.keyguard.KeyguardSecurityViewFlipper>
+        </com.android.keyguard.KeyguardSecurityContainer>
+
+    </com.android.keyguard.MultiPaneChallengeLayout>
+</com.android.keyguard.KeyguardHostView>
diff --git a/core/res/res/layout-sw600dp/keyguard_glow_pad_container.xml b/packages/Keyguard/res/layout-sw600dp/keyguard_glow_pad_container.xml
similarity index 100%
rename from core/res/res/layout-sw600dp/keyguard_glow_pad_container.xml
rename to packages/Keyguard/res/layout-sw600dp/keyguard_glow_pad_container.xml
diff --git a/packages/Keyguard/res/layout/keyguard_account_view.xml b/packages/Keyguard/res/layout/keyguard_account_view.xml
new file mode 100644
index 0000000..766effa
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_account_view.xml
@@ -0,0 +1,88 @@
+<?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.
+*/
+-->
+<com.android.keyguard.KeyguardAccountView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+	xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    android:id="@+id/keyguard_account_view"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    androidprv:layout_maxWidth="@dimen/keyguard_security_width"
+    androidprv:layout_maxHeight="@dimen/keyguard_security_height"
+    android:orientation="vertical">
+
+    <include layout="@layout/keyguard_message_area"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="0dip"
+        android:layout_weight="1">
+
+        <EditText
+            android:id="@+id/login"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="8dip"
+            android:layout_marginStart="7dip"
+            android:layout_marginEnd="7dip"
+            android:layout_alignParentTop="true"
+            android:hint="@string/kg_login_username_hint"
+            android:inputType="textEmailAddress"
+            />
+
+        <EditText
+            android:id="@+id/password"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_below="@id/login"
+            android:layout_toLeftOf="@+id/ok"
+            android:layout_marginTop="15dip"
+            android:layout_marginStart="7dip"
+            android:layout_marginEnd="7dip"
+            android:inputType="textPassword"
+            android:hint="@string/kg_login_password_hint"
+            android:nextFocusRight="@+id/ok"
+            android:nextFocusDown="@+id/ok"
+            />
+
+        <!-- ok below password, aligned to right of screen -->
+        <Button
+            android:id="@+id/ok"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="7dip"
+            android:layout_alignParentEnd="true"
+            android:layout_below="@id/login"
+            android:text="@string/kg_login_submit_button"
+            />
+
+    </RelativeLayout>
+
+    <!--  no room for ECA on this screen right now
+    <include layout="@layout/keyguard_eca"
+        android:id="@+id/keyguard_selector_fade_container"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:layout_gravity="bottom|center_horizontal"
+        android:gravity="center_horizontal" />
+    -->
+
+</com.android.keyguard.KeyguardAccountView>
diff --git a/packages/Keyguard/res/layout/keyguard_add_widget.xml b/packages/Keyguard/res/layout/keyguard_add_widget.xml
new file mode 100644
index 0000000..01b616c
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_add_widget.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2009, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- This is a view that shows general status information in Keyguard. -->
+<com.android.keyguard.KeyguardWidgetFrame
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/keyguard_add_widget"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    >
+    <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:contentDescription="@string/keyguard_accessibility_widget_empty_slot"
+            >
+        <ImageView
+            android:id="@+id/keyguard_add_widget_view"
+            android:clickable="true"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:padding="24dp"
+            android:src="@drawable/keyguard_add_widget_button"
+            android:contentDescription="@string/keyguard_accessibility_add_widget"/>
+    </FrameLayout>
+</com.android.keyguard.KeyguardWidgetFrame>
diff --git a/packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml b/packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml
new file mode 100644
index 0000000..de673ec
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml
@@ -0,0 +1,76 @@
+<?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.
+*/
+-->
+
+<!-- This contains emergency call button and carrier as shared by pin/pattern/password screens -->
+<com.android.keyguard.EmergencyCarrierArea
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:gravity="center"
+    android:layout_gravity="center_horizontal"
+    android:layout_alignParentBottom="true"
+    android:clickable="true">
+
+    <com.android.keyguard.CarrierText
+        android:id="@+id/carrier_text"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:singleLine="true"
+        android:ellipsize="marquee"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textSize="@dimen/kg_status_line_font_size"
+        android:textColor="?android:attr/textColorSecondary"/>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="-10dip"
+        style="?android:attr/buttonBarStyle"
+        android:orientation="horizontal"
+        android:gravity="center"
+        android:weightSum="2">
+
+        <com.android.keyguard.EmergencyButton
+            android:id="@+id/emergency_call_button"
+            android:layout_width="0dip"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:drawableLeft="@drawable/lockscreen_emergency_button"
+            android:text="@string/kg_emergency_call_label"
+            style="?android:attr/buttonBarButtonStyle"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textSize="@dimen/kg_status_line_font_size"
+            android:textColor="?android:attr/textColorSecondary"
+            android:drawablePadding="8dip" />
+
+        <Button android:id="@+id/forgot_password_button"
+            android:layout_width="0dip"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:drawableLeft="@drawable/lockscreen_forgot_password_button"
+            style="?android:attr/buttonBarButtonStyle"
+            android:textSize="@dimen/kg_status_line_font_size"
+            android:textColor="?android:attr/textColorSecondary"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:drawablePadding="8dip"
+            android:visibility="gone"/>
+    </LinearLayout>
+
+</com.android.keyguard.EmergencyCarrierArea>
diff --git a/core/res/res/layout/keyguard_emergency_carrier_area_empty.xml b/packages/Keyguard/res/layout/keyguard_emergency_carrier_area_empty.xml
similarity index 100%
rename from core/res/res/layout/keyguard_emergency_carrier_area_empty.xml
rename to packages/Keyguard/res/layout/keyguard_emergency_carrier_area_empty.xml
diff --git a/packages/Keyguard/res/layout/keyguard_face_unlock_view.xml b/packages/Keyguard/res/layout/keyguard_face_unlock_view.xml
new file mode 100644
index 0000000..94c68a5
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_face_unlock_view.xml
@@ -0,0 +1,79 @@
+<?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.
+*/
+-->
+
+<!-- This is the screen that allows the user to unlock by showing their face.  -->
+<com.android.keyguard.KeyguardFaceUnlockView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    android:id="@+id/keyguard_face_unlock_view"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    androidprv:layout_maxWidth="@dimen/keyguard_security_width"
+    androidprv:layout_maxHeight="@dimen/keyguard_security_height"
+    android:contentDescription="@string/keyguard_accessibility_face_unlock">
+
+    <include layout="@layout/keyguard_message_area"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        />
+
+    <FrameLayout
+       android:id="@+id/keyguard_bouncer_frame"
+       android:background="@drawable/kg_bouncer_bg_white"
+       android:layout_width="match_parent"
+       android:layout_height="0dp"
+       android:layout_weight="1"
+       >
+       <com.android.internal.widget.FaceUnlockView
+           android:id="@+id/face_unlock_area_view"
+           android:layout_width="match_parent"
+           android:layout_height="match_parent"
+           android:layout_gravity="center_horizontal"
+           android:background="@drawable/intro_bg"
+           android:gravity="center">
+
+           <View
+               android:id="@+id/spotlightMask"
+               android:layout_width="match_parent"
+               android:layout_height="match_parent"
+               android:background="@color/facelock_spotlight_mask"
+           />
+
+           <ImageButton
+               android:id="@+id/face_unlock_cancel_button"
+               android:layout_width="wrap_content"
+               android:layout_height="wrap_content"
+               android:padding="5dip"
+               android:layout_alignParentTop="true"
+               android:layout_alignParentEnd="true"
+               android:background="#00000000"
+               android:src="@drawable/ic_facial_backup"
+           />
+       </com.android.internal.widget.FaceUnlockView>
+    </FrameLayout>
+
+    <include layout="@layout/keyguard_eca"
+        android:id="@+id/keyguard_selector_fade_container"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:layout_gravity="bottom|center_horizontal"
+        android:gravity="center_horizontal" />
+</com.android.keyguard.KeyguardFaceUnlockView>
diff --git a/packages/Keyguard/res/layout/keyguard_glow_pad_container.xml b/packages/Keyguard/res/layout/keyguard_glow_pad_container.xml
new file mode 100644
index 0000000..376d0e9
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_glow_pad_container.xml
@@ -0,0 +1,26 @@
+<?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.
+*/
+-->
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+    <include layout="@layout/keyguard_glow_pad_view"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom|center_horizontal"
+        android:layout_marginBottom="-80dp"/>
+</merge>
\ No newline at end of file
diff --git a/packages/Keyguard/res/layout/keyguard_glow_pad_view.xml b/packages/Keyguard/res/layout/keyguard_glow_pad_view.xml
new file mode 100644
index 0000000..3a466dd
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_glow_pad_view.xml
@@ -0,0 +1,46 @@
+<?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.
+*/
+-->
+
+<!-- This is the selector widget that allows the user to select an action. -->
+<com.android.internal.widget.multiwaveview.GlowPadView
+    xmlns:prvandroid="http://schemas.android.com/apk/prv/res/android"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/glow_pad_view"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_gravity="center"
+    android:orientation="horizontal"
+    android:gravity="@integer/kg_selector_gravity"
+    android:contentDescription="@string/keyguard_accessibility_slide_area"
+
+    prvandroid:targetDrawables="@array/lockscreen_targets_unlock_only"
+    prvandroid:targetDescriptions="@array/lockscreen_target_descriptions_unlock_only"
+    prvandroid:directionDescriptions="@array/lockscreen_direction_descriptions"
+    prvandroid:handleDrawable="@drawable/ic_lockscreen_handle"
+    prvandroid:outerRingDrawable="@drawable/ic_lockscreen_outerring"
+    prvandroid:outerRadius="@dimen/glowpadview_target_placement_radius"
+    prvandroid:innerRadius="@dimen/glowpadview_inner_radius"
+    prvandroid:snapMargin="@dimen/glowpadview_snap_margin"
+    prvandroid:firstItemOffset="@integer/kg_glowpad_rotation_offset"
+    prvandroid:magneticTargets="true"
+    prvandroid:feedbackCount="1"
+    prvandroid:vibrationDuration="20"
+    prvandroid:glowRadius="@dimen/glowpadview_glow_radius"
+    prvandroid:pointDrawable="@drawable/ic_lockscreen_glowdot"
+    prvandroid:allowScaling="true" />
diff --git a/packages/Keyguard/res/layout/keyguard_message_area.xml b/packages/Keyguard/res/layout/keyguard_message_area.xml
new file mode 100644
index 0000000..a709e98
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_message_area.xml
@@ -0,0 +1,33 @@
+<?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.
+*/
+-->
+
+<!-- This contains emergency call button and carrier as shared by pin/pattern/password screens -->
+<com.android.keyguard.KeyguardMessageArea
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:gravity="center"
+    android:id="@+id/keyguard_message_area"
+    android:singleLine="true"
+    android:ellipsize="marquee"
+    android:textAppearance="?android:attr/textAppearance"
+    android:textSize="@dimen/kg_status_line_font_size"
+    android:textColor="?android:attr/textColorSecondary"
+    android:clickable="true" />
+
diff --git a/packages/Keyguard/res/layout/keyguard_message_area_large.xml b/packages/Keyguard/res/layout/keyguard_message_area_large.xml
new file mode 100644
index 0000000..ab6246d
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_message_area_large.xml
@@ -0,0 +1,31 @@
+<?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.
+*/
+-->
+
+<!-- This contains emergency call button and carrier as shared by pin/pattern/password screens -->
+<com.android.keyguard.KeyguardMessageArea
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:gravity="center"
+    android:id="@+id/keyguard_message_area"
+    android:maxLines="4"
+    android:textAppearance="?android:attr/textAppearance"
+    android:textSize="@dimen/kg_status_line_font_size"
+    android:textColor="?android:attr/textColorSecondary" />
+
diff --git a/packages/Keyguard/res/layout/keyguard_multi_user_avatar.xml b/packages/Keyguard/res/layout/keyguard_multi_user_avatar.xml
new file mode 100644
index 0000000..41b0be9
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_multi_user_avatar.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2009, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- This is a view that shows general status information in Keyguard. -->
+<com.android.keyguard.KeyguardMultiUserAvatar
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="@dimen/keyguard_avatar_size"
+    android:layout_height="@dimen/keyguard_avatar_size"
+    android:background="#00000000"
+    android:gravity="center_horizontal">
+    <ImageView
+        android:id="@+id/keyguard_user_avatar"
+        android:scaleType="center"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_gravity="center"/>
+    <TextView
+       android:id="@+id/keyguard_user_name"
+       android:layout_width="match_parent"
+       android:layout_height="wrap_content"
+       android:layout_gravity="bottom"
+       android:gravity="center"
+       android:textSize="@dimen/keyguard_avatar_name_size"
+       android:textColor="#ffffff"
+       android:singleLine="true"
+       android:ellipsize="end"
+       android:paddingLeft="2dp"
+       android:paddingRight="2dp" />
+</com.android.keyguard.KeyguardMultiUserAvatar>
diff --git a/packages/Keyguard/res/layout/keyguard_multi_user_selector.xml b/packages/Keyguard/res/layout/keyguard_multi_user_selector.xml
new file mode 100644
index 0000000..c1d5326
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_multi_user_selector.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2009, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<com.android.keyguard.KeyguardMultiUserSelectorView
+    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    androidprv:layout_childType="userSwitcher"
+    android:id="@+id/keyguard_user_selector"
+    android:orientation="horizontal"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_gravity="bottom"
+    android:contentDescription="@string/keyguard_accessibility_user_selector"
+    android:visibility="gone">
+
+    <com.android.keyguard.KeyguardLinearLayout
+        android:id="@+id/keyguard_users_grid"
+        android:orientation="horizontal"
+        android:layout_width="wrap_content"
+        android:layout_marginBottom="@dimen/keyguard_muliuser_selector_margin"
+        android:layout_height="@dimen/keyguard_avatar_size"
+        android:layout_gravity="center|bottom" />
+
+</com.android.keyguard.KeyguardMultiUserSelectorView>
diff --git a/packages/Keyguard/res/layout/keyguard_password_view.xml b/packages/Keyguard/res/layout/keyguard_password_view.xml
new file mode 100644
index 0000000..d8012bf
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_password_view.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<com.android.keyguard.KeyguardPasswordView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    android:id="@+id/keyguard_password_view"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    androidprv:layout_maxWidth="@dimen/keyguard_security_width"
+    androidprv:layout_maxHeight="@dimen/keyguard_security_height"
+    android:gravity="bottom"
+    android:contentDescription="@string/keyguard_accessibility_password_unlock"
+    >
+
+    <Space
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1"
+        />
+
+    <include layout="@layout/keyguard_message_area"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" />
+
+    <!-- Password entry field -->
+    <!-- Note: the entire container is styled to look like the edit field,
+         since the backspace/IME switcher looks better inside -->
+      <FrameLayout
+         android:id="@+id/keyguard_bouncer_frame"
+         android:background="@drawable/kg_bouncer_bg_white"
+         android:layout_height="wrap_content"
+         android:layout_width="match_parent"
+         >
+         <LinearLayout
+             android:layout_height="wrap_content"
+             android:layout_width="match_parent"
+             android:orientation="horizontal"
+             android:background="#70000000"
+             android:layout_marginTop="8dp"
+             android:layout_marginBottom="8dp"
+             >
+
+             <EditText android:id="@+id/passwordEntry"
+                 android:layout_width="0dip"
+                 android:layout_height="wrap_content"
+                 android:layout_weight="1"
+                 android:gravity="center_horizontal"
+                 android:layout_gravity="center_vertical"
+                 android:layout_marginStart="@dimen/keyguard_lockscreen_pin_margin_left"
+                 android:singleLine="true"
+                 android:textStyle="normal"
+                 android:inputType="textPassword"
+                 android:textSize="36sp"
+                 android:background="@null"
+                 android:textAppearance="?android:attr/textAppearanceMedium"
+                 android:textColor="#ffffffff"
+                 android:imeOptions="flagForceAscii|actionDone"
+                 />
+
+             <ImageView android:id="@+id/switch_ime_button"
+                 android:layout_width="wrap_content"
+                 android:layout_height="wrap_content"
+                 android:src="@drawable/ic_lockscreen_ime"
+                 android:clickable="true"
+                 android:padding="8dip"
+                 android:layout_gravity="center"
+                 android:background="?android:attr/selectableItemBackground"
+                 android:visibility="gone"
+                 />
+
+            </LinearLayout>
+       </FrameLayout>
+
+    <Space
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1"
+        />
+
+    <include layout="@layout/keyguard_eca"
+             android:id="@+id/keyguard_selector_fade_container"
+             android:layout_width="match_parent"
+             android:layout_height="wrap_content"
+             android:orientation="vertical"
+             android:layout_gravity="bottom|center_horizontal"
+             android:gravity="center_horizontal" />
+
+</com.android.keyguard.KeyguardPasswordView>
diff --git a/packages/Keyguard/res/layout/keyguard_pattern_view.xml b/packages/Keyguard/res/layout/keyguard_pattern_view.xml
new file mode 100644
index 0000000..0c9380c
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_pattern_view.xml
@@ -0,0 +1,79 @@
+<?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.
+*/
+-->
+
+<!-- This is the screen that shows the 9 circle unlock widget and instructs
+     the user how to unlock their device, or make an emergency call.  This
+     is the portrait layout.  -->
+<com.android.keyguard.KeyguardPatternView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    android:id="@+id/keyguard_pattern_view"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    androidprv:layout_maxWidth="@dimen/keyguard_security_width"
+    androidprv:layout_maxHeight="@dimen/keyguard_security_height"
+    android:gravity="center_horizontal"
+    android:contentDescription="@string/keyguard_accessibility_pattern_unlock">
+
+    <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <LinearLayout
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:orientation="vertical"
+            android:layout_gravity="center">
+
+            <include layout="@layout/keyguard_message_area"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+               />
+
+          <FrameLayout
+             android:id="@+id/keyguard_bouncer_frame"
+             android:background="@drawable/kg_bouncer_bg_white"
+             android:layout_width="match_parent"
+             android:layout_height="0dp"
+             android:layout_weight="1"
+             >
+            <com.android.internal.widget.LockPatternView
+                android:id="@+id/lockPatternView"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                android:layout_marginEnd="8dip"
+                android:layout_marginBottom="4dip"
+                android:layout_marginStart="8dip"
+                android:layout_gravity="center_horizontal"
+                android:gravity="center"
+                android:contentDescription="@string/keyguard_accessibility_pattern_area" />
+          </FrameLayout>
+          <include layout="@layout/keyguard_eca"
+              android:id="@+id/keyguard_selector_fade_container"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content"
+              android:orientation="vertical"
+              android:layout_gravity="bottom|center_horizontal"
+              android:gravity="center_horizontal" />
+        </LinearLayout>
+    </FrameLayout>
+
+</com.android.keyguard.KeyguardPatternView>
diff --git a/packages/Keyguard/res/layout/keyguard_pin_view.xml b/packages/Keyguard/res/layout/keyguard_pin_view.xml
new file mode 100644
index 0000000..00c6a21
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_pin_view.xml
@@ -0,0 +1,224 @@
+<?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.
+*/
+-->
+
+<com.android.keyguard.KeyguardPINView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    android:id="@+id/keyguard_pin_view"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    androidprv:layout_maxWidth="@dimen/keyguard_security_width"
+    androidprv:layout_maxHeight="@dimen/keyguard_security_height"
+    android:orientation="vertical"
+    android:contentDescription="@string/keyguard_accessibility_pin_unlock"
+    >
+    <include layout="@layout/keyguard_message_area"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        />
+    <LinearLayout
+       android:id="@+id/keyguard_bouncer_frame"
+       android:background="@drawable/kg_bouncer_bg_white"
+       android:layout_width="match_parent"
+       android:layout_height="0dp"
+       android:orientation="vertical"
+       android:layout_weight="1"
+       android:layoutDirection="ltr"
+       >
+       <LinearLayout
+          android:layout_width="match_parent"
+          android:layout_height="0dp"
+          android:orientation="horizontal"
+          android:layout_weight="1"
+          >
+          <TextView android:id="@+id/pinEntry"
+               android:editable="true"
+               android:layout_width="0dip"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               android:gravity="center"
+               android:layout_marginStart="@dimen/keyguard_lockscreen_pin_margin_left"
+               android:singleLine="true"
+               android:cursorVisible="false"
+               android:background="@null"
+               android:textAppearance="@style/TextAppearance.NumPadKey"
+               android:imeOptions="flagForceAscii|actionDone"
+               />
+           <ImageButton android:id="@+id/delete_button"
+               android:layout_width="wrap_content"
+               android:layout_height="match_parent"
+               android:gravity="center_vertical"
+               android:src="@drawable/ic_input_delete"
+               android:clickable="true"
+               android:paddingTop="8dip"
+               android:paddingBottom="8dip"
+               android:paddingLeft="24dp"
+               android:paddingRight="24dp"
+               android:background="?android:attr/selectableItemBackground"
+               android:contentDescription="@string/keyboardview_keycode_delete"
+               />
+       </LinearLayout>
+       <View
+           android:layout_width="wrap_content"
+           android:layout_height="1dp"
+           android:background="#55FFFFFF"
+           />
+       <LinearLayout
+           android:layout_width="match_parent"
+           android:layout_height="0dp"
+           android:layout_weight="1"
+           android:orientation="horizontal"
+           >
+           <view class="com.android.keyguard.NumPadKey"
+               android:id="@+id/key1"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="1"
+               />
+           <view class="com.android.keyguard.NumPadKey"
+               android:id="@+id/key2"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="2"
+               />
+           <view class="com.android.keyguard.NumPadKey"
+               android:id="@+id/key3"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="3"
+               />
+       </LinearLayout>
+       <LinearLayout
+           android:layout_width="match_parent"
+           android:layout_height="0dp"
+           android:layout_weight="1"
+           android:orientation="horizontal"
+           >
+           <view class="com.android.keyguard.NumPadKey"
+               android:id="@+id/key4"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="4"
+               />
+           <view class="com.android.keyguard.NumPadKey"
+               android:id="@+id/key5"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="5"
+               />
+           <view class="com.android.keyguard.NumPadKey"
+               android:id="@+id/key6"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="6"
+               />
+       </LinearLayout>
+       <LinearLayout
+           android:layout_width="match_parent"
+           android:layout_height="0dp"
+           android:orientation="horizontal"
+           android:layout_weight="1"
+           >
+           <view class="com.android.keyguard.NumPadKey"
+               android:id="@+id/key7"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="7"
+               />
+           <view class="com.android.keyguard.NumPadKey"
+               android:id="@+id/key8"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="8"
+               />
+           <view class="com.android.keyguard.NumPadKey"
+               android:id="@+id/key9"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="9"
+               />
+       </LinearLayout>
+       <LinearLayout
+           android:layout_width="match_parent"
+           android:layout_height="0dp"
+           android:layout_weight="1"
+           android:orientation="horizontal"
+           >
+           <Space
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               />
+           <view class="com.android.keyguard.NumPadKey"
+               android:id="@+id/key0"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="0"
+               />
+           <ImageButton
+               android:id="@+id/key_enter"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               android:paddingRight="30dp"
+               android:src="@drawable/sym_keyboard_return_holo"
+               android:contentDescription="@string/keyboardview_keycode_enter"
+               />
+       </LinearLayout>
+    </LinearLayout>
+    <include layout="@layout/keyguard_eca"
+                   android:id="@+id/keyguard_selector_fade_container"
+                   android:layout_width="match_parent"
+                   android:layout_height="wrap_content"
+                   android:orientation="vertical"
+                   android:layout_gravity="bottom|center_horizontal"
+                   android:gravity="center_horizontal" />
+
+</com.android.keyguard.KeyguardPINView>
diff --git a/packages/Keyguard/res/layout/keyguard_selector_view.xml b/packages/Keyguard/res/layout/keyguard_selector_view.xml
new file mode 100644
index 0000000..6cb5e67
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_selector_view.xml
@@ -0,0 +1,64 @@
+<?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.
+*/
+-->
+
+<!-- This is the selector widget that allows the user to select an action. -->
+<com.android.keyguard.KeyguardSelectorView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    android:id="@+id/keyguard_selector_view"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    androidprv:layout_maxWidth="420dp"
+    androidprv:layout_maxHeight="@dimen/keyguard_security_height"
+    android:clipChildren="false"
+    android:clipToPadding="false"
+    android:orientation="vertical"
+    android:contentDescription="@string/keyguard_accessibility_slide_unlock">
+
+    <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_gravity="center"
+        android:clipChildren="false"
+        android:clipToPadding="false"
+        android:gravity="center">
+
+        <include layout="@layout/keyguard_message_area"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+
+        <View
+            android:id="@+id/keyguard_selector_view_frame"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_marginLeft="16dp"
+            android:layout_marginRight="16dp"
+            android:background="@drawable/kg_bouncer_bg_white"/>
+
+        <include layout="@layout/keyguard_glow_pad_container" />
+
+        <include layout="@layout/keyguard_eca"
+            android:id="@+id/keyguard_selector_fade_container"
+            android:layout_width="match_parent"
+            android:layout_height="48dp"
+            android:layout_gravity="bottom|center_horizontal" />
+    </FrameLayout>
+
+</com.android.keyguard.KeyguardSelectorView>
+
diff --git a/packages/Keyguard/res/layout/keyguard_sim_pin_view.xml b/packages/Keyguard/res/layout/keyguard_sim_pin_view.xml
new file mode 100644
index 0000000..eccac19
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_sim_pin_view.xml
@@ -0,0 +1,230 @@
+<?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.
+*/
+-->
+<!-- This is the SIM PIN view that allows the user to enter a SIM PIN to unlock the device. -->
+<com.android.keyguard.KeyguardSimPinView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    android:id="@+id/keyguard_sim_pin_view"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    androidprv:layout_maxWidth="@dimen/keyguard_security_width"
+    androidprv:layout_maxHeight="@dimen/keyguard_security_height"
+    android:gravity="center_horizontal">
+
+    <ImageView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:src="@drawable/ic_lockscreen_sim"/>
+
+    <include layout="@layout/keyguard_message_area"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        />
+    <LinearLayout
+       android:id="@+id/keyguard_bouncer_frame"
+       android:background="@drawable/kg_bouncer_bg_white"
+       android:layout_width="match_parent"
+       android:layout_height="0dp"
+       android:orientation="vertical"
+       android:layout_weight="1"
+       android:layoutDirection="ltr"
+       >
+       <LinearLayout
+           android:layout_width="match_parent"
+           android:layout_height="0dp"
+           android:orientation="horizontal"
+           android:layout_weight="1"
+           >
+           <TextView android:id="@+id/pinEntry"
+               android:editable="true"
+               android:layout_width="0dip"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               android:gravity="center"
+               android:layout_marginStart="@dimen/keyguard_lockscreen_pin_margin_left"
+               android:singleLine="true"
+               android:cursorVisible="false"
+               android:background="@null"
+               android:textAppearance="@style/TextAppearance.NumPadKey"
+               android:imeOptions="flagForceAscii|actionDone"
+               />
+           <ImageButton android:id="@+id/delete_button"
+               android:layout_width="wrap_content"
+               android:layout_height="match_parent"
+               android:gravity="center_vertical"
+               android:src="@drawable/ic_input_delete"
+               android:clickable="true"
+               android:paddingTop="8dip"
+               android:paddingBottom="8dip"
+               android:paddingLeft="24dp"
+               android:paddingRight="24dp"
+               android:background="?android:attr/selectableItemBackground"
+               android:contentDescription="@string/keyboardview_keycode_delete"
+               />
+       </LinearLayout>
+       <View
+           android:layout_width="wrap_content"
+           android:layout_height="1dp"
+           android:background="#55FFFFFF"
+           />
+       <LinearLayout
+           android:layout_width="match_parent"
+           android:layout_height="0dp"
+           android:layout_weight="1"
+           android:orientation="horizontal"
+           >
+           <view class="com.android.keyguard.NumPadKey"
+               android:id="@+id/key1"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="1"
+               />
+           <view class="com.android.keyguard.NumPadKey"
+               android:id="@+id/key2"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="2"
+               />
+           <view class="com.android.keyguard.NumPadKey"
+               android:id="@+id/key3"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="3"
+               />
+       </LinearLayout>
+       <LinearLayout
+           android:layout_width="match_parent"
+           android:layout_height="0dp"
+           android:layout_weight="1"
+           android:orientation="horizontal"
+           >
+           <view class="com.android.keyguard.NumPadKey"
+               android:id="@+id/key4"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="4"
+               />
+           <view class="com.android.keyguard.NumPadKey"
+               android:id="@+id/key5"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="5"
+               />
+           <view class="com.android.keyguard.NumPadKey"
+               android:id="@+id/key6"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="6"
+               />
+       </LinearLayout>
+       <LinearLayout
+           android:layout_width="match_parent"
+           android:layout_height="0dp"
+           android:orientation="horizontal"
+           android:layout_weight="1"
+           >
+           <view class="com.android.keyguard.NumPadKey"
+               android:id="@+id/key7"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="7"
+               />
+           <view class="com.android.keyguard.NumPadKey"
+               android:id="@+id/key8"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="8"
+               />
+           <view class="com.android.keyguard.NumPadKey"
+               android:id="@+id/key9"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="9"
+               />
+       </LinearLayout>
+       <LinearLayout
+           android:layout_width="match_parent"
+           android:layout_height="0dp"
+           android:layout_weight="1"
+           android:orientation="horizontal"
+           >
+           <Space
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               />
+           <view class="com.android.keyguard.NumPadKey"
+               android:id="@+id/key0"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="0"
+               />
+           <ImageButton
+               android:id="@+id/key_enter"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               android:paddingRight="30dp"
+               android:src="@drawable/sym_keyboard_return_holo"
+               android:contentDescription="@string/keyboardview_keycode_enter"
+               />
+       </LinearLayout>
+    </LinearLayout>
+
+    <include layout="@layout/keyguard_eca"
+                   android:id="@+id/keyguard_selector_fade_container"
+                   android:layout_width="match_parent"
+                   android:layout_height="wrap_content"
+                   android:orientation="vertical"
+                   android:layout_gravity="bottom|center_horizontal"
+                   android:gravity="center_horizontal" />
+
+</com.android.keyguard.KeyguardSimPinView>
diff --git a/packages/Keyguard/res/layout/keyguard_sim_puk_view.xml b/packages/Keyguard/res/layout/keyguard_sim_puk_view.xml
new file mode 100644
index 0000000..fe37203
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_sim_puk_view.xml
@@ -0,0 +1,230 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<!-- This is the SIM PUK view that allows the user to recover their device by entering the
+    carrier-provided PUK code and entering a new SIM PIN for it. -->
+<com.android.keyguard.KeyguardSimPukView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    android:id="@+id/keyguard_sim_puk_view"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    androidprv:layout_maxWidth="@dimen/keyguard_security_width"
+    androidprv:layout_maxHeight="@dimen/keyguard_security_height"
+    android:gravity="center_horizontal">
+
+    <ImageView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:src="@drawable/ic_lockscreen_sim"/>
+
+    <include layout="@layout/keyguard_message_area"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        />
+    <LinearLayout
+       android:id="@+id/keyguard_bouncer_frame"
+       android:background="@drawable/kg_bouncer_bg_white"
+       android:layout_width="match_parent"
+       android:layout_height="0dp"
+       android:orientation="vertical"
+       android:layout_weight="1"
+       android:layoutDirection="ltr"
+       >
+       <LinearLayout
+           android:layout_width="match_parent"
+           android:layout_height="0dp"
+           android:orientation="horizontal"
+           android:layout_weight="1"
+           >
+           <TextView android:id="@+id/pinEntry"
+               android:editable="true"
+               android:layout_width="0dip"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               android:gravity="center"
+               android:layout_marginStart="@dimen/keyguard_lockscreen_pin_margin_left"
+               android:singleLine="true"
+               android:cursorVisible="false"
+               android:background="@null"
+               android:textAppearance="@style/TextAppearance.NumPadKey"
+               android:imeOptions="flagForceAscii|actionDone"
+               />
+           <ImageButton android:id="@+id/delete_button"
+               android:layout_width="wrap_content"
+               android:layout_height="match_parent"
+               android:gravity="center_vertical"
+               android:src="@drawable/ic_input_delete"
+               android:clickable="true"
+               android:paddingTop="8dip"
+               android:paddingBottom="8dip"
+               android:paddingLeft="24dp"
+               android:paddingRight="24dp"
+               android:background="?android:attr/selectableItemBackground"
+               android:contentDescription="@string/keyboardview_keycode_delete"
+               />
+       </LinearLayout>
+       <View
+           android:layout_width="wrap_content"
+           android:layout_height="1dp"
+           android:background="#55FFFFFF"
+           />
+       <LinearLayout
+           android:layout_width="match_parent"
+           android:layout_height="0dp"
+           android:layout_weight="1"
+           android:orientation="horizontal"
+           >
+           <view class="com.android.keyguard.NumPadKey"
+               android:id="@+id/key1"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="1"
+               />
+           <view class="com.android.keyguard.NumPadKey"
+               android:id="@+id/key2"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="2"
+               />
+           <view class="com.android.keyguard.NumPadKey"
+               android:id="@+id/key3"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="3"
+               />
+       </LinearLayout>
+       <LinearLayout
+           android:layout_width="match_parent"
+           android:layout_height="0dp"
+           android:layout_weight="1"
+           android:orientation="horizontal"
+           >
+           <view class="com.android.keyguard.NumPadKey"
+               android:id="@+id/key4"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="4"
+               />
+           <view class="com.android.keyguard.NumPadKey"
+               android:id="@+id/key5"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="5"
+               />
+           <view class="com.android.keyguard.NumPadKey"
+               android:id="@+id/key6"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="6"
+               />
+       </LinearLayout>
+       <LinearLayout
+           android:layout_width="match_parent"
+           android:layout_height="0dp"
+           android:orientation="horizontal"
+           android:layout_weight="1"
+           >
+           <view class="com.android.keyguard.NumPadKey"
+               android:id="@+id/key7"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="7"
+               />
+           <view class="com.android.keyguard.NumPadKey"
+               android:id="@+id/key8"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="8"
+               />
+           <view class="com.android.keyguard.NumPadKey"
+               android:id="@+id/key9"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="9"
+               />
+       </LinearLayout>
+       <LinearLayout
+           android:layout_width="match_parent"
+           android:layout_height="0dp"
+           android:layout_weight="1"
+           android:orientation="horizontal"
+           >
+           <Space
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               />
+           <view class="com.android.keyguard.NumPadKey"
+               android:id="@+id/key0"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               androidprv:textView="@+id/pinEntry"
+               androidprv:digit="0"
+               />
+           <ImageButton
+               android:id="@+id/key_enter"
+               style="@style/Widget.Button.NumPadKey"
+               android:layout_width="0px"
+               android:layout_height="match_parent"
+               android:layout_weight="1"
+               android:paddingRight="30dp"
+               android:src="@drawable/sym_keyboard_return_holo"
+               android:contentDescription="@string/keyboardview_keycode_enter"
+               />
+       </LinearLayout>
+    </LinearLayout>
+
+    <include layout="@layout/keyguard_eca"
+                   android:id="@+id/keyguard_selector_fade_container"
+                   android:layout_width="match_parent"
+                   android:layout_height="wrap_content"
+                   android:orientation="vertical"
+                   android:layout_gravity="bottom|center_horizontal"
+                   android:gravity="center_horizontal" />
+</com.android.keyguard.KeyguardSimPukView>
diff --git a/packages/Keyguard/res/layout/keyguard_status_view.xml b/packages/Keyguard/res/layout/keyguard_status_view.xml
new file mode 100644
index 0000000..2304d9f
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_status_view.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2009, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- This is a view that shows general status information in Keyguard. -->
+<com.android.keyguard.KeyguardWidgetFrame
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+    android:id="@+id/keyguard_status_view"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    androidprv:layout_maxWidth="@dimen/keyguard_security_width"
+    androidprv:layout_maxHeight="@dimen/keyguard_security_height"
+    android:gravity="center_horizontal">
+
+    <com.android.keyguard.KeyguardStatusView
+        android:id="@+id/keyguard_status_view_face_palm"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:gravity="center_horizontal|top"
+        android:contentDescription="@string/keyguard_accessibility_status">
+
+        <LinearLayout android:layout_width="match_parent"
+                      android:layout_height="wrap_content"
+                      android:layout_gravity="center_horizontal|top"
+                      android:orientation="vertical"
+                      android:focusable="true">
+            <com.android.keyguard.ClockView
+                android:id="@+id/clock_view"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
+                android:layout_gravity="right">
+
+                <TextView android:id="@+id/clock_text"
+                          android:layout_width="wrap_content"
+                          android:layout_height="wrap_content"
+                          android:singleLine="true"
+                          android:ellipsize="none"
+                          android:textSize="@dimen/kg_status_clock_font_size"
+                          android:textAppearance="?android:attr/textAppearanceMedium"
+                          android:textColor="#ffffffff"
+                          android:drawablePadding="2dip"
+                          />
+
+            </com.android.keyguard.ClockView>
+
+            <include layout="@layout/keyguard_status_area" />
+        </LinearLayout>
+
+    </com.android.keyguard.KeyguardStatusView>
+</com.android.keyguard.KeyguardWidgetFrame>
diff --git a/packages/Keyguard/res/layout/keyguard_transport_control_view.xml b/packages/Keyguard/res/layout/keyguard_transport_control_view.xml
new file mode 100644
index 0000000..7e36f9f
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_transport_control_view.xml
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<!-- This is a view to control music playback in keyguard. -->
+<com.android.keyguard.KeyguardTransportControlView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:gravity="center_horizontal"
+    android:id="@+id/keyguard_transport_control">
+
+    <!-- FrameLayout used as scrim to show between album art and buttons -->
+    <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:foreground="@drawable/ic_lockscreen_player_background"
+        android:contentDescription="@string/keygaurd_accessibility_media_controls">
+        <!-- Use ImageView for its cropping features; otherwise could be android:background -->
+        <ImageView
+            android:id="@+id/albumart"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_gravity="fill"
+            android:scaleType="centerCrop"
+            android:adjustViewBounds="false"
+        />
+    </FrameLayout>
+
+    <LinearLayout
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom">
+        <TextView
+            android:id="@+id/title"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="8dip"
+            android:layout_marginStart="16dip"
+            android:layout_marginEnd="16dip"
+            android:gravity="center_horizontal"
+            android:singleLine="true"
+            android:ellipsize="end"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+        />
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:layout_marginTop="5dip">
+            <FrameLayout
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="1">
+                <ImageView
+                    android:id="@+id/btn_prev"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center"
+                    android:src="@drawable/ic_media_previous"
+                    android:clickable="true"
+                    android:background="?android:attr/selectableItemBackground"
+                    android:padding="10dip"
+                    android:contentDescription="@string/keyguard_accessibility_transport_prev_description"/>
+            </FrameLayout>
+            <FrameLayout
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="1">
+                <ImageView
+                    android:id="@+id/btn_play"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center"
+                    android:clickable="true"
+                    android:src="@drawable/ic_media_play"
+                    android:background="?android:attr/selectableItemBackground"
+                    android:padding="10dip"
+                    android:contentDescription="@string/keyguard_accessibility_transport_play_description"/>
+            </FrameLayout>
+            <FrameLayout
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="1">
+                <ImageView
+                    android:id="@+id/btn_next"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center"
+                    android:clickable="true"
+                    android:src="@drawable/ic_media_next"
+                    android:background="?android:attr/selectableItemBackground"
+                    android:padding="10dip"
+                    android:contentDescription="@string/keyguard_accessibility_transport_next_description"/>
+            </FrameLayout>
+        </LinearLayout>
+    </LinearLayout>
+
+</com.android.keyguard.KeyguardTransportControlView>
diff --git a/core/res/res/layout/keyguard_widget_remove_drop_target.xml b/packages/Keyguard/res/layout/keyguard_widget_remove_drop_target.xml
similarity index 100%
rename from core/res/res/layout/keyguard_widget_remove_drop_target.xml
rename to packages/Keyguard/res/layout/keyguard_widget_remove_drop_target.xml
diff --git a/packages/Keyguard/res/values-af/activitystrings.xml b/packages/Keyguard/res/values-af/activitystrings.xml
new file mode 100644
index 0000000..f6e8d5e
--- /dev/null
+++ b/packages/Keyguard/res/values-af/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardToetsAktiwiteit"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"VerenigdeKamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Geen sekuriteit nie"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Wagwoord"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Patroon"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"SIM PIN"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"SIM PUK"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Kies legstuk…"</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"opSkermAfgeskakel"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"opSkermAangeskakel"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doenKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifieerOntsluit"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-af/strings.xml b/packages/Keyguard/res/values-af/strings.xml
new file mode 100644
index 0000000..7e1f0bf
--- /dev/null
+++ b/packages/Keyguard/res/values-af/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Voer PIN-kode in"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Voer PUK en nuwe PIN-kode in"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-kode"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Nuwe PIN-kode"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Raak om wagwoord in te voer"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Voer wagwoord in om te ontsluit"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Voer PIN in om te ontsluit"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Verkeerde PIN-kode."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Om te ontsluit, druk Kieslys dan 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Maksimum gesigontsluit-pogings oorskry"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Gelaai"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Laai, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Koppel jou herlaaier."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Druk kieslys om te ontsluit."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Netwerk gesluit"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Geen SIM-kaart nie"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Geen SIM-kaart in tablet nie."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Geen SIM-kaart in foon nie."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Steek \'n SIM-kaart in."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"Die SIM-kaart is weg of nie leesbaar nie. Steek \'n SIM-kaart in."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Onbruikbare SIM-kaart."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Jou SIM-kaart is permanent gedeaktiveer.\n Kontak jou draadlose diensverskaffer vir \'n ander SIM-kaart."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM-kaart is gesluit."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM-kaart is PUK-geslote."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Ontsluit tans SIM-kaart…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Legstuk %2$d van %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Voeg legstuk by."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Leeg"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Ontsluitruimte uitgevou."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Ontsluitruimte ingevou."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>-legstuk."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Gebruikerkieser"</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">"Media-kontroles"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Herordening van legstuk begin."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Herordening van legstuk beëindig."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Legstuk <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> uitgevee."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Vou ontsluitruimte uit."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Sleep-ontsluit."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Patroon ontsluit."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Gesigslot."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"PIN ontsluit."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Wagwoord ontsluit."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Patroonarea."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Sleep-area."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Vorigesnit-knoppie"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Volgendesnit-knoppie"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Laatwag-knoppie"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Speel-knoppie"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Stop-knoppie"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Kanselleer"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Vee uit"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Klaar"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Modus verander"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Invoersleutel"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Ontsluit"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Stil"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Klank aan"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Soek"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Gly op vir <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Gly af vir <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Gly links vir <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Gly regs vir <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g> ."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Noodoproep"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Het jy die patroon vergeet?"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Verkeerde patroon"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Verkeerde wagwoord"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Verkeerde PIN"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Probeer weer oor <xliff:g id="NUMBER">%d</xliff:g> sekondes."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Teken jou patroon"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Voer SIM-PIN in"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Voer PIN in"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Voer wagwoord in"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM is nou gedeaktiveer. Voer PUK-kode in om voort te gaan. Kontak diensverskaffer vir details."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Voer die gewenste PIN-kode in"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Bevestig gewenste PIN-kode"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Ontsluit tans SIM-kaart…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Verkeerde PIN-kode."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Tik \'n PIN in wat 4 tot 8 syfers lank is."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK-kode moet 8 of meer syfers wees."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Voer weer die korrekte PUK-kode in. Herhaalde pogings sal die SIM permanent deaktiveer."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-kodes stem nie ooreen nie"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Te veel patroonpogings"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Om te ontsluit, meld met jou Google-rekening aan."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Gebruikernaam (e-pos)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Wagwoord"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Meld aan"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Ongeldige gebruikernaam of wagwoord."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Het jy jou gebruikernaam of wagwoord vergeet?\nBesoek "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Kontroleer tans rekening..."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Jy het jou PIN <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerd ingetik. \n\nProbeer weer oor <xliff:g id="NUMBER_1">%d</xliff:g> sekondes."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Jy het <xliff:g id="NUMBER_0">%d</xliff:g> keer jou wagwoord verkeerdelik getik. \n\nProbeer weer oor <xliff:g id="NUMBER_1">%d</xliff:g> sekondes."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerdelik geteken. \n\nProbeer weer oor <xliff:g id="NUMBER_1">%d</xliff:g> sekondes."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Jy het <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerdelik gepoog om die tablet te ontsluit. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings, sal die tablet na die fabrieksverstek teruggestel word en al die gebruikerdata sal verlore wees."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Jy het <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerdelik gepoog om die foon te ontsluit. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings, sal die foon na die fabrieksverstek teruggestel word en al die gebruikerdata sal verlore wees."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Jy het <xliff:g id="NUMBER">%d</xliff:g> keer verkeerdelik gepoog om die tablet te ontsluit. Die tablet sal nou na fabrieksverstek teruggestel word."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Jy het <xliff:g id="NUMBER">%d</xliff:g> keer verkeerdelik gepoog om die foon te ontsluit. Die foon sal nou na fabrieksverstek teruggestel word."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerdelik geteken. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings, sal jy gevra word om jou tablet te ontsluit deur middel van \'n e-posrekening.\n\n Probeer weer oor <xliff:g id="NUMBER_2">%d</xliff:g> sekondes."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerdelik geteken. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings, sal jy gevra word om jou foon te ontsluit deur middel van \'n e-posrekening.\n\n Probeer weer oor <xliff:g id="NUMBER_2">%d</xliff:g> sekondes."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Verwyder"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Vorigesnit-knoppie"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Volgendesnit-knoppie"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Laatwag-knoppie"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Speel-knoppie"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Stop-knoppie"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Geen diens nie."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-am/activitystrings.xml b/packages/Keyguard/res/values-am/activitystrings.xml
new file mode 100644
index 0000000..a6c7449
--- /dev/null
+++ b/packages/Keyguard/res/values-am/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"ምንም ደህንነት የለም"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"ፒን"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"የይለፍ ቃል"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"ሥርዓተ ጥለት"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"የሲም ፒን"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"የሲም ፒዩኬ"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"ንዑስ ፕሮግራም ይምረጡ..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-am/strings.xml b/packages/Keyguard/res/values-am/strings.xml
new file mode 100644
index 0000000..2f6dab0
--- /dev/null
+++ b/packages/Keyguard/res/values-am/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"ፒን ኮድ ተይብ"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK እና አዲስ ፒን ተይብ"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"የPUK ኮድ"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"አዲስ Pin ኮድ"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><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">"ትክክል ያልሆነ PIN ኮድ።"</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"ለመክፈት፣ምናሌ ተጫን ከዛ 0"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"የመጨረሻውን  የገጽ ክፈት ሙከራዎችን አልፏል"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"ባትሪ ሞልቷል"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"ባትሪ በመሙላት ላይ፣ <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"የኃይል መሙያዎን ይሰኩ።"</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"ለመክፈት ምናሌውን ይጫኑ።"</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"አውታረ መረብ ተቆልፏል"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"ምንም ሲም ካርድ የለም"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"በጡባዊ ውስጥ ምንም ሲም ካርድ የለም።"</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"በስልኩ ውስጥ ምንም ሲም ካርድ የለም።"</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"ሲም ካርድ ያስገቡ።"</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"ሲም ካርዱ ጠፍቷል ወይም መነበብ አይችልም። እባክዎ ሲም ሲም ካርድ ያስገቡ።"</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"የማይሰራ ሲም ካርድ።"</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"ሲም ካርድዎ እስከመጨረሻው ተሰናክሏል።\n ሌላ ሲም ካርድ ለማግኘት ከገመድ አልባ አገልግሎት አቅራቢዎ ጋር ይገናኙ።"</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"ሲም ካርድ ተዘግቷል።"</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"ሲም ካርድ በፒዩኬ ተዘግቷል።"</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"ሲም ካርዱን በመክፈት ላይ…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s። ምግብር %2$d ከ%3$d።"</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_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>
+    <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_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="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"የቀዳሚ ትራክ አዝራር"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"የቀጣይ ትራክ አዝራር"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"ለአፍታ አቁም አዝራር"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"የአጫውት አዝራር"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"አቁም አዝራር"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</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">"ቀይር"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"አስገባ"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"ክፈት"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"ካሜራ"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"ፀጥታ"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"ድምፅ አብራ"</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_down" msgid="5087739728639014595">"ለ<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="description_direction_right" msgid="8034433242579600980">"ለ<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደ ቀኝ አንሸራትት።"</string>
+    <string name="user_switched" msgid="3768006783166984410">"የአሁኑ ተጠቃሚ <xliff:g id="NAME">%1$s</xliff:g>።"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"የአደጋ ጊዜ ጥሪ"</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_too_many_failed_attempts_countdown" msgid="6358110221603297548">"በ<xliff:g id="NUMBER">%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">"ሲም አሁን ተሰናክሏል። ለመቀጠል የ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="7553388325654369575">"የPUK ኮድ 8 ወይም ከዚያ በላይ ቁጥሮች ሊኖረው ይገባል።"</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"ትክክለኛውን የPUK ኮድ እንደገና ያስገቡ። ተደጋጋሚ ሙከራዎች ሲም ካርዱን እስከመጨረሻው ያሰናክሉታል።"</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"ፒን ኮዶች አይገጣጠሙም"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"በጣም ብዙ የስርዓተ ጥለት ሙከራዎች"</string>
+    <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_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">%d</xliff:g> ጊዜ በትክክል አልተየቡም። \n\nበ<xliff:g id="NUMBER_1">%d</xliff:g> ሰኮንዶች ውስጥ እንደገና ይሞክሩ።"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"የይለፍ ቃልዎን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ ትክክል ባልሆነ መንገድ ተይበዋል።\n\nበ<xliff:g id="NUMBER_1">%d</xliff:g> ሰኮንዶች ውስጥ እንደገና ይሞክሩ።"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"የመክፈቻ ስርዓተ ጥለትዎን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ በትክክል አልሳሉትም። \n\n ከ<xliff:g id="NUMBER_1">%d</xliff:g> ሰከንዶች በኋላ እንደገና ይሞክሩ።"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"ጡባዊ ቱኮውን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ ትክክል ባልሆነ መንገድ ለመክፈት ሞክረዋል። ከ<xliff:g id="NUMBER_1">%d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ ጡባዊ ቱኮው በፋብሪካ ነባሪ ቅንብር ዳግም ይጀመርና ሁሉም የተጠቃሚ ውሂብ ይጠፋል።"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"ስልኩን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ ትክክል ባልሆነ መንገድ ለመክፈት ሞክረዋል። ከ<xliff:g id="NUMBER_1">%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="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">%d</xliff:g> ጊዜ በትክክል አልሳሉትም። ከ<xliff:g id="NUMBER_1">%d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ የኢሜይል መለያ ተጠቅመው ጡባዊ ቱኮዎን እንዲከፍቱ ይጠየቃሉ።\n\n ከ<xliff:g id="NUMBER_2">%d</xliff:g> ከሰከንዶች በኋላ እንደገና ይሞክሩ።"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"የመክፈቻ ስርዓተ ጥለቱን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ በትክክል አልሳሉትም። ከ<xliff:g id="NUMBER_1">%d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ የኢሜይል መለያ ተጠቅመው ስልክዎን እንዲከፍቱ ይጠየቃሉ።\n\nእባክዎ ከ<xliff:g id="NUMBER_2">%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="keyguard_transport_prev_description" msgid="8229108430245669854">"የቀዳሚ ትራክ አዝራር"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"የቀጣይ ትራክ አዝራር"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"ለአፍታ አቁም አዝራር"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"የአጫውት አዝራር"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"አቁም አዝራር"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"ከአገልግሎት መስጫ ክልል ውጪ።"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-ar/activitystrings.xml b/packages/Keyguard/res/values-ar/activitystrings.xml
new file mode 100644
index 0000000..f77d8f00
--- /dev/null
+++ b/packages/Keyguard/res/values-ar/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"بدون تأمين"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"رقم التعريف الشخصي"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"كلمة المرور"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"نقش"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"رقم التعريف الشخصي لبطاقة SIM"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"رمز PUK لبطاقة SIM"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"جارٍ اختيار أداة..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-ar/strings.xml b/packages/Keyguard/res/values-ar/strings.xml
new file mode 100644
index 0000000..bcfe7db
--- /dev/null
+++ b/packages/Keyguard/res/values-ar/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"اكتب رمز رقم التعريف الشخصي"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"اكتب رمز PUK ورمز رقم التعريف الشخصي الجديد"</string>
+    <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="7858547464982981384"><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="faceunlock_multiple_failures" msgid="754137583022792429">"تم تجاوز الحد الأقصى لعدد محاولات تأمين الجهاز بالوجه"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"تم الشحن"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"جارٍ الشحن، <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"توصيل جهاز الشحن."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"اضغط على \"القائمة\" لإلغاء القفل."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"الشبكة مؤمّنة"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"ليست هناك بطاقة SIM"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"ليست هناك بطاقة SIM في الجهاز اللوحي."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"ليست هناك بطاقة SIM في الهاتف."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"أدخل بطاقة SIM."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"بطاقة SIM مفقودة أو غير قابلة للقراءة. أدخل بطاقة SIM."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"بطاقة SIM غير قابلة للاستخدام."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"تم تعطيل بطاقة SIM بشكل دائم.\n اتصل بمقدم خدمة اللاسلكي للحصول على بطاقة SIM أخرى."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"بطاقة SIM مؤمّنة."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"بطاقة SIM مؤمّنة بكود PUK."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"جارٍ إلغاء تأمين بطاقة SIM…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. الأداة %2$d من %3$d."</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_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>
+    <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_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="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"زر المقطع الصوتي السابق"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"زر المقطع الصوتي التالي"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"زر الإيقاف المؤقت"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"زر التشغيل"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"زر الإيقاف"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ب ت ث"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</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">"العالي"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"إلغاء تأمين"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"الكاميرا"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"صامت"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"تشغيل الصوت"</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_down" msgid="5087739728639014595">"تمرير لأسفل لـ <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="description_direction_right" msgid="8034433242579600980">"تمرير لليمين لـ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"المستخدم الحالي <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"الاتصال بالطوارئ"</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_too_many_failed_attempts_countdown" msgid="6358110221603297548">"حاول مرة أخرى خلال <xliff:g id="NUMBER">%d</xliff:g> ثانية."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"ارسم نقشك"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"أدخل رقم التعريف الشخصي لبطاقة SIM"</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_invalid_sim_puk_hint" msgid="7553388325654369575">"يجب أن يتضمن رمز PUK‏ 8 أرقام أو أكثر."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"أعد إدخال رمز PUK الصحيح. وستؤدي المحاولات المتكررة إلى تعطيل بطاقة SIM نهائيًا."</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_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">%d</xliff:g> مرة. \n\nأعد المحاولة خلال <xliff:g id="NUMBER_1">%d</xliff:g> ثانية."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"لقد كتبت كلمة المرور بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. \n\nأعد المحاولة خلال <xliff:g id="NUMBER_1">%d</xliff:g> ثانية."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"لقد رسمت نقش إلغاء التأمين بطريقة غير صحيحة <xliff:g id="NUMBER_0">%d</xliff:g> مرة. \n\nأعد المحاولة خلال <xliff:g id="NUMBER_1">%d</xliff:g> ثانية."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"لقد حاولت إلغاء تأمين الجهاز اللوحي بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة الأخرى، ستتم إعادة تعيين الجهاز اللوحي على الإعدادات الافتراضية للمصنع وسيتم فقد جميع بيانات المستخدم."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"لقد حاولت إلغاء تأمين الهاتف بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة الأخرى، ستطالَب بإلغاء تأمين الجهاز اللوحي باستخدام معلومات حساب بريد إلكتروني.\n\n أعد المحاولة خلال <xliff:g id="NUMBER_2">%d</xliff:g> ثانية."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"لقد رسمت نقش إلغاء التأمين بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة الأخرى، ستُطالب بإلغاء تأمين الهاتف باستخدام حساب بريد إلكتروني لإلغاء تأمين الهاتف.\n\n أعد المحاولة خلال <xliff:g id="NUMBER_2">%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="keyguard_transport_prev_description" msgid="8229108430245669854">"زر المقطع الصوتي السابق"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"زر المقطع الصوتي التالي"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"زر الإيقاف المؤقت"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"زر التشغيل"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"زر الإيقاف"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"لا تتوفر خدمة"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-be/activitystrings.xml b/packages/Keyguard/res/values-be/activitystrings.xml
new file mode 100644
index 0000000..ccefe40
--- /dev/null
+++ b/packages/Keyguard/res/values-be/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Аховы няма"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN-код"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Пароль"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Шаблон"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"PIN-код SIM-карты"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"PUK-код SIM-карты"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Выбар вiджэта..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-be/strings.xml b/packages/Keyguard/res/values-be/strings.xml
new file mode 100644
index 0000000..81020a0
--- /dev/null
+++ b/packages/Keyguard/res/values-be/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Увядзіце PIN-код"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Увядзіце PUK-код і новы PIN-код"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Новы PIN-код"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><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">"Каб разблакаваць, увядзіце PIN-код"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Няправільны PIN-код."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Каб разблакаваць, націсніце \"Меню\", затым 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Перавышана максімальная колькасць спроб разблакоўкі праз Фэйскантроль"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Зараджаны"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Зарадка, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Падключыце зарадную прыладу."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Націсніце кнопку \"Меню\", каб разблакіраваць."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Сетка заблакiраваная"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Няма SIM-карты"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"У планшэце няма SIM-карты."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"У тэлефоне няма SIM-карты."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Устаўце SIM-карту."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM-карта адсутнічае ці не чытаецца. Устаўце SIM-карту."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"SIM-карту немагчыма выкарыстоўваць."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Ваша SIM-карта была адключана назаўсёды.\n Звяжыцеся з аператарам бесправадной сувязі, каб атрымаць іншую SIM-карту."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM-карта заблакiраваная."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM-карта заблакiравана PUK-кодам."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Разблакiраванне SIM-карты..."</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. ВIджэт %2$d з %3$d."</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_widget" msgid="6527131039741808240">"Віджэт <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Селектар карыстальнiка"</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_slide_unlock" msgid="2959928478764697254">"Разблакiроўка слайда."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Узор разблакiроўкі."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Фэйскантроль"</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"PIN-код разблакiроўкі."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Пароль разблакiроўкі."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Вобласць узора."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Вобласць слайда."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Кнопка папярэдняй кампазiцыі"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Кнопка наступнай кампазiцыі"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Кнопка паўзы"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Кнопка прайгравання"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Кнопка спынення"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"Alt"</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_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Разблакаваць"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Ціхі рэжым"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Гук уключаны"</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_down" msgid="5087739728639014595">"Правядзіце пальцам уніз, каб атрымаць <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="description_direction_right" msgid="8034433242579600980">"Правядзіце пальцам управа, каб атрымаць <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Бягучы карыстальнік <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Экстранны выклік"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Забылі ключ"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Няправільна ключ"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Няправiльны пароль"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Няправільны PIN-код"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Паўтарыце спробу праз <xliff:g id="NUMBER">%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>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Увядзіце пароль"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM-карта зараз адключана. Увядзіце PUK-код, каб працягнуць. Звяжыцеся са сваiм аператарам, каб атрымаць дадатковую iнфармацыю."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Увядзіце жаданы PIN-код"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Пацвердзіце жадан PIN-код"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Разблакiроўка SIM-карты..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Няправільны PIN-код."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Увядзіце PIN-код, які змяшчае ад 4 да 8 лічбаў."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK-код павінен утрымлiваць 8 лiчбаў і больш."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Паўторна увядзіце правільны PUK-код. Неаднаразовыя спробы назаўжды адключаць SIM-карту."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-коды не супадаюць"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Занадта шмат спроб паўтарыць шаблон!"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Каб разблакiраваць, увайдзіце ў свой уліковы запіс 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">"Увайсцi"</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">"Праверка ўлiковага запiсу..."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Вы няправільна ўвялі PIN-код пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. \n\nПаўтарыце спробу праз <xliff:g id="NUMBER_1">%d</xliff:g> с."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Вы няправільна ўвялі пароль пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. \n\nПаўтарыце спробу праз <xliff:g id="NUMBER_1">%d</xliff:g> с."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Вы няправільна ўвялі графічны ключ разблакiроўкi пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. \n\nПаўтарыце спробу праз <xliff:g id="NUMBER_1">%d</xliff:g> с."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Вы няправільна спрабавалі разблакiраваць планшэт некалькi разоў (<xliff:g id="NUMBER_0">%d</xliff:g>). Пасля яшчэ некалькiх спроб (<xliff:g id="NUMBER_1">%d</xliff:g>) ён будзе скінуты да заводскіх налад i карыстальнiцкiя дадзеныя будуць згубленыя."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Вы няправільна спрабавалі разблакiраваць планшэт некалькi разоў (<xliff:g id="NUMBER_0">%d</xliff:g>). Пасля яшчэ некалькiх спроб (<xliff:g id="NUMBER_1">%d</xliff:g>) ён будзе скінуты да завадскіх налад i карыстальнiцкiя дадзеныя будуць згубленыя."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Вы няправільна спрабавалі разблакiраваць планшэт некалькi разоў (<xliff:g id="NUMBER">%d</xliff:g>). Цяпер ён будзе скінуты да завадскіх налад."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Вы няправільна спрабавалі разблакiраваць тэлефон некалькi разоў (<xliff:g id="NUMBER">%d</xliff:g>). Цяпер ён будзе скінуты да завадскіх налад."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Вы няправільна ўвялі графічны ключ разблакiроўкi пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. Пасля яшчэ некалькiх няўдалых спроб (<xliff:g id="NUMBER_1">%d</xliff:g>) вам будзе прапанавана разблакiраваць тэлефон, увайшоўшы ў Google.\n\n Паўтарыце спробу праз <xliff:g id="NUMBER_2">%d</xliff:g> с."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Вы няправільна ўвялі графічны ключ разблакiроўкi пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. Пасля яшчэ некалькiх няўдалых спроб (<xliff:g id="NUMBER_1">%d</xliff:g>) вам будзе прапанавана разблакiраваць тэлефон, увайшоўшы ў Google.\n\n Паўтарыце спробу праз <xliff:g id="NUMBER_2">%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">"Выдалiць"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Кнопка папярэдняй кампазiцыі"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Кнопка наступнай кампазiцыі"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Кнопка паўзы"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Кнопка прайгравання"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Кнопка спынення"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Не абслугоўваецца."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-bg/activitystrings.xml b/packages/Keyguard/res/values-bg/activitystrings.xml
new file mode 100644
index 0000000..807bcf2
--- /dev/null
+++ b/packages/Keyguard/res/values-bg/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Без защита"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"ПИН код"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Парола"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Фигура"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"ПИН код за SIM карта"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"PUK код за SIM карта"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Избиране на приспособление..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-bg/strings.xml b/packages/Keyguard/res/values-bg/strings.xml
new file mode 100644
index 0000000..869ab7b
--- /dev/null
+++ b/packages/Keyguard/res/values-bg/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Въведете ПИН кода"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Въведете PUK и новия ПИН код"</string>
+    <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="7858547464982981384"><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="faceunlock_multiple_failures" msgid="754137583022792429">"Максималният брой опити за отключване с лице е надвишен"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Заредена"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Зарежда се, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Свържете зарядното си устройство."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Натиснете иконата за меню, за да отключите."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Мрежата е заключена"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Няма SIM карта"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"В таблета няма SIM карта."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"В телефона няма SIM карта."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Поставете SIM карта."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM картата липсва или е нечетима. Поставете SIM карта."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Неизползваема SIM карта."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"SIM картата ви е деактивирана за постоянно.\nЗа да получите друга, се свържете с доставчика на безжичната си услуга."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM картата е заключена."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM картата е заключена с PUK код."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SIM картата се отключва…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Приспособление %2$d от %3$d."</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_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>
+    <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_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="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Бутон за предишния запис"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Бутон за следващия запис"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Бутон за пауза"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Бутон за пускане"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Бутон за спиране"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"АБВ"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</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_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Отключване"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Тих режим"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Включване на звука"</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_down" msgid="5087739728639014595">"Плъзнете надолу за <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="description_direction_right" msgid="8034433242579600980">"Плъзнете надясно за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Текущ потребител <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Спешно обаждане"</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_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Опитайте отново след <xliff:g id="NUMBER">%d</xliff:g> секунди."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Начертайте фигурата си"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Въведете ПИН кода за SIM картата"</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">"Въведете ПИН код с четири до осем цифри."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK кодът трябва да е с 8 или повече цифри."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Въведете отново правилния PUK код. Многократните опити ще деактивират за постоянно SIM картата."</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_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">%d</xliff:g> пъти. \n\nОпитайте отново след <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Въведохте неправилно паролата си <xliff:g id="NUMBER_0">%d</xliff:g> пъти. \n\nОпитайте отново след <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%d</xliff:g> пъти. \n\nОпитайте отново след <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Направихте опит да отключите неправилно таблета <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдат възстановени стандартните му фабрични настройки и всички потребителски данни ще бъдат заличени."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Направихте опит да отключите неправилно телефона <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдете помолени да отключите таблета посредством имейл адрес.\n\n Опитайте отново след <xliff:g id="NUMBER_2">%d</xliff:g> секунди."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдете помолени да отключите телефона посредством имейл адрес.\n\n Опитайте отново след <xliff:g id="NUMBER_2">%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="keyguard_transport_prev_description" msgid="8229108430245669854">"Бутон за предишния запис"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Бутон за следващия запис"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Бутон за пауза"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Бутон за пускане"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Бутон за спиране"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Няма покритие."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-ca/activitystrings.xml b/packages/Keyguard/res/values-ca/activitystrings.xml
new file mode 100644
index 0000000..c18b9bb
--- /dev/null
+++ b/packages/Keyguard/res/values-ca/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"No hi ha seguretat"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Contrasenya"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Patró"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"PIN de la SIM"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"PUK de la SIM"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Tria un widget..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-ca/strings.xml b/packages/Keyguard/res/values-ca/strings.xml
new file mode 100644
index 0000000..4f97c6b
--- /dev/null
+++ b/packages/Keyguard/res/values-ca/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Introdueix el codi PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Introdueix el codi PUK i el codi PIN nou"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Codi PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Codi PIN nou"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Toca per introduir contrasenya"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Introdueix la contrasenya per desbloquejar"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Introdueix la contrasenya per desbloquejar"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Codi PIN incorrecte."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Per desbloquejar-lo, premeu Menú i després 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"S\'ha superat el nombre màxim d\'intents de desbloqueig facial"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Carregada"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"S\'està carregant, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Connecta el carregador."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Prem Menú per desbloquejar."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Xarxa bloquejada"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"No hi ha cap targeta SIM."</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"No hi ha cap targeta SIM a la tauleta."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"No hi ha cap targeta SIM al telèfon."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Insereix una targeta SIM."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"Falta la targeta SIM o no es pot llegir. Insereix-ne una."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Targeta SIM no utilitzable."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"La targeta SIM s\'ha desactivat permanentment.\n Contacta amb el teu proveïdor de serveis sense fil per obtenir-ne una altra."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"La targeta SIM està bloquejada."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"La targeta SIM està bloquejada pel PUK."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"S\'està desbloquejant la targeta SIM..."</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d de %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Afegeix un widget"</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Buit"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"S\'ha ampliat l\'àrea de desbloqueig."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"L\'àrea de desbloqueig està replegada."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget de <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Selector d\'usuaris"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Estat"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Càmera"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Controls multimèdia"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"S\'ha iniciat la reorganització del widget."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Ha finalitzat la reorganització del widget."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"S\'ha suprimit el widget de <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Amplia l\'àrea de desbloqueig."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Desbloqueig lliscant el dit"</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Desbloqueig mitjançant patró"</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Desbloqueig facial"</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Desbloqueig mitjançant PIN"</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Desbloqueig mitjançant contrasenya"</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Àrea de patró"</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Àrea per lliscar el dit"</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Botó de pista anterior"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Botó de pista següent"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Botó de pausa"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Botó de reproducció"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Botó de parada"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Cancel·la"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Suprimeix"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Fet"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Canvi de mode"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Maj"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Retorn"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Desbloqueja"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Càmera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Silenci"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Activa el so"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Cerca"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Fes lliscar el dit cap amunt per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Fes lliscar el dit cap avall per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Fes lliscar el dit cap a l\'esquerra per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Fes lliscar el dit cap a la dreta per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Usuari actual: <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Trucada d\'emergència"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Patró oblidat"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Patró incorrecte"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Contrasenya incorrecta"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN incorrecte"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Torna-ho a provar d\'aquí a <xliff:g id="NUMBER">%d</xliff:g> segons."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Dibuixa el patró"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Introdueix el PIN de la SIM"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Introdueix el PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Introdueix la contrasenya"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"La SIM està desactivada. Introdueix el codi PUK per continuar. Contacta amb l\'operador de telefonia mòbil per obtenir detalls."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Introdueix el codi PIN"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Confirma el codi PIN"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"S\'està desbloquejant la targeta SIM..."</string>
+    <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="7553388325654369575">"El codi PUK ha de tenir 8 números o més."</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_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>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Nom d\'usuari (correu electrònic)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Contrasenya"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Inicia la sessió"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nom d\'usuari o contrasenya no vàlids."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Has oblidat el teu nom d\'usuari o la contrasenya?\nVisita "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"S\'està comprovant el compte…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Has escrit malament el PIN <xliff:g id="NUMBER_0">%d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Has escrit malament la contrasenya <xliff:g id="NUMBER_0">%d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Has dibuixat el patró de desbloqueig de manera incorrecta <xliff:g id="NUMBER_0">%d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. D\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, la tauleta es restablirà a la configuració predeterminada de fàbrica i es perdran totes les dades dels usuaris."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. D\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, el telèfon es restablirà a la configuració predeterminada de fàbrica i es perdran totes les dades dels usuaris."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER">%d</xliff:g> vegades de manera incorrecta. Ara la tauleta es restablirà a la configuració predeterminada de fàbrica."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER">%d</xliff:g> vegades de manera incorrecta. Ara el telèfon es restablirà a la configuració predeterminada de fàbrica."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Després de <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, se\'t demanarà que desbloquegis la tauleta amb un compte de correu electrònic.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Després de <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, se\'t demanarà que desbloquegis el telèfon amb un compte de correu electrònic.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Elimina"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Botó de pista anterior"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Botó de pista següent"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Botó de pausa"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Botó de reproducció"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Botó de parada"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Sense servei."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-cs/activitystrings.xml b/packages/Keyguard/res/values-cs/activitystrings.xml
new file mode 100644
index 0000000..354176e
--- /dev/null
+++ b/packages/Keyguard/res/values-cs/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Žádné zabezpečení"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Heslo"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Gesto"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"PIN SIM karty"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"PUK SIM karty"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Zvolte widget..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-cs/strings.xml b/packages/Keyguard/res/values-cs/strings.xml
new file mode 100644
index 0000000..ec2833c
--- /dev/null
+++ b/packages/Keyguard/res/values-cs/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Zadejte kód PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Zadejte kód PUK a nový kód PIN."</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Kód PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Nový kód PIN"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Dotykem zadáte heslo"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Zadejte heslo pro odemknutí"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Zadejte kód PIN pro odemknutí"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Nesprávný kód PIN."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Chcete-li telefon odemknout, stiskněte Menu a poté 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Překročili jste maximální povolený počet pokusů o odemknutí obličejem."</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Nabito"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Nabíjení, <xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Připojte dobíjecí zařízení."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Telefon odemknete stisknutím tlačítka Menu."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Síť je blokována"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Není vložena SIM karta."</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"V tabletu není SIM karta."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"V telefonu není SIM karta."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Vložte SIM kartu."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM karta chybí nebo je nečitelná. Vložte SIM kartu."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Nepoužitelná SIM karta."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Vaše SIM karta byla natrvalo zablokována.\n Požádejte svého poskytovatele bezdrátových služeb o další SIM kartu."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM karta je zablokována."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM karta je zablokována pomocí kódu PUK."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Odblokování SIM karty…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d z %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Přidat widget"</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Prázdné"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Oblast odemknutí byla rozšířena."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Oblast odemknutí byla sbalena."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>"</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Výběr uživatele"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Stav"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Fotoaparát"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Ovládání médií"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Přeuspořádání widgetů bylo zahájeno."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Přeuspořádání widgetů bylo dokončeno."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> byl smazán."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Rozšířit oblast odemknutí"</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Odemknutí přejetím prstem."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Odemknutí gestem."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Odemknutí obličejem."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Odemknutí kódem PIN."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Odemknutí heslem."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Oblast pro zadání bezpečnostního gesta."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Oblast pro přejetí prstem."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Tlačítko Předchozí stopa"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Tlačítko Další stopa"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Tlačítko Pozastavit"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Tlačítko Přehrát"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Tlačítko Zastavit"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"Alt"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Zrušit"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Smazat"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Hotovo"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Změna režimu"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Odemknout"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Fotoaparát"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Tichý"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Zapnout zvuk"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Vyhledávání"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Přejeďte prstem nahoru: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Přejeďte prstem dolů: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Přejeďte prstem doleva: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Přejeďte prstem doprava: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
+    <string name="user_switched" msgid="3768006783166984410">"Aktuální uživatel je <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Tísňové volání"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Zapomenuté gesto"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Nesprávné gesto"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Nesprávné heslo"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Nesprávný kód PIN"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Zkuste to znovu za <xliff:g id="NUMBER">%d</xliff:g> s."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Nakreslete gesto"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Zadejte kód PIN SIM karty"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Zadejte kód PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Zadejte heslo"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM karta byla deaktivována. Chcete-li pokračovat, je třeba zadat kód PUK. Podrobné informace získáte od operátora."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Zadejte požadovaný kód PIN."</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Potvrďte požadovaný kód PIN."</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Odblokování SIM karty..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Nesprávný kód PIN."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Zadejte kód PIN o délce 4–8 číslic."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Minimální délka kódu PUK je 8 číslic."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Znovu zadejte správný kód PUK. Opakovanými pokusy SIM kartu trvale deaktivujete."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Kódy PIN se neshodují."</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Příliš mnoho pokusů o nakreslení gesta"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Chcete-li telefon odemknout, přihlaste se pomocí svého účtu Google."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Uživatelské jméno (e-mail)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Heslo"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Přihlásit se"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Neplatné uživatelské jméno nebo heslo."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Zapomněli jste uživatelské jméno nebo heslo?\nPřejděte na stránku "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Kontrola účtu…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste zadali nesprávný kód PIN. \n\nZkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně zadali heslo. \n\nZkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste zadali nesprávné bezpečnostní gesto. \n\nZkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Již jste se <xliff:g id="NUMBER_0">%d</xliff:g>krát pokusili odemknout tablet nesprávným způsobem. Po <xliff:g id="NUMBER_1">%d</xliff:g> dalších neúspěšných pokusech se v tabletu obnoví tovární nastavení a veškerá uživatelská data budou ztracena."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Již jste se <xliff:g id="NUMBER_0">%d</xliff:g>krát pokusili odemknout telefon nesprávným způsobem. Po <xliff:g id="NUMBER_1">%d</xliff:g> dalších neúspěšných pokusech se v telefonu obnoví tovární nastavení a veškerá uživatelská data budou ztracena."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Již jste se <xliff:g id="NUMBER">%d</xliff:g>krát pokusili odemknout tablet nesprávným způsobem. V tabletu se nyní obnoví výchozí tovární nastavení."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Již jste se <xliff:g id="NUMBER">%d</xliff:g>krát pokusili odemknout telefon nesprávným způsobem. V telefonu se nyní obnoví výchozí tovární nastavení."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně nakreslili své heslo odemknutí. Po <xliff:g id="NUMBER_1">%d</xliff:g>dalších neúspěšných pokusech budete požádáni o odemčení tabletu pomocí e-mailového účtu.\n\n Zkuste to znovu za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně nakreslili své heslo odemknutí. Po <xliff:g id="NUMBER_1">%d</xliff:g> dalších neúspěšných pokusech budete požádáni o odemčení telefonu pomocí e-mailového účtu.\n\n Zkuste to znovu za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Odebrat"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Tlačítko Předchozí stopa"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Tlačítko Další stopa"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Tlačítko Pozastavit"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Tlačítko Přehrát"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Tlačítko Zastavit"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Žádný signál."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-da/activitystrings.xml b/packages/Keyguard/res/values-da/activitystrings.xml
new file mode 100644
index 0000000..af07ba5
--- /dev/null
+++ b/packages/Keyguard/res/values-da/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Ingen sikkerhed"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"Pinkode"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Adgangskode"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Mønster"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"Pinkode til SIM-kort"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"PUK-kode til SIM-kort"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Vælg widget..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-da/strings.xml b/packages/Keyguard/res/values-da/strings.xml
new file mode 100644
index 0000000..cfc7464
--- /dev/null
+++ b/packages/Keyguard/res/values-da/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Indtast pinkode"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Indtast PUK- og pinkode"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-kode"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Ny pinkode"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Tryk for at angive adgangskode"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Indtast adgangskoden for at låse op"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Indtast pinkode for at låse op"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Forkert pinkode."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Tryk på Menu og dernæst på 0 for at låse op."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Det maksimale antal forsøg på at bruge Ansigtslås er overskredet"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Opladet"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Oplader, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Tilslut din oplader."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Tryk på Menu for at låse op."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Netværket er låst"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Intet SIM-kort"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Der er ikke noget SIM-kort i tabletten."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Der er ikke noget SIM-kort i telefonen."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Indsæt et SIM-kort."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM-kortet mangler eller kan ikke læses. Indsæt et SIM-kort."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Ubrugeligt SIM-kort."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Dit SIM-kort er blevet permanent deaktiveret.\nKontakt din tjenesteudbyder for at få et nyt SIM-kort."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM-kortet er låst."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM-kort er låst med PUK-koden."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SIM-kortet låses op…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d af %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Tilføj widget."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tom"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Oplåsningsområdet er udvidet."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Oplåsningsområdet er skjult."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget til <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+    <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="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>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Udvid oplåsningsområdet."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Lås op ved at stryge."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Lås op med mønster."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Lås op med ansigt."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Lås op med pinkode."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Lås op med adgangskode."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Mønsterområde."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Strygeområde."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Knap til forrige nummer"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Knap til næste nummer"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Pause-knap"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Afspil-knap"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Stop-knap"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Annuller"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Slet"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Udført"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Ændring af tilstand"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Angiv"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Lås op"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Lydløs"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Lyd slået til"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Søgning"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Glid op for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Glid ned for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Glid til venstre for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Glid til højre for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Nuværende bruger <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Nødopkald"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Glemt mønster"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Forkert mønster"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Forkert adgangskode"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Forkert pinkode"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Prøv igen om <xliff:g id="NUMBER">%d</xliff:g> sekunder."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Tegn dit mønster"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Indtast pinkode til SIM"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Indtast pinkode"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Angiv adgangskode"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM-kortet er nu deaktiveret. Indtast PUK-koden for at fortsætte. Kontakt mobiloperatøren for at få flere oplysninger."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Indtast den ønskede pinkode"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Bekræft den ønskede pinkode"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM-kortet låses op…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Forkert pinkode."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Indtast en pinkode på mellem 4 og 8 tal."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK-koden skal være på 8 tal eller mere."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Indtast den korrekte PUK-kode. Gentagne forsøg vil permanent deaktivere SIM-kortet."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Pinkoderne stemmer ikke overens"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"For mange forsøg på at tegne mønstret korrekt"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Lås op ved at logge ind med din Google-konto."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Brugernavn (e-mail)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Adgangskode"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Log ind"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Ugyldigt brugernavn eller ugyldig adgangskode."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Har du glemt dit brugernavn eller din adgangskode?\nGå til "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Kontoen kontrolleres…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Du har indtastet en forkert pinkode <xliff:g id="NUMBER_0">%d</xliff:g> gange. \n\nPrøv igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Du har indtastet din adgangskode forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. \n\nPrøv igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. \n\nPrøv igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Du har forsøgt at låse tabletten op forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> yderligere mislykkede forsøg nulstilles tabletten til fabriksindstillingerne, og alle brugerdata mistes."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Du har forsøgt at låse telefonen op forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> yderligere mislykkede forsøg, nulstilles telefonen til fabriksindstillingerne, og alle brugerdata mistes."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Du har forsøgt at låse tabletten op forkert <xliff:g id="NUMBER">%d</xliff:g> gange. Tabletten nulstilles til fabriksindstillingerne."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Du har forsøgt at låse telefonen op forkert <xliff:g id="NUMBER">%d</xliff:g> gange. Telefonen nulstilles til fabriksindstillingerne."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> yderligere mislykkede forsøg vil du blive bedt om at låse din tablet op ved hjælp af en e-mailkonto\n\n Prøv igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> yderligere mislykkede forsøg til vil du blive bedt om at låse din telefon op ved hjælp af en e-mailkonto.\n\n Prøv igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Fjern"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Knap til forrige nummer"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Knap til næste nummer"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Pause-knap"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Afspil-knap"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Stop-knap"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Ingen dækning."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-de/activitystrings.xml b/packages/Keyguard/res/values-de/activitystrings.xml
new file mode 100644
index 0000000..d8e9272
--- /dev/null
+++ b/packages/Keyguard/res/values-de/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Keine Sicherheit"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Passwort"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Muster"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"PIN für SIM-Karte"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"PUK für SIM-Karte"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Widget auswählen..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-de/strings.xml b/packages/Keyguard/res/values-de/strings.xml
new file mode 100644
index 0000000..85d1a4f9
--- /dev/null
+++ b/packages/Keyguard/res/values-de/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN-Code eingeben"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK und neuen PIN-Code eingeben"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-Code"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Neuer PIN-Code"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Zur Passworteingabe berühren"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Passwort zum Entsperren eingeben"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"PIN zum Entsperren eingeben"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Falscher PIN-Code"</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Drücken Sie zum Entsperren die Menütaste und dann auf \"0\"."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Die maximal zulässige Anzahl an Face Unlock-Versuchen wurde überschritten."</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Aufgeladen"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Akku wird aufgeladen (<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>)"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Bitte Ladegerät anschließen"</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Zum Entsperren die Menütaste drücken"</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Netzwerk gesperrt"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Keine SIM-Karte"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Keine SIM-Karte im Tablet"</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Keine SIM-Karte im Telefon"</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Legen Sie eine SIM-Karte ein."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM-Karte fehlt oder ist nicht lesbar. Bitte legen Sie eine SIM-Karte ein."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"SIM-Karte unbrauchbar"</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Ihre SIM-Karte wurde dauerhaft deaktiviert.\n Wenden Sie sich an Ihren Mobilfunkanbieter, um eine andere SIM-Karte zu erhalten."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM-Karte ist gesperrt."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM-Karte ist gesperrt. PUK-Eingabe erforderlich."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SIM-Karte wird entsperrt…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d von %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Widget hinzufügen"</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Leer"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Entsperr-Bereich maximiert"</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Entsperr-Bereich mminimiert"</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>"</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Nutzerauswahl"</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">"Mediensteuerelemente"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Neuordnung der Widgets gestartet"</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Neuordnung der Widgets abgeschlossen"</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> gelöscht"</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Entsperr-Bereich maximieren"</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Entsperrung mit Fingerbewegung"</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Entsperrung mit Muster"</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Face Unlock"</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Entsperrung mit PIN"</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Entsperrung mit Passwort"</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Bereich für Muster"</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Bereich für Fingerbewegung"</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Schaltfläche für vorherigen Titel"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Schaltfläche für nächsten Titel"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Schaltfläche für Pause"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Schaltfläche für Wiedergabe"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Schaltfläche für Stopp"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Abbrechen"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Löschen"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Fertig"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Modusänderung"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Umschalttaste"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Eingabetaste"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Entsperren"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Lautlos"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Ton ein"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Suche"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Zum <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach oben schieben"</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Zum <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach unten schieben"</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Zum <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach links schieben"</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Zum <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach rechts schieben"</string>
+    <string name="user_switched" msgid="3768006783166984410">"Aktueller Nutzer <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Notruf"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Muster vergessen"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Falsches Muster"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Falsches Passwort"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Falsche PIN"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Versuchen Sie es in <xliff:g id="NUMBER">%d</xliff:g> Sekunden erneut."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Muster zeichnen"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM-PIN eingeben"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN eingeben"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Passwort eingeben"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"Die SIM-Karte ist jetzt deaktiviert. Geben Sie den PUK-Code ein, um fortzufahren. Weitere Informationen erhalten Sie von Ihrem Mobilfunkanbieter."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Gewünschten PIN-Code eingeben"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Gewünschten PIN-Code bestätigen"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM-Karte wird entsperrt…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Falscher PIN-Code"</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Geben Sie eine 4- bis 8-stellige PIN ein."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Der PUK-Code muss mindestens 8 Ziffern betragen."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Geben Sie den richtigen PUK-Code ein. Bei wiederholten Versuchen wird die SIM-Karte dauerhaft deaktiviert."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-Codes stimmen nicht überein"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Zu viele Musterversuche"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Melden Sie sich zum Entsperren mit Ihrem Google-Konto an."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Nutzername (E-Mail)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Passwort"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Anmelden"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Ungültiger Nutzername oder ungültiges Passwort"</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Nutzernamen oder Passwort vergessen?\nBesuchen Sie "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Konto wird geprüft…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Sie haben Ihre PIN <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch eingegeben.\n\nVersuchen Sie es in <xliff:g id="NUMBER_1">%d</xliff:g> Sekunden erneut."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Sie haben Ihr Passwort <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch eingegeben.\n\nVersuchen Sie es in <xliff:g id="NUMBER_1">%d</xliff:g> Sekunden erneut."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch gezeichnet. \n\nVersuchen Sie es in <xliff:g id="NUMBER_1">%d</xliff:g> Sekunden erneut."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Sie haben <xliff:g id="NUMBER_0">%d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Nach <xliff:g id="NUMBER_1">%d</xliff:g> weiteren erfolglosen Versuchen wird das Tablet auf die Werkseinstellungen zurückgesetzt und alle Nutzerdaten gehen verloren."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Sie haben <xliff:g id="NUMBER_0">%d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Nach <xliff:g id="NUMBER_1">%d</xliff:g> weiteren erfolglosen Versuchen wird das Telefon auf die Werkseinstellungen zurückgesetzt und alle Nutzerdaten gehen verloren."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Sie haben <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Das Tablet wird nun auf die Werkseinstellungen zurückgesetzt."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Sie haben <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Das Telefon wird nun auf die Werkseinstellungen zurückgesetzt."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%d</xliff:g> weiteren erfolglosen Versuchen werden Sie aufgefordert, Ihr Tablet mithilfe eines E-Mail-Kontos zu entsperren.\n\n Versuchen Sie es in <xliff:g id="NUMBER_2">%d</xliff:g> Sekunden erneut."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%d</xliff:g> weiteren erfolglosen Versuchen werden Sie aufgefordert, Ihr Telefon mithilfe eines E-Mail-Kontos zu entsperren.\n\n Versuchen Sie es in <xliff:g id="NUMBER_2">%d</xliff:g> Sekunden erneut."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Entfernen"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Schaltfläche für vorherigen Titel"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Schaltfläche für nächsten Titel"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Schaltfläche für Pause"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Schaltfläche für Wiedergabe"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Schaltfläche für Stopp"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Kein Dienst"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-el/activitystrings.xml b/packages/Keyguard/res/values-el/activitystrings.xml
new file mode 100644
index 0000000..3941f4f
--- /dev/null
+++ b/packages/Keyguard/res/values-el/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Χωρίς ασφάλεια"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Κωδικός πρόσβασης"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Μοτίβο"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"Κωδικός PIN κάρτας SIM"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"Κωδικός PUK κάρτας SIM"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Επιλογή γραφικού στοιχείου…"</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-el/strings.xml b/packages/Keyguard/res/values-el/strings.xml
new file mode 100644
index 0000000..e86f24d
--- /dev/null
+++ b/packages/Keyguard/res/values-el/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Πληκτρολογήστε τον κωδικό αριθμό PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Πληκτρολογήστε τον κωδικό PUK και τον νέο κωδικό PIN"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Κωδικός PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Νέος κωδικός PIN"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><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">"Πληκτρολογήστε τον αριθμό PIN για ξεκλείδωμα"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Εσφαλμένος κωδικός PIN."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Για ξεκλείδωμα, πατήστε το πλήκτρο Menu και, στη συνέχεια, το πλήκτρο 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Έγινε υπέρβαση του μέγιστου αριθμού προσπαθειών Face Unlock"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Φορτίστηκε"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Φόρτιση, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Συνδέστε τον φορτιστή."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Πατήστε \"Μενού\" για ξεκλείδωμα."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Το δίκτυο κλειδώθηκε"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Δεν υπάρχει κάρτα SIM"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Δεν υπάρχει κάρτα SIM στο tablet."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Δεν υπάρχει κάρτα SIM στο τηλέφωνο."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Τοποθετήστε μια κάρτα SIM."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"Η κάρτα SIM δεν υπάρχει ή δεν είναι δυνατή η ανάγνωσή της. Τοποθετήστε μια κάρτα SIM."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Η κάρτα SIM δεν μπορεί να χρησιμοποιηθεί."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Η κάρτα SIM έχει απενεργοποιηθεί οριστικά.\n Επικοινωνήστε με τον παροχέα υπηρεσιών ασύρματου δικτύου για να λάβετε μια νέα κάρτα SIM."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"Η κάρτα SIM είναι κλειδωμένη."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"Η κάρτα SIM είναι κλειδωμένη με κωδικό PUK."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Ξεκλείδωμα κάρτας SIM…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Γραφικό στοιχείο %2$d από %3$d."</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_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>
+    <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_slide_unlock" msgid="2959928478764697254">"Ξεκλείδωμα ολίσθησης."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Ξεκλείδωμα μοτίβου."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Face unlock."</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="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Κουμπί προηγούμενου κομματιού"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Κουμπί επόμενου κομματιού"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Κουμπί παύσης"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Κουμπί αναπαραγωγής"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Κουμπί διακοπής"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ΑΒΓ"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</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_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Ξεκλείδωμα"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Φωτογραφική μηχανή"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Αθόρυβο"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Ενεργοποίηση ήχου"</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_down" msgid="5087739728639014595">"Κύλιση προς τα κάτω για <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="description_direction_right" msgid="8034433242579600980">"Κύλιση προς τα δεξιά για <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Τρέχων χρήστης <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Κλήσεις επείγουσας ανάγκης"</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">"Εσφαλμένος κωδικός PIN"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Δοκιμάστε ξανά σε <xliff:g id="NUMBER">%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>
+    <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">"Εισαγάγετε τον απαιτούμενο κωδικό PIN"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Επιβεβαιώστε τον απαιτούμενο κωδικό PIN"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Ξεκλείδωμα κάρτας SIM..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Εσφαλμένος κωδικός PIN."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Πληκτρολογήστε έναν αριθμό PIN που να αποτελείται από 4 έως 8 αριθμούς."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Ο κωδικός PUK θα πρέπει να περιέχει τουλάχιστον 8 αριθμούς."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Εισαγάγετε ξανά τον κωδικό PUK. Οι επαναλαμβανόμενες προσπάθειες θα απενεργοποιήσουν οριστικά την κάρτα SIM."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Δεν υπάρχει αντιστοιχία των κωδικών PIN"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Πάρα πολλές προσπάθειες μοτίβου"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Για ξεκλείδωμα, συνδεθείτε με τον λογαριασμό σας Google."</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"Έλεγχος λογαριασμού…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Έχετε πληκτρολογήσει εσφαλμένα τον κωδικό σας PIN <xliff:g id="NUMBER_0">%d</xliff:g> φορές. \n\nΔοκιμάστε ξανά σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλεπτα."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Έχετε πληκτρολογήσει τον κωδικό πρόσβασης εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. \n\nΔοκιμάστε ξανά σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλεπτα."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Σχεδιάσατε εσφαλμένα το μοτίβο ξεκλειδώματος <xliff:g id="NUMBER_0">%d</xliff:g> φορές. \n\nΔοκιμάστε ξανά σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλετπα."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Προσπαθήσατε να ξεκλειδώσετε εσφαλμένα το tablet <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> προσπάθειες, το tablet θα επαναφερθεί στις εργοστασιακές ρυθμίσεις και όλα τα δεδομένα χρήστη θα χαθούν."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Προσπαθήσατε να ξεκλειδώσετε εσφαλμένα το τηλέφωνο <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> προσπάθειες, το τηλέφωνο θα επαναφερθεί στις εργοστασιακές ρυθμίσεις και όλα τα δεδομένα χρήστη θα χαθούν."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Προσπαθήσατε να ξεκλειδώσετε εσφαλμένα το tablet <xliff:g id="NUMBER">%d</xliff:g> φορές. Το tablet θα επαναφερθεί στις εργοστασιακές ρυθμίσεις."</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">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> ανεπιτυχείς προσπάθειες ακόμη, θα σας ζητηθεί να ξεκλειδώσετε το tablet σας με τη χρήση ενός λογαριασμού ηλεκτρονικού ταχυδρομείου.\n\n Δοκιμάστε να συνδεθείτε ξανά σε <xliff:g id="NUMBER_2">%d</xliff:g> δευτερόλεπτα."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Σχεδιάσατε το μοτίβο ξεκλειδώματος εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> ανεπιτυχείς προσπάθειες ακόμη, θα σας ζητηθεί να ξεκλειδώσετε το τηλέφωνό σας με τη χρήση ενός λογαριασμού ηλεκτρονικού ταχυδρομείου.\n\n Δοκιμάστε ξανά σε <xliff:g id="NUMBER_2">%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="keyguard_transport_prev_description" msgid="8229108430245669854">"Κουμπί προηγούμενου κομματιού"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Κουμπί επόμενου κομματιού"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Κουμπί παύσης"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Κουμπί αναπαραγωγής"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Κουμπί διακοπής"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Καμία υπηρεσία."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-en-rGB/activitystrings.xml b/packages/Keyguard/res/values-en-rGB/activitystrings.xml
new file mode 100644
index 0000000..88e806e
--- /dev/null
+++ b/packages/Keyguard/res/values-en-rGB/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"No security"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Password"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Pattern"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"SIM PIN"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"SIM PUK"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Choose widget..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-en-rGB/strings.xml b/packages/Keyguard/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..967c3fa
--- /dev/null
+++ b/packages/Keyguard/res/values-en-rGB/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Type PIN code"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Type PUK and new PIN code"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK code"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"New PIN Code"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Touch to type password"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Type password to unlock"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Type PIN to unlock"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Incorrect PIN code."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"To unlock, press Menu, then 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Maximum Face Unlock attempts exceeded"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Charged"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Charging, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Connect your charger."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Press Menu to unlock."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Network locked"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"No SIM card"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"No SIM card in tablet."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"No SIM card in phone."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Insert a SIM card."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"The SIM card is missing or not readable. Insert a SIM card."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Unusable SIM card."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Your SIM card has been permanently disabled.\n Contact your wireless service provider for another SIM card."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM card is locked."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM card is PUK-locked."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Unlocking SIM card…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d of %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Add widget"</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Empty"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Unlock area expanded."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Unlock area collapsed."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> widget."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"User selector"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Status"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Camera"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Media controls"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Widget reordering started."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Widget reordering ended."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> deleted."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Expand unlock area."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Slide unlock."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Pattern unlock."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Face unlock."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Pin unlock."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Password unlock."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Pattern area."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Slide area."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Previous track button"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Next track button"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Pause button"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Play button"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Stop button"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Cancel"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Done"</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>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Unlock"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Camera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Silent"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Sound on"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Search"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Slide up for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Slide down for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Slide left for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Slide right for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Emergency call"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Forgot Pattern"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Wrong Pattern"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Wrong Password"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Wrong PIN"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Try again in <xliff:g id="NUMBER">%d</xliff:g> seconds."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Draw your pattern"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Enter SIM PIN"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Enter PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Enter Password"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM is now disabled. Enter PUK code to continue. Contact carrier for details."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Enter desired PIN code"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Confirm desired PIN code"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Unlocking SIM card…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Incorrect PIN code."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Type a PIN that is 4 to 8 numbers."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK code should be 8 numbers or more."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Re-enter the correct PUK code. Repeated attempts will permanently disable the SIM."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN codes do not match"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Too many pattern attempts"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"To unlock, sign in with your Google account."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Username (email)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Password"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Sign in"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Invalid username or password."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Forgot your username or password?\nVisit "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Checking account…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the tablet will be reset to factory default and all user data will be lost."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the phone will be reset to factory default and all user data will be lost."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. The tablet will now be reset to factory default."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The phone will now be reset to factory default."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Remove"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Previous track button"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Next track button"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Pause button"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Play button"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Stop button"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"No service."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-en-rIN/strings.xml b/packages/Keyguard/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..967c3fa
--- /dev/null
+++ b/packages/Keyguard/res/values-en-rIN/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Type PIN code"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Type PUK and new PIN code"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK code"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"New PIN Code"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Touch to type password"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Type password to unlock"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Type PIN to unlock"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Incorrect PIN code."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"To unlock, press Menu, then 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Maximum Face Unlock attempts exceeded"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Charged"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Charging, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Connect your charger."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Press Menu to unlock."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Network locked"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"No SIM card"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"No SIM card in tablet."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"No SIM card in phone."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Insert a SIM card."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"The SIM card is missing or not readable. Insert a SIM card."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Unusable SIM card."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Your SIM card has been permanently disabled.\n Contact your wireless service provider for another SIM card."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM card is locked."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM card is PUK-locked."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Unlocking SIM card…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d of %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Add widget"</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Empty"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Unlock area expanded."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Unlock area collapsed."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> widget."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"User selector"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Status"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Camera"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Media controls"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Widget reordering started."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Widget reordering ended."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> deleted."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Expand unlock area."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Slide unlock."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Pattern unlock."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Face unlock."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Pin unlock."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Password unlock."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Pattern area."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Slide area."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Previous track button"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Next track button"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Pause button"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Play button"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Stop button"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Cancel"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Done"</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>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Unlock"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Camera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Silent"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Sound on"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Search"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Slide up for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Slide down for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Slide left for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Slide right for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Emergency call"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Forgot Pattern"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Wrong Pattern"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Wrong Password"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Wrong PIN"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Try again in <xliff:g id="NUMBER">%d</xliff:g> seconds."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Draw your pattern"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Enter SIM PIN"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Enter PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Enter Password"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM is now disabled. Enter PUK code to continue. Contact carrier for details."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Enter desired PIN code"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Confirm desired PIN code"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Unlocking SIM card…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Incorrect PIN code."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Type a PIN that is 4 to 8 numbers."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK code should be 8 numbers or more."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Re-enter the correct PUK code. Repeated attempts will permanently disable the SIM."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN codes do not match"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Too many pattern attempts"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"To unlock, sign in with your Google account."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Username (email)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Password"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Sign in"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Invalid username or password."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Forgot your username or password?\nVisit "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Checking account…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. \n\nTry again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the tablet will be reset to factory default and all user data will be lost."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the phone will be reset to factory default and all user data will be lost."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. The tablet will now be reset to factory default."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The phone will now be reset to factory default."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Remove"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Previous track button"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Next track button"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Pause button"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Play button"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Stop button"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"No service."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-es-rUS/activitystrings.xml b/packages/Keyguard/res/values-es-rUS/activitystrings.xml
new file mode 100644
index 0000000..20117c4
--- /dev/null
+++ b/packages/Keyguard/res/values-es-rUS/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Sin seguridad"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Contraseña"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Patrón"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"PIN de tarjeta SIM"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"PUK de tarjeta SIM"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Elegir widget..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-es-rUS/strings.xml b/packages/Keyguard/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..787581a
--- /dev/null
+++ b/packages/Keyguard/res/values-es-rUS/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Ingresa el código PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Escribe el código PUK y un nuevo código PIN."</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Código PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Nuevo código PIN"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Toca para ingresar la contraseña"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Ingresar contraseña para desbloquear"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Ingresa el 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, presiona el menú y luego 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Se superó el máximo de intentos permitido para el desbloqueo facial del dispositivo."</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Cargada"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Cargando (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Conecta tu cargador."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Presiona Menú para desbloquear."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Bloqueada para la red"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"No se insertó ninguna tarjeta SIM."</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"No se insertó ninguna tarjeta SIM en la tablet."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"No se insertó ninguna tarjeta SIM en el dispositivo."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Inserta una tarjeta SIM."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"Falta la tarjeta SIM o esta no se puede leer. Inserta una tarjeta SIM."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Tarjeta SIM inutilizable"</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Tu tarjeta SIM se inhabilitó de forma permanente.\n Comunícate con tu proveedor de servicios inalámbricos para obtener otra tarjeta SIM."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"La tarjeta SIM está bloqueada."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"La tarjeta SIM está bloqueada por código PUK."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Desbloqueando tarjeta SIM…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d de %3$d"</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Agregar widget"</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Vacío"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Área desbloqueada expandida."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"El área desbloqueada se contrajo."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> widget"</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Selector de usuarios"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Estado"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Cámara"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Controles de medios"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Se comenzaron a reordenar los widgets."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Se terminaron de reordenar los widgets."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> eliminado"</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Expandir el área desbloqueada"</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Desbloqueo por deslizamiento"</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Desbloqueo por patrón"</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Desbloqueo facial"</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Desbloqueo por PIN"</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Desbloqueo por contraseña"</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Área de patrón"</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Área de deslizamiento"</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Botón de pista anterior"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Botón de pista siguiente"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Botón de pausa"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Botón de reproducción"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Botón de detención"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Cancelar"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Eliminar"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Listo"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Cambio de modo"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Mayúscula"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Ingresar"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Desbloquear"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Cámara"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Silencioso"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Sonido activado"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Buscar"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Desliza el dedo hacia arriba para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Desliza el dedo hacia abajo para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Desliza el dedo hacia la izquierda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Desliza el dedo hacia la derecha para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Realizar llamada de emergencia"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"¿Olvidaste el patrón?"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Patrón incorrecto"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Contraseña incorrecta"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN incorrecto"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Vuelve a intentarlo en <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Dibuja tu patrón."</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Ingresa el PIN de la tarjeta SIM."</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Ingresa el PIN."</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Ingresa tu contraseña."</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"La tarjeta SIM está inhabilitada. Para continuar, ingresa el código PUK. Si quieres obtener más información, ponte en contacto con el proveedor."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Ingresa el código PIN deseado"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Confirmar código PIN deseado"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Desbloqueando tarjeta SIM…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Código PIN incorrecto"</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Escribe un PIN que tenga de cuatro a ocho números."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"El código PUK debe tener ocho números como mínimo."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Vuelve a ingresar el código PUK correcto. Si ingresas un código incorrecto varias veces, se inhabilitará la tarjeta SIM."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Los códigos PIN no coinciden."</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Demasiados intentos incorrectos de ingresar el patrón"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Para desbloquear, accede con tu cuenta de Google."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Nombre de usuario (correo)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Contraseña"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Acceder"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nombre de usuario o contraseña incorrectos"</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"¿Olvidaste tu nombre de usuario o contraseña?\nAccede a "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Comprobando la cuenta…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Escribiste incorrectamente tu PIN <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nVuelve a intentarlo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Escribiste incorrectamente tu contraseña <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nVuelve a intentarlo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Dibujaste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nVuelve a intentarlo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Intentaste desbloquear la tablet <xliff:g id="NUMBER_0">%d</xliff:g> veces, pero no lo lograste. Puedes intentarlo <xliff:g id="NUMBER_1">%d</xliff:g> veces más antes de que se restablezcan los valores predeterminados de fábrica de la tablet y se pierdan todos los datos del usuario."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Intentaste desbloquear el dispositivo <xliff:g id="NUMBER_0">%d</xliff:g> veces, pero no lo lograste. Puedes intentarlo <xliff:g id="NUMBER_1">%d</xliff:g> veces más antes de que se restablezcan los valores predeterminados de fábrica del dispositivo y se pierdan todos los datos del usuario."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Intentaste desbloquear la tablet <xliff:g id="NUMBER">%d</xliff:g> veces, pero no lo lograste. Se restablecerán los valores predeterminados de fábrica de la tablet."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Intentaste desbloquear el dispositivo <xliff:g id="NUMBER">%d</xliff:g> veces, pero no lo lograste. Se restablecerán los valores predeterminados de fábrica del dispositivo."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Dibujaste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos más, se te solicitará que desbloquees tu tablet mediante el uso de una cuenta de correo.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Dibujaste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos más, se te solicitará que desbloquees tu dispositivo mediante el uso de una cuenta de correo.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Eliminar"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Botón de pista anterior"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Botón de pista siguiente"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Botón de pausa"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Botón de reproducción"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Botón de detención"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Sin servicio"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-es/activitystrings.xml b/packages/Keyguard/res/values-es/activitystrings.xml
new file mode 100644
index 0000000..34899cc
--- /dev/null
+++ b/packages/Keyguard/res/values-es/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Sin seguridad"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Contraseña"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Patrón"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"PIN de tarjeta SIM"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"PUK de tarjeta SIM"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Seleccionar widget..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-es/strings.xml b/packages/Keyguard/res/values-es/strings.xml
new file mode 100644
index 0000000..3e4fe54
--- /dev/null
+++ b/packages/Keyguard/res/values-es/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Introduce el código PIN."</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Introduce el código PUK y un nuevo código PIN."</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Código PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Nuevo código PIN"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Toca para introducir contraseña"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Introduce la contraseña para desbloquear."</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Introduce el código 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 el teléfono, pulsa la tecla de menú y, a continuación, pulsa 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Se ha superado el número máximo de intentos de desbloqueo facial."</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Cargada"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Cargando (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Conecta el cargador."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Ve al menú para desbloquear la pantalla."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Bloqueada para la red"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Falta la tarjeta SIM"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"No se ha insertado ninguna tarjeta SIM en el tablet."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"No se ha insertado ninguna tarjeta SIM en el teléfono."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Inserta una tarjeta SIM."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"Falta la tarjeta SIM o no se puede leer. Introduce una tarjeta SIM."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Tarjeta SIM inutilizable"</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Tu tarjeta SIM se ha inhabilitado permanentemente.\n Para obtener otra, ponte en contacto con tu proveedor de servicios de telefonía."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"La tarjeta SIM está bloqueada."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"La tarjeta SIM está bloqueada con el código PUK."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Desbloqueando tarjeta SIM…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d de %3$d"</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Añadir widget"</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Vacío"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Área de desbloqueo ampliada"</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Área de desbloqueo contraída"</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget de <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>"</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Selector de usuarios"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Estado"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Cámara"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Controles multimedia"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Se ha empezado a cambiar el orden de los widgets."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Se ha terminado de cambiar el orden de los widgets."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> eliminado"</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Ampliar área de desbloqueo"</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Desbloqueo deslizando el dedo"</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Desbloqueo por patrón"</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Desbloqueo facial"</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Desbloqueo por PIN"</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Desbloqueo por contraseña"</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Área de patrón"</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Área para deslizar"</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Botón de canción anterior"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Botón de siguiente canción"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Botón de pausa"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Botón de reproducción"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Botón para detener la reproducción"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Cancelar"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Eliminar"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Listo"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Cambio de modo"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Mayús"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Intro"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Desbloquear"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Cámara"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Silencio"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Sonido activado"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Buscar"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Desliza el dedo hacia arriba para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Desliza el dedo hacia abajo para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Desliza el dedo hacia la izquierda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Desliza el dedo hacia la derecha para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Llamada de emergencia"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"¿Has olvidado el patrón?"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"El patrón es incorrecto"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Contraseña incorrecta"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN incorrecto"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Inténtalo de nuevo en <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Dibuja tu patrón de desbloqueo."</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Introduce el PIN de la tarjeta SIM."</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Introduce el PIN."</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Escribe tu contraseña."</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"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>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Introduce el código PIN deseado"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Confirma el código PIN"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Desbloqueando tarjeta SIM…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Código PIN incorrecto"</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Introduce un código PIN con una longitud comprendida entre cuatro y ocho dígitos."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"El código PUK debe tener ocho números como mínimo."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Vuelve a introducir el código PUK correcto. Si introduces un código incorrecto varias veces, se inhabilitará la tarjeta SIM."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Los códigos PIN no coinciden."</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Demasiados intentos incorrectos de crear el patrón"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Para desbloquear el teléfono, inicia sesión con tu cuenta de Google."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Nombre de usuario (correo electrónico)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Contraseña"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Iniciar sesión"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"El nombre de usuario o la contraseña no son válidos."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Si has olvidado tu nombre de usuario o tu contraseña,\naccede a la página "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Comprobando cuenta…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Has introducido un código PIN incorrecto <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nInténtalo de nuevo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Has introducido una contraseña incorrecta <xliff:g id="NUMBER_0">%d</xliff:g> veces. \n\nInténtalo de nuevo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Has fallado <xliff:g id="NUMBER_0">%d</xliff:g> veces al dibujar tu patrón de desbloqueo. \n\nInténtalo de nuevo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Has intentado desbloquear el tablet <xliff:g id="NUMBER_0">%d</xliff:g> veces, pero no lo has conseguido. Si fallas otras <xliff:g id="NUMBER_1">%d</xliff:g> veces, se restablecerán los datos de fábrica y se perderán todos los datos del usuario."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Has intentado desbloquear el teléfono <xliff:g id="NUMBER_0">%d</xliff:g> veces, pero no lo has conseguido. Si fallas otras <xliff:g id="NUMBER_1">%d</xliff:g> veces, se restablecerán los datos de fábrica y se perderán todos los datos del usuario."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Has intentado desbloquear el tablet <xliff:g id="NUMBER">%d</xliff:g> veces, pero no lo has conseguido. Se restablecerán los datos de fábrica del dispositivo."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Has intentado desbloquear el teléfono <xliff:g id="NUMBER">%d</xliff:g> veces, pero no lo has conseguido. Se restablecerán los datos de fábrica del dispositivo."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Has fallado <xliff:g id="NUMBER_0">%d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras <xliff:g id="NUMBER_1">%d</xliff:g> veces, deberás usar una cuenta de correo electrónico para desbloquear el tablet.\n\n Inténtalo de nuevo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Has fallado <xliff:g id="NUMBER_0">%d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras <xliff:g id="NUMBER_1">%d</xliff:g> veces, deberás usar una cuenta de correo electrónico para desbloquear el teléfono.\n\n Inténtalo de nuevo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Eliminar"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Botón de canción anterior"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Botón de siguiente canción"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Botón de pausa"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Botón de reproducción"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Botón para detener la reproducción"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Sin servicio"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-et-rEE/strings.xml b/packages/Keyguard/res/values-et-rEE/strings.xml
new file mode 100644
index 0000000..0a17a9c
--- /dev/null
+++ b/packages/Keyguard/res/values-et-rEE/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Sisestage PIN-kood"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Sisestage PUK-kood ja uus PIN-kood"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-kood"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Uus PIN-kood"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Puudutage parooli sisestamiseks"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Avamiseks sisestage parool"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Avamiseks sisestage PIN-kood"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Vale PIN-kood."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Avamiseks vajutage menüüklahvi, seejärel klahvi 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Maksimaalne teenusega Face Unlock avamise katsete arv on ületatud"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Laetud"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Laadimine, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Ühendage laadija."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Avamiseks vajutage menüüklahvi."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Võrk on suletud"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"SIM-kaarti pole"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Tahvelarvutis pole SIM-kaarti."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Telefonis pole SIM-kaarti."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Sisestage SIM-kaart."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM-kaart puudub või on loetamatu. Sisestage SIM-kaart."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Kasutamiskõlbmatu SIM-kaart."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"SIM-kaart on jäädavalt keelatud.\n Uue SIM-kaardi saamiseks võtke ühendust oma mobiilsideoperaatoriga."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM-kaart on lukus."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM-kaart on PUK-lukus."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SIM-kaardi avamine ..."</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Vidin %2$d/%3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Vidina lisamine."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tühi"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Avamisala on laiendatud."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Avamisala on ahendatud."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Vidin <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Kasutaja valija"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Olek"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Kaamera"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Meedia juhtnupud"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Vidina ümberkorraldamine algas."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Vidina ümberkorraldamine lõppes."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Vidin <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> on kustutatud."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Avamisala laiendamine."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Lohistamisega avamine."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Mustriga avamine."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Näoga avamine."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"PIN-koodiga avamine."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Parooliga avamine."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Mustri ala."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Lohistamisala."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Nupp Eelmine lugu"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Nupp Järgmine lugu"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Nupp Peata"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Nupp Esita"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Nupp Peata"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Tühista"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Kustuta"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Valmis"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Režiimi muutmine"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Tõstuklahv"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Sisestusklahv"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Luku avamine"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Kaamera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Hääletu"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Heli on sees"</string>
+    <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_down" msgid="5087739728639014595">"Lohistage alla: <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="description_direction_right" msgid="8034433242579600980">"Lohistage paremale: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Praegune kasutaja <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Hädaabikõne"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Unustasin mustri"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Vale muster"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Vale parool"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Vale PIN-kood"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Proovige uuesti <xliff:g id="NUMBER">%d</xliff:g> sekundi pärast."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Joonistage oma muster"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Sisestage SIM-i PIN-kood"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Sisestage PIN-kood"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Sisestage parool"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM on nüüd keelatud. Jätkamiseks sisestage PUK-kood. Üksikasju küsige operaatorilt."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Sisestage soovitud PIN-kood"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Kinnitage soovitud PIN-kood"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM-kaardi avamine ..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Vale PIN-kood."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Sisestage 4–8-numbriline PIN-kood."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK-koodi pikkus peab olema vähemalt 8 numbrit."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Sisestage uuesti õige PUK-kood. Korduvkatsete korral keelatakse SIM jäädavalt."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-koodid ei ole vastavuses"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Liiga palju mustrikatseid"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Avamiseks logige sisse oma Google\'i kontoga."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Kasutajanimi (e-post)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Parool"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Logi sisse"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Vale kasutajanimi või parool."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Kas unustasite kasutajanime või parooli?\nKülastage aadressi "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Konto kontrollimine ..."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Olete PIN-koodi <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti sisestanud.\n\nProovige <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast uuesti."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Olete parooli <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti sisestanud. \n\nProovige uuesti <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti.\n\nProovige <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast uuesti."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Olete üritanud <xliff:g id="NUMBER_0">%d</xliff:g> korda tahvelarvutit valesti avada. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset lähtestatakse tahvelarvuti tehase vaikeseadetele ja kõik kasutajaandmed lähevad kaotsi."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Olete üritanud <xliff:g id="NUMBER_0">%d</xliff:g> korda telefoni valesti avada. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset lähtestatakse telefon tehase vaikeseadetele ja kõik kasutajaandmed lähevad kaotsi."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Olete püüdnud tahvelarvutit <xliff:g id="NUMBER">%d</xliff:g> korda valesti avada. Tahvelarvuti lähtestatakse nüüd tehase vaikeseadetele."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Olete püüdnud telefoni <xliff:g id="NUMBER">%d</xliff:g> korda valesti avada. Telefon lähtestatakse nüüd tehase vaikeseadetele."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset palutakse teil tahvelarvuti avada meilikontoga.\n\n Proovige uuesti <xliff:g id="NUMBER_2">%d</xliff:g> sekundi pärast."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset palutakse teil telefon avada meilikontoga.\n\n Proovige uuesti <xliff:g id="NUMBER_2">%d</xliff:g> sekundi pärast."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Eemalda"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Nupp Eelmine lugu"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Nupp Järgmine lugu"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Nupp Peata"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Nupp Esita"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Nupp Peata"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Teenus puudub."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-et/activitystrings.xml b/packages/Keyguard/res/values-et/activitystrings.xml
new file mode 100644
index 0000000..eb71afc
--- /dev/null
+++ b/packages/Keyguard/res/values-et/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Turvamata"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN-kood"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Parool"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Muster"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"SIM-i PIN-kood"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"SIM-i PUK"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Vidina valimine ..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-et/strings.xml b/packages/Keyguard/res/values-et/strings.xml
new file mode 100644
index 0000000..0a17a9c
--- /dev/null
+++ b/packages/Keyguard/res/values-et/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Sisestage PIN-kood"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Sisestage PUK-kood ja uus PIN-kood"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-kood"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Uus PIN-kood"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Puudutage parooli sisestamiseks"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Avamiseks sisestage parool"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Avamiseks sisestage PIN-kood"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Vale PIN-kood."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Avamiseks vajutage menüüklahvi, seejärel klahvi 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Maksimaalne teenusega Face Unlock avamise katsete arv on ületatud"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Laetud"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Laadimine, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Ühendage laadija."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Avamiseks vajutage menüüklahvi."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Võrk on suletud"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"SIM-kaarti pole"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Tahvelarvutis pole SIM-kaarti."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Telefonis pole SIM-kaarti."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Sisestage SIM-kaart."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM-kaart puudub või on loetamatu. Sisestage SIM-kaart."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Kasutamiskõlbmatu SIM-kaart."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"SIM-kaart on jäädavalt keelatud.\n Uue SIM-kaardi saamiseks võtke ühendust oma mobiilsideoperaatoriga."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM-kaart on lukus."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM-kaart on PUK-lukus."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SIM-kaardi avamine ..."</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Vidin %2$d/%3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Vidina lisamine."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tühi"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Avamisala on laiendatud."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Avamisala on ahendatud."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Vidin <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Kasutaja valija"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Olek"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Kaamera"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Meedia juhtnupud"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Vidina ümberkorraldamine algas."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Vidina ümberkorraldamine lõppes."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Vidin <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> on kustutatud."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Avamisala laiendamine."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Lohistamisega avamine."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Mustriga avamine."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Näoga avamine."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"PIN-koodiga avamine."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Parooliga avamine."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Mustri ala."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Lohistamisala."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Nupp Eelmine lugu"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Nupp Järgmine lugu"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Nupp Peata"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Nupp Esita"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Nupp Peata"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Tühista"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Kustuta"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Valmis"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Režiimi muutmine"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Tõstuklahv"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Sisestusklahv"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Luku avamine"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Kaamera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Hääletu"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Heli on sees"</string>
+    <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_down" msgid="5087739728639014595">"Lohistage alla: <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="description_direction_right" msgid="8034433242579600980">"Lohistage paremale: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Praegune kasutaja <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Hädaabikõne"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Unustasin mustri"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Vale muster"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Vale parool"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Vale PIN-kood"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Proovige uuesti <xliff:g id="NUMBER">%d</xliff:g> sekundi pärast."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Joonistage oma muster"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Sisestage SIM-i PIN-kood"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Sisestage PIN-kood"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Sisestage parool"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM on nüüd keelatud. Jätkamiseks sisestage PUK-kood. Üksikasju küsige operaatorilt."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Sisestage soovitud PIN-kood"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Kinnitage soovitud PIN-kood"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM-kaardi avamine ..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Vale PIN-kood."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Sisestage 4–8-numbriline PIN-kood."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK-koodi pikkus peab olema vähemalt 8 numbrit."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Sisestage uuesti õige PUK-kood. Korduvkatsete korral keelatakse SIM jäädavalt."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-koodid ei ole vastavuses"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Liiga palju mustrikatseid"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Avamiseks logige sisse oma Google\'i kontoga."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Kasutajanimi (e-post)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Parool"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Logi sisse"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Vale kasutajanimi või parool."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Kas unustasite kasutajanime või parooli?\nKülastage aadressi "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Konto kontrollimine ..."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Olete PIN-koodi <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti sisestanud.\n\nProovige <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast uuesti."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Olete parooli <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti sisestanud. \n\nProovige uuesti <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti.\n\nProovige <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast uuesti."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Olete üritanud <xliff:g id="NUMBER_0">%d</xliff:g> korda tahvelarvutit valesti avada. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset lähtestatakse tahvelarvuti tehase vaikeseadetele ja kõik kasutajaandmed lähevad kaotsi."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Olete üritanud <xliff:g id="NUMBER_0">%d</xliff:g> korda telefoni valesti avada. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset lähtestatakse telefon tehase vaikeseadetele ja kõik kasutajaandmed lähevad kaotsi."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Olete püüdnud tahvelarvutit <xliff:g id="NUMBER">%d</xliff:g> korda valesti avada. Tahvelarvuti lähtestatakse nüüd tehase vaikeseadetele."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Olete püüdnud telefoni <xliff:g id="NUMBER">%d</xliff:g> korda valesti avada. Telefon lähtestatakse nüüd tehase vaikeseadetele."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset palutakse teil tahvelarvuti avada meilikontoga.\n\n Proovige uuesti <xliff:g id="NUMBER_2">%d</xliff:g> sekundi pärast."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset palutakse teil telefon avada meilikontoga.\n\n Proovige uuesti <xliff:g id="NUMBER_2">%d</xliff:g> sekundi pärast."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Eemalda"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Nupp Eelmine lugu"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Nupp Järgmine lugu"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Nupp Peata"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Nupp Esita"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Nupp Peata"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Teenus puudub."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-fa/activitystrings.xml b/packages/Keyguard/res/values-fa/activitystrings.xml
new file mode 100644
index 0000000..735af8d
--- /dev/null
+++ b/packages/Keyguard/res/values-fa/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"عدم وجود امنیت"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"پین"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"گذرواژه"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"الگو"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"پین سیم کارت"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"PUK سیم کارت"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"انتخاب ابزارک..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-fa/strings.xml b/packages/Keyguard/res/values-fa/strings.xml
new file mode 100644
index 0000000..83c5a34
--- /dev/null
+++ b/packages/Keyguard/res/values-fa/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"پین کد را وارد کنید"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK و پین کد جدید را تایپ کنید"</string>
+    <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="7858547464982981384"><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="faceunlock_multiple_failures" msgid="754137583022792429">"دفعات تلاش برای Face Unlock از حداکثر مجاز بیشتر شد"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"شارژ شد"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"شارژ، <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"شارژر خود را وصل کنید."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"برای بازگشایی قفل روی منو فشار دهید."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"شبکه قفل شد"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"سیم کارت موجود نیست"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"سیم کارتی در رایانه لوحی نیست."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"سیم کارت در تلفن نیست."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"سیم کارت را وارد کنید."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"سیم کارت موجود نیست یا قابل خواندن نیست. یک سیم کارت وارد کنید."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"سیم کارت غیرقابل استفاده است."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"سیم کارت شما به طور دائم غیر فعال شده است. \nبرای داشتن سیم کارت دیگر با ارائه‎دهنده سرویس بی‎سیم خود تماس بگیرید."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"سیم کارت قفل شد."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"سیم کارت با PUK قفل شده است."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"درحال بازگشایی قفل سیم کارت..."</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. ابزارک %2$d از %3$d."</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_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>
+    <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_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="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"دکمه تراک قبلی"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"دکمه تراک بعدی"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"دکمه توقف موقت"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"دکمه پخش"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"دکمه توقف"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</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">"Delete"</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_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"بازکردن قفل"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"دوربین"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"ساکت"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"صدا روشن"</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_down" msgid="5087739728639014595">"لغزاندن به پایین برای <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="description_direction_right" msgid="8034433242579600980">"لغزاندن به راست برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"کاربر کنونی <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"تماس اضطراری"</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_too_many_failed_attempts_countdown" msgid="6358110221603297548">"پس از <xliff:g id="NUMBER">%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">"اکنون سیم کارت غیرفعال است. پین کد را برای ادامه وارد کنید. برای جزئیات با شرکت مخابراتی خود تماس بگیرید."</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">"یک پین ۴ تا ۸ رقمی را تایپ کنید."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"پین کد باید ۸ عدد یا بیشتر باشد."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"پین کد صحیح را دوباره وارد کنید. تلاش‌های مکرر به‌طور دائم سیم کارت را غیرفعال خواهد کرد."</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_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">%d</xliff:g> بار اشتباه تایپ کردید. \n\nپس از <xliff:g id="NUMBER_1">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"گذرواژه خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه تایپ کردید. \n\nپس از <xliff:g id="NUMBER_1">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه کشیدید. \n\nلطفاً پس از <xliff:g id="NUMBER_1">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"شما به اشتباه <xliff:g id="NUMBER_0">%d</xliff:g> بار اقدام به باز کردن قفل رایانه لوحی کرده‌اید. پس از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق دیگر، رایانهٔ لوحی به پیش‌فرض کارخانه بازنشانی می‌شود و تمام داده‌های کاربر از دست خواهد رفت."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"شما به اشتباه <xliff:g id="NUMBER_0">%d</xliff:g> بار اقدام به باز کردن قفل تلفن کرده‌اید. پس از <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> بار اشتباه کشیده‎اید. بعد از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق، از شما خواسته می‎شود که با استفاده از یک حساب ایمیل قفل رایانه لوحی خود را باز کنید.\n\n لطفاً پس از <xliff:g id="NUMBER_2">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"شما الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه کشیده‌اید. پس از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق، از شما خواسته می‎شود که با استفاده از یک حساب ایمیل قفل تلفن خود را باز کنید.\n\n لطفاً پس از <xliff:g id="NUMBER_2">%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="keyguard_transport_prev_description" msgid="8229108430245669854">"دکمه تراک قبلی"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"دکمه تراک بعدی"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"دکمه توقف موقت"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"دکمه پخش"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"دکمه توقف"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"خدماتی وجود ندارد."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-fi/activitystrings.xml b/packages/Keyguard/res/values-fi/activitystrings.xml
new file mode 100644
index 0000000..6e0a5a9
--- /dev/null
+++ b/packages/Keyguard/res/values-fi/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Ei suojausta"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN-koodi"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Salasana"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Kuvio"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"SIM-kortin PIN-koodi"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"SIM-kortin PUK-koodi"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Valitse widget…"</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-fi/strings.xml b/packages/Keyguard/res/values-fi/strings.xml
new file mode 100644
index 0000000..dbca50d
--- /dev/null
+++ b/packages/Keyguard/res/values-fi/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Anna PIN-koodi"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Anna PUK-koodi ja uusi PIN-koodi"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-koodi"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Uusi PIN-koodi"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Kosketa ja anna salasana"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Poista lukitus antamalla salasana"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Poista lukitus antamalla PIN-koodi"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PIN-koodi väärin."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Poista lukitus painamalla Valikko-painiketta ja 0-näppäintä."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Face Unlock -yrityksiä tehty suurin sallittu määrä."</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Täynnä"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Ladataan (<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>)"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Kytke laturi."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Poista lukitus painamalla Valikko-painiketta."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Verkko lukittu"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Ei SIM-korttia"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Tablet-laitteessa ei ole SIM-korttia."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Puhelimessa ei ole SIM-korttia."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Aseta SIM-kortti."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM-korttia ei löydy tai sitä ei voi lukea. Aseta SIM-kortti."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"SIM-kortti ei kelpaa."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"SIM-kortti on poistettu pysyvästi käytöstä.\n Ota yhteyttä operaattoriisi ja hanki uusi SIM-kortti."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM-kortti on lukittu."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM-kortti on PUK-lukittu."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SIM-kortin lukitusta poistetaan…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d/%3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Lisää widget."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tyhjä"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Lukituksen poiston alue laajennettu."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Lukituksen poiston alue tiivistetty."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>-widget."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Käyttäjävalitsin"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Tila"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Kamera"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Mediaohjaimet"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Widgetien järjestely aloitettu."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Widgetien järjestely päättyi."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> poistettu."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Laajenna lukituksen poiston aluetta."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Lukituksen poisto liu\'uttamalla."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Lukituksen poisto salasanalla."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Face Unlock"</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Lukituksen poisto PIN-koodilla."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Lukituksen poisto salasanalla."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Kuvioalue."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Liu\'utusalue."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Edellinen kappale -painike"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Seuraava kappale -painike"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Tauko-painike"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Toista-painike"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Keskeytä-painike"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Peruuta"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Poista"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Valmis"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Tilan muutos"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Poista lukitus"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Äänetön"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Ääni käytössä"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Haku"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Liu\'uta ylös ja <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Liu\'uta alas ja <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Liu\'uta vasemmalle ja <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Liu\'uta oikealle ja <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Nykyinen käyttäjä: <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Hätäpuhelu"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Unohtunut kuvio"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Väärä kuvio"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Väärä salasana"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Väärä PIN-koodi"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Yritä uudelleen <xliff:g id="NUMBER">%d</xliff:g> sekunnin kuluttua."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Piirrä kuvio"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Anna SIM-kortin PIN-koodi"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Anna PIN-koodi"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Anna salasana"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM-kortti on nyt poistettu käytöstä. Jatka antamalla PUK-koodi. Saat lisätietoja ottamalla yhteyttä operaattoriin."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Anna haluamasi PIN-koodi"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Vahvista haluamasi PIN-koodi"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM-kortin lukitusta poistetaan…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Virheellinen PIN-koodi."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Anna 4–8-numeroinen PIN-koodi."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK-koodissa tulee olla vähintään 8 numeroa."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Anna uudelleen oikea PUK-koodi. Jos teet liian monta yritystä, SIM-kortti poistetaan käytöstä pysyvästi."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-koodit eivät täsmää"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Liikaa kuvionpiirtoyrityksiä"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Poista lukitus kirjautumalla sisään Google-tililläsi."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Käyttäjänimi (sähköposti)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Salasana"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Kirjaudu sisään"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Virheellinen käyttäjänimi tai salasana."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Unohditko käyttäjänimesi tai salasanasi?\nKäy osoitteessa "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Tarkistetaan tiliä..."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Olet kirjoittanut PIN-koodin väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. \n\nYritä uudelleen <xliff:g id="NUMBER_1">%d</xliff:g> sekunnin kuluttua."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Olet kirjoittanut salasanan väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. \n\nYritä uudelleen <xliff:g id="NUMBER_1">%d</xliff:g> sekunnin kuluttua."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Olet piirtänyt lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. \n\nYritä uudelleen <xliff:g id="NUMBER_1">%d</xliff:g> sekunnin kuluttua."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tablet-laitteen lukituksen poisto epäonnistui <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos teet vielä <xliff:g id="NUMBER_1">%d</xliff:g> epäonnistunutta yritystä, tablet-laitteeseen palautetaan tehdasasetukset ja kaikki käyttäjätiedot häviävät."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Puhelimen lukituksen poisto epäonnistui <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos teet vielä <xliff:g id="NUMBER_1">%d</xliff:g> epäonnistunutta yritystä, puhelimeen palautetaan tehdasasetukset ja kaikki käyttäjätiedot häviävät."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Tablet-laitteen lukituksen poisto epäonnistui <xliff:g id="NUMBER">%d</xliff:g> kertaa. Laitteeseen palautetaan nyt tehdasasetukset."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Puhelimen lukituksen poisto epäonnistui <xliff:g id="NUMBER">%d</xliff:g> kertaa. Puhelimeen palautetaan nyt tehdasasetukset."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%d</xliff:g> kertaa, sinua pyydetään poistamaan tablet-laitteesi lukitus sähköpostitilin avulla.\n\n Yritä uudelleen <xliff:g id="NUMBER_2">%d</xliff:g> sekunnin kuluttua."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%d</xliff:g> kertaa, sinua pyydetään poistamaan puhelimesi lukitus sähköpostitilin avulla.\n\n Yritä uudelleen <xliff:g id="NUMBER_2">%d</xliff:g> sekunnin kuluttua."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Poista"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Edellinen kappale -painike"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Seuraava kappale -painike"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Tauko-painike"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Toista-painike"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Keskeytä-painike"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Ei yhteyttä."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-fr-rCA/strings.xml b/packages/Keyguard/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..35e897d
--- /dev/null
+++ b/packages/Keyguard/res/values-fr-rCA/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Saisissez le NIP."</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Saisissez la clé PUK et le nouveau NIP."</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Clé PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Nouveau NIP"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Appuyer pour saisir mot passe"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Saisissez le mot de passe pour déverrouiller le clavier."</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Saisissez le NIP pour déverrouiller le clavier."</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"NIP erroné."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Pour déverrouiller le téléphone, appuyez sur \"Menu\", puis sur 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Nombre maximal autorisé de tentatives Face Unlock atteint."</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Chargé"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"En charge (<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>)"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Branchez votre chargeur."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Appuyez sur \"Menu\" pour déverrouiller l\'appareil."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Réseau verrouillé"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Aucune carte SIM"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Aucune carte SIM n\'est insérée dans la tablette."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Aucune carte SIM n\'est insérée dans le téléphone."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Insérez une carte SIM."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"Carte SIM absente ou illisible. Veuillez insérer une carte SIM."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Carte SIM inutilisable."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Votre carte SIM a été définitivement désactivée.\n Veuillez contacter votre opérateur de téléphonie mobile pour en obtenir une autre."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"La carte SIM est verrouillée."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"La carte SIM est verrouillée par clé PUK."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Déverrouillage de la carte SIM en cours…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d sur %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Ajouter un widget"</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Vide"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Développement de la zone de déverrouillage"</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Réduction de la zone de déverrouillage"</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>"</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Sélecteur d\'utilisateur"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"État"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Caméra"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Commandes multimédias"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Début de la réorganisation des widgets"</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Fin de la réorganisation des widgets"</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Le widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> a été supprimé."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Développer la zone de déverrouillage"</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Déverrouillage en faisant glisser votre doigt sur l\'écran"</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Déverrouillage par schéma"</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Déverrouillage par reconnaissance faciale"</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Déverrouillage par NIP"</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Déverrouillage par mot de passe"</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Zone du schéma"</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Zone où faire glisser votre doigt sur l\'écran"</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Bouton pour revenir au titre précédent"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Bouton pour atteindre le titre suivant"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Bouton de pause"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Bouton de lecture"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Bouton d\'arrêt"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Annuler"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Supprimer"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Terminé"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Changement de mode"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Maj"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Entrée"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Déverrouiller"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Appareil photo"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Mode silencieux"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Son activé"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Recherche"</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_down" msgid="5087739728639014595">"Faire glisser le doigt vers le bas : <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="description_direction_right" msgid="8034433242579600980">"Faites glisser votre doigt vers la droite pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Appel d\'urgence"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"J\'ai oublié le schéma"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Schéma incorrect."</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Mot de passe incorrect."</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"NIP incorrect."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Réessayez dans <xliff:g id="NUMBER">%d</xliff:g> secondes."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Dessinez votre schéma."</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Saisissez le NIP de la carte SIM"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Saisissez le NIP."</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Saisissez votre mot de passe."</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"La carte SIM est maintenant désactivée. Saisissez le code PUK pour continuer. Contactez votre opérateur pour en savoir plus."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Saisir le NIP souhaité"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Confirmer le NIP souhaité"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Déblocage de la carte SIM en cours…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"NIP erroné."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Saisissez un NIP comprenant entre quatre et huit chiffres"</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Le code PUK doit contenir au moins 8 chiffres."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Veuillez saisir de nouveau le code PUK correct. Des tentatives répétées désactivent définitivement la carte SIM."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Les codes PIN ne correspondent pas."</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Trop de tentatives."</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Pour déverrouiller l\'appareil, connectez-vous avec votre compte Google."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Nom d\'utilisateur (courriel)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Mot de passe"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Connexion"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nom d\'utilisateur ou mot de passe non valide."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Vous avez oublié votre nom d\'utilisateur ou votre mot de passe?\nRendez-vous sur la page "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Vérification du compte en cours…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Vous avez saisi un NIP incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Vous avez saisi un mot de passe incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Sa configuration d\'usine va être rétablie."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Sa configuration d\'usine va être rétablie."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, vous devrez déverrouiller votre tablette à l\'aide d\'un compte de messagerie électronique.\n\n Veuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, vous devrez déverrouiller votre téléphone à l\'aide d\'un compte de messagerie électronique.\n\n Veuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Supprimer"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Bouton pour revenir au titre précédent"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Bouton pour atteindre le titre suivant"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Bouton de pause"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Bouton de lecture"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Bouton d\'arrêt"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Aucun service"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-fr/activitystrings.xml b/packages/Keyguard/res/values-fr/activitystrings.xml
new file mode 100644
index 0000000..dc79842
--- /dev/null
+++ b/packages/Keyguard/res/values-fr/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Aucune sécurité"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"Code PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Mot de passe"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Schéma"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"Code PIN de la carte SIM"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"Clé PUK de la carte SIM"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Sélectionner un widget"</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-fr/strings.xml b/packages/Keyguard/res/values-fr/strings.xml
new file mode 100644
index 0000000..250a136
--- /dev/null
+++ b/packages/Keyguard/res/values-fr/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Saisissez le code PIN."</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Saisissez la clé PUK et le nouveau code PIN."</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Code PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Nouveau code PIN"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Appuyez pour saisir mot passe"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Saisissez le mot de passe pour déverrouiller le clavier."</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Saisissez le code PIN pour déverrouiller le clavier."</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Le code PIN est erroné."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Pour déverrouiller le clavier, appuyez sur \"Menu\" puis sur 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Nombre maximal autorisé de tentatives Face Unlock atteint."</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Chargé"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"En charge (<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>)"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Branchez votre chargeur."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Appuyez sur \"Menu\" pour déverrouiller l\'appareil."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Réseau verrouillé"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Aucune carte SIM"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Aucune carte SIM n\'est insérée dans la tablette."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Aucune carte SIM n\'est insérée dans le téléphone."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Insérez une carte SIM."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"Carte SIM absente ou illisible. Veuillez insérer une carte SIM."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Carte SIM inutilisable."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Votre carte SIM a été définitivement désactivée.\n Veuillez contacter votre opérateur de téléphonie mobile pour en obtenir une autre."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"La carte SIM est verrouillée."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"La carte SIM est verrouillée par clé PUK."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Déverrouillage de la carte SIM en cours…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d sur %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Ajouter un widget"</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Vide"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Zone de déverrouillage développée."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Zone de déverrouillage réduite."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>"</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Sélecteur d\'utilisateur"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"État"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Caméra"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Commandes multimédias"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Début de la réorganisation des widgets"</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Réorganisation des widgets terminée."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Le widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> a été supprimé."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Développer la zone de déverrouillage"</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Déverrouillage en faisant glisser votre doigt sur l\'écran"</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Déverrouillage par schéma"</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Déverrouillage par reconnaissance faciale"</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Déverrouillage par code PIN"</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Déverrouillage par mot de passe"</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Zone du schéma"</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Zone où faire glisser votre doigt sur l\'écran"</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Bouton pour revenir au titre précédent"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Bouton pour atteindre le titre suivant"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Bouton de pause"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Bouton de lecture"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Bouton d\'arrêt"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Annuler"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Supprimer"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Terminé"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Changement de mode"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Maj"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Entrée"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Déverrouiller"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Appareil photo"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Mode silencieux"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Son activé"</string>
+    <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_down" msgid="5087739728639014595">"Faites glisser vers le bas 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="description_direction_right" msgid="8034433242579600980">"Faites glisser vers la droite pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Appel d\'urgence"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"J\'ai oublié le schéma"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Schéma incorrect."</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Mot de passe incorrect."</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Code PIN incorrect."</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Réessayez dans <xliff:g id="NUMBER">%d</xliff:g> secondes."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Dessinez votre schéma."</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Saisissez le code PIN de la carte SIM."</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Saisissez le code PIN."</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Saisissez votre mot de passe."</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"La carte SIM est maintenant désactivée. Saisissez le code PUK pour continuer. Contactez votre opérateur pour en savoir plus."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Saisir le code PIN souhaité"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Confirmer le code PIN souhaité"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Déblocage de la carte SIM en cours…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Le code PIN est erroné."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Veuillez saisir un code PIN comprenant entre quatre et huit chiffres."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Le code PUK doit contenir au moins 8 chiffres."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Veuillez saisir de nouveau le code PUK correct. Des tentatives répétées désactivent définitivement la carte SIM."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Les codes PIN ne correspondent pas."</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Trop de tentatives."</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Pour déverrouiller le téléphone, veuillez vous connecter avec votre compte Google."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Nom d\'utilisateur (e-mail)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Mot de passe"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Connexion"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nom d\'utilisateur ou mot de passe non valide."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Vous avez oublié votre nom d\'utilisateur ou votre mot de passe ?\nRendez-vous sur la page "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Vérification du compte en cours…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Vous avez saisi un code PIN incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Vous avez saisi un mot de passe incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. \n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Sa configuration d\'usine va être rétablie."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Sa configuration d\'usine va être rétablie."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, vous devrez déverrouiller votre tablette à l\'aide d\'un compte de messagerie électronique.\n\n Veuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, vous devrez déverrouiller votre téléphone à l\'aide d\'un compte de messagerie électronique.\n\n Veuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Supprimer"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Bouton pour revenir au titre précédent"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Bouton pour atteindre le titre suivant"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Bouton de pause"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Bouton de lecture"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Bouton d\'arrêt"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Aucun service"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-hi/activitystrings.xml b/packages/Keyguard/res/values-hi/activitystrings.xml
new file mode 100644
index 0000000..4b0a082
--- /dev/null
+++ b/packages/Keyguard/res/values-hi/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"कोई सुरक्षा नहीं"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"पासवर्ड"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"प्रतिमान"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"SIM पिन"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"SIM PUK"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"विजेट चुनें..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-hi/strings.xml b/packages/Keyguard/res/values-hi/strings.xml
new file mode 100644
index 0000000..2c6188a
--- /dev/null
+++ b/packages/Keyguard/res/values-hi/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"पिन कोड लिखें"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK और नया पिन कोड लिखें"</string>
+    <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="7858547464982981384"><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="faceunlock_multiple_failures" msgid="754137583022792429">"फेस अनलॉक के अधिकतम प्रयासों की सीमा पार हो गई"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"चार्ज हो गई"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"चार्ज हो रही है, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"अपना चार्जर कनेक्‍ट करें."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"अनलॉक करने के लिए मेनू दबाएं."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"नेटवर्क लॉक किया गया"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"कोई SIM कार्ड नहीं है"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"टेबलेट में कोई SIM कार्ड नहीं है."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"फ़ोन में कोई SIM कार्ड नहीं है."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"SIM कार्ड डालें."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM कार्ड गुम है या पढ़ने योग्‍य नहीं है. SIM कार्ड डालें."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"अनुपयोगी SIM कार्ड."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"आपका SIM कार्ड स्‍थायी रूप से अक्षम कर दिया गया है.\n दूसरे SIM कार्ड के लिए अपने वायरलेस सेवा प्रदाता से संपर्क करें."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"सिम कार्ड लॉक है."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM कार्ड PUK द्वारा लॉक किया हुआ है."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SIM कार्ड अनलॉक हो रहा है…"</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_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_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>
+    <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_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="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"पिछला ट्रैक बटन"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"अगला ट्रैक बटन"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"पॉज़ करें बटन"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"चलाएं बटन"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"रोकें बटन"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</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">"Mode change"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"अनलॉक करें"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"कैमरा"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"मौन"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"ध्‍वनि चालू करें"</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_down" msgid="5087739728639014595">"<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="description_direction_right" msgid="8034433242579600980">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए दाएं स्‍लाइड करें."</string>
+    <string name="user_switched" msgid="3768006783166984410">"वर्तमान उपयोगकर्ता <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"आपातकालीन कॉल"</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">"गलत PIN"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"अपना आकार आरेखित करें"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"सिम PIN डालें"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN डालें"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"पासवर्ड डालें"</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">"गलत PIN कोड."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"ऐसा PIN लिखें, जो 4 से 8 अंकों का हो."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK कोड 8 या अधिक संख्या वाला होना चाहिए."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"सही PUK कोड पुन: डालें. बार-बार प्रयास करने से सिम स्थायी रूप से अक्षम हो जाएगी."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"पिन कोड का मिलान नहीं होता"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"बहुत अधिक आकार प्रयास"</string>
+    <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_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">%d</xliff:g> बार गलत तरीके से लिख चुके हैं. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"आप अपना पासवर्ड <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से लिख चुके हैं. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"आपने अपना अनलॉक आकार <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से आरेखित किया है. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"आप टेबलेट को अनलॉक करने के लिए <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से प्रयास कर चुके हैं. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, टेबलेट फ़ैक्टरी डिफ़ॉल्ट पर रीसेट हो जाएगा और सभी उपयोगकर्ता डेटा खो जाएगा."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"आप फ़ोन को अनलॉक करने के लिए <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से प्रयास कर चुके हैं. <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> बार गलत तरीके से आरेखित किया है. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने टेबलेट को किसी ईमेल खाते के उपयोग से अनलॉक करने के लिए कहा जाएगा.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"आपने अपने अनलॉक आकार को <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से आरेखित किया है. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने फ़ोन को किसी ईमेल खाते का उपयोग करके अनलॉक करने के लिए कहा जाएगा.\n\n <xliff:g id="NUMBER_2">%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="keyguard_transport_prev_description" msgid="8229108430245669854">"पिछला ट्रैक बटन"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"अगला ट्रैक बटन"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"पॉज़ करें बटन"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"चलाएं बटन"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"रोकें बटन"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"कोई सेवा नहीं."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-hr/activitystrings.xml b/packages/Keyguard/res/values-hr/activitystrings.xml
new file mode 100644
index 0000000..d2b8e92
--- /dev/null
+++ b/packages/Keyguard/res/values-hr/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Nema zaštite"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Zaporka"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Uzorak"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"PIN za SIM"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"PUK za SIM"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Odaberite widget..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-hr/strings.xml b/packages/Keyguard/res/values-hr/strings.xml
new file mode 100644
index 0000000..70e6305
--- /dev/null
+++ b/packages/Keyguard/res/values-hr/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Unesite PIN kôd"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Unesite PUK i novi PIN kôd"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK kôd"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Novi PIN kôd"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Dodirnite za tipkanje zaporke"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Unesite zaporku za otključavanje"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Unesite PIN za otključavanje"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Netočan PIN kôd."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Za otključavanje pritisnite Izbornik pa 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Premašen je maksimalni broj Otključavanja licem"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Napunjeno"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Puni se, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Priključite punjač."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Pritisnite Izbornik za otključavanje."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Mreža je zaključana"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Nema SIM kartice"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"U tabletnom uređaju nema SIM kartice."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"U telefonu nema SIM kartice."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Umetnite SIM karticu."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM kartica nedostaje ili nije čitljiva. Umetnite SIM karticu."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Neupotrebljiva SIM kartica."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Vaša SIM kartica trajno je onemogućena.\n Obratite se svom pružatelju bežičnih usluga da biste dobili drugu SIM karticu."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM kartica je zaključana."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM kartica zaključana je PUK-om."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Otključavanje SIM kartice…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d od %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Dodavanje widgeta."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Prazno"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Područje za otključavanje prošireno je."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Područje za otključavanje sažeto je."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> widget."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Birač korisnika"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Status"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Fotoaparat"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Nadzor medija"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Pokrenuta je promjena redoslijeda widgeta."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Završena je promjena redoslijeda widgeta."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> izbrisan je."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Proširivanje područja za otključavanje."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Otključavanje klizanjem."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Uzorak za otključavanje."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Otključavanje licem."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Otključavanje PIN-om."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Otključavanje zaporkom."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Područje uzorka."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Područje klizanja."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Gumb Prethodni zapis"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Gumb Sljedeći zapis"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Gumb Pauza"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Gumb Reprodukcija"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Gumb Zaustavi"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Odustani"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Izbriši"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Gotovo"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Promjena načina"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Otključaj"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Fotoaparat"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Bešumno"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Zvuk je uključen"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Pretraživanje"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Kliznite prema gore za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Kliznite prema dolje za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Kliznite lijevo za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Kliznite desno za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Trenutačni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Hitan poziv"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Zaboravili ste obrazac"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Pogrešan obrazac"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Pogrešna zaporka"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Pogrešan PIN"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Pokušajte ponovo za <xliff:g id="NUMBER">%d</xliff:g> s."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Iscrtajte svoj obrazac"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Unesite PIN za SIM"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Unesite PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Unesite zaporku"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM je sad onemogućen. Unesite PUK kôd da biste nastavili. Kontaktirajte operatera za pojedinosti."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Upišite željeni PIN kôd"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Potvrdite željeni PIN kôd"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Otključavanje SIM kartice…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Netočan PIN kôd."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Unesite PIN koji ima od 4 do 8 brojeva."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK kôd treba imati 8 brojeva ili više."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Ponovo unesite ispravan PUK kôd. Ponovljeni pokušaji trajno će onemogućiti SIM."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN kodovi nisu jednaki"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Previše pokušaja iscrtavanja obrasca"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Za otključavanje prijavite se Google računom."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Korisničko ime (e-pošta)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Zaporka"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Prijava"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nevažeće korisničko ime ili zaporka."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Zaboravili ste korisničko ime ili zaporku?\nPosjetite "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Provjera računa..."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Netočno ste napisali PIN <xliff:g id="NUMBER_0">%d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Netočno ste napisali zaporku <xliff:g id="NUMBER_0">%d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Netočno ste iscrtali obrazac za otključavanje <xliff:g id="NUMBER_0">%d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Netočno ste pokušali otključati tabletno računalo <xliff:g id="NUMBER_0">%d</xliff:g> puta. Ono će se vratiti na tvorničke postavke i svi korisnički podaci bit će izgubljeni nakon još ovoliko neuspjelih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Netočno ste pokušali otključati telefon <xliff:g id="NUMBER_0">%d</xliff:g> puta. On će se vratiti na tvorničke postavke i svi korisnički podaci bit će izgubljeni nakon još ovoliko neuspjelih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Netočno ste pokušali otključati tabletno računalo <xliff:g id="NUMBER">%d</xliff:g> puta. Sada će se vratiti na tvorničke postavke."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Netočno ste pokušali otključati telefon <xliff:g id="NUMBER">%d</xliff:g> puta. Sada će se vratiti na tvorničke postavke."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Netočno ste iscrtali obrazac za otključavanje <xliff:g id="NUMBER_0">%d</xliff:g> puta. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g> morat ćete otključati tabletno računalo pomoću računa e-pošte.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Netočno ste iscrtali obrazac za otključavanje <xliff:g id="NUMBER_0">%d</xliff:g> puta. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g> morat ćete otključati telefon pomoću računa e-pošte.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <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="keyguard_transport_prev_description" msgid="8229108430245669854">"Gumb Prethodni zapis"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Gumb Sljedeći zapis"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Gumb Pauza"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Gumb Reprodukcija"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Gumb Zaustavi"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Nema usluge."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-hu/activitystrings.xml b/packages/Keyguard/res/values-hu/activitystrings.xml
new file mode 100644
index 0000000..30d2951
--- /dev/null
+++ b/packages/Keyguard/res/values-hu/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Nincs védelem"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN kód"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Jelszó"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Minta"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"SIM kártya PIN kódja"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"SIM kártya PUK kódja"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Modul kiválasztása..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-hu/strings.xml b/packages/Keyguard/res/values-hu/strings.xml
new file mode 100644
index 0000000..611602e
--- /dev/null
+++ b/packages/Keyguard/res/values-hu/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Írja be a PIN kódot"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Írja be a PUK kódot, majd az új PIN kódot"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK kód"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Új PIN kód"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Érintsen jelszó megadásához"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"A feloldáshoz írja be a jelszót"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Feloldáshoz írja be a PIN kódot"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Helytelen PIN kód."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"A feloldáshoz nyomja meg a Menü, majd a 0 gombot."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Elérte az arcalapú feloldási kísérletek maximális számát"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Feltöltve"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Töltés (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Csatlakoztassa a töltőt."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"A feloldáshoz nyomja meg a Menü gombot."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"A hálózat lezárva"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Nincs SIM kártya."</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Nincs SIM kártya a táblagépben."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Nincs SIM kártya a telefonban."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Helyezzen be egy SIM kártyát."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"A SIM kártya hiányzik vagy nem olvasható. Helyezzen be egy SIM kártyát."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"A SIM kártya nem használható."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"SIM kártyája véglegesen le van tiltva.\n Forduljon a vezeték nélküli szolgáltatójához másik SIM kártya beszerzése érdekében."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"A SIM kártya le van zárva."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"A SIM kártya le van zárva a PUK kóddal."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SIM kártya feloldása..."</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Modul %3$d/%2$d"</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Modul hozzáadása."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Üres"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Feloldási terület kiterjesztve."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Feloldási terület összecsukva."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> modul."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Felhasználóválasztó"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Állapot"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Kamera"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Médiaelemek vezérlője"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"A modulátrendezés elkezdődött."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"A modulátrendezés véget ért."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> modul törölve."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"A feloldási terület kiterjesztése."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Feloldás csúsztatással"</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Feloldás mintával"</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Arcalapú feloldás"</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Feloldás PIN kóddal"</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Feloldás jelszóval"</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Mintaterület"</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Csúsztatási terület"</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Előző szám gomb"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Következő szám gomb"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Szünet gomb"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Lejátszás gomb"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Leállítás gomb"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Mégse"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Kész"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Mód váltása"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Feloldás"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Némítás"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Hang bekapcsolása"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Keresés"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"A(z) <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> művelethez csúsztassa felfelé."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"A(z) <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> művelethez csúsztassa lefelé."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"A(z) <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> művelethez csúsztassa balra."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"A(z) <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> művelethez csúsztassa jobbra."</string>
+    <string name="user_switched" msgid="3768006783166984410">"<xliff:g id="NAME">%1$s</xliff:g> az aktuális felhasználó."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Segélyhívás"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Elfelejtett minta"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Helytelen minta"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Helytelen jelszó"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Helytelen PIN kód"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Próbálkozzon újra <xliff:g id="NUMBER">%d</xliff:g> másodperc múlva."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Rajzolja le a mintát"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Adja meg a SIM kártya PIN kódját"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Adja meg a PIN kódot"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Írja be a jelszót"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"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>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Kívánt PIN kód megadása"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Kívánt PIN kód megerősítése"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM kártya feloldása..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Helytelen PIN kód."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4–8 számjegyű PIN kódot írjon be."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"A PUK kód legalább  8 számjegyből kell, hogy álljon."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Adja meg újra a helyes PUK kódot. Az ismételt próbálkozással véglegesen letiltja a SIM kártyát."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"A PIN kódok nem egyeznek."</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Túl sok mintarajzolási próbálkozás"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"A feloldáshoz jelentkezzen be Google Fiókjával."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Felhasználónév (e-mail cím)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Jelszó"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Bejelentkezés"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Érvénytelen felhasználónév vagy jelszó."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Elfelejtette a felhasználónevét vagy jelszavát?\nKeresse fel a "<b>"google.com/accounts/recovery"</b>" webhelyet."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Fiók ellenőrzése..."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül adta meg PIN kódját. \n\nPróbálja újra <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül adta meg a jelszót. \n\n Próbálja újra <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal rosszul rajzolta le feloldási mintát. \n\nPróbálja újra <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"A táblagépet <xliff:g id="NUMBER_0">%d</xliff:g> alkalommal próbálta meg sikertelenül feloldani. <xliff:g id="NUMBER_1">%d</xliff:g> további sikertelen próbálkozás után a rendszer visszaállítja a táblagép gyári alapértelmezett beállításait, és minden felhasználói adat elvész."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"A telefont <xliff:g id="NUMBER_0">%d</xliff:g> alkalommal próbálta meg sikertelenül feloldani. <xliff:g id="NUMBER_1">%d</xliff:g> további sikertelen próbálkozás után a rendszer visszaállítja a telefon gyári alapértelmezett beállításait, és minden felhasználói adat elvész."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"A táblagépet <xliff:g id="NUMBER">%d</xliff:g> alkalommal próbálta meg sikertelenül feloldani. A rendszer visszaállítja a táblagép gyári alapértelmezett beállításait."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"A telefont <xliff:g id="NUMBER">%d</xliff:g> alkalommal próbálta meg sikertelenül feloldani. A rendszer visszaállítja a telefon gyári alapértelmezett beállításait."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül rajzolta le a feloldási mintát. További <xliff:g id="NUMBER_1">%d</xliff:g> sikertelen kísérlet után egy e-mail fiók használatával kell feloldania a táblagépét.\n\n Kérjük, próbálja újra <xliff:g id="NUMBER_2">%d</xliff:g> másodperc múlva."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül rajzolta le a feloldási mintát. További <xliff:g id="NUMBER_1">%d</xliff:g> sikertelen kísérlet után egy e-mail fiók használatával kell feloldania a telefonját.\n\n Kérjük, próbálja újra <xliff:g id="NUMBER_2">%d</xliff:g> másodperc múlva."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Eltávolítás"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Előző szám gomb"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Következő szám gomb"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Szünet gomb"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Lejátszás gomb"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Leállítás gomb"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Nincs szolgáltatás."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-hy-rAM/strings.xml b/packages/Keyguard/res/values-hy-rAM/strings.xml
new file mode 100644
index 0000000..19b3c79
--- /dev/null
+++ b/packages/Keyguard/res/values-hy-rAM/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Մուտքագրեք PIN կոդը"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Մուտքագրեք PUK-ը և նոր PIN կոդը"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK կոդ"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Նոր PIN ծածկագիր"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><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">"Մուտքագրեք PIN-ը ապակողպման համար"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Սխալ PIN ծածկագիր:"</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Ապակողպման համար սեղմեք Ցանկ, ապա 0:"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Առավելագույն Դեմքով ապակողպման փորձերը գերազանցված են"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Լիցքավորված է"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Լիցքավորում, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Միացրեք ձեր լիցքավորիչը:"</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Ապակողպելու համար սեղմեք Ցանկը:"</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Ցանցը կողպված է"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"SIM քարտ չկա"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Գրասալիկում SIM քարտ չկա:"</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Հեռախոսի մեջ SIM քարտ չկա:"</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Զետեղեք SIM քարտը:"</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM քարտը բացակայում է կամ չի կարող կարդացվել: Մտցրեք SIM քարտ:"</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Անպիտան SIM քարտ:"</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Ձեր SIM քարտը ընդմիշտ կասեցվել է:\nԿապվեք ձեր բջջային ծառայության մատակարարի հետ նոր SIM քարտ ձեռք բերելու համար:"</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM քարտը կողպված է:"</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM քարտը PUK-ով կողպված է:"</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SIM քարտը ապակողպվում է..."</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Վիջեթ %2$d of %3$d:"</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_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>
+    <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_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">"Pin-ն ապակողպված է:"</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="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Նախորդ հետագծի կոճակը"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Հաջորդ հետագծի կոճակը"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Դադարի կոճակ"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Նվագարկման կոճակ"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Կանգի կոճակ"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</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_enter" msgid="2985864015076059467">"Մուտք"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Ապակողպել"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Ֆոտոխցիկ"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Լուռ"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Ձայնը միացնել"</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_down" msgid="5087739728639014595">"Սահեցրեք ցած <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="description_direction_right" msgid="8034433242579600980">"Սահեցրեք աջ` <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-ի համար:"</string>
+    <string name="user_switched" msgid="3768006783166984410">"Ներկայիս օգտվողը <xliff:g id="NAME">%1$s</xliff:g>:"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Արտակարգ իրավիճակի հեռախոսազանգ"</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">"Սխալ PIN"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Փորձեք կրկին <xliff:g id="NUMBER">%d</xliff:g> վայրկյանից:"</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Հավաքեք ձեր սխեման"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Մուտքագրեք SIM-ի PIN-ը"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Մուտքագրեք PIN-ը"</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">"Մուտքագրեք ցանկալի PIN ծածկագիրը"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Հաստատեք ցանկալի PIN ծածկագիրը"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Ապակողպում է SIM քարտը ..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Սխալ PIN ծածկագիր:"</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Մուտքագրեք PIN, որը 4-ից 8 թիվ է:"</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK կոդը պետք է լինի 8 կամ ավելի թիվ:"</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Վերամուտքագրեք ճիշտ PUK ծածկագիրը: Կրկնվող փորձերը ընդմիշտ կկասեցնեն SIM քարտը:"</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN ծածկագրերը չեն համընկնում"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Չափից շատ սխեմայի փորձեր"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Ապակողպելու համար` մուտք գործեք ձեր Google հաշվով:"</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"Հաշիվը ստուգվում է..."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ եք մուտքագրել ձեր PIN-ը: \n\nՓորձեք կրկին <xliff:g id="NUMBER_1">%d</xliff:g> վայրկյանից:"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Դուք սխալ եք մուտքագրել ձեր գաղտնաբառը <xliff:g id="NUMBER_0">%d</xliff:g> անգամ: \n\nՓորձեք կրկին <xliff:g id="NUMBER_1">%d</xliff:g> վայրկյանից:"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ եք հավաքել ձեր ապակողպման սխեման: \n\nՓորձեք կրկին <xliff:g id="NUMBER_1">%d</xliff:g> վայրկյանից:"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ փորձ եք արել գրասալիկն ապակողպելու համար: <xliff:g id="NUMBER_1">%d</xliff:g> անգամից ավել անհաջող փորձերից հետո գրասալիկը կվերակարգավորվի գործարանային լռելյայնի, և օգտվողի բոլոր տվյալները կկորեն:"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ փորձ եք արել հեռախոսն ապակողպելու համար: <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> անգամ: Եվս <xliff:g id="NUMBER_1">%d</xliff:g> անհաջող փորձից հետո ձեզանից կպահանջվի ապակողպել ձեր գրասալիկը` օգտագործելով էլփոստի հաշիվ:\n\n Փորձեք կրկին <xliff:g id="NUMBER_2">%d</xliff:g> վայրկյանից:"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Դուք <xliff:g id="NUMBER_0">%d</xliff:g> անգամ սխալ եք հավաքել ձեր ապակողպման նմուշը: <xliff:g id="NUMBER_1">%d</xliff:g> անգամից ավել անհաջող փորձերից հետո ձեզ կառաջարկվի ապակողպել ձեր հեռախոսը` օգտագործելով էլփոստի հաշիվ:\n\n Փորձեք կրկին <xliff:g id="NUMBER_2">%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="keyguard_transport_prev_description" msgid="8229108430245669854">"Նախորդ հետագծի կոճակ"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Հաջորդ հետագծի կոճակ"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Դադարի կոճակ"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Նվագարկման կոճակ"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Դադարի կոճակ"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Ծառայություն չկա:"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-in/activitystrings.xml b/packages/Keyguard/res/values-in/activitystrings.xml
new file mode 100644
index 0000000..ec9774d
--- /dev/null
+++ b/packages/Keyguard/res/values-in/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Tanpa pengamanan"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Sandi"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Pola"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"PIN SIM"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"PUK SIM"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Pilih widget..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-in/strings.xml b/packages/Keyguard/res/values-in/strings.xml
new file mode 100644
index 0000000..9f731ab
--- /dev/null
+++ b/packages/Keyguard/res/values-in/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Ketik kode PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Ketik kode PUK dan PIN baru"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Kode PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Kode Pin baru"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Sentuh untuk mengetikkan sandi"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Ketik sandi untuk membuka kunci"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Ketik PIN untuk membuka kunci"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Kode PIN salah."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Untuk membuka, tekan Menu lalu 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Percobaan Face Unlock melebihi batas maksimum"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Terisi"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Mengisi baterai, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Hubungkan pengisi daya."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Tekan Menu untuk membuka."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Jaringan terkunci"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Tidak ada kartu SIM"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Tidak ada kartu SIM dalam tablet."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Tidak ada Kartu SIM di dalam ponsel."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Masukkan kartu SIM."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"Kartu SIM tidak ada atau tidak dapat dibaca. Masukkan kartu SIM."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Kartu SIM tidak dapat digunakan."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Kartu SIM Anda telah dinonaktifkan secara permanen.\n Hubungi penyedia layanan nirkabel Anda untuk kartu SIM lain."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"Kartu SIM terkunci."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"Kartu SIM terkunci PUK."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Membuka kartu SIM…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d dari %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Tambahkan widget."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Kosong"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Area buka kunci diluaskan."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Area buka kunci diciutkan."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Pemilih pengguna"</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">"Kontrol media"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Pengurutan ulang widget dimulai."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Pengurutan ulang widget berakhir."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> dihapus."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Luaskan area buka kunci."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Buka kunci dengan menggeser."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Buka kunci dengan pola."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Buka kunci dengan face unlock."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Buka kunci dengan PIN."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Buka kunci dengan sandi."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Area pola."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Area geser."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Tombol lagu sebelumnya"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Tombol lagu berikutnya"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Tombol jeda"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Tombol putar"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Tombol hentikan"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Batal"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Hapus"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Selesai"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Pengubahan mode"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Membuka gembok"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Senyap"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Suara hidup"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Telusuri"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Geser ke atas untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Geser ke bawah untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Geser ke kiri untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Geser ke kanan untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Pengguna saat ini <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Panggilan darurat"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Lupa Pola?"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Pola Salah"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Sandi Salah"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN Salah"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Coba lagi dalam <xliff:g id="NUMBER">%d</xliff:g> detik."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Gambar pola Anda"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Masukkan PIN SIM"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Masukkan PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Masukkan Sandi"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM telah dinonaktifkan. Masukkan kode PUK untuk melanjutkan. Hubungi operator untuk keterangan selengkapnya."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Masukkan kode PIN yang diinginkan"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Konfirmasi kode PIN yang diinginkan"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Membuka kunci kartu SIM…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Kode PIN salah."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Ketik PIN yang terdiri dari 4 sampai 8 angka."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Kode PUK harus terdiri dari 8 angka atau lebih."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Masukkan kembali kode PUK yang benar. Jika berulang kali gagal, SIM akan dinonaktifkan secara permanen."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Kode PIN tidak cocok"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Terlalu banyak upaya pola"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Untuk membuka kunci, masuk dengan akun Google Anda."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Nama pengguna (email)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Sandi"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Masuk"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nama pengguna atau sandi tidak valid."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Lupa nama pengguna atau sandi Anda?\nKunjungi "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Memeriksa akun…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah mengetik PIN. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> detik."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah mengetik sandi. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> detik."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. \n\nCoba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> detik."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali gagal saat berusaha membuka kunci tablet. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, tablet akan disetel ulang ke setelan default pabrik dan semua data pengguna akan hilang."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali gagal saat berusaha membuka kunci ponsel. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, ponsel akan disetel ulang ke setelan default pabrik dan semua data pengguna akan hilang."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali gagal saat berusaha membuka kunci tablet. Kini tablet akan disetel ulang ke setelan default pabrik."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali gagal saat berusaha untuk membuka kunci ponsel. Kini ponsel akan disetel ulang ke setelan default pabrik."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci tablet menggunakan akun email.\n\nCoba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> detik."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci ponsel menggunakan akun email.\n\nCoba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> detik."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Hapus"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Tombol lagu sebelumnya"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Tombol lagu berikutnya"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Tombol jeda"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Tombol putar"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Tombol hentikan"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Tidak ada layanan."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-it/activitystrings.xml b/packages/Keyguard/res/values-it/activitystrings.xml
new file mode 100644
index 0000000..34ad96497
--- /dev/null
+++ b/packages/Keyguard/res/values-it/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Nessuna sicurezza"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Password"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Sequenza"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"PIN della SIM"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"PUK della SIM"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Scegli widget..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-it/strings.xml b/packages/Keyguard/res/values-it/strings.xml
new file mode 100644
index 0000000..4eda348
--- /dev/null
+++ b/packages/Keyguard/res/values-it/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Inserisci il codice PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Inserisci il PUK e il nuovo codice PIN"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Codice PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Nuovo codice PIN"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Tocca per inserire la password"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Inserisci password per sbloccare"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Inserisci PIN per sbloccare"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Codice PIN errato."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Per sbloccare, premi Menu, poi 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Numero massimo di tentativi di Sblocco col sorriso superato"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Carico"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"In carica (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Collega il caricabatterie."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Premi Menu per sbloccare."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Rete bloccata"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Nessuna scheda SIM"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Nessuna scheda SIM presente nel tablet."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Nessuna scheda SIM presente nel telefono."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Inserisci una scheda SIM."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"Scheda SIM mancante o non leggibile. Inserisci una scheda SIM."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Scheda SIM inutilizzabile."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"La scheda SIM è stata disattivata definitivamente.\n Contatta il fornitore del tuo servizio wireless per ricevere un\'altra scheda SIM."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"La SIM è bloccata."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"La SIM è bloccata tramite PUK."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Sblocco scheda SIM..."</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d di %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Aggiungi widget."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Vuoto"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Area di sblocco estesa."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Area di sblocco compressa."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> widget."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Selettore utente"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Stato"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Fotocamera"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Controlli media"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Riordino dei widget iniziato."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Riordino dei widget terminato."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> eliminato."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Espandi area di sblocco."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Sblocco con scorrimento."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Sblocco con sequenza."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Sblocco col sorriso."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Sblocco con PIN."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Sblocco con password."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Area sequenza."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Area di scorrimento."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Pulsante traccia precedente"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Pulsante traccia successiva"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Pulsante Pausa"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Pulsante Riproduci"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Pulsante di arresto"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Annulla"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Canc"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Fine"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Cambio modalità"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Maiuscolo"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Invio"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Sblocca"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Fotocamera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Silenzioso"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Audio attivato"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Ricerca"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Su per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Giù per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"A sinistra per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"A destra per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Utente corrente <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Chiamata di emergenza"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Sequenza dimenticata"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Sequenza sbagliata"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Password sbagliata"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN errato"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Riprova fra <xliff:g id="NUMBER">%d</xliff:g> secondi."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Inserisci la sequenza"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Inserisci il PIN della SIM"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Inserisci PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Inserisci la password"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"La scheda SIM è disattivata. Inserisci il codice PUK per continuare. Contatta l\'operatore per avere informazioni dettagliate."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Inserisci il codice PIN desiderato"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Conferma il codice PIN desiderato"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Sblocco scheda SIM..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Codice PIN errato."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Il PIN deve essere di 4-8 numeri."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Il codice PUK dovrebbe avere almeno otto numeri."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Inserisci di nuovo il codice PUK corretto. Ripetuti tentativi comportano la disattivazione definitiva della scheda SIM."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"I codici PIN non corrispondono"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Troppi tentativi di inserimento della sequenza"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Per sbloccare, accedi con il tuo account Google."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Nome utente (email)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Password"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Accedi"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nome utente o password non validi."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Hai dimenticato il nome utente o la password?\nVisita "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Controllo account…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Hai digitato il tuo PIN <xliff:g id="NUMBER_0">%d</xliff:g> volte in modo errato. \n\nRiprova tra <xliff:g id="NUMBER_1">%d</xliff:g> secondi."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Hai digitato la tua password <xliff:g id="NUMBER_0">%d</xliff:g> volte in modo errato. \n\nRiprova tra <xliff:g id="NUMBER_1">%d</xliff:g> secondi."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. \n\nRiprova tra <xliff:g id="NUMBER_1">%d</xliff:g> secondi."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di sblocco del tablet. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, il tablet verrà sottoposto a un ripristino dei dati di fabbrica e tutti i dati utente andranno persi."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di sblocco del telefono. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, il telefono verrà sottoposto a un ripristino dei dati di fabbrica e tutti i dati utente andranno persi."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"<xliff:g id="NUMBER">%d</xliff:g> tentativi errati di sblocco del tablet. Il tablet verrà sottoposto a un ripristino dei dati di fabbrica."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"<xliff:g id="NUMBER">%d</xliff:g> tentativi errati di sblocco del telefono. Il telefono verrà sottoposto a un ripristino dei dati di fabbrica."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il tablet con un account email.\n\n Riprova tra <xliff:g id="NUMBER_2">%d</xliff:g> secondi."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il telefono con un account email.\n\n Riprova tra <xliff:g id="NUMBER_2">%d</xliff:g> secondi."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Rimuovi"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Pulsante traccia precedente"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Pulsante traccia successiva"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Pulsante Pausa"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Pulsante Riproduci"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Pulsante di arresto"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Nessun servizio."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-iw/activitystrings.xml b/packages/Keyguard/res/values-iw/activitystrings.xml
new file mode 100644
index 0000000..84e351a2
--- /dev/null
+++ b/packages/Keyguard/res/values-iw/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"ללא אבטחה"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"סיסמה"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"קו ביטול נעילה"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"PIN של SIM"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"PUK של SIM"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"בחר Widget..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-iw/strings.xml b/packages/Keyguard/res/values-iw/strings.xml
new file mode 100644
index 0000000..c12a0e8
--- /dev/null
+++ b/packages/Keyguard/res/values-iw/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"הקלד קוד PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"הקלד את קוד ה-PUK וקוד  ה-PIN החדש"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"קוד PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"קוד PIN חדש"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><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">"הקלד קוד PIN לביטול הנעילה"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"קוד PIN שגוי"</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"כדי לבטל את הנעילה, לחץ על \'תפריט\' ולאחר מכן על 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"חרגת ממספר הניסיונות המרבי של זיהוי פנים"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"טעון"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"טוען, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"חבר את המטען."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"לחץ על \'תפריט\' כדי לבטל את הנעילה."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"רשת נעולה"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"אין כרטיס SIM"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"אין כרטיס SIM בטאבלט."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"אין כרטיס SIM בטלפון."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"הכנס כרטיס SIM."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"כרטיס ה-SIM חסר או שלא ניתן לקרוא אותו. הכנס כרטיס SIM."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"לא ניתן להשתמש בכרטיס SIM זה."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"כרטיס ה-SIM שלך הושבת לצמיתות.\nפנה לספק השירות האלחוטי שלך לקבלת כרטיס SIM אחר."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"כרטיס ה-SIM נעול."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"כרטיס SIM נעול באמצעות PUK."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"מבטל נעילה של כרטיס SIM…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d מתוך %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"הוסף Widget."</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_widget" msgid="6527131039741808240">"Widget ‏<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>
+    <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">"סידור מחדש של Widgets התחיל."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"סידור מחדש של Widgets הסתיים."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget ‏<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">"ביטול נעילה באמצעות מספר PIN."</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="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"לחצן \'הרצועה הקודמת\'"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"לחצן \'הרצועה הבאה\'"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"לחצן \'השהה\'"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"לחצן \'הפעל\'"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"לחצן \'הפסק\'"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"אבג"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</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_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"בטל נעילה"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"מצלמה"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"שקט"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"הקול פועל"</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_down" msgid="5087739728639014595">"הסט למטה כדי להציג <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="description_direction_right" msgid="8034433242579600980">"הסט ימינה כדי להציג <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"המשתמש הנוכחי <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"שיחת חירום"</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">"מספר PIN שגוי"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"נסה שוב בעוד <xliff:g id="NUMBER">%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>
+    <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">"הזן את קוד ה-PIN הרצוי"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"אשר את קוד ה-PIN הרצוי"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"מבטל נעילה של כרטיס SIM…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"קוד PIN שגוי."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"הקלד מספר PIN שאורכו 4 עד 8 ספרות."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"קוד PUK צריך להיות בן 8 ספרות או יותר."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"הזן מחדש את קוד PUK הנכון. ניסיונות חוזרים ישביתו לצמיתות את כרטיס ה-SIM."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"קודי ה-PIN אינם תואמים"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ניסיונות רבים מדי לשרטוט קו ביטול נעילה."</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"כדי לבטל את הנעילה, היכנס באמצעות חשבון Google שלך."</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"בודק חשבון…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"הקלדת מספר PIN שגוי <xliff:g id="NUMBER_0">%d</xliff:g> פעמים. \n\nנסה שוב בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"הקלדת סיסמה שגויה <xliff:g id="NUMBER_0">%d</xliff:g> פעמים.\n\nנסה שוב בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"שרטטת את קו ביטול הנעילה באופן שגוי <xliff:g id="NUMBER_0">%d</xliff:g> פעמים. \n\nנסה שוב בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"ביצעת <xliff:g id="NUMBER_0">%d</xliff:g> ניסיונות שגויים לביטול נעילת הטלפון. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, הטאבלט יעבור איפוס לברירת המחדל של היצרן וכל נתוני המשתמש יאבדו."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"ביצעת <xliff:g id="NUMBER_0">%d</xliff:g> ניסיונות שגויים לביטול נעילת הטלפון. לאחר <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטאבלט באמצעות חשבון דוא\"ל‏.\n\nנסה שוב בעוד <xliff:g id="NUMBER_2">%d</xliff:g> שניות."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"שרטטת את קו ביטול הנעילה באופן שגוי <xliff:g id="NUMBER_0">%d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטלפון באמצעות חשבון דוא\"ל‏.\n\nנסה שוב בעוד <xliff:g id="NUMBER_2">%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="keyguard_transport_prev_description" msgid="8229108430245669854">"לחצן \'הרצועה הקודמת\'"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"לחצן \'הרצועה הבאה\'"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"לחצן \'השהה\'"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"לחצן \'הפעל\'"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"לחצן \'הפסק\'"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"אין קליטה."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-ja/activitystrings.xml b/packages/Keyguard/res/values-ja/activitystrings.xml
new file mode 100644
index 0000000..b0e77f1
--- /dev/null
+++ b/packages/Keyguard/res/values-ja/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"セキュリティなし"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"パスワード"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"パターン"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"SIM PIN"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"SIM PUK"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"ウィジェットを選択..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-ja/strings.xml b/packages/Keyguard/res/values-ja/strings.xml
new file mode 100644
index 0000000..92e308b
--- /dev/null
+++ b/packages/Keyguard/res/values-ja/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PINコードを入力"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUKと新しいPINコードを入力"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUKコード"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"新しいPINコード"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><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">"ロックを解除するにはPINを入力"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PINコードが正しくありません。"</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"MENU、0キーでロック解除"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"フェイスアンロックの最大試行回数を超えました"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"充電完了"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"充電中: <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"充電してください。"</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"メニューからロックを解除できます。"</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"ネットワークがロックされました"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"SIMカードが挿入されていません"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"タブレット内にSIMカードがありません。"</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"SIMカードが端末に挿入されていません。"</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"SIMカードを挿入してください。"</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIMカードが見つからないか読み取れません。SIMカードを挿入してください。"</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"SIMカードは使用できません。"</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"お使いのSIMカードは永久に無効となっています。\nワイヤレスサービスプロバイダに問い合わせて新しいSIMカードを入手してください。"</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIMカードはロックされています。"</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIMカードはPUKでロックされています。"</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SIMカードをロック解除しています…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s。ウィジェット%2$d/%3$d。"</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_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>
+    <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_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">"PINロックを解除します。"</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="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"前のトラックボタン"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"次のトラックボタン"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"一時停止ボタン"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"再生ボタン"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"停止ボタン"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</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_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"ロックを解除"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"カメラ"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"マナーモード"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"サウンドON"</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_down" msgid="5087739728639014595">"下にスライドして<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="description_direction_right" msgid="8034433242579600980">"右にスライドして<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>を行います。"</string>
+    <string name="user_switched" msgid="3768006783166984410">"現在のユーザーは<xliff:g id="NAME">%1$s</xliff:g>です。"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"緊急通報"</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">"PINが正しくありません"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%d</xliff:g>秒後にもう一度お試しください。"</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"パターンを入力"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM PINを入力"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"PINを入力"</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">"希望のPINコードを入力してください"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"希望のPINコードを確認してください"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIMカードのロック解除中…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"PINコードが正しくありません。"</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"PINは4~8桁の数字で入力してください。"</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUKコードは8桁以上の番号です。"</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"正しいPUKコードを再入力してください。誤入力を繰り返すと、SIMが永久に無効になるおそれがあります。"</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PINコードが一致しません"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"パターンの入力を所定の回数以上間違えました。"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"ロックを解除するにはGoogleアカウントでログインしてください。"</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"アカウントをチェックしています…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PINの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。\n\n<xliff:g id="NUMBER_1">%d</xliff:g>秒後にもう一度お試しください。"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"パスワードの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。\n\n<xliff:g id="NUMBER_1">%d</xliff:g>秒後にもう一度お試しください。"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"ロック解除パターンの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。\n\n<xliff:g id="NUMBER_1">%d</xliff:g>秒後にもう一度お試しください。"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"タブレットのロック解除に<xliff:g id="NUMBER_0">%d</xliff:g>回失敗しました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回失敗すると、タブレットは出荷時設定にリセットされ、ユーザーのデータはすべて失われます。"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"携帯端末のロック解除に<xliff:g id="NUMBER_0">%d</xliff:g>回失敗しました。あと<xliff:g id="NUMBER_1">%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="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">%d</xliff:g>回間違えました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回間違えると、タブレットのロック解除にメールアカウントが必要になります。\n\n<xliff:g id="NUMBER_2">%d</xliff:g>秒後にもう一度お試しください。"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"ロック解除パターンの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回間違えると、携帯端末のロック解除にメールアカウントが必要になります。\n\n<xliff:g id="NUMBER_2">%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="keyguard_transport_prev_description" msgid="8229108430245669854">"前のトラックボタン"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"次のトラックボタン"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"一時停止ボタン"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"再生ボタン"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"停止ボタン"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"通信サービスはありません。"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-ka-rGE/strings.xml b/packages/Keyguard/res/values-ka-rGE/strings.xml
new file mode 100644
index 0000000..b901bf4
--- /dev/null
+++ b/packages/Keyguard/res/values-ka-rGE/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"აკრიფეთ PIN კოდი"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"დაბეჭდეთ PUK კოდი და ახალი PIN კოდი."</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK კოდი"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"ახალი PIN კოდი"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384">"შეეხეთ "<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">"განსაბლოკად აკრიფეთ PIN კოდი"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"არასწორი PIN კოდი."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"განბლოკვისათვის დააჭირეთ მენიუს და შემდეგ 0-ს."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"სახის ამოცნობით განბლოკვის მცდელობამ დაშვებულ რაოდენობას გადააჭარბა"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"დამუხტულია"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"მიმდინარეობს დამუხტვა (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"შეაერთეთ დამტენი."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"განბლოკვისთვის დააჭირეთ მენიუს."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"ქსელი ჩაკეტილია"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"SIM ბარათი არ არის"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"ტაბლეტში არ დევს SIM ბარათი."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"არ არის SIM ბარათი ტელეფონში."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"ჩადეთ SIM ბარათი."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM ბარათი არ არის ან არ იკითხება. ჩადეთ SIM ბარათი."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"არამოხმარებადი SIM ბარათი."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"თქვენი SIM ბარათი გამუდმებით გამორთული იყო.\n დაუკავშირდით თქვენი უკაბელო სერვისის პროვაიდერს სხვა SIM ბარათისთვის."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM ბარათი დაბლოკილია."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM ბარათი დაბლოკილია PUK კოდით."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"მიმდინარეობს SIM ბარათის განბლოკვა…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. ვიჯეტი %2$d of %3$d."</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_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>
+    <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_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">"განბლოკვა Pin-ით."</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="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"წინა ჩანაწერის ღილაკი"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"შემდეგი ჩანაწერის ღილაკი"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"პაუზის ღილაკი"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"დაკვრის ღილაკი"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Stop ღილაკი"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</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_enter" msgid="2985864015076059467">"შეყვანა"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"განბლოკვა"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"კამერა"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"უხმო"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"ხმის ჩართვა"</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_down" msgid="5087739728639014595">"გაასრიალეთ ქვემოთ <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="description_direction_right" msgid="8034433242579600980">"გაასრიალეთ მარჯვნივ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-თვის."</string>
+    <string name="user_switched" msgid="3768006783166984410">"ამჟამინდელი მომხმარებელი <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"გადაუდებელი დახმარების ზარი"</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">"არასწორი PIN"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"კიდევ სცადეთ <xliff:g id="NUMBER">%d</xliff:g> წამში."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"დახატეთ თქვენი ნიმუში."</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM PIN-ის შეყვანა"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"შეიყვანეთ PIN"</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">"სასურველი PIN კოდის შეყვანა"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"სასურველი PIN კოდის დადასტურება"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM ბარათის განბლოკვა…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"არასწორი PIN კოდი."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"აკრიფეთ PIN, რომელიც შედგება 4-დან 8 ციფრამდე."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK კოდი უნდა იყოს რვა ან მეტი ციფრისგან შემდგარი."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"ხელახლა შეიყვანეთ სწორი PUK კოდი. რამდენიმე წარუმატებელი მცდელობა გამოიწვევს SIM ბარათის დაბლოკვას."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN კოდები არ ემთხვევა"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ნახატი ნიმუშის ძალიან ბევრი მცდელობა"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"განბლოკვისთვის გაიარეთ ავტორიზაცია თქვენი Google  ანგარიშით."</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"მიმდინარეობს ანგარიშის შემოწმება…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"თქვენ <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ არასწორად შეიყვანეთ PIN კოდი. \n\nსცადეთ ხელახლა <xliff:g id="NUMBER_1">%d</xliff:g> წამში."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"თქვენ <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ არასწორად დაბეჭდეთ თქვენი პაროლი. \n\nხელახლა სცადეთ <xliff:g id="NUMBER_1">%d</xliff:g> წამში."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"თქვენ <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ დახატეთ განბლოკვის ნიმუში. \n\nსცადეთ ხელახლა <xliff:g id="NUMBER_1">%d</xliff:g> წამში."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"თქვენ არასწორად სცადეთ ტაბლეტის განბლოკვა <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%d</xliff:g> წარუმატებელი ცდის შემდეგ ტაბლეტზე დაყენდება საწყისი, ქარხნული პარამეტრები და მომხმარებლის ყველა მონაცემი დაიკარგება."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"თქვენ არასწორად სცადეთ ტელეფონის განბლოკვა <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> ჯერ. კიდევ <xliff:g id="NUMBER_1">%d</xliff:g> წარუმატებელი ცდის შემდეგ მოგთხოვთ ტაბლეტის განბლოკვას ელფოსტის ანგარიშის გამოყენებით.\n\n ხელახლა სცადეთ <xliff:g id="NUMBER_2">%d</xliff:g> წამში."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"თქვენ არასწორად დახატეთ თქვენი განბლოკვის ნიმუში <xliff:g id="NUMBER_0">%d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%d</xliff:g> წარუმატებელი ცდის შემდეგ, დაგჭირდებათ თქვენი ტელეფონის განბლოკვა ელფოსტის ანგარიშის გამოყენებით.\n\n ხელახლა სცადეთ <xliff:g id="NUMBER_2">%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="keyguard_transport_prev_description" msgid="8229108430245669854">"წინა ჩანაწერზე გადასვლის ღილაკი"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"შემდეგი ჩანაწერის ღილაკი"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"პაუზის ღილაკი"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"დაკვრის ღილაკი"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"შეჩერების ღილაკი"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"არ არის სერვისი."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-km-rKH/strings.xml b/packages/Keyguard/res/values-km-rKH/strings.xml
new file mode 100644
index 0000000..586169e
--- /dev/null
+++ b/packages/Keyguard/res/values-km-rKH/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"បញ្ចូល​កូដ PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"បញ្ចូល​កូដ PUK និង​ PIN ថ្មី"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"កូដ PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"កូដ PIN ថ្មី"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><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">"បញ្ចូល​កូដ PIN ដើម្បី​ដោះ​សោ"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"កូដ PIN មិន​ត្រឹមត្រូវ។"</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"ដើម្បី​ដោះ​សោ​​ ចុច​ម៉ឺនុយ​ បន្ទាប់មក 0 ។"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"បាន​លើស​ការ​ព្យាយាម​ដោះ​សោ​តាម​ទម្រង់​មុខ"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"បាន​បញ្ចូល​​ពេញ"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"បញ្ចូល​ថ្ម <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"ភ្ជាប់​ឧបករណ៍​បញ្ចូល​ថ្ម​។"</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"ចុច​ម៉ឺនុយ ដើម្បី​ដោះ​សោ។"</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"បណ្ដាញ​ជាប់​សោ"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"គ្មាន​ស៊ី​ម​កាត"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"គ្មាន​ស៊ី​ម​កាត​នៅ​ក្នុង​កុំព្យូទ័រ​បន្ទះ​។"</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"គ្មាន​ស៊ីមកាត​ក្នុង​ទូរស័ព្ទ។"</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"បញ្ចូល​​​ស៊ី​ម​កាត​។"</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"បាត់​ស៊ីមកាត ឬ​មិន​អាច​អាន។ បញ្ចូល​ស៊ីម​កាត។"</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"ស៊ីម​កាត​មិន​អាច​ប្រើ​បាន។"</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"បាន​បិទ​ស៊ីម​កាត​របស់​អ្នក​ជា​អចិន្ត្រៃយ៍។\n ទាក់ទង​​ក្រុមហ៊ុន​ផ្ដល់​សេវាកម្ម​ឥត​ខ្សែ​សម្រាប់​ស៊ីម​កាត​ផ្សេង។"</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"ស៊ីម​កាត​​ជាប់​សោ។"</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"ស៊ីម​កាត​ជាប់​កូដ​​ PUK ។"</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"កំពុង​ដោះ​សោ​ស៊ីម​កាត..."</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. ធាតុ​ក្រាហ្វិក %2$d នៃ %3$d ។"</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_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>
+    <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_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">"កូដ PIN ដោះ​សោ។"</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="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"ប៊ូតុង​បទ​មុន"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"ប៊ូតុង​បទ​បន្ទាប់"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"ប៊ូតុង​ផ្អាក"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"ប៊ូតុង​ចាក់"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"ប៊ូតុង​បញ្ឈប់"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</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_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"ដោះ​​សោ"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"ម៉ាស៊ីន​ថត"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"ស្ងាត់"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"បើក​សំឡេង"</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_down" msgid="5087739728639014595">"រុញ​ចុះក្រោម​សម្រាប់ <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="description_direction_right" msgid="8034433242579600980">"រុញ​​ទៅ​ស្ដាំ​ដើម្បី <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string>
+    <string name="user_switched" msgid="3768006783166984410">"អ្នក​ប្រើ​បច្ចុប្បន្ន <xliff:g id="NAME">%1$s</xliff:g> ។"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"ការ​ហៅ​ពេល​អាសន្ន"</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">"កូដ PIN មិន​ត្រឹមត្រូវ"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER">%d</xliff:g> វិនាទី។"</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"គូរ​លំនាំ​របស់​អ្នក"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"បញ្ចូល​កូដ PIN ស៊ីម​កាត"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"បញ្ចូល​​កូដ PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"បញ្ចូល​ពាក្យ​សម្ងាត់"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"ឥឡូវ​ស៊ីមកាត​ត្រូវ​បាន​បិទ។ បញ្ចូល​កូដ PUK ដើម្បី​បន្ត។ ចំពោះ​ព័ត៌មាន​លម្អិត​ទាក់ទង​ក្រុមហ៊ុន​បញ្ជូន​របស់​អ្នក។"</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"បញ្ចូល​កូដ PIN ដែល​ចង់​បាន"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"បញ្ជាក់​កូដ PIN ដែល​ចង់​បាន"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"កំពុង​ដោះ​សោ​​ស៊ីម​កាត..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"កូដ PIN មិន​ត្រឹមត្រូវ។"</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"បញ្ចូល​កូដ PIN ដែល​មាន​ពី ៤ ដល់ ៨ លេខ។"</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"កូដ PUK គួរ​តែ​មាន​​ ៨ លេខ ឬ​​ច្រើន​ជាង​នេះ។"</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"បញ្ចូល​កូដ PUK ម្ដង​ទៀត។ ការ​ព្យាយាម​ដដែល​ច្រើន​ដឹង​នឹង​បិទ​ស៊ីម​កាត​ជា​អចិន្ត្រៃយ៍។"</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"កូដ PIN មិន​ដូច​គ្នា"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ព្យាយាម​លំនាំ​ច្រើន​ពេក"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"ដើម្បី​ដោះ​សោ ចូល​ក្នុង​គណនី Google ។"</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"កំពុង​ពិនិត្យ​មើល​គណនី..."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"អ្នក​បាន​បញ្ចូល​កូដ PIN របស់​អ្នក​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។\n\n ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_1">%d</xliff:g> វិនាទី។"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"អ្នក​បាន​បញ្ចូល​ពាក្យ​សម្ងាត់​មិន​ត្រឹមត្រូវ <xliff:g id="NUMBER_0">%d</xliff:g> ដង។\n\nព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_1">%d</xliff:g> វិនាទី។"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"អ្នក​បាន​​គូរ​លំនាំ​ដោះ​សោ​របស់​អ្នក​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។\n\nព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_1">%d</xliff:g> វិនាទី។"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"អ្នក​បាន​ព្យាយាម​ដោះ​សោ​​កុំព្យូទ័រ​បន្ទះ​​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម​មិន​ជោគជ័យ​​ច្រើន​ជាង <xliff:g id="NUMBER_1">%d</xliff:g> ដង កុំព្យូទ័រ​បន្ទះ​​នឹង​ត្រូវ​បាន​កំណត់​ទៅ​លំនាំដើម​ដូច​ចេញ​ពី​រោងចក្រ ហើយ​ទិន្នន័យ​អ្នកប្រើ​នឹង​បាត់បង់។"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"អ្នក​បាន​ព្យាយាម​ដោះ​សោ​ទូរស័ព្ទ​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម​មិន​ជោគជ័យ​​ច្រើន​ជាង <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម <xliff:g id="NUMBER_1">%d</xliff:g> ដង​មិន​ជោគជ័យ អ្នក​នឹង​ត្រូវ​បាន​ស្នើ​ឲ្យ​ដោះ​សោ​កុំព្យូទ័រ​បន្ទះ​របស់​អ្នក ដោយ​ប្រើ​គណនី​អ៊ីមែល។\n\n ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_2">%d</xliff:g> វិនាទី។"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"អ្នក​បាន​គូរ​លំនាំ​ដោះ​​សោ​របស់​អ្នក​មិន​ត្រឹមត្រូវ​ចំនួន <xliff:g id="NUMBER_0">%d</xliff:g> ដង។ បន្ទាប់​ពី​ការ​ព្យាយាម​មិន​ជោគជ័យ​​ច្រើនជាង <xliff:g id="NUMBER_1">%d</xliff:g> ដង អ្នក​នឹង​ត្រូវ​បាន​​ស្នើ​ឲ្យ​ដោះ​សោ​ទូរស័ព្ទ​របស់​អ្នក​ដោយ​ប្រើ​គណនី​អ៊ីមែល។\n\n ព្យាយាម​ម្ដង​ទៀត​ក្នុង​រយៈ​ពេល <xliff:g id="NUMBER_2">%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="keyguard_transport_prev_description" msgid="8229108430245669854">"ប៊ូតុង​បទ​មុន"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"ប៊ូតុង​បទ​បន្ទាប់"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"ប៊ូតុង​ផ្អាក"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"ប៊ូតុង​ចាក់"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"ប៊ូតុង​បញ្ឈប់"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"គ្មាន​សេវា​។"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-ko/activitystrings.xml b/packages/Keyguard/res/values-ko/activitystrings.xml
new file mode 100644
index 0000000..3aab225
--- /dev/null
+++ b/packages/Keyguard/res/values-ko/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"보안 사용 안함"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"비밀번호"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"패턴"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"SIM PIN"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"SIM PUK"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"위젯 선택..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-ko/strings.xml b/packages/Keyguard/res/values-ko/strings.xml
new file mode 100644
index 0000000..dfac106
--- /dev/null
+++ b/packages/Keyguard/res/values-ko/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN 코드 입력"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK 및 새 PIN 코드 입력"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK 코드"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"새 PIN 코드"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><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">"잠금을 해제하려면 PIN 입력"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PIN 코드가 잘못되었습니다."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"잠금해제하려면 메뉴를 누른 다음 0을 누릅니다."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"얼굴 인식 잠금해제 최대 시도 횟수를 초과했습니다."</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"충전됨"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"충전 중(<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"충전기를 연결하세요."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"잠금해제하려면 메뉴를 누르세요."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"네트워크 잠김"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"SIM 카드가 없습니다."</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"태블릿에 SIM 카드가 없습니다."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"휴대전화에 SIM 카드가 없습니다."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"SIM 카드를 삽입하세요."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM 카드가 없거나 읽을 수 없습니다. SIM 카드를 삽입하세요."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"사용할 수 없는 SIM 카드입니다."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"SIM 카드를 완전히 사용할 수 없게 되었습니다.\n다른 SIM 카드를 사용하려면 무선 서비스 제공업체에 문의하시기 바랍니다."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM 카드가 잠겨 있습니다."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM 카드가 PUK 잠김 상태입니다."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SIM 카드 잠금해제 중..."</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_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_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>
+    <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_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="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"이전 트랙 버튼"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"다음 트랙 버튼"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"일시중지 버튼"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"재생 버튼"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"중지 버튼"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</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">"Delete 키"</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_enter" msgid="2985864015076059467">"Enter 키"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"잠금 해제"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"카메라"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"무음"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"사운드 켜기"</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_down" msgid="5087739728639014595">"<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="description_direction_right" msgid="8034433242579600980">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 오른쪽으로 슬라이드"</string>
+    <string name="user_switched" msgid="3768006783166984410">"현재 사용자는 <xliff:g id="NAME">%1$s</xliff:g>님입니다."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"긴급 통화"</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">"잘못된 PIN"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%d</xliff:g>초 후에 다시 시도해 주세요."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"패턴 그리기"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM PIN 입력"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN 입력"</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">"원하는 PIN 코드 입력"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"원하는 PIN 코드 확인"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM 카드 잠금해제 중..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"PIN 코드가 잘못되었습니다."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4~8자리 숫자로 된 PIN을 입력하세요."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK 코드는 8자리 이상의 숫자여야 합니다."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"올바른 PUK 코드를 다시 입력하세요. 입력을 반복해서 시도하면 SIM을 영구적으로 사용할 수 없게 됩니다."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN 코드가 일치하지 않음"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"패턴 시도 횟수가 너무 많음"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"잠금해제하려면 Google 계정으로 로그인하세요."</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"계정 확인 중…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 입력했습니다. \n\n<xliff:g id="NUMBER_1">%d</xliff:g>초 후에 다시 시도해 주세요."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"비밀번호를 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 입력했습니다. \n\n<xliff:g id="NUMBER_1">%d</xliff:g>초 후에 다시 시도해 주세요."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 그렸습니다. \n\n<xliff:g id="NUMBER_1">%d</xliff:g>초 후에 다시 시도해 주세요."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"태블릿을 잠금해제하려는 시도가 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못되었습니다. <xliff:g id="NUMBER_1">%d</xliff:g>회 더 실패하면 태블릿이 초기화되고 사용자 데이터가 모두 사라집니다."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"휴대전화를 잠금해제하려는 시도가 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못되었습니다. <xliff:g id="NUMBER_1">%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="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">%d</xliff:g>회 잘못 그렸습니다. <xliff:g id="NUMBER_1">%d</xliff:g>회 더 실패하면 이메일 계정을 사용하여 태블릿을 잠금해제해야 합니다.\n\n <xliff:g id="NUMBER_2">%d</xliff:g>초 후에 다시 시도해 주세요."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 그렸습니다. <xliff:g id="NUMBER_1">%d</xliff:g>회 더 실패하면 이메일 계정을 사용하여 휴대전화를 잠금해제해야 합니다.\n\n <xliff:g id="NUMBER_2">%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="keyguard_transport_prev_description" msgid="8229108430245669854">"이전 트랙 버튼"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"다음 트랙 버튼"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"일시중지 버튼"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"재생 버튼"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"중지 버튼"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"서비스 불가"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-land/alias.xml b/packages/Keyguard/res/values-land/alias.xml
new file mode 100644
index 0000000..7aac5b4
--- /dev/null
+++ b/packages/Keyguard/res/values-land/alias.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/colors.xml
+**
+** 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.
+*/
+-->
+<resources>
+    <!-- Alias used to reference one of two possible layouts in keyguard.  -->
+    <item type="layout" name="keyguard_eca">@layout/keyguard_emergency_carrier_area_empty</item>
+</resources>
diff --git a/packages/Keyguard/res/values-land/arrays.xml b/packages/Keyguard/res/values-land/arrays.xml
new file mode 100644
index 0000000..240b9e4
--- /dev/null
+++ b/packages/Keyguard/res/values-land/arrays.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/colors.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR 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">
+
+    <!-- Resources for GlowPadView in LockScreen -->
+    <array name="lockscreen_targets_when_silent">
+        <item>@null</item>"
+        <item>@drawable/ic_action_assist_generic</item>
+        <item>@drawable/ic_lockscreen_soundon</item>
+        <item>@drawable/ic_lockscreen_unlock</item>
+    </array>
+
+    <array name="lockscreen_target_descriptions_when_silent">
+        <item>@null</item>
+        <item>@string/description_target_search</item>
+        <item>@string/description_target_soundon</item>
+        <item>@string/description_target_unlock</item>
+    </array>
+
+    <array name="lockscreen_direction_descriptions">
+        <item>@null</item>
+        <item>@string/description_direction_up</item>
+        <item>@string/description_direction_left</item>
+        <item>@string/description_direction_down</item>
+    </array>
+
+    <array name="lockscreen_targets_when_soundon">
+        <item>@null</item>
+        <item>@drawable/ic_action_assist_generic</item>
+        <item>@drawable/ic_lockscreen_silent</item>
+        <item>@drawable/ic_lockscreen_unlock</item>
+    </array>
+
+    <array name="lockscreen_target_descriptions_when_soundon">
+        <item>@null</item>
+        <item>@string/description_target_search</item>
+        <item>@string/description_target_silent</item>
+        <item>@string/description_target_unlock</item>
+    </array>
+
+    <array name="lockscreen_targets_with_camera">
+        <item>@null</item>
+        <item>@drawable/ic_action_assist_generic</item>
+        <item>@drawable/ic_lockscreen_camera</item>
+        <item>@drawable/ic_lockscreen_unlock</item>
+    </array>
+
+    <array name="lockscreen_target_descriptions_with_camera">
+        <item>@null</item>
+        <item>@string/description_target_search</item>
+        <item>@string/description_target_camera</item>
+        <item>@string/description_target_unlock</item>
+    </array>
+
+</resources>
diff --git a/packages/Keyguard/res/values-land/bools.xml b/packages/Keyguard/res/values-land/bools.xml
new file mode 100644
index 0000000..a1dd2e4
--- /dev/null
+++ b/packages/Keyguard/res/values-land/bools.xml
@@ -0,0 +1,22 @@
+<?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>
+    <bool name="kg_enable_camera_default_widget">false</bool>
+    <bool name="kg_top_align_page_shrink_on_bouncer_visible">true</bool>
+    <bool name="kg_share_status_area">false</bool>
+    <bool name="kg_sim_puk_account_full_screen">false</bool>
+</resources>
diff --git a/packages/Keyguard/res/values-land/dimens.xml b/packages/Keyguard/res/values-land/dimens.xml
new file mode 100644
index 0000000..64e043c
--- /dev/null
+++ b/packages/Keyguard/res/values-land/dimens.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+
+<resources>
+    <!-- Default height of a key in the password keyboard for alpha -->
+    <dimen name="password_keyboard_key_height_alpha">47dip</dimen>
+    <!-- Default height of a key in the password keyboard for numeric -->
+    <dimen name="password_keyboard_key_height_numeric">50dip</dimen>
+    <!-- Default correction for the space key in the password keyboard -->
+    <dimen name="password_keyboard_spacebar_vertical_correction">2dip</dimen>
+    <dimen name="preference_widget_width">72dp</dimen>
+
+    <!-- Size of clock font in LockScreen on Unsecure unlock screen. -->
+    <dimen name="keyguard_lockscreen_clock_font_size">70sp</dimen>
+
+    <!-- Shift emergency button from the left edge by this amount.  Used by landscape layout on
+         phones -->
+    <dimen name="kg_emergency_button_shift">30dp</dimen>
+
+    <!-- Space reserved at the bottom of secure views (pin/pattern/password/SIM pin/SIM puk) -->
+    <dimen name="kg_secure_padding_height">0dp</dimen>
+
+    <!-- Top padding for the widget pager -->
+    <dimen name="kg_widget_pager_top_padding">0dp</dimen>
+
+    <!-- Bottom padding for the widget pager -->
+    <dimen name="kg_widget_pager_bottom_padding">0dp</dimen>
+
+    <!-- If the height if keyguard drops below this threshold (most likely
+    due to the appearance of the IME), then drop the multiuser selector.
+    Landscape's layout allows this to be smaller than for portrait. -->
+    <dimen name="kg_squashed_layout_threshold">400dp</dimen>
+
+</resources>
diff --git a/packages/Keyguard/res/values-land/integers.xml b/packages/Keyguard/res/values-land/integers.xml
new file mode 100644
index 0000000..020fd23
--- /dev/null
+++ b/packages/Keyguard/res/values-land/integers.xml
@@ -0,0 +1,26 @@
+<?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.
+*/
+-->
+<resources>
+    <!-- Gravity to make KeyguardSelectorView work in multiple orientations
+        0x13 == "left|center_vertical" -->
+    <integer name="kg_selector_gravity">0x13</integer>
+    <integer name="kg_widget_region_weight">45</integer>
+    <integer name="kg_security_flipper_weight">55</integer>
+    <integer name="kg_glowpad_rotation_offset">-90</integer>
+</resources>
diff --git a/packages/Keyguard/res/values-large/dimens.xml b/packages/Keyguard/res/values-large/dimens.xml
new file mode 100644
index 0000000..8cd614d
--- /dev/null
+++ b/packages/Keyguard/res/values-large/dimens.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+<resources>
+    <!-- Default height of a key in the password keyboard for alpha -->
+    <dimen name="password_keyboard_key_height_alpha">75dip</dimen>
+    <!-- Default height of a key in the password keyboard for numeric -->
+    <dimen name="password_keyboard_key_height_numeric">75dip</dimen>
+    <!-- keyboardHeight = key_height*4 + key_bottom_gap*3 -->
+    <dimen name="password_keyboard_height">48.0mm</dimen>
+
+    <!-- Minimum width of the search view text entry area. -->
+    <dimen name="search_view_text_min_width">192dip</dimen>
+
+    <item type="dimen" name="dialog_min_width_major">55%</item>
+    <item type="dimen" name="dialog_min_width_minor">80%</item>
+
+    <!-- Preference UI dimensions for larger screens. -->
+    <dimen name="preference_widget_width">56dp</dimen>
+</resources>
diff --git a/packages/Keyguard/res/values-lo-rLA/strings.xml b/packages/Keyguard/res/values-lo-rLA/strings.xml
new file mode 100644
index 0000000..0dcb7d1
--- /dev/null
+++ b/packages/Keyguard/res/values-lo-rLA/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"ພິມລະຫັດ PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"ພິມລະຫັດ PUK ແລະ​ລະ​ຫັດ PIN ອັນໃໝ່"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"ລະ​ຫັດ PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"ລະຫັດ PIN ໃໝ່"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><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">"ພິມລະຫັດ PIN ເພື່ອປົດລັອກ"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"ລະຫັດ PIN ບໍ່ຖືກຕ້ອງ."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"ເພື່ອປົດລັອກ, ໃຫ້ກົດເມນູ ແລ້ວກົດ 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"ຄວາມພະຍາຍາມປົດລັອກດ້ວຍໜ້ານັ້ນ ເກີນຈຳນວນທີ່ກຳນົດແລ້ວ"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"ສາກເຕັມແລ້ວ"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"ກຳລັງສາກ, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"ເຊື່ອມຕໍ່ອຸປະກອນສາກຂອງທ່ານ."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"ກົດເມນູເພື່ອປົດລັອກ."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"ເຄືອຂ່າຍຖືກລັອກ"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"ບໍ່ມີຊິມກາດ"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"ບໍ່ມີຊິມກາດໃນແທັບເລັດ."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"ບໍ່ມີຊິມກາດຢູ່ໃນໂທລະສັບ."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"ໃສ່ SIM card."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"ບໍ່ພົບເຫັນຊິມກາດ ຫຼືບໍ່ສາມາດອ່ານຊິມກາດໄດ້. ກະລຸນາໃສ່ຊິມກາດໃໝ່."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"SIM card ບໍ່ສາມາດໃຊ້ໄດ້."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"SIM card ຂອງທ່ານຖືກປິດການນຳໃຊ້ຢ່າງຖາວອນແລ້ວ.\n ຕິດຕໍ່ຜູ່ໃຫ້ບໍລິການລະບົບຂອງທ່ານເພື່ອຂໍ SIM card ໃໝ່."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"ຊິມກາດຖືກລັອກ."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"ຊິມກາດຖືກລັອກດ້ວຍລະຫັດ PUK."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"ກຳລັງປົດລັອກຊິມກາດ..."</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. ວິດເຈັດ %2$d ຈາກທັງໝົດ %3$d."</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_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>
+    <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_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">"ປົດລັອກດ້ວຍ PIN."</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="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"ປຸ່ມເພງກ່ອນໜ້າ"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"ປຸ່ມເພງຕໍ່ໄປ"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"ປຸ່ມຢຸດຊົ່ວຄາວ"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"ປຸ່ມຫຼິ້ນ"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"ປຸ່ມຢຸດ"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</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_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"ປົດລັອກ"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"ກ້ອງ"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"ປິດສຽງ"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"ເປີດສຽງ"</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_down" msgid="5087739728639014595">"ເລື່ອນລົງເພື່ອ <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="description_direction_right" msgid="8034433242579600980">"ເລື່ອນໄປທາງຂວາເພື່ອ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"ຜູ່ໃຊ້ປັດຈຸບັນ <xliff:g id="NAME">%1$s</xliff:g> ."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"ການໂທສຸກເສີນ"</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">"ລະຫັດ PIN ຜິດ"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"ລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER">%d</xliff:g> ວິນາທີ."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"ແຕ້ມຮູບແບບປົດລັອກຂອງທ່ານ"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"ໃສ່ລະຫັດ PIN ຂອງຊິມ"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"ໃສ່ລະຫັດ PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"ໃສ່ລະຫັດຜ່ານ"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"ຊິມຖືກປິດການນຳໃຊ້ແລ້ວ. ປ້ອນລະຫັດ PUK ເພື່ອດຳເນີນການຕໍ່. ຕິດຕໍ່ຜູ່ໃຫ້ບໍລິການສຳລັບລາຍລະອຽດ."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"ໃສ່ລະຫັດ PIN ທີ່ຕ້ອງການ."</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"ຢືນຢັນລະຫັດ PIN ທີ່ຕ້ອງການ"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"ປົດລັອກ SIM card..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"ລະຫັດ PIN ບໍ່ຖືກຕ້ອງ."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"ພິມລະຫັດ PIN ຄວາມຍາວ 4 ເຖິງ 8 ໂຕເລກ."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"ລະຫັດ PUK ຄວນມີຢ່າງໜ້ອຍ 8 ໂຕເລກ."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"ປ້ອນລະຫັດ PUK ທີ່ຖືກຕ້ອງຄືນໃໝ່. ການພະຍາຍາມໃສ່ຫຼາຍເທື່ອຈະເຮັດໃຫ້ຊິມກາດໃຊ້ບໍ່ໄດ້ຖາວອນ."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"ລະຫັດ PIN ບໍ່ກົງກັນ"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ແຕ້ມຮູບແບບປົດລັອກຫຼາຍເກີນໄປ"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"ເພື່ອປົດລັອກ, ເຂົ້າສູ່ລະບົບດ້ວຍບັນຊີ Google ຂອງທ່ານ."</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"ກຳລັງກວດສອບບັນຊີ..."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"ທ່ານພິມລະຫັດ PIN​ ຂອງທ່ານຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. \n\nກະລຸນາລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ວິນາທີ."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"ທ່ານພິມລະຫັດຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. \n\nລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ວິນາທີ."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"ທ່ານແຕ້ມຮູບແບບປົດລັອກຂອງທ່ານຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. \n\nກະລຸນາລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ວິນາທີ."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"ທ່ານໄດ້ພະຍາຍາມປົດລັອກແທັບເລັດບໍ່ສຳເລັດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກຄວາມພະຍາຍາມອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ເທື່ອ ແທັບເລັດຂອງທ່ານຈະຖືກຕັ້ງ ໃຫ້ກັບໄປໃຊ້ຄ່າເລີ່ມຕົ້ນຈາກໂຮງງານຄືນໃໝ່ ແລະຂໍ້ມູນຜູ່ໃຊ້ທັງໝົດຈະສູນຫາຍໄປ."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"ທ່ານໄດ້ພະຍາຍາມປົດລັອກໂທລະສັບບໍ່ສຳເລັດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກຄວາມພະຍາຍາມອີກ <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກແຕ້ມຜິດອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ເທື່ອ, ທ່ານຈະຖືກຖາມໃຫ້ປົດລັອກແທັບເລັດຂອງທ່ານ ດ້ວຍການເຂົ້າສູ່ລະບົບໂດຍໃຊ້ອີເມວຂອງທ່ານ.\n\n ກະລຸນາລອງໃໝ່ອີກຄັ້ງໃນອີກ <xliff:g id="NUMBER_2">%d</xliff:g> ວິນາທີ."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"ທ່ານແຕ້ມຮູບແບບປົດລັອກຂອງທ່ານຜິດ <xliff:g id="NUMBER_0">%d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກຄວາມພະຍາຍາມອີກ <xliff:g id="NUMBER_1">%d</xliff:g> ເທື່ອ ທ່ານຈະຖືກຖາມໃຫ້ປົດລັອກໂທລະສັບຂອງທ່ານດ້ວຍບັນຊີອີເມວ.\n\n ລອງໃໝ່ອີກຄັ້ງໃນ <xliff:g id="NUMBER_2">%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="keyguard_transport_prev_description" msgid="8229108430245669854">"ປຸ່ມເພງກ່ອນໜ້າ"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"ປຸ່ມເພງຕໍ່ໄປ"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"ປຸ່ມຢຸດຊົ່ວຄາວ"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"ປຸ່ມຫຼິ້ນ"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"ປຸ່ມຢຸດ"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"ບໍ່ມີບໍລິການ"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-lt/activitystrings.xml b/packages/Keyguard/res/values-lt/activitystrings.xml
new file mode 100644
index 0000000..9ec21e4
--- /dev/null
+++ b/packages/Keyguard/res/values-lt/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Neapsaugota"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN kodas"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Slaptažodis"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Šablonas"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"SIM kortelės PIN kodas"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"SIM kortelės PUK kodas"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Pasirinkite valdiklį..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-lt/strings.xml b/packages/Keyguard/res/values-lt/strings.xml
new file mode 100644
index 0000000..29f62a7
--- /dev/null
+++ b/packages/Keyguard/res/values-lt/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Įveskite PIN kodą"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Įveskite PUK ir naują PIN kodus"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK kodas"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Naujas PIN kodas"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Palieskite, kad įves. slaptaž."</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Jei norite atrakinti, įveskite slaptažodį"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Jei norite atrakinti, įveskite PIN kodą"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Neteisingas PIN kodas."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Jei norite atrakinti, paspauskite „Meniu“ ir 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Viršijote maksimalų atrakinimo pagal veidą bandymų skaičių"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Įkrauta"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Įkraunama, <xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Prijunkite įkroviklį."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Jei norite atrakinti, paspauskite „Meniu“."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Tinklas užrakintas"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Nėra SIM kortelės"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Planšetiniame kompiuteryje nėra SIM kortelės."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Telefone nėra SIM kortelės."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Įdėkite SIM kortelę."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"Trūksta SIM kortelės arba ji neskaitoma. Įdėkite SIM kortelę."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Negalima naudoti SIM kortelės."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"SIM kortelė visam laikui neleidžiama.\n Jei norite gauti kitą SIM kortelę, susisiekite su belaidžio ryšio paslaugos teikėju."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM kortelė užrakinta."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM kortelė užrakinta PUK kodu."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Atrakinama SIM kortelė…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %2$d valdiklis iš %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Pridėti valdiklį."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tuščia"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Atrakinimo sritis išplėsta."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Atrakinimo sritis sutraukta."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Valdiklis <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Naudotojo pasirinkimo valdiklis"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Būsena"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Fotoaparatas"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Medijos valdikliai"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Valdiklių pertvarkymas pradėtas."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Valdiklių pertvarkymas baigtas."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Valdiklis <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> ištrintas."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Išplėsti atrakinimo sritį."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Atrakinimas slystant."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Atrakinimas pagal piešinį."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Atrakinimas pagal veidą."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Atrakinimas įvedus PIN kodą."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Atrakinimas įvedus slaptažodį."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Atrakinimo pagal piešinį sritis."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Slydimo sritis."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Ankstesnio takelio mygtukas"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Kito takelio mygtukas"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Pristabdymo mygtukas"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Paleidimo mygtukas"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Sustabdymo mygtukas"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Atšaukti"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Ištrinti"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Atlikta"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Režimo keitimas"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Įvesti"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Atrakinti"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Vaizdo kamera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Begarsis"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Garsas įjungtas"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Paieška"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Slyskite aukštyn link <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Slyskite žemyn link <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Slyskite į kairę link <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Slyskite į dešinę link <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Dabartinis naudotojas: <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Skambutis pagalbos numeriu"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Pamiršau atrakinimo piešinį"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Netinkamas atrakinimo piešinys"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Netinkamas slaptažodis"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Netinkamas PIN kodas"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Bandyti dar kartą po <xliff:g id="NUMBER">%d</xliff:g> sek."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Nupieškite atrakinimo piešinį"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Įveskite SIM PIN kodą"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Įveskite PIN kodą"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Įveskite slaptažodį"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"Dabar SIM neleidžiama. Jei norite tęsti, įveskite PUK kodą. Jei reikia išsamios informacijos, susisiekite su operatoriumi."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Įveskite pageidaujamą PIN kodą"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Patvirtinkite pageidaujamą PIN kodą"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Atrakinama SIM kortelė…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Netinkamas PIN kodas."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Įveskite PIN kodą, sudarytą iš 4–8 skaičių."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK kodas turėtų būti mažiausiai 8 skaitmenų."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Pakartotinai įveskite tinkamą PUK kodą. Pakartotinai bandant SIM bus neleidžiama visam laikui."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN kodai neatitinka"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Per daug atrakinimo piešinių bandymų"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Jei norite atrakinti, prisijunkite naudodami „Google“ paskyrą."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Naudotojo vardas (el. paštas)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Slaptažodis"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Prisijungti"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Netinkamas naudotojo vardas ar slaptažodis."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Pamiršote naudotojo vardą ar slaptažodį?\nApsilankykite šiuo adresu: "<b>"google.com/accounts/recovery"</b></string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Tikrinama paskyra…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN kodą netinkamai įvedėte <xliff:g id="NUMBER_0">%d</xliff:g> k. \n\nBandykite dar kartą po <xliff:g id="NUMBER_1">%d</xliff:g> sek."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Neteisingai įvedėte slaptažodį <xliff:g id="NUMBER_0">%d</xliff:g> k. \n\nBandykite dar kartą po <xliff:g id="NUMBER_1">%d</xliff:g> sek."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Netinkamai nupiešėte atrakinimo piešinį <xliff:g id="NUMBER_0">%d</xliff:g> k. \n\nBandykite dar kartą po <xliff:g id="NUMBER_1">%d</xliff:g> sek."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"<xliff:g id="NUMBER_0">%d</xliff:g> k. bandėte netinkamai atrakinti planšetinį kompiuterį. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. planšetiniame kompiuteryje bus iš naujo nustatyti numatytieji gamyklos nustatymai ir bus prarasti visi naudotojo duomenys."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"<xliff:g id="NUMBER_0">%d</xliff:g> k. bandėte netinkamai atrakinti telefoną. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. telefone bus iš naujo nustatyti numatytieji gamyklos nustatymai ir bus prarasti visi naudotojo duomenys."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"<xliff:g id="NUMBER">%d</xliff:g> k. bandėte netinkamai atrakinti planšetinį kompiuterį. Planšetiniame kompiuteryje bus iš naujo nustatyti numatytieji gamyklos nustatymai."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"<xliff:g id="NUMBER">%d</xliff:g> k. bandėte netinkamai atrakinti telefoną. Telefone bus iš naujo nustatyti numatytieji gamyklos nustatymai."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Netinkamai nupiešėte atrakinimo piešinį <xliff:g id="NUMBER_0">%d</xliff:g> k. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. būsite paprašyti atrakinti planšetinį kompiuterį naudodami „Google“ prisijungimo duomenis.\n\n Bandykite dar kartą po <xliff:g id="NUMBER_2">%d</xliff:g> sek."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Netinkamai nupiešėte atrakinimo piešinį <xliff:g id="NUMBER_0">%d</xliff:g> k. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. būsite paprašyti atrakinti telefoną naudodami „Google“ prisijungimo duomenis.\n\n Bandykite dar kartą po <xliff:g id="NUMBER_2">%d</xliff:g> sek."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Pašalinti"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Ankstesnio takelio mygtukas"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Kito takelio mygtukas"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Pristabdymo mygtukas"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Paleidimo mygtukas"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Sustabdymo mygtukas"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Nėra paslaugos."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-lv/activitystrings.xml b/packages/Keyguard/res/values-lv/activitystrings.xml
new file mode 100644
index 0000000..96807de
--- /dev/null
+++ b/packages/Keyguard/res/values-lv/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Drošība nav iespējota"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Parole"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Kombinācija"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"SIM PIN"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"SIM PUK"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Izvēlēties logrīku..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-lv/strings.xml b/packages/Keyguard/res/values-lv/strings.xml
new file mode 100644
index 0000000..aa13934
--- /dev/null
+++ b/packages/Keyguard/res/values-lv/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Ievadiet PIN kodu."</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Ievadiet PUK kodu un jaunu PIN kodu."</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK kods"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Jauns PIN kods"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Pieskarieties, lai ievadītu paroli"</font>"."</string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Ievadiet paroli, lai atbloķētu."</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Lai atbloķētu, ievadiet PIN."</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PIN kods nav pareizs."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Lai atbloķētu, nospiediet Izvēlne, pēc tam 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Ir pārsniegts maksimālais Autorizācijas pēc sejas mēģinājumu skaits."</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Uzlādēts"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Notiek uzlāde (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Pievienojiet uzlādes ierīci."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Lai atbloķētu, nospiediet vienumu Izvēlne."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Tīkls ir bloķēts."</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Nav SIM kartes."</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Planšetdatorā nav SIM kartes."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Tālrunī nav SIM kartes."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Ievietojiet SIM karti."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"Nav SIM kartes, vai arī to nevar nolasīt. Ievietojiet SIM karti."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"SIM karte nav lietojama."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Jūsu SIM karte ir neatgriezeniski atspējota.\nSazinieties ar savu bezvadu pakalpojumu sniedzēju, lai iegūtu citu SIM karti."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM karte ir bloķēta."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM karte ir bloķēta ar PUK."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Notiek SIM kartes atbloķēšana..."</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %2$d. logrīks no %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Pievienot logrīku."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tukšs"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Atbloķēšanas apgabals ir izvērsts."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Atbloķēšanas apgabals ir sakļauts."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Logrīks <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Lietotāju atlasītājs"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Statuss"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Kamera"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Multivides vadīklas"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Logrīku pārkārtošana ir sākta."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Logrīku pārkārtošana ir pabeigta."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Logrīks <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> ir izdzēsts."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Izvērst atbloķēšanas apgabalu."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Autorizācija, velkot ar pirkstu."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Autorizācija ar kombināciju."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Autorizācija pēc sejas."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Autorizācija ar PIN kodu."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Autorizācija ar paroli."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Kombinācijas ievades apgabals."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Apgabals, kur vilkt ar pirkstu."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Iepriekšējā ieraksta poga"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Nākamā ieraksta poga"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Pārtraukšanas poga"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Atskaņošanas poga"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Apturēšanas poga"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alternēšanas taustiņš"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Atcelt"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Dzēšanas taustiņš"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Gatavs"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Režīma maiņa"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Pārslēgšanas taustiņš"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Ievadīšanas taustiņš"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Atbloķēt"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Klusums"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Skaņa ieslēgta"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Meklēt"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Velciet uz augšu, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Velciet uz leju, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Velciet pa kreisi, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Velciet pa labi, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Pašreizējais lietotājs: <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Ārkārtas izsaukums"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Aizmirsu kombināciju"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Nepareiza kombinācija"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Nepareiza parole"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Nepareizs PIN"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Mēģiniet vēlreiz pēc <xliff:g id="NUMBER">%d</xliff:g> sekundēm."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Norādiet savu kombināciju"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Ievadiet SIM kartes PIN"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Ievadiet PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Ievadiet paroli"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM karte ir atspējota. Lai turpinātu, ievadiet PUK kodu. Lai iegūtu detalizētu informāciju, sazinieties ar mobilo sakaru operatoru."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Ievadiet vēlamo PIN kodu."</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Apstipriniet vēlamo PIN."</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Notiek SIM kartes atbloķēšana..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"PIN kods nav pareizs."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Ievadiet PIN, kas sastāv no 4 līdz 8 cipariem."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK kodam ir jābūt vismaz 8 ciparus garam."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Atkārtoti ievadiet pareizo PUK kodu. Ja vairākas reizes ievadīsiet to nepareizi, SIM karte tiks neatgriezeniski atspējota."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN kodi neatbilst."</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Pārāk daudz kombinācijas mēģinājumu"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Lai atbloķētu, pierakstieties, izmantojot savu Google kontu."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Lietotājvārds (e-pasts)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Parole"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Pierakstīties"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nederīgs lietotājvārds vai parole."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Vai aizmirsāt lietotājvārdu vai paroli?\nApmeklējiet vietni "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Notiek konta pārbaude…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Jūs nepareizi ievadījāt PIN <xliff:g id="NUMBER_0">%d</xliff:g> reizes.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%d</xliff:g> sekundēm."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Jūs nepareizi ievadījāt paroli <xliff:g id="NUMBER_0">%d</xliff:g> reizes.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%d</xliff:g> sekundēm."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Jūs nepareizi norādījāt atbloķēšanas kombināciju <xliff:g id="NUMBER_0">%d</xliff:g> reizes.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%d</xliff:g> sekundēm."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Jūs nepareizi veicāt planšetdatora atbloķēšanu <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīgiem mēģinājumiem planšetdatorā tiks atiestatīti rūpnīcas noklusējuma iestatījumi un lietotāja dati tiks zaudēti."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Jūs nepareizi veicāt tālruņa atbloķēšanu <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīgiem mēģinājumiem tālrunī tiks atiestatīti rūpnīcas noklusējuma iestatījumi un lietotāja dati tiks zaudēti."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Jūs nepareizi veicāt planšetdatora atbloķēšanu <xliff:g id="NUMBER">%d</xliff:g> reizes. Planšetdatorā tiks atiestatīti rūpnīcas noklusējuma iestatījumi."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Jūs nepareizi veicāt tālruņa atbloķēšanu <xliff:g id="NUMBER">%d</xliff:g> reizes. Tālrunī tiks atiestatīti rūpnīcas noklusējuma iestatījumi."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Jūs nepareizi norādījāt atbloķēšanas kombināciju <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīgiem mēģinājumiem planšetdators būs jāatbloķē, izmantojot e-pasta kontu.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%d</xliff:g> sekundēm."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Jūs nepareizi norādījāt atbloķēšanas kombināciju <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīgiem mēģinājumiem tālrunis būs jāatbloķē, izmantojot e-pasta kontu.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%d</xliff:g> sekundēm."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">"  — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Noņemt"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Iepriekšējā ieraksta poga"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Nākamā ieraksta poga"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Pārtraukšanas poga"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Atskaņošanas poga"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Apturēšanas poga"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Nav pakalpojuma."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-mn-rMN/strings.xml b/packages/Keyguard/res/values-mn-rMN/strings.xml
new file mode 100644
index 0000000..4ae7220
--- /dev/null
+++ b/packages/Keyguard/res/values-mn-rMN/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN кодыг бичнэ үү"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK-г бичээд шинэ PIN код оруулна уу"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK код"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Шинэ PIN код"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><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">"Тайлах PIN-г оруулна уу"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Буруу PIN код."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Тайлах бол Цэсийг дараад 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Нүүрээр түгжээ тайлах оролдлогын тоо дээд хэмжээнээс хэтэрсэн"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Цэнэглэгдэв"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Цэнэглэж байна, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Цэнэглэгчээ холбоно уу."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Тайлх бол цэсийг дарна уу."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Сүлжээ түгжигдсэн"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"SIM карт байхгүй"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Таблет SIM картгүй."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Утсанд SIM карт байхгүй."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"SIM картыг оруулна уу."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM карт байхгүй эсвэл унших боломжгүй. SIM карт оруулна уу."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Ашиглаж болохгүй SIM карт."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Таны SIM карт бүрмөсөн идэвхгүй болов.\n Өөр SIM карт авах бол өөрийн утасгүй үйлчилгээний нийлүүлэгчтэй холбогдоно уу."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM карт түгжигдсэн."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM картны PUK-түгжигдсэн."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SIM картны түгжээг гаргаж байна…"</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_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_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>
+    <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_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="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Өмнөх бичлэг товч"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Дараагийн бичлэг товч"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Түр зогсоох товч"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Тоглуулах товч"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Зогсоох товч"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"АБВ"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</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">"Шифт"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Оруулах"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Тайлах"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Камер"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Чимээгүй"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Дуунууд идэвхтэй"</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_down" msgid="5087739728639014595">"<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="description_direction_right" msgid="8034433242579600980">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> хийх бол баруунлуу гулсуулах."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Одоогийн хэрэглэгч <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Яаралтай дуудлага"</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">"PIN буруу"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Хээг зурах"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM PIN оруулна уу"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN оруулна уу"</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">"Хүссэн PIN кодоо оруулна уу"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Хүссэн PIN кодоо дахин оруулна уу"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM картны түгжээг гаргаж байна…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Буруу PIN код."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4-8 тооноос бүтэх PIN-г бичнэ үү."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK код 8-с цөөнгүй тооноос бүтнэ."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Зөв PUK кодыг дахин оруулна уу. Давтан оролдвол SIM нь бүрмөсөн идэвхгүй болгоно."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN кодууд таарахгүй байна"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Хээ оруулах оролдлого хэт олон"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Түгжээг тайлах бол Google акаунтаараа нэвтэрнэ үү."</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"Акаунт шалгаж байна…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Та PIN кодоо <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу бичив. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Та PIN кодоо <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу бичив. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Та тайлах хээг <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу зурлаа. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Та таблетыг тайлах гэж <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу оролдлоо. <xliff:g id="NUMBER_1">%d</xliff:g> удаа дахин буруу оролдвол таблет үйлдвэрийн үндсэн утгаараа тохируулагдах ба хэрэглэгчийн дата бүхэлдээ устана."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Та утсыг тайлах гэж <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу оролдлоо. <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> удаа буруу зурлаа. <xliff:g id="NUMBER_1">%d</xliff:g> удаа дахин буруу оруулбал, та таблетаа тайлахын тулд имэйл акаунт шаардлагатай болно.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> секундын дараа дахин оролдоно уу."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Та тайлах хээг <xliff:g id="NUMBER_0">%d</xliff:g> удаа буруу зурлаа. <xliff:g id="NUMBER_1">%d</xliff:g> удаа дахин буруу оруулбал, та утсаа тайлахын тулд имэйл акаунтаа ашиглах шаардлагатай болно.\n\n <xliff:g id="NUMBER_2">%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="keyguard_transport_prev_description" msgid="8229108430245669854">"Өмнөх дуу товч"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Дараагийн дуу товч"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Түр зогсох товч"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Тоглуулах товч"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Зогсоох товч"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Үйлчилгээ байхгүй."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-ms-rMY/strings.xml b/packages/Keyguard/res/values-ms-rMY/strings.xml
new file mode 100644
index 0000000..0aeeeb5
--- /dev/null
+++ b/packages/Keyguard/res/values-ms-rMY/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Taip kod PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Taip PUK dan kod PIN baharu"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Kod PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Kod PIN Baharu"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Sentuh untuk menaip kata laluan"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Taip kata laluan untuk membuka kunci"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Taip PIN untuk membuka kunci"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Kod PIN salah."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Untuk membuka kunci, tekan Menu, kemudian 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Telah melepasi had cubaan Buka Kunci Wajah"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Sudah dicas"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Mengecas, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Sambungkan pengecas anda."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Tekan Menu untuk membuka kunci."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Rangkaian dikunci"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Tiada kad SIM"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Tiada kad SIM dalam tablet."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Tiada kad SIM dalam telefon."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Masukkan kad SIM."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"Kad SIM tiada atau tidak boleh dibaca. Sila masukkan kad SIM."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Kad SIM tidak boleh digunakan."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Kad SIM anda telah dilumpuhkan secara kekal.\n Hubungi pembekal perkhidmatan wayarles anda untuk mendapatkan kad SIM lain."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"Kad SIM dikunci."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"Kad SIM dikunci dengan PUK."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Membuka kunci kad SIM..."</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d dari %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Tambah widget."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Kosong"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Bahagian buka kunci dikembangkan."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Bahagian buka kunci diruntuhkan."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Pemilih pengguna"</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">"Kawalan media"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Penyusunan semula widget dimulakan."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Penyusunan semula widget tamat."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> dipadamkan."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Kembangkan bahagian buka kunci."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Buka kunci luncur."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Buka kunci corak."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Wajah Buka Kunci"</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Buka kunci pin."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Buka kunci kata laluan."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Kawasan corak."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Kawasan luncur."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Butang lagu sebelumnya"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Butang lagu seterusnya"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Butang jeda"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Butang main"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Butang berhenti"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Batal"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Padam"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Selesai"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Perubahan mod"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Masuk"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Buka kunci"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Senyap"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Bunyi dihidupkan"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Carian"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Luncurkan ke atas untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Luncurkan ke bawah untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Luncurkan ke kiri untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Luncurkan ke kanan untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Pengguna semasa <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Panggilan kecemasan"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Lupa Corak"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Corak Salah"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Kata Laluan Salah"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN salah"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Cuba lagi dalam <xliff:g id="NUMBER">%d</xliff:g> saat."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Lukiskan corak anda"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Masukkan PIN SIM"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Masukkan PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Masukkan Kata Laluan"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"Kini SIM dilumpuhkan. Masukkan kod PUK untuk meneruskan. Hubungi pembawa untuk butiran."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Masukkan kod PIN yang diingini"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Sahkan kod PIN yang diingini"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Membuka kunci kad SIM..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Kod PIN salah."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Taipkan PIN yang mengandungi 4 hingga 8 nombor."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Kod PUK mestilah 8 nombor atau lebih."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Masukkan semula kod PIN yang betul. Percubaan berulang akan melumpuhkan SIM secara kekal."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Kod PIN tidak sepadan"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Terlalu banyak percubaan melukis corak"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Untuk membuka kunci, log masuk dengan akaun Google anda."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Nama Pengguna (E-mel)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Kata laluan"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Log masuk"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nama pengguna atau kata laluan tidak sah."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Lupa nama pengguna atau kata laluan anda?\nLawati"<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Menyemak akaun…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Anda telah menaip PIN anda secara salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Anda telah menaip kata laluan anda secara salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Anda telah tersilap melukis corak buka kunci anda sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Anda telah mencuba untuk membuka kunci tablet dengan salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, tablet akan ditetapkan semula kepada tetapan lalai kilang dan semua data pengguna akan hilang."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Anda telah mencuba untuk membuka kunci telefon dengan salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, telefon akan ditetapkan semula kepada tetapan lalai kilang dan semua data pengguna akan hilang."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Anda telah mencuba untuk membuka kunci tablet secara salah sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Tablet kini akan ditetapkan semula ke tetapan lalai kilang."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Anda telah mencuba untuk membuka kunci telefon secara salah sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Telefon kini akan ditetapkan semula ke tetapan lalai kilang."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Anda telah tersilap melukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci tablet anda menggunakan log masuk Google anda.\n\n Cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Anda telah tersilap lukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci telefon anda menggunakan log masuk Google anda.\n\n Cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Alih keluar"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Butang lagu sebelumnya"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Butang lagu seterusnya"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Butang jeda"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Butang main"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Butang berhenti"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Tiada perkhidmatan."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-ms/activitystrings.xml b/packages/Keyguard/res/values-ms/activitystrings.xml
new file mode 100644
index 0000000..04e2184
--- /dev/null
+++ b/packages/Keyguard/res/values-ms/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Tiada keselamatan"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Kata laluan"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Corak"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"PIN SIM"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"PUK SIM"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Pilih widget..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-ms/strings.xml b/packages/Keyguard/res/values-ms/strings.xml
new file mode 100644
index 0000000..0aeeeb5
--- /dev/null
+++ b/packages/Keyguard/res/values-ms/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Taip kod PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Taip PUK dan kod PIN baharu"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Kod PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Kod PIN Baharu"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Sentuh untuk menaip kata laluan"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Taip kata laluan untuk membuka kunci"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Taip PIN untuk membuka kunci"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Kod PIN salah."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Untuk membuka kunci, tekan Menu, kemudian 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Telah melepasi had cubaan Buka Kunci Wajah"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Sudah dicas"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Mengecas, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Sambungkan pengecas anda."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Tekan Menu untuk membuka kunci."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Rangkaian dikunci"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Tiada kad SIM"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Tiada kad SIM dalam tablet."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Tiada kad SIM dalam telefon."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Masukkan kad SIM."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"Kad SIM tiada atau tidak boleh dibaca. Sila masukkan kad SIM."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Kad SIM tidak boleh digunakan."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Kad SIM anda telah dilumpuhkan secara kekal.\n Hubungi pembekal perkhidmatan wayarles anda untuk mendapatkan kad SIM lain."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"Kad SIM dikunci."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"Kad SIM dikunci dengan PUK."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Membuka kunci kad SIM..."</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d dari %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Tambah widget."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Kosong"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Bahagian buka kunci dikembangkan."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Bahagian buka kunci diruntuhkan."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Pemilih pengguna"</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">"Kawalan media"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Penyusunan semula widget dimulakan."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Penyusunan semula widget tamat."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> dipadamkan."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Kembangkan bahagian buka kunci."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Buka kunci luncur."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Buka kunci corak."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Wajah Buka Kunci"</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Buka kunci pin."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Buka kunci kata laluan."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Kawasan corak."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Kawasan luncur."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Butang lagu sebelumnya"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Butang lagu seterusnya"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Butang jeda"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Butang main"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Butang berhenti"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Batal"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Padam"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Selesai"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Perubahan mod"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Masuk"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Buka kunci"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Senyap"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Bunyi dihidupkan"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Carian"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Luncurkan ke atas untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Luncurkan ke bawah untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Luncurkan ke kiri untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Luncurkan ke kanan untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Pengguna semasa <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Panggilan kecemasan"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Lupa Corak"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Corak Salah"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Kata Laluan Salah"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN salah"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Cuba lagi dalam <xliff:g id="NUMBER">%d</xliff:g> saat."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Lukiskan corak anda"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Masukkan PIN SIM"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Masukkan PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Masukkan Kata Laluan"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"Kini SIM dilumpuhkan. Masukkan kod PUK untuk meneruskan. Hubungi pembawa untuk butiran."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Masukkan kod PIN yang diingini"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Sahkan kod PIN yang diingini"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Membuka kunci kad SIM..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Kod PIN salah."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Taipkan PIN yang mengandungi 4 hingga 8 nombor."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Kod PUK mestilah 8 nombor atau lebih."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Masukkan semula kod PIN yang betul. Percubaan berulang akan melumpuhkan SIM secara kekal."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Kod PIN tidak sepadan"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Terlalu banyak percubaan melukis corak"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Untuk membuka kunci, log masuk dengan akaun Google anda."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Nama Pengguna (E-mel)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Kata laluan"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Log masuk"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nama pengguna atau kata laluan tidak sah."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Lupa nama pengguna atau kata laluan anda?\nLawati"<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Menyemak akaun…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Anda telah menaip PIN anda secara salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Anda telah menaip kata laluan anda secara salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Anda telah tersilap melukis corak buka kunci anda sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. \n\nCuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Anda telah mencuba untuk membuka kunci tablet dengan salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, tablet akan ditetapkan semula kepada tetapan lalai kilang dan semua data pengguna akan hilang."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Anda telah mencuba untuk membuka kunci telefon dengan salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, telefon akan ditetapkan semula kepada tetapan lalai kilang dan semua data pengguna akan hilang."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Anda telah mencuba untuk membuka kunci tablet secara salah sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Tablet kini akan ditetapkan semula ke tetapan lalai kilang."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Anda telah mencuba untuk membuka kunci telefon secara salah sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Telefon kini akan ditetapkan semula ke tetapan lalai kilang."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Anda telah tersilap melukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci tablet anda menggunakan log masuk Google anda.\n\n Cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Anda telah tersilap lukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci telefon anda menggunakan log masuk Google anda.\n\n Cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Alih keluar"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Butang lagu sebelumnya"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Butang lagu seterusnya"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Butang jeda"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Butang main"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Butang berhenti"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Tiada perkhidmatan."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-nb/activitystrings.xml b/packages/Keyguard/res/values-nb/activitystrings.xml
new file mode 100644
index 0000000..015df15
--- /dev/null
+++ b/packages/Keyguard/res/values-nb/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Ingen sikkerhet"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Passord"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Mønster"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"Personlig kode for SIM-kort"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"PUK-kode for SIM-kort"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Velg modul"</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-nb/strings.xml b/packages/Keyguard/res/values-nb/strings.xml
new file mode 100644
index 0000000..6a5bfa9
--- /dev/null
+++ b/packages/Keyguard/res/values-nb/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Skriv inn PIN-kode"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Skriv inn PUK-kode og ny personlig kode"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-kode"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Ny PIN-kode"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Trykk for å skrive inn passord"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Skriv inn passord for å låse opp"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Skriv inn PIN-kode for å låse opp"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Feil personlig kode."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"For å låse opp, trykk på menyknappen og deretter 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Du har overskredet grensen for opplåsingsforsøk med Ansiktslås"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Oppladet"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Lader: <xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Koble til laderen."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Trykk på Meny for å låse opp."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Nettverk låst"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"SIM-kortet mangler"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Nettbrettet mangler SIM-kort."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Telefonen mangler SIM-kort."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Sett inn et SIM-kort."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM-kort mangler eller er uleselig. Sett inn et SIM-kort."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Ubrukelig SIM-kort."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"SIM-kortet er deaktivert permanent.\nTa kontakt med leverandøren av trådløstjenesten for å få et nytt SIM-kort."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM-kortet er låst."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM-kortet er PUK-låst."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Låser opp SIM-kortet ..."</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Modul %2$d av %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Legg til modul."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tom"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Opplåsingsfeltet vises."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Opplåsingsfeltet skjules."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>-modul."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Brukervelgeren"</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">"Mediekontroll"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Endring av modulplasseringen har startet."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Endringen av modulplasseringen er ferdig."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Modulen <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> ble slettet."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Vis opplåsingsfeltet."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Opplåsning ved å dra med fingeren."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Mønsteropplåsning."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Ansiktsopplåsning."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"PIN-opplåsning."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Passordopplåsning."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Mønsterområde."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Dra-felt."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Forrige spor-knapp"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Neste spor-knapp"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Pause-knapp"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Avspillingsknapp"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Stopp-knapp"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Avbryt"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Slett"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Ferdig"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Modusendring"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Lås opp"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Stille"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Lyd på"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Søk"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Dra opp for å <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Dra ned for å <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Dra til venstre for å <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Dra til høyre for å <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Gjeldende bruker: <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Nødnummer"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Har du glemt mønsteret?"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Feil mønster"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Feil passord"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Feil PIN-kode"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Prøv på nytt om <xliff:g id="NUMBER">%d</xliff:g> sekunder."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Tegn mønsteret ditt"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Skriv inn PIN-koden for SIM-kortet"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Skriv inn PIN-koden"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Skriv inn passordet"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM-kortet er nå deaktivert. Skriv inn PUK-koden for å fortsette. Ta kontakt med operatøren for mer informasjon."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Tast inn ønsket PIN-kode"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Bekreft ønsket PIN-kode"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Låser opp SIM-kortet ..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Feil PIN-kode."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Skriv inn en PIN-kode på fire til åtte sifre."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK-koden skal være på åtte eller flere siffer."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Skriv inn den korrekte PUK-koden på nytt. Gjentatte forsøk kommer til å deaktivere SIM-kortet."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-kodene stemmer ikke overens"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"For mange forsøk på tegning av mønster"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Logg deg på med Google-kontoen din for å låse opp."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Brukernavn (e-postadresse)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Passord"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Logg på"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Ugyldig brukernavn eller passord."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Har du glemt brukernavnet eller passordet?\nGå til "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Sjekker kontoen ..."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Du har oppgitt feil PIN-kode <xliff:g id="NUMBER_0">%d</xliff:g> ganger. \n\nPrøv på nytt om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Du har tastet inn passordet ditt feil <xliff:g id="NUMBER_0">%d</xliff:g> ganger. \n\nPrøv på nytt om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Du har tegnet opplåsningsmønsteret ditt feil <xliff:g id="NUMBER_0">%d</xliff:g> ganger. \n\nPrøv på nytt om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Du har oppgitt feil opplåsningspassord for nettbrettet <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%d</xliff:g> gale forsøk, tilbakestilles nettbrettet til fabrikkstandard og all data går tapt."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Du har oppgitt feil opplåsningspassord for telefonen <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%d</xliff:g> gale forsøk, tilbakestilles telefonen til fabrikkstandard og all data går tapt."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Du har oppgitt feil opplåsningspassord for nettbrettet <xliff:g id="NUMBER">%d</xliff:g> ganger. Telefonen tilbakestilles nå til fabrikkstandard."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Du har oppgitt feil opplåsningspassord for telefonen <xliff:g id="NUMBER">%d</xliff:g> ganger. Telefonen tilbakestilles nå til fabrikkstandard."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Du har tegnet opplåsningsmønsteret feil <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%d</xliff:g> gale forsøk, blir du bedt om å låse opp nettbrettet via en e-postkonto.\n\n Prøv på nytt om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Du har tegnet opplåsningsmønsteret feil <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%d</xliff:g> gale forsøk, blir du bedt om å låse opp telefonen via en e-postkonto.\n\n Prøv på nytt om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Fjern"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Forrige spor-knapp"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Neste spor-knapp"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Pause-knapp"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Avspillingsknapp"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Stopp-knappen"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Ingen tjeneste."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-nl/activitystrings.xml b/packages/Keyguard/res/values-nl/activitystrings.xml
new file mode 100644
index 0000000..fcb0be9
--- /dev/null
+++ b/packages/Keyguard/res/values-nl/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Geen beveiliging"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"Pincode"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Wachtwoord"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Patroon"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"Pincode van simkaart"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"PUK-code van simkaart"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Widget kiezen…"</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-nl/strings.xml b/packages/Keyguard/res/values-nl/strings.xml
new file mode 100644
index 0000000..b94cb70
--- /dev/null
+++ b/packages/Keyguard/res/values-nl/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Pincode typen"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Geef de PUK-code en de nieuwe pincode op"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-code"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Nieuwe pincode"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Raak aan om wachtwoord in te voeren"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Typ het wachtwoord om te ontgrendelen"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Typ pincode om te ontgrendelen"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Onjuiste pincode."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Druk op \'Menu\' en vervolgens op 0 om te ontgrendelen."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Maximaal aantal pogingen voor Ontgrendelen via gezichtsherkenning overschreden"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Opgeladen"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Opladen, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Sluit de oplader aan."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Druk op \'Menu\' om te ontgrendelen."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Netwerk vergrendeld"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Geen simkaart"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Geen simkaart in tablet."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Geen simkaart in telefoon."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Plaats een simkaart."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"De simkaart ontbreekt of kan niet worden gelezen. Plaats een simkaart."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Onbruikbare simkaart."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Uw simkaart is permanent uitgeschakeld.\n Neem contact op met uw mobiele serviceprovider voor een nieuwe simkaart."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"Simkaart is vergrendeld."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"Simkaart is vergrendeld met PUK-code."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Simkaart ontgrendelen…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d van %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Widget toevoegen."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Leeg"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Ontgrendelingsgebied uitgevouwen."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Ontgrendelingsgebied samengevouwen."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Gebruikersselectie"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Status"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Camera"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Mediabediening"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Opnieuw indelen van widget gestart."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Opnieuw indelen van widget beëindigd."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> verwijderd."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Ontgrendelingsgebied uitvouwen."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Ontgrendeling via schuiven."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Ontgrendeling via patroon."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Ontgrendelen via gezichtsherkenning"</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Ontgrendeling via pincode."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Ontgrendeling via wachtwoord."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Tekengebied voor patroon."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Schuifgebied."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Knop voor vorig nummer"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Knop voor volgend nummer"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Knop voor onderbreken"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Knop voor afspelen"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Knop voor stoppen"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"Alt"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Annuleren"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Gereed"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Modus wijzigen"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Ontgrendelen"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Camera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Stil"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Geluid aan"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Zoeken"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Veeg omhoog voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Veeg omlaag voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Veeg naar links voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Veeg naar rechts voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Noodoproep"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Patroon vergeten"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Onjuist patroon"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Onjuist wachtwoord"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Onjuiste pincode"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Probeer het over <xliff:g id="NUMBER">%d</xliff:g> seconden opnieuw."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Teken uw patroon"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Geef de pincode van de simkaart op"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Pincode opgeven"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Wachtwoord invoeren"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"De simkaart is nu uitgeschakeld. Geef de PUK-code op om door te gaan. Neem contact op met de provider voor informatie."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Gewenste pincode opgeven"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Gewenste pincode bevestigen"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Simkaart ontgrendelen..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Onjuiste pincode."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Voer een pincode van 4 tot 8 cijfers in."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"De PUK-code is minimaal acht nummers lang."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Geef de juiste PUK-code opnieuw op. Bij herhaalde pogingen wordt de simkaart permanent uitgeschakeld."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Pincodes komen niet overeen"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Te veel patroonpogingen"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Als u wilt ontgrendelen, moet u inloggen op uw Google-account."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Gebruikersnaam (e-mail)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Wachtwoord"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Inloggen"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Ongeldige gebruikersnaam of wachtwoord."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Bent u uw gebruikersnaam of wachtwoord vergeten?\nGa naar "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Account controleren…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"U heeft uw pincode <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. \n\nProbeer het over <xliff:g id="NUMBER_1">%d</xliff:g> seconden opnieuw."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"U heeft uw wachtwoord <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. \n\nProbeer het over <xliff:g id="NUMBER_1">%d</xliff:g> seconden opnieuw."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. \n\nProbeer het over <xliff:g id="NUMBER_1">%d</xliff:g> seconden opnieuw."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"U heeft <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de tablet op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de tablet en gaan alle gebruikersgegevens verloren."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"U heeft nu <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de telefoon op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de telefoon en gaan alle gebruikersgegevens verloren."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"U heeft <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de tablet op een onjuiste manier te ontgrendelen. De fabrieksinstellingen worden nu hersteld op de tablet."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"U heeft <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de telefoon op een onjuiste manier te ontgrendelen. De fabrieksinstellingen worden nu hersteld op de telefoon."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd uw tablet te ontgrendelen via een e-mailaccount.\n\n Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd uw telefoon te ontgrendelen via een e-mailaccount.\n\n Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Verwijderen"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Knop voor vorig nummer"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Knop voor volgend nummer"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Knop voor onderbreken"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Knop voor afspelen"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Knop voor stoppen"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Geen service"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-pl/activitystrings.xml b/packages/Keyguard/res/values-pl/activitystrings.xml
new file mode 100644
index 0000000..f04170e
--- /dev/null
+++ b/packages/Keyguard/res/values-pl/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Bez zabezpieczeń"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Hasło"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Wzór"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"PIN do karty SIM"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"PUK do karty SIM"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Wybierz widżet..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-pl/strings.xml b/packages/Keyguard/res/values-pl/strings.xml
new file mode 100644
index 0000000..15a4a7c
--- /dev/null
+++ b/packages/Keyguard/res/values-pl/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Wpisz kod PIN."</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Wpisz kod PUK i nowy kod PIN."</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Kod PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Nowy PIN"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Dotknij, aby wpisać hasło."</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Wpisz hasło, aby odblokować."</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Wpisz kod PIN, aby odblokować."</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Błędny kod PIN"</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Aby odblokować, naciśnij Menu, a następnie 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Przekroczono maksymalną liczbę prób rozpoznania twarzy."</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Naładowana"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Ładowanie (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Podłącz ładowarkę."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Naciśnij Menu, by odblokować."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Zablokowana sieć"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Brak karty SIM"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Brak karty SIM w tablecie."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Brak karty SIM w telefonie."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Włóż kartę SIM."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"Brak karty SIM lub nie można jej odczytać. Włóż kartę SIM."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Karta SIM bezużyteczna."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Karta SIM jest trwale wyłączona.\n Skontaktuj się z dostawcą usług bezprzewodowych, by otrzymać inną kartę SIM."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"Karta SIM jest zablokowana."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"Karta SIM jest zablokowana za pomocą kodu PUK."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Odblokowuję kartę SIM…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widżet %2$d z %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Dodaj widżet."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Puste"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Rozwinięto obszar odblokowania."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Zwinięto obszar odblokowania."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widżet <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Wybór użytkownika"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Stan"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Aparat"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Elementy sterujące multimediów"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Rozpoczęto zmienianie kolejności widżetów."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Zakończono zmienianie kolejności widżetów."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Usunięto widżet <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Rozwiń obszar odblokowania."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Odblokowanie przesunięciem."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Odblokowanie wzorem."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Rozpoznanie twarzy"</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Odblokowanie kodem PIN."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Odblokowanie hasłem."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Obszar wzoru."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Obszar przesuwania."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Przycisk poprzedniego utworu"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Przycisk następnego utworu"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Przycisk wstrzymania"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Przycisk odtwarzania"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Przycisk zatrzymania"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Anuluj"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Gotowe"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Zmiana trybu"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Odblokuj"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Aparat"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Wyciszenie"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Włącz dźwięk"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Szukaj"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Przesuń w górę: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Przesuń w dół: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Przesuń w lewo: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Przesuń w prawo: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Bieżący użytkownik: <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Połączenie alarmowe"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Nie pamiętam wzoru"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Nieprawidłowy wzór"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Nieprawidłowe hasło"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Nieprawidłowy PIN"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Spróbuj ponownie za <xliff:g id="NUMBER">%d</xliff:g> s."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Narysuj wzór"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Podaj PIN karty SIM"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Podaj PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Wpisz hasło"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"Karta SIM została wyłączona. Podaj kod PUK, by przejść dalej. Szczegóły uzyskasz od operatora."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Podaj wybrany kod PIN"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Potwierdź wybrany kod PIN"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Odblokowuję kartę SIM…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Nieprawidłowy PIN."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Wpisz PIN o długości od 4 do 8 cyfr."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Kod PUK musi mieć co najmniej 8 cyfr."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Ponownie podaj poprawny kod PUK. Nieudane próby spowodują trwałe wyłączenie karty SIM."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Kody PIN nie pasują"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Zbyt wiele prób narysowania wzoru"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Aby odblokować, zaloguj się na konto Google."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Nazwa użytkownika (e-mail)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Hasło"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Zaloguj się"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nieprawidłowa nazwa użytkownika lub hasło."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Nie pamiętasz nazwy użytkownika lub hasła?\nWejdź na "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Sprawdzam konto"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> wpisałeś nieprawidłowy PIN. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> wpisałeś nieprawidłowe hasło. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> narysowałeś nieprawidłowy wzór odblokowania. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> próbowałeś nieprawidłowo odblokować tablet. Po kolejnych <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach tablet zostanie zresetowany do ustawień fabrycznych, a wszystkie dane użytkownika zostaną utracone."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> próbowałeś nieprawidłowo odblokować telefon. Po kolejnych <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach telefon zostanie zresetowany do ustawień fabrycznych, a wszystkie dane użytkownika zostaną utracone."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Po raz <xliff:g id="NUMBER">%d</xliff:g> próbowałeś nieprawidłowo odblokować tablet. Tablet zostanie teraz zresetowany do ustawień fabrycznych."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Po raz <xliff:g id="NUMBER">%d</xliff:g> próbowałeś nieprawidłowo odblokować telefon. Telefon zostanie teraz zresetowany do ustawień fabrycznych."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> nieprawidłowo narysowałeś wzór odblokowania. Po kolejnych <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach konieczne będzie odblokowanie tabletu przy użyciu danych logowania na konto Google.\n\n Spróbuj ponownie za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> nieprawidłowo narysowałeś wzór odblokowania. Po kolejnych <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach konieczne będzie odblokowanie telefonu przy użyciu danych logowania na konto Google.\n\n Spróbuj ponownie za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Usuń"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Przycisk poprzedniego utworu"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Przycisk następnego utworu"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Przycisk wstrzymania"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Przycisk odtwarzania"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Przycisk zatrzymania"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Brak usługi."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-port/alias.xml b/packages/Keyguard/res/values-port/alias.xml
new file mode 100644
index 0000000..c3ecbb9
--- /dev/null
+++ b/packages/Keyguard/res/values-port/alias.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/colors.xml
+**
+** 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.
+*/
+-->
+<resources>
+    <!-- Alias used to reference one of two possible layouts in keyguard.  -->
+    <item type="layout" name="keyguard_eca">@layout/keyguard_emergency_carrier_area</item>
+</resources>
diff --git a/packages/Keyguard/res/values-port/bools.xml b/packages/Keyguard/res/values-port/bools.xml
new file mode 100644
index 0000000..1e2a4f2
--- /dev/null
+++ b/packages/Keyguard/res/values-port/bools.xml
@@ -0,0 +1,21 @@
+<?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>
+    <bool name="action_bar_embed_tabs">false</bool>
+    <bool name="kg_share_status_area">true</bool>
+    <bool name="kg_sim_puk_account_full_screen">true</bool>
+</resources>
diff --git a/packages/Keyguard/res/values-port/integers.xml b/packages/Keyguard/res/values-port/integers.xml
new file mode 100644
index 0000000..ef7e4da
--- /dev/null
+++ b/packages/Keyguard/res/values-port/integers.xml
@@ -0,0 +1,23 @@
+<?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.
+*/
+-->
+<resources>
+    <!-- Gravity to make KeyguardSelectorView work in multiple orientations
+        0x31 == "top|center_horizontal" -->
+    <integer name="kg_selector_gravity">0x31</integer>
+</resources>
\ No newline at end of file
diff --git a/packages/Keyguard/res/values-pt-rPT/activitystrings.xml b/packages/Keyguard/res/values-pt-rPT/activitystrings.xml
new file mode 100644
index 0000000..470865d
--- /dev/null
+++ b/packages/Keyguard/res/values-pt-rPT/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Sem segurança"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Palavra-passe"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Sequência"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"PIN do SIM"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"PUK do SIM"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Escolher widget..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-pt-rPT/strings.xml b/packages/Keyguard/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..222051c
--- /dev/null
+++ b/packages/Keyguard/res/values-pt-rPT/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Escreva o código PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Escreva o PUK e o novo código PIN"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Código PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Novo código PIN"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Toque para escrever a palavra-passe"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Escreva a palavra-passe para desbloquear"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Escreva o PIN para desbloquear"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Código PIN incorreto."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Para desbloquear, prima Menu e, em seguida, 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Excedido o n.º máximo de tentativas de Desbloqueio Através do Rosto"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Carregado"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"A carregar, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Ligue o carregador."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Prima Menu para desbloquear."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Rede bloqueada"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Nenhum cartão SIM"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Nenhum cartão SIM no tablet."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Nenhum cartão SIM no telemóvel."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Insira um cartão SIM."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"O cartão SIM está em falta ou não é legível. Introduza um cartão SIM."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Cartão SIM inutilizável."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"O cartão SIM foi desativado definitivamente.\n Contacte o seu fornecedor de serviços de rede sem fios para obter outro cartão SIM."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"O cartão SIM está bloqueado."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"O cartão SIM está bloqueado por PUK."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"A desbloquear o cartão SIM..."</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d de %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Adicionar widget."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Vazio"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Área de desbloqueio expandida."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Área de desbloqueio minimizada."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> widget."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Seletor de utilizadores"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Estado"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Câmara"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Controlos de multimédia"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Reordenação de widgets iniciada."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Reordenação de widgets concluída."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> eliminado."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Expandir área de desbloqueio."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Desbloqueio através de deslize."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Desbloqueio através de sequência."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Desbloqueio através do rosto."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Desbloqueio através de PIN."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Desbloqueio através de palavra-passe."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Área da sequência."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Área de deslize."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Botão Faixa anterior"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Botão Faixa seguinte"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Botão Pausa"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Botão Reproduzir"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Botão Parar"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Cancelar"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Concluído"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Alteração do modo"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Desbloquear"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Câmara"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Silencioso"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Som ativado"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Pesquisar"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Deslize para cima para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Deslize para baixo para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Deslize para a esquerda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Deslize para a direita para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
+    <string name="user_switched" msgid="3768006783166984410">"<xliff:g id="NAME">%1$s</xliff:g> do utilizador atual."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Chamada de emergência"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Esqueceu-se da Sequência"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Sequência Incorreta"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Palavra-passe Incorreta"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN Incorreto"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Tente novamente dentro de <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Desenhe a sua sequência"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Introduzir PIN do cartão SIM"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Introduzir PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Introduzir Palavra-passe"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"O SIM está agora desativado. Introduza o código PUK para continuar. Contacte o operador para obter detalhes."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Introduza o código PIN pretendido"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Confirme o código PIN pretendido"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"A desbloquear cartão SIM..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Código PIN incorreto."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Introduza um PIN entre 4 e 8 números."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"O código PUK deve ter 8 ou mais números."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Volte a introduzir o código PUK correto. Demasiadas tentativas consecutivas irão desativar permanentemente o SIM."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Os códigos PIN não correspondem"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Demasiadas tentativas para desenhar sequência"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Para desbloquear, inicie sessão com a sua Conta do Google."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Nome de utilizador (email)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Palavra-passe"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Iniciar sessão"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nome de utilizador ou palavra-passe inválidos."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Esqueceu-se do nome de utilizador ou da palavra-passe?\nAceda a "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"A verificar a conta…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Escreveu o PIN incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Escreveu a palavra-passe incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Desenhou a sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tentou desbloquear o tablet <xliff:g id="NUMBER_0">%d</xliff:g> vezes de forma incorreta. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem êxito, as definições de origem do telemóvel serão repostas e todos os dados do utilizador serão perdidos."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Tentou desbloquear o telemóvel <xliff:g id="NUMBER_0">%d</xliff:g> vezes de forma incorreta. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem êxito, as definições de origem do telemóvel serão repostas e todos os dados do utilizador serão perdidos."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Tentou desbloquear o tablet <xliff:g id="NUMBER">%d</xliff:g> vezes de forma incorreta, pelo que será reposta a predefinição de fábrica."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Tentou desbloquear o telemóvel <xliff:g id="NUMBER">%d</xliff:g> vezes de forma incorreta, pelo que será reposta a predefinição de fábrica."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Desenhou a sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, ser-lhe-á pedido para desbloquear o tablet através de uma conta de email.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Desenhou a sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, ser-lhe-á pedido para desbloquear o telemóvel através de uma conta de email.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" - "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Remover"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Botão Faixa anterior"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Botão Faixa seguinte"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Botão Pausa"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Botão Reproduzir"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Botão Parar"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Sem serviço."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-pt/activitystrings.xml b/packages/Keyguard/res/values-pt/activitystrings.xml
new file mode 100644
index 0000000..7a63708
--- /dev/null
+++ b/packages/Keyguard/res/values-pt/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Sem segurança"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Senha"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Padrão"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"PIN do SIM"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"PUK do SIM"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Escolher widget..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-pt/strings.xml b/packages/Keyguard/res/values-pt/strings.xml
new file mode 100644
index 0000000..a563372
--- /dev/null
+++ b/packages/Keyguard/res/values-pt/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Insira o código PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Insira o PUK e o novo código PIN"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Código PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Novo código PIN"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Toque para inserir a senha"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Digite a senha para desbloquear"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Insira o PIN para desbloquear"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Código PIN incorreto."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Para desbloquear, pressione Menu e, em seguida, 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"O número máximo de tentativas de Desbloqueio por reconhecimento facial foi excedido"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Carregado"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Carregando, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Conecte seu carregador."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Pressione \"Menu\" para desbloquear."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Rede bloqueada"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Sem cartão SIM"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Não há um cartão SIM no tablet."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Não há um cartão SIM no telefone."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Insira um cartão SIM."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"O cartão SIM não foi inserido ou não é possível lê-lo. Insira um cartão SIM."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Cartão SIM inutilizável."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"O cartão SIM foi desativado permanentemente.\nEntre em contato com seu provedor de serviços sem fio para receber outro cartão SIM."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"O cartão SIM está bloqueado."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"O cartão SIM está bloqueado pelo PUK."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Desbloqueando o cartão SIM…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d de %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Adicionar widget"</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Vazio"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Área de desbloqueio expandida."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Área de desbloqueio recolhida."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget de <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Seletor de usuários"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Status"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Câmera"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Controles de mídia"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Reordenação de widgets iniciada."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Reordenação de widgets concluída."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> excluído."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Expandir a área de desbloqueio."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Desbloqueio com deslize."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Desbloqueio com padrão."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Desbloqueio facial."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Desbloqueio com PIN."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Desbloqueio com senha."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Área do padrão."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Área de deslize."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Botão \"Faixa anterior\""</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Botão \"Próxima faixa\""</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Botão \"Pausar\""</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Botão \"Reproduzir\""</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Botão \"Parar\""</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Cancelar"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Excluir"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Concluído"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Alteração do modo"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Desbloquear"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Câmera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Silencioso"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Som ativado"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Pesquisar"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>, deslize para cima."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>, deslize para baixo."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>, deslize para a esquerda."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>, deslize para a direita."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Usuário atual <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Chamada de emergência"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Esqueci o padrão"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Padrão incorreto"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Senha incorreta"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN incorreto"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Tente novamente em <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Desenhe seu padrão"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Digite o PIN do cartão SIM"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Digite o PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Digite a senha"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"O SIM foi desativado. Insira o código PUK para continuar. Entre em contato com a operadora para obter mais detalhes."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Digite o código PIN desejado"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Confirme o código PIN desejado"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Desbloqueando o cartão SIM…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Código PIN incorreto."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Digite um PIN com quatro a oito números."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"O código PUK deve ter 8 números ou mais."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Introduza novamente o código PUK correto. Muitas tentativas malsucedidas desativarão permanentemente o SIM."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Os códigos PIN não coincidem"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Muitas tentativas de padrão"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Para desbloquear, faça login usando sua Conta do Google."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Nome de usuário (e-mail)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Senha"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Fazer login"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nome de usuário ou senha inválidos."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Esqueceu seu nome de usuário ou senha?\nAcesse "<b>"google.com.br/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Verificando a conta..."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Você digitou seu PIN incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Você digitou sua senha incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Você tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas malsucedidas, o tablet será redefinido para o padrão de fábrica e todos os dados do usuário serão perdidos."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Você tentou desbloquear incorretamente o telefone <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas malsucedidas, o telefone será redefinido para o padrão de fábrica e todos os dados do usuário serão perdidos."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Você tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER">%d</xliff:g> vezes. O tablet será redefinido para o padrão de fábrica."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Você tentou desbloquear incorretamente o telefone <xliff:g id="NUMBER">%d</xliff:g> vezes. O telefone será redefinido para o padrão de fábrica."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear seu tablet.\n\n Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear.\n\n Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Remover"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Botão \"Faixa anterior\""</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Botão \"Próxima faixa\""</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Botão \"Pausar\""</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Botão \"Reproduzir\""</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Botão \"Parar\""</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Sem serviço."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-rm/strings.xml b/packages/Keyguard/res/values-rm/strings.xml
new file mode 100644
index 0000000..8dda055
--- /dev/null
+++ b/packages/Keyguard/res/values-rm/strings.xml
@@ -0,0 +1,249 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- no translation found for keyguard_password_enter_pin_code (3037685796058495017) -->
+    <skip />
+    <!-- no translation found for keyguard_password_enter_puk_code (4800725266925845333) -->
+    <skip />
+    <!-- no translation found for keyguard_password_enter_puk_prompt (1341112146710087048) -->
+    <skip />
+    <!-- no translation found for keyguard_password_enter_pin_prompt (8027680321614196258) -->
+    <skip />
+    <!-- no translation found for keyguard_password_entry_touch_hint (7858547464982981384) -->
+    <skip />
+    <!-- no translation found for keyguard_password_enter_password_code (1054721668279049780) -->
+    <skip />
+    <!-- no translation found for keyguard_password_enter_pin_password_code (6391755146112503443) -->
+    <skip />
+    <!-- no translation found for keyguard_password_wrong_pin_code (2422225591006134936) -->
+    <skip />
+    <string name="keyguard_label_text" msgid="861796461028298424">"Smatgai per debloccar sin la tasta Menu e lura sin 0."</string>
+    <!-- no translation found for faceunlock_multiple_failures (754137583022792429) -->
+    <skip />
+    <!-- no translation found for keyguard_charged (3272223906073492454) -->
+    <skip />
+    <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+    <skip />
+    <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+    <skip />
+    <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+    <skip />
+    <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+    <skip />
+    <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+    <skip />
+    <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+    <skip />
+    <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+    <skip />
+    <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+    <skip />
+    <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+    <skip />
+    <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+    <skip />
+    <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+    <skip />
+    <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+    <skip />
+    <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+    <skip />
+    <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_widget_changed (5678624624681400191) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_add_widget (8273277058724924654) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_widget_empty_slot (1281505703307930757) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_unlock_area_expanded (2278106022311170299) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_unlock_area_collapsed (6366992066936076396) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_widget (6527131039741808240) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_user_selector (1226798370913698896) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_status (8008264603935930611) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_camera (8904231194181114603) -->
+    <skip />
+    <!-- no translation found for keygaurd_accessibility_media_controls (262209654292161806) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_widget_reorder_start (8736853615588828197) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_widget_reorder_end (7170190950870468320) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_widget_deleted (4426204263929224434) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_expand_lock_area (519859720934178024) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_slide_unlock (2959928478764697254) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_pattern_unlock (1490840706075246612) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_face_unlock (4817282543351718535) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_pin_unlock (2469687111784035046) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_password_unlock (7675777623912155089) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_pattern_area (7679891324509597904) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_slide_area (6736064494019979544) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+    <skip />
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <!-- no translation found for keyboardview_keycode_alt (4856868820040051939) -->
+    <skip />
+    <!-- no translation found for keyboardview_keycode_cancel (1203984017245783244) -->
+    <skip />
+    <!-- no translation found for keyboardview_keycode_delete (3337914833206635744) -->
+    <skip />
+    <!-- no translation found for keyboardview_keycode_done (1992571118466679775) -->
+    <skip />
+    <!-- no translation found for keyboardview_keycode_mode_change (4547387741906537519) -->
+    <skip />
+    <!-- no translation found for keyboardview_keycode_shift (2270748814315147690) -->
+    <skip />
+    <!-- no translation found for keyboardview_keycode_enter (2985864015076059467) -->
+    <skip />
+    <!-- no translation found for description_target_unlock (2228524900439801453) -->
+    <skip />
+    <!-- no translation found for description_target_camera (969071997552486814) -->
+    <skip />
+    <!-- no translation found for description_target_silent (893551287746522182) -->
+    <skip />
+    <!-- no translation found for description_target_soundon (30052466675500172) -->
+    <skip />
+    <!-- no translation found for description_target_search (3091587249776033139) -->
+    <skip />
+    <!-- no translation found for description_direction_up (7169032478259485180) -->
+    <skip />
+    <!-- no translation found for description_direction_down (5087739728639014595) -->
+    <skip />
+    <!-- no translation found for description_direction_left (7207478719805562165) -->
+    <skip />
+    <!-- no translation found for description_direction_right (8034433242579600980) -->
+    <skip />
+    <!-- no translation found for user_switched (3768006783166984410) -->
+    <skip />
+    <!-- no translation found for kg_emergency_call_label (684946192523830531) -->
+    <skip />
+    <!-- no translation found for kg_forgot_pattern_button_text (8852021467868220608) -->
+    <skip />
+    <!-- no translation found for kg_wrong_pattern (1850806070801358830) -->
+    <skip />
+    <!-- no translation found for kg_wrong_password (2333281762128113157) -->
+    <skip />
+    <!-- no translation found for kg_wrong_pin (1131306510833563801) -->
+    <skip />
+    <!-- no translation found for kg_too_many_failed_attempts_countdown (6358110221603297548) -->
+    <skip />
+    <!-- no translation found for kg_pattern_instructions (398978611683075868) -->
+    <skip />
+    <!-- no translation found for kg_sim_pin_instructions (2319508550934557331) -->
+    <skip />
+    <!-- no translation found for kg_pin_instructions (2377242233495111557) -->
+    <skip />
+    <!-- no translation found for kg_password_instructions (5753646556186936819) -->
+    <skip />
+    <!-- no translation found for kg_puk_enter_puk_hint (453227143861735537) -->
+    <skip />
+    <!-- no translation found for kg_puk_enter_pin_hint (7871604527429602024) -->
+    <skip />
+    <!-- no translation found for kg_enter_confirm_pin_hint (325676184762529976) -->
+    <skip />
+    <!-- no translation found for kg_sim_unlock_progress_dialog_message (8950398016976865762) -->
+    <skip />
+    <!-- no translation found for kg_password_wrong_pin_code (1139324887413846912) -->
+    <skip />
+    <!-- no translation found for kg_invalid_sim_pin_hint (8795159358110620001) -->
+    <skip />
+    <!-- no translation found for kg_invalid_sim_puk_hint (7553388325654369575) -->
+    <skip />
+    <!-- no translation found for kg_invalid_puk (3638289409676051243) -->
+    <skip />
+    <!-- no translation found for kg_invalid_confirm_pin_hint (7003469261464593516) -->
+    <skip />
+    <!-- no translation found for kg_login_too_many_attempts (6486842094005698475) -->
+    <skip />
+    <!-- no translation found for kg_login_instructions (1100551261265506448) -->
+    <skip />
+    <!-- no translation found for kg_login_username_hint (5718534272070920364) -->
+    <skip />
+    <!-- no translation found for kg_login_password_hint (9057289103827298549) -->
+    <skip />
+    <!-- no translation found for kg_login_submit_button (5355904582674054702) -->
+    <skip />
+    <!-- no translation found for kg_login_invalid_input (5754664119319872197) -->
+    <skip />
+    <!-- no translation found for kg_login_account_recovery_hint (5690709132841752974) -->
+    <skip />
+    <!-- no translation found for kg_login_checking_password (1052685197710252395) -->
+    <skip />
+    <!-- no translation found for kg_too_many_failed_pin_attempts_dialog_message (8276745642049502550) -->
+    <skip />
+    <!-- no translation found for kg_too_many_failed_password_attempts_dialog_message (7813713389422226531) -->
+    <skip />
+    <!-- no translation found for kg_too_many_failed_pattern_attempts_dialog_message (74089475965050805) -->
+    <skip />
+    <!-- no translation found for kg_failed_attempts_almost_at_wipe (1575557200627128949) -->
+    <skip />
+    <!-- no translation found for kg_failed_attempts_almost_at_wipe (4051015943038199910) -->
+    <skip />
+    <!-- no translation found for kg_failed_attempts_now_wiping (2072996269148483637) -->
+    <skip />
+    <!-- no translation found for kg_failed_attempts_now_wiping (4817627474419471518) -->
+    <skip />
+    <!-- no translation found for kg_failed_attempts_almost_at_login (3253575572118914370) -->
+    <skip />
+    <!-- no translation found for kg_failed_attempts_almost_at_login (1437638152015574839) -->
+    <skip />
+    <!-- no translation found for kg_text_message_separator (4160700433287233771) -->
+    <skip />
+    <!-- no translation found for kg_reordering_delete_drop_target_text (7899202978204438708) -->
+    <skip />
+    <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+    <skip />
+    <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+    <skip />
+    <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+    <skip />
+    <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+    <skip />
+    <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+    <skip />
+    <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+    <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-ro/activitystrings.xml b/packages/Keyguard/res/values-ro/activitystrings.xml
new file mode 100644
index 0000000..6d3447d
--- /dev/null
+++ b/packages/Keyguard/res/values-ro/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Fără securitate"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Parolă"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Model"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"PIN SIM"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"PUK SIM"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Alegeți un widget..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-ro/strings.xml b/packages/Keyguard/res/values-ro/strings.xml
new file mode 100644
index 0000000..01d79f8
--- /dev/null
+++ b/packages/Keyguard/res/values-ro/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Introduceţi codul PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Introduceţi codul PUK şi noul cod PIN"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Codul PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Noul cod PIN"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Atingeţi şi introduceţi parola"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Introduceţi parola pentru a debloca"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Introduceţi codul PIN pentru a debloca"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Cod PIN incorect."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Pentru a debloca, apăsaţi Meniu, apoi 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"S-a depăşit numărul maxim de încercări pentru Deblocare facială"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Încărcată"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Se încarcă, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Conectați încărcătorul."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Apăsați pe Meniu pentru a debloca."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Rețea blocată"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Niciun card SIM"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Tableta nu are card SIM."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Telefonul nu are card SIM."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Introduceți un card SIM."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"Cardul SIM lipsește sau nu poate fi citit. Introduceți un card SIM."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Card SIM inutilizabil."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Cardul SIM este dezactivat definitiv.\n Contactați furnizorul de servicii wireless pentru a obține alt card SIM."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"Cardul SIM este blocat."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"Cardul SIM este blocat cu codul PUK."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Se deblochează cardul SIM…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d din %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Adăugaţi un widget."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Gol"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Zona de deblocare a fost extinsă."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Zona de deblocare a fost restrânsă."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Selector utilizator"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Stare"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Cameră foto"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Comenzi media"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"A început reordonarea widgeturilor."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Reordonarea widgeturilor s-a încheiat."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widgetul <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> a fost eliminat."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Extindeţi zona de deblocare."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Deblocare prin glisare."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Deblocare cu model."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Deblocare facială."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Deblocare cu PIN."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Deblocare cu parolă."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Zonă model."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Zonă glisare."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Butonul Melodia anterioară"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Butonul Melodia următoare"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Butonul Întrerupeți"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Butonul Redați"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Butonul Opriți"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Anulaţi"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Ștergeţi"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Terminat"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Schimbarea modului"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Deblocaţi"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Cameră foto"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Silenţios"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Sunet activat"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Căutaţi"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Glisaţi în sus pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Glisaţi în jos pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Glisaţi spre stânga pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Glisaţi spre dreapta pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Utilizator curent: <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Apel de urgenţă"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Model uitat"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Model greşit"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Parolă greşită"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Cod PIN greşit"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Încercaţi din nou peste <xliff:g id="NUMBER">%d</xliff:g> (de) secunde."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Desenaţi modelul"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Introduceţi codul PIN al cardului SIM"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Introduceţi codul PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Introduceţi parola"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"Cardul SIM este acum dezactivat. Introduceţi codul PUK pentru a continua. Contactaţi operatorul pentru mai multe detalii."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Introduceţi codul PIN dorit"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Confirmaţi codul PIN dorit"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Se deblochează cardul SIM..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Cod PIN incorect."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Introduceţi un cod PIN format din 4 până la 8 cifre."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Codul PUK trebuie să aibă minimum 8 cifre."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Reintroduceţi codul PUK corect. Încercările repetate vor dezactiva definitiv cardul SIM."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Codurile PIN nu coincid"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Prea multe încercări de desenare a modelului"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Pentru a debloca, conectaţi-vă cu Contul dvs. Google."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Nume de utilizator (e-mail)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Parolă"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Conectaţi-vă"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nume de utilizator sau parolă nevalide."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Aţi uitat numele de utilizator sau parola?\nAccesaţi "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Se verifică contul…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Aţi introdus incorect codul PIN de <xliff:g id="NUMBER_0">%d</xliff:g> ori.\n\nÎncercaţi din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Aţi introdus incorect parola de <xliff:g id="NUMBER_0">%d</xliff:g> ori. \n\nÎncercaţi din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. \n\nÎncercaţi din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Aţi efectuat <xliff:g id="NUMBER_0">%d</xliff:g> încercări incorecte de deblocare a tabletei. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, aceasta va fi resetată la setările prestabilite din fabrică, iar toate datele de utilizator se vor pierde."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Aţi efectuat <xliff:g id="NUMBER_0">%d</xliff:g> încercări incorecte de deblocare a telefonului. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, acesta va fi resetat la setările prestabilite din fabrică, iar toate datele de utilizator se vor pierde."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Aţi efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a tabletei. Tableta va fi acum resetată la setările prestabilite din fabrică."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Aţi efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a telefonului. Telefonul va fi acum resetat la setările prestabilite din fabrică."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, vi se va solicita să deblocaţi tableta cu ajutorul unui cont de e-mail.\n\n Încercaţi din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, vi se va solicita să deblocaţi telefonul cu ajutorul unui cont de e-mail.\n\n Încercaţi din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Eliminaţi"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Butonul Melodia anterioară"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Butonul Melodia următoare"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Butonul Întrerupeți"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Butonul Redați"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Butonul Opriți"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Fără serviciu."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-ru/activitystrings.xml b/packages/Keyguard/res/values-ru/activitystrings.xml
new file mode 100644
index 0000000..002cd56
--- /dev/null
+++ b/packages/Keyguard/res/values-ru/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Защита отключена"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN-код"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Пароль"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Графический ключ"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"PIN-код SIM-карты"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"PUK-код SIM-карты"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Выбор виджета..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-ru/strings.xml b/packages/Keyguard/res/values-ru/strings.xml
new file mode 100644
index 0000000..136982a
--- /dev/null
+++ b/packages/Keyguard/res/values-ru/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Введите PIN-код"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Введите PUK-код и новый PIN-код"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-код"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Новый PIN-код"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><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">"Введите PIN-код"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Неверный PIN-код."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Для разблокировки нажмите \"Меню\", а затем 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Все попытки войти с помощью Фейсконтроля использованы"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Батарея заряжена"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Идет зарядка (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Подключите зарядное устройство."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Для разблокировки нажмите \"Меню\"."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Сеть заблокирована"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Нет SIM-карты"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Нет SIM-карты."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Нет SIM-карты."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Вставьте SIM-карту."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM-карта отсутствует или недоступна. Вставьте SIM-карту."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"SIM-карта непригодна."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"SIM-карта окончательно заблокирована.\nЧтобы получить новую, обратитесь к своему оператору."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM-карта заблокирована."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"Для разблокировки SIM-карты требуется PUK-код."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Разблокировка SIM-карты…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Виджет %2$d из %3$d."</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_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>
+    <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_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">"PIN-код"</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="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Кнопка перехода к предыдущему треку"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Кнопка перехода к следующему треку"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Кнопка паузы"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Кнопка воспроизведения"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Кнопка выключения"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"АБВ"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</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">"Клавиша смены регистра"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Клавиша ввода"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Разблокировать"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Без звука"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Включить звук"</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_down" msgid="5087739728639014595">"Проведите вниз, чтобы <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="description_direction_right" msgid="8034433242579600980">"Проведите вправо, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Выбран аккаунт пользователя <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Экстренный вызов"</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">"Неправильный PIN-код"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Повторите попытку через <xliff:g id="NUMBER">%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>
+    <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">"Введите желаемый PIN-код"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Введите PIN-код ещё раз"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Разблокировка SIM-карты…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Неверный PIN-код."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Введите PIN-код (от 4 до 8 цифр)."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK-код должен содержать не менее 8 символов."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Введите правильный PUK-код. После нескольких неудачных попыток SIM-карта будет заблокирована."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-коды не совпадают"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Слишком много попыток ввода графического ключа"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Чтобы разблокировать устройство, войдите в свой аккаунт Google."</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"Проверка данных…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали PIN-код. \n\nПовтор через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали пароль.\n\nПовтор через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали графический ключ.\n\nПовтор через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз не смогли разблокировать планшетный ПК. После <xliff:g id="NUMBER_1">%d</xliff:g> неверных попыток будут восстановлены заводские настройки, что приведет к удалению всех пользовательских данных."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз не смогли разблокировать телефон. После <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> раз неверно указали графический ключ. После <xliff:g id="NUMBER_1">%d</xliff:g> неверных попыток для разблокировки планшетного ПК потребуется войти в аккаунт Google.\n\nПовтор через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали графический ключ. После <xliff:g id="NUMBER_1">%d</xliff:g> неверных попыток для разблокировки телефона потребуется войти в аккаунт Google.\n\nПовтор через <xliff:g id="NUMBER_2">%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="keyguard_transport_prev_description" msgid="8229108430245669854">"Кнопка перехода к предыдущему треку"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Кнопка перехода к следующему треку"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Кнопка паузы"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Кнопка воспроизведения"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Кнопка выключения"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Нет сигнала."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-sk/activitystrings.xml b/packages/Keyguard/res/values-sk/activitystrings.xml
new file mode 100644
index 0000000..33f2228
--- /dev/null
+++ b/packages/Keyguard/res/values-sk/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Bez zabezpečenia"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"Kód PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Heslo"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Vzor"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"PIN karty SIM"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"PUK karty SIM"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Vyberte miniaplikáciu..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-sk/strings.xml b/packages/Keyguard/res/values-sk/strings.xml
new file mode 100644
index 0000000..4b2e1e3
--- /dev/null
+++ b/packages/Keyguard/res/values-sk/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Zadajte kód PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Zadajte kód PUK a nový kód PIN"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Kód PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Nový kód PIN"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Dotknutím zadajte heslo"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Zadajte heslo na odomknutie"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Zadajte kód PIN na odomknutie"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Nesprávny kód PIN."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Ak chcete telefón odomknúť, stlačte Menu a následne 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Prekročili ste maximálny povolený počet pokusov o odomknutie tvárou"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Batéria je nabitá"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Nabíjanie, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Pripojte nabíjačku."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Telefón odomknete stlačením tlačidla Menu."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Sieť je zablokovaná"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Nie je vložená karta SIM."</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"V tablete nie je žiadna karta SIM."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"V telefóne nie je žiadna karta SIM."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Vložte kartu SIM."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"Karta SIM chýba alebo sa z nej nedá čítať. Vložte kartu SIM."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Karta SIM je nepoužiteľná."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Vaša karta SIM bola natrvalo zakázaná.\nAk chcete získať inú kartu SIM, kontaktujte svojho poskytovateľa bezdrôtových služieb."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"Karta SIM je uzamknutá."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"Karta SIM je uzamknutá pomocou kódu PUK."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Prebieha odomykanie karty SIM..."</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Miniaplikácia %2$d z %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Pridať miniaplikáciu."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Prázdne"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Oblasť na odomknutie bola rozšírená."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Oblasť na odomknutie bola zúžená."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Miniaplikácia <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Výber používateľa"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Stav"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Fotoaparát"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Ovládacie prvky médií"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Zmena usporiadania miniaplikácií sa začala."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Zmena usporiadania miniaplikácií sa skončila."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Miniaplikácia <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> bola odstránená."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Rozšíriť oblasť na odomknutie."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Odomknutie prejdením prstom."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Odomknutie vzorom."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Odomknutie tvárou."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Odomknutie kódom PIN."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Odomknutie heslom."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Oblasť na zadanie bezpečnostného vzoru."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Oblasť na prejdenie prstom."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Tlačidlo Predchádzajúca stopa"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Tlačidlo Ďalšia stopa"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Tlačidlo Pozastaviť"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Tlačidlo Prehrať"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Tlačidlo Zastaviť"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Zrušiť"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Odstrániť"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Hotovo"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Zmena režimu"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Odomknúť"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Fotoaparát"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Tichý"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Zapnúť zvuk"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Vyhľadávanie"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Prejdite prstom nahor: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Prejdite prstom nadol: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Prejdite prstom doľava: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Prejdite prstom doprava: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Aktuálny používateľ je <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Tiesňové volanie"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Nepamätám si vzor"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Nesprávny vzor"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Nesprávne heslo"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Nesprávny kód PIN"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Skúste to znova o <xliff:g id="NUMBER">%d</xliff:g> s."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Nakreslite svoj vzor"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Zadajte kód PIN karty SIM"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Zadajte kód PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Zadajte heslo"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"Karta SIM je teraz zakázaná. Ak chcete pokračovať, zadajte kód PUK. Podrobné informácie získate od operátora."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Zadajte požadovaný kód PIN"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Potvrďte požadovaný kód PIN"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Prebieha odomykanie karty SIM..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Nesprávny kód PIN."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Zadajte kód PIN s dĺžkou 4 až 8 číslic."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Kód PUK musí obsahovať 8 alebo viac číslic."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Znova zadajte správny kód PUK. Opakované pokusy zakážu kartu SIM natrvalo."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Kódy PIN sa nezhodujú"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Príliš veľa pokusov o nakreslenie vzoru"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Ak chcete telefón odomknúť, prihláste sa pomocou svojho účtu Google."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Používateľské meno (e-mail)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Heslo"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Prihlásiť sa"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Neplatné používateľské meno alebo heslo."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Zabudli ste svoje používateľské meno alebo heslo?\n Navštívte stránky "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Prebieha kontrola účtu..."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste zadali nesprávny kód PIN. \n\nSkúste to znova o <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste zadali nesprávne heslo. \n\nSkúste to znova o <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste použili nesprávny bezpečnostný vzor. \n\nSkúste to znova o <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tablet ste sa pokúsili odomknúť nesprávnym spôsobom <xliff:g id="NUMBER_0">%d</xliff:g>-krát. Po <xliff:g id="NUMBER_1">%d</xliff:g> ďalších neúspešných pokusoch sa v tablete obnovia predvolené továrenské nastavenia a všetky používateľské údaje budú stratené."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Telefón ste sa pokúsili odomknúť nesprávnym spôsobom <xliff:g id="NUMBER_0">%d</xliff:g>-krát. Po <xliff:g id="NUMBER_1">%d</xliff:g> ďalších neúspešných pokusoch sa v telefóne obnovia predvolené továrenské nastavenia a všetky používateľské údaje budú stratené."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Tablet ste sa pokúsili odomknúť nesprávnym spôsobom <xliff:g id="NUMBER">%d</xliff:g>-krát. V tablete sa teraz obnovia predvolené továrenské nastavenia."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Telefón ste sa pokúsili odomknúť nesprávnym spôsobom <xliff:g id="NUMBER">%d</xliff:g>-krát. V telefóne sa teraz obnovia predvolené továrenské nastavenia."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste nesprávne nakreslili svoj bezpečnostný vzor. Po ďalších <xliff:g id="NUMBER_1">%d</xliff:g> neúspešných pokusoch sa zobrazí výzva na odomknutie tabletu pomocou e-mailového účtu.\n\n Skúste to znova o <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste nesprávne nakreslili svoj bezpečnostný vzor. Po <xliff:g id="NUMBER_1">%d</xliff:g> ďalších neúspešných pokusoch sa zobrazí výzva na odomknutie telefónu pomocou e-mailového účtu.\n\n Skúste to znova o <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Odstrániť"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Tlačidlo Predchádzajúca stopa"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Tlačidlo Ďalšia stopa"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Tlačidlo Pozastaviť"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Tlačidlo Prehrať"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Tlačidlo Zastaviť"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Žiadny signál"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-sl/activitystrings.xml b/packages/Keyguard/res/values-sl/activitystrings.xml
new file mode 100644
index 0000000..2c60219
--- /dev/null
+++ b/packages/Keyguard/res/values-sl/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Brez varnosti"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Geslo"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Vzorec"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"PIN za kartico SIM"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"PUK za kartico SIM"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Izberite pripomoček ..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-sl/strings.xml b/packages/Keyguard/res/values-sl/strings.xml
new file mode 100644
index 0000000..b6cfc1c
--- /dev/null
+++ b/packages/Keyguard/res/values-sl/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Vnesite kodo PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Vnesite kodo PUK in novo kodo PIN"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Koda PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Nova koda PIN"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Dotaknite se za vnos gesla"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Vnesite geslo za odklepanje"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Vnesite PIN za odklepanje"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Napačna koda PIN."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Če želite telefon odkleniti, pritisnite meni in nato 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Presegli ste dovoljeno število poskusov odklepanja z obrazom"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Napolnjeno"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Polnjenje, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Priključite napajalnik."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Če želite odkleniti, pritisnite meni."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Omrežje je zaklenjeno"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Ni kartice SIM"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"V tabličnem računalniku ni kartice SIM."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"V telefonu ni kartice SIM."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Vstavite kartico SIM."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"Kartice SIM ni ali je ni mogoče prebrati. Vstavite jo."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Neuporabna kartica SIM."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Kartica SIM je trajno onemogočena.\n Obrnite se na operaterja za drugo."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"Kartica SIM je zaklenjena."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"Kartica SIM je zaklenjena s kodo PUK."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Odklepanje kartice SIM …"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Pripomoček %2$d za %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Dodajanje pripomočka."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Prazno"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Območje odklepanja razširjeno."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Območje odklepanja strnjeno."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Pripomoček <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Izbirnik uporabnika"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Stanje"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Fotoaparat"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Kontrolniki predstavnosti"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Prerazporejanje pripomočkov začeto."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Prerazporejanje pripomočkov končano."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Pripomoček <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> izbrisan."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Razširitev območja odklepanja."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Odklepanje s podrsanjem."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Odklepanje z vzorcem."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Odklepanje z obrazom."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Odklepanje s kodo PIN."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Odklepanje z geslom."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Območje vzorca."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Območje podrsanja."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Gumb za prejšnjo skladbo"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Gumb za naslednjo skladbo"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Gumb za začasno ustavitev"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Gumb za predvajanje"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Gumb za ustavitev"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Tipka Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Prekliči"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Tipka Delete"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Končano"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Sprememba načina"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Tipka Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Tipka Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Odkleni"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Fotoaparat"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Tiho"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Vklopljen zvok"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Iskanje"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Povlecite navzgor za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Povlecite navzdol za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Povlecite v levo za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Povlecite v desno za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Trenutni uporabnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Klic v sili"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Pozabljen vzorec"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Napačen vzorec"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Napačno geslo"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Napačen PIN"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Čez <xliff:g id="NUMBER">%d</xliff:g> sekund poskusite znova."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Narišite vzorec"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Vnesite PIN za kartico SIM"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Vnesite PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Vnesite geslo"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"Kartica SIM je onemogočena. Če želite nadaljevati, vnesite kodo PUK. Za dodatne informacije se obrnite na operaterja."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Vnesite želeno kodo PIN"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Potrdite želeno kodo PIN"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Odklepanje kartice SIM ..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Napačna koda PIN."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Vnesite PIN, ki vsebuje od štiri do osem številk."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Koda PUK mora vsebovati 8 ali več števk."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Vnovič vnesite pravilno kodo PUK. Večkratni poskusi bodo trajno onemogočili kartico SIM."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Kodi PIN se ne ujemata"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Preveč poskusov vzorca"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Če želite odkleniti napravo, se prijavite z Google Računom."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Uporabniško ime (e-pošta)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Geslo"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Prijava"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Neveljavno uporabniško ime ali geslo."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Ali ste pozabili uporabniško ime ali geslo?\nObiščite "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Preverjanje računa ..."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN ste <xliff:g id="NUMBER_0">%d</xliff:g>-krat vnesli napačno. \n\nZnova poskusite čez <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Geslo ste <xliff:g id="NUMBER_0">%d</xliff:g>-krat vnesli napačno. \n\nZnova poskusite čez <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Vzorec za odklepanje ste nepravilno narisali <xliff:g id="NUMBER_0">%d</xliff:g>-krat. \n\nPoskusite znova čez <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tablični računalnik ste poskusili <xliff:g id="NUMBER_0">%d</xliff:g>-krat napačno odkleniti. Če poskusite še <xliff:g id="NUMBER_1">%d</xliff:g>-krat in ne uspete, bo ponastavljen na privzete tovarniške nastavitve in vsi uporabniški podatki bodo izgubljeni."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Telefon ste poskusili <xliff:g id="NUMBER_0">%d</xliff:g>-krat napačno odkleniti. Če poskusite še <xliff:g id="NUMBER_1">%d</xliff:g>-krat in ne uspete, bo ponastavljen na privzete tovarniške nastavitve in vsi uporabniški podatki bodo izgubljeni."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Tablični računalnik ste poskusili <xliff:g id="NUMBER">%d</xliff:g>-krat napačno odkleniti, zato bo ponastavljen na privzete tovarniške nastavitve."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Telefon ste poskusili <xliff:g id="NUMBER">%d</xliff:g>-krat napačno odkleniti, zato bo ponastavljen na privzete tovarniške nastavitve."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Vzorec za odklepanje ste <xliff:g id="NUMBER_0">%d</xliff:g>-krat napačno vnesli. Po nadaljnjih <xliff:g id="NUMBER_1">%d</xliff:g> neuspešnih poskusih boste pozvani, da tablični računalnik odklenete z e-poštnim računom.\n\nPoskusite znova čez <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Vzorec za odklepanje ste <xliff:g id="NUMBER_0">%d</xliff:g>-krat napačno vnesli. Po nadaljnjih <xliff:g id="NUMBER_1">%d</xliff:g> neuspešnih poskusih boste pozvani, da odklenete telefon z Googlovimi podatki za prijavo.\n\nPoskusite znova čez <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Odstrani"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Gumb za prejšnjo skladbo"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Gumb za naslednjo skladbo"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Gumb za začasno ustavitev"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Gumb za predvajanje"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Gumb za ustavitev"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Ni storitve."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-sr/activitystrings.xml b/packages/Keyguard/res/values-sr/activitystrings.xml
new file mode 100644
index 0000000..34802df
--- /dev/null
+++ b/packages/Keyguard/res/values-sr/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Без заштите"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Лозинка"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Шаблон"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"PIN SIM картице"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"PUK SIM картице"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Изабери виџет..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-sr/strings.xml b/packages/Keyguard/res/values-sr/strings.xml
new file mode 100644
index 0000000..937d029
--- /dev/null
+++ b/packages/Keyguard/res/values-sr/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Унесите PIN кôд"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Унесите PUK и нови PIN кôд"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK кôд"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Нови PIN кôд"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><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">"Унесите PIN за откључавање"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PIN кôд је нетачан."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Да бисте откључали, притисните „Мени“, а затим 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Премашен је највећи дозвољени број покушаја Откључавања лицем"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Напуњено"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Пуњење, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Повежите пуњач."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Притисните Мени да бисте откључали."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Мрежа је закључана"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Нема SIM картице"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"У таблету нема SIM картице."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"У телефону нема SIM картице."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Уметните SIM картицу."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM картица недостаје или не може да се прочита. Уметните SIM картицу."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"SIM картица је неупотребљива."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"SIM картица је трајно онемогућена.\n Обратите се добављачу услуге бежичне мреже да бисте добили другу SIM картицу."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM картица је закључана."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM картица је закључана PUK кодом."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Откључавање SIM картице…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Виџет %2$d од %3$d."</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_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>
+    <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_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">"Откључавање PIN-ом."</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="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Дугме за претходну песму"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Дугме за следећу песму"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Дугме за паузу"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Дугме за репродукцију"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Дугме за заустављање"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</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_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Откључај"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Нечујно"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Укључи звук"</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_down" msgid="5087739728639014595">"Превуците надоле за <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="description_direction_right" msgid="8034433242579600980">"Превуците удесно за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Актуелни корисник <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Хитни позив"</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">"Погрешан PIN"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Покушајте поново за <xliff:g id="NUMBER">%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>
+    <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">"Унесите жељени PIN кôд"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Потврдите жељени PIN кôд"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Откључавање SIM картице…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"PIN кôд је нетачан."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Унесите PIN који има од 4 до 8 бројева."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK кôд треба да има 8 или више бројева."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Поново унесите исправни PUK кôд. Поновљени покушаји ће трајно онемогућити SIM."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN кодови се не подударају"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Превише покушаја уноса шаблона"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Да бисте откључали, пријавите се помоћу Google налога."</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"Провера налога…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Унели сте PIN неисправно <xliff:g id="NUMBER_0">%d</xliff:g> пута. \n\nПокушајте поново за <xliff:g id="NUMBER_1">%d</xliff:g> секунде(и)."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Унели сте лозинку неисправно <xliff:g id="NUMBER_0">%d</xliff:g> пута. \n\nПокушајте поново за <xliff:g id="NUMBER_1">%d</xliff:g> секунде(и)."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Нацртали сте шаблон за откључавање неисправно <xliff:g id="NUMBER_0">%d</xliff:g> пута. \n\nПокушајте поново за <xliff:g id="NUMBER_1">%d</xliff:g> секунде(и)."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Покушали сте да откључате таблет неисправно <xliff:g id="NUMBER_0">%d</xliff:g> пута. Након још <xliff:g id="NUMBER_1">%d</xliff:g> неуспешна(их) покушаја таблет ће бити враћен на подразумевана фабричка подешавања и сви кориснички подаци ће бити изгубљени."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Покушали сте да откључате телефон неисправно <xliff:g id="NUMBER_0">%d</xliff:g> пута. После још <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> пута. После још <xliff:g id="NUMBER_1">%d</xliff:g> неуспешна(их) покушаја, од вас ће бити затражено да откључате таблет помоћу налога е-поште.\n\nПокушајте поново за <xliff:g id="NUMBER_2">%d</xliff:g> секунде(и)."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Нацртали сте шаблон за откључавање неисправно <xliff:g id="NUMBER_0">%d</xliff:g> пута. После још <xliff:g id="NUMBER_1">%d</xliff:g> неуспешна(их) покушаја, од вас ће бити затражено да откључате телефон помоћу налога е-поште.\n\nПокушајте поново за <xliff:g id="NUMBER_2">%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="keyguard_transport_prev_description" msgid="8229108430245669854">"Дугме за претходну песму"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Дугме за следећу песму"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Дугме за паузу"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Дугме за репродукцију"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Дугме за заустављање"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Офлајн сте."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-sv/activitystrings.xml b/packages/Keyguard/res/values-sv/activitystrings.xml
new file mode 100644
index 0000000..e664383
--- /dev/null
+++ b/packages/Keyguard/res/values-sv/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Ingen säkerhet"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN-kod"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Lösenord"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Grafiskt lösenord"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"PIN-kod för SIM-kort"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"PUK-kod för SIM-kort"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Välj widget ..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-sv/strings.xml b/packages/Keyguard/res/values-sv/strings.xml
new file mode 100644
index 0000000..fb0f912
--- /dev/null
+++ b/packages/Keyguard/res/values-sv/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Ange PIN-kod"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Ange PUK-koden och en ny PIN-kod"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-kod"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Ny PIN-kod"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Tryck om du vill ange lösenord"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Ange lösenord för att låsa upp"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Ange PIN-kod för att låsa upp"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Fel PIN-kod."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Tryck på Menu och sedan på 0 om du vill låsa upp."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Du har försökt låsa upp med Ansiktslås för många gånger"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Batteriet har laddats"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Laddar, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Anslut din laddare."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Tryck på Meny om du vill låsa upp."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Nätverk låst"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Inget SIM-kort"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Inget SIM-kort i surfplattan."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Inget SIM-kort i mobilen."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Sätt i ett SIM-kort."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM-kort saknas eller kan inte läsas. Sätt i ett SIM-kort."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Oanvändbart SIM-kort."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"SIM-kortet har inaktiverats permanent.\n Beställ ett nytt SIM-kort från din operatör."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM-kortet är låst."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM-kortet är PUK-låst."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Låser upp SIM-kort …"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d av %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Lägg till en widget."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tom"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Expanderad upplåsningsyta."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Komprimerad upplåsningsyta."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget för <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Användarväljare"</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">"Mediereglage"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Ändring av widgetarnas ordning har påbörjats."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Ändring av widgetarnas ordning har avslutats."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widgeten <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> har tagits bort."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Expandera upplåsningsytan."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Lås upp genom att dra."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Lås upp med grafiskt lösenord."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Lås upp med Ansiktslås."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Lås upp med PIN-kod."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Lås upp med lösenord."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Fält för grafiskt lösenord."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Fält med dragreglage."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Knapp för föregående spår"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Knapp för nästa spår"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Pausknappen"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Uppspelningsknappen"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Stoppknappen"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Avbryt"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Klar"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Funktionsändring"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Skift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Retur"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Lås upp"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Tyst"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Ljud på"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Sök"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Dra uppåt för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Dra nedåt för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Dra åt vänster för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Dra åt höger för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Nuvarande användare: <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Nödsamtal"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Har du glömt ditt grafiska lösenord?"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Fel grafiskt lösenord"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Fel lösenord"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Fel PIN-kod"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Försök igen om <xliff:g id="NUMBER">%d</xliff:g> sekunder."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Rita ditt grafiska lösenord"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Ange PIN-kod för SIM-kortet"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Ange PIN-kod"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Ange lösenord"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM-kortet är nu inaktiverat. Ange PUK-koden om du vill fortsätta. Kontakta operatören om du vill få mer information."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Ange önskad PIN-kod"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Bekräfta önskad PIN-kod"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Låser upp SIM-kort …"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Fel PIN-kod."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Ange en PIN-kod med 4 till 8 siffror."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK-koden ska vara minst åtta siffror."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Ange rätt PUK-kod igen. Om försöken upprepas inaktiveras SIM-kortet permanent."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-koderna stämmer inte överens"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"För många försök med grafiskt lösenord"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Logga in med ditt Google-konto om du vill låsa upp."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Användarnamn (e-post)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Lösenord"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Logga in"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Ogiltigt användarnamn eller lösenord."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Har du glömt ditt användarnamn eller lösenord?\nBesök "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Kontot kontrolleras …"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Du har angett fel lösenord <xliff:g id="NUMBER_0">%d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Du har angett fel lösenord <xliff:g id="NUMBER_0">%d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. \n\nFörsök igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Du har försökt låsa upp mobilen på fel sätt <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> misslyckade försök återställs surfplattan till fabriksinställningarna. Du förlorar då alla användardata."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Du har försökt låsa upp mobilen på fel sätt <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> misslyckade försök återställs mobilen till fabriksinställningarna. Du förlorar då alla användardata."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Du har försökt låsa upp surfplattan på fel sätt <xliff:g id="NUMBER">%d</xliff:g> gånger. Surfplattan återställs nu till fabriksinställningarna."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Du har försökt låsa upp mobilen på fel sätt <xliff:g id="NUMBER">%d</xliff:g> gånger. Mobilen återställs nu till fabriksinställningarna."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> försök ombeds du låsa upp surfplattan med ett e-postkonto.\n\n Försök igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> försök ombeds du låsa upp mobilen med hjälp av ett e-postkonto.\n\n Försök igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Ta bort"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Knapp för föregående spår"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Knapp för nästa spår"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Pausknappen"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Uppspelningsknappen"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Stoppknappen"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Ingen tjänst."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-sw/activitystrings.xml b/packages/Keyguard/res/values-sw/activitystrings.xml
new file mode 100644
index 0000000..357b911
--- /dev/null
+++ b/packages/Keyguard/res/values-sw/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Hakuna usalama"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Nenosiri"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Ruwaza"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"PIN ya SIM"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"PUK ya SIM"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Chagua wijeti..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-sw/strings.xml b/packages/Keyguard/res/values-sw/strings.xml
new file mode 100644
index 0000000..27f1f30
--- /dev/null
+++ b/packages/Keyguard/res/values-sw/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Ingiza msimbo wa PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Ingiza PUK na msimbo mpya wa PIN"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Msimbo wa PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Msimbo mpya wa PIN"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Gusa kuingiza nenosiri "</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Charaza nenosiri ili kufungua"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Ingiza PIN ili kufungua"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Msimbo wa PIN usio sahihi."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Ili kufungua, bofya Menyu kisha 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Majaribio ya Juu ya Kufungua Uso yamezidishwa"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Imechajiwa"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Inachaji, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Unganisha chaja yako."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Bonyeza Menyu ili kufungua."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Mtandao umefungwa"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Hakuna SIM kadi"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Hakuna SIM kadi katika kompyuta ndogo."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Hakuna SIM kadi kwenye simu."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Ingiza SIM kadi."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM kadi haiko au haisomeki. Ingiza SIM kadi."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"SIM kadi isiyotumika."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"SIM kadi yako imefungwa kabisa.\n Wasiliana na mtoa huduma wako wa pasi waya ili upate SIM kadi nyingine."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM kadi imefungwa."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM kadi imefungwa na PUK."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Inafungua SIM kadi..."</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Wiji %2$d ya %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Ongeza wiji"</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tupu"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Eneo la kufungua limepanuliwa."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Eneo la kufungua limekunjwa."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> ya wiji."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Kiteuzi cha mtumiaji"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Hali"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Kamera"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Vidhibiti vya media"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Upangaji upya wa wiji umeanza."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Upangaji upya wa wiji umekamilika."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Wiji <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> imefutwa."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Panua eneo la kufungua."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Kufungua slaidi."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Kufungua kwa ruwaza."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Kufungua kwa uso."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Kufungua kwa PIN."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Kufungua kwa nenosiri."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Eneo la ruwaza."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Eneo la slaidi."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Kitufe cha wimbo uliotangulia"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Kitufe cha wimbo unaofuata"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Kitufe cha kusitisha"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Kitufe cha kucheza"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Kitufe cha kusitisha"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Ghairi"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Futa"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Nimemaliza"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Modi ya mabadiliko"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Songa"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Fungua"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Kimya"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Sauti imewashwa"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Tafuta"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Sogeza juu kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Sogeza chini kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Sogeza kushoto kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Sogeza kulika kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Mtumiaji wa sasa <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Simu ya dharura"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Umesahau Ruwaza"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Mchoro Usio sahihi"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Nenosiri Lisilo sahihi"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN isiyo sahihi"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Jaribu tena baada ya sekunde <xliff:g id="NUMBER">%d</xliff:g>."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Chora ruwaza yako"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Ingiza PIN ya SIM"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Ingiza PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Ingiza Nenosiri"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM sasa imelemazwa. Ingiza msimbo wa PUK ili kuendelea. Wasiliana na mtoa huduma kwa maelezo."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Ingiza msimbo wa PIN unaopendelewa"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Thibitisha msimbo wa PIN unaopendelewa"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Inafungua SIM kadi..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Msimbo wa PIN usio sahihi."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Charaza PIN iliyo na tarakimu kati ya 4 na 8."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Msimbo wa PUK unafaa kuwa na nambari 8 au zaidi."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Ingiza upya msimbo sahihi wa PUK. Majaribio yanayorudiwa yatalemaza SIM kabisa."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Misimbo ya PIN haifanani"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Majaribio mengi mno ya mchoro"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Ili kufungua, ingia kwa Akaunti yako ya Google."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Jina la mtumiaji (barua pepe)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Nenosiri"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Ingia"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Jina la mtumiaji au nenosiri batili."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Je, umesahau jina lako la mtumiaji au nenosiri?\nTembela "<b>"Bgoogle.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Inakagua akaunti…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Umeingiza nenosiri lako kwa makosa mara <xliff:g id="NUMBER_0">%d</xliff:g>. \n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Umeingiza nenosiri lako kwa makosa mara <xliff:g id="NUMBER_0">%d</xliff:g>. \n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Umechora ruwaza yako ya kufunga kwa makosa mara <xliff:g id="NUMBER_0">%d</xliff:g>. \n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Umejaribu kufungua kompyuta ndogo kwa njia isiyo sahihi mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> zaidi yasiyofaulu, kompyuta ndogo itarejeshwa katika mfumo chaguo-msingi ilivyotoka kiwandani data yote ya mtumiaji itapotea."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Umejaribu kufungua simu kwa njia isiyo sahihi mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> zaidi yasiyofaulu, simu itarejeshwa katika mfumo chaguo-msingi ilivyotoka kiwandani na data yote ya mtumiaji itapotea."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Umejaribu kufungua kompyuta ndogo kwa njia isiyo sahihi mara <xliff:g id="NUMBER">%d</xliff:g>. Sasa kompyuta ndogo itarejeshwa katika mfumo chaguo-msingi ilivyotoka kiwandani."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Umejaribu kufungua simu kwa njia isiyo sahihi mara <xliff:g id="NUMBER">%d</xliff:g>. Sasa simu  itarejeshwa katika mfumo chaguo-msingi ilivyotoka kiwandani."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Umekosea katika kuweka mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> bila kufaulu, utaombwa kufungua kompyuta yako ndogo kwa kutumia akaunti yako ya barua pepe.\n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_2">%d</xliff:g>."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Umekosea kuchora mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> yasiyofaulu, utaombwa kufungua simu yako kwa kutumia akaunti ya barua pepe.\n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_2">%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">"Ondoa"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Kitufe cha wimbo wa awali"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Kitufe cha wimbo unaofuata"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Kitufe cha kusitisha"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Kitufe cha kucheza"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Kitufe cha kusimamisha"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Hakuna huduma."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-sw320dp/dimens.xml b/packages/Keyguard/res/values-sw320dp/dimens.xml
new file mode 100644
index 0000000..2c209e2
--- /dev/null
+++ b/packages/Keyguard/res/values-sw320dp/dimens.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/dimens.xml
+**
+** Copyright 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.
+*/
+-->
+<resources>
+
+    <!-- Height of the sliding KeyguardSecurityContainer (includes 2x keyguard_security_view_margin) -->
+    <dimen name="keyguard_security_height">345dp</dimen>
+
+</resources>
diff --git a/packages/Keyguard/res/values-sw360dp/dimens.xml b/packages/Keyguard/res/values-sw360dp/dimens.xml
new file mode 100644
index 0000000..41d6ac0
--- /dev/null
+++ b/packages/Keyguard/res/values-sw360dp/dimens.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/dimens.xml
+**
+** Copyright 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.
+*/
+-->
+<resources>
+
+    <!-- Height of the sliding KeyguardSecurityContainer (includes 2x keyguard_security_view_margin) -->
+    <dimen name="keyguard_security_height">400dp</dimen>
+
+</resources>
diff --git a/packages/Keyguard/res/values-sw380dp-land/dimens.xml b/packages/Keyguard/res/values-sw380dp-land/dimens.xml
new file mode 100644
index 0000000..20eb1be
--- /dev/null
+++ b/packages/Keyguard/res/values-sw380dp-land/dimens.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/dimens.xml
+**
+** 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.
+*/
+-->
+<resources>
+    <!-- Top margin for the clock view --> 
+    <dimen name="kg_clock_top_margin">48dp</dimen>
+</resources>
diff --git a/packages/Keyguard/res/values-sw380dp/dimens.xml b/packages/Keyguard/res/values-sw380dp/dimens.xml
new file mode 100644
index 0000000..fc0e85d
--- /dev/null
+++ b/packages/Keyguard/res/values-sw380dp/dimens.xml
@@ -0,0 +1,23 @@
+<?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.
+*/
+-->
+
+<resources>
+    <!-- Width of the sliding KeyguardSecurityContainer (includes 2x keyguard_security_view_margin) -->
+    <dimen name="keyguard_security_width">340dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/packages/Keyguard/res/values-sw600dp-land/arrays.xml b/packages/Keyguard/res/values-sw600dp-land/arrays.xml
new file mode 100644
index 0000000..5550216
--- /dev/null
+++ b/packages/Keyguard/res/values-sw600dp-land/arrays.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/colors.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR 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">
+
+    <!-- Resources for GlowPadView in LockScreen -->
+    <array name="lockscreen_targets_when_silent">
+        <item>@drawable/ic_lockscreen_unlock</item>
+        <item>@null</item>
+        <item>@drawable/ic_lockscreen_soundon</item>
+        <item>@null</item>
+    </array>
+
+    <array name="lockscreen_target_descriptions_when_silent">
+        <item>@string/description_target_unlock</item>
+        <item>@null</item>
+        <item>@string/description_target_soundon</item>
+        <item>@null</item>
+    </array>
+
+    <array name="lockscreen_direction_descriptions">
+        <item>@string/description_direction_right</item>
+        <item>@null</item>
+        <item>@string/description_direction_left</item>
+        <item>@null</item>
+    </array>
+
+    <array name="lockscreen_targets_when_soundon">
+        <item>@drawable/ic_lockscreen_unlock</item>
+        <item>@null</item>
+        <item>@drawable/ic_lockscreen_silent</item>
+        <item>@null</item>
+    </array>
+
+    <array name="lockscreen_target_descriptions_when_soundon">
+        <item>@string/description_target_unlock</item>
+        <item>@null</item>
+        <item>@string/description_target_silent</item>
+        <item>@null</item>
+    </array>
+
+    <array name="lockscreen_targets_with_camera">
+        <item>@drawable/ic_lockscreen_unlock</item>
+        <item>@drawable/ic_action_assist_generic</item>
+        <item>@drawable/ic_lockscreen_camera</item>
+        <item>@null</item>
+    </array>
+
+    <array name="lockscreen_target_descriptions_with_camera">
+        <item>@string/description_target_unlock</item>
+        <item>@string/description_target_search</item>
+        <item>@string/description_target_camera</item>
+        <item>@null</item>
+    </array>
+
+</resources>
diff --git a/packages/Keyguard/res/values-sw600dp-land/dimens.xml b/packages/Keyguard/res/values-sw600dp-land/dimens.xml
new file mode 100644
index 0000000..5507e5f
--- /dev/null
+++ b/packages/Keyguard/res/values-sw600dp-land/dimens.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/dimens.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+    <!-- Top margin for the clock view --> 
+    <dimen name="kg_clock_top_margin">85dp</dimen>
+
+    <!-- Size of margin on the right of keyguard's status view -->
+    <dimen name="kg_status_line_font_right_margin">16dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/packages/Keyguard/res/values-sw600dp-land/integers.xml b/packages/Keyguard/res/values-sw600dp-land/integers.xml
new file mode 100644
index 0000000..b724c90
--- /dev/null
+++ b/packages/Keyguard/res/values-sw600dp-land/integers.xml
@@ -0,0 +1,23 @@
+<?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.
+*/
+-->
+<resources>
+    <integer name="kg_widget_region_weight">50</integer>
+    <integer name="kg_security_flipper_weight">50</integer>
+    <integer name="kg_glowpad_rotation_offset">0</integer>
+</resources>
diff --git a/packages/Keyguard/res/values-sw600dp-port/integers.xml b/packages/Keyguard/res/values-sw600dp-port/integers.xml
new file mode 100644
index 0000000..65b854a
--- /dev/null
+++ b/packages/Keyguard/res/values-sw600dp-port/integers.xml
@@ -0,0 +1,22 @@
+<?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.
+*/
+-->
+<resources>
+    <integer name="kg_widget_region_weight">46</integer>
+    <integer name="kg_security_flipper_weight">54</integer>
+</resources>
\ No newline at end of file
diff --git a/packages/Keyguard/res/values-sw600dp/alias.xml b/packages/Keyguard/res/values-sw600dp/alias.xml
new file mode 100644
index 0000000..c3ecbb9
--- /dev/null
+++ b/packages/Keyguard/res/values-sw600dp/alias.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/colors.xml
+**
+** 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.
+*/
+-->
+<resources>
+    <!-- Alias used to reference one of two possible layouts in keyguard.  -->
+    <item type="layout" name="keyguard_eca">@layout/keyguard_emergency_carrier_area</item>
+</resources>
diff --git a/packages/Keyguard/res/values-sw600dp/bools.xml b/packages/Keyguard/res/values-sw600dp/bools.xml
new file mode 100644
index 0000000..ddc48c5
--- /dev/null
+++ b/packages/Keyguard/res/values-sw600dp/bools.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources>
+    <bool name="target_honeycomb_needs_options_menu">false</bool>
+    <bool name="show_ongoing_ime_switcher">true</bool>
+    <bool name="kg_share_status_area">false</bool>
+    <bool name="kg_sim_puk_account_full_screen">false</bool>
+    <bool name="kg_show_ime_at_screen_on">false</bool>
+    <!-- No camera for you, tablet user -->
+    <bool name="kg_enable_camera_default_widget">false</bool>
+    <bool name="kg_center_small_widgets_vertically">true</bool>
+    <bool name="kg_top_align_page_shrink_on_bouncer_visible">false</bool>
+</resources>
diff --git a/packages/Keyguard/res/values-sw600dp/dimens.xml b/packages/Keyguard/res/values-sw600dp/dimens.xml
new file mode 100644
index 0000000..c0e3937
--- /dev/null
+++ b/packages/Keyguard/res/values-sw600dp/dimens.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/dimens.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+    <!-- Size of clock font in LockScreen. -->
+    <dimen name="keyguard_pattern_unlock_clock_font_size">112sp</dimen>
+
+    <!-- Size of lockscreen outerring on unsecure unlock LockScreen -->
+    <dimen name="keyguard_lockscreen_outerring_diameter">364dp</dimen>
+
+    <!-- Height of FaceUnlock view in keyguard -->
+    <dimen name="face_unlock_height">430dip</dimen>
+
+    <!-- target placement radius for GlowPadView. Should be 1/2 of outerring diameter. -->
+    <dimen name="glowpadview_target_placement_radius">182dip</dimen>
+
+    <!-- Size of status line font in LockScreen. -->
+    <dimen name="keyguard_pattern_unlock_status_line_font_size">14sp</dimen>
+
+    <!-- Keyguard dimensions -->
+    <!-- Size of the clock font in keyguard's status view -->
+    <dimen name="kg_status_clock_font_size">141dp</dimen>
+
+    <!-- Size of the date font in keyguard's status view  -->
+    <dimen name="kg_status_date_font_size">25.5dp</dimen>
+
+    <!-- Size of the generic status lines keyguard's status view  -->
+    <dimen name="kg_status_line_font_size">16sp</dimen>
+
+    <!-- Top margin for the clock view --> 
+    <dimen name="kg_clock_top_margin">0dp</dimen>
+
+    <!-- Size of margin on the right of keyguard's status view -->
+    <dimen name="kg_status_line_font_right_margin">50dp</dimen>
+
+    <!-- Horizontal padding for the widget pager -->
+    <dimen name="kg_widget_pager_horizontal_padding">24dp</dimen>
+
+    <!-- Top padding for the widget pager -->
+    <dimen name="kg_widget_pager_top_padding">0dp</dimen>
+
+    <!-- Bottom padding for the widget pager -->
+    <dimen name="kg_widget_pager_bottom_padding">0dp</dimen>
+
+    <!-- Top margin for the runway lights. We add a negative margin in large
+        devices to account for the widget pager padding -->
+    <dimen name="kg_runway_lights_top_margin">-10dp</dimen>
+
+    <!-- Margin around the various security views -->
+    <dimen name="keyguard_security_view_margin">12dp</dimen>
+
+    <!-- Margin around the various security views -->
+    <dimen name="keyguard_muliuser_selector_margin">12dp</dimen>
+
+</resources>
diff --git a/packages/Keyguard/res/values-sw600dp/integers.xml b/packages/Keyguard/res/values-sw600dp/integers.xml
new file mode 100644
index 0000000..de9829c
--- /dev/null
+++ b/packages/Keyguard/res/values-sw600dp/integers.xml
@@ -0,0 +1,21 @@
+<?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.
+*/
+-->
+<resources>
+    <integer name="kg_carousel_angle">60</integer>
+</resources>
diff --git a/packages/Keyguard/res/values-sw720dp-land/dimens.xml b/packages/Keyguard/res/values-sw720dp-land/dimens.xml
new file mode 100644
index 0000000..14726ab
--- /dev/null
+++ b/packages/Keyguard/res/values-sw720dp-land/dimens.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/dimens.xml
+**
+** 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.
+*/
+-->
+<resources>
+    <!-- Top margin for the clock view --> 
+    <dimen name="kg_clock_top_margin">174dp</dimen>
+
+    <!-- Size of margin on the right of keyguard's status view -->
+    <dimen name="kg_status_line_font_right_margin">16dp</dimen>
+
+    <!-- Horizontal padding for the widget pager -->
+    <dimen name="kg_widget_pager_horizontal_padding">32dp</dimen>
+</resources>
diff --git a/packages/Keyguard/res/values-sw720dp-port/integers.xml b/packages/Keyguard/res/values-sw720dp-port/integers.xml
new file mode 100644
index 0000000..5f85f71
--- /dev/null
+++ b/packages/Keyguard/res/values-sw720dp-port/integers.xml
@@ -0,0 +1,22 @@
+<?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.
+*/
+-->
+<resources>
+    <integer name="kg_widget_region_weight">48</integer>
+    <integer name="kg_security_flipper_weight">52</integer>
+</resources>
\ No newline at end of file
diff --git a/packages/Keyguard/res/values-sw720dp/dimens.xml b/packages/Keyguard/res/values-sw720dp/dimens.xml
new file mode 100644
index 0000000..b29ac22
--- /dev/null
+++ b/packages/Keyguard/res/values-sw720dp/dimens.xml
@@ -0,0 +1,66 @@
+<?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.
+*/
+-->
+<resources>
+    <!-- Keyguard dimensions -->
+    <!-- Size of the clock font in keyguard's status view -->
+    <dimen name="kg_status_clock_font_size">188dp</dimen>
+
+    <!-- Size of the date font in keyguard's status view  -->
+    <dimen name="kg_status_date_font_size">34dp</dimen>
+
+    <!-- Size of the generic status lines keyguard's status view  -->
+    <dimen name="kg_status_line_font_size">19sp</dimen>
+
+    <!-- Top margin for the clock view --> 
+    <dimen name="kg_clock_top_margin">0dp</dimen>
+
+    <!-- Size of margin on the right of keyguard's status view -->
+    <dimen name="kg_status_line_font_right_margin">32dp</dimen>
+
+    <!-- Horizontal padding for the widget pager -->
+    <dimen name="kg_widget_pager_horizontal_padding">80dp</dimen>
+
+    <!-- Top padding for the widget pager -->
+    <dimen name="kg_widget_pager_top_padding">0dp</dimen>
+
+    <!-- Bottom padding for the widget pager -->
+    <dimen name="kg_widget_pager_bottom_padding">0dp</dimen>
+
+    <!-- Top margin for the runway lights. We add a negative margin in large
+        devices to account for the widget pager padding -->
+    <dimen name="kg_runway_lights_top_margin">-30dp</dimen>
+
+    <!-- Margin around the various security views -->
+    <dimen name="keyguard_muliuser_selector_margin">24dp</dimen>
+
+    <!-- Stroke width of the frame for the circular avatars. -->
+    <dimen name="keyguard_avatar_frame_stroke_width">3dp</dimen>
+
+    <!-- Size of the avator on the multiuser lockscreen. -->
+    <dimen name="keyguard_avatar_size">88dp</dimen>
+
+    <!-- Size of the text under the avator on the multiuser lockscreen. -->
+    <dimen name="keyguard_avatar_name_size">12sp</dimen>
+
+    <!-- Width of the sliding KeyguardSecurityContainer (includes 2x keyguard_security_view_margin) -->
+    <dimen name="keyguard_security_width">420dp</dimen>
+
+    <!-- Height of the sliding KeyguardSecurityContainer (includes 2x keyguard_security_view_margin) -->
+    <dimen name="keyguard_security_height">420dp</dimen>
+</resources>
diff --git a/packages/Keyguard/res/values-th/activitystrings.xml b/packages/Keyguard/res/values-th/activitystrings.xml
new file mode 100644
index 0000000..64f50cc
--- /dev/null
+++ b/packages/Keyguard/res/values-th/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"ไม่มีการรักษาความปลอดภัย"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"รหัสผ่าน"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"รูปแบบ"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"PIN ของซิม"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"PUK ของซิม"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"เลือกวิดเจ็ต..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-th/strings.xml b/packages/Keyguard/res/values-th/strings.xml
new file mode 100644
index 0000000..d6308b6
--- /dev/null
+++ b/packages/Keyguard/res/values-th/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"พิมพ์รหัส PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"พิมพ์ PUK และรหัส PIN ใหม่"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"รหัส PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"รหัส PIN ใหม่"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><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">"พิมพ์ PIN เพื่อปลดล็อก"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"รหัส PIN ไม่ถูกต้อง"</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"หากต้องการปลดล็อก กด เมนู ตามด้วย 0"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"มีความพยายามที่จะใช้ Face Unlock เกินขีดจำกัด"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"ชาร์จแล้ว"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"กำลังชาร์จ, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"เสียบที่ชาร์จของคุณ"</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"กด \"เมนู\" เพื่อปลดล็อก"</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"เครือข่ายล็อก"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"ไม่มีซิมการ์ด"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"ไม่มีซิมการ์ดในแท็บเล็ต"</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"ไม่มีซิมการ์ดในโทรศัพท์"</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"ใส่ซิมการ์ด"</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"ไม่มีหรือไม่สามารถอ่านซิมการ์ดได้ โปรดใส่ซิมการ์ด"</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"ซิมการ์ดใช้ไม่ได้"</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"ซิมการ์ดของคุณถูกปิดใช้งานอย่างถาวร\nติดต่อผู้ให้บริการระบบไร้สายของคุณเพื่อรับซิมการ์ดใหม่"</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"ซิมการ์ดถูกล็อก"</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"ซิมการ์ดถูกล็อกด้วย PUK"</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"กำลังปลดล็อกซิมการ์ด…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s วิดเจ็ต %2$d ของ %3$d"</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_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>
+    <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_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">"การปลดล็อกด้วย PIN"</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="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"ปุ่มแทร็กก่อนหน้า"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"ปุ่มแทร็กถัดไป"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"ปุ่มหยุดชั่วคราว"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"ปุ่มเล่น"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"ปุ่มหยุด"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</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_enter" msgid="2985864015076059467">"ป้อน"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"ปลดล็อก"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"กล้อง"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"ปิดเสียง"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"เปิดเสียง"</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_down" msgid="5087739728639014595">"เลื่อนลงเพื่อ <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="description_direction_right" msgid="8034433242579600980">"เลื่อนไปทางขวาเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
+    <string name="user_switched" msgid="3768006783166984410">"ผู้ใช้ปัจจุบัน <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"หมายเลขฉุกเฉิน"</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">"PIN ไม่ถูกต้อง"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"ลองอีกครั้งในอีก <xliff:g id="NUMBER">%d</xliff:g> วินาที"</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"วาดรูปแบบของคุณ"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"ป้อน PIN ของซิม"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"ป้อน PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"ป้อนรหัสผ่าน"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"ซิมการ์ดถูกปิดใช้งานแล้วในตอนนี้ ป้อนรหัส PUK เพื่อดำเนินการต่อ โปรดติดต่อผู้ให้บริการสำหรับรายละเอียด"</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"ป้อนรหัส PIN ที่ต้องการ"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"ยืนยันรหัส PIN ที่ต้องการ"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"กำลังปลดล็อกซิมการ์ด…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"รหัส PIN ไม่ถูกต้อง"</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"พิมพ์ PIN ซึ่งเป็นเลข 4 ถึง 8 หลัก"</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"รหัส PUK ต้องเป็นตัวเลขอย่างน้อย 8 หลัก"</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"ใส่รหัส PUK ที่ถูกต้องอีกครั้ง การพยายามซ้ำหลายครั้งจะทำให้ซิมการ์ดถูกปิดใช้งานอย่างถาวร"</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"รหัส PIN ไม่ตรง"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ลองหลายรูปแบบมากเกินไป"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"หากต้องการปลดล็อก ให้ลงชื่อเข้าใช้ด้วยบัญชี Google ของคุณ"</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"กำลังตรวจสอบบัญชี…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"คุณพิมพ์ PIN ไม่ถูกต้องไป <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว \n\nโปรดลองอีกครั้งใน <xliff:g id="NUMBER_1">%d</xliff:g> วินาที"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"คุณพิมพ์รหัสผ่านไม่ถูกต้องไป <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว \n\nโปรดลองอีกครั้งใน <xliff:g id="NUMBER_1">%d</xliff:g> วินาที"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้องไป <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว \n\nโปรดลองอีกครั้งใน <xliff:g id="NUMBER_1">%d</xliff:g> วินาที"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"คุณพยายามปลดล็อกแท็บเล็ตอย่างไม่ถูกต้อง <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว หากพยายามแล้วไม่สำเร็จอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง แท็บเล็ตจะถูกรีเซ็ตเป็นค่าเริ่มต้นจากโรงงานและข้อมูลผู้ใช้ทั้งหมดจะหายไป"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"คุณพยายามปลดล็อกโทรศัพท์อย่างไม่ถูกต้อง <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว หากพยายามแล้วไม่สำเร็จอีก <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> ครั้งแล้ว หากทำไม่สำเร็จอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง ระบบจะขอให้คุณปลดล็อกแท็บเล็ตโดยใช้บัญชีอีเมล\n\n โปรดลองอีกครั้งใน <xliff:g id="NUMBER_2">%d</xliff:g> วินาที"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้อง <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว หากทำไม่สำเร็จอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง ระบบจะขอให้คุณปลดล็อกโทรศัพท์โดยใช้ับัญชีอีเมล\n\n โปรดลองอีกครั้งในอีก <xliff:g id="NUMBER_2">%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="keyguard_transport_prev_description" msgid="8229108430245669854">"ปุ่มแทร็กก่อนหน้า"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"ปุ่มแทร็กถัดไป"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"ปุ่มหยุดชั่วคราว"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"ปุ่มเล่น"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"ปุ่มหยุด"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"ไม่มีบริการ"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-tl/activitystrings.xml b/packages/Keyguard/res/values-tl/activitystrings.xml
new file mode 100644
index 0000000..71f3564
--- /dev/null
+++ b/packages/Keyguard/res/values-tl/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Walang seguridad"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Password"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Pattern"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"SIM PIN"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"SIM PUK"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Pumili ng widget..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenNaka-off"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenNaka-on"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-tl/strings.xml b/packages/Keyguard/res/values-tl/strings.xml
new file mode 100644
index 0000000..a41d268
--- /dev/null
+++ b/packages/Keyguard/res/values-tl/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"I-type ang PIN code"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"I-type ang PUK at bagong PIN code"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK code"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Bagong PIN code"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Pindutin upang i-type password"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"I-type ang password upang i-unlock"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"I-type ang PIN upang i-unlock"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Maling PIN code."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Upang i-unlock, pindutin ang Menu pagkatapos ay 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Nalagpasan na ang maximum na mga pagtatangka sa Face Unlock"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Na-charge"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Nagcha-charge, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Ikonekta ang iyong charger."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Pindutin ang Menu upang i-unlock."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Naka-lock ang network"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Walang SIM card"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Walang SIM card sa tablet."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Walang SIM card sa telepono."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Maglagay ng SIM card."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"Wala o hindi nababasa ang SIM card. Maglagay ng SIM card."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Hindi nagagamit na SIM card."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Ang iyong SIM card ay permanenteng hindi pinagana.\n Makipag-ugnay sa iyong wireless service provider para sa isa pang SIM card."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"Naka-lock ang SIM card."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"Naka-lock ang SIM card gamit ang PUK."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Ina-unlock ang SIM card…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d ng %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Magdagdag ng widget."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Walang laman"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Pinalaki ang bahagi ng pag-unlock."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Pinaliit ang bahagi ng pag-unlock."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> widget."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Tagapili ng user"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Katayuan"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Camera"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Mga kontrol ng media"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Nagsimula na ang pagbabago ng ayos ng widget."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Natapos na ang pagbabago ng ayos ng widget."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Tinanggal ang widget na <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Palakihin ang bahagi ng pag-unlock."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Pag-unlock ng slide."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Pag-unlock ng pattern."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Face unlock."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Pag-unlock ng pin."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Pag-unlock ng password."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Bahagi ng pattern."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Bahagi ng slide."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Button na Nakaraang track"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Button na Susunod na track"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Button na I-pause"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Button na I-play"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Button na Ihinto"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Kanselahin"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Tanggalin"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Tapos na"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Pagbabago ng Mode"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"I-unlock"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Camera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Tahimik"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"I-on ang tunog"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Maghanap"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Mag-slide pataas para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Mag-slide pababa para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Mag-slide pakaliwa para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Mag-slide pakanan para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Kasalukuyang user <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Emergency na tawag"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Nakalimutan ang Pattern"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Maling Pattern"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Maling Password"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Maling PIN"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Subukang muli sa loob ng <xliff:g id="NUMBER">%d</xliff:g> (na) segundo."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Iguhit ang iyong pattern"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Ilagay ang SIM PIN"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Ilagay ang PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Ilagay ang Password"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"Hindi na pinagana ang SIM ngayon. Maglagay ng PUK code upang magpatuloy. Makipag-ugnay sa carrier para sa mga detalye."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Ilagay ang ninanais na PIN code"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Kumpirmahin ang ninanais na PIN code"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Ina-unlock ang SIM card…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Hindi tamang PIN code."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Mag-type ng PIN na 4 hanggang 8 numero."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Dapat ay 8 numero o higit pa ang PUK code."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Muling ilagay ang tamang PUK code. Permanenteng hindi pagaganahin ang SIM ng mga paulit-ulit na pagtatangka."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Hindi tumutugma ang mga PIN code"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Masyadong maraming pagtatangka sa pattern"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Upang i-unlock, mag-sign in gamit ang iyong Google account."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Username (email)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Password"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Mag-sign in"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Di-wastong username o password."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Nakalimutan ang iyong username o password?\nBisitahin ang "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Tinitingnan ang account…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Na-type mo nang hindi tama ang iyong PIN nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. \n\nSubukang muli sa loob ng <xliff:g id="NUMBER_1">%d</xliff:g> (na) segundo."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Na-type mo nang hindi tama ang iyong password nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. \n\nSubukang muli sa loob ng <xliff:g id="NUMBER_1">%d</xliff:g> (na) segundo."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. \n\nSubukang muli sa loob ng <xliff:g id="NUMBER_1">%d</xliff:g> (na) segundo."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tinangka mo sa hindi tamang paraan na i-unlock ang tabelt nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, ire-reset ang tablet sa factory default at mawawala ang lahat ng data ng user."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Tinangka mo sa hindi tamang paraan na i-unlock ang telepono nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, ire-reset ang telepono sa factory default at mawawala ang lahat ng data ng user."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Tinangka mo sa hindi tamang paraan na i-unlock ang tablet nang <xliff:g id="NUMBER">%d</xliff:g> (na) beses. Ire-reset na ngayon ang tablet sa factory default."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Tinangka mo sa hindi tamang paraan na i-unlock ang telepono nang <xliff:g id="NUMBER">%d</xliff:g> (na) beses. Ire-reset na ngayon ang telepono sa factory default."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, hihilingin sa iyong i-unlock ang tablet mo gamit ang isang email account.\n\n Subukang muli sa loob ng <xliff:g id="NUMBER_2">%d</xliff:g> (na) segundo."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, hihilingin sa iyong i-unlock ang telepono mo gamit ang isang email account.\n\n Subukang muli sa loob ng <xliff:g id="NUMBER_2">%d</xliff:g> (na) segundo."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Alisin"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Button na Nakaraang track"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Button na Susunod na track"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Button na I-pause"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Button na I-play"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Button na Ihinto"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Walang serbisyo."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-tr/activitystrings.xml b/packages/Keyguard/res/values-tr/activitystrings.xml
new file mode 100644
index 0000000..7f5a958
--- /dev/null
+++ b/packages/Keyguard/res/values-tr/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Güvenlik yok"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Şifre"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Desen"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"SIM PIN\'i"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"SIM PUK\'u"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Widget seç..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-tr/strings.xml b/packages/Keyguard/res/values-tr/strings.xml
new file mode 100644
index 0000000..0af7740
--- /dev/null
+++ b/packages/Keyguard/res/values-tr/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN kodunu yazın"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK ve yeni PIN kodunu yazın"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK kodu"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Yeni PIN kodu"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Şifre yazmak için dokunun"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Kilidi açmak için şifreyi yazın"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Kilidi açmak için PIN kodunu yazın"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Yanlış PIN kodu."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Kilidi açmak için önce Menü\'ye, sonra 0\'a basın."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Yüz Tanıma Kilidi için maksimum deneme sayısı aşıldı"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Şarj oldu"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Şarj oluyor, <xliff:g id="PERCENT">%%</xliff:g><xliff:g id="NUMBER">%d</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Şarj cihazınızı takın."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Kilidi açmak için Menü\'ye basın."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Ağ kilitli"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"SIM kart yok"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Tablette SIM kart yok."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Telefonda SIM kart yok."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"SIM kart takın."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM kart yok veya okunamıyor. Bir SIM kart takın."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Kullanılamayan SIM kart"</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"SIM kartınız kalıcı olarak devre dışı bırakıldı.\n Başka bir SIM kart için kablosuz servis sağlayıcınıza başvurun."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM kart kilitli."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM kart PUK kilidi devrede."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SIM kart kilidi açılıyor…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d / %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Widget ekleyin."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Boş"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Kilit açma alanı genişletildi."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Kilit açma alanı daraltıldı."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> widget\'ı."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Kullanıcı seçici"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Durum"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Kamera"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Medya denetimleri"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Widget\'ları yeniden sıralama işlemi başladı."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Widget\'ları yeniden sıralama işlemi bitti."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> widget\'ı silindi."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Kilit açma alanını genişletin."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Kaydırarak kilit açma."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Desenle kilit açma."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Yüzle kilit açma."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Pin koduyla kilit açma."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Şifreyle kilit açma."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Desen alanı."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Kaydırma alanı."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Önceki parça düğmesi"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Sonraki parça düğmesi"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Duraklat düğmesi"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Oynat düğmesi"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Durdur düğmesi"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"İptal"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Sil"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Bitti"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Mod değiştirme"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"ÜstKrkt"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Giriş"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Kilidi aç"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Sessiz"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Ses açık"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Ara"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için yukarı kaydırın."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için aşağı kaydırın."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için sola kaydırın."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için sağa kaydırın."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Geçerli kullanıcı: <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Acil durum çağrısı"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Deseni Unuttunuz mu?"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Yanlış Desen"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Yanlış Şifre"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Yanlış PIN"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%d</xliff:g> saniye içinde yeniden deneyin."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Deseninizi çizin"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM PIN kodunu girin"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN\'i girin"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Şifreyi Girin"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"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>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"İstenen PIN kodunu girin"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"İstenen PIN kodunu onaylayın"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM kart kilidi açılıyor…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Yanlış PIN kodu."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4-8 rakamdan oluşan bir PIN girin."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK kodu 8 veya daha çok basamaklı bir sayı olmalıdır."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Doğru PUK kodunu tekrar girin. Çok sayıda deneme yapılırsa SIM kart kalıcı olarak devre dışı bırakılır."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN kodları eşleşmiyor"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Çok fazla sayıda desen denemesi yapıldı"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Kilidi açmak için Google hesabınızla oturum açın."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Kullanıcı adı (e-posta)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Şifre"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Oturum aç"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Geçersiz kullanıcı adı veya şifre."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Kullanıcı adınızı veya şifrenizi mi unuttunuz?\n"<b>"google.com/accounts/recovery"</b>" adresini ziyaret edin."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Hesap denetleniyor…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN kodunuzu <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış girdiniz. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> saniye içinde tekrar deneyin."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Şifrenizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış yazdınız. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> saniye içinde tekrar deneyin."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış çizdiniz. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> saniye içinde tekrar deneyin."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tablet kilidini <xliff:g id="NUMBER_0">%d</xliff:g> defa yanlış bir şekilde açmaya çalıştınız. <xliff:g id="NUMBER_1">%d</xliff:g> defa daha başarısız deneme yapılırsa, tablet fabrika varsayılan değerine sıfırlanır ve tüm kullanıcı verileri kaybedilir."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Telefonun kilidini <xliff:g id="NUMBER_0">%d</xliff:g> defa yanlış bir şekilde açmaya çalıştınız. <xliff:g id="NUMBER_1">%d</xliff:g> defa daha başarısız deneme yapılırsa, telefon fabrika varsayılan değerine sıfırlanır ve tüm kullanıcı verileri kaybedilir."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Tablet kilidini <xliff:g id="NUMBER">%d</xliff:g> defa yanlış bir şekilde açmaya çalıştınız. Tablet şimdi fabrika varsayılanına sıfırlanacak."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Telefon kilidini <xliff:g id="NUMBER">%d</xliff:g> defa yanlış bir şekilde açmaya çalıştınız. Telefon şimdi fabrika varsayılanına sıfırlanacak."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> başarısız denemeden sonra, tabletinizi bir e-posta hesabı kullanarak açmanız istenir.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> saniye içinde tekrar deneyin."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> başarısız denemeden sonra telefonunuzu bir e-posta hesabı kullanarak açmanız istenir.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> saniye içinde tekrar deneyin."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Kaldır"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Önceki parça düğmesi"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Sonraki parça düğmesi"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Duraklat düğmesi"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Oynat düğmesi"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Durdur düğmesi"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Hizmet yok."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-uk/activitystrings.xml b/packages/Keyguard/res/values-uk/activitystrings.xml
new file mode 100644
index 0000000..d4d0a4d
--- /dev/null
+++ b/packages/Keyguard/res/values-uk/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Без захисту"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN-код"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Пароль"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Ключ"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"PIN-код SIM-карти"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"PUK-код SIM-карти"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Вибрати віджет…"</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-uk/strings.xml b/packages/Keyguard/res/values-uk/strings.xml
new file mode 100644
index 0000000..2879e87
--- /dev/null
+++ b/packages/Keyguard/res/values-uk/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Введіть PIN-код"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Введіть PUK-код і новий PIN-код"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-код"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Новий PIN-код"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><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">"Введіть PIN-код, щоб розблокувати"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Неправильний PIN-код."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Щоб розбл., натисн. меню та 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Перевищено максимальну кількість спроб розблокування за допомогою функції \"Фейсконтроль\""</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Заряджено"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Заряджається, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Підключіть зарядний пристрій."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Натисніть Меню, щоб розблокувати."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Мережу заблоковано"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Відсутня SIM-карта"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"У планшетному ПК немає SIM-карти."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"У телефоні немає SIM-карти."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Вставте SIM-карту."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM-карта відсутня або не доступна для читання. Вставте SIM-карту."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Непридатна SIM-карта."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Вашу SIM-карту вимкнено назавжди.\n Зверніться до свого постачальника послуг бездротового зв’язку, щоб отримати іншу SIM-карту."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM-карту заблоковано."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM-карту заблоковано PUK-кодом."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Розблокування SIM-карти…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Віджет %2$d з %3$d."</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_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>
+    <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_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">"Розблокування PIN-кодом."</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="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Кнопка \"Попередня композиція\""</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Кнопка \"Наступна композиція\""</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Кнопка \"Призупинити\""</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Кнопка \"Відтворити\""</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Кнопка \"Зупинити\""</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</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">"Delete"</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_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Розблокувати"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Без звуку"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Увімкнути звук"</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_down" msgid="5087739728639014595">"Проведіть пальцем униз, щоб <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="description_direction_right" msgid="8034433242579600980">"Проведіть пальцем праворуч, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Поточний користувач: <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Екстрений виклик"</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">"Неправильний PIN-код"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Повторіть спробу через <xliff:g id="NUMBER">%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>
+    <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">"Введіть потрібний PIN-код"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Підтвердьте потрібний PIN-код"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Розблокування SIM-карти…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Неправильний PIN-код."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Введіть PIN-код із 4–8 цифр."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK-код має складатися зі щонайменше 8 цифр."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Повторно введіть правильний PUK-код. Численні спроби назавжди вимкнуть SIM-карту."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-коди не збігаються"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Забагато спроб намалювати ключ"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Щоб розблокувати, увійдіть, використовуючи дані облікового запису Google."</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"Перевірка облікового запису…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN-код неправильно введено стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. \n\nПовторіть спробу через <xliff:g id="NUMBER_1">%d</xliff:g> с."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Пароль неправильно введено стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. \n\nПовторіть спробу через <xliff:g id="NUMBER_1">%d</xliff:g> с."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. \n\nПовторіть спробу через <xliff:g id="NUMBER_1">%d</xliff:g> с."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Кількість невдалих спроб розблокувати планшетний ПК: <xliff:g id="NUMBER_0">%d</xliff:g>. У вас є ще стільки спроб: <xliff:g id="NUMBER_1">%d</xliff:g>. У разі невдачі налаштування планшетного ПК буде змінено на заводські за умовчанням, а всі дані користувача – втрачено."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Кількість невдалих спроб розблокувати телефон: <xliff:g id="NUMBER_0">%d</xliff:g>. У вас є ще стільки спроб: <xliff:g id="NUMBER_1">%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="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">%d</xliff:g>. У вас є ще стільки спроб: <xliff:g id="NUMBER_1">%d</xliff:g>. У разі невдачі з’явиться запит розблокувати планшетний ПК за допомогою облікового запису електронної пошти.\n\n Повторіть спробу через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. У вас є ще стільки спроб: <xliff:g id="NUMBER_1">%d</xliff:g>. У разі невдачі з’явиться запит розблокувати телефон за допомогою облікового запису електронної пошти.\n\n Повторіть спробу через <xliff:g id="NUMBER_2">%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="keyguard_transport_prev_description" msgid="8229108430245669854">"Кнопка \"Попередня композиція\""</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Кнопка \"Наступна композиція\""</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Кнопка \"Призупинити\""</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Кнопка \"Відтворити\""</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Кнопка \"Зупинити\""</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Зв’язку немає."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-vi/activitystrings.xml b/packages/Keyguard/res/values-vi/activitystrings.xml
new file mode 100644
index 0000000..009c3bd
--- /dev/null
+++ b/packages/Keyguard/res/values-vi/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Không có bảo mật"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"Mã PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Mật khẩu"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Hình"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"Mã PIN của SIM"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"Mã PUK của SIM"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Chọn tiện ích..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-vi/strings.xml b/packages/Keyguard/res/values-vi/strings.xml
new file mode 100644
index 0000000..70d3c73
--- /dev/null
+++ b/packages/Keyguard/res/values-vi/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Nhập mã PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Nhập PUK và mã PIN mới"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Mã PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Mã PIN mới"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Chạm để nhập mật khẩu"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Nhập mật khẩu để mở khóa"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Nhập mã PIN để mở khóa"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Mã PIN không chính xác."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Để mở khóa, hãy nhấn vào Trình đơn sau đó nhấn 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Đã vượt quá số lần Mở khóa bằng khuôn mặt tối đa"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Pin đầy"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Đang sạc, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Kết nối bộ sạc của bạn."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Nhấn vào Trình đơn để mở khóa."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Mạng đã bị khóa"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Không có thẻ SIM nào"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Không có thẻ SIM nào trong máy tính bảng."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Không có thẻ SIM nào trong điện thoại."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Vui lòng lắp thẻ SIM."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"Thẻ SIM bị thiếu hoặc không thể đọc được. Vui lòng lắp thẻ SIM."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Thẻ SIM không sử dụng được."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"Thẻ SIM của bạn đã bị vô hiệu hóa vĩnh viễn.\n Hãy liên hệ với nhà cung cấp dịch vụ không dây của bạn để lấy thẻ SIM khác."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"Thẻ SIM đã bị khóa."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"Thẻ SIM đã bị khóa PUK."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Đang mở khóa thẻ SIM…"</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Tiện ích %2$d trong số %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Thêm tiện ích."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Trống"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Đã mở rộng vùng khóa."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Đã thu gọn vùng khóa."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> tiện ích."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Bộ chọn người dùng"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Trạng thái"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Máy ảnh"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Điều khiển phương tiện"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Đã bắt đầu xắp xếp lại tiện ích."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Đã kết thúc sắp xếp lại tiện ích."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Đã xóa tiện ích <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Mở rộng vùng khóa."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Mở khóa bằng cách trượt."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Mở khóa bằng hình."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Mở khóa bằng khuôn mặt."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Mở khóa bằng mã pin."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Mở khóa bằng mật khẩu."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Khu vực hình."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Khu vực trượt."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Nút bản nhạc trước"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Nút bản nhạc tiếp theo"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Nút tạm dừng"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Nút phát"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Nút dừng"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Hủy"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Xóa"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Xong"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Thay đổi chế độ"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Mở khóa"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Máy ảnh"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Im lặng"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Bật âm thanh"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Tìm kiếm"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Trượt lên để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Trượt xuống để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Trượt sang trái để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Trượt sang phải để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Người dùng hiện tại <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Cuộc gọi khẩn cấp"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Đã quên hình"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Hình sai"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Mật khẩu sai"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN sai"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Hãy thử lại sau <xliff:g id="NUMBER">%d</xliff:g> giây."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Vẽ hình của bạn"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Nhập PIN của SIM"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Nhập PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Nhập mật khẩu"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM hiện bị vô hiệu hóa. 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>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Nhập mã PIN mong muốn"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Xác nhận mã PIN mong muốn"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Đang mở khóa thẻ SIM…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Mã PIN không chính xác."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Nhập mã PIN có từ 4 đến 8 số."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Mã PUK phải có từ 8 số trở lên."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Hãy nhập lại mã PUK chính xác. Nhiều lần lặp lại sẽ vô hiệu hóa vĩnh viễn thẻ SIM."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Mã PIN không khớp"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Quá nhiều lần nhập hình"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Để mở khóa, hãy đăng nhập bằng tài khoản Google của bạn."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Tên người dùng (email)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Mật khẩu"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Đăng nhập"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Tên người dùng hoặc mật khẩu không hợp lệ."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Bạn quên tên người dùng hoặc mật khẩu?\nHãy truy cập "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Đang kiểm tra tài khoản…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần nhập sai mã PIN của mình. Hãy \n\nthử lại sau <xliff:g id="NUMBER_1">%d</xliff:g> giây."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần nhập sai mật khẩu của mình. Hãy \n\nthử lại sau <xliff:g id="NUMBER_1">%d</xliff:g> giây."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần vẽ không chính xác hình mở khóa của mình. Hãy \n\nthử lại sau <xliff:g id="NUMBER_1">%d</xliff:g> giây."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần mở khóa máy tính bảng không đúng cách. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần mở khóa không thành công nữa, máy tính bảng sẽ được đặt lại về mặc định ban đầu và tất cả dữ liệu người dùng sẽ bị mất."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần mở khóa điện thoại không đúng cách. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần mở khóa không thành công nữa, điện thoại sẽ được đặt lại về mặc định ban đầu và tất cả dữ liệu người dùng sẽ bị mất."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Bạn đã <xliff:g id="NUMBER">%d</xliff:g> lần mở khóa máy tính bảng không đúng cách. Bây giờ, máy tính bảng sẽ được đặt lại về mặc định ban đầu."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Bạn đã <xliff:g id="NUMBER">%d</xliff:g> lần mở khóa điện thoại không đúng cách. Bây giờ, điện thoại sẽ được đặt lại về mặc định ban đầu."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần vẽ không chính xác hình mở khóa của mình. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa máy tính bảng bằng tài khoản email.\n\n Vui lòng thử lại sau <xliff:g id="NUMBER_2">%d</xliff:g> giây."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần vẽ không chính xác hình mở khóa của mình. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa điện thoại bằng tài khoản email.\n\n Vui lòng thử lại sau <xliff:g id="NUMBER_2">%d</xliff:g> giây."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Xóa"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Nút bản nhạc trước"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Nút bản nhạc tiếp theo"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Nút tạm dừng"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Nút phát"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Nút dừng"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Không có dịch vụ."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-xlarge/dimens.xml b/packages/Keyguard/res/values-xlarge/dimens.xml
new file mode 100644
index 0000000..b8cf287
--- /dev/null
+++ b/packages/Keyguard/res/values-xlarge/dimens.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/dimens.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+    <!-- Default height of a key in the password keyboard for alpha -->
+    <dimen name="password_keyboard_key_height_alpha">75dip</dimen>
+    <!-- Default height of a key in the password keyboard for numeric -->
+    <dimen name="password_keyboard_key_height_numeric">75dip</dimen>
+    <!-- keyboardHeight = key_height*4 + key_bottom_gap*3 -->
+    <dimen name="password_keyboard_height">48.0mm</dimen>
+</resources>
diff --git a/packages/Keyguard/res/values-zh-rCN/activitystrings.xml b/packages/Keyguard/res/values-zh-rCN/activitystrings.xml
new file mode 100644
index 0000000..d9b99e0
--- /dev/null
+++ b/packages/Keyguard/res/values-zh-rCN/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"无安全措施"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"密码"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"图案"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"SIM 卡 PIN"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"SIM 卡 PUK"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"选择小部件..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-zh-rCN/strings.xml b/packages/Keyguard/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..cdb1944e
--- /dev/null
+++ b/packages/Keyguard/res/values-zh-rCN/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"输入 PIN 码"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"请输入 PUK 码和新的 PIN 码"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK 码"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"新的 PIN 码"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><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">"输入 PIN 进行解锁"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PIN 码有误。"</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"要解锁,请先按 MENU 再按 0。"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"已超过“人脸解锁”尝试次数上限"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"充电完成"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"正在充电 (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"请连接充电器。"</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"按“菜单”键解锁。"</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"网络已锁定"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"无 SIM 卡"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"平板电脑中没有 SIM 卡。"</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"手机中没有 SIM 卡。"</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"请插入 SIM 卡。"</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SIM 卡缺失或无法读取,请插入 SIM 卡。"</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"SIM 卡无法使用。"</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"您的 SIM 卡已永久停用。\n请与您的无线服务提供商联系,以便重新获取一张 SIM 卡。"</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM 卡已被锁定。"</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM 卡已被 PUK 锁定。"</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"正在解锁 SIM 卡..."</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_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_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>
+    <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_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">"PIN 解锁。"</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="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"上一曲按钮"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"下一曲按钮"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"暂停按钮"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"播放按钮"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"停止按钮"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</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">"Delete"</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_enter" msgid="2985864015076059467">"Enter"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"解锁"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"相机"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"静音"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"打开声音"</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_down" msgid="5087739728639014595">"向下滑动以<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="description_direction_right" msgid="8034433242579600980">"向右滑动以<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
+    <string name="user_switched" msgid="3768006783166984410">"当前用户是<xliff:g id="NAME">%1$s</xliff:g>。"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"紧急呼救"</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">"PIN 有误"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"请在 <xliff:g id="NUMBER">%d</xliff:g> 秒后重试。"</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"绘制您的图案"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"输入 SIM PIN"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"输入 PIN"</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">"请输入所需 PIN 码"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"请确认所需 PIN 码"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"正在解锁 SIM 卡..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"PIN 码有误。"</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"请输入 4 至 8 位数的 PIN。"</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK 码应至少包含 8 位数字。"</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"请重新输入正确的 PUK 码。如果尝试错误次数过多,SIM 卡将永久停用。"</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN 码不匹配"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"图案尝试次数过多"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"要解锁,请登录您的 Google 帐户。"</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"正在检查帐户…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地输入了 PIN。\n\n请在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒后重试。"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地输入了密码。\n\n请在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒后重试。"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地绘制了解锁图案。\n\n请在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒后重试。"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地尝试解锁平板电脑。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,平板电脑就会重置为出厂默认设置,而且所有用户数据都会丢失。"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地尝试解锁手机。如果再尝试 <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> 次错误地绘制了解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐户解锁平板电脑。\n\n请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地绘制了解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐户解锁手机。\n\n请在 <xliff:g id="NUMBER_2">%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="keyguard_transport_prev_description" msgid="8229108430245669854">"“上一曲”按钮"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"“下一曲”按钮"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"“暂停”按钮"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"“播放”按钮"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"“停止”按钮"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"无服务。"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-zh-rHK/strings.xml b/packages/Keyguard/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..49953c0
--- /dev/null
+++ b/packages/Keyguard/res/values-zh-rHK/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"輸入 PIN 碼"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"輸入 PUK 碼和新 PIN 碼"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK 碼"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"新 PIN 碼"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><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">"輸入 PIN 碼即可解鎖"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PIN 碼不正確。"</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"如要解鎖,請按選單鍵,然後按 0。"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"已超過臉容解鎖嘗試次數上限"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"充電完成"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"充電中 (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"請連接充電器。"</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"按選單鍵解鎖。"</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"網絡已鎖定"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"找不到 SIM 卡"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"平板電腦中沒有 SIM 卡。"</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"手機中沒有 SIM 卡。"</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"請插入 SIM 卡。"</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"找不到 SIM 卡或無法讀取 SIM 卡,請插入 SIM 卡。"</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"SIM 卡無法使用。"</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"您的 SIM 卡已被永久停用。\n請與您的無線服務供應商聯絡,以取得另一張 SIM 卡。"</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM 卡處於鎖定狀態。"</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM 卡處於 PUK 鎖定狀態。"</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"正在解開上鎖的 SIM 卡..."</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s。第 %2$d 個小工具,共 %3$d 個。"</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_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>
+    <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_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">"PIN 解鎖。"</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="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"[上一首曲目] 按鈕"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"[下一首曲目] 按鈕"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"[暫停] 按鈕"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"[播放] 按鈕"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"[停止] 按鈕"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</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_enter" msgid="2985864015076059467">"Enter 鍵"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"解鎖"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"相機"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"靜音"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"音效已開啟"</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_down" msgid="5087739728639014595">"向下滑動即可<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="description_direction_right" msgid="8034433242579600980">"向右滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
+    <string name="user_switched" msgid="3768006783166984410">"目前的用戶是<xliff:g id="NAME">%1$s</xliff:g>。"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"緊急電話"</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">"PIN 錯誤"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"請在 <xliff:g id="NUMBER">%d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"畫出圖案"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"輸入 SIM 卡 PIN 碼"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"輸入 PIN 碼"</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">"輸入所需的 PIN 碼"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"確認所需的 PIN 碼"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"正在解開上鎖的 SIM 卡..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"PIN 碼不正確。"</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"請輸入一個 4 至 8 位數的 PIN 碼。"</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK 碼應由 8 個或以上數字組成。"</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"請重新輸入正確的 PUK 碼。如果嘗試輸入的次數過多,SIM 卡將永久停用。"</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN 碼不符"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"圖案嘗試次數過多"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"如要解鎖,請以 Google 帳戶登入。"</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"正在檢查帳戶…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"您已輸入錯誤的 PIN 碼 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"您已輸入錯誤的密碼 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"您嘗試了 <xliff:g id="NUMBER_0">%d</xliff:g> 次仍未能成功解開這部上鎖的平板電腦。如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,平板電腦將回復原廠設定,所有用戶資料均會失去。"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"您嘗試了 <xliff:g id="NUMBER_0">%d</xliff:g> 次仍未能成功解開這部上鎖的手機。如果再嘗試 <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解開上鎖的平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解開上鎖的手機。\n\n請在 <xliff:g id="NUMBER_2">%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="keyguard_transport_prev_description" msgid="8229108430245669854">"[上一首曲目] 按鈕"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"[下一首曲目] 按鈕"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"[暫停] 按鈕"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"[播放] 按鈕"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"[停止] 按鈕"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"沒有服務。"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-zh-rTW/activitystrings.xml b/packages/Keyguard/res/values-zh-rTW/activitystrings.xml
new file mode 100644
index 0000000..42c2a51
--- /dev/null
+++ b/packages/Keyguard/res/values-zh-rTW/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"Keyguard 測試活動"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"整合式相機"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"無安全性設定"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"密碼"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"圖形"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"SIM PIN"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"SIM PUK"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"選擇小工具..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"在螢幕上關閉"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"在螢幕上開啟"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"執行 Keyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"驗證解鎖"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-zh-rTW/strings.xml b/packages/Keyguard/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..72a1c0f
--- /dev/null
+++ b/packages/Keyguard/res/values-zh-rTW/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"輸入 PIN 碼"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"輸入 PUK 碼和新 PIN 碼"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK 碼"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"新 PIN 碼"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><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">"輸入 PIN 即可解鎖"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PIN 碼不正確。"</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"如要解鎖,請按 Menu 鍵,然後按 0。"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"已超過人臉解鎖嘗試次數上限"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"充電完成"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"充電中 (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"連接充電器。"</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"按選單鍵解鎖。"</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"網路已鎖定"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"找不到 SIM 卡"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"平板電腦中沒有 SIM 卡。"</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"手機中沒有 SIM 卡。"</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"插入 SIM 卡。"</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"找不到或無法讀取 SIM 卡。請插入 SIM 卡。"</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"SIM 卡無法使用。"</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"您的 SIM 卡已遭永久停用。\n請與您的無線網路服務供應商聯絡,以取得別張 SIM 卡。"</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM 卡處於鎖定狀態。"</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM 卡處於 PUK 鎖定狀態"</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"正在解除 SIM 卡鎖定..."</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s。第 %2$d 個小工具,共 %3$d 個。"</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_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>
+    <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_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">"PIN 解鎖。"</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="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"[上一首曲目] 按鈕"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"[下一首曲目] 按鈕"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"[暫停] 按鈕"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"[播放] 按鈕"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"[停止] 按鈕"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</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">"Delete 鍵"</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_enter" msgid="2985864015076059467">"Enter 鍵"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"解除鎖定"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"相機"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"靜音"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"開啟音效"</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_down" msgid="5087739728639014595">"向下滑動即可<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="description_direction_right" msgid="8034433242579600980">"向右滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
+    <string name="user_switched" msgid="3768006783166984410">"目前的使用者是 <xliff:g id="NAME">%1$s</xliff:g>。"</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"緊急電話"</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">"PIN 錯誤"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"請在 <xliff:g id="NUMBER">%d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"畫出圖形"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"輸入 SIM PIN"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"輸入 PIN"</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">"輸入所需的 PIN 碼"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"確認所需的 PIN 碼"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"正在解除 SIM 卡鎖定..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"PIN 碼不正確。"</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"請輸入 4 到 8 碼的 PIN。"</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK 碼至少必須為 8 碼。"</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"重新輸入正確的 PUK 碼。如果錯誤次數過多,SIM 卡將會永久停用。"</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN 碼不符"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"圖形嘗試次數過多"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"如要解除鎖定,請使用 Google 帳戶登入。"</string>
+    <string name="kg_login_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_checking_password" msgid="1052685197710252395">"正在檢查帳戶…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"您的 PIN 已輸錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"您的密碼已輸錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次。\n\n請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"您嘗試解除這個平板電腦的鎖定已失敗 <xliff:g id="NUMBER_0">%d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%d</xliff:g> 次機會。如果失敗次數超過限制,平板電腦將恢復原廠設定,所有使用者資料都會遺失。"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"您嘗試解除這支手機的鎖定已失敗 <xliff:g id="NUMBER_0">%d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%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="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">%d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統就會要求您透過電子郵件帳戶解除平板電腦的鎖定狀態。\n\n請在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統就會要求您透過電子郵件帳戶解除手機的鎖定狀態。\n\n請在 <xliff:g id="NUMBER_2">%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="keyguard_transport_prev_description" msgid="8229108430245669854">"[上一首曲目] 按鈕"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"[下一首曲目] 按鈕"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"[暫停] 按鈕"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"[播放] 按鈕"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"[停止] 按鈕"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"沒有服務。"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-zu/activitystrings.xml b/packages/Keyguard/res/values-zu/activitystrings.xml
new file mode 100644
index 0000000..0031a8b
--- /dev/null
+++ b/packages/Keyguard/res/values-zu/activitystrings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="3352888186674981593">"I-KeyguardTestActivity"</string>
+    <string name="secure_app_name" msgid="7955498742816868049">"I-UnifiedCamera"</string>
+    <string name="none_menu_item" msgid="6156747285687551424">"Akukho ukuphepha"</string>
+    <string name="pin_menu_item" msgid="1179756433268962311">"I-PIN"</string>
+    <string name="password_menu_item" msgid="1959980499662153160">"Iphasiwedi"</string>
+    <string name="pattern_menu_item" msgid="2987798152175140249">"Iphethini"</string>
+    <string name="sim_pin_menu_item" msgid="3962286639645084880">"I-PIN ye-SIM"</string>
+    <string name="sim_puk_menu_item" msgid="6190044133008392974">"I-PUK YE-SIM"</string>
+    <string name="add_widget_item" msgid="279702152366857415">"Khetha iwijethi..."</string>
+    <string name="on_screen_turned_off" msgid="8761396329770508367">"I-onScreenTurnedOff"</string>
+    <string name="on_screen_turned_on" msgid="9222926818030728999">"I-onScreenTurnedOn"</string>
+    <string name="do_keyguard" msgid="9210936977823118796">"I-doKeyguard"</string>
+    <string name="verify_unlock" msgid="8508722273329306968">"I-verifyUnlock"</string>
+</resources>
diff --git a/packages/Keyguard/res/values-zu/strings.xml b/packages/Keyguard/res/values-zu/strings.xml
new file mode 100644
index 0000000..185ea03
--- /dev/null
+++ b/packages/Keyguard/res/values-zu/strings.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Faka ikhodi ye-PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Faka i-PUK nephinikhodi entsha"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Ikhodi le-PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Iphinikhodi entsha"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Thinta ukubhala iphasiwedi"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Bhala iphasiwedi ukuze kuvuleke"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Faka i-PIN ukuvula"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Ikhodi ye-PIN engalungile!"</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Ukuvula, chofoza Menyu bese 0."</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Ukuzama Kokuvula Ubuso Okuningi kudluliwe"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Kushajiwe"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Iyashaja, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Xhuma ishaja yakho."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Chofoza imenyu ukuze uvule."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Inethiwekhi ikhiyiwe"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"Alikho ikhadi le-SIM"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Alikho ikhadi le-SIM kuthebulethi."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Alikho ikhadi le-SIM kufoni."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"Faka ikhadi le-SIM."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"Ikhadi le-SIM alitholakali noma alifundeki. Faka ikhadi le-SIM."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Ikhadi le-SIM elingasebenziseki."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"I-SIM khadi yakho ikhutshazwe unomphela.\n Xhumana nomhlinzeki wakho wokuxhumana okungenazintambo ukuze uthole enye i-SIM khadi."</string>
+    <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"Ikhadi le-SIM likhiyiwe."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"Ikhadi le-SIM likhiywe nge-PUK."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Ivula ikhadi le-SIM..."</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. iwijethi %2$d ye-%3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Engeza iwijethi."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Akunalutho"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Indawo yokuvula inwetshisiwe."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Indawo yokuvula inciphisiwe."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> iwijethi."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Isikhethi somsebenzisi"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Isimo"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Ikhamera"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Izilawuli zemidiya"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Ukuhlelwa kabusha kwewijethi kuqalile"</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Ukuhlelwa kabusha kwewijethi kuphelile."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Iwijethi <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> isusiwe."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Nwebisa indawo yokuvula."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Ukuvula ngokuslayida."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Ukuvula ngephethini."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Vula ngobuso"</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Ukuvula ngephinikhodi."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Ukuvula ngephasiwedi."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Indawo yephethini."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Indawo yokushelelisa."</string>
+    <string name="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Inkinombo yethrekhi yangaphambilini"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Inkinobho yethrekhi elandelayo"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Inkinobho yokumiswa isikhashana"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Inkinobho yokudlala"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Inkinobho yokumisa"</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"i-ALT"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Khansela"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Susa"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Kwenziwe"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Ukushintsha kwendlela esetshenziswayo"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Beka kwenye indawo"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Faka"</string>
+    <string name="description_target_unlock" msgid="2228524900439801453">"Vula"</string>
+    <string name="description_target_camera" msgid="969071997552486814">"Ikhamera"</string>
+    <string name="description_target_silent" msgid="893551287746522182">"Thulile"</string>
+    <string name="description_target_soundon" msgid="30052466675500172">"Umsindo uvuliwe"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Sesha"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Shelelisela ngenhla ku-<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_down" msgid="5087739728639014595">"Shelelisela ngezansi ku-<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Shelelisela ngakwesokunxele ku-<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_right" msgid="8034433242579600980">"Shelelisela ngakwesokudla ku-<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Umsebenzisi wamanje <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="kg_emergency_call_label" msgid="684946192523830531">"Ucingo lwezimo eziphuthumayo"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Ukhohlwe iphethini?"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Iphatheni engalungile"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Iphasiwedi engalungile"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Iphinikhodi engalungile"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Zama futhi emasekhondini angu-<xliff:g id="NUMBER">%d</xliff:g>."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Dweba iphethini"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Faka iphinikhodi ye-SIM"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Faka iphinikhodi"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Faka iphasiwedi"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"I-SIM manje ikhutshaziwe. Faka ikhodi ye-PUK ukuze uqhubeke. Xhumana nenkampani yenethiwekhi ngemininingwane."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Faka iphinikhodi oyithandayo"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Qiniseka iphinikhodi oyithandayo"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Ivula ikhadi le-SIM..."</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Iphinikhodi engalungile."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Thayipha iphinikhodi enezinombolo ezingu-4 kuya kwezingu-8."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Ikhodi ye-PUK kufanele ibe yizinombolo ezingu-8 noma eziningi."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Faka kabusha ikhodi ye-PUK elungile. Imizamo ephindiwe izokhubaza unaphakade i-SIM."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Iphinikhodi ayifani"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Kunemizamo eminingi kakhulu yephathini"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Ukuvula, ngena ngemvume kwi-akhawunti ye-Google"</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Igama lomsebenzisi (i-imeyli)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Iphasiwedi"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Ngena ngemvume"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Igama lomsebezisi elingalungile noma iphasiwedi."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Ukhohlwe igama lomsebenzisi noma iphasiwedi?\nVakashela"<b>"google.com/accounts/recovery"</b></string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Ukuhlola i-akhawunti…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Ubhale iphinikhodi ykho ngendlela engafanele izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. \n\nZama futhi emasekhondini angu-<xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Ubhale iphasiwedi yakho ngendlela engafanele <xliff:g id="NUMBER_0">%d</xliff:g> izikhathi. \n\nZama futhi emasekhondini angu-<xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Udwebe iphathini yakho yokuvula ngendlela engafanele-<xliff:g id="NUMBER_0">%d</xliff:g>. \n\n Zama futhi emasekhondini angu-<xliff:g id="NUMBER_1">%d</xliff:g>"</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Uzame ngokusebenzisa indlela engafanele ukuvula ithebhulethi izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. Ngemuva kokuzama ngaphandle kwempumelelo okungu-<xliff:g id="NUMBER_1">%d</xliff:g>, ithebhulethi izobuyiselwa kwizimiso zasembonini futhi yonke imininingwane yomsebenzisi izolahleka."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Uzame ngokusebenzisa indlela engafanele ukuvula ifoni izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. Ngemuva kokuzama ngaphandle kwempumelelo okungu-<xliff:g id="NUMBER_1">%d</xliff:g>, ifoni izobuyiselwa kwizimiso zasembonini futhi yonke imininingwane yomsebenzisi izolahleka."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Uzame ukuvula ngendlela engafanele ifoni izikhathi ezingu-<xliff:g id="NUMBER">%d</xliff:g>. Ithebhulethi manje isizosethwa kabusha ibe yizimiso ezizenzakalelayo."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Uzame ukuvula ngendlela engafanele ifoni izikhathi ezingu-<xliff:g id="NUMBER">%d</xliff:g>. Ifoni manje isizosethwa kabusha ibe yizimiso ezizenzakalelayo."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Udwebe ngokungalungile iphathini yakho yokuvula izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. Emva <xliff:g id="NUMBER_1">%d</xliff:g> kweminye imizamo engaphumelelanga, uzocelwa ukuvula ithebhulethi yakho usebenzisa ukungena ngemvume kwi-Google.\n\n Sicela uzame futhi emuva kwamasekhondi angu-<xliff:g id="NUMBER_2">%d</xliff:g>"</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Ukulayisha ungenisa iphathini yakho yokuvula ngendlela engalungile izikhathi ezi-<xliff:g id="NUMBER_0">%d</xliff:g> Emva kweminye imizamo engu-<xliff:g id="NUMBER_1">%d</xliff:g>, uzocelwa ukuvula ifoni yakho usebenzisa ukungena ngemvume ku-Google\n\n Zame futhi emumva kwengu- <xliff:g id="NUMBER_2">%d</xliff:g> amasekhondi."</string>
+    <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Susa"</string>
+    <string name="keyguard_transport_prev_description" msgid="8229108430245669854">"Inkinombo yethrekhi yangaphambilini"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Inkinobho yethrekhi elandelayo"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Inkinobho yokumiswa isikhashana"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Inkinobho yokudlala"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Inkinobho yokumisa"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Ayikho isevisi."</string>
+</resources>
diff --git a/packages/Keyguard/res/values/alias.xml b/packages/Keyguard/res/values/alias.xml
new file mode 100644
index 0000000..47291b2
--- /dev/null
+++ b/packages/Keyguard/res/values/alias.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/colors.xml
+**
+** Copyright 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.
+*/
+-->
+<resources>
+
+    <!-- Alias used to reference framework color for transparency. -->
+    <item type="color" name="transparent">@android:color/transparent</item>
+
+    <!-- Alias used to reference framework drawable in keyguard. -->
+    <item type="drawable" name="stat_sys_warning">@android:drawable/stat_sys_warning</item>
+
+    <!-- Alias used to reference framework drawable in keyguard. -->
+    <item type="drawable" name="ic_media_pause">@android:drawable/ic_media_pause</item>
+
+    <!-- Alias used to reference framework drawable in keyguard. -->
+    <item type="drawable" name="ic_media_stop">@*android:drawable/ic_media_stop</item>
+
+    <!-- Alias used to reference framework drawable in keyguard. -->
+    <item type="drawable" name="ic_contact_picture">@*android:drawable/ic_contact_picture</item>
+
+    <!-- Alias used to reference framework drawable in keyguard. -->
+    <item type="drawable" name="ic_lock_idle_alarm">@*android:drawable/ic_lock_idle_alarm</item>
+
+    <!-- Alias used to reference framework "OK" string in keyguard.  -->
+    <item type="string" name="ok">@*android:string/ok</item>
+
+    <!-- Alias used to reference framework "OK" string in keyguard.  -->
+    <item type="string" name="system_ui_date_pattern">@*android:string/system_ui_date_pattern</item>
+
+    <!-- Alias used to reference framework configuration for screen rotation.  -->
+    <item type="bool" name="config_enableLockScreenRotation">@*android:bool/config_enableLockScreenRotation</item>
+
+    <!-- Alias used to reference framework activity duration.  -->
+    <item type="integer" name="config_activityDefaultDur">@*android:integer/config_activityDefaultDur</item>
+
+</resources>
\ No newline at end of file
diff --git a/packages/Keyguard/res/values/arrays.xml b/packages/Keyguard/res/values/arrays.xml
new file mode 100644
index 0000000..550f80c
--- /dev/null
+++ b/packages/Keyguard/res/values/arrays.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/colors.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR 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">
+
+    <!-- Resources for GlowPadView in LockScreen -->
+    <array name="lockscreen_targets_when_silent">
+        <item>@drawable/ic_lockscreen_unlock</item>
+        <item>@drawable/ic_action_assist_generic</item>
+        <item>@drawable/ic_lockscreen_soundon</item>
+        <item>@null</item>
+    </array>
+
+    <array name="lockscreen_target_descriptions_when_silent">
+        <item>@string/description_target_unlock</item>
+        <item>@string/description_target_search</item>
+        <item>@string/description_target_soundon</item>
+        <item>@null</item>
+    </array>
+
+    <array name="lockscreen_direction_descriptions">
+        <item>@string/description_direction_right</item>
+        <item>@string/description_direction_up</item>
+        <item>@string/description_direction_left</item>
+        <item>@null</item>
+    </array>
+
+    <array name="lockscreen_targets_when_soundon">
+        <item>@drawable/ic_lockscreen_unlock</item>
+        <item>@drawable/ic_action_assist_generic</item>
+        <item>@drawable/ic_lockscreen_silent</item>
+        <item>@null</item>
+    </array>
+
+    <array name="lockscreen_target_descriptions_when_soundon">
+        <item>@string/description_target_unlock</item>
+        <item>@string/description_target_search</item>
+        <item>@string/description_target_silent</item>
+        <item>@null</item>
+    </array>
+
+    <array name="lockscreen_targets_with_camera">
+        <item>@drawable/ic_lockscreen_unlock</item>
+        <item>@drawable/ic_action_assist_generic</item>
+        <item>@drawable/ic_lockscreen_camera</item>
+        <item>@null</item>
+    </array>
+
+    <array name="lockscreen_target_descriptions_with_camera">
+        <item>@string/description_target_unlock</item>
+        <item>@string/description_target_search</item>
+        <item>@string/description_target_camera</item>
+        <item>@null</item>
+    </array>
+
+    <array name="lockscreen_targets_unlock_only">
+        <item>@drawable/ic_lockscreen_unlock</item>
+    </array>
+
+    <array name="lockscreen_target_descriptions_unlock_only">
+        <item>@string/description_target_unlock</item>
+    </array>
+
+    <!-- list of 3- or 4-letter mnemonics for a 10-key numeric keypad -->
+    <string-array translatable="false" name="lockscreen_num_pad_klondike">
+        <item></item><!-- 0 -->
+        <item></item><!-- 1 -->
+        <item>ABC</item><!-- 2 -->
+        <item>DEF</item><!-- 3 -->
+        <item>GHI</item><!-- 4 -->
+        <item>JKL</item><!-- 5 -->
+        <item>MNO</item><!-- 6 -->
+        <item>PQRS</item><!-- 7 -->
+        <item>TUV</item><!-- 8 -->
+        <item>WXYZ</item><!-- 9 -->
+    </string-array>
+</resources>
diff --git a/packages/Keyguard/res/values/attrs.xml b/packages/Keyguard/res/values/attrs.xml
new file mode 100644
index 0000000..e045dd2
--- /dev/null
+++ b/packages/Keyguard/res/values/attrs.xml
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<!-- Formatting note: terminate all comments with a period, to avoid breaking
+     the documentation output. To suppress comment lines from the documentation
+     output, insert an eat-comment element after the comment lines.
+-->
+
+<resources>
+    <!-- Standard gravity constant that a child supplies to its parent.
+         Defines how the child view should be positioned, on both the X and Y axes, within its enclosing layout. -->
+    <attr name="layout_gravity">
+        <!-- Push object to the top of its container, not changing its size. -->
+        <flag name="top" value="0x30" />
+        <!-- Push object to the bottom of its container, not changing its size. -->
+        <flag name="bottom" value="0x50" />
+        <!-- Push object to the left of its container, not changing its size. -->
+        <flag name="left" value="0x03" />
+        <!-- Push object to the right of its container, not changing its size. -->
+        <flag name="right" value="0x05" />
+        <!-- Place object in the vertical center of its container, not changing its size. -->
+        <flag name="center_vertical" value="0x10" />
+        <!-- Grow the vertical size of the object if needed so it completely fills its container. -->
+        <flag name="fill_vertical" value="0x70" />
+        <!-- Place object in the horizontal center of its container, not changing its size. -->
+        <flag name="center_horizontal" value="0x01" />
+        <!-- Grow the horizontal size of the object if needed so it completely fills its container. -->
+        <flag name="fill_horizontal" value="0x07" />
+        <!-- Place the object in the center of its container in both the vertical and horizontal axis, not changing its size. -->
+        <flag name="center" value="0x11" />
+        <!-- Grow the horizontal and vertical size of the object if needed so it completely fills its container. -->
+        <flag name="fill" value="0x77" />
+        <!-- Additional option that can be set to have the top and/or bottom edges of
+             the child clipped to its container's bounds.
+             The clip will be based on the vertical gravity: a top gravity will clip the bottom
+             edge, a bottom gravity will clip the top edge, and neither will clip both edges. -->
+        <flag name="clip_vertical" value="0x80" />
+        <!-- Additional option that can be set to have the left and/or right edges of
+             the child clipped to its container's bounds.
+             The clip will be based on the horizontal gravity: a left gravity will clip the right
+             edge, a right gravity will clip the left edge, and neither will clip both edges. -->
+        <flag name="clip_horizontal" value="0x08" />
+        <!-- Push object to the beginning of its container, not changing its size. -->
+        <flag name="start" value="0x00800003" />
+        <!-- Push object to the end of its container, not changing its size. -->
+        <flag name="end" value="0x00800005" />
+    </attr>
+
+
+    <!-- PagedView specific attributes. These attributes are used to customize
+         a PagedView view in XML files. -->
+    <declare-styleable name="PagedView">
+        <!-- The space between adjacent pages of the PagedView. -->
+        <attr name="pageSpacing" format="dimension" />
+        <!-- The padding for the scroll indicator area -->
+        <attr name="scrollIndicatorPaddingLeft" format="dimension" />
+        <attr name="scrollIndicatorPaddingRight" format="dimension" />
+    </declare-styleable>
+
+    <declare-styleable name="KeyguardGlowStripView">
+        <attr name="dotSize" format="dimension" />
+        <attr name="numDots" format="integer" />
+        <attr name="glowDot" format="reference" />
+        <attr name="leftToRight" format="boolean" />
+    </declare-styleable>
+
+    <!-- Some child types have special behavior. -->
+    <attr name="layout_childType">
+        <!-- No special behavior. Layout will proceed as normal. -->
+        <enum name="none" value="0" />
+        <!-- Widget container.
+             This will be resized in response to certain events. -->
+        <enum name="widget" value="1" />
+        <!-- Security challenge container.
+             This will be dismissed/shown in response to certain events,
+             possibly obscuring widget elements. -->
+        <enum name="challenge" value="2" />
+        <!-- User switcher.
+             This will consume space from the total layout area. -->
+        <enum name="userSwitcher" value="3" />
+        <!-- Scrim. This will block access to child views that
+             come before it in the child list in bouncer mode. -->
+        <enum name="scrim" value="4" />
+        <!-- The home for widgets. All widgets will be descendents of this. -->
+        <enum name="widgets" value="5" />
+        <!-- This is a handle that is used for expanding the
+             security challenge container when it is collapsed. -->
+        <enum name="expandChallengeHandle" value="6" />
+        <!-- Delete drop target.  This will be the drop target to delete pages. -->
+        <enum name="pageDeleteDropTarget" value="7" />
+    </attr>
+
+    <declare-styleable name="SlidingChallengeLayout_Layout">
+        <attr name="layout_childType" />
+        <attr name="layout_maxHeight" format="dimension" />
+    </declare-styleable>
+
+    <declare-styleable name="MultiPaneChallengeLayout">
+        <!-- Influences how layout_centerWithinArea behaves -->
+        <attr name="android:orientation" />
+    </declare-styleable>
+
+    <declare-styleable name="MultiPaneChallengeLayout_Layout">
+        <!-- Percentage of the screen this child should consume or center within.
+             If 0/default, the view will be measured by standard rules
+             as if this were a FrameLayout. -->
+        <attr name="layout_centerWithinArea" format="float" />
+        <attr name="layout_childType" />
+        <attr name="layout_gravity" />
+        <attr name="layout_maxWidth" format="dimension" />
+        <attr name="layout_maxHeight" />
+    </declare-styleable>
+
+    <declare-styleable name="KeyguardSecurityViewFlipper_Layout">
+        <attr name="layout_maxWidth" />
+        <attr name="layout_maxHeight" />
+    </declare-styleable>
+
+    <declare-styleable name="NumPadKey">
+        <attr name="digit" format="integer" />
+        <attr name="textView" format="reference" />
+    </declare-styleable>
+</resources>
diff --git a/packages/Keyguard/res/values/bools.xml b/packages/Keyguard/res/values/bools.xml
new file mode 100644
index 0000000..a9f69e5
--- /dev/null
+++ b/packages/Keyguard/res/values/bools.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources>
+    <bool name="kg_enable_camera_default_widget">true</bool>
+    <bool name="kg_center_small_widgets_vertically">false</bool>
+    <bool name="kg_top_align_page_shrink_on_bouncer_visible">true</bool>
+    <bool name="kg_show_ime_at_screen_on">true</bool>
+</resources>
diff --git a/packages/Keyguard/res/values/colors.xml b/packages/Keyguard/res/values/colors.xml
new file mode 100644
index 0000000..0c56a43
--- /dev/null
+++ b/packages/Keyguard/res/values/colors.xml
@@ -0,0 +1,26 @@
+<?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>
+    <!-- Keyguard colors -->
+    <color name="keyguard_avatar_frame_color">#ffffffff</color>
+    <color name="keyguard_avatar_frame_shadow_color">#80000000</color>
+    <color name="keyguard_avatar_nick_color">#ffffffff</color>
+    <color name="keyguard_avatar_frame_pressed_color">#ff35b5e5</color>
+    <color name="kg_widget_pager_gradient">#ffffffff</color>
+
+    <!-- FaceLock -->
+    <color name="facelock_spotlight_mask">#CC000000</color>
+</resources>
diff --git a/packages/Keyguard/res/values/config.xml b/packages/Keyguard/res/values/config.xml
new file mode 100644
index 0000000..de17c4b
--- /dev/null
+++ b/packages/Keyguard/res/values/config.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2009, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Package name for default keyguard appwidget [DO NOT TRANSLATE] -->
+    <string name="widget_default_package_name"></string>
+
+    <!-- Class name for default keyguard appwidget [DO NOT TRANSLATE] -->
+    <string name="widget_default_class_name"></string>
+
+    <!-- Allow the menu hard key to be disabled in LockScreen on some devices [DO NOT TRANSLATE] -->
+    <bool name="config_disableMenuKeyInLockScreen">false</bool>
+
+</resources>
diff --git a/packages/Keyguard/res/values/dimens.xml b/packages/Keyguard/res/values/dimens.xml
new file mode 100644
index 0000000..fde63c4
--- /dev/null
+++ b/packages/Keyguard/res/values/dimens.xml
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/dimens.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+    <!-- Default height of a key in the password keyboard for alpha (used by keyguard) -->
+    <dimen name="password_keyboard_key_height_alpha">56dip</dimen>
+    <!-- Default height of a key in the password keyboard for numeric (used by keyguard) -->
+    <dimen name="password_keyboard_key_height_numeric">56dip</dimen>
+    <!-- Default correction for the space key in the password keyboard  (used by keyguard) -->
+    <dimen name="password_keyboard_spacebar_vertical_correction">4dip</dimen>
+    <!-- Default horizontal gap between keys in the password keyboard (used by keyguard) -->
+    <dimen name="password_keyboard_horizontalGap">3dip</dimen>
+    <!-- Default vertical gap between keys in the password keyboard (used by keyguard) -->
+    <dimen name="password_keyboard_verticalGap">9dip</dimen>
+
+    <!-- Size of lockscreen outerring on unsecure unlock LockScreen -->
+    <dimen name="keyguard_lockscreen_outerring_diameter">270dp</dimen>
+
+    <!-- Default target placement radius for GlowPadView. Should be 1/2 of outerring diameter. -->
+    <dimen name="glowpadview_target_placement_radius">135dip</dimen>
+
+    <!-- Default glow radius for GlowPadView -->
+    <dimen name="glowpadview_glow_radius">75dip</dimen>
+
+    <!-- Default distance beyond which GlowPadView snaps to the matching target -->
+    <dimen name="glowpadview_snap_margin">40dip</dimen>
+
+    <!-- Default distance from each snap target that GlowPadView considers a "hit" -->
+    <dimen name="glowpadview_inner_radius">15dip</dimen>
+
+    <!-- Size of clock font in LockScreen on Unsecure unlock screen. -->
+    <dimen name="keyguard_lockscreen_clock_font_size">80dip</dimen>
+
+    <!-- Size of status line font on Unsecure unlock LockScreen. -->
+    <dimen name="keyguard_lockscreen_status_line_font_size">14dip</dimen>
+
+    <!-- Size of right margin on Unsecure unlock LockScreen -->
+    <dimen name="keyguard_lockscreen_status_line_font_right_margin">42dip</dimen>
+
+    <!-- Size of top margin on Clock font to edge on unlock LockScreen -->
+    <dimen name="keyguard_lockscreen_status_line_clockfont_top_margin">22dip</dimen>
+
+    <!-- Size of top margin on Clock font to edge on unlock LockScreen -->
+    <dimen name="keyguard_lockscreen_status_line_clockfont_bottom_margin">12dip</dimen>
+
+    <!-- Padding on left margin of PIN text entry field to center it when del button is showing -->
+    <dimen name="keyguard_lockscreen_pin_margin_left">40dip</dimen>
+
+    <!-- Height of FaceUnlock view in keyguard -->
+    <dimen name="face_unlock_height">330dip</dimen>
+
+    <!-- Keyguard dimensions -->
+    <!-- TEMP -->
+    <dimen name="kg_security_panel_height">600dp</dimen>
+
+    <!-- Height of security view in keyguard. -->
+    <dimen name="kg_security_view_height">480dp</dimen>
+
+    <!-- Width of widget view in keyguard. -->
+    <dimen name="kg_widget_view_width">0dp</dimen>
+
+    <!-- Height of widget view in keyguard. -->
+    <dimen name="kg_widget_view_height">0dp</dimen>
+
+    <!-- Size of the clock font in keyguard's status view -->
+    <dimen name="kg_status_clock_font_size">75dp</dimen>
+
+    <!-- Size of the date font in keyguard's status view  -->
+    <dimen name="kg_status_date_font_size">15dp</dimen>
+
+    <!-- Size of the generic status lines keyguard's status view  -->
+    <dimen name="kg_status_line_font_size">13dp</dimen>
+
+    <!-- Size of margin on the right of keyguard's status view -->
+    <dimen name="kg_status_line_font_right_margin">16dp</dimen>
+
+    <!-- Top margin for the clock view -->
+    <dimen name="kg_clock_top_margin">-16dp</dimen>
+
+    <!-- Horizontal gap between keys in PIN and SIM PIN numeric keyboards in keyguard -->
+    <dimen name="kg_key_horizontal_gap">0dp</dimen>
+
+    <!-- Horizontal gap between keys in PIN and SIM PIN numeric keyboards in keyguard -->
+    <dimen name="kg_key_vertical_gap">0dp</dimen>
+
+    <!-- Horizontal gap between keys in PIN and SIM PIN numeric keyboards in keyguard -->
+    <dimen name="kg_pin_key_height">60dp</dimen>
+
+    <!-- Space reserved at the bottom of secure views (pin/pattern/password/SIM pin/SIM puk) -->
+    <dimen name="kg_secure_padding_height">46dp</dimen>
+
+    <!-- The height of the runway lights strip -->
+    <dimen name="kg_runway_lights_height">7dp</dimen>
+
+    <!-- The height of the runway lights strip -->
+    <dimen name="kg_runway_lights_vertical_padding">2dp</dimen>
+
+    <!-- Horizontal padding for the widget pager -->
+    <dimen name="kg_widget_pager_horizontal_padding">16dp</dimen>
+
+    <!-- Top padding for the widget pager -->
+    <dimen name="kg_widget_pager_top_padding">0dp</dimen>
+
+    <!-- Bottom padding for the widget pager -->
+    <dimen name="kg_widget_pager_bottom_padding">64dp</dimen>
+
+    <!-- Top margin for the runway lights. We add a negative margin in large
+        devices to account for the widget pager padding -->
+    <dimen name="kg_runway_lights_top_margin">0dp</dimen>
+
+    <!-- Touch slop for the global toggle accessibility gesture -->
+    <dimen name="accessibility_touch_slop">80dip</dimen>
+
+    <!-- Width of the sliding KeyguardSecurityContainer (includes 2x keyguard_security_view_margin) -->
+    <dimen name="keyguard_security_width">320dp</dimen>
+
+    <!-- Height of the sliding KeyguardSecurityContainer (includes 2x keyguard_security_view_margin) -->
+    <dimen name="keyguard_security_height">400dp</dimen>
+
+    <!-- Margin around the various security views -->
+    <dimen name="keyguard_security_view_margin">8dp</dimen>
+
+    <!-- Margin around the various security views -->
+    <dimen name="keyguard_muliuser_selector_margin">8dp</dimen>
+
+    <!-- Stroke width of the frame for the circular avatars. -->
+    <dimen name="keyguard_avatar_frame_stroke_width">2dp</dimen>
+
+    <!-- Shadow radius under the frame for the circular avatars. -->
+    <dimen name="keyguard_avatar_frame_shadow_radius">1dp</dimen>
+
+    <!-- Size of the avator on hte multiuser lockscreen. -->
+    <dimen name="keyguard_avatar_size">66dp</dimen>
+
+    <!-- Size of the text under the avator on the multiuser lockscreen. -->
+    <dimen name="keyguard_avatar_name_size">10sp</dimen>
+
+    <!-- Size of the region along the edge of the screen that will accept
+         swipes to scroll the widget area. -->
+    <dimen name="kg_edge_swipe_region_size">24dp</dimen>
+
+    <!-- If the height if keyguard drops below this threshold (most likely
+    due to the appearance of the IME), then drop the multiuser selector. -->
+    <dimen name="kg_squashed_layout_threshold">600dp</dimen>
+
+    <!-- The height of widgets which do not support vertical resizing. This is only
+    used on tablets; on phones, this size is determined by the space left by the
+    security mode. -->
+    <dimen name="kg_small_widget_height">160dp</dimen>
+
+</resources>
diff --git a/packages/Keyguard/res/values/integers.xml b/packages/Keyguard/res/values/integers.xml
new file mode 100644
index 0000000..053fc85
--- /dev/null
+++ b/packages/Keyguard/res/values/integers.xml
@@ -0,0 +1,24 @@
+<?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.
+*/
+-->
+<resources>
+    <integer name="kg_carousel_angle">75</integer>
+    <integer name="kg_security_flip_duration">100</integer>
+    <integer name="kg_security_fade_duration">100</integer>
+    <integer name="kg_glowpad_rotation_offset">0</integer>
+</resources>
diff --git a/packages/Keyguard/res/values/strings.xml b/packages/Keyguard/res/values/strings.xml
new file mode 100644
index 0000000..5cf05f8
--- /dev/null
+++ b/packages/Keyguard/res/values/strings.xml
@@ -0,0 +1,327 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR 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">
+    <!-- Instructions telling the user to enter their SIM PIN to unlock the keyguard.
+         Displayed in one line in a large font.  -->
+    <string name="keyguard_password_enter_pin_code">Type PIN code</string>
+
+    <!-- Instructions telling the user to enter their SIM PUK to unlock the keyguard.
+         Displayed in one line in a large font.  -->
+    <string name="keyguard_password_enter_puk_code">Type PUK and new PIN code</string>
+
+    <!-- Prompt to enter SIM PUK in Edit Text Box in unlock screen -->
+    <string name="keyguard_password_enter_puk_prompt">PUK code</string>
+    <!-- Prompt to enter New SIM PIN in Edit Text Box in unlock screen -->
+    <string name="keyguard_password_enter_pin_prompt">New PIN code</string>
+
+    <!-- Displayed as hint in passwordEntry EditText on PasswordUnlockScreen [CHAR LIMIT=30]-->
+    <string name="keyguard_password_entry_touch_hint"><font size="17">Touch to type password</font></string>
+
+    <!-- Instructions telling the user to enter their text password to unlock the keyguard.
+         Displayed in one line in a large font.  -->
+    <string name="keyguard_password_enter_password_code">Type password to unlock</string>
+
+    <!-- Instructions telling the user to enter their PIN password to unlock the keyguard.
+         Displayed in one line in a large font.  -->
+    <string name="keyguard_password_enter_pin_password_code">Type PIN to unlock</string>
+
+    <!-- Instructions telling the user that they entered the wrong pin while trying
+         to unlock the keyguard.  Displayed in one line in a large font.  -->
+    <string name="keyguard_password_wrong_pin_code">Incorrect PIN code.</string>
+
+    <!-- Instructions telling the user how to unlock the phone. -->
+    <string name="keyguard_label_text">To unlock, press Menu then 0.</string>
+
+    <!-- Shown when face unlock failed multiple times so we're just using the backup -->
+    <string name="faceunlock_multiple_failures">Maximum Face Unlock attempts exceeded</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>
+
+    <!-- When the lock screen is showing and the phone plugged in, and the battery
+         is not fully charged, show the current charge %.  -->
+    <string name="keyguard_plugged_in">Charging, <xliff:g id="number">%d</xliff:g><xliff:g id="percent">%%</xliff:g></string>
+
+    <!-- When the lock screen is showing and the battery is low, warn user to plug
+         in the phone soon. -->
+    <string name="keyguard_low_battery">Connect your charger.</string>
+
+    <!-- On the keyguard screen, when pattern lock is disabled, only tell them to press menu to unlock.  This is shown in small font at the bottom. -->
+    <string name="keyguard_instructions_when_pattern_disabled">Press Menu to unlock.</string>
+
+    <!-- SIM messages --><skip />
+    <!-- When the user inserts a sim card from an unsupported network, it becomes network locked -->
+    <string name="keyguard_network_locked_message">Network locked</string>
+    <!-- Shown when there is no SIM card. -->
+    <string name="keyguard_missing_sim_message_short">No SIM card</string>
+    <!-- Shown when there is no SIM card. -->
+    <string name="keyguard_missing_sim_message" product="tablet">No SIM card in tablet.</string>
+    <!-- Shown when there is no SIM card. -->
+    <string name="keyguard_missing_sim_message" product="default">No SIM card in phone.</string>
+    <!-- Shown to ask the user to insert a SIM card. -->
+    <string name="keyguard_missing_sim_instructions">Insert a SIM card.</string>
+    <!-- Shown to ask the user to insert a SIM card when sim is missing or not readable. -->
+    <string name="keyguard_missing_sim_instructions_long">The SIM card is missing or not readable. Insert a SIM card.</string>
+    <!-- Shown when SIM card is permanently disabled. -->
+    <string name="keyguard_permanent_disabled_sim_message_short">Unusable SIM card.</string>
+    <!-- Shown to inform the user to SIM card is permanently disabled. -->
+    <string name="keyguard_permanent_disabled_sim_instructions">Your SIM card has been permanently disabled.\n
+    Contact your wireless service provider for another SIM card.</string>
+    <!-- Shown to tell the user that their SIM is locked and they must unlock it. -->
+    <string name="keyguard_sim_locked_message">SIM card is locked.</string>
+    <!-- When the user enters a wrong sim pin too many times, it becomes PUK locked (Pin Unlock Kode) -->
+    <string name="keyguard_sim_puk_locked_message">SIM card is PUK-locked.</string>
+    <!-- For the unlock screen, When the user enters a sim unlock code, it takes a little while to check
+         whether it is valid, and to unlock the sim if it is valid.  we display a
+         progress dialog in the meantime.  this is the emssage. -->
+    <string name="keyguard_sim_unlock_progress_dialog_message">Unlocking SIM card\u2026</string>
+
+
+    <!-- Accessibility description sent when user changes the current lock screen widget. [CHAR_LIMIT=none] -->
+    <string name="keyguard_accessibility_widget_changed">%1$s. Widget %2$d of %3$d.</string>
+    <!-- Accessibility description of the add widget button. [CHAR_LIMIT=none] -->
+    <string name="keyguard_accessibility_add_widget">Add widget.</string>
+    <!-- Accessibility description of the empty sidget slot (place holder for a new widget). [CHAR_LIMIT=none] -->
+    <string name="keyguard_accessibility_widget_empty_slot">Empty</string>
+    <!-- Accessibility description of the event of expanding an unlock area. [CHAR_LIMIT=none] -->
+    <string name="keyguard_accessibility_unlock_area_expanded">Unlock area expanded.</string>
+    <!-- Accessibility description of the event of collapsing an unlock area. [CHAR_LIMIT=none] -->
+    <string name="keyguard_accessibility_unlock_area_collapsed">Unlock area collapsed.</string>
+    <!-- Accessibility description of a lock screen widget. [CHAR_LIMIT=none] -->
+    <string name="keyguard_accessibility_widget"><xliff:g id="widget_index">%1$s</xliff:g> widget.</string>
+    <!-- Accessibility description of the lock screen user selector widget. [CHAR_LIMIT=none] -->
+    <string name="keyguard_accessibility_user_selector">User selector</string>
+    <!-- Accessibility description of the lock screen status widget. [CHAR_LIMIT=none] -->
+    <string name="keyguard_accessibility_status">Status</string>
+    <!-- Accessibility description of the camera widget. [CHAR_LIMIT=none] -->
+    <string name="keyguard_accessibility_camera">Camera</string>
+    <!-- Accessibility description of the lock media control widget. [CHAR_LIMIT=none] -->
+    <string name="keygaurd_accessibility_media_controls">Media controls</string>
+    <!-- Accessibility description of widget reordering start. [CHAR_LIMIT=none] -->
+    <string name="keyguard_accessibility_widget_reorder_start">Widget reordering started.</string>
+    <!-- Accessibility description of widget reordering end. [CHAR_LIMIT=none] -->
+    <string name="keyguard_accessibility_widget_reorder_end">Widget reordering ended.</string>
+    <!-- Accessibility description of the a widget deletion event. [CHAR_LIMIT=none] -->
+    <string name="keyguard_accessibility_widget_deleted">Widget <xliff:g id="widget_index">%1$s</xliff:g> deleted.</string>
+    <!-- Accessibility description of the button to expand the lock area. [CHAR_LIMIT=none] -->
+    <string name="keyguard_accessibility_expand_lock_area">Expand unlock area.</string>
+    <!-- Accessibility description of the slide unlock. [CHAR_LIMIT=none] -->
+    <string name="keyguard_accessibility_slide_unlock">Slide unlock.</string>
+    <!-- Accessibility description of the pattern unlock. [CHAR_LIMIT=none] -->
+    <string name="keyguard_accessibility_pattern_unlock">Pattern unlock.</string>
+    <!-- Accessibility description of the face unlock. [CHAR_LIMIT=none] -->
+    <string name="keyguard_accessibility_face_unlock">Face unlock.</string>
+    <!-- Accessibility description of the pin lock. [CHAR_LIMIT=none] -->
+    <string name="keyguard_accessibility_pin_unlock">Pin unlock.</string>
+    <!-- Accessibility description of the password lock. [CHAR_LIMIT=none] -->
+    <string name="keyguard_accessibility_password_unlock">Password unlock.</string>
+    <!-- Accessibility description of the unlock pattern area. [CHAR_LIMIT=none] -->
+    <string name="keyguard_accessibility_pattern_area">Pattern area.</string>
+    <!-- Accessibility description of the unlock slide area. [CHAR_LIMIT=none] -->
+    <string name="keyguard_accessibility_slide_area">Slide area.</string>
+
+    <!-- Shown on transport control of lockscreen. Pressing button goes to previous track. -->
+    <string name="keyguard_accessibility_transport_prev_description">Previous track button</string>
+    <!-- Shown on transport control of lockscreen. Pressing button goes to next track. -->
+    <string name="keyguard_accessibility_transport_next_description">Next track button</string>
+    <!-- Shown on transport control of lockscreen. Pressing button pauses playback -->
+    <string name="keyguard_accessibility_transport_pause_description">Pause button</string>
+    <!-- Shown on transport control of lockscreen. Pressing button pauses playback -->
+    <string name="keyguard_accessibility_transport_play_description">Play button</string>
+    <!-- Shown on transport control of lockscreen. Pressing button pauses playback -->
+    <string name="keyguard_accessibility_transport_stop_description">Stop button</string>
+
+    <!-- Password keyboard strings. Used by LockScreen and Settings --><skip />
+    <!-- Label for "switch to symbols" key.  Must be short to fit on key! -->
+    <string name="password_keyboard_label_symbol_key">\?123</string>
+    <!-- Label for "switch to alphabetic" key.  Must be short to fit on key! -->
+    <string name="password_keyboard_label_alpha_key">ABC</string>
+    <!-- Label for ALT modifier key.  Must be short to fit on key! -->
+    <string name="password_keyboard_label_alt_key">ALT</string>
+
+    <!-- KeyboardView - accessibility support --><skip />
+    <!-- Description of the Alt button in a KeyboardView. [CHAR LIMIT=NONE] -->
+    <string name="keyboardview_keycode_alt">Alt</string>
+    <!-- Description of the Cancel button in a KeyboardView. [CHAR LIMIT=NONE] -->
+    <string name="keyboardview_keycode_cancel">Cancel</string>
+    <!-- Description of the Delete button in a KeyboardView. [CHAR LIMIT=NONE] -->
+    <string name="keyboardview_keycode_delete">Delete</string>
+    <!-- Description of the Done button in a KeyboardView. [CHAR LIMIT=NONE] -->
+    <string name="keyboardview_keycode_done">Done</string>
+    <!-- Description of the Mode change button in a KeyboardView. [CHAR LIMIT=NONE] -->
+    <string name="keyboardview_keycode_mode_change">Mode change</string>
+    <!-- Description of the Shift button in a KeyboardView. [CHAR LIMIT=NONE] -->
+    <string name="keyboardview_keycode_shift">Shift</string>
+    <!-- Description of the Enter button in a KeyboardView. [CHAR LIMIT=NONE] -->
+    <string name="keyboardview_keycode_enter">Enter</string>
+
+    <!-- Description of the unlock target in the Slide unlock screen. [CHAR LIMIT=NONE] -->
+    <string name="description_target_unlock">Unlock</string>
+    <!-- Description of the camera target in the Slide unlock screen. [CHAR LIMIT=NONE] -->
+    <string name="description_target_camera">Camera</string>
+    <!-- Description of the silent target in the Slide unlock screen. [CHAR LIMIT=NONE] -->
+    <string name="description_target_silent">Silent</string>
+    <!-- Description of the sound on target in the Slide unlock screen. [CHAR LIMIT=NONE] -->
+    <string name="description_target_soundon">Sound on</string>
+    <!-- Description of the unlock target in the Slide unlock screen. [CHAR LIMIT=NONE] -->
+    <string name="description_target_search">Search</string>
+
+    <!-- Description of the up direction in which one can to slide the handle in the Slide unlock screen. [CHAR LIMIT=NONE] -->
+    <string name="description_direction_up">Slide up for <xliff:g id="target_description" example="Unlock">%s</xliff:g>.</string>
+    <!-- Description of the down direction in which one can to slide the handle in the Slide unlock screen. [CHAR LIMIT=NONE] -->
+    <string name="description_direction_down">Slide down for <xliff:g id="target_description" example="Unlock">%s</xliff:g>.</string>
+    <!-- Description of the left direction in which one can to slide the handle in the Slide unlock screen. [CHAR LIMIT=NONE] -->
+    <string name="description_direction_left">"Slide left for <xliff:g id="target_description" example="Unlock">%s</xliff:g>.</string>
+    <!-- Description of the right direction in which one can to slide the handle in the Slide unlock screen. [CHAR LIMIT=NONE] -->
+    <string name="description_direction_right">Slide right for <xliff:g id="target_description" example="Unlock">%s</xliff:g>.</string>
+
+    <!-- Text spoken when the current user is switched if accessibility is enabled. [CHAR LIMIT=none] -->
+    <string name="user_switched">Current user <xliff:g id="name" example="Bob">%1$s</xliff:g>.</string>
+
+    <!-- Label shown on emergency call button in keyguard -->
+    <string name="kg_emergency_call_label">Emergency call</string>
+    <!-- Message shown in pattern unlock after some number of unsuccessful attempts -->
+    <string name="kg_forgot_pattern_button_text">Forgot Pattern</string>
+    <!-- Message shown when user enters wrong pattern -->
+    <string name="kg_wrong_pattern">Wrong Pattern</string>
+    <!-- Message shown when user enters wrong password -->
+    <string name="kg_wrong_password">Wrong Password</string>
+    <!-- Message shown when user enters wrong PIN -->
+    <string name="kg_wrong_pin">Wrong PIN</string>
+    <!-- Countdown message shown after too many failed unlock attempts -->
+    <string name="kg_too_many_failed_attempts_countdown">Try again in <xliff:g id="number">%d</xliff:g> seconds.</string>
+    <!-- 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>
+    <!-- Instructions for using the PIN unlock screen -->
+    <string name="kg_pin_instructions">Enter PIN</string>
+    <!-- Instructions for using the password unlock screen -->
+    <string name="kg_password_instructions">Enter Password</string>
+    <!-- Hint shown in the PUK screen that asks the user to enter the PUK code given to them by their provider -->
+    <string name="kg_puk_enter_puk_hint">SIM is now disabled. Enter PUK code to continue. Contact carrier for details.</string>
+    <!-- Hint shown in the PUK unlock screen PIN TextView -->
+    <string name="kg_puk_enter_pin_hint">Enter desired PIN code</string>
+    <!-- Message shown when the user needs to confirm the PIN they just entered in the PUK screen -->
+    <string name="kg_enter_confirm_pin_hint">Confirm desired PIN code</string>
+    <!-- Message shown in dialog while the device is unlocking the SIM card -->
+    <string name="kg_sim_unlock_progress_dialog_message">Unlocking SIM card\u2026</string>
+    <!-- Message shown when the user enters the wrong PIN code -->
+    <string name="kg_password_wrong_pin_code">Incorrect PIN code.</string>
+    <!-- Message shown when the user enters an invalid SIM pin password in PUK screen -->
+    <string name="kg_invalid_sim_pin_hint">Type a PIN that is 4 to 8 numbers.</string>
+    <!-- Message shown when the user enters an invalid PUK code in the PUK screen -->
+    <string name="kg_invalid_sim_puk_hint">PUK code should be 8 numbers or more.</string>
+    <!-- Message shown when the user enters an invalid PUK code -->
+    <string name="kg_invalid_puk">Re-enter the correct PUK code. Repeated attempts will permanently disable the SIM.</string>
+      <!-- String shown in PUK screen when PIN codes don't match -->
+    <string name="kg_invalid_confirm_pin_hint" product="default">PIN codes does not match</string>
+    <!-- Message shown when the user exceeds the maximum number of pattern attempts -->
+    <string name="kg_login_too_many_attempts">Too many pattern attempts</string>
+    <!-- Instructions show in account unlock screen allowing user to enter their email password -->
+    <string name="kg_login_instructions">To unlock, sign in with your Google account.</string>
+    <!-- Hint shown in TextView in account unlock screen of keyguard -->
+    <string name="kg_login_username_hint">Username (email)</string>
+    <!-- Hint shown in TextView in account unlock screen of keyguard -->
+    <string name="kg_login_password_hint">Password</string>
+    <!-- Label shown on sign in button on account unlock screen of keyguard -->
+    <string name="kg_login_submit_button">Sign in</string>
+    <!-- Message shown when the user enters an invalid username/password combination in account unlock screen of keyguard -->
+    <string name="kg_login_invalid_input">Invalid username or password.</string>
+    <!-- Hint text shown when user has too many failed password attempts in account unlock screen of keyguard -->
+    <string name="kg_login_account_recovery_hint">Forgot your username or password\?\nVisit <b>google.com/accounts/recovery</b>.</string>
+    <!-- Message shown while device checks username/password in account unlock screen of keyguard -->
+    <string name="kg_login_checking_password">Checking account\u2026</string>
+    <!-- Message shown in dialog when max number of attempts are reached for PIN screen of keyguard -->
+    <string name="kg_too_many_failed_pin_attempts_dialog_message">
+        You have incorrectly typed your PIN <xliff:g id="number">%d</xliff:g> times.
+        \n\nTry again in <xliff:g id="number">%d</xliff:g> seconds.
+    </string>
+    <!-- Message shown in dialog when max number of attempts are reached for password screen of keyguard -->
+    <string name="kg_too_many_failed_password_attempts_dialog_message">
+        You have incorrectly typed your password <xliff:g id="number">%d</xliff:g> times.
+        \n\nTry again in <xliff:g id="number">%d</xliff:g> seconds.
+    </string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message">
+        You have incorrectly drawn your unlock pattern <xliff:g id="number">%d</xliff:g> times.
+        \n\nTry again in <xliff:g id="number">%d</xliff:g> seconds.
+    </string>
+    <!-- Message shown when user is almost at the limit of password attempts where the device will be wiped. -->
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet">
+       You have incorrectly attempted to unlock the tablet <xliff:g id="number">%d</xliff:g> times.
+       After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
+       the tablet will be reset to factory default and all user data will be lost.
+    </string>
+    <!-- Message shown when user is almost at the limit of password attempts where the device will be wiped. -->
+    <string name="kg_failed_attempts_almost_at_wipe" product="default">
+       You have incorrectly attempted to unlock the phone <xliff:g id="number">%d</xliff:g> times.
+       After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
+       the phone will be reset to factory default and all user data will be lost.
+    </string>
+    <!-- Message shown in dialog when user has exceeded the maximum attempts and the device will now be wiped -->
+    <string name="kg_failed_attempts_now_wiping" product="tablet">
+       You have incorrectly attempted to unlock the tablet <xliff:g id="number">%d</xliff:g> times.
+       The tablet will now be reset to factory default.
+    </string>
+    <!-- Message shown in dialog when user has exceeded the maximum attempts and the device will now be wiped -->
+    <string name="kg_failed_attempts_now_wiping" product="default">
+       You have incorrectly attempted to unlock the phone <xliff:g id="number">%d</xliff:g> times.
+       The phone will now be reset to factory default.
+    </string>
+    <!-- Message shown in dialog when user is almost at the limit where they will be
+    locked out and may have to enter an alternate username/password to unlock the phone -->
+    <string name="kg_failed_attempts_almost_at_login" product="tablet">
+       You have incorrectly drawn your unlock pattern <xliff:g id="number">%d</xliff:g> times.
+       After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
+       you will be asked to unlock your tablet using an email account.\n\n
+       Try again in <xliff:g id="number">%d</xliff:g> seconds.
+    </string>
+    <!-- Message shown in dialog when user is almost at the limit where they will be
+    locked out and may have to enter an alternate username/password to unlock the phone -->
+    <string name="kg_failed_attempts_almost_at_login" product="default">
+       You have incorrectly drawn your unlock pattern <xliff:g id="number">%d</xliff:g> times.
+       After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
+       you will be asked to unlock your phone using an email account.\n\n
+       Try again in <xliff:g id="number">%d</xliff:g> seconds.
+    </string>
+    <!-- Sequence of characters used to separate message strings in keyguard. Typically just em-dash
+         with spaces on either side. [CHAR LIMIT=3] -->
+    <string name="kg_text_message_separator" product="default">" \u2014 "</string>
+    <!-- The delete-widget drop target button text -->
+    <string name="kg_reordering_delete_drop_target_text">Remove</string>
+
+    <!-- Transport control strings -->
+    <!-- Shown on transport control of lockscreen. Pressing button goes to previous track. -->
+    <string name="keyguard_transport_prev_description">Previous track button</string>
+    <!-- Shown on transport control of lockscreen. Pressing button goes to next track. -->
+    <string name="keyguard_transport_next_description">Next track button</string>
+    <!-- Shown on transport control of lockscreen. Pressing button pauses playback -->
+    <string name="keyguard_transport_pause_description">Pause button</string>
+    <!-- Shown on transport control of lockscreen. Pressing button pauses playback -->
+    <string name="keyguard_transport_play_description">Play button</string>
+    <!-- Shown on transport control of lockscreen. Pressing button pauses playback -->
+    <string name="keyguard_transport_stop_description">Stop button</string>
+
+    <!-- On the keyguard screen, it shows the carrier the phone is connected to.
+        This is displayed if the phone is not connected to a carrier.-->
+    <string name="keyguard_carrier_default">No service.</string>
+
+</resources>
diff --git a/packages/Keyguard/res/values/styles.xml b/packages/Keyguard/res/values/styles.xml
new file mode 100644
index 0000000..16a3f3f
--- /dev/null
+++ b/packages/Keyguard/res/values/styles.xml
@@ -0,0 +1,55 @@
+<?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.
+*/
+-->
+
+<resources>
+    <!-- Keyguard PIN pad styles -->
+    <style name="Widget.Button.NumPadKey"
+            parent="@android:style/Widget.Button">
+        <item name="android:singleLine">true</item>
+        <item name="android:padding">6dip</item>
+        <item name="android:gravity">left|center_vertical</item>
+        <item name="android:background">?android:attr/selectableItemBackground</item>
+        <item name="android:textSize">34dp</item>
+        <item name="android:fontFamily">sans-serif</item>
+        <item name="android:textStyle">normal</item>
+        <item name="android:textColor">#ffffff</item>
+        <item name="android:paddingBottom">10dp</item>
+        <item name="android:paddingLeft">20dp</item>
+    </style>
+    <style name="TextAppearance.NumPadKey"
+            parent="@android:style/TextAppearance">
+        <item name="android:textSize">34dp</item>
+        <item name="android:fontFamily">sans-serif</item>
+        <item name="android:textStyle">normal</item>
+        <item name="android:textColor">#ffffff</item>
+    </style>
+    <style name="TextAppearance.NumPadKey.Klondike">
+        <item name="android:textSize">20dp</item>
+        <item name="android:fontFamily">sans-serif-condensed</item>
+        <item name="android:textStyle">normal</item>
+        <item name="android:textColor">#80ffffff</item>
+    </style>
+
+    <!-- Standard animations for a non-full-screen window or activity. -->
+    <style name="Animation.LockScreen" parent="@android:style/Animation">
+        <item name="android:windowEnterAnimation">@anim/lock_screen_enter</item>
+        <item name="android:windowExitAnimation">@anim/lock_screen_exit</item>
+    </style>
+
+</resources>
diff --git a/packages/Keyguard/scripts/copy_profile_icons.sh b/packages/Keyguard/scripts/copy_profile_icons.sh
new file mode 100755
index 0000000..5416101
--- /dev/null
+++ b/packages/Keyguard/scripts/copy_profile_icons.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+for user in `adb $* shell ls /data/system/users | grep -v xml`
+do
+  user=${user/$'\r'/}
+  adb shell mkdir /data/user/${user}/users
+  for photo in `adb $* shell ls /data/system/users | grep -v xml`
+  do
+    photo=${photo/$'\r'/}
+    adb shell mkdir /data/user/${user}/users/${photo}
+    adb pull /data/system/users/${photo}/photo.png
+    adb push photo.png /data/user/${user}/users/${photo}
+  done
+done
diff --git a/packages/Keyguard/scripts/new_merge.py b/packages/Keyguard/scripts/new_merge.py
new file mode 100755
index 0000000..70fafec
--- /dev/null
+++ b/packages/Keyguard/scripts/new_merge.py
@@ -0,0 +1,165 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import difflib
+import filecmp
+import tempfile
+from optparse import OptionParser
+from subprocess import call
+from subprocess import Popen
+from subprocess import PIPE
+
+def which(program):
+    def executable(path):
+        return os.path.isfile(path) and os.access(path, os.X_OK)
+
+    path, file = os.path.split(program)
+    if path and executable(program):
+		return program
+    else:
+        for path in os.environ["PATH"].split(os.pathsep):
+            exe = os.path.join(path, program)
+            if executable(exe):
+                return exe
+    return ""
+
+DIFF_TOOLS=["meld", "kdiff3", "xdiff", "diffmerge.sh", "diff"]
+
+PROTO_SRC="./src/com/android/keyguard/"
+PROTO_RES="./res/"
+
+TEMP_FILE1="/tmp/tempFile1.txt"
+TEMP_FILE2="/tmp/tempFile2.txt"
+
+FW_SRC="../../../../frameworks/base/policy/src/com/android/internal/policy/impl/keyguard/"
+FW_RES="../../../../frameworks/base/core/res/res/"
+
+FW_PKG="com.android.internal.policy.impl.keyguard"
+PROTO_PKG="com.android.keyguard"
+
+FW_RES_IMPORT="import com.android.internal.R;"
+
+# Find a differ
+DIFF_TOOL=""
+if ("DIFF_TOOL" in os.environ and len(os.environ["DIFF_TOOL"]) > 0):
+	DIFF_TOOL=which(os.environ["DIFF_TOOL"])
+if len(DIFF_TOOL) == 0:
+	for differ in DIFF_TOOLS:
+		DIFF_TOOL=which(differ)
+		if len(DIFF_TOOL) > 0:
+			break
+
+print "Using differ", DIFF_TOOL
+
+#Anything file which contains any string in this list as a substring will be ommitted
+IGNORE=["LockHotnessActivity.java", "unified_lock_activity.xml", "optionmenu.xml"]
+WATCH=[]
+
+def dirCompare(sourceDir, destDir, ext, run_in_reverse):
+	sourceFiles = getFileList(sourceDir, ext)
+	destFiles = getFileList(destDir, ext)
+	for file in sourceFiles:
+		print file
+		destFile = destDir + file
+		sourceFile = sourceDir + file
+		if (file in destFiles):
+			if run_in_reverse:
+				prepareFileForCompare(sourceFile, TEMP_FILE1, FW_RES_IMPORT, FW_PKG, PROTO_PKG)
+				prepareFileForCompare(destFile, TEMP_FILE2, FW_RES_IMPORT,)
+			else:
+				prepareFileForCompare(destFile, TEMP_FILE1, FW_RES_IMPORT, FW_PKG, PROTO_PKG)
+				prepareFileForCompare(sourceFile, TEMP_FILE2, FW_RES_IMPORT,)
+			if (filecmp.cmp(TEMP_FILE1, TEMP_FILE2)):
+				print "File %s is the same in proto and framework" %(file)
+			else:
+				print "Running diff for: %s" %(file)
+				diff(sourceFile, destFile)
+		else:
+			print "File %s does not exist in framework" %(file)
+			if not run_in_reverse:
+				diff(sourceFile, destFile)
+
+def main(argv):
+	run_in_reverse = False
+	if len(argv) > 1:
+		if argv[1] == '--help' or argv[1] == '-h':
+			print ('Usage: %s [<commit>]' % argv[0])
+			print ('\tdiff to framework, ' +
+					'optionally restricting to files in <commit>')
+			sys.exit(0)
+		elif argv[1] == '--reverse':
+			print "Running in reverse"
+			run_in_reverse = True
+		else:
+			print ("**** Pulling file list from: %s" % argv[1])
+			pipe = Popen(['git', 'diff', '--name-only',  argv[1]], stdout=PIPE).stdout
+			for line in iter(pipe.readline,''):
+				path = line.rstrip()
+				file = path[path.rfind('/') + 1:]
+				print '**** watching: %s' % file
+				WATCH.append(file);
+			pipe.close()
+
+	if run_in_reverse:
+		#dirCompare(FW_RES, PROTO_RES, ".xml", run_in_reverse)
+		print ("**** Source files:")
+		dirCompare(FW_SRC, PROTO_SRC, ".java", run_in_reverse)
+	else:
+		#dirCompare(PROTO_RES, FW_RES, ".xml", run_in_reverse)
+		print ("**** Source files:")
+		dirCompare(PROTO_SRC, FW_SRC, ".java", run_in_reverse)
+
+	if (os.path.exists(TEMP_FILE1)):
+		os.remove(TEMP_FILE1)
+
+	if (os.path.exists(TEMP_FILE2)):
+		os.remove(TEMP_FILE2)
+
+def getFileList(rootdir, extension):
+	fileList = []
+
+	for root, subFolders, files in os.walk(rootdir):
+	    for file in files:
+	        f = os.path.join(root,file)
+	        if (os.path.splitext(f)[1] == extension and (not inIgnore(f))):
+	        	fileList.append(f[len(rootdir):])
+	return fileList
+
+
+def prepareFileForCompare(inFile, outFile, skip="", replace="", withText=""):
+	# Delete the outfile, so we're starting with a new file
+	if (os.path.exists(outFile)):
+		os.remove(outFile)
+
+	fin = open(inFile)
+	fout = open(outFile, "w")
+	for line in fin:
+		# Ignore any lines containing the ignore string ("import com.android.internal.R;) and
+		# ignore any lines containing only whitespace.
+		if (line.find(skip) < 0  and len(line.strip(' \t\n\r')) > 0):
+			# For comparison, for framework files, we replace the fw package with the
+			# proto package, since these aren't relevant.
+			if len(replace) > 0:
+				fout.write(line.replace(replace, withText))
+			else:
+				fout.write(line)
+	fin.close()
+	fout.close()
+
+def diff(file1, file2):
+	call([DIFF_TOOL, file1, file2])
+
+def inIgnore(file):
+	for ignore in IGNORE:
+		if file.find(ignore) >= 0:
+			return True
+        if len(WATCH) > 0:
+            for watch in WATCH:
+		if file.find(watch) >= 0:
+                    return False
+            return True
+	return False
+
+if __name__=="__main__":
+  main(sys.argv)
diff --git a/packages/Keyguard/src/com/android/keyguard/BiometricSensorUnlock.java b/packages/Keyguard/src/com/android/keyguard/BiometricSensorUnlock.java
new file mode 100644
index 0000000..230ef81
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/BiometricSensorUnlock.java
@@ -0,0 +1,68 @@
+/*
+ * 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.keyguard;
+
+import android.view.View;
+
+interface BiometricSensorUnlock {
+    /**
+     * Initializes the view provided for the biometric unlock UI to work within.  The provided area
+     * completely covers the backup unlock mechanism.
+     * @param biometricUnlockView View provided for the biometric unlock UI.
+     */
+    public void initializeView(View biometricUnlockView);
+
+    /**
+     * Indicates whether the biometric unlock is running.  Before
+     * {@link BiometricSensorUnlock#start} is called, isRunning() returns false.  After a successful
+     * call to {@link BiometricSensorUnlock#start}, isRunning() returns true until the biometric
+     * unlock completes, {@link BiometricSensorUnlock#stop} has been called, or an error has
+     * forced the biometric unlock to stop.
+     * @return whether the biometric unlock is currently running.
+     */
+    public boolean isRunning();
+
+    /**
+     * Stops and removes the biometric unlock and shows the backup unlock
+     */
+    public void stopAndShowBackup();
+
+    /**
+     * Binds to the biometric unlock service and starts the unlock procedure.  Called on the UI
+     * thread.
+     * @return false if it can't be started or the backup should be used.
+     */
+    public boolean start();
+
+    /**
+     * Stops the biometric unlock procedure and unbinds from the service.  Called on the UI thread.
+     * @return whether the biometric unlock was running when called.
+     */
+    public boolean stop();
+
+    /**
+     * Cleans up any resources used by the biometric unlock.
+     */
+    public void cleanUp();
+
+    /**
+     * Gets the Device Policy Manager quality of the biometric unlock sensor
+     * (e.g., PASSWORD_QUALITY_BIOMETRIC_WEAK).
+     * @return biometric unlock sensor quality, as defined by Device Policy Manager.
+     */
+    public int getQuality();
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/CameraWidgetFrame.java b/packages/Keyguard/src/com/android/keyguard/CameraWidgetFrame.java
new file mode 100644
index 0000000..146c092
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/CameraWidgetFrame.java
@@ -0,0 +1,457 @@
+/*
+ * 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.keyguard;
+
+import android.content.Context;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.graphics.Color;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.os.Handler;
+import android.os.SystemClock;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.ImageView.ScaleType;
+
+import com.android.keyguard.KeyguardActivityLauncher.CameraWidgetInfo;
+
+public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnClickListener {
+    private static final String TAG = CameraWidgetFrame.class.getSimpleName();
+    private static final boolean DEBUG = KeyguardHostView.DEBUG;
+    private static final int WIDGET_ANIMATION_DURATION = 250; // ms
+    private static final int WIDGET_WAIT_DURATION = 650; // ms
+    private static final int RECOVERY_DELAY = 1000; // ms
+
+    interface Callbacks {
+        void onLaunchingCamera();
+        void onCameraLaunchedSuccessfully();
+        void onCameraLaunchedUnsuccessfully();
+    }
+
+    private final Handler mHandler = new Handler();
+    private final KeyguardActivityLauncher mActivityLauncher;
+    private final Callbacks mCallbacks;
+    private final CameraWidgetInfo mWidgetInfo;
+    private final WindowManager mWindowManager;
+    private final Point mRenderedSize = new Point();
+    private final int[] mTmpLoc = new int[2];
+    private final Rect mTmpRect = new Rect();
+
+    private long mLaunchCameraStart;
+    private boolean mActive;
+    private boolean mTransitioning;
+    private boolean mDown;
+
+    private FixedSizeFrameLayout mPreview;
+    private View mFullscreenPreview;
+
+    private final Runnable mTransitionToCameraRunnable = new Runnable() {
+        @Override
+        public void run() {
+            transitionToCamera();
+        }};
+
+    private final Runnable mTransitionToCameraEndAction = new Runnable() {
+        @Override
+        public void run() {
+            if (!mTransitioning)
+                return;
+            Handler worker =  getWorkerHandler() != null ? getWorkerHandler() : mHandler;
+            mLaunchCameraStart = SystemClock.uptimeMillis();
+            if (DEBUG) Log.d(TAG, "Launching camera at " + mLaunchCameraStart);
+            mActivityLauncher.launchCamera(worker, mSecureCameraActivityStartedRunnable);
+        }};
+
+    private final Runnable mPostTransitionToCameraEndAction = new Runnable() {
+        @Override
+        public void run() {
+            mHandler.post(mTransitionToCameraEndAction);
+        }};
+
+    private final Runnable mRecoverRunnable = new Runnable() {
+        @Override
+        public void run() {
+            recover();
+        }};
+
+    private final Runnable mRenderRunnable = new Runnable() {
+        @Override
+        public void run() {
+            render();
+        }};
+
+    private final Runnable mSecureCameraActivityStartedRunnable = new Runnable() {
+        @Override
+        public void run() {
+            onSecureCameraActivityStarted();
+        }
+    };
+
+    private final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() {
+        private boolean mShowing;
+        void onKeyguardVisibilityChanged(boolean showing) {
+            if (mShowing == showing)
+                return;
+            mShowing = showing;
+            CameraWidgetFrame.this.onKeyguardVisibilityChanged(mShowing);
+        };
+    };
+
+    private static final class FixedSizeFrameLayout extends FrameLayout {
+        int width;
+        int height;
+
+        FixedSizeFrameLayout(Context context) {
+            super(context);
+        }
+
+        @Override
+        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+            measureChildren(
+                    MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
+                    MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
+            setMeasuredDimension(width, height);
+        }
+    }
+
+    private CameraWidgetFrame(Context context, Callbacks callbacks,
+            KeyguardActivityLauncher activityLauncher,
+            CameraWidgetInfo widgetInfo, View previewWidget) {
+        super(context);
+        mCallbacks = callbacks;
+        mActivityLauncher = activityLauncher;
+        mWidgetInfo = widgetInfo;
+        mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+        KeyguardUpdateMonitor.getInstance(context).registerCallback(mCallback);
+
+        mPreview = new FixedSizeFrameLayout(context);
+        mPreview.addView(previewWidget);
+        addView(mPreview);
+
+        View clickBlocker = new View(context);
+        clickBlocker.setBackgroundColor(Color.TRANSPARENT);
+        clickBlocker.setOnClickListener(this);
+        addView(clickBlocker);
+
+        setContentDescription(context.getString(R.string.keyguard_accessibility_camera));
+        if (DEBUG) Log.d(TAG, "new CameraWidgetFrame instance " + instanceId());
+    }
+
+    public static CameraWidgetFrame create(Context context, Callbacks callbacks,
+            KeyguardActivityLauncher launcher) {
+        if (context == null || callbacks == null || launcher == null)
+            return null;
+
+        CameraWidgetInfo widgetInfo = launcher.getCameraWidgetInfo();
+        if (widgetInfo == null)
+            return null;
+        View previewWidget = getPreviewWidget(context, widgetInfo);
+        if (previewWidget == null)
+            return null;
+
+        return new CameraWidgetFrame(context, callbacks, launcher, widgetInfo, previewWidget);
+    }
+
+    private static View getPreviewWidget(Context context, CameraWidgetInfo widgetInfo) {
+        return widgetInfo.layoutId > 0 ?
+                inflateWidgetView(context, widgetInfo) :
+                inflateGenericWidgetView(context);
+    }
+
+    private static View inflateWidgetView(Context context, CameraWidgetInfo widgetInfo) {
+        if (DEBUG) Log.d(TAG, "inflateWidgetView: " + widgetInfo.contextPackage);
+        View widgetView = null;
+        Exception exception = null;
+        try {
+            Context cameraContext = context.createPackageContext(
+                    widgetInfo.contextPackage, Context.CONTEXT_RESTRICTED);
+            LayoutInflater cameraInflater = (LayoutInflater)
+                    cameraContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+            cameraInflater = cameraInflater.cloneInContext(cameraContext);
+            widgetView = cameraInflater.inflate(widgetInfo.layoutId, null, false);
+        } catch (NameNotFoundException e) {
+            exception = e;
+        } catch (RuntimeException e) {
+            exception = e;
+        }
+        if (exception != null) {
+            Log.w(TAG, "Error creating camera widget view", exception);
+        }
+        return widgetView;
+    }
+
+    private static View inflateGenericWidgetView(Context context) {
+        if (DEBUG) Log.d(TAG, "inflateGenericWidgetView");
+        ImageView iv = new ImageView(context);
+        iv.setImageResource(R.drawable.ic_lockscreen_camera);
+        iv.setScaleType(ScaleType.CENTER);
+        iv.setBackgroundColor(Color.argb(127, 0, 0, 0));
+        return iv;
+    }
+
+    private void render() {
+        final View root = getRootView();
+        final int width = root.getWidth();
+        final int height = root.getHeight();
+        if (mRenderedSize.x == width && mRenderedSize.y == height) {
+            if (DEBUG) Log.d(TAG, String.format("Already rendered at size=%sx%s", width, height));
+            return;
+        }
+        if (width == 0 || height == 0) {
+            return;
+        }
+
+        mPreview.width = width;
+        mPreview.height = height;
+        mPreview.requestLayout();
+
+        final int thisWidth = getWidth() - getPaddingLeft() - getPaddingRight();
+        final int thisHeight = getHeight() - getPaddingTop() - getPaddingBottom();
+
+        final float pvScaleX = (float) thisWidth / width;
+        final float pvScaleY = (float) thisHeight / height;
+        final float pvScale = Math.min(pvScaleX, pvScaleY);
+
+        final int pvWidth = (int) (pvScale * width);
+        final int pvHeight = (int) (pvScale * height);
+
+        final float pvTransX = pvWidth < thisWidth ? (thisWidth - pvWidth) / 2 : 0;
+        final float pvTransY = pvHeight < thisHeight ? (thisHeight - pvHeight) / 2 : 0;
+
+        mPreview.setPivotX(0);
+        mPreview.setPivotY(0);
+        mPreview.setScaleX(pvScale);
+        mPreview.setScaleY(pvScale);
+        mPreview.setTranslationX(pvTransX);
+        mPreview.setTranslationY(pvTransY);
+
+        mRenderedSize.set(width, height);
+        if (DEBUG) Log.d(TAG, String.format("Rendered camera widget size=%sx%s instance=%s",
+                width, height, instanceId()));
+    }
+
+    private void transitionToCamera() {
+        if (mTransitioning || mDown) return;
+
+        mTransitioning = true;
+
+        enableWindowExitAnimation(false);
+
+        mPreview.getLocationInWindow(mTmpLoc);
+        final float pvHeight = mPreview.getHeight() * mPreview.getScaleY();
+        final float pvCenter = mTmpLoc[1] + pvHeight / 2f;
+
+        final ViewGroup root = (ViewGroup) getRootView();
+        if (mFullscreenPreview == null) {
+            mFullscreenPreview = getPreviewWidget(mContext, mWidgetInfo);
+            mFullscreenPreview.setClickable(false);
+            root.addView(mFullscreenPreview);
+        }
+
+        root.getWindowVisibleDisplayFrame(mTmpRect);
+        final float fsHeight = mTmpRect.height();
+        final float fsCenter = mTmpRect.top + fsHeight / 2;
+
+        final float fsScaleY = pvHeight / fsHeight;
+        final float fsTransY = pvCenter - fsCenter;
+        final float fsScaleX = mPreview.getScaleX();
+
+        mPreview.setVisibility(View.GONE);
+        mFullscreenPreview.setVisibility(View.VISIBLE);
+        mFullscreenPreview.setTranslationY(fsTransY);
+        mFullscreenPreview.setScaleX(fsScaleX);
+        mFullscreenPreview.setScaleY(fsScaleY);
+        mFullscreenPreview
+            .animate()
+            .scaleX(1)
+            .scaleY(1)
+            .translationX(0)
+            .translationY(0)
+            .setDuration(WIDGET_ANIMATION_DURATION)
+            .withEndAction(mPostTransitionToCameraEndAction)
+            .start();
+        mCallbacks.onLaunchingCamera();
+    }
+
+    private void recover() {
+        if (DEBUG) Log.d(TAG, "recovering at " + SystemClock.uptimeMillis());
+        mCallbacks.onCameraLaunchedUnsuccessfully();
+        reset();
+    }
+
+    @Override
+    public void setOnLongClickListener(OnLongClickListener l) {
+        // ignore
+    }
+
+    @Override
+    public void onClick(View v) {
+        if (DEBUG) Log.d(TAG, "clicked");
+        if (mTransitioning) return;
+        if (mActive) {
+            cancelTransitionToCamera();
+            transitionToCamera();
+        }
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        if (DEBUG) Log.d(TAG, "onDetachedFromWindow: instance " + instanceId()
+                + " at " + SystemClock.uptimeMillis());
+        super.onDetachedFromWindow();
+        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mCallback);
+        cancelTransitionToCamera();
+        mHandler.removeCallbacks(mRecoverRunnable);
+    }
+
+    @Override
+    public void onActive(boolean isActive) {
+        mActive = isActive;
+        if (mActive) {
+            rescheduleTransitionToCamera();
+        } else {
+            reset();
+        }
+    }
+
+    @Override
+    public boolean onUserInteraction(MotionEvent event) {
+        if (mTransitioning) {
+            if (DEBUG) Log.d(TAG, "onUserInteraction eaten: mTransitioning");
+            return true;
+        }
+
+        getLocationOnScreen(mTmpLoc);
+        int rawBottom = mTmpLoc[1] + getHeight();
+        if (event.getRawY() > rawBottom) {
+            if (DEBUG) Log.d(TAG, "onUserInteraction eaten: below widget");
+            return true;
+        }
+
+        int action = event.getAction();
+        mDown = action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE;
+        if (mActive) {
+            rescheduleTransitionToCamera();
+        }
+        if (DEBUG) Log.d(TAG, "onUserInteraction observed, not eaten");
+        return false;
+    }
+
+    @Override
+    protected void onFocusLost() {
+        if (DEBUG) Log.d(TAG, "onFocusLost at " + SystemClock.uptimeMillis());
+        cancelTransitionToCamera();
+        super.onFocusLost();
+    }
+
+    public void onScreenTurnedOff() {
+        if (DEBUG) Log.d(TAG, "onScreenTurnedOff");
+        reset();
+    }
+
+    private void rescheduleTransitionToCamera() {
+        if (DEBUG) Log.d(TAG, "rescheduleTransitionToCamera at " + SystemClock.uptimeMillis());
+        mHandler.removeCallbacks(mTransitionToCameraRunnable);
+        mHandler.postDelayed(mTransitionToCameraRunnable, WIDGET_WAIT_DURATION);
+    }
+
+    private void cancelTransitionToCamera() {
+        if (DEBUG) Log.d(TAG, "cancelTransitionToCamera at " + SystemClock.uptimeMillis());
+        mHandler.removeCallbacks(mTransitionToCameraRunnable);
+    }
+
+    private void onCameraLaunched() {
+        mCallbacks.onCameraLaunchedSuccessfully();
+        reset();
+    }
+
+    private void reset() {
+        if (DEBUG) Log.d(TAG, "reset at " + SystemClock.uptimeMillis());
+        mLaunchCameraStart = 0;
+        mTransitioning = false;
+        mDown = false;
+        cancelTransitionToCamera();
+        mHandler.removeCallbacks(mRecoverRunnable);
+        mPreview.setVisibility(View.VISIBLE);
+        if (mFullscreenPreview != null) {
+            mFullscreenPreview.animate().cancel();
+            mFullscreenPreview.setVisibility(View.GONE);
+        }
+        enableWindowExitAnimation(true);
+    }
+
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        if (DEBUG) Log.d(TAG, String.format("onSizeChanged new=%sx%s old=%sx%s at %s",
+                w, h, oldw, oldh, SystemClock.uptimeMillis()));
+        mHandler.post(mRenderRunnable);
+        super.onSizeChanged(w, h, oldw, oldh);
+    }
+
+    @Override
+    public void onBouncerShowing(boolean showing) {
+        if (showing) {
+            mTransitioning = false;
+            mHandler.post(mRecoverRunnable);
+        }
+    }
+
+    private void enableWindowExitAnimation(boolean isEnabled) {
+        View root = getRootView();
+        ViewGroup.LayoutParams lp = root.getLayoutParams();
+        if (!(lp instanceof WindowManager.LayoutParams))
+            return;
+        WindowManager.LayoutParams wlp = (WindowManager.LayoutParams) lp;
+        int newWindowAnimations = isEnabled ? R.style.Animation_LockScreen : 0;
+        if (newWindowAnimations != wlp.windowAnimations) {
+            if (DEBUG) Log.d(TAG, "setting windowAnimations to: " + newWindowAnimations
+                    + " at " + SystemClock.uptimeMillis());
+            wlp.windowAnimations = newWindowAnimations;
+            mWindowManager.updateViewLayout(root, wlp);
+        }
+    }
+
+    private void onKeyguardVisibilityChanged(boolean showing) {
+        if (DEBUG) Log.d(TAG, "onKeyguardVisibilityChanged " + showing
+                + " at " + SystemClock.uptimeMillis());
+        if (mTransitioning && !showing) {
+            mTransitioning = false;
+            mHandler.removeCallbacks(mRecoverRunnable);
+            if (mLaunchCameraStart > 0) {
+                long launchTime = SystemClock.uptimeMillis() - mLaunchCameraStart;
+                if (DEBUG) Log.d(TAG, String.format("Camera took %sms to launch", launchTime));
+                mLaunchCameraStart = 0;
+                onCameraLaunched();
+            }
+        }
+    }
+
+    private void onSecureCameraActivityStarted() {
+        if (DEBUG) Log.d(TAG, "onSecureCameraActivityStarted at " + SystemClock.uptimeMillis());
+        mHandler.postDelayed(mRecoverRunnable, RECOVERY_DELAY);
+    }
+
+    private String instanceId() {
+        return Integer.toHexString(hashCode());
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/CarrierText.java b/packages/Keyguard/src/com/android/keyguard/CarrierText.java
new file mode 100644
index 0000000..9f0a042
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/CarrierText.java
@@ -0,0 +1,257 @@
+/*
+ * 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.keyguard;
+
+import android.content.Context;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.widget.TextView;
+
+import com.android.internal.telephony.IccCardConstants;
+import com.android.internal.telephony.IccCardConstants.State;
+import com.android.internal.widget.LockPatternUtils;
+
+public class CarrierText extends TextView {
+    private static CharSequence mSeparator;
+
+    private LockPatternUtils mLockPatternUtils;
+
+    private KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() {
+        private CharSequence mPlmn;
+        private CharSequence mSpn;
+        private State mSimState;
+
+        @Override
+        public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) {
+            mPlmn = plmn;
+            mSpn = spn;
+            updateCarrierText(mSimState, mPlmn, mSpn);
+        }
+
+        @Override
+        public void onSimStateChanged(IccCardConstants.State simState) {
+            mSimState = simState;
+            updateCarrierText(mSimState, mPlmn, mSpn);
+        }
+    };
+    /**
+     * The status of this lock screen. Primarily used for widgets on LockScreen.
+     */
+    private static enum StatusMode {
+        Normal, // Normal case (sim card present, it's not locked)
+        NetworkLocked, // SIM card is 'network locked'.
+        SimMissing, // SIM card is missing.
+        SimMissingLocked, // SIM card is missing, and device isn't provisioned; don't allow access
+        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.
+    }
+
+    public CarrierText(Context context) {
+        this(context, null);
+    }
+
+    public CarrierText(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        mLockPatternUtils = new LockPatternUtils(mContext);
+    }
+
+    protected void updateCarrierText(State simState, CharSequence plmn, CharSequence spn) {
+        CharSequence text = getCarrierTextForSimState(simState, plmn, spn);
+        if (KeyguardViewManager.USE_UPPER_CASE) {
+            setText(text != null ? text.toString().toUpperCase() : null);
+        } else {
+            setText(text);
+        }
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mSeparator = getResources().getString(R.string.kg_text_message_separator);
+        setSelected(true); // Allow marquee to work.
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mCallback);
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mCallback);
+    }
+
+    /**
+     * Top-level function for creating carrier text. Makes text based on simState, PLMN
+     * and SPN as well as device capabilities, such as being emergency call capable.
+     *
+     * @param simState
+     * @param plmn
+     * @param spn
+     * @return
+     */
+    private CharSequence getCarrierTextForSimState(IccCardConstants.State simState,
+            CharSequence plmn, CharSequence spn) {
+        CharSequence carrierText = null;
+        StatusMode status = getStatusForIccState(simState);
+        switch (status) {
+            case Normal:
+                carrierText = concatenate(plmn, spn);
+                break;
+
+            case SimNotReady:
+                carrierText = null; // nothing to display yet.
+                break;
+
+            case NetworkLocked:
+                carrierText = makeCarrierStringOnEmergencyCapable(
+                        mContext.getText(R.string.keyguard_network_locked_message), plmn);
+                break;
+
+            case SimMissing:
+                // Shows "No SIM card | Emergency calls only" on devices that are voice-capable.
+                // This depends on mPlmn containing the text "Emergency calls only" when the radio
+                // has some connectivity. Otherwise, it should be null or empty and just show
+                // "No SIM card"
+                carrierText =  makeCarrierStringOnEmergencyCapable(
+                        getContext().getText(R.string.keyguard_missing_sim_message_short),
+                        plmn);
+                break;
+
+            case SimPermDisabled:
+                carrierText = getContext().getText(
+                        R.string.keyguard_permanent_disabled_sim_message_short);
+                break;
+
+            case SimMissingLocked:
+                carrierText =  makeCarrierStringOnEmergencyCapable(
+                        getContext().getText(R.string.keyguard_missing_sim_message_short),
+                        plmn);
+                break;
+
+            case SimLocked:
+                carrierText = makeCarrierStringOnEmergencyCapable(
+                        getContext().getText(R.string.keyguard_sim_locked_message),
+                        plmn);
+                break;
+
+            case SimPukLocked:
+                carrierText = makeCarrierStringOnEmergencyCapable(
+                        getContext().getText(R.string.keyguard_sim_puk_locked_message),
+                        plmn);
+                break;
+        }
+
+        return carrierText;
+    }
+
+    /*
+     * Add emergencyCallMessage to carrier string only if phone supports emergency calls.
+     */
+    private CharSequence makeCarrierStringOnEmergencyCapable(
+            CharSequence simMessage, CharSequence emergencyCallMessage) {
+        if (mLockPatternUtils.isEmergencyCallCapable()) {
+            return concatenate(simMessage, emergencyCallMessage);
+        }
+        return simMessage;
+    }
+
+    /**
+     * Determine the current status of the lock screen given the SIM state and other stuff.
+     */
+    private StatusMode getStatusForIccState(IccCardConstants.State simState) {
+        // Since reading the SIM may take a while, we assume it is present until told otherwise.
+        if (simState == null) {
+            return StatusMode.Normal;
+        }
+
+        final boolean missingAndNotProvisioned =
+                !KeyguardUpdateMonitor.getInstance(mContext).isDeviceProvisioned()
+                && (simState == IccCardConstants.State.ABSENT ||
+                        simState == IccCardConstants.State.PERM_DISABLED);
+
+        // Assume we're NETWORK_LOCKED if not provisioned
+        simState = missingAndNotProvisioned ? IccCardConstants.State.NETWORK_LOCKED : simState;
+        switch (simState) {
+            case ABSENT:
+                return StatusMode.SimMissing;
+            case NETWORK_LOCKED:
+                return StatusMode.SimMissingLocked;
+            case NOT_READY:
+                return StatusMode.SimNotReady;
+            case PIN_REQUIRED:
+                return StatusMode.SimLocked;
+            case PUK_REQUIRED:
+                return StatusMode.SimPukLocked;
+            case READY:
+                return StatusMode.Normal;
+            case PERM_DISABLED:
+                return StatusMode.SimPermDisabled;
+            case UNKNOWN:
+                return StatusMode.SimMissing;
+        }
+        return StatusMode.SimMissing;
+    }
+
+    private static CharSequence concatenate(CharSequence plmn, CharSequence spn) {
+        final boolean plmnValid = !TextUtils.isEmpty(plmn);
+        final boolean spnValid = !TextUtils.isEmpty(spn);
+        if (plmnValid && spnValid) {
+            return new StringBuilder().append(plmn).append(mSeparator).append(spn).toString();
+        } else if (plmnValid) {
+            return plmn;
+        } else if (spnValid) {
+            return spn;
+        } else {
+            return "";
+        }
+    }
+
+    private CharSequence getCarrierHelpTextForSimState(IccCardConstants.State simState,
+            String plmn, String spn) {
+        int carrierHelpTextId = 0;
+        StatusMode status = getStatusForIccState(simState);
+        switch (status) {
+            case NetworkLocked:
+                carrierHelpTextId = R.string.keyguard_instructions_when_pattern_disabled;
+                break;
+
+            case SimMissing:
+                carrierHelpTextId = R.string.keyguard_missing_sim_instructions_long;
+                break;
+
+            case SimPermDisabled:
+                carrierHelpTextId = R.string.keyguard_permanent_disabled_sim_instructions;
+                break;
+
+            case SimMissingLocked:
+                carrierHelpTextId = R.string.keyguard_missing_sim_instructions;
+                break;
+
+            case Normal:
+            case SimLocked:
+            case SimPukLocked:
+                break;
+        }
+
+        return mContext.getText(carrierHelpTextId);
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/ChallengeLayout.java b/packages/Keyguard/src/com/android/keyguard/ChallengeLayout.java
new file mode 100644
index 0000000..677f1f1
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/ChallengeLayout.java
@@ -0,0 +1,97 @@
+/*
+ * 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.keyguard;
+
+/**
+ * Interface implemented by ViewGroup-derived layouts that implement
+ * special logic for presenting security challenges to the user.
+ */
+public interface ChallengeLayout {
+    /**
+     * @return true if the security challenge area of this layout is currently visible
+     */
+    boolean isChallengeShowing();
+
+    /**
+     * @return true if the challenge area significantly overlaps other content
+     */
+    boolean isChallengeOverlapping();
+
+    /**
+     * Show or hide the challenge layout.
+     *
+     * If you want to show the challenge layout in bouncer mode where applicable,
+     * use {@link #showBouncer()} instead.
+     *
+     * @param b true to show, false to hide
+     */
+    void showChallenge(boolean b);
+
+    /**
+     * Show the bouncer challenge. This may block access to other child views.
+     */
+    void showBouncer();
+
+    /**
+     * Hide the bouncer challenge if it is currently showing.
+     * This may restore previously blocked access to other child views.
+     */
+    void hideBouncer();
+
+    /**
+     * Returns true if the challenge is currently in bouncer mode,
+     * potentially blocking access to other child views.
+     */
+    boolean isBouncing();
+
+    /**
+     * Returns the duration of the bounce animation.
+     */
+    int getBouncerAnimationDuration();
+
+    /**
+     * Set a listener that will respond to changes in bouncer state.
+     *
+     * @param listener listener to register
+     */
+    void setOnBouncerStateChangedListener(OnBouncerStateChangedListener listener);
+
+    /**
+     * Listener interface that reports changes in bouncer state.
+     * The bouncer is
+     */
+    public interface OnBouncerStateChangedListener {
+        /**
+         * Called when the bouncer state changes.
+         * The bouncer is activated when the user must pass a security challenge
+         * to proceed with the requested action.
+         *
+         * <p>This differs from simply showing or hiding the security challenge
+         * as the bouncer will prevent interaction with other elements of the UI.
+         * If the user attempts to escape from the bouncer, it will be dismissed,
+         * this method will be called with false as the parameter, and the action
+         * should be canceled. If the security component reports a successful
+         * authentication and the containing code calls hideBouncer() as a result,
+         * this method will also be called with a false parameter. It is up to the
+         * caller of hideBouncer to be ready for this.</p>
+         *
+         * @param bouncerActive true if the bouncer is now active,
+         *                      false if the bouncer was dismissed.
+         */
+        public void onBouncerStateChanged(boolean bouncerActive);
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/CheckLongPressHelper.java b/packages/Keyguard/src/com/android/keyguard/CheckLongPressHelper.java
new file mode 100644
index 0000000..52e7cd5
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/CheckLongPressHelper.java
@@ -0,0 +1,82 @@
+/*
+ * 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.keyguard;
+
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+
+public class CheckLongPressHelper {
+    private View mView;
+    private boolean mHasPerformedLongPress;
+    private CheckForLongPress mPendingCheckForLongPress;
+    private float mDownX, mDownY;
+    private int mLongPressTimeout;
+    private int mScaledTouchSlop;
+
+    class CheckForLongPress implements Runnable {
+        public void run() {
+            if ((mView.getParent() != null) && mView.hasWindowFocus()
+                    && !mHasPerformedLongPress) {
+                if (mView.performLongClick()) {
+                    mView.setPressed(false);
+                    mHasPerformedLongPress = true;
+                }
+            }
+        }
+    }
+
+    public CheckLongPressHelper(View v) {
+        mScaledTouchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();
+        mLongPressTimeout = ViewConfiguration.getLongPressTimeout();
+        mView = v;
+    }
+
+    public void postCheckForLongPress(MotionEvent ev) {
+        mDownX = ev.getX();
+        mDownY = ev.getY();
+        mHasPerformedLongPress = false;
+
+        if (mPendingCheckForLongPress == null) {
+            mPendingCheckForLongPress = new CheckForLongPress();
+        }
+        mView.postDelayed(mPendingCheckForLongPress, mLongPressTimeout);
+    }
+
+    public void onMove(MotionEvent ev) {
+        float x = ev.getX();
+        float y = ev.getY();
+        boolean xMoved = Math.abs(mDownX - x) > mScaledTouchSlop;
+        boolean yMoved = Math.abs(mDownY - y) > mScaledTouchSlop;
+
+        if (xMoved || yMoved) {
+            cancelLongPress();
+        }
+    }
+
+    public void cancelLongPress() {
+        mHasPerformedLongPress = false;
+        if (mPendingCheckForLongPress != null) {
+            mView.removeCallbacks(mPendingCheckForLongPress);
+            mPendingCheckForLongPress = null;
+        }
+    }
+
+    public boolean hasPerformedLongPress() {
+        return mHasPerformedLongPress;
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/ClockView.java b/packages/Keyguard/src/com/android/keyguard/ClockView.java
new file mode 100644
index 0000000..ad85e9a
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/ClockView.java
@@ -0,0 +1,223 @@
+/*
+ * 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.keyguard;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.graphics.Typeface;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.text.format.DateFormat;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import java.lang.ref.WeakReference;
+import java.text.DateFormatSymbols;
+import java.util.Calendar;
+
+/**
+ * Displays the time
+ */
+public class ClockView extends RelativeLayout {
+    private static final String ANDROID_CLOCK_FONT_FILE = "/system/fonts/AndroidClock.ttf";
+    private final static String M12 = "h:mm";
+    private final static String M24 = "HH:mm";
+
+    private Calendar mCalendar;
+    private String mFormat;
+    private TextView mTimeView;
+    private AmPm mAmPm;
+    private ContentObserver mFormatChangeObserver;
+    private int mAttached = 0; // for debugging - tells us whether attach/detach is unbalanced
+
+    /* called by system on minute ticks */
+    private final Handler mHandler = new Handler();
+    private BroadcastReceiver mIntentReceiver;
+
+    private static class TimeChangedReceiver extends BroadcastReceiver {
+        private WeakReference<ClockView> mClock;
+        private Context mContext;
+
+        public TimeChangedReceiver(ClockView clock) {
+            mClock = new WeakReference<ClockView>(clock);
+            mContext = clock.getContext();
+        }
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            // Post a runnable to avoid blocking the broadcast.
+            final boolean timezoneChanged =
+                    intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED);
+            final ClockView clock = mClock.get();
+            if (clock != null) {
+                clock.mHandler.post(new Runnable() {
+                    public void run() {
+                        if (timezoneChanged) {
+                            clock.mCalendar = Calendar.getInstance();
+                        }
+                        clock.updateTime();
+                    }
+                });
+            } else {
+                try {
+                    mContext.unregisterReceiver(this);
+                } catch (RuntimeException e) {
+                    // Shouldn't happen
+                }
+            }
+        }
+    };
+
+    static class AmPm {
+        private TextView mAmPmTextView;
+        private String mAmString, mPmString;
+
+        AmPm(View parent, Typeface tf) {
+            // No longer used, uncomment if we decide to use AM/PM indicator again
+            // mAmPmTextView = (TextView) parent.findViewById(R.id.am_pm);
+            if (mAmPmTextView != null && tf != null) {
+                mAmPmTextView.setTypeface(tf);
+            }
+
+            String[] ampm = new DateFormatSymbols().getAmPmStrings();
+            mAmString = ampm[0];
+            mPmString = ampm[1];
+        }
+
+        void setShowAmPm(boolean show) {
+            if (mAmPmTextView != null) {
+                mAmPmTextView.setVisibility(show ? View.VISIBLE : View.GONE);
+            }
+        }
+
+        void setIsMorning(boolean isMorning) {
+            if (mAmPmTextView != null) {
+                mAmPmTextView.setText(isMorning ? mAmString : mPmString);
+            }
+        }
+    }
+
+    private static class FormatChangeObserver extends ContentObserver {
+        private WeakReference<ClockView> mClock;
+        private Context mContext;
+        public FormatChangeObserver(ClockView clock) {
+            super(new Handler());
+            mClock = new WeakReference<ClockView>(clock);
+            mContext = clock.getContext();
+        }
+        @Override
+        public void onChange(boolean selfChange) {
+            ClockView digitalClock = mClock.get();
+            if (digitalClock != null) {
+                digitalClock.setDateFormat();
+                digitalClock.updateTime();
+            } else {
+                try {
+                    mContext.getContentResolver().unregisterContentObserver(this);
+                } catch (RuntimeException e) {
+                    // Shouldn't happen
+                }
+            }
+        }
+    }
+
+    public ClockView(Context context) {
+        this(context, null);
+    }
+
+    public ClockView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mTimeView = (TextView) findViewById(R.id.clock_text);
+        mTimeView.setTypeface(Typeface.createFromFile(ANDROID_CLOCK_FONT_FILE));
+        mAmPm = new AmPm(this, null);
+        mCalendar = Calendar.getInstance();
+        setDateFormat();
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+
+        mAttached++;
+
+        /* monitor time ticks, time changed, timezone */
+        if (mIntentReceiver == null) {
+            mIntentReceiver = new TimeChangedReceiver(this);
+            IntentFilter filter = new IntentFilter();
+            filter.addAction(Intent.ACTION_TIME_TICK);
+            filter.addAction(Intent.ACTION_TIME_CHANGED);
+            filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
+            mContext.registerReceiverAsUser(mIntentReceiver, UserHandle.OWNER, filter, null, null );
+        }
+
+        /* monitor 12/24-hour display preference */
+        if (mFormatChangeObserver == null) {
+            mFormatChangeObserver = new FormatChangeObserver(this);
+            mContext.getContentResolver().registerContentObserver(
+                    Settings.System.CONTENT_URI, true, mFormatChangeObserver);
+        }
+
+        updateTime();
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+
+        mAttached--;
+
+        if (mIntentReceiver != null) {
+            mContext.unregisterReceiver(mIntentReceiver);
+        }
+        if (mFormatChangeObserver != null) {
+            mContext.getContentResolver().unregisterContentObserver(
+                    mFormatChangeObserver);
+        }
+
+        mFormatChangeObserver = null;
+        mIntentReceiver = null;
+    }
+
+    void updateTime(Calendar c) {
+        mCalendar = c;
+        updateTime();
+    }
+
+    public void updateTime() {
+        mCalendar.setTimeInMillis(System.currentTimeMillis());
+
+        CharSequence newTime = DateFormat.format(mFormat, mCalendar);
+        mTimeView.setText(newTime);
+        mAmPm.setIsMorning(mCalendar.get(Calendar.AM_PM) == 0);
+    }
+
+    private void setDateFormat() {
+        mFormat = android.text.format.DateFormat.is24HourFormat(getContext()) ? M24 : M12;
+        mAmPm.setShowAmPm(mFormat.equals(M12));
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java b/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java
new file mode 100644
index 0000000..6badaaf
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java
@@ -0,0 +1,132 @@
+/*
+ * 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.keyguard;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.PowerManager;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.telephony.TelephonyManager;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.Button;
+
+import com.android.internal.telephony.IccCardConstants.State;
+import com.android.internal.widget.LockPatternUtils;
+
+/**
+ * This class implements a smart emergency button that updates itself based
+ * on telephony state.  When the phone is idle, it is an emergency call button.
+ * When there's a call in progress, it presents an appropriate message and
+ * allows the user to return to the call.
+ */
+public class EmergencyButton extends Button {
+
+    private static final int EMERGENCY_CALL_TIMEOUT = 10000; // screen timeout after starting e.d.
+    private static final String ACTION_EMERGENCY_DIAL = "com.android.phone.EmergencyDialer.DIAL";
+
+    KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
+
+        @Override
+        public void onSimStateChanged(State simState) {
+            int phoneState = KeyguardUpdateMonitor.getInstance(mContext).getPhoneState();
+            updateEmergencyCallButton(simState, phoneState);
+        }
+
+        void onPhoneStateChanged(int phoneState) {
+            State simState = KeyguardUpdateMonitor.getInstance(mContext).getSimState();
+            updateEmergencyCallButton(simState, phoneState);
+        };
+    };
+    private LockPatternUtils mLockPatternUtils;
+    private PowerManager mPowerManager;
+
+    public EmergencyButton(Context context) {
+        this(context, null);
+    }
+
+    public EmergencyButton(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mInfoCallback);
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mInfoCallback);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mLockPatternUtils = new LockPatternUtils(mContext);
+        mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+        setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                takeEmergencyCallAction();
+            }
+        });
+        int phoneState = KeyguardUpdateMonitor.getInstance(mContext).getPhoneState();
+        State simState = KeyguardUpdateMonitor.getInstance(mContext).getSimState();
+        updateEmergencyCallButton(simState, phoneState);
+    }
+
+    /**
+     * Shows the emergency dialer or returns the user to the existing call.
+     */
+    public void takeEmergencyCallAction() {
+        // TODO: implement a shorter timeout once new PowerManager API is ready.
+        // should be the equivalent to the old userActivity(EMERGENCY_CALL_TIMEOUT)
+        mPowerManager.userActivity(SystemClock.uptimeMillis(), true);
+        if (TelephonyManager.getDefault().getCallState()
+                == TelephonyManager.CALL_STATE_OFFHOOK) {
+            mLockPatternUtils.resumeCall();
+        } else {
+            Intent intent = new Intent(ACTION_EMERGENCY_DIAL);
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+            getContext().startActivityAsUser(intent,
+                    new UserHandle(mLockPatternUtils.getCurrentUser()));
+        }
+    }
+
+    private void updateEmergencyCallButton(State simState, int phoneState) {
+        boolean enabled = false;
+        if (phoneState == TelephonyManager.CALL_STATE_OFFHOOK) {
+            enabled = true; // always show "return to call" if phone is off-hook
+        } else if (mLockPatternUtils.isEmergencyCallCapable()) {
+            boolean simLocked = KeyguardUpdateMonitor.getInstance(mContext).isSimLocked();
+            if (simLocked) {
+                // Some countries can't handle emergency calls while SIM is locked.
+                enabled = mLockPatternUtils.isEmergencyCallEnabledWhileSimLocked();
+            } else {
+                // True if we need to show a secure screen (pin/pattern/SIM pin/SIM puk);
+                // hides emergency button on "Slide" screen if device is not secure.
+                enabled = mLockPatternUtils.isSecure();
+            }
+        }
+        mLockPatternUtils.updateEmergencyCallButtonState(this, phoneState, enabled,
+                KeyguardViewManager.USE_UPPER_CASE, false);
+    }
+
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/EmergencyCarrierArea.java b/packages/Keyguard/src/com/android/keyguard/EmergencyCarrierArea.java
new file mode 100644
index 0000000..6d392fc
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/EmergencyCarrierArea.java
@@ -0,0 +1,62 @@
+/*
+ * 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.keyguard;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.LinearLayout;
+
+import com.android.keyguard.R;
+
+public class EmergencyCarrierArea extends LinearLayout {
+
+    private CarrierText mCarrierText;
+    private EmergencyButton mEmergencyButton;
+
+    public EmergencyCarrierArea(Context context) {
+        super(context);
+    }
+
+    public EmergencyCarrierArea(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mCarrierText = (CarrierText) findViewById(R.id.carrier_text);
+        mEmergencyButton = (EmergencyButton) findViewById(R.id.emergency_call_button);
+
+        // The emergency button overlaps the carrier text, only noticeable when highlighted.
+        // So temporarily hide the carrier text while the emergency button is pressed.
+        mEmergencyButton.setOnTouchListener(new OnTouchListener(){
+            @Override
+            public boolean onTouch(View v, MotionEvent event) {
+                switch(event.getAction()) {
+                    case MotionEvent.ACTION_DOWN:
+                        mCarrierText.animate().alpha(0);
+                        break;
+                    case MotionEvent.ACTION_UP:
+                        mCarrierText.animate().alpha(1);
+                        break;
+                }
+                return false;
+            }});
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/FaceUnlock.java b/packages/Keyguard/src/com/android/keyguard/FaceUnlock.java
new file mode 100644
index 0000000..689366b
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/FaceUnlock.java
@@ -0,0 +1,462 @@
+/*
+ * 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.keyguard;
+
+import com.android.internal.policy.IFaceLockCallback;
+import com.android.internal.policy.IFaceLockInterface;
+import com.android.internal.widget.LockPatternUtils;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Log;
+import android.view.View;
+
+public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback {
+
+    private static final boolean DEBUG = false;
+    private static final String TAG = "FULLockscreen";
+
+    private final Context mContext;
+    private final LockPatternUtils mLockPatternUtils;
+
+    // TODO: is mServiceRunning needed or can we just use mIsRunning or check if mService is null?
+    private boolean mServiceRunning = false;
+    // TODO: now that the code has been restructure to do almost all operations from a handler, this
+    // lock may no longer be necessary.
+    private final Object mServiceRunningLock = new Object();
+    private IFaceLockInterface mService;
+    private boolean mBoundToService = false;
+    private View mFaceUnlockView;
+
+    private Handler mHandler;
+    private final int MSG_SERVICE_CONNECTED = 0;
+    private final int MSG_SERVICE_DISCONNECTED = 1;
+    private final int MSG_UNLOCK = 2;
+    private final int MSG_CANCEL = 3;
+    private final int MSG_REPORT_FAILED_ATTEMPT = 4;
+    private final int MSG_POKE_WAKELOCK = 5;
+
+    // TODO: This was added for the purpose of adhering to what the biometric interface expects
+    // the isRunning() function to return.  However, it is probably not necessary to have both
+    // mRunning and mServiceRunning.  I'd just rather wait to change that logic.
+    private volatile boolean mIsRunning = false;
+
+    // So the user has a consistent amount of time when brought to the backup method from Face
+    // Unlock
+    private final int BACKUP_LOCK_TIMEOUT = 5000;
+
+    KeyguardSecurityCallback mKeyguardScreenCallback;
+
+    /**
+     * Stores some of the structures that Face Unlock will need to access and creates the handler
+     * will be used to execute messages on the UI thread.
+     */
+    public FaceUnlock(Context context) {
+        mContext = context;
+        mLockPatternUtils = new LockPatternUtils(context);
+        mHandler = new Handler(this);
+    }
+
+    public void setKeyguardCallback(KeyguardSecurityCallback keyguardScreenCallback) {
+        mKeyguardScreenCallback = keyguardScreenCallback;
+    }
+
+    /**
+     * Stores and displays the view that Face Unlock is allowed to draw within.
+     * TODO: since the layout object will eventually be shared by multiple biometric unlock
+     * methods, we will have to add our other views (background, cancel button) here.
+     */
+    public void initializeView(View biometricUnlockView) {
+        Log.d(TAG, "initializeView()");
+        mFaceUnlockView = biometricUnlockView;
+    }
+
+    /**
+     * Indicates whether Face Unlock is currently running.
+     */
+    public boolean isRunning() {
+        return mIsRunning;
+    }
+
+    /**
+     * Dismisses face unlock and goes to the backup lock
+     */
+    public void stopAndShowBackup() {
+        if (DEBUG) Log.d(TAG, "stopAndShowBackup()");
+        mHandler.sendEmptyMessage(MSG_CANCEL);
+    }
+
+    /**
+     * Binds to the Face Unlock service.  Face Unlock will be started when the bind completes.  The
+     * Face Unlock view is displayed to hide the backup lock while the service is starting up.
+     * Called on the UI thread.
+     */
+    public boolean start() {
+        if (DEBUG) Log.d(TAG, "start()");
+        if (mHandler.getLooper() != Looper.myLooper()) {
+            Log.e(TAG, "start() called off of the UI thread");
+        }
+
+        if (mIsRunning) {
+            Log.w(TAG, "start() called when already running");
+        }
+
+        if (!mBoundToService) {
+            Log.d(TAG, "Binding to Face Unlock service for user="
+                    + mLockPatternUtils.getCurrentUser());
+            mContext.bindServiceAsUser(new Intent(IFaceLockInterface.class.getName()),
+                    mConnection,
+                    Context.BIND_AUTO_CREATE,
+                    new UserHandle(mLockPatternUtils.getCurrentUser()));
+            mBoundToService = true;
+        } else {
+            Log.w(TAG, "Attempt to bind to Face Unlock when already bound");
+        }
+
+        mIsRunning = true;
+        return true;
+    }
+
+    /**
+     * Stops Face Unlock and unbinds from the service.  Called on the UI thread.
+     */
+    public boolean stop() {
+        if (DEBUG) Log.d(TAG, "stop()");
+        if (mHandler.getLooper() != Looper.myLooper()) {
+            Log.e(TAG, "stop() called from non-UI thread");
+        }
+
+        // Clearing any old service connected messages.
+        mHandler.removeMessages(MSG_SERVICE_CONNECTED);
+
+        boolean mWasRunning = mIsRunning;
+
+        stopUi();
+
+        if (mBoundToService) {
+            if (mService != null) {
+                try {
+                    mService.unregisterCallback(mFaceUnlockCallback);
+                } catch (RemoteException e) {
+                    // Not much we can do
+                }
+            }
+            Log.d(TAG, "Unbinding from Face Unlock service");
+            mContext.unbindService(mConnection);
+            mBoundToService = false;
+        } else {
+            // This is usually not an error when this happens.  Sometimes we will tell it to
+            // unbind multiple times because it's called from both onWindowFocusChanged and
+            // onDetachedFromWindow.
+            if (DEBUG) Log.d(TAG, "Attempt to unbind from Face Unlock when not bound");
+        }
+        mIsRunning = false;
+        return mWasRunning;
+    }
+
+    /**
+     * Frees up resources used by Face Unlock and stops it if it is still running.
+     */
+    public void cleanUp() {
+        if (DEBUG) Log.d(TAG, "cleanUp()");
+        if (mService != null) {
+            try {
+                mService.unregisterCallback(mFaceUnlockCallback);
+            } catch (RemoteException e) {
+                // Not much we can do
+            }
+            stopUi();
+            mService = null;
+        }
+    }
+
+    /**
+     * Returns the Device Policy Manager quality for Face Unlock, which is BIOMETRIC_WEAK.
+     */
+    public int getQuality() {
+        return DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK;
+    }
+
+    /**
+     * Handles messages such that everything happens on the UI thread in a deterministic order.
+     * Calls from the Face Unlock service come from binder threads.  Calls from lockscreen typically
+     * come from the UI thread.  This makes sure there are no race conditions between those calls.
+     */
+    public boolean handleMessage(Message msg) {
+        switch (msg.what) {
+            case MSG_SERVICE_CONNECTED:
+                handleServiceConnected();
+                break;
+            case MSG_SERVICE_DISCONNECTED:
+                handleServiceDisconnected();
+                break;
+            case MSG_UNLOCK:
+                handleUnlock(msg.arg1);
+                break;
+            case MSG_CANCEL:
+                handleCancel();
+                break;
+            case MSG_REPORT_FAILED_ATTEMPT:
+                handleReportFailedAttempt();
+                break;
+            case MSG_POKE_WAKELOCK:
+                handlePokeWakelock(msg.arg1);
+                break;
+            default:
+                Log.e(TAG, "Unhandled message");
+                return false;
+        }
+        return true;
+    }
+
+    /**
+     * Tells the service to start its UI via an AIDL interface.  Called when the
+     * onServiceConnected() callback is received.
+     */
+    void handleServiceConnected() {
+        Log.d(TAG, "handleServiceConnected()");
+
+        // It is possible that an unbind has occurred in the time between the bind and when this
+        // function is reached.  If an unbind has already occurred, proceeding on to call startUi()
+        // can result in a fatal error.  Note that the onServiceConnected() callback is
+        // asynchronous, so this possibility would still exist if we executed this directly in
+        // onServiceConnected() rather than using a handler.
+        if (!mBoundToService) {
+            Log.d(TAG, "Dropping startUi() in handleServiceConnected() because no longer bound");
+            return;
+        }
+
+        try {
+            mService.registerCallback(mFaceUnlockCallback);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Caught exception connecting to Face Unlock: " + e.toString());
+            mService = null;
+            mBoundToService = false;
+            mIsRunning = false;
+            return;
+        }
+
+        if (mFaceUnlockView != null) {
+            IBinder windowToken = mFaceUnlockView.getWindowToken();
+            if (windowToken != null) {
+                // When switching between portrait and landscape view while Face Unlock is running,
+                // the screen will eventually go dark unless we poke the wakelock when Face Unlock
+                // is restarted.
+                mKeyguardScreenCallback.userActivity(0);
+
+                int[] position;
+                position = new int[2];
+                mFaceUnlockView.getLocationInWindow(position);
+                startUi(windowToken, position[0], position[1], mFaceUnlockView.getWidth(),
+                        mFaceUnlockView.getHeight());
+            } else {
+                Log.e(TAG, "windowToken is null in handleServiceConnected()");
+            }
+        }
+    }
+
+    /**
+     * Called when the onServiceDisconnected() callback is received.  This should not happen during
+     * normal operation.  It indicates an error has occurred.
+     */
+    void handleServiceDisconnected() {
+        Log.e(TAG, "handleServiceDisconnected()");
+        // TODO: this lock may no longer be needed now that everything is being called from a
+        // handler
+        synchronized (mServiceRunningLock) {
+            mService = null;
+            mServiceRunning = false;
+        }
+        mBoundToService = false;
+        mIsRunning = false;
+    }
+
+    /**
+     * Stops the Face Unlock service and tells the device to grant access to the user.
+     */
+    void handleUnlock(int authenticatedUserId) {
+        if (DEBUG) Log.d(TAG, "handleUnlock()");
+        stop();
+        int currentUserId = mLockPatternUtils.getCurrentUser();
+        if (authenticatedUserId == currentUserId) {
+            if (DEBUG) Log.d(TAG, "Unlocking for user " + authenticatedUserId);
+            mKeyguardScreenCallback.reportSuccessfulUnlockAttempt();
+            mKeyguardScreenCallback.dismiss(true);
+        } else {
+            Log.d(TAG, "Ignoring unlock for authenticated user (" + authenticatedUserId +
+                    ") because the current user is " + currentUserId);
+        }
+    }
+
+    /**
+     * Stops the Face Unlock service and goes to the backup lock.
+     */
+    void handleCancel() {
+        if (DEBUG) Log.d(TAG, "handleCancel()");
+        // We are going to the backup method, so we don't want to see Face Unlock again until the
+        // next time the user visits keyguard.
+        KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(false);
+
+        mKeyguardScreenCallback.showBackupSecurity();
+        stop();
+        mKeyguardScreenCallback.userActivity(BACKUP_LOCK_TIMEOUT);
+    }
+
+    /**
+     * Increments the number of failed Face Unlock attempts.
+     */
+    void handleReportFailedAttempt() {
+        if (DEBUG) Log.d(TAG, "handleReportFailedAttempt()");
+        // We are going to the backup method, so we don't want to see Face Unlock again until the
+        // next time the user visits keyguard.
+        KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(false);
+
+        mKeyguardScreenCallback.reportFailedUnlockAttempt();
+    }
+
+    /**
+     * If the screen is on, pokes the wakelock to keep the screen alive and active for a specific
+     * amount of time.
+     */
+    void handlePokeWakelock(int millis) {
+      PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+      if (powerManager.isScreenOn()) {
+        mKeyguardScreenCallback.userActivity(millis);
+      }
+    }
+
+    /**
+     * Implements service connection methods.
+     */
+    private ServiceConnection mConnection = new ServiceConnection() {
+        /**
+         * Called when the Face Unlock service connects after calling bind().
+         */
+        public void onServiceConnected(ComponentName className, IBinder iservice) {
+            Log.d(TAG, "Connected to Face Unlock service");
+            mService = IFaceLockInterface.Stub.asInterface(iservice);
+            mHandler.sendEmptyMessage(MSG_SERVICE_CONNECTED);
+        }
+
+        /**
+         * Called if the Face Unlock service unexpectedly disconnects.  This indicates an error.
+         */
+        public void onServiceDisconnected(ComponentName className) {
+            Log.e(TAG, "Unexpected disconnect from Face Unlock service");
+            mHandler.sendEmptyMessage(MSG_SERVICE_DISCONNECTED);
+        }
+    };
+
+    /**
+     * Tells the Face Unlock service to start displaying its UI and start processing.
+     */
+    private void startUi(IBinder windowToken, int x, int y, int w, int h) {
+        if (DEBUG) Log.d(TAG, "startUi()");
+        synchronized (mServiceRunningLock) {
+            if (!mServiceRunning) {
+                Log.d(TAG, "Starting Face Unlock");
+                try {
+                    mService.startUi(windowToken, x, y, w, h,
+                            mLockPatternUtils.isBiometricWeakLivelinessEnabled());
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Caught exception starting Face Unlock: " + e.toString());
+                    return;
+                }
+                mServiceRunning = true;
+            } else {
+                Log.w(TAG, "startUi() attempted while running");
+            }
+        }
+    }
+
+    /**
+     * Tells the Face Unlock service to stop displaying its UI and stop processing.
+     */
+    private void stopUi() {
+        if (DEBUG) Log.d(TAG, "stopUi()");
+        // Note that attempting to stop Face Unlock when it's not running is not an issue.
+        // Face Unlock can return, which stops it and then we try to stop it when the
+        // screen is turned off.  That's why we check.
+        synchronized (mServiceRunningLock) {
+            if (mServiceRunning) {
+                Log.d(TAG, "Stopping Face Unlock");
+                try {
+                    mService.stopUi();
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Caught exception stopping Face Unlock: " + e.toString());
+                }
+                mServiceRunning = false;
+            } else {
+                // This is usually not an error when this happens.  Sometimes we will tell it to
+                // stop multiple times because it's called from both onWindowFocusChanged and
+                // onDetachedFromWindow.
+                if (DEBUG) Log.d(TAG, "stopUi() attempted while not running");
+            }
+        }
+    }
+
+    /**
+     * Implements the AIDL biometric unlock service callback interface.
+     */
+    private final IFaceLockCallback mFaceUnlockCallback = new IFaceLockCallback.Stub() {
+        /**
+         * Called when Face Unlock wants to grant access to the user.
+         */
+        public void unlock() {
+            if (DEBUG) Log.d(TAG, "unlock()");
+            Message message = mHandler.obtainMessage(MSG_UNLOCK, UserHandle.getCallingUserId(), -1);
+            mHandler.sendMessage(message);
+        }
+
+        /**
+         * Called when Face Unlock wants to go to the backup.
+         */
+        public void cancel() {
+            if (DEBUG) Log.d(TAG, "cancel()");
+            mHandler.sendEmptyMessage(MSG_CANCEL);
+        }
+
+        /**
+         * Called when Face Unlock wants to increment the number of failed attempts.
+         */
+        public void reportFailedAttempt() {
+            if (DEBUG) Log.d(TAG, "reportFailedAttempt()");
+            mHandler.sendEmptyMessage(MSG_REPORT_FAILED_ATTEMPT);
+        }
+
+        /**
+         * Called when Face Unlock wants to keep the screen alive and active for a specific amount
+         * of time.
+         */
+        public void pokeWakelock(int millis) {
+            if (DEBUG) Log.d(TAG, "pokeWakelock() for " + millis + "ms");
+            Message message = mHandler.obtainMessage(MSG_POKE_WAKELOCK, millis, -1);
+            mHandler.sendMessage(message);
+        }
+
+    };
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
new file mode 100644
index 0000000..fb2eeda
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
@@ -0,0 +1,262 @@
+/*
+ * 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.keyguard;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.os.CountDownTimer;
+import android.os.SystemClock;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.util.AttributeSet;
+import android.view.HapticFeedbackConstants;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.inputmethod.EditorInfo;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.TextView.OnEditorActionListener;
+
+import com.android.internal.widget.LockPatternUtils;
+
+/**
+ * Base class for PIN and password unlock screens.
+ */
+public abstract class KeyguardAbsKeyInputView extends LinearLayout
+        implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
+    protected KeyguardSecurityCallback mCallback;
+    protected TextView mPasswordEntry;
+    protected LockPatternUtils mLockPatternUtils;
+    protected SecurityMessageDisplay mSecurityMessageDisplay;
+    protected View mEcaView;
+    private Drawable mBouncerFrame;
+    protected boolean mEnableHaptics;
+
+    // To avoid accidental lockout due to events while the device in in the pocket, ignore
+    // any passwords with length less than or equal to this length.
+    protected static final int MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT = 3;
+
+    public KeyguardAbsKeyInputView(Context context) {
+        this(context, null);
+    }
+
+    public KeyguardAbsKeyInputView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public void setKeyguardCallback(KeyguardSecurityCallback callback) {
+        mCallback = callback;
+    }
+
+    public void setLockPatternUtils(LockPatternUtils utils) {
+        mLockPatternUtils = utils;
+        mEnableHaptics = mLockPatternUtils.isTactileFeedbackEnabled();
+    }
+
+    @Override
+    public void onWindowFocusChanged(boolean hasWindowFocus) {
+        if (hasWindowFocus) {
+            reset();
+        }
+    }
+
+    public void reset() {
+        // start fresh
+        mPasswordEntry.setText("");
+        mPasswordEntry.requestFocus();
+
+        // if the user is currently locked out, enforce it.
+        long deadline = mLockPatternUtils.getLockoutAttemptDeadline();
+        if (deadline != 0) {
+            handleAttemptLockout(deadline);
+        } else {
+            resetState();
+        }
+    }
+
+    protected abstract int getPasswordTextViewId();
+    protected abstract void resetState();
+
+    @Override
+    protected void onFinishInflate() {
+        mLockPatternUtils = new LockPatternUtils(mContext);
+
+        mPasswordEntry = (TextView) findViewById(getPasswordTextViewId());
+        mPasswordEntry.setOnEditorActionListener(this);
+        mPasswordEntry.addTextChangedListener(this);
+
+        // Set selected property on so the view can send accessibility events.
+        mPasswordEntry.setSelected(true);
+
+        // Poke the wakelock any time the text is selected or modified
+        mPasswordEntry.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                mCallback.userActivity(0); // TODO: customize timeout for text?
+            }
+        });
+
+        mPasswordEntry.addTextChangedListener(new TextWatcher() {
+            public void onTextChanged(CharSequence s, int start, int before, int count) {
+            }
+
+            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+            }
+
+            public void afterTextChanged(Editable s) {
+                if (mCallback != null) {
+                    mCallback.userActivity(0);
+                }
+            }
+        });
+        mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
+        mEcaView = findViewById(R.id.keyguard_selector_fade_container);
+        View bouncerFrameView = findViewById(R.id.keyguard_bouncer_frame);
+        if (bouncerFrameView != null) {
+            mBouncerFrame = bouncerFrameView.getBackground();
+        }
+    }
+
+    @Override
+    protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
+        // send focus to the password field
+        return mPasswordEntry.requestFocus(direction, previouslyFocusedRect);
+    }
+
+    /*
+     * Override this if you have a different string for "wrong password"
+     *
+     * Note that PIN/PUK have their own implementation of verifyPasswordAndUnlock and so don't need this
+     */
+    protected int getWrongPasswordStringId() {
+        return R.string.kg_wrong_password;
+    }
+
+    protected void verifyPasswordAndUnlock() {
+        String entry = mPasswordEntry.getText().toString();
+        if (mLockPatternUtils.checkPassword(entry)) {
+            mCallback.reportSuccessfulUnlockAttempt();
+            mCallback.dismiss(true);
+        } else if (entry.length() > MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT ) {
+            // to avoid accidental lockout, only count attempts that are long enough to be a
+            // real password. This may require some tweaking.
+            mCallback.reportFailedUnlockAttempt();
+            if (0 == (mCallback.getFailedAttempts()
+                    % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT)) {
+                long deadline = mLockPatternUtils.setLockoutAttemptDeadline();
+                handleAttemptLockout(deadline);
+            }
+            mSecurityMessageDisplay.setMessage(getWrongPasswordStringId(), true);
+        }
+        mPasswordEntry.setText("");
+    }
+
+    // Prevent user from using the PIN/Password entry until scheduled deadline.
+    protected void handleAttemptLockout(long elapsedRealtimeDeadline) {
+        mPasswordEntry.setEnabled(false);
+        long elapsedRealtime = SystemClock.elapsedRealtime();
+        new CountDownTimer(elapsedRealtimeDeadline - elapsedRealtime, 1000) {
+
+            @Override
+            public void onTick(long millisUntilFinished) {
+                int secondsRemaining = (int) (millisUntilFinished / 1000);
+                mSecurityMessageDisplay.setMessage(
+                        R.string.kg_too_many_failed_attempts_countdown, true, secondsRemaining);
+            }
+
+            @Override
+            public void onFinish() {
+                mSecurityMessageDisplay.setMessage("", false);
+                resetState();
+            }
+        }.start();
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        mCallback.userActivity(0);
+        return false;
+    }
+
+    @Override
+    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+        // Check if this was the result of hitting the enter key
+        if (actionId == EditorInfo.IME_NULL || actionId == EditorInfo.IME_ACTION_DONE
+                || actionId == EditorInfo.IME_ACTION_NEXT) {
+            verifyPasswordAndUnlock();
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean needsInput() {
+        return false;
+    }
+
+    @Override
+    public void onPause() {
+
+    }
+
+    @Override
+    public void onResume(int reason) {
+        reset();
+    }
+
+    @Override
+    public KeyguardSecurityCallback getCallback() {
+        return mCallback;
+    }
+
+    @Override
+    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+        if (mCallback != null) {
+            mCallback.userActivity(KeyguardViewManager.DIGIT_PRESS_WAKE_MILLIS);
+        }
+    }
+
+    @Override
+    public void onTextChanged(CharSequence s, int start, int before, int count) {
+    }
+
+    @Override
+    public void afterTextChanged(Editable s) {
+    }
+
+    // Cause a VIRTUAL_KEY vibration
+    public void doHapticKeyClick() {
+        if (mEnableHaptics) {
+            performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
+                    HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING
+                    | HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
+        }
+    }
+
+    @Override
+    public void showBouncer(int duration) {
+        KeyguardSecurityViewHelper.
+                showBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration);
+    }
+
+    @Override
+    public void hideBouncer(int duration) {
+        KeyguardSecurityViewHelper.
+                hideBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration);
+    }
+}
+
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardAccountView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardAccountView.java
new file mode 100644
index 0000000..6b8be69
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardAccountView.java
@@ -0,0 +1,332 @@
+/*
+ * 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.keyguard;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.AccountManagerCallback;
+import android.accounts.AccountManagerFuture;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
+import android.app.Dialog;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.text.Editable;
+import android.text.InputFilter;
+import android.text.LoginFilter;
+import android.text.TextWatcher;
+import android.util.AttributeSet;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+
+import com.android.internal.widget.LockPatternUtils;
+
+import java.io.IOException;
+
+/**
+ * When the user forgets their password a bunch of times, we fall back on their
+ * account's login/password to unlock the phone (and reset their lock pattern).
+ */
+public class KeyguardAccountView extends LinearLayout implements KeyguardSecurityView,
+        View.OnClickListener, TextWatcher {
+    private static final int AWAKE_POKE_MILLIS = 30000;
+    private static final String LOCK_PATTERN_PACKAGE = "com.android.settings";
+    private static final String LOCK_PATTERN_CLASS = LOCK_PATTERN_PACKAGE + ".ChooseLockGeneric";
+
+    private KeyguardSecurityCallback mCallback;
+    private LockPatternUtils mLockPatternUtils;
+    private EditText mLogin;
+    private EditText mPassword;
+    private Button mOk;
+    public boolean mEnableFallback;
+    private SecurityMessageDisplay mSecurityMessageDisplay;
+
+    /**
+     * Shown while making asynchronous check of password.
+     */
+    private ProgressDialog mCheckingDialog;
+
+    public KeyguardAccountView(Context context) {
+        this(context, null, 0);
+    }
+
+    public KeyguardAccountView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public KeyguardAccountView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        mLockPatternUtils = new LockPatternUtils(getContext());
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+
+        mLogin = (EditText) findViewById(R.id.login);
+        mLogin.setFilters(new InputFilter[] { new LoginFilter.UsernameFilterGeneric() } );
+        mLogin.addTextChangedListener(this);
+
+        mPassword = (EditText) findViewById(R.id.password);
+        mPassword.addTextChangedListener(this);
+
+        mOk = (Button) findViewById(R.id.ok);
+        mOk.setOnClickListener(this);
+
+        mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
+        reset();
+    }
+
+    public void setKeyguardCallback(KeyguardSecurityCallback callback) {
+        mCallback = callback;
+    }
+
+    public void setLockPatternUtils(LockPatternUtils utils) {
+        mLockPatternUtils = utils;
+    }
+
+    public KeyguardSecurityCallback getCallback() {
+        return mCallback;
+    }
+
+
+    public void afterTextChanged(Editable s) {
+    }
+
+    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+    }
+
+    public void onTextChanged(CharSequence s, int start, int before, int count) {
+        if (mCallback != null) {
+            mCallback.userActivity(AWAKE_POKE_MILLIS);
+        }
+    }
+
+    @Override
+    protected boolean onRequestFocusInDescendants(int direction,
+            Rect previouslyFocusedRect) {
+        // send focus to the login field
+        return mLogin.requestFocus(direction, previouslyFocusedRect);
+    }
+
+    public boolean needsInput() {
+        return true;
+    }
+
+    public void reset() {
+        // start fresh
+        mLogin.setText("");
+        mPassword.setText("");
+        mLogin.requestFocus();
+        boolean permLocked = mLockPatternUtils.isPermanentlyLocked();
+        mSecurityMessageDisplay.setMessage(permLocked ? R.string.kg_login_too_many_attempts :
+            R.string.kg_login_instructions, permLocked ? true : false);
+    }
+
+    /** {@inheritDoc} */
+    public void cleanUp() {
+        if (mCheckingDialog != null) {
+            mCheckingDialog.hide();
+        }
+        mCallback = null;
+        mLockPatternUtils = null;
+    }
+
+    public void onClick(View v) {
+        mCallback.userActivity(0);
+        if (v == mOk) {
+            asyncCheckPassword();
+        }
+    }
+
+    private void postOnCheckPasswordResult(final boolean success) {
+        // ensure this runs on UI thread
+        mLogin.post(new Runnable() {
+            public void run() {
+                if (success) {
+                    // clear out forgotten password
+                    mLockPatternUtils.setPermanentlyLocked(false);
+                    mLockPatternUtils.setLockPatternEnabled(false);
+                    mLockPatternUtils.saveLockPattern(null);
+
+                    // launch the 'choose lock pattern' activity so
+                    // the user can pick a new one if they want to
+                    Intent intent = new Intent();
+                    intent.setClassName(LOCK_PATTERN_PACKAGE, LOCK_PATTERN_CLASS);
+                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                    mContext.startActivityAsUser(intent,
+                            new UserHandle(mLockPatternUtils.getCurrentUser()));
+                    mCallback.reportSuccessfulUnlockAttempt();
+
+                    // dismiss keyguard
+                    mCallback.dismiss(true);
+                } else {
+                    mSecurityMessageDisplay.setMessage(R.string.kg_login_invalid_input, true);
+                    mPassword.setText("");
+                    mCallback.reportFailedUnlockAttempt();
+                }
+            }
+        });
+    }
+
+    @Override
+    public boolean dispatchKeyEvent(KeyEvent event) {
+        if (event.getAction() == KeyEvent.ACTION_DOWN
+                && event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
+            if (mLockPatternUtils.isPermanentlyLocked()) {
+                mCallback.dismiss(false);
+            } else {
+                // TODO: mCallback.forgotPattern(false);
+            }
+            return true;
+        }
+        return super.dispatchKeyEvent(event);
+    }
+
+    /**
+     * Given the string the user entered in the 'username' field, find
+     * the stored account that they probably intended.  Prefer, in order:
+     *
+     *   - an exact match for what was typed, or
+     *   - a case-insensitive match for what was typed, or
+     *   - if they didn't include a domain, an exact match of the username, or
+     *   - if they didn't include a domain, a case-insensitive
+     *     match of the username.
+     *
+     * If there is a tie for the best match, choose neither --
+     * the user needs to be more specific.
+     *
+     * @return an account name from the database, or null if we can't
+     * find a single best match.
+     */
+    private Account findIntendedAccount(String username) {
+        Account[] accounts = AccountManager.get(mContext).getAccountsByTypeAsUser("com.google",
+                new UserHandle(mLockPatternUtils.getCurrentUser()));
+
+        // Try to figure out which account they meant if they
+        // typed only the username (and not the domain), or got
+        // the case wrong.
+
+        Account bestAccount = null;
+        int bestScore = 0;
+        for (Account a: accounts) {
+            int score = 0;
+            if (username.equals(a.name)) {
+                score = 4;
+            } else if (username.equalsIgnoreCase(a.name)) {
+                score = 3;
+            } else if (username.indexOf('@') < 0) {
+                int i = a.name.indexOf('@');
+                if (i >= 0) {
+                    String aUsername = a.name.substring(0, i);
+                    if (username.equals(aUsername)) {
+                        score = 2;
+                    } else if (username.equalsIgnoreCase(aUsername)) {
+                        score = 1;
+                    }
+                }
+            }
+            if (score > bestScore) {
+                bestAccount = a;
+                bestScore = score;
+            } else if (score == bestScore) {
+                bestAccount = null;
+            }
+        }
+        return bestAccount;
+    }
+
+    private void asyncCheckPassword() {
+        mCallback.userActivity(AWAKE_POKE_MILLIS);
+        final String login = mLogin.getText().toString();
+        final String password = mPassword.getText().toString();
+        Account account = findIntendedAccount(login);
+        if (account == null) {
+            postOnCheckPasswordResult(false);
+            return;
+        }
+        getProgressDialog().show();
+        Bundle options = new Bundle();
+        options.putString(AccountManager.KEY_PASSWORD, password);
+        AccountManager.get(mContext).confirmCredentialsAsUser(account, options, null /* activity */,
+                new AccountManagerCallback<Bundle>() {
+            public void run(AccountManagerFuture<Bundle> future) {
+                try {
+                    mCallback.userActivity(AWAKE_POKE_MILLIS);
+                    final Bundle result = future.getResult();
+                    final boolean verified = result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT);
+                    postOnCheckPasswordResult(verified);
+                } catch (OperationCanceledException e) {
+                    postOnCheckPasswordResult(false);
+                } catch (IOException e) {
+                    postOnCheckPasswordResult(false);
+                } catch (AuthenticatorException e) {
+                    postOnCheckPasswordResult(false);
+                } finally {
+                    mLogin.post(new Runnable() {
+                        public void run() {
+                            getProgressDialog().hide();
+                        }
+                    });
+                }
+            }
+        }, null /* handler */, new UserHandle(mLockPatternUtils.getCurrentUser()));
+    }
+
+    private Dialog getProgressDialog() {
+        if (mCheckingDialog == null) {
+            mCheckingDialog = new ProgressDialog(mContext);
+            mCheckingDialog.setMessage(
+                    mContext.getString(R.string.kg_login_checking_password));
+            mCheckingDialog.setIndeterminate(true);
+            mCheckingDialog.setCancelable(false);
+            mCheckingDialog.getWindow().setType(
+                    WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
+        }
+        return mCheckingDialog;
+    }
+
+    @Override
+    public void onPause() {
+
+    }
+
+    @Override
+    public void onResume(int reason) {
+        reset();
+    }
+
+    @Override
+    public void showUsabilityHint() {
+    }
+
+    @Override
+    public void showBouncer(int duration) {
+    }
+
+    @Override
+    public void hideBouncer(int duration) {
+    }
+}
+
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardActivityLauncher.java b/packages/Keyguard/src/com/android/keyguard/KeyguardActivityLauncher.java
new file mode 100644
index 0000000..9a1aa5b
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardActivityLauncher.java
@@ -0,0 +1,274 @@
+/*
+ * 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.keyguard;
+
+import com.android.internal.widget.LockPatternUtils;
+
+import android.app.ActivityManagerNative;
+import android.app.ActivityOptions;
+import android.app.IActivityManager.WaitResult;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.provider.MediaStore;
+import android.util.Log;
+import android.view.WindowManager;
+
+import com.android.keyguard.KeyguardHostView.OnDismissAction;
+
+import java.util.List;
+
+public abstract class KeyguardActivityLauncher {
+    private static final String TAG = KeyguardActivityLauncher.class.getSimpleName();
+    private static final boolean DEBUG = KeyguardHostView.DEBUG;
+    private static final String META_DATA_KEYGUARD_LAYOUT = "com.android.keyguard.layout";
+    private static final Intent SECURE_CAMERA_INTENT =
+            new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE)
+                    .addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+    private static final Intent INSECURE_CAMERA_INTENT =
+            new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
+
+    abstract Context getContext();
+
+    abstract KeyguardSecurityCallback getCallback();
+
+    abstract LockPatternUtils getLockPatternUtils();
+
+    public static class CameraWidgetInfo {
+        public String contextPackage;
+        public int layoutId;
+    }
+
+    public CameraWidgetInfo getCameraWidgetInfo() {
+        CameraWidgetInfo info = new CameraWidgetInfo();
+        Intent intent = getCameraIntent();
+        PackageManager packageManager = getContext().getPackageManager();
+        final List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser(
+                intent, PackageManager.MATCH_DEFAULT_ONLY, getLockPatternUtils().getCurrentUser());
+        if (appList.size() == 0) {
+            if (DEBUG) Log.d(TAG, "getCameraWidgetInfo(): Nothing found");
+            return null;
+        }
+        ResolveInfo resolved = packageManager.resolveActivityAsUser(intent,
+                PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA,
+                getLockPatternUtils().getCurrentUser());
+        if (DEBUG) Log.d(TAG, "getCameraWidgetInfo(): resolved: " + resolved);
+        if (wouldLaunchResolverActivity(resolved, appList)) {
+            if (DEBUG) Log.d(TAG, "getCameraWidgetInfo(): Would launch resolver");
+            return info;
+        }
+        if (resolved == null || resolved.activityInfo == null) {
+            return null;
+        }
+        if (resolved.activityInfo.metaData == null || resolved.activityInfo.metaData.isEmpty()) {
+            if (DEBUG) Log.d(TAG, "getCameraWidgetInfo(): no metadata found");
+            return info;
+        }
+        int layoutId = resolved.activityInfo.metaData.getInt(META_DATA_KEYGUARD_LAYOUT);
+        if (layoutId == 0) {
+            if (DEBUG) Log.d(TAG, "getCameraWidgetInfo(): no layout specified");
+            return info;
+        }
+        info.contextPackage = resolved.activityInfo.packageName;
+        info.layoutId = layoutId;
+        return info;
+    }
+
+    public void launchCamera(Handler worker, Runnable onSecureCameraStarted) {
+        LockPatternUtils lockPatternUtils = getLockPatternUtils();
+        if (lockPatternUtils.isSecure()) {
+            // Launch the secure version of the camera
+            if (wouldLaunchResolverActivity(SECURE_CAMERA_INTENT)) {
+                // TODO: Show disambiguation dialog instead.
+                // For now, we'll treat this like launching any other app from secure keyguard.
+                // When they do, user sees the system's ResolverActivity which lets them choose
+                // which secure camera to use.
+                launchActivity(SECURE_CAMERA_INTENT, false, false, null, null);
+            } else {
+                launchActivity(SECURE_CAMERA_INTENT, true, false, worker, onSecureCameraStarted);
+            }
+        } else {
+            // Launch the normal camera
+            launchActivity(INSECURE_CAMERA_INTENT, false, false, null, null);
+        }
+    }
+
+    public void launchWidgetPicker(int appWidgetId) {
+        Intent pickIntent = new Intent(AppWidgetManager.ACTION_KEYGUARD_APPWIDGET_PICK);
+
+        pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
+        pickIntent.putExtra(AppWidgetManager.EXTRA_CUSTOM_SORT, false);
+        pickIntent.putExtra(AppWidgetManager.EXTRA_CATEGORY_FILTER,
+                AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD);
+
+        Bundle options = new Bundle();
+        options.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,
+                AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD);
+        pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);
+        pickIntent.addFlags(
+                Intent.FLAG_ACTIVITY_NEW_TASK
+                | Intent.FLAG_ACTIVITY_SINGLE_TOP
+                | Intent.FLAG_ACTIVITY_CLEAR_TOP
+                | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+
+        launchActivity(pickIntent, false, false, null, null);
+    }
+
+    /**
+     * Launches the said intent for the current foreground user.
+     *
+     * @param intent
+     * @param showsWhileLocked true if the activity can be run on top of keyguard.
+     *   See {@link WindowManager#FLAG_SHOW_WHEN_LOCKED}
+     * @param useDefaultAnimations true if default transitions should be used, else suppressed.
+     * @param worker if supplied along with onStarted, used to launch the blocking activity call.
+     * @param onStarted if supplied along with worker, called after activity is started.
+     */
+    public void launchActivity(final Intent intent,
+            boolean showsWhileLocked,
+            boolean useDefaultAnimations,
+            final Handler worker,
+            final Runnable onStarted) {
+
+        final Context context = getContext();
+        final Bundle animation = useDefaultAnimations ? null
+                : ActivityOptions.makeCustomAnimation(context, 0, 0).toBundle();
+        launchActivityWithAnimation(intent, showsWhileLocked, animation, worker, onStarted);
+    }
+
+    public void launchActivityWithAnimation(final Intent intent,
+            boolean showsWhileLocked,
+            final Bundle animation,
+            final Handler worker,
+            final Runnable onStarted) {
+
+        LockPatternUtils lockPatternUtils = getLockPatternUtils();
+        intent.addFlags(
+                Intent.FLAG_ACTIVITY_NEW_TASK
+                | Intent.FLAG_ACTIVITY_SINGLE_TOP
+                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+        boolean isSecure = lockPatternUtils.isSecure();
+        if (!isSecure || showsWhileLocked) {
+            if (!isSecure) {
+                dismissKeyguardOnNextActivity();
+            }
+            try {
+                if (DEBUG) Log.d(TAG, String.format("Starting activity for intent %s at %s",
+                        intent, SystemClock.uptimeMillis()));
+                startActivityForCurrentUser(intent, animation, worker, onStarted);
+            } catch (ActivityNotFoundException e) {
+                Log.w(TAG, "Activity not found for intent + " + intent.getAction());
+            }
+        } else {
+            // Create a runnable to start the activity and ask the user to enter their
+            // credentials.
+            KeyguardSecurityCallback callback = getCallback();
+            callback.setOnDismissAction(new OnDismissAction() {
+                @Override
+                public boolean onDismiss() {
+                    dismissKeyguardOnNextActivity();
+                    startActivityForCurrentUser(intent, animation, worker, onStarted);
+                    return true;
+                }
+            });
+            callback.dismiss(false);
+        }
+    }
+
+    private void dismissKeyguardOnNextActivity() {
+        try {
+            ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
+        } catch (RemoteException e) {
+            Log.w(TAG, "can't dismiss keyguard on launch");
+        }
+    }
+
+    private void startActivityForCurrentUser(final Intent intent, final Bundle options,
+            Handler worker, final Runnable onStarted) {
+        final UserHandle user = new UserHandle(UserHandle.USER_CURRENT);
+        if (worker == null || onStarted == null) {
+            getContext().startActivityAsUser(intent, options, user);
+            return;
+        }
+        // if worker + onStarted are supplied, run blocking activity launch call in the background
+        worker.post(new Runnable(){
+            @Override
+            public void run() {
+                try {
+                    WaitResult result = ActivityManagerNative.getDefault().startActivityAndWait(
+                            null /*caller*/,
+                            null /*caller pkg*/,
+                            intent,
+                            intent.resolveTypeIfNeeded(getContext().getContentResolver()),
+                            null /*resultTo*/,
+                            null /*resultWho*/,
+                            0 /*requestCode*/,
+                            Intent.FLAG_ACTIVITY_NEW_TASK,
+                            null /*profileFile*/,
+                            null /*profileFd*/,
+                            options,
+                            user.getIdentifier());
+                    if (DEBUG) Log.d(TAG, String.format("waitResult[%s,%s,%s,%s] at %s",
+                            result.result, result.thisTime, result.totalTime, result.who,
+                            SystemClock.uptimeMillis()));
+                } catch (RemoteException e) {
+                    Log.w(TAG, "Error starting activity", e);
+                    return;
+                }
+                try {
+                    onStarted.run();
+                } catch (Throwable t) {
+                    Log.w(TAG, "Error running onStarted callback", t);
+                }
+            }});
+    }
+
+    private Intent getCameraIntent() {
+        return getLockPatternUtils().isSecure() ? SECURE_CAMERA_INTENT : INSECURE_CAMERA_INTENT;
+    }
+
+    private boolean wouldLaunchResolverActivity(Intent intent) {
+        PackageManager packageManager = getContext().getPackageManager();
+        ResolveInfo resolved = packageManager.resolveActivityAsUser(intent,
+                PackageManager.MATCH_DEFAULT_ONLY, getLockPatternUtils().getCurrentUser());
+        List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser(
+                intent, PackageManager.MATCH_DEFAULT_ONLY, getLockPatternUtils().getCurrentUser());
+        return wouldLaunchResolverActivity(resolved, appList);
+    }
+
+    private boolean wouldLaunchResolverActivity(ResolveInfo resolved, List<ResolveInfo> appList) {
+        // If the list contains the above resolved activity, then it can't be
+        // ResolverActivity itself.
+        for (int i = 0; i < appList.size(); i++) {
+            ResolveInfo tmp = appList.get(i);
+            if (tmp.activityInfo.name.equals(resolved.activityInfo.name)
+                    && tmp.activityInfo.packageName.equals(resolved.activityInfo.packageName)) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardCircleFramedDrawable.java b/packages/Keyguard/src/com/android/keyguard/KeyguardCircleFramedDrawable.java
new file mode 100644
index 0000000..63b61ad
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardCircleFramedDrawable.java
@@ -0,0 +1,175 @@
+/*
+ * 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.keyguard;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PixelFormat;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.drawable.Drawable;
+
+import android.util.Log;
+
+class KeyguardCircleFramedDrawable extends Drawable {
+
+    private final Bitmap mBitmap;
+    private final int mSize;
+    private final Paint mPaint;
+    private final float mShadowRadius;
+    private final float mStrokeWidth;
+    private final int mFrameColor;
+    private final int mHighlightColor;
+    private final int mFrameShadowColor;
+
+    private float mScale;
+    private Path mFramePath;
+    private Rect mSrcRect;
+    private RectF mDstRect;
+    private RectF mFrameRect;
+    private boolean mPressed;
+
+    public KeyguardCircleFramedDrawable(Bitmap bitmap, int size,
+            int frameColor, float strokeWidth,
+            int frameShadowColor, float shadowRadius,
+            int highlightColor) {
+        super();
+        mSize = size;
+        mShadowRadius = shadowRadius;
+        mFrameColor = frameColor;
+        mFrameShadowColor = frameShadowColor;
+        mStrokeWidth = strokeWidth;
+        mHighlightColor = highlightColor;
+
+        mBitmap = Bitmap.createBitmap(mSize, mSize, Bitmap.Config.ARGB_8888);
+        final Canvas canvas = new Canvas(mBitmap);
+
+        final int width = bitmap.getWidth();
+        final int height = bitmap.getHeight();
+        final int square = Math.min(width, height);
+
+        final Rect cropRect = new Rect((width - square) / 2, (height - square) / 2, square, square);
+        final RectF circleRect = new RectF(0f, 0f, mSize, mSize);
+        circleRect.inset(mStrokeWidth / 2f, mStrokeWidth / 2f);
+        circleRect.inset(mShadowRadius, mShadowRadius);
+
+        final Path fillPath = new Path();
+        fillPath.addArc(circleRect, 0f, 360f);
+
+        canvas.drawColor(0, PorterDuff.Mode.CLEAR);
+
+        // opaque circle matte
+        mPaint = new Paint();
+        mPaint.setAntiAlias(true);
+        mPaint.setColor(Color.BLACK);
+        mPaint.setStyle(Paint.Style.FILL);
+        canvas.drawPath(fillPath, mPaint);
+
+        // mask in the icon where the bitmap is opaque
+        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
+        canvas.drawBitmap(bitmap, cropRect, circleRect, mPaint);
+
+        // prepare paint for frame drawing
+        mPaint.setXfermode(null);
+
+        mScale = 1f;
+
+        mSrcRect = new Rect(0, 0, mSize, mSize);
+        mDstRect = new RectF(0, 0, mSize, mSize);
+        mFrameRect = new RectF(mDstRect);
+        mFramePath = new Path();
+    }
+
+    public void reset() {
+        mScale = 1f;
+        mPressed = false;
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        // clear background
+        final float outside = Math.min(canvas.getWidth(), canvas.getHeight());
+        final float inside = mScale * outside;
+        final float pad = (outside - inside) / 2f;
+
+        mDstRect.set(pad, pad, outside - pad, outside - pad);
+        canvas.drawBitmap(mBitmap, mSrcRect, mDstRect, null);
+
+        mFrameRect.set(mDstRect);
+        mFrameRect.inset(mStrokeWidth / 2f, mStrokeWidth / 2f);
+        mFrameRect.inset(mShadowRadius, mShadowRadius);
+
+        mFramePath.reset();
+        mFramePath.addArc(mFrameRect, 0f, 360f);
+
+        // white frame
+        if (mPressed) {
+            mPaint.setStyle(Paint.Style.FILL);
+            mPaint.setColor(Color.argb((int) (0.33f * 255),
+                            Color.red(mHighlightColor),
+                            Color.green(mHighlightColor),
+                            Color.blue(mHighlightColor)));
+            canvas.drawPath(mFramePath, mPaint);
+        }
+        mPaint.setStrokeWidth(mStrokeWidth);
+        mPaint.setStyle(Paint.Style.STROKE);
+        mPaint.setColor(mPressed ? mHighlightColor : mFrameColor);
+        mPaint.setShadowLayer(mShadowRadius, 0f, 0f, mFrameShadowColor);
+        canvas.drawPath(mFramePath, mPaint);
+    }
+
+    public void setScale(float scale) {
+        mScale = scale;
+    }
+
+    public float getScale() {
+        return mScale;
+    }
+
+    public void setPressed(boolean pressed) {
+        mPressed = pressed;
+    }
+
+    @Override
+    public int getOpacity() {
+        return PixelFormat.TRANSLUCENT;
+    }
+
+    @Override
+    public void setAlpha(int alpha) {
+    }
+
+    @Override
+    public void setColorFilter(ColorFilter cf) {
+    }
+
+    public boolean verifyParams(float iconSize, int frameColor, float stroke,
+            int frameShadowColor, float shadowRadius, int highlightColor) {
+        return mSize == iconSize
+                && mFrameColor == frameColor
+                && mStrokeWidth == stroke
+                && mFrameShadowColor == frameShadowColor
+                && mShadowRadius == shadowRadius
+                && mHighlightColor == highlightColor;
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardFaceUnlockView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardFaceUnlockView.java
new file mode 100644
index 0000000..3e499b2
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardFaceUnlockView.java
@@ -0,0 +1,316 @@
+/*
+ * 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.keyguard;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.os.PowerManager;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.telephony.TelephonyManager;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.IRotationWatcher;
+import android.view.IWindowManager;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.LinearLayout;
+
+import com.android.internal.widget.LockPatternUtils;
+
+import java.lang.Math;
+
+public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecurityView {
+
+    private static final String TAG = "FULKeyguardFaceUnlockView";
+    private static final boolean DEBUG = false;
+    private KeyguardSecurityCallback mKeyguardSecurityCallback;
+    private LockPatternUtils mLockPatternUtils;
+    private BiometricSensorUnlock mBiometricUnlock;
+    private View mFaceUnlockAreaView;
+    private ImageButton mCancelButton;
+    private SecurityMessageDisplay mSecurityMessageDisplay;
+    private View mEcaView;
+    private Drawable mBouncerFrame;
+
+    private boolean mIsShowing = false;
+    private final Object mIsShowingLock = new Object();
+
+    private int mLastRotation;
+    private boolean mWatchingRotation;
+    private final IWindowManager mWindowManager =
+            IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
+
+    private final IRotationWatcher mRotationWatcher = new IRotationWatcher.Stub() {
+        public void onRotationChanged(int rotation) {
+            if (DEBUG) Log.d(TAG, "onRotationChanged(): " + mLastRotation + "->" + rotation);
+
+            // If the difference between the new rotation value and the previous rotation value is
+            // equal to 2, the rotation change was 180 degrees.  This stops the biometric unlock
+            // and starts it in the new position.  This is not performed for 90 degree rotations
+            // since a 90 degree rotation is a configuration change, which takes care of this for
+            // us.
+            if (Math.abs(rotation - mLastRotation) == 2) {
+                if (mBiometricUnlock != null) {
+                    mBiometricUnlock.stop();
+                    maybeStartBiometricUnlock();
+                }
+            }
+            mLastRotation = rotation;
+        }
+    };
+
+    public KeyguardFaceUnlockView(Context context) {
+        this(context, null);
+    }
+
+    public KeyguardFaceUnlockView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+
+        initializeBiometricUnlockView();
+
+        mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
+        mEcaView = findViewById(R.id.keyguard_selector_fade_container);
+        View bouncerFrameView = findViewById(R.id.keyguard_bouncer_frame);
+        if (bouncerFrameView != null) {
+            mBouncerFrame = bouncerFrameView.getBackground();
+        }
+    }
+
+    @Override
+    public void setKeyguardCallback(KeyguardSecurityCallback callback) {
+        mKeyguardSecurityCallback = callback;
+        // TODO: formalize this in the interface or factor it out
+        ((FaceUnlock)mBiometricUnlock).setKeyguardCallback(callback);
+    }
+
+    @Override
+    public void setLockPatternUtils(LockPatternUtils utils) {
+        mLockPatternUtils = utils;
+    }
+
+    @Override
+    public void reset() {
+
+    }
+
+    @Override
+    public void onDetachedFromWindow() {
+        if (DEBUG) Log.d(TAG, "onDetachedFromWindow()");
+        if (mBiometricUnlock != null) {
+            mBiometricUnlock.stop();
+        }
+        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateCallback);
+        if (mWatchingRotation) {
+            try {
+                mWindowManager.removeRotationWatcher(mRotationWatcher);
+                mWatchingRotation = false;
+            } catch (RemoteException e) {
+                Log.e(TAG, "Remote exception when removing rotation watcher");
+            }
+        }
+    }
+
+    @Override
+    public void onPause() {
+        if (DEBUG) Log.d(TAG, "onPause()");
+        if (mBiometricUnlock != null) {
+            mBiometricUnlock.stop();
+        }
+        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateCallback);
+        if (mWatchingRotation) {
+            try {
+                mWindowManager.removeRotationWatcher(mRotationWatcher);
+                mWatchingRotation = false;
+            } catch (RemoteException e) {
+                Log.e(TAG, "Remote exception when removing rotation watcher");
+            }
+        }
+    }
+
+    @Override
+    public void onResume(int reason) {
+        if (DEBUG) Log.d(TAG, "onResume()");
+        mIsShowing = KeyguardUpdateMonitor.getInstance(mContext).isKeyguardVisible();
+        if (!KeyguardUpdateMonitor.getInstance(mContext).isSwitchingUser()) {
+          maybeStartBiometricUnlock();
+        }
+        KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateCallback);
+
+        // Registers a callback which handles stopping the biometric unlock and restarting it in
+        // the new position for a 180 degree rotation change.
+        if (!mWatchingRotation) {
+            try {
+                mLastRotation = mWindowManager.watchRotation(mRotationWatcher);
+                mWatchingRotation = true;
+            } catch (RemoteException e) {
+                Log.e(TAG, "Remote exception when adding rotation watcher");
+            }
+        }
+    }
+
+    @Override
+    public boolean needsInput() {
+        return false;
+    }
+
+    @Override
+    public KeyguardSecurityCallback getCallback() {
+        return mKeyguardSecurityCallback;
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        super.onLayout(changed, l, t, r, b);
+        mBiometricUnlock.initializeView(mFaceUnlockAreaView);
+    }
+
+    private void initializeBiometricUnlockView() {
+        if (DEBUG) Log.d(TAG, "initializeBiometricUnlockView()");
+        mFaceUnlockAreaView = findViewById(R.id.face_unlock_area_view);
+        if (mFaceUnlockAreaView != null) {
+            mBiometricUnlock = new FaceUnlock(mContext);
+
+            mCancelButton = (ImageButton) findViewById(R.id.face_unlock_cancel_button);
+            mCancelButton.setOnClickListener(new OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    mBiometricUnlock.stopAndShowBackup();
+                }
+            });
+        } else {
+            Log.w(TAG, "Couldn't find biometric unlock view");
+        }
+    }
+
+    /**
+     * Starts the biometric unlock if it should be started based on a number of factors.  If it
+     * should not be started, it either goes to the back up, or remains showing to prepare for
+     * it being started later.
+     */
+    private void maybeStartBiometricUnlock() {
+        if (DEBUG) Log.d(TAG, "maybeStartBiometricUnlock()");
+        if (mBiometricUnlock != null) {
+            KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
+            final boolean backupIsTimedOut = (
+                    monitor.getFailedUnlockAttempts() >=
+                    LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT);
+            PowerManager powerManager = (PowerManager) mContext.getSystemService(
+                    Context.POWER_SERVICE);
+
+            boolean isShowing;
+            synchronized(mIsShowingLock) {
+                isShowing = mIsShowing;
+            }
+
+            // Don't start it if the screen is off or if it's not showing, but keep this view up
+            // because we want it here and ready for when the screen turns on or when it does start
+            // showing.
+            if (!powerManager.isScreenOn() || !isShowing) {
+                mBiometricUnlock.stop(); // It shouldn't be running but calling this can't hurt.
+                return;
+            }
+
+            // Although these same conditions are handled in KeyguardSecurityModel, they are still
+            // necessary here.  When a tablet is rotated 90 degrees, a configuration change is
+            // triggered and everything is torn down and reconstructed.  That means
+            // KeyguardSecurityModel gets a chance to take care of the logic and doesn't even
+            // reconstruct KeyguardFaceUnlockView if the biometric unlock should be suppressed.
+            // However, for a 180 degree rotation, no configuration change is triggered, so only
+            // the logic here is capable of suppressing Face Unlock.
+            if (monitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE
+                    && monitor.isAlternateUnlockEnabled()
+                    && !monitor.getMaxBiometricUnlockAttemptsReached()
+                    && !backupIsTimedOut) {
+                mBiometricUnlock.start();
+            } else {
+                mBiometricUnlock.stopAndShowBackup();
+            }
+        }
+    }
+
+    KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() {
+        // We need to stop the biometric unlock when a phone call comes in
+        @Override
+        public void onPhoneStateChanged(int phoneState) {
+            if (DEBUG) Log.d(TAG, "onPhoneStateChanged(" + phoneState + ")");
+            if (phoneState == TelephonyManager.CALL_STATE_RINGING) {
+                if (mBiometricUnlock != null) {
+                    mBiometricUnlock.stopAndShowBackup();
+                }
+            }
+        }
+
+        @Override
+        public void onUserSwitching(int userId) {
+            if (DEBUG) Log.d(TAG, "onUserSwitched(" + userId + ")");
+            if (mBiometricUnlock != null) {
+                mBiometricUnlock.stop();
+            }
+            // No longer required; static value set by KeyguardViewMediator
+            // mLockPatternUtils.setCurrentUser(userId);
+        }
+
+        @Override
+        public void onUserSwitchComplete(int userId) {
+            if (DEBUG) Log.d(TAG, "onUserSwitchComplete(" + userId + ")");
+            if (mBiometricUnlock != null) {
+                maybeStartBiometricUnlock();
+            }
+        }
+
+        @Override
+        public void onKeyguardVisibilityChanged(boolean showing) {
+            if (DEBUG) Log.d(TAG, "onKeyguardVisibilityChanged(" + showing + ")");
+            boolean wasShowing = false;
+            synchronized(mIsShowingLock) {
+                wasShowing = mIsShowing;
+                mIsShowing = showing;
+            }
+            PowerManager powerManager = (PowerManager) mContext.getSystemService(
+                    Context.POWER_SERVICE);
+            if (mBiometricUnlock != null) {
+                if (!showing && wasShowing) {
+                    mBiometricUnlock.stop();
+                } else if (showing && powerManager.isScreenOn() && !wasShowing) {
+                    maybeStartBiometricUnlock();
+                }
+            }
+        }
+    };
+
+    @Override
+    public void showUsabilityHint() {
+    }
+
+    @Override
+    public void showBouncer(int duration) {
+        KeyguardSecurityViewHelper.
+                showBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration);
+    }
+
+    @Override
+    public void hideBouncer(int duration) {
+        KeyguardSecurityViewHelper.
+                hideBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration);
+    }
+
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardGlowStripView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardGlowStripView.java
new file mode 100644
index 0000000..98a44a6
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardGlowStripView.java
@@ -0,0 +1,137 @@
+/*
+ * 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.keyguard;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.Interpolator;
+import android.view.animation.LinearInterpolator;
+import android.widget.LinearLayout;
+
+/**
+ * A layout which animates a strip of horizontal, pulsing dots on request. This is used
+ * to indicate the presence of pages to the left / right.
+ */
+public class KeyguardGlowStripView extends LinearLayout {
+    private static final int DURATION = 500;
+
+    private static final float SLIDING_WINDOW_SIZE = 0.4f;
+    private int mDotStripTop;
+    private int mHorizontalDotGap;
+
+    private int mDotSize;
+    private int mNumDots;
+    private Drawable mDotDrawable;
+    private boolean mLeftToRight = true;
+
+    private float mAnimationProgress = 0f;
+    private boolean mDrawDots = false;
+    private ValueAnimator mAnimator;
+    private Interpolator mDotAlphaInterpolator = new DecelerateInterpolator(0.5f);
+
+    public KeyguardGlowStripView(Context context) {
+        this(context, null, 0);
+    }
+
+    public KeyguardGlowStripView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public KeyguardGlowStripView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.KeyguardGlowStripView);
+        mDotSize = a.getDimensionPixelSize(R.styleable.KeyguardGlowStripView_dotSize, mDotSize);
+        mNumDots = a.getInt(R.styleable.KeyguardGlowStripView_numDots, mNumDots);
+        mDotDrawable = a.getDrawable(R.styleable.KeyguardGlowStripView_glowDot);
+        mLeftToRight = a.getBoolean(R.styleable.KeyguardGlowStripView_leftToRight, mLeftToRight);
+    }
+
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        int availableWidth = w - getPaddingLeft() - getPaddingRight();
+        mHorizontalDotGap = (availableWidth - mDotSize * mNumDots) /  (mNumDots - 1);
+        mDotStripTop = getPaddingTop();
+        invalidate();
+    }
+
+    @Override
+    protected void dispatchDraw(Canvas canvas) {
+        super.dispatchDraw(canvas);
+
+        if (!mDrawDots) return;
+
+        int xOffset = getPaddingLeft();
+        mDotDrawable.setBounds(0, 0, mDotSize, mDotSize);
+
+        for (int i = 0; i < mNumDots; i++) {
+            // We fudge the relative position to provide a fade in of the first dot and a fade
+            // out of the final dot.
+            float relativeDotPosition = SLIDING_WINDOW_SIZE / 2 + ((1.0f * i) / (mNumDots - 1)) *
+                    (1 - SLIDING_WINDOW_SIZE);
+            float distance = Math.abs(relativeDotPosition - mAnimationProgress);
+            float alpha = Math.max(0, 1 - distance / (SLIDING_WINDOW_SIZE / 2));
+
+            alpha = mDotAlphaInterpolator.getInterpolation(alpha);
+
+            canvas.save();
+            canvas.translate(xOffset, mDotStripTop);
+            mDotDrawable.setAlpha((int) (alpha * 255));
+            mDotDrawable.draw(canvas);
+            canvas.restore();
+            xOffset += mDotSize + mHorizontalDotGap;
+        }
+    }
+
+    public void makeEmGo() {
+        if (mAnimator != null) {
+            mAnimator.cancel();
+        }
+        float from = mLeftToRight ? 0f : 1f;
+        float to = mLeftToRight ? 1f : 0f;
+        mAnimator = ValueAnimator.ofFloat(from, to);
+        mAnimator.setDuration(DURATION);
+        mAnimator.setInterpolator(new LinearInterpolator());
+        mAnimator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mDrawDots = false;
+                // make sure we draw one frame at the end with everything gone.
+                invalidate();
+            }
+
+            @Override
+            public void onAnimationStart(Animator animation) {
+                mDrawDots = true;
+            }
+        });
+        mAnimator.addUpdateListener(new AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                mAnimationProgress = (Float) animation.getAnimatedValue();
+                invalidate();
+            }
+        });
+        mAnimator.start();
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
new file mode 100644
index 0000000..fbe3a9c
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
@@ -0,0 +1,1653 @@
+/*
+ * 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.keyguard;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
+import com.android.keyguard.KeyguardUpdateMonitor.DisplayClientState;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.ActivityOptions;
+import android.app.AlertDialog;
+import android.app.PendingIntent;
+import android.app.SearchManager;
+import android.app.admin.DevicePolicyManager;
+import android.appwidget.AppWidgetHost;
+import android.appwidget.AppWidgetHostView;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentSender;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.UserInfo;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.media.RemoteControlClient;
+import android.os.Bundle;
+import android.os.Looper;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.telephony.TelephonyManager;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Slog;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.animation.AnimationUtils;
+import android.widget.RemoteViews.OnClickHandler;
+
+import java.io.File;
+import java.util.List;
+
+public class KeyguardHostView extends KeyguardViewBase {
+    private static final String TAG = "KeyguardHostView";
+
+    // Transport control states.
+    static final int TRANSPORT_GONE = 0;
+    static final int TRANSPORT_INVISIBLE = 1;
+    static final int TRANSPORT_VISIBLE = 2;
+
+    private int mTransportState = TRANSPORT_GONE;
+
+    // Use this to debug all of keyguard
+    public static boolean DEBUG = KeyguardViewMediator.DEBUG;
+    public static boolean DEBUGXPORT = true; // debug music transport control
+
+    // Found in KeyguardAppWidgetPickActivity.java
+    static final int APPWIDGET_HOST_ID = 0x4B455947;
+
+    private final int MAX_WIDGETS = 5;
+
+    private AppWidgetHost mAppWidgetHost;
+    private AppWidgetManager mAppWidgetManager;
+    private KeyguardWidgetPager mAppWidgetContainer;
+    private KeyguardSecurityViewFlipper mSecurityViewContainer;
+    private KeyguardSelectorView mKeyguardSelectorView;
+    private KeyguardTransportControlView mTransportControl;
+    private boolean mIsVerifyUnlockOnly;
+    private boolean mEnableFallback; // TODO: This should get the value from KeyguardPatternView
+    private SecurityMode mCurrentSecuritySelection = SecurityMode.Invalid;
+    private int mAppWidgetToShow;
+
+    private boolean mCheckAppWidgetConsistencyOnBootCompleted = false;
+    private boolean mCleanupAppWidgetsOnBootCompleted = false;
+
+    protected OnDismissAction mDismissAction;
+
+    protected int mFailedAttempts;
+    private LockPatternUtils mLockPatternUtils;
+
+    private KeyguardSecurityModel mSecurityModel;
+    private KeyguardViewStateManager mViewStateManager;
+
+    private Rect mTempRect = new Rect();
+
+    private int mDisabledFeatures;
+
+    private boolean mCameraDisabled;
+
+    private boolean mSafeModeEnabled;
+
+    private boolean mUserSetupCompleted;
+
+    // User for whom this host view was created.  Final because we should never change the
+    // id without reconstructing an instance of KeyguardHostView. See note below...
+    private final int mUserId;
+
+    private KeyguardMultiUserSelectorView mKeyguardMultiUserSelectorView;
+
+    private boolean mIsScreenOn;
+
+    protected int mClientGeneration;
+
+    protected boolean mShowSecurityWhenReturn;
+
+    /*package*/ interface UserSwitcherCallback {
+        void hideSecurityView(int duration);
+        void showSecurityView();
+        void showUnlockHint();
+        void userActivity();
+    }
+
+    /*package*/ interface OnDismissAction {
+        /* returns true if the dismiss should be deferred */
+        boolean onDismiss();
+    }
+
+    public KeyguardHostView(Context context) {
+        this(context, null);
+    }
+
+    public KeyguardHostView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        if (DEBUG) Log.e(TAG, "KeyguardHostView()");
+
+        mLockPatternUtils = new LockPatternUtils(context);
+
+        // Note: This depends on KeyguardHostView getting reconstructed every time the
+        // user switches, since mUserId will be used for the entire session.
+        // Once created, keyguard should *never* re-use this instance with another user.
+        // In other words, mUserId should never change - hence it's marked final.
+        mUserId = mLockPatternUtils.getCurrentUser();
+
+        DevicePolicyManager dpm =
+                (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+        if (dpm != null) {
+            mDisabledFeatures = getDisabledFeatures(dpm);
+            mCameraDisabled = dpm.getCameraDisabled(null);
+        }
+
+        mSafeModeEnabled = LockPatternUtils.isSafeModeEnabled();
+
+        // These need to be created with the user context...
+        Context userContext = null;
+        try {
+            final String packageName = "system";
+            userContext = mContext.createPackageContextAsUser(packageName, 0,
+                    new UserHandle(mUserId));
+
+        } catch (NameNotFoundException e) {
+            e.printStackTrace();
+            // This should never happen, but it's better to have no widgets than to crash.
+            userContext = context;
+        }
+
+        mAppWidgetHost = new AppWidgetHost(userContext, APPWIDGET_HOST_ID, mOnClickHandler,
+                Looper.myLooper());
+
+        cleanupAppWidgetIds();
+
+        mAppWidgetManager = AppWidgetManager.getInstance(userContext);
+
+        mSecurityModel = new KeyguardSecurityModel(context);
+
+        mViewStateManager = new KeyguardViewStateManager(this);
+
+        mUserSetupCompleted = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
+
+        // Ensure we have the current state *before* we call showAppropriateWidgetPage()
+        getInitialTransportState();
+
+        if (mSafeModeEnabled) {
+            Log.v(TAG, "Keyguard widgets disabled by safe mode");
+        }
+        if ((mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL) != 0) {
+            Log.v(TAG, "Keyguard widgets disabled by DPM");
+        }
+        if ((mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0) {
+            Log.v(TAG, "Keyguard secure camera disabled by DPM");
+        }
+    }
+
+    private void getInitialTransportState() {
+        DisplayClientState dcs = KeyguardUpdateMonitor.getInstance(mContext)
+                .getCachedDisplayClientState();
+        mTransportState = (dcs.clearing ? TRANSPORT_GONE :
+            (isMusicPlaying(dcs.playbackState) ? TRANSPORT_VISIBLE : TRANSPORT_INVISIBLE));
+
+        if (DEBUG) Log.v(TAG, "Initial transport state: "
+                + mTransportState + ", pbstate=" + dcs.playbackState);
+    }
+
+    private void cleanupAppWidgetIds() {
+        // Since this method may delete a widget (which we can't do until boot completed) we
+        // may have to defer it until after boot complete.
+        if (!KeyguardUpdateMonitor.getInstance(mContext).hasBootCompleted()) {
+            mCleanupAppWidgetsOnBootCompleted = true;
+            return;
+        }
+        if (!mSafeModeEnabled && !widgetsDisabled()) {
+            // Clean up appWidgetIds that are bound to lockscreen, but not actually used
+            // This is only to clean up after another bug: we used to not call
+            // deleteAppWidgetId when a user manually deleted a widget in keyguard. This code
+            // shouldn't have to run more than once per user. AppWidgetProviders rely on callbacks
+            // that are triggered by deleteAppWidgetId, which is why we're doing this
+            int[] appWidgetIdsInKeyguardSettings = mLockPatternUtils.getAppWidgets();
+            int[] appWidgetIdsBoundToHost = mAppWidgetHost.getAppWidgetIds();
+            for (int i = 0; i < appWidgetIdsBoundToHost.length; i++) {
+                int appWidgetId = appWidgetIdsBoundToHost[i];
+                if (!contains(appWidgetIdsInKeyguardSettings, appWidgetId)) {
+                    Log.d(TAG, "Found a appWidgetId that's not being used by keyguard, deleting id "
+                            + appWidgetId);
+                    mAppWidgetHost.deleteAppWidgetId(appWidgetId);
+                }
+            }
+        }
+    }
+
+    private static boolean contains(int[] array, int target) {
+        for (int value : array) {
+            if (value == target) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private KeyguardUpdateMonitorCallback mUpdateMonitorCallbacks =
+            new KeyguardUpdateMonitorCallback() {
+        @Override
+        public void onBootCompleted() {
+            if (mCheckAppWidgetConsistencyOnBootCompleted) {
+                checkAppWidgetConsistency();
+                mSwitchPageRunnable.run();
+                mCheckAppWidgetConsistencyOnBootCompleted = false;
+            }
+            if (mCleanupAppWidgetsOnBootCompleted) {
+                cleanupAppWidgetIds();
+                mCleanupAppWidgetsOnBootCompleted = false;
+            }
+        }
+        @Override
+        public void onUserSwitchComplete(int userId) {
+            if (mKeyguardMultiUserSelectorView != null) {
+                mKeyguardMultiUserSelectorView.finalizeActiveUserView(true);
+            }
+        }
+        @Override
+        void onMusicClientIdChanged(
+                int clientGeneration, boolean clearing, android.app.PendingIntent intent) {
+            // Set transport state to invisible until we know music is playing (below)
+            if (DEBUGXPORT && (mClientGeneration != clientGeneration || clearing)) {
+                Log.v(TAG, (clearing ? "hide" : "show") + " transport, gen:" + clientGeneration);
+            }
+            mClientGeneration = clientGeneration;
+            final int newState = (clearing ? TRANSPORT_GONE
+                    : (mTransportState == TRANSPORT_VISIBLE ?
+                    TRANSPORT_VISIBLE : TRANSPORT_INVISIBLE));
+            if (newState != mTransportState) {
+                mTransportState = newState;
+                if (DEBUGXPORT) Log.v(TAG, "update widget: transport state changed");
+                KeyguardHostView.this.post(mSwitchPageRunnable);
+            }
+        }
+        @Override
+        public void onMusicPlaybackStateChanged(int playbackState, long eventTime) {
+            if (DEBUGXPORT) Log.v(TAG, "music state changed: " + playbackState);
+            if (mTransportState != TRANSPORT_GONE) {
+                final int newState = (isMusicPlaying(playbackState) ?
+                        TRANSPORT_VISIBLE : TRANSPORT_INVISIBLE);
+                if (newState != mTransportState) {
+                    mTransportState = newState;
+                    if (DEBUGXPORT) Log.v(TAG, "update widget: play state changed");
+                    KeyguardHostView.this.post(mSwitchPageRunnable);
+                }
+            }
+        }
+    };
+
+    private static final boolean isMusicPlaying(int playbackState) {
+        // This should agree with the list in AudioService.isPlaystateActive()
+        switch (playbackState) {
+            case RemoteControlClient.PLAYSTATE_PLAYING:
+            case RemoteControlClient.PLAYSTATE_BUFFERING:
+            case RemoteControlClient.PLAYSTATE_FAST_FORWARDING:
+            case RemoteControlClient.PLAYSTATE_REWINDING:
+            case RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS:
+            case RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    private SlidingChallengeLayout mSlidingChallengeLayout;
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        boolean result = super.onTouchEvent(ev);
+        mTempRect.set(0, 0, 0, 0);
+        offsetRectIntoDescendantCoords(mSecurityViewContainer, mTempRect);
+        ev.offsetLocation(mTempRect.left, mTempRect.top);
+        result = mSecurityViewContainer.dispatchTouchEvent(ev) || result;
+        ev.offsetLocation(-mTempRect.left, -mTempRect.top);
+        return result;
+    }
+
+    @Override
+    protected void dispatchDraw(Canvas canvas) {
+        super.dispatchDraw(canvas);
+        if (mViewMediatorCallback != null) {
+            mViewMediatorCallback.keyguardDoneDrawing();
+        }
+    }
+
+    private int getWidgetPosition(int id) {
+        final KeyguardWidgetPager appWidgetContainer = mAppWidgetContainer;
+        final int children = appWidgetContainer.getChildCount();
+        for (int i = 0; i < children; i++) {
+            final View content = appWidgetContainer.getWidgetPageAt(i).getContent();
+            if (content != null && content.getId() == id) {
+                return i;
+            } else if (content == null) {
+                // Attempt to track down bug #8886916
+                Log.w(TAG, "*** Null content at " + "i=" + i + ",id=" + id + ",N=" + children);
+            }
+        }
+        return -1;
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        // Grab instances of and make any necessary changes to the main layouts. Create
+        // view state manager and wire up necessary listeners / callbacks.
+        View deleteDropTarget = findViewById(R.id.keyguard_widget_pager_delete_target);
+        mAppWidgetContainer = (KeyguardWidgetPager) findViewById(R.id.app_widget_container);
+        mAppWidgetContainer.setVisibility(VISIBLE);
+        mAppWidgetContainer.setCallbacks(mWidgetCallbacks);
+        mAppWidgetContainer.setDeleteDropTarget(deleteDropTarget);
+        mAppWidgetContainer.setMinScale(0.5f);
+
+        mSlidingChallengeLayout = (SlidingChallengeLayout) findViewById(R.id.sliding_layout);
+        if (mSlidingChallengeLayout != null) {
+            mSlidingChallengeLayout.setOnChallengeScrolledListener(mViewStateManager);
+        }
+        mAppWidgetContainer.setViewStateManager(mViewStateManager);
+        mAppWidgetContainer.setLockPatternUtils(mLockPatternUtils);
+
+        ChallengeLayout challenge = mSlidingChallengeLayout != null ? mSlidingChallengeLayout :
+            (ChallengeLayout) findViewById(R.id.multi_pane_challenge);
+        challenge.setOnBouncerStateChangedListener(mViewStateManager);
+        mAppWidgetContainer.setBouncerAnimationDuration(challenge.getBouncerAnimationDuration());
+        mViewStateManager.setPagedView(mAppWidgetContainer);
+        mViewStateManager.setChallengeLayout(challenge);
+        mSecurityViewContainer = (KeyguardSecurityViewFlipper) findViewById(R.id.view_flipper);
+        mKeyguardSelectorView = (KeyguardSelectorView) findViewById(R.id.keyguard_selector_view);
+        mViewStateManager.setSecurityViewContainer(mSecurityViewContainer);
+
+        setBackButtonEnabled(false);
+
+        addDefaultWidgets();
+
+        addWidgetsFromSettings();
+        if (!shouldEnableAddWidget()) {
+            mAppWidgetContainer.setAddWidgetEnabled(false);
+        }
+        checkAppWidgetConsistency();
+        mSwitchPageRunnable.run();
+        // This needs to be called after the pages are all added.
+        mViewStateManager.showUsabilityHints();
+
+        showPrimarySecurityScreen(false);
+        updateSecurityViews();
+    }
+
+    private void setBackButtonEnabled(boolean enabled) {
+        if (mContext instanceof Activity) return;  // always enabled in activity mode
+        setSystemUiVisibility(enabled ?
+                getSystemUiVisibility() & ~View.STATUS_BAR_DISABLE_BACK :
+                getSystemUiVisibility() | View.STATUS_BAR_DISABLE_BACK);
+    }
+
+    private boolean shouldEnableAddWidget() {
+        return numWidgets() < MAX_WIDGETS && mUserSetupCompleted;
+    }
+
+    private int getDisabledFeatures(DevicePolicyManager dpm) {
+        int disabledFeatures = DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE;
+        if (dpm != null) {
+            final int currentUser = mLockPatternUtils.getCurrentUser();
+            disabledFeatures = dpm.getKeyguardDisabledFeatures(null, currentUser);
+        }
+        return disabledFeatures;
+    }
+
+    private boolean widgetsDisabled() {
+        boolean disabledByDpm =
+                (mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL) != 0;
+        boolean disabledByUser = !mLockPatternUtils.getWidgetsEnabled();
+        return disabledByDpm || disabledByUser;
+    }
+
+    private boolean cameraDisabledByDpm() {
+        return mCameraDisabled
+                || (mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0;
+    }
+
+    private void updateSecurityViews() {
+        int children = mSecurityViewContainer.getChildCount();
+        for (int i = 0; i < children; i++) {
+            updateSecurityView(mSecurityViewContainer.getChildAt(i));
+        }
+    }
+
+    private void updateSecurityView(View view) {
+        if (view instanceof KeyguardSecurityView) {
+            KeyguardSecurityView ksv = (KeyguardSecurityView) view;
+            ksv.setKeyguardCallback(mCallback);
+            ksv.setLockPatternUtils(mLockPatternUtils);
+            if (mViewStateManager.isBouncing()) {
+                ksv.showBouncer(0);
+            } else {
+                ksv.hideBouncer(0);
+            }
+        } else {
+            Log.w(TAG, "View " + view + " is not a KeyguardSecurityView");
+        }
+    }
+
+    void setLockPatternUtils(LockPatternUtils utils) {
+        mSecurityModel.setLockPatternUtils(utils);
+        mLockPatternUtils = utils;
+        updateSecurityViews();
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        mAppWidgetHost.startListening();
+        KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallbacks);
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        mAppWidgetHost.stopListening();
+        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateMonitorCallbacks);
+    }
+
+    void addWidget(AppWidgetHostView view, int pageIndex) {
+        mAppWidgetContainer.addWidget(view, pageIndex);
+    }
+
+    private KeyguardWidgetPager.Callbacks mWidgetCallbacks
+            = new KeyguardWidgetPager.Callbacks() {
+        @Override
+        public void userActivity() {
+            KeyguardHostView.this.userActivity();
+        }
+
+        @Override
+        public void onUserActivityTimeoutChanged() {
+            KeyguardHostView.this.onUserActivityTimeoutChanged();
+        }
+
+        @Override
+        public void onAddView(View v) {
+            if (!shouldEnableAddWidget()) {
+                mAppWidgetContainer.setAddWidgetEnabled(false);
+            }
+        }
+
+        @Override
+        public void onRemoveView(View v, boolean deletePermanently) {
+            if (deletePermanently) {
+                final int appWidgetId = ((KeyguardWidgetFrame) v).getContentAppWidgetId();
+                if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID &&
+                        appWidgetId != LockPatternUtils.ID_DEFAULT_STATUS_WIDGET) {
+                    mAppWidgetHost.deleteAppWidgetId(appWidgetId);
+                }
+            }
+        }
+
+        @Override
+        public void onRemoveViewAnimationCompleted() {
+            if (shouldEnableAddWidget()) {
+                mAppWidgetContainer.setAddWidgetEnabled(true);
+            }
+        }
+    };
+
+    public void initializeSwitchingUserState(boolean switching) {
+        if (!switching && mKeyguardMultiUserSelectorView != null) {
+            mKeyguardMultiUserSelectorView.finalizeActiveUserView(false);
+        }
+    }
+
+    public void userActivity() {
+        if (mViewMediatorCallback != null) {
+            mViewMediatorCallback.userActivity();
+        }
+    }
+
+    public void onUserActivityTimeoutChanged() {
+        if (mViewMediatorCallback != null) {
+            mViewMediatorCallback.onUserActivityTimeoutChanged();
+        }
+    }
+
+    @Override
+    public long getUserActivityTimeout() {
+        // Currently only considering user activity timeouts needed by widgets.
+        // Could also take into account longer timeouts for certain security views.
+        if (mAppWidgetContainer != null) {
+            return mAppWidgetContainer.getUserActivityTimeout();
+        }
+        return -1;
+    }
+
+    private KeyguardSecurityCallback mCallback = new KeyguardSecurityCallback() {
+
+        public void userActivity(long timeout) {
+            if (mViewMediatorCallback != null) {
+                mViewMediatorCallback.userActivity(timeout);
+            }
+        }
+
+        public void dismiss(boolean authenticated) {
+            showNextSecurityScreenOrFinish(authenticated);
+        }
+
+        public boolean isVerifyUnlockOnly() {
+            return mIsVerifyUnlockOnly;
+        }
+
+        public void reportSuccessfulUnlockAttempt() {
+            KeyguardUpdateMonitor.getInstance(mContext).clearFailedUnlockAttempts();
+            mLockPatternUtils.reportSuccessfulPasswordAttempt();
+        }
+
+        public void reportFailedUnlockAttempt() {
+            if (mCurrentSecuritySelection == SecurityMode.Biometric) {
+                KeyguardUpdateMonitor.getInstance(mContext).reportFailedBiometricUnlockAttempt();
+            } else {
+                KeyguardHostView.this.reportFailedUnlockAttempt();
+            }
+        }
+
+        public int getFailedAttempts() {
+            return KeyguardUpdateMonitor.getInstance(mContext).getFailedUnlockAttempts();
+        }
+
+        @Override
+        public void showBackupSecurity() {
+            KeyguardHostView.this.showBackupSecurityScreen();
+        }
+
+        @Override
+        public void setOnDismissAction(OnDismissAction action) {
+            KeyguardHostView.this.setOnDismissAction(action);
+        }
+
+    };
+
+    private void showDialog(String title, String message) {
+        final AlertDialog dialog = new AlertDialog.Builder(mContext)
+            .setTitle(title)
+            .setMessage(message)
+            .setNeutralButton(R.string.ok, null)
+            .create();
+        if (!(mContext instanceof Activity)) {
+            dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
+        }
+        dialog.show();
+    }
+
+    private void showTimeoutDialog() {
+        int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000;
+        int messageId = 0;
+
+        switch (mSecurityModel.getSecurityMode()) {
+            case Pattern:
+                messageId = R.string.kg_too_many_failed_pattern_attempts_dialog_message;
+                break;
+            case PIN:
+                messageId = R.string.kg_too_many_failed_pin_attempts_dialog_message;
+                break;
+            case Password:
+                messageId = R.string.kg_too_many_failed_password_attempts_dialog_message;
+                break;
+        }
+
+        if (messageId != 0) {
+            final String message = mContext.getString(messageId,
+                    KeyguardUpdateMonitor.getInstance(mContext).getFailedUnlockAttempts(),
+                    timeoutInSeconds);
+            showDialog(null, message);
+        }
+    }
+
+    private void showAlmostAtWipeDialog(int attempts, int remaining) {
+        int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000;
+        String message = mContext.getString(R.string.kg_failed_attempts_almost_at_wipe,
+                attempts, remaining);
+        showDialog(null, message);
+    }
+
+    private void showWipeDialog(int attempts) {
+        String message = mContext.getString(R.string.kg_failed_attempts_now_wiping, attempts);
+        showDialog(null, message);
+    }
+
+    private void showAlmostAtAccountLoginDialog() {
+        final int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000;
+        final int count = LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET
+                - LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT;
+        String message = mContext.getString(R.string.kg_failed_attempts_almost_at_login,
+                count, LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT, timeoutInSeconds);
+        showDialog(null, message);
+    }
+
+    private void reportFailedUnlockAttempt() {
+        final KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
+        final int failedAttempts = monitor.getFailedUnlockAttempts() + 1; // +1 for this time
+
+        if (DEBUG) Log.d(TAG, "reportFailedPatternAttempt: #" + failedAttempts);
+
+        SecurityMode mode = mSecurityModel.getSecurityMode();
+        final boolean usingPattern = mode == KeyguardSecurityModel.SecurityMode.Pattern;
+
+        final int failedAttemptsBeforeWipe = mLockPatternUtils.getDevicePolicyManager()
+                .getMaximumFailedPasswordsForWipe(null, mLockPatternUtils.getCurrentUser());
+
+        final int failedAttemptWarning = LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET
+                - LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT;
+
+        final int remainingBeforeWipe = failedAttemptsBeforeWipe > 0 ?
+                (failedAttemptsBeforeWipe - failedAttempts)
+                : Integer.MAX_VALUE; // because DPM returns 0 if no restriction
+
+        boolean showTimeout = false;
+        if (remainingBeforeWipe < LockPatternUtils.FAILED_ATTEMPTS_BEFORE_WIPE_GRACE) {
+            // If we reach this code, it means the user has installed a DevicePolicyManager
+            // that requests device wipe after N attempts.  Once we get below the grace
+            // period, we'll post this dialog every time as a clear warning until the
+            // bombshell hits and the device is wiped.
+            if (remainingBeforeWipe > 0) {
+                showAlmostAtWipeDialog(failedAttempts, remainingBeforeWipe);
+            } else {
+                // Too many attempts. The device will be wiped shortly.
+                Slog.i(TAG, "Too many unlock attempts; device will be wiped!");
+                showWipeDialog(failedAttempts);
+            }
+        } else {
+            showTimeout =
+                (failedAttempts % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) == 0;
+            if (usingPattern && mEnableFallback) {
+                if (failedAttempts == failedAttemptWarning) {
+                    showAlmostAtAccountLoginDialog();
+                    showTimeout = false; // don't show both dialogs
+                } else if (failedAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET) {
+                    mLockPatternUtils.setPermanentlyLocked(true);
+                    showSecurityScreen(SecurityMode.Account);
+                    // don't show timeout dialog because we show account unlock screen next
+                    showTimeout = false;
+                }
+            }
+        }
+        monitor.reportFailedUnlockAttempt();
+        mLockPatternUtils.reportFailedPasswordAttempt();
+        if (showTimeout) {
+            showTimeoutDialog();
+        }
+    }
+
+    /**
+     * Shows the primary security screen for the user. This will be either the multi-selector
+     * or the user's security method.
+     * @param turningOff true if the device is being turned off
+     */
+    void showPrimarySecurityScreen(boolean turningOff) {
+        SecurityMode securityMode = mSecurityModel.getSecurityMode();
+        if (DEBUG) Log.v(TAG, "showPrimarySecurityScreen(turningOff=" + turningOff + ")");
+        if (!turningOff &&
+                KeyguardUpdateMonitor.getInstance(mContext).isAlternateUnlockEnabled()) {
+            // If we're not turning off, then allow biometric alternate.
+            // We'll reload it when the device comes back on.
+            securityMode = mSecurityModel.getAlternateFor(securityMode);
+        }
+        showSecurityScreen(securityMode);
+    }
+
+    /**
+     * Shows the backup security screen for the current security mode.  This could be used for
+     * password recovery screens but is currently only used for pattern unlock to show the
+     * account unlock screen and biometric unlock to show the user's normal unlock.
+     */
+    private void showBackupSecurityScreen() {
+        if (DEBUG) Log.d(TAG, "showBackupSecurity()");
+        SecurityMode backup = mSecurityModel.getBackupSecurityMode(mCurrentSecuritySelection);
+        showSecurityScreen(backup);
+    }
+
+    public boolean showNextSecurityScreenIfPresent() {
+        SecurityMode securityMode = mSecurityModel.getSecurityMode();
+        // Allow an alternate, such as biometric unlock
+        securityMode = mSecurityModel.getAlternateFor(securityMode);
+        if (SecurityMode.None == securityMode) {
+            return false;
+        } else {
+            showSecurityScreen(securityMode); // switch to the alternate security view
+            return true;
+        }
+    }
+
+    private void showNextSecurityScreenOrFinish(boolean authenticated) {
+        if (DEBUG) Log.d(TAG, "showNextSecurityScreenOrFinish(" + authenticated + ")");
+        boolean finish = false;
+        if (SecurityMode.None == mCurrentSecuritySelection) {
+            SecurityMode securityMode = mSecurityModel.getSecurityMode();
+            // Allow an alternate, such as biometric unlock
+            securityMode = mSecurityModel.getAlternateFor(securityMode);
+            if (SecurityMode.None == securityMode) {
+                finish = true; // no security required
+            } else {
+                showSecurityScreen(securityMode); // switch to the alternate security view
+            }
+        } else if (authenticated) {
+            switch (mCurrentSecuritySelection) {
+                case Pattern:
+                case Password:
+                case PIN:
+                case Account:
+                case Biometric:
+                    finish = true;
+                    break;
+
+                case SimPin:
+                case SimPuk:
+                    // Shortcut for SIM PIN/PUK to go to directly to user's security screen or home
+                    SecurityMode securityMode = mSecurityModel.getSecurityMode();
+                    if (securityMode != SecurityMode.None) {
+                        showSecurityScreen(securityMode);
+                    } else {
+                        finish = true;
+                    }
+                    break;
+
+                default:
+                    Log.v(TAG, "Bad security screen " + mCurrentSecuritySelection + ", fail safe");
+                    showPrimarySecurityScreen(false);
+                    break;
+            }
+        } else {
+            showPrimarySecurityScreen(false);
+        }
+        if (finish) {
+            // If the alternate unlock was suppressed, it can now be safely
+            // enabled because the user has left keyguard.
+            KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true);
+
+            // If there's a pending runnable because the user interacted with a widget
+            // and we're leaving keyguard, then run it.
+            boolean deferKeyguardDone = false;
+            if (mDismissAction != null) {
+                deferKeyguardDone = mDismissAction.onDismiss();
+                mDismissAction = null;
+            }
+            if (mViewMediatorCallback != null) {
+                if (deferKeyguardDone) {
+                    mViewMediatorCallback.keyguardDonePending();
+                } else {
+                    mViewMediatorCallback.keyguardDone(true);
+                }
+            }
+        } else {
+            mViewStateManager.showBouncer(true);
+        }
+    }
+
+    private OnClickHandler mOnClickHandler = new OnClickHandler() {
+        @Override
+        public boolean onClickHandler(final View view,
+                final android.app.PendingIntent pendingIntent,
+                final Intent fillInIntent) {
+            if (pendingIntent.isActivity()) {
+                setOnDismissAction(new OnDismissAction() {
+                    public boolean onDismiss() {
+                        try {
+                              // TODO: Unregister this handler if PendingIntent.FLAG_ONE_SHOT?
+                              Context context = view.getContext();
+                              ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(view,
+                                      0, 0,
+                                      view.getMeasuredWidth(), view.getMeasuredHeight());
+                              context.startIntentSender(
+                                      pendingIntent.getIntentSender(), fillInIntent,
+                                      Intent.FLAG_ACTIVITY_NEW_TASK,
+                                      Intent.FLAG_ACTIVITY_NEW_TASK, 0, opts.toBundle());
+                        } catch (IntentSender.SendIntentException e) {
+                            android.util.Log.e(TAG, "Cannot send pending intent: ", e);
+                        } catch (Exception e) {
+                            android.util.Log.e(TAG, "Cannot send pending intent due to " +
+                                    "unknown exception: ", e);
+                        }
+                        return false;
+                    }
+                });
+
+                if (mViewStateManager.isChallengeShowing()) {
+                    mViewStateManager.showBouncer(true);
+                } else {
+                    mCallback.dismiss(false);
+                }
+                return true;
+            } else {
+                return super.onClickHandler(view, pendingIntent, fillInIntent);
+            }
+        };
+    };
+
+    // Used to ignore callbacks from methods that are no longer current (e.g. face unlock).
+    // This avoids unwanted asynchronous events from messing with the state.
+    private KeyguardSecurityCallback mNullCallback = new KeyguardSecurityCallback() {
+
+        @Override
+        public void userActivity(long timeout) {
+        }
+
+        @Override
+        public void showBackupSecurity() {
+        }
+
+        @Override
+        public void setOnDismissAction(OnDismissAction action) {
+        }
+
+        @Override
+        public void reportSuccessfulUnlockAttempt() {
+        }
+
+        @Override
+        public void reportFailedUnlockAttempt() {
+        }
+
+        @Override
+        public boolean isVerifyUnlockOnly() {
+            return false;
+        }
+
+        @Override
+        public int getFailedAttempts() {
+            return 0;
+        }
+
+        @Override
+        public void dismiss(boolean securityVerified) {
+        }
+    };
+
+    /**
+     * Sets an action to perform when keyguard is dismissed.
+     * @param action
+     */
+    protected void setOnDismissAction(OnDismissAction action) {
+        mDismissAction = action;
+    }
+
+    private KeyguardSecurityView getSecurityView(SecurityMode securityMode) {
+        final int securityViewIdForMode = getSecurityViewIdForMode(securityMode);
+        KeyguardSecurityView view = null;
+        final int children = mSecurityViewContainer.getChildCount();
+        for (int child = 0; child < children; child++) {
+            if (mSecurityViewContainer.getChildAt(child).getId() == securityViewIdForMode) {
+                view = ((KeyguardSecurityView)mSecurityViewContainer.getChildAt(child));
+                break;
+            }
+        }
+        int layoutId = getLayoutIdFor(securityMode);
+        if (view == null && layoutId != 0) {
+            final LayoutInflater inflater = LayoutInflater.from(mContext);
+            if (DEBUG) Log.v(TAG, "inflating id = " + layoutId);
+            View v = inflater.inflate(layoutId, mSecurityViewContainer, false);
+            mSecurityViewContainer.addView(v);
+            updateSecurityView(v);
+            view = (KeyguardSecurityView)v;
+        }
+
+        if (view instanceof KeyguardSelectorView) {
+            KeyguardSelectorView selectorView = (KeyguardSelectorView) view;
+            View carrierText = selectorView.findViewById(R.id.keyguard_selector_fade_container);
+            selectorView.setCarrierArea(carrierText);
+        }
+
+        return view;
+    }
+
+    /**
+     * Switches to the given security view unless it's already being shown, in which case
+     * this is a no-op.
+     *
+     * @param securityMode
+     */
+    private void showSecurityScreen(SecurityMode securityMode) {
+        if (DEBUG) Log.d(TAG, "showSecurityScreen(" + securityMode + ")");
+
+        if (securityMode == mCurrentSecuritySelection) return;
+
+        KeyguardSecurityView oldView = getSecurityView(mCurrentSecuritySelection);
+        KeyguardSecurityView newView = getSecurityView(securityMode);
+
+        // Enter full screen mode if we're in SIM or Account screen
+        boolean fullScreenEnabled = getResources().getBoolean(R.bool.kg_sim_puk_account_full_screen);
+        boolean isSimOrAccount = securityMode == SecurityMode.SimPin
+                || securityMode == SecurityMode.SimPuk
+                || securityMode == SecurityMode.Account;
+        mAppWidgetContainer.setVisibility(
+                isSimOrAccount && fullScreenEnabled ? View.GONE : View.VISIBLE);
+
+        if (mSlidingChallengeLayout != null) {
+            mSlidingChallengeLayout.setChallengeInteractive(!fullScreenEnabled);
+        }
+
+        // Emulate Activity life cycle
+        if (oldView != null) {
+            oldView.onPause();
+            oldView.setKeyguardCallback(mNullCallback); // ignore requests from old view
+        }
+        newView.onResume(KeyguardSecurityView.VIEW_REVEALED);
+        newView.setKeyguardCallback(mCallback);
+
+        final boolean needsInput = newView.needsInput();
+        if (mViewMediatorCallback != null) {
+            mViewMediatorCallback.setNeedsInput(needsInput);
+        }
+
+        // Find and show this child.
+        final int childCount = mSecurityViewContainer.getChildCount();
+
+        mSecurityViewContainer.setInAnimation(
+                AnimationUtils.loadAnimation(mContext, R.anim.keyguard_security_fade_in));
+        mSecurityViewContainer.setOutAnimation(
+                AnimationUtils.loadAnimation(mContext, R.anim.keyguard_security_fade_out));
+        final int securityViewIdForMode = getSecurityViewIdForMode(securityMode);
+        for (int i = 0; i < childCount; i++) {
+            if (mSecurityViewContainer.getChildAt(i).getId() == securityViewIdForMode) {
+                mSecurityViewContainer.setDisplayedChild(i);
+                break;
+            }
+        }
+
+        if (securityMode == SecurityMode.None) {
+            // Discard current runnable if we're switching back to the selector view
+            setOnDismissAction(null);
+        }
+        if (securityMode == SecurityMode.Account && !mLockPatternUtils.isPermanentlyLocked()) {
+            // we're showing account as a backup, provide a way to get back to primary
+            setBackButtonEnabled(true);
+        }
+        mCurrentSecuritySelection = securityMode;
+    }
+
+    @Override
+    public void onScreenTurnedOn() {
+        if (DEBUG) Log.d(TAG, "screen on, instance " + Integer.toHexString(hashCode()));
+        mIsScreenOn = true;
+        showPrimarySecurityScreen(false);
+        getSecurityView(mCurrentSecuritySelection).onResume(KeyguardSecurityView.SCREEN_ON);
+
+        // This is a an attempt to fix bug 7137389 where the device comes back on but the entire
+        // layout is blank but forcing a layout causes it to reappear (e.g. with with
+        // hierarchyviewer).
+        requestLayout();
+
+        if (mViewStateManager != null) {
+            mViewStateManager.showUsabilityHints();
+        }
+
+        requestFocus();
+    }
+
+    @Override
+    public void onScreenTurnedOff() {
+        if (DEBUG) Log.d(TAG, String.format("screen off, instance %s at %s",
+                Integer.toHexString(hashCode()), SystemClock.uptimeMillis()));
+        mIsScreenOn = false;
+        // Once the screen turns off, we no longer consider this to be first boot and we want the
+        // biometric unlock to start next time keyguard is shown.
+        KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true);
+        // We use mAppWidgetToShow to show a particular widget after you add it-- once the screen
+        // turns off we reset that behavior
+        clearAppWidgetToShow();
+        checkAppWidgetConsistency();
+        showPrimarySecurityScreen(true);
+        getSecurityView(mCurrentSecuritySelection).onPause();
+        CameraWidgetFrame cameraPage = findCameraPage();
+        if (cameraPage != null) {
+            cameraPage.onScreenTurnedOff();
+        }
+
+        clearFocus();
+    }
+
+    public void clearAppWidgetToShow() {
+        mAppWidgetToShow = AppWidgetManager.INVALID_APPWIDGET_ID;
+    }
+
+    @Override
+    public void show() {
+        if (DEBUG) Log.d(TAG, "show()");
+        showPrimarySecurityScreen(false);
+    }
+
+    @Override
+    public void verifyUnlock() {
+        SecurityMode securityMode = mSecurityModel.getSecurityMode();
+        if (securityMode == KeyguardSecurityModel.SecurityMode.None) {
+            if (mViewMediatorCallback != null) {
+                mViewMediatorCallback.keyguardDone(true);
+            }
+        } else if (securityMode != KeyguardSecurityModel.SecurityMode.Pattern
+                && securityMode != KeyguardSecurityModel.SecurityMode.PIN
+                && securityMode != KeyguardSecurityModel.SecurityMode.Password) {
+            // can only verify unlock when in pattern/password mode
+            if (mViewMediatorCallback != null) {
+                mViewMediatorCallback.keyguardDone(false);
+            }
+        } else {
+            // otherwise, go to the unlock screen, see if they can verify it
+            mIsVerifyUnlockOnly = true;
+            showSecurityScreen(securityMode);
+        }
+    }
+
+    private int getSecurityViewIdForMode(SecurityMode securityMode) {
+        switch (securityMode) {
+            case None: return R.id.keyguard_selector_view;
+            case Pattern: return R.id.keyguard_pattern_view;
+            case PIN: return R.id.keyguard_pin_view;
+            case Password: return R.id.keyguard_password_view;
+            case Biometric: return R.id.keyguard_face_unlock_view;
+            case Account: return R.id.keyguard_account_view;
+            case SimPin: return R.id.keyguard_sim_pin_view;
+            case SimPuk: return R.id.keyguard_sim_puk_view;
+        }
+        return 0;
+    }
+
+    private int getLayoutIdFor(SecurityMode securityMode) {
+        switch (securityMode) {
+            case None: return R.layout.keyguard_selector_view;
+            case Pattern: return R.layout.keyguard_pattern_view;
+            case PIN: return R.layout.keyguard_pin_view;
+            case Password: return R.layout.keyguard_password_view;
+            case Biometric: return R.layout.keyguard_face_unlock_view;
+            case Account: return R.layout.keyguard_account_view;
+            case SimPin: return R.layout.keyguard_sim_pin_view;
+            case SimPuk: return R.layout.keyguard_sim_puk_view;
+            default:
+                return 0;
+        }
+    }
+
+    private boolean addWidget(int appId, int pageIndex, boolean updateDbIfFailed) {
+        AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appId);
+        if (appWidgetInfo != null) {
+            AppWidgetHostView view = mAppWidgetHost.createView(mContext, appId, appWidgetInfo);
+            addWidget(view, pageIndex);
+            return true;
+        } else {
+            if (updateDbIfFailed) {
+                Log.w(TAG, "*** AppWidgetInfo for app widget id " + appId + "  was null for user"
+                        + mUserId + ", deleting");
+                mAppWidgetHost.deleteAppWidgetId(appId);
+                mLockPatternUtils.removeAppWidget(appId);
+            }
+            return false;
+        }
+    }
+
+    private final CameraWidgetFrame.Callbacks mCameraWidgetCallbacks =
+        new CameraWidgetFrame.Callbacks() {
+            @Override
+            public void onLaunchingCamera() {
+                setSliderHandleAlpha(0);
+            }
+
+            @Override
+            public void onCameraLaunchedSuccessfully() {
+                if (mAppWidgetContainer.isCameraPage(mAppWidgetContainer.getCurrentPage())) {
+                    mAppWidgetContainer.scrollLeft();
+                }
+                setSliderHandleAlpha(1);
+                mShowSecurityWhenReturn = true;
+            }
+
+            @Override
+            public void onCameraLaunchedUnsuccessfully() {
+                setSliderHandleAlpha(1);
+            }
+
+            private void setSliderHandleAlpha(float alpha) {
+                SlidingChallengeLayout slider =
+                        (SlidingChallengeLayout) findViewById(R.id.sliding_layout);
+                if (slider != null) {
+                    slider.setHandleAlpha(alpha);
+                }
+            }
+        };
+
+    private final KeyguardActivityLauncher mActivityLauncher = new KeyguardActivityLauncher() {
+        @Override
+        Context getContext() {
+            return mContext;
+        }
+
+        @Override
+        KeyguardSecurityCallback getCallback() {
+            return mCallback;
+        }
+
+        @Override
+        LockPatternUtils getLockPatternUtils() {
+            return mLockPatternUtils;
+        }
+    };
+
+    private int numWidgets() {
+        final int childCount = mAppWidgetContainer.getChildCount();
+        int widgetCount = 0;
+        for (int i = 0; i < childCount; i++) {
+            if (mAppWidgetContainer.isWidgetPage(i)) {
+                widgetCount++;
+            }
+        }
+        return widgetCount;
+    }
+
+    private void addDefaultWidgets() {
+        if (!mSafeModeEnabled && !widgetsDisabled()) {
+            LayoutInflater inflater = LayoutInflater.from(mContext);
+            View addWidget = inflater.inflate(R.layout.keyguard_add_widget, this, false);
+            mAppWidgetContainer.addWidget(addWidget, 0);
+            View addWidgetButton = addWidget.findViewById(R.id.keyguard_add_widget_view);
+            addWidgetButton.setOnClickListener(new OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    // Pass in an invalid widget id... the picker will allocate an ID for us
+                    mActivityLauncher.launchWidgetPicker(AppWidgetManager.INVALID_APPWIDGET_ID);
+                }
+            });
+        }
+
+        // We currently disable cameras in safe mode because we support loading 3rd party
+        // cameras we can't trust.  TODO: plumb safe mode into camera creation code and only
+        // inflate system-provided camera?
+        if (!mSafeModeEnabled && !cameraDisabledByDpm() && mUserSetupCompleted
+                && mContext.getResources().getBoolean(R.bool.kg_enable_camera_default_widget)) {
+            View cameraWidget =
+                    CameraWidgetFrame.create(mContext, mCameraWidgetCallbacks, mActivityLauncher);
+            if (cameraWidget != null) {
+                mAppWidgetContainer.addWidget(cameraWidget);
+            }
+        }
+
+        enableUserSelectorIfNecessary();
+    }
+
+    /**
+     * Create KeyguardTransportControlView on demand.
+     * @return
+     */
+    private KeyguardTransportControlView getOrCreateTransportControl() {
+        if (mTransportControl == null) {
+            LayoutInflater inflater = LayoutInflater.from(mContext);
+            mTransportControl = (KeyguardTransportControlView)
+                    inflater.inflate(R.layout.keyguard_transport_control_view, this, false);
+        }
+        return mTransportControl;
+    }
+
+    private int getInsertPageIndex() {
+        View addWidget = mAppWidgetContainer.findViewById(R.id.keyguard_add_widget);
+        int insertionIndex = mAppWidgetContainer.indexOfChild(addWidget);
+        if (insertionIndex < 0) {
+            insertionIndex = 0; // no add widget page found
+        } else {
+            insertionIndex++; // place after add widget
+        }
+        return insertionIndex;
+    }
+
+    private void addDefaultStatusWidget(int index) {
+        LayoutInflater inflater = LayoutInflater.from(mContext);
+        View statusWidget = inflater.inflate(R.layout.keyguard_status_view, null, true);
+        mAppWidgetContainer.addWidget(statusWidget, index);
+    }
+
+    private void addWidgetsFromSettings() {
+        if (mSafeModeEnabled || widgetsDisabled()) {
+            addDefaultStatusWidget(0);
+            return;
+        }
+
+        int insertionIndex = getInsertPageIndex();
+
+        // Add user-selected widget
+        final int[] widgets = mLockPatternUtils.getAppWidgets();
+
+        if (widgets == null) {
+            Log.d(TAG, "Problem reading widgets");
+        } else {
+            for (int i = widgets.length -1; i >= 0; i--) {
+                if (widgets[i] == LockPatternUtils.ID_DEFAULT_STATUS_WIDGET) {
+                    addDefaultStatusWidget(insertionIndex);
+                } else {
+                    // We add the widgets from left to right, starting after the first page after
+                    // the add page. We count down, since the order will be persisted from right
+                    // to left, starting after camera.
+                    addWidget(widgets[i], insertionIndex, true);
+                }
+            }
+        }
+    }
+
+    private int allocateIdForDefaultAppWidget() {
+        int appWidgetId;
+        Resources res = getContext().getResources();
+        ComponentName defaultAppWidget = new ComponentName(
+                res.getString(R.string.widget_default_package_name),
+                res.getString(R.string.widget_default_class_name));
+
+        // Note: we don't support configuring the widget
+        appWidgetId = mAppWidgetHost.allocateAppWidgetId();
+
+        try {
+            mAppWidgetManager.bindAppWidgetId(appWidgetId, defaultAppWidget);
+        } catch (IllegalArgumentException e) {
+            Log.e(TAG, "Error when trying to bind default AppWidget: " + e);
+            mAppWidgetHost.deleteAppWidgetId(appWidgetId);
+            appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
+        }
+        return appWidgetId;
+    }
+
+    public void checkAppWidgetConsistency() {
+        // Since this method may bind a widget (which we can't do until boot completed) we
+        // may have to defer it until after boot complete.
+        if (!KeyguardUpdateMonitor.getInstance(mContext).hasBootCompleted()) {
+            mCheckAppWidgetConsistencyOnBootCompleted = true;
+            return;
+        }
+        final int childCount = mAppWidgetContainer.getChildCount();
+        boolean widgetPageExists = false;
+        for (int i = 0; i < childCount; i++) {
+            if (mAppWidgetContainer.isWidgetPage(i)) {
+                widgetPageExists = true;
+                break;
+            }
+        }
+        if (!widgetPageExists) {
+            final int insertPageIndex = getInsertPageIndex();
+
+            final boolean userAddedWidgetsEnabled = !widgetsDisabled();
+
+            boolean addedDefaultAppWidget = false;
+
+            if (!mSafeModeEnabled) {
+                if (userAddedWidgetsEnabled) {
+                    int appWidgetId = allocateIdForDefaultAppWidget();
+                    if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
+                        addedDefaultAppWidget = addWidget(appWidgetId, insertPageIndex, true);
+                    }
+                } else {
+                    // note: even if widgetsDisabledByDpm() returns true, we still bind/create
+                    // the default appwidget if possible
+                    int appWidgetId = mLockPatternUtils.getFallbackAppWidgetId();
+                    if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
+                        appWidgetId = allocateIdForDefaultAppWidget();
+                        if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
+                            mLockPatternUtils.writeFallbackAppWidgetId(appWidgetId);
+                        }
+                    }
+                    if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
+                        addedDefaultAppWidget = addWidget(appWidgetId, insertPageIndex, false);
+                        if (!addedDefaultAppWidget) {
+                            mAppWidgetHost.deleteAppWidgetId(appWidgetId);
+                            mLockPatternUtils.writeFallbackAppWidgetId(
+                                    AppWidgetManager.INVALID_APPWIDGET_ID);
+                        }
+                    }
+                }
+            }
+
+            // Use the built-in status/clock view if we can't inflate the default widget
+            if (!addedDefaultAppWidget) {
+                addDefaultStatusWidget(insertPageIndex);
+            }
+
+            // trigger DB updates only if user-added widgets are enabled
+            if (!mSafeModeEnabled && userAddedWidgetsEnabled) {
+                mAppWidgetContainer.onAddView(
+                        mAppWidgetContainer.getChildAt(insertPageIndex), insertPageIndex);
+            }
+        }
+    }
+
+    Runnable mSwitchPageRunnable = new Runnable() {
+        @Override
+        public void run() {
+           showAppropriateWidgetPage();
+        }
+    };
+
+    static class SavedState extends BaseSavedState {
+        int transportState;
+        int appWidgetToShow = AppWidgetManager.INVALID_APPWIDGET_ID;
+
+        SavedState(Parcelable superState) {
+            super(superState);
+        }
+
+        private SavedState(Parcel in) {
+            super(in);
+            this.transportState = in.readInt();
+            this.appWidgetToShow = in.readInt();
+        }
+
+        @Override
+        public void writeToParcel(Parcel out, int flags) {
+            super.writeToParcel(out, flags);
+            out.writeInt(this.transportState);
+            out.writeInt(this.appWidgetToShow);
+        }
+
+        public static final Parcelable.Creator<SavedState> CREATOR
+                = new Parcelable.Creator<SavedState>() {
+            public SavedState createFromParcel(Parcel in) {
+                return new SavedState(in);
+            }
+
+            public SavedState[] newArray(int size) {
+                return new SavedState[size];
+            }
+        };
+    }
+
+    @Override
+    public Parcelable onSaveInstanceState() {
+        if (DEBUG) Log.d(TAG, "onSaveInstanceState, tstate=" + mTransportState);
+        Parcelable superState = super.onSaveInstanceState();
+        SavedState ss = new SavedState(superState);
+        // If the transport is showing, force it to show it on restore.
+        final boolean showing = mTransportControl != null
+                && mAppWidgetContainer.getWidgetPageIndex(mTransportControl) >= 0;
+        ss.transportState =  showing ? TRANSPORT_VISIBLE : mTransportState;
+        ss.appWidgetToShow = mAppWidgetToShow;
+        return ss;
+    }
+
+    @Override
+    public void onRestoreInstanceState(Parcelable state) {
+        if (!(state instanceof SavedState)) {
+            super.onRestoreInstanceState(state);
+            return;
+        }
+        SavedState ss = (SavedState) state;
+        super.onRestoreInstanceState(ss.getSuperState());
+        mTransportState = (ss.transportState);
+        mAppWidgetToShow = ss.appWidgetToShow;
+        if (DEBUG) Log.d(TAG, "onRestoreInstanceState, transport=" + mTransportState);
+        post(mSwitchPageRunnable);
+    }
+
+    @Override
+    public void onWindowFocusChanged(boolean hasWindowFocus) {
+        super.onWindowFocusChanged(hasWindowFocus);
+        if (DEBUG) Log.d(TAG, "Window is " + (hasWindowFocus ? "focused" : "unfocused"));
+        if (hasWindowFocus && mShowSecurityWhenReturn) {
+            SlidingChallengeLayout slider =
+                (SlidingChallengeLayout) findViewById(R.id.sliding_layout);
+            if (slider != null) {
+                slider.setHandleAlpha(1);
+                slider.showChallenge(true);
+            }
+            mShowSecurityWhenReturn = false;
+        }
+    }
+
+    private void showAppropriateWidgetPage() {
+        int state = mTransportState;
+        ensureTransportPresentOrRemoved(state);
+        int pageToShow = getAppropriateWidgetPage(state);
+        mAppWidgetContainer.setCurrentPage(pageToShow);
+    }
+
+    /**
+     * Examines the current state and adds the transport to the widget pager when the state changes.
+     *
+     * Showing the initial transport and keeping it around is a bit tricky because the signals
+     * coming from music players aren't always clear. Here's how the states are handled:
+     *
+     * {@link TRANSPORT_GONE} means we have no reason to show the transport - remove it if present.
+     *
+     * {@link TRANSPORT_INVISIBLE} means we have potential to show the transport because a music
+     * player is registered but not currently playing music (or we don't know the state yet). The
+     * code adds it conditionally on play state.
+     *
+     * {@link #TRANSPORT_VISIBLE} means a music player is active and transport should be showing.
+     *
+     * Once the transport is showing, we always show it until keyguard is dismissed. This state is
+     * maintained by onSave/RestoreInstanceState(). This state is cleared in
+     * {@link KeyguardViewManager#hide} when keyguard is dismissed, which causes the transport to be
+     * gone when keyguard is restarted until we get an update with the current state.
+     *
+     * @param state
+     */
+    private void ensureTransportPresentOrRemoved(int state) {
+        final boolean showing = getWidgetPosition(R.id.keyguard_transport_control) != -1;
+        final boolean visible = state == TRANSPORT_VISIBLE;
+        final boolean shouldBeVisible = state == TRANSPORT_INVISIBLE && isMusicPlaying(state);
+        if (!showing && (visible || shouldBeVisible)) {
+            if (DEBUGXPORT) Log.v(TAG, "add transport");
+            // insert to left of camera if it exists, otherwise after right-most widget
+            int lastWidget = mAppWidgetContainer.getChildCount() - 1;
+            int position = 0; // handle no widget case
+            if (lastWidget >= 0) {
+                position = mAppWidgetContainer.isCameraPage(lastWidget) ?
+                        lastWidget : lastWidget + 1;
+            }
+            mAppWidgetContainer.addWidget(getOrCreateTransportControl(), position);
+        } else if (showing && state == TRANSPORT_GONE) {
+            if (DEBUGXPORT) Log.v(TAG, "remove transport");
+            mAppWidgetContainer.removeWidget(getOrCreateTransportControl());
+            mTransportControl = null;
+        }
+    }
+
+    private CameraWidgetFrame findCameraPage() {
+        for (int i = mAppWidgetContainer.getChildCount() - 1; i >= 0; i--) {
+            if (mAppWidgetContainer.isCameraPage(i)) {
+                return (CameraWidgetFrame) mAppWidgetContainer.getChildAt(i);
+            }
+        }
+        return null;
+    }
+
+    boolean isMusicPage(int pageIndex) {
+        return pageIndex >= 0 && pageIndex == getWidgetPosition(R.id.keyguard_transport_control);
+    }
+
+    private int getAppropriateWidgetPage(int musicTransportState) {
+        // assumes at least one widget (besides camera + add)
+        if (mAppWidgetToShow != AppWidgetManager.INVALID_APPWIDGET_ID) {
+            final int childCount = mAppWidgetContainer.getChildCount();
+            for (int i = 0; i < childCount; i++) {
+                if (mAppWidgetContainer.getWidgetPageAt(i).getContentAppWidgetId()
+                        == mAppWidgetToShow) {
+                    return i;
+                }
+            }
+            mAppWidgetToShow = AppWidgetManager.INVALID_APPWIDGET_ID;
+        }
+        // if music playing, show transport
+        if (musicTransportState == TRANSPORT_VISIBLE) {
+            if (DEBUG) Log.d(TAG, "Music playing, show transport");
+            return mAppWidgetContainer.getWidgetPageIndex(getOrCreateTransportControl());
+        }
+
+        // else show the right-most widget (except for camera)
+        int rightMost = mAppWidgetContainer.getChildCount() - 1;
+        if (mAppWidgetContainer.isCameraPage(rightMost)) {
+            rightMost--;
+        }
+        if (DEBUG) Log.d(TAG, "Show right-most page " + rightMost);
+        return rightMost;
+    }
+
+    private void enableUserSelectorIfNecessary() {
+        if (!UserManager.supportsMultipleUsers()) {
+            return; // device doesn't support multi-user mode
+        }
+        final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        if (um == null) {
+            Throwable t = new Throwable();
+            t.fillInStackTrace();
+            Log.e(TAG, "user service is null.", t);
+            return;
+        }
+
+        // if there are multiple users, we need to enable to multi-user switcher
+        final List<UserInfo> users = um.getUsers(true);
+        if (users == null) {
+            Throwable t = new Throwable();
+            t.fillInStackTrace();
+            Log.e(TAG, "list of users is null.", t);
+            return;
+        }
+
+        final View multiUserView = findViewById(R.id.keyguard_user_selector);
+        if (multiUserView == null) {
+            Throwable t = new Throwable();
+            t.fillInStackTrace();
+            Log.e(TAG, "can't find user_selector in layout.", t);
+            return;
+        }
+
+        if (users.size() > 1) {
+            if (multiUserView instanceof KeyguardMultiUserSelectorView) {
+                mKeyguardMultiUserSelectorView = (KeyguardMultiUserSelectorView) multiUserView;
+                mKeyguardMultiUserSelectorView.setVisibility(View.VISIBLE);
+                mKeyguardMultiUserSelectorView.addUsers(users);
+                UserSwitcherCallback callback = new UserSwitcherCallback() {
+                    @Override
+                    public void hideSecurityView(int duration) {
+                        mSecurityViewContainer.animate().alpha(0).setDuration(duration);
+                    }
+
+                    @Override
+                    public void showSecurityView() {
+                        mSecurityViewContainer.setAlpha(1.0f);
+                    }
+
+                    @Override
+                    public void showUnlockHint() {
+                        if (mKeyguardSelectorView != null) {
+                            mKeyguardSelectorView.showUsabilityHint();
+                        }
+                    }
+
+                    @Override
+                    public void userActivity() {
+                        if (mViewMediatorCallback != null) {
+                            mViewMediatorCallback.userActivity();
+                        }
+                    }
+                };
+                mKeyguardMultiUserSelectorView.setCallback(callback);
+            } else {
+                Throwable t = new Throwable();
+                t.fillInStackTrace();
+                if (multiUserView == null) {
+                    Log.e(TAG, "could not find the user_selector.", t);
+                } else {
+                    Log.e(TAG, "user_selector is the wrong type.", t);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void cleanUp() {
+        // Make sure we let go of all widgets and their package contexts promptly. If we don't do
+        // this, and the associated application is uninstalled, it can cause a soft reboot.
+        int count = mAppWidgetContainer.getChildCount();
+        for (int i = 0; i < count; i++) {
+            KeyguardWidgetFrame frame = mAppWidgetContainer.getWidgetPageAt(i);
+            frame.removeAllViews();
+        }
+    }
+
+    /**
+     * In general, we enable unlocking the insecure keyguard with the menu key. However, there are
+     * some cases where we wish to disable it, notably when the menu button placement or technology
+     * is prone to false positives.
+     *
+     * @return true if the menu key should be enabled
+     */
+    private static final String ENABLE_MENU_KEY_FILE = "/data/local/enable_menu_key";
+    private boolean shouldEnableMenuKey() {
+        final Resources res = getResources();
+        final boolean configDisabled = res.getBoolean(R.bool.config_disableMenuKeyInLockScreen);
+        final boolean isTestHarness = ActivityManager.isRunningInTestHarness();
+        final boolean fileOverride = (new File(ENABLE_MENU_KEY_FILE)).exists();
+        return !configDisabled || isTestHarness || fileOverride;
+    }
+
+    public void goToWidget(int appWidgetId) {
+        mAppWidgetToShow = appWidgetId;
+        mSwitchPageRunnable.run();
+    }
+
+    public boolean handleMenuKey() {
+        // The following enables the MENU key to work for testing automation
+        if (shouldEnableMenuKey()) {
+            showNextSecurityScreenOrFinish(false);
+            return true;
+        }
+        return false;
+    }
+
+    public boolean handleBackKey() {
+        if (mCurrentSecuritySelection == SecurityMode.Account) {
+            // go back to primary screen and re-disable back
+            setBackButtonEnabled(false);
+            showPrimarySecurityScreen(false /*turningOff*/);
+            return true;
+        }
+        if (mCurrentSecuritySelection != SecurityMode.None) {
+            mCallback.dismiss(false);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     *  Dismisses the keyguard by going to the next screen or making it gone.
+     */
+    public void dismiss() {
+        showNextSecurityScreenOrFinish(false);
+    }
+
+    public void showAssistant() {
+        final Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
+          .getAssistIntent(mContext, true, UserHandle.USER_CURRENT);
+
+        if (intent == null) return;
+
+        final ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext,
+                R.anim.keyguard_action_assist_enter, R.anim.keyguard_action_assist_exit,
+                getHandler(), null);
+
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+        mActivityLauncher.launchActivityWithAnimation(
+                intent, false, opts.toBundle(), null, null);
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardLinearLayout.java b/packages/Keyguard/src/com/android/keyguard/KeyguardLinearLayout.java
new file mode 100644
index 0000000..343fdcb
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardLinearLayout.java
@@ -0,0 +1,46 @@
+/*
+ * 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.keyguard;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.LinearLayout;
+
+/**
+ * A layout that arranges its children into a special type of grid.
+ */
+public class KeyguardLinearLayout extends LinearLayout {
+    int mTopChild = 0;
+
+    public KeyguardLinearLayout(Context context) {
+        this(context, null, 0);
+    }
+
+    public KeyguardLinearLayout(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public KeyguardLinearLayout(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    public void setTopChild(View child) {
+        int top = indexOfChild(child);
+        mTopChild = top;
+        invalidate();
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
new file mode 100644
index 0000000..ad59c02
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
@@ -0,0 +1,318 @@
+/*
+ * 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.keyguard;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.os.BatteryManager;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.util.Slog;
+import android.view.View;
+import android.widget.TextView;
+
+import libcore.util.MutableInt;
+
+import java.lang.ref.WeakReference;
+
+import com.android.internal.widget.LockPatternUtils;
+
+/***
+ * Manages a number of views inside of the given layout. See below for a list of widgets.
+ */
+class KeyguardMessageArea extends TextView {
+    /** Handler token posted with accessibility announcement runnables. */
+    private static final Object ANNOUNCE_TOKEN = new Object();
+
+    /**
+     * Delay before speaking an accessibility announcement. Used to prevent
+     * lift-to-type from interrupting itself.
+     */
+    private static final long ANNOUNCEMENT_DELAY = 250;
+
+    static final int CHARGING_ICON = 0; //R.drawable.ic_lock_idle_charging;
+    static final int BATTERY_LOW_ICON = 0; //R.drawable.ic_lock_idle_low_battery;
+
+    static final int SECURITY_MESSAGE_DURATION = 5000;
+    protected static final int FADE_DURATION = 750;
+
+    private static final String TAG = "KeyguardMessageArea";
+
+    // are we showing battery information?
+    boolean mShowingBatteryInfo = false;
+
+    // is the bouncer up?
+    boolean mShowingBouncer = false;
+
+    // last known plugged in state
+    boolean mCharging = false;
+
+    // last known battery level
+    int mBatteryLevel = 100;
+
+    KeyguardUpdateMonitor mUpdateMonitor;
+
+    // Timeout before we reset the message to show charging/owner info
+    long mTimeout = SECURITY_MESSAGE_DURATION;
+
+    // Shadowed text values
+    protected boolean mBatteryCharged;
+    protected boolean mBatteryIsLow;
+
+    private Handler mHandler;
+
+    CharSequence mMessage;
+    boolean mShowingMessage;
+    private CharSequence mSeparator;
+    private LockPatternUtils mLockPatternUtils;
+
+    Runnable mClearMessageRunnable = new Runnable() {
+        @Override
+        public void run() {
+            mMessage = null;
+            mShowingMessage = false;
+            if (mShowingBouncer) {
+                hideMessage(FADE_DURATION, true);
+            } else {
+                update();
+            }
+        }
+    };
+
+    public static class Helper implements SecurityMessageDisplay {
+        KeyguardMessageArea mMessageArea;
+        Helper(View v) {
+            mMessageArea = (KeyguardMessageArea) v.findViewById(R.id.keyguard_message_area);
+            if (mMessageArea == null) {
+                throw new RuntimeException("Can't find keyguard_message_area in " + v.getClass());
+            }
+        }
+
+        public void setMessage(CharSequence msg, boolean important) {
+            if (!TextUtils.isEmpty(msg) && important) {
+                mMessageArea.mMessage = msg;
+                mMessageArea.securityMessageChanged();
+            }
+        }
+
+        public void setMessage(int resId, boolean important) {
+            if (resId != 0 && important) {
+                mMessageArea.mMessage = mMessageArea.getContext().getResources().getText(resId);
+                mMessageArea.securityMessageChanged();
+            }
+        }
+
+        public void setMessage(int resId, boolean important, Object... formatArgs) {
+            if (resId != 0 && important) {
+                mMessageArea.mMessage = mMessageArea.getContext().getString(resId, formatArgs);
+                mMessageArea.securityMessageChanged();
+            }
+        }
+
+        @Override
+        public void showBouncer(int duration) {
+            mMessageArea.hideMessage(duration, false);
+            mMessageArea.mShowingBouncer = true;
+        }
+
+        @Override
+        public void hideBouncer(int duration) {
+            mMessageArea.showMessage(duration);
+            mMessageArea.mShowingBouncer = false;
+        }
+
+        @Override
+        public void setTimeout(int timeoutMs) {
+            mMessageArea.mTimeout = timeoutMs;
+        }
+    }
+
+    private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
+        @Override
+        public void onRefreshBatteryInfo(KeyguardUpdateMonitor.BatteryStatus status) {
+            mShowingBatteryInfo = status.isPluggedIn() || status.isBatteryLow();
+            mCharging = status.status == BatteryManager.BATTERY_STATUS_CHARGING
+                     || status.status == BatteryManager.BATTERY_STATUS_FULL;
+            mBatteryLevel = status.level;
+            mBatteryCharged = status.isCharged();
+            mBatteryIsLow = status.isBatteryLow();
+            update();
+        }
+    };
+
+    public KeyguardMessageArea(Context context) {
+        this(context, null);
+    }
+
+    public KeyguardMessageArea(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        mLockPatternUtils = new LockPatternUtils(context);
+
+        // This is required to ensure marquee works
+        setSelected(true);
+
+        // Registering this callback immediately updates the battery state, among other things.
+        mUpdateMonitor = KeyguardUpdateMonitor.getInstance(getContext());
+        mUpdateMonitor.registerCallback(mInfoCallback);
+        mHandler = new Handler(Looper.myLooper());
+
+        mSeparator = getResources().getString(R.string.kg_text_message_separator);
+
+        update();
+    }
+
+    public void securityMessageChanged() {
+        setAlpha(1f);
+        mShowingMessage = true;
+        update();
+        mHandler.removeCallbacks(mClearMessageRunnable);
+        if (mTimeout > 0) {
+            mHandler.postDelayed(mClearMessageRunnable, mTimeout);
+        }
+        mHandler.removeCallbacksAndMessages(ANNOUNCE_TOKEN);
+        mHandler.postAtTime(new AnnounceRunnable(this, getText()), ANNOUNCE_TOKEN,
+                (SystemClock.uptimeMillis() + ANNOUNCEMENT_DELAY));
+    }
+
+    /**
+     * Update the status lines based on these rules:
+     * AlarmStatus: Alarm state always gets it's own line.
+     * Status1 is shared between help, battery status and generic unlock instructions,
+     * prioritized in that order.
+     * @param showStatusLines status lines are shown if true
+     */
+    void update() {
+        MutableInt icon = new MutableInt(0);
+        CharSequence status = concat(getChargeInfo(icon), getOwnerInfo(), getCurrentMessage());
+        setCompoundDrawablesWithIntrinsicBounds(icon.value, 0, 0, 0);
+        setText(status);
+    }
+
+    private CharSequence concat(CharSequence... args) {
+        StringBuilder b = new StringBuilder();
+        if (!TextUtils.isEmpty(args[0])) {
+            b.append(args[0]);
+        }
+        for (int i = 1; i < args.length; i++) {
+            CharSequence text = args[i];
+            if (!TextUtils.isEmpty(text)) {
+                if (b.length() > 0) {
+                    b.append(mSeparator);
+                }
+                b.append(text);
+            }
+        }
+        return b.toString();
+    }
+
+    CharSequence getCurrentMessage() {
+        return mShowingMessage ? mMessage : null;
+    }
+
+    String getOwnerInfo() {
+        ContentResolver res = getContext().getContentResolver();
+        String info = null;
+        final boolean ownerInfoEnabled = mLockPatternUtils.isOwnerInfoEnabled();
+        if (ownerInfoEnabled && !mShowingMessage) {
+            info = mLockPatternUtils.getOwnerInfo(mLockPatternUtils.getCurrentUser());
+        }
+        return info;
+    }
+
+    private CharSequence getChargeInfo(MutableInt icon) {
+        CharSequence string = null;
+        if (mShowingBatteryInfo && !mShowingMessage) {
+            // Battery status
+            if (mCharging) {
+                // Charging, charged or waiting to charge.
+                string = getContext().getString(mBatteryCharged
+                        ? R.string.keyguard_charged
+                        : R.string.keyguard_plugged_in, mBatteryLevel);
+                icon.value = CHARGING_ICON;
+            } else if (mBatteryIsLow) {
+                // Battery is low
+                string = getContext().getString(R.string.keyguard_low_battery);
+                icon.value = BATTERY_LOW_ICON;
+            }
+        }
+        return string;
+    }
+
+    private void hideMessage(int duration, boolean thenUpdate) {
+        if (duration > 0) {
+            Animator anim = ObjectAnimator.ofFloat(this, "alpha", 0f);
+            anim.setDuration(duration);
+            if (thenUpdate) {
+                anim.addListener(new AnimatorListenerAdapter() {
+                        @Override
+                            public void onAnimationEnd(Animator animation) {
+                            update();
+                        }
+                });
+            }
+            anim.start();
+        } else {
+            setAlpha(0f);
+            if (thenUpdate) {
+                update();
+            }
+        }
+    }
+
+    private void showMessage(int duration) {
+        if (duration > 0) {
+            Animator anim = ObjectAnimator.ofFloat(this, "alpha", 1f);
+            anim.setDuration(duration);
+            anim.start();
+        } else {
+            setAlpha(1f);
+        }
+    }
+
+    /**
+     * Runnable used to delay accessibility announcements.
+     */
+    private static class AnnounceRunnable implements Runnable {
+        private final WeakReference<View> mHost;
+        private final CharSequence mTextToAnnounce;
+
+        public AnnounceRunnable(View host, CharSequence textToAnnounce) {
+            mHost = new WeakReference<View>(host);
+            mTextToAnnounce = textToAnnounce;
+        }
+
+        @Override
+        public void run() {
+            final View host = mHost.get();
+            if (host != null) {
+                host.announceForAccessibility(mTextToAnnounce);
+            }
+        }
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardMultiUserAvatar.java b/packages/Keyguard/src/com/android/keyguard/KeyguardMultiUserAvatar.java
new file mode 100644
index 0000000..aa2ae0e
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardMultiUserAvatar.java
@@ -0,0 +1,245 @@
+/*
+ * 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.keyguard;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.os.UserManager;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+class KeyguardMultiUserAvatar extends FrameLayout {
+    private static final String TAG = KeyguardMultiUserAvatar.class.getSimpleName();
+    private static final boolean DEBUG = KeyguardHostView.DEBUG;
+
+    private ImageView mUserImage;
+    private TextView mUserName;
+    private UserInfo mUserInfo;
+    private static final float ACTIVE_ALPHA = 1.0f;
+    private static final float INACTIVE_ALPHA = 1.0f;
+    private static final float ACTIVE_SCALE = 1.5f;
+    private static final float ACTIVE_TEXT_ALPHA = 0f;
+    private static final float INACTIVE_TEXT_ALPHA = 0.5f;
+    private static final int SWITCH_ANIMATION_DURATION = 150;
+
+    private final float mActiveAlpha;
+    private final float mActiveScale;
+    private final float mActiveTextAlpha;
+    private final float mInactiveAlpha;
+    private final float mInactiveTextAlpha;
+    private final float mShadowRadius;
+    private final float mStroke;
+    private final float mIconSize;
+    private final int mFrameColor;
+    private final int mFrameShadowColor;
+    private final int mTextColor;
+    private final int mHighlightColor;
+
+    private boolean mTouched;
+
+    private boolean mActive;
+    private boolean mInit = true;
+    private KeyguardMultiUserSelectorView mUserSelector;
+    private KeyguardCircleFramedDrawable mFramed;
+    private boolean mPressLock;
+    private UserManager mUserManager;
+
+    public static KeyguardMultiUserAvatar fromXml(int resId, Context context,
+            KeyguardMultiUserSelectorView userSelector, UserInfo info) {
+        KeyguardMultiUserAvatar icon = (KeyguardMultiUserAvatar)
+                LayoutInflater.from(context).inflate(resId, userSelector, false);
+
+        icon.init(info, userSelector);
+        return icon;
+    }
+
+    public KeyguardMultiUserAvatar(Context context) {
+        this(context, null, 0);
+    }
+
+    public KeyguardMultiUserAvatar(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public KeyguardMultiUserAvatar(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        Resources res = mContext.getResources();
+        mTextColor = res.getColor(R.color.keyguard_avatar_nick_color);
+        mIconSize = res.getDimension(R.dimen.keyguard_avatar_size);
+        mStroke = res.getDimension(R.dimen.keyguard_avatar_frame_stroke_width);
+        mShadowRadius = res.getDimension(R.dimen.keyguard_avatar_frame_shadow_radius);
+        mFrameColor = res.getColor(R.color.keyguard_avatar_frame_color);
+        mFrameShadowColor = res.getColor(R.color.keyguard_avatar_frame_shadow_color);
+        mHighlightColor = res.getColor(R.color.keyguard_avatar_frame_pressed_color);
+        mActiveTextAlpha = ACTIVE_TEXT_ALPHA;
+        mInactiveTextAlpha = INACTIVE_TEXT_ALPHA;
+        mActiveScale = ACTIVE_SCALE;
+        mActiveAlpha = ACTIVE_ALPHA;
+        mInactiveAlpha = INACTIVE_ALPHA;
+        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+
+        mTouched = false;
+
+        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
+    }
+
+    protected String rewriteIconPath(String path) {
+        return path;
+    }
+
+    public void init(UserInfo user, KeyguardMultiUserSelectorView userSelector) {
+        mUserInfo = user;
+        mUserSelector = userSelector;
+
+        mUserImage = (ImageView) findViewById(R.id.keyguard_user_avatar);
+        mUserName = (TextView) findViewById(R.id.keyguard_user_name);
+
+        mFramed = (KeyguardCircleFramedDrawable)
+                KeyguardViewMediator.getAvatarCache().get(user.id);
+
+        // If we can't find it or the params don't match, create the drawable again
+        if (mFramed == null
+                || !mFramed.verifyParams(mIconSize, mFrameColor, mStroke, mFrameShadowColor,
+                        mShadowRadius, mHighlightColor)) {
+            Bitmap icon = null;
+            try {
+                icon = mUserManager.getUserIcon(user.id);
+            } catch (Exception e) {
+                if (DEBUG) Log.d(TAG, "failed to get profile icon " + user, e);
+            }
+
+            if (icon == null) {
+                icon = BitmapFactory.decodeResource(mContext.getResources(),
+                        com.android.internal.R.drawable.ic_contact_picture);
+            }
+
+            mFramed = new KeyguardCircleFramedDrawable(icon, (int) mIconSize, mFrameColor, mStroke,
+                    mFrameShadowColor, mShadowRadius, mHighlightColor);
+            KeyguardViewMediator.getAvatarCache().put(user.id, mFramed);
+        }
+
+        mFramed.reset();
+
+        mUserImage.setImageDrawable(mFramed);
+        mUserName.setText(mUserInfo.name);
+        setOnClickListener(mUserSelector);
+        mInit = false;
+    }
+
+    public void setActive(boolean active, boolean animate, final Runnable onComplete) {
+        if (mActive != active || mInit) {
+            mActive = active;
+
+            if (active) {
+                KeyguardLinearLayout parent = (KeyguardLinearLayout) getParent();
+                parent.setTopChild(this);
+                // TODO: Create an appropriate asset when string changes are possible.
+                setContentDescription(mUserName.getText()
+                        + ". " + mContext.getString(R.string.user_switched, ""));
+            } else {
+                setContentDescription(mUserName.getText());
+            }
+        }
+        updateVisualsForActive(mActive, animate, SWITCH_ANIMATION_DURATION, onComplete);
+    }
+
+    void updateVisualsForActive(boolean active, boolean animate, int duration,
+            final Runnable onComplete) {
+        final float finalAlpha = active ? mActiveAlpha : mInactiveAlpha;
+        final float initAlpha = active ? mInactiveAlpha : mActiveAlpha;
+        final float finalScale = active ? 1f : 1f / mActiveScale;
+        final float initScale = mFramed.getScale();
+        final int finalTextAlpha = active ? (int) (mActiveTextAlpha * 255) :
+                (int) (mInactiveTextAlpha * 255);
+        final int initTextAlpha = active ? (int) (mInactiveTextAlpha * 255) :
+                (int) (mActiveTextAlpha * 255);
+        int textColor = mTextColor;
+        mUserName.setTextColor(textColor);
+
+        if (animate && mTouched) {
+            ValueAnimator va = ValueAnimator.ofFloat(0f, 1f);
+            va.addUpdateListener(new AnimatorUpdateListener() {
+                @Override
+                public void onAnimationUpdate(ValueAnimator animation) {
+                    float r = animation.getAnimatedFraction();
+                    float scale = (1 - r) * initScale + r * finalScale;
+                    float alpha = (1 - r) * initAlpha + r * finalAlpha;
+                    int textAlpha = (int) ((1 - r) * initTextAlpha + r * finalTextAlpha);
+                    mFramed.setScale(scale);
+                    mUserImage.setAlpha(alpha);
+                    mUserName.setTextColor(Color.argb(textAlpha, 255, 255, 255));
+                    mUserImage.invalidate();
+                }
+            });
+            va.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    if (onComplete != null) {
+                        onComplete.run();
+                    }
+                }
+            });
+            va.setDuration(duration);
+            va.start();
+        } else {
+            mFramed.setScale(finalScale);
+            mUserImage.setAlpha(finalAlpha);
+            mUserName.setTextColor(Color.argb(finalTextAlpha, 255, 255, 255));
+            if (onComplete != null) {
+                post(onComplete);
+            }
+        }
+
+        mTouched = true;
+    }
+
+    @Override
+    public void setPressed(boolean pressed) {
+        if (mPressLock && !pressed) {
+            return;
+        }
+
+        if (mPressLock || !pressed || isClickable()) {
+            super.setPressed(pressed);
+            mFramed.setPressed(pressed);
+            mUserImage.invalidate();
+        }
+    }
+
+    public void lockPressed(boolean pressed) {
+        mPressLock = pressed;
+        setPressed(pressed);
+    }
+
+    public UserInfo getUserInfo() {
+        return mUserInfo;
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardMultiUserSelectorView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardMultiUserSelectorView.java
new file mode 100644
index 0000000..7975d8e
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardMultiUserSelectorView.java
@@ -0,0 +1,166 @@
+/*
+ * 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.keyguard;
+
+import android.app.ActivityManagerNative;
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.os.RemoteException;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+
+public class KeyguardMultiUserSelectorView extends FrameLayout implements View.OnClickListener {
+    private static final String TAG = "KeyguardMultiUserSelectorView";
+
+    private ViewGroup mUsersGrid;
+    private KeyguardMultiUserAvatar mActiveUserAvatar;
+    private KeyguardHostView.UserSwitcherCallback mCallback;
+    private static final int FADE_OUT_ANIMATION_DURATION = 100;
+
+    public KeyguardMultiUserSelectorView(Context context) {
+        this(context, null, 0);
+    }
+
+    public KeyguardMultiUserSelectorView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public KeyguardMultiUserSelectorView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    protected void onFinishInflate () {
+        mUsersGrid = (ViewGroup) findViewById(R.id.keyguard_users_grid);
+        mUsersGrid.removeAllViews();
+        setClipChildren(false);
+        setClipToPadding(false);
+
+    }
+
+    public void setCallback(KeyguardHostView.UserSwitcherCallback callback) {
+        mCallback = callback;
+    }
+
+    public void addUsers(Collection<UserInfo> userList) {
+        UserInfo activeUser;
+        try {
+            activeUser = ActivityManagerNative.getDefault().getCurrentUser();
+        } catch (RemoteException re) {
+            activeUser = null;
+        }
+
+        ArrayList<UserInfo> users = new ArrayList<UserInfo>(userList);
+        Collections.sort(users, mOrderAddedComparator);
+
+        for (UserInfo user: users) {
+            KeyguardMultiUserAvatar uv = createAndAddUser(user);
+            if (user.id == activeUser.id) {
+                mActiveUserAvatar = uv;
+            }
+            uv.setActive(false, false, null);
+        }
+        mActiveUserAvatar.lockPressed(true);
+    }
+
+    public void finalizeActiveUserView(boolean animate) {
+        if (animate) {
+            getHandler().postDelayed(new Runnable() {
+                    @Override
+                        public void run() {
+                        finalizeActiveUserNow(true);
+                    }
+                }, 500);
+        } else {
+            finalizeActiveUserNow(animate);
+        }
+    }
+
+    void finalizeActiveUserNow(boolean animate) {
+        mActiveUserAvatar.lockPressed(false);
+        mActiveUserAvatar.setActive(true, animate, null);
+    }
+
+    Comparator<UserInfo> mOrderAddedComparator = new Comparator<UserInfo>() {
+        @Override
+        public int compare(UserInfo lhs, UserInfo rhs) {
+            return (lhs.serialNumber - rhs.serialNumber);
+        }
+    };
+
+    private KeyguardMultiUserAvatar createAndAddUser(UserInfo user) {
+        KeyguardMultiUserAvatar uv = KeyguardMultiUserAvatar.fromXml(
+                R.layout.keyguard_multi_user_avatar, mContext, this, user);
+        mUsersGrid.addView(uv);
+        return uv;
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent event) {
+        if(event.getActionMasked() != MotionEvent.ACTION_CANCEL && mCallback != null) {
+            mCallback.userActivity();
+        }
+        return false;
+    }
+
+    private void setAllClickable(boolean clickable)
+    {
+        for(int i = 0; i < mUsersGrid.getChildCount(); i++) {
+            View v = mUsersGrid.getChildAt(i);
+            v.setClickable(clickable);
+            v.setPressed(false);
+        }
+    }
+
+    @Override
+    public void onClick(View v) {
+        if (!(v instanceof KeyguardMultiUserAvatar)) return;
+        final KeyguardMultiUserAvatar avatar = (KeyguardMultiUserAvatar) v;
+        if (avatar.isClickable()) { // catch race conditions
+            if (mActiveUserAvatar == avatar) {
+                // If they click the currently active user, show the unlock hint
+                mCallback.showUnlockHint();
+                return;
+            } else {
+                // Reset the previously active user to appear inactive
+                mCallback.hideSecurityView(FADE_OUT_ANIMATION_DURATION);
+                setAllClickable(false);
+                avatar.lockPressed(true);
+                mActiveUserAvatar.setActive(false, true, new Runnable() {
+                    @Override
+                    public void run() {
+                        mActiveUserAvatar = avatar;
+                        try {
+                            ActivityManagerNative.getDefault()
+                                    .switchUser(avatar.getUserInfo().id);
+                        } catch (RemoteException re) {
+                            Log.e(TAG, "Couldn't switch user " + re);
+                        }
+                    }
+                });
+            }
+        }
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java
new file mode 100644
index 0000000..3d1c3f3
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java
@@ -0,0 +1,118 @@
+/*
+ * 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.keyguard;
+
+import android.content.Context;
+import android.text.Editable;
+import android.text.InputType;
+import android.text.TextWatcher;
+import android.text.method.DigitsKeyListener;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.TextView.OnEditorActionListener;
+
+/**
+ * Displays a PIN pad for unlocking.
+ */
+public class KeyguardPINView extends KeyguardAbsKeyInputView
+        implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
+
+    public KeyguardPINView(Context context) {
+        this(context, null);
+    }
+
+    public KeyguardPINView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    protected void resetState() {
+        if (KeyguardUpdateMonitor.getInstance(mContext).getMaxBiometricUnlockAttemptsReached()) {
+            mSecurityMessageDisplay.setMessage(R.string.faceunlock_multiple_failures, true);
+        } else {
+            mSecurityMessageDisplay.setMessage(R.string.kg_pin_instructions, false);
+        }
+        mPasswordEntry.setEnabled(true);
+    }
+
+    @Override
+    protected int getPasswordTextViewId() {
+        return R.id.pinEntry;
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+
+        final View ok = findViewById(R.id.key_enter);
+        if (ok != null) {
+            ok.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    doHapticKeyClick();
+                    if (mPasswordEntry.isEnabled()) {
+                        verifyPasswordAndUnlock();
+                    }
+                }
+            });
+            ok.setOnHoverListener(new LiftToActivateListener(getContext()));
+        }
+
+        // The delete button is of the PIN keyboard itself in some (e.g. tablet) layouts,
+        // not a separate view
+        View pinDelete = findViewById(R.id.delete_button);
+        if (pinDelete != null) {
+            pinDelete.setVisibility(View.VISIBLE);
+            pinDelete.setOnClickListener(new OnClickListener() {
+                public void onClick(View v) {
+                    // check for time-based lockouts
+                    if (mPasswordEntry.isEnabled()) {
+                        CharSequence str = mPasswordEntry.getText();
+                        if (str.length() > 0) {
+                            mPasswordEntry.setText(str.subSequence(0, str.length()-1));
+                        }
+                    }
+                    doHapticKeyClick();
+                }
+            });
+            pinDelete.setOnLongClickListener(new View.OnLongClickListener() {
+                public boolean onLongClick(View v) {
+                    // check for time-based lockouts
+                    if (mPasswordEntry.isEnabled()) {
+                        mPasswordEntry.setText("");
+                    }
+                    doHapticKeyClick();
+                    return true;
+                }
+            });
+        }
+
+        mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance());
+        mPasswordEntry.setInputType(InputType.TYPE_CLASS_NUMBER
+                | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
+
+        mPasswordEntry.requestFocus();
+    }
+
+    @Override
+    public void showUsabilityHint() {
+    }
+
+    @Override
+    public int getWrongPasswordStringId() {
+        return R.string.kg_wrong_pin;
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
new file mode 100644
index 0000000..4e3568b
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
@@ -0,0 +1,207 @@
+/*
+ * 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.keyguard;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.text.Editable;
+import android.text.InputType;
+import android.text.TextWatcher;
+import android.text.method.DigitsKeyListener;
+import android.text.method.TextKeyListener;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodManager;
+import android.view.inputmethod.InputMethodSubtype;
+import android.widget.TextView.OnEditorActionListener;
+
+import com.android.internal.widget.PasswordEntryKeyboardHelper;
+import com.android.internal.widget.PasswordEntryKeyboardView;
+
+import java.util.List;
+/**
+ * Displays an alphanumeric (latin-1) key entry for the user to enter
+ * an unlock password
+ */
+
+public class KeyguardPasswordView extends KeyguardAbsKeyInputView
+        implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
+
+    private final boolean mShowImeAtScreenOn;
+
+    InputMethodManager mImm;
+
+    public KeyguardPasswordView(Context context) {
+        this(context, null);
+    }
+
+    public KeyguardPasswordView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        mShowImeAtScreenOn = context.getResources().
+                getBoolean(R.bool.kg_show_ime_at_screen_on);
+    }
+
+    protected void resetState() {
+        mSecurityMessageDisplay.setMessage(R.string.kg_password_instructions, false);
+        mPasswordEntry.setEnabled(true);
+    }
+
+    @Override
+    protected int getPasswordTextViewId() {
+        return R.id.passwordEntry;
+    }
+
+    @Override
+    public boolean needsInput() {
+        return true;
+    }
+
+    @Override
+    public void onResume(int reason) {
+        super.onResume(reason);
+        mPasswordEntry.requestFocus();
+        if (reason != KeyguardSecurityView.SCREEN_ON || mShowImeAtScreenOn) {
+            mImm.showSoftInput(mPasswordEntry, InputMethodManager.SHOW_IMPLICIT);
+        }
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        mImm.hideSoftInputFromWindow(getWindowToken(), 0);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+
+        boolean imeOrDeleteButtonVisible = false;
+
+        mImm = (InputMethodManager) getContext().getSystemService(
+                Context.INPUT_METHOD_SERVICE);
+
+        mPasswordEntry.setKeyListener(TextKeyListener.getInstance());
+        mPasswordEntry.setInputType(InputType.TYPE_CLASS_TEXT
+                | InputType.TYPE_TEXT_VARIATION_PASSWORD);
+
+        // Poke the wakelock any time the text is selected or modified
+        mPasswordEntry.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                mCallback.userActivity(0); // TODO: customize timeout for text?
+            }
+        });
+
+        mPasswordEntry.addTextChangedListener(new TextWatcher() {
+            public void onTextChanged(CharSequence s, int start, int before, int count) {
+            }
+
+            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+            }
+
+            public void afterTextChanged(Editable s) {
+                if (mCallback != null) {
+                    mCallback.userActivity(0);
+                }
+            }
+        });
+
+        mPasswordEntry.requestFocus();
+
+        // If there's more than one IME, enable the IME switcher button
+        View switchImeButton = findViewById(R.id.switch_ime_button);
+        if (switchImeButton != null && hasMultipleEnabledIMEsOrSubtypes(mImm, false)) {
+            switchImeButton.setVisibility(View.VISIBLE);
+            imeOrDeleteButtonVisible = true;
+            switchImeButton.setOnClickListener(new OnClickListener() {
+                public void onClick(View v) {
+                    mCallback.userActivity(0); // Leave the screen on a bit longer
+                    mImm.showInputMethodPicker();
+                }
+            });
+        }
+
+        // If no icon is visible, reset the start margin on the password field so the text is
+        // still centered.
+        if (!imeOrDeleteButtonVisible) {
+            android.view.ViewGroup.LayoutParams params = mPasswordEntry.getLayoutParams();
+            if (params instanceof MarginLayoutParams) {
+                final MarginLayoutParams mlp = (MarginLayoutParams) params;
+                mlp.setMarginStart(0);
+                mPasswordEntry.setLayoutParams(params);
+            }
+        }
+    }
+
+    /**
+     * Method adapted from com.android.inputmethod.latin.Utils
+     *
+     * @param imm The input method manager
+     * @param shouldIncludeAuxiliarySubtypes
+     * @return true if we have multiple IMEs to choose from
+     */
+    private boolean hasMultipleEnabledIMEsOrSubtypes(InputMethodManager imm,
+            final boolean shouldIncludeAuxiliarySubtypes) {
+        final List<InputMethodInfo> enabledImis = imm.getEnabledInputMethodList();
+
+        // Number of the filtered IMEs
+        int filteredImisCount = 0;
+
+        for (InputMethodInfo imi : enabledImis) {
+            // We can return true immediately after we find two or more filtered IMEs.
+            if (filteredImisCount > 1) return true;
+            final List<InputMethodSubtype> subtypes =
+                    imm.getEnabledInputMethodSubtypeList(imi, true);
+            // IMEs that have no subtypes should be counted.
+            if (subtypes.isEmpty()) {
+                ++filteredImisCount;
+                continue;
+            }
+
+            int auxCount = 0;
+            for (InputMethodSubtype subtype : subtypes) {
+                if (subtype.isAuxiliary()) {
+                    ++auxCount;
+                }
+            }
+            final int nonAuxCount = subtypes.size() - auxCount;
+
+            // IMEs that have one or more non-auxiliary subtypes should be counted.
+            // If shouldIncludeAuxiliarySubtypes is true, IMEs that have two or more auxiliary
+            // subtypes should be counted as well.
+            if (nonAuxCount > 0 || (shouldIncludeAuxiliarySubtypes && auxCount > 1)) {
+                ++filteredImisCount;
+                continue;
+            }
+        }
+
+        return filteredImisCount > 1
+        // imm.getEnabledInputMethodSubtypeList(null, false) will return the current IME's enabled
+        // input method subtype (The current IME should be LatinIME.)
+                || imm.getEnabledInputMethodSubtypeList(null, false).size() > 1;
+    }
+
+    @Override
+    public void showUsabilityHint() {
+    }
+
+    @Override
+    public int getWrongPasswordStringId() {
+        return R.string.kg_wrong_password;
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
new file mode 100644
index 0000000..e7f1259
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
@@ -0,0 +1,411 @@
+/*
+ * 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.keyguard;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.AccountManagerCallback;
+import android.accounts.AccountManagerFuture;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
+import android.content.Context;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.os.CountDownTimer;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.Button;
+import android.widget.LinearLayout;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.LockPatternView;
+
+import java.io.IOException;
+import java.util.List;
+
+public class KeyguardPatternView extends LinearLayout implements KeyguardSecurityView {
+
+    private static final String TAG = "SecurityPatternView";
+    private static final boolean DEBUG = false;
+
+    // how long before we clear the wrong pattern
+    private static final int PATTERN_CLEAR_TIMEOUT_MS = 2000;
+
+    // how long we stay awake after each key beyond MIN_PATTERN_BEFORE_POKE_WAKELOCK
+    private static final int UNLOCK_PATTERN_WAKE_INTERVAL_MS = 7000;
+
+    // how long we stay awake after the user hits the first dot.
+    private static final int UNLOCK_PATTERN_WAKE_INTERVAL_FIRST_DOTS_MS = 2000;
+
+    // how many cells the user has to cross before we poke the wakelock
+    private static final int MIN_PATTERN_BEFORE_POKE_WAKELOCK = 2;
+
+    private int mFailedPatternAttemptsSinceLastTimeout = 0;
+    private int mTotalFailedPatternAttempts = 0;
+    private CountDownTimer mCountdownTimer = null;
+    private LockPatternUtils mLockPatternUtils;
+    private LockPatternView mLockPatternView;
+    private Button mForgotPatternButton;
+    private KeyguardSecurityCallback mCallback;
+    private boolean mEnableFallback;
+
+    /**
+     * Keeps track of the last time we poked the wake lock during dispatching of the touch event.
+     * Initialized to something guaranteed to make us poke the wakelock when the user starts
+     * drawing the pattern.
+     * @see #dispatchTouchEvent(android.view.MotionEvent)
+     */
+    private long mLastPokeTime = -UNLOCK_PATTERN_WAKE_INTERVAL_MS;
+
+    /**
+     * Useful for clearing out the wrong pattern after a delay
+     */
+    private Runnable mCancelPatternRunnable = new Runnable() {
+        public void run() {
+            mLockPatternView.clearPattern();
+        }
+    };
+    private Rect mTempRect = new Rect();
+    private SecurityMessageDisplay mSecurityMessageDisplay;
+    private View mEcaView;
+    private Drawable mBouncerFrame;
+
+    enum FooterMode {
+        Normal,
+        ForgotLockPattern,
+        VerifyUnlocked
+    }
+
+    public KeyguardPatternView(Context context) {
+        this(context, null);
+    }
+
+    public KeyguardPatternView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public void setKeyguardCallback(KeyguardSecurityCallback callback) {
+        mCallback = callback;
+    }
+
+    public void setLockPatternUtils(LockPatternUtils utils) {
+        mLockPatternUtils = utils;
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mLockPatternUtils = mLockPatternUtils == null
+                ? new LockPatternUtils(mContext) : mLockPatternUtils;
+
+        mLockPatternView = (LockPatternView) findViewById(R.id.lockPatternView);
+        mLockPatternView.setSaveEnabled(false);
+        mLockPatternView.setFocusable(false);
+        mLockPatternView.setOnPatternListener(new UnlockPatternListener());
+
+        // stealth mode will be the same for the life of this screen
+        mLockPatternView.setInStealthMode(!mLockPatternUtils.isVisiblePatternEnabled());
+
+        // vibrate mode will be the same for the life of this screen
+        mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled());
+
+        mForgotPatternButton = (Button) findViewById(R.id.forgot_password_button);
+        // note: some configurations don't have an emergency call area
+        if (mForgotPatternButton != null) {
+            mForgotPatternButton.setText(R.string.kg_forgot_pattern_button_text);
+            mForgotPatternButton.setOnClickListener(new OnClickListener() {
+                public void onClick(View v) {
+                    mCallback.showBackupSecurity();
+                }
+            });
+        }
+
+        setFocusableInTouchMode(true);
+
+        maybeEnableFallback(mContext);
+        mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
+        mEcaView = findViewById(R.id.keyguard_selector_fade_container);
+        View bouncerFrameView = findViewById(R.id.keyguard_bouncer_frame);
+        if (bouncerFrameView != null) {
+            mBouncerFrame = bouncerFrameView.getBackground();
+        }
+    }
+
+    private void updateFooter(FooterMode mode) {
+        if (mForgotPatternButton == null) return; // no ECA? no footer
+
+        switch (mode) {
+            case Normal:
+                if (DEBUG) Log.d(TAG, "mode normal");
+                mForgotPatternButton.setVisibility(View.GONE);
+                break;
+            case ForgotLockPattern:
+                if (DEBUG) Log.d(TAG, "mode ForgotLockPattern");
+                mForgotPatternButton.setVisibility(View.VISIBLE);
+                break;
+            case VerifyUnlocked:
+                if (DEBUG) Log.d(TAG, "mode VerifyUnlocked");
+                mForgotPatternButton.setVisibility(View.GONE);
+        }
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        boolean result = super.onTouchEvent(ev);
+        // as long as the user is entering a pattern (i.e sending a touch event that was handled
+        // by this screen), keep poking the wake lock so that the screen will stay on.
+        final long elapsed = SystemClock.elapsedRealtime() - mLastPokeTime;
+        if (result && (elapsed > (UNLOCK_PATTERN_WAKE_INTERVAL_MS - 100))) {
+            mLastPokeTime = SystemClock.elapsedRealtime();
+        }
+        mTempRect.set(0, 0, 0, 0);
+        offsetRectIntoDescendantCoords(mLockPatternView, mTempRect);
+        ev.offsetLocation(mTempRect.left, mTempRect.top);
+        result = mLockPatternView.dispatchTouchEvent(ev) || result;
+        ev.offsetLocation(-mTempRect.left, -mTempRect.top);
+        return result;
+    }
+
+    public void reset() {
+        // reset lock pattern
+        mLockPatternView.enableInput();
+        mLockPatternView.setEnabled(true);
+        mLockPatternView.clearPattern();
+
+        // if the user is currently locked out, enforce it.
+        long deadline = mLockPatternUtils.getLockoutAttemptDeadline();
+        if (deadline != 0) {
+            handleAttemptLockout(deadline);
+        } else {
+            displayDefaultSecurityMessage();
+        }
+
+        // the footer depends on how many total attempts the user has failed
+        if (mCallback.isVerifyUnlockOnly()) {
+            updateFooter(FooterMode.VerifyUnlocked);
+        } else if (mEnableFallback &&
+                (mTotalFailedPatternAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT)) {
+            updateFooter(FooterMode.ForgotLockPattern);
+        } else {
+            updateFooter(FooterMode.Normal);
+        }
+
+    }
+
+    private void displayDefaultSecurityMessage() {
+        if (KeyguardUpdateMonitor.getInstance(mContext).getMaxBiometricUnlockAttemptsReached()) {
+            mSecurityMessageDisplay.setMessage(R.string.faceunlock_multiple_failures, true);
+        } else {
+            mSecurityMessageDisplay.setMessage(R.string.kg_pattern_instructions, false);
+        }
+    }
+
+    @Override
+    public void showUsabilityHint() {
+    }
+
+    /** TODO: hook this up */
+    public void cleanUp() {
+        if (DEBUG) Log.v(TAG, "Cleanup() called on " + this);
+        mLockPatternUtils = null;
+        mLockPatternView.setOnPatternListener(null);
+    }
+
+    @Override
+    public void onWindowFocusChanged(boolean hasWindowFocus) {
+        super.onWindowFocusChanged(hasWindowFocus);
+        if (hasWindowFocus) {
+            // when timeout dialog closes we want to update our state
+            reset();
+        }
+    }
+
+    private class UnlockPatternListener implements LockPatternView.OnPatternListener {
+
+        public void onPatternStart() {
+            mLockPatternView.removeCallbacks(mCancelPatternRunnable);
+        }
+
+        public void onPatternCleared() {
+        }
+
+        public void onPatternCellAdded(List<LockPatternView.Cell> pattern) {
+            // To guard against accidental poking of the wakelock, look for
+            // the user actually trying to draw a pattern of some minimal length.
+            if (pattern.size() > MIN_PATTERN_BEFORE_POKE_WAKELOCK) {
+                mCallback.userActivity(UNLOCK_PATTERN_WAKE_INTERVAL_MS);
+            } else {
+                // Give just a little extra time if they hit one of the first few dots
+                mCallback.userActivity(UNLOCK_PATTERN_WAKE_INTERVAL_FIRST_DOTS_MS);
+            }
+        }
+
+        public void onPatternDetected(List<LockPatternView.Cell> pattern) {
+            if (mLockPatternUtils.checkPattern(pattern)) {
+                mCallback.reportSuccessfulUnlockAttempt();
+                mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Correct);
+                mTotalFailedPatternAttempts = 0;
+                mCallback.dismiss(true);
+            } else {
+                if (pattern.size() > MIN_PATTERN_BEFORE_POKE_WAKELOCK) {
+                    mCallback.userActivity(UNLOCK_PATTERN_WAKE_INTERVAL_MS);
+                }
+                mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Wrong);
+                if (pattern.size() >= LockPatternUtils.MIN_PATTERN_REGISTER_FAIL) {
+                    mTotalFailedPatternAttempts++;
+                    mFailedPatternAttemptsSinceLastTimeout++;
+                    mCallback.reportFailedUnlockAttempt();
+                }
+                if (mFailedPatternAttemptsSinceLastTimeout
+                        >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) {
+                    long deadline = mLockPatternUtils.setLockoutAttemptDeadline();
+                    handleAttemptLockout(deadline);
+                } else {
+                    mSecurityMessageDisplay.setMessage(R.string.kg_wrong_pattern, true);
+                    mLockPatternView.postDelayed(mCancelPatternRunnable, PATTERN_CLEAR_TIMEOUT_MS);
+                }
+            }
+        }
+    }
+
+    private void maybeEnableFallback(Context context) {
+        // Ask the account manager if we have an account that can be used as a
+        // fallback in case the user forgets his pattern.
+        AccountAnalyzer accountAnalyzer = new AccountAnalyzer(AccountManager.get(context));
+        accountAnalyzer.start();
+    }
+
+    private class AccountAnalyzer implements AccountManagerCallback<Bundle> {
+        private final AccountManager mAccountManager;
+        private final Account[] mAccounts;
+        private int mAccountIndex;
+
+        private AccountAnalyzer(AccountManager accountManager) {
+            mAccountManager = accountManager;
+            mAccounts = accountManager.getAccountsByTypeAsUser("com.google",
+                    new UserHandle(mLockPatternUtils.getCurrentUser()));
+        }
+
+        private void next() {
+            // if we are ready to enable the fallback or if we depleted the list of accounts
+            // then finish and get out
+            if (mEnableFallback || mAccountIndex >= mAccounts.length) {
+                return;
+            }
+
+            // lookup the confirmCredentials intent for the current account
+            mAccountManager.confirmCredentialsAsUser(mAccounts[mAccountIndex], null, null, this,
+                    null, new UserHandle(mLockPatternUtils.getCurrentUser()));
+        }
+
+        public void start() {
+            mEnableFallback = false;
+            mAccountIndex = 0;
+            next();
+        }
+
+        public void run(AccountManagerFuture<Bundle> future) {
+            try {
+                Bundle result = future.getResult();
+                if (result.getParcelable(AccountManager.KEY_INTENT) != null) {
+                    mEnableFallback = true;
+                }
+            } catch (OperationCanceledException e) {
+                // just skip the account if we are unable to query it
+            } catch (IOException e) {
+                // just skip the account if we are unable to query it
+            } catch (AuthenticatorException e) {
+                // just skip the account if we are unable to query it
+            } finally {
+                mAccountIndex++;
+                next();
+            }
+        }
+    }
+
+    private void handleAttemptLockout(long elapsedRealtimeDeadline) {
+        mLockPatternView.clearPattern();
+        mLockPatternView.setEnabled(false);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
+        if (mEnableFallback) {
+            updateFooter(FooterMode.ForgotLockPattern);
+        }
+
+        mCountdownTimer = new CountDownTimer(elapsedRealtimeDeadline - elapsedRealtime, 1000) {
+
+            @Override
+            public void onTick(long millisUntilFinished) {
+                final int secondsRemaining = (int) (millisUntilFinished / 1000);
+                mSecurityMessageDisplay.setMessage(
+                        R.string.kg_too_many_failed_attempts_countdown, true, secondsRemaining);
+            }
+
+            @Override
+            public void onFinish() {
+                mLockPatternView.setEnabled(true);
+                displayDefaultSecurityMessage();
+                // TODO mUnlockIcon.setVisibility(View.VISIBLE);
+                mFailedPatternAttemptsSinceLastTimeout = 0;
+                if (mEnableFallback) {
+                    updateFooter(FooterMode.ForgotLockPattern);
+                } else {
+                    updateFooter(FooterMode.Normal);
+                }
+            }
+
+        }.start();
+    }
+
+    @Override
+    public boolean needsInput() {
+        return false;
+    }
+
+    @Override
+    public void onPause() {
+        if (mCountdownTimer != null) {
+            mCountdownTimer.cancel();
+            mCountdownTimer = null;
+        }
+    }
+
+    @Override
+    public void onResume(int reason) {
+        reset();
+    }
+
+    @Override
+    public KeyguardSecurityCallback getCallback() {
+        return mCallback;
+    }
+
+    @Override
+    public void showBouncer(int duration) {
+        KeyguardSecurityViewHelper.
+                showBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration);
+    }
+
+    @Override
+    public void hideBouncer(int duration) {
+        KeyguardSecurityViewHelper.
+                hideBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration);
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityCallback.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityCallback.java
new file mode 100644
index 0000000..4f139ad
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityCallback.java
@@ -0,0 +1,68 @@
+/*
+ * 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.keyguard;
+
+import com.android.keyguard.KeyguardHostView.OnDismissAction;
+
+public interface KeyguardSecurityCallback {
+
+    /**
+     * Dismiss the given security screen.
+     * @param securityVerified true if the user correctly entered credentials for the given screen.
+     */
+    void dismiss(boolean securityVerified);
+
+    /**
+     * Manually report user activity to keep the device awake. If timeout is 0,
+     * uses user-defined timeout.
+     * @param timeout
+     */
+    void userActivity(long timeout);
+
+    /**
+     * Checks if keyguard is in "verify credentials" mode.
+     * @return true if user has been asked to verify security.
+     */
+    boolean isVerifyUnlockOnly();
+
+    /**
+     * Call when user correctly enters their credentials
+     */
+    void reportSuccessfulUnlockAttempt();
+
+    /**
+     * Call when the user incorrectly enters their credentials
+     */
+    void reportFailedUnlockAttempt();
+
+    /**
+     * Gets the number of attempts thus far as reported by {@link #reportFailedUnlockAttempt()}
+     * @return number of failed attempts
+     */
+    int getFailedAttempts();
+
+    /**
+     * Shows the backup security for the current method.  If none available, this call is a no-op.
+     */
+    void showBackupSecurity();
+
+    /**
+     * Sets an action to perform after the user successfully enters their credentials.
+     * @param action
+     */
+    void setOnDismissAction(OnDismissAction action);
+
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
new file mode 100644
index 0000000..9d03c6a
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -0,0 +1,45 @@
+package com.android.keyguard;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.FrameLayout;
+
+public class KeyguardSecurityContainer extends FrameLayout {
+    public KeyguardSecurityContainer(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public KeyguardSecurityContainer(Context context) {
+        this(null, null, 0);
+    }
+
+    public KeyguardSecurityContainer(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    KeyguardSecurityViewFlipper getFlipper() {
+        for (int i = 0; i < getChildCount(); i++) {
+            View child = getChildAt(i);
+            if (child instanceof KeyguardSecurityViewFlipper) {
+                return (KeyguardSecurityViewFlipper) child;
+            }
+        }
+        return null;
+    }
+
+    public void showBouncer(int duration) {
+        KeyguardSecurityViewFlipper flipper = getFlipper();
+        if (flipper != null) {
+            flipper.showBouncer(duration);
+        }
+    }
+
+    public void hideBouncer(int duration) {
+        KeyguardSecurityViewFlipper flipper = getFlipper();
+        if (flipper != null) {
+            flipper.hideBouncer(duration);
+        }
+    }
+}
+
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java
new file mode 100644
index 0000000..4129e33
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java
@@ -0,0 +1,147 @@
+/*
+ * 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.keyguard;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.telephony.TelephonyManager;
+
+import com.android.internal.telephony.IccCardConstants;
+import com.android.internal.widget.LockPatternUtils;
+
+public class KeyguardSecurityModel {
+    /**
+     * The different types of security available for {@link Mode#UnlockScreen}.
+     * @see com.android.internal.policy.impl.LockPatternKeyguardView#getUnlockMode()
+     */
+    enum SecurityMode {
+        Invalid, // NULL state
+        None, // No security enabled
+        Pattern, // Unlock by drawing a pattern.
+        Password, // Unlock by entering an alphanumeric password
+        PIN, // Strictly numeric password
+        Biometric, // Unlock with a biometric key (e.g. finger print or face unlock)
+        Account, // Unlock by entering an account's login and password.
+        SimPin, // Unlock by entering a sim pin.
+        SimPuk // Unlock by entering a sim puk
+    }
+
+    private Context mContext;
+    private LockPatternUtils mLockPatternUtils;
+
+    KeyguardSecurityModel(Context context) {
+        mContext = context;
+        mLockPatternUtils = new LockPatternUtils(context);
+    }
+
+    void setLockPatternUtils(LockPatternUtils utils) {
+        mLockPatternUtils = utils;
+    }
+
+    /**
+     * Returns true if biometric unlock is installed and selected.  If this returns false there is
+     * no need to even construct the biometric unlock.
+     */
+    boolean isBiometricUnlockEnabled() {
+        return mLockPatternUtils.usingBiometricWeak()
+                && mLockPatternUtils.isBiometricWeakInstalled();
+    }
+
+    /**
+     * Returns true if a condition is currently suppressing the biometric unlock.  If this returns
+     * true there is no need to even construct the biometric unlock.
+     */
+    private boolean isBiometricUnlockSuppressed() {
+        KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
+        final boolean backupIsTimedOut = monitor.getFailedUnlockAttempts() >=
+                LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT;
+        return monitor.getMaxBiometricUnlockAttemptsReached() || backupIsTimedOut
+                || !monitor.isAlternateUnlockEnabled()
+                || monitor.getPhoneState() != TelephonyManager.CALL_STATE_IDLE;
+    }
+
+    SecurityMode getSecurityMode() {
+        KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
+        final IccCardConstants.State simState = updateMonitor.getSimState();
+        SecurityMode mode = SecurityMode.None;
+        if (simState == IccCardConstants.State.PIN_REQUIRED) {
+            mode = SecurityMode.SimPin;
+        } else if (simState == IccCardConstants.State.PUK_REQUIRED
+                && mLockPatternUtils.isPukUnlockScreenEnable()) {
+            mode = SecurityMode.SimPuk;
+        } else {
+            final int security = mLockPatternUtils.getKeyguardStoredPasswordQuality();
+            switch (security) {
+                case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
+                    mode = mLockPatternUtils.isLockPasswordEnabled() ?
+                            SecurityMode.PIN : SecurityMode.None;
+                    break;
+                case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
+                case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
+                case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
+                    mode = mLockPatternUtils.isLockPasswordEnabled() ?
+                            SecurityMode.Password : SecurityMode.None;
+                    break;
+
+                case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
+                case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED:
+                    if (mLockPatternUtils.isLockPatternEnabled()) {
+                        mode = mLockPatternUtils.isPermanentlyLocked() ?
+                            SecurityMode.Account : SecurityMode.Pattern;
+                    }
+                    break;
+
+                default:
+                    throw new IllegalStateException("Unknown unlock mode:" + mode);
+            }
+        }
+        return mode;
+    }
+
+    /**
+     * Some unlock methods can have an alternate, such as biometric unlocks (e.g. face unlock).
+     * This function decides if an alternate unlock is available and returns it. Otherwise,
+     * returns @param mode.
+     *
+     * @param mode the mode we want the alternate for
+     * @return alternate or the given mode
+     */
+    SecurityMode getAlternateFor(SecurityMode mode) {
+        if (isBiometricUnlockEnabled() && !isBiometricUnlockSuppressed()
+                && (mode == SecurityMode.Password
+                        || mode == SecurityMode.PIN
+                        || mode == SecurityMode.Pattern)) {
+            return SecurityMode.Biometric;
+        }
+        return mode; // no alternate, return what was given
+    }
+
+    /**
+     * Some unlock methods can have a backup which gives the user another way to get into
+     * the device. This is currently only supported for Biometric and Pattern unlock.
+     *
+     * @return backup method or current security mode
+     */
+    SecurityMode getBackupSecurityMode(SecurityMode mode) {
+        switch(mode) {
+            case Biometric:
+                return getSecurityMode();
+            case Pattern:
+                return SecurityMode.Account;
+        }
+        return mode; // no backup, return current security mode
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java
new file mode 100644
index 0000000..dfeacf3
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java
@@ -0,0 +1,87 @@
+/*
+ * 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.keyguard;
+
+import com.android.internal.widget.LockPatternUtils;
+
+public interface KeyguardSecurityView {
+    static public final int SCREEN_ON = 1;
+    static public final int VIEW_REVEALED = 2;
+
+    /**
+     * Interface back to keyguard to tell it when security
+     * @param callback
+     */
+    void setKeyguardCallback(KeyguardSecurityCallback callback);
+
+    /**
+     * Set {@link LockPatternUtils} object. Useful for providing a mock interface.
+     * @param utils
+     */
+    void setLockPatternUtils(LockPatternUtils utils);
+
+    /**
+     * Reset the view and prepare to take input. This should do things like clearing the
+     * password or pattern and clear error messages.
+     */
+    void reset();
+
+    /**
+     * Emulate activity life cycle within the view. When called, the view should clean up
+     * and prepare to be removed.
+     */
+    void onPause();
+
+    /**
+     * Emulate activity life cycle within this view.  When called, the view should prepare itself
+     * to be shown.
+     * @param reason the root cause of the event.
+     */
+    void onResume(int reason);
+
+    /**
+     * Inquire whether this view requires IME (keyboard) interaction.
+     *
+     * @return true if IME interaction is required.
+     */
+    boolean needsInput();
+
+    /**
+     * Get {@link KeyguardSecurityCallback} for the given object
+     * @return KeyguardSecurityCallback
+     */
+    KeyguardSecurityCallback getCallback();
+
+    /**
+     * Instruct the view to show usability hints, if any.
+     *
+     */
+    void showUsabilityHint();
+
+    /**
+     * Place the security view into bouncer mode.
+     * Animate transisiton if duration is non-zero.
+     * @param duration millisends for the transisiton animation.
+     */
+    void showBouncer(int duration);
+
+    /**
+     * Place the security view into non-bouncer mode.
+     * Animate transisiton if duration is non-zero.
+     * @param duration millisends for the transisiton animation.
+     */
+    void hideBouncer(int duration);
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java
new file mode 100644
index 0000000..70a0e44
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java
@@ -0,0 +1,278 @@
+/*
+ * 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.keyguard;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewDebug;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.widget.FrameLayout;
+import android.widget.ViewFlipper;
+
+import com.android.internal.widget.LockPatternUtils;
+
+/**
+ * Subclass of the current view flipper that allows us to overload dispatchTouchEvent() so
+ * we can emulate {@link WindowManager.LayoutParams#FLAG_SLIPPERY} within a view hierarchy.
+ *
+ */
+public class KeyguardSecurityViewFlipper extends ViewFlipper implements KeyguardSecurityView {
+    private static final String TAG = "KeyguardSecurityViewFlipper";
+    private static final boolean DEBUG = false;
+
+    private Rect mTempRect = new Rect();
+
+    public KeyguardSecurityViewFlipper(Context context) {
+        this(context, null);
+    }
+
+    public KeyguardSecurityViewFlipper(Context context, AttributeSet attr) {
+        super(context, attr);
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        boolean result = super.onTouchEvent(ev);
+        mTempRect.set(0, 0, 0, 0);
+        for (int i = 0; i < getChildCount(); i++) {
+            View child = getChildAt(i);
+            if (child.getVisibility() == View.VISIBLE) {
+                offsetRectIntoDescendantCoords(child, mTempRect);
+                ev.offsetLocation(mTempRect.left, mTempRect.top);
+                result = child.dispatchTouchEvent(ev) || result;
+                ev.offsetLocation(-mTempRect.left, -mTempRect.top);
+            }
+        }
+        return result;
+    }
+
+    KeyguardSecurityView getSecurityView() {
+        View child = getChildAt(getDisplayedChild());
+        if (child instanceof KeyguardSecurityView) {
+            return (KeyguardSecurityView) child;
+        }
+        return null;
+    }
+
+    @Override
+    public void setKeyguardCallback(KeyguardSecurityCallback callback) {
+        KeyguardSecurityView ksv = getSecurityView();
+        if (ksv != null) {
+            ksv.setKeyguardCallback(callback);
+        }
+    }
+
+    @Override
+    public void setLockPatternUtils(LockPatternUtils utils) {
+        KeyguardSecurityView ksv = getSecurityView();
+        if (ksv != null) {
+            ksv.setLockPatternUtils(utils);
+        }
+    }
+
+    @Override
+    public void reset() {
+        KeyguardSecurityView ksv = getSecurityView();
+        if (ksv != null) {
+            ksv.reset();
+        }
+    }
+
+    @Override
+    public void onPause() {
+        KeyguardSecurityView ksv = getSecurityView();
+        if (ksv != null) {
+            ksv.onPause();
+        }
+    }
+
+    @Override
+    public void onResume(int reason) {
+        KeyguardSecurityView ksv = getSecurityView();
+        if (ksv != null) {
+            ksv.onResume(reason);
+        }
+    }
+
+    @Override
+    public boolean needsInput() {
+        KeyguardSecurityView ksv = getSecurityView();
+        return (ksv != null) ? ksv.needsInput() : false;
+    }
+
+    @Override
+    public KeyguardSecurityCallback getCallback() {
+        KeyguardSecurityView ksv = getSecurityView();
+        return (ksv != null) ? ksv.getCallback() : null;
+    }
+
+    @Override
+    public void showUsabilityHint() {
+        KeyguardSecurityView ksv = getSecurityView();
+        if (ksv != null) {
+            ksv.showUsabilityHint();
+        }
+    }
+
+    @Override
+    public void showBouncer(int duration) {
+        KeyguardSecurityView active = getSecurityView();
+        for (int i = 0; i < getChildCount(); i++) {
+            View child = getChildAt(i);
+            if (child instanceof KeyguardSecurityView) {
+                KeyguardSecurityView ksv = (KeyguardSecurityView) child;
+                ksv.showBouncer(ksv == active ? duration : 0);
+            }
+        }
+    }
+
+    @Override
+    public void hideBouncer(int duration) {
+        KeyguardSecurityView active = getSecurityView();
+        for (int i = 0; i < getChildCount(); i++) {
+            View child = getChildAt(i);
+            if (child instanceof KeyguardSecurityView) {
+                KeyguardSecurityView ksv = (KeyguardSecurityView) child;
+                ksv.hideBouncer(ksv == active ? duration : 0);
+            }
+        }
+    }
+
+    @Override
+    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
+        return p instanceof LayoutParams;
+    }
+
+    @Override
+    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
+        return p instanceof LayoutParams ? new LayoutParams((LayoutParams) p) : new LayoutParams(p);
+    }
+
+    @Override
+    public LayoutParams generateLayoutParams(AttributeSet attrs) {
+        return new LayoutParams(getContext(), attrs);
+    }
+
+    @Override
+    protected void onMeasure(int widthSpec, int heightSpec) {
+        final int widthMode = MeasureSpec.getMode(widthSpec);
+        final int heightMode = MeasureSpec.getMode(heightSpec);
+        if (DEBUG && widthMode != MeasureSpec.AT_MOST) {
+            Log.w(TAG, "onMeasure: widthSpec " + MeasureSpec.toString(widthSpec) +
+                    " should be AT_MOST");
+        }
+        if (DEBUG && heightMode != MeasureSpec.AT_MOST) {
+            Log.w(TAG, "onMeasure: heightSpec " + MeasureSpec.toString(heightSpec) +
+                    " should be AT_MOST");
+        }
+
+        final int widthSize = MeasureSpec.getSize(widthSpec);
+        final int heightSize = MeasureSpec.getSize(heightSpec);
+        int maxWidth = widthSize;
+        int maxHeight = heightSize;
+        final int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            final View child = getChildAt(i);
+            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+            if (lp.maxWidth > 0 && lp.maxWidth < maxWidth) {
+                maxWidth = lp.maxWidth;
+            }
+            if (lp.maxHeight > 0 && lp.maxHeight < maxHeight) {
+                maxHeight = lp.maxHeight;
+            }
+        }
+
+        final int wPadding = getPaddingLeft() + getPaddingRight();
+        final int hPadding = getPaddingTop() + getPaddingBottom();
+        maxWidth -= wPadding;
+        maxHeight -= hPadding;
+
+        int width = widthMode == MeasureSpec.EXACTLY ? widthSize : 0;
+        int height = heightMode == MeasureSpec.EXACTLY ? heightSize : 0;
+        for (int i = 0; i < count; i++) {
+            final View child = getChildAt(i);
+            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+            final int childWidthSpec = makeChildMeasureSpec(maxWidth, lp.width);
+            final int childHeightSpec = makeChildMeasureSpec(maxHeight, lp.height);
+
+            child.measure(childWidthSpec, childHeightSpec);
+
+            width = Math.max(width, Math.min(child.getMeasuredWidth(), widthSize - wPadding));
+            height = Math.max(height, Math.min(child.getMeasuredHeight(), heightSize - hPadding));
+        }
+        setMeasuredDimension(width + wPadding, height + hPadding);
+    }
+
+    private int makeChildMeasureSpec(int maxSize, int childDimen) {
+        final int mode;
+        final int size;
+        switch (childDimen) {
+            case LayoutParams.WRAP_CONTENT:
+                mode = MeasureSpec.AT_MOST;
+                size = maxSize;
+                break;
+            case LayoutParams.MATCH_PARENT:
+                mode = MeasureSpec.EXACTLY;
+                size = maxSize;
+                break;
+            default:
+                mode = MeasureSpec.EXACTLY;
+                size = Math.min(maxSize, childDimen);
+                break;
+        }
+        return MeasureSpec.makeMeasureSpec(size, mode);
+    }
+
+    public static class LayoutParams extends FrameLayout.LayoutParams {
+        @ViewDebug.ExportedProperty(category = "layout")
+        public int maxWidth;
+
+        @ViewDebug.ExportedProperty(category = "layout")
+        public int maxHeight;
+
+        public LayoutParams(ViewGroup.LayoutParams other) {
+            super(other);
+        }
+
+        public LayoutParams(LayoutParams other) {
+            super(other);
+
+            maxWidth = other.maxWidth;
+            maxHeight = other.maxHeight;
+        }
+
+        public LayoutParams(Context c, AttributeSet attrs) {
+            super(c, attrs);
+
+            final TypedArray a = c.obtainStyledAttributes(attrs,
+                    R.styleable.KeyguardSecurityViewFlipper_Layout, 0, 0);
+            maxWidth = a.getDimensionPixelSize(
+                    R.styleable.KeyguardSecurityViewFlipper_Layout_layout_maxWidth, 0);
+            maxHeight = a.getDimensionPixelSize(
+                    R.styleable.KeyguardSecurityViewFlipper_Layout_layout_maxHeight, 0);
+            a.recycle();
+        }
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewHelper.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewHelper.java
new file mode 100644
index 0000000..67a6f52
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewHelper.java
@@ -0,0 +1,94 @@
+/*
+ * 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.keyguard;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.graphics.drawable.Drawable;
+import android.view.View;
+
+/**
+ * Some common functions that are useful for KeyguardSecurityViews.
+ */
+public class KeyguardSecurityViewHelper {
+
+    public static void showBouncer(SecurityMessageDisplay securityMessageDisplay,
+            final View ecaView, Drawable bouncerFrame, int duration) {
+        if (securityMessageDisplay != null) {
+            securityMessageDisplay.showBouncer(duration);
+        }
+        if (ecaView != null) {
+            if (duration > 0) {
+                Animator anim = ObjectAnimator.ofFloat(ecaView, "alpha", 0f);
+                anim.setDuration(duration);
+                anim.addListener(new AnimatorListenerAdapter() {
+                    private boolean mCanceled;
+                    @Override
+                    public void onAnimationCancel(Animator animation) {
+                        // Fail safe and show the emergency button in onAnimationEnd()
+                        mCanceled = true;
+                        ecaView.setAlpha(1f);
+                    }
+                    @Override
+                    public void onAnimationEnd(Animator animation) {
+                        ecaView.setVisibility(mCanceled ? View.VISIBLE : View.INVISIBLE);
+                    }
+                });
+                anim.start();
+            } else {
+                ecaView.setAlpha(0f);
+                ecaView.setVisibility(View.INVISIBLE);
+            }
+        }
+        if (bouncerFrame != null) {
+            if (duration > 0) {
+                Animator anim = ObjectAnimator.ofInt(bouncerFrame, "alpha", 0, 255);
+                anim.setDuration(duration);
+                anim.start();
+            } else {
+                bouncerFrame.setAlpha(255);
+            }
+        }
+    }
+
+    public static void hideBouncer(SecurityMessageDisplay securityMessageDisplay,
+            View ecaView, Drawable bouncerFrame, int duration) {
+        if (securityMessageDisplay != null) {
+            securityMessageDisplay.hideBouncer(duration);
+        }
+        if (ecaView != null) {
+            ecaView.setVisibility(View.VISIBLE);
+            if (duration > 0) {
+                Animator anim = ObjectAnimator.ofFloat(ecaView, "alpha", 1f);
+                anim.setDuration(duration);
+                anim.start();
+            } else {
+                ecaView.setAlpha(1f);
+            }
+        }
+        if (bouncerFrame != null) {
+            if (duration > 0) {
+                Animator anim = ObjectAnimator.ofInt(bouncerFrame, "alpha", 255, 0);
+                anim.setDuration(duration);
+                anim.start();
+            } else {
+                bouncerFrame.setAlpha(0);
+            }
+        }
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java
new file mode 100644
index 0000000..63be102
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java
@@ -0,0 +1,289 @@
+/*
+ * 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.keyguard;
+
+import android.animation.ObjectAnimator;
+import android.app.ActivityManager;
+import android.app.PendingIntent;
+import android.app.SearchManager;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.os.PowerManager;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.telephony.TelephonyManager;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Slog;
+import android.view.View;
+import android.widget.LinearLayout;
+
+import com.android.internal.telephony.IccCardConstants.State;
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.multiwaveview.GlowPadView;
+import com.android.internal.widget.multiwaveview.GlowPadView.OnTriggerListener;
+
+public class KeyguardSelectorView extends LinearLayout implements KeyguardSecurityView {
+    private static final boolean DEBUG = KeyguardHostView.DEBUG;
+    private static final String TAG = "SecuritySelectorView";
+    private static final String ASSIST_ICON_METADATA_NAME =
+        "com.android.systemui.action_assist_icon";
+
+    private KeyguardSecurityCallback mCallback;
+    private GlowPadView mGlowPadView;
+    private ObjectAnimator mAnim;
+    private View mFadeView;
+    private boolean mIsBouncing;
+    private boolean mCameraDisabled;
+    private boolean mSearchDisabled;
+    private LockPatternUtils mLockPatternUtils;
+    private SecurityMessageDisplay mSecurityMessageDisplay;
+    private Drawable mBouncerFrame;
+
+    OnTriggerListener mOnTriggerListener = new OnTriggerListener() {
+
+        public void onTrigger(View v, int target) {
+            final int resId = mGlowPadView.getResourceIdForTarget(target);
+
+            switch (resId) {
+                case R.drawable.ic_action_assist_generic:
+                    Intent assistIntent =
+                            ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
+                            .getAssistIntent(mContext, true, UserHandle.USER_CURRENT);
+                    if (assistIntent != null) {
+                        mActivityLauncher.launchActivity(assistIntent, false, true, null, null);
+                    } else {
+                        Log.w(TAG, "Failed to get intent for assist activity");
+                    }
+                    mCallback.userActivity(0);
+                    break;
+
+                case R.drawable.ic_lockscreen_camera:
+                    mActivityLauncher.launchCamera(null, null);
+                    mCallback.userActivity(0);
+                    break;
+
+                case R.drawable.ic_lockscreen_unlock_phantom:
+                case R.drawable.ic_lockscreen_unlock:
+                    mCallback.userActivity(0);
+                    mCallback.dismiss(false);
+                break;
+            }
+        }
+
+        public void onReleased(View v, int handle) {
+            if (!mIsBouncing) {
+                doTransition(mFadeView, 1.0f);
+            }
+        }
+
+        public void onGrabbed(View v, int handle) {
+            mCallback.userActivity(0);
+            doTransition(mFadeView, 0.0f);
+        }
+
+        public void onGrabbedStateChange(View v, int handle) {
+
+        }
+
+        public void onFinishFinalAnimation() {
+
+        }
+
+    };
+
+    KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() {
+
+        @Override
+        public void onDevicePolicyManagerStateChanged() {
+            updateTargets();
+        }
+
+        @Override
+        public void onSimStateChanged(State simState) {
+            updateTargets();
+        }
+    };
+
+    private final KeyguardActivityLauncher mActivityLauncher = new KeyguardActivityLauncher() {
+
+        @Override
+        KeyguardSecurityCallback getCallback() {
+            return mCallback;
+        }
+
+        @Override
+        LockPatternUtils getLockPatternUtils() {
+            return mLockPatternUtils;
+        }
+
+        @Override
+        Context getContext() {
+            return mContext;
+        }};
+
+    public KeyguardSelectorView(Context context) {
+        this(context, null);
+    }
+
+    public KeyguardSelectorView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        mLockPatternUtils = new LockPatternUtils(getContext());
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mGlowPadView = (GlowPadView) findViewById(R.id.glow_pad_view);
+        mGlowPadView.setOnTriggerListener(mOnTriggerListener);
+        updateTargets();
+
+        mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
+        View bouncerFrameView = findViewById(R.id.keyguard_selector_view_frame);
+        mBouncerFrame = bouncerFrameView.getBackground();
+    }
+
+    public void setCarrierArea(View carrierArea) {
+        mFadeView = carrierArea;
+    }
+
+    public boolean isTargetPresent(int resId) {
+        return mGlowPadView.getTargetPosition(resId) != -1;
+    }
+
+    @Override
+    public void showUsabilityHint() {
+        mGlowPadView.ping();
+    }
+
+    private void updateTargets() {
+        int currentUserHandle = mLockPatternUtils.getCurrentUser();
+        DevicePolicyManager dpm = mLockPatternUtils.getDevicePolicyManager();
+        int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, currentUserHandle);
+        boolean secureCameraDisabled = mLockPatternUtils.isSecure()
+                && (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0;
+        boolean cameraDisabledByAdmin = dpm.getCameraDisabled(null, currentUserHandle)
+                || secureCameraDisabled;
+        final KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(getContext());
+        boolean disabledBySimState = monitor.isSimLocked();
+        boolean cameraTargetPresent =
+            isTargetPresent(R.drawable.ic_lockscreen_camera);
+        boolean searchTargetPresent =
+            isTargetPresent(R.drawable.ic_action_assist_generic);
+
+        if (cameraDisabledByAdmin) {
+            Log.v(TAG, "Camera disabled by Device Policy");
+        } else if (disabledBySimState) {
+            Log.v(TAG, "Camera disabled by Sim State");
+        }
+        boolean currentUserSetup = 0 != Settings.Secure.getIntForUser(
+                mContext.getContentResolver(),
+                Settings.Secure.USER_SETUP_COMPLETE,
+                0 /*default */,
+                currentUserHandle);
+        boolean searchActionAvailable =
+                ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
+                .getAssistIntent(mContext, false, UserHandle.USER_CURRENT) != null;
+        mCameraDisabled = cameraDisabledByAdmin || disabledBySimState || !cameraTargetPresent
+                || !currentUserSetup;
+        mSearchDisabled = disabledBySimState || !searchActionAvailable || !searchTargetPresent
+                || !currentUserSetup;
+        updateResources();
+    }
+
+    public void updateResources() {
+        // Update the search icon with drawable from the search .apk
+        if (!mSearchDisabled) {
+            Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
+                    .getAssistIntent(mContext, false, UserHandle.USER_CURRENT);
+            if (intent != null) {
+                // XXX Hack. We need to substitute the icon here but haven't formalized
+                // the public API. The "_google" metadata will be going away, so
+                // DON'T USE IT!
+                ComponentName component = intent.getComponent();
+                boolean replaced = mGlowPadView.replaceTargetDrawablesIfPresent(component,
+                        ASSIST_ICON_METADATA_NAME + "_google", R.drawable.ic_action_assist_generic);
+
+                if (!replaced && !mGlowPadView.replaceTargetDrawablesIfPresent(component,
+                            ASSIST_ICON_METADATA_NAME, R.drawable.ic_action_assist_generic)) {
+                        Slog.w(TAG, "Couldn't grab icon from package " + component);
+                }
+            }
+        }
+
+        mGlowPadView.setEnableTarget(R.drawable.ic_lockscreen_camera, !mCameraDisabled);
+        mGlowPadView.setEnableTarget(R.drawable.ic_action_assist_generic, !mSearchDisabled);
+    }
+
+    void doTransition(View view, float to) {
+        if (mAnim != null) {
+            mAnim.cancel();
+        }
+        mAnim = ObjectAnimator.ofFloat(view, "alpha", to);
+        mAnim.start();
+    }
+
+    public void setKeyguardCallback(KeyguardSecurityCallback callback) {
+        mCallback = callback;
+    }
+
+    public void setLockPatternUtils(LockPatternUtils utils) {
+        mLockPatternUtils = utils;
+    }
+
+    @Override
+    public void reset() {
+        mGlowPadView.reset(false);
+    }
+
+    @Override
+    public boolean needsInput() {
+        return false;
+    }
+
+    @Override
+    public void onPause() {
+        KeyguardUpdateMonitor.getInstance(getContext()).removeCallback(mUpdateCallback);
+    }
+
+    @Override
+    public void onResume(int reason) {
+        KeyguardUpdateMonitor.getInstance(getContext()).registerCallback(mUpdateCallback);
+    }
+
+    @Override
+    public KeyguardSecurityCallback getCallback() {
+        return mCallback;
+    }
+
+    @Override
+    public void showBouncer(int duration) {
+        mIsBouncing = true;
+        KeyguardSecurityViewHelper.
+                showBouncer(mSecurityMessageDisplay, mFadeView, mBouncerFrame, duration);
+    }
+
+    @Override
+    public void hideBouncer(int duration) {
+        mIsBouncing = false;
+        KeyguardSecurityViewHelper.
+                hideBouncer(mSecurityMessageDisplay, mFadeView, mBouncerFrame, duration);
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardService.java b/packages/Keyguard/src/com/android/keyguard/KeyguardService.java
new file mode 100644
index 0000000..a70e5bd
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardService.java
@@ -0,0 +1,138 @@
+/*
+ * 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.keyguard;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+import android.app.Service;
+import android.content.Intent;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Debug;
+import android.os.IBinder;
+import android.util.Log;
+
+import com.android.internal.policy.IKeyguardService;
+import com.android.internal.policy.IKeyguardExitCallback;
+import com.android.internal.policy.IKeyguardShowCallback;
+import com.android.internal.widget.LockPatternUtils;
+
+public class KeyguardService extends Service {
+    static final String TAG = "KeyguardService";
+    static final String PERMISSION = android.Manifest.permission.CONTROL_KEYGUARD;
+    private KeyguardViewMediator mKeyguardViewMediator;
+
+    @Override
+    public void onCreate() {
+        if (mKeyguardViewMediator == null) {
+            mKeyguardViewMediator = new KeyguardViewMediator(
+                    KeyguardService.this, new LockPatternUtils(KeyguardService.this));
+        }
+        Log.v(TAG, "onCreate()");
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return mBinder;
+    }
+
+    @Override
+    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        // TODO
+    }
+
+    void checkPermission() {
+        if (getBaseContext().checkCallingOrSelfPermission(PERMISSION) != PERMISSION_GRANTED) {
+            Log.w(TAG, "Caller needs permission '" + PERMISSION + "' to call " + Debug.getCaller());
+            throw new SecurityException("Access denied to process: " + Binder.getCallingPid()
+                    + ", must have permission " + PERMISSION);
+        }
+    }
+
+    private final IKeyguardService.Stub mBinder = new IKeyguardService.Stub() {
+        public boolean isShowing() {
+            return mKeyguardViewMediator.isShowing();
+        }
+        public boolean isSecure() {
+            return mKeyguardViewMediator.isSecure();
+        }
+        public boolean isShowingAndNotHidden() {
+            return mKeyguardViewMediator.isShowingAndNotHidden();
+        }
+        public boolean isInputRestricted() {
+            return mKeyguardViewMediator.isInputRestricted();
+        }
+        public void verifyUnlock(IKeyguardExitCallback callback) {
+            mKeyguardViewMediator.verifyUnlock(callback);
+        }
+        public void keyguardDone(boolean authenticated, boolean wakeup) {
+            checkPermission();
+            mKeyguardViewMediator.keyguardDone(authenticated, wakeup);
+        }
+        public void setHidden(boolean isHidden) {
+            checkPermission();
+            mKeyguardViewMediator.setHidden(isHidden);
+        }
+        public void dismiss() {
+            mKeyguardViewMediator.dismiss();
+        }
+        public void onDreamingStarted() {
+            checkPermission();
+            mKeyguardViewMediator.onDreamingStarted();
+        }
+        public void onDreamingStopped() {
+            checkPermission();
+            mKeyguardViewMediator.onDreamingStopped();
+        }
+        public void onScreenTurnedOff(int reason) {
+            checkPermission();
+            mKeyguardViewMediator.onScreenTurnedOff(reason);
+        }
+        public void onScreenTurnedOn(IKeyguardShowCallback callback) {
+            checkPermission();
+            mKeyguardViewMediator.onScreenTurnedOn(callback);
+        }
+        public void setKeyguardEnabled(boolean enabled) {
+            checkPermission();
+            mKeyguardViewMediator.setKeyguardEnabled(enabled);
+        }
+        public boolean isDismissable() {
+            return mKeyguardViewMediator.isDismissable();
+        }
+        public void onSystemReady() {
+            checkPermission();
+            mKeyguardViewMediator.onSystemReady();
+        }
+        public void doKeyguardTimeout(Bundle options) {
+            checkPermission();
+            mKeyguardViewMediator.doKeyguardTimeout(options);
+        }
+        public void setCurrentUser(int userId) {
+            checkPermission();
+            mKeyguardViewMediator.setCurrentUser(userId);
+        }
+        public void showAssistant() {
+            checkPermission();
+            mKeyguardViewMediator.showAssistant();
+        }
+    };
+
+}
+
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java
new file mode 100644
index 0000000..865a7c4
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java
@@ -0,0 +1,211 @@
+/*
+ * 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.keyguard;
+
+import com.android.internal.telephony.ITelephony;
+
+import android.content.Context;
+import android.app.Activity;
+import android.app.Dialog;
+import android.app.ProgressDialog;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.text.Editable;
+import android.text.InputType;
+import android.text.TextWatcher;
+import android.text.method.DigitsKeyListener;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.TextView.OnEditorActionListener;
+
+/**
+ * Displays a PIN pad for unlocking.
+ */
+public class KeyguardSimPinView extends KeyguardAbsKeyInputView
+        implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
+
+    private ProgressDialog mSimUnlockProgressDialog = null;
+    private volatile boolean mSimCheckInProgress;
+
+    public KeyguardSimPinView(Context context) {
+        this(context, null);
+    }
+
+    public KeyguardSimPinView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public void resetState() {
+        mSecurityMessageDisplay.setMessage(R.string.kg_sim_pin_instructions, true);
+        mPasswordEntry.setEnabled(true);
+    }
+
+    @Override
+    protected int getPasswordTextViewId() {
+        return R.id.pinEntry;
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+
+        final View ok = findViewById(R.id.key_enter);
+        if (ok != null) {
+            ok.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    doHapticKeyClick();
+                    verifyPasswordAndUnlock();
+                }
+            });
+        }
+
+        // The delete button is of the PIN keyboard itself in some (e.g. tablet) layouts,
+        // not a separate view
+        View pinDelete = findViewById(R.id.delete_button);
+        if (pinDelete != null) {
+            pinDelete.setVisibility(View.VISIBLE);
+            pinDelete.setOnClickListener(new OnClickListener() {
+                public void onClick(View v) {
+                    CharSequence str = mPasswordEntry.getText();
+                    if (str.length() > 0) {
+                        mPasswordEntry.setText(str.subSequence(0, str.length()-1));
+                    }
+                    doHapticKeyClick();
+                }
+            });
+            pinDelete.setOnLongClickListener(new View.OnLongClickListener() {
+                public boolean onLongClick(View v) {
+                    mPasswordEntry.setText("");
+                    doHapticKeyClick();
+                    return true;
+                }
+            });
+        }
+
+        mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance());
+        mPasswordEntry.setInputType(InputType.TYPE_CLASS_NUMBER
+                | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
+
+        mPasswordEntry.requestFocus();
+    }
+
+    @Override
+    public void showUsabilityHint() {
+    }
+
+    @Override
+    public void onPause() {
+        // dismiss the dialog.
+        if (mSimUnlockProgressDialog != null) {
+            mSimUnlockProgressDialog.dismiss();
+            mSimUnlockProgressDialog = null;
+        }
+    }
+
+    /**
+     * Since the IPC can block, we want to run the request in a separate thread
+     * with a callback.
+     */
+    private abstract class CheckSimPin extends Thread {
+        private final String mPin;
+
+        protected CheckSimPin(String pin) {
+            mPin = pin;
+        }
+
+        abstract void onSimCheckResponse(boolean success);
+
+        @Override
+        public void run() {
+            try {
+                final boolean result = ITelephony.Stub.asInterface(ServiceManager
+                        .checkService("phone")).supplyPin(mPin);
+                post(new Runnable() {
+                    public void run() {
+                        onSimCheckResponse(result);
+                    }
+                });
+            } catch (RemoteException e) {
+                post(new Runnable() {
+                    public void run() {
+                        onSimCheckResponse(false);
+                    }
+                });
+            }
+        }
+    }
+
+    private Dialog getSimUnlockProgressDialog() {
+        if (mSimUnlockProgressDialog == null) {
+            mSimUnlockProgressDialog = new ProgressDialog(mContext);
+            mSimUnlockProgressDialog.setMessage(
+                    mContext.getString(R.string.kg_sim_unlock_progress_dialog_message));
+            mSimUnlockProgressDialog.setIndeterminate(true);
+            mSimUnlockProgressDialog.setCancelable(false);
+            if (!(mContext instanceof Activity)) {
+                mSimUnlockProgressDialog.getWindow().setType(
+                        WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
+            }
+        }
+        return mSimUnlockProgressDialog;
+    }
+
+    @Override
+    protected void verifyPasswordAndUnlock() {
+        String entry = mPasswordEntry.getText().toString();
+        
+        if (entry.length() < 4) {
+            // otherwise, display a message to the user, and don't submit.
+            mSecurityMessageDisplay.setMessage(R.string.kg_invalid_sim_pin_hint, true);
+            mPasswordEntry.setText("");
+            mCallback.userActivity(0);
+            return;
+        }
+
+        getSimUnlockProgressDialog().show();
+
+        if (!mSimCheckInProgress) {
+            mSimCheckInProgress = true; // there should be only one
+            new CheckSimPin(mPasswordEntry.getText().toString()) {
+                void onSimCheckResponse(final boolean success) {
+                    post(new Runnable() {
+                        public void run() {
+                            if (mSimUnlockProgressDialog != null) {
+                                mSimUnlockProgressDialog.hide();
+                            }
+                            if (success) {
+                                // before closing the keyguard, report back that the sim is unlocked
+                                // so it knows right away.
+                                KeyguardUpdateMonitor.getInstance(getContext()).reportSimUnlocked();
+                                mCallback.dismiss(true);
+                            } else {
+                                mSecurityMessageDisplay.setMessage
+                                    (R.string.kg_password_wrong_pin_code, true);
+                                mPasswordEntry.setText("");
+                            }
+                            mCallback.userActivity(0);
+                            mSimCheckInProgress = false;
+                        }
+                    });
+                }
+            }.start();
+        }
+    }
+}
+
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java
new file mode 100644
index 0000000..7424fab
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java
@@ -0,0 +1,280 @@
+/*
+ * 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.keyguard;
+
+import com.android.internal.telephony.ITelephony;
+
+import android.content.Context;
+import android.app.Activity;
+import android.app.Dialog;
+import android.app.ProgressDialog;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.text.Editable;
+import android.text.InputType;
+import android.text.TextWatcher;
+import android.text.method.DigitsKeyListener;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.TextView.OnEditorActionListener;
+
+/**
+ * Displays a PIN pad for entering a PUK (Pin Unlock Kode) provided by a carrier.
+ */
+public class KeyguardSimPukView extends KeyguardAbsKeyInputView
+        implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
+
+    private ProgressDialog mSimUnlockProgressDialog = null;
+    private volatile boolean mCheckInProgress;
+    private String mPukText;
+    private String mPinText;
+    private StateMachine mStateMachine = new StateMachine();
+
+    private class StateMachine {
+        final int ENTER_PUK = 0;
+        final int ENTER_PIN = 1;
+        final int CONFIRM_PIN = 2;
+        final int DONE = 3;
+        private int state = ENTER_PUK;
+
+        public void next() {
+            int msg = 0;
+            if (state == ENTER_PUK) {
+                if (checkPuk()) {
+                    state = ENTER_PIN;
+                    msg = R.string.kg_puk_enter_pin_hint;
+                } else {
+                    msg = R.string.kg_invalid_sim_puk_hint;
+                }
+            } else if (state == ENTER_PIN) {
+                if (checkPin()) {
+                    state = CONFIRM_PIN;
+                    msg = R.string.kg_enter_confirm_pin_hint;
+                } else {
+                    msg = R.string.kg_invalid_sim_pin_hint;
+                }
+            } else if (state == CONFIRM_PIN) {
+                if (confirmPin()) {
+                    state = DONE;
+                    msg = R.string.keyguard_sim_unlock_progress_dialog_message;
+                    updateSim();
+                } else {
+                    state = ENTER_PIN; // try again?
+                    msg = R.string.kg_invalid_confirm_pin_hint;
+                }
+            }
+            mPasswordEntry.setText(null);
+            if (msg != 0) {
+                mSecurityMessageDisplay.setMessage(msg, true);
+            }
+        }
+
+        void reset() {
+            mPinText="";
+            mPukText="";
+            state = ENTER_PUK;
+            mSecurityMessageDisplay.setMessage(R.string.kg_puk_enter_puk_hint, true);
+            mPasswordEntry.requestFocus();
+        }
+    }
+
+    public KeyguardSimPukView(Context context) {
+        this(context, null);
+    }
+
+    public KeyguardSimPukView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public void resetState() {
+        mStateMachine.reset();
+        mPasswordEntry.setEnabled(true);
+    }
+
+    @Override
+    protected int getPasswordTextViewId() {
+        return R.id.pinEntry;
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+
+        final View ok = findViewById(R.id.key_enter);
+        if (ok != null) {
+            ok.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    doHapticKeyClick();
+                    verifyPasswordAndUnlock();
+                }
+            });
+        }
+
+        // The delete button is of the PIN keyboard itself in some (e.g. tablet) layouts,
+        // not a separate view
+        View pinDelete = findViewById(R.id.delete_button);
+        if (pinDelete != null) {
+            pinDelete.setVisibility(View.VISIBLE);
+            pinDelete.setOnClickListener(new OnClickListener() {
+                public void onClick(View v) {
+                    CharSequence str = mPasswordEntry.getText();
+                    if (str.length() > 0) {
+                        mPasswordEntry.setText(str.subSequence(0, str.length()-1));
+                    }
+                    doHapticKeyClick();
+                }
+            });
+            pinDelete.setOnLongClickListener(new View.OnLongClickListener() {
+                public boolean onLongClick(View v) {
+                    mPasswordEntry.setText("");
+                    doHapticKeyClick();
+                    return true;
+                }
+            });
+        }
+
+        mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance());
+        mPasswordEntry.setInputType(InputType.TYPE_CLASS_NUMBER
+                | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
+
+        mPasswordEntry.requestFocus();
+
+        mSecurityMessageDisplay.setTimeout(0); // don't show ownerinfo/charging status by default
+    }
+
+    @Override
+    public void showUsabilityHint() {
+    }
+
+    @Override
+    public void onPause() {
+        // dismiss the dialog.
+        if (mSimUnlockProgressDialog != null) {
+            mSimUnlockProgressDialog.dismiss();
+            mSimUnlockProgressDialog = null;
+        }
+    }
+
+    /**
+     * Since the IPC can block, we want to run the request in a separate thread
+     * with a callback.
+     */
+    private abstract class CheckSimPuk extends Thread {
+
+        private final String mPin, mPuk;
+
+        protected CheckSimPuk(String puk, String pin) {
+            mPuk = puk;
+            mPin = pin;
+        }
+
+        abstract void onSimLockChangedResponse(boolean success);
+
+        @Override
+        public void run() {
+            try {
+                final boolean result = ITelephony.Stub.asInterface(ServiceManager
+                        .checkService("phone")).supplyPuk(mPuk, mPin);
+
+                post(new Runnable() {
+                    public void run() {
+                        onSimLockChangedResponse(result);
+                    }
+                });
+            } catch (RemoteException e) {
+                post(new Runnable() {
+                    public void run() {
+                        onSimLockChangedResponse(false);
+                    }
+                });
+            }
+        }
+    }
+
+    private Dialog getSimUnlockProgressDialog() {
+        if (mSimUnlockProgressDialog == null) {
+            mSimUnlockProgressDialog = new ProgressDialog(mContext);
+            mSimUnlockProgressDialog.setMessage(
+                    mContext.getString(R.string.kg_sim_unlock_progress_dialog_message));
+            mSimUnlockProgressDialog.setIndeterminate(true);
+            mSimUnlockProgressDialog.setCancelable(false);
+            if (!(mContext instanceof Activity)) {
+                mSimUnlockProgressDialog.getWindow().setType(
+                        WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
+            }
+        }
+        return mSimUnlockProgressDialog;
+    }
+
+    private boolean checkPuk() {
+        // make sure the puk is at least 8 digits long.
+        if (mPasswordEntry.getText().length() >= 8) {
+            mPukText = mPasswordEntry.getText().toString();
+            return true;
+        }
+        return false;
+    }
+
+    private boolean checkPin() {
+        // make sure the PIN is between 4 and 8 digits
+        int length = mPasswordEntry.getText().length();
+        if (length >= 4 && length <= 8) {
+            mPinText = mPasswordEntry.getText().toString();
+            return true;
+        }
+        return false;
+    }
+
+    public boolean confirmPin() {
+        return mPinText.equals(mPasswordEntry.getText().toString());
+    }
+
+    private void updateSim() {
+        getSimUnlockProgressDialog().show();
+
+        if (!mCheckInProgress) {
+            mCheckInProgress = true;
+            new CheckSimPuk(mPukText, mPinText) {
+                void onSimLockChangedResponse(final boolean success) {
+                    post(new Runnable() {
+                        public void run() {
+                            if (mSimUnlockProgressDialog != null) {
+                                mSimUnlockProgressDialog.hide();
+                            }
+                            if (success) {
+                                mCallback.dismiss(true);
+                            } else {
+                                mStateMachine.reset();
+                                mSecurityMessageDisplay.setMessage(R.string.kg_invalid_puk, true);
+                            }
+                            mCheckInProgress = false;
+                        }
+                    });
+                }
+            }.start();
+        }
+    }
+
+    @Override
+    protected void verifyPasswordAndUnlock() {
+        mStateMachine.next();
+    }
+}
+
+
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
new file mode 100644
index 0000000..29f76f3
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
@@ -0,0 +1,154 @@
+/*
+ * 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.keyguard;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Typeface;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.util.Slog;
+import android.view.View;
+import android.widget.GridLayout;
+import android.widget.TextView;
+
+import com.android.internal.widget.LockPatternUtils;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+import libcore.icu.ICU;
+
+public class KeyguardStatusView extends GridLayout {
+    private static final boolean DEBUG = KeyguardViewMediator.DEBUG;
+    private static final String TAG = "KeyguardStatusView";
+
+    public static final int LOCK_ICON = 0; // R.drawable.ic_lock_idle_lock;
+    public static final int ALARM_ICON = R.drawable.ic_lock_idle_alarm;
+    public static final int CHARGING_ICON = 0; //R.drawable.ic_lock_idle_charging;
+    public static final int BATTERY_LOW_ICON = 0; //R.drawable.ic_lock_idle_low_battery;
+
+    private SimpleDateFormat mDateFormat;
+    private LockPatternUtils mLockPatternUtils;
+
+    private TextView mDateView;
+    private TextView mAlarmStatusView;
+    private ClockView mClockView;
+
+    private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
+
+        @Override
+        public void onTimeChanged() {
+            refresh();
+        }
+
+        @Override
+        void onKeyguardVisibilityChanged(boolean showing) {
+            if (showing) {
+                if (DEBUG) Slog.v(TAG, "refresh statusview showing:" + showing);
+                refresh();
+            }
+        };
+    };
+
+    public KeyguardStatusView(Context context) {
+        this(context, null, 0);
+    }
+
+    public KeyguardStatusView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public KeyguardStatusView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        Resources res = getContext().getResources();
+        final Locale locale = Locale.getDefault();
+        final String datePattern = res.getString(R.string.system_ui_date_pattern);
+        final String bestFormat = ICU.getBestDateTimePattern(datePattern, locale.toString());
+        mDateFormat = new SimpleDateFormat(bestFormat, locale);
+        mDateView = (TextView) findViewById(R.id.date);
+        mAlarmStatusView = (TextView) findViewById(R.id.alarm_status);
+        mClockView = (ClockView) findViewById(R.id.clock_view);
+        mLockPatternUtils = new LockPatternUtils(getContext());
+
+        // Use custom font in mDateView
+        mDateView.setTypeface(Typeface.SANS_SERIF, Typeface.BOLD);
+
+        // Required to get Marquee to work.
+        final View marqueeViews[] = { mDateView, mAlarmStatusView };
+        for (int i = 0; i < marqueeViews.length; i++) {
+            View v = marqueeViews[i];
+            if (v == null) {
+                throw new RuntimeException("Can't find widget at index " + i);
+            }
+            v.setSelected(true);
+        }
+        refresh();
+    }
+
+    protected void refresh() {
+        mClockView.updateTime();
+        refreshDate();
+        refreshAlarmStatus(); // might as well
+    }
+
+    void refreshAlarmStatus() {
+        // Update Alarm status
+        String nextAlarm = mLockPatternUtils.getNextAlarm();
+        if (!TextUtils.isEmpty(nextAlarm)) {
+            maybeSetUpperCaseText(mAlarmStatusView, nextAlarm);
+            mAlarmStatusView.setCompoundDrawablesWithIntrinsicBounds(ALARM_ICON, 0, 0, 0);
+            mAlarmStatusView.setVisibility(View.VISIBLE);
+        } else {
+            mAlarmStatusView.setVisibility(View.GONE);
+        }
+    }
+
+    void refreshDate() {
+        maybeSetUpperCaseText(mDateView, mDateFormat.format(new Date()));
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mInfoCallback);
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mInfoCallback);
+    }
+
+    public int getAppWidgetId() {
+        return LockPatternUtils.ID_DEFAULT_STATUS_WIDGET;
+    }
+
+    private void maybeSetUpperCaseText(TextView textView, CharSequence text) {
+        if (KeyguardViewManager.USE_UPPER_CASE) {
+            textView.setText(text != null ? text.toString().toUpperCase() : null);
+        } else {
+            textView.setText(text);
+        }
+    }
+}
diff --git a/cmds/system_server/MODULE_LICENSE_APACHE2 b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusViewManager.java
similarity index 100%
copy from cmds/system_server/MODULE_LICENSE_APACHE2
copy to packages/Keyguard/src/com/android/keyguard/KeyguardStatusViewManager.java
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardTransportControlView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardTransportControlView.java
new file mode 100644
index 0000000..3208aff
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardTransportControlView.java
@@ -0,0 +1,468 @@
+/*
+ * 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.keyguard;
+
+import android.app.PendingIntent;
+import android.app.PendingIntent.CanceledException;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.media.AudioManager;
+import android.media.IRemoteControlDisplay;
+import android.media.MediaMetadataRetriever;
+import android.media.RemoteControlClient;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.text.Spannable;
+import android.text.TextUtils;
+import android.text.style.ForegroundColorSpan;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import java.lang.ref.WeakReference;
+/**
+ * This is the widget responsible for showing music controls in keyguard.
+ */
+public class KeyguardTransportControlView extends FrameLayout implements OnClickListener {
+
+    private static final int MSG_UPDATE_STATE = 100;
+    private static final int MSG_SET_METADATA = 101;
+    private static final int MSG_SET_TRANSPORT_CONTROLS = 102;
+    private static final int MSG_SET_ARTWORK = 103;
+    private static final int MSG_SET_GENERATION_ID = 104;
+    private static final int DISPLAY_TIMEOUT_MS = 5000; // 5s
+    protected static final boolean DEBUG = false;
+    protected static final String TAG = "TransportControlView";
+
+    private ImageView mAlbumArt;
+    private TextView mTrackTitle;
+    private ImageView mBtnPrev;
+    private ImageView mBtnPlay;
+    private ImageView mBtnNext;
+    private int mClientGeneration;
+    private Metadata mMetadata = new Metadata();
+    private boolean mAttached;
+    private PendingIntent mClientIntent;
+    private int mTransportControlFlags;
+    private int mCurrentPlayState;
+    private AudioManager mAudioManager;
+    private IRemoteControlDisplayWeak mIRCD;
+
+    /**
+     * The metadata which should be populated into the view once we've been attached
+     */
+    private Bundle mPopulateMetadataWhenAttached = null;
+
+    // This handler is required to ensure messages from IRCD are handled in sequence and on
+    // the UI thread.
+    private Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+            case MSG_UPDATE_STATE:
+                if (mClientGeneration == msg.arg1) updatePlayPauseState(msg.arg2);
+                break;
+
+            case MSG_SET_METADATA:
+                if (mClientGeneration == msg.arg1) updateMetadata((Bundle) msg.obj);
+                break;
+
+            case MSG_SET_TRANSPORT_CONTROLS:
+                if (mClientGeneration == msg.arg1) updateTransportControls(msg.arg2);
+                break;
+
+            case MSG_SET_ARTWORK:
+                if (mClientGeneration == msg.arg1) {
+                    if (mMetadata.bitmap != null) {
+                        mMetadata.bitmap.recycle();
+                    }
+                    mMetadata.bitmap = (Bitmap) msg.obj;
+                    mAlbumArt.setImageBitmap(mMetadata.bitmap);
+                }
+                break;
+
+            case MSG_SET_GENERATION_ID:
+                if (DEBUG) Log.v(TAG, "New genId = " + msg.arg1 + ", clearing = " + msg.arg2);
+                mClientGeneration = msg.arg1;
+                mClientIntent = (PendingIntent) msg.obj;
+                break;
+
+            }
+        }
+    };
+
+    /**
+     * This class is required to have weak linkage to the current TransportControlView
+     * because the remote process can hold a strong reference to this binder object and
+     * we can't predict when it will be GC'd in the remote process. Without this code, it
+     * would allow a heavyweight object to be held on this side of the binder when there's
+     * no requirement to run a GC on the other side.
+     */
+    private static class IRemoteControlDisplayWeak extends IRemoteControlDisplay.Stub {
+        private WeakReference<Handler> mLocalHandler;
+
+        IRemoteControlDisplayWeak(Handler handler) {
+            mLocalHandler = new WeakReference<Handler>(handler);
+        }
+
+        public void setPlaybackState(int generationId, int state, long stateChangeTimeMs,
+                long currentPosMs, float speed) {
+            Handler handler = mLocalHandler.get();
+            if (handler != null) {
+                handler.obtainMessage(MSG_UPDATE_STATE, generationId, state).sendToTarget();
+            }
+        }
+
+        public void setMetadata(int generationId, Bundle metadata) {
+            Handler handler = mLocalHandler.get();
+            if (handler != null) {
+                handler.obtainMessage(MSG_SET_METADATA, generationId, 0, metadata).sendToTarget();
+            }
+        }
+
+        public void setTransportControlInfo(int generationId, int flags, int posCapabilities) {
+            Handler handler = mLocalHandler.get();
+            if (handler != null) {
+                handler.obtainMessage(MSG_SET_TRANSPORT_CONTROLS, generationId, flags)
+                        .sendToTarget();
+            }
+        }
+
+        public void setArtwork(int generationId, Bitmap bitmap) {
+            Handler handler = mLocalHandler.get();
+            if (handler != null) {
+                handler.obtainMessage(MSG_SET_ARTWORK, generationId, 0, bitmap).sendToTarget();
+            }
+        }
+
+        public void setAllMetadata(int generationId, Bundle metadata, Bitmap bitmap) {
+            Handler handler = mLocalHandler.get();
+            if (handler != null) {
+                handler.obtainMessage(MSG_SET_METADATA, generationId, 0, metadata).sendToTarget();
+                handler.obtainMessage(MSG_SET_ARTWORK, generationId, 0, bitmap).sendToTarget();
+            }
+        }
+
+        public void setCurrentClientId(int clientGeneration, PendingIntent mediaIntent,
+                boolean clearing) throws RemoteException {
+            Handler handler = mLocalHandler.get();
+            if (handler != null) {
+                handler.obtainMessage(MSG_SET_GENERATION_ID,
+                    clientGeneration, (clearing ? 1 : 0), mediaIntent).sendToTarget();
+            }
+        }
+    };
+
+    public KeyguardTransportControlView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        if (DEBUG) Log.v(TAG, "Create TCV " + this);
+        mAudioManager = new AudioManager(mContext);
+        mCurrentPlayState = RemoteControlClient.PLAYSTATE_NONE; // until we get a callback
+        mIRCD = new IRemoteControlDisplayWeak(mHandler);
+    }
+
+    private void updateTransportControls(int transportControlFlags) {
+        mTransportControlFlags = transportControlFlags;
+    }
+
+    @Override
+    public void onFinishInflate() {
+        super.onFinishInflate();
+        mTrackTitle = (TextView) findViewById(R.id.title);
+        mTrackTitle.setSelected(true); // enable marquee
+        mAlbumArt = (ImageView) findViewById(R.id.albumart);
+        mBtnPrev = (ImageView) findViewById(R.id.btn_prev);
+        mBtnPlay = (ImageView) findViewById(R.id.btn_play);
+        mBtnNext = (ImageView) findViewById(R.id.btn_next);
+        final View buttons[] = { mBtnPrev, mBtnPlay, mBtnNext };
+        for (View view : buttons) {
+            view.setOnClickListener(this);
+        }
+    }
+
+    @Override
+    public void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        if (DEBUG) Log.v(TAG, "onAttachToWindow()");
+        if (mPopulateMetadataWhenAttached != null) {
+            updateMetadata(mPopulateMetadataWhenAttached);
+            mPopulateMetadataWhenAttached = null;
+        }
+        if (!mAttached) {
+            if (DEBUG) Log.v(TAG, "Registering TCV " + this);
+            mAudioManager.registerRemoteControlDisplay(mIRCD);
+        }
+        mAttached = true;
+    }
+
+    @Override
+    protected void onSizeChanged (int w, int h, int oldw, int oldh) {
+        if (mAttached) {
+            int dim = Math.min(512, Math.max(w, h));
+            if (DEBUG) Log.v(TAG, "TCV uses bitmap size=" + dim);
+            mAudioManager.remoteControlDisplayUsesBitmapSize(mIRCD, dim, dim);
+        }
+    }
+
+    @Override
+    public void onDetachedFromWindow() {
+        if (DEBUG) Log.v(TAG, "onDetachFromWindow()");
+        super.onDetachedFromWindow();
+        if (mAttached) {
+            if (DEBUG) Log.v(TAG, "Unregistering TCV " + this);
+            mAudioManager.unregisterRemoteControlDisplay(mIRCD);
+        }
+        mAttached = false;
+    }
+
+    class Metadata {
+        private String artist;
+        private String trackTitle;
+        private String albumTitle;
+        private Bitmap bitmap;
+
+        public String toString() {
+            return "Metadata[artist=" + artist + " trackTitle=" + trackTitle + " albumTitle=" + albumTitle + "]";
+        }
+    }
+
+    private String getMdString(Bundle data, int id) {
+        return data.getString(Integer.toString(id));
+    }
+
+    private void updateMetadata(Bundle data) {
+        if (mAttached) {
+            mMetadata.artist = getMdString(data, MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST);
+            mMetadata.trackTitle = getMdString(data, MediaMetadataRetriever.METADATA_KEY_TITLE);
+            mMetadata.albumTitle = getMdString(data, MediaMetadataRetriever.METADATA_KEY_ALBUM);
+            populateMetadata();
+        } else {
+            mPopulateMetadataWhenAttached = data;
+        }
+    }
+
+    /**
+     * Populates the given metadata into the view
+     */
+    private void populateMetadata() {
+        StringBuilder sb = new StringBuilder();
+        int trackTitleLength = 0;
+        if (!TextUtils.isEmpty(mMetadata.trackTitle)) {
+            sb.append(mMetadata.trackTitle);
+            trackTitleLength = mMetadata.trackTitle.length();
+        }
+        if (!TextUtils.isEmpty(mMetadata.artist)) {
+            if (sb.length() != 0) {
+                sb.append(" - ");
+            }
+            sb.append(mMetadata.artist);
+        }
+        if (!TextUtils.isEmpty(mMetadata.albumTitle)) {
+            if (sb.length() != 0) {
+                sb.append(" - ");
+            }
+            sb.append(mMetadata.albumTitle);
+        }
+        mTrackTitle.setText(sb.toString(), TextView.BufferType.SPANNABLE);
+        Spannable str = (Spannable) mTrackTitle.getText();
+        if (trackTitleLength != 0) {
+            str.setSpan(new ForegroundColorSpan(0xffffffff), 0, trackTitleLength,
+                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+            trackTitleLength++;
+        }
+        if (sb.length() > trackTitleLength) {
+            str.setSpan(new ForegroundColorSpan(0x7fffffff), trackTitleLength, sb.length(),
+                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+        }
+
+        mAlbumArt.setImageBitmap(mMetadata.bitmap);
+        final int flags = mTransportControlFlags;
+        setVisibilityBasedOnFlag(mBtnPrev, flags, RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS);
+        setVisibilityBasedOnFlag(mBtnNext, flags, RemoteControlClient.FLAG_KEY_MEDIA_NEXT);
+        setVisibilityBasedOnFlag(mBtnPlay, flags,
+                RemoteControlClient.FLAG_KEY_MEDIA_PLAY
+                | RemoteControlClient.FLAG_KEY_MEDIA_PAUSE
+                | RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE
+                | RemoteControlClient.FLAG_KEY_MEDIA_STOP);
+
+        updatePlayPauseState(mCurrentPlayState);
+    }
+
+    private static void setVisibilityBasedOnFlag(View view, int flags, int flag) {
+        if ((flags & flag) != 0) {
+            view.setVisibility(View.VISIBLE);
+        } else {
+            view.setVisibility(View.GONE);
+        }
+    }
+
+    private void updatePlayPauseState(int state) {
+        if (DEBUG) Log.v(TAG,
+                "updatePlayPauseState(), old=" + mCurrentPlayState + ", state=" + state);
+        if (state == mCurrentPlayState) {
+            return;
+        }
+        final int imageResId;
+        final int imageDescId;
+        switch (state) {
+            case RemoteControlClient.PLAYSTATE_ERROR:
+                imageResId = R.drawable.stat_sys_warning;
+                // TODO use more specific image description string for warning, but here the "play"
+                //      message is still valid because this button triggers a play command.
+                imageDescId = R.string.keyguard_transport_play_description;
+                break;
+
+            case RemoteControlClient.PLAYSTATE_PLAYING:
+                imageResId = R.drawable.ic_media_pause;
+                imageDescId = R.string.keyguard_transport_pause_description;
+                break;
+
+            case RemoteControlClient.PLAYSTATE_BUFFERING:
+                imageResId = R.drawable.ic_media_stop;
+                imageDescId = R.string.keyguard_transport_stop_description;
+                break;
+
+            case RemoteControlClient.PLAYSTATE_PAUSED:
+            default:
+                imageResId = R.drawable.ic_media_play;
+                imageDescId = R.string.keyguard_transport_play_description;
+                break;
+        }
+        mBtnPlay.setImageResource(imageResId);
+        mBtnPlay.setContentDescription(getResources().getString(imageDescId));
+        mCurrentPlayState = state;
+    }
+
+    static class SavedState extends BaseSavedState {
+        boolean clientPresent;
+
+        SavedState(Parcelable superState) {
+            super(superState);
+        }
+
+        private SavedState(Parcel in) {
+            super(in);
+            this.clientPresent = in.readInt() != 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel out, int flags) {
+            super.writeToParcel(out, flags);
+            out.writeInt(this.clientPresent ? 1 : 0);
+        }
+
+        public static final Parcelable.Creator<SavedState> CREATOR
+                = new Parcelable.Creator<SavedState>() {
+            public SavedState createFromParcel(Parcel in) {
+                return new SavedState(in);
+            }
+
+            public SavedState[] newArray(int size) {
+                return new SavedState[size];
+            }
+        };
+    }
+
+    public void onClick(View v) {
+        int keyCode = -1;
+        if (v == mBtnPrev) {
+            keyCode = KeyEvent.KEYCODE_MEDIA_PREVIOUS;
+        } else if (v == mBtnNext) {
+            keyCode = KeyEvent.KEYCODE_MEDIA_NEXT;
+        } else if (v == mBtnPlay) {
+            keyCode = KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE;
+
+        }
+        if (keyCode != -1) {
+            sendMediaButtonClick(keyCode);
+        }
+    }
+
+    private void sendMediaButtonClick(int keyCode) {
+        if (mClientIntent == null) {
+            // Shouldn't be possible because this view should be hidden in this case.
+            Log.e(TAG, "sendMediaButtonClick(): No client is currently registered");
+            return;
+        }
+        // use the registered PendingIntent that will be processed by the registered
+        //    media button event receiver, which is the component of mClientIntent
+        KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
+        Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
+        intent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
+        try {
+            mClientIntent.send(getContext(), 0, intent);
+        } catch (CanceledException e) {
+            Log.e(TAG, "Error sending intent for media button down: "+e);
+            e.printStackTrace();
+        }
+
+        keyEvent = new KeyEvent(KeyEvent.ACTION_UP, keyCode);
+        intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
+        intent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
+        try {
+            mClientIntent.send(getContext(), 0, intent);
+        } catch (CanceledException e) {
+            Log.e(TAG, "Error sending intent for media button up: "+e);
+            e.printStackTrace();
+        }
+    }
+
+    public boolean providesClock() {
+        return false;
+    }
+
+    private boolean wasPlayingRecently(int state, long stateChangeTimeMs) {
+        switch (state) {
+            case RemoteControlClient.PLAYSTATE_PLAYING:
+            case RemoteControlClient.PLAYSTATE_FAST_FORWARDING:
+            case RemoteControlClient.PLAYSTATE_REWINDING:
+            case RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS:
+            case RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS:
+            case RemoteControlClient.PLAYSTATE_BUFFERING:
+                // actively playing or about to play
+                return true;
+            case RemoteControlClient.PLAYSTATE_NONE:
+                return false;
+            case RemoteControlClient.PLAYSTATE_STOPPED:
+            case RemoteControlClient.PLAYSTATE_PAUSED:
+            case RemoteControlClient.PLAYSTATE_ERROR:
+                // we have stopped playing, check how long ago
+                if (DEBUG) {
+                    if ((SystemClock.elapsedRealtime() - stateChangeTimeMs) < DISPLAY_TIMEOUT_MS) {
+                        Log.v(TAG, "wasPlayingRecently: time < TIMEOUT was playing recently");
+                    } else {
+                        Log.v(TAG, "wasPlayingRecently: time > TIMEOUT");
+                    }
+                }
+                return ((SystemClock.elapsedRealtime() - stateChangeTimeMs) < DISPLAY_TIMEOUT_MS);
+            default:
+                Log.e(TAG, "Unknown playback state " + state + " in wasPlayingRecently()");
+                return false;
+        }
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
new file mode 100644
index 0000000..dcec654
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -0,0 +1,982 @@
+/*
+ * 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.keyguard;
+
+import android.app.ActivityManagerNative;
+import android.app.IUserSwitchObserver;
+import android.app.PendingIntent;
+import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.graphics.Bitmap;
+
+import static android.os.BatteryManager.BATTERY_STATUS_FULL;
+import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
+import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
+import static android.os.BatteryManager.EXTRA_STATUS;
+import static android.os.BatteryManager.EXTRA_PLUGGED;
+import static android.os.BatteryManager.EXTRA_LEVEL;
+import static android.os.BatteryManager.EXTRA_HEALTH;
+import android.media.AudioManager;
+import android.media.IRemoteControlDisplay;
+import android.os.BatteryManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IRemoteCallback;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.provider.Settings;
+
+import com.android.internal.telephony.IccCardConstants;
+import com.android.internal.telephony.TelephonyIntents;
+
+import android.telephony.TelephonyManager;
+import android.util.Log;
+import com.google.android.collect.Lists;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+
+/**
+ * Watches for updates that may be interesting to the keyguard, and provides
+ * the up to date information as well as a registration for callbacks that care
+ * to be updated.
+ *
+ * Note: under time crunch, this has been extended to include some stuff that
+ * doesn't really belong here.  see {@link #handleBatteryUpdate} where it shutdowns
+ * the device, and {@link #getFailedUnlockAttempts()}, {@link #reportFailedAttempt()}
+ * and {@link #clearFailedUnlockAttempts()}.  Maybe we should rename this 'KeyguardContext'...
+ */
+public class KeyguardUpdateMonitor {
+
+    private static final String TAG = "KeyguardUpdateMonitor";
+    private static final boolean DEBUG = false;
+    private static final boolean DEBUG_SIM_STATES = DEBUG || false;
+    private static final int FAILED_BIOMETRIC_UNLOCK_ATTEMPTS_BEFORE_BACKUP = 3;
+    private static final int LOW_BATTERY_THRESHOLD = 20;
+
+    // Callback messages
+    private static final int MSG_TIME_UPDATE = 301;
+    private static final int MSG_BATTERY_UPDATE = 302;
+    private static final int MSG_CARRIER_INFO_UPDATE = 303;
+    private static final int MSG_SIM_STATE_CHANGE = 304;
+    private static final int MSG_RINGER_MODE_CHANGED = 305;
+    private static final int MSG_PHONE_STATE_CHANGED = 306;
+    private static final int MSG_CLOCK_VISIBILITY_CHANGED = 307;
+    private static final int MSG_DEVICE_PROVISIONED = 308;
+    private static final int MSG_DPM_STATE_CHANGED = 309;
+    private static final int MSG_USER_SWITCHING = 310;
+    private static final int MSG_USER_REMOVED = 311;
+    private static final int MSG_KEYGUARD_VISIBILITY_CHANGED = 312;
+    protected static final int MSG_BOOT_COMPLETED = 313;
+    private static final int MSG_USER_SWITCH_COMPLETE = 314;
+    private static final int MSG_SET_CURRENT_CLIENT_ID = 315;
+    protected static final int MSG_SET_PLAYBACK_STATE = 316;
+    protected static final int MSG_USER_INFO_CHANGED = 317;
+
+
+    private static KeyguardUpdateMonitor sInstance;
+
+    private final Context mContext;
+
+    // Telephony state
+    private IccCardConstants.State mSimState = IccCardConstants.State.READY;
+    private CharSequence mTelephonyPlmn;
+    private CharSequence mTelephonySpn;
+    private int mRingMode;
+    private int mPhoneState;
+    private boolean mKeyguardIsVisible;
+    private boolean mBootCompleted;
+
+    // Device provisioning state
+    private boolean mDeviceProvisioned;
+
+    // Battery status
+    private BatteryStatus mBatteryStatus;
+
+    // Password attempts
+    private int mFailedAttempts = 0;
+    private int mFailedBiometricUnlockAttempts = 0;
+
+    private boolean mAlternateUnlockEnabled;
+
+    private boolean mClockVisible;
+
+    private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
+            mCallbacks = Lists.newArrayList();
+    private ContentObserver mDeviceProvisionedObserver;
+
+    private boolean mSwitchingUser;
+
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_TIME_UPDATE:
+                    handleTimeUpdate();
+                    break;
+                case MSG_BATTERY_UPDATE:
+                    handleBatteryUpdate((BatteryStatus) msg.obj);
+                    break;
+                case MSG_CARRIER_INFO_UPDATE:
+                    handleCarrierInfoUpdate();
+                    break;
+                case MSG_SIM_STATE_CHANGE:
+                    handleSimStateChange((SimArgs) msg.obj);
+                    break;
+                case MSG_RINGER_MODE_CHANGED:
+                    handleRingerModeChange(msg.arg1);
+                    break;
+                case MSG_PHONE_STATE_CHANGED:
+                    handlePhoneStateChanged((String)msg.obj);
+                    break;
+                case MSG_CLOCK_VISIBILITY_CHANGED:
+                    handleClockVisibilityChanged();
+                    break;
+                case MSG_DEVICE_PROVISIONED:
+                    handleDeviceProvisioned();
+                    break;
+                case MSG_DPM_STATE_CHANGED:
+                    handleDevicePolicyManagerStateChanged();
+                    break;
+                case MSG_USER_SWITCHING:
+                    handleUserSwitching(msg.arg1, (IRemoteCallback)msg.obj);
+                    break;
+                case MSG_USER_SWITCH_COMPLETE:
+                    handleUserSwitchComplete(msg.arg1);
+                    break;
+                case MSG_USER_REMOVED:
+                    handleUserRemoved(msg.arg1);
+                    break;
+                case MSG_KEYGUARD_VISIBILITY_CHANGED:
+                    handleKeyguardVisibilityChanged(msg.arg1);
+                    break;
+                case MSG_BOOT_COMPLETED:
+                    handleBootCompleted();
+                    break;
+                case MSG_SET_CURRENT_CLIENT_ID:
+                    handleSetGenerationId(msg.arg1, msg.arg2 != 0, (PendingIntent) msg.obj);
+                    break;
+                case MSG_SET_PLAYBACK_STATE:
+                    handleSetPlaybackState(msg.arg1, msg.arg2, (Long) msg.obj);
+                    break;
+                case MSG_USER_INFO_CHANGED:
+                    handleUserInfoChanged(msg.arg1);
+                    break;
+            }
+        }
+    };
+
+    private AudioManager mAudioManager;
+
+    static class DisplayClientState {
+        public int clientGeneration;
+        public boolean clearing;
+        public PendingIntent intent;
+        public int playbackState;
+        public long playbackEventTime;
+    }
+
+    private DisplayClientState mDisplayClientState = new DisplayClientState();
+
+    /**
+     * This currently implements the bare minimum required to enable showing and hiding
+     * KeyguardTransportControl.  There's a lot of client state to maintain which is why
+     * KeyguardTransportControl maintains an independent connection while it's showing.
+     */
+    private final IRemoteControlDisplay.Stub mRemoteControlDisplay =
+                new IRemoteControlDisplay.Stub() {
+
+        public void setPlaybackState(int generationId, int state, long stateChangeTimeMs,
+                long currentPosMs, float speed) {
+            Message msg = mHandler.obtainMessage(MSG_SET_PLAYBACK_STATE,
+                    generationId, state, stateChangeTimeMs);
+            mHandler.sendMessage(msg);
+        }
+
+        public void setMetadata(int generationId, Bundle metadata) {
+
+        }
+
+        public void setTransportControlInfo(int generationId, int flags, int posCapabilities) {
+
+        }
+
+        public void setArtwork(int generationId, Bitmap bitmap) {
+
+        }
+
+        public void setAllMetadata(int generationId, Bundle metadata, Bitmap bitmap) {
+
+        }
+
+        public void setCurrentClientId(int clientGeneration, PendingIntent mediaIntent,
+                boolean clearing) throws RemoteException {
+            Message msg = mHandler.obtainMessage(MSG_SET_CURRENT_CLIENT_ID,
+                        clientGeneration, (clearing ? 1 : 0), mediaIntent);
+            mHandler.sendMessage(msg);
+        }
+    };
+
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+
+        public void onReceive(Context context, Intent intent) {
+            final String action = intent.getAction();
+            if (DEBUG) Log.d(TAG, "received broadcast " + action);
+
+            if (Intent.ACTION_TIME_TICK.equals(action)
+                    || Intent.ACTION_TIME_CHANGED.equals(action)
+                    || Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
+                mHandler.sendMessage(mHandler.obtainMessage(MSG_TIME_UPDATE));
+            } else if (TelephonyIntents.SPN_STRINGS_UPDATED_ACTION.equals(action)) {
+                mTelephonyPlmn = getTelephonyPlmnFrom(intent);
+                mTelephonySpn = getTelephonySpnFrom(intent);
+                mHandler.sendMessage(mHandler.obtainMessage(MSG_CARRIER_INFO_UPDATE));
+            } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
+                final int status = intent.getIntExtra(EXTRA_STATUS, BATTERY_STATUS_UNKNOWN);
+                final int plugged = intent.getIntExtra(EXTRA_PLUGGED, 0);
+                final int level = intent.getIntExtra(EXTRA_LEVEL, 0);
+                final int health = intent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
+                final Message msg = mHandler.obtainMessage(
+                        MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health));
+                mHandler.sendMessage(msg);
+            } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
+                if (DEBUG_SIM_STATES) {
+                    Log.v(TAG, "action " + action + " state" +
+                        intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE));
+                }
+                mHandler.sendMessage(mHandler.obtainMessage(
+                        MSG_SIM_STATE_CHANGE, SimArgs.fromIntent(intent)));
+            } else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
+                mHandler.sendMessage(mHandler.obtainMessage(MSG_RINGER_MODE_CHANGED,
+                        intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1), 0));
+            } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
+                String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
+                mHandler.sendMessage(mHandler.obtainMessage(MSG_PHONE_STATE_CHANGED, state));
+            } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
+                    .equals(action)) {
+                mHandler.sendMessage(mHandler.obtainMessage(MSG_DPM_STATE_CHANGED));
+            } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
+                mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_REMOVED,
+                       intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0), 0));
+            } else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
+                mHandler.sendMessage(mHandler.obtainMessage(MSG_BOOT_COMPLETED));
+            }
+        }
+    };
+
+    private final BroadcastReceiver mBroadcastAllReceiver = new BroadcastReceiver() {
+
+        public void onReceive(Context context, Intent intent) {
+            final String action = intent.getAction();
+            if (Intent.ACTION_USER_INFO_CHANGED.equals(action)) {
+                mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_INFO_CHANGED,
+                        intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId()), 0));
+            }
+        }
+    };
+
+    /**
+     * When we receive a
+     * {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast,
+     * and then pass a result via our handler to {@link KeyguardUpdateMonitor#handleSimStateChange},
+     * we need a single object to pass to the handler.  This class helps decode
+     * the intent and provide a {@link SimCard.State} result.
+     */
+    private static class SimArgs {
+        public final IccCardConstants.State simState;
+
+        SimArgs(IccCardConstants.State state) {
+            simState = state;
+        }
+
+        static SimArgs fromIntent(Intent intent) {
+            IccCardConstants.State state;
+            if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
+                throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
+            }
+            String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
+            if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
+                final String absentReason = intent
+                    .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
+
+                if (IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
+                        absentReason)) {
+                    state = IccCardConstants.State.PERM_DISABLED;
+                } else {
+                    state = IccCardConstants.State.ABSENT;
+                }
+            } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
+                state = IccCardConstants.State.READY;
+            } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
+                final String lockedReason = intent
+                        .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
+                if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
+                    state = IccCardConstants.State.PIN_REQUIRED;
+                } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
+                    state = IccCardConstants.State.PUK_REQUIRED;
+                } else {
+                    state = IccCardConstants.State.UNKNOWN;
+                }
+            } else if (IccCardConstants.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
+                state = IccCardConstants.State.NETWORK_LOCKED;
+            } 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
+                // these state transitions. See bug 7197471.
+                state = IccCardConstants.State.READY;
+            } else {
+                state = IccCardConstants.State.UNKNOWN;
+            }
+            return new SimArgs(state);
+        }
+
+        public String toString() {
+            return simState.toString();
+        }
+    }
+
+    /* package */ static class BatteryStatus {
+        public final int status;
+        public final int level;
+        public final int plugged;
+        public final int health;
+        public BatteryStatus(int status, int level, int plugged, int health) {
+            this.status = status;
+            this.level = level;
+            this.plugged = plugged;
+            this.health = health;
+        }
+
+        /**
+         * Determine whether the device is plugged in (USB, power, or wireless).
+         * @return true if the device is plugged in.
+         */
+        boolean isPluggedIn() {
+            return plugged == BatteryManager.BATTERY_PLUGGED_AC
+                    || plugged == BatteryManager.BATTERY_PLUGGED_USB
+                    || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
+        }
+
+        /**
+         * Whether or not the device is charged. Note that some devices never return 100% for
+         * battery level, so this allows either battery level or status to determine if the
+         * battery is charged.
+         * @return true if the device is charged
+         */
+        public boolean isCharged() {
+            return status == BATTERY_STATUS_FULL || level >= 100;
+        }
+
+        /**
+         * Whether battery is low and needs to be charged.
+         * @return true if battery is low
+         */
+        public boolean isBatteryLow() {
+            return level < LOW_BATTERY_THRESHOLD;
+        }
+
+    }
+
+    public static KeyguardUpdateMonitor getInstance(Context context) {
+        if (sInstance == null) {
+            sInstance = new KeyguardUpdateMonitor(context);
+        }
+        return sInstance;
+    }
+
+    protected void handleSetGenerationId(int clientGeneration, boolean clearing, PendingIntent p) {
+        mDisplayClientState.clientGeneration = clientGeneration;
+        mDisplayClientState.clearing = clearing;
+        mDisplayClientState.intent = p;
+        if (DEBUG)
+            Log.v(TAG, "handleSetGenerationId(g=" + clientGeneration + ", clear=" + clearing + ")");
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+            if (cb != null) {
+                cb.onMusicClientIdChanged(clientGeneration, clearing, p);
+            }
+        }
+    }
+
+    protected void handleSetPlaybackState(int generationId, int playbackState, long eventTime) {
+        if (DEBUG)
+            Log.v(TAG, "handleSetPlaybackState(gen=" + generationId
+                + ", state=" + playbackState + ", t=" + eventTime + ")");
+        mDisplayClientState.playbackState = playbackState;
+        mDisplayClientState.playbackEventTime = eventTime;
+        if (generationId == mDisplayClientState.clientGeneration) {
+            for (int i = 0; i < mCallbacks.size(); i++) {
+                KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+                if (cb != null) {
+                    cb.onMusicPlaybackStateChanged(playbackState, eventTime);
+                }
+            }
+        } else {
+            Log.w(TAG, "Ignoring generation id " + generationId + " because it's not current");
+        }
+    }
+
+    private void handleUserInfoChanged(int userId) {
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+            if (cb != null) {
+                cb.onUserInfoChanged(userId);
+            }
+        }
+    }
+
+    private KeyguardUpdateMonitor(Context context) {
+        mContext = context;
+
+        mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
+        // Since device can't be un-provisioned, we only need to register a content observer
+        // to update mDeviceProvisioned when we are...
+        if (!mDeviceProvisioned) {
+            watchForDeviceProvisioning();
+        }
+
+        // Take a guess at initial SIM state, battery status and PLMN until we get an update
+        mSimState = IccCardConstants.State.NOT_READY;
+        mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0);
+        mTelephonyPlmn = getDefaultPlmn();
+
+        // Watch for interesting updates
+        final IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_TIME_TICK);
+        filter.addAction(Intent.ACTION_TIME_CHANGED);
+        filter.addAction(Intent.ACTION_BATTERY_CHANGED);
+        filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
+        filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
+        filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
+        filter.addAction(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION);
+        filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
+        filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
+        filter.addAction(Intent.ACTION_USER_REMOVED);
+        context.registerReceiver(mBroadcastReceiver, filter);
+
+        final IntentFilter bootCompleteFilter = new IntentFilter();
+        bootCompleteFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
+        bootCompleteFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
+        context.registerReceiver(mBroadcastReceiver, bootCompleteFilter);
+
+        final IntentFilter userInfoFilter = new IntentFilter(Intent.ACTION_USER_INFO_CHANGED);
+        context.registerReceiverAsUser(mBroadcastAllReceiver, UserHandle.ALL, userInfoFilter,
+                null, null);
+
+        try {
+            ActivityManagerNative.getDefault().registerUserSwitchObserver(
+                    new IUserSwitchObserver.Stub() {
+                        @Override
+                        public void onUserSwitching(int newUserId, IRemoteCallback reply) {
+                            mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHING,
+                                    newUserId, 0, reply));
+                            mSwitchingUser = true;
+                        }
+                        @Override
+                        public void onUserSwitchComplete(int newUserId) throws RemoteException {
+                            mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCH_COMPLETE,
+                                    newUserId));
+                            mSwitchingUser = false;
+                        }
+                    });
+        } catch (RemoteException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+
+    private boolean isDeviceProvisionedInSettingsDb() {
+        return Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.DEVICE_PROVISIONED, 0) != 0;
+    }
+
+    private void watchForDeviceProvisioning() {
+        mDeviceProvisionedObserver = new ContentObserver(mHandler) {
+            @Override
+            public void onChange(boolean selfChange) {
+                super.onChange(selfChange);
+                mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
+                if (mDeviceProvisioned) {
+                    mHandler.sendMessage(mHandler.obtainMessage(MSG_DEVICE_PROVISIONED));
+                }
+                if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned);
+            }
+        };
+
+        mContext.getContentResolver().registerContentObserver(
+                Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
+                false, mDeviceProvisionedObserver);
+
+        // prevent a race condition between where we check the flag and where we register the
+        // observer by grabbing the value once again...
+        boolean provisioned = isDeviceProvisionedInSettingsDb();
+        if (provisioned != mDeviceProvisioned) {
+            mDeviceProvisioned = provisioned;
+            if (mDeviceProvisioned) {
+                mHandler.sendMessage(mHandler.obtainMessage(MSG_DEVICE_PROVISIONED));
+            }
+        }
+    }
+
+    /**
+     * Handle {@link #MSG_DPM_STATE_CHANGED}
+     */
+    protected void handleDevicePolicyManagerStateChanged() {
+        for (int i = mCallbacks.size() - 1; i >= 0; i--) {
+            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+            if (cb != null) {
+                cb.onDevicePolicyManagerStateChanged();
+            }
+        }
+    }
+
+    /**
+     * Handle {@link #MSG_USER_SWITCHING}
+     */
+    protected void handleUserSwitching(int userId, IRemoteCallback reply) {
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+            if (cb != null) {
+                cb.onUserSwitching(userId);
+            }
+        }
+        try {
+            reply.sendResult(null);
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
+     * Handle {@link #MSG_USER_SWITCH_COMPLETE}
+     */
+    protected void handleUserSwitchComplete(int userId) {
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+            if (cb != null) {
+                cb.onUserSwitchComplete(userId);
+            }
+        }
+    }
+
+    /**
+     * Handle {@link #MSG_BOOT_COMPLETED}
+     */
+    protected void handleBootCompleted() {
+        mBootCompleted = true;
+        mAudioManager = new AudioManager(mContext);
+        mAudioManager.registerRemoteControlDisplay(mRemoteControlDisplay);
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+            if (cb != null) {
+                cb.onBootCompleted();
+            }
+        }
+    }
+
+    /**
+     * We need to store this state in the KeyguardUpdateMonitor since this class will not be
+     * destroyed.
+     */
+    public boolean hasBootCompleted() {
+        return mBootCompleted;
+    }
+
+    /**
+     * Handle {@link #MSG_USER_REMOVED}
+     */
+    protected void handleUserRemoved(int userId) {
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+            if (cb != null) {
+                cb.onUserRemoved(userId);
+            }
+        }
+    }
+
+    /**
+     * Handle {@link #MSG_DEVICE_PROVISIONED}
+     */
+    protected void handleDeviceProvisioned() {
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+            if (cb != null) {
+                cb.onDeviceProvisioned();
+            }
+        }
+        if (mDeviceProvisionedObserver != null) {
+            // We don't need the observer anymore...
+            mContext.getContentResolver().unregisterContentObserver(mDeviceProvisionedObserver);
+            mDeviceProvisionedObserver = null;
+        }
+    }
+
+    /**
+     * Handle {@link #MSG_PHONE_STATE_CHANGED}
+     */
+    protected void handlePhoneStateChanged(String newState) {
+        if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")");
+        if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) {
+            mPhoneState = TelephonyManager.CALL_STATE_IDLE;
+        } else if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(newState)) {
+            mPhoneState = TelephonyManager.CALL_STATE_OFFHOOK;
+        } else if (TelephonyManager.EXTRA_STATE_RINGING.equals(newState)) {
+            mPhoneState = TelephonyManager.CALL_STATE_RINGING;
+        }
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+            if (cb != null) {
+                cb.onPhoneStateChanged(mPhoneState);
+            }
+        }
+    }
+
+    /**
+     * Handle {@link #MSG_RINGER_MODE_CHANGED}
+     */
+    protected void handleRingerModeChange(int mode) {
+        if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")");
+        mRingMode = mode;
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+            if (cb != null) {
+                cb.onRingerModeChanged(mode);
+            }
+        }
+    }
+
+    /**
+     * Handle {@link #MSG_TIME_UPDATE}
+     */
+    private void handleTimeUpdate() {
+        if (DEBUG) Log.d(TAG, "handleTimeUpdate");
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+            if (cb != null) {
+                cb.onTimeChanged();
+            }
+        }
+    }
+
+    /**
+     * Handle {@link #MSG_BATTERY_UPDATE}
+     */
+    private void handleBatteryUpdate(BatteryStatus status) {
+        if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
+        final boolean batteryUpdateInteresting = isBatteryUpdateInteresting(mBatteryStatus, status);
+        mBatteryStatus = status;
+        if (batteryUpdateInteresting) {
+            for (int i = 0; i < mCallbacks.size(); i++) {
+                KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+                if (cb != null) {
+                    cb.onRefreshBatteryInfo(status);
+                }
+            }
+        }
+    }
+
+    /**
+     * Handle {@link #MSG_CARRIER_INFO_UPDATE}
+     */
+    private void handleCarrierInfoUpdate() {
+        if (DEBUG) Log.d(TAG, "handleCarrierInfoUpdate: plmn = " + mTelephonyPlmn
+            + ", spn = " + mTelephonySpn);
+
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+            if (cb != null) {
+                cb.onRefreshCarrierInfo(mTelephonyPlmn, mTelephonySpn);
+            }
+        }
+    }
+
+    /**
+     * Handle {@link #MSG_SIM_STATE_CHANGE}
+     */
+    private void handleSimStateChange(SimArgs simArgs) {
+        final IccCardConstants.State state = simArgs.simState;
+
+        if (DEBUG) {
+            Log.d(TAG, "handleSimStateChange: intentValue = " + simArgs + " "
+                    + "state resolved to " + state.toString());
+        }
+
+        if (state != IccCardConstants.State.UNKNOWN && state != mSimState) {
+            mSimState = state;
+            for (int i = 0; i < mCallbacks.size(); i++) {
+                KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+                if (cb != null) {
+                    cb.onSimStateChanged(state);
+                }
+            }
+        }
+    }
+
+    /**
+     * Handle {@link #MSG_CLOCK_VISIBILITY_CHANGED}
+     */
+    private void handleClockVisibilityChanged() {
+        if (DEBUG) Log.d(TAG, "handleClockVisibilityChanged()");
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+            if (cb != null) {
+                cb.onClockVisibilityChanged();
+            }
+        }
+    }
+
+    /**
+     * Handle {@link #MSG_KEYGUARD_VISIBILITY_CHANGED}
+     */
+    private void handleKeyguardVisibilityChanged(int showing) {
+        if (DEBUG) Log.d(TAG, "handleKeyguardVisibilityChanged(" + showing + ")");
+        boolean isShowing = (showing == 1);
+        mKeyguardIsVisible = isShowing;
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+            if (cb != null) {
+                cb.onKeyguardVisibilityChanged(isShowing);
+            }
+        }
+    }
+
+    public boolean isKeyguardVisible() {
+        return mKeyguardIsVisible;
+    }
+
+    public boolean isSwitchingUser() {
+        return mSwitchingUser;
+    }
+
+    private static boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) {
+        final boolean nowPluggedIn = current.isPluggedIn();
+        final boolean wasPluggedIn = old.isPluggedIn();
+        final boolean stateChangedWhilePluggedIn =
+            wasPluggedIn == true && nowPluggedIn == true
+            && (old.status != current.status);
+
+        // change in plug state is always interesting
+        if (wasPluggedIn != nowPluggedIn || stateChangedWhilePluggedIn) {
+            return true;
+        }
+
+        // change in battery level while plugged in
+        if (nowPluggedIn && old.level != current.level) {
+            return true;
+        }
+
+        // change where battery needs charging
+        if (!nowPluggedIn && current.isBatteryLow() && current.level != old.level) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * @param intent The intent with action {@link TelephonyIntents#SPN_STRINGS_UPDATED_ACTION}
+     * @return The string to use for the plmn, or null if it should not be shown.
+     */
+    private CharSequence getTelephonyPlmnFrom(Intent intent) {
+        if (intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_PLMN, false)) {
+            final String plmn = intent.getStringExtra(TelephonyIntents.EXTRA_PLMN);
+            return (plmn != null) ? plmn : getDefaultPlmn();
+        }
+        return null;
+    }
+
+    /**
+     * @return The default plmn (no service)
+     */
+    private CharSequence getDefaultPlmn() {
+        return mContext.getResources().getText(R.string.keyguard_carrier_default);
+    }
+
+    /**
+     * @param intent The intent with action {@link Telephony.Intents#SPN_STRINGS_UPDATED_ACTION}
+     * @return The string to use for the plmn, or null if it should not be shown.
+     */
+    private CharSequence getTelephonySpnFrom(Intent intent) {
+        if (intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_SPN, false)) {
+            final String spn = intent.getStringExtra(TelephonyIntents.EXTRA_SPN);
+            if (spn != null) {
+                return spn;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Remove the given observer's callback.
+     *
+     * @param callback The callback to remove
+     */
+    public void removeCallback(KeyguardUpdateMonitorCallback callback) {
+        if (DEBUG) Log.v(TAG, "*** unregister callback for " + callback);
+        for (int i = mCallbacks.size() - 1; i >= 0; i--) {
+            if (mCallbacks.get(i).get() == callback) {
+                mCallbacks.remove(i);
+            }
+        }
+    }
+
+    /**
+     * Register to receive notifications about general keyguard information
+     * (see {@link InfoCallback}.
+     * @param callback The callback to register
+     */
+    public void registerCallback(KeyguardUpdateMonitorCallback callback) {
+        if (DEBUG) Log.v(TAG, "*** register callback for " + callback);
+        // Prevent adding duplicate callbacks
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            if (mCallbacks.get(i).get() == callback) {
+                if (DEBUG) Log.e(TAG, "Object tried to add another callback",
+                        new Exception("Called by"));
+                return;
+            }
+        }
+        mCallbacks.add(new WeakReference<KeyguardUpdateMonitorCallback>(callback));
+        removeCallback(null); // remove unused references
+        sendUpdates(callback);
+    }
+
+    private void sendUpdates(KeyguardUpdateMonitorCallback callback) {
+        // Notify listener of the current state
+        callback.onRefreshBatteryInfo(mBatteryStatus);
+        callback.onTimeChanged();
+        callback.onRingerModeChanged(mRingMode);
+        callback.onPhoneStateChanged(mPhoneState);
+        callback.onRefreshCarrierInfo(mTelephonyPlmn, mTelephonySpn);
+        callback.onClockVisibilityChanged();
+        callback.onSimStateChanged(mSimState);
+        callback.onMusicClientIdChanged(
+                mDisplayClientState.clientGeneration,
+                mDisplayClientState.clearing,
+                mDisplayClientState.intent);
+        callback.onMusicPlaybackStateChanged(mDisplayClientState.playbackState,
+                mDisplayClientState.playbackEventTime);
+    }
+
+    public void sendKeyguardVisibilityChanged(boolean showing) {
+        if (DEBUG) Log.d(TAG, "sendKeyguardVisibilityChanged(" + showing + ")");
+        Message message = mHandler.obtainMessage(MSG_KEYGUARD_VISIBILITY_CHANGED);
+        message.arg1 = showing ? 1 : 0;
+        message.sendToTarget();
+    }
+
+    public void reportClockVisible(boolean visible) {
+        mClockVisible = visible;
+        mHandler.obtainMessage(MSG_CLOCK_VISIBILITY_CHANGED).sendToTarget();
+    }
+
+    public IccCardConstants.State getSimState() {
+        return mSimState;
+    }
+
+    /**
+     * Report that the user successfully entered the SIM PIN or PUK/SIM PIN so we
+     * have the information earlier than waiting for the intent
+     * broadcast from the telephony code.
+     *
+     * NOTE: Because handleSimStateChange() invokes callbacks immediately without going
+     * through mHandler, this *must* be called from the UI thread.
+     */
+    public void reportSimUnlocked() {
+        handleSimStateChange(new SimArgs(IccCardConstants.State.READY));
+    }
+
+    public CharSequence getTelephonyPlmn() {
+        return mTelephonyPlmn;
+    }
+
+    public CharSequence getTelephonySpn() {
+        return mTelephonySpn;
+    }
+
+    /**
+     * @return Whether the device is provisioned (whether they have gone through
+     *   the setup wizard)
+     */
+    public boolean isDeviceProvisioned() {
+        return mDeviceProvisioned;
+    }
+
+    public int getFailedUnlockAttempts() {
+        return mFailedAttempts;
+    }
+
+    public void clearFailedUnlockAttempts() {
+        mFailedAttempts = 0;
+        mFailedBiometricUnlockAttempts = 0;
+    }
+
+    public void reportFailedUnlockAttempt() {
+        mFailedAttempts++;
+    }
+
+    public boolean isClockVisible() {
+        return mClockVisible;
+    }
+
+    public int getPhoneState() {
+        return mPhoneState;
+    }
+
+    public void reportFailedBiometricUnlockAttempt() {
+        mFailedBiometricUnlockAttempts++;
+    }
+
+    public boolean getMaxBiometricUnlockAttemptsReached() {
+        return mFailedBiometricUnlockAttempts >= FAILED_BIOMETRIC_UNLOCK_ATTEMPTS_BEFORE_BACKUP;
+    }
+
+    public boolean isAlternateUnlockEnabled() {
+        return mAlternateUnlockEnabled;
+    }
+
+    public void setAlternateUnlockEnabled(boolean enabled) {
+        mAlternateUnlockEnabled = enabled;
+    }
+
+    public boolean isSimLocked() {
+        return isSimLocked(mSimState);
+    }
+
+    public static boolean isSimLocked(IccCardConstants.State state) {
+        return state == IccCardConstants.State.PIN_REQUIRED
+        || state == IccCardConstants.State.PUK_REQUIRED
+        || state == IccCardConstants.State.PERM_DISABLED;
+    }
+
+    public boolean isSimPinSecure() {
+        return isSimPinSecure(mSimState);
+    }
+
+    public static boolean isSimPinSecure(IccCardConstants.State state) {
+        final IccCardConstants.State simState = state;
+        return (simState == IccCardConstants.State.PIN_REQUIRED
+                || simState == IccCardConstants.State.PUK_REQUIRED
+                || simState == IccCardConstants.State.PERM_DISABLED);
+    }
+
+    public DisplayClientState getCachedDisplayClientState() {
+        return mDisplayClientState;
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
new file mode 100644
index 0000000..30b43f5
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -0,0 +1,134 @@
+/*
+ * 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.keyguard;
+
+import android.app.PendingIntent;
+import android.app.admin.DevicePolicyManager;
+import android.media.AudioManager;
+
+import com.android.internal.telephony.IccCardConstants;
+
+/**
+ * Callback for general information relevant to lock screen.
+ */
+class KeyguardUpdateMonitorCallback {
+    /**
+     * Called when the battery status changes, e.g. when plugged in or unplugged, charge
+     * level, etc. changes.
+     *
+     * @param status current battery status
+     */
+    void onRefreshBatteryInfo(KeyguardUpdateMonitor.BatteryStatus status) { }
+
+    /**
+     * Called once per minute or when the time changes.
+     */
+    void onTimeChanged() { }
+
+    /**
+     * Called when the carrier PLMN or SPN changes.
+     *
+     * @param plmn The operator name of the registered network.  May be null if it shouldn't
+     *   be displayed.
+     * @param spn The service provider name.  May be null if it shouldn't be displayed.
+     */
+    void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) { }
+
+    /**
+     * Called when the ringer mode changes.
+     * @param state the current ringer state, as defined in
+     * {@link AudioManager#RINGER_MODE_CHANGED_ACTION}
+     */
+    void onRingerModeChanged(int state) { }
+
+    /**
+     * Called when the phone state changes. String will be one of:
+     * {@link TelephonyManager#EXTRA_STATE_IDLE}
+     * {@link TelephonyManager@EXTRA_STATE_RINGING}
+     * {@link TelephonyManager#EXTRA_STATE_OFFHOOK
+     */
+    void onPhoneStateChanged(int phoneState) { }
+
+    /**
+     * Called when the visibility of the keyguard changes.
+     * @param showing Indicates if the keyguard is now visible.
+     */
+    void onKeyguardVisibilityChanged(boolean showing) { }
+
+    /**
+     * Called when visibility of lockscreen clock changes, such as when
+     * obscured by a widget.
+     */
+    void onClockVisibilityChanged() { }
+
+    /**
+     * Called when the device becomes provisioned
+     */
+    void onDeviceProvisioned() { }
+
+    /**
+     * Called when the device policy changes.
+     * See {@link DevicePolicyManager#ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED}
+     */
+    void onDevicePolicyManagerStateChanged() { }
+
+    /**
+     * Called when the user change begins.
+     */
+    void onUserSwitching(int userId) { }
+
+    /**
+     * Called when the user change is complete.
+     */
+    void onUserSwitchComplete(int userId) { }
+
+    /**
+     * Called when the SIM state changes.
+     * @param simState
+     */
+    void onSimStateChanged(IccCardConstants.State simState) { }
+
+    /**
+     * Called when a user is removed.
+     */
+    void onUserRemoved(int userId) { }
+
+    /**
+     * Called when the user's info changed.
+     */
+    void onUserInfoChanged(int userId) { }
+
+    /**
+     * Called when boot completed.
+     *
+     * Note, this callback will only be received if boot complete occurs after registering with
+     * KeyguardUpdateMonitor.
+     */
+    void onBootCompleted() { }
+
+    /**
+     * Called when audio client attaches or detaches from AudioManager.
+     */
+    void onMusicClientIdChanged(int clientGeneration, boolean clearing, PendingIntent intent) { }
+
+    /**
+     * Called when the audio playback state changes.
+     * @param playbackState
+     * @param eventTime
+     */
+    public void onMusicPlaybackStateChanged(int playbackState, long eventTime) { }
+
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java
new file mode 100644
index 0000000..893562e
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.keyguard;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.PixelFormat;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
+import android.media.AudioManager;
+import android.media.IAudioService;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.telephony.TelephonyManager;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Slog;
+import android.view.KeyEvent;
+import android.widget.FrameLayout;
+
+/**
+ * Base class for keyguard view.  {@link #reset} is where you should
+ * reset the state of your view.  Use the {@link KeyguardViewCallback} via
+ * {@link #getCallback()} to send information back (such as poking the wake lock,
+ * or finishing the keyguard).
+ *
+ * Handles intercepting of media keys that still work when the keyguard is
+ * showing.
+ */
+public abstract class KeyguardViewBase extends FrameLayout {
+
+    private static final int BACKGROUND_COLOR = 0x70000000;
+    private AudioManager mAudioManager;
+    private TelephonyManager mTelephonyManager = null;
+    protected KeyguardViewMediator.ViewMediatorCallback mViewMediatorCallback;
+
+    // Whether the volume keys should be handled by keyguard. If true, then
+    // they will be handled here for specific media types such as music, otherwise
+    // the audio service will bring up the volume dialog.
+    private static final boolean KEYGUARD_MANAGES_VOLUME = true;
+
+    // This is a faster way to draw the background on devices without hardware acceleration
+    private static final Drawable mBackgroundDrawable = new Drawable() {
+        @Override
+        public void draw(Canvas canvas) {
+            canvas.drawColor(BACKGROUND_COLOR, PorterDuff.Mode.SRC);
+        }
+
+        @Override
+        public void setAlpha(int alpha) {
+        }
+
+        @Override
+        public void setColorFilter(ColorFilter cf) {
+        }
+
+        @Override
+        public int getOpacity() {
+            return PixelFormat.TRANSLUCENT;
+        }
+    };
+
+    public KeyguardViewBase(Context context) {
+        this(context, null);
+    }
+
+    public KeyguardViewBase(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        resetBackground();
+    }
+
+    public void resetBackground() {
+        setBackground(mBackgroundDrawable);
+    }
+
+    /**
+     * Called when the screen turned off.
+     */
+    abstract public void onScreenTurnedOff();
+
+    /**
+     * Called when the screen turned on.
+     */
+    abstract public void onScreenTurnedOn();
+
+    /**
+     * Called when the view needs to be shown.
+     */
+    abstract public void show();
+
+    /**
+     * Verify that the user can get past the keyguard securely.  This is called,
+     * for example, when the phone disables the keyguard but then wants to launch
+     * something else that requires secure access.
+     *
+     * The result will be propogated back via {@link KeyguardViewCallback#keyguardDone(boolean)}
+     */
+    abstract public void verifyUnlock();
+
+    /**
+     * Called before this view is being removed.
+     */
+    abstract public void cleanUp();
+
+    /**
+     * Gets the desired user activity timeout in milliseconds, or -1 if the
+     * default should be used.
+     */
+    abstract public long getUserActivityTimeout();
+
+    @Override
+    public boolean dispatchKeyEvent(KeyEvent event) {
+        if (interceptMediaKey(event)) {
+            return true;
+        }
+        return super.dispatchKeyEvent(event);
+    }
+
+    /**
+     * Allows the media keys to work when the keyguard is showing.
+     * The media keys should be of no interest to the actual keyguard view(s),
+     * so intercepting them here should not be of any harm.
+     * @param event The key event
+     * @return whether the event was consumed as a media key.
+     */
+    private boolean interceptMediaKey(KeyEvent event) {
+        final int keyCode = event.getKeyCode();
+        if (event.getAction() == KeyEvent.ACTION_DOWN) {
+            switch (keyCode) {
+                case KeyEvent.KEYCODE_MEDIA_PLAY:
+                case KeyEvent.KEYCODE_MEDIA_PAUSE:
+                case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
+                    /* Suppress PLAY/PAUSE toggle when phone is ringing or
+                     * in-call to avoid music playback */
+                    if (mTelephonyManager == null) {
+                        mTelephonyManager = (TelephonyManager) getContext().getSystemService(
+                                Context.TELEPHONY_SERVICE);
+                    }
+                    if (mTelephonyManager != null &&
+                            mTelephonyManager.getCallState() != TelephonyManager.CALL_STATE_IDLE) {
+                        return true;  // suppress key event
+                    }
+                case KeyEvent.KEYCODE_MUTE:
+                case KeyEvent.KEYCODE_HEADSETHOOK:
+                case KeyEvent.KEYCODE_MEDIA_STOP:
+                case KeyEvent.KEYCODE_MEDIA_NEXT:
+                case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
+                case KeyEvent.KEYCODE_MEDIA_REWIND:
+                case KeyEvent.KEYCODE_MEDIA_RECORD:
+                case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
+                case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: {
+                    handleMediaKeyEvent(event);
+                    return true;
+                }
+
+                case KeyEvent.KEYCODE_VOLUME_UP:
+                case KeyEvent.KEYCODE_VOLUME_DOWN:
+                case KeyEvent.KEYCODE_VOLUME_MUTE: {
+                    if (KEYGUARD_MANAGES_VOLUME) {
+                        synchronized (this) {
+                            if (mAudioManager == null) {
+                                mAudioManager = (AudioManager) getContext().getSystemService(
+                                        Context.AUDIO_SERVICE);
+                            }
+                        }
+                        // Volume buttons should only function for music (local or remote).
+                        // TODO: Actually handle MUTE.
+                        mAudioManager.adjustLocalOrRemoteStreamVolume(
+                                AudioManager.STREAM_MUSIC,
+                                keyCode == KeyEvent.KEYCODE_VOLUME_UP
+                                        ? AudioManager.ADJUST_RAISE
+                                        : AudioManager.ADJUST_LOWER);
+                        // Don't execute default volume behavior
+                        return true;
+                    } else {
+                        return false;
+                    }
+                }
+            }
+        } else if (event.getAction() == KeyEvent.ACTION_UP) {
+            switch (keyCode) {
+                case KeyEvent.KEYCODE_MUTE:
+                case KeyEvent.KEYCODE_HEADSETHOOK:
+                case KeyEvent.KEYCODE_MEDIA_PLAY:
+                case KeyEvent.KEYCODE_MEDIA_PAUSE:
+                case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
+                case KeyEvent.KEYCODE_MEDIA_STOP:
+                case KeyEvent.KEYCODE_MEDIA_NEXT:
+                case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
+                case KeyEvent.KEYCODE_MEDIA_REWIND:
+                case KeyEvent.KEYCODE_MEDIA_RECORD:
+                case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
+                case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: {
+                    handleMediaKeyEvent(event);
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    void handleMediaKeyEvent(KeyEvent keyEvent) {
+        IAudioService audioService = IAudioService.Stub.asInterface(
+                ServiceManager.checkService(Context.AUDIO_SERVICE));
+        if (audioService != null) {
+            try {
+                audioService.dispatchMediaKeyEvent(keyEvent);
+            } catch (RemoteException e) {
+                Log.e("KeyguardViewBase", "dispatchMediaKeyEvent threw exception " + e);
+            }
+        } else {
+            Slog.w("KeyguardViewBase", "Unable to find IAudioService for media key event");
+        }
+    }
+
+    @Override
+    public void dispatchSystemUiVisibilityChanged(int visibility) {
+        super.dispatchSystemUiVisibilityChanged(visibility);
+
+        if (!(mContext instanceof Activity)) {
+            setSystemUiVisibility(STATUS_BAR_DISABLE_BACK);
+        }
+    }
+
+    public void setViewMediatorCallback(
+            KeyguardViewMediator.ViewMediatorCallback viewMediatorCallback) {
+        mViewMediatorCallback = viewMediatorCallback;
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
new file mode 100644
index 0000000..35bea26
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
@@ -0,0 +1,428 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.keyguard;
+
+import com.android.internal.policy.IKeyguardShowCallback;
+import com.android.internal.widget.LockPatternUtils;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.appwidget.AppWidgetManager;
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.os.SystemProperties;
+import android.util.Log;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewManager;
+import android.view.WindowManager;
+import android.widget.FrameLayout;
+
+/**
+ * Manages creating, showing, hiding and resetting the keyguard.  Calls back
+ * via {@link KeyguardViewMediator.ViewMediatorCallback} to poke
+ * the wake lock and report that the keyguard is done, which is in turn,
+ * reported to this class by the current {@link KeyguardViewBase}.
+ */
+public class KeyguardViewManager {
+    private final static boolean DEBUG = KeyguardViewMediator.DEBUG;
+    private static String TAG = "KeyguardViewManager";
+    public static boolean USE_UPPER_CASE = true;
+    public final static String IS_SWITCHING_USER = "is_switching_user";
+
+    // Timeout used for keypresses
+    static final int DIGIT_PRESS_WAKE_MILLIS = 5000;
+
+    private final Context mContext;
+    private final ViewManager mViewManager;
+    private final KeyguardViewMediator.ViewMediatorCallback mViewMediatorCallback;
+
+    private WindowManager.LayoutParams mWindowLayoutParams;
+    private boolean mNeedsInput = false;
+
+    private FrameLayout mKeyguardHost;
+    private KeyguardHostView mKeyguardView;
+
+    private boolean mScreenOn = false;
+    private LockPatternUtils mLockPatternUtils;
+
+    public interface ShowListener {
+        void onShown(IBinder windowToken);
+    };
+
+    /**
+     * @param context Used to create views.
+     * @param viewManager Keyguard will be attached to this.
+     * @param callback Used to notify of changes.
+     * @param lockPatternUtils
+     */
+    public KeyguardViewManager(Context context, ViewManager viewManager,
+            KeyguardViewMediator.ViewMediatorCallback callback,
+            LockPatternUtils lockPatternUtils) {
+        mContext = context;
+        mViewManager = viewManager;
+        mViewMediatorCallback = callback;
+        mLockPatternUtils = lockPatternUtils;
+    }
+
+    /**
+     * Show the keyguard.  Will handle creating and attaching to the view manager
+     * lazily.
+     */
+    public synchronized void show(Bundle options) {
+        if (DEBUG) Log.d(TAG, "show(); mKeyguardView==" + mKeyguardView);
+
+        boolean enableScreenRotation = shouldEnableScreenRotation();
+
+        maybeCreateKeyguardLocked(enableScreenRotation, false, options);
+        maybeEnableScreenRotation(enableScreenRotation);
+
+        // Disable common aspects of the system/status/navigation bars that are not appropriate or
+        // useful on any keyguard screen but can be re-shown by dialogs or SHOW_WHEN_LOCKED
+        // activities. Other disabled bits are handled by the KeyguardViewMediator talking
+        // directly to the status bar service.
+        final int visFlags = View.STATUS_BAR_DISABLE_HOME;
+        if (DEBUG) Log.v(TAG, "show:setSystemUiVisibility(" + Integer.toHexString(visFlags)+")");
+        mKeyguardHost.setSystemUiVisibility(visFlags);
+
+        mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
+        mKeyguardHost.setVisibility(View.VISIBLE);
+        mKeyguardView.show();
+        mKeyguardView.requestFocus();
+    }
+
+    private boolean shouldEnableScreenRotation() {
+        Resources res = mContext.getResources();
+        return SystemProperties.getBoolean("lockscreen.rot_override",false)
+                || res.getBoolean(R.bool.config_enableLockScreenRotation);
+    }
+
+    class ViewManagerHost extends FrameLayout {
+        public ViewManagerHost(Context context) {
+            super(context);
+            setFitsSystemWindows(true);
+        }
+
+        @Override
+        protected boolean fitSystemWindows(Rect insets) {
+            Log.v("TAG", "bug 7643792: fitSystemWindows(" + insets.toShortString() + ")");
+            return super.fitSystemWindows(insets);
+        }
+
+        @Override
+        protected void onConfigurationChanged(Configuration newConfig) {
+            super.onConfigurationChanged(newConfig);
+            if (mKeyguardHost.getVisibility() == View.VISIBLE) {
+                // only propagate configuration messages if we're currently showing
+                maybeCreateKeyguardLocked(shouldEnableScreenRotation(), true, null);
+            } else {
+                if (DEBUG) Log.v(TAG, "onConfigurationChanged: view not visible");
+            }
+        }
+
+        @Override
+        public boolean dispatchKeyEvent(KeyEvent event) {
+            if (mKeyguardView != null) {
+                // Always process back and menu keys, regardless of focus
+                if (event.getAction() == KeyEvent.ACTION_DOWN) {
+                    int keyCode = event.getKeyCode();
+                    if (keyCode == KeyEvent.KEYCODE_BACK && mKeyguardView.handleBackKey()) {
+                        return true;
+                    } else if (keyCode == KeyEvent.KEYCODE_MENU && mKeyguardView.handleMenuKey()) {
+                        return true;
+                    }
+                }
+                // Always process media keys, regardless of focus
+                if (mKeyguardView.dispatchKeyEvent(event)) {
+                    return true;
+                }
+            }
+            return super.dispatchKeyEvent(event);
+        }
+    }
+
+    SparseArray<Parcelable> mStateContainer = new SparseArray<Parcelable>();
+
+    private void maybeCreateKeyguardLocked(boolean enableScreenRotation, boolean force,
+            Bundle options) {
+        if (mKeyguardHost != null) {
+            mKeyguardHost.saveHierarchyState(mStateContainer);
+        }
+
+        if (mKeyguardHost == null) {
+            if (DEBUG) Log.d(TAG, "keyguard host is null, creating it...");
+
+            mKeyguardHost = new ViewManagerHost(mContext);
+
+            int flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                    | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
+                    | WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN
+                    | WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+
+            if (!mNeedsInput) {
+                flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+            }
+
+            final int stretch = ViewGroup.LayoutParams.MATCH_PARENT;
+            final int type = WindowManager.LayoutParams.TYPE_KEYGUARD;
+            WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+                    stretch, stretch, type, flags, PixelFormat.TRANSLUCENT);
+            lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
+            lp.windowAnimations = R.style.Animation_LockScreen;
+            lp.screenOrientation = enableScreenRotation ?
+                    ActivityInfo.SCREEN_ORIENTATION_USER : ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
+
+            if (ActivityManager.isHighEndGfx()) {
+                lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+                lp.privateFlags |=
+                        WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED;
+            }
+            lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SET_NEEDS_MENU_KEY;
+            lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY;
+            lp.setTitle("Keyguard");
+            mWindowLayoutParams = lp;
+            mViewManager.addView(mKeyguardHost, lp);
+        }
+
+        if (force || mKeyguardView == null) {
+            inflateKeyguardView(options);
+            mKeyguardView.requestFocus();
+        }
+        updateUserActivityTimeoutInWindowLayoutParams();
+        mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
+
+        mKeyguardHost.restoreHierarchyState(mStateContainer);
+    }
+
+    private void inflateKeyguardView(Bundle options) {
+        View v = mKeyguardHost.findViewById(R.id.keyguard_host_view);
+        if (v != null) {
+            mKeyguardHost.removeView(v);
+        }
+        final LayoutInflater inflater = LayoutInflater.from(mContext);
+        View view = inflater.inflate(R.layout.keyguard_host_view, mKeyguardHost, true);
+        mKeyguardView = (KeyguardHostView) view.findViewById(R.id.keyguard_host_view);
+        mKeyguardView.setLockPatternUtils(mLockPatternUtils);
+        mKeyguardView.setViewMediatorCallback(mViewMediatorCallback);
+        mKeyguardView.initializeSwitchingUserState(options != null &&
+                options.getBoolean(IS_SWITCHING_USER));
+
+        // HACK
+        // The keyguard view will have set up window flags in onFinishInflate before we set
+        // the view mediator callback. Make sure it knows the correct IME state.
+        if (mViewMediatorCallback != null) {
+            KeyguardPasswordView kpv = (KeyguardPasswordView) mKeyguardView.findViewById(
+                    R.id.keyguard_password_view);
+
+            if (kpv != null) {
+                mViewMediatorCallback.setNeedsInput(kpv.needsInput());
+            }
+        }
+
+        if (options != null) {
+            int widgetToShow = options.getInt(LockPatternUtils.KEYGUARD_SHOW_APPWIDGET,
+                    AppWidgetManager.INVALID_APPWIDGET_ID);
+            if (widgetToShow != AppWidgetManager.INVALID_APPWIDGET_ID) {
+                mKeyguardView.goToWidget(widgetToShow);
+            }
+        }
+    }
+
+    public void updateUserActivityTimeout() {
+        updateUserActivityTimeoutInWindowLayoutParams();
+        mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
+    }
+
+    private void updateUserActivityTimeoutInWindowLayoutParams() {
+        // Use the user activity timeout requested by the keyguard view, if any.
+        if (mKeyguardView != null) {
+            long timeout = mKeyguardView.getUserActivityTimeout();
+            if (timeout >= 0) {
+                mWindowLayoutParams.userActivityTimeout = timeout;
+                return;
+            }
+        }
+
+        // Otherwise, use the default timeout.
+        mWindowLayoutParams.userActivityTimeout = KeyguardViewMediator.AWAKE_INTERVAL_DEFAULT_MS;
+    }
+
+    private void maybeEnableScreenRotation(boolean enableScreenRotation) {
+        // TODO: move this outside
+        if (enableScreenRotation) {
+            if (DEBUG) Log.d(TAG, "Rotation sensor for lock screen On!");
+            mWindowLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_USER;
+        } else {
+            if (DEBUG) Log.d(TAG, "Rotation sensor for lock screen Off!");
+            mWindowLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
+        }
+        mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
+    }
+
+    public void setNeedsInput(boolean needsInput) {
+        mNeedsInput = needsInput;
+        if (mWindowLayoutParams != null) {
+            if (needsInput) {
+                mWindowLayoutParams.flags &=
+                    ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+            } else {
+                mWindowLayoutParams.flags |=
+                    WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+            }
+
+            try {
+                mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
+            } catch (java.lang.IllegalArgumentException e) {
+                // TODO: Ensure this method isn't called on views that are changing...
+                Log.w(TAG,"Can't update input method on " + mKeyguardHost + " window not attached");
+            }
+        }
+    }
+
+    /**
+     * Reset the state of the view.
+     */
+    public synchronized void reset(Bundle options) {
+        if (DEBUG) Log.d(TAG, "reset()");
+        // User might have switched, check if we need to go back to keyguard
+        // TODO: It's preferable to stay and show the correct lockscreen or unlock if none
+        maybeCreateKeyguardLocked(shouldEnableScreenRotation(), true, options);
+    }
+
+    public synchronized void onScreenTurnedOff() {
+        if (DEBUG) Log.d(TAG, "onScreenTurnedOff()");
+        mScreenOn = false;
+        if (mKeyguardView != null) {
+            mKeyguardView.onScreenTurnedOff();
+        }
+    }
+
+    public synchronized void onScreenTurnedOn(final IKeyguardShowCallback callback) {
+        if (DEBUG) Log.d(TAG, "onScreenTurnedOn()");
+        mScreenOn = true;
+        if (mKeyguardView != null) {
+            mKeyguardView.onScreenTurnedOn();
+
+            // Caller should wait for this window to be shown before turning
+            // on the screen.
+            if (callback != null) {
+                if (mKeyguardHost.getVisibility() == View.VISIBLE) {
+                    // Keyguard may be in the process of being shown, but not yet
+                    // updated with the window manager...  give it a chance to do so.
+                    mKeyguardHost.post(new Runnable() {
+                        @Override
+                        public void run() {
+                            IBinder token = null;
+                            if (mKeyguardHost.getVisibility() == View.VISIBLE) {
+                                token = mKeyguardHost.getWindowToken();
+                            }
+                            try {
+                                callback.onShown(token);
+                            } catch (RemoteException e) {
+                                Slog.w(TAG, "Exception calling onShown():", e);
+                            }
+                        }
+                    });
+                } else {
+                    try {
+                        callback.onShown(null);
+                    } catch (RemoteException e) {
+                        Slog.w(TAG, "Exception calling onShown():", e);
+                    }
+                }
+            }
+        } else if (callback != null) {
+            try {
+                callback.onShown(null);
+            } catch (RemoteException e) {
+                Slog.w(TAG, "Exception calling onShown():", e);
+            }
+        }
+    }
+
+    public synchronized void verifyUnlock() {
+        if (DEBUG) Log.d(TAG, "verifyUnlock()");
+        show(null);
+        mKeyguardView.verifyUnlock();
+    }
+
+    /**
+     * Hides the keyguard view
+     */
+    public synchronized void hide() {
+        if (DEBUG) Log.d(TAG, "hide()");
+
+        if (mKeyguardHost != null) {
+            mKeyguardHost.setVisibility(View.GONE);
+
+            // We really only want to preserve keyguard state for configuration changes. Hence
+            // we should clear state of widgets (e.g. Music) when we hide keyguard so it can
+            // start with a fresh state when we return.
+            mStateContainer.clear();
+
+            // Don't do this right away, so we can let the view continue to animate
+            // as it goes away.
+            if (mKeyguardView != null) {
+                final KeyguardViewBase lastView = mKeyguardView;
+                mKeyguardView = null;
+                mKeyguardHost.postDelayed(new Runnable() {
+                    @Override
+                    public void run() {
+                        synchronized (KeyguardViewManager.this) {
+                            lastView.cleanUp();
+                            mKeyguardHost.removeView(lastView);
+                        }
+                    }
+                }, 500);
+            }
+        }
+    }
+
+    /**
+     * Dismisses the keyguard by going to the next screen or making it gone.
+     */
+    public synchronized void dismiss() {
+        if (mScreenOn) {
+            mKeyguardView.dismiss();
+        }
+    }
+
+    /**
+     * @return Whether the keyguard is showing
+     */
+    public synchronized boolean isShowing() {
+        return (mKeyguardHost != null && mKeyguardHost.getVisibility() == View.VISIBLE);
+    }
+
+    public void showAssistant() {
+        if (mKeyguardView != null) {
+            mKeyguardView.showAssistant();
+        }
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
new file mode 100644
index 0000000..e746f72
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
@@ -0,0 +1,1330 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.keyguard;
+
+import com.android.internal.policy.IKeyguardExitCallback;
+import com.android.internal.policy.IKeyguardShowCallback;
+import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
+
+import android.app.Activity;
+import android.app.ActivityManagerNative;
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.app.SearchManager;
+import android.app.StatusBarManager;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.media.AudioManager;
+import android.media.SoundPool;
+import android.os.Bundle;
+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.Settings;
+import android.telephony.TelephonyManager;
+import android.util.EventLog;
+import android.util.Log;
+import android.util.Slog;
+import android.view.KeyEvent;
+import android.view.WindowManager;
+import android.view.WindowManagerPolicy;
+
+import com.android.internal.telephony.IccCardConstants;
+import com.android.internal.widget.LockPatternUtils;
+
+
+/**
+ * Mediates requests related to the keyguard.  This includes queries about the
+ * state of the keyguard, power management events that effect whether the keyguard
+ * should be shown or reset, callbacks to the phone window manager to notify
+ * it of when the keyguard is showing, and events from the keyguard view itself
+ * stating that the keyguard was succesfully unlocked.
+ *
+ * Note that the keyguard view is shown when the screen is off (as appropriate)
+ * so that once the screen comes on, it will be ready immediately.
+ *
+ * Example queries about the keyguard:
+ * - is {movement, key} one that should wake the keygaurd?
+ * - is the keyguard showing?
+ * - are input events restricted due to the state of the keyguard?
+ *
+ * Callbacks to the phone window manager:
+ * - the keyguard is showing
+ *
+ * Example external events that translate to keyguard view changes:
+ * - screen turned off -> reset the keyguard, and show it so it will be ready
+ *   next time the screen turns on
+ * - keyboard is slid open -> if the keyguard is not secure, hide it
+ *
+ * Events from the keyguard view:
+ * - user succesfully unlocked keyguard -> hide keyguard view, and no longer
+ *   restrict input events.
+ *
+ * Note: in addition to normal power managment events that effect the state of
+ * whether the keyguard should be showing, external apps and services may request
+ * that the keyguard be disabled via {@link #setKeyguardEnabled(boolean)}.  When
+ * false, this will override all other conditions for turning on the keyguard.
+ *
+ * Threading and synchronization:
+ * This class is created by the initialization routine of the {@link WindowManagerPolicy},
+ * and runs on its thread.  The keyguard UI is created from that thread in the
+ * constructor of this class.  The apis may be called from other threads, including the
+ * {@link com.android.server.input.InputManagerService}'s and {@link android.view.WindowManager}'s.
+ * Therefore, methods on this class are synchronized, and any action that is pointed
+ * directly to the keyguard UI is posted to a {@link Handler} to ensure it is taken on the UI
+ * thread of the keyguard.
+ */
+public class KeyguardViewMediator {
+    private static final int KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT = 30000;
+    final static boolean DEBUG = false;
+    private final static boolean DBG_WAKE = false;
+
+    private final static String TAG = "KeyguardViewMediator";
+
+    private static final String DELAYED_KEYGUARD_ACTION =
+        "com.android.internal.policy.impl.PhoneWindowManager.DELAYED_KEYGUARD";
+
+    // used for handler messages
+    private static final int SHOW = 2;
+    private static final int HIDE = 3;
+    private static final int RESET = 4;
+    private static final int VERIFY_UNLOCK = 5;
+    private static final int NOTIFY_SCREEN_OFF = 6;
+    private static final int NOTIFY_SCREEN_ON = 7;
+    private static final int KEYGUARD_DONE = 9;
+    private static final int KEYGUARD_DONE_DRAWING = 10;
+    private static final int KEYGUARD_DONE_AUTHENTICATING = 11;
+    private static final int SET_HIDDEN = 12;
+    private static final int KEYGUARD_TIMEOUT = 13;
+    private static final int SHOW_ASSISTANT = 14;
+
+    /**
+     * The default amount of time we stay awake (used for all key input)
+     */
+    protected static final int AWAKE_INTERVAL_DEFAULT_MS = 10000;
+
+    /**
+     * How long to wait after the screen turns off due to timeout before
+     * turning on the keyguard (i.e, the user has this much time to turn
+     * the screen back on without having to face the keyguard).
+     */
+    private static final int KEYGUARD_LOCK_AFTER_DELAY_DEFAULT = 5000;
+
+    /**
+     * How long we'll wait for the {@link ViewMediatorCallback#keyguardDoneDrawing()}
+     * callback before unblocking a call to {@link #setKeyguardEnabled(boolean)}
+     * that is reenabling the keyguard.
+     */
+    private static final int KEYGUARD_DONE_DRAWING_TIMEOUT_MS = 2000;
+
+    /**
+     * Allow the user to expand the status bar when the keyguard is engaged
+     * (without a pattern or password).
+     */
+    private static final boolean ENABLE_INSECURE_STATUS_BAR_EXPAND = true;
+
+    /** The stream type that the lock sounds are tied to. */
+    private int mMasterStreamType;
+
+    private Context mContext;
+    private AlarmManager mAlarmManager;
+    private AudioManager mAudioManager;
+    private StatusBarManager mStatusBarManager;
+    private boolean mSwitchingUser;
+
+    private boolean mSystemReady;
+
+    // Whether the next call to playSounds() should be skipped.  Defaults to
+    // true because the first lock (on boot) should be silent.
+    private boolean mSuppressNextLockSound = true;
+
+
+    /** High level access to the power manager for WakeLocks */
+    private PowerManager mPM;
+
+    /** UserManager for querying number of users */
+    private UserManager mUserManager;
+
+    /** SearchManager for determining whether or not search assistant is available */
+    private SearchManager mSearchManager;
+
+    /**
+     * Used to keep the device awake while to ensure the keyguard finishes opening before
+     * we sleep.
+     */
+    private PowerManager.WakeLock mShowKeyguardWakeLock;
+
+    private KeyguardViewManager mKeyguardViewManager;
+
+    // these are protected by synchronized (this)
+
+    /**
+     * External apps (like the phone app) can tell us to disable the keygaurd.
+     */
+    private boolean mExternallyEnabled = true;
+
+    /**
+     * Remember if an external call to {@link #setKeyguardEnabled} with value
+     * false caused us to hide the keyguard, so that we need to reshow it once
+     * the keygaurd is reenabled with another call with value true.
+     */
+    private boolean mNeedToReshowWhenReenabled = false;
+
+    // cached value of whether we are showing (need to know this to quickly
+    // answer whether the input should be restricted)
+    private boolean mShowing = false;
+
+    // true if the keyguard is hidden by another window
+    private boolean mHidden = false;
+
+    /**
+     * Helps remember whether the screen has turned on since the last time
+     * it turned off due to timeout. see {@link #onScreenTurnedOff(int)}
+     */
+    private int mDelayedShowingSequence;
+
+    /**
+     * If the user has disabled the keyguard, then requests to exit, this is
+     * how we'll ultimately let them know whether it was successful.  We use this
+     * var being non-null as an indicator that there is an in progress request.
+     */
+    private IKeyguardExitCallback mExitSecureCallback;
+
+    // the properties of the keyguard
+
+    private KeyguardUpdateMonitor mUpdateMonitor;
+
+    private boolean mScreenOn;
+
+    // last known state of the cellular connection
+    private String mPhoneState = TelephonyManager.EXTRA_STATE_IDLE;
+
+    /**
+     * we send this intent when the keyguard is dismissed.
+     */
+    private static final Intent USER_PRESENT_INTENT = new Intent(Intent.ACTION_USER_PRESENT)
+            .addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
+                    | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+
+    /**
+     * {@link #setKeyguardEnabled} waits on this condition when it reenables
+     * the keyguard.
+     */
+    private boolean mWaitingUntilKeyguardVisible = false;
+    private LockPatternUtils mLockPatternUtils;
+    private boolean mKeyguardDonePending = false;
+
+    private SoundPool mLockSounds;
+    private int mLockSoundId;
+    private int mUnlockSoundId;
+    private int mLockSoundStreamId;
+
+    /**
+     * The volume applied to the lock/unlock sounds.
+     */
+    private final float mLockSoundVolume;
+
+    /**
+     * Cache of avatar drawables, for use by KeyguardMultiUserAvatar.
+     */
+    private static MultiUserAvatarCache sMultiUserAvatarCache = new MultiUserAvatarCache();
+
+    /**
+     * The callback used by the keyguard view to tell the {@link KeyguardViewMediator}
+     * various things.
+     */
+    public interface ViewMediatorCallback {
+        /**
+         * Reports user activity and requests that the screen stay on.
+         */
+        void userActivity();
+
+        /**
+         * Reports user activity and requests that the screen stay on for at least
+         * the specified amount of time.
+         * @param millis The amount of time in millis.  This value is currently ignored.
+         */
+        void userActivity(long millis);
+
+        /**
+         * Report that the keyguard is done.
+         * @param authenticated Whether the user securely got past the keyguard.
+         *   the only reason for this to be false is if the keyguard was instructed
+         *   to appear temporarily to verify the user is supposed to get past the
+         *   keyguard, and the user fails to do so.
+         */
+        void keyguardDone(boolean authenticated);
+
+        /**
+         * Report that the keyguard is done drawing.
+         */
+        void keyguardDoneDrawing();
+
+        /**
+         * Tell ViewMediator that the current view needs IME input
+         * @param needsInput
+         */
+        void setNeedsInput(boolean needsInput);
+
+        /**
+         * Tell view mediator that the keyguard view's desired user activity timeout
+         * has changed and needs to be reapplied to the window.
+         */
+        void onUserActivityTimeoutChanged();
+
+        /**
+         * Report that the keyguard is dismissable, pending the next keyguardDone call.
+         */
+        void keyguardDonePending();
+    }
+
+    KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() {
+
+        @Override
+        public void onUserSwitching(int userId) {
+            // Note that the mLockPatternUtils user has already been updated from setCurrentUser.
+            // We need to force a reset of the views, since lockNow (called by
+            // ActivityManagerService) will not reconstruct the keyguard if it is already showing.
+            synchronized (KeyguardViewMediator.this) {
+                mSwitchingUser = true;
+                resetStateLocked(null);
+                adjustStatusBarLocked();
+                // When we switch users we want to bring the new user to the biometric unlock even
+                // if the current user has gone to the backup.
+                KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true);
+            }
+        }
+
+        @Override
+        public void onUserSwitchComplete(int userId) {
+            mSwitchingUser = false;
+        }
+
+        @Override
+        public void onUserRemoved(int userId) {
+            mLockPatternUtils.removeUser(userId);
+            sMultiUserAvatarCache.clear(userId);
+        }
+
+        @Override
+        public void onUserInfoChanged(int userId) {
+            sMultiUserAvatarCache.clear(userId);
+        }
+
+        @Override
+        void onPhoneStateChanged(int phoneState) {
+            synchronized (KeyguardViewMediator.this) {
+                if (TelephonyManager.CALL_STATE_IDLE == phoneState  // call ending
+                        && !mScreenOn                           // screen off
+                        && mExternallyEnabled) {                // not disabled by any app
+
+                    // note: this is a way to gracefully reenable the keyguard when the call
+                    // ends and the screen is off without always reenabling the keyguard
+                    // each time the screen turns off while in call (and having an occasional ugly
+                    // flicker while turning back on the screen and disabling the keyguard again).
+                    if (DEBUG) Log.d(TAG, "screen is off and call ended, let's make sure the "
+                            + "keyguard is showing");
+                    doKeyguardLocked(null);
+                }
+            }
+        };
+
+        @Override
+        public void onClockVisibilityChanged() {
+            adjustStatusBarLocked();
+        }
+
+        @Override
+        public void onDeviceProvisioned() {
+            sendUserPresentBroadcast();
+        }
+
+        @Override
+        public void onSimStateChanged(IccCardConstants.State simState) {
+            if (DEBUG) Log.d(TAG, "onSimStateChanged: " + simState);
+
+            switch (simState) {
+                case NOT_READY:
+                case ABSENT:
+                    // only force lock screen in case of missing sim if user hasn't
+                    // gone through setup wizard
+                    synchronized (this) {
+                        if (!mUpdateMonitor.isDeviceProvisioned()) {
+                            if (!isShowing()) {
+                                if (DEBUG) Log.d(TAG, "ICC_ABSENT isn't showing,"
+                                        + " we need to show the keyguard since the "
+                                        + "device isn't provisioned yet.");
+                                doKeyguardLocked(null);
+                            } else {
+                                resetStateLocked(null);
+                            }
+                        }
+                    }
+                    break;
+                case PIN_REQUIRED:
+                case PUK_REQUIRED:
+                    synchronized (this) {
+                        if (!isShowing()) {
+                            if (DEBUG) Log.d(TAG, "INTENT_VALUE_ICC_LOCKED and keygaurd isn't "
+                                    + "showing; need to show keyguard so user can enter sim pin");
+                            doKeyguardLocked(null);
+                        } else {
+                            resetStateLocked(null);
+                        }
+                    }
+                    break;
+                case PERM_DISABLED:
+                    synchronized (this) {
+                        if (!isShowing()) {
+                            if (DEBUG) Log.d(TAG, "PERM_DISABLED and "
+                                  + "keygaurd isn't showing.");
+                            doKeyguardLocked(null);
+                        } else {
+                            if (DEBUG) Log.d(TAG, "PERM_DISABLED, resetStateLocked to"
+                                  + "show permanently disabled message in lockscreen.");
+                            resetStateLocked(null);
+                        }
+                    }
+                    break;
+                case READY:
+                    synchronized (this) {
+                        if (isShowing()) {
+                            resetStateLocked(null);
+                        }
+                    }
+                    break;
+            }
+        }
+
+    };
+
+    ViewMediatorCallback mViewMediatorCallback = new ViewMediatorCallback() {
+        public void userActivity() {
+            KeyguardViewMediator.this.userActivity();
+        }
+
+        public void userActivity(long holdMs) {
+            KeyguardViewMediator.this.userActivity(holdMs);
+        }
+
+        public void keyguardDone(boolean authenticated) {
+            KeyguardViewMediator.this.keyguardDone(authenticated, true);
+        }
+
+        public void keyguardDoneDrawing() {
+            mHandler.sendEmptyMessage(KEYGUARD_DONE_DRAWING);
+        }
+
+        @Override
+        public void setNeedsInput(boolean needsInput) {
+            mKeyguardViewManager.setNeedsInput(needsInput);
+        }
+
+        @Override
+        public void onUserActivityTimeoutChanged() {
+            mKeyguardViewManager.updateUserActivityTimeout();
+        }
+
+        @Override
+        public void keyguardDonePending() {
+            mKeyguardDonePending = true;
+        }
+    };
+
+    private void userActivity() {
+        userActivity(AWAKE_INTERVAL_DEFAULT_MS);
+    }
+
+    public void userActivity(long holdMs) {
+        // We ignore the hold time.  Eventually we should remove it.
+        // Instead, the keyguard window has an explicit user activity timeout set on it.
+        mPM.userActivity(SystemClock.uptimeMillis(), false);
+    }
+
+    /**
+     * Construct a KeyguardViewMediator
+     * @param context
+     * @param lockPatternUtils optional mock interface for LockPatternUtils
+     */
+    public KeyguardViewMediator(Context context, LockPatternUtils lockPatternUtils) {
+        mContext = context;
+        mPM = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        mShowKeyguardWakeLock = mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "show keyguard");
+        mShowKeyguardWakeLock.setReferenceCounted(false);
+
+        mContext.registerReceiver(mBroadcastReceiver, new IntentFilter(DELAYED_KEYGUARD_ACTION));
+
+        mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+
+        mUpdateMonitor = KeyguardUpdateMonitor.getInstance(context);
+
+        mLockPatternUtils = lockPatternUtils != null
+                ? lockPatternUtils : new LockPatternUtils(mContext);
+        mLockPatternUtils.setCurrentUser(UserHandle.USER_OWNER);
+
+        WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
+
+        mKeyguardViewManager = new KeyguardViewManager(context, wm, mViewMediatorCallback,
+                mLockPatternUtils);
+
+        final ContentResolver cr = mContext.getContentResolver();
+
+        mScreenOn = mPM.isScreenOn();
+
+        mLockSounds = new SoundPool(1, AudioManager.STREAM_SYSTEM, 0);
+        String soundPath = Settings.Global.getString(cr, Settings.Global.LOCK_SOUND);
+        if (soundPath != null) {
+            mLockSoundId = mLockSounds.load(soundPath, 1);
+        }
+        if (soundPath == null || mLockSoundId == 0) {
+            Log.w(TAG, "failed to load lock sound from " + soundPath);
+        }
+        soundPath = Settings.Global.getString(cr, Settings.Global.UNLOCK_SOUND);
+        if (soundPath != null) {
+            mUnlockSoundId = mLockSounds.load(soundPath, 1);
+        }
+        if (soundPath == null || mUnlockSoundId == 0) {
+            Log.w(TAG, "failed to load unlock sound from " + soundPath);
+        }
+        int lockSoundDefaultAttenuation = context.getResources().getInteger(
+                com.android.internal.R.integer.config_lockSoundVolumeDb);
+        mLockSoundVolume = (float)Math.pow(10, (float)lockSoundDefaultAttenuation/20);
+    }
+
+    /**
+     * Let us know that the system is ready after startup.
+     */
+    public void onSystemReady() {
+        mSearchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE);
+        synchronized (this) {
+            if (DEBUG) Log.d(TAG, "onSystemReady");
+            mSystemReady = true;
+            mUpdateMonitor.registerCallback(mUpdateCallback);
+
+            // Suppress biometric unlock right after boot until things have settled if it is the
+            // selected security method, otherwise unsuppress it.  It must be unsuppressed if it is
+            // not the selected security method for the following reason:  if the user starts
+            // without a screen lock selected, the biometric unlock would be suppressed the first
+            // time they try to use it.
+            //
+            // Note that the biometric unlock will still not show if it is not the selected method.
+            // Calling setAlternateUnlockEnabled(true) simply says don't suppress it if it is the
+            // selected method.
+            if (mLockPatternUtils.usingBiometricWeak()
+                    && mLockPatternUtils.isBiometricWeakInstalled()) {
+                if (DEBUG) Log.d(TAG, "suppressing biometric unlock during boot");
+                mUpdateMonitor.setAlternateUnlockEnabled(false);
+            } else {
+                mUpdateMonitor.setAlternateUnlockEnabled(true);
+            }
+
+            doKeyguardLocked(null);
+        }
+        // Most services aren't available until the system reaches the ready state, so we
+        // send it here when the device first boots.
+        maybeSendUserPresentBroadcast();
+    }
+
+    /**
+     * Called to let us know the screen was turned off.
+     * @param why either {@link WindowManagerPolicy#OFF_BECAUSE_OF_USER},
+     *   {@link WindowManagerPolicy#OFF_BECAUSE_OF_TIMEOUT} or
+     *   {@link WindowManagerPolicy#OFF_BECAUSE_OF_PROX_SENSOR}.
+     */
+    public void onScreenTurnedOff(int why) {
+        synchronized (this) {
+            mScreenOn = false;
+            if (DEBUG) Log.d(TAG, "onScreenTurnedOff(" + why + ")");
+
+            mKeyguardDonePending = false;
+
+            // Lock immediately based on setting if secure (user has a pin/pattern/password).
+            // This also "locks" the device when not secure to provide easy access to the
+            // camera while preventing unwanted input.
+            final boolean lockImmediately =
+                mLockPatternUtils.getPowerButtonInstantlyLocks() || !mLockPatternUtils.isSecure();
+
+            if (mExitSecureCallback != null) {
+                if (DEBUG) Log.d(TAG, "pending exit secure callback cancelled");
+                try {
+                    mExitSecureCallback.onKeyguardExitResult(false);
+                } catch (RemoteException e) {
+                    Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e);
+                }
+                mExitSecureCallback = null;
+                if (!mExternallyEnabled) {
+                    hideLocked();
+                }
+            } else if (mShowing) {
+                notifyScreenOffLocked();
+                resetStateLocked(null);
+            } else if (why == WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT
+                   || (why == WindowManagerPolicy.OFF_BECAUSE_OF_USER && !lockImmediately)) {
+                doKeyguardLaterLocked();
+            } else if (why == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR) {
+                // Do not enable the keyguard if the prox sensor forced the screen off.
+            } else {
+                doKeyguardLocked(null);
+            }
+        }
+    }
+
+    private void doKeyguardLaterLocked() {
+        // if the screen turned off because of timeout or the user hit the power button
+        // and we don't need to lock immediately, set an alarm
+        // to enable it a little bit later (i.e, give the user a chance
+        // to turn the screen back on within a certain window without
+        // having to unlock the screen)
+        final ContentResolver cr = mContext.getContentResolver();
+
+        // From DisplaySettings
+        long displayTimeout = Settings.System.getInt(cr, SCREEN_OFF_TIMEOUT,
+                KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT);
+
+        // From SecuritySettings
+        final long lockAfterTimeout = Settings.Secure.getInt(cr,
+                Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT,
+                KEYGUARD_LOCK_AFTER_DELAY_DEFAULT);
+
+        // From DevicePolicyAdmin
+        final long policyTimeout = mLockPatternUtils.getDevicePolicyManager()
+                .getMaximumTimeToLock(null, mLockPatternUtils.getCurrentUser());
+
+        long timeout;
+        if (policyTimeout > 0) {
+            // policy in effect. Make sure we don't go beyond policy limit.
+            displayTimeout = Math.max(displayTimeout, 0); // ignore negative values
+            timeout = Math.min(policyTimeout - displayTimeout, lockAfterTimeout);
+        } else {
+            timeout = lockAfterTimeout;
+        }
+
+        if (timeout <= 0) {
+            // Lock now
+            mSuppressNextLockSound = true;
+            doKeyguardLocked(null);
+        } else {
+            // Lock in the future
+            long when = SystemClock.elapsedRealtime() + timeout;
+            Intent intent = new Intent(DELAYED_KEYGUARD_ACTION);
+            intent.putExtra("seq", mDelayedShowingSequence);
+            PendingIntent sender = PendingIntent.getBroadcast(mContext,
+                    0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
+            mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, when, sender);
+            if (DEBUG) Log.d(TAG, "setting alarm to turn off keyguard, seq = "
+                             + mDelayedShowingSequence);
+        }
+    }
+
+    private void cancelDoKeyguardLaterLocked() {
+        mDelayedShowingSequence++;
+    }
+
+    /**
+     * Let's us know the screen was turned on.
+     */
+    public void onScreenTurnedOn(IKeyguardShowCallback callback) {
+        synchronized (this) {
+            mScreenOn = true;
+            cancelDoKeyguardLaterLocked();
+            if (DEBUG) Log.d(TAG, "onScreenTurnedOn, seq = " + mDelayedShowingSequence);
+            if (callback != null) {
+                notifyScreenOnLocked(callback);
+            }
+        }
+        maybeSendUserPresentBroadcast();
+    }
+
+    private void maybeSendUserPresentBroadcast() {
+        if (mSystemReady && mLockPatternUtils.isLockScreenDisabled()
+                && mUserManager.getUsers(true).size() == 1) {
+            // Lock screen is disabled because the user has set the preference to "None".
+            // In this case, send out ACTION_USER_PRESENT here instead of in
+            // handleKeyguardDone()
+            sendUserPresentBroadcast();
+        }
+    }
+
+    /**
+     * A dream started.  We should lock after the usual screen-off lock timeout but only
+     * if there is a secure lock pattern.
+     */
+    public void onDreamingStarted() {
+        synchronized (this) {
+            if (mScreenOn && mLockPatternUtils.isSecure()) {
+                doKeyguardLaterLocked();
+            }
+        }
+    }
+
+    /**
+     * A dream stopped.
+     */
+    public void onDreamingStopped() {
+        synchronized (this) {
+            if (mScreenOn) {
+                cancelDoKeyguardLaterLocked();
+            }
+        }
+    }
+
+    /**
+     * Same semantics as {@link WindowManagerPolicy#enableKeyguard}; provide
+     * a way for external stuff to override normal keyguard behavior.  For instance
+     * the phone app disables the keyguard when it receives incoming calls.
+     */
+    public void setKeyguardEnabled(boolean enabled) {
+        synchronized (this) {
+            if (DEBUG) Log.d(TAG, "setKeyguardEnabled(" + enabled + ")");
+
+            mExternallyEnabled = enabled;
+
+            if (!enabled && mShowing) {
+                if (mExitSecureCallback != null) {
+                    if (DEBUG) Log.d(TAG, "in process of verifyUnlock request, ignoring");
+                    // we're in the process of handling a request to verify the user
+                    // can get past the keyguard. ignore extraneous requests to disable / reenable
+                    return;
+                }
+
+                // hiding keyguard that is showing, remember to reshow later
+                if (DEBUG) Log.d(TAG, "remembering to reshow, hiding keyguard, "
+                        + "disabling status bar expansion");
+                mNeedToReshowWhenReenabled = true;
+                hideLocked();
+            } else if (enabled && mNeedToReshowWhenReenabled) {
+                // reenabled after previously hidden, reshow
+                if (DEBUG) Log.d(TAG, "previously hidden, reshowing, reenabling "
+                        + "status bar expansion");
+                mNeedToReshowWhenReenabled = false;
+
+                if (mExitSecureCallback != null) {
+                    if (DEBUG) Log.d(TAG, "onKeyguardExitResult(false), resetting");
+                    try {
+                        mExitSecureCallback.onKeyguardExitResult(false);
+                    } catch (RemoteException e) {
+                        Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e);
+                    }
+                    mExitSecureCallback = null;
+                    resetStateLocked(null);
+                } else {
+                    showLocked(null);
+
+                    // block until we know the keygaurd is done drawing (and post a message
+                    // to unblock us after a timeout so we don't risk blocking too long
+                    // and causing an ANR).
+                    mWaitingUntilKeyguardVisible = true;
+                    mHandler.sendEmptyMessageDelayed(KEYGUARD_DONE_DRAWING, KEYGUARD_DONE_DRAWING_TIMEOUT_MS);
+                    if (DEBUG) Log.d(TAG, "waiting until mWaitingUntilKeyguardVisible is false");
+                    while (mWaitingUntilKeyguardVisible) {
+                        try {
+                            wait();
+                        } catch (InterruptedException e) {
+                            Thread.currentThread().interrupt();
+                        }
+                    }
+                    if (DEBUG) Log.d(TAG, "done waiting for mWaitingUntilKeyguardVisible");
+                }
+            }
+        }
+    }
+
+    /**
+     * @see android.app.KeyguardManager#exitKeyguardSecurely
+     */
+    public void verifyUnlock(IKeyguardExitCallback callback) {
+        synchronized (this) {
+            if (DEBUG) Log.d(TAG, "verifyUnlock");
+            if (!mUpdateMonitor.isDeviceProvisioned()) {
+                // don't allow this api when the device isn't provisioned
+                if (DEBUG) Log.d(TAG, "ignoring because device isn't provisioned");
+                try {
+                    callback.onKeyguardExitResult(false);
+                } catch (RemoteException e) {
+                    Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e);
+                }
+            } else if (mExternallyEnabled) {
+                // this only applies when the user has externally disabled the
+                // keyguard.  this is unexpected and means the user is not
+                // using the api properly.
+                Log.w(TAG, "verifyUnlock called when not externally disabled");
+                try {
+                    callback.onKeyguardExitResult(false);
+                } catch (RemoteException e) {
+                    Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e);
+                }
+            } else if (mExitSecureCallback != null) {
+                // already in progress with someone else
+                try {
+                    callback.onKeyguardExitResult(false);
+                } catch (RemoteException e) {
+                    Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e);
+                }
+            } else {
+                mExitSecureCallback = callback;
+                verifyUnlockLocked();
+            }
+        }
+    }
+
+    /**
+     * Is the keyguard currently showing?
+     */
+    public boolean isShowing() {
+        return mShowing;
+    }
+
+    /**
+     * Is the keyguard currently showing and not being force hidden?
+     */
+    public boolean isShowingAndNotHidden() {
+        return mShowing && !mHidden;
+    }
+
+    /**
+     * Notify us when the keyguard is hidden by another window
+     */
+    public void setHidden(boolean isHidden) {
+        if (DEBUG) Log.d(TAG, "setHidden " + isHidden);
+        mUpdateMonitor.sendKeyguardVisibilityChanged(!isHidden);
+        mHandler.removeMessages(SET_HIDDEN);
+        Message msg = mHandler.obtainMessage(SET_HIDDEN, (isHidden ? 1 : 0), 0);
+        mHandler.sendMessage(msg);
+    }
+
+    /**
+     * Handles SET_HIDDEN message sent by setHidden()
+     */
+    private void handleSetHidden(boolean isHidden) {
+        synchronized (KeyguardViewMediator.this) {
+            if (mHidden != isHidden) {
+                mHidden = isHidden;
+                updateActivityLockScreenState();
+                adjustStatusBarLocked();
+            }
+        }
+    }
+
+    /**
+     * Used by PhoneWindowManager to enable the keyguard due to a user activity timeout.
+     * This must be safe to call from any thread and with any window manager locks held.
+     */
+    public void doKeyguardTimeout(Bundle options) {
+        mHandler.removeMessages(KEYGUARD_TIMEOUT);
+        Message msg = mHandler.obtainMessage(KEYGUARD_TIMEOUT, options);
+        mHandler.sendMessage(msg);
+    }
+
+    /**
+     * Given the state of the keyguard, is the input restricted?
+     * Input is restricted when the keyguard is showing, or when the keyguard
+     * was suppressed by an app that disabled the keyguard or we haven't been provisioned yet.
+     */
+    public boolean isInputRestricted() {
+        return mShowing || mNeedToReshowWhenReenabled || !mUpdateMonitor.isDeviceProvisioned();
+    }
+
+    /**
+     * Enable the keyguard if the settings are appropriate.
+     */
+    private void doKeyguardLocked(Bundle options) {
+        // if another app is disabling us, don't show
+        if (!mExternallyEnabled) {
+            if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled");
+
+            // note: we *should* set mNeedToReshowWhenReenabled=true here, but that makes
+            // for an occasional ugly flicker in this situation:
+            // 1) receive a call with the screen on (no keyguard) or make a call
+            // 2) screen times out
+            // 3) user hits key to turn screen back on
+            // instead, we reenable the keyguard when we know the screen is off and the call
+            // ends (see the broadcast receiver below)
+            // TODO: clean this up when we have better support at the window manager level
+            // for apps that wish to be on top of the keyguard
+            return;
+        }
+
+        // if the keyguard is already showing, don't bother
+        if (mKeyguardViewManager.isShowing()) {
+            if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing");
+            return;
+        }
+
+        // if the setup wizard hasn't run yet, don't show
+        final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim",
+                false);
+        final boolean provisioned = mUpdateMonitor.isDeviceProvisioned();
+        final IccCardConstants.State state = mUpdateMonitor.getSimState();
+        final boolean lockedOrMissing = state.isPinLocked()
+                || ((state == IccCardConstants.State.ABSENT
+                || state == IccCardConstants.State.PERM_DISABLED)
+                && requireSim);
+
+        if (!lockedOrMissing && !provisioned) {
+            if (DEBUG) Log.d(TAG, "doKeyguard: not showing because device isn't provisioned"
+                    + " and the sim is not locked or missing");
+            return;
+        }
+
+        if (mUserManager.getUsers(true).size() < 2
+                && mLockPatternUtils.isLockScreenDisabled() && !lockedOrMissing) {
+            if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off");
+            return;
+        }
+
+        if (DEBUG) Log.d(TAG, "doKeyguard: showing the lock screen");
+        showLocked(options);
+    }
+
+    /**
+     * Dismiss the keyguard through the security layers.
+     */
+    public void dismiss() {
+        if (mShowing && !mHidden) {
+            mKeyguardViewManager.dismiss();
+        }
+    }
+
+    /**
+     * Send message to keyguard telling it to reset its state.
+     * @param options options about how to show the keyguard
+     * @see #handleReset()
+     */
+    private void resetStateLocked(Bundle options) {
+        if (DEBUG) Log.e(TAG, "resetStateLocked");
+        Message msg = mHandler.obtainMessage(RESET, options);
+        mHandler.sendMessage(msg);
+    }
+
+    /**
+     * Send message to keyguard telling it to verify unlock
+     * @see #handleVerifyUnlock()
+     */
+    private void verifyUnlockLocked() {
+        if (DEBUG) Log.d(TAG, "verifyUnlockLocked");
+        mHandler.sendEmptyMessage(VERIFY_UNLOCK);
+    }
+
+
+    /**
+     * Send a message to keyguard telling it the screen just turned on.
+     * @see #onScreenTurnedOff(int)
+     * @see #handleNotifyScreenOff
+     */
+    private void notifyScreenOffLocked() {
+        if (DEBUG) Log.d(TAG, "notifyScreenOffLocked");
+        mHandler.sendEmptyMessage(NOTIFY_SCREEN_OFF);
+    }
+
+    /**
+     * Send a message to keyguard telling it the screen just turned on.
+     * @see #onScreenTurnedOn()
+     * @see #handleNotifyScreenOn
+     */
+    private void notifyScreenOnLocked(IKeyguardShowCallback result) {
+        if (DEBUG) Log.d(TAG, "notifyScreenOnLocked");
+        Message msg = mHandler.obtainMessage(NOTIFY_SCREEN_ON, result);
+        mHandler.sendMessage(msg);
+    }
+
+    /**
+     * Send message to keyguard telling it to show itself
+     * @see #handleShow()
+     */
+    private void showLocked(Bundle options) {
+        if (DEBUG) Log.d(TAG, "showLocked");
+        // ensure we stay awake until we are finished displaying the keyguard
+        mShowKeyguardWakeLock.acquire();
+        Message msg = mHandler.obtainMessage(SHOW, options);
+        mHandler.sendMessage(msg);
+    }
+
+    /**
+     * Send message to keyguard telling it to hide itself
+     * @see #handleHide()
+     */
+    private void hideLocked() {
+        if (DEBUG) Log.d(TAG, "hideLocked");
+        Message msg = mHandler.obtainMessage(HIDE);
+        mHandler.sendMessage(msg);
+    }
+
+    public boolean isSecure() {
+        return mLockPatternUtils.isSecure()
+            || KeyguardUpdateMonitor.getInstance(mContext).isSimPinSecure();
+    }
+
+    /**
+     * Update the newUserId. Call while holding WindowManagerService lock.
+     * NOTE: Should only be called by KeyguardViewMediator in response to the user id changing.
+     *
+     * @param newUserId The id of the incoming user.
+     */
+    public void setCurrentUser(int newUserId) {
+        mLockPatternUtils.setCurrentUser(newUserId);
+    }
+
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (DELAYED_KEYGUARD_ACTION.equals(intent.getAction())) {
+                final int sequence = intent.getIntExtra("seq", 0);
+                if (DEBUG) Log.d(TAG, "received DELAYED_KEYGUARD_ACTION with seq = "
+                        + sequence + ", mDelayedShowingSequence = " + mDelayedShowingSequence);
+                synchronized (KeyguardViewMediator.this) {
+                    if (mDelayedShowingSequence == sequence) {
+                        // Don't play lockscreen SFX if the screen went off due to timeout.
+                        mSuppressNextLockSound = true;
+                        doKeyguardLocked(null);
+                    }
+                }
+            }
+        }
+    };
+
+    public void keyguardDone(boolean authenticated, boolean wakeup) {
+        mKeyguardDonePending = false;
+        synchronized (this) {
+            EventLog.writeEvent(70000, 2);
+            if (DEBUG) Log.d(TAG, "keyguardDone(" + authenticated + ")");
+            Message msg = mHandler.obtainMessage(KEYGUARD_DONE, authenticated ? 1 : 0,
+                    wakeup ? 1 : 0);
+            mHandler.sendMessage(msg);
+        }
+    }
+
+    /**
+     * This handler will be associated with the policy thread, which will also
+     * be the UI thread of the keyguard.  Since the apis of the policy, and therefore
+     * this class, can be called by other threads, any action that directly
+     * interacts with the keyguard ui should be posted to this handler, rather
+     * than called directly.
+     */
+    private Handler mHandler = new Handler(Looper.myLooper(), null, true /*async*/) {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case SHOW:
+                    handleShow((Bundle) msg.obj);
+                    return ;
+                case HIDE:
+                    handleHide();
+                    return ;
+                case RESET:
+                    handleReset((Bundle) msg.obj);
+                    return ;
+                case VERIFY_UNLOCK:
+                    handleVerifyUnlock();
+                    return;
+                case NOTIFY_SCREEN_OFF:
+                    handleNotifyScreenOff();
+                    return;
+                case NOTIFY_SCREEN_ON:
+                    handleNotifyScreenOn((IKeyguardShowCallback) msg.obj);
+                    return;
+                case KEYGUARD_DONE:
+                    handleKeyguardDone(msg.arg1 != 0, msg.arg2 != 0);
+                    return;
+                case KEYGUARD_DONE_DRAWING:
+                    handleKeyguardDoneDrawing();
+                    return;
+                case KEYGUARD_DONE_AUTHENTICATING:
+                    keyguardDone(true, true);
+                    return;
+                case SET_HIDDEN:
+                    handleSetHidden(msg.arg1 != 0);
+                    break;
+                case KEYGUARD_TIMEOUT:
+                    synchronized (KeyguardViewMediator.this) {
+                        doKeyguardLocked((Bundle) msg.obj);
+                    }
+                    break;
+                case SHOW_ASSISTANT:
+                    handleShowAssistant();
+                    break;
+            }
+        }
+    };
+
+    /**
+     * @see #keyguardDone
+     * @see #KEYGUARD_DONE
+     */
+    private void handleKeyguardDone(boolean authenticated, boolean wakeup) {
+        if (DEBUG) Log.d(TAG, "handleKeyguardDone");
+
+        if (authenticated) {
+            mUpdateMonitor.clearFailedUnlockAttempts();
+        }
+
+        if (mExitSecureCallback != null) {
+            try {
+                mExitSecureCallback.onKeyguardExitResult(authenticated);
+            } catch (RemoteException e) {
+                Slog.w(TAG, "Failed to call onKeyguardExitResult(" + authenticated + ")", e);
+            }
+
+            mExitSecureCallback = null;
+
+            if (authenticated) {
+                // after succesfully exiting securely, no need to reshow
+                // the keyguard when they've released the lock
+                mExternallyEnabled = true;
+                mNeedToReshowWhenReenabled = false;
+            }
+        }
+
+        handleHide();
+        sendUserPresentBroadcast();
+    }
+
+    private void sendUserPresentBroadcast() {
+        final UserHandle currentUser = new UserHandle(mLockPatternUtils.getCurrentUser());
+        mContext.sendBroadcastAsUser(USER_PRESENT_INTENT, currentUser);
+    }
+
+    /**
+     * @see #keyguardDoneDrawing
+     * @see #KEYGUARD_DONE_DRAWING
+     */
+    private void handleKeyguardDoneDrawing() {
+        synchronized(this) {
+            if (DEBUG) Log.d(TAG, "handleKeyguardDoneDrawing");
+            if (mWaitingUntilKeyguardVisible) {
+                if (DEBUG) Log.d(TAG, "handleKeyguardDoneDrawing: notifying mWaitingUntilKeyguardVisible");
+                mWaitingUntilKeyguardVisible = false;
+                notifyAll();
+
+                // there will usually be two of these sent, one as a timeout, and one
+                // as a result of the callback, so remove any remaining messages from
+                // the queue
+                mHandler.removeMessages(KEYGUARD_DONE_DRAWING);
+            }
+        }
+    }
+
+    private void playSounds(boolean locked) {
+        // User feedback for keyguard.
+
+        if (mSuppressNextLockSound) {
+            mSuppressNextLockSound = false;
+            return;
+        }
+
+        final ContentResolver cr = mContext.getContentResolver();
+        if (Settings.System.getInt(cr, Settings.System.LOCKSCREEN_SOUNDS_ENABLED, 1) == 1) {
+            final int whichSound = locked
+                ? mLockSoundId
+                : mUnlockSoundId;
+            mLockSounds.stop(mLockSoundStreamId);
+            // Init mAudioManager
+            if (mAudioManager == null) {
+                mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+                if (mAudioManager == null) return;
+                mMasterStreamType = mAudioManager.getMasterStreamType();
+            }
+            // If the stream is muted, don't play the sound
+            if (mAudioManager.isStreamMute(mMasterStreamType)) return;
+
+            mLockSoundStreamId = mLockSounds.play(whichSound,
+                    mLockSoundVolume, mLockSoundVolume, 1/*priortiy*/, 0/*loop*/, 1.0f/*rate*/);
+        }
+    }
+
+    private void updateActivityLockScreenState() {
+        try {
+            ActivityManagerNative.getDefault().setLockScreenShown(
+                    mShowing && !mHidden);
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
+     * Handle message sent by {@link #showLocked}.
+     * @see #SHOW
+     */
+    private void handleShow(Bundle options) {
+        synchronized (KeyguardViewMediator.this) {
+            if (!mSystemReady) {
+                if (DEBUG) Log.d(TAG, "ignoring handleShow because system is not ready.");
+                return;
+            } else {
+                if (DEBUG) Log.d(TAG, "handleShow");
+            }
+
+            mKeyguardViewManager.show(options);
+            mShowing = true;
+            mKeyguardDonePending = false;
+            updateActivityLockScreenState();
+            adjustStatusBarLocked();
+            userActivity();
+            try {
+                ActivityManagerNative.getDefault().closeSystemDialogs("lock");
+            } catch (RemoteException e) {
+            }
+
+            // Do this at the end to not slow down display of the keyguard.
+            playSounds(true);
+
+            mShowKeyguardWakeLock.release();
+        }
+    }
+
+    /**
+     * Handle message sent by {@link #hideLocked()}
+     * @see #HIDE
+     */
+    private void handleHide() {
+        synchronized (KeyguardViewMediator.this) {
+            if (DEBUG) Log.d(TAG, "handleHide");
+
+            // only play "unlock" noises if not on a call (since the incall UI
+            // disables the keyguard)
+            if (TelephonyManager.EXTRA_STATE_IDLE.equals(mPhoneState)) {
+                playSounds(false);
+            }
+
+            mKeyguardViewManager.hide();
+            mShowing = false;
+            mKeyguardDonePending = false;
+            updateActivityLockScreenState();
+            adjustStatusBarLocked();
+        }
+    }
+
+    private void adjustStatusBarLocked() {
+        if (mStatusBarManager == null) {
+            mStatusBarManager = (StatusBarManager)
+                    mContext.getSystemService(Context.STATUS_BAR_SERVICE);
+        }
+        if (mStatusBarManager == null) {
+            Log.w(TAG, "Could not get status bar manager");
+        } else {
+            // Disable aspects of the system/status/navigation bars that must not be re-enabled by
+            // windows that appear on top, ever
+            int flags = StatusBarManager.DISABLE_NONE;
+            if (mShowing) {
+                // Permanently disable components not available when keyguard is enabled
+                // (like recents). Temporary enable/disable (e.g. the "back" button) are
+                // done in KeyguardHostView.
+                flags |= StatusBarManager.DISABLE_RECENT;
+                if (isSecure() || !ENABLE_INSECURE_STATUS_BAR_EXPAND) {
+                    // showing secure lockscreen; disable expanding.
+                    flags |= StatusBarManager.DISABLE_EXPAND;
+                }
+                if (isSecure()) {
+                    // showing secure lockscreen; disable ticker.
+                    flags |= StatusBarManager.DISABLE_NOTIFICATION_TICKER;
+                }
+                if (!isAssistantAvailable()) {
+                    flags |= StatusBarManager.DISABLE_SEARCH;
+                }
+            }
+
+            if (DEBUG) {
+                Log.d(TAG, "adjustStatusBarLocked: mShowing=" + mShowing + " mHidden=" + mHidden
+                        + " isSecure=" + isSecure() + " --> flags=0x" + Integer.toHexString(flags));
+            }
+
+            if (!(mContext instanceof Activity)) {
+                mStatusBarManager.disable(flags);
+            }
+        }
+    }
+
+    /**
+     * Handle message sent by {@link #resetStateLocked(Bundle)}
+     * @see #RESET
+     */
+    private void handleReset(Bundle options) {
+        if (options == null) {
+            options = new Bundle();
+        }
+        options.putBoolean(KeyguardViewManager.IS_SWITCHING_USER, mSwitchingUser);
+        synchronized (KeyguardViewMediator.this) {
+            if (DEBUG) Log.d(TAG, "handleReset");
+            mKeyguardViewManager.reset(options);
+        }
+    }
+
+    /**
+     * Handle message sent by {@link #verifyUnlock}
+     * @see #VERIFY_UNLOCK
+     */
+    private void handleVerifyUnlock() {
+        synchronized (KeyguardViewMediator.this) {
+            if (DEBUG) Log.d(TAG, "handleVerifyUnlock");
+            mKeyguardViewManager.verifyUnlock();
+            mShowing = true;
+            updateActivityLockScreenState();
+        }
+    }
+
+    /**
+     * Handle message sent by {@link #notifyScreenOffLocked()}
+     * @see #NOTIFY_SCREEN_OFF
+     */
+    private void handleNotifyScreenOff() {
+        synchronized (KeyguardViewMediator.this) {
+            if (DEBUG) Log.d(TAG, "handleNotifyScreenOff");
+            mKeyguardViewManager.onScreenTurnedOff();
+        }
+    }
+
+    /**
+     * Handle message sent by {@link #notifyScreenOnLocked()}
+     * @see #NOTIFY_SCREEN_ON
+     */
+    private void handleNotifyScreenOn(IKeyguardShowCallback callback) {
+        synchronized (KeyguardViewMediator.this) {
+            if (DEBUG) Log.d(TAG, "handleNotifyScreenOn");
+            mKeyguardViewManager.onScreenTurnedOn(callback);
+        }
+    }
+
+    public boolean isDismissable() {
+        return mKeyguardDonePending || !isSecure();
+    }
+
+    public void showAssistant() {
+        Message msg = mHandler.obtainMessage(SHOW_ASSISTANT);
+        mHandler.sendMessage(msg);
+    }
+
+    public void handleShowAssistant() {
+        mKeyguardViewManager.showAssistant();
+    }
+
+    private boolean isAssistantAvailable() {
+        return mSearchManager != null
+                && mSearchManager.getAssistIntent(mContext, false, UserHandle.USER_CURRENT) != null;
+    }
+
+    public static MultiUserAvatarCache getAvatarCache() {
+        return sMultiUserAvatarCache;
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java
new file mode 100644
index 0000000..e85f6df
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java
@@ -0,0 +1,317 @@
+/*
+ * 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.keyguard;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.view.View;
+
+public class KeyguardViewStateManager implements
+        SlidingChallengeLayout.OnChallengeScrolledListener,
+        ChallengeLayout.OnBouncerStateChangedListener {
+
+    private KeyguardWidgetPager mKeyguardWidgetPager;
+    private ChallengeLayout mChallengeLayout;
+    private KeyguardHostView mKeyguardHostView;
+    private int[] mTmpPoint = new int[2];
+    private int[] mTmpLoc = new int[2];
+
+    private KeyguardSecurityView mKeyguardSecurityContainer;
+    private static final int SCREEN_ON_HINT_DURATION = 1000;
+    private static final int SCREEN_ON_RING_HINT_DELAY = 300;
+    Handler mMainQueue = new Handler(Looper.myLooper());
+
+    int mLastScrollState = SlidingChallengeLayout.SCROLL_STATE_IDLE;
+
+    // Paged view state
+    private int mPageListeningToSlider = -1;
+    private int mCurrentPage = -1;
+    private int mPageIndexOnPageBeginMoving = -1;
+
+    int mChallengeTop = 0;
+
+    public KeyguardViewStateManager(KeyguardHostView hostView) {
+        mKeyguardHostView = hostView;
+    }
+
+    public void setPagedView(KeyguardWidgetPager pagedView) {
+        mKeyguardWidgetPager = pagedView;
+        updateEdgeSwiping();
+    }
+
+    public void setChallengeLayout(ChallengeLayout layout) {
+        mChallengeLayout = layout;
+        updateEdgeSwiping();
+    }
+
+    private void updateEdgeSwiping() {
+        if (mChallengeLayout != null && mKeyguardWidgetPager != null) {
+            if (mChallengeLayout.isChallengeOverlapping()) {
+                mKeyguardWidgetPager.setOnlyAllowEdgeSwipes(true);
+            } else {
+                mKeyguardWidgetPager.setOnlyAllowEdgeSwipes(false);
+            }
+        }
+    }
+
+    public boolean isChallengeShowing() {
+        if (mChallengeLayout != null) {
+            return mChallengeLayout.isChallengeShowing();
+        }
+        return false;
+    }
+
+    public boolean isChallengeOverlapping() {
+        if (mChallengeLayout != null) {
+            return mChallengeLayout.isChallengeOverlapping();
+        }
+        return false;
+    }
+
+    public void setSecurityViewContainer(KeyguardSecurityView container) {
+        mKeyguardSecurityContainer = container;
+    }
+
+    public void showBouncer(boolean show) {
+        mChallengeLayout.showBouncer();
+    }
+
+    public boolean isBouncing() {
+        return mChallengeLayout.isBouncing();
+    }
+
+    public void fadeOutSecurity(int duration) {
+        ((View) mKeyguardSecurityContainer).animate().alpha(0).setDuration(duration);
+    }
+
+    public void fadeInSecurity(int duration) {
+        ((View) mKeyguardSecurityContainer).animate().alpha(1f).setDuration(duration);
+    }
+
+    public void onPageBeginMoving() {
+        if (mChallengeLayout.isChallengeOverlapping() &&
+                mChallengeLayout instanceof SlidingChallengeLayout) {
+            SlidingChallengeLayout scl = (SlidingChallengeLayout) mChallengeLayout;
+            scl.fadeOutChallenge();
+            mPageIndexOnPageBeginMoving = mKeyguardWidgetPager.getCurrentPage();
+        }
+        // We use mAppWidgetToShow to show a particular widget after you add it--
+        // once the user swipes a page we clear that behavior
+        if (mKeyguardHostView != null) {
+            mKeyguardHostView.clearAppWidgetToShow();
+            mKeyguardHostView.setOnDismissAction(null);
+        }
+        if (mHideHintsRunnable != null) {
+            mMainQueue.removeCallbacks(mHideHintsRunnable);
+            mHideHintsRunnable = null;
+        }
+    }
+
+    public void onPageEndMoving() {
+        mPageIndexOnPageBeginMoving = -1;
+    }
+
+    public void onPageSwitching(View newPage, int newPageIndex) {
+        if (mKeyguardWidgetPager != null && mChallengeLayout instanceof SlidingChallengeLayout) {
+            boolean isCameraPage = newPage instanceof CameraWidgetFrame;
+            ((SlidingChallengeLayout) mChallengeLayout).setChallengeInteractive(!isCameraPage);
+        }
+
+        // If the page we're settling to is the same as we started on, and the action of
+        // moving the page hid the security, we restore it immediately.
+        if (mPageIndexOnPageBeginMoving == mKeyguardWidgetPager.getNextPage() &&
+                mChallengeLayout instanceof SlidingChallengeLayout) {
+            SlidingChallengeLayout scl = (SlidingChallengeLayout) mChallengeLayout;
+            scl.fadeInChallenge();
+            mKeyguardWidgetPager.setWidgetToResetOnPageFadeOut(-1);
+        }
+        mPageIndexOnPageBeginMoving = -1;
+    }
+
+    public void onPageSwitched(View newPage, int newPageIndex) {
+        // Reset the previous page size and ensure the current page is sized appropriately.
+        // We only modify the page state if it is not currently under control by the slider.
+        // This prevents conflicts.
+
+        // If the page hasn't switched, don't bother with any of this
+        if (mCurrentPage == newPageIndex) return;
+
+        if (mKeyguardWidgetPager != null && mChallengeLayout != null) {
+            KeyguardWidgetFrame prevPage = mKeyguardWidgetPager.getWidgetPageAt(mCurrentPage);
+            if (prevPage != null && mCurrentPage != mPageListeningToSlider && mCurrentPage
+                    != mKeyguardWidgetPager.getWidgetToResetOnPageFadeOut()) {
+                prevPage.resetSize();
+            }
+
+            KeyguardWidgetFrame newCurPage = mKeyguardWidgetPager.getWidgetPageAt(newPageIndex);
+            boolean challengeOverlapping = mChallengeLayout.isChallengeOverlapping();
+            if (challengeOverlapping && !newCurPage.isSmall()
+                    && mPageListeningToSlider != newPageIndex) {
+                newCurPage.shrinkWidget();
+            }
+        }
+
+        mCurrentPage = newPageIndex;
+    }
+
+    private int getChallengeTopRelativeToFrame(KeyguardWidgetFrame frame, int top) {
+        mTmpPoint[0] = 0;
+        mTmpPoint[1] = top;
+        mapPoint((View) mChallengeLayout, frame, mTmpPoint);
+        return mTmpPoint[1];
+    }
+
+    /**
+     * Simple method to map a point from one view's coordinates to another's. Note: this method
+     * doesn't account for transforms, so if the views will be transformed, this should not be used.
+     *
+     * @param fromView The view to which the point is relative
+     * @param toView The view into which the point should be mapped
+     * @param pt The point
+     */
+    private void mapPoint(View fromView, View toView, int pt[]) {
+        fromView.getLocationInWindow(mTmpLoc);
+
+        int x = mTmpLoc[0];
+        int y = mTmpLoc[1];
+
+        toView.getLocationInWindow(mTmpLoc);
+        int vX = mTmpLoc[0];
+        int vY = mTmpLoc[1];
+
+        pt[0] += x - vX;
+        pt[1] += y - vY;
+    }
+
+    private void userActivity() {
+        if (mKeyguardHostView != null) {
+            mKeyguardHostView.onUserActivityTimeoutChanged();
+            mKeyguardHostView.userActivity();
+        }
+    }
+
+    @Override
+    public void onScrollStateChanged(int scrollState) {
+        if (mKeyguardWidgetPager == null || mChallengeLayout == null) return;
+
+        boolean challengeOverlapping = mChallengeLayout.isChallengeOverlapping();
+
+        if (scrollState == SlidingChallengeLayout.SCROLL_STATE_IDLE) {
+            KeyguardWidgetFrame frame = mKeyguardWidgetPager.getWidgetPageAt(mPageListeningToSlider);
+            if (frame == null) return;
+
+            if (!challengeOverlapping) {
+                if (!mKeyguardWidgetPager.isPageMoving()) {
+                    frame.resetSize();
+                    userActivity();
+                } else {
+                    mKeyguardWidgetPager.setWidgetToResetOnPageFadeOut(mPageListeningToSlider);
+                }
+            }
+            if (frame.isSmall()) {
+                // This is to make sure that if the scroller animation gets cut off midway
+                // that the frame doesn't stay in a partial down position.
+                frame.setFrameHeight(frame.getSmallFrameHeight());
+            }
+            if (scrollState != SlidingChallengeLayout.SCROLL_STATE_FADING) {
+                frame.hideFrame(this);
+            }
+            updateEdgeSwiping();
+
+            if (mChallengeLayout.isChallengeShowing()) {
+                mKeyguardSecurityContainer.onResume(KeyguardSecurityView.VIEW_REVEALED);
+            } else {
+                mKeyguardSecurityContainer.onPause();
+            }
+            mPageListeningToSlider = -1;
+        } else if (mLastScrollState == SlidingChallengeLayout.SCROLL_STATE_IDLE) {
+            // Whether dragging or settling, if the last state was idle, we use this signal
+            // to update the current page who will receive events from the sliding challenge.
+            // We resize the frame as appropriate.
+            mPageListeningToSlider = mKeyguardWidgetPager.getNextPage();
+            KeyguardWidgetFrame frame = mKeyguardWidgetPager.getWidgetPageAt(mPageListeningToSlider);
+            if (frame == null) return;
+
+            // Skip showing the frame and shrinking the widget if we are
+            if (!mChallengeLayout.isBouncing()) {
+                if (scrollState != SlidingChallengeLayout.SCROLL_STATE_FADING) {
+                    frame.showFrame(this);
+                }
+
+                // As soon as the security begins sliding, the widget becomes small (if it wasn't
+                // small to begin with).
+                if (!frame.isSmall()) {
+                    // We need to fetch the final page, in case the pages are in motion.
+                    mPageListeningToSlider = mKeyguardWidgetPager.getNextPage();
+                    frame.shrinkWidget(false);
+                }
+            } else {
+                if (!frame.isSmall()) {
+                    // We need to fetch the final page, in case the pages are in motion.
+                    mPageListeningToSlider = mKeyguardWidgetPager.getNextPage();
+                }
+            }
+
+            // View is on the move.  Pause the security view until it completes.
+            mKeyguardSecurityContainer.onPause();
+        }
+        mLastScrollState = scrollState;
+    }
+
+    @Override
+    public void onScrollPositionChanged(float scrollPosition, int challengeTop) {
+        mChallengeTop = challengeTop;
+        KeyguardWidgetFrame frame = mKeyguardWidgetPager.getWidgetPageAt(mPageListeningToSlider);
+        if (frame != null && mLastScrollState != SlidingChallengeLayout.SCROLL_STATE_FADING) {
+            frame.adjustFrame(getChallengeTopRelativeToFrame(frame, mChallengeTop));
+        }
+    }
+
+    private Runnable mHideHintsRunnable = new Runnable() {
+        @Override
+        public void run() {
+            if (mKeyguardWidgetPager != null) {
+                mKeyguardWidgetPager.hideOutlinesAndSidePages();
+            }
+        }
+    };
+
+    public void showUsabilityHints() {
+        mMainQueue.postDelayed( new Runnable() {
+            @Override
+            public void run() {
+                mKeyguardSecurityContainer.showUsabilityHint();
+            }
+        } , SCREEN_ON_RING_HINT_DELAY);
+        mKeyguardWidgetPager.showInitialPageHints();
+        if (mHideHintsRunnable != null) {
+            mMainQueue.postDelayed(mHideHintsRunnable, SCREEN_ON_HINT_DURATION);
+        }
+    }
+
+    // ChallengeLayout.OnBouncerStateChangedListener
+    @Override
+    public void onBouncerStateChanged(boolean bouncerActive) {
+        if (bouncerActive) {
+            mKeyguardWidgetPager.zoomOutToBouncer();
+        } else {
+            mKeyguardWidgetPager.zoomInFromBouncer();
+            if (mKeyguardHostView != null) {
+                mKeyguardHostView.setOnDismissAction(null);
+            }
+        }
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetCarousel.java b/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetCarousel.java
new file mode 100644
index 0000000..98b31b7
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetCarousel.java
@@ -0,0 +1,288 @@
+/*
+ * 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.keyguard;
+
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.Interpolator;
+
+import java.util.ArrayList;
+
+public class KeyguardWidgetCarousel extends KeyguardWidgetPager {
+
+    private float mAdjacentPagesAngle;
+    private static float MAX_SCROLL_PROGRESS = 1.3f;
+    private static float CAMERA_DISTANCE = 10000;
+    protected AnimatorSet mChildrenTransformsAnimator;
+    float[] mTmpTransform = new float[3];
+
+    public KeyguardWidgetCarousel(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public KeyguardWidgetCarousel(Context context) {
+        this(context, null, 0);
+    }
+
+    public KeyguardWidgetCarousel(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        mAdjacentPagesAngle = context.getResources().getInteger(R.integer.kg_carousel_angle);
+    }
+
+    protected float getMaxScrollProgress() {
+        return MAX_SCROLL_PROGRESS;
+    }
+
+    public float getAlphaForPage(int screenCenter, int index, boolean showSidePages) {
+        View child = getChildAt(index);
+        if (child == null) return 0f;
+
+        boolean inVisibleRange = index >= getNextPage() - 1 && index <= getNextPage() + 1;
+        float scrollProgress = getScrollProgress(screenCenter, child, index);
+
+        if (isOverScrollChild(index, scrollProgress)) {
+            return 1.0f;
+        } else if ((showSidePages && inVisibleRange) || index == getNextPage()) {
+            scrollProgress = getBoundedScrollProgress(screenCenter, child, index);
+            float alpha = 1.0f - 1.0f * Math.abs(scrollProgress / MAX_SCROLL_PROGRESS);
+            return alpha;
+        } else {
+            return 0f;
+        }
+    }
+
+    public float getOutlineAlphaForPage(int screenCenter, int index, boolean showSidePages) {
+        boolean inVisibleRange = index >= getNextPage() - 1 && index <= getNextPage() + 1;
+        if (inVisibleRange) {
+            return super.getOutlineAlphaForPage(screenCenter, index, showSidePages);
+        } else {
+            return 0f;
+        }
+    }
+
+    private void updatePageAlphaValues(int screenCenter) {
+        if (mChildrenOutlineFadeAnimation != null) {
+            mChildrenOutlineFadeAnimation.cancel();
+            mChildrenOutlineFadeAnimation = null;
+        }
+        boolean showSidePages = mShowingInitialHints || isPageMoving();
+        if (!isReordering(false)) {
+            for (int i = 0; i < getChildCount(); i++) {
+                KeyguardWidgetFrame child = getWidgetPageAt(i);
+                if (child != null) {
+                    float outlineAlpha = getOutlineAlphaForPage(screenCenter, i, showSidePages);
+                    float contentAlpha = getAlphaForPage(screenCenter, i,showSidePages);
+                    child.setBackgroundAlpha(outlineAlpha);
+                    child.setContentAlpha(contentAlpha);
+                }
+            }
+        }
+    }
+
+    public void showInitialPageHints() {
+        mShowingInitialHints = true;
+        int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            boolean inVisibleRange = i >= getNextPage() - 1 && i <= getNextPage() + 1;
+            KeyguardWidgetFrame child = getWidgetPageAt(i);
+            if (inVisibleRange) {
+                child.setBackgroundAlpha(KeyguardWidgetFrame.OUTLINE_ALPHA_MULTIPLIER);
+                child.setContentAlpha(1f);
+            } else {
+                child.setBackgroundAlpha(0f);
+                child.setContentAlpha(0f);
+            }
+        }
+    }
+
+    @Override
+    protected void screenScrolled(int screenCenter) {
+        mScreenCenter = screenCenter;
+        updatePageAlphaValues(screenCenter);
+        if (isReordering(false)) return;
+        for (int i = 0; i < getChildCount(); i++) {
+            KeyguardWidgetFrame v = getWidgetPageAt(i);
+            float scrollProgress = getScrollProgress(screenCenter, v, i);
+            float boundedProgress = getBoundedScrollProgress(screenCenter, v, i);
+            if (v == mDragView || v == null) continue;
+            v.setCameraDistance(CAMERA_DISTANCE);
+
+            if (isOverScrollChild(i, scrollProgress)) {
+                v.setRotationY(- OVERSCROLL_MAX_ROTATION * scrollProgress);
+                v.setOverScrollAmount(Math.abs(scrollProgress), scrollProgress < 0);
+            } else {
+                int width = v.getMeasuredWidth();
+                float pivotX = (width / 2f) + boundedProgress * (width / 2f);
+                float pivotY = v.getMeasuredHeight() / 2;
+                float rotationY = - mAdjacentPagesAngle * boundedProgress;
+                v.setPivotX(pivotX);
+                v.setPivotY(pivotY);
+                v.setRotationY(rotationY);
+                v.setOverScrollAmount(0f, false);
+            }
+            float alpha = v.getAlpha();
+            // If the view has 0 alpha, we set it to be invisible so as to prevent
+            // it from accepting touches
+            if (alpha == 0) {
+                v.setVisibility(INVISIBLE);
+            } else if (v.getVisibility() != VISIBLE) {
+                v.setVisibility(VISIBLE);
+            }
+        }
+    }
+
+    void animatePagesToNeutral() {
+        if (mChildrenTransformsAnimator != null) {
+            mChildrenTransformsAnimator.cancel();
+            mChildrenTransformsAnimator = null;
+        }
+
+        int count = getChildCount();
+        PropertyValuesHolder alpha;
+        PropertyValuesHolder outlineAlpha;
+        PropertyValuesHolder rotationY;
+        ArrayList<Animator> anims = new ArrayList<Animator>();
+
+        for (int i = 0; i < count; i++) {
+            KeyguardWidgetFrame child = getWidgetPageAt(i);
+            boolean inVisibleRange = (i >= mCurrentPage - 1 && i <= mCurrentPage + 1);
+            if (!inVisibleRange) {
+                child.setRotationY(0f);
+            }
+            alpha = PropertyValuesHolder.ofFloat("contentAlpha", 1.0f);
+            outlineAlpha = PropertyValuesHolder.ofFloat("backgroundAlpha",
+                    KeyguardWidgetFrame.OUTLINE_ALPHA_MULTIPLIER);
+            rotationY = PropertyValuesHolder.ofFloat("rotationY", 0f);
+            ObjectAnimator a = ObjectAnimator.ofPropertyValuesHolder(child, alpha, outlineAlpha, rotationY);
+            child.setVisibility(VISIBLE);
+            if (!inVisibleRange) {
+                a.setInterpolator(mSlowFadeInterpolator);
+            }
+            anims.add(a);
+        }
+
+        int duration = REORDERING_ZOOM_IN_OUT_DURATION;
+        mChildrenTransformsAnimator = new AnimatorSet();
+        mChildrenTransformsAnimator.playTogether(anims);
+
+        mChildrenTransformsAnimator.setDuration(duration);
+        mChildrenTransformsAnimator.start();
+    }
+
+    private void getTransformForPage(int screenCenter, int index, float[] transform) {
+        View child = getChildAt(index);
+        float boundedProgress = getBoundedScrollProgress(screenCenter, child, index);
+        float rotationY = - mAdjacentPagesAngle * boundedProgress;
+        int width = child.getMeasuredWidth();
+        float pivotX = (width / 2f) + boundedProgress * (width / 2f);
+        float pivotY = child.getMeasuredHeight() / 2;
+
+        transform[0] = pivotX;
+        transform[1] = pivotY;
+        transform[2] = rotationY;
+    }
+
+    Interpolator mFastFadeInterpolator = new Interpolator() {
+        Interpolator mInternal = new DecelerateInterpolator(1.5f);
+        float mFactor = 2.5f;
+        @Override
+        public float getInterpolation(float input) {
+            return mInternal.getInterpolation(Math.min(mFactor * input, 1f));
+        }
+    };
+
+    Interpolator mSlowFadeInterpolator = new Interpolator() {
+        Interpolator mInternal = new AccelerateInterpolator(1.5f);
+        float mFactor = 1.3f;
+        @Override
+        public float getInterpolation(float input) {
+            input -= (1 - 1 / mFactor);
+            input = mFactor * Math.max(input, 0f);
+            return mInternal.getInterpolation(input);
+        }
+    };
+
+    void animatePagesToCarousel() {
+        if (mChildrenTransformsAnimator != null) {
+            mChildrenTransformsAnimator.cancel();
+            mChildrenTransformsAnimator = null;
+        }
+
+        int count = getChildCount();
+        PropertyValuesHolder alpha;
+        PropertyValuesHolder outlineAlpha;
+        PropertyValuesHolder rotationY;
+        PropertyValuesHolder pivotX;
+        PropertyValuesHolder pivotY;
+        ArrayList<Animator> anims = new ArrayList<Animator>();
+
+        for (int i = 0; i < count; i++) {
+            KeyguardWidgetFrame child = getWidgetPageAt(i);
+            float finalAlpha = getAlphaForPage(mScreenCenter, i, true);
+            float finalOutlineAlpha = getOutlineAlphaForPage(mScreenCenter, i, true);
+            getTransformForPage(mScreenCenter, i, mTmpTransform);
+
+            boolean inVisibleRange = (i >= mCurrentPage - 1 && i <= mCurrentPage + 1);
+
+            ObjectAnimator a;
+            alpha = PropertyValuesHolder.ofFloat("contentAlpha", finalAlpha);
+            outlineAlpha = PropertyValuesHolder.ofFloat("backgroundAlpha", finalOutlineAlpha);
+            pivotX = PropertyValuesHolder.ofFloat("pivotX", mTmpTransform[0]);
+            pivotY = PropertyValuesHolder.ofFloat("pivotY", mTmpTransform[1]);
+            rotationY = PropertyValuesHolder.ofFloat("rotationY", mTmpTransform[2]);
+
+            if (inVisibleRange) {
+                // for the central pages we animate into a rotated state
+                a = ObjectAnimator.ofPropertyValuesHolder(child, alpha, outlineAlpha,
+                        pivotX, pivotY, rotationY);
+            } else {
+                a = ObjectAnimator.ofPropertyValuesHolder(child, alpha, outlineAlpha);
+                a.setInterpolator(mFastFadeInterpolator);
+            }
+            anims.add(a);
+        }
+
+        int duration = REORDERING_ZOOM_IN_OUT_DURATION;
+        mChildrenTransformsAnimator = new AnimatorSet();
+        mChildrenTransformsAnimator.playTogether(anims);
+
+        mChildrenTransformsAnimator.setDuration(duration);
+        mChildrenTransformsAnimator.start();
+    }
+
+    protected void reorderStarting() {
+        mViewStateManager.fadeOutSecurity(REORDERING_ZOOM_IN_OUT_DURATION);
+        animatePagesToNeutral();
+    }
+
+    protected boolean zoomIn(final Runnable onCompleteRunnable) {
+        animatePagesToCarousel();
+        return super.zoomIn(onCompleteRunnable);
+    }
+
+    @Override
+    protected void onEndReordering() {
+        super.onEndReordering();
+        mViewStateManager.fadeInSecurity(REORDERING_ZOOM_IN_OUT_DURATION);
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetFrame.java b/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetFrame.java
new file mode 100644
index 0000000..81f6221
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetFrame.java
@@ -0,0 +1,527 @@
+/*
+ * 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.keyguard;
+
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.appwidget.AppWidgetHostView;
+import android.appwidget.AppWidgetManager;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.LinearGradient;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.Rect;
+import android.graphics.Shader;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.FrameLayout;
+
+public class KeyguardWidgetFrame extends FrameLayout {
+    private final static PorterDuffXfermode sAddBlendMode =
+            new PorterDuffXfermode(PorterDuff.Mode.ADD);
+
+    static final float OUTLINE_ALPHA_MULTIPLIER = 0.6f;
+    static final int HOVER_OVER_DELETE_DROP_TARGET_OVERLAY_COLOR = 0x99FF0000;
+
+    // Temporarily disable this for the time being until we know why the gfx is messing up
+    static final boolean ENABLE_HOVER_OVER_DELETE_DROP_TARGET_OVERLAY = true;
+
+    private int mGradientColor;
+    private LinearGradient mForegroundGradient;
+    private LinearGradient mLeftToRightGradient;
+    private LinearGradient mRightToLeftGradient;
+    private Paint mGradientPaint = new Paint();
+    boolean mLeftToRight = true;
+
+    private float mOverScrollAmount = 0f;
+    private final Rect mForegroundRect = new Rect();
+    private int mForegroundAlpha = 0;
+    private CheckLongPressHelper mLongPressHelper;
+    private Animator mFrameFade;
+    private boolean mIsSmall = false;
+    private Handler mWorkerHandler;
+
+    private float mBackgroundAlpha;
+    private float mContentAlpha;
+    private float mBackgroundAlphaMultiplier = 1.0f;
+    private Drawable mBackgroundDrawable;
+    private Rect mBackgroundRect = new Rect();
+
+    // These variables are all needed in order to size things properly before we're actually
+    // measured.
+    private int mSmallWidgetHeight;
+    private int mSmallFrameHeight;
+    private boolean mWidgetLockedSmall = false;
+    private int mMaxChallengeTop = -1;
+    private int mFrameStrokeAdjustment;
+    private boolean mPerformAppWidgetSizeUpdateOnBootComplete;
+
+    // This will hold the width value before we've actually been measured
+    private int mFrameHeight;
+
+    private boolean mIsHoveringOverDeleteDropTarget;
+
+    // Multiple callers may try and adjust the alpha of the frame. When a caller shows
+    // the outlines, we give that caller control, and nobody else can fade them out.
+    // This prevents animation conflicts.
+    private Object mBgAlphaController;
+
+    public KeyguardWidgetFrame(Context context) {
+        this(context, null, 0);
+    }
+
+    public KeyguardWidgetFrame(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public KeyguardWidgetFrame(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        mLongPressHelper = new CheckLongPressHelper(this);
+
+        Resources res = context.getResources();
+        // TODO: this padding should really correspond to the padding embedded in the background
+        // drawable (ie. outlines).
+        float density = res.getDisplayMetrics().density;
+        int padding = (int) (res.getDisplayMetrics().density * 8);
+        setPadding(padding, padding, padding, padding);
+
+        mFrameStrokeAdjustment = 2 + (int) (2 * density);
+
+        // This will be overriden on phones based on the current security mode, however on tablets
+        // we need to specify a height.
+        mSmallWidgetHeight =
+                res.getDimensionPixelSize(R.dimen.kg_small_widget_height);
+        mBackgroundDrawable = res.getDrawable(R.drawable.kg_widget_bg_padded);
+        mGradientColor = res.getColor(R.color.kg_widget_pager_gradient);
+        mGradientPaint.setXfermode(sAddBlendMode);
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        cancelLongPress();
+        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateMonitorCallbacks);
+
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallbacks);
+    }
+
+    private KeyguardUpdateMonitorCallback mUpdateMonitorCallbacks =
+            new KeyguardUpdateMonitorCallback() {
+        @Override
+        public void onBootCompleted() {
+            if (mPerformAppWidgetSizeUpdateOnBootComplete) {
+                performAppWidgetSizeCallbacksIfNecessary();
+                mPerformAppWidgetSizeUpdateOnBootComplete = false;
+            }
+        }
+    };
+
+    void setIsHoveringOverDeleteDropTarget(boolean isHovering) {
+        if (ENABLE_HOVER_OVER_DELETE_DROP_TARGET_OVERLAY) {
+            if (mIsHoveringOverDeleteDropTarget != isHovering) {
+                mIsHoveringOverDeleteDropTarget = isHovering;
+                invalidate();
+            }
+        }
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        // Watch for longpress events at this level to make sure
+        // users can always pick up this widget
+        switch (ev.getAction()) {
+            case MotionEvent.ACTION_DOWN:
+                mLongPressHelper.postCheckForLongPress(ev);
+                break;
+            case MotionEvent.ACTION_MOVE:
+                mLongPressHelper.onMove(ev);
+                break;
+            case MotionEvent.ACTION_POINTER_DOWN:
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_CANCEL:
+                mLongPressHelper.cancelLongPress();
+                break;
+        }
+
+        // Otherwise continue letting touch events fall through to children
+        return false;
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        // Watch for longpress events at this level to make sure
+        // users can always pick up this widget
+        switch (ev.getAction()) {
+            case MotionEvent.ACTION_MOVE:
+                mLongPressHelper.onMove(ev);
+                break;
+            case MotionEvent.ACTION_POINTER_DOWN:
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_CANCEL:
+                mLongPressHelper.cancelLongPress();
+                break;
+        }
+
+        // We return true here to ensure that we will get cancel / up signal
+        // even if none of our children have requested touch.
+        return true;
+    }
+
+    @Override
+    public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
+        super.requestDisallowInterceptTouchEvent(disallowIntercept);
+        cancelLongPress();
+    }
+
+    @Override
+    public void cancelLongPress() {
+        super.cancelLongPress();
+        mLongPressHelper.cancelLongPress();
+    }
+
+
+    private void drawGradientOverlay(Canvas c) {
+        mGradientPaint.setShader(mForegroundGradient);
+        mGradientPaint.setAlpha(mForegroundAlpha);
+        c.drawRect(mForegroundRect, mGradientPaint);
+    }
+
+    private void drawHoveringOverDeleteOverlay(Canvas c) {
+        if (mIsHoveringOverDeleteDropTarget) {
+            c.drawColor(HOVER_OVER_DELETE_DROP_TARGET_OVERLAY_COLOR);
+        }
+    }
+
+    protected void drawBg(Canvas canvas) {
+        if (mBackgroundAlpha > 0.0f) {
+            Drawable bg = mBackgroundDrawable;
+
+            bg.setAlpha((int) (mBackgroundAlpha * mBackgroundAlphaMultiplier * 255));
+            bg.setBounds(mBackgroundRect);
+            bg.draw(canvas);
+        }
+    }
+
+    @Override
+    protected void dispatchDraw(Canvas canvas) {
+        if (ENABLE_HOVER_OVER_DELETE_DROP_TARGET_OVERLAY) {
+            canvas.save();
+        }
+        drawBg(canvas);
+        super.dispatchDraw(canvas);
+        drawGradientOverlay(canvas);
+        if (ENABLE_HOVER_OVER_DELETE_DROP_TARGET_OVERLAY) {
+            drawHoveringOverDeleteOverlay(canvas);
+            canvas.restore();
+        }
+    }
+
+    /**
+     * Because this view has fading outlines, it is essential that we enable hardware
+     * layers on the content (child) so that updating the alpha of the outlines doesn't
+     * result in the content layer being recreated.
+     */
+    public void enableHardwareLayersForContent() {
+        View widget = getContent();
+        if (widget != null) {
+            widget.setLayerType(LAYER_TYPE_HARDWARE, null);
+        }
+    }
+
+    /**
+     * Because this view has fading outlines, it is essential that we enable hardware
+     * layers on the content (child) so that updating the alpha of the outlines doesn't
+     * result in the content layer being recreated.
+     */
+    public void disableHardwareLayersForContent() {
+        View widget = getContent();
+        if (widget != null) {
+            widget.setLayerType(LAYER_TYPE_NONE, null);
+        }
+    }
+
+    public void enableHardwareLayers() {
+        setLayerType(LAYER_TYPE_HARDWARE, null);
+    }
+
+    public void disableHardwareLayers() {
+        setLayerType(LAYER_TYPE_NONE, null);
+    }
+
+    public View getContent() {
+        return getChildAt(0);
+    }
+
+    public int getContentAppWidgetId() {
+        View content = getContent();
+        if (content instanceof AppWidgetHostView) {
+            return ((AppWidgetHostView) content).getAppWidgetId();
+        } else if (content instanceof KeyguardStatusView) {
+            return ((KeyguardStatusView) content).getAppWidgetId();
+        } else {
+            return AppWidgetManager.INVALID_APPWIDGET_ID;
+        }
+    }
+
+    public float getBackgroundAlpha() {
+        return mBackgroundAlpha;
+    }
+
+    public void setBackgroundAlphaMultiplier(float multiplier) {
+        if (Float.compare(mBackgroundAlphaMultiplier, multiplier) != 0) {
+            mBackgroundAlphaMultiplier = multiplier;
+            invalidate();
+        }
+    }
+
+    public float getBackgroundAlphaMultiplier() {
+        return mBackgroundAlphaMultiplier;
+    }
+
+    public void setBackgroundAlpha(float alpha) {
+        if (Float.compare(mBackgroundAlpha, alpha) != 0) {
+            mBackgroundAlpha = alpha;
+            invalidate();
+        }
+    }
+
+    public float getContentAlpha() {
+        return mContentAlpha;
+    }
+
+    public void setContentAlpha(float alpha) {
+        mContentAlpha = alpha;
+        View content = getContent();
+        if (content != null) {
+            content.setAlpha(alpha);
+        }
+    }
+
+    /**
+     * Depending on whether the security is up, the widget size needs to change
+     * 
+     * @param height The height of the widget, -1 for full height
+     */
+    private void setWidgetHeight(int height) {
+        boolean needLayout = false;
+        View widget = getContent();
+        if (widget != null) {
+            LayoutParams lp = (LayoutParams) widget.getLayoutParams();
+            if (lp.height != height) {
+                needLayout = true;
+                lp.height = height;
+            }
+        }
+        if (needLayout) {
+            requestLayout();
+        }
+    }
+
+    public void setMaxChallengeTop(int top) {
+        boolean dirty = mMaxChallengeTop != top;
+        mMaxChallengeTop = top;
+        mSmallWidgetHeight = top - getPaddingTop();
+        mSmallFrameHeight = top + getPaddingBottom();
+        if (dirty && mIsSmall) {
+            setWidgetHeight(mSmallWidgetHeight);
+            setFrameHeight(mSmallFrameHeight);
+        } else if (dirty && mWidgetLockedSmall) {
+            setWidgetHeight(mSmallWidgetHeight);
+        }
+    }
+
+    public boolean isSmall() {
+        return mIsSmall;
+    }
+
+    public void adjustFrame(int challengeTop) {
+        int frameHeight = challengeTop + getPaddingBottom();
+        setFrameHeight(frameHeight);
+    }
+
+    public void shrinkWidget(boolean alsoShrinkFrame) {
+        mIsSmall = true;
+        setWidgetHeight(mSmallWidgetHeight);
+
+        if (alsoShrinkFrame) {
+            setFrameHeight(mSmallFrameHeight);
+        }
+    }
+
+    public int getSmallFrameHeight() {
+        return mSmallFrameHeight;
+    }
+
+    public void shrinkWidget() {
+        shrinkWidget(true);
+    }
+
+    public void setWidgetLockedSmall(boolean locked) {
+        if (locked) {
+            setWidgetHeight(mSmallWidgetHeight);
+        }
+        mWidgetLockedSmall = locked;
+    }
+
+    public void resetSize() {
+        mIsSmall = false;
+        if (!mWidgetLockedSmall) {
+            setWidgetHeight(LayoutParams.MATCH_PARENT);
+        }
+        setFrameHeight(getMeasuredHeight());
+    }
+
+    public void setFrameHeight(int height) {
+        mFrameHeight = height;
+        mBackgroundRect.set(0, 0, getMeasuredWidth(), Math.min(mFrameHeight, getMeasuredHeight()));
+        mForegroundRect.set(mFrameStrokeAdjustment, mFrameStrokeAdjustment,getMeasuredWidth() -
+                mFrameStrokeAdjustment, Math.min(getMeasuredHeight(), mFrameHeight) -
+                mFrameStrokeAdjustment);
+        updateGradient();
+        invalidate();
+    }
+
+    public void hideFrame(Object caller) {
+        fadeFrame(caller, false, 0f, KeyguardWidgetPager.CHILDREN_OUTLINE_FADE_OUT_DURATION);
+    }
+
+    public void showFrame(Object caller) {
+        fadeFrame(caller, true, OUTLINE_ALPHA_MULTIPLIER,
+                KeyguardWidgetPager.CHILDREN_OUTLINE_FADE_IN_DURATION);
+    }
+
+    public void fadeFrame(Object caller, boolean takeControl, float alpha, int duration) {
+        if (takeControl) {
+            mBgAlphaController = caller;
+        }
+
+        if (mBgAlphaController != caller && mBgAlphaController != null) {
+            return;
+        }
+
+        if (mFrameFade != null) {
+            mFrameFade.cancel();
+            mFrameFade = null;
+        }
+        PropertyValuesHolder bgAlpha = PropertyValuesHolder.ofFloat("backgroundAlpha", alpha);
+        mFrameFade = ObjectAnimator.ofPropertyValuesHolder(this, bgAlpha);
+        mFrameFade.setDuration(duration);
+        mFrameFade.start();
+    }
+
+    private void updateGradient() {
+        float x0 = mLeftToRight ? 0 : mForegroundRect.width();
+        float x1 = mLeftToRight ? mForegroundRect.width(): 0;
+        mLeftToRightGradient = new LinearGradient(x0, 0f, x1, 0f,
+                mGradientColor, 0, Shader.TileMode.CLAMP);
+        mRightToLeftGradient = new LinearGradient(x1, 0f, x0, 0f,
+                mGradientColor, 0, Shader.TileMode.CLAMP);
+    }
+
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        super.onSizeChanged(w, h, oldw, oldh);
+
+        if (!mIsSmall) {
+            mFrameHeight = h;
+        }
+
+        // mFrameStrokeAdjustment is a cludge to prevent the overlay from drawing outside the
+        // rounded rect background.
+        mForegroundRect.set(mFrameStrokeAdjustment, mFrameStrokeAdjustment,
+                w - mFrameStrokeAdjustment, Math.min(h, mFrameHeight) - mFrameStrokeAdjustment);
+
+        mBackgroundRect.set(0, 0, getMeasuredWidth(), Math.min(h, mFrameHeight));
+        updateGradient();
+        invalidate();
+    }
+
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        performAppWidgetSizeCallbacksIfNecessary();
+    }
+
+    private void performAppWidgetSizeCallbacksIfNecessary() {
+        View content = getContent();
+        if (!(content instanceof AppWidgetHostView)) return;
+
+        if (!KeyguardUpdateMonitor.getInstance(mContext).hasBootCompleted()) {
+            mPerformAppWidgetSizeUpdateOnBootComplete = true;
+            return;
+        }
+
+        // TODO: there's no reason to force the AppWidgetHostView to catch duplicate size calls.
+        // We can do that even more cheaply here. It's not an issue right now since we're in the
+        // system process and hence no binder calls.
+        AppWidgetHostView awhv = (AppWidgetHostView) content;
+        float density = getResources().getDisplayMetrics().density;
+
+        int width = (int) (content.getMeasuredWidth() / density);
+        int height = (int) (content.getMeasuredHeight() / density);
+        awhv.updateAppWidgetSize(null, width, height, width, height, true);
+    }
+
+    void setOverScrollAmount(float r, boolean left) {
+        if (Float.compare(mOverScrollAmount, r) != 0) {
+            mOverScrollAmount = r;
+            mForegroundGradient = left ? mLeftToRightGradient : mRightToLeftGradient;
+            mForegroundAlpha = (int) Math.round((0.5f * r * 255));
+
+            // We bump up the alpha of the outline to hide the fact that the overlay is drawing
+            // over the rounded part of the frame.
+            float bgAlpha = Math.min(OUTLINE_ALPHA_MULTIPLIER + r * (1 - OUTLINE_ALPHA_MULTIPLIER),
+                    1f);
+            setBackgroundAlpha(bgAlpha);
+            invalidate();
+        }
+    }
+
+    public void onActive(boolean isActive) {
+        // hook for subclasses
+    }
+
+    public boolean onUserInteraction(MotionEvent event) {
+        // hook for subclasses
+        return false;
+    }
+
+    public void onBouncerShowing(boolean showing) {
+        // hook for subclasses
+    }
+
+    public void setWorkerHandler(Handler workerHandler) {
+        mWorkerHandler = workerHandler;
+    }
+
+    public Handler getWorkerHandler() {
+        return mWorkerHandler;
+    }
+
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java
new file mode 100644
index 0000000..c566457
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java
@@ -0,0 +1,926 @@
+/*
+ * 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.keyguard;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.TimeInterpolator;
+import android.appwidget.AppWidgetHostView;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.Context;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.text.format.DateFormat;
+import android.util.AttributeSet;
+import android.util.Slog;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.OnLongClickListener;
+import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+import android.view.animation.DecelerateInterpolator;
+import android.widget.FrameLayout;
+import android.widget.TextClock;
+
+import com.android.internal.widget.LockPatternUtils;
+
+import java.util.ArrayList;
+import java.util.TimeZone;
+
+public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwitchListener,
+        OnLongClickListener, ChallengeLayout.OnBouncerStateChangedListener {
+
+    ZInterpolator mZInterpolator = new ZInterpolator(0.5f);
+    private static float CAMERA_DISTANCE = 10000;
+    protected static float OVERSCROLL_MAX_ROTATION = 30;
+    private static final boolean PERFORM_OVERSCROLL_ROTATION = true;
+
+    private static final int FLAG_HAS_LOCAL_HOUR = 0x1;
+    private static final int FLAG_HAS_LOCAL_MINUTE = 0x2;
+
+    protected KeyguardViewStateManager mViewStateManager;
+    private LockPatternUtils mLockPatternUtils;
+
+    // Related to the fading in / out background outlines
+    public static final int CHILDREN_OUTLINE_FADE_OUT_DURATION = 375;
+    public static final int CHILDREN_OUTLINE_FADE_IN_DURATION = 100;
+    protected AnimatorSet mChildrenOutlineFadeAnimation;
+    protected int mScreenCenter;
+    private boolean mHasMeasure = false;
+    boolean showHintsAfterLayout = false;
+
+    private static final long CUSTOM_WIDGET_USER_ACTIVITY_TIMEOUT = 30000;
+    private static final String TAG = "KeyguardWidgetPager";
+    private boolean mCenterSmallWidgetsVertically;
+
+    private int mPage = 0;
+    private Callbacks mCallbacks;
+
+    private int mWidgetToResetAfterFadeOut;
+    protected boolean mShowingInitialHints = false;
+
+    // A temporary handle to the Add-Widget view
+    private View mAddWidgetView;
+    private int mLastWidthMeasureSpec;
+    private int mLastHeightMeasureSpec;
+
+    // Bouncer
+    private int mBouncerZoomInOutDuration = 250;
+    private float BOUNCER_SCALE_FACTOR = 0.67f;
+
+    // Background worker thread: used here for persistence, also made available to widget frames
+    private final HandlerThread mBackgroundWorkerThread;
+    private final Handler mBackgroundWorkerHandler;
+
+    public KeyguardWidgetPager(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public KeyguardWidgetPager(Context context) {
+        this(null, null, 0);
+    }
+
+    public KeyguardWidgetPager(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        if (getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
+            setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+        }
+
+        setPageSwitchListener(this);
+
+        mBackgroundWorkerThread = new HandlerThread("KeyguardWidgetPager Worker");
+        mBackgroundWorkerThread.start();
+        mBackgroundWorkerHandler = new Handler(mBackgroundWorkerThread.getLooper());
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+
+        // Clean up the worker thread
+        mBackgroundWorkerThread.quit();
+    }
+
+    public void setViewStateManager(KeyguardViewStateManager viewStateManager) {
+        mViewStateManager = viewStateManager;
+    }
+
+    public void setLockPatternUtils(LockPatternUtils l) {
+        mLockPatternUtils = l;
+    }
+
+    @Override
+    public void onPageSwitching(View newPage, int newPageIndex) {
+        if (mViewStateManager != null) {
+            mViewStateManager.onPageSwitching(newPage, newPageIndex);
+        }
+    }
+
+    @Override
+    public void onPageSwitched(View newPage, int newPageIndex) {
+        boolean showingClock = false;
+        if (newPage instanceof ViewGroup) {
+            ViewGroup vg = (ViewGroup) newPage;
+            if (vg.getChildAt(0) instanceof KeyguardStatusView) {
+                showingClock = true;
+            }
+        }
+
+        if (newPage != null &&
+                findClockInHierarchy(newPage) == (FLAG_HAS_LOCAL_HOUR | FLAG_HAS_LOCAL_MINUTE)) {
+            showingClock = true;
+        }
+
+        // Disable the status bar clock if we're showing the default status widget
+        if (showingClock) {
+            setSystemUiVisibility(getSystemUiVisibility() | View.STATUS_BAR_DISABLE_CLOCK);
+        } else {
+            setSystemUiVisibility(getSystemUiVisibility() & ~View.STATUS_BAR_DISABLE_CLOCK);
+        }
+
+        // Extend the display timeout if the user switches pages
+        if (mPage != newPageIndex) {
+            int oldPageIndex = mPage;
+            mPage = newPageIndex;
+            userActivity();
+            KeyguardWidgetFrame oldWidgetPage = getWidgetPageAt(oldPageIndex);
+            if (oldWidgetPage != null) {
+                oldWidgetPage.onActive(false);
+            }
+            KeyguardWidgetFrame newWidgetPage = getWidgetPageAt(newPageIndex);
+            if (newWidgetPage != null) {
+                newWidgetPage.onActive(true);
+                newWidgetPage.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+                newWidgetPage.requestAccessibilityFocus();
+            }
+            if (mParent != null && AccessibilityManager.getInstance(mContext).isEnabled()) {
+                AccessibilityEvent event = AccessibilityEvent.obtain(
+                        AccessibilityEvent.TYPE_VIEW_SCROLLED);
+                onInitializeAccessibilityEvent(event);
+                onPopulateAccessibilityEvent(event);
+                mParent.requestSendAccessibilityEvent(this, event);
+            }
+        }
+        if (mViewStateManager != null) {
+            mViewStateManager.onPageSwitched(newPage, newPageIndex);
+        }
+    }
+
+    @Override
+    public void sendAccessibilityEvent(int eventType) {
+        if (eventType != AccessibilityEvent.TYPE_VIEW_SCROLLED || isPageMoving()) {
+            super.sendAccessibilityEvent(eventType);
+        }
+    }
+
+    private void updateWidgetFramesImportantForAccessibility() {
+        final int pageCount = getPageCount();
+        for (int i = 0; i < pageCount; i++) {
+            KeyguardWidgetFrame frame = getWidgetPageAt(i);
+            updateWidgetFrameImportantForAccessibility(frame);
+        }
+    }
+
+    private void updateWidgetFrameImportantForAccessibility(KeyguardWidgetFrame frame) {
+        if (frame.getContentAlpha() <= 0) {
+            frame.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
+        } else {
+            frame.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+        }
+    }
+
+    private void userActivity() {
+        if (mCallbacks != null) {
+            mCallbacks.onUserActivityTimeoutChanged();
+            mCallbacks.userActivity();
+        }
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        return captureUserInteraction(ev) || super.onTouchEvent(ev);
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        return captureUserInteraction(ev) || super.onInterceptTouchEvent(ev);
+    }
+
+    private boolean captureUserInteraction(MotionEvent ev) {
+        KeyguardWidgetFrame currentWidgetPage = getWidgetPageAt(getCurrentPage());
+        return currentWidgetPage != null && currentWidgetPage.onUserInteraction(ev);
+    }
+
+    public void showPagingFeedback() {
+        // Nothing yet.
+    }
+
+    public long getUserActivityTimeout() {
+        View page = getPageAt(mPage);
+        if (page instanceof ViewGroup) {
+            ViewGroup vg = (ViewGroup) page;
+            View view = vg.getChildAt(0);
+            if (!(view instanceof KeyguardStatusView)
+                    && !(view instanceof KeyguardMultiUserSelectorView)) {
+                return CUSTOM_WIDGET_USER_ACTIVITY_TIMEOUT;
+            }
+        }
+        return -1;
+    }
+
+    public void setCallbacks(Callbacks callbacks) {
+        mCallbacks = callbacks;
+    }
+
+    public interface Callbacks {
+        public void userActivity();
+        public void onUserActivityTimeoutChanged();
+        public void onAddView(View v);
+        public void onRemoveView(View v, boolean deletePermanently);
+        public void onRemoveViewAnimationCompleted();
+    }
+
+    public void addWidget(View widget) {
+        addWidget(widget, -1);
+    }
+
+    public void onRemoveView(View v, final boolean deletePermanently) {
+        final int appWidgetId = ((KeyguardWidgetFrame) v).getContentAppWidgetId();
+        if (mCallbacks != null) {
+            mCallbacks.onRemoveView(v, deletePermanently);
+        }
+        mBackgroundWorkerHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                mLockPatternUtils.removeAppWidget(appWidgetId);
+            }
+        });
+    }
+
+    @Override
+    public void onRemoveViewAnimationCompleted() {
+        if (mCallbacks != null) {
+            mCallbacks.onRemoveViewAnimationCompleted();
+        }
+    }
+
+    public void onAddView(View v, final int index) {
+        final int appWidgetId = ((KeyguardWidgetFrame) v).getContentAppWidgetId();
+        final int[] pagesRange = new int[mTempVisiblePagesRange.length];
+        getVisiblePages(pagesRange);
+        boundByReorderablePages(true, pagesRange);
+        if (mCallbacks != null) {
+            mCallbacks.onAddView(v);
+        }
+        // Subtract from the index to take into account pages before the reorderable
+        // pages (e.g. the "add widget" page)
+        mBackgroundWorkerHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                mLockPatternUtils.addAppWidget(appWidgetId, index - pagesRange[0]);
+            }
+        });
+    }
+
+    /*
+     * We wrap widgets in a special frame which handles drawing the over scroll foreground.
+     */
+    public void addWidget(View widget, int pageIndex) {
+        KeyguardWidgetFrame frame;
+        // All views contained herein should be wrapped in a KeyguardWidgetFrame
+        if (!(widget instanceof KeyguardWidgetFrame)) {
+            frame = new KeyguardWidgetFrame(getContext());
+            FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
+                    LayoutParams.MATCH_PARENT);
+            lp.gravity = Gravity.TOP;
+
+            // The framework adds a default padding to AppWidgetHostView. We don't need this padding
+            // for the Keyguard, so we override it to be 0.
+            widget.setPadding(0,  0, 0, 0);
+            frame.addView(widget, lp);
+
+            // We set whether or not this widget supports vertical resizing.
+            if (widget instanceof AppWidgetHostView) {
+                AppWidgetHostView awhv = (AppWidgetHostView) widget;
+                AppWidgetProviderInfo info = awhv.getAppWidgetInfo();
+                if ((info.resizeMode & AppWidgetProviderInfo.RESIZE_VERTICAL) != 0) {
+                    frame.setWidgetLockedSmall(false);
+                } else {
+                    // Lock the widget to be small.
+                    frame.setWidgetLockedSmall(true);
+                    if (mCenterSmallWidgetsVertically) {
+                        lp.gravity = Gravity.CENTER;
+                    }
+                }
+            }
+        } else {
+            frame = (KeyguardWidgetFrame) widget;
+        }
+
+        ViewGroup.LayoutParams pageLp = new ViewGroup.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
+        frame.setOnLongClickListener(this);
+        frame.setWorkerHandler(mBackgroundWorkerHandler);
+
+        if (pageIndex == -1) {
+            addView(frame, pageLp);
+        } else {
+            addView(frame, pageIndex, pageLp);
+        }
+
+        // Update the frame content description.
+        View content = (widget == frame) ?  frame.getContent() : widget;
+        if (content != null) {
+            String contentDescription = mContext.getString(
+                R.string.keyguard_accessibility_widget,
+                content.getContentDescription());
+            frame.setContentDescription(contentDescription);
+        }
+        updateWidgetFrameImportantForAccessibility(frame);
+    }
+
+    /**
+     * Use addWidget() instead.
+     * @deprecated
+     */
+    @Override
+    public void addView(View child, int index) {
+        enforceKeyguardWidgetFrame(child);
+        super.addView(child, index);
+    }
+
+    /**
+     * Use addWidget() instead.
+     * @deprecated
+     */
+    @Override
+    public void addView(View child, int width, int height) {
+        enforceKeyguardWidgetFrame(child);
+        super.addView(child, width, height);
+    }
+
+    /**
+     * Use addWidget() instead.
+     * @deprecated
+     */
+    @Override
+    public void addView(View child, LayoutParams params) {
+        enforceKeyguardWidgetFrame(child);
+        super.addView(child, params);
+    }
+
+    /**
+     * Use addWidget() instead.
+     * @deprecated
+     */
+    @Override
+    public void addView(View child, int index, LayoutParams params) {
+        enforceKeyguardWidgetFrame(child);
+        super.addView(child, index, params);
+    }
+
+    private void enforceKeyguardWidgetFrame(View child) {
+        if (!(child instanceof KeyguardWidgetFrame)) {
+            throw new IllegalArgumentException(
+                    "KeyguardWidgetPager children must be KeyguardWidgetFrames");
+        }
+    }
+
+    public KeyguardWidgetFrame getWidgetPageAt(int index) {
+        // This is always a valid cast as we've guarded the ability to
+        return (KeyguardWidgetFrame) getChildAt(index);
+    }
+
+    protected void onUnhandledTap(MotionEvent ev) {
+        showPagingFeedback();
+    }
+
+    @Override
+    protected void onPageBeginMoving() {
+        if (mViewStateManager != null) {
+            mViewStateManager.onPageBeginMoving();
+        }
+        if (!isReordering(false)) {
+            showOutlinesAndSidePages();
+        }
+        userActivity();
+    }
+
+    @Override
+    protected void onPageEndMoving() {
+        if (mViewStateManager != null) {
+            mViewStateManager.onPageEndMoving();
+        }
+
+        // In the reordering case, the pages will be faded appropriately on completion
+        // of the zoom in animation.
+        if (!isReordering(false)) {
+            hideOutlinesAndSidePages();
+        }
+    }
+
+    protected void enablePageContentLayers() {
+        int children = getChildCount();
+        for (int i = 0; i < children; i++) {
+            getWidgetPageAt(i).enableHardwareLayersForContent();
+        }
+    }
+
+    protected void disablePageContentLayers() {
+        int children = getChildCount();
+        for (int i = 0; i < children; i++) {
+            getWidgetPageAt(i).disableHardwareLayersForContent();
+        }
+    }
+
+    /*
+     * This interpolator emulates the rate at which the perceived scale of an object changes
+     * as its distance from a camera increases. When this interpolator is applied to a scale
+     * animation on a view, it evokes the sense that the object is shrinking due to moving away
+     * from the camera.
+     */
+    static class ZInterpolator implements TimeInterpolator {
+        private float focalLength;
+
+        public ZInterpolator(float foc) {
+            focalLength = foc;
+        }
+
+        public float getInterpolation(float input) {
+            return (1.0f - focalLength / (focalLength + input)) /
+                (1.0f - focalLength / (focalLength + 1.0f));
+        }
+    }
+
+    @Override
+    protected void overScroll(float amount) {
+        acceleratedOverScroll(amount);
+    }
+
+    float backgroundAlphaInterpolator(float r) {
+        return Math.min(1f, r);
+    }
+
+    private void updatePageAlphaValues(int screenCenter) {
+    }
+
+    public float getAlphaForPage(int screenCenter, int index, boolean showSidePages) {
+        if (showSidePages) {
+            return 1f;
+        } else {
+            return index == mCurrentPage ? 1.0f : 0f;
+        }
+    }
+
+    public float getOutlineAlphaForPage(int screenCenter, int index, boolean showSidePages) {
+        if (showSidePages) {
+            return getAlphaForPage(screenCenter, index, showSidePages)
+                    * KeyguardWidgetFrame.OUTLINE_ALPHA_MULTIPLIER;
+        } else {
+            return 0f;
+        }
+    }
+
+    protected boolean isOverScrollChild(int index, float scrollProgress) {
+        boolean isInOverscroll = mOverScrollX < 0 || mOverScrollX > mMaxScrollX;
+        return (isInOverscroll && (index == 0 && scrollProgress < 0 ||
+                index == getChildCount() - 1 && scrollProgress > 0));
+    }
+
+    @Override
+    protected void screenScrolled(int screenCenter) {
+        mScreenCenter = screenCenter;
+        updatePageAlphaValues(screenCenter);
+        for (int i = 0; i < getChildCount(); i++) {
+            KeyguardWidgetFrame v = getWidgetPageAt(i);
+            if (v == mDragView) continue;
+            if (v != null) {
+                float scrollProgress = getScrollProgress(screenCenter, v, i);
+
+                v.setCameraDistance(mDensity * CAMERA_DISTANCE);
+
+                if (isOverScrollChild(i, scrollProgress) && PERFORM_OVERSCROLL_ROTATION) {
+                    float pivotX = v.getMeasuredWidth() / 2;
+                    float pivotY = v.getMeasuredHeight() / 2;
+                    v.setPivotX(pivotX);
+                    v.setPivotY(pivotY);
+                    v.setRotationY(- OVERSCROLL_MAX_ROTATION * scrollProgress);
+                    v.setOverScrollAmount(Math.abs(scrollProgress), scrollProgress < 0);
+                } else {
+                    v.setRotationY(0f);
+                    v.setOverScrollAmount(0, false);
+                }
+
+                float alpha = v.getAlpha();
+                // If the view has 0 alpha, we set it to be invisible so as to prevent
+                // it from accepting touches
+                if (alpha == 0) {
+                    v.setVisibility(INVISIBLE);
+                } else if (v.getVisibility() != VISIBLE) {
+                    v.setVisibility(VISIBLE);
+                }
+            }
+        }
+    }
+
+    public boolean isWidgetPage(int pageIndex) {
+        if (pageIndex < 0 || pageIndex >= getChildCount()) {
+            return false;
+        }
+        View v = getChildAt(pageIndex);
+        if (v != null && v instanceof KeyguardWidgetFrame) {
+            KeyguardWidgetFrame kwf = (KeyguardWidgetFrame) v;
+            return kwf.getContentAppWidgetId() != AppWidgetManager.INVALID_APPWIDGET_ID;
+        }
+        return false;
+    }
+
+    /**
+     * Returns the bounded set of pages that are re-orderable.  The range is fully inclusive.
+     */
+    @Override
+    void boundByReorderablePages(boolean isReordering, int[] range) {
+        if (isReordering) {
+            // Remove non-widget pages from the range
+            while (range[1] >= range[0] && !isWidgetPage(range[1])) {
+                range[1]--;
+            }
+            while (range[0] <= range[1] && !isWidgetPage(range[0])) {
+                range[0]++;
+            }
+        }
+    }
+
+    protected void reorderStarting() {
+        showOutlinesAndSidePages();
+    }
+
+    @Override
+    protected void onStartReordering() {
+        super.onStartReordering();
+        enablePageContentLayers();
+        reorderStarting();
+    }
+
+    @Override
+    protected void onEndReordering() {
+        super.onEndReordering();
+        hideOutlinesAndSidePages();
+    }
+
+    void showOutlinesAndSidePages() {
+        animateOutlinesAndSidePages(true);
+    }
+
+    void hideOutlinesAndSidePages() {
+        animateOutlinesAndSidePages(false);
+    }
+
+    void updateChildrenContentAlpha(float sidePageAlpha) {
+        int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            KeyguardWidgetFrame child = getWidgetPageAt(i);
+            if (i != mCurrentPage) {
+                child.setBackgroundAlpha(sidePageAlpha);
+                child.setContentAlpha(0f);
+            } else {
+                child.setBackgroundAlpha(0f);
+                child.setContentAlpha(1f);
+            }
+        }
+    }
+
+    public void showInitialPageHints() {
+        mShowingInitialHints = true;
+        updateChildrenContentAlpha(KeyguardWidgetFrame.OUTLINE_ALPHA_MULTIPLIER);
+    }
+
+    @Override
+    void setCurrentPage(int currentPage) {
+        super.setCurrentPage(currentPage);
+        updateChildrenContentAlpha(0.0f);
+        updateWidgetFramesImportantForAccessibility();
+    }
+
+    @Override
+    public void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        mHasMeasure = false;
+    }
+
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        mLastWidthMeasureSpec = widthMeasureSpec;
+        mLastHeightMeasureSpec = heightMeasureSpec;
+
+        int maxChallengeTop = -1;
+        View parent = (View) getParent();
+        boolean challengeShowing = false;
+        // Widget pages need to know where the top of the sliding challenge is so that they
+        // now how big the widget should be when the challenge is up. We compute it here and
+        // then propagate it to each of our children.
+        if (parent.getParent() instanceof SlidingChallengeLayout) {
+            SlidingChallengeLayout scl = (SlidingChallengeLayout) parent.getParent();
+            int top = scl.getMaxChallengeTop();
+
+            // This is a bit evil, but we need to map a coordinate relative to the SCL into a
+            // coordinate relative to our children, hence we subtract the top padding.s
+            maxChallengeTop = top - getPaddingTop();
+            challengeShowing = scl.isChallengeShowing();
+
+            int count = getChildCount();
+            for (int i = 0; i < count; i++) {
+                KeyguardWidgetFrame frame = getWidgetPageAt(i);
+                frame.setMaxChallengeTop(maxChallengeTop);
+                // On the very first measure pass, if the challenge is showing, we need to make sure
+                // that the widget on the current page is small.
+                if (challengeShowing && i == mCurrentPage && !mHasMeasure) {
+                    frame.shrinkWidget();
+                }
+            }
+        }
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        mHasMeasure = true;
+    }
+
+    void animateOutlinesAndSidePages(final boolean show) {
+        animateOutlinesAndSidePages(show, -1);
+    }
+
+    public void setWidgetToResetOnPageFadeOut(int widget) {
+        mWidgetToResetAfterFadeOut = widget;
+    }
+
+    public int getWidgetToResetOnPageFadeOut() {
+        return mWidgetToResetAfterFadeOut;
+    }
+
+    void animateOutlinesAndSidePages(final boolean show, int duration) {
+        if (mChildrenOutlineFadeAnimation != null) {
+            mChildrenOutlineFadeAnimation.cancel();
+            mChildrenOutlineFadeAnimation = null;
+        }
+        int count = getChildCount();
+        PropertyValuesHolder alpha;
+        ArrayList<Animator> anims = new ArrayList<Animator>();
+
+        if (duration == -1) {
+            duration = show ? CHILDREN_OUTLINE_FADE_IN_DURATION :
+                CHILDREN_OUTLINE_FADE_OUT_DURATION;
+        }
+
+        int curPage = getNextPage();
+        for (int i = 0; i < count; i++) {
+            float finalContentAlpha;
+            if (show) {
+                finalContentAlpha = getAlphaForPage(mScreenCenter, i, true);
+            } else if (!show && i == curPage) {
+                finalContentAlpha = 1f;
+            } else {
+                finalContentAlpha = 0f;
+            }
+            KeyguardWidgetFrame child = getWidgetPageAt(i);
+
+            alpha = PropertyValuesHolder.ofFloat("contentAlpha", finalContentAlpha);
+            ObjectAnimator a = ObjectAnimator.ofPropertyValuesHolder(child, alpha);
+            anims.add(a);
+
+            float finalOutlineAlpha = show ? getOutlineAlphaForPage(mScreenCenter, i, true) : 0f;
+            child.fadeFrame(this, show, finalOutlineAlpha, duration);
+        }
+
+        mChildrenOutlineFadeAnimation = new AnimatorSet();
+        mChildrenOutlineFadeAnimation.playTogether(anims);
+
+        mChildrenOutlineFadeAnimation.setDuration(duration);
+        mChildrenOutlineFadeAnimation.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationStart(Animator animation) {
+                if (show) {
+                    enablePageContentLayers();
+                }
+            }
+
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                if (!show) {
+                    disablePageContentLayers();
+                    KeyguardWidgetFrame frame = getWidgetPageAt(mWidgetToResetAfterFadeOut);
+                    if (frame != null && !(frame == getWidgetPageAt(mCurrentPage) &&
+                            mViewStateManager.isChallengeOverlapping())) {
+                        frame.resetSize();
+                    }
+                    mWidgetToResetAfterFadeOut = -1;
+                    mShowingInitialHints = false;
+                }
+                updateWidgetFramesImportantForAccessibility();
+            }
+        });
+        mChildrenOutlineFadeAnimation.start();
+    }
+
+    @Override
+    public boolean onLongClick(View v) {
+        // Disallow long pressing to reorder if the challenge is showing
+        boolean isChallengeOverlapping = mViewStateManager.isChallengeShowing() &&
+                mViewStateManager.isChallengeOverlapping();
+        if (!isChallengeOverlapping && startReordering()) {
+            return true;
+        }
+        return false;
+    }
+
+    public void removeWidget(View view) {
+        if (view instanceof KeyguardWidgetFrame) {
+            removeView(view);
+        } else {
+            // Assume view was wrapped by a KeyguardWidgetFrame in KeyguardWidgetPager#addWidget().
+            // This supports legacy hard-coded "widgets" like KeyguardTransportControlView.
+            int pos = getWidgetPageIndex(view);
+            if (pos != -1) {
+                KeyguardWidgetFrame frame = (KeyguardWidgetFrame) getChildAt(pos);
+                frame.removeView(view);
+                removeView(frame);
+            } else {
+                Slog.w(TAG, "removeWidget() can't find:" + view);
+            }
+        }
+    }
+
+    public int getWidgetPageIndex(View view) {
+        if (view instanceof KeyguardWidgetFrame) {
+            return indexOfChild(view);
+        } else {
+            // View was wrapped by a KeyguardWidgetFrame by KeyguardWidgetPager#addWidget()
+            return indexOfChild((KeyguardWidgetFrame)view.getParent());
+        }
+    }
+
+    @Override
+    protected void setPageHoveringOverDeleteDropTarget(int viewIndex, boolean isHovering) {
+        KeyguardWidgetFrame child = getWidgetPageAt(viewIndex);
+        child.setIsHoveringOverDeleteDropTarget(isHovering);
+    }
+
+    // ChallengeLayout.OnBouncerStateChangedListener
+    @Override
+    public void onBouncerStateChanged(boolean bouncerActive) {
+        if (bouncerActive) {
+            zoomOutToBouncer();
+        } else {
+            zoomInFromBouncer();
+        }
+    }
+
+    void setBouncerAnimationDuration(int duration) {
+        mBouncerZoomInOutDuration = duration;
+    }
+
+    // Zoom in after the bouncer is dismissed
+    void zoomInFromBouncer() {
+        if (mZoomInOutAnim != null && mZoomInOutAnim.isRunning()) {
+            mZoomInOutAnim.cancel();
+        }
+        final View currentPage = getPageAt(getCurrentPage());
+        if (currentPage.getScaleX() < 1f || currentPage.getScaleY() < 1f) {
+            mZoomInOutAnim = new AnimatorSet();
+            mZoomInOutAnim.playTogether(
+                    ObjectAnimator.ofFloat(currentPage, "scaleX", 1f),
+                    ObjectAnimator.ofFloat(currentPage , "scaleY", 1f));
+            mZoomInOutAnim.setDuration(mBouncerZoomInOutDuration);
+            mZoomInOutAnim.setInterpolator(new DecelerateInterpolator(1.5f));
+            mZoomInOutAnim.start();
+        }
+        if (currentPage instanceof KeyguardWidgetFrame) {
+            ((KeyguardWidgetFrame)currentPage).onBouncerShowing(false);
+        }
+    }
+
+    // Zoom out after the bouncer is initiated
+    void zoomOutToBouncer() {
+        if (mZoomInOutAnim != null && mZoomInOutAnim.isRunning()) {
+            mZoomInOutAnim.cancel();
+        }
+        int curPage = getCurrentPage();
+        View currentPage = getPageAt(curPage);
+        if (shouldSetTopAlignedPivotForWidget(curPage)) {
+            currentPage.setPivotY(0);
+            // Note: we are working around the issue that setting the x-pivot to the same value as it
+            //       was does not actually work.
+            currentPage.setPivotX(0);
+            currentPage.setPivotX(currentPage.getMeasuredWidth() / 2);
+        }
+        if (!(currentPage.getScaleX() < 1f || currentPage.getScaleY() < 1f)) {
+            mZoomInOutAnim = new AnimatorSet();
+            mZoomInOutAnim.playTogether(
+                    ObjectAnimator.ofFloat(currentPage, "scaleX", BOUNCER_SCALE_FACTOR),
+                    ObjectAnimator.ofFloat(currentPage, "scaleY", BOUNCER_SCALE_FACTOR));
+            mZoomInOutAnim.setDuration(mBouncerZoomInOutDuration);
+            mZoomInOutAnim.setInterpolator(new DecelerateInterpolator(1.5f));
+            mZoomInOutAnim.start();
+        }
+        if (currentPage instanceof KeyguardWidgetFrame) {
+            ((KeyguardWidgetFrame)currentPage).onBouncerShowing(true);
+        }
+    }
+
+    void setAddWidgetEnabled(boolean enabled) {
+        if (mAddWidgetView != null && enabled) {
+            addView(mAddWidgetView, 0);
+            // We need to force measure the PagedView so that the calls to update the scroll
+            // position below work
+            measure(mLastWidthMeasureSpec, mLastHeightMeasureSpec);
+            // Bump up the current page to account for the addition of the new page
+            setCurrentPage(mCurrentPage + 1);
+            mAddWidgetView = null;
+        } else if (mAddWidgetView == null && !enabled) {
+            View addWidget = findViewById(R.id.keyguard_add_widget);
+            if (addWidget != null) {
+                mAddWidgetView = addWidget;
+                removeView(addWidget);
+            }
+        }
+    }
+
+    boolean isAddPage(int pageIndex) {
+        View v = getChildAt(pageIndex);
+        return v != null && v.getId() == R.id.keyguard_add_widget;
+    }
+
+    boolean isCameraPage(int pageIndex) {
+        View v = getChildAt(pageIndex);
+        return v != null && v instanceof CameraWidgetFrame;
+    }
+
+    @Override
+    protected boolean shouldSetTopAlignedPivotForWidget(int childIndex) {
+        return !isCameraPage(childIndex) && super.shouldSetTopAlignedPivotForWidget(childIndex);
+    }
+
+    /**
+     * Search given {@link View} hierarchy for {@link TextClock} instances that
+     * show various time components. Returns combination of
+     * {@link #FLAG_HAS_LOCAL_HOUR} and {@link #FLAG_HAS_LOCAL_MINUTE}.
+     */
+    private static int findClockInHierarchy(View view) {
+        if (view instanceof TextClock) {
+            return getClockFlags((TextClock) view);
+        } else if (view instanceof ViewGroup) {
+            int flags = 0;
+            final ViewGroup group = (ViewGroup) view;
+            final int size = group.getChildCount();
+            for (int i = 0; i < size; i++) {
+                flags |= findClockInHierarchy(group.getChildAt(i));
+            }
+            return flags;
+        } else {
+            return 0;
+        }
+    }
+
+    /**
+     * Return combination of {@link #FLAG_HAS_LOCAL_HOUR} and
+     * {@link #FLAG_HAS_LOCAL_MINUTE} describing the time represented described
+     * by the given {@link TextClock}.
+     */
+    private static int getClockFlags(TextClock clock) {
+        int flags = 0;
+
+        final String timeZone = clock.getTimeZone();
+        if (timeZone != null && !TimeZone.getDefault().equals(TimeZone.getTimeZone(timeZone))) {
+            // Ignore clocks showing another timezone
+            return 0;
+        }
+
+        final CharSequence format = clock.getFormat();
+        final char hour = clock.is24HourModeEnabled() ? DateFormat.HOUR_OF_DAY
+                : DateFormat.HOUR;
+
+        if (DateFormat.hasDesignator(format, hour)) {
+            flags |= FLAG_HAS_LOCAL_HOUR;
+        }
+        if (DateFormat.hasDesignator(format, DateFormat.MINUTE)) {
+            flags |= FLAG_HAS_LOCAL_MINUTE;
+        }
+
+        return flags;
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/LiftToActivateListener.java b/packages/Keyguard/src/com/android/keyguard/LiftToActivateListener.java
new file mode 100644
index 0000000..e59602b
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/LiftToActivateListener.java
@@ -0,0 +1,71 @@
+/*
+ * 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.keyguard;
+
+import android.content.Context;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.accessibility.AccessibilityManager;
+
+/**
+ * Hover listener that implements lift-to-activate interaction for
+ * accessibility. May be added to multiple views.
+ */
+class LiftToActivateListener implements View.OnHoverListener {
+    /** Manager used to query accessibility enabled state. */
+    private final AccessibilityManager mAccessibilityManager;
+
+    private boolean mCachedClickableState;
+
+    public LiftToActivateListener(Context context) {
+        mAccessibilityManager = (AccessibilityManager) context.getSystemService(
+                Context.ACCESSIBILITY_SERVICE);
+    }
+
+    @Override
+    public boolean onHover(View v, MotionEvent event) {
+        // When touch exploration is turned on, lifting a finger while
+        // inside the view bounds should perform a click action.
+        if (mAccessibilityManager.isEnabled()
+                && mAccessibilityManager.isTouchExplorationEnabled()) {
+            switch (event.getActionMasked()) {
+                case MotionEvent.ACTION_HOVER_ENTER:
+                    // Lift-to-type temporarily disables double-tap
+                    // activation by setting the view as not clickable.
+                    mCachedClickableState = v.isClickable();
+                    v.setClickable(false);
+                    break;
+                case MotionEvent.ACTION_HOVER_EXIT:
+                    final int x = (int) event.getX();
+                    final int y = (int) event.getY();
+                    if ((x > v.getPaddingLeft()) && (y > v.getPaddingTop())
+                            && (x < v.getWidth() - v.getPaddingRight())
+                            && (y < v.getHeight() - v.getPaddingBottom())) {
+                        v.performClick();
+                    }
+                    v.setClickable(mCachedClickableState);
+                    break;
+            }
+        }
+
+        // Pass the event to View.onHoverEvent() to handle accessibility.
+        v.onHoverEvent(event);
+
+        // Consume the event so it doesn't fall through to other views.
+        return true;
+    }
+}
\ No newline at end of file
diff --git a/packages/Keyguard/src/com/android/keyguard/MultiPaneChallengeLayout.java b/packages/Keyguard/src/com/android/keyguard/MultiPaneChallengeLayout.java
new file mode 100644
index 0000000..8fd39c0
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/MultiPaneChallengeLayout.java
@@ -0,0 +1,564 @@
+/*
+ * 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.keyguard;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+
+public class MultiPaneChallengeLayout extends ViewGroup implements ChallengeLayout {
+    private static final String TAG = "MultiPaneChallengeLayout";
+
+    final int mOrientation;
+    private boolean mIsBouncing;
+
+    public static final int HORIZONTAL = LinearLayout.HORIZONTAL;
+    public static final int VERTICAL = LinearLayout.VERTICAL;
+    public static final int ANIMATE_BOUNCE_DURATION = 350;
+
+    private KeyguardSecurityContainer mChallengeView;
+    private View mUserSwitcherView;
+    private View mScrimView;
+    private OnBouncerStateChangedListener mBouncerListener;
+
+    private final Rect mTempRect = new Rect();
+    private final Rect mZeroPadding = new Rect();
+
+    private final DisplayMetrics mDisplayMetrics;
+
+    private final OnClickListener mScrimClickListener = new OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            hideBouncer();
+        }
+    };
+
+    public MultiPaneChallengeLayout(Context context) {
+        this(context, null);
+    }
+
+    public MultiPaneChallengeLayout(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public MultiPaneChallengeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                R.styleable.MultiPaneChallengeLayout, defStyleAttr, 0);
+        mOrientation = a.getInt(R.styleable.MultiPaneChallengeLayout_android_orientation,
+                HORIZONTAL);
+        a.recycle();
+
+        final Resources res = getResources();
+        mDisplayMetrics = res.getDisplayMetrics();
+
+        setSystemUiVisibility(SYSTEM_UI_FLAG_LAYOUT_STABLE);
+    }
+
+    @Override
+    public boolean isChallengeShowing() {
+        return true;
+    }
+
+    @Override
+    public boolean isChallengeOverlapping() {
+        return false;
+    }
+
+    @Override
+    public void showChallenge(boolean b) {
+    }
+
+    @Override
+    public int getBouncerAnimationDuration() {
+        return ANIMATE_BOUNCE_DURATION;
+    }
+
+    @Override
+    public void showBouncer() {
+        if (mIsBouncing) return;
+        mIsBouncing = true;
+        if (mScrimView != null) {
+            if (mChallengeView != null) {
+                mChallengeView.showBouncer(ANIMATE_BOUNCE_DURATION);
+            }
+
+            Animator anim = ObjectAnimator.ofFloat(mScrimView, "alpha", 1f);
+            anim.setDuration(ANIMATE_BOUNCE_DURATION);
+            anim.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationStart(Animator animation) {
+                    mScrimView.setVisibility(VISIBLE);
+                }
+            });
+            anim.start();
+        }
+        if (mBouncerListener != null) {
+            mBouncerListener.onBouncerStateChanged(true);
+        }
+    }
+
+    @Override
+    public void hideBouncer() {
+        if (!mIsBouncing) return;
+        mIsBouncing = false;
+        if (mScrimView != null) {
+            if (mChallengeView != null) {
+                mChallengeView.hideBouncer(ANIMATE_BOUNCE_DURATION);
+            }
+
+            Animator anim = ObjectAnimator.ofFloat(mScrimView, "alpha", 0f);
+            anim.setDuration(ANIMATE_BOUNCE_DURATION);
+            anim.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    mScrimView.setVisibility(INVISIBLE);
+                }
+            });
+            anim.start();
+        }
+        if (mBouncerListener != null) {
+            mBouncerListener.onBouncerStateChanged(false);
+        }
+    }
+
+    @Override
+    public boolean isBouncing() {
+        return mIsBouncing;
+    }
+
+    @Override
+    public void setOnBouncerStateChangedListener(OnBouncerStateChangedListener listener) {
+        mBouncerListener = listener;
+    }
+
+    @Override
+    public void requestChildFocus(View child, View focused) {
+        if (mIsBouncing && child != mChallengeView) {
+            // Clear out of the bouncer if the user tries to move focus outside of
+            // the security challenge view.
+            hideBouncer();
+        }
+        super.requestChildFocus(child, focused);
+    }
+
+    void setScrimView(View scrim) {
+        if (mScrimView != null) {
+            mScrimView.setOnClickListener(null);
+        }
+        mScrimView = scrim;
+        mScrimView.setAlpha(mIsBouncing ? 1.0f : 0.0f);
+        mScrimView.setVisibility(mIsBouncing ? VISIBLE : INVISIBLE);
+        mScrimView.setFocusable(true);
+        mScrimView.setOnClickListener(mScrimClickListener);
+    }
+
+    private int getVirtualHeight(LayoutParams lp, int height, int heightUsed) {
+        int virtualHeight = height;
+        final View root = getRootView();
+        if (root != null) {
+            // This calculation is super dodgy and relies on several assumptions.
+            // Specifically that the root of the window will be padded in for insets
+            // and that the window is LAYOUT_IN_SCREEN.
+            virtualHeight = mDisplayMetrics.heightPixels - root.getPaddingTop();
+        }
+        if (lp.childType == LayoutParams.CHILD_TYPE_WIDGET ||
+                lp.childType == LayoutParams.CHILD_TYPE_USER_SWITCHER) {
+            // Always measure the widget pager/user switcher as if there were no IME insets
+            // on the window. We want to avoid resizing widgets when possible as it can
+            // be ugly/expensive. This lets us simply clip them instead.
+            return virtualHeight - heightUsed;
+        } else if (lp.childType == LayoutParams.CHILD_TYPE_PAGE_DELETE_DROP_TARGET) {
+            return height;
+        }
+        return Math.min(virtualHeight - heightUsed, height);
+    }
+
+    @Override
+    protected void onMeasure(final int widthSpec, final int heightSpec) {
+        if (MeasureSpec.getMode(widthSpec) != MeasureSpec.EXACTLY ||
+                MeasureSpec.getMode(heightSpec) != MeasureSpec.EXACTLY) {
+            throw new IllegalArgumentException(
+                    "MultiPaneChallengeLayout must be measured with an exact size");
+        }
+
+        final int width = MeasureSpec.getSize(widthSpec);
+        final int height = MeasureSpec.getSize(heightSpec);
+        setMeasuredDimension(width, height);
+
+        int widthUsed = 0;
+        int heightUsed = 0;
+
+        // First pass. Find the challenge view and measure the user switcher,
+        // which consumes space in the layout.
+        mChallengeView = null;
+        mUserSwitcherView = null;
+        final int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            final View child = getChildAt(i);
+            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+            if (lp.childType == LayoutParams.CHILD_TYPE_CHALLENGE) {
+                if (mChallengeView != null) {
+                    throw new IllegalStateException(
+                            "There may only be one child of type challenge");
+                }
+                if (!(child instanceof KeyguardSecurityContainer)) {
+                    throw new IllegalArgumentException(
+                            "Challenge must be a KeyguardSecurityContainer");
+                }
+                mChallengeView = (KeyguardSecurityContainer) child;
+            } else if (lp.childType == LayoutParams.CHILD_TYPE_USER_SWITCHER) {
+                if (mUserSwitcherView != null) {
+                    throw new IllegalStateException(
+                            "There may only be one child of type userSwitcher");
+                }
+                mUserSwitcherView = child;
+
+                if (child.getVisibility() == GONE) continue;
+
+                int adjustedWidthSpec = widthSpec;
+                int adjustedHeightSpec = heightSpec;
+                if (lp.maxWidth >= 0) {
+                    adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
+                            Math.min(lp.maxWidth, width), MeasureSpec.EXACTLY);
+                }
+                if (lp.maxHeight >= 0) {
+                    adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
+                            Math.min(lp.maxHeight, height), MeasureSpec.EXACTLY);
+                }
+                // measureChildWithMargins will resolve layout direction for the LayoutParams
+                measureChildWithMargins(child, adjustedWidthSpec, 0, adjustedHeightSpec, 0);
+
+                // Only subtract out space from one dimension. Favor vertical.
+                // Offset by 1.5x to add some balance along the other edge.
+                if (Gravity.isVertical(lp.gravity)) {
+                    heightUsed += child.getMeasuredHeight() * 1.5f;
+                } else if (Gravity.isHorizontal(lp.gravity)) {
+                    widthUsed += child.getMeasuredWidth() * 1.5f;
+                }
+            } else if (lp.childType == LayoutParams.CHILD_TYPE_SCRIM) {
+                setScrimView(child);
+                child.measure(widthSpec, heightSpec);
+            }
+        }
+
+        // Second pass. Measure everything that's left.
+        for (int i = 0; i < count; i++) {
+            final View child = getChildAt(i);
+            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+            if (lp.childType == LayoutParams.CHILD_TYPE_USER_SWITCHER ||
+                    lp.childType == LayoutParams.CHILD_TYPE_SCRIM ||
+                    child.getVisibility() == GONE) {
+                // Don't need to measure GONE children, and the user switcher was already measured.
+                continue;
+            }
+
+            final int virtualHeight = getVirtualHeight(lp, height, heightUsed);
+
+            int adjustedWidthSpec;
+            int adjustedHeightSpec;
+            if (lp.centerWithinArea > 0) {
+                if (mOrientation == HORIZONTAL) {
+                    adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
+                            (int) ((width - widthUsed) * lp.centerWithinArea + 0.5f),
+                            MeasureSpec.EXACTLY);
+                    adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
+                            virtualHeight, MeasureSpec.EXACTLY);
+                } else {
+                    adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
+                            width - widthUsed, MeasureSpec.EXACTLY);
+                    adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
+                            (int) (virtualHeight * lp.centerWithinArea + 0.5f),
+                            MeasureSpec.EXACTLY);
+                }
+            } else {
+                adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
+                        width - widthUsed, MeasureSpec.EXACTLY);
+                adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
+                        virtualHeight, MeasureSpec.EXACTLY);
+            }
+            if (lp.maxWidth >= 0) {
+                adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
+                        Math.min(lp.maxWidth, MeasureSpec.getSize(adjustedWidthSpec)),
+                        MeasureSpec.EXACTLY);
+            }
+            if (lp.maxHeight >= 0) {
+                adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
+                        Math.min(lp.maxHeight, MeasureSpec.getSize(adjustedHeightSpec)),
+                        MeasureSpec.EXACTLY);
+            }
+
+            measureChildWithMargins(child, adjustedWidthSpec, 0, adjustedHeightSpec, 0);
+        }
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        final Rect padding = mTempRect;
+        padding.left = getPaddingLeft();
+        padding.top = getPaddingTop();
+        padding.right = getPaddingRight();
+        padding.bottom = getPaddingBottom();
+        final int width = r - l;
+        final int height = b - t;
+
+        // Reserve extra space in layout for the user switcher by modifying
+        // local padding during this layout pass
+        if (mUserSwitcherView != null && mUserSwitcherView.getVisibility() != GONE) {
+            layoutWithGravity(width, height, mUserSwitcherView, padding, true);
+        }
+
+        final int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            final View child = getChildAt(i);
+            LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+            // We did the user switcher above if we have one.
+            if (child == mUserSwitcherView || child.getVisibility() == GONE) continue;
+
+            if (child == mScrimView) {
+                child.layout(0, 0, width, height);
+                continue;
+            } else if (lp.childType == LayoutParams.CHILD_TYPE_PAGE_DELETE_DROP_TARGET) {
+                layoutWithGravity(width, height, child, mZeroPadding, false);
+                continue;
+            }
+
+            layoutWithGravity(width, height, child, padding, false);
+        }
+    }
+
+    private void layoutWithGravity(int width, int height, View child, Rect padding,
+            boolean adjustPadding) {
+        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+        final int heightUsed = padding.top + padding.bottom - getPaddingTop() - getPaddingBottom();
+        height = getVirtualHeight(lp, height, heightUsed);
+
+        final int gravity = Gravity.getAbsoluteGravity(lp.gravity, getLayoutDirection());
+
+        final boolean fixedLayoutSize = lp.centerWithinArea > 0;
+        final boolean fixedLayoutHorizontal = fixedLayoutSize && mOrientation == HORIZONTAL;
+        final boolean fixedLayoutVertical = fixedLayoutSize && mOrientation == VERTICAL;
+
+        final int adjustedWidth;
+        final int adjustedHeight;
+        if (fixedLayoutHorizontal) {
+            final int paddedWidth = width - padding.left - padding.right;
+            adjustedWidth = (int) (paddedWidth * lp.centerWithinArea + 0.5f);
+            adjustedHeight = height;
+        } else if (fixedLayoutVertical) {
+            final int paddedHeight = height - getPaddingTop() - getPaddingBottom();
+            adjustedWidth = width;
+            adjustedHeight = (int) (paddedHeight * lp.centerWithinArea + 0.5f);
+        } else {
+            adjustedWidth = width;
+            adjustedHeight = height;
+        }
+
+        final boolean isVertical = Gravity.isVertical(gravity);
+        final boolean isHorizontal = Gravity.isHorizontal(gravity);
+        final int childWidth = child.getMeasuredWidth();
+        final int childHeight = child.getMeasuredHeight();
+
+        int left = padding.left;
+        int top = padding.top;
+        int right = left + childWidth;
+        int bottom = top + childHeight;
+        switch (gravity & Gravity.VERTICAL_GRAVITY_MASK) {
+            case Gravity.TOP:
+                top = fixedLayoutVertical ?
+                        padding.top + (adjustedHeight - childHeight) / 2 : padding.top;
+                bottom = top + childHeight;
+                if (adjustPadding && isVertical) {
+                    padding.top = bottom;
+                    padding.bottom += childHeight / 2;
+                }
+                break;
+            case Gravity.BOTTOM:
+                bottom = fixedLayoutVertical
+                        ? padding.top + height - (adjustedHeight - childHeight) / 2
+                        : padding.top + height;
+                top = bottom - childHeight;
+                if (adjustPadding && isVertical) {
+                    padding.bottom = height - top;
+                    padding.top += childHeight / 2;
+                }
+                break;
+            case Gravity.CENTER_VERTICAL:
+                top = padding.top + (height - childHeight) / 2;
+                bottom = top + childHeight;
+                break;
+        }
+        switch (gravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
+            case Gravity.LEFT:
+                left = fixedLayoutHorizontal ?
+                        padding.left + (adjustedWidth - childWidth) / 2 : padding.left;
+                right = left + childWidth;
+                if (adjustPadding && isHorizontal && !isVertical) {
+                    padding.left = right;
+                    padding.right += childWidth / 2;
+                }
+                break;
+            case Gravity.RIGHT:
+                right = fixedLayoutHorizontal
+                        ? width - padding.right - (adjustedWidth - childWidth) / 2
+                        : width - padding.right;
+                left = right - childWidth;
+                if (adjustPadding && isHorizontal && !isVertical) {
+                    padding.right = width - left;
+                    padding.left += childWidth / 2;
+                }
+                break;
+            case Gravity.CENTER_HORIZONTAL:
+                final int paddedWidth = width - padding.left - padding.right;
+                left = (paddedWidth - childWidth) / 2;
+                right = left + childWidth;
+                break;
+        }
+        child.layout(left, top, right, bottom);
+    }
+
+    @Override
+    public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
+        return new LayoutParams(getContext(), attrs, this);
+    }
+
+    @Override
+    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
+        return p instanceof LayoutParams ? new LayoutParams((LayoutParams) p) :
+                p instanceof MarginLayoutParams ? new LayoutParams((MarginLayoutParams) p) :
+                new LayoutParams(p);
+    }
+
+    @Override
+    protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
+        return new LayoutParams();
+    }
+
+    @Override
+    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
+        return p instanceof LayoutParams;
+    }
+
+    public static class LayoutParams extends MarginLayoutParams {
+
+        public float centerWithinArea = 0;
+
+        public int childType = 0;
+
+        public static final int CHILD_TYPE_NONE = 0;
+        public static final int CHILD_TYPE_WIDGET = 1;
+        public static final int CHILD_TYPE_CHALLENGE = 2;
+        public static final int CHILD_TYPE_USER_SWITCHER = 3;
+        public static final int CHILD_TYPE_SCRIM = 4;
+        public static final int CHILD_TYPE_PAGE_DELETE_DROP_TARGET = 7;
+
+        public int gravity = Gravity.NO_GRAVITY;
+
+        public int maxWidth = -1;
+        public int maxHeight = -1;
+
+        public LayoutParams() {
+            this(WRAP_CONTENT, WRAP_CONTENT);
+        }
+
+        LayoutParams(Context c, AttributeSet attrs, MultiPaneChallengeLayout parent) {
+            super(c, attrs);
+
+            final TypedArray a = c.obtainStyledAttributes(attrs,
+                    R.styleable.MultiPaneChallengeLayout_Layout);
+
+            centerWithinArea = a.getFloat(
+                    R.styleable.MultiPaneChallengeLayout_Layout_layout_centerWithinArea, 0);
+            childType = a.getInt(R.styleable.MultiPaneChallengeLayout_Layout_layout_childType,
+                    CHILD_TYPE_NONE);
+            gravity = a.getInt(R.styleable.MultiPaneChallengeLayout_Layout_layout_gravity,
+                    Gravity.NO_GRAVITY);
+            maxWidth = a.getDimensionPixelSize(
+                    R.styleable.MultiPaneChallengeLayout_Layout_layout_maxWidth, -1);
+            maxHeight = a.getDimensionPixelSize(
+                    R.styleable.MultiPaneChallengeLayout_Layout_layout_maxHeight, -1);
+
+            // Default gravity settings based on type and parent orientation
+            if (gravity == Gravity.NO_GRAVITY) {
+                if (parent.mOrientation == HORIZONTAL) {
+                    switch (childType) {
+                        case CHILD_TYPE_WIDGET:
+                            gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL;
+                            break;
+                        case CHILD_TYPE_CHALLENGE:
+                            gravity = Gravity.RIGHT | Gravity.CENTER_VERTICAL;
+                            break;
+                        case CHILD_TYPE_USER_SWITCHER:
+                            gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
+                            break;
+                    }
+                } else {
+                    switch (childType) {
+                        case CHILD_TYPE_WIDGET:
+                            gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
+                            break;
+                        case CHILD_TYPE_CHALLENGE:
+                            gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
+                            break;
+                        case CHILD_TYPE_USER_SWITCHER:
+                            gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
+                            break;
+                    }
+                }
+            }
+
+            a.recycle();
+        }
+
+        public LayoutParams(int width, int height) {
+            super(width, height);
+        }
+
+        public LayoutParams(ViewGroup.LayoutParams source) {
+            super(source);
+        }
+
+        public LayoutParams(MarginLayoutParams source) {
+            super(source);
+        }
+
+        public LayoutParams(LayoutParams source) {
+            this((MarginLayoutParams) source);
+
+            centerWithinArea = source.centerWithinArea;
+            childType = source.childType;
+            gravity = source.gravity;
+            maxWidth = source.maxWidth;
+            maxHeight = source.maxHeight;
+        }
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/MultiUserAvatarCache.java b/packages/Keyguard/src/com/android/keyguard/MultiUserAvatarCache.java
new file mode 100644
index 0000000..9930e72
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/MultiUserAvatarCache.java
@@ -0,0 +1,42 @@
+/*
+ * 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.keyguard;
+
+import android.graphics.drawable.Drawable;
+
+import java.util.HashMap;
+
+public class MultiUserAvatarCache {
+
+    private final HashMap<Integer, Drawable> mCache;
+
+    public MultiUserAvatarCache() {
+        mCache = new HashMap<Integer, Drawable>();
+    }
+
+    public void clear(int userId) {
+        mCache.remove(userId);
+    }
+
+    public Drawable get(int userId) {
+        return mCache.get(userId);
+    }
+
+    public void put(int userId, Drawable image) {
+        mCache.put(userId, image);
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/NumPadKey.java b/packages/Keyguard/src/com/android/keyguard/NumPadKey.java
new file mode 100644
index 0000000..532670f
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/NumPadKey.java
@@ -0,0 +1,127 @@
+/*
+ * 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.keyguard;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.text.SpannableStringBuilder;
+import android.text.style.TextAppearanceSpan;
+import android.util.AttributeSet;
+import android.view.HapticFeedbackConstants;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+
+import com.android.internal.widget.LockPatternUtils;
+
+public class NumPadKey extends Button {
+    // list of "ABC", etc per digit, starting with '0'
+    static String sKlondike[];
+
+    int mDigit = -1;
+    int mTextViewResId;
+    TextView mTextView = null;
+    boolean mEnableHaptics;
+
+    private View.OnClickListener mListener = new View.OnClickListener() {
+        @Override
+        public void onClick(View thisView) {
+            if (mTextView == null) {
+                if (mTextViewResId > 0) {
+                    final View v = NumPadKey.this.getRootView().findViewById(mTextViewResId);
+                    if (v != null && v instanceof TextView) {
+                        mTextView = (TextView) v;
+                    }
+                }
+            }
+            // check for time-based lockouts
+            if (mTextView != null && mTextView.isEnabled()) {
+                mTextView.append(String.valueOf(mDigit));
+            }
+            doHapticKeyClick();
+        }
+    };
+
+    public NumPadKey(Context context) {
+        this(context, null);
+    }
+
+    public NumPadKey(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public NumPadKey(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NumPadKey);
+        mDigit = a.getInt(R.styleable.NumPadKey_digit, mDigit);
+        setTextViewResId(a.getResourceId(R.styleable.NumPadKey_textView, 0));
+
+        setOnClickListener(mListener);
+        setOnHoverListener(new LiftToActivateListener(context));
+        setAccessibilityDelegate(new ObscureSpeechDelegate(context));
+
+        mEnableHaptics = new LockPatternUtils(context).isTactileFeedbackEnabled();
+
+        SpannableStringBuilder builder = new SpannableStringBuilder();
+        builder.append(String.valueOf(mDigit));
+        if (mDigit >= 0) {
+            if (sKlondike == null) {
+                sKlondike = context.getResources().getStringArray(
+                        R.array.lockscreen_num_pad_klondike);
+            }
+            if (sKlondike != null && sKlondike.length > mDigit) {
+                final String extra = sKlondike[mDigit];
+                final int extraLen = extra.length();
+                if (extraLen > 0) {
+                    builder.append(" ");
+                    builder.append(extra);
+                    builder.setSpan(
+                        new TextAppearanceSpan(context, R.style.TextAppearance_NumPadKey_Klondike),
+                        builder.length()-extraLen, builder.length(), 0);
+                }
+            }
+        }
+        setText(builder);
+    }
+
+    @Override
+    public void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+
+        // Reset the "announced headset" flag when detached.
+        ObscureSpeechDelegate.sAnnouncedHeadset = false;
+    }
+
+    public void setTextView(TextView tv) {
+        mTextView = tv;
+    }
+
+    public void setTextViewResId(int resId) {
+        mTextView = null;
+        mTextViewResId = resId;
+    }
+
+    // Cause a VIRTUAL_KEY vibration
+    public void doHapticKeyClick() {
+        if (mEnableHaptics) {
+            performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
+                    HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING
+                    | HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
+        }
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/ObscureSpeechDelegate.java b/packages/Keyguard/src/com/android/keyguard/ObscureSpeechDelegate.java
new file mode 100644
index 0000000..573122a
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/ObscureSpeechDelegate.java
@@ -0,0 +1,101 @@
+/*
+ * 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.keyguard;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.media.AudioManager;
+import android.provider.Settings;
+import android.view.View;
+import android.view.View.AccessibilityDelegate;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import com.android.internal.R;
+
+/**
+ * Accessibility delegate that obscures speech for a view when the user has
+ * not turned on the "speak passwords" preference and is not listening
+ * through headphones.
+ */
+class ObscureSpeechDelegate extends AccessibilityDelegate {
+    /** Whether any client has announced the "headset" notification. */
+    static boolean sAnnouncedHeadset = false;
+
+    private final ContentResolver mContentResolver;
+    private final AudioManager mAudioManager;
+
+    public ObscureSpeechDelegate(Context context) {
+        mContentResolver = context.getContentResolver();
+        mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+    }
+
+    @Override
+    public void sendAccessibilityEvent(View host, int eventType) {
+        super.sendAccessibilityEvent(host, eventType);
+
+        // Play the "headset required" announcement the first time the user
+        // places accessibility focus on a key.
+        if ((eventType == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED)
+                && !sAnnouncedHeadset && shouldObscureSpeech()) {
+            sAnnouncedHeadset = true;
+            host.announceForAccessibility(host.getContext().getString(
+                    R.string.keyboard_headset_required_to_hear_password));
+        }
+    }
+
+    @Override
+    public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
+        super.onPopulateAccessibilityEvent(host, event);
+
+        if ((event.getEventType() != AccessibilityEvent.TYPE_ANNOUNCEMENT)
+                && shouldObscureSpeech()) {
+            event.getText().clear();
+            event.setContentDescription(host.getContext().getString(
+                    R.string.keyboard_password_character_no_headset));
+        }
+    }
+
+    @Override
+    public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfo(host, info);
+
+        if (shouldObscureSpeech()) {
+            final Context ctx = host.getContext();
+            info.setText(null);
+            info.setContentDescription(
+                    ctx.getString(R.string.keyboard_password_character_no_headset));
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    private boolean shouldObscureSpeech() {
+        // The user can optionally force speaking passwords.
+        if (Settings.Secure.getInt(mContentResolver,
+                Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD, 0) != 0) {
+            return false;
+        }
+
+        // Always speak if the user is listening through headphones.
+        if (mAudioManager.isWiredHeadsetOn() || mAudioManager.isBluetoothA2dpOn()) {
+            return false;
+        }
+
+        // Don't speak since this key is used to type a password.
+        return true;
+    }
+}
\ No newline at end of file
diff --git a/packages/Keyguard/src/com/android/keyguard/PagedView.java b/packages/Keyguard/src/com/android/keyguard/PagedView.java
new file mode 100644
index 0000000..881d14d
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/PagedView.java
@@ -0,0 +1,2567 @@
+/*
+ * 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.keyguard;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.TimeInterpolator;
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.InputDevice;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.animation.AnimationUtils;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.Interpolator;
+import android.view.animation.LinearInterpolator;
+import android.widget.Scroller;
+
+import java.util.ArrayList;
+
+/**
+ * An abstraction of the original Workspace which supports browsing through a
+ * sequential list of "pages"
+ */
+public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarchyChangeListener {
+    private static final String TAG = "WidgetPagedView";
+    private static final boolean DEBUG = false;
+    protected static final int INVALID_PAGE = -1;
+
+    // the min drag distance for a fling to register, to prevent random page shifts
+    private static final int MIN_LENGTH_FOR_FLING = 25;
+
+    protected static final int PAGE_SNAP_ANIMATION_DURATION = 750;
+    protected static final int SLOW_PAGE_SNAP_ANIMATION_DURATION = 950;
+    protected static final float NANOTIME_DIV = 1000000000.0f;
+
+    private static final float OVERSCROLL_ACCELERATE_FACTOR = 2;
+    private static final float OVERSCROLL_DAMP_FACTOR = 0.14f;
+
+    private static final float RETURN_TO_ORIGINAL_PAGE_THRESHOLD = 0.33f;
+    // The page is moved more than halfway, automatically move to the next page on touch up.
+    private static final float SIGNIFICANT_MOVE_THRESHOLD = 0.4f;
+
+    // The following constants need to be scaled based on density. The scaled versions will be
+    // assigned to the corresponding member variables below.
+    private static final int FLING_THRESHOLD_VELOCITY = 500;
+    private static final int MIN_SNAP_VELOCITY = 1500;
+    private static final int MIN_FLING_VELOCITY = 250;
+
+    // We are disabling touch interaction of the widget region for factory ROM.
+    private static final boolean DISABLE_TOUCH_INTERACTION = false;
+    private static final boolean DISABLE_TOUCH_SIDE_PAGES = true;
+    private static final boolean DISABLE_FLING_TO_DELETE = false;
+
+    static final int AUTOMATIC_PAGE_SPACING = -1;
+
+    protected int mFlingThresholdVelocity;
+    protected int mMinFlingVelocity;
+    protected int mMinSnapVelocity;
+
+    protected float mDensity;
+    protected float mSmoothingTime;
+    protected float mTouchX;
+
+    protected boolean mFirstLayout = true;
+
+    protected int mCurrentPage;
+    protected int mChildCountOnLastMeasure;
+
+    protected int mNextPage = INVALID_PAGE;
+    protected int mMaxScrollX;
+    protected Scroller mScroller;
+    private VelocityTracker mVelocityTracker;
+
+    private float mParentDownMotionX;
+    private float mParentDownMotionY;
+    private float mDownMotionX;
+    private float mDownMotionY;
+    private float mDownScrollX;
+    protected float mLastMotionX;
+    protected float mLastMotionXRemainder;
+    protected float mLastMotionY;
+    protected float mTotalMotionX;
+    private int mLastScreenCenter = -1;
+    private int[] mChildOffsets;
+    private int[] mChildRelativeOffsets;
+    private int[] mChildOffsetsWithLayoutScale;
+
+    protected final static int TOUCH_STATE_REST = 0;
+    protected final static int TOUCH_STATE_SCROLLING = 1;
+    protected final static int TOUCH_STATE_PREV_PAGE = 2;
+    protected final static int TOUCH_STATE_NEXT_PAGE = 3;
+    protected final static int TOUCH_STATE_REORDERING = 4;
+
+    protected final static float ALPHA_QUANTIZE_LEVEL = 0.0001f;
+
+    protected int mTouchState = TOUCH_STATE_REST;
+    protected boolean mForceScreenScrolled = false;
+
+    protected OnLongClickListener mLongClickListener;
+
+    protected int mTouchSlop;
+    private int mPagingTouchSlop;
+    private int mMaximumVelocity;
+    private int mMinimumWidth;
+    protected int mPageSpacing;
+    protected int mCellCountX = 0;
+    protected int mCellCountY = 0;
+    protected boolean mAllowOverScroll = true;
+    protected int mUnboundedScrollX;
+    protected int[] mTempVisiblePagesRange = new int[2];
+    protected boolean mForceDrawAllChildrenNextFrame;
+
+    // mOverScrollX is equal to getScrollX() when we're within the normal scroll range. Otherwise
+    // it is equal to the scaled overscroll position. We use a separate value so as to prevent
+    // the screens from continuing to translate beyond the normal bounds.
+    protected int mOverScrollX;
+
+    // parameter that adjusts the layout to be optimized for pages with that scale factor
+    protected float mLayoutScale = 1.0f;
+
+    protected static final int INVALID_POINTER = -1;
+
+    protected int mActivePointerId = INVALID_POINTER;
+
+    private PageSwitchListener mPageSwitchListener;
+
+    protected ArrayList<Boolean> mDirtyPageContent;
+
+    // If true, syncPages and syncPageItems will be called to refresh pages
+    protected boolean mContentIsRefreshable = true;
+
+    // If true, modify alpha of neighboring pages as user scrolls left/right
+    protected boolean mFadeInAdjacentScreens = false;
+
+    // It true, use a different slop parameter (pagingTouchSlop = 2 * touchSlop) for deciding
+    // to switch to a new page
+    protected boolean mUsePagingTouchSlop = true;
+
+    // If true, the subclass should directly update scrollX itself in its computeScroll method
+    // (SmoothPagedView does this)
+    protected boolean mDeferScrollUpdate = false;
+
+    protected boolean mIsPageMoving = false;
+
+    // All syncs and layout passes are deferred until data is ready.
+    protected boolean mIsDataReady = true;
+
+    // Scrolling indicator
+    private ValueAnimator mScrollIndicatorAnimator;
+    private View mScrollIndicator;
+    private int mScrollIndicatorPaddingLeft;
+    private int mScrollIndicatorPaddingRight;
+    private boolean mShouldShowScrollIndicator = false;
+    private boolean mShouldShowScrollIndicatorImmediately = false;
+    protected static final int sScrollIndicatorFadeInDuration = 150;
+    protected static final int sScrollIndicatorFadeOutDuration = 650;
+    protected static final int sScrollIndicatorFlashDuration = 650;
+
+    // The viewport whether the pages are to be contained (the actual view may be larger than the
+    // viewport)
+    private Rect mViewport = new Rect();
+
+    // Reordering
+    // We use the min scale to determine how much to expand the actually PagedView measured
+    // dimensions such that when we are zoomed out, the view is not clipped
+    private int REORDERING_DROP_REPOSITION_DURATION = 200;
+    protected int REORDERING_REORDER_REPOSITION_DURATION = 300;
+    protected int REORDERING_ZOOM_IN_OUT_DURATION = 250;
+    private int REORDERING_SIDE_PAGE_HOVER_TIMEOUT = 300;
+    private float REORDERING_SIDE_PAGE_BUFFER_PERCENTAGE = 0.1f;
+    private long REORDERING_DELETE_DROP_TARGET_FADE_DURATION = 150;
+    private float mMinScale = 1f;
+    protected View mDragView;
+    protected AnimatorSet mZoomInOutAnim;
+    private Runnable mSidePageHoverRunnable;
+    private int mSidePageHoverIndex = -1;
+    // This variable's scope is only for the duration of startReordering() and endReordering()
+    private boolean mReorderingStarted = false;
+    // This variable's scope is for the duration of startReordering() and after the zoomIn()
+    // animation after endReordering()
+    private boolean mIsReordering;
+    // The runnable that settles the page after snapToPage and animateDragViewToOriginalPosition
+    private int NUM_ANIMATIONS_RUNNING_BEFORE_ZOOM_OUT = 2;
+    private int mPostReorderingPreZoomInRemainingAnimationCount;
+    private Runnable mPostReorderingPreZoomInRunnable;
+
+    // Edge swiping
+    private boolean mOnlyAllowEdgeSwipes = false;
+    private boolean mDownEventOnEdge = false;
+    private int mEdgeSwipeRegionSize = 0;
+
+    // Convenience/caching
+    private Matrix mTmpInvMatrix = new Matrix();
+    private float[] mTmpPoint = new float[2];
+    private Rect mTmpRect = new Rect();
+    private Rect mAltTmpRect = new Rect();
+
+    // Fling to delete
+    private int FLING_TO_DELETE_FADE_OUT_DURATION = 350;
+    private float FLING_TO_DELETE_FRICTION = 0.035f;
+    // The degrees specifies how much deviation from the up vector to still consider a fling "up"
+    private float FLING_TO_DELETE_MAX_FLING_DEGREES = 65f;
+    protected int mFlingToDeleteThresholdVelocity = -1400;
+    // Drag to delete
+    private boolean mDeferringForDelete = false;
+    private int DELETE_SLIDE_IN_SIDE_PAGE_DURATION = 250;
+    private int DRAG_TO_DELETE_FADE_OUT_DURATION = 350;
+
+    // Drop to delete
+    private View mDeleteDropTarget;
+
+    // Bouncer
+    private boolean mTopAlignPageWhenShrinkingForBouncer = false;
+
+    public interface PageSwitchListener {
+        void onPageSwitching(View newPage, int newPageIndex);
+        void onPageSwitched(View newPage, int newPageIndex);
+    }
+
+    public PagedView(Context context) {
+        this(context, null);
+    }
+
+    public PagedView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public PagedView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        TypedArray a = context.obtainStyledAttributes(attrs,
+                R.styleable.PagedView, defStyle, 0);
+        setPageSpacing(a.getDimensionPixelSize(R.styleable.PagedView_pageSpacing, 0));
+        mScrollIndicatorPaddingLeft =
+            a.getDimensionPixelSize(R.styleable.PagedView_scrollIndicatorPaddingLeft, 0);
+        mScrollIndicatorPaddingRight =
+                a.getDimensionPixelSize(R.styleable.PagedView_scrollIndicatorPaddingRight, 0);
+        a.recycle();
+
+        Resources r = getResources();
+        mEdgeSwipeRegionSize = r.getDimensionPixelSize(R.dimen.kg_edge_swipe_region_size);
+        mTopAlignPageWhenShrinkingForBouncer =
+                r.getBoolean(R.bool.kg_top_align_page_shrink_on_bouncer_visible);
+
+        setHapticFeedbackEnabled(false);
+        init();
+    }
+
+    /**
+     * Initializes various states for this workspace.
+     */
+    protected void init() {
+        mDirtyPageContent = new ArrayList<Boolean>();
+        mDirtyPageContent.ensureCapacity(32);
+        mScroller = new Scroller(getContext(), new ScrollInterpolator());
+        mCurrentPage = 0;
+
+        final ViewConfiguration configuration = ViewConfiguration.get(getContext());
+        mTouchSlop = configuration.getScaledTouchSlop();
+        mPagingTouchSlop = configuration.getScaledPagingTouchSlop();
+        mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
+        mDensity = getResources().getDisplayMetrics().density;
+
+        // Scale the fling-to-delete threshold by the density
+        mFlingToDeleteThresholdVelocity =
+                (int) (mFlingToDeleteThresholdVelocity * mDensity);
+
+        mFlingThresholdVelocity = (int) (FLING_THRESHOLD_VELOCITY * mDensity);
+        mMinFlingVelocity = (int) (MIN_FLING_VELOCITY * mDensity);
+        mMinSnapVelocity = (int) (MIN_SNAP_VELOCITY * mDensity);
+        setOnHierarchyChangeListener(this);
+    }
+
+    void setDeleteDropTarget(View v) {
+        mDeleteDropTarget = v;
+    }
+
+    // Convenience methods to map points from self to parent and vice versa
+    float[] mapPointFromViewToParent(View v, float x, float y) {
+        mTmpPoint[0] = x;
+        mTmpPoint[1] = y;
+        v.getMatrix().mapPoints(mTmpPoint);
+        mTmpPoint[0] += v.getLeft();
+        mTmpPoint[1] += v.getTop();
+        return mTmpPoint;
+    }
+    float[] mapPointFromParentToView(View v, float x, float y) {
+        mTmpPoint[0] = x - v.getLeft();
+        mTmpPoint[1] = y - v.getTop();
+        v.getMatrix().invert(mTmpInvMatrix);
+        mTmpInvMatrix.mapPoints(mTmpPoint);
+        return mTmpPoint;
+    }
+
+    void updateDragViewTranslationDuringDrag() {
+        float x = mLastMotionX - mDownMotionX + getScrollX() - mDownScrollX;
+        float y = mLastMotionY - mDownMotionY;
+        mDragView.setTranslationX(x);
+        mDragView.setTranslationY(y);
+
+        if (DEBUG) Log.d(TAG, "PagedView.updateDragViewTranslationDuringDrag(): " + x + ", " + y);
+    }
+
+    public void setMinScale(float f) {
+        mMinScale = f;
+        requestLayout();
+    }
+
+    @Override
+    public void setScaleX(float scaleX) {
+        super.setScaleX(scaleX);
+        if (isReordering(true)) {
+            float[] p = mapPointFromParentToView(this, mParentDownMotionX, mParentDownMotionY);
+            mLastMotionX = p[0];
+            mLastMotionY = p[1];
+            updateDragViewTranslationDuringDrag();
+        }
+    }
+
+    // Convenience methods to get the actual width/height of the PagedView (since it is measured
+    // to be larger to account for the minimum possible scale)
+    int getViewportWidth() {
+        return mViewport.width();
+    }
+    int getViewportHeight() {
+        return mViewport.height();
+    }
+
+    // Convenience methods to get the offset ASSUMING that we are centering the pages in the
+    // PagedView both horizontally and vertically
+    int getViewportOffsetX() {
+        return (getMeasuredWidth() - getViewportWidth()) / 2;
+    }
+    int getViewportOffsetY() {
+        return (getMeasuredHeight() - getViewportHeight()) / 2;
+    }
+
+    public void setPageSwitchListener(PageSwitchListener pageSwitchListener) {
+        mPageSwitchListener = pageSwitchListener;
+        if (mPageSwitchListener != null) {
+            mPageSwitchListener.onPageSwitched(getPageAt(mCurrentPage), mCurrentPage);
+        }
+    }
+
+    /**
+     * Called by subclasses to mark that data is ready, and that we can begin loading and laying
+     * out pages.
+     */
+    protected void setDataIsReady() {
+        mIsDataReady = true;
+    }
+
+    protected boolean isDataReady() {
+        return mIsDataReady;
+    }
+
+    /**
+     * Returns the index of the currently displayed page.
+     *
+     * @return The index of the currently displayed page.
+     */
+    int getCurrentPage() {
+        return mCurrentPage;
+    }
+
+    int getNextPage() {
+        return (mNextPage != INVALID_PAGE) ? mNextPage : mCurrentPage;
+    }
+
+    int getPageCount() {
+        return getChildCount();
+    }
+
+    View getPageAt(int index) {
+        return getChildAt(index);
+    }
+
+    protected int indexToPage(int index) {
+        return index;
+    }
+
+    /**
+     * Updates the scroll of the current page immediately to its final scroll position.  We use this
+     * in CustomizePagedView to allow tabs to share the same PagedView while resetting the scroll of
+     * the previous tab page.
+     */
+    protected void updateCurrentPageScroll() {
+        int offset = getChildOffset(mCurrentPage);
+        int relOffset = getRelativeChildOffset(mCurrentPage);
+        int newX = offset - relOffset;
+        scrollTo(newX, 0);
+        mScroller.setFinalX(newX);
+        mScroller.forceFinished(true);
+    }
+
+    /**
+     * Sets the current page.
+     */
+    void setCurrentPage(int currentPage) {
+        notifyPageSwitching(currentPage);
+        if (!mScroller.isFinished()) {
+            mScroller.abortAnimation();
+        }
+        // don't introduce any checks like mCurrentPage == currentPage here-- if we change the
+        // the default
+        if (getChildCount() == 0) {
+            return;
+        }
+
+        mForceScreenScrolled = true;
+        mCurrentPage = Math.max(0, Math.min(currentPage, getPageCount() - 1));
+        updateCurrentPageScroll();
+        updateScrollingIndicator();
+        notifyPageSwitched();
+        invalidate();
+    }
+
+    public void setOnlyAllowEdgeSwipes(boolean enable) {
+        mOnlyAllowEdgeSwipes = enable;
+    }
+
+    protected void notifyPageSwitching(int whichPage) {
+        if (mPageSwitchListener != null) {
+            mPageSwitchListener.onPageSwitching(getPageAt(whichPage), whichPage);
+        }
+    }
+
+    protected void notifyPageSwitched() {
+        if (mPageSwitchListener != null) {
+            mPageSwitchListener.onPageSwitched(getPageAt(mCurrentPage), mCurrentPage);
+        }
+    }
+
+    protected void pageBeginMoving() {
+        if (!mIsPageMoving) {
+            mIsPageMoving = true;
+            onPageBeginMoving();
+        }
+    }
+
+    protected void pageEndMoving() {
+        if (mIsPageMoving) {
+            mIsPageMoving = false;
+            onPageEndMoving();
+        }
+    }
+
+    protected boolean isPageMoving() {
+        return mIsPageMoving;
+    }
+
+    // a method that subclasses can override to add behavior
+    protected void onPageBeginMoving() {
+    }
+
+    // a method that subclasses can override to add behavior
+    protected void onPageEndMoving() {
+    }
+
+    /**
+     * Registers the specified listener on each page contained in this workspace.
+     *
+     * @param l The listener used to respond to long clicks.
+     */
+    @Override
+    public void setOnLongClickListener(OnLongClickListener l) {
+        mLongClickListener = l;
+        final int count = getPageCount();
+        for (int i = 0; i < count; i++) {
+            getPageAt(i).setOnLongClickListener(l);
+        }
+    }
+
+    @Override
+    public void scrollBy(int x, int y) {
+        scrollTo(mUnboundedScrollX + x, getScrollY() + y);
+    }
+
+    @Override
+    public void scrollTo(int x, int y) {
+        mUnboundedScrollX = x;
+
+        if (x < 0) {
+            super.scrollTo(0, y);
+            if (mAllowOverScroll) {
+                overScroll(x);
+            }
+        } else if (x > mMaxScrollX) {
+            super.scrollTo(mMaxScrollX, y);
+            if (mAllowOverScroll) {
+                overScroll(x - mMaxScrollX);
+            }
+        } else {
+            mOverScrollX = x;
+            super.scrollTo(x, y);
+        }
+
+        mTouchX = x;
+        mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
+
+        // Update the last motion events when scrolling
+        if (isReordering(true)) {
+            float[] p = mapPointFromParentToView(this, mParentDownMotionX, mParentDownMotionY);
+            mLastMotionX = p[0];
+            mLastMotionY = p[1];
+            updateDragViewTranslationDuringDrag();
+        }
+    }
+
+    // we moved this functionality to a helper function so SmoothPagedView can reuse it
+    protected boolean computeScrollHelper() {
+        if (mScroller.computeScrollOffset()) {
+            // Don't bother scrolling if the page does not need to be moved
+            if (getScrollX() != mScroller.getCurrX()
+                || getScrollY() != mScroller.getCurrY()
+                || mOverScrollX != mScroller.getCurrX()) {
+                scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
+            }
+            invalidate();
+            return true;
+        } else if (mNextPage != INVALID_PAGE) {
+            mCurrentPage = Math.max(0, Math.min(mNextPage, getPageCount() - 1));
+            mNextPage = INVALID_PAGE;
+            notifyPageSwitched();
+
+            // We don't want to trigger a page end moving unless the page has settled
+            // and the user has stopped scrolling
+            if (mTouchState == TOUCH_STATE_REST) {
+                pageEndMoving();
+            }
+
+            onPostReorderingAnimationCompleted();
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public void computeScroll() {
+        computeScrollHelper();
+    }
+
+    protected boolean shouldSetTopAlignedPivotForWidget(int childIndex) {
+        return mTopAlignPageWhenShrinkingForBouncer;
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        if (!mIsDataReady || getChildCount() == 0) {
+            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+            return;
+        }
+
+        // We measure the dimensions of the PagedView to be larger than the pages so that when we
+        // zoom out (and scale down), the view is still contained in the parent
+        View parent = (View) getParent();
+        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
+        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
+        // NOTE: We multiply by 1.5f to account for the fact that depending on the offset of the
+        // viewport, we can be at most one and a half screens offset once we scale down
+        DisplayMetrics dm = getResources().getDisplayMetrics();
+        int maxSize = Math.max(dm.widthPixels, dm.heightPixels);
+        int parentWidthSize = (int) (1.5f * maxSize);
+        int parentHeightSize = maxSize;
+        int scaledWidthSize = (int) (parentWidthSize / mMinScale);
+        int scaledHeightSize = (int) (parentHeightSize / mMinScale);
+        mViewport.set(0, 0, widthSize, heightSize);
+
+        if (widthMode == MeasureSpec.UNSPECIFIED || heightMode == MeasureSpec.UNSPECIFIED) {
+            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+            return;
+        }
+
+        // Return early if we aren't given a proper dimension
+        if (widthSize <= 0 || heightSize <= 0) {
+            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+            return;
+        }
+
+        /* Allow the height to be set as WRAP_CONTENT. This allows the particular case
+         * of the All apps view on XLarge displays to not take up more space then it needs. Width
+         * is still not allowed to be set as WRAP_CONTENT since many parts of the code expect
+         * each page to have the same width.
+         */
+        final int verticalPadding = getPaddingTop() + getPaddingBottom();
+        final int horizontalPadding = getPaddingLeft() + getPaddingRight();
+
+        // The children are given the same width and height as the workspace
+        // unless they were set to WRAP_CONTENT
+        if (DEBUG) Log.d(TAG, "PagedView.onMeasure(): " + widthSize + ", " + heightSize);
+        if (DEBUG) Log.d(TAG, "PagedView.scaledSize: " + scaledWidthSize + ", " + scaledHeightSize);
+        if (DEBUG) Log.d(TAG, "PagedView.parentSize: " + parentWidthSize + ", " + parentHeightSize);
+        if (DEBUG) Log.d(TAG, "PagedView.horizontalPadding: " + horizontalPadding);
+        if (DEBUG) Log.d(TAG, "PagedView.verticalPadding: " + verticalPadding);
+        final int childCount = getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            // disallowing padding in paged view (just pass 0)
+            final View child = getPageAt(i);
+            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+            int childWidthMode;
+            if (lp.width == LayoutParams.WRAP_CONTENT) {
+                childWidthMode = MeasureSpec.AT_MOST;
+            } else {
+                childWidthMode = MeasureSpec.EXACTLY;
+            }
+
+            int childHeightMode;
+            if (lp.height == LayoutParams.WRAP_CONTENT) {
+                childHeightMode = MeasureSpec.AT_MOST;
+            } else {
+                childHeightMode = MeasureSpec.EXACTLY;
+            }
+
+            final int childWidthMeasureSpec =
+                MeasureSpec.makeMeasureSpec(widthSize - horizontalPadding, childWidthMode);
+            final int childHeightMeasureSpec =
+                MeasureSpec.makeMeasureSpec(heightSize - verticalPadding, childHeightMode);
+
+            child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+        }
+        setMeasuredDimension(scaledWidthSize, scaledHeightSize);
+
+        // We can't call getChildOffset/getRelativeChildOffset until we set the measured dimensions.
+        // We also wait until we set the measured dimensions before flushing the cache as well, to
+        // ensure that the cache is filled with good values.
+        invalidateCachedOffsets();
+
+        if (mChildCountOnLastMeasure != getChildCount() && !mDeferringForDelete) {
+            setCurrentPage(mCurrentPage);
+        }
+        mChildCountOnLastMeasure = getChildCount();
+
+        if (childCount > 0) {
+            if (DEBUG) Log.d(TAG, "getRelativeChildOffset(): " + getViewportWidth() + ", "
+                    + getChildWidth(0));
+
+            // Calculate the variable page spacing if necessary
+            if (mPageSpacing == AUTOMATIC_PAGE_SPACING) {
+                // The gap between pages in the PagedView should be equal to the gap from the page
+                // to the edge of the screen (so it is not visible in the current screen).  To
+                // account for unequal padding on each side of the paged view, we take the maximum
+                // of the left/right gap and use that as the gap between each page.
+                int offset = getRelativeChildOffset(0);
+                int spacing = Math.max(offset, widthSize - offset -
+                        getChildAt(0).getMeasuredWidth());
+                setPageSpacing(spacing);
+            }
+        }
+
+        updateScrollingIndicatorPosition();
+
+        if (childCount > 0) {
+            mMaxScrollX = getChildOffset(childCount - 1) - getRelativeChildOffset(childCount - 1);
+        } else {
+            mMaxScrollX = 0;
+        }
+    }
+
+    public void setPageSpacing(int pageSpacing) {
+        mPageSpacing = pageSpacing;
+        invalidateCachedOffsets();
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        if (!mIsDataReady || getChildCount() == 0) {
+            return;
+        }
+
+        if (DEBUG) Log.d(TAG, "PagedView.onLayout()");
+        final int childCount = getChildCount();
+
+        int offsetX = getViewportOffsetX();
+        int offsetY = getViewportOffsetY();
+
+        // Update the viewport offsets
+        mViewport.offset(offsetX,  offsetY);
+
+        int childLeft = offsetX + getRelativeChildOffset(0);
+        for (int i = 0; i < childCount; i++) {
+            final View child = getPageAt(i);
+            int childTop = offsetY + getPaddingTop();
+            if (child.getVisibility() != View.GONE) {
+                final int childWidth = getScaledMeasuredWidth(child);
+                final int childHeight = child.getMeasuredHeight();
+
+                if (DEBUG) Log.d(TAG, "\tlayout-child" + i + ": " + childLeft + ", " + childTop);
+                child.layout(childLeft, childTop,
+                        childLeft + child.getMeasuredWidth(), childTop + childHeight);
+                childLeft += childWidth + mPageSpacing;
+            }
+        }
+
+        if (mFirstLayout && mCurrentPage >= 0 && mCurrentPage < getChildCount()) {
+            setHorizontalScrollBarEnabled(false);
+            updateCurrentPageScroll();
+            setHorizontalScrollBarEnabled(true);
+            mFirstLayout = false;
+        }
+    }
+
+    protected void screenScrolled(int screenCenter) {
+    }
+
+    @Override
+    public void onChildViewAdded(View parent, View child) {
+        // This ensures that when children are added, they get the correct transforms / alphas
+        // in accordance with any scroll effects.
+        mForceScreenScrolled = true;
+        invalidate();
+        invalidateCachedOffsets();
+    }
+
+    @Override
+    public void onChildViewRemoved(View parent, View child) {
+        mForceScreenScrolled = true;
+        invalidate();
+        invalidateCachedOffsets();
+    }
+
+    protected void invalidateCachedOffsets() {
+        int count = getChildCount();
+        if (count == 0) {
+            mChildOffsets = null;
+            mChildRelativeOffsets = null;
+            mChildOffsetsWithLayoutScale = null;
+            return;
+        }
+
+        mChildOffsets = new int[count];
+        mChildRelativeOffsets = new int[count];
+        mChildOffsetsWithLayoutScale = new int[count];
+        for (int i = 0; i < count; i++) {
+            mChildOffsets[i] = -1;
+            mChildRelativeOffsets[i] = -1;
+            mChildOffsetsWithLayoutScale[i] = -1;
+        }
+    }
+
+    protected int getChildOffset(int index) {
+        if (index < 0 || index > getChildCount() - 1) return 0;
+
+        int[] childOffsets = Float.compare(mLayoutScale, 1f) == 0 ?
+                mChildOffsets : mChildOffsetsWithLayoutScale;
+
+        if (childOffsets != null && childOffsets[index] != -1) {
+            return childOffsets[index];
+        } else {
+            if (getChildCount() == 0)
+                return 0;
+
+            int offset = getRelativeChildOffset(0);
+            for (int i = 0; i < index; ++i) {
+                offset += getScaledMeasuredWidth(getPageAt(i)) + mPageSpacing;
+            }
+            if (childOffsets != null) {
+                childOffsets[index] = offset;
+            }
+            return offset;
+        }
+    }
+
+    protected int getRelativeChildOffset(int index) {
+        if (index < 0 || index > getChildCount() - 1) return 0;
+
+        if (mChildRelativeOffsets != null && mChildRelativeOffsets[index] != -1) {
+            return mChildRelativeOffsets[index];
+        } else {
+            final int padding = getPaddingLeft() + getPaddingRight();
+            final int offset = getPaddingLeft() +
+                    (getViewportWidth() - padding - getChildWidth(index)) / 2;
+            if (mChildRelativeOffsets != null) {
+                mChildRelativeOffsets[index] = offset;
+            }
+            return offset;
+        }
+    }
+
+    protected int getScaledMeasuredWidth(View child) {
+        // This functions are called enough times that it actually makes a difference in the
+        // profiler -- so just inline the max() here
+        final int measuredWidth = child.getMeasuredWidth();
+        final int minWidth = mMinimumWidth;
+        final int maxWidth = (minWidth > measuredWidth) ? minWidth : measuredWidth;
+        return (int) (maxWidth * mLayoutScale + 0.5f);
+    }
+
+    void boundByReorderablePages(boolean isReordering, int[] range) {
+        // Do nothing
+    }
+
+    // TODO: Fix this
+    protected void getVisiblePages(int[] range) {
+        range[0] = 0;
+        range[1] = getPageCount() - 1;
+
+        /*
+        final int pageCount = getChildCount();
+
+        if (pageCount > 0) {
+            final int screenWidth = getViewportWidth();
+            int leftScreen = 0;
+            int rightScreen = 0;
+            int offsetX = getViewportOffsetX() + getScrollX();
+            View currPage = getPageAt(leftScreen);
+            while (leftScreen < pageCount - 1 &&
+                    currPage.getX() + currPage.getWidth() -
+                    currPage.getPaddingRight() < offsetX) {
+                leftScreen++;
+                currPage = getPageAt(leftScreen);
+            }
+            rightScreen = leftScreen;
+            currPage = getPageAt(rightScreen + 1);
+            while (rightScreen < pageCount - 1 &&
+                    currPage.getX() - currPage.getPaddingLeft() < offsetX + screenWidth) {
+                rightScreen++;
+                currPage = getPageAt(rightScreen + 1);
+            }
+
+            // TEMP: this is a hacky way to ensure that animations to new pages are not clipped
+            // because we don't draw them while scrolling?
+            range[0] = Math.max(0, leftScreen - 1);
+            range[1] = Math.min(rightScreen + 1, getChildCount() - 1);
+        } else {
+            range[0] = -1;
+            range[1] = -1;
+        }
+        */
+    }
+
+    protected boolean shouldDrawChild(View child) {
+        return child.getAlpha() > 0;
+    }
+
+    @Override
+    protected void dispatchDraw(Canvas canvas) {
+        int halfScreenSize = getViewportWidth() / 2;
+        // mOverScrollX is equal to getScrollX() when we're within the normal scroll range.
+        // Otherwise it is equal to the scaled overscroll position.
+        int screenCenter = mOverScrollX + halfScreenSize;
+
+        if (screenCenter != mLastScreenCenter || mForceScreenScrolled) {
+            // set mForceScreenScrolled before calling screenScrolled so that screenScrolled can
+            // set it for the next frame
+            mForceScreenScrolled = false;
+            screenScrolled(screenCenter);
+            mLastScreenCenter = screenCenter;
+        }
+
+        // Find out which screens are visible; as an optimization we only call draw on them
+        final int pageCount = getChildCount();
+        if (pageCount > 0) {
+            getVisiblePages(mTempVisiblePagesRange);
+            final int leftScreen = mTempVisiblePagesRange[0];
+            final int rightScreen = mTempVisiblePagesRange[1];
+            if (leftScreen != -1 && rightScreen != -1) {
+                final long drawingTime = getDrawingTime();
+                // Clip to the bounds
+                canvas.save();
+                canvas.clipRect(getScrollX(), getScrollY(), getScrollX() + getRight() - getLeft(),
+                        getScrollY() + getBottom() - getTop());
+
+                // Draw all the children, leaving the drag view for last
+                for (int i = pageCount - 1; i >= 0; i--) {
+                    final View v = getPageAt(i);
+                    if (v == mDragView) continue;
+                    if (mForceDrawAllChildrenNextFrame ||
+                               (leftScreen <= i && i <= rightScreen && shouldDrawChild(v))) {
+                        drawChild(canvas, v, drawingTime);
+                    }
+                }
+                // Draw the drag view on top (if there is one)
+                if (mDragView != null) {
+                    drawChild(canvas, mDragView, drawingTime);
+                }
+
+                mForceDrawAllChildrenNextFrame = false;
+                canvas.restore();
+            }
+        }
+    }
+
+    @Override
+    public boolean requestChildRectangleOnScreen(View child, Rect rectangle, boolean immediate) {
+        int page = indexToPage(indexOfChild(child));
+        if (page != mCurrentPage || !mScroller.isFinished()) {
+            snapToPage(page);
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
+        int focusablePage;
+        if (mNextPage != INVALID_PAGE) {
+            focusablePage = mNextPage;
+        } else {
+            focusablePage = mCurrentPage;
+        }
+        View v = getPageAt(focusablePage);
+        if (v != null) {
+            return v.requestFocus(direction, previouslyFocusedRect);
+        }
+        return false;
+    }
+
+    @Override
+    public boolean dispatchUnhandledMove(View focused, int direction) {
+        if (direction == View.FOCUS_LEFT) {
+            if (getCurrentPage() > 0) {
+                snapToPage(getCurrentPage() - 1);
+                return true;
+            }
+        } else if (direction == View.FOCUS_RIGHT) {
+            if (getCurrentPage() < getPageCount() - 1) {
+                snapToPage(getCurrentPage() + 1);
+                return true;
+            }
+        }
+        return super.dispatchUnhandledMove(focused, direction);
+    }
+
+    @Override
+    public void addFocusables(ArrayList<View> views, int direction, int focusableMode) {
+        if (mCurrentPage >= 0 && mCurrentPage < getPageCount()) {
+            getPageAt(mCurrentPage).addFocusables(views, direction, focusableMode);
+        }
+        if (direction == View.FOCUS_LEFT) {
+            if (mCurrentPage > 0) {
+                getPageAt(mCurrentPage - 1).addFocusables(views, direction, focusableMode);
+            }
+        } else if (direction == View.FOCUS_RIGHT){
+            if (mCurrentPage < getPageCount() - 1) {
+                getPageAt(mCurrentPage + 1).addFocusables(views, direction, focusableMode);
+            }
+        }
+    }
+
+    /**
+     * If one of our descendant views decides that it could be focused now, only
+     * pass that along if it's on the current page.
+     *
+     * This happens when live folders requery, and if they're off page, they
+     * end up calling requestFocus, which pulls it on page.
+     */
+    @Override
+    public void focusableViewAvailable(View focused) {
+        View current = getPageAt(mCurrentPage);
+        View v = focused;
+        while (true) {
+            if (v == current) {
+                super.focusableViewAvailable(focused);
+                return;
+            }
+            if (v == this) {
+                return;
+            }
+            ViewParent parent = v.getParent();
+            if (parent instanceof View) {
+                v = (View)v.getParent();
+            } else {
+                return;
+            }
+        }
+    }
+
+    /**
+     * Return true if a tap at (x, y) should trigger a flip to the previous page.
+     */
+    protected boolean hitsPreviousPage(float x, float y) {
+        return (x < getViewportOffsetX() + getRelativeChildOffset(mCurrentPage) - mPageSpacing);
+    }
+
+    /**
+     * Return true if a tap at (x, y) should trigger a flip to the next page.
+     */
+    protected boolean hitsNextPage(float x, float y) {
+        return  (x > (getViewportOffsetX() + getViewportWidth() - getRelativeChildOffset(mCurrentPage) + mPageSpacing));
+    }
+
+    /** Returns whether x and y originated within the buffered viewport */
+    private boolean isTouchPointInViewportWithBuffer(int x, int y) {
+        mTmpRect.set(mViewport.left - mViewport.width() / 2, mViewport.top,
+                mViewport.right + mViewport.width() / 2, mViewport.bottom);
+        return mTmpRect.contains(x, y);
+    }
+
+    /** Returns whether x and y originated within the current page view bounds */
+    private boolean isTouchPointInCurrentPage(int x, int y) {
+        View v = getPageAt(getCurrentPage());
+        if (v != null) {
+            mTmpRect.set((v.getLeft() - getScrollX()), 0, (v.getRight() - getScrollX()),
+                    v.getBottom());
+            return mTmpRect.contains(x, y);
+        }
+        return false;
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        if (DISABLE_TOUCH_INTERACTION) {
+            return false;
+        }
+
+        /*
+         * This method JUST determines whether we want to intercept the motion.
+         * If we return true, onTouchEvent will be called and we do the actual
+         * scrolling there.
+         */
+        acquireVelocityTrackerAndAddMovement(ev);
+
+        // Skip touch handling if there are no pages to swipe
+        if (getChildCount() <= 0) return super.onInterceptTouchEvent(ev);
+
+        /*
+         * Shortcut the most recurring case: the user is in the dragging
+         * state and he is moving his finger.  We want to intercept this
+         * motion.
+         */
+        final int action = ev.getAction();
+        if ((action == MotionEvent.ACTION_MOVE) &&
+                (mTouchState == TOUCH_STATE_SCROLLING)) {
+            return true;
+        }
+
+        switch (action & MotionEvent.ACTION_MASK) {
+            case MotionEvent.ACTION_MOVE: {
+                /*
+                 * mIsBeingDragged == false, otherwise the shortcut would have caught it. Check
+                 * whether the user has moved far enough from his original down touch.
+                 */
+                if (mActivePointerId != INVALID_POINTER) {
+                    determineScrollingStart(ev);
+                    break;
+                }
+                // if mActivePointerId is INVALID_POINTER, then we must have missed an ACTION_DOWN
+                // event. in that case, treat the first occurence of a move event as a ACTION_DOWN
+                // i.e. fall through to the next case (don't break)
+                // (We sometimes miss ACTION_DOWN events in Workspace because it ignores all events
+                // while it's small- this was causing a crash before we checked for INVALID_POINTER)
+            }
+
+            case MotionEvent.ACTION_DOWN: {
+                final float x = ev.getX();
+                final float y = ev.getY();
+                // Remember location of down touch
+                mDownMotionX = x;
+                mDownMotionY = y;
+                mDownScrollX = getScrollX();
+                mLastMotionX = x;
+                mLastMotionY = y;
+                float[] p = mapPointFromViewToParent(this, x, y);
+                mParentDownMotionX = p[0];
+                mParentDownMotionY = p[1];
+                mLastMotionXRemainder = 0;
+                mTotalMotionX = 0;
+                mActivePointerId = ev.getPointerId(0);
+
+                // Determine if the down event is within the threshold to be an edge swipe
+                int leftEdgeBoundary = getViewportOffsetX() + mEdgeSwipeRegionSize;
+                int rightEdgeBoundary = getMeasuredWidth() - getViewportOffsetX() - mEdgeSwipeRegionSize;
+                if ((mDownMotionX <= leftEdgeBoundary || mDownMotionX >= rightEdgeBoundary)) {
+                    mDownEventOnEdge = true;
+                }
+
+                /*
+                 * If being flinged and user touches the screen, initiate drag;
+                 * otherwise don't.  mScroller.isFinished should be false when
+                 * being flinged.
+                 */
+                final int xDist = Math.abs(mScroller.getFinalX() - mScroller.getCurrX());
+                final boolean finishedScrolling = (mScroller.isFinished() || xDist < mTouchSlop);
+                if (finishedScrolling) {
+                    mTouchState = TOUCH_STATE_REST;
+                    mScroller.abortAnimation();
+                } else {
+                    if (isTouchPointInViewportWithBuffer((int) mDownMotionX, (int) mDownMotionY)) {
+                        mTouchState = TOUCH_STATE_SCROLLING;
+                    } else {
+                        mTouchState = TOUCH_STATE_REST;
+                    }
+                }
+
+                // check if this can be the beginning of a tap on the side of the pages
+                // to scroll the current page
+                if (!DISABLE_TOUCH_SIDE_PAGES) {
+                    if (mTouchState != TOUCH_STATE_PREV_PAGE && mTouchState != TOUCH_STATE_NEXT_PAGE) {
+                        if (getChildCount() > 0) {
+                            if (hitsPreviousPage(x, y)) {
+                                mTouchState = TOUCH_STATE_PREV_PAGE;
+                            } else if (hitsNextPage(x, y)) {
+                                mTouchState = TOUCH_STATE_NEXT_PAGE;
+                            }
+                        }
+                    }
+                }
+                break;
+            }
+
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_CANCEL:
+                resetTouchState();
+                // Just intercept the touch event on up if we tap outside the strict viewport
+                if (!isTouchPointInCurrentPage((int) mLastMotionX, (int) mLastMotionY)) {
+                    return true;
+                }
+                break;
+
+            case MotionEvent.ACTION_POINTER_UP:
+                onSecondaryPointerUp(ev);
+                releaseVelocityTracker();
+                break;
+        }
+
+        /*
+         * The only time we want to intercept motion events is if we are in the
+         * drag mode.
+         */
+        return mTouchState != TOUCH_STATE_REST;
+    }
+
+    protected void determineScrollingStart(MotionEvent ev) {
+        determineScrollingStart(ev, 1.0f);
+    }
+
+    /*
+     * Determines if we should change the touch state to start scrolling after the
+     * user moves their touch point too far.
+     */
+    protected void determineScrollingStart(MotionEvent ev, float touchSlopScale) {
+        // Disallow scrolling if we don't have a valid pointer index
+        final int pointerIndex = ev.findPointerIndex(mActivePointerId);
+        if (pointerIndex == -1) return;
+
+        // Disallow scrolling if we started the gesture from outside the viewport
+        final float x = ev.getX(pointerIndex);
+        final float y = ev.getY(pointerIndex);
+        if (!isTouchPointInViewportWithBuffer((int) x, (int) y)) return;
+
+        // If we're only allowing edge swipes, we break out early if the down event wasn't
+        // at the edge.
+        if (mOnlyAllowEdgeSwipes && !mDownEventOnEdge) return;
+
+        final int xDiff = (int) Math.abs(x - mLastMotionX);
+        final int yDiff = (int) Math.abs(y - mLastMotionY);
+
+        final int touchSlop = Math.round(touchSlopScale * mTouchSlop);
+        boolean xPaged = xDiff > mPagingTouchSlop;
+        boolean xMoved = xDiff > touchSlop;
+        boolean yMoved = yDiff > touchSlop;
+
+        if (xMoved || xPaged || yMoved) {
+            if (mUsePagingTouchSlop ? xPaged : xMoved) {
+                // Scroll if the user moved far enough along the X axis
+                mTouchState = TOUCH_STATE_SCROLLING;
+                mTotalMotionX += Math.abs(mLastMotionX - x);
+                mLastMotionX = x;
+                mLastMotionXRemainder = 0;
+                mTouchX = getViewportOffsetX() + getScrollX();
+                mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
+                pageBeginMoving();
+            }
+        }
+    }
+
+    protected float getMaxScrollProgress() {
+        return 1.0f;
+    }
+
+    protected float getBoundedScrollProgress(int screenCenter, View v, int page) {
+        final int halfScreenSize = getViewportWidth() / 2;
+
+        screenCenter = Math.min(mScrollX + halfScreenSize, screenCenter);
+        screenCenter = Math.max(halfScreenSize,  screenCenter);
+
+        return getScrollProgress(screenCenter, v, page);
+    }
+
+    protected float getScrollProgress(int screenCenter, View v, int page) {
+        final int halfScreenSize = getViewportWidth() / 2;
+
+        int totalDistance = getScaledMeasuredWidth(v) + mPageSpacing;
+        int delta = screenCenter - (getChildOffset(page) -
+                getRelativeChildOffset(page) + halfScreenSize);
+
+        float scrollProgress = delta / (totalDistance * 1.0f);
+        scrollProgress = Math.min(scrollProgress, getMaxScrollProgress());
+        scrollProgress = Math.max(scrollProgress, - getMaxScrollProgress());
+        return scrollProgress;
+    }
+
+    // This curve determines how the effect of scrolling over the limits of the page dimishes
+    // as the user pulls further and further from the bounds
+    private float overScrollInfluenceCurve(float f) {
+        f -= 1.0f;
+        return f * f * f + 1.0f;
+    }
+
+    protected void acceleratedOverScroll(float amount) {
+        int screenSize = getViewportWidth();
+
+        // We want to reach the max over scroll effect when the user has
+        // over scrolled half the size of the screen
+        float f = OVERSCROLL_ACCELERATE_FACTOR * (amount / screenSize);
+
+        if (f == 0) return;
+
+        // Clamp this factor, f, to -1 < f < 1
+        if (Math.abs(f) >= 1) {
+            f /= Math.abs(f);
+        }
+
+        int overScrollAmount = (int) Math.round(f * screenSize);
+        if (amount < 0) {
+            mOverScrollX = overScrollAmount;
+            super.scrollTo(0, getScrollY());
+        } else {
+            mOverScrollX = mMaxScrollX + overScrollAmount;
+            super.scrollTo(mMaxScrollX, getScrollY());
+        }
+        invalidate();
+    }
+
+    protected void dampedOverScroll(float amount) {
+        int screenSize = getViewportWidth();
+
+        float f = (amount / screenSize);
+
+        if (f == 0) return;
+        f = f / (Math.abs(f)) * (overScrollInfluenceCurve(Math.abs(f)));
+
+        // Clamp this factor, f, to -1 < f < 1
+        if (Math.abs(f) >= 1) {
+            f /= Math.abs(f);
+        }
+
+        int overScrollAmount = (int) Math.round(OVERSCROLL_DAMP_FACTOR * f * screenSize);
+        if (amount < 0) {
+            mOverScrollX = overScrollAmount;
+            super.scrollTo(0, getScrollY());
+        } else {
+            mOverScrollX = mMaxScrollX + overScrollAmount;
+            super.scrollTo(mMaxScrollX, getScrollY());
+        }
+        invalidate();
+    }
+
+    protected void overScroll(float amount) {
+        dampedOverScroll(amount);
+    }
+
+    protected float maxOverScroll() {
+        // Using the formula in overScroll, assuming that f = 1.0 (which it should generally not
+        // exceed). Used to find out how much extra wallpaper we need for the over scroll effect
+        float f = 1.0f;
+        f = f / (Math.abs(f)) * (overScrollInfluenceCurve(Math.abs(f)));
+        return OVERSCROLL_DAMP_FACTOR * f;
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        if (DISABLE_TOUCH_INTERACTION) {
+            return false;
+        }
+
+        // Skip touch handling if there are no pages to swipe
+        if (getChildCount() <= 0) return super.onTouchEvent(ev);
+
+        acquireVelocityTrackerAndAddMovement(ev);
+
+        final int action = ev.getAction();
+
+        switch (action & MotionEvent.ACTION_MASK) {
+        case MotionEvent.ACTION_DOWN:
+            /*
+             * If being flinged and user touches, stop the fling. isFinished
+             * will be false if being flinged.
+             */
+            if (!mScroller.isFinished()) {
+                mScroller.abortAnimation();
+            }
+
+            // Remember where the motion event started
+            mDownMotionX = mLastMotionX = ev.getX();
+            mDownMotionY = mLastMotionY = ev.getY();
+            mDownScrollX = getScrollX();
+            float[] p = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY);
+            mParentDownMotionX = p[0];
+            mParentDownMotionY = p[1];
+            mLastMotionXRemainder = 0;
+            mTotalMotionX = 0;
+            mActivePointerId = ev.getPointerId(0);
+
+            // Determine if the down event is within the threshold to be an edge swipe
+            int leftEdgeBoundary = getViewportOffsetX() + mEdgeSwipeRegionSize;
+            int rightEdgeBoundary = getMeasuredWidth() - getViewportOffsetX() - mEdgeSwipeRegionSize;
+            if ((mDownMotionX <= leftEdgeBoundary || mDownMotionX >= rightEdgeBoundary)) {
+                mDownEventOnEdge = true;
+            }
+
+            if (mTouchState == TOUCH_STATE_SCROLLING) {
+                pageBeginMoving();
+            }
+            break;
+
+        case MotionEvent.ACTION_MOVE:
+            if (mTouchState == TOUCH_STATE_SCROLLING) {
+                // Scroll to follow the motion event
+                final int pointerIndex = ev.findPointerIndex(mActivePointerId);
+
+                if (pointerIndex == -1) return true;
+
+                final float x = ev.getX(pointerIndex);
+                final float deltaX = mLastMotionX + mLastMotionXRemainder - x;
+
+                mTotalMotionX += Math.abs(deltaX);
+
+                // Only scroll and update mLastMotionX if we have moved some discrete amount.  We
+                // keep the remainder because we are actually testing if we've moved from the last
+                // scrolled position (which is discrete).
+                if (Math.abs(deltaX) >= 1.0f) {
+                    mTouchX += deltaX;
+                    mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
+                    if (!mDeferScrollUpdate) {
+                        scrollBy((int) deltaX, 0);
+                        if (DEBUG) Log.d(TAG, "onTouchEvent().Scrolling: " + deltaX);
+                    } else {
+                        invalidate();
+                    }
+                    mLastMotionX = x;
+                    mLastMotionXRemainder = deltaX - (int) deltaX;
+                } else {
+                    awakenScrollBars();
+                }
+            } else if (mTouchState == TOUCH_STATE_REORDERING) {
+                // Update the last motion position
+                mLastMotionX = ev.getX();
+                mLastMotionY = ev.getY();
+
+                // Update the parent down so that our zoom animations take this new movement into
+                // account
+                float[] pt = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY);
+                mParentDownMotionX = pt[0];
+                mParentDownMotionY = pt[1];
+                updateDragViewTranslationDuringDrag();
+
+                // Find the closest page to the touch point
+                final int dragViewIndex = indexOfChild(mDragView);
+                int bufferSize = (int) (REORDERING_SIDE_PAGE_BUFFER_PERCENTAGE *
+                    getViewportWidth());
+                int leftBufferEdge = (int) (mapPointFromViewToParent(this, mViewport.left, 0)[0]
+                        + bufferSize);
+                int rightBufferEdge = (int) (mapPointFromViewToParent(this, mViewport.right, 0)[0]
+                        - bufferSize);
+
+                // Change the drag view if we are hovering over the drop target
+                boolean isHoveringOverDelete = isHoveringOverDeleteDropTarget(
+                        (int) mParentDownMotionX, (int) mParentDownMotionY);
+                setPageHoveringOverDeleteDropTarget(dragViewIndex, isHoveringOverDelete);
+
+                if (DEBUG) Log.d(TAG, "leftBufferEdge: " + leftBufferEdge);
+                if (DEBUG) Log.d(TAG, "rightBufferEdge: " + rightBufferEdge);
+                if (DEBUG) Log.d(TAG, "mLastMotionX: " + mLastMotionX);
+                if (DEBUG) Log.d(TAG, "mLastMotionY: " + mLastMotionY);
+                if (DEBUG) Log.d(TAG, "mParentDownMotionX: " + mParentDownMotionX);
+                if (DEBUG) Log.d(TAG, "mParentDownMotionY: " + mParentDownMotionY);
+
+                float parentX = mParentDownMotionX;
+                int pageIndexToSnapTo = -1;
+                if (parentX < leftBufferEdge && dragViewIndex > 0) {
+                    pageIndexToSnapTo = dragViewIndex - 1;
+                } else if (parentX > rightBufferEdge && dragViewIndex < getChildCount() - 1) {
+                    pageIndexToSnapTo = dragViewIndex + 1;
+                }
+
+                final int pageUnderPointIndex = pageIndexToSnapTo;
+                if (pageUnderPointIndex > -1 && !isHoveringOverDelete) {
+                    mTempVisiblePagesRange[0] = 0;
+                    mTempVisiblePagesRange[1] = getPageCount() - 1;
+                    boundByReorderablePages(true, mTempVisiblePagesRange);
+                    if (mTempVisiblePagesRange[0] <= pageUnderPointIndex &&
+                            pageUnderPointIndex <= mTempVisiblePagesRange[1] &&
+                            pageUnderPointIndex != mSidePageHoverIndex && mScroller.isFinished()) {
+                        mSidePageHoverIndex = pageUnderPointIndex;
+                        mSidePageHoverRunnable = new Runnable() {
+                            @Override
+                            public void run() {
+                                // Update the down scroll position to account for the fact that the
+                                // current page is moved
+                                mDownScrollX = getChildOffset(pageUnderPointIndex)
+                                        - getRelativeChildOffset(pageUnderPointIndex);
+
+                                // Setup the scroll to the correct page before we swap the views
+                                snapToPage(pageUnderPointIndex);
+
+                                // For each of the pages between the paged view and the drag view,
+                                // animate them from the previous position to the new position in
+                                // the layout (as a result of the drag view moving in the layout)
+                                int shiftDelta = (dragViewIndex < pageUnderPointIndex) ? -1 : 1;
+                                int lowerIndex = (dragViewIndex < pageUnderPointIndex) ?
+                                        dragViewIndex + 1 : pageUnderPointIndex;
+                                int upperIndex = (dragViewIndex > pageUnderPointIndex) ?
+                                        dragViewIndex - 1 : pageUnderPointIndex;
+                                for (int i = lowerIndex; i <= upperIndex; ++i) {
+                                    View v = getChildAt(i);
+                                    // dragViewIndex < pageUnderPointIndex, so after we remove the
+                                    // drag view all subsequent views to pageUnderPointIndex will
+                                    // shift down.
+                                    int oldX = getViewportOffsetX() + getChildOffset(i);
+                                    int newX = getViewportOffsetX() + getChildOffset(i + shiftDelta);
+
+                                    // Animate the view translation from its old position to its new
+                                    // position
+                                    AnimatorSet anim = (AnimatorSet) v.getTag();
+                                    if (anim != null) {
+                                        anim.cancel();
+                                    }
+
+                                    v.setTranslationX(oldX - newX);
+                                    anim = new AnimatorSet();
+                                    anim.setDuration(REORDERING_REORDER_REPOSITION_DURATION);
+                                    anim.playTogether(
+                                            ObjectAnimator.ofFloat(v, "translationX", 0f));
+                                    anim.start();
+                                    v.setTag(anim);
+                                }
+
+                                removeView(mDragView);
+                                onRemoveView(mDragView, false);
+                                addView(mDragView, pageUnderPointIndex);
+                                onAddView(mDragView, pageUnderPointIndex);
+                                mSidePageHoverIndex = -1;
+                            }
+                        };
+                        postDelayed(mSidePageHoverRunnable, REORDERING_SIDE_PAGE_HOVER_TIMEOUT);
+                    }
+                } else {
+                    removeCallbacks(mSidePageHoverRunnable);
+                    mSidePageHoverIndex = -1;
+                }
+            } else {
+                determineScrollingStart(ev);
+            }
+            break;
+
+        case MotionEvent.ACTION_UP:
+            if (mTouchState == TOUCH_STATE_SCROLLING) {
+                final int activePointerId = mActivePointerId;
+                final int pointerIndex = ev.findPointerIndex(activePointerId);
+                final float x = ev.getX(pointerIndex);
+                final VelocityTracker velocityTracker = mVelocityTracker;
+                velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
+                int velocityX = (int) velocityTracker.getXVelocity(activePointerId);
+                final int deltaX = (int) (x - mDownMotionX);
+                final int pageWidth = getScaledMeasuredWidth(getPageAt(mCurrentPage));
+                boolean isSignificantMove = Math.abs(deltaX) > pageWidth *
+                        SIGNIFICANT_MOVE_THRESHOLD;
+
+                mTotalMotionX += Math.abs(mLastMotionX + mLastMotionXRemainder - x);
+
+                boolean isFling = mTotalMotionX > MIN_LENGTH_FOR_FLING &&
+                        Math.abs(velocityX) > mFlingThresholdVelocity;
+
+                // In the case that the page is moved far to one direction and then is flung
+                // in the opposite direction, we use a threshold to determine whether we should
+                // just return to the starting page, or if we should skip one further.
+                boolean returnToOriginalPage = false;
+                if (Math.abs(deltaX) > pageWidth * RETURN_TO_ORIGINAL_PAGE_THRESHOLD &&
+                        Math.signum(velocityX) != Math.signum(deltaX) && isFling) {
+                    returnToOriginalPage = true;
+                }
+
+                int finalPage;
+                // We give flings precedence over large moves, which is why we short-circuit our
+                // test for a large move if a fling has been registered. That is, a large
+                // move to the left and fling to the right will register as a fling to the right.
+                if (((isSignificantMove && deltaX > 0 && !isFling) ||
+                        (isFling && velocityX > 0)) && mCurrentPage > 0) {
+                    finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage - 1;
+                    snapToPageWithVelocity(finalPage, velocityX);
+                } else if (((isSignificantMove && deltaX < 0 && !isFling) ||
+                        (isFling && velocityX < 0)) &&
+                        mCurrentPage < getChildCount() - 1) {
+                    finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage + 1;
+                    snapToPageWithVelocity(finalPage, velocityX);
+                } else {
+                    snapToDestination();
+                }
+            } else if (mTouchState == TOUCH_STATE_PREV_PAGE) {
+                // at this point we have not moved beyond the touch slop
+                // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so
+                // we can just page
+                int nextPage = Math.max(0, mCurrentPage - 1);
+                if (nextPage != mCurrentPage) {
+                    snapToPage(nextPage);
+                } else {
+                    snapToDestination();
+                }
+            } else if (mTouchState == TOUCH_STATE_NEXT_PAGE) {
+                // at this point we have not moved beyond the touch slop
+                // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so
+                // we can just page
+                int nextPage = Math.min(getChildCount() - 1, mCurrentPage + 1);
+                if (nextPage != mCurrentPage) {
+                    snapToPage(nextPage);
+                } else {
+                    snapToDestination();
+                }
+            } else if (mTouchState == TOUCH_STATE_REORDERING) {
+                // Update the last motion position
+                mLastMotionX = ev.getX();
+                mLastMotionY = ev.getY();
+
+                // Update the parent down so that our zoom animations take this new movement into
+                // account
+                float[] pt = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY);
+                mParentDownMotionX = pt[0];
+                mParentDownMotionY = pt[1];
+                updateDragViewTranslationDuringDrag();
+                boolean handledFling = false;
+                if (!DISABLE_FLING_TO_DELETE) {
+                    // Check the velocity and see if we are flinging-to-delete
+                    PointF flingToDeleteVector = isFlingingToDelete();
+                    if (flingToDeleteVector != null) {
+                        onFlingToDelete(flingToDeleteVector);
+                        handledFling = true;
+                    }
+                }
+                if (!handledFling && isHoveringOverDeleteDropTarget((int) mParentDownMotionX,
+                        (int) mParentDownMotionY)) {
+                    onDropToDelete();
+                }
+            } else {
+                onUnhandledTap(ev);
+            }
+
+            // Remove the callback to wait for the side page hover timeout
+            removeCallbacks(mSidePageHoverRunnable);
+            // End any intermediate reordering states
+            resetTouchState();
+            break;
+
+        case MotionEvent.ACTION_CANCEL:
+            if (mTouchState == TOUCH_STATE_SCROLLING) {
+                snapToDestination();
+            }
+            resetTouchState();
+            break;
+
+        case MotionEvent.ACTION_POINTER_UP:
+            onSecondaryPointerUp(ev);
+            break;
+        }
+
+        return true;
+    }
+
+    //public abstract void onFlingToDelete(View v);
+    public abstract void onRemoveView(View v, boolean deletePermanently);
+    public abstract void onRemoveViewAnimationCompleted();
+    public abstract void onAddView(View v, int index);
+
+    private void resetTouchState() {
+        releaseVelocityTracker();
+        endReordering();
+        mTouchState = TOUCH_STATE_REST;
+        mActivePointerId = INVALID_POINTER;
+        mDownEventOnEdge = false;
+    }
+
+    protected void onUnhandledTap(MotionEvent ev) {}
+
+    @Override
+    public boolean onGenericMotionEvent(MotionEvent event) {
+        if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+            switch (event.getAction()) {
+                case MotionEvent.ACTION_SCROLL: {
+                    // Handle mouse (or ext. device) by shifting the page depending on the scroll
+                    final float vscroll;
+                    final float hscroll;
+                    if ((event.getMetaState() & KeyEvent.META_SHIFT_ON) != 0) {
+                        vscroll = 0;
+                        hscroll = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
+                    } else {
+                        vscroll = -event.getAxisValue(MotionEvent.AXIS_VSCROLL);
+                        hscroll = event.getAxisValue(MotionEvent.AXIS_HSCROLL);
+                    }
+                    if (hscroll != 0 || vscroll != 0) {
+                        if (hscroll > 0 || vscroll > 0) {
+                            scrollRight();
+                        } else {
+                            scrollLeft();
+                        }
+                        return true;
+                    }
+                }
+            }
+        }
+        return super.onGenericMotionEvent(event);
+    }
+
+    private void acquireVelocityTrackerAndAddMovement(MotionEvent ev) {
+        if (mVelocityTracker == null) {
+            mVelocityTracker = VelocityTracker.obtain();
+        }
+        mVelocityTracker.addMovement(ev);
+    }
+
+    private void releaseVelocityTracker() {
+        if (mVelocityTracker != null) {
+            mVelocityTracker.recycle();
+            mVelocityTracker = null;
+        }
+    }
+
+    private void onSecondaryPointerUp(MotionEvent ev) {
+        final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >>
+                MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+        final int pointerId = ev.getPointerId(pointerIndex);
+        if (pointerId == mActivePointerId) {
+            // This was our active pointer going up. Choose a new
+            // active pointer and adjust accordingly.
+            // TODO: Make this decision more intelligent.
+            final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
+            mLastMotionX = mDownMotionX = ev.getX(newPointerIndex);
+            mLastMotionY = ev.getY(newPointerIndex);
+            mLastMotionXRemainder = 0;
+            mActivePointerId = ev.getPointerId(newPointerIndex);
+            if (mVelocityTracker != null) {
+                mVelocityTracker.clear();
+            }
+        }
+    }
+
+    @Override
+    public void requestChildFocus(View child, View focused) {
+        super.requestChildFocus(child, focused);
+        int page = indexToPage(indexOfChild(child));
+        if (page >= 0 && page != getCurrentPage() && !isInTouchMode()) {
+            snapToPage(page);
+        }
+    }
+
+    protected int getChildIndexForRelativeOffset(int relativeOffset) {
+        final int childCount = getChildCount();
+        int left;
+        int right;
+        for (int i = 0; i < childCount; ++i) {
+            left = getRelativeChildOffset(i);
+            right = (left + getScaledMeasuredWidth(getPageAt(i)));
+            if (left <= relativeOffset && relativeOffset <= right) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    protected int getChildWidth(int index) {
+        // This functions are called enough times that it actually makes a difference in the
+        // profiler -- so just inline the max() here
+        final int measuredWidth = getPageAt(index).getMeasuredWidth();
+        final int minWidth = mMinimumWidth;
+        return (minWidth > measuredWidth) ? minWidth : measuredWidth;
+    }
+
+    int getPageNearestToPoint(float x) {
+        int index = 0;
+        for (int i = 0; i < getChildCount(); ++i) {
+            if (x < getChildAt(i).getRight() - getScrollX()) {
+                return index;
+            } else {
+                index++;
+            }
+        }
+        return Math.min(index, getChildCount() - 1);
+    }
+
+    int getPageNearestToCenterOfScreen() {
+        int minDistanceFromScreenCenter = Integer.MAX_VALUE;
+        int minDistanceFromScreenCenterIndex = -1;
+        int screenCenter = getViewportOffsetX() + getScrollX() + (getViewportWidth() / 2);
+        final int childCount = getChildCount();
+        for (int i = 0; i < childCount; ++i) {
+            View layout = (View) getPageAt(i);
+            int childWidth = getScaledMeasuredWidth(layout);
+            int halfChildWidth = (childWidth / 2);
+            int childCenter = getViewportOffsetX() + getChildOffset(i) + halfChildWidth;
+            int distanceFromScreenCenter = Math.abs(childCenter - screenCenter);
+            if (distanceFromScreenCenter < minDistanceFromScreenCenter) {
+                minDistanceFromScreenCenter = distanceFromScreenCenter;
+                minDistanceFromScreenCenterIndex = i;
+            }
+        }
+        return minDistanceFromScreenCenterIndex;
+    }
+
+    protected void snapToDestination() {
+        snapToPage(getPageNearestToCenterOfScreen(), PAGE_SNAP_ANIMATION_DURATION);
+    }
+
+    private static class ScrollInterpolator implements Interpolator {
+        public ScrollInterpolator() {
+        }
+
+        public float getInterpolation(float t) {
+            t -= 1.0f;
+            return t*t*t*t*t + 1;
+        }
+    }
+
+    // We want the duration of the page snap animation to be influenced by the distance that
+    // the screen has to travel, however, we don't want this duration to be effected in a
+    // purely linear fashion. Instead, we use this method to moderate the effect that the distance
+    // of travel has on the overall snap duration.
+    float distanceInfluenceForSnapDuration(float f) {
+        f -= 0.5f; // center the values about 0.
+        f *= 0.3f * Math.PI / 2.0f;
+        return (float) Math.sin(f);
+    }
+
+    protected void snapToPageWithVelocity(int whichPage, int velocity) {
+        whichPage = Math.max(0, Math.min(whichPage, getChildCount() - 1));
+        int halfScreenSize = getViewportWidth() / 2;
+
+        if (DEBUG) Log.d(TAG, "snapToPage.getChildOffset(): " + getChildOffset(whichPage));
+        if (DEBUG) Log.d(TAG, "snapToPageWithVelocity.getRelativeChildOffset(): "
+                + getViewportWidth() + ", " + getChildWidth(whichPage));
+        final int newX = getChildOffset(whichPage) - getRelativeChildOffset(whichPage);
+        int delta = newX - mUnboundedScrollX;
+        int duration = 0;
+
+        if (Math.abs(velocity) < mMinFlingVelocity) {
+            // If the velocity is low enough, then treat this more as an automatic page advance
+            // as opposed to an apparent physical response to flinging
+            snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION);
+            return;
+        }
+
+        // Here we compute a "distance" that will be used in the computation of the overall
+        // snap duration. This is a function of the actual distance that needs to be traveled;
+        // we keep this value close to half screen size in order to reduce the variance in snap
+        // duration as a function of the distance the page needs to travel.
+        float distanceRatio = Math.min(1f, 1.0f * Math.abs(delta) / (2 * halfScreenSize));
+        float distance = halfScreenSize + halfScreenSize *
+                distanceInfluenceForSnapDuration(distanceRatio);
+
+        velocity = Math.abs(velocity);
+        velocity = Math.max(mMinSnapVelocity, velocity);
+
+        // we want the page's snap velocity to approximately match the velocity at which the
+        // user flings, so we scale the duration by a value near to the derivative of the scroll
+        // interpolator at zero, ie. 5. We use 4 to make it a little slower.
+        duration = 4 * Math.round(1000 * Math.abs(distance / velocity));
+
+        snapToPage(whichPage, delta, duration);
+    }
+
+    protected void snapToPage(int whichPage) {
+        snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION);
+    }
+    protected void snapToPageImmediately(int whichPage) {
+        snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION, true);
+    }
+
+    protected void snapToPage(int whichPage, int duration) {
+        snapToPage(whichPage, duration, false);
+    }
+    protected void snapToPage(int whichPage, int duration, boolean immediate) {
+        whichPage = Math.max(0, Math.min(whichPage, getPageCount() - 1));
+
+        if (DEBUG) Log.d(TAG, "snapToPage.getChildOffset(): " + getChildOffset(whichPage));
+        if (DEBUG) Log.d(TAG, "snapToPage.getRelativeChildOffset(): " + getViewportWidth() + ", "
+                + getChildWidth(whichPage));
+        int newX = getChildOffset(whichPage) - getRelativeChildOffset(whichPage);
+        final int sX = mUnboundedScrollX;
+        final int delta = newX - sX;
+        snapToPage(whichPage, delta, duration, immediate);
+    }
+
+    protected void snapToPage(int whichPage, int delta, int duration) {
+        snapToPage(whichPage, delta, duration, false);
+    }
+    protected void snapToPage(int whichPage, int delta, int duration, boolean immediate) {
+        mNextPage = whichPage;
+        notifyPageSwitching(whichPage);
+        View focusedChild = getFocusedChild();
+        if (focusedChild != null && whichPage != mCurrentPage &&
+                focusedChild == getPageAt(mCurrentPage)) {
+            focusedChild.clearFocus();
+        }
+
+        pageBeginMoving();
+        awakenScrollBars(duration);
+        if (immediate) {
+            duration = 0;
+        } else if (duration == 0) {
+            duration = Math.abs(delta);
+        }
+
+        if (!mScroller.isFinished()) mScroller.abortAnimation();
+        mScroller.startScroll(mUnboundedScrollX, 0, delta, 0, duration);
+
+        notifyPageSwitched();
+
+        // Trigger a compute() to finish switching pages if necessary
+        if (immediate) {
+            computeScroll();
+        }
+
+        mForceScreenScrolled = true;
+        invalidate();
+    }
+
+    public void scrollLeft() {
+        if (mScroller.isFinished()) {
+            if (mCurrentPage > 0) snapToPage(mCurrentPage - 1);
+        } else {
+            if (mNextPage > 0) snapToPage(mNextPage - 1);
+        }
+    }
+
+    public void scrollRight() {
+        if (mScroller.isFinished()) {
+            if (mCurrentPage < getChildCount() -1) snapToPage(mCurrentPage + 1);
+        } else {
+            if (mNextPage < getChildCount() -1) snapToPage(mNextPage + 1);
+        }
+    }
+
+    public int getPageForView(View v) {
+        int result = -1;
+        if (v != null) {
+            ViewParent vp = v.getParent();
+            int count = getChildCount();
+            for (int i = 0; i < count; i++) {
+                if (vp == getPageAt(i)) {
+                    return i;
+                }
+            }
+        }
+        return result;
+    }
+
+    public static class SavedState extends BaseSavedState {
+        int currentPage = -1;
+
+        SavedState(Parcelable superState) {
+            super(superState);
+        }
+
+        private SavedState(Parcel in) {
+            super(in);
+            currentPage = in.readInt();
+        }
+
+        @Override
+        public void writeToParcel(Parcel out, int flags) {
+            super.writeToParcel(out, flags);
+            out.writeInt(currentPage);
+        }
+
+        public static final Parcelable.Creator<SavedState> CREATOR =
+                new Parcelable.Creator<SavedState>() {
+            public SavedState createFromParcel(Parcel in) {
+                return new SavedState(in);
+            }
+
+            public SavedState[] newArray(int size) {
+                return new SavedState[size];
+            }
+        };
+    }
+
+    protected View getScrollingIndicator() {
+        return null;
+    }
+
+    protected boolean isScrollingIndicatorEnabled() {
+        return false;
+    }
+
+    Runnable hideScrollingIndicatorRunnable = new Runnable() {
+        @Override
+        public void run() {
+            hideScrollingIndicator(false);
+        }
+    };
+
+    protected void flashScrollingIndicator(boolean animated) {
+        removeCallbacks(hideScrollingIndicatorRunnable);
+        showScrollingIndicator(!animated);
+        postDelayed(hideScrollingIndicatorRunnable, sScrollIndicatorFlashDuration);
+    }
+
+    protected void showScrollingIndicator(boolean immediately) {
+        mShouldShowScrollIndicator = true;
+        mShouldShowScrollIndicatorImmediately = true;
+        if (getChildCount() <= 1) return;
+        if (!isScrollingIndicatorEnabled()) return;
+
+        mShouldShowScrollIndicator = false;
+        getScrollingIndicator();
+        if (mScrollIndicator != null) {
+            // Fade the indicator in
+            updateScrollingIndicatorPosition();
+            mScrollIndicator.setVisibility(View.VISIBLE);
+            cancelScrollingIndicatorAnimations();
+            if (immediately) {
+                mScrollIndicator.setAlpha(1f);
+            } else {
+                mScrollIndicatorAnimator = ObjectAnimator.ofFloat(mScrollIndicator, "alpha", 1f);
+                mScrollIndicatorAnimator.setDuration(sScrollIndicatorFadeInDuration);
+                mScrollIndicatorAnimator.start();
+            }
+        }
+    }
+
+    protected void cancelScrollingIndicatorAnimations() {
+        if (mScrollIndicatorAnimator != null) {
+            mScrollIndicatorAnimator.cancel();
+        }
+    }
+
+    protected void hideScrollingIndicator(boolean immediately) {
+        if (getChildCount() <= 1) return;
+        if (!isScrollingIndicatorEnabled()) return;
+
+        getScrollingIndicator();
+        if (mScrollIndicator != null) {
+            // Fade the indicator out
+            updateScrollingIndicatorPosition();
+            cancelScrollingIndicatorAnimations();
+            if (immediately) {
+                mScrollIndicator.setVisibility(View.INVISIBLE);
+                mScrollIndicator.setAlpha(0f);
+            } else {
+                mScrollIndicatorAnimator = ObjectAnimator.ofFloat(mScrollIndicator, "alpha", 0f);
+                mScrollIndicatorAnimator.setDuration(sScrollIndicatorFadeOutDuration);
+                mScrollIndicatorAnimator.addListener(new AnimatorListenerAdapter() {
+                    private boolean cancelled = false;
+                    @Override
+                    public void onAnimationCancel(android.animation.Animator animation) {
+                        cancelled = true;
+                    }
+                    @Override
+                    public void onAnimationEnd(Animator animation) {
+                        if (!cancelled) {
+                            mScrollIndicator.setVisibility(View.INVISIBLE);
+                        }
+                    }
+                });
+                mScrollIndicatorAnimator.start();
+            }
+        }
+    }
+
+    /**
+     * To be overridden by subclasses to determine whether the scroll indicator should stretch to
+     * fill its space on the track or not.
+     */
+    protected boolean hasElasticScrollIndicator() {
+        return true;
+    }
+
+    private void updateScrollingIndicator() {
+        if (getChildCount() <= 1) return;
+        if (!isScrollingIndicatorEnabled()) return;
+
+        getScrollingIndicator();
+        if (mScrollIndicator != null) {
+            updateScrollingIndicatorPosition();
+        }
+        if (mShouldShowScrollIndicator) {
+            showScrollingIndicator(mShouldShowScrollIndicatorImmediately);
+        }
+    }
+
+    private void updateScrollingIndicatorPosition() {
+        if (!isScrollingIndicatorEnabled()) return;
+        if (mScrollIndicator == null) return;
+        int numPages = getChildCount();
+        int pageWidth = getViewportWidth();
+        int lastChildIndex = Math.max(0, getChildCount() - 1);
+        int maxScrollX = getChildOffset(lastChildIndex) - getRelativeChildOffset(lastChildIndex);
+        int trackWidth = pageWidth - mScrollIndicatorPaddingLeft - mScrollIndicatorPaddingRight;
+        int indicatorWidth = mScrollIndicator.getMeasuredWidth() -
+                mScrollIndicator.getPaddingLeft() - mScrollIndicator.getPaddingRight();
+
+        float offset = Math.max(0f, Math.min(1f, (float) getScrollX() / maxScrollX));
+        int indicatorSpace = trackWidth / numPages;
+        int indicatorPos = (int) (offset * (trackWidth - indicatorSpace)) + mScrollIndicatorPaddingLeft;
+        if (hasElasticScrollIndicator()) {
+            if (mScrollIndicator.getMeasuredWidth() != indicatorSpace) {
+                mScrollIndicator.getLayoutParams().width = indicatorSpace;
+                mScrollIndicator.requestLayout();
+            }
+        } else {
+            int indicatorCenterOffset = indicatorSpace / 2 - indicatorWidth / 2;
+            indicatorPos += indicatorCenterOffset;
+        }
+        mScrollIndicator.setTranslationX(indicatorPos);
+    }
+
+    // Animate the drag view back to the original position
+    void animateDragViewToOriginalPosition() {
+        if (mDragView != null) {
+            AnimatorSet anim = new AnimatorSet();
+            anim.setDuration(REORDERING_DROP_REPOSITION_DURATION);
+            anim.playTogether(
+                    ObjectAnimator.ofFloat(mDragView, "translationX", 0f),
+                    ObjectAnimator.ofFloat(mDragView, "translationY", 0f));
+            anim.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    onPostReorderingAnimationCompleted();
+                }
+            });
+            anim.start();
+        }
+    }
+
+    // "Zooms out" the PagedView to reveal more side pages
+    protected boolean zoomOut() {
+        if (mZoomInOutAnim != null && mZoomInOutAnim.isRunning()) {
+            mZoomInOutAnim.cancel();
+        }
+
+        if (!(getScaleX() < 1f || getScaleY() < 1f)) {
+            mZoomInOutAnim = new AnimatorSet();
+            mZoomInOutAnim.setDuration(REORDERING_ZOOM_IN_OUT_DURATION);
+            mZoomInOutAnim.playTogether(
+                    ObjectAnimator.ofFloat(this, "scaleX", mMinScale),
+                    ObjectAnimator.ofFloat(this, "scaleY", mMinScale));
+            mZoomInOutAnim.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationStart(Animator animation) {
+                    // Show the delete drop target
+                    if (mDeleteDropTarget != null) {
+                        mDeleteDropTarget.setVisibility(View.VISIBLE);
+                        mDeleteDropTarget.animate().alpha(1f)
+                            .setDuration(REORDERING_DELETE_DROP_TARGET_FADE_DURATION)
+                            .setListener(new AnimatorListenerAdapter() {
+                                @Override
+                                public void onAnimationStart(Animator animation) {
+                                    mDeleteDropTarget.setAlpha(0f);
+                                }
+                            });
+                    }
+                }
+            });
+            mZoomInOutAnim.start();
+            return true;
+        }
+        return false;
+    }
+
+    protected void onStartReordering() {
+        if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+            announceForAccessibility(mContext.getString(
+                    R.string.keyguard_accessibility_widget_reorder_start));
+        }
+
+        // Set the touch state to reordering (allows snapping to pages, dragging a child, etc.)
+        mTouchState = TOUCH_STATE_REORDERING;
+        mIsReordering = true;
+
+        // Mark all the non-widget pages as invisible
+        getVisiblePages(mTempVisiblePagesRange);
+        boundByReorderablePages(true, mTempVisiblePagesRange);
+        for (int i = 0; i < getPageCount(); ++i) {
+            if (i < mTempVisiblePagesRange[0] || i > mTempVisiblePagesRange[1]) {
+                getPageAt(i).setAlpha(0f);
+            }
+        }
+
+        // We must invalidate to trigger a redraw to update the layers such that the drag view
+        // is always drawn on top
+        invalidate();
+    }
+
+    private void onPostReorderingAnimationCompleted() {
+        // Trigger the callback when reordering has settled
+        --mPostReorderingPreZoomInRemainingAnimationCount;
+        if (mPostReorderingPreZoomInRunnable != null &&
+                mPostReorderingPreZoomInRemainingAnimationCount == 0) {
+            mPostReorderingPreZoomInRunnable.run();
+            mPostReorderingPreZoomInRunnable = null;
+        }
+    }
+
+    protected void onEndReordering() {
+        if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+            announceForAccessibility(mContext.getString(
+                    R.string.keyguard_accessibility_widget_reorder_end));
+        }
+        mIsReordering = false;
+
+        // Mark all the non-widget pages as visible again
+        getVisiblePages(mTempVisiblePagesRange);
+        boundByReorderablePages(true, mTempVisiblePagesRange);
+        for (int i = 0; i < getPageCount(); ++i) {
+            if (i < mTempVisiblePagesRange[0] || i > mTempVisiblePagesRange[1]) {
+                getPageAt(i).setAlpha(1f);
+            }
+        }
+    }
+
+    public boolean startReordering() {
+        int dragViewIndex = getPageNearestToCenterOfScreen();
+        mTempVisiblePagesRange[0] = 0;
+        mTempVisiblePagesRange[1] = getPageCount() - 1;
+        boundByReorderablePages(true, mTempVisiblePagesRange);
+        mReorderingStarted = true;
+
+        // Check if we are within the reordering range
+        if (mTempVisiblePagesRange[0] <= dragViewIndex &&
+                dragViewIndex <= mTempVisiblePagesRange[1]) {
+            if (zoomOut()) {
+                // Find the drag view under the pointer
+                mDragView = getChildAt(dragViewIndex);
+
+                onStartReordering();
+            }
+            return true;
+        }
+        return false;
+    }
+
+    boolean isReordering(boolean testTouchState) {
+        boolean state = mIsReordering;
+        if (testTouchState) {
+            state &= (mTouchState == TOUCH_STATE_REORDERING);
+        }
+        return state;
+    }
+    void endReordering() {
+        // For simplicity, we call endReordering sometimes even if reordering was never started.
+        // In that case, we don't want to do anything.
+        if (!mReorderingStarted) return;
+        mReorderingStarted = false;
+
+        // If we haven't flung-to-delete the current child, then we just animate the drag view
+        // back into position
+        final Runnable onCompleteRunnable = new Runnable() {
+            @Override
+            public void run() {
+                onEndReordering();
+            }
+        };
+        if (!mDeferringForDelete) {
+            mPostReorderingPreZoomInRunnable = new Runnable() {
+                public void run() {
+                    zoomIn(onCompleteRunnable);
+                };
+            };
+
+            mPostReorderingPreZoomInRemainingAnimationCount =
+                    NUM_ANIMATIONS_RUNNING_BEFORE_ZOOM_OUT;
+            // Snap to the current page
+            snapToPage(indexOfChild(mDragView), 0);
+            // Animate the drag view back to the front position
+            animateDragViewToOriginalPosition();
+        } else {
+            // Handled in post-delete-animation-callbacks
+        }
+    }
+
+    // "Zooms in" the PagedView to highlight the current page
+    protected boolean zoomIn(final Runnable onCompleteRunnable) {
+        if (mZoomInOutAnim != null && mZoomInOutAnim.isRunning()) {
+            mZoomInOutAnim.cancel();
+        }
+        if (getScaleX() < 1f || getScaleY() < 1f) {
+            mZoomInOutAnim = new AnimatorSet();
+            mZoomInOutAnim.setDuration(REORDERING_ZOOM_IN_OUT_DURATION);
+            mZoomInOutAnim.playTogether(
+                    ObjectAnimator.ofFloat(this, "scaleX", 1f),
+                    ObjectAnimator.ofFloat(this, "scaleY", 1f));
+            mZoomInOutAnim.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationStart(Animator animation) {
+                    // Hide the delete drop target
+                    if (mDeleteDropTarget != null) {
+                        mDeleteDropTarget.animate().alpha(0f)
+                            .setDuration(REORDERING_DELETE_DROP_TARGET_FADE_DURATION)
+                            .setListener(new AnimatorListenerAdapter() {
+                                @Override
+                                public void onAnimationEnd(Animator animation) {
+                                    mDeleteDropTarget.setVisibility(View.GONE);
+                                }
+                            });
+                    }
+                }
+                @Override
+                public void onAnimationCancel(Animator animation) {
+                    mDragView = null;
+                }
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    mDragView = null;
+                    if (onCompleteRunnable != null) {
+                        onCompleteRunnable.run();
+                    }
+                }
+            });
+            mZoomInOutAnim.start();
+            return true;
+        } else {
+            if (onCompleteRunnable != null) {
+                onCompleteRunnable.run();
+            }
+        }
+        return false;
+    }
+
+    /*
+     * Flinging to delete - IN PROGRESS
+     */
+    private PointF isFlingingToDelete() {
+        ViewConfiguration config = ViewConfiguration.get(getContext());
+        mVelocityTracker.computeCurrentVelocity(1000, config.getScaledMaximumFlingVelocity());
+
+        if (mVelocityTracker.getYVelocity() < mFlingToDeleteThresholdVelocity) {
+            // Do a quick dot product test to ensure that we are flinging upwards
+            PointF vel = new PointF(mVelocityTracker.getXVelocity(),
+                    mVelocityTracker.getYVelocity());
+            PointF upVec = new PointF(0f, -1f);
+            float theta = (float) Math.acos(((vel.x * upVec.x) + (vel.y * upVec.y)) /
+                    (vel.length() * upVec.length()));
+            if (theta <= Math.toRadians(FLING_TO_DELETE_MAX_FLING_DEGREES)) {
+                return vel;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Creates an animation from the current drag view along its current velocity vector.
+     * For this animation, the alpha runs for a fixed duration and we update the position
+     * progressively.
+     */
+    private static class FlingAlongVectorAnimatorUpdateListener implements AnimatorUpdateListener {
+        private View mDragView;
+        private PointF mVelocity;
+        private Rect mFrom;
+        private long mPrevTime;
+        private float mFriction;
+
+        private final TimeInterpolator mAlphaInterpolator = new DecelerateInterpolator(0.75f);
+
+        public FlingAlongVectorAnimatorUpdateListener(View dragView, PointF vel, Rect from,
+                long startTime, float friction) {
+            mDragView = dragView;
+            mVelocity = vel;
+            mFrom = from;
+            mPrevTime = startTime;
+            mFriction = 1f - (mDragView.getResources().getDisplayMetrics().density * friction);
+        }
+
+        @Override
+        public void onAnimationUpdate(ValueAnimator animation) {
+            float t = ((Float) animation.getAnimatedValue()).floatValue();
+            long curTime = AnimationUtils.currentAnimationTimeMillis();
+
+            mFrom.left += (mVelocity.x * (curTime - mPrevTime) / 1000f);
+            mFrom.top += (mVelocity.y * (curTime - mPrevTime) / 1000f);
+
+            mDragView.setTranslationX(mFrom.left);
+            mDragView.setTranslationY(mFrom.top);
+            mDragView.setAlpha(1f - mAlphaInterpolator.getInterpolation(t));
+
+            mVelocity.x *= mFriction;
+            mVelocity.y *= mFriction;
+            mPrevTime = curTime;
+        }
+    };
+
+    private Runnable createPostDeleteAnimationRunnable(final View dragView) {
+        return new Runnable() {
+            @Override
+            public void run() {
+                int dragViewIndex = indexOfChild(dragView);
+
+                // For each of the pages around the drag view, animate them from the previous
+                // position to the new position in the layout (as a result of the drag view moving
+                // in the layout)
+                // NOTE: We can make an assumption here because we have side-bound pages that we
+                //       will always have pages to animate in from the left
+                getVisiblePages(mTempVisiblePagesRange);
+                boundByReorderablePages(true, mTempVisiblePagesRange);
+                boolean isLastWidgetPage = (mTempVisiblePagesRange[0] == mTempVisiblePagesRange[1]);
+                boolean slideFromLeft = (isLastWidgetPage ||
+                        dragViewIndex > mTempVisiblePagesRange[0]);
+
+                // Setup the scroll to the correct page before we swap the views
+                if (slideFromLeft) {
+                    snapToPageImmediately(dragViewIndex - 1);
+                }
+
+                int firstIndex = (isLastWidgetPage ? 0 : mTempVisiblePagesRange[0]);
+                int lastIndex = Math.min(mTempVisiblePagesRange[1], getPageCount() - 1);
+                int lowerIndex = (slideFromLeft ? firstIndex : dragViewIndex + 1 );
+                int upperIndex = (slideFromLeft ? dragViewIndex - 1 : lastIndex);
+                ArrayList<Animator> animations = new ArrayList<Animator>();
+                for (int i = lowerIndex; i <= upperIndex; ++i) {
+                    View v = getChildAt(i);
+                    // dragViewIndex < pageUnderPointIndex, so after we remove the
+                    // drag view all subsequent views to pageUnderPointIndex will
+                    // shift down.
+                    int oldX = 0;
+                    int newX = 0;
+                    if (slideFromLeft) {
+                        if (i == 0) {
+                            // Simulate the page being offscreen with the page spacing
+                            oldX = getViewportOffsetX() + getChildOffset(i) - getChildWidth(i)
+                                    - mPageSpacing;
+                        } else {
+                            oldX = getViewportOffsetX() + getChildOffset(i - 1);
+                        }
+                        newX = getViewportOffsetX() + getChildOffset(i);
+                    } else {
+                        oldX = getChildOffset(i) - getChildOffset(i - 1);
+                        newX = 0;
+                    }
+
+                    // Animate the view translation from its old position to its new
+                    // position
+                    AnimatorSet anim = (AnimatorSet) v.getTag();
+                    if (anim != null) {
+                        anim.cancel();
+                    }
+
+                    // Note: Hacky, but we want to skip any optimizations to not draw completely
+                    // hidden views
+                    v.setAlpha(Math.max(v.getAlpha(), 0.01f));
+                    v.setTranslationX(oldX - newX);
+                    anim = new AnimatorSet();
+                    anim.playTogether(
+                            ObjectAnimator.ofFloat(v, "translationX", 0f),
+                            ObjectAnimator.ofFloat(v, "alpha", 1f));
+                    animations.add(anim);
+                    v.setTag(anim);
+                }
+
+                AnimatorSet slideAnimations = new AnimatorSet();
+                slideAnimations.playTogether(animations);
+                slideAnimations.setDuration(DELETE_SLIDE_IN_SIDE_PAGE_DURATION);
+                slideAnimations.addListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationEnd(Animator animation) {
+                        final Runnable onCompleteRunnable = new Runnable() {
+                            @Override
+                            public void run() {
+                                mDeferringForDelete = false;
+                                onEndReordering();
+                                onRemoveViewAnimationCompleted();
+                            }
+                        };
+                        zoomIn(onCompleteRunnable);
+                    }
+                });
+                slideAnimations.start();
+
+                removeView(dragView);
+                onRemoveView(dragView, true);
+            }
+        };
+    }
+
+    public void onFlingToDelete(PointF vel) {
+        final long startTime = AnimationUtils.currentAnimationTimeMillis();
+
+        // NOTE: Because it takes time for the first frame of animation to actually be
+        // called and we expect the animation to be a continuation of the fling, we have
+        // to account for the time that has elapsed since the fling finished.  And since
+        // we don't have a startDelay, we will always get call to update when we call
+        // start() (which we want to ignore).
+        final TimeInterpolator tInterpolator = new TimeInterpolator() {
+            private int mCount = -1;
+            private long mStartTime;
+            private float mOffset;
+            /* Anonymous inner class ctor */ {
+                mStartTime = startTime;
+            }
+
+            @Override
+            public float getInterpolation(float t) {
+                if (mCount < 0) {
+                    mCount++;
+                } else if (mCount == 0) {
+                    mOffset = Math.min(0.5f, (float) (AnimationUtils.currentAnimationTimeMillis() -
+                            mStartTime) / FLING_TO_DELETE_FADE_OUT_DURATION);
+                    mCount++;
+                }
+                return Math.min(1f, mOffset + t);
+            }
+        };
+
+        final Rect from = new Rect();
+        final View dragView = mDragView;
+        from.left = (int) dragView.getTranslationX();
+        from.top = (int) dragView.getTranslationY();
+        AnimatorUpdateListener updateCb = new FlingAlongVectorAnimatorUpdateListener(dragView, vel,
+                from, startTime, FLING_TO_DELETE_FRICTION);
+
+        final Runnable onAnimationEndRunnable = createPostDeleteAnimationRunnable(dragView);
+
+        // Create and start the animation
+        ValueAnimator mDropAnim = new ValueAnimator();
+        mDropAnim.setInterpolator(tInterpolator);
+        mDropAnim.setDuration(FLING_TO_DELETE_FADE_OUT_DURATION);
+        mDropAnim.setFloatValues(0f, 1f);
+        mDropAnim.addUpdateListener(updateCb);
+        mDropAnim.addListener(new AnimatorListenerAdapter() {
+            public void onAnimationEnd(Animator animation) {
+                onAnimationEndRunnable.run();
+            }
+        });
+        mDropAnim.start();
+        mDeferringForDelete = true;
+    }
+
+    /* Drag to delete */
+    private boolean isHoveringOverDeleteDropTarget(int x, int y) {
+        if (mDeleteDropTarget != null) {
+            mAltTmpRect.set(0, 0, 0, 0);
+            View parent = (View) mDeleteDropTarget.getParent();
+            if (parent != null) {
+                parent.getGlobalVisibleRect(mAltTmpRect);
+            }
+            mDeleteDropTarget.getGlobalVisibleRect(mTmpRect);
+            mTmpRect.offset(-mAltTmpRect.left, -mAltTmpRect.top);
+            return mTmpRect.contains(x, y);
+        }
+        return false;
+    }
+
+    protected void setPageHoveringOverDeleteDropTarget(int viewIndex, boolean isHovering) {}
+
+    private void onDropToDelete() {
+        final View dragView = mDragView;
+
+        final float toScale = 0f;
+        final float toAlpha = 0f;
+
+        // Create and start the complex animation
+        ArrayList<Animator> animations = new ArrayList<Animator>();
+        AnimatorSet motionAnim = new AnimatorSet();
+        motionAnim.setInterpolator(new DecelerateInterpolator(2));
+        motionAnim.playTogether(
+                ObjectAnimator.ofFloat(dragView, "scaleX", toScale),
+                ObjectAnimator.ofFloat(dragView, "scaleY", toScale));
+        animations.add(motionAnim);
+
+        AnimatorSet alphaAnim = new AnimatorSet();
+        alphaAnim.setInterpolator(new LinearInterpolator());
+        alphaAnim.playTogether(
+                ObjectAnimator.ofFloat(dragView, "alpha", toAlpha));
+        animations.add(alphaAnim);
+
+        final Runnable onAnimationEndRunnable = createPostDeleteAnimationRunnable(dragView);
+
+        AnimatorSet anim = new AnimatorSet();
+        anim.playTogether(animations);
+        anim.setDuration(DRAG_TO_DELETE_FADE_OUT_DURATION);
+        anim.addListener(new AnimatorListenerAdapter() {
+            public void onAnimationEnd(Animator animation) {
+                onAnimationEndRunnable.run();
+            }
+        });
+        anim.start();
+
+        mDeferringForDelete = true;
+    }
+
+    /* Accessibility */
+    @Override
+    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfo(info);
+        info.setScrollable(getPageCount() > 1);
+        if (getCurrentPage() < getPageCount() - 1) {
+            info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
+        }
+        if (getCurrentPage() > 0) {
+            info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
+        }
+    }
+
+    @Override
+    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+        super.onInitializeAccessibilityEvent(event);
+        event.setScrollable(true);
+        if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
+            event.setFromIndex(mCurrentPage);
+            event.setToIndex(mCurrentPage);
+            event.setItemCount(getChildCount());
+        }
+    }
+
+    @Override
+    public boolean performAccessibilityAction(int action, Bundle arguments) {
+        if (super.performAccessibilityAction(action, arguments)) {
+            return true;
+        }
+        switch (action) {
+            case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: {
+                if (getCurrentPage() < getPageCount() - 1) {
+                    scrollRight();
+                    return true;
+                }
+            } break;
+            case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: {
+                if (getCurrentPage() > 0) {
+                    scrollLeft();
+                    return true;
+                }
+            } break;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean onHoverEvent(android.view.MotionEvent event) {
+        return true;
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/SecurityMessageDisplay.java b/packages/Keyguard/src/com/android/keyguard/SecurityMessageDisplay.java
new file mode 100644
index 0000000..e2f91e3
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/SecurityMessageDisplay.java
@@ -0,0 +1,31 @@
+/*
+ * 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.keyguard;
+
+public interface SecurityMessageDisplay {
+    public void setMessage(CharSequence msg, boolean important);
+
+    public void setMessage(int resId, boolean important);
+
+    public void setMessage(int resId, boolean important, Object... formatArgs);
+
+    public void setTimeout(int timeout_ms);
+
+    public void showBouncer(int animationDuration);
+
+    public void hideBouncer(int animationDuration);
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/SlidingChallengeLayout.java b/packages/Keyguard/src/com/android/keyguard/SlidingChallengeLayout.java
new file mode 100644
index 0000000..05b35a1
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/SlidingChallengeLayout.java
@@ -0,0 +1,1242 @@
+/*
+ * 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.keyguard;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.util.FloatProperty;
+import android.util.Log;
+import android.util.Property;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityManager;
+import android.view.animation.Interpolator;
+import android.widget.Scroller;
+
+/**
+ * This layout handles interaction with the sliding security challenge views
+ * that overlay/resize other keyguard contents.
+ */
+public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout {
+    private static final String TAG = "SlidingChallengeLayout";
+    private static final boolean DEBUG = false;
+
+    // The drag handle is measured in dp above & below the top edge of the
+    // challenge view; these parameters change based on whether the challenge 
+    // is open or closed.
+    private static final int DRAG_HANDLE_CLOSED_ABOVE = 8; // dp
+    private static final int DRAG_HANDLE_CLOSED_BELOW = 0; // dp
+    private static final int DRAG_HANDLE_OPEN_ABOVE = 8; // dp
+    private static final int DRAG_HANDLE_OPEN_BELOW = 0; // dp
+
+    private static final int HANDLE_ANIMATE_DURATION = 250; // ms
+
+    // Drawn to show the drag handle in closed state; crossfades to the challenge view
+    // when challenge is fully visible
+    private boolean mEdgeCaptured;
+
+    private DisplayMetrics mDisplayMetrics;
+
+    // Initialized during measurement from child layoutparams
+    private View mExpandChallengeView;
+    private KeyguardSecurityContainer mChallengeView;
+    private View mScrimView;
+    private View mWidgetsView;
+
+    // Range: 0 (fully hidden) to 1 (fully visible)
+    private float mChallengeOffset = 1.f;
+    private boolean mChallengeShowing = true;
+    private boolean mChallengeShowingTargetState = true;
+    private boolean mWasChallengeShowing = true;
+    private boolean mIsBouncing = false;
+
+    private final Scroller mScroller;
+    private ObjectAnimator mFader;
+    private int mScrollState;
+    private OnChallengeScrolledListener mScrollListener;
+    private OnBouncerStateChangedListener mBouncerListener;
+
+    public static final int SCROLL_STATE_IDLE = 0;
+    public static final int SCROLL_STATE_DRAGGING = 1;
+    public static final int SCROLL_STATE_SETTLING = 2;
+    public static final int SCROLL_STATE_FADING = 3;
+
+    private static final int CHALLENGE_FADE_OUT_DURATION = 100;
+    private static final int CHALLENGE_FADE_IN_DURATION = 160;
+
+    private static final int MAX_SETTLE_DURATION = 600; // ms
+
+    // ID of the pointer in charge of a current drag
+    private int mActivePointerId = INVALID_POINTER;
+    private static final int INVALID_POINTER = -1;
+
+    // True if the user is currently dragging the slider
+    private boolean mDragging;
+    // True if the user may not drag until a new gesture begins
+    private boolean mBlockDrag;
+
+    private VelocityTracker mVelocityTracker;
+    private int mMinVelocity;
+    private int mMaxVelocity;
+    private float mGestureStartX, mGestureStartY; // where did you first touch the screen?
+    private int mGestureStartChallengeBottom; // where was the challenge at that time?
+
+    private int mDragHandleClosedBelow; // handle hitrect extension into the challenge view
+    private int mDragHandleClosedAbove; // extend the handle's hitrect this far above the line
+    private int mDragHandleOpenBelow; // handle hitrect extension into the challenge view
+    private int mDragHandleOpenAbove; // extend the handle's hitrect this far above the line
+
+    private int mDragHandleEdgeSlop;
+    private int mChallengeBottomBound; // Number of pixels from the top of the challenge view
+                                       // that should remain on-screen
+
+    private int mTouchSlop;
+    private int mTouchSlopSquare;
+
+    float mHandleAlpha;
+    float mFrameAlpha;
+    float mFrameAnimationTarget = Float.MIN_VALUE;
+    private ObjectAnimator mHandleAnimation;
+    private ObjectAnimator mFrameAnimation;
+
+    private boolean mHasGlowpad;
+
+    // We have an internal and external version, and we and them together.
+    private boolean mChallengeInteractiveExternal = true;
+    private boolean mChallengeInteractiveInternal = true;
+
+    static final Property<SlidingChallengeLayout, Float> HANDLE_ALPHA =
+            new FloatProperty<SlidingChallengeLayout>("handleAlpha") {
+        @Override
+        public void setValue(SlidingChallengeLayout view, float value) {
+            view.mHandleAlpha = value;
+            view.invalidate();
+        }
+
+        @Override
+        public Float get(SlidingChallengeLayout view) {
+            return view.mHandleAlpha;
+        }
+    };
+
+    // True if at least one layout pass has happened since the view was attached.
+    private boolean mHasLayout;
+
+    private static final Interpolator sMotionInterpolator = new Interpolator() {
+        public float getInterpolation(float t) {
+            t -= 1.0f;
+            return t * t * t * t * t + 1.0f;
+        }
+    };
+
+    private static final Interpolator sHandleFadeInterpolator = new Interpolator() {
+        public float getInterpolation(float t) {
+            return t * t;
+        }
+    };
+
+    private final Runnable mEndScrollRunnable = new Runnable () {
+        public void run() {
+            completeChallengeScroll();
+        }
+    };
+
+    private final OnClickListener mScrimClickListener = new OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            hideBouncer();
+        }
+    };
+
+    private final OnClickListener mExpandChallengeClickListener = new OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            if (!isChallengeShowing()) {
+                showChallenge(true);
+            }
+        }
+    };
+
+    /**
+     * Listener interface that reports changes in scroll state of the challenge area.
+     */
+    public interface OnChallengeScrolledListener {
+        /**
+         * The scroll state itself changed.
+         *
+         * <p>scrollState will be one of the following:</p>
+         *
+         * <ul>
+         * <li><code>SCROLL_STATE_IDLE</code> - The challenge area is stationary.</li>
+         * <li><code>SCROLL_STATE_DRAGGING</code> - The user is actively dragging
+         * the challenge area.</li>
+         * <li><code>SCROLL_STATE_SETTLING</code> - The challenge area is animating
+         * into place.</li>
+         * </ul>
+         *
+         * <p>Do not perform expensive operations (e.g. layout)
+         * while the scroll state is not <code>SCROLL_STATE_IDLE</code>.</p>
+         *
+         * @param scrollState The new scroll state of the challenge area.
+         */
+        public void onScrollStateChanged(int scrollState);
+
+        /**
+         * The precise position of the challenge area has changed.
+         *
+         * <p>NOTE: It is NOT safe to modify layout or call any View methods that may
+         * result in a requestLayout anywhere in your view hierarchy as a result of this call.
+         * It may be called during drawing.</p>
+         *
+         * @param scrollPosition New relative position of the challenge area.
+         *                       1.f = fully visible/ready to be interacted with.
+         *                       0.f = fully invisible/inaccessible to the user.
+         * @param challengeTop Position of the top edge of the challenge view in px in the
+         *                     SlidingChallengeLayout's coordinate system.
+         */
+        public void onScrollPositionChanged(float scrollPosition, int challengeTop);
+    }
+
+    public SlidingChallengeLayout(Context context) {
+        this(context, null);
+    }
+
+    public SlidingChallengeLayout(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public SlidingChallengeLayout(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        mScroller = new Scroller(context, sMotionInterpolator);
+
+        final ViewConfiguration vc = ViewConfiguration.get(context);
+        mMinVelocity = vc.getScaledMinimumFlingVelocity();
+        mMaxVelocity = vc.getScaledMaximumFlingVelocity();
+
+        final Resources res = getResources();
+        mDragHandleEdgeSlop = res.getDimensionPixelSize(R.dimen.kg_edge_swipe_region_size);
+
+        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
+        mTouchSlopSquare = mTouchSlop * mTouchSlop;
+
+        mDisplayMetrics = res.getDisplayMetrics();
+        final float density = mDisplayMetrics.density;
+
+        // top half of the lock icon, plus another 25% to be sure
+        mDragHandleClosedAbove = (int) (DRAG_HANDLE_CLOSED_ABOVE * density + 0.5f);
+        mDragHandleClosedBelow = (int) (DRAG_HANDLE_CLOSED_BELOW * density + 0.5f);
+        mDragHandleOpenAbove = (int) (DRAG_HANDLE_OPEN_ABOVE * density + 0.5f);
+        mDragHandleOpenBelow = (int) (DRAG_HANDLE_OPEN_BELOW * density + 0.5f);
+
+        // how much space to account for in the handle when closed
+        mChallengeBottomBound = res.getDimensionPixelSize(R.dimen.kg_widget_pager_bottom_padding);
+
+        setWillNotDraw(false);
+        setSystemUiVisibility(SYSTEM_UI_FLAG_LAYOUT_STABLE);
+    }
+
+    public void setHandleAlpha(float alpha) {
+        if (mExpandChallengeView != null) {
+            mExpandChallengeView.setAlpha(alpha);
+        }
+    }
+
+    public void setChallengeInteractive(boolean interactive) {
+        mChallengeInteractiveExternal = interactive;
+        if (mExpandChallengeView != null) {
+            mExpandChallengeView.setEnabled(interactive);
+        }
+    }
+
+    void animateHandle(boolean visible) {
+        if (mHandleAnimation != null) {
+            mHandleAnimation.cancel();
+            mHandleAnimation = null;
+        }
+        final float targetAlpha = visible ? 1.f : 0.f;
+        if (targetAlpha == mHandleAlpha) {
+            return;
+        }
+        mHandleAnimation = ObjectAnimator.ofFloat(this, HANDLE_ALPHA, targetAlpha);
+        mHandleAnimation.setInterpolator(sHandleFadeInterpolator);
+        mHandleAnimation.setDuration(HANDLE_ANIMATE_DURATION);
+        mHandleAnimation.start();
+    }
+
+    private void sendInitialListenerUpdates() {
+        if (mScrollListener != null) {
+            int challengeTop = mChallengeView != null ? mChallengeView.getTop() : 0;
+            mScrollListener.onScrollPositionChanged(mChallengeOffset, challengeTop);
+            mScrollListener.onScrollStateChanged(mScrollState);
+        }
+    }
+
+    public void setOnChallengeScrolledListener(OnChallengeScrolledListener listener) {
+        mScrollListener = listener;
+        if (mHasLayout) {
+            sendInitialListenerUpdates();
+        }
+    }
+
+    public void setOnBouncerStateChangedListener(OnBouncerStateChangedListener listener) {
+        mBouncerListener = listener;
+    }
+
+    @Override
+    public void onAttachedToWindow() {
+        super.onAttachedToWindow();
+
+        mHasLayout = false;
+    }
+
+    @Override
+    public void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+
+        removeCallbacks(mEndScrollRunnable);
+        mHasLayout = false;
+    }
+
+    @Override
+    public void requestChildFocus(View child, View focused) {
+        if (mIsBouncing && child != mChallengeView) {
+            // Clear out of the bouncer if the user tries to move focus outside of
+            // the security challenge view.
+            hideBouncer();
+        }
+        super.requestChildFocus(child, focused);
+    }
+
+    // We want the duration of the page snap animation to be influenced by the distance that
+    // the screen has to travel, however, we don't want this duration to be effected in a
+    // purely linear fashion. Instead, we use this method to moderate the effect that the distance
+    // of travel has on the overall snap duration.
+    float distanceInfluenceForSnapDuration(float f) {
+        f -= 0.5f; // center the values about 0.
+        f *= 0.3f * Math.PI / 2.0f;
+        return (float) Math.sin(f);
+    }
+
+    void setScrollState(int state) {
+        if (mScrollState != state) {
+            mScrollState = state;
+
+            animateHandle(state == SCROLL_STATE_IDLE && !mChallengeShowing);
+            if (mScrollListener != null) {
+                mScrollListener.onScrollStateChanged(state);
+            }
+        }
+    }
+
+    void completeChallengeScroll() {
+        setChallengeShowing(mChallengeShowingTargetState);
+        mChallengeOffset = mChallengeShowing ? 1.f : 0.f;
+        setScrollState(SCROLL_STATE_IDLE);
+        mChallengeInteractiveInternal = true;
+        mChallengeView.setLayerType(LAYER_TYPE_NONE, null);
+    }
+
+    void setScrimView(View scrim) {
+        if (mScrimView != null) {
+            mScrimView.setOnClickListener(null);
+        }
+        mScrimView = scrim;
+        mScrimView.setVisibility(mIsBouncing ? VISIBLE : GONE);
+        mScrimView.setFocusable(true);
+        mScrimView.setOnClickListener(mScrimClickListener);
+    }
+
+    /**
+     * Animate the bottom edge of the challenge view to the given position.
+     *
+     * @param y desired final position for the bottom edge of the challenge view in px
+     * @param velocity velocity in
+     */
+    void animateChallengeTo(int y, int velocity) {
+        if (mChallengeView == null) {
+            // Nothing to do.
+            return;
+        }
+
+        cancelTransitionsInProgress();
+
+        mChallengeInteractiveInternal = false;
+        mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null);
+        final int sy = mChallengeView.getBottom();
+        final int dy = y - sy;
+        if (dy == 0) {
+            completeChallengeScroll();
+            return;
+        }
+
+        setScrollState(SCROLL_STATE_SETTLING);
+
+        final int childHeight = mChallengeView.getHeight();
+        final int halfHeight = childHeight / 2;
+        final float distanceRatio = Math.min(1f, 1.0f * Math.abs(dy) / childHeight);
+        final float distance = halfHeight + halfHeight *
+                distanceInfluenceForSnapDuration(distanceRatio);
+
+        int duration = 0;
+        velocity = Math.abs(velocity);
+        if (velocity > 0) {
+            duration = 4 * Math.round(1000 * Math.abs(distance / velocity));
+        } else {
+            final float childDelta = (float) Math.abs(dy) / childHeight;
+            duration = (int) ((childDelta + 1) * 100);
+        }
+        duration = Math.min(duration, MAX_SETTLE_DURATION);
+
+        mScroller.startScroll(0, sy, 0, dy, duration);
+        postInvalidateOnAnimation();
+    }
+
+    private void setChallengeShowing(boolean showChallenge) {
+        if (mChallengeShowing == showChallenge) {
+            return;
+        }
+        mChallengeShowing = showChallenge;
+
+        if (mExpandChallengeView == null || mChallengeView == null) {
+            // These might not be here yet if we haven't been through layout.
+            // If we haven't, the first layout pass will set everything up correctly
+            // based on mChallengeShowing as set above.
+            return;
+        }
+
+        if (mChallengeShowing) {
+            mExpandChallengeView.setVisibility(View.INVISIBLE);
+            mChallengeView.setVisibility(View.VISIBLE);
+            if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+                mChallengeView.requestAccessibilityFocus();
+                mChallengeView.announceForAccessibility(mContext.getString(
+                        R.string.keyguard_accessibility_unlock_area_expanded));
+            }
+        } else {
+            mExpandChallengeView.setVisibility(View.VISIBLE);
+            mChallengeView.setVisibility(View.INVISIBLE);
+            if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+                mExpandChallengeView.requestAccessibilityFocus();
+                mChallengeView.announceForAccessibility(mContext.getString(
+                        R.string.keyguard_accessibility_unlock_area_collapsed));
+            }
+        }
+    }
+
+    /**
+     * @return true if the challenge is at all visible.
+     */
+    public boolean isChallengeShowing() {
+        return mChallengeShowing;
+    }
+
+    @Override
+    public boolean isChallengeOverlapping() {
+        return mChallengeShowing;
+    }
+
+    @Override
+    public boolean isBouncing() {
+        return mIsBouncing;
+    }
+
+    @Override
+    public int getBouncerAnimationDuration() {
+        return HANDLE_ANIMATE_DURATION;
+    }
+
+    @Override
+    public void showBouncer() {
+        if (mIsBouncing) return;
+        mWasChallengeShowing = mChallengeShowing;
+        mIsBouncing = true;
+        showChallenge(true);
+        if (mScrimView != null) {
+            Animator anim = ObjectAnimator.ofFloat(mScrimView, "alpha", 1f);
+            anim.setDuration(HANDLE_ANIMATE_DURATION);
+            anim.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationStart(Animator animation) {
+                    mScrimView.setVisibility(VISIBLE);
+                }
+            });
+            anim.start();
+        }
+        if (mChallengeView != null) {
+            mChallengeView.showBouncer(HANDLE_ANIMATE_DURATION);
+        }
+
+        if (mBouncerListener != null) {
+            mBouncerListener.onBouncerStateChanged(true);
+        }
+    }
+
+    @Override
+    public void hideBouncer() {
+        if (!mIsBouncing) return;
+        if (!mWasChallengeShowing) showChallenge(false);
+        mIsBouncing = false;
+
+        if (mScrimView != null) {
+            Animator anim = ObjectAnimator.ofFloat(mScrimView, "alpha", 0f);
+            anim.setDuration(HANDLE_ANIMATE_DURATION);
+            anim.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    mScrimView.setVisibility(GONE);
+                }
+            });
+            anim.start();
+        }
+        if (mChallengeView != null) {
+            mChallengeView.hideBouncer(HANDLE_ANIMATE_DURATION);
+        }
+        if (mBouncerListener != null) {
+            mBouncerListener.onBouncerStateChanged(false);
+        }
+    }
+
+    private int getChallengeMargin(boolean expanded) {
+        return expanded && mHasGlowpad ? 0 : mDragHandleEdgeSlop;
+    }
+
+    private float getChallengeAlpha() {
+        float x = mChallengeOffset - 1;
+        return x * x * x + 1.f;
+    }
+
+    @Override
+    public void requestDisallowInterceptTouchEvent(boolean allowIntercept) {
+        // We'll intercept whoever we feel like! ...as long as it isn't a challenge view.
+        // If there are one or more pointers in the challenge view before we take over
+        // touch events, onInterceptTouchEvent will set mBlockDrag.
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        if (mVelocityTracker == null) {
+            mVelocityTracker = VelocityTracker.obtain();
+        }
+        mVelocityTracker.addMovement(ev);
+
+        final int action = ev.getActionMasked();
+        switch (action) {
+            case MotionEvent.ACTION_DOWN:
+                mGestureStartX = ev.getX();
+                mGestureStartY = ev.getY();
+                mBlockDrag = false;
+                break;
+
+            case MotionEvent.ACTION_CANCEL:
+            case MotionEvent.ACTION_UP:
+                resetTouch();
+                break;
+
+            case MotionEvent.ACTION_MOVE:
+                final int count = ev.getPointerCount();
+                for (int i = 0; i < count; i++) {
+                    final float x = ev.getX(i);
+                    final float y = ev.getY(i);
+                    if (!mIsBouncing && mActivePointerId == INVALID_POINTER
+                                && (crossedDragHandle(x, y, mGestureStartY)
+                                || (isInChallengeView(x, y) &&
+                                        mScrollState == SCROLL_STATE_SETTLING))) {
+                        mActivePointerId = ev.getPointerId(i);
+                        mGestureStartX = x;
+                        mGestureStartY = y;
+                        mGestureStartChallengeBottom = getChallengeBottom();
+                        mDragging = true;
+                        mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null);
+                    } else if (mChallengeShowing && isInChallengeView(x, y)) {
+                        mBlockDrag = true;
+                    }
+                }
+                break;
+        }
+
+        if (mBlockDrag || isChallengeInteractionBlocked()) {
+            mActivePointerId = INVALID_POINTER;
+            mDragging = false;
+        }
+
+        return mDragging;
+    }
+
+    private boolean isChallengeInteractionBlocked() {
+        return !mChallengeInteractiveExternal || !mChallengeInteractiveInternal;
+    }
+
+    private void resetTouch() {
+        mVelocityTracker.recycle();
+        mVelocityTracker = null;
+        mActivePointerId = INVALID_POINTER;
+        mDragging = mBlockDrag = false;
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        if (mVelocityTracker == null) {
+            mVelocityTracker = VelocityTracker.obtain();
+        }
+        mVelocityTracker.addMovement(ev);
+
+        final int action = ev.getActionMasked();
+        switch (action) {
+            case MotionEvent.ACTION_DOWN:
+                mBlockDrag = false;
+                mGestureStartX = ev.getX();
+                mGestureStartY = ev.getY();
+                break;
+
+            case MotionEvent.ACTION_CANCEL:
+                if (mDragging && !isChallengeInteractionBlocked()) {
+                    showChallenge(0);
+                }
+                resetTouch();
+                break;
+
+            case MotionEvent.ACTION_POINTER_UP:
+                if (mActivePointerId != ev.getPointerId(ev.getActionIndex())) {
+                    break;
+                }
+            case MotionEvent.ACTION_UP:
+                if (mDragging && !isChallengeInteractionBlocked()) {
+                    mVelocityTracker.computeCurrentVelocity(1000, mMaxVelocity);
+                    showChallenge((int) mVelocityTracker.getYVelocity(mActivePointerId));
+                }
+                resetTouch();
+                break;
+
+            case MotionEvent.ACTION_MOVE:
+                if (!mDragging && !mBlockDrag && !mIsBouncing) {
+                    final int count = ev.getPointerCount();
+                    for (int i = 0; i < count; i++) {
+                        final float x = ev.getX(i);
+                        final float y = ev.getY(i);
+
+                        if ((isInDragHandle(x, y) || crossedDragHandle(x, y, mGestureStartY) ||
+                                (isInChallengeView(x, y) && mScrollState == SCROLL_STATE_SETTLING))
+                                && mActivePointerId == INVALID_POINTER
+                                && !isChallengeInteractionBlocked()) {
+                            mGestureStartX = x;
+                            mGestureStartY = y;
+                            mActivePointerId = ev.getPointerId(i);
+                            mGestureStartChallengeBottom = getChallengeBottom();
+                            mDragging = true;
+                            mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null);
+                            break;
+                        }
+                    }
+                }
+                // Not an else; this can be set above.
+                if (mDragging) {
+                    // No-op if already in this state, but set it here in case we arrived
+                    // at this point from either intercept or the above.
+                    setScrollState(SCROLL_STATE_DRAGGING);
+
+                    final int index = ev.findPointerIndex(mActivePointerId);
+                    if (index < 0) {
+                        // Oops, bogus state. We lost some touch events somewhere.
+                        // Just drop it with no velocity and let things settle.
+                        resetTouch();
+                        showChallenge(0);
+                        return true;
+                    }
+                    final float y = ev.getY(index);
+                    final float pos = Math.min(y - mGestureStartY,
+                            getLayoutBottom() - mChallengeBottomBound);
+
+                    moveChallengeTo(mGestureStartChallengeBottom + (int) pos);
+                }
+                break;
+        }
+        return true;
+    }
+
+    /**
+     * The lifecycle of touch events is subtle and it's very easy to do something
+     * that will cause bugs that will be nasty to track when overriding this method.
+     * Normally one should always override onInterceptTouchEvent instead.
+     *
+     * To put it another way, don't try this at home.
+     */
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent ev) {
+        final int action = ev.getActionMasked();
+        boolean handled = false;
+        if (action == MotionEvent.ACTION_DOWN) {
+            // Defensive programming: if we didn't get the UP or CANCEL, reset anyway.
+            mEdgeCaptured = false;
+        }
+        if (mWidgetsView != null && !mIsBouncing && (mEdgeCaptured || isEdgeSwipeBeginEvent(ev))) {
+            // Normally we would need to do a lot of extra stuff here.
+            // We can only get away with this because we haven't padded in
+            // the widget pager or otherwise transformed it during layout.
+            // We also don't support things like splitting MotionEvents.
+
+            // We set handled to captured even if dispatch is returning false here so that
+            // we don't send a different view a busted or incomplete event stream.
+            handled = mEdgeCaptured |= mWidgetsView.dispatchTouchEvent(ev);
+        }
+
+        if (!handled && !mEdgeCaptured) {
+            handled = super.dispatchTouchEvent(ev);
+        }
+
+        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
+            mEdgeCaptured = false;
+        }
+
+        return handled;
+    }
+
+    private boolean isEdgeSwipeBeginEvent(MotionEvent ev) {
+        if (ev.getActionMasked() != MotionEvent.ACTION_DOWN) {
+            return false;
+        }
+
+        final float x = ev.getX();
+        return x < mDragHandleEdgeSlop || x >= getWidth() - mDragHandleEdgeSlop;
+    }
+
+    /**
+     * We only want to add additional vertical space to the drag handle when the panel is fully
+     * closed.
+     */
+    private int getDragHandleSizeAbove() {
+        return isChallengeShowing() ? mDragHandleOpenAbove : mDragHandleClosedAbove;
+    }
+    private int getDragHandleSizeBelow() {
+        return isChallengeShowing() ? mDragHandleOpenBelow : mDragHandleClosedBelow;
+    }
+
+    private boolean isInChallengeView(float x, float y) {
+        return isPointInView(x, y, mChallengeView);
+    }
+
+    private boolean isInDragHandle(float x, float y) {
+        return isPointInView(x, y, mExpandChallengeView);
+    }
+
+    private boolean isPointInView(float x, float y, View view) {
+        if (view == null) {
+            return false;
+        }
+        return x >= view.getLeft() && y >= view.getTop()
+                && x < view.getRight() && y < view.getBottom();
+    }
+
+    private boolean crossedDragHandle(float x, float y, float initialY) {
+
+        final int challengeTop = mChallengeView.getTop();
+        final boolean horizOk = x >= 0 && x < getWidth();
+
+        final boolean vertOk;
+        if (mChallengeShowing) {
+            vertOk = initialY < (challengeTop - getDragHandleSizeAbove()) &&
+                    y > challengeTop + getDragHandleSizeBelow();
+        } else {
+            vertOk = initialY > challengeTop + getDragHandleSizeBelow() &&
+                    y < challengeTop - getDragHandleSizeAbove();
+        }
+        return horizOk && vertOk;
+    }
+
+    private int makeChildMeasureSpec(int maxSize, int childDimen) {
+        final int mode;
+        final int size;
+        switch (childDimen) {
+            case LayoutParams.WRAP_CONTENT:
+                mode = MeasureSpec.AT_MOST;
+                size = maxSize;
+                break;
+            case LayoutParams.MATCH_PARENT:
+                mode = MeasureSpec.EXACTLY;
+                size = maxSize;
+                break;
+            default:
+                mode = MeasureSpec.EXACTLY;
+                size = Math.min(maxSize, childDimen);
+                break;
+        }
+        return MeasureSpec.makeMeasureSpec(size, mode);
+    }
+
+    @Override
+    protected void onMeasure(int widthSpec, int heightSpec) {
+        if (MeasureSpec.getMode(widthSpec) != MeasureSpec.EXACTLY ||
+                MeasureSpec.getMode(heightSpec) != MeasureSpec.EXACTLY) {
+            throw new IllegalArgumentException(
+                    "SlidingChallengeLayout must be measured with an exact size");
+        }
+
+        final int width = MeasureSpec.getSize(widthSpec);
+        final int height = MeasureSpec.getSize(heightSpec);
+        setMeasuredDimension(width, height);
+
+        // Find one and only one challenge view.
+        final View oldChallengeView = mChallengeView;
+        final View oldExpandChallengeView = mChallengeView;
+        mChallengeView = null;
+        mExpandChallengeView = null;
+        final int count = getChildCount();
+
+        // First iteration through the children finds special children and sets any associated
+        // state.
+        for (int i = 0; i < count; i++) {
+            final View child = getChildAt(i);
+            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+            if (lp.childType == LayoutParams.CHILD_TYPE_CHALLENGE) {
+                if (mChallengeView != null) {
+                    throw new IllegalStateException(
+                            "There may only be one child with layout_isChallenge=\"true\"");
+                }
+                if (!(child instanceof KeyguardSecurityContainer)) {
+                            throw new IllegalArgumentException(
+                                    "Challenge must be a KeyguardSecurityContainer");
+                }
+                mChallengeView = (KeyguardSecurityContainer) child;
+                if (mChallengeView != oldChallengeView) {
+                    mChallengeView.setVisibility(mChallengeShowing ? VISIBLE : INVISIBLE);
+                }
+                // We're going to play silly games with the frame's background drawable later.
+                if (!mHasLayout) {
+                    // Set up the margin correctly based on our content for the first run.
+                    mHasGlowpad = child.findViewById(R.id.keyguard_selector_view) != null;
+                    lp.leftMargin = lp.rightMargin = getChallengeMargin(true);
+                }
+            } else if (lp.childType == LayoutParams.CHILD_TYPE_EXPAND_CHALLENGE_HANDLE) {
+                if (mExpandChallengeView != null) {
+                    throw new IllegalStateException(
+                            "There may only be one child with layout_childType"
+                            + "=\"expandChallengeHandle\"");
+                }
+                mExpandChallengeView = child;
+                if (mExpandChallengeView != oldExpandChallengeView) {
+                    mExpandChallengeView.setVisibility(mChallengeShowing ? INVISIBLE : VISIBLE);
+                    mExpandChallengeView.setOnClickListener(mExpandChallengeClickListener);
+                }
+            } else if (lp.childType == LayoutParams.CHILD_TYPE_SCRIM) {
+                setScrimView(child);
+            } else if (lp.childType == LayoutParams.CHILD_TYPE_WIDGETS) {
+                mWidgetsView = child;
+            }
+        }
+
+        // We want to measure the challenge view first, since the KeyguardWidgetPager
+        // needs to do things its measure pass that are dependent on the challenge view
+        // having been measured.
+        if (mChallengeView != null && mChallengeView.getVisibility() != View.GONE) {
+            // This one's a little funny. If the IME is present - reported in the form
+            // of insets on the root view - we only give the challenge the space it would
+            // have had if the IME wasn't there in order to keep the rest of the layout stable.
+            // We base this on the layout_maxHeight on the challenge view. If it comes out
+            // negative or zero, either we didn't have a maxHeight or we're totally out of space,
+            // so give up and measure as if this rule weren't there.
+            int challengeHeightSpec = heightSpec;
+            final View root = getRootView();
+            if (root != null) {
+                final LayoutParams lp = (LayoutParams) mChallengeView.getLayoutParams();
+                final int specSize = MeasureSpec.getSize(heightSpec);
+                final int windowHeight = mDisplayMetrics.heightPixels - root.getPaddingTop();
+                final int diff = windowHeight - specSize;
+                final int maxChallengeHeight = lp.maxHeight - diff;
+                if (maxChallengeHeight > 0) {
+                    challengeHeightSpec = makeChildMeasureSpec(maxChallengeHeight, lp.height);
+                }
+            }
+            measureChildWithMargins(mChallengeView, widthSpec, 0, challengeHeightSpec, 0);
+        }
+
+        // Measure the rest of the children
+        for (int i = 0; i < count; i++) {
+            final View child = getChildAt(i);
+            if (child.getVisibility() == GONE) {
+                continue;
+            }
+            // Don't measure the challenge view twice!
+            if (child == mChallengeView) continue;
+
+            // Measure children. Widget frame measures special, so that we can ignore
+            // insets for the IME.
+            int parentWidthSpec = widthSpec, parentHeightSpec = heightSpec;
+            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+            if (lp.childType == LayoutParams.CHILD_TYPE_WIDGETS) {
+                final View root = getRootView();
+                if (root != null) {
+                    // This calculation is super dodgy and relies on several assumptions.
+                    // Specifically that the root of the window will be padded in for insets
+                    // and that the window is LAYOUT_IN_SCREEN.
+                    final int windowWidth = mDisplayMetrics.widthPixels;
+                    final int windowHeight = mDisplayMetrics.heightPixels - root.getPaddingTop();
+                    parentWidthSpec = MeasureSpec.makeMeasureSpec(
+                            windowWidth, MeasureSpec.EXACTLY);
+                    parentHeightSpec = MeasureSpec.makeMeasureSpec(
+                            windowHeight, MeasureSpec.EXACTLY);
+                }
+            }
+            measureChildWithMargins(child, parentWidthSpec, 0, parentHeightSpec, 0);
+        }
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        final int paddingLeft = getPaddingLeft();
+        final int paddingTop = getPaddingTop();
+        final int paddingRight = getPaddingRight();
+        final int paddingBottom = getPaddingBottom();
+        final int width = r - l;
+        final int height = b - t;
+
+        final int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            final View child = getChildAt(i);
+
+            if (child.getVisibility() == GONE) continue;
+
+            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+            if (lp.childType == LayoutParams.CHILD_TYPE_CHALLENGE) {
+                // Challenge views pin to the bottom, offset by a portion of their height,
+                // and center horizontally.
+                final int center = (paddingLeft + width - paddingRight) / 2;
+                final int childWidth = child.getMeasuredWidth();
+                final int childHeight = child.getMeasuredHeight();
+                final int left = center - childWidth / 2;
+                final int layoutBottom = height - paddingBottom - lp.bottomMargin;
+                // We use the top of the challenge view to position the handle, so
+                // we never want less than the handle size showing at the bottom.
+                final int bottom = layoutBottom + (int) ((childHeight - mChallengeBottomBound)
+                        * (1 - mChallengeOffset));
+                child.setAlpha(getChallengeAlpha());
+                child.layout(left, bottom - childHeight, left + childWidth, bottom);
+            } else if (lp.childType == LayoutParams.CHILD_TYPE_EXPAND_CHALLENGE_HANDLE) {
+                final int center = (paddingLeft + width - paddingRight) / 2;
+                final int left = center - child.getMeasuredWidth() / 2;
+                final int right = left + child.getMeasuredWidth();
+                final int bottom = height - paddingBottom - lp.bottomMargin;
+                final int top = bottom - child.getMeasuredHeight();
+                child.layout(left, top, right, bottom);
+            } else {
+                // Non-challenge views lay out from the upper left, layered.
+                child.layout(paddingLeft + lp.leftMargin,
+                        paddingTop + lp.topMargin,
+                        paddingLeft + child.getMeasuredWidth(),
+                        paddingTop + child.getMeasuredHeight());
+            }
+        }
+
+        if (!mHasLayout) {
+            mHasLayout = true;
+        }
+    }
+
+    @Override
+    public void draw(Canvas c) {
+        super.draw(c);
+        if (DEBUG) {
+            final Paint debugPaint = new Paint();
+            debugPaint.setColor(0x40FF00CC);
+            // show the isInDragHandle() rect
+            c.drawRect(mDragHandleEdgeSlop,
+                    mChallengeView.getTop() - getDragHandleSizeAbove(),
+                    getWidth() - mDragHandleEdgeSlop,
+                    mChallengeView.getTop() + getDragHandleSizeBelow(),
+                    debugPaint);
+        }
+    }
+
+    public void computeScroll() {
+        super.computeScroll();
+
+        if (!mScroller.isFinished()) {
+            if (mChallengeView == null) {
+                // Can't scroll if the view is missing.
+                Log.e(TAG, "Challenge view missing in computeScroll");
+                mScroller.abortAnimation();
+                return;
+            }
+
+            mScroller.computeScrollOffset();
+            moveChallengeTo(mScroller.getCurrY());
+
+            if (mScroller.isFinished()) {
+                post(mEndScrollRunnable);
+            }
+        }
+    }
+
+    private void cancelTransitionsInProgress() {
+        if (!mScroller.isFinished()) {
+            mScroller.abortAnimation();
+            completeChallengeScroll();
+        }
+        if (mFader != null) {
+            mFader.cancel();
+        }
+    }
+
+    public void fadeInChallenge() {
+        fadeChallenge(true);
+    }
+
+    public void fadeOutChallenge() {
+        fadeChallenge(false);
+    }
+
+    public void fadeChallenge(final boolean show) {
+        if (mChallengeView != null) {
+
+            cancelTransitionsInProgress();
+            float alpha = show ? 1f : 0f;
+            int duration = show ? CHALLENGE_FADE_IN_DURATION : CHALLENGE_FADE_OUT_DURATION;
+            mFader = ObjectAnimator.ofFloat(mChallengeView, "alpha", alpha);
+            mFader.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationStart(Animator animation) {
+                    onFadeStart(show);
+                }
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    onFadeEnd(show);
+                }
+            });
+            mFader.setDuration(duration);
+            mFader.start();
+        }
+    }
+
+    private int getMaxChallengeBottom() {
+        if (mChallengeView == null) return 0;
+        final int layoutBottom = getLayoutBottom();
+        final int challengeHeight = mChallengeView.getMeasuredHeight();
+
+        return (layoutBottom + challengeHeight - mChallengeBottomBound);
+    }
+
+    private int getMinChallengeBottom() {
+        return getLayoutBottom();
+    }
+
+
+    private void onFadeStart(boolean show) {
+        mChallengeInteractiveInternal = false;
+        mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null);
+
+        if (show) {
+            moveChallengeTo(getMinChallengeBottom());
+        }
+
+        setScrollState(SCROLL_STATE_FADING);
+    }
+
+    private void onFadeEnd(boolean show) {
+        mChallengeInteractiveInternal = true;
+        setChallengeShowing(show);
+
+        if (!show) {
+            moveChallengeTo(getMaxChallengeBottom());
+        }
+
+        mChallengeView.setLayerType(LAYER_TYPE_NONE, null);
+        mFader = null;
+        setScrollState(SCROLL_STATE_IDLE);
+    }
+
+    public int getMaxChallengeTop() {
+        if (mChallengeView == null) return 0;
+
+        final int layoutBottom = getLayoutBottom();
+        final int challengeHeight = mChallengeView.getMeasuredHeight();
+        return layoutBottom - challengeHeight;
+    }
+
+    /**
+     * Move the bottom edge of mChallengeView to a new position and notify the listener
+     * if it represents a change in position. Changes made through this method will
+     * be stable across layout passes. If this method is called before first layout of
+     * this SlidingChallengeLayout it will have no effect.
+     *
+     * @param bottom New bottom edge in px in this SlidingChallengeLayout's coordinate system.
+     * @return true if the challenge view was moved
+     */
+    private boolean moveChallengeTo(int bottom) {
+        if (mChallengeView == null || !mHasLayout) {
+            return false;
+        }
+
+        final int layoutBottom = getLayoutBottom();
+        final int challengeHeight = mChallengeView.getHeight();
+
+        bottom = Math.max(getMinChallengeBottom(),
+                Math.min(bottom, getMaxChallengeBottom()));
+
+        float offset = 1.f - (float) (bottom - layoutBottom) /
+                (challengeHeight - mChallengeBottomBound);
+        mChallengeOffset = offset;
+        if (offset > 0 && !mChallengeShowing) {
+            setChallengeShowing(true);
+        }
+
+        mChallengeView.layout(mChallengeView.getLeft(),
+                bottom - mChallengeView.getHeight(), mChallengeView.getRight(), bottom);
+
+        mChallengeView.setAlpha(getChallengeAlpha());
+        if (mScrollListener != null) {
+            mScrollListener.onScrollPositionChanged(offset, mChallengeView.getTop());
+        }
+        postInvalidateOnAnimation();
+        return true;
+    }
+
+    /**
+     * The bottom edge of this SlidingChallengeLayout's coordinate system; will coincide with
+     * the bottom edge of mChallengeView when the challenge is fully opened.
+     */
+    private int getLayoutBottom() {
+        final int bottomMargin = (mChallengeView == null)
+                ? 0
+                : ((LayoutParams) mChallengeView.getLayoutParams()).bottomMargin;
+        final int layoutBottom = getMeasuredHeight() - getPaddingBottom() - bottomMargin;
+        return layoutBottom;
+    }
+
+    /**
+     * The bottom edge of mChallengeView; essentially, where the sliding challenge 'is'.
+     */
+    private int getChallengeBottom() {
+        if (mChallengeView == null) return 0;
+
+        return mChallengeView.getBottom();
+    }
+
+    /**
+     * Show or hide the challenge view, animating it if necessary.
+     * @param show true to show, false to hide
+     */
+    public void showChallenge(boolean show) {
+        showChallenge(show, 0);
+        if (!show) {
+            // Block any drags in progress so that callers can use this to disable dragging
+            // for other touch interactions.
+            mBlockDrag = true;
+        }
+    }
+
+    private void showChallenge(int velocity) {
+        boolean show = false;
+        if (Math.abs(velocity) > mMinVelocity) {
+            show = velocity < 0;
+        } else {
+            show = mChallengeOffset >= 0.5f;
+        }
+        showChallenge(show, velocity);
+    }
+
+    private void showChallenge(boolean show, int velocity) {
+        if (mChallengeView == null) {
+            setChallengeShowing(false);
+            return;
+        }
+
+        if (mHasLayout) {
+            mChallengeShowingTargetState = show;
+            final int layoutBottom = getLayoutBottom();
+            animateChallengeTo(show ? layoutBottom :
+                    layoutBottom + mChallengeView.getHeight() - mChallengeBottomBound, velocity);
+        }
+    }
+
+    @Override
+    public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
+        return new LayoutParams(getContext(), attrs);
+    }
+
+    @Override
+    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
+        return p instanceof LayoutParams ? new LayoutParams((LayoutParams) p) :
+                p instanceof MarginLayoutParams ? new LayoutParams((MarginLayoutParams) p) :
+                new LayoutParams(p);
+    }
+
+    @Override
+    protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
+        return new LayoutParams();
+    }
+
+    @Override
+    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
+        return p instanceof LayoutParams;
+    }
+
+    public static class LayoutParams extends MarginLayoutParams {
+        public int childType = CHILD_TYPE_NONE;
+        public static final int CHILD_TYPE_NONE = 0;
+        public static final int CHILD_TYPE_CHALLENGE = 2;
+        public static final int CHILD_TYPE_SCRIM = 4;
+        public static final int CHILD_TYPE_WIDGETS = 5;
+        public static final int CHILD_TYPE_EXPAND_CHALLENGE_HANDLE = 6;
+
+        public int maxHeight;
+
+        public LayoutParams() {
+            this(MATCH_PARENT, WRAP_CONTENT);
+        }
+
+        public LayoutParams(int width, int height) {
+            super(width, height);
+        }
+
+        public LayoutParams(android.view.ViewGroup.LayoutParams source) {
+            super(source);
+        }
+
+        public LayoutParams(MarginLayoutParams source) {
+            super(source);
+        }
+
+        public LayoutParams(LayoutParams source) {
+            super(source);
+
+            childType = source.childType;
+        }
+
+        public LayoutParams(Context c, AttributeSet attrs) {
+            super(c, attrs);
+
+            final TypedArray a = c.obtainStyledAttributes(attrs,
+                    R.styleable.SlidingChallengeLayout_Layout);
+            childType = a.getInt(R.styleable.SlidingChallengeLayout_Layout_layout_childType,
+                    CHILD_TYPE_NONE);
+            maxHeight = a.getDimensionPixelSize(
+                    R.styleable.SlidingChallengeLayout_Layout_layout_maxHeight, 0);
+            a.recycle();
+        }
+    }
+}
diff --git a/packages/Keyguard/test/Android.mk b/packages/Keyguard/test/Android.mk
new file mode 100644
index 0000000..15059c6
--- /dev/null
+++ b/packages/Keyguard/test/Android.mk
@@ -0,0 +1,29 @@
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := KeyguardTest
+
+# Remove these to verify permission checks are working correctly
+LOCAL_CERTIFICATE := platform
+LOCAL_PRIVILEGED_MODULE := true
+
+# LOCAL_PROGUARD_FLAG_FILES := proguard.flags
+
+include $(BUILD_PACKAGE)
diff --git a/packages/Keyguard/test/AndroidManifest.xml b/packages/Keyguard/test/AndroidManifest.xml
new file mode 100644
index 0000000..b801e4b
--- /dev/null
+++ b/packages/Keyguard/test/AndroidManifest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.keyguard.test">
+    <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="17"/>
+    <uses-permission android:name="android.permission.CONTROL_KEYGUARD" />
+    <application android:label="@string/app_name" android:icon="@drawable/app_icon">
+        <activity android:name=".KeyguardTestActivity"
+                android:label="@string/app_name"
+                android:theme="@android:style/Theme.Holo">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_lock_normal.png b/packages/Keyguard/test/res/drawable-hdpi/app_icon.png
similarity index 100%
copy from core/res/res/drawable-hdpi/ic_lockscreen_lock_normal.png
copy to packages/Keyguard/test/res/drawable-hdpi/app_icon.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_lock_normal.png b/packages/Keyguard/test/res/drawable-mdpi/app_icon.png
similarity index 100%
copy from core/res/res/drawable-mdpi/ic_lockscreen_lock_normal.png
copy to packages/Keyguard/test/res/drawable-mdpi/app_icon.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_lock_normal.png b/packages/Keyguard/test/res/drawable-xhdpi/app_icon.png
similarity index 100%
copy from core/res/res/drawable-xhdpi/ic_lockscreen_lock_normal.png
copy to packages/Keyguard/test/res/drawable-xhdpi/app_icon.png
Binary files differ
diff --git a/packages/Keyguard/test/res/layout/keyguard_test_activity.xml b/packages/Keyguard/test/res/layout/keyguard_test_activity.xml
new file mode 100644
index 0000000..dab1088
--- /dev/null
+++ b/packages/Keyguard/test/res/layout/keyguard_test_activity.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 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.
+*/
+-->
+
+<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">
+
+    <Button android:id="@+id/do_keyguard"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/do_keyguard" />
+
+    <Button android:id="@+id/on_screen_turned_off"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/on_screen_turned_off" />
+
+    <Button android:id="@+id/on_screen_turned_on"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/on_screen_turned_on" />
+
+    <Button android:id="@+id/verify_unlock"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/verify_unlock" />
+
+</LinearLayout>
diff --git a/packages/Keyguard/test/res/menu/optionmenu.xml b/packages/Keyguard/test/res/menu/optionmenu.xml
new file mode 100644
index 0000000..22f300d
--- /dev/null
+++ b/packages/Keyguard/test/res/menu/optionmenu.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/none_menu_item"
+          android:title="@string/none_menu_item" />
+    <item android:id="@+id/pin_menu_item"
+          android:title="@string/pin_menu_item" />
+    <item android:id="@+id/password_menu_item"
+        android:title="@string/password_menu_item" />
+    <item android:id="@+id/pattern_menu_item"
+          android:title="@string/pattern_menu_item" />
+    <item android:id="@+id/sim_pin_menu_item"
+          android:title="@string/sim_pin_menu_item" />
+    <item android:id="@+id/sim_puk_menu_item"
+          android:title="@string/sim_puk_menu_item" />
+    <item android:id="@+id/add_widget_item"
+          android:title="@string/add_widget_item" />
+</menu>
diff --git a/packages/Keyguard/test/res/values/strings.xml b/packages/Keyguard/test/res/values/strings.xml
new file mode 100644
index 0000000..129204b
--- /dev/null
+++ b/packages/Keyguard/test/res/values/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name">KeyguardTestActivity</string>
+    <string name="secure_app_name">UnifiedCamera</string>
+    <string name="none_menu_item">No security</string>
+    <string name="pin_menu_item">PIN</string>
+    <string name="password_menu_item">Password</string>
+    <string name="pattern_menu_item">Pattern</string>
+    <string name="sim_pin_menu_item">SIM PIN</string>
+    <string name="sim_puk_menu_item">SIM PUK</string>
+    <string name="add_widget_item">Choose widget...</string>
+    <string name="on_screen_turned_off">onScreenTurnedOff</string>
+    <string name="on_screen_turned_on">onScreenTurnedOn</string>
+    <string name="do_keyguard">doKeyguard</string>
+    <string name="verify_unlock">verifyUnlock</string>
+</resources>
diff --git a/packages/Keyguard/test/src/com/android/keyguard/test/KeyguardTestActivity.java b/packages/Keyguard/test/src/com/android/keyguard/test/KeyguardTestActivity.java
new file mode 100644
index 0000000..e89c10e
--- /dev/null
+++ b/packages/Keyguard/test/src/com/android/keyguard/test/KeyguardTestActivity.java
@@ -0,0 +1,373 @@
+/*
+ * 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.keyguard.test;
+
+import com.android.internal.policy.IKeyguardShowCallback;
+import com.android.internal.policy.IKeyguardExitCallback;
+import com.android.internal.policy.IKeyguardService;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.WindowManagerPolicy;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.LockPatternView.Cell;
+
+import java.util.List;
+
+public class KeyguardTestActivity extends Activity implements OnClickListener {
+    private static final String KEYGUARD_PACKAGE = "com.android.keyguard";
+    private static final String KEYGUARD_CLASS = "com.android.keyguard.KeyguardService";
+    private static final String TAG = "LockScreenTestActivity";
+    private static final int MODE_NONE = 0;
+    private static final int MODE_PIN = 1;
+    private static final int MODE_PASSWORD = 2;
+    private static final int MODE_PATTERN = 3;
+    private static final int MODE_SIM_PIN = 4;
+    private static final int MODE_SIM_PUK = 5;
+    private static final String SECURITY_MODE = "security_mode";
+    Handler mHandler = new Handler();
+
+    IKeyguardService mService = null;
+
+    KeyguardShowCallback mKeyguardShowCallback = new KeyguardShowCallback();
+    KeyguardExitCallback mKeyguardExitCallback = new KeyguardExitCallback();
+
+    RemoteServiceConnection mConnection;
+    private boolean mSentSystemReady;
+
+    class KeyguardShowCallback extends IKeyguardShowCallback.Stub {
+
+        @Override
+        public void onShown(IBinder windowToken) throws RemoteException {
+            Log.v(TAG, "Keyguard is shown, windowToken = " + windowToken);
+        }
+    }
+
+    class KeyguardExitCallback extends IKeyguardExitCallback.Stub {
+
+        @Override
+        public void onKeyguardExitResult(final boolean success) throws RemoteException {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    new AlertDialog.Builder(KeyguardTestActivity.this)
+                    .setMessage("Result: " + success)
+                    .setPositiveButton("OK", null)
+                    .show();
+                }
+            });
+        }
+    };
+
+    private class RemoteServiceConnection implements ServiceConnection {
+        public void onServiceConnected(ComponentName className, IBinder service) {
+            Log.v(TAG, "onServiceConnected()");
+            mService = IKeyguardService.Stub.asInterface(service);
+            try {
+                mService.asBinder().linkToDeath(new IBinder.DeathRecipient() {
+                    @Override
+                    public void binderDied() {
+                        new AlertDialog.Builder(KeyguardTestActivity.this)
+                            .setMessage("Oops! Keygued died")
+                            .setPositiveButton("OK", null)
+                            .show();
+                    }
+                }, 0);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Couldn't linkToDeath");
+                e.printStackTrace();
+            }
+//            try {
+//                mService.onSystemReady();
+//            } catch (RemoteException e) {
+//                Log.v(TAG, "Remote service died trying to call onSystemReady");
+//                e.printStackTrace();
+//            }
+        }
+
+        public void onServiceDisconnected(ComponentName className) {
+            Log.v(TAG, "onServiceDisconnected()");
+            mService = null;
+        }
+    };
+
+    private void bindService() {
+        if (mConnection == null) {
+            mConnection = new RemoteServiceConnection();
+            Intent intent = new Intent();
+            intent.setClassName(KEYGUARD_PACKAGE, KEYGUARD_CLASS);
+            Log.v(TAG, "BINDING SERVICE: " + KEYGUARD_CLASS);
+            if (!bindService(intent, mConnection, Context.BIND_AUTO_CREATE)) {
+                Log.v(TAG, "FAILED TO BIND TO KEYGUARD!");
+            }
+        } else {
+            Log.v(TAG, "Service already bound");
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.keyguard_test_activity);
+        final int[] buttons = {
+                R.id.on_screen_turned_off, R.id.on_screen_turned_on,
+                R.id.do_keyguard, R.id.verify_unlock
+        };
+        for (int i = 0; i < buttons.length; i++) {
+            findViewById(buttons[i]).setOnClickListener(this);
+        }
+        Log.v(TAG, "Binding service...");
+        bindService();
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putInt(SECURITY_MODE, mSecurityMode);
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Bundle savedInstanceState) {
+        super.onRestoreInstanceState(savedInstanceState);
+        setMode(savedInstanceState.getInt(SECURITY_MODE));
+    }
+
+// TODO: Find a secure way to inject mock into keyguard...
+//    @Override
+//    public boolean onCreateOptionsMenu(Menu menu) {
+//        MenuInflater inflater = getMenuInflater();
+//        inflater.inflate(R.menu.optionmenu, menu);
+//        return true;
+//    }
+
+    private void setMode(int mode) {
+        mTestSimPin = false;
+        mTestSimPuk = false;
+        mLockPasswordEnabled = false;
+        mLockPatternEnabled = false;
+        switch(mode) {
+            case MODE_NONE:
+                mSecurityModeMock = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+                break;
+            case MODE_PIN:
+                mSecurityModeMock = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
+                mLockPasswordEnabled = true;
+                break;
+            case MODE_PASSWORD:
+                mSecurityModeMock = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
+                mLockPasswordEnabled = true;
+                break;
+            case MODE_PATTERN:
+                mSecurityModeMock = DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
+                mLockPatternEnabled = true;
+                break;
+            case MODE_SIM_PIN:
+                mTestSimPin = true;
+                break;
+            case MODE_SIM_PUK:
+                mTestSimPuk = true;
+                break;
+        }
+        mSecurityMode = mode;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        // Handle item selection
+        switch (item.getItemId()) {
+            case R.id.none_menu_item:
+                setMode(MODE_NONE);
+                break;
+            case R.id.pin_menu_item:
+                setMode(MODE_PIN);
+                break;
+            case R.id.password_menu_item:
+                setMode(MODE_PASSWORD);
+                break;
+            case R.id.pattern_menu_item:
+                setMode(MODE_PATTERN);
+                break;
+            case R.id.sim_pin_menu_item:
+                setMode(MODE_SIM_PIN);
+                break;
+            case R.id.sim_puk_menu_item:
+                setMode(MODE_SIM_PUK);
+                break;
+            case R.id.add_widget_item:
+                startWidgetPicker();
+                break;
+            default:
+                return super.onOptionsItemSelected(item);
+        }
+        try {
+            mService.doKeyguardTimeout(null);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Remote service died");
+            e.printStackTrace();
+        }
+        return true;
+    }
+
+    private void startWidgetPicker() {
+        startActivity(new Intent(Settings.ACTION_SECURITY_SETTINGS));
+    }
+
+    @Override
+    public void onClick(View v) {
+        try {
+            switch (v.getId()) {
+            case R.id.on_screen_turned_on:
+                mService.onScreenTurnedOn(mKeyguardShowCallback);
+                break;
+            case R.id.on_screen_turned_off:
+                mService.onScreenTurnedOff(WindowManagerPolicy.OFF_BECAUSE_OF_USER);
+                break;
+            case R.id.do_keyguard:
+                if (!mSentSystemReady) {
+                    mSentSystemReady = true;
+                    mService.onSystemReady();
+                }
+                mService.doKeyguardTimeout(null);
+                break;
+            case R.id.verify_unlock:
+                mService.doKeyguardTimeout(null);
+                // Wait for keyguard to lock and then try this...
+                mHandler.postDelayed(new Runnable() {
+                    @Override
+                    public void run() {
+                        try {
+                            mService.verifyUnlock(mKeyguardExitCallback);
+                        } catch (RemoteException e) {
+                            Log.e(TAG, "Failed verifyUnlock()", e);
+                        }
+                    }
+                }, 5000);
+                break;
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "onClick(): Failed due to remote exeption", e);
+        }
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        try {
+            if (mService != null) {
+                mService.setHidden(true);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Remote service died");
+            e.printStackTrace();
+        }
+    }
+
+    protected void onResume() {
+        super.onResume();
+        try {
+            if (mService != null) {
+                mService.setHidden(false);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Remote service died");
+            e.printStackTrace();
+        }
+    }
+
+    public int mSecurityModeMock;
+    private boolean mTestSimPin;
+    private boolean mTestSimPuk;
+    private boolean mLockPasswordEnabled;
+    public boolean mLockPatternEnabled;
+    private int mSecurityMode;
+
+    class LockPatternUtilsMock extends LockPatternUtils {
+        private long mDeadline;
+        public LockPatternUtilsMock(Context context) {
+            super(context);
+        }
+
+        @Override
+        public boolean checkPattern(List<Cell> pattern) {
+            return pattern.size() > 4;
+        }
+
+        @Override
+        public boolean checkPassword(String password) {
+            return password.length() > 4;
+        }
+        @Override
+        public long setLockoutAttemptDeadline() {
+            final long deadline = SystemClock.elapsedRealtime() + FAILED_ATTEMPT_TIMEOUT_MS;
+            mDeadline = deadline;
+            return deadline;
+        }
+        @Override
+        public boolean isLockScreenDisabled() {
+            return false;
+        }
+        @Override
+        public long getLockoutAttemptDeadline() {
+            return mDeadline;
+        }
+        @Override
+        public void reportFailedPasswordAttempt() {
+            // Ignored
+        }
+        @Override
+        public void reportSuccessfulPasswordAttempt() {
+            // Ignored
+        }
+        @Override
+        public boolean isLockPatternEnabled() {
+            return mLockPatternEnabled;
+        }
+
+        @Override
+        public boolean isLockPasswordEnabled() {
+            return mLockPasswordEnabled;
+        }
+
+        @Override
+        public int getKeyguardStoredPasswordQuality() {
+            return mSecurityModeMock;
+        }
+
+        public boolean isSecure() {
+            return mLockPatternEnabled || mLockPasswordEnabled || mTestSimPin || mTestSimPuk;
+        }
+
+    }
+}
diff --git a/packages/PrintSpooler/Android.mk b/packages/PrintSpooler/Android.mk
new file mode 100644
index 0000000..f65fe4b
--- /dev/null
+++ b/packages/PrintSpooler/Android.mk
@@ -0,0 +1,30 @@
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := PrintSpooler
+
+LOCAL_JAVA_LIBRARIES := framework-base
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+include $(BUILD_PACKAGE)
+
diff --git a/packages/PrintSpooler/AndroidManifest.xml b/packages/PrintSpooler/AndroidManifest.xml
new file mode 100644
index 0000000..9319025
--- /dev/null
+++ b/packages/PrintSpooler/AndroidManifest.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (c) 2013 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.printspooler"
+        android:versionName="1"
+        android:versionCode="1">
+
+    <!-- Allows an application to call APIs that give it access to all print jobs
+         on the device. Usually an app can access only the print jobs it created. -->
+    <permission
+        android:name="com.android.printspooler.permission.ACCESS_ALL_PRINT_JOBS"
+        android:label="@string/permlab_accessAllPrintJobs"
+        android:description="@string/permdesc_accessAllPrintJobs"
+        android:protectionLevel="signature" />
+
+    <!-- May be required by the settings and add printer activities of a
+         print service if the developer wants only trusted system code to
+         be able to launch these activities. -->
+    <permission android:name="android.permission.START_PRINT_SERVICE_CONFIG_ACTIVITY"
+        android:label="@string/permlab_startPrintServiceConfigActivity"
+        android:description="@string/permdesc_startPrintServiceConfigActivity"
+        android:protectionLevel="signature" />
+
+    <uses-permission android:name="com.android.printspooler.permission.ACCESS_ALL_PRINT_JOBS"/>
+    <uses-permission android:name="android.permission.WAKE_LOCK"/>
+    <uses-permission android:name="android.permission.START_PRINT_SERVICE_CONFIG_ACTIVITY"/>
+
+    <uses-sdk android:minSdkVersion="18" android:targetSdkVersion="18"/>
+
+    <application
+            android:allowClearUserData="false"
+            android:label="@string/app_label"
+            android:allowBackup= "false"
+            android:supportsRtl="true">
+
+        <service
+            android:name=".PrintSpoolerService"
+            android:exported="true"
+            android:permission="android.permission.BIND_PRINT_SPOOLER_SERVICE">
+        </service>
+
+        <activity
+            android:name=".PrintJobConfigActivity"
+            android:configChanges="orientation|screenSize"
+            android:exported="false"
+            android:theme="@style/PrintJobConfigActivityTheme">
+        </activity>
+
+        <activity
+            android:name=".SelectPrinterActivity"
+            android:label="@string/all_printers_label"
+            android:theme="@style/SelectPrinterActivityTheme"
+            android:exported="false">
+        </activity>
+
+        <receiver
+            android:name=".NotificationController$NotificationBroadcastReceiver"
+            android:exported="false" >
+        </receiver>
+
+    </application>
+
+</manifest>
diff --git a/cmds/system_server/MODULE_LICENSE_APACHE2 b/packages/PrintSpooler/MODULE_LICENSE_APACHE2
similarity index 100%
rename from cmds/system_server/MODULE_LICENSE_APACHE2
rename to packages/PrintSpooler/MODULE_LICENSE_APACHE2
diff --git a/cmds/system_server/NOTICE b/packages/PrintSpooler/NOTICE
similarity index 100%
rename from cmds/system_server/NOTICE
rename to packages/PrintSpooler/NOTICE
diff --git a/packages/PrintSpooler/res/drawable-hdpi/stat_notify_cancelling.png b/packages/PrintSpooler/res/drawable-hdpi/stat_notify_cancelling.png
new file mode 100644
index 0000000..2757db0
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-hdpi/stat_notify_cancelling.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-hdpi/stat_notify_error.png b/packages/PrintSpooler/res/drawable-hdpi/stat_notify_error.png
new file mode 100644
index 0000000..7846a78
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-hdpi/stat_notify_error.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-hdpi/stat_notify_print.png b/packages/PrintSpooler/res/drawable-hdpi/stat_notify_print.png
new file mode 100644
index 0000000..aaff3dd
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-hdpi/stat_notify_print.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-mdpi/stat_notify_cancelling.png b/packages/PrintSpooler/res/drawable-mdpi/stat_notify_cancelling.png
new file mode 100644
index 0000000..c1b380a
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-mdpi/stat_notify_cancelling.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-mdpi/stat_notify_error.png b/packages/PrintSpooler/res/drawable-mdpi/stat_notify_error.png
new file mode 100644
index 0000000..44109eb
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-mdpi/stat_notify_error.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-mdpi/stat_notify_print.png b/packages/PrintSpooler/res/drawable-mdpi/stat_notify_print.png
new file mode 100644
index 0000000..a3954b5
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-mdpi/stat_notify_print.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-xhdpi/stat_notify_cancelling.png b/packages/PrintSpooler/res/drawable-xhdpi/stat_notify_cancelling.png
new file mode 100644
index 0000000..fedc00e
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-xhdpi/stat_notify_cancelling.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-xhdpi/stat_notify_error.png b/packages/PrintSpooler/res/drawable-xhdpi/stat_notify_error.png
new file mode 100644
index 0000000..c3faa42
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-xhdpi/stat_notify_error.png
Binary files differ
diff --git a/packages/PrintSpooler/res/drawable-xhdpi/stat_notify_print.png b/packages/PrintSpooler/res/drawable-xhdpi/stat_notify_print.png
new file mode 100644
index 0000000..6b55a14
--- /dev/null
+++ b/packages/PrintSpooler/res/drawable-xhdpi/stat_notify_print.png
Binary files differ
diff --git a/packages/PrintSpooler/res/layout/print_job_config_activity_container.xml b/packages/PrintSpooler/res/layout/print_job_config_activity_container.xml
new file mode 100644
index 0000000..7817094
--- /dev/null
+++ b/packages/PrintSpooler/res/layout/print_job_config_activity_container.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/content_container"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_gravity="center"
+    android:background="@color/container_background">
+</FrameLayout>
diff --git a/packages/PrintSpooler/res/layout/print_job_config_activity_content_editing.xml b/packages/PrintSpooler/res/layout/print_job_config_activity_content_editing.xml
new file mode 100644
index 0000000..abf3c03
--- /dev/null
+++ b/packages/PrintSpooler/res/layout/print_job_config_activity_content_editing.xml
@@ -0,0 +1,246 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:scrollbars="vertical"
+    android:background="@color/editable_background">
+
+    <GridLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:columnCount="2">
+
+        <!-- Destination -->
+
+        <Spinner
+            android:id="@+id/destination_spinner"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="fill_horizontal"
+            android:layout_marginTop="24dip"
+            android:layout_marginStart="24dip"
+            android:layout_marginEnd="24dip"
+            android:layout_row="0"
+            android:layout_column="0"
+            android:layout_columnSpan="2"
+            android:minHeight="?android:attr/listPreferredItemHeightSmall">
+        </Spinner>
+
+        <!-- Copies -->
+
+        <view
+            class="com.android.printspooler.PrintJobConfigActivity$CustomEditText"
+            android:id="@+id/copies_edittext"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="24dip"
+            android:layout_marginEnd="6dip"
+            android:layout_row="2"
+            android:layout_column="0"
+            android:layout_gravity="bottom|fill_horizontal"
+            style="@style/PrintOptionEditTextStyle"
+            android:inputType="numberDecimal">
+        </view>
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="12dip"
+            android:layout_marginStart="36dip"
+            android:layout_marginEnd="6dip"
+            android:layout_row="1"
+            android:layout_column="0"
+            style="@style/PrintOptionTextViewStyle"
+            android:labelFor="@id/copies_edittext"
+            android:text="@string/label_copies">
+        </TextView>
+
+        <!-- Paper size -->
+
+        <Spinner
+            android:id="@+id/paper_size_spinner"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="6dip"
+            android:layout_marginEnd="24dip"
+            android:layout_row="2"
+            android:layout_column="1"
+            android:layout_gravity="fill_horizontal"
+            style="@style/PrintOptionSpinnerStyle">
+        </Spinner>
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="12dip"
+            android:layout_marginStart="18dip"
+            android:layout_marginEnd="24dip"
+            android:layout_row="1"
+            android:layout_column="1"
+            style="@style/PrintOptionTextViewStyle"
+            android:labelFor="@id/paper_size_spinner"
+            android:text="@string/label_paper_size">
+        </TextView>
+
+        <!-- Color -->
+
+        <Spinner
+            android:id="@+id/color_spinner"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="24dip"
+            android:layout_marginEnd="6dip"
+            android:layout_row="4"
+            android:layout_column="0"
+            android:layout_gravity="fill_horizontal"
+            style="@style/PrintOptionSpinnerStyle">
+        </Spinner>
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="12dip"
+            android:layout_marginStart="36dip"
+            android:layout_marginEnd="6dip"
+            android:layout_row="3"
+            android:layout_column="0"
+            style="@style/PrintOptionTextViewStyle"
+            android:labelFor="@id/color_spinner"
+            android:text="@string/label_color">
+        </TextView>
+
+        <!-- Orientation -->
+
+        <Spinner
+            android:id="@+id/orientation_spinner"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="6dip"
+            android:layout_marginEnd="24dip"
+            android:layout_row="4"
+            android:layout_column="1"
+            android:layout_gravity="fill_horizontal"
+            style="@style/PrintOptionSpinnerStyle">
+        </Spinner>
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="12dip"
+            android:layout_marginStart="18dip"
+            android:layout_marginEnd="24dip"
+            android:layout_row="3"
+            android:layout_column="1"
+            style="@style/PrintOptionTextViewStyle"
+            android:labelFor="@id/orientation_spinner"
+            android:text="@string/label_orientation">
+        </TextView>
+
+        <!-- Range options -->
+
+        <Spinner
+            android:id="@+id/range_options_spinner"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="24dip"
+            android:layout_marginEnd="6dip"
+            android:layout_row="6"
+            android:layout_column="0"
+            android:layout_gravity="fill_horizontal"
+            style="@style/PrintOptionSpinnerStyle">
+        </Spinner>
+
+        <TextView
+            android:id="@+id/range_options_title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="12dip"
+            android:layout_marginStart="36dip"
+            android:layout_row="5"
+            android:layout_column="0"
+            style="@style/PrintOptionTextViewStyle"
+            android:labelFor="@id/range_options_spinner"
+            android:text="@string/label_pages">
+        </TextView>
+
+        <!-- Pages -->
+
+        <view
+            class="com.android.printspooler.PrintJobConfigActivity$CustomEditText"
+            android:id="@+id/page_range_edittext"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="6dip"
+            android:layout_marginEnd="24dip"
+            android:layout_row="6"
+            android:layout_column="1"
+            android:layout_gravity="bottom|fill_horizontal"
+            style="@style/PrintOptionEditTextStyle"
+            android:visibility="gone"
+            android:inputType="textNoSuggestions">
+        </view>
+
+       <TextView
+            android:id="@+id/page_range_title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="12dip"
+            android:layout_marginStart="12dip"
+            android:layout_marginEnd="24dip"
+            android:layout_row="5"
+            android:layout_column="1"
+            style="@style/PrintOptionTextViewStyle"
+            android:labelFor="@id/page_range_edittext"
+            android:text="@string/pages_range_example"
+            android:textAllCaps="false">
+        </TextView>
+
+       <!-- Print button -->
+
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="1dip"
+            android:layout_marginTop="24dip"
+            android:layout_row="7"
+            android:layout_column="0"
+            android:layout_columnSpan="2"
+            android:layout_gravity="fill_horizontal"
+            android:background="@color/separator"
+            android:contentDescription="@null">
+        </ImageView>
+
+        <Button
+            android:id="@+id/print_button"
+            style="?android:attr/buttonBarButtonStyle"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="fill_horizontal"
+            android:layout_row="8"
+            android:layout_column="0"
+            android:layout_columnSpan="2"
+            android:text="@string/print_button"
+            android:textSize="16sp"
+            android:textColor="@color/important_text">
+        </Button>
+
+    </GridLayout>
+
+</ScrollView>
+
diff --git a/packages/PrintSpooler/res/layout/print_job_config_activity_content_generating.xml b/packages/PrintSpooler/res/layout/print_job_config_activity_content_generating.xml
new file mode 100644
index 0000000..8bdb6c9
--- /dev/null
+++ b/packages/PrintSpooler/res/layout/print_job_config_activity_content_generating.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/content_generating"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:background="@color/editable_background"
+        android:orientation="vertical">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="16dip"
+            android:layout_marginEnd="16dip"
+            android:layout_gravity="center"
+            style="?android:attr/buttonBarButtonStyle"
+            android:singleLine="true"
+            android:ellipsize="end"
+            android:text="@string/generating_print_job"
+            android:textColor="@color/important_text"
+            android:textSize="16sp">
+        </TextView>
+
+        <ProgressBar
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="32dip"
+            android:layout_marginEnd="32dip"
+            android:layout_marginTop="16dip"
+            android:layout_marginBottom="32dip"
+            android:layout_gravity="center_horizontal"
+            style="?android:attr/progressBarStyleLarge">
+        </ProgressBar>
+
+        <View
+            android:layout_width="fill_parent"
+            android:layout_height="1dip"
+            android:background="@color/separator">
+        </View>
+
+    </LinearLayout>
+
+    <Button
+        android:id="@+id/cancel_button"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="fill_horizontal"
+        style="?android:attr/buttonBarButtonStyle"
+        android:text="@string/cancel"
+        android:textSize="16sp"
+        android:textColor="@color/important_text">
+    </Button>
+
+</LinearLayout>
diff --git a/packages/PrintSpooler/res/layout/select_printer_activity.xml b/packages/PrintSpooler/res/layout/select_printer_activity.xml
new file mode 100644
index 0000000..f4e1853
--- /dev/null
+++ b/packages/PrintSpooler/res/layout/select_printer_activity.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content">
+
+    <fragment
+        android:name="com.android.printspooler.SelectPrinterFragment"
+        android:id="@+id/select_printer_fragment"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content">
+    </fragment>
+
+</FrameLayout>
\ No newline at end of file
diff --git a/packages/PrintSpooler/res/layout/spinner_dropdown_item.xml b/packages/PrintSpooler/res/layout/spinner_dropdown_item.xml
new file mode 100644
index 0000000..48189bd
--- /dev/null
+++ b/packages/PrintSpooler/res/layout/spinner_dropdown_item.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:paddingStart="8dip"
+    android:paddingEnd="8dip"
+    android:minHeight="?android:attr/listPreferredItemHeightSmall"
+    android:orientation="vertical"
+    android:gravity="start|center_vertical">
+
+    <TextView
+        android:id="@+id/title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:singleLine="true"
+        android:ellipsize="end"
+        android:textIsSelectable="false"
+        android:gravity="top|left"
+        android:textColor="@color/important_text">
+    </TextView>
+
+    <TextView
+        android:id="@+id/subtitle"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:singleLine="true"
+        android:ellipsize="end"
+        android:textIsSelectable="false"
+        android:visibility="gone"
+        android:textColor="@color/important_text">
+
+    </TextView>
+
+</LinearLayout>
diff --git a/packages/PrintSpooler/res/menu/select_printer_activity.xml b/packages/PrintSpooler/res/menu/select_printer_activity.xml
new file mode 100644
index 0000000..d4ce1cf
--- /dev/null
+++ b/packages/PrintSpooler/res/menu/select_printer_activity.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <item
+        android:id="@+id/action_search"
+        android:title="@string/search"
+        android:icon="@*android:drawable/ic_menu_search_holo_light"
+        android:actionViewClass="android.widget.SearchView"
+        android:showAsAction="ifRoom"
+        android:alphabeticShortcut="f"
+        android:imeOptions="actionSearch">
+    </item>
+
+    <item
+        android:id="@+id/action_add_printer"
+        android:title="@null"
+        android:icon="@*android:drawable/create_contact"
+        android:showAsAction="ifRoom"
+        android:alphabeticShortcut="a">
+    </item>
+
+</menu>
diff --git a/packages/PrintSpooler/res/values/colors.xml b/packages/PrintSpooler/res/values/colors.xml
new file mode 100644
index 0000000..9972c96
--- /dev/null
+++ b/packages/PrintSpooler/res/values/colors.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+
+    <color name="container_background">#FFFFFF</color>
+    <color name="important_text">#333333</color>
+    <color name="print_option_title">#888888</color>
+    <color name="separator">#CCCCCC</color>
+    <color name="editable_background">#F2F2F2</color>
+
+</resources>
\ No newline at end of file
diff --git a/packages/PrintSpooler/res/values/constants.xml b/packages/PrintSpooler/res/values/constants.xml
new file mode 100644
index 0000000..96cdeb1
--- /dev/null
+++ b/packages/PrintSpooler/res/values/constants.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+
+    <integer name="page_option_value_all">0</integer>
+    <integer name="page_option_value_page_range">1</integer>
+
+    <integer-array name="page_options_values" translatable="false">
+        <item>@integer/page_option_value_all</item>
+        <item>@integer/page_option_value_page_range</item>
+    </integer-array>
+
+</resources>
\ No newline at end of file
diff --git a/packages/PrintSpooler/res/values/strings.xml b/packages/PrintSpooler/res/values/strings.xml
new file mode 100644
index 0000000..21a4867
--- /dev/null
+++ b/packages/PrintSpooler/res/values/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Title of the PrintSpooler application. [CHAR LIMIT=50] -->
+    <string name="app_label">Print Spooler</string>
+
+    <!-- Label of the print dialog's print button. [CHAR LIMIT=16] -->
+    <string name="print_button">Print</string>
+
+    <!-- Label of the print dialog's save button. [CHAR LIMIT=16] -->
+    <string name="save_button">Save</string>
+
+    <!-- Label of the destination widget. [CHAR LIMIT=20] -->
+    <string name="label_destination">DESTIINATION</string>
+
+    <!-- Label of the copies count widget. [CHAR LIMIT=20] -->
+    <string name="label_copies">COPIES</string>
+
+    <!-- Label of the paper size widget. [CHAR LIMIT=20] -->
+    <string name="label_paper_size">PAPER SIZE</string>
+
+    <!-- Label of the color mode widget. [CHAR LIMIT=20] -->
+    <string name="label_color">COLOR</string>
+
+    <!-- Label of the orientation widget. [CHAR LIMIT=20] -->
+    <string name="label_orientation">ORIENTATION</string>
+
+    <!-- Label of the page selection widget. [CHAR LIMIT=20] -->
+    <string name="label_pages">PAGES (<xliff:g id="page_count" example="5">%1$s</xliff:g>)</string>
+
+    <!-- Page range exmple used as a hint of how to specify such. [CHAR LIMIT=15] -->
+    <string name="pages_range_example">e.g. 1&#8211;5, 8, 11&#8211;13</string>
+
+    <!-- Title for the pring preview button .[CHAR LIMIT=30] -->
+    <string name="print_preview">Print preview</string>
+
+    <!-- Title for the pring preview button if there is no PDF viewer isntalled. [CHAR LIMIT=50] -->
+    <string name="install_for_print_preview">Install PDF viewer for preview</string>
+
+    <!-- Title of the message that the printing application crashed. [CHAR LIMIT=50] -->
+    <string name="printing_app_crashed">Printing app crashed</string>
+
+    <!-- Title if the number of pages in a printed document is unknown. [CHAR LIMIT=20] -->
+    <string name="page_count_unknown">unknown</string>
+
+    <!-- Title for the temporary dialog show while an app is generating a print job. [CHAR LIMIT=30] -->
+    <string name="generating_print_job">Generating print job</string>
+
+    <!-- Title for the save as PDF option in the printer list. [CHAR LIMIT=30] -->
+    <string name="save_as_pdf">Save as PDF</string>
+
+    <!-- Title for the open all printers UI option in the printer list. [CHAR LIMIT=30] -->
+    <string name="all_printers">All printers&#8230;</string>
+
+    <!-- Select printer activity -->
+
+    <!-- Title for the share action bar menu item. [CHAR LIMIT=20] -->
+    <string name="search">Search</string>
+
+    <!-- Title for the select printer activity. [CHAR LIMIT=30] -->
+    <string name="all_printers_label">All printers</string>
+
+    <!-- Add printer dialog  -->
+
+    <!-- Title for the alert dialog for selecting a print service. [CHAR LIMIT=50] -->
+    <string name="choose_print_service">Choose print service</string>
+
+    <!-- Title for the button to search the play store for print services. [CHAR LIMIT=50] -->
+    <string name="search_play_store">Search in play store</string>
+
+    <!-- Notifications -->
+
+    <!-- Template for the notificaiton label for a printing print job. [CHAR LIMIT=25] -->
+    <string name="printing_notification_title_template">Printing <xliff:g id="print_job_name" example="foo.jpg">%1$s</xliff:g></string>
+
+    <!-- Template for the notificaiton label for a cancelling print job. [CHAR LIMIT=25] -->
+    <string name="cancelling_notification_title_template">Cancelling <xliff:g id="print_job_name" example="foo.jpg">%1$s</xliff:g></string>
+
+    <!-- Template for the notificaiton label for a failed print job. [CHAR LIMIT=25] -->
+    <string name="failed_notification_title_template">Printer error <xliff:g id="print_job_name" example="foo.jpg">%1$s</xliff:g></string>
+
+    <!-- Template for the notificaiton label for a blocked print job. [CHAR LIMIT=25] -->
+    <string name="blocked_notification_title_template">Printer blocked <xliff:g id="print_job_name" example="foo.jpg">%1$s</xliff:g></string>
+
+    <!-- Label for the notification button for cancelling a print job. [CHAR LIMIT=25] -->
+    <string name="cancel">Cancel</string>
+
+    <!-- Label for the notification button for restrating a filed print job. [CHAR LIMIT=25] -->
+    <string name="restart">Restart</string>
+
+    <!-- Message that there is no connection to a printer. [CHAR LIMIT=40] -->
+    <string name="no_connection_to_printer">No connection to printer</string>
+
+    <!-- Label for an unknown reason for failed or blocked print job. [CHAR LIMIT=25] -->
+    <string name="reason_unknown">unknown</string>
+
+    <!-- Arrays -->
+
+    <!-- Color mode labels. -->
+    <string-array name="color_mode_labels">
+        <!-- Color modelabel: Monochrome color scheme, e.g. one color is used. [CHAR LIMIT=20] -->
+        <item>Black &amp; White</item>
+        <!-- Color mode label: Color color scheme, e.g. many colors are used. [CHAR LIMIT=20] -->
+        <item>Color</item>
+    </string-array>
+
+    <!-- Orientation labels. -->
+    <string-array name="orientation_labels">
+        <!-- Orientation label: Portrait page orientation. [CHAR LIMIT=30] -->
+        <item>Portrait</item>
+        <!-- Orientation label: Landscape page orientation [CHAR LIMIT=30] -->
+        <item>Landscape</item>
+    </string-array>
+
+    <!-- Page options labels. -->
+    <string-array name="page_options_labels">
+        <!-- Page range option label: Print all pages [CHAR LIMIT=30] -->
+        <item>All</item>
+        <!-- Page range option label: Print a page range [CHAR LIMIT=30] -->
+        <item>Range</item>
+    </string-array>
+
+    <!-- Permissions -->
+
+    <!-- Title of an application permission, listed so the user can choose whether they want
+         to allow the application to do this. -->
+    <string name="permlab_accessAllPrintJobs">access all print jobs</string>
+    <!-- Description of an application permission, listed so the user can choose whether
+         they want to allow the application to do this. -->
+    <string name="permdesc_accessAllPrintJobs">Allows the holder to access print jobs
+        created by another app. Should never be needed for normal apps.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want
+         to allow the application to do this. -->
+    <string name="permlab_startPrintServiceConfigActivity">start print service configuration activities</string>
+    <!-- Description of an application permission, listed so the user can choose whether they
+         want to allow the application to do this. -->
+    <string name="permdesc_startPrintServiceConfigActivity">Allows the holder to start the
+        configuration activities of a print service. Should never be needed for normal apps.</string>
+
+</resources>
diff --git a/packages/PrintSpooler/res/values/styles.xml b/packages/PrintSpooler/res/values/styles.xml
new file mode 100644
index 0000000..fe11c93
--- /dev/null
+++ b/packages/PrintSpooler/res/values/styles.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+
+    <style name="PrintOptionTitleTextAppearance">
+        <item name="android:textStyle">normal</item>
+        <item name="android:textSize">14sp</item>
+        <item name="android:textAllCaps">true</item>
+        <item name="android:textColor">@color/print_option_title</item>
+    </style>
+
+    <style name="PrintOptionSpinnerStyle">
+        <item name="android:paddingTop">0dip</item>
+        <item name="android:paddingBottom">0dip</item>
+        <item name="android:minWidth">150dip</item>
+        <item name="android:maxWidth">200dip</item>
+        <item name="android:minHeight">?android:attr/listPreferredItemHeightSmall</item>
+    </style>
+
+    <style name="PrintOptionEditTextStyle">
+         <item name="android:selectAllOnFocus">true</item>
+         <item name="android:minHeight">?android:attr/listPreferredItemHeightSmall</item>
+         <item name="android:maxWidth">200dip</item>
+         <item name="android:singleLine">true</item>
+         <item name="android:ellipsize">end</item>
+    </style>
+
+    <style name="PrintOptionTextViewStyle">
+         <item name="android:textAppearance">@style/PrintOptionTitleTextAppearance</item>
+         <item name="android:maxWidth">200dip</item>
+    </style>
+
+</resources>
diff --git a/packages/PrintSpooler/res/values/themes.xml b/packages/PrintSpooler/res/values/themes.xml
new file mode 100644
index 0000000..bb41527
--- /dev/null
+++ b/packages/PrintSpooler/res/values/themes.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+
+    <style name="PrintJobConfigActivityTheme" parent="@android:style/Theme.Holo.Light.NoActionBar">
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:windowSoftInputMode">stateAlwaysHidden|adjustResize</item>
+        <item name="android:windowIsTranslucent">true</item>
+        <item name="android:backgroundDimEnabled">true</item>
+        <item name="android:colorBackgroundCacheHint">@android:color/transparent</item>
+    </style>
+
+    <style name="SelectPrinterActivityTheme" parent="@android:style/Theme.Holo.Light">
+        <item name="android:actionBarStyle">@style/SelectPrinterActivityActionBarStyle</item>
+    </style>
+
+    <style name="SelectPrinterActivityActionBarStyle" parent="@android:style/Widget.Holo.ActionBar">
+        <item name="android:displayOptions">showTitle</item>
+    </style>
+
+</resources>
diff --git a/packages/PrintSpooler/src/com/android/printspooler/FusedPrintersProvider.java b/packages/PrintSpooler/src/com/android/printspooler/FusedPrintersProvider.java
new file mode 100644
index 0000000..0431b94
--- /dev/null
+++ b/packages/PrintSpooler/src/com/android/printspooler/FusedPrintersProvider.java
@@ -0,0 +1,567 @@
+/*
+ * 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.printspooler;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Loader;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.print.PrintManager;
+import android.print.PrinterDiscoverySession;
+import android.print.PrinterDiscoverySession.OnPrintersChangeListener;
+import android.print.PrinterId;
+import android.print.PrinterInfo;
+import android.util.ArrayMap;
+import android.util.AtomicFile;
+import android.util.Log;
+import android.util.Slog;
+import android.util.Xml;
+
+import com.android.internal.util.FastXmlSerializer;
+
+import libcore.io.IoUtils;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This class is responsible for loading printers by doing discovery
+ * and merging the discovered printers with the previously used ones.
+ */
+public class FusedPrintersProvider extends Loader<List<PrinterInfo>> {
+    private static final String LOG_TAG = "FusedPrintersProvider";
+
+    private static final boolean DEBUG = false;
+
+    private static final double WEIGHT_DECAY_COEFFICIENT = 0.95f;
+
+    private static final int MAX_HISTORY_LENGTH = 50;
+
+    private static final int MAX_FAVORITE_PRINTER_COUNT = 4;
+
+    private final List<PrinterInfo> mPrinters =
+            new ArrayList<PrinterInfo>();
+
+    private final List<PrinterInfo> mFavoritePrinters =
+            new ArrayList<PrinterInfo>();
+
+    private final PersistenceManager mPersistenceManager;
+
+    private PrinterDiscoverySession mDiscoverySession;
+
+    private PrinterId mTrackedPrinter;
+
+    public FusedPrintersProvider(Context context) {
+        super(context);
+        mPersistenceManager = new PersistenceManager(context);
+    }
+
+    public void addHistoricalPrinter(PrinterInfo printer) {
+        mPersistenceManager.addPrinterAndWritePrinterHistory(printer);
+    }
+
+    private void computeAndDeliverResult() {
+        if (!isStarted()) {
+            return;
+        }
+
+        List<PrinterInfo> printers = new ArrayList<PrinterInfo>();
+
+        // We want the first few favorite printers on top of the list.
+        final int favoriteCount = Math.min(mFavoritePrinters.size(),
+                MAX_FAVORITE_PRINTER_COUNT);
+        for (int i = 0; i < favoriteCount; i++) {
+            printers.add(mFavoritePrinters.get(i));
+        }
+
+        // Add discovered printers updating favorites if needed.
+        final int printerCount = mPrinters.size();
+        for (int i = 0; i < printerCount; i++) {
+            PrinterInfo discoveredPrinter = mPrinters.get(i);
+            boolean printerHandled = false;
+            for (int j = 0; j< favoriteCount; j++) {
+                PrinterInfo favoritePrinter = printers.get(j);
+                if (favoritePrinter.getId().equals(discoveredPrinter.getId())) {
+                    printers.set(j, discoveredPrinter);
+                    printerHandled = true;
+                    break;
+                }
+            }
+            if (!printerHandled) {
+                printers.add(discoveredPrinter);
+            }
+        }
+
+        // Deliver the printers.
+        deliverResult(printers);
+    }
+
+    @Override
+    protected void onStartLoading() {
+        if (DEBUG) {
+            Log.i(LOG_TAG, "onStartLoading()" + FusedPrintersProvider.this.hashCode());
+        }
+        // The contract is that if we already have a valid,
+        // result the we have to deliver it immediately.
+        if (!mPrinters.isEmpty() || !mFavoritePrinters.isEmpty()) {
+            computeAndDeliverResult();
+        }
+        // Always load the data to ensure discovery period is
+        // started and to make sure obsolete printers are updated.
+        onForceLoad();
+    }
+
+    @Override
+    protected void onStopLoading() {
+        if (DEBUG) {
+            Log.i(LOG_TAG, "onStopLoading()" + FusedPrintersProvider.this.hashCode());
+        }
+        onCancelLoad();
+    }
+
+    @Override
+    protected void onForceLoad() {
+        if (DEBUG) {
+            Log.i(LOG_TAG, "onForceLoad()" + FusedPrintersProvider.this.hashCode());
+        }
+        loadInternal();
+    }
+
+    private void loadInternal() {
+        if (mDiscoverySession == null) {
+            PrintManager printManager = (PrintManager) getContext()
+                    .getSystemService(Context.PRINT_SERVICE);
+            mDiscoverySession = printManager.createPrinterDiscoverySession();
+            mDiscoverySession.setOnPrintersChangeListener(new OnPrintersChangeListener() {
+                @Override
+                public void onPrintersChanged() {
+                    mPrinters.clear();
+                    mPrinters.addAll(mDiscoverySession.getPrinters());
+                    computeAndDeliverResult();
+                }
+            });
+            mPersistenceManager.readPrinterHistory();
+        }
+        if (mPersistenceManager.isReadHistoryCompleted()
+                && !mDiscoverySession.isPrinterDiscoveryStarted()) {
+            final int favoriteCount = Math.min(MAX_FAVORITE_PRINTER_COUNT,
+                    mFavoritePrinters.size());
+            List<PrinterId> printerIds = new ArrayList<PrinterId>(favoriteCount);
+            for (int i = 0; i < favoriteCount; i++) {
+                printerIds.add(mFavoritePrinters.get(i).getId());
+            }
+            mDiscoverySession.startPrinterDisovery(printerIds);
+        }
+    }
+
+    @Override
+    protected boolean onCancelLoad() {
+        if (DEBUG) {
+            Log.i(LOG_TAG, "onCancelLoad()" + FusedPrintersProvider.this.hashCode());
+        }
+        return cancelInternal();
+    }
+
+    private boolean cancelInternal() {
+        if (mDiscoverySession != null
+                && mDiscoverySession.isPrinterDiscoveryStarted()) {
+            if (mTrackedPrinter != null) {
+                mDiscoverySession.stopPrinterStateTracking(mTrackedPrinter);
+                mTrackedPrinter = null;
+            }
+            mDiscoverySession.stopPrinterDiscovery();
+            return true;
+        } else if (mPersistenceManager.isReadHistoryInProgress()) {
+            return mPersistenceManager.stopReadPrinterHistory();
+        }
+        return false;
+    }
+
+    @Override
+    protected void onReset() {
+        if (DEBUG) {
+            Log.i(LOG_TAG, "onReset()" + FusedPrintersProvider.this.hashCode());
+        }
+        onStopLoading();
+        mPrinters.clear();
+        if (mDiscoverySession != null) {
+            mDiscoverySession.destroy();
+            mDiscoverySession = null;
+        }
+    }
+
+    @Override
+    protected void onAbandon() {
+        if (DEBUG) {
+            Log.i(LOG_TAG, "onAbandon()" + FusedPrintersProvider.this.hashCode());
+        }
+        onStopLoading();
+    }
+
+    public void setTrackedPrinter(PrinterId printerId) {
+        if (isStarted() && mDiscoverySession != null
+                && mDiscoverySession.isPrinterDiscoveryStarted()) {
+            if (mTrackedPrinter != null) {
+                mDiscoverySession.stopPrinterStateTracking(mTrackedPrinter);
+            }
+            mTrackedPrinter = printerId;
+            mDiscoverySession.startPrinterStateTracking(printerId);
+        }
+    }
+
+    private final class PersistenceManager {
+        private static final String PERSIST_FILE_NAME = "printer_history.xml";
+
+        private static final String TAG_PRINTERS = "printers";
+
+        private static final String TAG_PRINTER = "printer";
+        private static final String TAG_PRINTER_ID = "printerId";
+
+        private static final String ATTR_LOCAL_ID = "localId";
+        private static final String ATTR_SERVICE_NAME = "serviceName";
+
+        private static final String ATTR_NAME = "name";
+        private static final String ATTR_DESCRIPTION = "description";
+        private static final String ATTR_STATUS = "status";
+
+        private final AtomicFile mStatePersistFile;
+
+        private List<PrinterInfo> mHistoricalPrinters;
+
+        private boolean mReadHistoryCompleted;
+        private boolean mReadHistoryInProgress;
+
+        private ReadTask mReadTask;
+
+        private PersistenceManager(Context context) {
+            mStatePersistFile = new AtomicFile(new File(context.getFilesDir(),
+                    PERSIST_FILE_NAME));
+        }
+
+        public boolean isReadHistoryInProgress() {
+            return mReadHistoryInProgress;
+        }
+
+        public boolean isReadHistoryCompleted() {
+            return mReadHistoryCompleted;
+        }
+
+        public boolean stopReadPrinterHistory() {
+            final boolean cancelled = mReadTask.cancel(true);
+            mReadTask = null;
+            return cancelled;
+        }
+
+        public void readPrinterHistory() {
+            if (DEBUG) {
+                Log.i(LOG_TAG, "read history started");
+            }
+            mReadHistoryInProgress = true;
+            mReadTask = new ReadTask();
+            mReadTask.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, (Void[]) null);
+        }
+
+        @SuppressWarnings("unchecked")
+        public void addPrinterAndWritePrinterHistory(PrinterInfo printer) {
+            if (mHistoricalPrinters.size() >= MAX_HISTORY_LENGTH) {
+                mHistoricalPrinters.remove(0);
+            }
+            mHistoricalPrinters.add(printer);
+            new WriteTask().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR,
+                    new ArrayList<PrinterInfo>(mHistoricalPrinters));
+        }
+
+        private List<PrinterInfo> computeFavoritePrinters(List<PrinterInfo> printers) {
+            Map<PrinterId, PrinterRecord> recordMap =
+                    new ArrayMap<PrinterId, PrinterRecord>();
+
+            // Recompute the weights.
+            float currentWeight = 1.0f;
+            final int printerCount = printers.size();
+            for (int i = printerCount - 1; i >= 0; i--) {
+                PrinterInfo printer = printers.get(i);
+                // Aggregate weight for the same printer
+                PrinterRecord record = recordMap.get(printer.getId());
+                if (record == null) {
+                    record = new PrinterRecord(printer);
+                    recordMap.put(printer.getId(), record);
+                }
+                record.weight += currentWeight;
+                currentWeight *= WEIGHT_DECAY_COEFFICIENT;
+            }
+
+            // Soft the favorite printers.
+            List<PrinterRecord> favoriteRecords = new ArrayList<PrinterRecord>(
+                    recordMap.values());
+            Collections.sort(favoriteRecords);
+
+            // Write the favorites to the output.
+            final int favoriteCount = favoriteRecords.size();
+            List<PrinterInfo> favoritePrinters = new ArrayList<PrinterInfo>(favoriteCount);
+            for (int i = 0; i < favoriteCount; i++) {
+                PrinterInfo printer = favoriteRecords.get(i).printer;
+                favoritePrinters.add(printer);
+            }
+
+            return favoritePrinters;
+        }
+
+        private final class PrinterRecord implements Comparable<PrinterRecord> {
+            public final PrinterInfo printer;
+            public float weight;
+
+            public PrinterRecord(PrinterInfo printer) {
+                this.printer = printer;
+            }
+
+            @Override
+            public int compareTo(PrinterRecord another) {
+                return Float.floatToIntBits(another.weight) - Float.floatToIntBits(weight);
+            }
+        }
+
+        private final class ReadTask extends AsyncTask<Void, Void, List<PrinterInfo>> {
+            @Override
+            protected List<PrinterInfo> doInBackground(Void... args) {
+               return doReadPrinterHistory();
+            }
+
+            @Override
+            protected void onPostExecute(List<PrinterInfo> printers) {
+                if (DEBUG) {
+                    Log.i(LOG_TAG, "read history completed"
+                            + FusedPrintersProvider.this.hashCode());
+                }
+
+                mHistoricalPrinters = printers;
+
+                // Compute the favorite printers.
+                mFavoritePrinters.addAll(computeFavoritePrinters(printers));
+
+                mReadHistoryInProgress = false;
+                mReadHistoryCompleted = true;
+
+                // Deliver the favorites.
+                computeAndDeliverResult();
+
+                // Start loading the available printers.
+                loadInternal();
+
+                // We are done.
+                mReadTask = null;
+            }
+
+            private List<PrinterInfo> doReadPrinterHistory() {
+                FileInputStream in = null;
+                try {
+                    in = mStatePersistFile.openRead();
+                } catch (FileNotFoundException fnfe) {
+                    Log.i(LOG_TAG, "No existing printer history.");
+                    return new ArrayList<PrinterInfo>();
+                }
+                try {
+                    List<PrinterInfo> printers = new ArrayList<PrinterInfo>();
+                    XmlPullParser parser = Xml.newPullParser();
+                    parser.setInput(in, null);
+                    parseState(parser, printers);
+                    return printers;
+                } catch (IllegalStateException ise) {
+                    Slog.w(LOG_TAG, "Failed parsing ", ise);
+                } catch (NullPointerException npe) {
+                    Slog.w(LOG_TAG, "Failed parsing ", npe);
+                } catch (NumberFormatException nfe) {
+                    Slog.w(LOG_TAG, "Failed parsing ", nfe);
+                } catch (XmlPullParserException xppe) {
+                    Slog.w(LOG_TAG, "Failed parsing ", xppe);
+                } catch (IOException ioe) {
+                    Slog.w(LOG_TAG, "Failed parsing ", ioe);
+                } catch (IndexOutOfBoundsException iobe) {
+                    Slog.w(LOG_TAG, "Failed parsing ", iobe);
+                } finally {
+                    IoUtils.closeQuietly(in);
+                }
+
+                return Collections.emptyList();
+            }
+
+            private void parseState(XmlPullParser parser, List<PrinterInfo> outPrinters)
+                    throws IOException, XmlPullParserException {
+                parser.next();
+                skipEmptyTextTags(parser);
+                expect(parser, XmlPullParser.START_TAG, TAG_PRINTERS);
+                parser.next();
+
+                while (parsePrinter(parser, outPrinters)) {
+                    // Be nice and respond to cancellation
+                    if (isCancelled()) {
+                        return;
+                    }
+                    parser.next();
+                }
+
+                skipEmptyTextTags(parser);
+                expect(parser, XmlPullParser.END_TAG, TAG_PRINTERS);
+            }
+
+            private boolean parsePrinter(XmlPullParser parser, List<PrinterInfo> outPrinters)
+                    throws IOException, XmlPullParserException {
+                skipEmptyTextTags(parser);
+                if (!accept(parser, XmlPullParser.START_TAG, TAG_PRINTER)) {
+                    return false;
+                }
+
+                String name = parser.getAttributeValue(null, ATTR_NAME);
+                String description = parser.getAttributeValue(null, ATTR_DESCRIPTION);
+                final int status = Integer.parseInt(parser.getAttributeValue(null, ATTR_STATUS));
+
+                parser.next();
+
+                skipEmptyTextTags(parser);
+                expect(parser, XmlPullParser.START_TAG, TAG_PRINTER_ID);
+                String localId = parser.getAttributeValue(null, ATTR_LOCAL_ID);
+                ComponentName service = ComponentName.unflattenFromString(parser.getAttributeValue(
+                        null, ATTR_SERVICE_NAME));
+                PrinterId printerId =  new PrinterId(service, localId);
+                parser.next();
+                skipEmptyTextTags(parser);
+                expect(parser, XmlPullParser.END_TAG, TAG_PRINTER_ID);
+                parser.next();
+
+                PrinterInfo.Builder builder = new PrinterInfo.Builder(printerId, name, status);
+                builder.setDescription(description);
+                PrinterInfo printer = builder.build();
+
+                outPrinters.add(printer);
+
+                if (DEBUG) {
+                    Log.i(LOG_TAG, "[RESTORED] " + printer);
+                }
+
+                skipEmptyTextTags(parser);
+                expect(parser, XmlPullParser.END_TAG, TAG_PRINTER);
+
+                return true;
+            }
+
+            private void expect(XmlPullParser parser, int type, String tag)
+                    throws IOException, XmlPullParserException {
+                if (!accept(parser, type, tag)) {
+                    throw new XmlPullParserException("Exepected event: " + type
+                            + " and tag: " + tag + " but got event: " + parser.getEventType()
+                            + " and tag:" + parser.getName());
+                }
+            }
+
+            private void skipEmptyTextTags(XmlPullParser parser)
+                    throws IOException, XmlPullParserException {
+                while (accept(parser, XmlPullParser.TEXT, null)
+                        && "\n".equals(parser.getText())) {
+                    parser.next();
+                }
+            }
+
+            private boolean accept(XmlPullParser parser, int type, String tag)
+                    throws IOException, XmlPullParserException {
+                if (parser.getEventType() != type) {
+                    return false;
+                }
+                if (tag != null) {
+                    if (!tag.equals(parser.getName())) {
+                        return false;
+                    }
+                } else if (parser.getName() != null) {
+                    return false;
+                }
+                return true;
+            }
+        };
+
+        private final class WriteTask extends AsyncTask<List<PrinterInfo>, Void, Void> {
+            @Override
+            protected Void doInBackground(List<PrinterInfo>... printers) {
+                doWritePrinterHistory(printers[0]);
+                return null;
+            }
+
+            private void doWritePrinterHistory(List<PrinterInfo> printers) {
+                FileOutputStream out = null;
+                try {
+                    out = mStatePersistFile.startWrite();
+
+                    XmlSerializer serializer = new FastXmlSerializer();
+                    serializer.setOutput(out, "utf-8");
+                    serializer.startDocument(null, true);
+                    serializer.startTag(null, TAG_PRINTERS);
+
+                    final int printerCount = printers.size();
+                    for (int i = 0; i < printerCount; i++) {
+                        PrinterInfo printer = printers.get(i);
+
+                        serializer.startTag(null, TAG_PRINTER);
+
+                        serializer.attribute(null, ATTR_NAME, printer.getName());
+                        // Historical printers are always stored as unavailable.
+                        serializer.attribute(null, ATTR_STATUS, String.valueOf(
+                                PrinterInfo.STATUS_UNAVAILABLE));
+                        String description = printer.getDescription();
+                        if (description != null) {
+                            serializer.attribute(null, ATTR_DESCRIPTION, description);
+                        }
+
+                        PrinterId printerId = printer.getId();
+                        serializer.startTag(null, TAG_PRINTER_ID);
+                        serializer.attribute(null, ATTR_LOCAL_ID, printerId.getLocalId());
+                        serializer.attribute(null, ATTR_SERVICE_NAME, printerId.getServiceName()
+                                .flattenToString());
+                        serializer.endTag(null, TAG_PRINTER_ID);
+
+                        serializer.endTag(null, TAG_PRINTER);
+
+                        if (DEBUG) {
+                            Log.i(LOG_TAG, "[PERSISTED] " + printer);
+                        }
+                    }
+
+                    serializer.endTag(null, TAG_PRINTERS);
+                    serializer.endDocument();
+                    mStatePersistFile.finishWrite(out);
+
+                    if (DEBUG) {
+                        Log.i(LOG_TAG, "[PERSIST END]");
+                    }
+                } catch (IOException ioe) {
+                    Slog.w(LOG_TAG, "Failed to write printer history, restoring backup.", ioe);
+                    mStatePersistFile.failWrite(out);
+                } finally {
+                    IoUtils.closeQuietly(out);
+                }
+            }
+        };
+    }
+}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/NotificationController.java b/packages/PrintSpooler/src/com/android/printspooler/NotificationController.java
new file mode 100644
index 0000000..43a751c
--- /dev/null
+++ b/packages/PrintSpooler/src/com/android/printspooler/NotificationController.java
@@ -0,0 +1,266 @@
+/*
+ * 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.printspooler;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.print.IPrintManager;
+import android.print.PrintJobInfo;
+import android.print.PrintManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+/**
+ * This class is responsible for updating the print notifications
+ * based on print job state transitions.
+ */
+public class NotificationController {
+    public static final boolean DEBUG = true && Build.IS_DEBUGGABLE;
+
+    public static final String LOG_TAG = "NotificationController";
+
+    private static final String INTENT_ACTION_CANCEL_PRINTJOB = "INTENT_ACTION_CANCEL_PRINTJOB";
+    private static final String INTENT_ACTION_RESTART_PRINTJOB = "INTENT_ACTION_RESTART_PRINTJOB";
+    private static final String INTENT_EXTRA_PRINTJOB_ID = "INTENT_EXTRA_PRINTJOB_ID";
+    private static final String INTENT_EXTRA_PRINTJOB_LABEL = "INTENT_EXTRA_PRINTJOB_LABEL";
+    private static final String INTENT_EXTRA_PRINTER_NAME = "INTENT_EXTRA_PRINTER_NAME";
+
+    private final Context mContext;
+    private final NotificationManager mNotificationManager;
+
+    public NotificationController(Context context) {
+        mContext = context;
+        mNotificationManager = (NotificationManager)
+                mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+    }
+
+    public void onPrintJobStateChanged(PrintJobInfo printJob) {
+        if (DEBUG) {
+            Log.i(LOG_TAG, "onPrintJobStateChanged() printJobId: " + printJob.getId()
+                    + " state:" + PrintJobInfo.stateToString(printJob.getState()));
+        }
+        switch (printJob.getState()) {
+            case PrintJobInfo.STATE_QUEUED:
+            case PrintJobInfo.STATE_STARTED: {
+                createPrintingNotification(printJob);
+            } break;
+
+            case PrintJobInfo.STATE_FAILED: {
+                createFailedNotification(printJob);
+            } break;
+
+            case PrintJobInfo.STATE_COMPLETED:
+            case PrintJobInfo.STATE_CANCELED: {
+                removeNotification(printJob.getId());
+            } break;
+
+            case PrintJobInfo.STATE_BLOCKED: {
+                createBlockedNotification(printJob);
+            } break;
+        }
+    }
+
+    private void createPrintingNotification(PrintJobInfo printJob) {
+        Notification.Builder builder = new Notification.Builder(mContext)
+                .setSmallIcon(R.drawable.stat_notify_print)
+                .setContentTitle(mContext.getString(R.string.printing_notification_title_template,
+                        printJob.getLabel()))
+                .addAction(R.drawable.stat_notify_cancelling, mContext.getString(R.string.cancel),
+                        createCancelIntent(printJob))
+                .setContentText(printJob.getPrinterName())
+                .setWhen(System.currentTimeMillis())
+                .setOngoing(true)
+                .setShowWhen(true);
+        mNotificationManager.notify(printJob.getId(), builder.build());
+    }
+
+    private void createFailedNotification(PrintJobInfo printJob) {
+        String reason = !TextUtils.isEmpty(printJob.getStateReason())
+                ? printJob.getStateReason() : mContext.getString(R.string.reason_unknown);
+
+        Notification.Builder builder = new Notification.Builder(mContext)
+                .setSmallIcon(R.drawable.stat_notify_error)
+                .setContentTitle(mContext.getString(R.string.failed_notification_title_template,
+                        printJob.getLabel()))
+                .addAction(R.drawable.stat_notify_cancelling, mContext.getString(R.string.cancel),
+                        createCancelIntent(printJob))
+                .addAction(android.R.drawable.ic_secure, mContext.getString(R.string.restart),
+                        createRestartIntent(printJob.getId()))
+                .setContentText(reason)
+                .setWhen(System.currentTimeMillis())
+                .setOngoing(true)
+                .setShowWhen(true);
+        mNotificationManager.notify(printJob.getId(), builder.build());
+    }
+
+    private void createBlockedNotification(PrintJobInfo printJob) {
+        String reason = !TextUtils.isEmpty(printJob.getStateReason())
+                ? printJob.getStateReason() : mContext.getString(R.string.reason_unknown);
+
+        Notification.Builder builder = new Notification.Builder(mContext)
+                .setSmallIcon(R.drawable.stat_notify_error)
+                .setContentTitle(mContext.getString(R.string.blocked_notification_title_template,
+                        printJob.getLabel()))
+                .addAction(R.drawable.stat_notify_cancelling, mContext.getString(R.string.cancel),
+                        createCancelIntent(printJob))
+                .setContentText(reason)
+                .setWhen(System.currentTimeMillis())
+                .setOngoing(true)
+                .setShowWhen(true);
+        mNotificationManager.notify(printJob.getId(), builder.build());
+    }
+
+    private void removeNotification(int printJobId) {
+        mNotificationManager.cancel(printJobId);
+    }
+
+    private PendingIntent createCancelIntent(PrintJobInfo printJob) {
+        Intent intent = new Intent(mContext, NotificationBroadcastReceiver.class);
+        intent.setAction(INTENT_ACTION_CANCEL_PRINTJOB + "_" + String.valueOf(printJob.getId()));
+        intent.putExtra(INTENT_EXTRA_PRINTJOB_ID, printJob.getId());
+        intent.putExtra(INTENT_EXTRA_PRINTJOB_LABEL, printJob.getLabel());
+        intent.putExtra(INTENT_EXTRA_PRINTER_NAME, printJob.getPrinterName());
+        return PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT);
+    }
+
+    private PendingIntent createRestartIntent(int printJobId) {
+        Intent intent = new Intent(mContext, NotificationBroadcastReceiver.class);
+        intent.setAction(INTENT_ACTION_RESTART_PRINTJOB + "_" + String.valueOf(printJobId));
+        intent.putExtra(INTENT_EXTRA_PRINTJOB_ID, printJobId);
+        return PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT);
+    }
+
+    public static final class NotificationBroadcastReceiver extends BroadcastReceiver {
+        private static final String LOG_TAG = "NotificationBroadcastReceiver";
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action != null && action.startsWith(INTENT_ACTION_CANCEL_PRINTJOB)) {
+                final int printJobId = intent.getExtras().getInt(INTENT_EXTRA_PRINTJOB_ID);
+                String printJobLabel = intent.getExtras().getString(INTENT_EXTRA_PRINTJOB_LABEL);
+                String printerName = intent.getExtras().getString(INTENT_EXTRA_PRINTER_NAME);
+                handleCancelPrintJob(context, printJobId, printJobLabel, printerName);
+            } else if (action != null && action.startsWith(INTENT_ACTION_RESTART_PRINTJOB)) {
+                final int printJobId = intent.getExtras().getInt(INTENT_EXTRA_PRINTJOB_ID);
+                handleRestartPrintJob(context, printJobId);
+            }
+        }
+
+        private void handleCancelPrintJob(final Context context, final int printJobId,
+                final String printJobLabel, final String printerName) {
+            if (DEBUG) {
+                Log.i(LOG_TAG, "handleCancelPrintJob() printJobId:" + printJobId);
+            }
+
+            // Put up a notification that we are trying to cancel.
+            NotificationManager notificationManager = (NotificationManager)
+                    context.getSystemService(Context.NOTIFICATION_SERVICE);
+            Notification.Builder builder = new Notification.Builder(context)
+                    .setSmallIcon(R.drawable.stat_notify_cancelling)
+                    .setContentTitle(context.getString(
+                            R.string.cancelling_notification_title_template,
+                            printJobLabel))
+                    .setContentText(printerName)
+                    .setWhen(System.currentTimeMillis())
+                    .setOngoing(true)
+                    .setShowWhen(true);
+            notificationManager.notify(printJobId, builder.build());
+
+            // Call into the print manager service off the main thread since
+            // the print manager service may end up binding to the print spooler
+            // service which binding is handled on the main thread.
+            PowerManager powerManager = (PowerManager)
+                    context.getSystemService(Context.POWER_SERVICE);
+            final WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+                    LOG_TAG);
+            wakeLock.acquire();
+
+            new AsyncTask<Void, Void, Void>() {
+                @Override
+                protected Void doInBackground(Void... params) {
+                    // We need to request the cancellation to be done by the print
+                    // manager service since it has to communicate with the managing
+                    // print service to request the cancellation. Also we need the
+                    // system service to be bound to the spooler since canceling a
+                    // print job will trigger persistence of current jobs which is
+                    // done on another thread and until it finishes the spooler has
+                    // to be kept around.
+                    try {
+                    IPrintManager printManager = IPrintManager.Stub.asInterface(
+                            ServiceManager.getService(Context.PRINT_SERVICE));
+                        printManager.cancelPrintJob(printJobId, PrintManager.APP_ID_ANY,
+                                UserHandle.myUserId());
+                    } catch (RemoteException re) {
+                        Log.i(LOG_TAG, "Error requestion print job cancellation", re);
+                    } finally {
+                        wakeLock.release();
+                    }
+                    return null;
+                }
+            }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
+        }
+
+        private void handleRestartPrintJob(final Context context, final int printJobId) {
+            if (DEBUG) {
+                Log.i(LOG_TAG, "handleRestartPrintJob() printJobId:" + printJobId);
+            }
+
+            // Call into the print manager service off the main thread since
+            // the print manager service may end up binding to the print spooler
+            // service which binding is handled on the main thread.
+            PowerManager powerManager = (PowerManager)
+                    context.getSystemService(Context.POWER_SERVICE);
+            final WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+                    LOG_TAG);
+            wakeLock.acquire();
+
+            new AsyncTask<Void, Void, Void>() {
+                @Override
+                protected Void doInBackground(Void... params) {
+                    // We need to request the restart to be done by the print manager
+                    // service since the latter must be bound to the spooler because
+                    // restarting a print job will trigger persistence of current jobs
+                    // which is done on another thread and until it finishes the spooler has
+                    // to be kept around.
+                    try {
+                        IPrintManager printManager = IPrintManager.Stub.asInterface(
+                                ServiceManager.getService(Context.PRINT_SERVICE));
+                        printManager.restartPrintJob(printJobId, PrintManager.APP_ID_ANY,
+                                UserHandle.myUserId());
+                    } catch (RemoteException re) {
+                        Log.i(LOG_TAG, "Error requestion print job restart", re);
+                    } finally {
+                        wakeLock.release();
+                    }
+                    return null;
+                }
+            }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
+        }
+    }
+}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
new file mode 100644
index 0000000..14f60f1
--- /dev/null
+++ b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
@@ -0,0 +1,2281 @@
+/*
+ * 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.printspooler;
+
+import android.app.Activity;
+import android.app.Dialog;
+import android.app.LoaderManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.Loader;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.database.DataSetObserver;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.IBinder.DeathRecipient;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.print.ILayoutResultCallback;
+import android.print.IPrintDocumentAdapter;
+import android.print.IWriteResultCallback;
+import android.print.PageRange;
+import android.print.PrintAttributes;
+import android.print.PrintAttributes.Margins;
+import android.print.PrintAttributes.MediaSize;
+import android.print.PrintAttributes.Resolution;
+import android.print.PrintDocumentAdapter;
+import android.print.PrintDocumentInfo;
+import android.print.PrintJobInfo;
+import android.print.PrintManager;
+import android.print.PrinterCapabilitiesInfo;
+import android.print.PrinterId;
+import android.print.PrinterInfo;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextUtils.SimpleStringSplitter;
+import android.text.TextWatcher;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.MeasureSpec;
+import android.view.View.OnAttachStateChangeListener;
+import android.view.View.OnClickListener;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+import android.view.ViewPropertyAnimator;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.ArrayAdapter;
+import android.widget.BaseAdapter;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.Spinner;
+import android.widget.TextView;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import libcore.io.IoUtils;
+
+/**
+ * Activity for configuring a print job.
+ */
+public class PrintJobConfigActivity extends Activity {
+
+    private static final String LOG_TAG = "PrintJobConfigActivity";
+
+    private static final boolean DEBUG = true && Build.IS_DEBUGGABLE;
+
+    public static final String EXTRA_PRINT_DOCUMENT_ADAPTER = "printDocumentAdapter";
+    public static final String EXTRA_PRINT_ATTRIBUTES = "printAttributes";
+    public static final String EXTRA_PRINT_JOB_ID = "printJobId";
+
+    public static final String INTENT_EXTRA_PRINTER_ID = "INTENT_EXTRA_PRINTER_ID";
+
+    private static final int LOADER_ID_PRINTERS_LOADER = 1;
+
+    private static final int ORIENTATION_PORTRAIT = 0;
+    private static final int ORIENTATION_LANDSCAPE = 1;
+
+    private static final int DEST_ADAPTER_MAX_ITEM_COUNT = 9;
+
+    private static final int DEST_ADAPTER_ITEM_ID_SAVE_AS_PDF = Integer.MAX_VALUE;
+    private static final int DEST_ADAPTER_ITEM_ID_ALL_PRINTERS = Integer.MAX_VALUE - 1;
+
+    private static final int ACTIVITY_REQUEST_CREATE_FILE = 1;
+    private static final int ACTIVITY_REQUEST_SELECT_PRINTER = 2;
+
+    private static final int CONTROLLER_STATE_FINISHED = 1;
+    private static final int CONTROLLER_STATE_FAILED = 2;
+    private static final int CONTROLLER_STATE_CANCELLED = 3;
+    private static final int CONTROLLER_STATE_INITIALIZED = 4;
+    private static final int CONTROLLER_STATE_STARTED = 5;
+    private static final int CONTROLLER_STATE_LAYOUT_STARTED = 6;
+    private static final int CONTROLLER_STATE_LAYOUT_COMPLETED = 7;
+    private static final int CONTROLLER_STATE_WRITE_STARTED = 8;
+    private static final int CONTROLLER_STATE_WRITE_COMPLETED = 9;
+
+    private static final int EDITOR_STATE_INITIALIZED = 1;
+    private static final int EDITOR_STATE_CONFIRMED_PRINT = 2;
+    private static final int EDITOR_STATE_CANCELLED = 3;
+
+    private static final int MIN_COPIES = 1;
+    private static final String MIN_COPIES_STRING = String.valueOf(MIN_COPIES);
+
+    private static final Pattern PATTERN_DIGITS = Pattern.compile("\\d");
+
+    private static final Pattern PATTERN_ESCAPE_SPECIAL_CHARS = Pattern.compile(
+            "(?=[]\\[+&|!(){}^\"~*?:\\\\])");
+
+    private static final Pattern PATTERN_PAGE_RANGE = Pattern.compile(
+            "([0-9]+[\\s]*[\\-]?[\\s]*[0-9]*[\\s]*[,]?[\\s]*)+");
+
+    public static final PageRange[] ALL_PAGES_ARRAY = new PageRange[] {PageRange.ALL_PAGES};
+
+    private final PrintAttributes mOldPrintAttributes = new PrintAttributes.Builder().build();
+    private final PrintAttributes mCurrPrintAttributes = new PrintAttributes.Builder().build();
+
+    private final DeathRecipient mDeathRecipient = new DeathRecipient() {
+        @Override
+        public void binderDied() {
+            finish();
+        }
+    };
+
+    private Editor mEditor;
+    private Document mDocument;
+    private PrintController mController;
+
+    private int mPrintJobId;
+
+    private IBinder mIPrintDocumentAdapter;
+
+    private Dialog mGeneratingPrintJobDialog;
+
+    @Override
+    protected void onCreate(Bundle bundle) {
+        super.onCreate(bundle);
+
+        Bundle extras = getIntent().getExtras();
+
+        mPrintJobId = extras.getInt(EXTRA_PRINT_JOB_ID, -1);
+        if (mPrintJobId < 0) {
+            throw new IllegalArgumentException("Invalid print job id: " + mPrintJobId);
+        }
+
+        mIPrintDocumentAdapter = extras.getBinder(EXTRA_PRINT_DOCUMENT_ADAPTER);
+        if (mIPrintDocumentAdapter == null) {
+            throw new IllegalArgumentException("PrintDocumentAdapter cannot be null");
+        }
+
+        PrintAttributes attributes = getIntent().getParcelableExtra(EXTRA_PRINT_ATTRIBUTES);
+        if (attributes != null) {
+            mCurrPrintAttributes.copyFrom(attributes);
+        }
+
+        setContentView(R.layout.print_job_config_activity_container);
+
+        mDocument = new Document();
+        mController = new PrintController(new RemotePrintDocumentAdapter(
+                IPrintDocumentAdapter.Stub.asInterface(mIPrintDocumentAdapter),
+                PrintSpoolerService.peekInstance().generateFileForPrintJob(mPrintJobId)));
+        mEditor = new Editor();
+
+        try {
+            mIPrintDocumentAdapter.linkToDeath(mDeathRecipient, 0);
+        } catch (RemoteException re) {
+            finish();
+            return;
+        }
+
+        mController.initialize();
+        mEditor.initialize();
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        mEditor.refreshCurrentPrinter();
+    }
+
+    @Override
+    protected void onDestroy() {
+        // We can safely do the work in here since at this point
+        // the system is bound to our (spooler) process which
+        // guarantees that this process will not be killed.
+        if (mController.hasStarted()) {
+            mController.finish();
+        }
+        if (mEditor.isPrintConfirmed() && mController.isFinished()) {
+            PrintSpoolerService.peekInstance().setPrintJobState(mPrintJobId,
+                    PrintJobInfo.STATE_QUEUED, null);
+        } else {
+            PrintSpoolerService.peekInstance().setPrintJobState(mPrintJobId,
+                    PrintJobInfo.STATE_CANCELED, null);
+        }
+        mIPrintDocumentAdapter.unlinkToDeath(mDeathRecipient, 0);
+        if (mGeneratingPrintJobDialog != null) {
+            mGeneratingPrintJobDialog.dismiss();
+            mGeneratingPrintJobDialog = null;
+        }
+        super.onDestroy();
+    }
+
+    public boolean onTouchEvent(MotionEvent event) {
+        if (!mEditor.isPrintConfirmed() && mEditor.shouldCloseOnTouch(event)) {
+            if (!mController.isWorking()) {
+                PrintJobConfigActivity.this.finish();
+            }
+            mEditor.cancel();
+            return true;
+        }
+        return super.onTouchEvent(event);
+    }
+
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if (keyCode == KeyEvent.KEYCODE_BACK) {
+            event.startTracking();
+        }
+        return super.onKeyDown(keyCode, event);
+    }
+
+    public boolean onKeyUp(int keyCode, KeyEvent event) {
+        if (keyCode == KeyEvent.KEYCODE_BACK) {
+            if (mEditor.isShwoingGeneratingPrintJobUi()) {
+                return true;
+            }
+            if (event.isTracking() && !event.isCanceled()) {
+                if (!mController.isWorking()) {
+                    PrintJobConfigActivity.this.finish();
+                }
+            }
+            mEditor.cancel();
+            return true;
+        }
+        return super.onKeyUp(keyCode, event);
+    }
+
+    private boolean printAttributesChanged() {
+        return !mOldPrintAttributes.equals(mCurrPrintAttributes);
+    }
+
+    private class PrintController {
+        private final AtomicInteger mRequestCounter = new AtomicInteger();
+
+        private final RemotePrintDocumentAdapter mRemotePrintAdapter;
+
+        private final Bundle mMetadata;
+
+        private final ControllerHandler mHandler;
+
+        private final LayoutResultCallback mLayoutResultCallback;
+
+        private final WriteResultCallback mWriteResultCallback;
+
+        private int mControllerState = CONTROLLER_STATE_INITIALIZED;
+
+        private boolean mHasStarted;
+
+        private PageRange[] mRequestedPages;
+
+        public PrintController(RemotePrintDocumentAdapter adapter) {
+            mRemotePrintAdapter = adapter;
+            mMetadata = new Bundle();
+            mHandler = new ControllerHandler(getMainLooper());
+            mLayoutResultCallback = new LayoutResultCallback(mHandler);
+            mWriteResultCallback = new WriteResultCallback(mHandler);
+        }
+
+        public void initialize() {
+            mHasStarted = false;
+            mControllerState = CONTROLLER_STATE_INITIALIZED;
+        }
+
+        public void cancel() {
+            mControllerState = CONTROLLER_STATE_CANCELLED;
+        }
+
+        public boolean isCancelled() {
+            return (mControllerState == CONTROLLER_STATE_CANCELLED);
+        }
+
+        public boolean isFinished() {
+            return (mControllerState == CONTROLLER_STATE_FINISHED);
+        }
+
+        public boolean hasStarted() {
+            return mHasStarted;
+        }
+
+        public boolean hasPerformedLayout() {
+            return mControllerState >= CONTROLLER_STATE_LAYOUT_COMPLETED;
+        }
+
+        public boolean isWorking() {
+            return mControllerState == CONTROLLER_STATE_LAYOUT_STARTED
+                    || mControllerState == CONTROLLER_STATE_WRITE_STARTED;
+        }
+
+        public void start() {
+            mControllerState = CONTROLLER_STATE_STARTED;
+            mHasStarted = true;
+            mRemotePrintAdapter.start();
+        }
+
+        public void update() {
+            if (!mController.hasStarted()) {
+                mController.start();
+            }
+            if (!printAttributesChanged()) {
+                if (mDocument.info == null) {
+                    // We are waiting for the result of a layout, so do nothing.
+                    return;
+                }
+                // If the attributes didn't change and we have done a layout, then
+                // we do not do a layout but may have to ask the app to write some
+                // pages. Hence, pretend layout completed and nothing changed, so
+                // we handle writing as usual.
+                handleOnLayoutFinished(mDocument.info, false, mRequestCounter.get());
+            } else {
+                PrintSpoolerService.peekInstance().setPrintJobAttributesNoPersistence(
+                        mPrintJobId, mCurrPrintAttributes);
+
+                mMetadata.putBoolean(PrintDocumentAdapter.METADATA_KEY_PRINT_PREVIEW,
+                        !mEditor.isPrintConfirmed());
+
+                mControllerState = CONTROLLER_STATE_LAYOUT_STARTED;
+
+                mRemotePrintAdapter.layout(mOldPrintAttributes, mCurrPrintAttributes,
+                        mLayoutResultCallback, mMetadata, mRequestCounter.incrementAndGet());
+
+                mOldPrintAttributes.copyFrom(mCurrPrintAttributes);
+            }
+        }
+
+        public void finish() {
+            mControllerState = CONTROLLER_STATE_FINISHED;
+            mRemotePrintAdapter.finish();
+        }
+
+        private void handleOnLayoutFinished(PrintDocumentInfo info,
+                boolean layoutChanged, int sequence) {
+            if (mRequestCounter.get() != sequence) {
+                return;
+            }
+
+            if (isCancelled()) {
+                mEditor.updateUi();
+                if (mEditor.isDone()) {
+                    PrintJobConfigActivity.this.finish();
+                }
+                return;
+            }
+
+            mControllerState = CONTROLLER_STATE_LAYOUT_COMPLETED;
+
+            // If the info changed, we update the document and the print job.
+            final boolean infoChanged = !info.equals(mDocument.info);
+            if (infoChanged) {
+                mDocument.info = info;
+                // Set the info.
+                PrintSpoolerService.peekInstance().setPrintJobPrintDocumentInfoNoPersistence(
+                        mPrintJobId, info);
+            }
+
+            // If the document info or the layout changed, then
+            // drop the pages since we have to fetch them again.
+            if (infoChanged || layoutChanged) {
+                mDocument.pages = null;
+                PrintSpoolerService.peekInstance().setPrintJobPagesNoPersistence(
+                        mPrintJobId, null);
+            }
+
+            // No pages means that the user selected an invalid range while we
+            // were doing a layout or the layout returned a document info for
+            // which the selected range is invalid. In such a case we do not
+            // write anything and wait for the user to fix the range which will
+            // trigger an update.
+            mRequestedPages = mEditor.getRequestedPages();
+            if (mRequestedPages == null) {
+                mEditor.updateUi();
+                if (mEditor.isDone()) {
+                    PrintJobConfigActivity.this.finish();
+                }
+                return;
+            }
+
+            // If the info and the layout did not change and we already have
+            // the requested pages, then nothing else to do.
+            if (!infoChanged && !layoutChanged
+                    && PageRangeUtils.contains(mDocument.pages, mRequestedPages)) {
+                if (mEditor.isDone()) {
+                    requestCreatePdfFileOrFinish();
+                }
+                return;
+            }
+
+            mEditor.updateUi();
+
+            // Request a write of the pages of interest.
+            mControllerState = CONTROLLER_STATE_WRITE_STARTED;
+            mRemotePrintAdapter.write(mRequestedPages, mWriteResultCallback,
+                    mRequestCounter.incrementAndGet());
+        }
+
+        private void handleOnLayoutFailed(CharSequence error, int sequence) {
+            if (mRequestCounter.get() != sequence) {
+                return;
+            }
+            mControllerState = CONTROLLER_STATE_FAILED;
+            // TODO: We need some UI for announcing an error.
+            Log.e(LOG_TAG, "Error during layout: " + error);
+            PrintJobConfigActivity.this.finish();
+        }
+
+        private void handleOnWriteFinished(PageRange[] pages, int sequence) {
+            if (mRequestCounter.get() != sequence) {
+                return;
+            }
+
+            if (isCancelled()) {
+                if (mEditor.isDone()) {
+                    PrintJobConfigActivity.this.finish();
+                }
+                return;
+            }
+
+            mControllerState = CONTROLLER_STATE_WRITE_COMPLETED;
+
+            // Update the document size.
+            File file = PrintSpoolerService.peekInstance()
+                    .generateFileForPrintJob(mPrintJobId);
+            mDocument.info.setDataSize(file.length());
+
+            // Update which pages we have fetched.
+            mDocument.pages = PageRangeUtils.normalize(pages);
+
+            if (DEBUG) {
+                Log.i(LOG_TAG, "Requested: " + Arrays.toString(mRequestedPages)
+                        + " and got: " + Arrays.toString(mDocument.pages));
+            }
+
+            // Adjust the print job pages based on what was requested and written.
+            // The cases are ordered in the most expected to the least expected.
+            if (Arrays.equals(mDocument.pages, mRequestedPages)) {
+                // We got a document with exactly the pages we wanted. Hence,
+                // the printer has to print all pages in the data.
+                PrintSpoolerService.peekInstance().setPrintJobPagesNoPersistence(mPrintJobId,
+                        ALL_PAGES_ARRAY);
+            } else if (Arrays.equals(mDocument.pages, ALL_PAGES_ARRAY)) {
+                // We requested specific pages but got all of them. Hence,
+                // the printer has to print only the requested pages.
+                PrintSpoolerService.peekInstance().setPrintJobPagesNoPersistence(mPrintJobId,
+                        mRequestedPages);
+            } else if (PageRangeUtils.contains(mDocument.pages, mRequestedPages)) {
+                // We requested specific pages and got more but not all pages.
+                // Hence, we have to offset appropriately the printed pages to
+                // exclude the pages we did not request. Note that pages is
+                // guaranteed to be not null and not empty.
+                final int offset = mDocument.pages[0].getStart() - pages[0].getStart();
+                PageRange[] offsetPages = Arrays.copyOf(mDocument.pages, mDocument.pages.length);
+                PageRangeUtils.offsetStart(offsetPages, offset);
+                PrintSpoolerService.peekInstance().setPrintJobPagesNoPersistence(mPrintJobId,
+                        offsetPages);
+            } else if (Arrays.equals(mRequestedPages, ALL_PAGES_ARRAY)
+                    && mDocument.pages.length == 1 && mDocument.pages[0].getStart() == 0
+                    && mDocument.pages[0].getEnd() == mDocument.info.getPageCount() - 1) {
+                // We requested all pages via the special constant and got all
+                // of them as an explicit enumeration. Hence, the printer has
+                // to print only the requested pages.
+                PrintSpoolerService.peekInstance().setPrintJobPagesNoPersistence(mPrintJobId,
+                        mDocument.pages);
+            } else {
+                // We did not get the pages we requested, then the application
+                // misbehaves, so we fail quickly.
+                // TODO: We need some UI for announcing an error.
+                mControllerState = CONTROLLER_STATE_FAILED;
+                Log.e(LOG_TAG, "Received invalid pages from the app");
+                PrintJobConfigActivity.this.finish();
+            }
+
+            if (mEditor.isDone()) {
+                requestCreatePdfFileOrFinish();
+            }
+        }
+
+        private void requestCreatePdfFileOrFinish() {
+            if (mEditor.isPrintingToPdf()) {
+                PrintJobInfo printJob = PrintSpoolerService.peekInstance()
+                        .getPrintJobInfo(mPrintJobId, PrintManager.APP_ID_ANY);
+                Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
+                intent.setType("application/pdf");
+                intent.putExtra(Intent.EXTRA_TITLE, printJob.getLabel());
+                startActivityForResult(intent, ACTIVITY_REQUEST_CREATE_FILE);
+            } else {
+                PrintJobConfigActivity.this.finish();
+            }
+        }
+
+        private void handleOnWriteFailed(CharSequence error, int sequence) {
+            if (mRequestCounter.get() != sequence) {
+                return;
+            }
+            mControllerState = CONTROLLER_STATE_FAILED;
+            Log.e(LOG_TAG, "Error during write: " + error);
+            PrintJobConfigActivity.this.finish();
+        }
+
+        private final class ControllerHandler extends Handler {
+            public static final int MSG_ON_LAYOUT_FINISHED = 1;
+            public static final int MSG_ON_LAYOUT_FAILED = 2;
+            public static final int MSG_ON_WRITE_FINISHED = 3;
+            public static final int MSG_ON_WRITE_FAILED = 4;
+
+            public ControllerHandler(Looper looper) {
+                super(looper, null, false);
+            }
+
+            @Override
+            public void handleMessage(Message message) {
+                switch (message.what) {
+                    case MSG_ON_LAYOUT_FINISHED: {
+                        PrintDocumentInfo info = (PrintDocumentInfo) message.obj;
+                        final boolean changed = (message.arg1 == 1);
+                        final int sequence = message.arg2;
+                        handleOnLayoutFinished(info, changed, sequence);
+                    } break;
+
+                    case MSG_ON_LAYOUT_FAILED: {
+                        CharSequence error = (CharSequence) message.obj;
+                        final int sequence = message.arg1;
+                        handleOnLayoutFailed(error, sequence);
+                    } break;
+
+                    case MSG_ON_WRITE_FINISHED: {
+                        PageRange[] pages = (PageRange[]) message.obj;
+                        final int sequence = message.arg1;
+                        handleOnWriteFinished(pages, sequence);
+                    } break;
+
+                    case MSG_ON_WRITE_FAILED: {
+                        CharSequence error = (CharSequence) message.obj;
+                        final int sequence = message.arg1;
+                        handleOnWriteFailed(error, sequence);
+                    } break;
+                }
+            }
+        }
+    }
+
+    private static final class LayoutResultCallback extends ILayoutResultCallback.Stub {
+        private final WeakReference<PrintController.ControllerHandler> mWeakHandler;
+
+        public LayoutResultCallback(PrintController.ControllerHandler handler) {
+            mWeakHandler = new WeakReference<PrintController.ControllerHandler>(handler);
+        }
+
+        @Override
+        public void onLayoutFinished(PrintDocumentInfo info, boolean changed, int sequence) {
+            Handler handler = mWeakHandler.get();
+            if (handler != null) {
+                handler.obtainMessage(PrintController.ControllerHandler.MSG_ON_LAYOUT_FINISHED,
+                        changed ? 1 : 0, sequence, info).sendToTarget();
+            }
+        }
+
+        @Override
+        public void onLayoutFailed(CharSequence error, int sequence) {
+            Handler handler = mWeakHandler.get();
+            if (handler != null) {
+                handler.obtainMessage(PrintController.ControllerHandler.MSG_ON_LAYOUT_FAILED,
+                        sequence, 0, error).sendToTarget();
+            }
+        }
+    }
+
+    private static final class WriteResultCallback extends IWriteResultCallback.Stub {
+        private final WeakReference<PrintController.ControllerHandler> mWeakHandler;
+
+        public WriteResultCallback(PrintController.ControllerHandler handler) {
+            mWeakHandler = new WeakReference<PrintController.ControllerHandler>(handler);
+        }
+
+        @Override
+        public void onWriteFinished(PageRange[] pages, int sequence) {
+            Handler handler = mWeakHandler.get();
+            if (handler != null) {
+                handler.obtainMessage(PrintController.ControllerHandler.MSG_ON_WRITE_FINISHED,
+                        sequence, 0, pages).sendToTarget();
+            }
+        }
+
+        @Override
+        public void onWriteFailed(CharSequence error, int sequence) {
+            Handler handler = mWeakHandler.get();
+            if (handler != null) {
+                handler.obtainMessage(PrintController.ControllerHandler.MSG_ON_WRITE_FAILED,
+                    sequence, 0, error).sendToTarget();
+            }
+        }
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        switch (requestCode) {
+            case ACTIVITY_REQUEST_CREATE_FILE: {
+                if (data != null) {
+                    Uri uri = data.getData();
+                    writePrintJobDataAndFinish(uri);
+                } else {
+                    mEditor.showUi(Editor.UI_EDITING_PRINT_JOB,
+                            new Runnable() {
+                        @Override
+                        public void run() {
+                            mEditor.initialize();
+                            mEditor.bindUi();
+                            mEditor.updateUi();
+                        }
+                    });
+                }
+            } break;
+
+            case ACTIVITY_REQUEST_SELECT_PRINTER: {
+                if (resultCode == RESULT_OK) {
+                    PrinterId printerId = (PrinterId) data.getParcelableExtra(
+                            INTENT_EXTRA_PRINTER_ID);
+                    mEditor.selectPrinter(printerId);
+                }
+            } break;
+        }
+    }
+
+    private void writePrintJobDataAndFinish(final Uri uri) {
+        new AsyncTask<Void, Void, Void>() {
+            @Override
+            protected Void doInBackground(Void... params) {
+                InputStream in = null;
+                OutputStream out = null;
+                try {
+                    PrintJobInfo printJob = PrintSpoolerService.peekInstance()
+                            .getPrintJobInfo(mPrintJobId, PrintManager.APP_ID_ANY);
+                    if (printJob == null) {
+                        return null;
+                    }
+                    File file = PrintSpoolerService.peekInstance()
+                            .generateFileForPrintJob(mPrintJobId);
+                    in = new FileInputStream(file);
+                    out = getContentResolver().openOutputStream(uri);
+                    final byte[] buffer = new byte[8192];
+                    while (true) {
+                        final int readByteCount = in.read(buffer);
+                        if (readByteCount < 0) {
+                            break;
+                        }
+                        out.write(buffer, 0, readByteCount);
+                    }
+                } catch (FileNotFoundException fnfe) {
+                    Log.e(LOG_TAG, "Error writing print job data!", fnfe);
+                } catch (IOException ioe) {
+                    Log.e(LOG_TAG, "Error writing print job data!", ioe);
+                } finally {
+                    IoUtils.closeQuietly(in);
+                    IoUtils.closeQuietly(out);
+                }
+                return null;
+            }
+
+            @Override
+            public void onPostExecute(Void result) {
+                mEditor.cancel();
+                PrintJobConfigActivity.this.finish();
+            }
+        }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, (Void[]) null);
+    }
+
+    private final class Editor {
+        private static final int UI_NONE = 0;
+        private static final int UI_EDITING_PRINT_JOB = 1;
+        private static final int UI_GENERATING_PRINT_JOB = 2;
+
+        private EditText mCopiesEditText;
+
+        private TextView mRangeOptionsTitle;
+        private TextView mPageRangeTitle;
+        private EditText mPageRangeEditText;
+
+        private Spinner mDestinationSpinner;
+        private final DestinationAdapter mDestinationSpinnerAdapter;
+
+        private Spinner mMediaSizeSpinner;
+        private final ArrayAdapter<SpinnerItem<MediaSize>> mMediaSizeSpinnerAdapter;
+
+        private Spinner mColorModeSpinner;
+        private final ArrayAdapter<SpinnerItem<Integer>> mColorModeSpinnerAdapter;
+
+        private Spinner mOrientationSpinner;
+        private final  ArrayAdapter<SpinnerItem<Integer>> mOrientationSpinnerAdapter;
+
+        private Spinner mRangeOptionsSpinner;
+        private final ArrayAdapter<SpinnerItem<Integer>> mRangeOptionsSpinnerAdapter;
+
+        private final SimpleStringSplitter mStringCommaSplitter =
+                new SimpleStringSplitter(',');
+
+        private View mContentContainer;
+
+        private Button mPrintButton;
+
+        private PrinterInfo mCurrentPrinter;
+
+        private boolean mRequestedCurrentPrinterRefresh;
+
+        private final OnItemSelectedListener mOnItemSelectedListener =
+                new AdapterView.OnItemSelectedListener() {
+            @Override
+            public void onItemSelected(AdapterView<?> spinner, View view, int position, long id) {
+                if (spinner == mDestinationSpinner) {
+                    if (mIgnoreNextDestinationChange) {
+                        mIgnoreNextDestinationChange = false;
+                        return;
+                    }
+
+                    if (id == DEST_ADAPTER_ITEM_ID_ALL_PRINTERS) {
+                        // The selection changed to the all printers item. We
+                        // want to select back the last selected printer.
+                        mIgnoreNextDestinationChange = true;
+                        mEditor.selectPrinter(mCurrentPrinter.getId());
+                        startSelectPrinterActivity();
+                        return;
+                    }
+
+                    mRequestedCurrentPrinterRefresh = false;
+
+                    mCurrentPrinter = (PrinterInfo) mDestinationSpinnerAdapter
+                            .getItem(position);
+
+                    PrintSpoolerService.peekInstance().setPrintJobPrinterNoPersistence(
+                            mPrintJobId, mCurrentPrinter);
+
+                    if (mCurrentPrinter.getStatus() == PrinterInfo.STATUS_UNAVAILABLE) {
+                        updateUi();
+                        return;
+                    }
+
+                    PrinterCapabilitiesInfo capabilities = mCurrentPrinter.getCapabilities();
+                    if (capabilities == null) {
+                        // TODO: We need a timeout for the update.
+                        mRequestedCurrentPrinterRefresh = true;
+                        updateUi();
+                        refreshCurrentPrinter();
+                    } else {
+                        updatePrintAttributes(capabilities);
+                        updateUi();
+                        mController.update();
+                    }
+                } else if (spinner == mMediaSizeSpinner) {
+                    if (mOldMediaSizeSelectionIndex
+                            == mMediaSizeSpinner.getSelectedItemPosition()) {
+                        mOldMediaSizeSelectionIndex = AdapterView.INVALID_POSITION;
+                        return;
+                    }
+                    SpinnerItem<MediaSize> mediaItem = mMediaSizeSpinnerAdapter.getItem(position);
+                    mCurrPrintAttributes.setMediaSize(mediaItem.value);
+                    if (!hasErrors()) {
+                        mController.update();
+                    }
+                } else if (spinner == mColorModeSpinner) {
+                    if (mOldColorModeSelectionIndex
+                            == mColorModeSpinner.getSelectedItemPosition()) {
+                        mOldColorModeSelectionIndex = AdapterView.INVALID_POSITION;
+                        return;
+                    }
+                    SpinnerItem<Integer> colorModeItem =
+                            mColorModeSpinnerAdapter.getItem(position);
+                    mCurrPrintAttributes.setColorMode(colorModeItem.value);
+                    if (!hasErrors()) {
+                        mController.update();
+                    }
+                } else if (spinner == mOrientationSpinner) {
+                    if (mIgnoreNextOrientationChange) {
+                        mIgnoreNextOrientationChange = false;
+                        return;
+                    }
+                    SpinnerItem<Integer> orientationItem =
+                            mOrientationSpinnerAdapter.getItem(position);
+                    setCurrentPrintAttributesOrientation(orientationItem.value);
+                    if (!hasErrors()) {
+                        mController.update();
+                    }
+                } else if (spinner == mRangeOptionsSpinner) {
+                    if (mIgnoreNextRangeOptionChange) {
+                        mIgnoreNextRangeOptionChange = false;
+                        return;
+                    }
+                    updateUi();
+                    if (!hasErrors()) {
+                        mController.update();
+                    }
+                }
+            }
+
+            @Override
+            public void onNothingSelected(AdapterView<?> parent) {
+                /* do nothing*/
+            }
+        };
+
+        private void setCurrentPrintAttributesOrientation(int orientation) {
+            MediaSize mediaSize = mCurrPrintAttributes.getMediaSize();
+            if (orientation == ORIENTATION_PORTRAIT) {
+                if (!mediaSize.isPortrait()) {
+                    // Rotate the media size.
+                    mCurrPrintAttributes.setMediaSize(mediaSize.asPortrait());
+
+                    // Rotate the resolution.
+                    Resolution oldResolution = mCurrPrintAttributes.getResolution();
+                    Resolution newResolution = new Resolution(
+                            oldResolution.getId(),
+                            oldResolution.getLabel(),
+                            oldResolution.getVerticalDpi(),
+                            oldResolution.getHorizontalDpi());
+                    mCurrPrintAttributes.setResolution(newResolution);
+
+                    // Rotate the physical margins.
+                    Margins oldMinMargins = mCurrPrintAttributes.getMinMargins();
+                    Margins newMinMargins = new Margins(
+                            oldMinMargins.getBottomMils(),
+                            oldMinMargins.getLeftMils(),
+                            oldMinMargins.getTopMils(),
+                            oldMinMargins.getRightMils());
+                    mCurrPrintAttributes.setMinMargins(newMinMargins);
+                }
+            } else {
+                if (mediaSize.isPortrait()) {
+                    // Rotate the media size.
+                    mCurrPrintAttributes.setMediaSize(mediaSize.asLandscape());
+
+                    // Rotate the resolution.
+                    Resolution oldResolution = mCurrPrintAttributes.getResolution();
+                    Resolution newResolution = new Resolution(
+                            oldResolution.getId(),
+                            oldResolution.getLabel(),
+                            oldResolution.getVerticalDpi(),
+                            oldResolution.getHorizontalDpi());
+                    mCurrPrintAttributes.setResolution(newResolution);
+
+                    // Rotate the physical margins.
+                    Margins oldMinMargins = mCurrPrintAttributes.getMinMargins();
+                    Margins newMargins = new Margins(
+                            oldMinMargins.getTopMils(),
+                            oldMinMargins.getRightMils(),
+                            oldMinMargins.getBottomMils(),
+                            oldMinMargins.getLeftMils());
+                    mCurrPrintAttributes.setMinMargins(newMargins);
+                }
+            }
+        }
+
+        private void updatePrintAttributes(PrinterCapabilitiesInfo capabilities) {
+            PrintAttributes defaults = capabilities.getDefaults();
+
+            // Media size.
+            MediaSize currMediaSize = mCurrPrintAttributes.getMediaSize();
+            if (currMediaSize == null) {
+                mCurrPrintAttributes.setMediaSize(defaults.getMediaSize());
+            } else {
+                MediaSize currMediaSizePortrait = currMediaSize.asPortrait();
+                List<MediaSize> mediaSizes = capabilities.getMediaSizes();
+                final int mediaSizeCount = mediaSizes.size();
+                for (int i = 0; i < mediaSizeCount; i++) {
+                    MediaSize mediaSize = mediaSizes.get(i);
+                    if (currMediaSizePortrait.equals(mediaSize.asPortrait())) {
+                        mCurrPrintAttributes.setMediaSize(mediaSize);
+                        break;
+                    }
+                }
+            }
+
+            // Color mode.
+            final int colorMode = mCurrPrintAttributes.getColorMode();
+            if ((capabilities.getColorModes() & colorMode) == 0) {
+                mCurrPrintAttributes.setColorMode(colorMode);
+            }
+
+            // Resolution
+            Resolution resolution = mCurrPrintAttributes.getResolution();
+            if (resolution == null || !capabilities.getResolutions().contains(resolution)) {
+                mCurrPrintAttributes.setResolution(defaults.getResolution());
+            }
+
+            // Margins.
+            Margins margins = mCurrPrintAttributes.getMinMargins();
+            if (margins == null) {
+                mCurrPrintAttributes.setMinMargins(defaults.getMinMargins());
+            } else {
+                Margins minMargins = capabilities.getMinMargins();
+                if (margins.getLeftMils() < minMargins.getLeftMils()
+                        || margins.getTopMils() < minMargins.getTopMils()
+                        || margins.getRightMils() > minMargins.getRightMils()
+                        || margins.getBottomMils() > minMargins.getBottomMils()) {
+                    mCurrPrintAttributes.setMinMargins(defaults.getMinMargins());
+                }
+            }
+        }
+
+        private final TextWatcher mCopiesTextWatcher = new TextWatcher() {
+            @Override
+            public void onTextChanged(CharSequence s, int start, int before, int count) {
+                /* do nothing */
+            }
+
+            @Override
+            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+                /* do nothing */
+            }
+
+            @Override
+            public void afterTextChanged(Editable editable) {
+                if (mIgnoreNextCopiesChange) {
+                    mIgnoreNextCopiesChange = false;
+                    return;
+                }
+
+                final boolean hadErrors = hasErrors();
+
+                if (editable.length() == 0) {
+                    mCopiesEditText.setError("");
+                    updateUi();
+                    return;
+                }
+
+                int copies = 0;
+                try {
+                    copies = Integer.parseInt(editable.toString());
+                } catch (NumberFormatException nfe) {
+                    /* ignore */
+                }
+
+                if (copies < MIN_COPIES) {
+                    mCopiesEditText.setError("");
+                    updateUi();
+                    return;
+                }
+
+                mCopiesEditText.setError(null);
+                PrintSpoolerService.peekInstance().setPrintJobCopiesNoPersistence(
+                        mPrintJobId, copies);
+                updateUi();
+
+                if (hadErrors && !hasErrors() && printAttributesChanged()) {
+                    mController.update();
+                }
+            }
+        };
+
+        private final TextWatcher mRangeTextWatcher = new TextWatcher() {
+            @Override
+            public void onTextChanged(CharSequence s, int start, int before, int count) {
+                /* do nothing */
+            }
+
+            @Override
+            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+                /* do nothing */
+            }
+
+            @Override
+            public void afterTextChanged(Editable editable) {
+                if (mIgnoreNextRangeChange) {
+                    mIgnoreNextRangeChange = false;
+                    return;
+                }
+
+                final boolean hadErrors = hasErrors();
+
+                String text = editable.toString();
+
+                if (TextUtils.isEmpty(text)) {
+                    mPageRangeEditText.setError("");
+                    updateUi();
+                    return;
+                }
+
+                String escapedText = PATTERN_ESCAPE_SPECIAL_CHARS.matcher(text).replaceAll("////");
+                if (!PATTERN_PAGE_RANGE.matcher(escapedText).matches()) {
+                    mPageRangeEditText.setError("");
+                    updateUi();
+                    return;
+                }
+
+                Matcher matcher = PATTERN_DIGITS.matcher(text);
+                while (matcher.find()) {
+                    String numericString = text.substring(matcher.start(), matcher.end());
+                    final int pageIndex = Integer.parseInt(numericString);
+                    if (pageIndex < 1 || pageIndex > mDocument.info.getPageCount()) {
+                        mPageRangeEditText.setError("");
+                        updateUi();
+                        return;
+                    }
+                }
+
+                //TODO: Catch the error if start is less grater than the end.
+
+                mPageRangeEditText.setError(null);
+                mPrintButton.setEnabled(true);
+                updateUi();
+
+                if (hadErrors && !hasErrors() && printAttributesChanged()) {
+                    updateUi();
+                }
+            }
+        };
+
+        private int mEditorState;
+
+        private boolean mIgnoreNextDestinationChange;
+        private int mOldMediaSizeSelectionIndex;
+        private int mOldColorModeSelectionIndex;
+        private boolean mIgnoreNextOrientationChange;
+        private boolean mIgnoreNextRangeOptionChange;
+        private boolean mIgnoreNextCopiesChange;
+        private boolean mIgnoreNextRangeChange;
+
+        private int mCurrentUi = UI_NONE;
+
+        private boolean mFavoritePrinterSelected;
+
+        public Editor() {
+            // Destination.
+            mDestinationSpinnerAdapter = new DestinationAdapter();
+            mDestinationSpinnerAdapter.registerDataSetObserver(new DataSetObserver() {
+                @Override
+                public void onChanged() {
+                    // Initially, we have only safe to PDF as a printer but after some
+                    // printers are loaded we want to select the user's favorite one
+                    // which is the first.
+                    if (!mFavoritePrinterSelected && mDestinationSpinnerAdapter.getCount() > 2) {
+                        mFavoritePrinterSelected = true;
+                        mDestinationSpinner.setSelection(0);
+                    }
+
+                    // If the current printer properties changed, we update the UI.
+                    if (mCurrentPrinter != null) {
+                        final int printerCount = mDestinationSpinnerAdapter.getCount();
+                        for (int i = 0; i < printerCount; i++) {
+                            Object item = mDestinationSpinnerAdapter.getItem(i);
+                            // Some items are not printers
+                            if (item instanceof PrinterInfo) {
+                                PrinterInfo printer = (PrinterInfo) item;
+                                if (!printer.getId().equals(mCurrentPrinter.getId())) {
+                                    continue;
+                                }
+
+                                // If the current printer became available and has no
+                                // capabilities, we refresh it.
+                                if (mCurrentPrinter.getStatus() == PrinterInfo.STATUS_UNAVAILABLE
+                                        && printer.getStatus() != PrinterInfo.STATUS_UNAVAILABLE
+                                        && printer.getCapabilities() == null
+                                        && !mRequestedCurrentPrinterRefresh) {
+                                    mRequestedCurrentPrinterRefresh = true;
+                                    refreshCurrentPrinter();
+                                    return;
+                                }
+
+                                // We just refreshed the current printer.
+                                if (printer.getCapabilities() != null
+                                        && mRequestedCurrentPrinterRefresh) {
+                                    mRequestedCurrentPrinterRefresh = false;
+                                    updatePrintAttributes(printer.getCapabilities());
+                                    updateUi();
+                                    mController.update();
+                                }
+
+                                // Update the UI if capabilities changed.
+                                boolean capabilitiesChanged = false;
+
+                                if (mCurrentPrinter.getCapabilities() == null) {
+                                    if (printer.getCapabilities() != null) {
+                                        capabilitiesChanged = true;
+                                    }
+                                } else if (!mCurrentPrinter.getCapabilities().equals(
+                                        printer.getCapabilities())) {
+                                    capabilitiesChanged = true;
+                                }
+
+                                // Update the UI if the status changed.
+                                final boolean statusChanged = mCurrentPrinter.getStatus()
+                                        != printer.getStatus();
+
+                                // Update the printer with the latest info.
+                                if (!mCurrentPrinter.equals(printer)) {
+                                    mCurrentPrinter.copyFrom(printer);
+                                }
+
+                                if (capabilitiesChanged || statusChanged) {
+                                    // If something changed during update...
+                                    if (updateUi()) {
+                                        // Update the document.
+                                        mController.update();
+                                    }
+                                }
+
+                                break;
+                            }
+                        }
+                    }
+                }
+
+                @Override
+                public void onInvalidated() {
+                    /* do nothing - we always have one fake PDF printer */
+                }
+            });
+
+            // Media size.
+            mMediaSizeSpinnerAdapter = new ArrayAdapter<SpinnerItem<MediaSize>>(
+                    PrintJobConfigActivity.this,
+                    R.layout.spinner_dropdown_item, R.id.title);
+
+            // Color mode.
+            mColorModeSpinnerAdapter = new ArrayAdapter<SpinnerItem<Integer>>(
+                    PrintJobConfigActivity.this,
+                    R.layout.spinner_dropdown_item, R.id.title);
+
+            // Orientation
+            mOrientationSpinnerAdapter = new ArrayAdapter<SpinnerItem<Integer>>(
+                    PrintJobConfigActivity.this,
+                    R.layout.spinner_dropdown_item, R.id.title);
+            String[] orientationLabels = getResources().getStringArray(
+                  R.array.orientation_labels);
+            mOrientationSpinnerAdapter.add(new SpinnerItem<Integer>(
+                    ORIENTATION_PORTRAIT, orientationLabels[0]));
+            mOrientationSpinnerAdapter.add(new SpinnerItem<Integer>(
+                    ORIENTATION_LANDSCAPE, orientationLabels[1]));
+
+            // Range options
+            mRangeOptionsSpinnerAdapter = new ArrayAdapter<SpinnerItem<Integer>>(
+                    PrintJobConfigActivity.this,
+                    R.layout.spinner_dropdown_item, R.id.title);
+            final int[] rangeOptionsValues = getResources().getIntArray(
+                    R.array.page_options_values);
+            String[] rangeOptionsLabels = getResources().getStringArray(
+                    R.array.page_options_labels);
+            final int rangeOptionsCount = rangeOptionsLabels.length;
+            for (int i = 0; i < rangeOptionsCount; i++) {
+                mRangeOptionsSpinnerAdapter.add(new SpinnerItem<Integer>(
+                        rangeOptionsValues[i], rangeOptionsLabels[i]));
+            }
+
+            showUi(UI_EDITING_PRINT_JOB, null);
+            bindUi();
+
+            mCurrentPrinter = mDestinationSpinnerAdapter.mFakePdfPrinter;
+            updatePrintAttributes(mCurrentPrinter.getCapabilities());
+
+            updateUi();
+        }
+
+        public void refreshCurrentPrinter() {
+            PrinterInfo printer = (PrinterInfo) mDestinationSpinner.getSelectedItem();
+            if (printer != null) {
+                FusedPrintersProvider printersLoader = (FusedPrintersProvider)
+                        (Loader<?>) getLoaderManager().getLoader(
+                                LOADER_ID_PRINTERS_LOADER);
+                if (printersLoader != null) {
+                    printersLoader.setTrackedPrinter(printer.getId());
+                }
+            }
+        }
+
+        public void addCurrentPrinterToHistory() {
+            PrinterInfo printer = (PrinterInfo) mDestinationSpinner.getSelectedItem();
+            PrinterId fakePdfPritnerId = mDestinationSpinnerAdapter.mFakePdfPrinter.getId();
+            if (printer != null && !printer.getId().equals(fakePdfPritnerId)) {
+                FusedPrintersProvider printersLoader = (FusedPrintersProvider)
+                        (Loader<?>) getLoaderManager().getLoader(
+                                LOADER_ID_PRINTERS_LOADER);
+                if (printersLoader != null) {
+                    printersLoader.addHistoricalPrinter(printer);
+                }
+            }
+        }
+
+        public void selectPrinter(PrinterId printerId) {
+            mDestinationSpinnerAdapter.ensurePrinterShownPrinterShown(printerId);
+            final int position = mDestinationSpinnerAdapter.getPrinterIndex(printerId);
+            mDestinationSpinner.setSelection(position);
+        }
+
+        public boolean isPrintingToPdf() {
+            return mDestinationSpinner.getSelectedItem()
+                    == mDestinationSpinnerAdapter.mFakePdfPrinter;
+        }
+
+        public boolean shouldCloseOnTouch(MotionEvent event) {
+            if (event.getAction() != MotionEvent.ACTION_DOWN) {
+                return false;
+            }
+
+            final int[] locationInWindow = new int[2];
+            mContentContainer.getLocationInWindow(locationInWindow);
+
+            final int windowTouchSlop = ViewConfiguration.get(PrintJobConfigActivity.this)
+                    .getScaledWindowTouchSlop();
+            final int eventX = (int) event.getX();
+            final int eventY = (int) event.getY();
+            final int lenientWindowLeft = locationInWindow[0] - windowTouchSlop;
+            final int lenientWindowRight = lenientWindowLeft + mContentContainer.getWidth()
+                    + windowTouchSlop;
+            final int lenientWindowTop = locationInWindow[1] - windowTouchSlop;
+            final int lenientWindowBottom = lenientWindowTop + mContentContainer.getHeight()
+                    + windowTouchSlop;
+
+            if (eventX < lenientWindowLeft || eventX > lenientWindowRight
+                    || eventY < lenientWindowTop || eventY > lenientWindowBottom) {
+                return true;
+            }
+            return false;
+        }
+
+        public boolean isShwoingGeneratingPrintJobUi() {
+            return (mCurrentUi == UI_GENERATING_PRINT_JOB);
+        }
+
+        public void showUi(int ui, final Runnable postSwitchCallback) {
+            if (ui == UI_NONE) {
+                throw new IllegalStateException("cannot remove the ui");
+            }
+
+            if (mCurrentUi == ui) {
+                return;
+            }
+
+            switch (mCurrentUi) {
+                case UI_NONE: {
+                    switch (ui) {
+                        case UI_EDITING_PRINT_JOB: {
+                            doUiSwitch(R.layout.print_job_config_activity_content_editing);
+                            registerPrintButtonClickListener();
+                            if (postSwitchCallback != null) {
+                                postSwitchCallback.run();
+                            }
+                        } break;
+
+                        case UI_GENERATING_PRINT_JOB: {
+                            doUiSwitch(R.layout.print_job_config_activity_content_generating);
+                            registerCancelButtonClickListener();
+                            if (postSwitchCallback != null) {
+                                postSwitchCallback.run();
+                            }
+                        } break;
+                    }
+                } break;
+
+                case UI_EDITING_PRINT_JOB: {
+                    switch (ui) {
+                        case UI_GENERATING_PRINT_JOB: {
+                            animateUiSwitch(R.layout.print_job_config_activity_content_generating,
+                                    new Runnable() {
+                                @Override
+                                public void run() {
+                                    registerCancelButtonClickListener();
+                                    if (postSwitchCallback != null) {
+                                        postSwitchCallback.run();
+                                    }
+                                }
+                            });
+                        } break;
+                    }
+                } break;
+
+                case UI_GENERATING_PRINT_JOB: {
+                    switch (ui) {
+                        case UI_EDITING_PRINT_JOB: {
+                            animateUiSwitch(R.layout.print_job_config_activity_content_editing,
+                                    new Runnable() {
+                                @Override
+                                public void run() {
+                                    registerPrintButtonClickListener();
+                                    if (postSwitchCallback != null) {
+                                        postSwitchCallback.run();
+                                    }
+                                }
+                            });
+                        } break;
+                    }
+                } break;
+            }
+
+            mCurrentUi = ui;
+        }
+
+        private void registerPrintButtonClickListener() {
+            Button printButton = (Button) findViewById(R.id.print_button);
+            printButton.setOnClickListener(new OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    PrinterInfo printer = (PrinterInfo) mDestinationSpinner.getSelectedItem();
+                    if (printer != null) {
+                        mEditor.confirmPrint();
+                        mController.update();
+                        if (!printer.equals(mDestinationSpinnerAdapter.mFakePdfPrinter)) {
+                            mEditor.refreshCurrentPrinter();
+                        }
+                    } else {
+                        mEditor.cancel();
+                        PrintJobConfigActivity.this.finish();
+                    }
+                }
+            });
+        }
+
+        private void registerCancelButtonClickListener() {
+            Button cancelButton = (Button) findViewById(R.id.cancel_button);
+            cancelButton.setOnClickListener(new OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    if (!mController.isWorking()) {
+                        PrintJobConfigActivity.this.finish();
+                    }
+                    mEditor.cancel();
+                }
+            });
+        }
+
+        private void doUiSwitch(int showLayoutId) {
+            ViewGroup contentContainer = (ViewGroup) findViewById(R.id.content_container);
+            contentContainer.removeAllViews();
+            getLayoutInflater().inflate(showLayoutId, contentContainer, true);
+        }
+
+        private void animateUiSwitch(int showLayoutId, final Runnable postAnimateCommand) {
+            // Find everything we will shuffle around.
+            final ViewGroup contentContainer = (ViewGroup) findViewById(R.id.content_container);
+            final View hidingView = contentContainer.getChildAt(0);
+            final View showingView = getLayoutInflater().inflate(showLayoutId,
+                    null, false);
+
+            // First animation - fade out the old content.
+            AutoCancellingAnimator.animate(hidingView).alpha(0.0f)
+                    .withLayer().withEndAction(new Runnable() {
+                @Override
+                public void run() {
+                    hidingView.setVisibility(View.INVISIBLE);
+
+                    // Prepare the new content with correct size and alpha.
+                    showingView.setMinimumWidth(contentContainer.getWidth());
+                    showingView.setAlpha(0.0f);
+
+                    // Compute how to much shrink /stretch the content.
+                    final int widthSpec = MeasureSpec.makeMeasureSpec(
+                            contentContainer.getWidth(), MeasureSpec.UNSPECIFIED);
+                    final int heightSpec = MeasureSpec.makeMeasureSpec(
+                            contentContainer.getHeight(), MeasureSpec.UNSPECIFIED);
+                    showingView.measure(widthSpec, heightSpec);
+                    final float scaleY = (float) showingView.getMeasuredHeight()
+                            / (float) contentContainer.getHeight();
+
+                    // Second animation - resize the container.
+                    AutoCancellingAnimator.animate(contentContainer).scaleY(scaleY).withLayer()
+                            .withEndAction(new Runnable() {
+                        @Override
+                        public void run() {
+                            // Swap the old and the new content.
+                            contentContainer.removeAllViews();
+                            contentContainer.setScaleY(1.0f);
+                            contentContainer.addView(showingView);
+
+                            // Third animation - show the new content.
+                            AutoCancellingAnimator.animate(showingView).withLayer().alpha(1.0f)
+                                    .withEndAction(new Runnable() {
+                                @Override
+                                public void run() {
+                                    postAnimateCommand.run();
+                                }
+                            });
+                        }
+                    });
+                }
+            });
+        }
+
+        public void initialize() {
+            mEditorState = EDITOR_STATE_INITIALIZED;
+        }
+
+        public boolean isCancelled() {
+            return mEditorState == EDITOR_STATE_CANCELLED;
+        }
+
+        public void cancel() {
+            mEditorState = EDITOR_STATE_CANCELLED;
+            mController.cancel();
+            updateUi();
+        }
+
+        public boolean isDone() {
+            return isPrintConfirmed() || isCancelled();
+        }
+
+        public boolean isPrintConfirmed() {
+            return mEditorState == EDITOR_STATE_CONFIRMED_PRINT;
+        }
+
+        public void confirmPrint() {
+            addCurrentPrinterToHistory();
+            mEditorState = EDITOR_STATE_CONFIRMED_PRINT;
+            showUi(UI_GENERATING_PRINT_JOB, null);
+        }
+
+        public PageRange[] getRequestedPages() {
+            if (hasErrors()) {
+                return null;
+            }
+            if (mRangeOptionsSpinner.getSelectedItemPosition() > 0) {
+                List<PageRange> pageRanges = new ArrayList<PageRange>();
+                mStringCommaSplitter.setString(mPageRangeEditText.getText().toString());
+
+                while (mStringCommaSplitter.hasNext()) {
+                    String range = mStringCommaSplitter.next().trim();
+                    final int dashIndex = range.indexOf('-');
+                    final int fromIndex;
+                    final int toIndex;
+
+                    if (dashIndex > 0) {
+                        fromIndex = Integer.parseInt(range.substring(0, dashIndex)) - 1;
+                        toIndex = Integer.parseInt(range.substring(
+                                dashIndex + 1, range.length())) - 1;
+                    } else {
+                        fromIndex = toIndex = Integer.parseInt(range) - 1;
+                    }
+
+                    PageRange pageRange = new PageRange(fromIndex, toIndex);
+                    pageRanges.add(pageRange);
+                }
+
+                PageRange[] pageRangesArray = new PageRange[pageRanges.size()];
+                pageRanges.toArray(pageRangesArray);
+
+                return PageRangeUtils.normalize(pageRangesArray);
+            }
+
+            return ALL_PAGES_ARRAY;
+        }
+
+        private void bindUi() {
+            if (mCurrentUi != UI_EDITING_PRINT_JOB) {
+                return;
+            }
+
+            // Content container
+            mContentContainer = findViewById(R.id.content_container);
+
+            // Copies
+            mCopiesEditText = (EditText) findViewById(R.id.copies_edittext);
+            mCopiesEditText.setText(MIN_COPIES_STRING);
+            mCopiesEditText.addTextChangedListener(mCopiesTextWatcher);
+            mCopiesEditText.selectAll();
+            if (!TextUtils.equals(mCopiesEditText.getText(), MIN_COPIES_STRING)) {
+                mIgnoreNextCopiesChange = true;
+            }
+            PrintSpoolerService.peekInstance().setPrintJobCopiesNoPersistence(
+                    mPrintJobId, MIN_COPIES);
+
+            // Destination.
+            mDestinationSpinner = (Spinner) findViewById(R.id.destination_spinner);
+            mDestinationSpinner.setAdapter(mDestinationSpinnerAdapter);
+            mDestinationSpinner.setOnItemSelectedListener(mOnItemSelectedListener);
+            if (mDestinationSpinnerAdapter.getCount() > 0 && mController.hasStarted()) {
+                mIgnoreNextDestinationChange = true;
+            }
+
+            // Media size.
+            mMediaSizeSpinner = (Spinner) findViewById(R.id.paper_size_spinner);
+            mMediaSizeSpinner.setAdapter(mMediaSizeSpinnerAdapter);
+            mMediaSizeSpinner.setOnItemSelectedListener(mOnItemSelectedListener);
+            if (mMediaSizeSpinnerAdapter.getCount() > 0) {
+                mOldMediaSizeSelectionIndex = 0;
+            }
+
+            // Color mode.
+            mColorModeSpinner = (Spinner) findViewById(R.id.color_spinner);
+            mColorModeSpinner.setAdapter(mColorModeSpinnerAdapter);
+            mColorModeSpinner.setOnItemSelectedListener(mOnItemSelectedListener);
+            if (mColorModeSpinnerAdapter.getCount() > 0) {
+                mOldColorModeSelectionIndex = 0;
+            }
+
+            // Orientation
+            mOrientationSpinner = (Spinner) findViewById(R.id.orientation_spinner);
+            mOrientationSpinner.setAdapter(mOrientationSpinnerAdapter);
+            mOrientationSpinner.setOnItemSelectedListener(mOnItemSelectedListener);
+            if (mOrientationSpinnerAdapter.getCount() > 0) {
+                mIgnoreNextOrientationChange = true;
+            }
+
+            // Range options
+            mRangeOptionsTitle = (TextView) findViewById(R.id.range_options_title);
+            mRangeOptionsSpinner = (Spinner) findViewById(R.id.range_options_spinner);
+            mRangeOptionsSpinner.setAdapter(mRangeOptionsSpinnerAdapter);
+            mRangeOptionsSpinner.setOnItemSelectedListener(mOnItemSelectedListener);
+            if (mRangeOptionsSpinnerAdapter.getCount() > 0) {
+                mIgnoreNextRangeOptionChange = true;
+            }
+
+            // Page range
+            mPageRangeTitle = (TextView) findViewById(R.id.page_range_title);
+            mPageRangeEditText = (EditText) findViewById(R.id.page_range_edittext);
+            mPageRangeEditText.addTextChangedListener(mRangeTextWatcher);
+
+            // Print button
+            mPrintButton = (Button) findViewById(R.id.print_button);
+            registerPrintButtonClickListener();
+        }
+
+        public boolean updateUi() {
+            if (mCurrentUi != UI_EDITING_PRINT_JOB) {
+                return false;
+            }
+            if (isPrintConfirmed() || isCancelled()) {
+                mDestinationSpinner.setEnabled(false);
+                mCopiesEditText.setEnabled(false);
+                mMediaSizeSpinner.setEnabled(false);
+                mColorModeSpinner.setEnabled(false);
+                mOrientationSpinner.setEnabled(false);
+                mRangeOptionsSpinner.setEnabled(false);
+                mPageRangeEditText.setEnabled(false);
+                mPrintButton.setEnabled(false);
+                return false;
+            }
+
+            // If a printer with capabilities is selected, then we enabled all options.
+            boolean allOptionsEnabled = false;
+            final int selectedIndex = mDestinationSpinner.getSelectedItemPosition();
+            if (selectedIndex >= 0) {
+                Object item = mDestinationSpinnerAdapter.getItem(selectedIndex);
+                if (item instanceof PrinterInfo) {
+                    PrinterInfo printer = (PrinterInfo) item;
+                    if (printer.getCapabilities() != null
+                            && printer.getStatus() != PrinterInfo.STATUS_UNAVAILABLE) {
+                        allOptionsEnabled = true;
+                    }
+                }
+            }
+
+            if (!allOptionsEnabled) {
+                String minCopiesString = String.valueOf(MIN_COPIES);
+                if (!TextUtils.equals(mCopiesEditText.getText(), minCopiesString)) {
+                    mIgnoreNextCopiesChange = true;
+                    mCopiesEditText.setText(minCopiesString);
+                }
+                mCopiesEditText.setEnabled(false);
+
+                // Media size
+                if (mMediaSizeSpinner.getSelectedItemPosition() != AdapterView.INVALID_POSITION) {
+                    mOldMediaSizeSelectionIndex = AdapterView.INVALID_POSITION;
+                    mMediaSizeSpinner.setSelection(AdapterView.INVALID_POSITION);
+                }
+                mMediaSizeSpinner.setEnabled(false);
+
+                // Color mode
+                if (mColorModeSpinner.getSelectedItemPosition() != AdapterView.INVALID_POSITION) {
+                    mOldColorModeSelectionIndex = AdapterView.INVALID_POSITION;
+                    mColorModeSpinner.setSelection(AdapterView.INVALID_POSITION);
+                }
+                mColorModeSpinner.setEnabled(false);
+
+                // Orientation
+                if (mOrientationSpinner.getSelectedItemPosition() != 0) {
+                    mIgnoreNextOrientationChange = true;
+                    mOrientationSpinner.setSelection(0);
+                }
+                mOrientationSpinner.setEnabled(false);
+
+                // Range
+                if (mRangeOptionsSpinner.getSelectedItemPosition() != 0) {
+                    mIgnoreNextRangeOptionChange = true;
+                    mRangeOptionsSpinner.setSelection(0);
+                }
+                mRangeOptionsSpinner.setEnabled(false);
+                mRangeOptionsTitle.setText(getString(R.string.label_pages,
+                        getString(R.string.page_count_unknown)));
+                if (!TextUtils.equals(mPageRangeEditText.getText(), "")) {
+                    mIgnoreNextRangeChange = true;
+                    mPageRangeEditText.setText("");
+                }
+
+                mPageRangeEditText.setEnabled(false);
+                mPageRangeEditText.setVisibility(View.INVISIBLE);
+                mPageRangeTitle.setVisibility(View.INVISIBLE);
+
+                // Print
+                mPrintButton.setEnabled(false);
+
+                return false;
+            } else {
+                boolean someAttributeSelectionChanged = false;
+
+                PrinterInfo printer = (PrinterInfo) mDestinationSpinner.getSelectedItem();
+                PrinterCapabilitiesInfo capabilities = printer.getCapabilities();
+                PrintAttributes defaultAttributes = printer.getCapabilities().getDefaults();
+
+                // Media size.
+                List<MediaSize> mediaSizes = capabilities.getMediaSizes();
+
+                // If the media sizes changed, we update the adapter and the spinner.
+                boolean mediaSizesChanged = false;
+                final int mediaSizeCount = mediaSizes.size();
+                if (mediaSizeCount != mMediaSizeSpinnerAdapter.getCount()) {
+                    mediaSizesChanged = true;
+                } else {
+                    for (int i = 0; i < mediaSizeCount; i++) {
+                        if (!mediaSizes.get(i).equals(mMediaSizeSpinnerAdapter.getItem(i).value)) {
+                            mediaSizesChanged = true;
+                            break;
+                        }
+                    }
+                }
+                if (mediaSizesChanged) {
+                    // Remember the old media size to try selecting it again.
+                    int oldMediaSizeNewIndex = AdapterView.INVALID_POSITION;
+                    MediaSize oldMediaSize = mCurrPrintAttributes.getMediaSize();
+
+                    // Rebuild the adapter data.
+                    mMediaSizeSpinnerAdapter.clear();
+                    for (int i = 0; i < mediaSizeCount; i++) {
+                        MediaSize mediaSize = mediaSizes.get(i);
+                        if (mediaSize.equals(oldMediaSize)) {
+                            // Update the index of the old selection.
+                            oldMediaSizeNewIndex = i;
+                        }
+                        mMediaSizeSpinnerAdapter.add(new SpinnerItem<MediaSize>(
+                                mediaSize, mediaSize.getLabel(getPackageManager())));
+                    }
+
+                    mMediaSizeSpinner.setEnabled(true);
+
+                    if (oldMediaSizeNewIndex != AdapterView.INVALID_POSITION) {
+                        // Select the old media size - nothing really changed.
+                        setMediaSizeSpinnerSelectionNoCallback(oldMediaSizeNewIndex);
+                    } else {
+                        // Select the first or the default and mark if selection changed.
+                        final int mediaSizeIndex = Math.max(mediaSizes.indexOf(
+                                defaultAttributes.getMediaSize()), 0);
+                        setMediaSizeSpinnerSelectionNoCallback(mediaSizeIndex);
+                        mCurrPrintAttributes.setMediaSize(mMediaSizeSpinnerAdapter
+                                .getItem(mediaSizeIndex).value);
+                        someAttributeSelectionChanged = true;
+                    }
+                }
+                mMediaSizeSpinner.setEnabled(true);
+
+                // Color mode.
+                final int colorModes = capabilities.getColorModes();
+
+                // If the color modes changed, we update the adapter and the spinner.
+                boolean colorModesChanged = false;
+                if (Integer.bitCount(colorModes) != mColorModeSpinnerAdapter.getCount()) {
+                    colorModesChanged = true;
+                } else {
+                    int remainingColorModes = colorModes;
+                    int adapterIndex = 0;
+                    while (remainingColorModes != 0) {
+                        final int colorBitOffset = Integer.numberOfTrailingZeros(
+                                remainingColorModes);
+                        final int colorMode = 1 << colorBitOffset;
+                        remainingColorModes &= ~colorMode;
+                        if (colorMode != mColorModeSpinnerAdapter.getItem(adapterIndex).value) {
+                            colorModesChanged = true;
+                            break;
+                        }
+                        adapterIndex++;
+                    }
+                }
+                if (colorModesChanged) {
+                    // Remember the old color mode to try selecting it again.
+                    int oldColorModeNewIndex = AdapterView.INVALID_POSITION;
+                    final int oldColorMode = mCurrPrintAttributes.getColorMode();
+
+                    // Rebuild the adapter data.
+                    mColorModeSpinnerAdapter.clear();
+                    String[] colorModeLabels = getResources().getStringArray(
+                            R.array.color_mode_labels);
+                    int remainingColorModes = colorModes;
+                    while (remainingColorModes != 0) {
+                        final int colorBitOffset = Integer.numberOfTrailingZeros(
+                                remainingColorModes);
+                        final int colorMode = 1 << colorBitOffset;
+                        if (colorMode == oldColorMode) {
+                            // Update the index of the old selection.
+                            oldColorModeNewIndex = colorBitOffset;
+                        }
+                        remainingColorModes &= ~colorMode;
+                        mColorModeSpinnerAdapter.add(new SpinnerItem<Integer>(colorMode,
+                                colorModeLabels[colorBitOffset]));
+                    }
+                    mColorModeSpinner.setEnabled(true);
+                    if (oldColorModeNewIndex != AdapterView.INVALID_POSITION) {
+                        // Select the old color mode - nothing really changed.
+                        setColorModeSpinnerSelectionNoCallback(oldColorModeNewIndex);
+                    } else {
+                        final int selectedColorModeIndex = Integer.numberOfTrailingZeros(
+                                    (colorModes & defaultAttributes.getColorMode()));
+                        setColorModeSpinnerSelectionNoCallback(selectedColorModeIndex);
+                        mCurrPrintAttributes.setColorMode(mColorModeSpinnerAdapter
+                                .getItem(selectedColorModeIndex).value);
+                        someAttributeSelectionChanged = true;
+                    }
+                }
+                mColorModeSpinner.setEnabled(true);
+
+                // Orientation
+                MediaSize mediaSize = mCurrPrintAttributes.getMediaSize();
+                if (mediaSize.isPortrait()
+                        && mOrientationSpinner.getSelectedItemPosition() != 0) {
+                    mIgnoreNextOrientationChange = true;
+                    mOrientationSpinner.setSelection(0);
+                } else if (!mediaSize.isPortrait()
+                        && mOrientationSpinner.getSelectedItemPosition() != 1) {
+                    mIgnoreNextOrientationChange = true;
+                    mOrientationSpinner.setSelection(1);
+                }
+                mOrientationSpinner.setEnabled(true);
+
+                // Range options
+                PrintDocumentInfo info = mDocument.info;
+                if (info != null && (info.getPageCount() > 0
+                        || info.getPageCount() == PrintDocumentInfo.PAGE_COUNT_UNKNOWN)) {
+                    if (info.getPageCount() == 1) {
+                        mRangeOptionsSpinner.setEnabled(false);
+                    } else {
+                        mRangeOptionsSpinner.setEnabled(true);
+                        if (mRangeOptionsSpinner.getSelectedItemPosition() > 0) {
+                            if (!mPageRangeEditText.isEnabled()) {
+                                mPageRangeEditText.setEnabled(true);
+                                mPageRangeEditText.setVisibility(View.VISIBLE);
+                                mPageRangeTitle.setVisibility(View.VISIBLE);
+                                mPageRangeEditText.requestFocus();
+                                InputMethodManager imm = (InputMethodManager)
+                                        getSystemService(INPUT_METHOD_SERVICE);
+                                imm.showSoftInput(mPageRangeEditText, 0);
+                            }
+                        } else {
+                            mPageRangeEditText.setEnabled(false);
+                            mPageRangeEditText.setVisibility(View.INVISIBLE);
+                            mPageRangeTitle.setVisibility(View.INVISIBLE);
+                        }
+                    }
+                    final int pageCount = mDocument.info.getPageCount();
+                    mRangeOptionsTitle.setText(getString(R.string.label_pages,
+                            (pageCount == PrintDocumentInfo.PAGE_COUNT_UNKNOWN)
+                                    ? getString(R.string.page_count_unknown)
+                                    : String.valueOf(pageCount)));
+                } else {
+                    if (mRangeOptionsSpinner.getSelectedItemPosition() != 0) {
+                        mIgnoreNextRangeOptionChange = true;
+                        mRangeOptionsSpinner.setSelection(0);
+                    }
+                    mRangeOptionsSpinner.setEnabled(false);
+                    mRangeOptionsTitle.setText(getString(R.string.label_pages,
+                            getString(R.string.page_count_unknown)));
+                    mPageRangeEditText.setEnabled(false);
+                    mPageRangeEditText.setVisibility(View.INVISIBLE);
+                    mPageRangeTitle.setVisibility(View.INVISIBLE);
+                }
+
+                // Print/Print preview
+                if (mDestinationSpinner.getSelectedItemId()
+                        != DEST_ADAPTER_ITEM_ID_SAVE_AS_PDF) {
+                    String newText = getString(R.string.print_button);
+                    if (!TextUtils.equals(newText, mPrintButton.getText())) {
+                        mPrintButton.setText(R.string.print_button);
+                    }
+                } else {
+                    String newText = getString(R.string.save_button);
+                    if (!TextUtils.equals(newText, mPrintButton.getText())) {
+                        mPrintButton.setText(R.string.save_button);
+                    }
+                }
+                if ((mRangeOptionsSpinner.getSelectedItemPosition() == 1
+                            && (TextUtils.isEmpty(mPageRangeEditText.getText()) || hasErrors()))
+                        || (mRangeOptionsSpinner.getSelectedItemPosition() == 0
+                            && (!mController.hasPerformedLayout() || hasErrors()))) {
+                    mPrintButton.setEnabled(false);
+                } else {
+                    mPrintButton.setEnabled(true);
+                }
+
+                // Copies
+                if (mDestinationSpinner.getSelectedItemId()
+                        != DEST_ADAPTER_ITEM_ID_SAVE_AS_PDF) {
+                    mCopiesEditText.setEnabled(true);
+                } else {
+                    mCopiesEditText.setEnabled(false);
+                }
+                if (mCopiesEditText.getError() == null
+                        && TextUtils.isEmpty(mCopiesEditText.getText())) {
+                    mIgnoreNextCopiesChange = true;
+                    mCopiesEditText.setText(String.valueOf(MIN_COPIES));
+                    mCopiesEditText.selectAll();
+                    mCopiesEditText.requestFocus();
+                }
+
+                return someAttributeSelectionChanged;
+            }
+        }
+
+        private void setMediaSizeSpinnerSelectionNoCallback(int position) {
+            if (mMediaSizeSpinner.getSelectedItemPosition() != position) {
+                mOldMediaSizeSelectionIndex = position;
+                mMediaSizeSpinner.setSelection(position);
+            }
+        }
+
+        private void setColorModeSpinnerSelectionNoCallback(int position) {
+            if (mColorModeSpinner.getSelectedItemPosition() != position) {
+                mOldColorModeSelectionIndex = position;
+                mColorModeSpinner.setSelection(position);
+            }
+        }
+
+        private void startSelectPrinterActivity() {
+            Intent intent = new Intent(PrintJobConfigActivity.this,
+                    SelectPrinterActivity.class);
+            startActivityForResult(intent, ACTIVITY_REQUEST_SELECT_PRINTER);
+        }
+
+        private boolean hasErrors() {
+            if (mCopiesEditText.getError() != null) {
+                return true;
+            }
+            return mPageRangeEditText.getVisibility() == View.VISIBLE
+                    && mPageRangeEditText.getError() != null;
+        }
+
+        private final class SpinnerItem<T> {
+            final T value;
+            CharSequence label;
+
+            public SpinnerItem(T value, CharSequence label) {
+                this.value = value;
+                this.label = label;
+            }
+
+            public String toString() {
+                return label.toString();
+            }
+        }
+
+        private final class DestinationAdapter extends BaseAdapter
+                implements LoaderManager.LoaderCallbacks<List<PrinterInfo>>{
+            private final List<PrinterInfo> mPrinters = new ArrayList<PrinterInfo>();
+
+            private final PrinterInfo mFakePdfPrinter;
+
+            private PrinterId mLastShownPrinterId;
+
+            public DestinationAdapter() {
+                getLoaderManager().initLoader(LOADER_ID_PRINTERS_LOADER, null, this);
+                mFakePdfPrinter = createFakePdfPrinter();
+            }
+
+            public int getPrinterIndex(PrinterId printerId) {
+                for (int i = 0; i < getCount(); i++) {
+                    PrinterInfo printer = (PrinterInfo) getItem(i);
+                    if (printer != null && printer.getId().equals(printerId)) {
+                        return i;
+                    }
+                }
+                return AdapterView.INVALID_POSITION;
+            }
+
+            public void ensurePrinterShownPrinterShown(PrinterId printerId) {
+                mLastShownPrinterId = printerId;
+                ensureLastShownPrinterInPosition();
+            }
+
+            @Override
+            public int getCount() {
+                return Math.min(mPrinters.size() + 2, DEST_ADAPTER_MAX_ITEM_COUNT);
+            }
+
+            @Override
+            public Object getItem(int position) {
+                if (mPrinters.isEmpty()) {
+                    if (position == 0) {
+                        return mFakePdfPrinter;
+                    }
+                } else {
+                    if (position < 1) {
+                        return mPrinters.get(position);
+                    }
+                    if (position == 1) {
+                        return mFakePdfPrinter;
+                    }
+                    if (position < getCount() - 1) {
+                        return mPrinters.get(position - 1);
+                    }
+                }
+                return null;
+            }
+
+            @Override
+            public long getItemId(int position) {
+                if (mPrinters.isEmpty()) {
+                    if (position == 0) {
+                        return DEST_ADAPTER_ITEM_ID_SAVE_AS_PDF;
+                    }
+                    if (position == 1) {
+                        return DEST_ADAPTER_ITEM_ID_ALL_PRINTERS;
+                    }
+                } else {
+                    if (position == 1) {
+                        return DEST_ADAPTER_ITEM_ID_SAVE_AS_PDF;
+                    }
+                    if (position == getCount() - 1) {
+                        return DEST_ADAPTER_ITEM_ID_ALL_PRINTERS;
+                    }
+                }
+                return position;
+            }
+
+            @Override
+            public View getDropDownView(int position, View convertView,
+                    ViewGroup parent) {
+                return getView(position, convertView, parent);
+            }
+
+            @Override
+            public View getView(int position, View convertView, ViewGroup parent) {
+                if (convertView == null) {
+                    convertView = getLayoutInflater().inflate(
+                            R.layout.spinner_dropdown_item, parent, false);
+                }
+
+                CharSequence title = null;
+                CharSequence subtitle = null;
+
+                if (mPrinters.isEmpty()) {
+                    if (position == 0) {
+                        PrinterInfo printer = (PrinterInfo) getItem(position);
+                        title = printer.getName();
+                    } else if (position == 1) {
+                        title = getString(R.string.all_printers);
+                    }
+                } else {
+                    if (position == 1) {
+                        PrinterInfo printer = (PrinterInfo) getItem(position);
+                        title = printer.getName();
+                    } else if (position == getCount() - 1) {
+                        title = getString(R.string.all_printers);
+                    } else {
+                        PrinterInfo printer = (PrinterInfo) getItem(position);
+                        title = printer.getName();
+                        try {
+                            PackageInfo packageInfo = getPackageManager().getPackageInfo(
+                                    printer.getId().getServiceName().getPackageName(), 0);
+                            subtitle = packageInfo.applicationInfo.loadLabel(getPackageManager());
+                        } catch (NameNotFoundException nnfe) {
+                            /* ignore */
+                        }
+                    }
+                }
+
+                TextView titleView = (TextView) convertView.findViewById(R.id.title);
+                titleView.setText(title);
+
+                TextView subtitleView = (TextView) convertView.findViewById(R.id.subtitle);
+                if (!TextUtils.isEmpty(subtitle)) {
+                    subtitleView.setText(subtitle);
+                    subtitleView.setVisibility(View.VISIBLE);
+                } else {
+                    subtitleView.setText(null);
+                    subtitleView.setVisibility(View.GONE);
+                }
+
+                return convertView;
+            }
+
+            @Override
+            public Loader<List<PrinterInfo>> onCreateLoader(int id, Bundle args) {
+                if (id == LOADER_ID_PRINTERS_LOADER) {
+                    return new FusedPrintersProvider(PrintJobConfigActivity.this);
+                }
+                return null;
+            }
+
+            @Override
+            public void onLoadFinished(Loader<List<PrinterInfo>> loader,
+                    List<PrinterInfo> printers) {
+                mPrinters.clear();
+                mPrinters.addAll(printers);
+                ensureLastShownPrinterInPosition();
+                notifyDataSetChanged();
+            }
+
+            @Override
+            public void onLoaderReset(Loader<List<PrinterInfo>> loader) {
+                mPrinters.clear();
+                notifyDataSetInvalidated();
+            }
+
+            private void ensureLastShownPrinterInPosition() {
+                if (mLastShownPrinterId == null) {
+                    return;
+                }
+                final int printerCount = mPrinters.size();
+                for (int i = 0; i < printerCount; i++) {
+                    PrinterInfo printer = (PrinterInfo) mPrinters.get(i);
+                    if (printer.getId().equals(mLastShownPrinterId)) {
+                        // If already in the list - do nothing.
+                        if (i < getCount() - 2) {
+                            return;
+                        }
+                        // Else replace the last one.
+                        final int lastPrinter = getCount() - 2;
+                        mPrinters.set(i, mPrinters.get(lastPrinter - 1));
+                        mPrinters.set(lastPrinter - 1, printer);
+                        return;
+                    }
+                }
+            }
+
+            private PrinterInfo createFakePdfPrinter() {
+                PrinterId printerId = new PrinterId(getComponentName(), "PDF printer");
+
+                PrinterCapabilitiesInfo capabilities =
+                        new PrinterCapabilitiesInfo.Builder(printerId)
+                    .addMediaSize(MediaSize.ISO_A4, true)
+                    .addMediaSize(MediaSize.NA_LETTER, false)
+                    .addResolution(new Resolution("PDF resolution", "PDF resolution",
+                            300, 300), true)
+                    .setColorModes(PrintAttributes.COLOR_MODE_COLOR
+                            | PrintAttributes.COLOR_MODE_MONOCHROME,
+                            PrintAttributes.COLOR_MODE_COLOR)
+                    .build();
+
+                return new PrinterInfo.Builder(printerId, getString(R.string.save_as_pdf),
+                        PrinterInfo.STATUS_IDLE)
+                    .setCapabilities(capabilities)
+                    .build();
+            }
+        }
+    }
+
+    /**
+     * An instance of this class class is intended to be the first focusable
+     * in a layout to which the system automatically gives focus. It performs
+     * some voodoo to avoid the first tap on it to start an edit mode, rather
+     * to bring up the IME, i.e. to get the behavior as if the view was not
+     * focused.
+     */
+    public static final class CustomEditText extends EditText {
+        private boolean mClickedBeforeFocus;
+        private CharSequence mError;
+
+        public CustomEditText(Context context, AttributeSet attrs) {
+            super(context, attrs);
+        }
+
+        @Override
+        public boolean performClick() {
+            super.performClick();
+            if (isFocused() && !mClickedBeforeFocus) {
+                clearFocus();
+                requestFocus();
+            }
+            mClickedBeforeFocus = true;
+            return true;
+        }
+
+        @Override
+        public CharSequence getError() {
+            return mError;
+        }
+
+        @Override
+        public void setError(CharSequence error, Drawable icon) {
+            setCompoundDrawables(null, null, icon, null);
+            mError = error;
+        }
+
+        protected void onFocusChanged(boolean gainFocus, int direction,
+                Rect previouslyFocusedRect) {
+            if (!gainFocus) {
+                mClickedBeforeFocus = false;
+            }
+            super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
+        }
+    }
+
+    private static final class Document {
+        public PrintDocumentInfo info;
+        public PageRange[] pages;
+    }
+
+    private static final class PageRangeUtils {
+
+        private static final Comparator<PageRange> sComparator = new Comparator<PageRange>() {
+            @Override
+            public int compare(PageRange lhs, PageRange rhs) {
+                return lhs.getStart() - rhs.getStart();
+            }
+        };
+
+        private PageRangeUtils() {
+            throw new UnsupportedOperationException();
+        }
+
+        public static boolean contains(PageRange[] ourPageRanges, PageRange[] otherPageRanges) {
+            if (ourPageRanges == null || otherPageRanges == null) {
+                return false;
+            }
+
+            otherPageRanges = normalize(otherPageRanges);
+
+            int otherPageIdx = 0;
+            final int myPageCount = ourPageRanges.length;
+            final int otherPageCount = otherPageRanges.length;
+            for (int i= 0; i < myPageCount; i++) {
+                PageRange myPage = ourPageRanges[i];
+                for (; otherPageIdx < otherPageCount; otherPageIdx++) {
+                    PageRange otherPage = otherPageRanges[otherPageIdx];
+                    if (otherPage.getStart() > myPage.getStart()) {
+                        break;
+                    }
+                    if ((otherPage.getStart() < myPage.getStart()
+                                    && otherPage.getEnd() > myPage.getStart())
+                            || (otherPage.getEnd() > myPage.getEnd()
+                                    && otherPage.getStart() < myPage.getEnd())
+                            || (otherPage.getEnd() < myPage.getStart())) {
+                        return false;
+                    }
+                }
+            }
+            if (otherPageIdx < otherPageCount) {
+                return false;
+            }
+            return true;
+        }
+
+        public static PageRange[] normalize(PageRange[] pageRanges) {
+            if (pageRanges == null) {
+                return null;
+            }
+            final int oldPageCount = pageRanges.length;
+            if (oldPageCount <= 1) {
+                return pageRanges;
+            }
+            Arrays.sort(pageRanges, sComparator);
+            int newRangeCount = 0;
+            for (int i = 0; i < oldPageCount - 1; i++) {
+                newRangeCount++;
+                PageRange currentRange = pageRanges[i];
+                PageRange nextRange = pageRanges[i + 1];
+                if (currentRange.getEnd() >= nextRange.getStart()) {
+                    newRangeCount--;
+                    pageRanges[i] = null;
+                    pageRanges[i + 1] = new PageRange(currentRange.getStart(),
+                            nextRange.getEnd());
+                }
+            }
+            if (newRangeCount == oldPageCount) {
+                return pageRanges;
+            }
+            return Arrays.copyOfRange(pageRanges, oldPageCount - newRangeCount,
+                    oldPageCount - 1);
+        }
+
+        public static void offsetStart(PageRange[] pageRanges, int offset) {
+            if (offset == 0) {
+                return;
+            }
+            final int pageRangeCount = pageRanges.length;
+            for (int i = 0; i < pageRangeCount; i++) {
+                final int start = pageRanges[i].getStart() + offset;
+                final int end = pageRanges[i].getEnd() + offset;
+                pageRanges[i] = new PageRange(start, end);
+            }
+        }
+    }
+
+    private static final class AutoCancellingAnimator
+            implements OnAttachStateChangeListener, Runnable {
+
+        private ViewPropertyAnimator mAnimator;
+
+        private boolean mCancelled;
+        private Runnable mEndCallback;
+
+        public static AutoCancellingAnimator animate(View view) {
+            ViewPropertyAnimator animator = view.animate();
+            AutoCancellingAnimator cancellingWrapper =
+                    new AutoCancellingAnimator(animator);
+            view.addOnAttachStateChangeListener(cancellingWrapper);
+            return cancellingWrapper;
+        }
+
+        private AutoCancellingAnimator(ViewPropertyAnimator animator) {
+            mAnimator = animator;
+        }
+
+        public AutoCancellingAnimator alpha(float alpha) {
+            mAnimator = mAnimator.alpha(alpha);
+            return this;
+        }
+
+        public void cancel() {
+            mAnimator.cancel();
+        }
+
+        public AutoCancellingAnimator withLayer() {
+            mAnimator = mAnimator.withLayer();
+            return this;
+        }
+
+        public AutoCancellingAnimator withEndAction(Runnable callback) {
+            mEndCallback = callback;
+            mAnimator = mAnimator.withEndAction(this);
+            return this;
+        }
+
+        public AutoCancellingAnimator scaleY(float scale) {
+            mAnimator = mAnimator.scaleY(scale);
+            return this;
+        }
+
+        @Override
+        public void onViewAttachedToWindow(View v) {
+            /* do nothing */
+        }
+
+        @Override
+        public void onViewDetachedFromWindow(View v) {
+            cancel();
+        }
+
+        @Override
+        public void run() {
+            if (!mCancelled) {
+                mEndCallback.run();
+            }
+        }
+    }
+}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java b/packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java
new file mode 100644
index 0000000..8580fcd
--- /dev/null
+++ b/packages/PrintSpooler/src/com/android/printspooler/PrintSpoolerService.java
@@ -0,0 +1,1134 @@
+/*
+ * 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.printspooler;
+
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.IntentSender;
+import android.os.AsyncTask;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.print.IPrintClient;
+import android.print.IPrintDocumentAdapter;
+import android.print.IPrintSpooler;
+import android.print.IPrintSpoolerCallbacks;
+import android.print.IPrintSpoolerClient;
+import android.print.PageRange;
+import android.print.PrintAttributes;
+import android.print.PrintAttributes.Margins;
+import android.print.PrintAttributes.MediaSize;
+import android.print.PrintAttributes.Resolution;
+import android.print.PrintDocumentInfo;
+import android.print.PrintJobInfo;
+import android.print.PrintManager;
+import android.print.PrinterId;
+import android.print.PrinterInfo;
+import android.text.TextUtils;
+import android.util.AtomicFile;
+import android.util.Log;
+import android.util.Slog;
+import android.util.Xml;
+
+import com.android.internal.os.HandlerCaller;
+import com.android.internal.os.SomeArgs;
+import com.android.internal.util.FastXmlSerializer;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import libcore.io.IoUtils;
+
+/**
+ * Service for exposing some of the {@link PrintSpooler} functionality to
+ * another process.
+ */
+public final class PrintSpoolerService extends Service {
+
+    private static final String LOG_TAG = "PrintSpoolerService";
+
+    private static final boolean DEBUG_PRINT_JOB_LIFECYCLE = false;
+
+    private static final boolean DEBUG_PERSISTENCE = false;
+
+    private static final boolean PERSISTNECE_MANAGER_ENABLED = true;
+
+    private static final long CHECK_ALL_PRINTJOBS_HANDLED_DELAY = 5000;
+
+    private static final String PRINT_FILE_EXTENSION = "pdf";
+
+    private static final Object sLock = new Object();
+
+    private final Object mLock = new Object();
+
+    private final List<PrintJobInfo> mPrintJobs = new ArrayList<PrintJobInfo>();
+
+    private static PrintSpoolerService sInstance;
+
+    private static int sPrintJobIdCounter;
+
+    private Intent mStartPrintJobConfigActivityIntent;
+
+    private IPrintSpoolerClient mClient;
+
+    private HandlerCaller mHandlerCaller;
+
+    private PersistenceManager mPersistanceManager;
+
+    private NotificationController mNotificationController;
+
+    public static PrintSpoolerService peekInstance() {
+        synchronized (sLock) {
+            return sInstance;
+        }
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        mStartPrintJobConfigActivityIntent = new Intent(PrintSpoolerService.this,
+                PrintJobConfigActivity.class);
+        mHandlerCaller = new HandlerCaller(this, getMainLooper(),
+                new HandlerCallerCallback(), false);
+
+        mPersistanceManager = new PersistenceManager();
+        mNotificationController = new NotificationController(PrintSpoolerService.this);
+
+        synchronized (mLock) {
+            mPersistanceManager.readStateLocked();
+            handleReadPrintJobsLocked();
+        }
+
+        synchronized (sLock) {
+            sInstance = this;
+        }
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return new IPrintSpooler.Stub() {
+            @Override
+            public void getPrintJobInfos(IPrintSpoolerCallbacks callback,
+                    ComponentName componentName, int state, int appId, int sequence)
+                    throws RemoteException {
+                List<PrintJobInfo> printJobs = null;
+                try {
+                    printJobs = PrintSpoolerService.this.getPrintJobInfos(
+                            componentName, state, appId);
+                } finally {
+                    callback.onGetPrintJobInfosResult(printJobs, sequence);
+                }
+            }
+
+            @Override
+            public void getPrintJobInfo(int printJobId, IPrintSpoolerCallbacks callback,
+                    int appId, int sequence) throws RemoteException {
+                PrintJobInfo printJob = null;
+                try {
+                    printJob = PrintSpoolerService.this.getPrintJobInfo(printJobId, appId);
+                } finally {
+                    callback.onGetPrintJobInfoResult(printJob, sequence);
+                }
+            }
+
+            @SuppressWarnings("deprecation")
+            @Override
+            public void createPrintJob(String printJobName, IPrintClient client,
+                    IPrintDocumentAdapter printAdapter, PrintAttributes attributes,
+                    IPrintSpoolerCallbacks callback, int appId, int sequence)
+                    throws RemoteException {
+                PrintJobInfo printJob = null;
+                try {
+                    printJob = PrintSpoolerService.this.createPrintJob(
+                            printJobName, client, attributes, appId);
+                    if (printJob != null) {
+                        Intent intent = mStartPrintJobConfigActivityIntent;
+                        intent.putExtra(PrintJobConfigActivity.EXTRA_PRINT_DOCUMENT_ADAPTER,
+                                printAdapter.asBinder());
+                        intent.putExtra(PrintJobConfigActivity.EXTRA_PRINT_JOB_ID,
+                                printJob.getId());
+                        intent.putExtra(PrintJobConfigActivity.EXTRA_PRINT_ATTRIBUTES, attributes);
+
+                        IntentSender sender = PendingIntent.getActivity(
+                                PrintSpoolerService.this, 0, intent, PendingIntent.FLAG_ONE_SHOT
+                                        | PendingIntent.FLAG_CANCEL_CURRENT).getIntentSender();
+
+                        Message message = mHandlerCaller.obtainMessageOO(
+                                HandlerCallerCallback.MSG_START_PRINT_JOB_CONFIG_ACTIVITY,
+                                client, sender);
+                        mHandlerCaller.executeOrSendMessage(message);
+                    }
+                } finally {
+                    callback.onCreatePrintJobResult(printJob, sequence);
+                }
+            }
+
+            @Override
+            public void setPrintJobState(int printJobId, int state, String error,
+                    IPrintSpoolerCallbacks callback, int sequece) throws RemoteException {
+                boolean success = false;
+                try {
+                    success = PrintSpoolerService.this.setPrintJobState(
+                            printJobId, state, error);
+                } finally {
+                    callback.onSetPrintJobStateResult(success, sequece);
+                }
+            }
+
+            @Override
+            public void setPrintJobTag(int printJobId, String tag,
+                    IPrintSpoolerCallbacks callback, int sequece) throws RemoteException {
+                boolean success = false;
+                try {
+                    success = PrintSpoolerService.this.setPrintJobTag(printJobId, tag);
+                } finally {
+                    callback.onSetPrintJobTagResult(success, sequece);
+                }
+            }
+
+            @Override
+            public void writePrintJobData(ParcelFileDescriptor fd, int printJobId) {
+                PrintSpoolerService.this.writePrintJobData(fd, printJobId);
+            }
+
+            @Override
+            public void setClient(IPrintSpoolerClient client) {
+                Message message = mHandlerCaller.obtainMessageO(
+                        HandlerCallerCallback.MSG_SET_CLIENT, client);
+                mHandlerCaller.executeOrSendMessage(message);
+            }
+        };
+    }
+
+    private void sendOnPrintJobQueued(PrintJobInfo printJob) {
+        Message message = mHandlerCaller.obtainMessageO(
+                HandlerCallerCallback.MSG_ON_PRINT_JOB_QUEUED, printJob);
+        mHandlerCaller.executeOrSendMessage(message);
+    }
+
+    private void sendOnAllPrintJobsForServiceHandled(ComponentName service) {
+        Message message = mHandlerCaller.obtainMessageO(
+                HandlerCallerCallback.MSG_ON_ALL_PRINT_JOBS_FOR_SERIVICE_HANDLED, service);
+        mHandlerCaller.executeOrSendMessage(message);
+    }
+
+    private void sendOnAllPrintJobsHandled() {
+        Message message = mHandlerCaller.obtainMessage(
+                HandlerCallerCallback.MSG_ON_ALL_PRINT_JOBS_HANDLED);
+        mHandlerCaller.executeOrSendMessage(message);
+    }
+
+    private final class HandlerCallerCallback implements HandlerCaller.Callback {
+        public static final int MSG_SET_CLIENT = 9;
+        public static final int MSG_START_PRINT_JOB_CONFIG_ACTIVITY = 10;
+        public static final int MSG_ON_PRINT_JOB_QUEUED = 11;
+        public static final int MSG_ON_ALL_PRINT_JOBS_FOR_SERIVICE_HANDLED = 12;
+        public static final int MSG_ON_ALL_PRINT_JOBS_HANDLED = 13;
+        public static final int MSG_CHECK_ALL_PRINTJOBS_HANDLED = 14;
+
+        @Override
+        public void executeMessage(Message message) {
+            switch (message.what) {
+                case MSG_SET_CLIENT: {
+                    synchronized (mLock) {
+                        mClient = (IPrintSpoolerClient) message.obj;
+                        if (mClient != null) {
+                            Message msg = mHandlerCaller.obtainMessage(
+                                    HandlerCallerCallback.MSG_CHECK_ALL_PRINTJOBS_HANDLED);
+                            mHandlerCaller.sendMessageDelayed(msg,
+                                    CHECK_ALL_PRINTJOBS_HANDLED_DELAY);
+                        }
+                    }
+                } break;
+
+                case MSG_START_PRINT_JOB_CONFIG_ACTIVITY: {
+                    SomeArgs args = (SomeArgs) message.obj;
+                    IPrintClient client = (IPrintClient) args.arg1;
+                    IntentSender sender = (IntentSender) args.arg2;
+                    args.recycle();
+                    try {
+                        client.startPrintJobConfigActivity(sender);
+                    } catch (RemoteException re) {
+                        Slog.i(LOG_TAG, "Error starting print job config activity!", re);
+                    }
+                } break;
+
+                case MSG_ON_PRINT_JOB_QUEUED: {
+                    PrintJobInfo printJob = (PrintJobInfo) message.obj;
+                    if (mClient != null) {
+                        try {
+                            mClient.onPrintJobQueued(printJob);
+                        } catch (RemoteException re) {
+                            Slog.e(LOG_TAG, "Error notify for a queued print job.", re);
+                        }
+                    }
+                } break;
+
+                case MSG_ON_ALL_PRINT_JOBS_FOR_SERIVICE_HANDLED: {
+                    ComponentName service = (ComponentName) message.obj;
+                    if (mClient != null) {
+                        try {
+                            mClient.onAllPrintJobsForServiceHandled(service);
+                        } catch (RemoteException re) {
+                            Slog.e(LOG_TAG, "Error notify for all print jobs per service"
+                                    + " handled.", re);
+                        }
+                    }
+                } break;
+
+                case MSG_ON_ALL_PRINT_JOBS_HANDLED: {
+                    if (mClient != null) {
+                        try {
+                            mClient.onAllPrintJobsHandled();
+                        } catch (RemoteException re) {
+                            Slog.e(LOG_TAG, "Error notify for all print job handled.", re);
+                        }
+                    }
+                } break;
+
+                case MSG_CHECK_ALL_PRINTJOBS_HANDLED: {
+                    checkAllPrintJobsHandled();
+                } break;
+            }
+        }
+    }
+
+    public List<PrintJobInfo> getPrintJobInfos(ComponentName componentName,
+            int state, int appId) {
+        List<PrintJobInfo> foundPrintJobs = null;
+        synchronized (mLock) {
+            final int printJobCount = mPrintJobs.size();
+            for (int i = 0; i < printJobCount; i++) {
+                PrintJobInfo printJob = mPrintJobs.get(i);
+                PrinterId printerId = printJob.getPrinterId();
+                final boolean sameComponent = (componentName == null
+                        || (printerId != null
+                        && componentName.equals(printerId.getServiceName())));
+                final boolean sameAppId = appId == PrintManager.APP_ID_ANY
+                        || printJob.getAppId() == appId;
+                final boolean sameState = (state == printJob.getState())
+                        || (state == PrintJobInfo.STATE_ANY)
+                        || (state == PrintJobInfo.STATE_ANY_VISIBLE_TO_CLIENTS
+                            && isStateVisibleToUser(printJob.getState()))
+                        || (state == PrintJobInfo.STATE_ANY_ACTIVE
+                            && isActiveState(printJob.getState()));
+                if (sameComponent && sameAppId && sameState) {
+                    if (foundPrintJobs == null) {
+                        foundPrintJobs = new ArrayList<PrintJobInfo>();
+                    }
+                    foundPrintJobs.add(printJob);
+                }
+            }
+        }
+        return foundPrintJobs;
+    }
+
+    private boolean isStateVisibleToUser(int state) {
+        return (isActiveState(state) && (state == PrintJobInfo.STATE_FAILED
+                || state == PrintJobInfo.STATE_COMPLETED|| state == PrintJobInfo.STATE_CANCELED));
+    }
+
+    public PrintJobInfo getPrintJobInfo(int printJobId, int appId) {
+        synchronized (mLock) {
+            final int printJobCount = mPrintJobs.size();
+            for (int i = 0; i < printJobCount; i++) {
+                PrintJobInfo printJob = mPrintJobs.get(i);
+                if (printJob.getId() == printJobId
+                        && (appId == PrintManager.APP_ID_ANY
+                        || appId == printJob.getAppId())) {
+                    return printJob;
+                }
+            }
+            return null;
+        }
+    }
+
+    public PrintJobInfo createPrintJob(String label, IPrintClient client,
+            PrintAttributes attributes, int appId) {
+        synchronized (mLock) {
+            final int printJobId = generatePrintJobIdLocked();
+            PrintJobInfo printJob = new PrintJobInfo();
+            printJob.setId(printJobId);
+            printJob.setAppId(appId);
+            printJob.setLabel(label);
+            printJob.setAttributes(attributes);
+            printJob.setState(PrintJobInfo.STATE_CREATED);
+
+            addPrintJobLocked(printJob);
+
+            return printJob;
+        }
+    }
+
+    private void handleReadPrintJobsLocked() {
+        final int printJobCount = mPrintJobs.size();
+        for (int i = 0; i < printJobCount; i++) {
+            PrintJobInfo printJob = mPrintJobs.get(i);
+
+            // Update the notification.
+            mNotificationController.onPrintJobStateChanged(printJob);
+
+            switch (printJob.getState()) {
+                case PrintJobInfo.STATE_QUEUED:
+                case PrintJobInfo.STATE_STARTED:
+                case PrintJobInfo.STATE_BLOCKED: {
+                    // We have a print job that was queued or started or blocked in
+                    // the past but the device battery died or a crash occurred. In
+                    // this case we assume the print job failed and let the user
+                    // decide whether to restart the job or just cancel it.
+                    setPrintJobState(printJob.getId(), PrintJobInfo.STATE_FAILED,
+                            getString(R.string.no_connection_to_printer));
+                }
+                    break;
+            }
+        }
+    }
+
+    public void checkAllPrintJobsHandled() {
+        synchronized (mLock) {
+            if (!hasActivePrintJobsLocked()) {
+                notifyOnAllPrintJobsHandled();
+            }
+        }
+    }
+
+    private int generatePrintJobIdLocked() {
+        int printJobId = sPrintJobIdCounter++;
+        while (isDuplicatePrintJobId(printJobId)) {
+            printJobId = sPrintJobIdCounter++;
+        }
+        return printJobId;
+    }
+
+    private boolean isDuplicatePrintJobId(int printJobId) {
+        final int printJobCount = mPrintJobs.size();
+        for (int j = 0; j < printJobCount; j++) {
+            PrintJobInfo printJob = mPrintJobs.get(j);
+            if (printJob.getId() == printJobId) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public void writePrintJobData(final ParcelFileDescriptor fd, final int printJobId) {
+        final PrintJobInfo printJob;
+        synchronized (mLock) {
+            printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
+        }
+        new AsyncTask<Void, Void, Void>() {
+            @Override
+            protected Void doInBackground(Void... params) {
+                FileInputStream in = null;
+                FileOutputStream out = null;
+                try {
+                    if (printJob != null) {
+                        File file = generateFileForPrintJob(printJobId);
+                        in = new FileInputStream(file);
+                        out = new FileOutputStream(fd.getFileDescriptor());
+                    }
+                    final byte[] buffer = new byte[8192];
+                    while (true) {
+                        final int readByteCount = in.read(buffer);
+                        if (readByteCount < 0) {
+                            return null;
+                        }
+                        out.write(buffer, 0, readByteCount);
+                    }
+                } catch (FileNotFoundException fnfe) {
+                    Log.e(LOG_TAG, "Error writing print job data!", fnfe);
+                } catch (IOException ioe) {
+                    Log.e(LOG_TAG, "Error writing print job data!", ioe);
+                } finally {
+                    IoUtils.closeQuietly(in);
+                    IoUtils.closeQuietly(out);
+                    IoUtils.closeQuietly(fd);
+                }
+                Log.i(LOG_TAG, "[END WRITE]");
+                return null;
+            }
+        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
+    }
+
+    public File generateFileForPrintJob(int printJobId) {
+        return new File(getFilesDir(), "print_job_"
+                + printJobId + "." + PRINT_FILE_EXTENSION);
+    }
+
+    private void addPrintJobLocked(PrintJobInfo printJob) {
+        mPrintJobs.add(printJob);
+        if (DEBUG_PRINT_JOB_LIFECYCLE) {
+            Slog.i(LOG_TAG, "[ADD] " + printJob);
+        }
+    }
+
+    private void removePrintJobLocked(PrintJobInfo printJob) {
+        if (mPrintJobs.remove(printJob)) {
+            generateFileForPrintJob(printJob.getId()).delete();
+            if (DEBUG_PRINT_JOB_LIFECYCLE) {
+                Slog.i(LOG_TAG, "[REMOVE] " + printJob);
+            }
+        }
+    }
+
+    public boolean setPrintJobState(int printJobId, int state, String error) {
+        boolean success = false;
+
+        synchronized (mLock) {
+            PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
+            if (printJob != null) {
+                success = true;
+
+                printJob.setState(state);
+                printJob.setStateReason(error);
+                mNotificationController.onPrintJobStateChanged(printJob);
+
+                if (DEBUG_PRINT_JOB_LIFECYCLE) {
+                    Slog.i(LOG_TAG, "[STATE CHANGED] " + printJob);
+                }
+
+                switch (state) {
+                    case PrintJobInfo.STATE_COMPLETED:
+                    case PrintJobInfo.STATE_CANCELED:
+                        removePrintJobLocked(printJob);
+                        // $fall-through$
+
+                    case PrintJobInfo.STATE_FAILED: {
+                        PrinterId printerId = printJob.getPrinterId();
+                        if (printerId != null) {
+                            ComponentName service = printerId.getServiceName();
+                            if (!hasActivePrintJobsForServiceLocked(service)) {
+                                sendOnAllPrintJobsForServiceHandled(service);
+                            }
+                        }
+                    } break;
+
+                    case PrintJobInfo.STATE_QUEUED: {
+                        sendOnPrintJobQueued(new PrintJobInfo(printJob));
+                    }  break;
+                }
+
+                if (shouldPersistPrintJob(printJob)) {
+                    mPersistanceManager.writeStateLocked();
+                }
+
+                if (!hasActivePrintJobsLocked()) {
+                    notifyOnAllPrintJobsHandled();
+                }
+            }
+        }
+
+        return success;
+    }
+
+    public boolean hasActivePrintJobsLocked() {
+        final int printJobCount = mPrintJobs.size();
+        for (int i = 0; i < printJobCount; i++) {
+            PrintJobInfo printJob = mPrintJobs.get(i);
+            if (isActiveState(printJob.getState())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public boolean hasActivePrintJobsForServiceLocked(ComponentName service) {
+        final int printJobCount = mPrintJobs.size();
+        for (int i = 0; i < printJobCount; i++) {
+            PrintJobInfo printJob = mPrintJobs.get(i);
+            if (isActiveState(printJob.getState())
+                    && printJob.getPrinterId().getServiceName().equals(service)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean isActiveState(int printJobState) {
+        return printJobState == PrintJobInfo.STATE_CREATED
+                || printJobState == PrintJobInfo.STATE_QUEUED
+                || printJobState == PrintJobInfo.STATE_STARTED
+                || printJobState == PrintJobInfo.STATE_BLOCKED;
+    }
+
+    public boolean setPrintJobTag(int printJobId, String tag) {
+        synchronized (mLock) {
+            PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
+            if (printJob != null) {
+                String printJobTag = printJob.getTag();
+                if (printJobTag == null) {
+                    if (tag == null) {
+                        return false;
+                    }
+                } else if (printJobTag.equals(tag)) {
+                    return false;
+                }
+                printJob.setTag(tag);
+                if (shouldPersistPrintJob(printJob)) {
+                    mPersistanceManager.writeStateLocked();
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public void setPrintJobCopiesNoPersistence(int printJobId, int copies) {
+        synchronized (mLock) {
+            PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
+            if (printJob != null) {
+                printJob.setCopies(copies);
+            }
+        }
+    }
+
+    public void setPrintJobPrintDocumentInfoNoPersistence(int printJobId, PrintDocumentInfo info) {
+        synchronized (mLock) {
+            PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
+            if (printJob != null) {
+                printJob.setDocumentInfo(info);
+            }
+        }
+    }
+
+    public void setPrintJobAttributesNoPersistence(int printJobId, PrintAttributes attributes) {
+        synchronized (mLock) {
+            PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
+            if (printJob != null) {
+                printJob.setAttributes(attributes);
+            }
+        }
+    }
+
+    public void setPrintJobPrinterNoPersistence(int printJobId, PrinterInfo printer) {
+        synchronized (mLock) {
+            PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
+            if (printJob != null) {
+                printJob.setPrinterId(printer.getId());
+                printJob.setPrinterName(printer.getName());
+            }
+        }
+    }
+
+    public void setPrintJobPagesNoPersistence(int printJobId, PageRange[] pages) {
+        synchronized (mLock) {
+            PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
+            if (printJob != null) {
+                printJob.setPages(pages);
+            }
+        }
+    }
+
+    private boolean shouldPersistPrintJob(PrintJobInfo printJob) {
+        return printJob.getState() >= PrintJobInfo.STATE_QUEUED;
+    }
+
+    private void notifyOnAllPrintJobsHandled() {
+        // This has to run on the tread that is persisting the current state
+        // since this call may result in the system unbinding from the spooler
+        // and as a result the spooler process may get killed before the write
+        // completes.
+        new AsyncTask<Void, Void, Void>() {
+            @Override
+            protected Void doInBackground(Void... params) {
+                sendOnAllPrintJobsHandled();
+                return null;
+            }
+        }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, (Void[]) null);
+    }
+
+    private final class PersistenceManager {
+        private static final String PERSIST_FILE_NAME = "print_spooler_state.xml";
+
+        private static final String TAG_SPOOLER = "spooler";
+        private static final String TAG_JOB = "job";
+
+        private static final String TAG_PRINTER_ID = "printerId";
+        private static final String TAG_PAGE_RANGE = "pageRange";
+        private static final String TAG_ATTRIBUTES = "attributes";
+        private static final String TAG_DOCUMENT_INFO = "documentInfo";
+
+        private static final String ATTR_ID = "id";
+        private static final String ATTR_LABEL = "label";
+        private static final String ATTR_LABEL_RES_ID = "labelResId";
+        private static final String ATTR_PACKAGE_NAME = "packageName";
+        private static final String ATTR_STATE = "state";
+        private static final String ATTR_APP_ID = "appId";
+        private static final String ATTR_USER_ID = "userId";
+        private static final String ATTR_TAG = "tag";
+        private static final String ATTR_COPIES = "copies";
+
+        private static final String TAG_MEDIA_SIZE = "mediaSize";
+        private static final String TAG_RESOLUTION = "resolution";
+        private static final String TAG_MARGINS = "margins";
+
+        private static final String ATTR_COLOR_MODE = "colorMode";
+
+        private static final String ATTR_LOCAL_ID = "printerName";
+        private static final String ATTR_SERVICE_NAME = "serviceName";
+
+        private static final String ATTR_WIDTH_MILS = "widthMils";
+        private static final String ATTR_HEIGHT_MILS = "heightMils";
+
+        private static final String ATTR_HORIZONTAL_DPI = "horizontalDip";
+        private static final String ATTR_VERTICAL_DPI = "verticalDpi";
+
+        private static final String ATTR_LEFT_MILS = "leftMils";
+        private static final String ATTR_TOP_MILS = "topMils";
+        private static final String ATTR_RIGHT_MILS = "rightMils";
+        private static final String ATTR_BOTTOM_MILS = "bottomMils";
+
+        private static final String ATTR_START = "start";
+        private static final String ATTR_END = "end";
+
+        private static final String ATTR_NAME = "name";
+        private static final String ATTR_PAGE_COUNT = "pageCount";
+        private static final String ATTR_CONTENT_TYPE = "contentType";
+
+        private final AtomicFile mStatePersistFile;
+
+        private boolean mWriteStateScheduled;
+
+        private PersistenceManager() {
+            mStatePersistFile = new AtomicFile(new File(getFilesDir(),
+                    PERSIST_FILE_NAME));
+        }
+
+        public void writeStateLocked() {
+            if (!PERSISTNECE_MANAGER_ENABLED) {
+                return;
+            }
+            if (mWriteStateScheduled) {
+                return;
+            }
+            mWriteStateScheduled = true;
+            new AsyncTask<Void, Void, Void>() {
+                @Override
+                protected Void doInBackground(Void... params) {
+                    synchronized (mLock) {
+                        mWriteStateScheduled = false;
+                        doWriteStateLocked();
+                    }
+                    return null;
+                }
+            }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, (Void[]) null);
+        }
+
+        private void doWriteStateLocked() {
+            if (DEBUG_PERSISTENCE) {
+                Log.i(LOG_TAG, "[PERSIST START]");
+            }
+            FileOutputStream out = null;
+            try {
+                out = mStatePersistFile.startWrite();
+
+                XmlSerializer serializer = new FastXmlSerializer();
+                serializer.setOutput(out, "utf-8");
+                serializer.startDocument(null, true);
+                serializer.startTag(null, TAG_SPOOLER);
+
+                List<PrintJobInfo> printJobs = mPrintJobs;
+
+                final int printJobCount = printJobs.size();
+                for (int j = 0; j < printJobCount; j++) {
+                    PrintJobInfo printJob = printJobs.get(j);
+
+                    final int state = printJob.getState();
+                    if (state < PrintJobInfo.STATE_QUEUED
+                            || state > PrintJobInfo.STATE_CANCELED) {
+                        continue;
+                    }
+
+                    serializer.startTag(null, TAG_JOB);
+
+                    serializer.attribute(null, ATTR_ID, String.valueOf(printJob.getId()));
+                    serializer.attribute(null, ATTR_LABEL, printJob.getLabel().toString());
+                    serializer.attribute(null, ATTR_STATE, String.valueOf(printJob.getState()));
+                    serializer.attribute(null, ATTR_APP_ID, String.valueOf(printJob.getAppId()));
+                    serializer.attribute(null, ATTR_USER_ID, String.valueOf(printJob.getUserId()));
+                    String tag = printJob.getTag();
+                    if (tag != null) {
+                        serializer.attribute(null, ATTR_TAG, tag);
+                    }
+                    serializer.attribute(null, ATTR_COPIES, String.valueOf(printJob.getCopies()));
+
+                    PrinterId printerId = printJob.getPrinterId();
+                    if (printerId != null) {
+                        serializer.startTag(null, TAG_PRINTER_ID);
+                        serializer.attribute(null, ATTR_LOCAL_ID, printerId.getLocalId());
+                        serializer.attribute(null, ATTR_SERVICE_NAME, printerId.getServiceName()
+                                .flattenToString());
+                        serializer.endTag(null, TAG_PRINTER_ID);
+                    }
+
+                    PageRange[] pages = printJob.getPages();
+                    if (pages != null) {
+                        for (int i = 0; i < pages.length; i++) {
+                            serializer.startTag(null, TAG_PAGE_RANGE);
+                            serializer.attribute(null, ATTR_START, String.valueOf(
+                                    pages[i].getStart()));
+                            serializer.attribute(null, ATTR_END, String.valueOf(
+                                    pages[i].getEnd()));
+                            serializer.endTag(null, TAG_PAGE_RANGE);
+                        }
+                    }
+
+                    PrintAttributes attributes = printJob.getAttributes();
+                    if (attributes != null) {
+                        serializer.startTag(null, TAG_ATTRIBUTES);
+
+                        final int colorMode = attributes.getColorMode();
+                        serializer.attribute(null, ATTR_COLOR_MODE,
+                                String.valueOf(colorMode));
+
+                        MediaSize mediaSize = attributes.getMediaSize();
+                        if (mediaSize != null) {
+                            serializer.startTag(null, TAG_MEDIA_SIZE);
+                            serializer.attribute(null, ATTR_ID, mediaSize.getId());
+                            serializer.attribute(null, ATTR_WIDTH_MILS, String.valueOf(
+                                    mediaSize.getWidthMils()));
+                            serializer.attribute(null, ATTR_HEIGHT_MILS, String.valueOf(
+                                    mediaSize.getHeightMils()));
+                            // We prefer to store only the package name and
+                            // resource id and fallback to the label.
+                            if (!TextUtils.isEmpty(mediaSize.mPackageName)
+                                    && mediaSize.mLabelResId > 0) {
+                                serializer.attribute(null, ATTR_PACKAGE_NAME,
+                                        mediaSize.mPackageName);
+                                serializer.attribute(null, ATTR_LABEL_RES_ID,
+                                        String.valueOf(mediaSize.mLabelResId));
+                            } else {
+                                serializer.attribute(null, ATTR_LABEL,
+                                        mediaSize.getLabel(getPackageManager()));
+                            }
+                            serializer.endTag(null, TAG_MEDIA_SIZE);
+                        }
+
+                        Resolution resolution = attributes.getResolution();
+                        if (resolution != null) {
+                            serializer.startTag(null, TAG_RESOLUTION);
+                            serializer.attribute(null, ATTR_ID, resolution.getId());
+                            serializer.attribute(null, ATTR_HORIZONTAL_DPI, String.valueOf(
+                                    resolution.getHorizontalDpi()));
+                            serializer.attribute(null, ATTR_VERTICAL_DPI, String.valueOf(
+                                    resolution.getVerticalDpi()));
+                            serializer.attribute(null, ATTR_LABEL,
+                                    resolution.getLabel());
+                            serializer.endTag(null, TAG_RESOLUTION);
+                        }
+
+                        Margins margins = attributes.getMinMargins();
+                        if (margins != null) {
+                            serializer.startTag(null, TAG_MARGINS);
+                            serializer.attribute(null, ATTR_LEFT_MILS, String.valueOf(
+                                    margins.getLeftMils()));
+                            serializer.attribute(null, ATTR_TOP_MILS, String.valueOf(
+                                    margins.getTopMils()));
+                            serializer.attribute(null, ATTR_RIGHT_MILS, String.valueOf(
+                                    margins.getRightMils()));
+                            serializer.attribute(null, ATTR_BOTTOM_MILS, String.valueOf(
+                                    margins.getBottomMils()));
+                            serializer.endTag(null, TAG_MARGINS);
+                        }
+
+                        serializer.endTag(null, TAG_ATTRIBUTES);
+                    }
+
+                    PrintDocumentInfo documentInfo = printJob.getDocumentInfo();
+                    if (documentInfo != null) {
+                        serializer.startTag(null, TAG_DOCUMENT_INFO);
+                        serializer.attribute(null, ATTR_NAME, documentInfo.getName());
+                        serializer.attribute(null, ATTR_CONTENT_TYPE, String.valueOf(
+                                documentInfo.getContentType()));
+                        serializer.attribute(null, ATTR_PAGE_COUNT, String.valueOf(
+                                documentInfo.getPageCount()));
+                        serializer.endTag(null, TAG_DOCUMENT_INFO);
+                    }
+
+                    serializer.endTag(null, TAG_JOB);
+
+                    if (DEBUG_PERSISTENCE) {
+                        Log.i(LOG_TAG, "[PERSISTED] " + printJob);
+                    }
+                }
+
+                serializer.endTag(null, TAG_SPOOLER);
+                serializer.endDocument();
+                mStatePersistFile.finishWrite(out);
+                if (DEBUG_PERSISTENCE) {
+                    Log.i(LOG_TAG, "[PERSIST END]");
+                }
+            } catch (IOException e) {
+                Slog.w(LOG_TAG, "Failed to write state, restoring backup.", e);
+                mStatePersistFile.failWrite(out);
+            } finally {
+                IoUtils.closeQuietly(out);
+            }
+        }
+
+        public void readStateLocked() {
+            if (!PERSISTNECE_MANAGER_ENABLED) {
+                return;
+            }
+            FileInputStream in = null;
+            try {
+                in = mStatePersistFile.openRead();
+            } catch (FileNotFoundException e) {
+                Log.i(LOG_TAG, "No existing print spooler state.");
+                return;
+            }
+            try {
+                XmlPullParser parser = Xml.newPullParser();
+                parser.setInput(in, null);
+                parseState(parser);
+            } catch (IllegalStateException ise) {
+                Slog.w(LOG_TAG, "Failed parsing ", ise);
+            } catch (NullPointerException npe) {
+                Slog.w(LOG_TAG, "Failed parsing ", npe);
+            } catch (NumberFormatException nfe) {
+                Slog.w(LOG_TAG, "Failed parsing ", nfe);
+            } catch (XmlPullParserException xppe) {
+                Slog.w(LOG_TAG, "Failed parsing ", xppe);
+            } catch (IOException ioe) {
+                Slog.w(LOG_TAG, "Failed parsing ", ioe);
+            } catch (IndexOutOfBoundsException iobe) {
+                Slog.w(LOG_TAG, "Failed parsing ", iobe);
+            } finally {
+                IoUtils.closeQuietly(in);
+            }
+        }
+
+        private void parseState(XmlPullParser parser)
+                throws IOException, XmlPullParserException {
+            parser.next();
+            skipEmptyTextTags(parser);
+            expect(parser, XmlPullParser.START_TAG, TAG_SPOOLER);
+            parser.next();
+
+            while (parsePrintJob(parser)) {
+                parser.next();
+            }
+
+            skipEmptyTextTags(parser);
+            expect(parser, XmlPullParser.END_TAG, TAG_SPOOLER);
+        }
+
+        private boolean parsePrintJob(XmlPullParser parser)
+                throws IOException, XmlPullParserException {
+            skipEmptyTextTags(parser);
+            if (!accept(parser, XmlPullParser.START_TAG, TAG_JOB)) {
+                return false;
+            }
+
+            PrintJobInfo printJob = new PrintJobInfo();
+
+            final int printJobId = Integer.parseInt(parser.getAttributeValue(null, ATTR_ID));
+            printJob.setId(printJobId);
+            String label = parser.getAttributeValue(null, ATTR_LABEL);
+            printJob.setLabel(label);
+            final int state = Integer.parseInt(parser.getAttributeValue(null, ATTR_STATE));
+            printJob.setState(state);
+            final int appId = Integer.parseInt(parser.getAttributeValue(null, ATTR_APP_ID));
+            printJob.setAppId(appId);
+            final int userId = Integer.parseInt(parser.getAttributeValue(null, ATTR_USER_ID));
+            printJob.setUserId(userId);
+            String tag = parser.getAttributeValue(null, ATTR_TAG);
+            printJob.setTag(tag);
+            String copies = parser.getAttributeValue(null, ATTR_COPIES);
+            printJob.setCopies(Integer.parseInt(copies));
+
+            parser.next();
+
+            skipEmptyTextTags(parser);
+            if (accept(parser, XmlPullParser.START_TAG, TAG_PRINTER_ID)) {
+                String localId = parser.getAttributeValue(null, ATTR_LOCAL_ID);
+                ComponentName service = ComponentName.unflattenFromString(parser.getAttributeValue(
+                        null, ATTR_SERVICE_NAME));
+                printJob.setPrinterId(new PrinterId(service, localId));
+                parser.next();
+                skipEmptyTextTags(parser);
+                expect(parser, XmlPullParser.END_TAG, TAG_PRINTER_ID);
+                parser.next();
+            }
+
+            skipEmptyTextTags(parser);
+            List<PageRange> pageRanges = null;
+            while (accept(parser, XmlPullParser.START_TAG, TAG_PAGE_RANGE)) {
+                final int start = Integer.parseInt(parser.getAttributeValue(null, ATTR_START));
+                final int end = Integer.parseInt(parser.getAttributeValue(null, ATTR_END));
+                PageRange pageRange = new PageRange(start, end);
+                if (pageRanges == null) {
+                    pageRanges = new ArrayList<PageRange>();
+                }
+                pageRanges.add(pageRange);
+                parser.next();
+                skipEmptyTextTags(parser);
+                expect(parser, XmlPullParser.END_TAG, TAG_PAGE_RANGE);
+                parser.next();
+            }
+            if (pageRanges != null) {
+                PageRange[] pageRangesArray = new PageRange[pageRanges.size()];
+                pageRanges.toArray(pageRangesArray);
+                printJob.setPages(pageRangesArray);
+            }
+
+            skipEmptyTextTags(parser);
+            if (accept(parser, XmlPullParser.START_TAG, TAG_ATTRIBUTES)) {
+
+                PrintAttributes.Builder builder = new PrintAttributes.Builder();
+
+                String colorMode = parser.getAttributeValue(null, ATTR_COLOR_MODE);
+                builder.setColorMode(Integer.parseInt(colorMode));
+
+                parser.next();
+
+                skipEmptyTextTags(parser);
+                if (accept(parser, XmlPullParser.START_TAG, TAG_MEDIA_SIZE)) {
+                    String id = parser.getAttributeValue(null, ATTR_ID);
+                    label = parser.getAttributeValue(null, ATTR_LABEL);
+                    final int widthMils = Integer.parseInt(parser.getAttributeValue(null,
+                            ATTR_WIDTH_MILS));
+                    final int heightMils = Integer.parseInt(parser.getAttributeValue(null,
+                            ATTR_HEIGHT_MILS));
+                    String packageName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
+                    final int labelResId = Integer.parseInt(parser.getAttributeValue(null,
+                            ATTR_LABEL_RES_ID));
+                    label = parser.getAttributeValue(null, ATTR_LABEL);
+                    MediaSize mediaSize = new MediaSize(id, label, packageName, labelResId,
+                                widthMils, heightMils);
+                    builder.setMediaSize(mediaSize);
+                    parser.next();
+                    skipEmptyTextTags(parser);
+                    expect(parser, XmlPullParser.END_TAG, TAG_MEDIA_SIZE);
+                    parser.next();
+                }
+
+                skipEmptyTextTags(parser);
+                if (accept(parser, XmlPullParser.START_TAG, TAG_RESOLUTION)) {
+                    String id = parser.getAttributeValue(null, ATTR_ID);
+                    label = parser.getAttributeValue(null, ATTR_LABEL);
+                    final int horizontalDpi = Integer.parseInt(parser.getAttributeValue(null,
+                            ATTR_HORIZONTAL_DPI));
+                    final int verticalDpi = Integer.parseInt(parser.getAttributeValue(null,
+                            ATTR_VERTICAL_DPI));
+                    Resolution resolution = new Resolution(id, label, horizontalDpi, verticalDpi);
+                    builder.setResolution(resolution);
+                    parser.next();
+                    skipEmptyTextTags(parser);
+                    expect(parser, XmlPullParser.END_TAG, TAG_RESOLUTION);
+                    parser.next();
+                }
+
+                skipEmptyTextTags(parser);
+                if (accept(parser, XmlPullParser.START_TAG, TAG_MARGINS)) {
+                    final int leftMils = Integer.parseInt(parser.getAttributeValue(null,
+                            ATTR_LEFT_MILS));
+                    final int topMils = Integer.parseInt(parser.getAttributeValue(null,
+                            ATTR_TOP_MILS));
+                    final int rightMils = Integer.parseInt(parser.getAttributeValue(null,
+                            ATTR_RIGHT_MILS));
+                    final int bottomMils = Integer.parseInt(parser.getAttributeValue(null,
+                            ATTR_BOTTOM_MILS));
+                    Margins margins = new Margins(leftMils, topMils, rightMils, bottomMils);
+                    builder.setMinMargins(margins);
+                    parser.next();
+                    skipEmptyTextTags(parser);
+                    expect(parser, XmlPullParser.END_TAG, TAG_MARGINS);
+                    parser.next();
+                }
+
+                printJob.setAttributes(builder.build());
+
+                skipEmptyTextTags(parser);
+                expect(parser, XmlPullParser.END_TAG, TAG_ATTRIBUTES);
+                parser.next();
+            }
+
+            skipEmptyTextTags(parser);
+            if (accept(parser, XmlPullParser.START_TAG, TAG_DOCUMENT_INFO)) {
+                String name = parser.getAttributeValue(null, ATTR_NAME);
+                final int pageCount = Integer.parseInt(parser.getAttributeValue(null,
+                        ATTR_PAGE_COUNT));
+                final int contentType = Integer.parseInt(parser.getAttributeValue(null,
+                        ATTR_CONTENT_TYPE));
+                PrintDocumentInfo info = new PrintDocumentInfo.Builder(name)
+                        .setPageCount(pageCount)
+                        .setContentType(contentType).build();
+                printJob.setDocumentInfo(info);
+                parser.next();
+                skipEmptyTextTags(parser);
+                expect(parser, XmlPullParser.END_TAG, TAG_DOCUMENT_INFO);
+                parser.next();
+            }
+
+            mPrintJobs.add(printJob);
+
+            if (DEBUG_PERSISTENCE) {
+                Log.i(LOG_TAG, "[RESTORED] " + printJob);
+            }
+
+            skipEmptyTextTags(parser);
+            expect(parser, XmlPullParser.END_TAG, TAG_JOB);
+
+            return true;
+        }
+
+        private void expect(XmlPullParser parser, int type, String tag)
+                throws IOException, XmlPullParserException {
+            if (!accept(parser, type, tag)) {
+                throw new XmlPullParserException("Exepected event: " + type
+                        + " and tag: " + tag + " but got event: " + parser.getEventType()
+                        + " and tag:" + parser.getName());
+            }
+        }
+
+        private void skipEmptyTextTags(XmlPullParser parser)
+                throws IOException, XmlPullParserException {
+            while (accept(parser, XmlPullParser.TEXT, null)
+                    && "\n".equals(parser.getText())) {
+                parser.next();
+            }
+        }
+
+        private boolean accept(XmlPullParser parser, int type, String tag)
+                throws IOException, XmlPullParserException {
+            if (parser.getEventType() != type) {
+                return false;
+            }
+            if (tag != null) {
+                if (!tag.equals(parser.getName())) {
+                    return false;
+                }
+            } else if (parser.getName() != null) {
+                return false;
+            }
+            return true;
+        }
+    }
+}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/RemotePrintDocumentAdapter.java b/packages/PrintSpooler/src/com/android/printspooler/RemotePrintDocumentAdapter.java
new file mode 100644
index 0000000..fd14af9
--- /dev/null
+++ b/packages/PrintSpooler/src/com/android/printspooler/RemotePrintDocumentAdapter.java
@@ -0,0 +1,140 @@
+/*
+ * 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.printspooler;
+
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.print.ILayoutResultCallback;
+import android.print.IPrintDocumentAdapter;
+import android.print.IWriteResultCallback;
+import android.print.PageRange;
+import android.print.PrintAttributes;
+import android.util.Log;
+
+import libcore.io.IoUtils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * This class represents a remote print document adapter instance.
+ */
+final class RemotePrintDocumentAdapter {
+    private static final String LOG_TAG = "RemotePrintDocumentAdapter";
+
+    private static final boolean DEBUG = false;
+
+    private final IPrintDocumentAdapter mRemoteInterface;
+
+    private final File mFile;
+
+    public RemotePrintDocumentAdapter(IPrintDocumentAdapter printAdatper, File file) {
+        mRemoteInterface = printAdatper;
+        mFile = file;
+    }
+
+    public void start()  {
+        if (DEBUG) {
+            Log.i(LOG_TAG, "start()");
+        }
+        try {
+            mRemoteInterface.start();
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error calling start()", re);
+        }
+    }
+
+    public void layout(PrintAttributes oldAttributes, PrintAttributes newAttributes,
+            ILayoutResultCallback callback, Bundle metadata, int sequence) {
+        if (DEBUG) {
+            Log.i(LOG_TAG, "layout()");
+        }
+        try {
+            mRemoteInterface.layout(oldAttributes, newAttributes, callback, metadata, sequence);
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error calling layout()", re);
+        }
+    }
+
+    public void write(final PageRange[] pages, final IWriteResultCallback callback,
+            final int sequence) {
+        if (DEBUG) {
+            Log.i(LOG_TAG, "write()");
+        }
+        new AsyncTask<Void, Void, Void>() {
+            @Override
+            protected Void doInBackground(Void... params) {
+                InputStream in = null;
+                OutputStream out = null;
+                ParcelFileDescriptor source = null;
+                ParcelFileDescriptor sink = null;
+                try {
+                    ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
+                    source = pipe[0];
+                    sink = pipe[1];
+
+                    in = new FileInputStream(source.getFileDescriptor());
+                    out = new FileOutputStream(mFile);
+
+                    // Async call to initiate the other process writing the data.
+                    mRemoteInterface.write(pages, sink, callback, sequence);
+
+                    // Close the source. It is now held by the client.
+                    sink.close();
+                    sink = null;
+
+                    // Read the data.
+                    final byte[] buffer = new byte[8192];
+                    while (true) {
+                        final int readByteCount = in.read(buffer);
+                        if (readByteCount < 0) {
+                            break;
+                        }
+                        out.write(buffer, 0, readByteCount);
+                    }
+                } catch (RemoteException re) {
+                    Log.e(LOG_TAG, "Error calling write()", re);
+                } catch (IOException ioe) {
+                    Log.e(LOG_TAG, "Error calling write()", ioe);
+                } finally {
+                    IoUtils.closeQuietly(in);
+                    IoUtils.closeQuietly(out);
+                    IoUtils.closeQuietly(sink);
+                    IoUtils.closeQuietly(source);
+                }
+                return null;
+            }
+        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
+    }
+
+    public void finish() {
+        if (DEBUG) {
+            Log.i(LOG_TAG, "finish()");
+        }
+        try {
+            mRemoteInterface.finish();
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error calling finish()", re);
+        }
+    }
+}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/SelectPrinterActivity.java b/packages/PrintSpooler/src/com/android/printspooler/SelectPrinterActivity.java
new file mode 100644
index 0000000..141dbd1
--- /dev/null
+++ b/packages/PrintSpooler/src/com/android/printspooler/SelectPrinterActivity.java
@@ -0,0 +1,41 @@
+/*
+ * 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.printspooler;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.print.PrinterId;
+
+import com.android.printspooler.SelectPrinterFragment.OnPrinterSelectedListener;
+
+public class SelectPrinterActivity extends Activity implements OnPrinterSelectedListener {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.select_printer_activity);
+    }
+
+    @Override
+    public void onPrinterSelected(PrinterId printer) {
+        Intent intent = new Intent();
+        intent.putExtra(PrintJobConfigActivity.INTENT_EXTRA_PRINTER_ID, printer);
+        setResult(RESULT_OK, intent);
+        finish();
+    }
+}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/SelectPrinterFragment.java b/packages/PrintSpooler/src/com/android/printspooler/SelectPrinterFragment.java
new file mode 100644
index 0000000..c397c40
--- /dev/null
+++ b/packages/PrintSpooler/src/com/android/printspooler/SelectPrinterFragment.java
@@ -0,0 +1,422 @@
+/*
+ * 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.printspooler;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.Fragment;
+import android.app.FragmentTransaction;
+import android.app.ListFragment;
+import android.app.LoaderManager;
+import android.content.ActivityNotFoundException;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.Loader;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.net.Uri;
+import android.os.Bundle;
+import android.print.PrintManager;
+import android.print.PrinterId;
+import android.print.PrinterInfo;
+import android.printservice.PrintServiceInfo;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.BaseAdapter;
+import android.widget.Filter;
+import android.widget.Filterable;
+import android.widget.ListView;
+import android.widget.SearchView;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This is a fragment for selecting a printer.
+ */
+public final class SelectPrinterFragment extends ListFragment {
+
+    private static final String LOG_TAG = "SelectPrinterFragment";
+
+    private static final int LOADER_ID_PRINTERS_LOADER = 1;
+
+    private static final String FRAGMRNT_TAG_ADD_PRINTER_DIALOG =
+            "FRAGMRNT_TAG_ADD_PRINTER_DIALOG";
+
+    private static final String FRAGMRNT_ARGUMENT_PRINT_SERVICE_INFOS =
+            "FRAGMRNT_ARGUMENT_PRINT_SERVICE_INFOS";
+
+    private final ArrayList<PrintServiceInfo> mAddPrinterServices =
+            new ArrayList<PrintServiceInfo>();
+
+    public static interface OnPrinterSelectedListener {
+        public void onPrinterSelected(PrinterId printerId);
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setHasOptionsMenu(true);
+    }
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+        setListAdapter(new DestinationAdapter());
+    }
+
+    @Override
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        super.onCreateOptionsMenu(menu, inflater);
+        inflater.inflate(R.menu.select_printer_activity, menu);
+
+        MenuItem searchItem = menu.findItem(R.id.action_search);
+        SearchView searchView = (SearchView) searchItem.getActionView();
+        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
+            @Override
+            public boolean onQueryTextSubmit(String query) {
+                return true;
+            }
+
+            @Override
+            public boolean onQueryTextChange(String searchString) {
+                ((DestinationAdapter) getListAdapter()).getFilter().filter(searchString);
+                return true;
+            }
+        });
+
+        if (mAddPrinterServices.isEmpty()) {
+            menu.removeItem(R.id.action_add_printer);
+        }
+    }
+
+    @Override
+    public void onResume() {
+        updateAddPrintersAdapter();
+        getActivity().invalidateOptionsMenu();
+        super.onResume();
+    }
+
+    @Override
+    public void onListItemClick(ListView list, View view, int position, long id) {
+        PrinterInfo printer = (PrinterInfo) list.getAdapter().getItem(position);
+        Activity activity = getActivity();
+        if (activity instanceof OnPrinterSelectedListener) {
+            ((OnPrinterSelectedListener) activity).onPrinterSelected(printer.getId());
+        } else {
+            throw new IllegalStateException("the host activity must implement"
+                    + " OnPrinterSelectedListener");
+        }
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        if (item.getItemId() == R.id.action_add_printer) {
+            showAddPrinterSelectionDialog();
+            return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    private void updateAddPrintersAdapter() {
+        mAddPrinterServices.clear();
+
+        // Get all enabled print services.
+        PrintManager printManager = (PrintManager) getActivity()
+                .getSystemService(Context.PRINT_SERVICE);
+        List<PrintServiceInfo> enabledServices = printManager.getEnabledPrintServices();
+
+        // No enabled print services - done.
+        if (enabledServices.isEmpty()) {
+            return;
+        }
+
+        // Find the services with valid add printers activities.
+        final int enabledServiceCount = enabledServices.size();
+        for (int i = 0; i < enabledServiceCount; i++) {
+            PrintServiceInfo enabledService = enabledServices.get(i);
+
+            // No add printers activity declared - done.
+            if (TextUtils.isEmpty(enabledService.getAddPrintersActivityName())) {
+                continue;
+            }
+
+            ServiceInfo serviceInfo = enabledService.getResolveInfo().serviceInfo;
+            ComponentName addPrintersComponentName = new ComponentName(
+                    serviceInfo.packageName, enabledService.getAddPrintersActivityName());
+            Intent addPritnersIntent = new Intent()
+                .setComponent(addPrintersComponentName);
+
+            // The add printers activity is valid - add it.
+            PackageManager pm = getActivity().getPackageManager();
+            List<ResolveInfo> resolvedActivities = pm.queryIntentActivities(addPritnersIntent, 0);
+            if (!resolvedActivities.isEmpty()) {
+                // The activity is a component name, therefore it is one or none.
+                ActivityInfo activityInfo = resolvedActivities.get(0).activityInfo;
+                if (activityInfo.exported
+                        && (activityInfo.permission == null
+                                || pm.checkPermission(activityInfo.permission,
+                                        getActivity().getPackageName())
+                                        == PackageManager.PERMISSION_GRANTED)) {
+                    mAddPrinterServices.add(enabledService);
+                }
+            }
+        }
+    }
+
+    private void showAddPrinterSelectionDialog() {
+        FragmentTransaction transaction = getFragmentManager().beginTransaction();
+        Fragment oldFragment = getFragmentManager().findFragmentByTag(
+                FRAGMRNT_TAG_ADD_PRINTER_DIALOG);
+        if (oldFragment != null) {
+            transaction.remove(oldFragment);
+        }
+        AddPrinterAlertDialogFragment newFragment = new AddPrinterAlertDialogFragment();
+        Bundle arguments = new Bundle();
+        arguments.putParcelableArrayList(FRAGMRNT_ARGUMENT_PRINT_SERVICE_INFOS,
+                mAddPrinterServices);
+        newFragment.setArguments(arguments);
+        transaction.add(newFragment, FRAGMRNT_TAG_ADD_PRINTER_DIALOG);
+        transaction.commit();
+    }
+
+    public static class AddPrinterAlertDialogFragment extends DialogFragment {
+
+        private static final String DEFAULT_MARKET_QUERY_STRING =
+                "market://search?q=print";
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public Dialog onCreateDialog(Bundle savedInstanceState) {
+            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
+                    .setTitle(R.string.choose_print_service);
+
+            final List<PrintServiceInfo> printServices = (List<PrintServiceInfo>) (List<?>)
+                    getArguments().getParcelableArrayList(FRAGMRNT_ARGUMENT_PRINT_SERVICE_INFOS);
+
+            ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
+                    android.R.layout.simple_list_item_1);
+            final int printServiceCount = printServices.size();
+            for (int i = 0; i < printServiceCount; i++) {
+                PrintServiceInfo printService = printServices.get(i);
+                adapter.add(printService.getResolveInfo().loadLabel(
+                        getActivity().getPackageManager()).toString());
+            }
+
+            builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
+                @Override
+                public void onClick(DialogInterface dialog, int which) {
+                    PrintServiceInfo printService = printServices.get(which);
+                    ComponentName componentName = new ComponentName(
+                            printService.getResolveInfo().serviceInfo.packageName,
+                            printService.getAddPrintersActivityName());
+                    Intent intent = new Intent(Intent.ACTION_MAIN);
+                    intent.setComponent(componentName);
+                    try {
+                        startActivity(intent);
+                    } catch (ActivityNotFoundException anfe) {
+                        Log.w(LOG_TAG, "Couldn't start settings activity", anfe);
+                    }
+                }
+            });
+
+            Uri marketUri = Uri.parse(DEFAULT_MARKET_QUERY_STRING);
+            final Intent marketIntent = new Intent(Intent.ACTION_VIEW, marketUri);
+            if (getActivity().getPackageManager().resolveActivity(marketIntent, 0) != null) {
+                builder.setPositiveButton(R.string.search_play_store,
+                    new DialogInterface.OnClickListener() {
+                        public void onClick(DialogInterface dialog, int whichButton) {
+                            try {
+                                startActivity(marketIntent);
+                            } catch (ActivityNotFoundException anfe) {
+                                Log.w(LOG_TAG, "Couldn't start add printer activity", anfe);
+                            }
+                        }
+                    });
+            }
+
+            return builder.create();
+        }
+    }
+
+    private final class DestinationAdapter extends BaseAdapter
+            implements LoaderManager.LoaderCallbacks<List<PrinterInfo>>, Filterable {
+
+        private final Object mLock = new Object();
+
+        private final List<PrinterInfo> mPrinters = new ArrayList<PrinterInfo>();
+
+        private final List<PrinterInfo> mFilteredPrinters = new ArrayList<PrinterInfo>();
+
+        private CharSequence mLastSearchString;
+
+        public DestinationAdapter() {
+            getLoaderManager().initLoader(LOADER_ID_PRINTERS_LOADER, null, this);
+        }
+
+        @Override
+        public Filter getFilter() {
+            return new Filter() {
+                @Override
+                protected FilterResults performFiltering(CharSequence constraint) {
+                    synchronized (mLock) {
+                        if (TextUtils.isEmpty(constraint)) {
+                            return null;
+                        }
+                        FilterResults results = new FilterResults();
+                        List<PrinterInfo> filteredPrinters = new ArrayList<PrinterInfo>();
+                        String constraintLowerCase = constraint.toString().toLowerCase();
+                        final int printerCount = mPrinters.size();
+                        for (int i = 0; i < printerCount; i++) {
+                            PrinterInfo printer = mPrinters.get(i);
+                            if (printer.getName().toLowerCase().contains(constraintLowerCase)) {
+                                filteredPrinters.add(printer);
+                            }
+                        }
+                        results.values = filteredPrinters;
+                        results.count = filteredPrinters.size();
+                        return results;
+                    }
+                }
+
+                @Override
+                @SuppressWarnings("unchecked")
+                protected void publishResults(CharSequence constraint, FilterResults results) {
+                    synchronized (mLock) {
+                        mLastSearchString = constraint;
+                        mFilteredPrinters.clear();
+                        if (results == null) {
+                            mFilteredPrinters.addAll(mPrinters);
+                        } else {
+                            List<PrinterInfo> printers = (List<PrinterInfo>) results.values;
+                            mFilteredPrinters.addAll(printers);
+                        }
+                    }
+                    notifyDataSetChanged();
+                }
+            };
+        }
+
+        @Override
+        public int getCount() {
+            synchronized (mLock) {
+                return mFilteredPrinters.size();
+            }
+        }
+
+        @Override
+        public Object getItem(int position) {
+            synchronized (mLock) {
+                return mFilteredPrinters.get(position);
+            }
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return position;
+        }
+
+        @Override
+        public View getDropDownView(int position, View convertView,
+                ViewGroup parent) {
+            return getView(position, convertView, parent);
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            if (convertView == null) {
+                convertView = getActivity().getLayoutInflater().inflate(
+                        R.layout.spinner_dropdown_item, parent, false);
+            }
+
+            CharSequence title = null;
+            CharSequence subtitle = null;
+
+            PrinterInfo printer = (PrinterInfo) getItem(position);
+            title = printer.getName();
+            try {
+                PackageManager pm = getActivity().getPackageManager();
+                PackageInfo packageInfo = pm.getPackageInfo(printer.getId()
+                        .getServiceName().getPackageName(), 0);
+                subtitle = packageInfo.applicationInfo.loadLabel(pm);
+            } catch (NameNotFoundException nnfe) {
+                /* ignore */
+            }
+
+            TextView titleView = (TextView) convertView.findViewById(R.id.title);
+            titleView.setText(title);
+
+            TextView subtitleView = (TextView) convertView.findViewById(R.id.subtitle);
+            if (!TextUtils.isEmpty(subtitle)) {
+                subtitleView.setText(subtitle);
+                subtitleView.setVisibility(View.VISIBLE);
+            } else {
+                subtitleView.setText(null);
+                subtitleView.setVisibility(View.GONE);
+            }
+
+            return convertView;
+        }
+
+        @Override
+        public Loader<List<PrinterInfo>> onCreateLoader(int id, Bundle args) {
+            if (id == LOADER_ID_PRINTERS_LOADER) {
+                return new FusedPrintersProvider(getActivity());
+            }
+            return null;
+        }
+
+        @Override
+        public void onLoadFinished(Loader<List<PrinterInfo>> loader,
+                List<PrinterInfo> printers) {
+            synchronized (mLock) {
+                mPrinters.clear();
+                mPrinters.addAll(printers);
+                mFilteredPrinters.clear();
+                mFilteredPrinters.addAll(printers);
+                if (!TextUtils.isEmpty(mLastSearchString)) {
+                    getFilter().filter(mLastSearchString);
+                }
+            }
+            notifyDataSetChanged();
+        }
+
+        @Override
+        public void onLoaderReset(Loader<List<PrinterInfo>> loader) {
+            synchronized (mLock) {
+                mPrinters.clear();
+                mFilteredPrinters.clear();
+            }
+            notifyDataSetInvalidated();
+        }
+    }
+}
diff --git a/packages/SettingsProvider/Android.mk b/packages/SettingsProvider/Android.mk
index a2ea554..da929ae 100644
--- a/packages/SettingsProvider/Android.mk
+++ b/packages/SettingsProvider/Android.mk
@@ -9,6 +9,7 @@
 
 LOCAL_PACKAGE_NAME := SettingsProvider
 LOCAL_CERTIFICATE := platform
+LOCAL_PRIVILEGED_MODULE := true
 
 include $(BUILD_PACKAGE)
 
diff --git a/packages/SettingsProvider/res/values-en-rIN/strings.xml b/packages/SettingsProvider/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..c19fdd7
--- /dev/null
+++ b/packages/SettingsProvider/res/values-en-rIN/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="4567566098528588863">"Settings Storage"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-et-rEE/strings.xml b/packages/SettingsProvider/res/values-et-rEE/strings.xml
new file mode 100644
index 0000000..30b7293
--- /dev/null
+++ b/packages/SettingsProvider/res/values-et-rEE/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="4567566098528588863">"Seadete talletusruum"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-fr-rCA/strings.xml b/packages/SettingsProvider/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..c90eb09
--- /dev/null
+++ b/packages/SettingsProvider/res/values-fr-rCA/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="4567566098528588863">"Stockage des paramètres"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-hy-rAM/strings.xml b/packages/SettingsProvider/res/values-hy-rAM/strings.xml
new file mode 100644
index 0000000..b1f1afb
--- /dev/null
+++ b/packages/SettingsProvider/res/values-hy-rAM/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="4567566098528588863">"Կարգավորումների պահուստ"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-ka-rGE/strings.xml b/packages/SettingsProvider/res/values-ka-rGE/strings.xml
new file mode 100644
index 0000000..691a2e9
--- /dev/null
+++ b/packages/SettingsProvider/res/values-ka-rGE/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="4567566098528588863">"პარამეტრების საცავი"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-km-rKH/strings.xml b/packages/SettingsProvider/res/values-km-rKH/strings.xml
new file mode 100644
index 0000000..7be6242
--- /dev/null
+++ b/packages/SettingsProvider/res/values-km-rKH/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="4567566098528588863">"កំណត់​ការ​ផ្ទុក"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-lo-rLA/strings.xml b/packages/SettingsProvider/res/values-lo-rLA/strings.xml
new file mode 100644
index 0000000..4e57936
--- /dev/null
+++ b/packages/SettingsProvider/res/values-lo-rLA/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="4567566098528588863">"ບ່ອນເກັບຂໍ້ມູນການຕັ້ງຄ່າ"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-mn-rMN/strings.xml b/packages/SettingsProvider/res/values-mn-rMN/strings.xml
new file mode 100644
index 0000000..9452145
--- /dev/null
+++ b/packages/SettingsProvider/res/values-mn-rMN/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="4567566098528588863">"Тохиргооны Сан"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-ms-rMY/strings.xml b/packages/SettingsProvider/res/values-ms-rMY/strings.xml
new file mode 100644
index 0000000..9108b07
--- /dev/null
+++ b/packages/SettingsProvider/res/values-ms-rMY/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="4567566098528588863">"Storan Tetapan"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-zh-rHK/strings.xml b/packages/SettingsProvider/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..977c9b9
--- /dev/null
+++ b/packages/SettingsProvider/res/values-zh-rHK/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="4567566098528588863">"設定儲存空間"</string>
+</resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index 3f04470..7b09092 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -137,6 +137,7 @@
     static class Network {
         String ssid = "";  // equals() and hashCode() need these to be non-null
         String key_mgmt = "";
+        boolean certUsed = false;
         final ArrayList<String> rawLines = new ArrayList<String>();
 
         public static Network readFromStream(BufferedReader in) {
@@ -167,6 +168,12 @@
                 ssid = line;
             } else if (line.startsWith("key_mgmt")) {
                 key_mgmt = line;
+            } else if (line.startsWith("client_cert=")) {
+                certUsed = true;
+            } else if (line.startsWith("ca_cert=")) {
+                certUsed = true;
+            } else if (line.startsWith("ca_path=")) {
+                certUsed = true;
             }
         }
 
@@ -246,6 +253,13 @@
 
         public void write(Writer w) throws IOException {
             for (Network net : mNetworks) {
+                if (net.certUsed) {
+                    // Networks that use certificates for authentication can't be restored
+                    // because the certificates they need don't get restored (because they
+                    // are stored in keystore, and can't be restored)
+                    continue;
+                }
+
                 net.write(w);
             }
         }
@@ -738,10 +752,12 @@
                 }
             }
 
+            // Intercept the keys and see if they need special handling
+            value = mSettingsHelper.onBackupValue(key, value);
+
             if (value == null) {
                 continue;
             }
-
             // Write the key and value in the intermediary array.
             byte[] keyBytes = key.getBytes();
             totalSize += INTEGER_BYTE_COUNT + keyBytes.length;
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index a446e40..dd7a828 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -23,6 +23,8 @@
 import android.content.res.Configuration;
 import android.location.LocationManager;
 import android.media.AudioManager;
+import android.media.RingtoneManager;
+import android.net.Uri;
 import android.os.IPowerManager;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -33,6 +35,7 @@
 import java.util.Locale;
 
 public class SettingsHelper {
+    private static final String SILENT_RINGTONE = "_silent";
     private Context mContext;
     private AudioManager mAudioManager;
 
@@ -63,10 +66,60 @@
             setAutoRestore(Integer.parseInt(value) == 1);
         } else if (isAlreadyConfiguredCriticalAccessibilitySetting(name)) {
             return false;
+        } else if (Settings.System.RINGTONE.equals(name)
+                || Settings.System.NOTIFICATION_SOUND.equals(name)) {
+            setRingtone(name, value);
+            return false;
         }
         return true;
     }
 
+    public String onBackupValue(String name, String value) {
+        // Special processing for backing up ringtones
+        if (Settings.System.RINGTONE.equals(name)
+                || Settings.System.NOTIFICATION_SOUND.equals(name)) {
+            if (value == null) {
+                // Silent ringtone
+                return SILENT_RINGTONE;
+            } else {
+                return getCanonicalRingtoneValue(value);
+            }
+        }
+        // Return the original value
+        return value;
+    }
+
+    /**
+     * Sets the ringtone of type specified by the name.
+     *
+     * @param name should be Settings.System.RINGTONE or Settings.System.NOTIFICATION_SOUND.
+     * @param value can be a canonicalized uri or "_silent" to indicate a silent (null) ringtone.
+     */
+    private void setRingtone(String name, String value) {
+        // If it's null, don't change the default
+        if (value == null) return;
+        Uri ringtoneUri = null;
+        if (SILENT_RINGTONE.equals(value)) {
+            ringtoneUri = null;
+        } else {
+            Uri canonicalUri = Uri.parse(value);
+            ringtoneUri = mContext.getContentResolver().uncanonicalize(canonicalUri);
+            if (ringtoneUri == null) {
+                // Unrecognized or invalid Uri, don't restore
+                return;
+            }
+        }
+        final int ringtoneType = Settings.System.RINGTONE.equals(name)
+                ? RingtoneManager.TYPE_RINGTONE : RingtoneManager.TYPE_NOTIFICATION;
+        RingtoneManager.setActualDefaultRingtoneUri(mContext, ringtoneType, ringtoneUri);
+    }
+
+    private String getCanonicalRingtoneValue(String value) {
+        final Uri ringtoneUri = Uri.parse(value);
+        final Uri canonicalUri = mContext.getContentResolver().canonicalize(ringtoneUri);
+        return canonicalUri == null ? null : canonicalUri.toString();
+    }
+
     private boolean isAlreadyConfiguredCriticalAccessibilitySetting(String name) {
         // These are the critical accessibility settings that are required for a
         // blind user to be able to interact with the device. If these settings are
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 0177504..bc02b0d 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -33,6 +33,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
 import android.content.res.AssetFileDescriptor;
 import android.database.AbstractCursor;
 import android.database.Cursor;
@@ -49,7 +50,6 @@
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.provider.DrmStore;
 import android.provider.MediaStore;
 import android.provider.Settings;
 import android.text.TextUtils;
@@ -478,6 +478,13 @@
         try {
             final String value = c.moveToNext() ? c.getString(0) : null;
             if (value == null) {
+                // sanity-check the user before touching the db
+                final UserInfo user = mUserManager.getUserInfo(userHandle);
+                if (user == null) {
+                    // can happen due to races when deleting users; treat as benign
+                    return false;
+                }
+
                 final SecureRandom random = new SecureRandom();
                 final String newAndroidIdValue = Long.toHexString(random.nextLong());
                 final ContentValues values = new ContentValues();
@@ -491,7 +498,7 @@
                 Slog.d(TAG, "Generated and saved new ANDROID_ID [" + newAndroidIdValue
                         + "] for user " + userHandle);
                 // Write a dropbox entry if it's a restricted profile
-                if (mUserManager.getUserInfo(userHandle).isRestricted()) {
+                if (user.isRestricted()) {
                     DropBoxManager dbm = (DropBoxManager)
                             getContext().getSystemService(Context.DROPBOX_SERVICE);
                     if (dbm != null && dbm.isTagEnabled(DROPBOX_TAG_USERLOG)) {
@@ -560,8 +567,7 @@
      * Fast path that avoids the use of chatty remoted Cursors.
      */
     @Override
-    public Bundle callFromPackage(String callingPackage, String method, String request,
-            Bundle args) {
+    public Bundle call(String method, String request, Bundle args) {
         int callingUser = UserHandle.getCallingUserId();
         if (args != null) {
             int reqUser = args.getInt(Settings.CALL_METHOD_USER_KEY, callingUser);
@@ -616,7 +622,7 @@
 
         // Also need to take care of app op.
         if (getAppOpsManager().noteOp(AppOpsManager.OP_WRITE_SETTINGS, Binder.getCallingUid(),
-                callingPackage) != AppOpsManager.MODE_ALLOWED) {
+                getCallingPackage()) != AppOpsManager.MODE_ALLOWED) {
             return null;
         }
 
@@ -992,7 +998,7 @@
         /*
          * When a client attempts to openFile the default ringtone or
          * notification setting Uri, we will proxy the call to the current
-         * default ringtone's Uri (if it is in the DRM or media provider).
+         * default ringtone's Uri (if it is in the media provider).
          */
         int ringtoneType = RingtoneManager.getDefaultType(uri);
         // Above call returns -1 if the Uri doesn't match a default type
@@ -1003,22 +1009,9 @@
             Uri soundUri = RingtoneManager.getActualDefaultRingtoneUri(context, ringtoneType);
 
             if (soundUri != null) {
-                // Only proxy the openFile call to drm or media providers
+                // Proxy the openFile call to media provider
                 String authority = soundUri.getAuthority();
-                boolean isDrmAuthority = authority.equals(DrmStore.AUTHORITY);
-                if (isDrmAuthority || authority.equals(MediaStore.AUTHORITY)) {
-
-                    if (isDrmAuthority) {
-                        try {
-                            // Check DRM access permission here, since once we
-                            // do the below call the DRM will be checking our
-                            // permission, not our caller's permission
-                            DrmStore.enforceAccessDrmPermission(context);
-                        } catch (SecurityException e) {
-                            throw new FileNotFoundException(e.getMessage());
-                        }
-                    }
-
+                if (authority.equals(MediaStore.AUTHORITY)) {
                     return context.getContentResolver().openFileDescriptor(soundUri, mode);
                 }
             }
@@ -1033,7 +1026,7 @@
         /*
          * When a client attempts to openFile the default ringtone or
          * notification setting Uri, we will proxy the call to the current
-         * default ringtone's Uri (if it is in the DRM or media provider).
+         * default ringtone's Uri (if it is in the media provider).
          */
         int ringtoneType = RingtoneManager.getDefaultType(uri);
         // Above call returns -1 if the Uri doesn't match a default type
@@ -1044,22 +1037,9 @@
             Uri soundUri = RingtoneManager.getActualDefaultRingtoneUri(context, ringtoneType);
 
             if (soundUri != null) {
-                // Only proxy the openFile call to drm or media providers
+                // Proxy the openFile call to media provider
                 String authority = soundUri.getAuthority();
-                boolean isDrmAuthority = authority.equals(DrmStore.AUTHORITY);
-                if (isDrmAuthority || authority.equals(MediaStore.AUTHORITY)) {
-
-                    if (isDrmAuthority) {
-                        try {
-                            // Check DRM access permission here, since once we
-                            // do the below call the DRM will be checking our
-                            // permission, not our caller's permission
-                            DrmStore.enforceAccessDrmPermission(context);
-                        } catch (SecurityException e) {
-                            throw new FileNotFoundException(e.getMessage());
-                        }
-                    }
-
+                if (authority.equals(MediaStore.AUTHORITY)) {
                     ParcelFileDescriptor pfd = null;
                     try {
                         pfd = context.getContentResolver().openFileDescriptor(soundUri, mode);
diff --git a/packages/SharedStorageBackup/Android.mk b/packages/SharedStorageBackup/Android.mk
index 1d4f4da7..a213965f 100644
--- a/packages/SharedStorageBackup/Android.mk
+++ b/packages/SharedStorageBackup/Android.mk
@@ -25,6 +25,7 @@
 
 LOCAL_PACKAGE_NAME := SharedStorageBackup
 LOCAL_CERTIFICATE := platform
+LOCAL_PRIVILEGED_MODULE := true
 
 include $(BUILD_PACKAGE)
 
diff --git a/packages/SharedStorageBackup/src/com/android/sharedstoragebackup/ObbBackupService.java b/packages/SharedStorageBackup/src/com/android/sharedstoragebackup/ObbBackupService.java
index 7ebe096..0485334 100644
--- a/packages/SharedStorageBackup/src/com/android/sharedstoragebackup/ObbBackupService.java
+++ b/packages/SharedStorageBackup/src/com/android/sharedstoragebackup/ObbBackupService.java
@@ -57,7 +57,7 @@
                 int token, IBackupManager callbackBinder) {
             final FileDescriptor outFd = data.getFileDescriptor();
             try {
-                File obbDir = Environment.getExternalStorageAppObbDirectory(packageName);
+                File obbDir = Environment.buildExternalStorageAppObbDirs(packageName)[0];
                 if (obbDir != null) {
                     if (obbDir.exists()) {
                         ArrayList<File> obbList = allFileContents(obbDir);
@@ -106,7 +106,7 @@
                 long fileSize, int type, String path, long mode, long mtime,
                 int token, IBackupManager callbackBinder) {
             try {
-                File outFile = Environment.getExternalStorageAppObbDirectory(packageName);
+                File outFile = Environment.buildExternalStorageAppObbDirs(packageName)[0];
                 if (outFile != null) {
                     outFile = new File(outFile, path);
                 }
diff --git a/packages/Shell/Android.mk b/packages/Shell/Android.mk
index fc4c0f5..5bd48c6 100644
--- a/packages/Shell/Android.mk
+++ b/packages/Shell/Android.mk
@@ -9,5 +9,6 @@
 
 LOCAL_PACKAGE_NAME := Shell
 LOCAL_CERTIFICATE := platform
+LOCAL_PRIVILEGED_MODULE := true
 
 include $(BUILD_PACKAGE)
diff --git a/packages/Shell/res/values-af/strings.xml b/packages/Shell/res/values-af/strings.xml
new file mode 100644
index 0000000..3dc6a0f
--- /dev/null
+++ b/packages/Shell/res/values-af/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Tuisskerm"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Foutverslag vasgevang"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Raak om jou foutverslag te deel"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Foutverslae bevat data van die stelsel se verskillende loglêers af, insluitend persoonlike en private inligting. Deel foutverslae net met programme en mense wat jy vertrou."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Wys hierdie boodskap volgende keer"</string>
+</resources>
diff --git a/packages/Shell/res/values-am/strings.xml b/packages/Shell/res/values-am/strings.xml
new file mode 100644
index 0000000..c90a5f5
--- /dev/null
+++ b/packages/Shell/res/values-am/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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_finished_title" msgid="2293711546892863898">"የሳንካ ሪፖርት ተይዟል"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"የሳንካ ሪፖርትዎን ለማጋራት ይንክኩ"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"የሳንካ ሪፖርቶች የግል መረጃን ጨምሮ ከበርካታ የስርዓቱ ምዝግብ ማስታወሻዎች የመጣ ውሂብን ይዟል። የሳንካ ሪፖርቶች ለሚያምኗቸው መተግበሪያዎችን እና ሰዎችን ብቻ ያጋሩ።"</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"ይህን መልዕክት በሚቀጥለው ጊዜ አሳይ"</string>
+</resources>
diff --git a/packages/Shell/res/values-ar/strings.xml b/packages/Shell/res/values-ar/strings.xml
new file mode 100644
index 0000000..6a595d5
--- /dev/null
+++ b/packages/Shell/res/values-ar/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Shell"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"تم الحصول على تقرير الأخطاء"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"المس لمشاركة تقرير الأخطاء"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"تحتوي تقارير الأخطاء على بيانات من ملفات سجلات النظام المتنوعة، بما في ذلك معلومات شخصية وخاصة. لا تشارك تقارير الأخطاء إلا مع التطبيقات والأشخاص الموثوق بهم."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"إظهار هذه الرسالة في المرة القادمة"</string>
+</resources>
diff --git a/packages/Shell/res/values-be/strings.xml b/packages/Shell/res/values-be/strings.xml
new file mode 100644
index 0000000..e713975
--- /dev/null
+++ b/packages/Shell/res/values-be/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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_finished_title" msgid="2293711546892863898">"Справаздача пра збой захавана"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Націсніце, каб падзяліцца сваёй справаздачай пра збой"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Справаздача пра памылку ўтрымлівае дадзеныя з гiсторыi сістэмных файлаў, у тым ліку персанальную і прыватную інфармацыю. Дзялiцеся справаздачамi пра збоi толькi з праверанымi карыстальнiкамi i прыкладаннямi."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"У наступны раз паказваць гэта паведамленне"</string>
+</resources>
diff --git a/packages/Shell/res/values-bg/strings.xml b/packages/Shell/res/values-bg/strings.xml
new file mode 100644
index 0000000..2fae953
--- /dev/null
+++ b/packages/Shell/res/values-bg/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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_finished_title" msgid="2293711546892863898">"Отчетът за програмни грешки е записан"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Докоснете, за да споделите отчета си за програмни грешки"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Отчетите за програмни грешки съдържат данни от различни регистрационни файлове на системата, включително лична и поверителна информация. Споделяйте ги само с приложения и хора, на които имате доверие."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Това съобщение да се показва следващия път"</string>
+</resources>
diff --git a/packages/Shell/res/values-ca/strings.xml b/packages/Shell/res/values-ca/strings.xml
new file mode 100644
index 0000000..8bf368a
--- /dev/null
+++ b/packages/Shell/res/values-ca/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Protecció"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"S\'ha registrat l\'informe d\'error"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Toca aquí per compartir el teu informe d\'error."</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Els informes d\'error contenen dades dels diferents fitxers de registre del sistema, inclosa informació privada i personal. Comparteix els informes d\'error només amb les aplicacions i amb les persones en qui confies."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Mostra aquest missatge la propera vegada"</string>
+</resources>
diff --git a/packages/Shell/res/values-cs/strings.xml b/packages/Shell/res/values-cs/strings.xml
new file mode 100644
index 0000000..577f69c
--- /dev/null
+++ b/packages/Shell/res/values-cs/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Prostředí"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Byla vytvořena zpráva o chybě"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Zprávu o chybě můžete sdílet klepnutím."</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Chybová hlášení obsahují data z různých souborů protokolů systému včetně osobních a soukromých informací. Chybová hlášení sdílejte pouze s aplikacemi a uživateli, kterým důvěřujete."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Zobrazit tuto zprávu příště"</string>
+</resources>
diff --git a/packages/Shell/res/values-da/strings.xml b/packages/Shell/res/values-da/strings.xml
new file mode 100644
index 0000000..01ea42b
--- /dev/null
+++ b/packages/Shell/res/values-da/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Shell"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Fejlrapporten er registreret"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Tryk for at dele din fejlrapport"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Fejlrapporter indeholder data fra systemets forskellige logfiler, herunder personlige og private oplysninger. Del kun fejlrapporter med apps og personer, du har tillid til."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Vis denne meddelelse næste gang"</string>
+</resources>
diff --git a/packages/Shell/res/values-de/strings.xml b/packages/Shell/res/values-de/strings.xml
new file mode 100644
index 0000000..99522b1
--- /dev/null
+++ b/packages/Shell/res/values-de/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Shell"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Fehlerbericht erfasst"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Berühren, um Fehlerbericht zu teilen"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Fehlerberichte enthalten Daten aus verschiedenen Protokolldateien des Systems, darunter auch personenbezogene und private Daten. Teilen Sie Fehlerberichte nur mit Apps und Personen, denen Sie vertrauen."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Diese Nachricht nächstes Mal zeigen"</string>
+</resources>
diff --git a/packages/Shell/res/values-el/strings.xml b/packages/Shell/res/values-el/strings.xml
new file mode 100644
index 0000000..3669f78
--- /dev/null
+++ b/packages/Shell/res/values-el/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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_finished_title" msgid="2293711546892863898">"Η λήψη της αναφοράς ήταν επιτυχής"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Αγγίξτε για κοινή χρήση της αναφοράς σας σφαλμάτων"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Οι αναφορές σφαλμάτων περιέχουν δεδομένα από τα διάφορα αρχεία καταγραφής του συστήματος, συμπεριλαμβανομένων προσωπικών και ιδιωτικών πληροφοριών. Να μοιράζεστε αναφορές σφαλμάτων μόνο με εφαρμογές και άτομα που εμπιστεύεστε."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Εμφάνιση αυτού του μηνύματος την επόμενη φορά"</string>
+</resources>
diff --git a/packages/Shell/res/values-en-rGB/strings.xml b/packages/Shell/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..68708e0
--- /dev/null
+++ b/packages/Shell/res/values-en-rGB/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Shell"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Bug report captured"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Touch to share your bug report"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Bug reports contain data from the system\'s various log files, including personal and private information. Only share bug reports with apps and people that you trust."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Show this message next time"</string>
+</resources>
diff --git a/packages/Shell/res/values-en-rIN/strings.xml b/packages/Shell/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..68708e0
--- /dev/null
+++ b/packages/Shell/res/values-en-rIN/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Shell"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Bug report captured"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Touch to share your bug report"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Bug reports contain data from the system\'s various log files, including personal and private information. Only share bug reports with apps and people that you trust."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Show this message next time"</string>
+</resources>
diff --git a/packages/Shell/res/values-es-rUS/strings.xml b/packages/Shell/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..f1ec75c
--- /dev/null
+++ b/packages/Shell/res/values-es-rUS/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Shell"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Informe de errores capturado"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Toca para compartir tu informe de errores."</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Los informes de errores contienen datos de los distintos archivos de registro del sistema, incluida la información personal y privada. Comparte los informes de errores únicamente con aplicaciones y personas en las que confíes."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Mostrar este mensaje la próxima vez"</string>
+</resources>
diff --git a/packages/Shell/res/values-es/strings.xml b/packages/Shell/res/values-es/strings.xml
new file mode 100644
index 0000000..7990672
--- /dev/null
+++ b/packages/Shell/res/values-es/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Shell"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Informe de error capturado"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Toca para compartir tu informe de error"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Los informes de errores contienen datos de los distintos archivos de registro del sistema, incluida información personal y privada. Comparte los informes de errores únicamente con aplicaciones y usuarios en los que confíes."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Mostrar este mensaje la próxima vez"</string>
+</resources>
diff --git a/packages/Shell/res/values-et-rEE/strings.xml b/packages/Shell/res/values-et-rEE/strings.xml
new file mode 100644
index 0000000..7788158
--- /dev/null
+++ b/packages/Shell/res/values-et-rEE/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Kest"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Veaaruanne jäädvustati"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Veaaruande jagamiseks puudutage"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Veaaruanded sisaldavad andmeid erinevatest süsteemi logifailidest, sh isiklikku ja privaatset teavet. Jagage veaaruandeid ainult usaldusväärsete rakenduste ja inimestega."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Kuva see sõnum järgmisel korral"</string>
+</resources>
diff --git a/packages/Shell/res/values-et/strings.xml b/packages/Shell/res/values-et/strings.xml
new file mode 100644
index 0000000..7788158
--- /dev/null
+++ b/packages/Shell/res/values-et/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Kest"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Veaaruanne jäädvustati"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Veaaruande jagamiseks puudutage"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Veaaruanded sisaldavad andmeid erinevatest süsteemi logifailidest, sh isiklikku ja privaatset teavet. Jagage veaaruandeid ainult usaldusväärsete rakenduste ja inimestega."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Kuva see sõnum järgmisel korral"</string>
+</resources>
diff --git a/packages/Shell/res/values-fa/strings.xml b/packages/Shell/res/values-fa/strings.xml
new file mode 100644
index 0000000..2d2c223
--- /dev/null
+++ b/packages/Shell/res/values-fa/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Shell"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"گزارش اشکال دریافت شد"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"جهت اشتراک‌گذاری گزارش اشکال خود لمس کنید"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"گزارش‌های اشکال حاوی داده‌هایی از فایل‌های گزارش مختلف در سیستم هستند، شامل اطلاعات شخصی و خصوصی. گزارش‌های اشکال را فقط با افراد و برنامه‌های مورد اعتماد خود به اشتراک بگذارید."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"دفعه بعد این پیام نشان داده شود"</string>
+</resources>
diff --git a/packages/Shell/res/values-fi/strings.xml b/packages/Shell/res/values-fi/strings.xml
new file mode 100644
index 0000000..ee57279
--- /dev/null
+++ b/packages/Shell/res/values-fi/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Komentotulkki"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Virheraportti tallennettu"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Jaa virheraportti koskettamalla tätä"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Virheraportit sisältävät järjestelmän lokitietoja, ja niihin voi sisältyä henkilökohtaisia ja yksityisiä tietoja. Jaa virheraportteja vain luotettaville sovelluksille ja käyttäjille."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Näytä tämä viesti seuraavalla kerralla"</string>
+</resources>
diff --git a/packages/Shell/res/values-fr-rCA/strings.xml b/packages/Shell/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..c672f23
--- /dev/null
+++ b/packages/Shell/res/values-fr-rCA/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Shell"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Rapport de bogue enregistré"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Appuyer ici pour partager votre rapport de bogue"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Les rapports de bogue contiennent des données des fichiers journaux du système, y compris des informations personnelles et privées. Ne partagez les rapports de bogue qu\'avec les applications et les personnes que vous estimez fiables."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Afficher ce message la prochaine fois"</string>
+</resources>
diff --git a/packages/Shell/res/values-fr/strings.xml b/packages/Shell/res/values-fr/strings.xml
new file mode 100644
index 0000000..1da6f1f
--- /dev/null
+++ b/packages/Shell/res/values-fr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Shell"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Rapport de bug enregistré"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Appuyer ici pour partager votre rapport de bug"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Les rapports de bug contiennent des données des fichiers journaux du système, y compris des informations personnelles et privées. Ne partagez les rapports de bug qu\'avec les applications et les personnes que vous estimez fiables."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Afficher ce message la prochaine fois"</string>
+</resources>
diff --git a/packages/Shell/res/values-hi/strings.xml b/packages/Shell/res/values-hi/strings.xml
new file mode 100644
index 0000000..7e73c79
--- /dev/null
+++ b/packages/Shell/res/values-hi/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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_finished_title" msgid="2293711546892863898">"बग रिपोर्ट कैप्चर कर ली गई"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"अपनी बग रिपोर्ट साझा करने के लिए स्पर्श करें"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"बग रिपोर्ट में व्यक्तिगत और निजी जानकारी सहित, सिस्टम की विभिन्न लॉग फ़ाइलों का डेटा होता है. बग रिपोर्ट केवल विश्वसनीय एप्स और व्यक्तियों से ही साझा करें."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"यह संदेश अगली बार दिखाएं"</string>
+</resources>
diff --git a/packages/Shell/res/values-hr/strings.xml b/packages/Shell/res/values-hr/strings.xml
new file mode 100644
index 0000000..2c4ea23
--- /dev/null
+++ b/packages/Shell/res/values-hr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Ljuska"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Prijava programske pogreške snimljena je"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Dodirnite za dijeljenje prijave programske pogreške"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Prijave programskih pogrešaka sadržavaju podatke iz različitih datoteka zapisnika sustava, uključujući osobne i privatne informacije. Prijave programskih pogrešaka dijelite samo s aplikacijama i osobama koje smatrate pouzdanima."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Prikaži tu poruku sljedeći put"</string>
+</resources>
diff --git a/packages/Shell/res/values-hu/strings.xml b/packages/Shell/res/values-hu/strings.xml
new file mode 100644
index 0000000..8d684da
--- /dev/null
+++ b/packages/Shell/res/values-hu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Héj"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Programhiba-jelentés rögzítve"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Érintse meg a programhiba-jelentés megosztásához"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"A programhiba-jelentések a rendszer különféle naplófájljaiból származó adatokat tartalmaznak, köztük személyes és magánjellegű információkat is. Csak olyan alkalmazásokkal és személyekkel osszon meg programhiba-jelentéseket, amelyekben vagy akikben megbízik."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Üzenet mutatása legközelebb"</string>
+</resources>
diff --git a/packages/Shell/res/values-hy-rAM/strings.xml b/packages/Shell/res/values-hy-rAM/strings.xml
new file mode 100644
index 0000000..ea7fa9f
--- /dev/null
+++ b/packages/Shell/res/values-hy-rAM/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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_finished_title" msgid="2293711546892863898">"Վրիպակի զեկույց ստացվեց"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Հպեք` ձեր վրիպակի մասին զեկույցը տարածելու համար"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Վրիպակի զեկույցները պարունակում են տվյալներ համակարգի տարբեր մուտքի ֆայլերից, այդ թվում նաև անհատական ​​և գաղտնի տեղեկություններ: Վրիպակի զեկույցները կիսեք միայն այն հավելվածների և մարդկանց հետ, որոնց վստահում եք:"</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Այս հաղորդագրությունը ցույց տալ հաջորդ անգամ"</string>
+</resources>
diff --git a/packages/Shell/res/values-in/strings.xml b/packages/Shell/res/values-in/strings.xml
new file mode 100644
index 0000000..8ea2584
--- /dev/null
+++ b/packages/Shell/res/values-in/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Kerangka"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Laporan bug tercatat"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Sentuh untuk membagikan laporan bug Anda"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Laporan bug berisi data dari berbagai file log sistem, termasuk informasi pribadi dan rahasia. Hanya bagikan laporan bug dengan aplikasi dan orang yang Anda percaya."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Tampilkan pesan ini lain kali"</string>
+</resources>
diff --git a/packages/Shell/res/values-it/strings.xml b/packages/Shell/res/values-it/strings.xml
new file mode 100644
index 0000000..18a03fe
--- /dev/null
+++ b/packages/Shell/res/values-it/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Shell"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Segnalazione di bug acquisita"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Tocca per condividere la segnalazione di bug"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Le segnalazioni di bug contengono dati da vari file di log del sistema, incluse informazioni personali e private. Condividi le segnalazioni di bug solo con app e persone attendibili."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Mostra questo messaggio la prossima volta"</string>
+</resources>
diff --git a/packages/Shell/res/values-iw/strings.xml b/packages/Shell/res/values-iw/strings.xml
new file mode 100644
index 0000000..e7715e9
--- /dev/null
+++ b/packages/Shell/res/values-iw/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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_finished_title" msgid="2293711546892863898">"דוח הבאגים צולם"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"גע כדי לשתף את דוח הבאגים שלך"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"דוחות על באגים כוללים נתונים מקובצי היומן השונים במערכת, כולל מידע אישי ופרטי. שתף דוחות באגים רק עם יישומים ואנשים שאתה סומך עליהם."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"הצג את ההודעה הזו בפעם הבאה"</string>
+</resources>
diff --git a/packages/Shell/res/values-ja/strings.xml b/packages/Shell/res/values-ja/strings.xml
new file mode 100644
index 0000000..88b9c14
--- /dev/null
+++ b/packages/Shell/res/values-ja/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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_finished_title" msgid="2293711546892863898">"バグレポートが記録されました"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"タップしてバグレポートを共有する"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"バグレポートには、個人の非公開情報など、システムのさまざまなログファイルのデータが含まれます。共有する場合は信頼するアプリとユーザーのみを選択してください。"</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"このメッセージを次回も表示する"</string>
+</resources>
diff --git a/packages/Shell/res/values-ka-rGE/strings.xml b/packages/Shell/res/values-ka-rGE/strings.xml
new file mode 100644
index 0000000..7d9c72a
--- /dev/null
+++ b/packages/Shell/res/values-ka-rGE/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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_finished_title" msgid="2293711546892863898">"ანგარიში ხარვეზების შესახებ შექმნილია"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"შეეხეთ თქვენი ხარვეზების ანგარიშის გასაზიარებლად"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"ხარვეზის ანგარიშები მოიცავს მონაცემებს სხვადასხვა სისტემური ჟურნალის ფაილებიდან, მათ შორის პირად და კონფიდენციალურ ინფორმაციას."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"შემდგომში აჩვენე ეს შეტყობინება"</string>
+</resources>
diff --git a/packages/Shell/res/values-km-rKH/strings.xml b/packages/Shell/res/values-km-rKH/strings.xml
new file mode 100644
index 0000000..efb345c
--- /dev/null
+++ b/packages/Shell/res/values-km-rKH/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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_finished_title" msgid="2293711546892863898">"បាន​ចាប់​យក​របាយការណ៍​កំហុស"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"ប៉ះ​ ដើម្បី​ចែក​រំលែក​របាយការណ៍​កំហុស​របស់​អ្នក"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"របាយការណ៍​កំហុស​រួមមាន​ឯកសារ​កំណត់​ហេតុ​ផ្សេងៗ​របស់​ប្រព័ន្ធ រួមមាន​ព័ត៌មាន​ផ្ទាល់ខ្លួន និង​ឯកជន។ ចែករំលែក​របាយការណ៍​កំហុស​ជា​មួយ​កម្មវិធី និង​មនុស្ស​ដែល​អ្នក​ទុក​ចិត្ត។"</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"បង្ហាញ​សារ​នេះ​ពេល​ក្រោយ"</string>
+</resources>
diff --git a/packages/Shell/res/values-ko/strings.xml b/packages/Shell/res/values-ko/strings.xml
new file mode 100644
index 0000000..d22a8b0
--- /dev/null
+++ b/packages/Shell/res/values-ko/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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_finished_title" msgid="2293711546892863898">"버그 신고서 캡처됨"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"버그 신고서를 공유하려면 터치하세요."</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"버그 신고서는 시스템의 다양한 로그 파일 데이터(예: 개인 및 비공개 정보)를 포함합니다. 신뢰할 수 있는 앱과 사용자에게만 버그 신고서를 공유합니다."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"다음에 이 메시지 표시"</string>
+</resources>
diff --git a/packages/Shell/res/values-lo-rLA/strings.xml b/packages/Shell/res/values-lo-rLA/strings.xml
new file mode 100644
index 0000000..a237d48
--- /dev/null
+++ b/packages/Shell/res/values-lo-rLA/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Shell"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"ລາຍງານຈຸດບົກພ່ອງຖືກເກັບກຳແລ້ວ"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"ແຕະເພື່ອສົ່ງການລາຍງານປັນຫາຂອງທ່ານ"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"ການລາຍງານຂໍ້ຜິດພາດປະກອບມີ ຂໍ້ມູນຈາກໄຟລ໌ບັນທຶກຂອງລະບົບຫຼາຍໄຟລ໌, ຮວມທັງຂໍ້ມູນສ່ວນໂຕນຳ. ທ່ານຕ້ອງແບ່ງປັນລາຍງານຂໍ້ຜິດພາດໃຫ້ແອັບຯ ແລະຄົນທີ່ທ່ານເຊື່ອຖືໄດ້ເທົ່ານັ້ນ."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"ສະແດງຂໍ້ຄວາມນີ້ອີກໃນເທື່ອຕໍ່ໄປ"</string>
+</resources>
diff --git a/packages/Shell/res/values-lt/strings.xml b/packages/Shell/res/values-lt/strings.xml
new file mode 100644
index 0000000..3ac4820
--- /dev/null
+++ b/packages/Shell/res/values-lt/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Apvalkalas"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Trikčių ataskaita užfiksuota"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Palieskite, kad bendrintumėte trikčių ataskaitą"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Trikčių ataskaitose pateikiami duomenys iš įvairių sistemos žurnalo failų, įskaitant asmeninę ir privačią informaciją. Trikčių ataskaitas bendrinkite tik su patikimomis programomis ir žmonėmis."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Rodyti šį pranešimą kitą kartą"</string>
+</resources>
diff --git a/packages/Shell/res/values-lv/strings.xml b/packages/Shell/res/values-lv/strings.xml
new file mode 100644
index 0000000..3f7f7c1
--- /dev/null
+++ b/packages/Shell/res/values-lv/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Aizsargs"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Izveidots kļūdu pārskats"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Pieskarieties, lai kopīgotu kļūdu pārskatu."</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Kļūdu pārskatā ir iekļauti dati no dažādiem sistēmas žurnālfailiem, tostarp personas dati un privāta informācija. Kļūdu pārskatus ieteicams kopīgot tikai ar uzticamām lietotnēm un lietotājiem."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Rādīt šo ziņojumu nākamajā reizē"</string>
+</resources>
diff --git a/packages/Shell/res/values-mn-rMN/strings.xml b/packages/Shell/res/values-mn-rMN/strings.xml
new file mode 100644
index 0000000..f74298d
--- /dev/null
+++ b/packages/Shell/res/values-mn-rMN/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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_finished_title" msgid="2293711546892863898">"Алдааны мэдээлэл хүлээн авав"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Та алдааны мэдэгдлийг хуваалцах бол хүрнэ үү"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Алдааны репорт нь хувийн болон нууц мэдээлэл зэргийг агуулсан системийн төрөл бүрийн лог файлын датаг агуулна. Алдааны репортыг зөвхөн итгэлтэй апп болон хүмүүст хуваалцана уу."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Энэ мессежийг дараагийн удаа харуулах"</string>
+</resources>
diff --git a/packages/Shell/res/values-ms-rMY/strings.xml b/packages/Shell/res/values-ms-rMY/strings.xml
new file mode 100644
index 0000000..8d1e4a2
--- /dev/null
+++ b/packages/Shell/res/values-ms-rMY/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Shell"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Laporan pepijat telah ditangkap"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Sentuh untuk berkongsi laporan pepijat anda"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Laporan pepijat mengandungi data dari pelbagai fail log sistem, termasuk maklumat peribadi dan sulit. Kongsikan laporan pepijat hanya dengan apl dan orang yang anda percayai."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Tunjukkan mesej ini pada masa akan datang"</string>
+</resources>
diff --git a/packages/Shell/res/values-ms/strings.xml b/packages/Shell/res/values-ms/strings.xml
new file mode 100644
index 0000000..8d1e4a2
--- /dev/null
+++ b/packages/Shell/res/values-ms/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Shell"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Laporan pepijat telah ditangkap"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Sentuh untuk berkongsi laporan pepijat anda"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Laporan pepijat mengandungi data dari pelbagai fail log sistem, termasuk maklumat peribadi dan sulit. Kongsikan laporan pepijat hanya dengan apl dan orang yang anda percayai."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Tunjukkan mesej ini pada masa akan datang"</string>
+</resources>
diff --git a/packages/Shell/res/values-nb/strings.xml b/packages/Shell/res/values-nb/strings.xml
new file mode 100644
index 0000000..96d53a6
--- /dev/null
+++ b/packages/Shell/res/values-nb/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Kommandoliste"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Feilrapporten er lagret"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Trykk for å dele feilrapporten din"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Feilrapporter inkluderer data fra systemets forskjellige loggfiler. Dette omfatter personlig og privat informasjon. Du bør bare dele feilrapporter ned apper og folk du stoler på."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Vis denne meldingen neste gang"</string>
+</resources>
diff --git a/packages/Shell/res/values-nl/strings.xml b/packages/Shell/res/values-nl/strings.xml
new file mode 100644
index 0000000..5c32c73
--- /dev/null
+++ b/packages/Shell/res/values-nl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Shell"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Foutenrapport vastgelegd"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Raak aan om uw foutenrapport te delen"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Foutenrapporten bevatten gegevens uit de verschillende logbestanden van het systeem, waaronder persoonlijke en privégegevens. Deel foutenrapporten alleen met apps en mensen die u vertrouwt."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Dit bericht de volgende keer weergeven"</string>
+</resources>
diff --git a/packages/Shell/res/values-pl/strings.xml b/packages/Shell/res/values-pl/strings.xml
new file mode 100644
index 0000000..2e28f8d
--- /dev/null
+++ b/packages/Shell/res/values-pl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Powłoka"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Raport o błędach został zapisany"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Kliknij, by udostępnić raport o błędach"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Raporty o błędach zawierają dane z różnych plików dzienników systemu, w tym dane osobowe i prywatne. Udostępniaj je tylko aplikacjom i osobom, którym ufasz."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Pokaż ten komunikat następnym razem"</string>
+</resources>
diff --git a/packages/Shell/res/values-pt-rPT/strings.xml b/packages/Shell/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..1c465e0
--- /dev/null
+++ b/packages/Shell/res/values-pt-rPT/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Shell"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Relatório de erros capturado"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Toque para partilhar o relatório de erros"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Os relatórios de erros incluem dados de vários ficheiros de registo do sistema, nomeadamente informações pessoais e privadas. Partilhe relatórios de erros apenas com aplicações e pessoas fidedignas."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Mostrar esta mensagem da próxima vez"</string>
+</resources>
diff --git a/packages/Shell/res/values-pt/strings.xml b/packages/Shell/res/values-pt/strings.xml
new file mode 100644
index 0000000..20f4cc9
--- /dev/null
+++ b/packages/Shell/res/values-pt/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Shell"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Relatório de bugs capturado"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Toque para compartilhar seu relatório de bugs"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Os relatórios de bugs contêm dados de diversos arquivos de registro do sistema, inclusive informações pessoais e particulares. Compartilhe relatórios de bugs somente com aplicativos e pessoas nos quais você confia."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Mostrar esta mensagem da próxima vez"</string>
+</resources>
diff --git a/packages/Shell/res/values-ro/strings.xml b/packages/Shell/res/values-ro/strings.xml
new file mode 100644
index 0000000..45c2b0a
--- /dev/null
+++ b/packages/Shell/res/values-ro/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Shell"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Raportul despre erori a fost creat"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Atingeți pentru a permite accesul la raportul despre erori"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Rapoartele despre erori conțin date din diferite fișiere de jurnal ale sistemului, inclusiv informații private și personale. Permiteți accesul la rapoartele despre erori numai aplicațiilor și persoanelor în care aveți încredere."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Afișați acest mesaj data viitoare"</string>
+</resources>
diff --git a/packages/Shell/res/values-ru/strings.xml b/packages/Shell/res/values-ru/strings.xml
new file mode 100644
index 0000000..153e972
--- /dev/null
+++ b/packages/Shell/res/values-ru/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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_finished_title" msgid="2293711546892863898">"Отчет об ошибках сохранен"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Нажмите, чтобы отправить отчет об ошибках"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Отчеты об ошибках содержат данные различных системных журналов и могут включать личную информацию. Рекомендуем открывать к ним доступ только лицам и приложениям, заслуживающим доверие."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Показать это сообщение в следующий раз"</string>
+</resources>
diff --git a/packages/Shell/res/values-sk/strings.xml b/packages/Shell/res/values-sk/strings.xml
new file mode 100644
index 0000000..99f36f9
--- /dev/null
+++ b/packages/Shell/res/values-sk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Prostredie"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Správa o chybách sa zaznamenala"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Dotykom môžete zdieľať správu o chybách"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Správy o chybách obsahujú údaje z rôznych súborov denníkov systému vrátane osobných a súkromných informácií. Zdieľajte ich iba s dôveryhodnými aplikáciami a ľuďmi."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Zobraziť túto správu nabudúce"</string>
+</resources>
diff --git a/packages/Shell/res/values-sl/strings.xml b/packages/Shell/res/values-sl/strings.xml
new file mode 100644
index 0000000..8522d1b
--- /dev/null
+++ b/packages/Shell/res/values-sl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Lupina"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Poročilo o napaki je posneto"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Dotaknite se, če želite deliti sporočilo o napaki z drugimi"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Poročila o napakah vsebujejo podatke iz različnih dnevniških datotek sistema, vključno z osebnimi in zasebnimi podatki. Poročila o napakah delite samo z aplikacijami in ljudmi, ki jim zaupate."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Pokaži to sporočilo naslednjič"</string>
+</resources>
diff --git a/packages/Shell/res/values-sr/strings.xml b/packages/Shell/res/values-sr/strings.xml
new file mode 100644
index 0000000..bef6ff4
--- /dev/null
+++ b/packages/Shell/res/values-sr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Shell"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Извештај о грешци је снимљен"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Додирните да бисте делили извештај о грешци"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Извештаји о грешкама садрже податке из различитих системских датотека евиденције, укључујући личне и приватне податке. Делите извештаје о грешкама само са апликацијама и људима у које имате поверења."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Прикажи ову поруку следећи пут"</string>
+</resources>
diff --git a/packages/Shell/res/values-sv/strings.xml b/packages/Shell/res/values-sv/strings.xml
new file mode 100644
index 0000000..055dc41
--- /dev/null
+++ b/packages/Shell/res/values-sv/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Skal"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Felrapporten har skapats"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Tryck om du vill dela felrapporten"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Felrapporter innehåller data från systemets olika loggfiler, inklusive personliga och privata uppgifter. Dela bara felrapporter med personer du litar på."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Visa det här meddelandet nästa gång"</string>
+</resources>
diff --git a/packages/Shell/res/values-sw/strings.xml b/packages/Shell/res/values-sw/strings.xml
new file mode 100644
index 0000000..b1d4407
--- /dev/null
+++ b/packages/Shell/res/values-sw/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Ganda"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Ripoti ya hitilafu imenaswa"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Gusa ili ushiriki ripoti yako ya hitilafu"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Ripoti ya hitilafu ina data kutoka kwenye faili za kumbukumbu mbalimbali za mfumo, pamoja na maelezo ya kibinafsi na faragha. Shiriki ripoti ya hitilafu na programu na watu unaowaamini pekee."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Onyesha ujumbe huu wakati mwingine"</string>
+</resources>
diff --git a/packages/Shell/res/values-th/strings.xml b/packages/Shell/res/values-th/strings.xml
new file mode 100644
index 0000000..b484a42
--- /dev/null
+++ b/packages/Shell/res/values-th/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Shell"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"จับภาพรายงานข้อบกพร่องแล้ว"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"แตะเพื่อแชร์รายงานข้อบกพร่องของคุณ"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"รายงานข้อบกพร่องมีข้อมูลจากไฟล์บันทึกต่างๆ ของระบบ รวมถึงข้อมูลส่วนตัว แชร์รายงานข้อบกพร่องกับแอปและบุคคลที่คุณไว้ใจเท่านั้น"</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"แสดงข้อความนี้ในครั้งต่อไป"</string>
+</resources>
diff --git a/packages/Shell/res/values-tl/strings.xml b/packages/Shell/res/values-tl/strings.xml
new file mode 100644
index 0000000..20d1b09
--- /dev/null
+++ b/packages/Shell/res/values-tl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Shell"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Na-capture ang ulat ng bug"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Pindutin upang ibahagi ang iyong ulat ng bug"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Naglalaman ang mga ulat ng bug ng data mula sa iba\'t ibang file ng log ng system, kabilang ang personal at pribadong impormasyon. Magbahagi lang ng mga ulat ng bug sa apps at mga tao na pinagkakatiwalaan mo."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Ipakita ang mensaheng ito sa susunod"</string>
+</resources>
diff --git a/packages/Shell/res/values-tr/strings.xml b/packages/Shell/res/values-tr/strings.xml
new file mode 100644
index 0000000..56db3fc
--- /dev/null
+++ b/packages/Shell/res/values-tr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Kabuk"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Hata raporu kaydedildi"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Hata raporunuzu paylaşmak için dokunun"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Hata raporları, kişisel ve özel bilgiler dahil olmak üzere sistemin çeşitli günlük dosyalarından veriler içerir. Hata raporlarını sadece güvendiğiniz uygulamalar ve kişilerle paylaşın."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Bir dahaki sefere bu mesajı göster"</string>
+</resources>
diff --git a/packages/Shell/res/values-uk/strings.xml b/packages/Shell/res/values-uk/strings.xml
new file mode 100644
index 0000000..68e68a8
--- /dev/null
+++ b/packages/Shell/res/values-uk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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_finished_title" msgid="2293711546892863898">"Звіт про помилки створено"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Торкніться, щоб надіслати звіт про помилки"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Звіти про помилки містять дані з різних файлів журналу системи, зокрема особисті та конфіденційні. Надсилайте звіт про помилки лише тим, кому довіряєте."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Показати це повідомлення наступного разу"</string>
+</resources>
diff --git a/packages/Shell/res/values-vi/strings.xml b/packages/Shell/res/values-vi/strings.xml
new file mode 100644
index 0000000..ca4fcaa
--- /dev/null
+++ b/packages/Shell/res/values-vi/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Shell"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Báo cáo lỗi đã được chụp"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Chạm để chia sẻ báo cáo lỗi của bạn"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Các báo cáo lỗi chứa dữ liệu từ nhiều tệp nhật ký khác nhau của hệ thống, bao gồm cả thông tin cá nhân và riêng tư. Chỉ chia sẻ báo cáo lỗi với các ứng dụng và những người mà bạn tin tưởng."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Hiển thị thông báo này vào lần tới"</string>
+</resources>
diff --git a/packages/Shell/res/values-zh-rCN/strings.xml b/packages/Shell/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..f1c385f
--- /dev/null
+++ b/packages/Shell/res/values-zh-rCN/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Shell"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"已抓取错误报告"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"触摸即可分享您的错误报告"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"错误报告包含的数据来自于系统的各个日志文件,其中包含个人信息和隐私信息。请务必只与您信任的应用和用户分享错误报告。"</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"下次再显示这条讯息"</string>
+</resources>
diff --git a/packages/Shell/res/values-zh-rHK/strings.xml b/packages/Shell/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..b5f1935
--- /dev/null
+++ b/packages/Shell/res/values-zh-rHK/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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_finished_title" msgid="2293711546892863898">"已擷取錯誤報告"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"輕觸即可分享您的錯誤報告"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"錯誤報告中有來自系統各個記錄檔案的資料,包括個人和私人資料。請只與您信任的應用程式和用戶分享錯誤報告。"</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"下次再顯示這則訊息"</string>
+</resources>
diff --git a/packages/Shell/res/values-zh-rTW/strings.xml b/packages/Shell/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..d3d3140
--- /dev/null
+++ b/packages/Shell/res/values-zh-rTW/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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_finished_title" msgid="2293711546892863898">"已擷取錯誤報告"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"輕觸即可分享您的錯誤報告"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"錯誤報告的資料來自系統各個紀錄檔,包括個人和私密資訊。請務必只與您信任的應用程式和使用者分享錯誤報告。"</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"下次仍顯示這則訊息"</string>
+</resources>
diff --git a/packages/Shell/res/values-zu/strings.xml b/packages/Shell/res/values-zu/strings.xml
new file mode 100644
index 0000000..e524b80
--- /dev/null
+++ b/packages/Shell/res/values-zu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"I-Shell"</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Umbiko wesiphazamisi uthwetshuliwe"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Thinta ukuze wabelane ngombiko wakho wesiphazamisi"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Imibiko yeziphazamisi iqukethe idatha yamafayela wokungena ahlukile wesistimu, afaka ulwazi lomuntu siqu noma lobumfihlo. Yabelana kuphela ngemibiko yeziphazamisi nezinhlelo zokusebenza nabantu obathembayo."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Bonisa lo mlayezo ngesikhathi esilandelayo"</string>
+</resources>
diff --git a/packages/SystemUI/Android.mk b/packages/SystemUI/Android.mk
index 015c0cc..f8f064a 100644
--- a/packages/SystemUI/Android.mk
+++ b/packages/SystemUI/Android.mk
@@ -6,10 +6,11 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src) \
     src/com/android/systemui/EventLogTags.logtags
 
-LOCAL_JAVA_LIBRARIES := services telephony-common
+LOCAL_JAVA_LIBRARIES := telephony-common
 
 LOCAL_PACKAGE_NAME := SystemUI
 LOCAL_CERTIFICATE := platform
+LOCAL_PRIVILEGED_MODULE := true
 
 LOCAL_PROGUARD_FLAG_FILES := proguard.flags
 
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 66080f3..fa5c769 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -1,6 +1,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
         package="com.android.systemui"
+        android:sharedUserId="android.uid.systemui"
         coreApp="true">
 
     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
@@ -23,6 +24,7 @@
     <uses-permission android:name="android.permission.READ_CONTACTS" />
     <uses-permission android:name="android.permission.CONFIGURE_WIFI_DISPLAY" />
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+    <uses-permission android:name="android.permission.GET_APP_OPS_STATS" />
 
     <!-- Networking and telephony -->
     <uses-permission android:name="android.permission.BLUETOOTH" />
@@ -37,7 +39,6 @@
     <uses-permission android:name="android.permission.MANAGE_USB" />
     <uses-permission android:name="android.permission.DEVICE_POWER" />
     <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
-    <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
     <uses-permission android:name="android.permission.MASTER_CLEAR" />
     <uses-permission android:name="android.permission.VIBRATE" />
 
@@ -64,6 +65,9 @@
     <uses-permission android:name="android.permission.READ_DREAM_STATE" />
     <uses-permission android:name="android.permission.WRITE_DREAM_STATE" />
 
+    <!-- Alarm clocks -->
+    <uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
+
     <application
         android:persistent="true"
         android:allowClearUserData="false"
@@ -71,6 +75,7 @@
         android:hardwareAccelerated="true"
         android:label="@string/app_label"
         android:icon="@*android:drawable/platlogo"
+        android:process="com.android.systemui"
         android:supportsRtl="true">
 
         <!-- Broadcast receiver that gets the broadcast at boot time and starts
@@ -184,12 +189,11 @@
             android:taskAffinity="com.android.systemui.net"
             android:excludeFromRecents="true" />
 
-        <!-- started from ... somewhere -->
+        <!-- platform logo easter egg activity -->
         <activity
-            android:name=".BeanBag"
+            android:name=".DessertCase"
             android:exported="true"
-            android:label="BeanBag"
-            android:icon="@drawable/redbean2"
+            android:label="@string/dessert_case"
             android:theme="@android:style/Theme.Wallpaper.NoTitleBar.Fullscreen"
             android:hardwareAccelerated="true"
             android:launchMode="singleInstance"
@@ -198,15 +202,14 @@
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.DEFAULT" />
                 <category android:name="com.android.internal.category.PLATLOGO" />
-<!--            <category android:name="android.intent.category.LAUNCHER" />-->
             </intent-filter>
         </activity>
 
-        <!-- Beans in space -->
+        <!-- a gallery of delicious treats -->
         <service
-            android:name=".BeanBagDream"
+            android:name=".DessertCaseDream"
             android:exported="true"
-            android:label="@string/jelly_bean_dream_name"
+            android:label="@string/dessert_case"
             android:enabled="false"
             >
             <intent-filter>
diff --git a/packages/SystemUI/assets/fonts/AndroidClock.ttf b/packages/SystemUI/assets/fonts/AndroidClock.ttf
deleted file mode 100644
index 7b550ee..0000000
--- a/packages/SystemUI/assets/fonts/AndroidClock.ttf
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/assets/fonts/AndroidClock2.ttf b/packages/SystemUI/assets/fonts/AndroidClock2.ttf
deleted file mode 100644
index a95d548..0000000
--- a/packages/SystemUI/assets/fonts/AndroidClock2.ttf
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/ic_sysbar_internal.psd b/packages/SystemUI/ic_sysbar_internal.psd
deleted file mode 100644
index 929c872..0000000
--- a/packages/SystemUI/ic_sysbar_internal.psd
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/proguard.flags b/packages/SystemUI/proguard.flags
index c886eea..ab45d99 100644
--- a/packages/SystemUI/proguard.flags
+++ b/packages/SystemUI/proguard.flags
@@ -1,10 +1,3 @@
--keep class com.android.systemui.statusbar.tablet.TabletStatusBarService {
-  public void notificationIconsClicked(android.view.View);
-  public void systemInfoClicked(android.view.View);
-  public void recentButtonClicked(android.view.View);
-  public void toggleLightsOut(android.view.View);
-}
-
 -keep class com.android.systemui.statusbar.policy.KeyButtonView {
   public float getDrawingAlpha();
   public float getGlowAlpha();
diff --git a/packages/SystemUI/res/anim/heads_up_enter.xml b/packages/SystemUI/res/anim/heads_up_enter.xml
new file mode 100644
index 0000000..59eef42
--- /dev/null
+++ b/packages/SystemUI/res/anim/heads_up_enter.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        >
+    <translate
+        android:interpolator="@android:interpolator/overshoot"
+        android:fromYDelta="-50%" android:toYDelta="0"
+        android:duration="@android:integer/config_shortAnimTime" />
+    <alpha 
+        android:interpolator="@android:interpolator/decelerate_quad"
+        android:fromAlpha="0.0" android:toAlpha="1.0"
+        android:duration="@android:integer/config_shortAnimTime" />
+</set>
diff --git a/packages/SystemUI/res/anim/priority_alert_exit.xml b/packages/SystemUI/res/anim/heads_up_exit.xml
similarity index 100%
rename from packages/SystemUI/res/anim/priority_alert_exit.xml
rename to packages/SystemUI/res/anim/heads_up_exit.xml
diff --git a/packages/SystemUI/res/anim/priority_alert_enter.xml b/packages/SystemUI/res/anim/priority_alert_enter.xml
deleted file mode 100644
index 4fd6a7c..0000000
--- a/packages/SystemUI/res/anim/priority_alert_enter.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-        >
-    <scale
-        android:interpolator="@android:interpolator/overshoot"
-        android:fromXScale="0.7" android:toXScale="1.0"
-        android:fromYScale="0.7" android:toYScale="1.0"
-        android:pivotX="50%" android:pivotY="50%"
-        android:duration="@android:integer/config_shortAnimTime" />
-    <alpha 
-        android:interpolator="@android:interpolator/decelerate_quad"
-        android:fromAlpha="0.0" android:toAlpha="1.0"
-        android:duration="@android:integer/config_shortAnimTime" />
-</set>
diff --git a/packages/SystemUI/res/anim/wallpaper_recents_launch_from_launcher_enter.xml b/packages/SystemUI/res/anim/wallpaper_recents_launch_from_launcher_enter.xml
index 121daae..73ae9f2 100644
--- a/packages/SystemUI/res/anim/wallpaper_recents_launch_from_launcher_enter.xml
+++ b/packages/SystemUI/res/anim/wallpaper_recents_launch_from_launcher_enter.xml
@@ -18,6 +18,7 @@
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:detachWallpaper="true"
      android:shareInterpolator="false"
      android:zAdjustment="normal">
   <!--scale android:fromXScale="2.0" android:toXScale="1.0"
diff --git a/packages/SystemUI/res/anim/wallpaper_recents_launch_from_launcher_exit.xml b/packages/SystemUI/res/anim/wallpaper_recents_launch_from_launcher_exit.xml
index fa28cf4..7e257d9 100644
--- a/packages/SystemUI/res/anim/wallpaper_recents_launch_from_launcher_exit.xml
+++ b/packages/SystemUI/res/anim/wallpaper_recents_launch_from_launcher_exit.xml
@@ -18,6 +18,7 @@
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:detachWallpaper="true"
      android:shareInterpolator="false"
      android:zAdjustment="top">
   <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
diff --git a/packages/SystemUI/res/drawable-hdpi/alert_bar_background_normal.9.png b/packages/SystemUI/res/drawable-hdpi/alert_bar_background_normal.9.png
deleted file mode 100644
index a90c412..0000000
--- a/packages/SystemUI/res/drawable-hdpi/alert_bar_background_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/alert_bar_background_pressed.9.png b/packages/SystemUI/res/drawable-hdpi/alert_bar_background_pressed.9.png
deleted file mode 100644
index 9d6032c..0000000
--- a/packages/SystemUI/res/drawable-hdpi/alert_bar_background_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/arrow_dashed.png b/packages/SystemUI/res/drawable-hdpi/arrow_dashed.png
deleted file mode 100644
index a8075d5..0000000
--- a/packages/SystemUI/res/drawable-hdpi/arrow_dashed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/battery_low_battery.png b/packages/SystemUI/res/drawable-hdpi/battery_low_battery.png
index 5107bd1..e6af81e 100644
--- a/packages/SystemUI/res/drawable-hdpi/battery_low_battery.png
+++ b/packages/SystemUI/res/drawable-hdpi/battery_low_battery.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/btn_cling_normal.9.png b/packages/SystemUI/res/drawable-hdpi/btn_cling_normal.9.png
deleted file mode 100644
index aea8beb..0000000
--- a/packages/SystemUI/res/drawable-hdpi/btn_cling_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/btn_cling_pressed.9.png b/packages/SystemUI/res/drawable-hdpi/btn_cling_pressed.9.png
deleted file mode 100644
index ebefd20..0000000
--- a/packages/SystemUI/res/drawable-hdpi/btn_cling_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/btn_default_small_normal.9.png b/packages/SystemUI/res/drawable-hdpi/btn_default_small_normal.9.png
deleted file mode 100644
index 6f456f3..0000000
--- a/packages/SystemUI/res/drawable-hdpi/btn_default_small_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/btn_default_small_normal_disable.9.png b/packages/SystemUI/res/drawable-hdpi/btn_default_small_normal_disable.9.png
deleted file mode 100644
index e592ae6..0000000
--- a/packages/SystemUI/res/drawable-hdpi/btn_default_small_normal_disable.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/btn_default_small_normal_disable_focused.9.png b/packages/SystemUI/res/drawable-hdpi/btn_default_small_normal_disable_focused.9.png
deleted file mode 100644
index c1f87a7..0000000
--- a/packages/SystemUI/res/drawable-hdpi/btn_default_small_normal_disable_focused.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/btn_default_small_pressed.9.png b/packages/SystemUI/res/drawable-hdpi/btn_default_small_pressed.9.png
deleted file mode 100644
index 2d16eda..0000000
--- a/packages/SystemUI/res/drawable-hdpi/btn_default_small_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/btn_default_small_selected.9.png b/packages/SystemUI/res/drawable-hdpi/btn_default_small_selected.9.png
deleted file mode 100644
index 0749413..0000000
--- a/packages/SystemUI/res/drawable-hdpi/btn_default_small_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/compat_mode_help_diagram.png b/packages/SystemUI/res/drawable-hdpi/compat_mode_help_diagram.png
deleted file mode 100644
index 944b1f0..0000000
--- a/packages/SystemUI/res/drawable-hdpi/compat_mode_help_diagram.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/compat_mode_help_divider_bottom.9.png b/packages/SystemUI/res/drawable-hdpi/compat_mode_help_divider_bottom.9.png
deleted file mode 100644
index 155a315..0000000
--- a/packages/SystemUI/res/drawable-hdpi/compat_mode_help_divider_bottom.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/compat_mode_help_divider_top.9.png b/packages/SystemUI/res/drawable-hdpi/compat_mode_help_divider_top.9.png
deleted file mode 100644
index 3eb6fa2..0000000
--- a/packages/SystemUI/res/drawable-hdpi/compat_mode_help_divider_top.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/compat_mode_help_icon.png b/packages/SystemUI/res/drawable-hdpi/compat_mode_help_icon.png
deleted file mode 100644
index 46bb891..0000000
--- a/packages/SystemUI/res/drawable-hdpi/compat_mode_help_icon.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/hd_off.png b/packages/SystemUI/res/drawable-hdpi/hd_off.png
deleted file mode 100644
index e7246cb..0000000
--- a/packages/SystemUI/res/drawable-hdpi/hd_off.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/hd_on.png b/packages/SystemUI/res/drawable-hdpi/hd_on.png
deleted file mode 100644
index 5360d42..0000000
--- a/packages/SystemUI/res/drawable-hdpi/hd_on.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/heads_up_window_bg.9.png b/packages/SystemUI/res/drawable-hdpi/heads_up_window_bg.9.png
new file mode 100644
index 0000000..3b952d0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/heads_up_window_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_launcher_settings.png b/packages/SystemUI/res/drawable-hdpi/ic_launcher_settings.png
deleted file mode 100644
index c02bd42..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_launcher_settings.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notification_dnd.png b/packages/SystemUI/res/drawable-hdpi/ic_notification_dnd.png
deleted file mode 100644
index 92bc75c..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_notification_dnd.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notification_open.png b/packages/SystemUI/res/drawable-hdpi/ic_notification_open.png
deleted file mode 100644
index cd9a54a..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_notification_open.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notification_overlay.9.png b/packages/SystemUI/res/drawable-hdpi/ic_notification_overlay.9.png
index fd33ef3..a93916f 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_notification_overlay.9.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notification_overlay.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notifications_normal.png b/packages/SystemUI/res/drawable-hdpi/ic_notifications_normal.png
deleted file mode 100644
index 62afe76..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_notifications_normal.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_normal.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_normal.png
index ead184d..54dde82 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_normal.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_pressed.png
deleted file mode 100644
index 203e232..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_open_normal.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_open_normal.png
index ca56ad4..092b561 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_notify_open_normal.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_open_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_open_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_open_pressed.png
deleted file mode 100644
index 1a14231..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_notify_open_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_normal.png
index 4436359..064860d 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_normal.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_pressed.png
deleted file mode 100644
index c86710d..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_rotation_off_normal.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_rotation_off_normal.png
deleted file mode 100644
index 4ca1ab8..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_notify_rotation_off_normal.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_rotation_off_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_rotation_off_pressed.png
deleted file mode 100644
index 85a4cd2..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_notify_rotation_off_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_rotation_on_normal.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_rotation_on_normal.png
deleted file mode 100644
index d0cb087..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_notify_rotation_on_normal.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_rotation_on_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_rotation_on_pressed.png
deleted file mode 100644
index c1c9e16..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_notify_rotation_on_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_settings_normal.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_settings_normal.png
index 3ed7418..2d8d074 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_notify_settings_normal.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_settings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_settings_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_settings_pressed.png
deleted file mode 100644
index 5e20eea..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_notify_settings_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_airplane_off.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_airplane_off.png
index ab66137..fd9d9db 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_airplane_off.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_airplane_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_airplane_on.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_airplane_on.png
index e058bcd..5f2e95a 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_airplane_on.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_airplane_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_alarm_on.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_alarm_on.png
index e214c00..c100353 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_alarm_on.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_alarm_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_auto_rotate.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_auto_rotate.png
index 8d45fc5..63acea0 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_auto_rotate.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_auto_rotate.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_0.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_0.png
index 6fd7910..beb0e05 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_0.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_100.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_100.png
index f3632f3..14832c5f 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_100.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_15.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_15.png
index 228f59a..603fff1 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_15.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_28.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_28.png
index dc8510d..5556d6a 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_28.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_43.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_43.png
index 77abaaa..0004633 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_43.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_57.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_57.png
index 403bfbc..abd336b 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_57.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_71.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_71.png
index c0ff12c..f23dda8 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_71.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_85.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_85.png
index 18e8864..c7482a9 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_85.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_bolt.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_bolt.png
deleted file mode 100644
index f7dca8b..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_bolt.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_charge_100.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_charge_100.png
index 64db815..e8f92e2 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_charge_100.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_charge_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_charge_15.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_charge_15.png
index 3965162..0d01eb5 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_charge_15.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_charge_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_charge_28.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_charge_28.png
index 4b14d62..3d66ffb 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_charge_28.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_charge_28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_charge_43.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_charge_43.png
index 3f51ba5..3562cea 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_charge_43.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_charge_43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_charge_57.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_charge_57.png
index aecf7e6..2b2ebf6 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_charge_57.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_charge_57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_charge_71.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_charge_71.png
index 524bf73..f9f9537 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_charge_71.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_charge_71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_charge_85.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_charge_85.png
index 80325c7..2c7532a 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_charge_85.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_charge_85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_unknown.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_unknown.png
index ceaa03b..ebcd336 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_unknown.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_battery_unknown.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_bluetooth_not_connected.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_bluetooth_not_connected.png
index 8fb71ba..e417a19 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_bluetooth_not_connected.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_bluetooth_not_connected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_bluetooth_off.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_bluetooth_off.png
index ac76535..be153d1 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_bluetooth_off.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_bluetooth_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_bluetooth_on.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_bluetooth_on.png
index 090d235..ee88a1b 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_bluetooth_on.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_bluetooth_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_brightness_auto_off.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_brightness_auto_off.png
index 841b7d9..0a29157 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_brightness_auto_off.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_brightness_auto_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_brightness_auto_on.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_brightness_auto_on.png
index bb58171..9c1d8ef 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_brightness_auto_on.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_brightness_auto_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_certificate_info.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_certificate_info.png
new file mode 100644
index 0000000..1fdaaf9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_certificate_info.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_clock_circle.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_clock_circle.png
index f724ea5..f82a037 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_clock_circle.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_clock_circle.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_clock_hour.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_clock_hour.png
index ca73621..ed6c0db 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_clock_hour.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_clock_hour.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_clock_minute.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_clock_minute.png
index 8ee38ee..e28c06a 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_clock_minute.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_clock_minute.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_default_user.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_default_user.png
index 03c450c..18257e0 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_default_user.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_default_user.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_ime.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_ime.png
index e20a061..7220968 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_ime.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_location.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_location.png
index 7e67171..c561446 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_location.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_location.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_location_off.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_location_off.png
new file mode 100644
index 0000000..7570610
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_location_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_location_on.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_location_on.png
new file mode 100644
index 0000000..0df2411
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_location_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_remote_display.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_remote_display.png
index a7bc3c5..cf510b4 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_remote_display.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_remote_display.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_remote_display_connected.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_remote_display_connected.png
index 012a4e8..263f07c 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_remote_display_connected.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_remote_display_connected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_rotation_locked.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_rotation_locked.png
index 1a7618d..f3dc08f 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_rotation_locked.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_rotation_locked.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_settings.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_settings.png
index cac7192..8b6ecc2 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_settings.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_settings.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_0.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_0.png
index 39fff41..a14b8d8 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_0.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_1.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_1.png
index f9ecb02..b226694 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_1.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_1x.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_1x.png
index c7cfa21..cbabd61 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_1x.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_2.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_2.png
index 2268801..1e9fbfd 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_2.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_3.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_3.png
index 16ecb6a..0676919 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_3.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_3g.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_3g.png
index fb01687..12569d1 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_3g.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_4.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_4.png
index fbbf225..3ad9e76 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_4.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_4g.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_4g.png
index c151a64..7d5f6d0 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_4g.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_e.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_e.png
index 47e9ad5..2102263 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_e.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_0.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_0.png
index 97d84a9..c288137 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_0.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_1.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_1.png
index 544dcf9..e20fdf7 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_1.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_1x.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_1x.png
index 5ca9892..c24cd4d 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_1x.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_2.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_2.png
index 7f050f8..79c9099 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_2.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_3.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_3.png
index be1ed56..8cb1cec 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_3.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_3g.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_3g.png
index 5eab3c8..4f76f66 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_3g.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_4.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_4.png
index 502787b..9570dae 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_4.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_4g.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_4g.png
index 777f8fc..b23a043 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_4g.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_e.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_e.png
index e436ed8..75de8cd 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_e.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_g.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_g.png
index 304c278..c0ae67c 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_g.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_h.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_h.png
index 26687ca..858afc8 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_h.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_lte.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_lte.png
index 1a5a8aa..9dfde67 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_lte.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_lte.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_r.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_r.png
index b0449e1..4fea255 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_r.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_full_r.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_g.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_g.png
index 2f622c2..fa905cc 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_g.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_h.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_h.png
index f5f76c2c..5b5b5d2 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_h.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_in.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_in.png
index a9dc907..6ff215b 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_in.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_inout.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_inout.png
index 89d2939..cf5e825 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_inout.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_lte.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_lte.png
index cceab0a..5128c0d 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_lte.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_lte.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_no_network.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_no_network.png
index 3ed973b..05bb0a0 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_no_network.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_no_network.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_no_signal.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_no_signal.png
index 0fb96d9..c7b035a 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_no_signal.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_no_signal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_out.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_out.png
index d8993f8..5d8fd07 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_out.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_r.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_r.png
index b78f474..da77a35 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_r.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_signal_r.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_usb_device.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_usb_device.png
index 13ee0a5..c3f4729 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_usb_device.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_usb_device.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_0.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_0.png
index 7e7d068..6aa522b 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_0.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_1.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_1.png
index b720720..c500691 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_1.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_2.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_2.png
index 1a4c6d1..ae87896 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_2.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_3.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_3.png
index 96cd8ab..e47ef7a 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_3.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_4.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_4.png
index 54bab4d..9fd1ae6 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_4.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_full_1.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_full_1.png
index 0a31297..2afa621 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_full_1.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_full_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_full_2.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_full_2.png
index 3e712ad..c873c55 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_full_2.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_full_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_full_3.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_full_3.png
index 565ae54..e3e0e8d 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_full_3.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_full_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_full_4.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_full_4.png
index 2c30f8e..2762df5 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_full_4.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_full_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_in.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_in.png
index a9dc907..ebd2001 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_in.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_inout.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_inout.png
index 89d2939..cf5e825 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_inout.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_no_network.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_no_network.png
index 6e4276f..a5e0bde 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_no_network.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_no_network.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_not_connected.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_not_connected.png
index 6095942..c9e0a7c 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_not_connected.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_not_connected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_out.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_out.png
index d8993f8..5d8fd07 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_out.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_airplane_on.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_airplane_on.png
deleted file mode 100644
index 7096b73..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_airplane_on.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
index 84e6bc8..873ca7e 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime.png
index 3071fb3..9d3cf53 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png
index 782d214..288d36a 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_brightness.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_brightness.png
deleted file mode 100644
index e72fde8..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_brightness.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png
index 38e4f45..266d34d 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png
index c39f7b1..0298054 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_ime_default.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_ime_default.png
deleted file mode 100644
index c925a53..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_ime_default.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_lights_out_dot_large.png
index 2e5dc3c..1233fca 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_lights_out_dot_large.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_lights_out_dot_large.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_lights_out_dot_small.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_lights_out_dot_small.png
index a8f4daa..6768c1f 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_lights_out_dot_small.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_lights_out_dot_small.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png
index 58843bb..91e2edf 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_land.png
index 66cd57b..9ed15a7 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_quicksettings.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_quicksettings.png
deleted file mode 100644
index 2a94b5d..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_quicksettings.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png
index bf9f300..6f2915b 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png
index 194c51f..3f3b692 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_rotate_on.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_rotate_on.png
deleted file mode 100644
index 02da243..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_rotate_on.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_wifi_on.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_wifi_on.png
deleted file mode 100644
index d645a3c..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_wifi_on.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/pocket_drag_pattern.png b/packages/SystemUI/res/drawable-hdpi/pocket_drag_pattern.png
deleted file mode 100644
index b436fc5..0000000
--- a/packages/SystemUI/res/drawable-hdpi/pocket_drag_pattern.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/recents_blue_glow.9.png b/packages/SystemUI/res/drawable-hdpi/recents_blue_glow.9.png
deleted file mode 100644
index b5d85188..0000000
--- a/packages/SystemUI/res/drawable-hdpi/recents_blue_glow.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_dragging.9.png b/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_dragging.9.png
index 652f66f..080f2f2 100644
--- a/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_dragging.9.png
+++ b/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_dragging.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_normal.9.png b/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_normal.9.png
index d000f7e..8b45500 100644
--- a/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_normal.9.png
+++ b/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_normal.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_press.9.png b/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_press.9.png
index 288d818..e591a7b 100644
--- a/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_press.9.png
+++ b/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_press.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/screenshot_panel.9.png b/packages/SystemUI/res/drawable-hdpi/screenshot_panel.9.png
index 2509321..da56dcc 100644
--- a/packages/SystemUI/res/drawable-hdpi/screenshot_panel.9.png
+++ b/packages/SystemUI/res/drawable-hdpi/screenshot_panel.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/search_light.png b/packages/SystemUI/res/drawable-hdpi/search_light.png
index c8b5a2e..9a8f771 100644
--- a/packages/SystemUI/res/drawable-hdpi/search_light.png
+++ b/packages/SystemUI/res/drawable-hdpi/search_light.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_notify_image.png b/packages/SystemUI/res/drawable-hdpi/stat_notify_image.png
index 3f36546..7b0fcc7 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_notify_image.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_notify_image.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_notify_image_error.png b/packages/SystemUI/res/drawable-hdpi/stat_notify_image_error.png
index 2b116bf..73e9c96 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_notify_image_error.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_notify_image_error.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_alarm.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_alarm.png
index fc8dee1..2c55017 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_alarm.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_alarm.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_0.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_0.png
index f6b7df7..4ff22d2 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_0.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_100.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_100.png
index c920ec4..612b362 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_100.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_15.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_15.png
index a51fd00..c971443 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_15.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_28.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_28.png
index 4e830a4..a6d4796 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_28.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_43.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_43.png
index 48e7122..67a6a73 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_43.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_57.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_57.png
index f807434..f972ebd 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_57.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_71.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_71.png
index 98c8dea..b707fa1 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_71.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_85.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_85.png
index 9700b1b..82d6545 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_85.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim0.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim0.png
index 554aaff5..59edd98 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim0.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim100.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim100.png
index 829378e..450dd70 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim100.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim15.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim15.png
index 11ce50d..ae6fee5 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim15.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim28.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim28.png
index 2d8fbe0..67fa3ad 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim28.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim43.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim43.png
index df0bb45..ba367ea 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim43.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim57.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim57.png
index f6fc90b..3ce0c6e 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim57.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim71.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim71.png
index b2a1bcd..d502d5d 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim71.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim85.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim85.png
index 6ccced5..2f44643 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim85.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_battery_charge_anim85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_bluetooth.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_bluetooth.png
index 4a5d001..7ed4c78 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_bluetooth.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_bluetooth.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_bluetooth_connected.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_bluetooth_connected.png
index da61485..08c07b2 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_bluetooth_connected.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_bluetooth_connected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_1x.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_1x.png
deleted file mode 100644
index 551c672..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_1x.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_3g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_3g.png
deleted file mode 100644
index aee2cf2..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_3g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_4g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_4g.png
deleted file mode 100644
index 28bdabb..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_4g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_e.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_e.png
deleted file mode 100644
index a6d4672..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_e.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_g.png
deleted file mode 100644
index c9a6c8e..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_h.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_h.png
deleted file mode 100644
index 83aa3c7..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_h.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_lte.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_lte.png
deleted file mode 100644
index e377608..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_lte.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_roam.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_roam.png
deleted file mode 100644
index 24ad4de..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_roam.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_1x.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_1x.png
index 15faa3a..804d1ac 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_1x.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_3g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_3g.png
index 4dbca1e..1d863e9 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_3g.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_4g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_4g.png
index c3cda8a..62970fe 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_4g.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_e.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_e.png
index 6cdc111..6c3fbdc 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_e.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_g.png
index 9a3fa43..a5effe0 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_g.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_h.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_h.png
index 80f340f..b7071b9 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_h.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_lte.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_lte.png
index d619f6b..bd145fa 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_lte.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_lte.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_roam.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_roam.png
new file mode 100644
index 0000000..be38df8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_roam.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_0.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_0.png
index 55272f5..432b166 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_0.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_0_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_0_fully.png
index e5e6305..aa071c77 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_0_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_0_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_1.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_1.png
index f595ae1..194698a 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_1.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_1_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_1_fully.png
index f555fc9..0b4b368 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_1_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_2.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_2.png
index ecf1349..8887f2e0 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_2.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_2_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_2_fully.png
index 918a9f9..87c3244 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_2_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_3.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_3.png
index f5d1479..8206cd8 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_3.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_3_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_3_fully.png
index f58a19c..293f88c 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_3_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_disconnected.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_disconnected.png
index 744b1fa..cb9c8ac 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_disconnected.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_disconnected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_idle.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_idle.png
index bef4358..88eafcb 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_idle.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_wimax_signal_idle.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_device_access_location_found.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_device_access_location_found.png
new file mode 100644
index 0000000..9befc34
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_device_access_location_found.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_gps_acquiring.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_gps_acquiring.png
deleted file mode 100644
index 5503df1..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_gps_acquiring.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_no_sim.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_no_sim.png
index 765548b..5ce8708 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_no_sim.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_no_sim.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_ringer_silent.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_ringer_silent.png
index cbd9b87..58f67d0 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_ringer_silent.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_ringer_silent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_ringer_vibrate.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_ringer_vibrate.png
index 72e6821..b794c9a 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_ringer_vibrate.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_ringer_vibrate.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_roaming_cdma_0.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_roaming_cdma_0.png
index a59c844..8f17b72 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_roaming_cdma_0.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_roaming_cdma_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_roaming_cdma_flash_anim0.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_roaming_cdma_flash_anim0.png
deleted file mode 100644
index 67f16b9..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_roaming_cdma_flash_anim0.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_roaming_cdma_flash_anim1.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_roaming_cdma_flash_anim1.png
deleted file mode 100644
index a59c844..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_roaming_cdma_flash_anim1.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_0.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_0.png
index a2ba6c4..da941c8 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_0.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_0_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_0_fully.png
index 00b560c..0fd09d7 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_0_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_0_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_1.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_1.png
deleted file mode 100644
index fd8d2f2..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_1.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_1_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_1_fully.png
index 92364d2..cfe43dd 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_1_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_2.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_2.png
deleted file mode 100644
index 3b4aaa1..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_2.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_2_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_2_fully.png
index 8cea4e9..92a5b1c 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_2_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_3.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_3.png
deleted file mode 100644
index 873a317..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_3.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_3_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_3_fully.png
index 94a4a35..9454cd8 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_3_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_4.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_4.png
deleted file mode 100644
index d2381fcc..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_4.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_4_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_4_fully.png
index 93552cb..6cb18c7 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_4_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_4_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_flightmode.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_flightmode.png
index d5a78ca..dcf86c0 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_flightmode.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_flightmode.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_in.png
deleted file mode 100644
index 6e84546..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_inout.png
deleted file mode 100644
index c56905e..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_null.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_null.png
index d9ec745..45ed7ca 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_null.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_null.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_out.png
deleted file mode 100644
index 11ffbde..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_sync.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_sync.png
index ed31e8e..2dc2b17 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_sync.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_sync.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_sync_error.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_sync_error.png
deleted file mode 100644
index 6583878..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_sync_error.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_tty_mode.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_tty_mode.png
index a2aadd9..ece3450 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_tty_mode.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_tty_mode.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_in.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_in.png
deleted file mode 100644
index 2bb923e..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_inout.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_inout.png
deleted file mode 100644
index 783ad175..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_out.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_out.png
deleted file mode 100644
index e499f9d..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_0.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_0.png
index 7a39a97..0060eba 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_0.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_1.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_1.png
deleted file mode 100644
index 6b46001..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_1.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_1_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_1_fully.png
index ca49f46..faf4153 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_1_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_2.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_2.png
deleted file mode 100644
index 4ba2761..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_2.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_2_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_2_fully.png
index 597c214..6a25705 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_2_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_3.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_3.png
deleted file mode 100644
index 965e42c..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_3.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_3_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_3_fully.png
index 810a6b2..c609847 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_3_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_4.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_4.png
deleted file mode 100644
index 2994c72..0000000
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_4.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_4_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_4_fully.png
index 931daed..6248cfd 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_4_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_4_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_null.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_null.png
index 117cf19..8c3e896 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_null.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_wifi_signal_null.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_bg_tile.png b/packages/SystemUI/res/drawable-hdpi/status_bar_bg_tile.png
deleted file mode 100644
index aee197c..0000000
--- a/packages/SystemUI/res/drawable-hdpi/status_bar_bg_tile.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_close_off.9.png b/packages/SystemUI/res/drawable-hdpi/status_bar_close_off.9.png
index 0c301ab..6feb622 100644
--- a/packages/SystemUI/res/drawable-hdpi/status_bar_close_off.9.png
+++ b/packages/SystemUI/res/drawable-hdpi/status_bar_close_off.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.png b/packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.png
index ec0424a..42c773d 100644
--- a/packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.png
+++ b/packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_expand_default.png b/packages/SystemUI/res/drawable-hdpi/status_bar_expand_default.png
deleted file mode 100644
index 017145e..0000000
--- a/packages/SystemUI/res/drawable-hdpi/status_bar_expand_default.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_expand_pressed.png b/packages/SystemUI/res/drawable-hdpi/status_bar_expand_pressed.png
deleted file mode 100644
index 7466d1d..0000000
--- a/packages/SystemUI/res/drawable-hdpi/status_bar_expand_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_hr.9.png b/packages/SystemUI/res/drawable-hdpi/status_bar_hr.9.png
deleted file mode 100644
index f5e6031..0000000
--- a/packages/SystemUI/res/drawable-hdpi/status_bar_hr.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/title_bar_shadow.9.png b/packages/SystemUI/res/drawable-hdpi/title_bar_shadow.9.png
deleted file mode 100644
index 4650417..0000000
--- a/packages/SystemUI/res/drawable-hdpi/title_bar_shadow.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notifications_normal.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notifications_normal.png
deleted file mode 100644
index a937a7d..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notifications_normal.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_clear_normal.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_clear_normal.png
index b0cca26..c526433 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_clear_normal.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_clear_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_clear_pressed.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_clear_pressed.png
deleted file mode 100644
index f9489bb..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_clear_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_open_normal.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_open_normal.png
index d26aab0..13f6b7f 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_open_normal.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_open_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_open_pressed.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_open_pressed.png
deleted file mode 100644
index c02c794..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_open_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_quicksettings_normal.png
index fb8c108..ecdb240 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_quicksettings_normal.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_quicksettings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_quicksettings_pressed.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_quicksettings_pressed.png
deleted file mode 100644
index 293debc..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_notify_quicksettings_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_airplane_off.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_airplane_off.png
index 1403416..d37e446 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_airplane_off.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_airplane_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_airplane_on.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_airplane_on.png
index c35c34d..6158c01 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_airplane_on.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_airplane_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_default_user.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_default_user.png
index 28df7e82..54afe32 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_default_user.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_default_user.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_0.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_0.png
index 3cc2ab4..d924756 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_0.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_1.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_1.png
index 258e49b..b6388e1 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_1.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_1x.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_1x.png
index 075250a..969bff4 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_1x.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_2.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_2.png
index b485967..610a018 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_2.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_3.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_3.png
index a9e0a06..badebf5 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_3.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_3g.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_3g.png
index b03296c..ff96e40 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_3g.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_4.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_4.png
index 2974c2f..52c9a74 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_4.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_4g.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_4g.png
index 58b84fc..312a384 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_4g.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_e.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_e.png
index 6a4da0d..1211e0d 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_e.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_0.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_0.png
index 4e2cb12..8177ef9 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_0.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_1.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_1.png
index abadd36..ce85449 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_1.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_1x.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_1x.png
index a644516..3226db6 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_1x.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_2.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_2.png
index dd52748..ec4b0a6 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_2.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_3.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_3.png
index ecbed41..1498198 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_3.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_3g.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_3g.png
index 6471056..99484b1 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_3g.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_4.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_4.png
index 964574d..656f9ef 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_4.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_4g.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_4g.png
index e34a1ab..f4f0035 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_4g.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_e.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_e.png
index 2454d81..935a743 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_e.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_g.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_g.png
index d3e9a16..5510f6b 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_g.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_h.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_h.png
index 43bccb3..c21352c 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_h.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_lte.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_lte.png
index 515788a..9298dae 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_lte.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_lte.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_r.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_r.png
index 071e569..da4093e 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_r.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_full_r.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_g.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_g.png
index b8b298b..b65abc6 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_g.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_h.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_h.png
index fb633cc..08e21d2 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_h.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_in.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_in.png
deleted file mode 100644
index fb08a0c..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_inout.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_inout.png
deleted file mode 100644
index 013881f..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_lte.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_lte.png
index 58327c1..464ebbc 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_lte.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_lte.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_no_network.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_no_network.png
index f0e3410..c532510 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_no_network.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_no_network.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_no_signal.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_no_signal.png
index 7c22391..f87944f 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_no_signal.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_no_signal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_out.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_out.png
deleted file mode 100644
index a6ed1f9..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_r.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_r.png
index d4ecfb9..37da1f4 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_r.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_qs_signal_r.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back.png
index 782ebfe..3f7c4b0 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_land.png
index efca67e..956bb7c 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_recent.png
index 677b471..86e2947 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_recent_land.png
index 478b9ca..d8ab8ea 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_connected_1x.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_connected_1x.png
deleted file mode 100644
index bbf897f..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_connected_1x.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_connected_3g.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_connected_3g.png
deleted file mode 100644
index 292f5b7..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_connected_3g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_connected_4g.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_connected_4g.png
deleted file mode 100644
index 851892c..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_connected_4g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_connected_e.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_connected_e.png
deleted file mode 100644
index 8ad379e..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_connected_e.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_connected_g.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_connected_g.png
deleted file mode 100644
index ca1800c..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_connected_g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_connected_h.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_connected_h.png
deleted file mode 100644
index 1e71680..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_connected_h.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_connected_lte.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_connected_lte.png
deleted file mode 100644
index 66dc694..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_connected_lte.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_connected_roam.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_connected_roam.png
deleted file mode 100644
index b1cb4b8..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_connected_roam.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_1x.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_1x.png
index 983ba67..3d82daf 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_1x.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_3g.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_3g.png
index fa5ffe9..dfbf1a4 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_3g.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_4g.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_4g.png
index 859adb9..85721db 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_4g.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_e.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_e.png
index 0d78728..4a2421c 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_e.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_g.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_g.png
index 5290dc4..acc98b7 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_g.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_h.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_h.png
index f034fbfd..64653eb 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_h.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_lte.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_lte.png
index 8078424..f440755 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_lte.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_lte.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_roam.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_roam.png
new file mode 100644
index 0000000..ffb58ca
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_data_fully_connected_roam.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_ringer_silent.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_ringer_silent.png
index 6872ec8..f3e9da2 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_ringer_silent.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_ringer_silent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_ringer_vibrate.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_ringer_vibrate.png
index 98520d3..a90aef9 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_ringer_vibrate.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_ringer_vibrate.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_0.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_0.png
index 733563d..b477332 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_0.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_0_fully.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_0_fully.png
index 3ac0231..b477332 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_0_fully.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_0_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_1.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_1.png
deleted file mode 100644
index 50a3078..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_1.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_1_fully.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_1_fully.png
index 9e353da..36cb7e5 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_1_fully.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_2.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_2.png
deleted file mode 100644
index 5ff0ac6..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_2.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_2_fully.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_2_fully.png
index 91ca89a..cc30aa1 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_2_fully.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_3.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_3.png
deleted file mode 100644
index 784c5da..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_3.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_3_fully.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_3_fully.png
index 484d4b8..6f0b419 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_3_fully.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_4.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_4.png
deleted file mode 100644
index db06343..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_4.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_4_fully.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_4_fully.png
index 62130a0..01d47c5 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_4_fully.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_4_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_flightmode.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_flightmode.png
index 44d1afb..5171333 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_flightmode.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_flightmode.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_in.png
deleted file mode 100644
index f2bd618..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_inout.png
deleted file mode 100644
index 468dec9..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_null.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_null.png
index 7bbe2cc..cd4056c 100644
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_null.png
+++ b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_null.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_out.png
deleted file mode 100644
index b2f7f59..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/stat_sys_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notifications_normal.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notifications_normal.png
deleted file mode 100644
index 78c4a5f..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notifications_normal.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_clear_normal.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_clear_normal.png
index a9dbc93..d13bc69 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_clear_normal.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_clear_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_clear_pressed.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_clear_pressed.png
deleted file mode 100644
index 5bba00f..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_clear_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_open_normal.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_open_normal.png
index b38ddd6..c98911c 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_open_normal.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_open_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_open_pressed.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_open_pressed.png
deleted file mode 100644
index 032ce42..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_open_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_quicksettings_normal.png
index d815761..bb99022 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_quicksettings_normal.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_quicksettings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_quicksettings_pressed.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_quicksettings_pressed.png
deleted file mode 100644
index 369bb61..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_notify_quicksettings_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_airplane_off.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_airplane_off.png
index 6587c2d..d5e1da4 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_airplane_off.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_airplane_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_airplane_on.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_airplane_on.png
index 833b7f0..c37ba79 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_airplane_on.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_airplane_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_default_user.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_default_user.png
index 16743ef..2495830 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_default_user.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_default_user.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_0.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_0.png
index c8020e0..cdf76e2 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_0.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_1.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_1.png
index a968e96..7116084 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_1.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_1x.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_1x.png
index 712cce4..8596aa6 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_1x.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_2.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_2.png
index 5ac3715..1b81c42 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_2.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_3.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_3.png
index 8b4c97c..03591c2a 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_3.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_3g.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_3g.png
index 835219c..ee72967 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_3g.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_4.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_4.png
index 7fea77c..162315c 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_4.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_4g.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_4g.png
index ec861fa..c472f2b 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_4g.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_e.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_e.png
index 3bef9e7..e4bf4e2 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_e.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_0.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_0.png
index 31637c2..d41a2c7 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_0.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_1.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_1.png
index 4bedf72..d45c0ad 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_1.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_1x.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_1x.png
index 0cb5f26..e5e2c27 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_1x.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_2.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_2.png
index c779281..2f21063 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_2.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_3.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_3.png
index 7e0f98d..db913dd 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_3.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_3g.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_3g.png
index c258489..e1760b4 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_3g.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_4.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_4.png
index d479043..c098fd9 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_4.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_4g.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_4g.png
index e1ce328..d084a6b7 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_4g.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_e.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_e.png
index b1d5d5c..5c2e8e5 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_e.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_g.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_g.png
index b907713..f69c1f7 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_g.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_h.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_h.png
index 6396b64..066efdd 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_h.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_lte.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_lte.png
index 50e5011..d3b51c1 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_lte.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_lte.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_r.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_r.png
index fd3b644..4fcc7bc 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_r.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_full_r.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_g.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_g.png
index 07f514c..98b0104 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_g.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_h.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_h.png
index 9ccd5aa..fc19c7a 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_h.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_in.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_in.png
deleted file mode 100644
index efee374..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_inout.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_inout.png
deleted file mode 100644
index e69f3f7..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_lte.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_lte.png
index bb1de06..2250282 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_lte.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_lte.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_no_network.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_no_network.png
index f465084..5ec4543 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_no_network.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_no_network.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_no_signal.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_no_signal.png
index dc52a7b..b8f137c 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_no_signal.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_no_signal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_out.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_out.png
deleted file mode 100644
index 69f15e3..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_r.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_r.png
index bf1f50e..8290e1b 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_r.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_qs_signal_r.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back.png
index a1b8062..a53aef1 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_land.png
index 23318ae..e1b2145 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_recent.png
index fcdbefe..dffc059 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_recent_land.png
index 7f0cc51..c0209b0 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_connected_1x.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_connected_1x.png
deleted file mode 100644
index f6d53bb..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_connected_1x.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_connected_3g.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_connected_3g.png
deleted file mode 100644
index 2fec581..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_connected_3g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_connected_4g.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_connected_4g.png
deleted file mode 100644
index df46db2..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_connected_4g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_connected_e.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_connected_e.png
deleted file mode 100644
index d556d57..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_connected_e.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_connected_g.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_connected_g.png
deleted file mode 100644
index 546cff9..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_connected_g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_connected_h.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_connected_h.png
deleted file mode 100644
index 0ed7558..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_connected_h.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_connected_lte.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_connected_lte.png
deleted file mode 100644
index 6de14dc..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_connected_lte.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_connected_roam.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_connected_roam.png
deleted file mode 100644
index 0f0cf49..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_connected_roam.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_1x.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_1x.png
index 2ac1a96..0d97960 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_1x.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_3g.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_3g.png
index 2625fab..f8e06e1 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_3g.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_4g.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_4g.png
index 17a77b1..35be266 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_4g.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_e.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_e.png
index e482a26..64727d3 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_e.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_g.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_g.png
index 05628d0..3b14d98 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_g.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_h.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_h.png
index 7dc5d96..c51c4b1 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_h.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_lte.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_lte.png
index 17ca21a..867a014 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_lte.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_lte.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_roam.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_roam.png
new file mode 100644
index 0000000..c54ceba
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_data_fully_connected_roam.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_ringer_silent.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_ringer_silent.png
index 66b4741..b05bf78 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_ringer_silent.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_ringer_silent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_ringer_vibrate.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_ringer_vibrate.png
index f8abf25..2f782cf 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_ringer_vibrate.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_ringer_vibrate.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_0.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_0.png
index 9be8d23..6f457e0 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_0.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_0_fully.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_0_fully.png
index 0002165..6f457e0 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_0_fully.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_0_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_1.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_1.png
deleted file mode 100644
index d142737..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_1.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_1_fully.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_1_fully.png
index dc31490..45d733e 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_1_fully.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_2.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_2.png
deleted file mode 100644
index 4e5b7d3..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_2.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_2_fully.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_2_fully.png
index 6acb475..093387a 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_2_fully.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_3.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_3.png
deleted file mode 100644
index 509d1752..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_3.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_3_fully.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_3_fully.png
index 5791615..2f32c4c 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_3_fully.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_4.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_4.png
deleted file mode 100644
index 01b27ec..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_4.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_4_fully.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_4_fully.png
index c970e0e..8e9ba9c 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_4_fully.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_4_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_flightmode.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_flightmode.png
index 9070357..1b45762 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_flightmode.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_flightmode.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_in.png
deleted file mode 100644
index e0b0f9b..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_inout.png
deleted file mode 100644
index 2fb3c2e..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_null.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_null.png
index 8691360..c18d103 100644
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_null.png
+++ b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_null.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_out.png
deleted file mode 100644
index 0fe8012..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/stat_sys_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back.png
index 194a843..2d8f81d 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back_land.png
index ed08779..61c6d11 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_recent.png
index 542a93b..a67ed6d 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_recent_land.png
index e96f340..6101333 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-hdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back.png
index a345a4e..90eece6 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back_land.png
index 96ea0c9..382cf23 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_recent.png
index 70dc8af..ca1c8c4 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_recent_land.png
index db4d907..cfef88d 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-mdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back.png
index 9f9afd4..a4b3b37 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back_land.png
index cc376c4..ee5f623 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_recent.png
index ea4a8ca..ca3c541 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_recent_land.png
index 73ef87b..78d4490 100644
--- a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back.png
new file mode 100644
index 0000000..3d21350
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back_land.png
new file mode 100644
index 0000000..40fbaec
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_recent.png
new file mode 100644
index 0000000..77bef31
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_recent_land.png
new file mode 100644
index 0000000..d79f5b7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-sw600dp-xxhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_0.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_0.png
deleted file mode 100644
index db07305..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_0.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_0_fully.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_0_fully.png
deleted file mode 100644
index 4518ad5..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_0_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_1.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_1.png
deleted file mode 100644
index 3b6f74ad..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_1.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_1_fully.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_1_fully.png
deleted file mode 100644
index 396d51d..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_1_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_2.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_2.png
deleted file mode 100644
index bb90a95..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_2.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_2_fully.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_2_fully.png
deleted file mode 100644
index 34dc19f..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_2_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_3.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_3.png
deleted file mode 100644
index 64c2de2..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_3.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_3_fully.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_3_fully.png
deleted file mode 100644
index 9d93d2b..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_3_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_4.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_4.png
deleted file mode 100644
index 28ae311..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_4.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_4_fully.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_4_fully.png
deleted file mode 100644
index cd4f706..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_in.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_in.png
deleted file mode 100644
index cbce322..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_inout.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_inout.png
deleted file mode 100644
index 6788da8..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_null.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_null.png
deleted file mode 100644
index 0f00fb0..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_null.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_out.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_out.png
deleted file mode 100644
index db05c5f..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-hdpi/ic_sysbar_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_0.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_0.png
deleted file mode 100644
index 9b99940..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_0.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_0_fully.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_0_fully.png
deleted file mode 100644
index 2cd8c90..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_0_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_1.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_1.png
deleted file mode 100644
index f5363c3..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_1.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_1_fully.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_1_fully.png
deleted file mode 100644
index ded5029..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_1_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_2.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_2.png
deleted file mode 100644
index 01f4eb0..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_2.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_2_fully.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_2_fully.png
deleted file mode 100644
index 9963e97..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_2_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_3.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_3.png
deleted file mode 100644
index 3123cc9..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_3.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_3_fully.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_3_fully.png
deleted file mode 100644
index 34363fa..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_3_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_4.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_4.png
deleted file mode 100644
index 186844c..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_4.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_4_fully.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_4_fully.png
deleted file mode 100644
index 680f806..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_in.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_in.png
deleted file mode 100644
index 4d5bb0b..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_inout.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_inout.png
deleted file mode 100644
index 253d15c..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_null.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_null.png
deleted file mode 100644
index 5d688aa..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_null.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_out.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_out.png
deleted file mode 100644
index 8198fdc..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-mdpi/ic_sysbar_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_0.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_0.png
deleted file mode 100644
index a8691dc..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_0.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_0_fully.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_0_fully.png
deleted file mode 100644
index 77ade2f..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_0_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_1.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_1.png
deleted file mode 100644
index 0974b2c..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_1.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_1_fully.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_1_fully.png
deleted file mode 100644
index 4be5612..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_1_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_2.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_2.png
deleted file mode 100644
index 79f8b88..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_2.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_2_fully.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_2_fully.png
deleted file mode 100644
index 6167246..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_2_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_3.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_3.png
deleted file mode 100644
index d2ecd47..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_3.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_3_fully.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_3_fully.png
deleted file mode 100644
index 92871c3..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_3_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_4.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_4.png
deleted file mode 100644
index 4b86ca4..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_4.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_4_fully.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_4_fully.png
deleted file mode 100644
index 200d1cb..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_in.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_in.png
deleted file mode 100644
index f4c5281..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_inout.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_inout.png
deleted file mode 100644
index 42e2170..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_null.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_null.png
deleted file mode 100644
index eaff2c0..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_null.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_out.png b/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_out.png
deleted file mode 100644
index 9feb041..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw720dp-xhdpi/ic_sysbar_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notifications_normal.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notifications_normal.png
deleted file mode 100644
index a2787eb..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notifications_normal.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_clear_normal.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_clear_normal.png
index 53a74c9..a137a80 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_clear_normal.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_clear_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_clear_pressed.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_clear_pressed.png
deleted file mode 100644
index c9d50c0..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_clear_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_open_normal.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_open_normal.png
index 57faad8..d9d8b13 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_open_normal.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_open_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_open_pressed.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_open_pressed.png
deleted file mode 100644
index c736dcd..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_open_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_quicksettings_normal.png
index c8ff8a6..09e0a3c 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_quicksettings_normal.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_quicksettings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_quicksettings_pressed.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_quicksettings_pressed.png
deleted file mode 100644
index 3add352..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_notify_quicksettings_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_airplane_off.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_airplane_off.png
index d16e3d3..8d53a7c 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_airplane_off.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_airplane_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_airplane_on.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_airplane_on.png
index 53523f6..d59f0e92 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_airplane_on.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_airplane_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_default_user.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_default_user.png
index 73db61d..0d5b50c 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_default_user.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_default_user.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_0.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_0.png
index 3f87163..10c6905 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_0.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_1.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_1.png
index 5fae5fe..a5d68e1 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_1.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_1x.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_1x.png
index 24c8fde..69d0461 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_1x.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_2.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_2.png
index 2e68d0f..df0948b 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_2.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_3.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_3.png
index 01af7f9..4409267 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_3.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_3g.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_3g.png
index f5e4b7e..de0181b 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_3g.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_4.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_4.png
index 2368f71..c3e4181 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_4.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_4g.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_4g.png
index eeeed04..69a950d 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_4g.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_e.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_e.png
index 6188ec3..04948ae 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_e.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_0.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_0.png
index cd41a810..ef8c677 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_0.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_1.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_1.png
index 637c8bb..53bf4de 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_1.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_1x.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_1x.png
index c8348d4..5733b5d 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_1x.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_2.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_2.png
index b499d01..8d3dede 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_2.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_3.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_3.png
index 589f41b..52df2f7 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_3.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_3g.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_3g.png
index c756e15..503cc78 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_3g.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_4.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_4.png
index 0208cdb..b5c176d 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_4.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_4g.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_4g.png
index 9cd1154..4c169ec 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_4g.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_e.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_e.png
index 01c8876..5d09b042 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_e.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_g.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_g.png
index 5516e0f..94f332e 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_g.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_h.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_h.png
index 8f411c3..1d2594b 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_h.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_lte.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_lte.png
index 0d344b9..22eec00 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_lte.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_lte.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_r.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_r.png
index ef65b74..99efc08 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_r.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_full_r.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_g.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_g.png
index 6e51ecb..a6b0393 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_g.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_h.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_h.png
index 7c8155c..ede64f1 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_h.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_in.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_in.png
deleted file mode 100644
index fd5f0e52..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_inout.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_inout.png
deleted file mode 100644
index 1f04910..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_lte.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_lte.png
index ac010bf..e82ba13 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_lte.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_lte.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_no_network.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_no_network.png
index 74b5b92..7097b26 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_no_network.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_no_network.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_no_signal.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_no_signal.png
index bcdd82d..43fbaeb 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_no_signal.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_no_signal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_out.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_out.png
deleted file mode 100644
index d95b997..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_r.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_r.png
index 1e6aef5..83e7206 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_r.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_qs_signal_r.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back.png
index 633d864..61b4569 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_land.png
index 7b9613c..1a0312b 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_recent.png
index 4665e2a..d04916e 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_recent_land.png
index 6d33a6e..d940d34 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_connected_1x.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_connected_1x.png
deleted file mode 100644
index d3b57c3..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_connected_1x.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_connected_3g.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_connected_3g.png
deleted file mode 100644
index cc2256f..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_connected_3g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_connected_4g.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_connected_4g.png
deleted file mode 100644
index e1f1ab9..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_connected_4g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_connected_e.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_connected_e.png
deleted file mode 100644
index 5a04dde..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_connected_e.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_connected_g.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_connected_g.png
deleted file mode 100644
index 65c4fe1..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_connected_g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_connected_h.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_connected_h.png
deleted file mode 100644
index 066405f..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_connected_h.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_connected_lte.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_connected_lte.png
deleted file mode 100644
index b704cdf..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_connected_lte.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_connected_roam.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_connected_roam.png
deleted file mode 100644
index 97d5d5b7..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_connected_roam.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_1x.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_1x.png
index a3d2b35..8a72b0a 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_1x.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_3g.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_3g.png
index 8e13caa..4f1632d 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_3g.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_4g.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_4g.png
index 23fcf42..fd9eb8b 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_4g.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_e.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_e.png
index 4370c22..aa0677e 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_e.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_g.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_g.png
index 3504a75..cf1f099 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_g.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_h.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_h.png
index 21fc58c..441e9dd 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_h.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_lte.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_lte.png
index 3cb8f3e..2614d61 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_lte.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_lte.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_roam.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_roam.png
new file mode 100644
index 0000000..d8db235
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_data_fully_connected_roam.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_ringer_silent.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_ringer_silent.png
index 629b5f8..8299301 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_ringer_silent.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_ringer_silent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_ringer_vibrate.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_ringer_vibrate.png
index 8e3e8b4..e171d53 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_ringer_vibrate.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_ringer_vibrate.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_0.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_0.png
index 62d1d34..60ede0a 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_0.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_0_fully.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_0_fully.png
index b263831..a22fa28 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_0_fully.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_0_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_1.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_1.png
deleted file mode 100644
index 6f9620e..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_1.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_1_fully.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_1_fully.png
index 7adae9f..26a0543 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_1_fully.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_2.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_2.png
deleted file mode 100644
index 906b418..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_2.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_2_fully.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_2_fully.png
index ebdf136..ec31162 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_2_fully.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_3.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_3.png
deleted file mode 100644
index 1a2ab1c..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_3.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_3_fully.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_3_fully.png
index c0170a6..26cd26f 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_3_fully.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_4.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_4.png
deleted file mode 100644
index 2cc587b..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_4.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_4_fully.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_4_fully.png
index 11a26c6..25ed626 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_4_fully.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_4_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_flightmode.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_flightmode.png
index 9ede64c..fcbfac1 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_flightmode.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_flightmode.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_in.png
deleted file mode 100644
index 3afb5b2..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_inout.png
deleted file mode 100644
index fcf7f6e..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_null.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_null.png
index 815de33..37da3339 100644
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_null.png
+++ b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_null.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_out.png
deleted file mode 100644
index f153216..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/stat_sys_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_notify_clear_normal.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_notify_clear_normal.png
new file mode 100644
index 0000000..8da7945
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_notify_clear_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_notify_open_normal.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_notify_open_normal.png
new file mode 100644
index 0000000..c0855b5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_notify_open_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_notify_quicksettings_normal.png
new file mode 100644
index 0000000..e3fb992
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_notify_quicksettings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_airplane_off.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_airplane_off.png
new file mode 100644
index 0000000..255b39d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_airplane_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_airplane_on.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_airplane_on.png
new file mode 100644
index 0000000..a2342fc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_airplane_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_default_user.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_default_user.png
new file mode 100644
index 0000000..07f16c3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_default_user.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_0.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_0.png
new file mode 100644
index 0000000..5c378ef
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_1.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_1.png
new file mode 100644
index 0000000..19809c2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_1x.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_1x.png
new file mode 100644
index 0000000..cd34141
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_2.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_2.png
new file mode 100644
index 0000000..5691f96
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_3.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_3.png
new file mode 100644
index 0000000..56768dd
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_3g.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_3g.png
new file mode 100644
index 0000000..094d4ca
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_4.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_4.png
new file mode 100644
index 0000000..55ec5b8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_4g.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_4g.png
new file mode 100644
index 0000000..f92aac2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_e.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_e.png
new file mode 100644
index 0000000..4329b67
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_0.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_0.png
new file mode 100644
index 0000000..6db5d0d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_1.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_1.png
new file mode 100644
index 0000000..41c1f89
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_1x.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_1x.png
new file mode 100644
index 0000000..dea2bf2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_2.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_2.png
new file mode 100644
index 0000000..4faff9b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_3.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_3.png
new file mode 100644
index 0000000..2e84aa1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_3g.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_3g.png
new file mode 100644
index 0000000..79c97fa
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_4.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_4.png
new file mode 100644
index 0000000..742b5bb
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_4g.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_4g.png
new file mode 100644
index 0000000..3b297af
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_e.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_e.png
new file mode 100644
index 0000000..c5a7b8c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_g.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_g.png
new file mode 100644
index 0000000..077b754
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_h.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_h.png
new file mode 100644
index 0000000..7907b02
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_lte.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_lte.png
new file mode 100644
index 0000000..190d3f4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_lte.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_r.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_r.png
new file mode 100644
index 0000000..7c70da6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_full_r.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_g.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_g.png
new file mode 100644
index 0000000..3577fbb
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_h.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_h.png
new file mode 100644
index 0000000..0aae48b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_lte.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_lte.png
new file mode 100644
index 0000000..2d2b106
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_lte.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_no_network.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_no_network.png
new file mode 100644
index 0000000..330b96b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_no_network.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_no_signal.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_no_signal.png
new file mode 100644
index 0000000..30fe798
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_no_signal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_r.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_r.png
new file mode 100644
index 0000000..a2003fc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_qs_signal_r.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back.png
new file mode 100644
index 0000000..8715a11
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_land.png
new file mode 100644
index 0000000..487a0b1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_recent.png
new file mode 100644
index 0000000..a7cff47
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_recent_land.png
new file mode 100644
index 0000000..0a60bb6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_data_fully_connected_1x.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_data_fully_connected_1x.png
new file mode 100644
index 0000000..c4507c7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_data_fully_connected_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_data_fully_connected_3g.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_data_fully_connected_3g.png
new file mode 100644
index 0000000..bfef649
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_data_fully_connected_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_data_fully_connected_4g.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_data_fully_connected_4g.png
new file mode 100644
index 0000000..c39658d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_data_fully_connected_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_data_fully_connected_e.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_data_fully_connected_e.png
new file mode 100644
index 0000000..0f2e79c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_data_fully_connected_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_data_fully_connected_g.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_data_fully_connected_g.png
new file mode 100644
index 0000000..d37b2929
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_data_fully_connected_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_data_fully_connected_h.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_data_fully_connected_h.png
new file mode 100644
index 0000000..96a1463
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_data_fully_connected_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_data_fully_connected_lte.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_data_fully_connected_lte.png
new file mode 100644
index 0000000..9b5dbfa
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_data_fully_connected_lte.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_data_fully_connected_roam.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_data_fully_connected_roam.png
new file mode 100644
index 0000000..cc6155f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_data_fully_connected_roam.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_ringer_silent.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_ringer_silent.png
new file mode 100644
index 0000000..1c847da2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_ringer_silent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_ringer_vibrate.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_ringer_vibrate.png
new file mode 100644
index 0000000..d0ab910
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_ringer_vibrate.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_0.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_0.png
new file mode 100644
index 0000000..5950ef8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_0_fully.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_0_fully.png
new file mode 100644
index 0000000..a930649
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_0_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_1_fully.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_1_fully.png
new file mode 100644
index 0000000..9245462
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_2_fully.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_2_fully.png
new file mode 100644
index 0000000..b5b8884
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_3_fully.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_3_fully.png
new file mode 100644
index 0000000..11b5832
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_4_fully.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_4_fully.png
new file mode 100644
index 0000000..ff8246e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_4_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_flightmode.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_flightmode.png
new file mode 100644
index 0000000..4555731
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_flightmode.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_null.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_null.png
new file mode 100644
index 0000000..e0c5408
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/stat_sys_signal_null.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/alert_bar_background_normal.9.png b/packages/SystemUI/res/drawable-mdpi/alert_bar_background_normal.9.png
deleted file mode 100644
index b94b144..0000000
--- a/packages/SystemUI/res/drawable-mdpi/alert_bar_background_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/alert_bar_background_pressed.9.png b/packages/SystemUI/res/drawable-mdpi/alert_bar_background_pressed.9.png
deleted file mode 100644
index b94b144..0000000
--- a/packages/SystemUI/res/drawable-mdpi/alert_bar_background_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/arrow_dashed.png b/packages/SystemUI/res/drawable-mdpi/arrow_dashed.png
deleted file mode 100644
index c17c668d..0000000
--- a/packages/SystemUI/res/drawable-mdpi/arrow_dashed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/battery_low_battery.png b/packages/SystemUI/res/drawable-mdpi/battery_low_battery.png
index ecc909a..e865f4c 100644
--- a/packages/SystemUI/res/drawable-mdpi/battery_low_battery.png
+++ b/packages/SystemUI/res/drawable-mdpi/battery_low_battery.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/btn_cling_normal.9.png b/packages/SystemUI/res/drawable-mdpi/btn_cling_normal.9.png
deleted file mode 100644
index 43a407e..0000000
--- a/packages/SystemUI/res/drawable-mdpi/btn_cling_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/btn_cling_pressed.9.png b/packages/SystemUI/res/drawable-mdpi/btn_cling_pressed.9.png
deleted file mode 100644
index bf0c8cb..0000000
--- a/packages/SystemUI/res/drawable-mdpi/btn_cling_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/btn_default_small_normal.9.png b/packages/SystemUI/res/drawable-mdpi/btn_default_small_normal.9.png
deleted file mode 100644
index 9b59b05..0000000
--- a/packages/SystemUI/res/drawable-mdpi/btn_default_small_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/btn_default_small_normal_disable.9.png b/packages/SystemUI/res/drawable-mdpi/btn_default_small_normal_disable.9.png
deleted file mode 100644
index b517af6..0000000
--- a/packages/SystemUI/res/drawable-mdpi/btn_default_small_normal_disable.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/btn_default_small_normal_disable_focused.9.png b/packages/SystemUI/res/drawable-mdpi/btn_default_small_normal_disable_focused.9.png
deleted file mode 100644
index 019f33a..0000000
--- a/packages/SystemUI/res/drawable-mdpi/btn_default_small_normal_disable_focused.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/btn_default_small_pressed.9.png b/packages/SystemUI/res/drawable-mdpi/btn_default_small_pressed.9.png
deleted file mode 100644
index 6ce1bd3..0000000
--- a/packages/SystemUI/res/drawable-mdpi/btn_default_small_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/btn_default_small_selected.9.png b/packages/SystemUI/res/drawable-mdpi/btn_default_small_selected.9.png
deleted file mode 100644
index 0633543..0000000
--- a/packages/SystemUI/res/drawable-mdpi/btn_default_small_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/compat_mode_help_diagram.png b/packages/SystemUI/res/drawable-mdpi/compat_mode_help_diagram.png
deleted file mode 100644
index 5f08b52..0000000
--- a/packages/SystemUI/res/drawable-mdpi/compat_mode_help_diagram.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/compat_mode_help_divider_bottom.9.png b/packages/SystemUI/res/drawable-mdpi/compat_mode_help_divider_bottom.9.png
deleted file mode 100644
index b7f4523..0000000
--- a/packages/SystemUI/res/drawable-mdpi/compat_mode_help_divider_bottom.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/compat_mode_help_divider_top.9.png b/packages/SystemUI/res/drawable-mdpi/compat_mode_help_divider_top.9.png
deleted file mode 100644
index fae17b1..0000000
--- a/packages/SystemUI/res/drawable-mdpi/compat_mode_help_divider_top.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/compat_mode_help_icon.png b/packages/SystemUI/res/drawable-mdpi/compat_mode_help_icon.png
deleted file mode 100644
index e017e03..0000000
--- a/packages/SystemUI/res/drawable-mdpi/compat_mode_help_icon.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/hd_off.png b/packages/SystemUI/res/drawable-mdpi/hd_off.png
deleted file mode 100644
index 6c01b8a..0000000
--- a/packages/SystemUI/res/drawable-mdpi/hd_off.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/hd_on.png b/packages/SystemUI/res/drawable-mdpi/hd_on.png
deleted file mode 100644
index de878ef..0000000
--- a/packages/SystemUI/res/drawable-mdpi/hd_on.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/heads_up_window_bg.9.png b/packages/SystemUI/res/drawable-mdpi/heads_up_window_bg.9.png
new file mode 100644
index 0000000..a0ab991
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/heads_up_window_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_launcher_settings.png b/packages/SystemUI/res/drawable-mdpi/ic_launcher_settings.png
deleted file mode 100644
index 05cdd9a..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_launcher_settings.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notification_dnd.png b/packages/SystemUI/res/drawable-mdpi/ic_notification_dnd.png
deleted file mode 100644
index fd2bcb2..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_notification_dnd.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notification_open.png b/packages/SystemUI/res/drawable-mdpi/ic_notification_open.png
deleted file mode 100644
index 5661eaf..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_notification_open.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notification_overlay.9.png b/packages/SystemUI/res/drawable-mdpi/ic_notification_overlay.9.png
index 667b13d..7ae6079 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_notification_overlay.9.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notification_overlay.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notifications_normal.png b/packages/SystemUI/res/drawable-mdpi/ic_notifications_normal.png
deleted file mode 100644
index 62afe76..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_notifications_normal.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_normal.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_normal.png
index 5dacccb..7cb52e3 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_normal.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_pressed.png
deleted file mode 100644
index f1f6b00..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_open_normal.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_open_normal.png
index f04aab1..ae5d263 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_notify_open_normal.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_open_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_open_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_open_pressed.png
deleted file mode 100644
index 549c5efd..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_notify_open_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_normal.png
index 09d2c55..32fbed4 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_normal.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_pressed.png
deleted file mode 100644
index 322d1a7..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_rotation_off_normal.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_rotation_off_normal.png
deleted file mode 100644
index 77da014..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_notify_rotation_off_normal.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_rotation_off_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_rotation_off_pressed.png
deleted file mode 100644
index f132d5c..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_notify_rotation_off_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_rotation_on_normal.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_rotation_on_normal.png
deleted file mode 100644
index 1637209..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_notify_rotation_on_normal.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_rotation_on_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_rotation_on_pressed.png
deleted file mode 100644
index 4d8fbde..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_notify_rotation_on_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_settings_normal.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_settings_normal.png
index 44cfc5b..399db00 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_notify_settings_normal.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_settings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_settings_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_settings_pressed.png
deleted file mode 100644
index 0c3fdcd..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_notify_settings_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_airplane_off.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_airplane_off.png
index 2d0c479..31fbf40 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_airplane_off.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_airplane_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_airplane_on.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_airplane_on.png
index 6a2906e..251fc30 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_airplane_on.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_airplane_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_alarm_on.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_alarm_on.png
index d6590e2..27f08dd 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_alarm_on.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_alarm_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_auto_rotate.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_auto_rotate.png
index 46beb62..ac6c1cf0 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_auto_rotate.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_auto_rotate.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_0.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_0.png
index c581919..8dd3d4d 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_0.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_100.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_100.png
index 2f330f7..2a9bf50 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_100.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_15.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_15.png
index 2a1637c..f59ba48 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_15.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_28.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_28.png
index 8457c2b..12f16dd 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_28.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_43.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_43.png
index f72fe4a..649c89d 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_43.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_57.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_57.png
index 10e3275..95494e6 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_57.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_71.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_71.png
index ca1613c..dfd92ee 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_71.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_85.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_85.png
index 2bfe20d..dcabf3f 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_85.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_bolt.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_bolt.png
deleted file mode 100644
index b01d7d0..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_bolt.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_charge_100.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_charge_100.png
index 480f579..2a05827 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_charge_100.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_charge_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_charge_15.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_charge_15.png
index cee2a44..86d1158 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_charge_15.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_charge_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_charge_28.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_charge_28.png
index f2056db..076add9 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_charge_28.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_charge_28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_charge_43.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_charge_43.png
index 697d4ec..4bdae3c 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_charge_43.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_charge_43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_charge_57.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_charge_57.png
index 9c53dd4..8353d91 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_charge_57.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_charge_57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_charge_71.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_charge_71.png
index c967999..91bd62e 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_charge_71.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_charge_71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_charge_85.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_charge_85.png
index 8df8234..a36d25d 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_charge_85.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_charge_85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_unknown.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_unknown.png
index c3a4ab4..a2e3cc9 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_unknown.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_battery_unknown.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_bluetooth_not_connected.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_bluetooth_not_connected.png
index d0ce4f6..b01b27f 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_bluetooth_not_connected.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_bluetooth_not_connected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_bluetooth_off.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_bluetooth_off.png
index 2116449..426b33d 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_bluetooth_off.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_bluetooth_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_bluetooth_on.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_bluetooth_on.png
index 1cc6e62..0acf3a4 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_bluetooth_on.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_bluetooth_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_brightness_auto_off.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_brightness_auto_off.png
index df5987c9..74df151 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_brightness_auto_off.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_brightness_auto_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_brightness_auto_on.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_brightness_auto_on.png
index 753e9f7..56add92 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_brightness_auto_on.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_brightness_auto_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_certificate_info.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_certificate_info.png
new file mode 100644
index 0000000..3b49472
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_certificate_info.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_clock_circle.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_clock_circle.png
index 27904f2..3073986 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_clock_circle.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_clock_circle.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_clock_hour.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_clock_hour.png
index f7f8c42..2a0bc59 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_clock_hour.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_clock_hour.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_clock_minute.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_clock_minute.png
index fb17e5ab..9b1cc58 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_clock_minute.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_clock_minute.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_default_user.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_default_user.png
index d90bdd3..a35c30d 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_default_user.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_default_user.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_ime.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_ime.png
index 3263c55..8c2dc68 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_ime.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_location.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_location.png
index 79f1f470..e285bba 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_location.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_location.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_location_off.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_location_off.png
new file mode 100644
index 0000000..7c73ace
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_location_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_location_on.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_location_on.png
new file mode 100644
index 0000000..c6f41d2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_location_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_remote_display.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_remote_display.png
index 1ff9cbc..8e080ff 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_remote_display.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_remote_display.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_remote_display_connected.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_remote_display_connected.png
index 0ec78c0..780cfc8 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_remote_display_connected.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_remote_display_connected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_rotation_locked.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_rotation_locked.png
index b70df3d..3b7a284 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_rotation_locked.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_rotation_locked.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_settings.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_settings.png
index 673d2e0..021ae6d 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_settings.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_settings.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_0.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_0.png
index d46fced..3afbca4 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_0.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_1.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_1.png
index ef5179f..2994632 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_1.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_1x.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_1x.png
index 53dc47d..a89191f 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_1x.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_2.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_2.png
index 359f445..b111939 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_2.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_3.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_3.png
index 7ebebcd..98c8e25 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_3.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_3g.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_3g.png
index 88cf8b6..8a8e323 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_3g.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_4.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_4.png
index db72661..625dbd9 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_4.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_4g.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_4g.png
index 6022a6a..c1063a9 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_4g.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_e.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_e.png
index e493d3b..f145410 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_e.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_0.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_0.png
index 6668846..ea4ab18 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_0.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_1.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_1.png
index 5c8dc82..52faded 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_1.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_1x.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_1x.png
index 01560e8..2f76529 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_1x.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_2.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_2.png
index 3082ff0..bcf825d 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_2.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_3.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_3.png
index 7966be8..f9de3ef 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_3.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_3g.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_3g.png
index a78c4d6..244280b 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_3g.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_4.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_4.png
index dce07ae..f0bd70e 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_4.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_4g.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_4g.png
index 82bcb79..befe94d 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_4g.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_e.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_e.png
index 828a728..01a81ab 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_e.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_g.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_g.png
index f1a8017..abed290 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_g.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_h.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_h.png
index 9077d56..e4b1fad 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_h.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_lte.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_lte.png
index d819f5c..da8ebce 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_lte.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_lte.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_r.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_r.png
index d298624..776210b 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_r.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_full_r.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_g.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_g.png
index cb52c98..a5de26f 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_g.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_h.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_h.png
index 14550d5..b3d4524 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_h.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_in.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_in.png
index 4dd6401..da4ffa2 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_in.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_inout.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_inout.png
index 07ebd9c..e1c7972 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_inout.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_lte.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_lte.png
index bb1de06..0555eed 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_lte.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_lte.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_no_network.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_no_network.png
index cf2cc52..b27479a 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_no_network.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_no_network.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_no_signal.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_no_signal.png
index dcd2dbd..9441f61 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_no_signal.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_no_signal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_out.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_out.png
index d8eda87..b8c8b4e 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_out.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_r.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_r.png
index d26beb5..f1753d6 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_r.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_signal_r.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_usb_device.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_usb_device.png
index 6ac70fa..19b95dd 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_usb_device.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_usb_device.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_0.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_0.png
index 9ab044d..42210a6 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_0.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_1.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_1.png
index 1de33ba..60e38ad 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_1.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_2.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_2.png
index 34c916d..8983380 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_2.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_3.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_3.png
index 2f7a885..ff652df 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_3.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_4.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_4.png
index f11cc08..8dd9c43 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_4.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_full_1.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_full_1.png
index e78ab6b..092ddbb 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_full_1.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_full_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_full_2.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_full_2.png
index 1b025f26..e10a1da 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_full_2.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_full_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_full_3.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_full_3.png
index 3036c86..bd235ae 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_full_3.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_full_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_full_4.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_full_4.png
index de000eb..5873b37 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_full_4.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_full_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_in.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_in.png
index 4dd6401..5d0ad7c 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_in.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_inout.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_inout.png
index 07ebd9c..e1c7972 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_inout.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_no_network.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_no_network.png
index 72da3e8..7208427 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_no_network.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_no_network.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_not_connected.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_not_connected.png
index f606a60..fdf34bf 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_not_connected.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_not_connected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_out.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_out.png
index d8eda87..b8c8b4e 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_out.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_airplane_on.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_airplane_on.png
deleted file mode 100644
index c33271b..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_airplane_on.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
index a00bc5b..225d924 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime.png
index 72b5ffe..7779d57 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png
index 8605701..37d17d2 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_brightness.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_brightness.png
deleted file mode 100644
index 4dbca6d..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_brightness.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png
index dc3183b..5e70a07 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png
index 5dff6e7..39a0c07 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_default.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_default.png
deleted file mode 100644
index cf12bb9..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_default.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lights_out_dot_large.png
index 45183b0..4d9c21c 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lights_out_dot_large.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lights_out_dot_large.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lights_out_dot_small.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lights_out_dot_small.png
index 8169fba..9f0570a 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lights_out_dot_small.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lights_out_dot_small.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png
index cc65b07..5bbf3fe 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_land.png
index d0404bf..798f62f 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_quicksettings.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_quicksettings.png
deleted file mode 100644
index 238df06..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_quicksettings.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png
index b07f611..f8e549a 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png
index 47e209e..c7fda96 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_on.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_on.png
deleted file mode 100644
index 9c117ae..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_on.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_wifi_on.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_wifi_on.png
deleted file mode 100644
index 4f51201..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_wifi_on.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/pocket_drag_pattern.png b/packages/SystemUI/res/drawable-mdpi/pocket_drag_pattern.png
deleted file mode 100644
index 3370aeb..0000000
--- a/packages/SystemUI/res/drawable-mdpi/pocket_drag_pattern.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/recents_blue_glow.9.png b/packages/SystemUI/res/drawable-mdpi/recents_blue_glow.9.png
deleted file mode 100644
index 5744885..0000000
--- a/packages/SystemUI/res/drawable-mdpi/recents_blue_glow.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_dragging.9.png b/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_dragging.9.png
index 6f4d658..60dc3f2 100644
--- a/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_dragging.9.png
+++ b/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_dragging.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_normal.9.png b/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_normal.9.png
index f19dc93..4b7de52 100644
--- a/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_normal.9.png
+++ b/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_normal.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_press.9.png b/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_press.9.png
index 10e4fd2..7dfea4c 100644
--- a/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_press.9.png
+++ b/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_press.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/screenshot_panel.9.png b/packages/SystemUI/res/drawable-mdpi/screenshot_panel.9.png
index be1cd31..295e91f 100644
--- a/packages/SystemUI/res/drawable-mdpi/screenshot_panel.9.png
+++ b/packages/SystemUI/res/drawable-mdpi/screenshot_panel.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/search_light.png b/packages/SystemUI/res/drawable-mdpi/search_light.png
index 4b5b2a4..c355b6a 100644
--- a/packages/SystemUI/res/drawable-mdpi/search_light.png
+++ b/packages/SystemUI/res/drawable-mdpi/search_light.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_notify_image.png b/packages/SystemUI/res/drawable-mdpi/stat_notify_image.png
index f345ca7..a02e21c 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_notify_image.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_notify_image.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_notify_image_error.png b/packages/SystemUI/res/drawable-mdpi/stat_notify_image_error.png
index d95480d..4af2617 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_notify_image_error.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_notify_image_error.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_alarm.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_alarm.png
index 4b0a74f..c6dc466 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_alarm.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_alarm.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_0.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_0.png
index edf244a..edcb1b3 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_0.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_100.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_100.png
index 943332e..8e0ec0f 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_100.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_15.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_15.png
index d465337..b1b675b 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_15.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_28.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_28.png
index 4b0ad71..868bbbc 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_28.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_43.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_43.png
index 70c40e8..890129e 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_43.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_57.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_57.png
index aa0fde1..86279af 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_57.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_71.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_71.png
index 95688d0..de2aa4e 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_71.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_85.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_85.png
index ac3b5f3..c008d6f 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_85.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim0.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim0.png
index 31aa745..62ab39a 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim0.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim100.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim100.png
index 2773a70..4082a2c 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim100.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim15.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim15.png
index 4471eb9..8c1c15a 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim15.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim28.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim28.png
index 0c2f994..6ba3496 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim28.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim43.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim43.png
index 98a3931..4a91d65 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim43.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim57.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim57.png
index 7443b59..18d6198 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim57.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim71.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim71.png
index e791a88..a11e57e 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim71.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim85.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim85.png
index 51c106c..5a3a627 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim85.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_battery_charge_anim85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_bluetooth.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_bluetooth.png
index 53a7364..bd4e1ae 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_bluetooth.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_bluetooth.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_bluetooth_connected.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_bluetooth_connected.png
index 3451fff..e82c6e4 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_bluetooth_connected.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_bluetooth_connected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_1x.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_1x.png
deleted file mode 100644
index 5076cf9..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_1x.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_3g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_3g.png
deleted file mode 100644
index 3ab8470..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_3g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_4g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_4g.png
deleted file mode 100644
index 83538d4..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_4g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_e.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_e.png
deleted file mode 100644
index aa011ca..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_e.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_g.png
deleted file mode 100644
index 4cebc43..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_h.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_h.png
deleted file mode 100644
index bd2b4ed..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_h.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_lte.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_lte.png
deleted file mode 100644
index 6de14dc..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_lte.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_roam.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_roam.png
deleted file mode 100644
index 243dfea..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_connected_roam.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_1x.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_1x.png
index 8184f2c..36713ae 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_1x.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_3g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_3g.png
index 19780bd..1c9e313 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_3g.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_4g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_4g.png
index efba454..7b1b16f 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_4g.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_e.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_e.png
index a4455ae..02dc258 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_e.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_g.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_g.png
index e82f3f4..27417d8f 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_g.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_h.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_h.png
index f8e13ab..f3a805c 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_h.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_lte.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_lte.png
index 17ca21a..8a8c3d9 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_lte.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_lte.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_roam.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_roam.png
new file mode 100644
index 0000000..fb2a6b6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_fully_connected_roam.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_0.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_0.png
index a0c7a99..e5a8f95 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_0.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_0_fully.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_0_fully.png
index b1f1e5b..c1c2b5c 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_0_fully.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_0_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_1.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_1.png
index 8b31618..421eee8 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_1.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_1_fully.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_1_fully.png
index 1a62682..bfd2494 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_1_fully.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_2.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_2.png
index ff51551..b1af6786 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_2.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_2_fully.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_2_fully.png
index 0374142..9ad245b 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_2_fully.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_3.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_3.png
index 8f881f2..69a1a97 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_3.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_3_fully.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_3_fully.png
index 7870cee..d865673 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_3_fully.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_disconnected.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_disconnected.png
index 65404c2..6bd3189 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_disconnected.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_disconnected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_idle.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_idle.png
index 327f89d..f7f0e93 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_idle.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_data_wimax_signal_idle.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_device_access_location_found.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_device_access_location_found.png
new file mode 100644
index 0000000..2e24f6f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_device_access_location_found.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_gps_acquiring.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_gps_acquiring.png
deleted file mode 100644
index 81c0c10..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_gps_acquiring.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_no_sim.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_no_sim.png
index 24bee66..bdf0f67 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_no_sim.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_no_sim.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_ringer_silent.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_ringer_silent.png
index faefe36..1e05a91 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_ringer_silent.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_ringer_silent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_ringer_vibrate.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_ringer_vibrate.png
index 900a717..f4afa52 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_ringer_vibrate.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_ringer_vibrate.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_roaming_cdma_0.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_roaming_cdma_0.png
index 876d9ee..cb38896 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_roaming_cdma_0.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_roaming_cdma_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_roaming_cdma_flash_anim0.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_roaming_cdma_flash_anim0.png
deleted file mode 100644
index 436f16d..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_roaming_cdma_flash_anim0.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_roaming_cdma_flash_anim1.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_roaming_cdma_flash_anim1.png
deleted file mode 100644
index 876d9ee..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_roaming_cdma_flash_anim1.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_0.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_0.png
index d93a661..ca02605 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_0.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_0_fully.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_0_fully.png
index b39cc04..2dcbe28 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_0_fully.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_0_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_1.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_1.png
deleted file mode 100644
index 4305351..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_1.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_1_fully.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_1_fully.png
index 4305be2..fe71893 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_1_fully.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_2.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_2.png
deleted file mode 100644
index beb641b..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_2.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_2_fully.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_2_fully.png
index 7b8ddc2..a6c61ff 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_2_fully.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_3.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_3.png
deleted file mode 100644
index a4028cd..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_3.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_3_fully.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_3_fully.png
index fad1873..ba4a9d9 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_3_fully.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_4.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_4.png
deleted file mode 100644
index b5ed22b..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_4.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_4_fully.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_4_fully.png
index cca7bf3..79c2ec1 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_4_fully.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_4_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_flightmode.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_flightmode.png
index 5ce22de..14d1060 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_flightmode.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_flightmode.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_in.png
deleted file mode 100644
index 31c0936..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_inout.png
deleted file mode 100644
index 7e9b752..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_null.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_null.png
index 2cebe85..4548617 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_null.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_null.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_out.png
deleted file mode 100644
index 3209234d..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_sync.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_sync.png
index 06b3913..ad5b2ff 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_sync.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_sync.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_sync_error.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_sync_error.png
deleted file mode 100644
index 4f23dae..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_sync_error.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_tty_mode.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_tty_mode.png
index fb70ba87..b4db0bb 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_tty_mode.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_tty_mode.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_in.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_in.png
deleted file mode 100644
index 95c56ed..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_inout.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_inout.png
deleted file mode 100644
index 11b9a93..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_out.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_out.png
deleted file mode 100644
index 0f85ca0..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_0.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_0.png
index f39d0bb..3cc96ee 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_0.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_1.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_1.png
deleted file mode 100644
index 4f015d2..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_1.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_1_fully.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_1_fully.png
index b1314a6..34ae3bf 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_1_fully.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_2.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_2.png
deleted file mode 100644
index c451919..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_2.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_2_fully.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_2_fully.png
index 84746e7..cb3623a 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_2_fully.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_3.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_3.png
deleted file mode 100644
index ce752b1..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_3.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_3_fully.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_3_fully.png
index d6e746d..4f9a8b0 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_3_fully.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_4.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_4.png
deleted file mode 100644
index 3ecfff5..0000000
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_4.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_4_fully.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_4_fully.png
index 6e1ac91..441de0c 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_4_fully.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_4_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_null.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_null.png
index 7c60bea..34abc98 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_null.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_wifi_signal_null.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_bg_tile.png b/packages/SystemUI/res/drawable-mdpi/status_bar_bg_tile.png
deleted file mode 100644
index 6579ff9..0000000
--- a/packages/SystemUI/res/drawable-mdpi/status_bar_bg_tile.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_close_off.9.png b/packages/SystemUI/res/drawable-mdpi/status_bar_close_off.9.png
index 5c577cb..bd1cd12 100644
--- a/packages/SystemUI/res/drawable-mdpi/status_bar_close_off.9.png
+++ b/packages/SystemUI/res/drawable-mdpi/status_bar_close_off.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_close_on.9.png b/packages/SystemUI/res/drawable-mdpi/status_bar_close_on.9.png
index 7efb502..20c8785 100644
--- a/packages/SystemUI/res/drawable-mdpi/status_bar_close_on.9.png
+++ b/packages/SystemUI/res/drawable-mdpi/status_bar_close_on.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_expand_default.png b/packages/SystemUI/res/drawable-mdpi/status_bar_expand_default.png
deleted file mode 100644
index 1fd5dd3..0000000
--- a/packages/SystemUI/res/drawable-mdpi/status_bar_expand_default.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_expand_pressed.png b/packages/SystemUI/res/drawable-mdpi/status_bar_expand_pressed.png
deleted file mode 100644
index b2edd46..0000000
--- a/packages/SystemUI/res/drawable-mdpi/status_bar_expand_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_hr.9.png b/packages/SystemUI/res/drawable-mdpi/status_bar_hr.9.png
deleted file mode 100644
index f5e6031..0000000
--- a/packages/SystemUI/res/drawable-mdpi/status_bar_hr.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/title_bar_shadow.9.png b/packages/SystemUI/res/drawable-mdpi/title_bar_shadow.9.png
deleted file mode 100644
index f334023..0000000
--- a/packages/SystemUI/res/drawable-mdpi/title_bar_shadow.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/compat_mode_help_bg.png b/packages/SystemUI/res/drawable-nodpi/compat_mode_help_bg.png
deleted file mode 100644
index 87d8c41..0000000
--- a/packages/SystemUI/res/drawable-nodpi/compat_mode_help_bg.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/qs_coming_soon.png b/packages/SystemUI/res/drawable-nodpi/qs_coming_soon.png
deleted file mode 100644
index 47c89b1..0000000
--- a/packages/SystemUI/res/drawable-nodpi/qs_coming_soon.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/redbean0.png b/packages/SystemUI/res/drawable-nodpi/redbean0.png
deleted file mode 100644
index b088939..0000000
--- a/packages/SystemUI/res/drawable-nodpi/redbean0.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/redbean1.png b/packages/SystemUI/res/drawable-nodpi/redbean1.png
deleted file mode 100644
index 8fc8d9d..0000000
--- a/packages/SystemUI/res/drawable-nodpi/redbean1.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/redbean2.png b/packages/SystemUI/res/drawable-nodpi/redbean2.png
deleted file mode 100644
index ef11ca8..0000000
--- a/packages/SystemUI/res/drawable-nodpi/redbean2.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/redbeandroid.png b/packages/SystemUI/res/drawable-nodpi/redbeandroid.png
deleted file mode 100644
index 9aa3f82..0000000
--- a/packages/SystemUI/res/drawable-nodpi/redbeandroid.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.png
index 38bd0cd..3361e34 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_ime.png
index 6d4825e..ed52bc3 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.png
index baeb49e..b380327 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_brightness.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_brightness.png
deleted file mode 100644
index 77eae9a..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_brightness.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_highlight.png
index 202c8bc..8014b70 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_highlight.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_highlight.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_highlight_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_highlight_land.png
index 31bc09c..41a34e2 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_highlight_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_highlight_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home.png
index 0652753..49df31b 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home_land.png
index b8ea740..ac45bcd 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_ime_default.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_ime_default.png
deleted file mode 100644
index 2d5594c..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_ime_default.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_lights_out_dot_large.png
index 5e8e7f6..11e3b65 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_lights_out_dot_large.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_lights_out_dot_large.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_lights_out_dot_small.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_lights_out_dot_small.png
index 3529974..afcc487 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_lights_out_dot_small.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_lights_out_dot_small.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu.png
index bfec943..9fb4266 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu_land.png
index 3a6a2d8..459d011 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent.png
index 61f409d..e1cddde 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent_land.png
index 5629cca..e459f2c 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.png
index 0c12c16..0ec4d23 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_ime.png
index ec38e6a..4dedcbe 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.png
index 23f976c..e55f2bf 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_brightness.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_brightness.png
deleted file mode 100644
index f5fcb04..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_brightness.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_highlight.png
index bef6de3..9c623e5 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_highlight.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_highlight.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_highlight_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_highlight_land.png
index 406eeab..a011aa1 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_highlight_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_highlight_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home.png
index e3e683c..a39c3e5 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home_land.png
index 1f3410d..80e988f 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_ime_default.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_ime_default.png
deleted file mode 100644
index bea5339d..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_ime_default.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_lights_out_dot_large.png
index 1849a53a..24442343 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_lights_out_dot_large.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_lights_out_dot_large.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_lights_out_dot_small.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_lights_out_dot_small.png
index c5fe4df..a3e32f4c 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_lights_out_dot_small.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_lights_out_dot_small.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu.png
index a0ea296..4ef12b0d 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu_land.png
index 54d9cda..8ef12a8 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent.png
index 670fed9..c2977c0 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent_land.png
index a567e07..60ec10e 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/heads_up_window_bg.9.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/heads_up_window_bg.9.png
new file mode 100644
index 0000000..6002cfb
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/heads_up_window_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.png
index 477df5f..8aa6e3a 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_ime.png
index 5839fd0..e272b62 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.png
index 27b7ace..bf68b22 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_brightness.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_brightness.png
deleted file mode 100644
index f3dfb4f..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_brightness.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_highlight.png
index 75b5fbb..61a36e3 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_highlight.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_highlight.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_highlight_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_highlight_land.png
index a7a4ce3..52bf290 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_highlight_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_highlight_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home.png
index f753383..59ef663 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home_land.png
index b6e898e..cf3a5ff 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_ime_default.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_ime_default.png
deleted file mode 100644
index fb34efc..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_ime_default.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_lights_out_dot_large.png
index f079b85..298b62f 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_lights_out_dot_large.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_lights_out_dot_large.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_lights_out_dot_small.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_lights_out_dot_small.png
index fa5f001..41f4b42 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_lights_out_dot_small.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_lights_out_dot_small.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu.png
index 7690b47..2598954 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu_land.png
index 8c50621..66853db 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent.png
index f2db326..c46fd026 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent_land.png
index 93c737b..0e84d92 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/heads_up_window_bg.9.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/heads_up_window_bg.9.png
new file mode 100644
index 0000000..586a738
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/heads_up_window_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back.png
new file mode 100644
index 0000000..7e96395e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_ime.png
new file mode 100644
index 0000000..cb94580
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_land.png
new file mode 100644
index 0000000..382ef39
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_highlight.png
new file mode 100644
index 0000000..e5d4273
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_highlight.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_highlight_land.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_highlight_land.png
new file mode 100644
index 0000000..1cc5009
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_highlight_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home.png
new file mode 100644
index 0000000..8d7be53
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home_land.png
new file mode 100644
index 0000000..613fba0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_lights_out_dot_large.png
new file mode 100644
index 0000000..5ef7798
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_lights_out_dot_large.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_lights_out_dot_small.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_lights_out_dot_small.png
new file mode 100644
index 0000000..4a98e31
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_lights_out_dot_small.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu.png
new file mode 100644
index 0000000..0511ad1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu_land.png
new file mode 100644
index 0000000..77fe9b2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent.png
new file mode 100644
index 0000000..ae78eb0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent_land.png
new file mode 100644
index 0000000..5b446b1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/notification_panel_bg.9.png
new file mode 100644
index 0000000..8703e1d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_alarm.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_alarm.png
deleted file mode 100644
index 2f4cf9d..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_alarm.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_0.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_0.png
deleted file mode 100644
index 80184ab..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_0.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_100.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_100.png
deleted file mode 100644
index f33f00e..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_15.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_15.png
deleted file mode 100644
index 7f16039..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_15.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_28.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_28.png
deleted file mode 100644
index 83bfd39..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_28.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_43.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_43.png
deleted file mode 100644
index 2c85bcf..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_43.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_57.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_57.png
deleted file mode 100644
index ce1acbd..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_57.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_71.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_71.png
deleted file mode 100644
index df53bb0..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_71.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_85.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_85.png
deleted file mode 100644
index 44d8726..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_85.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_charge_anim0.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_charge_anim0.png
deleted file mode 100644
index 1a060e7..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_charge_anim0.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_charge_anim100.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_charge_anim100.png
deleted file mode 100644
index 02fd013..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_charge_anim100.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_charge_anim15.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_charge_anim15.png
deleted file mode 100644
index 496c5af..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_charge_anim15.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_charge_anim28.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_charge_anim28.png
deleted file mode 100644
index e371412..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_charge_anim28.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_charge_anim43.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_charge_anim43.png
deleted file mode 100644
index 13a0141..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_charge_anim43.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_charge_anim57.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_charge_anim57.png
deleted file mode 100644
index bc6344a..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_charge_anim57.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_charge_anim71.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_charge_anim71.png
deleted file mode 100644
index 3a1bc96..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_charge_anim71.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_charge_anim85.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_charge_anim85.png
deleted file mode 100644
index 12f5b99..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_battery_charge_anim85.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_bluetooth.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_bluetooth.png
deleted file mode 100644
index 31762a2..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_bluetooth.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_bluetooth_connected.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_bluetooth_connected.png
deleted file mode 100644
index c4376a2..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_bluetooth_connected.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_connected_1x.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_connected_1x.png
deleted file mode 100644
index 5691427..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_connected_1x.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_connected_3g.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_connected_3g.png
deleted file mode 100644
index 2464d9e..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_connected_3g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_connected_4g.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_connected_4g.png
deleted file mode 100644
index ffe90bc..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_connected_4g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_connected_e.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_connected_e.png
deleted file mode 100644
index 823b3fa3..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_connected_e.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_connected_g.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_connected_g.png
deleted file mode 100644
index 1ac455c..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_connected_g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_connected_h.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_connected_h.png
deleted file mode 100644
index 7a38b12..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_connected_h.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_connected_roam.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_connected_roam.png
deleted file mode 100644
index 3861bfe..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_connected_roam.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_fully_connected_1x.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_fully_connected_1x.png
deleted file mode 100644
index 2eb6246..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_fully_connected_1x.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_fully_connected_3g.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_fully_connected_3g.png
deleted file mode 100644
index 0ce5ec3..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_fully_connected_3g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_fully_connected_4g.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_fully_connected_4g.png
deleted file mode 100644
index 6bf2412..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_fully_connected_4g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_fully_connected_e.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_fully_connected_e.png
deleted file mode 100644
index 791de4d..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_fully_connected_e.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_fully_connected_g.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_fully_connected_g.png
deleted file mode 100644
index 0712aa6..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_fully_connected_g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_fully_connected_h.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_fully_connected_h.png
deleted file mode 100644
index 2886e55..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_data_fully_connected_h.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_ime_default.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_ime_default.png
deleted file mode 100644
index 47f0745c..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_ime_default.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_ime_pressed.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_ime_pressed.png
deleted file mode 100644
index 490504e..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_ime_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_0.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_0.png
deleted file mode 100644
index ac322ba..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_0.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_0_fully.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_0_fully.png
deleted file mode 100644
index ac322ba..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_0_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_1.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_1.png
deleted file mode 100644
index f139bbe..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_1.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_1_fully.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_1_fully.png
deleted file mode 100644
index af67018..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_1_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_2.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_2.png
deleted file mode 100644
index fe404e2..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_2.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_2_fully.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_2_fully.png
deleted file mode 100644
index 1ffa9b6..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_2_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_3.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_3.png
deleted file mode 100644
index 75cd8ee..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_3.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_3_fully.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_3_fully.png
deleted file mode 100644
index 666d1f6..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_3_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_4.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_4.png
deleted file mode 100644
index da9607b..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_4.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_4_fully.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_4_fully.png
deleted file mode 100644
index d05297f..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_flightmode.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_flightmode.png
deleted file mode 100644
index 64d4e60..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_flightmode.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_in.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_in.png
deleted file mode 100644
index 3d67766..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_inout.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_inout.png
deleted file mode 100644
index b74e070..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_null.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_null.png
deleted file mode 100644
index 709b181..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_null.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_out.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_out.png
deleted file mode 100644
index 24485e1..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_in.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_in.png
deleted file mode 100644
index 390d500..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_inout.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_inout.png
deleted file mode 100644
index 78998f9..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_out.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_out.png
deleted file mode 100644
index c539615..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_signal_0.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_signal_0.png
deleted file mode 100644
index 57675a2..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_signal_0.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_signal_1.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_signal_1.png
deleted file mode 100644
index eec0390..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_signal_1.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_signal_1_fully.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_signal_1_fully.png
deleted file mode 100644
index 900867a..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_signal_1_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_signal_2.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_signal_2.png
deleted file mode 100644
index 253bdac..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_signal_2.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_signal_2_fully.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_signal_2_fully.png
deleted file mode 100644
index b50576c..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_signal_2_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_signal_3.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_signal_3.png
deleted file mode 100644
index d69a171..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_signal_3.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_signal_3_fully.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_signal_3_fully.png
deleted file mode 100644
index 47df06f..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_signal_3_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_signal_4.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_signal_4.png
deleted file mode 100644
index 99184f0..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_signal_4.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_signal_4_fully.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_signal_4_fully.png
deleted file mode 100644
index 4a2ac51..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_signal_null.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_signal_null.png
deleted file mode 100644
index 4fd3a08..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_wifi_signal_null.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_zoom_default.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_zoom_default.png
deleted file mode 100644
index 348afb5..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_zoom_default.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_zoom_pressed.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_zoom_pressed.png
deleted file mode 100644
index 2f20d67..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/ic_sysbar_zoom_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/notify_panel_clock_bg_normal.9.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/notify_panel_clock_bg_normal.9.png
deleted file mode 100644
index 88137e8..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/notify_panel_clock_bg_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/notify_panel_clock_bg_pressed.9.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/notify_panel_clock_bg_pressed.9.png
deleted file mode 100644
index 6507a51..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/notify_panel_clock_bg_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/recents_bg_protect_tile.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/recents_bg_protect_tile.png
deleted file mode 100644
index a57c27a..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/recents_bg_protect_tile.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/recents_blue_glow.9.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/recents_blue_glow.9.png
deleted file mode 100644
index 4ac131a..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/recents_blue_glow.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/sysbar_notification_panel_bg.9.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/sysbar_notification_panel_bg.9.png
deleted file mode 100644
index 0c20ba2..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/sysbar_notification_panel_bg.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_alarm.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_alarm.png
deleted file mode 100644
index 9b7c5d6..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_alarm.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_0.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_0.png
deleted file mode 100644
index ea2918f..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_0.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_100.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_100.png
deleted file mode 100644
index 906c818..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_15.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_15.png
deleted file mode 100644
index c855fa599d..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_15.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_28.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_28.png
deleted file mode 100644
index cafa16f..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_28.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_43.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_43.png
deleted file mode 100644
index 400c2ca..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_43.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_57.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_57.png
deleted file mode 100644
index 1aa0d82..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_57.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_71.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_71.png
deleted file mode 100644
index ac0bca1..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_71.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_85.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_85.png
deleted file mode 100644
index 2e76eee..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_85.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_charge_anim0.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_charge_anim0.png
deleted file mode 100644
index 8d54b97..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_charge_anim0.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_charge_anim100.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_charge_anim100.png
deleted file mode 100644
index 784c4e7..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_charge_anim100.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_charge_anim15.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_charge_anim15.png
deleted file mode 100644
index 6bc543c..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_charge_anim15.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_charge_anim28.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_charge_anim28.png
deleted file mode 100644
index ba449ac..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_charge_anim28.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_charge_anim43.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_charge_anim43.png
deleted file mode 100644
index 13399f4..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_charge_anim43.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_charge_anim57.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_charge_anim57.png
deleted file mode 100644
index e2a95ef..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_charge_anim57.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_charge_anim71.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_charge_anim71.png
deleted file mode 100644
index 4c8ac28..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_charge_anim71.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_charge_anim85.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_charge_anim85.png
deleted file mode 100644
index b3b9f52..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_battery_charge_anim85.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_bluetooth.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_bluetooth.png
deleted file mode 100644
index c4f0d78..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_bluetooth.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_bluetooth_connected.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_bluetooth_connected.png
deleted file mode 100644
index 3034a47..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_bluetooth_connected.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_connected_1x.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_connected_1x.png
deleted file mode 100644
index 5287c0f..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_connected_1x.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_connected_3g.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_connected_3g.png
deleted file mode 100644
index d8a5ee8..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_connected_3g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_connected_4g.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_connected_4g.png
deleted file mode 100644
index 11737ee..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_connected_4g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_connected_e.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_connected_e.png
deleted file mode 100644
index 842faac..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_connected_e.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_connected_g.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_connected_g.png
deleted file mode 100644
index 0548dd3..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_connected_g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_connected_h.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_connected_h.png
deleted file mode 100644
index be79e0d..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_connected_h.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_connected_roam.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_connected_roam.png
deleted file mode 100644
index ee2e99e..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_connected_roam.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_fully_connected_1x.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_fully_connected_1x.png
deleted file mode 100644
index ee43332..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_fully_connected_1x.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_fully_connected_3g.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_fully_connected_3g.png
deleted file mode 100644
index 4e38c5d..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_fully_connected_3g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_fully_connected_4g.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_fully_connected_4g.png
deleted file mode 100644
index 6c08aa9..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_fully_connected_4g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_fully_connected_e.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_fully_connected_e.png
deleted file mode 100644
index 2e7c46d..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_fully_connected_e.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_fully_connected_g.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_fully_connected_g.png
deleted file mode 100644
index 57f48fb..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_fully_connected_g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_fully_connected_h.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_fully_connected_h.png
deleted file mode 100644
index f751a31..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_data_fully_connected_h.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_ime_default.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_ime_default.png
deleted file mode 100644
index 33edce0..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_ime_default.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_ime_pressed.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_ime_pressed.png
deleted file mode 100644
index 8bab6cf..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_ime_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_0.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_0.png
deleted file mode 100644
index f931c60..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_0.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_0_fully.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_0_fully.png
deleted file mode 100644
index f931c60..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_0_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_1.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_1.png
deleted file mode 100644
index 398f4d5..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_1.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_1_fully.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_1_fully.png
deleted file mode 100644
index a0fc3f2..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_1_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_2.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_2.png
deleted file mode 100644
index 5fe96a3..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_2.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_2_fully.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_2_fully.png
deleted file mode 100644
index 8a66255..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_2_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_3.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_3.png
deleted file mode 100644
index e785a7a..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_3.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_3_fully.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_3_fully.png
deleted file mode 100644
index 63be95d..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_3_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_4.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_4.png
deleted file mode 100644
index 533bcdc..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_4.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_4_fully.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_4_fully.png
deleted file mode 100644
index 566172e..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_flightmode.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_flightmode.png
deleted file mode 100644
index f61c058..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_flightmode.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_in.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_in.png
deleted file mode 100644
index 5c38d45..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_inout.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_inout.png
deleted file mode 100644
index 6a79695..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_null.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_null.png
deleted file mode 100644
index 67d5cbf..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_null.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_out.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_out.png
deleted file mode 100644
index 99dbe1b..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_in.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_in.png
deleted file mode 100644
index 6a73a89..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_inout.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_inout.png
deleted file mode 100644
index 7042f2b..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_out.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_out.png
deleted file mode 100644
index 3da781e..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_signal_0.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_signal_0.png
deleted file mode 100644
index 1570dd2..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_signal_0.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_signal_1.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_signal_1.png
deleted file mode 100644
index 80a7a4a7..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_signal_1.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_signal_1_fully.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_signal_1_fully.png
deleted file mode 100644
index 9db1a84..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_signal_1_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_signal_2.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_signal_2.png
deleted file mode 100644
index f9720f2..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_signal_2.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_signal_2_fully.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_signal_2_fully.png
deleted file mode 100644
index 8567d11..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_signal_2_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_signal_3.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_signal_3.png
deleted file mode 100644
index 5ee6d07..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_signal_3.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_signal_3_fully.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_signal_3_fully.png
deleted file mode 100644
index b38f7eb..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_signal_3_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_signal_4.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_signal_4.png
deleted file mode 100644
index ec6e805..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_signal_4.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_signal_4_fully.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_signal_4_fully.png
deleted file mode 100644
index 9a79c54..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_signal_null.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_signal_null.png
deleted file mode 100644
index 1943e8c..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_wifi_signal_null.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_zoom_default.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_zoom_default.png
deleted file mode 100644
index 89d486f..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_zoom_default.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_zoom_pressed.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_zoom_pressed.png
deleted file mode 100644
index b134436..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/ic_sysbar_zoom_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/notify_panel_clock_bg_normal.9.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/notify_panel_clock_bg_normal.9.png
deleted file mode 100644
index 798f589..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/notify_panel_clock_bg_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/notify_panel_clock_bg_pressed.9.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/notify_panel_clock_bg_pressed.9.png
deleted file mode 100644
index 73247e5..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/notify_panel_clock_bg_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/recents_bg_protect_tile.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/recents_bg_protect_tile.png
deleted file mode 100644
index 87c7be6..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/recents_bg_protect_tile.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/recents_blue_glow.9.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/recents_blue_glow.9.png
deleted file mode 100644
index 4362836..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/recents_blue_glow.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/sysbar_notification_panel_bg.9.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/sysbar_notification_panel_bg.9.png
deleted file mode 100644
index 56cd238..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/sysbar_notification_panel_bg.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-tvdpi/sysbar_notification_panel_bg.9.png b/packages/SystemUI/res/drawable-sw720dp-tvdpi/sysbar_notification_panel_bg.9.png
deleted file mode 100644
index 571a7a5..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-tvdpi/sysbar_notification_panel_bg.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_alarm.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_alarm.png
deleted file mode 100644
index 0f83f7a..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_alarm.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_0.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_0.png
deleted file mode 100644
index 511923c..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_0.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_100.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_100.png
deleted file mode 100644
index 61fa300..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_15.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_15.png
deleted file mode 100644
index daefb7c..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_15.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_28.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_28.png
deleted file mode 100644
index bc8c467..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_28.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_43.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_43.png
deleted file mode 100644
index a16c979..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_43.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_57.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_57.png
deleted file mode 100644
index 4778dc1..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_57.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_71.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_71.png
deleted file mode 100644
index 81693b6..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_71.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_85.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_85.png
deleted file mode 100644
index e81bb8d..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_85.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_charge_anim0.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_charge_anim0.png
deleted file mode 100644
index 9834f5a..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_charge_anim0.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_charge_anim100.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_charge_anim100.png
deleted file mode 100644
index b314f8b..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_charge_anim100.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_charge_anim15.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_charge_anim15.png
deleted file mode 100644
index 59de3f2..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_charge_anim15.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_charge_anim28.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_charge_anim28.png
deleted file mode 100644
index 91397ed..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_charge_anim28.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_charge_anim43.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_charge_anim43.png
deleted file mode 100644
index 268fea4..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_charge_anim43.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_charge_anim57.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_charge_anim57.png
deleted file mode 100644
index 15ee476..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_charge_anim57.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_charge_anim71.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_charge_anim71.png
deleted file mode 100644
index 4dead31..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_charge_anim71.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_charge_anim85.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_charge_anim85.png
deleted file mode 100644
index 8b4563f..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_battery_charge_anim85.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_bluetooth.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_bluetooth.png
deleted file mode 100644
index 2984394..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_bluetooth.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_bluetooth_connected.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_bluetooth_connected.png
deleted file mode 100644
index 4b904b4..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_bluetooth_connected.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_connected_1x.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_connected_1x.png
deleted file mode 100644
index 31af3c2..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_connected_1x.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_connected_3g.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_connected_3g.png
deleted file mode 100644
index 4f5fa70..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_connected_3g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_connected_4g.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_connected_4g.png
deleted file mode 100644
index e7eb85e..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_connected_4g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_connected_e.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_connected_e.png
deleted file mode 100644
index 79038f7..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_connected_e.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_connected_g.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_connected_g.png
deleted file mode 100644
index c554b23..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_connected_g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_connected_h.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_connected_h.png
deleted file mode 100644
index e5c0780f0..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_connected_h.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_connected_roam.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_connected_roam.png
deleted file mode 100644
index 0edc9b5..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_connected_roam.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_fully_connected_1x.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_fully_connected_1x.png
deleted file mode 100644
index de93431..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_fully_connected_1x.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_fully_connected_3g.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_fully_connected_3g.png
deleted file mode 100644
index 9b01f30..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_fully_connected_3g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_fully_connected_4g.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_fully_connected_4g.png
deleted file mode 100644
index a44d3a2..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_fully_connected_4g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_fully_connected_e.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_fully_connected_e.png
deleted file mode 100644
index a4a93e3..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_fully_connected_e.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_fully_connected_g.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_fully_connected_g.png
deleted file mode 100644
index 4f6f1ba..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_fully_connected_g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_fully_connected_h.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_fully_connected_h.png
deleted file mode 100644
index bc135c3..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_data_fully_connected_h.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_ime_default.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_ime_default.png
deleted file mode 100644
index d670177..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_ime_default.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_ime_pressed.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_ime_pressed.png
deleted file mode 100644
index c9f0302..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_ime_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_0.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_0.png
deleted file mode 100644
index ccf1ba1..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_0.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_0_fully.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_0_fully.png
deleted file mode 100644
index ccf1ba1..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_0_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_1.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_1.png
deleted file mode 100644
index 07937fe..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_1.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_1_fully.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_1_fully.png
deleted file mode 100644
index ba1b077..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_1_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_2.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_2.png
deleted file mode 100644
index a705a89..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_2.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_2_fully.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_2_fully.png
deleted file mode 100644
index 0187d12..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_2_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_3.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_3.png
deleted file mode 100644
index 0ed7d6f4..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_3.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_3_fully.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_3_fully.png
deleted file mode 100644
index 24a6e5a..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_3_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_4.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_4.png
deleted file mode 100644
index 1a47801..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_4.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_4_fully.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_4_fully.png
deleted file mode 100644
index d9648b6f..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_flightmode.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_flightmode.png
deleted file mode 100644
index 620da77..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_flightmode.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_in.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_in.png
deleted file mode 100644
index cf63e24..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_inout.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_inout.png
deleted file mode 100644
index 8f68e1f..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_null.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_null.png
deleted file mode 100644
index fa8735d..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_null.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_out.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_out.png
deleted file mode 100644
index 894c63b..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_in.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_in.png
deleted file mode 100644
index 1ec5b49..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_inout.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_inout.png
deleted file mode 100644
index 9ca3ca8..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_out.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_out.png
deleted file mode 100644
index 74241e0..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_signal_0.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_signal_0.png
deleted file mode 100644
index 9553241..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_signal_0.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_signal_1.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_signal_1.png
deleted file mode 100644
index 4d70eb3..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_signal_1.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_signal_1_fully.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_signal_1_fully.png
deleted file mode 100644
index bfa3ad7..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_signal_1_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_signal_2.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_signal_2.png
deleted file mode 100644
index f7e78d0..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_signal_2.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_signal_2_fully.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_signal_2_fully.png
deleted file mode 100644
index fc90385..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_signal_2_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_signal_3.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_signal_3.png
deleted file mode 100644
index 931905e..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_signal_3.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_signal_3_fully.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_signal_3_fully.png
deleted file mode 100644
index f1fa45b..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_signal_3_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_signal_4.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_signal_4.png
deleted file mode 100644
index 0dd11a2..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_signal_4.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_signal_4_fully.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_signal_4_fully.png
deleted file mode 100644
index 20991eb..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_signal_4_fully.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_signal_null.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_signal_null.png
deleted file mode 100644
index de573b6..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_wifi_signal_null.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_zoom_default.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_zoom_default.png
deleted file mode 100644
index dd8c498..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_zoom_default.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_zoom_pressed.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_zoom_pressed.png
deleted file mode 100644
index dc42157..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/ic_sysbar_zoom_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/notify_panel_clock_bg_normal.9.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/notify_panel_clock_bg_normal.9.png
deleted file mode 100644
index 2b46c89..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/notify_panel_clock_bg_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/notify_panel_clock_bg_pressed.9.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/notify_panel_clock_bg_pressed.9.png
deleted file mode 100644
index dd476b7..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/notify_panel_clock_bg_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/recents_bg_protect_tile.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/recents_bg_protect_tile.png
deleted file mode 100644
index 59908ad..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/recents_bg_protect_tile.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/recents_blue_glow.9.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/recents_blue_glow.9.png
deleted file mode 100644
index 3938502..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/recents_blue_glow.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/sysbar_notification_panel_bg.9.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/sysbar_notification_panel_bg.9.png
deleted file mode 100644
index 3f05767..0000000
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/sysbar_notification_panel_bg.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/alert_bar_background_normal.9.png b/packages/SystemUI/res/drawable-xhdpi/alert_bar_background_normal.9.png
deleted file mode 100644
index eb44262..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/alert_bar_background_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/alert_bar_background_pressed.9.png b/packages/SystemUI/res/drawable-xhdpi/alert_bar_background_pressed.9.png
deleted file mode 100644
index 887e006..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/alert_bar_background_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/arrow_dashed.png b/packages/SystemUI/res/drawable-xhdpi/arrow_dashed.png
deleted file mode 100644
index c26ed9c..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/arrow_dashed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/battery_low_battery.png b/packages/SystemUI/res/drawable-xhdpi/battery_low_battery.png
index f3c0fca..83693c1 100644
--- a/packages/SystemUI/res/drawable-xhdpi/battery_low_battery.png
+++ b/packages/SystemUI/res/drawable-xhdpi/battery_low_battery.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/btn_cling_normal.9.png b/packages/SystemUI/res/drawable-xhdpi/btn_cling_normal.9.png
deleted file mode 100644
index 35511d6..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/btn_cling_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/btn_cling_pressed.9.png b/packages/SystemUI/res/drawable-xhdpi/btn_cling_pressed.9.png
deleted file mode 100644
index a38b40f..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/btn_cling_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/btn_default_small_normal.9.png b/packages/SystemUI/res/drawable-xhdpi/btn_default_small_normal.9.png
deleted file mode 100644
index 5e601d2..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/btn_default_small_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/btn_default_small_normal_disable.9.png b/packages/SystemUI/res/drawable-xhdpi/btn_default_small_normal_disable.9.png
deleted file mode 100644
index ed92cd0..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/btn_default_small_normal_disable.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/btn_default_small_normal_disable_focused.9.png b/packages/SystemUI/res/drawable-xhdpi/btn_default_small_normal_disable_focused.9.png
deleted file mode 100644
index f77dbfb..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/btn_default_small_normal_disable_focused.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/btn_default_small_pressed.9.png b/packages/SystemUI/res/drawable-xhdpi/btn_default_small_pressed.9.png
deleted file mode 100644
index e34107b..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/btn_default_small_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/btn_default_small_selected.9.png b/packages/SystemUI/res/drawable-xhdpi/btn_default_small_selected.9.png
deleted file mode 100644
index 8f70177..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/btn_default_small_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/compat_mode_help_diagram.png b/packages/SystemUI/res/drawable-xhdpi/compat_mode_help_diagram.png
deleted file mode 100644
index 03f4732..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/compat_mode_help_diagram.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/compat_mode_help_divider_bottom.9.png b/packages/SystemUI/res/drawable-xhdpi/compat_mode_help_divider_bottom.9.png
deleted file mode 100644
index 7bfdb46..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/compat_mode_help_divider_bottom.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/compat_mode_help_divider_top.9.png b/packages/SystemUI/res/drawable-xhdpi/compat_mode_help_divider_top.9.png
deleted file mode 100644
index 4e20851..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/compat_mode_help_divider_top.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/compat_mode_help_icon.png b/packages/SystemUI/res/drawable-xhdpi/compat_mode_help_icon.png
deleted file mode 100644
index 1c1b26b..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/compat_mode_help_icon.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/hd_off.png b/packages/SystemUI/res/drawable-xhdpi/hd_off.png
deleted file mode 100644
index 7f5bd88..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/hd_off.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/hd_on.png b/packages/SystemUI/res/drawable-xhdpi/hd_on.png
deleted file mode 100644
index 55305ce..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/hd_on.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/heads_up_window_bg.9.png b/packages/SystemUI/res/drawable-xhdpi/heads_up_window_bg.9.png
new file mode 100644
index 0000000..42e5593
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/heads_up_window_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_launcher_settings.png b/packages/SystemUI/res/drawable-xhdpi/ic_launcher_settings.png
deleted file mode 100644
index 2b2907b..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_launcher_settings.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notification_dnd.png b/packages/SystemUI/res/drawable-xhdpi/ic_notification_dnd.png
deleted file mode 100644
index 0e926ab..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notification_dnd.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notification_open.png b/packages/SystemUI/res/drawable-xhdpi/ic_notification_open.png
deleted file mode 100644
index 98455cf..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notification_open.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notification_overlay.9.png b/packages/SystemUI/res/drawable-xhdpi/ic_notification_overlay.9.png
index 8758b02..aae807b7 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notification_overlay.9.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notification_overlay.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notifications_normal.png b/packages/SystemUI/res/drawable-xhdpi/ic_notifications_normal.png
deleted file mode 100644
index 983302c..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notifications_normal.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_normal.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_normal.png
index c882e9a..b9afa44 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_normal.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_pressed.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_pressed.png
deleted file mode 100644
index 992b50d..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_open_normal.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_open_normal.png
index 56386f8..990f8bb 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notify_open_normal.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_open_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_open_pressed.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_open_pressed.png
deleted file mode 100644
index 501c777..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notify_open_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_normal.png
index 2d445279..96eaafe 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_normal.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_pressed.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_pressed.png
deleted file mode 100644
index ddf2c7a..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_rotation_off_normal.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_rotation_off_normal.png
deleted file mode 100644
index cebd6d8..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notify_rotation_off_normal.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_rotation_off_pressed.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_rotation_off_pressed.png
deleted file mode 100644
index ef4d9a1..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notify_rotation_off_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_rotation_on_normal.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_rotation_on_normal.png
deleted file mode 100644
index 01146aa..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notify_rotation_on_normal.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_rotation_on_pressed.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_rotation_on_pressed.png
deleted file mode 100644
index e8f01c5..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notify_rotation_on_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_settings_normal.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_settings_normal.png
index 80fdb79..c0032e2 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notify_settings_normal.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_settings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_settings_pressed.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_settings_pressed.png
deleted file mode 100644
index ac7c1a7..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notify_settings_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_airplane_off.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_airplane_off.png
index 9a4239b..ea4b8d6 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_airplane_off.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_airplane_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_airplane_on.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_airplane_on.png
index 0af4f3d..79e4ff6 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_airplane_on.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_airplane_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_alarm_on.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_alarm_on.png
index 07e749a..3c0eac1 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_alarm_on.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_alarm_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_auto_rotate.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_auto_rotate.png
index f9ab581..c553bc2 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_auto_rotate.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_auto_rotate.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_0.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_0.png
index 2b592cc..ff3bdf0 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_0.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_100.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_100.png
index 2c56c9b..8bc6d17 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_100.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_15.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_15.png
index 9895f71..39fccc8 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_15.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_28.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_28.png
index 323fa8b..70829a1 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_28.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_43.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_43.png
index 98eea99..ebd97c8 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_43.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_57.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_57.png
index 64555c0..9d5be12 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_57.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_71.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_71.png
index ad8b15f..1ffa245 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_71.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_85.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_85.png
index 071b79b..b6aebe6 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_85.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_bolt.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_bolt.png
deleted file mode 100644
index 0c5594d..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_bolt.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_charge_100.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_charge_100.png
index 234bb63..37cb7c4 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_charge_100.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_charge_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_charge_15.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_charge_15.png
index e3c6920..1a595ed 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_charge_15.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_charge_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_charge_28.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_charge_28.png
index 3dfbe4c..e36e68c 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_charge_28.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_charge_28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_charge_43.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_charge_43.png
index 3f493f1..e58f9c0 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_charge_43.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_charge_43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_charge_57.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_charge_57.png
index 0cce725..c7fafa4 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_charge_57.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_charge_57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_charge_71.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_charge_71.png
index f6fff00..5dcec0e 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_charge_71.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_charge_71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_charge_85.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_charge_85.png
index 35ef746..6e81974 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_charge_85.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_charge_85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_unknown.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_unknown.png
index f5fbbfb..1db2eb3 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_unknown.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_battery_unknown.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_bluetooth_not_connected.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_bluetooth_not_connected.png
index e312f8e..ce965c2 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_bluetooth_not_connected.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_bluetooth_not_connected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_bluetooth_off.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_bluetooth_off.png
index 44cd31b..273f363 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_bluetooth_off.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_bluetooth_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_bluetooth_on.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_bluetooth_on.png
index 62a518a..ac5b09d 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_bluetooth_on.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_bluetooth_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_brightness_auto_off.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_brightness_auto_off.png
index 653fa3f..37d7ac7 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_brightness_auto_off.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_brightness_auto_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_brightness_auto_on.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_brightness_auto_on.png
index 4ed4a9e..626e283 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_brightness_auto_on.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_brightness_auto_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_certificate_info.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_certificate_info.png
new file mode 100644
index 0000000..b3de2ce
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_certificate_info.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_clock_circle.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_clock_circle.png
index c7864ba..72c587d 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_clock_circle.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_clock_circle.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_clock_hour.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_clock_hour.png
index 02c4a05..d18dbd9 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_clock_hour.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_clock_hour.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_clock_minute.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_clock_minute.png
index aa6be72..31230af 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_clock_minute.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_clock_minute.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_default_user.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_default_user.png
index fd9b677..d14a67f 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_default_user.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_default_user.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_ime.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_ime.png
index 7eabd10..bffbf55 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_ime.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_location.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_location.png
index b2033df..a52dc8d 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_location.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_location.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_location_off.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_location_off.png
new file mode 100644
index 0000000..466470c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_location_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_location_on.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_location_on.png
new file mode 100644
index 0000000..77c3ec0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_location_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_remote_display.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_remote_display.png
index 88ea017..92c6df0 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_remote_display.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_remote_display.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_remote_display_connected.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_remote_display_connected.png
index 7573636..621c045 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_remote_display_connected.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_remote_display_connected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_rotation_locked.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_rotation_locked.png
index 0098df49..b6daaf3 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_rotation_locked.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_rotation_locked.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_settings.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_settings.png
index 2d3638c..e888ac2 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_settings.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_settings.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_0.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_0.png
index 7419be9..e303016 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_0.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_1.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_1.png
index 471e1fa..abc9358 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_1.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_1x.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_1x.png
index cb1eb0f..f88e3a4 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_1x.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_2.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_2.png
index 4311330..0419144 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_2.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_3.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_3.png
index 637e079..515ffe7 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_3.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_3g.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_3g.png
index 8fdd7ff..9aff8aa 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_3g.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_4.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_4.png
index 8fca5f2..118de2d 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_4.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_4g.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_4g.png
index 125e33d..2e00303 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_4g.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_e.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_e.png
index acf4752..33ae551 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_e.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_0.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_0.png
index 25a5c53..2ef694e 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_0.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_1.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_1.png
index 1cbe239..58317e3 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_1.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_1x.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_1x.png
index 9507162..2866e4c 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_1x.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_2.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_2.png
index deb8c87..57b8039 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_2.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_3.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_3.png
index 7186579..0cb099c 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_3.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_3g.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_3g.png
index 1aa2393..922f7ca 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_3g.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_4.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_4.png
index adafb2c..a857c32 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_4.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_4g.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_4g.png
index 0083754..82ced1e 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_4g.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_e.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_e.png
index 67e2e11..7ae8f90 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_e.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_g.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_g.png
index f47c63e..050cbcb 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_g.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_h.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_h.png
index 2421050..7440bc0 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_h.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_lte.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_lte.png
index 75c5c72..4212e49 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_lte.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_lte.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_r.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_r.png
index cb4782e..2176a88 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_r.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_full_r.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_g.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_g.png
index fd5fb17..fb09a26 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_g.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_h.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_h.png
index c63bbfa..b52aec7 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_h.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_in.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_in.png
index a0d588d..46fd826 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_in.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_inout.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_inout.png
index 341716d..c824b97 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_inout.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_lte.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_lte.png
index 402db43..9942e7a 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_lte.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_lte.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_no_network.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_no_network.png
index 7f2be8c..f7571db 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_no_network.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_no_network.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_no_signal.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_no_signal.png
index 15169b9..43a7d82 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_no_signal.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_no_signal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_out.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_out.png
index b2ad34d..fb9ecd0 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_out.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_r.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_r.png
index 89680ce..1efdebf 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_r.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_signal_r.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_usb_device.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_usb_device.png
index 780a511..86de480 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_usb_device.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_usb_device.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_0.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_0.png
index 42fdbe8..5599069 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_0.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_1.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_1.png
index eefe7ed..715e60a 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_1.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_2.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_2.png
index a2caca2..ed7f5b9 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_2.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_3.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_3.png
index 08c1abd..8f1464b 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_3.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_4.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_4.png
index 8af72e51..b32c676 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_4.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_full_1.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_full_1.png
index 7d9f032..0702c31 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_full_1.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_full_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_full_2.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_full_2.png
index 896eacc..6693090 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_full_2.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_full_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_full_3.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_full_3.png
index 0224da1..ded4c67 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_full_3.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_full_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_full_4.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_full_4.png
index fe28671..c2e0da9 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_full_4.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_full_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_in.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_in.png
index a0d588d..6cf0a4b 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_in.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_inout.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_inout.png
index 341716d..c824b97 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_inout.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_no_network.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_no_network.png
index 4c6f1ff..22e0f8c 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_no_network.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_no_network.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_not_connected.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_not_connected.png
index a6dd06a..2344349 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_not_connected.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_not_connected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_out.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_out.png
index b2ad34d..fb9ecd0 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_out.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_airplane_on.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_airplane_on.png
deleted file mode 100644
index 31ac35d..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_airplane_on.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
index bd60cd6..a2bb50a 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime.png
index 7f05602..24897ce 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png
index 5272c91..aaeeb1b 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_brightness.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_brightness.png
deleted file mode 100644
index bc024da..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_brightness.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home.png
index c5bc5c9..ddee461 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png
index 33e1801..23a7997 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_ime_default.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_ime_default.png
deleted file mode 100644
index 2d77fb1..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_ime_default.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_lights_out_dot_large.png
index 155c788..e62dece 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_lights_out_dot_large.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_lights_out_dot_large.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_lights_out_dot_small.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_lights_out_dot_small.png
index e84f3fb..958b2fe 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_lights_out_dot_small.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_lights_out_dot_small.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu.png
index 5c9c0e5f..9f200c2 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_land.png
index 4db9e9d..43e9bc2 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_land.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_quicksettings.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_quicksettings.png
deleted file mode 100644
index bbf5f7e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_quicksettings.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent.png
index f621d9c..5c0ba82 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png
index b530638..b76a0ca 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_rotate_on.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_rotate_on.png
deleted file mode 100644
index 35d85e1..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_rotate_on.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_wifi_on.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_wifi_on.png
deleted file mode 100644
index bc1628f..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_wifi_on.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/pocket_drag_pattern.png b/packages/SystemUI/res/drawable-xhdpi/pocket_drag_pattern.png
deleted file mode 100644
index 34431f4..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/pocket_drag_pattern.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/recents_blue_glow.9.png b/packages/SystemUI/res/drawable-xhdpi/recents_blue_glow.9.png
deleted file mode 100644
index e1e08c6..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/recents_blue_glow.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/recents_thumbnail_bg_dragging.9.png b/packages/SystemUI/res/drawable-xhdpi/recents_thumbnail_bg_dragging.9.png
index 1d097c5..79d1b3c 100644
--- a/packages/SystemUI/res/drawable-xhdpi/recents_thumbnail_bg_dragging.9.png
+++ b/packages/SystemUI/res/drawable-xhdpi/recents_thumbnail_bg_dragging.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/recents_thumbnail_bg_normal.9.png b/packages/SystemUI/res/drawable-xhdpi/recents_thumbnail_bg_normal.9.png
index 80fc849..c57ec67 100644
--- a/packages/SystemUI/res/drawable-xhdpi/recents_thumbnail_bg_normal.9.png
+++ b/packages/SystemUI/res/drawable-xhdpi/recents_thumbnail_bg_normal.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/recents_thumbnail_bg_press.9.png b/packages/SystemUI/res/drawable-xhdpi/recents_thumbnail_bg_press.9.png
index 5bae56d..f01a79e 100644
--- a/packages/SystemUI/res/drawable-xhdpi/recents_thumbnail_bg_press.9.png
+++ b/packages/SystemUI/res/drawable-xhdpi/recents_thumbnail_bg_press.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/screenshot_panel.9.png b/packages/SystemUI/res/drawable-xhdpi/screenshot_panel.9.png
index c096c7a..511537a 100644
--- a/packages/SystemUI/res/drawable-xhdpi/screenshot_panel.9.png
+++ b/packages/SystemUI/res/drawable-xhdpi/screenshot_panel.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/search_light.png b/packages/SystemUI/res/drawable-xhdpi/search_light.png
index 3aa890f..68b70eb 100644
--- a/packages/SystemUI/res/drawable-xhdpi/search_light.png
+++ b/packages/SystemUI/res/drawable-xhdpi/search_light.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_notify_image.png b/packages/SystemUI/res/drawable-xhdpi/stat_notify_image.png
index 4931304..24bdbb6 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_notify_image.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_notify_image.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_notify_image_error.png b/packages/SystemUI/res/drawable-xhdpi/stat_notify_image_error.png
index 5ba83b6..6ecd2d3 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_notify_image_error.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_notify_image_error.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_notify_more.png b/packages/SystemUI/res/drawable-xhdpi/stat_notify_more.png
index 16bf510..64327ba 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_notify_more.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_notify_more.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_alarm.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_alarm.png
index 19ad300..8bca860 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_alarm.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_alarm.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_0.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_0.png
index 2b47449..8ea54ee 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_0.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_100.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_100.png
index 36c61e1..877abf4 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_100.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_15.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_15.png
index 00f3aca..94605c9 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_15.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_28.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_28.png
index ae5d0ca..c4b77ec 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_28.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_43.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_43.png
index 201a33c..9983d60 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_43.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_57.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_57.png
index a0c9d3a..de09dc6 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_57.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_71.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_71.png
index 6595973..99908696 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_71.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_85.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_85.png
index 40fce24..7a630f9 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_85.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim0.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim0.png
index eee1bde..4378a895 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim0.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim100.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim100.png
index c7fd719..dc144aa 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim100.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim15.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim15.png
index 7bbbe27..722148c 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim15.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim28.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim28.png
index 88c65f8..a3d11f2 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim28.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim43.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim43.png
index f89e797..9e63b78 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim43.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim57.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim57.png
index d58d5f6..74f9129 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim57.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim71.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim71.png
index 1ea3ed2..38838fe 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim71.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim85.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim85.png
index 7c89149..28d26f2 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim85.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_battery_charge_anim85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_bluetooth.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_bluetooth.png
index 524b31b..757dbf3 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_bluetooth.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_bluetooth.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_bluetooth_connected.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_bluetooth_connected.png
index 25eb75e..d431dc2 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_bluetooth_connected.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_bluetooth_connected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_1x.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_1x.png
deleted file mode 100644
index bd31253..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_1x.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_3g.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_3g.png
deleted file mode 100644
index 5ed365c..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_3g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_4g.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_4g.png
deleted file mode 100644
index 5b22d20..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_4g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_e.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_e.png
deleted file mode 100644
index b156b06..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_e.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_g.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_g.png
deleted file mode 100644
index f850477..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_g.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_h.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_h.png
deleted file mode 100644
index b261c1e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_h.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_lte.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_lte.png
deleted file mode 100644
index 7a59975..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_lte.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_roam.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_roam.png
deleted file mode 100644
index c0b1fea..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_connected_roam.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_1x.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_1x.png
index cb2be9d..2204093 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_1x.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_3g.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_3g.png
index 61821c7..9f5e4af 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_3g.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_4g.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_4g.png
index 2594dd4..a95b9e1 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_4g.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_e.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_e.png
index 6f2619b..42ad245 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_e.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_g.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_g.png
index 7f7c6f2..fde5323 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_g.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_h.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_h.png
index 24830b6..c6cca3e 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_h.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_lte.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_lte.png
index 84348ad..84f5cb1 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_lte.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_lte.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_roam.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_roam.png
new file mode 100644
index 0000000..5228c29
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_fully_connected_roam.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_0.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_0.png
index 7a8d1f3..f64d582 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_0.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_0_fully.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_0_fully.png
index 5f86bbb..31f5b90 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_0_fully.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_0_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_1.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_1.png
index 70e2011..881d5e8 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_1.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_1_fully.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_1_fully.png
index c1d1cc3..2d80c4d 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_1_fully.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_2.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_2.png
index c62d977..ad85c83 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_2.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_2_fully.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_2_fully.png
index 86d30df..bde43c6 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_2_fully.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_3.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_3.png
index b112748..914ac49 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_3.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_3_fully.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_3_fully.png
index bfc7d81..c83e9fe 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_3_fully.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_disconnected.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_disconnected.png
index bea643f3a..48bca90 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_disconnected.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_disconnected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_idle.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_idle.png
index a8a89d6..15514340 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_idle.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_data_wimax_signal_idle.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_device_access_location_found.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_device_access_location_found.png
new file mode 100644
index 0000000..a7f0017
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_device_access_location_found.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_gps_acquiring.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_gps_acquiring.png
deleted file mode 100644
index 263c591..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_gps_acquiring.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_no_sim.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_no_sim.png
index 2e64402..461535c 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_no_sim.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_no_sim.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_ringer_silent.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_ringer_silent.png
index a8e8e0f..662d062 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_ringer_silent.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_ringer_silent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_ringer_vibrate.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_ringer_vibrate.png
index d2d03cd..18be9c0 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_ringer_vibrate.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_ringer_vibrate.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_roaming_cdma_0.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_roaming_cdma_0.png
index 51b291c..f0c2f05 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_roaming_cdma_0.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_roaming_cdma_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_roaming_cdma_flash_anim0.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_roaming_cdma_flash_anim0.png
deleted file mode 100644
index 23d30fe..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_roaming_cdma_flash_anim0.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_roaming_cdma_flash_anim1.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_roaming_cdma_flash_anim1.png
deleted file mode 100644
index 51b291c..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_roaming_cdma_flash_anim1.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_0.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_0.png
index 0a28885..659275f 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_0.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_0_fully.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_0_fully.png
index bbe70cc..17c0d99 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_0_fully.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_0_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_1.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_1.png
deleted file mode 100644
index 9943613..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_1.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_1_fully.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_1_fully.png
index e25a55c..8a5a476 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_1_fully.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_2.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_2.png
deleted file mode 100644
index 1fc1775..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_2.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_2_fully.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_2_fully.png
index d1aefca..a6c12b2 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_2_fully.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_3.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_3.png
deleted file mode 100644
index 82b9741..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_3.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_3_fully.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_3_fully.png
index c8c2c63..3fdc60e 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_3_fully.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_4.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_4.png
deleted file mode 100644
index 9f4979c..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_4.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_4_fully.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_4_fully.png
index b2e64b9..b09247e 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_4_fully.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_4_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_flightmode.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_flightmode.png
index 7b43654..95c217c 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_flightmode.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_flightmode.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_in.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_in.png
deleted file mode 100644
index cc9c49f..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_inout.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_inout.png
deleted file mode 100644
index 5a313c5..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_null.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_null.png
index 90b8c84..3b94b6b 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_null.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_null.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_out.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_out.png
deleted file mode 100644
index 373a4a4..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_signal_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_sync.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_sync.png
index fdd640c..75b002d 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_sync.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_sync.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_sync_error.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_sync_error.png
deleted file mode 100644
index a1a0646..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_sync_error.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_tty_mode.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_tty_mode.png
index d28972f..8c48af4 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_tty_mode.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_tty_mode.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_in.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_in.png
deleted file mode 100644
index d299daf..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_in.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_inout.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_inout.png
deleted file mode 100644
index dcfdb7b..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_inout.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_out.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_out.png
deleted file mode 100644
index fb8125a..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_out.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_0.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_0.png
index a834f79..e402ff6 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_0.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_1.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_1.png
deleted file mode 100644
index 9185030..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_1.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_1_fully.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_1_fully.png
index 76f9f4a..313ce4e 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_1_fully.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_2.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_2.png
deleted file mode 100644
index 17889bb..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_2.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_2_fully.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_2_fully.png
index 16b877b..546c7a8 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_2_fully.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_3.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_3.png
deleted file mode 100644
index e197eb6..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_3.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_3_fully.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_3_fully.png
index b6cd98c..ec45d86 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_3_fully.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_4.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_4.png
deleted file mode 100644
index a87cd66..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_4.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_4_fully.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_4_fully.png
index 625c61d..459a1a2 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_4_fully.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_4_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_null.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_null.png
index 5881402..d6f752a 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_null.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_wifi_signal_null.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/status_bar_bg_tile.png b/packages/SystemUI/res/drawable-xhdpi/status_bar_bg_tile.png
deleted file mode 100644
index d01b117..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/status_bar_bg_tile.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/status_bar_close_off.9.png b/packages/SystemUI/res/drawable-xhdpi/status_bar_close_off.9.png
index 98d0cfb..1fed081 100644
--- a/packages/SystemUI/res/drawable-xhdpi/status_bar_close_off.9.png
+++ b/packages/SystemUI/res/drawable-xhdpi/status_bar_close_off.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/status_bar_close_on.9.png b/packages/SystemUI/res/drawable-xhdpi/status_bar_close_on.9.png
index 17f4169..b4e129c 100644
--- a/packages/SystemUI/res/drawable-xhdpi/status_bar_close_on.9.png
+++ b/packages/SystemUI/res/drawable-xhdpi/status_bar_close_on.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/status_bar_expand_default.png b/packages/SystemUI/res/drawable-xhdpi/status_bar_expand_default.png
deleted file mode 100644
index 3abbe25..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/status_bar_expand_default.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/status_bar_expand_pressed.png b/packages/SystemUI/res/drawable-xhdpi/status_bar_expand_pressed.png
deleted file mode 100644
index 041eac5..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/status_bar_expand_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/status_bar_hr.9.png b/packages/SystemUI/res/drawable-xhdpi/status_bar_hr.9.png
deleted file mode 100644
index 748b9f7..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/status_bar_hr.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/title_bar_shadow.9.png b/packages/SystemUI/res/drawable-xhdpi/title_bar_shadow.9.png
deleted file mode 100644
index 89f14db..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/title_bar_shadow.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/battery_low_battery.png b/packages/SystemUI/res/drawable-xxhdpi/battery_low_battery.png
new file mode 100644
index 0000000..cebbb15
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/battery_low_battery.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/heads_up_window_bg.9.png b/packages/SystemUI/res/drawable-xxhdpi/heads_up_window_bg.9.png
new file mode 100644
index 0000000..586a738
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/heads_up_window_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_menu_share.png b/packages/SystemUI/res/drawable-xxhdpi/ic_menu_share.png
new file mode 100644
index 0000000..d450531
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_menu_share.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_notification_overlay.9.png b/packages/SystemUI/res/drawable-xxhdpi/ic_notification_overlay.9.png
new file mode 100644
index 0000000..fa7de0e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_notification_overlay.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_notify_clear_normal.png b/packages/SystemUI/res/drawable-xxhdpi/ic_notify_clear_normal.png
new file mode 100644
index 0000000..afdee8f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_notify_clear_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_notify_open_normal.png b/packages/SystemUI/res/drawable-xxhdpi/ic_notify_open_normal.png
new file mode 100644
index 0000000..60579f9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_notify_open_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-xxhdpi/ic_notify_quicksettings_normal.png
new file mode 100644
index 0000000..abb9b18
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_notify_quicksettings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_notify_settings_normal.png b/packages/SystemUI/res/drawable-xxhdpi/ic_notify_settings_normal.png
new file mode 100644
index 0000000..a3cc08d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_notify_settings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_airplane_off.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_airplane_off.png
new file mode 100644
index 0000000..9867b0b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_airplane_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_airplane_on.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_airplane_on.png
new file mode 100644
index 0000000..dd16165
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_airplane_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_alarm_on.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_alarm_on.png
new file mode 100644
index 0000000..1e8509b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_alarm_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_auto_rotate.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_auto_rotate.png
new file mode 100644
index 0000000..b6cfaec
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_auto_rotate.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_0.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_0.png
new file mode 100644
index 0000000..6ddf734
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_100.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_100.png
new file mode 100644
index 0000000..c04dc4b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_15.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_15.png
new file mode 100644
index 0000000..e1e1b2e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_28.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_28.png
new file mode 100644
index 0000000..6ff8518
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_43.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_43.png
new file mode 100644
index 0000000..c0e94f2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_57.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_57.png
new file mode 100644
index 0000000..175e14b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_71.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_71.png
new file mode 100644
index 0000000..ca6ba47
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_85.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_85.png
new file mode 100644
index 0000000..95017e4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_bang_orange.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_bang_orange.png
new file mode 100644
index 0000000..2b333d7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_bang_orange.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_bang_red.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_bang_red.png
new file mode 100644
index 0000000..4c71154
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_bang_red.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_bang_white.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_bang_white.png
new file mode 100644
index 0000000..976a36b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_bang_white.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_charge_0.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_charge_0.png
new file mode 100644
index 0000000..82d4806
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_charge_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_charge_100.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_charge_100.png
new file mode 100644
index 0000000..7d11599
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_charge_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_charge_15.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_charge_15.png
new file mode 100644
index 0000000..3b36bb9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_charge_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_charge_28.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_charge_28.png
new file mode 100644
index 0000000..d36bd5a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_charge_28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_charge_43.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_charge_43.png
new file mode 100644
index 0000000..a3f543a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_charge_43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_charge_57.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_charge_57.png
new file mode 100644
index 0000000..0208baf
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_charge_57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_charge_71.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_charge_71.png
new file mode 100644
index 0000000..ea46076
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_charge_71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_charge_85.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_charge_85.png
new file mode 100644
index 0000000..4cbfea6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_charge_85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_unknown.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_unknown.png
new file mode 100644
index 0000000..5ae0221
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_battery_unknown.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_bluetooth_not_connected.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_bluetooth_not_connected.png
new file mode 100644
index 0000000..c5b7333
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_bluetooth_not_connected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_bluetooth_off.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_bluetooth_off.png
new file mode 100644
index 0000000..ca1aef0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_bluetooth_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_bluetooth_on.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_bluetooth_on.png
new file mode 100644
index 0000000..7c20110
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_bluetooth_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_brightness_auto_off.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_brightness_auto_off.png
new file mode 100644
index 0000000..2697b5a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_brightness_auto_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_brightness_auto_on.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_brightness_auto_on.png
new file mode 100644
index 0000000..b6443fa
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_brightness_auto_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_certificate_info.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_certificate_info.png
new file mode 100644
index 0000000..5d6f6c7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_certificate_info.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_clock_circle.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_clock_circle.png
new file mode 100644
index 0000000..849d547
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_clock_circle.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_clock_hour.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_clock_hour.png
new file mode 100644
index 0000000..57dd8a6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_clock_hour.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_clock_minute.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_clock_minute.png
new file mode 100644
index 0000000..a9b8ba5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_clock_minute.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_default_user.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_default_user.png
new file mode 100644
index 0000000..07f16c3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_default_user.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_ime.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_ime.png
new file mode 100644
index 0000000..ab841d2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_location.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_location.png
new file mode 100644
index 0000000..3175636
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_location.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_location_off.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_location_off.png
new file mode 100644
index 0000000..920407d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_location_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_location_on.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_location_on.png
new file mode 100644
index 0000000..3175636
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_location_on.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_remote_display.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_remote_display.png
new file mode 100644
index 0000000..5f6231c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_remote_display.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_remote_display_connected.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_remote_display_connected.png
new file mode 100644
index 0000000..f02d0ab
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_remote_display_connected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_rotation_locked.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_rotation_locked.png
new file mode 100644
index 0000000..8e37884
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_rotation_locked.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_settings.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_settings.png
new file mode 100644
index 0000000..d1a72be
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_settings.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_0.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_0.png
new file mode 100644
index 0000000..76f39c0
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_1.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_1.png
new file mode 100644
index 0000000..746b9ea
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_1x.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_1x.png
new file mode 100644
index 0000000..6706ae2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_2.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_2.png
new file mode 100644
index 0000000..55ba5ab
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_3.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_3.png
new file mode 100644
index 0000000..547f875
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_3g.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_3g.png
new file mode 100644
index 0000000..4d1dc75
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_4.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_4.png
new file mode 100644
index 0000000..1f65ad5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_4g.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_4g.png
new file mode 100644
index 0000000..aab9d27
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_e.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_e.png
new file mode 100644
index 0000000..cd92c5f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_0.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_0.png
new file mode 100644
index 0000000..eb4b855
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_1.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_1.png
new file mode 100644
index 0000000..edc44ab
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_1x.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_1x.png
new file mode 100644
index 0000000..ed1f7c5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_2.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_2.png
new file mode 100644
index 0000000..5bd9b76
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_3.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_3.png
new file mode 100644
index 0000000..16196a03
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_3g.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_3g.png
new file mode 100644
index 0000000..a4f4461
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_4.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_4.png
new file mode 100644
index 0000000..7b3d06d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_4g.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_4g.png
new file mode 100644
index 0000000..7cdcdf4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_e.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_e.png
new file mode 100644
index 0000000..c9bed1a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_g.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_g.png
new file mode 100644
index 0000000..b9aca9a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_h.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_h.png
new file mode 100644
index 0000000..25edf97
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_lte.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_lte.png
new file mode 100644
index 0000000..0dc66b4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_lte.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_r.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_r.png
new file mode 100644
index 0000000..b60cda6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_full_r.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_g.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_g.png
new file mode 100644
index 0000000..b686376
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_h.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_h.png
new file mode 100644
index 0000000..bfe2271
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_in.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_in.png
new file mode 100644
index 0000000..1094bc3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_inout.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_inout.png
new file mode 100644
index 0000000..1037b02
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_lte.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_lte.png
new file mode 100644
index 0000000..b5def3e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_lte.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_no_network.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_no_network.png
new file mode 100644
index 0000000..78fe964
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_no_network.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_no_signal.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_no_signal.png
new file mode 100644
index 0000000..d2e27d9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_no_signal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_out.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_out.png
new file mode 100644
index 0000000..f5595e3b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_r.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_r.png
new file mode 100644
index 0000000..60e2bd3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_signal_r.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_usb_device.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_usb_device.png
new file mode 100644
index 0000000..99abb6a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_usb_device.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_0.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_0.png
new file mode 100644
index 0000000..f1d9f21
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_1.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_1.png
new file mode 100644
index 0000000..01274a6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_2.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_2.png
new file mode 100644
index 0000000..a02832d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_3.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_3.png
new file mode 100644
index 0000000..7e55bbb
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_4.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_4.png
new file mode 100644
index 0000000..eeb8989
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_full_1.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_full_1.png
new file mode 100644
index 0000000..dbae28c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_full_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_full_2.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_full_2.png
new file mode 100644
index 0000000..06e8d5b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_full_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_full_3.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_full_3.png
new file mode 100644
index 0000000..bff132b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_full_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_full_4.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_full_4.png
new file mode 100644
index 0000000..636bd702
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_full_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_in.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_in.png
new file mode 100644
index 0000000..7183a07
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_in.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_inout.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_inout.png
new file mode 100644
index 0000000..3746328
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_inout.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_no_network.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_no_network.png
new file mode 100644
index 0000000..83402ff
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_no_network.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_not_connected.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_not_connected.png
new file mode 100644
index 0000000..9c5a207
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_not_connected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_out.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_out.png
new file mode 100644
index 0000000..dbf54ce
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_wifi_out.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back.png
new file mode 100644
index 0000000..79cfcee
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime.png
new file mode 100644
index 0000000..7959f65
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_land.png
new file mode 100644
index 0000000..c3bfcfb
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_highlight.png
new file mode 100644
index 0000000..0df6203
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_highlight.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_highlight_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_highlight_land.png
new file mode 100644
index 0000000..b400b14
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_highlight_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home.png
new file mode 100644
index 0000000..64f6a22
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_land.png
new file mode 100644
index 0000000..8fd36bc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_lights_out_dot_large.png
new file mode 100644
index 0000000..55a266f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_lights_out_dot_large.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_lights_out_dot_small.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_lights_out_dot_small.png
new file mode 100644
index 0000000..97d1fbc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_lights_out_dot_small.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu.png
new file mode 100644
index 0000000..6f30e54
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu_land.png
new file mode 100644
index 0000000..024ef8f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent.png
new file mode 100644
index 0000000..6e0b071
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_land.png
new file mode 100644
index 0000000..9a56987
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-xxhdpi/notification_panel_bg.9.png
new file mode 100644
index 0000000..adcdcb7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/recents_thumbnail_bg.9.png b/packages/SystemUI/res/drawable-xxhdpi/recents_thumbnail_bg.9.png
new file mode 100644
index 0000000..a446448
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/recents_thumbnail_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/recents_thumbnail_bg_dragging.9.png b/packages/SystemUI/res/drawable-xxhdpi/recents_thumbnail_bg_dragging.9.png
new file mode 100644
index 0000000..c424ffe
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/recents_thumbnail_bg_dragging.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/recents_thumbnail_bg_normal.9.png b/packages/SystemUI/res/drawable-xxhdpi/recents_thumbnail_bg_normal.9.png
new file mode 100644
index 0000000..a446448
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/recents_thumbnail_bg_normal.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/recents_thumbnail_bg_press.9.png b/packages/SystemUI/res/drawable-xxhdpi/recents_thumbnail_bg_press.9.png
new file mode 100644
index 0000000..b7bbd82
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/recents_thumbnail_bg_press.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/screenshot_panel.9.png b/packages/SystemUI/res/drawable-xxhdpi/screenshot_panel.9.png
new file mode 100644
index 0000000..45259d7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/screenshot_panel.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/search_light.png b/packages/SystemUI/res/drawable-xxhdpi/search_light.png
new file mode 100644
index 0000000..faa97f8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/search_light.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_notify_image.png b/packages/SystemUI/res/drawable-xxhdpi/stat_notify_image.png
new file mode 100644
index 0000000..5e733ef
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_notify_image.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_notify_image_error.png b/packages/SystemUI/res/drawable-xxhdpi/stat_notify_image_error.png
new file mode 100644
index 0000000..ecc2c83
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_notify_image_error.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_notify_more.png b/packages/SystemUI/res/drawable-xxhdpi/stat_notify_more.png
new file mode 100644
index 0000000..3c33a56
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_notify_more.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_alarm.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_alarm.png
new file mode 100644
index 0000000..d42d9d6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_alarm.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_0.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_0.png
new file mode 100644
index 0000000..2d916d7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_100.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_100.png
new file mode 100644
index 0000000..fe3c750
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_15.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_15.png
new file mode 100644
index 0000000..a2bab6d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_28.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_28.png
new file mode 100644
index 0000000..224be03
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_43.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_43.png
new file mode 100644
index 0000000..dabed32
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_57.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_57.png
new file mode 100644
index 0000000..82d04c5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_71.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_71.png
new file mode 100644
index 0000000..1d403c6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_85.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_85.png
new file mode 100644
index 0000000..b917d37
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_charge_anim0.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_charge_anim0.png
new file mode 100644
index 0000000..3356733
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_charge_anim0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_charge_anim100.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_charge_anim100.png
new file mode 100644
index 0000000..080bdda
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_charge_anim100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_charge_anim15.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_charge_anim15.png
new file mode 100644
index 0000000..0d1e47a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_charge_anim15.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_charge_anim28.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_charge_anim28.png
new file mode 100644
index 0000000..f565046
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_charge_anim28.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_charge_anim43.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_charge_anim43.png
new file mode 100644
index 0000000..378d433
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_charge_anim43.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_charge_anim57.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_charge_anim57.png
new file mode 100644
index 0000000..3bd5759
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_charge_anim57.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_charge_anim71.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_charge_anim71.png
new file mode 100644
index 0000000..3d56db4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_charge_anim71.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_charge_anim85.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_charge_anim85.png
new file mode 100644
index 0000000..2d24d99
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_battery_charge_anim85.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_bluetooth.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_bluetooth.png
new file mode 100644
index 0000000..17ffdb9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_bluetooth.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_bluetooth_connected.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_bluetooth_connected.png
new file mode 100644
index 0000000..6ec234e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_bluetooth_connected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_fully_connected_1x.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_fully_connected_1x.png
new file mode 100644
index 0000000..ba64922
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_fully_connected_1x.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_fully_connected_3g.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_fully_connected_3g.png
new file mode 100644
index 0000000..5b57c1e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_fully_connected_3g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_fully_connected_4g.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_fully_connected_4g.png
new file mode 100644
index 0000000..64b8b26
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_fully_connected_4g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_fully_connected_e.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_fully_connected_e.png
new file mode 100644
index 0000000..02e7411
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_fully_connected_e.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_fully_connected_g.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_fully_connected_g.png
new file mode 100644
index 0000000..0a5dc61
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_fully_connected_g.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_fully_connected_h.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_fully_connected_h.png
new file mode 100644
index 0000000..96a747c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_fully_connected_h.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_fully_connected_lte.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_fully_connected_lte.png
new file mode 100644
index 0000000..46584bc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_fully_connected_lte.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_fully_connected_roam.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_fully_connected_roam.png
new file mode 100644
index 0000000..1f8549e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_fully_connected_roam.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_0.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_0.png
new file mode 100644
index 0000000..21daf5c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_0_fully.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_0_fully.png
new file mode 100644
index 0000000..3397570
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_0_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_1.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_1.png
new file mode 100644
index 0000000..87039c5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_1_fully.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_1_fully.png
new file mode 100644
index 0000000..a21f3c4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_2.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_2.png
new file mode 100644
index 0000000..65b323f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_2_fully.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_2_fully.png
new file mode 100644
index 0000000..c5c3550
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_3.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_3.png
new file mode 100644
index 0000000..801cb3c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_3_fully.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_3_fully.png
new file mode 100644
index 0000000..149d227
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_disconnected.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_disconnected.png
new file mode 100644
index 0000000..6edb37a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_disconnected.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_idle.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_idle.png
new file mode 100644
index 0000000..2b01e9b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_data_wimax_signal_idle.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_device_access_location_found.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_device_access_location_found.png
new file mode 100644
index 0000000..ad34d49
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_device_access_location_found.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_no_sim.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_no_sim.png
new file mode 100644
index 0000000..7b03a11
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_no_sim.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_ringer_silent.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_ringer_silent.png
new file mode 100644
index 0000000..aabf0aa
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_ringer_silent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_ringer_vibrate.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_ringer_vibrate.png
new file mode 100644
index 0000000..654c2a5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_ringer_vibrate.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_roaming_cdma_0.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_roaming_cdma_0.png
new file mode 100644
index 0000000..1c544c4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_roaming_cdma_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_0.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_0.png
new file mode 100644
index 0000000..3c9d3e6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_0_fully.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_0_fully.png
new file mode 100644
index 0000000..065f1da
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_0_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_1_fully.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_1_fully.png
new file mode 100644
index 0000000..da2da18
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_2_fully.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_2_fully.png
new file mode 100644
index 0000000..30c5abf
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_3_fully.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_3_fully.png
new file mode 100644
index 0000000..e49fd0a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_4_fully.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_4_fully.png
new file mode 100644
index 0000000..c5114e7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_4_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_flightmode.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_flightmode.png
new file mode 100644
index 0000000..155c222
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_flightmode.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_null.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_null.png
new file mode 100644
index 0000000..b388b8f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_signal_null.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_sync.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_sync.png
new file mode 100644
index 0000000..99b2fff
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_sync.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_tty_mode.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_tty_mode.png
new file mode 100644
index 0000000..075208a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_tty_mode.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_0.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_0.png
new file mode 100644
index 0000000..bc272ed
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_1_fully.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_1_fully.png
new file mode 100644
index 0000000..d032db3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_2_fully.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_2_fully.png
new file mode 100644
index 0000000..562101b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_3_fully.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_3_fully.png
new file mode 100644
index 0000000..ceb4163
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_4_fully.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_4_fully.png
new file mode 100644
index 0000000..494b005
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_4_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_null.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_null.png
new file mode 100644
index 0000000..3da56ad
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_wifi_signal_null.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/status_bar_close_off.9.png b/packages/SystemUI/res/drawable-xxhdpi/status_bar_close_off.9.png
new file mode 100644
index 0000000..d50ff85
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/status_bar_close_off.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/status_bar_close_on.9.png b/packages/SystemUI/res/drawable-xxhdpi/status_bar_close_on.9.png
new file mode 100644
index 0000000..5d27ccd
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/status_bar_close_on.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/title_bar_shadow.9.png b/packages/SystemUI/res/drawable-xxhdpi/title_bar_shadow.9.png
new file mode 100644
index 0000000..e86f891
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/title_bar_shadow.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/alert_bar_background.xml b/packages/SystemUI/res/drawable/alert_bar_background.xml
deleted file mode 100644
index 24b6aa3..0000000
--- a/packages/SystemUI/res/drawable/alert_bar_background.xml
+++ /dev/null
@@ -1,23 +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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_pressed="true" 
-        android:drawable="@drawable/alert_bar_background_pressed" />
-    <item
-         android:drawable="@drawable/alert_bar_background_normal" />
-</selector>
-
diff --git a/packages/SystemUI/res/drawable/btn_default_small.xml b/packages/SystemUI/res/drawable/btn_default_small.xml
deleted file mode 100644
index 5485ea0..0000000
--- a/packages/SystemUI/res/drawable/btn_default_small.xml
+++ /dev/null
@@ -1,33 +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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_window_focused="false" android:state_enabled="true"
-        android:drawable="@drawable/btn_default_small_normal" />
-    <item android:state_window_focused="false" android:state_enabled="false"
-        android:drawable="@drawable/btn_default_small_normal_disable" />
-    <item android:state_pressed="true" 
-        android:drawable="@drawable/btn_default_small_pressed" />
-    <item android:state_focused="true" android:state_enabled="true"
-        android:drawable="@drawable/btn_default_small_selected" />
-    <item android:state_enabled="true"
-        android:drawable="@drawable/btn_default_small_normal" />
-    <item android:state_focused="true"
-        android:drawable="@drawable/btn_default_small_normal_disable_focused" />
-    <item
-         android:drawable="@drawable/btn_default_small_normal_disable" />
-</selector>
-
diff --git a/packages/SystemUI/res/drawable/cling_button_bg.xml b/packages/SystemUI/res/drawable/cling_button_bg.xml
deleted file mode 100644
index d175f53..0000000
--- a/packages/SystemUI/res/drawable/cling_button_bg.xml
+++ /dev/null
@@ -1,20 +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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_pressed="true" android:drawable="@drawable/btn_cling_pressed" />
-    <item android:drawable="@drawable/btn_cling_normal" />
-</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/hd.xml b/packages/SystemUI/res/drawable/hd.xml
deleted file mode 100644
index 73867a2..0000000
--- a/packages/SystemUI/res/drawable/hd.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_checked="false"
-          android:drawable="@drawable/hd_off" />
-    <item android:drawable="@drawable/hd_on" />
-</selector>
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
new file mode 100644
index 0000000..59d9fcf
--- /dev/null
+++ b/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
@@ -0,0 +1,21 @@
+<?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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
+    <item android:state_pressed="true"
+          android:drawable="@drawable/heads_up_notification_bg_pressed" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/ic_notify_rotation.xml b/packages/SystemUI/res/drawable/ic_notify_rotation.xml
deleted file mode 100644
index 11bc22c..0000000
--- a/packages/SystemUI/res/drawable/ic_notify_rotation.xml
+++ /dev/null
@@ -1,36 +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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:constantSize="true">
-    <item android:state_checked="true" android:state_pressed="true">
-        <bitmap android:src="@drawable/ic_notify_rotation_on_pressed"
-                android:gravity="center" />
-    </item>
-    <item android:state_checked="true">
-        <bitmap android:src="@drawable/ic_notify_rotation_on_normal"
-                android:gravity="center" />
-    </item>
-    <item android:state_pressed="true">
-        <bitmap android:src="@drawable/ic_notify_rotation_off_pressed"
-                android:gravity="center" />
-    </item>
-    <item>
-        <bitmap android:src="@drawable/ic_notify_rotation_off_normal"
-                android:gravity="center" />
-    </item>
-</selector>
-
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_ime.xml b/packages/SystemUI/res/drawable/ic_sysbar_ime.xml
deleted file mode 100644
index 1accf00..0000000
--- a/packages/SystemUI/res/drawable/ic_sysbar_ime.xml
+++ /dev/null
@@ -1,21 +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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_pressed="true" android:drawable="@drawable/ic_sysbar_ime_pressed" />
-    <item android:drawable="@drawable/ic_sysbar_ime_default" />
-</selector>
-
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_zoom.xml b/packages/SystemUI/res/drawable/ic_sysbar_zoom.xml
deleted file mode 100644
index 97d0348..0000000
--- a/packages/SystemUI/res/drawable/ic_sysbar_zoom.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_pressed="true" android:drawable="@drawable/ic_sysbar_zoom_pressed" />
-    <item android:state_selected="true" android:drawable="@drawable/ic_sysbar_zoom_pressed" />
-    <item android:drawable="@drawable/ic_sysbar_zoom_default" />
-</selector>
-
diff --git a/packages/SystemUI/res/drawable/intruder_row_bg.xml b/packages/SystemUI/res/drawable/intruder_row_bg.xml
deleted file mode 100644
index 1c7c9c4..0000000
--- a/packages/SystemUI/res/drawable/intruder_row_bg.xml
+++ /dev/null
@@ -1,20 +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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:exitFadeDuration="@android:integer/config_mediumAnimTime">
-    <item android:state_pressed="true"  android:drawable="@drawable/intruder_bg_pressed" />
-</selector>
diff --git a/packages/SystemUI/res/drawable/intruder_window_bg.9.png b/packages/SystemUI/res/drawable/intruder_window_bg.9.png
deleted file mode 100644
index caad169..0000000
--- a/packages/SystemUI/res/drawable/intruder_window_bg.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable/notify_panel_clock_bg.xml b/packages/SystemUI/res/drawable/notify_panel_clock_bg.xml
deleted file mode 100644
index c83d878..0000000
--- a/packages/SystemUI/res/drawable/notify_panel_clock_bg.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_pressed="true"
-        android:drawable="@drawable/notify_panel_clock_bg_pressed" />
-    <item android:drawable="@drawable/notify_panel_clock_bg_normal" />
-</selector>
-
diff --git a/packages/SystemUI/res/drawable/pocket_drag_bg.xml b/packages/SystemUI/res/drawable/pocket_drag_bg.xml
deleted file mode 100644
index 573a702..0000000
--- a/packages/SystemUI/res/drawable/pocket_drag_bg.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<bitmap
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:tileMode="repeat"
-    android:src="@drawable/pocket_drag_pattern"
-    />
diff --git a/packages/SystemUI/res/drawable/stat_sys_gps_acquiring_anim.xml b/packages/SystemUI/res/drawable/stat_sys_gps_acquiring_anim.xml
deleted file mode 100644
index 393697c..0000000
--- a/packages/SystemUI/res/drawable/stat_sys_gps_acquiring_anim.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2008, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<animation-list
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        android:oneshot="false">
-    <item android:drawable="@drawable/stat_sys_gps_acquiring" android:duration="500" />
-    <item android:drawable="@*android:drawable/stat_sys_gps_on" android:duration="500" />
-</animation-list>
diff --git a/packages/SystemUI/res/drawable/stat_sys_roaming_cdma_flash.xml b/packages/SystemUI/res/drawable/stat_sys_roaming_cdma_flash.xml
deleted file mode 100644
index 07dc446..0000000
--- a/packages/SystemUI/res/drawable/stat_sys_roaming_cdma_flash.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/res/drawable/stat_sys_battery.xml
-**
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<animation-list
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        android:oneshot="false">
-    <item android:drawable="@drawable/stat_sys_roaming_cdma_flash_anim0" android:duration="800" />
-    <item android:drawable="@drawable/stat_sys_roaming_cdma_flash_anim1" android:duration="1200" />
-</animation-list>
diff --git a/packages/SystemUI/res/drawable/status_bar_bg.xml b/packages/SystemUI/res/drawable/status_bar_bg.xml
deleted file mode 100644
index 403493b..0000000
--- a/packages/SystemUI/res/drawable/status_bar_bg.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<bitmap
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:tileMode="repeat"
-    android:src="@drawable/status_bar_bg_tile"
-    />
diff --git a/packages/SystemUI/res/drawable/status_bar_expand.xml b/packages/SystemUI/res/drawable/status_bar_expand.xml
deleted file mode 100644
index f966920..0000000
--- a/packages/SystemUI/res/drawable/status_bar_expand.xml
+++ /dev/null
@@ -1,21 +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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_pressed="true" android:drawable="@drawable/status_bar_expand_pressed" />
-    <item android:drawable="@drawable/status_bar_expand_default" />
-</selector>
-
diff --git a/packages/SystemUI/res/layout-land/status_bar_help.xml b/packages/SystemUI/res/layout-land/status_bar_help.xml
deleted file mode 100644
index a885b86..0000000
--- a/packages/SystemUI/res/layout-land/status_bar_help.xml
+++ /dev/null
@@ -1,71 +0,0 @@
-<?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.
-*/
--->
-
-<!-- This is the combined status bar / notification panel window. -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:id="@+id/status_bar_cling"
-    android:paddingStart="40dp"
-    android:paddingEnd="40dp"
-    android:background="#DD000000"
-    android:focusable="true"
-    android:orientation="horizontal" 
-    android:gravity="top|start"
-    >
-
-    <ImageView
-        android:layout_width="wrap_content"
-        android:layout_weight="0"
-        android:layout_height="wrap_content"
-        android:layout_marginEnd="50dp"
-        android:gravity="center"
-        android:src="@drawable/arrow_dashed"
-        tools:ignore="ContentDescription" />
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_weight="1"
-        android:orientation="vertical"
-        android:layout_marginTop="40dp"
-        >
-        <TextView
-            style="@style/ClingTitleText"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:text="@string/status_bar_help_title" />
-
-        <TextView
-            style="@style/ClingText"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_marginBottom="30dp"
-            android:text="@string/status_bar_help_text" />
-
-        <Button
-            android:id="@+id/ok"
-            style="@style/ClingButton"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:paddingStart="50dp"
-            android:paddingEnd="50dp"
-            android:text="@android:string/ok" />
-    </LinearLayout>
-</LinearLayout>
diff --git a/packages/SystemUI/res/layout/compat_mode_help.xml b/packages/SystemUI/res/layout/compat_mode_help.xml
deleted file mode 100644
index 566d07d..0000000
--- a/packages/SystemUI/res/layout/compat_mode_help.xml
+++ /dev/null
@@ -1,92 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-
-<RelativeLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_height="match_parent"
-    android:layout_width="match_parent"
-    android:background="@drawable/compat_mode_help_bg"
-    >
-    <TextView
-        android:id="@+id/header"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="80dp"
-        android:layout_marginTop="80dp"
-        android:layout_marginEnd="80dp"
-        android:textSize="60sp"
-        android:maxLines="1"
-        android:shadowRadius="8"
-        android:shadowColor="#FF000000"
-        android:text="@string/compat_mode_help_header"
-        android:background="@drawable/compat_mode_help_divider_top"
-        />
-    <ImageView
-        android:id="@+id/diagram"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_centerInParent="true"
-        android:src="@drawable/compat_mode_help_diagram"
-        android:contentDescription="@string/accessibility_compatibility_zoom_example"
-        />
-    <RelativeLayout
-        android:orientation="horizontal"
-        android:layout_width="match_parent"
-        android:layout_height="190dp"
-        android:background="@drawable/compat_mode_help_divider_bottom"
-        android:layout_marginBottom="55dp"
-        android:layout_marginEnd="80dp"
-        android:layout_alignStart="@id/header"
-        android:layout_alignParentBottom="true"
-        >
-        <ImageView
-            android:id="@+id/icon"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_alignParentEnd="true"
-            android:layout_centerVertical="true"
-            android:src="@drawable/compat_mode_help_icon"
-            android:contentDescription="@string/accessibility_compatibility_zoom_button"
-            />
-        <TextView
-            android:id="@+id/explanation"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_centerVertical="true"
-            android:layout_alignParentStart="true"
-            android:layout_toStartOf="@id/icon"
-            android:layout_marginEnd="10dp"
-            android:shadowRadius="4"
-            android:shadowColor="#FF000000"
-            android:textSize="28sp"
-            android:text="@string/compat_mode_help_body"
-            />
-    </RelativeLayout>
-    <Button
-        android:id="@+id/button"
-        android:layout_width="208dp"
-        android:layout_height="48dp"
-        android:layout_alignStart="@id/header"
-        android:layout_alignParentBottom="true"
-        android:layout_marginBottom="20dp"
-        android:textSize="28sp"
-        android:text="@android:string/ok"
-        />
-</RelativeLayout>
-
diff --git a/packages/SystemUI/res/layout/heads_up.xml b/packages/SystemUI/res/layout/heads_up.xml
new file mode 100644
index 0000000..564dc51
--- /dev/null
+++ b/packages/SystemUI/res/layout/heads_up.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* apps/common/assets/default/default/skins/StatusBar.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+-->
+
+<!--    android:background="@drawable/status_bar_closed_default_background" -->
+<com.android.systemui.statusbar.policy.HeadsUpNotificationView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_height="wrap_content"
+    android:layout_width="match_parent"
+    android:orientation="vertical"
+    >
+    <FrameLayout
+            android:layout_height="wrap_content"
+            android:layout_width="@dimen/notification_panel_width"
+            android:id="@+id/content_slider"
+            android:layout_marginStart="@dimen/notification_panel_margin_left"
+            >
+        <FrameLayout
+                android:layout_height="wrap_content"
+                android:layout_width="match_parent"
+                android:id="@+id/content_holder"
+                android:background="@drawable/heads_up_window_bg"
+                />
+    </FrameLayout>
+</com.android.systemui.statusbar.policy.HeadsUpNotificationView>
diff --git a/packages/SystemUI/res/layout/intruder_alert.xml b/packages/SystemUI/res/layout/intruder_alert.xml
deleted file mode 100644
index c4141ae..0000000
--- a/packages/SystemUI/res/layout/intruder_alert.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* apps/common/assets/default/default/skins/StatusBar.xml
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
--->
-
-<!--    android:background="@drawable/status_bar_closed_default_background" -->
-<com.android.systemui.statusbar.policy.IntruderAlertView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_height="wrap_content"
-    android:layout_width="match_parent"
-    android:orientation="vertical"
-    >
-    <FrameLayout
-        android:layout_height="wrap_content"
-        android:layout_width="match_parent"
-        android:id="@+id/contentHolder"
-        android:background="@drawable/intruder_window_bg"
-        />
-<!--    <ImageView
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:src="@drawable/title_bar_shadow"
-        android:scaleType="fitXY"
-        /> -->
-</com.android.systemui.statusbar.policy.IntruderAlertView>
diff --git a/packages/SystemUI/res/layout/quick_settings_tile_battery.xml b/packages/SystemUI/res/layout/quick_settings_tile_battery.xml
index c41e9b9..f3b894c 100644
--- a/packages/SystemUI/res/layout/quick_settings_tile_battery.xml
+++ b/packages/SystemUI/res/layout/quick_settings_tile_battery.xml
@@ -19,14 +19,14 @@
         android:layout_height="match_parent"
         android:layout_gravity="top"
         android:orientation="vertical">
-    <ImageView
+    <com.android.systemui.BatteryMeterView
             android:id="@+id/image"
             android:layout_marginTop="@dimen/qs_tile_margin_above_icon"
             android:layout_marginBottom="@dimen/qs_tile_margin_below_icon"
-            android:layout_width="@dimen/qs_tile_icon_size"
-            android:layout_height="@dimen/qs_tile_icon_size"
+            android:layout_width="22dp"
+            android:layout_height="32dp"
+            android:padding="3dp"
             android:layout_gravity="top|center_horizontal"
-            android:scaleType="centerInside"
             />
     <TextView
             style="@style/TextAppearance.QuickSettings.TileView"
@@ -36,4 +36,4 @@
             android:layout_gravity="top|center_horizontal"
             android:gravity="top|center_horizontal"
             />
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout/quick_settings_tile_rssi.xml b/packages/SystemUI/res/layout/quick_settings_tile_rssi.xml
index 34506b1..cabfaa5 100644
--- a/packages/SystemUI/res/layout/quick_settings_tile_rssi.xml
+++ b/packages/SystemUI/res/layout/quick_settings_tile_rssi.xml
@@ -13,32 +13,49 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<LinearLayout
+<RelativeLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:layout_gravity="top"
-    android:orientation="vertical">
+    android:layout_gravity="top">
     <FrameLayout
+        android:id="@+id/rssi_images"
         android:layout_marginTop="@dimen/qs_tile_margin_above_icon"
         android:layout_marginBottom="@dimen/qs_tile_margin_below_icon"
         android:layout_width="@dimen/qs_tile_icon_size"
         android:layout_height="@dimen/qs_tile_icon_size"
         android:layout_gravity="top|center_horizontal"
+        android:layout_centerHorizontal="true"
         >
         <ImageView
             android:id="@+id/rssi_image"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_gravity="center"
+            android:layout_centerInParent="true"
             />
         <ImageView
             android:id="@+id/rssi_overlay_image"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_gravity="center"
+            android:layout_centerInParent="true"
             />
     </FrameLayout>
+    <ImageView
+            android:id="@+id/activity_in"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/ic_qs_signal_in"
+            android:layout_toRightOf="@id/rssi_images"
+            android:layout_alignBottom="@id/rssi_images"
+            />
+    <ImageView
+            android:id="@+id/activity_out"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/ic_qs_signal_out"
+            android:layout_toRightOf="@id/rssi_images"
+            android:layout_alignBottom="@id/rssi_images"
+            />
     <TextView
         style="@style/TextAppearance.QuickSettings.TileView"
         android:id="@+id/rssi_textview"
@@ -47,5 +64,7 @@
         android:layout_gravity="top|center_horizontal"
         android:gravity="top|center_horizontal"
         android:text="@string/quick_settings_rssi_label"
+        android:layout_centerHorizontal="true"
+        android:layout_below="@id/rssi_images"
         />
-</LinearLayout>
\ No newline at end of file
+</RelativeLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/quick_settings_tile_wifi.xml b/packages/SystemUI/res/layout/quick_settings_tile_wifi.xml
new file mode 100644
index 0000000..e61c595
--- /dev/null
+++ b/packages/SystemUI/res/layout/quick_settings_tile_wifi.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:layout_gravity="top">
+    <ImageView
+        android:id="@+id/image"
+        android:layout_marginTop="@dimen/qs_tile_margin_above_icon"
+        android:layout_marginBottom="@dimen/qs_tile_margin_below_icon"
+        android:layout_width="@dimen/qs_tile_icon_size"
+        android:layout_height="@dimen/qs_tile_icon_size"
+        android:layout_gravity="top|center_horizontal"
+        android:layout_centerHorizontal="true"
+        android:scaleType="centerInside"
+        />
+    <ImageView
+            android:id="@+id/activity_in"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/ic_qs_wifi_in"
+            android:layout_toRightOf="@id/image"
+            android:layout_alignBottom="@id/image"
+            />
+    <ImageView
+            android:id="@+id/activity_out"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/ic_qs_wifi_out"
+            android:layout_toRightOf="@id/image"
+            android:layout_alignBottom="@id/image"
+            />
+    <TextView
+        style="@style/TextAppearance.QuickSettings.TileView"
+        android:id="@+id/text"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="top|center_horizontal"
+        android:gravity="top|center_horizontal"
+        android:layout_centerHorizontal="true"
+        android:layout_below="@id/image" 
+        />
+</RelativeLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/signal_cluster_view.xml b/packages/SystemUI/res/layout/signal_cluster_view.xml
index aab5083..2b9cef91 100644
--- a/packages/SystemUI/res/layout/signal_cluster_view.xml
+++ b/packages/SystemUI/res/layout/signal_cluster_view.xml
@@ -20,8 +20,9 @@
 
 <com.android.systemui.statusbar.SignalClusterView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_height="wrap_content"
+    android:layout_height="match_parent"
     android:layout_width="wrap_content"
+    android:gravity="center"
     android:orientation="horizontal"
     >
     <FrameLayout
@@ -38,12 +39,6 @@
             android:layout_centerVertical="true"
             android:scaleType="center"
             />
-        <ImageView
-            android:id="@+id/wifi_inout"
-            android:layout_height="wrap_content"
-            android:layout_width="wrap_content"
-            android:layout_gravity="center|bottom"
-            />
     </FrameLayout>
     <View
         android:layout_height="6dp"
@@ -65,12 +60,6 @@
             android:layout_centerVertical="true"
             android:scaleType="center"
             />
-        <ImageView
-            android:id="@+id/wimax_inout"
-            android:layout_height="wrap_content"
-            android:layout_width="wrap_content"
-            android:layout_gravity="center|bottom"
-            />
     </FrameLayout>
     -->
     <FrameLayout
@@ -97,12 +86,6 @@
                 android:layout_height="wrap_content"
                 android:layout_width="wrap_content"
                 />
-            <ImageView
-                android:id="@+id/mobile_inout"
-                android:layout_height="wrap_content"
-                android:layout_width="wrap_content"
-                android:layout_gravity="end|bottom"
-                />
         </FrameLayout>
     </FrameLayout>
     <ImageView
diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml
index b27536d..4741cec 100644
--- a/packages/SystemUI/res/layout/status_bar.xml
+++ b/packages/SystemUI/res/layout/status_bar.xml
@@ -95,11 +95,13 @@
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     />
-                <ImageView
+                <!-- battery must be padded below by 1px to match assets -->
+                <com.android.systemui.BatteryMeterView
                     android:id="@+id/battery"
-                    android:layout_height="wrap_content"
-                    android:layout_width="wrap_content"
-                    android:paddingStart="4dip"
+                    android:layout_height="16dp"
+                    android:layout_width="10dp"
+                    android:paddingBottom="1px"
+                    android:layout_marginStart="4dip"
                     />
             </LinearLayout>
     
diff --git a/packages/SystemUI/res/layout/status_bar_help.xml b/packages/SystemUI/res/layout/status_bar_help.xml
deleted file mode 100644
index f638767..0000000
--- a/packages/SystemUI/res/layout/status_bar_help.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-<?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.
-*/
--->
-
-<!-- This is the combined status bar / notification panel window. -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:id="@+id/status_bar_cling"
-    android:paddingStart="40dp"
-    android:paddingEnd="40dp"
-    android:background="#DD000000"
-    android:focusable="true"
-    android:orientation="vertical" 
-    android:gravity="top|start"
-    >
-
-    <ImageView
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_marginBottom="50dp"
-        android:gravity="center"
-        android:src="@drawable/arrow_dashed"
-        tools:ignore="ContentDescription" />
-
-    <TextView
-        style="@style/ClingTitleText"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:text="@string/status_bar_help_title" />
-
-    <TextView
-        style="@style/ClingText"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_marginBottom="30dp"
-        android:text="@string/status_bar_help_text" />
-
-    <Button
-        android:id="@+id/ok"
-        style="@style/ClingButton"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:paddingStart="50dp"
-        android:paddingEnd="50dp"
-        android:text="@android:string/ok" />
-
-</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/status_bar_icon.xml b/packages/SystemUI/res/layout/status_bar_icon.xml
deleted file mode 100644
index 063212e..0000000
--- a/packages/SystemUI/res/layout/status_bar_icon.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* apps/common/assets/default/default/skins/StatusBar.xml
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
--->
-
-<!-- The icons are a fixed size so an app can't mess everything up with bogus images -->
-<!-- TODO: the icons are hard coded to 25x25 pixels.  Their size should come from a theme -->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
-    android:layout_width="25dp" 
-    android:layout_height="25dp"
-    >
-
-    <com.android.systemui.statusbar.AnimatedImageView android:id="@+id/image"
-        android:layout_width="match_parent" 
-        android:layout_height="match_parent"
-        />
-
-    <TextView android:id="@+id/number"
-        android:layout_width="wrap_content" 
-        android:layout_height="wrap_content"
-        android:layout_gravity="end|bottom"
-        android:layout_marginEnd="1dp"
-        android:layout_marginBottom="1dp"
-        android:textSize="10sp"
-        android:textColor="#ffffffff"
-        android:background="@drawable/ic_notification_overlay"
-        android:gravity="center"
-        android:textStyle="bold"
-        />
-
-</FrameLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/status_bar_notification_row.xml b/packages/SystemUI/res/layout/status_bar_notification_row.xml
index 7a5ff3c..f827967 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_row.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_row.xml
@@ -1,4 +1,5 @@
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.systemui.statusbar.ExpandableNotificationRow
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     >
@@ -62,4 +63,4 @@
         android:padding="2dp"
         />
 
-</FrameLayout>
+</com.android.systemui.statusbar.ExpandableNotificationRow>
diff --git a/packages/SystemUI/res/layout/system_bar.xml b/packages/SystemUI/res/layout/system_bar.xml
deleted file mode 100644
index 28c9dc0..0000000
--- a/packages/SystemUI/res/layout/system_bar.xml
+++ /dev/null
@@ -1,151 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * 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.
--->
-
-<!-- TabletStatusBarView extends FrameLayout -->
-<com.android.systemui.statusbar.tablet.TabletStatusBarView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
-    android:background="@drawable/system_bar_background"
-    >
-    
-    <FrameLayout
-        android:id="@+id/bar_contents_holder"
-        android:layout_width="match_parent"
-        android:layout_height="@*android:dimen/system_bar_height"
-        android:layout_gravity="bottom"
-        >
-        <RelativeLayout
-            android:id="@+id/bar_contents"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:clipChildren="false"
-            >
-
-            <!-- notification icons & panel access -->
-            <include layout="@layout/system_bar_notification_area" 
-                android:layout_width="wrap_content"
-                android:layout_height="match_parent"
-                android:layout_alignParentEnd="true"
-                android:layout_marginTop="1dp"
-                />
-
-            <!-- navigation controls -->
-            <LinearLayout
-                android:id="@+id/navigationArea"
-                android:layout_width="wrap_content"
-                android:layout_height="match_parent"
-                android:layout_alignParentStart="true"
-                android:orientation="horizontal"
-                android:clipChildren="false"
-                android:clipToPadding="false"
-                >
-                <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
-                    android:layout_width="@dimen/navigation_key_width"
-                    android:layout_height="match_parent"
-                    android:src="@drawable/ic_sysbar_back"
-                    systemui:keyCode="4"
-                    android:contentDescription="@string/accessibility_back"
-                    systemui:glowBackground="@drawable/ic_sysbar_highlight"
-                    />
-                <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
-                    android:layout_width="@dimen/navigation_key_width"
-                    android:layout_height="match_parent"
-                    android:src="@drawable/ic_sysbar_home"
-                    systemui:keyCode="3"
-                    android:contentDescription="@string/accessibility_home"
-                    systemui:glowBackground="@drawable/ic_sysbar_highlight"
-                    />
-                <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps"
-                    android:layout_width="@dimen/navigation_key_width"
-                    android:layout_height="match_parent"
-                    android:src="@drawable/ic_sysbar_recent"
-                    android:contentDescription="@string/accessibility_recent"
-                    systemui:glowBackground="@drawable/ic_sysbar_highlight"
-                    />
-                <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
-                    android:layout_width="@dimen/navigation_menu_key_width"
-                    android:layout_height="match_parent"
-                    android:src="@drawable/ic_sysbar_menu"
-                    systemui:keyCode="82"
-                    android:visibility="invisible"
-                    android:contentDescription="@string/accessibility_menu"
-                    systemui:glowBackground="@drawable/ic_sysbar_highlight"
-                    />
-            </LinearLayout>
-
-            <!-- fake space bar zone -->
-            <com.android.systemui.statusbar.policy.EventHole android:id="@+id/fake_space_bar"
-                android:layout_height="match_parent"
-                android:layout_width="0dp"
-                android:paddingStart="8dip"
-                android:paddingEnd="8dip"
-                android:layout_toEndOf="@+id/navigationArea"
-                android:layout_toStartOf="@+id/notificationArea"
-                android:visibility="gone"
-                />
-        </RelativeLayout>
-    </FrameLayout>
-
-    <FrameLayout
-        android:id="@+id/bar_shadow_holder"
-        android:layout_width="match_parent"
-        android:layout_height="@*android:dimen/system_bar_height"
-        android:layout_gravity="bottom"
-        >
-        <!-- lights out shade -->
-        <RelativeLayout
-            android:id="@+id/bar_shadow"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:background="#FF000000"
-            android:visibility="gone"
-            >
-            <ImageView
-                android:id="@+id/dot0"
-                android:layout_width="80dip"
-                android:layout_height="48dip"
-                android:src="@drawable/ic_sysbar_lights_out_dot_small"
-                android:layout_alignParentStart="true"
-                android:layout_alignParentBottom="true"
-                />
-            <ImageView
-                android:id="@+id/dot1"
-                android:layout_width="80dip"
-                android:layout_height="48dip"
-                android:src="@drawable/ic_sysbar_lights_out_dot_large"
-                android:layout_toEndOf="@+id/dot0"
-                android:layout_alignParentBottom="true"
-                />
-            <ImageView
-                android:id="@+id/dot2"
-                android:layout_width="80dip"
-                android:layout_height="48dip"
-                android:src="@drawable/ic_sysbar_lights_out_dot_small"
-                android:layout_toEndOf="@+id/dot1"
-                android:layout_alignParentBottom="true"
-                />
-            <ImageView
-                android:id="@+id/dot3"
-                android:layout_width="80dip"
-                android:layout_height="48dip"
-                android:src="@drawable/ic_sysbar_lights_out_dot_small"
-                android:layout_alignParentEnd="true"
-                android:layout_alignParentBottom="true"
-                />
-        </RelativeLayout>
-    </FrameLayout>
-</com.android.systemui.statusbar.tablet.TabletStatusBarView>
diff --git a/packages/SystemUI/res/layout/system_bar_compat_mode_panel.xml b/packages/SystemUI/res/layout/system_bar_compat_mode_panel.xml
deleted file mode 100644
index 9ad9e05..0000000
--- a/packages/SystemUI/res/layout/system_bar_compat_mode_panel.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 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.
-*/
--->
-
-<com.android.systemui.statusbar.tablet.CompatModePanel
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_height="wrap_content"
-    android:layout_width="match_parent"
-    android:paddingBottom="@dimen/panel_float"
-    android:paddingEnd="20dp"
-    >
-    <RadioGroup android:id="@+id/compat_mode_radio_group"
-        android:background="@*android:drawable/dialog_full_holo_dark"
-        android:layout_height="wrap_content"
-        android:layout_width="match_parent"
-        android:orientation="vertical"
-        android:padding="10dp"
-        >
-        <RadioButton android:id="@+id/compat_mode_off_radio"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="@string/compat_mode_off" />
-        <RadioButton android:id="@+id/compat_mode_on_radio"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="@string/compat_mode_on" />
-    </RadioGroup>
-</com.android.systemui.statusbar.tablet.CompatModePanel>
diff --git a/packages/SystemUI/res/layout/system_bar_input_methods_item.xml b/packages/SystemUI/res/layout/system_bar_input_methods_item.xml
deleted file mode 100644
index 1a95ec1..0000000
--- a/packages/SystemUI/res/layout/system_bar_input_methods_item.xml
+++ /dev/null
@@ -1,105 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-
-<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:background="@drawable/status_bar_item_background"
-    android:orientation="vertical"
-    android:paddingEnd="6dip"
-    android:paddingStart="6dip"
-    android:paddingTop="5dip"
-    android:paddingBottom="5dip"
-    android:gravity="center_vertical">
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_weight="1"
-        android:gravity="center_vertical"
-        android:orientation="horizontal">
-        <LinearLayout
-            android:id="@+id/item_subtype"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            android:gravity="center_vertical"
-            android:orientation="horizontal"
-            android:background="?android:attr/selectableItemBackground">
-            <RadioButton
-                android:id="@+id/item_radio"
-                android:layout_width="30dip"
-                android:layout_height="wrap_content"
-                android:focusable="false"
-                android:clickable="false" />
-            <ImageView
-                android:id="@+id/item_icon"
-                android:layout_width="@android:dimen/app_icon_size"
-                android:layout_height="wrap_content"
-                android:scaleType="fitCenter"
-                android:contentDescription="@null" />
-            <LinearLayout
-                android:orientation="vertical"
-                android:layout_width="0px"
-                android:layout_weight="1"
-                android:layout_height="wrap_content">
-                <TextView
-                    android:id="@+id/item_title"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:textAppearance="?android:attr/textAppearanceMedium"
-                    android:singleLine="true"
-                    android:ellipsize="marquee"
-                    android:layout_marginBottom="2dip" />
-                <TextView
-                    android:id="@+id/item_subtitle"
-                    android:layout_marginTop="-4dip"
-                    android:layout_gravity="center_vertical|start"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:textAppearance="?android:attr/textAppearanceSmall" />
-            </LinearLayout>
-        </LinearLayout>
-        <View
-            android:id="@+id/item_vertical_separator"
-            android:layout_width="2dip"
-            android:layout_height="match_parent"
-            android:layout_marginBottom="5dip"
-            android:background="@android:drawable/divider_horizontal_dark" />
-        <ImageView
-            android:id="@+id/item_settings_icon"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_marginStart="5dip"
-            android:layout_gravity="center_vertical"
-            android:paddingEnd="10dip"
-            android:paddingStart="10dip"
-            android:src="@drawable/ic_sysbar_quicksettings"
-            android:visibility="visible"
-            android:clickable="true"
-            android:focusable="true"
-            android:background="?android:attr/selectableItemBackground"
-            android:contentDescription="@string/accessibility_settings_button" />
-    </LinearLayout>
-    <View
-        android:layout_width="match_parent"
-        android:layout_height="1dip"
-        android:background="@android:drawable/divider_horizontal_dark" />
-</LinearLayout>
diff --git a/packages/SystemUI/res/layout/system_bar_input_methods_panel.xml b/packages/SystemUI/res/layout/system_bar_input_methods_panel.xml
deleted file mode 100644
index 547f937..0000000
--- a/packages/SystemUI/res/layout/system_bar_input_methods_panel.xml
+++ /dev/null
@@ -1,117 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 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.
-*/
--->
-
-<com.android.systemui.statusbar.tablet.InputMethodsPanel
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_height="match_parent"
-    android:layout_width="match_parent"
-    android:paddingBottom="7dip"
-    android:orientation="vertical"
-    android:visibility="gone">
-    <View
-        android:layout_width="match_parent"
-        android:layout_height="0dip"
-        android:layout_weight="1" />
-    <FrameLayout
-        android:id="@+id/glow"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:background="@drawable/recents_blue_glow">
-        <LinearLayout
-            android:layout_width="450dip"
-            android:layout_height="wrap_content"
-            android:layout_marginStart="20dip"
-            android:orientation="vertical"
-            android:background="@drawable/notify_panel_clock_bg">
-            <!-- Hard keyboard switch -->
-            <LinearLayout
-                android:id="@+id/hard_keyboard_section"
-                android:layout_height="wrap_content"
-                android:layout_width="match_parent"
-                android:orientation="vertical">
-                <LinearLayout
-                    android:layout_height="wrap_content"
-                    android:layout_width="match_parent"
-                    android:orientation="horizontal">
-                    <TextView
-                        android:id="@+id/use_physical_keyboard_label"
-                        android:layout_width="0dip"
-                        android:layout_height="wrap_content"
-                        android:layout_weight="1"
-                        android:minHeight="?android:attr/listPreferredItemHeight"
-                        android:background="?android:attr/selectableItemBackground"
-                        android:orientation="vertical"
-                        android:paddingEnd="6dip"
-                        android:paddingStart="30dip"
-                        android:paddingTop="5dip"
-                        android:paddingBottom="5dip"
-                        android:gravity="center_vertical"
-                        android:singleLine="true"
-                        android:text="@string/status_bar_use_physical_keyboard"
-                        android:textAppearance="?android:attr/textAppearanceMedium"
-                        android:ellipsize="marquee" />
-                    <Switch
-                        android:id="@+id/hard_keyboard_switch"
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:layout_gravity="center_vertical"
-                        android:layout_marginEnd="16dip" />
-                </LinearLayout>
-                <View
-                    android:layout_width="match_parent"
-                    android:layout_height="1dip"
-                    android:background="@android:drawable/divider_horizontal_dark" />
-            </LinearLayout>
-
-            <!-- Input method list -->
-            <ScrollView
-                android:layout_width="wrap_content"
-                android:layout_height="0dip"
-                android:overScrollMode="ifContentScrolls"
-                android:layout_marginTop="3dip"
-                android:layout_weight="1"
-                android:scrollbarAlwaysDrawVerticalTrack="true"
-                android:scrollbarDefaultDelayBeforeFade="75000">
-                <LinearLayout
-                    android:id="@+id/input_method_menu_list"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:orientation="vertical" />
-            </ScrollView>
-
-            <!-- Configure input methods -->
-            <TextView
-                android:id="@+id/ime_settings_shortcut"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:minHeight="?android:attr/listPreferredItemHeight"
-                android:background="?android:attr/selectableItemBackground"
-                android:orientation="vertical"
-                android:paddingEnd="6dip"
-                android:paddingStart="30dip"
-                android:paddingTop="5dip"
-                android:paddingBottom="5dip"
-                android:gravity="center_vertical"
-                android:singleLine="true"
-                android:text="@string/status_bar_input_method_settings_configure_input_methods"
-                android:textAppearance="?android:attr/textAppearanceMedium"
-                android:ellipsize="marquee" />
-        </LinearLayout>
-    </FrameLayout>
-</com.android.systemui.statusbar.tablet.InputMethodsPanel>
diff --git a/packages/SystemUI/res/layout/system_bar_no_recent_apps.xml b/packages/SystemUI/res/layout/system_bar_no_recent_apps.xml
deleted file mode 100644
index c023ef7..0000000
--- a/packages/SystemUI/res/layout/system_bar_no_recent_apps.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* apps/common/assets/default/default/skins/StatusBar.xml
-**
-** Copyright 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.
-*/
--->
-
-<FrameLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_height="match_parent"
-    android:layout_width="match_parent"
-    >
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:textSize="20dp"
-        android:textColor="@android:color/holo_blue_light"
-        android:text="@string/status_bar_no_recent_apps"
-        android:gravity="start"
-        android:layout_gravity="bottom|start"
-    />
-</FrameLayout>
diff --git a/packages/SystemUI/res/layout/system_bar_notification_area.xml b/packages/SystemUI/res/layout/system_bar_notification_area.xml
deleted file mode 100644
index 2fd91ef..0000000
--- a/packages/SystemUI/res/layout/system_bar_notification_area.xml
+++ /dev/null
@@ -1,133 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * 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.
--->
-
-<!-- notification icons & panel access -->
-<com.android.systemui.statusbar.tablet.NotificationArea
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
-    android:id="@+id/notificationArea"
-    android:layout_width="wrap_content"
-    android:layout_height="match_parent"
-    android:layout_alignParentEnd="true"
-    android:orientation="horizontal"
-    android:background="?android:attr/listChoiceBackgroundIndicator"
-    android:clickable="true"
-    >
-
-    <LinearLayout
-        android:id="@+id/feedbackIconArea"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:orientation="horizontal"
-        >
-
-        <com.android.systemui.statusbar.tablet.InputMethodButton
-            android:id="@+id/imeSwitchButton"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_marginStart="8dip"
-            android:src="@drawable/ic_sysbar_ime_default"
-            android:visibility="gone"
-            android:contentDescription="@string/accessibility_ime_switch_button"
-            />
-
-        <com.android.systemui.statusbar.policy.CompatModeButton
-            android:id="@+id/compatModeButton"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_marginStart="8dip"
-            android:src="@drawable/ic_sysbar_zoom"
-            android:visibility="gone"
-            android:contentDescription="@string/accessibility_compatibility_zoom_button"
-            />
-
-        <com.android.systemui.statusbar.tablet.NotificationIconArea
-            android:id="@+id/notificationIcons"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            >
-            <view
-                class="com.android.systemui.statusbar.tablet.NotificationIconArea$IconLayout"
-                android:id="@+id/icons"
-                android:layout_width="wrap_content"
-                android:layout_height="match_parent"
-                android:layout_gravity="center_vertical"
-                android:layout_marginStart="8dp"
-                android:alpha="0.4"
-                />
-        </com.android.systemui.statusbar.tablet.NotificationIconArea>
-    </LinearLayout>
-
-    <LinearLayout
-        android:id="@+id/notificationTrigger"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:gravity="center"
-        >
-        <com.android.systemui.statusbar.policy.Clock
-            android:id="@+id/clock"
-            android:textAppearance="@style/TextAppearance.StatusBar.Clock"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:singleLine="true"
-            android:paddingStart="6dip"
-            android:layout_marginEnd="8dip"
-            android:gravity="center_vertical|start"
-            />
-
-        <TextView
-            android:id="@+id/network_text"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_marginEnd="6dip"
-            android:layout_marginStart="6dip"
-            android:gravity="center"
-            android:singleLine="true"
-            android:visibility="gone"
-            android:textSize="16sp"
-            android:textColor="#606060"
-            />
-
-        <LinearLayout
-            android:id="@+id/signal_battery_cluster"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_marginEnd="16dp"
-            android:orientation="horizontal"
-            android:gravity="center"
-            >
-            <include layout="@layout/signal_cluster_view" 
-                android:id="@+id/signal_cluster"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                />
-            <ImageView
-                android:id="@+id/bluetooth"
-                android:layout_height="wrap_content"
-                android:layout_width="wrap_content"
-                android:paddingStart="4dip"
-                android:visibility="gone"
-                />
-            <ImageView
-                android:id="@+id/battery"
-                android:layout_height="wrap_content"
-                android:layout_width="wrap_content"
-                android:paddingStart="4dip"
-                />
-        </LinearLayout>
-    </LinearLayout>
-</com.android.systemui.statusbar.tablet.NotificationArea>
diff --git a/packages/SystemUI/res/layout/system_bar_notification_panel.xml b/packages/SystemUI/res/layout/system_bar_notification_panel.xml
deleted file mode 100644
index 58a6de3..0000000
--- a/packages/SystemUI/res/layout/system_bar_notification_panel.xml
+++ /dev/null
@@ -1,75 +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.
--->
-
-<!--    android:background="@drawable/system_bar_closed_default_background" -->
-<com.android.systemui.statusbar.tablet.NotificationPanel
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
-    android:id="@+id/content_parent"
-    android:layout_height="match_parent"
-    android:layout_width="match_parent"
-    android:gravity="end"
-    >
-
-    <!-- lift the panel up off the status bar while leaving a touchable are -->
-    <Space
-        android:id="@+id/system_bar_notification_panel_bottom_space"
-        android:layout_height="56dp"
-        android:layout_width="478dp"
-        android:layout_alignParentEnd="true"
-        android:layout_alignParentBottom="true"
-        />
-
-    <LinearLayout
-        android:id="@+id/content_frame"
-        android:background="@drawable/notification_panel_bg"
-        android:layout_height="wrap_content"
-        android:layout_width="478dp"
-        android:orientation="vertical"
-        android:layout_alignParentEnd="true"
-        android:layout_above="@id/system_bar_notification_panel_bottom_space"
-        android:paddingBottom="8dp"
-        >
-
-        <include layout="@layout/system_bar_notification_panel_title"
-            android:layout_width="match_parent"
-            android:layout_height="130dp"
-            android:layout_above="@id/content_frame"
-            android:layout_alignParentEnd="true"
-            android:layout_weight="0"
-            />
-
-        <ScrollView
-
-            android:id="@+id/notification_scroller"
-            android:layout_height="wrap_content"
-            android:layout_width="match_parent"
-            android:overScrollMode="ifContentScrolls"
-            android:layout_weight="1"
-            >
-            <com.android.systemui.statusbar.policy.NotificationRowLayout
-                android:id="@+id/content"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:gravity="center_horizontal|bottom"
-                android:clickable="true"
-                android:focusable="true"
-                android:descendantFocusability="afterDescendants"
-                systemui:rowHeight="@dimen/notification_row_min_height"
-                />
-        </ScrollView>
-    </LinearLayout>
-</com.android.systemui.statusbar.tablet.NotificationPanel>
diff --git a/packages/SystemUI/res/layout/system_bar_notification_panel_title.xml b/packages/SystemUI/res/layout/system_bar_notification_panel_title.xml
deleted file mode 100644
index d08fbce..0000000
--- a/packages/SystemUI/res/layout/system_bar_notification_panel_title.xml
+++ /dev/null
@@ -1,231 +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.
--->
-
-<com.android.systemui.statusbar.tablet.NotificationPanelTitle
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
-    android:id="@+id/title_area"
-    android:background="@drawable/system_bar_notification_header_bg"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:clickable="true"
-    android:orientation="vertical"
-    android:paddingStart="26dp"
-    android:paddingTop="14dp"
-    android:paddingEnd="26dp"
-    >
-
-    <TableLayout
-        android:id="@+id/icons"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_alignParentStart="true"
-        android:layout_alignParentBottom="true"
-        android:layout_marginTop="16dp"
-        android:layout_marginBottom="16dp"
-        android:shrinkColumns="2,4"
-        android:stretchColumns="7"
-        >
-        <TableRow>
-
-            <!-- to keep the column ids stable we wrap disappearing views in
-                 frames -->
-            <FrameLayout
-                android:layout_height="wrap_content"
-                android:layout_width="wrap_content"
-                android:layout_gravity="center_vertical"
-                >
-                <ImageView
-                    android:id="@+id/bluetooth"
-                    android:layout_height="wrap_content"
-                    android:layout_width="wrap_content"
-                    android:paddingEnd="16dp"
-                    android:visibility="gone"
-                    android:contentDescription="@null"
-                    android:layout_gravity="center_vertical"
-                    />
-            </FrameLayout>
-
-            <!-- mobile data -->
-            <FrameLayout
-                android:id="@+id/mobile_icon"
-                android:layout_height="wrap_content"
-                android:layout_width="wrap_content"
-                android:layout_gravity="center_vertical"
-                android:paddingEnd="6dp"
-                >
-
-                <ImageView
-                    android:id="@+id/mobile_signal"
-                    android:layout_height="wrap_content"
-                    android:layout_width="wrap_content"
-                    android:contentDescription="@null"
-                    />
-
-                <ImageView
-                    android:id="@+id/mobile_type"
-                    android:layout_height="wrap_content"
-                    android:layout_width="wrap_content"
-                    android:contentDescription="@null"
-                    />
-
-            </FrameLayout>
-            <TextView
-                android:id="@+id/mobile_text"
-                style="@style/SystemBarNotificationText"
-                android:layout_gravity="start|center_vertical"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:paddingEnd="12dp"
-                android:singleLine="true"
-                android:ellipsize="end"
-                android:text="@string/status_bar_settings_settings_button"
-                />
-
-            <!-- wifi -->
-            <FrameLayout
-                android:id="@+id/wifi_icon"
-                android:layout_height="wrap_content"
-                android:layout_width="wrap_content"
-                android:layout_gravity="center_vertical"
-                android:paddingEnd="6dp"
-                >
-
-                <ImageView
-                    android:id="@+id/wifi_signal"
-                    android:layout_height="wrap_content"
-                    android:layout_width="wrap_content"
-                    android:contentDescription="@null"
-                    />
-
-                <ImageView
-                    android:id="@+id/wifi_direction"
-                    android:layout_height="wrap_content"
-                    android:layout_width="wrap_content"
-                    android:contentDescription="@null"
-                    />
-
-            </FrameLayout>
-            <TextView
-                android:id="@+id/wifi_text"
-                style="@style/SystemBarNotificationText"
-                android:layout_gravity="start|center_vertical"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:paddingEnd="12dp"
-                android:singleLine="true"
-                android:ellipsize="end"
-                android:text="@string/status_bar_settings_settings_button"
-                />
-
-            <ImageView
-                android:id="@+id/battery"
-                android:layout_height="wrap_content"
-                android:layout_width="wrap_content"
-                android:scaleType="centerInside"
-                android:layout_gravity="center_vertical"
-                android:layout_alignBaseline="@id/wifi_signal"
-                android:paddingEnd="6dp"
-                android:contentDescription="@null"
-                />
-
-            <TextView
-                android:id="@+id/battery_text"
-                style="@style/SystemBarNotificationText"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="start|center_vertical"
-                android:paddingEnd="2dp"
-                android:singleLine="true"
-                android:text="@string/status_bar_settings_settings_button"
-                />
-
-            <!-- this will stretch to eat up available space -->
-            <View
-                android:layout_width="0dp"
-                android:layout_height="0dp"
-                />
-
-            <FrameLayout
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center_vertical"
-                >
-
-                <ImageView
-                    android:id="@+id/settings_button"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:src="@drawable/ic_sysbar_quicksettings"
-                    android:contentDescription="@string/accessibility_desc_quick_settings"
-                    />
-
-                <ImageView
-                    android:id="@+id/notification_button"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:src="@drawable/ic_notification_open"
-                    android:visibility="invisible"
-                    android:contentDescription="@string/accessibility_notifications_button"
-                    />
-            </FrameLayout>
-
-        </TableRow>
-    </TableLayout>
-
-    <LinearLayout
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:paddingTop="@dimen/notification_panel_header_padding_top"
-        android:orientation="horizontal"
-        android:gravity="center_vertical"
-        android:baselineAligned="false"
-        >
-
-        <com.android.systemui.statusbar.policy.Clock
-            android:id="@+id/clock"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:singleLine="true"
-            android:textAppearance="@style/TextAppearance.SystemBar.Expanded.Clock"
-            />
-    
-        <com.android.systemui.statusbar.policy.DateView
-            android:id="@+id/date"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginStart="8dp"
-            android:layout_marginEnd="8dp"
-            android:textAppearance="@style/TextAppearance.SystemBar.Expanded.Date"
-            />
-
-        <Space
-            android:layout_width="0dp"
-            android:layout_height="48dp"
-            android:layout_weight="1"
-            />
-
-        <ImageView android:id="@+id/clear_all_button"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:scaleType="center"
-            android:src="@drawable/ic_notify_clear"
-            android:contentDescription="@string/accessibility_clear_all"
-            />
-    </LinearLayout>
-</com.android.systemui.statusbar.tablet.NotificationPanelTitle>
diff --git a/packages/SystemUI/res/layout/system_bar_notification_peek.xml b/packages/SystemUI/res/layout/system_bar_notification_peek.xml
deleted file mode 100644
index 3cff47b..0000000
--- a/packages/SystemUI/res/layout/system_bar_notification_peek.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* apps/common/assets/default/default/skins/StatusBar.xml
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
--->
-
-<!--    android:background="@drawable/system_bar_closed_default_background" -->
-<com.android.systemui.statusbar.tablet.NotificationPeekPanel
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_height="wrap_content"
-    android:layout_width="match_parent"
-    android:background="@*android:drawable/dialog_full_holo_dark"
-    android:orientation="vertical"
-    >
-
-    <FrameLayout 
-        android:id="@+id/content"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:gravity="center_horizontal|bottom"
-        android:animationCache="false"
-        android:orientation="vertical"
-        android:background="@drawable/system_bar_background"
-        android:clickable="true"
-        android:focusable="true"
-        android:descendantFocusability="afterDescendants"
-        >
-    </FrameLayout>
-</com.android.systemui.statusbar.tablet.NotificationPeekPanel>
diff --git a/packages/SystemUI/res/layout/system_bar_pocket_panel.xml b/packages/SystemUI/res/layout/system_bar_pocket_panel.xml
deleted file mode 100644
index e4a6da4..0000000
--- a/packages/SystemUI/res/layout/system_bar_pocket_panel.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* apps/common/assets/default/default/skins/StatusBar.xml
-**
-** Copyright 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.
-*/
--->
-
-<RelativeLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_height="match_parent"
-    android:layout_width="match_parent"
-    android:background="@*android:drawable/dialog_full_holo_dark"
-    >
-    <TextView
-        android:id="@+id/description"
-        android:textAppearance="@android:style/TextAppearance.Small"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:gravity="center"
-        android:textStyle="bold"
-        android:maxLines="1"
-        android:layout_alignParentBottom="true"
-        />
-
-    <FrameLayout
-        android:id="@+id/preview"
-        android:layout_height="match_parent"
-        android:layout_width="match_parent"
-        android:layout_above="@+id/description"
-        android:descendantFocusability="blocksDescendants"
-        >
-        <ImageView
-            android:id="@+id/icon"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:scaleType="centerInside"
-            android:visibility="gone"
-            />
-        <TextView
-            android:id="@+id/alt"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:textAppearance="@android:style/TextAppearance.Large"
-            android:gravity="center"
-            android:visibility="gone"
-            />
-    </FrameLayout>
-</RelativeLayout>
diff --git a/packages/SystemUI/res/layout/system_bar_recent_item.xml b/packages/SystemUI/res/layout/system_bar_recent_item.xml
deleted file mode 100644
index 34f60b2..0000000
--- a/packages/SystemUI/res/layout/system_bar_recent_item.xml
+++ /dev/null
@@ -1,100 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* apps/common/assets/default/default/skins/StatusBar.xml
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT 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 android:id="@+id/recent_item"
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_height="wrap_content"
-    android:layout_width="wrap_content">
-
-    <TextView android:id="@+id/app_label"
-        android:layout_width="@dimen/status_bar_recents_app_label_width"
-        android:layout_height="wrap_content"
-        android:textSize="@dimen/status_bar_recents_app_label_text_size"
-        android:fadingEdge="horizontal"
-        android:fadingEdgeLength="@dimen/status_bar_recents_text_fading_edge_length"
-        android:scrollHorizontally="true"
-        android:layout_alignParentStart="true"
-        android:layout_alignParentTop="true"
-        android:layout_marginStart="@dimen/status_bar_recents_app_label_left_margin"
-        android:layout_marginTop="32dip"
-        android:singleLine="true"
-        android:ellipsize="marquee"
-        android:textColor="@color/status_bar_recents_app_label_color"
-        android:importantForAccessibility="no"
-    />
-
-    <FrameLayout android:id="@+id/app_thumbnail"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_toEndOf="@id/app_label"
-        android:layout_marginStart="@dimen/status_bar_recents_thumbnail_left_margin"
-        android:scaleType="center"
-        android:background="@drawable/recents_thumbnail_bg"
-        android:foreground="@drawable/recents_thumbnail_fg"
-        android:visibility="invisible">
-        <ImageView android:id="@+id/app_thumbnail_image"
-            android:layout_width="@dimen/status_bar_recents_thumbnail_width"
-            android:layout_height="@dimen/status_bar_recents_thumbnail_height"
-        />
-    </FrameLayout>
-
-
-    <ImageView android:id="@+id/app_icon"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_toEndOf="@id/app_label"
-        android:layout_marginStart="@dimen/status_bar_recents_app_icon_left_margin"
-        android:layout_marginTop="@dimen/status_bar_recents_app_icon_top_margin"
-        android:maxWidth="@dimen/status_bar_recents_app_icon_max_width"
-        android:maxHeight="@dimen/status_bar_recents_app_icon_max_height"
-        android:scaleType="centerInside"
-        android:adjustViewBounds="true"
-        android:visibility="invisible"
-    />
-
-
-    <View android:id="@+id/recents_callout_line"
-        android:layout_width="@dimen/status_bar_recents_app_label_width"
-        android:layout_height="1dip"
-        android:layout_below="@id/app_label"
-        android:layout_marginTop="3dip"
-        android:layout_alignParentStart="true"
-        android:layout_marginStart="@dimen/status_bar_recents_app_label_left_margin"
-        android:layout_toStartOf="@id/app_thumbnail"
-        android:layout_marginEnd="3dip"
-        android:background="@drawable/recents_callout_line"
-    />
-
-    <TextView android:id="@+id/app_description"
-        android:layout_width="@dimen/status_bar_recents_app_label_width"
-        android:layout_height="wrap_content"
-        android:textSize="@dimen/status_bar_recents_app_description_text_size"
-        android:fadingEdge="horizontal"
-        android:fadingEdgeLength="@dimen/status_bar_recents_text_fading_edge_length"
-        android:scrollHorizontally="true"
-        android:layout_alignParentStart="true"
-        android:layout_below="@id/recents_callout_line"
-        android:layout_marginStart="@dimen/status_bar_recents_app_label_left_margin"
-        android:layout_marginTop="3dip"
-        android:singleLine="true"
-        android:ellipsize="marquee"
-    />
-
-</RelativeLayout>
diff --git a/packages/SystemUI/res/layout/system_bar_recent_panel.xml b/packages/SystemUI/res/layout/system_bar_recent_panel.xml
deleted file mode 100644
index 3d15d9b..0000000
--- a/packages/SystemUI/res/layout/system_bar_recent_panel.xml
+++ /dev/null
@@ -1,84 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* apps/common/assets/default/default/skins/StatusBar.xml
-**
-** Copyright 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.
-*/
--->
-
-<com.android.systemui.recent.RecentsPanelView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
-    android:id="@+id/recents_root"
-    android:layout_height="match_parent"
-    android:layout_width="wrap_content"
-    android:clipToPadding="false"
-    android:clipChildren="false"
-    systemui:recentItemLayout="@layout/system_bar_recent_item"
-    >
-    <FrameLayout
-        android:id="@+id/recents_bg_protect"
-        android:background="@drawable/recents_bg_protect_tile"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:layout_alignParentBottom="true"
-        android:layout_marginBottom="@*android:dimen/system_bar_height"
-        android:clipToPadding="false"
-        android:clipChildren="false">
-
-        <com.android.systemui.recent.RecentsVerticalScrollView android:id="@+id/recents_container"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginEnd="@dimen/status_bar_recents_right_glow_margin"
-            android:divider="@null"
-            android:stackFromBottom="true"
-            android:fadingEdge="vertical"
-            android:scrollbars="none"
-            android:fadingEdgeLength="20dip"
-            android:layout_gravity="bottom|start"
-            android:clipToPadding="false"
-            android:clipChildren="false"
-            android:fitsSystemWindows="true">
-
-            <LinearLayout android:id="@+id/recents_linear_layout"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:orientation="vertical"
-                android:clipToPadding="false"
-                android:clipChildren="false">
-            </LinearLayout>
-
-        </com.android.systemui.recent.RecentsVerticalScrollView>
-
-        <include layout="@layout/system_bar_no_recent_apps"
-            android:id="@+id/recents_no_apps"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layout_marginStart="58dip"
-            android:layout_marginBottom="36dip"
-            android:visibility="invisible" />
-
-    </FrameLayout>
-
-    <com.android.systemui.recent.StatusBarTouchProxy
-        android:id="@+id/status_bar_touch_proxy"
-        android:layout_width="match_parent"
-        android:layout_height="@*android:dimen/system_bar_height"
-        android:layout_alignParentBottom="true"
-        android:layout_alignParentStart="true"
-    />
-
-
-</com.android.systemui.recent.RecentsPanelView>
diff --git a/packages/SystemUI/res/layout/system_bar_recent_panel_footer.xml b/packages/SystemUI/res/layout/system_bar_recent_panel_footer.xml
deleted file mode 100644
index 4d14d1f..0000000
--- a/packages/SystemUI/res/layout/system_bar_recent_panel_footer.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* apps/common/assets/default/default/skins/StatusBar.xml
-**
-** Copyright 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.
-*/
--->
-
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/listview_footer_padding"
-    android:layout_height="24dip"
-    android:layout_width="match_parent">
-</FrameLayout>
diff --git a/packages/SystemUI/res/layout/system_bar_settings_view.xml b/packages/SystemUI/res/layout/system_bar_settings_view.xml
deleted file mode 100644
index 4987dd9..0000000
--- a/packages/SystemUI/res/layout/system_bar_settings_view.xml
+++ /dev/null
@@ -1,157 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * 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.
--->
-
-<com.android.systemui.statusbar.tablet.SettingsView
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="vertical"
-        >
-
-    <!-- Airplane mode -->
-    <LinearLayout
-            android:id="@+id/airplane"
-            style="@style/SystemBarPanelSettingsRow"
-            >
-        <ImageView
-                android:id="@+id/airplane_icon"
-                style="@style/SystemBarPanelSettingsIcon"
-                android:src="@drawable/ic_sysbar_airplane_on"
-                />
-        <TextView
-                android:id="@+id/airplane_label"
-                style="@style/SystemBarPanelSettingsContents"
-                android:text="@string/status_bar_settings_airplane"
-                />
-        <Switch
-                android:id="@+id/airplane_checkbox"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center_vertical"
-                android:layout_marginEnd="5dp"
-                />
-    </LinearLayout>
-    <View style="@style/SystemBarPanelSettingsPanelSeparator" />
-
-    <!-- Network -->
-    <LinearLayout
-            android:id="@+id/network"
-            style="@style/SystemBarPanelSettingsRow"
-            >
-        <ImageView
-                android:id="@+id/network_icon"
-                style="@style/SystemBarPanelSettingsIcon"
-                android:src="@drawable/ic_sysbar_wifi_on"
-                />
-        <TextView
-                android:id="@+id/network_label"
-                style="@style/SystemBarPanelSettingsContents"
-                android:text="@string/status_bar_settings_wifi_button"
-                />
-    </LinearLayout>
-    <View style="@style/SystemBarPanelSettingsPanelSeparator" />
-
-    <!-- Rotation lock -->
-    <LinearLayout
-            android:id="@+id/rotate"
-            style="@style/SystemBarPanelSettingsRow"
-            >
-        <ImageView
-                android:id="@+id/rotate_icon"
-                style="@style/SystemBarPanelSettingsIcon"
-                android:src="@drawable/ic_sysbar_rotate_on"
-                />
-        <TextView
-                android:id="@+id/rotate_label"
-                style="@style/SystemBarPanelSettingsContents"
-                android:text="@string/status_bar_settings_auto_rotation"
-                />
-        <Switch
-                android:id="@+id/rotate_checkbox"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center_vertical"
-                android:layout_marginEnd="5dp"
-                />
-    </LinearLayout>
-    <View
-            android:id="@+id/rotate_separator"
-            style="@style/SystemBarPanelSettingsPanelSeparator" />
-
-    <!-- Brightness -->
-    <LinearLayout style="@style/SystemBarPanelSettingsRow" >
-        <ImageView
-                android:id="@+id/brightness_icon"
-                style="@style/SystemBarPanelSettingsIcon"
-                android:src="@drawable/ic_sysbar_brightness"
-                />
-        <com.android.systemui.settings.ToggleSlider
-                android:id="@+id/brightness"
-                android:layout_width="0dp"
-                android:layout_height="fill_parent"
-                android:layout_weight="1"
-                android:layout_marginEnd="2dp"
-                systemui:text="@string/status_bar_settings_auto_brightness_label"
-                />
-    </LinearLayout>
-    <View style="@style/SystemBarPanelSettingsPanelSeparator" />
-
-    <!-- Notifications / Do not disturb -->
-    <LinearLayout
-            android:id="@+id/do_not_disturb"
-            style="@style/SystemBarPanelSettingsRow"
-            >
-        <ImageView
-                android:id="@+id/do_not_disturb_icon"
-                style="@style/SystemBarPanelSettingsIcon"
-                android:src="@drawable/ic_notification_open"
-                />
-        <TextView
-                style="@style/SystemBarPanelSettingsContents"
-                android:text="@string/status_bar_settings_notifications"
-                />
-        <Switch
-                android:id="@+id/do_not_disturb_checkbox"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center_vertical"
-                android:layout_marginEnd="5dp"
-                />
-    </LinearLayout>
-    <View style="@style/SystemBarPanelSettingsPanelSeparator" />
-
-    <!-- Link to settings -->
-    <LinearLayout
-            android:id="@+id/settings"
-            style="@style/SystemBarPanelSettingsRow"
-            >
-
-        <ImageView
-                android:id="@+id/settings"
-                style="@style/SystemBarPanelSettingsIcon"
-                android:src="@drawable/ic_sysbar_quicksettings"
-                />
-        <TextView
-                style="@style/SystemBarPanelSettingsContents"
-                android:text="@string/status_bar_settings_settings_button"
-                />
-    </LinearLayout>
-    <View style="@style/SystemBarPanelSettingsPanelSeparator" />
-
-</com.android.systemui.statusbar.tablet.SettingsView>
-
diff --git a/packages/SystemUI/res/layout/system_bar_ticker_compat.xml b/packages/SystemUI/res/layout/system_bar_ticker_compat.xml
deleted file mode 100644
index 14cdc40..0000000
--- a/packages/SystemUI/res/layout/system_bar_ticker_compat.xml
+++ /dev/null
@@ -1,67 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * 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.
--->
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="horizontal"
-    android:gravity="bottom"
-    >
-
-    <ImageView
-        android:id="@+id/large_icon"
-        android:layout_width="@android:dimen/notification_large_icon_width"
-        android:layout_height="@android:dimen/notification_large_icon_height"
-        android:scaleType="center"
-        android:visibility="gone"
-        />
-
-    <LinearLayout
-        android:layout_width="wrap_content"
-        android:layout_height="@*android:dimen/system_bar_height"
-        android:layout_weight="1"
-        android:background="@drawable/system_bar_ticker_background"
-        >
-        
-        <ImageView android:id="@+id/left_icon"
-            android:layout_width="64dp"
-            android:layout_height="match_parent"
-            android:scaleType="center"
-            android:visibility="gone"
-            />
-
-        <TextView android:id="@+id/text"
-            android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layout_gravity="center_vertical"
-            android:layout_marginStart="12dp"
-            android:gravity="center_vertical"
-            android:maxLines="2"
-            />
-
-        <ImageView android:id="@+id/right_icon"
-            android:layout_width="64dp"
-            android:layout_height="match_parent"
-            android:scaleType="center"
-            android:visibility="gone"
-            />
-
-    </LinearLayout>
-
-</LinearLayout>
diff --git a/packages/SystemUI/res/layout/system_bar_ticker_panel.xml b/packages/SystemUI/res/layout/system_bar_ticker_panel.xml
deleted file mode 100644
index 49d0405..0000000
--- a/packages/SystemUI/res/layout/system_bar_ticker_panel.xml
+++ /dev/null
@@ -1,52 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * 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.
--->
-
-<RelativeLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    >
-
-    <View
-        android:layout_height="@*android:dimen/system_bar_height"
-        android:layout_width="match_parent"
-        android:background="@drawable/system_bar_ticker_background"
-        android:layout_alignParentStart="true"
-        android:layout_alignParentBottom="true"
-        android:clickable="false"
-        />
-
-    <ImageView
-        android:id="@+id/large_icon"
-        android:layout_width="@android:dimen/notification_large_icon_height"
-        android:layout_height="@android:dimen/notification_large_icon_width"
-        android:scaleType="center"
-        android:visibility="gone"
-        android:layout_alignParentStart="true"
-        android:layout_alignParentBottom="true"
-        />
-
-    <FrameLayout
-        android:id="@+id/ticker_expanded"
-        android:layout_weight="1"
-        android:layout_height="@*android:dimen/system_bar_height"
-        android:layout_width="match_parent"
-        android:layout_toEndOf="@id/large_icon"
-        android:layout_alignParentBottom="true"
-        android:layout_alignWithParentIfMissing="true"
-        />
-</RelativeLayout>
diff --git a/packages/SystemUI/res/layout/universe.xml b/packages/SystemUI/res/layout/universe.xml
deleted file mode 100644
index 390c467..0000000
--- a/packages/SystemUI/res/layout/universe.xml
+++ /dev/null
@@ -1,39 +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.
--->
-
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent" android:layout_height="match_parent">
-    <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content"
-        android:layout_centerHorizontal="true" android:layout_alignParentTop="true"
-        android:src="@drawable/bugdroid" android:scaleType="center" />
-
-    <Button android:id="@+id/close"
-        android:layout_width="wrap_content" android:layout_height="wrap_content"
-        android:layout_alignParentTop="true" android:layout_alignParentEnd="true"
-        android:text="@string/close_universe" />
-
-    <TextView android:id="@+id/title"
-        android:layout_width="match_parent" android:layout_height="wrap_content"
-        android:layout_below="@id/close" android:layout_centerHorizontal="true"
-        android:paddingBottom="16dp"
-        android:textAppearance="?android:attr/textAppearanceLarge"
-        android:gravity="center" />
-
-    <ImageView android:id="@+id/bottom"
-        android:layout_width="wrap_content" android:layout_height="wrap_content"
-        android:layout_below="@id/title" android:layout_centerHorizontal="true"
-        android:layout_marginTop="16dp" />
-</RelativeLayout>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 60d6edc..a1a2ee5 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"Stelsel-UI"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Maak skoon"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Moenie steur nie"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Wys kennisgewings"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Verwyder uit lys"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Program Info"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Geen onlangse programme nie"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Koppel herlaaier"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Die battery raak pap."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> oor"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"USB-laaiery nie ondersteun nie."\n"Gebruik net die laaier wat verskaf is."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB-laaiery nie ondersteun nie.\nGebruik net die laaier wat verskaf is."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Batterygebruik"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Instellings"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <string name="always_use_device" msgid="1450287437017315906">"Gebruik by verstek vir hierdie USB-toestel"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Gebruik by verstek vir hierdie USB-toebehoorsel"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"Laat USB-ontfouting toe?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"Die rekenaar se RSA-sleutel-vingerafdruk is:"\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"Die rekenaar se RSA-sleutel-vingerafdruk is:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Laat altyd toe van hierdie rekenaar af"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoem om skerm te vul"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Strek om skerm te vul"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Versoenbaarheidszoem"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"As \'n program vir \'n kleiner skerm ontwerp is, sal \'n zoemkontrole naby die horlosie verskyn"</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Stoor tans skermkiekie..."</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"Stoor tans skermkiekie..."</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"Skermkiekie word tans gestoor."</string>
@@ -160,17 +156,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G data gedeaktiveer"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobieldata gedeaktiveer"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Data gedeaktiveer"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Jy het die gespesifiseerde data-gebruikslimiet bereik."\n\n"As jy data weer heraktiveer, kan jy deur jou diensverskaffer gehef word."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Jy het die gespesifiseerde data-gebruikslimiet bereik.\n\nAs jy data weer heraktiveer, kan jy deur jou diensverskaffer gehef word."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Heraktiveer data"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Geen internetverbinding nie"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi gekoppel"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Soek vir GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Ligging deur GPS gestel"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Liggingversoeke aktief"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Verwyder alle kennisgewings."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Programinligting"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Maak toe"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Kennisgewings af"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Tik hier om kennisgewings weer aan te skakel."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Die skerm sal outomaties draai."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Skerm is in landskapsoriëntasie gesluit."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Skerm is in portretoriëntasie gesluit."</string>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Outoroteer"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Rotasie gesluit"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Invoermetode"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Ligging in gebruik"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Ligging"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Ligging af"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Mediatoestel"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Net noodoproepe"</string>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Draadlose aansig"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Helderheid"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"OUTO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Kennisgewings verskyn hier"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Verkry enige tyd toegang tot hulle deur af te sleep."\n"Sleep weer af vir stelselkontroles."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Netwerk kan dalk gemonitor word"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 600ad6f..f56d200 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"የስርዓት UI"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"አጥራ"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"አይረብሹ"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"ማሳወቂያዎች አሳይ"</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="6576392951053994640">"ምንም የቅርብ ጊዜ ትግበራዎች የሉም"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"የኃይል መሙያ አገናኝ።"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"ባትሪው እያነሰ ነው።"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> ቀሪ"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"USB ኃይል መሙያ አይታገዝም።"\n" የቀረበውን ኃይል መሙያ ብቻ ተጠቀም።"</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB ኃይል መሙያ አይታገዝም።\n የቀረበውን ኃይል መሙያ ብቻ ተጠቀም።"</string>
     <string name="battery_low_why" msgid="7279169609518386372">"የባትሪ ጥቅም"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"ቅንብሮች"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <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="compat_mode_on" msgid="6623839244840638213">"ማያ እንዲሞላ አጉላ"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"ማያ ለመሙለት ሳብ"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"የተኳኋኝነት አጉላ"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"ትግበራ ለትንሽ ማያ ሲነደፍ፣ የአጉላ መቆመጣጠሪያ በሰዓት በኩል ብቅ ይላል።"</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>
@@ -160,17 +156,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G ውሂብ ቦዝኗል"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"የተንቀሳቃሽ ውሂብ ቦዝኗል"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"ውሂብ ቦዝኗል"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"የተቀመጠውን የውሂብ አጠቃቀም ገደብ ላይ ደርሰሃል:: "\n\n"ውሂብን እንደገና መልሰህ ዳግም-ካነቃህ በከዋኙ ክፍያ ልትጠየቅበት ትችል ይሆናል::"</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"የተቀመጠውን የውሂብ አጠቃቀም ገደብ ላይ ደርሰሃል:: \n\nውሂብን እንደገና መልሰህ ዳግም-ካነቃህ በከዋኙ ክፍያ ልትጠየቅበት ትችል ይሆናል::"</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"ውሂብ ድጋሚ አንቃ"</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="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="accessibility_clear_all" msgid="5235938559247164925">"ሁሉንም ማሳወቂያዎች አጽዳ"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"የመተግበሪያ መረጃ"</string>
-    <string name="close_universe" msgid="3736513750241754348">"ዝጋ"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"ማሳወቂያዎች ጠፍተዋል"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"ማስታወቅያዎችን መልሶ ለማብራት እዚህ ጋር መታ አድርግ።"</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>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"ራስ-አዙር"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"አዙሪት ተቆልፏል"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"የግቤት ስልት"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"በስራ ላይ ያለው አካባቢ"</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>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"ገመድ አልባ ማሳያ"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"ብሩህነት"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ራስ-ሰር"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"ማሳወቂያዎች እዚህ ላይ ይታያሉ"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"ወደ ታች በማንሸራተት በማንኛውም ጊዜ ይድረሱባቸው።"\n"Swipe የስርዓት መቆጣጠሪያዎችን ለማምጣት እንደገና ወደ ታች ያንሸራትቱ።"</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"አውታረ መረብ በክትትል ውስጥ ሊሆን ይችላል"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 44dcac1..3c709e4 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -21,8 +21,6 @@
     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_do_not_disturb_button" msgid="5812628897510997853">"عدم الإزعاج"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"إظهار التنبيهات"</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="6576392951053994640">"ليس هناك تطبيقات حديثة"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"توصيل الشاحن"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"انخفضت طاقة البطارية."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"المتبقي: <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"شحن USB غير معتمد."\n"استخدم الشاحن الموفر فقط."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"شحن USB غير معتمد.\nاستخدم الشاحن الموفر فقط."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"استخدام البطارية"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"الإعدادات"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <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="compat_mode_on" msgid="6623839244840638213">"تكبير/تصغير لملء الشاشة"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"توسيع بملء الشاشة"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"تكبير/تصغير التوافق"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"عند تصميم تطبيق لشاشة أصغر، سيظهر عنصر تحكم في التكبير/التصغير بجوار الساعة."</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>
@@ -160,17 +156,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"تم تعطيل بيانات شبكة الجيل الرابع"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"تم تعطيل بيانات الجوال"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"تم تعطيل البيانات"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"لقد وصلت إلى حد استخدام البيانات المحدد. "\n" "\n" إذا أعدت تمكين البيانات ، فقد يتم تحصيل رسوم منك من قبل مشغل شبكة الجوال."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"لقد وصلت إلى حد استخدام البيانات المحدد. \n \n إذا أعدت تمكين البيانات ، فقد يتم تحصيل رسوم منك من قبل مشغل شبكة الجوال."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"إعادة تمكين البيانات"</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="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="accessibility_clear_all" msgid="5235938559247164925">"محو جميع الإشعارات."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"معلومات التطبيق"</string>
-    <string name="close_universe" msgid="3736513750241754348">"إغلاق"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"التنبيهات معطّلة"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"انقر هنا لإعادة تشغيل الإشعارات."</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>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"تدوير تلقائي"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"تم قفل التدوير"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"أسلوب الإدخال"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"الموقع المستخدم"</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>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"عرض شاشة لاسلكي"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"السطوع"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"تلقائي"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"تظهر الإشعارات هنا"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"يمكنك الدخول إليها في أي وقت بالتمرير السريع إلى أسفل."\n"يمكنك التمرير السريع إلى أسفل مرة أخرى للوصول إلى عناصر تحكم النظام."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"قد تكون الشبكة مراقبة"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-az-rAZ-land/strings.xml b/packages/SystemUI/res/values-az-rAZ-land/strings.xml
new file mode 100644
index 0000000..8eb6978
--- /dev/null
+++ b/packages/SystemUI/res/values-az-rAZ-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * 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.
+ */
+ -->
+
+<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">"Hazırda ekran landşaft orientasiyasında kilidlənib."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-az-rAZ/strings.xml b/packages/SystemUI/res/values-az-rAZ/strings.xml
new file mode 100644
index 0000000..9565eee
--- /dev/null
+++ b/packages/SystemUI/res/values-az-rAZ/strings.xml
@@ -0,0 +1,206 @@
+<?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:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="7164937344850004466">"Sistemin İstifadə İnterfeysi"</string>
+    <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Təmizlə"</string>
+    <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Siyahıdan sil"</string>
+    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Tətbiq infosu"</string>
+    <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Yeni tətbiq yoxdur"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Son tətbiqləri kənarlaşdır"</string>
+  <plurals name="status_bar_accessibility_recent_apps">
+    <item quantity="one" msgid="5854176083865845541">"1 son tətbiq"</item>
+    <item quantity="other" msgid="1040784359794890744">"%d son tətbiq"</item>
+  </plurals>
+    <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Bildiriş yoxdu"</string>
+    <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Davam edir"</string>
+    <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Bildirişlər"</string>
+    <string name="battery_low_title" msgid="2783104807551211639">"Adapteri qoşun"</string>
+    <string name="battery_low_subtitle" msgid="1752040062087829196">"Batareya azalır."</string>
+    <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> qalıb"</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB ilə elektrik doldurma dəstəklənmir.\nYalnız adapter istifadə edin."</string>
+    <string name="battery_low_why" msgid="7279169609518386372">"Batareya istifadəsi"</string>
+    <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Ayarlar"</string>
+    <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
+    <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Təyyarə rejimi"</string>
+    <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"Ekranın avto-dönüşü"</string>
+    <string name="status_bar_settings_mute_label" msgid="554682549917429396">"SUSDUR"</string>
+    <string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AVTO"</string>
+    <string name="status_bar_settings_notifications" msgid="397146176280905137">"Bildirişlər"</string>
+    <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth tezerinq"</string>
+    <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Daxiletmə metodlarını ayarlayın"</string>
+    <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Fiziki klaviatura"</string>
+    <string name="usb_device_permission_prompt" msgid="834698001271562057">"<xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqinə USB cihazına daxil olmağa icazə verilsin?"</string>
+    <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"<xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqinə USB aksesuarına qoşulmağa icazə verirsiniz?"</string>
+    <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"USB cihaz qoşulu olan zaman <xliff:g id="ACTIVITY">%1$s</xliff:g> açılsın mı?"</string>
+    <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"USB aksesuar qoşulu olan zaman <xliff:g id="ACTIVITY">%1$s</xliff:g> açılsın mı?"</string>
+    <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"Heç bir quraşdırılmış tətbiq bu USB aksesuar ilə işləmir. Bu aksesuar haqqında daha ətraflı məlumatı <xliff:g id="URL">%1$s</xliff:g> adresindən öyrənin"</string>
+    <string name="title_usb_accessory" msgid="4966265263465181372">"USB aksesuar"</string>
+    <string name="label_view" msgid="6304565553218192990">"Göstər"</string>
+    <string name="always_use_device" msgid="1450287437017315906">"Bu USB cihaz üçün defolt olaraq istifadə edin."</string>
+    <string name="always_use_accessory" msgid="1210954576979621596">"Bu USB aksesuar üçün defolt istifadə edin"</string>
+    <string name="usb_debugging_title" msgid="4513918393387141949">"USB sazlamaya icazə verilsin?"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"Kompüterin RSA barmaq izi: \n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_always" msgid="303335496705863070">"Bu kompüterdən həmişə icazə verilsin"</string>
+    <string name="compat_mode_on" msgid="6623839244840638213">"Ekranı doldurmaq üçün yaxınlaşdır"</string>
+    <string name="compat_mode_off" msgid="4434467572461327898">"Ekranı doldurmaq üçün uzat"</string>
+    <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Skrinşot yadda saxlanılır..."</string>
+    <string name="screenshot_saving_title" msgid="8242282144535555697">"Skrinşot yadda saxlanır..."</string>
+    <string name="screenshot_saving_text" msgid="2419718443411738818">"Skrinşot yadda saxlanır."</string>
+    <string name="screenshot_saved_title" msgid="6461865960961414961">"Skrinşot çəkildi."</string>
+    <string name="screenshot_saved_text" msgid="1152839647677558815">"Skrinşotunuza baxmaq üçün toxunun"</string>
+    <string name="screenshot_failed_title" msgid="705781116746922771">"Skrinşot götürülə bilinmədi."</string>
+    <string name="screenshot_failed_text" msgid="8134011269572415402">"Skrinşotu yadda saxlamaq alınmadı, yəqin yaddaş istifadə olunur."</string>
+    <string name="usb_preference_title" msgid="6551050377388882787">"USB fayl transferi seçimləri"</string>
+    <string name="use_mtp_button_title" msgid="4333504413563023626">"Media pleyer (MTP) kimi montaj edin"</string>
+    <string name="use_ptp_button_title" msgid="7517127540301625751">"Kamera kimi birləşdir (PTP)"</string>
+    <string name="installer_cd_button_title" msgid="2312667578562201583">"Mac üçün Android File Transfer tətbiqini quraşdırın"</string>
+    <string name="accessibility_back" msgid="567011538994429120">"Geri"</string>
+    <string name="accessibility_home" msgid="8217216074895377641">"Ana səhifə"</string>
+    <string name="accessibility_menu" msgid="316839303324695949">"Menyu"</string>
+    <string name="accessibility_recent" msgid="8571350598987952883">"Son tətbiqlər"</string>
+    <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Daxiletmə metodu düyməsinə keç"</string>
+    <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Uyğunluq zoom düyməsi."</string>
+    <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Daha böyük ekranda uzaqlaşdır."</string>
+    <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth qoşulub."</string>
+    <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth əlaqəsi kəsildi."</string>
+    <string name="accessibility_no_battery" msgid="358343022352820946">"Batareya yoxdur."</string>
+    <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Batareya bir xətdir."</string>
+    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Batareya iki xətdir."</string>
+    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Batareya üç xətdir."</string>
+    <string name="accessibility_battery_full" msgid="8909122401720158582">"Batareya doludur"</string>
+    <string name="accessibility_no_phone" msgid="4894708937052611281">"Telefon yoxdur."</string>
+    <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Şəbəkə bir xətdir."</string>
+    <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Şəbəkə iki xətdir."</string>
+    <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"Şəbəkə üç xətdir."</string>
+    <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"Tam şəbəkə."</string>
+    <string name="accessibility_no_data" msgid="4791966295096867555">"Məlumat yoxdur."</string>
+    <string name="accessibility_data_one_bar" msgid="1415625833238273628">"Data bir xətdir."</string>
+    <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Data iki xətdir."</string>
+    <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Data üç xətdir."</string>
+    <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Data siqnalı tamdır."</string>
+    <string name="accessibility_wifi_off" msgid="3177380296697933627">"Wifi sönülüdür."</string>
+    <string name="accessibility_no_wifi" msgid="1425476551827924474">"Wifi bağlantı kəsildi."</string>
+    <string name="accessibility_wifi_one_bar" msgid="7735893178010724377">"Wifi bir xətdir."</string>
+    <string name="accessibility_wifi_two_bars" msgid="4994274250497262434">"Wifi iki xətdir."</string>
+    <string name="accessibility_wifi_three_bars" msgid="3495755044276588384">"Wifi üç xətdir."</string>
+    <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"Wifi siqnalı tamdır."</string>
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"WiMAX yoxdur."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX bir xətt."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX iki xətdir."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX üç xətdir."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX siqnalı tamdır."</string>
+    <string name="accessibility_no_signal" msgid="7064645320782585167">"Siqnal yoxdur."</string>
+    <string name="accessibility_not_connected" msgid="6395326276213402883">"Qoşulu deyil."</string>
+    <string name="accessibility_zero_bars" msgid="3806060224467027887">"Sıfır xətt."</string>
+    <string name="accessibility_one_bar" msgid="1685730113192081895">"Bir xətt."</string>
+    <string name="accessibility_two_bars" msgid="6437363648385206679">"İki xətt."</string>
+    <string name="accessibility_three_bars" msgid="2648241415119396648">"Üç xətdir."</string>
+    <string name="accessibility_signal_full" msgid="9122922886519676839">"Siqnal tamdır."</string>
+    <string name="accessibility_desc_on" msgid="2385254693624345265">"Aktiv."</string>
+    <string name="accessibility_desc_off" msgid="6475508157786853157">"Deaktiv"</string>
+    <string name="accessibility_desc_connected" msgid="8366256693719499665">"Qoşuludur."</string>
+    <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+    <string name="accessibility_data_connection_1x" msgid="994133468120244018">"1 X"</string>
+    <string name="accessibility_data_connection_hspa" msgid="2032328855462645198">"HSPA"</string>
+    <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+    <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+    <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+    <string name="accessibility_data_connection_lte" msgid="5413468808637540658">"LTE"</string>
+    <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+    <string name="accessibility_data_connection_roaming" msgid="5977362333466556094">"Rouminq"</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 yoxdur"</string>
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth tezering."</string>
+    <string name="accessibility_airplane_mode" msgid="834748999790763092">"Uçuş rejimi"</string>
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"Batareya <xliff:g id="NUMBER">%d</xliff:g> faizdir."</string>
+    <string name="accessibility_settings_button" msgid="799583911231893380">"Sistem parametrləri"</string>
+    <string name="accessibility_notifications_button" msgid="4498000369779421892">"Bildirişlər."</string>
+    <string name="accessibility_remove_notification" msgid="3603099514902182350">"Bildirişi təmizlə."</string>
+    <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS aktivdir."</string>
+    <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS əldə edilir."</string>
+    <string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter aktivləşdirilib."</string>
+    <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Zəng vibrasiyası"</string>
+    <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Zəngvuran səssiz."</string>
+    <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> çıxarıldı."</string>
+    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Bildiriş uzaqlaşdırıldı."</string>
+    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Bildiriş kölgəsi."</string>
+    <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Tez ayarlar."</string>
+    <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Axırıncı tətbiqlər."</string>
+    <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"İstifadəçi <xliff:g id="USER">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</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">"Batareya <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Təyyarə Rejimi <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarm <xliff:g id="TIME">%s</xliff:g> üçün qurulub."</string>
+    <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G data qeyri-aktivdir"</string>
+    <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G data deaktiv edildi"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobil data qeyri-aktivdir"</string>
+    <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Data qeyri-aktivdir"</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Göstərilmiş data istifadə limitinə çatdınız.\n\nƏgər datanı yenidən aktivləşdirsəniz, operator tərəfindən əlavə tariflər tətbiq oluna bilər."</string>
+    <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Datanı yenidən aktiv et"</string>
+    <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"İnternet bağlantısı yoxdur"</string>
+    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi qoşulub"</string>
+    <string name="gps_notification_searching_text" msgid="8574247005642736060">"GPS Axtarışı"</string>
+    <string name="gps_notification_found_text" msgid="4619274244146446464">"Yer GPS tərəfindən müəyyən edildi"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Məkan sorğuları arxivi"</string>
+    <string name="accessibility_clear_all" msgid="5235938559247164925">"Bütün bildirişləri sil."</string>
+    <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Tətbiq infosu"</string>
+    <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekran avtomatik döndəriləcək."</string>
+    <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Ekran landşaft orientasiyasında kilidlənib."</string>
+    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Ekran portret orientasiyasında kilidlənib."</string>
+    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="start_dreams" msgid="7219575858348719790">"Xəyal"</string>
+    <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Uçuş rejimi"</string>
+    <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"Dolur, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"Dolub"</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> Cihaz)"</string>
+    <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Bluetooth bağlıdır"</string>
+    <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Parlaqlıq"</string>
+    <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Avtofırlanma"</string>
+    <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Fırlatma kilidlidir"</string>
+    <string name="quick_settings_ime_label" msgid="7073463064369468429">"Daxiletmə metodu"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Yer"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Yer Deaktiv"</string>
+    <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Media cihazı"</string>
+    <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Yalnız fövqəladə zənglər"</string>
+    <string name="quick_settings_settings_label" msgid="5326556592578065401">"Nizamlar"</string>
+    <string name="quick_settings_time_label" msgid="4635969182239736408">"Vaxt"</string>
+    <string name="quick_settings_user_label" msgid="5238995632130897840">"Mən"</string>
+    <string name="quick_settings_wifi_label" msgid="9135344704899546041">"Wi-Fi"</string>
+    <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Bağlantı yoxdur"</string>
+    <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Şəbəkə yoxdur"</string>
+    <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi sönülüdür"</string>
+    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Wi-Fi Ekran"</string>
+    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Simsiz Ekran"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Parlaqlıq"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AVTO"</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Şəbəkə monitor edilə bilər"</string>
+    <string name="done_button" msgid="1759387181766603361">"Hazırdır"</string>
+    <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Şəbəkə Monitorinqi"</string>
+    <string name="ssl_ca_cert_info_message" msgid="5430320539555358452">"Bu cihaz <xliff:g id="MANAGING_DOMAIN">%s</xliff:g> tərəfindən idarə edilir . \n \n Sizin administrator şəbəkə fəaliyyətinizin, həmçinin e-poçt, tətbiqlər və təhlükəsiz veb saytlarınızın monitorinqini etməyə qadirdir. \n \n Ətraflı məlumat üçün administrator ilə əlaqə saxlayın."</string>
+    <string name="ssl_ca_cert_warning_message" msgid="2033091656129963669">"Üçüncü tərəf \n şəbəkə fəaliyyətinizin, həmçinin e-poçt, tətbiqlər və təhlükəsiz veb saytlarınızın monitorinqini etməyə qadirdir. . \n \nCihanzınıza yüklənmiş etibarlı etimad bunu mümkün edir."</string>
+    <string name="ssl_ca_cert_settings_button" msgid="7946956977377166709">"Etibarlı etimadları yoxlayın"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
new file mode 100644
index 0000000..cb48aa0
--- /dev/null
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -0,0 +1,208 @@
+<?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:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="7164937344850004466">"Sistemin İstifadə İnterfeysi"</string>
+    <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Təmizlə"</string>
+    <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Siyahıdan sil"</string>
+    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Tətbiq infosu"</string>
+    <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Yeni tətbiq yoxdur"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Son tətbiqləri kənarlaşdır"</string>
+  <plurals name="status_bar_accessibility_recent_apps">
+    <item quantity="one" msgid="5854176083865845541">"1 son tətbiq"</item>
+    <item quantity="other" msgid="1040784359794890744">"%d son tətbiq"</item>
+  </plurals>
+    <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Bildiriş yoxdu"</string>
+    <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Davam edir"</string>
+    <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Bildirişlər"</string>
+    <string name="battery_low_title" msgid="2783104807551211639">"Adapteri qoşun"</string>
+    <string name="battery_low_subtitle" msgid="1752040062087829196">"Batareya azalır."</string>
+    <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> qalıb"</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB ilə elektrik doldurma dəstəklənmir.\nYalnız adapter istifadə edin."</string>
+    <string name="battery_low_why" msgid="7279169609518386372">"Batareya istifadəsi"</string>
+    <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Ayarlar"</string>
+    <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
+    <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Təyyarə rejimi"</string>
+    <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"Ekranın avto-dönüşü"</string>
+    <string name="status_bar_settings_mute_label" msgid="554682549917429396">"SUSDUR"</string>
+    <string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AVTO"</string>
+    <string name="status_bar_settings_notifications" msgid="397146176280905137">"Bildirişlər"</string>
+    <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth tezerinq"</string>
+    <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Daxiletmə metodlarını ayarlayın"</string>
+    <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Fiziki klaviatura"</string>
+    <string name="usb_device_permission_prompt" msgid="834698001271562057">"<xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqinə USB cihazına daxil olmağa icazə verilsin?"</string>
+    <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"<xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqinə USB aksesuarına qoşulmağa icazə verirsiniz?"</string>
+    <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"USB cihaz qoşulu olan zaman <xliff:g id="ACTIVITY">%1$s</xliff:g> açılsın mı?"</string>
+    <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"USB aksesuar qoşulu olan zaman <xliff:g id="ACTIVITY">%1$s</xliff:g> açılsın mı?"</string>
+    <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"Heç bir quraşdırılmış tətbiq bu USB aksesuar ilə işləmir. Bu aksesuar haqqında daha ətraflı məlumatı <xliff:g id="URL">%1$s</xliff:g> adresindən öyrənin"</string>
+    <string name="title_usb_accessory" msgid="4966265263465181372">"USB aksesuar"</string>
+    <string name="label_view" msgid="6304565553218192990">"Göstər"</string>
+    <string name="always_use_device" msgid="1450287437017315906">"Bu USB cihaz üçün defolt olaraq istifadə edin."</string>
+    <string name="always_use_accessory" msgid="1210954576979621596">"Bu USB aksesuar üçün defolt istifadə edin"</string>
+    <string name="usb_debugging_title" msgid="4513918393387141949">"USB sazlamaya icazə verilsin?"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"Kompüterin RSA barmaq izi: \n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_always" msgid="303335496705863070">"Bu kompüterdən həmişə icazə verilsin"</string>
+    <string name="compat_mode_on" msgid="6623839244840638213">"Ekranı doldurmaq üçün yaxınlaşdır"</string>
+    <string name="compat_mode_off" msgid="4434467572461327898">"Ekranı doldurmaq üçün uzat"</string>
+    <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Skrinşot yadda saxlanılır..."</string>
+    <string name="screenshot_saving_title" msgid="8242282144535555697">"Skrinşot yadda saxlanır..."</string>
+    <string name="screenshot_saving_text" msgid="2419718443411738818">"Skrinşot yadda saxlanır."</string>
+    <string name="screenshot_saved_title" msgid="6461865960961414961">"Skrinşot çəkildi."</string>
+    <string name="screenshot_saved_text" msgid="1152839647677558815">"Skrinşotunuza baxmaq üçün toxunun"</string>
+    <string name="screenshot_failed_title" msgid="705781116746922771">"Skrinşot götürülə bilinmədi."</string>
+    <string name="screenshot_failed_text" msgid="8134011269572415402">"Skrinşotu yadda saxlamaq alınmadı, yəqin yaddaş istifadə olunur."</string>
+    <string name="usb_preference_title" msgid="6551050377388882787">"USB fayl transferi seçimləri"</string>
+    <string name="use_mtp_button_title" msgid="4333504413563023626">"Media pleyer (MTP) kimi montaj edin"</string>
+    <string name="use_ptp_button_title" msgid="7517127540301625751">"Kamera kimi birləşdir (PTP)"</string>
+    <string name="installer_cd_button_title" msgid="2312667578562201583">"Mac üçün Android File Transfer tətbiqini quraşdırın"</string>
+    <string name="accessibility_back" msgid="567011538994429120">"Geri"</string>
+    <string name="accessibility_home" msgid="8217216074895377641">"Ana səhifə"</string>
+    <string name="accessibility_menu" msgid="316839303324695949">"Menyu"</string>
+    <string name="accessibility_recent" msgid="8571350598987952883">"Son tətbiqlər"</string>
+    <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Daxiletmə metodu düyməsinə keç"</string>
+    <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Uyğunluq zoom düyməsi."</string>
+    <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Daha böyük ekranda uzaqlaşdır."</string>
+    <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth qoşulub."</string>
+    <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth əlaqəsi kəsildi."</string>
+    <string name="accessibility_no_battery" msgid="358343022352820946">"Batareya yoxdur."</string>
+    <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Batareya bir xətdir."</string>
+    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Batareya iki xətdir."</string>
+    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Batareya üç xətdir."</string>
+    <string name="accessibility_battery_full" msgid="8909122401720158582">"Batareya doludur"</string>
+    <string name="accessibility_no_phone" msgid="4894708937052611281">"Telefon yoxdur."</string>
+    <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Şəbəkə bir xətdir."</string>
+    <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Şəbəkə iki xətdir."</string>
+    <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"Şəbəkə üç xətdir."</string>
+    <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"Tam şəbəkə."</string>
+    <string name="accessibility_no_data" msgid="4791966295096867555">"Məlumat yoxdur."</string>
+    <string name="accessibility_data_one_bar" msgid="1415625833238273628">"Data bir xətdir."</string>
+    <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Data iki xətdir."</string>
+    <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Data üç xətdir."</string>
+    <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Data siqnalı tamdır."</string>
+    <string name="accessibility_wifi_off" msgid="3177380296697933627">"Wifi sönülüdür."</string>
+    <string name="accessibility_no_wifi" msgid="1425476551827924474">"Wifi bağlantı kəsildi."</string>
+    <string name="accessibility_wifi_one_bar" msgid="7735893178010724377">"Wifi bir xətdir."</string>
+    <string name="accessibility_wifi_two_bars" msgid="4994274250497262434">"Wifi iki xətdir."</string>
+    <string name="accessibility_wifi_three_bars" msgid="3495755044276588384">"Wifi üç xətdir."</string>
+    <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"Wifi siqnalı tamdır."</string>
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"WiMAX yoxdur."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX bir xətt."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX iki xətdir."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX üç xətdir."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX siqnalı tamdır."</string>
+    <string name="accessibility_no_signal" msgid="7064645320782585167">"Siqnal yoxdur."</string>
+    <string name="accessibility_not_connected" msgid="6395326276213402883">"Qoşulu deyil."</string>
+    <string name="accessibility_zero_bars" msgid="3806060224467027887">"Sıfır xətt."</string>
+    <string name="accessibility_one_bar" msgid="1685730113192081895">"Bir xətt."</string>
+    <string name="accessibility_two_bars" msgid="6437363648385206679">"İki xətt."</string>
+    <string name="accessibility_three_bars" msgid="2648241415119396648">"Üç xətdir."</string>
+    <string name="accessibility_signal_full" msgid="9122922886519676839">"Siqnal tamdır."</string>
+    <string name="accessibility_desc_on" msgid="2385254693624345265">"Aktiv."</string>
+    <string name="accessibility_desc_off" msgid="6475508157786853157">"Deaktiv"</string>
+    <string name="accessibility_desc_connected" msgid="8366256693719499665">"Qoşuludur."</string>
+    <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+    <string name="accessibility_data_connection_1x" msgid="994133468120244018">"1 X"</string>
+    <string name="accessibility_data_connection_hspa" msgid="2032328855462645198">"HSPA"</string>
+    <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+    <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+    <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+    <string name="accessibility_data_connection_lte" msgid="5413468808637540658">"LTE"</string>
+    <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+    <string name="accessibility_data_connection_roaming" msgid="5977362333466556094">"Rouminq"</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 yoxdur"</string>
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth tezering."</string>
+    <string name="accessibility_airplane_mode" msgid="834748999790763092">"Uçuş rejimi"</string>
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"Batareya <xliff:g id="NUMBER">%d</xliff:g> faizdir."</string>
+    <string name="accessibility_settings_button" msgid="799583911231893380">"Sistem parametrləri"</string>
+    <string name="accessibility_notifications_button" msgid="4498000369779421892">"Bildirişlər."</string>
+    <string name="accessibility_remove_notification" msgid="3603099514902182350">"Bildirişi təmizlə."</string>
+    <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS aktivdir."</string>
+    <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS əldə edilir."</string>
+    <string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter aktivləşdirilib."</string>
+    <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Zəng vibrasiyası"</string>
+    <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Zəngvuran səssiz."</string>
+    <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> çıxarıldı."</string>
+    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Bildiriş uzaqlaşdırıldı."</string>
+    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Bildiriş kölgəsi."</string>
+    <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Tez ayarlar."</string>
+    <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Axırıncı tətbiqlər."</string>
+    <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"İstifadəçi <xliff:g id="USER">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</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">"Batareya <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Təyyarə Rejimi <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarm <xliff:g id="TIME">%s</xliff:g> üçün qurulub."</string>
+    <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G data qeyri-aktivdir"</string>
+    <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G data deaktiv edildi"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobil data qeyri-aktivdir"</string>
+    <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Data qeyri-aktivdir"</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Göstərilmiş data istifadə limitinə çatdınız.\n\nƏgər datanı yenidən aktivləşdirsəniz, operator tərəfindən əlavə tariflər tətbiq oluna bilər."</string>
+    <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Datanı yenidən aktiv et"</string>
+    <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"İnternet bağlantısı yoxdur"</string>
+    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi qoşulub"</string>
+    <string name="gps_notification_searching_text" msgid="8574247005642736060">"GPS Axtarışı"</string>
+    <string name="gps_notification_found_text" msgid="4619274244146446464">"Yer GPS tərəfindən müəyyən edildi"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Məkan sorğuları arxivi"</string>
+    <string name="accessibility_clear_all" msgid="5235938559247164925">"Bütün bildirişləri sil."</string>
+    <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Tətbiq infosu"</string>
+    <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekran avtomatik döndəriləcək."</string>
+    <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Ekran landşaft orientasiyasında kilidlənib."</string>
+    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Ekran portret orientasiyasında kilidlənib."</string>
+    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="start_dreams" msgid="7219575858348719790">"Xəyal"</string>
+    <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Uçuş rejimi"</string>
+    <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"Dolur, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"Dolub"</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> Cihaz)"</string>
+    <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Bluetooth bağlıdır"</string>
+    <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Parlaqlıq"</string>
+    <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Avtofırlanma"</string>
+    <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Fırlatma kilidlidir"</string>
+    <string name="quick_settings_ime_label" msgid="7073463064369468429">"Daxiletmə metodu"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Yer"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Yer Deaktiv"</string>
+    <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Media cihazı"</string>
+    <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Yalnız fövqəladə zənglər"</string>
+    <string name="quick_settings_settings_label" msgid="5326556592578065401">"Nizamlar"</string>
+    <string name="quick_settings_time_label" msgid="4635969182239736408">"Vaxt"</string>
+    <string name="quick_settings_user_label" msgid="5238995632130897840">"Mən"</string>
+    <string name="quick_settings_wifi_label" msgid="9135344704899546041">"Wi-Fi"</string>
+    <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Bağlantı yoxdur"</string>
+    <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Şəbəkə yoxdur"</string>
+    <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi sönülüdür"</string>
+    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Wi-Fi Ekran"</string>
+    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Simsiz Ekran"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Parlaqlıq"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AVTO"</string>
+    <string name="status_bar_help_title" msgid="1199237744086469217">"Bildirişlər burada görünür"</string>
+    <string name="status_bar_help_text" msgid="7874607155052076323">"Aşağı sürüşdürməklə istənilən vaxt onları əldə edin.\nSistemi nəzarəti üçün yenə də aşağı sürüşdürün."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Şəbəkə monitor edilə bilər"</string>
+    <string name="done_button" msgid="1759387181766603361">"Hazırdır"</string>
+    <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Şəbəkə Monitorinqi"</string>
+    <string name="ssl_ca_cert_info_message" msgid="5430320539555358452">"Bu cihaz <xliff:g id="MANAGING_DOMAIN">%s</xliff:g> tərəfindən idarə edilir . \n \n Sizin administrator şəbəkə fəaliyyətinizin, həmçinin e-poçt, tətbiqlər və təhlükəsiz veb saytlarınızın monitorinqini etməyə qadirdir. \n \n Ətraflı məlumat üçün administrator ilə əlaqə saxlayın."</string>
+    <string name="ssl_ca_cert_warning_message" msgid="2033091656129963669">"Üçüncü tərəf \n şəbəkə fəaliyyətinizin, həmçinin e-poçt, tətbiqlər və təhlükəsiz veb saytlarınızın monitorinqini etməyə qadirdir. . \n \nCihanzınıza yüklənmiş etibarlı etimad bunu mümkün edir."</string>
+    <string name="ssl_ca_cert_settings_button" msgid="7946956977377166709">"Etibarlı etimadları yoxlayın"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index d66e946..b379bab 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -21,8 +21,6 @@
     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_do_not_disturb_button" msgid="5812628897510997853">"Не турбаваць"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Паказваць паведамленні"</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="6576392951053994640">"Апошніх прыкладанняў няма"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Падлучыце зарадную прыладу."</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Зарад батарэі становіцца нізкім."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"Спроб засталося: <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"USB-зарадка не падтрымліваецца."\n"Карыстайцеся толькі зарадкай для прылады."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB-зарадка не падтрымліваецца.\nКарыстайцеся толькі зарадкай для прылады."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Выкарыстанне батарэі"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Налады"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <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">"Адбiтак ключа RSA на гэтым камп\'ютары:"\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"Адбiтак ключа RSA на гэтым камп\'ютары:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Заўсёды дазваляць з гэтага камп\'ютара"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Павял. на ўвесь экран"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Расцягн. на ўвесь экран"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Маштабаванне для сумяшчальнасцi"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Калі прыкладанне распрацаванае для невялікіх экранаў, каля гадзінніка з\'явіцца кіраванне маштабаваннем."</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>
@@ -162,17 +158,16 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Дадзеныя 4G адключаныя"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Мабільная перадача дадзеных адключаная"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Дадзеныя адключаныя"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Вы перавысiлi ўсталяваны лiмiт на выкарыстанне. "\n\n"Калі вы паўторна ўключыце перадачу дадзеных, можа спаганяцца плата."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Вы перавысiлi ўсталяваны лiмiт на выкарыстанне. \n\nКалі вы паўторна ўключыце перадачу дадзеных, можа спаганяцца плата."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Паўторна ўключыць дадзеныя"</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>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Пошук GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Месца задана праз GPS"</string>
+    <!-- no translation found for accessibility_location_active (2427290146138169014) -->
+    <skip />
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Выдалiць усе апавяшчэннi."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Інфармацыя пра прыкладанне"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Закрыць"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Паведамленні адключаны"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Націсніце тут, каб зноў уключыць апавяшчэнні."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Экран паварочваецца аўтаматычна."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Экран заблакiраваны ў альбомнай арыентацыі."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Экран заблакiраваны ў партрэтнай арыентацыі."</string>
@@ -189,7 +184,10 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Аўтапаварот"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Паварот забаронены"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Метад уводу"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Месцазнаходжанне выкарыстоўваецца"</string>
+    <!-- no translation found for quick_settings_location_label (5011327048748762257) -->
+    <skip />
+    <!-- no translation found for quick_settings_location_off_label (7464544086507331459) -->
+    <skip />
     <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>
@@ -204,6 +202,6 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Бесправадны дысплей"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Яркасць"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АЎТА"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Апавяшчэнні з\'яўляюцца тут"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Атрымлівайце доступ да іх у любы час, праводзячы пальцам уніз."\n"Правядзіце пальцам уніз яшчэ раз, каб атрымаць доступ да сродкаў кіравання сістэмай."</string>
+    <!-- no translation found for ssl_ca_cert_warning (5848402127455021714) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index d7094af..5d2f249 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -21,8 +21,6 @@
     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_do_not_disturb_button" msgid="5812628897510997853">"Не ме безпокойте"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Показване на известията"</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="6576392951053994640">"Няма скорошни приложения"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Включете зарядното устройство"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Батерията се изтощава."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"Остава: <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"Не се поддържа зареждане през USB."\n"Използвайте само доставеното зарядно устройство."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"Не се поддържа зареждане през USB.\nИзползвайте само доставеното зарядно устройство."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Използване на батерията"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Настройки"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <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="compat_mode_on" msgid="6623839244840638213">"Мащаб – запълва екрана"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Разпъване – запълва екрана"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Промяна на мащаба за съвместимост"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Когато дадено приложение е създадено за по-малък екран, до часовника ще се покаже управление за промяна на мащаба."</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>
@@ -160,17 +156,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G данните са деактивирани"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Мобилните данни са деактивирани"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Трафикът на данни е деактивиран"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Достигнахте определеното ограничение за използване на данни."\n\n"Ако ги активирате отново, е възможно да бъдете таксувани от оператора."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Достигнахте определеното ограничение за използване на данни.\n\nАко ги активирате отново, е възможно да бъдете таксувани от оператора."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Активиране на данните отново"</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="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="accessibility_clear_all" msgid="5235938559247164925">"Изчистване на всички известия."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Информация за приложението"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Затваряне"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Известията са изключени"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Докоснете тук, за да включите отново известията."</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>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Автоматична ориентация"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Ориентацията е заключена"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Метод на въвеждане"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Използвано местоположение"</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>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Безжичен дисплей"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Яркост"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АВТ."</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Известията се показват тук"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Осъществявайте достъп до тях по всяко време, като прекарате пръст надолу."\n"Направете го отново за системните контроли."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Мрежата може да се наблюдава"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index a8d1e7b..e0ed9fb 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"IU del sistema"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Esborra"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"No molesteu"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Mostra notificacions"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Elimina de la llista"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Informació de l\'aplicació"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"No hi ha aplicacions recents"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Connecta el carregador"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"La bateria comença a estar baixa."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> restant"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"Càrrega d\'USB no admesa."\n"Utilitza només el carregador proporcionat."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"Càrrega d\'USB no admesa.\nUtilitza només el carregador proporcionat."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Ús de la bateria"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Configuració"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <string name="always_use_device" msgid="1450287437017315906">"Utilitza de manera predet. per al dispositiu USB"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Utilitza de manera predet. per a l\'accessori USB"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"Vols permetre la depuració USB?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"L\'empremta digital de la clau de l\'RSA de l\'equip és:"\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"L\'empremta digital de la clau de l\'RSA de l\'equip és:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Dóna sempre permís des d\'aquest equip"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom per omplir pantalla"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Estira per omplir pant."</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Zoom de compatibilitat"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Quan una aplicació s\'hagi dissenyat per a una pantalla més petita, apareixerà un control de zoom al costat del rellotge."</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Desant captura de pantalla..."</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"S\'està desant la captura de pantalla..."</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"La captura de pantalla s\'ha desat."</string>
@@ -162,17 +158,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Dades 4G desactivades"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Dades mòbils desactivades"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Dades desactivades"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Has arribat al límit especificat d\'utilització de dades."\n\n"Si has reactivat les dades, és possible que l\'operador et faci algun càrrec."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Has arribat al límit especificat d\'utilització de dades.\n\nSi has reactivat les dades, és possible que l\'operador et faci algun càrrec."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Torna a activar les dades"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"No hi ha connexió a Internet"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi: connectada"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"S\'està cercant un GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"S\'ha establert la ubicació per GPS"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Sol·licituds d\'ubicació actives"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Esborra totes les notificacions."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informació de l\'aplicació"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Tanca"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Notificacions desactivades"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Pica aquí per tornar a activar les notificacions."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"La pantalla girarà automàticament."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"La pantalla està bloquejada en orientació horitzontal."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"La pantalla està bloquejada en orientació vertical."</string>
@@ -189,7 +183,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Rotació automàtica"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Rotació bloquejada"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Mètode d\'entrada"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Ubicació en ús"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Ubicació"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Ubicació desactivada"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Dispositiu multimèdia"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Només trucades d\'emergència"</string>
@@ -204,6 +199,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Pantalla sense fil"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brillantor"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMÀTICA"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Les notificacions apareixen aquí"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Accedeix-hi en qualsevol moment: només has de fer lliscar el dit cap avall."\n"Torna a fer lliscar el dit cap avall per fer que es mostrin els controls del sistema."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Pot ser que la xarxa se supervisi."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 86f069f..0b0597a 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <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_do_not_disturb_button" msgid="5812628897510997853">"Nerušit"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Zobrazit upozornění"</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_no_recent_apps" msgid="6576392951053994640">"Žádné nové aplikace"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Připojte nabíječku"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Baterie je vybitá."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"Zbývá <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"Nabíjení pomocí rozhraní USB není podporováno."\n"Používejte pouze nabíječku, která byla dodána se zařízením."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"Nabíjení pomocí rozhraní USB není podporováno.\nPoužívejte pouze nabíječku, která byla dodána se zařízením."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Využití baterie"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Nastavení"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <string name="always_use_device" msgid="1450287437017315906">"Pro toto zařízení USB použít jako výchozí"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Pro toto periferní zařízení USB použít jako výchozí"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"Povolit ladění USB?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"Digitální otisk RSA počítače je:"\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"Digitální otisk RSA počítače je:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Vždy povolit z tohoto počítače"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Přiblížit na celou obrazovku"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Na celou obrazovku"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Úprava velikosti z důvodu kompatibility"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Pokud je aplikace navržena pro menší obrazovku, zobrazí se vedle hodin ovládací prvek přiblížení."</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Ukládání snímku obrazovky..."</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"Ukládání snímku obrazovky..."</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"Probíhá ukládání snímku obrazovky."</string>
@@ -162,17 +158,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Datové přenosy 4G jsou zakázány"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobilní data jsou zakázána"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Přenos dat vypnut"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Dosáhli jste stanoveného limitu využití dat."\n\n"Chcete-li datové připojení znovu zapnout, operátor vám může účtovat poplatky."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Dosáhli jste stanoveného limitu využití dat.\n\nChcete-li datové připojení znovu zapnout, operátor vám může účtovat poplatky."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Znovu povolit data"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Žádné přip. k internetu"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi: připojeno"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Vyhledávání satelitů GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Poloha nastavena pomocí systému GPS"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Aktivní žádosti o polohu"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Vymazat všechna oznámení."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informace o aplikaci"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Zavřít"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Oznámení jsou vypnuta"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Chcete-li oznámení znovu zapnout, klepněte sem."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Obrazovka se automaticky otočí."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Obrazovka je uzamčena v orientaci na šířku."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Obrazovka je uzamčena v orientaci na výšku."</string>
@@ -189,7 +183,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Automatické otáčení"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Otáčení je uzamčeno"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Metoda zadávání dat"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Používaná poloha"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Poloha"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Poloha vypnuta"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Mediální zařízení"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Pouze tísňová volání"</string>
@@ -204,6 +199,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Bezdrátový displej"</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="status_bar_help_title" msgid="1199237744086469217">"Zde se zobrazují oznámení"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Můžete je kdykoli zobrazit tím, že přejedete prstem dolů."\n"Přejedete-li prstem dolů ještě jednou, zobrazí se ovládací prvky systému."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Síť může být monitorována"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 1bfe7c5..e502b26 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"System-UI"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Ryd"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Forstyr ikke"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Vis meddelelser"</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_no_recent_apps" msgid="6576392951053994640">"Der er ingen seneste apps"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Tilslut oplader"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Batteriet er ved at være fladt."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> tilbage"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"Opladning via USB understøttes ikke."\n"Brug kun den medfølgende oplader."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"Opladning via USB understøttes ikke.\nBrug kun den medfølgende oplader."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Batteriforbrug"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Indstillinger"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <string name="always_use_device" msgid="1450287437017315906">"Brug som standard til denne USB-enhed"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Brug som standard til dette USB-tilbehør"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"Vil du tillade USB-fejlretning?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"Fingeraftrykket for computerens RSA-nøgle er:"\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"Fingeraftrykket for computerens RSA-nøgle er:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Tillad altid fra denne computer"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom til fuld skærm"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Stræk til fuld skærm"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Kompatibilitetszoom"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Når en app er udviklet til en mindre skærm, vises der en zoomfunktion ved uret."</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Gemmer skærmbillede..."</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"Gemmer skærmbillede..."</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"Skærmbilledet gemmes."</string>
@@ -160,17 +156,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G-data er deaktiveret"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobildata er deaktiveret"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Data er deaktiveret"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Du har nået den angivne grænse for dataforbruget."\n\n"Hvis du genaktiverer data, kan dit mobilselskab opkræve ekstra."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Du har nået den angivne grænse for dataforbruget.\n\nHvis du genaktiverer data, kan dit mobilselskab opkræve ekstra."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Genaktiver data"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Ingen internetforb."</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi er forbundet"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Søger efter GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Placeringen er angivet ved hjælp af GPS"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Aktive placeringsanmodninger"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Ryd alle meddelelser."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Oplysninger om appen"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Luk"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Underretninger slået fra"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Tryk her for at slå underretninger til igen."</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>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Skærmen er nu låst i stående retning."</string>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Automatisk rotation"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Rotation er låst"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Inputmetode"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Placering i brug"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Placering"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Placering fra"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Medieenhed"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Kun nødopkald"</string>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Trådløs skærm"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Lysstyrke"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Underretninger vises her"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Få adgang til dem når som helst ved at stryge ned."\n"Stryg ned igen for at komme til systemindstillingerne."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Netværket kan være overvåget"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index cb073d2..17b425b 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"System-UI"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Löschen"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Bitte nicht stören"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Benachrichtigungen zeigen"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Aus Liste entfernen"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"App-Info"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Keine kürzlich geöffneten Apps"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Ladegerät anschließen"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Akku ist fast leer."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"Noch <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"USB-Aufladung wird nicht unterstützt."\n"Verwenden Sie das mitgelieferte Aufladegerät."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB-Aufladung wird nicht unterstützt.\nVerwenden Sie das mitgelieferte Aufladegerät."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Akkuverbrauch"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Einstellungen"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"WLAN"</string>
@@ -59,12 +57,10 @@
     <string name="always_use_device" msgid="1450287437017315906">"Standardmäßig für dieses USB-Gerät verwenden"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Standardmäßig für dieses USB-Zubehör verwenden"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"USB-Debugging zulassen?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"Der Fingerabdruck des RSA-Schlüssels für diesen Computer lautet: "\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"Der Fingerabdruck des RSA-Schlüssels für diesen Computer lautet: \n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Von diesem Computer immer zulassen"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom auf Bildschirmgröße"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Auf Bildschirmgröße anpassen"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Kompatibilitätszoom"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Wenn eine App für einen kleineren Bildschirm ausgelegt ist, wird ein Zoom-Steuerelement neben der Uhr angezeigt."</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Screenshot wird gespeichert..."</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"Screenshot wird gespeichert..."</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"Screenshot wird gespeichert..."</string>
@@ -162,17 +158,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G-Daten deaktiviert"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobilfunk Daten deaktiviert"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Daten deaktiviert"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Sie haben die angegebenen Grenze für den Datenverbrauch erreicht."\n\n"Wenn Sie die Datennutzung erneut aktivieren, berechnet Ihr Mobilfunkanbieter unter Umständen zusätzliche Gebühren."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Sie haben die angegebenen Grenze für den Datenverbrauch erreicht.\n\nWenn Sie die Datennutzung erneut aktivieren, berechnet Ihr Mobilfunkanbieter unter Umständen zusätzliche Gebühren."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Daten erneut aktivieren"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Keine Internetverbindung"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"WLAN verbunden"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"GPS wird gesucht"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Standort durch GPS festgelegt"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Standortanfragen aktiv"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Alle Benachrichtigungen löschen"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"App-Details"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Schließen"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Benachrichtigungen aus"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Tippen Sie hier, um die Benachrichtigungen wieder zu aktivieren."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Bildschirm wird automatisch gedreht."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Bildschirm bleibt im Querformat."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Bildschirm bleibt im Hochformat."</string>
@@ -189,7 +183,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Autom. drehen"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Drehung gesperrt"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Eingabemethode"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Verwendeter Standort"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Standort"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Standort aus"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Mediengerät"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Nur Notrufe"</string>
@@ -204,6 +199,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Kabellose Übertragung (WiDi)"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Helligkeit"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Benachrichtigungen erscheinen hier"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Greifen Sie jederzeit auf sie zu, indem Sie nach unten wischen."\n"Wischen Sie für Systemeinstellungen erneut nach unten."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Das Netzwerk wird möglicherweise überwacht."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 9baeb37..43b9cbc 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"UI συστήματ."</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Εκκαθάριση"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Μην ενοχλείτε"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Εμφάνιση ειδοποιήσεων"</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="6576392951053994640">"Δεν υπάρχουν πρόσφατες εφαρμογές"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Συνδέστε φορτιστή"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Η στάθμη της μπαταρίας είναι χαμηλή."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"Απομένει <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"Δεν υποστηρίζεται η φόρτιση USB."\n"Χρησιμοποιείτε μόνο τον φορτιστή που παρέχεται."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"Δεν υποστηρίζεται η φόρτιση USB.\nΧρησιμοποιείτε μόνο τον φορτιστή που παρέχεται."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Χρήση μπαταρίας"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Ρυθμίσεις"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <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="compat_mode_on" msgid="6623839244840638213">"Ζουμ σε πλήρη οθόνη"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Προβoλή σε πλήρη οθ."</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Ζουμ για συμβατότητα"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Όταν μια εφαρμογή έχει σχεδιαστεί για προβολή σε μικρότερη οθόνη, δίπλα από το ρολόι θα εμφανιστεί ένα στοιχείο ελέγχου ζουμ."</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>
@@ -162,17 +158,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Τα δεδομένα 4G απενεργοποιήθηκαν"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Τα δεδομένα κινητής τηλεφωνίας απενεργοποιήθηκαν"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Απενεργοποιήθηκαν τα δεδομένα"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Συμπληρώσατε το καθορισμένο όριο χρήσης δεδομένων."\n\n"Αν ενεργοποιήσετε ξανά τα δεδομένα, ενδέχεται να χρεωθείτε από την εταιρεία κινητής τηλεφωνίας."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Συμπληρώσατε το καθορισμένο όριο χρήσης δεδομένων.\n\nΑν ενεργοποιήσετε ξανά τα δεδομένα, ενδέχεται να χρεωθείτε από την εταιρεία κινητής τηλεφωνίας."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Νέα ενεργοποίηση δεδομένων"</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="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="accessibility_clear_all" msgid="5235938559247164925">"Εκκαθάριση όλων των ειδοποιήσεων."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Πληροφορίες εφαρμογής"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Κλείσιμο"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Ειδοποιήσεις ανενεργές"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Πατήστε εδώ για να ενεργοποιήσετε ξανά τις ειδοποιήσεις."</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>
@@ -189,7 +183,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Αυτόματη περιστροφή"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Η περιστροφή είναι κλειδωμένη"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Μέθοδος εισαγωγής"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Τοποθεσία σε χρήση"</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>
@@ -204,6 +199,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Ασύρματη οθόνη"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Φωτεινότητα"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ΑΥΤΟΜΑΤΗ"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Οι ειδοποιήσεις εμφανίζονται εδώ"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Μεταβείτε σε αυτές ανά πάσα στιγμή σύροντας προς τα κάτω."\n"Σύρετε ξανά προς τα κάτω για τα στοιχεία ελέγχου συστήματος."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Το δίκτυο ενδέχεται να παρακολουθείται"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index deb7d09..8a16d7c 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"System UI"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Clear"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Do not disturb"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Show notifications"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Remove from list"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"App info"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"No recent apps"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Connect charger"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"The battery is getting low."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> remaining"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"USB charging not supported."\n"Use only the supplied charger."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB charging not supported.\nUse only the supplied charger."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Battery use"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Settings"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <string name="always_use_device" msgid="1450287437017315906">"Use by default for this USB device"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Use by default for this USB accessory"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"Allow USB debugging?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"The computer\'s RSA key fingerprint is:"\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"The computer\'s RSA key fingerprint is:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Always allow from this computer"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom to fill screen"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Stretch to fill screen"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Compatibility zoom"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"When an app was designed for a smaller screen, a zoom control will appear by the clock."</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Saving screenshot…"</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"Saving screenshot…"</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"Screenshot is being saved."</string>
@@ -160,17 +156,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G data disabled"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobile data disabled"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Data disabled"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"You\'ve reached the specified data usage limit."\n\n"If you re-enable data, you may be charged by the operator."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"You\'ve reached the specified data usage limit.\n\nIf you re-enable data, you may be charged by the operator."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Reenable data"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"No Internet connection"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi connected"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Searching for GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Location set by GPS"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Location requests active"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Clear all notifications."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"App info"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Close"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Notifications off"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Tap here to turn notifications back on."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Screen will rotate automatically."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Screen is locked in landscape orientation."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Screen is locked in portrait orientation."</string>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Auto Rotate"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Rotation Locked"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Input Method"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Location in use"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Location"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Location Off"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Media device"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Emergency Calls Only"</string>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Wireless Display"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brightness"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Notifications appear here"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Access them any time by swiping down."\n"Swipe down again for system controls."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Network may be monitored"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN-land/strings.xml b/packages/SystemUI/res/values-en-rIN-land/strings.xml
new file mode 100644
index 0000000..ba773b8
--- /dev/null
+++ b/packages/SystemUI/res/values-en-rIN-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * 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.
+ */
+ -->
+
+<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">"Screen is now locked in landscape orientation."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..8a16d7c
--- /dev/null
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -0,0 +1,201 @@
+<?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:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="7164937344850004466">"System UI"</string>
+    <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Clear"</string>
+    <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Remove from list"</string>
+    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"App info"</string>
+    <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"No recent apps"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Dismiss recent apps"</string>
+  <plurals name="status_bar_accessibility_recent_apps">
+    <item quantity="one" msgid="5854176083865845541">"1 recent app"</item>
+    <item quantity="other" msgid="1040784359794890744">"%d recent apps"</item>
+  </plurals>
+    <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"No notifications"</string>
+    <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Ongoing"</string>
+    <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notifications"</string>
+    <string name="battery_low_title" msgid="2783104807551211639">"Connect charger"</string>
+    <string name="battery_low_subtitle" msgid="1752040062087829196">"The battery is getting low."</string>
+    <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> remaining"</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB charging not supported.\nUse only the supplied charger."</string>
+    <string name="battery_low_why" msgid="7279169609518386372">"Battery use"</string>
+    <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Settings"</string>
+    <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
+    <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Aeroplane mode"</string>
+    <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"Auto-rotate screen"</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">"Notifications"</string>
+    <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth tethered"</string>
+    <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Set up input methods"</string>
+    <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Physical keyboard"</string>
+    <string name="usb_device_permission_prompt" msgid="834698001271562057">"Allow the app <xliff:g id="APPLICATION">%1$s</xliff:g> to access the USB device?"</string>
+    <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Allow the app <xliff:g id="APPLICATION">%1$s</xliff:g> to access the USB accessory?"</string>
+    <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Open <xliff:g id="ACTIVITY">%1$s</xliff:g> when this USB device is connected?"</string>
+    <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Open <xliff:g id="ACTIVITY">%1$s</xliff:g> when this USB accessory is connected?"</string>
+    <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"No installed apps work with this USB accessory. Learn more about this accessory at <xliff:g id="URL">%1$s</xliff:g>"</string>
+    <string name="title_usb_accessory" msgid="4966265263465181372">"USB accessory"</string>
+    <string name="label_view" msgid="6304565553218192990">"View"</string>
+    <string name="always_use_device" msgid="1450287437017315906">"Use by default for this USB device"</string>
+    <string name="always_use_accessory" msgid="1210954576979621596">"Use by default for this USB accessory"</string>
+    <string name="usb_debugging_title" msgid="4513918393387141949">"Allow USB debugging?"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"The computer\'s RSA key fingerprint is:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_always" msgid="303335496705863070">"Always allow from this computer"</string>
+    <string name="compat_mode_on" msgid="6623839244840638213">"Zoom to fill screen"</string>
+    <string name="compat_mode_off" msgid="4434467572461327898">"Stretch to fill screen"</string>
+    <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Saving screenshot…"</string>
+    <string name="screenshot_saving_title" msgid="8242282144535555697">"Saving screenshot…"</string>
+    <string name="screenshot_saving_text" msgid="2419718443411738818">"Screenshot is being saved."</string>
+    <string name="screenshot_saved_title" msgid="6461865960961414961">"Screenshot captured."</string>
+    <string name="screenshot_saved_text" msgid="1152839647677558815">"Touch to view your screenshot."</string>
+    <string name="screenshot_failed_title" msgid="705781116746922771">"Couldn\'t capture screenshot."</string>
+    <string name="screenshot_failed_text" msgid="8134011269572415402">"Couldn\'t save screenshot. Storage may be in use."</string>
+    <string name="usb_preference_title" msgid="6551050377388882787">"USB file transfer options"</string>
+    <string name="use_mtp_button_title" msgid="4333504413563023626">"Mount as a media player (MTP)"</string>
+    <string name="use_ptp_button_title" msgid="7517127540301625751">"Mount as a camera (PTP)"</string>
+    <string name="installer_cd_button_title" msgid="2312667578562201583">"Install Android File Transfer application for Mac"</string>
+    <string name="accessibility_back" msgid="567011538994429120">"Back"</string>
+    <string name="accessibility_home" msgid="8217216074895377641">"Home"</string>
+    <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
+    <string name="accessibility_recent" msgid="8571350598987952883">"Recent apps"</string>
+    <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Switch input method button."</string>
+    <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Compatibility zoom button."</string>
+    <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom smaller to larger screen."</string>
+    <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth connected."</string>
+    <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth disconnected."</string>
+    <string name="accessibility_no_battery" msgid="358343022352820946">"No battery."</string>
+    <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Battery one bar."</string>
+    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Battery two bars."</string>
+    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Battery three bars."</string>
+    <string name="accessibility_battery_full" msgid="8909122401720158582">"Battery full."</string>
+    <string name="accessibility_no_phone" msgid="4894708937052611281">"No phone."</string>
+    <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Phone one bar."</string>
+    <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Phone two bars."</string>
+    <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"Phone three bars."</string>
+    <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"Phone signal full."</string>
+    <string name="accessibility_no_data" msgid="4791966295096867555">"No data."</string>
+    <string name="accessibility_data_one_bar" msgid="1415625833238273628">"Data one bar."</string>
+    <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Data two bars."</string>
+    <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Data three bars."</string>
+    <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Data signal full."</string>
+    <string name="accessibility_wifi_off" msgid="3177380296697933627">"Wi-Fi off."</string>
+    <string name="accessibility_no_wifi" msgid="1425476551827924474">"Wi-Fi disconnected."</string>
+    <string name="accessibility_wifi_one_bar" msgid="7735893178010724377">"Wi-Fi one bar."</string>
+    <string name="accessibility_wifi_two_bars" msgid="4994274250497262434">"Wi-Fi two bars."</string>
+    <string name="accessibility_wifi_three_bars" msgid="3495755044276588384">"Wi-Fi three bars."</string>
+    <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"Wi-Fi signal full."</string>
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"No WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX one bar."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX two bars."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX three bars."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX signal full."</string>
+    <string name="accessibility_no_signal" msgid="7064645320782585167">"No signal."</string>
+    <string name="accessibility_not_connected" msgid="6395326276213402883">"Not connected."</string>
+    <string name="accessibility_zero_bars" msgid="3806060224467027887">"Zero bars."</string>
+    <string name="accessibility_one_bar" msgid="1685730113192081895">"One bar."</string>
+    <string name="accessibility_two_bars" msgid="6437363648385206679">"Two bars."</string>
+    <string name="accessibility_three_bars" msgid="2648241415119396648">"Three bars."</string>
+    <string name="accessibility_signal_full" msgid="9122922886519676839">"Signal full."</string>
+    <string name="accessibility_desc_on" msgid="2385254693624345265">"On."</string>
+    <string name="accessibility_desc_off" msgid="6475508157786853157">"Off."</string>
+    <string name="accessibility_desc_connected" msgid="8366256693719499665">"Connected."</string>
+    <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+    <string name="accessibility_data_connection_1x" msgid="994133468120244018">"1 X"</string>
+    <string name="accessibility_data_connection_hspa" msgid="2032328855462645198">"HSPA"</string>
+    <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+    <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+    <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+    <string name="accessibility_data_connection_lte" msgid="5413468808637540658">"LTE"</string>
+    <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_no_sim" msgid="8274017118472455155">"No SIM."</string>
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth tethering"</string>
+    <string name="accessibility_airplane_mode" msgid="834748999790763092">"Aeroplane mode"</string>
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"Battery <xliff:g id="NUMBER">%d</xliff:g> per cent."</string>
+    <string name="accessibility_settings_button" msgid="799583911231893380">"System settings"</string>
+    <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifications."</string>
+    <string name="accessibility_remove_notification" msgid="3603099514902182350">"Clear notification."</string>
+    <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS enabled."</string>
+    <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS acquiring."</string>
+    <string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter enabled."</string>
+    <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Ringer vibrate."</string>
+    <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Ringer silent."</string>
+    <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> dismissed."</string>
+    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notification dismissed."</string>
+    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Notification shade."</string>
+    <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Quick settings."</string>
+    <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Recent apps"</string>
+    <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"User <xliff:g id="USER">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobile <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">"Battery <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Aeroplane Mode <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarm set for <xliff:g id="TIME">%s</xliff:g>."</string>
+    <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G data disabled"</string>
+    <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G data disabled"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobile data disabled"</string>
+    <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Data disabled"</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"You\'ve reached the specified data usage limit.\n\nIf you re-enable data, you may be charged by the operator."</string>
+    <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Reenable data"</string>
+    <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"No Internet connection"</string>
+    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi connected"</string>
+    <string name="gps_notification_searching_text" msgid="8574247005642736060">"Searching for GPS"</string>
+    <string name="gps_notification_found_text" msgid="4619274244146446464">"Location set by GPS"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Location requests active"</string>
+    <string name="accessibility_clear_all" msgid="5235938559247164925">"Clear all notifications."</string>
+    <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"App info"</string>
+    <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Screen will rotate automatically."</string>
+    <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Screen is locked in landscape orientation."</string>
+    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Screen is locked in portrait orientation."</string>
+    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="start_dreams" msgid="7219575858348719790">"Daydream"</string>
+    <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Aeroplane mode"</string>
+    <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"Charging, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"Charged"</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> Devices)"</string>
+    <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Bluetooth Off"</string>
+    <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Brightness"</string>
+    <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Auto Rotate"</string>
+    <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Rotation Locked"</string>
+    <string name="quick_settings_ime_label" msgid="7073463064369468429">"Input Method"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Location"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Location Off"</string>
+    <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Media device"</string>
+    <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Emergency Calls Only"</string>
+    <string name="quick_settings_settings_label" msgid="5326556592578065401">"Settings"</string>
+    <string name="quick_settings_time_label" msgid="4635969182239736408">"Time"</string>
+    <string name="quick_settings_user_label" msgid="5238995632130897840">"Me"</string>
+    <string name="quick_settings_wifi_label" msgid="9135344704899546041">"Wi-Fi"</string>
+    <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Not Connected"</string>
+    <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"No Network"</string>
+    <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi Off"</string>
+    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Wi-Fi Display"</string>
+    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Wireless Display"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brightness"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Network may be monitored"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 7306469..1aed7dc 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"IU del sistema"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Eliminar"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"No molestar"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Mostrar notificaciones"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Eliminar de la lista"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Información de la aplicación"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Ninguna aplicación reciente"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Conecta el cargador."</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Hay poca batería."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"Quedan <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"No admite la carga USB."\n"Usa sólo el cargador provisto."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"No admite la carga USB.\nUsa sólo el cargador provisto."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Uso de la 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>
@@ -59,12 +57,10 @@
     <string name="always_use_device" msgid="1450287437017315906">"Se usa de forma predeterminada para este dispositivo USB."</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Se usa de forma predeterminada para este accesorio USB."</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"¿Permitir depuración por USB?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"La huella digital de tu clave RSA es:"\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"La huella digital de tu clave RSA es:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Permitir siempre desde esta computadora"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom para ocupar la pantalla"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Estirar p/ ocupar la pantalla"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Zoom de compatibilidad"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Cuando una aplicación fue diseñada para una pantalla más pequeña, aparece un control de zoom junto al reloj."</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Guardando captura de pantalla"</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"Guardando la captura de pantalla..."</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"La captura de pantalla se está guardando."</string>
@@ -162,17 +158,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Datos de 4G inhabilitados"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Se inhabilitaron los datos móviles"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Datos inhabilitados"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Alcanzaste el límite de uso de datos especificado."\n\n"Puede que tu operador te cobre por volver a activar datos."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Alcanzaste el límite de uso de datos especificado.\n\nPuede que tu operador te cobre por volver a activar datos."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Volver a activar datos"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Sin conexión a Internet"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi conectado"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Buscando GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"La ubicación se estableció por GPS"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Solicitudes de ubicación activas"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Eliminar todas las notificaciones"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Información de la aplicación"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Cerrar"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Notificaciones desactivadas"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Toca aquí para volver a activar las notificaciones."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"La pantalla girará automáticamente."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"La pantalla está bloqueada en modo horizontal."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"La pantalla está bloqueada en modo vertical."</string>
@@ -189,7 +183,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Girar automáticamente"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Rotación bloqueada"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Método de introducción"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Ubicación en uso"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Ubicación"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Ubicació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">"Solo emergencia"</string>
@@ -204,6 +199,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Pantalla inalámbrica"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brillo"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMÁTICO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Las notificaciones aparecen aquí."</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Desliza el dedo hacia abajo para acceder al contenido."\n"Vuelve a deslizar el dedo hacia abajo para acceder a los controles del sistema."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Es posible que la red esté supervisada."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 6e5be0a..5386842 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"IU sistema"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Borrar"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"No molestar"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Mostrar notificaciones"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Eliminar de la lista"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Información de la aplicación"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"No hay aplicaciones recientes."</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Conecta el cargador"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Se está agotando la batería."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> restante"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"No se admite la carga por USB."\n"Utiliza solo el cargador proporcionado."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"No se admite la carga por USB.\nUtiliza solo el cargador proporcionado."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Uso de la 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>
@@ -59,12 +57,10 @@
     <string name="always_use_device" msgid="1450287437017315906">"Usar de forma predeterminada para este dispositivo USB"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Usar de forma predeterminada para este accesorio USB"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"¿Permitir depuración USB?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"La huella digital de tu clave RSA es:"\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"La huella digital de tu clave RSA es:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Permitir siempre desde este ordenador"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom para ajustar"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Expandir para ajustar"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Zoom de compatibilidad"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Si la aplicación se ha diseñado para una pantalla más pequeña, aparecerá un control de zoom junto al reloj."</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Guardando captura..."</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"Guardando captura..."</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"La captura de pantalla se está guardando."</string>
@@ -160,17 +156,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Datos 4G inhabilitados"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Datos móviles inhabilitados"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Datos inhabilitados"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Has alcanzado el límite de uso de datos especificado."\n\n"Si vuelves a habilitar los datos, es posible que tu operador te cobre una tarifa adicional."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Has alcanzado el límite de uso de datos especificado.\n\nSi vuelves a habilitar los datos, es posible que tu operador te cobre una tarifa adicional."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Volver a habilitar los datos"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Sin conexión a Internet"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Con conexión Wi-Fi"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Buscando GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Ubicación definida por GPS"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Solicitudes de ubicación activas"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Borrar todas las notificaciones"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Información de la aplicación"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Cerrar"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Notificaciones desactivadas"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Toca aquí para volver a activar las notificaciones."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"La pantalla girará automáticamente."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"La pantalla está bloqueada en modo horizontal."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"La pantalla está bloqueada en modo vertical."</string>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Girar automáticamente"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Rotación bloqueada"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Método de entrada"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Ubicación en uso"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Ubicación"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Ubicació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">"Solo llamadas de emergencia"</string>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Pantalla inalámbrica"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brillo"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Las notificaciones aparecen aquí"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Desliza el dedo hacia abajo para acceder al contenido."\n"Vuelve a deslizar el dedo hacia abajo para acceder a los controles del sistema."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Es posible que la red esté supervisada"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-et-rEE-land/strings.xml b/packages/SystemUI/res/values-et-rEE-land/strings.xml
new file mode 100644
index 0000000..77b0ce1
--- /dev/null
+++ b/packages/SystemUI/res/values-et-rEE-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * 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.
+ */
+ -->
+
+<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">"Ekraan on nüüd lukustatud horisontaalasendisse."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml
new file mode 100644
index 0000000..335feaa
--- /dev/null
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -0,0 +1,201 @@
+<?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:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="7164937344850004466">"Süsteemi UI"</string>
+    <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Kustuta"</string>
+    <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Loendist eemaldamine"</string>
+    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Rakenduse teave"</string>
+    <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Uusi rakendusi pole"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Loobu hiljutistest rakendustest"</string>
+  <plurals name="status_bar_accessibility_recent_apps">
+    <item quantity="one" msgid="5854176083865845541">"1 hiljutine rakendus"</item>
+    <item quantity="other" msgid="1040784359794890744">"%d hiljutist rakendust"</item>
+  </plurals>
+    <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Teatisi pole"</string>
+    <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Jätkuv"</string>
+    <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Teadistused"</string>
+    <string name="battery_low_title" msgid="2783104807551211639">"Ühendage laadija"</string>
+    <string name="battery_low_subtitle" msgid="1752040062087829196">"Aku hakkab tühjenema."</string>
+    <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> on alles"</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB laadimist ei toetata.\nKasutage ainult tootja laadija."</string>
+    <string name="battery_low_why" msgid="7279169609518386372">"Akukasutus"</string>
+    <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Seaded"</string>
+    <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"WiFi"</string>
+    <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Lennurežiim"</string>
+    <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"Pööra ekraani automaatselt"</string>
+    <string name="status_bar_settings_mute_label" msgid="554682549917429396">"SUMMUTA"</string>
+    <string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
+    <string name="status_bar_settings_notifications" msgid="397146176280905137">"Teatised"</string>
+    <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth on jagatud"</string>
+    <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Seadista sisestusmeetodeid"</string>
+    <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Füüsiline klaviatuur"</string>
+    <string name="usb_device_permission_prompt" msgid="834698001271562057">"Kas lubate rakendusel <xliff:g id="APPLICATION">%1$s</xliff:g> USB-seadmele juurde pääseda?"</string>
+    <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Kas lubate rakendusel <xliff:g id="APPLICATION">%1$s</xliff:g> USB-seadmele juurde pääseda?"</string>
+    <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Kas avada <xliff:g id="ACTIVITY">%1$s</xliff:g>, kui see USB-seade on ühendatud?"</string>
+    <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Kas avada <xliff:g id="ACTIVITY">%1$s</xliff:g>, kui USB-lisaseade on ühendatud?"</string>
+    <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"Inst. rak. ei tööta selle USB-seadmega. Lisateavet lisaseadme kohta vt siit: <xliff:g id="URL">%1$s</xliff:g>"</string>
+    <string name="title_usb_accessory" msgid="4966265263465181372">"USB-lisaseade"</string>
+    <string name="label_view" msgid="6304565553218192990">"Kuva"</string>
+    <string name="always_use_device" msgid="1450287437017315906">"Kasuta vaikimisi selle USB-seadme jaoks"</string>
+    <string name="always_use_accessory" msgid="1210954576979621596">"Vaikimisi kasuta seda USB-lisaseadet"</string>
+    <string name="usb_debugging_title" msgid="4513918393387141949">"Kas luban USB silumise?"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"Arvuti RSA-võtme sõrmejälg:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_always" msgid="303335496705863070">"Luba alati sellest arvutist"</string>
+    <string name="compat_mode_on" msgid="6623839244840638213">"Suumi ekraani täitmiseks"</string>
+    <string name="compat_mode_off" msgid="4434467572461327898">"Venita ekraani täitmiseks"</string>
+    <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Kuvatõmmise salvestamine ..."</string>
+    <string name="screenshot_saving_title" msgid="8242282144535555697">"Kuvatõmmise salvestamine ..."</string>
+    <string name="screenshot_saving_text" msgid="2419718443411738818">"Kuvatõmmist salvestatakse."</string>
+    <string name="screenshot_saved_title" msgid="6461865960961414961">"Ekraanipilt on jäädvustatud."</string>
+    <string name="screenshot_saved_text" msgid="1152839647677558815">"Puudutage kuvatõmmise vaatamiseks."</string>
+    <string name="screenshot_failed_title" msgid="705781116746922771">"Kuvatõmmist ei saanud jäädvustada."</string>
+    <string name="screenshot_failed_text" msgid="8134011269572415402">"Kuvatõmmist ei saa salvestada. Mäluseade võib olla kasutuses."</string>
+    <string name="usb_preference_title" msgid="6551050377388882787">"USB-failiedastuse valikud"</string>
+    <string name="use_mtp_button_title" msgid="4333504413563023626">"Paigalda meediumimängijana (MTP)"</string>
+    <string name="use_ptp_button_title" msgid="7517127540301625751">"Paigalda kaamerana (PTP)"</string>
+    <string name="installer_cd_button_title" msgid="2312667578562201583">"Android File Transferi installimine Macile"</string>
+    <string name="accessibility_back" msgid="567011538994429120">"Tagasi"</string>
+    <string name="accessibility_home" msgid="8217216074895377641">"Kodu"</string>
+    <string name="accessibility_menu" msgid="316839303324695949">"Menüü"</string>
+    <string name="accessibility_recent" msgid="8571350598987952883">"Hiljutised rakendused"</string>
+    <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Sisestusmeetodi vahetamise nupp."</string>
+    <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Sobivussuumi nupp."</string>
+    <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Suumi suuremale ekraanile vähem."</string>
+    <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth on ühendatud."</string>
+    <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetoothi ühendus katkestatud."</string>
+    <string name="accessibility_no_battery" msgid="358343022352820946">"Aku puudub."</string>
+    <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Aku: üks pulk."</string>
+    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Aku: kaks pulka."</string>
+    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Aku: kolm pulka."</string>
+    <string name="accessibility_battery_full" msgid="8909122401720158582">"Aku täis."</string>
+    <string name="accessibility_no_phone" msgid="4894708937052611281">"Telefonisignaal puudub"</string>
+    <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Telefonisignaal: üks pulk."</string>
+    <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Telefonisignaal: kaks pulka."</string>
+    <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"Telefonisignaal: kolm pulka."</string>
+    <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"Telefonisignaal on tugev."</string>
+    <string name="accessibility_no_data" msgid="4791966295096867555">"Andmed puuduvad."</string>
+    <string name="accessibility_data_one_bar" msgid="1415625833238273628">"Andmesignaal: üks pulk."</string>
+    <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Andmeside: kaks pulka."</string>
+    <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Andmeside: kolm pulka."</string>
+    <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Andmesignaal on tugev."</string>
+    <string name="accessibility_wifi_off" msgid="3177380296697933627">"Wifi on väljas."</string>
+    <string name="accessibility_no_wifi" msgid="1425476551827924474">"Wifi-ühendus on katkestatud."</string>
+    <string name="accessibility_wifi_one_bar" msgid="7735893178010724377">"WiFi: üks pulk."</string>
+    <string name="accessibility_wifi_two_bars" msgid="4994274250497262434">"WiFi: kaks pulka."</string>
+    <string name="accessibility_wifi_three_bars" msgid="3495755044276588384">"WiFi: kolm pulka."</string>
+    <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"WiFi-signaal on tugev."</string>
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"WiMAX-i pole."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX-i on üks riba."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX-i on kaks riba."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX-i on kolm riba."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX-i signaal on tugev."</string>
+    <string name="accessibility_no_signal" msgid="7064645320782585167">"Signaal puudub."</string>
+    <string name="accessibility_not_connected" msgid="6395326276213402883">"Ühendus puudub."</string>
+    <string name="accessibility_zero_bars" msgid="3806060224467027887">"Null pulka."</string>
+    <string name="accessibility_one_bar" msgid="1685730113192081895">"Üks pulk."</string>
+    <string name="accessibility_two_bars" msgid="6437363648385206679">"Kaks pulka."</string>
+    <string name="accessibility_three_bars" msgid="2648241415119396648">"Kolm pulka."</string>
+    <string name="accessibility_signal_full" msgid="9122922886519676839">"Signaal on tugev."</string>
+    <string name="accessibility_desc_on" msgid="2385254693624345265">"Sees."</string>
+    <string name="accessibility_desc_off" msgid="6475508157786853157">"Väljas."</string>
+    <string name="accessibility_desc_connected" msgid="8366256693719499665">"Ühendatud."</string>
+    <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+    <string name="accessibility_data_connection_1x" msgid="994133468120244018">"1 X"</string>
+    <string name="accessibility_data_connection_hspa" msgid="2032328855462645198">"HSPA"</string>
+    <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+    <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3,5G"</string>
+    <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+    <string name="accessibility_data_connection_lte" msgid="5413468808637540658">"LTE"</string>
+    <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+    <string name="accessibility_data_connection_roaming" msgid="5977362333466556094">"Rändlus"</string>
+    <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Serv"</string>
+    <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"WiFi"</string>
+    <string name="accessibility_no_sim" msgid="8274017118472455155">"SIM-kaarti pole."</string>
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetoothi jagamine."</string>
+    <string name="accessibility_airplane_mode" msgid="834748999790763092">"Lennurežiim."</string>
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"Aku: <xliff:g id="NUMBER">%d</xliff:g> protsenti."</string>
+    <string name="accessibility_settings_button" msgid="799583911231893380">"Süsteemiseaded"</string>
+    <string name="accessibility_notifications_button" msgid="4498000369779421892">"Teatised"</string>
+    <string name="accessibility_remove_notification" msgid="3603099514902182350">"Teatise kustutamine"</string>
+    <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS on lubatud."</string>
+    <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS-signaali otsimine."</string>
+    <string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter lubatud."</string>
+    <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Vibreeriv kõlisti."</string>
+    <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Vaikne kõlisti."</string>
+    <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Loobusite rakendusest <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Märguandest on loobutud."</string>
+    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Märguande vari."</string>
+    <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Kiirseaded."</string>
+    <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Hiljutised rakendused"</string>
+    <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Kasutaja <xliff:g id="USER">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobiili <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">"Aku: <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Lennukirežiim: <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth: <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Määratud äratus: <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G–3G andmeside keelatud"</string>
+    <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G andmeside keelatud"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobiilne andmeside keelatud"</string>
+    <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Andmekasutus keelatud."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Olete jõudnud määratud andmekasutuse piirini.\n\nKui lülitate andmeside uuesti sisse, siis võib operaator teilt tasu võtta."</string>
+    <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Luba andmeside uuesti"</string>
+    <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Interneti-ühendus puudub"</string>
+    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"WiFi on ühendatud"</string>
+    <string name="gps_notification_searching_text" msgid="8574247005642736060">"GPS-i otsimine"</string>
+    <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS-i määratud asukoht"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Asukoha taotlused on aktiivsed"</string>
+    <string name="accessibility_clear_all" msgid="5235938559247164925">"Kustuta kõik teatised."</string>
+    <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Rakenduse teave"</string>
+    <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekraani pööramine toimub automaatselt."</string>
+    <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Ekraan on lukustatud horisontaalsuunas."</string>
+    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Ekraan on lukustatud vertikaalsuunas."</string>
+    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="start_dreams" msgid="7219575858348719790">"Unistus"</string>
+    <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Lennurežiim"</string>
+    <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"Laadimine, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"Laetud"</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>
+    <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Bluetooth on väljas"</string>
+    <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Heledus"</string>
+    <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Automaatne pööramine"</string>
+    <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Pööramine lukus"</string>
+    <string name="quick_settings_ime_label" msgid="7073463064369468429">"Sisestusmeetod"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Asukoht"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Asukoht on väljas"</string>
+    <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Meediaseade"</string>
+    <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Ainult hädaabikõned"</string>
+    <string name="quick_settings_settings_label" msgid="5326556592578065401">"Seaded"</string>
+    <string name="quick_settings_time_label" msgid="4635969182239736408">"Aeg"</string>
+    <string name="quick_settings_user_label" msgid="5238995632130897840">"Mina"</string>
+    <string name="quick_settings_wifi_label" msgid="9135344704899546041">"WiFi"</string>
+    <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Ühendus puudub"</string>
+    <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Võrku pole"</string>
+    <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"WiFi-ühendus on väljas"</string>
+    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"WiFi-ekraan"</string>
+    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Juhtmeta ekraaniühendus"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Heledus"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMAATNE"</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Võrku võidakse jälgida"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 5737645..28ece65 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"Süsteemi UI"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Kustuta"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Mitte häirida"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Kuva teatised"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Loendist eemaldamine"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Rakenduse teave"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Uusi rakendusi pole"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Ühendage laadija"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Aku hakkab tühjenema."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> on alles"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"USB laadimist ei toetata."\n"Kasutage ainult tootja laadija."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB laadimist ei toetata.\nKasutage ainult tootja laadija."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Akukasutus"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Seaded"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"WiFi"</string>
@@ -59,7 +57,7 @@
     <string name="always_use_device" msgid="1450287437017315906">"Kasuta vaikimisi selle USB-seadme jaoks"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Vaikimisi kasuta seda USB-lisaseadet"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"Kas luban USB silumise?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"Arvuti RSA-võtme sõrmejälg:"\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"Arvuti RSA-võtme sõrmejälg:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Luba alati sellest arvutist"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Suumi ekraani täitmiseks"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Venita ekraani täitmiseks"</string>
@@ -160,17 +158,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G andmeside keelatud"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobiilne andmeside keelatud"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Andmekasutus keelatud."</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Olete jõudnud määratud andmekasutuse piirini."\n\n"Kui lülitate andmeside uuesti sisse, siis võib operaator teilt tasu võtta."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Olete jõudnud määratud andmekasutuse piirini.\n\nKui lülitate andmeside uuesti sisse, siis võib operaator teilt tasu võtta."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Luba andmeside uuesti"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Interneti-ühendus puudub"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"WiFi on ühendatud"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"GPS-i otsimine"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS-i määratud asukoht"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Asukoha taotlused on aktiivsed"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Kustuta kõik teatised."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Rakenduse teave"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Sule"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Teatised väljas"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Teatiste uuesti sisselülitamiseks puudutage siin."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekraani pööramine toimub automaatselt."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Ekraan on lukustatud horisontaalsuunas."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Ekraan on lukustatud vertikaalsuunas."</string>
@@ -187,7 +183,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Automaatne pööramine"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Pööramine lukus"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Sisestusmeetod"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Kasutatav asukoht"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Asukoht"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Asukoht on väljas"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Meediaseade"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Ainult hädaabikõned"</string>
@@ -203,5 +200,5 @@
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Heledus"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMAATNE"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Märguanded ilmuvad siia"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Juurdepääs igal ajal sõrmega alla pühkides."\n"Süsteemi juhtnuppude jaoks pühkige uuesti alla."</string>
+    <string name="status_bar_help_text" msgid="7874607155052076323">"Juurdepääs igal ajal sõrmega alla pühkides.\nSüsteemi juhtnuppude jaoks pühkige uuesti alla."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index b15afcc..489b654 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -21,8 +21,6 @@
     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_do_not_disturb_button" msgid="5812628897510997853">"مزاحم نشوید"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"نمایش اعلان‌ها"</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="6576392951053994640">"برنامه جدیدی موجود نیست"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"شارژر را متصل کنید"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"باتری در حال کم شدن است."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> باقیمانده است"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"شارژ USB پشتیبانی نمی‌شود."\n"فقط از شارژر ارائه شده استفاده کنید."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"شارژ USB پشتیبانی نمی‌شود.\nفقط از شارژر ارائه شده استفاده کنید."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"استفاده از باتری"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"تنظیمات"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <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="compat_mode_on" msgid="6623839244840638213">"بزرگنمایی برای پر کردن صفحه"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"گسترده کردن برای پر کردن صفحه"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"بزرگنمایی سازگاری"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"اگر یک برنامه برای صفحه کوچک تری طراحی شده باشد، یک کنترل بزرگنمایی توسط ساعت نشان داده می‌شود."</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>
@@ -160,17 +156,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"داده 4G غیر فعال شد"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"داده‌های تلفن همراه غیرفعال است"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"داده غیرفعال شد"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"به حداکثر محدوده مشخص شده برای استفاده از داده رسیده‌اید."\n\n"در صورت فعال کردن مجدد داده، ممکن است از طرف اپراتور برای شما هزینه محاسبه شود."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"به حداکثر محدوده مشخص شده برای استفاده از داده رسیده‌اید.\n\nدر صورت فعال کردن مجدد داده، ممکن است از طرف اپراتور برای شما هزینه محاسبه شود."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"فعال کردن مجدد داده"</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="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="accessibility_clear_all" msgid="5235938559247164925">"پاک کردن تمام اعلان‌ها"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"اطلاعات برنامه"</string>
-    <string name="close_universe" msgid="3736513750241754348">"بستن"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"اعلان‌ها خاموش"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"برای روشن کردن مجدد اعلان‌ها، اینجا را ضربه بزنید."</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>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"چرخش خودکار"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"چرخش قفل شد"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"روش ورودی"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"موقعیت مکانی در حال استفاده"</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>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"نمایش بدون سیم"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"روشنایی"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"خودکار"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"اعلان‌ها در اینجا نمایش داده می‌شوند"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"با کشیدن انگشت به طرف پایین به آنها دسترسی پیدا کنید."\n"برای کنترل‌های سیستم دوباره انگشت خود را به سمت پایین بکشید."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"ممکن است شبکه نظارت شده باشد"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index c5e0e21..852ec08 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"Käyttöliitt."</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Tyhjennä"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Varattu"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Näytä ilmoitukset"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Poista luettelosta"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Sovelluksen tiedot"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Ei viimeisimpiä sovelluksia"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Kytke laturi"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Akun virta on vähissä."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> jäljellä"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"USB-latausta ei tueta."\n"Käytä laitteen mukana tullutta laturia."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB-latausta ei tueta.\nKäytä laitteen mukana tullutta laturia."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Akun käyttö"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Asetukset"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wifi"</string>
@@ -59,12 +57,10 @@
     <string name="always_use_device" msgid="1450287437017315906">"Käytä oletuksena tällä USB-laitteella"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Käytä oletuksena tällä USB-lisälaitteella"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"Sallitaanko USB-vianetsintä?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"Tietokoneen RSA-avaintunnistetiedosto on:"\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"Tietokoneen RSA-avaintunnistetiedosto on:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Salli aina tällä tietokoneella"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoomaa koko näyttöön"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Venytä koko näyttöön"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Yhteensopivuuszoomaus"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Jos sovellus on suunniteltu pienemmälle näytölle, kellon viereen tulee näkyviin zoomaussäädin."</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Tallennetaan kuvakaappausta..."</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"Tallennetaan kuvakaappausta..."</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"Kuvakaappausta tallennetaan."</string>
@@ -160,17 +156,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G-tiedonsiirto pois käytöstä"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobiilitiedonsiirto pois käytöstä"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Tiedonsiirto pois käytöstä"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Tiedonsiirtoraja saavutettu."\n\n"Jos otat tiedonsiirron uudelleen käyttöön, operaattorisi voi veloittaa sinua."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Tiedonsiirtoraja saavutettu.\n\nJos otat tiedonsiirron uudelleen käyttöön, operaattorisi voi veloittaa sinua."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Ota tiedonsiirto käyttöön"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Ei internetyhteyttä"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wifi yhdistetty"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Haetaan GPS-yhteyttä"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Sijainti määritetty GPS:n avulla"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Sijaintipyynnöt aktiiviset"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Tyhjennä kaikki ilmoitukset."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Sovelluksen tiedot"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Sulje"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Ilmoitukset pois käytöstä"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Ota ilmoitukset uudelleen käyttöön napauttamalla tätä."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ruutu kääntyy automaattisesti."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Ruutu on lukittu vaakasuuntaan."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Ruutu on lukittu pystysuuntaan."</string>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Automaattinen kääntö"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Kääntö lukittu"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Syöttötapa"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Sijainti käytössä"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Sijainti"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Sijainti ei käytössä"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Medialaite"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Vain hätäpuhelut"</string>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Langaton näyttö"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Kirkkaus"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Ilmoitukset näkyvät tässä"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Näet ilmoitukset liu\'uttamalla sormea alas ruudulla."\n"Voit palauttaa järjestelmän ohjaimet näkyviin liu\'uttamalla sormea alas uudelleen."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Verkkoa saatetaan valvoa"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA-land/strings.xml b/packages/SystemUI/res/values-fr-rCA-land/strings.xml
new file mode 100644
index 0000000..4775fc6
--- /dev/null
+++ b/packages/SystemUI/res/values-fr-rCA-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * 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.
+ */
+ -->
+
+<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">"L\'écran est désormais verrouillé au format paysage."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..48f62d3
--- /dev/null
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -0,0 +1,203 @@
+<?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:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="7164937344850004466">"IU système"</string>
+    <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Effacer"</string>
+    <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Supprimer de la liste"</string>
+    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Informations sur l\'application"</string>
+    <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Aucune application récente"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Masquer les applications récentes"</string>
+  <plurals name="status_bar_accessibility_recent_apps">
+    <item quantity="one" msgid="5854176083865845541">"1 application récente"</item>
+    <item quantity="other" msgid="1040784359794890744">"%d applications récentes"</item>
+  </plurals>
+    <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Aucune notification"</string>
+    <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"En cours"</string>
+    <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notifications"</string>
+    <string name="battery_low_title" msgid="2783104807551211639">"Brancher le chargeur"</string>
+    <string name="battery_low_subtitle" msgid="1752040062087829196">"Le niveau de la batterie est faible."</string>
+    <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> restant(s)"</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"Chargement USB non compatible.\nVous devez utiliser le chargeur fourni."</string>
+    <string name="battery_low_why" msgid="7279169609518386372">"Utilisation de la batterie"</string>
+    <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Paramètres"</string>
+    <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
+    <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Mode Avion"</string>
+    <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"Rotation auto de l\'écran"</string>
+    <string name="status_bar_settings_mute_label" msgid="554682549917429396">"MUET"</string>
+    <string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTOMATIQUE"</string>
+    <string name="status_bar_settings_notifications" msgid="397146176280905137">"Notifications"</string>
+    <string name="bluetooth_tethered" msgid="7094101612161133267">"Connexion Bluetooth partagée"</string>
+    <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configurer les modes de saisie"</string>
+    <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Clavier physique"</string>
+    <string name="usb_device_permission_prompt" msgid="834698001271562057">"Autoriser l\'application <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder au périphérique USB?"</string>
+    <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Autoriser l\'application <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder à l\'accessoire USB?"</string>
+    <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Ouvrir <xliff:g id="ACTIVITY">%1$s</xliff:g> lors de la connexion de ce périphérique USB?"</string>
+    <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Ouvrir <xliff:g id="ACTIVITY">%1$s</xliff:g> lors de la connexion de cet accessoire USB?"</string>
+    <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"Aucune application installée compatible avec accessoire USB. En savoir plus sur <xliff:g id="URL">%1$s</xliff:g>"</string>
+    <string name="title_usb_accessory" msgid="4966265263465181372">"Accessoire USB"</string>
+    <string name="label_view" msgid="6304565553218192990">"Afficher"</string>
+    <string name="always_use_device" msgid="1450287437017315906">"Utiliser par défaut pour ce périphérique USB"</string>
+    <string name="always_use_accessory" msgid="1210954576979621596">"Utiliser par défaut pour cet accessoire USB"</string>
+    <string name="usb_debugging_title" msgid="4513918393387141949">"Autoriser le débogage USB?"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"Empreinte numérique de la clé RSA de l\'ordinateur : \n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_always" msgid="303335496705863070">"Toujours autoriser sur cet ordinateur"</string>
+    <string name="compat_mode_on" msgid="6623839244840638213">"Zoomer pour remplir l\'écran"</string>
+    <string name="compat_mode_off" msgid="4434467572461327898">"Étirer pour remplir l\'écran"</string>
+    <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Enregistrement capture écran…"</string>
+    <string name="screenshot_saving_title" msgid="8242282144535555697">"Enregistrement capture écran…"</string>
+    <string name="screenshot_saving_text" msgid="2419718443411738818">"Enregistrement de la capture d\'écran en cours…"</string>
+    <string name="screenshot_saved_title" msgid="6461865960961414961">"Capture d\'écran réussie"</string>
+    <string name="screenshot_saved_text" msgid="1152839647677558815">"Appuyez pour afficher votre capture d\'écran."</string>
+    <string name="screenshot_failed_title" msgid="705781116746922771">"Impossible de réaliser une capture d\'écran"</string>
+    <string name="screenshot_failed_text" msgid="8134011269572415402">"Impossible enregistrer capture d\'écran. Périphérique de stockage peut-être en cours d\'utilisation."</string>
+    <string name="usb_preference_title" msgid="6551050377388882787">"Options transfert fichiers USB"</string>
+    <string name="use_mtp_button_title" msgid="4333504413563023626">"Installer comme un lecteur multimédia (MTP)"</string>
+    <string name="use_ptp_button_title" msgid="7517127540301625751">"Installer comme un appareil photo (PTP)"</string>
+    <string name="installer_cd_button_title" msgid="2312667578562201583">"Installer application Android File Transfer (Mac)"</string>
+    <string name="accessibility_back" msgid="567011538994429120">"Précédent"</string>
+    <string name="accessibility_home" msgid="8217216074895377641">"Domicile"</string>
+    <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
+    <string name="accessibility_recent" msgid="8571350598987952883">"Applications récentes"</string>
+    <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Bouton \"Changer le mode de saisie\""</string>
+    <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Bouton \"Zoom de compatibilité\""</string>
+    <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom de compatibilité avec la taille de l\'écran"</string>
+    <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth connecté"</string>
+    <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth déconnecté"</string>
+    <string name="accessibility_no_battery" msgid="358343022352820946">"Batterie vide"</string>
+    <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Niveau de batterie : faible"</string>
+    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Niveau de batterie : moyen"</string>
+    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Niveau de batterie : bon"</string>
+    <string name="accessibility_battery_full" msgid="8909122401720158582">"Batterie pleine"</string>
+    <string name="accessibility_no_phone" msgid="4894708937052611281">"Aucun signal"</string>
+    <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Signal : faible"</string>
+    <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Signal : moyen"</string>
+    <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"Signal : bon"</string>
+    <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"Signal excellent"</string>
+    <string name="accessibility_no_data" msgid="4791966295096867555">"Aucun signal"</string>
+    <string name="accessibility_data_one_bar" msgid="1415625833238273628">"Signal faible"</string>
+    <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Signal moyen"</string>
+    <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Signal bon"</string>
+    <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Signal excellent"</string>
+    <string name="accessibility_wifi_off" msgid="3177380296697933627">"Wi-Fi désactivé"</string>
+    <string name="accessibility_no_wifi" msgid="1425476551827924474">"Wi-Fi déconnecté"</string>
+    <string name="accessibility_wifi_one_bar" msgid="7735893178010724377">"Signal Wi-Fi faible"</string>
+    <string name="accessibility_wifi_two_bars" msgid="4994274250497262434">"Signal Wi-Fi moyen"</string>
+    <string name="accessibility_wifi_three_bars" msgid="3495755044276588384">"Signal Wi-Fi bon"</string>
+    <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"Signal Wi-Fi excellent"</string>
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Aucun signal WiMAX"</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"Signal WiMAX : faible"</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"Signal WiMAX : moyen"</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"Signal WiMAX : bon"</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"Signal WiMAX : excellent"</string>
+    <string name="accessibility_no_signal" msgid="7064645320782585167">"Aucun signal"</string>
+    <string name="accessibility_not_connected" msgid="6395326276213402883">"Non connecté"</string>
+    <string name="accessibility_zero_bars" msgid="3806060224467027887">"Aucun signal"</string>
+    <string name="accessibility_one_bar" msgid="1685730113192081895">"Signal faible"</string>
+    <string name="accessibility_two_bars" msgid="6437363648385206679">"Moyen"</string>
+    <string name="accessibility_three_bars" msgid="2648241415119396648">"Bon"</string>
+    <string name="accessibility_signal_full" msgid="9122922886519676839">"Signal excellent"</string>
+    <string name="accessibility_desc_on" msgid="2385254693624345265">"Activé"</string>
+    <string name="accessibility_desc_off" msgid="6475508157786853157">"Désactivé"</string>
+    <string name="accessibility_desc_connected" msgid="8366256693719499665">"Connecté"</string>
+    <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+    <string name="accessibility_data_connection_1x" msgid="994133468120244018">"1x"</string>
+    <string name="accessibility_data_connection_hspa" msgid="2032328855462645198">"3G+"</string>
+    <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+    <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3G+"</string>
+    <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+    <string name="accessibility_data_connection_lte" msgid="5413468808637540658">"LTE"</string>
+    <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+    <string name="accessibility_data_connection_roaming" msgid="5977362333466556094">"Itinérance"</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">"Aucune carte SIM"</string>
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Partage de connexion Bluetooth"</string>
+    <string name="accessibility_airplane_mode" msgid="834748999790763092">"Mode Avion"</string>
+    <!-- String.format failed for translation -->
+    <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
+    <skip />
+    <string name="accessibility_settings_button" msgid="799583911231893380">"Paramètres système"</string>
+    <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifications"</string>
+    <string name="accessibility_remove_notification" msgid="3603099514902182350">"Supprimer la notification"</string>
+    <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS activé"</string>
+    <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Acquisition de données GPS"</string>
+    <string name="accessibility_tty_enabled" msgid="4613200365379426561">"Téléscripteur activé"</string>
+    <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Sonnerie en mode vibreur"</string>
+    <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Sonnerie en mode silencieux"</string>
+    <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Application \"<xliff:g id="APP">%s</xliff:g>\" ignorée."</string>
+    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notification masquée"</string>
+    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Volet des notifications"</string>
+    <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Paramètres rapides"</string>
+    <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Applications récentes"</string>
+    <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Utilisateur : <xliff:g id="USER">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>, <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Signal mobile : <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">"Batterie : <xliff:g id="STATE">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Mode Avion : <xliff:g id="STATE">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth : <xliff:g id="STATE">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarme réglée sur <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Données 2G-3G  désactivées"</string>
+    <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Données 4G désactivées"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Données mobiles désactivées"</string>
+    <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Données désactivées"</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Vous avez atteint le plafond de consommation de données spécifié.\n\nSi vous utilisez des données supplémentaires, celles-ci pourront être facturées par l\'opérateur."</string>
+    <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Réactiver connexion données"</string>
+    <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Aucune connexion Internet"</string>
+    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Connecté au Wi-Fi"</string>
+    <string name="gps_notification_searching_text" msgid="8574247005642736060">"Recherche de GPS..."</string>
+    <string name="gps_notification_found_text" msgid="4619274244146446464">"Position définie par GPS"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Demandes de localisation actives"</string>
+    <string name="accessibility_clear_all" msgid="5235938559247164925">"Supprimer toutes les notifications"</string>
+    <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informations sur l\'application"</string>
+    <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"L\'écran pivote automatiquement."</string>
+    <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"L\'écran est verrouillé en mode paysage."</string>
+    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"L\'écran est verrouillé en mode portrait."</string>
+    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="start_dreams" msgid="7219575858348719790">"Écran de veille"</string>
+    <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Mode Avion"</string>
+    <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"En charge (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
+    <string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"Chargée"</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>
+    <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"BLUETOOTH DÉSACTIVÉ"</string>
+    <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Luminosité"</string>
+    <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Rotation automatique"</string>
+    <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Rotation verrouillée"</string>
+    <string name="quick_settings_ime_label" msgid="7073463064369468429">"Mode de saisie"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Position"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Localisation désactivée"</string>
+    <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Appareil multimédia"</string>
+    <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Appels d\'urgence uniquement"</string>
+    <string name="quick_settings_settings_label" msgid="5326556592578065401">"Paramètres"</string>
+    <string name="quick_settings_time_label" msgid="4635969182239736408">"Heures"</string>
+    <string name="quick_settings_user_label" msgid="5238995632130897840">"Moi"</string>
+    <string name="quick_settings_wifi_label" msgid="9135344704899546041">"Wi-Fi"</string>
+    <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Non connecté"</string>
+    <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Aucun réseau"</string>
+    <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi désactivé"</string>
+    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Affichage Wi-Fi"</string>
+    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Affichage sans fil"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Luminosité"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATIQUE"</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Le réseau peut être surveillé"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 616adf5..2af370b 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"IU système"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Effacer"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Ne pas déranger"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Afficher les notifications"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Supprimer de la liste"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Informations sur l\'application"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Aucune application récente."</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Brancher le chargeur"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Le niveau de la batterie est faible."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> restant(s)"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"Chargement USB non disponible."\n"Vous devez utiliser le chargeur fourni."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"Chargement USB non disponible.\nVous devez utiliser le chargeur fourni."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Utilisation de la batterie"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Paramètres"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <string name="always_use_device" msgid="1450287437017315906">"Utiliser par défaut pour ce périphérique USB"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Utiliser par défaut pour cet accessoire USB"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"Autoriser le débogage USB ?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"Empreinte numérique de la clé RSA de l\'ordinateur : "\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"Empreinte numérique de la clé RSA de l\'ordinateur : \n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Toujours autoriser sur cet ordinateur"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoomer pour remplir l\'écran"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Étirer pour remplir l\'écran"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Zoom de compatibilité"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Si une application a été conçue pour un écran plus petit, une commande de zoom s\'affiche à côté de l\'horloge."</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Enregistrement capture écran…"</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"Enregistrement de la capture d\'écran…"</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"Enregistrement de la capture d\'écran en cours…"</string>
@@ -162,17 +158,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Données 4G désactivées"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Données mobiles désactivées"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Données désactivées"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Vous avez atteint le plafond de consommation de données spécifié."\n\n"Si vous utilisez des données supplémentaires, celles-ci pourront être facturées par l\'opérateur."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Vous avez atteint le plafond de consommation de données spécifié.\n\nSi vous utilisez des données supplémentaires, celles-ci pourront être facturées par l\'opérateur."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Réactiver connexion données"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Aucune connexion Internet"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Connecté au Wi-Fi"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Recherche de GPS..."</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Position définie par GPS"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Demandes de localisation actives"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Supprimer toutes les notifications"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informations sur l\'application"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Fermer"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Notifications désactivées"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Appuyez ici pour réactiver les notifications."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"L\'écran pivote automatiquement."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"L\'écran est verrouillé en mode paysage."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"L\'écran est verrouillé en mode portrait."</string>
@@ -189,7 +183,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Rotation auto"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Rotation bloquée"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Mode de saisie"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Utilisation des données de localisation"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Localisation"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Localisation désactivée"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Appareil multimédia"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Appels d\'urgence uniquement"</string>
@@ -204,6 +199,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Affichage sans fil"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Luminosité"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATIQUE"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Les notifications s’affichent ici"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Accédez-y à tout moment en faisant glisser le doigt vers le bas."\n"Répétez l\'opération pour accéder aux commandes du système."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Il est possible que le réseau soit surveillé."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 0342e18..5256ff0 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -21,15 +21,13 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"सिस्‍टम UI"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"साफ़ करें"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"परेशान न करें"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"सूचनाएं दिखाएं"</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="6576392951053994640">"कोई हाल ही के एप्लिकेशन नहीं"</string>
-    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"हाल ही के एप्लिकेशन खारिज करें"</string>
+    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"एप्‍स जानकारी"</string>
+    <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"कोई हाल ही के एप्स नहीं"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"हाल ही के एप्स खारिज करें"</string>
   <plurals name="status_bar_accessibility_recent_apps">
-    <item quantity="one" msgid="5854176083865845541">"1 हाल ही का एप्लिकेशन"</item>
-    <item quantity="other" msgid="1040784359794890744">"%d हाल ही के एप्लिकेशन"</item>
+    <item quantity="one" msgid="5854176083865845541">"1 हाल ही का एप्स"</item>
+    <item quantity="other" msgid="1040784359794890744">"%d हाल ही के एप्स"</item>
   </plurals>
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"कोई सूचना नहीं"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"ऑनगोइंग"</string>
@@ -37,34 +35,32 @@
     <string name="battery_low_title" msgid="2783104807551211639">"चार्जर कनेक्‍ट करें"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"बैटरी कम हो रही है."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> शेष"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"USB चार्जिंग समर्थित नहीं है."\n"केवल आपूर्ति किए गए चार्जर का उपयोग करें."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB चार्जिंग समर्थित नहीं है.\nकेवल आपूर्ति किए गए चार्जर का उपयोग करें."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"बैटरी उपयोग"</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_airplane" msgid="4879879698500955300">"हवाई जहाज मोड"</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>
     <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">"जब यह 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="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="compat_mode_on" msgid="6623839244840638213">"स्‍क्रीन भरने हेतु ज़ूम करें"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"स्‍क्रीन को भरने के लिए खींचें"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"संगतता ज़ूम"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"जब किसी छोटी स्‍क्रीन के लिए एप्‍लिकेशन को डिज़ाइन किया जाता है, तो ज़ूम नियंत्रण क्लॉक के पास दिखाई देगा."</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>
@@ -79,7 +75,7 @@
     <string name="accessibility_back" msgid="567011538994429120">"वापस जाएं"</string>
     <string name="accessibility_home" msgid="8217216074895377641">"होम"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"मेनू"</string>
-    <string name="accessibility_recent" msgid="8571350598987952883">"हाल ही के एप्‍लिकेशन"</string>
+    <string name="accessibility_recent" msgid="8571350598987952883">"हाल ही के एप्‍स"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"इनपुट पद्धति‍ बटन स्विच करें."</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"संगतता ज़ूम बटन."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"छोटी से बड़ी स्‍क्रीन पर ज़ूम करें."</string>
@@ -148,7 +144,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_recent_apps" msgid="9014032916410590027">"हाल ही के एप्‍लिकेशन."</string>
+    <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"हाल ही के एप्‍स."</string>
     <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"उपयोगकर्ता <xliff:g id="USER">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</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>
@@ -160,22 +156,20 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G डेटा अक्षम"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"मोबाइल डेटा अक्षम"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"डेटा अक्षम"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"आप निर्दिष्ट डेटा उपयोग सीमा तक पहुंच चुके हैं."\n\n"यदि आप डेटा को पुनः सक्षम करते हैं, तो ऑपरेटर द्वारा आपसे शुल्क लिया जा सकता है."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"आप निर्दिष्ट डेटा उपयोग सीमा तक पहुंच चुके हैं.\n\nयदि आप डेटा को पुनः सक्षम करते हैं, तो ऑपरेटर द्वारा आपसे शुल्क लिया जा सकता है."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"डेटा पुन: सक्षम करें"</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="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="accessibility_clear_all" msgid="5235938559247164925">"सभी सूचनाएं साफ़ करें."</string>
-    <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"एप्‍लिकेशन जानकारी"</string>
-    <string name="close_universe" msgid="3736513750241754348">"बंद करें"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"सूचनाएं बंद"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"सूचनाओं को पुन: चालू करने के लिए यहां टैप करें."</string>
+    <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"एप्‍स जानकारी"</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="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
-    <string name="start_dreams" msgid="7219575858348719790">"Daydream"</string>
+    <string name="start_dreams" msgid="7219575858348719790">"दिवास्वप्न"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"ईथरनेट"</string>
     <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"हवाई जहाज़ मोड"</string>
     <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"चार्ज हो रही है, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"स्वत: रोटेट"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"रोटेशन लॉक किया गया"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"इनपुट विधि"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"उपयोग हो रहा स्थान"</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>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"वायरलेस डिस्प्ले"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"चमक"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"स्वत:"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"सूचनाएं यहां दिखाई देती हैं"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"नीचे स्वाइप करके उन तक कभी भी पहुंचें."\n"सिस्टम नियंत्रणों के लिए पुन: नीचे स्वाइप करें."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"नेटवर्क को मॉनिटर किया जा सकता है"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index c35b237..84d4111 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"UI sustava"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Očisti"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Ne uznemiravaj"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Prikaži obavijesti"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Ukloni s popisa"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Informacije o aplikaciji"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Nema nedavnih aplikacija"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Priključite punjač"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Baterija će uskoro biti potrošena."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> preostalo"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"USB punjenje nije podržano."\n"Upotrijebite samo priloženi punjač."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB punjenje nije podržano.\nUpotrijebite samo priloženi punjač."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Iskorištenost baterije"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Postavke"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <string name="always_use_device" msgid="1450287437017315906">"Koristi se prema zadanim postavkama za ovaj USB uređaj"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Koristi se prema zadanim postavkama za ovaj USB pribor"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"Omogućiti rješavanje programske pogreške na USB-u?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"Otisak prsta RSA ključa računala je: "\n" <xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"Otisak prsta RSA ključa računala je: \n <xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Uvijek dopusti s ovog računala"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zumiraj i ispuni zaslon"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Rastegni i ispuni zaslon"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Kompatibilno zumiranje"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Kada je aplikacija dizajnirana za manji zaslon, kontrole zumiranja prikazuju se pored sata."</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Spremanje snimke zaslona..."</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"Spremanje snimke zaslona..."</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"Spremanje snimke zaslona."</string>
@@ -160,17 +156,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Onemogućeni su 4G podaci"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Onemogućeni su mobilni podaci"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Podaci su onemogućeni"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Dosegnuli ste navedeno ograničenje upotrebe podataka."\n\n"Ako ponovo omogućite podatke, operator će vam to možda dodatno naplatiti."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Dosegnuli ste navedeno ograničenje upotrebe podataka.\n\nAko ponovo omogućite podatke, operator će vam to možda dodatno naplatiti."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Ponovo omogući podatke"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Nema internetske veze"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi povezan"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Traženje GPS-a"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Lokaciju utvrdio GPS"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Zahtjevi za lokaciju aktivni su"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Brisanje svih obavijesti."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informacije o aplikaciji"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Zatvori"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Obavijesti isključene"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Dotaknite ovdje da biste ponovo uključili obavijesti."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Zaslon će se automatski zakrenuti."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Zaslon je zaključan u pejzažnoj orijentaciji."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Zaslon je zaključan u portretnoj orijentaciji."</string>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Automatska rotacija"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Rotacija zaključana"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Način unosa"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Lokacija u uporabi"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Lokacija"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Lokacija je isključena"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Medijski uređaj"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Samo hitni pozivi"</string>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Bežični prikaz"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Svjetlina"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATSKI"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Obavijesti se prikazuju ovdje"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Pristupite im u bilo kojem trenutku tako da prstom trznete prema dolje. "\n"Ponovo prstom trznite prema dolje za kontrole sustava."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Mreža se možda nadzire"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index b71cc78..55a135f 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"Rendszer UI"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Törlés"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Ne zavarjanak"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Értesítések megjelenítése"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Eltávolítás a listából"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Alkalmazásinformáció"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Nincs újabb alkalmazás"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Csatlakoztassa a töltőt"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Az akkufeszültség alacsony."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> maradt"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"Az USB-n keresztüli töltés nincs támogatva."\n"Használja a kapott töltőt."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"Az USB-n keresztüli töltés nincs támogatva.\nHasználja a kapott töltőt."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Akkumulátorhasználat"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Beállítások"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <string name="always_use_device" msgid="1450287437017315906">"Alapértelmezett használat ehhez az USB-eszközhöz"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Alapértelmezett használat ehhez az USB-kiegészítőhöz"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"Engedélyezi az USB hibakeresést?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"A számítógép RSA kulcs ujjlenyomata:"\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"A számítógép RSA kulcs ujjlenyomata:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Mindig engedélyezze erről a számítógépről"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Nagyítás a kitöltéshez"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Nyújtás kitöltéshez"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Kompatibilitás -- nagyítás/kicsinyítés"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Ha egy alkalmazást kisebb képernyőre terveztek, akkor a nagyítás/kicsinyítés vezérlője az óra mellett jelenik meg."</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Képernyőkép mentése..."</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"Képernyőkép mentése..."</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"Képernyőkép mentése."</string>
@@ -160,17 +156,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G adatforgalom letiltva"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobil adatforgalom letiltva"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Adatok letiltva"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Elérte a megadott adathasználati korlátot."\n\n"Ha újra engedélyezi az adatforgalmat, szolgáltatója díjat számolhat fel."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Elérte a megadott adathasználati korlátot.\n\nHa újra engedélyezi az adatforgalmat, szolgáltatója díjat számolhat fel."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Adatforgalom engedélyezése"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Nincs internet"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi csatlakoztatva"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"GPS keresése"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"A GPS beállította a helyet"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Aktív helylekérések"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Minden értesítés törlése"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Alkalmazásinformáció"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Bezárás"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Értesítések kikapcsolva"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Itt érintse meg az értesítések bekapcsolásához."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"A képernyő automatikusan forogni fog."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"A képernyő zárolva van fekvő tájolásban."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"A képernyő zárolva van álló tájolásban."</string>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Automatikus forgatás"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Forgatás zárolva"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Beviteli módszer"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Használatban lévő hely"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Tartózkodási hely"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Hely kikapcsolva"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Médiaeszköz"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Csak segélyhívások"</string>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Vezeték nélküli kijelző"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Fényerő"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"automatikus"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Az értesítések itt jelennek meg."</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Bármikor elérheti őket, ha lefelé húzza az ujját."\n"Húzza le az ujját még egyszer a rendszerbeállítások eléréséhez."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Lehet, hogy a hálózat felügyelt"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hy-rAM-land/strings.xml b/packages/SystemUI/res/values-hy-rAM-land/strings.xml
new file mode 100644
index 0000000..7c0535c
--- /dev/null
+++ b/packages/SystemUI/res/values-hy-rAM-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * 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.
+ */
+ -->
+
+<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>
+</resources>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
new file mode 100644
index 0000000..ce97d01
--- /dev/null
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -0,0 +1,201 @@
+<?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: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="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="6576392951053994640">"Թարմ հավելվածներ չկան"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Անտեսել վերջին ծրագրերը"</string>
+  <plurals name="status_bar_accessibility_recent_apps">
+    <item quantity="one" msgid="5854176083865845541">"1 նոր ծրագիր"</item>
+    <item quantity="other" msgid="1040784359794890744">"%d նոր ծրագիր"</item>
+  </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="battery_low_title" msgid="2783104807551211639">"Միացրեք լիցքավորիչը"</string>
+    <string name="battery_low_subtitle" msgid="1752040062087829196">"Մարտկոցը լիցքաթափվում է:"</string>
+    <string name="battery_low_percent_format" msgid="1077244949318261761">"մնում է <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB լիցքավորումը չի աջակցվում:\nՕգտվեք միայն գործող լիցքավորիչից:"</string>
+    <string name="battery_low_why" msgid="7279169609518386372">"Մարտկոցի օգտագործումը"</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_airplane" msgid="4879879698500955300">"Ինքնաթիռային ռեժիմ"</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_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">"Բացե՞լ <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>
+    <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="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>
+    <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_saved_text" msgid="1152839647677558815">"Հպեք ձեր էկրանի հանույթը տեսնելու համար:"</string>
+    <string name="screenshot_failed_title" msgid="705781116746922771">"Չհաջողվեց լուսանկարել էկրանի հանույթը:"</string>
+    <string name="screenshot_failed_text" msgid="8134011269572415402">"Չհաջողվեց պահել էկրանի հանույթը: Հնարավոր է` պահոցն օգտագործման մեջ է:"</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">"Տեղադրել Android ֆայլերի փոխանցման հավելվածը Mac-ի համար"</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_recent" msgid="8571350598987952883">"Վերջին ծրագրերը"</string>
+    <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Միացնել մուտքագրման եղանակի կոճակը:"</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>
+    <string name="accessibility_no_battery" msgid="358343022352820946">"Մարտկոց չկա:"</string>
+    <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Մարտկոցի մեկ գիծ:"</string>
+    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Մարտկոցի երկու գիծ:"</string>
+    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Մարտկոցի երեք գիծ:"</string>
+    <string name="accessibility_battery_full" msgid="8909122401720158582">"Մարտկոցը լիքն է:"</string>
+    <string name="accessibility_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_off" msgid="3177380296697933627">"Wifi-ը անջատված է:"</string>
+    <string name="accessibility_no_wifi" msgid="1425476551827924474">"WiFi-ը անջատված է:"</string>
+    <string name="accessibility_wifi_one_bar" msgid="7735893178010724377">"Wifi-ի մեկ գիծ:"</string>
+    <string name="accessibility_wifi_two_bars" msgid="4994274250497262434">"Wifi-ի երկու գիծ:"</string>
+    <string name="accessibility_wifi_three_bars" msgid="3495755044276588384">"WiFi-ի երեք գիծ:"</string>
+    <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"Wifi-ի ազդանշանը լիքն է:"</string>
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"WiMAX չկա:"</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX-ի մեկ գիծ:"</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX-ի երկու գիծ:"</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX-ի երեք գիծ:"</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX-ի ազդանշանը լիքն է:"</string>
+    <string name="accessibility_no_signal" msgid="7064645320782585167">"Ազդանշան չկա:"</string>
+    <string name="accessibility_not_connected" msgid="6395326276213402883">"Միացված չէ:"</string>
+    <string name="accessibility_zero_bars" msgid="3806060224467027887">"Զրո գիծ:"</string>
+    <string name="accessibility_one_bar" msgid="1685730113192081895">"Մեկ գիծ:"</string>
+    <string name="accessibility_two_bars" msgid="6437363648385206679">"Երկու գիծ:"</string>
+    <string name="accessibility_three_bars" msgid="2648241415119396648">"Երեք գիծ:"</string>
+    <string name="accessibility_signal_full" msgid="9122922886519676839">"Ազդանշանը լրիվ է:"</string>
+    <string name="accessibility_desc_on" msgid="2385254693624345265">"Միացված է:"</string>
+    <string name="accessibility_desc_off" msgid="6475508157786853157">"Անջատված է:"</string>
+    <string name="accessibility_desc_connected" msgid="8366256693719499665">"Միացված է:"</string>
+    <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+    <string name="accessibility_data_connection_1x" msgid="994133468120244018">"1 X"</string>
+    <string name="accessibility_data_connection_hspa" msgid="2032328855462645198">"HSPA"</string>
+    <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+    <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+    <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+    <string name="accessibility_data_connection_lte" msgid="5413468808637540658">"LTE"</string>
+    <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_bluetooth_tether" msgid="4102784498140271969">"Bluetooth-ը կապվում է:"</string>
+    <string name="accessibility_airplane_mode" msgid="834748999790763092">"Ինքնաթիռային ռեժիմ"</string>
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"Մարտկոցը <xliff:g id="NUMBER">%d</xliff:g> տոկոս է:"</string>
+    <string name="accessibility_settings_button" msgid="799583911231893380">"Համակարգի կարգավորումներ:"</string>
+    <string name="accessibility_notifications_button" msgid="4498000369779421892">"Ծանուցումներ:"</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_silent" msgid="9061243307939135383">"Զանգակը լռեցված է:"</string>
+    <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g>-ը անտեսված է:"</string>
+    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Ծանուցումը անտեսվեց:"</string>
+    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Ծանուցումների վահանակ:"</string>
+    <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Արագ կարգավորումներ:"</string>
+    <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Վերջին հավելվածները:"</string>
+    <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Օգտվող <xliff:g id="USER">%s</xliff:g>:"</string>
+    <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>: <xliff:g id="NETWORK">%2$s</xliff:g>"</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" msgid="4196876722090224753">"Ինքնաթիռային ռեժիմը <xliff:g id="STATE">%s</xliff:g> է:"</string>
+    <string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth-ը <xliff:g id="STATE">%s</xliff:g> է:"</string>
+    <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Զարթուցիչը դրված է <xliff:g id="TIME">%s</xliff:g>-ին:"</string>
+    <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G տվյալները անջատված են"</string>
+    <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G տվյալները անջատված են"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Շարժական տվյալները անջատված են"</string>
+    <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Տվյալները անջատված են"</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Դուք հասել եք նշված տվյալների օգտագործման սահմանին:\n\n Եթե դուք կրկին ակտիվացնեք տվյալները, այն կարող է գանձվել օպերատորի կողմից:"</string>
+    <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Վերամիացնել տվյալները"</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="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="accessibility_clear_all" msgid="5235938559247164925">"Մաքրել բոլոր ծանուցումները:"</string>
+    <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Տեղեկություններ ծրագրի մասին"</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="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="start_dreams" msgid="7219575858348719790">"Ցերեկային ռեժիմ"</string>
+    <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Ինքնաթիռային ռեժիմ"</string>
+    <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"Լիցքավորում` <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"Լիցքավորված է"</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_brightness_label" msgid="6968372297018755815">"Պայծառություն"</string>
+    <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Ինքնապտտում"</string>
+    <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Պտտումը կողպված է"</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>
+    <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Միայն արտակարգ իրավիճակների զանգեր"</string>
+    <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_wifi_label" msgid="9135344704899546041">"Wi-Fi"</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_display_label" msgid="6893592964463624333">"Wi-Fi ցուցադրիչ"</string>
+    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Անլար էկրան"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Պայծառություն"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"Ինքնաշխատ"</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Ցանցը կարող է վերահսկվել"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
new file mode 100644
index 0000000..4241898
--- /dev/null
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -0,0 +1,204 @@
+<?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: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="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="6576392951053994640">"Թարմ հավելվածներ չկան"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Անտեսել վերջին ծրագրերը"</string>
+  <plurals name="status_bar_accessibility_recent_apps">
+    <item quantity="one" msgid="5854176083865845541">"1 նոր ծրագիր"</item>
+    <item quantity="other" msgid="1040784359794890744">"%d նոր ծրագիր"</item>
+  </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="battery_low_title" msgid="2783104807551211639">"Միացրեք լիցքավորիչը"</string>
+    <string name="battery_low_subtitle" msgid="1752040062087829196">"Մարտկոցը լիցքաթափվում է:"</string>
+    <string name="battery_low_percent_format" msgid="1077244949318261761">"մնում է <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB լիցքավորումը չի աջակցվում:\nՕգտվեք միայն գործող լիցքավորիչից:"</string>
+    <string name="battery_low_why" msgid="7279169609518386372">"Մարտկոցի օգտագործումը"</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_airplane" msgid="4879879698500955300">"Ինքնաթիռային ռեժիմ"</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_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">"Բացե՞լ <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>
+    <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="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>
+    <string name="compat_mode_on" msgid="6623839244840638213">"Խոշորացնել` էկրանը լցնելու համար"</string>
+    <string name="compat_mode_off" msgid="4434467572461327898">"Ձգել` էկրանը լցնելու համար"</string>
+    <string name="compat_mode_help_header" msgid="7969493989397529910">"Համատեղելիության խոշորացում"</string>
+    <string name="compat_mode_help_body" msgid="4946726776359270040">"Երբ հավելվածը նախագծված է ավելի փոքր էկրանի համար, խոշորացման կարգավորիչը կհայտնվի ժամացույցի կողքին:"</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="1152839647677558815">"Հպեք ձեր էկրանի հանույթը տեսնելու համար:"</string>
+    <string name="screenshot_failed_title" msgid="705781116746922771">"Չհաջողվեց լուսանկարել էկրանի հանույթը:"</string>
+    <string name="screenshot_failed_text" msgid="8134011269572415402">"Չհաջողվեց պահել էկրանի հանույթը: Հնարավոր է` պահոցն օգտագործման մեջ է:"</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">"Տեղադրել Android ֆայլերի փոխանցման հավելվածը Mac-ի համար"</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_recent" msgid="8571350598987952883">"Վերջին ծրագրերը"</string>
+    <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Միացնել մուտքագրման եղանակի կոճակը:"</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>
+    <string name="accessibility_no_battery" msgid="358343022352820946">"Մարտկոց չկա:"</string>
+    <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Մարտկոցի մեկ գիծ:"</string>
+    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Մարտկոցի երկու գիծ:"</string>
+    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Մարտկոցի երեք գիծ:"</string>
+    <string name="accessibility_battery_full" msgid="8909122401720158582">"Մարտկոցը լիքն է:"</string>
+    <string name="accessibility_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_off" msgid="3177380296697933627">"Wifi-ը անջատված է:"</string>
+    <string name="accessibility_no_wifi" msgid="1425476551827924474">"WiFi-ը անջատված է:"</string>
+    <string name="accessibility_wifi_one_bar" msgid="7735893178010724377">"Wifi-ի մեկ գիծ:"</string>
+    <string name="accessibility_wifi_two_bars" msgid="4994274250497262434">"Wifi-ի երկու գիծ:"</string>
+    <string name="accessibility_wifi_three_bars" msgid="3495755044276588384">"WiFi-ի երեք գիծ:"</string>
+    <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"Wifi-ի ազդանշանը լիքն է:"</string>
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"WiMAX չկա:"</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX-ի մեկ գիծ:"</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX-ի երկու գիծ:"</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX-ի երեք գիծ:"</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX-ի ազդանշանը լիքն է:"</string>
+    <string name="accessibility_no_signal" msgid="7064645320782585167">"Ազդանշան չկա:"</string>
+    <string name="accessibility_not_connected" msgid="6395326276213402883">"Միացված չէ:"</string>
+    <string name="accessibility_zero_bars" msgid="3806060224467027887">"Զրո գիծ:"</string>
+    <string name="accessibility_one_bar" msgid="1685730113192081895">"Մեկ գիծ:"</string>
+    <string name="accessibility_two_bars" msgid="6437363648385206679">"Երկու գիծ:"</string>
+    <string name="accessibility_three_bars" msgid="2648241415119396648">"Երեք գիծ:"</string>
+    <string name="accessibility_signal_full" msgid="9122922886519676839">"Ազդանշանը լրիվ է:"</string>
+    <string name="accessibility_desc_on" msgid="2385254693624345265">"Միացված է:"</string>
+    <string name="accessibility_desc_off" msgid="6475508157786853157">"Անջատված է:"</string>
+    <string name="accessibility_desc_connected" msgid="8366256693719499665">"Միացված է:"</string>
+    <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+    <string name="accessibility_data_connection_1x" msgid="994133468120244018">"1 X"</string>
+    <string name="accessibility_data_connection_hspa" msgid="2032328855462645198">"HSPA"</string>
+    <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+    <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+    <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+    <string name="accessibility_data_connection_lte" msgid="5413468808637540658">"LTE"</string>
+    <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_bluetooth_tether" msgid="4102784498140271969">"Bluetooth-ը կապվում է:"</string>
+    <string name="accessibility_airplane_mode" msgid="834748999790763092">"Ինքնաթիռային ռեժիմ"</string>
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"Մարտկոցը <xliff:g id="NUMBER">%d</xliff:g> տոկոս է:"</string>
+    <string name="accessibility_settings_button" msgid="799583911231893380">"Համակարգի կարգավորումներ:"</string>
+    <string name="accessibility_notifications_button" msgid="4498000369779421892">"Ծանուցումներ:"</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_silent" msgid="9061243307939135383">"Զանգակը լռեցված է:"</string>
+    <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g>-ը անտեսված է:"</string>
+    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Ծանուցումը անտեսվեց:"</string>
+    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Ծանուցումների վահանակ:"</string>
+    <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Արագ կարգավորումներ:"</string>
+    <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Վերջին հավելվածները:"</string>
+    <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Օգտվող <xliff:g id="USER">%s</xliff:g>:"</string>
+    <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>: <xliff:g id="NETWORK">%2$s</xliff:g>"</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" msgid="4196876722090224753">"Ինքնաթիռային ռեժիմը <xliff:g id="STATE">%s</xliff:g> է:"</string>
+    <string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth-ը <xliff:g id="STATE">%s</xliff:g> է:"</string>
+    <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Զարթուցիչը դրված է <xliff:g id="TIME">%s</xliff:g>-ին:"</string>
+    <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G տվյալները անջատված են"</string>
+    <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G տվյալները անջատված են"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Շարժական տվյալները անջատված են"</string>
+    <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Տվյալները անջատված են"</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Դուք հասել եք նշված տվյալների օգտագործման սահմանին:\n\n Եթե դուք կրկին ակտիվացնեք տվյալները, այն կարող է գանձվել օպերատորի կողմից:"</string>
+    <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Վերամիացնել տվյալները"</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="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="accessibility_clear_all" msgid="5235938559247164925">"Մաքրել բոլոր ծանուցումները:"</string>
+    <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Տեղեկություններ ծրագրի մասին"</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="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="start_dreams" msgid="7219575858348719790">"Ցերեկային ռեժիմ"</string>
+    <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Ինքնաթիռային ռեժիմ"</string>
+    <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"Լիցքավորում` <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"Լիցքավորված է"</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_brightness_label" msgid="6968372297018755815">"Պայծառություն"</string>
+    <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Ինքնապտտում"</string>
+    <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Պտտումը կողպված է"</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>
+    <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Միայն արտակարգ իրավիճակների զանգեր"</string>
+    <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_wifi_label" msgid="9135344704899546041">"Wi-Fi"</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_display_label" msgid="6893592964463624333">"Wi-Fi ցուցադրիչ"</string>
+    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Անլար էկրան"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Պայծառություն"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"Ինքնաշխատ"</string>
+    <string name="status_bar_help_title" msgid="1199237744086469217">"Ծանուցումները հայտնվում են այստեղ"</string>
+    <string name="status_bar_help_text" msgid="7874607155052076323">"Դրանք մատչեք ցանկացած պահի` սահահարվածելով:\nԿրկին սահահարվածեք ներքև` համակարգային կառավարման համար:"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 2c26b0d..6589ae1 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"Sistem UI"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Bersihkan"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Jangan ganggu"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Tampilkan pemberitahuan"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Hapus dari daftar"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Info apl"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Tidak ada apl terbaru"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Hubungkan pengisi daya"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Baterai semakin lemah."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> tersisa"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"Pengisian daya USB tidak didukung."\n"Gunakan hanya pengisi daya yang disediakan."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"Pengisian daya USB tidak didukung.\nGunakan hanya pengisi daya yang disediakan."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Penggunaan baterai"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Setelan"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <string name="always_use_device" msgid="1450287437017315906">"Gunakan secara default untuk perangkat USB ini"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Gunakan secara default untuk aksesori USB ini"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"Izinkan debugging USB?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"Sidik jari kunci RSA komputer adalah:"\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"Sidik jari kunci RSA komputer adalah:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Selalu izinkan dari komputer ini"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Perbesar utk mengisi layar"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Rentangkn utk mngisi layar"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Perbesar/perkecil untuk kompatibilitas"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Saat apl dirancang untuk layar yang lebih kecil, kontrol zoom akan tampil di dekat jam."</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Menyimpan tangkapan layar..."</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"Menyimpan tangkapan layar..."</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"Tangkapan layar sedang disimpan."</string>
@@ -160,17 +156,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Data 4G dinonaktifkan"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Data seluler dinonaktifkan"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Data dinonaktifkan"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Anda telah mencapai batas penggunaan data yang ditentukan."\n\n"Jika Anda mengaktifkan ulang data, Anda mungkin akan dikenai biaya oleh operator."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Anda telah mencapai batas penggunaan data yang ditentukan.\n\nJika Anda mengaktifkan ulang data, Anda mungkin akan dikenai biaya oleh operator."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Aktifkan ulang data"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Tidak ada sambungan internet"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi tersambung"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Menelusuri GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Lokasi yang disetel oleh GPS"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Permintaan lokasi aktif"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Menghapus semua pemberitahuan."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Info aplikasi"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Tutup"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Pemberitahuan mati"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Ketuk di sini untuk menyalakan pemberitahuan lagi."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Layar akan diputar secara otomatis."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Layar dikunci dalam orientasi lanskap."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Layar dikunci dalam orientasi potret."</string>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Rotasi Otomatis"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Rotasi Dikunci"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Metode Masukan"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Lokasi penggunaan"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Lokasi"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Lokasi Mati"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Perangkat media"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Panggilan Darurat Saja"</string>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Layar Nirkabel"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Kecerahan"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"OTOMATIS"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Pemberitahuan muncul di sini"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Akses kapan saja dengan menggesek ke bawah."\n"Gesek ke bawah sekali lagi untuk kontrol sistem."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Jaringan mungkin dipantau"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 0665fb8..2aaa1e7 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"UI sistema"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Cancella"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Non disturbare"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Mostra notifiche"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Rimuovi dall\'elenco"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Informazioni applicazione"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Nessuna app recente"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Collega il caricabatterie"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Batteria quasi scarica."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> rimanente"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"Ricarica tramite USB non supportata."\n"Utilizza solo il caricatore in dotazione."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"Ricarica tramite USB non supportata.\nUtilizza solo il caricatore in dotazione."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Utilizzo batteria"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Impostazioni"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <string name="always_use_device" msgid="1450287437017315906">"Usa per impostazione predef. per dispositivo USB"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Usa per impostazione predef. per accessorio USB"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"Consentire debug USB?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"Fingerprint della chiave RSA del computer: "\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"Fingerprint della chiave RSA del computer: \n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Consenti sempre da questo computer"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom per riempire schermo"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Estendi per riemp. schermo"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Zoom compatibilità"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Se un\'applicazione è stata progettata per uno schermo più piccolo, accanto all\'orologio viene visualizzato un controllo dello zoom."</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Salvataggio screenshot..."</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"Salvataggio screenshot..."</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"Screenshot in corso di salvataggio."</string>
@@ -162,17 +158,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Dati 4G disattivati"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Dati mobili disattivati"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Dati disabilati"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Hai raggiunto il limite di utilizzo dei dati specificato."\n\n"Se riattivi i dati, l\'operatore potrebbe addebitarti un costo."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Hai raggiunto il limite di utilizzo dei dati specificato.\n\nSe riattivi i dati, l\'operatore potrebbe addebitarti un costo."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Riattiva dati"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Nessuna connessione"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi connesso"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Ricerca del GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Posizione stabilita dal GPS"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Richieste di accesso alla posizione attive"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Cancella tutte le notifiche."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informazioni applicazione"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Chiudi"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Notifiche disattivate"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Tocca qui per riattivare le notifiche."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Lo schermo ruoterà automaticamente."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Lo schermo è bloccato in orientamento orizzontale."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Lo schermo è bloccato in orientamento verticale."</string>
@@ -189,7 +183,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Rotazione autom."</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Rotazione bloccata"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Metodo di immissione"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Posizione in uso"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Posizione"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Posizione non attiva"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Dispositivo multimediale"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Solo chiamate di emergenza"</string>
@@ -204,6 +199,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Visualizzazione wireless"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Luminosità"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Le notifiche vengono visualizzate qui"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Puoi accedervi in qualsiasi momento scorrendo verso il basso."\n"Fai scorrere di nuovo verso il basso per visualizzare i controlli del sistema."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"La rete potrebbe essere monitorata"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index c75c039..668c77a 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -21,8 +21,6 @@
     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_do_not_disturb_button" msgid="5812628897510997853">"נא לא להפריע"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"הצג התראות"</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="6576392951053994640">"אין יישומים אחרונים"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"חבר מטען"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"הסוללה נחלשת."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"נותרו <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"טעינה באמצעות USB אינה נתמכת."\n"השתמש אך ורק במטען שסופק."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"טעינה באמצעות USB אינה נתמכת.\nהשתמש אך ורק במטען שסופק."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"צריכת סוללה"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"הגדרות"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <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="compat_mode_on" msgid="6623839244840638213">"הגדל תצוגה כדי למלא את המסך"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"מתח כדי למלא את המסך"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"שינוי מרחק מתצוגה לצורך תאימות"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"כאשר יישום מיועד למסך קטן יותר, פקד של מרחק מתצוגה יופיע ליד השעון."</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>
@@ -160,17 +156,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"נתוני 4G מושבתים"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"נתונים לנייד מושבתים"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"הנתונים מושבתים"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"הגעת לגבול המוגדר של שימוש בנתונים."\n\n"אם תפעיל מחדש נתונים, ייתכן שתחויב על ידי הספק שלך."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"הגעת לגבול המוגדר של שימוש בנתונים.\n\nאם תפעיל מחדש נתונים, ייתכן שתחויב על ידי הספק שלך."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"הפעל מחדש את הנתונים"</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="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="accessibility_clear_all" msgid="5235938559247164925">"נקה את כל ההתראות."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"פרטי יישום"</string>
-    <string name="close_universe" msgid="3736513750241754348">"סגור"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"מצב התראות כבוי"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"הקש כאן כדי להפעיל מחדש את ההתראות."</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>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"סיבוב אוטומטי"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"סיבוב נעול"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"שיטת קלט"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"מיקום בשימוש"</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>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"תצוגת Wi-Fi"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"בהירות"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"אוטומטי"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"הודעות מופיעות כאן"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"גש אליהם בכל עת על ידי החלקה למטה."\n"החלק למטה שוב למעבר למרכז הבקרה של המערכת."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"ייתכן שהרשת מנוטרת"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index fe0b9af..0451117 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"システムUI"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"通知を消去"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"通知を非表示"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"通知を表示"</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="6576392951053994640">"最近使ったアプリはありません"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"充電してください"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"電池が残り少なくなっています。"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"残り<xliff:g id="NUMBER">%d%%</xliff:g>"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"USB充電には対応していません。"\n"付属の充電器をお使いください。"</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB充電には対応していません。\n付属の充電器をお使いください。"</string>
     <string name="battery_low_why" msgid="7279169609518386372">"電池使用量"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"設定"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <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">"このパソコンからのUSBデバッグを常に許可する"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"画面サイズに合わせて拡大"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"画面サイズに合わせて拡大"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"互換ズーム"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"より小型の画面向けのアプリの場合は、ズームコントロールが時計のそばに表示されます。"</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>
@@ -162,17 +158,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4Gデータが無効になりました"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"モバイルデータが無効になりました"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"データが無効になりました"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"指定したデータ使用上限に達しました。"\n\n"データ接続を再度有効にした場合、携帯通信会社の料金が発生する可能性があります。"</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"指定したデータ使用上限に達しました。\n\nデータ接続を再度有効にした場合、携帯通信会社の料金が発生する可能性があります。"</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"データ接続を再度有効にする"</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="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="accessibility_clear_all" msgid="5235938559247164925">"通知をすべて消去。"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"アプリ情報"</string>
-    <string name="close_universe" msgid="3736513750241754348">"閉じる"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"通知OFF"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"通知を再度ONにするにはここをタップします。"</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>
@@ -189,7 +183,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"自動回転"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"画面の向きをロック"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"入力方法"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"使用中のロケーション"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"現在地"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"現在地OFF"</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>
@@ -204,6 +199,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"ワイヤレスディスプレイ"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"画面の明るさ"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"自動"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"ここに通知が表示されます"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"下にスワイプすると、いつでも通知を表示できます。"\n"システムを管理するにはもう一度下にスワイプしてください。"</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"ネットワークが監視される場合があります"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ka-rGE-land/strings.xml b/packages/SystemUI/res/values-ka-rGE-land/strings.xml
new file mode 100644
index 0000000..3f20938
--- /dev/null
+++ b/packages/SystemUI/res/values-ka-rGE-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * 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.
+ */
+ -->
+
+<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>
+</resources>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
new file mode 100644
index 0000000..49ed9ba
--- /dev/null
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -0,0 +1,201 @@
+<?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: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="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="6576392951053994640">"ბოლოს გამოყენებული აპების სია ცარიელია"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"ბოლო აპების გაუქმება"</string>
+  <plurals name="status_bar_accessibility_recent_apps">
+    <item quantity="one" msgid="5854176083865845541">"1 ბოლო აპი"</item>
+    <item quantity="other" msgid="1040784359794890744">"%d ბოლო აპი"</item>
+  </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="battery_low_title" msgid="2783104807551211639">"შეაერთეთ დამტენი."</string>
+    <string name="battery_low_subtitle" msgid="1752040062087829196">"ბატარეა ჯდება."</string>
+    <string name="battery_low_percent_format" msgid="1077244949318261761">"დარჩენილია <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB-ით დატენვა არ არის მხარდაჭერილი.\nგამოიყენეთ მხოლოდ ელექტრო-დამტენი."</string>
+    <string name="battery_low_why" msgid="7279169609518386372">"ელემენტის გამოყენება"</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_airplane" msgid="4879879698500955300">"თვითმფრინავის რეჟიმი"</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_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">"გსურთ <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>
+    <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="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>
+    <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_saved_text" msgid="1152839647677558815">"შეეხეთ ეკრანის სურათის სანახავად."</string>
+    <string name="screenshot_failed_title" msgid="705781116746922771">"ვერ მოხერხდა ეკრანის ანაბეჭდის გადაღება."</string>
+    <string name="screenshot_failed_text" msgid="8134011269572415402">"ეკრანის სურათი ვერ შეინახა. შესაძლოა, მეხსიერება უკვე დაკავებულია."</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">"Android File Transfer აპის დაყენება Mac-თვის"</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_recent" msgid="8571350598987952883">"ბოლოს გამოყენებული აპები"</string>
+    <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"შეყვანის მეთოდის გადართვის ღილაკი."</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>
+    <string name="accessibility_no_battery" msgid="358343022352820946">"ბატარეა დამჯდარია."</string>
+    <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"ბატარეია ერთ ზოლზეა."</string>
+    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"ელემენტი ორ ზოლზე."</string>
+    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"ელემენტი სამ ზოლზე."</string>
+    <string name="accessibility_battery_full" msgid="8909122401720158582">"ელემენტი სავსეა."</string>
+    <string name="accessibility_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_off" msgid="3177380296697933627">"Wifi გამორთულია."</string>
+    <string name="accessibility_no_wifi" msgid="1425476551827924474">"Wifi არ არის დაკავშირებული."</string>
+    <string name="accessibility_wifi_one_bar" msgid="7735893178010724377">"Wifi სიგნალი ერთ ზოლზეა."</string>
+    <string name="accessibility_wifi_two_bars" msgid="4994274250497262434">"Wifi სიგნალი ორ ზოლზეა."</string>
+    <string name="accessibility_wifi_three_bars" msgid="3495755044276588384">"Wifi სამი ზოლი."</string>
+    <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"Wifi სიგნალი სრულია."</string>
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"WiMAX არ არის."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX ერთი სვეტი."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX-ის ორი ზოლი."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX-ის სამი ზოლი."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX სიგნალი სრულია."</string>
+    <string name="accessibility_no_signal" msgid="7064645320782585167">"სიგნალი არ არის."</string>
+    <string name="accessibility_not_connected" msgid="6395326276213402883">"არ არის დაკავშირებული."</string>
+    <string name="accessibility_zero_bars" msgid="3806060224467027887">"სიგნალი ნულ ზოლზეა."</string>
+    <string name="accessibility_one_bar" msgid="1685730113192081895">"ერთი ზოლი."</string>
+    <string name="accessibility_two_bars" msgid="6437363648385206679">"ორი სვეტი."</string>
+    <string name="accessibility_three_bars" msgid="2648241415119396648">"სამი ზოლი."</string>
+    <string name="accessibility_signal_full" msgid="9122922886519676839">"სრული სიგნალი."</string>
+    <string name="accessibility_desc_on" msgid="2385254693624345265">"ჩართული"</string>
+    <string name="accessibility_desc_off" msgid="6475508157786853157">"გამორთულია."</string>
+    <string name="accessibility_desc_connected" msgid="8366256693719499665">"დაკავშირებულია."</string>
+    <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+    <string name="accessibility_data_connection_1x" msgid="994133468120244018">"1 X"</string>
+    <string name="accessibility_data_connection_hspa" msgid="2032328855462645198">"HSPA"</string>
+    <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+    <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5გბ"</string>
+    <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+    <string name="accessibility_data_connection_lte" msgid="5413468808637540658">"LTE"</string>
+    <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_bluetooth_tether" msgid="4102784498140271969">"Bluetooth-ის ჩართვა"</string>
+    <string name="accessibility_airplane_mode" msgid="834748999790763092">"თვითმფრინავის რეჟიმი"</string>
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"ბატარეა: <xliff:g id="NUMBER">%d</xliff:g> პროცენტი."</string>
+    <string name="accessibility_settings_button" msgid="799583911231893380">"სისტემის პარამეტრები."</string>
+    <string name="accessibility_notifications_button" msgid="4498000369779421892">"შეტყობინებები"</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_silent" msgid="9061243307939135383">"უხმო რეჟიმი."</string>
+    <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ამოშლილია სიიდან."</string>
+    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"შეტყობინება წაიშალა."</string>
+    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"შეტყობინებების ფარდა"</string>
+    <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"სწრაფი პარამეტრები"</string>
+    <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"ბოლო აპები."</string>
+    <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"მომხმარებელი: <xliff:g id="USER">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</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" msgid="4196876722090224753">"თვითმფრინავის რეჟიმი <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"მაღვიძარა დაყენებულია: <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G ინტერნეტი გაითიშა."</string>
+    <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G მონაცემები გათიშულია"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"მობილური ინტერნეტი გაითიშა."</string>
+    <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"ინტერნეტი გაითიშა."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"თქვენ მიაღწიეთ ინტერნეტის გამოყენების განსაზღვრულ ლიმიტს.\n\nთუ გააქტიურებთ ინტერნეტს, შესაძლოა მობილური ოპერატორისთვის დამატებითი თანხის გადახდა მოგიწიოთ."</string>
+    <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"მონაცემების ხელახლა ჩართვა"</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="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="accessibility_clear_all" msgid="5235938559247164925">"ყველა შეტყობინების წაშლა"</string>
+    <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"აპის შესახებ"</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="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="start_dreams" msgid="7219575858348719790">"Daydream"</string>
+    <string name="ethernet_label" msgid="7967563676324087464">"ეთერნეტი"</string>
+    <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"თვითმფრინავის რეჟიმი"</string>
+    <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"დამუხტვა, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"დამუხტულია"</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_brightness_label" msgid="6968372297018755815">"სიკაშკაშე"</string>
+    <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"ავტო მობრუნება"</string>
+    <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"როტაციის ჩაკეტვა"</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>
+    <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"მხოლოდ გადაუდებელი დახმარების ზარებისთვის"</string>
+    <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_wifi_label" msgid="9135344704899546041">"Wi-Fi"</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_display_label" msgid="6893592964463624333">"Wi-Fi ეკრანი"</string>
+    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"უსადენო ეკრანი"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"განათება"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ავტომატურად"</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"შესაძლოა ქსელი მონიტორინგის ქვეშ იმყოფება"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
new file mode 100644
index 0000000..bcbe4de
--- /dev/null
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -0,0 +1,204 @@
+<?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: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="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="6576392951053994640">"ბოლოს გამოყენებული აპების სია ცარიელია"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"ბოლო აპების გაუქმება"</string>
+  <plurals name="status_bar_accessibility_recent_apps">
+    <item quantity="one" msgid="5854176083865845541">"1 ბოლო აპი"</item>
+    <item quantity="other" msgid="1040784359794890744">"%d ბოლო აპი"</item>
+  </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="battery_low_title" msgid="2783104807551211639">"შეაერთეთ დამტენი."</string>
+    <string name="battery_low_subtitle" msgid="1752040062087829196">"ბატარეა ჯდება."</string>
+    <string name="battery_low_percent_format" msgid="1077244949318261761">"დარჩენილია <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB-ით დატენვა არ არის მხარდაჭერილი.\nგამოიყენეთ მხოლოდ ელექტრო-დამტენი."</string>
+    <string name="battery_low_why" msgid="7279169609518386372">"ელემენტის გამოყენება"</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_airplane" msgid="4879879698500955300">"თვითმფრინავის რეჟიმი"</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_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">"გსურთ <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>
+    <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="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>
+    <string name="compat_mode_on" msgid="6623839244840638213">"მასშტაბი შეცვალეთ ეკრანის შესავსებად."</string>
+    <string name="compat_mode_off" msgid="4434467572461327898">"გაწიეთ ეკრანის შესავსებად."</string>
+    <string name="compat_mode_help_header" msgid="7969493989397529910">"თავსებადობის მასშტაბი"</string>
+    <string name="compat_mode_help_body" msgid="4946726776359270040">"თუ აპი გათვლილია მცირე ეკრანისთვის, საათის გვერდით გაჩნდება მასშტაბის მართვის ელემენტი."</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="1152839647677558815">"შეეხეთ ეკრანის სურათის სანახავად."</string>
+    <string name="screenshot_failed_title" msgid="705781116746922771">"ვერ მოხერხდა ეკრანის ანაბეჭდის გადაღება."</string>
+    <string name="screenshot_failed_text" msgid="8134011269572415402">"ეკრანის სურათი ვერ შეინახა. შესაძლოა, მეხსიერება უკვე დაკავებულია."</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">"Android File Transfer აპის დაყენება Mac-თვის"</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_recent" msgid="8571350598987952883">"ბოლოს გამოყენებული აპები"</string>
+    <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"შეყვანის მეთოდის გადართვის ღილაკი."</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>
+    <string name="accessibility_no_battery" msgid="358343022352820946">"ბატარეა დამჯდარია."</string>
+    <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"ბატარეია ერთ ზოლზეა."</string>
+    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"ელემენტი ორ ზოლზე."</string>
+    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"ელემენტი სამ ზოლზე."</string>
+    <string name="accessibility_battery_full" msgid="8909122401720158582">"ელემენტი სავსეა."</string>
+    <string name="accessibility_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_off" msgid="3177380296697933627">"Wifi გამორთულია."</string>
+    <string name="accessibility_no_wifi" msgid="1425476551827924474">"Wifi არ არის დაკავშირებული."</string>
+    <string name="accessibility_wifi_one_bar" msgid="7735893178010724377">"Wifi სიგნალი ერთ ზოლზეა."</string>
+    <string name="accessibility_wifi_two_bars" msgid="4994274250497262434">"Wifi სიგნალი ორ ზოლზეა."</string>
+    <string name="accessibility_wifi_three_bars" msgid="3495755044276588384">"Wifi სამი ზოლი."</string>
+    <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"Wifi სიგნალი სრულია."</string>
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"WiMAX არ არის."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX ერთი სვეტი."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX-ის ორი ზოლი."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX-ის სამი ზოლი."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX სიგნალი სრულია."</string>
+    <string name="accessibility_no_signal" msgid="7064645320782585167">"სიგნალი არ არის."</string>
+    <string name="accessibility_not_connected" msgid="6395326276213402883">"არ არის დაკავშირებული."</string>
+    <string name="accessibility_zero_bars" msgid="3806060224467027887">"სიგნალი ნულ ზოლზეა."</string>
+    <string name="accessibility_one_bar" msgid="1685730113192081895">"ერთი ზოლი."</string>
+    <string name="accessibility_two_bars" msgid="6437363648385206679">"ორი სვეტი."</string>
+    <string name="accessibility_three_bars" msgid="2648241415119396648">"სამი ზოლი."</string>
+    <string name="accessibility_signal_full" msgid="9122922886519676839">"სრული სიგნალი."</string>
+    <string name="accessibility_desc_on" msgid="2385254693624345265">"ჩართული"</string>
+    <string name="accessibility_desc_off" msgid="6475508157786853157">"გამორთულია."</string>
+    <string name="accessibility_desc_connected" msgid="8366256693719499665">"დაკავშირებულია."</string>
+    <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+    <string name="accessibility_data_connection_1x" msgid="994133468120244018">"1 X"</string>
+    <string name="accessibility_data_connection_hspa" msgid="2032328855462645198">"HSPA"</string>
+    <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+    <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5გბ"</string>
+    <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+    <string name="accessibility_data_connection_lte" msgid="5413468808637540658">"LTE"</string>
+    <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_bluetooth_tether" msgid="4102784498140271969">"Bluetooth-ის ჩართვა"</string>
+    <string name="accessibility_airplane_mode" msgid="834748999790763092">"თვითმფრინავის რეჟიმი"</string>
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"ბატარეა: <xliff:g id="NUMBER">%d</xliff:g> პროცენტი."</string>
+    <string name="accessibility_settings_button" msgid="799583911231893380">"სისტემის პარამეტრები."</string>
+    <string name="accessibility_notifications_button" msgid="4498000369779421892">"შეტყობინებები"</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_silent" msgid="9061243307939135383">"უხმო რეჟიმი."</string>
+    <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ამოშლილია სიიდან."</string>
+    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"შეტყობინება წაიშალა."</string>
+    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"შეტყობინებების ფარდა"</string>
+    <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"სწრაფი პარამეტრები"</string>
+    <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"ბოლო აპები."</string>
+    <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"მომხმარებელი: <xliff:g id="USER">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</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" msgid="4196876722090224753">"თვითმფრინავის რეჟიმი <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"მაღვიძარა დაყენებულია: <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G ინტერნეტი გაითიშა."</string>
+    <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G მონაცემები გათიშულია"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"მობილური ინტერნეტი გაითიშა."</string>
+    <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"ინტერნეტი გაითიშა."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"თქვენ მიაღწიეთ ინტერნეტის გამოყენების განსაზღვრულ ლიმიტს.\n\nთუ გააქტიურებთ ინტერნეტს, შესაძლოა მობილური ოპერატორისთვის დამატებითი თანხის გადახდა მოგიწიოთ."</string>
+    <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"მონაცემების ხელახლა ჩართვა"</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="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="accessibility_clear_all" msgid="5235938559247164925">"ყველა შეტყობინების წაშლა"</string>
+    <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"აპის შესახებ"</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="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="start_dreams" msgid="7219575858348719790">"Daydream"</string>
+    <string name="ethernet_label" msgid="7967563676324087464">"ეთერნეტი"</string>
+    <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"თვითმფრინავის რეჟიმი"</string>
+    <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"დამუხტვა, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"დამუხტულია"</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_brightness_label" msgid="6968372297018755815">"სიკაშკაშე"</string>
+    <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"ავტოროტაცია"</string>
+    <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"როტაციის ჩაკეტვა"</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>
+    <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"მხოლოდ გადაუდებელი დახმარების ზარებისთვის"</string>
+    <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_wifi_label" msgid="9135344704899546041">"Wi-Fi"</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_display_label" msgid="6893592964463624333">"Wi-Fi ეკრანი"</string>
+    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"უსადენო ეკრანი"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"განათება"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ავტომატურად"</string>
+    <string name="status_bar_help_title" msgid="1199237744086469217">"შეტყობინებები აქ გამოჩნდება"</string>
+    <string name="status_bar_help_text" msgid="7874607155052076323">"მათზე წვდომისათვის, ნებისმიერ დროს გადაფურცლეთ ქვემოთ.\nსისტემის კონტროლისთვისაც გადაფურცლეთ ქვემოთ."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-km-rKH-land/strings.xml b/packages/SystemUI/res/values-km-rKH-land/strings.xml
new file mode 100644
index 0000000..f148cc3
--- /dev/null
+++ b/packages/SystemUI/res/values-km-rKH-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * 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.
+ */
+ -->
+
+<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>
+</resources>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
new file mode 100644
index 0000000..5e0318d
--- /dev/null
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -0,0 +1,201 @@
+<?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: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_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="6576392951053994640">"គ្មាន​កម្មវិធី​ថ្មីៗ"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"បដិសេធ​កម្មវិធី​ថ្មីៗ"</string>
+  <plurals name="status_bar_accessibility_recent_apps">
+    <item quantity="one" msgid="5854176083865845541">"កម្មវិធី​ថ្មី ១"</item>
+    <item quantity="other" msgid="1040784359794890744">"កម្មវិធី​ថ្មីៗ %d"</item>
+  </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="battery_low_title" msgid="2783104807551211639">"ភ្ជាប់​ឧបករណ៍​បញ្ចូល​ថ្ម"</string>
+    <string name="battery_low_subtitle" msgid="1752040062087829196">"ជិត​អស់​ថ្ម​ហើយ។"</string>
+    <string name="battery_low_percent_format" msgid="1077244949318261761">"នៅ​សល់ <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"មិន​គាំទ្រ​ការ​បញ្ចូល​តាម​យូអេសប៊ី។\nប្រើ​តែ​ឧបករណ៍​បញ្ចូល​ថ្ម​ដែល​បាន​ផ្ដល់។"</string>
+    <string name="battery_low_why" msgid="7279169609518386372">"ការ​ប្រើ​ថ្ម"</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_airplane" msgid="4879879698500955300">"ពេល​ជិះ​យន្តហោះ"</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">"បាន​ភ្ជាប់​ប៊្លូធូស"</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> ចូល​ដំណើរការ​ឧបករណ៍​យូអេសប៊ី?"</string>
+    <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"ឲ្យ​កម្មវិធី <xliff:g id="APPLICATION">%1$s</xliff:g> ចូល​ដំណើរការ​ឧបករណ៍​យូអេសប៊ី?"</string>
+    <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"បើក <xliff:g id="ACTIVITY">%1$s</xliff:g> ពេល​បាន​ភ្ជាប់​ឧបករណ៍​យូអេសប៊ី​នេះ?"</string>
+    <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"បើក <xliff:g id="ACTIVITY">%1$s</xliff:g> ពេល​បាន​ភ្ជាប់​ឧបករណ៍​យូអេសប៊ី?"</string>
+    <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"គ្មាន​កម្មវិធី​បាន​ដំឡើង​ដំណើរការ​ជា​មួយ​ឧបករណ៍​យូអេសប៊ី។ ស្វែងយល់​បន្ថែម​អំពី​ឧបករណ៍​នេះ​នៅ <xliff:g id="URL">%1$s</xliff:g>"</string>
+    <string name="title_usb_accessory" msgid="4966265263465181372">"ឧបករណ៍​យូអេសប៊ី"</string>
+    <string name="label_view" msgid="6304565553218192990">"មើល"</string>
+    <string name="always_use_device" msgid="1450287437017315906">"ប្រើ​តាម​លំនាំដើម​សម្រាប់​ឧបករណ៍​យូអេសប៊ី​នេះ"</string>
+    <string name="always_use_accessory" msgid="1210954576979621596">"ប្រើ​តាម​លំនាំដើម​សម្រាប់​ខ្សែ​យូអេសប៊ី​នេះ"</string>
+    <string name="usb_debugging_title" msgid="4513918393387141949">"អនុញ្ញាត​ការ​កែ​កំហុស​យូអេសប៊ី?"</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="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_saved_text" msgid="1152839647677558815">"ប៉ះ ​ដើម្បី​មើល​រូបថត​អេក្រង់​របស់​អ្នក​។"</string>
+    <string name="screenshot_failed_title" msgid="705781116746922771">"មិន​អាច​ចាប់​យក​រូប​ថត​អេក្រង់​។"</string>
+    <string name="screenshot_failed_text" msgid="8134011269572415402">"មិន​អាច​រក្សាទុក​រូបថត​អេក្រង់​។ ឧបករណ៍​ផ្ទុក​អាច​កំពុង​ប្រើ​​។"</string>
+    <string name="usb_preference_title" msgid="6551050377388882787">"ជម្រើស​ផ្ទេរ​ឯកសារ​តាម​យូអេសប៊ី"</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">"ដំឡើង​កម្មវិធី​ផ្ទេរ​ឯកសារ Android សម្រាប់ Mac"</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_recent" msgid="8571350598987952883">"កម្មវិធី​ថ្មីៗ"</string>
+    <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"ប្ដូរ​ប៊ូតុង​វិធីសាស្ត្រ​បញ្ចូល។"</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_no_battery" msgid="358343022352820946">"គ្មាន​ថ្ម។"</string>
+    <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"ថ្ម​មួយ​កាំ។"</string>
+    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"ថ្ម​ពីរ​កាំ។"</string>
+    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"ថ្ម​ទាំង​បី​​កាំ​។"</string>
+    <string name="accessibility_battery_full" msgid="8909122401720158582">"ថ្ម​ពេញ​ហើយ។"</string>
+    <string name="accessibility_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_off" msgid="3177380296697933627">"បិទ​វ៉ាយហ្វាយ។"</string>
+    <string name="accessibility_no_wifi" msgid="1425476551827924474">"បាន​ផ្ដាច់​វ៉ាយហ្វាយ។"</string>
+    <string name="accessibility_wifi_one_bar" msgid="7735893178010724377">"សញ្ញា​វ៉ាយហ្វាយ​មួយ​កាំ។"</string>
+    <string name="accessibility_wifi_two_bars" msgid="4994274250497262434">"សេវា​វ៉ាយហ្វាយ​ពីរ​កាំ។"</string>
+    <string name="accessibility_wifi_three_bars" msgid="3495755044276588384">"វ៉ាយហ្វាយ​បី​កាំ។"</string>
+    <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"សញ្ញា​វ៉ាយហ្វាយ​ពេញ។"</string>
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"គ្មាន WiMAX ។"</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX មួយ​កាំ។"</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX ពីរ​កាំ។"</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX បី​កាំ។"</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"សញ្ញា WiMAX ពេញ។"</string>
+    <string name="accessibility_no_signal" msgid="7064645320782585167">"គ្មាន​សញ្ញា។"</string>
+    <string name="accessibility_not_connected" msgid="6395326276213402883">"មិន​បាន​តភ្ជាប់​។"</string>
+    <string name="accessibility_zero_bars" msgid="3806060224467027887">"សូន្យ​កាំ។"</string>
+    <string name="accessibility_one_bar" msgid="1685730113192081895">"មួយ​កាំ។"</string>
+    <string name="accessibility_two_bars" msgid="6437363648385206679">"ពីរ​កាំ។"</string>
+    <string name="accessibility_three_bars" msgid="2648241415119396648">"បី​កាំ។"</string>
+    <string name="accessibility_signal_full" msgid="9122922886519676839">"សញ្ញា​ពេញ​​។"</string>
+    <string name="accessibility_desc_on" msgid="2385254693624345265">"បើក។"</string>
+    <string name="accessibility_desc_off" msgid="6475508157786853157">"បិទ"</string>
+    <string name="accessibility_desc_connected" msgid="8366256693719499665">"បាន​តភ្ជាប់។"</string>
+    <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+    <string name="accessibility_data_connection_1x" msgid="994133468120244018">"1 X"</string>
+    <string name="accessibility_data_connection_hspa" msgid="2032328855462645198">"HSPA"</string>
+    <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+    <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+    <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+    <string name="accessibility_data_connection_lte" msgid="5413468808637540658">"LTE"</string>
+    <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_no_sim" msgid="8274017118472455155">"គ្មាន​ស៊ីម​កាត។"</string>
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"ការ​ភ្ជាប់​ប៊្លូធូស។"</string>
+    <string name="accessibility_airplane_mode" msgid="834748999790763092">"របៀប​​ជិះ​យន្តហោះ"</string>
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"ថ្ម <xliff:g id="NUMBER">%d</xliff:g> ភាគរយ។"</string>
+    <string name="accessibility_settings_button" msgid="799583911231893380">"ការ​កំណត់​ប្រព័ន្ធ​។"</string>
+    <string name="accessibility_notifications_button" msgid="4498000369779421892">"ការ​ជូន​ដំណឹង។"</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_silent" msgid="9061243307939135383">"កម្មវិធី​រោទ៍​ស្ងាត់។"</string>
+    <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> បដិសេធ។"</string>
+    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"បាន​បដិសេធ​ការ​ជូនដំណឹង"</string>
+    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"ពណ៌​ការ​ជូន​ដំណឹង"</string>
+    <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"ការ​កំណត់​រហ័ស។"</string>
+    <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"កម្មវិធី​ថ្មី​ៗ។"</string>
+    <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"អ្នក​ប្រើ <xliff:g id="USER">%s</xliff:g> ។"</string>
+    <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</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" msgid="4196876722090224753">"របៀប​ជិះ​យន្ត​ហោះ <xliff:g id="STATE">%s</xliff:g> ។"</string>
+    <string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"ប៊្លូធូស <xliff:g id="STATE">%s</xliff:g> ។"</string>
+    <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"កំណត់​សំឡេង​រោទ៍​សម្រាប់ <xliff:g id="TIME">%s</xliff:g> ។"</string>
+    <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"បាន​បិទ​ទិន្នន័យ 2G-3G"</string>
+    <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"បាន​បិទ​ទិន្នន័យ 4G"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"បាន​បិទ​ទិន្នន័យ​ចល័ត"</string>
+    <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"បាន​បិទ​ទិន្នន័យ"</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"អ្នក​បាន​ដល់​ដែន​កំណត់​ប្រើ​ទិន្នន័យ​បាន​បញ្ជាក់។\n\nបើ​អ្នក​បើក​ទិន្នន័យ​ឡើងវិញ អ្នក​អាច​ត្រូវ​បាន​ប្ដូរ​ដោយ​ប្រតិបត្តិ​ករ។"</string>
+    <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"បើក​​ទិន្នន័យ​ឡើងវិញ"</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="accessibility_clear_all" msgid="5235938559247164925">"សម្អាត​ការ​ជូន​ដំណឹង​ទាំងអស់។"</string>
+    <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"ព័ត៌មាន​កម្មវិធី"</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="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="start_dreams" msgid="7219575858348719790">"ស្រមើ​ស្រមៃ"</string>
+    <string name="ethernet_label" msgid="7967563676324087464">"អ៊ីសឺរណិត"</string>
+    <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"របៀប​​ជិះ​យន្តហោះ"</string>
+    <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"បញ្ចូល​ថ្ម <xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"បាន​បញ្ចូល​ពេញ"</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_brightness_label" msgid="6968372297018755815">"ពន្លឺ"</string>
+    <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"បង្វិល​​ស្វ័យ​ប្រវត្តិ"</string>
+    <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"បាន​ចាក់​សោ​ការ​បង្វិល"</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>
+    <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"សម្រាប់​តែ​ការ​ហៅ​ពេល​អាសន្ន"</string>
+    <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_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">"បិទ​វ៉ាយហ្វាយ"</string>
+    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"បង្ហា​ញ​វ៉ាយហ្វាយ"</string>
+    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"​បង្ហាញ​បណ្ដាញ​ឥត​ខ្សែ"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"ពន្លឺ"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ស្វ័យប្រវត្តិ"</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"បណ្ដាញ​អាច​ត្រូវ​បាន​តាមដាន"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
new file mode 100644
index 0000000..f972925
--- /dev/null
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -0,0 +1,204 @@
+<?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: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_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="6576392951053994640">"គ្មាន​កម្មវិធី​ថ្មីៗ"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"បដិសេធ​កម្មវិធី​ថ្មីៗ"</string>
+  <plurals name="status_bar_accessibility_recent_apps">
+    <item quantity="one" msgid="5854176083865845541">"កម្មវិធី​ថ្មី ១"</item>
+    <item quantity="other" msgid="1040784359794890744">"កម្មវិធី​ថ្មីៗ %d"</item>
+  </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="battery_low_title" msgid="2783104807551211639">"ភ្ជាប់​ឧបករណ៍​បញ្ចូល​ថ្ម"</string>
+    <string name="battery_low_subtitle" msgid="1752040062087829196">"ជិត​អស់​ថ្ម​ហើយ។"</string>
+    <string name="battery_low_percent_format" msgid="1077244949318261761">"នៅ​សល់ <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"មិន​គាំទ្រ​ការ​បញ្ចូល​តាម​យូអេសប៊ី។\nប្រើ​តែ​ឧបករណ៍​បញ្ចូល​ថ្ម​ដែល​បាន​ផ្ដល់។"</string>
+    <string name="battery_low_why" msgid="7279169609518386372">"ការ​ប្រើ​ថ្ម"</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_airplane" msgid="4879879698500955300">"ពេល​ជិះ​យន្តហោះ"</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">"បាន​ភ្ជាប់​ប៊្លូធូស"</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> ចូល​ដំណើរការ​ឧបករណ៍​យូអេសប៊ី?"</string>
+    <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"ឲ្យ​កម្មវិធី <xliff:g id="APPLICATION">%1$s</xliff:g> ចូល​ដំណើរការ​ឧបករណ៍​យូអេសប៊ី?"</string>
+    <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"បើក <xliff:g id="ACTIVITY">%1$s</xliff:g> ពេល​បាន​ភ្ជាប់​ឧបករណ៍​យូអេសប៊ី​នេះ?"</string>
+    <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"បើក <xliff:g id="ACTIVITY">%1$s</xliff:g> ពេល​បាន​ភ្ជាប់​ឧបករណ៍​យូអេសប៊ី?"</string>
+    <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"គ្មាន​កម្មវិធី​បាន​ដំឡើង​ដំណើរការ​ជា​មួយ​ឧបករណ៍​យូអេសប៊ី។ ស្វែងយល់​បន្ថែម​អំពី​ឧបករណ៍​នេះ​នៅ <xliff:g id="URL">%1$s</xliff:g>"</string>
+    <string name="title_usb_accessory" msgid="4966265263465181372">"ឧបករណ៍​យូអេសប៊ី"</string>
+    <string name="label_view" msgid="6304565553218192990">"មើល"</string>
+    <string name="always_use_device" msgid="1450287437017315906">"ប្រើ​តាម​លំនាំដើម​សម្រាប់​ឧបករណ៍​យូអេសប៊ី​នេះ"</string>
+    <string name="always_use_accessory" msgid="1210954576979621596">"ប្រើ​តាម​លំនាំដើម​សម្រាប់​ខ្សែ​យូអេសប៊ី​នេះ"</string>
+    <string name="usb_debugging_title" msgid="4513918393387141949">"អនុញ្ញាត​ការ​កែ​កំហុស​យូអេសប៊ី?"</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="compat_mode_on" msgid="6623839244840638213">"ពង្រីក​​ដើម្បី​ឲ្យ​ពេញ​អេក្រង់"</string>
+    <string name="compat_mode_off" msgid="4434467572461327898">"ទាញ​ដើម្បី​ឲ្យ​ពេញ​អេក្រង់"</string>
+    <string name="compat_mode_help_header" msgid="7969493989397529910">"ការ​ពង្រីក​ត្រូវ​គ្នា"</string>
+    <string name="compat_mode_help_body" msgid="4946726776359270040">"ពេល​កម្មវិធី​ត្រូវ​បាន​រៀបចំ​សម្រាប់​អេក្រង់​តូច ការ​គ្រប់គ្រង​ការ​ពង្រីក​នឹង​បង្ហាញ​តាម​នាឡិកា។"</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="1152839647677558815">"ប៉ះ ​ដើម្បី​មើល​រូបថត​អេក្រង់​របស់​អ្នក​។"</string>
+    <string name="screenshot_failed_title" msgid="705781116746922771">"មិន​អាច​ចាប់​យក​រូប​ថត​អេក្រង់​។"</string>
+    <string name="screenshot_failed_text" msgid="8134011269572415402">"មិន​អាច​រក្សាទុក​រូបថត​អេក្រង់​។ ឧបករណ៍​ផ្ទុក​អាច​កំពុង​ប្រើ​​។"</string>
+    <string name="usb_preference_title" msgid="6551050377388882787">"ជម្រើស​ផ្ទេរ​ឯកសារ​តាម​យូអេសប៊ី"</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">"ដំឡើង​កម្មវិធី​ផ្ទេរ​ឯកសារ Android សម្រាប់ Mac"</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_recent" msgid="8571350598987952883">"កម្មវិធី​ថ្មីៗ"</string>
+    <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"ប្ដូរ​ប៊ូតុង​វិធីសាស្ត្រ​បញ្ចូល។"</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_no_battery" msgid="358343022352820946">"គ្មាន​ថ្ម។"</string>
+    <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"ថ្ម​មួយ​កាំ។"</string>
+    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"ថ្ម​ពីរ​កាំ។"</string>
+    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"ថ្ម​ទាំង​បី​​កាំ​។"</string>
+    <string name="accessibility_battery_full" msgid="8909122401720158582">"ថ្ម​ពេញ​ហើយ។"</string>
+    <string name="accessibility_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_off" msgid="3177380296697933627">"បិទ​វ៉ាយហ្វាយ។"</string>
+    <string name="accessibility_no_wifi" msgid="1425476551827924474">"បាន​ផ្ដាច់​វ៉ាយហ្វាយ។"</string>
+    <string name="accessibility_wifi_one_bar" msgid="7735893178010724377">"សញ្ញា​វ៉ាយហ្វាយ​មួយ​កាំ។"</string>
+    <string name="accessibility_wifi_two_bars" msgid="4994274250497262434">"សេវា​វ៉ាយហ្វាយ​ពីរ​កាំ។"</string>
+    <string name="accessibility_wifi_three_bars" msgid="3495755044276588384">"វ៉ាយហ្វាយ​បី​កាំ។"</string>
+    <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"សញ្ញា​វ៉ាយហ្វាយ​ពេញ។"</string>
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"គ្មាន WiMAX ។"</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX មួយ​កាំ។"</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX ពីរ​កាំ។"</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX បី​កាំ។"</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"សញ្ញា WiMAX ពេញ។"</string>
+    <string name="accessibility_no_signal" msgid="7064645320782585167">"គ្មាន​សញ្ញា។"</string>
+    <string name="accessibility_not_connected" msgid="6395326276213402883">"មិន​បាន​តភ្ជាប់​។"</string>
+    <string name="accessibility_zero_bars" msgid="3806060224467027887">"សូន្យ​កាំ។"</string>
+    <string name="accessibility_one_bar" msgid="1685730113192081895">"មួយ​កាំ។"</string>
+    <string name="accessibility_two_bars" msgid="6437363648385206679">"ពីរ​កាំ។"</string>
+    <string name="accessibility_three_bars" msgid="2648241415119396648">"បី​កាំ។"</string>
+    <string name="accessibility_signal_full" msgid="9122922886519676839">"សញ្ញា​ពេញ​​។"</string>
+    <string name="accessibility_desc_on" msgid="2385254693624345265">"បើក។"</string>
+    <string name="accessibility_desc_off" msgid="6475508157786853157">"បិទ"</string>
+    <string name="accessibility_desc_connected" msgid="8366256693719499665">"បាន​តភ្ជាប់។"</string>
+    <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+    <string name="accessibility_data_connection_1x" msgid="994133468120244018">"1 X"</string>
+    <string name="accessibility_data_connection_hspa" msgid="2032328855462645198">"HSPA"</string>
+    <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+    <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+    <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+    <string name="accessibility_data_connection_lte" msgid="5413468808637540658">"LTE"</string>
+    <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_no_sim" msgid="8274017118472455155">"គ្មាន​ស៊ីម​កាត។"</string>
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"ការ​ភ្ជាប់​ប៊្លូធូស។"</string>
+    <string name="accessibility_airplane_mode" msgid="834748999790763092">"របៀប​​ជិះ​យន្តហោះ"</string>
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"ថ្ម <xliff:g id="NUMBER">%d</xliff:g> ភាគរយ។"</string>
+    <string name="accessibility_settings_button" msgid="799583911231893380">"ការ​កំណត់​ប្រព័ន្ធ​។"</string>
+    <string name="accessibility_notifications_button" msgid="4498000369779421892">"ការ​ជូន​ដំណឹង។"</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_silent" msgid="9061243307939135383">"កម្មវិធី​រោទ៍​ស្ងាត់។"</string>
+    <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> បដិសេធ។"</string>
+    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"បាន​បដិសេធ​ការ​ជូនដំណឹង"</string>
+    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"ពណ៌​ការ​ជូន​ដំណឹង"</string>
+    <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"ការ​កំណត់​រហ័ស។"</string>
+    <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"កម្មវិធី​ថ្មី​ៗ។"</string>
+    <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"អ្នក​ប្រើ <xliff:g id="USER">%s</xliff:g> ។"</string>
+    <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</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" msgid="4196876722090224753">"របៀប​ជិះ​យន្ត​ហោះ <xliff:g id="STATE">%s</xliff:g> ។"</string>
+    <string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"ប៊្លូធូស <xliff:g id="STATE">%s</xliff:g> ។"</string>
+    <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"កំណត់​សំឡេង​រោទ៍​សម្រាប់ <xliff:g id="TIME">%s</xliff:g> ។"</string>
+    <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"បាន​បិទ​ទិន្នន័យ 2G-3G"</string>
+    <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"បាន​បិទ​ទិន្នន័យ 4G"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"បាន​បិទ​ទិន្នន័យ​ចល័ត"</string>
+    <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"បាន​បិទ​ទិន្នន័យ"</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"អ្នក​បាន​ដល់​ដែន​កំណត់​ប្រើ​ទិន្នន័យ​បាន​បញ្ជាក់។\n\nបើ​អ្នក​បើក​ទិន្នន័យ​ឡើងវិញ អ្នក​អាច​ត្រូវ​បាន​ប្ដូរ​ដោយ​ប្រតិបត្តិ​ករ។"</string>
+    <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"បើក​​ទិន្នន័យ​ឡើងវិញ"</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="accessibility_clear_all" msgid="5235938559247164925">"សម្អាត​ការ​ជូន​ដំណឹង​ទាំងអស់។"</string>
+    <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"ព័ត៌មាន​កម្មវិធី"</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="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="start_dreams" msgid="7219575858348719790">"ស្រមើ​ស្រមៃ"</string>
+    <string name="ethernet_label" msgid="7967563676324087464">"អ៊ីសឺរណិត"</string>
+    <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"របៀប​​ជិះ​យន្តហោះ"</string>
+    <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"បញ្ចូល​ថ្ម <xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"បាន​បញ្ចូល​ពេញ"</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_brightness_label" msgid="6968372297018755815">"ពន្លឺ"</string>
+    <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"បង្វិល​​ស្វ័យ​ប្រវត្តិ"</string>
+    <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"បាន​ចាក់​សោ​ការ​បង្វិល"</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>
+    <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"សម្រាប់​តែ​ការ​ហៅ​ពេល​អាសន្ន"</string>
+    <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_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">"បិទ​វ៉ាយហ្វាយ"</string>
+    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"បង្ហា​ញ​វ៉ាយហ្វាយ"</string>
+    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"​បង្ហាញ​បណ្ដាញ​ឥត​ខ្សែ"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"ពន្លឺ"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ស្វ័យប្រវត្តិ"</string>
+    <string name="status_bar_help_title" msgid="1199237744086469217">"ការ​ជូន​ដំណឹង​​បង្ហាញ​​នៅ​ទីនេះ"</string>
+    <string name="status_bar_help_text" msgid="7874607155052076323">"ចូល​ដំណើរការ​ពួក​វា​ពេល​ណា​មួយ​ដោយ​អូស​ចុះក្រោម។\nអូស​ចុះក្រោម​ម្ដង​ទៀត​ ដើម្បី​ពិនិត្យ​ប្រព័ន្ធ។"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index eb583e1..7711bd5 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"시스템 UI"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"지우기"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"응답 거부"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"알림 표시"</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="6576392951053994640">"최근에 사용한 앱 없음"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"충전기를 연결하세요."</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"배터리가 얼마 남지 않았습니다."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> 남음"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"USB 충전이 지원되지 않습니다."\n"제공된 충전기만 사용하세요."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB 충전이 지원되지 않습니다.\n제공된 충전기만 사용하세요."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"배터리 사용량"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"설정"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <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="compat_mode_on" msgid="6623839244840638213">"전체화면 모드로 확대"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"전체화면 모드로 확대"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"호환성 확대/축소"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"앱이 작은 화면에 맞도록 설계된 경우 시계 옆에 확대/축소 컨트롤이 표시됩니다."</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>
@@ -160,17 +156,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G 데이터 사용중지됨"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"모바일 데이터 사용중지됨"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"데이터 사용중지됨"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"지정된 데이터 사용 한도에 도달했습니다."\n\n"데이터 연결을 다시 사용하면 통신사에서 요금이 부과될 수도 있습니다."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"지정된 데이터 사용 한도에 도달했습니다.\n\n데이터 연결을 다시 사용하면 통신사에서 요금이 부과될 수도 있습니다."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"데이터 연결 다시 사용"</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="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="accessibility_clear_all" msgid="5235938559247164925">"모든 알림 지우기"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"앱 정보"</string>
-    <string name="close_universe" msgid="3736513750241754348">"닫기"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"알림 사용 안함"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"알림을 다시 사용하려면 여기를 터치하세요."</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>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"자동 회전"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"회전 잠금"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"입력 방법"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"위치 사용 중"</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>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"무선 디스플레이"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"밝기"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"자동"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"알림이 여기에 표시됨"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"아래로 스와이프하여 언제든 액세스하세요."\n"한 번 더 아래로 스와이프하면 시스템 관리로 이동합니다."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"네트워크가 모니터링될 수 있음"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lo-rLA-land/strings.xml b/packages/SystemUI/res/values-lo-rLA-land/strings.xml
new file mode 100644
index 0000000..a838a15
--- /dev/null
+++ b/packages/SystemUI/res/values-lo-rLA-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * 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.
+ */
+ -->
+
+<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>
+</resources>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
new file mode 100644
index 0000000..e62c4f3
--- /dev/null
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -0,0 +1,201 @@
+<?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: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_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="6576392951053994640">"ບໍ່ມີແອັບຯທີ່ຫາກໍໃຊ້"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"ປິດແອັບຯຫຼ້າສຸດທີ່ໃຊ້"</string>
+  <plurals name="status_bar_accessibility_recent_apps">
+    <item quantity="one" msgid="5854176083865845541">"1 ແອັບຯຫຼ້າສຸດ"</item>
+    <item quantity="other" msgid="1040784359794890744">"%d ແອັບຯຫຼ້າສຸດ"</item>
+  </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="battery_low_title" msgid="2783104807551211639">"ເຊື່ອມຕໍ່ສາຍສາກ"</string>
+    <string name="battery_low_subtitle" msgid="1752040062087829196">"ແບັດເຕີຣີເຫຼືອໜ້ອຍແລ້ວ."</string>
+    <string name="battery_low_percent_format" msgid="1077244949318261761">"ຍັງເຫຼືອອີກ <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"ບໍ່ຮອງຮັບການສາກໄຟດ້ວຍ USB.\nຕ້ອງໃຊ້ສະເພາະເຄື່ອງສາກທີ່ແຖມມານຳເທົ່ານັ້ນ."</string>
+    <string name="battery_low_why" msgid="7279169609518386372">"ການນຳໃຊ້ແບັດເຕີຣີ"</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_airplane" msgid="4879879698500955300">"ໂໝດເທິງຍົນ"</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_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">"ເປີດ <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>
+    <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="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>
+    <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_saved_text" msgid="1152839647677558815">"ແຕະເພື່ອເບິ່ງພາບໜ້າຈໍຂອງທ່ານ."</string>
+    <string name="screenshot_failed_title" msgid="705781116746922771">"ບໍ່ສາມາດຖ່າຍຮູບໜ້າຈໍໄດ້"</string>
+    <string name="screenshot_failed_text" msgid="8134011269572415402">"ບໍ່ສາມາດບັນທຶກພາບໜ້າຈໍໄດ້. ບ່ອນຈັດເກັບອາດກຳລັງຖືກນຳໃຊ້ຢູ່."</string>
+    <string name="usb_preference_title" msgid="6551050377388882787">"USB ໂຕເລືອກການຍ້າຍໄຟລ໌"</string>
+    <string name="use_mtp_button_title" msgid="4333504413563023626">"ເຊື່ອມຕໍ່ເປັນ media player (MTP)"</string>
+    <string name="use_ptp_button_title" msgid="7517127540301625751">"ເຊື່ອມຕໍ່ເປັນກ້ອງຖ່າຍຮູບ (PTP)"</string>
+    <string name="installer_cd_button_title" msgid="2312667578562201583">"ຕິດຕັ້ງແອັບຯ Android File Transfer ສຳລັບ Mac"</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_recent" msgid="8571350598987952883">"ແອັບຯຫຼ້າສຸດ"</string>
+    <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"ປຸ່ມສະລັບຮູບແບບການປ້ອນຂໍ້ມູນ."</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>
+    <string name="accessibility_no_battery" msgid="358343022352820946">"ແບັດເຕີຣີໝົດ."</string>
+    <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"ແບັດເຕີຣີນຶ່ງຂີດ."</string>
+    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"ແບັດເຕີຣີສອງຂີດ."</string>
+    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"ແບັດເຕີຣີສາມຂີດ."</string>
+    <string name="accessibility_battery_full" msgid="8909122401720158582">"ແບັດເຕີຣີເຕັມ."</string>
+    <string name="accessibility_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_off" msgid="3177380296697933627">"WiFi ປິດຢູ່."</string>
+    <string name="accessibility_no_wifi" msgid="1425476551827924474">"ຕັດການເຊື່ອມຕໍ່ Wi-Fi ແລ້ວ."</string>
+    <string name="accessibility_wifi_one_bar" msgid="7735893178010724377">"ສັນຍານ Wi-Fi ນຶ່ງຂີດ."</string>
+    <string name="accessibility_wifi_two_bars" msgid="4994274250497262434">"ສັນຍານ Wi-Fi ສອງຂີດ."</string>
+    <string name="accessibility_wifi_three_bars" msgid="3495755044276588384">"Wifi ສາມຂີດ."</string>
+    <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"ສັນຍານ Wi-Fi ເຕັມ"</string>
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"ບໍ່ມີ WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX ນຶ່ງຂີດ."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX ສອງຂີດ."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX ສາມຂີດ."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"ສັນ​ຍານ WiMAX ເຕັມ."</string>
+    <string name="accessibility_no_signal" msgid="7064645320782585167">"ບໍ່ມີສັນຍານ."</string>
+    <string name="accessibility_not_connected" msgid="6395326276213402883">"ບໍ່ໄດ້ເຊື່ອມຕໍ່."</string>
+    <string name="accessibility_zero_bars" msgid="3806060224467027887">"ບໍ່ມີຈັກຂີດ."</string>
+    <string name="accessibility_one_bar" msgid="1685730113192081895">"ນຶ່ງຂີດ."</string>
+    <string name="accessibility_two_bars" msgid="6437363648385206679">"ສອງຂີດ."</string>
+    <string name="accessibility_three_bars" msgid="2648241415119396648">"ສາມຂີດ."</string>
+    <string name="accessibility_signal_full" msgid="9122922886519676839">"ສັນຍານເຕັມ."</string>
+    <string name="accessibility_desc_on" msgid="2385254693624345265">"ເປີດ."</string>
+    <string name="accessibility_desc_off" msgid="6475508157786853157">"ປິດ."</string>
+    <string name="accessibility_desc_connected" msgid="8366256693719499665">"ເຊື່ອມ​ຕໍ່ແລ້ວ."</string>
+    <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+    <string name="accessibility_data_connection_1x" msgid="994133468120244018">"1 X"</string>
+    <string name="accessibility_data_connection_hspa" msgid="2032328855462645198">"HSPA"</string>
+    <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+    <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+    <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+    <string name="accessibility_data_connection_lte" msgid="5413468808637540658">"LTE"</string>
+    <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">"ບໍ່ມີຊິມ."</string>
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"ການປ່ອຍສັນຍານ Bluetooth."</string>
+    <string name="accessibility_airplane_mode" msgid="834748999790763092">"ໂໝດໃນຍົນ."</string>
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"ແບັດເຕີຣີ <xliff:g id="NUMBER">%d</xliff:g> ເປີເຊັນ."</string>
+    <string name="accessibility_settings_button" msgid="799583911231893380">"ການຕັ້ງຄ່າລະບົບ."</string>
+    <string name="accessibility_notifications_button" msgid="4498000369779421892">"ການແຈ້ງເຕືອນ."</string>
+    <string name="accessibility_remove_notification" msgid="3603099514902182350">"ລຶບລ້າງການແຈ້ງເຕືອນ."</string>
+    <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS ເປີດແລ້ວ."</string>
+    <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"ກຳລັງຊອກຫາ GPS."</string>
+    <string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter ຖືກເປີດຢູ່."</string>
+    <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"ສັ່ນເຕືອນພ້ອມສຽງເອີ້ນເຂົ້າ."</string>
+    <string name="accessibility_ringer_silent" msgid="9061243307939135383">"ປິດສຽງ."</string>
+    <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"ປິດ <xliff:g id="APP">%s</xliff:g> ແລ້ວ."</string>
+    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"ປິດການແຈ້ງເຕືອນແລ້ວ."</string>
+    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"ໜ້າຈໍແຈ້ງເຕືອນ."</string>
+    <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"ການຕັ້ງຄ່າດ່ວນ."</string>
+    <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"ແອັບຯທີ່ຫາກໍໃຊ້."</string>
+    <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"ຜູ່ໃຊ້ <xliff:g id="USER">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</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" msgid="4196876722090224753">"ໂໝດໃນຍົນ <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"ຕັ້ງໂມງປຸກ <xliff:g id="TIME">%s</xliff:g> ແລ້ວ."</string>
+    <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"ອິນເຕີເນັດ 2G​, 3G ຖືກປິດແລ້ວ"</string>
+    <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"ການນຳໃຊ້ຂໍ້ມູນ 4G ຖືກປິດແລ້ວ"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"ອິນເຕີເນັດໃນມືຖືຖືກປິດການນຳໃຊ້ແລ້ວ"</string>
+    <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"ອິນເຕີເນັດຖືກປິດການນຳໃຊ້ແລ້ວ"</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"ທ່ານໄດ້ໃຊ້ຂໍ້ມູນຈົນຮອດຈຳນວນທີ່ຈຳກັດໄວ້ແລ້ວ.\n\nຫາກທ່ານເປີດນຳໃຊ້ຂໍ້ມູນຄືນອີກຄັ້ງ, ທ່ານອາດຖືກຮຽກເກັບເງິນໂດຍຜູ່ໃຫ້ບໍລິການໄດ້."</string>
+    <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"ເປີດນຳໃຊ້ຂໍ້ມູນຄືນໃໝ່"</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="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="accessibility_clear_all" msgid="5235938559247164925">"ລຶບການແຈ້ງເຕືອນທັງໝົດ."</string>
+    <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"ຂໍ້ມູນແອັບຯ"</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="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="start_dreams" msgid="7219575858348719790">"Daydream"</string>
+    <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"ໂໝດຢູ່ໃນຍົນ"</string>
+    <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"ກຳລັງສາກ, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"ສາກເຕັມແລ້ວ"</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_brightness_label" msgid="6968372297018755815">"ຄວາມສະຫວ່າງ"</string>
+    <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"ໝຸນໜ້າຈໍອັດຕະໂນມັດ"</string>
+    <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"ລັອກການປ່ຽນລວງ"</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>
+    <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"ໂທສຸກເສີນເທົ່ານັ້ນ"</string>
+    <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_wifi_label" msgid="9135344704899546041">"Wi​-Fi"</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_display_label" msgid="6893592964463624333">"ຈໍສະແດງຜົນ Wi-Fi"</string>
+    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"ການສະແດງຜົນໄຮ້ສາຍ"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"ຄວາມແຈ້ງ"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ອັດຕະໂນມັດ"</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"ການນຳໃຊ້ເຄືອຂ່າຍອາດມີການກວດສອບຕິດຕາມ"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
new file mode 100644
index 0000000..85b10f7
--- /dev/null
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -0,0 +1,204 @@
+<?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: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_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="6576392951053994640">"ບໍ່ມີແອັບຯທີ່ຫາກໍໃຊ້"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"ປິດແອັບຯຫຼ້າສຸດທີ່ໃຊ້"</string>
+  <plurals name="status_bar_accessibility_recent_apps">
+    <item quantity="one" msgid="5854176083865845541">"1 ແອັບຯຫຼ້າສຸດ"</item>
+    <item quantity="other" msgid="1040784359794890744">"%d ແອັບຯຫຼ້າສຸດ"</item>
+  </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="battery_low_title" msgid="2783104807551211639">"ເຊື່ອມຕໍ່ສາຍສາກ"</string>
+    <string name="battery_low_subtitle" msgid="1752040062087829196">"ແບັດເຕີຣີເຫຼືອໜ້ອຍແລ້ວ."</string>
+    <string name="battery_low_percent_format" msgid="1077244949318261761">"ຍັງເຫຼືອອີກ <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"ບໍ່ຮອງຮັບການສາກໄຟດ້ວຍ USB.\nຕ້ອງໃຊ້ສະເພາະເຄື່ອງສາກທີ່ແຖມມານຳເທົ່ານັ້ນ."</string>
+    <string name="battery_low_why" msgid="7279169609518386372">"ການນຳໃຊ້ແບັດເຕີຣີ"</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_airplane" msgid="4879879698500955300">"ໂໝດເທິງຍົນ"</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_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">"ເປີດ <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>
+    <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="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>
+    <string name="compat_mode_on" msgid="6623839244840638213">"ຊູມໃຫ້ເຕັມໜ້າຈໍ"</string>
+    <string name="compat_mode_off" msgid="4434467572461327898">"ປັບໃຫ້ເຕັມໜ້າຈໍ"</string>
+    <string name="compat_mode_help_header" msgid="7969493989397529910">"ຄວາມເຂົ້າກັນໄດ້ຂອງການຊູມ"</string>
+    <string name="compat_mode_help_body" msgid="4946726776359270040">"ເມື່ອແອັບຯຖືກອອກແບບມາສຳລັບໜ້າຈໍນ້ອຍກວ່າ​, ຕົວຄວບຄຸມການຊູມຈະປາກົດຢູ່ໃກ້ກັບໂມງ."</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="1152839647677558815">"ແຕະເພື່ອເບິ່ງພາບໜ້າຈໍຂອງທ່ານ."</string>
+    <string name="screenshot_failed_title" msgid="705781116746922771">"ບໍ່ສາມາດຖ່າຍຮູບໜ້າຈໍໄດ້"</string>
+    <string name="screenshot_failed_text" msgid="8134011269572415402">"ບໍ່ສາມາດບັນທຶກພາບໜ້າຈໍໄດ້. ບ່ອນຈັດເກັບອາດກຳລັງຖືກນຳໃຊ້ຢູ່."</string>
+    <string name="usb_preference_title" msgid="6551050377388882787">"USB ໂຕເລືອກການຍ້າຍໄຟລ໌"</string>
+    <string name="use_mtp_button_title" msgid="4333504413563023626">"ເຊື່ອມຕໍ່ເປັນ media player (MTP)"</string>
+    <string name="use_ptp_button_title" msgid="7517127540301625751">"ເຊື່ອມຕໍ່ເປັນກ້ອງຖ່າຍຮູບ (PTP)"</string>
+    <string name="installer_cd_button_title" msgid="2312667578562201583">"ຕິດຕັ້ງແອັບຯ Android File Transfer ສຳລັບ Mac"</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_recent" msgid="8571350598987952883">"ແອັບຯຫຼ້າສຸດ"</string>
+    <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"ປຸ່ມສະລັບຮູບແບບການປ້ອນຂໍ້ມູນ."</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>
+    <string name="accessibility_no_battery" msgid="358343022352820946">"ແບັດເຕີຣີໝົດ."</string>
+    <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"ແບັດເຕີຣີນຶ່ງຂີດ."</string>
+    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"ແບັດເຕີຣີສອງຂີດ."</string>
+    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"ແບັດເຕີຣີສາມຂີດ."</string>
+    <string name="accessibility_battery_full" msgid="8909122401720158582">"ແບັດເຕີຣີເຕັມ."</string>
+    <string name="accessibility_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_off" msgid="3177380296697933627">"WiFi ປິດຢູ່."</string>
+    <string name="accessibility_no_wifi" msgid="1425476551827924474">"ຕັດການເຊື່ອມຕໍ່ Wi-Fi ແລ້ວ."</string>
+    <string name="accessibility_wifi_one_bar" msgid="7735893178010724377">"ສັນຍານ Wi-Fi ນຶ່ງຂີດ."</string>
+    <string name="accessibility_wifi_two_bars" msgid="4994274250497262434">"ສັນຍານ Wi-Fi ສອງຂີດ."</string>
+    <string name="accessibility_wifi_three_bars" msgid="3495755044276588384">"Wifi ສາມຂີດ."</string>
+    <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"ສັນຍານ Wi-Fi ເຕັມ"</string>
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"ບໍ່ມີ WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX ນຶ່ງຂີດ."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX ສອງຂີດ."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX ສາມຂີດ."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"ສັນ​ຍານ WiMAX ເຕັມ."</string>
+    <string name="accessibility_no_signal" msgid="7064645320782585167">"ບໍ່ມີສັນຍານ."</string>
+    <string name="accessibility_not_connected" msgid="6395326276213402883">"ບໍ່ໄດ້ເຊື່ອມຕໍ່."</string>
+    <string name="accessibility_zero_bars" msgid="3806060224467027887">"ບໍ່ມີຈັກຂີດ."</string>
+    <string name="accessibility_one_bar" msgid="1685730113192081895">"ນຶ່ງຂີດ."</string>
+    <string name="accessibility_two_bars" msgid="6437363648385206679">"ສອງຂີດ."</string>
+    <string name="accessibility_three_bars" msgid="2648241415119396648">"ສາມຂີດ."</string>
+    <string name="accessibility_signal_full" msgid="9122922886519676839">"ສັນຍານເຕັມ."</string>
+    <string name="accessibility_desc_on" msgid="2385254693624345265">"ເປີດ."</string>
+    <string name="accessibility_desc_off" msgid="6475508157786853157">"ປິດ."</string>
+    <string name="accessibility_desc_connected" msgid="8366256693719499665">"ເຊື່ອມ​ຕໍ່ແລ້ວ."</string>
+    <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+    <string name="accessibility_data_connection_1x" msgid="994133468120244018">"1 X"</string>
+    <string name="accessibility_data_connection_hspa" msgid="2032328855462645198">"HSPA"</string>
+    <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+    <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+    <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+    <string name="accessibility_data_connection_lte" msgid="5413468808637540658">"LTE"</string>
+    <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">"ບໍ່ມີຊິມ."</string>
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"ການປ່ອຍສັນຍານ Bluetooth."</string>
+    <string name="accessibility_airplane_mode" msgid="834748999790763092">"ໂໝດໃນຍົນ."</string>
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"ແບັດເຕີຣີ <xliff:g id="NUMBER">%d</xliff:g> ເປີເຊັນ."</string>
+    <string name="accessibility_settings_button" msgid="799583911231893380">"ການຕັ້ງຄ່າລະບົບ."</string>
+    <string name="accessibility_notifications_button" msgid="4498000369779421892">"ການແຈ້ງເຕືອນ."</string>
+    <string name="accessibility_remove_notification" msgid="3603099514902182350">"ລຶບລ້າງການແຈ້ງເຕືອນ."</string>
+    <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS ເປີດແລ້ວ."</string>
+    <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"ກຳລັງຊອກຫາ GPS."</string>
+    <string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter ຖືກເປີດຢູ່."</string>
+    <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"ສັ່ນເຕືອນພ້ອມສຽງເອີ້ນເຂົ້າ."</string>
+    <string name="accessibility_ringer_silent" msgid="9061243307939135383">"ປິດສຽງ."</string>
+    <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"ປິດ <xliff:g id="APP">%s</xliff:g> ແລ້ວ."</string>
+    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"ປິດການແຈ້ງເຕືອນແລ້ວ."</string>
+    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"ໜ້າຈໍແຈ້ງເຕືອນ."</string>
+    <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"ການຕັ້ງຄ່າດ່ວນ."</string>
+    <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"ແອັບຯທີ່ຫາກໍໃຊ້."</string>
+    <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"ຜູ່ໃຊ້ <xliff:g id="USER">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</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" msgid="4196876722090224753">"ໂໝດໃນຍົນ <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"ຕັ້ງໂມງປຸກ <xliff:g id="TIME">%s</xliff:g> ແລ້ວ."</string>
+    <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"ອິນເຕີເນັດ 2G​, 3G ຖືກປິດແລ້ວ"</string>
+    <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"ການນຳໃຊ້ຂໍ້ມູນ 4G ຖືກປິດແລ້ວ"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"ອິນເຕີເນັດໃນມືຖືຖືກປິດການນຳໃຊ້ແລ້ວ"</string>
+    <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"ອິນເຕີເນັດຖືກປິດການນຳໃຊ້ແລ້ວ"</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"ທ່ານໄດ້ໃຊ້ຂໍ້ມູນຈົນຮອດຈຳນວນທີ່ຈຳກັດໄວ້ແລ້ວ.\n\nຫາກທ່ານເປີດນຳໃຊ້ຂໍ້ມູນຄືນອີກຄັ້ງ, ທ່ານອາດຖືກຮຽກເກັບເງິນໂດຍຜູ່ໃຫ້ບໍລິການໄດ້."</string>
+    <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"ເປີດນຳໃຊ້ຂໍ້ມູນຄືນໃໝ່"</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="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="accessibility_clear_all" msgid="5235938559247164925">"ລຶບການແຈ້ງເຕືອນທັງໝົດ."</string>
+    <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"ຂໍ້ມູນແອັບຯ"</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="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="start_dreams" msgid="7219575858348719790">"Daydream"</string>
+    <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"ໂໝດຢູ່ໃນຍົນ"</string>
+    <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"ກຳລັງສາກ, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"ສາກເຕັມແລ້ວ"</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_brightness_label" msgid="6968372297018755815">"ຄວາມສະຫວ່າງ"</string>
+    <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"ໝຸນໜ້າຈໍອັດຕະໂນມັດ"</string>
+    <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"ລັອກການປ່ຽນລວງ"</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>
+    <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"ໂທສຸກເສີນເທົ່ານັ້ນ"</string>
+    <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_wifi_label" msgid="9135344704899546041">"Wi​-Fi"</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_display_label" msgid="6893592964463624333">"ຈໍສະແດງຜົນ Wi-Fi"</string>
+    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"ການສະແດງຜົນໄຮ້ສາຍ"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"ຄວາມແຈ້ງ"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ອັດຕະໂນມັດ"</string>
+    <string name="status_bar_help_title" msgid="1199237744086469217">"ການແຈ້ງເຕືອນຈະປາກົດບ່ອນນີ້"</string>
+    <string name="status_bar_help_text" msgid="7874607155052076323">"ເຂົ້າເຖິງໄດ້ທຸກເມື່ອໂດຍການປັດນິ້ວລົງ.\nປັດລົງອີກເທື່ອນຶ່ງສຳລັບການຄວບຄຸມລະບົບ."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 77d9e9a..173fbbf 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"Sistemos NS"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Išvalyti"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Netrukdyti"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Rodyti pranešimus"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Pašalinti iš sąrašo"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Programos informacija"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Nėra naujausių programų"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Prijunkite įkroviklį"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Akumuliatorius senka."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"Liko <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"USB krovimas nepalaikomas."\n"Naudokite tik pateiktą įkroviklį."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB krovimas nepalaikomas.\nNaudokite tik pateiktą įkroviklį."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Akumuliatoriaus naudojimas"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Nustatymai"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <string name="always_use_device" msgid="1450287437017315906">"Šiam USB įreng. naudoti pagal numat. nustatymus"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Šiam USB priedui naudoti pagal numat. nustatymus"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"Leisti USB derinimą?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"Šio kompiuterio RSA rakto kontrolinis kodas yra:"\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"Šio kompiuterio RSA rakto kontrolinis kodas yra:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Visada leisti iš šio kompiuterio"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Keisti mast., kad atit. ekr."</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Ištempti, kad atit. ekr."</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Suderinamumo mastelio keitimas"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Kai programa bus pritaikyta mažesniam ekranui, mastelio keitimo valdiklis bus parodytas šalia laikrodžio."</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Išsaugoma ekrano kopija..."</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"Išsaugoma ekrano kopija..."</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"Išsaugoma ekrano kopija."</string>
@@ -160,17 +156,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G duomenys neleidžiami"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobilieji duomenys neleidžiami"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Duomenys neleidžiami"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Pasiekėte nurodytą duomenų naudojimo apribojimą."\n\n"Jei iš naujo įgalinsite duomenis, jus gali apmokestinti operatorius."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Pasiekėte nurodytą duomenų naudojimo apribojimą.\n\nJei iš naujo įgalinsite duomenis, jus gali apmokestinti operatorius."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Iš naujo įgalinti duomenis"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Nėra interneto ryš."</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Prisij. prie „Wi-Fi“"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Ieškoma GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS nustatyta vieta"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Vietovės užklausos aktyvios"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Išvalyti visus pranešimus."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Programos informacija"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Uždaryti"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Pranešimai išjungti"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Jei norite vėl įjungti pranešimus, palieskite čia."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekranas bus sukamas automatiškai."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Užrakintas ekranas yra horizontalios orientacijos."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Užrakintas ekranas yra vertikalios orientacijos."</string>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Automatiškai sukti"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Sukimas užrakintas"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Įvesties metodas"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Naudojama vieta"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Vietovė"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Vietovė išjungta"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Medijos įrenginys"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Tik skambučiai pagalbos numeriu"</string>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Belaidis rodymas"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Skaistis"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATINIS"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Pranešimai rodomi čia"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Perbraukę žemyn bet kuriuo metu pasieksite pranešimus."\n"Jei norite naudoti sistemos valdiklius, perbraukite žemyn dar kartą."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Tinklas gali būti stebimas"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index f1a9727..bdb8975 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"Sistēmas UI"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Notīrīt"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Netraucēt"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Rādīt paziņojumus"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Noņemšana no saraksta"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Lietotnes informācija"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Nav nesen izmantotu lietotņu."</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Pievienojiet uzlādes ierīci."</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Akumulators drīz izlādēsies."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"Atlicis: <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"USB lādēšana netiek atbalstīta."\n"Izmantojiet tikai komplektā iekļauto lādētāju."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB lādēšana netiek atbalstīta.\nIzmantojiet tikai komplektā iekļauto lādētāju."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Akumulatora lietojums"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Iestatījumi"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <string name="always_use_device" msgid="1450287437017315906">"Pēc noklusējuma izmantot šai USB ierīcei"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Pēc noklusējuma izmantot šim USB piederumam"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"Vai atļaut USB atkļūdošanu?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"Datora RSA atslēgas ciparfails: "\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"Datora RSA atslēgas ciparfails: \n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Vienmēr atļaut no šī datora"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Tālumm., lai aizp. ekr."</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Stiepiet, lai aizp. ekr."</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Saderības tālummaiņa"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Ja lietotne ir paredzēta mazākam ekrānam, blakus pulkstenim tiks parādīta tālummaiņas vadīkla."</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Saglabā ekrānuzņēmumu…"</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"Notiek ekrānuzņēmuma saglabāšana..."</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"Notiek ekrānuzņēmuma saglabāšana."</string>
@@ -160,17 +156,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G dati atspējoti"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobilie dati atspējoti"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Dati atspējoti"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Ir sasniegts noteiktais datu lietošanas apjoma ierobežojums."\n\n"Ja atkārtoti iespējosiet datus, operators no jums var iekasēt maksu."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Ir sasniegts noteiktais datu lietošanas apjoma ierobežojums.\n\nJa atkārtoti iespējosiet datus, operators no jums var iekasēt maksu."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Atkārtoti iespējot datus"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Nav interneta sav."</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Izv. sav. ar Wi-Fi"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Notiek GPS meklēšana..."</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS iestatītā atrašanās vieta"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Aktīvi atrašanās vietu pieprasījumi"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Notīrīt visus paziņojumus"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informācija par lietotni"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Aizvērt"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Paziņojumi ir izslēgti"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Pieskarieties šeit, lai atkal ieslēgtu paziņojumus."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekrāns tiks pagriezts automātiski."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Ekrāns tagad ir bloķēts ainavas orientācijā."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Ekrāns tagad ir bloķēts portreta orientācijā."</string>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Automātiska pagriešana"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Pagriešana bloķēta"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Ievades metode"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Izmantotā atrašanās vieta"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Atrašanās vieta"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Atrašanās vieta izslēgta"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Multivides ierīce"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Tikai ārkārtas izsaukumi"</string>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Bezvadu attēlošana"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Spilgtums"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMĀTISKI"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Šeit tiek rādīti paziņojumi"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Piekļūstiet tiem jebkurā laikā, velkot uz leju."\n"Vēlreiz velciet, lai tiktu parādītas sistēmas vadīklas."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Iespējams, tīklā veiktās darbības tiek pārraudzītas."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mn-rMN-land/strings.xml b/packages/SystemUI/res/values-mn-rMN-land/strings.xml
new file mode 100644
index 0000000..ec4616f
--- /dev/null
+++ b/packages/SystemUI/res/values-mn-rMN-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * 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.
+ */
+ -->
+
+<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>
+</resources>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
new file mode 100644
index 0000000..6a548db
--- /dev/null
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -0,0 +1,201 @@
+<?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: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="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="6576392951053994640">"Сүүлийн апп хоосон"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Сүүлийн апп-уудыг хаах"</string>
+  <plurals name="status_bar_accessibility_recent_apps">
+    <item quantity="one" msgid="5854176083865845541">"1 сүүлийн апп"</item>
+    <item quantity="other" msgid="1040784359794890744">"%d сүүлийн апп"</item>
+  </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="battery_low_title" msgid="2783104807551211639">"Цэнэглэгчийг холбоно уу"</string>
+    <string name="battery_low_subtitle" msgid="1752040062087829196">"Батерей дуусаж байна."</string>
+    <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> үлдсэн"</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB цэнэглэлт дэмжигдэхгүй байна.\nЗөвхөн нийлүүлэгдсэн цэнэглэгчийг ашиглана уу."</string>
+    <string name="battery_low_why" msgid="7279169609518386372">"Батерей ашиглах"</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_airplane" msgid="4879879698500955300">"Нислэгийн горим"</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">"Блютүүтыг модем болгож байна"</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_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="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>
+    <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_saved_text" msgid="1152839647677558815">"Дэлгэцийн агшныг харах бол хүрнэ үү."</string>
+    <string name="screenshot_failed_title" msgid="705781116746922771">"Дэлгэцийн агшинг авч чадсангүй."</string>
+    <string name="screenshot_failed_text" msgid="8134011269572415402">"Дэлгэцийн агшинг хадгалж чадсангүй. Сан ашиглагдаж байгаа бололтой."</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">"Мас-д зориулсан  Андройд Файл Шилжүүлэх апп-г суулгана уу"</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_recent" msgid="8571350598987952883">"Сүүлийн апп"</string>
+    <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Оруулах аргыг сэлгэх товч."</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_no_battery" msgid="358343022352820946">"Батерей байхгүй."</string>
+    <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Батерей нэг баганатай."</string>
+    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Батерей хоёр баганатай."</string>
+    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Батерей гурван баганатай."</string>
+    <string name="accessibility_battery_full" msgid="8909122401720158582">"Батерей дүүрэн."</string>
+    <string name="accessibility_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_off" msgid="3177380296697933627">"Wifi унтарсан."</string>
+    <string name="accessibility_no_wifi" msgid="1425476551827924474">"Wifi салав."</string>
+    <string name="accessibility_wifi_one_bar" msgid="7735893178010724377">"Wifi нэг баганатай."</string>
+    <string name="accessibility_wifi_two_bars" msgid="4994274250497262434">"Wifi хоёр баганатай."</string>
+    <string name="accessibility_wifi_three_bars" msgid="3495755044276588384">"Wifi гурван баганатай."</string>
+    <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"Wifi дохио дүүрэн."</string>
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"WiMAX байхгүй."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX нэг багана."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX хоёр баганатай."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX гурван баганатай."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX дохио дүүрэн."</string>
+    <string name="accessibility_no_signal" msgid="7064645320782585167">"Дохио байхгүй."</string>
+    <string name="accessibility_not_connected" msgid="6395326276213402883">"Холбогдоогүй."</string>
+    <string name="accessibility_zero_bars" msgid="3806060224467027887">"Тэг баганатай."</string>
+    <string name="accessibility_one_bar" msgid="1685730113192081895">"Нэг баганатай."</string>
+    <string name="accessibility_two_bars" msgid="6437363648385206679">"Хоёр багана."</string>
+    <string name="accessibility_three_bars" msgid="2648241415119396648">"Гурван баганатай."</string>
+    <string name="accessibility_signal_full" msgid="9122922886519676839">"Дохио дүүрэн."</string>
+    <string name="accessibility_desc_on" msgid="2385254693624345265">"Идэвхижсэн."</string>
+    <string name="accessibility_desc_off" msgid="6475508157786853157">"Унтраах"</string>
+    <string name="accessibility_desc_connected" msgid="8366256693719499665">"Холбогдсон."</string>
+    <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+    <string name="accessibility_data_connection_1x" msgid="994133468120244018">"1 X"</string>
+    <string name="accessibility_data_connection_hspa" msgid="2032328855462645198">"HSPA"</string>
+    <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+    <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+    <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+    <string name="accessibility_data_connection_lte" msgid="5413468808637540658">"LTE"</string>
+    <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_bluetooth_tether" msgid="4102784498140271969">"Блютүүт модем болж байна."</string>
+    <string name="accessibility_airplane_mode" msgid="834748999790763092">"Нислэгийн горим"</string>
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"Батерей <xliff:g id="NUMBER">%d</xliff:g> хувьтай."</string>
+    <string name="accessibility_settings_button" msgid="799583911231893380">"Системийн тохиргоо."</string>
+    <string name="accessibility_notifications_button" msgid="4498000369779421892">"Мэдэгдэл."</string>
+    <string name="accessibility_remove_notification" msgid="3603099514902182350">"Мэдэгдлийг цэвэрлэх."</string>
+    <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS идэвхтэй."</string>
+    <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS хайж байна."</string>
+    <string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter идэвхтэй болов."</string>
+    <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Хонхны чичиргээ."</string>
+    <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Хонхыг хаах."</string>
+    <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> байхгүй."</string>
+    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Мэдэгдэл хаагдсан."</string>
+    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Мэдэгдлийн хураангуй самбар"</string>
+    <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Шуурхай тохиргоо."</string>
+    <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Сүүлийн апп"</string>
+    <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Хэрэглэгч <xliff:g id="USER">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</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" msgid="4196876722090224753">"Нислэгийн горим <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Блютүүт <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Сэрүүлгийг <xliff:g id="TIME">%s</xliff:g>-д тохируулсан."</string>
+    <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G дата идэвхгүй болов"</string>
+    <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G дата идэвхгүй байна"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Мобайл дата идэвхгүй болов"</string>
+    <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Дата идэвхгүй болов"</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Та заасан дата ашиглалтын хязгаарт хүрэв.\n\nХэрэв та датаг дахин идэвхжүүлбэл операторт төлбөр төлөх хэрэгтэй."</string>
+    <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Дата дахин идэвхжүүлэх"</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="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="accessibility_clear_all" msgid="5235938559247164925">"Бүх мэдэгдлийг цэвэрлэх."</string>
+    <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Апп мэдээлэл"</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="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="start_dreams" msgid="7219575858348719790">"Daydream"</string>
+    <string name="ethernet_label" msgid="7967563676324087464">"Этернет"</string>
+    <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Нислэгийн горим"</string>
+    <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"Цэнэглэж байна, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"Цэнэглэгдсэн"</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_brightness_label" msgid="6968372297018755815">"Тодрол"</string>
+    <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Автомат эргэх"</string>
+    <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Эргүүлэлт түгжигдсэн"</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>
+    <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Зөвхөн яаралтай дуудлага"</string>
+    <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_wifi_label" msgid="9135344704899546041">"Wi-Fi"</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_display_label" msgid="6893592964463624333">"Wi-Fi Дэлгэц"</string>
+    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Утасгүй дэлгэц"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Тодрол"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АВТОМАТ"</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Сүлжээ хянагдаж байж болзошгүй"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
new file mode 100644
index 0000000..aea7be1
--- /dev/null
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -0,0 +1,208 @@
+<?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: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="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="6576392951053994640">"Сүүлийн апп хоосон"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Сүүлийн апп-уудыг хаах"</string>
+  <plurals name="status_bar_accessibility_recent_apps">
+    <item quantity="one" msgid="5854176083865845541">"1 сүүлийн апп"</item>
+    <item quantity="other" msgid="1040784359794890744">"%d сүүлийн апп"</item>
+  </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="battery_low_title" msgid="2783104807551211639">"Цэнэглэгчийг холбоно уу"</string>
+    <string name="battery_low_subtitle" msgid="1752040062087829196">"Батерей дуусаж байна."</string>
+    <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> үлдсэн"</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB цэнэглэлт дэмжигдэхгүй байна.\nЗөвхөн нийлүүлэгдсэн цэнэглэгчийг ашиглана уу."</string>
+    <string name="battery_low_why" msgid="7279169609518386372">"Батерей ашиглах"</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_airplane" msgid="4879879698500955300">"Нислэгийн горим"</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">"Блютүүтыг модем болгож байна"</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_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="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>
+    <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_saved_text" msgid="1152839647677558815">"Дэлгэцийн агшныг харах бол хүрнэ үү."</string>
+    <string name="screenshot_failed_title" msgid="705781116746922771">"Дэлгэцийн агшинг авч чадсангүй."</string>
+    <string name="screenshot_failed_text" msgid="8134011269572415402">"Дэлгэцийн агшинг хадгалж чадсангүй. Сан ашиглагдаж байгаа бололтой."</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">"Мас-д зориулсан  Андройд Файл Шилжүүлэх апп-г суулгана уу"</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_recent" msgid="8571350598987952883">"Сүүлийн апп"</string>
+    <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Оруулах аргыг сэлгэх товч."</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_no_battery" msgid="358343022352820946">"Батерей байхгүй."</string>
+    <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Батерей нэг баганатай."</string>
+    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Батерей хоёр баганатай."</string>
+    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Батерей гурван баганатай."</string>
+    <string name="accessibility_battery_full" msgid="8909122401720158582">"Батерей дүүрэн."</string>
+    <string name="accessibility_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_off" msgid="3177380296697933627">"Wifi унтарсан."</string>
+    <string name="accessibility_no_wifi" msgid="1425476551827924474">"Wifi салав."</string>
+    <string name="accessibility_wifi_one_bar" msgid="7735893178010724377">"Wifi нэг баганатай."</string>
+    <string name="accessibility_wifi_two_bars" msgid="4994274250497262434">"Wifi хоёр баганатай."</string>
+    <string name="accessibility_wifi_three_bars" msgid="3495755044276588384">"Wifi гурван баганатай."</string>
+    <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"Wifi дохио дүүрэн."</string>
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"WiMAX байхгүй."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX нэг багана."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX хоёр баганатай."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX гурван баганатай."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX дохио дүүрэн."</string>
+    <string name="accessibility_no_signal" msgid="7064645320782585167">"Дохио байхгүй."</string>
+    <string name="accessibility_not_connected" msgid="6395326276213402883">"Холбогдоогүй."</string>
+    <string name="accessibility_zero_bars" msgid="3806060224467027887">"Тэг баганатай."</string>
+    <string name="accessibility_one_bar" msgid="1685730113192081895">"Нэг баганатай."</string>
+    <string name="accessibility_two_bars" msgid="6437363648385206679">"Хоёр багана."</string>
+    <string name="accessibility_three_bars" msgid="2648241415119396648">"Гурван баганатай."</string>
+    <string name="accessibility_signal_full" msgid="9122922886519676839">"Дохио дүүрэн."</string>
+    <string name="accessibility_desc_on" msgid="2385254693624345265">"Идэвхижсэн."</string>
+    <string name="accessibility_desc_off" msgid="6475508157786853157">"Унтраах"</string>
+    <string name="accessibility_desc_connected" msgid="8366256693719499665">"Холбогдсон."</string>
+    <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+    <string name="accessibility_data_connection_1x" msgid="994133468120244018">"1 X"</string>
+    <string name="accessibility_data_connection_hspa" msgid="2032328855462645198">"HSPA"</string>
+    <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+    <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+    <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+    <string name="accessibility_data_connection_lte" msgid="5413468808637540658">"LTE"</string>
+    <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_bluetooth_tether" msgid="4102784498140271969">"Блютүүт модем болж байна."</string>
+    <string name="accessibility_airplane_mode" msgid="834748999790763092">"Нислэгийн горим"</string>
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"Батерей <xliff:g id="NUMBER">%d</xliff:g> хувьтай."</string>
+    <string name="accessibility_settings_button" msgid="799583911231893380">"Системийн тохиргоо."</string>
+    <string name="accessibility_notifications_button" msgid="4498000369779421892">"Мэдэгдэл."</string>
+    <string name="accessibility_remove_notification" msgid="3603099514902182350">"Мэдэгдлийг цэвэрлэх."</string>
+    <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS идэвхтэй."</string>
+    <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS хайж байна."</string>
+    <string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter идэвхтэй болов."</string>
+    <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Хонхны чичиргээ."</string>
+    <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Хонхыг хаах."</string>
+    <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> байхгүй."</string>
+    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Мэдэгдэл хаагдсан."</string>
+    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Мэдэгдлийн хураангуй самбар"</string>
+    <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Шуурхай тохиргоо."</string>
+    <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Сүүлийн апп"</string>
+    <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Хэрэглэгч <xliff:g id="USER">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</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" msgid="4196876722090224753">"Нислэгийн горим <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Блютүүт <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Сэрүүлгийг <xliff:g id="TIME">%s</xliff:g>-д тохируулсан."</string>
+    <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G дата идэвхгүй болов"</string>
+    <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G дата идэвхгүй байна"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Мобайл дата идэвхгүй болов"</string>
+    <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Дата идэвхгүй болов"</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Та заасан дата ашиглалтын хязгаарт хүрэв.\n\nХэрэв та датаг дахин идэвхжүүлбэл операторт төлбөр төлөх хэрэгтэй."</string>
+    <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Дата дахин идэвхжүүлэх"</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="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="accessibility_clear_all" msgid="5235938559247164925">"Бүх мэдэгдлийг цэвэрлэх."</string>
+    <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Апп мэдээлэл"</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="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="start_dreams" msgid="7219575858348719790">"Daydream"</string>
+    <string name="ethernet_label" msgid="7967563676324087464">"Этернет"</string>
+    <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Нислэгийн горим"</string>
+    <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"Цэнэглэж байна, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"Цэнэглэгдсэн"</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_brightness_label" msgid="6968372297018755815">"Тодрол"</string>
+    <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Автомат эргэх"</string>
+    <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Эргүүлэлт түгжигдсэн"</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>
+    <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Зөвхөн яаралтай дуудлага"</string>
+    <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_wifi_label" msgid="9135344704899546041">"Wi-Fi"</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_display_label" msgid="6893592964463624333">"Wi-Fi Дэлгэц"</string>
+    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Утасгүй дэлгэц"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Тодрол"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АВТОМАТ"</string>
+    <string name="status_bar_help_title" msgid="1199237744086469217">"Мэдэгдэл энд харагдана"</string>
+    <string name="status_bar_help_text" msgid="7874607155052076323">"Доош татаад тэдгээрт хандана уу.\nДахин доош татаад систем контролд хандана уу."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Сүлжээ хянагдаж байж болзошгүй"</string>
+    <string name="done_button" msgid="1759387181766603361">"Дууссан"</string>
+    <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"Сүлжээний Хяналт"</string>
+    <string name="ssl_ca_cert_info_message" msgid="5430320539555358452">"Энэ төхөөрөмжийг удирдагч: <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>.\n\nТаны админ имэйл, апп-ууд болон аюулгүй вебсайтуудыг оруулан таны сүлжээний үйл ажиллагааг хянах боломжтой.\n\nДэлгэрэнгүй мэдээллийг өөрийн админтай холбогдож авна уу."</string>
+    <string name="ssl_ca_cert_warning_message" msgid="2033091656129963669">"Гуравдагч талын этгээд таны сүлжээг хянаж байж болзошгүй\nүүнд имэйл, апп-ууд болон аюулгүй вебсайтууд багтана.\n\nТаны төхөөрөмж дээр суулгасан итгэмжлэгдсэн жуух энэ боломжоор хангаж байна."</string>
+    <string name="ssl_ca_cert_settings_button" msgid="7946956977377166709">"Итгэмжлэгдсэн жуухуудыг шалгах"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ms-rMY-land/strings.xml b/packages/SystemUI/res/values-ms-rMY-land/strings.xml
new file mode 100644
index 0000000..175b0fa
--- /dev/null
+++ b/packages/SystemUI/res/values-ms-rMY-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * 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.
+ */
+ -->
+
+<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">"Skrin kini dikunci dalam orientasi landskap."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
new file mode 100644
index 0000000..bb780fe
--- /dev/null
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -0,0 +1,201 @@
+<?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:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="7164937344850004466">"Sistem UI"</string>
+    <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Pdm bersih"</string>
+    <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Alih keluar dari senarai"</string>
+    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Maklumat aplikasi"</string>
+    <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Tiada aplikasi terbaharu"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Buang aplikasi terbaharu"</string>
+  <plurals name="status_bar_accessibility_recent_apps">
+    <item quantity="one" msgid="5854176083865845541">"1 aplikasi terbaharu"</item>
+    <item quantity="other" msgid="1040784359794890744">"%d aplikasi terbaharu"</item>
+  </plurals>
+    <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Tiada pemberitahuan"</string>
+    <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Sedang berlangsung"</string>
+    <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Pemberitahuan"</string>
+    <string name="battery_low_title" msgid="2783104807551211639">"Sambungkan pengecas"</string>
+    <string name="battery_low_subtitle" msgid="1752040062087829196">"Bateri semakin lemah."</string>
+    <string name="battery_low_percent_format" msgid="1077244949318261761">"Berbaki <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"Pengecasan USB tidak disokong.\nGunakan hanya pengecas yang dibekalkan."</string>
+    <string name="battery_low_why" msgid="7279169609518386372">"Penggunaan bateri"</string>
+    <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Tetapan"</string>
+    <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
+    <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Mod pesawat"</string>
+    <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"Autoputar skrin"</string>
+    <string name="status_bar_settings_mute_label" msgid="554682549917429396">"REDAM"</string>
+    <string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
+    <string name="status_bar_settings_notifications" msgid="397146176280905137">"Pemberitahuan"</string>
+    <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth ditambatkan"</string>
+    <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Sediakan kaedah input"</string>
+    <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Papan kekunci fizikal"</string>
+    <string name="usb_device_permission_prompt" msgid="834698001271562057">"Benarkan aplikasi <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses peranti USB?"</string>
+    <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Benarkan aplikasi <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses aksesori USB?"</string>
+    <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Buka <xliff:g id="ACTIVITY">%1$s</xliff:g> apabila peranti USB ini disambungkan?"</string>
+    <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Buka <xliff:g id="ACTIVITY">%1$s</xliff:g> apabila aksesori USB ini disambungkan?"</string>
+    <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"Tiada apl yg dipsg bfungsi dgn aksesori USB ini. Ketahui lg ttg aksesori ini di <xliff:g id="URL">%1$s</xliff:g>"</string>
+    <string name="title_usb_accessory" msgid="4966265263465181372">"Aksesori USB"</string>
+    <string name="label_view" msgid="6304565553218192990">"Lihat"</string>
+    <string name="always_use_device" msgid="1450287437017315906">"Gunakan secara lalai untuk peranti USB ini"</string>
+    <string name="always_use_accessory" msgid="1210954576979621596">"Gunakan secara lalai untuk aksesori USB ini"</string>
+    <string name="usb_debugging_title" msgid="4513918393387141949">"Benarkan penyahpepijatan USB?"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"Cap jari kekunci RSA komputer ialah:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_always" msgid="303335496705863070">"Sentiasa benarkan komputer ini"</string>
+    <string name="compat_mode_on" msgid="6623839244840638213">"Zum untuk memenuhi skrin"</string>
+    <string name="compat_mode_off" msgid="4434467572461327898">"Regang utk memenuhi skrin"</string>
+    <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Menyimpan tangkapan skrin..."</string>
+    <string name="screenshot_saving_title" msgid="8242282144535555697">"Menyimpan tangkapan skrin..."</string>
+    <string name="screenshot_saving_text" msgid="2419718443411738818">"Tangkapan skrin sedang disimpan."</string>
+    <string name="screenshot_saved_title" msgid="6461865960961414961">"Tangkapan skrin ditangkap."</string>
+    <string name="screenshot_saved_text" msgid="1152839647677558815">"Sentuh untuk melihat tangkapan skrin anda."</string>
+    <string name="screenshot_failed_title" msgid="705781116746922771">"Tidak dapat menangkap tangkapan skrin."</string>
+    <string name="screenshot_failed_text" msgid="8134011269572415402">"Tidak boleh menyimpan tangkapan skrin. Storan mungkin sedang digunakan."</string>
+    <string name="usb_preference_title" msgid="6551050377388882787">"Pilihan pemindahan fail USB"</string>
+    <string name="use_mtp_button_title" msgid="4333504413563023626">"Lekapkan sebagai pemain media (MTP)"</string>
+    <string name="use_ptp_button_title" msgid="7517127540301625751">"Lekapkan sebagai kamera (PTP)"</string>
+    <string name="installer_cd_button_title" msgid="2312667578562201583">"Pasang aplikasi Pindahan Fail Android untuk Mac"</string>
+    <string name="accessibility_back" msgid="567011538994429120">"Kembali"</string>
+    <string name="accessibility_home" msgid="8217216074895377641">"Rumah"</string>
+    <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
+    <string name="accessibility_recent" msgid="8571350598987952883">"Aplikasi terbaharu"</string>
+    <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Butang tukar kaedah input."</string>
+    <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Butang zum keserasian."</string>
+    <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Skrin zum lebih kecil kepada lebih besar."</string>
+    <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth disambungkan."</string>
+    <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth diputuskan sambungan."</string>
+    <string name="accessibility_no_battery" msgid="358343022352820946">"Tiada bateri."</string>
+    <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Bateri satu bar."</string>
+    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Bateri dua bar."</string>
+    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Bateri tiga bar."</string>
+    <string name="accessibility_battery_full" msgid="8909122401720158582">"Bateri penuh."</string>
+    <string name="accessibility_no_phone" msgid="4894708937052611281">"Tiada telefon."</string>
+    <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Telefon satu bar."</string>
+    <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Telefon dua bar."</string>
+    <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"Telefon tiga bar."</string>
+    <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"Isyarat telefon penuh."</string>
+    <string name="accessibility_no_data" msgid="4791966295096867555">"Tiada data."</string>
+    <string name="accessibility_data_one_bar" msgid="1415625833238273628">"Data satu bar."</string>
+    <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Data dua bar."</string>
+    <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Data tiga bar."</string>
+    <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Isyarat data penuh."</string>
+    <string name="accessibility_wifi_off" msgid="3177380296697933627">"Wifi dimatikan."</string>
+    <string name="accessibility_no_wifi" msgid="1425476551827924474">"Wifi diputuskan sambungannya."</string>
+    <string name="accessibility_wifi_one_bar" msgid="7735893178010724377">"WiFi satu bar."</string>
+    <string name="accessibility_wifi_two_bars" msgid="4994274250497262434">"WiFi dua bar."</string>
+    <string name="accessibility_wifi_three_bars" msgid="3495755044276588384">"WiFi tiga bar."</string>
+    <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"Isyarat WiFi penuh."</string>
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Tiada WiMAX"</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX satu bar."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX dua bar."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX tiga bar."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"Isyarat WiMAX penuh."</string>
+    <string name="accessibility_no_signal" msgid="7064645320782585167">"Tiada isyarat."</string>
+    <string name="accessibility_not_connected" msgid="6395326276213402883">"Tidak disambungkan."</string>
+    <string name="accessibility_zero_bars" msgid="3806060224467027887">"Tiada bar."</string>
+    <string name="accessibility_one_bar" msgid="1685730113192081895">"Satu bar."</string>
+    <string name="accessibility_two_bars" msgid="6437363648385206679">"Dua bar."</string>
+    <string name="accessibility_three_bars" msgid="2648241415119396648">"Tiga bar."</string>
+    <string name="accessibility_signal_full" msgid="9122922886519676839">"Isyarat penuh."</string>
+    <string name="accessibility_desc_on" msgid="2385254693624345265">"Dihidupkan."</string>
+    <string name="accessibility_desc_off" msgid="6475508157786853157">"Dimatikan."</string>
+    <string name="accessibility_desc_connected" msgid="8366256693719499665">"Disambungkan."</string>
+    <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+    <string name="accessibility_data_connection_1x" msgid="994133468120244018">"1 X"</string>
+    <string name="accessibility_data_connection_hspa" msgid="2032328855462645198">"HSPA"</string>
+    <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+    <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+    <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+    <string name="accessibility_data_connection_lte" msgid="5413468808637540658">"LTE"</string>
+    <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+    <string name="accessibility_data_connection_roaming" msgid="5977362333466556094">"Perayauan"</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">"Tiada SIM."</string>
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Penambatan Bluetooth."</string>
+    <string name="accessibility_airplane_mode" msgid="834748999790763092">"Mod pesawat"</string>
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"Bateri <xliff:g id="NUMBER">%d</xliff:g> peratus."</string>
+    <string name="accessibility_settings_button" msgid="799583911231893380">"Tetapan sistem."</string>
+    <string name="accessibility_notifications_button" msgid="4498000369779421892">"Pemberitahuan."</string>
+    <string name="accessibility_remove_notification" msgid="3603099514902182350">"Padamkan pemberitahuan."</string>
+    <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS didayakan."</string>
+    <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS sedang mendapatkan."</string>
+    <string name="accessibility_tty_enabled" msgid="4613200365379426561">"Mesin Teletaip didayakan."</string>
+    <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Pendering bergetar."</string>
+    <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Pendering senyap."</string>
+    <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ditolak."</string>
+    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Pemberitahuan diketepikan."</string>
+    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Bidai pemberitahuan."</string>
+    <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Tetapan pantas."</string>
+    <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Apl terbaru."</string>
+    <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Pengguna <xliff:g id="USER">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mudah Alih <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">"Bateri <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Mod Pesawat <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Penggera ditetapkan pada <xliff:g id="TIME">%s</xliff:g>."</string>
+    <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Data 2G-3G dilumpuhkan"</string>
+    <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Data 4G dilumpuhkan"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Data mudah alih dilumpuhkan"</string>
+    <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Data dilumpuhkan"</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Anda telah mencapai had penggunaan data yang dinyatakan.\n\nJika anda mendayakan semula data, anda mungkin dikenakan caj oleh operator."</string>
+    <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Dayakan semula data"</string>
+    <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Tiada smbg Internet"</string>
+    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi disambungkan"</string>
+    <string name="gps_notification_searching_text" msgid="8574247005642736060">"Mencari GPS"</string>
+    <string name="gps_notification_found_text" msgid="4619274244146446464">"Lokasi ditetapkan oleh GPS"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Permintaan lokasi aktif"</string>
+    <string name="accessibility_clear_all" msgid="5235938559247164925">"Padamkan semua pemberitahuan."</string>
+    <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Maklumat apl"</string>
+    <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skrin akan berputar secara automatik."</string>
+    <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Skrin dikunci dalam orientasi landskap."</string>
+    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Skrin dikunci dalam orientasi potret."</string>
+    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="start_dreams" msgid="7219575858348719790">"Lamun"</string>
+    <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Mod kapal terbang"</string>
+    <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"Mengecas, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"Sudah dicas"</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> Peranti)"</string>
+    <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Bluetooth Dimatikan"</string>
+    <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Kecerahan"</string>
+    <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Auto Putar"</string>
+    <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Putaran Dikunci"</string>
+    <string name="quick_settings_ime_label" msgid="7073463064369468429">"Kaedah Input"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Lokasi"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Lokasi Dimatikan"</string>
+    <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Peranti media"</string>
+    <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Panggilan Kecemasan Sahaja"</string>
+    <string name="quick_settings_settings_label" msgid="5326556592578065401">"Tetapan"</string>
+    <string name="quick_settings_time_label" msgid="4635969182239736408">"Masa"</string>
+    <string name="quick_settings_user_label" msgid="5238995632130897840">"Saya"</string>
+    <string name="quick_settings_wifi_label" msgid="9135344704899546041">"Wi-Fi"</string>
+    <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Tidak Disambungkan"</string>
+    <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Tiada Rangkaian"</string>
+    <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi Dimatikan"</string>
+    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Paparan Wi-Fi"</string>
+    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Paparan Wayarles"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Kecerahan"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Rangkaian mungkin dipantau"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index c99626d..9c76eae 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"Sistem UI"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Pdm bersih"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Jangan ganggu"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Tunjukkan pemberitahuan"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Alih keluar dari senarai"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Maklumat aplikasi"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Tiada aplikasi terbaharu"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Sambungkan pengecas"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Bateri semakin lemah."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"Berbaki <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"Pengecasan USB tidak disokong."\n"Gunakan hanya pengecas yang dibekalkan."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"Pengecasan USB tidak disokong.\nGunakan hanya pengecas yang dibekalkan."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Penggunaan bateri"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Tetapan"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,7 +57,7 @@
     <string name="always_use_device" msgid="1450287437017315906">"Gunakan secara lalai untuk peranti USB ini"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Gunakan secara lalai untuk aksesori USB ini"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"Benarkan penyahpepijatan USB?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"Cap jari kekunci RSA komputer ialah:"\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"Cap jari kekunci RSA komputer ialah:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Sentiasa benarkan komputer ini"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zum untuk memenuhi skrin"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Regang utk memenuhi skrin"</string>
@@ -160,17 +158,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Data 4G dilumpuhkan"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Data mudah alih dilumpuhkan"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Data dilumpuhkan"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Anda telah mencapai had penggunaan data yang dinyatakan."\n\n"Jika anda mendayakan semula data, anda mungkin dikenakan caj oleh operator."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Anda telah mencapai had penggunaan data yang dinyatakan.\n\nJika anda mendayakan semula data, anda mungkin dikenakan caj oleh operator."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Dayakan semula data"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Tiada smbg Internet"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi disambungkan"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Mencari GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Lokasi ditetapkan oleh GPS"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Permintaan lokasi aktif"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Padamkan semua pemberitahuan."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Maklumat apl"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Tutup"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Pemberitahuan dimatikan"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Ketik di sini untuk menghidupkan kembali pemberitahuan."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skrin akan berputar secara automatik."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Skrin dikunci dalam orientasi landskap."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Skrin dikunci dalam orientasi potret."</string>
@@ -187,7 +183,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Auto Putar"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Putaran Dikunci"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Kaedah Input"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Lokasi sedang digunakan"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Lokasi"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Lokasi Dimatikan"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Peranti media"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Panggilan Kecemasan Sahaja"</string>
@@ -203,5 +200,5 @@
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Kecerahan"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Pemberitahuan dipaparkan di sini"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Akses panel pada bila-bila masa dengan meleret ke bawah."\n"Leret ke bawah sekali lagi untuk mendapatkan kawalan sistem."</string>
+    <string name="status_bar_help_text" msgid="7874607155052076323">"Akses panel pada bila-bila masa dengan meleret ke bawah.\nLeret ke bawah sekali lagi untuk mendapatkan kawalan sistem."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 3d32563..82c4090 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"Sys.gr.snitt"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Fjern"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Ikke forstyrr"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Vis varslinger"</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">"Info om app"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Ingen nylige apper"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Koble til lader"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Lavt batterinivå."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> gjenværende"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"USB-lading støttes ikke."\n"Bruk kun den medfølgende laderen."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB-lading støttes ikke.\nBruk kun den medfølgende laderen."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Batteribruk"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Innstillinger"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Trådløse nettverk"</string>
@@ -59,12 +57,10 @@
     <string name="always_use_device" msgid="1450287437017315906">"Bruk som standard for denne USB-enheten"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Bruk som standard for dette USB-tilbehøret"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"Vil du tillate USB-feilsøking?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"Datamaskinens nøkkelfingeravtrykk for RSA er:"\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"Datamaskinens nøkkelfingeravtrykk for RSA er:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Tillat alltid fra denne datamaskinen"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom for å fylle skjermen"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Strekk for å fylle skjerm"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Kompatibilitets-zooming"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Når en app er utformet for en mindre skjerm, vises det en zoomkontroll ved klokken."</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Lagrer skjermdumpen …"</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"Lagrer skjermdumpen …"</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"Skjermdumpen lagres."</string>
@@ -160,17 +156,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G-data er deaktivert"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobildata er deaktivert"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Data deaktivert"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Du har nådd den angitte databruksgrensen."\n\n"Hvis du slår på igjen databruk, kan du bli belastet med kostnader av operatøren."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Du har nådd den angitte databruksgrensen.\n\nHvis du slår på igjen databruk, kan du bli belastet med kostnader av operatøren."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Aktiver data på nytt"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Ingen Internett-forbindelse"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi tilkoblet"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Søker etter GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Posisjon angitt av GPS"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Aktive stedsforespørsler"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Fjern alle varslinger."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Info om app"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Lukk"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Varsler er deaktivert"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Trykk her for å aktivere varsler på nytt."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skjermen roterer automatisk."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Skjermen er låst i liggende retning."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Skjermen er låst i stående retning."</string>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Automatisk rotasjon"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Rotasjon er låst"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Inndatametode"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Posisjon i bruk"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Sted"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Posisjon av"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Medieenhet"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Bare nødanrop"</string>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Trådløs skjerm"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Lysstyrke"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Varslene vises her"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Bruk dem når som helst ved å sveipe nedover."\n"Sveip nedover igjen for å gå til systemkontrollene."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Nettverket blir muligens overvåket"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ne-rNP-land/strings.xml b/packages/SystemUI/res/values-ne-rNP-land/strings.xml
new file mode 100644
index 0000000..8d5286e
--- /dev/null
+++ b/packages/SystemUI/res/values-ne-rNP-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * 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.
+ */
+ -->
+
+<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>
+</resources>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml
new file mode 100644
index 0000000..9e6605e
--- /dev/null
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -0,0 +1,206 @@
+<?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: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="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="6576392951053994640">"कुनै नयाँ अनुप्रयोगहरू छैनन्"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"नयाँ अनुप्रयोगहरू खारेज गर्नुहोस्"</string>
+  <plurals name="status_bar_accessibility_recent_apps">
+    <item quantity="one" msgid="5854176083865845541">"१ भरखरै अनुप्रयोग"</item>
+    <item quantity="other" msgid="1040784359794890744">"%d भरखरैका अनुप्रयोगहरू"</item>
+  </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="battery_low_title" msgid="2783104807551211639">"चार्जर जडान गर्नुहोस्"</string>
+    <string name="battery_low_subtitle" msgid="1752040062087829196">"ब्याट्रि न्यून हुँदै छ।"</string>
+    <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> बाँकी"</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB चार्ज गर्न समर्थित छैन।\n आपूर्ति गरिएको चार्जर मात्र प्रयोग गर्नुहोस्।"</string>
+    <string name="battery_low_why" msgid="7279169609518386372">"ब्याट्रि प्रयोग"</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_airplane" msgid="4879879698500955300">"हवाइजहाज मोड"</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">"ब्लुटुथ टेथर भयो"</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_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="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>
+    <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_saved_text" msgid="1152839647677558815">"तपाईँको स्क्रिनसट हेर्न छुनुहोस्।"</string>
+    <string name="screenshot_failed_title" msgid="705781116746922771">"स्क्रिनसट क्याप्चर गर्न सकिएन।"</string>
+    <string name="screenshot_failed_text" msgid="8134011269572415402">"स्क्रिनसटलाई बचत गर्न सकेन। भण्डारण उपयोगमा हुन सक्छ।"</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">"म्याकको लागि एन्ड्रोइड फाइल ट्रान्सफर अनुप्रयोग स्थापना गर्नुहोस्"</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_recent" msgid="8571350598987952883">"भर्खरका अनुप्रयोगहरू"</string>
+    <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"इनपुट विधि बटन स्विच गर्नुहोस्।"</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_no_battery" msgid="358343022352820946">"कुनै ब्याट्रि छैन।"</string>
+    <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"ब्याट्रि एउटा पट्टि।"</string>
+    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"ब्याट्रिका दुईवटा पट्टिहरू"</string>
+    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"ब्याट्रिका तिनवटा पट्टिहरू"</string>
+    <string name="accessibility_battery_full" msgid="8909122401720158582">"ब्याट्रि पूर्ण छ।"</string>
+    <string name="accessibility_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_off" msgid="3177380296697933627">"वाइफाइ बन्द।"</string>
+    <string name="accessibility_no_wifi" msgid="1425476551827924474">"वाइफाइ विच्छेद भयो।"</string>
+    <string name="accessibility_wifi_one_bar" msgid="7735893178010724377">"वाइफाइ एक पट्टि।"</string>
+    <string name="accessibility_wifi_two_bars" msgid="4994274250497262434">"वाइफाइ दुई पट्टि।"</string>
+    <string name="accessibility_wifi_three_bars" msgid="3495755044276588384">"वाइफाइ तिन बारहरू।"</string>
+    <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"वाइफाइ सङ्केत भरिएको।"</string>
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"वाइम्यास छैन।"</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX एउटा पट्टि।"</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"वाइम्याक्स दुईवटा बारहरू।"</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"वाइम्याक्स तिनवटा बारहरू।"</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"वाइम्याक्स सङ्केत भरिएका।"</string>
+    <string name="accessibility_no_signal" msgid="7064645320782585167">"सङ्केत छैन।"</string>
+    <string name="accessibility_not_connected" msgid="6395326276213402883">"जडान नगरिएको।"</string>
+    <string name="accessibility_zero_bars" msgid="3806060224467027887">"शून्य पट्टि।"</string>
+    <string name="accessibility_one_bar" msgid="1685730113192081895">"एउटा बार।"</string>
+    <string name="accessibility_two_bars" msgid="6437363648385206679">"दुई पट्टिहरू।"</string>
+    <string name="accessibility_three_bars" msgid="2648241415119396648">"तिनवटा पट्टिहरू"</string>
+    <string name="accessibility_signal_full" msgid="9122922886519676839">"सङ्केत पूर्ण छ।"</string>
+    <string name="accessibility_desc_on" msgid="2385254693624345265">"चालु।"</string>
+    <string name="accessibility_desc_off" msgid="6475508157786853157">"बन्द गर्नुहोस्।"</string>
+    <string name="accessibility_desc_connected" msgid="8366256693719499665">"जडान गरिएको।"</string>
+    <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+    <string name="accessibility_data_connection_1x" msgid="994133468120244018">"1 X"</string>
+    <string name="accessibility_data_connection_hspa" msgid="2032328855462645198">"HSPA"</string>
+    <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+    <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+    <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+    <string name="accessibility_data_connection_lte" msgid="5413468808637540658">"LTE"</string>
+    <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_no_sim" msgid="8274017118472455155">"SIM छैन।"</string>
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"ब्लुटुथ टेदर गर्दै।"</string>
+    <string name="accessibility_airplane_mode" msgid="834748999790763092">"हवाइजहाज मोड।"</string>
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"ब्याट्रि <xliff:g id="NUMBER">%d</xliff:g> प्रतिशत"</string>
+    <string name="accessibility_settings_button" msgid="799583911231893380">"प्रणाली सेटिङहरू"</string>
+    <string name="accessibility_notifications_button" msgid="4498000369779421892">"सूचनाहरू।"</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_silent" msgid="9061243307939135383">"घन्टी मौन।"</string>
+    <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> खारेज गरिएको छ।"</string>
+    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"सूचना खारेज।"</string>
+    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"सूचना कक्ष।"</string>
+    <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"द्रुत सेटिङहरू"</string>
+    <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"वर्तमान अनुप्रयोगहरू"</string>
+    <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"प्रयोगकर्ता <xliff:g id="USER">%s</xliff:g>।"</string>
+    <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>। <xliff:g id="NETWORK">%2$s</xliff:g>"</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" msgid="4196876722090224753">"हवाजहाज मोड <xliff:g id="STATE">%s</xliff:g>।"</string>
+    <string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"ब्लुटुथ <xliff:g id="STATE">%s</xliff:g>।"</string>
+    <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"<xliff:g id="TIME">%s</xliff:g>को लागि सङ्केत घन्टी सेट गरिएको"</string>
+    <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G डेटा अक्षम गरियो"</string>
+    <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G डेटा असक्षम गरियो"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"मोबाइल डेटा अक्षम गरियो"</string>
+    <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"डेटा अक्षम गरियो"</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"तपाईँ निर्दिष्ट डेटा उपयोग सीमामा पुग्नु भएको छ।\n\nयदि तपाईँले डेटालाई पुनःसक्षम पार्नु भयो भने तपाईँलाई अर्को संचालकबाट शुल्क लगाउन सक्छ।"</string>
+    <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"डेटा पुनः सक्षम गर्नुहोस्"</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="accessibility_clear_all" msgid="5235938559247164925">"सबै सूचनाहरू हटाउनुहोस्।"</string>
+    <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"अनुप्रयोगको जानकारी"</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="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="start_dreams" msgid="7219575858348719790">"दिवासपना"</string>
+    <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"हवाइजहाज मोड"</string>
+    <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"चार्ज हुँदै, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"चार्ज भयो"</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_brightness_label" msgid="6968372297018755815">"चमक"</string>
+    <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"स्वतः घुमाइ"</string>
+    <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"घुम्ने लक गरेको"</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>
+    <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"आकस्मिक कल मात्र"</string>
+    <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_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">"वाइफाइ बन्द"</string>
+    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"वाइफाइ प्रदर्शन"</string>
+    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"ताररहित प्रदर्शन"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"उज्यालपन"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"स्वतः"</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"सञ्जाल अनुगमित हुन सक्छ"</string>
+    <string name="done_button" msgid="1759387181766603361">"भयो"</string>
+    <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"सञ्जाल निगरानी"</string>
+    <string name="ssl_ca_cert_info_message" msgid="5430320539555358452">"यो उपकरण <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>द्वारा प्रबन्धित छ। \n \n तपाईँको प्रशासक तपाईँको अनुप्रयोग र सुरक्षित वेब साइट लगायत सञ्जाल गतिविधि अनुगमन गर्न सक्षम छ। \n \n थप जानकारीको लागि तपाईँको प्रशासकसँग सम्पर्क राख्नुहोस्।"</string>
+    <string name="ssl_ca_cert_warning_message" msgid="2033091656129963669">"एक तेस्रो पक्ष तपाईँको सञ्जाल\n गतिविधि, इमेल, अनुप्रयोग र सुरक्षित वेबसाइट अनुगमन गर्न सक्षम छ। \n \n तपाईँको उपकरणमा स्थापित एक विश्वसनीय प्रामाणिक डेटाले सम्भव तुल्याइरहेको छ।"</string>
+    <string name="ssl_ca_cert_settings_button" msgid="7946956977377166709">"विश्वसनीय प्रामाणिक डेटा जाँच गर्नुहोस्"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
new file mode 100644
index 0000000..c3eee01
--- /dev/null
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -0,0 +1,204 @@
+<?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: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="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="6576392951053994640">"कुनै नयाँ अनुप्रयोगहरू छैनन्"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"नयाँ अनुप्रयोगहरू खारेज गर्नुहोस्"</string>
+  <plurals name="status_bar_accessibility_recent_apps">
+    <item quantity="one" msgid="5854176083865845541">"१ भरखरै अनुप्रयोग"</item>
+    <item quantity="other" msgid="1040784359794890744">"%d भरखरैका अनुप्रयोगहरू"</item>
+  </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="battery_low_title" msgid="2783104807551211639">"चार्जर जडान गर्नुहोस्"</string>
+    <string name="battery_low_subtitle" msgid="1752040062087829196">"ब्याट्रि न्यून हुँदै छ।"</string>
+    <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> बाँकी"</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB चार्ज गर्न समर्थित छैन।\n आपूर्ति गरिएको चार्जर मात्र प्रयोग गर्नुहोस्।"</string>
+    <string name="battery_low_why" msgid="7279169609518386372">"ब्याट्रि प्रयोग"</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_airplane" msgid="4879879698500955300">"हवाइजहाज मोड"</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">"ब्लुटुथ टेथर भयो"</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_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="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>
+    <string name="compat_mode_on" msgid="6623839244840638213">"स्क्रिन भर्न जुम गर्नुहोस्"</string>
+    <string name="compat_mode_off" msgid="4434467572461327898">"स्क्रिन भर्न तन्काउनुहोस्"</string>
+    <string name="compat_mode_help_header" msgid="7969493989397529910">"अनुकूलता जुम"</string>
+    <string name="compat_mode_help_body" msgid="4946726776359270040">"जब कुनै अनुप्रयोग सानो स्क्रिनको लागि बनाइएको हुन्छ, तब जुम नियन्त्रण घडीको नजिक देखिन्छ।"</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="1152839647677558815">"तपाईँको स्क्रिनसट हेर्न छुनुहोस्।"</string>
+    <string name="screenshot_failed_title" msgid="705781116746922771">"स्क्रिनसट क्याप्चर गर्न सकिएन।"</string>
+    <string name="screenshot_failed_text" msgid="8134011269572415402">"स्क्रिनसटलाई बचत गर्न सकेन। भण्डारण उपयोगमा हुन सक्छ।"</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">"म्याकको लागि एन्ड्रोइड फाइल ट्रान्सफर अनुप्रयोग स्थापना गर्नुहोस्"</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_recent" msgid="8571350598987952883">"भर्खरका अनुप्रयोगहरू"</string>
+    <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"इनपुट विधि बटन स्विच गर्नुहोस्।"</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_no_battery" msgid="358343022352820946">"कुनै ब्याट्रि छैन।"</string>
+    <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"ब्याट्रि एउटा पट्टि।"</string>
+    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"ब्याट्रिका दुईवटा पट्टिहरू"</string>
+    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"ब्याट्रिका तिनवटा पट्टिहरू"</string>
+    <string name="accessibility_battery_full" msgid="8909122401720158582">"ब्याट्रि पूर्ण छ।"</string>
+    <string name="accessibility_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_off" msgid="3177380296697933627">"वाइफाइ बन्द।"</string>
+    <string name="accessibility_no_wifi" msgid="1425476551827924474">"वाइफाइ विच्छेद भयो।"</string>
+    <string name="accessibility_wifi_one_bar" msgid="7735893178010724377">"वाइफाइ एक पट्टि।"</string>
+    <string name="accessibility_wifi_two_bars" msgid="4994274250497262434">"वाइफाइ दुई पट्टि।"</string>
+    <string name="accessibility_wifi_three_bars" msgid="3495755044276588384">"वाइफाइ तिन बारहरू।"</string>
+    <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"वाइफाइ सङ्केत भरिएको।"</string>
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"वाइम्यास छैन।"</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX एउटा पट्टि।"</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"वाइम्याक्स दुईवटा बारहरू।"</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"वाइम्याक्स तिनवटा बारहरू।"</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"वाइम्याक्स सङ्केत भरिएका।"</string>
+    <string name="accessibility_no_signal" msgid="7064645320782585167">"सङ्केत छैन।"</string>
+    <string name="accessibility_not_connected" msgid="6395326276213402883">"जडान नगरिएको।"</string>
+    <string name="accessibility_zero_bars" msgid="3806060224467027887">"शून्य पट्टि।"</string>
+    <string name="accessibility_one_bar" msgid="1685730113192081895">"एउटा बार।"</string>
+    <string name="accessibility_two_bars" msgid="6437363648385206679">"दुई पट्टिहरू।"</string>
+    <string name="accessibility_three_bars" msgid="2648241415119396648">"तिनवटा पट्टिहरू"</string>
+    <string name="accessibility_signal_full" msgid="9122922886519676839">"सङ्केत पूर्ण छ।"</string>
+    <string name="accessibility_desc_on" msgid="2385254693624345265">"चालु।"</string>
+    <string name="accessibility_desc_off" msgid="6475508157786853157">"बन्द गर्नुहोस्।"</string>
+    <string name="accessibility_desc_connected" msgid="8366256693719499665">"जडान गरिएको।"</string>
+    <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+    <string name="accessibility_data_connection_1x" msgid="994133468120244018">"1 X"</string>
+    <string name="accessibility_data_connection_hspa" msgid="2032328855462645198">"HSPA"</string>
+    <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+    <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+    <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+    <string name="accessibility_data_connection_lte" msgid="5413468808637540658">"LTE"</string>
+    <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_no_sim" msgid="8274017118472455155">"SIM छैन।"</string>
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"ब्लुटुथ टिथर गर्दै।"</string>
+    <string name="accessibility_airplane_mode" msgid="834748999790763092">"हवाइजहाज मोड।"</string>
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"ब्याट्रि <xliff:g id="NUMBER">%d</xliff:g> प्रतिशत"</string>
+    <string name="accessibility_settings_button" msgid="799583911231893380">"प्रणाली सेटिङहरू"</string>
+    <string name="accessibility_notifications_button" msgid="4498000369779421892">"सूचनाहरू।"</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_silent" msgid="9061243307939135383">"घन्टी मौन।"</string>
+    <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> खारेज गरिएको छ।"</string>
+    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"सूचना खारेज।"</string>
+    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"सूचना कक्ष।"</string>
+    <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"द्रुत सेटिङहरू"</string>
+    <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"वर्तमान अनुप्रयोगहरू"</string>
+    <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"प्रयोगकर्ता <xliff:g id="USER">%s</xliff:g>।"</string>
+    <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>। <xliff:g id="NETWORK">%2$s</xliff:g>"</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" msgid="4196876722090224753">"हवाजहाज मोड <xliff:g id="STATE">%s</xliff:g>।"</string>
+    <string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"ब्लुटुथ <xliff:g id="STATE">%s</xliff:g>।"</string>
+    <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"<xliff:g id="TIME">%s</xliff:g>को लागि सङ्केत घन्टी सेट गरिएको"</string>
+    <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G डेटा अक्षम गरियो"</string>
+    <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G डेटा असक्षम गरियो"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"मोबाइल डेटा अक्षम गरियो"</string>
+    <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"डेटा अक्षम गरियो"</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"तपाईँ निर्दिष्ट डेटा उपयोग सीमामा पुग्नु भएको छ।\n\nयदि तपाईँले डेटालाई पुनःसक्षम पार्नु भयो भने तपाईँलाई अर्को संचालकबाट शुल्क लगाउन सक्छ।"</string>
+    <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"डेटा पुनः सक्षम गर्नुहोस्"</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="accessibility_clear_all" msgid="5235938559247164925">"सबै सूचनाहरू हटाउनुहोस्।"</string>
+    <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"अनुप्रयोगको जानकारी"</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="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="start_dreams" msgid="7219575858348719790">"दिवासपना"</string>
+    <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"उडान मोड"</string>
+    <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"चार्ज हुँदै, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"चार्ज भयो"</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_brightness_label" msgid="6968372297018755815">"चमक"</string>
+    <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"स्वतः घुमाइ"</string>
+    <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"घुम्ने लक गरेको"</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>
+    <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"आकस्मिक कल मात्र"</string>
+    <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_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">"वाइ-फाइ बन्द"</string>
+    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"वाइ-फाइ प्रदर्शन"</string>
+    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"ताररहित प्रदर्शन"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"उज्यालपन"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"स्वतः"</string>
+    <string name="status_bar_help_title" msgid="1199237744086469217">"यहाँ जानकारीहरू देखा पर्छन्"</string>
+    <string name="status_bar_help_text" msgid="7874607155052076323">"तल हुत्त्याएर तिनीहरूलाई सधैं पहुँच गर्नुहोस्\nप्रणाली नियन्त्रणको लागि पुनः तल हुत्त्याउनुहोस्"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 66f0a35..46b14a4 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"Systeem-UI"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Wissen"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Niet storen"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Meldingen weergeven"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Verwijderen uit lijst"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"App-info"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Geen recente apps"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Sluit de oplader aan"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"De accu raakt leeg."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> resterend"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"Opladen via USB niet ondersteund."\n"Gebruik alleen de bijgeleverde oplader."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"Opladen via USB niet ondersteund.\nGebruik alleen de bijgeleverde oplader."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Accugebruik"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Instellingen"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wifi"</string>
@@ -59,19 +57,17 @@
     <string name="always_use_device" msgid="1450287437017315906">"Standaard gebruiken voor dit USB-apparaat"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Standaard gebruiken voor dit USB-accessoire"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"USB-foutopsporing toestaan?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"De vingerafdruk voor de RSA-sleutel van de computer is:"\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"De vingerafdruk voor de RSA-sleutel van de computer is:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Altijd toestaan vanaf deze computer"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom om scherm te vullen"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Rek uit v. schermvulling"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Compatibiliteitszoom"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Wanneer een app is ontworpen voor een kleiner scherm, wordt naast de klok een zoomknop weergegeven."</string>
-    <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Schermafbeelding opslaan..."</string>
-    <string name="screenshot_saving_title" msgid="8242282144535555697">"Schermafbeelding opslaan..."</string>
-    <string name="screenshot_saving_text" msgid="2419718443411738818">"Schermafbeelding wordt opgeslagen."</string>
-    <string name="screenshot_saved_title" msgid="6461865960961414961">"Schermafbeelding gemaakt."</string>
-    <string name="screenshot_saved_text" msgid="1152839647677558815">"Raak aan om uw schermafbeelding te bekijken."</string>
-    <string name="screenshot_failed_title" msgid="705781116746922771">"Schermafbeelding is niet gemaakt."</string>
-    <string name="screenshot_failed_text" msgid="8134011269572415402">"Kan schermafbeelding niet opslaan. Mogelijk is de opslag in gebruik."</string>
+    <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Screenshot opslaan..."</string>
+    <string name="screenshot_saving_title" msgid="8242282144535555697">"Screenshot opslaan..."</string>
+    <string name="screenshot_saving_text" msgid="2419718443411738818">"Screenshot wordt opgeslagen."</string>
+    <string name="screenshot_saved_title" msgid="6461865960961414961">"Screenshot gemaakt."</string>
+    <string name="screenshot_saved_text" msgid="1152839647677558815">"Raak aan om uw screenshot te bekijken."</string>
+    <string name="screenshot_failed_title" msgid="705781116746922771">"Screenshot is niet gemaakt."</string>
+    <string name="screenshot_failed_text" msgid="8134011269572415402">"Kan screenshot niet opslaan. Mogelijk is de opslag in gebruik."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Opties voor USB-bestandsoverdracht"</string>
     <string name="use_mtp_button_title" msgid="4333504413563023626">"Koppelen als mediaspeler (MTP)"</string>
     <string name="use_ptp_button_title" msgid="7517127540301625751">"Koppelen als camera (PTP)"</string>
@@ -160,17 +156,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G-gegevens uitgeschakeld"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobiele gegevens uitgeschakeld"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Gegevens uitgeschakeld"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"U heeft de gestelde limiet voor gegevensverbruik bereikt."\n\n"Als u gegevens opnieuw inschakelt, kunnen er kosten in rekening worden gebracht door uw provider."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"U heeft de gestelde limiet voor gegevensverbruik bereikt.\n\nAls u gegevens opnieuw inschakelt, kunnen er kosten in rekening worden gebracht door uw provider."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Gegevens opnieuw inschakelen"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Geen internetverbinding"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Verbonden via wifi"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Zoeken naar GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Locatie bepaald met GPS"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Locatieverzoeken actief"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Alle meldingen wissen."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"App-info"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Sluiten"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Meldingen uit"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Tik hier om meldingen weer in te schakelen."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Scherm wordt automatisch geroteerd."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Het scherm is nu vergrendeld in liggende stand."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Het scherm is nu vergrendeld in staande stand."</string>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Automatische rotatie"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Rotatie vergrendeld"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Invoermethode"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Locatie in gebruik"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Locatie"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Locatie uit"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Media-apparaat"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Alleen noodoproepen"</string>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Draadloze display"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Helderheid"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATISCH"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Meldingen worden hier weergegeven"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"U kunt de meldingen op elk gewenst moment openen door met uw vinger omlaag te vegen."\n"Veeg nogmaals met uw vinger omlaag om de systeembesturingselementen weer te geven."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Netwerk kan worden gecontroleerd"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 67e54de..22bb708 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"Interfejs"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Wyczyść"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Nie przeszkadzać"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Pokaż powiadomienia"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Usuń z listy"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Informacje o aplikacji"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Brak ostatnio uruchomionych aplikacji."</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Podłącz ładowarkę"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Bateria wkrótce się rozładuje."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"Pozostało: <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"Ładowanie przy użyciu złącza USB nie jest obsługiwane."\n"Należy używać tylko dołączonej ładowarki."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"Ładowanie przy użyciu złącza USB nie jest obsługiwane.\nNależy używać tylko dołączonej ładowarki."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Użycie baterii"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Ustawienia"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <string name="always_use_device" msgid="1450287437017315906">"Używaj domyślnie dla tego urządzenia USB"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Używaj domyślnie dla tego akcesorium USB"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"Zezwalać na debugowanie USB?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"Odcisk cyfrowy klucza RSA komputera to:"\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"Odcisk cyfrowy klucza RSA komputera to:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Zawsze zezwalaj z tego komputera"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Powiększ, aby wypełnić ekran"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Rozciągnij, aby wypełnić ekran"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Powiększenie w trybie zgodności"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Jeśli aplikacja została przystosowana do mniejszego ekranu, obok zegara zostanie wyświetlony element sterujący powiększeniem."</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Zapisywanie zrzutu ekranu..."</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"Zapisywanie zrzutu ekranu..."</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"Zapisywanie zrzutu ekranu."</string>
@@ -160,17 +156,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Wyłączono transmisję danych 4G"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Transmisja danych została wyłączona"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Wyłączono transmisję danych"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Ustawiony limit transmisji danych został osiągnięty."\n\n"Jeśli ponownie włączysz przesyłanie danych, operator może naliczyć dodatkowe opłaty."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Ustawiony limit transmisji danych został osiągnięty.\n\nJeśli ponownie włączysz przesyłanie danych, operator może naliczyć dodatkowe opłaty."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Włącz transmisję danych"</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>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Wyszukiwanie sygnału GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Lokalizacja z GPSa"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Prośby o lokalizację są aktywne"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Usuń wszystkie powiadomienia."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"O aplikacji"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Zamknij"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Powiadomienia wyłączone"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Kliknij tutaj, by przywrócić powiadomienia."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekran zostanie obrócony automatycznie."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Ekran jest zablokowany w orientacji poziomej."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Ekran jest zablokowany w orientacji pionowej."</string>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Autoobracanie"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Obracanie jest zablokowane"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Metoda wprowadzania"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Lokalizacja w użyciu"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Lokalizacja"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Lokalizacja wyłączona"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Urządzenie multimedialne"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Tylko połączenia alarmowe"</string>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Wyświetlacz bezprzewodowy"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Jasność"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATYCZNA"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Tutaj pokazują się powiadomienia"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Możesz je otworzyć w dowolnej chwili, przesuwając w dół."\n"Przesuń jeszcze raz w dół, by otworzyć ustawienia systemowe."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Sieć może być monitorowana"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index ffbfa88..42b6a62 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"IU do sist."</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Limpar"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Não incomodar"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Mostrar notificações"</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 da aplicação"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Não existem aplicações recentes"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Ligar carregador"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"A bateria está a ficar fraca."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> restante"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"Carregamento USB não suportado. "\n"Utilize apenas o carregador fornecido."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"Carregamento USB não suportado. \nUtilize apenas o carregador fornecido."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Utilização da bateria"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Definições"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <string name="always_use_device" msgid="1450287437017315906">"Utilizar por predefinição para este aparelho USB"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Utilizar por predefinição para este acessório USB"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"Permitir depuração USB?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"A impressão digital da chave RSA do computador é:"\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"A impressão digital da chave RSA do computador é:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Permitir sempre a partir deste computador"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom para preencher o ecrã"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Esticar p. caber em ec. int."</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Zoom de compatibilidade"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Sempre que uma aplicação tiver sido concebida para ecrãs mais pequenos, aparecerá um controlo de zoom junto ao relógio."</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"A guardar captura de ecrã..."</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"A guardar captura de ecrã..."</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"A guardar captura de ecrã."</string>
@@ -160,17 +156,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Os dados 4G estão desativados"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Os dados móveis estão desativados"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Dados desativados"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Atingiu o limite de utilização de dados especificado."\n\n"Se voltar a ativar os dados, pode levar a uma cobrança por parte do operador."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Atingiu o limite de utilização de dados especificado.\n\nSe voltar a ativar os dados, pode levar a uma cobrança por parte do operador."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Reativar dados"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Sem ligação internet"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi ligado"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"A procurar GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Localização definida por GPS"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Pedidos de localização ativos"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Limpar todas as notificações."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informações da aplicação"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Fechar"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Notificações desativadas"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Toque aqui para voltar a ativar as notificações."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"O ecrã será rodado automaticamente."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"O ecrã está bloqueado na orientação horizontal."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"O ecrã está bloqueado na orientação vertical."</string>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Rodar automat."</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Rotação Bloqueada"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Método de Introdução"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Localização em utilização"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Localização"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Localização Desativada"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Dispositivo multimédia"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Apenas Chamadas de Emergência"</string>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Display Sem Fios"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brilho"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMÁTICO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"As notificações são apresentadas aqui"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Pode aceder em qualquer altura, deslizando rapidamente para baixo com o dedo."\n"Deslize novamente para baixo para aceder aos controlos do sistema."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"A rede pode ser monitorizada"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index ffe4027..51ce1c6 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"Interf sist"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Limpar"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Não perturbe"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Mostrar notificações"</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 aplicativo"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Nenhum aplicativo recente"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Conecte o carregador"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"A bateria está ficando baixa."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> restante"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"O carregamento via USB não é suportado."\n"Use apenas o carregador fornecido."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"O carregamento via USB não é suportado.\nUse apenas o carregador fornecido."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Uso da bateria"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Configurações"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <string name="always_use_device" msgid="1450287437017315906">"Usar por padrão para este dispositivo USB"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Usar por padrão para este acessório USB"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"Permitir a depuração USB?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"A impressão digital da chave RSA deste computador é:"\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"A impressão digital da chave RSA deste computador é:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Sempre permitir a partir deste computador"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom p/ preencher a tela"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Ampliar p/ preencher tela"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Zoom em modo de compatibilidade"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Quando um aplicativo é desenvolvido para uma tela menor, um controle de zoom é exibido perto do relógio."</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Salvando captura de tela..."</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"Salvando captura de tela..."</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"A captura de tela está sendo salva."</string>
@@ -162,17 +158,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Dados 4G desativados"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Dados móveis desativados"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Dados desativados"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Você atingiu o limite de uso de dados especificados."\n\n"Se você reativá-los, poderá receber uma cobrança do operador."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Você atingiu o limite de uso de dados especificados.\n\nSe você reativá-los, poderá receber uma cobrança do operador."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Reativar dados"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Sem conexão à Internet"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi conectado"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Buscando GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Local definido por GPS"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Solicitações de localização ativas"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Limpar todas as notificações."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informações do aplicativo"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Fechar"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Notificações desativadas"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Toque aqui para ativar as notificações novamente."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"A tela girará automaticamente."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"A tela está bloqueada na orientação paisagem."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"A tela está bloqueada na orientação retrato."</string>
@@ -189,7 +183,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Girar automat."</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Rotação bloqueada"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Método de entrada"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Local em uso"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Localização"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Localização desativada"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Dispositivo de mídia"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Somente chamadas de emergência"</string>
@@ -204,6 +199,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Display sem fio"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brilho"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"As notificações aparecem aqui"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Acesse a qualquer momento deslizando para baixo."\n"Deslize para baixo novamente para acessar os controles do sistema."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"A rede pode ser monitorada"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-rm/strings.xml b/packages/SystemUI/res/values-rm/strings.xml
index 9e5dbe1..c26c055 100644
--- a/packages/SystemUI/res/values-rm/strings.xml
+++ b/packages/SystemUI/res/values-rm/strings.xml
@@ -22,10 +22,6 @@
     <!-- no translation found for app_label (7164937344850004466) -->
     <skip />
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Stizzar"</string>
-    <!-- no translation found for status_bar_do_not_disturb_button (5812628897510997853) -->
-    <skip />
-    <!-- no translation found for status_bar_please_disturb_button (3345398298841572813) -->
-    <skip />
     <!-- no translation found for status_bar_recent_remove_item_title (6026395868129852968) -->
     <skip />
     <!-- no translation found for status_bar_recent_inspect_item_title (7793624864528818569) -->
@@ -96,10 +92,6 @@
     <skip />
     <!-- no translation found for compat_mode_off (4434467572461327898) -->
     <skip />
-    <!-- no translation found for compat_mode_help_header (7969493989397529910) -->
-    <skip />
-    <!-- no translation found for compat_mode_help_body (4946726776359270040) -->
-    <skip />
     <!-- no translation found for screenshot_saving_ticker (7403652894056693515) -->
     <skip />
     <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
@@ -302,16 +294,12 @@
     <skip />
     <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
     <skip />
+    <!-- no translation found for accessibility_location_active (2427290146138169014) -->
+    <skip />
     <!-- no translation found for accessibility_clear_all (5235938559247164925) -->
     <skip />
     <!-- no translation found for status_bar_notification_inspect_item_title (1163547729015390250) -->
     <skip />
-    <!-- no translation found for close_universe (3736513750241754348) -->
-    <skip />
-    <!-- no translation found for notifications_off_title (8936620513608443224) -->
-    <skip />
-    <!-- no translation found for notifications_off_text (2529001315769385273) -->
-    <skip />
     <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
     <skip />
     <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
@@ -344,7 +332,9 @@
     <skip />
     <!-- no translation found for quick_settings_ime_label (7073463064369468429) -->
     <skip />
-    <!-- no translation found for quick_settings_location_label (3292451598267467545) -->
+    <!-- no translation found for quick_settings_location_label (5011327048748762257) -->
+    <skip />
+    <!-- no translation found for quick_settings_location_off_label (7464544086507331459) -->
     <skip />
     <!-- no translation found for quick_settings_media_device_label (1302906836372603762) -->
     <skip />
@@ -374,8 +364,6 @@
     <skip />
     <!-- no translation found for quick_settings_brightness_dialog_auto_brightness_label (5064982743784071218) -->
     <skip />
-    <!-- no translation found for status_bar_help_title (1199237744086469217) -->
-    <skip />
-    <!-- no translation found for status_bar_help_text (7874607155052076323) -->
+    <!-- no translation found for ssl_ca_cert_warning (5848402127455021714) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index bea8141..4bd25f8 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <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_do_not_disturb_button" msgid="5812628897510997853">"Nu deranjaţi"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Afişaţi notificări"</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_no_recent_apps" msgid="6576392951053994640">"Nu există aplicaţii recente"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Conectaţi încărcătorul"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Bateria este descărcată."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"Rămas: <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"Încărcarea USB nu este acceptată. "\n"Utilizaţi numai încărcătorul furnizat."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"Încărcarea USB nu este acceptată. \nUtilizaţi numai încărcătorul furnizat."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Utilizarea bateriei"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Setări"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <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_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_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="compat_mode_on" msgid="6623839244840638213">"Zoom pt. a umple ecranul"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Înt. pt. a umple ecranul"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Zoom de compatibilitate"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Atunci când o aplicaţie a fost concepută pentru un ecran mai mic, o comandă pentru mărire/micşorare va apărea alături de ceas."</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Se salv. captura de ecran..."</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"Se salvează captura de ecran..."</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"Captura de ecran este salvată."</string>
@@ -160,17 +156,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Datele 4G au fost dezactivate"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Datele mobile au fost dezactivate"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Utilizare date dezactivată"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Aţi atins limita specificată pentru utilizarea datelor."\n\n"Dacă reactivaţi datele, puteţi fi taxat(ă) de către operator."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Aţi atins limita specificată pentru utilizarea datelor.\n\nDacă reactivaţi datele, puteţi fi taxat(ă) de către operator."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Reactivaţi datele"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Fără conex. internet"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi conectat"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Se caută GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Locaţie setată prin GPS"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Solicitări locație active"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Ștergeţi toate notificările."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informaţii despre aplicaţie"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Închideţi"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Notificările sunt dezactivate"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Apăsaţi aici pentru a reactiva notificările."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ecranul se va roti în mod automat."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Ecranul este blocat în orientarea de tip peisaj."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Ecranul este blocat în orientarea de tip portret."</string>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Rotire automată"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Rotire blocată"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Metodă de introducere"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Locaţie în uz"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Locație"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Localizarea este dezactivată"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Dispozitiv media"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Numai apeluri de urgenţă"</string>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Ecran wireless"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Luminozitate"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMAT"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Notificările se afişează aici"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Accesaţi-le oricând glisând în jos."\n"Glisaţi în jos din nou pentru comenzile sistemului."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Rețeaua poate fi monitorizată"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 5525ed8..0a45aa9 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -21,8 +21,6 @@
     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_do_not_disturb_button" msgid="5812628897510997853">"Не беспокоить"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Показать уведомления"</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="6576392951053994640">"Список недавно использованных приложений пуст."</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Подключите зарядное устройство"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Батарея разряжена."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"Осталось <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"Зарядка через порт USB не поддерживается."\n"Используйте только зарядное устройство из комплекта поставки."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"Зарядка через порт USB не поддерживается.\nИспользуйте только зарядное устройство из комплекта поставки."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Подробнее"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Настройки"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <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="compat_mode_on" msgid="6623839244840638213">"Подогнать по размерам экрана"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Растянуть на весь экран"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Масштаб и совместимость"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Если приложение рассчитано на экран меньших размеров, рядом с часами появятся средства масштабирования."</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>
@@ -162,17 +158,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Передача данных по каналу 4G отключена"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Моб. Интернет отключен"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Передача данных отключена"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Достигнут лимит трафика."\n\n"При восстановлении подключения оператор может взимать плату за передачу данных."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Достигнут лимит трафика.\n\nПри восстановлении подключения оператор может взимать плату за передачу данных."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Восстановить подключение"</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="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="accessibility_clear_all" msgid="5235938559247164925">"Удалить все уведомления"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"О приложении"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Закрыть"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Уведомления отключены"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Нажмите здесь, чтобы снова включить уведомления."</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>
@@ -191,7 +185,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Автоповорот"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Автоповорот выкл."</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Способ ввода"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Геосервис вкл."</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>
@@ -206,6 +201,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Wi-Fi-монитор"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Яркость"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АВТОНАСТРОЙКА"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Это панель уведомлений"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Ее можно открыть, пролистнув экран вниз."\n"Чтобы открыть настройки, проведите пальцем вниз ещё раз."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Действия в сети могут отслеживаться"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-si-rLK-land/strings.xml b/packages/SystemUI/res/values-si-rLK-land/strings.xml
new file mode 100644
index 0000000..b5aba2a
--- /dev/null
+++ b/packages/SystemUI/res/values-si-rLK-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * 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.
+ */
+ -->
+
+<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>
+</resources>
diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml
new file mode 100644
index 0000000..24accd1
--- /dev/null
+++ b/packages/SystemUI/res/values-si-rLK/strings.xml
@@ -0,0 +1,206 @@
+<?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: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="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="6576392951053994640">"මෑත උපාංග නැත"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"මෑත යෙදුම් ඉවතලන්න"</string>
+  <plurals name="status_bar_accessibility_recent_apps">
+    <item quantity="one" msgid="5854176083865845541">"මෑත යෙදුම් 1 ක්"</item>
+    <item quantity="other" msgid="1040784359794890744">"මෑත යෙදුම් %d ක්"</item>
+  </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="battery_low_title" msgid="2783104807551211639">"අරෝපකයට සම්බන්ධ කරන්න"</string>
+    <string name="battery_low_subtitle" msgid="1752040062087829196">"බැටරිය අඩු වෙමින් පවතී."</string>
+    <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> ක් ඉතිරියි"</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB ආරෝපණය සහය නොදක්වයි.\nසපයන ලද ආරෝපකය පමණක් භාවිතා කරන්න."</string>
+    <string name="battery_low_why" msgid="7279169609518386372">"බැටරි භාවිතය"</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_airplane" msgid="4879879698500955300">"අහස්යානා ආකාරය"</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">"බ්ලූටූත් ටෙදර් කරා"</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_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="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>
+    <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_saved_text" msgid="1152839647677558815">"ඔබගේ තිර රුව බැලීමට ස්පර්ශ කරන්න."</string>
+    <string name="screenshot_failed_title" msgid="705781116746922771">"තිර රුව ග්‍රහණය කිරීමට නොහැකි විය."</string>
+    <string name="screenshot_failed_text" msgid="8134011269572415402">"තිර රුව සුරැකීමට නොහැකි විය. ආචයනය භාවිතාවේ තිබෙනවා විය හැක."</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="accessibility_back" msgid="567011538994429120">"ආපසු"</string>
+    <string name="accessibility_home" msgid="8217216074895377641">"මුල් පිටුව"</string>
+    <string name="accessibility_menu" msgid="316839303324695949">"මෙනුව"</string>
+    <string name="accessibility_recent" msgid="8571350598987952883">"මෑත යෙදුම්"</string>
+    <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"ආදාන ක්‍රමය මාරු කිරීමේ බොත්තම."</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_no_battery" msgid="358343022352820946">"බැටරිය නැත."</string>
+    <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"බැටරිය තීරු එකයි."</string>
+    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"බැටරිය තීරු දෙකයි."</string>
+    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"බැටරිය තීරු තුනයි."</string>
+    <string name="accessibility_battery_full" msgid="8909122401720158582">"බැටරිය පිරී ඇත."</string>
+    <string name="accessibility_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">"දත්ත තීරු 2."</string>
+    <string name="accessibility_data_three_bars" msgid="9167670452395038520">"දත්ත තීරු 3."</string>
+    <string name="accessibility_data_signal_full" msgid="2708384608124519369">"දත්ත සංඥාව පිරී ඇත."</string>
+    <string name="accessibility_wifi_off" msgid="3177380296697933627">"Wifi අක්‍රියයි."</string>
+    <string name="accessibility_no_wifi" msgid="1425476551827924474">"Wifi සම්බන්ධ කර නොමැත."</string>
+    <string name="accessibility_wifi_one_bar" msgid="7735893178010724377">"Wifi තීරු එකයි."</string>
+    <string name="accessibility_wifi_two_bars" msgid="4994274250497262434">"Wifi තීරු දෙකයි."</string>
+    <string name="accessibility_wifi_three_bars" msgid="3495755044276588384">"WiFi තීරු තුනයි."</string>
+    <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"Wifi සංඥාව පිරී ඇත."</string>
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"WiMAX නැත."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX තීරු එකයි."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX තීරු දෙකයි."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX තීරු තුනයි."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX සංඥාව පිරී ඇත."</string>
+    <string name="accessibility_no_signal" msgid="7064645320782585167">"සංඥා නැත."</string>
+    <string name="accessibility_not_connected" msgid="6395326276213402883">"සම්බන්ධ වී නැත."</string>
+    <string name="accessibility_zero_bars" msgid="3806060224467027887">"තීරු ශුන්‍යයි."</string>
+    <string name="accessibility_one_bar" msgid="1685730113192081895">"තීරු එක."</string>
+    <string name="accessibility_two_bars" msgid="6437363648385206679">"තීරු දෙකයි."</string>
+    <string name="accessibility_three_bars" msgid="2648241415119396648">"තීරු තුනයි."</string>
+    <string name="accessibility_signal_full" msgid="9122922886519676839">"සංඥාව පිරී ඇත."</string>
+    <string name="accessibility_desc_on" msgid="2385254693624345265">"සක්‍රීයයි."</string>
+    <string name="accessibility_desc_off" msgid="6475508157786853157">"අක්‍රිය කරන්න."</string>
+    <string name="accessibility_desc_connected" msgid="8366256693719499665">"සම්බන්ධිතයි."</string>
+    <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+    <string name="accessibility_data_connection_1x" msgid="994133468120244018">"1 X"</string>
+    <string name="accessibility_data_connection_hspa" msgid="2032328855462645198">"HSPA"</string>
+    <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+    <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+    <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+    <string name="accessibility_data_connection_lte" msgid="5413468808637540658">"LTE"</string>
+    <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_bluetooth_tether" msgid="4102784498140271969">"බ්ලූටූත් ටෙදරින්."</string>
+    <string name="accessibility_airplane_mode" msgid="834748999790763092">"අහස්යානා ආකාරය."</string>
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"බැටරි ප්‍රතිශතය <xliff:g id="NUMBER">%d</xliff:g>"</string>
+    <string name="accessibility_settings_button" msgid="799583911231893380">"පද්ධති සැකසීම්."</string>
+    <string name="accessibility_notifications_button" msgid="4498000369779421892">"දැනුම්දීම්."</string>
+    <string name="accessibility_remove_notification" msgid="3603099514902182350">"දැනුම්දීම හිස් කරන්න."</string>
+    <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS සබල කර ඇත."</string>
+    <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS ලබා ගනිමින්."</string>
+    <string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter ක්‍රියාත්මකයි."</string>
+    <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"හඬ නඟනය කම්පනය වේ."</string>
+    <string name="accessibility_ringer_silent" msgid="9061243307939135383">"හඬ නඟනය නිශ්ශබ්දයි."</string>
+    <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> අස් කර ඇත."</string>
+    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"දැනුම්දීම නිෂ්ප්‍රභා කරඇත."</string>
+    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"දැනුම්දීම් ආවරණය."</string>
+    <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"ක්ෂණික සැකසීම්."</string>
+    <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"මෑත කාලීන යෙදුම්."</string>
+    <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"පරිශීලකයා <xliff:g id="USER">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</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" msgid="4196876722090224753">"අහස්යානා ආකාරය <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"බ්ලූටූත් <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"<xliff:g id="TIME">%s</xliff:g> සඳහා සීනුව සකස් කර ඇත."</string>
+    <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G දත්ත අබල කර ඇත"</string>
+    <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G දත්ත අබල කරන ලදි"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"ජංගම දත්ත අබල කර ඇත"</string>
+    <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"දත්ත අබල කර ඇත"</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"ඔබ නියමිත දත්ත භාවිත සීමාවට ළඟා වී ඇත.\n\nඔබ දත්ත නැවත සබල කළහොත් වාහකයා ඔබගෙන් ඇතැම් විට අය කරගත හැක."</string>
+    <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"නැවත දත්ත සබල කරන්න"</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="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="accessibility_clear_all" msgid="5235938559247164925">"සියලු දැනුම්දීම් හිස් කරන්න."</string>
+    <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"යෙදුම් තොරතුරු"</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="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="start_dreams" msgid="7219575858348719790">"දවල් හීනය"</string>
+    <string name="ethernet_label" msgid="7967563676324087464">"ඊතර නෙට්"</string>
+    <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"අහස්යානා ආකාරය"</string>
+    <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"ආරෝපණය වෙමින්, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"අරෝපිතයි"</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_brightness_label" msgid="6968372297018755815">"දීප්තිය"</string>
+    <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"ස්වයංක්‍රීය කරකැවීම"</string>
+    <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"භ්‍රමණය අගුළු දමා ඇත"</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>
+    <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"හදිසි ඇමතුම් පමණි"</string>
+    <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_wifi_label" msgid="9135344704899546041">"Wi-Fi"</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_display_label" msgid="6893592964463624333">"Wi-Fi සංදර්ශකය"</string>
+    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"නොරැහැන් සංදර්ශකය"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"දීප්තිමත් බව"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ස්වයංක්‍රීය"</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"ඇතැම් විට ජාලය නිරීක්ෂණය විය හැක"</string>
+    <string name="done_button" msgid="1759387181766603361">"හරි"</string>
+    <string name="ssl_ca_cert_dialog_title" msgid="1273796967092027291">"ජාල නිරීක්ෂණය කිරීම"</string>
+    <string name="ssl_ca_cert_info_message" msgid="5430320539555358452">"මෙම උපාංගය කළමනාකරණය කරනුයේ: <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>.\n\nඔබගේ පරිපාලකයා ඊ-තැපැල්, යෙදුම්, සහ ආරක්‍ෂිත වෙබ් අඩවි ඇතුළුව ඔබගේ ජාල ක්‍රියාකාරකම් නිරීක්ෂණය කිරීමට හැකියාව ඇත.\n\nවැඩි විස්තර සඳහා, ඔබේ පරිපාලකයා සම්බන්ධ කරගන්න."</string>
+    <string name="ssl_ca_cert_warning_message" msgid="2033091656129963669">"තුන්වන පාර්ශවයකට ඔබගේ ජාලය නිරීක්ෂණය කිරීමට හැකියාව ඇත\nක්‍රියාකාරකම්, ඊ-තැපැල්, යෙදුම් සහ ආරක්‍ෂිත වෙබ් අඩවි ඇතුළුව.\n\nඔබගේ උපාංගය මත ස්ථාපිත විශ්වාසදයී අක්තපත්‍ර මෙය සිදුවීමේ හැකියාව ඇතිකරයි."</string>
+    <string name="ssl_ca_cert_settings_button" msgid="7946956977377166709">"විශ්වාසදායී අක්තපත්‍ර පරික්ෂා කරන්න"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
new file mode 100644
index 0000000..f28cd16
--- /dev/null
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -0,0 +1,204 @@
+<?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: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="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="6576392951053994640">"මෑත උපාංග නැත"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"මෑත යෙදුම් ඉවතලන්න"</string>
+  <plurals name="status_bar_accessibility_recent_apps">
+    <item quantity="one" msgid="5854176083865845541">"මෑත යෙදුම් 1 ක්"</item>
+    <item quantity="other" msgid="1040784359794890744">"මෑත යෙදුම් %d ක්"</item>
+  </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="battery_low_title" msgid="2783104807551211639">"අරෝපකයට සම්බන්ධ කරන්න"</string>
+    <string name="battery_low_subtitle" msgid="1752040062087829196">"බැටරිය අඩු වෙමින් පවතී."</string>
+    <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> ක් ඉතිරියි"</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB ආරෝපණය සහය නොදක්වයි.\nසපයන ලද ආරෝපකය පමණක් භාවිතා කරන්න."</string>
+    <string name="battery_low_why" msgid="7279169609518386372">"බැටරි භාවිතය"</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_airplane" msgid="4879879698500955300">"අහස්යානා ආකාරය"</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">"බ්ලූටූත් ටෙදර් කරා"</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_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="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>
+    <string name="compat_mode_on" msgid="6623839244840638213">"තිරය පිරවීමට විශාලනය කරන්න"</string>
+    <string name="compat_mode_off" msgid="4434467572461327898">"තිරය පිරවීමට අදින්න"</string>
+    <string name="compat_mode_help_header" msgid="7969493989397529910">"ගැළපෙන විශාලනය"</string>
+    <string name="compat_mode_help_body" msgid="4946726776359270040">"කුඩා තිරයක් සඳහා යෙදුමක් නිර්මාණය කළ විට, විශාලනය පාලකය ඔරලෝසුව ළඟින් පෙන්වයි."</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="1152839647677558815">"ඔබගේ තිර රුව බැලීමට ස්පර්ශ කරන්න."</string>
+    <string name="screenshot_failed_title" msgid="705781116746922771">"තිර රුව ග්‍රහණය කිරීමට නොහැකි විය."</string>
+    <string name="screenshot_failed_text" msgid="8134011269572415402">"තිර රුව සුරැකීමට නොහැකි විය. ආචයනය භාවිතාවේ තිබෙනවා විය හැක."</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="accessibility_back" msgid="567011538994429120">"ආපසු"</string>
+    <string name="accessibility_home" msgid="8217216074895377641">"මුල් පිටුව"</string>
+    <string name="accessibility_menu" msgid="316839303324695949">"මෙනුව"</string>
+    <string name="accessibility_recent" msgid="8571350598987952883">"මෑත යෙදුම්"</string>
+    <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"ආදාන ක්‍රමය මාරු කිරීමේ බොත්තම."</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_no_battery" msgid="358343022352820946">"බැටරිය නැත."</string>
+    <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"බැටරිය තීරු එකයි."</string>
+    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"බැටරිය තීරු දෙකයි."</string>
+    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"බැටරිය තීරු තුනයි."</string>
+    <string name="accessibility_battery_full" msgid="8909122401720158582">"බැටරිය පිරී ඇත."</string>
+    <string name="accessibility_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">"දත්ත තීරු 2."</string>
+    <string name="accessibility_data_three_bars" msgid="9167670452395038520">"දත්ත තීරු 3."</string>
+    <string name="accessibility_data_signal_full" msgid="2708384608124519369">"දත්ත සංඥාව පිරී ඇත."</string>
+    <string name="accessibility_wifi_off" msgid="3177380296697933627">"Wifi අක්‍රියයි."</string>
+    <string name="accessibility_no_wifi" msgid="1425476551827924474">"Wifi සම්බන්ධ කර නොමැත."</string>
+    <string name="accessibility_wifi_one_bar" msgid="7735893178010724377">"Wifi තීරු එකයි."</string>
+    <string name="accessibility_wifi_two_bars" msgid="4994274250497262434">"Wifi තීරු දෙකයි."</string>
+    <string name="accessibility_wifi_three_bars" msgid="3495755044276588384">"WiFi තීරු තුනයි."</string>
+    <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"Wifi සංඥාව පිරී ඇත."</string>
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"WiMAX නැත."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX තීරු එකයි."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX තීරු දෙකයි."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX තීරු තුනයි."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX සංඥාව පිරී ඇත."</string>
+    <string name="accessibility_no_signal" msgid="7064645320782585167">"සංඥා නැත."</string>
+    <string name="accessibility_not_connected" msgid="6395326276213402883">"සම්බන්ධ වී නැත."</string>
+    <string name="accessibility_zero_bars" msgid="3806060224467027887">"තීරු ශුන්‍යයි."</string>
+    <string name="accessibility_one_bar" msgid="1685730113192081895">"තීරු එක."</string>
+    <string name="accessibility_two_bars" msgid="6437363648385206679">"තීරු දෙකයි."</string>
+    <string name="accessibility_three_bars" msgid="2648241415119396648">"තීරු තුනයි."</string>
+    <string name="accessibility_signal_full" msgid="9122922886519676839">"සංඥාව පිරී ඇත."</string>
+    <string name="accessibility_desc_on" msgid="2385254693624345265">"සක්‍රීයයි."</string>
+    <string name="accessibility_desc_off" msgid="6475508157786853157">"අක්‍රිය කරන්න."</string>
+    <string name="accessibility_desc_connected" msgid="8366256693719499665">"සම්බන්ධිතයි."</string>
+    <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+    <string name="accessibility_data_connection_1x" msgid="994133468120244018">"1 X"</string>
+    <string name="accessibility_data_connection_hspa" msgid="2032328855462645198">"HSPA"</string>
+    <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+    <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+    <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+    <string name="accessibility_data_connection_lte" msgid="5413468808637540658">"LTE"</string>
+    <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_bluetooth_tether" msgid="4102784498140271969">"බ්ලූටූත් ටෙදරින්."</string>
+    <string name="accessibility_airplane_mode" msgid="834748999790763092">"අහස්යානා ආකාරය."</string>
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"බැටරි ප්‍රතිශතය <xliff:g id="NUMBER">%d</xliff:g>"</string>
+    <string name="accessibility_settings_button" msgid="799583911231893380">"පද්ධති සැකසීම්."</string>
+    <string name="accessibility_notifications_button" msgid="4498000369779421892">"දැනුම්දීම්."</string>
+    <string name="accessibility_remove_notification" msgid="3603099514902182350">"දැනුම්දීම හිස් කරන්න."</string>
+    <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS සබල කර ඇත."</string>
+    <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS ලබා ගනිමින්."</string>
+    <string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter ක්‍රියාත්මකයි."</string>
+    <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"හඬ නඟනය කම්පනය වේ."</string>
+    <string name="accessibility_ringer_silent" msgid="9061243307939135383">"හඬ නඟනය නිශ්ශබ්දයි."</string>
+    <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> අස් කර ඇත."</string>
+    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"දැනුම්දීම නිෂ්ප්‍රභා කරඇත."</string>
+    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"දැනුම්දීම් ආවරණය."</string>
+    <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"ක්ෂණික සැකසීම්."</string>
+    <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"මෑත කාලීන යෙදුම්."</string>
+    <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"පරිශීලකයා <xliff:g id="USER">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</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" msgid="4196876722090224753">"අහස්යානා ආකාරය <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"බ්ලූටූත් <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"<xliff:g id="TIME">%s</xliff:g> සඳහා සීනුව සකස් කර ඇත."</string>
+    <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G දත්ත අබල කර ඇත"</string>
+    <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G දත්ත අබල කරන ලදි"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"ජංගම දත්ත අබල කර ඇත"</string>
+    <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"දත්ත අබල කර ඇත"</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"ඔබ නියමිත දත්ත භාවිත සීමාවට ළඟා වී ඇත.\n\nඔබ දත්ත නැවත සබල කළහොත් වාහකයා ඔබගෙන් ඇතැම් විට අය කරගත හැක."</string>
+    <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"නැවත දත්ත සබල කරන්න"</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="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="accessibility_clear_all" msgid="5235938559247164925">"සියලු දැනුම්දීම් හිස් කරන්න."</string>
+    <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"යෙදුම් තොරතුරු"</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="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="start_dreams" msgid="7219575858348719790">"දවල් හීනය"</string>
+    <string name="ethernet_label" msgid="7967563676324087464">"ඊතර නෙට්"</string>
+    <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"අහස්යානා ආකාරය"</string>
+    <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"ආරෝපණය වෙමින්, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"අරෝපිතයි"</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_brightness_label" msgid="6968372297018755815">"දීප්තිය"</string>
+    <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"ස්වයංක්‍රීය කරකැවීම"</string>
+    <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"භ්‍රමණය අගුළු දමා ඇත"</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>
+    <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"හදිසි ඇමතුම් පමණි"</string>
+    <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_wifi_label" msgid="9135344704899546041">"Wi-Fi"</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_display_label" msgid="6893592964463624333">"Wi-Fi සංදර්ශකය"</string>
+    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"නොරැහැන් සංදර්ශකය"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"දීප්තිමත් බව"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ස්වයංක්‍රීය"</string>
+    <string name="status_bar_help_title" msgid="1199237744086469217">"දැනුම්දීම් මෙතන පෙන්නුම් කරයි"</string>
+    <string name="status_bar_help_text" msgid="7874607155052076323">"පහලට සර්පණය කිරීමෙන් ඕනෑම වෙලාවක ඒවා වෙත පිවිසෙන්න.\nපද්ධති පාලක සඳහා නැවත පහළට සර්පණය කරන්න."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 79005f1..8a4ef39 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"UI systému"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Vymazať"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Nerušiť"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Zobraziť upozornenia"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Odstrániť zo zoznamu"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Informácie o aplikácii"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Žiadne nedávne aplikácie"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Pripojte nabíjačku"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Batéria je skoro vybitá."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"Zostáva: <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"Nabíjanie pomocou rozhrania USB nie je podporované."\n"Používajte iba nabíjačku, ktorá bola dodaná spolu so zariadením."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"Nabíjanie pomocou rozhrania USB nie je podporované.\nPoužívajte iba nabíjačku, ktorá bola dodaná spolu so zariadením."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Využitie 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>
@@ -59,12 +57,10 @@
     <string name="always_use_device" msgid="1450287437017315906">"Pre toto zariadenie USB použiť ako predvolené"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Pre toto periférne zar. USB použiť ako predvolené"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"Povoliť ladenie USB?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"Digitálny odtlačok RSA počítača je:"\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"Digitálny odtlačok RSA počítača je:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Vždy povoliť z tohto počítača"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Priblížiť na celú obrazovku"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Na celú obrazovku"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Úprava veľkosti z dôvodu kompatibility"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Ak je aplikácia navrhnutá pre menšiu obrazovku, zobrazí sa vedľa hodín ovládací prvok priblíženia."</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Prebieha ukladanie snímky obrazovky..."</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"Prebieha ukladanie snímky obrazovky..."</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"Snímka obrazovky sa ukladá."</string>
@@ -162,17 +158,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Dátové prenosy 4G sú zakázané"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobilné dátové prenosy sú zakázané"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Dáta boli zakázané"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Dosiahli ste stanovený limit využitia dát."\n\n"Ak dátové pripojenie znova povolíte, môže vám váš operátor účtovať poplatky."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Dosiahli ste stanovený limit využitia dát.\n\nAk dátové pripojenie znova povolíte, môže vám váš operátor účtovať poplatky."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Znova povoliť dátové prenosy"</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="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>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Vymazať všetky upozornenia."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Informácie o aplikácii"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Zavrieť"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Upozornenia sú vypnuté"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Klepnutím sem upozornenia znova povolíte."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Obrazovka sa automaticky otočí."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Obrazovka je uzamknutá v orientácii na šírku."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Obrazovka je uzamknutá v orientácii na výšku."</string>
@@ -189,7 +183,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Automatické otáčanie"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Otáčanie uzamknuté"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Metóda vstupu"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Používaná poloha"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Poloha"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Poloha vypnutá"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Mediálne zariadenie"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Len tiesňové volania"</string>
@@ -204,6 +199,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Bezdrôtový displej"</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="status_bar_help_title" msgid="1199237744086469217">"Tu sa zobrazujú upozornenia"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Môžete ich kedykoľvek zobraziť tak, že posuniete prstom nadol."\n"Ak posuniete prstom nadol ešte raz, zobrazia sa ovládacie prvky systému."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Sieť môže byť monitorovaná"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 742361d..eaa8b11 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"Sistemski uporabniški vmesnik"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Počisti"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Ne moti"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Pokaži obvestila"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Odstrani s seznama"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Podatki o programu"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Ni nedavnih programov"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Priključite polnilnik"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Baterija je skoraj prazna."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> preostalo"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"Polnjenje po povezavi USB ni podprto."\n"Uporabite priloženi polnilnik."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"Polnjenje po povezavi USB ni podprto.\nUporabite priloženi polnilnik."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Uporaba baterije"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Nastavitve"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <string name="always_use_device" msgid="1450287437017315906">"Privzeto uporabi za to napravo USB"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Privzeto uporabi za ta dodatek USB"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"Ali dovolite odpravljanje težav prek USB?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"Računalnikov prstni odtis ključa RSA je:"\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"Računalnikov prstni odtis ključa RSA je:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Vedno dovoli iz tega računalnika"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Povečava čez cel zaslon"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Raztegnitev čez zaslon"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Razširitev združljivosti"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Če je program izdelan za manjše zaslone, se ob uri pokaže kontrolnik za povečavo."</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Shranjev. posnetka zaslona ..."</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"Shranjevanje posnetka zaslona ..."</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"Shranjevanje posnetka zaslona."</string>
@@ -160,17 +156,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Podatki 4G so onemogočeni"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobilni podatki so onemogočeni"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Podatki onemogočeni"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Dosegli ste omejitev količine prenesenih podatkov."\n\n"Če prenos podatkov znova omogočite, vam ga lahko operater zaračuna."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Dosegli ste omejitev količine prenesenih podatkov.\n\nČe prenos podatkov znova omogočite, vam ga lahko operater zaračuna."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Znova omogoči podatke"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Ni internetne povez."</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi povezan"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Iskanje GPS-a"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Lokacija nastavljena z GPS-om"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Aktivne zahteve za lokacijo"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Izbriši vsa obvestila."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Podatki o aplikaciji"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Zapri"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Obvestila so izklopljena"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Dotaknite se tukaj, da ponovno vklopite obvestila."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Zaslon se bo samodejno zasukal."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Zaslon je zaklenjen v ležeči usmerjenosti."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Zaslon je zaklenjen v pokončni usmerjenosti."</string>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Samodejno vrtenje"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Zaklenjeno vrtenje"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Način vnosa"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Mesto uporabe"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Lokacija"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Lokacija izklopljena"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Predstavnostna naprava"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Le klici v sili"</string>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Prikaz brezžičnih naprav"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Svetlost"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"SAMODEJNO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Obvestila so prikazana tukaj"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Do njih lahko kadar koli dostopate tako, da povlečete navzdol."\n"Za prikaz sistemskih kontrolnikov znova povlecite navzdol."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Omrežje je lahko nadzorovano"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 3bf5052..ccda6e9 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"UI система"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Обриши"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Не узнемиравај"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Приказуј упозорења"</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="6576392951053994640">"Нема недавних апликација"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Прикључите пуњач"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Батерија ће се ускоро испразнити."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"преостало је <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"Пуњење преко USB-а није подржано."\n"Користите само приложени пуњач."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"Пуњење преко USB-а није подржано.\nКористите само приложени пуњач."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Коришћење батерије"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Подешавања"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <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="compat_mode_on" msgid="6623839244840638213">"Зумирај на целом екрану"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Развуци на цео екран"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Компатибилно зумирање"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Када је апликација намењена мањем екрану, контрола зумирања приказује се поред сата."</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>
@@ -160,17 +156,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G подаци су онемогућени"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Подаци мобилне мреже су онемогућени"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Подаци су онемогућени"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Достигли сте наведено ограничење за коришћење података."\n\n"Ако поново омогућите податке, мобилни оператер ће вам можда наплатити."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Достигли сте наведено ограничење за коришћење података.\n\nАко поново омогућите податке, мобилни оператер ће вам можда наплатити."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Поново омогући податке"</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="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="accessibility_clear_all" msgid="5235938559247164925">"Обриши сва обавештења."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Информације о апликацији"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Затвори"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Обавештења су искључена"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Додирните овде да бисте поново укључили обавештења."</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>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Аутоматско ротирање"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Ротирање је закључано"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Метод уноса"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Локација која се користи"</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>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Бежични екран"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Осветљеност"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АУТОМАТСКА"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Обавештења се појављују овде"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Приступите им у било ком тренутку листањем надоле."\n"Поново листајте надоле да би се приказале системске контроле."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Мрежа се можда надгледа"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 71eedd8..ffe8c84 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"Gränssnitt"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Ta bort"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Stör ej"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Visa aviseringar"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Ta bort från listan"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Info om appen"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Inga nya appar"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Anslut laddaren"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Batteriet håller på att ta slut."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> återstår"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"Det går inte att ladda via USB."\n"Använd endast den laddare som levererades med telefonen."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"Det går inte att ladda via USB.\nAnvänd endast den laddare som levererades med telefonen."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Batteriförbrukning"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Inställningar"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <string name="always_use_device" msgid="1450287437017315906">"Använd som standard för den här USB-enheten"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Använd som standard för det här USB-tillbehöret"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"Ska USB-felsökning tillåtas?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"Fingeravtrycket för datorns RSA-nyckel är:"\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"Fingeravtrycket för datorns RSA-nyckel är:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Tillåt alltid på den här datorn"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zooma för att fylla skärm"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Dra för att fylla skärmen"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Zoom i kompatibilitetsläge"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"När en app är anpassad för en mindre skärm visas ett zoomreglage vid klockan."</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Skärmdumpen sparas ..."</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"Skärmdumpen sparas ..."</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"Skärmdumpen sparas."</string>
@@ -160,17 +156,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Data via 4G har inaktiverats"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobildata har inaktiverats"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Data har inaktiverats"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Du har nått den angivna gränsen för dataanvändning."\n\n"Om du aktiverar data på nytt kan du bli debiterad av operatören."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Du har nått den angivna gränsen för dataanvändning.\n\nOm du aktiverar data på nytt kan du bli debiterad av operatören."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Återaktivera data"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Ingen anslutning"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi-ansluten"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Sökning efter GPS pågår"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Platsen har identifierats av GPS"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Det finns aktiva platsbegäranden"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Ta bort alla meddelanden."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Info om appen"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Stäng"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Meddelanden inaktiverade"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Knacka lätt här om du vill aktivera meddelanden igen."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skärmen roteras automatiskt."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Bildskärmens riktning är nu låst i liggande format."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Bildskärmens riktning är nu låst i stående format."</string>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Rotera automatiskt"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Rotationen har låsts"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Inmatningsmetod"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Plats som används"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Plats"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Plats har inaktiverats"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Medieenhet"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Endast nödsamtal"</string>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Trådlös skärm"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Ljusstyrka"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Meddelanden visas här"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Du kommer åt dem när som helst genom att dra nedåt."\n"Dra nedåt igen om du vill visa systemkontroller."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Nätverket kan vara övervakat"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index ccbc51f..bdf22c3 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"UI ya Mfumo"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Futa"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Usisumbue"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Onyesha arifa"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Ondoa kwenye orodha"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Taarifa za programu-matumizi"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Hakuna programu za sasa"</string>
@@ -35,7 +33,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Unganisha chaja"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Betri inaisha."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> zimebakia"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"Chaji ya USB haihamiliwi."\n" Tumia chaka iliyopeanwa."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"Chaji ya USB haihamiliwi.\n Tumia chaka iliyopeanwa."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Utumiaji wa betri"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Mipangilio"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Mtandao-Hewa"</string>
@@ -57,12 +55,10 @@
     <string name="always_use_device" msgid="1450287437017315906">"Kwa kifaa hiki cha USB tumia chaguo-msingi"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Tumia kama chaguo-msingi ya kifuasi hiki cha USB"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"Ruhusu utatuaji wa USB?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"Alama ya kidole ya kitufe cha RSA ya kompyuta ni:"\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"Alama ya kidole ya kitufe cha RSA ya kompyuta ni:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Ruhusu kutoka kwenye kompyuta hii kila wakati"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Kuza ili kujaza skrini"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Tanua ili kujaza skrini"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Kukuza kwa Utangamanifu"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Wakati programu ilibuniwa kwa skrini ndogo, kidhibiti cha kukuza kitaonekana kwa saa."</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Inahifadhi picha ya skrini..."</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"Inahifadhi picha ya skrini..."</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"Picha ya skrini inahifadhiwa"</string>
@@ -132,7 +128,7 @@
     <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
     <string name="accessibility_no_sim" msgid="8274017118472455155">"Hakuna SIM."</string>
     <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Shiriki intaneti kwa Bluetooth."</string>
-    <string name="accessibility_airplane_mode" msgid="834748999790763092">"Modi ya ndege."</string>
+    <string name="accessibility_airplane_mode" msgid="834748999790763092">"Hali ya ndege."</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Asilimia <xliff:g id="NUMBER">%d</xliff:g> ya betri"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Mipangilio ya mfumo."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Arifa."</string>
@@ -158,24 +154,22 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Data ya 4G imelemazwa"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Data ya kifaa cha mkononi imelemazwa"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Data imelemazwa"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Umefika kikomo maalum cha matumizi ya data. "\n" "\n" Ukiwezesha data tena, unaweza kutozwa na mtoa huduma."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Umefika kikomo maalum cha matumizi ya data. \n \n Ukiwezesha data tena, unaweza kutozwa na mtoa huduma."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Wezesha upya data"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Hakuna muunganisho wa mtandao"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Mtandao-hewa umeunganishwa"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Inatafuta GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Mahali pamewekwa na GPS"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Maombi ya eneo yanatumika"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Futa arifa zote."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Taarifa ya programu"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Funga"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Arifa zimelemazwa"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Gonga hapa ili kuwezesha tena arifa."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skrini itazunguka kiotomatiki."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Skrini imefungwa sasa katika uelekezo wa mandhari."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Skrini imefungwa katika uelekeo wa picha."</string>
     <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
     <string name="start_dreams" msgid="7219575858348719790">"Hali Tulivu"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
-    <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Modi ya ndege"</string>
+    <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Hali ya ndege"</string>
     <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"Inachaji, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
     <string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"Imechajiwa"</string>
     <string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"Bluetooth"</string>
@@ -185,7 +179,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Zungusha Otomatiki"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Mzunguko Umefungwa"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Mbinu ya uingizaji"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Eneo linalotumika"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Kutambua Eneo"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Eneo Limezimwa"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Kifaa cha midia"</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>
@@ -200,6 +195,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Uonyeshaji Pasiwaya"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Ung\'avu"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"KIOTOMATIKI"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Arifa zitaonekana hapa"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Zifikie wakati wowote kwa kutelezesha chini."\n"Telezesha chini tena kupata vidhibiti vya mfumo."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Mtandao unaweza kufuatiliwa"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw720dp/dimens.xml b/packages/SystemUI/res/values-sw720dp/dimens.xml
index e42855c..b1fc00a 100644
--- a/packages/SystemUI/res/values-sw720dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp/dimens.xml
@@ -16,22 +16,10 @@
 */
 -->
 <resources>
-    <!-- size at which Notification icons will be drawn in the status bar -->
-    <dimen name="system_bar_icon_drawing_size">24dip</dimen>
-
-    <!-- opacity at which Notification icons will be drawn in the status bar -->
-    <item type="dimen" name="system_bar_icon_drawing_alpha">100%</item>
-
-    <!-- The width of the view containing non-menu status bar icons -->
-    <dimen name="system_bar_navigation_key_width">80dip</dimen>
-
-    <!-- The width of the view containing the menu status bar icon -->
-    <dimen name="system_bar_navigation_menu_key_width">80dip</dimen>
 
     <!-- ======================================== -->
     <!-- The following resources were recently moved from sw600dp; there may
-         be situations where they don't sync up perfectly with
-         PhoneStatusBar/TabletStatusBar. -->
+         be situations where they don't sync up perfectly with PhoneStatusBar. -->
     <!-- ======================================== -->
 
     <!-- The width of the ticker, including the icon -->
diff --git a/packages/SystemUI/res/values-sw720dp/styles.xml b/packages/SystemUI/res/values-sw720dp/styles.xml
deleted file mode 100644
index 5009395..0000000
--- a/packages/SystemUI/res/values-sw720dp/styles.xml
+++ /dev/null
@@ -1,74 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <style name="SystemBarNotificationText">
-        <item name="android:textSize">16sp</item>
-        <item name="android:textColor">#ff999999</item>
-    </style>
-
-    <style name="SystemBarPanelSettingsRow">
-        <item name="android:paddingRight">16dp</item>
-        <item name="android:layout_height">64dp</item>
-        <item name="android:layout_width">match_parent</item>
-        <item name="android:orientation">horizontal</item>
-        <item name="android:background">?android:attr/listChoiceBackgroundIndicator</item>
-    </style>
-
-    <style name="SystemBarPanelSettingsIcon">
-        <item name="android:layout_height">match_parent</item>
-        <item name="android:layout_width">64dp</item>
-        <item name="android:scaleType">center</item>
-    </style>
-
-    <style name="SystemBarPanelSettingsContents">
-        <item name="android:layout_height">wrap_content</item>
-        <item name="android:layout_width">0dp</item>
-        <item name="android:layout_weight">1</item>
-        <item name="android:layout_gravity">start|center_vertical</item>
-        <item name="android:textColor">?android:attr/textColorPrimary</item>
-        <item name="android:textSize">18sp</item>
-    </style>
-
-    <style name="SystemBarPanelSettingsPanelSeparator">
-        <item name="android:layout_marginEnd">0dp</item>
-        <item name="android:layout_width">match_parent</item>
-        <item name="android:layout_height">1dp</item>
-        <item name="android:background">@android:drawable/divider_horizontal_dark</item>
-    </style>
-
-    <style name="TextAppearance.SystemBar.Clock" parent="@*android:style/TextAppearance.StatusBar.Icon">
-        <item name="android:textSize">30dp</item>
-        <item name="android:textStyle">normal</item>
-        <item name="android:textColor">@android:color/holo_blue_light</item>
-    </style>
-
-    <style name="TextAppearance.SystemBar.Expanded.Clock" parent="@style/TextAppearance.StatusBar.Expanded.Clock">
-        <item name="android:textSize">48dp</item>
-        <item name="android:fontFamily">sans-serif-light</item>
-        <item name="android:textStyle">normal</item>
-        <item name="android:textColor">#ffffff</item>
-    </style>
-
-    <style name="TextAppearance.SystemBar.Expanded.Date" parent="@style/TextAppearance.StatusBar.Expanded.Date">
-        <item name="android:textSize">14dp</item>
-        <item name="android:textStyle">normal</item>
-        <item name="android:textColor">#666666</item>
-        <item name="android:textAllCaps">true</item>
-    </style>
-
-</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 1429a3c..af4bb092 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -21,8 +21,6 @@
     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_do_not_disturb_button" msgid="5812628897510997853">"ห้ามรบกวน"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"แสดงการแจ้งเตือน"</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="6576392951053994640">"ไม่มีแอปพลิเคชันล่าสุด"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"เสียบที่ชาร์จ"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"แบตเตอรี่เหลือน้อย"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"เหลืออีก <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"ไม่สนับสนุนการชาร์จแบบ USB"\n"ใช้เฉพาะที่ชาร์จที่ให้มาเท่านั้น"</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"ไม่สนับสนุนการชาร์จแบบ USB\nใช้เฉพาะที่ชาร์จที่ให้มาเท่านั้น"</string>
     <string name="battery_low_why" msgid="7279169609518386372">"การใช้แบตเตอรี่"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"การตั้งค่า"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"WiFi"</string>
@@ -59,12 +57,10 @@
     <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="compat_mode_on" msgid="6623839244840638213">"ขยายจนเต็มหน้าจอ"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"ยืดจนเต็มหน้าจอ"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"ความเข้ากันได้ของการย่อ/ขยาย"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"สำหรับแอปพลิเคชันที่ออกแบบมาสำหรับหน้าจอขนาดเล็ก ตัวควบคุมการย่อ/ขยายจะปรากฏขึ้นข้างนาฬิกา"</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>
@@ -160,17 +156,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"ปิดใช้งานข้อมูล 4G แล้ว"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"ปิดใช้งานข้อมูลมือถือแล้ว"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"ข้อมูลถูกปิดใช้งาน"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"คุณได้มาถึงขีดจำกัดการใช้ข้อมูลที่ระบุไว้แล้ว"\n\n"หากคุณเปิดใช้งานข้อมูลอีกครั้ง ผู้ให้บริการของคุณอาจเรียกเก็บค่าบริการ"</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"คุณได้มาถึงขีดจำกัดการใช้ข้อมูลที่ระบุไว้แล้ว\n\nหากคุณเปิดใช้งานข้อมูลอีกครั้ง ผู้ให้บริการของคุณอาจเรียกเก็บค่าบริการ"</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"เปิดใช้งานข้อมูลอีกครั้ง"</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>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"ตำแหน่งที่กำหนดโดย GPS"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"คำขอตำแหน่งที่มีการใช้งาน"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"ล้างการแจ้งเตือนทั้งหมด"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"ข้อมูลแอป"</string>
-    <string name="close_universe" msgid="3736513750241754348">"ปิด"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"การแจ้งเตือนปิดอยู่"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"แตะที่นี่เพื่อเปิดการแจ้งเตือนอีกครั้ง"</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>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"หมุนอัตโนมัติ"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"ล็อกการหมุนแล้ว"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"วิธีป้อนข้อมูล"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"สถานที่ที่ใช้งาน"</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>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"จอแสดงผลไร้สาย"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"ความสว่าง"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"อัตโนมัติ"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"การแจ้งเตือนจะแสดงขึ้นที่นี่"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"เข้าถึงได้ทุกเมื่อด้วยการกวาดนิ้วลง"\n"กวาดนิ้วลงอีกครั้งสำหรับการควบคุมระบบ"</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"เครือข่ายอาจได้รับการตรวจสอบ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index c48db46..33bd368 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"UI ng System"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"I-clear"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Huwag gambalain"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Magpakita ng notification"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Alisin mula sa listahan"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Impormasyon ng app"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Walang kamakailang apps"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Ikabit ang charger"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Humihina na ang baterya."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> natitira"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"Hindi sinusuportahan ang pag-charge sa USB."\n"Gamitin lang ang ibinigay na charger."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"Hindi sinusuportahan ang pag-charge sa USB.\nGamitin lang ang ibinigay na charger."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Paggamit ng baterya"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Mga Setting"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <string name="always_use_device" msgid="1450287437017315906">"Gamitin bilang default para sa USB device"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Gamitin bilang default sa USB accessory na ito"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"Payagan ang pag-debug ng USB?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"Ang RSA key fingerprint ng computer ay:"\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"Ang RSA key fingerprint ng computer ay:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Palaging payagan mula sa computer na ito"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"I-zoom upang punan screen"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"I-stretch upang mapuno screen"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Zoom sa pagiging Tugma"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Kapag nakadisenyo ang isang app para sa mas maliit na screen, isang kontrol ng zoom ang lalabas sa may orasan."</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Sine-save ang screenshot…"</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"Sine-save ang screenshot…"</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"Sine-save ang screenshot."</string>
@@ -160,17 +156,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Hindi pinapagana ang 4G na data"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Hindi pinapagana ang data ng mobile"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Hindi pinapagana ang data"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Naabot mo na ang tinukoy na limitasyon ng paggamit ng data."\n\n"Kung muli mong papaganahin ang data, maaari kang masingil ng operator."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Naabot mo na ang tinukoy na limitasyon ng paggamit ng data.\n\nKung muli mong papaganahin ang data, maaari kang masingil ng operator."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Muling paganahin ang data"</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>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Naghahanap ng GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Lokasyong itinatakda ng GPS"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Aktibo ang mga kahilingan ng lokasyon"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"I-clear ang lahat ng notification."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Impormasyon ng app"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Isara"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Naka-off ang mga notification"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Tumapik dito upang muling i-on ang mga notification."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Awtomatikong iikot ang screen."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Naka-lock ang screen sa pahigang oryentasyon."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Naka-lock ang screen sa patayong oryentasyon."</string>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"I-auto Rotate"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Naka-lock ang Pag-rotate"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Pamamaraan ng Pag-input"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Lokasyong ginagamit"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Lokasyon"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Naka-off ang Lokasyon"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Device ng media"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Mga Pang-emergency na Tawag Lamang"</string>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Wireless Display"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brightness"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Dito lumalabas ang mga notification"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"I-access ang mga ito anumang oras sa pamamagitan ng pag-swipe pababa."\n"Muling mag-swipe pababa para sa mga kontrol ng system."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Maaaring sinusubaybayan ang network"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index d0dd099..fcc5a97 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"Sist Arayüzü"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Temizle"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Rahatsız etmeyin"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Bildirimleri göster"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Listeden kaldır"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Uygulama bilgileri"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Son uygulama yok"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Şarj cihazını takın"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Pil azalıyor."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> kaldı"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"USB üzerinden şarj desteklenmiyor."\n"Yalnızca ürünle birlikte verilen şarj cihazını kullanın."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB üzerinden şarj desteklenmiyor.\nYalnızca ürünle birlikte verilen şarj cihazını kullanın."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Pil kullanımı"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Ayarlar"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Kablosuz"</string>
@@ -59,12 +57,10 @@
     <string name="always_use_device" msgid="1450287437017315906">"Bu USB cihazı için varsayılan olarak kullan"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Bu USB aksesuar için varsayılan olarak kullan"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"USB hata ayıklamasına izin verilsin mi?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"Bilgisayarın RSA anahtarı parmak izi:"\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"Bilgisayarın RSA anahtarı parmak izi:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Bu bilgisayardan her zaman izin ver"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Yakınlaştır (ekranı kaplasın)"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Genişlet (ekran kapansın)"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Uyumluluk yakınlaştırması"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Uygulama küçük bir ekran için tasarlanmışsa saatin yanında bir yakınlaştırma denetimi görünür."</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Ekran görüntüsü kaydediliyor..."</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"Ekran görüntüsü kaydediliyor..."</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"Ekran görüntüsü kaydediliyor."</string>
@@ -160,17 +156,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G verileri devre dışı"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobil veriler devre dışı"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Veriler devre dışı"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Belirtilen veri kullanım limitine ulaştınız."\n\n"Verileri yeniden etkinleştirirseniz, operatör sizden ücret talep edebilir."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Belirtilen veri kullanım limitine ulaştınız.\n\nVerileri yeniden etkinleştirirseniz, operatör sizden ücret talep edebilir."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Veriyi yeniden etkinleştir"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"İnternet bağlantısı yok"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Kablosuz bağlandı"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"GPS aranıyor"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Konum GPS ile belirlendi"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Konum bilgisi istekleri etkin"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Tüm bildirimleri temizle"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Uygulama bilgileri"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Kapat"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Bildirimler kapalı"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Bildirimleri tekrar açmak için buraya hafifçe vurun."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekran otomatik olarak dönecektir."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Ekran yatay yönde kilitlendi."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Ekran dikey yönde kilitlendi."</string>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Otomatik Döndür"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Dönme Kilitlendi"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Giriş Yöntemi"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Kullanılan konum"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Konum"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Konum Bilgisi Kapalı"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Medya cihazı"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Yalnızca Acil Çağrılar İçin"</string>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Kablosuz Ekran"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Parlaklık"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"OTOMATİK"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Bildirimler burada görünür"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Aşağıya hızlıca kaydırarak bunlara istediğiniz zaman erişebilirsiniz."\n"Sistem denetimleri için tekrar hızlıca aşağı kaydırın."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Ağ izlenebilir"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 5f059b4..b1d8a39 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -21,8 +21,6 @@
     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_do_not_disturb_button" msgid="5812628897510997853">"Не турбувати"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Показувати сповіщення"</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="6576392951053994640">"Немає останніх програм"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Підключіть зарядний пристрій"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Акумулятор розряджається."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"Залишилося <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"Заряджання USB не підтримується."\n"Використовуйте лише наданий у комплекті зарядний пристрій."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"Заряджання USB не підтримується.\nВикористовуйте лише наданий у комплекті зарядний пристрій."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Використання акумулятора"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Налаштування"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <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="compat_mode_on" msgid="6623839244840638213">"Масштабув. на весь екран"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Розтягнути на весь екран"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Масштабування для сумісності"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Якщо програму призначено для менших екранів, елемент керування масштабом буде відображатися біля годинника."</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>
@@ -160,17 +156,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Дані 4G вимкнено"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Мобільне передавання даних вимкнено"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Використання даних вимкнено"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Досягнуто вказаного ліміту використання даних."\n\n"Якщо ввімкнути використання даних знову, оператор може стягнути плату."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Досягнуто вказаного ліміту використання даних.\n\nЯкщо ввімкнути використання даних знову, оператор може стягнути плату."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Повторно ввімкнути дані"</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="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="accessibility_clear_all" msgid="5235938559247164925">"Очистити всі сповіщення."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Інформація про програму"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Закрити"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Сповіщення вимкнено"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Торкніться тут, щоб знову ввімкнути сповіщення."</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>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Обертати автоматично"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Обертання заблоковано"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Метод введення"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Поточне місцезнаходження"</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>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Бездротове відображення"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Яскравість"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АВТО"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Сповіщення з’являються тут"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Отримуйте до них доступ будь-коли, провівши пальцем униз."\n"Знову проведіть униз, щоб відкрити елементи керування системи."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Мережу можуть відстежувати"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index b56dd74..6a079b3 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"Giao diện người dùng hệ thống"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Xóa"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Không làm phiền"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Hiển thị thông báo"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Xóa khỏi danh sách"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Thông tin về ứng dụng"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Không có ứng dụng nào gần đây"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Cắm bộ sạc"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Pin đang yếu."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> còn lại"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"Không hỗ trợ sạc qua USB."\n"Chỉ sử dụng bộ sạc được cung cấp."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"Không hỗ trợ sạc qua USB.\nChỉ sử dụng bộ sạc được cung cấp."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Sử dụng pin"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Cài đặt"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <string name="always_use_device" msgid="1450287437017315906">"Sử dụng theo mặc định cho thiết bị USB này"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Sử dụng theo mặc định cho phụ kiện USB này"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"Cho phép gỡ lỗi USB?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"Tệp tham chiếu khóa RSA của máy tính là:"\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"Tệp tham chiếu khóa RSA của máy tính là:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Luôn cho phép từ máy tính này"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"T.phóng để lấp đầy m.hình"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Giãn ra để lấp đầy m.hình"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Thu phóng tương thích"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Khi ứng dụng được thiết kế cho một màn hình nhỏ hơn, điều khiển thu phóng sẽ xuất hiện bên cạnh đồng hồ."</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Đang lưu ảnh chụp màn hình..."</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"Đang lưu ảnh chụp màn hình..."</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"Ảnh chụp màn hình đang được lưu."</string>
@@ -160,17 +156,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Đã tắt dữ liệu 4G"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Dữ liệu di động bị vô hiệu hóa"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Dữ liệu đã bị vô hiệu hóa"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Bạn đã đạt đến giới hạn sử dụng dữ liệu chỉ định."\n\n"Nếu bạn bật lại dữ liệu, bạn có thể bị nhà cung cấp tính phí."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Bạn đã đạt đến giới hạn sử dụng dữ liệu chỉ định.\n\nNếu bạn bật lại dữ liệu, bạn có thể bị nhà cung cấp tính phí."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Bật lại dữ liệu"</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>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Đang tìm kiếm GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Vị trí đặt bởi GPS"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Yêu cầu về thông tin vị trí đang hoạt động"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Xóa tất cả thông báo."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Thông tin về ứng dụng"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Đóng"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Tắt thông báo"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Chạm vào đây để bật lại thông báo."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Màn hình sẽ xoay tự động."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Màn hình hiện bị khóa theo hướng ngang."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Màn hình hiện bị khóa theo hướng dọc."</string>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Tự động xoay"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Khóa xoay"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Phương thức nhập"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Vị trí đang được sử dụng"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Vị trí"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Tắt vị trí"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Thiết bị phương tiện"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Chỉ cuộc gọi khẩn cấp"</string>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Hiển thị không dây"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Độ sáng"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"TỰ ĐỘNG"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Thông báo xuất hiện tại đây"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Truy cập vào chúng bất kỳ lúc nào bằng cách vuốt xuống."\n"Vuốt lại xuống để hiển thị các điều khiển hệ thống."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Mạng có thể được giám sát"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index d0811d9..1d0d99d 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -21,8 +21,6 @@
     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_do_not_disturb_button" msgid="5812628897510997853">"请勿打扰"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"显示通知"</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="6576392951053994640">"最近没有运行任何应用"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"请连接充电器"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"电池电量低。"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"还剩 <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"不支持 USB 充电功能。"\n"只能使用随附的充电器充电。"</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"不支持 USB 充电功能。\n只能使用随附的充电器充电。"</string>
     <string name="battery_low_why" msgid="7279169609518386372">"电量使用情况"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"设置"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"WLAN"</string>
@@ -59,12 +57,10 @@
     <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="compat_mode_on" msgid="6623839244840638213">"缩放以填满屏幕"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"拉伸以填满屏幕"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"兼容性缩放"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"如果应用是针对较小屏幕设计的,则时钟旁会显示缩放控件。"</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>
@@ -162,17 +158,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G 数据网络已停用"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"移动数据已停用"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"数据已停用"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"您已达到指定的数据流量上限。"\n\n"如果您重新启用数据,运营商可能会收取相应的费用。"</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"您已达到指定的数据流量上限。\n\n如果您重新启用数据,运营商可能会收取相应的费用。"</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"重新启用数据连接"</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>
     <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="accessibility_clear_all" msgid="5235938559247164925">"清除所有通知。"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"应用信息"</string>
-    <string name="close_universe" msgid="3736513750241754348">"关闭"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"通知功能已停用"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"点按此处可重新启用通知功能。"</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>
@@ -189,7 +183,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"自动旋转"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"屏幕方向已锁定"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"输入法"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"位置信息"</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>
@@ -204,6 +199,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"无线显示"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"亮度"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"自动"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"通知会显示在这里"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"向下滑动可随时查看通知。"\n"再次向下滑动可使用系统控制功能。"</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"网络可能会受到监控"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK-land/strings.xml b/packages/SystemUI/res/values-zh-rHK-land/strings.xml
new file mode 100644
index 0000000..8d55df4
--- /dev/null
+++ b/packages/SystemUI/res/values-zh-rHK-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * 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.
+ */
+ -->
+
+<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>
+</resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..ae816380
--- /dev/null
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -0,0 +1,203 @@
+<?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: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_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="6576392951053994640">"沒有最近的應用程式"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"關閉最近使用的應用程式"</string>
+  <plurals name="status_bar_accessibility_recent_apps">
+    <item quantity="one" msgid="5854176083865845541">"1 個最近使用的應用程式"</item>
+    <item quantity="other" msgid="1040784359794890744">"%d 個最近使用的應用程式"</item>
+  </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="battery_low_title" msgid="2783104807551211639">"連接充電器"</string>
+    <string name="battery_low_subtitle" msgid="1752040062087829196">"電池即將用盡。"</string>
+    <string name="battery_low_percent_format" msgid="1077244949318261761">"剩餘 <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"不支援 USB 充電。\n僅能使用隨附的充電器。"</string>
+    <string name="battery_low_why" msgid="7279169609518386372">"電池使用情況"</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_airplane" msgid="4879879698500955300">"飛行模式"</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">"已經由藍牙進行網絡共享"</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_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="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>
+    <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_saved_text" msgid="1152839647677558815">"輕觸即可查看屏幕擷取畫面。"</string>
+    <string name="screenshot_failed_title" msgid="705781116746922771">"無法擷取屏幕畫面。"</string>
+    <string name="screenshot_failed_text" msgid="8134011269572415402">"無法儲存屏幕擷取畫面,儲存裝置可能正在使用。"</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="accessibility_back" msgid="567011538994429120">"返回"</string>
+    <string name="accessibility_home" msgid="8217216074895377641">"首頁"</string>
+    <string name="accessibility_menu" msgid="316839303324695949">"選單"</string>
+    <string name="accessibility_recent" msgid="8571350598987952883">"最近使用的應用程式"</string>
+    <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"切換輸入法按鈕。"</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_no_battery" msgid="358343022352820946">"未安裝電池。"</string>
+    <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"電池電量為一格。"</string>
+    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"電池電量為兩格。"</string>
+    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"電池電量為三格。"</string>
+    <string name="accessibility_battery_full" msgid="8909122401720158582">"電池已滿。"</string>
+    <string name="accessibility_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_off" msgid="3177380296697933627">"WiFi 已關閉。"</string>
+    <string name="accessibility_no_wifi" msgid="1425476551827924474">"WiFi 連線已中斷。"</string>
+    <string name="accessibility_wifi_one_bar" msgid="7735893178010724377">"WiFi 訊號強度為一格。"</string>
+    <string name="accessibility_wifi_two_bars" msgid="4994274250497262434">"WiFi 訊號強度為兩格。"</string>
+    <string name="accessibility_wifi_three_bars" msgid="3495755044276588384">"WiFi 訊號強度為三格。"</string>
+    <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"WiFi 訊號已滿。"</string>
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"沒有 WiMAX 訊號。"</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX 訊號強度一格。"</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX 訊號強度兩格。"</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX 訊號強度三格。"</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX 訊號滿格。"</string>
+    <string name="accessibility_no_signal" msgid="7064645320782585167">"沒有訊號。"</string>
+    <string name="accessibility_not_connected" msgid="6395326276213402883">"未連線。"</string>
+    <string name="accessibility_zero_bars" msgid="3806060224467027887">"訊號強度為零格。"</string>
+    <string name="accessibility_one_bar" msgid="1685730113192081895">"訊號強度為一格。"</string>
+    <string name="accessibility_two_bars" msgid="6437363648385206679">"訊號強度為兩格。"</string>
+    <string name="accessibility_three_bars" msgid="2648241415119396648">"訊號強度為三格。"</string>
+    <string name="accessibility_signal_full" msgid="9122922886519676839">"訊號已滿。"</string>
+    <string name="accessibility_desc_on" msgid="2385254693624345265">"開啟。"</string>
+    <string name="accessibility_desc_off" msgid="6475508157786853157">"關閉。"</string>
+    <string name="accessibility_desc_connected" msgid="8366256693719499665">"已連線。"</string>
+    <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+    <string name="accessibility_data_connection_1x" msgid="994133468120244018">"1 X"</string>
+    <string name="accessibility_data_connection_hspa" msgid="2032328855462645198">"HSPA"</string>
+    <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+    <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+    <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+    <string name="accessibility_data_connection_lte" msgid="5413468808637540658">"LTE"</string>
+    <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_bluetooth_tether" msgid="4102784498140271969">"藍牙數據連線。"</string>
+    <string name="accessibility_airplane_mode" msgid="834748999790763092">"飛航模式。"</string>
+    <!-- String.format failed for translation -->
+    <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
+    <skip />
+    <string name="accessibility_settings_button" msgid="799583911231893380">"系統設定"</string>
+    <string name="accessibility_notifications_button" msgid="4498000369779421892">"通知。"</string>
+    <string name="accessibility_remove_notification" msgid="3603099514902182350">"清除通知。"</string>
+    <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS 已啟用。"</string>
+    <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"正在取得 GPS 訊號。"</string>
+    <string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter (TTY) 已啟用。"</string>
+    <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"鈴聲震動。"</string>
+    <string name="accessibility_ringer_silent" msgid="9061243307939135383">"鈴聲靜音。"</string>
+    <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"「<xliff:g id="APP">%s</xliff:g>」已關閉。"</string>
+    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"通知已關閉。"</string>
+    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"通知欄。"</string>
+    <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"快速設定。"</string>
+    <string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"最近使用的應用程式"</string>
+    <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"用戶:<xliff:g id="USER">%s</xliff:g>。"</string>
+    <string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>、<xliff:g id="NETWORK">%2$s</xliff:g>"</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" msgid="4196876722090224753">"飛航模式:<xliff:g id="STATE">%s</xliff:g>。"</string>
+    <string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"藍牙:<xliff:g id="STATE">%s</xliff:g>。"</string>
+    <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"鬧鐘已設定為:<xliff:g id="TIME">%s</xliff:g>。"</string>
+    <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"已停用 2G-3G 數據"</string>
+    <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"已停用 4G 數據"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"已停用流動數據"</string>
+    <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"數據停用"</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"您已到達指定的數據用量上限。\n\n如果您重新啟用數據傳輸,流動網絡供應商可能會向您收費。"</string>
+    <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"重新啟用數據"</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="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="accessibility_clear_all" msgid="5235938559247164925">"清除所有通知。"</string>
+    <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"應用程式資訊"</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="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="start_dreams" msgid="7219575858348719790">"Daydream"</string>
+    <string name="ethernet_label" msgid="7967563676324087464">"以太網"</string>
+    <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"飛行模式"</string>
+    <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"充電中 (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
+    <string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"充電完成"</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_brightness_label" msgid="6968372297018755815">"亮度"</string>
+    <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"自動旋轉"</string>
+    <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"已鎖定屏幕旋轉功能"</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>
+    <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"只可撥打緊急電話"</string>
+    <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_wifi_label" msgid="9135344704899546041">"Wi-Fi"</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_display_label" msgid="6893592964463624333">"Wi-Fi Display"</string>
+    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"無線顯示"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"亮度"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"自動"</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"網絡可能會受到監控"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 170f15a..4f86806 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -21,8 +21,6 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"系統 UI"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"清除"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"勿干擾"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"顯示通知"</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="6576392951053994640">"沒有最近使用的應用程式"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"連接充電器"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"電池電量即將不足。"</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"還剩 <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"不支援 USB 充電。"\n"僅能使用隨附的充電器。"</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"不支援 USB 充電。\n僅能使用隨附的充電器。"</string>
     <string name="battery_low_why" msgid="7279169609518386372">"電池使用狀況"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"設定"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
@@ -59,12 +57,10 @@
     <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="compat_mode_on" msgid="6623839244840638213">"放大為全螢幕"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"放大為全螢幕"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"相容性縮放"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"執行專為較小螢幕設計的應用程式時,系統會在時鐘旁顯示縮放控制項。"</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>
@@ -162,17 +158,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"已停用 4G 數據"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"已停用行動數據"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"數據已停用"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"您已達到指定的資料用量上限。"\n\n"如果您重新啟用數據傳輸,行動通訊業者可能會向您收費。"</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"您已達到指定的資料用量上限。\n\n如果您重新啟用數據傳輸,行動通訊業者可能會向您收費。"</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"重新啟用數據連線"</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="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="accessibility_clear_all" msgid="5235938559247164925">"清除所有通知。"</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"應用程式資訊"</string>
-    <string name="close_universe" msgid="3736513750241754348">"關閉"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"關閉通知"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"輕按這裡即可重新開啟通知。"</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>
@@ -189,7 +183,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"自動旋轉"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"已鎖定螢幕旋轉功能"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"輸入法"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"使用位置"</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>
@@ -204,6 +199,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"無線螢幕分享"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"亮度"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"自動"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"系統會在這裡顯示通知"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"向下滑動即可隨時存取通知。"\n"再次向下滑動即可使用系統控制項。"</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"網路可能會受到監控"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 8219ea7..def73ff 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -21,15 +21,13 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="7164937344850004466">"Uhlelo lwe-UI"</string>
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Sula"</string>
-    <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Ungaphazamisi"</string>
-    <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Bonisa izaziso"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Susa ohlwini"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Ulwazi lwensiza"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Azikho izinhlelo zokusebenza zakamuva"</string>
-    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Susa izinsiza zakamumva"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Susa izinhlelo zokusebenza zakamumva"</string>
   <plurals name="status_bar_accessibility_recent_apps">
     <item quantity="one" msgid="5854176083865845541">"Insiza eyi-1 yakamumva"</item>
-    <item quantity="other" msgid="1040784359794890744">"%d izinsiza zakamumva"</item>
+    <item quantity="other" msgid="1040784359794890744">"%d izinhlelo zokusebenza zakamumva"</item>
   </plurals>
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Azikho izaziso"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Okuqhubekayo"</string>
@@ -37,7 +35,7 @@
     <string name="battery_low_title" msgid="2783104807551211639">"Xhuma ishaja."</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Ibhetri iya ngokuphela."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> okusele"</string>
-    <string name="invalid_charger" msgid="4549105996740522523">"Ukushaja i-USB akusekelwe."\n"Sebenzisa kuphela ishaja enikeziwe."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"Ukushaja i-USB akusekelwe.\nSebenzisa kuphela ishaja enikeziwe."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Ukusebenzisa ibhetri"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Izilungiselelo"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"I-Wi-Fi"</string>
@@ -49,22 +47,20 @@
     <string name="bluetooth_tethered" msgid="7094101612161133267">"Ukusebenzisa i-Bluetooth njengemodemu"</string>
     <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Izilungiselelo zezindlela zokufakwayo"</string>
     <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Ukwakheka kwekhibhodi"</string>
-    <string name="usb_device_permission_prompt" msgid="834698001271562057">"Vumela insiza <xliff:g id="APPLICATION">%1$s</xliff:g> ukuthi ufinyelele ezintweni eziphuma ne-USB?"</string>
-    <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Vumela insiza <xliff:g id="APPLICATION">%1$s</xliff:g> ukuthi ufinyelele ezintweni eziphuma ne-USB?"</string>
+    <string name="usb_device_permission_prompt" msgid="834698001271562057">"Vumela uhlelo lokusebenza <xliff:g id="APPLICATION">%1$s</xliff:g> ukuthi ufinyelele ezintweni eziphuma ne-USB?"</string>
+    <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Vumela uhlelo lokusebenza <xliff:g id="APPLICATION">%1$s</xliff:g> ukuthi ufinyelele ezintweni eziphuma ne-USB?"</string>
     <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Vula <xliff:g id="ACTIVITY">%1$s</xliff:g> uma ledivayisi ye-USB ixhunyiwe?"</string>
     <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Vula <xliff:g id="ACTIVITY">%1$s</xliff:g> uma le-accessory ye-USB ixhunyiwe"</string>
-    <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"Azikho izinsiza ezisebenze ngezinto ze-USB. Funda okwengeziwe ngale into kwi <xliff:g id="URL">%1$s</xliff:g>"</string>
+    <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"Azikho izinhlelo zokusebenza ezisebenze ngezinto ze-USB. Funda okwengeziwe ngale into kwi <xliff:g id="URL">%1$s</xliff:g>"</string>
     <string name="title_usb_accessory" msgid="4966265263465181372">"ama-accessory e-USB"</string>
     <string name="label_view" msgid="6304565553218192990">"Buka"</string>
     <string name="always_use_device" msgid="1450287437017315906">"Sebenzisa ngokuzenzakalelayo yale divayisi ye-USB"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Sebenzisa ngokuzenzakalelayo kule-accessory ye-USB"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"Vumela ukulungisa iphutha le-USB?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"Izigxivizo zeminwe zokhiye we-RSA wekhompyutha ngu:"\n"<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"Izigxivizo zeminwe zokhiye we-RSA wekhompyutha ngu:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Hlala uvumela njalo kusuka kule khompyutha"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Sondeza ukugcwalisa isikrini"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Nweba ukugcwalisa isikrini"</string>
-    <string name="compat_mode_help_header" msgid="7969493989397529910">"Ukuhambelana Kokusondeza"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Uma uhlelo lokusebenza lwenzelwe isikrini ezincane, isilawuli sokusondeza sizovela ngakuyiwashi."</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Ilondoloz umfanekiso weskrini..."</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"Ilondoloz umfanekiso weskrini..."</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"Umfanekiso weskrini uyalondolozwa."</string>
@@ -75,7 +71,7 @@
     <string name="usb_preference_title" msgid="6551050377388882787">"Okukhethwa kokudluliswa kwefayela ye-USB"</string>
     <string name="use_mtp_button_title" msgid="4333504413563023626">"Lengisa njengesidlali semediya (MTP)"</string>
     <string name="use_ptp_button_title" msgid="7517127540301625751">"Lengisa ikhamera (PTP)"</string>
-    <string name="installer_cd_button_title" msgid="2312667578562201583">"Faka insiza yokudluliswa Kwefayela ye-Android kwi-Mac"</string>
+    <string name="installer_cd_button_title" msgid="2312667578562201583">"Faka uhlelo lokusebenza yokudluliswa Kwefayela ye-Android kwi-Mac"</string>
     <string name="accessibility_back" msgid="567011538994429120">"Emuva"</string>
     <string name="accessibility_home" msgid="8217216074895377641">"Ekhaya"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Imenyu"</string>
@@ -160,17 +156,15 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Idatha ye-4G ivimbelwe"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Idatha yefoni ivimbelwe"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Idatha ivimbelwe"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Usufike emkhawulweni wokusebenzisa i-ata. "\n\n"Uma uqla kabusha ukusebenza kwe-ata, kungenzek umhlinzeki akukhokhise."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Usufike emkhawulweni wokusebenzisa i-ata. \n\nUma uqla kabusha ukusebenza kwe-ata, kungenzek umhlinzeki akukhokhise."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Vumela futhi idatha"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Alukho uxhumano lwe-Inthanethi"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"I-Wi-Fi ixhunyiwe"</string>
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Isesha i-GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Indawo ihlelwe i-GPS"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Izicelo zendawo ziyasebenza"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Susa zonke izaziso."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Ulwazi lohlelo lokusebenza"</string>
-    <string name="close_universe" msgid="3736513750241754348">"Vala"</string>
-    <string name="notifications_off_title" msgid="8936620513608443224">"Izaziso zivaliwe"</string>
-    <string name="notifications_off_text" msgid="2529001315769385273">"Thepha lapha ukuvula futhi izaziso."</string>
     <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Isikrini sizophenduka ngokuzenzakalela."</string>
     <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Isikrini sikhiyelwe ngomumo we-landscape."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Isikrini sikhiyelwe ngomumo we-portrait."</string>
@@ -187,7 +181,8 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Ukuphendula ngokuzenzakalela"</string>
     <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Ukuphendula kukhiyiwe"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Indlela yokungenayo"</string>
-    <string name="quick_settings_location_label" msgid="3292451598267467545">"Indawo iyasetshenziswa"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Indawo"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Indawo ivaliwe"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Idivayisi yemidiya"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Amakholi aphuthumayo kuphela"</string>
@@ -202,6 +197,5 @@
     <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Ukubonisa okungenazintambo"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Ukugqama"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"OKUZENZAKALELAYO"</string>
-    <string name="status_bar_help_title" msgid="1199237744086469217">"Izaziso zivela lapha"</string>
-    <string name="status_bar_help_text" msgid="7874607155052076323">"Kufinyelele noma kunini ngokuswayiphela phansi."\n"Swayiphela phansi futhi ngezilawuli zesistimu."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Inethiwekhi ingase inganyelwe"</string>
 </resources>
diff --git a/packages/SystemUI/res/values/arrays.xml b/packages/SystemUI/res/values/arrays.xml
index cd6aaf6..b2c8aee 100644
--- a/packages/SystemUI/res/values/arrays.xml
+++ b/packages/SystemUI/res/values/arrays.xml
@@ -40,4 +40,25 @@
         <item>@null</item>
     </array>
 
+    <!-- BatteryMeterView parameters -->
+    <array name="batterymeter_color_levels">
+        <item>4</item>
+        <item>15</item>
+        <item>100</item>
+    </array>
+    <array name="batterymeter_color_values">
+        <item>#FFFF3300</item>
+        <item>#FFFF3300</item>
+        <item>#FFFFFFFF</item>
+    </array>
+    <array name="batterymeter_bolt_points">
+        <item>88</item> <item>0</item>
+        <item>459</item><item>1</item>
+        <item>238</item><item>333</item>
+        <item>525</item><item>310</item>
+        <item>120</item><item>840</item>
+        <item>82</item> <item>818</item>
+        <item>246</item><item>373</item>
+        <item>0</item>  <item>408</item>
+    </array>
 </resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index acb192d..67a932a 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -20,6 +20,10 @@
     <drawable name="notification_number_text_color">#ffffffff</drawable>
     <drawable name="ticker_background_color">#ff1d1d1d</drawable>
     <drawable name="status_bar_background">#ff000000</drawable>
+    <color name="status_bar_background_semi_transparent">#66000000</color>
+    <color name="status_bar_background_transparent">#00000000</color>
+    <color name="navigation_bar_background_transparent_start">#7f000000</color>
+    <color name="navigation_bar_background_transparent_end">#00000000</color>
     <color name="notification_panel_solid_background">#ff000000</color>
     <drawable name="status_bar_recents_app_thumbnail_background">#88000000</drawable>
     <color name="status_bar_recents_app_label_color">#ffffffff</color>
@@ -27,12 +31,10 @@
     <color name="notification_list_shadow_top">#80000000</color>
     <drawable name="recents_callout_line">#99ffffff</drawable>
     <drawable name="notification_item_background_legacy_color">#ffaaaaaa</drawable>
-    <drawable name="intruder_bg_pressed">#ff33B5E5</drawable>
+    <drawable name="heads_up_notification_bg_pressed">#ff33B5E5</drawable>
     <drawable name="notification_header_bg">#FF000000</drawable>
-
-    <!-- ==================== system bar only ==================== -->
-    <drawable name="system_bar_background">#ff000000</drawable>
-    <!-- the darkening filter applied to notifications -->
-    <drawable name="notification_icon_area_smoke">#aa000000</drawable>
     <color name="notification_panel_scrim_color">#B0000000</color>
+    <color name="batterymeter_frame_color">#66FFFFFF</color><!-- 40% white -->
+    <color name="batterymeter_charge_color">#FFFFFFFF</color>
+    <color name="status_bar_clock_color">#FFFFFFFF</color>
 </resources>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 92df9b9..8ce959f 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -37,10 +37,6 @@
      interface.  This name is in the ComponentName flattened format (package/class)  -->
     <string name="config_statusBarComponent" translatable="false">com.android.systemui.statusbar.phone.PhoneStatusBar</string>
 
-    <!-- Component to be used as the system bar service.  Must implement the IStatusBar
-     interface.  This name is in the ComponentName flattened format (package/class)  -->
-    <string name="config_systemBarComponent" translatable="false">com.android.systemui.statusbar.tablet.TabletStatusBar</string>
-
     <!-- Whether or not we show the number in the bar. -->
     <bool name="config_statusBarShowNumber">false</bool>
 
@@ -105,5 +101,11 @@
 
     <!-- Should "4G" be shown instead of "LTE" when the network is NETWORK_TYPE_LTE? -->
     <bool name="config_show4GForLTE">true</bool>
+
+    <!-- milliseconds before the heads up notification auto-dismisses. -->
+    <integer name="heads_up_notification_decay">3700</integer>
+
+    <!-- milliseconds before the heads up notification accepts touches. -->
+    <integer name="heads_up_sensitivity_delay">700</integer>
 </resources>
 
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index f90f08a..3076ab4 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -89,7 +89,7 @@
     <dimen name="status_bar_icon_drawing_size">18dip</dimen>
 
     <!-- opacity at which Notification icons will be drawn in the status bar -->
-    <item type="dimen" name="status_bar_icon_drawing_alpha">65%</item>
+    <item type="dimen" name="status_bar_icon_drawing_alpha">75%</item>
 
     <!-- gap on either side of status bar notification icons -->
     <dimen name="status_bar_icon_padding">0dp</dimen>
@@ -212,4 +212,7 @@
     <dimen name="qs_tile_margin_below_icon">17dp</dimen>
     <!-- Quick Settings tile geometry: icon size -->
     <dimen name="qs_tile_icon_size">32dp</dimen>
+
+    <!-- The width of the notification panel window: match_parent below sw600dp -->
+    <dimen name="notification_panel_width">-1dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
deleted file mode 100644
index 2cc3446..0000000
--- a/packages/SystemUI/res/values/ids.xml
+++ /dev/null
@@ -1,23 +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>
-    <item type="id" name="expandable_tag" />
-    <item type="id" name="user_expanded_tag" />
-    <item type="id" name="user_lock_tag" />
-    <item type="id" name="status_bar_cling_stub" />
-</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 5767e63..7fdd308 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -24,17 +24,6 @@
          all of the currently visible notifications. [CHAR LIMIT=10]-->
     <string name="status_bar_clear_all_button">Clear</string>
 
-    <!-- The text for the button in the notification window-shade that turns
-         on do not disturb mode, where notifications no longer show their ticker,
-         no sound plays, and no icons are visible.  The windowshade continues to show
-         the notifications. [CHAR LIMIT=25]-->
-    <string name="status_bar_do_not_disturb_button">Do not disturb</string>
-
-    <!-- The text for the button in the notification window-shade that turns
-         off do not disturb mode.  After clicking this, notifications will be
-         shown again. [CHAR LIMIT=25] -->
-    <string name="status_bar_please_disturb_button">Show notifications</string>
-
     <!-- Title shown in recents popup for removing an application from the list -->
     <string name="status_bar_recent_remove_item_title">Remove from list</string>
 
@@ -171,12 +160,6 @@
          [CHAR LIMIT=25] -->
     <string name="compat_mode_off">Stretch to fill screen</string>
 
-    <!-- Compatibility mode help screen: header text. [CHAR LIMIT=50] -->
-    <string name="compat_mode_help_header">Compatibility zoom</string>
-
-    <!-- Compatibility mode help screen: body text. [CHAR LIMIT=150] -->
-    <string name="compat_mode_help_body">When an app was designed for a smaller screen, a zoom control will appear by the clock.</string>
-
     <!-- Notification ticker displayed when a screenshot is being saved to the Gallery. [CHAR LIMIT=30] -->
     <string name="screenshot_saving_ticker">Saving screenshot\u2026</string>
     <!-- Notification title displayed when a screenshot is being saved to the Gallery. [CHAR LIMIT=50] -->
@@ -429,6 +412,9 @@
     <!-- Notification text: when GPS has found a fix [CHAR LIMIT=50] -->
     <string name="gps_notification_found_text">Location set by GPS</string>
 
+    <!-- Accessibility text describing the presence of active location requests by one or more apps -->
+    <string name="accessibility_location_active">Location requests active</string>
+
     <!-- Content description of the clear button in the notification panel for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_clear_all">Clear all notifications.</string>
 
@@ -436,16 +422,6 @@
          application -->
     <string name="status_bar_notification_inspect_item_title">App info</string>
 
-    <!-- [CHAR LIMIT=NONE] -->
-    <string name="close_universe">Close</string>
-
-    <!-- Title for the pseudo-notification shown when notifications are disabled (do-not-disturb
-         mode) -->
-    <string name="notifications_off_title">Notifications off</string>
-
-    <!-- Content text for do-not-disturb mode notification -->
-    <string name="notifications_off_text">Tap here to turn notifications back on.</string>
-
     <!-- Description of the button in the phone-style notification panel that controls auto-rotation, when auto-rotation is on. [CHAR LIMIT=NONE] -->
     <string name="accessibility_rotation_lock_off">Screen will rotate automatically.</string>
 
@@ -455,8 +431,8 @@
     <!-- Description of the button in the phone-style notification panel that controls auto-rotation, when auto-rotation is off. [CHAR LIMIT=NONE] -->
     <string name="accessibility_rotation_lock_on_portrait">Screen is locked in portrait orientation.</string>
 
-    <!-- Name of the Jelly Bean platlogo screensaver -->
-    <string name="jelly_bean_dream_name">BeanFlinger</string>
+    <!-- Name of the K-release easter egg: a display case for all our tastiest desserts. [CHAR LIMIT=30] -->
+    <string name="dessert_case">Dessert Case</string>
 
     <!-- Name of the launcher shortcut icon that allows dreams to be started immediately [CHAR LIMIT=20] -->
     <string name="start_dreams">Daydream</string>
@@ -485,7 +461,9 @@
     <!-- QuickSettings: IME [CHAR LIMIT=NONE] -->
     <string name="quick_settings_ime_label">Input Method</string>
     <!-- QuickSettings: Location [CHAR LIMIT=NONE] -->
-    <string name="quick_settings_location_label">Location in use</string>
+    <string name="quick_settings_location_label">Location</string>
+    <!-- QuickSettings: Location (Off) [CHAR LIMIT=NONE] -->
+    <string name="quick_settings_location_off_label">Location Off</string>
     <!-- QuickSettings: Media device [CHAR LIMIT=NONE] -->
     <string name="quick_settings_media_device_label">Media device</string>
     <!-- QuickSettings: RSSI [CHAR LIMIT=NONE] -->
@@ -515,8 +493,12 @@
     <!-- QuickSettings: Brightness dialog auto brightness button [CHAR LIMIT=NONE] -->
     <string name="quick_settings_brightness_dialog_auto_brightness_label">AUTO</string>
 
-    <!-- Title of help text shown when the notification panel is pulled down for the very first time. [CHAR LIMIT=NONE] -->
-    <string name="status_bar_help_title">Notifications appear here</string>
-    <!-- Body of help text shown when the notification panel is pulled down for the very first time. [CHAR LIMIT=NONE] -->
-    <string name="status_bar_help_text">Access them anytime by swiping down.\nSwipe down again for system controls.</string>
+
+    <!-- Glyph to be overlaid atop the battery when the level is extremely low. Do not translate. -->
+    <string name="battery_meter_very_low_overlay_symbol">!</string>
+
+    <!-- Shows up when there is a user SSL CA Cert installed on the
+         device.  Indicates to the user that SSL traffic can be intercepted.  [CHAR LIMIT=NONE] -->
+    <string name="ssl_ca_cert_warning">Network may be monitored</string>
+
 </resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 7ddf261..134f228 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -34,7 +34,7 @@
         <item name="android:wallpaperIntraOpenExitAnimation">@anim/wallpaper_recents_launch_from_launcher_exit</item>
     </style>
 
-    <style name="TextAppearance.StatusBar.IntruderAlert"
+    <style name="TextAppearance.StatusBar.HeadsUp"
         parent="@*android:style/TextAppearance.StatusBar">
     </style>
 
@@ -56,13 +56,7 @@
         <!-- Note: must be dp to fit in status bar -->
         <item name="android:textSize">16dp</item>
         <item name="android:textStyle">normal</item>
-        <item name="android:textColor">@android:color/holo_blue_light</item>
-    </style>
-
-    <style name="TextAppearance.StatusBar.Date" parent="@*android:style/TextAppearance.StatusBar.Icon">
-        <item name="android:textSize">16dp</item>
-        <item name="android:textStyle">normal</item>
-        <item name="android:textColor">@android:color/holo_blue_light</item>
+        <item name="android:textColor">@color/status_bar_clock_color</item>
     </style>
 
     <style name="TextAppearance.StatusBar.Expanded" parent="@*android:style/TextAppearance.StatusBar" />
@@ -154,9 +148,9 @@
     <style name="Animation.StatusBar">
     </style>
 
-    <style name="Animation.StatusBar.IntruderAlert">
-        <item name="android:windowEnterAnimation">@anim/priority_alert_enter</item>
-        <item name="android:windowExitAnimation">@anim/priority_alert_exit</item>
+    <style name="Animation.StatusBar.HeadsUp">
+        <item name="android:windowEnterAnimation">@anim/heads_up_enter</item>
+        <item name="android:windowExitAnimation">@anim/heads_up_exit</item>
     </style>
 
     <style name="TextAppearance.StatusBar.PhoneTicker"
@@ -165,33 +159,4 @@
         <item name="android:textSize">14dp</item>
     </style>
     
-    <style name="ClingButton">
-        <item name="android:layout_width">wrap_content</item>
-        <item name="android:layout_height">wrap_content</item>
-        <item name="android:paddingTop">10dp</item>
-        <item name="android:paddingBottom">15dp</item>
-        <item name="android:paddingLeft">35dp</item>
-        <item name="android:paddingRight">35dp</item>
-        <item name="android:textStyle">bold</item>
-        <item name="android:background">@drawable/cling_button_bg</item>
-    </style>
-    <style name="ClingTitleText">
-        <item name="android:layout_width">wrap_content</item>
-        <item name="android:layout_height">wrap_content</item>
-        <item name="android:layout_marginBottom">5dp</item>
-        <item name="android:textSize">23sp</item>
-        <item name="android:textColor">#49C0EC</item>
-        <item name="android:shadowColor">#000000</item>
-        <item name="android:shadowDy">2</item>
-        <item name="android:shadowRadius">2.0</item>
-    </style>
-    <style name="ClingText">
-        <item name="android:textSize">15sp</item>
-        <item name="android:textColor">#FFFFFF</item>
-        <item name="android:shadowColor">#000000</item>
-        <item name="android:shadowDy">2</item>
-        <item name="android:shadowRadius">2.0</item>
-        <item name="android:lineSpacingMultiplier">1.1</item>
-    </style>
-
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
new file mode 100755
index 0000000..2257617
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -0,0 +1,362 @@
+/*
+ * 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.systemui;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.Typeface;
+import android.os.BatteryManager;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.util.AttributeSet;
+import android.view.View;
+
+public class BatteryMeterView extends View implements DemoMode {
+    public static final String TAG = BatteryMeterView.class.getSimpleName();
+    public static final String ACTION_LEVEL_TEST = "com.android.systemui.BATTERY_LEVEL_TEST";
+
+    public static final boolean ENABLE_PERCENT = true;
+    public static final boolean SINGLE_DIGIT_PERCENT = false;
+    public static final boolean SHOW_100_PERCENT = false;
+
+    public static final int FULL = 96;
+    public static final int EMPTY = 4;
+
+    int[] mColors;
+
+    boolean mShowPercent = true;
+    Paint mFramePaint, mBatteryPaint, mWarningTextPaint, mTextPaint, mBoltPaint;
+    int mButtonHeight;
+    private float mTextHeight, mWarningTextHeight;
+
+    private int mHeight;
+    private int mWidth;
+    private String mWarningString;
+    private final int mChargeColor;
+    private final float[] mBoltPoints;
+    private final Path mBoltPath = new Path();
+
+    private final RectF mFrame = new RectF();
+    private final RectF mButtonFrame = new RectF();
+    private final RectF mClipFrame = new RectF();
+    private final Rect mBoltFrame = new Rect();
+
+    private class BatteryTracker extends BroadcastReceiver {
+        // current battery status
+        int level;
+        String percentStr;
+        int plugType;
+        boolean plugged;
+        int health;
+        int status;
+        String technology;
+        int voltage;
+        int temperature;
+        boolean testmode = false;
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final String action = intent.getAction();
+            if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
+                if (testmode && ! intent.getBooleanExtra("testmode", false)) return;
+
+                level = (int)(100f
+                        * intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0)
+                        / intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100));
+
+                plugType = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
+                plugged = plugType != 0;
+                health = intent.getIntExtra(BatteryManager.EXTRA_HEALTH,
+                        BatteryManager.BATTERY_HEALTH_UNKNOWN);
+                status = intent.getIntExtra(BatteryManager.EXTRA_STATUS,
+                        BatteryManager.BATTERY_STATUS_UNKNOWN);
+                technology = intent.getStringExtra(BatteryManager.EXTRA_TECHNOLOGY);
+                voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, 0);
+                temperature = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 0);
+
+                setContentDescription(
+                        context.getString(R.string.accessibility_battery_level, level));
+                postInvalidate();
+            } else if (action.equals(ACTION_LEVEL_TEST)) {
+                testmode = true;
+                post(new Runnable() {
+                    int curLevel = 0;
+                    int incr = 1;
+                    int saveLevel = level;
+                    int savePlugged = plugType;
+                    Intent dummy = new Intent(Intent.ACTION_BATTERY_CHANGED);
+                    @Override
+                    public void run() {
+                        if (curLevel < 0) {
+                            testmode = false;
+                            dummy.putExtra("level", saveLevel);
+                            dummy.putExtra("plugged", savePlugged);
+                            dummy.putExtra("testmode", false);
+                        } else {
+                            dummy.putExtra("level", curLevel);
+                            dummy.putExtra("plugged", incr > 0 ? BatteryManager.BATTERY_PLUGGED_AC : 0);
+                            dummy.putExtra("testmode", true);
+                        }
+                        getContext().sendBroadcast(dummy);
+
+                        if (!testmode) return;
+
+                        curLevel += incr;
+                        if (curLevel == 100) {
+                            incr *= -1;
+                        }
+                        postDelayed(this, 200);
+                    }
+                });
+            }
+        }
+    }
+
+    BatteryTracker mTracker = new BatteryTracker();
+
+    @Override
+    public void onAttachedToWindow() {
+        super.onAttachedToWindow();
+
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_BATTERY_CHANGED);
+        filter.addAction(ACTION_LEVEL_TEST);
+        getContext().registerReceiver(mTracker, filter);
+    }
+
+    @Override
+    public void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+
+        getContext().unregisterReceiver(mTracker);
+    }
+
+    public BatteryMeterView(Context context) {
+        this(context, null, 0);
+    }
+
+    public BatteryMeterView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public BatteryMeterView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        final Resources res = context.getResources();
+        TypedArray levels = res.obtainTypedArray(R.array.batterymeter_color_levels);
+        TypedArray colors = res.obtainTypedArray(R.array.batterymeter_color_values);
+
+        final int N = levels.length();
+        mColors = new int[2*N];
+        for (int i=0; i<N; i++) {
+            mColors[2*i] = levels.getInt(i, 0);
+            mColors[2*i+1] = colors.getColor(i, 0);
+        }
+        levels.recycle();
+        colors.recycle();
+        mShowPercent = ENABLE_PERCENT && 0 != Settings.System.getInt(
+                context.getContentResolver(), "status_bar_show_battery_percent", 0);
+
+        mWarningString = context.getString(R.string.battery_meter_very_low_overlay_symbol);
+
+        mFramePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        mFramePaint.setColor(res.getColor(R.color.batterymeter_frame_color));
+        mBatteryPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        mBatteryPaint.setColor(0xFF00FF00); // will be replaced by something from mColors
+
+        mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        mTextPaint.setColor(0xFFFFFFFF);
+        Typeface font = Typeface.create("sans-serif-condensed", Typeface.NORMAL);
+        mTextPaint.setTypeface(font);
+        mTextPaint.setTextAlign(Paint.Align.CENTER);
+
+        mWarningTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        mWarningTextPaint.setColor(mColors[1]);
+        font = Typeface.create("sans-serif", Typeface.BOLD);
+        mWarningTextPaint.setTypeface(font);
+        mWarningTextPaint.setTextAlign(Paint.Align.CENTER);
+
+        mChargeColor = getResources().getColor(R.color.batterymeter_charge_color);
+
+        mBoltPaint = new Paint();
+        mBoltPaint.setAntiAlias(true);
+        mBoltPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));  // punch hole
+        setLayerType(LAYER_TYPE_HARDWARE, null);
+        mBoltPoints = loadBoltPoints(res);
+    }
+
+    private static float[] loadBoltPoints(Resources res) {
+        final int[] pts = res.getIntArray(R.array.batterymeter_bolt_points);
+        int maxX = 0, maxY = 0;
+        for (int i = 0; i < pts.length; i += 2) {
+            maxX = Math.max(maxX, pts[i]);
+            maxY = Math.max(maxY, pts[i + 1]);
+        }
+        final float[] ptsF = new float[pts.length];
+        for (int i = 0; i < pts.length; i += 2) {
+            ptsF[i] = (float)pts[i] / maxX;
+            ptsF[i + 1] = (float)pts[i + 1] / maxY;
+        }
+        return ptsF;
+    }
+
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        mHeight = h;
+        mWidth = w;
+        mWarningTextPaint.setTextSize(h * 0.75f);
+        mWarningTextHeight = -mWarningTextPaint.getFontMetrics().ascent;
+    }
+
+    private int getColorForLevel(int percent) {
+        int thresh, color = 0;
+        for (int i=0; i<mColors.length; i+=2) {
+            thresh = mColors[i];
+            color = mColors[i+1];
+            if (percent <= thresh) return color;
+        }
+        return color;
+    }
+
+    @Override
+    public void draw(Canvas c) {
+        BatteryTracker tracker = mDemoMode ? mDemoTracker : mTracker;
+        final int level = tracker.level;
+        float drawFrac = (float) level / 100f;
+        final int pt = getPaddingTop();
+        final int pl = getPaddingLeft();
+        final int pr = getPaddingRight();
+        final int pb = getPaddingBottom();
+        int height = mHeight - pt - pb;
+        int width = mWidth - pl - pr;
+
+        mButtonHeight = (int) (height * 0.12f);
+
+        mFrame.set(0, 0, width, height);
+        mFrame.offset(pl, pt);
+
+        mButtonFrame.set(
+                mFrame.left + width * 0.25f,
+                mFrame.top,
+                mFrame.right - width * 0.25f,
+                mFrame.top + mButtonHeight);
+
+        mFrame.top += mButtonHeight;
+
+        // first, draw the battery shape
+        c.drawRect(mFrame, mFramePaint);
+
+        // fill 'er up
+        final int pct = tracker.level;
+        final int color = tracker.plugged ? mChargeColor : getColorForLevel(pct);
+        mBatteryPaint.setColor(color);
+
+        if (level >= FULL) {
+            drawFrac = 1f;
+        } else if (level <= EMPTY) {
+            drawFrac = 0f;
+        }
+
+        c.drawRect(mButtonFrame, drawFrac == 1f ? mBatteryPaint : mFramePaint);
+
+        mClipFrame.set(mFrame);
+        mClipFrame.top += (mFrame.height() * (1f - drawFrac));
+
+        c.save(Canvas.CLIP_SAVE_FLAG);
+        c.clipRect(mClipFrame);
+        c.drawRect(mFrame, mBatteryPaint);
+        c.restore();
+
+        if (level <= EMPTY) {
+            final float x = mWidth * 0.5f;
+            final float y = (mHeight + mWarningTextHeight) * 0.48f;
+            c.drawText(mWarningString, x, y, mWarningTextPaint);
+        } else if (tracker.plugged) {
+            // draw the bolt
+            final int bl = (int)(mFrame.left + width / 4f);
+            final int bt = (int)(mFrame.top + height / 6f);
+            final int br = (int)(mFrame.right - width / 5f);
+            final int bb = (int)(mFrame.bottom - height / 6f);
+            if (mBoltFrame.left != bl || mBoltFrame.top != bt
+                    || mBoltFrame.right != br || mBoltFrame.bottom != bb) {
+                mBoltFrame.set(bl, bt, br, bb);
+                mBoltPath.reset();
+                mBoltPath.moveTo(
+                        mBoltFrame.left + mBoltPoints[0] * mBoltFrame.width(),
+                        mBoltFrame.top + mBoltPoints[1] * mBoltFrame.height());
+                for (int i = 2; i < mBoltPoints.length; i += 2) {
+                    mBoltPath.lineTo(
+                            mBoltFrame.left + mBoltPoints[i] * mBoltFrame.width(),
+                            mBoltFrame.top + mBoltPoints[i + 1] * mBoltFrame.height());
+                }
+                mBoltPath.lineTo(
+                        mBoltFrame.left + mBoltPoints[0] * mBoltFrame.width(),
+                        mBoltFrame.top + mBoltPoints[1] * mBoltFrame.height());
+            }
+            c.drawPath(mBoltPath, mBoltPaint);
+        } else if (mShowPercent && !(tracker.level == 100 && !SHOW_100_PERCENT)) {
+            mTextPaint.setTextSize(height *
+                    (SINGLE_DIGIT_PERCENT ? 0.75f
+                            : (tracker.level == 100 ? 0.38f : 0.5f)));
+            mTextHeight = -mTextPaint.getFontMetrics().ascent;
+
+            final String str = String.valueOf(SINGLE_DIGIT_PERCENT ? (pct/10) : pct);
+            final float x = mWidth * 0.5f;
+            final float y = (mHeight + mTextHeight) * 0.47f;
+            c.drawText(str,
+                    x,
+                    y,
+                    mTextPaint);
+        }
+    }
+
+    private boolean mDemoMode;
+    private BatteryTracker mDemoTracker = new BatteryTracker();
+
+    @Override
+    public void dispatchDemoCommand(String command, Bundle args) {
+        if (!mDemoMode && command.equals(COMMAND_ENTER)) {
+            mDemoMode = true;
+            mDemoTracker.level = mTracker.level;
+            mDemoTracker.plugged = mTracker.plugged;
+        } else if (mDemoMode && command.equals(COMMAND_EXIT)) {
+            mDemoMode = false;
+            postInvalidate();
+        } else if (mDemoMode && command.equals(COMMAND_BATTERY)) {
+           String level = args.getString("level");
+           String plugged = args.getString("plugged");
+           if (level != null) {
+               mDemoTracker.level = Math.min(Math.max(Integer.parseInt(level), 0), 100);
+           }
+           if (plugged != null) {
+               mDemoTracker.plugged = Boolean.parseBoolean(plugged);
+           }
+           postInvalidate();
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/BeanBag.java b/packages/SystemUI/src/com/android/systemui/BeanBag.java
deleted file mode 100644
index f5a90ca..0000000
--- a/packages/SystemUI/src/com/android/systemui/BeanBag.java
+++ /dev/null
@@ -1,431 +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.systemui;
-
-import android.animation.AnimatorSet;
-import android.animation.PropertyValuesHolder;
-import android.animation.ObjectAnimator;
-import android.animation.TimeAnimator;
-import android.app.Activity;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.graphics.drawable.AnimationDrawable;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.ColorMatrix;
-import android.graphics.ColorMatrixColorFilter;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.Point;
-import android.graphics.PorterDuffColorFilter;
-import android.graphics.PorterDuffXfermode;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.os.Handler;
-import android.os.SystemClock;
-import android.provider.Settings;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.Pair;
-import android.view.Gravity;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.view.animation.AnimationUtils;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import java.util.HashMap;
-import java.util.Random;
-
-public class BeanBag extends Activity {
-    final static boolean DEBUG = false;
-
-    public static class Board extends FrameLayout
-    {
-        static Random sRNG = new Random();
-
-        static float lerp(float a, float b, float f) {
-            return (b-a)*f + a;
-        }
-
-        static float randfrange(float a, float b) {
-            return lerp(a, b, sRNG.nextFloat());
-        }
-
-        static int randsign() {
-            return sRNG.nextBoolean() ? 1 : -1;
-        }
-
-        static boolean flip() {
-            return sRNG.nextBoolean();
-        }
-
-        static float mag(float x, float y) {
-            return (float) Math.sqrt(x*x+y*y);
-        }
-
-        static float clamp(float x, float a, float b) {
-            return ((x<a)?a:((x>b)?b:x));
-        }
-
-        static float dot(float x1, float y1, float x2, float y2) {
-            return x1*x2+y1+y2;
-        }
-
-        static <E> E pick(E[] array) {
-            if (array.length == 0) return null;
-            return array[sRNG.nextInt(array.length)];
-        }
-
-        static int pickInt(int[] array) {
-            if (array.length == 0) return 0;
-            return array[sRNG.nextInt(array.length)];
-        }
-
-        static int NUM_BEANS = 40;
-        static float MIN_SCALE = 0.2f;
-        static float MAX_SCALE = 1f;
-
-        static float LUCKY = 0.001f;
-
-        static int MAX_RADIUS = (int)(576 * MAX_SCALE);
-
-        static int BEANS[] = {
-          R.drawable.redbean0,
-          R.drawable.redbean0,
-          R.drawable.redbean0,
-          R.drawable.redbean0,
-          R.drawable.redbean1,
-          R.drawable.redbean1,
-          R.drawable.redbean2,
-          R.drawable.redbean2,
-          R.drawable.redbeandroid,
-        };
-
-        static int COLORS[] = {
-            0xFF00CC00,
-            0xFFCC0000,
-            0xFF0000CC,
-            0xFFFFFF00,
-            0xFFFF8000,
-            0xFF00CCFF,
-            0xFFFF0080,
-            0xFF8000FF,
-            0xFFFF8080,
-            0xFF8080FF,
-            0xFFB0C0D0,
-            0xFFDDDDDD,
-            0xFF333333,
-        };
-
-        public class Bean extends ImageView {
-            public static final float VMAX = 1000.0f;
-            public static final float VMIN = 100.0f;
-
-            public float x, y, a;
-
-            public float va;
-            public float vx, vy;
-
-            public float r;
-
-            public float z;
-
-            public int h,w;
-
-            public boolean grabbed;
-            public float grabx, graby;
-            public long grabtime;
-            private float grabx_offset, graby_offset;
-
-            public Bean(Context context, AttributeSet as) {
-                super(context, as);
-            }
-
-            public String toString() {
-                return String.format("<bean (%.1f, %.1f) (%d x %d)>",
-                    getX(), getY(), getWidth(), getHeight());
-            }
-
-            private void pickBean() {
-                int beanId = pickInt(BEANS);
-                if (randfrange(0,1) <= LUCKY) {
-                    beanId = R.drawable.jandycane;
-                }
-                BitmapDrawable bean = (BitmapDrawable) getContext().getResources().getDrawable(beanId);
-                Bitmap beanBits = bean.getBitmap();
-                h=beanBits.getHeight();
-                w=beanBits.getWidth();
-
-                if (DEBUG) {
-                    bean.setAlpha(0x80);
-                }
-                this.setImageDrawable(bean);
-
-                Paint pt = new Paint();
-                final int color = pickInt(COLORS);
-                ColorMatrix CM = new ColorMatrix();
-                float[] M = CM.getArray();
-                // we assume the color information is in the red channel
-                /* R */ M[0]  = (float)((color & 0x00FF0000) >> 16) / 0xFF;
-                /* G */ M[5]  = (float)((color & 0x0000FF00) >> 8)  / 0xFF;
-                /* B */ M[10] = (float)((color & 0x000000FF))       / 0xFF;
-                pt.setColorFilter(new ColorMatrixColorFilter(M));
-                setLayerType(View.LAYER_TYPE_HARDWARE, (beanId == R.drawable.jandycane) ? null : pt);
-            }
-
-            public void reset() {
-                pickBean();
-
-                final float scale = lerp(MIN_SCALE,MAX_SCALE,z);
-                setScaleX(scale); setScaleY(scale);
-
-                r = 0.3f*Math.max(h,w)*scale;
-
-                a=(randfrange(0,360));
-                va = randfrange(-30,30);
-
-                vx = randfrange(-40,40) * z;
-                vy = randfrange(-40,40) * z;
-                final float boardh = boardHeight;
-                final float boardw = boardWidth;
-                //android.util.Log.d("BeanBag", "reset: w="+w+" h="+h);
-                if (flip()) {
-                    x=(vx < 0 ? boardw+2*r : -r*4f);
-                    y=(randfrange(0, boardh-3*r)*0.5f + ((vy < 0)?boardh*0.5f:0));
-                } else {
-                    y=(vy < 0 ? boardh+2*r : -r*4f);
-                    x=(randfrange(0, boardw-3*r)*0.5f + ((vx < 0)?boardw*0.5f:0));
-                }
-            }
-
-            public void update(float dt) {
-                if (grabbed) {
-//                    final float interval = (SystemClock.uptimeMillis() - grabtime) / 1000f;
-                    vx = (vx * 0.75f) + ((grabx - x) / dt) * 0.25f;
-                    x = grabx;
-                    vy = (vy * 0.75f) + ((graby - y) / dt) * 0.25f;;
-                    y = graby;
-                } else {
-                    x = (x + vx * dt);
-                    y = (y + vy * dt);
-                    a = (a + va * dt);
-                }
-            }
-
-            public float overlap(Bean other) {
-                final float dx = (x - other.x);
-                final float dy = (y - other.y);
-                return mag(dx, dy) - r - other.r;
-            }
-
-            @Override
-            public boolean onTouchEvent(MotionEvent e) {
-                switch (e.getAction()) {
-                    case MotionEvent.ACTION_DOWN:
-                        grabbed = true;
-                        grabx_offset = e.getRawX() - x;
-                        graby_offset = e.getRawY() - y;
-                        va = 0;
-                        // fall
-                    case MotionEvent.ACTION_MOVE:
-                        grabx = e.getRawX() - grabx_offset;
-                        graby = e.getRawY() - graby_offset;
-                        grabtime = e.getEventTime();
-                        break;
-                    case MotionEvent.ACTION_CANCEL:
-                    case MotionEvent.ACTION_UP:
-                        grabbed = false;
-                        float a = randsign() * clamp(mag(vx, vy) * 0.33f, 0, 1080f);
-                        va = randfrange(a*0.5f, a);
-                        break;
-                }
-                return true;
-            }
-        }
-
-        TimeAnimator mAnim;
-        private int boardWidth;
-        private int boardHeight;
-
-        public Board(Context context, AttributeSet as) {
-            super(context, as);
-
-            setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
-
-            setWillNotDraw(!DEBUG);
-        }
-
-        private void reset() {
-//            android.util.Log.d("Nyandroid", "board reset");
-            removeAllViews();
-
-            final ViewGroup.LayoutParams wrap = new ViewGroup.LayoutParams(
-                        ViewGroup.LayoutParams.WRAP_CONTENT,
-                        ViewGroup.LayoutParams.WRAP_CONTENT);
-
-            for(int i=0; i<NUM_BEANS; i++) {
-                Bean nv = new Bean(getContext(), null);
-                addView(nv, wrap);
-                nv.z = ((float)i/NUM_BEANS);
-                nv.z *= nv.z;
-                nv.reset();
-                nv.x = (randfrange(0, boardWidth));
-                nv.y = (randfrange(0, boardHeight));
-            }
-
-            if (mAnim != null) {
-                mAnim.cancel();
-            }
-            mAnim = new TimeAnimator();
-            mAnim.setTimeListener(new TimeAnimator.TimeListener() {
-                private long lastPrint = 0;
-                public void onTimeUpdate(TimeAnimator animation, long totalTime, long deltaTime) {
-                    if (DEBUG && totalTime - lastPrint > 5000) {
-                        lastPrint = totalTime;
-                        for (int i=0; i<getChildCount(); i++) {
-                            android.util.Log.d("BeanBag", "bean " + i + ": " + getChildAt(i));
-                        }
-                    }
-
-                    for (int i=0; i<getChildCount(); i++) {
-                        View v = getChildAt(i);
-                        if (!(v instanceof Bean)) continue;
-                        Bean nv = (Bean) v;
-                        nv.update(deltaTime / 1000f);
-
-                        for (int j=i+1; j<getChildCount(); j++) {
-                            View v2 = getChildAt(j);
-                            if (!(v2 instanceof Bean)) continue;
-                            Bean nv2 = (Bean) v2;
-                            final float overlap = nv.overlap(nv2);
-                        }
-
-                        nv.setRotation(nv.a);
-                        nv.setX(nv.x-nv.getPivotX());
-                        nv.setY(nv.y-nv.getPivotY());
-
-                        if (   nv.x < - MAX_RADIUS
-                            || nv.x > boardWidth + MAX_RADIUS
-                            || nv.y < -MAX_RADIUS
-                            || nv.y > boardHeight + MAX_RADIUS)
-                        {
-                            nv.reset();
-                        }
-                    }
-
-                    if (DEBUG) invalidate();
-                }
-            });
-        }
-
-        @Override
-        protected void onSizeChanged (int w, int h, int oldw, int oldh) {
-            super.onSizeChanged(w,h,oldw,oldh);
-            boardWidth = w;
-            boardHeight = h;
-//            android.util.Log.d("Nyandroid", "resized: " + w + "x" + h);
-        }
-
-        public void startAnimation() {
-            stopAnimation();
-            if (mAnim == null) {
-                post(new Runnable() { public void run() {
-                    reset();
-                    startAnimation();
-                } });
-            } else {
-                mAnim.start();
-            }
-        }
-
-        public void stopAnimation() {
-            if (mAnim != null) mAnim.cancel();
-        }
-
-        @Override
-        protected void onDetachedFromWindow() {
-            super.onDetachedFromWindow();
-            stopAnimation();
-        }
-
-        @Override
-        public boolean isOpaque() {
-            return false;
-        }
-
-        @Override
-        public void onDraw(Canvas c) {
-            if (DEBUG) {
-                //android.util.Log.d("BeanBag", "onDraw");
-                Paint pt = new Paint();
-                pt.setAntiAlias(true);
-                pt.setStyle(Paint.Style.STROKE);
-                pt.setColor(0xFFFF0000);
-                pt.setStrokeWidth(4.0f);
-                c.drawRect(0, 0, getWidth(), getHeight(), pt);
-                pt.setColor(0xFFFFCC00);
-                pt.setStrokeWidth(1.0f);
-                for (int i=0; i<getChildCount(); i++) {
-                    Bean b = (Bean) getChildAt(i);
-                    final float a = (360-b.a)/180f*3.14159f;
-                    final float tx = b.getTranslationX();
-                    final float ty = b.getTranslationY();
-                    c.drawCircle(b.x, b.y, b.r, pt);
-                    c.drawCircle(tx, ty, 4, pt);
-                    c.drawLine(b.x, b.y, (float)(b.x+b.r*Math.sin(a)), (float)(b.y+b.r*Math.cos(a)), pt);
-                }
-            }
-        }
-    }
-
-    private Board mBoard;
-
-    @Override
-    public void onStart() {
-        super.onStart();
-
-        // ACHIEVEMENT UNLOCKED
-        PackageManager pm = getPackageManager();
-        pm.setComponentEnabledSetting(new ComponentName(this, BeanBagDream.class),
-                PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0);
-
-        getWindow().addFlags(
-                  WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
-                | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
-                );
-        mBoard = new Board(this, null);
-        setContentView(mBoard);
-    }
-
-    @Override
-    public void onPause() {
-        super.onPause();
-        mBoard.stopAnimation();
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        mBoard.startAnimation();
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/BeanBagDream.java b/packages/SystemUI/src/com/android/systemui/BeanBagDream.java
deleted file mode 100644
index 39e4727..0000000
--- a/packages/SystemUI/src/com/android/systemui/BeanBagDream.java
+++ /dev/null
@@ -1,47 +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.systemui;
-
-import android.service.dreams.DreamService;
-
-import com.android.systemui.BeanBag.Board;
-
-public class BeanBagDream extends DreamService {
-
-    private Board mBoard;
-
-    @Override
-    public void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        setInteractive(true);
-        setFullscreen(true);
-        mBoard = new Board(this, null);
-        setContentView(mBoard);
-    }
-
-    @Override
-    public void onDreamingStarted() {
-        super.onDreamingStarted();
-        mBoard.startAnimation();
-    }
-
-    @Override
-    public void onDreamingStopped() {
-        mBoard.stopAnimation();
-        super.onDreamingStopped();
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/BootReceiver.java b/packages/SystemUI/src/com/android/systemui/BootReceiver.java
index d3ce30d..8e24eeb 100644
--- a/packages/SystemUI/src/com/android/systemui/BootReceiver.java
+++ b/packages/SystemUI/src/com/android/systemui/BootReceiver.java
@@ -21,7 +21,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.provider.Settings;
-import android.util.Slog;
+import android.util.Log;
 
 /**
  * Performs a number of miscellaneous, non-system-critical actions
@@ -40,7 +40,7 @@
                 context.startService(loadavg);
             }
         } catch (Exception e) {
-            Slog.e(TAG, "Can't start load average service", e);
+            Log.e(TAG, "Can't start load average service", e);
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/DemoMode.java b/packages/SystemUI/src/com/android/systemui/DemoMode.java
new file mode 100644
index 0000000..8d271e4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/DemoMode.java
@@ -0,0 +1,34 @@
+/*
+ * 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.systemui;
+
+import android.os.Bundle;
+
+public interface DemoMode {
+
+    void dispatchDemoCommand(String command, Bundle args);
+
+    public static final String ACTION_DEMO = "com.android.systemui.demo";
+
+    public static final String COMMAND_ENTER = "enter";
+    public static final String COMMAND_EXIT = "exit";
+    public static final String COMMAND_CLOCK = "clock";
+    public static final String COMMAND_BATTERY = "battery";
+    public static final String COMMAND_NETWORK = "network";
+    public static final String COMMAND_BARS = "bars";
+    public static final String COMMAND_STATUS = "status";
+}
diff --git a/packages/SystemUI/src/com/android/systemui/DessertCase.java b/packages/SystemUI/src/com/android/systemui/DessertCase.java
new file mode 100644
index 0000000..b6424af0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/DessertCase.java
@@ -0,0 +1,37 @@
+/*
+ * 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.systemui;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.pm.PackageManager;
+import android.util.Slog;
+
+public class DessertCase extends Activity {
+
+    @Override
+    public void onStart() {
+        super.onStart();
+
+        Slog.v("DessertCase", "ACHIEVEMENT UNLOCKED");
+        PackageManager pm = getPackageManager();
+        pm.setComponentEnabledSetting(new ComponentName(this, DessertCaseDream.class),
+                PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0);
+
+        finish();
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/DessertCaseDream.java b/packages/SystemUI/src/com/android/systemui/DessertCaseDream.java
new file mode 100644
index 0000000..022e4d8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/DessertCaseDream.java
@@ -0,0 +1,39 @@
+/*
+ * 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.systemui;
+
+import android.service.dreams.DreamService;
+
+public class DessertCaseDream extends DreamService {
+
+    @Override
+    public void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        setInteractive(true);
+        setFullscreen(true);
+    }
+
+    @Override
+    public void onDreamingStarted() {
+        super.onDreamingStarted();
+    }
+
+    @Override
+    public void onDreamingStopped() {
+        super.onDreamingStopped();
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
index edfaf49..e1a4bb2 100644
--- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
@@ -23,23 +23,23 @@
 import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.os.Vibrator;
-import android.util.Slog;
+import android.util.Log;
 import android.view.Gravity;
 import android.view.MotionEvent;
 import android.view.ScaleGestureDetector;
 import android.view.ScaleGestureDetector.OnScaleGestureListener;
 import android.view.View;
+import android.view.View.OnClickListener;
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
-import android.view.View.OnClickListener;
 
 public class ExpandHelper implements Gefingerpoken, OnClickListener {
     public interface Callback {
         View getChildAtRawPosition(float x, float y);
         View getChildAtPosition(float x, float y);
         boolean canChildBeExpanded(View v);
-        boolean setUserExpandedChild(View v, boolean userExpanded);
-        boolean setUserLockedChild(View v, boolean userLocked);
+        void setUserExpandedChild(View v, boolean userExpanded);
+        void setUserLockedChild(View v, boolean userLocked);
     }
 
     private static final String TAG = "ExpandHelper";
@@ -109,11 +109,11 @@
 
     private View mScrollView;
 
-    private OnScaleGestureListener mScaleGestureListener 
+    private OnScaleGestureListener mScaleGestureListener
             = new ScaleGestureDetector.SimpleOnScaleGestureListener() {
         @Override
         public boolean onScaleBegin(ScaleGestureDetector detector) {
-            if (DEBUG_SCALE) Slog.v(TAG, "onscalebegin()");
+            if (DEBUG_SCALE) Log.v(TAG, "onscalebegin()");
             float focusX = detector.getFocusX();
             float focusY = detector.getFocusY();
 
@@ -126,7 +126,7 @@
 
         @Override
         public boolean onScale(ScaleGestureDetector detector) {
-            if (DEBUG_SCALE) Slog.v(TAG, "onscale() on " + mCurrView);
+            if (DEBUG_SCALE) Log.v(TAG, "onscale() on " + mCurrView);
             return true;
         }
 
@@ -143,7 +143,7 @@
             mView = v;
         }
         public void setHeight(float h) {
-            if (DEBUG_SCALE) Slog.v(TAG, "SetHeight: setting to " + h);
+            if (DEBUG_SCALE) Log.v(TAG, "SetHeight: setting to " + h);
             ViewGroup.LayoutParams lp = mView.getLayoutParams();
             lp.height = (int)h;
             mView.setLayoutParams(lp);
@@ -158,7 +158,7 @@
         }
         public int getNaturalHeight(int maximum) {
             ViewGroup.LayoutParams lp = mView.getLayoutParams();
-            if (DEBUG_SCALE) Slog.v(TAG, "Inspecting a child of type: " +
+            if (DEBUG_SCALE) Log.v(TAG, "Inspecting a child of type: " +
                     mView.getClass().getName());
             int oldHeight = lp.height;
             lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
@@ -181,7 +181,6 @@
      * @param callback the container that holds the items to be manipulated
      * @param small the smallest allowable size for the manuipulated items.
      * @param large the largest allowable size for the manuipulated items.
-     * @param scoller if non-null also manipulate the scroll position to obey the gravity.
      */
     public ExpandHelper(Context context, Callback callback, int small, int large) {
         mSmallSize = small;
@@ -230,7 +229,7 @@
     }
 
     private void updateExpansion() {
-        if (DEBUG_SCALE) Slog.v(TAG, "updateExpansion()");
+        if (DEBUG_SCALE) Log.v(TAG, "updateExpansion()");
         // are we scaling or dragging?
         float span = mSGD.getCurrentSpan() - mInitialTouchSpan;
         span *= USE_SPAN ? 1f : 0f;
@@ -270,10 +269,10 @@
     }
 
     private boolean isInside(View v, float x, float y) {
-        if (DEBUG) Slog.d(TAG, "isinside (" + x + ", " + y + ")");
+        if (DEBUG) Log.d(TAG, "isinside (" + x + ", " + y + ")");
 
         if (v == null) {
-            if (DEBUG) Slog.d(TAG, "isinside null subject");
+            if (DEBUG) Log.d(TAG, "isinside null subject");
             return false;
         }
         if (mEventSource != null) {
@@ -281,14 +280,14 @@
             mEventSource.getLocationOnScreen(location);
             x += location[0];
             y += location[1];
-            if (DEBUG) Slog.d(TAG, "  to global (" + x + ", " + y + ")");
+            if (DEBUG) Log.d(TAG, "  to global (" + x + ", " + y + ")");
         }
         int[] location = new int[2];
         v.getLocationOnScreen(location);
         x -= location[0];
         y -= location[1];
-        if (DEBUG) Slog.d(TAG, "  to local (" + x + ", " + y + ")");
-        if (DEBUG) Slog.d(TAG, "  inside (" + v.getWidth() + ", " + v.getHeight() + ")");
+        if (DEBUG) Log.d(TAG, "  to local (" + x + ", " + y + ")");
+        if (DEBUG) Log.d(TAG, "  inside (" + v.getWidth() + ", " + v.getHeight() + ")");
         boolean inside = (x > 0f && y > 0f && x < v.getWidth() & y < v.getHeight());
         return inside;
     }
@@ -307,10 +306,10 @@
 
     private float calculateGlow(float target, float actual) {
         // glow if overscale
-        if (DEBUG_GLOW) Slog.d(TAG, "target: " + target + " actual: " + actual);
+        if (DEBUG_GLOW) Log.d(TAG, "target: " + target + " actual: " + actual);
         float stretch = Math.abs((target - actual) / mMaximumStretch);
         float strength = 1f / (1f + (float) Math.pow(Math.E, -1 * ((8f * stretch) - 5f)));
-        if (DEBUG_GLOW) Slog.d(TAG, "stretch: " + stretch + " strength: " + strength);
+        if (DEBUG_GLOW) Log.d(TAG, "stretch: " + stretch + " strength: " + strength);
         return (GLOW_BASE + strength * (1f - GLOW_BASE));
     }
 
@@ -348,7 +347,7 @@
     @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
         final int action = ev.getAction();
-        if (DEBUG_SCALE) Slog.d(TAG, "intercept: act=" + MotionEvent.actionToString(action) +
+        if (DEBUG_SCALE) Log.d(TAG, "intercept: act=" + MotionEvent.actionToString(action) +
                          " expanding=" + mExpanding +
                          (0 != (mExpansionStyle & BLINDS) ? " (blinds)" : "") +
                          (0 != (mExpansionStyle & PULL) ? " (pull)" : "") +
@@ -362,7 +361,7 @@
         mInitialTouchSpan = mSGD.getCurrentSpan();
         mLastFocusY = mInitialTouchFocusY;
         mLastSpanY = mInitialTouchSpan;
-        if (DEBUG_SCALE) Slog.d(TAG, "set initial span: " + mInitialTouchSpan);
+        if (DEBUG_SCALE) Log.d(TAG, "set initial span: " + mInitialTouchSpan);
 
         if (mExpanding) {
             return true;
@@ -376,7 +375,7 @@
                     xspan > mPullGestureMinXSpan &&
                     xspan > mSGD.getCurrentSpanY())) {
                 // detect a vertical pulling gesture with fingers somewhat separated
-                if (DEBUG_SCALE) Slog.v(TAG, "got pull gesture (xspan=" + xspan + "px)");
+                if (DEBUG_SCALE) Log.v(TAG, "got pull gesture (xspan=" + xspan + "px)");
 
                 final View underFocus = findView(x, y);
                 if (underFocus != null) {
@@ -393,7 +392,7 @@
                 if (mWatchingForPull) {
                     final int yDiff = y - mLastMotionY;
                     if (yDiff > mTouchSlop) {
-                        if (DEBUG) Slog.v(TAG, "got venetian gesture (dy=" + yDiff + "px)");
+                        if (DEBUG) Log.v(TAG, "got venetian gesture (dy=" + yDiff + "px)");
                         mLastMotionY = y;
                         final View underFocus = findView(x, y);
                         if (underFocus != null) {
@@ -413,7 +412,7 @@
 
             case MotionEvent.ACTION_CANCEL:
             case MotionEvent.ACTION_UP:
-                if (DEBUG) Slog.d(TAG, "up/cancel");
+                if (DEBUG) Log.d(TAG, "up/cancel");
                 finishExpanding(false);
                 clearView();
                 break;
@@ -425,7 +424,7 @@
     @Override
     public boolean onTouchEvent(MotionEvent ev) {
         final int action = ev.getActionMasked();
-        if (DEBUG_SCALE) Slog.d(TAG, "touch: act=" + MotionEvent.actionToString(action) +
+        if (DEBUG_SCALE) Log.d(TAG, "touch: act=" + MotionEvent.actionToString(action) +
                 " expanding=" + mExpanding +
                 (0 != (mExpansionStyle & BLINDS) ? " (blinds)" : "") +
                 (0 != (mExpansionStyle & PULL) ? " (pull)" : "") +
@@ -484,14 +483,14 @@
 
             case MotionEvent.ACTION_POINTER_UP:
             case MotionEvent.ACTION_POINTER_DOWN:
-                if (DEBUG) Slog.d(TAG, "pointer change");
+                if (DEBUG) Log.d(TAG, "pointer change");
                 mInitialTouchY += mSGD.getFocusY() - mLastFocusY;
                 mInitialTouchSpan += mSGD.getCurrentSpan() - mLastSpanY;
                 break;
 
             case MotionEvent.ACTION_UP:
             case MotionEvent.ACTION_CANCEL:
-                if (DEBUG) Slog.d(TAG, "up/cancel");
+                if (DEBUG) Log.d(TAG, "up/cancel");
                 finishExpanding(false);
                 clearView();
                 break;
@@ -505,20 +504,20 @@
             return;
         }
         mExpanding = true;
-        if (DEBUG) Slog.d(TAG, "scale type " + expandType + " beginning on view: " + v);
+        if (DEBUG) Log.d(TAG, "scale type " + expandType + " beginning on view: " + v);
         mCallback.setUserLockedChild(v, true);
         setView(v);
         setGlow(GLOW_BASE);
         mScaler.setView(v);
         mOldHeight = mScaler.getHeight();
         if (mCallback.canChildBeExpanded(v)) {
-            if (DEBUG) Slog.d(TAG, "working on an expandable child");
+            if (DEBUG) Log.d(TAG, "working on an expandable child");
             mNaturalHeight = mScaler.getNaturalHeight(mLargeSize);
         } else {
-            if (DEBUG) Slog.d(TAG, "working on a non-expandable child");
+            if (DEBUG) Log.d(TAG, "working on a non-expandable child");
             mNaturalHeight = mOldHeight;
         }
-        if (DEBUG) Slog.d(TAG, "got mOldHeight: " + mOldHeight +
+        if (DEBUG) Log.d(TAG, "got mOldHeight: " + mOldHeight +
                     " mNaturalHeight: " + mNaturalHeight);
         v.getParent().requestDisallowInterceptTouchEvent(true);
     }
@@ -526,7 +525,7 @@
     private void finishExpanding(boolean force) {
         if (!mExpanding) return;
 
-        if (DEBUG) Slog.d(TAG, "scale in finishing on view: " + mCurrView);
+        if (DEBUG) Log.d(TAG, "scale in finishing on view: " + mCurrView);
 
         float currentHeight = mScaler.getHeight();
         float targetHeight = mSmallSize;
@@ -552,11 +551,11 @@
         mExpanding = false;
         mExpansionStyle = NONE;
 
-        if (DEBUG) Slog.d(TAG, "wasClosed is: " + wasClosed);
-        if (DEBUG) Slog.d(TAG, "currentHeight is: " + currentHeight);
-        if (DEBUG) Slog.d(TAG, "mSmallSize is: " + mSmallSize);
-        if (DEBUG) Slog.d(TAG, "targetHeight is: " + targetHeight);
-        if (DEBUG) Slog.d(TAG, "scale was finished on view: " + mCurrView);
+        if (DEBUG) Log.d(TAG, "wasClosed is: " + wasClosed);
+        if (DEBUG) Log.d(TAG, "currentHeight is: " + currentHeight);
+        if (DEBUG) Log.d(TAG, "mSmallSize is: " + mSmallSize);
+        if (DEBUG) Log.d(TAG, "targetHeight is: " + targetHeight);
+        if (DEBUG) Log.d(TAG, "scale was finished on view: " + mCurrView);
     }
 
     private void clearView() {
@@ -575,7 +574,7 @@
                 String debugLog = "Looking for glows: " +
                         (mCurrViewTopGlow != null ? "found top " : "didn't find top") +
                         (mCurrViewBottomGlow != null ? "found bottom " : "didn't find bottom");
-                Slog.v(TAG,  debugLog);
+                Log.v(TAG,  debugLog);
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index cdd3d84..6fa863d 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -16,6 +16,9 @@
 
 package com.android.systemui;
 
+import static android.opengl.GLES20.*;
+import static javax.microedition.khronos.egl.EGL10.*;
+
 import android.app.ActivityManager;
 import android.app.WallpaperManager;
 import android.content.BroadcastReceiver;
@@ -35,18 +38,16 @@
 import android.view.SurfaceHolder;
 import android.view.WindowManager;
 
-import javax.microedition.khronos.egl.EGL10;
-import javax.microedition.khronos.egl.EGLConfig;
-import javax.microedition.khronos.egl.EGLContext;
-import javax.microedition.khronos.egl.EGLDisplay;
-import javax.microedition.khronos.egl.EGLSurface;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.nio.FloatBuffer;
 
-import static android.opengl.GLES20.*;
-import static javax.microedition.khronos.egl.EGL10.*;
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+import javax.microedition.khronos.egl.EGLSurface;
 
 /**
  * Default built-in wallpaper that simply shows a static image.
@@ -139,7 +140,7 @@
                 "\nvoid main(void) {\n" +
                 "    gl_FragColor = texture2D(texture, outTexCoords);\n" +
                 "}\n\n";
-    
+
         private static final int FLOAT_SIZE_BYTES = 4;
         private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES;
         private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0;
@@ -183,7 +184,7 @@
             }
 
             super.onCreate(surfaceHolder);
-            
+
             // TODO: Don't need this currently because the wallpaper service
             // will restart the image wallpaper whenever the image changes.
             //IntentFilter filter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
@@ -511,44 +512,44 @@
 
         private int loadTexture(Bitmap bitmap) {
             int[] textures = new int[1];
-    
+
             glActiveTexture(GL_TEXTURE0);
             glGenTextures(1, textures, 0);
             checkGlError();
-    
+
             int texture = textures[0];
             glBindTexture(GL_TEXTURE_2D, texture);
             checkGlError();
-            
+
             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-    
+
             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-    
+
             GLUtils.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bitmap, GL_UNSIGNED_BYTE, 0);
             checkGlError();
 
             return texture;
         }
-        
+
         private int buildProgram(String vertex, String fragment) {
             int vertexShader = buildShader(vertex, GL_VERTEX_SHADER);
             if (vertexShader == 0) return 0;
-    
+
             int fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER);
             if (fragmentShader == 0) return 0;
-    
+
             int program = glCreateProgram();
             glAttachShader(program, vertexShader);
             checkGlError();
-    
+
             glAttachShader(program, fragmentShader);
             checkGlError();
-    
+
             glLinkProgram(program);
             checkGlError();
-    
+
             int[] status = new int[1];
             glGetProgramiv(program, GL_LINK_STATUS, status, 0);
             if (status[0] != GL_TRUE) {
@@ -559,19 +560,19 @@
                 glDeleteProgram(program);
                 return 0;
             }
-    
+
             return program;
         }
 
         private int buildShader(String source, int type) {
             int shader = glCreateShader(type);
-    
+
             glShaderSource(shader, source);
             checkGlError();
-    
+
             glCompileShader(shader);
             checkGlError();
-    
+
             int[] status = new int[1];
             glGetShaderiv(shader, GL_COMPILE_STATUS, status, 0);
             if (status[0] != GL_TRUE) {
@@ -580,7 +581,7 @@
                 glDeleteShader(shader);
                 return 0;
             }
-            
+
             return shader;
         }
 
@@ -607,24 +608,24 @@
 
         private boolean initGL(SurfaceHolder surfaceHolder) {
             mEgl = (EGL10) EGLContext.getEGL();
-    
+
             mEglDisplay = mEgl.eglGetDisplay(EGL_DEFAULT_DISPLAY);
             if (mEglDisplay == EGL_NO_DISPLAY) {
                 throw new RuntimeException("eglGetDisplay failed " +
                         GLUtils.getEGLErrorString(mEgl.eglGetError()));
             }
-            
+
             int[] version = new int[2];
             if (!mEgl.eglInitialize(mEglDisplay, version)) {
                 throw new RuntimeException("eglInitialize failed " +
                         GLUtils.getEGLErrorString(mEgl.eglGetError()));
             }
-    
+
             mEglConfig = chooseEglConfig();
             if (mEglConfig == null) {
                 throw new RuntimeException("eglConfig not initialized");
             }
-            
+
             mEglContext = createContext(mEgl, mEglDisplay, mEglConfig);
             if (mEglContext == EGL_NO_CONTEXT) {
                 throw new RuntimeException("createContext failed " +
@@ -666,7 +667,7 @@
                 throw new RuntimeException("createWindowSurface failed " +
                         GLUtils.getEGLErrorString(error));
             }
-    
+
             if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
                 throw new RuntimeException("eglMakeCurrent failed " +
                         GLUtils.getEGLErrorString(mEgl.eglGetError()));
@@ -674,13 +675,13 @@
 
             return true;
         }
-        
-    
+
+
         EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) {
             int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
-            return egl.eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, attrib_list);            
+            return egl.eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, attrib_list);
         }
-    
+
         private EGLConfig chooseEglConfig() {
             int[] configsCount = new int[1];
             EGLConfig[] configs = new EGLConfig[1];
diff --git a/packages/SystemUI/src/com/android/systemui/LoadAverageService.java b/packages/SystemUI/src/com/android/systemui/LoadAverageService.java
index 2b45ad1..610e42b 100644
--- a/packages/SystemUI/src/com/android/systemui/LoadAverageService.java
+++ b/packages/SystemUI/src/com/android/systemui/LoadAverageService.java
@@ -16,8 +16,6 @@
 
 package com.android.systemui;
 
-import com.android.internal.os.ProcessStats;
-
 import android.app.Service;
 import android.content.Context;
 import android.content.Intent;
@@ -31,20 +29,22 @@
 import android.view.View;
 import android.view.WindowManager;
 
+import com.android.internal.os.ProcessCpuTracker;
+
 public class LoadAverageService extends Service {
     private View mView;
-    
-    private static final class Stats extends ProcessStats {
+
+    private static final class CpuTracker extends ProcessCpuTracker {
         String mLoadText;
         int mLoadWidth;
-        
+
         private final Paint mPaint;
-        
-        Stats(Paint paint) {
+
+        CpuTracker(Paint paint) {
             super(false);
             mPaint = paint;
         }
-        
+
         @Override
         public void onLoadChanged(float load1, float load5, float load15) {
             mLoadText = load1 + " / " + load5 + " / " + load15;
@@ -56,7 +56,7 @@
             return (int)mPaint.measureText(name);
         }
     }
-    
+
     private class LoadView extends View {
         private Handler mHandler = new Handler() {
             @Override
@@ -70,8 +70,8 @@
             }
         };
 
-        private final Stats mStats;
-        
+        private final CpuTracker mStats;
+
         private Paint mLoadPaint;
         private Paint mAddedPaint;
         private Paint mRemovedPaint;
@@ -150,7 +150,7 @@
             float descent = mLoadPaint.descent();
             mFH = (int)(descent - mAscent + .5f);
 
-            mStats = new Stats(mLoadPaint);
+            mStats = new CpuTracker(mLoadPaint);
             mStats.init();
             updateDisplay();
         }
@@ -179,14 +179,14 @@
             final int W = mNeededWidth;
             final int RIGHT = getWidth()-1;
 
-            final Stats stats = mStats;
+            final CpuTracker stats = mStats;
             final int userTime = stats.getLastUserTime();
             final int systemTime = stats.getLastSystemTime();
             final int iowaitTime = stats.getLastIoWaitTime();
             final int irqTime = stats.getLastIrqTime();
             final int softIrqTime = stats.getLastSoftIrqTime();
             final int idleTime = stats.getLastIdleTime();
-            
+
             final int totalTime = userTime+systemTime+iowaitTime+irqTime+softIrqTime+idleTime;
             if (totalTime == 0) {
                 return;
@@ -226,7 +226,7 @@
 
             int N = stats.countWorkingStats();
             for (int i=0; i<N; i++) {
-                Stats.Stats st = stats.getWorkingStats(i);
+                CpuTracker.Stats st = stats.getWorkingStats(i);
                 y += mFH;
                 top += mFH;
                 bottom += mFH;
@@ -259,17 +259,17 @@
         }
 
         void updateDisplay() {
-            final Stats stats = mStats;
+            final CpuTracker stats = mStats;
             final int NW = stats.countWorkingStats();
 
             int maxWidth = stats.mLoadWidth;
             for (int i=0; i<NW; i++) {
-                Stats.Stats st = stats.getWorkingStats(i);
+                CpuTracker.Stats st = stats.getWorkingStats(i);
                 if (st.nameWidth > maxWidth) {
                     maxWidth = st.nameWidth;
                 }
             }
-            
+
             int neededWidth = mPaddingLeft + mPaddingRight + maxWidth;
             int neededHeight = mPaddingTop + mPaddingBottom + (mFH*(1+NW));
             if (neededWidth != mNeededWidth || neededHeight != mNeededHeight) {
diff --git a/packages/SystemUI/src/com/android/systemui/RecentsComponent.java b/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
new file mode 100644
index 0000000..323905f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
@@ -0,0 +1,30 @@
+/*
+ * 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.systemui;
+
+import android.view.Display;
+import android.view.View;
+
+public interface RecentsComponent {
+    void toggleRecents(Display display, int layoutDirection, View statusBarView);
+
+    void preloadRecentTasksList();
+
+    void cancelPreloadingRecentTasksList();
+
+    void closeRecents();
+}
diff --git a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
index 1f29990..c32f741 100644
--- a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
@@ -32,7 +32,7 @@
 import android.provider.Settings;
 import android.util.AttributeSet;
 import android.util.EventLog;
-import android.util.Slog;
+import android.util.Log;
 import android.view.IWindowManager;
 import android.view.MotionEvent;
 import android.view.View;
@@ -43,27 +43,21 @@
 
 import com.android.internal.widget.multiwaveview.GlowPadView;
 import com.android.internal.widget.multiwaveview.GlowPadView.OnTriggerListener;
-
-import com.android.systemui.EventLogTags;
-import com.android.systemui.R;
-import com.android.systemui.recent.StatusBarTouchProxy;
 import com.android.systemui.statusbar.BaseStatusBar;
 import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.StatusBarPanel;
 import com.android.systemui.statusbar.phone.PhoneStatusBar;
-import com.android.systemui.statusbar.tablet.StatusBarPanel;
-import com.android.systemui.statusbar.tablet.TabletStatusBar;
 
 public class SearchPanelView extends FrameLayout implements
         StatusBarPanel, ActivityOptions.OnAnimationStartedListener {
     private static final int SEARCH_PANEL_HOLD_DURATION = 0;
     static final String TAG = "SearchPanelView";
-    static final boolean DEBUG = TabletStatusBar.DEBUG || PhoneStatusBar.DEBUG || false;
+    static final boolean DEBUG = PhoneStatusBar.DEBUG || false;
     public static final boolean DEBUG_GESTURES = true;
     private static final String ASSIST_ICON_METADATA_NAME =
             "com.android.systemui.action_assist_icon";
     private final Context mContext;
     private BaseStatusBar mBar;
-    private StatusBarTouchProxy mStatusBarTouchProxy;
 
     private boolean mShowing;
     private View mSearchTargetsContainer;
@@ -120,7 +114,7 @@
                 mContext.startActivityAsUser(intent, opts.toBundle(),
                         new UserHandle(UserHandle.USER_CURRENT));
             } catch (ActivityNotFoundException e) {
-                Slog.w(TAG, "Activity not found for " + intent.getAction());
+                Log.w(TAG, "Activity not found for " + intent.getAction());
                 onAnimationStarted();
             }
         }
@@ -172,7 +166,6 @@
         super.onFinishInflate();
         mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         mSearchTargetsContainer = findViewById(R.id.search_panel_container);
-        mStatusBarTouchProxy = (StatusBarTouchProxy) findViewById(R.id.status_bar_touch_proxy);
         // TODO: fetch views
         mGlowPadView = (GlowPadView) findViewById(R.id.glow_pad_view);
         mGlowPadView.setOnTriggerListener(mGlowPadViewListener);
@@ -186,7 +179,7 @@
             if (component == null || !mGlowPadView.replaceTargetDrawablesIfPresent(component,
                     ASSIST_ICON_METADATA_NAME,
                     com.android.internal.R.drawable.ic_action_assist_generic)) {
-                if (DEBUG) Slog.v(TAG, "Couldn't grab icon for component " + component);
+                if (DEBUG) Log.v(TAG, "Couldn't grab icon for component " + component);
             }
         }
     }
@@ -200,14 +193,7 @@
     }
 
     public boolean isInContentArea(int x, int y) {
-        if (pointInside(x, y, mSearchTargetsContainer)) {
-            return true;
-        } else if (mStatusBarTouchProxy != null &&
-                pointInside(x, y, mStatusBarTouchProxy)) {
-            return true;
-        } else {
-            return false;
-        }
+        return pointInside(x, y, mSearchTargetsContainer);
     }
 
     private final OnPreDrawListener mPreDrawListener = new ViewTreeObserver.OnPreDrawListener() {
@@ -297,17 +283,6 @@
         mBar = bar;
     }
 
-    public void setStatusBarView(final View statusBarView) {
-        if (mStatusBarTouchProxy != null) {
-            mStatusBarTouchProxy.setStatusBar(statusBarView);
-//            mGlowPadView.setOnTouchListener(new OnTouchListener() {
-//                public boolean onTouch(View v, MotionEvent event) {
-//                    return statusBarView.onTouchEvent(event);
-//                }
-//            });
-        }
-    }
-
     @Override
     public boolean onTouchEvent(MotionEvent event) {
         if (DEBUG_GESTURES) {
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index f824a8e..d38d828 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -19,18 +19,17 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
-import android.animation.Animator.AnimatorListener;
 import android.animation.ValueAnimator;
 import android.animation.ValueAnimator.AnimatorUpdateListener;
 import android.graphics.RectF;
 import android.os.Handler;
 import android.util.Log;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.animation.LinearInterpolator;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 import android.view.View;
 import android.view.ViewConfiguration;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.animation.LinearInterpolator;
 
 public class SwipeHelper implements Gefingerpoken {
     static final String TAG = "com.android.systemui.SwipeHelper";
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUI.java b/packages/SystemUI/src/com/android/systemui/SystemUI.java
index 2110483c..cb624ad 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUI.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUI.java
@@ -16,20 +16,33 @@
 
 package com.android.systemui;
 
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
 import android.content.Context;
 import android.content.res.Configuration;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.Map;
+
 public abstract class SystemUI {
     public Context mContext;
+    public Map<Class<?>, Object> mComponents;
 
     public abstract void start();
-    
+
     protected void onConfigurationChanged(Configuration newConfig) {
     }
 
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
     }
+
+    @SuppressWarnings("unchecked")
+    public <T> T getComponent(Class<T> interfaceType) {
+        return (T) (mComponents != null ? mComponents.get(interfaceType) : null);
+    }
+
+    public <T, C extends T> void putComponent(Class<T> interfaceType, C component) {
+        if (mComponents != null) {
+            mComponents.put(interfaceType, component);
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIService.java b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
index 1f3e942..ca5f7d1 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIService.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
@@ -16,32 +16,26 @@
 
 package com.android.systemui;
 
+import android.app.Service;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.os.IBinder;
+import android.util.Log;
+
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-
-import android.app.Service;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.res.Configuration;
-import android.os.Binder;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.util.Slog;
-import android.view.IWindowManager;
-import android.view.WindowManagerGlobal;
-import android.view.accessibility.AccessibilityManager;
+import java.util.HashMap;
 
 public class SystemUIService extends Service {
-    static final String TAG = "SystemUIService";
+    private static final String TAG = "SystemUIService";
 
     /**
-     * The class names of the stuff to start.
+     * The classes of the stuff to start.
      */
-    final Object[] SERVICES = new Object[] {
-            0, // system bar or status bar, filled in below.
+    private final Class<?>[] SERVICES = new Class[] {
+            com.android.systemui.recent.Recents.class,
+            com.android.systemui.statusbar.SystemBars.class,
+            com.android.systemui.usb.StorageNotification.class,
             com.android.systemui.power.PowerUI.class,
             com.android.systemui.media.RingtonePlayer.class,
             com.android.systemui.settings.SettingsUI.class,
@@ -50,44 +44,15 @@
     /**
      * Hold a reference on the stuff we start.
      */
-    SystemUI[] mServices;
-
-    private Class chooseClass(Object o) {
-        if (o instanceof Integer) {
-            final String cl = getString((Integer)o);
-            try {
-                return getClassLoader().loadClass(cl);
-            } catch (ClassNotFoundException ex) {
-                throw new RuntimeException(ex);
-            }
-        } else if (o instanceof Class) {
-            return (Class)o;
-        } else {
-            throw new RuntimeException("Unknown system ui service: " + o);
-        }
-    }
+    private final SystemUI[] mServices = new SystemUI[SERVICES.length];
 
     @Override
     public void onCreate() {
-        // Tell the accessibility layer that this process will
-        // run as the current user, i.e. run across users.
-        AccessibilityManager.createAsSharedAcrossUsers(this);
-
-        // Pick status bar or system bar.
-        IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
-        try {
-            SERVICES[0] = wm.hasSystemNavBar()
-                    ? R.string.config_systemBarComponent
-                    : R.string.config_statusBarComponent;
-        } catch (RemoteException e) {
-            Slog.w(TAG, "Failing checking whether status bar can hide", e);
-        }
-
+        HashMap<Class<?>, Object> components = new HashMap<Class<?>, Object>();
         final int N = SERVICES.length;
-        mServices = new SystemUI[N];
         for (int i=0; i<N; i++) {
-            Class cl = chooseClass(SERVICES[i]);
-            Slog.d(TAG, "loading: " + cl);
+            Class<?> cl = SERVICES[i];
+            Log.d(TAG, "loading: " + cl);
             try {
                 mServices[i] = (SystemUI)cl.newInstance();
             } catch (IllegalAccessException ex) {
@@ -96,7 +61,8 @@
                 throw new RuntimeException(ex);
             }
             mServices[i].mContext = this;
-            Slog.d(TAG, "running: " + mServices[i]);
+            mServices[i].mComponents = components;
+            Log.d(TAG, "running: " + mServices[i]);
             mServices[i].start();
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/UniverseBackground.java b/packages/SystemUI/src/com/android/systemui/UniverseBackground.java
deleted file mode 100644
index f859880..0000000
--- a/packages/SystemUI/src/com/android/systemui/UniverseBackground.java
+++ /dev/null
@@ -1,458 +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.systemui;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.graphics.Matrix;
-import android.graphics.PixelFormat;
-import android.os.RemoteException;
-import android.util.Log;
-import android.util.Slog;
-import android.view.Choreographer;
-import android.view.Display;
-import android.view.IWindowSession;
-import android.view.MotionEvent;
-import android.view.VelocityTracker;
-import android.view.View;
-import android.view.ViewRootImpl;
-import android.view.WindowManager;
-import android.view.WindowManagerGlobal;
-import android.view.animation.Transformation;
-import android.widget.FrameLayout;
-
-public class UniverseBackground extends FrameLayout {
-    static final String TAG = "UniverseBackground";
-    static final boolean SPEW = false;
-    static final boolean CHATTY = false;
-
-    final IWindowSession mSession;
-    final View mContent;
-    final View mBottomAnchor;
-
-    final Runnable mAnimationCallback = new Runnable() {
-        @Override
-        public void run() {
-            doAnimation(mChoreographer.getFrameTimeNanos());
-        }
-    };
-
-    // fling gesture tuning parameters, scaled to display density
-    private float mSelfExpandVelocityPx; // classic value: 2000px/s
-    private float mSelfCollapseVelocityPx; // classic value: 2000px/s (will be negated to collapse "up")
-    private float mFlingExpandMinVelocityPx; // classic value: 200px/s
-    private float mFlingCollapseMinVelocityPx; // classic value: 200px/s
-    private float mCollapseMinDisplayFraction; // classic value: 0.08 (25px/min(320px,480px) on G1)
-    private float mExpandMinDisplayFraction; // classic value: 0.5 (drag open halfway to expand)
-    private float mFlingGestureMaxXVelocityPx; // classic value: 150px/s
-
-    private float mExpandAccelPx; // classic value: 2000px/s/s
-    private float mCollapseAccelPx; // classic value: 2000px/s/s (will be negated to collapse "up")
-
-    static final int STATE_CLOSED = 0;
-    static final int STATE_OPENING = 1;
-    static final int STATE_OPEN = 2;
-    private int mState = STATE_CLOSED;
-
-    private float mDragStartX, mDragStartY;
-    private float mAverageX, mAverageY;
-
-    // position
-    private int[] mPositionTmp = new int[2];
-    private boolean mExpanded;
-    private boolean mExpandedVisible;
-
-    private boolean mTracking;
-    private VelocityTracker mVelocityTracker;
-
-    private Choreographer mChoreographer;
-    private boolean mAnimating;
-    private boolean mClosing; // only valid when mAnimating; indicates the initial acceleration
-    private float mAnimY;
-    private float mAnimVel;
-    private float mAnimAccel;
-    private long mAnimLastTimeNanos;
-    private boolean mAnimatingReveal = false;
-
-    private int mYDelta = 0;
-    private Transformation mUniverseTransform = new Transformation();
-    private final float[] mTmpFloats = new float[9];
-
-    public UniverseBackground(Context context) {
-        super(context);
-        setBackgroundColor(0xff000000);
-        mSession = WindowManagerGlobal.getWindowSession();
-        mContent = View.inflate(context, R.layout.universe, null);
-        addView(mContent);
-        mContent.findViewById(R.id.close).setOnClickListener(new View.OnClickListener() {
-            @Override public void onClick(View v) {
-                animateCollapse();
-            }
-        });
-        mBottomAnchor = mContent.findViewById(R.id.bottom);
-        mChoreographer = Choreographer.getInstance();
-        loadDimens();
-    }
-
-    @Override
-    protected void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        loadDimens();
-    }
-
-    private void loadDimens() {
-        final Resources res = getContext().getResources();
-        mSelfExpandVelocityPx = res.getDimension(R.dimen.self_expand_velocity);
-        mSelfCollapseVelocityPx = res.getDimension(R.dimen.self_collapse_velocity);
-        mFlingExpandMinVelocityPx = res.getDimension(R.dimen.fling_expand_min_velocity);
-        mFlingCollapseMinVelocityPx = res.getDimension(R.dimen.fling_collapse_min_velocity);
-
-        mCollapseMinDisplayFraction = res.getFraction(R.dimen.collapse_min_display_fraction, 1, 1);
-        mExpandMinDisplayFraction = res.getFraction(R.dimen.expand_min_display_fraction, 1, 1);
-
-        mExpandAccelPx = res.getDimension(R.dimen.expand_accel);
-        mCollapseAccelPx = res.getDimension(R.dimen.collapse_accel);
-
-        mFlingGestureMaxXVelocityPx = res.getDimension(R.dimen.fling_gesture_max_x_velocity);
-    }
-
-    private void computeAveragePos(MotionEvent event) {
-        final int num = event.getPointerCount();
-        float x = 0, y = 0;
-        for (int i=0; i<num; i++) {
-            x += event.getX(i);
-            y += event.getY(i);
-        }
-        mAverageX = x / num;
-        mAverageY = y / num;
-    }
-
-    private void sendUniverseTransform() {
-        if (getWindowToken() != null) {
-            mUniverseTransform.getMatrix().getValues(mTmpFloats);
-            try {
-                mSession.setUniverseTransform(getWindowToken(), mUniverseTransform.getAlpha(),
-                        mTmpFloats[Matrix.MTRANS_X], mTmpFloats[Matrix.MTRANS_Y],
-                        mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y],
-                        mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]);
-            } catch (RemoteException e) {
-            }
-        }
-    }
-
-    public WindowManager.LayoutParams getLayoutParams() {
-        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
-                LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
-                WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND,
-                    0
-                    | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
-                PixelFormat.OPAQUE);
-        // this will allow the window to run in an overlay on devices that support this
-        if (ActivityManager.isHighEndGfx()) {
-            lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
-        }
-        lp.setTitle("UniverseBackground");
-        lp.windowAnimations = 0;
-        return lp;
-    }
-
-    private int getExpandedViewMaxHeight() {
-        return mBottomAnchor.getTop();
-    }
-
-    public void animateCollapse() {
-        animateCollapse(1.0f);
-    }
-
-    public void animateCollapse(float velocityMultiplier) {
-        if (SPEW) {
-            Slog.d(TAG, "animateCollapse(): mExpanded=" + mExpanded
-                    + " mExpandedVisible=" + mExpandedVisible
-                    + " mExpanded=" + mExpanded
-                    + " mAnimating=" + mAnimating
-                    + " mAnimY=" + mAnimY
-                    + " mAnimVel=" + mAnimVel);
-        }
-
-        mState = STATE_CLOSED;
-        if (!mExpandedVisible) {
-            return;
-        }
-
-        int y;
-        if (mAnimating) {
-            y = (int)mAnimY;
-        } else {
-            y = getExpandedViewMaxHeight()-1;
-        }
-        // Let the fling think that we're open so it goes in the right direction
-        // and doesn't try to re-open the windowshade.
-        mExpanded = true;
-        prepareTracking(y, false);
-        performFling(y, -mSelfCollapseVelocityPx*velocityMultiplier, true);
-    }
-
-    private void updateUniverseScale() {
-        if (mYDelta > 0) {
-            int w = getWidth();
-            int h = getHeight();
-            float scale = (h-mYDelta+.5f) / (float)h;
-            mUniverseTransform.getMatrix().setScale(scale, scale, w/2, h);
-            if (CHATTY) Log.i(TAG, "w=" + w + " h=" + h + " scale=" + scale
-                    + ": " + mUniverseTransform);
-            sendUniverseTransform();
-            if (getVisibility() != VISIBLE) {
-                setVisibility(VISIBLE);
-            }
-        } else {
-            if (CHATTY) Log.i(TAG, "mYDelta=" + mYDelta);
-            mUniverseTransform.clear();
-            sendUniverseTransform();
-            if (getVisibility() == VISIBLE) {
-                setVisibility(GONE);
-            }
-        }
-    }
-
-    void resetLastAnimTime() {
-        mAnimLastTimeNanos = System.nanoTime();
-        if (SPEW) {
-            Throwable t = new Throwable();
-            t.fillInStackTrace();
-            Slog.d(TAG, "resetting last anim time=" + mAnimLastTimeNanos, t);
-        }
-    }
-
-    void doAnimation(long frameTimeNanos) {
-        if (mAnimating) {
-            if (SPEW) Slog.d(TAG, "doAnimation dt=" + (frameTimeNanos - mAnimLastTimeNanos));
-            if (SPEW) Slog.d(TAG, "doAnimation before mAnimY=" + mAnimY);
-            incrementAnim(frameTimeNanos);
-            if (SPEW) {
-                Slog.d(TAG, "doAnimation after  mAnimY=" + mAnimY);
-            }
-
-            if (mAnimY >= getExpandedViewMaxHeight()-1 && !mClosing) {
-                if (SPEW) Slog.d(TAG, "Animation completed to expanded state.");
-                mAnimating = false;
-                mYDelta = getExpandedViewMaxHeight();
-                updateUniverseScale();
-                mExpanded = true;
-                mState = STATE_OPEN;
-                return;
-            }
-
-            if (mAnimY <= 0 && mClosing) {
-                if (SPEW) Slog.d(TAG, "Animation completed to collapsed state.");
-                mAnimating = false;
-                mYDelta = 0;
-                updateUniverseScale();
-                mExpanded = false;
-                mState = STATE_CLOSED;
-                return;
-            }
-
-            mYDelta = (int)mAnimY;
-            updateUniverseScale();
-            mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION,
-                    mAnimationCallback, null);
-        }
-    }
-
-    void stopTracking() {
-        mTracking = false;
-        mVelocityTracker.recycle();
-        mVelocityTracker = null;
-    }
-
-    void incrementAnim(long frameTimeNanos) {
-        final long deltaNanos = Math.max(frameTimeNanos - mAnimLastTimeNanos, 0);
-        final float t = deltaNanos * 0.000000001f;                  // ns -> s
-        final float y = mAnimY;
-        final float v = mAnimVel;                                   // px/s
-        final float a = mAnimAccel;                                 // px/s/s
-        mAnimY = y + (v*t) + (0.5f*a*t*t);                          // px
-        mAnimVel = v + (a*t);                                       // px/s
-        mAnimLastTimeNanos = frameTimeNanos;                        // ns
-        //Slog.d(TAG, "y=" + y + " v=" + v + " a=" + a + " t=" + t + " mAnimY=" + mAnimY
-        //        + " mAnimAccel=" + mAnimAccel);
-    }
-
-    void prepareTracking(int y, boolean opening) {
-        if (CHATTY) {
-            Slog.d(TAG, "panel: beginning to track the user's touch, y=" + y + " opening=" + opening);
-        }
-
-        mTracking = true;
-        mVelocityTracker = VelocityTracker.obtain();
-        if (opening) {
-            mAnimAccel = mExpandAccelPx;
-            mAnimVel = mFlingExpandMinVelocityPx;
-            mAnimY = y;
-            mAnimating = true;
-            mAnimatingReveal = true;
-            resetLastAnimTime();
-            mExpandedVisible = true;
-        }
-        if (mAnimating) {
-            mAnimating = false;
-            mChoreographer.removeCallbacks(Choreographer.CALLBACK_ANIMATION,
-                    mAnimationCallback, null);
-        }
-    }
-
-    void performFling(int y, float vel, boolean always) {
-        if (CHATTY) {
-            Slog.d(TAG, "panel: will fling, y=" + y + " vel=" + vel);
-        }
-
-        mAnimatingReveal = false;
-
-        mAnimY = y;
-        mAnimVel = vel;
-
-        //Slog.d(TAG, "starting with mAnimY=" + mAnimY + " mAnimVel=" + mAnimVel);
-
-        if (mExpanded) {
-            if (!always && (
-                    vel > mFlingCollapseMinVelocityPx
-                    || (y > (getExpandedViewMaxHeight()*(1f-mCollapseMinDisplayFraction)) &&
-                        vel > -mFlingExpandMinVelocityPx))) {
-                // We are expanded, but they didn't move sufficiently to cause
-                // us to retract.  Animate back to the expanded position.
-                mAnimAccel = mExpandAccelPx;
-                if (vel < 0) {
-                    mAnimVel = 0;
-                }
-            }
-            else {
-                // We are expanded and are now going to animate away.
-                mAnimAccel = -mCollapseAccelPx;
-                if (vel > 0) {
-                    mAnimVel = 0;
-                }
-            }
-        } else {
-            if (always || (
-                    vel > mFlingExpandMinVelocityPx
-                    || (y > (getExpandedViewMaxHeight()*(1f-mExpandMinDisplayFraction)) &&
-                        vel > -mFlingCollapseMinVelocityPx))) {
-                // We are collapsed, and they moved enough to allow us to
-                // expand.  Animate in the notifications.
-                mAnimAccel = mExpandAccelPx;
-                if (vel < 0) {
-                    mAnimVel = 0;
-                }
-            }
-            else {
-                // We are collapsed, but they didn't move sufficiently to cause
-                // us to retract.  Animate back to the collapsed position.
-                mAnimAccel = -mCollapseAccelPx;
-                if (vel > 0) {
-                    mAnimVel = 0;
-                }
-            }
-        }
-        //Slog.d(TAG, "mAnimY=" + mAnimY + " mAnimVel=" + mAnimVel
-        //        + " mAnimAccel=" + mAnimAccel);
-
-        resetLastAnimTime();
-        mAnimating = true;
-        mClosing = mAnimAccel < 0;
-        mChoreographer.removeCallbacks(Choreographer.CALLBACK_ANIMATION,
-                mAnimationCallback, null);
-        mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION,
-                mAnimationCallback, null);
-
-        stopTracking();
-    }
-
-    private void trackMovement(MotionEvent event) {
-        mVelocityTracker.addMovement(event);
-    }
-
-    public boolean consumeEvent(MotionEvent event) {
-        if (mState == STATE_CLOSED) {
-            if (event.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) {
-                // Second finger down, time to start opening!
-                computeAveragePos(event);
-                mDragStartX = mAverageX;
-                mDragStartY = mAverageY;
-                mYDelta = 0;
-                mUniverseTransform.clear();
-                sendUniverseTransform();
-                setVisibility(VISIBLE);
-                mState = STATE_OPENING;
-                prepareTracking((int)mDragStartY, true);
-                mVelocityTracker.clear();
-                trackMovement(event);
-                return true;
-            }
-            return false;
-        }
-
-        if (mState == STATE_OPENING) {
-            if (event.getActionMasked() == MotionEvent.ACTION_UP
-                    || event.getActionMasked() == MotionEvent.ACTION_CANCEL) {
-                mVelocityTracker.computeCurrentVelocity(1000);
-                computeAveragePos(event);
-
-                float yVel = mVelocityTracker.getYVelocity();
-                boolean negative = yVel < 0;
-
-                float xVel = mVelocityTracker.getXVelocity();
-                if (xVel < 0) {
-                    xVel = -xVel;
-                }
-                if (xVel > mFlingGestureMaxXVelocityPx) {
-                    xVel = mFlingGestureMaxXVelocityPx; // limit how much we care about the x axis
-                }
-
-                float vel = (float)Math.hypot(yVel, xVel);
-                if (negative) {
-                    vel = -vel;
-                }
-
-                if (CHATTY) {
-                    Slog.d(TAG, String.format("gesture: vraw=(%f,%f) vnorm=(%f,%f) vlinear=%f",
-                        mVelocityTracker.getXVelocity(),
-                        mVelocityTracker.getYVelocity(),
-                        xVel, yVel,
-                        vel));
-                }
-
-                performFling((int)mAverageY, vel, false);
-                mState = STATE_OPEN;
-                return true;
-            }
-
-            computeAveragePos(event);
-            mYDelta = (int)(mAverageY - mDragStartY);
-            if (mYDelta > getExpandedViewMaxHeight()) {
-                mYDelta = getExpandedViewMaxHeight();
-            }
-            updateUniverseScale();
-            return true;
-        }
-
-        return false;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java b/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java
index 8979fc2..f8b347c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java
+++ b/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java
@@ -26,7 +26,6 @@
 import android.os.SystemClock;
 import android.util.Log;
 
-import java.lang.Thread;
 import java.util.LinkedList;
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java b/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
index 0c6e59c..5b4bb2c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
+++ b/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
@@ -28,10 +28,9 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
-import android.util.Slog;
+import android.util.Log;
 
 import com.android.systemui.SystemUI;
-import com.google.android.collect.Maps;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -50,7 +49,7 @@
     private IAudioService mAudioService;
 
     private final NotificationPlayer mAsyncPlayer = new NotificationPlayer(TAG);
-    private final HashMap<IBinder, Client> mClients = Maps.newHashMap();
+    private final HashMap<IBinder, Client> mClients = new HashMap<IBinder, Client>();
 
     @Override
     public void start() {
@@ -61,7 +60,7 @@
         try {
             mAudioService.setRingtonePlayer(mCallback);
         } catch (RemoteException e) {
-            Slog.e(TAG, "Problem registering RingtonePlayer: " + e);
+            Log.e(TAG, "Problem registering RingtonePlayer: " + e);
         }
     }
 
@@ -82,7 +81,7 @@
 
         @Override
         public void binderDied() {
-            if (LOGD) Slog.d(TAG, "binderDied() token=" + mToken);
+            if (LOGD) Log.d(TAG, "binderDied() token=" + mToken);
             synchronized (mClients) {
                 mClients.remove(mToken);
             }
@@ -94,7 +93,7 @@
         @Override
         public void play(IBinder token, Uri uri, int streamType) throws RemoteException {
             if (LOGD) {
-                Slog.d(TAG, "play(token=" + token + ", uri=" + uri + ", uid="
+                Log.d(TAG, "play(token=" + token + ", uri=" + uri + ", uid="
                         + Binder.getCallingUid() + ")");
             }
             Client client;
@@ -112,7 +111,7 @@
 
         @Override
         public void stop(IBinder token) {
-            if (LOGD) Slog.d(TAG, "stop(token=" + token + ")");
+            if (LOGD) Log.d(TAG, "stop(token=" + token + ")");
             Client client;
             synchronized (mClients) {
                 client = mClients.remove(token);
@@ -125,7 +124,7 @@
 
         @Override
         public boolean isPlaying(IBinder token) {
-            if (LOGD) Slog.d(TAG, "isPlaying(token=" + token + ")");
+            if (LOGD) Log.d(TAG, "isPlaying(token=" + token + ")");
             Client client;
             synchronized (mClients) {
                 client = mClients.get(token);
@@ -139,7 +138,7 @@
 
         @Override
         public void playAsync(Uri uri, UserHandle user, boolean looping, int streamType) {
-            if (LOGD) Slog.d(TAG, "playAsync(uri=" + uri + ", user=" + user + ")");
+            if (LOGD) Log.d(TAG, "playAsync(uri=" + uri + ", user=" + user + ")");
             if (Binder.getCallingUid() != Process.SYSTEM_UID) {
                 throw new SecurityException("Async playback only available from system UID.");
             }
@@ -149,7 +148,7 @@
 
         @Override
         public void stopAsync() {
-            if (LOGD) Slog.d(TAG, "stopAsync()");
+            if (LOGD) Log.d(TAG, "stopAsync()");
             if (Binder.getCallingUid() != Process.SYSTEM_UID) {
                 throw new SecurityException("Async playback only available from system UID.");
             }
diff --git a/packages/SystemUI/src/com/android/systemui/net/NetworkOverLimitActivity.java b/packages/SystemUI/src/com/android/systemui/net/NetworkOverLimitActivity.java
index 888b76e..1ac8295 100644
--- a/packages/SystemUI/src/com/android/systemui/net/NetworkOverLimitActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/net/NetworkOverLimitActivity.java
@@ -32,7 +32,7 @@
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.util.Slog;
+import android.util.Log;
 import android.view.WindowManager;
 
 import com.android.systemui.R;
@@ -79,7 +79,7 @@
         try {
             policyService.snoozeLimit(template);
         } catch (RemoteException e) {
-            Slog.w(TAG, "problem snoozing network policy", e);
+            Log.w(TAG, "problem snoozing network policy", e);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index ccb711a..a08eb9b 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -16,10 +16,6 @@
 
 package com.android.systemui.power;
 
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.Arrays;
-
 import android.app.AlertDialog;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
@@ -27,15 +23,15 @@
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.media.AudioManager;
+import android.media.Ringtone;
+import android.media.RingtoneManager;
 import android.net.Uri;
 import android.os.BatteryManager;
 import android.os.Handler;
 import android.os.UserHandle;
-import android.media.AudioManager;
-import android.media.Ringtone;
-import android.media.RingtoneManager;
 import android.provider.Settings;
-import android.util.Slog;
+import android.util.Log;
 import android.view.View;
 import android.view.WindowManager;
 import android.widget.TextView;
@@ -43,6 +39,10 @@
 import com.android.systemui.R;
 import com.android.systemui.SystemUI;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.Arrays;
+
 public class PowerUI extends SystemUI {
     static final String TAG = "PowerUI";
 
@@ -126,19 +126,19 @@
                 int bucket = findBatteryLevelBucket(mBatteryLevel);
 
                 if (DEBUG) {
-                    Slog.d(TAG, "buckets   ....." + mLowBatteryAlertCloseLevel
+                    Log.d(TAG, "buckets   ....." + mLowBatteryAlertCloseLevel
                             + " .. " + mLowBatteryReminderLevels[0]
                             + " .. " + mLowBatteryReminderLevels[1]);
-                    Slog.d(TAG, "level          " + oldBatteryLevel + " --> " + mBatteryLevel);
-                    Slog.d(TAG, "status         " + oldBatteryStatus + " --> " + mBatteryStatus);
-                    Slog.d(TAG, "plugType       " + oldPlugType + " --> " + mPlugType);
-                    Slog.d(TAG, "invalidCharger " + oldInvalidCharger + " --> " + mInvalidCharger);
-                    Slog.d(TAG, "bucket         " + oldBucket + " --> " + bucket);
-                    Slog.d(TAG, "plugged        " + oldPlugged + " --> " + plugged);
+                    Log.d(TAG, "level          " + oldBatteryLevel + " --> " + mBatteryLevel);
+                    Log.d(TAG, "status         " + oldBatteryStatus + " --> " + mBatteryStatus);
+                    Log.d(TAG, "plugType       " + oldPlugType + " --> " + mPlugType);
+                    Log.d(TAG, "invalidCharger " + oldInvalidCharger + " --> " + mInvalidCharger);
+                    Log.d(TAG, "bucket         " + oldBucket + " --> " + bucket);
+                    Log.d(TAG, "plugged        " + oldPlugged + " --> " + plugged);
                 }
 
                 if (oldInvalidCharger == 0 && mInvalidCharger != 0) {
-                    Slog.d(TAG, "showing invalid charger warning");
+                    Log.d(TAG, "showing invalid charger warning");
                     showInvalidChargerDialog();
                     return;
                 } else if (oldInvalidCharger != 0 && mInvalidCharger == 0) {
@@ -164,20 +164,20 @@
                     showLowBatteryWarning();
                 }
             } else {
-                Slog.w(TAG, "unknown intent: " + intent);
+                Log.w(TAG, "unknown intent: " + intent);
             }
         }
     };
 
     void dismissLowBatteryWarning() {
         if (mLowBatteryDialog != null) {
-            Slog.i(TAG, "closing low battery warning: level=" + mBatteryLevel);
+            Log.i(TAG, "closing low battery warning: level=" + mBatteryLevel);
             mLowBatteryDialog.dismiss();
         }
     }
 
     void showLowBatteryWarning() {
-        Slog.i(TAG,
+        Log.i(TAG,
                 ((mBatteryLevelTextView == null) ? "showing" : "updating")
                 + " low battery warning: level=" + mBatteryLevel
                 + " [" + findBatteryLevelBucket(mBatteryLevel) + "]");
@@ -234,7 +234,7 @@
 
     void playLowBatterySound() {
         if (DEBUG) {
-            Slog.i(TAG, "playing low battery sound. WOMP-WOMP!");
+            Log.i(TAG, "playing low battery sound. WOMP-WOMP!");
         }
 
         final ContentResolver cr = mContext.getContentResolver();
@@ -261,7 +261,7 @@
     }
 
     void showInvalidChargerDialog() {
-        Slog.d(TAG, "showing invalid charger dialog");
+        Log.d(TAG, "showing invalid charger dialog");
 
         dismissLowBatteryWarning();
 
@@ -283,7 +283,7 @@
         d.show();
         mInvalidChargerDialog = d;
     }
-    
+
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.print("mLowBatteryAlertCloseLevel=");
         pw.println(mLowBatteryAlertCloseLevel);
diff --git a/packages/SystemUI/src/com/android/systemui/recent/FirstFrameAnimatorHelper.java b/packages/SystemUI/src/com/android/systemui/recent/FirstFrameAnimatorHelper.java
index 2fc7dfc..84d13cf 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/FirstFrameAnimatorHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/FirstFrameAnimatorHelper.java
@@ -19,18 +19,18 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
-import android.animation.Animator.AnimatorListener;
 import android.util.Log;
-import android.view.ViewTreeObserver;
 import android.view.View;
 import android.view.ViewPropertyAnimator;
+import android.view.ViewTreeObserver;
 
 /*
  *  This is a helper class that listens to updates from the corresponding animation.
  *  For the first two frames, it adjusts the current play time of the animation to
  *  prevent jank at the beginning of the animation
  */
-public class FirstFrameAnimatorHelper implements ValueAnimator.AnimatorUpdateListener {
+public class FirstFrameAnimatorHelper extends AnimatorListenerAdapter
+    implements ValueAnimator.AnimatorUpdateListener {
     private static final boolean DEBUG = false;
     private static final int MAX_DELAY = 1000;
     private static final int IDEAL_FRAME_DURATION = 16;
@@ -50,13 +50,14 @@
 
     public FirstFrameAnimatorHelper(ViewPropertyAnimator vpa, View target) {
         mTarget = target;
-        vpa.setListener(new AnimatorListenerAdapter() {
-                public void onAnimationStart (Animator animation) {
-                    final ValueAnimator va = (ValueAnimator) animation;
-                    va.addUpdateListener(FirstFrameAnimatorHelper.this);
-                    onAnimationUpdate(va);
-                }
-            });
+        vpa.setListener(this);
+    }
+
+    // only used for ViewPropertyAnimators
+    public void onAnimationStart(Animator animation) {
+        final ValueAnimator va = (ValueAnimator) animation;
+        va.addUpdateListener(FirstFrameAnimatorHelper.this);
+        onAnimationUpdate(va);
     }
 
     public static void initializeDrawListener(View view) {
@@ -84,7 +85,11 @@
             mStartTime = currentTime;
         }
 
-        if (!mHandlingOnAnimationUpdate) {
+        if (!mHandlingOnAnimationUpdate &&
+            // If the current play time exceeds the duration, the animation
+            // will get finished, even if we call setCurrentPlayTime -- therefore
+            // don't adjust the animation in that case
+            animation.getCurrentPlayTime() < animation.getDuration()) {
             mHandlingOnAnimationUpdate = true;
             long frameNum = sGlobalFrameCounter - mStartFrame;
             // If we haven't drawn our first frame, reset the time to t = 0
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java b/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java
index 02ddb73..8b2cd3f 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java
@@ -37,7 +37,6 @@
 
 import com.android.systemui.R;
 import com.android.systemui.statusbar.phone.PhoneStatusBar;
-import com.android.systemui.statusbar.tablet.TabletStatusBar;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -46,7 +45,7 @@
 
 public class RecentTasksLoader implements View.OnTouchListener {
     static final String TAG = "RecentTasksLoader";
-    static final boolean DEBUG = TabletStatusBar.DEBUG || PhoneStatusBar.DEBUG || false;
+    static final boolean DEBUG = PhoneStatusBar.DEBUG || false;
 
     private static final int DISPLAY_TASKS = 20;
     private static final int MAX_TASKS = DISPLAY_TASKS + 1; // allow extra for non-apps
diff --git a/packages/SystemUI/src/com/android/systemui/recent/Recents.java b/packages/SystemUI/src/com/android/systemui/recent/Recents.java
new file mode 100644
index 0000000..f51e34b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recent/Recents.java
@@ -0,0 +1,212 @@
+/*
+ * 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.systemui.recent;
+
+import android.app.ActivityOptions;
+import android.content.ActivityNotFoundException;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Paint;
+import android.os.UserHandle;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.Display;
+import android.view.View;
+
+import com.android.systemui.R;
+import com.android.systemui.RecentsComponent;
+import com.android.systemui.SystemUI;
+
+public class Recents extends SystemUI implements RecentsComponent {
+    private static final String TAG = "Recents";
+    private static final boolean DEBUG = false;
+
+    @Override
+    public void start() {
+        putComponent(RecentsComponent.class, this);
+    }
+
+    @Override
+    public void toggleRecents(Display display, int layoutDirection, View statusBarView) {
+        if (DEBUG) Log.d(TAG, "toggle recents panel");
+        try {
+            TaskDescription firstTask = RecentTasksLoader.getInstance(mContext).getFirstTask();
+
+            Intent intent = new Intent(RecentsActivity.TOGGLE_RECENTS_INTENT);
+            intent.setClassName("com.android.systemui",
+                    "com.android.systemui.recent.RecentsActivity");
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+
+            if (firstTask == null) {
+                if (RecentsActivity.forceOpaqueBackground(mContext)) {
+                    ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext,
+                            R.anim.recents_launch_from_launcher_enter,
+                            R.anim.recents_launch_from_launcher_exit);
+                    mContext.startActivityAsUser(intent, opts.toBundle(), new UserHandle(
+                            UserHandle.USER_CURRENT));
+                } else {
+                    // The correct window animation will be applied via the activity's style
+                    mContext.startActivityAsUser(intent, new UserHandle(
+                            UserHandle.USER_CURRENT));
+                }
+
+            } else {
+                Bitmap first = firstTask.getThumbnail();
+                final Resources res = mContext.getResources();
+
+                float thumbWidth = res
+                        .getDimensionPixelSize(R.dimen.status_bar_recents_thumbnail_width);
+                float thumbHeight = res
+                        .getDimensionPixelSize(R.dimen.status_bar_recents_thumbnail_height);
+                if (first == null) {
+                    throw new RuntimeException("Recents thumbnail is null");
+                }
+                if (first.getWidth() != thumbWidth || first.getHeight() != thumbHeight) {
+                    first = Bitmap.createScaledBitmap(first, (int) thumbWidth, (int) thumbHeight,
+                            true);
+                    if (first == null) {
+                        throw new RuntimeException("Recents thumbnail is null");
+                    }
+                }
+
+
+                DisplayMetrics dm = new DisplayMetrics();
+                display.getMetrics(dm);
+                // calculate it here, but consider moving it elsewhere
+                // first, determine which orientation you're in.
+                final Configuration config = res.getConfiguration();
+                int x, y;
+
+                if (config.orientation == Configuration.ORIENTATION_PORTRAIT) {
+                    float appLabelLeftMargin = res.getDimensionPixelSize(
+                            R.dimen.status_bar_recents_app_label_left_margin);
+                    float appLabelWidth = res.getDimensionPixelSize(
+                            R.dimen.status_bar_recents_app_label_width);
+                    float thumbLeftMargin = res.getDimensionPixelSize(
+                            R.dimen.status_bar_recents_thumbnail_left_margin);
+                    float thumbBgPadding = res.getDimensionPixelSize(
+                            R.dimen.status_bar_recents_thumbnail_bg_padding);
+
+                    float width = appLabelLeftMargin +
+                            +appLabelWidth
+                            + thumbLeftMargin
+                            + thumbWidth
+                            + 2 * thumbBgPadding;
+
+                    x = (int) ((dm.widthPixels - width) / 2f + appLabelLeftMargin + appLabelWidth
+                            + thumbBgPadding + thumbLeftMargin);
+                    y = (int) (dm.heightPixels
+                            - res.getDimensionPixelSize(R.dimen.status_bar_recents_thumbnail_height)
+                            - thumbBgPadding);
+                    if (layoutDirection == View.LAYOUT_DIRECTION_RTL) {
+                        x = dm.widthPixels - x - res.getDimensionPixelSize(
+                                R.dimen.status_bar_recents_thumbnail_width);
+                    }
+
+                } else { // if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
+                    float thumbTopMargin = res.getDimensionPixelSize(
+                            R.dimen.status_bar_recents_thumbnail_top_margin);
+                    float thumbBgPadding = res.getDimensionPixelSize(
+                            R.dimen.status_bar_recents_thumbnail_bg_padding);
+                    float textPadding = res.getDimensionPixelSize(
+                            R.dimen.status_bar_recents_text_description_padding);
+                    float labelTextSize = res.getDimensionPixelSize(
+                            R.dimen.status_bar_recents_app_label_text_size);
+                    Paint p = new Paint();
+                    p.setTextSize(labelTextSize);
+                    float labelTextHeight = p.getFontMetricsInt().bottom
+                            - p.getFontMetricsInt().top;
+                    float descriptionTextSize = res.getDimensionPixelSize(
+                            R.dimen.status_bar_recents_app_description_text_size);
+                    p.setTextSize(descriptionTextSize);
+                    float descriptionTextHeight = p.getFontMetricsInt().bottom
+                            - p.getFontMetricsInt().top;
+
+                    float statusBarHeight = res.getDimensionPixelSize(
+                            com.android.internal.R.dimen.status_bar_height);
+                    float recentsItemTopPadding = statusBarHeight;
+
+                    float height = thumbTopMargin
+                            + thumbHeight
+                            + 2 * thumbBgPadding + textPadding + labelTextHeight
+                            + recentsItemTopPadding + textPadding + descriptionTextHeight;
+                    float recentsItemRightPadding = res
+                            .getDimensionPixelSize(R.dimen.status_bar_recents_item_padding);
+                    float recentsScrollViewRightPadding = res
+                            .getDimensionPixelSize(R.dimen.status_bar_recents_right_glow_margin);
+                    x = (int) (dm.widthPixels - res
+                            .getDimensionPixelSize(R.dimen.status_bar_recents_thumbnail_width)
+                            - thumbBgPadding - recentsItemRightPadding
+                            - recentsScrollViewRightPadding);
+                    y = (int) ((dm.heightPixels - statusBarHeight - height) / 2f + thumbTopMargin
+                            + recentsItemTopPadding + thumbBgPadding + statusBarHeight);
+                }
+
+                ActivityOptions opts = ActivityOptions.makeThumbnailScaleDownAnimation(
+                        statusBarView,
+                        first, x, y,
+                        new ActivityOptions.OnAnimationStartedListener() {
+                            public void onAnimationStarted() {
+                                Intent intent =
+                                        new Intent(RecentsActivity.WINDOW_ANIMATION_START_INTENT);
+                                intent.setPackage("com.android.systemui");
+                                mContext.sendBroadcastAsUser(intent,
+                                        new UserHandle(UserHandle.USER_CURRENT));
+                            }
+                        });
+                intent.putExtra(RecentsActivity.WAITING_FOR_WINDOW_ANIMATION_PARAM, true);
+                mContext.startActivityAsUser(intent, opts.toBundle(), new UserHandle(
+                        UserHandle.USER_CURRENT));
+            }
+        } catch (ActivityNotFoundException e) {
+            Log.e(TAG, "Failed to launch RecentAppsIntent", e);
+        }
+    }
+
+    @Override
+    public void preloadRecentTasksList() {
+        if (DEBUG) Log.d(TAG, "preloading recents");
+        Intent intent = new Intent(RecentsActivity.PRELOAD_INTENT);
+        intent.setClassName("com.android.systemui",
+                "com.android.systemui.recent.RecentsPreloadReceiver");
+        mContext.sendBroadcastAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
+
+        RecentTasksLoader.getInstance(mContext).preloadFirstTask();
+    }
+
+    @Override
+    public void cancelPreloadingRecentTasksList() {
+        if (DEBUG) Log.d(TAG, "cancel preloading recents");
+        Intent intent = new Intent(RecentsActivity.CANCEL_PRELOAD_INTENT);
+        intent.setClassName("com.android.systemui",
+                "com.android.systemui.recent.RecentsPreloadReceiver");
+        mContext.sendBroadcastAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
+
+        RecentTasksLoader.getInstance(mContext).cancelPreloadingFirstTask();
+    }
+
+    @Override
+    public void closeRecents() {
+        if (DEBUG) Log.d(TAG, "closing recents panel");
+        Intent intent = new Intent(RecentsActivity.CLOSE_RECENTS_INTENT);
+        intent.setPackage("com.android.systemui");
+        mContext.sendBroadcastAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsActivity.java
index 62030ad..818c2980 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsActivity.java
@@ -30,7 +30,7 @@
 import android.view.WindowManager;
 
 import com.android.systemui.R;
-import com.android.systemui.statusbar.tablet.StatusBarPanel;
+import com.android.systemui.statusbar.StatusBarPanel;
 
 import java.util.List;
 
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index c64b954..ada30ac 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -61,21 +61,19 @@
 
 import com.android.systemui.R;
 import com.android.systemui.statusbar.BaseStatusBar;
+import com.android.systemui.statusbar.StatusBarPanel;
 import com.android.systemui.statusbar.phone.PhoneStatusBar;
-import com.android.systemui.statusbar.tablet.StatusBarPanel;
-import com.android.systemui.statusbar.tablet.TabletStatusBar;
 
 import java.util.ArrayList;
 
 public class RecentsPanelView extends FrameLayout implements OnItemClickListener, RecentsCallback,
         StatusBarPanel, Animator.AnimatorListener {
     static final String TAG = "RecentsPanelView";
-    static final boolean DEBUG = TabletStatusBar.DEBUG || PhoneStatusBar.DEBUG || false;
+    static final boolean DEBUG = PhoneStatusBar.DEBUG || false;
     private PopupMenu mPopup;
     private View mRecentsScrim;
     private View mRecentsNoApps;
     private ViewGroup mRecentsContainer;
-    private StatusBarTouchProxy mStatusBarTouchProxy;
 
     private boolean mShowing;
     private boolean mWaitingToShow;
@@ -289,14 +287,7 @@
     }
 
     public boolean isInContentArea(int x, int y) {
-        if (pointInside(x, y, mRecentsContainer)) {
-            return true;
-        } else if (mStatusBarTouchProxy != null &&
-                pointInside(x, y, mStatusBarTouchProxy)) {
-            return true;
-        } else {
-            return false;
-        }
+        return pointInside(x, y, mRecentsContainer);
     }
 
     public void show(boolean show) {
@@ -430,12 +421,6 @@
         return mShowing;
     }
 
-    public void setStatusBarView(View statusBarView) {
-        if (mStatusBarTouchProxy != null) {
-            mStatusBarTouchProxy.setStatusBar(statusBarView);
-        }
-    }
-
     public void setRecentTasksLoader(RecentTasksLoader loader) {
         mRecentTasksLoader = loader;
     }
@@ -451,7 +436,6 @@
         super.onFinishInflate();
 
         mRecentsContainer = (ViewGroup) findViewById(R.id.recents_container);
-        mStatusBarTouchProxy = (StatusBarTouchProxy) findViewById(R.id.status_bar_touch_proxy);
         mListAdapter = new TaskDescriptionAdapter(mContext);
         if (mRecentsContainer instanceof RecentsScrollView){
             RecentsScrollView scrollView
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
index 403c643f..ee076d9 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
@@ -21,7 +21,6 @@
 import android.content.res.Configuration;
 import android.database.DataSetObserver;
 import android.graphics.Canvas;
-import android.graphics.Paint;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.util.FloatMath;
diff --git a/packages/SystemUI/src/com/android/systemui/recent/StatusBarTouchProxy.java b/packages/SystemUI/src/com/android/systemui/recent/StatusBarTouchProxy.java
deleted file mode 100644
index ded114f..0000000
--- a/packages/SystemUI/src/com/android/systemui/recent/StatusBarTouchProxy.java
+++ /dev/null
@@ -1,40 +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.systemui.recent;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.widget.FrameLayout;
-
-public class StatusBarTouchProxy extends FrameLayout {
-
-    private View mStatusBar;
-
-    public StatusBarTouchProxy(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public void setStatusBar(View statusBar) {
-        mStatusBar = statusBar;
-    }
-
-    public boolean onTouchEvent (MotionEvent event) {
-        return mStatusBar.dispatchTouchEvent(event);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 5041617..2063563 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -45,7 +45,6 @@
 import android.os.Process;
 import android.provider.MediaStore;
 import android.util.DisplayMetrics;
-import android.util.Log;
 import android.view.Display;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
@@ -197,6 +196,10 @@
             // Create screenshot directory if it doesn't exist
             mScreenshotDir.mkdirs();
 
+            // media provider uses seconds for DATE_MODIFIED and DATE_ADDED, but milliseconds
+            // for DATE_TAKEN
+            long dateSeconds = mImageTime / 1000;
+
             // Save the screenshot to the MediaStore
             ContentValues values = new ContentValues();
             ContentResolver resolver = context.getContentResolver();
@@ -204,8 +207,8 @@
             values.put(MediaStore.Images.ImageColumns.TITLE, mImageFileName);
             values.put(MediaStore.Images.ImageColumns.DISPLAY_NAME, mImageFileName);
             values.put(MediaStore.Images.ImageColumns.DATE_TAKEN, mImageTime);
-            values.put(MediaStore.Images.ImageColumns.DATE_ADDED, mImageTime);
-            values.put(MediaStore.Images.ImageColumns.DATE_MODIFIED, mImageTime);
+            values.put(MediaStore.Images.ImageColumns.DATE_ADDED, dateSeconds);
+            values.put(MediaStore.Images.ImageColumns.DATE_MODIFIED, dateSeconds);
             values.put(MediaStore.Images.ImageColumns.MIME_TYPE, "image/png");
             values.put(MediaStore.Images.ImageColumns.WIDTH, mImageWidth);
             values.put(MediaStore.Images.ImageColumns.HEIGHT, mImageHeight);
@@ -220,12 +223,12 @@
             sharingIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
 
             Intent chooserIntent = Intent.createChooser(sharingIntent, null);
-            chooserIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK 
+            chooserIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK
                     | Intent.FLAG_ACTIVITY_NEW_TASK);
 
             mNotificationBuilder.addAction(R.drawable.ic_menu_share,
                      r.getString(com.android.internal.R.string.share),
-                     PendingIntent.getActivity(context, 0, chooserIntent, 
+                     PendingIntent.getActivity(context, 0, chooserIntent,
                              PendingIntent.FLAG_CANCEL_CURRENT));
 
             OutputStream out = resolver.openOutputStream(uri);
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
index 6a0fe47..456b5fa 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
@@ -23,7 +23,6 @@
 import android.os.Message;
 import android.os.Messenger;
 import android.os.RemoteException;
-import android.util.Log;
 
 public class TakeScreenshotService extends Service {
     private static final String TAG = "TakeScreenshotService";
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
index fdeead1..327e715 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
@@ -18,7 +18,6 @@
 
 import android.content.ContentResolver;
 import android.content.Context;
-import android.content.Intent;
 import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.AsyncTask;
@@ -30,9 +29,6 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
-import android.util.Slog;
-import android.view.IWindowManager;
-import android.widget.CompoundButton;
 import android.widget.ImageView;
 
 import java.util.ArrayList;
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
index 1b05084..ff79f04 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
@@ -16,19 +16,16 @@
 
 package com.android.systemui.settings;
 
-import com.android.systemui.R;
-
 import android.app.Dialog;
 import android.content.Context;
 import android.content.res.Resources;
 import android.os.Bundle;
 import android.os.Handler;
-import android.util.Log;
 import android.view.Window;
 import android.view.WindowManager;
 import android.widget.ImageView;
 
-import java.lang.Runnable;
+import com.android.systemui.R;
 
 /** A dialog that provides controls for adjusting the screen brightness. */
 public class BrightnessDialog extends Dialog implements
diff --git a/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java
index 122f81e..036bd4f 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserTracker.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.os.UserHandle;
 
 public abstract class CurrentUserTracker extends BroadcastReceiver {
 
@@ -54,4 +55,8 @@
     }
 
     public abstract void onUserSwitched(int newUserId);
+
+    public boolean isCurrentUserOwner() {
+        return mCurrentUserId == UserHandle.USER_OWNER;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/settings/SettingsUI.java b/packages/SystemUI/src/com/android/systemui/settings/SettingsUI.java
index 1075a73..8bc72c9 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/SettingsUI.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/SettingsUI.java
@@ -16,9 +16,6 @@
 
 package com.android.systemui.settings;
 
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.DialogInterface;
@@ -26,10 +23,13 @@
 import android.content.IntentFilter;
 import android.os.Handler;
 import android.os.UserHandle;
-import android.util.Slog;
+import android.util.Log;
 
 import com.android.systemui.SystemUI;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
 public class SettingsUI extends SystemUI {
     private static final String TAG = "SettingsUI";
     private static final boolean DEBUG = false;
@@ -42,7 +42,7 @@
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
             if (action.equals(Intent.ACTION_SHOW_BRIGHTNESS_DIALOG)) {
-                if (DEBUG) Slog.d(TAG, "showing brightness dialog");
+                if (DEBUG) Log.d(TAG, "showing brightness dialog");
 
                 if (mBrightnessDialog == null) {
                     mBrightnessDialog = new BrightnessDialog(mContext);
@@ -59,7 +59,7 @@
                 }
 
             } else {
-                Slog.w(TAG, "unknown intent: " + intent);
+                Log.w(TAG, "unknown intent: " + intent);
             }
         }
     };
diff --git a/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java b/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java
index c7c361c..d584043 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java
@@ -21,10 +21,8 @@
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
-import android.util.Slog;
 import android.view.View;
 import android.widget.CompoundButton;
-import android.widget.ProgressBar;
 import android.widget.RelativeLayout;
 import android.widget.SeekBar;
 import android.widget.TextView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java b/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java
index 78226c5..9839fe9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java
@@ -20,7 +20,6 @@
 import android.graphics.drawable.AnimationDrawable;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
-import android.util.Slog;
 import android.view.View;
 import android.widget.ImageView;
 import android.widget.RemoteViews.RemoteView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 683824b..54c9f5d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (C) 2010 The Android Open Source Project
  *
@@ -17,52 +16,36 @@
 
 package com.android.systemui.statusbar;
 
-import android.service.notification.StatusBarNotification;
-import android.content.res.Configuration;
-import com.android.internal.statusbar.IStatusBarService;
-import com.android.internal.statusbar.StatusBarIcon;
-import com.android.internal.statusbar.StatusBarIconList;
-import com.android.internal.widget.SizeAdaptiveLayout;
-import com.android.systemui.R;
-import com.android.systemui.SearchPanelView;
-import com.android.systemui.SystemUI;
-import com.android.systemui.recent.RecentTasksLoader;
-import com.android.systemui.recent.RecentsActivity;
-import com.android.systemui.recent.TaskDescription;
-import com.android.systemui.statusbar.policy.NotificationRowLayout;
-import com.android.systemui.statusbar.tablet.StatusBarPanel;
-
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
-import android.app.ActivityOptions;
 import android.app.KeyguardManager;
+import android.app.Notification;
 import android.app.PendingIntent;
 import android.app.TaskStackBuilder;
-import android.content.ActivityNotFoundException;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources;
+import android.content.res.Configuration;
 import android.database.ContentObserver;
-import android.graphics.Bitmap;
-import android.graphics.Paint;
 import android.graphics.Rect;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
+import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.provider.Settings;
+import android.service.dreams.DreamService;
+import android.service.dreams.IDreamManager;
+import android.service.notification.StatusBarNotification;
 import android.text.TextUtils;
-import android.util.DisplayMetrics;
 import android.util.Log;
-import android.util.Slog;
 import android.view.Display;
 import android.view.IWindowManager;
 import android.view.LayoutInflater;
@@ -79,6 +62,16 @@
 import android.widget.RemoteViews;
 import android.widget.TextView;
 
+import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.statusbar.StatusBarIcon;
+import com.android.internal.statusbar.StatusBarIconList;
+import com.android.internal.widget.SizeAdaptiveLayout;
+import com.android.systemui.R;
+import com.android.systemui.RecentsComponent;
+import com.android.systemui.SearchPanelView;
+import com.android.systemui.SystemUI;
+import com.android.systemui.statusbar.policy.NotificationRowLayout;
+
 import java.util.ArrayList;
 import java.util.Locale;
 
@@ -94,16 +87,20 @@
     protected static final int MSG_CANCEL_PRELOAD_RECENT_APPS = 1023;
     protected static final int MSG_OPEN_SEARCH_PANEL = 1024;
     protected static final int MSG_CLOSE_SEARCH_PANEL = 1025;
-    protected static final int MSG_SHOW_INTRUDER = 1026;
-    protected static final int MSG_HIDE_INTRUDER = 1027;
+    protected static final int MSG_SHOW_HEADS_UP = 1026;
+    protected static final int MSG_HIDE_HEADS_UP = 1027;
+    protected static final int MSG_ESCALATE_HEADS_UP = 1028;
 
-    protected static final boolean ENABLE_INTRUDERS = false;
+    protected static final boolean ENABLE_HEADS_UP = true;
+    // scores above this threshold should be displayed in heads up mode.
+    private static final int INTERRUPTION_THRESHOLD = 11;
 
     // Should match the value in PhoneWindowManager
     public static final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
 
     public static final int EXPANDED_LEAVE_ALONE = -10000;
     public static final int EXPANDED_FULL_OPEN = -10001;
+    private static final String SETTING_HEADS_UP = "heads_up_enabled";
 
     protected CommandQueue mCommandQueue;
     protected IStatusBarService mBarService;
@@ -113,7 +110,8 @@
     protected NotificationData mNotificationData = new NotificationData();
     protected NotificationRowLayout mPile;
 
-    protected StatusBarNotification mCurrentlyIntrudingNotification;
+    protected NotificationData.Entry mInterruptingNotificationEntry;
+    protected long mInterruptingNotificationTime;
 
     // used to notify status bar for suppressing notification LED
     protected boolean mPanelSlightlyVisible;
@@ -127,6 +125,12 @@
 
     protected int mLayoutDirection;
     private Locale mLocale;
+    protected boolean mUseHeadsUp = true;
+
+    protected IDreamManager mDreamManager;
+    KeyguardManager mKeyguardManager;
+    PowerManager mPowerManager;
+    protected int mRowHeight;
 
     // UI-specific methods
 
@@ -144,6 +148,8 @@
 
     private boolean mDeviceProvisioned = false;
 
+    private RecentsComponent mRecents;
+
     public IStatusBarService getStatusBarService() {
         return mBarService;
     }
@@ -164,11 +170,24 @@
         }
     };
 
+    final private ContentObserver mHeadsUpObserver = new ContentObserver(mHandler) {
+        @Override
+        public void onChange(boolean selfChange) {
+            mUseHeadsUp = ENABLE_HEADS_UP && 0 != Settings.Global.getInt(
+                    mContext.getContentResolver(), SETTING_HEADS_UP, 0);
+            Log.d(TAG, "heads up is " + (mUseHeadsUp ? "enabled" : "disabled"));
+            if (!mUseHeadsUp) {
+                Log.d(TAG, "dismissing any existing heads up notification on disable event");
+                mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
+            }
+        }
+    };
+
     private RemoteViews.OnClickHandler mOnClickHandler = new RemoteViews.OnClickHandler() {
         @Override
         public boolean onClickHandler(View view, PendingIntent pendingIntent, Intent fillInIntent) {
             if (DEBUG) {
-                Slog.v(TAG, "Notification click handler invoked for intent: " + pendingIntent);
+                Log.v(TAG, "Notification click handler invoked for intent: " + pendingIntent);
             }
             final boolean isActivity = pendingIntent.isActivity();
             if (isActivity) {
@@ -196,19 +215,43 @@
         }
     };
 
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (Intent.ACTION_USER_SWITCHED.equals(action)) {
+                mCurrentUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
+                if (true) Log.v(TAG, "userId " + mCurrentUserId + " is in the house");
+                userSwitched(mCurrentUserId);
+            }
+        }
+    };
+
     public void start() {
         mWindowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
         mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
         mDisplay = mWindowManager.getDefaultDisplay();
 
+        mDreamManager = IDreamManager.Stub.asInterface(
+                ServiceManager.checkService(DreamService.DREAM_SERVICE));
+        mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
+        mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+
         mProvisioningObserver.onChange(false); // set up
         mContext.getContentResolver().registerContentObserver(
                 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED), true,
                 mProvisioningObserver);
 
+        mHeadsUpObserver.onChange(false); // set up
+        mContext.getContentResolver().registerContentObserver(
+                Settings.Global.getUriFor(SETTING_HEADS_UP), true,
+                mHeadsUpObserver);
+
         mBarService = IStatusBarService.Stub.asInterface(
                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
 
+        mRecents = getComponent(RecentsComponent.class);
+
         mLocale = mContext.getResources().getConfiguration().locale;
         mLayoutDirection = TextUtils.getLayoutDirectionFromLocale(mLocale);
 
@@ -259,7 +302,7 @@
         }
 
         if (DEBUG) {
-            Slog.d(TAG, String.format(
+            Log.d(TAG, String.format(
                     "init: icons=%d disabled=0x%08x lights=0x%08x menu=0x%08x imeButton=0x%08x",
                    iconList.size(),
                    switches[0],
@@ -273,16 +316,7 @@
 
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_USER_SWITCHED);
-        mContext.registerReceiver(new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                String action = intent.getAction();
-                if (Intent.ACTION_USER_SWITCHED.equals(action)) {
-                    mCurrentUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
-                    if (true) Slog.v(TAG, "userId " + mCurrentUserId + " is in the house");
-                    userSwitched(mCurrentUserId);
-                }
-            }}, filter);
+        mContext.registerReceiver(mBroadcastReceiver, filter);
 
         mLocale = mContext.getResources().getConfiguration().locale;
     }
@@ -295,7 +329,7 @@
         final int thisUserId = mCurrentUserId;
         final int notificationUserId = n.getUserId();
         if (DEBUG && MULTIUSER_DEBUG) {
-            Slog.v(TAG, String.format("%s: current userid: %d, notification userid: %d",
+            Log.v(TAG, String.format("%s: current userid: %d, notification userid: %d",
                     n, thisUserId, notificationUserId));
         }
         return notificationUserId == UserHandle.USER_ALL
@@ -314,7 +348,8 @@
 
     protected View updateNotificationVetoButton(View row, StatusBarNotification n) {
         View vetoButton = row.findViewById(R.id.veto);
-        if (n.isClearable()) {
+        if (n.isClearable() || (mInterruptingNotificationEntry != null
+                && mInterruptingNotificationEntry.row == row)) {
             final String _pkg = n.getPackageName();
             final String _tag = n.getTag();
             final int _id = n.getId();
@@ -348,7 +383,7 @@
                 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(sbn.getPackageName(), 0);
                 version = info.targetSdkVersion;
             } catch (NameNotFoundException ex) {
-                Slog.e(TAG, "Failed looking up ApplicationInfo for " + sbn.getPackageName(), ex);
+                Log.e(TAG, "Failed looking up ApplicationInfo for " + sbn.getPackageName(), ex);
             }
             if (version > 0 && version < Build.VERSION_CODES.GINGERBREAD) {
                 content.setBackgroundResource(R.drawable.notification_row_legacy_bg);
@@ -402,8 +437,7 @@
         }
     }
 
-    public void dismissIntruder() {
-        // pass
+    public void onHeadsUpDismissed() {
     }
 
     @Override
@@ -441,9 +475,6 @@
         mHandler.sendEmptyMessage(msg);
     }
 
-    protected abstract WindowManager.LayoutParams getRecentsLayoutParams(
-            LayoutParams layoutParams);
-
     protected abstract WindowManager.LayoutParams getSearchLayoutParams(
             LayoutParams layoutParams);
 
@@ -487,141 +518,6 @@
 
     protected abstract View getStatusBarView();
 
-    protected void toggleRecentsActivity() {
-        try {
-
-            TaskDescription firstTask = RecentTasksLoader.getInstance(mContext).getFirstTask();
-
-            Intent intent = new Intent(RecentsActivity.TOGGLE_RECENTS_INTENT);
-            intent.setClassName("com.android.systemui",
-                    "com.android.systemui.recent.RecentsActivity");
-            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-
-            if (firstTask == null) {
-                if (RecentsActivity.forceOpaqueBackground(mContext)) {
-                    ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext,
-                            R.anim.recents_launch_from_launcher_enter,
-                            R.anim.recents_launch_from_launcher_exit);
-                    mContext.startActivityAsUser(intent, opts.toBundle(), new UserHandle(
-                            UserHandle.USER_CURRENT));
-                } else {
-                    // The correct window animation will be applied via the activity's style
-                    mContext.startActivityAsUser(intent, new UserHandle(
-                            UserHandle.USER_CURRENT));
-                }
-
-            } else {
-                Bitmap first = firstTask.getThumbnail();
-                final Resources res = mContext.getResources();
-
-                float thumbWidth = res
-                        .getDimensionPixelSize(R.dimen.status_bar_recents_thumbnail_width);
-                float thumbHeight = res
-                        .getDimensionPixelSize(R.dimen.status_bar_recents_thumbnail_height);
-                if (first == null) {
-                    throw new RuntimeException("Recents thumbnail is null");
-                }
-                if (first.getWidth() != thumbWidth || first.getHeight() != thumbHeight) {
-                    first = Bitmap.createScaledBitmap(first, (int) thumbWidth, (int) thumbHeight,
-                            true);
-                    if (first == null) {
-                        throw new RuntimeException("Recents thumbnail is null");
-                    }
-                }
-
-
-                DisplayMetrics dm = new DisplayMetrics();
-                mDisplay.getMetrics(dm);
-                // calculate it here, but consider moving it elsewhere
-                // first, determine which orientation you're in.
-                // todo: move the system_bar layouts to sw600dp ?
-                final Configuration config = res.getConfiguration();
-                int x, y;
-
-                if (config.orientation == Configuration.ORIENTATION_PORTRAIT) {
-                    float appLabelLeftMargin = res
-                            .getDimensionPixelSize(R.dimen.status_bar_recents_app_label_left_margin);
-                    float appLabelWidth = res
-                            .getDimensionPixelSize(R.dimen.status_bar_recents_app_label_width);
-                    float thumbLeftMargin = res
-                            .getDimensionPixelSize(R.dimen.status_bar_recents_thumbnail_left_margin);
-                    float thumbBgPadding = res
-                            .getDimensionPixelSize(R.dimen.status_bar_recents_thumbnail_bg_padding);
-
-                    float width = appLabelLeftMargin +
-                            +appLabelWidth
-                            + thumbLeftMargin
-                            + thumbWidth
-                            + 2 * thumbBgPadding;
-
-                    x = (int) ((dm.widthPixels - width) / 2f + appLabelLeftMargin + appLabelWidth
-                            + thumbBgPadding + thumbLeftMargin);
-                    y = (int) (dm.heightPixels
-                            - res.getDimensionPixelSize(R.dimen.status_bar_recents_thumbnail_height) - thumbBgPadding);
-                    if (mLayoutDirection == View.LAYOUT_DIRECTION_RTL) {
-                        x = dm.widthPixels - x - res
-                                .getDimensionPixelSize(R.dimen.status_bar_recents_thumbnail_width);
-                    }
-
-                } else { // if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
-                    float thumbTopMargin = res
-                            .getDimensionPixelSize(R.dimen.status_bar_recents_thumbnail_top_margin);
-                    float thumbBgPadding = res
-                            .getDimensionPixelSize(R.dimen.status_bar_recents_thumbnail_bg_padding);
-                    float textPadding = res
-                            .getDimensionPixelSize(R.dimen.status_bar_recents_text_description_padding);
-                    float labelTextSize = res
-                            .getDimensionPixelSize(R.dimen.status_bar_recents_app_label_text_size);
-                    Paint p = new Paint();
-                    p.setTextSize(labelTextSize);
-                    float labelTextHeight = p.getFontMetricsInt().bottom
-                            - p.getFontMetricsInt().top;
-                    float descriptionTextSize = res
-                            .getDimensionPixelSize(R.dimen.status_bar_recents_app_description_text_size);
-                    p.setTextSize(descriptionTextSize);
-                    float descriptionTextHeight = p.getFontMetricsInt().bottom
-                            - p.getFontMetricsInt().top;
-
-                    float statusBarHeight = res
-                            .getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
-                    float recentsItemTopPadding = statusBarHeight;
-
-                    float height = thumbTopMargin
-                            + thumbHeight
-                            + 2 * thumbBgPadding + textPadding + labelTextHeight
-                            + recentsItemTopPadding + textPadding + descriptionTextHeight;
-                    float recentsItemRightPadding = res
-                            .getDimensionPixelSize(R.dimen.status_bar_recents_item_padding);
-                    float recentsScrollViewRightPadding = res
-                            .getDimensionPixelSize(R.dimen.status_bar_recents_right_glow_margin);
-                    x = (int) (dm.widthPixels - res
-                            .getDimensionPixelSize(R.dimen.status_bar_recents_thumbnail_width)
-                            - thumbBgPadding - recentsItemRightPadding - recentsScrollViewRightPadding);
-                    y = (int) ((dm.heightPixels - statusBarHeight - height) / 2f + thumbTopMargin
-                            + recentsItemTopPadding + thumbBgPadding + statusBarHeight);
-                }
-
-                ActivityOptions opts = ActivityOptions.makeThumbnailScaleDownAnimation(
-                        getStatusBarView(),
-                        first, x, y,
-                        new ActivityOptions.OnAnimationStartedListener() {
-                            public void onAnimationStarted() {
-                                Intent intent = new Intent(RecentsActivity.WINDOW_ANIMATION_START_INTENT);
-                                intent.setPackage("com.android.systemui");
-                                mContext.sendBroadcastAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
-                            }
-                        });
-                intent.putExtra(RecentsActivity.WAITING_FOR_WINDOW_ANIMATION_PARAM, true);
-                mContext.startActivityAsUser(intent, opts.toBundle(), new UserHandle(
-                        UserHandle.USER_CURRENT));
-            }
-            return;
-        } catch (ActivityNotFoundException e) {
-            Log.e(TAG, "Failed to launch RecentAppsIntent", e);
-        }
-    }
-
     protected View.OnTouchListener mRecentsPreloadOnTouchListener = new View.OnTouchListener() {
         // additional optimization when we have software system buttons - start loading the recent
         // tasks on touch down
@@ -642,39 +538,41 @@
         }
     };
 
-    protected void preloadRecentTasksList() {
-        if (DEBUG) Slog.d(TAG, "preloading recents");
-        Intent intent = new Intent(RecentsActivity.PRELOAD_INTENT);
-        intent.setClassName("com.android.systemui",
-                "com.android.systemui.recent.RecentsPreloadReceiver");
-        mContext.sendBroadcastAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
+    protected void toggleRecentsActivity() {
+        if (mRecents != null) {
+            mRecents.toggleRecents(mDisplay, mLayoutDirection, getStatusBarView());
+        }
+    }
 
-        RecentTasksLoader.getInstance(mContext).preloadFirstTask();
+    protected void preloadRecentTasksList() {
+        if (mRecents != null) {
+            mRecents.preloadRecentTasksList();
+        }
     }
 
     protected void cancelPreloadingRecentTasksList() {
-        if (DEBUG) Slog.d(TAG, "cancel preloading recents");
-        Intent intent = new Intent(RecentsActivity.CANCEL_PRELOAD_INTENT);
-        intent.setClassName("com.android.systemui",
-                "com.android.systemui.recent.RecentsPreloadReceiver");
-        mContext.sendBroadcastAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
-
-        RecentTasksLoader.getInstance(mContext).cancelPreloadingFirstTask();
+        if (mRecents != null) {
+            mRecents.cancelPreloadingRecentTasksList();
+        }
     }
 
+    protected void closeRecents() {
+        if (mRecents != null) {
+            mRecents.closeRecents();
+        }
+    }
+
+    public abstract void resetHeadsUpDecayTimer();
+
     protected class H extends Handler {
         public void handleMessage(Message m) {
             Intent intent;
             switch (m.what) {
              case MSG_TOGGLE_RECENTS_PANEL:
-                 if (DEBUG) Slog.d(TAG, "toggle recents panel");
                  toggleRecentsActivity();
                  break;
              case MSG_CLOSE_RECENTS_PANEL:
-                 if (DEBUG) Slog.d(TAG, "closing recents panel");
-                 intent = new Intent(RecentsActivity.CLOSE_RECENTS_INTENT);
-                 intent.setPackage("com.android.systemui");
-                 mContext.sendBroadcastAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
+                 closeRecents();
                  break;
              case MSG_PRELOAD_RECENT_APPS:
                   preloadRecentTasksList();
@@ -683,13 +581,13 @@
                   cancelPreloadingRecentTasksList();
                   break;
              case MSG_OPEN_SEARCH_PANEL:
-                 if (DEBUG) Slog.d(TAG, "opening search panel");
+                 if (DEBUG) Log.d(TAG, "opening search panel");
                  if (mSearchPanelView != null && mSearchPanelView.isAssistantAvailable()) {
                      mSearchPanelView.show(true, true);
                  }
                  break;
              case MSG_CLOSE_SEARCH_PANEL:
-                 if (DEBUG) Slog.d(TAG, "closing search panel");
+                 if (DEBUG) Log.d(TAG, "closing search panel");
                  if (mSearchPanelView != null && mSearchPanelView.isShowing()) {
                      mSearchPanelView.show(false, true);
                  }
@@ -723,22 +621,23 @@
     protected void workAroundBadLayerDrawableOpacity(View v) {
     }
 
-    protected  boolean inflateViews(NotificationData.Entry entry, ViewGroup parent) {
+    public boolean inflateViews(NotificationData.Entry entry, ViewGroup parent) {
         int minHeight =
                 mContext.getResources().getDimensionPixelSize(R.dimen.notification_min_height);
         int maxHeight =
                 mContext.getResources().getDimensionPixelSize(R.dimen.notification_max_height);
         StatusBarNotification sbn = entry.notification;
-        RemoteViews oneU = sbn.getNotification().contentView;
-        RemoteViews large = sbn.getNotification().bigContentView;
-        if (oneU == null) {
+        RemoteViews contentView = sbn.getNotification().contentView;
+        RemoteViews bigContentView = sbn.getNotification().bigContentView;
+        if (contentView == null) {
             return false;
         }
 
         // create the row view
         LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(
                 Context.LAYOUT_INFLATER_SERVICE);
-        View row = inflater.inflate(R.layout.status_bar_notification_row, parent, false);
+        ExpandableNotificationRow row = (ExpandableNotificationRow) inflater.inflate(
+                R.layout.status_bar_notification_row, parent, false);
 
         // for blaming (see SwipeHelper.setLongPressListener)
         row.setTag(sbn.getPackageName());
@@ -765,41 +664,38 @@
             content.setOnClickListener(null);
         }
 
-        // TODO(cwren) normalize variable names with those in updateNotification
-        View expandedOneU = null;
-        View expandedLarge = null;
+        View contentViewLocal = null;
+        View bigContentViewLocal = null;
         try {
-            expandedOneU = oneU.apply(mContext, adaptive, mOnClickHandler);
-            if (large != null) {
-                expandedLarge = large.apply(mContext, adaptive, mOnClickHandler);
+            contentViewLocal = contentView.apply(mContext, adaptive, mOnClickHandler);
+            if (bigContentView != null) {
+                bigContentViewLocal = bigContentView.apply(mContext, adaptive, mOnClickHandler);
             }
         }
         catch (RuntimeException e) {
             final String ident = sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId());
-            Slog.e(TAG, "couldn't inflate view for notification " + ident, e);
+            Log.e(TAG, "couldn't inflate view for notification " + ident, e);
             return false;
         }
 
-        if (expandedOneU != null) {
+        if (contentViewLocal != null) {
             SizeAdaptiveLayout.LayoutParams params =
-                    new SizeAdaptiveLayout.LayoutParams(expandedOneU.getLayoutParams());
+                    new SizeAdaptiveLayout.LayoutParams(contentViewLocal.getLayoutParams());
             params.minHeight = minHeight;
             params.maxHeight = minHeight;
-            adaptive.addView(expandedOneU, params);
+            adaptive.addView(contentViewLocal, params);
         }
-        if (expandedLarge != null) {
+        if (bigContentViewLocal != null) {
             SizeAdaptiveLayout.LayoutParams params =
-                    new SizeAdaptiveLayout.LayoutParams(expandedLarge.getLayoutParams());
+                    new SizeAdaptiveLayout.LayoutParams(bigContentViewLocal.getLayoutParams());
             params.minHeight = minHeight+1;
             params.maxHeight = maxHeight;
-            adaptive.addView(expandedLarge, params);
+            adaptive.addView(bigContentViewLocal, params);
         }
         row.setDrawingCacheEnabled(true);
 
         applyLegacyRowBackground(sbn, content);
 
-        row.setTag(R.id.expandable_tag, Boolean.valueOf(large != null));
-
         if (MULTIUSER_DEBUG) {
             TextView debug = (TextView) row.findViewById(R.id.debug_info);
             if (debug != null) {
@@ -808,9 +704,10 @@
             }
         }
         entry.row = row;
+        entry.row.setRowHeight(mRowHeight);
         entry.content = content;
-        entry.expanded = expandedOneU;
-        entry.setLargeView(expandedLarge);
+        entry.expanded = contentViewLocal;
+        entry.setBigContentView(bigContentViewLocal);
 
         return true;
     }
@@ -819,13 +716,13 @@
         return new NotificationClicker(intent, pkg, tag, id);
     }
 
-    private class NotificationClicker implements View.OnClickListener {
+    protected class NotificationClicker implements View.OnClickListener {
         private PendingIntent mIntent;
         private String mPkg;
         private String mTag;
         private int mId;
 
-        NotificationClicker(PendingIntent intent, String pkg, String tag, int id) {
+        public NotificationClicker(PendingIntent intent, String pkg, String tag, int id) {
             mIntent = intent;
             mPkg = pkg;
             mTag = tag;
@@ -855,7 +752,7 @@
                     mIntent.send(mContext, 0, overlay);
                 } catch (PendingIntent.CanceledException e) {
                     // the stack trace isn't very helpful here.  Just log the exception message.
-                    Slog.w(TAG, "Sending contentIntent failed: " + e);
+                    Log.w(TAG, "Sending contentIntent failed: " + e);
                 }
 
                 KeyguardManager kgm =
@@ -872,9 +769,6 @@
             // close the shade if it was open
             animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
             visibilityChanged(false);
-
-            // If this click was on the intruder alert, hide that instead
-//            mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
         }
     }
     /**
@@ -913,7 +807,7 @@
     protected StatusBarNotification removeNotificationViews(IBinder key) {
         NotificationData.Entry entry = mNotificationData.remove(key);
         if (entry == null) {
-            Slog.w(TAG, "removeNotification for unknown key: " + key);
+            Log.w(TAG, "removeNotification for unknown key: " + key);
             return null;
         }
         // Remove the expanded view.
@@ -925,10 +819,10 @@
         return entry.notification;
     }
 
-    protected StatusBarIconView addNotificationViews(IBinder key,
+    protected NotificationData.Entry createNotificationViews(IBinder key,
             StatusBarNotification notification) {
         if (DEBUG) {
-            Slog.d(TAG, "addNotificationViews(key=" + key + ", notification=" + notification);
+            Log.d(TAG, "createNotificationViews(key=" + key + ", notification=" + notification);
         }
         // Construct the icon.
         final StatusBarIconView iconView = new StatusBarIconView(mContext,
@@ -953,51 +847,41 @@
                     + notification);
             return null;
         }
+        return entry;
+    }
 
+    protected void addNotificationViews(NotificationData.Entry entry) {
         // Add the expanded view and icon.
         int pos = mNotificationData.add(entry);
         if (DEBUG) {
-            Slog.d(TAG, "addNotificationViews: added at " + pos);
+            Log.d(TAG, "addNotificationViews: added at " + pos);
         }
         updateExpansionStates();
         updateNotificationIcons();
-
-        return iconView;
     }
 
-    protected boolean expandView(NotificationData.Entry entry, boolean expand) {
-        int rowHeight =
-                mContext.getResources().getDimensionPixelSize(R.dimen.notification_row_min_height);
-        ViewGroup.LayoutParams lp = entry.row.getLayoutParams();
-        if (entry.expandable() && expand) {
-            if (DEBUG) Slog.d(TAG, "setting expanded row height to WRAP_CONTENT");
-            lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
-        } else {
-            if (DEBUG) Slog.d(TAG, "setting collapsed row height to " + rowHeight);
-            lp.height = rowHeight;
-        }
-        entry.row.setLayoutParams(lp);
-        return expand;
+    private void addNotificationViews(IBinder key, StatusBarNotification notification) {
+        addNotificationViews(createNotificationViews(key, notification));
     }
 
     protected void updateExpansionStates() {
         int N = mNotificationData.size();
         for (int i = 0; i < N; i++) {
             NotificationData.Entry entry = mNotificationData.get(i);
-            if (!entry.userLocked()) {
+            if (!entry.row.isUserLocked()) {
                 if (i == (N-1)) {
-                    if (DEBUG) Slog.d(TAG, "expanding top notification at " + i);
-                    expandView(entry, true);
+                    if (DEBUG) Log.d(TAG, "expanding top notification at " + i);
+                    entry.row.setExpanded(true);
                 } else {
-                    if (!entry.userExpanded()) {
-                        if (DEBUG) Slog.d(TAG, "collapsing notification at " + i);
-                        expandView(entry, false);
+                    if (!entry.row.isUserExpanded()) {
+                        if (DEBUG) Log.d(TAG, "collapsing notification at " + i);
+                        entry.row.setExpanded(false);
                     } else {
-                        if (DEBUG) Slog.d(TAG, "ignoring user-modified notification at " + i);
+                        if (DEBUG) Log.d(TAG, "ignoring user-modified notification at " + i);
                     }
                 }
             } else {
-                if (DEBUG) Slog.d(TAG, "ignoring notification being held by user at " + i);
+                if (DEBUG) Log.d(TAG, "ignoring notification being held by user at " + i);
             }
         }
     }
@@ -1015,11 +899,11 @@
     }
 
     public void updateNotification(IBinder key, StatusBarNotification notification) {
-        if (DEBUG) Slog.d(TAG, "updateNotification(" + key + " -> " + notification + ")");
+        if (DEBUG) Log.d(TAG, "updateNotification(" + key + " -> " + notification + ")");
 
         final NotificationData.Entry oldEntry = mNotificationData.findByKey(key);
         if (oldEntry == null) {
-            Slog.w(TAG, "updateNotification for unknown key: " + key);
+            Log.w(TAG, "updateNotification for unknown key: " + key);
             return;
         }
 
@@ -1032,13 +916,13 @@
         final RemoteViews bigContentView = notification.getNotification().bigContentView;
 
         if (DEBUG) {
-            Slog.d(TAG, "old notification: when=" + oldNotification.getNotification().when
+            Log.d(TAG, "old notification: when=" + oldNotification.getNotification().when
                     + " ongoing=" + oldNotification.isOngoing()
                     + " expanded=" + oldEntry.expanded
                     + " contentView=" + oldContentView
                     + " bigContentView=" + oldBigContentView
                     + " rowParent=" + oldEntry.row.getParent());
-            Slog.d(TAG, "new notification: when=" + notification.getNotification().when
+            Log.d(TAG, "new notification: when=" + notification.getNotification().when
                     + " ongoing=" + oldNotification.isOngoing()
                     + " contentView=" + contentView
                     + " bigContentView=" + bigContentView);
@@ -1055,8 +939,8 @@
                 && oldContentView.getLayoutId() == contentView.getLayoutId();
         // large view may be null
         boolean bigContentsUnchanged =
-                (oldEntry.getLargeView() == null && bigContentView == null)
-                || ((oldEntry.getLargeView() != null && bigContentView != null)
+                (oldEntry.getBigContentView() == null && bigContentView == null)
+                || ((oldEntry.getBigContentView() != null && bigContentView != null)
                     && bigContentView.getPackage() != null
                     && oldBigContentView.getPackage() != null
                     && oldBigContentView.getPackage().equals(bigContentView.getPackage())
@@ -1071,23 +955,23 @@
                         oldEntry.notification.getNotification().tickerText);
         boolean isTopAnyway = isTopNotification(rowParent, oldEntry);
         if (contentsUnchanged && bigContentsUnchanged && (orderUnchanged || isTopAnyway)) {
-            if (DEBUG) Slog.d(TAG, "reusing notification for key: " + key);
+            if (DEBUG) Log.d(TAG, "reusing notification for key: " + key);
             oldEntry.notification = notification;
             try {
-                // Reapply the RemoteViews
-                contentView.reapply(mContext, oldEntry.expanded, mOnClickHandler);
-                if (bigContentView != null && oldEntry.getLargeView() != null) {
-                    bigContentView.reapply(mContext, oldEntry.getLargeView(), mOnClickHandler);
+                updateNotificationViews(oldEntry, notification);
+
+                if (ENABLE_HEADS_UP && mInterruptingNotificationEntry != null
+                        && oldNotification == mInterruptingNotificationEntry.notification) {
+                    if (!shouldInterrupt(notification)) {
+                        if (DEBUG) Log.d(TAG, "no longer interrupts!");
+                        mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
+                    } else {
+                        if (DEBUG) Log.d(TAG, "updating the current heads up:" + notification);
+                        mInterruptingNotificationEntry.notification = notification;
+                        updateNotificationViews(mInterruptingNotificationEntry, notification);
+                    }
                 }
-                // update the contentIntent
-                final PendingIntent contentIntent = notification.getNotification().contentIntent;
-                if (contentIntent != null) {
-                    final View.OnClickListener listener = makeClicker(contentIntent,
-                            notification.getPackageName(), notification.getTag(), notification.getId());
-                    oldEntry.content.setOnClickListener(listener);
-                } else {
-                    oldEntry.content.setOnClickListener(null);
-                }
+
                 // Update the icon.
                 final StatusBarIcon ic = new StatusBarIcon(notification.getPackageName(),
                         notification.getUser(),
@@ -1102,22 +986,22 @@
             }
             catch (RuntimeException e) {
                 // It failed to add cleanly.  Log, and remove the view from the panel.
-                Slog.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e);
+                Log.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e);
                 removeNotificationViews(key);
                 addNotificationViews(key, notification);
             }
         } else {
-            if (DEBUG) Slog.d(TAG, "not reusing notification for key: " + key);
-            if (DEBUG) Slog.d(TAG, "contents was " + (contentsUnchanged ? "unchanged" : "changed"));
-            if (DEBUG) Slog.d(TAG, "order was " + (orderUnchanged ? "unchanged" : "changed"));
-            if (DEBUG) Slog.d(TAG, "notification is " + (isTopAnyway ? "top" : "not top"));
-            final boolean wasExpanded = oldEntry.userExpanded();
+            if (DEBUG) Log.d(TAG, "not reusing notification for key: " + key);
+            if (DEBUG) Log.d(TAG, "contents was " + (contentsUnchanged ? "unchanged" : "changed"));
+            if (DEBUG) Log.d(TAG, "order was " + (orderUnchanged ? "unchanged" : "changed"));
+            if (DEBUG) Log.d(TAG, "notification is " + (isTopAnyway ? "top" : "not top"));
+            final boolean wasExpanded = oldEntry.row.isUserExpanded();
             removeNotificationViews(key);
-            addNotificationViews(key, notification);
+            addNotificationViews(key, notification);  // will also replace the heads up
             if (wasExpanded) {
                 final NotificationData.Entry newEntry = mNotificationData.findByKey(key);
-                expandView(newEntry, true);
-                newEntry.setUserExpanded(true);
+                newEntry.row.setExpanded(true);
+                newEntry.row.setUserExpanded(true);
             }
         }
 
@@ -1127,7 +1011,7 @@
 
         // Is this for you?
         boolean isForCurrentUser = notificationIsForCurrentUser(notification);
-        if (DEBUG) Slog.d(TAG, "notification is " + (isForCurrentUser ? "" : "not ") + "for you");
+        if (DEBUG) Log.d(TAG, "notification is " + (isForCurrentUser ? "" : "not ") + "for you");
 
         // Restart the ticker if it's still running
         if (updateTicker && isForCurrentUser) {
@@ -1138,17 +1022,57 @@
         // Recalculate the position of the sliding windows and the titles.
         setAreThereNotifications();
         updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
+    }
 
-        // See if we need to update the intruder.
-        if (ENABLE_INTRUDERS && oldNotification == mCurrentlyIntrudingNotification) {
-            if (DEBUG) Slog.d(TAG, "updating the current intruder:" + notification);
-            // XXX: this is a hack for Alarms. The real implementation will need to *update*
-            // the intruder.
-            if (notification.getNotification().fullScreenIntent == null) { // TODO(dsandler): consistent logic with add()
-                if (DEBUG) Slog.d(TAG, "no longer intrudes!");
-                mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
-            }
+    private void updateNotificationViews(NotificationData.Entry entry,
+            StatusBarNotification notification) {
+        final RemoteViews contentView = notification.getNotification().contentView;
+        final RemoteViews bigContentView = notification.getNotification().bigContentView;
+        // Reapply the RemoteViews
+        contentView.reapply(mContext, entry.expanded, mOnClickHandler);
+        if (bigContentView != null && entry.getBigContentView() != null) {
+            bigContentView.reapply(mContext, entry.getBigContentView(), mOnClickHandler);
         }
+        // update the contentIntent
+        final PendingIntent contentIntent = notification.getNotification().contentIntent;
+        if (contentIntent != null) {
+            final View.OnClickListener listener = makeClicker(contentIntent,
+                    notification.getPackageName(), notification.getTag(), notification.getId());
+            entry.content.setOnClickListener(listener);
+        } else {
+            entry.content.setOnClickListener(null);
+        }
+    }
+
+    protected void notifyHeadsUpScreenOn(boolean screenOn) {
+        if (!screenOn && mInterruptingNotificationEntry != null) {
+            mHandler.sendEmptyMessage(MSG_ESCALATE_HEADS_UP);
+        }
+    }
+
+    protected boolean shouldInterrupt(StatusBarNotification sbn) {
+        Notification notification = sbn.getNotification();
+        // some predicates to make the boolean logic legible
+        boolean isNoisy = (notification.defaults & Notification.DEFAULT_SOUND) != 0
+                || (notification.defaults & Notification.DEFAULT_VIBRATE) != 0
+                || notification.sound != null
+                || notification.vibrate != null;
+        boolean isHighPriority = sbn.getScore() >= INTERRUPTION_THRESHOLD;
+        boolean isFullscreen = notification.fullScreenIntent != null;
+        boolean isAllowed = notification.extras.getInt(Notification.EXTRA_AS_HEADS_UP,
+                Notification.HEADS_UP_ALLOWED) != Notification.HEADS_UP_NEVER;
+
+        boolean interrupt = (isFullscreen || (isHighPriority && isNoisy))
+                && isAllowed
+                && mPowerManager.isScreenOn()
+                && !mKeyguardManager.isKeyguardLocked();
+        try {
+            interrupt = interrupt && !mDreamManager.isDreaming();
+        } catch (RemoteException e) {
+            Log.d(TAG, "failed to query dream manager", e);
+        }
+        if (DEBUG) Log.d(TAG, "interrupt: " + interrupt);
+        return interrupt;
     }
 
     // Q: What kinds of notifications should show during setup?
@@ -1172,4 +1096,15 @@
         KeyguardManager km = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
         return km.inKeyguardRestrictedInputMode();
     }
+
+    public void setInteracting(int barWindow, boolean interacting) {
+        // hook for subclasses
+    }
+
+    public void destroy() {
+        if (mSearchPanelView != null) {
+            mWindowManager.removeViewImmediate(mSearchPanelView);
+        }
+        mContext.unregisterReceiver(mBroadcastReceiver);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index cbbaab3..e8173b7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -19,8 +19,8 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
-
 import android.service.notification.StatusBarNotification;
+
 import com.android.internal.statusbar.IStatusBar;
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.internal.statusbar.StatusBarIconList;
@@ -56,6 +56,7 @@
     private static final int MSG_PRELOAD_RECENT_APPS        = 14 << MSG_SHIFT;
     private static final int MSG_CANCEL_PRELOAD_RECENT_APPS = 15 << MSG_SHIFT;
     private static final int MSG_SET_NAVIGATION_ICON_HINTS  = 16 << MSG_SHIFT;
+    private static final int MSG_SET_WINDOW_STATE           = 17 << MSG_SHIFT;
 
     public static final int FLAG_EXCLUDE_NONE = 0;
     public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
@@ -98,6 +99,7 @@
         public void hideSearchPanel();
         public void cancelPreloadRecentApps();
         public void setNavigationIconHints(int hints);
+        public void setWindowState(int window, int state);
     }
 
     public CommandQueue(Callbacks callbacks, StatusBarIconList list) {
@@ -232,6 +234,13 @@
         }
     }
 
+    public void setWindowState(int window, int state) {
+        synchronized (mList) {
+            // don't coalesce these
+            mHandler.obtainMessage(MSG_SET_WINDOW_STATE, window, state, null).sendToTarget();
+        }
+    }
+
     private final class H extends Handler {
         public void handleMessage(Message msg) {
             final int what = msg.what & MSG_MASK;
@@ -312,6 +321,9 @@
                 case MSG_SET_NAVIGATION_ICON_HINTS:
                     mCallbacks.setNavigationIconHints(msg.arg1);
                     break;
+                case MSG_SET_WINDOW_STATE:
+                    mCallbacks.setWindowState(msg.arg1, msg.arg2);
+                    break;
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java
index 3ac1bcf..900e1e0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar;
 
+import android.app.StatusBarManager;
 import android.graphics.RectF;
 import android.view.MotionEvent;
 import android.view.View;
@@ -57,8 +58,8 @@
         final float sourceX = mTempPoint[0];
         final float sourceY = mTempPoint[1];
 
-
-        switch (event.getAction()) {
+        final int action = event.getAction();
+        switch (action) {
             case MotionEvent.ACTION_DOWN:
                 mPanelShowing = mDelegateView.getVisibility() == View.VISIBLE;
                 mDownPoint[0] = event.getX();
@@ -71,7 +72,7 @@
             return false;
         }
 
-        if (!mPanelShowing && event.getAction() == MotionEvent.ACTION_MOVE) {
+        if (!mPanelShowing && action == MotionEvent.ACTION_MOVE) {
             final int historySize = event.getHistorySize();
             for (int k = 0; k < historySize + 1; k++) {
                 float x = k < historySize ? event.getHistoricalX(k) : event.getX();
@@ -85,6 +86,12 @@
             }
         }
 
+        if (action == MotionEvent.ACTION_DOWN) {
+            mBar.setInteracting(StatusBarManager.WINDOW_NAVIGATION_BAR, true);
+        } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
+            mBar.setInteracting(StatusBarManager.WINDOW_NAVIGATION_BAR, false);
+        }
+
         mDelegateView.getLocationOnScreen(mTempPoint);
         final float delegateX = mTempPoint[0];
         final float delegateY = mTempPoint[1];
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DoNotDisturb.java b/packages/SystemUI/src/com/android/systemui/statusbar/DoNotDisturb.java
deleted file mode 100644
index 9e44e71..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DoNotDisturb.java
+++ /dev/null
@@ -1,60 +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.systemui.statusbar;
-
-import android.app.StatusBarManager;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.util.Slog;
-
-import com.android.systemui.statusbar.policy.Prefs;
-
-public class DoNotDisturb implements SharedPreferences.OnSharedPreferenceChangeListener {
-    private Context mContext;
-    private StatusBarManager mStatusBar;
-    SharedPreferences mPrefs;
-    private boolean mDoNotDisturb;
-
-    public DoNotDisturb(Context context) {
-        mContext = context;
-        mStatusBar = (StatusBarManager)context.getSystemService(Context.STATUS_BAR_SERVICE);
-        mPrefs = Prefs.read(context);
-        mPrefs.registerOnSharedPreferenceChangeListener(this);
-        mDoNotDisturb = mPrefs.getBoolean(Prefs.DO_NOT_DISTURB_PREF, Prefs.DO_NOT_DISTURB_DEFAULT);
-        updateDisableRecord();
-    }
-
-    public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
-        final boolean val = prefs.getBoolean(Prefs.DO_NOT_DISTURB_PREF,
-                Prefs.DO_NOT_DISTURB_DEFAULT);
-        if (val != mDoNotDisturb) {
-            mDoNotDisturb = val;
-            updateDisableRecord();
-        }
-    }
-
-    private void updateDisableRecord() {
-        final int disabled = StatusBarManager.DISABLE_NOTIFICATION_ICONS
-                | StatusBarManager.DISABLE_NOTIFICATION_ALERTS
-                | StatusBarManager.DISABLE_NOTIFICATION_TICKER;
-        mStatusBar.disable(mDoNotDisturb ? disabled : 0);
-    }
-}
-
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
new file mode 100644
index 0000000..cd6495f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -0,0 +1,79 @@
+/*
+ * 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.systemui.statusbar;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+public class ExpandableNotificationRow extends FrameLayout {
+    private int mRowHeight;
+
+    /** does this row contain layouts that can adapt to row expansion */
+    private boolean mExpandable;
+    /** has the user manually expanded this row */
+    private boolean mUserExpanded;
+    /** is the user touching this row */
+    private boolean mUserLocked;
+
+    public ExpandableNotificationRow(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public int getRowHeight() {
+        return mRowHeight;
+    }
+
+    public void setRowHeight(int rowHeight) {
+        this.mRowHeight = rowHeight;
+    }
+
+    public boolean isExpandable() {
+        return mExpandable;
+    }
+
+    public void setExpandable(boolean expandable) {
+        mExpandable = expandable;
+    }
+
+    public boolean isUserExpanded() {
+        return mUserExpanded;
+    }
+
+    public void setUserExpanded(boolean userExpanded) {
+        mUserExpanded = userExpanded;
+    }
+
+    public boolean isUserLocked() {
+        return mUserLocked;
+    }
+
+    public void setUserLocked(boolean userLocked) {
+        mUserLocked = userLocked;
+    }
+
+    public void setExpanded(boolean expand) {
+        ViewGroup.LayoutParams lp = getLayoutParams();
+        if (expand && mExpandable) {
+            lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+        } else {
+            lp.height = mRowHeight;
+        }
+        setLayoutParams(lp);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/GestureRecorder.java b/packages/SystemUI/src/com/android/systemui/statusbar/GestureRecorder.java
index 0f894a1..f2adaf0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/GestureRecorder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/GestureRecorder.java
@@ -16,6 +16,12 @@
 
 package com.android.systemui.statusbar;
 
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemClock;
+import android.util.Log;
+import android.view.MotionEvent;
+
 import java.io.BufferedWriter;
 import java.io.FileDescriptor;
 import java.io.FileWriter;
@@ -24,12 +30,6 @@
 import java.util.HashSet;
 import java.util.LinkedList;
 
-import android.os.Handler;
-import android.os.Message;
-import android.os.SystemClock;
-import android.util.Slog;
-import android.view.MotionEvent;
-
 /**
  * Convenience class for capturing gestures for later analysis.
  */
@@ -46,7 +46,7 @@
             public MotionEvent event;
             public MotionEventRecord(long when, MotionEvent event) {
                 this.time = when;
-                this.event = event.copy();
+                this.event = MotionEvent.obtain(event);
             }
             String actionName(int action) {
                 switch (action) {
@@ -101,7 +101,7 @@
                 mDownTime = ev.getDownTime();
             } else {
                 if (mDownTime != ev.getDownTime()) {
-                    Slog.w(TAG, "Assertion failure in GestureRecorder: event downTime ("
+                    Log.w(TAG, "Assertion failure in GestureRecorder: event downTime ("
                             +ev.getDownTime()+") does not match gesture downTime ("+mDownTime+")");
                 }
             }
@@ -237,10 +237,10 @@
                     mGestures.add(mCurrentGesture);
                 }
                 if (DEBUG) {
-                    Slog.v(TAG, String.format("Wrote %d complete gestures to %s", mLastSaveLen, mLogfile));
+                    Log.v(TAG, String.format("Wrote %d complete gestures to %s", mLastSaveLen, mLogfile));
                 }
             } catch (IOException e) {
-                Slog.e(TAG, String.format("Couldn't write gestures to %s", mLogfile), e);
+                Log.e(TAG, String.format("Couldn't write gestures to %s", mLogfile), e);
                 mLastSaveLen = -1;
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 2c7a2a8..5264998 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -16,15 +16,15 @@
 
 package com.android.systemui.statusbar;
 
-import android.service.notification.StatusBarNotification;
 import android.os.IBinder;
+import android.service.notification.StatusBarNotification;
 import android.view.View;
 import android.widget.ImageView;
 
 import com.android.systemui.R;
 
-import java.util.Comparator;
 import java.util.ArrayList;
+import java.util.Comparator;
 
 /**
  * The list of currently displaying notifications.
@@ -34,53 +34,34 @@
         public IBinder key;
         public StatusBarNotification notification;
         public StatusBarIconView icon;
-        public View row; // the outer expanded view
+        public ExpandableNotificationRow row; // the outer expanded view
         public View content; // takes the click events and sends the PendingIntent
         public View expanded; // the inflated RemoteViews
         public ImageView largeIcon;
-        protected View expandedLarge;
+        private View expandedBig;
+        private boolean interruption;
         public Entry() {}
         public Entry(IBinder key, StatusBarNotification n, StatusBarIconView ic) {
             this.key = key;
             this.notification = n;
             this.icon = ic;
         }
-        public void setLargeView(View expandedLarge) {
-            this.expandedLarge = expandedLarge;
-            writeBooleanTag(row, R.id.expandable_tag, expandedLarge != null);
+        public void setBigContentView(View bigContentView) {
+            this.expandedBig = bigContentView;
+            row.setExpandable(bigContentView != null);
         }
-        public View getLargeView() {
-            return expandedLarge;
-        }
-        /**
-         * Return whether the entry can be expanded.
-         */
-        public boolean expandable() {
-            return NotificationData.getIsExpandable(row);
-        }
-        /**
-         * Return whether the entry has been manually expanded by the user.
-         */
-        public boolean userExpanded() {
-            return NotificationData.getUserExpanded(row);
-        }
-        /**
-         * Set the flag indicating that this was manually expanded by the user.
-         */
-        public boolean setUserExpanded(boolean userExpanded) {
-            return NotificationData.setUserExpanded(row, userExpanded);
-        }
-        /**
-         * Return whether the entry is being touched by the user.
-         */
-        public boolean userLocked() {
-            return NotificationData.getUserLocked(row);
+        public View getBigContentView() {
+            return expandedBig;
         }
         /**
          * Set the flag indicating that this is being touched by the user.
          */
-        public boolean setUserLocked(boolean userLocked) {
-            return NotificationData.setUserLocked(row, userLocked);
+        public void setUserLocked(boolean userLocked) {
+            row.setUserLocked(userLocked);
+        }
+
+        public void setInterruption() {
+            interruption = true;
         }
     }
     private final ArrayList<Entry> mEntries = new ArrayList<Entry>();
@@ -90,9 +71,13 @@
             final StatusBarNotification na = a.notification;
             final StatusBarNotification nb = b.notification;
             int d = na.getScore() - nb.getScore();
-            return (d != 0)
-                ? d
-                : (int)(na.getNotification().when - nb.getNotification().when);
+	    if (a.interruption != b.interruption) {
+	      return a.interruption ? 1 : -1;
+	    } else if (d != 0) {
+                return d;
+            } else {
+                return (int) (na.getNotification().when - nb.getNotification().when);
+            }
         }
     };
 
@@ -125,8 +110,8 @@
         return i;
     }
 
-    public int add(IBinder key, StatusBarNotification notification, View row, View content,
-            View expanded, StatusBarIconView icon) {
+    public int add(IBinder key, StatusBarNotification notification, ExpandableNotificationRow row,
+            View content, View expanded, StatusBarIconView icon) {
         Entry entry = new Entry();
         entry.key = key;
         entry.notification = notification;
@@ -171,55 +156,4 @@
         }
         return false;
     }
-
-    protected static boolean readBooleanTag(View view, int id)  {
-        if (view != null) {
-            Object value = view.getTag(id);
-            return value != null && value instanceof Boolean && ((Boolean) value).booleanValue();
-        }
-        return false;
-    }
-
-    protected static boolean writeBooleanTag(View view, int id, boolean value)  {
-        if (view != null) {
-            view.setTag(id, Boolean.valueOf(value));
-            return value;
-        }
-        return false;
-    }
-
-    /**
-     * Return whether the entry can be expanded.
-     */
-    public static boolean getIsExpandable(View row) {
-        return readBooleanTag(row, R.id.expandable_tag);
-    }
-
-    /**
-     * Return whether the entry has been manually expanded by the user.
-     */
-    public static boolean getUserExpanded(View row) {
-        return readBooleanTag(row, R.id.user_expanded_tag);
-    }
-
-    /**
-     * Set whether the entry has been manually expanded by the user.
-     */
-    public static boolean setUserExpanded(View row, boolean userExpanded) {
-        return writeBooleanTag(row, R.id.user_expanded_tag, userExpanded);
-    }
-
-    /**
-     * Return whether the entry is being touched by the user.
-     */
-    public static boolean getUserLocked(View row) {
-        return readBooleanTag(row, R.id.user_lock_tag);
-    }
-
-    /**
-     * Set whether the entry is being touched by the user.
-     */
-    public static boolean setUserLocked(View row, boolean userLocked) {
-        return writeBooleanTag(row, R.id.user_lock_tag, userLocked);
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/RotationToggle.java b/packages/SystemUI/src/com/android/systemui/statusbar/RotationToggle.java
deleted file mode 100644
index 735ee25..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/RotationToggle.java
+++ /dev/null
@@ -1,60 +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.systemui.statusbar;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.CompoundButton;
-
-import com.android.systemui.statusbar.policy.AutoRotateController;
-
-public class RotationToggle extends CompoundButton
-        implements AutoRotateController.RotationLockCallbacks {
-    private AutoRotateController mRotater;
-
-    public RotationToggle(Context context) {
-        super(context);
-    }
-
-    public RotationToggle(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public RotationToggle(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        mRotater = new AutoRotateController(getContext(), this, this);
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        if (mRotater != null) {
-            mRotater.release();
-            mRotater = null;
-        }
-    }
-
-    @Override
-    public void setRotationLockControlVisibility(boolean show) {
-        setVisibility(show ? VISIBLE : GONE);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ServiceMonitor.java b/packages/SystemUI/src/com/android/systemui/statusbar/ServiceMonitor.java
new file mode 100644
index 0000000..aea9ec6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ServiceMonitor.java
@@ -0,0 +1,282 @@
+/*
+ * 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.systemui.statusbar;
+
+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.ServiceConnection;
+import android.content.pm.PackageManager;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.Log;
+
+import java.util.Arrays;
+
+/**
+ * Manages a persistent connection to a service component defined in a secure setting.
+ *
+ * <p>If a valid service component is specified in the secure setting, starts it up and keeps it
+ * running; handling setting changes, package updates, component disabling, and unexpected
+ * process termination.
+ *
+ * <p>Clients can listen for important events using the supplied {@link Callbacks}.
+ */
+public class ServiceMonitor {
+    private static final int RECHECK_DELAY = 2000;
+    private static final int WAIT_FOR_STOP = 500;
+
+    public interface Callbacks {
+        /** The service does not exist or failed to bind */
+        void onNoService();
+        /** The service is about to start, this is a chance to perform cleanup and
+         * delay the start if necessary */
+        long onServiceStartAttempt();
+    }
+
+    // internal handler + messages used to serialize access to internal state
+    public static final int MSG_START_SERVICE = 1;
+    public static final int MSG_CONTINUE_START_SERVICE = 2;
+    public static final int MSG_STOP_SERVICE = 3;
+    public static final int MSG_PACKAGE_INTENT = 4;
+    public static final int MSG_CHECK_BOUND = 5;
+    public static final int MSG_SERVICE_DISCONNECTED = 6;
+
+    private final Handler mHandler = new Handler() {
+        public void handleMessage(Message msg) {
+            switch(msg.what) {
+                case MSG_START_SERVICE:
+                    startService();
+                    break;
+                case MSG_CONTINUE_START_SERVICE:
+                    continueStartService();
+                    break;
+                case MSG_STOP_SERVICE:
+                    stopService();
+                    break;
+                case MSG_PACKAGE_INTENT:
+                    packageIntent((Intent)msg.obj);
+                    break;
+                case MSG_CHECK_BOUND:
+                    checkBound();
+                    break;
+                case MSG_SERVICE_DISCONNECTED:
+                    serviceDisconnected((ComponentName)msg.obj);
+                    break;
+            }
+        }
+    };
+
+    private final ContentObserver mSettingObserver = new ContentObserver(mHandler) {
+        public void onChange(boolean selfChange) {
+            onChange(selfChange, null);
+        }
+
+        public void onChange(boolean selfChange, Uri uri) {
+            if (mDebug) Log.d(mTag, "onChange selfChange=" + selfChange + " uri=" + uri);
+            ComponentName cn = getComponentNameFromSetting();
+            if (cn == null && mServiceName == null || cn != null && cn.equals(mServiceName)) {
+                if (mDebug) Log.d(mTag, "skipping no-op restart");
+                return;
+            }
+            if (mBound) {
+                mHandler.sendEmptyMessage(MSG_STOP_SERVICE);
+            }
+            mHandler.sendEmptyMessageDelayed(MSG_START_SERVICE, WAIT_FOR_STOP);
+        }
+    };
+
+    private final class SC implements ServiceConnection, IBinder.DeathRecipient {
+        private ComponentName mName;
+        private IBinder mService;
+
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            if (mDebug) Log.d(mTag, "onServiceConnected name=" + name + " service=" + service);
+            mName = name;
+            mService = service;
+            try {
+                service.linkToDeath(this, 0);
+            } catch (RemoteException e) {
+                Log.w(mTag, "Error linking to death", e);
+            }
+        }
+
+        public void onServiceDisconnected(ComponentName name) {
+            if (mDebug) Log.d(mTag, "onServiceDisconnected name=" + name);
+            boolean unlinked = mService.unlinkToDeath(this, 0);
+            if (mDebug) Log.d(mTag, "  unlinked=" + unlinked);
+            mHandler.sendMessage(mHandler.obtainMessage(MSG_SERVICE_DISCONNECTED, mName));
+        }
+
+        public void binderDied() {
+            if (mDebug) Log.d(mTag, "binderDied");
+            mHandler.sendMessage(mHandler.obtainMessage(MSG_SERVICE_DISCONNECTED, mName));
+        }
+    }
+
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        public void onReceive(Context context, Intent intent) {
+            String pkg = intent.getData().getSchemeSpecificPart();
+            if (mServiceName != null && mServiceName.getPackageName().equals(pkg)) {
+                mHandler.sendMessage(mHandler.obtainMessage(MSG_PACKAGE_INTENT, intent));
+            }
+        }
+    };
+
+    private final String mTag;
+    private final boolean mDebug;
+
+    private final Context mContext;
+    private final String mSettingKey;
+    private final Callbacks mCallbacks;
+
+    private ComponentName mServiceName;
+    private SC mServiceConnection;
+    private boolean mBound;
+
+    public ServiceMonitor(String ownerTag, boolean debug,
+            Context context, String settingKey, Callbacks callbacks) {
+        mTag = ownerTag + ".ServiceMonitor";
+        mDebug = debug;
+        mContext = context;
+        mSettingKey = settingKey;
+        mCallbacks = callbacks;
+    }
+
+    public void start() {
+        // listen for setting changes
+        ContentResolver cr = mContext.getContentResolver();
+        cr.registerContentObserver(Settings.Secure.getUriFor(mSettingKey),
+                false /*notifyForDescendents*/, mSettingObserver, UserHandle.USER_ALL);
+
+        // listen for package/component changes
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_PACKAGE_ADDED);
+        filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+        filter.addDataScheme("package");
+        mContext.registerReceiver(mBroadcastReceiver, filter);
+
+        mHandler.sendEmptyMessage(MSG_START_SERVICE);
+    }
+
+    private ComponentName getComponentNameFromSetting() {
+        String cn = Settings.Secure.getStringForUser(mContext.getContentResolver(),
+                mSettingKey, UserHandle.USER_CURRENT);
+        return cn == null ? null : ComponentName.unflattenFromString(cn);
+    }
+
+    // everything below is called on the handler
+
+    private void packageIntent(Intent intent) {
+        if (mDebug) Log.d(mTag, "packageIntent intent=" + intent
+                + " extras=" + bundleToString(intent.getExtras()));
+        if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
+            mHandler.sendEmptyMessage(MSG_START_SERVICE);
+        } else if (Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())) {
+            PackageManager pm = mContext.getPackageManager();
+            boolean serviceEnabled =
+                    pm.getApplicationEnabledSetting(mServiceName.getPackageName())
+                        != PackageManager.COMPONENT_ENABLED_STATE_DISABLED
+                    && pm.getComponentEnabledSetting(mServiceName)
+                        != PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
+            if (mBound && !serviceEnabled) {
+                stopService();
+                scheduleCheckBound();
+            } else if (!mBound && serviceEnabled) {
+                startService();
+            }
+        }
+    }
+
+    private void stopService() {
+        if (mDebug) Log.d(mTag, "stopService");
+        boolean stopped = mContext.stopService(new Intent().setComponent(mServiceName));
+        if (mDebug) Log.d(mTag, "  stopped=" + stopped);
+        mContext.unbindService(mServiceConnection);
+        mBound = false;
+    }
+
+    private void startService() {
+        mServiceName = getComponentNameFromSetting();
+        if (mDebug) Log.d(mTag, "startService mServiceName=" + mServiceName);
+        if (mServiceName == null) {
+            mBound = false;
+            mCallbacks.onNoService();
+        } else {
+            long delay = mCallbacks.onServiceStartAttempt();
+            mHandler.sendEmptyMessageDelayed(MSG_CONTINUE_START_SERVICE, delay);
+        }
+    }
+
+    private void continueStartService() {
+        if (mDebug) Log.d(mTag, "continueStartService");
+        Intent intent = new Intent().setComponent(mServiceName);
+        try {
+            mServiceConnection = new SC();
+            mBound = mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
+            if (mDebug) Log.d(mTag, "mBound: " + mBound);
+        } catch (Throwable t) {
+            Log.w(mTag, "Error binding to service: " + mServiceName, t);
+        }
+        if (!mBound) {
+            mCallbacks.onNoService();
+        }
+    }
+
+    private void serviceDisconnected(ComponentName serviceName) {
+        if (mDebug) Log.d(mTag, "serviceDisconnected serviceName=" + serviceName
+                + " mServiceName=" + mServiceName);
+        if (serviceName.equals(mServiceName)) {
+            mBound = false;
+            scheduleCheckBound();
+        }
+    }
+
+    private void checkBound() {
+        if (mDebug) Log.d(mTag, "checkBound mBound=" + mBound);
+        if (!mBound) {
+            startService();
+        }
+    }
+
+    private void scheduleCheckBound() {
+        mHandler.removeMessages(MSG_CHECK_BOUND);
+        mHandler.sendEmptyMessageDelayed(MSG_CHECK_BOUND, RECHECK_DELAY);
+    }
+
+    private static String bundleToString(Bundle bundle) {
+        if (bundle == null) return null;
+        StringBuilder sb = new StringBuilder('{');
+        for (String key : bundle.keySet()) {
+            if (sb.length() > 1) sb.append(',');
+            Object v = bundle.get(key);
+            v = (v instanceof String[]) ? Arrays.asList((String[]) v) : v;
+            sb.append(key).append('=').append(v);
+        }
+        return sb.append('}').toString();
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index 46916f7..f1c8e01 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -18,16 +18,15 @@
 
 import android.content.Context;
 import android.util.AttributeSet;
-import android.util.Slog;
+import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 
-import com.android.systemui.statusbar.policy.NetworkController;
-
 import com.android.systemui.R;
+import com.android.systemui.statusbar.policy.NetworkController;
 
 // Intimately tied to the design of res/layout/signal_cluster_view.xml
 public class SignalClusterView
@@ -40,15 +39,15 @@
     NetworkController mNC;
 
     private boolean mWifiVisible = false;
-    private int mWifiStrengthId = 0, mWifiActivityId = 0;
+    private int mWifiStrengthId = 0;
     private boolean mMobileVisible = false;
-    private int mMobileStrengthId = 0, mMobileActivityId = 0, mMobileTypeId = 0;
+    private int mMobileStrengthId = 0, mMobileTypeId = 0;
     private boolean mIsAirplaneMode = false;
     private int mAirplaneIconId = 0;
     private String mWifiDescription, mMobileDescription, mMobileTypeDescription;
 
     ViewGroup mWifiGroup, mMobileGroup;
-    ImageView mWifi, mMobile, mWifiActivity, mMobileActivity, mMobileType, mAirplane;
+    ImageView mWifi, mMobile, mMobileType, mAirplane;
     View mSpacer;
 
     public SignalClusterView(Context context) {
@@ -64,7 +63,7 @@
     }
 
     public void setNetworkController(NetworkController nc) {
-        if (DEBUG) Slog.d(TAG, "NetworkController=" + nc);
+        if (DEBUG) Log.d(TAG, "NetworkController=" + nc);
         mNC = nc;
     }
 
@@ -74,10 +73,8 @@
 
         mWifiGroup      = (ViewGroup) findViewById(R.id.wifi_combo);
         mWifi           = (ImageView) findViewById(R.id.wifi_signal);
-        mWifiActivity   = (ImageView) findViewById(R.id.wifi_inout);
         mMobileGroup    = (ViewGroup) findViewById(R.id.mobile_combo);
         mMobile         = (ImageView) findViewById(R.id.mobile_signal);
-        mMobileActivity = (ImageView) findViewById(R.id.mobile_inout);
         mMobileType     = (ImageView) findViewById(R.id.mobile_type);
         mSpacer         =             findViewById(R.id.spacer);
         mAirplane       = (ImageView) findViewById(R.id.airplane);
@@ -89,10 +86,8 @@
     protected void onDetachedFromWindow() {
         mWifiGroup      = null;
         mWifi           = null;
-        mWifiActivity   = null;
         mMobileGroup    = null;
         mMobile         = null;
-        mMobileActivity = null;
         mMobileType     = null;
         mSpacer         = null;
         mAirplane       = null;
@@ -101,22 +96,19 @@
     }
 
     @Override
-    public void setWifiIndicators(boolean visible, int strengthIcon, int activityIcon,
-            String contentDescription) {
+    public void setWifiIndicators(boolean visible, int strengthIcon, String contentDescription) {
         mWifiVisible = visible;
         mWifiStrengthId = strengthIcon;
-        mWifiActivityId = activityIcon;
         mWifiDescription = contentDescription;
 
         apply();
     }
 
     @Override
-    public void setMobileDataIndicators(boolean visible, int strengthIcon, int activityIcon,
+    public void setMobileDataIndicators(boolean visible, int strengthIcon,
             int typeIcon, String contentDescription, String typeContentDescription) {
         mMobileVisible = visible;
         mMobileStrengthId = strengthIcon;
-        mMobileActivityId = activityIcon;
         mMobileTypeId = typeIcon;
         mMobileDescription = contentDescription;
         mMobileTypeDescription = typeContentDescription;
@@ -136,9 +128,9 @@
     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
         // Standard group layout onPopulateAccessibilityEvent() implementations
         // ignore content description, so populate manually
-        if (mWifiVisible && mWifiGroup.getContentDescription() != null)
+        if (mWifiVisible && mWifiGroup != null && mWifiGroup.getContentDescription() != null)
             event.getText().add(mWifiGroup.getContentDescription());
-        if (mMobileVisible && mMobileGroup.getContentDescription() != null)
+        if (mMobileVisible && mMobileGroup != null && mMobileGroup.getContentDescription() != null)
             event.getText().add(mMobileGroup.getContentDescription());
         return super.dispatchPopulateAccessibilityEvent(event);
     }
@@ -150,16 +142,11 @@
         if (mWifi != null) {
             mWifi.setImageDrawable(null);
         }
-        if (mWifiActivity != null) {
-            mWifiActivity.setImageDrawable(null);
-        }
 
         if (mMobile != null) {
             mMobile.setImageDrawable(null);
         }
-        if (mMobileActivity != null) {
-            mMobileActivity.setImageDrawable(null);
-        }
+
         if (mMobileType != null) {
             mMobileType.setImageDrawable(null);
         }
@@ -177,7 +164,6 @@
 
         if (mWifiVisible) {
             mWifi.setImageResource(mWifiStrengthId);
-            mWifiActivity.setImageResource(mWifiActivityId);
 
             mWifiGroup.setContentDescription(mWifiDescription);
             mWifiGroup.setVisibility(View.VISIBLE);
@@ -185,14 +171,13 @@
             mWifiGroup.setVisibility(View.GONE);
         }
 
-        if (DEBUG) Slog.d(TAG,
-                String.format("wifi: %s sig=%d act=%d",
+        if (DEBUG) Log.d(TAG,
+                String.format("wifi: %s sig=%d",
                     (mWifiVisible ? "VISIBLE" : "GONE"),
-                    mWifiStrengthId, mWifiActivityId));
+                    mWifiStrengthId));
 
         if (mMobileVisible && !mIsAirplaneMode) {
             mMobile.setImageResource(mMobileStrengthId);
-            mMobileActivity.setImageResource(mMobileActivityId);
             mMobileType.setImageResource(mMobileTypeId);
 
             mMobileGroup.setContentDescription(mMobileTypeDescription + " " + mMobileDescription);
@@ -214,10 +199,10 @@
             mSpacer.setVisibility(View.GONE);
         }
 
-        if (DEBUG) Slog.d(TAG,
-                String.format("mobile: %s sig=%d act=%d typ=%d",
+        if (DEBUG) Log.d(TAG,
+                String.format("mobile: %s sig=%d typ=%d",
                     (mMobileVisible ? "VISIBLE" : "GONE"),
-                    mMobileStrengthId, mMobileActivityId, mMobileTypeId));
+                    mMobileStrengthId, mMobileTypeId));
 
         mMobileType.setVisibility(
                 !mWifiVisible ? View.VISIBLE : View.GONE);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 39d56a4..9f9524b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -20,25 +20,23 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.AttributeSet;
-import android.util.Slog;
 import android.util.Log;
 import android.view.ViewDebug;
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.ImageView;
 
-import java.text.NumberFormat;
-
 import com.android.internal.statusbar.StatusBarIcon;
-
 import com.android.systemui.R;
 
+import java.text.NumberFormat;
+
 public class StatusBarIconView extends AnimatedImageView {
     private static final String TAG = "StatusBarIconView";
 
@@ -70,8 +68,6 @@
             final float scale = (float)imageBounds / (float)outerBounds;
             setScaleX(scale);
             setScaleY(scale);
-            final float alpha = res.getFraction(R.dimen.status_bar_icon_drawing_alpha, 1, 1);
-            setAlpha(alpha);
         }
 
         setScaleType(ImageView.ScaleType.CENTER);
@@ -85,8 +81,6 @@
         final float scale = (float)imageBounds / (float)outerBounds;
         setScaleX(scale);
         setScaleY(scale);
-        final float alpha = res.getFraction(R.dimen.status_bar_icon_drawing_alpha, 1, 1);
-        setAlpha(alpha);
     }
 
     private static boolean streq(String a, String b) {
@@ -151,7 +145,7 @@
     private boolean updateDrawable(boolean withClear) {
         Drawable drawable = getIcon(mIcon);
         if (drawable == null) {
-            Slog.w(TAG, "No icon for slot " + mSlot);
+            Log.w(TAG, "No icon for slot " + mSlot);
             return false;
         }
         if (withClear) {
@@ -168,7 +162,7 @@
     /**
      * Returns the right icon to use for this item, respecting the iconId and
      * iconPackage (if set)
-     * 
+     *
      * @param context Context to use to get resources if iconPackage is not set
      * @return Drawable for this item, or null if the package or item could not
      *         be found
@@ -185,7 +179,7 @@
                 r = context.getPackageManager()
                         .getResourcesForApplicationAsUser(icon.iconPackage, userId);
             } catch (PackageManager.NameNotFoundException ex) {
-                Slog.e(TAG, "Icon package not found: " + icon.iconPackage);
+                Log.e(TAG, "Icon package not found: " + icon.iconPackage);
                 return null;
             }
         } else {
@@ -195,11 +189,11 @@
         if (icon.iconId == 0) {
             return null;
         }
-        
+
         try {
             return r.getDrawable(icon.iconId);
         } catch (RuntimeException e) {
-            Slog.w(TAG, "Icon not found in "
+            Log.w(TAG, "Icon not found in "
                   + (icon.iconPackage != null ? icon.iconId : "<system>")
                   + ": " + Integer.toHexString(icon.iconId));
         }
@@ -287,7 +281,7 @@
     }
 
     public String toString() {
-        return "StatusBarIconView(slot=" + mSlot + " icon=" + mIcon 
+        return "StatusBarIconView(slot=" + mSlot + " icon=" + mIcon
             + " notification=" + mNotification + ")";
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarPanel.java
new file mode 100644
index 0000000..272c321
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarPanel.java
@@ -0,0 +1,21 @@
+/*
+ * 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.systemui.statusbar;
+
+public interface StatusBarPanel {
+    public boolean isInContentArea(int x, int y);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SystemBars.java b/packages/SystemUI/src/com/android/systemui/statusbar/SystemBars.java
new file mode 100644
index 0000000..ecf7b35
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SystemBars.java
@@ -0,0 +1,106 @@
+/*
+ * 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.systemui.statusbar;
+
+import android.provider.Settings;
+import android.util.Log;
+
+import com.android.systemui.R;
+import com.android.systemui.SystemUI;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * Ensure a single status bar service implementation is running at all times.
+ *
+ * <p>The implementation either comes from a service component running in a remote process (defined
+ * using a secure setting), else falls back to using the in-process implementation according
+ * to the product config.
+ */
+public class SystemBars extends SystemUI implements ServiceMonitor.Callbacks {
+    private static final String TAG = "SystemBars";
+    private static final boolean DEBUG = true;
+    private static final int WAIT_FOR_BARS_TO_DIE = 500;
+
+    // manages the implementation coming from the remote process
+    private ServiceMonitor mServiceMonitor;
+
+    // in-process fallback implementation, per the product config
+    private BaseStatusBar mStatusBar;
+
+    @Override
+    public void start() {
+        if (DEBUG) Log.d(TAG, "start");
+        mServiceMonitor = new ServiceMonitor(TAG, DEBUG,
+                mContext, Settings.Secure.BAR_SERVICE_COMPONENT, this);
+        mServiceMonitor.start();  // will call onNoService if no remote service is found
+    }
+
+    @Override
+    public void onNoService() {
+        if (DEBUG) Log.d(TAG, "onNoService");
+        createStatusBarFromConfig();  // fallback to using an in-process implementation
+    }
+
+    @Override
+    public long onServiceStartAttempt() {
+        if (DEBUG) Log.d(TAG, "onServiceStartAttempt mStatusBar="+mStatusBar);
+        if (mStatusBar != null) {
+            // tear down the in-process version, we'll recreate it again if needed
+            mStatusBar.destroy();
+            mStatusBar = null;
+            return WAIT_FOR_BARS_TO_DIE;
+        }
+        return 0;
+    }
+
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (mStatusBar != null) {
+            mStatusBar.dump(fd, pw, args);
+        }
+    }
+
+    private void createStatusBarFromConfig() {
+        if (DEBUG) Log.d(TAG, "createStatusBarFromConfig");
+        final String clsName = mContext.getString(R.string.config_statusBarComponent);
+        if (clsName == null || clsName.length() == 0) {
+            throw andLog("No status bar component configured", null);
+        }
+        Class<?> cls = null;
+        try {
+            cls = mContext.getClassLoader().loadClass(clsName);
+        } catch (Throwable t) {
+            throw andLog("Error loading status bar component: " + clsName, t);
+        }
+        try {
+            mStatusBar = (BaseStatusBar) cls.newInstance();
+        } catch (Throwable t) {
+            throw andLog("Error creating status bar component: " + clsName, t);
+        }
+        mStatusBar.mContext = mContext;
+        mStatusBar.mComponents = mComponents;
+        mStatusBar.start();
+        if (DEBUG) Log.d(TAG, "started " + mStatusBar.getClass().getSimpleName());
+    }
+
+    private RuntimeException andLog(String msg, Throwable t) {
+        Log.w(TAG, msg, t);
+        throw new RuntimeException(msg, t);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
new file mode 100644
index 0000000..212d704
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
@@ -0,0 +1,123 @@
+/*
+ * 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.systemui.statusbar.phone;
+
+import android.animation.ArgbEvaluator;
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.app.ActivityManager;
+import android.content.res.Resources;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.util.Log;
+import android.view.View;
+
+import com.android.systemui.R;
+
+public class BarTransitions {
+    private static final boolean DEBUG = false;
+
+    public static final int MODE_OPAQUE = 0;
+    public static final int MODE_SEMI_TRANSPARENT = 1;
+    public static final int MODE_TRANSPARENT = 2;
+    public static final int MODE_LIGHTS_OUT = 3;
+
+    protected static final int LIGHTS_IN_DURATION = 250;
+    protected static final int LIGHTS_OUT_DURATION = 750;
+
+    private final String mTag;
+    protected final View mTarget;
+    protected final int mOpaque;
+    protected final int mSemiTransparent;
+
+    protected Drawable mTransparent;
+    private int mMode;
+    private ValueAnimator mBackgroundColorAnimator;
+
+    private final AnimatorUpdateListener mBackgroundColorListener = new AnimatorUpdateListener() {
+        @Override
+        public void onAnimationUpdate(ValueAnimator animator) {
+            mTarget.setBackgroundColor((Integer) animator.getAnimatedValue());
+        }
+    };
+
+    public BarTransitions(View target) {
+        mTag = "BarTransitions." + target.getClass().getSimpleName();
+        mTarget = target;
+        final Resources res = target.getContext().getResources();
+        mOpaque = res.getColor(R.drawable.status_bar_background);
+        mSemiTransparent = res.getColor(R.color.status_bar_background_semi_transparent);
+    }
+
+    public int getMode() {
+        return mMode;
+    }
+
+    public void transitionTo(int mode, boolean animate) {
+        if (mMode == mode) return;
+        int oldMode = mMode;
+        mMode = mode;
+        if (!ActivityManager.isHighEndGfx()) return;
+        if (DEBUG) Log.d(mTag, modeToString(oldMode) + " -> " + modeToString(mode));
+        onTransition(oldMode, mMode, animate);
+    }
+
+    protected Integer getBackgroundColor(int mode) {
+        if (mode == MODE_SEMI_TRANSPARENT) return mSemiTransparent;
+        if (mode == MODE_OPAQUE) return mOpaque;
+        if (mode == MODE_LIGHTS_OUT) return mOpaque;
+        return null;
+    }
+
+    protected void onTransition(int oldMode, int newMode, boolean animate) {
+        cancelBackgroundColorAnimation();
+        Integer oldColor = getBackgroundColor(oldMode);
+        Integer newColor = getBackgroundColor(newMode);
+        if (oldColor != null && newColor != null) {
+            if (animate) {
+                startBackgroundColorAnimation(oldColor, newColor);
+            } else {
+                mTarget.setBackgroundColor(newColor);
+            }
+        } else {
+            mTarget.setBackground(newMode == MODE_TRANSPARENT ? mTransparent
+                    : newMode == MODE_SEMI_TRANSPARENT ? new ColorDrawable(mSemiTransparent)
+                    : new ColorDrawable(mOpaque));
+        }
+    }
+
+    private void startBackgroundColorAnimation(int from, int to) {
+        mBackgroundColorAnimator = ValueAnimator.ofObject(new ArgbEvaluator(), from, to);
+        mBackgroundColorAnimator.addUpdateListener(mBackgroundColorListener);
+        mBackgroundColorAnimator.start();
+    }
+
+    private void cancelBackgroundColorAnimation() {
+        if (mBackgroundColorAnimator != null && mBackgroundColorAnimator.isStarted()) {
+            mBackgroundColorAnimator.cancel();
+            mBackgroundColorAnimator = null;
+        }
+    }
+
+    public static String modeToString(int mode) {
+        if (mode == MODE_OPAQUE) return "MODE_OPAQUE";
+        if (mode == MODE_SEMI_TRANSPARENT) return "MODE_SEMI_TRANSPARENT";
+        if (mode == MODE_TRANSPARENT) return "MODE_TRANSPARENT";
+        if (mode == MODE_LIGHTS_OUT) return "MODE_LIGHTS_OUT";
+        throw new IllegalArgumentException("Unknown mode " + mode);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CarrierLabel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CarrierLabel.java
deleted file mode 100644
index 66494e4..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CarrierLabel.java
+++ /dev/null
@@ -1,115 +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 com.android.systemui.statusbar.phone;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.util.Slog;
-import android.view.View;
-import android.widget.TextView;
-
-import com.android.internal.telephony.TelephonyIntents;
-
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.TimeZone;
-
-import com.android.internal.R;
-
-/**
- * This widget display an analogic clock with two hands for hours and
- * minutes.
- */
-public class CarrierLabel extends TextView {
-    private boolean mAttached;
-
-    public CarrierLabel(Context context) {
-        this(context, null);
-    }
-
-    public CarrierLabel(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public CarrierLabel(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        updateNetworkName(false, null, false, null);
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-
-        if (!mAttached) {
-            mAttached = true;
-            IntentFilter filter = new IntentFilter();
-            filter.addAction(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION);
-            getContext().registerReceiver(mIntentReceiver, filter, null, getHandler());
-        }
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        if (mAttached) {
-            getContext().unregisterReceiver(mIntentReceiver);
-            mAttached = false;
-        }
-    }
-
-    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (TelephonyIntents.SPN_STRINGS_UPDATED_ACTION.equals(action)) {
-                updateNetworkName(intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_SPN, false),
-                        intent.getStringExtra(TelephonyIntents.EXTRA_SPN),
-                        intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_PLMN, false),
-                        intent.getStringExtra(TelephonyIntents.EXTRA_PLMN));
-            }
-        }
-    };
-
-    void updateNetworkName(boolean showSpn, String spn, boolean showPlmn, String plmn) {
-        if (false) {
-            Slog.d("CarrierLabel", "updateNetworkName showSpn=" + showSpn + " spn=" + spn
-                    + " showPlmn=" + showPlmn + " plmn=" + plmn);
-        }
-        final String str;
-        // match logic in KeyguardStatusViewManager
-        final boolean plmnValid = showPlmn && !TextUtils.isEmpty(plmn);
-        final boolean spnValid = showSpn && !TextUtils.isEmpty(spn);
-        if (plmnValid && spnValid) {
-            str = plmn + "|" + spn;
-        } else if (plmnValid) {
-            str = plmn;
-        } else if (spnValid) {
-            str = spn;
-        } else {
-            str = "";
-        }
-        setText(str);
-    }
-
-
-}
-
-
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CloseDragHandle.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CloseDragHandle.java
deleted file mode 100644
index ee01489..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CloseDragHandle.java
+++ /dev/null
@@ -1,53 +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.systemui.statusbar.phone;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.widget.LinearLayout;
-
-
-public class CloseDragHandle extends LinearLayout {
-    PhoneStatusBar mService;
-
-    public CloseDragHandle(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    /**
-     * Ensure that, if there is no target under us to receive the touch,
-     * that we process it ourself.  This makes sure that onInterceptTouchEvent()
-     * is always called for the entire gesture.
-     */
-    @Override
-    public boolean onTouchEvent(MotionEvent event) {
-        if (event.getAction() == MotionEvent.ACTION_DOWN) {
-            setPressed(true);
-        } else {
-            mService.interceptTouchEvent(event);
-        }
-        return true;
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent event) {
-        return mService.interceptTouchEvent(event)
-                ? true : super.onInterceptTouchEvent(event);
-    }
-}
-
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
new file mode 100644
index 0000000..aba7afa
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
@@ -0,0 +1,151 @@
+/*
+ * 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.systemui.statusbar.phone;
+
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+
+import com.android.internal.statusbar.StatusBarIcon;
+import com.android.systemui.DemoMode;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.StatusBarIconView;
+import com.android.systemui.statusbar.policy.LocationController;
+
+public class DemoStatusIcons extends LinearLayout implements DemoMode {
+    private final LinearLayout mStatusIcons;
+    private final int mIconSize;
+
+    private boolean mDemoMode;
+
+    public DemoStatusIcons(LinearLayout statusIcons, int iconSize) {
+        super(statusIcons.getContext());
+        mStatusIcons = statusIcons;
+        mIconSize = iconSize;
+
+        setLayoutParams(mStatusIcons.getLayoutParams());
+        setOrientation(mStatusIcons.getOrientation());
+        setGravity(Gravity.CENTER_VERTICAL); // no LL.getGravity()
+        ViewGroup p = (ViewGroup) mStatusIcons.getParent();
+        p.addView(this, p.indexOfChild(mStatusIcons));
+    }
+
+    @Override
+    public void dispatchDemoCommand(String command, Bundle args) {
+        if (!mDemoMode && command.equals(COMMAND_ENTER)) {
+            mDemoMode = true;
+            mStatusIcons.setVisibility(View.GONE);
+            setVisibility(View.VISIBLE);
+        } else if (mDemoMode && command.equals(COMMAND_EXIT)) {
+            mDemoMode = false;
+            mStatusIcons.setVisibility(View.VISIBLE);
+            setVisibility(View.GONE);
+        } else if (mDemoMode && command.equals(COMMAND_STATUS)) {
+            String volume = args.getString("volume");
+            if (volume != null) {
+                int iconId = volume.equals("silent") ? R.drawable.stat_sys_ringer_silent
+                        : volume.equals("vibrate") ? R.drawable.stat_sys_ringer_vibrate
+                        : 0;
+                updateSlot("volume", null, iconId);
+            }
+            String bt = args.getString("bluetooth");
+            if (bt != null) {
+                int iconId = bt.equals("disconnected") ? R.drawable.stat_sys_data_bluetooth
+                        : bt.equals("connected") ? R.drawable.stat_sys_data_bluetooth_connected
+                        : 0;
+                updateSlot("bluetooth", null, iconId);
+            }
+            String location = args.getString("location");
+            if (location != null) {
+                int iconId = location.equals("show") ? LocationController.LOCATION_STATUS_ICON_ID
+                        : 0;
+                updateSlot(LocationController.LOCATION_STATUS_ICON_PLACEHOLDER, null, iconId);
+            }
+            String alarm = args.getString("alarm");
+            if (alarm != null) {
+                int iconId = alarm.equals("show") ? R.drawable.stat_sys_alarm
+                        : 0;
+                updateSlot("alarm_clock", null, iconId);
+            }
+            String sync = args.getString("sync");
+            if (sync != null) {
+                int iconId = sync.equals("show") ? R.drawable.stat_sys_sync
+                        : 0;
+                updateSlot("sync_active", null, iconId);
+            }
+            String tty = args.getString("tty");
+            if (tty != null) {
+                int iconId = tty.equals("show") ? R.drawable.stat_sys_tty_mode
+                        : 0;
+                updateSlot("tty", null, iconId);
+            }
+            String eri = args.getString("eri");
+            if (eri != null) {
+                int iconId = eri.equals("show") ? R.drawable.stat_sys_roaming_cdma_0
+                        : 0;
+                updateSlot("cdma_eri", null, iconId);
+            }
+            String mute = args.getString("mute");
+            if (mute != null) {
+                int iconId = mute.equals("show") ? android.R.drawable.stat_notify_call_mute
+                        : 0;
+                updateSlot("mute", null, iconId);
+            }
+            String speakerphone = args.getString("speakerphone");
+            if (speakerphone != null) {
+                int iconId = speakerphone.equals("show") ? android.R.drawable.stat_sys_speakerphone
+                        : 0;
+                updateSlot("speakerphone", null, iconId);
+            }
+        }
+    }
+
+    private void updateSlot(String slot, String iconPkg, int iconId) {
+        if (!mDemoMode) return;
+        int removeIndex = -1;
+        for (int i = 0; i < getChildCount(); i++) {
+            StatusBarIconView v = (StatusBarIconView) getChildAt(i);
+            if (slot.equals(v.getTag())) {
+                if (iconId == 0) {
+                    removeIndex = i;
+                    break;
+                } else {
+                    StatusBarIcon icon = v.getStatusBarIcon();
+                    icon.iconPackage = iconPkg;
+                    icon.iconId = iconId;
+                    v.set(icon);
+                    v.updateDrawable();
+                    return;
+                }
+            }
+        }
+        if (iconId == 0) {
+            if (removeIndex != -1) {
+                removeViewAt(removeIndex);
+                return;
+            }
+        }
+        StatusBarIcon icon = new StatusBarIcon(iconPkg, UserHandle.CURRENT, iconId, 0, 0, "Demo");
+        StatusBarIconView v = new StatusBarIconView(mContext, null);
+        v.setTag(slot);
+        v.set(icon);
+        addView(v, 0, new LinearLayout.LayoutParams(mIconSize, mIconSize));
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java
index 0640282..50ead3d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java
@@ -17,16 +17,11 @@
 package com.android.systemui.statusbar.phone;
 
 import android.content.Context;
-import android.os.Handler;
 import android.util.AttributeSet;
-import android.util.Slog;
 import android.view.View;
 import android.widget.LinearLayout;
 
-import com.android.internal.statusbar.StatusBarIcon;
-
 import com.android.systemui.R;
-import com.android.systemui.statusbar.StatusBarIconView;
 
 public class IconMerger extends LinearLayout {
     private static final String TAG = "IconMerger";
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
new file mode 100644
index 0000000..085130b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
@@ -0,0 +1,163 @@
+/*
+ * 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.systemui.statusbar.phone;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.GradientDrawable;
+import android.graphics.drawable.GradientDrawable.Orientation;
+import android.os.ServiceManager;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.animation.AccelerateInterpolator;
+
+import com.android.internal.statusbar.IStatusBarService;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.policy.KeyButtonView;
+
+public final class NavigationBarTransitions extends BarTransitions {
+    private static final boolean ENABLE_GRADIENT = false;  // until we can smooth transition
+
+    private final NavigationBarView mView;
+    private final Drawable mTransparentBottom;
+    private final Drawable mTransparentRight;
+    private final int mTransparentColor;
+    private final IStatusBarService mBarService;
+
+    private boolean mLightsOut;
+
+    public NavigationBarTransitions(NavigationBarView view) {
+        super(view);
+        mView = view;
+        final Resources res = mView.getContext().getResources();
+        final int[] gradientColors = new int[] {
+                res.getColor(R.color.navigation_bar_background_transparent_start),
+                res.getColor(R.color.navigation_bar_background_transparent_end)
+        };
+        mTransparentBottom = new GradientDrawable(Orientation.BOTTOM_TOP, gradientColors);
+        mTransparentRight = new GradientDrawable(Orientation.RIGHT_LEFT, gradientColors);
+        mTransparentColor = res.getColor(R.color.status_bar_background_transparent);
+        mBarService = IStatusBarService.Stub.asInterface(
+                ServiceManager.getService(Context.STATUS_BAR_SERVICE));
+    }
+
+    public void setVertical(boolean isVertical) {
+        if (!ENABLE_GRADIENT) return;
+        mTransparent = isVertical ? mTransparentRight : mTransparentBottom;
+    }
+
+    @Override
+    protected Integer getBackgroundColor(int mode) {
+        if (!ENABLE_GRADIENT && mode == MODE_TRANSPARENT) return mTransparentColor;
+        return super.getBackgroundColor(mode);
+    }
+
+    @Override
+    protected void onTransition(int oldMode, int newMode, boolean animate) {
+        super.onTransition(oldMode, newMode, animate);
+        applyMode(newMode, animate, false /*force*/);
+    }
+
+    public void reapplyMode() {
+        applyMode(getMode(), false /*animate*/, true /*force*/);
+    }
+
+    private void applyMode(int mode, boolean animate, boolean force) {
+        // apply to key buttons
+        final boolean isOpaque = mode == MODE_OPAQUE || mode == MODE_LIGHTS_OUT;
+        final float alpha = isOpaque ? KeyButtonView.DEFAULT_QUIESCENT_ALPHA : 1f;
+        setKeyButtonViewQuiescentAlpha(mView.getBackButton(), alpha, animate);
+        setKeyButtonViewQuiescentAlpha(mView.getHomeButton(), alpha, animate);
+        setKeyButtonViewQuiescentAlpha(mView.getRecentsButton(), alpha, animate);
+        setKeyButtonViewQuiescentAlpha(mView.getMenuButton(), alpha, animate);
+
+        // apply to lights out
+        applyLightsOut(mode == MODE_LIGHTS_OUT, animate, force);
+    }
+
+    private void setKeyButtonViewQuiescentAlpha(View button, float alpha, boolean animate) {
+        if (button instanceof KeyButtonView) {
+            ((KeyButtonView) button).setQuiescentAlpha(alpha, animate);
+        }
+    }
+
+    private void applyLightsOut(boolean lightsOut, boolean animate, boolean force) {
+        if (!force && lightsOut == mLightsOut) return;
+
+        mLightsOut = lightsOut;
+
+        final View navButtons = mView.getCurrentView().findViewById(R.id.nav_buttons);
+        final View lowLights = mView.getCurrentView().findViewById(R.id.lights_out);
+
+        // ok, everyone, stop it right there
+        navButtons.animate().cancel();
+        lowLights.animate().cancel();
+
+        final float navButtonsAlpha = lightsOut ? 0f : 1f;
+        final float lowLightsAlpha = lightsOut ? 1f : 0f;
+
+        if (!animate) {
+            navButtons.setAlpha(navButtonsAlpha);
+            lowLights.setAlpha(lowLightsAlpha);
+            lowLights.setVisibility(lightsOut ? View.VISIBLE : View.GONE);
+        } else {
+            final int duration = lightsOut ? LIGHTS_OUT_DURATION : LIGHTS_IN_DURATION;
+            navButtons.animate()
+                .alpha(navButtonsAlpha)
+                .setDuration(duration)
+                .start();
+
+            lowLights.setOnTouchListener(mLightsOutListener);
+            if (lowLights.getVisibility() == View.GONE) {
+                lowLights.setAlpha(0f);
+                lowLights.setVisibility(View.VISIBLE);
+            }
+            lowLights.animate()
+                .alpha(lowLightsAlpha)
+                .setDuration(duration)
+                .setInterpolator(new AccelerateInterpolator(2.0f))
+                .setListener(lightsOut ? null : new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationEnd(Animator _a) {
+                        lowLights.setVisibility(View.GONE);
+                    }
+                })
+                .start();
+        }
+    }
+
+    private final View.OnTouchListener mLightsOutListener = new View.OnTouchListener() {
+        @Override
+        public boolean onTouch(View v, MotionEvent ev) {
+            if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+                // even though setting the systemUI visibility below will turn these views
+                // on, we need them to come up faster so that they can catch this motion
+                // event
+                applyLightsOut(false, false, false);
+
+                try {
+                    mBarService.setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE);
+                } catch (android.os.RemoteException ex) {
+                }
+            }
+            return false;
+        }
+    };
+}
\ No newline at end of file
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 54c4666..4683030 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -16,8 +16,6 @@
 
 package com.android.systemui.statusbar.phone;
 
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
 import android.animation.LayoutTransition;
 import android.app.StatusBarManager;
 import android.content.Context;
@@ -27,28 +25,25 @@
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
 import android.os.Message;
-import android.os.ServiceManager;
 import android.util.AttributeSet;
-import android.util.Slog;
-import android.view.animation.AccelerateInterpolator;
+import android.util.Log;
 import android.view.Display;
 import android.view.MotionEvent;
-import android.view.View;
 import android.view.Surface;
+import android.view.View;
 import android.view.ViewGroup;
 import android.view.WindowManager;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-import com.android.internal.statusbar.IStatusBarService;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.BaseStatusBar;
 import com.android.systemui.statusbar.DelegateViewHelper;
 import com.android.systemui.statusbar.policy.DeadZone;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
 public class NavigationBarView extends LinearLayout {
     final static boolean DEBUG = false;
     final static String TAG = "PhoneStatusBar/NavigationBarView";
@@ -56,11 +51,8 @@
     final static boolean NAVBAR_ALWAYS_AT_RIGHT = true;
 
     // slippery nav bar when everything is disabled, e.g. during setup
-    final static boolean SLIPPERY_WHEN_DISABLED= true;
+    final static boolean SLIPPERY_WHEN_DISABLED = true;
 
-    final static boolean ANIMATE_HIDE_TRANSITION = false; // turned off because it introduces unsightly delay when videos goes to full screen
-
-    protected IStatusBarService mBarService;
     final Display mDisplay;
     View mCurrentView = null;
     View[] mRotatedViews = new View[4];
@@ -69,7 +61,7 @@
     boolean mVertical;
     boolean mScreenOn;
 
-    boolean mHidden, mLowProfile, mShowMenu;
+    boolean mShowMenu;
     int mDisabledFlags = 0;
     int mNavigationIconHints = 0;
 
@@ -79,6 +71,7 @@
 
     private DelegateViewHelper mDelegateHelper;
     private DeadZone mDeadZone;
+    private final NavigationBarTransitions mBarTransitions;
 
     // workaround for LayoutTransitions leaving the nav buttons in a weird state (bug 5549288)
     final static boolean WORKAROUND_INVALID_LAYOUT = true;
@@ -95,7 +88,7 @@
                     final int vh = mCurrentView.getHeight();
 
                     if (h != vh || w != vw) {
-                        Slog.w(TAG, String.format(
+                        Log.w(TAG, String.format(
                             "*** Invalid layout in navigation bar (%s this=%dx%d cur=%dx%d)",
                             how, w, h, vw, vh));
                         if (WORKAROUND_INVALID_LAYOUT) {
@@ -107,6 +100,27 @@
         }
     }
 
+    public NavigationBarView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        mDisplay = ((WindowManager)context.getSystemService(
+                Context.WINDOW_SERVICE)).getDefaultDisplay();
+
+        final Resources res = mContext.getResources();
+        mBarSize = res.getDimensionPixelSize(R.dimen.navigation_bar_size);
+        mVertical = false;
+        mShowMenu = false;
+        mDelegateHelper = new DelegateViewHelper(this);
+
+        getIcons(res);
+
+        mBarTransitions = new NavigationBarTransitions(this);
+    }
+
+    public BarTransitions getBarTransitions() {
+        return mBarTransitions;
+    }
+
     public void setDelegateView(View view) {
         mDelegateHelper.setDelegateView(view);
     }
@@ -134,6 +148,10 @@
 
     private H mHandler = new H();
 
+    public View getCurrentView() {
+        return mCurrentView;
+    }
+
     public View getRecentsButton() {
         return mCurrentView.findViewById(R.id.recent_apps);
     }
@@ -155,25 +173,6 @@
         return mCurrentView.findViewById(R.id.search_light);
     }
 
-    public NavigationBarView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-
-        mHidden = false;
-
-        mDisplay = ((WindowManager)context.getSystemService(
-                Context.WINDOW_SERVICE)).getDefaultDisplay();
-        mBarService = IStatusBarService.Stub.asInterface(
-                ServiceManager.getService(Context.STATUS_BAR_SERVICE));
-
-        final Resources res = mContext.getResources();
-        mBarSize = res.getDimensionPixelSize(R.dimen.navigation_bar_size);
-        mVertical = false;
-        mShowMenu = false;
-        mDelegateHelper = new DelegateViewHelper(this);
-
-        getIcons(res);
-    }
-
     private void getIcons(Resources res) {
         mBackIcon = res.getDrawable(R.drawable.ic_sysbar_back);
         mBackLandIcon = res.getDrawable(R.drawable.ic_sysbar_back_land);
@@ -195,24 +194,6 @@
         setDisabledFlags(mDisabledFlags, true);
     }
 
-    View.OnTouchListener mLightsOutListener = new View.OnTouchListener() {
-        @Override
-        public boolean onTouch(View v, MotionEvent ev) {
-            if (ev.getAction() == MotionEvent.ACTION_DOWN) {
-                // even though setting the systemUI visibility below will turn these views
-                // on, we need them to come up faster so that they can catch this motion
-                // event
-                setLowProfile(false, false, false);
-
-                try {
-                    mBarService.setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE);
-                } catch (android.os.RemoteException ex) {
-                }
-            }
-            return false;
-        }
-    };
-
     public void setNavigationIconHints(int hints) {
         setNavigationIconHints(hints, false);
     }
@@ -309,72 +290,13 @@
         getMenuButton().setVisibility(mShowMenu ? View.VISIBLE : View.INVISIBLE);
     }
 
-    public void setLowProfile(final boolean lightsOut) {
-        setLowProfile(lightsOut, true, false);
-    }
-
-    public void setLowProfile(final boolean lightsOut, final boolean animate, final boolean force) {
-        if (!force && lightsOut == mLowProfile) return;
-
-        mLowProfile = lightsOut;
-
-        if (DEBUG) Slog.d(TAG, "setting lights " + (lightsOut?"out":"on"));
-
-        final View navButtons = mCurrentView.findViewById(R.id.nav_buttons);
-        final View lowLights = mCurrentView.findViewById(R.id.lights_out);
-
-        // ok, everyone, stop it right there
-        navButtons.animate().cancel();
-        lowLights.animate().cancel();
-
-        if (!animate) {
-            navButtons.setAlpha(lightsOut ? 0f : 1f);
-
-            lowLights.setAlpha(lightsOut ? 1f : 0f);
-            lowLights.setVisibility(lightsOut ? View.VISIBLE : View.GONE);
-        } else {
-            navButtons.animate()
-                .alpha(lightsOut ? 0f : 1f)
-                .setDuration(lightsOut ? 750 : 250)
-                .start();
-
-            lowLights.setOnTouchListener(mLightsOutListener);
-            if (lowLights.getVisibility() == View.GONE) {
-                lowLights.setAlpha(0f);
-                lowLights.setVisibility(View.VISIBLE);
-            }
-            lowLights.animate()
-                .alpha(lightsOut ? 1f : 0f)
-                .setDuration(lightsOut ? 750 : 250)
-                .setInterpolator(new AccelerateInterpolator(2.0f))
-                .setListener(lightsOut ? null : new AnimatorListenerAdapter() {
-                    @Override
-                    public void onAnimationEnd(Animator _a) {
-                        lowLights.setVisibility(View.GONE);
-                    }
-                })
-                .start();
-        }
-    }
-
-    public void setHidden(final boolean hide) {
-        if (hide == mHidden) return;
-
-        mHidden = hide;
-        Slog.d(TAG,
-            (hide ? "HIDING" : "SHOWING") + " navigation bar");
-
-        // bring up the lights no matter what
-        setLowProfile(false);
-    }
-
     @Override
     public void onFinishInflate() {
-        mRotatedViews[Surface.ROTATION_0] = 
+        mRotatedViews[Surface.ROTATION_0] =
         mRotatedViews[Surface.ROTATION_180] = findViewById(R.id.rot0);
 
         mRotatedViews[Surface.ROTATION_90] = findViewById(R.id.rot90);
-        
+
         mRotatedViews[Surface.ROTATION_270] = NAVBAR_ALWAYS_AT_RIGHT
                                                 ? findViewById(R.id.rot90)
                                                 : findViewById(R.id.rot270);
@@ -382,6 +304,10 @@
         mCurrentView = mRotatedViews[Surface.ROTATION_0];
     }
 
+    public boolean isVertical() {
+        return mVertical;
+    }
+
     public void reorient() {
         final int rot = mDisplay.getRotation();
         for (int i=0; i<4; i++) {
@@ -393,15 +319,16 @@
         mDeadZone = (DeadZone) mCurrentView.findViewById(R.id.deadzone);
 
         // force the low profile & disabled states into compliance
-        setLowProfile(mLowProfile, false, true /* force */);
+        mBarTransitions.reapplyMode();
         setDisabledFlags(mDisabledFlags, true /* force */);
         setMenuVisibility(mShowMenu, true /* force */);
 
         if (DEBUG) {
-            Slog.d(TAG, "reorient(): rot=" + mDisplay.getRotation());
+            Log.d(TAG, "reorient(): rot=" + mDisplay.getRotation());
         }
 
         setNavigationIconHints(mNavigationIconHints, true);
+        mBarTransitions.setVertical(mVertical);
     }
 
     @Override
@@ -412,13 +339,13 @@
 
     @Override
     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
-        if (DEBUG) Slog.d(TAG, String.format(
+        if (DEBUG) Log.d(TAG, String.format(
                     "onSizeChanged: (%dx%d) old: (%dx%d)", w, h, oldw, oldh));
 
         final boolean newVertical = w > 0 && h > w;
         if (newVertical != mVertical) {
             mVertical = newVertical;
-            //Slog.v(TAG, String.format("onSizeChanged: h=%d, w=%d, vert=%s", h, w, mVertical?"y":"n"));
+            //Log.v(TAG, String.format("onSizeChanged: h=%d, w=%d, vert=%s", h, w, mVertical?"y":"n"));
             reorient();
         }
 
@@ -429,8 +356,8 @@
     /*
     @Override
     protected void onLayout (boolean changed, int left, int top, int right, int bottom) {
-        if (DEBUG) Slog.d(TAG, String.format(
-                    "onLayout: %s (%d,%d,%d,%d)", 
+        if (DEBUG) Log.d(TAG, String.format(
+                    "onLayout: %s (%d,%d,%d,%d)",
                     changed?"changed":"notchanged", left, top, right, bottom));
         super.onLayout(changed, left, top, right, bottom);
     }
@@ -439,14 +366,14 @@
     // fails, any touch on the display will fix the layout.
     @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
-        if (DEBUG) Slog.d(TAG, "onInterceptTouchEvent: " + ev.toString());
+        if (DEBUG) Log.d(TAG, "onInterceptTouchEvent: " + ev.toString());
         if (ev.getAction() == MotionEvent.ACTION_DOWN) {
             postCheckForInvalidLayout("touch");
         }
         return super.onInterceptTouchEvent(ev);
     }
     */
-        
+
 
     private String getResourceName(int resId) {
         if (resId != 0) {
@@ -487,7 +414,7 @@
 
         getWindowVisibleDisplayFrame(r);
         final boolean offscreen = r.right > size.x || r.bottom > size.y;
-        pw.println("      window: " 
+        pw.println("      window: "
                 + r.toShortString()
                 + " " + visibilityToString(getWindowVisibility())
                 + (offscreen ? " OFFSCREEN!" : ""));
@@ -500,8 +427,6 @@
         pw.println(String.format("      disabled=0x%08x vertical=%s hidden=%s low=%s menu=%s",
                         mDisabledFlags,
                         mVertical ? "true" : "false",
-                        mHidden ? "true" : "false",
-                        mLowProfile ? "true" : "false",
                         mShowMenu ? "true" : "false"));
 
         final View back = getBackButton();
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 f33dc20..6be6d4d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -22,7 +22,6 @@
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.util.EventLog;
-import android.util.Slog;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.accessibility.AccessibilityEvent;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
index 565a3f2..a3e35d1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
@@ -16,21 +16,21 @@
 
 package com.android.systemui.statusbar.phone;
 
-import java.util.ArrayList;
-
 import android.content.Context;
 import android.util.AttributeSet;
-import android.util.Slog;
+import android.util.Log;
 import android.view.MotionEvent;
 import android.view.View;
 import android.widget.FrameLayout;
 
+import java.util.ArrayList;
+
 public class PanelBar extends FrameLayout {
     public static final boolean DEBUG = false;
     public static final String TAG = PanelBar.class.getSimpleName();
     public static final void LOG(String fmt, Object... args) {
         if (!DEBUG) return;
-        Slog.v(TAG, String.format(fmt, args));
+        Log.v(TAG, String.format(fmt, args));
     }
 
     public static final int STATE_CLOSED = 0;
@@ -66,7 +66,7 @@
 
     public void setPanelHolder(PanelHolder ph) {
         if (ph == null) {
-            Slog.e(TAG, "setPanelHolder: null PanelHolder", new Throwable());
+            Log.e(TAG, "setPanelHolder: null PanelHolder", new Throwable());
             return;
         }
         ph.setBar(this);
@@ -98,7 +98,7 @@
         // Allow subclasses to implement enable/disable semantics
         if (!panelsEnabled()) {
             if (event.getAction() == MotionEvent.ACTION_DOWN) {
-                Slog.v(TAG, String.format("onTouch: all panels disabled, ignoring touch at (%d,%d)",
+                Log.v(TAG, String.format("onTouch: all panels disabled, ignoring touch at (%d,%d)",
                         (int) event.getX(), (int) event.getY()));
             }
             return false;
@@ -109,7 +109,7 @@
             final PanelView panel = selectPanelForTouch(event);
             if (panel == null) {
                 // panel is not there, so we'll eat the gesture
-                Slog.v(TAG, String.format("onTouch: no panel for touch at (%d,%d)",
+                Log.v(TAG, String.format("onTouch: no panel for touch at (%d,%d)",
                         (int) event.getX(), (int) event.getY()));
                 mTouchingPanel = null;
                 return true;
@@ -119,7 +119,7 @@
                     (enabled ? "" : " (disabled)"));
             if (!enabled) {
                 // panel is disabled, so we'll eat the gesture
-                Slog.v(TAG, String.format(
+                Log.v(TAG, String.format(
                         "onTouch: panel (%s) is disabled, ignoring touch at (%d,%d)",
                         panel, (int) event.getX(), (int) event.getY()));
                 mTouchingPanel = null;
@@ -194,11 +194,12 @@
             } else {
                 pv.setExpandedFraction(0); // just in case
                 pv.setVisibility(View.GONE);
+                pv.cancelPeek();
             }
         }
         if (DEBUG) LOG("collapseAllPanels: animate=%s waiting=%s", animate, waiting);
         if (!waiting && mState != STATE_CLOSED) {
-            // it's possible that nothing animated, so we replicate the termination 
+            // it's possible that nothing animated, so we replicate the termination
             // conditions of panelExpansionChanged here
             go(STATE_CLOSED);
             onAllPanelsCollapsed();
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 e351429..4b2c3e1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -16,33 +16,32 @@
 
 package com.android.systemui.statusbar.phone;
 
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayDeque;
-import java.util.Iterator;
-
 import android.animation.ObjectAnimator;
 import android.animation.TimeAnimator;
 import android.animation.TimeAnimator.TimeListener;
 import android.content.Context;
 import android.content.res.Resources;
 import android.util.AttributeSet;
-import android.util.Slog;
+import android.util.Log;
 import android.view.MotionEvent;
 import android.view.View;
 import android.widget.FrameLayout;
 
 import com.android.systemui.R;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayDeque;
+import java.util.Iterator;
+
 public class PanelView extends FrameLayout {
     public static final boolean DEBUG = PanelBar.DEBUG;
     public static final String TAG = PanelView.class.getSimpleName();
 
     public static final boolean DEBUG_NAN = true; // http://b/7686690
 
-    public final void LOG(String fmt, Object... args) {
-        if (!DEBUG) return;
-        Slog.v(TAG, (mViewName != null ? (mViewName + ": ") : "") + String.format(fmt, args));
+    private final void logf(String fmt, Object... args) {
+        Log.v(TAG, (mViewName != null ? (mViewName + ": ") : "") + String.format(fmt, args));
     }
 
     public static final boolean BRAKES = false;
@@ -77,6 +76,7 @@
     private boolean mClosing;
     private boolean mRubberbanding;
     private boolean mTracking;
+    private int mTrackingPointer;
 
     private TimeAnimator mTimeAnimator;
     private ObjectAnimator mPeekAnimator;
@@ -112,14 +112,14 @@
         }
         public void computeCurrentVelocity(long timebase) {
             if (FlingTracker.DEBUG) {
-                Slog.v("FlingTracker", "computing velocities for " + mEventBuf.size() + " events");
+                Log.v("FlingTracker", "computing velocities for " + mEventBuf.size() + " events");
             }
             mVX = mVY = 0;
             MotionEventCopy last = null;
             int i = 0;
             float totalweight = 0f;
             float weight = 10f;
-            for (final Iterator<MotionEventCopy> iter = mEventBuf.descendingIterator();
+            for (final Iterator<MotionEventCopy> iter = mEventBuf.iterator();
                     iter.hasNext();) {
                 final MotionEventCopy event = iter.next();
                 if (last != null) {
@@ -127,13 +127,22 @@
                     final float dx = (event.x - last.x);
                     final float dy = (event.y - last.y);
                     if (FlingTracker.DEBUG) {
-                        Slog.v("FlingTracker", String.format("   [%d] dx=%.1f dy=%.1f dt=%.0f vx=%.1f vy=%.1f",
-                                i,
+                        Log.v("FlingTracker", String.format(
+                                "   [%d] (t=%d %.1f,%.1f) dx=%.1f dy=%.1f dt=%f vx=%.1f vy=%.1f",
+                                i, event.t, event.x, event.y,
                                 dx, dy, dt,
                                 (dx/dt),
                                 (dy/dt)
                                 ));
                     }
+                    if (event.t == last.t) {
+                        // Really not sure what to do with events that happened at the same time,
+                        // so we'll skip subsequent events.
+                        if (DEBUG_NAN) {
+                            Log.v("FlingTracker", "skipping simultaneous event at t=" + event.t);
+                        }
+                        continue;
+                    }
                     mVX += weight * dx / dt;
                     mVY += weight * dy / dt;
                     totalweight += weight;
@@ -147,7 +156,7 @@
                 mVY /= totalweight;
             } else {
                 if (DEBUG_NAN) {
-                    Slog.v("FlingTracker", "computeCurrentVelocity warning: totalweight=0",
+                    Log.v("FlingTracker", "computeCurrentVelocity warning: totalweight=0",
                             new Throwable());
                 }
                 // so as not to contaminate the velocities with NaN
@@ -155,22 +164,22 @@
             }
 
             if (FlingTracker.DEBUG) {
-                Slog.v("FlingTracker", "computed: vx=" + mVX + " vy=" + mVY);
+                Log.v("FlingTracker", "computed: vx=" + mVX + " vy=" + mVY);
             }
         }
         public float getXVelocity() {
-            if (Float.isNaN(mVX)) {
+            if (Float.isNaN(mVX) || Float.isInfinite(mVX)) {
                 if (DEBUG_NAN) {
-                    Slog.v("FlingTracker", "warning: vx=NaN");
+                    Log.v("FlingTracker", "warning: vx=" + mVX);
                 }
                 mVX = 0;
             }
             return mVX;
         }
         public float getYVelocity() {
-            if (Float.isNaN(mVY)) {
+            if (Float.isNaN(mVY) || Float.isInfinite(mVX)) {
                 if (DEBUG_NAN) {
-                    Slog.v("FlingTracker", "warning: vx=NaN");
+                    Log.v("FlingTracker", "warning: vx=" + mVY);
                 }
                 mVY = 0;
             }
@@ -221,12 +230,12 @@
     }
 
     private void runPeekAnimation() {
-        if (DEBUG) LOG("peek to height=%.1f", mPeekHeight);
+        if (DEBUG) logf("peek to height=%.1f", mPeekHeight);
         if (mTimeAnimator.isStarted()) {
             return;
         }
         if (mPeekAnimator == null) {
-            mPeekAnimator = ObjectAnimator.ofFloat(this, 
+            mPeekAnimator = ObjectAnimator.ofFloat(this,
                     "expandedHeight", mPeekHeight)
                 .setDuration(250);
         }
@@ -256,8 +265,8 @@
             }
         } else if (dtms > 0) {
             final float dt = dtms * 0.001f;                  // ms -> s
-            if (DEBUG) LOG("tick: v=%.2fpx/s dt=%.4fs", mVel, dt);
-            if (DEBUG) LOG("tick: before: h=%d", (int) mExpandedHeight);
+            if (DEBUG) logf("tick: v=%.2fpx/s dt=%.4fs", mVel, dt);
+            if (DEBUG) logf("tick: before: h=%d", (int) mExpandedHeight);
 
             final float fh = getFullHeight();
             boolean braking = false;
@@ -295,7 +304,7 @@
                 h = fh;
             }
 
-            if (DEBUG) LOG("tick: new h=%d closing=%s", (int) h, mClosing?"true":"false");
+            if (DEBUG) logf("tick: new h=%d closing=%s", (int) h, mClosing?"true":"false");
 
             setExpandedHeightInternal(h);
 
@@ -307,7 +316,7 @@
                 post(mStopAnimator);
             }
         } else {
-            Slog.v(TAG, "animationTick called with dtms=" + dtms + "; nothing to do (h="
+            Log.v(TAG, "animationTick called with dtms=" + dtms + "; nothing to do (h="
                     + mExpandedHeight + " v=" + mVel + ")");
         }
     }
@@ -339,7 +348,7 @@
 
         mFlingGestureMaxOutputVelocityPx = res.getDimension(R.dimen.fling_gesture_max_output_velocity);
 
-        mPeekHeight = res.getDimension(R.dimen.peek_height) 
+        mPeekHeight = res.getDimension(R.dimen.peek_height)
             + getPaddingBottom() // our window might have a dropshadow
             - (mHandleView == null ? 0 : mHandleView.getPaddingTop()); // the handle might have a topshadow
     }
@@ -367,19 +376,26 @@
 
         loadDimens();
 
-        if (DEBUG) LOG("handle view: " + mHandleView);
+        if (DEBUG) logf("handle view: " + mHandleView);
         if (mHandleView != null) {
             mHandleView.setOnTouchListener(new View.OnTouchListener() {
                 @Override
                 public boolean onTouch(View v, MotionEvent event) {
-                    final float y = event.getY();
-                    final float rawY = event.getRawY();
-                    if (DEBUG) LOG("handle.onTouch: a=%s y=%.1f rawY=%.1f off=%.1f",
+                    int pointerIndex = event.findPointerIndex(mTrackingPointer);
+                    if (pointerIndex < 0) {
+                        pointerIndex = 0;
+                        mTrackingPointer = event.getPointerId(pointerIndex);
+                    }
+                    final float y = event.getY(pointerIndex);
+                    final float rawDelta = event.getRawY() - event.getY();
+                    final float rawY = y + rawDelta;
+                    if (DEBUG) logf("handle.onTouch: a=%s p=[%d,%d] y=%.1f rawY=%.1f off=%.1f",
                             MotionEvent.actionToString(event.getAction()),
+                            mTrackingPointer, pointerIndex,
                             y, rawY, mTouchOffset);
                     PanelView.this.getLocationOnScreen(mAbsPos);
 
-                    switch (event.getAction()) {
+                    switch (event.getActionMasked()) {
                         case MotionEvent.ACTION_DOWN:
                             mTracking = true;
                             mHandleView.setPressed(true);
@@ -389,13 +405,26 @@
                             trackMovement(event);
                             mTimeAnimator.cancel(); // end any outstanding animations
                             mBar.onTrackingStarted(PanelView.this);
-                            mTouchOffset = (rawY - mAbsPos[1]) - PanelView.this.getExpandedHeight();
+                            mTouchOffset = (rawY - mAbsPos[1]) - mExpandedHeight;
                             if (mExpandedHeight == 0) {
                                 mJustPeeked = true;
                                 runPeekAnimation();
                             }
                             break;
 
+                        case MotionEvent.ACTION_POINTER_UP:
+                            final int upPointer = event.getPointerId(event.getActionIndex());
+                            if (mTrackingPointer == upPointer) {
+                                // gesture is ongoing, find a new pointer to track
+                                final int newIndex = event.getPointerId(0) != upPointer ? 0 : 1;
+                                final float newY = event.getY(newIndex);
+                                final float newRawY = newY + rawDelta;
+                                mTrackingPointer = event.getPointerId(newIndex);
+                                mTouchOffset = (newRawY - mAbsPos[1]) - mExpandedHeight;
+                                mInitialTouchY = newY;
+                            }
+                            break;
+
                         case MotionEvent.ACTION_MOVE:
                             final float h = rawY - mAbsPos[1] - mTouchOffset;
                             if (h > mPeekHeight) {
@@ -416,6 +445,7 @@
                         case MotionEvent.ACTION_CANCEL:
                             mFinalTouchY = y;
                             mTracking = false;
+                            mTrackingPointer = -1;
                             mHandleView.setPressed(false);
                             postInvalidate(); // catch the press state change
                             mBar.onTrackingStopped(PanelView.this);
@@ -461,7 +491,7 @@
                                 vel = -vel;
                             }
 
-                            if (DEBUG) LOG("gesture: dy=%f vel=(%f,%f) vlinear=%f",
+                            if (DEBUG) logf("gesture: dy=%f vel=(%f,%f) vlinear=%f",
                                     deltaY,
                                     xVel, yVel,
                                     vel);
@@ -476,7 +506,7 @@
     }
 
     public void fling(float vel, boolean always) {
-        if (DEBUG) LOG("fling: vel=%.3f, this=%s", vel, this);
+        if (DEBUG) logf("fling: vel=%.3f, this=%s", vel, this);
         mVel = vel;
 
         if (always||mVel != 0) {
@@ -496,7 +526,7 @@
 
     @Override
     protected void onViewAdded(View child) {
-        if (DEBUG) LOG("onViewAdded: " + child);
+        if (DEBUG) logf("onViewAdded: " + child);
     }
 
     public View getHandle() {
@@ -508,7 +538,7 @@
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
 
-        if (DEBUG) LOG("onMeasure(%d, %d) -> (%d, %d)",
+        if (DEBUG) logf("onMeasure(%d, %d) -> (%d, %d)",
                 widthMeasureSpec, heightMeasureSpec, getMeasuredWidth(), getMeasuredHeight());
 
         // Did one of our children change size?
@@ -528,7 +558,7 @@
 
 
     public void setExpandedHeight(float height) {
-        if (DEBUG) LOG("setExpandedHeight(%.1f)", height);
+        if (DEBUG) logf("setExpandedHeight(%.1f)", height);
         mRubberbanding = false;
         if (mTimeAnimator.isStarted()) {
             post(mStopAnimator);
@@ -539,7 +569,7 @@
 
     @Override
     protected void onLayout (boolean changed, int left, int top, int right, int bottom) {
-        if (DEBUG) LOG("onLayout: changed=%s, bottom=%d eh=%d fh=%d", changed?"T":"f", bottom, (int)mExpandedHeight, mFullHeight);
+        if (DEBUG) logf("onLayout: changed=%s, bottom=%d eh=%d fh=%d", changed?"T":"f", bottom, (int)mExpandedHeight, mFullHeight);
         super.onLayout(changed, left, top, right, bottom);
     }
 
@@ -547,7 +577,7 @@
         if (Float.isNaN(h)) {
             // If a NaN gets in here, it will freeze the Animators.
             if (DEBUG_NAN) {
-                Slog.v(TAG, "setExpandedHeightInternal: warning: h=NaN, using 0 instead",
+                Log.v(TAG, "setExpandedHeightInternal: warning: h=NaN, using 0 instead",
                         new Throwable());
             }
             h = 0;
@@ -563,7 +593,7 @@
 
         mExpandedHeight = h;
 
-        if (DEBUG) LOG("setExpansion: height=%.1f fh=%.1f tracking=%s rubber=%s", h, fh, mTracking?"T":"f", mRubberbanding?"T":"f");
+        if (DEBUG) logf("setExpansion: height=%.1f fh=%.1f tracking=%s rubber=%s", h, fh, mTracking?"T":"f", mRubberbanding?"T":"f");
 
         requestLayout();
 //        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
@@ -575,7 +605,7 @@
 
     private float getFullHeight() {
         if (mFullHeight <= 0) {
-            if (DEBUG) LOG("Forcing measure() since fullHeight=" + mFullHeight);
+            if (DEBUG) logf("Forcing measure() since fullHeight=" + mFullHeight);
             measure(MeasureSpec.makeMeasureSpec(android.view.ViewGroup.LayoutParams.WRAP_CONTENT, MeasureSpec.EXACTLY),
                     MeasureSpec.makeMeasureSpec(android.view.ViewGroup.LayoutParams.WRAP_CONTENT, MeasureSpec.EXACTLY));
         }
@@ -586,7 +616,7 @@
         if (Float.isNaN(frac)) {
             // If a NaN gets in here, it will freeze the Animators.
             if (DEBUG_NAN) {
-                Slog.v(TAG, "setExpandedFraction: frac=NaN, using 0 instead",
+                Log.v(TAG, "setExpandedFraction: frac=NaN, using 0 instead",
                         new Throwable());
             }
             frac = 0;
@@ -614,13 +644,17 @@
         return mClosing;
     }
 
+    public boolean isTracking() {
+        return mTracking;
+    }
+
     public void setBar(PanelBar panelBar) {
         mBar = panelBar;
     }
 
     public void collapse() {
         // TODO: abort animation or ongoing touch
-        if (DEBUG) LOG("collapse: " + this);
+        if (DEBUG) logf("collapse: " + this);
         if (!isFullyCollapsed()) {
             mTimeAnimator.cancel();
             mClosing = true;
@@ -631,12 +665,18 @@
     }
 
     public void expand() {
-        if (DEBUG) LOG("expand: " + this);
+        if (DEBUG) logf("expand: " + this);
         if (isFullyCollapsed()) {
             mBar.startOpeningPanel(this);
             fling(mSelfExpandVelocityPx, /*always=*/ true);
         } else if (DEBUG) {
-            if (DEBUG) LOG("skipping expansion: is expanded");
+            if (DEBUG) logf("skipping expansion: is expanded");
+        }
+    }
+
+    public void cancelPeek() {
+        if (mPeekAnimator != null && mPeekAnimator.isStarted()) {
+            mPeekAnimator.cancel();
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 7d23e89..d15626b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -16,9 +16,17 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
+import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
+import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
+import static android.app.StatusBarManager.windowStateToString;
+import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
+import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
+import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
+import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
+
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.animation.TimeInterpolator;
 import android.app.ActivityManager;
@@ -26,12 +34,10 @@
 import android.app.Notification;
 import android.app.PendingIntent;
 import android.app.StatusBarManager;
-import android.service.notification.StatusBarNotification;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.SharedPreferences;
 import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.graphics.Canvas;
@@ -42,20 +48,18 @@
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.inputmethodservice.InputMethodService;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.Settings;
-import android.service.dreams.DreamService;
-import android.service.dreams.IDreamManager;
+import android.service.notification.StatusBarNotification;
 import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.Log;
-import android.util.Slog;
 import android.view.Display;
 import android.view.Gravity;
 import android.view.MotionEvent;
@@ -77,6 +81,7 @@
 import android.widget.TextView;
 
 import com.android.internal.statusbar.StatusBarIcon;
+import com.android.systemui.DemoMode;
 import com.android.systemui.EventLogTags;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.BaseStatusBar;
@@ -89,27 +94,25 @@
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.BluetoothController;
 import com.android.systemui.statusbar.policy.DateView;
-import com.android.systemui.statusbar.policy.IntruderAlertView;
+import com.android.systemui.statusbar.policy.HeadsUpNotificationView;
 import com.android.systemui.statusbar.policy.LocationController;
 import com.android.systemui.statusbar.policy.NetworkController;
 import com.android.systemui.statusbar.policy.NotificationRowLayout;
 import com.android.systemui.statusbar.policy.OnSizeChangedListener;
-import com.android.systemui.statusbar.policy.Prefs;
+import com.android.systemui.statusbar.policy.RotationLockController;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 
-public class PhoneStatusBar extends BaseStatusBar {
+public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
     static final String TAG = "PhoneStatusBar";
     public static final boolean DEBUG = BaseStatusBar.DEBUG;
-    public static final boolean SPEW = DEBUG;
+    public static final boolean SPEW = false;
     public static final boolean DUMPTRUCK = true; // extra dumpsys info
     public static final boolean DEBUG_GESTURES = false;
 
-    public static final boolean DEBUG_CLINGS = false;
-
-    public static final boolean ENABLE_NOTIFICATION_PANEL_CLING = false;
+    public static final boolean DEBUG_WINDOW_STATE = true;
 
     public static final boolean SETTINGS_DRAG_SHORTCUT = true;
 
@@ -124,14 +127,15 @@
     private static final int MSG_OPEN_SETTINGS_PANEL = 1002;
     // 1020-1030 reserved for BaseStatusBar
 
-    // will likely move to a resource or other tunable param at some point
-    private static final int INTRUDER_ALERT_DECAY_MS = 0; // disabled, was 10000;
-
     private static final boolean CLOSE_PANEL_WHEN_EMPTIED = true;
 
     private static final int NOTIFICATION_PRIORITY_MULTIPLIER = 10; // see NotificationManagerService
     private static final int HIDE_ICONS_BELOW_SCORE = Notification.PRIORITY_LOW * NOTIFICATION_PRIORITY_MULTIPLIER;
 
+    private static final int STATUS_OR_NAV_TRANSIENT =
+            View.STATUS_BAR_TRANSIENT | View.NAVIGATION_BAR_TRANSIENT;
+    private static final long AUTOHIDE_TIMEOUT_MS = 3000;
+
     // fling gesture tuning parameters, scaled to display density
     private float mSelfExpandVelocityPx; // classic value: 2000px/s
     private float mSelfCollapseVelocityPx; // classic value: 2000px/s (will be negated to collapse "up")
@@ -144,7 +148,7 @@
     private float mExpandAccelPx; // classic value: 2000px/s/s
     private float mCollapseAccelPx; // classic value: 2000px/s/s (will be negated to collapse "up")
 
-    private float mFlingGestureMaxOutputVelocityPx; // how fast can it really go? (should be a little 
+    private float mFlingGestureMaxOutputVelocityPx; // how fast can it really go? (should be a little
                                                     // faster than mSelfCollapseVelocityPx)
 
     PhoneStatusBarPolicy mIconPolicy;
@@ -154,28 +158,30 @@
     BatteryController mBatteryController;
     LocationController mLocationController;
     NetworkController mNetworkController;
+    RotationLockController mRotationLockController;
 
     int mNaturalBarHeight = -1;
     int mIconSize = -1;
     int mIconHPadding = -1;
     Display mDisplay;
     Point mCurrentDisplaySize = new Point();
-
-    IDreamManager mDreamManager;
+    private float mHeadsUpVerticalOffset;
+    private int[] mPilePosition = new int[2];
 
     StatusBarWindowView mStatusBarWindow;
     PhoneStatusBarView mStatusBarView;
+    private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
 
     int mPixelFormat;
     Object mQueueLock = new Object();
 
     // viewgroup containing the normal contents of the statusbar
     LinearLayout mStatusBarContents;
-    
+
     // right-hand icons
     LinearLayout mSystemIconArea;
-    
-    // left-hand icons 
+
+    // left-hand icons
     LinearLayout mStatusIcons;
     // the icons themselves
     IconMerger mNotificationIcons;
@@ -202,7 +208,7 @@
 
     // top bar
     View mNotificationPanelHeader;
-    View mDateTimeView; 
+    View mDateTimeView;
     View mClearButton;
     ImageView mSettingsButton, mNotificationButton;
 
@@ -222,11 +228,13 @@
     // the date view
     DateView mDateView;
 
-    // for immersive activities
-    private IntruderAlertView mIntruderAlertView;
+    // for heads up notifications
+    private HeadsUpNotificationView mHeadsUpNotificationView;
+    private int mHeadsUpNotificationDecay;
 
     // on-screen navigation buttons
     private NavigationBarView mNavigationBarView = null;
+    private int mNavigationBarWindowState = WINDOW_STATE_SHOWING;
 
     // the tracker view
     int mTrackingPosition; // the position of the top of the tracking view.
@@ -241,17 +249,9 @@
     boolean mTracking;
     VelocityTracker mVelocityTracker;
 
-    // help screen
-    private boolean mClingShown;
-    private ViewGroup mCling;
-    private boolean mSuppressStatusBarDrags; // while a cling is up, briefly deaden the bar to give things time to settle
-
     int[] mAbsPos = new int[2];
     Runnable mPostCollapseCleanup = null;
 
-    private Animator mLightsOutAnimation;
-    private Animator mLightsOnAnimation;
-
     // for disabling the status bar
     int mDisabled = 0;
 
@@ -262,7 +262,7 @@
 
     // XXX: gesture research
     private final GestureRecorder mGestureRec = DEBUG_GESTURES
-        ? new GestureRecorder("/sdcard/statusbar_gestures.dat") 
+        ? new GestureRecorder("/sdcard/statusbar_gestures.dat")
         : null;
 
     private int mNavigationIconHints = 0;
@@ -271,7 +271,7 @@
         public void onAnimationEnd(Animator animation) {
             // double-check to avoid races
             if (mStatusBarContents.getAlpha() == 0) {
-                if (DEBUG) Slog.d(TAG, "makeIconsInvisible");
+                if (DEBUG) Log.d(TAG, "makeIconsInvisible");
                 mStatusBarContents.setVisibility(View.INVISIBLE);
             }
         }
@@ -287,7 +287,7 @@
                     Settings.Secure.USER_SETUP_COMPLETE,
                     0 /*default */,
                     mCurrentUserId);
-            if (MULTIUSER_DEBUG) Slog.d(TAG, String.format("User setup changed: " +
+            if (MULTIUSER_DEBUG) Log.d(TAG, String.format("User setup changed: " +
                     "selfChange=%s userSetup=%s mUserSetup=%s",
                     selfChange, userSetup, mUserSetup));
             if (mSettingsButton != null && mHasFlipSettings) {
@@ -304,20 +304,30 @@
         }
     };
 
+    private int mInteractingWindows;
+    private boolean mAutohideSuspended;
+    private int mStatusBarMode;
+    private int mNavigationBarMode;
+
+    private final Runnable mAutohide = new Runnable() {
+        @Override
+        public void run() {
+            int requested = mSystemUiVisibility & ~STATUS_OR_NAV_TRANSIENT;
+            if (mSystemUiVisibility != requested) {
+                notifyUiVisibilityChanged(requested);
+            }
+        }};
+
     @Override
     public void start() {
         mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
                 .getDefaultDisplay();
-
-        mDreamManager = IDreamManager.Stub.asInterface(
-                ServiceManager.checkService(DreamService.DREAM_SERVICE));
+        mDisplay.getSize(mCurrentDisplaySize);
 
         super.start(); // calls createAndAddWindows()
 
         addNavigationBar();
 
-        if (ENABLE_INTRUDERS) addIntruderView();
-
         // Lastly, call to the icon policy to install/update all the icons.
         mIconPolicy = new PhoneStatusBarPolicy(mContext);
     }
@@ -341,6 +351,7 @@
         mStatusBarWindow.setOnTouchListener(new View.OnTouchListener() {
             @Override
             public boolean onTouch(View v, MotionEvent event) {
+                checkUserAutohide(v, event);
                 if (event.getAction() == MotionEvent.ACTION_DOWN) {
                     if (mExpandedVisible) {
                         animateCollapsePanels();
@@ -351,7 +362,6 @@
 
         mStatusBarView = (PhoneStatusBarView) mStatusBarWindow.findViewById(R.id.status_bar);
         mStatusBarView.setBar(this);
-        
 
         PanelHolder holder = (PanelHolder) mStatusBarWindow.findViewById(R.id.panel_holder);
         mStatusBarView.setPanelHolder(holder);
@@ -375,10 +385,11 @@
             mNotificationPanel.setBackground(new FastColorDrawable(context.getResources().getColor(
                     R.color.notification_panel_solid_background)));
         }
-        if (ENABLE_INTRUDERS) {
-            mIntruderAlertView = (IntruderAlertView) View.inflate(context, R.layout.intruder_alert, null);
-            mIntruderAlertView.setVisibility(View.GONE);
-            mIntruderAlertView.setBar(this);
+        if (ENABLE_HEADS_UP) {
+            mHeadsUpNotificationView =
+                    (HeadsUpNotificationView) View.inflate(context, R.layout.heads_up, null);
+            mHeadsUpNotificationView.setVisibility(View.GONE);
+            mHeadsUpNotificationView.setBar(this);
         }
         if (MULTIUSER_DEBUG) {
             mNotificationPanelDebugText = (TextView) mNotificationPanel.findViewById(R.id.header_debug_info);
@@ -389,13 +400,19 @@
 
         try {
             boolean showNav = mWindowManagerService.hasNavigationBar();
-            if (DEBUG) Slog.v(TAG, "hasNavigationBar=" + showNav);
+            if (DEBUG) Log.v(TAG, "hasNavigationBar=" + showNav);
             if (showNav) {
                 mNavigationBarView =
                     (NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);
 
                 mNavigationBarView.setDisabledFlags(mDisabled);
                 mNavigationBarView.setBar(this);
+                mNavigationBarView.setOnTouchListener(new View.OnTouchListener() {
+                    @Override
+                    public boolean onTouch(View v, MotionEvent event) {
+                        checkUserAutohide(v, event);
+                        return false;
+                    }});
             }
         } catch (RemoteException ex) {
             // no window manager? good luck with that
@@ -486,9 +503,9 @@
         // Other icons
         mLocationController = new LocationController(mContext); // will post a notification
         mBatteryController = new BatteryController(mContext);
-        mBatteryController.addIconView((ImageView)mStatusBarView.findViewById(R.id.battery));
         mNetworkController = new NetworkController(mContext);
         mBluetoothController = new BluetoothController(mContext);
+        mRotationLockController = new RotationLockController(mContext);
         final SignalClusterView signalCluster =
                 (SignalClusterView)mStatusBarView.findViewById(R.id.signal_cluster);
 
@@ -515,7 +532,7 @@
 
         mCarrierLabel = (TextView)mStatusBarWindow.findViewById(R.id.carrier_label);
         mShowCarrierInPanel = (mCarrierLabel != null);
-        if (DEBUG) Slog.v(TAG, "carrierlabel=" + mCarrierLabel + " show=" + mShowCarrierInPanel);
+        if (DEBUG) Log.v(TAG, "carrierlabel=" + mCarrierLabel + " show=" + mShowCarrierInPanel);
         if (mShowCarrierInPanel) {
             mCarrierLabel.setVisibility(mCarrierLabelVisible ? View.VISIBLE : View.INVISIBLE);
 
@@ -581,31 +598,19 @@
                 mQS.setService(this);
                 mQS.setBar(mStatusBarView);
                 mQS.setup(mNetworkController, mBluetoothController, mBatteryController,
-                        mLocationController);
+                        mLocationController, mRotationLockController);
             } else {
                 mQS = null; // fly away, be free
             }
         }
 
-        mClingShown = ! (DEBUG_CLINGS 
-            || !Prefs.read(mContext).getBoolean(Prefs.SHOWN_QUICK_SETTINGS_HELP, false));
-
-        if (!ENABLE_NOTIFICATION_PANEL_CLING || ActivityManager.isRunningInTestHarness()) {
-            mClingShown = true;
-        }
-
-//        final ImageView wimaxRSSI =
-//                (ImageView)sb.findViewById(R.id.wimax_signal);
-//        if (wimaxRSSI != null) {
-//            mNetworkController.addWimaxIconView(wimaxRSSI);
-//        }
-
         // receive broadcasts
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
         filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
         filter.addAction(Intent.ACTION_SCREEN_OFF);
         filter.addAction(Intent.ACTION_SCREEN_ON);
+        filter.addAction(ACTION_DEMO);
         context.registerReceiver(mBroadcastReceiver, filter);
 
         // listen for USER_SETUP_COMPLETE setting (per-user)
@@ -620,31 +625,6 @@
     }
 
     @Override
-    protected WindowManager.LayoutParams getRecentsLayoutParams(LayoutParams layoutParams) {
-        boolean opaque = false;
-        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
-                layoutParams.width,
-                layoutParams.height,
-                WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
-                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-                | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
-                | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
-                (opaque ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT));
-        if (ActivityManager.isHighEndGfx()) {
-            lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
-        } else {
-            lp.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
-            lp.dimAmount = 0.75f;
-        }
-        lp.gravity = Gravity.BOTTOM | Gravity.START;
-        lp.setTitle("RecentsPanel");
-        lp.windowAnimations = com.android.internal.R.style.Animation_RecentApplications;
-        lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
-        | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
-        return lp;
-    }
-
-    @Override
     protected WindowManager.LayoutParams getSearchLayoutParams(LayoutParams layoutParams) {
         boolean opaque = false;
         WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
@@ -670,8 +650,9 @@
     @Override
     protected void updateSearchPanel() {
         super.updateSearchPanel();
-        mSearchPanelView.setStatusBarView(mNavigationBarView);
-        mNavigationBarView.setDelegateView(mSearchPanelView);
+        if (mNavigationBarView != null) {
+            mNavigationBarView.setDelegateView(mSearchPanelView);
+        }
     }
 
     @Override
@@ -682,19 +663,23 @@
         // we want to freeze the sysui state wherever it is
         mSearchPanelView.setSystemUiVisibility(mSystemUiVisibility);
 
-        WindowManager.LayoutParams lp =
-            (android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams();
-        lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
-        mWindowManager.updateViewLayout(mNavigationBarView, lp);
+        if (mNavigationBarView != null) {
+            WindowManager.LayoutParams lp =
+                (android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams();
+            lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
+            mWindowManager.updateViewLayout(mNavigationBarView, lp);
+        }
     }
 
     @Override
     public void hideSearchPanel() {
         super.hideSearchPanel();
-        WindowManager.LayoutParams lp =
-            (android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams();
-        lp.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
-        mWindowManager.updateViewLayout(mNavigationBarView, lp);
+        if (mNavigationBarView != null) {
+            WindowManager.LayoutParams lp =
+                (android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams();
+            lp.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
+            mWindowManager.updateViewLayout(mNavigationBarView, lp);
+        }
     }
 
     protected int getStatusBarGravity() {
@@ -767,7 +752,7 @@
 
     // For small-screen devices (read: phones) that lack hardware navigation buttons
     private void addNavigationBar() {
-        if (DEBUG) Slog.v(TAG, "addNavigationBar: about to add " + mNavigationBarView);
+        if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + mNavigationBarView);
         if (mNavigationBarView == null) return;
 
         prepareNavigationBarView();
@@ -798,7 +783,7 @@
                     | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                     | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                     | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
-                PixelFormat.OPAQUE);
+                PixelFormat.TRANSLUCENT);
         // this will allow the navbar to run in an overlay on devices that support this
         if (ActivityManager.isHighEndGfx()) {
             lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
@@ -809,10 +794,9 @@
         return lp;
     }
 
-    private void addIntruderView() {
+    private void addHeadsUpView() {
         WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                ViewGroup.LayoutParams.WRAP_CONTENT,
+                LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT,
                 WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, // above the status bar!
                 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                     | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
@@ -821,13 +805,14 @@
                     | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
                     | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
                 PixelFormat.TRANSLUCENT);
-        lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
-        //lp.y += height * 1.5; // FIXME
-        lp.setTitle("IntruderAlert");
+        lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+        lp.gravity = Gravity.TOP;
+        lp.y = getStatusBarHeight();
+        lp.setTitle("Heads Up");
         lp.packageName = mContext.getPackageName();
-        lp.windowAnimations = R.style.Animation_StatusBar_IntruderAlert;
+        lp.windowAnimations = R.style.Animation_StatusBar_HeadsUp;
 
-        mWindowManager.addView(mIntruderAlertView, lp);
+        mWindowManager.addView(mHeadsUpNotificationView, lp);
     }
 
     public void refreshAllStatusBarIcons() {
@@ -846,7 +831,7 @@
     }
 
     public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
-        if (SPEW) Slog.d(TAG, "addIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
+        if (SPEW) Log.d(TAG, "addIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
                 + " icon=" + icon);
         StatusBarIconView view = new StatusBarIconView(mContext, slot, null);
         view.set(icon);
@@ -855,74 +840,47 @@
 
     public void updateIcon(String slot, int index, int viewIndex,
             StatusBarIcon old, StatusBarIcon icon) {
-        if (SPEW) Slog.d(TAG, "updateIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
+        if (SPEW) Log.d(TAG, "updateIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
                 + " old=" + old + " icon=" + icon);
         StatusBarIconView view = (StatusBarIconView)mStatusIcons.getChildAt(viewIndex);
         view.set(icon);
     }
 
     public void removeIcon(String slot, int index, int viewIndex) {
-        if (SPEW) Slog.d(TAG, "removeIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex);
+        if (SPEW) Log.d(TAG, "removeIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex);
         mStatusIcons.removeViewAt(viewIndex);
     }
 
     public void addNotification(IBinder key, StatusBarNotification notification) {
-        if (DEBUG) Slog.d(TAG, "addNotification score=" + notification.getScore());
-        StatusBarIconView iconView = addNotificationViews(key, notification);
-        if (iconView == null) return;
-
-        boolean immersive = false;
-        try {
-            immersive = ActivityManagerNative.getDefault().isTopActivityImmersive();
-            if (DEBUG) {
-                Slog.d(TAG, "Top activity is " + (immersive?"immersive":"not immersive"));
-            }
-        } catch (RemoteException ex) {
+        if (DEBUG) Log.d(TAG, "addNotification score=" + notification.getScore());
+        Entry shadeEntry = createNotificationViews(key, notification);
+        if (shadeEntry == null) {
+            return;
         }
+        if (mUseHeadsUp && shouldInterrupt(notification)) {
+            if (DEBUG) Log.d(TAG, "launching notification in heads up mode");
+            Entry interruptionCandidate = new Entry(key, notification, null);
+            if (inflateViews(interruptionCandidate, mHeadsUpNotificationView.getHolder())) {
+                mInterruptingNotificationTime = System.currentTimeMillis();
+                mInterruptingNotificationEntry = interruptionCandidate;
+                shadeEntry.setInterruption();
 
-        /*
-         * DISABLED due to missing API
-        if (ENABLE_INTRUDERS && (
-                   // TODO(dsandler): Only if the screen is on
-                notification.notification.intruderView != null)) {
-            Slog.d(TAG, "Presenting high-priority notification");
-            // special new transient ticker mode
-            // 1. Populate mIntruderAlertView
+                // 1. Populate mHeadsUpNotificationView
+                mHeadsUpNotificationView.setNotification(mInterruptingNotificationEntry);
 
-            if (notification.notification.intruderView == null) {
-                Slog.e(TAG, notification.notification.toString() + " wanted to intrude but intruderView was null");
-                return;
+                // 2. Animate mHeadsUpNotificationView in
+                mHandler.sendEmptyMessage(MSG_SHOW_HEADS_UP);
+
+                // 3. Set alarm to age the notification off
+                resetHeadsUpDecayTimer();
             }
-
-            // bind the click event to the content area
-            PendingIntent contentIntent = notification.notification.contentIntent;
-            final View.OnClickListener listener = (contentIntent != null)
-                    ? new NotificationClicker(contentIntent,
-                            notification.pkg, notification.tag, notification.id)
-                    : null;
-
-            mIntruderAlertView.applyIntruderContent(notification.notification.intruderView, listener);
-
-            mCurrentlyIntrudingNotification = notification;
-
-            // 2. Animate mIntruderAlertView in
-            mHandler.sendEmptyMessage(MSG_SHOW_INTRUDER);
-
-            // 3. Set alarm to age the notification off (TODO)
-            mHandler.removeMessages(MSG_HIDE_INTRUDER);
-            if (INTRUDER_ALERT_DECAY_MS > 0) {
-                mHandler.sendEmptyMessageDelayed(MSG_HIDE_INTRUDER, INTRUDER_ALERT_DECAY_MS);
-            }
-        } else
-         */
-
-        if (notification.getNotification().fullScreenIntent != null) {
+        } else if (notification.getNotification().fullScreenIntent != null) {
             // Stop screensaver if the notification has a full-screen intent.
             // (like an incoming phone call)
             awakenDreams();
 
             // not immersive & a full-screen alert should be shown
-            if (DEBUG) Slog.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
+            if (DEBUG) Log.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
             try {
                 notification.getNotification().fullScreenIntent.send();
             } catch (PendingIntent.CanceledException e) {
@@ -930,20 +888,29 @@
         } else {
             // usual case: status bar visible & not immersive
 
-            // show the ticker if there isn't an intruder too
-            if (mCurrentlyIntrudingNotification == null) {
+            // show the ticker if there isn't already a heads up
+            if (mInterruptingNotificationEntry == null) {
                 tick(null, notification, true);
             }
         }
-
+        addNotificationViews(shadeEntry);
         // Recalculate the position of the sliding windows and the titles.
         setAreThereNotifications();
         updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
     }
 
+    @Override
+    public void resetHeadsUpDecayTimer() {
+        if (mUseHeadsUp && mHeadsUpNotificationDecay > 0
+                && mHeadsUpNotificationView.isClearable()) {
+            mHandler.removeMessages(MSG_HIDE_HEADS_UP);
+            mHandler.sendEmptyMessageDelayed(MSG_HIDE_HEADS_UP, mHeadsUpNotificationDecay);
+        }
+    }
+
     public void removeNotification(IBinder key) {
         StatusBarNotification old = removeNotificationViews(key);
-        if (SPEW) Slog.d(TAG, "removeNotification key=" + key + " old=" + old);
+        if (SPEW) Log.d(TAG, "removeNotification key=" + key + " old=" + old);
 
         if (old != null) {
             // Cancel the ticker if it's still running
@@ -952,11 +919,13 @@
             // Recalculate the position of the sliding windows and the titles.
             updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
 
-            if (ENABLE_INTRUDERS && old == mCurrentlyIntrudingNotification) {
-                mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
+            if (ENABLE_HEADS_UP && mInterruptingNotificationEntry != null
+                    && old == mInterruptingNotificationEntry.notification) {
+                mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
             }
 
-            if (CLOSE_PANEL_WHEN_EMPTIED && mNotificationData.size() == 0) {
+            if (CLOSE_PANEL_WHEN_EMPTIED && mNotificationData.size() == 0
+                    && !mNotificationPanel.isTracking()) {
                 animateCollapsePanels();
             }
         }
@@ -1048,7 +1017,7 @@
         int N = mNotificationData.size();
 
         if (DEBUG) {
-            Slog.d(TAG, "refreshing icons: " + N + " notifications, mNotificationIcons=" + mNotificationIcons);
+            Log.d(TAG, "refreshing icons: " + N + " notifications, mNotificationIcons=" + mNotificationIcons);
         }
 
         ArrayList<View> toShow = new ArrayList<View>();
@@ -1085,10 +1054,10 @@
 
     protected void updateCarrierLabelVisibility(boolean force) {
         if (!mShowCarrierInPanel) return;
-        // The idea here is to only show the carrier label when there is enough room to see it, 
+        // The idea here is to only show the carrier label when there is enough room to see it,
         // i.e. when there aren't enough notifications to fill the panel.
-        if (DEBUG) {
-            Slog.d(TAG, String.format("pileh=%d scrollh=%d carrierh=%d",
+        if (SPEW) {
+            Log.d(TAG, String.format("pileh=%d scrollh=%d carrierh=%d",
                     mPile.getHeight(), mScrollView.getHeight(), mCarrierLabelHeight));
         }
 
@@ -1097,11 +1066,11 @@
             !(emergencyCallsShownElsewhere && mNetworkController.isEmergencyOnly())
             && mPile.getHeight() < (mNotificationPanel.getHeight() - mCarrierLabelHeight - mNotificationHeaderHeight)
             && mScrollView.getVisibility() == View.VISIBLE;
-        
+
         if (force || mCarrierLabelVisible != makeVisible) {
             mCarrierLabelVisible = makeVisible;
             if (DEBUG) {
-                Slog.d(TAG, "making carrier label " + (makeVisible?"visible":"invisible"));
+                Log.d(TAG, "making carrier label " + (makeVisible?"visible":"invisible"));
             }
             mCarrierLabel.animate().cancel();
             if (makeVisible) {
@@ -1131,13 +1100,13 @@
 
         final boolean clearable = any && mNotificationData.hasClearableItems();
 
-        if (DEBUG) {
-            Slog.d(TAG, "setAreThereNotifications: N=" + mNotificationData.size()
+        if (SPEW) {
+            Log.d(TAG, "setAreThereNotifications: N=" + mNotificationData.size()
                     + " any=" + any + " clearable=" + clearable);
         }
 
-        if (mHasFlipSettings 
-                && mFlipSettingsView != null 
+        if (mHasFlipSettings
+                && mFlipSettingsView != null
                 && mFlipSettingsView.getVisibility() == View.VISIBLE
                 && mScrollView.getVisibility() != View.VISIBLE) {
             // the flip settings panel is unequivocally showing; we should not be shown
@@ -1209,7 +1178,7 @@
         mDisabled = state;
 
         if (DEBUG) {
-            Slog.d(TAG, String.format("disable: 0x%08x -> 0x%08x (diff: 0x%08x)",
+            Log.d(TAG, String.format("disable: 0x%08x -> 0x%08x (diff: 0x%08x)",
                 old, state, diff));
         }
 
@@ -1236,7 +1205,7 @@
         flagdbg.append(((state & StatusBarManager.DISABLE_SEARCH) != 0) ? "SEARCH" : "search");
         flagdbg.append(((diff  & StatusBarManager.DISABLE_SEARCH) != 0) ? "* " : " ");
         flagdbg.append(">");
-        Slog.d(TAG, flagdbg.toString());
+        Log.d(TAG, flagdbg.toString());
 
         if ((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
             mSystemIconArea.animate().cancel();
@@ -1335,13 +1304,32 @@
                 case MSG_CLOSE_PANELS:
                     animateCollapsePanels();
                     break;
-                case MSG_SHOW_INTRUDER:
-                    setIntruderAlertVisibility(true);
+                case MSG_SHOW_HEADS_UP:
+                    setHeadsUpVisibility(true);
                     break;
-                case MSG_HIDE_INTRUDER:
-                    setIntruderAlertVisibility(false);
-                    mCurrentlyIntrudingNotification = null;
+                case MSG_HIDE_HEADS_UP:
+                    setHeadsUpVisibility(false);
                     break;
+                case MSG_ESCALATE_HEADS_UP:
+                    escalateHeadsUp();
+                    setHeadsUpVisibility(false);
+                    break;
+            }
+        }
+    }
+
+    /**  if the interrupting notification had a fullscreen intent, fire it now.  */
+    private void escalateHeadsUp() {
+        if (mInterruptingNotificationEntry != null) {
+            final StatusBarNotification sbn = mInterruptingNotificationEntry.notification;
+            final Notification notification = sbn.getNotification();
+            if (notification.fullScreenIntent != null) {
+                if (DEBUG)
+                    Log.d(TAG, "converting a heads up to fullScreen");
+                try {
+                    notification.fullScreenIntent.send();
+                } catch (PendingIntent.CanceledException e) {
+                }
             }
         }
     }
@@ -1358,9 +1346,13 @@
         }
     };
 
-    void makeExpandedVisible(boolean revealAfterDraw) {
-        if (SPEW) Slog.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);
-        if (mExpandedVisible) {
+    boolean panelsEnabled() {
+        return (mDisabled & StatusBarManager.DISABLE_EXPAND) == 0;
+    }
+
+    void makeExpandedVisible() {
+        if (SPEW) Log.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);
+        if (mExpandedVisible || !panelsEnabled()) {
             return;
         }
 
@@ -1381,13 +1373,17 @@
         lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
         mWindowManager.updateViewLayout(mStatusBarWindow, lp);
 
-        // Updating the window layout will force an expensive traversal/redraw.
-        // Kick off the reveal animation after this is complete to avoid animation latency.
-        if (revealAfterDraw) {
-//            mHandler.post(mStartRevealAnimation);
-        }
-
         visibilityChanged(true);
+
+        setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
+    }
+
+    private void releaseFocus() {
+        WindowManager.LayoutParams lp =
+                (WindowManager.LayoutParams) mStatusBarWindow.getLayoutParams();
+        lp.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+        lp.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+        mWindowManager.updateViewLayout(mStatusBarWindow, lp);
     }
 
     public void animateCollapsePanels() {
@@ -1396,11 +1392,14 @@
 
     public void animateCollapsePanels(int flags) {
         if (SPEW) {
-            Slog.d(TAG, "animateCollapse():"
+            Log.d(TAG, "animateCollapse():"
                     + " mExpandedVisible=" + mExpandedVisible
                     + " flags=" + flags);
         }
 
+        // release focus immediately to kick off focus change transition
+        releaseFocus();
+
         if ((flags & CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL) == 0) {
             mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
             mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
@@ -1447,7 +1446,7 @@
         a.setStartDelay(d);
         return a;
     }
-    
+
     public Animator start(Animator a) {
         a.start();
         return a;
@@ -1464,8 +1463,8 @@
 
     @Override
     public void animateExpandNotificationsPanel() {
-        if (SPEW) Slog.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
-        if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
+        if (SPEW) Log.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
+        if (!panelsEnabled()) {
             return ;
         }
 
@@ -1519,8 +1518,8 @@
 
     @Override
     public void animateExpandSettingsPanel() {
-        if (SPEW) Slog.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
-        if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
+        if (SPEW) Log.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
+        if (!panelsEnabled()) {
             return;
         }
 
@@ -1576,7 +1575,7 @@
                 interpolator(mAccelerateInterpolator,
                         ObjectAnimator.ofFloat(mScrollView, View.SCALE_X, 1f, 0f)
                         )
-                    .setDuration(FLIP_DURATION_OUT), 
+                    .setDuration(FLIP_DURATION_OUT),
                 mScrollView, View.INVISIBLE));
         mSettingsButtonAnim = start(
             setVisibilityWhenDone(
@@ -1618,7 +1617,7 @@
     }
 
     void makeExpandedInvisible() {
-        if (SPEW) Slog.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible
+        if (SPEW) Log.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible
                 + " mExpandedVisible=" + mExpandedVisible);
 
         if (!mExpandedVisible) {
@@ -1670,17 +1669,19 @@
             mPostCollapseCleanup.run();
             mPostCollapseCleanup = null;
         }
+
+        setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
     }
 
     /**
      * Enables or disables layers on the children of the notifications pile.
-     * 
+     *
      * When layers are enabled, this method attempts to enable layers for the minimal
      * number of children. Only children visible when the notification area is fully
      * expanded will receive a layer. The technique used in this method might cause
      * more children than necessary to get a layer (at most one extra child with the
      * current UI.)
-     * 
+     *
      * @param layerType {@link View#LAYER_TYPE_NONE} or {@link View#LAYER_TYPE_HARDWARE}
      */
     private void setPileLayers(int layerType) {
@@ -1693,7 +1694,7 @@
                 }
                 break;
             case View.LAYER_TYPE_HARDWARE:
-                final int[] location = new int[2]; 
+                final int[] location = new int[2];
                 mNotificationPanel.getLocationInWindow(location);
 
                 final int left = location[0];
@@ -1719,63 +1720,6 @@
         }
     }
 
-    public boolean isClinging() {
-        return mCling != null && mCling.getVisibility() == View.VISIBLE;
-    }
-
-    public void hideCling() {
-        if (isClinging()) {
-            mCling.animate().alpha(0f).setDuration(250).start();
-            mCling.setVisibility(View.GONE);
-            mSuppressStatusBarDrags = false;
-        }
-    }
-
-    public void showCling() {
-        // lazily inflate this to accommodate orientation change
-        final ViewStub stub = (ViewStub) mStatusBarWindow.findViewById(R.id.status_bar_cling_stub);
-        if (stub == null) {
-            mClingShown = true;
-            return; // no clings on this device
-        }
-
-        mSuppressStatusBarDrags = true;
-
-        mHandler.postDelayed(new Runnable() {
-            @Override
-            public void run() {
-                mCling = (ViewGroup) stub.inflate();
-
-                mCling.setOnTouchListener(new View.OnTouchListener() {
-                    @Override
-                    public boolean onTouch(View v, MotionEvent event) {
-                        return true; // e eats everything
-                    }});
-                mCling.findViewById(R.id.ok).setOnClickListener(new View.OnClickListener() {
-                    @Override
-                    public void onClick(View v) {
-                        hideCling();
-                    }});
-
-                mCling.setAlpha(0f);
-                mCling.setVisibility(View.VISIBLE);
-                mCling.animate().alpha(1f);
-
-                mClingShown = true;
-                SharedPreferences.Editor editor = Prefs.edit(mContext);
-                editor.putBoolean(Prefs.SHOWN_QUICK_SETTINGS_HELP, true);
-                editor.apply();
-
-                makeExpandedVisible(true); // enforce visibility in case the shade is still animating closed
-                animateExpandNotificationsPanel();
-
-                mSuppressStatusBarDrags = false;
-            }
-        }, 500);
-
-        animateExpandNotificationsPanel();
-    }
-
     public boolean interceptTouchEvent(MotionEvent event) {
         if (DEBUG_GESTURES) {
             if (event.getActionMasked() != MotionEvent.ACTION_MOVE) {
@@ -1786,11 +1730,11 @@
         }
 
         if (SPEW) {
-            Slog.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled="
+            Log.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled="
                 + mDisabled + " mTracking=" + mTracking);
         } else if (CHATTY) {
             if (event.getAction() != MotionEvent.ACTION_MOVE) {
-                Slog.d(TAG, String.format(
+                Log.d(TAG, String.format(
                             "panel: %s at (%f, %f) mDisabled=0x%08x",
                             MotionEvent.actionToString(event.getAction()),
                             event.getRawX(), event.getRawY(), mDisabled));
@@ -1801,21 +1745,16 @@
             mGestureRec.add(event);
         }
 
-        // Cling (first-run help) handling.
-        // The cling is supposed to show the first time you drag, or even tap, the status bar.
-        // It should show the notification panel, then fade in after half a second, giving you 
-        // an explanation of what just happened, as well as teach you how to access quick
-        // settings (another drag). The user can dismiss the cling by clicking OK or by 
-        // dragging quick settings into view.
-        final int act = event.getActionMasked();
-        if (mSuppressStatusBarDrags) {
-            return true;
-        } else if (act == MotionEvent.ACTION_UP && !mClingShown) {
-            showCling();
-        } else {
-            hideCling();
+        if (mStatusBarWindowState == WINDOW_STATE_SHOWING) {
+            final boolean upOrCancel =
+                    event.getAction() == MotionEvent.ACTION_UP ||
+                    event.getAction() == MotionEvent.ACTION_CANCEL;
+            if (upOrCancel && !mExpandedVisible) {
+                setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
+            } else {
+                setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
+            }
         }
-
         return false;
     }
 
@@ -1832,6 +1771,27 @@
         if (mNavigationBarView != null) {
             mNavigationBarView.setNavigationIconHints(hints);
         }
+        checkBarModes();
+    }
+
+    @Override // CommandQueue
+    public void setWindowState(int window, int state) {
+        boolean showing = state == WINDOW_STATE_SHOWING;
+        if (mStatusBarWindow != null
+                && window == StatusBarManager.WINDOW_STATUS_BAR
+                && mStatusBarWindowState != state) {
+            mStatusBarWindowState = state;
+            if (DEBUG_WINDOW_STATE) Log.d(TAG, "Status bar " + windowStateToString(state));
+            if (!showing) {
+                mStatusBarView.collapseAllPanels(false);
+            }
+        }
+        if (mNavigationBarView != null
+                && window == StatusBarManager.WINDOW_NAVIGATION_BAR
+                && mNavigationBarWindowState != state) {
+            mNavigationBarWindowState = state;
+            if (DEBUG_WINDOW_STATE) Log.d(TAG, "Navigation bar " + windowStateToString(state));
+        }
     }
 
     @Override // CommandQueue
@@ -1839,12 +1799,17 @@
         final int oldVal = mSystemUiVisibility;
         final int newVal = (oldVal&~mask) | (vis&mask);
         final int diff = newVal ^ oldVal;
-
+        if (DEBUG) Log.d(TAG, String.format(
+                "setSystemUiVisibility vis=%s mask=%s oldVal=%s newVal=%s diff=%s",
+                Integer.toHexString(vis), Integer.toHexString(mask),
+                Integer.toHexString(oldVal), Integer.toHexString(newVal),
+                Integer.toHexString(diff)));
         if (diff != 0) {
             mSystemUiVisibility = newVal;
 
-            if (0 != (diff & View.SYSTEM_UI_FLAG_LOW_PROFILE)) {
-                final boolean lightsOut = (0 != (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE));
+            // update low profile
+            if ((diff & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0) {
+                final boolean lightsOut = (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0;
                 if (lightsOut) {
                     animateCollapsePanels();
                     if (mTicking) {
@@ -1852,56 +1817,141 @@
                     }
                 }
 
-                if (mNavigationBarView != null) {
-                    mNavigationBarView.setLowProfile(lightsOut);
-                }
-
-                setStatusBarLowProfile(lightsOut);
+                setAreThereNotifications();
             }
 
-            notifyUiVisibilityChanged();
+            // update status bar mode
+            final int sbMode = computeBarMode(oldVal, newVal, mStatusBarView.getBarTransitions(),
+                    View.STATUS_BAR_TRANSIENT, View.SYSTEM_UI_FLAG_TRANSPARENT_STATUS);
+
+            // update navigation bar mode
+            final int nbMode = mNavigationBarView == null ? -1 : computeBarMode(
+                    oldVal, newVal, mNavigationBarView.getBarTransitions(),
+                    View.NAVIGATION_BAR_TRANSIENT, View.SYSTEM_UI_FLAG_TRANSPARENT_NAVIGATION);
+            final boolean sbModeChanged = sbMode != -1;
+            final boolean nbModeChanged = nbMode != -1;
+            boolean checkBarModes = false;
+            if (sbModeChanged && sbMode != mStatusBarMode) {
+                mStatusBarMode = sbMode;
+                checkBarModes = true;
+            }
+            if (nbModeChanged && nbMode != mNavigationBarMode) {
+                mNavigationBarMode = nbMode;
+                checkBarModes = true;
+            }
+            if (checkBarModes) {
+                checkBarModes();
+            }
+            if (sbModeChanged || nbModeChanged) {
+                // update transient bar autohide
+                if (sbMode == MODE_SEMI_TRANSPARENT || nbMode == MODE_SEMI_TRANSPARENT) {
+                    scheduleAutohide();
+                } else {
+                    cancelAutohide();
+                }
+            }
+
+            // ready to unhide
+            if ((vis & View.STATUS_BAR_UNHIDE) != 0) {
+                mSystemUiVisibility &= ~View.STATUS_BAR_UNHIDE;
+            }
+            if ((vis & View.NAVIGATION_BAR_UNHIDE) != 0) {
+                mSystemUiVisibility &= ~View.NAVIGATION_BAR_UNHIDE;
+            }
+
+            // send updated sysui visibility to window manager
+            notifyUiVisibilityChanged(mSystemUiVisibility);
         }
     }
 
-    private void setStatusBarLowProfile(boolean lightsOut) {
-        if (mLightsOutAnimation == null) {
-            final View notifications = mStatusBarView.findViewById(R.id.notification_icon_area);
-            final View systemIcons = mStatusBarView.findViewById(R.id.statusIcons);
-            final View signal = mStatusBarView.findViewById(R.id.signal_cluster);
-            final View battery = mStatusBarView.findViewById(R.id.battery);
-            final View clock = mStatusBarView.findViewById(R.id.clock);
-
-            final AnimatorSet lightsOutAnim = new AnimatorSet();
-            lightsOutAnim.playTogether(
-                    ObjectAnimator.ofFloat(notifications, View.ALPHA, 0),
-                    ObjectAnimator.ofFloat(systemIcons, View.ALPHA, 0),
-                    ObjectAnimator.ofFloat(signal, View.ALPHA, 0),
-                    ObjectAnimator.ofFloat(battery, View.ALPHA, 0.5f),
-                    ObjectAnimator.ofFloat(clock, View.ALPHA, 0.5f)
-                );
-            lightsOutAnim.setDuration(750);
-
-            final AnimatorSet lightsOnAnim = new AnimatorSet();
-            lightsOnAnim.playTogether(
-                    ObjectAnimator.ofFloat(notifications, View.ALPHA, 1),
-                    ObjectAnimator.ofFloat(systemIcons, View.ALPHA, 1),
-                    ObjectAnimator.ofFloat(signal, View.ALPHA, 1),
-                    ObjectAnimator.ofFloat(battery, View.ALPHA, 1),
-                    ObjectAnimator.ofFloat(clock, View.ALPHA, 1)
-                );
-            lightsOnAnim.setDuration(250);
-
-            mLightsOutAnimation = lightsOutAnim;
-            mLightsOnAnimation = lightsOnAnim;
+    private int computeBarMode(int oldVis, int newVis, BarTransitions transitions,
+            int transientFlag, int transparentFlag) {
+        final int oldMode = barMode(oldVis, transientFlag, transparentFlag);
+        final int newMode = barMode(newVis, transientFlag, transparentFlag);
+        if (oldMode == newMode) {
+            return -1; // no mode change
         }
+        return newMode;
+    }
 
-        mLightsOutAnimation.cancel();
-        mLightsOnAnimation.cancel();
+    private int barMode(int vis, int transientFlag, int transparentFlag) {
+        return (vis & transientFlag) != 0 ? MODE_SEMI_TRANSPARENT
+                : (vis & transparentFlag) != 0 ? MODE_TRANSPARENT
+                : (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0 ? MODE_LIGHTS_OUT
+                : MODE_OPAQUE;
+    }
 
-        final Animator a = lightsOut ? mLightsOutAnimation : mLightsOnAnimation;
-        a.start();
+    private void checkBarModes() {
+        if (mDemoMode) return;
+        checkBarMode((mInteractingWindows & StatusBarManager.WINDOW_STATUS_BAR) != 0 ? MODE_OPAQUE
+                : mStatusBarMode, mStatusBarWindowState, mStatusBarView.getBarTransitions());
+        if (mNavigationBarView != null) {
+            checkBarMode(mNavigationBarMode,
+                    mNavigationBarWindowState, mNavigationBarView.getBarTransitions());
+        }
+    }
 
-        setAreThereNotifications();
+    private void checkBarMode(int mode, int windowState, BarTransitions transitions) {
+        final boolean imeVisible = (mNavigationIconHints & NAVIGATION_HINT_BACK_ALT) != 0;
+        final int finalMode = imeVisible ? MODE_OPAQUE : mode;
+        final boolean animate = windowState != WINDOW_STATE_HIDDEN;
+        transitions.transitionTo(finalMode, animate);
+    }
+
+    private final Runnable mCheckBarModes = new Runnable() {
+        @Override
+        public void run() {
+            checkBarModes();
+        }};
+
+    @Override
+    public void setInteracting(int barWindow, boolean interacting) {
+        mInteractingWindows = interacting
+                ? (mInteractingWindows | barWindow)
+                : (mInteractingWindows & ~barWindow);
+        if (mInteractingWindows != 0) {
+            suspendAutohide();
+        } else {
+            resumeSuspendedAutohide();
+        }
+        checkBarModes();
+    }
+
+    private void resumeSuspendedAutohide() {
+        if (mAutohideSuspended) {
+            scheduleAutohide();
+            mHandler.postDelayed(mCheckBarModes, 500); // longer than home -> launcher
+        }
+    }
+
+    private void suspendAutohide() {
+        mHandler.removeCallbacks(mAutohide);
+        mHandler.removeCallbacks(mCheckBarModes);
+        mAutohideSuspended = (mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0;
+    }
+
+    private void cancelAutohide() {
+        mAutohideSuspended = false;
+        mHandler.removeCallbacks(mAutohide);
+    }
+
+    private void scheduleAutohide() {
+        cancelAutohide();
+        mHandler.postDelayed(mAutohide, AUTOHIDE_TIMEOUT_MS);
+    }
+
+    private void checkUserAutohide(View v, MotionEvent event) {
+        if ((mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0  // a transient bar is revealed
+                && event.getAction() == MotionEvent.ACTION_OUTSIDE // touch outside the source bar
+                && event.getX() == 0 && event.getY() == 0  // a touch outside both bars
+                ) {
+            userAutohide();
+        }
+    }
+
+    private void userAutohide() {
+        cancelAutohide();
+        mHandler.postDelayed(mAutohide, 350); // longer than app gesture -> flag clear
     }
 
     private boolean areLightsOn() {
@@ -1917,16 +1967,16 @@
         }
     }
 
-    private void notifyUiVisibilityChanged() {
+    private void notifyUiVisibilityChanged(int vis) {
         try {
-            mWindowManagerService.statusBarVisibilityChanged(mSystemUiVisibility);
+            mWindowManagerService.statusBarVisibilityChanged(vis);
         } catch (RemoteException ex) {
         }
     }
 
     public void topAppWindowChanged(boolean showMenu) {
         if (DEBUG) {
-            Slog.d(TAG, (showMenu?"showing":"hiding") + " the MENU button");
+            Log.d(TAG, (showMenu?"showing":"hiding") + " the MENU button");
         }
         if (mNavigationBarView != null) {
             mNavigationBarView.setMenuVisibility(showMenu);
@@ -1942,8 +1992,8 @@
             || ((vis & InputMethodService.IME_VISIBLE) != 0);
 
         mCommandQueue.setNavigationIconHints(
-                altBack ? (mNavigationIconHints | StatusBarManager.NAVIGATION_HINT_BACK_ALT)
-                        : (mNavigationIconHints & ~StatusBarManager.NAVIGATION_HINT_BACK_ALT));
+                altBack ? (mNavigationIconHints | NAVIGATION_HINT_BACK_ALT)
+                        : (mNavigationIconHints & ~NAVIGATION_HINT_BACK_ALT));
         if (mQS != null) mQS.setImeWindowStatus(vis > 0);
     }
 
@@ -2041,6 +2091,20 @@
                     + " scroll " + mScrollView.getScrollX() + "," + mScrollView.getScrollY());
         }
 
+        pw.print("  mInteractingWindows="); pw.println(mInteractingWindows);
+        pw.print("  mStatusBarWindowState=");
+        pw.println(windowStateToString(mStatusBarWindowState));
+        pw.print("  mStatusBarMode=");
+        pw.println(BarTransitions.modeToString(mStatusBarMode));
+        dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
+        if (mNavigationBarView != null) {
+            pw.print("  mNavigationBarWindowState=");
+            pw.println(windowStateToString(mNavigationBarWindowState));
+            pw.print("  mNavigationBarMode=");
+            pw.println(BarTransitions.modeToString(mNavigationBarMode));
+            dumpBarTransitions(pw, "mNavigationBarView", mNavigationBarView.getBarTransitions());
+        }
+
         pw.print("  mNavigationBarView=");
         if (mNavigationBarView == null) {
             pw.println("null");
@@ -2089,7 +2153,7 @@
                 mHandler.post(new Runnable() {
                         public void run() {
                             mStatusBarView.getLocationOnScreen(mAbsPos);
-                            Slog.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
+                            Log.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
                                     + ") " + mStatusBarView.getWidth() + "x"
                                     + getStatusBarHeight());
                             mStatusBarView.debug();
@@ -2106,9 +2170,15 @@
         mNetworkController.dump(fd, pw, args);
     }
 
+    private static void dumpBarTransitions(PrintWriter pw, String var, BarTransitions transitions) {
+        pw.print("  "); pw.print(var); pw.print(".BarTransitions.mMode=");
+        pw.println(BarTransitions.modeToString(transitions.getMode()));
+    }
+
     @Override
     public void createAndAddWindows() {
         addStatusBarWindow();
+        if (ENABLE_HEADS_UP) addHeadsUpView();
     }
 
     private void addStatusBarWindow() {
@@ -2124,7 +2194,8 @@
                 WindowManager.LayoutParams.TYPE_STATUS_BAR,
                 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                     | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
-                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
+                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
+                    | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
                 PixelFormat.TRANSLUCENT);
 
         lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
@@ -2161,7 +2232,7 @@
 
     @Override
     public void updateExpandedViewPos(int thingy) {
-        if (DEBUG) Slog.v(TAG, "updateExpandedViewPos");
+        if (SPEW) Log.v(TAG, "updateExpandedViewPos");
 
         // on larger devices, the notification panel is propped open a bit
         mNotificationPanel.setMinimumHeight(
@@ -2179,6 +2250,12 @@
             mSettingsPanel.setLayoutParams(lp);
         }
 
+        if (ENABLE_HEADS_UP && mHeadsUpNotificationView != null) {
+            mHeadsUpNotificationView.setMargin(mNotificationPanelMarginPx);
+            mPile.getLocationOnScreen(mPilePosition);
+            mHeadsUpVerticalOffset = mPilePosition[1] - mNaturalBarHeight;
+        }
+
         updateCarrierLabelVisibility(false);
     }
 
@@ -2186,7 +2263,7 @@
     void updateDisplaySize() {
         mDisplay.getMetrics(mDisplayMetrics);
         if (DEBUG_GESTURES) {
-            mGestureRec.tag("display", 
+            mGestureRec.tag("display",
                     String.format("%dx%d", mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels));
         }
     }
@@ -2229,7 +2306,7 @@
                             @Override
                             public void run() {
                                 if (DEBUG) {
-                                    Slog.v(TAG, "running post-collapse cleanup");
+                                    Log.v(TAG, "running post-collapse cleanup");
                                 }
                                 try {
                                     mPile.setViewRemoval(true);
@@ -2307,7 +2384,7 @@
 
     private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         public void onReceive(Context context, Intent intent) {
-            if (DEBUG) Slog.v(TAG, "onReceive: " + intent);
+            if (DEBUG) Log.v(TAG, "onReceive: " + intent);
             String action = intent.getAction();
             if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
                 int flags = CommandQueue.FLAG_EXCLUDE_NONE;
@@ -2323,10 +2400,11 @@
                 // no waiting!
                 makeExpandedInvisible();
                 notifyNavigationBarScreenOn(false);
+                notifyHeadsUpScreenOn(false);
             }
             else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
                 if (DEBUG) {
-                    Slog.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
+                    Log.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
                 }
                 mDisplay.getSize(mCurrentDisplaySize);
 
@@ -2340,6 +2418,19 @@
                 repositionNavigationBar();
                 notifyNavigationBarScreenOn(true);
             }
+            else if (ACTION_DEMO.equals(action)) {
+                Bundle bundle = intent.getExtras();
+                if (bundle != null) {
+                    String command = bundle.getString("command", "").trim().toLowerCase();
+                    if (command.length() > 0) {
+                        try {
+                            dispatchDemoCommand(command, bundle);
+                        } catch (Throwable t) {
+                            Log.w(TAG, "Error running demo command, intent=" + intent, t);
+                        }
+                    }
+                }
+            }
         }
     };
 
@@ -2360,24 +2451,39 @@
                 mCurrentUserId);
     }
 
-    private void setIntruderAlertVisibility(boolean vis) {
-        if (!ENABLE_INTRUDERS) return;
-        if (DEBUG) {
-            Slog.v(TAG, (vis ? "showing" : "hiding") + " intruder alert window");
+    private void setHeadsUpVisibility(boolean vis) {
+        if (!ENABLE_HEADS_UP) return;
+        if (DEBUG) Log.v(TAG, (vis ? "showing" : "hiding") + " heads up window");
+        mHeadsUpNotificationView.setVisibility(vis ? View.VISIBLE : View.GONE);
+        if (!vis) {
+            if (DEBUG) Log.d(TAG, "setting heads up entry to null");
+            mInterruptingNotificationEntry = null;
         }
-        mIntruderAlertView.setVisibility(vis ? View.VISIBLE : View.GONE);
     }
 
-    public void dismissIntruder() {
-        if (mCurrentlyIntrudingNotification == null) return;
+    public void animateHeadsUp(boolean animateInto, float frac) {
+        if (!ENABLE_HEADS_UP || mHeadsUpNotificationView == null) return;
+        frac = frac / 0.4f;
+        frac = frac < 1.0f ? frac : 1.0f;
+        float alpha = 1.0f - frac;
+        float offset = mHeadsUpVerticalOffset * frac;
+        offset = animateInto ? offset : 0f;
+        mHeadsUpNotificationView.setAlpha(alpha);
+        mHeadsUpNotificationView.setY(offset);
+    }
 
-        try {
-            mBarService.onNotificationClear(
-                    mCurrentlyIntrudingNotification.getPackageName(),
-                    mCurrentlyIntrudingNotification.getTag(),
-                    mCurrentlyIntrudingNotification.getId());
-        } catch (android.os.RemoteException ex) {
-            // oh well
+    public void onHeadsUpDismissed() {
+        if (mInterruptingNotificationEntry == null) return;
+        mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
+        if (mHeadsUpNotificationView.isClearable()) {
+            try {
+                mBarService.onNotificationClear(
+                        mInterruptingNotificationEntry.notification.getPackageName(),
+                        mInterruptingNotificationEntry.notification.getTag(),
+                        mInterruptingNotificationEntry.notification.getId());
+            } catch (android.os.RemoteException ex) {
+                // oh well
+            }
         }
     }
 
@@ -2414,7 +2520,7 @@
             R.dimen.status_bar_icon_padding);
 
         if (newIconHPadding != mIconHPadding || newIconSize != mIconSize) {
-//            Slog.d(TAG, "size=" + newIconSize + " padding=" + newIconHPadding);
+//            Log.d(TAG, "size=" + newIconSize + " padding=" + newIconHPadding);
             mIconHPadding = newIconHPadding;
             mIconSize = newIconSize;
             //reloadAllNotificationIcons(); // reload the tray
@@ -2459,7 +2565,10 @@
             mNotificationPanelMinHeightFrac = 0f;
         }
 
-        if (false) Slog.v(TAG, "updateResources");
+        mHeadsUpNotificationDecay = res.getInteger(R.integer.heads_up_notification_decay);
+        mRowHeight =  res.getDimensionPixelSize(R.dimen.notification_row_min_height);
+
+        if (false) Log.v(TAG, "updateResources");
     }
 
     //
@@ -2480,7 +2589,7 @@
         public void run() {
             vibrate();
             SystemClock.sleep(250);
-            Slog.d(TAG, "startTracing");
+            Log.d(TAG, "startTracing");
             android.os.Debug.startMethodTracing("/data/statusbar-traces/trace");
             mHandler.postDelayed(mStopTracing, 10000);
         }
@@ -2489,7 +2598,7 @@
     Runnable mStopTracing = new Runnable() {
         public void run() {
             android.os.Debug.stopMethodTracing();
-            Slog.d(TAG, "stopTracing");
+            Log.d(TAG, "stopTracing");
             vibrate();
         }
     };
@@ -2539,4 +2648,78 @@
         public void setBounds(Rect bounds) {
         }
     }
+
+    @Override
+    public void destroy() {
+        super.destroy();
+        if (mStatusBarWindow != null) {
+            mWindowManager.removeViewImmediate(mStatusBarWindow);
+        }
+        if (mNavigationBarView != null) {
+            mWindowManager.removeViewImmediate(mNavigationBarView);
+        }
+        mContext.unregisterReceiver(mBroadcastReceiver);
+    }
+
+    private boolean mDemoModeAllowed;
+    private boolean mDemoMode;
+    private DemoStatusIcons mDemoStatusIcons;
+
+    @Override
+    public void dispatchDemoCommand(String command, Bundle args) {
+        if (!mDemoModeAllowed) {
+            mDemoModeAllowed = Settings.Global.getInt(mContext.getContentResolver(),
+                    "sysui_demo_allowed", 0) != 0;
+        }
+        if (!mDemoModeAllowed) return;
+        if (command.equals(COMMAND_ENTER)) {
+            mDemoMode = true;
+        } else if (command.equals(COMMAND_EXIT)) {
+            mDemoMode = false;
+            checkBarModes();
+        } else if (!mDemoMode) {
+            // automatically enter demo mode on first demo command
+            dispatchDemoCommand(COMMAND_ENTER, new Bundle());
+        }
+        boolean modeChange = command.equals(COMMAND_ENTER) || command.equals(COMMAND_EXIT);
+        if (modeChange || command.equals(COMMAND_CLOCK)) {
+            dispatchDemoCommandToView(command, args, R.id.clock);
+        }
+        if (modeChange || command.equals(COMMAND_BATTERY)) {
+            dispatchDemoCommandToView(command, args, R.id.battery);
+        }
+        if (modeChange || command.equals(COMMAND_STATUS)) {
+            if (mDemoStatusIcons == null) {
+                mDemoStatusIcons = new DemoStatusIcons(mStatusIcons, mIconSize);
+            }
+            mDemoStatusIcons.dispatchDemoCommand(command, args);
+        }
+        if (mNetworkController != null && (modeChange || command.equals(COMMAND_NETWORK))) {
+            mNetworkController.dispatchDemoCommand(command, args);
+        }
+        if (command.equals(COMMAND_BARS)) {
+            String mode = args.getString("mode");
+            int barMode = "opaque".equals(mode) ? MODE_OPAQUE :
+                    "transparent".equals(mode) ? MODE_TRANSPARENT :
+                    "semi-transparent".equals(mode) ? MODE_SEMI_TRANSPARENT :
+                    -1;
+            if (barMode != -1) {
+                boolean animate = true;
+                if (mStatusBarView != null) {
+                    mStatusBarView.getBarTransitions().transitionTo(barMode, animate);
+                }
+                if (mNavigationBarView != null) {
+                    mNavigationBarView.getBarTransitions().transitionTo(barMode, animate);
+                }
+            }
+        }
+    }
+
+    private void dispatchDemoCommandToView(String command, Bundle args, int id) {
+        if (mStatusBarView == null) return;
+        View v = mStatusBarView.findViewById(id);
+        if (v instanceof DemoMode) {
+            ((DemoMode)v).dispatchDemoCommand(command, args);
+        }
+    }
 }
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 9b8bd22..8957a77 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -22,28 +22,13 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.location.LocationManager;
 import android.media.AudioManager;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.net.wifi.WifiManager;
-import android.os.Binder;
 import android.os.Handler;
-import android.os.RemoteException;
-import android.os.storage.StorageManager;
-import android.provider.Settings;
-import android.telephony.PhoneStateListener;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import android.telephony.TelephonyManager;
-import android.util.Slog;
+import android.util.Log;
 
-import com.android.internal.telephony.IccCard;
 import com.android.internal.telephony.IccCardConstants;
 import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.telephony.cdma.EriInfo;
 import com.android.internal.telephony.cdma.TtyIntent;
-import com.android.server.am.BatteryStatsService;
 import com.android.systemui.R;
 
 /**
@@ -71,10 +56,6 @@
     private final StatusBarManager mService;
     private final Handler mHandler = new Handler();
 
-    // storage
-    private StorageManager mStorageManager;
-
-
     // Assume it's all good unless we hear otherwise.  We don't always seem
     // to get broadcasts that it *is* there.
     IccCardConstants.State mSimState = IccCardConstants.State.READY;
@@ -85,20 +66,6 @@
     // bluetooth device status
     private boolean mBluetoothEnabled = false;
 
-    // wifi
-    private static final int[][] sWifiSignalImages = {
-            { R.drawable.stat_sys_wifi_signal_1,
-              R.drawable.stat_sys_wifi_signal_2,
-              R.drawable.stat_sys_wifi_signal_3,
-              R.drawable.stat_sys_wifi_signal_4 },
-            { R.drawable.stat_sys_wifi_signal_1_fully,
-              R.drawable.stat_sys_wifi_signal_2_fully,
-              R.drawable.stat_sys_wifi_signal_3_fully,
-              R.drawable.stat_sys_wifi_signal_4_fully }
-        };
-    private static final int sWifiTemporarilyNotConnectedImage =
-            R.drawable.stat_sys_wifi_signal_0;
-
     private int mLastWifiSignalLevel = -1;
     private boolean mIsWifiConnected = false;
 
@@ -150,11 +117,6 @@
         filter.addAction(TtyIntent.TTY_ENABLED_CHANGE_ACTION);
         mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);
 
-        // storage
-        mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
-        mStorageManager.registerListener(
-                new com.android.systemui.usb.StorageNotification(context));
-
         // TTY status
         mService.setIcon("tty",  R.drawable.stat_sys_tty_mode, 0, null);
         mService.setIconVisibility("tty", false);
@@ -181,9 +143,8 @@
 
         // Sync state
         mService.setIcon("sync_active", R.drawable.stat_sys_sync, 0, null);
-        mService.setIcon("sync_failing", R.drawable.stat_sys_sync_error, 0, null);
         mService.setIconVisibility("sync_active", false);
-        mService.setIconVisibility("sync_failing", false);
+        // "sync_failing" is obsolete: b/1297963
 
         // volume
         mService.setIcon("volume", R.drawable.stat_sys_ringer_silent, 0, null);
@@ -199,10 +160,7 @@
     private final void updateSyncState(Intent intent) {
         if (!SHOW_SYNC_ICON) return;
         boolean isActive = intent.getBooleanExtra("active", false);
-        boolean isFailing = intent.getBooleanExtra("failing", false);
         mService.setIconVisibility("sync_active", isActive);
-        // Don't display sync failing icon: BUG 1297963 Set sync error timeout to "never"
-        //mService.setIconVisibility("sync_failing", isFailing && !isActive);
     }
 
     private final void updateSimState(Intent intent) {
@@ -284,17 +242,17 @@
         final String action = intent.getAction();
         final boolean enabled = intent.getBooleanExtra(TtyIntent.TTY_ENABLED, false);
 
-        if (false) Slog.v(TAG, "updateTTY: enabled: " + enabled);
+        if (false) Log.v(TAG, "updateTTY: enabled: " + enabled);
 
         if (enabled) {
             // TTY is on
-            if (false) Slog.v(TAG, "updateTTY: set TTY on");
+            if (false) Log.v(TAG, "updateTTY: set TTY on");
             mService.setIcon("tty", R.drawable.stat_sys_tty_mode, 0,
                     mContext.getString(R.string.accessibility_tty_enabled));
             mService.setIconVisibility("tty", true);
         } else {
             // TTY is off
-            if (false) Slog.v(TAG, "updateTTY: set TTY off");
+            if (false) Log.v(TAG, "updateTTY: set TTY off");
             mService.setIconVisibility("tty", false);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
new file mode 100644
index 0000000..b9ffd6e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
@@ -0,0 +1,117 @@
+/*
+ * 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.systemui.statusbar.phone;
+
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.content.res.Resources;
+import android.util.Log;
+import android.view.View;
+
+import com.android.systemui.R;
+
+public final class PhoneStatusBarTransitions extends BarTransitions {
+    private static final float ALPHA_WHEN_TRANSPARENT = 1;
+    private static final float ALPHA_WHEN_LIGHTS_OUT_BATTERY_CLOCK = 0.5f;
+    private static final float ALPHA_WHEN_LIGHTS_OUT_NON_BATTERY_CLOCK = 0;
+
+    private final PhoneStatusBarView mView;
+    private final int mTransparent;
+    private final float mAlphaWhenOpaque;
+
+    private View mLeftSide, mStatusIcons, mSignalCluster, mBattery, mClock;
+    private Animator mCurrentAnimation;
+
+    public PhoneStatusBarTransitions(PhoneStatusBarView view) {
+        super(view);
+        mView = view;
+        final Resources res = mView.getContext().getResources();
+        mTransparent = res.getColor(R.color.status_bar_background_transparent);
+        mAlphaWhenOpaque = res.getFraction(R.dimen.status_bar_icon_drawing_alpha, 1, 1);
+    }
+
+    public void init() {
+        mLeftSide = mView.findViewById(R.id.notification_icon_area);
+        mStatusIcons = mView.findViewById(R.id.statusIcons);
+        mSignalCluster = mView.findViewById(R.id.signal_cluster);
+        mBattery = mView.findViewById(R.id.battery);
+        mClock = mView.findViewById(R.id.clock);
+        applyMode(getMode(), false /*animate*/);
+    }
+
+    @Override
+    protected Integer getBackgroundColor(int mode) {
+        if (mode == MODE_TRANSPARENT) return mTransparent;
+        return super.getBackgroundColor(mode);
+    }
+
+    public ObjectAnimator animateTransitionTo(View v, float toAlpha) {
+        return ObjectAnimator.ofFloat(v, "alpha", v.getAlpha(), toAlpha);
+    }
+
+    private float getNonBatteryClockAlphaFor(int mode) {
+        return mode == MODE_LIGHTS_OUT ? ALPHA_WHEN_LIGHTS_OUT_NON_BATTERY_CLOCK
+                : isTransparent(mode) ? ALPHA_WHEN_TRANSPARENT
+                : mAlphaWhenOpaque;
+    }
+
+    private float getBatteryClockAlpha(int mode) {
+        return mode == MODE_LIGHTS_OUT ? ALPHA_WHEN_LIGHTS_OUT_BATTERY_CLOCK
+                : getNonBatteryClockAlphaFor(mode);
+    }
+
+    private boolean isTransparent(int mode) {
+        return mode == MODE_SEMI_TRANSPARENT || mode == MODE_TRANSPARENT;
+    }
+
+    @Override
+    protected void onTransition(int oldMode, int newMode, boolean animate) {
+        super.onTransition(oldMode, newMode, animate);
+        applyMode(newMode, animate);
+    }
+
+    private void applyMode(int mode, boolean animate) {
+        if (mLeftSide == null) return; // pre-init
+        float newAlpha = getNonBatteryClockAlphaFor(mode);
+        float newAlphaBC = getBatteryClockAlpha(mode);
+        if (mCurrentAnimation != null) {
+            mCurrentAnimation.cancel();
+        }
+        if (animate) {
+            AnimatorSet anims = new AnimatorSet();
+            anims.playTogether(
+                    animateTransitionTo(mLeftSide, newAlpha),
+                    animateTransitionTo(mStatusIcons, newAlpha),
+                    animateTransitionTo(mSignalCluster, newAlpha),
+                    animateTransitionTo(mBattery, newAlphaBC),
+                    animateTransitionTo(mClock, newAlphaBC)
+                    );
+            if (mode == MODE_LIGHTS_OUT) {
+                anims.setDuration(LIGHTS_OUT_DURATION);
+            }
+            anims.start();
+            mCurrentAnimation = anims;
+        } else {
+            mLeftSide.setAlpha(newAlpha);
+            mStatusIcons.setAlpha(newAlpha);
+            mSignalCluster.setAlpha(newAlpha);
+            mBattery.setAlpha(newAlphaBC);
+            mClock.setAlpha(newAlphaBC);
+        }
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index de9f750..d9ac7e4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -17,13 +17,12 @@
 package com.android.systemui.statusbar.phone;
 
 import android.app.ActivityManager;
-import android.app.StatusBarManager;
 import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.Resources.NotFoundException;
 import android.util.AttributeSet;
 import android.util.EventLog;
-import android.util.Slog;
+import android.util.Log;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.accessibility.AccessibilityEvent;
@@ -46,6 +45,7 @@
     PanelView mLastFullyOpenedPanel = null;
     PanelView mNotificationPanel, mSettingsPanel;
     private boolean mShouldFade;
+    private final PhoneStatusBarTransitions mBarTransitions;
 
     public PhoneStatusBarView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -59,6 +59,11 @@
             mSettingsPanelDragzoneFrac = 0f;
         }
         mFullWidthNotifications = mSettingsPanelDragzoneFrac <= 0f;
+        mBarTransitions = new PhoneStatusBarTransitions(this);
+    }
+
+    public BarTransitions getBarTransitions() {
+        return mBarTransitions;
     }
 
     public void setBar(PhoneStatusBar bar) {
@@ -74,6 +79,7 @@
         for (PanelView pv : mPanels) {
             pv.setRubberbandingEnabled(!mFullWidthNotifications);
         }
+        mBarTransitions.init();
     }
 
     @Override
@@ -89,7 +95,7 @@
 
     @Override
     public boolean panelsEnabled() {
-        return ((mBar.mDisabled & StatusBarManager.DISABLE_EXPAND) == 0);
+        return mBar.panelsEnabled();
     }
 
     @Override
@@ -114,9 +120,9 @@
 
         if (mFullWidthNotifications) {
             // No double swiping. If either panel is open, nothing else can be pulled down.
-            return ((mSettingsPanel == null ? 0 : mSettingsPanel.getExpandedHeight()) 
-                        + mNotificationPanel.getExpandedHeight() > 0) 
-                    ? null 
+            return ((mSettingsPanel == null ? 0 : mSettingsPanel.getExpandedHeight())
+                        + mNotificationPanel.getExpandedHeight() > 0)
+                    ? null
                     : mNotificationPanel;
         }
 
@@ -128,7 +134,7 @@
         float region = (w * mSettingsPanelDragzoneFrac);
 
         if (DEBUG) {
-            Slog.v(TAG, String.format(
+            Log.v(TAG, String.format(
                 "w=%.1f frac=%.3f region=%.1f min=%.1f x=%.1f w-x=%.1f",
                 w, mSettingsPanelDragzoneFrac, region, mSettingsPanelDragzoneMin, x, (w-x)));
         }
@@ -142,7 +148,7 @@
     @Override
     public void onPanelPeeked() {
         super.onPanelPeeked();
-        mBar.makeExpandedVisible(true);
+        mBar.makeExpandedVisible();
     }
 
     @Override
@@ -152,7 +158,7 @@
         // which is kind of tricky to determine
         mShouldFade = (mFadingPanel == null || mFadingPanel.isFullyExpanded());
         if (DEBUG) {
-            Slog.v(TAG, "start opening: " + panel + " shouldfade=" + mShouldFade);
+            Log.v(TAG, "start opening: " + panel + " shouldfade=" + mShouldFade);
         }
         mFadingPanel = panel;
     }
@@ -202,7 +208,7 @@
         super.panelExpansionChanged(panel, frac);
 
         if (DEBUG) {
-            Slog.v(TAG, "panelExpansionChanged: f=" + frac);
+            Log.v(TAG, "panelExpansionChanged: f=" + frac);
         }
 
         if (panel == mFadingPanel && mScrimColor != 0 && ActivityManager.isHighEndGfx()) {
@@ -236,6 +242,8 @@
             panel.setAlpha(alpha);
         }
 
+        mBar.animateHeadsUp(mNotificationPanel == panel, mPanelExpandedFractionSum);
+
         mBar.updateCarrierLabelVisibility(false);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
index 85bcd8b..ceed30e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
@@ -16,23 +16,12 @@
 
 package com.android.systemui.statusbar.phone;
 
-import com.android.internal.view.RotationPolicy;
-import com.android.systemui.R;
-
-import com.android.systemui.statusbar.phone.QuickSettingsModel.BluetoothState;
-import com.android.systemui.statusbar.phone.QuickSettingsModel.RSSIState;
-import com.android.systemui.statusbar.phone.QuickSettingsModel.State;
-import com.android.systemui.statusbar.phone.QuickSettingsModel.UserState;
-import com.android.systemui.statusbar.phone.QuickSettingsModel.WifiState;
-import com.android.systemui.statusbar.policy.BatteryController;
-import com.android.systemui.statusbar.policy.BluetoothController;
-import com.android.systemui.statusbar.policy.LocationController;
-import com.android.systemui.statusbar.policy.NetworkController;
-
+import android.animation.ValueAnimator;
 import android.app.ActivityManagerNative;
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.app.PendingIntent;
+import android.app.admin.DevicePolicyManager;
 import android.bluetooth.BluetoothAdapter;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -57,10 +46,12 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.provider.AlarmClock;
 import android.provider.ContactsContract;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
 import android.provider.ContactsContract.Profile;
 import android.provider.Settings;
+import android.security.KeyChain;
 import android.util.Log;
 import android.util.Pair;
 import android.view.LayoutInflater;
@@ -71,8 +62,20 @@
 import android.widget.ImageView;
 import android.widget.TextView;
 
-import java.util.ArrayList;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.QuickSettingsModel.ActivityState;
+import com.android.systemui.statusbar.phone.QuickSettingsModel.BluetoothState;
+import com.android.systemui.statusbar.phone.QuickSettingsModel.RSSIState;
+import com.android.systemui.statusbar.phone.QuickSettingsModel.State;
+import com.android.systemui.statusbar.phone.QuickSettingsModel.UserState;
+import com.android.systemui.statusbar.phone.QuickSettingsModel.WifiState;
+import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.BluetoothController;
+import com.android.systemui.statusbar.policy.LocationController;
+import com.android.systemui.statusbar.policy.NetworkController;
+import com.android.systemui.statusbar.policy.RotationLockController;
 
+import java.util.ArrayList;
 
 /**
  *
@@ -90,6 +93,7 @@
     private ViewGroup mContainerView;
 
     private DisplayManager mDisplayManager;
+    private DevicePolicyManager mDevicePolicyManager;
     private WifiDisplayStatus mWifiDisplayStatus;
     private PhoneStatusBar mStatusBarService;
     private BluetoothState mBluetoothState;
@@ -97,8 +101,11 @@
     private WifiManager mWifiManager;
 
     private BluetoothController mBluetoothController;
+    private RotationLockController mRotationLockController;
+    private LocationController mLocationController;
 
     private AsyncTask<Void, Void, Pair<String, Drawable>> mUserInfoTask;
+    private AsyncTask<Void, Void, Pair<Boolean, Boolean>> mQueryCertTask;
 
     private LevelListDrawable mBatteryLevels;
     private LevelListDrawable mChargingBatteryLevels;
@@ -113,16 +120,10 @@
     private final ArrayList<QuickSettingsTileView> mDynamicSpannedTiles =
             new ArrayList<QuickSettingsTileView>();
 
-    private final RotationPolicy.RotationPolicyListener mRotationPolicyListener =
-            new RotationPolicy.RotationPolicyListener() {
-        @Override
-        public void onChange() {
-            mModel.onRotationLockChanged();
-        }
-    };
-
     public QuickSettings(Context context, QuickSettingsContainerView container) {
         mDisplayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
+        mDevicePolicyManager
+            = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
         mContext = context;
         mContainerView = container;
         mModel = new QuickSettingsModel(context);
@@ -144,6 +145,7 @@
         filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
         filter.addAction(Intent.ACTION_USER_SWITCHED);
         filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
+        filter.addAction(KeyChain.ACTION_STORAGE_CHANGED);
         mContext.registerReceiver(mReceiver, filter);
 
         IntentFilter profileFilter = new IntentFilter();
@@ -170,19 +172,42 @@
     }
 
     void setup(NetworkController networkController, BluetoothController bluetoothController,
-            BatteryController batteryController, LocationController locationController) {
+            BatteryController batteryController, LocationController locationController,
+            RotationLockController rotationLockController) {
         mBluetoothController = bluetoothController;
+        mRotationLockController = rotationLockController;
+        mLocationController = locationController;
 
         setupQuickSettings();
         updateWifiDisplayStatus();
         updateResources();
+        applyLocationEnabledStatus();
 
         networkController.addNetworkSignalChangedCallback(mModel);
         bluetoothController.addStateChangedCallback(mModel);
         batteryController.addStateChangedCallback(mModel);
-        locationController.addStateChangedCallback(mModel);
-        RotationPolicy.registerRotationPolicyListener(mContext, mRotationPolicyListener,
-                UserHandle.USER_ALL);
+        locationController.addSettingsChangedCallback(mModel);
+        rotationLockController.addRotationLockControllerCallback(mModel);
+    }
+
+    private void queryForSslCaCerts() {
+        mQueryCertTask = new AsyncTask<Void, Void, Pair<Boolean, Boolean>>() {
+            @Override
+            protected Pair<Boolean, Boolean> doInBackground(Void... params) {
+                boolean hasCert = DevicePolicyManager.hasAnyCaCertsInstalled();
+                boolean isManaged = mDevicePolicyManager.getDeviceOwner() != null;
+
+                return Pair.create(hasCert, isManaged);
+            }
+            @Override
+            protected void onPostExecute(Pair<Boolean, Boolean> result) {
+                super.onPostExecute(result);
+                boolean hasCert = result.first;
+                boolean isManaged = result.second;
+                mModel.setSslCaCertWarningTileInfo(hasCert, isManaged);
+            }
+        };
+        mQueryCertTask.execute();
     }
 
     private void queryForUserInformation() {
@@ -258,6 +283,7 @@
         addTemporaryTiles(mContainerView, inflater);
 
         queryForUserInformation();
+        queryForSslCaCerts();
         mTilesSetUp = true;
     }
 
@@ -377,8 +403,9 @@
 
     private void addSystemTiles(ViewGroup parent, LayoutInflater inflater) {
         // Wi-fi
-        final QuickSettingsBasicTile wifiTile
-                = new QuickSettingsBasicTile(mContext);
+        final QuickSettingsTileView wifiTile = (QuickSettingsTileView)
+                inflater.inflate(R.layout.quick_settings_tile, parent, false);
+        wifiTile.setContent(R.layout.quick_settings_tile_wifi, inflater);
         wifiTile.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
@@ -409,12 +436,15 @@
                     return true;
                 }} );
         }
-        mModel.addWifiTile(wifiTile, new QuickSettingsModel.RefreshCallback() {
+        mModel.addWifiTile(wifiTile, new NetworkActivityCallback() {
             @Override
-            public void refreshView(QuickSettingsTileView unused, State state) {
+            public void refreshView(QuickSettingsTileView view, State state) {
                 WifiState wifiState = (WifiState) state;
-                wifiTile.setImageResource(wifiState.iconId);
-                wifiTile.setText(wifiState.label);
+                ImageView iv = (ImageView) view.findViewById(R.id.image);
+                iv.setImageResource(wifiState.iconId);
+                setActivity(view, wifiState);
+                TextView tv = (TextView) view.findViewById(R.id.text);
+                tv.setText(wifiState.label);
                 wifiTile.setContentDescription(mContext.getString(
                         R.string.accessibility_quick_settings_wifi,
                         wifiState.signalContentDescription,
@@ -438,7 +468,7 @@
                     startSettingsActivity(intent);
                 }
             });
-            mModel.addRSSITile(rssiTile, new QuickSettingsModel.RefreshCallback() {
+            mModel.addRSSITile(rssiTile, new NetworkActivityCallback() {
                 @Override
                 public void refreshView(QuickSettingsTileView view, State state) {
                     RSSIState rssiState = (RSSIState) state;
@@ -454,6 +484,8 @@
                     } else {
                         iov.setImageDrawable(null);
                     }
+                    setActivity(view, rssiState);
+
                     tv.setText(state.label);
                     view.setContentDescription(mContext.getResources().getString(
                             R.string.accessibility_quick_settings_mobile,
@@ -471,18 +503,36 @@
                     = new QuickSettingsBasicTile(mContext);
             rotationLockTile.setOnClickListener(new View.OnClickListener() {
                 @Override
-                public void onClick(View v) {
-                    boolean locked = RotationPolicy.isRotationLocked(mContext);
-                    RotationPolicy.setRotationLock(mContext, !locked);
+                public void onClick(View view) {
+                    final boolean locked = mRotationLockController.isRotationLocked();
+                    mRotationLockController.setRotationLocked(!locked);
                 }
             });
-            mModel.addRotationLockTile(rotationLockTile,
-                    new QuickSettingsModel.BasicRefreshCallback(rotationLockTile));
+            mModel.addRotationLockTile(rotationLockTile, mRotationLockController,
+                    new QuickSettingsModel.RefreshCallback() {
+                        @Override
+                        public void refreshView(QuickSettingsTileView view, State state) {
+                            QuickSettingsModel.RotationLockState rotationLockState =
+                                    (QuickSettingsModel.RotationLockState) state;
+                            view.setVisibility(rotationLockState.visible
+                                    ? View.VISIBLE : View.GONE);
+                            if (state.iconId != 0) {
+                                // needed to flush any cached IDs
+                                rotationLockTile.setImageDrawable(null);
+                                rotationLockTile.setImageResource(state.iconId);
+                            }
+                            if (state.label != null) {
+                                rotationLockTile.setText(state.label);
+                            }
+                        }
+                    });
             parent.addView(rotationLockTile);
         }
 
         // Battery
-        final QuickSettingsBasicTile batteryTile = new QuickSettingsBasicTile(mContext);
+        final QuickSettingsTileView batteryTile = (QuickSettingsTileView)
+                inflater.inflate(R.layout.quick_settings_tile, parent, false);
+        batteryTile.setContent(R.layout.quick_settings_tile_battery, inflater);
         batteryTile.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
@@ -494,9 +544,6 @@
             public void refreshView(QuickSettingsTileView unused, State state) {
                 QuickSettingsModel.BatteryState batteryState =
                         (QuickSettingsModel.BatteryState) state;
-                Drawable d = batteryState.pluggedIn
-                        ? mChargingBatteryLevels
-                        : mBatteryLevels;
                 String t;
                 if (batteryState.batteryLevel == 100) {
                     t = mContext.getString(R.string.quick_settings_battery_charged_label);
@@ -507,9 +554,7 @@
                         : mContext.getString(R.string.status_bar_settings_battery_meter_format,
                                 batteryState.batteryLevel);
                 }
-                batteryTile.setImageDrawable(d);
-                batteryTile.getImageView().setImageLevel(batteryState.batteryLevel);
-                batteryTile.setText(t);
+                ((TextView)batteryTile.findViewById(R.id.text)).setText(t);
                 batteryTile.setContentDescription(
                         mContext.getString(R.string.accessibility_quick_settings_battery, t));
             }
@@ -587,6 +632,35 @@
             parent.addView(bluetoothTile);
         }
 
+        // Location
+        final QuickSettingsBasicTile locationTile
+                = new QuickSettingsBasicTile(mContext);
+        locationTile.setImageResource(R.drawable.ic_qs_location_on);
+        locationTile.setTextResource(R.string.quick_settings_location_label);
+        locationTile.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                startSettingsActivity(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
+            }
+        });
+        if (LONG_PRESS_TOGGLES) {
+            locationTile.setOnLongClickListener(new View.OnLongClickListener() {
+                @Override
+                public boolean onLongClick(View v) {
+                    boolean newLocationEnabledState = !mLocationController.isLocationEnabled();
+                    if (mLocationController.setLocationEnabled(newLocationEnabledState)
+                            && newLocationEnabledState) {
+                        // If we've successfully switched from location off to on, close the
+                        // notifications tray to show the network location provider consent dialog.
+                        Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+                        mContext.sendBroadcast(closeDialog);
+                    }
+                    return true; // Consume click
+                }} );
+        }
+        mModel.addLocationTile(locationTile,
+                new QuickSettingsModel.BasicRefreshCallback(locationTile));
+        parent.addView(locationTile);
     }
 
     private void addTemporaryTiles(final ViewGroup parent, final LayoutInflater inflater) {
@@ -597,12 +671,7 @@
         alarmTile.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                // TODO: Jump into the alarm application
-                Intent intent = new Intent();
-                intent.setComponent(new ComponentName(
-                        "com.google.android.deskclock",
-                        "com.android.deskclock.AlarmClock"));
-                startSettingsActivity(intent);
+                startSettingsActivity(AlarmClock.ACTION_SET_ALARM);
             }
         });
         mModel.addAlarmTile(alarmTile, new QuickSettingsModel.RefreshCallback() {
@@ -616,22 +685,6 @@
         });
         parent.addView(alarmTile);
 
-        // Location
-        final QuickSettingsBasicTile locationTile
-                = new QuickSettingsBasicTile(mContext);
-        locationTile.setImageResource(R.drawable.ic_qs_location);
-        locationTile.setTextResource(R.string.quick_settings_location_label);
-        locationTile.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                startSettingsActivity(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
-            }
-        });
-        mModel.addLocationTile(locationTile,
-                new QuickSettingsModel.BasicRefreshCallback(locationTile)
-                        .setShowWhenEnabled(true));
-        parent.addView(locationTile);
-
         // Wifi Display
         QuickSettingsBasicTile wifiDisplayTile
                 = new QuickSettingsBasicTile(mContext);
@@ -704,6 +757,25 @@
         });
         parent.addView(imeTile);
         */
+
+        // SSL CA Cert Warning.
+        final QuickSettingsBasicTile sslCaCertWarningTile = new QuickSettingsBasicTile(mContext);
+        sslCaCertWarningTile.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                collapsePanels();
+                startSettingsActivity(Settings.ACTION_MONITORING_CERT_INFO);
+            }
+        });
+
+        sslCaCertWarningTile.setImageResource(
+                com.android.internal.R.drawable.indicator_input_error);
+        sslCaCertWarningTile.setTextResource(R.string.ssl_ca_cert_warning);
+
+        mModel.addSslCaCertWarningTile(sslCaCertWarningTile,
+                new QuickSettingsModel.BasicRefreshCallback(sslCaCertWarningTile)
+                        .setShowWhenEnabled(true));
+        parent.addView(sslCaCertWarningTile);
     }
 
     void updateResources() {
@@ -773,6 +845,10 @@
         mModel.onBluetoothStateChange(mBluetoothState);
     }
 
+    private void applyLocationEnabledStatus() {
+        mModel.onLocationSettingsChanged(mLocationController.isLocationEnabled());
+    }
+
     void reloadUserInfo() {
         if (mUserInfoTask != null) {
             mUserInfoTask.cancel(false);
@@ -780,6 +856,7 @@
         }
         if (mTilesSetUp) {
             queryForUserInformation();
+            queryForSslCaCerts();
         }
     }
 
@@ -808,6 +885,8 @@
                 if (mUseDefaultAvatar) {
                     queryForUserInformation();
                 }
+            } else if (KeyChain.ACTION_STORAGE_CHANGED.equals(action)) {
+                queryForSslCaCerts();
             }
         }
     };
@@ -832,4 +911,25 @@
 
         }
     };
+
+    private abstract static class NetworkActivityCallback
+            implements QuickSettingsModel.RefreshCallback {
+        private final long mDefaultDuration = new ValueAnimator().getDuration();
+        private final long mShortDuration = mDefaultDuration / 3;
+
+        public void setActivity(View view, ActivityState state) {
+            setVisibility(view.findViewById(R.id.activity_in), state.activityIn);
+            setVisibility(view.findViewById(R.id.activity_out), state.activityOut);
+        }
+
+        private void setVisibility(View view, boolean visible) {
+            final float newAlpha = visible ? 1 : 0;
+            if (view.getAlpha() != newAlpha) {
+                view.animate()
+                    .setDuration(visible ? mShortDuration : mDefaultDuration)
+                    .alpha(newAlpha)
+                    .start();
+            }
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsBasicTile.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsBasicTile.java
index 94b2fc7..ef850d5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsBasicTile.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsBasicTile.java
@@ -16,8 +16,6 @@
 
 package com.android.systemui.statusbar.phone;
 
-import com.android.systemui.R;
-
 import android.content.Context;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
@@ -26,6 +24,8 @@
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import com.android.systemui.R;
+
 class QuickSettingsBasicTile extends QuickSettingsTileView {
     private final TextView mTextView;
     private final ImageView mImageView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
index 38c46c4..9d0418d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
@@ -39,22 +39,23 @@
 import android.view.inputmethod.InputMethodManager;
 import android.view.inputmethod.InputMethodSubtype;
 
-import com.android.internal.view.RotationPolicy;
 import com.android.systemui.R;
-import com.android.systemui.settings.CurrentUserTracker;
 import com.android.systemui.settings.BrightnessController.BrightnessStateChangeCallback;
+import com.android.systemui.settings.CurrentUserTracker;
 import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
-import com.android.systemui.statusbar.policy.LocationController.LocationGpsStateChangeCallback;
+import com.android.systemui.statusbar.policy.LocationController.LocationSettingsChangeCallback;
 import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
+import com.android.systemui.statusbar.policy.RotationLockController;
+import com.android.systemui.statusbar.policy.RotationLockController.RotationLockControllerCallback;
 
 import java.util.List;
 
-
 class QuickSettingsModel implements BluetoothStateChangeCallback,
         NetworkSignalChangedCallback,
         BatteryStateChangeCallback,
-        LocationGpsStateChangeCallback,
-        BrightnessStateChangeCallback {
+        BrightnessStateChangeCallback,
+        RotationLockControllerCallback,
+        LocationSettingsChangeCallback {
 
     // Sett InputMethoManagerService
     private static final String TAG_TRY_SUPPRESSING_IME_SWITCHER = "TrySuppressingImeSwitcher";
@@ -69,13 +70,17 @@
         int batteryLevel;
         boolean pluggedIn;
     }
-    static class RSSIState extends State {
+    static class ActivityState extends State {
+        boolean activityIn;
+        boolean activityOut;
+    }
+    static class RSSIState extends ActivityState {
         int signalIconId;
         String signalContentDescription;
         int dataTypeIconId;
         String dataContentDescription;
     }
-    static class WifiState extends State {
+    static class WifiState extends ActivityState {
         String signalContentDescription;
         boolean connected;
     }
@@ -89,6 +94,9 @@
         boolean connected = false;
         String stateContentDescription;
     }
+    public static class RotationLockState extends State {
+        boolean visible = false;
+    }
 
     /** The callback to update a given tile. */
     interface RefreshCallback {
@@ -245,7 +253,7 @@
 
     private QuickSettingsTileView mRotationLockTile;
     private RefreshCallback mRotationLockCallback;
-    private State mRotationLockState = new State();
+    private RotationLockState mRotationLockState = new RotationLockState();
 
     private QuickSettingsTileView mBrightnessTile;
     private RefreshCallback mBrightnessCallback;
@@ -259,6 +267,12 @@
     private RefreshCallback mSettingsCallback;
     private State mSettingsState = new State();
 
+    private QuickSettingsTileView mSslCaCertWarningTile;
+    private RefreshCallback mSslCaCertWarningCallback;
+    private State mSslCaCertWarningState = new State();
+
+    private RotationLockController mRotationLockController;
+
     public QuickSettingsModel(Context context) {
         mContext = context;
         mHandler = new Handler();
@@ -413,13 +427,14 @@
         if (string == null) return null;
         final int length = string.length();
         if (string.endsWith(".")) {
-            string.substring(0, length - 1);
+            return string.substring(0, length - 1);
         }
         return string;
     }
     // NetworkSignalChanged callback
     @Override
     public void onWifiSignalChanged(boolean enabled, int wifiSignalIconId,
+            boolean activityIn, boolean activityOut,
             String wifiSignalContentDescription, String enabledDesc) {
         // TODO: If view is in awaiting state, disable
         Resources r = mContext.getResources();
@@ -428,6 +443,8 @@
         boolean wifiNotConnected = (wifiSignalIconId > 0) && (enabledDesc == null);
         mWifiState.enabled = enabled;
         mWifiState.connected = wifiConnected;
+        mWifiState.activityIn = enabled && activityIn;
+        mWifiState.activityOut = enabled && activityOut;
         if (wifiConnected) {
             mWifiState.iconId = wifiSignalIconId;
             mWifiState.label = removeDoubleQuotes(enabledDesc);
@@ -458,7 +475,8 @@
     @Override
     public void onMobileDataSignalChanged(
             boolean enabled, int mobileSignalIconId, String signalContentDescription,
-            int dataTypeIconId, String dataContentDescription, String enabledDesc) {
+            int dataTypeIconId, boolean activityIn, boolean activityOut,
+            String dataContentDescription,String enabledDesc) {
         if (deviceHasMobileData()) {
             // TODO: If view is in awaiting state, disable
             Resources r = mContext.getResources();
@@ -471,6 +489,8 @@
             mRSSIState.dataTypeIconId = enabled && (dataTypeIconId > 0) && !mWifiState.enabled
                     ? dataTypeIconId
                     : 0;
+            mRSSIState.activityIn = enabled && activityIn;
+            mRSSIState.activityOut = enabled && activityOut;
             mRSSIState.dataContentDescription = enabled && (dataTypeIconId > 0) && !mWifiState.enabled
                     ? dataContentDescription
                     : r.getString(R.string.accessibility_no_data);
@@ -551,11 +571,17 @@
         mLocationCallback = cb;
         mLocationCallback.refreshView(mLocationTile, mLocationState);
     }
-    // LocationController callback
+
     @Override
-    public void onLocationGpsStateChanged(boolean inUse, String description) {
-        mLocationState.enabled = inUse;
-        mLocationState.label = description;
+    public void onLocationSettingsChanged(boolean locationEnabled) {
+        int textResId = locationEnabled ? R.string.quick_settings_location_label
+                : R.string.quick_settings_location_off_label;
+        String label = mContext.getText(textResId).toString();
+        int locationIconId = locationEnabled
+                ? R.drawable.ic_qs_location_on : R.drawable.ic_qs_location_off;
+        mLocationState.enabled = locationEnabled;
+        mLocationState.label = label;
+        mLocationState.iconId = locationIconId;
         mLocationCallback.refreshView(mLocationTile, mLocationState);
     }
 
@@ -574,7 +600,7 @@
         } catch (SettingNotFoundException e) {
         }
 
-        mBugreportState.enabled = enabled;
+        mBugreportState.enabled = enabled && mUserTracker.isCurrentUserOwner();
         mBugreportCallback.refreshView(mBugreportTile, mBugreportState);
     }
 
@@ -681,25 +707,29 @@
     }
 
     // Rotation lock
-    void addRotationLockTile(QuickSettingsTileView view, RefreshCallback cb) {
+    void addRotationLockTile(QuickSettingsTileView view,
+            RotationLockController rotationLockController,
+            RefreshCallback cb) {
         mRotationLockTile = view;
         mRotationLockCallback = cb;
+        mRotationLockController = rotationLockController;
         onRotationLockChanged();
     }
     void onRotationLockChanged() {
-        boolean locked = RotationPolicy.isRotationLocked(mContext);
-        mRotationLockState.enabled = locked;
-        mRotationLockState.iconId = locked
+        onRotationLockStateChanged(mRotationLockController.isRotationLocked(),
+                mRotationLockController.isRotationLockAffordanceVisible());
+    }
+    @Override
+    public void onRotationLockStateChanged(boolean rotationLocked, boolean affordanceVisible) {
+        mRotationLockState.visible = affordanceVisible;
+        mRotationLockState.enabled = rotationLocked;
+        mRotationLockState.iconId = rotationLocked
                 ? R.drawable.ic_qs_rotation_locked
                 : R.drawable.ic_qs_auto_rotate;
-        mRotationLockState.label = locked
+        mRotationLockState.label = rotationLocked
                 ? mContext.getString(R.string.quick_settings_rotation_locked_label)
                 : mContext.getString(R.string.quick_settings_rotation_unlocked_label);
-
-        // may be called before addRotationLockTile due to RotationPolicyListener in QuickSettings
-        if (mRotationLockTile != null && mRotationLockCallback != null) {
-            mRotationLockCallback.refreshView(mRotationLockTile, mRotationLockState);
-        }
+        mRotationLockCallback.refreshView(mRotationLockTile, mRotationLockState);
     }
     void refreshRotationLockTile() {
         if (mRotationLockTile != null) {
@@ -731,4 +761,23 @@
     void refreshBrightnessTile() {
         onBrightnessLevelChanged();
     }
+
+    // SSL CA Cert warning.
+    public void addSslCaCertWarningTile(QuickSettingsTileView view, RefreshCallback cb) {
+        mSslCaCertWarningTile = view;
+        mSslCaCertWarningCallback = cb;
+        // Set a sane default while we wait for the AsyncTask to finish (no cert).
+        setSslCaCertWarningTileInfo(false, true);
+    }
+    public void setSslCaCertWarningTileInfo(boolean hasCert, boolean isManaged) {
+        Resources r = mContext.getResources();
+        mSslCaCertWarningState.enabled = hasCert;
+        if (isManaged) {
+            mSslCaCertWarningState.iconId = R.drawable.ic_qs_certificate_info;
+        } else {
+            mSslCaCertWarningState.iconId = android.R.drawable.stat_notify_error;
+        }
+        mSslCaCertWarningState.label = r.getString(R.string.ssl_ca_cert_warning);
+        mSslCaCertWarningCallback.refreshView(mSslCaCertWarningTile, mSslCaCertWarningState);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java
index 33335631..c10a0d4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java
@@ -16,28 +16,24 @@
 
 package com.android.systemui.statusbar.phone;
 
-import android.animation.LayoutTransition;
 import android.content.Context;
-import android.content.Intent;
 import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.util.EventLog;
-import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 
 import com.android.systemui.EventLogTags;
 import com.android.systemui.R;
-import com.android.systemui.statusbar.BaseStatusBar;
 import com.android.systemui.statusbar.GestureRecorder;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.BluetoothController;
 import com.android.systemui.statusbar.policy.LocationController;
 import com.android.systemui.statusbar.policy.NetworkController;
+import com.android.systemui.statusbar.policy.RotationLockController;
 
 public class SettingsPanelView extends PanelView {
     public static final boolean DEBUG_GESTURES = true;
@@ -85,10 +81,11 @@
     }
 
     public void setup(NetworkController networkController, BluetoothController bluetoothController,
-            BatteryController batteryController, LocationController locationController) {
+            BatteryController batteryController, LocationController locationController,
+            RotationLockController rotationLockController) {
         if (mQS != null) {
             mQS.setup(networkController, bluetoothController, batteryController,
-                    locationController);
+                    locationController, rotationLockController);
         }
     }
 
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 5620e1b..a600aae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -20,14 +20,12 @@
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewRootImpl;
 import android.widget.FrameLayout;
 import android.widget.ScrollView;
-import android.widget.TextSwitcher;
 
 import com.android.systemui.ExpandHelper;
 import com.android.systemui.R;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java
index f3f6a80..a6ce288 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java
@@ -16,31 +16,29 @@
 
 package com.android.systemui.statusbar.phone;
 
-import android.service.notification.StatusBarNotification;
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
-import android.text.StaticLayout;
+import android.service.notification.StatusBarNotification;
 import android.text.Layout.Alignment;
+import android.text.StaticLayout;
 import android.text.TextPaint;
 import android.view.View;
 import android.view.animation.AnimationUtils;
+import android.widget.ImageSwitcher;
 import android.widget.TextSwitcher;
 import android.widget.TextView;
-import android.widget.ImageSwitcher;
-
-import java.util.ArrayList;
 
 import com.android.internal.statusbar.StatusBarIcon;
-import com.android.internal.util.CharSequences;
-
 import com.android.systemui.R;
 import com.android.systemui.statusbar.StatusBarIconView;
 
+import java.util.ArrayList;
+
 public abstract class Ticker {
     private static final int TICKER_SEGMENT_DELAY = 3000;
-    
+
     private Context mContext;
     private Handler mHandler = new Handler();
     private ArrayList<Segment> mSegments = new ArrayList();
@@ -192,7 +190,7 @@
             if (n.getPackageName().equals(seg.notification.getPackageName())
                     && n.getNotification().icon == seg.notification.getNotification().icon
                     && n.getNotification().iconLevel == seg.notification.getNotification().iconLevel
-                    && CharSequences.equals(seg.notification.getNotification().tickerText,
+                    && charSequencesEqual(seg.notification.getNotification().tickerText,
                         n.getNotification().tickerText)) {
                 return;
             }
@@ -218,20 +216,34 @@
         if (initialCount == 0 && mSegments.size() > 0) {
             Segment seg = mSegments.get(0);
             seg.first = false;
-            
+
             mIconSwitcher.setAnimateFirstView(false);
             mIconSwitcher.reset();
             mIconSwitcher.setImageDrawable(seg.icon);
-            
+
             mTextSwitcher.setAnimateFirstView(false);
             mTextSwitcher.reset();
             mTextSwitcher.setText(seg.getText());
-            
+
             tickerStarting();
             scheduleAdvance();
         }
     }
 
+    private static boolean charSequencesEqual(CharSequence a, CharSequence b) {
+        if (a.length() != b.length()) {
+            return false;
+        }
+
+        int length = a.length();
+        for (int i = 0; i < length; i++) {
+            if (a.charAt(i) != b.charAt(i)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     public void removeEntry(StatusBarNotification n) {
         for (int i=mSegments.size()-1; i>=0; i--) {
             Segment seg = mSegments.get(i);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrackingPatternView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrackingPatternView.java
deleted file mode 100644
index d2ed5ff..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrackingPatternView.java
+++ /dev/null
@@ -1,70 +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.systemui.statusbar.phone;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.util.AttributeSet;
-import android.util.Slog;
-import android.view.View;
-import android.graphics.BitmapFactory;
-import android.graphics.Bitmap;
-import android.graphics.Paint;
-import android.graphics.Canvas;
-
-public class TrackingPatternView extends View {
-    private Bitmap mTexture;
-    private Paint mPaint;
-    private int mTextureWidth;
-    private int mTextureHeight;
-    
-    public TrackingPatternView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-
-        mTexture = BitmapFactory.decodeResource(getResources(), 
-                com.android.internal.R.drawable.status_bar_background);
-        mTextureWidth = mTexture.getWidth();
-        mTextureHeight = mTexture.getHeight();
-
-        mPaint = new Paint();
-        mPaint.setDither(false);
-    }
-
-    @Override
-    public void onDraw(Canvas canvas) {
-        final Bitmap texture = mTexture;
-        final Paint paint = mPaint;
-
-        final int width = getWidth();
-        final int height = getHeight();
-
-        final int textureWidth = mTextureWidth;
-        final int textureHeight = mTextureHeight;
-
-        int x = 0;
-        int y;
-
-        while (x < width) {
-            y = 0;
-            while (y < height) {
-                canvas.drawBitmap(texture, x, y, paint);
-                y += textureHeight;
-            }
-            x += textureWidth;
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AirplaneModeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AirplaneModeController.java
deleted file mode 100644
index 3c8276d..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AirplaneModeController.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 com.android.systemui.statusbar.policy;
-
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.AsyncTask;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.util.Slog;
-import android.widget.CompoundButton;
-
-public class AirplaneModeController extends BroadcastReceiver
-        implements CompoundButton.OnCheckedChangeListener {
-    private static final String TAG = "StatusBar.AirplaneModeController";
-
-    private Context mContext;
-    private CompoundButton mCheckBox;
-
-    private boolean mAirplaneMode;
-
-    public AirplaneModeController(Context context, CompoundButton checkbox) {
-        mContext = context;
-        mAirplaneMode = getAirplaneMode();
-        mCheckBox = checkbox;
-        checkbox.setChecked(mAirplaneMode);
-        checkbox.setOnCheckedChangeListener(this);
-
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
-        context.registerReceiver(this, filter);
-
-    }
-
-    public void release() {
-        mContext.unregisterReceiver(this);
-    }
-
-    public void onCheckedChanged(CompoundButton view, boolean checked) {
-        if (checked != mAirplaneMode) {
-            mAirplaneMode = checked;
-            unsafe(checked);
-        }
-    }
-
-    public void onReceive(Context context, Intent intent) {
-        if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(intent.getAction())) {
-            final boolean enabled = intent.getBooleanExtra("state", false);
-            if (enabled != mAirplaneMode) {
-                mAirplaneMode = enabled;
-                mCheckBox.setChecked(enabled);
-            }
-        }
-    }
-
-    private boolean getAirplaneMode() {
-        ContentResolver cr = mContext.getContentResolver();
-        return 0 != Settings.Global.getInt(cr, Settings.Global.AIRPLANE_MODE_ON, 0);
-    }
-
-    // TODO: Fix this racy API by adding something better to TelephonyManager or
-    // ConnectivityService.
-    private void unsafe(final boolean enabled) {
-        AsyncTask.execute(new Runnable() {
-                public void run() {
-                    Settings.Global.putInt(
-                            mContext.getContentResolver(),
-                            Settings.Global.AIRPLANE_MODE_ON,
-                            enabled ? 1 : 0);
-                    Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
-                    intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
-                    intent.putExtra("state", enabled);
-                    mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
-                }
-            });
-    }
-}
-
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AutoRotateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AutoRotateController.java
deleted file mode 100644
index 7d58032..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AutoRotateController.java
+++ /dev/null
@@ -1,77 +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.systemui.statusbar.policy;
-
-import com.android.internal.view.RotationPolicy;
-
-import android.content.Context;
-import android.os.UserHandle;
-import android.widget.CompoundButton;
-
-public final class AutoRotateController implements CompoundButton.OnCheckedChangeListener {
-    private final Context mContext;
-    private final CompoundButton mCheckbox;
-    private final RotationLockCallbacks mCallbacks;
-
-    private boolean mAutoRotation;
-
-    private final RotationPolicy.RotationPolicyListener mRotationPolicyListener =
-            new RotationPolicy.RotationPolicyListener() {
-        @Override
-        public void onChange() {
-            updateState();
-        }
-    };
-
-    public AutoRotateController(Context context, CompoundButton checkbox,
-            RotationLockCallbacks callbacks) {
-        mContext = context;
-        mCheckbox = checkbox;
-        mCallbacks = callbacks;
-
-        mCheckbox.setOnCheckedChangeListener(this);
-
-        RotationPolicy.registerRotationPolicyListener(context, mRotationPolicyListener,
-                UserHandle.USER_ALL);
-        updateState();
-    }
-
-    public void onCheckedChanged(CompoundButton view, boolean checked) {
-        if (checked != mAutoRotation) {
-            mAutoRotation = checked;
-            RotationPolicy.setRotationLock(mContext, !checked);
-        }
-    }
-
-    public void release() {
-        RotationPolicy.unregisterRotationPolicyListener(mContext,
-                mRotationPolicyListener);
-    }
-
-    private void updateState() {
-        mAutoRotation = !RotationPolicy.isRotationLocked(mContext);
-        mCheckbox.setChecked(mAutoRotation);
-
-        boolean visible = RotationPolicy.isRotationLockToggleVisible(mContext);
-        mCallbacks.setRotationLockControlVisibility(visible);
-        mCheckbox.setEnabled(visible);
-    }
-
-    public interface RotationLockCallbacks {
-        void setRotationLockControlVisibility(boolean show);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
index 716341f..575b44e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
@@ -16,20 +16,18 @@
 
 package com.android.systemui.statusbar.policy;
 
-import java.util.ArrayList;
-
-import android.bluetooth.BluetoothAdapter.BluetoothStateChangeCallback;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.os.BatteryManager;
-import android.util.Slog;
 import android.widget.ImageView;
 import android.widget.TextView;
 
 import com.android.systemui.R;
 
+import java.util.ArrayList;
+
 public class BatteryController extends BroadcastReceiver {
     private static final String TAG = "StatusBar.BatteryController";
 
@@ -73,7 +71,7 @@
 
             boolean plugged = false;
             switch (status) {
-                case BatteryManager.BATTERY_STATUS_CHARGING: 
+                case BatteryManager.BATTERY_STATUS_CHARGING:
                 case BatteryManager.BATTERY_STATUS_FULL:
                     plugged = true;
                     break;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothController.java
index fece57e..0e53f0d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothController.java
@@ -23,10 +23,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.view.View;
-import android.widget.ImageView;
-
-import com.android.systemui.R;
 
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -35,11 +31,6 @@
 public class BluetoothController extends BroadcastReceiver {
     private static final String TAG = "StatusBar.BluetoothController";
 
-    private Context mContext;
-    private ArrayList<ImageView> mIconViews = new ArrayList<ImageView>();
-
-    private int mIconId = R.drawable.stat_sys_data_bluetooth;
-    private int mContentDescriptionId = 0;
     private boolean mEnabled = false;
 
     private Set<BluetoothDevice> mBondedDevices = new HashSet<BluetoothDevice>();
@@ -48,7 +39,6 @@
             new ArrayList<BluetoothStateChangeCallback>();
 
     public BluetoothController(Context context) {
-        mContext = context;
 
         IntentFilter filter = new IntentFilter();
         filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
@@ -59,16 +49,11 @@
         final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
         if (adapter != null) {
             handleAdapterStateChange(adapter.getState());
-            handleConnectionStateChange(adapter.getConnectionState());
         }
-        refreshViews();
+        fireCallbacks();
         updateBondedBluetoothDevices();
     }
 
-    public void addIconView(ImageView v) {
-        mIconViews.add(v);
-    }
-
     public void addStateChangedCallback(BluetoothStateChangeCallback cb) {
         mChangeCallbacks.add(cb);
     }
@@ -84,14 +69,8 @@
         if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
             handleAdapterStateChange(
                     intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR));
-        } else if (action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) {
-            handleConnectionStateChange(
-                    intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE,
-                        BluetoothAdapter.STATE_DISCONNECTED));
-        } else if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
-            // Fall through and update bonded devices and refresh view
         }
-        refreshViews();
+        fireCallbacks();
         updateBondedBluetoothDevices();
     }
 
@@ -111,31 +90,11 @@
         }
     }
 
-    public void handleAdapterStateChange(int adapterState) {
+    private void handleAdapterStateChange(int adapterState) {
         mEnabled = (adapterState == BluetoothAdapter.STATE_ON);
     }
 
-    public void handleConnectionStateChange(int connectionState) {
-        final boolean connected = (connectionState == BluetoothAdapter.STATE_CONNECTED);
-        if (connected) {
-            mIconId = R.drawable.stat_sys_data_bluetooth_connected;
-            mContentDescriptionId = R.string.accessibility_bluetooth_connected;
-        } else {
-            mIconId = R.drawable.stat_sys_data_bluetooth;
-            mContentDescriptionId = R.string.accessibility_bluetooth_disconnected;
-        }
-    }
-
-    public void refreshViews() {
-        int N = mIconViews.size();
-        for (int i=0; i<N; i++) {
-            ImageView v = mIconViews.get(i);
-            v.setImageResource(mIconId);
-            v.setVisibility(mEnabled ? View.VISIBLE : View.GONE);
-            v.setContentDescription((mContentDescriptionId == 0)
-                    ? null
-                    : mContext.getString(mContentDescriptionId));
-        }
+    private void fireCallbacks() {
         for (BluetoothStateChangeCallback cb : mChangeCallbacks) {
             cb.onBluetoothStateChange(mEnabled);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index bff6cda..8ced1c9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -20,24 +20,17 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
+import android.os.Bundle;
 import android.text.Spannable;
 import android.text.SpannableStringBuilder;
 import android.text.format.DateFormat;
 import android.text.style.CharacterStyle;
-import android.text.style.ForegroundColorSpan;
 import android.text.style.RelativeSizeSpan;
-import android.text.style.RelativeSizeSpan;
-import android.text.style.StyleSpan;
 import android.util.AttributeSet;
-import android.util.Slog;
-import android.view.View;
 import android.widget.TextView;
 
+import com.android.systemui.DemoMode;
+
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
 import java.util.Locale;
@@ -45,12 +38,10 @@
 
 import libcore.icu.LocaleData;
 
-import com.android.internal.R;
-
 /**
  * Digital clock for the status bar.
  */
-public class Clock extends TextView {
+public class Clock extends TextView implements DemoMode {
     private boolean mAttached;
     private Calendar mCalendar;
     private String mClockFormatString;
@@ -133,6 +124,7 @@
     };
 
     final void updateClock() {
+        if (mDemoMode) return;
         mCalendar.setTimeInMillis(System.currentTimeMillis());
         setText(getSmallTime());
     }
@@ -204,9 +196,33 @@
                 return formatted;
             }
         }
- 
+
         return result;
 
     }
+
+    private boolean mDemoMode;
+
+    @Override
+    public void dispatchDemoCommand(String command, Bundle args) {
+        if (!mDemoMode && command.equals(COMMAND_ENTER)) {
+            mDemoMode = true;
+        } else if (mDemoMode && command.equals(COMMAND_EXIT)) {
+            mDemoMode = false;
+            updateClock();
+        } else if (mDemoMode && command.equals(COMMAND_CLOCK)) {
+            String millis = args.getString("millis");
+            String hhmm = args.getString("hhmm");
+            if (millis != null) {
+                mCalendar.setTimeInMillis(Long.parseLong(millis));
+            } else if (hhmm != null && hhmm.length() == 4) {
+                int hh = Integer.parseInt(hhmm.substring(0, 2));
+                int mm = Integer.parseInt(hhmm.substring(2));
+                mCalendar.set(Calendar.HOUR, hh);
+                mCalendar.set(Calendar.MINUTE, mm);
+            }
+            setText(getSmallTime());
+        }
+    }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CompatModeButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CompatModeButton.java
deleted file mode 100644
index 2d951c2..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CompatModeButton.java
+++ /dev/null
@@ -1,61 +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.systemui.statusbar.policy;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.os.RemoteException;
-import android.util.AttributeSet;
-import android.util.Slog;
-import android.view.View;
-import android.widget.ImageView;
-
-import com.android.systemui.R;
-
-public class CompatModeButton extends ImageView {
-    private static final boolean DEBUG = false;
-    private static final String TAG = "StatusBar.CompatModeButton";
-
-    private ActivityManager mAM;
-
-    public CompatModeButton(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public CompatModeButton(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs);
-
-        setClickable(true);
-
-        mAM = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
-
-        refresh();
-    }
-
-    public void refresh() {
-        int mode = mAM.getFrontActivityScreenCompatMode();
-        if (mode == ActivityManager.COMPAT_MODE_UNKNOWN) {
-            // If in an unknown state, don't change.
-            return;
-        }
-        final boolean vis = (mode != ActivityManager.COMPAT_MODE_NEVER
-                          && mode != ActivityManager.COMPAT_MODE_ALWAYS);
-        if (DEBUG) Slog.d(TAG, "compat mode is " + mode + "; icon will " + (vis ? "show" : "hide"));
-        setVisibility(vis ? View.VISIBLE : View.GONE);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CurrentUserTracker.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CurrentUserTracker.java
deleted file mode 100644
index 225ebc1..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CurrentUserTracker.java
+++ /dev/null
@@ -1,45 +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.systemui.statusbar.policy;
-
-import android.app.ActivityManager;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-
-public class CurrentUserTracker extends BroadcastReceiver {
-
-    private int mCurrentUserId;
-
-    public CurrentUserTracker(Context context) {
-        IntentFilter filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
-        context.registerReceiver(this, filter);
-        mCurrentUserId = ActivityManager.getCurrentUser();
-    }
-
-    public int getCurrentUserId() {
-        return mCurrentUserId;
-    }
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
-            mCurrentUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
index 27a3a15..277501d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
@@ -36,6 +36,10 @@
 public class DateView extends TextView {
     private static final String TAG = "DateView";
 
+    private final Date mCurrentTime = new Date();
+
+    private SimpleDateFormat mDateFormat;
+    private boolean mChangedLocale;
     private boolean mAttachedToWindow;
     private boolean mWindowVisible;
     private boolean mUpdating;
@@ -48,6 +52,9 @@
                     || Intent.ACTION_TIME_CHANGED.equals(action)
                     || Intent.ACTION_TIMEZONE_CHANGED.equals(action)
                     || Intent.ACTION_LOCALE_CHANGED.equals(action)) {
+                if (Intent.ACTION_LOCALE_CHANGED.equals(action)) {
+                    mChangedLocale = true;
+                }
                 updateClock();
             }
         }
@@ -63,7 +70,7 @@
         mAttachedToWindow = true;
         setUpdates();
     }
-    
+
     @Override
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
@@ -91,11 +98,16 @@
     }
 
     protected void updateClock() {
-        final String dateFormat = getContext().getString(R.string.system_ui_date_pattern);
-        final Locale l = Locale.getDefault();
-        String fmt = ICU.getBestDateTimePattern(dateFormat, l.toString());
-        SimpleDateFormat sdf = new SimpleDateFormat(fmt, l);
-        setText(sdf.format(new Date()));
+        if (mDateFormat == null || mChangedLocale) {
+            final String dateFormat = getContext().getString(R.string.system_ui_date_pattern);
+            final Locale l = Locale.getDefault();
+            final String fmt = ICU.getBestDateTimePattern(dateFormat, l.toString());
+            mDateFormat = new SimpleDateFormat(fmt, l);
+            mChangedLocale = false;
+        }
+
+        mCurrentTime.setTime(System.currentTimeMillis());
+        setText(mDateFormat.format(mCurrentTime));
     }
 
     private boolean isVisible() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java
index 6eb88be..dca5e41 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java
@@ -22,7 +22,7 @@
 import android.graphics.Canvas;
 import android.os.SystemClock;
 import android.util.AttributeSet;
-import android.util.Slog;
+import android.util.Log;
 import android.view.MotionEvent;
 import android.view.View;
 
@@ -75,7 +75,7 @@
         mVertical = (index == VERTICAL);
 
         if (DEBUG)
-            Slog.v(TAG, this + " size=[" + mSizeMin + "-" + mSizeMax + "] hold=" + mHold
+            Log.v(TAG, this + " size=[" + mSizeMin + "-" + mSizeMax + "] hold=" + mHold
                     + (mVertical ? " vertical" : " horizontal"));
 
         setFlashOnTouchCapture(context.getResources().getBoolean(R.bool.config_dead_zone_flash));
@@ -106,7 +106,7 @@
     @Override
     public boolean onTouchEvent(MotionEvent event) {
         if (DEBUG) {
-            Slog.v(TAG, this + " onTouch: " + MotionEvent.actionToString(event.getAction()));
+            Log.v(TAG, this + " onTouch: " + MotionEvent.actionToString(event.getAction()));
         }
 
         final int action = event.getAction();
@@ -114,12 +114,12 @@
             poke(event);
         } else if (action == MotionEvent.ACTION_DOWN) {
             if (DEBUG) {
-                Slog.v(TAG, this + " ACTION_DOWN: " + event.getX() + "," + event.getY());
+                Log.v(TAG, this + " ACTION_DOWN: " + event.getX() + "," + event.getY());
             }
             int size = (int) getSize(event.getEventTime());
             if ((mVertical && event.getX() < size) || event.getY() < size) {
                 if (CHATTY) {
-                    Slog.v(TAG, "consuming errant click: (" + event.getX() + "," + event.getY() + ")");
+                    Log.v(TAG, "consuming errant click: (" + event.getX() + "," + event.getY() + ")");
                 }
                 if (mShouldFlash) {
                     post(mDebugFlash);
@@ -134,7 +134,7 @@
     public void poke(MotionEvent event) {
         mLastPokeTime = event.getEventTime();
         if (DEBUG)
-            Slog.v(TAG, "poked! size=" + getSize(mLastPokeTime));
+            Log.v(TAG, "poked! size=" + getSize(mLastPokeTime));
         if (mShouldFlash) postInvalidate();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DoNotDisturbController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DoNotDisturbController.java
deleted file mode 100644
index 94c8aa5..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DoNotDisturbController.java
+++ /dev/null
@@ -1,77 +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.systemui.statusbar.policy;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.provider.Settings;
-import android.util.Slog;
-import android.view.IWindowManager;
-import android.widget.CompoundButton;
-
-public class DoNotDisturbController implements CompoundButton.OnCheckedChangeListener,
-        SharedPreferences.OnSharedPreferenceChangeListener {
-    private static final String TAG = "StatusBar.DoNotDisturbController";
-
-    SharedPreferences mPrefs;
-    private Context mContext;
-    private CompoundButton mCheckBox;
-
-    private boolean mDoNotDisturb;
-
-    public DoNotDisturbController(Context context, CompoundButton checkbox) {
-        mContext = context;
-
-        mPrefs = Prefs.read(context);
-        mPrefs.registerOnSharedPreferenceChangeListener(this);
-        mDoNotDisturb = mPrefs.getBoolean(Prefs.DO_NOT_DISTURB_PREF, Prefs.DO_NOT_DISTURB_DEFAULT);
-
-        mCheckBox = checkbox;
-        checkbox.setOnCheckedChangeListener(this);
-
-        checkbox.setChecked(!mDoNotDisturb);
-    }
-
-    // The checkbox is ON for notifications coming in and OFF for Do not disturb, so we
-    // don't have a double negative.
-    public void onCheckedChanged(CompoundButton view, boolean checked) {
-        //Slog.d(TAG, "onCheckedChanged checked=" + checked + " mDoNotDisturb=" + mDoNotDisturb);
-        final boolean value = !checked;
-        if (value != mDoNotDisturb) {
-            SharedPreferences.Editor editor = Prefs.edit(mContext);
-            editor.putBoolean(Prefs.DO_NOT_DISTURB_PREF, value);
-            editor.apply();
-        }
-    }
-    
-    public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
-        final boolean val = prefs.getBoolean(Prefs.DO_NOT_DISTURB_PREF,
-                Prefs.DO_NOT_DISTURB_DEFAULT);
-        if (val != mDoNotDisturb) {
-            mDoNotDisturb = val;
-            mCheckBox.setChecked(!val);
-        }
-    }
-
-    public void release() {
-        mPrefs.unregisterOnSharedPreferenceChangeListener(this);
-    }
-}
-
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EventHole.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EventHole.java
deleted file mode 100644
index 47e758c..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EventHole.java
+++ /dev/null
@@ -1,99 +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.systemui.statusbar.policy;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Region;
-import android.graphics.drawable.AnimationDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.ServiceManager;
-import android.util.AttributeSet;
-import android.util.Slog;
-import android.view.HapticFeedbackConstants;
-import android.view.IWindowManager;
-import android.view.InputDevice;
-import android.view.KeyCharacterMap;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.ViewTreeObserver;
-import android.widget.RemoteViews.RemoteView;
-
-import com.android.systemui.R;
-
-public class EventHole extends View implements ViewTreeObserver.OnComputeInternalInsetsListener {
-    private static final String TAG = "StatusBar.EventHole";
-
-    private boolean mWindowVis;
-    private int[] mLoc = new int[2];
-
-    public EventHole(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public EventHole(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs);
-    }
-
-    @Override
-    protected void onWindowVisibilityChanged(int visibility) {
-        super.onWindowVisibilityChanged(visibility);
-        mWindowVis = visibility == View.VISIBLE;
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        getViewTreeObserver().addOnComputeInternalInsetsListener(this);
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        getViewTreeObserver().removeOnComputeInternalInsetsListener(this);
-    }
-
-    public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo info) {
-        final boolean visible = isShown() && mWindowVis && getWidth() > 0 && getHeight() > 0;
-        final int[] loc = mLoc;
-        getLocationInWindow(loc);
-        final int l = loc[0];
-        final int r = l + getWidth();
-        final int t = loc[1];
-        final int b = t + getHeight();
-        
-        View top = this;
-        while (top.getParent() instanceof View) {
-            top = (View)top.getParent();
-        }
-
-        if (visible) {
-            info.setTouchableInsets(
-                    ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
-            info.touchableRegion.set(0, 0, top.getWidth(), top.getHeight());
-            info.touchableRegion.op(l, t, r, b, Region.Op.DIFFERENCE);
-        } else {
-            info.setTouchableInsets(
-                    ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME);
-        }
-    }
-}
-
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FixedSizeDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FixedSizeDrawable.java
deleted file mode 100644
index 8f2f5f9..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FixedSizeDrawable.java
+++ /dev/null
@@ -1,66 +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.systemui.statusbar.policy;
-
-import android.graphics.drawable.Drawable;
-import android.graphics.Canvas;
-import android.graphics.ColorFilter;
-import android.graphics.Rect;
-import android.util.Slog;
-
-public class FixedSizeDrawable extends Drawable {
-    Drawable mDrawable;
-    int mLeft;
-    int mTop;
-    int mRight;
-    int mBottom;
-
-    public FixedSizeDrawable(Drawable that) {
-        mDrawable = that;
-    }
-
-    public void setFixedBounds(int l, int t, int r, int b) {
-        mLeft = l;
-        mTop = t;
-        mRight = r;
-        mBottom = b;
-    }
-
-    public void setBounds(Rect bounds) {
-        mDrawable.setBounds(mLeft, mTop, mRight, mBottom);
-    }
-
-    public void setBounds(int l, int t, int r, int b) {
-        mDrawable.setBounds(mLeft, mTop, mRight, mBottom);
-    }
-
-    public void draw(Canvas canvas) {
-        mDrawable.draw(canvas);
-    }
-
-    public int getOpacity() {
-        return mDrawable.getOpacity();
-    }
-
-    public void setAlpha(int alpha) {
-        mDrawable.setAlpha(alpha);
-    }
-
-    public void setColorFilter(ColorFilter cf) {
-        mDrawable.setColorFilter(cf);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
new file mode 100644
index 0000000..f1fda78
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
@@ -0,0 +1,237 @@
+/*
+ * 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.systemui.statusbar.policy;
+
+import android.app.Notification;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+
+import com.android.systemui.ExpandHelper;
+import com.android.systemui.R;
+import com.android.systemui.SwipeHelper;
+import com.android.systemui.statusbar.BaseStatusBar;
+import com.android.systemui.statusbar.NotificationData;
+
+public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.Callback, ExpandHelper.Callback {
+    private static final String TAG = "HeadsUpNotificationView";
+    private static final boolean DEBUG = false;
+    private static final boolean SPEW = DEBUG;
+
+    Rect mTmpRect = new Rect();
+
+    private final int mTouchSensitivityDelay;
+    private SwipeHelper mSwipeHelper;
+
+    private BaseStatusBar mBar;
+    private ExpandHelper mExpandHelper;
+    private long mStartTouchTime;
+
+    private ViewGroup mContentHolder;
+    private ViewGroup mContentSlider;
+
+    private NotificationData.Entry mHeadsUp;
+
+    public HeadsUpNotificationView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public HeadsUpNotificationView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        mTouchSensitivityDelay = getResources().getInteger(R.integer.heads_up_sensitivity_delay);
+        if (DEBUG) Log.v(TAG, "create() " + mTouchSensitivityDelay);
+    }
+
+    public void setBar(BaseStatusBar bar) {
+        mBar = bar;
+    }
+
+    public ViewGroup getHolder() {
+        return mContentHolder;
+    }
+
+    public boolean setNotification(NotificationData.Entry headsUp) {
+        mHeadsUp = headsUp;
+        mHeadsUp.row.setExpanded(false);
+        if (mContentHolder == null) {
+            // too soon!
+            return false;
+        }
+        mContentHolder.setX(0);
+        mContentHolder.setVisibility(View.VISIBLE);
+        mContentHolder.setAlpha(1f);
+        mContentHolder.removeAllViews();
+        mContentHolder.addView(mHeadsUp.row);
+        mSwipeHelper.snapChild(mContentSlider, 1f);
+        mStartTouchTime = System.currentTimeMillis() + mTouchSensitivityDelay;
+        return true;
+    }
+
+    public boolean isClearable() {
+        return mHeadsUp == null || mHeadsUp.notification.isClearable();
+    }
+
+    public void setMargin(int notificationPanelMarginPx) {
+        if (SPEW) Log.v(TAG, "setMargin() " + notificationPanelMarginPx);
+        if (mContentSlider != null) {
+            FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mContentSlider.getLayoutParams();
+            lp.setMarginStart(notificationPanelMarginPx);
+            mContentSlider.setLayoutParams(lp);
+        }
+    }
+
+    // LinearLayout methods
+
+    @Override
+    public void onDraw(android.graphics.Canvas c) {
+        super.onDraw(c);
+        if (DEBUG) {
+            //Log.d(TAG, "onDraw: canvas height: " + c.getHeight() + "px; measured height: "
+            //        + getMeasuredHeight() + "px");
+            c.save();
+            c.clipRect(6, 6, c.getWidth() - 6, getMeasuredHeight() - 6,
+                    android.graphics.Region.Op.DIFFERENCE);
+            c.drawColor(0xFFcc00cc);
+            c.restore();
+        }
+    }
+
+    // ViewGroup methods
+
+    @Override
+    public void onAttachedToWindow() {
+        float densityScale = getResources().getDisplayMetrics().density;
+        float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop();
+        mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, densityScale, pagingTouchSlop);
+
+        int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_min_height);
+        int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_max_height);
+        mExpandHelper = new ExpandHelper(mContext, this, minHeight, maxHeight);
+
+        mContentHolder = (ViewGroup) findViewById(R.id.content_holder);
+        mContentSlider = (ViewGroup) findViewById(R.id.content_slider);
+
+        if (mHeadsUp != null) {
+            // whoops, we're on already!
+            setNotification(mHeadsUp);
+        }
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        if (DEBUG) Log.v(TAG, "onInterceptTouchEvent()");
+        if (System.currentTimeMillis() < mStartTouchTime) {
+            return true;
+        }
+        return mSwipeHelper.onInterceptTouchEvent(ev)
+                || mExpandHelper.onInterceptTouchEvent(ev)
+                || super.onInterceptTouchEvent(ev);
+    }
+
+    // View methods
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        if (System.currentTimeMillis() < mStartTouchTime) {
+            return false;
+        }
+        mBar.resetHeadsUpDecayTimer();
+        return mSwipeHelper.onTouchEvent(ev)
+                || mExpandHelper.onTouchEvent(ev)
+                || super.onTouchEvent(ev);
+    }
+
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        float densityScale = getResources().getDisplayMetrics().density;
+        mSwipeHelper.setDensityScale(densityScale);
+        float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop();
+        mSwipeHelper.setPagingTouchSlop(pagingTouchSlop);
+    }
+
+    // ExpandHelper.Callback methods
+
+    @Override
+    public View getChildAtRawPosition(float x, float y) {
+        return getChildAtPosition(x, y);
+    }
+
+    @Override
+    public View getChildAtPosition(float x, float y) {
+        return mHeadsUp == null ? null : mHeadsUp.row;
+    }
+
+    @Override
+    public boolean canChildBeExpanded(View v) {
+        return mHeadsUp != null && mHeadsUp.row == v && mHeadsUp.row.isExpandable();
+    }
+
+    @Override
+    public void setUserExpandedChild(View v, boolean userExpanded) {
+        if (mHeadsUp != null && mHeadsUp.row == v) {
+            mHeadsUp.row.setUserExpanded(userExpanded);
+        }
+    }
+
+    @Override
+    public void setUserLockedChild(View v, boolean userLocked) {
+        if (mHeadsUp != null && mHeadsUp.row == v) {
+            mHeadsUp.row.setUserLocked(userLocked);
+        }
+    }
+
+    // SwipeHelper.Callback methods
+
+    @Override
+    public boolean canChildBeDismissed(View v) {
+        return true;
+    }
+
+    @Override
+    public void onChildDismissed(View v) {
+        Log.v(TAG, "User swiped heads up to dismiss");
+        mBar.onHeadsUpDismissed();
+    }
+
+    @Override
+    public void onBeginDrag(View v) {
+    }
+
+    @Override
+    public void onDragCancelled(View v) {
+        mContentHolder.setAlpha(1f); // sometimes this isn't quite reset
+    }
+
+    @Override
+    public View getChildAtPosition(MotionEvent ev) {
+        return mContentSlider;
+    }
+
+    @Override
+    public View getChildContentView(View v) {
+        return mContentSlider;
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/IntruderAlertView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/IntruderAlertView.java
deleted file mode 100644
index ee5c863..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/IntruderAlertView.java
+++ /dev/null
@@ -1,176 +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.systemui.statusbar.policy;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.LayoutTransition;
-import android.animation.ObjectAnimator;
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.TypedArray;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.Slog;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewConfiguration;
-import android.view.ViewGroup;
-import android.widget.LinearLayout;
-import android.widget.RemoteViews;
-
-import com.android.systemui.R;
-import com.android.systemui.SwipeHelper;
-import com.android.systemui.statusbar.BaseStatusBar;
-
-import java.util.HashMap;
-
-public class IntruderAlertView extends LinearLayout implements SwipeHelper.Callback {
-    private static final String TAG = "IntruderAlertView";
-    private static final boolean DEBUG = false;
-
-    Rect mTmpRect = new Rect();
-
-    private SwipeHelper mSwipeHelper;
-    
-    BaseStatusBar mBar;
-    private ViewGroup mContentHolder;
-    
-    private RemoteViews mIntruderRemoteViews;
-    private OnClickListener mOnClickListener;
-
-    public IntruderAlertView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public IntruderAlertView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-
-        setOrientation(LinearLayout.VERTICAL);
-    }
-
-    @Override
-    public void onAttachedToWindow() {
-        float densityScale = getResources().getDisplayMetrics().density;
-        float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop();
-        mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, densityScale, pagingTouchSlop);
-        
-        mContentHolder = (ViewGroup) findViewById(R.id.contentHolder);
-        if (mIntruderRemoteViews != null) {
-            // whoops, we're on already!
-            applyIntruderContent(mIntruderRemoteViews, mOnClickListener);
-        }
-    }
-    
-    public void setBar(BaseStatusBar bar) {
-        mBar = bar;
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-        if (DEBUG) Log.v(TAG, "onInterceptTouchEvent()");
-        return mSwipeHelper.onInterceptTouchEvent(ev) ||
-            super.onInterceptTouchEvent(ev);
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev) {
-        return mSwipeHelper.onTouchEvent(ev) ||
-            super.onTouchEvent(ev);
-    }
-
-    public boolean canChildBeDismissed(View v) {
-        return true;
-    }
-
-    public void onChildDismissed(View v) {
-        Slog.v(TAG, "User swiped intruder to dismiss");
-        mBar.dismissIntruder();
-    }
-
-    public void onBeginDrag(View v) {
-    }
-
-    public void onDragCancelled(View v) {
-        mContentHolder.setAlpha(1f); // sometimes this isn't quite reset
-    }
-
-    public View getChildAtPosition(MotionEvent ev) {
-        return mContentHolder;
-    }
-
-    public View getChildContentView(View v) {
-        return v;
-    }
-
-    @Override
-    protected void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        float densityScale = getResources().getDisplayMetrics().density;
-        mSwipeHelper.setDensityScale(densityScale);
-        float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop();
-        mSwipeHelper.setPagingTouchSlop(pagingTouchSlop);
-    }
-
-    @Override
-    public void onDraw(android.graphics.Canvas c) {
-        super.onDraw(c);
-        if (DEBUG) {
-            //Slog.d(TAG, "onDraw: canvas height: " + c.getHeight() + "px; measured height: "
-            //        + getMeasuredHeight() + "px");
-            c.save();
-            c.clipRect(6, 6, c.getWidth() - 6, getMeasuredHeight() - 6,
-                    android.graphics.Region.Op.DIFFERENCE);
-            c.drawColor(0xFFcc00cc);
-            c.restore();
-        }
-    }
-
-    public void applyIntruderContent(RemoteViews intruderView, OnClickListener listener) {
-        if (DEBUG) {
-            Slog.v(TAG, "applyIntruderContent: view=" + intruderView + " listener=" + listener);
-        }
-        mIntruderRemoteViews = intruderView;
-        mOnClickListener = listener;
-        if (mContentHolder == null) { 
-            // too soon!
-            return;
-        }
-        mContentHolder.setX(0);
-        mContentHolder.setVisibility(View.VISIBLE);
-        mContentHolder.setAlpha(1f);
-        mContentHolder.removeAllViews();
-        final View content = intruderView.apply(getContext(), mContentHolder);
-        if (listener != null) {
-            content.setOnClickListener(listener);
-            
-            //content.setBackgroundResource(R.drawable.intruder_row_bg);
-            Drawable bg = getResources().getDrawable(R.drawable.intruder_row_bg);
-            if (bg == null) {
-                Log.e(TAG, String.format("Can't find background drawable id=0x%08x", R.drawable.intruder_row_bg));
-            } else {
-                content.setBackgroundDrawable(bg);
-            }
-        }
-        mContentHolder.addView(content);
-        
-    }
-}
\ No newline at end of file
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 82d6a99..55fb95d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -16,21 +16,19 @@
 
 package com.android.systemui.statusbar.policy;
 
+import android.animation.Animator;
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.content.res.TypedArray;
-import android.graphics.drawable.Drawable;
 import android.graphics.Canvas;
 import android.graphics.RectF;
+import android.graphics.drawable.Drawable;
 import android.hardware.input.InputManager;
-import android.os.RemoteException;
 import android.os.SystemClock;
-import android.os.ServiceManager;
 import android.util.AttributeSet;
-import android.view.accessibility.AccessibilityEvent;
+import android.util.Log;
 import android.view.HapticFeedbackConstants;
-import android.view.IWindowManager;
 import android.view.InputDevice;
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
@@ -38,15 +36,17 @@
 import android.view.SoundEffectConstants;
 import android.view.View;
 import android.view.ViewConfiguration;
+import android.view.accessibility.AccessibilityEvent;
 import android.widget.ImageView;
 
 import com.android.systemui.R;
 
 public class KeyButtonView extends ImageView {
     private static final String TAG = "StatusBar.KeyButtonView";
+    private static final boolean DEBUG = false;
 
     final float GLOW_MAX_SCALE_FACTOR = 1.8f;
-    final float BUTTON_QUIESCENT_ALPHA = 0.70f;
+    public static final float DEFAULT_QUIESCENT_ALPHA = 0.70f;
 
     long mDownTime;
     int mCode;
@@ -54,14 +54,16 @@
     Drawable mGlowBG;
     int mGlowWidth, mGlowHeight;
     float mGlowAlpha = 0f, mGlowScale = 1f, mDrawingAlpha = 1f;
+    float mQuiescentAlpha = DEFAULT_QUIESCENT_ALPHA;
     boolean mSupportsLongpress = true;
     RectF mRect = new RectF(0f,0f,0f,0f);
     AnimatorSet mPressedAnim;
+    Animator mAnimateToQuiescent = new ObjectAnimator();
 
     Runnable mCheckLongPress = new Runnable() {
         public void run() {
             if (isPressed()) {
-                // Slog.d("KeyButtonView", "longpressed: " + this);
+                // Log.d("KeyButtonView", "longpressed: " + this);
                 if (mCode != 0) {
                     sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS);
                     sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
@@ -84,16 +86,16 @@
                 defStyle, 0);
 
         mCode = a.getInteger(R.styleable.KeyButtonView_keyCode, 0);
-        
+
         mSupportsLongpress = a.getBoolean(R.styleable.KeyButtonView_keyRepeat, true);
 
         mGlowBG = a.getDrawable(R.styleable.KeyButtonView_glowBackground);
         if (mGlowBG != null) {
-            setDrawingAlpha(BUTTON_QUIESCENT_ALPHA);
+            setDrawingAlpha(mQuiescentAlpha);
             mGlowWidth = mGlowBG.getIntrinsicWidth();
             mGlowHeight = mGlowBG.getIntrinsicHeight();
         }
-        
+
         a.recycle();
 
         setClickable(true);
@@ -121,6 +123,26 @@
         super.onDraw(canvas);
     }
 
+    public void setQuiescentAlpha(float alpha, boolean animate) {
+        mAnimateToQuiescent.cancel();
+        alpha = Math.min(Math.max(alpha, 0), 1);
+        if (alpha == mQuiescentAlpha) return;
+        mQuiescentAlpha = alpha;
+        if (DEBUG) Log.d(TAG, "New quiescent alpha = " + mQuiescentAlpha);
+        if (mGlowBG != null) {
+            if (animate) {
+                mAnimateToQuiescent = animateToQuiescent();
+                mAnimateToQuiescent.start();
+            } else {
+                setDrawingAlpha(mQuiescentAlpha);
+            }
+        }
+    }
+
+    private ObjectAnimator animateToQuiescent() {
+        return ObjectAnimator.ofFloat(this, "drawingAlpha", mQuiescentAlpha);
+    }
+
     public float getDrawingAlpha() {
         if (mGlowBG == null) return 0;
         return mDrawingAlpha;
@@ -183,10 +205,10 @@
                 }
                 final AnimatorSet as = mPressedAnim = new AnimatorSet();
                 if (pressed) {
-                    if (mGlowScale < GLOW_MAX_SCALE_FACTOR) 
+                    if (mGlowScale < GLOW_MAX_SCALE_FACTOR)
                         mGlowScale = GLOW_MAX_SCALE_FACTOR;
-                    if (mGlowAlpha < BUTTON_QUIESCENT_ALPHA)
-                        mGlowAlpha = BUTTON_QUIESCENT_ALPHA;
+                    if (mGlowAlpha < mQuiescentAlpha)
+                        mGlowAlpha = mQuiescentAlpha;
                     setDrawingAlpha(1f);
                     as.playTogether(
                         ObjectAnimator.ofFloat(this, "glowAlpha", 1f),
@@ -194,10 +216,12 @@
                     );
                     as.setDuration(50);
                 } else {
+                    mAnimateToQuiescent.cancel();
+                    mAnimateToQuiescent = animateToQuiescent();
                     as.playTogether(
                         ObjectAnimator.ofFloat(this, "glowAlpha", 0f),
                         ObjectAnimator.ofFloat(this, "glowScale", 1f),
-                        ObjectAnimator.ofFloat(this, "drawingAlpha", BUTTON_QUIESCENT_ALPHA)
+                        mAnimateToQuiescent
                     );
                     as.setDuration(500);
                 }
@@ -213,7 +237,7 @@
 
         switch (action) {
             case MotionEvent.ACTION_DOWN:
-                //Slog.d("KeyButtonView", "press");
+                //Log.d("KeyButtonView", "press");
                 mDownTime = SystemClock.uptimeMillis();
                 setPressed(true);
                 if (mCode != 0) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
index 68d048d..312bba3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
@@ -16,127 +16,209 @@
 
 package com.android.systemui.statusbar.policy;
 
-import java.util.ArrayList;
-
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
+import android.app.ActivityManager;
+import android.app.AppOpsManager;
+import android.app.StatusBarManager;
 import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.database.ContentObserver;
 import android.location.LocationManager;
+import android.os.Handler;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.provider.Settings;
 
-// private NM API
-import android.app.INotificationManager;
-
 import com.android.systemui.R;
 
-public class LocationController extends BroadcastReceiver {
-    private static final String TAG = "StatusBar.LocationController";
+import java.util.ArrayList;
+import java.util.List;
 
-    private static final int GPS_NOTIFICATION_ID = 374203-122084;
+/**
+ * A controller to manage changes of location related states and update the views accordingly.
+ */
+public class LocationController extends BroadcastReceiver {
+    // The name of the placeholder corresponding to the location request status icon.
+    // This string corresponds to config_statusBarIcons in core/res/res/values/config.xml.
+    public static final String LOCATION_STATUS_ICON_PLACEHOLDER = "location";
+    public static final int LOCATION_STATUS_ICON_ID
+        = R.drawable.stat_sys_device_access_location_found;
+
+    private static final int[] mHighPowerRequestAppOpArray
+        = new int[] {AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION};
 
     private Context mContext;
 
-    private INotificationManager mNotificationService;
+    private AppOpsManager mAppOpsManager;
+    private StatusBarManager mStatusBarManager;
 
-    private ArrayList<LocationGpsStateChangeCallback> mChangeCallbacks =
-            new ArrayList<LocationGpsStateChangeCallback>();
+    private boolean mAreActiveLocationRequests;
 
-    public interface LocationGpsStateChangeCallback {
-        public void onLocationGpsStateChanged(boolean inUse, String description);
+    private ArrayList<LocationSettingsChangeCallback> mSettingsChangeCallbacks =
+            new ArrayList<LocationSettingsChangeCallback>();
+
+    /**
+     * A callback for change in location settings (the user has enabled/disabled location).
+     */
+    public interface LocationSettingsChangeCallback {
+        /**
+         * Called whenever location settings change.
+         *
+         * @param locationEnabled A value of true indicates that at least one type of location
+         *                        is enabled in settings.
+         */
+        public void onLocationSettingsChanged(boolean locationEnabled);
     }
 
     public LocationController(Context context) {
         mContext = context;
 
         IntentFilter filter = new IntentFilter();
-        filter.addAction(LocationManager.GPS_ENABLED_CHANGE_ACTION);
-        filter.addAction(LocationManager.GPS_FIX_CHANGE_ACTION);
+        filter.addAction(LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION);
         context.registerReceiver(this, filter);
 
-        NotificationManager nm = (NotificationManager)context.getSystemService(
-                Context.NOTIFICATION_SERVICE);
-        mNotificationService = nm.getService();
+        mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
+        mStatusBarManager
+                = (StatusBarManager) context.getSystemService(Context.STATUS_BAR_SERVICE);
+
+        // Register to listen for changes in location settings.
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(LocationManager.MODE_CHANGED_ACTION);
+        context.registerReceiverAsUser(new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                String action = intent.getAction();
+                if (LocationManager.MODE_CHANGED_ACTION.equals(action)) {
+                    locationSettingsChanged();
+                }
+            }
+        }, UserHandle.ALL, intentFilter, null, new Handler());
+
+        // Examine the current location state and initialize the status view.
+        updateActiveLocationRequests();
+        refreshViews();
     }
 
-    public void addStateChangedCallback(LocationGpsStateChangeCallback cb) {
-        mChangeCallbacks.add(cb);
+    /**
+     * Add a callback to listen for changes in location settings.
+     */
+    public void addSettingsChangedCallback(LocationSettingsChangeCallback cb) {
+        mSettingsChangeCallbacks.add(cb);
+    }
+
+    /**
+     * Enable or disable location in settings.
+     *
+     * <p>This will attempt to enable/disable every type of location setting
+     * (e.g. high and balanced power).
+     *
+     * <p>If enabling, a user consent dialog will pop up prompting the user to accept.
+     * If the user doesn't accept, network location won't be enabled.
+     *
+     * @return true if attempt to change setting was successful.
+     */
+    public boolean setLocationEnabled(boolean enabled) {
+        int currentUserId = ActivityManager.getCurrentUser();
+        if (isUserLocationRestricted(currentUserId)) {
+            return false;
+        }
+        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 mode = enabled
+                ? Settings.Secure.LOCATION_MODE_HIGH_ACCURACY : 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);
+    }
+
+    /**
+     * Returns true if location isn't disabled in settings.
+     */
+    public boolean isLocationEnabled() {
+        ContentResolver resolver = mContext.getContentResolver();
+        // QuickSettings always runs as the owner, so specifically retrieve the settings
+        // for the current foreground user.
+        int mode = Settings.Secure.getIntForUser(resolver, Settings.Secure.LOCATION_MODE,
+                Settings.Secure.LOCATION_MODE_OFF, ActivityManager.getCurrentUser());
+        return mode != Settings.Secure.LOCATION_MODE_OFF;
+    }
+
+    /**
+     * Returns true if the current user is restricted from using location.
+     */
+    private boolean isUserLocationRestricted(int userId) {
+        final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        return um.hasUserRestriction(
+                UserManager.DISALLOW_SHARE_LOCATION,
+                new UserHandle(userId));
+    }
+
+    /**
+     * Returns true if there currently exist active high power location requests.
+     */
+    private boolean areActiveHighPowerLocationRequests() {
+        List<AppOpsManager.PackageOps> packages
+            = mAppOpsManager.getPackagesForOps(mHighPowerRequestAppOpArray);
+        // AppOpsManager can return null when there is no requested data.
+        if (packages != null) {
+            final int numPackages = packages.size();
+            for (int packageInd = 0; packageInd < numPackages; packageInd++) {
+                AppOpsManager.PackageOps packageOp = packages.get(packageInd);
+                List<AppOpsManager.OpEntry> opEntries = packageOp.getOps();
+                if (opEntries != null) {
+                    final int numOps = opEntries.size();
+                    for (int opInd = 0; opInd < numOps; opInd++) {
+                        AppOpsManager.OpEntry opEntry = opEntries.get(opInd);
+                        // AppOpsManager should only return OP_MONITOR_HIGH_POWER_LOCATION because
+                        // of the mHighPowerRequestAppOpArray filter, but checking defensively.
+                        if (opEntry.getOp() == AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION) {
+                            if (opEntry.isRunning()) {
+                                return true;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
+    // Updates the status view based on the current state of location requests.
+    private void refreshViews() {
+        if (mAreActiveLocationRequests) {
+            mStatusBarManager.setIcon(LOCATION_STATUS_ICON_PLACEHOLDER, LOCATION_STATUS_ICON_ID, 0,
+                    mContext.getString(R.string.accessibility_location_active));
+        } else {
+            mStatusBarManager.removeIcon(LOCATION_STATUS_ICON_PLACEHOLDER);
+        }
+    }
+
+    // Reads the active location requests and updates the status view if necessary.
+    private void updateActiveLocationRequests() {
+        boolean hadActiveLocationRequests = mAreActiveLocationRequests;
+        mAreActiveLocationRequests = areActiveHighPowerLocationRequests();
+        if (mAreActiveLocationRequests != hadActiveLocationRequests) {
+            refreshViews();
+        }
+    }
+
+    private void locationSettingsChanged() {
+        boolean isEnabled = isLocationEnabled();
+        for (LocationSettingsChangeCallback cb : mSettingsChangeCallbacks) {
+            cb.onLocationSettingsChanged(isEnabled);
+        }
     }
 
     @Override
     public void onReceive(Context context, Intent intent) {
         final String action = intent.getAction();
-        final boolean enabled = intent.getBooleanExtra(LocationManager.EXTRA_GPS_ENABLED, false);
-
-        boolean visible;
-        int iconId, textResId;
-
-        if (action.equals(LocationManager.GPS_FIX_CHANGE_ACTION) && enabled) {
-            // GPS is getting fixes
-            iconId = com.android.internal.R.drawable.stat_sys_gps_on;
-            textResId = R.string.gps_notification_found_text;
-            visible = true;
-        } else if (action.equals(LocationManager.GPS_ENABLED_CHANGE_ACTION) && !enabled) {
-            // GPS is off
-            visible = false;
-            iconId = textResId = 0;
-        } else {
-            // GPS is on, but not receiving fixes
-            iconId = R.drawable.stat_sys_gps_acquiring_anim;
-            textResId = R.string.gps_notification_searching_text;
-            visible = true;
-        }
-        
-        try {
-            if (visible) {
-                Intent gpsIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
-                gpsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-                PendingIntent pendingIntent = PendingIntent.getActivityAsUser(context, 0,
-                        gpsIntent, 0, null, UserHandle.CURRENT);
-                String text = mContext.getText(textResId).toString();
-
-                Notification n = new Notification.Builder(mContext)
-                    .setSmallIcon(iconId)
-                    .setContentTitle(text)
-                    .setOngoing(true)
-                    .setContentIntent(pendingIntent)
-                    .getNotification();
-
-                // Notification.Builder will helpfully fill these out for you no matter what you do
-                n.tickerView = null;
-                n.tickerText = null;
-                
-                n.priority = Notification.PRIORITY_HIGH;
-
-                int[] idOut = new int[1];
-                mNotificationService.enqueueNotificationWithTag(
-                        mContext.getPackageName(), mContext.getBasePackageName(),
-                        null, 
-                        GPS_NOTIFICATION_ID, 
-                        n,
-                        idOut,
-                        UserHandle.USER_ALL);
-
-                for (LocationGpsStateChangeCallback cb : mChangeCallbacks) {
-                    cb.onLocationGpsStateChanged(true, text);
-                }
-            } else {
-                mNotificationService.cancelNotificationWithTag(
-                        mContext.getPackageName(), null,
-                        GPS_NOTIFICATION_ID, UserHandle.USER_ALL);
-
-                for (LocationGpsStateChangeCallback cb : mChangeCallbacks) {
-                    cb.onLocationGpsStateChanged(false, null);
-                }
-            }
-        } catch (android.os.RemoteException ex) {
-            // well, it was worth a shot
+        if (LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)) {
+            updateActiveLocationRequests();
         }
     }
 }
-
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 73752e5..09f1695 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -27,27 +27,24 @@
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.net.wimax.WimaxManagerConstants;
-import android.os.Binder;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
 import android.os.Messenger;
-import android.os.RemoteException;
 import android.provider.Settings;
 import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.telephony.TelephonyManager;
-import android.util.Slog;
+import android.util.Log;
 import android.view.View;
-import android.widget.ImageView;
 import android.widget.TextView;
 
-import com.android.internal.app.IBatteryStats;
 import com.android.internal.telephony.IccCardConstants;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.telephony.cdma.EriInfo;
 import com.android.internal.util.AsyncChannel;
-import com.android.server.am.BatteryStatsService;
+import com.android.systemui.DemoMode;
 import com.android.systemui.R;
 
 import java.io.FileDescriptor;
@@ -56,12 +53,14 @@
 import java.util.List;
 import java.util.Locale;
 
-public class NetworkController extends BroadcastReceiver {
+public class NetworkController extends BroadcastReceiver implements DemoMode {
     // debug
     static final String TAG = "StatusBar.NetworkController";
     static final boolean DEBUG = false;
     static final boolean CHATTY = false; // additional diagnostics, but not logspew
 
+    private static final int FLIGHT_MODE_ICON = R.drawable.stat_sys_signal_flightmode;
+
     // telephony
     boolean mHspaDataDistinguishable;
     final TelephonyManager mPhone;
@@ -85,7 +84,6 @@
     int mQSDataTypeIconId;
     int mAirplaneIconId;
     boolean mDataActive;
-    int mMobileActivityIconId; // overlay arrows for data direction
     int mLastSignalLevel;
     boolean mShowPhoneRSSIForData = false;
     boolean mShowAtLeastThreeGees = false;
@@ -105,7 +103,6 @@
     String mWifiSsid;
     int mWifiIconId = 0;
     int mQSWifiIconId = 0;
-    int mWifiActivityIconId = 0; // overlay arrows for wifi direction
     int mWifiActivity = WifiManager.DATA_ACTIVITY_NONE;
 
     // bluetooth
@@ -139,13 +136,6 @@
 
     // our ui
     Context mContext;
-    ArrayList<ImageView> mPhoneSignalIconViews = new ArrayList<ImageView>();
-    ArrayList<ImageView> mDataDirectionIconViews = new ArrayList<ImageView>();
-    ArrayList<ImageView> mDataDirectionOverlayIconViews = new ArrayList<ImageView>();
-    ArrayList<ImageView> mWifiIconViews = new ArrayList<ImageView>();
-    ArrayList<ImageView> mWimaxIconViews = new ArrayList<ImageView>();
-    ArrayList<ImageView> mCombinedSignalIconViews = new ArrayList<ImageView>();
-    ArrayList<ImageView> mDataTypeIconViews = new ArrayList<ImageView>();
     ArrayList<TextView> mCombinedLabelViews = new ArrayList<TextView>();
     ArrayList<TextView> mMobileLabelViews = new ArrayList<TextView>();
     ArrayList<TextView> mWifiLabelViews = new ArrayList<TextView>();
@@ -155,7 +145,6 @@
             new ArrayList<NetworkSignalChangedCallback>();
     int mLastPhoneSignalIconId = -1;
     int mLastDataDirectionIconId = -1;
-    int mLastDataDirectionOverlayIconId = -1;
     int mLastWifiIconId = -1;
     int mLastWimaxIconId = -1;
     int mLastCombinedSignalIconId = -1;
@@ -166,22 +155,21 @@
 
     boolean mDataAndWifiStacked = false;
 
-    // yuck -- stop doing this here and put it in the framework
-    IBatteryStats mBatteryStats;
-
     public interface SignalCluster {
-        void setWifiIndicators(boolean visible, int strengthIcon, int activityIcon,
+        void setWifiIndicators(boolean visible, int strengthIcon,
                 String contentDescription);
-        void setMobileDataIndicators(boolean visible, int strengthIcon, int activityIcon,
+        void setMobileDataIndicators(boolean visible, int strengthIcon,
                 int typeIcon, String contentDescription, String typeContentDescription);
         void setIsAirplaneMode(boolean is, int airplaneIcon);
     }
 
     public interface NetworkSignalChangedCallback {
         void onWifiSignalChanged(boolean enabled, int wifiSignalIconId,
-                String wifitSignalContentDescriptionId, String description);
+                boolean activityIn, boolean activityOut,
+                String wifiSignalContentDescriptionId, String description);
         void onMobileDataSignalChanged(boolean enabled, int mobileSignalIconId,
                 String mobileSignalContentDescriptionId, int dataTypeIconId,
+                boolean activityIn, boolean activityOut,
                 String dataTypeContentDescriptionId, String description);
         void onAirplaneModeChanged(boolean enabled);
     }
@@ -253,9 +241,6 @@
         // AIRPLANE_MODE_CHANGED is sent at boot; we've probably already missed it
         updateAirplaneMode();
 
-        // yuck
-        mBatteryStats = BatteryStatsService.getService();
-
         mLastLocale = mContext.getResources().getConfiguration().locale;
     }
 
@@ -271,33 +256,6 @@
         return (mServiceState != null && mServiceState.isEmergencyOnly());
     }
 
-    public void addPhoneSignalIconView(ImageView v) {
-        mPhoneSignalIconViews.add(v);
-    }
-
-    public void addDataDirectionIconView(ImageView v) {
-        mDataDirectionIconViews.add(v);
-    }
-
-    public void addDataDirectionOverlayIconView(ImageView v) {
-        mDataDirectionOverlayIconViews.add(v);
-    }
-
-    public void addWifiIconView(ImageView v) {
-        mWifiIconViews.add(v);
-    }
-    public void addWimaxIconView(ImageView v) {
-        mWimaxIconViews.add(v);
-    }
-
-    public void addCombinedSignalIconView(ImageView v) {
-        mCombinedSignalIconViews.add(v);
-    }
-
-    public void addDataTypeIconView(ImageView v) {
-        mDataTypeIconViews.add(v);
-    }
-
     public void addCombinedLabelView(TextView v) {
         mCombinedLabelViews.add(v);
     }
@@ -325,11 +283,11 @@
     }
 
     public void refreshSignalCluster(SignalCluster cluster) {
+        if (mDemoMode) return;
         cluster.setWifiIndicators(
                 // only show wifi in the cluster if connected or if wifi-only
                 mWifiEnabled && (mWifiConnected || !mHasMobileDataFeature),
                 mWifiIconId,
-                mWifiActivityIconId,
                 mContentDescriptionWifi);
 
         if (mIsWimaxEnabled && mWimaxConnected) {
@@ -337,7 +295,6 @@
             cluster.setMobileDataIndicators(
                     true,
                     mAlwaysShowCdmaRssi ? mPhoneSignalIconId : mWimaxIconId,
-                    mMobileActivityIconId,
                     mDataTypeIconId,
                     mContentDescriptionWimax,
                     mContentDescriptionDataType);
@@ -346,7 +303,6 @@
             cluster.setMobileDataIndicators(
                     mHasMobileDataFeature,
                     mShowPhoneRSSIForData ? mPhoneSignalIconId : mDataSignalIconId,
-                    mMobileActivityIconId,
                     mDataTypeIconId,
                     mContentDescriptionPhoneSignal,
                     mContentDescriptionDataType);
@@ -359,22 +315,33 @@
         boolean wifiEnabled = mWifiEnabled && (mWifiConnected || !mHasMobileDataFeature);
         String wifiDesc = wifiEnabled ?
                 mWifiSsid : null;
-        cb.onWifiSignalChanged(wifiEnabled, mQSWifiIconId, mContentDescriptionWifi, wifiDesc);
+        boolean wifiIn = wifiEnabled && mWifiSsid != null
+                && (mWifiActivity == WifiManager.DATA_ACTIVITY_INOUT
+                || mWifiActivity == WifiManager.DATA_ACTIVITY_IN);
+        boolean wifiOut = wifiEnabled && mWifiSsid != null
+                && (mWifiActivity == WifiManager.DATA_ACTIVITY_INOUT
+                || mWifiActivity == WifiManager.DATA_ACTIVITY_OUT);
+        cb.onWifiSignalChanged(wifiEnabled, mQSWifiIconId, wifiIn, wifiOut,
+                mContentDescriptionWifi, wifiDesc);
 
+        boolean mobileIn = mDataConnected && (mDataActivity == TelephonyManager.DATA_ACTIVITY_INOUT
+                || mDataActivity == TelephonyManager.DATA_ACTIVITY_IN);
+        boolean mobileOut = mDataConnected && (mDataActivity == TelephonyManager.DATA_ACTIVITY_INOUT
+                || mDataActivity == TelephonyManager.DATA_ACTIVITY_OUT);
         if (isEmergencyOnly()) {
             cb.onMobileDataSignalChanged(false, mQSPhoneSignalIconId,
-                    mContentDescriptionPhoneSignal, mQSDataTypeIconId, mContentDescriptionDataType,
-                    null);
+                    mContentDescriptionPhoneSignal, mQSDataTypeIconId, mobileIn, mobileOut,
+                    mContentDescriptionDataType, null);
         } else {
             if (mIsWimaxEnabled && mWimaxConnected) {
                 // Wimax is special
                 cb.onMobileDataSignalChanged(true, mQSPhoneSignalIconId,
-                        mContentDescriptionPhoneSignal, mQSDataTypeIconId,
+                        mContentDescriptionPhoneSignal, mQSDataTypeIconId, mobileIn, mobileOut,
                         mContentDescriptionDataType, mNetworkName);
             } else {
                 // Normal mobile data
                 cb.onMobileDataSignalChanged(mHasMobileDataFeature, mQSPhoneSignalIconId,
-                        mContentDescriptionPhoneSignal, mQSDataTypeIconId,
+                        mContentDescriptionPhoneSignal, mQSDataTypeIconId, mobileIn, mobileOut,
                         mContentDescriptionDataType, mNetworkName);
             }
         }
@@ -429,7 +396,7 @@
         @Override
         public void onSignalStrengthsChanged(SignalStrength signalStrength) {
             if (DEBUG) {
-                Slog.d(TAG, "onSignalStrengthsChanged signalStrength=" + signalStrength +
+                Log.d(TAG, "onSignalStrengthsChanged signalStrength=" + signalStrength +
                     ((signalStrength == null) ? "" : (" level=" + signalStrength.getLevel())));
             }
             mSignalStrength = signalStrength;
@@ -440,7 +407,8 @@
         @Override
         public void onServiceStateChanged(ServiceState state) {
             if (DEBUG) {
-                Slog.d(TAG, "onServiceStateChanged state=" + state.getState());
+                Log.d(TAG, "onServiceStateChanged voiceState=" + state.getVoiceRegState()
+                        + " dataState=" + state.getDataRegState());
             }
             mServiceState = state;
             updateTelephonySignalStrength();
@@ -452,7 +420,7 @@
         @Override
         public void onCallStateChanged(int state, String incomingNumber) {
             if (DEBUG) {
-                Slog.d(TAG, "onCallStateChanged state=" + state);
+                Log.d(TAG, "onCallStateChanged state=" + state);
             }
             // In cdma, if a voice call is made, RSSI should switch to 1x.
             if (isCdma()) {
@@ -464,7 +432,7 @@
         @Override
         public void onDataConnectionStateChanged(int state, int networkType) {
             if (DEBUG) {
-                Slog.d(TAG, "onDataConnectionStateChanged: state=" + state
+                Log.d(TAG, "onDataConnectionStateChanged: state=" + state
                         + " type=" + networkType);
             }
             mDataState = state;
@@ -477,7 +445,7 @@
         @Override
         public void onDataActivity(int direction) {
             if (DEBUG) {
-                Slog.d(TAG, "onDataActivity: direction=" + direction);
+                Log.d(TAG, "onDataActivity: direction=" + direction);
             }
             mDataActivity = direction;
             updateDataIcon();
@@ -516,10 +484,16 @@
 
     private boolean hasService() {
         if (mServiceState != null) {
-            switch (mServiceState.getState()) {
-                case ServiceState.STATE_OUT_OF_SERVICE:
+            // Consider the device to be in service if either voice or data service is available.
+            // Some SIM cards are marketed as data-only and do not support voice service, and on
+            // these SIM cards, we want to show signal bars for data service as well as the "no
+            // service" or "emergency calls only" text that indicates that voice is not available.
+            switch(mServiceState.getVoiceRegState()) {
                 case ServiceState.STATE_POWER_OFF:
                     return false;
+                case ServiceState.STATE_OUT_OF_SERVICE:
+                case ServiceState.STATE_EMERGENCY_ONLY:
+                    return mServiceState.getDataRegState() == ServiceState.STATE_IN_SERVICE;
                 default:
                     return true;
             }
@@ -539,13 +513,13 @@
 
     private final void updateTelephonySignalStrength() {
         if (!hasService()) {
-            if (CHATTY) Slog.d(TAG, "updateTelephonySignalStrength: !hasService()");
+            if (CHATTY) Log.d(TAG, "updateTelephonySignalStrength: !hasService()");
             mPhoneSignalIconId = R.drawable.stat_sys_signal_null;
             mQSPhoneSignalIconId = R.drawable.ic_qs_signal_no_signal;
             mDataSignalIconId = R.drawable.stat_sys_signal_null;
         } else {
             if (mSignalStrength == null) {
-                if (CHATTY) Slog.d(TAG, "updateTelephonySignalStrength: mSignalStrength == null");
+                if (CHATTY) Log.d(TAG, "updateTelephonySignalStrength: mSignalStrength == null");
                 mPhoneSignalIconId = R.drawable.stat_sys_signal_null;
                 mQSPhoneSignalIconId = R.drawable.ic_qs_signal_no_signal;
                 mDataSignalIconId = R.drawable.stat_sys_signal_null;
@@ -556,7 +530,7 @@
                 int[] iconList;
                 if (isCdma() && mAlwaysShowCdmaRssi) {
                     mLastSignalLevel = iconLevel = mSignalStrength.getCdmaLevel();
-                    if(DEBUG) Slog.d(TAG, "mAlwaysShowCdmaRssi=" + mAlwaysShowCdmaRssi
+                    if(DEBUG) Log.d(TAG, "mAlwaysShowCdmaRssi=" + mAlwaysShowCdmaRssi
                             + " set to cdmaLevel=" + mSignalStrength.getCdmaLevel()
                             + " instead of level=" + mSignalStrength.getLevel());
                 } else {
@@ -591,8 +565,8 @@
         if (mIsWimaxEnabled && mWimaxConnected) {
             // wimax is a special 4g network not handled by telephony
             mDataIconList = TelephonyIcons.DATA_4G[mInetCondition];
-            mDataTypeIconId = R.drawable.stat_sys_data_connected_4g;
-            mQSDataTypeIconId = R.drawable.ic_qs_signal_4g;
+            mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_4g;
+            mQSDataTypeIconId = TelephonyIcons.QS_DATA_4G[mInetCondition];
             mContentDescriptionDataType = mContext.getString(
                     R.string.accessibility_data_connection_4g);
         } else {
@@ -611,8 +585,8 @@
                 case TelephonyManager.NETWORK_TYPE_EDGE:
                     if (!mShowAtLeastThreeGees) {
                         mDataIconList = TelephonyIcons.DATA_E[mInetCondition];
-                        mDataTypeIconId = R.drawable.stat_sys_data_connected_e;
-                        mQSDataTypeIconId = R.drawable.ic_qs_signal_e;
+                        mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_e;
+                        mQSDataTypeIconId = TelephonyIcons.QS_DATA_E[mInetCondition];
                         mContentDescriptionDataType = mContext.getString(
                                 R.string.accessibility_data_connection_edge);
                         break;
@@ -621,8 +595,8 @@
                     }
                 case TelephonyManager.NETWORK_TYPE_UMTS:
                     mDataIconList = TelephonyIcons.DATA_3G[mInetCondition];
-                    mDataTypeIconId = R.drawable.stat_sys_data_connected_3g;
-                    mQSDataTypeIconId = R.drawable.ic_qs_signal_3g;
+                    mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_3g;
+                    mQSDataTypeIconId = TelephonyIcons.QS_DATA_3G[mInetCondition];
                     mContentDescriptionDataType = mContext.getString(
                             R.string.accessibility_data_connection_3g);
                     break;
@@ -632,14 +606,14 @@
                 case TelephonyManager.NETWORK_TYPE_HSPAP:
                     if (mHspaDataDistinguishable) {
                         mDataIconList = TelephonyIcons.DATA_H[mInetCondition];
-                        mDataTypeIconId = R.drawable.stat_sys_data_connected_h;
-                        mQSDataTypeIconId = R.drawable.ic_qs_signal_h;
+                        mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_h;
+                        mQSDataTypeIconId = TelephonyIcons.QS_DATA_H[mInetCondition];
                         mContentDescriptionDataType = mContext.getString(
                                 R.string.accessibility_data_connection_3_5g);
                     } else {
                         mDataIconList = TelephonyIcons.DATA_3G[mInetCondition];
-                        mDataTypeIconId = R.drawable.stat_sys_data_connected_3g;
-                        mQSDataTypeIconId = R.drawable.ic_qs_signal_3g;
+                        mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_3g;
+                        mQSDataTypeIconId = TelephonyIcons.QS_DATA_3G[mInetCondition];
                         mContentDescriptionDataType = mContext.getString(
                                 R.string.accessibility_data_connection_3g);
                     }
@@ -648,8 +622,8 @@
                     if (!mShowAtLeastThreeGees) {
                         // display 1xRTT for IS95A/B
                         mDataIconList = TelephonyIcons.DATA_1X[mInetCondition];
-                        mDataTypeIconId = R.drawable.stat_sys_data_connected_1x;
-                        mQSDataTypeIconId = R.drawable.ic_qs_signal_1x;
+                        mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_1x;
+                        mQSDataTypeIconId = TelephonyIcons.QS_DATA_1X[mInetCondition];
                         mContentDescriptionDataType = mContext.getString(
                                 R.string.accessibility_data_connection_cdma);
                         break;
@@ -659,8 +633,8 @@
                 case TelephonyManager.NETWORK_TYPE_1xRTT:
                     if (!mShowAtLeastThreeGees) {
                         mDataIconList = TelephonyIcons.DATA_1X[mInetCondition];
-                        mDataTypeIconId = R.drawable.stat_sys_data_connected_1x;
-                        mQSDataTypeIconId = R.drawable.ic_qs_signal_1x;
+                        mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_1x;
+                        mQSDataTypeIconId = TelephonyIcons.QS_DATA_1X[mInetCondition];
                         mContentDescriptionDataType = mContext.getString(
                                 R.string.accessibility_data_connection_cdma);
                         break;
@@ -672,8 +646,8 @@
                 case TelephonyManager.NETWORK_TYPE_EVDO_B:
                 case TelephonyManager.NETWORK_TYPE_EHRPD:
                     mDataIconList = TelephonyIcons.DATA_3G[mInetCondition];
-                    mDataTypeIconId = R.drawable.stat_sys_data_connected_3g;
-                    mQSDataTypeIconId = R.drawable.ic_qs_signal_3g;
+                    mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_3g;
+                    mQSDataTypeIconId = TelephonyIcons.QS_DATA_3G[mInetCondition];
                     mContentDescriptionDataType = mContext.getString(
                             R.string.accessibility_data_connection_3g);
                     break;
@@ -681,14 +655,14 @@
                     boolean show4GforLTE = mContext.getResources().getBoolean(R.bool.config_show4GForLTE);
                     if (show4GforLTE) {
                         mDataIconList = TelephonyIcons.DATA_4G[mInetCondition];
-                        mDataTypeIconId = R.drawable.stat_sys_data_connected_4g;
-                        mQSDataTypeIconId = R.drawable.ic_qs_signal_4g;
+                        mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_4g;
+                        mQSDataTypeIconId = TelephonyIcons.QS_DATA_4G[mInetCondition];
                         mContentDescriptionDataType = mContext.getString(
                                 R.string.accessibility_data_connection_4g);
                     } else {
                         mDataIconList = TelephonyIcons.DATA_LTE[mInetCondition];
-                        mDataTypeIconId = R.drawable.stat_sys_data_connected_lte;
-                        mQSDataTypeIconId = R.drawable.ic_qs_signal_lte;
+                        mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_lte;
+                        mQSDataTypeIconId = TelephonyIcons.QS_DATA_LTE[mInetCondition];
                         mContentDescriptionDataType = mContext.getString(
                                 R.string.accessibility_data_connection_lte);
                     }
@@ -696,14 +670,14 @@
                 default:
                     if (!mShowAtLeastThreeGees) {
                         mDataIconList = TelephonyIcons.DATA_G[mInetCondition];
-                        mDataTypeIconId = R.drawable.stat_sys_data_connected_g;
-                        mQSDataTypeIconId = R.drawable.ic_qs_signal_g;
+                        mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_g;
+                        mQSDataTypeIconId = TelephonyIcons.QS_DATA_G[mInetCondition];
                         mContentDescriptionDataType = mContext.getString(
                                 R.string.accessibility_data_connection_gprs);
                     } else {
                         mDataIconList = TelephonyIcons.DATA_3G[mInetCondition];
-                        mDataTypeIconId = R.drawable.stat_sys_data_connected_3g;
-                        mQSDataTypeIconId = R.drawable.ic_qs_signal_3g;
+                        mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_3g;
+                        mQSDataTypeIconId = TelephonyIcons.QS_DATA_3G[mInetCondition];
                         mContentDescriptionDataType = mContext.getString(
                                 R.string.accessibility_data_connection_3g);
                     }
@@ -713,12 +687,12 @@
 
         if (isCdma()) {
             if (isCdmaEri()) {
-                mDataTypeIconId = R.drawable.stat_sys_data_connected_roam;
-                mQSDataTypeIconId = R.drawable.ic_qs_signal_r;
+                mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_roam;
+                mQSDataTypeIconId = TelephonyIcons.QS_DATA_R[mInetCondition];
             }
         } else if (mPhone.isNetworkRoaming()) {
-                mDataTypeIconId = R.drawable.stat_sys_data_connected_roam;
-                mQSDataTypeIconId = R.drawable.ic_qs_signal_r;
+                mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_roam;
+                mQSDataTypeIconId = TelephonyIcons.QS_DATA_R[mInetCondition];
         }
     }
 
@@ -792,22 +766,13 @@
             }
         }
 
-        // yuck - this should NOT be done by the status bar
-        long ident = Binder.clearCallingIdentity();
-        try {
-            mBatteryStats.notePhoneDataConnectionState(mPhone.getNetworkType(), visible);
-        } catch (RemoteException e) {
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
-
         mDataDirectionIconId = iconId;
         mDataConnected = visible;
     }
 
     void updateNetworkName(boolean showSpn, String spn, boolean showPlmn, String plmn) {
         if (false) {
-            Slog.d("CarrierLabel", "updateNetworkName showSpn=" + showSpn + " spn=" + spn
+            Log.d("CarrierLabel", "updateNetworkName showSpn=" + showSpn + " spn=" + spn
                     + " showPlmn=" + showPlmn + " plmn=" + plmn);
         }
         StringBuilder str = new StringBuilder();
@@ -841,7 +806,7 @@
                         mWifiChannel.sendMessage(Message.obtain(this,
                                 AsyncChannel.CMD_CHANNEL_FULL_CONNECTION));
                     } else {
-                        Slog.e(TAG, "Failed to connect to wifi");
+                        Log.e(TAG, "Failed to connect to wifi");
                     }
                     break;
                 case WifiManager.DATA_ACTIVITY_NOTIFICATION:
@@ -973,7 +938,7 @@
 
     private void updateConnectivity(Intent intent) {
         if (CHATTY) {
-            Slog.d(TAG, "updateConnectivity: intent=" + intent);
+            Log.d(TAG, "updateConnectivity: intent=" + intent);
         }
 
         final ConnectivityManager connManager = (ConnectivityManager) mContext
@@ -993,8 +958,8 @@
         int connectionStatus = intent.getIntExtra(ConnectivityManager.EXTRA_INET_CONDITION, 0);
 
         if (CHATTY) {
-            Slog.d(TAG, "updateConnectivity: networkInfo=" + info);
-            Slog.d(TAG, "updateConnectivity: connectionStatus=" + connectionStatus);
+            Log.d(TAG, "updateConnectivity: networkInfo=" + info);
+            Log.d(TAG, "updateConnectivity: connectionStatus=" + connectionStatus);
         }
 
         mInetCondition = (connectionStatus > INET_CONDITION_THRESHOLD ? 1 : 0);
@@ -1020,7 +985,6 @@
         Context context = mContext;
 
         int combinedSignalIconId = 0;
-        int combinedActivityIconId = 0;
         String combinedLabel = "";
         String wifiLabel = "";
         String mobileLabel = "";
@@ -1058,56 +1022,23 @@
             // Now for things that should only be shown when actually using mobile data.
             if (mDataConnected) {
                 combinedSignalIconId = mDataSignalIconId;
-                switch (mDataActivity) {
-                    case TelephonyManager.DATA_ACTIVITY_IN:
-                        mMobileActivityIconId = R.drawable.stat_sys_signal_in;
-                        break;
-                    case TelephonyManager.DATA_ACTIVITY_OUT:
-                        mMobileActivityIconId = R.drawable.stat_sys_signal_out;
-                        break;
-                    case TelephonyManager.DATA_ACTIVITY_INOUT:
-                        mMobileActivityIconId = R.drawable.stat_sys_signal_inout;
-                        break;
-                    default:
-                        mMobileActivityIconId = 0;
-                        break;
-                }
 
                 combinedLabel = mobileLabel;
-                combinedActivityIconId = mMobileActivityIconId;
                 combinedSignalIconId = mDataSignalIconId; // set by updateDataIcon()
                 mContentDescriptionCombinedSignal = mContentDescriptionDataType;
-            } else {
-                mMobileActivityIconId = 0;
             }
         }
 
         if (mWifiConnected) {
             if (mWifiSsid == null) {
                 wifiLabel = context.getString(R.string.status_bar_settings_signal_meter_wifi_nossid);
-                mWifiActivityIconId = 0; // no wifis, no bits
             } else {
                 wifiLabel = mWifiSsid;
                 if (DEBUG) {
                     wifiLabel += "xxxxXXXXxxxxXXXX";
                 }
-                switch (mWifiActivity) {
-                    case WifiManager.DATA_ACTIVITY_IN:
-                        mWifiActivityIconId = R.drawable.stat_sys_wifi_in;
-                        break;
-                    case WifiManager.DATA_ACTIVITY_OUT:
-                        mWifiActivityIconId = R.drawable.stat_sys_wifi_out;
-                        break;
-                    case WifiManager.DATA_ACTIVITY_INOUT:
-                        mWifiActivityIconId = R.drawable.stat_sys_wifi_inout;
-                        break;
-                    case WifiManager.DATA_ACTIVITY_NONE:
-                        mWifiActivityIconId = 0;
-                        break;
-                }
             }
 
-            combinedActivityIconId = mWifiActivityIconId;
             combinedLabel = wifiLabel;
             combinedSignalIconId = mWifiIconId; // set by updateWifiIcons()
             mContentDescriptionCombinedSignal = mContentDescriptionWifi;
@@ -1138,7 +1069,7 @@
             // look again; your radios are now airplanes
             mContentDescriptionPhoneSignal = mContext.getString(
                     R.string.accessibility_airplane_mode);
-            mAirplaneIconId = R.drawable.stat_sys_signal_flightmode;
+            mAirplaneIconId = FLIGHT_MODE_ICON;
             mPhoneSignalIconId = mDataSignalIconId = mDataTypeIconId = mQSDataTypeIconId = 0;
             mQSPhoneSignalIconId = 0;
 
@@ -1172,17 +1103,17 @@
             mQSDataTypeIconId = 0;
             if (isCdma()) {
                 if (isCdmaEri()) {
-                    mDataTypeIconId = R.drawable.stat_sys_data_connected_roam;
-                    mQSDataTypeIconId = R.drawable.ic_qs_signal_r;
+                    mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_roam;
+                    mQSDataTypeIconId = TelephonyIcons.QS_DATA_R[mInetCondition];
                 }
             } else if (mPhone.isNetworkRoaming()) {
-                mDataTypeIconId = R.drawable.stat_sys_data_connected_roam;
-                mQSDataTypeIconId = R.drawable.ic_qs_signal_r;
+                mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_roam;
+                mQSDataTypeIconId = TelephonyIcons.QS_DATA_R[mInetCondition];
             }
         }
 
         if (DEBUG) {
-            Slog.d(TAG, "refreshViews connected={"
+            Log.d(TAG, "refreshViews connected={"
                     + (mWifiConnected?" wifi":"")
                     + (mDataConnected?" data":"")
                     + " } level="
@@ -1190,7 +1121,6 @@
                     + " combinedSignalIconId=0x"
                     + Integer.toHexString(combinedSignalIconId)
                     + "/" + getResourceName(combinedSignalIconId)
-                    + " combinedActivityIconId=0x" + Integer.toHexString(combinedActivityIconId)
                     + " mobileLabel=" + mobileLabel
                     + " wifiLabel=" + wifiLabel
                     + " emergencyOnly=" + emergencyOnly
@@ -1208,8 +1138,12 @@
                     + " mBluetoothTetherIconId=0x" + Integer.toHexString(mBluetoothTetherIconId));
         }
 
+        // update QS
+        for (NetworkSignalChangedCallback cb : mSignalsChangedCallbacks) {
+            notifySignalsChangedCallbacks(cb);
+        }
+
         if (mLastPhoneSignalIconId          != mPhoneSignalIconId
-         || mLastDataDirectionOverlayIconId != combinedActivityIconId
          || mLastWifiIconId                 != mWifiIconId
          || mLastWimaxIconId                != mWimaxIconId
          || mLastDataTypeIconId             != mDataTypeIconId
@@ -1220,9 +1154,6 @@
             for (SignalCluster cluster : mSignalClusters) {
                 refreshSignalCluster(cluster);
             }
-            for (NetworkSignalChangedCallback cb : mSignalsChangedCallbacks) {
-                notifySignalsChangedCallbacks(cb);
-            }
         }
 
         if (mLastAirplaneMode != mAirplaneMode) {
@@ -1236,105 +1167,30 @@
         // the phone icon on phones
         if (mLastPhoneSignalIconId != mPhoneSignalIconId) {
             mLastPhoneSignalIconId = mPhoneSignalIconId;
-            N = mPhoneSignalIconViews.size();
-            for (int i=0; i<N; i++) {
-                final ImageView v = mPhoneSignalIconViews.get(i);
-                if (mPhoneSignalIconId == 0) {
-                    v.setVisibility(View.GONE);
-                } else {
-                    v.setVisibility(View.VISIBLE);
-                    v.setImageResource(mPhoneSignalIconId);
-                    v.setContentDescription(mContentDescriptionPhoneSignal);
-                }
-            }
         }
 
         // the data icon on phones
         if (mLastDataDirectionIconId != mDataDirectionIconId) {
             mLastDataDirectionIconId = mDataDirectionIconId;
-            N = mDataDirectionIconViews.size();
-            for (int i=0; i<N; i++) {
-                final ImageView v = mDataDirectionIconViews.get(i);
-                v.setImageResource(mDataDirectionIconId);
-                v.setContentDescription(mContentDescriptionDataType);
-            }
         }
 
         // the wifi icon on phones
         if (mLastWifiIconId != mWifiIconId) {
             mLastWifiIconId = mWifiIconId;
-            N = mWifiIconViews.size();
-            for (int i=0; i<N; i++) {
-                final ImageView v = mWifiIconViews.get(i);
-                if (mWifiIconId == 0) {
-                    v.setVisibility(View.GONE);
-                } else {
-                    v.setVisibility(View.VISIBLE);
-                    v.setImageResource(mWifiIconId);
-                    v.setContentDescription(mContentDescriptionWifi);
-                }
-            }
         }
 
         // the wimax icon on phones
         if (mLastWimaxIconId != mWimaxIconId) {
             mLastWimaxIconId = mWimaxIconId;
-            N = mWimaxIconViews.size();
-            for (int i=0; i<N; i++) {
-                final ImageView v = mWimaxIconViews.get(i);
-                if (mWimaxIconId == 0) {
-                    v.setVisibility(View.GONE);
-                } else {
-                    v.setVisibility(View.VISIBLE);
-                    v.setImageResource(mWimaxIconId);
-                    v.setContentDescription(mContentDescriptionWimax);
-                }
-           }
         }
         // the combined data signal icon
         if (mLastCombinedSignalIconId != combinedSignalIconId) {
             mLastCombinedSignalIconId = combinedSignalIconId;
-            N = mCombinedSignalIconViews.size();
-            for (int i=0; i<N; i++) {
-                final ImageView v = mCombinedSignalIconViews.get(i);
-                v.setImageResource(combinedSignalIconId);
-                v.setContentDescription(mContentDescriptionCombinedSignal);
-            }
         }
 
         // the data network type overlay
         if (mLastDataTypeIconId != mDataTypeIconId) {
             mLastDataTypeIconId = mDataTypeIconId;
-            N = mDataTypeIconViews.size();
-            for (int i=0; i<N; i++) {
-                final ImageView v = mDataTypeIconViews.get(i);
-                if (mDataTypeIconId == 0) {
-                    v.setVisibility(View.GONE);
-                } else {
-                    v.setVisibility(View.VISIBLE);
-                    v.setImageResource(mDataTypeIconId);
-                    v.setContentDescription(mContentDescriptionDataType);
-                }
-            }
-        }
-
-        // the data direction overlay
-        if (mLastDataDirectionOverlayIconId != combinedActivityIconId) {
-            if (DEBUG) {
-                Slog.d(TAG, "changing data overlay icon id to " + combinedActivityIconId);
-            }
-            mLastDataDirectionOverlayIconId = combinedActivityIconId;
-            N = mDataDirectionOverlayIconViews.size();
-            for (int i=0; i<N; i++) {
-                final ImageView v = mDataDirectionOverlayIconViews.get(i);
-                if (combinedActivityIconId == 0) {
-                    v.setVisibility(View.GONE);
-                } else {
-                    v.setVisibility(View.VISIBLE);
-                    v.setImageResource(combinedActivityIconId);
-                    v.setContentDescription(mContentDescriptionDataType);
-                }
-            }
         }
 
         // the combinedLabel in the notification panel
@@ -1493,10 +1349,6 @@
         pw.print(Integer.toHexString(mLastDataDirectionIconId));
         pw.print("/");
         pw.println(getResourceName(mLastDataDirectionIconId));
-        pw.print("  mLastDataDirectionOverlayIconId=0x");
-        pw.print(Integer.toHexString(mLastDataDirectionOverlayIconId));
-        pw.print("/");
-        pw.println(getResourceName(mLastDataDirectionOverlayIconId));
         pw.print("  mLastWifiIconId=0x");
         pw.print(Integer.toHexString(mLastWifiIconId));
         pw.print("/");
@@ -1527,4 +1379,88 @@
         }
     }
 
+    private boolean mDemoMode;
+    private int mDemoInetCondition;
+    private int mDemoWifiLevel;
+    private int mDemoDataTypeIconId;
+    private int mDemoMobileLevel;
+
+    @Override
+    public void dispatchDemoCommand(String command, Bundle args) {
+        if (!mDemoMode && command.equals(COMMAND_ENTER)) {
+            mDemoMode = true;
+            mDemoWifiLevel = mWifiLevel;
+            mDemoInetCondition = mInetCondition;
+            mDemoDataTypeIconId = mDataTypeIconId;
+            mDemoMobileLevel = mLastSignalLevel;
+        } else if (mDemoMode && command.equals(COMMAND_EXIT)) {
+            mDemoMode = false;
+            for (SignalCluster cluster : mSignalClusters) {
+                refreshSignalCluster(cluster);
+            }
+        } else if (mDemoMode && command.equals(COMMAND_NETWORK)) {
+            String airplane = args.getString("airplane");
+            if (airplane != null) {
+                boolean show = airplane.equals("show");
+                for (SignalCluster cluster : mSignalClusters) {
+                    cluster.setIsAirplaneMode(show, FLIGHT_MODE_ICON);
+                }
+            }
+            String fully = args.getString("fully");
+            if (fully != null) {
+                mDemoInetCondition = Boolean.parseBoolean(fully) ? 1 : 0;
+            }
+            String wifi = args.getString("wifi");
+            if (wifi != null) {
+                boolean show = wifi.equals("show");
+                String level = args.getString("level");
+                if (level != null) {
+                    mDemoWifiLevel = level.equals("null") ? -1
+                            : Math.min(Integer.parseInt(level), WifiIcons.WIFI_LEVEL_COUNT - 1);
+                }
+                int iconId = mDemoWifiLevel < 0 ? R.drawable.stat_sys_wifi_signal_null
+                        : WifiIcons.WIFI_SIGNAL_STRENGTH[mDemoInetCondition][mDemoWifiLevel];
+                for (SignalCluster cluster : mSignalClusters) {
+                    cluster.setWifiIndicators(
+                            show,
+                            iconId,
+                            "Demo");
+                }
+            }
+            String mobile = args.getString("mobile");
+            if (mobile != null) {
+                boolean show = mobile.equals("show");
+                String datatype = args.getString("datatype");
+                if (datatype != null) {
+                    mDemoDataTypeIconId =
+                            datatype.equals("1x") ? R.drawable.stat_sys_data_fully_connected_1x :
+                            datatype.equals("3g") ? R.drawable.stat_sys_data_fully_connected_3g :
+                            datatype.equals("4g") ? R.drawable.stat_sys_data_fully_connected_4g :
+                            datatype.equals("e") ? R.drawable.stat_sys_data_fully_connected_e :
+                            datatype.equals("g") ? R.drawable.stat_sys_data_fully_connected_g :
+                            datatype.equals("h") ? R.drawable.stat_sys_data_fully_connected_h :
+                            datatype.equals("lte") ? R.drawable.stat_sys_data_fully_connected_lte :
+                            datatype.equals("roam")
+                                    ? R.drawable.stat_sys_data_fully_connected_roam :
+                            0;
+                }
+                int[][] icons = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH;
+                String level = args.getString("level");
+                if (level != null) {
+                    mDemoMobileLevel = level.equals("null") ? -1
+                            : Math.min(Integer.parseInt(level), icons[0].length - 1);
+                }
+                int iconId = mDemoMobileLevel < 0 ? R.drawable.stat_sys_signal_null :
+                        icons[mDemoInetCondition][mDemoMobileLevel];
+                for (SignalCluster cluster : mSignalClusters) {
+                    cluster.setMobileDataIndicators(
+                            show,
+                            iconId,
+                            mDemoDataTypeIconId,
+                            "Demo",
+                            "Demo");
+                }
+            }
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
index 89eed1b..259422d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
@@ -16,34 +16,29 @@
 
 package com.android.systemui.statusbar.policy;
 
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
 import android.animation.LayoutTransition;
-import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
 import android.content.Context;
 import android.content.res.Configuration;
-import android.content.res.TypedArray;
 import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.util.Log;
-import android.util.Slog;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
-import android.view.inputmethod.InputMethodManager;
 import android.widget.LinearLayout;
 
 import com.android.systemui.ExpandHelper;
 import com.android.systemui.R;
 import com.android.systemui.SwipeHelper;
+import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.NotificationData;
 
 import java.util.HashMap;
 
-public class NotificationRowLayout 
-        extends LinearLayout 
+public class NotificationRowLayout
+        extends LinearLayout
         implements SwipeHelper.Callback, ExpandHelper.Callback
 {
     private static final String TAG = "NotificationRowLayout";
@@ -61,7 +56,7 @@
     HashMap<View, ValueAnimator> mDisappearingViews = new HashMap<View, ValueAnimator>();
 
     private SwipeHelper mSwipeHelper;
-    
+
     private OnSizeChangedListener mOnSizeChangedListener;
 
     // Flag set during notification removal animation to avoid causing too much work until
@@ -80,18 +75,18 @@
         mRealLayoutTransition = new LayoutTransition();
         mRealLayoutTransition.setAnimateParentHierarchy(true);
         setLayoutTransitionsEnabled(true);
-        
+
         setOrientation(LinearLayout.VERTICAL);
 
         if (DEBUG) {
             setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {
                 @Override
                 public void onChildViewAdded(View parent, View child) {
-                    Slog.d(TAG, "view added: " + child + "; new count: " + getChildCount());
+                    Log.d(TAG, "view added: " + child + "; new count: " + getChildCount());
                 }
                 @Override
                 public void onChildViewRemoved(View parent, View child) {
-                    Slog.d(TAG, "view removed: " + child + "; new count: " + (getChildCount() - 1));
+                    Log.d(TAG, "view removed: " + child + "; new count: " + (getChildCount() - 1));
                 }
             });
 
@@ -155,19 +150,24 @@
     }
 
     public boolean canChildBeExpanded(View v) {
-        return NotificationData.getIsExpandable(v);
+        return v instanceof ExpandableNotificationRow
+                && ((ExpandableNotificationRow) v).isExpandable();
     }
 
-    public boolean setUserExpandedChild(View v, boolean userExpanded) {
-        return NotificationData.setUserExpanded(v, userExpanded);
+    public void setUserExpandedChild(View v, boolean userExpanded) {
+        if (v instanceof ExpandableNotificationRow) {
+            ((ExpandableNotificationRow) v).setUserExpanded(userExpanded);
+        }
     }
 
-    public boolean setUserLockedChild(View v, boolean userLocked) {
-        return NotificationData.setUserLocked(v, userLocked);
+    public void setUserLockedChild(View v, boolean userLocked) {
+        if (v instanceof ExpandableNotificationRow) {
+            ((ExpandableNotificationRow) v).setUserLocked(userLocked);
+        }
     }
 
     public void onChildDismissed(View v) {
-        if (DEBUG) Slog.v(TAG, "onChildDismissed: " + v + " mRemoveViews=" + mRemoveViews);
+        if (DEBUG) Log.v(TAG, "onChildDismissed: " + v + " mRemoveViews=" + mRemoveViews);
         final View veto = v.findViewById(R.id.veto);
         if (veto != null && veto.getVisibility() != View.GONE && mRemoveViews) {
             veto.performClick();
@@ -231,7 +231,7 @@
      * get removed properly.
      */
     public void setViewRemoval(boolean removeViews) {
-        if (DEBUG) Slog.v(TAG, "setViewRemoval: " + removeViews);
+        if (DEBUG) Log.v(TAG, "setViewRemoval: " + removeViews);
         mRemoveViews = removeViews;
     }
 
@@ -266,7 +266,7 @@
         super.onDraw(c);
         if (DEBUG) logLayoutTransition();
         if (DEBUG) {
-            //Slog.d(TAG, "onDraw: canvas height: " + c.getHeight() + "px; measured height: "
+            //Log.d(TAG, "onDraw: canvas height: " + c.getHeight() + "px; measured height: "
             //        + getMeasuredHeight() + "px");
             c.save();
             c.clipRect(6, 6, c.getWidth() - 6, getMeasuredHeight() - 6,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Prefs.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Prefs.java
index 5d2198e..f339401 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Prefs.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Prefs.java
@@ -22,13 +22,6 @@
 public class Prefs {
     private static final String SHARED_PREFS_NAME = "status_bar";
 
-    // a boolean
-    public static final String DO_NOT_DISTURB_PREF = "do_not_disturb";
-    public static final boolean DO_NOT_DISTURB_DEFAULT = false;
-
-    public static final String SHOWN_COMPAT_MODE_HELP = "shown_compat_mode_help";
-    public static final String SHOWN_QUICK_SETTINGS_HELP = "shown_quick_settings_help";
-
     public static SharedPreferences read(Context context) {
         return context.getSharedPreferences(Prefs.SHARED_PREFS_NAME, Context.MODE_PRIVATE);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RotationLockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RotationLockController.java
new file mode 100644
index 0000000..6f61ec8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RotationLockController.java
@@ -0,0 +1,89 @@
+/*
+ * 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.systemui.statusbar.policy;
+
+import android.content.Context;
+import android.os.UserHandle;
+
+import com.android.internal.view.RotationPolicy;
+
+import java.util.concurrent.CopyOnWriteArrayList;
+
+public final class RotationLockController {
+    private final Context mContext;
+    private final CopyOnWriteArrayList<RotationLockControllerCallback> mCallbacks =
+            new CopyOnWriteArrayList<RotationLockControllerCallback>();
+
+    private final RotationPolicy.RotationPolicyListener mRotationPolicyListener =
+            new RotationPolicy.RotationPolicyListener() {
+        @Override
+        public void onChange() {
+            notifyChanged();
+        }
+    };
+
+    public interface RotationLockControllerCallback {
+        public void onRotationLockStateChanged(boolean rotationLocked, boolean affordanceVisible);
+    }
+
+    public RotationLockController(Context context) {
+        mContext = context;
+        notifyChanged();
+        if (RotationPolicy.isRotationLockToggleSupported(mContext)) {
+            RotationPolicy.registerRotationPolicyListener(mContext,
+                    mRotationPolicyListener, UserHandle.USER_ALL);
+        }
+    }
+
+    public void addRotationLockControllerCallback(RotationLockControllerCallback callback) {
+        mCallbacks.add(callback);
+    }
+
+    public boolean isRotationLocked() {
+        if (RotationPolicy.isRotationLockToggleSupported(mContext)) {
+            return RotationPolicy.isRotationLocked(mContext);
+        }
+        return false;
+    }
+
+    public void setRotationLocked(boolean locked) {
+        if (RotationPolicy.isRotationLockToggleSupported(mContext)) {
+            RotationPolicy.setRotationLock(mContext, locked);
+        }
+    }
+
+    public boolean isRotationLockAffordanceVisible() {
+        if (RotationPolicy.isRotationLockToggleSupported(mContext)) {
+            return RotationPolicy.isRotationLockToggleVisible(mContext);
+        }
+        return false;
+    }
+
+    public void release() {
+        if (RotationPolicy.isRotationLockToggleSupported(mContext)) {
+            RotationPolicy.unregisterRotationPolicyListener(mContext,
+                    mRotationPolicyListener);
+        }
+    }
+
+    private void notifyChanged() {
+        for (RotationLockControllerCallback callback : mCallbacks) {
+            callback.onRotationLockStateChanged(RotationPolicy.isRotationLocked(mContext),
+                    RotationPolicy.isRotationLockToggleVisible(mContext));
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
index 4b2c65e..67ba879 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java
@@ -23,11 +23,11 @@
 
     //GSM/UMTS
     static final int[][] TELEPHONY_SIGNAL_STRENGTH = {
-        { R.drawable.stat_sys_signal_0,
-          R.drawable.stat_sys_signal_1,
-          R.drawable.stat_sys_signal_2,
-          R.drawable.stat_sys_signal_3,
-          R.drawable.stat_sys_signal_4 },
+        { R.drawable.stat_sys_signal_0_fully,
+          R.drawable.stat_sys_signal_1_fully,
+          R.drawable.stat_sys_signal_2_fully,
+          R.drawable.stat_sys_signal_3_fully,
+          R.drawable.stat_sys_signal_4_fully },
         { R.drawable.stat_sys_signal_0_fully,
           R.drawable.stat_sys_signal_1_fully,
           R.drawable.stat_sys_signal_2_fully,
@@ -49,11 +49,11 @@
     };
 
     static final int[][] TELEPHONY_SIGNAL_STRENGTH_ROAMING = {
-        { R.drawable.stat_sys_signal_0,
-          R.drawable.stat_sys_signal_1,
-          R.drawable.stat_sys_signal_2,
-          R.drawable.stat_sys_signal_3,
-          R.drawable.stat_sys_signal_4 },
+        { R.drawable.stat_sys_signal_0_fully,
+          R.drawable.stat_sys_signal_1_fully,
+          R.drawable.stat_sys_signal_2_fully,
+          R.drawable.stat_sys_signal_3_fully,
+          R.drawable.stat_sys_signal_4_fully },
         { R.drawable.stat_sys_signal_0_fully,
           R.drawable.stat_sys_signal_1_fully,
           R.drawable.stat_sys_signal_2_fully,
@@ -61,92 +61,132 @@
           R.drawable.stat_sys_signal_4_fully }
     };
 
+    static final int[] QS_DATA_R = {
+        R.drawable.ic_qs_signal_r,
+        R.drawable.ic_qs_signal_full_r
+    };
+
     static final int[][] DATA_SIGNAL_STRENGTH = TELEPHONY_SIGNAL_STRENGTH;
 
     //***** Data connection icons
 
     //GSM/UMTS
     static final int[][] DATA_G = {
-            { R.drawable.stat_sys_data_connected_g,
-              R.drawable.stat_sys_data_connected_g,
-              R.drawable.stat_sys_data_connected_g,
-              R.drawable.stat_sys_data_connected_g },
+            { R.drawable.stat_sys_data_fully_connected_g,
+              R.drawable.stat_sys_data_fully_connected_g,
+              R.drawable.stat_sys_data_fully_connected_g,
+              R.drawable.stat_sys_data_fully_connected_g },
             { R.drawable.stat_sys_data_fully_connected_g,
               R.drawable.stat_sys_data_fully_connected_g,
               R.drawable.stat_sys_data_fully_connected_g,
               R.drawable.stat_sys_data_fully_connected_g }
         };
 
+    static final int[] QS_DATA_G = {
+        R.drawable.ic_qs_signal_g,
+        R.drawable.ic_qs_signal_full_g
+    };
+
     static final int[][] DATA_3G = {
-            { R.drawable.stat_sys_data_connected_3g,
-              R.drawable.stat_sys_data_connected_3g,
-              R.drawable.stat_sys_data_connected_3g,
-              R.drawable.stat_sys_data_connected_3g },
+            { R.drawable.stat_sys_data_fully_connected_3g,
+              R.drawable.stat_sys_data_fully_connected_3g,
+              R.drawable.stat_sys_data_fully_connected_3g,
+              R.drawable.stat_sys_data_fully_connected_3g },
             { R.drawable.stat_sys_data_fully_connected_3g,
               R.drawable.stat_sys_data_fully_connected_3g,
               R.drawable.stat_sys_data_fully_connected_3g,
               R.drawable.stat_sys_data_fully_connected_3g }
         };
 
+    static final int[] QS_DATA_3G = {
+        R.drawable.ic_qs_signal_3g,
+        R.drawable.ic_qs_signal_full_3g
+    };
+
     static final int[][] DATA_E = {
-            { R.drawable.stat_sys_data_connected_e,
-              R.drawable.stat_sys_data_connected_e,
-              R.drawable.stat_sys_data_connected_e,
-              R.drawable.stat_sys_data_connected_e },
+            { R.drawable.stat_sys_data_fully_connected_e,
+              R.drawable.stat_sys_data_fully_connected_e,
+              R.drawable.stat_sys_data_fully_connected_e,
+              R.drawable.stat_sys_data_fully_connected_e },
             { R.drawable.stat_sys_data_fully_connected_e,
               R.drawable.stat_sys_data_fully_connected_e,
               R.drawable.stat_sys_data_fully_connected_e,
               R.drawable.stat_sys_data_fully_connected_e }
         };
 
+    static final int[] QS_DATA_E = {
+        R.drawable.ic_qs_signal_e,
+        R.drawable.ic_qs_signal_full_e
+    };
+
     //3.5G
     static final int[][] DATA_H = {
-            { R.drawable.stat_sys_data_connected_h,
-              R.drawable.stat_sys_data_connected_h,
-              R.drawable.stat_sys_data_connected_h,
-              R.drawable.stat_sys_data_connected_h },
+            { R.drawable.stat_sys_data_fully_connected_h,
+              R.drawable.stat_sys_data_fully_connected_h,
+              R.drawable.stat_sys_data_fully_connected_h,
+              R.drawable.stat_sys_data_fully_connected_h },
             { R.drawable.stat_sys_data_fully_connected_h,
               R.drawable.stat_sys_data_fully_connected_h,
               R.drawable.stat_sys_data_fully_connected_h,
               R.drawable.stat_sys_data_fully_connected_h }
     };
 
+    static final int[] QS_DATA_H = {
+                R.drawable.ic_qs_signal_h,
+                R.drawable.ic_qs_signal_full_h
+    };
+
     //CDMA
     // Use 3G icons for EVDO data and 1x icons for 1XRTT data
     static final int[][] DATA_1X = {
-            { R.drawable.stat_sys_data_connected_1x,
-              R.drawable.stat_sys_data_connected_1x,
-              R.drawable.stat_sys_data_connected_1x,
-              R.drawable.stat_sys_data_connected_1x },
+            { R.drawable.stat_sys_data_fully_connected_1x,
+              R.drawable.stat_sys_data_fully_connected_1x,
+              R.drawable.stat_sys_data_fully_connected_1x,
+              R.drawable.stat_sys_data_fully_connected_1x },
             { R.drawable.stat_sys_data_fully_connected_1x,
               R.drawable.stat_sys_data_fully_connected_1x,
               R.drawable.stat_sys_data_fully_connected_1x,
               R.drawable.stat_sys_data_fully_connected_1x }
             };
 
+    static final int[] QS_DATA_1X = {
+        R.drawable.ic_qs_signal_1x,
+        R.drawable.ic_qs_signal_full_1x
+    };
+
     // LTE and eHRPD
     static final int[][] DATA_4G = {
-            { R.drawable.stat_sys_data_connected_4g,
-              R.drawable.stat_sys_data_connected_4g,
-              R.drawable.stat_sys_data_connected_4g,
-              R.drawable.stat_sys_data_connected_4g },
+            { R.drawable.stat_sys_data_fully_connected_4g,
+              R.drawable.stat_sys_data_fully_connected_4g,
+              R.drawable.stat_sys_data_fully_connected_4g,
+              R.drawable.stat_sys_data_fully_connected_4g },
             { R.drawable.stat_sys_data_fully_connected_4g,
               R.drawable.stat_sys_data_fully_connected_4g,
               R.drawable.stat_sys_data_fully_connected_4g,
               R.drawable.stat_sys_data_fully_connected_4g }
         };
 
+    static final int[] QS_DATA_4G = {
+        R.drawable.ic_qs_signal_4g,
+        R.drawable.ic_qs_signal_full_4g
+    };
+
     // LTE branded "LTE"
     static final int[][] DATA_LTE = {
-            { R.drawable.stat_sys_data_connected_lte,
-                    R.drawable.stat_sys_data_connected_lte,
-                    R.drawable.stat_sys_data_connected_lte,
-                    R.drawable.stat_sys_data_connected_lte },
+            { R.drawable.stat_sys_data_fully_connected_lte,
+                    R.drawable.stat_sys_data_fully_connected_lte,
+                    R.drawable.stat_sys_data_fully_connected_lte,
+                    R.drawable.stat_sys_data_fully_connected_lte },
             { R.drawable.stat_sys_data_fully_connected_lte,
                     R.drawable.stat_sys_data_fully_connected_lte,
                     R.drawable.stat_sys_data_fully_connected_lte,
                     R.drawable.stat_sys_data_fully_connected_lte }
     };
 
+    static final int[] QS_DATA_LTE = {
+        R.drawable.ic_qs_signal_lte,
+        R.drawable.ic_qs_signal_full_lte
+    };
+
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/VolumeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/VolumeController.java
deleted file mode 100644
index 70f9ac8..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/VolumeController.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 com.android.systemui.statusbar.policy;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.Vibrator;
-import android.media.AudioManager;
-import android.provider.Settings;
-import android.util.Slog;
-import android.view.IWindowManager;
-import android.widget.CompoundButton;
-
-import com.android.systemui.settings.ToggleSlider;
-
-public class VolumeController implements ToggleSlider.Listener {
-    private static final String TAG = "StatusBar.VolumeController";
-    private static final int STREAM = AudioManager.STREAM_NOTIFICATION;
-
-    private Context mContext;
-    private ToggleSlider mControl;
-    private AudioManager mAudioManager;
-
-    private boolean mMute;
-    private int mVolume;
-    // Is there a vibrator
-    private final boolean mHasVibrator;
-
-    public VolumeController(Context context, ToggleSlider control) {
-        mContext = context;
-        mControl = control;
-
-        Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
-        mHasVibrator = vibrator == null ? false : vibrator.hasVibrator();
-
-        mAudioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
-
-        mMute = mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL;
-        mVolume = mAudioManager.getStreamVolume(STREAM);
-
-        control.setOnChangedListener(this);
-    }
-
-    @Override
-    public void onInit(ToggleSlider control) {
-        control.setMax(mAudioManager.getStreamMaxVolume(STREAM));
-        control.setValue(mVolume);
-        control.setChecked(mMute);
-    }
-
-    public void onChanged(ToggleSlider view, boolean tracking, boolean mute, int level) {
-        if (!tracking) {
-            if (mute) {
-                mAudioManager.setRingerMode(
-                        mHasVibrator ? AudioManager.RINGER_MODE_VIBRATE
-                                     : AudioManager.RINGER_MODE_SILENT);
-            } else {
-                mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
-                mAudioManager.setStreamVolume(STREAM, level, AudioManager.FLAG_PLAY_SOUND);
-            }
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiIcons.java
index 8cc0338..57ddf7a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiIcons.java
@@ -21,10 +21,10 @@
 class WifiIcons {
     static final int[][] WIFI_SIGNAL_STRENGTH = {
             { R.drawable.stat_sys_wifi_signal_0,
-              R.drawable.stat_sys_wifi_signal_1,
-              R.drawable.stat_sys_wifi_signal_2,
-              R.drawable.stat_sys_wifi_signal_3,
-              R.drawable.stat_sys_wifi_signal_4 },
+              R.drawable.stat_sys_wifi_signal_1_fully,
+              R.drawable.stat_sys_wifi_signal_2_fully,
+              R.drawable.stat_sys_wifi_signal_3_fully,
+              R.drawable.stat_sys_wifi_signal_4_fully },
             { R.drawable.stat_sys_wifi_signal_0,
               R.drawable.stat_sys_wifi_signal_1_fully,
               R.drawable.stat_sys_wifi_signal_2_fully,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WimaxIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WimaxIcons.java
index d3d4338..4877828 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WimaxIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WimaxIcons.java
@@ -1,28 +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 com.android.systemui.statusbar.policy;

-

-import com.android.systemui.statusbar.policy.TelephonyIcons;

-import com.android.systemui.R;

-

-class WimaxIcons {

-    static final int[][] WIMAX_SIGNAL_STRENGTH = TelephonyIcons.DATA_SIGNAL_STRENGTH;

-

-    static final int WIMAX_DISCONNECTED = WIMAX_SIGNAL_STRENGTH[0][0];

-

-    static final int WIMAX_IDLE = WIMAX_DISCONNECTED; // XXX: unclear if we need a different icon

-}

+/*
+ * 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.systemui.statusbar.policy;
+
+import com.android.systemui.statusbar.policy.TelephonyIcons;
+
+class WimaxIcons {
+    static final int[][] WIMAX_SIGNAL_STRENGTH = TelephonyIcons.DATA_SIGNAL_STRENGTH;
+
+    static final int WIMAX_DISCONNECTED = WIMAX_SIGNAL_STRENGTH[0][0];
+
+    static final int WIMAX_IDLE = WIMAX_DISCONNECTED; // XXX: unclear if we need a different icon
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/CompatModePanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/CompatModePanel.java
deleted file mode 100644
index 8c4ae19..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/CompatModePanel.java
+++ /dev/null
@@ -1,134 +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.systemui.statusbar.tablet;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.os.RemoteException;
-import android.util.AttributeSet;
-import android.util.Slog;
-import android.view.MotionEvent;
-import android.view.View;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.RadioButton;
-import android.widget.RadioGroup;
-
-import com.android.systemui.R;
-
-public class CompatModePanel extends FrameLayout implements StatusBarPanel,
-        View.OnClickListener {
-    private static final boolean DEBUG = TabletStatusBar.DEBUG;
-    private static final String TAG = "CompatModePanel";
-
-    private ActivityManager mAM;
-
-    private boolean mAttached = false;
-    private Context mContext;
-    private RadioButton mOnButton, mOffButton;
-
-    private View mTrigger;
-//    private InputMethodButton mInputMethodSwitchButton;
-
-    public CompatModePanel(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        mContext = context;
-        mAM = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
-    }
-
-    @Override
-    public void onFinishInflate() {
-        mOnButton  = (RadioButton) findViewById(R.id.compat_mode_on_radio);
-        mOffButton = (RadioButton) findViewById(R.id.compat_mode_off_radio);
-        mOnButton.setOnClickListener(this);
-        mOffButton.setOnClickListener(this);
-
-        refresh();
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        if (mAttached) {
-            mAttached = false;
-        }
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        if (!mAttached) {
-            mAttached = true;
-        }
-    }
-
-    @Override
-    public void onClick(View v) {
-        if (v == mOnButton) {
-            mAM.setFrontActivityScreenCompatMode(ActivityManager.COMPAT_MODE_ENABLED);
-        } else if (v == mOffButton) {
-            mAM.setFrontActivityScreenCompatMode(ActivityManager.COMPAT_MODE_DISABLED);
-        }
-    }
-
-    @Override
-    public boolean isInContentArea(int x, int y) {
-        return false;
-    }
-
-    @Override
-    public boolean dispatchHoverEvent(MotionEvent event) {
-        // Ignore hover events outside of this panel bounds since such events
-        // generate spurious accessibility events with the panel content when
-        // tapping outside of it, thus confusing the user.
-        final int x = (int) event.getX();
-        final int y = (int) event.getY();
-        if (x >= 0 && x < getWidth() && y >= 0 && y < getHeight()) {
-            return super.dispatchHoverEvent(event);
-        }
-        return true;
-    }
-
-    public void setTrigger(View v) {
-        mTrigger = v;
-    }
-
-    public void openPanel() {
-        setVisibility(View.VISIBLE);
-        if (mTrigger != null) mTrigger.setSelected(true);
-        refresh();
-    }
-
-    public void closePanel() {
-        setVisibility(View.GONE);
-        if (mTrigger != null) mTrigger.setSelected(false);
-    }
-
-    private void refresh() {
-        int mode = mAM.getFrontActivityScreenCompatMode();
-        if (mode == ActivityManager.COMPAT_MODE_ALWAYS
-                || mode == ActivityManager.COMPAT_MODE_NEVER) {
-            // No longer have something to switch.
-            closePanel();
-            return;
-        }
-        final boolean on = (mode == ActivityManager.COMPAT_MODE_ENABLED);
-        mOnButton.setChecked(on);
-        mOffButton.setChecked(!on);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java
deleted file mode 100644
index fa8aa6d..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.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 com.android.systemui.statusbar.tablet;
-
-import android.content.Context;
-import android.os.IBinder;
-import android.provider.Settings;
-import android.util.AttributeSet;
-import android.view.inputmethod.InputMethodInfo;
-import android.view.inputmethod.InputMethodManager;
-import android.view.inputmethod.InputMethodSubtype;
-import android.view.View;
-import android.widget.ImageView;
-
-import com.android.systemui.R;
-
-import java.util.List;
-
-public class InputMethodButton extends ImageView {
-
-    private static final String  TAG = "StatusBar/InputMethodButton";
-    private static final boolean DEBUG = false;
-
-    // These values are defined in Settings application.
-    private static final int ID_IME_BUTTON_VISIBILITY_AUTO = 0;
-    private static final int ID_IME_BUTTON_VISIBILITY_ALWAYS_SHOW = 1;
-    private static final int ID_IME_BUTTON_VISIBILITY_ALWAYS_HIDE = 2;
-
-    // other services we wish to talk to
-    private final InputMethodManager mImm;
-    private final int mId;
-    private ImageView mIcon;
-    private IBinder mToken;
-    private boolean mShowButton = false;
-    private boolean mScreenLocked = false;
-    private boolean mHardKeyboardAvailable;
-
-    // Please refer to InputMethodManagerService.TAG_TRY_SUPPRESSING_IME_SWITCHER
-    private static final String TAG_TRY_SUPPRESSING_IME_SWITCHER = "TrySuppressingImeSwitcher";
-
-    public InputMethodButton(Context context, AttributeSet attrs) {
-        super(context, attrs);
-
-        // Resource Id of the input method button. This id is defined in status_bar.xml
-        mId = getId();
-        // IME hookup
-        mImm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        mIcon = (ImageView) findViewById(mId);
-
-        refreshStatusIcon();
-    }
-
-    // Refer to InputMethodManagerService.needsToShowImeSwitchOngoingNotification()
-    private boolean needsToShowIMEButtonWhenVisibilityAuto() {
-        List<InputMethodInfo> imis = mImm.getEnabledInputMethodList();
-        final int N = imis.size();
-        if (N > 2) return true;
-        if (N < 1) return false;
-        int nonAuxCount = 0;
-        int auxCount = 0;
-        InputMethodSubtype nonAuxSubtype = null;
-        InputMethodSubtype auxSubtype = null;
-        for(int i = 0; i < N; ++i) {
-            final InputMethodInfo imi = imis.get(i);
-            final List<InputMethodSubtype> subtypes = mImm.getEnabledInputMethodSubtypeList(
-                    imi, true);
-            final int subtypeCount = subtypes.size();
-            if (subtypeCount == 0) {
-                ++nonAuxCount;
-            } else {
-                for (int j = 0; j < subtypeCount; ++j) {
-                    final InputMethodSubtype subtype = subtypes.get(j);
-                    if (!subtype.isAuxiliary()) {
-                        ++nonAuxCount;
-                        nonAuxSubtype = subtype;
-                    } else {
-                        ++auxCount;
-                        auxSubtype = subtype;
-                    }
-                }
-            }
-        }
-        if (nonAuxCount > 1 || auxCount > 1) {
-            return true;
-        } else if (nonAuxCount == 1 && auxCount == 1) {
-            if (nonAuxSubtype != null && auxSubtype != null
-                    && (nonAuxSubtype.getLocale().equals(auxSubtype.getLocale())
-                            || auxSubtype.overridesImplicitlyEnabledSubtype()
-                            || nonAuxSubtype.overridesImplicitlyEnabledSubtype())
-                    && nonAuxSubtype.containsExtraValueKey(TAG_TRY_SUPPRESSING_IME_SWITCHER)) {
-                return false;
-            }
-            return true;
-        }
-        return false;
-    }
-
-    private boolean needsToShowIMEButton() {
-        if (!mShowButton || mScreenLocked) return false;
-
-        if (mHardKeyboardAvailable) {
-            return true;
-        }
-
-        final int visibility = loadInputMethodSelectorVisibility();
-        switch (visibility) {
-            case ID_IME_BUTTON_VISIBILITY_AUTO:
-                return needsToShowIMEButtonWhenVisibilityAuto();
-            case ID_IME_BUTTON_VISIBILITY_ALWAYS_SHOW:
-                return true;
-            case ID_IME_BUTTON_VISIBILITY_ALWAYS_HIDE:
-                return false;
-        }
-        return false;
-    }
-
-    private void refreshStatusIcon() {
-        if (mIcon == null) {
-            return;
-        }
-        if (!needsToShowIMEButton()) {
-            setVisibility(View.GONE);
-            return;
-        } else {
-            setVisibility(View.VISIBLE);
-        }
-        mIcon.setImageResource(R.drawable.ic_sysbar_ime);
-    }
-
-    private int loadInputMethodSelectorVisibility() {
-        return Settings.Secure.getInt(getContext().getContentResolver(),
-                Settings.Secure.INPUT_METHOD_SELECTOR_VISIBILITY, ID_IME_BUTTON_VISIBILITY_AUTO);
-    }
-
-    public void setIconImage(int resId) {
-        if (mIcon != null) {
-            mIcon.setImageResource(resId);
-        }
-    }
-
-    public void setImeWindowStatus(IBinder token, boolean showButton) {
-        mToken = token;
-        mShowButton = showButton;
-        refreshStatusIcon();
-    }
-
-    public void setHardKeyboardStatus(boolean available) {
-        if (mHardKeyboardAvailable != available) {
-            mHardKeyboardAvailable = available;
-            refreshStatusIcon();
-        }
-    }
-
-    public void setScreenLocked(boolean locked) {
-        mScreenLocked = locked;
-        refreshStatusIcon();
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java
deleted file mode 100644
index 8924087..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java
+++ /dev/null
@@ -1,487 +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.systemui.statusbar.tablet;
-
-import com.android.systemui.R;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.graphics.drawable.Drawable;
-import android.os.IBinder;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.Pair;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.inputmethod.InputMethodInfo;
-import android.view.inputmethod.InputMethodManager;
-import android.view.inputmethod.InputMethodSubtype;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.RadioButton;
-import android.widget.Switch;
-import android.widget.TextView;
-
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-
-public class InputMethodsPanel extends LinearLayout implements StatusBarPanel,
-        View.OnClickListener {
-    private static final boolean DEBUG = TabletStatusBar.DEBUG;
-    private static final String TAG = "InputMethodsPanel";
-
-    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            onPackageChanged();
-        }
-    };
-
-    private final InputMethodManager mImm;
-    private final IntentFilter mIntentFilter = new IntentFilter();
-    private final HashMap<View, Pair<InputMethodInfo, InputMethodSubtype>> mRadioViewAndImiMap =
-            new HashMap<View, Pair<InputMethodInfo, InputMethodSubtype>>();
-    private final TreeMap<InputMethodInfo, List<InputMethodSubtype>>
-            mEnabledInputMethodAndSubtypesCache =
-                    new TreeMap<InputMethodInfo, List<InputMethodSubtype>>(
-                            new InputMethodComparator());
-
-    private boolean mAttached = false;
-    private boolean mPackageChanged = false;
-    private Context mContext;
-    private IBinder mToken;
-    private InputMethodButton mInputMethodSwitchButton;
-    private LinearLayout mInputMethodMenuList;
-    private boolean mHardKeyboardAvailable;
-    private boolean mHardKeyboardEnabled;
-    private OnHardKeyboardEnabledChangeListener mHardKeyboardEnabledChangeListener;
-    private LinearLayout mHardKeyboardSection;
-    private Switch mHardKeyboardSwitch;
-    private PackageManager mPackageManager;
-    private String mEnabledInputMethodAndSubtypesCacheStr;
-    private String mLastSystemLocaleString;
-    private View mConfigureImeShortcut;
-
-    private class InputMethodComparator implements Comparator<InputMethodInfo> {
-        @Override
-        public int compare(InputMethodInfo imi1, InputMethodInfo imi2) {
-            if (imi2 == null) return 0;
-            if (imi1 == null) return 1;
-            if (mPackageManager == null) {
-                return imi1.getId().compareTo(imi2.getId());
-            }
-            CharSequence imiId1 = imi1.loadLabel(mPackageManager) + "/" + imi1.getId();
-            CharSequence imiId2 = imi2.loadLabel(mPackageManager) + "/" + imi2.getId();
-            return imiId1.toString().compareTo(imiId2.toString());
-        }
-    }
-
-    public InputMethodsPanel(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public InputMethodsPanel(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        mContext = context;
-        mImm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
-        mIntentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
-        mIntentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
-        mIntentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
-        mIntentFilter.addDataScheme("package");
-    }
-
-    public void setHardKeyboardEnabledChangeListener(
-            OnHardKeyboardEnabledChangeListener listener) {
-        mHardKeyboardEnabledChangeListener = listener;
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        if (mAttached) {
-            getContext().unregisterReceiver(mBroadcastReceiver);
-            mAttached = false;
-        }
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        if (!mAttached) {
-            getContext().registerReceiver(mBroadcastReceiver, mIntentFilter);
-            mAttached = true;
-        }
-    }
-
-    @Override
-    public void onFinishInflate() {
-        mInputMethodMenuList = (LinearLayout) findViewById(R.id.input_method_menu_list);
-        mHardKeyboardSection = (LinearLayout) findViewById(R.id.hard_keyboard_section);
-        mHardKeyboardSwitch = (Switch) findViewById(R.id.hard_keyboard_switch);
-        mConfigureImeShortcut = findViewById(R.id.ime_settings_shortcut);
-        mConfigureImeShortcut.setOnClickListener(this);
-        // TODO: If configurations for IME are not changed, do not update
-        // by checking onConfigurationChanged.
-        updateUiElements();
-    }
-
-    @Override
-    public boolean isInContentArea(int x, int y) {
-        return false;
-    }
-
-    @Override
-    public void onClick(View view) {
-        if (view == mConfigureImeShortcut) {
-            showConfigureInputMethods();
-            closePanel(true);
-        }
-    }
-
-    @Override
-    public boolean dispatchHoverEvent(MotionEvent event) {
-        // Ignore hover events outside of this panel bounds since such events
-        // generate spurious accessibility events with the panel content when
-        // tapping outside of it, thus confusing the user.
-        final int x = (int) event.getX();
-        final int y = (int) event.getY();
-        if (x >= 0 && x < getWidth() && y >= 0 && y < getHeight()) {
-            return super.dispatchHoverEvent(event);
-        }
-        return true;
-    }
-
-    private void updateHardKeyboardEnabled() {
-        if (mHardKeyboardAvailable) {
-            final boolean checked = mHardKeyboardSwitch.isChecked();
-            if (mHardKeyboardEnabled != checked) {
-                mHardKeyboardEnabled = checked;
-                if (mHardKeyboardEnabledChangeListener != null)
-                    mHardKeyboardEnabledChangeListener.onHardKeyboardEnabledChange(checked);
-            }
-        }
-    }
-
-    public void openPanel() {
-        setVisibility(View.VISIBLE);
-        updateUiElements();
-        if (mInputMethodSwitchButton != null) {
-            mInputMethodSwitchButton.setIconImage(R.drawable.ic_sysbar_ime_pressed);
-        }
-    }
-
-    public void closePanel(boolean closeKeyboard) {
-        setVisibility(View.GONE);
-        if (mInputMethodSwitchButton != null) {
-            mInputMethodSwitchButton.setIconImage(R.drawable.ic_sysbar_ime);
-        }
-        if (closeKeyboard) {
-            mImm.hideSoftInputFromWindow(getWindowToken(), 0);
-        }
-    }
-
-    private void startActivity(Intent intent) {
-        mContext.startActivity(intent);
-    }
-
-    private void showConfigureInputMethods() {
-        Intent intent = new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS);
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
-                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
-        startActivity(intent);
-    }
-
-    private View createInputMethodItem(
-            final InputMethodInfo imi, final InputMethodSubtype subtype) {
-        final CharSequence subtypeName;
-        if (subtype == null || subtype.overridesImplicitlyEnabledSubtype()) {
-            subtypeName = null;
-        } else {
-            subtypeName = getSubtypeName(imi, subtype);
-        }
-        final CharSequence imiName = getIMIName(imi);
-        final Drawable icon = getSubtypeIcon(imi, subtype);
-        final View view = View.inflate(mContext, R.layout.system_bar_input_methods_item, null);
-        final ImageView subtypeIcon = (ImageView)view.findViewById(R.id.item_icon);
-        final TextView itemTitle = (TextView)view.findViewById(R.id.item_title);
-        final TextView itemSubtitle = (TextView)view.findViewById(R.id.item_subtitle);
-        final ImageView settingsIcon = (ImageView)view.findViewById(R.id.item_settings_icon);
-        final View subtypeView = view.findViewById(R.id.item_subtype);
-        if (subtypeName == null) {
-            itemTitle.setText(imiName);
-            itemSubtitle.setVisibility(View.GONE);
-        } else {
-            itemTitle.setText(subtypeName);
-            itemSubtitle.setVisibility(View.VISIBLE);
-            itemSubtitle.setText(imiName);
-        }
-        subtypeIcon.setImageDrawable(icon);
-        subtypeIcon.setContentDescription(itemTitle.getText());
-        final String settingsActivity = imi.getSettingsActivity();
-        if (!TextUtils.isEmpty(settingsActivity)) {
-            settingsIcon.setOnClickListener(new View.OnClickListener() {
-                @Override
-                public void onClick(View arg0) {
-                    Intent intent = new Intent(Intent.ACTION_MAIN);
-                    intent.setClassName(imi.getPackageName(), settingsActivity);
-                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                            | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
-                            | Intent.FLAG_ACTIVITY_CLEAR_TOP);
-                    startActivity(intent);
-                    closePanel(true);
-                }
-            });
-        } else {
-            // Do not show the settings icon if the IME does not have a settings preference
-            view.findViewById(R.id.item_vertical_separator).setVisibility(View.GONE);
-            settingsIcon.setVisibility(View.GONE);
-        }
-        mRadioViewAndImiMap.put(
-                subtypeView, new Pair<InputMethodInfo, InputMethodSubtype> (imi, subtype));
-        subtypeView.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                Pair<InputMethodInfo, InputMethodSubtype> imiAndSubtype =
-                        updateRadioButtonsByView(v);
-                closePanel(false);
-                setInputMethodAndSubtype(imiAndSubtype.first, imiAndSubtype.second);
-            }
-        });
-        return view;
-    }
-
-    private void updateUiElements() {
-        updateHardKeyboardSection();
-
-        // TODO: Reuse subtype views.
-        mInputMethodMenuList.removeAllViews();
-        mRadioViewAndImiMap.clear();
-        mPackageManager = mContext.getPackageManager();
-
-        Map<InputMethodInfo, List<InputMethodSubtype>> enabledIMIs =
-                getEnabledInputMethodAndSubtypeList();
-        Set<InputMethodInfo> cachedImiSet = enabledIMIs.keySet();
-        for (InputMethodInfo imi: cachedImiSet) {
-            List<InputMethodSubtype> subtypes = enabledIMIs.get(imi);
-            if (subtypes == null || subtypes.size() == 0) {
-                mInputMethodMenuList.addView(
-                        createInputMethodItem(imi, null));
-                continue;
-            }
-            for (InputMethodSubtype subtype: subtypes) {
-                mInputMethodMenuList.addView(createInputMethodItem(imi, subtype));
-            }
-        }
-        updateRadioButtons();
-    }
-
-    public void setImeToken(IBinder token) {
-        mToken = token;
-    }
-
-    public void setImeSwitchButton(InputMethodButton imb) {
-        mInputMethodSwitchButton = imb;
-    }
-
-    private void setInputMethodAndSubtype(InputMethodInfo imi, InputMethodSubtype subtype) {
-        if (mToken != null) {
-            mImm.setInputMethodAndSubtype(mToken, imi.getId(), subtype);
-        } else {
-            Log.w(TAG, "IME Token is not set yet.");
-        }
-    }
-
-    public void setHardKeyboardStatus(boolean available, boolean enabled) {
-        if (mHardKeyboardAvailable != available || mHardKeyboardEnabled != enabled) {
-            mHardKeyboardAvailable = available;
-            mHardKeyboardEnabled = enabled;
-            updateHardKeyboardSection();
-        }
-    }
-
-    private void updateHardKeyboardSection() {
-        if (mHardKeyboardAvailable) {
-            mHardKeyboardSection.setVisibility(View.VISIBLE);
-            if (mHardKeyboardSwitch.isChecked() != mHardKeyboardEnabled) {
-                mHardKeyboardSwitch.setChecked(mHardKeyboardEnabled);
-                updateHardKeyboardEnabled();
-            }
-        } else {
-            mHardKeyboardSection.setVisibility(View.GONE);
-        }
-    }
-
-    // Turn on the selected radio button when the user chooses the item
-    private Pair<InputMethodInfo, InputMethodSubtype> updateRadioButtonsByView(View selectedView) {
-        Pair<InputMethodInfo, InputMethodSubtype> selectedImiAndSubtype = null;
-        if (mRadioViewAndImiMap.containsKey(selectedView)) {
-            for (View radioView: mRadioViewAndImiMap.keySet()) {
-                RadioButton subtypeRadioButton =
-                        (RadioButton) radioView.findViewById(R.id.item_radio);
-                if (subtypeRadioButton == null) {
-                    Log.w(TAG, "RadioButton was not found in the selected subtype view");
-                    return null;
-                }
-                if (radioView == selectedView) {
-                    Pair<InputMethodInfo, InputMethodSubtype> imiAndSubtype =
-                        mRadioViewAndImiMap.get(radioView);
-                    selectedImiAndSubtype = imiAndSubtype;
-                    subtypeRadioButton.setChecked(true);
-                } else {
-                    subtypeRadioButton.setChecked(false);
-                }
-            }
-        }
-        return selectedImiAndSubtype;
-    }
-
-    private void updateRadioButtons() {
-        updateRadioButtonsByImiAndSubtype(
-                getCurrentInputMethodInfo(), mImm.getCurrentInputMethodSubtype());
-    }
-
-    // Turn on the selected radio button at startup
-    private void updateRadioButtonsByImiAndSubtype(
-            InputMethodInfo imi, InputMethodSubtype subtype) {
-        if (imi == null) return;
-        if (DEBUG) {
-            Log.d(TAG, "Update radio buttons by " + imi.getId() + ", " + subtype);
-        }
-        for (View radioView: mRadioViewAndImiMap.keySet()) {
-            RadioButton subtypeRadioButton =
-                    (RadioButton) radioView.findViewById(R.id.item_radio);
-            if (subtypeRadioButton == null) {
-                Log.w(TAG, "RadioButton was not found in the selected subtype view");
-                return;
-            }
-            Pair<InputMethodInfo, InputMethodSubtype> imiAndSubtype =
-                    mRadioViewAndImiMap.get(radioView);
-            if (imiAndSubtype.first.getId().equals(imi.getId())
-                    && (imiAndSubtype.second == null || imiAndSubtype.second.equals(subtype))) {
-                subtypeRadioButton.setChecked(true);
-            } else {
-                subtypeRadioButton.setChecked(false);
-            }
-        }
-    }
-
-    private TreeMap<InputMethodInfo, List<InputMethodSubtype>>
-            getEnabledInputMethodAndSubtypeList() {
-        String newEnabledIMIs = Settings.Secure.getString(
-                mContext.getContentResolver(), Settings.Secure.ENABLED_INPUT_METHODS);
-        String currentSystemLocaleString =
-                mContext.getResources().getConfiguration().locale.toString();
-        if (!TextUtils.equals(mEnabledInputMethodAndSubtypesCacheStr, newEnabledIMIs)
-                || !TextUtils.equals(mLastSystemLocaleString, currentSystemLocaleString)
-                || mPackageChanged) {
-            mEnabledInputMethodAndSubtypesCache.clear();
-            final List<InputMethodInfo> imis = mImm.getEnabledInputMethodList();
-            for (InputMethodInfo imi: imis) {
-                mEnabledInputMethodAndSubtypesCache.put(imi,
-                        mImm.getEnabledInputMethodSubtypeList(imi, true));
-            }
-            mEnabledInputMethodAndSubtypesCacheStr = newEnabledIMIs;
-            mPackageChanged = false;
-            mLastSystemLocaleString = currentSystemLocaleString;
-        }
-        return mEnabledInputMethodAndSubtypesCache;
-    }
-
-    private InputMethodInfo getCurrentInputMethodInfo() {
-        String curInputMethodId = Settings.Secure.getString(getContext()
-                .getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
-        Set<InputMethodInfo> cachedImiSet = mEnabledInputMethodAndSubtypesCache.keySet();
-        // 1. Search IMI in cache
-        for (InputMethodInfo imi: cachedImiSet) {
-            if (imi.getId().equals(curInputMethodId)) {
-                return imi;
-            }
-        }
-        // 2. Get current enabled IMEs and search IMI
-        cachedImiSet = getEnabledInputMethodAndSubtypeList().keySet();
-        for (InputMethodInfo imi: cachedImiSet) {
-            if (imi.getId().equals(curInputMethodId)) {
-                return imi;
-            }
-        }
-        return null;
-    }
-
-    private CharSequence getIMIName(InputMethodInfo imi) {
-        if (imi == null) return null;
-        return imi.loadLabel(mPackageManager);
-    }
-
-    private CharSequence getSubtypeName(InputMethodInfo imi, InputMethodSubtype subtype) {
-        if (imi == null || subtype == null) return null;
-        if (DEBUG) {
-            Log.d(TAG, "Get text from: " + imi.getPackageName() + subtype.getNameResId()
-                    + imi.getServiceInfo().applicationInfo);
-        }
-        return subtype.getDisplayName(
-                mContext, imi.getPackageName(), imi.getServiceInfo().applicationInfo);
-    }
-
-    private Drawable getSubtypeIcon(InputMethodInfo imi, InputMethodSubtype subtype) {
-        if (imi != null) {
-            if (DEBUG) {
-                Log.d(TAG, "Update icons of IME: " + imi.getPackageName());
-                if (subtype != null) {
-                    Log.d(TAG, "subtype =" + subtype.getLocale() + "," + subtype.getMode());
-                }
-            }
-            if (subtype != null) {
-                return mPackageManager.getDrawable(imi.getPackageName(), subtype.getIconResId(),
-                        imi.getServiceInfo().applicationInfo);
-            } else if (imi.getSubtypeCount() > 0) {
-                return mPackageManager.getDrawable(imi.getPackageName(),
-                        imi.getSubtypeAt(0).getIconResId(),
-                        imi.getServiceInfo().applicationInfo);
-            } else {
-                try {
-                    return mPackageManager.getApplicationInfo(
-                            imi.getPackageName(), 0).loadIcon(mPackageManager);
-                } catch (PackageManager.NameNotFoundException e) {
-                    Log.w(TAG, "IME can't be found: " + imi.getPackageName());
-                }
-            }
-        }
-        return null;
-    }
-
-    private void onPackageChanged() {
-        if (DEBUG) {
-            Log.d(TAG, "onPackageChanged.");
-        }
-        mPackageChanged = true;
-    }
-
-    public interface OnHardKeyboardEnabledChangeListener {
-        public void onHardKeyboardEnabledChange(boolean enabled);
-    }
-
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationArea.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationArea.java
deleted file mode 100644
index 42bdf3d..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationArea.java
+++ /dev/null
@@ -1,45 +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.systemui.statusbar.tablet;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.accessibility.AccessibilityEvent;
-import android.widget.LinearLayout;
-
-public class NotificationArea extends LinearLayout {
-
-    public NotificationArea(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    @Override
-    public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) {
-        if (super.onRequestSendAccessibilityEvent(child, event)) {
-            // The event is coming from a descendant like battery but append
-            // the content of the entire notification area so accessibility
-            // services can choose how to present the content to the user.
-            AccessibilityEvent record = AccessibilityEvent.obtain();
-            onInitializeAccessibilityEvent(record);
-            dispatchPopulateAccessibilityEvent(record);
-            event.appendRecord(record);
-            return true;
-        }
-        return false;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationIconArea.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationIconArea.java
deleted file mode 100644
index 3d6c1a2..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationIconArea.java
+++ /dev/null
@@ -1,56 +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.systemui.statusbar.tablet;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.os.Handler;
-import android.util.AttributeSet;
-import android.util.Slog;
-import android.view.View;
-import android.widget.LinearLayout;
-import android.widget.RelativeLayout;
-import android.widget.ImageView;
-import android.view.MotionEvent;
-
-import com.android.systemui.R;
-
-
-public class NotificationIconArea extends RelativeLayout {
-    private static final String TAG = "NotificationIconArea";
-
-    IconLayout mIconLayout;
-
-    public NotificationIconArea(Context context, AttributeSet attrs) {
-        super(context, attrs);
-
-        mIconLayout = (IconLayout)findViewById(R.id.icons);
-    }
-
-    static class IconLayout extends LinearLayout {
-        public IconLayout(Context context, AttributeSet attrs) {
-            super(context, attrs);
-        }
-
-        public boolean onInterceptTouchEvent(MotionEvent e) {
-            return true;
-        }
-    }
-}
-
-
-
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationLinearLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationLinearLayout.java
deleted file mode 100644
index 9ecb2e4..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationLinearLayout.java
+++ /dev/null
@@ -1,92 +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.systemui.statusbar.tablet;
-
-import android.animation.Animator;
-import android.animation.ObjectAnimator;
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.util.Slog;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.animation.AccelerateInterpolator;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import com.android.systemui.R;
-
-public class NotificationLinearLayout extends LinearLayout {
-    private static final String TAG = "NotificationLinearLayout";
-
-    Drawable mItemGlow;
-    int mInsetLeft;
-    Rect mTmp = new Rect();
-
-    public NotificationLinearLayout(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public NotificationLinearLayout(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-
-        final Resources res = context.getResources();
-
-        mItemGlow = res.getDrawable(R.drawable.notify_item_glow_bottom);
-
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NotificationLinearLayout,
-                defStyle, 0);
-        mInsetLeft = a.getDimensionPixelSize(R.styleable.NotificationLinearLayout_insetLeft, 0);
-        a.recycle();
-    }
-
-    @Override
-    public void onFinishInflate() {
-        super.onFinishInflate();
-        setWillNotDraw(false);
-    }
-
-    @Override
-    public void onDraw(Canvas canvas) {
-        super.onDraw(canvas);
-
-        final Rect padding = mTmp;
-        final Drawable glow = mItemGlow;
-        glow.getPadding(padding);
-        final int glowHeight = glow.getIntrinsicHeight();
-        final int insetLeft = mInsetLeft;
-
-        final int N = getChildCount();
-        for (int i=0; i<N; i++) {
-            final View child = getChildAt(i);
-
-            final int childBottom = child.getBottom();
-
-            glow.setBounds(child.getLeft() - padding.left + insetLeft, childBottom,
-                    child.getRight() - padding.right, childBottom + glowHeight);
-            glow.draw(canvas);
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
deleted file mode 100644
index 87fc6fc..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
+++ /dev/null
@@ -1,464 +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.systemui.statusbar.tablet;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.content.Context;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.util.Slog;
-import android.view.Gravity;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
-import android.view.animation.AccelerateInterpolator;
-import android.view.animation.DecelerateInterpolator;
-import android.view.animation.Interpolator;
-import android.widget.ImageView;
-import android.widget.RelativeLayout;
-
-import com.android.systemui.ExpandHelper;
-import com.android.systemui.R;
-import com.android.systemui.statusbar.policy.NotificationRowLayout;
-
-public class NotificationPanel extends RelativeLayout implements StatusBarPanel,
-        View.OnClickListener {
-    private ExpandHelper mExpandHelper;
-    private NotificationRowLayout latestItems;
-
-    static final String TAG = "Tablet/NotificationPanel";
-    static final boolean DEBUG = false;
-
-    final static int PANEL_FADE_DURATION = 150;
-
-    boolean mShowing;
-    boolean mHasClearableNotifications = false;
-    int mNotificationCount = 0;
-    NotificationPanelTitle mTitleArea;
-    ImageView mSettingsButton;
-    ImageView mNotificationButton;
-    View mNotificationScroller;
-    ViewGroup mContentFrame;
-    Rect mContentArea = new Rect();
-    View mSettingsView;
-    ViewGroup mContentParent;
-    TabletStatusBar mBar;
-    View mClearButton;
-    static Interpolator sAccelerateInterpolator = new AccelerateInterpolator();
-    static Interpolator sDecelerateInterpolator = new DecelerateInterpolator();
-
-    // amount to slide mContentParent down by when mContentFrame is missing
-    float mContentFrameMissingTranslation;
-
-    Choreographer mChoreo = new Choreographer();
-
-    public NotificationPanel(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public NotificationPanel(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    public void setBar(TabletStatusBar b) {
-        mBar = b;
-    }
-
-    @Override
-    public void onFinishInflate() {
-        super.onFinishInflate();
-
-        setWillNotDraw(false);
-
-        mContentParent = (ViewGroup)findViewById(R.id.content_parent);
-        mContentParent.bringToFront();
-        mTitleArea = (NotificationPanelTitle) findViewById(R.id.title_area);
-        mTitleArea.setPanel(this);
-
-        mSettingsButton = (ImageView) findViewById(R.id.settings_button);
-        mNotificationButton = (ImageView) findViewById(R.id.notification_button);
-
-        mNotificationScroller = findViewById(R.id.notification_scroller);
-        mContentFrame = (ViewGroup)findViewById(R.id.content_frame);
-        mContentFrameMissingTranslation = 0; // not needed with current assets
-
-        // the "X" that appears in place of the clock when the panel is showing notifications
-        mClearButton = findViewById(R.id.clear_all_button);
-        mClearButton.setOnClickListener(mClearButtonListener);
-
-        mShowing = false;
-    }
-
-    @Override
-    protected void onAttachedToWindow () {
-        super.onAttachedToWindow();
-        latestItems = (NotificationRowLayout) findViewById(R.id.content);
-        int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_min_height);
-        int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_max_height);
-        mExpandHelper = new ExpandHelper(mContext, latestItems, minHeight, maxHeight);
-        mExpandHelper.setEventSource(this);
-        mExpandHelper.setGravity(Gravity.BOTTOM);
-    }
-
-    private View.OnClickListener mClearButtonListener = new View.OnClickListener() {
-        public void onClick(View v) {
-            mBar.clearAll();
-        }
-    };
-
-    public View getClearButton() {
-        return mClearButton;
-    }
-
-    public void show(boolean show, boolean animate) {
-        if (animate) {
-            if (mShowing != show) {
-                mShowing = show;
-                if (show) {
-                    setVisibility(View.VISIBLE);
-                    // Don't start the animation until we've created the layer, which is done
-                    // right before we are drawn
-                    mContentParent.setLayerType(View.LAYER_TYPE_HARDWARE, null);
-                    getViewTreeObserver().addOnPreDrawListener(mPreDrawListener);
-                } else {
-                    mChoreo.startAnimation(show);
-                }
-            }
-        } else {
-            mShowing = show;
-            setVisibility(show ? View.VISIBLE : View.GONE);
-        }
-    }
-
-    /**
-     * This is used only when we've created a hardware layer and are waiting until it's
-     * been created in order to start the appearing animation.
-     */
-    private ViewTreeObserver.OnPreDrawListener mPreDrawListener =
-            new ViewTreeObserver.OnPreDrawListener() {
-        @Override
-        public boolean onPreDraw() {
-            getViewTreeObserver().removeOnPreDrawListener(this);
-            mChoreo.startAnimation(true);
-            return false;
-        }
-    };
-
-    /**
-     * Whether the panel is showing, or, if it's animating, whether it will be
-     * when the animation is done.
-     */
-    public boolean isShowing() {
-        return mShowing;
-    }
-
-    @Override
-    public void onVisibilityChanged(View v, int vis) {
-        super.onVisibilityChanged(v, vis);
-        // when we hide, put back the notifications
-        if (vis != View.VISIBLE) {
-            if (mSettingsView != null) removeSettingsView();
-            mNotificationScroller.setVisibility(View.VISIBLE);
-            mNotificationScroller.setAlpha(1f);
-            mNotificationScroller.scrollTo(0, 0);
-            updatePanelModeButtons();
-        }
-    }
-
-    @Override
-    public boolean dispatchHoverEvent(MotionEvent event) {
-        // Ignore hover events outside of this panel bounds since such events
-        // generate spurious accessibility events with the panel content when
-        // tapping outside of it, thus confusing the user.
-        final int x = (int) event.getX();
-        final int y = (int) event.getY();
-        if (x >= 0 && x < getWidth() && y >= 0 && y < getHeight()) {
-            return super.dispatchHoverEvent(event);
-        }
-        return true;
-    }
-
-    @Override
-    public boolean dispatchKeyEvent(KeyEvent event) {
-    final int keyCode = event.getKeyCode();
-        switch (keyCode) {
-            // We exclusively handle the back key by hiding this panel.
-            case KeyEvent.KEYCODE_BACK: {
-                if (event.getAction() == KeyEvent.ACTION_UP) {
-                    mBar.animateCollapsePanels();
-                }
-                return true;
-            }
-            // We react to the home key but let the system handle it.
-            case KeyEvent.KEYCODE_HOME: {
-                if (event.getAction() == KeyEvent.ACTION_UP) {
-                    mBar.animateCollapsePanels();
-                }
-            } break;
-        }
-        return super.dispatchKeyEvent(event);
-    }
-
-    /*
-    @Override
-    protected void onLayout(boolean changed, int l, int t, int r, int b) {
-        super.onLayout(changed, l, t, r, b);
-
-        if (DEBUG) Slog.d(TAG, String.format("PANEL: onLayout: (%d, %d, %d, %d)", l, t, r, b));
-    }
-
-    @Override
-    public void onSizeChanged(int w, int h, int oldw, int oldh) {
-        super.onSizeChanged(w, h, oldw, oldh);
-        
-        if (DEBUG) {
-            Slog.d(TAG, String.format("PANEL: onSizeChanged: (%d -> %d, %d -> %d)",
-                        oldw, w, oldh, h));
-        }
-    }
-    */
-
-    public void onClick(View v) {
-        if (mSettingsButton.isEnabled() && v == mTitleArea) {
-            swapPanels();
-        }
-    }
-
-    public void setNotificationCount(int n) {
-        mNotificationCount = n;
-    }
-
-    public void setContentFrameVisible(final boolean showing, boolean animate) {
-    }
-
-    public void swapPanels() {
-        final View toShow, toHide;
-        if (mSettingsView == null) {
-            addSettingsView();
-            toShow = mSettingsView;
-            toHide = mNotificationScroller;
-        } else {
-            toShow = mNotificationScroller;
-            toHide = mSettingsView;
-        }
-        Animator a = ObjectAnimator.ofFloat(toHide, "alpha", 1f, 0f)
-                .setDuration(PANEL_FADE_DURATION);
-        a.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator _a) {
-                toHide.setVisibility(View.GONE);
-                if (toShow != null) {
-                    toShow.setVisibility(View.VISIBLE);
-                    if (toShow == mSettingsView || mNotificationCount > 0) {
-                        ObjectAnimator.ofFloat(toShow, "alpha", 0f, 1f)
-                                .setDuration(PANEL_FADE_DURATION)
-                                .start();
-                    }
-
-                    if (toHide == mSettingsView) {
-                        removeSettingsView();
-                    }
-                }
-                updateClearButton();
-                updatePanelModeButtons();
-            }
-        });
-        a.start();
-    }
- 
-    public void updateClearButton() {
-        if (mBar != null) {
-            final boolean showX 
-                = (isShowing()
-                        && mHasClearableNotifications
-                        && mNotificationScroller.getVisibility() == View.VISIBLE);
-            getClearButton().setVisibility(showX ? View.VISIBLE : View.INVISIBLE);
-        }
-    }
-
-    public void setClearable(boolean clearable) {
-        mHasClearableNotifications = clearable;
-    }
-
-    public void updatePanelModeButtons() {
-        final boolean settingsVisible = (mSettingsView != null);
-        mSettingsButton.setVisibility(!settingsVisible && mSettingsButton.isEnabled() ? View.VISIBLE : View.GONE);
-        mNotificationButton.setVisibility(settingsVisible ? View.VISIBLE : View.GONE);
-    }
-
-    public boolean isInContentArea(int x, int y) {
-        mContentArea.left = mContentFrame.getLeft() + mContentFrame.getPaddingLeft();
-        mContentArea.top = mContentFrame.getTop() + mContentFrame.getPaddingTop()
-            + (int)mContentParent.getTranslationY(); // account for any adjustment
-        mContentArea.right = mContentFrame.getRight() - mContentFrame.getPaddingRight();
-        mContentArea.bottom = mContentFrame.getBottom() - mContentFrame.getPaddingBottom();
-
-        offsetDescendantRectToMyCoords(mContentParent, mContentArea);
-        return mContentArea.contains(x, y);
-    }
-
-    void removeSettingsView() {
-        if (mSettingsView != null) {
-            mContentFrame.removeView(mSettingsView);
-            mSettingsView = null;
-        }
-    }
-
-    // NB: it will be invisible until you show it
-    void addSettingsView() {
-        LayoutInflater infl = LayoutInflater.from(getContext());
-        mSettingsView = infl.inflate(R.layout.system_bar_settings_view, mContentFrame, false);
-        mSettingsView.setVisibility(View.GONE);
-        mContentFrame.addView(mSettingsView);
-    }
-
-    private class Choreographer implements Animator.AnimatorListener {
-        boolean mVisible;
-        int mPanelHeight;
-        AnimatorSet mContentAnim;
-
-        // should group this into a multi-property animation
-        final static int OPEN_DURATION = 250;
-        final static int CLOSE_DURATION = 250;
-
-        // the panel will start to appear this many px from the end
-        final int HYPERSPACE_OFFRAMP = 200;
-
-        Choreographer() {
-        }
-
-        void createAnimation(boolean appearing) {
-            // mVisible: previous state; appearing: new state
-            
-            float start, end;
-
-            // 0: on-screen
-            // height: off-screen
-            float y = mContentParent.getTranslationY();
-            if (appearing) {
-                // we want to go from near-the-top to the top, unless we're half-open in the right
-                // general vicinity
-                end = 0;
-                if (mNotificationCount == 0) {
-                    end += mContentFrameMissingTranslation;
-                }
-                start = HYPERSPACE_OFFRAMP+end;
-            } else {
-                start = y;
-                end = y + HYPERSPACE_OFFRAMP;
-            }
-
-            Animator posAnim = ObjectAnimator.ofFloat(mContentParent, "translationY",
-                    start, end);
-            posAnim.setInterpolator(appearing ? sDecelerateInterpolator : sAccelerateInterpolator);
-
-            if (mContentAnim != null && mContentAnim.isRunning()) {
-                mContentAnim.cancel();
-            }
-
-            Animator fadeAnim = ObjectAnimator.ofFloat(mContentParent, "alpha",
-                    appearing ? 1.0f : 0.0f);
-            fadeAnim.setInterpolator(appearing ? sAccelerateInterpolator : sDecelerateInterpolator);
-
-            mContentAnim = new AnimatorSet();
-            mContentAnim
-                .play(fadeAnim)
-                .with(posAnim)
-                ;
-            mContentAnim.setDuration((DEBUG?10:1)*(appearing ? OPEN_DURATION : CLOSE_DURATION));
-            mContentAnim.addListener(this);
-        }
-
-        void startAnimation(boolean appearing) {
-            if (DEBUG) Slog.d(TAG, "startAnimation(appearing=" + appearing + ")");
-
-            createAnimation(appearing);
-            mContentAnim.start();
-
-            mVisible = appearing;
-
-            // we want to start disappearing promptly
-            if (!mVisible) updateClearButton();
-        }
-
-        public void onAnimationCancel(Animator animation) {
-            if (DEBUG) Slog.d(TAG, "onAnimationCancel");
-        }
-
-        public void onAnimationEnd(Animator animation) {
-            if (DEBUG) Slog.d(TAG, "onAnimationEnd");
-            if (! mVisible) {
-                setVisibility(View.GONE);
-            }
-            mContentParent.setLayerType(View.LAYER_TYPE_NONE, null);
-            mContentAnim = null;
-
-            // we want to show the X lazily
-            if (mVisible) updateClearButton();
-        }
-
-        public void onAnimationRepeat(Animator animation) {
-        }
-
-        public void onAnimationStart(Animator animation) {
-        }
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-        MotionEvent cancellation = MotionEvent.obtain(ev);
-        cancellation.setAction(MotionEvent.ACTION_CANCEL);
-
-        boolean intercept = mExpandHelper.onInterceptTouchEvent(ev) ||
-                super.onInterceptTouchEvent(ev);
-        if (intercept) {
-            latestItems.onInterceptTouchEvent(cancellation);
-        }
-        return intercept;
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev) {
-        boolean handled = mExpandHelper.onTouchEvent(ev) ||
-                super.onTouchEvent(ev);
-        return handled;
-    }
-
-    public void setSettingsEnabled(boolean settingsEnabled) {
-        if (mSettingsButton != null) {
-            mSettingsButton.setEnabled(settingsEnabled);
-            mSettingsButton.setVisibility(settingsEnabled ? View.VISIBLE : View.GONE);
-        }
-    }
-
-    public void refreshLayout(int layoutDirection) {
-        // Force asset reloading
-        mSettingsButton.setImageDrawable(null);
-        mSettingsButton.setImageResource(R.drawable.ic_notify_settings);
-
-        // Force asset reloading
-        mNotificationButton.setImageDrawable(null);
-        mNotificationButton.setImageResource(R.drawable.ic_notifications);
-    }
-}
-
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanelTitle.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanelTitle.java
deleted file mode 100644
index d180ab9..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanelTitle.java
+++ /dev/null
@@ -1,109 +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.systemui.statusbar.tablet;
-
-import java.util.ArrayList;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.SoundEffectConstants;
-import android.view.View;
-import android.view.accessibility.AccessibilityEvent;
-import android.widget.RelativeLayout;
-
-import com.android.systemui.R;
-
-
-public class NotificationPanelTitle extends RelativeLayout implements View.OnClickListener {
-    private NotificationPanel mPanel;
-    private ArrayList<View> buttons;
-    private View mSettingsButton;
-
-    public NotificationPanelTitle(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        buttons = new ArrayList<View>();
-        setOnClickListener(this);
-    }
-
-    public void setPanel(NotificationPanel p) {
-        mPanel = p;
-    }
-
-    @Override
-    public void onFinishInflate() {
-        super.onFinishInflate();
-        buttons.add(mSettingsButton = findViewById(R.id.settings_button));
-        buttons.add(findViewById(R.id.notification_button));
-    }
-
-    @Override
-    public void setPressed(boolean pressed) {
-        super.setPressed(pressed);
-        for (View button : buttons) {
-            if (button != null) {
-                button.setPressed(pressed);
-            }
-        }
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent e) {
-        if (!mSettingsButton.isEnabled())
-            return false;
-        switch (e.getAction()) {
-            case MotionEvent.ACTION_DOWN:
-                setPressed(true);
-                break;
-            case MotionEvent.ACTION_MOVE:
-                final int x = (int) e.getX();
-                final int y = (int) e.getY();
-                setPressed(x > 0 && x < getWidth() && y > 0 && y < getHeight());
-                break;
-            case MotionEvent.ACTION_UP:
-                if (isPressed()) {
-                    playSoundEffect(SoundEffectConstants.CLICK);
-                    mPanel.swapPanels();
-                    setPressed(false);
-                }
-                break;
-            case MotionEvent.ACTION_CANCEL:
-                setPressed(false);
-                break;
-        }
-        return true;
-    }
-
-    @Override
-    public void onClick(View v) {
-        if (mSettingsButton.isEnabled() && v == this) {
-            mPanel.swapPanels();
-        }
-    }
-
-    @Override
-    public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) {
-        if (super.onRequestSendAccessibilityEvent(child, event)) {
-            AccessibilityEvent record = AccessibilityEvent.obtain();
-            onInitializeAccessibilityEvent(record);
-            dispatchPopulateAccessibilityEvent(record);
-            event.appendRecord(record);
-            return true;
-        }
-        return false;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPeekPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPeekPanel.java
deleted file mode 100644
index ba28306..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPeekPanel.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.tablet;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.widget.RelativeLayout;
-
-public class NotificationPeekPanel extends RelativeLayout implements StatusBarPanel {
-    TabletStatusBar mBar;
-
-    public NotificationPeekPanel(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public NotificationPeekPanel(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    public boolean isInContentArea(int x, int y) {
-        final int l = getPaddingLeft();
-        final int r = getWidth() - getPaddingRight();
-        final int t = getPaddingTop();
-        final int b = getHeight() - getPaddingBottom();
-        return x >= l && x < r && y >= t && y < b;
-    }
-
-    public void setBar(TabletStatusBar bar) {
-        mBar = bar;
-    }
-
-    // We don't really want to intercept the touch event, but we *do* want to reset the fade timer
-    // in case the user is interacting with some custom controls or something.
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-        mBar.resetNotificationPeekFadeTimer();
-        return false;
-    }
-
-    @Override
-    public boolean dispatchHoverEvent(MotionEvent event) {
-        // Ignore hover events outside of this panel bounds since such events
-        // generate spurious accessibility events with the panel content when
-        // tapping outside of it, thus confusing the user.
-        final int x = (int) event.getX();
-        final int y = (int) event.getY();
-        if (x >= 0 && x < getWidth() && y >= 0 && y < getHeight()) {
-            return super.dispatchHoverEvent(event);
-        }
-        return true;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/PanelBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/PanelBackgroundView.java
deleted file mode 100644
index 9ac933f..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/PanelBackgroundView.java
+++ /dev/null
@@ -1,70 +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.systemui.statusbar.tablet;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.util.AttributeSet;
-import android.view.View;
-
-public class PanelBackgroundView extends View {
-    /*
-    private Bitmap mTexture;
-    private Paint mPaint;
-    private int mTextureWidth;
-    private int mTextureHeight;
-    */
-
-    public PanelBackgroundView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        /*
-        mTexture = BitmapFactory.decodeResource(getResources(),
-                com.android.internal.R.drawable.status_bar_background);
-        mTextureWidth = mTexture.getWidth();
-        mTextureHeight = mTexture.getHeight();
-
-        mPaint = new Paint();
-        mPaint.setDither(false);
-        */
-    }
-
-    @Override
-    public void onDraw(Canvas canvas) {
-        /*
-        final Bitmap texture = mTexture;
-        final Paint paint = mPaint;
-
-        final int width = getWidth();
-        final int height = getHeight();
-
-        final int textureWidth = mTextureWidth;
-        final int textureHeight = mTextureHeight;
-
-        int x = 0;
-        int y;
-
-        while (x < width) {
-            y = 0;
-            while (y < height) {
-                canvas.drawBitmap(texture, x, y, paint);
-                y += textureHeight;
-            }
-            x += textureWidth;
-        }
-        */
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SettingsView.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SettingsView.java
deleted file mode 100644
index e0dcbcd..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SettingsView.java
+++ /dev/null
@@ -1,128 +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.systemui.statusbar.tablet;
-
-import android.app.StatusBarManager;
-import android.content.Context;
-import android.content.Intent;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.util.AttributeSet;
-import android.util.Slog;
-import android.widget.LinearLayout;
-import android.view.View;
-import android.widget.CompoundButton;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import com.android.systemui.R;
-import com.android.systemui.settings.BrightnessController;
-import com.android.systemui.settings.ToggleSlider;
-import com.android.systemui.statusbar.policy.AirplaneModeController;
-import com.android.systemui.statusbar.policy.AutoRotateController;
-import com.android.systemui.statusbar.policy.DoNotDisturbController;
-import com.android.systemui.statusbar.policy.VolumeController;
-
-public class SettingsView extends LinearLayout implements View.OnClickListener {
-    static final String TAG = "SettingsView";
-
-    AirplaneModeController mAirplane;
-    AutoRotateController mRotate;
-    BrightnessController mBrightness;
-    DoNotDisturbController mDoNotDisturb;
-    View mRotationLockContainer;
-    View mRotationLockSeparator;
-
-    public SettingsView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public SettingsView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-
-        final Context context = getContext();
-
-        mAirplane = new AirplaneModeController(context,
-                (CompoundButton)findViewById(R.id.airplane_checkbox));
-        findViewById(R.id.network).setOnClickListener(this);
-
-        mRotationLockContainer = findViewById(R.id.rotate);
-        mRotationLockSeparator = findViewById(R.id.rotate_separator);
-        mRotate = new AutoRotateController(context,
-                (CompoundButton)findViewById(R.id.rotate_checkbox),
-                new AutoRotateController.RotationLockCallbacks() {
-                    @Override
-                    public void setRotationLockControlVisibility(boolean show) {
-                        mRotationLockContainer.setVisibility(show ? View.VISIBLE : View.GONE);
-                        mRotationLockSeparator.setVisibility(show ? View.VISIBLE : View.GONE);
-                    }
-                });
-
-        mBrightness = new BrightnessController(context,
-                (ImageView)findViewById(R.id.brightness_icon),
-                (ToggleSlider)findViewById(R.id.brightness));
-        mDoNotDisturb = new DoNotDisturbController(context,
-                (CompoundButton)findViewById(R.id.do_not_disturb_checkbox));
-        findViewById(R.id.settings).setOnClickListener(this);
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        mAirplane.release();
-        mDoNotDisturb.release();
-        mRotate.release();
-    }
-
-    public void onClick(View v) {
-        switch (v.getId()) {
-            case R.id.network:
-                onClickNetwork();
-                break;
-            case R.id.settings:
-                onClickSettings();
-                break;
-        }
-    }
-
-    private StatusBarManager getStatusBarManager() {
-        return (StatusBarManager)getContext().getSystemService(Context.STATUS_BAR_SERVICE);
-    }
-
-    // Network
-    // ----------------------------
-    private void onClickNetwork() {
-        getContext().startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS)
-                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
-        getStatusBarManager().collapsePanels();
-    }
-
-    // Settings
-    // ----------------------------
-    private void onClickSettings() {
-        getContext().startActivityAsUser(new Intent(Settings.ACTION_SETTINGS)
-                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
-                new UserHandle(UserHandle.USER_CURRENT));
-        getStatusBarManager().collapsePanels();
-    }
-}
-
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java
deleted file mode 100644
index 2924cc9..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java
+++ /dev/null
@@ -1,241 +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.systemui.statusbar.tablet;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
-import android.content.ClipData;
-import android.content.ClipDescription;
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.PixelFormat;
-import android.graphics.Point;
-import android.util.AttributeSet;
-import android.util.Slog;
-import android.view.DragEvent;
-import android.view.Gravity;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.WindowManager;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import com.android.systemui.R;
-
-public class ShirtPocket extends ImageView {
-    private static final boolean DEBUG = false;
-    private static final String  TAG = "StatusBar/ShirtPocket";
-
-    private ClipData mClipping = null;
-
-    private ImageView mPreviewIcon;
-
-    public static class DropZone extends View {
-        ShirtPocket mPocket;
-        public DropZone(Context context, AttributeSet attrs) {
-            super(context, attrs);
-        }
-        public void setPocket(ShirtPocket p) {
-            mPocket = p;
-        }
-
-        public void onAttachedToWindow() {
-            super.onAttachedToWindow();
-            if (mPocket.holding()) {
-                show(false);
-            } else {
-                hide(false);
-            }
-        }
-
-        // Drag API notes: we must be visible to receive drag events
-        private void show(boolean animate) {
-            setTranslationY(0f);
-            if (animate) {
-                setAlpha(0f);
-                ObjectAnimator.ofFloat(this, "alpha", 0f, 1f).start();
-            } else {
-                setAlpha(1f);
-            }
-        }
-
-        private void hide(boolean animate) {
-            AnimatorListenerAdapter onEnd = new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationEnd(Animator _a) {
-                    DropZone.this.setTranslationY(getHeight() + 2);
-                    DropZone.this.setAlpha(0f);
-                }
-            };
-            if (animate) {
-                Animator a = ObjectAnimator.ofFloat(this, "alpha", getAlpha(), 0f);
-                a.addListener(onEnd);
-                a.start();
-            } else {
-                onEnd.onAnimationEnd(null);
-            }
-        }
-
-        @Override
-        public boolean onDragEvent(DragEvent event) {
-            if (DEBUG) Slog.d(TAG, "onDragEvent: " + event);
-            switch (event.getAction()) {
-                // We want to appear whenever a potential drag takes off from anywhere in the UI.
-                case DragEvent.ACTION_DRAG_STARTED:
-                    show(true);
-                    break;
-                case DragEvent.ACTION_DRAG_ENTERED:
-                    if (DEBUG) Slog.d(TAG, "entered!");
-                    // XXX: TODO
-                    break;
-                case DragEvent.ACTION_DRAG_EXITED:
-                    if (DEBUG) Slog.d(TAG, "exited!");
-                    break;
-                case DragEvent.ACTION_DROP:
-                    if (DEBUG) Slog.d(TAG, "dropped!");
-                    mPocket.stash(event.getClipData());
-                    break;
-                case DragEvent.ACTION_DRAG_ENDED:
-                    hide(true);
-                    break;
-            }
-            return true; // we want everything, thank you
-        }
-    }
-
-    public ShirtPocket(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    // TODO: "pin area" panel, dragging things out
-    ObjectAnimator mAnimHide, mAnimShow;
-    
-    protected void onAttachedToWindow() {
-    }
-
-    public boolean holding() {
-        return (mClipping != null);
-    }
-
-    private void stash(ClipData clipping) {
-        mClipping = clipping;
-        if (mClipping != null) {
-            setVisibility(View.VISIBLE);
-            Bitmap icon = mClipping.getIcon();
-//            mDescription.setText(mClipping.getDescription().getLabel());
-            if (icon != null) {
-                setImageBitmap(icon);
-            } else {
-                if (mClipping.getItemCount() > 0) {
-                    // TODO: figure out how to visualize every kind of ClipData!
-                    //mAltText.setText(mClipping.getItemAt(0).coerceToText(getContext()));
-                }
-            }
-        } else {
-            setVisibility(View.GONE);
-        }
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev) {
-        final int action = ev.getAction();
-        if (action == MotionEvent.ACTION_DOWN) {
-            final ClipData clip = mClipping;
-            if (clip != null) {
-                final Bitmap icon = clip.getIcon();
-                DragShadowBuilder shadow;
-                if (icon != null) {
-                    shadow = new DragShadowBuilder(this) {
-                        public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint) {
-                            shadowSize.set(icon.getWidth(), icon.getHeight());
-                            shadowTouchPoint.set(shadowSize.x / 2, shadowSize.y / 2);
-                        }
-                        public void onDrawShadow(Canvas canvas) {
-                            canvas.drawBitmap(icon, 0, 0, new Paint());
-                        }
-                    };
-                } else {
-                    // uhhh, what now?
-                    shadow = new DragShadowBuilder(this);
-                }
-
-                startDrag(clip, shadow, null, 0);
-
-                // TODO: only discard the clipping if it was accepted
-                stash(null);
-
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /*
-    private boolean isInViewContentArea(View v, int x, int y) {
-        final int l = v.getPaddingLeft();
-        final int r = v.getWidth() - v.getPaddingRight();
-        final int t = v.getPaddingTop();
-        final int b = v.getHeight() - v.getPaddingBottom();
-        return x >= l && x < r && y >= t && y < b;
-    }
-
-    View.OnTouchListener mWindowTouchListener = new View.OnTouchListener() {
-        public boolean onTouch(View v, MotionEvent ev) {
-            final int action = ev.getAction();
-            if (action == MotionEvent.ACTION_OUTSIDE
-                    || (action == MotionEvent.ACTION_DOWN
-                        && !isInViewContentArea(mWindow, (int)ev.getX(), (int)ev.getY()))) {
-                hideWindow();
-                return true;
-            } else if (action == MotionEvent.ACTION_DOWN) {
-                final ClipData clip = mClipping;
-                if (clip != null) {
-                    final Bitmap icon = clip.getIcon();
-                    DragShadowBuilder shadow;
-                    if (icon != null) {
-                        shadow = new DragShadowBuilder(v) {
-                            public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint) {
-                                shadowSize.set(icon.getWidth(), icon.getHeight());
-                                shadowTouchPoint.set(shadowSize.x / 2, shadowSize.y / 2);
-                            }
-                            public void onDrawShadow(Canvas canvas) {
-                                canvas.drawBitmap(icon, 0, 0, new Paint());
-                            }
-                        };
-                    } else {
-                        // uhhh, what now?
-                        shadow = new DragShadowBuilder(mWindow.findViewById(R.id.preview));
-                    }
-
-                    v.startDrag(clip, shadow, null, 0);
-
-                    // TODO: only discard the clipping if it was accepted
-                    stash(null);
-
-                    return true;
-                }
-            }
-            return false;
-        }
-    };
-    */
-}
-
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/StatusBarPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/StatusBarPanel.java
deleted file mode 100644
index 8fa01d5..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/StatusBarPanel.java
+++ /dev/null
@@ -1,21 +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.systemui.statusbar.tablet;
-
-public interface StatusBarPanel {
-    public boolean isInContentArea(int x, int y);
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
deleted file mode 100644
index bfa1b63..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ /dev/null
@@ -1,1545 +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.systemui.statusbar.tablet;
-
-import android.animation.LayoutTransition;
-import android.animation.ObjectAnimator;
-import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
-import android.app.Notification;
-import android.app.PendingIntent;
-import android.app.StatusBarManager;
-import android.service.notification.StatusBarNotification;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SharedPreferences;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.graphics.PixelFormat;
-import android.graphics.Point;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.LayerDrawable;
-import android.inputmethodservice.InputMethodService;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.RemoteException;
-import android.text.TextUtils;
-import android.util.Slog;
-import android.view.Display;
-import android.view.Gravity;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.SoundEffectConstants;
-import android.view.VelocityTracker;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
-import android.view.WindowManager;
-import android.view.accessibility.AccessibilityEvent;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.ScrollView;
-import android.widget.TextView;
-
-import com.android.internal.statusbar.StatusBarIcon;
-import com.android.systemui.R;
-import com.android.systemui.statusbar.BaseStatusBar;
-import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.DoNotDisturb;
-import com.android.systemui.statusbar.NotificationData;
-import com.android.systemui.statusbar.NotificationData.Entry;
-import com.android.systemui.statusbar.SignalClusterView;
-import com.android.systemui.statusbar.StatusBarIconView;
-import com.android.systemui.statusbar.policy.BatteryController;
-import com.android.systemui.statusbar.policy.BluetoothController;
-import com.android.systemui.statusbar.policy.CompatModeButton;
-import com.android.systemui.statusbar.policy.LocationController;
-import com.android.systemui.statusbar.policy.NetworkController;
-import com.android.systemui.statusbar.policy.NotificationRowLayout;
-import com.android.systemui.statusbar.policy.Prefs;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-
-public class TabletStatusBar extends BaseStatusBar implements
-        InputMethodsPanel.OnHardKeyboardEnabledChangeListener {
-    public static final boolean DEBUG = false;
-    public static final boolean DEBUG_COMPAT_HELP = false;
-    public static final String TAG = "TabletStatusBar";
-
-
-    public static final int MSG_OPEN_NOTIFICATION_PANEL = 1000;
-    public static final int MSG_CLOSE_NOTIFICATION_PANEL = 1001;
-    public static final int MSG_OPEN_NOTIFICATION_PEEK = 1002;
-    public static final int MSG_CLOSE_NOTIFICATION_PEEK = 1003;
-    // 1020-1029 reserved for BaseStatusBar
-    public static final int MSG_SHOW_CHROME = 1030;
-    public static final int MSG_HIDE_CHROME = 1031;
-    public static final int MSG_OPEN_INPUT_METHODS_PANEL = 1040;
-    public static final int MSG_CLOSE_INPUT_METHODS_PANEL = 1041;
-    public static final int MSG_OPEN_COMPAT_MODE_PANEL = 1050;
-    public static final int MSG_CLOSE_COMPAT_MODE_PANEL = 1051;
-    public static final int MSG_STOP_TICKER = 2000;
-
-    // Fitts' Law assistance for LatinIME; see policy.EventHole
-    private static final boolean FAKE_SPACE_BAR = true;
-
-    // Notification "peeking" (flyover preview of individual notifications)
-    final static int NOTIFICATION_PEEK_HOLD_THRESH = 200; // ms
-    final static int NOTIFICATION_PEEK_FADE_DELAY = 3000; // ms
-
-    private static final int NOTIFICATION_PRIORITY_MULTIPLIER = 10; // see NotificationManagerService
-    private static final int HIDE_ICONS_BELOW_SCORE = Notification.PRIORITY_LOW * NOTIFICATION_PRIORITY_MULTIPLIER;
-
-    // The height of the bar, as definied by the build.  It may be taller if we're plugged
-    // into hdmi.
-    int mNaturalBarHeight = -1;
-    int mIconSize = -1;
-    int mIconHPadding = -1;
-    int mNavIconWidth = -1;
-    int mMenuNavIconWidth = -1;
-    private int mMaxNotificationIcons = 5;
-
-    TabletStatusBarView mStatusBarView;
-    View mNotificationArea;
-    View mNotificationTrigger;
-    NotificationIconArea mNotificationIconArea;
-    ViewGroup mNavigationArea;
-
-    boolean mNotificationDNDMode;
-    NotificationData.Entry mNotificationDNDDummyEntry;
-
-    ImageView mBackButton;
-    View mHomeButton;
-    View mMenuButton;
-    View mRecentButton;
-    private boolean mAltBackButtonEnabledForIme;
-
-    ViewGroup mFeedbackIconArea; // notification icons, IME icon, compat icon
-    InputMethodButton mInputMethodSwitchButton;
-    CompatModeButton mCompatModeButton;
-
-    NotificationPanel mNotificationPanel;
-    WindowManager.LayoutParams mNotificationPanelParams;
-    NotificationPeekPanel mNotificationPeekWindow;
-    ViewGroup mNotificationPeekRow;
-    int mNotificationPeekIndex;
-    IBinder mNotificationPeekKey;
-    LayoutTransition mNotificationPeekScrubLeft, mNotificationPeekScrubRight;
-
-    int mNotificationPeekTapDuration;
-    int mNotificationFlingVelocity;
-
-    BatteryController mBatteryController;
-    BluetoothController mBluetoothController;
-    LocationController mLocationController;
-    NetworkController mNetworkController;
-    DoNotDisturb mDoNotDisturb;
-
-    ViewGroup mBarContents;
-
-    // hide system chrome ("lights out") support
-    View mShadow;
-
-    NotificationIconArea.IconLayout mIconLayout;
-
-    TabletTicker mTicker;
-
-    View mFakeSpaceBar;
-    KeyEvent mSpaceBarKeyEvent = null;
-
-    View mCompatibilityHelpDialog = null;
-
-    // for disabling the status bar
-    int mDisabled = 0;
-
-    private InputMethodsPanel mInputMethodsPanel;
-    private CompatModePanel mCompatModePanel;
-
-    private int mSystemUiVisibility = 0;
-
-    private int mNavigationIconHints = 0;
-
-    private int mShowSearchHoldoff = 0;
-
-    public Context getContext() { return mContext; }
-
-    private Runnable mShowSearchPanel = new Runnable() {
-        public void run() {
-            showSearchPanel();
-        }
-    };
-
-    private View.OnTouchListener mHomeSearchActionListener = new View.OnTouchListener() {
-        public boolean onTouch(View v, MotionEvent event) {
-            switch(event.getAction()) {
-                case MotionEvent.ACTION_DOWN:
-                    if (!shouldDisableNavbarGestures() && !inKeyguardRestrictedInputMode()) {
-                        mHandler.removeCallbacks(mShowSearchPanel);
-                        mHandler.postDelayed(mShowSearchPanel, mShowSearchHoldoff);
-                    }
-                break;
-
-                case MotionEvent.ACTION_UP:
-                case MotionEvent.ACTION_CANCEL:
-                    mHandler.removeCallbacks(mShowSearchPanel);
-                break;
-            }
-            return false;
-        }
-    };
-
-    @Override
-    protected void createAndAddWindows() {
-        addStatusBarWindow();
-        addPanelWindows();
-    }
-
-    private void addStatusBarWindow() {
-        final View sb = makeStatusBarView();
-
-        final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
-                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                    | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
-                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
-                PixelFormat.OPAQUE);
-
-        // We explicitly leave FLAG_HARDWARE_ACCELERATED out of the flags.  The status bar occupies
-        // very little screen real-estate and is updated fairly frequently.  By using CPU rendering
-        // for the status bar, we prevent the GPU from having to wake up just to do these small
-        // updates, which should help keep power consumption down.
-
-        lp.gravity = getStatusBarGravity();
-        lp.setTitle("SystemBar");
-        lp.packageName = mContext.getPackageName();
-        mWindowManager.addView(sb, lp);
-    }
-
-    protected void addPanelWindows() {
-        final Context context = mContext;
-        final Resources res = mContext.getResources();
-
-        // Notification Panel
-        mNotificationPanel = (NotificationPanel)View.inflate(context,
-                R.layout.system_bar_notification_panel, null);
-        mNotificationPanel.setBar(this);
-        mNotificationPanel.show(false, false);
-        mNotificationPanel.setOnTouchListener(
-                new TouchOutsideListener(MSG_CLOSE_NOTIFICATION_PANEL, mNotificationPanel));
-
-        // the battery icon
-        mBatteryController.addIconView((ImageView)mNotificationPanel.findViewById(R.id.battery));
-        mBatteryController.addLabelView(
-                (TextView)mNotificationPanel.findViewById(R.id.battery_text));
-
-        // Bt
-        mBluetoothController.addIconView(
-                (ImageView)mNotificationPanel.findViewById(R.id.bluetooth));
-
-        // network icons: either a combo icon that switches between mobile and data, or distinct
-        // mobile and data icons
-        final ImageView mobileRSSI =
-                (ImageView)mNotificationPanel.findViewById(R.id.mobile_signal);
-        if (mobileRSSI != null) {
-            mNetworkController.addPhoneSignalIconView(mobileRSSI);
-        }
-        final ImageView wifiRSSI =
-                (ImageView)mNotificationPanel.findViewById(R.id.wifi_signal);
-        if (wifiRSSI != null) {
-            mNetworkController.addWifiIconView(wifiRSSI);
-        }
-        mNetworkController.addWifiLabelView(
-                (TextView)mNotificationPanel.findViewById(R.id.wifi_text));
-
-        mNetworkController.addDataTypeIconView(
-                (ImageView)mNotificationPanel.findViewById(R.id.mobile_type));
-        mNetworkController.addMobileLabelView(
-                (TextView)mNotificationPanel.findViewById(R.id.mobile_text));
-        mNetworkController.addCombinedLabelView(
-                (TextView)mBarContents.findViewById(R.id.network_text));
-
-        mStatusBarView.setIgnoreChildren(0, mNotificationTrigger, mNotificationPanel);
-
-        WindowManager.LayoutParams lp = mNotificationPanelParams = new WindowManager.LayoutParams(
-                res.getDimensionPixelSize(R.dimen.notification_panel_width),
-                getNotificationPanelHeight(),
-                WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
-                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-                    | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
-                    | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
-                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
-                    | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
-                PixelFormat.TRANSLUCENT);
-        lp.gravity = Gravity.BOTTOM | Gravity.END;
-        lp.setTitle("NotificationPanel");
-        lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
-                | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
-        lp.windowAnimations = com.android.internal.R.style.Animation; // == no animation
-//        lp.windowAnimations = com.android.internal.R.style.Animation_ZoomButtons; // simple fade
-
-        mWindowManager.addView(mNotificationPanel, lp);
-
-        // Search Panel
-        mStatusBarView.setBar(this);
-        mHomeButton.setOnTouchListener(mHomeSearchActionListener);
-        updateSearchPanel();
-
-        // Input methods Panel
-        mInputMethodsPanel = (InputMethodsPanel) View.inflate(context,
-                R.layout.system_bar_input_methods_panel, null);
-        mInputMethodsPanel.setHardKeyboardEnabledChangeListener(this);
-        mInputMethodsPanel.setOnTouchListener(new TouchOutsideListener(
-                MSG_CLOSE_INPUT_METHODS_PANEL, mInputMethodsPanel));
-        mInputMethodsPanel.setImeSwitchButton(mInputMethodSwitchButton);
-        mStatusBarView.setIgnoreChildren(2, mInputMethodSwitchButton, mInputMethodsPanel);
-        lp = new WindowManager.LayoutParams(
-                ViewGroup.LayoutParams.WRAP_CONTENT,
-                ViewGroup.LayoutParams.WRAP_CONTENT,
-                WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
-                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-                    | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
-                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
-                    | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
-                PixelFormat.TRANSLUCENT);
-        lp.gravity = Gravity.BOTTOM | Gravity.END;
-        lp.setTitle("InputMethodsPanel");
-        lp.windowAnimations = R.style.Animation_RecentPanel;
-
-        mWindowManager.addView(mInputMethodsPanel, lp);
-
-        // Compatibility mode selector panel
-        mCompatModePanel = (CompatModePanel) View.inflate(context,
-                R.layout.system_bar_compat_mode_panel, null);
-        mCompatModePanel.setOnTouchListener(new TouchOutsideListener(
-                MSG_CLOSE_COMPAT_MODE_PANEL, mCompatModePanel));
-        mCompatModePanel.setTrigger(mCompatModeButton);
-        mCompatModePanel.setVisibility(View.GONE);
-        mStatusBarView.setIgnoreChildren(3, mCompatModeButton, mCompatModePanel);
-        lp = new WindowManager.LayoutParams(
-                250,
-                ViewGroup.LayoutParams.WRAP_CONTENT,
-                WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
-                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-                    | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
-                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
-                    | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
-                PixelFormat.TRANSLUCENT);
-        lp.gravity = Gravity.BOTTOM | Gravity.END;
-        lp.setTitle("CompatModePanel");
-        lp.windowAnimations = android.R.style.Animation_Dialog;
-
-        mWindowManager.addView(mCompatModePanel, lp);
-
-        mRecentButton.setOnTouchListener(mRecentsPreloadOnTouchListener);
-
-        mPile = (NotificationRowLayout)mNotificationPanel.findViewById(R.id.content);
-        mPile.removeAllViews();
-        mPile.setLongPressListener(getNotificationLongClicker());
-
-        ScrollView scroller = (ScrollView)mPile.getParent();
-        scroller.setFillViewport(true);
-    }
-
-    @Override
-    protected int getExpandedViewMaxHeight() {
-        return getNotificationPanelHeight();
-    }
-
-    private int getNotificationPanelHeight() {
-        final Resources res = mContext.getResources();
-        final Display d = mWindowManager.getDefaultDisplay();
-        final Point size = new Point();
-        d.getRealSize(size);
-        return Math.max(res.getDimensionPixelSize(R.dimen.notification_panel_min_height), size.y);
-    }
-
-    @Override
-    public void start() {
-        super.start(); // will add the main bar view
-    }
-
-    @Override
-    protected void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        loadDimens();
-        mNotificationPanelParams.height = getNotificationPanelHeight();
-        mWindowManager.updateViewLayout(mNotificationPanel, mNotificationPanelParams);
-        mShowSearchHoldoff = mContext.getResources().getInteger(
-                R.integer.config_show_search_delay);
-        updateSearchPanel();
-    }
-
-    @Override
-    protected void refreshLayout(int layoutDirection) {
-        mNotificationPanel.refreshLayout(layoutDirection);
-    }
-
-    protected void loadDimens() {
-        final Resources res = mContext.getResources();
-
-        mNaturalBarHeight = res.getDimensionPixelSize(
-                com.android.internal.R.dimen.navigation_bar_height);
-
-        int newIconSize = res.getDimensionPixelSize(
-            com.android.internal.R.dimen.system_bar_icon_size);
-        int newIconHPadding = res.getDimensionPixelSize(
-            R.dimen.status_bar_icon_padding);
-        int newNavIconWidth = res.getDimensionPixelSize(R.dimen.navigation_key_width);
-        int newMenuNavIconWidth = res.getDimensionPixelSize(R.dimen.navigation_menu_key_width);
-
-        if (mNavigationArea != null && newNavIconWidth != mNavIconWidth) {
-            mNavIconWidth = newNavIconWidth;
-
-            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
-                     mNavIconWidth, ViewGroup.LayoutParams.MATCH_PARENT);
-            mBackButton.setLayoutParams(lp);
-            mHomeButton.setLayoutParams(lp);
-            mRecentButton.setLayoutParams(lp);
-        }
-
-        if (mNavigationArea != null && newMenuNavIconWidth != mMenuNavIconWidth) {
-            mMenuNavIconWidth = newMenuNavIconWidth;
-
-            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
-                     mMenuNavIconWidth, ViewGroup.LayoutParams.MATCH_PARENT);
-            mMenuButton.setLayoutParams(lp);
-        }
-
-        if (newIconHPadding != mIconHPadding || newIconSize != mIconSize) {
-//            Slog.d(TAG, "size=" + newIconSize + " padding=" + newIconHPadding);
-            mIconHPadding = newIconHPadding;
-            mIconSize = newIconSize;
-            reloadAllNotificationIcons(); // reload the tray
-        }
-
-        final int numIcons = res.getInteger(R.integer.config_maxNotificationIcons);
-        if (numIcons != mMaxNotificationIcons) {
-            mMaxNotificationIcons = numIcons;
-            if (DEBUG) Slog.d(TAG, "max notification icons: " + mMaxNotificationIcons);
-            reloadAllNotificationIcons();
-        }
-    }
-
-    @Override
-    public View getStatusBarView() {
-        return mStatusBarView;
-    }
-
-    protected View makeStatusBarView() {
-        final Context context = mContext;
-
-        loadDimens();
-
-        final TabletStatusBarView sb = (TabletStatusBarView)View.inflate(
-                context, R.layout.system_bar, null);
-        mStatusBarView = sb;
-
-        sb.setHandler(mHandler);
-
-        try {
-            // Sanity-check that someone hasn't set up the config wrong and asked for a navigation
-            // bar on a tablet that has only the system bar
-            if (mWindowManagerService.hasNavigationBar()) {
-                Slog.e(TAG, "Tablet device cannot show navigation bar and system bar");
-            }
-        } catch (RemoteException ex) {
-        }
-
-        mBarContents = (ViewGroup) sb.findViewById(R.id.bar_contents);
-
-        // the whole right-hand side of the bar
-        mNotificationArea = sb.findViewById(R.id.notificationArea);
-        mNotificationArea.setOnTouchListener(new NotificationTriggerTouchListener());
-
-        // the button to open the notification area
-        mNotificationTrigger = sb.findViewById(R.id.notificationTrigger);
-
-        // the more notifications icon
-        mNotificationIconArea = (NotificationIconArea)sb.findViewById(R.id.notificationIcons);
-
-        // where the icons go
-        mIconLayout = (NotificationIconArea.IconLayout) sb.findViewById(R.id.icons);
-
-        mNotificationPeekTapDuration = ViewConfiguration.getTapTimeout();
-        mNotificationFlingVelocity = 300; // px/s
-
-        mTicker = new TabletTicker(this);
-
-        // The icons
-        mLocationController = new LocationController(mContext); // will post a notification
-
-        // watch the PREF_DO_NOT_DISTURB and convert to appropriate disable() calls
-        mDoNotDisturb = new DoNotDisturb(mContext);
-
-        mBatteryController = new BatteryController(mContext);
-        mBatteryController.addIconView((ImageView)sb.findViewById(R.id.battery));
-        mBluetoothController = new BluetoothController(mContext);
-        mBluetoothController.addIconView((ImageView)sb.findViewById(R.id.bluetooth));
-
-        mNetworkController = new NetworkController(mContext);
-        final SignalClusterView signalCluster =
-                (SignalClusterView)sb.findViewById(R.id.signal_cluster);
-        mNetworkController.addSignalCluster(signalCluster);
-
-        // The navigation buttons
-        mBackButton = (ImageView)sb.findViewById(R.id.back);
-        mNavigationArea = (ViewGroup) sb.findViewById(R.id.navigationArea);
-        mHomeButton = mNavigationArea.findViewById(R.id.home);
-        mMenuButton = mNavigationArea.findViewById(R.id.menu);
-        mRecentButton = mNavigationArea.findViewById(R.id.recent_apps);
-        mRecentButton.setOnClickListener(mOnClickListener);
-
-        LayoutTransition lt = new LayoutTransition();
-        lt.setDuration(250);
-        // don't wait for these transitions; we just want icons to fade in/out, not move around
-        lt.setDuration(LayoutTransition.CHANGE_APPEARING, 0);
-        lt.setDuration(LayoutTransition.CHANGE_DISAPPEARING, 0);
-        lt.addTransitionListener(new LayoutTransition.TransitionListener() {
-            public void endTransition(LayoutTransition transition, ViewGroup container,
-                    View view, int transitionType) {
-                // ensure the menu button doesn't stick around on the status bar after it's been
-                // removed
-                mBarContents.invalidate();
-            }
-            public void startTransition(LayoutTransition transition, ViewGroup container,
-                    View view, int transitionType) {}
-        });
-        mNavigationArea.setLayoutTransition(lt);
-        // no multi-touch on the nav buttons
-        mNavigationArea.setMotionEventSplittingEnabled(false);
-
-        // The bar contents buttons
-        mFeedbackIconArea = (ViewGroup)sb.findViewById(R.id.feedbackIconArea);
-        mInputMethodSwitchButton = (InputMethodButton) sb.findViewById(R.id.imeSwitchButton);
-        // Overwrite the lister
-        mInputMethodSwitchButton.setOnClickListener(mOnClickListener);
-
-        mCompatModeButton = (CompatModeButton) sb.findViewById(R.id.compatModeButton);
-        mCompatModeButton.setOnClickListener(mOnClickListener);
-        mCompatModeButton.setVisibility(View.GONE);
-
-        // for redirecting errant bar taps to the IME
-        mFakeSpaceBar = sb.findViewById(R.id.fake_space_bar);
-
-        // "shadows" of the status bar features, for lights-out mode
-        mShadow = sb.findViewById(R.id.bar_shadow);
-        mShadow.setOnTouchListener(
-            new View.OnTouchListener() {
-                public boolean onTouch(View v, MotionEvent ev) {
-                    if (ev.getAction() == MotionEvent.ACTION_DOWN) {
-                        // even though setting the systemUI visibility below will turn these views
-                        // on, we need them to come up faster so that they can catch this motion
-                        // event
-                        mShadow.setVisibility(View.GONE);
-                        mBarContents.setVisibility(View.VISIBLE);
-
-                        try {
-                            mBarService.setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE);
-                        } catch (RemoteException ex) {
-                            // system process dead
-                        }
-                    }
-                    return false;
-                }
-            });
-
-        // tuning parameters
-        final int LIGHTS_GOING_OUT_SYSBAR_DURATION = 750;
-        final int LIGHTS_GOING_OUT_SHADOW_DURATION = 750;
-        final int LIGHTS_GOING_OUT_SHADOW_DELAY    = 0;
-
-        final int LIGHTS_COMING_UP_SYSBAR_DURATION = 200;
-//        final int LIGHTS_COMING_UP_SYSBAR_DELAY    = 50;
-        final int LIGHTS_COMING_UP_SHADOW_DURATION = 0;
-
-        LayoutTransition xition = new LayoutTransition();
-        xition.setAnimator(LayoutTransition.APPEARING,
-               ObjectAnimator.ofFloat(null, "alpha", 0.5f, 1f));
-        xition.setDuration(LayoutTransition.APPEARING, LIGHTS_COMING_UP_SYSBAR_DURATION);
-        xition.setStartDelay(LayoutTransition.APPEARING, 0);
-        xition.setAnimator(LayoutTransition.DISAPPEARING,
-               ObjectAnimator.ofFloat(null, "alpha", 1f, 0f));
-        xition.setDuration(LayoutTransition.DISAPPEARING, LIGHTS_GOING_OUT_SYSBAR_DURATION);
-        xition.setStartDelay(LayoutTransition.DISAPPEARING, 0);
-        ((ViewGroup)sb.findViewById(R.id.bar_contents_holder)).setLayoutTransition(xition);
-
-        xition = new LayoutTransition();
-        xition.setAnimator(LayoutTransition.APPEARING,
-               ObjectAnimator.ofFloat(null, "alpha", 0f, 1f));
-        xition.setDuration(LayoutTransition.APPEARING, LIGHTS_GOING_OUT_SHADOW_DURATION);
-        xition.setStartDelay(LayoutTransition.APPEARING, LIGHTS_GOING_OUT_SHADOW_DELAY);
-        xition.setAnimator(LayoutTransition.DISAPPEARING,
-               ObjectAnimator.ofFloat(null, "alpha", 1f, 0f));
-        xition.setDuration(LayoutTransition.DISAPPEARING, LIGHTS_COMING_UP_SHADOW_DURATION);
-        xition.setStartDelay(LayoutTransition.DISAPPEARING, 0);
-        ((ViewGroup)sb.findViewById(R.id.bar_shadow_holder)).setLayoutTransition(xition);
-
-        // set the initial view visibility
-        setAreThereNotifications();
-
-        // receive broadcasts
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
-        filter.addAction(Intent.ACTION_SCREEN_OFF);
-        context.registerReceiver(mBroadcastReceiver, filter);
-
-        return sb;
-    }
-
-    @Override
-    protected WindowManager.LayoutParams getRecentsLayoutParams(LayoutParams layoutParams) {
-        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
-                (int) mContext.getResources().getDimension(R.dimen.status_bar_recents_width),
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
-                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-                | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
-                | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
-                | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
-                PixelFormat.TRANSLUCENT);
-        lp.gravity = Gravity.BOTTOM | Gravity.START;
-        lp.setTitle("RecentsPanel");
-        lp.windowAnimations = com.android.internal.R.style.Animation_RecentApplications;
-        lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
-            | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
-
-        return lp;
-    }
-
-    @Override
-    protected WindowManager.LayoutParams getSearchLayoutParams(LayoutParams layoutParams) {
-        boolean opaque = false;
-        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
-                LayoutParams.MATCH_PARENT,
-                LayoutParams.MATCH_PARENT,
-                WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
-                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-                        | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
-                        | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
-                (opaque ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT));
-        if (ActivityManager.isHighEndGfx()) {
-            lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
-        } else {
-            lp.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
-            lp.dimAmount = 0.7f;
-        }
-        lp.gravity = Gravity.BOTTOM | Gravity.START;
-        lp.setTitle("SearchPanel");
-        // TODO: Define custom animation for Search panel
-        lp.windowAnimations = com.android.internal.R.style.Animation_RecentApplications;
-        lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
-                | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
-        return lp;
-    }
-
-    @Override
-    protected void updateSearchPanel() {
-        super.updateSearchPanel();
-        mSearchPanelView.setStatusBarView(mStatusBarView);
-        mStatusBarView.setDelegateView(mSearchPanelView);
-    }
-
-    @Override
-    public void showSearchPanel() {
-        super.showSearchPanel();
-        WindowManager.LayoutParams lp =
-            (android.view.WindowManager.LayoutParams) mStatusBarView.getLayoutParams();
-        lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
-        mWindowManager.updateViewLayout(mStatusBarView, lp);
-    }
-
-    @Override
-    public void hideSearchPanel() {
-        super.hideSearchPanel();
-        WindowManager.LayoutParams lp =
-            (android.view.WindowManager.LayoutParams) mStatusBarView.getLayoutParams();
-        lp.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
-        mWindowManager.updateViewLayout(mStatusBarView, lp);
-    }
-
-    public int getStatusBarHeight() {
-        return mStatusBarView != null ? mStatusBarView.getHeight()
-                : mContext.getResources().getDimensionPixelSize(
-                        com.android.internal.R.dimen.navigation_bar_height);
-    }
-
-    protected int getStatusBarGravity() {
-        return Gravity.BOTTOM | Gravity.FILL_HORIZONTAL;
-    }
-
-    public void onBarHeightChanged(int height) {
-        final WindowManager.LayoutParams lp
-                = (WindowManager.LayoutParams)mStatusBarView.getLayoutParams();
-        if (lp == null) {
-            // haven't been added yet
-            return;
-        }
-        if (lp.height != height) {
-            lp.height = height;
-            mWindowManager.updateViewLayout(mStatusBarView, lp);
-        }
-    }
-
-    @Override
-    protected BaseStatusBar.H createHandler() {
-        return new TabletStatusBar.H();
-    }
-
-    private class H extends BaseStatusBar.H {
-        public void handleMessage(Message m) {
-            super.handleMessage(m);
-            switch (m.what) {
-                case MSG_OPEN_NOTIFICATION_PEEK:
-                    if (DEBUG) Slog.d(TAG, "opening notification peek window; arg=" + m.arg1);
-
-                    if (m.arg1 >= 0) {
-                        final int N = mNotificationData.size();
-
-                        if (!mNotificationDNDMode) {
-                            if (mNotificationPeekIndex >= 0 && mNotificationPeekIndex < N) {
-                                NotificationData.Entry entry = mNotificationData.get(N-1-mNotificationPeekIndex);
-                                entry.icon.setBackgroundColor(0);
-                                mNotificationPeekIndex = -1;
-                                mNotificationPeekKey = null;
-                            }
-                        }
-
-                        final int peekIndex = m.arg1;
-                        if (peekIndex < N) {
-                            //Slog.d(TAG, "loading peek: " + peekIndex);
-                            NotificationData.Entry entry =
-                                mNotificationDNDMode
-                                    ? mNotificationDNDDummyEntry
-                                    : mNotificationData.get(N-1-peekIndex);
-                            NotificationData.Entry copy = new NotificationData.Entry(
-                                    entry.key,
-                                    entry.notification,
-                                    entry.icon);
-                            inflateViews(copy, mNotificationPeekRow);
-
-                            if (mNotificationDNDMode) {
-                                copy.content.setOnClickListener(new View.OnClickListener() {
-                                    public void onClick(View v) {
-                                        SharedPreferences.Editor editor = Prefs.edit(mContext);
-                                        editor.putBoolean(Prefs.DO_NOT_DISTURB_PREF, false);
-                                        editor.apply();
-                                        animateCollapsePanels();
-                                        visibilityChanged(false);
-                                    }
-                                });
-                            }
-
-                            entry.icon.setBackgroundColor(0x20FFFFFF);
-
-//                          mNotificationPeekRow.setLayoutTransition(
-//                              peekIndex < mNotificationPeekIndex
-//                                  ? mNotificationPeekScrubLeft
-//                                  : mNotificationPeekScrubRight);
-
-                            mNotificationPeekRow.removeAllViews();
-                            mNotificationPeekRow.addView(copy.row);
-
-                            mNotificationPeekWindow.setVisibility(View.VISIBLE);
-                            mNotificationPanel.show(false, true);
-
-                            mNotificationPeekIndex = peekIndex;
-                            mNotificationPeekKey = entry.key;
-                        }
-                    }
-                    break;
-                case MSG_CLOSE_NOTIFICATION_PEEK:
-                    if (DEBUG) Slog.d(TAG, "closing notification peek window");
-                    mNotificationPeekWindow.setVisibility(View.GONE);
-                    mNotificationPeekRow.removeAllViews();
-
-                    final int N = mNotificationData.size();
-                    if (mNotificationPeekIndex >= 0 && mNotificationPeekIndex < N) {
-                        NotificationData.Entry entry =
-                            mNotificationDNDMode
-                                ? mNotificationDNDDummyEntry
-                                : mNotificationData.get(N-1-mNotificationPeekIndex);
-                        entry.icon.setBackgroundColor(0);
-                    }
-
-                    mNotificationPeekIndex = -1;
-                    mNotificationPeekKey = null;
-                    break;
-                case MSG_OPEN_NOTIFICATION_PANEL:
-                    if (DEBUG) Slog.d(TAG, "opening notifications panel");
-                    if (!mNotificationPanel.isShowing()) {
-                        mNotificationPanel.show(true, true);
-                        mNotificationArea.setVisibility(View.INVISIBLE);
-                        mTicker.halt();
-                    }
-                    break;
-                case MSG_CLOSE_NOTIFICATION_PANEL:
-                    if (DEBUG) Slog.d(TAG, "closing notifications panel");
-                    if (mNotificationPanel.isShowing()) {
-                        mNotificationPanel.show(false, true);
-                        mNotificationArea.setVisibility(View.VISIBLE);
-                    }
-                    break;
-                case MSG_OPEN_INPUT_METHODS_PANEL:
-                    if (DEBUG) Slog.d(TAG, "opening input methods panel");
-                    if (mInputMethodsPanel != null) mInputMethodsPanel.openPanel();
-                    break;
-                case MSG_CLOSE_INPUT_METHODS_PANEL:
-                    if (DEBUG) Slog.d(TAG, "closing input methods panel");
-                    if (mInputMethodsPanel != null) mInputMethodsPanel.closePanel(false);
-                    break;
-                case MSG_OPEN_COMPAT_MODE_PANEL:
-                    if (DEBUG) Slog.d(TAG, "opening compat panel");
-                    if (mCompatModePanel != null) mCompatModePanel.openPanel();
-                    break;
-                case MSG_CLOSE_COMPAT_MODE_PANEL:
-                    if (DEBUG) Slog.d(TAG, "closing compat panel");
-                    if (mCompatModePanel != null) mCompatModePanel.closePanel();
-                    break;
-                case MSG_SHOW_CHROME:
-                    if (DEBUG) Slog.d(TAG, "hiding shadows (lights on)");
-                    mBarContents.setVisibility(View.VISIBLE);
-                    mShadow.setVisibility(View.GONE);
-                    mSystemUiVisibility &= ~View.SYSTEM_UI_FLAG_LOW_PROFILE;
-                    notifyUiVisibilityChanged();
-                    break;
-                case MSG_HIDE_CHROME:
-                    if (DEBUG) Slog.d(TAG, "showing shadows (lights out)");
-                    animateCollapsePanels();
-                    visibilityChanged(false);
-                    mBarContents.setVisibility(View.GONE);
-                    mShadow.setVisibility(View.VISIBLE);
-                    mSystemUiVisibility |= View.SYSTEM_UI_FLAG_LOW_PROFILE;
-                    notifyUiVisibilityChanged();
-                    break;
-                case MSG_STOP_TICKER:
-                    mTicker.halt();
-                    break;
-            }
-        }
-    }
-
-    public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
-        if (DEBUG) Slog.d(TAG, "addIcon(" + slot + ") -> " + icon);
-    }
-
-    public void updateIcon(String slot, int index, int viewIndex,
-            StatusBarIcon old, StatusBarIcon icon) {
-        if (DEBUG) Slog.d(TAG, "updateIcon(" + slot + ") -> " + icon);
-    }
-
-    public void removeIcon(String slot, int index, int viewIndex) {
-        if (DEBUG) Slog.d(TAG, "removeIcon(" + slot + ")");
-    }
-
-    public void addNotification(IBinder key, StatusBarNotification notification) {
-        if (DEBUG) Slog.d(TAG, "addNotification(" + key + " -> " + notification + ")");
-        addNotificationViews(key, notification);
-
-        final boolean immersive = isImmersive();
-        if (false && immersive) {
-            // TODO: immersive mode popups for tablet
-        } else if (notification.getNotification().fullScreenIntent != null) {
-            // not immersive & a full-screen alert should be shown
-            Slog.w(TAG, "Notification has fullScreenIntent and activity is not immersive;"
-                    + " sending fullScreenIntent");
-            try {
-                notification.getNotification().fullScreenIntent.send();
-            } catch (PendingIntent.CanceledException e) {
-            }
-        } else {
-            tick(key, notification, true);
-        }
-
-        setAreThereNotifications();
-    }
-
-    public void removeNotification(IBinder key) {
-        if (DEBUG) Slog.d(TAG, "removeNotification(" + key + ")");
-        removeNotificationViews(key);
-        mTicker.remove(key);
-        setAreThereNotifications();
-    }
-
-    public void showClock(boolean show) {
-        View clock = mBarContents.findViewById(R.id.clock);
-        View network_text = mBarContents.findViewById(R.id.network_text);
-        if (clock != null) {
-            clock.setVisibility(show ? View.VISIBLE : View.GONE);
-        }
-        if (network_text != null) {
-            network_text.setVisibility((!show) ? View.VISIBLE : View.GONE);
-        }
-    }
-
-    public void disable(int state) {
-        int old = mDisabled;
-        int diff = state ^ old;
-        mDisabled = state;
-
-        // act accordingly
-        if ((diff & StatusBarManager.DISABLE_CLOCK) != 0) {
-            boolean show = (state & StatusBarManager.DISABLE_CLOCK) == 0;
-            Slog.i(TAG, "DISABLE_CLOCK: " + (show ? "no" : "yes"));
-            showClock(show);
-        }
-        if ((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
-            boolean show = (state & StatusBarManager.DISABLE_SYSTEM_INFO) == 0;
-            Slog.i(TAG, "DISABLE_SYSTEM_INFO: " + (show ? "no" : "yes"));
-            mNotificationTrigger.setVisibility(show ? View.VISIBLE : View.GONE);
-        }
-        if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {
-            if ((state & StatusBarManager.DISABLE_EXPAND) != 0) {
-                Slog.i(TAG, "DISABLE_EXPAND: yes");
-                animateCollapsePanels();
-                visibilityChanged(false);
-            }
-        }
-        if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
-            mNotificationDNDMode = Prefs.read(mContext)
-                        .getBoolean(Prefs.DO_NOT_DISTURB_PREF, Prefs.DO_NOT_DISTURB_DEFAULT);
-
-            if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
-                Slog.i(TAG, "DISABLE_NOTIFICATION_ICONS: yes" + (mNotificationDNDMode?" (DND)":""));
-                mTicker.halt();
-            } else {
-                Slog.i(TAG, "DISABLE_NOTIFICATION_ICONS: no" + (mNotificationDNDMode?" (DND)":""));
-            }
-
-            // refresh icons to show either notifications or the DND message
-            reloadAllNotificationIcons();
-        } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
-            if ((state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
-                mTicker.halt();
-            }
-        }
-        if ((diff & (StatusBarManager.DISABLE_RECENT
-                        | StatusBarManager.DISABLE_BACK
-                        | StatusBarManager.DISABLE_HOME)) != 0) {
-            setNavigationVisibility(state);
-
-            if ((state & StatusBarManager.DISABLE_RECENT) != 0) {
-                // close recents if it's visible
-                mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
-                mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
-            }
-        }
-    }
-
-    private void setNavigationVisibility(int visibility) {
-        boolean disableHome = ((visibility & StatusBarManager.DISABLE_HOME) != 0);
-        boolean disableRecent = ((visibility & StatusBarManager.DISABLE_RECENT) != 0);
-        boolean disableBack = ((visibility & StatusBarManager.DISABLE_BACK) != 0);
-
-        mBackButton.setVisibility(disableBack ? View.INVISIBLE : View.VISIBLE);
-        mHomeButton.setVisibility(disableHome ? View.INVISIBLE : View.VISIBLE);
-        mRecentButton.setVisibility(disableRecent ? View.INVISIBLE : View.VISIBLE);
-
-        mInputMethodSwitchButton.setScreenLocked(
-                (visibility & StatusBarManager.DISABLE_SYSTEM_INFO) != 0);
-    }
-
-    private boolean hasTicker(Notification n) {
-        return n.tickerView != null || !TextUtils.isEmpty(n.tickerText);
-    }
-
-    @Override
-    protected void tick(IBinder key, StatusBarNotification n, boolean firstTime) {
-        // Don't show the ticker when the windowshade is open.
-        if (mNotificationPanel.isShowing()) {
-            return;
-        }
-        // If they asked for FLAG_ONLY_ALERT_ONCE, then only show this notification
-        // if it's a new notification.
-        if (!firstTime && (n.getNotification().flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0) {
-            return;
-        }
-        // Show the ticker if one is requested. Also don't do this
-        // until status bar window is attached to the window manager,
-        // because...  well, what's the point otherwise?  And trying to
-        // run a ticker without being attached will crash!
-        if (hasTicker(n.getNotification()) && mStatusBarView.getWindowToken() != null) {
-            if (0 == (mDisabled & (StatusBarManager.DISABLE_NOTIFICATION_ICONS
-                            | StatusBarManager.DISABLE_NOTIFICATION_TICKER))) {
-                mTicker.add(key, n);
-                mFeedbackIconArea.setVisibility(View.GONE);
-            }
-        }
-    }
-
-    // called by TabletTicker when it's done with all queued ticks
-    public void doneTicking() {
-        mFeedbackIconArea.setVisibility(View.VISIBLE);
-    }
-
-    public void animateExpandNotificationsPanel() {
-        mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PANEL);
-        mHandler.sendEmptyMessage(MSG_OPEN_NOTIFICATION_PANEL);
-    }
-
-    public void animateCollapsePanels() {
-        animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
-    }
-
-    public void animateCollapsePanels(int flags) {
-        if ((flags & CommandQueue.FLAG_EXCLUDE_NOTIFICATION_PANEL) == 0) {
-            mHandler.removeMessages(MSG_CLOSE_NOTIFICATION_PANEL);
-            mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PANEL);
-        }
-        if ((flags & CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL) == 0) {
-            mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
-            mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
-        }
-        if ((flags & CommandQueue.FLAG_EXCLUDE_SEARCH_PANEL) == 0) {
-            mHandler.removeMessages(MSG_CLOSE_SEARCH_PANEL);
-            mHandler.sendEmptyMessage(MSG_CLOSE_SEARCH_PANEL);
-        }
-        if ((flags & CommandQueue.FLAG_EXCLUDE_INPUT_METHODS_PANEL) == 0) {
-            mHandler.removeMessages(MSG_CLOSE_INPUT_METHODS_PANEL);
-            mHandler.sendEmptyMessage(MSG_CLOSE_INPUT_METHODS_PANEL);
-        }
-        if ((flags & CommandQueue.FLAG_EXCLUDE_COMPAT_MODE_PANEL) == 0) {
-            mHandler.removeMessages(MSG_CLOSE_COMPAT_MODE_PANEL);
-            mHandler.sendEmptyMessage(MSG_CLOSE_COMPAT_MODE_PANEL);
-        }
-
-    }
-
-    @Override
-    public void animateExpandSettingsPanel() {
-        // TODO: Implement when TabletStatusBar begins to be used.
-    }
-
-    @Override // CommandQueue
-    public void setNavigationIconHints(int hints) {
-        if (hints == mNavigationIconHints) return;
-
-        if (DEBUG) {
-            android.widget.Toast.makeText(mContext,
-                "Navigation icon hints = " + hints,
-                500).show();
-        }
-
-        mNavigationIconHints = hints;
-
-        mBackButton.setAlpha(
-            (0 != (hints & StatusBarManager.NAVIGATION_HINT_BACK_NOP)) ? 0.5f : 1.0f);
-        mHomeButton.setAlpha(
-            (0 != (hints & StatusBarManager.NAVIGATION_HINT_HOME_NOP)) ? 0.5f : 1.0f);
-        mRecentButton.setAlpha(
-            (0 != (hints & StatusBarManager.NAVIGATION_HINT_RECENT_NOP)) ? 0.5f : 1.0f);
-
-        mBackButton.setImageResource(
-            (0 != (hints & StatusBarManager.NAVIGATION_HINT_BACK_ALT))
-                ? R.drawable.ic_sysbar_back_ime
-                : R.drawable.ic_sysbar_back);
-    }
-
-    private void notifyUiVisibilityChanged() {
-        try {
-            mWindowManagerService.statusBarVisibilityChanged(mSystemUiVisibility);
-        } catch (RemoteException ex) {
-        }
-    }
-
-    @Override // CommandQueue
-    public void setSystemUiVisibility(int vis, int mask) {
-        final int oldVal = mSystemUiVisibility;
-        final int newVal = (oldVal&~mask) | (vis&mask);
-        final int diff = newVal ^ oldVal;
-
-        if (diff != 0) {
-            mSystemUiVisibility = newVal;
-
-            if (0 != (diff & View.SYSTEM_UI_FLAG_LOW_PROFILE)) {
-                mHandler.removeMessages(MSG_HIDE_CHROME);
-                mHandler.removeMessages(MSG_SHOW_CHROME);
-                mHandler.sendEmptyMessage(0 == (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE)
-                        ? MSG_SHOW_CHROME : MSG_HIDE_CHROME);
-            }
-
-            notifyUiVisibilityChanged();
-        }
-    }
-
-    public void setLightsOn(boolean on) {
-        // Policy note: if the frontmost activity needs the menu key, we assume it is a legacy app
-        // that can't handle lights-out mode.
-        if (mMenuButton.getVisibility() == View.VISIBLE) {
-            on = true;
-        }
-
-        Slog.v(TAG, "setLightsOn(" + on + ")");
-        if (on) {
-            setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE);
-        } else {
-            setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE, View.SYSTEM_UI_FLAG_LOW_PROFILE);
-        }
-    }
-
-    public void topAppWindowChanged(boolean showMenu) {
-        if (DEBUG) {
-            Slog.d(TAG, (showMenu?"showing":"hiding") + " the MENU button");
-        }
-        mMenuButton.setVisibility(showMenu ? View.VISIBLE : View.GONE);
-
-        // See above re: lights-out policy for legacy apps.
-        if (showMenu) setLightsOn(true);
-
-        mCompatModeButton.refresh();
-        if (mCompatModeButton.getVisibility() == View.VISIBLE) {
-            if (DEBUG_COMPAT_HELP
-                    || ! Prefs.read(mContext).getBoolean(Prefs.SHOWN_COMPAT_MODE_HELP, false)) {
-                showCompatibilityHelp();
-            }
-        } else {
-            hideCompatibilityHelp();
-            mCompatModePanel.closePanel();
-        }
-    }
-
-    private void showCompatibilityHelp() {
-        if (mCompatibilityHelpDialog != null) {
-            return;
-        }
-
-        mCompatibilityHelpDialog = View.inflate(mContext, R.layout.compat_mode_help, null);
-        View button = mCompatibilityHelpDialog.findViewById(R.id.button);
-
-        button.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                hideCompatibilityHelp();
-                SharedPreferences.Editor editor = Prefs.edit(mContext);
-                editor.putBoolean(Prefs.SHOWN_COMPAT_MODE_HELP, true);
-                editor.apply();
-            }
-        });
-
-        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG,
-                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-                    | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
-                    | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
-                PixelFormat.TRANSLUCENT);
-        lp.setTitle("CompatibilityModeDialog");
-        lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
-                | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
-        lp.windowAnimations = com.android.internal.R.style.Animation_ZoomButtons; // simple fade
-
-        mWindowManager.addView(mCompatibilityHelpDialog, lp);
-    }
-
-    private void hideCompatibilityHelp() {
-        if (mCompatibilityHelpDialog != null) {
-            mWindowManager.removeView(mCompatibilityHelpDialog);
-            mCompatibilityHelpDialog = null;
-        }
-    }
-
-    public void setImeWindowStatus(IBinder token, int vis, int backDisposition) {
-        mInputMethodSwitchButton.setImeWindowStatus(token,
-                (vis & InputMethodService.IME_ACTIVE) != 0);
-        updateNotificationIcons();
-        mInputMethodsPanel.setImeToken(token);
-
-        boolean altBack = (backDisposition == InputMethodService.BACK_DISPOSITION_WILL_DISMISS)
-            || ((vis & InputMethodService.IME_VISIBLE) != 0);
-        mAltBackButtonEnabledForIme = altBack;
-
-        mCommandQueue.setNavigationIconHints(
-                altBack ? (mNavigationIconHints | StatusBarManager.NAVIGATION_HINT_BACK_ALT)
-                        : (mNavigationIconHints & ~StatusBarManager.NAVIGATION_HINT_BACK_ALT));
-
-        if (FAKE_SPACE_BAR) {
-            mFakeSpaceBar.setVisibility(((vis & InputMethodService.IME_VISIBLE) != 0)
-                    ? View.VISIBLE : View.GONE);
-        }
-    }
-
-    @Override
-    public void setHardKeyboardStatus(boolean available, boolean enabled) {
-        if (DEBUG) {
-            Slog.d(TAG, "Set hard keyboard status: available=" + available
-                    + ", enabled=" + enabled);
-        }
-        mInputMethodSwitchButton.setHardKeyboardStatus(available);
-        updateNotificationIcons();
-        mInputMethodsPanel.setHardKeyboardStatus(available, enabled);
-    }
-
-    @Override
-    public void onHardKeyboardEnabledChange(boolean enabled) {
-        try {
-            mBarService.setHardKeyboardEnabled(enabled);
-        } catch (RemoteException ex) {
-        }
-    }
-
-    private boolean isImmersive() {
-        try {
-            return ActivityManagerNative.getDefault().isTopActivityImmersive();
-            //Slog.d(TAG, "Top activity is " + (immersive?"immersive":"not immersive"));
-        } catch (RemoteException ex) {
-            // the end is nigh
-            return false;
-        }
-    }
-
-    @Override
-    protected void setAreThereNotifications() {
-        if (mNotificationPanel != null) {
-            mNotificationPanel.setClearable(isDeviceProvisioned() && mNotificationData.hasClearableItems());
-        }
-    }
-
-    private View.OnClickListener mOnClickListener = new View.OnClickListener() {
-        public void onClick(View v) {
-            if (v == mRecentButton) {
-                onClickRecentButton();
-            } else if (v == mInputMethodSwitchButton) {
-                onClickInputMethodSwitchButton();
-            } else if (v == mCompatModeButton) {
-                onClickCompatModeButton();
-            }
-        }
-    };
-
-    public void onClickRecentButton() {
-        if (DEBUG) Slog.d(TAG, "clicked recent apps; disabled=" + mDisabled);
-        if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) {
-            toggleRecentApps();
-        }
-    }
-
-    public void onClickInputMethodSwitchButton() {
-        if (DEBUG) Slog.d(TAG, "clicked input methods panel; disabled=" + mDisabled);
-        int msg = (mInputMethodsPanel.getVisibility() == View.GONE) ?
-                MSG_OPEN_INPUT_METHODS_PANEL : MSG_CLOSE_INPUT_METHODS_PANEL;
-        mHandler.removeMessages(msg);
-        mHandler.sendEmptyMessage(msg);
-    }
-
-    public void onClickCompatModeButton() {
-        int msg = (mCompatModePanel.getVisibility() == View.GONE) ?
-                MSG_OPEN_COMPAT_MODE_PANEL : MSG_CLOSE_COMPAT_MODE_PANEL;
-        mHandler.removeMessages(msg);
-        mHandler.sendEmptyMessage(msg);
-    }
-
-    private class NotificationTriggerTouchListener implements View.OnTouchListener {
-        VelocityTracker mVT;
-        float mInitialTouchX, mInitialTouchY;
-        int mTouchSlop;
-
-        public NotificationTriggerTouchListener() {
-            mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
-        }
-
-        private Runnable mHiliteOnR = new Runnable() { public void run() {
-            mNotificationArea.setBackgroundResource(
-                com.android.internal.R.drawable.list_selector_pressed_holo_dark);
-        }};
-        public void hilite(final boolean on) {
-            if (on) {
-                mNotificationArea.postDelayed(mHiliteOnR, 100);
-            } else {
-                mNotificationArea.removeCallbacks(mHiliteOnR);
-                mNotificationArea.setBackground(null);
-            }
-        }
-
-        public boolean onTouch(View v, MotionEvent event) {
-//            Slog.d(TAG, String.format("touch: (%.1f, %.1f) initial: (%.1f, %.1f)",
-//                        event.getX(),
-//                        event.getY(),
-//                        mInitialTouchX,
-//                        mInitialTouchY));
-
-            if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
-                return true;
-            }
-
-            final int action = event.getAction();
-            switch (action) {
-                case MotionEvent.ACTION_DOWN:
-                    mVT = VelocityTracker.obtain();
-                    mInitialTouchX = event.getX();
-                    mInitialTouchY = event.getY();
-                    hilite(true);
-                    // fall through
-                case MotionEvent.ACTION_OUTSIDE:
-                case MotionEvent.ACTION_MOVE:
-                    // check for fling
-                    if (mVT != null) {
-                        mVT.addMovement(event);
-                        mVT.computeCurrentVelocity(1000); // pixels per second
-                        // require a little more oomph once we're already in peekaboo mode
-                        if (mVT.getYVelocity() < -mNotificationFlingVelocity) {
-                            animateExpandNotificationsPanel();
-                            visibilityChanged(true);
-                            hilite(false);
-                            mVT.recycle();
-                            mVT = null;
-                        }
-                    }
-                    return true;
-                case MotionEvent.ACTION_UP:
-                case MotionEvent.ACTION_CANCEL:
-                    hilite(false);
-                    if (mVT != null) {
-                        if (action == MotionEvent.ACTION_UP
-                         // was this a sloppy tap?
-                         && Math.abs(event.getX() - mInitialTouchX) < mTouchSlop
-                         && Math.abs(event.getY() - mInitialTouchY) < (mTouchSlop / 3)
-                         // dragging off the bottom doesn't count
-                         && (int)event.getY() < v.getBottom()) {
-                            animateExpandNotificationsPanel();
-                            visibilityChanged(true);
-                            v.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
-                            v.playSoundEffect(SoundEffectConstants.CLICK);
-                        }
-
-                        mVT.recycle();
-                        mVT = null;
-                        return true;
-                    }
-            }
-            return false;
-        }
-    }
-
-    public void resetNotificationPeekFadeTimer() {
-        if (DEBUG) {
-            Slog.d(TAG, "setting peek fade timer for " + NOTIFICATION_PEEK_FADE_DELAY
-                + "ms from now");
-        }
-        mHandler.removeMessages(MSG_CLOSE_NOTIFICATION_PEEK);
-        mHandler.sendEmptyMessageDelayed(MSG_CLOSE_NOTIFICATION_PEEK,
-                NOTIFICATION_PEEK_FADE_DELAY);
-    }
-
-    private void reloadAllNotificationIcons() {
-        if (mIconLayout == null) return;
-        mIconLayout.removeAllViews();
-        updateNotificationIcons();
-    }
-
-    @Override
-    protected void updateNotificationIcons() {
-        // XXX: need to implement a new limited linear layout class
-        // to avoid removing & readding everything
-
-        if (mIconLayout == null) return;
-
-        // first, populate the main notification panel
-        loadNotificationPanel();
-
-        final LinearLayout.LayoutParams params
-            = new LinearLayout.LayoutParams(mIconSize + 2*mIconHPadding, mNaturalBarHeight);
-
-        // alternate behavior in DND mode
-        if (mNotificationDNDMode) {
-            if (mIconLayout.getChildCount() == 0) {
-                final Notification dndNotification = new Notification.Builder(mContext)
-                    .setContentTitle(mContext.getText(R.string.notifications_off_title))
-                    .setContentText(mContext.getText(R.string.notifications_off_text))
-                    .setSmallIcon(R.drawable.ic_notification_dnd)
-                    .setOngoing(true)
-                    .getNotification();
-
-                final StatusBarIconView iconView = new StatusBarIconView(mContext, "_dnd",
-                        dndNotification);
-                iconView.setImageResource(R.drawable.ic_notification_dnd);
-                iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
-                iconView.setPadding(mIconHPadding, 0, mIconHPadding, 0);
-
-                mNotificationDNDDummyEntry = new NotificationData.Entry(
-                        null, new StatusBarNotification("", 0, "", 0, 0, Notification.PRIORITY_MAX,
-                                dndNotification, android.os.Process.myUserHandle()), iconView);
-
-                mIconLayout.addView(iconView, params);
-            }
-
-            return;
-        } else if (0 != (mDisabled & StatusBarManager.DISABLE_NOTIFICATION_ICONS)) {
-            // if icons are disabled but we're not in DND mode, this is probably Setup and we should
-            // just leave the area totally empty
-            return;
-        }
-
-        int N = mNotificationData.size();
-
-        if (DEBUG) {
-            Slog.d(TAG, "refreshing icons: " + N + " notifications, mIconLayout=" + mIconLayout);
-        }
-
-        ArrayList<View> toShow = new ArrayList<View>();
-
-        // Extra Special Icons
-        // The IME switcher and compatibility mode icons take the place of notifications. You didn't
-        // need to see all those new emails, did you?
-        int maxNotificationIconsCount = mMaxNotificationIcons;
-        if (mInputMethodSwitchButton.getVisibility() != View.GONE) maxNotificationIconsCount --;
-        if (mCompatModeButton.getVisibility()        != View.GONE) maxNotificationIconsCount --;
-
-        final boolean provisioned = isDeviceProvisioned();
-        // If the device hasn't been through Setup, we only show system notifications
-        for (int i=0; toShow.size()< maxNotificationIconsCount; i++) {
-            if (i >= N) break;
-            Entry ent = mNotificationData.get(N-i-1);
-            if ((provisioned && ent.notification.getScore() >= HIDE_ICONS_BELOW_SCORE)
-                    || showNotificationEvenIfUnprovisioned(ent.notification)) {
-                toShow.add(ent.icon);
-            }
-        }
-
-        ArrayList<View> toRemove = new ArrayList<View>();
-        for (int i=0; i<mIconLayout.getChildCount(); i++) {
-            View child = mIconLayout.getChildAt(i);
-            if (!toShow.contains(child)) {
-                toRemove.add(child);
-            }
-        }
-
-        for (View remove : toRemove) {
-            mIconLayout.removeView(remove);
-        }
-
-        for (int i=0; i<toShow.size(); i++) {
-            View v = toShow.get(i);
-            v.setPadding(mIconHPadding, 0, mIconHPadding, 0);
-            if (v.getParent() == null) {
-                mIconLayout.addView(v, i, params);
-            }
-        }
-    }
-
-    private void loadNotificationPanel() {
-        int N = mNotificationData.size();
-
-        ArrayList<View> toShow = new ArrayList<View>();
-
-        final boolean provisioned = isDeviceProvisioned();
-        // If the device hasn't been through Setup, we only show system notifications
-        for (int i=0; i<N; i++) {
-            Entry ent = mNotificationData.get(N-i-1);
-            if (provisioned || showNotificationEvenIfUnprovisioned(ent.notification)) {
-                toShow.add(ent.row);
-            }
-        }
-
-        ArrayList<View> toRemove = new ArrayList<View>();
-        for (int i=0; i<mPile.getChildCount(); i++) {
-            View child = mPile.getChildAt(i);
-            if (!toShow.contains(child)) {
-                toRemove.add(child);
-            }
-        }
-
-        for (View remove : toRemove) {
-            mPile.removeView(remove);
-        }
-
-        for (int i=0; i<toShow.size(); i++) {
-            View v = toShow.get(i);
-            if (v.getParent() == null) {
-                // the notification panel has the most important things at the bottom
-                mPile.addView(v, Math.min(toShow.size()-1-i, mPile.getChildCount()));
-            }
-        }
-
-        mNotificationPanel.setNotificationCount(toShow.size());
-        mNotificationPanel.setSettingsEnabled(isDeviceProvisioned());
-    }
-
-    @Override
-    protected void workAroundBadLayerDrawableOpacity(View v) {
-        Drawable bgd = v.getBackground();
-        if (!(bgd instanceof LayerDrawable)) return;
-
-        LayerDrawable d = (LayerDrawable) bgd;
-        v.setBackground(null);
-        d.setOpacity(PixelFormat.TRANSLUCENT);
-        v.setBackground(d);
-    }
-
-    public void clearAll() {
-        try {
-            mBarService.onClearAllNotifications();
-        } catch (RemoteException ex) {
-            // system process is dead if we're here.
-        }
-        animateCollapsePanels();
-        visibilityChanged(false);
-    }
-
-    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
-                || Intent.ACTION_SCREEN_OFF.equals(action)) {
-                int flags = CommandQueue.FLAG_EXCLUDE_NONE;
-                if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
-                    String reason = intent.getStringExtra("reason");
-                    if (reason != null && reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
-                        flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
-                    }
-                }
-                animateCollapsePanels(flags);
-            }
-        }
-    };
-
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.print("mDisabled=0x");
-        pw.println(Integer.toHexString(mDisabled));
-        pw.println("mNetworkController:");
-        mNetworkController.dump(fd, pw, args);
-    }
-
-    @Override
-    protected boolean isTopNotification(ViewGroup parent, NotificationData.Entry entry) {
-        if (parent == null || entry == null) return false;
-        return parent.indexOfChild(entry.row) == parent.getChildCount()-1;
-    }
-
-    @Override
-    protected void haltTicker() {
-        mTicker.halt();
-    }
-
-    @Override
-    protected void updateExpandedViewPos(int expandedPosition) {
-    }
-
-    @Override
-    protected boolean shouldDisableNavbarGestures() {
-        return mNotificationPanel.getVisibility() == View.VISIBLE
-                || (mDisabled & StatusBarManager.DISABLE_HOME) != 0;
-    }
-}
-
-
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java
deleted file mode 100644
index 30d49ca..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java
+++ /dev/null
@@ -1,146 +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.systemui.statusbar.tablet;
-
-import com.android.systemui.R;
-import com.android.systemui.statusbar.BaseStatusBar;
-import com.android.systemui.statusbar.DelegateViewHelper;
-
-import android.content.Context;
-import android.os.Handler;
-import android.util.AttributeSet;
-import android.util.Slog;
-import android.view.View;
-import android.view.MotionEvent;
-import android.widget.FrameLayout;
-
-public class TabletStatusBarView extends FrameLayout {
-    private Handler mHandler;
-
-    private final int MAX_PANELS = 5;
-    private final View[] mIgnoreChildren = new View[MAX_PANELS];
-    private final View[] mPanels = new View[MAX_PANELS];
-    private final int[] mPos = new int[2];
-    private DelegateViewHelper mDelegateHelper;
-
-    public TabletStatusBarView(Context context) {
-        this(context, null);
-    }
-
-    public TabletStatusBarView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        mDelegateHelper = new DelegateViewHelper(this);
-    }
-
-    public void setDelegateView(View view) {
-        mDelegateHelper.setDelegateView(view);
-    }
-
-    public void setBar(BaseStatusBar phoneStatusBar) {
-        mDelegateHelper.setBar(phoneStatusBar);
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent event) {
-        if (mDelegateHelper != null) {
-            mDelegateHelper.onInterceptTouchEvent(event);
-        }
-        return true;
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        super.onLayout(changed, left, top, right, bottom);
-        // Find the view we wish to grab events from in order to detect search gesture.
-        // Depending on the device, this will be one of the id's listed below.
-        // If we don't find one, we'll use the view provided in the constructor above (this view).
-        View view = findViewById(R.id.navigationArea);
-        if (view == null) {
-            view = findViewById(R.id.nav_buttons);
-        }
-        mDelegateHelper.setSourceView(view);
-        mDelegateHelper.setInitialTouchRegion(view);
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
-            if (TabletStatusBar.DEBUG) {
-                Slog.d(TabletStatusBar.TAG, "TabletStatusBarView intercepting touch event: " + ev);
-            }
-            // do not close the recents panel here- the intended behavior is that recents is dismissed
-            // on touch up when clicking on status bar buttons
-            // TODO: should we be closing the notification panel and input methods panel?
-            mHandler.removeMessages(TabletStatusBar.MSG_CLOSE_NOTIFICATION_PANEL);
-            mHandler.sendEmptyMessage(TabletStatusBar.MSG_CLOSE_NOTIFICATION_PANEL);
-            mHandler.removeMessages(TabletStatusBar.MSG_CLOSE_INPUT_METHODS_PANEL);
-            mHandler.sendEmptyMessage(TabletStatusBar.MSG_CLOSE_INPUT_METHODS_PANEL);
-            mHandler.removeMessages(TabletStatusBar.MSG_STOP_TICKER);
-            mHandler.sendEmptyMessage(TabletStatusBar.MSG_STOP_TICKER);
-
-            for (int i=0; i < mPanels.length; i++) {
-                if (mPanels[i] != null && mPanels[i].getVisibility() == View.VISIBLE) {
-                    if (eventInside(mIgnoreChildren[i], ev)) {
-                        if (TabletStatusBar.DEBUG) {
-                            Slog.d(TabletStatusBar.TAG,
-                                    "TabletStatusBarView eating event for view: "
-                                    + mIgnoreChildren[i]);
-                        }
-                        return true;
-                    }
-                }
-            }
-        }
-        if (TabletStatusBar.DEBUG) {
-            Slog.d(TabletStatusBar.TAG, "TabletStatusBarView not intercepting event");
-        }
-        if (mDelegateHelper != null && mDelegateHelper.onInterceptTouchEvent(ev)) {
-            return true;
-        }
-        return super.onInterceptTouchEvent(ev);
-    }
-
-    private boolean eventInside(View v, MotionEvent ev) {
-        // assume that x and y are window coords because we are.
-        final int x = (int)ev.getX();
-        final int y = (int)ev.getY();
-
-        final int[] p = mPos;
-        v.getLocationInWindow(p);
-
-        final int l = p[0];
-        final int t = p[1];
-        final int r = p[0] + v.getWidth();
-        final int b = p[1] + v.getHeight();
-
-        return x >= l && x < r && y >= t && y < b;
-    }
-
-    public void setHandler(Handler h) {
-        mHandler = h;
-    }
-
-    /**
-     * Let the status bar know that if you tap on ignore while panel is showing, don't do anything.
-     *
-     * Debounces taps on, say, a popup's trigger when the popup is already showing.
-     */
-    public void setIgnoreChildren(int index, View ignore, View panel) {
-        mIgnoreChildren[index] = ignore;
-        mPanels[index] = panel;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
deleted file mode 100644
index 095c441..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
+++ /dev/null
@@ -1,336 +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.systemui.statusbar.tablet;
-
-import java.util.Arrays;
-
-import android.animation.LayoutTransition;
-import android.app.Notification;
-import android.app.PendingIntent;
-import android.service.notification.StatusBarNotification;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.PixelFormat;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.util.Slog;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import com.android.internal.statusbar.StatusBarIcon;
-
-import com.android.systemui.R;
-import com.android.systemui.statusbar.StatusBarIconView;
-
-public class TabletTicker
-        extends Handler
-        implements LayoutTransition.TransitionListener {
-
-    private static final String TAG = "StatusBar.TabletTicker";
-
-    private static final boolean CLICKABLE_TICKER = true;
-
-    // 3 is enough to let us see most cases, but not get so far behind that it's too annoying.
-    private static final int QUEUE_LENGTH = 3;
-
-    private static final int MSG_ADVANCE = 1;
-
-    private static final int ADVANCE_DELAY = 5000; // 5 seconds
-
-    private final Context mContext;
-    private final WindowManager mWindowManager;
-
-    private ViewGroup mWindow;
-    private IBinder mCurrentKey;
-    private StatusBarNotification mCurrentNotification;
-    private View mCurrentView;
-
-    private IBinder[] mKeys = new IBinder[QUEUE_LENGTH];
-    private StatusBarNotification[] mQueue = new StatusBarNotification[QUEUE_LENGTH];
-    private int mQueuePos;
-
-    private final int mLargeIconHeight;
-
-    private TabletStatusBar mBar;
-
-    private LayoutTransition mLayoutTransition;
-    private boolean mWindowShouldClose;
-
-    public TabletTicker(TabletStatusBar bar) {
-        mBar = bar;
-        mContext = bar.getContext();
-        mWindowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
-        final Resources res = mContext.getResources();
-        mLargeIconHeight = res.getDimensionPixelSize(
-                android.R.dimen.notification_large_icon_height);
-    }
-
-    public void add(IBinder key, StatusBarNotification notification) {
-        if (false) {
-            Slog.d(TAG, "add 1 mCurrentNotification=" + mCurrentNotification
-                    + " mQueuePos=" + mQueuePos + " mQueue=" + Arrays.toString(mQueue));
-        }
-
-        // If it's already in here, remove whatever's in there and put the new one at the end.
-        remove(key, false);
-
-        mKeys[mQueuePos] = key;
-        mQueue[mQueuePos] = notification;
-
-        // If nothing is running now, start the next one.
-        if (mQueuePos == 0 && mCurrentNotification == null) {
-            sendEmptyMessage(MSG_ADVANCE);
-        }
-
-        if (mQueuePos < QUEUE_LENGTH - 1) {
-            mQueuePos++;
-        }
-    }
-
-    public void remove(IBinder key) {
-        remove(key, true);
-    }
-
-    public void remove(IBinder key, boolean advance) {
-        if (mCurrentKey == key) {
-            // Showing now
-            if (advance) {
-                removeMessages(MSG_ADVANCE);
-                sendEmptyMessage(MSG_ADVANCE);
-            }
-        } else {
-            // In the queue
-            for (int i=0; i<QUEUE_LENGTH; i++) {
-                if (mKeys[i] == key) {
-                    for (; i<QUEUE_LENGTH-1; i++) {
-                        mKeys[i] = mKeys[i+1];
-                        mQueue[i] = mQueue[i+1];
-                    }
-                    mKeys[QUEUE_LENGTH-1] = null;
-                    mQueue[QUEUE_LENGTH-1] = null;
-                    if (mQueuePos > 0) {
-                        mQueuePos--;
-                    }
-                    break;
-                }
-            }
-        }
-    }
-
-    public void halt() {
-        removeMessages(MSG_ADVANCE);
-        if (mCurrentView != null || mQueuePos != 0) {
-            for (int i=0; i<QUEUE_LENGTH; i++) {
-                mKeys[i] = null;
-                mQueue[i] = null;
-            }
-            mQueuePos = 0;
-            sendEmptyMessage(MSG_ADVANCE);
-        }
-    }
-
-    public void handleMessage(Message msg) {
-        switch (msg.what) {
-            case MSG_ADVANCE:
-                advance();
-                break;
-        }
-    }
-
-    private void advance() {
-        // Out with the old...
-        if (mCurrentView != null) {
-            if (mWindow != null) {
-                mWindow.removeView(mCurrentView);
-            }
-            mCurrentView = null;
-            mCurrentKey = null;
-            mCurrentNotification = null;
-        }
-
-        // In with the new...
-        dequeue();
-        while (mCurrentNotification != null) {
-            mCurrentView = makeTickerView(mCurrentNotification);
-            if (mCurrentView != null) {
-                if (mWindow == null) {
-                    mWindow = makeWindow();
-                    mWindowManager.addView(mWindow, mWindow.getLayoutParams());
-                }
-
-                mWindow.addView(mCurrentView);
-                sendEmptyMessageDelayed(MSG_ADVANCE, ADVANCE_DELAY);
-                break;
-            }
-            dequeue();
-        }
-
-        // if there's nothing left, close the window
-        mWindowShouldClose = (mCurrentView == null && mWindow != null);
-    }
-
-    private void dequeue() {
-        mCurrentKey = mKeys[0];
-        mCurrentNotification = mQueue[0];
-        if (false) {
-            Slog.d(TAG, "dequeue mQueuePos=" + mQueuePos + " mQueue=" + Arrays.toString(mQueue));
-        }
-        final int N = mQueuePos;
-        for (int i=0; i<N; i++) {
-            mKeys[i] = mKeys[i+1];
-            mQueue[i] = mQueue[i+1];
-        }
-        mKeys[N] = null;
-        mQueue[N] = null;
-        if (mQueuePos > 0) {
-            mQueuePos--;
-        }
-    }
-
-    private ViewGroup makeWindow() {
-        final Resources res = mContext.getResources();
-        final FrameLayout view = new FrameLayout(mContext);
-        final int width = res.getDimensionPixelSize(R.dimen.notification_ticker_width);
-        int windowFlags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                    | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
-        if (CLICKABLE_TICKER) {
-            windowFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
-        } else {
-            windowFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
-        }
-        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(width, mLargeIconHeight,
-                WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, windowFlags,
-                PixelFormat.TRANSLUCENT);
-        lp.gravity = Gravity.BOTTOM | Gravity.END;
-//        lp.windowAnimations = com.android.internal.R.style.Animation_Toast;
-
-        mLayoutTransition = new LayoutTransition();
-        mLayoutTransition.addTransitionListener(this);
-        view.setLayoutTransition(mLayoutTransition);
-        lp.setTitle("NotificationTicker");
-        view.setLayoutParams(lp);
-        return view;
-    }
-
-    public void startTransition(LayoutTransition transition, ViewGroup container,
-            View view, int transitionType) {}
-
-    public void endTransition(LayoutTransition transition, ViewGroup container,
-            View view, int transitionType) {
-        if (mWindowShouldClose) {
-            mWindowManager.removeView(mWindow);
-            mWindow = null;
-            mWindowShouldClose = false;
-            mBar.doneTicking();
-        }
-    }
-
-    private View makeTickerView(StatusBarNotification notification) {
-        final Notification n = notification.getNotification();
-
-        LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(
-                Context.LAYOUT_INFLATER_SERVICE);
-
-        ViewGroup group;
-        int layoutId;
-        int iconId;
-        if (n.largeIcon != null) {
-            iconId = R.id.right_icon;
-        } else {
-            iconId = R.id.left_icon;
-        }
-        if (n.tickerView != null) {
-            group = (ViewGroup)inflater.inflate(R.layout.system_bar_ticker_panel, null, false);
-            ViewGroup content = (FrameLayout) group.findViewById(R.id.ticker_expanded);
-            View expanded = null;
-            Exception exception = null;
-            try {
-                expanded = n.tickerView.apply(mContext, content);
-            }
-            catch (RuntimeException e) {
-                exception = e;
-            }
-            if (expanded == null) {
-                final String ident = notification.getPackageName()
-                        + "/0x" + Integer.toHexString(notification.getId());
-                Slog.e(TAG, "couldn't inflate view for notification " + ident, exception);
-                return null;
-            }
-            FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
-                    ViewGroup.LayoutParams.MATCH_PARENT, 
-                    ViewGroup.LayoutParams.MATCH_PARENT);
-            content.addView(expanded, lp);
-        } else if (n.tickerText != null) {
-            group = (ViewGroup)inflater.inflate(R.layout.system_bar_ticker_compat, mWindow, false);
-            final Drawable icon = StatusBarIconView.getIcon(mContext,
-                    new StatusBarIcon(notification.getPackageName(), notification.getUser(), n.icon, n.iconLevel, 0,
-                            n.tickerText));
-            ImageView iv = (ImageView)group.findViewById(iconId);
-            iv.setImageDrawable(icon);
-            iv.setVisibility(View.VISIBLE);
-            TextView tv = (TextView)group.findViewById(R.id.text);
-            tv.setText(n.tickerText);
-        } else {
-            throw new RuntimeException("tickerView==null && tickerText==null");
-        }
-        ImageView largeIcon = (ImageView)group.findViewById(R.id.large_icon);
-        if (n.largeIcon != null) {
-            largeIcon.setImageBitmap(n.largeIcon);
-            largeIcon.setVisibility(View.VISIBLE);
-            final ViewGroup.LayoutParams lp = largeIcon.getLayoutParams();
-            final int statusBarHeight = mBar.getStatusBarHeight();
-            if (n.largeIcon.getHeight() <= statusBarHeight) {
-                // for smallish largeIcons, it looks a little odd to have them floating halfway up
-                // the ticker, so we vertically center them in the status bar area instead
-                lp.height = statusBarHeight;
-            } else {
-                lp.height = mLargeIconHeight;
-            }
-            largeIcon.setLayoutParams(lp);
-        }
-
-        if (CLICKABLE_TICKER) {
-            PendingIntent contentIntent = notification.getNotification().contentIntent;
-            if (contentIntent != null) {
-                // create the usual notification clicker, but chain it together with a halt() call
-                // to abort the ticker too
-                final View.OnClickListener clicker = mBar.makeClicker(contentIntent,
-                        notification.getPackageName(), notification.getTag(), notification.getId());
-                group.setOnClickListener(new View.OnClickListener() {
-                    public void onClick(View v) {
-                        halt();
-                        clicker.onClick(v);
-                    }
-                });
-            } else {
-                group.setOnClickListener(null);
-            }
-        }
-
-        return group;
-    }
-}
-
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
index dc5de02..a53b25a5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -16,15 +16,15 @@
 
 package com.android.systemui.statusbar.tv;
 
-import android.service.notification.StatusBarNotification;
-import com.android.internal.statusbar.StatusBarIcon;
-import com.android.systemui.statusbar.BaseStatusBar;
-
 import android.os.IBinder;
+import android.service.notification.StatusBarNotification;
 import android.view.View;
 import android.view.ViewGroup.LayoutParams;
 import android.view.WindowManager;
 
+import com.android.internal.statusbar.StatusBarIcon;
+import com.android.systemui.statusbar.BaseStatusBar;
+
 /*
  * Status bar implementation for "large screen" products that mostly present no on-screen nav
  */
@@ -92,14 +92,12 @@
     public void setNavigationIconHints(int hints) {
     }
 
-    @Override
-    protected void createAndAddWindows() {
+    @Override // CommandQueue
+    public void setWindowState(int window, int state) {
     }
 
     @Override
-    protected WindowManager.LayoutParams getRecentsLayoutParams(
-            LayoutParams layoutParams) {
-        return null;
+    protected void createAndAddWindows() {
     }
 
     @Override
@@ -143,6 +141,10 @@
     }
 
     @Override
+    public void resetHeadsUpDecayTimer() {
+    }
+
+    @Override
     public void animateExpandSettingsPanel() {
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
index 06696fe..2c36ab7 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
@@ -29,22 +29,19 @@
 import android.os.storage.StorageEventListener;
 import android.os.storage.StorageManager;
 import android.provider.Settings;
-import android.util.Slog;
+import android.util.Log;
 
-public class StorageNotification extends StorageEventListener {
+import com.android.systemui.SystemUI;
+
+public class StorageNotification extends SystemUI {
     private static final String TAG = "StorageNotification";
     private static final boolean DEBUG = false;
 
     private static final boolean POP_UMS_ACTIVITY_ON_CONNECT = true;
 
     /**
-     * Binder context for this service
-     */
-    private Context mContext;
-    
-    /**
      * The notification that is shown when a USB mass storage host
-     * is connected. 
+     * is connected.
      * <p>
      * This is lazily created, so use {@link #setUsbStorageNotification()}.
      */
@@ -66,32 +63,40 @@
 
     private Handler        mAsyncEventHandler;
 
-    public StorageNotification(Context context) {
-        mContext = context;
+    private class StorageNotificationEventListener extends StorageEventListener {
+        public void onUsbMassStorageConnectionChanged(final boolean connected) {
+            mAsyncEventHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    onUsbMassStorageConnectionChangedAsync(connected);
+                }
+            });
+        }
+        public void onStorageStateChanged(final String path,
+                final String oldState, final String newState) {
+            mAsyncEventHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    onStorageStateChangedAsync(path, oldState, newState);
+                }
+            });
+        }
+    }
 
-        mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
+    @Override
+    public void start() {
+        mStorageManager = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
         final boolean connected = mStorageManager.isUsbMassStorageConnected();
-        if (DEBUG) Slog.d(TAG, String.format( "Startup with UMS connection %s (media state %s)",
+        if (DEBUG) Log.d(TAG, String.format( "Startup with UMS connection %s (media state %s)",
                 mUmsAvailable, Environment.getExternalStorageState()));
-        
+
         HandlerThread thr = new HandlerThread("SystemUI StorageNotification");
         thr.start();
         mAsyncEventHandler = new Handler(thr.getLooper());
 
-        onUsbMassStorageConnectionChanged(connected);
-    }
-
-    /*
-     * @override com.android.os.storage.StorageEventListener
-     */
-    @Override
-    public void onUsbMassStorageConnectionChanged(final boolean connected) {
-        mAsyncEventHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                onUsbMassStorageConnectionChangedAsync(connected);
-            }
-        });
+        StorageNotificationEventListener listener = new StorageNotificationEventListener();
+        listener.onUsbMassStorageConnectionChanged(connected);
+        mStorageManager.registerListener(listener);
     }
 
     private void onUsbMassStorageConnectionChangedAsync(boolean connected) {
@@ -102,7 +107,7 @@
          */
         String st = Environment.getExternalStorageState();
 
-        if (DEBUG) Slog.i(TAG, String.format("UMS connection changed to %s (media state %s)",
+        if (DEBUG) Log.i(TAG, String.format("UMS connection changed to %s (media state %s)",
                 connected, st));
 
         if (connected && (st.equals(
@@ -115,21 +120,8 @@
         updateUsbMassStorageNotification(connected);
     }
 
-    /*
-     * @override com.android.os.storage.StorageEventListener
-     */
-    @Override
-    public void onStorageStateChanged(final String path, final String oldState, final String newState) {
-        mAsyncEventHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                onStorageStateChangedAsync(path, oldState, newState);
-            }
-        });
-    }
-
     private void onStorageStateChangedAsync(String path, String oldState, String newState) {
-        if (DEBUG) Slog.i(TAG, String.format(
+        if (DEBUG) Log.i(TAG, String.format(
                 "Media {%s} state changed from {%s} -> {%s}", path, oldState, newState));
         if (newState.equals(Environment.MEDIA_SHARED)) {
             /*
@@ -225,7 +217,7 @@
             setMediaStorageNotification(
                     com.android.internal.R.string.ext_media_unmountable_notification_title,
                     com.android.internal.R.string.ext_media_unmountable_notification_message,
-                    com.android.internal.R.drawable.stat_notify_sdcard_usb, true, false, pi); 
+                    com.android.internal.R.drawable.stat_notify_sdcard_usb, true, false, pi);
             updateUsbMassStorageNotification(mUmsAvailable);
         } else if (newState.equals(Environment.MEDIA_REMOVED)) {
             /*
@@ -250,7 +242,7 @@
                     true, true, null);
             updateUsbMassStorageNotification(false);
         } else {
-            Slog.w(TAG, String.format("Ignoring unknown state {%s}", newState));
+            Log.w(TAG, String.format("Ignoring unknown state {%s}", newState));
         }
     }
 
@@ -291,7 +283,7 @@
         if (notificationManager == null) {
             return;
         }
-        
+
         if (visible) {
             Resources r = Resources.getSystem();
             CharSequence title = r.getText(titleId);
@@ -308,7 +300,7 @@
             } else {
                 mUsbStorageNotification.defaults &= ~Notification.DEFAULT_SOUND;
             }
-                
+
             mUsbStorageNotification.flags = Notification.FLAG_ONGOING_EVENT;
 
             mUsbStorageNotification.tickerText = title;
@@ -337,7 +329,7 @@
                 mUsbStorageNotification.fullScreenIntent = pi;
             }
         }
-    
+
         final int notificationId = mUsbStorageNotification.icon;
         if (visible) {
             notificationManager.notifyAsUser(null, notificationId, mUsbStorageNotification,
@@ -381,7 +373,7 @@
             final int notificationId = mMediaStorageNotification.icon;
             notificationManager.cancel(notificationId);
         }
-        
+
         if (visible) {
             Resources r = Resources.getSystem();
             CharSequence title = r.getText(titleId);
@@ -410,7 +402,7 @@
             mMediaStorageNotification.icon = icon;
             mMediaStorageNotification.setLatestEventInfo(mContext, title, message, pi);
         }
-    
+
         final int notificationId = mMediaStorageNotification.icon;
         if (visible) {
             notificationManager.notifyAsUser(null, notificationId,
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java
index ff06630..b5f98ad 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbAccessoryUriActivity.java
@@ -16,22 +16,19 @@
 
 package com.android.systemui.usb;
 
-import android.app.Activity;
 import android.app.AlertDialog;
 import android.content.ActivityNotFoundException;
-import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
-import android.net.Uri;
 import android.hardware.usb.UsbAccessory;
 import android.hardware.usb.UsbManager;
+import android.net.Uri;
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.util.Log;
 
 import com.android.internal.app.AlertActivity;
 import com.android.internal.app.AlertController;
-
 import com.android.systemui.R;
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java
index 2c25236..7abfc88 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java
@@ -23,9 +23,7 @@
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.graphics.Typeface;
 import android.hardware.usb.IUsbManager;
-import android.hardware.usb.UsbDevice;
 import android.hardware.usb.UsbManager;
 import android.os.Bundle;
 import android.os.IBinder;
@@ -35,12 +33,9 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.CheckBox;
-import android.widget.LinearLayout;
-import android.widget.TextView;
 
 import com.android.internal.app.AlertActivity;
 import com.android.internal.app.AlertController;
-
 import com.android.systemui.R;
 
 public class UsbDebuggingActivity extends AlertActivity
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java
index 6e88d0d..1e69fc5 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java
@@ -16,7 +16,6 @@
 
 package com.android.systemui.usb;
 
-import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.PendingIntent;
 import android.content.Context;
@@ -25,8 +24,8 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.hardware.usb.IUsbManager;
-import android.hardware.usb.UsbDevice;
 import android.hardware.usb.UsbAccessory;
+import android.hardware.usb.UsbDevice;
 import android.hardware.usb.UsbManager;
 import android.os.Bundle;
 import android.os.IBinder;
@@ -42,7 +41,6 @@
 
 import com.android.internal.app.AlertActivity;
 import com.android.internal.app.AlertController;
-
 import com.android.systemui.R;
 
 public class UsbPermissionActivity extends AlertActivity
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbStorageActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbStorageActivity.java
index e61ef8a..0ed2a54 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbStorageActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbStorageActivity.java
@@ -16,7 +16,6 @@
 
 package com.android.systemui.usb;
 
-import com.android.internal.R;
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.AlertDialog;
@@ -24,31 +23,30 @@
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.DialogInterface;
+import android.content.DialogInterface.OnCancelListener;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.DialogInterface.OnCancelListener;
 import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
 import android.hardware.usb.UsbManager;
 import android.os.Bundle;
 import android.os.Environment;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IBinder;
-import android.os.storage.IMountService;
-import android.os.storage.StorageManager;
-import android.os.storage.StorageEventListener;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.widget.ImageView;
+import android.os.storage.IMountService;
+import android.os.storage.StorageEventListener;
+import android.os.storage.StorageManager;
+import android.util.Log;
+import android.view.View;
+import android.view.WindowManager;
 import android.widget.Button;
+import android.widget.ImageView;
 import android.widget.ProgressBar;
 import android.widget.TextView;
-import android.view.View;
-import android.view.Window;
-import android.view.WindowManager;
-import android.util.Log;
+
+import com.android.internal.R;
 
 import java.util.List;
 
@@ -96,7 +94,7 @@
             switchDisplay(on);
         }
     };
-    
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -107,7 +105,7 @@
                 Log.w(TAG, "Failed to get StorageManager");
             }
         }
-        
+
         mUIHandler = new Handler();
 
         HandlerThread thr = new HandlerThread("SystemUI UsbStorageActivity");
@@ -186,7 +184,7 @@
     @Override
     protected void onPause() {
         super.onPause();
-        
+
         unregisterReceiver(mUsbStateReceiver);
         if (mStorageManager == null && mStorageListener != null) {
             mStorageManager.unregisterListener(mStorageListener);
@@ -258,7 +256,7 @@
                 // will be hidden once USB mass storage kicks in (or fails)
             }
         });
-        
+
         // things to do elsewhere
         mAsyncStorageHandler.post(new Runnable() {
             @Override
diff --git a/packages/VpnDialogs/Android.mk b/packages/VpnDialogs/Android.mk
index ac84125..4c80a26 100644
--- a/packages/VpnDialogs/Android.mk
+++ b/packages/VpnDialogs/Android.mk
@@ -22,6 +22,8 @@
 
 LOCAL_CERTIFICATE := platform
 
+LOCAL_PRIVILEGED_MODULE := true
+
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := VpnDialogs
diff --git a/packages/VpnDialogs/res/values-en-rIN/strings.xml b/packages/VpnDialogs/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..afc46d8
--- /dev/null
+++ b/packages/VpnDialogs/res/values-en-rIN/strings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="prompt" msgid="8359175999006833462">"<xliff:g id="APP">%s</xliff:g> attempts to create a VPN connection."</string>
+    <string name="warning" msgid="5470743576660160079">"By proceeding, you are giving the application permission to intercept all network traffic. "<b>"Do NOT accept unless you trust the application."</b>" Otherwise, you run the risk of having your data compromised by malicious software."</string>
+    <string name="accept" msgid="2889226408765810173">"I trust this application."</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>
+</resources>
diff --git a/packages/VpnDialogs/res/values-et-rEE/strings.xml b/packages/VpnDialogs/res/values-et-rEE/strings.xml
new file mode 100644
index 0000000..c016eb0
--- /dev/null
+++ b/packages/VpnDialogs/res/values-et-rEE/strings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="prompt" msgid="8359175999006833462">"Rakenduse <xliff:g id="APP">%s</xliff:g> katsed luua VPN-ühendust."</string>
+    <string name="warning" msgid="5470743576660160079">"Jätkates annate rakendusele loa jälgida kogu võrguliiklust. "<b>"ÄRGE nõustuge, kui te seda rakendust ei usalda."</b>" Vastasel juhul on oht, et pahavara võib kahjustada teie andmeid."</string>
+    <string name="accept" msgid="2889226408765810173">"Usaldan seda rakendust."</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>
+</resources>
diff --git a/packages/VpnDialogs/res/values-fr-rCA/strings.xml b/packages/VpnDialogs/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..1028f83
--- /dev/null
+++ b/packages/VpnDialogs/res/values-fr-rCA/strings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="prompt" msgid="8359175999006833462">"<xliff:g id="APP">%s</xliff:g> tente de créer une connexion VPN."</string>
+    <string name="warning" msgid="5470743576660160079">"En continuant, vous autorisez l\'application à intercepter l\'ensemble du trafic réseau. "<b>"N\'acceptez PAS, sauf si vous avez confiance en l\'application."</b>"Sinon, vos données risquent d\'être piratées par un logiciel malveillant."</string>
+    <string name="accept" msgid="2889226408765810173">"J\'ai confiance en cette application."</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">"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>
+</resources>
diff --git a/packages/VpnDialogs/res/values-hi/strings.xml b/packages/VpnDialogs/res/values-hi/strings.xml
index e2cb51a..50be98c 100644
--- a/packages/VpnDialogs/res/values-hi/strings.xml
+++ b/packages/VpnDialogs/res/values-hi/strings.xml
@@ -17,8 +17,8 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="prompt" msgid="8359175999006833462">"<xliff:g id="APP">%s</xliff:g> एक VPN कनेक्‍शन बनाने का प्रयास करता है."</string>
-    <string name="warning" msgid="5470743576660160079">"जारी रखकर, आप एप्लिकेशन को सभी नेटवर्क ट्रैफ़िक अवरोधित करने की अनुमति देते हैं. "<b>"जब तक आपको एप्लिकेशन पर विश्वास न हो स्‍वीकार न करें."</b>" अन्‍यथा, आपको अपने डेटा के साथ किसी दुर्भावनापूर्ण सॉफ़्टवेयर द्वारा छेड़छाड़ किए जाने का जोखिम हो सकता है."</string>
-    <string name="accept" msgid="2889226408765810173">"मुझे इस एप्लिकेशन पर विश्वास है."</string>
+    <string name="warning" msgid="5470743576660160079">"जारी रखकर, आप एप्स को सभी नेटवर्क ट्रैफ़िक अवरोधित करने की अनुमति देते हैं. "<b>"जब तक आपको एप्स पर विश्वास न हो स्‍वीकार न करें."</b>" अन्‍यथा, आपको अपने डेटा के साथ किसी दुर्भावनापूर्ण सॉफ़्टवेयर द्वारा छेड़छाड़ किए जाने का जोखिम हो सकता है."</string>
+    <string name="accept" msgid="2889226408765810173">"मुझे इस एप्स पर विश्वास है."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN कनेक्‍ट है"</string>
     <string name="configure" msgid="4905518375574791375">"कॉन्फ़िगर करें"</string>
     <string name="disconnect" msgid="971412338304200056">"डिस्‍कनेक्‍ट करें"</string>
diff --git a/packages/VpnDialogs/res/values-hy-rAM/strings.xml b/packages/VpnDialogs/res/values-hy-rAM/strings.xml
new file mode 100644
index 0000000..85db579
--- /dev/null
+++ b/packages/VpnDialogs/res/values-hy-rAM/strings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="prompt" msgid="8359175999006833462">"<xliff:g id="APP">%s</xliff:g>-ը փորձում է ստեղծել VPN կապ:"</string>
+    <string name="warning" msgid="5470743576660160079">"Շարունակելով` դուք հավելվածին թույլատրում եք կանգնեցնել ամբողջ ցանցային շարժը: "<b>"Մի ընդունեք, եթե չեք վստահում հավելվածին:"</b>" Այլապես ռիսկ կա ձեր տվյալները վտանգելու վնասարար հավելվածների կողմից:"</string>
+    <string name="accept" msgid="2889226408765810173">"Ես վստահում եմ այս ծրագրին:"</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>
+</resources>
diff --git a/packages/VpnDialogs/res/values-ka-rGE/strings.xml b/packages/VpnDialogs/res/values-ka-rGE/strings.xml
new file mode 100644
index 0000000..960d3f6
--- /dev/null
+++ b/packages/VpnDialogs/res/values-ka-rGE/strings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="prompt" msgid="8359175999006833462">"<xliff:g id="APP">%s</xliff:g> ცდილობს VPN კავშირის შექმნას."</string>
+    <string name="warning" msgid="5470743576660160079">"გაგრძელების შემთხვევაში, აპლიკაციას ექნება ქსელში გადაცემული მონაცემების მოპოვების საშუალება. "<b>"არ განაგრძოთ, თუ არ ენდობით აპლიკაციას."</b>" წინააღმდეგ შემთვევაში შესაძლოა მავნე პროგრამას თქვენ მონაცემებთან წვდომის საშუალება მიეცეს."</string>
+    <string name="accept" msgid="2889226408765810173">"ვენდობი ამ აპლიკაციას."</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>
+</resources>
diff --git a/packages/VpnDialogs/res/values-km-rKH/strings.xml b/packages/VpnDialogs/res/values-km-rKH/strings.xml
new file mode 100644
index 0000000..2c79e26
--- /dev/null
+++ b/packages/VpnDialogs/res/values-km-rKH/strings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="prompt" msgid="8359175999006833462">"<xliff:g id="APP">%s</xliff:g> ព្យាយាម​បង្កើត​ការ​តភ្ជាប់ VPN ។"</string>
+    <string name="warning" msgid="5470743576660160079">"ដោយ​បន្ត អ្នក​កំពុង​ផ្ដល់​សិទ្ធិ​ឲ្យ​កម្មវិធី​ទប់ស្កាត់​ចរាចរណ៍​បណ្ដាញ។ "<b>"កុំ​ទទួល​ លុះ​ត្រា​តែ​អ្នក​ទុក​ចិត្ត​កម្មវិធី។"</b>" បើ​មិន​ដូច្នេះ​ទេ អ្នក​ដំណើរការ​ប្រឈម​នឹង​គ្រោះថ្នាក់ ដោយ​ទិន្នន័យ​របស់​អ្នក​បាន​សម្របសម្រួល​ដោយ​កម្មវិធី​ព្យាបាទ។"</string>
+    <string name="accept" msgid="2889226408765810173">"ខ្ញុំ​ទុកចិត្ត​​​កម្មវិធី​នេះ​។"</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>
+</resources>
diff --git a/packages/VpnDialogs/res/values-lo-rLA/strings.xml b/packages/VpnDialogs/res/values-lo-rLA/strings.xml
new file mode 100644
index 0000000..9f5216b
--- /dev/null
+++ b/packages/VpnDialogs/res/values-lo-rLA/strings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="prompt" msgid="8359175999006833462">"<xliff:g id="APP">%s</xliff:g> ພະຍາຍາມສ້າງການເຊື່ອມຕໍ່ VPN."</string>
+    <string name="warning" msgid="5470743576660160079">"ຖ້າດຳເນີນຕໍ່, ແມ່ນທ່ານກຳລັງຈະໃຫ້ສິດແກ່ແອັບພລິເຄຊັນ ໃນການດັກຂໍ້ມູນຈະລາຈອນໃນເຄືອຂ່າຍທັງໝົດ. "<b>"ຢ່າຍອມຮັບ ນອກຈາກວ່າທ່ານຈະເຊື່ອໃຈແອັບພລິເຄຊັນດັ່ງກ່າວ."</b>" ຖ້າບໍ່ດັ່ງນັ້ນ, ທ່ານຈະຕົກຢູ່ໃນຄວາມສ່ຽງ ທີ່ຂໍ້ມູນຂອງທ່ານຈະຖືກຄຸກຄາມໂດຍຊອບແວທີ່ເປັນອັນຕະລາຍ."</string>
+    <string name="accept" msgid="2889226408765810173">"ຂ້ອຍເຊື່ອແອັບພລິເຄຊັນນີ້."</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>
+</resources>
diff --git a/packages/VpnDialogs/res/values-mn-rMN/strings.xml b/packages/VpnDialogs/res/values-mn-rMN/strings.xml
new file mode 100644
index 0000000..887bb73
--- /dev/null
+++ b/packages/VpnDialogs/res/values-mn-rMN/strings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="prompt" msgid="8359175999006833462">"<xliff:g id="APP">%s</xliff:g> VPN холболтыг үүсгэх гэж байна."</string>
+    <string name="warning" msgid="5470743576660160079">"Үргэлжлүүлсэнээр та аппликешнд бүх сүлжээний урсгалыг таслах зөвшөөрлийг өгөх болно. "<b>"Аппикешн баталгаагүй гэж үзсэн тохиолдолд л зөвшөөрч болорхгүй."</b>" Бусад тохиолдолд та өөрийн датаг хортой софтверийн аюулд өртөх эрсдэлийг үүсгэж байна."</string>
+    <string name="accept" msgid="2889226408765810173">"Би энэ аппликешнд итгэж байна."</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>
+</resources>
diff --git a/packages/VpnDialogs/res/values-ms-rMY/strings.xml b/packages/VpnDialogs/res/values-ms-rMY/strings.xml
new file mode 100644
index 0000000..417fbae
--- /dev/null
+++ b/packages/VpnDialogs/res/values-ms-rMY/strings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="prompt" msgid="8359175999006833462">"<xliff:g id="APP">%s</xliff:g> percubaan untuk membuat sambungan VPN."</string>
+    <string name="warning" msgid="5470743576660160079">"Dengan meneruskan, anda memberi keizinan kepada aplikasi untuk memintas semua trafik rangkaian. "<b>"JANGAN terima melainkan anda mempercayai aplikasi itu."</b>" Jika tidak, anda akan mengalami risiko data terjejas oleh perisian berniat jahat."</string>
+    <string name="accept" msgid="2889226408765810173">"Saya percayai aplikasi ini."</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>
+</resources>
diff --git a/packages/VpnDialogs/res/values-nb/strings.xml b/packages/VpnDialogs/res/values-nb/strings.xml
index f716422..6bffc98 100644
--- a/packages/VpnDialogs/res/values-nb/strings.xml
+++ b/packages/VpnDialogs/res/values-nb/strings.xml
@@ -17,8 +17,8 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="prompt" msgid="8359175999006833462">"<xliff:g id="APP">%s</xliff:g> forsøker å etablere en VPN-tilkobling."</string>
-    <string name="warning" msgid="5470743576660160079">"Ved å fortsette gir du applikasjonen tillatelse til å fange opp all nettverkstrafikk. "<b>"IKKE godta med mindre du stoler på applikasjonen."</b>" Ellers risikerer du at dataene dine kompromitteres av en ondsinnet programvare."</string>
-    <string name="accept" msgid="2889226408765810173">"Jeg stoler på denne applikasjonen."</string>
+    <string name="warning" msgid="5470743576660160079">"Ved å fortsette gir du appen tillatelse til å fange opp all nettverkstrafikk. "<b>"IKKE godta med mindre du stoler på appen."</b>" Ellers risikerer du at dataene dine kompromitteres av en ondsinnet programvare."</string>
+    <string name="accept" msgid="2889226408765810173">"Jeg stoler på denne appen."</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>
diff --git a/packages/VpnDialogs/res/values-zh-rHK/strings.xml b/packages/VpnDialogs/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..8b25d41
--- /dev/null
+++ b/packages/VpnDialogs/res/values-zh-rHK/strings.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="prompt" msgid="8359175999006833462">"<xliff:g id="APP">%s</xliff:g> 嘗試建立 VPN 連線。"</string>
+    <string name="warning" msgid="5470743576660160079">"如果繼續進行,即表示您允許該應用程式攔截所有網絡流量。"<b>"除非您信任該應用程式,否則不應接受。"</b>"不然就會讓您的資料陷於遭惡意程式入侵的風險。"</string>
+    <string name="accept" msgid="2889226408765810173">"我信任這個應用程式。"</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>
+</resources>
diff --git a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
index 96de1b9..42b8cce 100644
--- a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
+++ b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
@@ -65,11 +65,18 @@
         }
 
         try {
-            mConfig = getIntent().getParcelableExtra("config");
 
             mService = IConnectivityManager.Stub.asInterface(
                     ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
 
+            mConfig = mService.getVpnConfig();
+
+            // mConfig can be null if we are a restricted user, in that case don't show this dialog
+            if (mConfig == null) {
+                finish();
+                return;
+            }
+
             View view = View.inflate(this, R.layout.manage, null);
             if (mConfig.session != null) {
                 ((TextView) view.findViewById(R.id.session)).setText(mConfig.session);
diff --git a/packages/WallpaperCropper/Android.mk b/packages/WallpaperCropper/Android.mk
new file mode 100644
index 0000000..09b41fd
--- /dev/null
+++ b/packages/WallpaperCropper/Android.mk
@@ -0,0 +1,19 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := telephony-common
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4
+
+LOCAL_PACKAGE_NAME := WallpaperCropper
+LOCAL_CERTIFICATE := platform
+LOCAL_PRIVILEGED_MODULE := true
+
+LOCAL_PROGUARD_FLAG_FILES := proguard.flags
+
+include $(BUILD_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/WallpaperCropper/AndroidManifest.xml b/packages/WallpaperCropper/AndroidManifest.xml
new file mode 100644
index 0000000..27755bd
--- /dev/null
+++ b/packages/WallpaperCropper/AndroidManifest.xml
@@ -0,0 +1,19 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.wallpapercropper" >
+        <uses-permission android:name="android.permission.SET_WALLPAPER" />
+        <uses-permission android:name="android.permission.SET_WALLPAPER_HINTS" />
+
+        <application android:requiredForAllUsers="true">
+        <activity
+            android:name="WallpaperCropActivity"
+            android:theme="@style/Theme.WallpaperCropper"
+            android:label="@string/crop_wallpaper"
+            android:finishOnCloseSystemDialogs="true">
+            <intent-filter>
+                <action android:name="android.service.wallpaper.CROP_AND_SET_WALLPAPER" />
+                <data android:mimeType="image/*" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+        </application>
+</manifest>
diff --git a/cmds/system_server/MODULE_LICENSE_APACHE2 b/packages/WallpaperCropper/proguard.flags
similarity index 100%
copy from cmds/system_server/MODULE_LICENSE_APACHE2
copy to packages/WallpaperCropper/proguard.flags
diff --git a/packages/WallpaperCropper/res/drawable-hdpi/ic_actionbar_accept.png b/packages/WallpaperCropper/res/drawable-hdpi/ic_actionbar_accept.png
new file mode 100755
index 0000000..53cf687
--- /dev/null
+++ b/packages/WallpaperCropper/res/drawable-hdpi/ic_actionbar_accept.png
Binary files differ
diff --git a/packages/WallpaperCropper/res/drawable-mdpi/ic_actionbar_accept.png b/packages/WallpaperCropper/res/drawable-mdpi/ic_actionbar_accept.png
new file mode 100755
index 0000000..35cda8e
--- /dev/null
+++ b/packages/WallpaperCropper/res/drawable-mdpi/ic_actionbar_accept.png
Binary files differ
diff --git a/packages/WallpaperCropper/res/drawable-xhdpi/ic_actionbar_accept.png b/packages/WallpaperCropper/res/drawable-xhdpi/ic_actionbar_accept.png
new file mode 100755
index 0000000..b52dc37
--- /dev/null
+++ b/packages/WallpaperCropper/res/drawable-xhdpi/ic_actionbar_accept.png
Binary files differ
diff --git a/packages/WallpaperCropper/res/layout/actionbar_set_wallpaper.xml b/packages/WallpaperCropper/res/layout/actionbar_set_wallpaper.xml
new file mode 100644
index 0000000..1622742
--- /dev/null
+++ b/packages/WallpaperCropper/res/layout/actionbar_set_wallpaper.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    style="?android:actionButtonStyle"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" >
+    <TextView style="?android:actionBarTabTextStyle"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="start|center_vertical"
+        android:paddingRight="20dp"
+        android:drawableLeft="@drawable/ic_actionbar_accept"
+        android:drawablePadding="8dp"
+        android:gravity="center_vertical"
+        android:text="@string/wallpaper_instructions" />
+</FrameLayout>
diff --git a/packages/WallpaperCropper/res/layout/wallpaper_cropper.xml b/packages/WallpaperCropper/res/layout/wallpaper_cropper.xml
new file mode 100644
index 0000000..6dc7e35
--- /dev/null
+++ b/packages/WallpaperCropper/res/layout/wallpaper_cropper.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/wallpaper_cropper"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <com.android.wallpapercropper.CropView
+        android:id="@+id/cropView"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+    <ProgressBar
+        android:id="@+id/loading"
+        style="@android:style/Widget.Holo.ProgressBar.Large"
+        android:visibility="invisible"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:indeterminate="true"
+        android:indeterminateOnly="true"
+        android:background="@android:color/transparent" />
+</RelativeLayout>
diff --git a/packages/WallpaperCropper/res/values/strings.xml b/packages/WallpaperCropper/res/values/strings.xml
new file mode 100644
index 0000000..2b8111d
--- /dev/null
+++ b/packages/WallpaperCropper/res/values/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="crop_wallpaper">Crop wallpaper</string>
+    <!-- Button label on Wallpaper picker screen; user selects this button to set a specific wallpaper -->
+    <string name="wallpaper_instructions">Set wallpaper</string>
+</resources>
diff --git a/packages/WallpaperCropper/res/values/styles.xml b/packages/WallpaperCropper/res/values/styles.xml
new file mode 100644
index 0000000..2b63fe0
--- /dev/null
+++ b/packages/WallpaperCropper/res/values/styles.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <style name="Theme.WallpaperCropper" parent="@android:style/Theme.Holo">
+        <item name="android:actionBarStyle">@style/WallpaperCropperActionBar</item>
+        <item name="android:windowFullscreen">true</item>
+        <item name="android:windowActionBarOverlay">true</item>
+    </style>
+
+    <style name="WallpaperCropperActionBar" parent="android:style/Widget.Holo.ActionBar">
+        <item name="android:displayOptions">showCustom</item>
+        <item name="android:background">#88000000</item>
+    </style>
+</resources>
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/common/BitmapUtils.java b/packages/WallpaperCropper/src/com/android/gallery3d/common/BitmapUtils.java
new file mode 100644
index 0000000..a671ed2
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/common/BitmapUtils.java
@@ -0,0 +1,260 @@
+/*
+ * 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.gallery3d.common;
+
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.CompressFormat;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.os.Build;
+import android.util.FloatMath;
+import android.util.Log;
+
+import java.io.ByteArrayOutputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+public class BitmapUtils {
+    private static final String TAG = "BitmapUtils";
+    private static final int DEFAULT_JPEG_QUALITY = 90;
+    public static final int UNCONSTRAINED = -1;
+
+    private BitmapUtils(){}
+
+    /*
+     * Compute the sample size as a function of minSideLength
+     * and maxNumOfPixels.
+     * minSideLength is used to specify that minimal width or height of a
+     * bitmap.
+     * maxNumOfPixels is used to specify the maximal size in pixels that is
+     * tolerable in terms of memory usage.
+     *
+     * The function returns a sample size based on the constraints.
+     * Both size and minSideLength can be passed in as UNCONSTRAINED,
+     * which indicates no care of the corresponding constraint.
+     * The functions prefers returning a sample size that
+     * generates a smaller bitmap, unless minSideLength = UNCONSTRAINED.
+     *
+     * Also, the function rounds up the sample size to a power of 2 or multiple
+     * of 8 because BitmapFactory only honors sample size this way.
+     * For example, BitmapFactory downsamples an image by 2 even though the
+     * request is 3. So we round up the sample size to avoid OOM.
+     */
+    public static int computeSampleSize(int width, int height,
+            int minSideLength, int maxNumOfPixels) {
+        int initialSize = computeInitialSampleSize(
+                width, height, minSideLength, maxNumOfPixels);
+
+        return initialSize <= 8
+                ? Utils.nextPowerOf2(initialSize)
+                : (initialSize + 7) / 8 * 8;
+    }
+
+    private static int computeInitialSampleSize(int w, int h,
+            int minSideLength, int maxNumOfPixels) {
+        if (maxNumOfPixels == UNCONSTRAINED
+                && minSideLength == UNCONSTRAINED) return 1;
+
+        int lowerBound = (maxNumOfPixels == UNCONSTRAINED) ? 1 :
+                (int) FloatMath.ceil(FloatMath.sqrt((float) (w * h) / maxNumOfPixels));
+
+        if (minSideLength == UNCONSTRAINED) {
+            return lowerBound;
+        } else {
+            int sampleSize = Math.min(w / minSideLength, h / minSideLength);
+            return Math.max(sampleSize, lowerBound);
+        }
+    }
+
+    // This computes a sample size which makes the longer side at least
+    // minSideLength long. If that's not possible, return 1.
+    public static int computeSampleSizeLarger(int w, int h,
+            int minSideLength) {
+        int initialSize = Math.max(w / minSideLength, h / minSideLength);
+        if (initialSize <= 1) return 1;
+
+        return initialSize <= 8
+                ? Utils.prevPowerOf2(initialSize)
+                : initialSize / 8 * 8;
+    }
+
+    // Find the min x that 1 / x >= scale
+    public static int computeSampleSizeLarger(float scale) {
+        int initialSize = (int) FloatMath.floor(1f / scale);
+        if (initialSize <= 1) return 1;
+
+        return initialSize <= 8
+                ? Utils.prevPowerOf2(initialSize)
+                : initialSize / 8 * 8;
+    }
+
+    // Find the max x that 1 / x <= scale.
+    public static int computeSampleSize(float scale) {
+        Utils.assertTrue(scale > 0);
+        int initialSize = Math.max(1, (int) FloatMath.ceil(1 / scale));
+        return initialSize <= 8
+                ? Utils.nextPowerOf2(initialSize)
+                : (initialSize + 7) / 8 * 8;
+    }
+
+    public static Bitmap resizeBitmapByScale(
+            Bitmap bitmap, float scale, boolean recycle) {
+        int width = Math.round(bitmap.getWidth() * scale);
+        int height = Math.round(bitmap.getHeight() * scale);
+        if (width == bitmap.getWidth()
+                && height == bitmap.getHeight()) return bitmap;
+        Bitmap target = Bitmap.createBitmap(width, height, getConfig(bitmap));
+        Canvas canvas = new Canvas(target);
+        canvas.scale(scale, scale);
+        Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG);
+        canvas.drawBitmap(bitmap, 0, 0, paint);
+        if (recycle) bitmap.recycle();
+        return target;
+    }
+
+    private static Bitmap.Config getConfig(Bitmap bitmap) {
+        Bitmap.Config config = bitmap.getConfig();
+        if (config == null) {
+            config = Bitmap.Config.ARGB_8888;
+        }
+        return config;
+    }
+
+    public static Bitmap resizeDownBySideLength(
+            Bitmap bitmap, int maxLength, boolean recycle) {
+        int srcWidth = bitmap.getWidth();
+        int srcHeight = bitmap.getHeight();
+        float scale = Math.min(
+                (float) maxLength / srcWidth, (float) maxLength / srcHeight);
+        if (scale >= 1.0f) return bitmap;
+        return resizeBitmapByScale(bitmap, scale, recycle);
+    }
+
+    public static Bitmap resizeAndCropCenter(Bitmap bitmap, int size, boolean recycle) {
+        int w = bitmap.getWidth();
+        int h = bitmap.getHeight();
+        if (w == size && h == size) return bitmap;
+
+        // scale the image so that the shorter side equals to the target;
+        // the longer side will be center-cropped.
+        float scale = (float) size / Math.min(w,  h);
+
+        Bitmap target = Bitmap.createBitmap(size, size, getConfig(bitmap));
+        int width = Math.round(scale * bitmap.getWidth());
+        int height = Math.round(scale * bitmap.getHeight());
+        Canvas canvas = new Canvas(target);
+        canvas.translate((size - width) / 2f, (size - height) / 2f);
+        canvas.scale(scale, scale);
+        Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG);
+        canvas.drawBitmap(bitmap, 0, 0, paint);
+        if (recycle) bitmap.recycle();
+        return target;
+    }
+
+    public static void recycleSilently(Bitmap bitmap) {
+        if (bitmap == null) return;
+        try {
+            bitmap.recycle();
+        } catch (Throwable t) {
+            Log.w(TAG, "unable recycle bitmap", t);
+        }
+    }
+
+    public static Bitmap rotateBitmap(Bitmap source, int rotation, boolean recycle) {
+        if (rotation == 0) return source;
+        int w = source.getWidth();
+        int h = source.getHeight();
+        Matrix m = new Matrix();
+        m.postRotate(rotation);
+        Bitmap bitmap = Bitmap.createBitmap(source, 0, 0, w, h, m, true);
+        if (recycle) source.recycle();
+        return bitmap;
+    }
+
+    public static Bitmap createVideoThumbnail(String filePath) {
+        // MediaMetadataRetriever is available on API Level 8
+        // but is hidden until API Level 10
+        Class<?> clazz = null;
+        Object instance = null;
+        try {
+            clazz = Class.forName("android.media.MediaMetadataRetriever");
+            instance = clazz.newInstance();
+
+            Method method = clazz.getMethod("setDataSource", String.class);
+            method.invoke(instance, filePath);
+
+            // The method name changes between API Level 9 and 10.
+            if (Build.VERSION.SDK_INT <= 9) {
+                return (Bitmap) clazz.getMethod("captureFrame").invoke(instance);
+            } else {
+                byte[] data = (byte[]) clazz.getMethod("getEmbeddedPicture").invoke(instance);
+                if (data != null) {
+                    Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
+                    if (bitmap != null) return bitmap;
+                }
+                return (Bitmap) clazz.getMethod("getFrameAtTime").invoke(instance);
+            }
+        } catch (IllegalArgumentException ex) {
+            // Assume this is a corrupt video file
+        } catch (RuntimeException ex) {
+            // Assume this is a corrupt video file.
+        } catch (InstantiationException e) {
+            Log.e(TAG, "createVideoThumbnail", e);
+        } catch (InvocationTargetException e) {
+            Log.e(TAG, "createVideoThumbnail", e);
+        } catch (ClassNotFoundException e) {
+            Log.e(TAG, "createVideoThumbnail", e);
+        } catch (NoSuchMethodException e) {
+            Log.e(TAG, "createVideoThumbnail", e);
+        } catch (IllegalAccessException e) {
+            Log.e(TAG, "createVideoThumbnail", e);
+        } finally {
+            try {
+                if (instance != null) {
+                    clazz.getMethod("release").invoke(instance);
+                }
+            } catch (Exception ignored) {
+            }
+        }
+        return null;
+    }
+
+    public static byte[] compressToBytes(Bitmap bitmap) {
+        return compressToBytes(bitmap, DEFAULT_JPEG_QUALITY);
+    }
+
+    public static byte[] compressToBytes(Bitmap bitmap, int quality) {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream(65536);
+        bitmap.compress(CompressFormat.JPEG, quality, baos);
+        return baos.toByteArray();
+    }
+
+    public static boolean isSupportedByRegionDecoder(String mimeType) {
+        if (mimeType == null) return false;
+        mimeType = mimeType.toLowerCase();
+        return mimeType.startsWith("image/") &&
+                (!mimeType.equals("image/gif") && !mimeType.endsWith("bmp"));
+    }
+
+    public static boolean isRotationSupported(String mimeType) {
+        if (mimeType == null) return false;
+        mimeType = mimeType.toLowerCase();
+        return mimeType.equals("image/jpeg");
+    }
+}
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/common/Utils.java b/packages/WallpaperCropper/src/com/android/gallery3d/common/Utils.java
new file mode 100644
index 0000000..614a081
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/common/Utils.java
@@ -0,0 +1,340 @@
+/*
+ * 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.gallery3d.common;
+
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.database.Cursor;
+import android.os.Build;
+import android.os.ParcelFileDescriptor;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+
+public class Utils {
+    private static final String TAG = "Utils";
+    private static final String DEBUG_TAG = "GalleryDebug";
+
+    private static final long POLY64REV = 0x95AC9329AC4BC9B5L;
+    private static final long INITIALCRC = 0xFFFFFFFFFFFFFFFFL;
+
+    private static long[] sCrcTable = new long[256];
+
+    private static final boolean IS_DEBUG_BUILD =
+            Build.TYPE.equals("eng") || Build.TYPE.equals("userdebug");
+
+    private static final String MASK_STRING = "********************************";
+
+    // Throws AssertionError if the input is false.
+    public static void assertTrue(boolean cond) {
+        if (!cond) {
+            throw new AssertionError();
+        }
+    }
+
+    // Throws AssertionError with the message. We had a method having the form
+    //   assertTrue(boolean cond, String message, Object ... args);
+    // However a call to that method will cause memory allocation even if the
+    // condition is false (due to autoboxing generated by "Object ... args"),
+    // so we don't use that anymore.
+    public static void fail(String message, Object ... args) {
+        throw new AssertionError(
+                args.length == 0 ? message : String.format(message, args));
+    }
+
+    // Throws NullPointerException if the input is null.
+    public static <T> T checkNotNull(T object) {
+        if (object == null) throw new NullPointerException();
+        return object;
+    }
+
+    // Returns true if two input Object are both null or equal
+    // to each other.
+    public static boolean equals(Object a, Object b) {
+        return (a == b) || (a == null ? false : a.equals(b));
+    }
+
+    // Returns the next power of two.
+    // Returns the input if it is already power of 2.
+    // Throws IllegalArgumentException if the input is <= 0 or
+    // the answer overflows.
+    public static int nextPowerOf2(int n) {
+        if (n <= 0 || n > (1 << 30)) throw new IllegalArgumentException("n is invalid: " + n);
+        n -= 1;
+        n |= n >> 16;
+        n |= n >> 8;
+        n |= n >> 4;
+        n |= n >> 2;
+        n |= n >> 1;
+        return n + 1;
+    }
+
+    // Returns the previous power of two.
+    // Returns the input if it is already power of 2.
+    // Throws IllegalArgumentException if the input is <= 0
+    public static int prevPowerOf2(int n) {
+        if (n <= 0) throw new IllegalArgumentException();
+        return Integer.highestOneBit(n);
+    }
+
+    // Returns the input value x clamped to the range [min, max].
+    public static int clamp(int x, int min, int max) {
+        if (x > max) return max;
+        if (x < min) return min;
+        return x;
+    }
+
+    // Returns the input value x clamped to the range [min, max].
+    public static float clamp(float x, float min, float max) {
+        if (x > max) return max;
+        if (x < min) return min;
+        return x;
+    }
+
+    // Returns the input value x clamped to the range [min, max].
+    public static long clamp(long x, long min, long max) {
+        if (x > max) return max;
+        if (x < min) return min;
+        return x;
+    }
+
+    public static boolean isOpaque(int color) {
+        return color >>> 24 == 0xFF;
+    }
+
+    public static void swap(int[] array, int i, int j) {
+        int temp = array[i];
+        array[i] = array[j];
+        array[j] = temp;
+    }
+
+    /**
+     * A function thats returns a 64-bit crc for string
+     *
+     * @param in input string
+     * @return a 64-bit crc value
+     */
+    public static final long crc64Long(String in) {
+        if (in == null || in.length() == 0) {
+            return 0;
+        }
+        return crc64Long(getBytes(in));
+    }
+
+    static {
+        // http://bioinf.cs.ucl.ac.uk/downloads/crc64/crc64.c
+        long part;
+        for (int i = 0; i < 256; i++) {
+            part = i;
+            for (int j = 0; j < 8; j++) {
+                long x = ((int) part & 1) != 0 ? POLY64REV : 0;
+                part = (part >> 1) ^ x;
+            }
+            sCrcTable[i] = part;
+        }
+    }
+
+    public static final long crc64Long(byte[] buffer) {
+        long crc = INITIALCRC;
+        for (int k = 0, n = buffer.length; k < n; ++k) {
+            crc = sCrcTable[(((int) crc) ^ buffer[k]) & 0xff] ^ (crc >> 8);
+        }
+        return crc;
+    }
+
+    public static byte[] getBytes(String in) {
+        byte[] result = new byte[in.length() * 2];
+        int output = 0;
+        for (char ch : in.toCharArray()) {
+            result[output++] = (byte) (ch & 0xFF);
+            result[output++] = (byte) (ch >> 8);
+        }
+        return result;
+    }
+
+    public static void closeSilently(Closeable c) {
+        if (c == null) return;
+        try {
+            c.close();
+        } catch (IOException t) {
+            Log.w(TAG, "close fail ", t);
+        }
+    }
+
+    public static int compare(long a, long b) {
+        return a < b ? -1 : a == b ? 0 : 1;
+    }
+
+    public static int ceilLog2(float value) {
+        int i;
+        for (i = 0; i < 31; i++) {
+            if ((1 << i) >= value) break;
+        }
+        return i;
+    }
+
+    public static int floorLog2(float value) {
+        int i;
+        for (i = 0; i < 31; i++) {
+            if ((1 << i) > value) break;
+        }
+        return i - 1;
+    }
+
+    public static void closeSilently(ParcelFileDescriptor fd) {
+        try {
+            if (fd != null) fd.close();
+        } catch (Throwable t) {
+            Log.w(TAG, "fail to close", t);
+        }
+    }
+
+    public static void closeSilently(Cursor cursor) {
+        try {
+            if (cursor != null) cursor.close();
+        } catch (Throwable t) {
+            Log.w(TAG, "fail to close", t);
+        }
+    }
+
+    public static float interpolateAngle(
+            float source, float target, float progress) {
+        // interpolate the angle from source to target
+        // We make the difference in the range of [-179, 180], this is the
+        // shortest path to change source to target.
+        float diff = target - source;
+        if (diff < 0) diff += 360f;
+        if (diff > 180) diff -= 360f;
+
+        float result = source + diff * progress;
+        return result < 0 ? result + 360f : result;
+    }
+
+    public static float interpolateScale(
+            float source, float target, float progress) {
+        return source + progress * (target - source);
+    }
+
+    public static String ensureNotNull(String value) {
+        return value == null ? "" : value;
+    }
+
+    public static float parseFloatSafely(String content, float defaultValue) {
+        if (content == null) return defaultValue;
+        try {
+            return Float.parseFloat(content);
+        } catch (NumberFormatException e) {
+            return defaultValue;
+        }
+    }
+
+    public static int parseIntSafely(String content, int defaultValue) {
+        if (content == null) return defaultValue;
+        try {
+            return Integer.parseInt(content);
+        } catch (NumberFormatException e) {
+            return defaultValue;
+        }
+    }
+
+    public static boolean isNullOrEmpty(String exifMake) {
+        return TextUtils.isEmpty(exifMake);
+    }
+
+    public static void waitWithoutInterrupt(Object object) {
+        try {
+            object.wait();
+        } catch (InterruptedException e) {
+            Log.w(TAG, "unexpected interrupt: " + object);
+        }
+    }
+
+    public static boolean handleInterrruptedException(Throwable e) {
+        // A helper to deal with the interrupt exception
+        // If an interrupt detected, we will setup the bit again.
+        if (e instanceof InterruptedIOException
+                || e instanceof InterruptedException) {
+            Thread.currentThread().interrupt();
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * @return String with special XML characters escaped.
+     */
+    public static String escapeXml(String s) {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0, len = s.length(); i < len; ++i) {
+            char c = s.charAt(i);
+            switch (c) {
+                case '<':  sb.append("&lt;"); break;
+                case '>':  sb.append("&gt;"); break;
+                case '\"': sb.append("&quot;"); break;
+                case '\'': sb.append("&#039;"); break;
+                case '&':  sb.append("&amp;"); break;
+                default: sb.append(c);
+            }
+        }
+        return sb.toString();
+    }
+
+    public static String getUserAgent(Context context) {
+        PackageInfo packageInfo;
+        try {
+            packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
+        } catch (NameNotFoundException e) {
+            throw new IllegalStateException("getPackageInfo failed");
+        }
+        return String.format("%s/%s; %s/%s/%s/%s; %s/%s/%s",
+                packageInfo.packageName,
+                packageInfo.versionName,
+                Build.BRAND,
+                Build.DEVICE,
+                Build.MODEL,
+                Build.ID,
+                Build.VERSION.SDK_INT,
+                Build.VERSION.RELEASE,
+                Build.VERSION.INCREMENTAL);
+    }
+
+    public static String[] copyOf(String[] source, int newSize) {
+        String[] result = new String[newSize];
+        newSize = Math.min(source.length, newSize);
+        System.arraycopy(source, 0, result, 0, newSize);
+        return result;
+    }
+
+    // Mask information for debugging only. It returns <code>info.toString()</code> directly
+    // for debugging build (i.e., 'eng' and 'userdebug') and returns a mask ("****")
+    // in release build to protect the information (e.g. for privacy issue).
+    public static String maskDebugInfo(Object info) {
+        if (info == null) return null;
+        String s = info.toString();
+        int length = Math.min(s.length(), MASK_STRING.length());
+        return IS_DEBUG_BUILD ? s : MASK_STRING.substring(0, length);
+    }
+
+    // This method should be ONLY used for debugging.
+    public static void debug(String message, Object ... args) {
+        Log.v(DEBUG_TAG, String.format(message, args));
+    }
+}
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/exif/ByteBufferInputStream.java b/packages/WallpaperCropper/src/com/android/gallery3d/exif/ByteBufferInputStream.java
new file mode 100644
index 0000000..7fb9f22
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/exif/ByteBufferInputStream.java
@@ -0,0 +1,48 @@
+/*
+ * 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.gallery3d.exif;
+
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+class ByteBufferInputStream extends InputStream {
+
+    private ByteBuffer mBuf;
+
+    public ByteBufferInputStream(ByteBuffer buf) {
+        mBuf = buf;
+    }
+
+    @Override
+    public int read() {
+        if (!mBuf.hasRemaining()) {
+            return -1;
+        }
+        return mBuf.get() & 0xFF;
+    }
+
+    @Override
+    public int read(byte[] bytes, int off, int len) {
+        if (!mBuf.hasRemaining()) {
+            return -1;
+        }
+
+        len = Math.min(len, mBuf.remaining());
+        mBuf.get(bytes, off, len);
+        return len;
+    }
+}
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/exif/CountedDataInputStream.java b/packages/WallpaperCropper/src/com/android/gallery3d/exif/CountedDataInputStream.java
new file mode 100644
index 0000000..dfd4a1a
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/exif/CountedDataInputStream.java
@@ -0,0 +1,136 @@
+/*
+ * 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.gallery3d.exif;
+
+import java.io.EOFException;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+
+class CountedDataInputStream extends FilterInputStream {
+
+    private int mCount = 0;
+
+    // allocate a byte buffer for a long value;
+    private final byte mByteArray[] = new byte[8];
+    private final ByteBuffer mByteBuffer = ByteBuffer.wrap(mByteArray);
+
+    protected CountedDataInputStream(InputStream in) {
+        super(in);
+    }
+
+    public int getReadByteCount() {
+        return mCount;
+    }
+
+    @Override
+    public int read(byte[] b) throws IOException {
+        int r = in.read(b);
+        mCount += (r >= 0) ? r : 0;
+        return r;
+    }
+
+    @Override
+    public int read(byte[] b, int off, int len) throws IOException {
+        int r = in.read(b, off, len);
+        mCount += (r >= 0) ? r : 0;
+        return r;
+    }
+
+    @Override
+    public int read() throws IOException {
+        int r = in.read();
+        mCount += (r >= 0) ? 1 : 0;
+        return r;
+    }
+
+    @Override
+    public long skip(long length) throws IOException {
+        long skip = in.skip(length);
+        mCount += skip;
+        return skip;
+    }
+
+    public void skipOrThrow(long length) throws IOException {
+        if (skip(length) != length) throw new EOFException();
+    }
+
+    public void skipTo(long target) throws IOException {
+        long cur = mCount;
+        long diff = target - cur;
+        assert(diff >= 0);
+        skipOrThrow(diff);
+    }
+
+    public void readOrThrow(byte[] b, int off, int len) throws IOException {
+        int r = read(b, off, len);
+        if (r != len) throw new EOFException();
+    }
+
+    public void readOrThrow(byte[] b) throws IOException {
+        readOrThrow(b, 0, b.length);
+    }
+
+    public void setByteOrder(ByteOrder order) {
+        mByteBuffer.order(order);
+    }
+
+    public ByteOrder getByteOrder() {
+        return mByteBuffer.order();
+    }
+
+    public short readShort() throws IOException {
+        readOrThrow(mByteArray, 0 ,2);
+        mByteBuffer.rewind();
+        return mByteBuffer.getShort();
+    }
+
+    public int readUnsignedShort() throws IOException {
+        return readShort() & 0xffff;
+    }
+
+    public int readInt() throws IOException {
+        readOrThrow(mByteArray, 0 , 4);
+        mByteBuffer.rewind();
+        return mByteBuffer.getInt();
+    }
+
+    public long readUnsignedInt() throws IOException {
+        return readInt() & 0xffffffffL;
+    }
+
+    public long readLong() throws IOException {
+        readOrThrow(mByteArray, 0 , 8);
+        mByteBuffer.rewind();
+        return mByteBuffer.getLong();
+    }
+
+    public String readString(int n) throws IOException {
+        byte buf[] = new byte[n];
+        readOrThrow(buf);
+        return new String(buf, "UTF8");
+    }
+
+    public String readString(int n, Charset charset) throws IOException {
+        byte buf[] = new byte[n];
+        readOrThrow(buf);
+        return new String(buf, charset);
+    }
+}
\ No newline at end of file
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifData.java b/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifData.java
new file mode 100644
index 0000000..8422382
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifData.java
@@ -0,0 +1,348 @@
+/*
+ * 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.gallery3d.exif;
+
+import android.util.Log;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * This class stores the EXIF header in IFDs according to the JPEG
+ * specification. It is the result produced by {@link ExifReader}.
+ *
+ * @see ExifReader
+ * @see IfdData
+ */
+class ExifData {
+    private static final String TAG = "ExifData";
+    private static final byte[] USER_COMMENT_ASCII = {
+            0x41, 0x53, 0x43, 0x49, 0x49, 0x00, 0x00, 0x00
+    };
+    private static final byte[] USER_COMMENT_JIS = {
+            0x4A, 0x49, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00
+    };
+    private static final byte[] USER_COMMENT_UNICODE = {
+            0x55, 0x4E, 0x49, 0x43, 0x4F, 0x44, 0x45, 0x00
+    };
+
+    private final IfdData[] mIfdDatas = new IfdData[IfdId.TYPE_IFD_COUNT];
+    private byte[] mThumbnail;
+    private ArrayList<byte[]> mStripBytes = new ArrayList<byte[]>();
+    private final ByteOrder mByteOrder;
+
+    ExifData(ByteOrder order) {
+        mByteOrder = order;
+    }
+
+    /**
+     * Gets the compressed thumbnail. Returns null if there is no compressed
+     * thumbnail.
+     *
+     * @see #hasCompressedThumbnail()
+     */
+    protected byte[] getCompressedThumbnail() {
+        return mThumbnail;
+    }
+
+    /**
+     * Sets the compressed thumbnail.
+     */
+    protected void setCompressedThumbnail(byte[] thumbnail) {
+        mThumbnail = thumbnail;
+    }
+
+    /**
+     * Returns true it this header contains a compressed thumbnail.
+     */
+    protected boolean hasCompressedThumbnail() {
+        return mThumbnail != null;
+    }
+
+    /**
+     * Adds an uncompressed strip.
+     */
+    protected void setStripBytes(int index, byte[] strip) {
+        if (index < mStripBytes.size()) {
+            mStripBytes.set(index, strip);
+        } else {
+            for (int i = mStripBytes.size(); i < index; i++) {
+                mStripBytes.add(null);
+            }
+            mStripBytes.add(strip);
+        }
+    }
+
+    /**
+     * Gets the strip count.
+     */
+    protected int getStripCount() {
+        return mStripBytes.size();
+    }
+
+    /**
+     * Gets the strip at the specified index.
+     *
+     * @exceptions #IndexOutOfBoundException
+     */
+    protected byte[] getStrip(int index) {
+        return mStripBytes.get(index);
+    }
+
+    /**
+     * Returns true if this header contains uncompressed strip.
+     */
+    protected boolean hasUncompressedStrip() {
+        return mStripBytes.size() != 0;
+    }
+
+    /**
+     * Gets the byte order.
+     */
+    protected ByteOrder getByteOrder() {
+        return mByteOrder;
+    }
+
+    /**
+     * Returns the {@link IfdData} object corresponding to a given IFD if it
+     * exists or null.
+     */
+    protected IfdData getIfdData(int ifdId) {
+        if (ExifTag.isValidIfd(ifdId)) {
+            return mIfdDatas[ifdId];
+        }
+        return null;
+    }
+
+    /**
+     * Adds IFD data. If IFD data of the same type already exists, it will be
+     * replaced by the new data.
+     */
+    protected void addIfdData(IfdData data) {
+        mIfdDatas[data.getId()] = data;
+    }
+
+    /**
+     * Returns the {@link IfdData} object corresponding to a given IFD or
+     * generates one if none exist.
+     */
+    protected IfdData getOrCreateIfdData(int ifdId) {
+        IfdData ifdData = mIfdDatas[ifdId];
+        if (ifdData == null) {
+            ifdData = new IfdData(ifdId);
+            mIfdDatas[ifdId] = ifdData;
+        }
+        return ifdData;
+    }
+
+    /**
+     * Returns the tag with a given TID in the given IFD if the tag exists.
+     * Otherwise returns null.
+     */
+    protected ExifTag getTag(short tag, int ifd) {
+        IfdData ifdData = mIfdDatas[ifd];
+        return (ifdData == null) ? null : ifdData.getTag(tag);
+    }
+
+    /**
+     * Adds the given ExifTag to its default IFD and returns an existing ExifTag
+     * with the same TID or null if none exist.
+     */
+    protected ExifTag addTag(ExifTag tag) {
+        if (tag != null) {
+            int ifd = tag.getIfd();
+            return addTag(tag, ifd);
+        }
+        return null;
+    }
+
+    /**
+     * Adds the given ExifTag to the given IFD and returns an existing ExifTag
+     * with the same TID or null if none exist.
+     */
+    protected ExifTag addTag(ExifTag tag, int ifdId) {
+        if (tag != null && ExifTag.isValidIfd(ifdId)) {
+            IfdData ifdData = getOrCreateIfdData(ifdId);
+            return ifdData.setTag(tag);
+        }
+        return null;
+    }
+
+    protected void clearThumbnailAndStrips() {
+        mThumbnail = null;
+        mStripBytes.clear();
+    }
+
+    /**
+     * Removes the thumbnail and its related tags. IFD1 will be removed.
+     */
+    protected void removeThumbnailData() {
+        clearThumbnailAndStrips();
+        mIfdDatas[IfdId.TYPE_IFD_1] = null;
+    }
+
+    /**
+     * Removes the tag with a given TID and IFD.
+     */
+    protected void removeTag(short tagId, int ifdId) {
+        IfdData ifdData = mIfdDatas[ifdId];
+        if (ifdData == null) {
+            return;
+        }
+        ifdData.removeTag(tagId);
+    }
+
+    /**
+     * Decodes the user comment tag into string as specified in the EXIF
+     * standard. Returns null if decoding failed.
+     */
+    protected String getUserComment() {
+        IfdData ifdData = mIfdDatas[IfdId.TYPE_IFD_0];
+        if (ifdData == null) {
+            return null;
+        }
+        ExifTag tag = ifdData.getTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_USER_COMMENT));
+        if (tag == null) {
+            return null;
+        }
+        if (tag.getComponentCount() < 8) {
+            return null;
+        }
+
+        byte[] buf = new byte[tag.getComponentCount()];
+        tag.getBytes(buf);
+
+        byte[] code = new byte[8];
+        System.arraycopy(buf, 0, code, 0, 8);
+
+        try {
+            if (Arrays.equals(code, USER_COMMENT_ASCII)) {
+                return new String(buf, 8, buf.length - 8, "US-ASCII");
+            } else if (Arrays.equals(code, USER_COMMENT_JIS)) {
+                return new String(buf, 8, buf.length - 8, "EUC-JP");
+            } else if (Arrays.equals(code, USER_COMMENT_UNICODE)) {
+                return new String(buf, 8, buf.length - 8, "UTF-16");
+            } else {
+                return null;
+            }
+        } catch (UnsupportedEncodingException e) {
+            Log.w(TAG, "Failed to decode the user comment");
+            return null;
+        }
+    }
+
+    /**
+     * Returns a list of all {@link ExifTag}s in the ExifData or null if there
+     * are none.
+     */
+    protected List<ExifTag> getAllTags() {
+        ArrayList<ExifTag> ret = new ArrayList<ExifTag>();
+        for (IfdData d : mIfdDatas) {
+            if (d != null) {
+                ExifTag[] tags = d.getAllTags();
+                if (tags != null) {
+                    for (ExifTag t : tags) {
+                        ret.add(t);
+                    }
+                }
+            }
+        }
+        if (ret.size() == 0) {
+            return null;
+        }
+        return ret;
+    }
+
+    /**
+     * Returns a list of all {@link ExifTag}s in a given IFD or null if there
+     * are none.
+     */
+    protected List<ExifTag> getAllTagsForIfd(int ifd) {
+        IfdData d = mIfdDatas[ifd];
+        if (d == null) {
+            return null;
+        }
+        ExifTag[] tags = d.getAllTags();
+        if (tags == null) {
+            return null;
+        }
+        ArrayList<ExifTag> ret = new ArrayList<ExifTag>(tags.length);
+        for (ExifTag t : tags) {
+            ret.add(t);
+        }
+        if (ret.size() == 0) {
+            return null;
+        }
+        return ret;
+    }
+
+    /**
+     * Returns a list of all {@link ExifTag}s with a given TID or null if there
+     * are none.
+     */
+    protected List<ExifTag> getAllTagsForTagId(short tag) {
+        ArrayList<ExifTag> ret = new ArrayList<ExifTag>();
+        for (IfdData d : mIfdDatas) {
+            if (d != null) {
+                ExifTag t = d.getTag(tag);
+                if (t != null) {
+                    ret.add(t);
+                }
+            }
+        }
+        if (ret.size() == 0) {
+            return null;
+        }
+        return ret;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (obj instanceof ExifData) {
+            ExifData data = (ExifData) obj;
+            if (data.mByteOrder != mByteOrder ||
+                    data.mStripBytes.size() != mStripBytes.size() ||
+                    !Arrays.equals(data.mThumbnail, mThumbnail)) {
+                return false;
+            }
+            for (int i = 0; i < mStripBytes.size(); i++) {
+                if (!Arrays.equals(data.mStripBytes.get(i), mStripBytes.get(i))) {
+                    return false;
+                }
+            }
+            for (int i = 0; i < IfdId.TYPE_IFD_COUNT; i++) {
+                IfdData ifd1 = data.getIfdData(i);
+                IfdData ifd2 = getIfdData(i);
+                if (ifd1 != ifd2 && ifd1 != null && !ifd1.equals(ifd2)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+}
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifInterface.java b/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifInterface.java
new file mode 100644
index 0000000..a1cf0fc
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifInterface.java
@@ -0,0 +1,2407 @@
+/*
+ * 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.gallery3d.exif;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.util.SparseIntArray;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.channels.FileChannel.MapMode;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.TimeZone;
+
+/**
+ * This class provides methods and constants for reading and writing jpeg file
+ * metadata. It contains a collection of ExifTags, and a collection of
+ * definitions for creating valid ExifTags. The collection of ExifTags can be
+ * updated by: reading new ones from a file, deleting or adding existing ones,
+ * or building new ExifTags from a tag definition. These ExifTags can be written
+ * to a valid jpeg image as exif metadata.
+ * <p>
+ * Each ExifTag has a tag ID (TID) and is stored in a specific image file
+ * directory (IFD) as specified by the exif standard. A tag definition can be
+ * looked up with a constant that is a combination of TID and IFD. This
+ * definition has information about the type, number of components, and valid
+ * IFDs for a tag.
+ *
+ * @see ExifTag
+ */
+public class ExifInterface {
+    public static final int TAG_NULL = -1;
+    public static final int IFD_NULL = -1;
+    public static final int DEFINITION_NULL = 0;
+
+    /**
+     * Tag constants for Jeita EXIF 2.2
+     */
+
+    // IFD 0
+    public static final int TAG_IMAGE_WIDTH =
+        defineTag(IfdId.TYPE_IFD_0, (short) 0x0100);
+    public static final int TAG_IMAGE_LENGTH =
+        defineTag(IfdId.TYPE_IFD_0, (short) 0x0101); // Image height
+    public static final int TAG_BITS_PER_SAMPLE =
+        defineTag(IfdId.TYPE_IFD_0, (short) 0x0102);
+    public static final int TAG_COMPRESSION =
+        defineTag(IfdId.TYPE_IFD_0, (short) 0x0103);
+    public static final int TAG_PHOTOMETRIC_INTERPRETATION =
+        defineTag(IfdId.TYPE_IFD_0, (short) 0x0106);
+    public static final int TAG_IMAGE_DESCRIPTION =
+        defineTag(IfdId.TYPE_IFD_0, (short) 0x010E);
+    public static final int TAG_MAKE =
+        defineTag(IfdId.TYPE_IFD_0, (short) 0x010F);
+    public static final int TAG_MODEL =
+        defineTag(IfdId.TYPE_IFD_0, (short) 0x0110);
+    public static final int TAG_STRIP_OFFSETS =
+        defineTag(IfdId.TYPE_IFD_0, (short) 0x0111);
+    public static final int TAG_ORIENTATION =
+        defineTag(IfdId.TYPE_IFD_0, (short) 0x0112);
+    public static final int TAG_SAMPLES_PER_PIXEL =
+        defineTag(IfdId.TYPE_IFD_0, (short) 0x0115);
+    public static final int TAG_ROWS_PER_STRIP =
+        defineTag(IfdId.TYPE_IFD_0, (short) 0x0116);
+    public static final int TAG_STRIP_BYTE_COUNTS =
+        defineTag(IfdId.TYPE_IFD_0, (short) 0x0117);
+    public static final int TAG_X_RESOLUTION =
+        defineTag(IfdId.TYPE_IFD_0, (short) 0x011A);
+    public static final int TAG_Y_RESOLUTION =
+        defineTag(IfdId.TYPE_IFD_0, (short) 0x011B);
+    public static final int TAG_PLANAR_CONFIGURATION =
+        defineTag(IfdId.TYPE_IFD_0, (short) 0x011C);
+    public static final int TAG_RESOLUTION_UNIT =
+        defineTag(IfdId.TYPE_IFD_0, (short) 0x0128);
+    public static final int TAG_TRANSFER_FUNCTION =
+        defineTag(IfdId.TYPE_IFD_0, (short) 0x012D);
+    public static final int TAG_SOFTWARE =
+        defineTag(IfdId.TYPE_IFD_0, (short) 0x0131);
+    public static final int TAG_DATE_TIME =
+        defineTag(IfdId.TYPE_IFD_0, (short) 0x0132);
+    public static final int TAG_ARTIST =
+        defineTag(IfdId.TYPE_IFD_0, (short) 0x013B);
+    public static final int TAG_WHITE_POINT =
+        defineTag(IfdId.TYPE_IFD_0, (short) 0x013E);
+    public static final int TAG_PRIMARY_CHROMATICITIES =
+        defineTag(IfdId.TYPE_IFD_0, (short) 0x013F);
+    public static final int TAG_Y_CB_CR_COEFFICIENTS =
+        defineTag(IfdId.TYPE_IFD_0, (short) 0x0211);
+    public static final int TAG_Y_CB_CR_SUB_SAMPLING =
+        defineTag(IfdId.TYPE_IFD_0, (short) 0x0212);
+    public static final int TAG_Y_CB_CR_POSITIONING =
+        defineTag(IfdId.TYPE_IFD_0, (short) 0x0213);
+    public static final int TAG_REFERENCE_BLACK_WHITE =
+        defineTag(IfdId.TYPE_IFD_0, (short) 0x0214);
+    public static final int TAG_COPYRIGHT =
+        defineTag(IfdId.TYPE_IFD_0, (short) 0x8298);
+    public static final int TAG_EXIF_IFD =
+        defineTag(IfdId.TYPE_IFD_0, (short) 0x8769);
+    public static final int TAG_GPS_IFD =
+        defineTag(IfdId.TYPE_IFD_0, (short) 0x8825);
+    // IFD 1
+    public static final int TAG_JPEG_INTERCHANGE_FORMAT =
+        defineTag(IfdId.TYPE_IFD_1, (short) 0x0201);
+    public static final int TAG_JPEG_INTERCHANGE_FORMAT_LENGTH =
+        defineTag(IfdId.TYPE_IFD_1, (short) 0x0202);
+    // IFD Exif Tags
+    public static final int TAG_EXPOSURE_TIME =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x829A);
+    public static final int TAG_F_NUMBER =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x829D);
+    public static final int TAG_EXPOSURE_PROGRAM =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x8822);
+    public static final int TAG_SPECTRAL_SENSITIVITY =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x8824);
+    public static final int TAG_ISO_SPEED_RATINGS =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x8827);
+    public static final int TAG_OECF =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x8828);
+    public static final int TAG_EXIF_VERSION =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9000);
+    public static final int TAG_DATE_TIME_ORIGINAL =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9003);
+    public static final int TAG_DATE_TIME_DIGITIZED =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9004);
+    public static final int TAG_COMPONENTS_CONFIGURATION =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9101);
+    public static final int TAG_COMPRESSED_BITS_PER_PIXEL =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9102);
+    public static final int TAG_SHUTTER_SPEED_VALUE =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9201);
+    public static final int TAG_APERTURE_VALUE =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9202);
+    public static final int TAG_BRIGHTNESS_VALUE =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9203);
+    public static final int TAG_EXPOSURE_BIAS_VALUE =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9204);
+    public static final int TAG_MAX_APERTURE_VALUE =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9205);
+    public static final int TAG_SUBJECT_DISTANCE =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9206);
+    public static final int TAG_METERING_MODE =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9207);
+    public static final int TAG_LIGHT_SOURCE =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9208);
+    public static final int TAG_FLASH =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9209);
+    public static final int TAG_FOCAL_LENGTH =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x920A);
+    public static final int TAG_SUBJECT_AREA =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9214);
+    public static final int TAG_MAKER_NOTE =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x927C);
+    public static final int TAG_USER_COMMENT =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9286);
+    public static final int TAG_SUB_SEC_TIME =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9290);
+    public static final int TAG_SUB_SEC_TIME_ORIGINAL =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9291);
+    public static final int TAG_SUB_SEC_TIME_DIGITIZED =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0x9292);
+    public static final int TAG_FLASHPIX_VERSION =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA000);
+    public static final int TAG_COLOR_SPACE =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA001);
+    public static final int TAG_PIXEL_X_DIMENSION =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA002);
+    public static final int TAG_PIXEL_Y_DIMENSION =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA003);
+    public static final int TAG_RELATED_SOUND_FILE =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA004);
+    public static final int TAG_INTEROPERABILITY_IFD =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA005);
+    public static final int TAG_FLASH_ENERGY =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA20B);
+    public static final int TAG_SPATIAL_FREQUENCY_RESPONSE =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA20C);
+    public static final int TAG_FOCAL_PLANE_X_RESOLUTION =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA20E);
+    public static final int TAG_FOCAL_PLANE_Y_RESOLUTION =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA20F);
+    public static final int TAG_FOCAL_PLANE_RESOLUTION_UNIT =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA210);
+    public static final int TAG_SUBJECT_LOCATION =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA214);
+    public static final int TAG_EXPOSURE_INDEX =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA215);
+    public static final int TAG_SENSING_METHOD =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA217);
+    public static final int TAG_FILE_SOURCE =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA300);
+    public static final int TAG_SCENE_TYPE =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA301);
+    public static final int TAG_CFA_PATTERN =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA302);
+    public static final int TAG_CUSTOM_RENDERED =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA401);
+    public static final int TAG_EXPOSURE_MODE =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA402);
+    public static final int TAG_WHITE_BALANCE =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA403);
+    public static final int TAG_DIGITAL_ZOOM_RATIO =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA404);
+    public static final int TAG_FOCAL_LENGTH_IN_35_MM_FILE =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA405);
+    public static final int TAG_SCENE_CAPTURE_TYPE =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA406);
+    public static final int TAG_GAIN_CONTROL =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA407);
+    public static final int TAG_CONTRAST =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA408);
+    public static final int TAG_SATURATION =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA409);
+    public static final int TAG_SHARPNESS =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA40A);
+    public static final int TAG_DEVICE_SETTING_DESCRIPTION =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA40B);
+    public static final int TAG_SUBJECT_DISTANCE_RANGE =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA40C);
+    public static final int TAG_IMAGE_UNIQUE_ID =
+        defineTag(IfdId.TYPE_IFD_EXIF, (short) 0xA420);
+    // IFD GPS tags
+    public static final int TAG_GPS_VERSION_ID =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 0);
+    public static final int TAG_GPS_LATITUDE_REF =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 1);
+    public static final int TAG_GPS_LATITUDE =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 2);
+    public static final int TAG_GPS_LONGITUDE_REF =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 3);
+    public static final int TAG_GPS_LONGITUDE =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 4);
+    public static final int TAG_GPS_ALTITUDE_REF =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 5);
+    public static final int TAG_GPS_ALTITUDE =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 6);
+    public static final int TAG_GPS_TIME_STAMP =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 7);
+    public static final int TAG_GPS_SATTELLITES =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 8);
+    public static final int TAG_GPS_STATUS =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 9);
+    public static final int TAG_GPS_MEASURE_MODE =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 10);
+    public static final int TAG_GPS_DOP =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 11);
+    public static final int TAG_GPS_SPEED_REF =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 12);
+    public static final int TAG_GPS_SPEED =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 13);
+    public static final int TAG_GPS_TRACK_REF =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 14);
+    public static final int TAG_GPS_TRACK =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 15);
+    public static final int TAG_GPS_IMG_DIRECTION_REF =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 16);
+    public static final int TAG_GPS_IMG_DIRECTION =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 17);
+    public static final int TAG_GPS_MAP_DATUM =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 18);
+    public static final int TAG_GPS_DEST_LATITUDE_REF =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 19);
+    public static final int TAG_GPS_DEST_LATITUDE =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 20);
+    public static final int TAG_GPS_DEST_LONGITUDE_REF =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 21);
+    public static final int TAG_GPS_DEST_LONGITUDE =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 22);
+    public static final int TAG_GPS_DEST_BEARING_REF =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 23);
+    public static final int TAG_GPS_DEST_BEARING =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 24);
+    public static final int TAG_GPS_DEST_DISTANCE_REF =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 25);
+    public static final int TAG_GPS_DEST_DISTANCE =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 26);
+    public static final int TAG_GPS_PROCESSING_METHOD =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 27);
+    public static final int TAG_GPS_AREA_INFORMATION =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 28);
+    public static final int TAG_GPS_DATE_STAMP =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 29);
+    public static final int TAG_GPS_DIFFERENTIAL =
+        defineTag(IfdId.TYPE_IFD_GPS, (short) 30);
+    // IFD Interoperability tags
+    public static final int TAG_INTEROPERABILITY_INDEX =
+        defineTag(IfdId.TYPE_IFD_INTEROPERABILITY, (short) 1);
+
+    /**
+     * Tags that contain offset markers. These are included in the banned
+     * defines.
+     */
+    private static HashSet<Short> sOffsetTags = new HashSet<Short>();
+    static {
+        sOffsetTags.add(getTrueTagKey(TAG_GPS_IFD));
+        sOffsetTags.add(getTrueTagKey(TAG_EXIF_IFD));
+        sOffsetTags.add(getTrueTagKey(TAG_JPEG_INTERCHANGE_FORMAT));
+        sOffsetTags.add(getTrueTagKey(TAG_INTEROPERABILITY_IFD));
+        sOffsetTags.add(getTrueTagKey(TAG_STRIP_OFFSETS));
+    }
+
+    /**
+     * Tags with definitions that cannot be overridden (banned defines).
+     */
+    protected static HashSet<Short> sBannedDefines = new HashSet<Short>(sOffsetTags);
+    static {
+        sBannedDefines.add(getTrueTagKey(TAG_NULL));
+        sBannedDefines.add(getTrueTagKey(TAG_JPEG_INTERCHANGE_FORMAT_LENGTH));
+        sBannedDefines.add(getTrueTagKey(TAG_STRIP_BYTE_COUNTS));
+    }
+
+    /**
+     * Returns the constant representing a tag with a given TID and default IFD.
+     */
+    public static int defineTag(int ifdId, short tagId) {
+        return (tagId & 0x0000ffff) | (ifdId << 16);
+    }
+
+    /**
+     * Returns the TID for a tag constant.
+     */
+    public static short getTrueTagKey(int tag) {
+        // Truncate
+        return (short) tag;
+    }
+
+    /**
+     * Returns the default IFD for a tag constant.
+     */
+    public static int getTrueIfd(int tag) {
+        return tag >>> 16;
+    }
+
+    /**
+     * Constants for {@link TAG_ORIENTATION}. They can be interpreted as
+     * follows:
+     * <ul>
+     * <li>TOP_LEFT is the normal orientation.</li>
+     * <li>TOP_RIGHT is a left-right mirror.</li>
+     * <li>BOTTOM_LEFT is a 180 degree rotation.</li>
+     * <li>BOTTOM_RIGHT is a top-bottom mirror.</li>
+     * <li>LEFT_TOP is mirrored about the top-left<->bottom-right axis.</li>
+     * <li>RIGHT_TOP is a 90 degree clockwise rotation.</li>
+     * <li>LEFT_BOTTOM is mirrored about the top-right<->bottom-left axis.</li>
+     * <li>RIGHT_BOTTOM is a 270 degree clockwise rotation.</li>
+     * </ul>
+     */
+    public static interface Orientation {
+        public static final short TOP_LEFT = 1;
+        public static final short TOP_RIGHT = 2;
+        public static final short BOTTOM_LEFT = 3;
+        public static final short BOTTOM_RIGHT = 4;
+        public static final short LEFT_TOP = 5;
+        public static final short RIGHT_TOP = 6;
+        public static final short LEFT_BOTTOM = 7;
+        public static final short RIGHT_BOTTOM = 8;
+    }
+
+    /**
+     * Constants for {@link TAG_Y_CB_CR_POSITIONING}
+     */
+    public static interface YCbCrPositioning {
+        public static final short CENTERED = 1;
+        public static final short CO_SITED = 2;
+    }
+
+    /**
+     * Constants for {@link TAG_COMPRESSION}
+     */
+    public static interface Compression {
+        public static final short UNCOMPRESSION = 1;
+        public static final short JPEG = 6;
+    }
+
+    /**
+     * Constants for {@link TAG_RESOLUTION_UNIT}
+     */
+    public static interface ResolutionUnit {
+        public static final short INCHES = 2;
+        public static final short CENTIMETERS = 3;
+    }
+
+    /**
+     * Constants for {@link TAG_PHOTOMETRIC_INTERPRETATION}
+     */
+    public static interface PhotometricInterpretation {
+        public static final short RGB = 2;
+        public static final short YCBCR = 6;
+    }
+
+    /**
+     * Constants for {@link TAG_PLANAR_CONFIGURATION}
+     */
+    public static interface PlanarConfiguration {
+        public static final short CHUNKY = 1;
+        public static final short PLANAR = 2;
+    }
+
+    /**
+     * Constants for {@link TAG_EXPOSURE_PROGRAM}
+     */
+    public static interface ExposureProgram {
+        public static final short NOT_DEFINED = 0;
+        public static final short MANUAL = 1;
+        public static final short NORMAL_PROGRAM = 2;
+        public static final short APERTURE_PRIORITY = 3;
+        public static final short SHUTTER_PRIORITY = 4;
+        public static final short CREATIVE_PROGRAM = 5;
+        public static final short ACTION_PROGRAM = 6;
+        public static final short PROTRAIT_MODE = 7;
+        public static final short LANDSCAPE_MODE = 8;
+    }
+
+    /**
+     * Constants for {@link TAG_METERING_MODE}
+     */
+    public static interface MeteringMode {
+        public static final short UNKNOWN = 0;
+        public static final short AVERAGE = 1;
+        public static final short CENTER_WEIGHTED_AVERAGE = 2;
+        public static final short SPOT = 3;
+        public static final short MULTISPOT = 4;
+        public static final short PATTERN = 5;
+        public static final short PARTAIL = 6;
+        public static final short OTHER = 255;
+    }
+
+    /**
+     * Constants for {@link TAG_FLASH} As the definition in Jeita EXIF 2.2
+     * standard, we can treat this constant as bitwise flag.
+     * <p>
+     * e.g.
+     * <p>
+     * short flash = FIRED | RETURN_STROBE_RETURN_LIGHT_DETECTED |
+     * MODE_AUTO_MODE
+     */
+    public static interface Flash {
+        // LSB
+        public static final short DID_NOT_FIRED = 0;
+        public static final short FIRED = 1;
+        // 1st~2nd bits
+        public static final short RETURN_NO_STROBE_RETURN_DETECTION_FUNCTION = 0 << 1;
+        public static final short RETURN_STROBE_RETURN_LIGHT_NOT_DETECTED = 2 << 1;
+        public static final short RETURN_STROBE_RETURN_LIGHT_DETECTED = 3 << 1;
+        // 3rd~4th bits
+        public static final short MODE_UNKNOWN = 0 << 3;
+        public static final short MODE_COMPULSORY_FLASH_FIRING = 1 << 3;
+        public static final short MODE_COMPULSORY_FLASH_SUPPRESSION = 2 << 3;
+        public static final short MODE_AUTO_MODE = 3 << 3;
+        // 5th bit
+        public static final short FUNCTION_PRESENT = 0 << 5;
+        public static final short FUNCTION_NO_FUNCTION = 1 << 5;
+        // 6th bit
+        public static final short RED_EYE_REDUCTION_NO_OR_UNKNOWN = 0 << 6;
+        public static final short RED_EYE_REDUCTION_SUPPORT = 1 << 6;
+    }
+
+    /**
+     * Constants for {@link TAG_COLOR_SPACE}
+     */
+    public static interface ColorSpace {
+        public static final short SRGB = 1;
+        public static final short UNCALIBRATED = (short) 0xFFFF;
+    }
+
+    /**
+     * Constants for {@link TAG_EXPOSURE_MODE}
+     */
+    public static interface ExposureMode {
+        public static final short AUTO_EXPOSURE = 0;
+        public static final short MANUAL_EXPOSURE = 1;
+        public static final short AUTO_BRACKET = 2;
+    }
+
+    /**
+     * Constants for {@link TAG_WHITE_BALANCE}
+     */
+    public static interface WhiteBalance {
+        public static final short AUTO = 0;
+        public static final short MANUAL = 1;
+    }
+
+    /**
+     * Constants for {@link TAG_SCENE_CAPTURE_TYPE}
+     */
+    public static interface SceneCapture {
+        public static final short STANDARD = 0;
+        public static final short LANDSCAPE = 1;
+        public static final short PROTRAIT = 2;
+        public static final short NIGHT_SCENE = 3;
+    }
+
+    /**
+     * Constants for {@link TAG_COMPONENTS_CONFIGURATION}
+     */
+    public static interface ComponentsConfiguration {
+        public static final short NOT_EXIST = 0;
+        public static final short Y = 1;
+        public static final short CB = 2;
+        public static final short CR = 3;
+        public static final short R = 4;
+        public static final short G = 5;
+        public static final short B = 6;
+    }
+
+    /**
+     * Constants for {@link TAG_LIGHT_SOURCE}
+     */
+    public static interface LightSource {
+        public static final short UNKNOWN = 0;
+        public static final short DAYLIGHT = 1;
+        public static final short FLUORESCENT = 2;
+        public static final short TUNGSTEN = 3;
+        public static final short FLASH = 4;
+        public static final short FINE_WEATHER = 9;
+        public static final short CLOUDY_WEATHER = 10;
+        public static final short SHADE = 11;
+        public static final short DAYLIGHT_FLUORESCENT = 12;
+        public static final short DAY_WHITE_FLUORESCENT = 13;
+        public static final short COOL_WHITE_FLUORESCENT = 14;
+        public static final short WHITE_FLUORESCENT = 15;
+        public static final short STANDARD_LIGHT_A = 17;
+        public static final short STANDARD_LIGHT_B = 18;
+        public static final short STANDARD_LIGHT_C = 19;
+        public static final short D55 = 20;
+        public static final short D65 = 21;
+        public static final short D75 = 22;
+        public static final short D50 = 23;
+        public static final short ISO_STUDIO_TUNGSTEN = 24;
+        public static final short OTHER = 255;
+    }
+
+    /**
+     * Constants for {@link TAG_SENSING_METHOD}
+     */
+    public static interface SensingMethod {
+        public static final short NOT_DEFINED = 1;
+        public static final short ONE_CHIP_COLOR = 2;
+        public static final short TWO_CHIP_COLOR = 3;
+        public static final short THREE_CHIP_COLOR = 4;
+        public static final short COLOR_SEQUENTIAL_AREA = 5;
+        public static final short TRILINEAR = 7;
+        public static final short COLOR_SEQUENTIAL_LINEAR = 8;
+    }
+
+    /**
+     * Constants for {@link TAG_FILE_SOURCE}
+     */
+    public static interface FileSource {
+        public static final short DSC = 3;
+    }
+
+    /**
+     * Constants for {@link TAG_SCENE_TYPE}
+     */
+    public static interface SceneType {
+        public static final short DIRECT_PHOTOGRAPHED = 1;
+    }
+
+    /**
+     * Constants for {@link TAG_GAIN_CONTROL}
+     */
+    public static interface GainControl {
+        public static final short NONE = 0;
+        public static final short LOW_UP = 1;
+        public static final short HIGH_UP = 2;
+        public static final short LOW_DOWN = 3;
+        public static final short HIGH_DOWN = 4;
+    }
+
+    /**
+     * Constants for {@link TAG_CONTRAST}
+     */
+    public static interface Contrast {
+        public static final short NORMAL = 0;
+        public static final short SOFT = 1;
+        public static final short HARD = 2;
+    }
+
+    /**
+     * Constants for {@link TAG_SATURATION}
+     */
+    public static interface Saturation {
+        public static final short NORMAL = 0;
+        public static final short LOW = 1;
+        public static final short HIGH = 2;
+    }
+
+    /**
+     * Constants for {@link TAG_SHARPNESS}
+     */
+    public static interface Sharpness {
+        public static final short NORMAL = 0;
+        public static final short SOFT = 1;
+        public static final short HARD = 2;
+    }
+
+    /**
+     * Constants for {@link TAG_SUBJECT_DISTANCE}
+     */
+    public static interface SubjectDistance {
+        public static final short UNKNOWN = 0;
+        public static final short MACRO = 1;
+        public static final short CLOSE_VIEW = 2;
+        public static final short DISTANT_VIEW = 3;
+    }
+
+    /**
+     * Constants for {@link TAG_GPS_LATITUDE_REF},
+     * {@link TAG_GPS_DEST_LATITUDE_REF}
+     */
+    public static interface GpsLatitudeRef {
+        public static final String NORTH = "N";
+        public static final String SOUTH = "S";
+    }
+
+    /**
+     * Constants for {@link TAG_GPS_LONGITUDE_REF},
+     * {@link TAG_GPS_DEST_LONGITUDE_REF}
+     */
+    public static interface GpsLongitudeRef {
+        public static final String EAST = "E";
+        public static final String WEST = "W";
+    }
+
+    /**
+     * Constants for {@link TAG_GPS_ALTITUDE_REF}
+     */
+    public static interface GpsAltitudeRef {
+        public static final short SEA_LEVEL = 0;
+        public static final short SEA_LEVEL_NEGATIVE = 1;
+    }
+
+    /**
+     * Constants for {@link TAG_GPS_STATUS}
+     */
+    public static interface GpsStatus {
+        public static final String IN_PROGRESS = "A";
+        public static final String INTEROPERABILITY = "V";
+    }
+
+    /**
+     * Constants for {@link TAG_GPS_MEASURE_MODE}
+     */
+    public static interface GpsMeasureMode {
+        public static final String MODE_2_DIMENSIONAL = "2";
+        public static final String MODE_3_DIMENSIONAL = "3";
+    }
+
+    /**
+     * Constants for {@link TAG_GPS_SPEED_REF},
+     * {@link TAG_GPS_DEST_DISTANCE_REF}
+     */
+    public static interface GpsSpeedRef {
+        public static final String KILOMETERS = "K";
+        public static final String MILES = "M";
+        public static final String KNOTS = "N";
+    }
+
+    /**
+     * Constants for {@link TAG_GPS_TRACK_REF},
+     * {@link TAG_GPS_IMG_DIRECTION_REF}, {@link TAG_GPS_DEST_BEARING_REF}
+     */
+    public static interface GpsTrackRef {
+        public static final String TRUE_DIRECTION = "T";
+        public static final String MAGNETIC_DIRECTION = "M";
+    }
+
+    /**
+     * Constants for {@link TAG_GPS_DIFFERENTIAL}
+     */
+    public static interface GpsDifferential {
+        public static final short WITHOUT_DIFFERENTIAL_CORRECTION = 0;
+        public static final short DIFFERENTIAL_CORRECTION_APPLIED = 1;
+    }
+
+    private static final String NULL_ARGUMENT_STRING = "Argument is null";
+    private ExifData mData = new ExifData(DEFAULT_BYTE_ORDER);
+    public static final ByteOrder DEFAULT_BYTE_ORDER = ByteOrder.BIG_ENDIAN;
+
+    public ExifInterface() {
+        mGPSDateStampFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
+    }
+
+    /**
+     * Reads the exif tags from a byte array, clearing this ExifInterface
+     * object's existing exif tags.
+     *
+     * @param jpeg a byte array containing a jpeg compressed image.
+     * @throws IOException
+     */
+    public void readExif(byte[] jpeg) throws IOException {
+        readExif(new ByteArrayInputStream(jpeg));
+    }
+
+    /**
+     * Reads the exif tags from an InputStream, clearing this ExifInterface
+     * object's existing exif tags.
+     *
+     * @param inStream an InputStream containing a jpeg compressed image.
+     * @throws IOException
+     */
+    public void readExif(InputStream inStream) throws IOException {
+        if (inStream == null) {
+            throw new IllegalArgumentException(NULL_ARGUMENT_STRING);
+        }
+        ExifData d = null;
+        try {
+            d = new ExifReader(this).read(inStream);
+        } catch (ExifInvalidFormatException e) {
+            throw new IOException("Invalid exif format : " + e);
+        }
+        mData = d;
+    }
+
+    /**
+     * Reads the exif tags from a file, clearing this ExifInterface object's
+     * existing exif tags.
+     *
+     * @param inFileName a string representing the filepath to jpeg file.
+     * @throws FileNotFoundException
+     * @throws IOException
+     */
+    public void readExif(String inFileName) throws FileNotFoundException, IOException {
+        if (inFileName == null) {
+            throw new IllegalArgumentException(NULL_ARGUMENT_STRING);
+        }
+        InputStream is = null;
+        try {
+            is = (InputStream) new BufferedInputStream(new FileInputStream(inFileName));
+            readExif(is);
+        } catch (IOException e) {
+            closeSilently(is);
+            throw e;
+        }
+        is.close();
+    }
+
+    /**
+     * Sets the exif tags, clearing this ExifInterface object's existing exif
+     * tags.
+     *
+     * @param tags a collection of exif tags to set.
+     */
+    public void setExif(Collection<ExifTag> tags) {
+        clearExif();
+        setTags(tags);
+    }
+
+    /**
+     * Clears this ExifInterface object's existing exif tags.
+     */
+    public void clearExif() {
+        mData = new ExifData(DEFAULT_BYTE_ORDER);
+    }
+
+    /**
+     * Writes the tags from this ExifInterface object into a jpeg image,
+     * removing prior exif tags.
+     *
+     * @param jpeg a byte array containing a jpeg compressed image.
+     * @param exifOutStream an OutputStream to which the jpeg image with added
+     *            exif tags will be written.
+     * @throws IOException
+     */
+    public void writeExif(byte[] jpeg, OutputStream exifOutStream) throws IOException {
+        if (jpeg == null || exifOutStream == null) {
+            throw new IllegalArgumentException(NULL_ARGUMENT_STRING);
+        }
+        OutputStream s = getExifWriterStream(exifOutStream);
+        s.write(jpeg, 0, jpeg.length);
+        s.flush();
+    }
+
+    /**
+     * Writes the tags from this ExifInterface object into a jpeg compressed
+     * bitmap, removing prior exif tags.
+     *
+     * @param bmap a bitmap to compress and write exif into.
+     * @param exifOutStream the OutputStream to which the jpeg image with added
+     *            exif tags will be written.
+     * @throws IOException
+     */
+    public void writeExif(Bitmap bmap, OutputStream exifOutStream) throws IOException {
+        if (bmap == null || exifOutStream == null) {
+            throw new IllegalArgumentException(NULL_ARGUMENT_STRING);
+        }
+        OutputStream s = getExifWriterStream(exifOutStream);
+        bmap.compress(Bitmap.CompressFormat.JPEG, 90, s);
+        s.flush();
+    }
+
+    /**
+     * Writes the tags from this ExifInterface object into a jpeg stream,
+     * removing prior exif tags.
+     *
+     * @param jpegStream an InputStream containing a jpeg compressed image.
+     * @param exifOutStream an OutputStream to which the jpeg image with added
+     *            exif tags will be written.
+     * @throws IOException
+     */
+    public void writeExif(InputStream jpegStream, OutputStream exifOutStream) throws IOException {
+        if (jpegStream == null || exifOutStream == null) {
+            throw new IllegalArgumentException(NULL_ARGUMENT_STRING);
+        }
+        OutputStream s = getExifWriterStream(exifOutStream);
+        doExifStreamIO(jpegStream, s);
+        s.flush();
+    }
+
+    /**
+     * Writes the tags from this ExifInterface object into a jpeg image,
+     * removing prior exif tags.
+     *
+     * @param jpeg a byte array containing a jpeg compressed image.
+     * @param exifOutFileName a String containing the filepath to which the jpeg
+     *            image with added exif tags will be written.
+     * @throws FileNotFoundException
+     * @throws IOException
+     */
+    public void writeExif(byte[] jpeg, String exifOutFileName) throws FileNotFoundException,
+            IOException {
+        if (jpeg == null || exifOutFileName == null) {
+            throw new IllegalArgumentException(NULL_ARGUMENT_STRING);
+        }
+        OutputStream s = null;
+        try {
+            s = getExifWriterStream(exifOutFileName);
+            s.write(jpeg, 0, jpeg.length);
+            s.flush();
+        } catch (IOException e) {
+            closeSilently(s);
+            throw e;
+        }
+        s.close();
+    }
+
+    /**
+     * Writes the tags from this ExifInterface object into a jpeg compressed
+     * bitmap, removing prior exif tags.
+     *
+     * @param bmap a bitmap to compress and write exif into.
+     * @param exifOutFileName a String containing the filepath to which the jpeg
+     *            image with added exif tags will be written.
+     * @throws FileNotFoundException
+     * @throws IOException
+     */
+    public void writeExif(Bitmap bmap, String exifOutFileName) throws FileNotFoundException,
+            IOException {
+        if (bmap == null || exifOutFileName == null) {
+            throw new IllegalArgumentException(NULL_ARGUMENT_STRING);
+        }
+        OutputStream s = null;
+        try {
+            s = getExifWriterStream(exifOutFileName);
+            bmap.compress(Bitmap.CompressFormat.JPEG, 90, s);
+            s.flush();
+        } catch (IOException e) {
+            closeSilently(s);
+            throw e;
+        }
+        s.close();
+    }
+
+    /**
+     * Writes the tags from this ExifInterface object into a jpeg stream,
+     * removing prior exif tags.
+     *
+     * @param jpegStream an InputStream containing a jpeg compressed image.
+     * @param exifOutFileName a String containing the filepath to which the jpeg
+     *            image with added exif tags will be written.
+     * @throws FileNotFoundException
+     * @throws IOException
+     */
+    public void writeExif(InputStream jpegStream, String exifOutFileName)
+            throws FileNotFoundException, IOException {
+        if (jpegStream == null || exifOutFileName == null) {
+            throw new IllegalArgumentException(NULL_ARGUMENT_STRING);
+        }
+        OutputStream s = null;
+        try {
+            s = getExifWriterStream(exifOutFileName);
+            doExifStreamIO(jpegStream, s);
+            s.flush();
+        } catch (IOException e) {
+            closeSilently(s);
+            throw e;
+        }
+        s.close();
+    }
+
+    /**
+     * Writes the tags from this ExifInterface object into a jpeg file, removing
+     * prior exif tags.
+     *
+     * @param jpegFileName a String containing the filepath for a jpeg file.
+     * @param exifOutFileName a String containing the filepath to which the jpeg
+     *            image with added exif tags will be written.
+     * @throws FileNotFoundException
+     * @throws IOException
+     */
+    public void writeExif(String jpegFileName, String exifOutFileName)
+            throws FileNotFoundException, IOException {
+        if (jpegFileName == null || exifOutFileName == null) {
+            throw new IllegalArgumentException(NULL_ARGUMENT_STRING);
+        }
+        InputStream is = null;
+        try {
+            is = new FileInputStream(jpegFileName);
+            writeExif(is, exifOutFileName);
+        } catch (IOException e) {
+            closeSilently(is);
+            throw e;
+        }
+        is.close();
+    }
+
+    /**
+     * Wraps an OutputStream object with an ExifOutputStream. Exif tags in this
+     * ExifInterface object will be added to a jpeg image written to this
+     * stream, removing prior exif tags. Other methods of this ExifInterface
+     * object should not be called until the returned OutputStream has been
+     * closed.
+     *
+     * @param outStream an OutputStream to wrap.
+     * @return an OutputStream that wraps the outStream parameter, and adds exif
+     *         metadata. A jpeg image should be written to this stream.
+     */
+    public OutputStream getExifWriterStream(OutputStream outStream) {
+        if (outStream == null) {
+            throw new IllegalArgumentException(NULL_ARGUMENT_STRING);
+        }
+        ExifOutputStream eos = new ExifOutputStream(outStream, this);
+        eos.setExifData(mData);
+        return eos;
+    }
+
+    /**
+     * Returns an OutputStream object that writes to a file. Exif tags in this
+     * ExifInterface object will be added to a jpeg image written to this
+     * stream, removing prior exif tags. Other methods of this ExifInterface
+     * object should not be called until the returned OutputStream has been
+     * closed.
+     *
+     * @param exifOutFileName an String containing a filepath for a jpeg file.
+     * @return an OutputStream that writes to the exifOutFileName file, and adds
+     *         exif metadata. A jpeg image should be written to this stream.
+     * @throws FileNotFoundException
+     */
+    public OutputStream getExifWriterStream(String exifOutFileName) throws FileNotFoundException {
+        if (exifOutFileName == null) {
+            throw new IllegalArgumentException(NULL_ARGUMENT_STRING);
+        }
+        OutputStream out = null;
+        try {
+            out = (OutputStream) new FileOutputStream(exifOutFileName);
+        } catch (FileNotFoundException e) {
+            closeSilently(out);
+            throw e;
+        }
+        return getExifWriterStream(out);
+    }
+
+    /**
+     * Attempts to do an in-place rewrite the exif metadata in a file for the
+     * given tags. If tags do not exist or do not have the same size as the
+     * existing exif tags, this method will fail.
+     *
+     * @param filename a String containing a filepath for a jpeg file with exif
+     *            tags to rewrite.
+     * @param tags tags that will be written into the jpeg file over existing
+     *            tags if possible.
+     * @return true if success, false if could not overwrite. If false, no
+     *         changes are made to the file.
+     * @throws FileNotFoundException
+     * @throws IOException
+     */
+    public boolean rewriteExif(String filename, Collection<ExifTag> tags)
+            throws FileNotFoundException, IOException {
+        RandomAccessFile file = null;
+        InputStream is = null;
+        boolean ret;
+        try {
+            File temp = new File(filename);
+            is = new BufferedInputStream(new FileInputStream(temp));
+
+            // Parse beginning of APP1 in exif to find size of exif header.
+            ExifParser parser = null;
+            try {
+                parser = ExifParser.parse(is, this);
+            } catch (ExifInvalidFormatException e) {
+                throw new IOException("Invalid exif format : ", e);
+            }
+            long exifSize = parser.getOffsetToExifEndFromSOF();
+
+            // Free up resources
+            is.close();
+            is = null;
+
+            // Open file for memory mapping.
+            file = new RandomAccessFile(temp, "rw");
+            long fileLength = file.length();
+            if (fileLength < exifSize) {
+                throw new IOException("Filesize changed during operation");
+            }
+
+            // Map only exif header into memory.
+            ByteBuffer buf = file.getChannel().map(MapMode.READ_WRITE, 0, exifSize);
+
+            // Attempt to overwrite tag values without changing lengths (avoids
+            // file copy).
+            ret = rewriteExif(buf, tags);
+        } catch (IOException e) {
+            closeSilently(file);
+            throw e;
+        } finally {
+            closeSilently(is);
+        }
+        file.close();
+        return ret;
+    }
+
+    /**
+     * Attempts to do an in-place rewrite the exif metadata in a ByteBuffer for
+     * the given tags. If tags do not exist or do not have the same size as the
+     * existing exif tags, this method will fail.
+     *
+     * @param buf a ByteBuffer containing a jpeg file with existing exif tags to
+     *            rewrite.
+     * @param tags tags that will be written into the jpeg ByteBuffer over
+     *            existing tags if possible.
+     * @return true if success, false if could not overwrite. If false, no
+     *         changes are made to the ByteBuffer.
+     * @throws IOException
+     */
+    public boolean rewriteExif(ByteBuffer buf, Collection<ExifTag> tags) throws IOException {
+        ExifModifier mod = null;
+        try {
+            mod = new ExifModifier(buf, this);
+            for (ExifTag t : tags) {
+                mod.modifyTag(t);
+            }
+            return mod.commit();
+        } catch (ExifInvalidFormatException e) {
+            throw new IOException("Invalid exif format : " + e);
+        }
+    }
+
+    /**
+     * Attempts to do an in-place rewrite of the exif metadata. If this fails,
+     * fall back to overwriting file. This preserves tags that are not being
+     * rewritten.
+     *
+     * @param filename a String containing a filepath for a jpeg file.
+     * @param tags tags that will be written into the jpeg file over existing
+     *            tags if possible.
+     * @throws FileNotFoundException
+     * @throws IOException
+     * @see #rewriteExif
+     */
+    public void forceRewriteExif(String filename, Collection<ExifTag> tags)
+            throws FileNotFoundException,
+            IOException {
+        // Attempt in-place write
+        if (!rewriteExif(filename, tags)) {
+            // Fall back to doing a copy
+            ExifData tempData = mData;
+            mData = new ExifData(DEFAULT_BYTE_ORDER);
+            FileInputStream is = null;
+            ByteArrayOutputStream bytes = null;
+            try {
+                is = new FileInputStream(filename);
+                bytes = new ByteArrayOutputStream();
+                doExifStreamIO(is, bytes);
+                byte[] imageBytes = bytes.toByteArray();
+                readExif(imageBytes);
+                setTags(tags);
+                writeExif(imageBytes, filename);
+            } catch (IOException e) {
+                closeSilently(is);
+                throw e;
+            } finally {
+                is.close();
+                // Prevent clobbering of mData
+                mData = tempData;
+            }
+        }
+    }
+
+    /**
+     * Attempts to do an in-place rewrite of the exif metadata using the tags in
+     * this ExifInterface object. If this fails, fall back to overwriting file.
+     * This preserves tags that are not being rewritten.
+     *
+     * @param filename a String containing a filepath for a jpeg file.
+     * @throws FileNotFoundException
+     * @throws IOException
+     * @see #rewriteExif
+     */
+    public void forceRewriteExif(String filename) throws FileNotFoundException, IOException {
+        forceRewriteExif(filename, getAllTags());
+    }
+
+    /**
+     * Get the exif tags in this ExifInterface object or null if none exist.
+     *
+     * @return a List of {@link ExifTag}s.
+     */
+    public List<ExifTag> getAllTags() {
+        return mData.getAllTags();
+    }
+
+    /**
+     * Returns a list of ExifTags that share a TID (which can be obtained by
+     * calling {@link #getTrueTagKey} on a defined tag constant) or null if none
+     * exist.
+     *
+     * @param tagId a TID as defined in the exif standard (or with
+     *            {@link #defineTag}).
+     * @return a List of {@link ExifTag}s.
+     */
+    public List<ExifTag> getTagsForTagId(short tagId) {
+        return mData.getAllTagsForTagId(tagId);
+    }
+
+    /**
+     * Returns a list of ExifTags that share an IFD (which can be obtained by
+     * calling {@link #getTrueIFD} on a defined tag constant) or null if none
+     * exist.
+     *
+     * @param ifdId an IFD as defined in the exif standard (or with
+     *            {@link #defineTag}).
+     * @return a List of {@link ExifTag}s.
+     */
+    public List<ExifTag> getTagsForIfdId(int ifdId) {
+        return mData.getAllTagsForIfd(ifdId);
+    }
+
+    /**
+     * Gets an ExifTag for an IFD other than the tag's default.
+     *
+     * @see #getTag
+     */
+    public ExifTag getTag(int tagId, int ifdId) {
+        if (!ExifTag.isValidIfd(ifdId)) {
+            return null;
+        }
+        return mData.getTag(getTrueTagKey(tagId), ifdId);
+    }
+
+    /**
+     * Returns the ExifTag in that tag's default IFD for a defined tag constant
+     * or null if none exists.
+     *
+     * @param tagId a defined tag constant, e.g. {@link #TAG_IMAGE_WIDTH}.
+     * @return an {@link ExifTag} or null if none exists.
+     */
+    public ExifTag getTag(int tagId) {
+        int ifdId = getDefinedTagDefaultIfd(tagId);
+        return getTag(tagId, ifdId);
+    }
+
+    /**
+     * Gets a tag value for an IFD other than the tag's default.
+     *
+     * @see #getTagValue
+     */
+    public Object getTagValue(int tagId, int ifdId) {
+        ExifTag t = getTag(tagId, ifdId);
+        return (t == null) ? null : t.getValue();
+    }
+
+    /**
+     * Returns the value of the ExifTag in that tag's default IFD for a defined
+     * tag constant or null if none exists or the value could not be cast into
+     * the return type.
+     *
+     * @param tagId a defined tag constant, e.g. {@link #TAG_IMAGE_WIDTH}.
+     * @return the value of the ExifTag or null if none exists.
+     */
+    public Object getTagValue(int tagId) {
+        int ifdId = getDefinedTagDefaultIfd(tagId);
+        return getTagValue(tagId, ifdId);
+    }
+
+    /*
+     * Getter methods that are similar to getTagValue. Null is returned if the
+     * tag value cannot be cast into the return type.
+     */
+
+    /**
+     * @see #getTagValue
+     */
+    public String getTagStringValue(int tagId, int ifdId) {
+        ExifTag t = getTag(tagId, ifdId);
+        if (t == null) {
+            return null;
+        }
+        return t.getValueAsString();
+    }
+
+    /**
+     * @see #getTagValue
+     */
+    public String getTagStringValue(int tagId) {
+        int ifdId = getDefinedTagDefaultIfd(tagId);
+        return getTagStringValue(tagId, ifdId);
+    }
+
+    /**
+     * @see #getTagValue
+     */
+    public Long getTagLongValue(int tagId, int ifdId) {
+        long[] l = getTagLongValues(tagId, ifdId);
+        if (l == null || l.length <= 0) {
+            return null;
+        }
+        return new Long(l[0]);
+    }
+
+    /**
+     * @see #getTagValue
+     */
+    public Long getTagLongValue(int tagId) {
+        int ifdId = getDefinedTagDefaultIfd(tagId);
+        return getTagLongValue(tagId, ifdId);
+    }
+
+    /**
+     * @see #getTagValue
+     */
+    public Integer getTagIntValue(int tagId, int ifdId) {
+        int[] l = getTagIntValues(tagId, ifdId);
+        if (l == null || l.length <= 0) {
+            return null;
+        }
+        return new Integer(l[0]);
+    }
+
+    /**
+     * @see #getTagValue
+     */
+    public Integer getTagIntValue(int tagId) {
+        int ifdId = getDefinedTagDefaultIfd(tagId);
+        return getTagIntValue(tagId, ifdId);
+    }
+
+    /**
+     * @see #getTagValue
+     */
+    public Byte getTagByteValue(int tagId, int ifdId) {
+        byte[] l = getTagByteValues(tagId, ifdId);
+        if (l == null || l.length <= 0) {
+            return null;
+        }
+        return new Byte(l[0]);
+    }
+
+    /**
+     * @see #getTagValue
+     */
+    public Byte getTagByteValue(int tagId) {
+        int ifdId = getDefinedTagDefaultIfd(tagId);
+        return getTagByteValue(tagId, ifdId);
+    }
+
+    /**
+     * @see #getTagValue
+     */
+    public Rational getTagRationalValue(int tagId, int ifdId) {
+        Rational[] l = getTagRationalValues(tagId, ifdId);
+        if (l == null || l.length == 0) {
+            return null;
+        }
+        return new Rational(l[0]);
+    }
+
+    /**
+     * @see #getTagValue
+     */
+    public Rational getTagRationalValue(int tagId) {
+        int ifdId = getDefinedTagDefaultIfd(tagId);
+        return getTagRationalValue(tagId, ifdId);
+    }
+
+    /**
+     * @see #getTagValue
+     */
+    public long[] getTagLongValues(int tagId, int ifdId) {
+        ExifTag t = getTag(tagId, ifdId);
+        if (t == null) {
+            return null;
+        }
+        return t.getValueAsLongs();
+    }
+
+    /**
+     * @see #getTagValue
+     */
+    public long[] getTagLongValues(int tagId) {
+        int ifdId = getDefinedTagDefaultIfd(tagId);
+        return getTagLongValues(tagId, ifdId);
+    }
+
+    /**
+     * @see #getTagValue
+     */
+    public int[] getTagIntValues(int tagId, int ifdId) {
+        ExifTag t = getTag(tagId, ifdId);
+        if (t == null) {
+            return null;
+        }
+        return t.getValueAsInts();
+    }
+
+    /**
+     * @see #getTagValue
+     */
+    public int[] getTagIntValues(int tagId) {
+        int ifdId = getDefinedTagDefaultIfd(tagId);
+        return getTagIntValues(tagId, ifdId);
+    }
+
+    /**
+     * @see #getTagValue
+     */
+    public byte[] getTagByteValues(int tagId, int ifdId) {
+        ExifTag t = getTag(tagId, ifdId);
+        if (t == null) {
+            return null;
+        }
+        return t.getValueAsBytes();
+    }
+
+    /**
+     * @see #getTagValue
+     */
+    public byte[] getTagByteValues(int tagId) {
+        int ifdId = getDefinedTagDefaultIfd(tagId);
+        return getTagByteValues(tagId, ifdId);
+    }
+
+    /**
+     * @see #getTagValue
+     */
+    public Rational[] getTagRationalValues(int tagId, int ifdId) {
+        ExifTag t = getTag(tagId, ifdId);
+        if (t == null) {
+            return null;
+        }
+        return t.getValueAsRationals();
+    }
+
+    /**
+     * @see #getTagValue
+     */
+    public Rational[] getTagRationalValues(int tagId) {
+        int ifdId = getDefinedTagDefaultIfd(tagId);
+        return getTagRationalValues(tagId, ifdId);
+    }
+
+    /**
+     * Checks whether a tag has a defined number of elements.
+     *
+     * @param tagId a defined tag constant, e.g. {@link #TAG_IMAGE_WIDTH}.
+     * @return true if the tag has a defined number of elements.
+     */
+    public boolean isTagCountDefined(int tagId) {
+        int info = getTagInfo().get(tagId);
+        // No value in info can be zero, as all tags have a non-zero type
+        if (info == 0) {
+            return false;
+        }
+        return getComponentCountFromInfo(info) != ExifTag.SIZE_UNDEFINED;
+    }
+
+    /**
+     * Gets the defined number of elements for a tag.
+     *
+     * @param tagId a defined tag constant, e.g. {@link #TAG_IMAGE_WIDTH}.
+     * @return the number of elements or {@link ExifTag#SIZE_UNDEFINED} if the
+     *         tag or the number of elements is not defined.
+     */
+    public int getDefinedTagCount(int tagId) {
+        int info = getTagInfo().get(tagId);
+        if (info == 0) {
+            return ExifTag.SIZE_UNDEFINED;
+        }
+        return getComponentCountFromInfo(info);
+    }
+
+    /**
+     * Gets the number of elements for an ExifTag in a given IFD.
+     *
+     * @param tagId a defined tag constant, e.g. {@link #TAG_IMAGE_WIDTH}.
+     * @param ifdId the IFD containing the ExifTag to check.
+     * @return the number of elements in the ExifTag, if the tag's size is
+     *         undefined this will return the actual number of elements that is
+     *         in the ExifTag's value.
+     */
+    public int getActualTagCount(int tagId, int ifdId) {
+        ExifTag t = getTag(tagId, ifdId);
+        if (t == null) {
+            return 0;
+        }
+        return t.getComponentCount();
+    }
+
+    /**
+     * Gets the default IFD for a tag.
+     *
+     * @param tagId a defined tag constant, e.g. {@link #TAG_IMAGE_WIDTH}.
+     * @return the default IFD for a tag definition or {@link #IFD_NULL} if no
+     *         definition exists.
+     */
+    public int getDefinedTagDefaultIfd(int tagId) {
+        int info = getTagInfo().get(tagId);
+        if (info == DEFINITION_NULL) {
+            return IFD_NULL;
+        }
+        return getTrueIfd(tagId);
+    }
+
+    /**
+     * Gets the defined type for a tag.
+     *
+     * @param tagId a defined tag constant, e.g. {@link #TAG_IMAGE_WIDTH}.
+     * @return the type.
+     * @see ExifTag#getDataType()
+     */
+    public short getDefinedTagType(int tagId) {
+        int info = getTagInfo().get(tagId);
+        if (info == 0) {
+            return -1;
+        }
+        return getTypeFromInfo(info);
+    }
+
+    /**
+     * Returns true if tag TID is one of the following: {@link TAG_EXIF_IFD},
+     * {@link TAG_GPS_IFD}, {@link TAG_JPEG_INTERCHANGE_FORMAT},
+     * {@link TAG_STRIP_OFFSETS}, {@link TAG_INTEROPERABILITY_IFD}
+     * <p>
+     * Note: defining tags with these TID's is disallowed.
+     *
+     * @param tag a tag's TID (can be obtained from a defined tag constant with
+     *            {@link #getTrueTagKey}).
+     * @return true if the TID is that of an offset tag.
+     */
+    protected static boolean isOffsetTag(short tag) {
+        return sOffsetTags.contains(tag);
+    }
+
+    /**
+     * Creates a tag for a defined tag constant in a given IFD if that IFD is
+     * allowed for the tag.  This method will fail anytime the appropriate
+     * {@link ExifTag#setValue} for this tag's datatype would fail.
+     *
+     * @param tagId a tag constant, e.g. {@link #TAG_IMAGE_WIDTH}.
+     * @param ifdId the IFD that the tag should be in.
+     * @param val the value of the tag to set.
+     * @return an ExifTag object or null if one could not be constructed.
+     * @see #buildTag
+     */
+    public ExifTag buildTag(int tagId, int ifdId, Object val) {
+        int info = getTagInfo().get(tagId);
+        if (info == 0 || val == null) {
+            return null;
+        }
+        short type = getTypeFromInfo(info);
+        int definedCount = getComponentCountFromInfo(info);
+        boolean hasDefinedCount = (definedCount != ExifTag.SIZE_UNDEFINED);
+        if (!ExifInterface.isIfdAllowed(info, ifdId)) {
+            return null;
+        }
+        ExifTag t = new ExifTag(getTrueTagKey(tagId), type, definedCount, ifdId, hasDefinedCount);
+        if (!t.setValue(val)) {
+            return null;
+        }
+        return t;
+    }
+
+    /**
+     * Creates a tag for a defined tag constant in the tag's default IFD.
+     *
+     * @param tagId a tag constant, e.g. {@link #TAG_IMAGE_WIDTH}.
+     * @param val the tag's value.
+     * @return an ExifTag object.
+     */
+    public ExifTag buildTag(int tagId, Object val) {
+        int ifdId = getTrueIfd(tagId);
+        return buildTag(tagId, ifdId, val);
+    }
+
+    protected ExifTag buildUninitializedTag(int tagId) {
+        int info = getTagInfo().get(tagId);
+        if (info == 0) {
+            return null;
+        }
+        short type = getTypeFromInfo(info);
+        int definedCount = getComponentCountFromInfo(info);
+        boolean hasDefinedCount = (definedCount != ExifTag.SIZE_UNDEFINED);
+        int ifdId = getTrueIfd(tagId);
+        ExifTag t = new ExifTag(getTrueTagKey(tagId), type, definedCount, ifdId, hasDefinedCount);
+        return t;
+    }
+
+    /**
+     * Sets the value of an ExifTag if it exists in the given IFD. The value
+     * must be the correct type and length for that ExifTag.
+     *
+     * @param tagId a tag constant, e.g. {@link #TAG_IMAGE_WIDTH}.
+     * @param ifdId the IFD that the ExifTag is in.
+     * @param val the value to set.
+     * @return true if success, false if the ExifTag doesn't exist or the value
+     *         is the wrong type/length.
+     * @see #setTagValue
+     */
+    public boolean setTagValue(int tagId, int ifdId, Object val) {
+        ExifTag t = getTag(tagId, ifdId);
+        if (t == null) {
+            return false;
+        }
+        return t.setValue(val);
+    }
+
+    /**
+     * Sets the value of an ExifTag if it exists it's default IFD. The value
+     * must be the correct type and length for that ExifTag.
+     *
+     * @param tagId a tag constant, e.g. {@link #TAG_IMAGE_WIDTH}.
+     * @param val the value to set.
+     * @return true if success, false if the ExifTag doesn't exist or the value
+     *         is the wrong type/length.
+     */
+    public boolean setTagValue(int tagId, Object val) {
+        int ifdId = getDefinedTagDefaultIfd(tagId);
+        return setTagValue(tagId, ifdId, val);
+    }
+
+    /**
+     * Puts an ExifTag into this ExifInterface object's tags, removing a
+     * previous ExifTag with the same TID and IFD. The IFD it is put into will
+     * be the one the tag was created with in {@link #buildTag}.
+     *
+     * @param tag an ExifTag to put into this ExifInterface's tags.
+     * @return the previous ExifTag with the same TID and IFD or null if none
+     *         exists.
+     */
+    public ExifTag setTag(ExifTag tag) {
+        return mData.addTag(tag);
+    }
+
+    /**
+     * Puts a collection of ExifTags into this ExifInterface objects's tags. Any
+     * previous ExifTags with the same TID and IFDs will be removed.
+     *
+     * @param tags a Collection of ExifTags.
+     * @see #setTag
+     */
+    public void setTags(Collection<ExifTag> tags) {
+        for (ExifTag t : tags) {
+            setTag(t);
+        }
+    }
+
+    /**
+     * Removes the ExifTag for a tag constant from the given IFD.
+     *
+     * @param tagId a tag constant, e.g. {@link #TAG_IMAGE_WIDTH}.
+     * @param ifdId the IFD of the ExifTag to remove.
+     */
+    public void deleteTag(int tagId, int ifdId) {
+        mData.removeTag(getTrueTagKey(tagId), ifdId);
+    }
+
+    /**
+     * Removes the ExifTag for a tag constant from that tag's default IFD.
+     *
+     * @param tagId a tag constant, e.g. {@link #TAG_IMAGE_WIDTH}.
+     */
+    public void deleteTag(int tagId) {
+        int ifdId = getDefinedTagDefaultIfd(tagId);
+        deleteTag(tagId, ifdId);
+    }
+
+    /**
+     * Creates a new tag definition in this ExifInterface object for a given TID
+     * and default IFD. Creating a definition with the same TID and default IFD
+     * as a previous definition will override it.
+     *
+     * @param tagId the TID for the tag.
+     * @param defaultIfd the default IFD for the tag.
+     * @param tagType the type of the tag (see {@link ExifTag#getDataType()}).
+     * @param defaultComponentCount the number of elements of this tag's type in
+     *            the tags value.
+     * @param allowedIfds the IFD's this tag is allowed to be put in.
+     * @return the defined tag constant (e.g. {@link #TAG_IMAGE_WIDTH}) or
+     *         {@link #TAG_NULL} if the definition could not be made.
+     */
+    public int setTagDefinition(short tagId, int defaultIfd, short tagType,
+            short defaultComponentCount, int[] allowedIfds) {
+        if (sBannedDefines.contains(tagId)) {
+            return TAG_NULL;
+        }
+        if (ExifTag.isValidType(tagType) && ExifTag.isValidIfd(defaultIfd)) {
+            int tagDef = defineTag(defaultIfd, tagId);
+            if (tagDef == TAG_NULL) {
+                return TAG_NULL;
+            }
+            int[] otherDefs = getTagDefinitionsForTagId(tagId);
+            SparseIntArray infos = getTagInfo();
+            // Make sure defaultIfd is in allowedIfds
+            boolean defaultCheck = false;
+            for (int i : allowedIfds) {
+                if (defaultIfd == i) {
+                    defaultCheck = true;
+                }
+                if (!ExifTag.isValidIfd(i)) {
+                    return TAG_NULL;
+                }
+            }
+            if (!defaultCheck) {
+                return TAG_NULL;
+            }
+
+            int ifdFlags = getFlagsFromAllowedIfds(allowedIfds);
+            // Make sure no identical tags can exist in allowedIfds
+            if (otherDefs != null) {
+                for (int def : otherDefs) {
+                    int tagInfo = infos.get(def);
+                    int allowedFlags = getAllowedIfdFlagsFromInfo(tagInfo);
+                    if ((ifdFlags & allowedFlags) != 0) {
+                        return TAG_NULL;
+                    }
+                }
+            }
+            getTagInfo().put(tagDef, ifdFlags << 24 | (tagType << 16) | defaultComponentCount);
+            return tagDef;
+        }
+        return TAG_NULL;
+    }
+
+    protected int getTagDefinition(short tagId, int defaultIfd) {
+        return getTagInfo().get(defineTag(defaultIfd, tagId));
+    }
+
+    protected int[] getTagDefinitionsForTagId(short tagId) {
+        int[] ifds = IfdData.getIfds();
+        int[] defs = new int[ifds.length];
+        int counter = 0;
+        SparseIntArray infos = getTagInfo();
+        for (int i : ifds) {
+            int def = defineTag(i, tagId);
+            if (infos.get(def) != DEFINITION_NULL) {
+                defs[counter++] = def;
+            }
+        }
+        if (counter == 0) {
+            return null;
+        }
+
+        return Arrays.copyOfRange(defs, 0, counter);
+    }
+
+    protected int getTagDefinitionForTag(ExifTag tag) {
+        short type = tag.getDataType();
+        int count = tag.getComponentCount();
+        int ifd = tag.getIfd();
+        return getTagDefinitionForTag(tag.getTagId(), type, count, ifd);
+    }
+
+    protected int getTagDefinitionForTag(short tagId, short type, int count, int ifd) {
+        int[] defs = getTagDefinitionsForTagId(tagId);
+        if (defs == null) {
+            return TAG_NULL;
+        }
+        SparseIntArray infos = getTagInfo();
+        int ret = TAG_NULL;
+        for (int i : defs) {
+            int info = infos.get(i);
+            short def_type = getTypeFromInfo(info);
+            int def_count = getComponentCountFromInfo(info);
+            int[] def_ifds = getAllowedIfdsFromInfo(info);
+            boolean valid_ifd = false;
+            for (int j : def_ifds) {
+                if (j == ifd) {
+                    valid_ifd = true;
+                    break;
+                }
+            }
+            if (valid_ifd && type == def_type
+                    && (count == def_count || def_count == ExifTag.SIZE_UNDEFINED)) {
+                ret = i;
+                break;
+            }
+        }
+        return ret;
+    }
+
+    /**
+     * Removes a tag definition for given defined tag constant.
+     *
+     * @param tagId a defined tag constant, e.g. {@link #TAG_IMAGE_WIDTH}.
+     */
+    public void removeTagDefinition(int tagId) {
+        getTagInfo().delete(tagId);
+    }
+
+    /**
+     * Resets tag definitions to the default ones.
+     */
+    public void resetTagDefinitions() {
+        mTagInfo = null;
+    }
+
+    /**
+     * Returns the thumbnail from IFD1 as a bitmap, or null if none exists.
+     *
+     * @return the thumbnail as a bitmap.
+     */
+    public Bitmap getThumbnailBitmap() {
+        if (mData.hasCompressedThumbnail()) {
+            byte[] thumb = mData.getCompressedThumbnail();
+            return BitmapFactory.decodeByteArray(thumb, 0, thumb.length);
+        } else if (mData.hasUncompressedStrip()) {
+            // TODO: implement uncompressed
+        }
+        return null;
+    }
+
+    /**
+     * Returns the thumbnail from IFD1 as a byte array, or null if none exists.
+     * The bytes may either be an uncompressed strip as specified in the exif
+     * standard or a jpeg compressed image.
+     *
+     * @return the thumbnail as a byte array.
+     */
+    public byte[] getThumbnailBytes() {
+        if (mData.hasCompressedThumbnail()) {
+            return mData.getCompressedThumbnail();
+        } else if (mData.hasUncompressedStrip()) {
+            // TODO: implement this
+        }
+        return null;
+    }
+
+    /**
+     * Returns the thumbnail if it is jpeg compressed, or null if none exists.
+     *
+     * @return the thumbnail as a byte array.
+     */
+    public byte[] getThumbnail() {
+        return mData.getCompressedThumbnail();
+    }
+
+    /**
+     * Check if thumbnail is compressed.
+     *
+     * @return true if the thumbnail is compressed.
+     */
+    public boolean isThumbnailCompressed() {
+        return mData.hasCompressedThumbnail();
+    }
+
+    /**
+     * Check if thumbnail exists.
+     *
+     * @return true if a compressed thumbnail exists.
+     */
+    public boolean hasThumbnail() {
+        // TODO: add back in uncompressed strip
+        return mData.hasCompressedThumbnail();
+    }
+
+    // TODO: uncompressed thumbnail setters
+
+    /**
+     * Sets the thumbnail to be a jpeg compressed image. Clears any prior
+     * thumbnail.
+     *
+     * @param thumb a byte array containing a jpeg compressed image.
+     * @return true if the thumbnail was set.
+     */
+    public boolean setCompressedThumbnail(byte[] thumb) {
+        mData.clearThumbnailAndStrips();
+        mData.setCompressedThumbnail(thumb);
+        return true;
+    }
+
+    /**
+     * Sets the thumbnail to be a jpeg compressed bitmap. Clears any prior
+     * thumbnail.
+     *
+     * @param thumb a bitmap to compress to a jpeg thumbnail.
+     * @return true if the thumbnail was set.
+     */
+    public boolean setCompressedThumbnail(Bitmap thumb) {
+        ByteArrayOutputStream thumbnail = new ByteArrayOutputStream();
+        if (!thumb.compress(Bitmap.CompressFormat.JPEG, 90, thumbnail)) {
+            return false;
+        }
+        return setCompressedThumbnail(thumbnail.toByteArray());
+    }
+
+    /**
+     * Clears the compressed thumbnail if it exists.
+     */
+    public void removeCompressedThumbnail() {
+        mData.setCompressedThumbnail(null);
+    }
+
+    // Convenience methods:
+
+    /**
+     * Decodes the user comment tag into string as specified in the EXIF
+     * standard. Returns null if decoding failed.
+     */
+    public String getUserComment() {
+        return mData.getUserComment();
+    }
+
+    /**
+     * Returns the Orientation ExifTag value for a given number of degrees.
+     *
+     * @param degrees the amount an image is rotated in degrees.
+     */
+    public static short getOrientationValueForRotation(int degrees) {
+        degrees %= 360;
+        if (degrees < 0) {
+            degrees += 360;
+        }
+        if (degrees < 90) {
+            return Orientation.TOP_LEFT; // 0 degrees
+        } else if (degrees < 180) {
+            return Orientation.RIGHT_TOP; // 90 degrees cw
+        } else if (degrees < 270) {
+            return Orientation.BOTTOM_LEFT; // 180 degrees
+        } else {
+            return Orientation.RIGHT_BOTTOM; // 270 degrees cw
+        }
+    }
+
+    /**
+     * Returns the rotation degrees corresponding to an ExifTag Orientation
+     * value.
+     *
+     * @param orientation the ExifTag Orientation value.
+     */
+    public static int getRotationForOrientationValue(short orientation) {
+        switch (orientation) {
+            case Orientation.TOP_LEFT:
+                return 0;
+            case Orientation.RIGHT_TOP:
+                return 90;
+            case Orientation.BOTTOM_LEFT:
+                return 180;
+            case Orientation.RIGHT_BOTTOM:
+                return 270;
+            default:
+                return 0;
+        }
+    }
+
+    /**
+     * Gets the double representation of the GPS latitude or longitude
+     * coordinate.
+     *
+     * @param coordinate an array of 3 Rationals representing the degrees,
+     *            minutes, and seconds of the GPS location as defined in the
+     *            exif specification.
+     * @param reference a GPS reference reperesented by a String containing "N",
+     *            "S", "E", or "W".
+     * @return the GPS coordinate represented as degrees + minutes/60 +
+     *         seconds/3600
+     */
+    public static double convertLatOrLongToDouble(Rational[] coordinate, String reference) {
+        try {
+            double degrees = coordinate[0].toDouble();
+            double minutes = coordinate[1].toDouble();
+            double seconds = coordinate[2].toDouble();
+            double result = degrees + minutes / 60.0 + seconds / 3600.0;
+            if ((reference.equals("S") || reference.equals("W"))) {
+                return -result;
+            }
+            return result;
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw new IllegalArgumentException();
+        }
+    }
+
+    /**
+     * Gets the GPS latitude and longitude as a pair of doubles from this
+     * ExifInterface object's tags, or null if the necessary tags do not exist.
+     *
+     * @return an array of 2 doubles containing the latitude, and longitude
+     *         respectively.
+     * @see #convertLatOrLongToDouble
+     */
+    public double[] getLatLongAsDoubles() {
+        Rational[] latitude = getTagRationalValues(TAG_GPS_LATITUDE);
+        String latitudeRef = getTagStringValue(TAG_GPS_LATITUDE_REF);
+        Rational[] longitude = getTagRationalValues(TAG_GPS_LONGITUDE);
+        String longitudeRef = getTagStringValue(TAG_GPS_LONGITUDE_REF);
+        if (latitude == null || longitude == null || latitudeRef == null || longitudeRef == null
+                || latitude.length < 3 || longitude.length < 3) {
+            return null;
+        }
+        double[] latLon = new double[2];
+        latLon[0] = convertLatOrLongToDouble(latitude, latitudeRef);
+        latLon[1] = convertLatOrLongToDouble(longitude, longitudeRef);
+        return latLon;
+    }
+
+    private static final String GPS_DATE_FORMAT_STR = "yyyy:MM:dd";
+    private static final String DATETIME_FORMAT_STR = "yyyy:MM:dd kk:mm:ss";
+    private final DateFormat mDateTimeStampFormat = new SimpleDateFormat(DATETIME_FORMAT_STR);
+    private final DateFormat mGPSDateStampFormat = new SimpleDateFormat(GPS_DATE_FORMAT_STR);
+    private final Calendar mGPSTimeStampCalendar = Calendar
+            .getInstance(TimeZone.getTimeZone("UTC"));
+
+    /**
+     * Creates, formats, and sets the DateTimeStamp tag for one of:
+     * {@link #TAG_DATE_TIME}, {@link #TAG_DATE_TIME_DIGITIZED},
+     * {@link #TAG_DATE_TIME_ORIGINAL}.
+     *
+     * @param tagId one of the DateTimeStamp tags.
+     * @param timestamp a timestamp to format.
+     * @param timezone a TimeZone object.
+     * @return true if success, false if the tag could not be set.
+     */
+    public boolean addDateTimeStampTag(int tagId, long timestamp, TimeZone timezone) {
+        if (tagId == TAG_DATE_TIME || tagId == TAG_DATE_TIME_DIGITIZED
+                || tagId == TAG_DATE_TIME_ORIGINAL) {
+            mDateTimeStampFormat.setTimeZone(timezone);
+            ExifTag t = buildTag(tagId, mDateTimeStampFormat.format(timestamp));
+            if (t == null) {
+                return false;
+            }
+            setTag(t);
+        } else {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Creates and sets all to the GPS tags for a give latitude and longitude.
+     *
+     * @param latitude a GPS latitude coordinate.
+     * @param longitude a GPS longitude coordinate.
+     * @return true if success, false if they could not be created or set.
+     */
+    public boolean addGpsTags(double latitude, double longitude) {
+        ExifTag latTag = buildTag(TAG_GPS_LATITUDE, toExifLatLong(latitude));
+        ExifTag longTag = buildTag(TAG_GPS_LONGITUDE, toExifLatLong(longitude));
+        ExifTag latRefTag = buildTag(TAG_GPS_LATITUDE_REF,
+                latitude >= 0 ? ExifInterface.GpsLatitudeRef.NORTH
+                        : ExifInterface.GpsLatitudeRef.SOUTH);
+        ExifTag longRefTag = buildTag(TAG_GPS_LONGITUDE_REF,
+                longitude >= 0 ? ExifInterface.GpsLongitudeRef.EAST
+                        : ExifInterface.GpsLongitudeRef.WEST);
+        if (latTag == null || longTag == null || latRefTag == null || longRefTag == null) {
+            return false;
+        }
+        setTag(latTag);
+        setTag(longTag);
+        setTag(latRefTag);
+        setTag(longRefTag);
+        return true;
+    }
+
+    /**
+     * Creates and sets the GPS timestamp tag.
+     *
+     * @param timestamp a GPS timestamp.
+     * @return true if success, false if could not be created or set.
+     */
+    public boolean addGpsDateTimeStampTag(long timestamp) {
+        ExifTag t = buildTag(TAG_GPS_DATE_STAMP, mGPSDateStampFormat.format(timestamp));
+        if (t == null) {
+            return false;
+        }
+        setTag(t);
+        mGPSTimeStampCalendar.setTimeInMillis(timestamp);
+        t = buildTag(TAG_GPS_TIME_STAMP, new Rational[] {
+                new Rational(mGPSTimeStampCalendar.get(Calendar.HOUR_OF_DAY), 1),
+                new Rational(mGPSTimeStampCalendar.get(Calendar.MINUTE), 1),
+                new Rational(mGPSTimeStampCalendar.get(Calendar.SECOND), 1)
+        });
+        if (t == null) {
+            return false;
+        }
+        setTag(t);
+        return true;
+    }
+
+    private static Rational[] toExifLatLong(double value) {
+        // convert to the format dd/1 mm/1 ssss/100
+        value = Math.abs(value);
+        int degrees = (int) value;
+        value = (value - degrees) * 60;
+        int minutes = (int) value;
+        value = (value - minutes) * 6000;
+        int seconds = (int) value;
+        return new Rational[] {
+                new Rational(degrees, 1), new Rational(minutes, 1), new Rational(seconds, 100)
+        };
+    }
+
+    private void doExifStreamIO(InputStream is, OutputStream os) throws IOException {
+        byte[] buf = new byte[1024];
+        int ret = is.read(buf, 0, 1024);
+        while (ret != -1) {
+            os.write(buf, 0, ret);
+            ret = is.read(buf, 0, 1024);
+        }
+    }
+
+    protected static void closeSilently(Closeable c) {
+        if (c != null) {
+            try {
+                c.close();
+            } catch (Throwable e) {
+                // ignored
+            }
+        }
+    }
+
+    private SparseIntArray mTagInfo = null;
+
+    protected SparseIntArray getTagInfo() {
+        if (mTagInfo == null) {
+            mTagInfo = new SparseIntArray();
+            initTagInfo();
+        }
+        return mTagInfo;
+    }
+
+    private void initTagInfo() {
+        /**
+         * We put tag information in a 4-bytes integer. The first byte a bitmask
+         * representing the allowed IFDs of the tag, the second byte is the data
+         * type, and the last two byte are a short value indicating the default
+         * component count of this tag.
+         */
+        // IFD0 tags
+        int[] ifdAllowedIfds = {
+                IfdId.TYPE_IFD_0, IfdId.TYPE_IFD_1
+        };
+        int ifdFlags = getFlagsFromAllowedIfds(ifdAllowedIfds) << 24;
+        mTagInfo.put(ExifInterface.TAG_MAKE,
+                ifdFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED);
+        mTagInfo.put(ExifInterface.TAG_IMAGE_WIDTH,
+                ifdFlags | ExifTag.TYPE_UNSIGNED_LONG << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_IMAGE_LENGTH,
+                ifdFlags | ExifTag.TYPE_UNSIGNED_LONG << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_BITS_PER_SAMPLE,
+                ifdFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 3);
+        mTagInfo.put(ExifInterface.TAG_COMPRESSION,
+                ifdFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_PHOTOMETRIC_INTERPRETATION,
+                ifdFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_ORIENTATION, ifdFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16
+                | 1);
+        mTagInfo.put(ExifInterface.TAG_SAMPLES_PER_PIXEL,
+                ifdFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_PLANAR_CONFIGURATION,
+                ifdFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_Y_CB_CR_SUB_SAMPLING,
+                ifdFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 2);
+        mTagInfo.put(ExifInterface.TAG_Y_CB_CR_POSITIONING,
+                ifdFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_X_RESOLUTION,
+                ifdFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_Y_RESOLUTION,
+                ifdFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_RESOLUTION_UNIT,
+                ifdFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_STRIP_OFFSETS,
+                ifdFlags | ExifTag.TYPE_UNSIGNED_LONG << 16 | ExifTag.SIZE_UNDEFINED);
+        mTagInfo.put(ExifInterface.TAG_ROWS_PER_STRIP,
+                ifdFlags | ExifTag.TYPE_UNSIGNED_LONG << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_STRIP_BYTE_COUNTS,
+                ifdFlags | ExifTag.TYPE_UNSIGNED_LONG << 16 | ExifTag.SIZE_UNDEFINED);
+        mTagInfo.put(ExifInterface.TAG_TRANSFER_FUNCTION,
+                ifdFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 3 * 256);
+        mTagInfo.put(ExifInterface.TAG_WHITE_POINT,
+                ifdFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 2);
+        mTagInfo.put(ExifInterface.TAG_PRIMARY_CHROMATICITIES,
+                ifdFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 6);
+        mTagInfo.put(ExifInterface.TAG_Y_CB_CR_COEFFICIENTS,
+                ifdFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 3);
+        mTagInfo.put(ExifInterface.TAG_REFERENCE_BLACK_WHITE,
+                ifdFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 6);
+        mTagInfo.put(ExifInterface.TAG_DATE_TIME,
+                ifdFlags | ExifTag.TYPE_ASCII << 16 | 20);
+        mTagInfo.put(ExifInterface.TAG_IMAGE_DESCRIPTION,
+                ifdFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED);
+        mTagInfo.put(ExifInterface.TAG_MAKE,
+                ifdFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED);
+        mTagInfo.put(ExifInterface.TAG_MODEL,
+                ifdFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED);
+        mTagInfo.put(ExifInterface.TAG_SOFTWARE,
+                ifdFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED);
+        mTagInfo.put(ExifInterface.TAG_ARTIST,
+                ifdFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED);
+        mTagInfo.put(ExifInterface.TAG_COPYRIGHT,
+                ifdFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED);
+        mTagInfo.put(ExifInterface.TAG_EXIF_IFD,
+                ifdFlags | ExifTag.TYPE_UNSIGNED_LONG << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_GPS_IFD,
+                ifdFlags | ExifTag.TYPE_UNSIGNED_LONG << 16 | 1);
+        // IFD1 tags
+        int[] ifd1AllowedIfds = {
+            IfdId.TYPE_IFD_1
+        };
+        int ifdFlags1 = getFlagsFromAllowedIfds(ifd1AllowedIfds) << 24;
+        mTagInfo.put(ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT,
+                ifdFlags1 | ExifTag.TYPE_UNSIGNED_LONG << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH,
+                ifdFlags1 | ExifTag.TYPE_UNSIGNED_LONG << 16 | 1);
+        // Exif tags
+        int[] exifAllowedIfds = {
+            IfdId.TYPE_IFD_EXIF
+        };
+        int exifFlags = getFlagsFromAllowedIfds(exifAllowedIfds) << 24;
+        mTagInfo.put(ExifInterface.TAG_EXIF_VERSION,
+                exifFlags | ExifTag.TYPE_UNDEFINED << 16 | 4);
+        mTagInfo.put(ExifInterface.TAG_FLASHPIX_VERSION,
+                exifFlags | ExifTag.TYPE_UNDEFINED << 16 | 4);
+        mTagInfo.put(ExifInterface.TAG_COLOR_SPACE,
+                exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_COMPONENTS_CONFIGURATION,
+                exifFlags | ExifTag.TYPE_UNDEFINED << 16 | 4);
+        mTagInfo.put(ExifInterface.TAG_COMPRESSED_BITS_PER_PIXEL,
+                exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_PIXEL_X_DIMENSION,
+                exifFlags | ExifTag.TYPE_UNSIGNED_LONG << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_PIXEL_Y_DIMENSION,
+                exifFlags | ExifTag.TYPE_UNSIGNED_LONG << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_MAKER_NOTE,
+                exifFlags | ExifTag.TYPE_UNDEFINED << 16 | ExifTag.SIZE_UNDEFINED);
+        mTagInfo.put(ExifInterface.TAG_USER_COMMENT,
+                exifFlags | ExifTag.TYPE_UNDEFINED << 16 | ExifTag.SIZE_UNDEFINED);
+        mTagInfo.put(ExifInterface.TAG_RELATED_SOUND_FILE,
+                exifFlags | ExifTag.TYPE_ASCII << 16 | 13);
+        mTagInfo.put(ExifInterface.TAG_DATE_TIME_ORIGINAL,
+                exifFlags | ExifTag.TYPE_ASCII << 16 | 20);
+        mTagInfo.put(ExifInterface.TAG_DATE_TIME_DIGITIZED,
+                exifFlags | ExifTag.TYPE_ASCII << 16 | 20);
+        mTagInfo.put(ExifInterface.TAG_SUB_SEC_TIME,
+                exifFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED);
+        mTagInfo.put(ExifInterface.TAG_SUB_SEC_TIME_ORIGINAL,
+                exifFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED);
+        mTagInfo.put(ExifInterface.TAG_SUB_SEC_TIME_DIGITIZED,
+                exifFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED);
+        mTagInfo.put(ExifInterface.TAG_IMAGE_UNIQUE_ID,
+                exifFlags | ExifTag.TYPE_ASCII << 16 | 33);
+        mTagInfo.put(ExifInterface.TAG_EXPOSURE_TIME,
+                exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_F_NUMBER,
+                exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_EXPOSURE_PROGRAM,
+                exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_SPECTRAL_SENSITIVITY,
+                exifFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED);
+        mTagInfo.put(ExifInterface.TAG_ISO_SPEED_RATINGS,
+                exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | ExifTag.SIZE_UNDEFINED);
+        mTagInfo.put(ExifInterface.TAG_OECF,
+                exifFlags | ExifTag.TYPE_UNDEFINED << 16 | ExifTag.SIZE_UNDEFINED);
+        mTagInfo.put(ExifInterface.TAG_SHUTTER_SPEED_VALUE,
+                exifFlags | ExifTag.TYPE_RATIONAL << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_APERTURE_VALUE,
+                exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_BRIGHTNESS_VALUE,
+                exifFlags | ExifTag.TYPE_RATIONAL << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_EXPOSURE_BIAS_VALUE,
+                exifFlags | ExifTag.TYPE_RATIONAL << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_MAX_APERTURE_VALUE,
+                exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_SUBJECT_DISTANCE,
+                exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_METERING_MODE,
+                exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_LIGHT_SOURCE,
+                exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_FLASH,
+                exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_FOCAL_LENGTH,
+                exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_SUBJECT_AREA,
+                exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | ExifTag.SIZE_UNDEFINED);
+        mTagInfo.put(ExifInterface.TAG_FLASH_ENERGY,
+                exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_SPATIAL_FREQUENCY_RESPONSE,
+                exifFlags | ExifTag.TYPE_UNDEFINED << 16 | ExifTag.SIZE_UNDEFINED);
+        mTagInfo.put(ExifInterface.TAG_FOCAL_PLANE_X_RESOLUTION,
+                exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_FOCAL_PLANE_Y_RESOLUTION,
+                exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_FOCAL_PLANE_RESOLUTION_UNIT,
+                exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_SUBJECT_LOCATION,
+                exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 2);
+        mTagInfo.put(ExifInterface.TAG_EXPOSURE_INDEX,
+                exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_SENSING_METHOD,
+                exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_FILE_SOURCE,
+                exifFlags | ExifTag.TYPE_UNDEFINED << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_SCENE_TYPE,
+                exifFlags | ExifTag.TYPE_UNDEFINED << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_CFA_PATTERN,
+                exifFlags | ExifTag.TYPE_UNDEFINED << 16 | ExifTag.SIZE_UNDEFINED);
+        mTagInfo.put(ExifInterface.TAG_CUSTOM_RENDERED,
+                exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_EXPOSURE_MODE,
+                exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_WHITE_BALANCE,
+                exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_DIGITAL_ZOOM_RATIO,
+                exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_FOCAL_LENGTH_IN_35_MM_FILE,
+                exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_SCENE_CAPTURE_TYPE,
+                exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_GAIN_CONTROL,
+                exifFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_CONTRAST,
+                exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_SATURATION,
+                exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_SHARPNESS,
+                exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_DEVICE_SETTING_DESCRIPTION,
+                exifFlags | ExifTag.TYPE_UNDEFINED << 16 | ExifTag.SIZE_UNDEFINED);
+        mTagInfo.put(ExifInterface.TAG_SUBJECT_DISTANCE_RANGE,
+                exifFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_INTEROPERABILITY_IFD, exifFlags
+                | ExifTag.TYPE_UNSIGNED_LONG << 16 | 1);
+        // GPS tag
+        int[] gpsAllowedIfds = {
+            IfdId.TYPE_IFD_GPS
+        };
+        int gpsFlags = getFlagsFromAllowedIfds(gpsAllowedIfds) << 24;
+        mTagInfo.put(ExifInterface.TAG_GPS_VERSION_ID,
+                gpsFlags | ExifTag.TYPE_UNSIGNED_BYTE << 16 | 4);
+        mTagInfo.put(ExifInterface.TAG_GPS_LATITUDE_REF,
+                gpsFlags | ExifTag.TYPE_ASCII << 16 | 2);
+        mTagInfo.put(ExifInterface.TAG_GPS_LONGITUDE_REF,
+                gpsFlags | ExifTag.TYPE_ASCII << 16 | 2);
+        mTagInfo.put(ExifInterface.TAG_GPS_LATITUDE,
+                gpsFlags | ExifTag.TYPE_RATIONAL << 16 | 3);
+        mTagInfo.put(ExifInterface.TAG_GPS_LONGITUDE,
+                gpsFlags | ExifTag.TYPE_RATIONAL << 16 | 3);
+        mTagInfo.put(ExifInterface.TAG_GPS_ALTITUDE_REF,
+                gpsFlags | ExifTag.TYPE_UNSIGNED_BYTE << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_GPS_ALTITUDE,
+                gpsFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_GPS_TIME_STAMP,
+                gpsFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 3);
+        mTagInfo.put(ExifInterface.TAG_GPS_SATTELLITES,
+                gpsFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED);
+        mTagInfo.put(ExifInterface.TAG_GPS_STATUS,
+                gpsFlags | ExifTag.TYPE_ASCII << 16 | 2);
+        mTagInfo.put(ExifInterface.TAG_GPS_MEASURE_MODE,
+                gpsFlags | ExifTag.TYPE_ASCII << 16 | 2);
+        mTagInfo.put(ExifInterface.TAG_GPS_DOP,
+                gpsFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_GPS_SPEED_REF,
+                gpsFlags | ExifTag.TYPE_ASCII << 16 | 2);
+        mTagInfo.put(ExifInterface.TAG_GPS_SPEED,
+                gpsFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_GPS_TRACK_REF,
+                gpsFlags | ExifTag.TYPE_ASCII << 16 | 2);
+        mTagInfo.put(ExifInterface.TAG_GPS_TRACK,
+                gpsFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_GPS_IMG_DIRECTION_REF,
+                gpsFlags | ExifTag.TYPE_ASCII << 16 | 2);
+        mTagInfo.put(ExifInterface.TAG_GPS_IMG_DIRECTION,
+                gpsFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_GPS_MAP_DATUM,
+                gpsFlags | ExifTag.TYPE_ASCII << 16 | ExifTag.SIZE_UNDEFINED);
+        mTagInfo.put(ExifInterface.TAG_GPS_DEST_LATITUDE_REF,
+                gpsFlags | ExifTag.TYPE_ASCII << 16 | 2);
+        mTagInfo.put(ExifInterface.TAG_GPS_DEST_LATITUDE,
+                gpsFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_GPS_DEST_BEARING_REF,
+                gpsFlags | ExifTag.TYPE_ASCII << 16 | 2);
+        mTagInfo.put(ExifInterface.TAG_GPS_DEST_BEARING,
+                gpsFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_GPS_DEST_DISTANCE_REF,
+                gpsFlags | ExifTag.TYPE_ASCII << 16 | 2);
+        mTagInfo.put(ExifInterface.TAG_GPS_DEST_DISTANCE,
+                gpsFlags | ExifTag.TYPE_UNSIGNED_RATIONAL << 16 | 1);
+        mTagInfo.put(ExifInterface.TAG_GPS_PROCESSING_METHOD,
+                gpsFlags | ExifTag.TYPE_UNDEFINED << 16 | ExifTag.SIZE_UNDEFINED);
+        mTagInfo.put(ExifInterface.TAG_GPS_AREA_INFORMATION,
+                gpsFlags | ExifTag.TYPE_UNDEFINED << 16 | ExifTag.SIZE_UNDEFINED);
+        mTagInfo.put(ExifInterface.TAG_GPS_DATE_STAMP,
+                gpsFlags | ExifTag.TYPE_ASCII << 16 | 11);
+        mTagInfo.put(ExifInterface.TAG_GPS_DIFFERENTIAL,
+                gpsFlags | ExifTag.TYPE_UNSIGNED_SHORT << 16 | 11);
+        // Interoperability tag
+        int[] interopAllowedIfds = {
+            IfdId.TYPE_IFD_INTEROPERABILITY
+        };
+        int interopFlags = getFlagsFromAllowedIfds(interopAllowedIfds) << 24;
+        mTagInfo.put(TAG_INTEROPERABILITY_INDEX, interopFlags | ExifTag.TYPE_ASCII << 16
+                | ExifTag.SIZE_UNDEFINED);
+    }
+
+    protected static int getAllowedIfdFlagsFromInfo(int info) {
+        return info >>> 24;
+    }
+
+    protected static int[] getAllowedIfdsFromInfo(int info) {
+        int ifdFlags = getAllowedIfdFlagsFromInfo(info);
+        int[] ifds = IfdData.getIfds();
+        ArrayList<Integer> l = new ArrayList<Integer>();
+        for (int i = 0; i < IfdId.TYPE_IFD_COUNT; i++) {
+            int flag = (ifdFlags >> i) & 1;
+            if (flag == 1) {
+                l.add(ifds[i]);
+            }
+        }
+        if (l.size() <= 0) {
+            return null;
+        }
+        int[] ret = new int[l.size()];
+        int j = 0;
+        for (int i : l) {
+            ret[j++] = i;
+        }
+        return ret;
+    }
+
+    protected static boolean isIfdAllowed(int info, int ifd) {
+        int[] ifds = IfdData.getIfds();
+        int ifdFlags = getAllowedIfdFlagsFromInfo(info);
+        for (int i = 0; i < ifds.length; i++) {
+            if (ifd == ifds[i] && ((ifdFlags >> i) & 1) == 1) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    protected static int getFlagsFromAllowedIfds(int[] allowedIfds) {
+        if (allowedIfds == null || allowedIfds.length == 0) {
+            return 0;
+        }
+        int flags = 0;
+        int[] ifds = IfdData.getIfds();
+        for (int i = 0; i < IfdId.TYPE_IFD_COUNT; i++) {
+            for (int j : allowedIfds) {
+                if (ifds[i] == j) {
+                    flags |= 1 << i;
+                    break;
+                }
+            }
+        }
+        return flags;
+    }
+
+    protected static short getTypeFromInfo(int info) {
+        return (short) ((info >> 16) & 0x0ff);
+    }
+
+    protected static int getComponentCountFromInfo(int info) {
+        return info & 0x0ffff;
+    }
+
+}
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifInvalidFormatException.java b/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifInvalidFormatException.java
new file mode 100644
index 0000000..bf923ec
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifInvalidFormatException.java
@@ -0,0 +1,23 @@
+/*
+ * 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.gallery3d.exif;
+
+public class ExifInvalidFormatException extends Exception {
+    public ExifInvalidFormatException(String meg) {
+        super(meg);
+    }
+}
\ No newline at end of file
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifModifier.java b/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifModifier.java
new file mode 100644
index 0000000..f00362b
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifModifier.java
@@ -0,0 +1,196 @@
+/*
+ * 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.gallery3d.exif;
+
+import android.util.Log;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.List;
+
+class ExifModifier {
+    public static final String TAG = "ExifModifier";
+    public static final boolean DEBUG = false;
+    private final ByteBuffer mByteBuffer;
+    private final ExifData mTagToModified;
+    private final List<TagOffset> mTagOffsets = new ArrayList<TagOffset>();
+    private final ExifInterface mInterface;
+    private int mOffsetBase;
+
+    private static class TagOffset {
+        final int mOffset;
+        final ExifTag mTag;
+
+        TagOffset(ExifTag tag, int offset) {
+            mTag = tag;
+            mOffset = offset;
+        }
+    }
+
+    protected ExifModifier(ByteBuffer byteBuffer, ExifInterface iRef) throws IOException,
+            ExifInvalidFormatException {
+        mByteBuffer = byteBuffer;
+        mOffsetBase = byteBuffer.position();
+        mInterface = iRef;
+        InputStream is = null;
+        try {
+            is = new ByteBufferInputStream(byteBuffer);
+            // Do not require any IFD;
+            ExifParser parser = ExifParser.parse(is, mInterface);
+            mTagToModified = new ExifData(parser.getByteOrder());
+            mOffsetBase += parser.getTiffStartPosition();
+            mByteBuffer.position(0);
+        } finally {
+            ExifInterface.closeSilently(is);
+        }
+    }
+
+    protected ByteOrder getByteOrder() {
+        return mTagToModified.getByteOrder();
+    }
+
+    protected boolean commit() throws IOException, ExifInvalidFormatException {
+        InputStream is = null;
+        try {
+            is = new ByteBufferInputStream(mByteBuffer);
+            int flag = 0;
+            IfdData[] ifdDatas = new IfdData[] {
+                    mTagToModified.getIfdData(IfdId.TYPE_IFD_0),
+                    mTagToModified.getIfdData(IfdId.TYPE_IFD_1),
+                    mTagToModified.getIfdData(IfdId.TYPE_IFD_EXIF),
+                    mTagToModified.getIfdData(IfdId.TYPE_IFD_INTEROPERABILITY),
+                    mTagToModified.getIfdData(IfdId.TYPE_IFD_GPS)
+            };
+
+            if (ifdDatas[IfdId.TYPE_IFD_0] != null) {
+                flag |= ExifParser.OPTION_IFD_0;
+            }
+            if (ifdDatas[IfdId.TYPE_IFD_1] != null) {
+                flag |= ExifParser.OPTION_IFD_1;
+            }
+            if (ifdDatas[IfdId.TYPE_IFD_EXIF] != null) {
+                flag |= ExifParser.OPTION_IFD_EXIF;
+            }
+            if (ifdDatas[IfdId.TYPE_IFD_GPS] != null) {
+                flag |= ExifParser.OPTION_IFD_GPS;
+            }
+            if (ifdDatas[IfdId.TYPE_IFD_INTEROPERABILITY] != null) {
+                flag |= ExifParser.OPTION_IFD_INTEROPERABILITY;
+            }
+
+            ExifParser parser = ExifParser.parse(is, flag, mInterface);
+            int event = parser.next();
+            IfdData currIfd = null;
+            while (event != ExifParser.EVENT_END) {
+                switch (event) {
+                    case ExifParser.EVENT_START_OF_IFD:
+                        currIfd = ifdDatas[parser.getCurrentIfd()];
+                        if (currIfd == null) {
+                            parser.skipRemainingTagsInCurrentIfd();
+                        }
+                        break;
+                    case ExifParser.EVENT_NEW_TAG:
+                        ExifTag oldTag = parser.getTag();
+                        ExifTag newTag = currIfd.getTag(oldTag.getTagId());
+                        if (newTag != null) {
+                            if (newTag.getComponentCount() != oldTag.getComponentCount()
+                                    || newTag.getDataType() != oldTag.getDataType()) {
+                                return false;
+                            } else {
+                                mTagOffsets.add(new TagOffset(newTag, oldTag.getOffset()));
+                                currIfd.removeTag(oldTag.getTagId());
+                                if (currIfd.getTagCount() == 0) {
+                                    parser.skipRemainingTagsInCurrentIfd();
+                                }
+                            }
+                        }
+                        break;
+                }
+                event = parser.next();
+            }
+            for (IfdData ifd : ifdDatas) {
+                if (ifd != null && ifd.getTagCount() > 0) {
+                    return false;
+                }
+            }
+            modify();
+        } finally {
+            ExifInterface.closeSilently(is);
+        }
+        return true;
+    }
+
+    private void modify() {
+        mByteBuffer.order(getByteOrder());
+        for (TagOffset tagOffset : mTagOffsets) {
+            writeTagValue(tagOffset.mTag, tagOffset.mOffset);
+        }
+    }
+
+    private void writeTagValue(ExifTag tag, int offset) {
+        if (DEBUG) {
+            Log.v(TAG, "modifying tag to: \n" + tag.toString());
+            Log.v(TAG, "at offset: " + offset);
+        }
+        mByteBuffer.position(offset + mOffsetBase);
+        switch (tag.getDataType()) {
+            case ExifTag.TYPE_ASCII:
+                byte buf[] = tag.getStringByte();
+                if (buf.length == tag.getComponentCount()) {
+                    buf[buf.length - 1] = 0;
+                    mByteBuffer.put(buf);
+                } else {
+                    mByteBuffer.put(buf);
+                    mByteBuffer.put((byte) 0);
+                }
+                break;
+            case ExifTag.TYPE_LONG:
+            case ExifTag.TYPE_UNSIGNED_LONG:
+                for (int i = 0, n = tag.getComponentCount(); i < n; i++) {
+                    mByteBuffer.putInt((int) tag.getValueAt(i));
+                }
+                break;
+            case ExifTag.TYPE_RATIONAL:
+            case ExifTag.TYPE_UNSIGNED_RATIONAL:
+                for (int i = 0, n = tag.getComponentCount(); i < n; i++) {
+                    Rational v = tag.getRational(i);
+                    mByteBuffer.putInt((int) v.getNumerator());
+                    mByteBuffer.putInt((int) v.getDenominator());
+                }
+                break;
+            case ExifTag.TYPE_UNDEFINED:
+            case ExifTag.TYPE_UNSIGNED_BYTE:
+                buf = new byte[tag.getComponentCount()];
+                tag.getBytes(buf);
+                mByteBuffer.put(buf);
+                break;
+            case ExifTag.TYPE_UNSIGNED_SHORT:
+                for (int i = 0, n = tag.getComponentCount(); i < n; i++) {
+                    mByteBuffer.putShort((short) tag.getValueAt(i));
+                }
+                break;
+        }
+    }
+
+    public void modifyTag(ExifTag tag) {
+        mTagToModified.addTag(tag);
+    }
+}
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifOutputStream.java b/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifOutputStream.java
new file mode 100644
index 0000000..7ca05f2e
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifOutputStream.java
@@ -0,0 +1,518 @@
+/*
+ * 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.gallery3d.exif;
+
+import android.util.Log;
+
+import java.io.BufferedOutputStream;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+
+/**
+ * This class provides a way to replace the Exif header of a JPEG image.
+ * <p>
+ * Below is an example of writing EXIF data into a file
+ *
+ * <pre>
+ * public static void writeExif(byte[] jpeg, ExifData exif, String path) {
+ *     OutputStream os = null;
+ *     try {
+ *         os = new FileOutputStream(path);
+ *         ExifOutputStream eos = new ExifOutputStream(os);
+ *         // Set the exif header
+ *         eos.setExifData(exif);
+ *         // Write the original jpeg out, the header will be add into the file.
+ *         eos.write(jpeg);
+ *     } catch (FileNotFoundException e) {
+ *         e.printStackTrace();
+ *     } catch (IOException e) {
+ *         e.printStackTrace();
+ *     } finally {
+ *         if (os != null) {
+ *             try {
+ *                 os.close();
+ *             } catch (IOException e) {
+ *                 e.printStackTrace();
+ *             }
+ *         }
+ *     }
+ * }
+ * </pre>
+ */
+class ExifOutputStream extends FilterOutputStream {
+    private static final String TAG = "ExifOutputStream";
+    private static final boolean DEBUG = false;
+    private static final int STREAMBUFFER_SIZE = 0x00010000; // 64Kb
+
+    private static final int STATE_SOI = 0;
+    private static final int STATE_FRAME_HEADER = 1;
+    private static final int STATE_JPEG_DATA = 2;
+
+    private static final int EXIF_HEADER = 0x45786966;
+    private static final short TIFF_HEADER = 0x002A;
+    private static final short TIFF_BIG_ENDIAN = 0x4d4d;
+    private static final short TIFF_LITTLE_ENDIAN = 0x4949;
+    private static final short TAG_SIZE = 12;
+    private static final short TIFF_HEADER_SIZE = 8;
+    private static final int MAX_EXIF_SIZE = 65535;
+
+    private ExifData mExifData;
+    private int mState = STATE_SOI;
+    private int mByteToSkip;
+    private int mByteToCopy;
+    private byte[] mSingleByteArray = new byte[1];
+    private ByteBuffer mBuffer = ByteBuffer.allocate(4);
+    private final ExifInterface mInterface;
+
+    protected ExifOutputStream(OutputStream ou, ExifInterface iRef) {
+        super(new BufferedOutputStream(ou, STREAMBUFFER_SIZE));
+        mInterface = iRef;
+    }
+
+    /**
+     * Sets the ExifData to be written into the JPEG file. Should be called
+     * before writing image data.
+     */
+    protected void setExifData(ExifData exifData) {
+        mExifData = exifData;
+    }
+
+    /**
+     * Gets the Exif header to be written into the JPEF file.
+     */
+    protected ExifData getExifData() {
+        return mExifData;
+    }
+
+    private int requestByteToBuffer(int requestByteCount, byte[] buffer
+            , int offset, int length) {
+        int byteNeeded = requestByteCount - mBuffer.position();
+        int byteToRead = length > byteNeeded ? byteNeeded : length;
+        mBuffer.put(buffer, offset, byteToRead);
+        return byteToRead;
+    }
+
+    /**
+     * Writes the image out. The input data should be a valid JPEG format. After
+     * writing, it's Exif header will be replaced by the given header.
+     */
+    @Override
+    public void write(byte[] buffer, int offset, int length) throws IOException {
+        while ((mByteToSkip > 0 || mByteToCopy > 0 || mState != STATE_JPEG_DATA)
+                && length > 0) {
+            if (mByteToSkip > 0) {
+                int byteToProcess = length > mByteToSkip ? mByteToSkip : length;
+                length -= byteToProcess;
+                mByteToSkip -= byteToProcess;
+                offset += byteToProcess;
+            }
+            if (mByteToCopy > 0) {
+                int byteToProcess = length > mByteToCopy ? mByteToCopy : length;
+                out.write(buffer, offset, byteToProcess);
+                length -= byteToProcess;
+                mByteToCopy -= byteToProcess;
+                offset += byteToProcess;
+            }
+            if (length == 0) {
+                return;
+            }
+            switch (mState) {
+                case STATE_SOI:
+                    int byteRead = requestByteToBuffer(2, buffer, offset, length);
+                    offset += byteRead;
+                    length -= byteRead;
+                    if (mBuffer.position() < 2) {
+                        return;
+                    }
+                    mBuffer.rewind();
+                    if (mBuffer.getShort() != JpegHeader.SOI) {
+                        throw new IOException("Not a valid jpeg image, cannot write exif");
+                    }
+                    out.write(mBuffer.array(), 0, 2);
+                    mState = STATE_FRAME_HEADER;
+                    mBuffer.rewind();
+                    writeExifData();
+                    break;
+                case STATE_FRAME_HEADER:
+                    // We ignore the APP1 segment and copy all other segments
+                    // until SOF tag.
+                    byteRead = requestByteToBuffer(4, buffer, offset, length);
+                    offset += byteRead;
+                    length -= byteRead;
+                    // Check if this image data doesn't contain SOF.
+                    if (mBuffer.position() == 2) {
+                        short tag = mBuffer.getShort();
+                        if (tag == JpegHeader.EOI) {
+                            out.write(mBuffer.array(), 0, 2);
+                            mBuffer.rewind();
+                        }
+                    }
+                    if (mBuffer.position() < 4) {
+                        return;
+                    }
+                    mBuffer.rewind();
+                    short marker = mBuffer.getShort();
+                    if (marker == JpegHeader.APP1) {
+                        mByteToSkip = (mBuffer.getShort() & 0x0000ffff) - 2;
+                        mState = STATE_JPEG_DATA;
+                    } else if (!JpegHeader.isSofMarker(marker)) {
+                        out.write(mBuffer.array(), 0, 4);
+                        mByteToCopy = (mBuffer.getShort() & 0x0000ffff) - 2;
+                    } else {
+                        out.write(mBuffer.array(), 0, 4);
+                        mState = STATE_JPEG_DATA;
+                    }
+                    mBuffer.rewind();
+            }
+        }
+        if (length > 0) {
+            out.write(buffer, offset, length);
+        }
+    }
+
+    /**
+     * Writes the one bytes out. The input data should be a valid JPEG format.
+     * After writing, it's Exif header will be replaced by the given header.
+     */
+    @Override
+    public void write(int oneByte) throws IOException {
+        mSingleByteArray[0] = (byte) (0xff & oneByte);
+        write(mSingleByteArray);
+    }
+
+    /**
+     * Equivalent to calling write(buffer, 0, buffer.length).
+     */
+    @Override
+    public void write(byte[] buffer) throws IOException {
+        write(buffer, 0, buffer.length);
+    }
+
+    private void writeExifData() throws IOException {
+        if (mExifData == null) {
+            return;
+        }
+        if (DEBUG) {
+            Log.v(TAG, "Writing exif data...");
+        }
+        ArrayList<ExifTag> nullTags = stripNullValueTags(mExifData);
+        createRequiredIfdAndTag();
+        int exifSize = calculateAllOffset();
+        if (exifSize + 8 > MAX_EXIF_SIZE) {
+            throw new IOException("Exif header is too large (>64Kb)");
+        }
+        OrderedDataOutputStream dataOutputStream = new OrderedDataOutputStream(out);
+        dataOutputStream.setByteOrder(ByteOrder.BIG_ENDIAN);
+        dataOutputStream.writeShort(JpegHeader.APP1);
+        dataOutputStream.writeShort((short) (exifSize + 8));
+        dataOutputStream.writeInt(EXIF_HEADER);
+        dataOutputStream.writeShort((short) 0x0000);
+        if (mExifData.getByteOrder() == ByteOrder.BIG_ENDIAN) {
+            dataOutputStream.writeShort(TIFF_BIG_ENDIAN);
+        } else {
+            dataOutputStream.writeShort(TIFF_LITTLE_ENDIAN);
+        }
+        dataOutputStream.setByteOrder(mExifData.getByteOrder());
+        dataOutputStream.writeShort(TIFF_HEADER);
+        dataOutputStream.writeInt(8);
+        writeAllTags(dataOutputStream);
+        writeThumbnail(dataOutputStream);
+        for (ExifTag t : nullTags) {
+            mExifData.addTag(t);
+        }
+    }
+
+    private ArrayList<ExifTag> stripNullValueTags(ExifData data) {
+        ArrayList<ExifTag> nullTags = new ArrayList<ExifTag>();
+        for(ExifTag t : data.getAllTags()) {
+            if (t.getValue() == null && !ExifInterface.isOffsetTag(t.getTagId())) {
+                data.removeTag(t.getTagId(), t.getIfd());
+                nullTags.add(t);
+            }
+        }
+        return nullTags;
+    }
+
+    private void writeThumbnail(OrderedDataOutputStream dataOutputStream) throws IOException {
+        if (mExifData.hasCompressedThumbnail()) {
+            dataOutputStream.write(mExifData.getCompressedThumbnail());
+        } else if (mExifData.hasUncompressedStrip()) {
+            for (int i = 0; i < mExifData.getStripCount(); i++) {
+                dataOutputStream.write(mExifData.getStrip(i));
+            }
+        }
+    }
+
+    private void writeAllTags(OrderedDataOutputStream dataOutputStream) throws IOException {
+        writeIfd(mExifData.getIfdData(IfdId.TYPE_IFD_0), dataOutputStream);
+        writeIfd(mExifData.getIfdData(IfdId.TYPE_IFD_EXIF), dataOutputStream);
+        IfdData interoperabilityIfd = mExifData.getIfdData(IfdId.TYPE_IFD_INTEROPERABILITY);
+        if (interoperabilityIfd != null) {
+            writeIfd(interoperabilityIfd, dataOutputStream);
+        }
+        IfdData gpsIfd = mExifData.getIfdData(IfdId.TYPE_IFD_GPS);
+        if (gpsIfd != null) {
+            writeIfd(gpsIfd, dataOutputStream);
+        }
+        IfdData ifd1 = mExifData.getIfdData(IfdId.TYPE_IFD_1);
+        if (ifd1 != null) {
+            writeIfd(mExifData.getIfdData(IfdId.TYPE_IFD_1), dataOutputStream);
+        }
+    }
+
+    private void writeIfd(IfdData ifd, OrderedDataOutputStream dataOutputStream)
+            throws IOException {
+        ExifTag[] tags = ifd.getAllTags();
+        dataOutputStream.writeShort((short) tags.length);
+        for (ExifTag tag : tags) {
+            dataOutputStream.writeShort(tag.getTagId());
+            dataOutputStream.writeShort(tag.getDataType());
+            dataOutputStream.writeInt(tag.getComponentCount());
+            if (DEBUG) {
+                Log.v(TAG, "\n" + tag.toString());
+            }
+            if (tag.getDataSize() > 4) {
+                dataOutputStream.writeInt(tag.getOffset());
+            } else {
+                ExifOutputStream.writeTagValue(tag, dataOutputStream);
+                for (int i = 0, n = 4 - tag.getDataSize(); i < n; i++) {
+                    dataOutputStream.write(0);
+                }
+            }
+        }
+        dataOutputStream.writeInt(ifd.getOffsetToNextIfd());
+        for (ExifTag tag : tags) {
+            if (tag.getDataSize() > 4) {
+                ExifOutputStream.writeTagValue(tag, dataOutputStream);
+            }
+        }
+    }
+
+    private int calculateOffsetOfIfd(IfdData ifd, int offset) {
+        offset += 2 + ifd.getTagCount() * TAG_SIZE + 4;
+        ExifTag[] tags = ifd.getAllTags();
+        for (ExifTag tag : tags) {
+            if (tag.getDataSize() > 4) {
+                tag.setOffset(offset);
+                offset += tag.getDataSize();
+            }
+        }
+        return offset;
+    }
+
+    private void createRequiredIfdAndTag() throws IOException {
+        // IFD0 is required for all file
+        IfdData ifd0 = mExifData.getIfdData(IfdId.TYPE_IFD_0);
+        if (ifd0 == null) {
+            ifd0 = new IfdData(IfdId.TYPE_IFD_0);
+            mExifData.addIfdData(ifd0);
+        }
+        ExifTag exifOffsetTag = mInterface.buildUninitializedTag(ExifInterface.TAG_EXIF_IFD);
+        if (exifOffsetTag == null) {
+            throw new IOException("No definition for crucial exif tag: "
+                    + ExifInterface.TAG_EXIF_IFD);
+        }
+        ifd0.setTag(exifOffsetTag);
+
+        // Exif IFD is required for all files.
+        IfdData exifIfd = mExifData.getIfdData(IfdId.TYPE_IFD_EXIF);
+        if (exifIfd == null) {
+            exifIfd = new IfdData(IfdId.TYPE_IFD_EXIF);
+            mExifData.addIfdData(exifIfd);
+        }
+
+        // GPS IFD
+        IfdData gpsIfd = mExifData.getIfdData(IfdId.TYPE_IFD_GPS);
+        if (gpsIfd != null) {
+            ExifTag gpsOffsetTag = mInterface.buildUninitializedTag(ExifInterface.TAG_GPS_IFD);
+            if (gpsOffsetTag == null) {
+                throw new IOException("No definition for crucial exif tag: "
+                        + ExifInterface.TAG_GPS_IFD);
+            }
+            ifd0.setTag(gpsOffsetTag);
+        }
+
+        // Interoperability IFD
+        IfdData interIfd = mExifData.getIfdData(IfdId.TYPE_IFD_INTEROPERABILITY);
+        if (interIfd != null) {
+            ExifTag interOffsetTag = mInterface
+                    .buildUninitializedTag(ExifInterface.TAG_INTEROPERABILITY_IFD);
+            if (interOffsetTag == null) {
+                throw new IOException("No definition for crucial exif tag: "
+                        + ExifInterface.TAG_INTEROPERABILITY_IFD);
+            }
+            exifIfd.setTag(interOffsetTag);
+        }
+
+        IfdData ifd1 = mExifData.getIfdData(IfdId.TYPE_IFD_1);
+
+        // thumbnail
+        if (mExifData.hasCompressedThumbnail()) {
+
+            if (ifd1 == null) {
+                ifd1 = new IfdData(IfdId.TYPE_IFD_1);
+                mExifData.addIfdData(ifd1);
+            }
+
+            ExifTag offsetTag = mInterface
+                    .buildUninitializedTag(ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT);
+            if (offsetTag == null) {
+                throw new IOException("No definition for crucial exif tag: "
+                        + ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT);
+            }
+
+            ifd1.setTag(offsetTag);
+            ExifTag lengthTag = mInterface
+                    .buildUninitializedTag(ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH);
+            if (lengthTag == null) {
+                throw new IOException("No definition for crucial exif tag: "
+                        + ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH);
+            }
+
+            lengthTag.setValue(mExifData.getCompressedThumbnail().length);
+            ifd1.setTag(lengthTag);
+
+            // Get rid of tags for uncompressed if they exist.
+            ifd1.removeTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_STRIP_OFFSETS));
+            ifd1.removeTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_STRIP_BYTE_COUNTS));
+        } else if (mExifData.hasUncompressedStrip()) {
+            if (ifd1 == null) {
+                ifd1 = new IfdData(IfdId.TYPE_IFD_1);
+                mExifData.addIfdData(ifd1);
+            }
+            int stripCount = mExifData.getStripCount();
+            ExifTag offsetTag = mInterface.buildUninitializedTag(ExifInterface.TAG_STRIP_OFFSETS);
+            if (offsetTag == null) {
+                throw new IOException("No definition for crucial exif tag: "
+                        + ExifInterface.TAG_STRIP_OFFSETS);
+            }
+            ExifTag lengthTag = mInterface
+                    .buildUninitializedTag(ExifInterface.TAG_STRIP_BYTE_COUNTS);
+            if (lengthTag == null) {
+                throw new IOException("No definition for crucial exif tag: "
+                        + ExifInterface.TAG_STRIP_BYTE_COUNTS);
+            }
+            long[] lengths = new long[stripCount];
+            for (int i = 0; i < mExifData.getStripCount(); i++) {
+                lengths[i] = mExifData.getStrip(i).length;
+            }
+            lengthTag.setValue(lengths);
+            ifd1.setTag(offsetTag);
+            ifd1.setTag(lengthTag);
+            // Get rid of tags for compressed if they exist.
+            ifd1.removeTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT));
+            ifd1.removeTag(ExifInterface
+                    .getTrueTagKey(ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH));
+        } else if (ifd1 != null) {
+            // Get rid of offset and length tags if there is no thumbnail.
+            ifd1.removeTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_STRIP_OFFSETS));
+            ifd1.removeTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_STRIP_BYTE_COUNTS));
+            ifd1.removeTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT));
+            ifd1.removeTag(ExifInterface
+                    .getTrueTagKey(ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH));
+        }
+    }
+
+    private int calculateAllOffset() {
+        int offset = TIFF_HEADER_SIZE;
+        IfdData ifd0 = mExifData.getIfdData(IfdId.TYPE_IFD_0);
+        offset = calculateOffsetOfIfd(ifd0, offset);
+        ifd0.getTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_EXIF_IFD)).setValue(offset);
+
+        IfdData exifIfd = mExifData.getIfdData(IfdId.TYPE_IFD_EXIF);
+        offset = calculateOffsetOfIfd(exifIfd, offset);
+
+        IfdData interIfd = mExifData.getIfdData(IfdId.TYPE_IFD_INTEROPERABILITY);
+        if (interIfd != null) {
+            exifIfd.getTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_INTEROPERABILITY_IFD))
+                    .setValue(offset);
+            offset = calculateOffsetOfIfd(interIfd, offset);
+        }
+
+        IfdData gpsIfd = mExifData.getIfdData(IfdId.TYPE_IFD_GPS);
+        if (gpsIfd != null) {
+            ifd0.getTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_GPS_IFD)).setValue(offset);
+            offset = calculateOffsetOfIfd(gpsIfd, offset);
+        }
+
+        IfdData ifd1 = mExifData.getIfdData(IfdId.TYPE_IFD_1);
+        if (ifd1 != null) {
+            ifd0.setOffsetToNextIfd(offset);
+            offset = calculateOffsetOfIfd(ifd1, offset);
+        }
+
+        // thumbnail
+        if (mExifData.hasCompressedThumbnail()) {
+            ifd1.getTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT))
+                    .setValue(offset);
+            offset += mExifData.getCompressedThumbnail().length;
+        } else if (mExifData.hasUncompressedStrip()) {
+            int stripCount = mExifData.getStripCount();
+            long[] offsets = new long[stripCount];
+            for (int i = 0; i < mExifData.getStripCount(); i++) {
+                offsets[i] = offset;
+                offset += mExifData.getStrip(i).length;
+            }
+            ifd1.getTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_STRIP_OFFSETS)).setValue(
+                    offsets);
+        }
+        return offset;
+    }
+
+    static void writeTagValue(ExifTag tag, OrderedDataOutputStream dataOutputStream)
+            throws IOException {
+        switch (tag.getDataType()) {
+            case ExifTag.TYPE_ASCII:
+                byte buf[] = tag.getStringByte();
+                if (buf.length == tag.getComponentCount()) {
+                    buf[buf.length - 1] = 0;
+                    dataOutputStream.write(buf);
+                } else {
+                    dataOutputStream.write(buf);
+                    dataOutputStream.write(0);
+                }
+                break;
+            case ExifTag.TYPE_LONG:
+            case ExifTag.TYPE_UNSIGNED_LONG:
+                for (int i = 0, n = tag.getComponentCount(); i < n; i++) {
+                    dataOutputStream.writeInt((int) tag.getValueAt(i));
+                }
+                break;
+            case ExifTag.TYPE_RATIONAL:
+            case ExifTag.TYPE_UNSIGNED_RATIONAL:
+                for (int i = 0, n = tag.getComponentCount(); i < n; i++) {
+                    dataOutputStream.writeRational(tag.getRational(i));
+                }
+                break;
+            case ExifTag.TYPE_UNDEFINED:
+            case ExifTag.TYPE_UNSIGNED_BYTE:
+                buf = new byte[tag.getComponentCount()];
+                tag.getBytes(buf);
+                dataOutputStream.write(buf);
+                break;
+            case ExifTag.TYPE_UNSIGNED_SHORT:
+                for (int i = 0, n = tag.getComponentCount(); i < n; i++) {
+                    dataOutputStream.writeShort((short) tag.getValueAt(i));
+                }
+                break;
+        }
+    }
+}
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifParser.java b/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifParser.java
new file mode 100644
index 0000000..5467d42
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifParser.java
@@ -0,0 +1,916 @@
+/*
+ * 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.gallery3d.exif;
+
+import android.util.Log;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+
+/**
+ * This class provides a low-level EXIF parsing API. Given a JPEG format
+ * InputStream, the caller can request which IFD's to read via
+ * {@link #parse(InputStream, int)} with given options.
+ * <p>
+ * Below is an example of getting EXIF data from IFD 0 and EXIF IFD using the
+ * parser.
+ *
+ * <pre>
+ * void parse() {
+ *     ExifParser parser = ExifParser.parse(mImageInputStream,
+ *             ExifParser.OPTION_IFD_0 | ExifParser.OPTIONS_IFD_EXIF);
+ *     int event = parser.next();
+ *     while (event != ExifParser.EVENT_END) {
+ *         switch (event) {
+ *             case ExifParser.EVENT_START_OF_IFD:
+ *                 break;
+ *             case ExifParser.EVENT_NEW_TAG:
+ *                 ExifTag tag = parser.getTag();
+ *                 if (!tag.hasValue()) {
+ *                     parser.registerForTagValue(tag);
+ *                 } else {
+ *                     processTag(tag);
+ *                 }
+ *                 break;
+ *             case ExifParser.EVENT_VALUE_OF_REGISTERED_TAG:
+ *                 tag = parser.getTag();
+ *                 if (tag.getDataType() != ExifTag.TYPE_UNDEFINED) {
+ *                     processTag(tag);
+ *                 }
+ *                 break;
+ *         }
+ *         event = parser.next();
+ *     }
+ * }
+ *
+ * void processTag(ExifTag tag) {
+ *     // process the tag as you like.
+ * }
+ * </pre>
+ */
+class ExifParser {
+    private static final boolean LOGV = false;
+    private static final String TAG = "ExifParser";
+    /**
+     * When the parser reaches a new IFD area. Call {@link #getCurrentIfd()} to
+     * know which IFD we are in.
+     */
+    public static final int EVENT_START_OF_IFD = 0;
+    /**
+     * When the parser reaches a new tag. Call {@link #getTag()}to get the
+     * corresponding tag.
+     */
+    public static final int EVENT_NEW_TAG = 1;
+    /**
+     * When the parser reaches the value area of tag that is registered by
+     * {@link #registerForTagValue(ExifTag)} previously. Call {@link #getTag()}
+     * to get the corresponding tag.
+     */
+    public static final int EVENT_VALUE_OF_REGISTERED_TAG = 2;
+
+    /**
+     * When the parser reaches the compressed image area.
+     */
+    public static final int EVENT_COMPRESSED_IMAGE = 3;
+    /**
+     * When the parser reaches the uncompressed image strip. Call
+     * {@link #getStripIndex()} to get the index of the strip.
+     *
+     * @see #getStripIndex()
+     * @see #getStripCount()
+     */
+    public static final int EVENT_UNCOMPRESSED_STRIP = 4;
+    /**
+     * When there is nothing more to parse.
+     */
+    public static final int EVENT_END = 5;
+
+    /**
+     * Option bit to request to parse IFD0.
+     */
+    public static final int OPTION_IFD_0 = 1 << 0;
+    /**
+     * Option bit to request to parse IFD1.
+     */
+    public static final int OPTION_IFD_1 = 1 << 1;
+    /**
+     * Option bit to request to parse Exif-IFD.
+     */
+    public static final int OPTION_IFD_EXIF = 1 << 2;
+    /**
+     * Option bit to request to parse GPS-IFD.
+     */
+    public static final int OPTION_IFD_GPS = 1 << 3;
+    /**
+     * Option bit to request to parse Interoperability-IFD.
+     */
+    public static final int OPTION_IFD_INTEROPERABILITY = 1 << 4;
+    /**
+     * Option bit to request to parse thumbnail.
+     */
+    public static final int OPTION_THUMBNAIL = 1 << 5;
+
+    protected static final int EXIF_HEADER = 0x45786966; // EXIF header "Exif"
+    protected static final short EXIF_HEADER_TAIL = (short) 0x0000; // EXIF header in APP1
+
+    // TIFF header
+    protected static final short LITTLE_ENDIAN_TAG = (short) 0x4949; // "II"
+    protected static final short BIG_ENDIAN_TAG = (short) 0x4d4d; // "MM"
+    protected static final short TIFF_HEADER_TAIL = 0x002A;
+
+    protected static final int TAG_SIZE = 12;
+    protected static final int OFFSET_SIZE = 2;
+
+    private static final Charset US_ASCII = Charset.forName("US-ASCII");
+
+    protected static final int DEFAULT_IFD0_OFFSET = 8;
+
+    private final CountedDataInputStream mTiffStream;
+    private final int mOptions;
+    private int mIfdStartOffset = 0;
+    private int mNumOfTagInIfd = 0;
+    private int mIfdType;
+    private ExifTag mTag;
+    private ImageEvent mImageEvent;
+    private int mStripCount;
+    private ExifTag mStripSizeTag;
+    private ExifTag mJpegSizeTag;
+    private boolean mNeedToParseOffsetsInCurrentIfd;
+    private boolean mContainExifData = false;
+    private int mApp1End;
+    private int mOffsetToApp1EndFromSOF = 0;
+    private byte[] mDataAboveIfd0;
+    private int mIfd0Position;
+    private int mTiffStartPosition;
+    private final ExifInterface mInterface;
+
+    private static final short TAG_EXIF_IFD = ExifInterface
+            .getTrueTagKey(ExifInterface.TAG_EXIF_IFD);
+    private static final short TAG_GPS_IFD = ExifInterface.getTrueTagKey(ExifInterface.TAG_GPS_IFD);
+    private static final short TAG_INTEROPERABILITY_IFD = ExifInterface
+            .getTrueTagKey(ExifInterface.TAG_INTEROPERABILITY_IFD);
+    private static final short TAG_JPEG_INTERCHANGE_FORMAT = ExifInterface
+            .getTrueTagKey(ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT);
+    private static final short TAG_JPEG_INTERCHANGE_FORMAT_LENGTH = ExifInterface
+            .getTrueTagKey(ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH);
+    private static final short TAG_STRIP_OFFSETS = ExifInterface
+            .getTrueTagKey(ExifInterface.TAG_STRIP_OFFSETS);
+    private static final short TAG_STRIP_BYTE_COUNTS = ExifInterface
+            .getTrueTagKey(ExifInterface.TAG_STRIP_BYTE_COUNTS);
+
+    private final TreeMap<Integer, Object> mCorrespondingEvent = new TreeMap<Integer, Object>();
+
+    private boolean isIfdRequested(int ifdType) {
+        switch (ifdType) {
+            case IfdId.TYPE_IFD_0:
+                return (mOptions & OPTION_IFD_0) != 0;
+            case IfdId.TYPE_IFD_1:
+                return (mOptions & OPTION_IFD_1) != 0;
+            case IfdId.TYPE_IFD_EXIF:
+                return (mOptions & OPTION_IFD_EXIF) != 0;
+            case IfdId.TYPE_IFD_GPS:
+                return (mOptions & OPTION_IFD_GPS) != 0;
+            case IfdId.TYPE_IFD_INTEROPERABILITY:
+                return (mOptions & OPTION_IFD_INTEROPERABILITY) != 0;
+        }
+        return false;
+    }
+
+    private boolean isThumbnailRequested() {
+        return (mOptions & OPTION_THUMBNAIL) != 0;
+    }
+
+    private ExifParser(InputStream inputStream, int options, ExifInterface iRef)
+            throws IOException, ExifInvalidFormatException {
+        if (inputStream == null) {
+            throw new IOException("Null argument inputStream to ExifParser");
+        }
+        if (LOGV) {
+            Log.v(TAG, "Reading exif...");
+        }
+        mInterface = iRef;
+        mContainExifData = seekTiffData(inputStream);
+        mTiffStream = new CountedDataInputStream(inputStream);
+        mOptions = options;
+        if (!mContainExifData) {
+            return;
+        }
+
+        parseTiffHeader();
+        long offset = mTiffStream.readUnsignedInt();
+        if (offset > Integer.MAX_VALUE) {
+            throw new ExifInvalidFormatException("Invalid offset " + offset);
+        }
+        mIfd0Position = (int) offset;
+        mIfdType = IfdId.TYPE_IFD_0;
+        if (isIfdRequested(IfdId.TYPE_IFD_0) || needToParseOffsetsInCurrentIfd()) {
+            registerIfd(IfdId.TYPE_IFD_0, offset);
+            if (offset != DEFAULT_IFD0_OFFSET) {
+                mDataAboveIfd0 = new byte[(int) offset - DEFAULT_IFD0_OFFSET];
+                read(mDataAboveIfd0);
+            }
+        }
+    }
+
+    /**
+     * Parses the the given InputStream with the given options
+     *
+     * @exception IOException
+     * @exception ExifInvalidFormatException
+     */
+    protected static ExifParser parse(InputStream inputStream, int options, ExifInterface iRef)
+            throws IOException, ExifInvalidFormatException {
+        return new ExifParser(inputStream, options, iRef);
+    }
+
+    /**
+     * Parses the the given InputStream with default options; that is, every IFD
+     * and thumbnaill will be parsed.
+     *
+     * @exception IOException
+     * @exception ExifInvalidFormatException
+     * @see #parse(InputStream, int)
+     */
+    protected static ExifParser parse(InputStream inputStream, ExifInterface iRef)
+            throws IOException, ExifInvalidFormatException {
+        return new ExifParser(inputStream, OPTION_IFD_0 | OPTION_IFD_1
+                | OPTION_IFD_EXIF | OPTION_IFD_GPS | OPTION_IFD_INTEROPERABILITY
+                | OPTION_THUMBNAIL, iRef);
+    }
+
+    /**
+     * Moves the parser forward and returns the next parsing event
+     *
+     * @exception IOException
+     * @exception ExifInvalidFormatException
+     * @see #EVENT_START_OF_IFD
+     * @see #EVENT_NEW_TAG
+     * @see #EVENT_VALUE_OF_REGISTERED_TAG
+     * @see #EVENT_COMPRESSED_IMAGE
+     * @see #EVENT_UNCOMPRESSED_STRIP
+     * @see #EVENT_END
+     */
+    protected int next() throws IOException, ExifInvalidFormatException {
+        if (!mContainExifData) {
+            return EVENT_END;
+        }
+        int offset = mTiffStream.getReadByteCount();
+        int endOfTags = mIfdStartOffset + OFFSET_SIZE + TAG_SIZE * mNumOfTagInIfd;
+        if (offset < endOfTags) {
+            mTag = readTag();
+            if (mTag == null) {
+                return next();
+            }
+            if (mNeedToParseOffsetsInCurrentIfd) {
+                checkOffsetOrImageTag(mTag);
+            }
+            return EVENT_NEW_TAG;
+        } else if (offset == endOfTags) {
+            // There is a link to ifd1 at the end of ifd0
+            if (mIfdType == IfdId.TYPE_IFD_0) {
+                long ifdOffset = readUnsignedLong();
+                if (isIfdRequested(IfdId.TYPE_IFD_1) || isThumbnailRequested()) {
+                    if (ifdOffset != 0) {
+                        registerIfd(IfdId.TYPE_IFD_1, ifdOffset);
+                    }
+                }
+            } else {
+                int offsetSize = 4;
+                // Some camera models use invalid length of the offset
+                if (mCorrespondingEvent.size() > 0) {
+                    offsetSize = mCorrespondingEvent.firstEntry().getKey() -
+                            mTiffStream.getReadByteCount();
+                }
+                if (offsetSize < 4) {
+                    Log.w(TAG, "Invalid size of link to next IFD: " + offsetSize);
+                } else {
+                    long ifdOffset = readUnsignedLong();
+                    if (ifdOffset != 0) {
+                        Log.w(TAG, "Invalid link to next IFD: " + ifdOffset);
+                    }
+                }
+            }
+        }
+        while (mCorrespondingEvent.size() != 0) {
+            Entry<Integer, Object> entry = mCorrespondingEvent.pollFirstEntry();
+            Object event = entry.getValue();
+            try {
+                skipTo(entry.getKey());
+            } catch (IOException e) {
+                Log.w(TAG, "Failed to skip to data at: " + entry.getKey() +
+                        " for " + event.getClass().getName() + ", the file may be broken.");
+                continue;
+            }
+            if (event instanceof IfdEvent) {
+                mIfdType = ((IfdEvent) event).ifd;
+                mNumOfTagInIfd = mTiffStream.readUnsignedShort();
+                mIfdStartOffset = entry.getKey();
+
+                if (mNumOfTagInIfd * TAG_SIZE + mIfdStartOffset + OFFSET_SIZE > mApp1End) {
+                    Log.w(TAG, "Invalid size of IFD " + mIfdType);
+                    return EVENT_END;
+                }
+
+                mNeedToParseOffsetsInCurrentIfd = needToParseOffsetsInCurrentIfd();
+                if (((IfdEvent) event).isRequested) {
+                    return EVENT_START_OF_IFD;
+                } else {
+                    skipRemainingTagsInCurrentIfd();
+                }
+            } else if (event instanceof ImageEvent) {
+                mImageEvent = (ImageEvent) event;
+                return mImageEvent.type;
+            } else {
+                ExifTagEvent tagEvent = (ExifTagEvent) event;
+                mTag = tagEvent.tag;
+                if (mTag.getDataType() != ExifTag.TYPE_UNDEFINED) {
+                    readFullTagValue(mTag);
+                    checkOffsetOrImageTag(mTag);
+                }
+                if (tagEvent.isRequested) {
+                    return EVENT_VALUE_OF_REGISTERED_TAG;
+                }
+            }
+        }
+        return EVENT_END;
+    }
+
+    /**
+     * Skips the tags area of current IFD, if the parser is not in the tag area,
+     * nothing will happen.
+     *
+     * @throws IOException
+     * @throws ExifInvalidFormatException
+     */
+    protected void skipRemainingTagsInCurrentIfd() throws IOException, ExifInvalidFormatException {
+        int endOfTags = mIfdStartOffset + OFFSET_SIZE + TAG_SIZE * mNumOfTagInIfd;
+        int offset = mTiffStream.getReadByteCount();
+        if (offset > endOfTags) {
+            return;
+        }
+        if (mNeedToParseOffsetsInCurrentIfd) {
+            while (offset < endOfTags) {
+                mTag = readTag();
+                offset += TAG_SIZE;
+                if (mTag == null) {
+                    continue;
+                }
+                checkOffsetOrImageTag(mTag);
+            }
+        } else {
+            skipTo(endOfTags);
+        }
+        long ifdOffset = readUnsignedLong();
+        // For ifd0, there is a link to ifd1 in the end of all tags
+        if (mIfdType == IfdId.TYPE_IFD_0
+                && (isIfdRequested(IfdId.TYPE_IFD_1) || isThumbnailRequested())) {
+            if (ifdOffset > 0) {
+                registerIfd(IfdId.TYPE_IFD_1, ifdOffset);
+            }
+        }
+    }
+
+    private boolean needToParseOffsetsInCurrentIfd() {
+        switch (mIfdType) {
+            case IfdId.TYPE_IFD_0:
+                return isIfdRequested(IfdId.TYPE_IFD_EXIF) || isIfdRequested(IfdId.TYPE_IFD_GPS)
+                        || isIfdRequested(IfdId.TYPE_IFD_INTEROPERABILITY)
+                        || isIfdRequested(IfdId.TYPE_IFD_1);
+            case IfdId.TYPE_IFD_1:
+                return isThumbnailRequested();
+            case IfdId.TYPE_IFD_EXIF:
+                // The offset to interoperability IFD is located in Exif IFD
+                return isIfdRequested(IfdId.TYPE_IFD_INTEROPERABILITY);
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * If {@link #next()} return {@link #EVENT_NEW_TAG} or
+     * {@link #EVENT_VALUE_OF_REGISTERED_TAG}, call this function to get the
+     * corresponding tag.
+     * <p>
+     * For {@link #EVENT_NEW_TAG}, the tag may not contain the value if the size
+     * of the value is greater than 4 bytes. One should call
+     * {@link ExifTag#hasValue()} to check if the tag contains value. If there
+     * is no value,call {@link #registerForTagValue(ExifTag)} to have the parser
+     * emit {@link #EVENT_VALUE_OF_REGISTERED_TAG} when it reaches the area
+     * pointed by the offset.
+     * <p>
+     * When {@link #EVENT_VALUE_OF_REGISTERED_TAG} is emitted, the value of the
+     * tag will have already been read except for tags of undefined type. For
+     * tags of undefined type, call one of the read methods to get the value.
+     *
+     * @see #registerForTagValue(ExifTag)
+     * @see #read(byte[])
+     * @see #read(byte[], int, int)
+     * @see #readLong()
+     * @see #readRational()
+     * @see #readString(int)
+     * @see #readString(int, Charset)
+     */
+    protected ExifTag getTag() {
+        return mTag;
+    }
+
+    /**
+     * Gets number of tags in the current IFD area.
+     */
+    protected int getTagCountInCurrentIfd() {
+        return mNumOfTagInIfd;
+    }
+
+    /**
+     * Gets the ID of current IFD.
+     *
+     * @see IfdId#TYPE_IFD_0
+     * @see IfdId#TYPE_IFD_1
+     * @see IfdId#TYPE_IFD_GPS
+     * @see IfdId#TYPE_IFD_INTEROPERABILITY
+     * @see IfdId#TYPE_IFD_EXIF
+     */
+    protected int getCurrentIfd() {
+        return mIfdType;
+    }
+
+    /**
+     * When receiving {@link #EVENT_UNCOMPRESSED_STRIP}, call this function to
+     * get the index of this strip.
+     *
+     * @see #getStripCount()
+     */
+    protected int getStripIndex() {
+        return mImageEvent.stripIndex;
+    }
+
+    /**
+     * When receiving {@link #EVENT_UNCOMPRESSED_STRIP}, call this function to
+     * get the number of strip data.
+     *
+     * @see #getStripIndex()
+     */
+    protected int getStripCount() {
+        return mStripCount;
+    }
+
+    /**
+     * When receiving {@link #EVENT_UNCOMPRESSED_STRIP}, call this function to
+     * get the strip size.
+     */
+    protected int getStripSize() {
+        if (mStripSizeTag == null)
+            return 0;
+        return (int) mStripSizeTag.getValueAt(0);
+    }
+
+    /**
+     * When receiving {@link #EVENT_COMPRESSED_IMAGE}, call this function to get
+     * the image data size.
+     */
+    protected int getCompressedImageSize() {
+        if (mJpegSizeTag == null) {
+            return 0;
+        }
+        return (int) mJpegSizeTag.getValueAt(0);
+    }
+
+    private void skipTo(int offset) throws IOException {
+        mTiffStream.skipTo(offset);
+        while (!mCorrespondingEvent.isEmpty() && mCorrespondingEvent.firstKey() < offset) {
+            mCorrespondingEvent.pollFirstEntry();
+        }
+    }
+
+    /**
+     * When getting {@link #EVENT_NEW_TAG} in the tag area of IFD, the tag may
+     * not contain the value if the size of the value is greater than 4 bytes.
+     * When the value is not available here, call this method so that the parser
+     * will emit {@link #EVENT_VALUE_OF_REGISTERED_TAG} when it reaches the area
+     * where the value is located.
+     *
+     * @see #EVENT_VALUE_OF_REGISTERED_TAG
+     */
+    protected void registerForTagValue(ExifTag tag) {
+        if (tag.getOffset() >= mTiffStream.getReadByteCount()) {
+            mCorrespondingEvent.put(tag.getOffset(), new ExifTagEvent(tag, true));
+        }
+    }
+
+    private void registerIfd(int ifdType, long offset) {
+        // Cast unsigned int to int since the offset is always smaller
+        // than the size of APP1 (65536)
+        mCorrespondingEvent.put((int) offset, new IfdEvent(ifdType, isIfdRequested(ifdType)));
+    }
+
+    private void registerCompressedImage(long offset) {
+        mCorrespondingEvent.put((int) offset, new ImageEvent(EVENT_COMPRESSED_IMAGE));
+    }
+
+    private void registerUncompressedStrip(int stripIndex, long offset) {
+        mCorrespondingEvent.put((int) offset, new ImageEvent(EVENT_UNCOMPRESSED_STRIP
+                , stripIndex));
+    }
+
+    private ExifTag readTag() throws IOException, ExifInvalidFormatException {
+        short tagId = mTiffStream.readShort();
+        short dataFormat = mTiffStream.readShort();
+        long numOfComp = mTiffStream.readUnsignedInt();
+        if (numOfComp > Integer.MAX_VALUE) {
+            throw new ExifInvalidFormatException(
+                    "Number of component is larger then Integer.MAX_VALUE");
+        }
+        // Some invalid image file contains invalid data type. Ignore those tags
+        if (!ExifTag.isValidType(dataFormat)) {
+            Log.w(TAG, String.format("Tag %04x: Invalid data type %d", tagId, dataFormat));
+            mTiffStream.skip(4);
+            return null;
+        }
+        // TODO: handle numOfComp overflow
+        ExifTag tag = new ExifTag(tagId, dataFormat, (int) numOfComp, mIfdType,
+                ((int) numOfComp) != ExifTag.SIZE_UNDEFINED);
+        int dataSize = tag.getDataSize();
+        if (dataSize > 4) {
+            long offset = mTiffStream.readUnsignedInt();
+            if (offset > Integer.MAX_VALUE) {
+                throw new ExifInvalidFormatException(
+                        "offset is larger then Integer.MAX_VALUE");
+            }
+            // Some invalid images put some undefined data before IFD0.
+            // Read the data here.
+            if ((offset < mIfd0Position) && (dataFormat == ExifTag.TYPE_UNDEFINED)) {
+                byte[] buf = new byte[(int) numOfComp];
+                System.arraycopy(mDataAboveIfd0, (int) offset - DEFAULT_IFD0_OFFSET,
+                        buf, 0, (int) numOfComp);
+                tag.setValue(buf);
+            } else {
+                tag.setOffset((int) offset);
+            }
+        } else {
+            boolean defCount = tag.hasDefinedCount();
+            // Set defined count to 0 so we can add \0 to non-terminated strings
+            tag.setHasDefinedCount(false);
+            // Read value
+            readFullTagValue(tag);
+            tag.setHasDefinedCount(defCount);
+            mTiffStream.skip(4 - dataSize);
+            // Set the offset to the position of value.
+            tag.setOffset(mTiffStream.getReadByteCount() - 4);
+        }
+        return tag;
+    }
+
+    /**
+     * Check the tag, if the tag is one of the offset tag that points to the IFD
+     * or image the caller is interested in, register the IFD or image.
+     */
+    private void checkOffsetOrImageTag(ExifTag tag) {
+        // Some invalid formattd image contains tag with 0 size.
+        if (tag.getComponentCount() == 0) {
+            return;
+        }
+        short tid = tag.getTagId();
+        int ifd = tag.getIfd();
+        if (tid == TAG_EXIF_IFD && checkAllowed(ifd, ExifInterface.TAG_EXIF_IFD)) {
+            if (isIfdRequested(IfdId.TYPE_IFD_EXIF)
+                    || isIfdRequested(IfdId.TYPE_IFD_INTEROPERABILITY)) {
+                registerIfd(IfdId.TYPE_IFD_EXIF, tag.getValueAt(0));
+            }
+        } else if (tid == TAG_GPS_IFD && checkAllowed(ifd, ExifInterface.TAG_GPS_IFD)) {
+            if (isIfdRequested(IfdId.TYPE_IFD_GPS)) {
+                registerIfd(IfdId.TYPE_IFD_GPS, tag.getValueAt(0));
+            }
+        } else if (tid == TAG_INTEROPERABILITY_IFD
+                && checkAllowed(ifd, ExifInterface.TAG_INTEROPERABILITY_IFD)) {
+            if (isIfdRequested(IfdId.TYPE_IFD_INTEROPERABILITY)) {
+                registerIfd(IfdId.TYPE_IFD_INTEROPERABILITY, tag.getValueAt(0));
+            }
+        } else if (tid == TAG_JPEG_INTERCHANGE_FORMAT
+                && checkAllowed(ifd, ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT)) {
+            if (isThumbnailRequested()) {
+                registerCompressedImage(tag.getValueAt(0));
+            }
+        } else if (tid == TAG_JPEG_INTERCHANGE_FORMAT_LENGTH
+                && checkAllowed(ifd, ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH)) {
+            if (isThumbnailRequested()) {
+                mJpegSizeTag = tag;
+            }
+        } else if (tid == TAG_STRIP_OFFSETS && checkAllowed(ifd, ExifInterface.TAG_STRIP_OFFSETS)) {
+            if (isThumbnailRequested()) {
+                if (tag.hasValue()) {
+                    for (int i = 0; i < tag.getComponentCount(); i++) {
+                        if (tag.getDataType() == ExifTag.TYPE_UNSIGNED_SHORT) {
+                            registerUncompressedStrip(i, tag.getValueAt(i));
+                        } else {
+                            registerUncompressedStrip(i, tag.getValueAt(i));
+                        }
+                    }
+                } else {
+                    mCorrespondingEvent.put(tag.getOffset(), new ExifTagEvent(tag, false));
+                }
+            }
+        } else if (tid == TAG_STRIP_BYTE_COUNTS
+                && checkAllowed(ifd, ExifInterface.TAG_STRIP_BYTE_COUNTS)
+                &&isThumbnailRequested() && tag.hasValue()) {
+            mStripSizeTag = tag;
+        }
+    }
+
+    private boolean checkAllowed(int ifd, int tagId) {
+        int info = mInterface.getTagInfo().get(tagId);
+        if (info == ExifInterface.DEFINITION_NULL) {
+            return false;
+        }
+        return ExifInterface.isIfdAllowed(info, ifd);
+    }
+
+    protected void readFullTagValue(ExifTag tag) throws IOException {
+        // Some invalid images contains tags with wrong size, check it here
+        short type = tag.getDataType();
+        if (type == ExifTag.TYPE_ASCII || type == ExifTag.TYPE_UNDEFINED ||
+                type == ExifTag.TYPE_UNSIGNED_BYTE) {
+            int size = tag.getComponentCount();
+            if (mCorrespondingEvent.size() > 0) {
+                if (mCorrespondingEvent.firstEntry().getKey() < mTiffStream.getReadByteCount()
+                        + size) {
+                    Object event = mCorrespondingEvent.firstEntry().getValue();
+                    if (event instanceof ImageEvent) {
+                        // Tag value overlaps thumbnail, ignore thumbnail.
+                        Log.w(TAG, "Thumbnail overlaps value for tag: \n" + tag.toString());
+                        Entry<Integer, Object> entry = mCorrespondingEvent.pollFirstEntry();
+                        Log.w(TAG, "Invalid thumbnail offset: " + entry.getKey());
+                    } else {
+                        // Tag value overlaps another tag, shorten count
+                        if (event instanceof IfdEvent) {
+                            Log.w(TAG, "Ifd " + ((IfdEvent) event).ifd
+                                    + " overlaps value for tag: \n" + tag.toString());
+                        } else if (event instanceof ExifTagEvent) {
+                            Log.w(TAG, "Tag value for tag: \n"
+                                    + ((ExifTagEvent) event).tag.toString()
+                                    + " overlaps value for tag: \n" + tag.toString());
+                        }
+                        size = mCorrespondingEvent.firstEntry().getKey()
+                                - mTiffStream.getReadByteCount();
+                        Log.w(TAG, "Invalid size of tag: \n" + tag.toString()
+                                + " setting count to: " + size);
+                        tag.forceSetComponentCount(size);
+                    }
+                }
+            }
+        }
+        switch (tag.getDataType()) {
+            case ExifTag.TYPE_UNSIGNED_BYTE:
+            case ExifTag.TYPE_UNDEFINED: {
+                byte buf[] = new byte[tag.getComponentCount()];
+                read(buf);
+                tag.setValue(buf);
+            }
+                break;
+            case ExifTag.TYPE_ASCII:
+                tag.setValue(readString(tag.getComponentCount()));
+                break;
+            case ExifTag.TYPE_UNSIGNED_LONG: {
+                long value[] = new long[tag.getComponentCount()];
+                for (int i = 0, n = value.length; i < n; i++) {
+                    value[i] = readUnsignedLong();
+                }
+                tag.setValue(value);
+            }
+                break;
+            case ExifTag.TYPE_UNSIGNED_RATIONAL: {
+                Rational value[] = new Rational[tag.getComponentCount()];
+                for (int i = 0, n = value.length; i < n; i++) {
+                    value[i] = readUnsignedRational();
+                }
+                tag.setValue(value);
+            }
+                break;
+            case ExifTag.TYPE_UNSIGNED_SHORT: {
+                int value[] = new int[tag.getComponentCount()];
+                for (int i = 0, n = value.length; i < n; i++) {
+                    value[i] = readUnsignedShort();
+                }
+                tag.setValue(value);
+            }
+                break;
+            case ExifTag.TYPE_LONG: {
+                int value[] = new int[tag.getComponentCount()];
+                for (int i = 0, n = value.length; i < n; i++) {
+                    value[i] = readLong();
+                }
+                tag.setValue(value);
+            }
+                break;
+            case ExifTag.TYPE_RATIONAL: {
+                Rational value[] = new Rational[tag.getComponentCount()];
+                for (int i = 0, n = value.length; i < n; i++) {
+                    value[i] = readRational();
+                }
+                tag.setValue(value);
+            }
+                break;
+        }
+        if (LOGV) {
+            Log.v(TAG, "\n" + tag.toString());
+        }
+    }
+
+    private void parseTiffHeader() throws IOException,
+            ExifInvalidFormatException {
+        short byteOrder = mTiffStream.readShort();
+        if (LITTLE_ENDIAN_TAG == byteOrder) {
+            mTiffStream.setByteOrder(ByteOrder.LITTLE_ENDIAN);
+        } else if (BIG_ENDIAN_TAG == byteOrder) {
+            mTiffStream.setByteOrder(ByteOrder.BIG_ENDIAN);
+        } else {
+            throw new ExifInvalidFormatException("Invalid TIFF header");
+        }
+
+        if (mTiffStream.readShort() != TIFF_HEADER_TAIL) {
+            throw new ExifInvalidFormatException("Invalid TIFF header");
+        }
+    }
+
+    private boolean seekTiffData(InputStream inputStream) throws IOException,
+            ExifInvalidFormatException {
+        CountedDataInputStream dataStream = new CountedDataInputStream(inputStream);
+        if (dataStream.readShort() != JpegHeader.SOI) {
+            throw new ExifInvalidFormatException("Invalid JPEG format");
+        }
+
+        short marker = dataStream.readShort();
+        while (marker != JpegHeader.EOI
+                && !JpegHeader.isSofMarker(marker)) {
+            int length = dataStream.readUnsignedShort();
+            // Some invalid formatted image contains multiple APP1,
+            // try to find the one with Exif data.
+            if (marker == JpegHeader.APP1) {
+                int header = 0;
+                short headerTail = 0;
+                if (length >= 8) {
+                    header = dataStream.readInt();
+                    headerTail = dataStream.readShort();
+                    length -= 6;
+                    if (header == EXIF_HEADER && headerTail == EXIF_HEADER_TAIL) {
+                        mTiffStartPosition = dataStream.getReadByteCount();
+                        mApp1End = length;
+                        mOffsetToApp1EndFromSOF = mTiffStartPosition + mApp1End;
+                        return true;
+                    }
+                }
+            }
+            if (length < 2 || (length - 2) != dataStream.skip(length - 2)) {
+                Log.w(TAG, "Invalid JPEG format.");
+                return false;
+            }
+            marker = dataStream.readShort();
+        }
+        return false;
+    }
+
+    protected int getOffsetToExifEndFromSOF() {
+        return mOffsetToApp1EndFromSOF;
+    }
+
+    protected int getTiffStartPosition() {
+        return mTiffStartPosition;
+    }
+
+    /**
+     * Reads bytes from the InputStream.
+     */
+    protected int read(byte[] buffer, int offset, int length) throws IOException {
+        return mTiffStream.read(buffer, offset, length);
+    }
+
+    /**
+     * Equivalent to read(buffer, 0, buffer.length).
+     */
+    protected int read(byte[] buffer) throws IOException {
+        return mTiffStream.read(buffer);
+    }
+
+    /**
+     * Reads a String from the InputStream with US-ASCII charset. The parser
+     * will read n bytes and convert it to ascii string. This is used for
+     * reading values of type {@link ExifTag#TYPE_ASCII}.
+     */
+    protected String readString(int n) throws IOException {
+        return readString(n, US_ASCII);
+    }
+
+    /**
+     * Reads a String from the InputStream with the given charset. The parser
+     * will read n bytes and convert it to string. This is used for reading
+     * values of type {@link ExifTag#TYPE_ASCII}.
+     */
+    protected String readString(int n, Charset charset) throws IOException {
+        if (n > 0) {
+            return mTiffStream.readString(n, charset);
+        } else {
+            return "";
+        }
+    }
+
+    /**
+     * Reads value of type {@link ExifTag#TYPE_UNSIGNED_SHORT} from the
+     * InputStream.
+     */
+    protected int readUnsignedShort() throws IOException {
+        return mTiffStream.readShort() & 0xffff;
+    }
+
+    /**
+     * Reads value of type {@link ExifTag#TYPE_UNSIGNED_LONG} from the
+     * InputStream.
+     */
+    protected long readUnsignedLong() throws IOException {
+        return readLong() & 0xffffffffL;
+    }
+
+    /**
+     * Reads value of type {@link ExifTag#TYPE_UNSIGNED_RATIONAL} from the
+     * InputStream.
+     */
+    protected Rational readUnsignedRational() throws IOException {
+        long nomi = readUnsignedLong();
+        long denomi = readUnsignedLong();
+        return new Rational(nomi, denomi);
+    }
+
+    /**
+     * Reads value of type {@link ExifTag#TYPE_LONG} from the InputStream.
+     */
+    protected int readLong() throws IOException {
+        return mTiffStream.readInt();
+    }
+
+    /**
+     * Reads value of type {@link ExifTag#TYPE_RATIONAL} from the InputStream.
+     */
+    protected Rational readRational() throws IOException {
+        int nomi = readLong();
+        int denomi = readLong();
+        return new Rational(nomi, denomi);
+    }
+
+    private static class ImageEvent {
+        int stripIndex;
+        int type;
+
+        ImageEvent(int type) {
+            this.stripIndex = 0;
+            this.type = type;
+        }
+
+        ImageEvent(int type, int stripIndex) {
+            this.type = type;
+            this.stripIndex = stripIndex;
+        }
+    }
+
+    private static class IfdEvent {
+        int ifd;
+        boolean isRequested;
+
+        IfdEvent(int ifd, boolean isInterestedIfd) {
+            this.ifd = ifd;
+            this.isRequested = isInterestedIfd;
+        }
+    }
+
+    private static class ExifTagEvent {
+        ExifTag tag;
+        boolean isRequested;
+
+        ExifTagEvent(ExifTag tag, boolean isRequireByUser) {
+            this.tag = tag;
+            this.isRequested = isRequireByUser;
+        }
+    }
+
+    /**
+     * Gets the byte order of the current InputStream.
+     */
+    protected ByteOrder getByteOrder() {
+        return mTiffStream.getByteOrder();
+    }
+}
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifReader.java b/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifReader.java
new file mode 100644
index 0000000..68e972f
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifReader.java
@@ -0,0 +1,92 @@
+/*
+ * 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.gallery3d.exif;
+
+import android.util.Log;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * This class reads the EXIF header of a JPEG file and stores it in
+ * {@link ExifData}.
+ */
+class ExifReader {
+    private static final String TAG = "ExifReader";
+
+    private final ExifInterface mInterface;
+
+    ExifReader(ExifInterface iRef) {
+        mInterface = iRef;
+    }
+
+    /**
+     * Parses the inputStream and and returns the EXIF data in an
+     * {@link ExifData}.
+     *
+     * @throws ExifInvalidFormatException
+     * @throws IOException
+     */
+    protected ExifData read(InputStream inputStream) throws ExifInvalidFormatException,
+            IOException {
+        ExifParser parser = ExifParser.parse(inputStream, mInterface);
+        ExifData exifData = new ExifData(parser.getByteOrder());
+        ExifTag tag = null;
+
+        int event = parser.next();
+        while (event != ExifParser.EVENT_END) {
+            switch (event) {
+                case ExifParser.EVENT_START_OF_IFD:
+                    exifData.addIfdData(new IfdData(parser.getCurrentIfd()));
+                    break;
+                case ExifParser.EVENT_NEW_TAG:
+                    tag = parser.getTag();
+                    if (!tag.hasValue()) {
+                        parser.registerForTagValue(tag);
+                    } else {
+                        exifData.getIfdData(tag.getIfd()).setTag(tag);
+                    }
+                    break;
+                case ExifParser.EVENT_VALUE_OF_REGISTERED_TAG:
+                    tag = parser.getTag();
+                    if (tag.getDataType() == ExifTag.TYPE_UNDEFINED) {
+                        parser.readFullTagValue(tag);
+                    }
+                    exifData.getIfdData(tag.getIfd()).setTag(tag);
+                    break;
+                case ExifParser.EVENT_COMPRESSED_IMAGE:
+                    byte buf[] = new byte[parser.getCompressedImageSize()];
+                    if (buf.length == parser.read(buf)) {
+                        exifData.setCompressedThumbnail(buf);
+                    } else {
+                        Log.w(TAG, "Failed to read the compressed thumbnail");
+                    }
+                    break;
+                case ExifParser.EVENT_UNCOMPRESSED_STRIP:
+                    buf = new byte[parser.getStripSize()];
+                    if (buf.length == parser.read(buf)) {
+                        exifData.setStripBytes(parser.getStripIndex(), buf);
+                    } else {
+                        Log.w(TAG, "Failed to read the strip bytes");
+                    }
+                    break;
+            }
+            event = parser.next();
+        }
+        return exifData;
+    }
+}
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifTag.java b/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifTag.java
new file mode 100644
index 0000000..b8b3872
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifTag.java
@@ -0,0 +1,1008 @@
+/*
+ * 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.gallery3d.exif;
+
+import java.nio.charset.Charset;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Date;
+
+/**
+ * This class stores information of an EXIF tag. For more information about
+ * defined EXIF tags, please read the Jeita EXIF 2.2 standard. Tags should be
+ * instantiated using {@link ExifInterface#buildTag}.
+ *
+ * @see ExifInterface
+ */
+public class ExifTag {
+    /**
+     * The BYTE type in the EXIF standard. An 8-bit unsigned integer.
+     */
+    public static final short TYPE_UNSIGNED_BYTE = 1;
+    /**
+     * The ASCII type in the EXIF standard. An 8-bit byte containing one 7-bit
+     * ASCII code. The final byte is terminated with NULL.
+     */
+    public static final short TYPE_ASCII = 2;
+    /**
+     * The SHORT type in the EXIF standard. A 16-bit (2-byte) unsigned integer
+     */
+    public static final short TYPE_UNSIGNED_SHORT = 3;
+    /**
+     * The LONG type in the EXIF standard. A 32-bit (4-byte) unsigned integer
+     */
+    public static final short TYPE_UNSIGNED_LONG = 4;
+    /**
+     * The RATIONAL type of EXIF standard. It consists of two LONGs. The first
+     * one is the numerator and the second one expresses the denominator.
+     */
+    public static final short TYPE_UNSIGNED_RATIONAL = 5;
+    /**
+     * The UNDEFINED type in the EXIF standard. An 8-bit byte that can take any
+     * value depending on the field definition.
+     */
+    public static final short TYPE_UNDEFINED = 7;
+    /**
+     * The SLONG type in the EXIF standard. A 32-bit (4-byte) signed integer
+     * (2's complement notation).
+     */
+    public static final short TYPE_LONG = 9;
+    /**
+     * The SRATIONAL type of EXIF standard. It consists of two SLONGs. The first
+     * one is the numerator and the second one is the denominator.
+     */
+    public static final short TYPE_RATIONAL = 10;
+
+    private static Charset US_ASCII = Charset.forName("US-ASCII");
+    private static final int TYPE_TO_SIZE_MAP[] = new int[11];
+    private static final int UNSIGNED_SHORT_MAX = 65535;
+    private static final long UNSIGNED_LONG_MAX = 4294967295L;
+    private static final long LONG_MAX = Integer.MAX_VALUE;
+    private static final long LONG_MIN = Integer.MIN_VALUE;
+
+    static {
+        TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_BYTE] = 1;
+        TYPE_TO_SIZE_MAP[TYPE_ASCII] = 1;
+        TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_SHORT] = 2;
+        TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_LONG] = 4;
+        TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_RATIONAL] = 8;
+        TYPE_TO_SIZE_MAP[TYPE_UNDEFINED] = 1;
+        TYPE_TO_SIZE_MAP[TYPE_LONG] = 4;
+        TYPE_TO_SIZE_MAP[TYPE_RATIONAL] = 8;
+    }
+
+    static final int SIZE_UNDEFINED = 0;
+
+    // Exif TagId
+    private final short mTagId;
+    // Exif Tag Type
+    private final short mDataType;
+    // If tag has defined count
+    private boolean mHasDefinedDefaultComponentCount;
+    // Actual data count in tag (should be number of elements in value array)
+    private int mComponentCountActual;
+    // The ifd that this tag should be put in
+    private int mIfd;
+    // The value (array of elements of type Tag Type)
+    private Object mValue;
+    // Value offset in exif header.
+    private int mOffset;
+
+    private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("yyyy:MM:dd kk:mm:ss");
+
+    /**
+     * Returns true if the given IFD is a valid IFD.
+     */
+    public static boolean isValidIfd(int ifdId) {
+        return ifdId == IfdId.TYPE_IFD_0 || ifdId == IfdId.TYPE_IFD_1
+                || ifdId == IfdId.TYPE_IFD_EXIF || ifdId == IfdId.TYPE_IFD_INTEROPERABILITY
+                || ifdId == IfdId.TYPE_IFD_GPS;
+    }
+
+    /**
+     * Returns true if a given type is a valid tag type.
+     */
+    public static boolean isValidType(short type) {
+        return type == TYPE_UNSIGNED_BYTE || type == TYPE_ASCII ||
+                type == TYPE_UNSIGNED_SHORT || type == TYPE_UNSIGNED_LONG ||
+                type == TYPE_UNSIGNED_RATIONAL || type == TYPE_UNDEFINED ||
+                type == TYPE_LONG || type == TYPE_RATIONAL;
+    }
+
+    // Use builtTag in ExifInterface instead of constructor.
+    ExifTag(short tagId, short type, int componentCount, int ifd,
+            boolean hasDefinedComponentCount) {
+        mTagId = tagId;
+        mDataType = type;
+        mComponentCountActual = componentCount;
+        mHasDefinedDefaultComponentCount = hasDefinedComponentCount;
+        mIfd = ifd;
+        mValue = null;
+    }
+
+    /**
+     * Gets the element size of the given data type in bytes.
+     *
+     * @see #TYPE_ASCII
+     * @see #TYPE_LONG
+     * @see #TYPE_RATIONAL
+     * @see #TYPE_UNDEFINED
+     * @see #TYPE_UNSIGNED_BYTE
+     * @see #TYPE_UNSIGNED_LONG
+     * @see #TYPE_UNSIGNED_RATIONAL
+     * @see #TYPE_UNSIGNED_SHORT
+     */
+    public static int getElementSize(short type) {
+        return TYPE_TO_SIZE_MAP[type];
+    }
+
+    /**
+     * Returns the ID of the IFD this tag belongs to.
+     *
+     * @see IfdId#TYPE_IFD_0
+     * @see IfdId#TYPE_IFD_1
+     * @see IfdId#TYPE_IFD_EXIF
+     * @see IfdId#TYPE_IFD_GPS
+     * @see IfdId#TYPE_IFD_INTEROPERABILITY
+     */
+    public int getIfd() {
+        return mIfd;
+    }
+
+    protected void setIfd(int ifdId) {
+        mIfd = ifdId;
+    }
+
+    /**
+     * Gets the TID of this tag.
+     */
+    public short getTagId() {
+        return mTagId;
+    }
+
+    /**
+     * Gets the data type of this tag
+     *
+     * @see #TYPE_ASCII
+     * @see #TYPE_LONG
+     * @see #TYPE_RATIONAL
+     * @see #TYPE_UNDEFINED
+     * @see #TYPE_UNSIGNED_BYTE
+     * @see #TYPE_UNSIGNED_LONG
+     * @see #TYPE_UNSIGNED_RATIONAL
+     * @see #TYPE_UNSIGNED_SHORT
+     */
+    public short getDataType() {
+        return mDataType;
+    }
+
+    /**
+     * Gets the total data size in bytes of the value of this tag.
+     */
+    public int getDataSize() {
+        return getComponentCount() * getElementSize(getDataType());
+    }
+
+    /**
+     * Gets the component count of this tag.
+     */
+
+    // TODO: fix integer overflows with this
+    public int getComponentCount() {
+        return mComponentCountActual;
+    }
+
+    /**
+     * Sets the component count of this tag. Call this function before
+     * setValue() if the length of value does not match the component count.
+     */
+    protected void forceSetComponentCount(int count) {
+        mComponentCountActual = count;
+    }
+
+    /**
+     * Returns true if this ExifTag contains value; otherwise, this tag will
+     * contain an offset value that is determined when the tag is written.
+     */
+    public boolean hasValue() {
+        return mValue != null;
+    }
+
+    /**
+     * Sets integer values into this tag. This method should be used for tags of
+     * type {@link #TYPE_UNSIGNED_SHORT}. This method will fail if:
+     * <ul>
+     * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_SHORT},
+     * {@link #TYPE_UNSIGNED_LONG}, or {@link #TYPE_LONG}.</li>
+     * <li>The value overflows.</li>
+     * <li>The value.length does NOT match the component count in the definition
+     * for this tag.</li>
+     * </ul>
+     */
+    public boolean setValue(int[] value) {
+        if (checkBadComponentCount(value.length)) {
+            return false;
+        }
+        if (mDataType != TYPE_UNSIGNED_SHORT && mDataType != TYPE_LONG &&
+                mDataType != TYPE_UNSIGNED_LONG) {
+            return false;
+        }
+        if (mDataType == TYPE_UNSIGNED_SHORT && checkOverflowForUnsignedShort(value)) {
+            return false;
+        } else if (mDataType == TYPE_UNSIGNED_LONG && checkOverflowForUnsignedLong(value)) {
+            return false;
+        }
+
+        long[] data = new long[value.length];
+        for (int i = 0; i < value.length; i++) {
+            data[i] = value[i];
+        }
+        mValue = data;
+        mComponentCountActual = value.length;
+        return true;
+    }
+
+    /**
+     * Sets integer value into this tag. This method should be used for tags of
+     * type {@link #TYPE_UNSIGNED_SHORT}, or {@link #TYPE_LONG}. This method
+     * will fail if:
+     * <ul>
+     * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_SHORT},
+     * {@link #TYPE_UNSIGNED_LONG}, or {@link #TYPE_LONG}.</li>
+     * <li>The value overflows.</li>
+     * <li>The component count in the definition of this tag is not 1.</li>
+     * </ul>
+     */
+    public boolean setValue(int value) {
+        return setValue(new int[] {
+                value
+        });
+    }
+
+    /**
+     * Sets long values into this tag. This method should be used for tags of
+     * type {@link #TYPE_UNSIGNED_LONG}. This method will fail if:
+     * <ul>
+     * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_LONG}.</li>
+     * <li>The value overflows.</li>
+     * <li>The value.length does NOT match the component count in the definition
+     * for this tag.</li>
+     * </ul>
+     */
+    public boolean setValue(long[] value) {
+        if (checkBadComponentCount(value.length) || mDataType != TYPE_UNSIGNED_LONG) {
+            return false;
+        }
+        if (checkOverflowForUnsignedLong(value)) {
+            return false;
+        }
+        mValue = value;
+        mComponentCountActual = value.length;
+        return true;
+    }
+
+    /**
+     * Sets long values into this tag. This method should be used for tags of
+     * type {@link #TYPE_UNSIGNED_LONG}. This method will fail if:
+     * <ul>
+     * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_LONG}.</li>
+     * <li>The value overflows.</li>
+     * <li>The component count in the definition for this tag is not 1.</li>
+     * </ul>
+     */
+    public boolean setValue(long value) {
+        return setValue(new long[] {
+                value
+        });
+    }
+
+    /**
+     * Sets a string value into this tag. This method should be used for tags of
+     * type {@link #TYPE_ASCII}. The string is converted to an ASCII string.
+     * Characters that cannot be converted are replaced with '?'. The length of
+     * the string must be equal to either (component count -1) or (component
+     * count). The final byte will be set to the string null terminator '\0',
+     * overwriting the last character in the string if the value.length is equal
+     * to the component count. This method will fail if:
+     * <ul>
+     * <li>The data type is not {@link #TYPE_ASCII} or {@link #TYPE_UNDEFINED}.</li>
+     * <li>The length of the string is not equal to (component count -1) or
+     * (component count) in the definition for this tag.</li>
+     * </ul>
+     */
+    public boolean setValue(String value) {
+        if (mDataType != TYPE_ASCII && mDataType != TYPE_UNDEFINED) {
+            return false;
+        }
+
+        byte[] buf = value.getBytes(US_ASCII);
+        byte[] finalBuf = buf;
+        if (buf.length > 0) {
+            finalBuf = (buf[buf.length - 1] == 0 || mDataType == TYPE_UNDEFINED) ? buf : Arrays
+                .copyOf(buf, buf.length + 1);
+        } else if (mDataType == TYPE_ASCII && mComponentCountActual == 1) {
+            finalBuf = new byte[] { 0 };
+        }
+        int count = finalBuf.length;
+        if (checkBadComponentCount(count)) {
+            return false;
+        }
+        mComponentCountActual = count;
+        mValue = finalBuf;
+        return true;
+    }
+
+    /**
+     * Sets Rational values into this tag. This method should be used for tags
+     * of type {@link #TYPE_UNSIGNED_RATIONAL}, or {@link #TYPE_RATIONAL}. This
+     * method will fail if:
+     * <ul>
+     * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_RATIONAL}
+     * or {@link #TYPE_RATIONAL}.</li>
+     * <li>The value overflows.</li>
+     * <li>The value.length does NOT match the component count in the definition
+     * for this tag.</li>
+     * </ul>
+     *
+     * @see Rational
+     */
+    public boolean setValue(Rational[] value) {
+        if (checkBadComponentCount(value.length)) {
+            return false;
+        }
+        if (mDataType != TYPE_UNSIGNED_RATIONAL && mDataType != TYPE_RATIONAL) {
+            return false;
+        }
+        if (mDataType == TYPE_UNSIGNED_RATIONAL && checkOverflowForUnsignedRational(value)) {
+            return false;
+        } else if (mDataType == TYPE_RATIONAL && checkOverflowForRational(value)) {
+            return false;
+        }
+
+        mValue = value;
+        mComponentCountActual = value.length;
+        return true;
+    }
+
+    /**
+     * Sets a Rational value into this tag. This method should be used for tags
+     * of type {@link #TYPE_UNSIGNED_RATIONAL}, or {@link #TYPE_RATIONAL}. This
+     * method will fail if:
+     * <ul>
+     * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_RATIONAL}
+     * or {@link #TYPE_RATIONAL}.</li>
+     * <li>The value overflows.</li>
+     * <li>The component count in the definition for this tag is not 1.</li>
+     * </ul>
+     *
+     * @see Rational
+     */
+    public boolean setValue(Rational value) {
+        return setValue(new Rational[] {
+                value
+        });
+    }
+
+    /**
+     * Sets byte values into this tag. This method should be used for tags of
+     * type {@link #TYPE_UNSIGNED_BYTE} or {@link #TYPE_UNDEFINED}. This method
+     * will fail if:
+     * <ul>
+     * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_BYTE} or
+     * {@link #TYPE_UNDEFINED} .</li>
+     * <li>The length does NOT match the component count in the definition for
+     * this tag.</li>
+     * </ul>
+     */
+    public boolean setValue(byte[] value, int offset, int length) {
+        if (checkBadComponentCount(length)) {
+            return false;
+        }
+        if (mDataType != TYPE_UNSIGNED_BYTE && mDataType != TYPE_UNDEFINED) {
+            return false;
+        }
+        mValue = new byte[length];
+        System.arraycopy(value, offset, mValue, 0, length);
+        mComponentCountActual = length;
+        return true;
+    }
+
+    /**
+     * Equivalent to setValue(value, 0, value.length).
+     */
+    public boolean setValue(byte[] value) {
+        return setValue(value, 0, value.length);
+    }
+
+    /**
+     * Sets byte value into this tag. This method should be used for tags of
+     * type {@link #TYPE_UNSIGNED_BYTE} or {@link #TYPE_UNDEFINED}. This method
+     * will fail if:
+     * <ul>
+     * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_BYTE} or
+     * {@link #TYPE_UNDEFINED} .</li>
+     * <li>The component count in the definition for this tag is not 1.</li>
+     * </ul>
+     */
+    public boolean setValue(byte value) {
+        return setValue(new byte[] {
+                value
+        });
+    }
+
+    /**
+     * Sets the value for this tag using an appropriate setValue method for the
+     * given object. This method will fail if:
+     * <ul>
+     * <li>The corresponding setValue method for the class of the object passed
+     * in would fail.</li>
+     * <li>There is no obvious way to cast the object passed in into an EXIF tag
+     * type.</li>
+     * </ul>
+     */
+    public boolean setValue(Object obj) {
+        if (obj == null) {
+            return false;
+        } else if (obj instanceof Short) {
+            return setValue(((Short) obj).shortValue() & 0x0ffff);
+        } else if (obj instanceof String) {
+            return setValue((String) obj);
+        } else if (obj instanceof int[]) {
+            return setValue((int[]) obj);
+        } else if (obj instanceof long[]) {
+            return setValue((long[]) obj);
+        } else if (obj instanceof Rational) {
+            return setValue((Rational) obj);
+        } else if (obj instanceof Rational[]) {
+            return setValue((Rational[]) obj);
+        } else if (obj instanceof byte[]) {
+            return setValue((byte[]) obj);
+        } else if (obj instanceof Integer) {
+            return setValue(((Integer) obj).intValue());
+        } else if (obj instanceof Long) {
+            return setValue(((Long) obj).longValue());
+        } else if (obj instanceof Byte) {
+            return setValue(((Byte) obj).byteValue());
+        } else if (obj instanceof Short[]) {
+            // Nulls in this array are treated as zeroes.
+            Short[] arr = (Short[]) obj;
+            int[] fin = new int[arr.length];
+            for (int i = 0; i < arr.length; i++) {
+                fin[i] = (arr[i] == null) ? 0 : arr[i].shortValue() & 0x0ffff;
+            }
+            return setValue(fin);
+        } else if (obj instanceof Integer[]) {
+            // Nulls in this array are treated as zeroes.
+            Integer[] arr = (Integer[]) obj;
+            int[] fin = new int[arr.length];
+            for (int i = 0; i < arr.length; i++) {
+                fin[i] = (arr[i] == null) ? 0 : arr[i].intValue();
+            }
+            return setValue(fin);
+        } else if (obj instanceof Long[]) {
+            // Nulls in this array are treated as zeroes.
+            Long[] arr = (Long[]) obj;
+            long[] fin = new long[arr.length];
+            for (int i = 0; i < arr.length; i++) {
+                fin[i] = (arr[i] == null) ? 0 : arr[i].longValue();
+            }
+            return setValue(fin);
+        } else if (obj instanceof Byte[]) {
+            // Nulls in this array are treated as zeroes.
+            Byte[] arr = (Byte[]) obj;
+            byte[] fin = new byte[arr.length];
+            for (int i = 0; i < arr.length; i++) {
+                fin[i] = (arr[i] == null) ? 0 : arr[i].byteValue();
+            }
+            return setValue(fin);
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Sets a timestamp to this tag. The method converts the timestamp with the
+     * format of "yyyy:MM:dd kk:mm:ss" and calls {@link #setValue(String)}. This
+     * method will fail if the data type is not {@link #TYPE_ASCII} or the
+     * component count of this tag is not 20 or undefined.
+     *
+     * @param time the number of milliseconds since Jan. 1, 1970 GMT
+     * @return true on success
+     */
+    public boolean setTimeValue(long time) {
+        // synchronized on TIME_FORMAT as SimpleDateFormat is not thread safe
+        synchronized (TIME_FORMAT) {
+            return setValue(TIME_FORMAT.format(new Date(time)));
+        }
+    }
+
+    /**
+     * Gets the value as a String. This method should be used for tags of type
+     * {@link #TYPE_ASCII}.
+     *
+     * @return the value as a String, or null if the tag's value does not exist
+     *         or cannot be converted to a String.
+     */
+    public String getValueAsString() {
+        if (mValue == null) {
+            return null;
+        } else if (mValue instanceof String) {
+            return (String) mValue;
+        } else if (mValue instanceof byte[]) {
+            return new String((byte[]) mValue, US_ASCII);
+        }
+        return null;
+    }
+
+    /**
+     * Gets the value as a String. This method should be used for tags of type
+     * {@link #TYPE_ASCII}.
+     *
+     * @param defaultValue the String to return if the tag's value does not
+     *            exist or cannot be converted to a String.
+     * @return the tag's value as a String, or the defaultValue.
+     */
+    public String getValueAsString(String defaultValue) {
+        String s = getValueAsString();
+        if (s == null) {
+            return defaultValue;
+        }
+        return s;
+    }
+
+    /**
+     * Gets the value as a byte array. This method should be used for tags of
+     * type {@link #TYPE_UNDEFINED} or {@link #TYPE_UNSIGNED_BYTE}.
+     *
+     * @return the value as a byte array, or null if the tag's value does not
+     *         exist or cannot be converted to a byte array.
+     */
+    public byte[] getValueAsBytes() {
+        if (mValue instanceof byte[]) {
+            return (byte[]) mValue;
+        }
+        return null;
+    }
+
+    /**
+     * Gets the value as a byte. If there are more than 1 bytes in this value,
+     * gets the first byte. This method should be used for tags of type
+     * {@link #TYPE_UNDEFINED} or {@link #TYPE_UNSIGNED_BYTE}.
+     *
+     * @param defaultValue the byte to return if tag's value does not exist or
+     *            cannot be converted to a byte.
+     * @return the tag's value as a byte, or the defaultValue.
+     */
+    public byte getValueAsByte(byte defaultValue) {
+        byte[] b = getValueAsBytes();
+        if (b == null || b.length < 1) {
+            return defaultValue;
+        }
+        return b[0];
+    }
+
+    /**
+     * Gets the value as an array of Rationals. This method should be used for
+     * tags of type {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}.
+     *
+     * @return the value as as an array of Rationals, or null if the tag's value
+     *         does not exist or cannot be converted to an array of Rationals.
+     */
+    public Rational[] getValueAsRationals() {
+        if (mValue instanceof Rational[]) {
+            return (Rational[]) mValue;
+        }
+        return null;
+    }
+
+    /**
+     * Gets the value as a Rational. If there are more than 1 Rationals in this
+     * value, gets the first one. This method should be used for tags of type
+     * {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}.
+     *
+     * @param defaultValue the Rational to return if tag's value does not exist
+     *            or cannot be converted to a Rational.
+     * @return the tag's value as a Rational, or the defaultValue.
+     */
+    public Rational getValueAsRational(Rational defaultValue) {
+        Rational[] r = getValueAsRationals();
+        if (r == null || r.length < 1) {
+            return defaultValue;
+        }
+        return r[0];
+    }
+
+    /**
+     * Gets the value as a Rational. If there are more than 1 Rationals in this
+     * value, gets the first one. This method should be used for tags of type
+     * {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}.
+     *
+     * @param defaultValue the numerator of the Rational to return if tag's
+     *            value does not exist or cannot be converted to a Rational (the
+     *            denominator will be 1).
+     * @return the tag's value as a Rational, or the defaultValue.
+     */
+    public Rational getValueAsRational(long defaultValue) {
+        Rational defaultVal = new Rational(defaultValue, 1);
+        return getValueAsRational(defaultVal);
+    }
+
+    /**
+     * Gets the value as an array of ints. This method should be used for tags
+     * of type {@link #TYPE_UNSIGNED_SHORT}, {@link #TYPE_UNSIGNED_LONG}.
+     *
+     * @return the value as as an array of ints, or null if the tag's value does
+     *         not exist or cannot be converted to an array of ints.
+     */
+    public int[] getValueAsInts() {
+        if (mValue == null) {
+            return null;
+        } else if (mValue instanceof long[]) {
+            long[] val = (long[]) mValue;
+            int[] arr = new int[val.length];
+            for (int i = 0; i < val.length; i++) {
+                arr[i] = (int) val[i]; // Truncates
+            }
+            return arr;
+        }
+        return null;
+    }
+
+    /**
+     * Gets the value as an int. If there are more than 1 ints in this value,
+     * gets the first one. This method should be used for tags of type
+     * {@link #TYPE_UNSIGNED_SHORT}, {@link #TYPE_UNSIGNED_LONG}.
+     *
+     * @param defaultValue the int to return if tag's value does not exist or
+     *            cannot be converted to an int.
+     * @return the tag's value as a int, or the defaultValue.
+     */
+    public int getValueAsInt(int defaultValue) {
+        int[] i = getValueAsInts();
+        if (i == null || i.length < 1) {
+            return defaultValue;
+        }
+        return i[0];
+    }
+
+    /**
+     * Gets the value as an array of longs. This method should be used for tags
+     * of type {@link #TYPE_UNSIGNED_LONG}.
+     *
+     * @return the value as as an array of longs, or null if the tag's value
+     *         does not exist or cannot be converted to an array of longs.
+     */
+    public long[] getValueAsLongs() {
+        if (mValue instanceof long[]) {
+            return (long[]) mValue;
+        }
+        return null;
+    }
+
+    /**
+     * Gets the value or null if none exists. If there are more than 1 longs in
+     * this value, gets the first one. This method should be used for tags of
+     * type {@link #TYPE_UNSIGNED_LONG}.
+     *
+     * @param defaultValue the long to return if tag's value does not exist or
+     *            cannot be converted to a long.
+     * @return the tag's value as a long, or the defaultValue.
+     */
+    public long getValueAsLong(long defaultValue) {
+        long[] l = getValueAsLongs();
+        if (l == null || l.length < 1) {
+            return defaultValue;
+        }
+        return l[0];
+    }
+
+    /**
+     * Gets the tag's value or null if none exists.
+     */
+    public Object getValue() {
+        return mValue;
+    }
+
+    /**
+     * Gets a long representation of the value.
+     *
+     * @param defaultValue value to return if there is no value or value is a
+     *            rational with a denominator of 0.
+     * @return the tag's value as a long, or defaultValue if no representation
+     *         exists.
+     */
+    public long forceGetValueAsLong(long defaultValue) {
+        long[] l = getValueAsLongs();
+        if (l != null && l.length >= 1) {
+            return l[0];
+        }
+        byte[] b = getValueAsBytes();
+        if (b != null && b.length >= 1) {
+            return b[0];
+        }
+        Rational[] r = getValueAsRationals();
+        if (r != null && r.length >= 1 && r[0].getDenominator() != 0) {
+            return (long) r[0].toDouble();
+        }
+        return defaultValue;
+    }
+
+    /**
+     * Gets a string representation of the value.
+     */
+    public String forceGetValueAsString() {
+        if (mValue == null) {
+            return "";
+        } else if (mValue instanceof byte[]) {
+            if (mDataType == TYPE_ASCII) {
+                return new String((byte[]) mValue, US_ASCII);
+            } else {
+                return Arrays.toString((byte[]) mValue);
+            }
+        } else if (mValue instanceof long[]) {
+            if (((long[]) mValue).length == 1) {
+                return String.valueOf(((long[]) mValue)[0]);
+            } else {
+                return Arrays.toString((long[]) mValue);
+            }
+        } else if (mValue instanceof Object[]) {
+            if (((Object[]) mValue).length == 1) {
+                Object val = ((Object[]) mValue)[0];
+                if (val == null) {
+                    return "";
+                } else {
+                    return val.toString();
+                }
+            } else {
+                return Arrays.toString((Object[]) mValue);
+            }
+        } else {
+            return mValue.toString();
+        }
+    }
+
+    /**
+     * Gets the value for type {@link #TYPE_ASCII}, {@link #TYPE_LONG},
+     * {@link #TYPE_UNDEFINED}, {@link #TYPE_UNSIGNED_BYTE},
+     * {@link #TYPE_UNSIGNED_LONG}, or {@link #TYPE_UNSIGNED_SHORT}. For
+     * {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}, call
+     * {@link #getRational(int)} instead.
+     *
+     * @exception IllegalArgumentException if the data type is
+     *                {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}.
+     */
+    protected long getValueAt(int index) {
+        if (mValue instanceof long[]) {
+            return ((long[]) mValue)[index];
+        } else if (mValue instanceof byte[]) {
+            return ((byte[]) mValue)[index];
+        }
+        throw new IllegalArgumentException("Cannot get integer value from "
+                + convertTypeToString(mDataType));
+    }
+
+    /**
+     * Gets the {@link #TYPE_ASCII} data.
+     *
+     * @exception IllegalArgumentException If the type is NOT
+     *                {@link #TYPE_ASCII}.
+     */
+    protected String getString() {
+        if (mDataType != TYPE_ASCII) {
+            throw new IllegalArgumentException("Cannot get ASCII value from "
+                    + convertTypeToString(mDataType));
+        }
+        return new String((byte[]) mValue, US_ASCII);
+    }
+
+    /*
+     * Get the converted ascii byte. Used by ExifOutputStream.
+     */
+    protected byte[] getStringByte() {
+        return (byte[]) mValue;
+    }
+
+    /**
+     * Gets the {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL} data.
+     *
+     * @exception IllegalArgumentException If the type is NOT
+     *                {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}.
+     */
+    protected Rational getRational(int index) {
+        if ((mDataType != TYPE_RATIONAL) && (mDataType != TYPE_UNSIGNED_RATIONAL)) {
+            throw new IllegalArgumentException("Cannot get RATIONAL value from "
+                    + convertTypeToString(mDataType));
+        }
+        return ((Rational[]) mValue)[index];
+    }
+
+    /**
+     * Equivalent to getBytes(buffer, 0, buffer.length).
+     */
+    protected void getBytes(byte[] buf) {
+        getBytes(buf, 0, buf.length);
+    }
+
+    /**
+     * Gets the {@link #TYPE_UNDEFINED} or {@link #TYPE_UNSIGNED_BYTE} data.
+     *
+     * @param buf the byte array in which to store the bytes read.
+     * @param offset the initial position in buffer to store the bytes.
+     * @param length the maximum number of bytes to store in buffer. If length >
+     *            component count, only the valid bytes will be stored.
+     * @exception IllegalArgumentException If the type is NOT
+     *                {@link #TYPE_UNDEFINED} or {@link #TYPE_UNSIGNED_BYTE}.
+     */
+    protected void getBytes(byte[] buf, int offset, int length) {
+        if ((mDataType != TYPE_UNDEFINED) && (mDataType != TYPE_UNSIGNED_BYTE)) {
+            throw new IllegalArgumentException("Cannot get BYTE value from "
+                    + convertTypeToString(mDataType));
+        }
+        System.arraycopy(mValue, 0, buf, offset,
+                (length > mComponentCountActual) ? mComponentCountActual : length);
+    }
+
+    /**
+     * Gets the offset of this tag. This is only valid if this data size > 4 and
+     * contains an offset to the location of the actual value.
+     */
+    protected int getOffset() {
+        return mOffset;
+    }
+
+    /**
+     * Sets the offset of this tag.
+     */
+    protected void setOffset(int offset) {
+        mOffset = offset;
+    }
+
+    protected void setHasDefinedCount(boolean d) {
+        mHasDefinedDefaultComponentCount = d;
+    }
+
+    protected boolean hasDefinedCount() {
+        return mHasDefinedDefaultComponentCount;
+    }
+
+    private boolean checkBadComponentCount(int count) {
+        if (mHasDefinedDefaultComponentCount && (mComponentCountActual != count)) {
+            return true;
+        }
+        return false;
+    }
+
+    private static String convertTypeToString(short type) {
+        switch (type) {
+            case TYPE_UNSIGNED_BYTE:
+                return "UNSIGNED_BYTE";
+            case TYPE_ASCII:
+                return "ASCII";
+            case TYPE_UNSIGNED_SHORT:
+                return "UNSIGNED_SHORT";
+            case TYPE_UNSIGNED_LONG:
+                return "UNSIGNED_LONG";
+            case TYPE_UNSIGNED_RATIONAL:
+                return "UNSIGNED_RATIONAL";
+            case TYPE_UNDEFINED:
+                return "UNDEFINED";
+            case TYPE_LONG:
+                return "LONG";
+            case TYPE_RATIONAL:
+                return "RATIONAL";
+            default:
+                return "";
+        }
+    }
+
+    private boolean checkOverflowForUnsignedShort(int[] value) {
+        for (int v : value) {
+            if (v > UNSIGNED_SHORT_MAX || v < 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean checkOverflowForUnsignedLong(long[] value) {
+        for (long v : value) {
+            if (v < 0 || v > UNSIGNED_LONG_MAX) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean checkOverflowForUnsignedLong(int[] value) {
+        for (int v : value) {
+            if (v < 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean checkOverflowForUnsignedRational(Rational[] value) {
+        for (Rational v : value) {
+            if (v.getNumerator() < 0 || v.getDenominator() < 0
+                    || v.getNumerator() > UNSIGNED_LONG_MAX
+                    || v.getDenominator() > UNSIGNED_LONG_MAX) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean checkOverflowForRational(Rational[] value) {
+        for (Rational v : value) {
+            if (v.getNumerator() < LONG_MIN || v.getDenominator() < LONG_MIN
+                    || v.getNumerator() > LONG_MAX
+                    || v.getDenominator() > LONG_MAX) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (obj instanceof ExifTag) {
+            ExifTag tag = (ExifTag) obj;
+            if (tag.mTagId != this.mTagId
+                    || tag.mComponentCountActual != this.mComponentCountActual
+                    || tag.mDataType != this.mDataType) {
+                return false;
+            }
+            if (mValue != null) {
+                if (tag.mValue == null) {
+                    return false;
+                } else if (mValue instanceof long[]) {
+                    if (!(tag.mValue instanceof long[])) {
+                        return false;
+                    }
+                    return Arrays.equals((long[]) mValue, (long[]) tag.mValue);
+                } else if (mValue instanceof Rational[]) {
+                    if (!(tag.mValue instanceof Rational[])) {
+                        return false;
+                    }
+                    return Arrays.equals((Rational[]) mValue, (Rational[]) tag.mValue);
+                } else if (mValue instanceof byte[]) {
+                    if (!(tag.mValue instanceof byte[])) {
+                        return false;
+                    }
+                    return Arrays.equals((byte[]) mValue, (byte[]) tag.mValue);
+                } else {
+                    return mValue.equals(tag.mValue);
+                }
+            } else {
+                return tag.mValue == null;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("tag id: %04X\n", mTagId) + "ifd id: " + mIfd + "\ntype: "
+                + convertTypeToString(mDataType) + "\ncount: " + mComponentCountActual
+                + "\noffset: " + mOffset + "\nvalue: " + forceGetValueAsString() + "\n";
+    }
+
+}
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/exif/IfdData.java b/packages/WallpaperCropper/src/com/android/gallery3d/exif/IfdData.java
new file mode 100644
index 0000000..093944a
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/exif/IfdData.java
@@ -0,0 +1,152 @@
+/*
+ * 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.gallery3d.exif;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This class stores all the tags in an IFD.
+ *
+ * @see ExifData
+ * @see ExifTag
+ */
+class IfdData {
+
+    private final int mIfdId;
+    private final Map<Short, ExifTag> mExifTags = new HashMap<Short, ExifTag>();
+    private int mOffsetToNextIfd = 0;
+    private static final int[] sIfds = {
+            IfdId.TYPE_IFD_0, IfdId.TYPE_IFD_1, IfdId.TYPE_IFD_EXIF,
+            IfdId.TYPE_IFD_INTEROPERABILITY, IfdId.TYPE_IFD_GPS
+    };
+    /**
+     * Creates an IfdData with given IFD ID.
+     *
+     * @see IfdId#TYPE_IFD_0
+     * @see IfdId#TYPE_IFD_1
+     * @see IfdId#TYPE_IFD_EXIF
+     * @see IfdId#TYPE_IFD_GPS
+     * @see IfdId#TYPE_IFD_INTEROPERABILITY
+     */
+    IfdData(int ifdId) {
+        mIfdId = ifdId;
+    }
+
+    static protected int[] getIfds() {
+        return sIfds;
+    }
+
+    /**
+     * Get a array the contains all {@link ExifTag} in this IFD.
+     */
+    protected ExifTag[] getAllTags() {
+        return mExifTags.values().toArray(new ExifTag[mExifTags.size()]);
+    }
+
+    /**
+     * Gets the ID of this IFD.
+     *
+     * @see IfdId#TYPE_IFD_0
+     * @see IfdId#TYPE_IFD_1
+     * @see IfdId#TYPE_IFD_EXIF
+     * @see IfdId#TYPE_IFD_GPS
+     * @see IfdId#TYPE_IFD_INTEROPERABILITY
+     */
+    protected int getId() {
+        return mIfdId;
+    }
+
+    /**
+     * Gets the {@link ExifTag} with given tag id. Return null if there is no
+     * such tag.
+     */
+    protected ExifTag getTag(short tagId) {
+        return mExifTags.get(tagId);
+    }
+
+    /**
+     * Adds or replaces a {@link ExifTag}.
+     */
+    protected ExifTag setTag(ExifTag tag) {
+        tag.setIfd(mIfdId);
+        return mExifTags.put(tag.getTagId(), tag);
+    }
+
+    protected boolean checkCollision(short tagId) {
+        return mExifTags.get(tagId) != null;
+    }
+
+    /**
+     * Removes the tag of the given ID
+     */
+    protected void removeTag(short tagId) {
+        mExifTags.remove(tagId);
+    }
+
+    /**
+     * Gets the tags count in the IFD.
+     */
+    protected int getTagCount() {
+        return mExifTags.size();
+    }
+
+    /**
+     * Sets the offset of next IFD.
+     */
+    protected void setOffsetToNextIfd(int offset) {
+        mOffsetToNextIfd = offset;
+    }
+
+    /**
+     * Gets the offset of next IFD.
+     */
+    protected int getOffsetToNextIfd() {
+        return mOffsetToNextIfd;
+    }
+
+    /**
+     * Returns true if all tags in this two IFDs are equal. Note that tags of
+     * IFDs offset or thumbnail offset will be ignored.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (obj instanceof IfdData) {
+            IfdData data = (IfdData) obj;
+            if (data.getId() == mIfdId && data.getTagCount() == getTagCount()) {
+                ExifTag[] tags = data.getAllTags();
+                for (ExifTag tag : tags) {
+                    if (ExifInterface.isOffsetTag(tag.getTagId())) {
+                        continue;
+                    }
+                    ExifTag tag2 = mExifTags.get(tag.getTagId());
+                    if (!tag.equals(tag2)) {
+                        return false;
+                    }
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/exif/IfdId.java b/packages/WallpaperCropper/src/com/android/gallery3d/exif/IfdId.java
new file mode 100644
index 0000000..7842edb
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/exif/IfdId.java
@@ -0,0 +1,31 @@
+/*
+ * 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.gallery3d.exif;
+
+/**
+ * The constants of the IFD ID defined in EXIF spec.
+ */
+public interface IfdId {
+    public static final int TYPE_IFD_0 = 0;
+    public static final int TYPE_IFD_1 = 1;
+    public static final int TYPE_IFD_EXIF = 2;
+    public static final int TYPE_IFD_INTEROPERABILITY = 3;
+    public static final int TYPE_IFD_GPS = 4;
+    /* This is used in ExifData to allocate enough IfdData */
+    static final int TYPE_IFD_COUNT = 5;
+
+}
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/exif/JpegHeader.java b/packages/WallpaperCropper/src/com/android/gallery3d/exif/JpegHeader.java
new file mode 100644
index 0000000..e3e787e
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/exif/JpegHeader.java
@@ -0,0 +1,39 @@
+/*
+ * 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.gallery3d.exif;
+
+class JpegHeader {
+    public static final short SOI =  (short) 0xFFD8;
+    public static final short APP1 = (short) 0xFFE1;
+    public static final short APP0 = (short) 0xFFE0;
+    public static final short EOI = (short) 0xFFD9;
+
+    /**
+     *  SOF (start of frame). All value between SOF0 and SOF15 is SOF marker except for DHT, JPG,
+     *  and DAC marker.
+     */
+    public static final short SOF0 = (short) 0xFFC0;
+    public static final short SOF15 = (short) 0xFFCF;
+    public static final short DHT = (short) 0xFFC4;
+    public static final short JPG = (short) 0xFFC8;
+    public static final short DAC = (short) 0xFFCC;
+
+    public static final boolean isSofMarker(short marker) {
+        return marker >= SOF0 && marker <= SOF15 && marker != DHT && marker != JPG
+                && marker != DAC;
+    }
+}
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/exif/OrderedDataOutputStream.java b/packages/WallpaperCropper/src/com/android/gallery3d/exif/OrderedDataOutputStream.java
new file mode 100644
index 0000000..428e6b9
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/exif/OrderedDataOutputStream.java
@@ -0,0 +1,56 @@
+/*
+ * 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.gallery3d.exif;
+
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+class OrderedDataOutputStream extends FilterOutputStream {
+    private final ByteBuffer mByteBuffer = ByteBuffer.allocate(4);
+
+    public OrderedDataOutputStream(OutputStream out) {
+        super(out);
+    }
+
+    public OrderedDataOutputStream setByteOrder(ByteOrder order) {
+        mByteBuffer.order(order);
+        return this;
+    }
+
+    public OrderedDataOutputStream writeShort(short value) throws IOException {
+        mByteBuffer.rewind();
+        mByteBuffer.putShort(value);
+        out.write(mByteBuffer.array(), 0, 2);
+        return this;
+    }
+
+    public OrderedDataOutputStream writeInt(int value) throws IOException {
+        mByteBuffer.rewind();
+        mByteBuffer.putInt(value);
+        out.write(mByteBuffer.array());
+        return this;
+    }
+
+    public OrderedDataOutputStream writeRational(Rational rational) throws IOException {
+        writeInt((int) rational.getNumerator());
+        writeInt((int) rational.getDenominator());
+        return this;
+    }
+}
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/exif/Rational.java b/packages/WallpaperCropper/src/com/android/gallery3d/exif/Rational.java
new file mode 100644
index 0000000..591d63f
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/exif/Rational.java
@@ -0,0 +1,88 @@
+/*
+ * 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.gallery3d.exif;
+
+/**
+ * The rational data type of EXIF tag. Contains a pair of longs representing the
+ * numerator and denominator of a Rational number.
+ */
+public class Rational {
+
+    private final long mNumerator;
+    private final long mDenominator;
+
+    /**
+     * Create a Rational with a given numerator and denominator.
+     *
+     * @param nominator
+     * @param denominator
+     */
+    public Rational(long nominator, long denominator) {
+        mNumerator = nominator;
+        mDenominator = denominator;
+    }
+
+    /**
+     * Create a copy of a Rational.
+     */
+    public Rational(Rational r) {
+        mNumerator = r.mNumerator;
+        mDenominator = r.mDenominator;
+    }
+
+    /**
+     * Gets the numerator of the rational.
+     */
+    public long getNumerator() {
+        return mNumerator;
+    }
+
+    /**
+     * Gets the denominator of the rational
+     */
+    public long getDenominator() {
+        return mDenominator;
+    }
+
+    /**
+     * Gets the rational value as type double. Will cause a divide-by-zero error
+     * if the denominator is 0.
+     */
+    public double toDouble() {
+        return mNumerator / (double) mDenominator;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof Rational) {
+            Rational data = (Rational) obj;
+            return mNumerator == data.mNumerator && mDenominator == data.mDenominator;
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return mNumerator + "/" + mDenominator;
+    }
+}
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/BasicTexture.java b/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/BasicTexture.java
new file mode 100644
index 0000000..2e77b90
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/BasicTexture.java
@@ -0,0 +1,212 @@
+/*
+ * 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.gallery3d.glrenderer;
+
+import android.util.Log;
+
+import com.android.gallery3d.common.Utils;
+
+import java.util.WeakHashMap;
+
+// BasicTexture is a Texture corresponds to a real GL texture.
+// The state of a BasicTexture indicates whether its data is loaded to GL memory.
+// If a BasicTexture is loaded into GL memory, it has a GL texture id.
+public abstract class BasicTexture implements Texture {
+
+    @SuppressWarnings("unused")
+    private static final String TAG = "BasicTexture";
+    protected static final int UNSPECIFIED = -1;
+
+    protected static final int STATE_UNLOADED = 0;
+    protected static final int STATE_LOADED = 1;
+    protected static final int STATE_ERROR = -1;
+
+    // Log a warning if a texture is larger along a dimension
+    private static final int MAX_TEXTURE_SIZE = 4096;
+
+    protected int mId = -1;
+    protected int mState;
+
+    protected int mWidth = UNSPECIFIED;
+    protected int mHeight = UNSPECIFIED;
+
+    protected int mTextureWidth;
+    protected int mTextureHeight;
+
+    private boolean mHasBorder;
+
+    protected GLCanvas mCanvasRef = null;
+    private static WeakHashMap<BasicTexture, Object> sAllTextures
+            = new WeakHashMap<BasicTexture, Object>();
+    private static ThreadLocal sInFinalizer = new ThreadLocal();
+
+    protected BasicTexture(GLCanvas canvas, int id, int state) {
+        setAssociatedCanvas(canvas);
+        mId = id;
+        mState = state;
+        synchronized (sAllTextures) {
+            sAllTextures.put(this, null);
+        }
+    }
+
+    protected BasicTexture() {
+        this(null, 0, STATE_UNLOADED);
+    }
+
+    protected void setAssociatedCanvas(GLCanvas canvas) {
+        mCanvasRef = canvas;
+    }
+
+    /**
+     * Sets the content size of this texture. In OpenGL, the actual texture
+     * size must be of power of 2, the size of the content may be smaller.
+     */
+    public void setSize(int width, int height) {
+        mWidth = width;
+        mHeight = height;
+        mTextureWidth = width > 0 ? Utils.nextPowerOf2(width) : 0;
+        mTextureHeight = height > 0 ? Utils.nextPowerOf2(height) : 0;
+        if (mTextureWidth > MAX_TEXTURE_SIZE || mTextureHeight > MAX_TEXTURE_SIZE) {
+            Log.w(TAG, String.format("texture is too large: %d x %d",
+                    mTextureWidth, mTextureHeight), new Exception());
+        }
+    }
+
+    public boolean isFlippedVertically() {
+      return false;
+    }
+
+    public int getId() {
+        return mId;
+    }
+
+    @Override
+    public int getWidth() {
+        return mWidth;
+    }
+
+    @Override
+    public int getHeight() {
+        return mHeight;
+    }
+
+    // Returns the width rounded to the next power of 2.
+    public int getTextureWidth() {
+        return mTextureWidth;
+    }
+
+    // Returns the height rounded to the next power of 2.
+    public int getTextureHeight() {
+        return mTextureHeight;
+    }
+
+    // Returns true if the texture has one pixel transparent border around the
+    // actual content. This is used to avoid jigged edges.
+    //
+    // The jigged edges appear because we use GL_CLAMP_TO_EDGE for texture wrap
+    // mode (GL_CLAMP is not available in OpenGL ES), so a pixel partially
+    // covered by the texture will use the color of the edge texel. If we add
+    // the transparent border, the color of the edge texel will be mixed with
+    // appropriate amount of transparent.
+    //
+    // Currently our background is black, so we can draw the thumbnails without
+    // enabling blending.
+    public boolean hasBorder() {
+        return mHasBorder;
+    }
+
+    protected void setBorder(boolean hasBorder) {
+        mHasBorder = hasBorder;
+    }
+
+    @Override
+    public void draw(GLCanvas canvas, int x, int y) {
+        canvas.drawTexture(this, x, y, getWidth(), getHeight());
+    }
+
+    @Override
+    public void draw(GLCanvas canvas, int x, int y, int w, int h) {
+        canvas.drawTexture(this, x, y, w, h);
+    }
+
+    // onBind is called before GLCanvas binds this texture.
+    // It should make sure the data is uploaded to GL memory.
+    abstract protected boolean onBind(GLCanvas canvas);
+
+    // Returns the GL texture target for this texture (e.g. GL_TEXTURE_2D).
+    abstract protected int getTarget();
+
+    public boolean isLoaded() {
+        return mState == STATE_LOADED;
+    }
+
+    // recycle() is called when the texture will never be used again,
+    // so it can free all resources.
+    public void recycle() {
+        freeResource();
+    }
+
+    // yield() is called when the texture will not be used temporarily,
+    // so it can free some resources.
+    // The default implementation unloads the texture from GL memory, so
+    // the subclass should make sure it can reload the texture to GL memory
+    // later, or it will have to override this method.
+    public void yield() {
+        freeResource();
+    }
+
+    private void freeResource() {
+        GLCanvas canvas = mCanvasRef;
+        if (canvas != null && mId != -1) {
+            canvas.unloadTexture(this);
+            mId = -1; // Don't free it again.
+        }
+        mState = STATE_UNLOADED;
+        setAssociatedCanvas(null);
+    }
+
+    @Override
+    protected void finalize() {
+        sInFinalizer.set(BasicTexture.class);
+        recycle();
+        sInFinalizer.set(null);
+    }
+
+    // This is for deciding if we can call Bitmap's recycle().
+    // We cannot call Bitmap's recycle() in finalizer because at that point
+    // the finalizer of Bitmap may already be called so recycle() will crash.
+    public static boolean inFinalizer() {
+        return sInFinalizer.get() != null;
+    }
+
+    public static void yieldAllTextures() {
+        synchronized (sAllTextures) {
+            for (BasicTexture t : sAllTextures.keySet()) {
+                t.yield();
+            }
+        }
+    }
+
+    public static void invalidateAllTextures() {
+        synchronized (sAllTextures) {
+            for (BasicTexture t : sAllTextures.keySet()) {
+                t.mState = STATE_UNLOADED;
+                t.setAssociatedCanvas(null);
+            }
+        }
+    }
+}
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/BitmapTexture.java b/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/BitmapTexture.java
new file mode 100644
index 0000000..100b0b3b
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/BitmapTexture.java
@@ -0,0 +1,54 @@
+/*
+ * 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.gallery3d.glrenderer;
+
+import android.graphics.Bitmap;
+
+import junit.framework.Assert;
+
+// BitmapTexture is a texture whose content is specified by a fixed Bitmap.
+//
+// The texture does not own the Bitmap. The user should make sure the Bitmap
+// is valid during the texture's lifetime. When the texture is recycled, it
+// does not free the Bitmap.
+public class BitmapTexture extends UploadedTexture {
+    protected Bitmap mContentBitmap;
+
+    public BitmapTexture(Bitmap bitmap) {
+        this(bitmap, false);
+    }
+
+    public BitmapTexture(Bitmap bitmap, boolean hasBorder) {
+        super(hasBorder);
+        Assert.assertTrue(bitmap != null && !bitmap.isRecycled());
+        mContentBitmap = bitmap;
+    }
+
+    @Override
+    protected void onFreeBitmap(Bitmap bitmap) {
+        // Do nothing.
+    }
+
+    @Override
+    protected Bitmap onGetBitmap() {
+        return mContentBitmap;
+    }
+
+    public Bitmap getBitmap() {
+        return mContentBitmap;
+    }
+}
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/GLCanvas.java b/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/GLCanvas.java
new file mode 100644
index 0000000..305e905
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/GLCanvas.java
@@ -0,0 +1,217 @@
+/*
+ * 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.gallery3d.glrenderer;
+
+import android.graphics.Bitmap;
+import android.graphics.Rect;
+import android.graphics.RectF;
+
+import javax.microedition.khronos.opengles.GL11;
+
+//
+// GLCanvas gives a convenient interface to draw using OpenGL.
+//
+// When a rectangle is specified in this interface, it means the region
+// [x, x+width) * [y, y+height)
+//
+public interface GLCanvas {
+
+    public GLId getGLId();
+
+    // Tells GLCanvas the size of the underlying GL surface. This should be
+    // called before first drawing and when the size of GL surface is changed.
+    // This is called by GLRoot and should not be called by the clients
+    // who only want to draw on the GLCanvas. Both width and height must be
+    // nonnegative.
+    public abstract void setSize(int width, int height);
+
+    // Clear the drawing buffers. This should only be used by GLRoot.
+    public abstract void clearBuffer();
+
+    public abstract void clearBuffer(float[] argb);
+
+    // Sets and gets the current alpha, alpha must be in [0, 1].
+    public abstract void setAlpha(float alpha);
+
+    public abstract float getAlpha();
+
+    // (current alpha) = (current alpha) * alpha
+    public abstract void multiplyAlpha(float alpha);
+
+    // Change the current transform matrix.
+    public abstract void translate(float x, float y, float z);
+
+    public abstract void translate(float x, float y);
+
+    public abstract void scale(float sx, float sy, float sz);
+
+    public abstract void rotate(float angle, float x, float y, float z);
+
+    public abstract void multiplyMatrix(float[] mMatrix, int offset);
+
+    // Pushes the configuration state (matrix, and alpha) onto
+    // a private stack.
+    public abstract void save();
+
+    // Same as save(), but only save those specified in saveFlags.
+    public abstract void save(int saveFlags);
+
+    public static final int SAVE_FLAG_ALL = 0xFFFFFFFF;
+    public static final int SAVE_FLAG_ALPHA = 0x01;
+    public static final int SAVE_FLAG_MATRIX = 0x02;
+
+    // Pops from the top of the stack as current configuration state (matrix,
+    // alpha, and clip). This call balances a previous call to save(), and is
+    // used to remove all modifications to the configuration state since the
+    // last save call.
+    public abstract void restore();
+
+    // Draws a line using the specified paint from (x1, y1) to (x2, y2).
+    // (Both end points are included).
+    public abstract void drawLine(float x1, float y1, float x2, float y2, GLPaint paint);
+
+    // Draws a rectangle using the specified paint from (x1, y1) to (x2, y2).
+    // (Both end points are included).
+    public abstract void drawRect(float x1, float y1, float x2, float y2, GLPaint paint);
+
+    // Fills the specified rectangle with the specified color.
+    public abstract void fillRect(float x, float y, float width, float height, int color);
+
+    // Draws a texture to the specified rectangle.
+    public abstract void drawTexture(
+            BasicTexture texture, int x, int y, int width, int height);
+
+    public abstract void drawMesh(BasicTexture tex, int x, int y, int xyBuffer,
+            int uvBuffer, int indexBuffer, int indexCount);
+
+    // Draws the source rectangle part of the texture to the target rectangle.
+    public abstract void drawTexture(BasicTexture texture, RectF source, RectF target);
+
+    // Draw a texture with a specified texture transform.
+    public abstract void drawTexture(BasicTexture texture, float[] mTextureTransform,
+                int x, int y, int w, int h);
+
+    // Draw two textures to the specified rectangle. The actual texture used is
+    // from * (1 - ratio) + to * ratio
+    // The two textures must have the same size.
+    public abstract void drawMixed(BasicTexture from, int toColor,
+            float ratio, int x, int y, int w, int h);
+
+    // Draw a region of a texture and a specified color to the specified
+    // rectangle. The actual color used is from * (1 - ratio) + to * ratio.
+    // The region of the texture is defined by parameter "src". The target
+    // rectangle is specified by parameter "target".
+    public abstract void drawMixed(BasicTexture from, int toColor,
+            float ratio, RectF src, RectF target);
+
+    // Unloads the specified texture from the canvas. The resource allocated
+    // to draw the texture will be released. The specified texture will return
+    // to the unloaded state. This function should be called only from
+    // BasicTexture or its descendant
+    public abstract boolean unloadTexture(BasicTexture texture);
+
+    // Delete the specified buffer object, similar to unloadTexture.
+    public abstract void deleteBuffer(int bufferId);
+
+    // Delete the textures and buffers in GL side. This function should only be
+    // called in the GL thread.
+    public abstract void deleteRecycledResources();
+
+    // Dump statistics information and clear the counters. For debug only.
+    public abstract void dumpStatisticsAndClear();
+
+    public abstract void beginRenderTarget(RawTexture texture);
+
+    public abstract void endRenderTarget();
+
+    /**
+     * Sets texture parameters to use GL_CLAMP_TO_EDGE for both
+     * GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T. Sets texture parameters to be
+     * GL_LINEAR for GL_TEXTURE_MIN_FILTER and GL_TEXTURE_MAG_FILTER.
+     * bindTexture() must be called prior to this.
+     *
+     * @param texture The texture to set parameters on.
+     */
+    public abstract void setTextureParameters(BasicTexture texture);
+
+    /**
+     * Initializes the texture to a size by calling texImage2D on it.
+     *
+     * @param texture The texture to initialize the size.
+     * @param format The texture format (e.g. GL_RGBA)
+     * @param type The texture type (e.g. GL_UNSIGNED_BYTE)
+     */
+    public abstract void initializeTextureSize(BasicTexture texture, int format, int type);
+
+    /**
+     * Initializes the texture to a size by calling texImage2D on it.
+     *
+     * @param texture The texture to initialize the size.
+     * @param bitmap The bitmap to initialize the bitmap with.
+     */
+    public abstract void initializeTexture(BasicTexture texture, Bitmap bitmap);
+
+    /**
+     * Calls glTexSubImage2D to upload a bitmap to the texture.
+     *
+     * @param texture The target texture to write to.
+     * @param xOffset Specifies a texel offset in the x direction within the
+     *            texture array.
+     * @param yOffset Specifies a texel offset in the y direction within the
+     *            texture array.
+     * @param format The texture format (e.g. GL_RGBA)
+     * @param type The texture type (e.g. GL_UNSIGNED_BYTE)
+     */
+    public abstract void texSubImage2D(BasicTexture texture, int xOffset, int yOffset,
+            Bitmap bitmap,
+            int format, int type);
+
+    /**
+     * Generates buffers and uploads the buffer data.
+     *
+     * @param buffer The buffer to upload
+     * @return The buffer ID that was generated.
+     */
+    public abstract int uploadBuffer(java.nio.FloatBuffer buffer);
+
+    /**
+     * Generates buffers and uploads the element array buffer data.
+     *
+     * @param buffer The buffer to upload
+     * @return The buffer ID that was generated.
+     */
+    public abstract int uploadBuffer(java.nio.ByteBuffer buffer);
+
+    /**
+     * After LightCycle makes GL calls, this method is called to restore the GL
+     * configuration to the one expected by GLCanvas.
+     */
+    public abstract void recoverFromLightCycle();
+
+    /**
+     * Gets the bounds given by x, y, width, and height as well as the internal
+     * matrix state. There is no special handling for non-90-degree rotations.
+     * It only considers the lower-left and upper-right corners as the bounds.
+     *
+     * @param bounds The output bounds to write to.
+     * @param x The left side of the input rectangle.
+     * @param y The bottom of the input rectangle.
+     * @param width The width of the input rectangle.
+     * @param height The height of the input rectangle.
+     */
+    public abstract void getBounds(Rect bounds, int x, int y, int width, int height);
+}
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/GLES20Canvas.java b/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/GLES20Canvas.java
new file mode 100644
index 0000000..4ead131
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/GLES20Canvas.java
@@ -0,0 +1,1009 @@
+/*
+ * 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.gallery3d.glrenderer;
+
+import android.graphics.Bitmap;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.opengl.GLES20;
+import android.opengl.GLUtils;
+import android.opengl.Matrix;
+import android.util.Log;
+
+import com.android.gallery3d.util.IntArray;
+
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+public class GLES20Canvas implements GLCanvas {
+    // ************** Constants **********************
+    private static final String TAG = GLES20Canvas.class.getSimpleName();
+    private static final int FLOAT_SIZE = Float.SIZE / Byte.SIZE;
+    private static final float OPAQUE_ALPHA = 0.95f;
+
+    private static final int COORDS_PER_VERTEX = 2;
+    private static final int VERTEX_STRIDE = COORDS_PER_VERTEX * FLOAT_SIZE;
+
+    private static final int COUNT_FILL_VERTEX = 4;
+    private static final int COUNT_LINE_VERTEX = 2;
+    private static final int COUNT_RECT_VERTEX = 4;
+    private static final int OFFSET_FILL_RECT = 0;
+    private static final int OFFSET_DRAW_LINE = OFFSET_FILL_RECT + COUNT_FILL_VERTEX;
+    private static final int OFFSET_DRAW_RECT = OFFSET_DRAW_LINE + COUNT_LINE_VERTEX;
+
+    private static final float[] BOX_COORDINATES = {
+            0, 0, // Fill rectangle
+            1, 0,
+            0, 1,
+            1, 1,
+            0, 0, // Draw line
+            1, 1,
+            0, 0, // Draw rectangle outline
+            0, 1,
+            1, 1,
+            1, 0,
+    };
+
+    private static final float[] BOUNDS_COORDINATES = {
+        0, 0, 0, 1,
+        1, 1, 0, 1,
+    };
+
+    private static final String POSITION_ATTRIBUTE = "aPosition";
+    private static final String COLOR_UNIFORM = "uColor";
+    private static final String MATRIX_UNIFORM = "uMatrix";
+    private static final String TEXTURE_MATRIX_UNIFORM = "uTextureMatrix";
+    private static final String TEXTURE_SAMPLER_UNIFORM = "uTextureSampler";
+    private static final String ALPHA_UNIFORM = "uAlpha";
+    private static final String TEXTURE_COORD_ATTRIBUTE = "aTextureCoordinate";
+
+    private static final String DRAW_VERTEX_SHADER = ""
+            + "uniform mat4 " + MATRIX_UNIFORM + ";\n"
+            + "attribute vec2 " + POSITION_ATTRIBUTE + ";\n"
+            + "void main() {\n"
+            + "  vec4 pos = vec4(" + POSITION_ATTRIBUTE + ", 0.0, 1.0);\n"
+            + "  gl_Position = " + MATRIX_UNIFORM + " * pos;\n"
+            + "}\n";
+
+    private static final String DRAW_FRAGMENT_SHADER = ""
+            + "precision mediump float;\n"
+            + "uniform vec4 " + COLOR_UNIFORM + ";\n"
+            + "void main() {\n"
+            + "  gl_FragColor = " + COLOR_UNIFORM + ";\n"
+            + "}\n";
+
+    private static final String TEXTURE_VERTEX_SHADER = ""
+            + "uniform mat4 " + MATRIX_UNIFORM + ";\n"
+            + "uniform mat4 " + TEXTURE_MATRIX_UNIFORM + ";\n"
+            + "attribute vec2 " + POSITION_ATTRIBUTE + ";\n"
+            + "varying vec2 vTextureCoord;\n"
+            + "void main() {\n"
+            + "  vec4 pos = vec4(" + POSITION_ATTRIBUTE + ", 0.0, 1.0);\n"
+            + "  gl_Position = " + MATRIX_UNIFORM + " * pos;\n"
+            + "  vTextureCoord = (" + TEXTURE_MATRIX_UNIFORM + " * pos).xy;\n"
+            + "}\n";
+
+    private static final String MESH_VERTEX_SHADER = ""
+            + "uniform mat4 " + MATRIX_UNIFORM + ";\n"
+            + "attribute vec2 " + POSITION_ATTRIBUTE + ";\n"
+            + "attribute vec2 " + TEXTURE_COORD_ATTRIBUTE + ";\n"
+            + "varying vec2 vTextureCoord;\n"
+            + "void main() {\n"
+            + "  vec4 pos = vec4(" + POSITION_ATTRIBUTE + ", 0.0, 1.0);\n"
+            + "  gl_Position = " + MATRIX_UNIFORM + " * pos;\n"
+            + "  vTextureCoord = " + TEXTURE_COORD_ATTRIBUTE + ";\n"
+            + "}\n";
+
+    private static final String TEXTURE_FRAGMENT_SHADER = ""
+            + "precision mediump float;\n"
+            + "varying vec2 vTextureCoord;\n"
+            + "uniform float " + ALPHA_UNIFORM + ";\n"
+            + "uniform sampler2D " + TEXTURE_SAMPLER_UNIFORM + ";\n"
+            + "void main() {\n"
+            + "  gl_FragColor = texture2D(" + TEXTURE_SAMPLER_UNIFORM + ", vTextureCoord);\n"
+            + "  gl_FragColor *= " + ALPHA_UNIFORM + ";\n"
+            + "}\n";
+
+    private static final String OES_TEXTURE_FRAGMENT_SHADER = ""
+            + "#extension GL_OES_EGL_image_external : require\n"
+            + "precision mediump float;\n"
+            + "varying vec2 vTextureCoord;\n"
+            + "uniform float " + ALPHA_UNIFORM + ";\n"
+            + "uniform samplerExternalOES " + TEXTURE_SAMPLER_UNIFORM + ";\n"
+            + "void main() {\n"
+            + "  gl_FragColor = texture2D(" + TEXTURE_SAMPLER_UNIFORM + ", vTextureCoord);\n"
+            + "  gl_FragColor *= " + ALPHA_UNIFORM + ";\n"
+            + "}\n";
+
+    private static final int INITIAL_RESTORE_STATE_SIZE = 8;
+    private static final int MATRIX_SIZE = 16;
+
+    // Keep track of restore state
+    private float[] mMatrices = new float[INITIAL_RESTORE_STATE_SIZE * MATRIX_SIZE];
+    private float[] mAlphas = new float[INITIAL_RESTORE_STATE_SIZE];
+    private IntArray mSaveFlags = new IntArray();
+
+    private int mCurrentAlphaIndex = 0;
+    private int mCurrentMatrixIndex = 0;
+
+    // Viewport size
+    private int mWidth;
+    private int mHeight;
+
+    // Projection matrix
+    private float[] mProjectionMatrix = new float[MATRIX_SIZE];
+
+    // Screen size for when we aren't bound to a texture
+    private int mScreenWidth;
+    private int mScreenHeight;
+
+    // GL programs
+    private int mDrawProgram;
+    private int mTextureProgram;
+    private int mOesTextureProgram;
+    private int mMeshProgram;
+
+    // GL buffer containing BOX_COORDINATES
+    private int mBoxCoordinates;
+
+    // Handle indices -- common
+    private static final int INDEX_POSITION = 0;
+    private static final int INDEX_MATRIX = 1;
+
+    // Handle indices -- draw
+    private static final int INDEX_COLOR = 2;
+
+    // Handle indices -- texture
+    private static final int INDEX_TEXTURE_MATRIX = 2;
+    private static final int INDEX_TEXTURE_SAMPLER = 3;
+    private static final int INDEX_ALPHA = 4;
+
+    // Handle indices -- mesh
+    private static final int INDEX_TEXTURE_COORD = 2;
+
+    private abstract static class ShaderParameter {
+        public int handle;
+        protected final String mName;
+
+        public ShaderParameter(String name) {
+            mName = name;
+        }
+
+        public abstract void loadHandle(int program);
+    }
+
+    private static class UniformShaderParameter extends ShaderParameter {
+        public UniformShaderParameter(String name) {
+            super(name);
+        }
+
+        @Override
+        public void loadHandle(int program) {
+            handle = GLES20.glGetUniformLocation(program, mName);
+            checkError();
+        }
+    }
+
+    private static class AttributeShaderParameter extends ShaderParameter {
+        public AttributeShaderParameter(String name) {
+            super(name);
+        }
+
+        @Override
+        public void loadHandle(int program) {
+            handle = GLES20.glGetAttribLocation(program, mName);
+            checkError();
+        }
+    }
+
+    ShaderParameter[] mDrawParameters = {
+            new AttributeShaderParameter(POSITION_ATTRIBUTE), // INDEX_POSITION
+            new UniformShaderParameter(MATRIX_UNIFORM), // INDEX_MATRIX
+            new UniformShaderParameter(COLOR_UNIFORM), // INDEX_COLOR
+    };
+    ShaderParameter[] mTextureParameters = {
+            new AttributeShaderParameter(POSITION_ATTRIBUTE), // INDEX_POSITION
+            new UniformShaderParameter(MATRIX_UNIFORM), // INDEX_MATRIX
+            new UniformShaderParameter(TEXTURE_MATRIX_UNIFORM), // INDEX_TEXTURE_MATRIX
+            new UniformShaderParameter(TEXTURE_SAMPLER_UNIFORM), // INDEX_TEXTURE_SAMPLER
+            new UniformShaderParameter(ALPHA_UNIFORM), // INDEX_ALPHA
+    };
+    ShaderParameter[] mOesTextureParameters = {
+            new AttributeShaderParameter(POSITION_ATTRIBUTE), // INDEX_POSITION
+            new UniformShaderParameter(MATRIX_UNIFORM), // INDEX_MATRIX
+            new UniformShaderParameter(TEXTURE_MATRIX_UNIFORM), // INDEX_TEXTURE_MATRIX
+            new UniformShaderParameter(TEXTURE_SAMPLER_UNIFORM), // INDEX_TEXTURE_SAMPLER
+            new UniformShaderParameter(ALPHA_UNIFORM), // INDEX_ALPHA
+    };
+    ShaderParameter[] mMeshParameters = {
+            new AttributeShaderParameter(POSITION_ATTRIBUTE), // INDEX_POSITION
+            new UniformShaderParameter(MATRIX_UNIFORM), // INDEX_MATRIX
+            new AttributeShaderParameter(TEXTURE_COORD_ATTRIBUTE), // INDEX_TEXTURE_COORD
+            new UniformShaderParameter(TEXTURE_SAMPLER_UNIFORM), // INDEX_TEXTURE_SAMPLER
+            new UniformShaderParameter(ALPHA_UNIFORM), // INDEX_ALPHA
+    };
+
+    private final IntArray mUnboundTextures = new IntArray();
+    private final IntArray mDeleteBuffers = new IntArray();
+
+    // Keep track of statistics for debugging
+    private int mCountDrawMesh = 0;
+    private int mCountTextureRect = 0;
+    private int mCountFillRect = 0;
+    private int mCountDrawLine = 0;
+
+    // Buffer for framebuffer IDs -- we keep track so we can switch the attached
+    // texture.
+    private int[] mFrameBuffer = new int[1];
+
+    // Bound textures.
+    private ArrayList<RawTexture> mTargetTextures = new ArrayList<RawTexture>();
+
+    // Temporary variables used within calculations
+    private final float[] mTempMatrix = new float[32];
+    private final float[] mTempColor = new float[4];
+    private final RectF mTempSourceRect = new RectF();
+    private final RectF mTempTargetRect = new RectF();
+    private final float[] mTempTextureMatrix = new float[MATRIX_SIZE];
+    private final int[] mTempIntArray = new int[1];
+
+    private static final GLId mGLId = new GLES20IdImpl();
+
+    public GLES20Canvas() {
+        Matrix.setIdentityM(mTempTextureMatrix, 0);
+        Matrix.setIdentityM(mMatrices, mCurrentMatrixIndex);
+        mAlphas[mCurrentAlphaIndex] = 1f;
+        mTargetTextures.add(null);
+
+        FloatBuffer boxBuffer = createBuffer(BOX_COORDINATES);
+        mBoxCoordinates = uploadBuffer(boxBuffer);
+
+        int drawVertexShader = loadShader(GLES20.GL_VERTEX_SHADER, DRAW_VERTEX_SHADER);
+        int textureVertexShader = loadShader(GLES20.GL_VERTEX_SHADER, TEXTURE_VERTEX_SHADER);
+        int meshVertexShader = loadShader(GLES20.GL_VERTEX_SHADER, MESH_VERTEX_SHADER);
+        int drawFragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, DRAW_FRAGMENT_SHADER);
+        int textureFragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, TEXTURE_FRAGMENT_SHADER);
+        int oesTextureFragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER,
+                OES_TEXTURE_FRAGMENT_SHADER);
+
+        mDrawProgram = assembleProgram(drawVertexShader, drawFragmentShader, mDrawParameters);
+        mTextureProgram = assembleProgram(textureVertexShader, textureFragmentShader,
+                mTextureParameters);
+        mOesTextureProgram = assembleProgram(textureVertexShader, oesTextureFragmentShader,
+                mOesTextureParameters);
+        mMeshProgram = assembleProgram(meshVertexShader, textureFragmentShader, mMeshParameters);
+        GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA);
+        checkError();
+    }
+
+    private static FloatBuffer createBuffer(float[] values) {
+        // First create an nio buffer, then create a VBO from it.
+        int size = values.length * FLOAT_SIZE;
+        FloatBuffer buffer = ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder())
+                .asFloatBuffer();
+        buffer.put(values, 0, values.length).position(0);
+        return buffer;
+    }
+
+    private int assembleProgram(int vertexShader, int fragmentShader, ShaderParameter[] params) {
+        int program = GLES20.glCreateProgram();
+        checkError();
+        if (program == 0) {
+            throw new RuntimeException("Cannot create GL program: " + GLES20.glGetError());
+        }
+        GLES20.glAttachShader(program, vertexShader);
+        checkError();
+        GLES20.glAttachShader(program, fragmentShader);
+        checkError();
+        GLES20.glLinkProgram(program);
+        checkError();
+        int[] mLinkStatus = mTempIntArray;
+        GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, mLinkStatus, 0);
+        if (mLinkStatus[0] != GLES20.GL_TRUE) {
+            Log.e(TAG, "Could not link program: ");
+            Log.e(TAG, GLES20.glGetProgramInfoLog(program));
+            GLES20.glDeleteProgram(program);
+            program = 0;
+        }
+        for (int i = 0; i < params.length; i++) {
+            params[i].loadHandle(program);
+        }
+        return program;
+    }
+
+    private static int loadShader(int type, String shaderCode) {
+        // create a vertex shader type (GLES20.GL_VERTEX_SHADER)
+        // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
+        int shader = GLES20.glCreateShader(type);
+
+        // add the source code to the shader and compile it
+        GLES20.glShaderSource(shader, shaderCode);
+        checkError();
+        GLES20.glCompileShader(shader);
+        checkError();
+
+        return shader;
+    }
+
+    @Override
+    public void setSize(int width, int height) {
+        mWidth = width;
+        mHeight = height;
+        GLES20.glViewport(0, 0, mWidth, mHeight);
+        checkError();
+        Matrix.setIdentityM(mMatrices, mCurrentMatrixIndex);
+        Matrix.orthoM(mProjectionMatrix, 0, 0, width, 0, height, -1, 1);
+        if (getTargetTexture() == null) {
+            mScreenWidth = width;
+            mScreenHeight = height;
+            Matrix.translateM(mMatrices, mCurrentMatrixIndex, 0, height, 0);
+            Matrix.scaleM(mMatrices, mCurrentMatrixIndex, 1, -1, 1);
+        }
+    }
+
+    @Override
+    public void clearBuffer() {
+        GLES20.glClearColor(0f, 0f, 0f, 1f);
+        checkError();
+        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
+        checkError();
+    }
+
+    @Override
+    public void clearBuffer(float[] argb) {
+        GLES20.glClearColor(argb[1], argb[2], argb[3], argb[0]);
+        checkError();
+        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
+        checkError();
+    }
+
+    @Override
+    public float getAlpha() {
+        return mAlphas[mCurrentAlphaIndex];
+    }
+
+    @Override
+    public void setAlpha(float alpha) {
+        mAlphas[mCurrentAlphaIndex] = alpha;
+    }
+
+    @Override
+    public void multiplyAlpha(float alpha) {
+        setAlpha(getAlpha() * alpha);
+    }
+
+    @Override
+    public void translate(float x, float y, float z) {
+        Matrix.translateM(mMatrices, mCurrentMatrixIndex, x, y, z);
+    }
+
+    // This is a faster version of translate(x, y, z) because
+    // (1) we knows z = 0, (2) we inline the Matrix.translateM call,
+    // (3) we unroll the loop
+    @Override
+    public void translate(float x, float y) {
+        int index = mCurrentMatrixIndex;
+        float[] m = mMatrices;
+        m[index + 12] += m[index + 0] * x + m[index + 4] * y;
+        m[index + 13] += m[index + 1] * x + m[index + 5] * y;
+        m[index + 14] += m[index + 2] * x + m[index + 6] * y;
+        m[index + 15] += m[index + 3] * x + m[index + 7] * y;
+    }
+
+    @Override
+    public void scale(float sx, float sy, float sz) {
+        Matrix.scaleM(mMatrices, mCurrentMatrixIndex, sx, sy, sz);
+    }
+
+    @Override
+    public void rotate(float angle, float x, float y, float z) {
+        if (angle == 0f) {
+            return;
+        }
+        float[] temp = mTempMatrix;
+        Matrix.setRotateM(temp, 0, angle, x, y, z);
+        float[] matrix = mMatrices;
+        int index = mCurrentMatrixIndex;
+        Matrix.multiplyMM(temp, MATRIX_SIZE, matrix, index, temp, 0);
+        System.arraycopy(temp, MATRIX_SIZE, matrix, index, MATRIX_SIZE);
+    }
+
+    @Override
+    public void multiplyMatrix(float[] matrix, int offset) {
+        float[] temp = mTempMatrix;
+        float[] currentMatrix = mMatrices;
+        int index = mCurrentMatrixIndex;
+        Matrix.multiplyMM(temp, 0, currentMatrix, index, matrix, offset);
+        System.arraycopy(temp, 0, currentMatrix, index, 16);
+    }
+
+    @Override
+    public void save() {
+        save(SAVE_FLAG_ALL);
+    }
+
+    @Override
+    public void save(int saveFlags) {
+        boolean saveAlpha = (saveFlags & SAVE_FLAG_ALPHA) == SAVE_FLAG_ALPHA;
+        if (saveAlpha) {
+            float currentAlpha = getAlpha();
+            mCurrentAlphaIndex++;
+            if (mAlphas.length <= mCurrentAlphaIndex) {
+                mAlphas = Arrays.copyOf(mAlphas, mAlphas.length * 2);
+            }
+            mAlphas[mCurrentAlphaIndex] = currentAlpha;
+        }
+        boolean saveMatrix = (saveFlags & SAVE_FLAG_MATRIX) == SAVE_FLAG_MATRIX;
+        if (saveMatrix) {
+            int currentIndex = mCurrentMatrixIndex;
+            mCurrentMatrixIndex += MATRIX_SIZE;
+            if (mMatrices.length <= mCurrentMatrixIndex) {
+                mMatrices = Arrays.copyOf(mMatrices, mMatrices.length * 2);
+            }
+            System.arraycopy(mMatrices, currentIndex, mMatrices, mCurrentMatrixIndex, MATRIX_SIZE);
+        }
+        mSaveFlags.add(saveFlags);
+    }
+
+    @Override
+    public void restore() {
+        int restoreFlags = mSaveFlags.removeLast();
+        boolean restoreAlpha = (restoreFlags & SAVE_FLAG_ALPHA) == SAVE_FLAG_ALPHA;
+        if (restoreAlpha) {
+            mCurrentAlphaIndex--;
+        }
+        boolean restoreMatrix = (restoreFlags & SAVE_FLAG_MATRIX) == SAVE_FLAG_MATRIX;
+        if (restoreMatrix) {
+            mCurrentMatrixIndex -= MATRIX_SIZE;
+        }
+    }
+
+    @Override
+    public void drawLine(float x1, float y1, float x2, float y2, GLPaint paint) {
+        draw(GLES20.GL_LINE_STRIP, OFFSET_DRAW_LINE, COUNT_LINE_VERTEX, x1, y1, x2 - x1, y2 - y1,
+                paint);
+        mCountDrawLine++;
+    }
+
+    @Override
+    public void drawRect(float x, float y, float width, float height, GLPaint paint) {
+        draw(GLES20.GL_LINE_LOOP, OFFSET_DRAW_RECT, COUNT_RECT_VERTEX, x, y, width, height, paint);
+        mCountDrawLine++;
+    }
+
+    private void draw(int type, int offset, int count, float x, float y, float width, float height,
+            GLPaint paint) {
+        draw(type, offset, count, x, y, width, height, paint.getColor(), paint.getLineWidth());
+    }
+
+    private void draw(int type, int offset, int count, float x, float y, float width, float height,
+            int color, float lineWidth) {
+        prepareDraw(offset, color, lineWidth);
+        draw(mDrawParameters, type, count, x, y, width, height);
+    }
+
+    private void prepareDraw(int offset, int color, float lineWidth) {
+        GLES20.glUseProgram(mDrawProgram);
+        checkError();
+        if (lineWidth > 0) {
+            GLES20.glLineWidth(lineWidth);
+            checkError();
+        }
+        float[] colorArray = getColor(color);
+        boolean blendingEnabled = (colorArray[3] < 1f);
+        enableBlending(blendingEnabled);
+        if (blendingEnabled) {
+            GLES20.glBlendColor(colorArray[0], colorArray[1], colorArray[2], colorArray[3]);
+            checkError();
+        }
+
+        GLES20.glUniform4fv(mDrawParameters[INDEX_COLOR].handle, 1, colorArray, 0);
+        setPosition(mDrawParameters, offset);
+        checkError();
+    }
+
+    private float[] getColor(int color) {
+        float alpha = ((color >>> 24) & 0xFF) / 255f * getAlpha();
+        float red = ((color >>> 16) & 0xFF) / 255f * alpha;
+        float green = ((color >>> 8) & 0xFF) / 255f * alpha;
+        float blue = (color & 0xFF) / 255f * alpha;
+        mTempColor[0] = red;
+        mTempColor[1] = green;
+        mTempColor[2] = blue;
+        mTempColor[3] = alpha;
+        return mTempColor;
+    }
+
+    private void enableBlending(boolean enableBlending) {
+        if (enableBlending) {
+            GLES20.glEnable(GLES20.GL_BLEND);
+            checkError();
+        } else {
+            GLES20.glDisable(GLES20.GL_BLEND);
+            checkError();
+        }
+    }
+
+    private void setPosition(ShaderParameter[] params, int offset) {
+        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mBoxCoordinates);
+        checkError();
+        GLES20.glVertexAttribPointer(params[INDEX_POSITION].handle, COORDS_PER_VERTEX,
+                GLES20.GL_FLOAT, false, VERTEX_STRIDE, offset * VERTEX_STRIDE);
+        checkError();
+        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
+        checkError();
+    }
+
+    private void draw(ShaderParameter[] params, int type, int count, float x, float y, float width,
+            float height) {
+        setMatrix(params, x, y, width, height);
+        int positionHandle = params[INDEX_POSITION].handle;
+        GLES20.glEnableVertexAttribArray(positionHandle);
+        checkError();
+        GLES20.glDrawArrays(type, 0, count);
+        checkError();
+        GLES20.glDisableVertexAttribArray(positionHandle);
+        checkError();
+    }
+
+    private void setMatrix(ShaderParameter[] params, float x, float y, float width, float height) {
+        Matrix.translateM(mTempMatrix, 0, mMatrices, mCurrentMatrixIndex, x, y, 0f);
+        Matrix.scaleM(mTempMatrix, 0, width, height, 1f);
+        Matrix.multiplyMM(mTempMatrix, MATRIX_SIZE, mProjectionMatrix, 0, mTempMatrix, 0);
+        GLES20.glUniformMatrix4fv(params[INDEX_MATRIX].handle, 1, false, mTempMatrix, MATRIX_SIZE);
+        checkError();
+    }
+
+    @Override
+    public void fillRect(float x, float y, float width, float height, int color) {
+        draw(GLES20.GL_TRIANGLE_STRIP, OFFSET_FILL_RECT, COUNT_FILL_VERTEX, x, y, width, height,
+                color, 0f);
+        mCountFillRect++;
+    }
+
+    @Override
+    public void drawTexture(BasicTexture texture, int x, int y, int width, int height) {
+        if (width <= 0 || height <= 0) {
+            return;
+        }
+        copyTextureCoordinates(texture, mTempSourceRect);
+        mTempTargetRect.set(x, y, x + width, y + height);
+        convertCoordinate(mTempSourceRect, mTempTargetRect, texture);
+        drawTextureRect(texture, mTempSourceRect, mTempTargetRect);
+    }
+
+    private static void copyTextureCoordinates(BasicTexture texture, RectF outRect) {
+        int left = 0;
+        int top = 0;
+        int right = texture.getWidth();
+        int bottom = texture.getHeight();
+        if (texture.hasBorder()) {
+            left = 1;
+            top = 1;
+            right -= 1;
+            bottom -= 1;
+        }
+        outRect.set(left, top, right, bottom);
+    }
+
+    @Override
+    public void drawTexture(BasicTexture texture, RectF source, RectF target) {
+        if (target.width() <= 0 || target.height() <= 0) {
+            return;
+        }
+        mTempSourceRect.set(source);
+        mTempTargetRect.set(target);
+
+        convertCoordinate(mTempSourceRect, mTempTargetRect, texture);
+        drawTextureRect(texture, mTempSourceRect, mTempTargetRect);
+    }
+
+    @Override
+    public void drawTexture(BasicTexture texture, float[] textureTransform, int x, int y, int w,
+            int h) {
+        if (w <= 0 || h <= 0) {
+            return;
+        }
+        mTempTargetRect.set(x, y, x + w, y + h);
+        drawTextureRect(texture, textureTransform, mTempTargetRect);
+    }
+
+    private void drawTextureRect(BasicTexture texture, RectF source, RectF target) {
+        setTextureMatrix(source);
+        drawTextureRect(texture, mTempTextureMatrix, target);
+    }
+
+    private void setTextureMatrix(RectF source) {
+        mTempTextureMatrix[0] = source.width();
+        mTempTextureMatrix[5] = source.height();
+        mTempTextureMatrix[12] = source.left;
+        mTempTextureMatrix[13] = source.top;
+    }
+
+    // This function changes the source coordinate to the texture coordinates.
+    // It also clips the source and target coordinates if it is beyond the
+    // bound of the texture.
+    private static void convertCoordinate(RectF source, RectF target, BasicTexture texture) {
+        int width = texture.getWidth();
+        int height = texture.getHeight();
+        int texWidth = texture.getTextureWidth();
+        int texHeight = texture.getTextureHeight();
+        // Convert to texture coordinates
+        source.left /= texWidth;
+        source.right /= texWidth;
+        source.top /= texHeight;
+        source.bottom /= texHeight;
+
+        // Clip if the rendering range is beyond the bound of the texture.
+        float xBound = (float) width / texWidth;
+        if (source.right > xBound) {
+            target.right = target.left + target.width() * (xBound - source.left) / source.width();
+            source.right = xBound;
+        }
+        float yBound = (float) height / texHeight;
+        if (source.bottom > yBound) {
+            target.bottom = target.top + target.height() * (yBound - source.top) / source.height();
+            source.bottom = yBound;
+        }
+    }
+
+    private void drawTextureRect(BasicTexture texture, float[] textureMatrix, RectF target) {
+        ShaderParameter[] params = prepareTexture(texture);
+        setPosition(params, OFFSET_FILL_RECT);
+        GLES20.glUniformMatrix4fv(params[INDEX_TEXTURE_MATRIX].handle, 1, false, textureMatrix, 0);
+        checkError();
+        if (texture.isFlippedVertically()) {
+            save(SAVE_FLAG_MATRIX);
+            translate(0, target.centerY());
+            scale(1, -1, 1);
+            translate(0, -target.centerY());
+        }
+        draw(params, GLES20.GL_TRIANGLE_STRIP, COUNT_FILL_VERTEX, target.left, target.top,
+                target.width(), target.height());
+        if (texture.isFlippedVertically()) {
+            restore();
+        }
+        mCountTextureRect++;
+    }
+
+    private ShaderParameter[] prepareTexture(BasicTexture texture) {
+        ShaderParameter[] params;
+        int program;
+        if (texture.getTarget() == GLES20.GL_TEXTURE_2D) {
+            params = mTextureParameters;
+            program = mTextureProgram;
+        } else {
+            params = mOesTextureParameters;
+            program = mOesTextureProgram;
+        }
+        prepareTexture(texture, program, params);
+        return params;
+    }
+
+    private void prepareTexture(BasicTexture texture, int program, ShaderParameter[] params) {
+        GLES20.glUseProgram(program);
+        checkError();
+        enableBlending(!texture.isOpaque() || getAlpha() < OPAQUE_ALPHA);
+        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
+        checkError();
+        texture.onBind(this);
+        GLES20.glBindTexture(texture.getTarget(), texture.getId());
+        checkError();
+        GLES20.glUniform1i(params[INDEX_TEXTURE_SAMPLER].handle, 0);
+        checkError();
+        GLES20.glUniform1f(params[INDEX_ALPHA].handle, getAlpha());
+        checkError();
+    }
+
+    @Override
+    public void drawMesh(BasicTexture texture, int x, int y, int xyBuffer, int uvBuffer,
+            int indexBuffer, int indexCount) {
+        prepareTexture(texture, mMeshProgram, mMeshParameters);
+
+        GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
+        checkError();
+
+        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, xyBuffer);
+        checkError();
+        int positionHandle = mMeshParameters[INDEX_POSITION].handle;
+        GLES20.glVertexAttribPointer(positionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false,
+                VERTEX_STRIDE, 0);
+        checkError();
+
+        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, uvBuffer);
+        checkError();
+        int texCoordHandle = mMeshParameters[INDEX_TEXTURE_COORD].handle;
+        GLES20.glVertexAttribPointer(texCoordHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT,
+                false, VERTEX_STRIDE, 0);
+        checkError();
+        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
+        checkError();
+
+        GLES20.glEnableVertexAttribArray(positionHandle);
+        checkError();
+        GLES20.glEnableVertexAttribArray(texCoordHandle);
+        checkError();
+
+        setMatrix(mMeshParameters, x, y, 1, 1);
+        GLES20.glDrawElements(GLES20.GL_TRIANGLE_STRIP, indexCount, GLES20.GL_UNSIGNED_BYTE, 0);
+        checkError();
+
+        GLES20.glDisableVertexAttribArray(positionHandle);
+        checkError();
+        GLES20.glDisableVertexAttribArray(texCoordHandle);
+        checkError();
+        GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
+        checkError();
+        mCountDrawMesh++;
+    }
+
+    @Override
+    public void drawMixed(BasicTexture texture, int toColor, float ratio, int x, int y, int w, int h) {
+        copyTextureCoordinates(texture, mTempSourceRect);
+        mTempTargetRect.set(x, y, x + w, y + h);
+        drawMixed(texture, toColor, ratio, mTempSourceRect, mTempTargetRect);
+    }
+
+    @Override
+    public void drawMixed(BasicTexture texture, int toColor, float ratio, RectF source, RectF target) {
+        if (target.width() <= 0 || target.height() <= 0) {
+            return;
+        }
+        save(SAVE_FLAG_ALPHA);
+
+        float currentAlpha = getAlpha();
+        float cappedRatio = Math.min(1f, Math.max(0f, ratio));
+
+        float textureAlpha = (1f - cappedRatio) * currentAlpha;
+        setAlpha(textureAlpha);
+        drawTexture(texture, source, target);
+
+        float colorAlpha = cappedRatio * currentAlpha;
+        setAlpha(colorAlpha);
+        fillRect(target.left, target.top, target.width(), target.height(), toColor);
+
+        restore();
+    }
+
+    @Override
+    public boolean unloadTexture(BasicTexture texture) {
+        boolean unload = texture.isLoaded();
+        if (unload) {
+            synchronized (mUnboundTextures) {
+                mUnboundTextures.add(texture.getId());
+            }
+        }
+        return unload;
+    }
+
+    @Override
+    public void deleteBuffer(int bufferId) {
+        synchronized (mUnboundTextures) {
+            mDeleteBuffers.add(bufferId);
+        }
+    }
+
+    @Override
+    public void deleteRecycledResources() {
+        synchronized (mUnboundTextures) {
+            IntArray ids = mUnboundTextures;
+            if (mUnboundTextures.size() > 0) {
+                mGLId.glDeleteTextures(null, ids.size(), ids.getInternalArray(), 0);
+                ids.clear();
+            }
+
+            ids = mDeleteBuffers;
+            if (ids.size() > 0) {
+                mGLId.glDeleteBuffers(null, ids.size(), ids.getInternalArray(), 0);
+                ids.clear();
+            }
+        }
+    }
+
+    @Override
+    public void dumpStatisticsAndClear() {
+        String line = String.format("MESH:%d, TEX_RECT:%d, FILL_RECT:%d, LINE:%d", mCountDrawMesh,
+                mCountTextureRect, mCountFillRect, mCountDrawLine);
+        mCountDrawMesh = 0;
+        mCountTextureRect = 0;
+        mCountFillRect = 0;
+        mCountDrawLine = 0;
+        Log.d(TAG, line);
+    }
+
+    @Override
+    public void endRenderTarget() {
+        RawTexture oldTexture = mTargetTextures.remove(mTargetTextures.size() - 1);
+        RawTexture texture = getTargetTexture();
+        setRenderTarget(oldTexture, texture);
+        restore(); // restore matrix and alpha
+    }
+
+    @Override
+    public void beginRenderTarget(RawTexture texture) {
+        save(); // save matrix and alpha and blending
+        RawTexture oldTexture = getTargetTexture();
+        mTargetTextures.add(texture);
+        setRenderTarget(oldTexture, texture);
+    }
+
+    private RawTexture getTargetTexture() {
+        return mTargetTextures.get(mTargetTextures.size() - 1);
+    }
+
+    private void setRenderTarget(BasicTexture oldTexture, RawTexture texture) {
+        if (oldTexture == null && texture != null) {
+            GLES20.glGenFramebuffers(1, mFrameBuffer, 0);
+            checkError();
+            GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mFrameBuffer[0]);
+            checkError();
+        } else if (oldTexture != null && texture == null) {
+            GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
+            checkError();
+            GLES20.glDeleteFramebuffers(1, mFrameBuffer, 0);
+            checkError();
+        }
+
+        if (texture == null) {
+            setSize(mScreenWidth, mScreenHeight);
+        } else {
+            setSize(texture.getWidth(), texture.getHeight());
+
+            if (!texture.isLoaded()) {
+                texture.prepare(this);
+            }
+
+            GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0,
+                    texture.getTarget(), texture.getId(), 0);
+            checkError();
+
+            checkFramebufferStatus();
+        }
+    }
+
+    private static void checkFramebufferStatus() {
+        int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER);
+        if (status != GLES20.GL_FRAMEBUFFER_COMPLETE) {
+            String msg = "";
+            switch (status) {
+                case GLES20.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
+                    msg = "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
+                    break;
+                case GLES20.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
+                    msg = "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS";
+                    break;
+                case GLES20.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
+                    msg = "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
+                    break;
+                case GLES20.GL_FRAMEBUFFER_UNSUPPORTED:
+                    msg = "GL_FRAMEBUFFER_UNSUPPORTED";
+                    break;
+            }
+            throw new RuntimeException(msg + ":" + Integer.toHexString(status));
+        }
+    }
+
+    @Override
+    public void setTextureParameters(BasicTexture texture) {
+        int target = texture.getTarget();
+        GLES20.glBindTexture(target, texture.getId());
+        checkError();
+        GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
+        GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
+        GLES20.glTexParameterf(target, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
+        GLES20.glTexParameterf(target, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
+    }
+
+    @Override
+    public void initializeTextureSize(BasicTexture texture, int format, int type) {
+        int target = texture.getTarget();
+        GLES20.glBindTexture(target, texture.getId());
+        checkError();
+        int width = texture.getTextureWidth();
+        int height = texture.getTextureHeight();
+        GLES20.glTexImage2D(target, 0, format, width, height, 0, format, type, null);
+    }
+
+    @Override
+    public void initializeTexture(BasicTexture texture, Bitmap bitmap) {
+        int target = texture.getTarget();
+        GLES20.glBindTexture(target, texture.getId());
+        checkError();
+        GLUtils.texImage2D(target, 0, bitmap, 0);
+    }
+
+    @Override
+    public void texSubImage2D(BasicTexture texture, int xOffset, int yOffset, Bitmap bitmap,
+            int format, int type) {
+        int target = texture.getTarget();
+        GLES20.glBindTexture(target, texture.getId());
+        checkError();
+        GLUtils.texSubImage2D(target, 0, xOffset, yOffset, bitmap, format, type);
+    }
+
+    @Override
+    public int uploadBuffer(FloatBuffer buf) {
+        return uploadBuffer(buf, FLOAT_SIZE);
+    }
+
+    @Override
+    public int uploadBuffer(ByteBuffer buf) {
+        return uploadBuffer(buf, 1);
+    }
+
+    private int uploadBuffer(Buffer buffer, int elementSize) {
+        mGLId.glGenBuffers(1, mTempIntArray, 0);
+        checkError();
+        int bufferId = mTempIntArray[0];
+        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, bufferId);
+        checkError();
+        GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, buffer.capacity() * elementSize, buffer,
+                GLES20.GL_STATIC_DRAW);
+        checkError();
+        return bufferId;
+    }
+
+    public static void checkError() {
+        int error = GLES20.glGetError();
+        if (error != 0) {
+            Throwable t = new Throwable();
+            Log.e(TAG, "GL error: " + error, t);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    private static void printMatrix(String message, float[] m, int offset) {
+        StringBuilder b = new StringBuilder(message);
+        for (int i = 0; i < MATRIX_SIZE; i++) {
+            b.append(' ');
+            if (i % 4 == 0) {
+                b.append('\n');
+            }
+            b.append(m[offset + i]);
+        }
+        Log.v(TAG, b.toString());
+    }
+
+    @Override
+    public void recoverFromLightCycle() {
+        GLES20.glViewport(0, 0, mWidth, mHeight);
+        GLES20.glDisable(GLES20.GL_DEPTH_TEST);
+        GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA);
+        checkError();
+    }
+
+    @Override
+    public void getBounds(Rect bounds, int x, int y, int width, int height) {
+        Matrix.translateM(mTempMatrix, 0, mMatrices, mCurrentMatrixIndex, x, y, 0f);
+        Matrix.scaleM(mTempMatrix, 0, width, height, 1f);
+        Matrix.multiplyMV(mTempMatrix, MATRIX_SIZE, mTempMatrix, 0, BOUNDS_COORDINATES, 0);
+        Matrix.multiplyMV(mTempMatrix, MATRIX_SIZE + 4, mTempMatrix, 0, BOUNDS_COORDINATES, 4);
+        bounds.left = Math.round(mTempMatrix[MATRIX_SIZE]);
+        bounds.right = Math.round(mTempMatrix[MATRIX_SIZE + 4]);
+        bounds.top = Math.round(mTempMatrix[MATRIX_SIZE + 1]);
+        bounds.bottom = Math.round(mTempMatrix[MATRIX_SIZE + 5]);
+        bounds.sort();
+    }
+
+    @Override
+    public GLId getGLId() {
+        return mGLId;
+    }
+}
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/GLES20IdImpl.java b/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/GLES20IdImpl.java
new file mode 100644
index 0000000..6cd7149
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/GLES20IdImpl.java
@@ -0,0 +1,42 @@
+package com.android.gallery3d.glrenderer;
+
+import android.opengl.GLES20;
+
+import javax.microedition.khronos.opengles.GL11;
+import javax.microedition.khronos.opengles.GL11ExtensionPack;
+
+public class GLES20IdImpl implements GLId {
+    private final int[] mTempIntArray = new int[1];
+
+    @Override
+    public int generateTexture() {
+        GLES20.glGenTextures(1, mTempIntArray, 0);
+        GLES20Canvas.checkError();
+        return mTempIntArray[0];
+    }
+
+    @Override
+    public void glGenBuffers(int n, int[] buffers, int offset) {
+        GLES20.glGenBuffers(n, buffers, offset);
+        GLES20Canvas.checkError();
+    }
+
+    @Override
+    public void glDeleteTextures(GL11 gl, int n, int[] textures, int offset) {
+        GLES20.glDeleteTextures(n, textures, offset);
+        GLES20Canvas.checkError();
+    }
+
+
+    @Override
+    public void glDeleteBuffers(GL11 gl, int n, int[] buffers, int offset) {
+        GLES20.glDeleteBuffers(n, buffers, offset);
+        GLES20Canvas.checkError();
+    }
+
+    @Override
+    public void glDeleteFramebuffers(GL11ExtensionPack gl11ep, int n, int[] buffers, int offset) {
+        GLES20.glDeleteFramebuffers(n, buffers, offset);
+        GLES20Canvas.checkError();
+    }
+}
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/GLId.java b/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/GLId.java
new file mode 100644
index 0000000..3cec558
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/GLId.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.glrenderer;
+
+import javax.microedition.khronos.opengles.GL11;
+import javax.microedition.khronos.opengles.GL11ExtensionPack;
+
+// This mimics corresponding GL functions.
+public interface GLId {
+    public int generateTexture();
+
+    public void glGenBuffers(int n, int[] buffers, int offset);
+
+    public void glDeleteTextures(GL11 gl, int n, int[] textures, int offset);
+
+    public void glDeleteBuffers(GL11 gl, int n, int[] buffers, int offset);
+
+    public void glDeleteFramebuffers(GL11ExtensionPack gl11ep, int n, int[] buffers, int offset);
+}
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/GLPaint.java b/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/GLPaint.java
new file mode 100644
index 0000000..16b2206
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/GLPaint.java
@@ -0,0 +1,41 @@
+/*
+ * 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.gallery3d.glrenderer;
+
+import junit.framework.Assert;
+
+public class GLPaint {
+    private float mLineWidth = 1f;
+    private int mColor = 0;
+
+    public void setColor(int color) {
+        mColor = color;
+    }
+
+    public int getColor() {
+        return mColor;
+    }
+
+    public void setLineWidth(float width) {
+        Assert.assertTrue(width >= 0);
+        mLineWidth = width;
+    }
+
+    public float getLineWidth() {
+        return mLineWidth;
+    }
+}
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/RawTexture.java b/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/RawTexture.java
new file mode 100644
index 0000000..93f0fdf
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/RawTexture.java
@@ -0,0 +1,73 @@
+/*
+ * 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.gallery3d.glrenderer;
+
+import android.util.Log;
+
+import javax.microedition.khronos.opengles.GL11;
+
+public class RawTexture extends BasicTexture {
+    private static final String TAG = "RawTexture";
+
+    private final boolean mOpaque;
+    private boolean mIsFlipped;
+
+    public RawTexture(int width, int height, boolean opaque) {
+        mOpaque = opaque;
+        setSize(width, height);
+    }
+
+    @Override
+    public boolean isOpaque() {
+        return mOpaque;
+    }
+
+    @Override
+    public boolean isFlippedVertically() {
+        return mIsFlipped;
+    }
+
+    public void setIsFlippedVertically(boolean isFlipped) {
+        mIsFlipped = isFlipped;
+    }
+
+    protected void prepare(GLCanvas canvas) {
+        GLId glId = canvas.getGLId();
+        mId = glId.generateTexture();
+        canvas.initializeTextureSize(this, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE);
+        canvas.setTextureParameters(this);
+        mState = STATE_LOADED;
+        setAssociatedCanvas(canvas);
+    }
+
+    @Override
+    protected boolean onBind(GLCanvas canvas) {
+        if (isLoaded()) return true;
+        Log.w(TAG, "lost the content due to context change");
+        return false;
+    }
+
+    @Override
+     public void yield() {
+         // we cannot free the texture because we have no backup.
+     }
+
+    @Override
+    protected int getTarget() {
+        return GL11.GL_TEXTURE_2D;
+    }
+}
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/Texture.java b/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/Texture.java
new file mode 100644
index 0000000..3dcae4a
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/Texture.java
@@ -0,0 +1,44 @@
+/*
+ * 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.gallery3d.glrenderer;
+
+
+// Texture is a rectangular image which can be drawn on GLCanvas.
+// The isOpaque() function gives a hint about whether the texture is opaque,
+// so the drawing can be done faster.
+//
+// This is the current texture hierarchy:
+//
+// Texture
+// -- ColorTexture
+// -- FadeInTexture
+// -- BasicTexture
+//    -- UploadedTexture
+//       -- BitmapTexture
+//       -- Tile
+//       -- ResourceTexture
+//          -- NinePatchTexture
+//       -- CanvasTexture
+//          -- StringTexture
+//
+public interface Texture {
+    public int getWidth();
+    public int getHeight();
+    public void draw(GLCanvas canvas, int x, int y);
+    public void draw(GLCanvas canvas, int x, int y, int w, int h);
+    public boolean isOpaque();
+}
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/UploadedTexture.java b/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/UploadedTexture.java
new file mode 100644
index 0000000..f41a979
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/UploadedTexture.java
@@ -0,0 +1,298 @@
+/*
+ * 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.gallery3d.glrenderer;
+
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+import android.opengl.GLUtils;
+
+import junit.framework.Assert;
+
+import java.util.HashMap;
+
+import javax.microedition.khronos.opengles.GL11;
+
+// UploadedTextures use a Bitmap for the content of the texture.
+//
+// Subclasses should implement onGetBitmap() to provide the Bitmap and
+// implement onFreeBitmap(mBitmap) which will be called when the Bitmap
+// is not needed anymore.
+//
+// isContentValid() is meaningful only when the isLoaded() returns true.
+// It means whether the content needs to be updated.
+//
+// The user of this class should call recycle() when the texture is not
+// needed anymore.
+//
+// By default an UploadedTexture is opaque (so it can be drawn faster without
+// blending). The user or subclass can override it using setOpaque().
+public abstract class UploadedTexture extends BasicTexture {
+
+    // To prevent keeping allocation the borders, we store those used borders here.
+    // Since the length will be power of two, it won't use too much memory.
+    private static HashMap<BorderKey, Bitmap> sBorderLines =
+            new HashMap<BorderKey, Bitmap>();
+    private static BorderKey sBorderKey = new BorderKey();
+
+    @SuppressWarnings("unused")
+    private static final String TAG = "Texture";
+    private boolean mContentValid = true;
+
+    // indicate this textures is being uploaded in background
+    private boolean mIsUploading = false;
+    private boolean mOpaque = true;
+    private boolean mThrottled = false;
+    private static int sUploadedCount;
+    private static final int UPLOAD_LIMIT = 100;
+
+    protected Bitmap mBitmap;
+    private int mBorder;
+
+    protected UploadedTexture() {
+        this(false);
+    }
+
+    protected UploadedTexture(boolean hasBorder) {
+        super(null, 0, STATE_UNLOADED);
+        if (hasBorder) {
+            setBorder(true);
+            mBorder = 1;
+        }
+    }
+
+    protected void setIsUploading(boolean uploading) {
+        mIsUploading = uploading;
+    }
+
+    public boolean isUploading() {
+        return mIsUploading;
+    }
+
+    private static class BorderKey implements Cloneable {
+        public boolean vertical;
+        public Config config;
+        public int length;
+
+        @Override
+        public int hashCode() {
+            int x = config.hashCode() ^ length;
+            return vertical ? x : -x;
+        }
+
+        @Override
+        public boolean equals(Object object) {
+            if (!(object instanceof BorderKey)) return false;
+            BorderKey o = (BorderKey) object;
+            return vertical == o.vertical
+                    && config == o.config && length == o.length;
+        }
+
+        @Override
+        public BorderKey clone() {
+            try {
+                return (BorderKey) super.clone();
+            } catch (CloneNotSupportedException e) {
+                throw new AssertionError(e);
+            }
+        }
+    }
+
+    protected void setThrottled(boolean throttled) {
+        mThrottled = throttled;
+    }
+
+    private static Bitmap getBorderLine(
+            boolean vertical, Config config, int length) {
+        BorderKey key = sBorderKey;
+        key.vertical = vertical;
+        key.config = config;
+        key.length = length;
+        Bitmap bitmap = sBorderLines.get(key);
+        if (bitmap == null) {
+            bitmap = vertical
+                    ? Bitmap.createBitmap(1, length, config)
+                    : Bitmap.createBitmap(length, 1, config);
+            sBorderLines.put(key.clone(), bitmap);
+        }
+        return bitmap;
+    }
+
+    private Bitmap getBitmap() {
+        if (mBitmap == null) {
+            mBitmap = onGetBitmap();
+            int w = mBitmap.getWidth() + mBorder * 2;
+            int h = mBitmap.getHeight() + mBorder * 2;
+            if (mWidth == UNSPECIFIED) {
+                setSize(w, h);
+            }
+        }
+        return mBitmap;
+    }
+
+    private void freeBitmap() {
+        Assert.assertTrue(mBitmap != null);
+        onFreeBitmap(mBitmap);
+        mBitmap = null;
+    }
+
+    @Override
+    public int getWidth() {
+        if (mWidth == UNSPECIFIED) getBitmap();
+        return mWidth;
+    }
+
+    @Override
+    public int getHeight() {
+        if (mWidth == UNSPECIFIED) getBitmap();
+        return mHeight;
+    }
+
+    protected abstract Bitmap onGetBitmap();
+
+    protected abstract void onFreeBitmap(Bitmap bitmap);
+
+    protected void invalidateContent() {
+        if (mBitmap != null) freeBitmap();
+        mContentValid = false;
+        mWidth = UNSPECIFIED;
+        mHeight = UNSPECIFIED;
+    }
+
+    /**
+     * Whether the content on GPU is valid.
+     */
+    public boolean isContentValid() {
+        return isLoaded() && mContentValid;
+    }
+
+    /**
+     * Updates the content on GPU's memory.
+     * @param canvas
+     */
+    public void updateContent(GLCanvas canvas) {
+        if (!isLoaded()) {
+            if (mThrottled && ++sUploadedCount > UPLOAD_LIMIT) {
+                return;
+            }
+            uploadToCanvas(canvas);
+        } else if (!mContentValid) {
+            Bitmap bitmap = getBitmap();
+            int format = GLUtils.getInternalFormat(bitmap);
+            int type = GLUtils.getType(bitmap);
+            canvas.texSubImage2D(this, mBorder, mBorder, bitmap, format, type);
+            freeBitmap();
+            mContentValid = true;
+        }
+    }
+
+    public static void resetUploadLimit() {
+        sUploadedCount = 0;
+    }
+
+    public static boolean uploadLimitReached() {
+        return sUploadedCount > UPLOAD_LIMIT;
+    }
+
+    private void uploadToCanvas(GLCanvas canvas) {
+
+        Bitmap bitmap = getBitmap();
+        if (bitmap != null) {
+            try {
+                int bWidth = bitmap.getWidth();
+                int bHeight = bitmap.getHeight();
+                int width = bWidth + mBorder * 2;
+                int height = bHeight + mBorder * 2;
+                int texWidth = getTextureWidth();
+                int texHeight = getTextureHeight();
+
+                Assert.assertTrue(bWidth <= texWidth && bHeight <= texHeight);
+
+                // Upload the bitmap to a new texture.
+                mId = canvas.getGLId().generateTexture();
+                canvas.setTextureParameters(this);
+
+                if (bWidth == texWidth && bHeight == texHeight) {
+                    canvas.initializeTexture(this, bitmap);
+                } else {
+                    int format = GLUtils.getInternalFormat(bitmap);
+                    int type = GLUtils.getType(bitmap);
+                    Config config = bitmap.getConfig();
+
+                    canvas.initializeTextureSize(this, format, type);
+                    canvas.texSubImage2D(this, mBorder, mBorder, bitmap, format, type);
+
+                    if (mBorder > 0) {
+                        // Left border
+                        Bitmap line = getBorderLine(true, config, texHeight);
+                        canvas.texSubImage2D(this, 0, 0, line, format, type);
+
+                        // Top border
+                        line = getBorderLine(false, config, texWidth);
+                        canvas.texSubImage2D(this, 0, 0, line, format, type);
+                    }
+
+                    // Right border
+                    if (mBorder + bWidth < texWidth) {
+                        Bitmap line = getBorderLine(true, config, texHeight);
+                        canvas.texSubImage2D(this, mBorder + bWidth, 0, line, format, type);
+                    }
+
+                    // Bottom border
+                    if (mBorder + bHeight < texHeight) {
+                        Bitmap line = getBorderLine(false, config, texWidth);
+                        canvas.texSubImage2D(this, 0, mBorder + bHeight, line, format, type);
+                    }
+                }
+            } finally {
+                freeBitmap();
+            }
+            // Update texture state.
+            setAssociatedCanvas(canvas);
+            mState = STATE_LOADED;
+            mContentValid = true;
+        } else {
+            mState = STATE_ERROR;
+            throw new RuntimeException("Texture load fail, no bitmap");
+        }
+    }
+
+    @Override
+    protected boolean onBind(GLCanvas canvas) {
+        updateContent(canvas);
+        return isContentValid();
+    }
+
+    @Override
+    protected int getTarget() {
+        return GL11.GL_TEXTURE_2D;
+    }
+
+    public void setOpaque(boolean isOpaque) {
+        mOpaque = isOpaque;
+    }
+
+    @Override
+    public boolean isOpaque() {
+        return mOpaque;
+    }
+
+    @Override
+    public void recycle() {
+        super.recycle();
+        if (mBitmap != null) freeBitmap();
+    }
+}
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/util/IntArray.java b/packages/WallpaperCropper/src/com/android/gallery3d/util/IntArray.java
new file mode 100644
index 0000000..2c4dc2c
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/util/IntArray.java
@@ -0,0 +1,60 @@
+/*
+ * 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.gallery3d.util;
+
+public class IntArray {
+    private static final int INIT_CAPACITY = 8;
+
+    private int mData[] = new int[INIT_CAPACITY];
+    private int mSize = 0;
+
+    public void add(int value) {
+        if (mData.length == mSize) {
+            int temp[] = new int[mSize + mSize];
+            System.arraycopy(mData, 0, temp, 0, mSize);
+            mData = temp;
+        }
+        mData[mSize++] = value;
+    }
+
+    public int removeLast() {
+        mSize--;
+        return mData[mSize];
+    }
+
+    public int size() {
+        return mSize;
+    }
+
+    // For testing only
+    public int[] toArray(int[] result) {
+        if (result == null || result.length < mSize) {
+            result = new int[mSize];
+        }
+        System.arraycopy(mData, 0, result, 0, mSize);
+        return result;
+    }
+
+    public int[] getInternalArray() {
+        return mData;
+    }
+
+    public void clear() {
+        mSize = 0;
+        if (mData.length != INIT_CAPACITY) mData = new int[INIT_CAPACITY];
+    }
+}
diff --git a/packages/WallpaperCropper/src/com/android/photos/BitmapRegionTileSource.java b/packages/WallpaperCropper/src/com/android/photos/BitmapRegionTileSource.java
new file mode 100644
index 0000000..5f64018
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/photos/BitmapRegionTileSource.java
@@ -0,0 +1,260 @@
+/*
+ * 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.photos;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+import android.graphics.BitmapFactory;
+import android.graphics.BitmapRegionDecoder;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Build.VERSION_CODES;
+import android.util.Log;
+
+import com.android.gallery3d.common.BitmapUtils;
+import com.android.gallery3d.glrenderer.BasicTexture;
+import com.android.gallery3d.glrenderer.BitmapTexture;
+import com.android.photos.views.TiledImageRenderer;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * A {@link com.android.photos.views.TiledImageRenderer.TileSource} using
+ * {@link BitmapRegionDecoder} to wrap a local file
+ */
+@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
+public class BitmapRegionTileSource implements TiledImageRenderer.TileSource {
+
+    private static final String TAG = "BitmapRegionTileSource";
+
+    private static final boolean REUSE_BITMAP =
+            Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN;
+    private static final int GL_SIZE_LIMIT = 2048;
+    // This must be no larger than half the size of the GL_SIZE_LIMIT
+    // due to decodePreview being allowed to be up to 2x the size of the target
+    private static final int MAX_PREVIEW_SIZE = 1024;
+
+    BitmapRegionDecoder mDecoder;
+    int mWidth;
+    int mHeight;
+    int mTileSize;
+    private BasicTexture mPreview;
+    private final int mRotation;
+
+    // For use only by getTile
+    private Rect mWantRegion = new Rect();
+    private Rect mOverlapRegion = new Rect();
+    private BitmapFactory.Options mOptions;
+    private Canvas mCanvas;
+
+    public BitmapRegionTileSource(Context context, String path, int previewSize, int rotation) {
+        this(null, context, path, null, 0, previewSize, rotation);
+    }
+
+    public BitmapRegionTileSource(Context context, Uri uri, int previewSize, int rotation) {
+        this(null, context, null, uri, 0, previewSize, rotation);
+    }
+
+    public BitmapRegionTileSource(Resources res,
+            Context context, int resId, int previewSize, int rotation) {
+        this(res, context, null, null, resId, previewSize, rotation);
+    }
+
+    private BitmapRegionTileSource(Resources res,
+            Context context, String path, Uri uri, int resId, int previewSize, int rotation) {
+        mTileSize = TiledImageRenderer.suggestedTileSize(context);
+        mRotation = rotation;
+        try {
+            if (path != null) {
+                mDecoder = BitmapRegionDecoder.newInstance(path, true);
+            } else if (uri != null) {
+                InputStream is = context.getContentResolver().openInputStream(uri);
+                BufferedInputStream bis = new BufferedInputStream(is);
+                mDecoder = BitmapRegionDecoder.newInstance(bis, true);
+            } else {
+                InputStream is = res.openRawResource(resId);
+                BufferedInputStream bis = new BufferedInputStream(is);
+                mDecoder = BitmapRegionDecoder.newInstance(bis, true);
+            }
+            mWidth = mDecoder.getWidth();
+            mHeight = mDecoder.getHeight();
+        } catch (IOException e) {
+            Log.w("BitmapRegionTileSource", "ctor failed", e);
+        }
+        mOptions = new BitmapFactory.Options();
+        mOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
+        mOptions.inPreferQualityOverSpeed = true;
+        mOptions.inTempStorage = new byte[16 * 1024];
+        if (previewSize != 0) {
+            previewSize = Math.min(previewSize, MAX_PREVIEW_SIZE);
+            // Although this is the same size as the Bitmap that is likely already
+            // loaded, the lifecycle is different and interactions are on a different
+            // thread. Thus to simplify, this source will decode its own bitmap.
+            Bitmap preview = decodePreview(res, context, path, uri, resId, previewSize);
+            if (preview.getWidth() <= GL_SIZE_LIMIT && preview.getHeight() <= GL_SIZE_LIMIT) {
+                mPreview = new BitmapTexture(preview);
+            } else {
+                Log.w(TAG, String.format(
+                        "Failed to create preview of apropriate size! "
+                        + " in: %dx%d, out: %dx%d",
+                        mWidth, mHeight,
+                        preview.getWidth(), preview.getHeight()));
+            }
+        }
+    }
+
+    @Override
+    public int getTileSize() {
+        return mTileSize;
+    }
+
+    @Override
+    public int getImageWidth() {
+        return mWidth;
+    }
+
+    @Override
+    public int getImageHeight() {
+        return mHeight;
+    }
+
+    @Override
+    public BasicTexture getPreview() {
+        return mPreview;
+    }
+
+    @Override
+    public int getRotation() {
+        return mRotation;
+    }
+
+    @Override
+    public Bitmap getTile(int level, int x, int y, Bitmap bitmap) {
+        int tileSize = getTileSize();
+        if (!REUSE_BITMAP) {
+            return getTileWithoutReusingBitmap(level, x, y, tileSize);
+        }
+
+        int t = tileSize << level;
+        mWantRegion.set(x, y, x + t, y + t);
+
+        if (bitmap == null) {
+            bitmap = Bitmap.createBitmap(tileSize, tileSize, Bitmap.Config.ARGB_8888);
+        }
+
+        mOptions.inSampleSize = (1 << level);
+        mOptions.inBitmap = bitmap;
+
+        try {
+            bitmap = mDecoder.decodeRegion(mWantRegion, mOptions);
+        } finally {
+            if (mOptions.inBitmap != bitmap && mOptions.inBitmap != null) {
+                mOptions.inBitmap = null;
+            }
+        }
+
+        if (bitmap == null) {
+            Log.w("BitmapRegionTileSource", "fail in decoding region");
+        }
+        return bitmap;
+    }
+
+    private Bitmap getTileWithoutReusingBitmap(
+            int level, int x, int y, int tileSize) {
+
+        int t = tileSize << level;
+        mWantRegion.set(x, y, x + t, y + t);
+
+        mOverlapRegion.set(0, 0, mWidth, mHeight);
+
+        mOptions.inSampleSize = (1 << level);
+        Bitmap bitmap = mDecoder.decodeRegion(mOverlapRegion, mOptions);
+
+        if (bitmap == null) {
+            Log.w(TAG, "fail in decoding region");
+        }
+
+        if (mWantRegion.equals(mOverlapRegion)) {
+            return bitmap;
+        }
+
+        Bitmap result = Bitmap.createBitmap(tileSize, tileSize, Config.ARGB_8888);
+        if (mCanvas == null) {
+            mCanvas = new Canvas();
+        }
+        mCanvas.setBitmap(result);
+        mCanvas.drawBitmap(bitmap,
+                (mOverlapRegion.left - mWantRegion.left) >> level,
+                (mOverlapRegion.top - mWantRegion.top) >> level, null);
+        mCanvas.setBitmap(null);
+        return result;
+    }
+
+    /**
+     * Note that the returned bitmap may have a long edge that's longer
+     * than the targetSize, but it will always be less than 2x the targetSize
+     */
+    private Bitmap decodePreview(
+            Resources res, Context context, String file, Uri uri, int resId, int targetSize) {
+        float scale = (float) targetSize / Math.max(mWidth, mHeight);
+        mOptions.inSampleSize = BitmapUtils.computeSampleSizeLarger(scale);
+        mOptions.inJustDecodeBounds = false;
+
+        Bitmap result = null;
+        if (file != null) {
+            result = BitmapFactory.decodeFile(file, mOptions);
+        } else if (uri != null) {
+            try {
+                InputStream is = context.getContentResolver().openInputStream(uri);
+                BufferedInputStream bis = new BufferedInputStream(is);
+                result = BitmapFactory.decodeStream(bis, null, mOptions);
+            } catch (IOException e) {
+                Log.w("BitmapRegionTileSource", "getting preview failed", e);
+            }
+        } else {
+            result = BitmapFactory.decodeResource(res, resId, mOptions);
+        }
+        if (result == null) {
+            return null;
+        }
+
+        // We need to resize down if the decoder does not support inSampleSize
+        // or didn't support the specified inSampleSize (some decoders only do powers of 2)
+        scale = (float) targetSize / (float) (Math.max(result.getWidth(), result.getHeight()));
+
+        if (scale <= 0.5) {
+            result = BitmapUtils.resizeBitmapByScale(result, scale, true);
+        }
+        return ensureGLCompatibleBitmap(result);
+    }
+
+    private static Bitmap ensureGLCompatibleBitmap(Bitmap bitmap) {
+        if (bitmap == null || bitmap.getConfig() != null) {
+            return bitmap;
+        }
+        Bitmap newBitmap = bitmap.copy(Config.ARGB_8888, false);
+        bitmap.recycle();
+        return newBitmap;
+    }
+}
diff --git a/packages/WallpaperCropper/src/com/android/photos/views/BlockingGLTextureView.java b/packages/WallpaperCropper/src/com/android/photos/views/BlockingGLTextureView.java
new file mode 100644
index 0000000..8a05051
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/photos/views/BlockingGLTextureView.java
@@ -0,0 +1,438 @@
+/*
+ * 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.photos.views;
+
+import android.content.Context;
+import android.graphics.SurfaceTexture;
+import android.opengl.GLSurfaceView.Renderer;
+import android.opengl.GLUtils;
+import android.util.Log;
+import android.view.TextureView;
+import android.view.TextureView.SurfaceTextureListener;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+import javax.microedition.khronos.egl.EGLSurface;
+import javax.microedition.khronos.opengles.GL10;
+
+/**
+ * A TextureView that supports blocking rendering for synchronous drawing
+ */
+public class BlockingGLTextureView extends TextureView
+        implements SurfaceTextureListener {
+
+    private RenderThread mRenderThread;
+
+    public BlockingGLTextureView(Context context) {
+        super(context);
+        setSurfaceTextureListener(this);
+    }
+
+    public void setRenderer(Renderer renderer) {
+        if (mRenderThread != null) {
+            throw new IllegalArgumentException("Renderer already set");
+        }
+        mRenderThread = new RenderThread(renderer);
+    }
+
+    public void render() {
+        mRenderThread.render();
+    }
+
+    public void destroy() {
+        if (mRenderThread != null) {
+            mRenderThread.finish();
+            mRenderThread = null;
+        }
+    }
+
+    @Override
+    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width,
+            int height) {
+        mRenderThread.setSurface(surface);
+        mRenderThread.setSize(width, height);
+    }
+
+    @Override
+    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width,
+            int height) {
+        mRenderThread.setSize(width, height);
+    }
+
+    @Override
+    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
+        if (mRenderThread != null) {
+            mRenderThread.setSurface(null);
+        }
+        return false;
+    }
+
+    @Override
+    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            destroy();
+        } catch (Throwable t) {
+            // Ignore
+        }
+        super.finalize();
+    }
+
+    /**
+     * An EGL helper class.
+     */
+
+    private static class EglHelper {
+        private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
+        private static final int EGL_OPENGL_ES2_BIT = 4;
+
+        EGL10 mEgl;
+        EGLDisplay mEglDisplay;
+        EGLSurface mEglSurface;
+        EGLConfig mEglConfig;
+        EGLContext mEglContext;
+
+        private EGLConfig chooseEglConfig() {
+            int[] configsCount = new int[1];
+            EGLConfig[] configs = new EGLConfig[1];
+            int[] configSpec = getConfig();
+            if (!mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, configsCount)) {
+                throw new IllegalArgumentException("eglChooseConfig failed " +
+                        GLUtils.getEGLErrorString(mEgl.eglGetError()));
+            } else if (configsCount[0] > 0) {
+                return configs[0];
+            }
+            return null;
+        }
+
+        private static int[] getConfig() {
+            return new int[] {
+                    EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+                    EGL10.EGL_RED_SIZE, 8,
+                    EGL10.EGL_GREEN_SIZE, 8,
+                    EGL10.EGL_BLUE_SIZE, 8,
+                    EGL10.EGL_ALPHA_SIZE, 8,
+                    EGL10.EGL_DEPTH_SIZE, 0,
+                    EGL10.EGL_STENCIL_SIZE, 0,
+                    EGL10.EGL_NONE
+            };
+        }
+
+        EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) {
+            int[] attribList = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
+            return egl.eglCreateContext(eglDisplay, eglConfig, EGL10.EGL_NO_CONTEXT, attribList);
+        }
+
+        /**
+         * Initialize EGL for a given configuration spec.
+         */
+        public void start() {
+            /*
+             * Get an EGL instance
+             */
+            mEgl = (EGL10) EGLContext.getEGL();
+
+            /*
+             * Get to the default display.
+             */
+            mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
+
+            if (mEglDisplay == EGL10.EGL_NO_DISPLAY) {
+                throw new RuntimeException("eglGetDisplay failed");
+            }
+
+            /*
+             * We can now initialize EGL for that display
+             */
+            int[] version = new int[2];
+            if (!mEgl.eglInitialize(mEglDisplay, version)) {
+                throw new RuntimeException("eglInitialize failed");
+            }
+            mEglConfig = chooseEglConfig();
+
+            /*
+            * Create an EGL context. We want to do this as rarely as we can, because an
+            * EGL context is a somewhat heavy object.
+            */
+            mEglContext = createContext(mEgl, mEglDisplay, mEglConfig);
+
+            if (mEglContext == null || mEglContext == EGL10.EGL_NO_CONTEXT) {
+                mEglContext = null;
+                throwEglException("createContext");
+            }
+
+            mEglSurface = null;
+        }
+
+        /**
+         * Create an egl surface for the current SurfaceTexture surface. If a surface
+         * already exists, destroy it before creating the new surface.
+         *
+         * @return true if the surface was created successfully.
+         */
+        public boolean createSurface(SurfaceTexture surface) {
+            /*
+             * Check preconditions.
+             */
+            if (mEgl == null) {
+                throw new RuntimeException("egl not initialized");
+            }
+            if (mEglDisplay == null) {
+                throw new RuntimeException("eglDisplay not initialized");
+            }
+            if (mEglConfig == null) {
+                throw new RuntimeException("mEglConfig not initialized");
+            }
+
+            /*
+             *  The window size has changed, so we need to create a new
+             *  surface.
+             */
+            destroySurfaceImp();
+
+            /*
+             * Create an EGL surface we can render into.
+             */
+            if (surface != null) {
+                mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, mEglConfig, surface, null);
+            } else {
+                mEglSurface = null;
+            }
+
+            if (mEglSurface == null || mEglSurface == EGL10.EGL_NO_SURFACE) {
+                int error = mEgl.eglGetError();
+                if (error == EGL10.EGL_BAD_NATIVE_WINDOW) {
+                    Log.e("EglHelper", "createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
+                }
+                return false;
+            }
+
+            /*
+             * Before we can issue GL commands, we need to make sure
+             * the context is current and bound to a surface.
+             */
+            if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
+                /*
+                 * Could not make the context current, probably because the underlying
+                 * SurfaceView surface has been destroyed.
+                 */
+                logEglErrorAsWarning("EGLHelper", "eglMakeCurrent", mEgl.eglGetError());
+                return false;
+            }
+
+            return true;
+        }
+
+        /**
+         * Create a GL object for the current EGL context.
+         */
+        public GL10 createGL() {
+            return (GL10) mEglContext.getGL();
+        }
+
+        /**
+         * Display the current render surface.
+         * @return the EGL error code from eglSwapBuffers.
+         */
+        public int swap() {
+            if (!mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) {
+                return mEgl.eglGetError();
+            }
+            return EGL10.EGL_SUCCESS;
+        }
+
+        public void destroySurface() {
+            destroySurfaceImp();
+        }
+
+        private void destroySurfaceImp() {
+            if (mEglSurface != null && mEglSurface != EGL10.EGL_NO_SURFACE) {
+                mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE,
+                        EGL10.EGL_NO_SURFACE,
+                        EGL10.EGL_NO_CONTEXT);
+                mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
+                mEglSurface = null;
+            }
+        }
+
+        public void finish() {
+            if (mEglContext != null) {
+                mEgl.eglDestroyContext(mEglDisplay, mEglContext);
+                mEglContext = null;
+            }
+            if (mEglDisplay != null) {
+                mEgl.eglTerminate(mEglDisplay);
+                mEglDisplay = null;
+            }
+        }
+
+        private void throwEglException(String function) {
+            throwEglException(function, mEgl.eglGetError());
+        }
+
+        public static void throwEglException(String function, int error) {
+            String message = formatEglError(function, error);
+            throw new RuntimeException(message);
+        }
+
+        public static void logEglErrorAsWarning(String tag, String function, int error) {
+            Log.w(tag, formatEglError(function, error));
+        }
+
+        public static String formatEglError(String function, int error) {
+            return function + " failed: " + error;
+        }
+
+    }
+
+    private static class RenderThread extends Thread {
+        private static final int INVALID = -1;
+        private static final int RENDER = 1;
+        private static final int CHANGE_SURFACE = 2;
+        private static final int RESIZE_SURFACE = 3;
+        private static final int FINISH = 4;
+
+        private EglHelper mEglHelper = new EglHelper();
+
+        private Object mLock = new Object();
+        private int mExecMsgId = INVALID;
+        private SurfaceTexture mSurface;
+        private Renderer mRenderer;
+        private int mWidth, mHeight;
+
+        private boolean mFinished = false;
+        private GL10 mGL;
+
+        public RenderThread(Renderer renderer) {
+            super("RenderThread");
+            mRenderer = renderer;
+            start();
+        }
+
+        private void checkRenderer() {
+            if (mRenderer == null) {
+                throw new IllegalArgumentException("Renderer is null!");
+            }
+        }
+
+        private void checkSurface() {
+            if (mSurface == null) {
+                throw new IllegalArgumentException("surface is null!");
+            }
+        }
+
+        public void setSurface(SurfaceTexture surface) {
+            // If the surface is null we're being torn down, don't need a
+            // renderer then
+            if (surface != null) {
+                checkRenderer();
+            }
+            mSurface = surface;
+            exec(CHANGE_SURFACE);
+        }
+
+        public void setSize(int width, int height) {
+            checkRenderer();
+            checkSurface();
+            mWidth = width;
+            mHeight = height;
+            exec(RESIZE_SURFACE);
+        }
+
+        public void render() {
+            checkRenderer();
+            if (mSurface != null) {
+                exec(RENDER);
+                mSurface.updateTexImage();
+            }
+        }
+
+        public void finish() {
+            mSurface = null;
+            exec(FINISH);
+            try {
+                join();
+            } catch (InterruptedException e) {
+                // Ignore
+            }
+        }
+
+        private void exec(int msgid) {
+            synchronized (mLock) {
+                if (mExecMsgId != INVALID) {
+                    throw new IllegalArgumentException(
+                            "Message already set - multithreaded access?");
+                }
+                mExecMsgId = msgid;
+                mLock.notify();
+                try {
+                    mLock.wait();
+                } catch (InterruptedException e) {
+                    // Ignore
+                }
+            }
+        }
+
+        private void handleMessageLocked(int what) {
+            switch (what) {
+            case CHANGE_SURFACE:
+                if (mEglHelper.createSurface(mSurface)) {
+                    mGL = mEglHelper.createGL();
+                    mRenderer.onSurfaceCreated(mGL, mEglHelper.mEglConfig);
+                }
+                break;
+            case RESIZE_SURFACE:
+                mRenderer.onSurfaceChanged(mGL, mWidth, mHeight);
+                break;
+            case RENDER:
+                mRenderer.onDrawFrame(mGL);
+                mEglHelper.swap();
+                break;
+            case FINISH:
+                mEglHelper.destroySurface();
+                mEglHelper.finish();
+                mFinished = true;
+                break;
+            }
+        }
+
+        @Override
+        public void run() {
+            synchronized (mLock) {
+                mEglHelper.start();
+                while (!mFinished) {
+                    while (mExecMsgId == INVALID) {
+                        try {
+                            mLock.wait();
+                        } catch (InterruptedException e) {
+                            // Ignore
+                        }
+                    }
+                    handleMessageLocked(mExecMsgId);
+                    mExecMsgId = INVALID;
+                    mLock.notify();
+                }
+                mExecMsgId = FINISH;
+            }
+        }
+    }
+}
diff --git a/packages/WallpaperCropper/src/com/android/photos/views/TiledImageRenderer.java b/packages/WallpaperCropper/src/com/android/photos/views/TiledImageRenderer.java
new file mode 100644
index 0000000..c4e493b
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/photos/views/TiledImageRenderer.java
@@ -0,0 +1,825 @@
+/*
+ * 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.photos.views;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.support.v4.util.LongSparseArray;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.util.Pools.Pool;
+import android.util.Pools.SynchronizedPool;
+import android.view.View;
+import android.view.WindowManager;
+
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.glrenderer.BasicTexture;
+import com.android.gallery3d.glrenderer.GLCanvas;
+import com.android.gallery3d.glrenderer.UploadedTexture;
+
+/**
+ * Handles laying out, decoding, and drawing of tiles in GL
+ */
+public class TiledImageRenderer {
+    public static final int SIZE_UNKNOWN = -1;
+
+    private static final String TAG = "TiledImageRenderer";
+    private static final int UPLOAD_LIMIT = 1;
+
+    /*
+     *  This is the tile state in the CPU side.
+     *  Life of a Tile:
+     *      ACTIVATED (initial state)
+     *              --> IN_QUEUE - by queueForDecode()
+     *              --> RECYCLED - by recycleTile()
+     *      IN_QUEUE --> DECODING - by decodeTile()
+     *               --> RECYCLED - by recycleTile)
+     *      DECODING --> RECYCLING - by recycleTile()
+     *               --> DECODED  - by decodeTile()
+     *               --> DECODE_FAIL - by decodeTile()
+     *      RECYCLING --> RECYCLED - by decodeTile()
+     *      DECODED --> ACTIVATED - (after the decoded bitmap is uploaded)
+     *      DECODED --> RECYCLED - by recycleTile()
+     *      DECODE_FAIL -> RECYCLED - by recycleTile()
+     *      RECYCLED --> ACTIVATED - by obtainTile()
+     */
+    private static final int STATE_ACTIVATED = 0x01;
+    private static final int STATE_IN_QUEUE = 0x02;
+    private static final int STATE_DECODING = 0x04;
+    private static final int STATE_DECODED = 0x08;
+    private static final int STATE_DECODE_FAIL = 0x10;
+    private static final int STATE_RECYCLING = 0x20;
+    private static final int STATE_RECYCLED = 0x40;
+
+    private static Pool<Bitmap> sTilePool = new SynchronizedPool<Bitmap>(64);
+
+    // TILE_SIZE must be 2^N
+    private int mTileSize;
+
+    private TileSource mModel;
+    private BasicTexture mPreview;
+    protected int mLevelCount;  // cache the value of mScaledBitmaps.length
+
+    // The mLevel variable indicates which level of bitmap we should use.
+    // Level 0 means the original full-sized bitmap, and a larger value means
+    // a smaller scaled bitmap (The width and height of each scaled bitmap is
+    // half size of the previous one). If the value is in [0, mLevelCount), we
+    // use the bitmap in mScaledBitmaps[mLevel] for display, otherwise the value
+    // is mLevelCount
+    private int mLevel = 0;
+
+    private int mOffsetX;
+    private int mOffsetY;
+
+    private int mUploadQuota;
+    private boolean mRenderComplete;
+
+    private final RectF mSourceRect = new RectF();
+    private final RectF mTargetRect = new RectF();
+
+    private final LongSparseArray<Tile> mActiveTiles = new LongSparseArray<Tile>();
+
+    // The following three queue are guarded by mQueueLock
+    private final Object mQueueLock = new Object();
+    private final TileQueue mRecycledQueue = new TileQueue();
+    private final TileQueue mUploadQueue = new TileQueue();
+    private final TileQueue mDecodeQueue = new TileQueue();
+
+    // The width and height of the full-sized bitmap
+    protected int mImageWidth = SIZE_UNKNOWN;
+    protected int mImageHeight = SIZE_UNKNOWN;
+
+    protected int mCenterX;
+    protected int mCenterY;
+    protected float mScale;
+    protected int mRotation;
+
+    private boolean mLayoutTiles;
+
+    // Temp variables to avoid memory allocation
+    private final Rect mTileRange = new Rect();
+    private final Rect mActiveRange[] = {new Rect(), new Rect()};
+
+    private TileDecoder mTileDecoder;
+    private boolean mBackgroundTileUploaded;
+
+    private int mViewWidth, mViewHeight;
+    private View mParent;
+
+    /**
+     * Interface for providing tiles to a {@link TiledImageRenderer}
+     */
+    public static interface TileSource {
+
+        /**
+         * If the source does not care about the tile size, it should use
+         * {@link TiledImageRenderer#suggestedTileSize(Context)}
+         */
+        public int getTileSize();
+        public int getImageWidth();
+        public int getImageHeight();
+        public int getRotation();
+
+        /**
+         * Return a Preview image if available. This will be used as the base layer
+         * if higher res tiles are not yet available
+         */
+        public BasicTexture getPreview();
+
+        /**
+         * The tile returned by this method can be specified this way: Assuming
+         * the image size is (width, height), first take the intersection of (0,
+         * 0) - (width, height) and (x, y) - (x + tileSize, y + tileSize). If
+         * in extending the region, we found some part of the region is outside
+         * the image, those pixels are filled with black.
+         *
+         * If level > 0, it does the same operation on a down-scaled version of
+         * the original image (down-scaled by a factor of 2^level), but (x, y)
+         * still refers to the coordinate on the original image.
+         *
+         * The method would be called by the decoder thread.
+         */
+        public Bitmap getTile(int level, int x, int y, Bitmap reuse);
+    }
+
+    public static int suggestedTileSize(Context context) {
+        return isHighResolution(context) ? 512 : 256;
+    }
+
+    private static boolean isHighResolution(Context context) {
+        DisplayMetrics metrics = new DisplayMetrics();
+        WindowManager wm = (WindowManager)
+                context.getSystemService(Context.WINDOW_SERVICE);
+        wm.getDefaultDisplay().getMetrics(metrics);
+        return metrics.heightPixels > 2048 ||  metrics.widthPixels > 2048;
+    }
+
+    public TiledImageRenderer(View parent) {
+        mParent = parent;
+        mTileDecoder = new TileDecoder();
+        mTileDecoder.start();
+    }
+
+    public int getViewWidth() {
+        return mViewWidth;
+    }
+
+    public int getViewHeight() {
+        return mViewHeight;
+    }
+
+    private void invalidate() {
+        mParent.postInvalidate();
+    }
+
+    public void setModel(TileSource model, int rotation) {
+        if (mModel != model) {
+            mModel = model;
+            notifyModelInvalidated();
+        }
+        if (mRotation != rotation) {
+            mRotation = rotation;
+            mLayoutTiles = true;
+        }
+    }
+
+    private void calculateLevelCount() {
+        if (mPreview != null) {
+            mLevelCount = Math.max(0, Utils.ceilLog2(
+                mImageWidth / (float) mPreview.getWidth()));
+        } else {
+            int levels = 1;
+            int maxDim = Math.max(mImageWidth, mImageHeight);
+            int t = mTileSize;
+            while (t < maxDim) {
+                t <<= 1;
+                levels++;
+            }
+            mLevelCount = levels;
+        }
+    }
+
+    public void notifyModelInvalidated() {
+        invalidateTiles();
+        if (mModel == null) {
+            mImageWidth = 0;
+            mImageHeight = 0;
+            mLevelCount = 0;
+            mPreview = null;
+        } else {
+            mImageWidth = mModel.getImageWidth();
+            mImageHeight = mModel.getImageHeight();
+            mPreview = mModel.getPreview();
+            mTileSize = mModel.getTileSize();
+            calculateLevelCount();
+        }
+        mLayoutTiles = true;
+    }
+
+    public void setViewSize(int width, int height) {
+        mViewWidth = width;
+        mViewHeight = height;
+    }
+
+    public void setPosition(int centerX, int centerY, float scale) {
+        if (mCenterX == centerX && mCenterY == centerY
+                && mScale == scale) {
+            return;
+        }
+        mCenterX = centerX;
+        mCenterY = centerY;
+        mScale = scale;
+        mLayoutTiles = true;
+    }
+
+    // Prepare the tiles we want to use for display.
+    //
+    // 1. Decide the tile level we want to use for display.
+    // 2. Decide the tile levels we want to keep as texture (in addition to
+    //    the one we use for display).
+    // 3. Recycle unused tiles.
+    // 4. Activate the tiles we want.
+    private void layoutTiles() {
+        if (mViewWidth == 0 || mViewHeight == 0 || !mLayoutTiles) {
+            return;
+        }
+        mLayoutTiles = false;
+
+        // The tile levels we want to keep as texture is in the range
+        // [fromLevel, endLevel).
+        int fromLevel;
+        int endLevel;
+
+        // We want to use a texture larger than or equal to the display size.
+        mLevel = Utils.clamp(Utils.floorLog2(1f / mScale), 0, mLevelCount);
+
+        // We want to keep one more tile level as texture in addition to what
+        // we use for display. So it can be faster when the scale moves to the
+        // next level. We choose the level closest to the current scale.
+        if (mLevel != mLevelCount) {
+            Rect range = mTileRange;
+            getRange(range, mCenterX, mCenterY, mLevel, mScale, mRotation);
+            mOffsetX = Math.round(mViewWidth / 2f + (range.left - mCenterX) * mScale);
+            mOffsetY = Math.round(mViewHeight / 2f + (range.top - mCenterY) * mScale);
+            fromLevel = mScale * (1 << mLevel) > 0.75f ? mLevel - 1 : mLevel;
+        } else {
+            // Activate the tiles of the smallest two levels.
+            fromLevel = mLevel - 2;
+            mOffsetX = Math.round(mViewWidth / 2f - mCenterX * mScale);
+            mOffsetY = Math.round(mViewHeight / 2f - mCenterY * mScale);
+        }
+
+        fromLevel = Math.max(0, Math.min(fromLevel, mLevelCount - 2));
+        endLevel = Math.min(fromLevel + 2, mLevelCount);
+
+        Rect range[] = mActiveRange;
+        for (int i = fromLevel; i < endLevel; ++i) {
+            getRange(range[i - fromLevel], mCenterX, mCenterY, i, mRotation);
+        }
+
+        // If rotation is transient, don't update the tile.
+        if (mRotation % 90 != 0) {
+            return;
+        }
+
+        synchronized (mQueueLock) {
+            mDecodeQueue.clean();
+            mUploadQueue.clean();
+            mBackgroundTileUploaded = false;
+
+            // Recycle unused tiles: if the level of the active tile is outside the
+            // range [fromLevel, endLevel) or not in the visible range.
+            int n = mActiveTiles.size();
+            for (int i = 0; i < n; i++) {
+                Tile tile = mActiveTiles.valueAt(i);
+                int level = tile.mTileLevel;
+                if (level < fromLevel || level >= endLevel
+                        || !range[level - fromLevel].contains(tile.mX, tile.mY)) {
+                    mActiveTiles.removeAt(i);
+                    i--;
+                    n--;
+                    recycleTile(tile);
+                }
+            }
+        }
+
+        for (int i = fromLevel; i < endLevel; ++i) {
+            int size = mTileSize << i;
+            Rect r = range[i - fromLevel];
+            for (int y = r.top, bottom = r.bottom; y < bottom; y += size) {
+                for (int x = r.left, right = r.right; x < right; x += size) {
+                    activateTile(x, y, i);
+                }
+            }
+        }
+        invalidate();
+    }
+
+    private void invalidateTiles() {
+        synchronized (mQueueLock) {
+            mDecodeQueue.clean();
+            mUploadQueue.clean();
+
+            // TODO(xx): disable decoder
+            int n = mActiveTiles.size();
+            for (int i = 0; i < n; i++) {
+                Tile tile = mActiveTiles.valueAt(i);
+                recycleTile(tile);
+            }
+            mActiveTiles.clear();
+        }
+    }
+
+    private void getRange(Rect out, int cX, int cY, int level, int rotation) {
+        getRange(out, cX, cY, level, 1f / (1 << (level + 1)), rotation);
+    }
+
+    // If the bitmap is scaled by the given factor "scale", return the
+    // rectangle containing visible range. The left-top coordinate returned is
+    // aligned to the tile boundary.
+    //
+    // (cX, cY) is the point on the original bitmap which will be put in the
+    // center of the ImageViewer.
+    private void getRange(Rect out,
+            int cX, int cY, int level, float scale, int rotation) {
+
+        double radians = Math.toRadians(-rotation);
+        double w = mViewWidth;
+        double h = mViewHeight;
+
+        double cos = Math.cos(radians);
+        double sin = Math.sin(radians);
+        int width = (int) Math.ceil(Math.max(
+                Math.abs(cos * w - sin * h), Math.abs(cos * w + sin * h)));
+        int height = (int) Math.ceil(Math.max(
+                Math.abs(sin * w + cos * h), Math.abs(sin * w - cos * h)));
+
+        int left = (int) Math.floor(cX - width / (2f * scale));
+        int top = (int) Math.floor(cY - height / (2f * scale));
+        int right = (int) Math.ceil(left + width / scale);
+        int bottom = (int) Math.ceil(top + height / scale);
+
+        // align the rectangle to tile boundary
+        int size = mTileSize << level;
+        left = Math.max(0, size * (left / size));
+        top = Math.max(0, size * (top / size));
+        right = Math.min(mImageWidth, right);
+        bottom = Math.min(mImageHeight, bottom);
+
+        out.set(left, top, right, bottom);
+    }
+
+    public void freeTextures() {
+        mLayoutTiles = true;
+
+        mTileDecoder.finishAndWait();
+        synchronized (mQueueLock) {
+            mUploadQueue.clean();
+            mDecodeQueue.clean();
+            Tile tile = mRecycledQueue.pop();
+            while (tile != null) {
+                tile.recycle();
+                tile = mRecycledQueue.pop();
+            }
+        }
+
+        int n = mActiveTiles.size();
+        for (int i = 0; i < n; i++) {
+            Tile texture = mActiveTiles.valueAt(i);
+            texture.recycle();
+        }
+        mActiveTiles.clear();
+        mTileRange.set(0, 0, 0, 0);
+
+        while (sTilePool.acquire() != null) {}
+    }
+
+    public boolean draw(GLCanvas canvas) {
+        layoutTiles();
+        uploadTiles(canvas);
+
+        mUploadQuota = UPLOAD_LIMIT;
+        mRenderComplete = true;
+
+        int level = mLevel;
+        int rotation = mRotation;
+        int flags = 0;
+        if (rotation != 0) {
+            flags |= GLCanvas.SAVE_FLAG_MATRIX;
+        }
+
+        if (flags != 0) {
+            canvas.save(flags);
+            if (rotation != 0) {
+                int centerX = mViewWidth / 2, centerY = mViewHeight / 2;
+                canvas.translate(centerX, centerY);
+                canvas.rotate(rotation, 0, 0, 1);
+                canvas.translate(-centerX, -centerY);
+            }
+        }
+        try {
+            if (level != mLevelCount) {
+                int size = (mTileSize << level);
+                float length = size * mScale;
+                Rect r = mTileRange;
+
+                for (int ty = r.top, i = 0; ty < r.bottom; ty += size, i++) {
+                    float y = mOffsetY + i * length;
+                    for (int tx = r.left, j = 0; tx < r.right; tx += size, j++) {
+                        float x = mOffsetX + j * length;
+                        drawTile(canvas, tx, ty, level, x, y, length);
+                    }
+                }
+            } else if (mPreview != null) {
+                mPreview.draw(canvas, mOffsetX, mOffsetY,
+                        Math.round(mImageWidth * mScale),
+                        Math.round(mImageHeight * mScale));
+            }
+        } finally {
+            if (flags != 0) {
+                canvas.restore();
+            }
+        }
+
+        if (mRenderComplete) {
+            if (!mBackgroundTileUploaded) {
+                uploadBackgroundTiles(canvas);
+            }
+        } else {
+            invalidate();
+        }
+        return mRenderComplete || mPreview != null;
+    }
+
+    private void uploadBackgroundTiles(GLCanvas canvas) {
+        mBackgroundTileUploaded = true;
+        int n = mActiveTiles.size();
+        for (int i = 0; i < n; i++) {
+            Tile tile = mActiveTiles.valueAt(i);
+            if (!tile.isContentValid()) {
+                queueForDecode(tile);
+            }
+        }
+    }
+
+   private void queueForDecode(Tile tile) {
+       synchronized (mQueueLock) {
+           if (tile.mTileState == STATE_ACTIVATED) {
+               tile.mTileState = STATE_IN_QUEUE;
+               if (mDecodeQueue.push(tile)) {
+                   mQueueLock.notifyAll();
+               }
+           }
+       }
+    }
+
+    private void decodeTile(Tile tile) {
+        synchronized (mQueueLock) {
+            if (tile.mTileState != STATE_IN_QUEUE) {
+                return;
+            }
+            tile.mTileState = STATE_DECODING;
+        }
+        boolean decodeComplete = tile.decode();
+        synchronized (mQueueLock) {
+            if (tile.mTileState == STATE_RECYCLING) {
+                tile.mTileState = STATE_RECYCLED;
+                if (tile.mDecodedTile != null) {
+                    sTilePool.release(tile.mDecodedTile);
+                    tile.mDecodedTile = null;
+                }
+                mRecycledQueue.push(tile);
+                return;
+            }
+            tile.mTileState = decodeComplete ? STATE_DECODED : STATE_DECODE_FAIL;
+            if (!decodeComplete) {
+                return;
+            }
+            mUploadQueue.push(tile);
+        }
+        invalidate();
+    }
+
+    private Tile obtainTile(int x, int y, int level) {
+        synchronized (mQueueLock) {
+            Tile tile = mRecycledQueue.pop();
+            if (tile != null) {
+                tile.mTileState = STATE_ACTIVATED;
+                tile.update(x, y, level);
+                return tile;
+            }
+            return new Tile(x, y, level);
+        }
+    }
+
+    private void recycleTile(Tile tile) {
+        synchronized (mQueueLock) {
+            if (tile.mTileState == STATE_DECODING) {
+                tile.mTileState = STATE_RECYCLING;
+                return;
+            }
+            tile.mTileState = STATE_RECYCLED;
+            if (tile.mDecodedTile != null) {
+                sTilePool.release(tile.mDecodedTile);
+                tile.mDecodedTile = null;
+            }
+            mRecycledQueue.push(tile);
+        }
+    }
+
+    private void activateTile(int x, int y, int level) {
+        long key = makeTileKey(x, y, level);
+        Tile tile = mActiveTiles.get(key);
+        if (tile != null) {
+            if (tile.mTileState == STATE_IN_QUEUE) {
+                tile.mTileState = STATE_ACTIVATED;
+            }
+            return;
+        }
+        tile = obtainTile(x, y, level);
+        mActiveTiles.put(key, tile);
+    }
+
+    private Tile getTile(int x, int y, int level) {
+        return mActiveTiles.get(makeTileKey(x, y, level));
+    }
+
+    private static long makeTileKey(int x, int y, int level) {
+        long result = x;
+        result = (result << 16) | y;
+        result = (result << 16) | level;
+        return result;
+    }
+
+    private void uploadTiles(GLCanvas canvas) {
+        int quota = UPLOAD_LIMIT;
+        Tile tile = null;
+        while (quota > 0) {
+            synchronized (mQueueLock) {
+                tile = mUploadQueue.pop();
+            }
+            if (tile == null) {
+                break;
+            }
+            if (!tile.isContentValid()) {
+                if (tile.mTileState == STATE_DECODED) {
+                    tile.updateContent(canvas);
+                    --quota;
+                } else {
+                    Log.w(TAG, "Tile in upload queue has invalid state: " + tile.mTileState);
+                }
+            }
+        }
+        if (tile != null) {
+            invalidate();
+        }
+    }
+
+    // Draw the tile to a square at canvas that locates at (x, y) and
+    // has a side length of length.
+    private void drawTile(GLCanvas canvas,
+            int tx, int ty, int level, float x, float y, float length) {
+        RectF source = mSourceRect;
+        RectF target = mTargetRect;
+        target.set(x, y, x + length, y + length);
+        source.set(0, 0, mTileSize, mTileSize);
+
+        Tile tile = getTile(tx, ty, level);
+        if (tile != null) {
+            if (!tile.isContentValid()) {
+                if (tile.mTileState == STATE_DECODED) {
+                    if (mUploadQuota > 0) {
+                        --mUploadQuota;
+                        tile.updateContent(canvas);
+                    } else {
+                        mRenderComplete = false;
+                    }
+                } else if (tile.mTileState != STATE_DECODE_FAIL){
+                    mRenderComplete = false;
+                    queueForDecode(tile);
+                }
+            }
+            if (drawTile(tile, canvas, source, target)) {
+                return;
+            }
+        }
+        if (mPreview != null) {
+            int size = mTileSize << level;
+            float scaleX = (float) mPreview.getWidth() / mImageWidth;
+            float scaleY = (float) mPreview.getHeight() / mImageHeight;
+            source.set(tx * scaleX, ty * scaleY, (tx + size) * scaleX,
+                    (ty + size) * scaleY);
+            canvas.drawTexture(mPreview, source, target);
+        }
+    }
+
+    private boolean drawTile(
+            Tile tile, GLCanvas canvas, RectF source, RectF target) {
+        while (true) {
+            if (tile.isContentValid()) {
+                canvas.drawTexture(tile, source, target);
+                return true;
+            }
+
+            // Parent can be divided to four quads and tile is one of the four.
+            Tile parent = tile.getParentTile();
+            if (parent == null) {
+                return false;
+            }
+            if (tile.mX == parent.mX) {
+                source.left /= 2f;
+                source.right /= 2f;
+            } else {
+                source.left = (mTileSize + source.left) / 2f;
+                source.right = (mTileSize + source.right) / 2f;
+            }
+            if (tile.mY == parent.mY) {
+                source.top /= 2f;
+                source.bottom /= 2f;
+            } else {
+                source.top = (mTileSize + source.top) / 2f;
+                source.bottom = (mTileSize + source.bottom) / 2f;
+            }
+            tile = parent;
+        }
+    }
+
+    private class Tile extends UploadedTexture {
+        public int mX;
+        public int mY;
+        public int mTileLevel;
+        public Tile mNext;
+        public Bitmap mDecodedTile;
+        public volatile int mTileState = STATE_ACTIVATED;
+
+        public Tile(int x, int y, int level) {
+            mX = x;
+            mY = y;
+            mTileLevel = level;
+        }
+
+        @Override
+        protected void onFreeBitmap(Bitmap bitmap) {
+            sTilePool.release(bitmap);
+        }
+
+        boolean decode() {
+            // Get a tile from the original image. The tile is down-scaled
+            // by (1 << mTilelevel) from a region in the original image.
+            try {
+                Bitmap reuse = sTilePool.acquire();
+                if (reuse != null && reuse.getWidth() != mTileSize) {
+                    reuse = null;
+                }
+                mDecodedTile = mModel.getTile(mTileLevel, mX, mY, reuse);
+            } catch (Throwable t) {
+                Log.w(TAG, "fail to decode tile", t);
+            }
+            return mDecodedTile != null;
+        }
+
+        @Override
+        protected Bitmap onGetBitmap() {
+            Utils.assertTrue(mTileState == STATE_DECODED);
+
+            // We need to override the width and height, so that we won't
+            // draw beyond the boundaries.
+            int rightEdge = ((mImageWidth - mX) >> mTileLevel);
+            int bottomEdge = ((mImageHeight - mY) >> mTileLevel);
+            setSize(Math.min(mTileSize, rightEdge), Math.min(mTileSize, bottomEdge));
+
+            Bitmap bitmap = mDecodedTile;
+            mDecodedTile = null;
+            mTileState = STATE_ACTIVATED;
+            return bitmap;
+        }
+
+        // We override getTextureWidth() and getTextureHeight() here, so the
+        // texture can be re-used for different tiles regardless of the actual
+        // size of the tile (which may be small because it is a tile at the
+        // boundary).
+        @Override
+        public int getTextureWidth() {
+            return mTileSize;
+        }
+
+        @Override
+        public int getTextureHeight() {
+            return mTileSize;
+        }
+
+        public void update(int x, int y, int level) {
+            mX = x;
+            mY = y;
+            mTileLevel = level;
+            invalidateContent();
+        }
+
+        public Tile getParentTile() {
+            if (mTileLevel + 1 == mLevelCount) {
+                return null;
+            }
+            int size = mTileSize << (mTileLevel + 1);
+            int x = size * (mX / size);
+            int y = size * (mY / size);
+            return getTile(x, y, mTileLevel + 1);
+        }
+
+        @Override
+        public String toString() {
+            return String.format("tile(%s, %s, %s / %s)",
+                    mX / mTileSize, mY / mTileSize, mLevel, mLevelCount);
+        }
+    }
+
+    private static class TileQueue {
+        private Tile mHead;
+
+        public Tile pop() {
+            Tile tile = mHead;
+            if (tile != null) {
+                mHead = tile.mNext;
+            }
+            return tile;
+        }
+
+        public boolean push(Tile tile) {
+            if (contains(tile)) {
+                Log.w(TAG, "Attempting to add a tile already in the queue!");
+                return false;
+            }
+            boolean wasEmpty = mHead == null;
+            tile.mNext = mHead;
+            mHead = tile;
+            return wasEmpty;
+        }
+
+        private boolean contains(Tile tile) {
+            Tile other = mHead;
+            while (other != null) {
+                if (other == tile) {
+                    return true;
+                }
+                other = other.mNext;
+            }
+            return false;
+        }
+
+        public void clean() {
+            mHead = null;
+        }
+    }
+
+    private class TileDecoder extends Thread {
+
+        public void finishAndWait() {
+            interrupt();
+            try {
+                join();
+            } catch (InterruptedException e) {
+                Log.w(TAG, "Interrupted while waiting for TileDecoder thread to finish!");
+            }
+        }
+
+        private Tile waitForTile() throws InterruptedException {
+            synchronized (mQueueLock) {
+                while (true) {
+                    Tile tile = mDecodeQueue.pop();
+                    if (tile != null) {
+                        return tile;
+                    }
+                    mQueueLock.wait();
+                }
+            }
+        }
+
+        @Override
+        public void run() {
+            try {
+                while (!isInterrupted()) {
+                    Tile tile = waitForTile();
+                    decodeTile(tile);
+                }
+            } catch (InterruptedException ex) {
+                // We were finished
+            }
+        }
+
+    }
+}
diff --git a/packages/WallpaperCropper/src/com/android/photos/views/TiledImageView.java b/packages/WallpaperCropper/src/com/android/photos/views/TiledImageView.java
new file mode 100644
index 0000000..36cb438
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/photos/views/TiledImageView.java
@@ -0,0 +1,386 @@
+/*
+ * 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.photos.views;
+
+import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Paint.Align;
+import android.graphics.RectF;
+import android.opengl.GLSurfaceView;
+import android.opengl.GLSurfaceView.Renderer;
+import android.os.Build;
+import android.util.AttributeSet;
+import android.view.Choreographer;
+import android.view.Choreographer.FrameCallback;
+import android.view.View;
+import android.widget.FrameLayout;
+
+import com.android.gallery3d.glrenderer.BasicTexture;
+import com.android.gallery3d.glrenderer.GLES20Canvas;
+import com.android.photos.views.TiledImageRenderer.TileSource;
+
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+/**
+ * Shows an image using {@link TiledImageRenderer} using either {@link GLSurfaceView}
+ * or {@link BlockingGLTextureView}.
+ */
+public class TiledImageView extends FrameLayout {
+
+    private static final boolean USE_TEXTURE_VIEW = false;
+    private static final boolean IS_SUPPORTED =
+            Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN;
+    private static final boolean USE_CHOREOGRAPHER =
+            Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN;
+
+    private BlockingGLTextureView mTextureView;
+    private GLSurfaceView mGLSurfaceView;
+    private boolean mInvalPending = false;
+    private FrameCallback mFrameCallback;
+
+    protected static class ImageRendererWrapper {
+        // Guarded by locks
+        public float scale;
+        public int centerX, centerY;
+        int rotation;
+        public TileSource source;
+        Runnable isReadyCallback;
+
+        // GL thread only
+        TiledImageRenderer image;
+    }
+
+    private float[] mValues = new float[9];
+
+    // -------------------------
+    // Guarded by mLock
+    // -------------------------
+    protected Object mLock = new Object();
+    protected ImageRendererWrapper mRenderer;
+
+    public static boolean isTilingSupported() {
+        return IS_SUPPORTED;
+    }
+
+    public TiledImageView(Context context) {
+        this(context, null);
+    }
+
+    public TiledImageView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        if (!IS_SUPPORTED) {
+            return;
+        }
+
+        mRenderer = new ImageRendererWrapper();
+        mRenderer.image = new TiledImageRenderer(this);
+        View view;
+        if (USE_TEXTURE_VIEW) {
+            mTextureView = new BlockingGLTextureView(context);
+            mTextureView.setRenderer(new TileRenderer());
+            view = mTextureView;
+        } else {
+            mGLSurfaceView = new GLSurfaceView(context);
+            mGLSurfaceView.setEGLContextClientVersion(2);
+            mGLSurfaceView.setRenderer(new TileRenderer());
+            mGLSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
+            view = mGLSurfaceView;
+        }
+        addView(view, new LayoutParams(
+                LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
+        //setTileSource(new ColoredTiles());
+    }
+
+    public void destroy() {
+        if (!IS_SUPPORTED) {
+            return;
+        }
+        if (USE_TEXTURE_VIEW) {
+            mTextureView.destroy();
+        } else {
+            mGLSurfaceView.queueEvent(mFreeTextures);
+        }
+    }
+
+    private Runnable mFreeTextures = new Runnable() {
+
+        @Override
+        public void run() {
+            mRenderer.image.freeTextures();
+        }
+    };
+
+    public void onPause() {
+        if (!IS_SUPPORTED) {
+            return;
+        }
+        if (!USE_TEXTURE_VIEW) {
+            mGLSurfaceView.onPause();
+        }
+    }
+
+    public void onResume() {
+        if (!IS_SUPPORTED) {
+            return;
+        }
+        if (!USE_TEXTURE_VIEW) {
+            mGLSurfaceView.onResume();
+        }
+    }
+
+    public void setTileSource(TileSource source, Runnable isReadyCallback) {
+        if (!IS_SUPPORTED) {
+            return;
+        }
+        synchronized (mLock) {
+            mRenderer.source = source;
+            mRenderer.isReadyCallback = isReadyCallback;
+            mRenderer.centerX = source != null ? source.getImageWidth() / 2 : 0;
+            mRenderer.centerY = source != null ? source.getImageHeight() / 2 : 0;
+            mRenderer.rotation = source != null ? source.getRotation() : 0;
+            mRenderer.scale = 0;
+            updateScaleIfNecessaryLocked(mRenderer);
+        }
+        invalidate();
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right,
+            int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+        if (!IS_SUPPORTED) {
+            return;
+        }
+        synchronized (mLock) {
+            updateScaleIfNecessaryLocked(mRenderer);
+        }
+    }
+
+    private void updateScaleIfNecessaryLocked(ImageRendererWrapper renderer) {
+        if (renderer == null || renderer.source == null
+                || renderer.scale > 0 || getWidth() == 0) {
+            return;
+        }
+        renderer.scale = Math.min(
+                (float) getWidth() / (float) renderer.source.getImageWidth(),
+                (float) getHeight() / (float) renderer.source.getImageHeight());
+    }
+
+    @Override
+    protected void dispatchDraw(Canvas canvas) {
+        if (!IS_SUPPORTED) {
+            return;
+        }
+        if (USE_TEXTURE_VIEW) {
+            mTextureView.render();
+        }
+        super.dispatchDraw(canvas);
+    }
+
+    @SuppressLint("NewApi")
+    @Override
+    public void setTranslationX(float translationX) {
+        if (!IS_SUPPORTED) {
+            return;
+        }
+        super.setTranslationX(translationX);
+    }
+
+    @Override
+    public void invalidate() {
+        if (!IS_SUPPORTED) {
+            return;
+        }
+        if (USE_TEXTURE_VIEW) {
+            super.invalidate();
+            mTextureView.invalidate();
+        } else {
+            if (USE_CHOREOGRAPHER) {
+                invalOnVsync();
+            } else {
+                mGLSurfaceView.requestRender();
+            }
+        }
+    }
+
+    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
+    private void invalOnVsync() {
+        if (!mInvalPending) {
+            mInvalPending = true;
+            if (mFrameCallback == null) {
+                mFrameCallback = new FrameCallback() {
+                    @Override
+                    public void doFrame(long frameTimeNanos) {
+                        mInvalPending = false;
+                        mGLSurfaceView.requestRender();
+                    }
+                };
+            }
+            Choreographer.getInstance().postFrameCallback(mFrameCallback);
+        }
+    }
+
+    private RectF mTempRectF = new RectF();
+    public void positionFromMatrix(Matrix matrix) {
+        if (!IS_SUPPORTED) {
+            return;
+        }
+        if (mRenderer.source != null) {
+            final int rotation = mRenderer.source.getRotation();
+            final boolean swap = !(rotation % 180 == 0);
+            final int width = swap ? mRenderer.source.getImageHeight()
+                    : mRenderer.source.getImageWidth();
+            final int height = swap ? mRenderer.source.getImageWidth()
+                    : mRenderer.source.getImageHeight();
+            mTempRectF.set(0, 0, width, height);
+            matrix.mapRect(mTempRectF);
+            matrix.getValues(mValues);
+            int cx = width / 2;
+            int cy = height / 2;
+            float scale = mValues[Matrix.MSCALE_X];
+            int xoffset = Math.round((getWidth() - mTempRectF.width()) / 2 / scale);
+            int yoffset = Math.round((getHeight() - mTempRectF.height()) / 2 / scale);
+            if (rotation == 90 || rotation == 180) {
+                cx += (mTempRectF.left / scale) - xoffset;
+            } else {
+                cx -= (mTempRectF.left / scale) - xoffset;
+            }
+            if (rotation == 180 || rotation == 270) {
+                cy += (mTempRectF.top / scale) - yoffset;
+            } else {
+                cy -= (mTempRectF.top / scale) - yoffset;
+            }
+            mRenderer.scale = scale;
+            mRenderer.centerX = swap ? cy : cx;
+            mRenderer.centerY = swap ? cx : cy;
+            invalidate();
+        }
+    }
+
+    private class TileRenderer implements Renderer {
+
+        private GLES20Canvas mCanvas;
+
+        @Override
+        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+            mCanvas = new GLES20Canvas();
+            BasicTexture.invalidateAllTextures();
+            mRenderer.image.setModel(mRenderer.source, mRenderer.rotation);
+        }
+
+        @Override
+        public void onSurfaceChanged(GL10 gl, int width, int height) {
+            mCanvas.setSize(width, height);
+            mRenderer.image.setViewSize(width, height);
+        }
+
+        @Override
+        public void onDrawFrame(GL10 gl) {
+            mCanvas.clearBuffer();
+            Runnable readyCallback;
+            synchronized (mLock) {
+                readyCallback = mRenderer.isReadyCallback;
+                mRenderer.image.setModel(mRenderer.source, mRenderer.rotation);
+                mRenderer.image.setPosition(mRenderer.centerX, mRenderer.centerY,
+                        mRenderer.scale);
+            }
+            boolean complete = mRenderer.image.draw(mCanvas);
+            if (complete && readyCallback != null) {
+                synchronized (mLock) {
+                    // Make sure we don't trample on a newly set callback/source
+                    // if it changed while we were rendering
+                    if (mRenderer.isReadyCallback == readyCallback) {
+                        mRenderer.isReadyCallback = null;
+                    }
+                }
+                if (readyCallback != null) {
+                    post(readyCallback);
+                }
+            }
+        }
+
+    }
+
+    @SuppressWarnings("unused")
+    private static class ColoredTiles implements TileSource {
+        private static final int[] COLORS = new int[] {
+            Color.RED,
+            Color.BLUE,
+            Color.YELLOW,
+            Color.GREEN,
+            Color.CYAN,
+            Color.MAGENTA,
+            Color.WHITE,
+        };
+
+        private Paint mPaint = new Paint();
+        private Canvas mCanvas = new Canvas();
+
+        @Override
+        public int getTileSize() {
+            return 256;
+        }
+
+        @Override
+        public int getImageWidth() {
+            return 16384;
+        }
+
+        @Override
+        public int getImageHeight() {
+            return 8192;
+        }
+
+        @Override
+        public int getRotation() {
+            return 0;
+        }
+
+        @Override
+        public Bitmap getTile(int level, int x, int y, Bitmap bitmap) {
+            int tileSize = getTileSize();
+            if (bitmap == null) {
+                bitmap = Bitmap.createBitmap(tileSize, tileSize,
+                        Bitmap.Config.ARGB_8888);
+            }
+            mCanvas.setBitmap(bitmap);
+            mCanvas.drawColor(COLORS[level]);
+            mPaint.setColor(Color.BLACK);
+            mPaint.setTextSize(20);
+            mPaint.setTextAlign(Align.CENTER);
+            mCanvas.drawText(x + "x" + y, 128, 128, mPaint);
+            tileSize <<= level;
+            x /= tileSize;
+            y /= tileSize;
+            mCanvas.drawText(x + "x" + y + " @ " + level, 128, 30, mPaint);
+            mCanvas.setBitmap(null);
+            return bitmap;
+        }
+
+        @Override
+        public BasicTexture getPreview() {
+            return null;
+        }
+    }
+}
diff --git a/packages/WallpaperCropper/src/com/android/wallpapercropper/CropView.java b/packages/WallpaperCropper/src/com/android/wallpapercropper/CropView.java
new file mode 100644
index 0000000..ecebd642
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/wallpapercropper/CropView.java
@@ -0,0 +1,246 @@
+/*
+ * 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.
+ */
+/* Copied from Launcher3 */
+package com.android.wallpapercropper;
+
+import android.content.Context;
+import android.graphics.Point;
+import android.graphics.RectF;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.ScaleGestureDetector;
+import android.view.ViewConfiguration;
+import android.view.ScaleGestureDetector.OnScaleGestureListener;
+import android.view.ViewTreeObserver;
+import android.view.ViewTreeObserver.OnGlobalLayoutListener;
+
+import com.android.photos.views.TiledImageRenderer.TileSource;
+import com.android.photos.views.TiledImageView;
+
+public class CropView extends TiledImageView implements OnScaleGestureListener {
+
+    private ScaleGestureDetector mScaleGestureDetector;
+    private long mTouchDownTime;
+    private float mFirstX, mFirstY;
+    private float mLastX, mLastY;
+    private float mMinScale;
+    private boolean mTouchEnabled = true;
+    private RectF mTempEdges = new RectF();
+    TouchCallback mTouchCallback;
+
+    public interface TouchCallback {
+        void onTouchDown();
+        void onTap();
+    }
+
+    public CropView(Context context) {
+        this(context, null);
+    }
+
+    public CropView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        mScaleGestureDetector = new ScaleGestureDetector(context, this);
+    }
+
+    private void getEdgesHelper(RectF edgesOut) {
+        final float width = getWidth();
+        final float height = getHeight();
+        final float imageWidth = mRenderer.source.getImageWidth();
+        final float imageHeight = mRenderer.source.getImageHeight();
+        final float scale = mRenderer.scale;
+        float centerX = (width / 2f - mRenderer.centerX + (imageWidth - width) / 2f)
+                * scale + width / 2f;
+        float centerY = (height / 2f - mRenderer.centerY + (imageHeight - height) / 2f)
+                * scale + height / 2f;
+        float leftEdge = centerX - imageWidth / 2f * scale;
+        float rightEdge = centerX + imageWidth / 2f * scale;
+        float topEdge = centerY - imageHeight / 2f * scale;
+        float bottomEdge = centerY + imageHeight / 2f * scale;
+
+        edgesOut.left = leftEdge;
+        edgesOut.right = rightEdge;
+        edgesOut.top = topEdge;
+        edgesOut.bottom = bottomEdge;
+    }
+
+    public RectF getCrop() {
+        final RectF edges = mTempEdges;
+        getEdgesHelper(edges);
+        final float scale = mRenderer.scale;
+
+        float cropLeft = -edges.left / scale;
+        float cropTop = -edges.top / scale;
+        float cropRight = cropLeft + getWidth() / scale;
+        float cropBottom = cropTop + getHeight() / scale;
+
+        return new RectF(cropLeft, cropTop, cropRight, cropBottom);
+    }
+
+    public Point getSourceDimensions() {
+        return new Point(mRenderer.source.getImageWidth(), mRenderer.source.getImageHeight());
+    }
+
+    public void setTileSource(TileSource source, Runnable isReadyCallback) {
+        super.setTileSource(source, isReadyCallback);
+        updateMinScale(getWidth(), getHeight(), source, true);
+    }
+
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        updateMinScale(w, h, mRenderer.source, false);
+    }
+
+    public void setScale(float scale) {
+        synchronized (mLock) {
+            mRenderer.scale = scale;
+        }
+    }
+
+    private void updateMinScale(int w, int h, TileSource source, boolean resetScale) {
+        synchronized (mLock) {
+            if (resetScale) {
+                mRenderer.scale = 1;
+            }
+            if (source != null) {
+                mMinScale = Math.max(w / (float) source.getImageWidth(),
+                        h / (float) source.getImageHeight());
+                mRenderer.scale = Math.max(mMinScale, mRenderer.scale);
+            }
+        }
+    }
+
+    @Override
+    public boolean onScaleBegin(ScaleGestureDetector detector) {
+        return true;
+    }
+
+    @Override
+    public boolean onScale(ScaleGestureDetector detector) {
+        // Don't need the lock because this will only fire inside of
+        // onTouchEvent
+        mRenderer.scale *= detector.getScaleFactor();
+        mRenderer.scale = Math.max(mMinScale, mRenderer.scale);
+        invalidate();
+        return true;
+    }
+
+    @Override
+    public void onScaleEnd(ScaleGestureDetector detector) {
+    }
+
+    public void moveToUpperLeft() {
+        if (getWidth() == 0 || getHeight() == 0) {
+            final ViewTreeObserver observer = getViewTreeObserver();
+            observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
+                    public void onGlobalLayout() {
+                        moveToUpperLeft();
+                        getViewTreeObserver().removeOnGlobalLayoutListener(this);
+                    }
+                });
+        }
+        final RectF edges = mTempEdges;
+        getEdgesHelper(edges);
+        final float scale = mRenderer.scale;
+        mRenderer.centerX += Math.ceil(edges.left / scale);
+        mRenderer.centerY += Math.ceil(edges.top / scale);
+    }
+
+    public void setTouchEnabled(boolean enabled) {
+        mTouchEnabled = enabled;
+    }
+
+    public void setTouchCallback(TouchCallback cb) {
+        mTouchCallback = cb;
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        int action = event.getActionMasked();
+        final boolean pointerUp = action == MotionEvent.ACTION_POINTER_UP;
+        final int skipIndex = pointerUp ? event.getActionIndex() : -1;
+
+        // Determine focal point
+        float sumX = 0, sumY = 0;
+        final int count = event.getPointerCount();
+        for (int i = 0; i < count; i++) {
+            if (skipIndex == i)
+                continue;
+            sumX += event.getX(i);
+            sumY += event.getY(i);
+        }
+        final int div = pointerUp ? count - 1 : count;
+        float x = sumX / div;
+        float y = sumY / div;
+
+        if (action == MotionEvent.ACTION_DOWN) {
+            mFirstX = x;
+            mFirstY = y;
+            mTouchDownTime = System.currentTimeMillis();
+            if (mTouchCallback != null) {
+                mTouchCallback.onTouchDown();
+            }
+        } else if (action == MotionEvent.ACTION_UP) {
+            ViewConfiguration config = ViewConfiguration.get(getContext());
+
+            float squaredDist = (mFirstX - x) * (mFirstX - x) + (mFirstY - y) * (mFirstY - y);
+            float slop = config.getScaledTouchSlop() * config.getScaledTouchSlop();
+            long now = System.currentTimeMillis();
+            // only do this if it's a small movement
+            if (mTouchCallback != null &&
+                    squaredDist < slop &&
+                    now < mTouchDownTime + ViewConfiguration.getTapTimeout()) {
+                mTouchCallback.onTap();
+            }
+        }
+
+        if (!mTouchEnabled) {
+            return true;
+        }
+
+        synchronized (mLock) {
+            mScaleGestureDetector.onTouchEvent(event);
+            switch (action) {
+                case MotionEvent.ACTION_MOVE:
+                    mRenderer.centerX += (mLastX - x) / mRenderer.scale;
+                    mRenderer.centerY += (mLastY - y) / mRenderer.scale;
+                    invalidate();
+                    break;
+            }
+            if (mRenderer.source != null) {
+                // Adjust position so that the wallpaper covers the entire area
+                // of the screen
+                final RectF edges = mTempEdges;
+                getEdgesHelper(edges);
+                final float scale = mRenderer.scale;
+                if (edges.left > 0) {
+                    mRenderer.centerX += Math.ceil(edges.left / scale);
+                }
+                if (edges.right < getWidth()) {
+                    mRenderer.centerX += (edges.right - getWidth()) / scale;
+                }
+                if (edges.top > 0) {
+                    mRenderer.centerY += Math.ceil(edges.top / scale);
+                }
+                if (edges.bottom < getHeight()) {
+                    mRenderer.centerY += (edges.bottom - getHeight()) / scale;
+                }
+            }
+        }
+
+        mLastX = x;
+        mLastY = y;
+        return true;
+    }
+}
diff --git a/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java b/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java
new file mode 100644
index 0000000..a993ed3
--- /dev/null
+++ b/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java
@@ -0,0 +1,646 @@
+/*
+ * 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.
+ */
+/* Copied from Launcher3 */
+package com.android.wallpapercropper;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.app.WallpaperManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.CompressFormat;
+import android.graphics.BitmapFactory;
+import android.graphics.BitmapRegionDecoder;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Display;
+import android.view.View;
+import android.view.WindowManager;
+
+import com.android.gallery3d.common.Utils;
+import com.android.photos.BitmapRegionTileSource;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class WallpaperCropActivity extends Activity {
+    private static final String LOGTAG = "Launcher3.CropActivity";
+
+    protected static final String WALLPAPER_WIDTH_KEY = "wallpaper.width";
+    protected static final String WALLPAPER_HEIGHT_KEY = "wallpaper.height";
+    private static final int DEFAULT_COMPRESS_QUALITY = 90;
+    /**
+     * The maximum bitmap size we allow to be returned through the intent.
+     * Intents have a maximum of 1MB in total size. However, the Bitmap seems to
+     * have some overhead to hit so that we go way below the limit here to make
+     * sure the intent stays below 1MB.We should consider just returning a byte
+     * array instead of a Bitmap instance to avoid overhead.
+     */
+    public static final int MAX_BMAP_IN_INTENT = 750000;
+    private static final float WALLPAPER_SCREENS_SPAN = 2f;
+
+    protected CropView mCropView;
+    protected Uri mUri;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        init();
+    }
+
+    protected void init() {
+        setContentView(R.layout.wallpaper_cropper);
+
+        mCropView = (CropView) findViewById(R.id.cropView);
+
+        Intent cropIntent = this.getIntent();
+        final Uri imageUri = cropIntent.getData();
+
+        mCropView.setTileSource(new BitmapRegionTileSource(this, imageUri, 1024, 0), null);
+        mCropView.setTouchEnabled(true);
+        // Action bar
+        // Show the custom action bar view
+        final ActionBar actionBar = getActionBar();
+        actionBar.setCustomView(R.layout.actionbar_set_wallpaper);
+        actionBar.getCustomView().setOnClickListener(
+                new View.OnClickListener() {
+                    @Override
+                    public void onClick(View v) {
+                        boolean finishActivityWhenDone = true;
+                        cropImageAndSetWallpaper(imageUri, null, finishActivityWhenDone);
+                    }
+                });
+    }
+
+    public static String getSharedPreferencesKey() {
+        return WallpaperCropActivity.class.getName();
+    }
+
+    // As a ratio of screen height, the total distance we want the parallax effect to span
+    // horizontally
+    private static float wallpaperTravelToScreenWidthRatio(int width, int height) {
+        float aspectRatio = width / (float) height;
+
+        // At an aspect ratio of 16/10, the wallpaper parallax effect should span 1.5 * screen width
+        // At an aspect ratio of 10/16, the wallpaper parallax effect should span 1.2 * screen width
+        // We will use these two data points to extrapolate how much the wallpaper parallax effect
+        // to span (ie travel) at any aspect ratio:
+
+        final float ASPECT_RATIO_LANDSCAPE = 16/10f;
+        final float ASPECT_RATIO_PORTRAIT = 10/16f;
+        final float WALLPAPER_WIDTH_TO_SCREEN_RATIO_LANDSCAPE = 1.5f;
+        final float WALLPAPER_WIDTH_TO_SCREEN_RATIO_PORTRAIT = 1.2f;
+
+        // To find out the desired width at different aspect ratios, we use the following two
+        // formulas, where the coefficient on x is the aspect ratio (width/height):
+        //   (16/10)x + y = 1.5
+        //   (10/16)x + y = 1.2
+        // We solve for x and y and end up with a final formula:
+        final float x =
+            (WALLPAPER_WIDTH_TO_SCREEN_RATIO_LANDSCAPE - WALLPAPER_WIDTH_TO_SCREEN_RATIO_PORTRAIT) /
+            (ASPECT_RATIO_LANDSCAPE - ASPECT_RATIO_PORTRAIT);
+        final float y = WALLPAPER_WIDTH_TO_SCREEN_RATIO_PORTRAIT - x * ASPECT_RATIO_PORTRAIT;
+        return x * aspectRatio + y;
+    }
+
+    static protected Point getDefaultWallpaperSize(Resources res, WindowManager windowManager) {
+        Point minDims = new Point();
+        Point maxDims = new Point();
+        windowManager.getDefaultDisplay().getCurrentSizeRange(minDims, maxDims);
+
+        int maxDim = Math.max(maxDims.x, maxDims.y);
+        final int minDim = Math.min(minDims.x, minDims.y);
+
+        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
+            Point realSize = new Point();
+            windowManager.getDefaultDisplay().getRealSize(realSize);
+            maxDim = Math.max(realSize.x, realSize.y);
+        }
+
+        // We need to ensure that there is enough extra space in the wallpaper
+        // for the intended
+        // parallax effects
+        final int defaultWidth, defaultHeight;
+        if (isScreenLarge(res)) {
+            defaultWidth = (int) (maxDim * wallpaperTravelToScreenWidthRatio(maxDim, minDim));
+            defaultHeight = maxDim;
+        } else {
+            defaultWidth = Math.max((int) (minDim * WALLPAPER_SCREENS_SPAN), maxDim);
+            defaultHeight = maxDim;
+        }
+        return new Point(defaultWidth, defaultHeight);
+    }
+
+    protected void setWallpaper(String filePath, final boolean finishActivityWhenDone) {
+
+        BitmapCropTask cropTask = new BitmapCropTask(this,
+                filePath, null, 0, 0, true, false, null);
+        final Point bounds = cropTask.getImageBounds();
+        Runnable onEndCrop = new Runnable() {
+            public void run() {
+                updateWallpaperDimensions(bounds.x, bounds.y);
+                if (finishActivityWhenDone) {
+                    setResult(Activity.RESULT_OK);
+                    finish();
+                }
+            }
+        };
+        cropTask.setOnEndRunnable(onEndCrop);
+        cropTask.setNoCrop(true);
+        cropTask.execute();
+    }
+
+    protected void cropImageAndSetWallpaper(
+            Resources res, int resId, final boolean finishActivityWhenDone) {
+        // crop this image and scale it down to the default wallpaper size for
+        // this device
+        Point inSize = mCropView.getSourceDimensions();
+        Point outSize = getDefaultWallpaperSize(getResources(),
+                getWindowManager());
+        RectF crop = getMaxCropRect(
+                inSize.x, inSize.y, outSize.x, outSize.y, false);
+        Runnable onEndCrop = new Runnable() {
+            public void run() {
+                // Passing 0, 0 will cause launcher to revert to using the
+                // default wallpaper size
+                updateWallpaperDimensions(0, 0);
+                if (finishActivityWhenDone) {
+                    setResult(Activity.RESULT_OK);
+                    finish();
+                }
+            }
+        };
+        BitmapCropTask cropTask = new BitmapCropTask(res, resId,
+                crop, outSize.x, outSize.y,
+                true, false, onEndCrop);
+        cropTask.execute();
+    }
+
+    private static boolean isScreenLarge(Resources res) {
+        Configuration config = res.getConfiguration();
+        return config.smallestScreenWidthDp >= 720;
+    }
+
+    protected void cropImageAndSetWallpaper(Uri uri,
+            OnBitmapCroppedHandler onBitmapCroppedHandler, final boolean finishActivityWhenDone) {
+     // Get the crop
+        Point inSize = mCropView.getSourceDimensions();
+
+        Point minDims = new Point();
+        Point maxDims = new Point();
+        Display d = getWindowManager().getDefaultDisplay();
+        d.getCurrentSizeRange(minDims, maxDims);
+
+        Point displaySize = new Point();
+        d.getSize(displaySize);
+
+        int maxDim = Math.max(maxDims.x, maxDims.y);
+        final int minDim = Math.min(minDims.x, minDims.y);
+        int defaultWidth;
+        if (isScreenLarge(getResources())) {
+            defaultWidth = (int) (maxDim *
+                    wallpaperTravelToScreenWidthRatio(maxDim, minDim));
+        } else {
+            defaultWidth = Math.max((int)
+                    (minDim * WALLPAPER_SCREENS_SPAN), maxDim);
+        }
+
+        boolean isPortrait = displaySize.x < displaySize.y;
+        int portraitHeight;
+        if (isPortrait) {
+            portraitHeight = mCropView.getHeight();
+        } else {
+            // TODO: how to actually get the proper portrait height?
+            // This is not quite right:
+            portraitHeight = Math.max(maxDims.x, maxDims.y);
+        }
+        if (android.os.Build.VERSION.SDK_INT >=
+                android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
+            Point realSize = new Point();
+            d.getRealSize(realSize);
+            portraitHeight = Math.max(realSize.x, realSize.y);
+        }
+        // Get the crop
+        RectF cropRect = mCropView.getCrop();
+        float cropScale = mCropView.getWidth() / (float) cropRect.width();
+
+        // ADJUST CROP WIDTH
+        // Extend the crop all the way to the right, for parallax
+        float extraSpaceToRight = inSize.x - cropRect.right;
+        // Cap the amount of extra width
+        float maxExtraSpace = defaultWidth / cropScale - cropRect.width();
+        extraSpaceToRight = Math.min(extraSpaceToRight, maxExtraSpace);
+
+        cropRect.right += extraSpaceToRight;
+
+        // ADJUST CROP HEIGHT
+        if (isPortrait) {
+            cropRect.bottom = cropRect.top + portraitHeight / cropScale;
+        } else { // LANDSCAPE
+            float extraPortraitHeight =
+                    portraitHeight / cropScale - cropRect.height();
+            float expandHeight =
+                    Math.min(Math.min(inSize.y - cropRect.bottom, cropRect.top),
+                            extraPortraitHeight / 2);
+            cropRect.top -= expandHeight;
+            cropRect.bottom += expandHeight;
+        }
+        final int outWidth = (int) Math.round(cropRect.width() * cropScale);
+        final int outHeight = (int) Math.round(cropRect.height() * cropScale);
+
+        Runnable onEndCrop = new Runnable() {
+            public void run() {
+                updateWallpaperDimensions(outWidth, outHeight);
+                if (finishActivityWhenDone) {
+                    setResult(Activity.RESULT_OK);
+                    finish();
+                }
+            }
+        };
+        BitmapCropTask cropTask = new BitmapCropTask(uri,
+                cropRect, outWidth, outHeight, true, false, onEndCrop);
+        if (onBitmapCroppedHandler != null) {
+            cropTask.setOnBitmapCropped(onBitmapCroppedHandler);
+        }
+        cropTask.execute();
+    }
+
+    public interface OnBitmapCroppedHandler {
+        public void onBitmapCropped(byte[] imageBytes);
+    }
+
+    protected class BitmapCropTask extends AsyncTask<Void, Void, Boolean> {
+        Uri mInUri = null;
+        Context mContext;
+        String mInFilePath;
+        byte[] mInImageBytes;
+        int mInResId = 0;
+        InputStream mInStream;
+        RectF mCropBounds = null;
+        int mOutWidth, mOutHeight;
+        int mRotation = 0; // for now
+        protected final WallpaperManager mWPManager;
+        String mOutputFormat = "jpg"; // for now
+        boolean mSetWallpaper;
+        boolean mSaveCroppedBitmap;
+        Bitmap mCroppedBitmap;
+        Runnable mOnEndRunnable;
+        Resources mResources;
+        OnBitmapCroppedHandler mOnBitmapCroppedHandler;
+        boolean mNoCrop;
+
+        public BitmapCropTask(Context c, String filePath,
+                RectF cropBounds, int outWidth, int outHeight,
+                boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
+            mContext = c;
+            mInFilePath = filePath;
+            mWPManager = WallpaperManager.getInstance(getApplicationContext());
+            init(cropBounds, outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
+        }
+
+        public BitmapCropTask(byte[] imageBytes,
+                RectF cropBounds, int outWidth, int outHeight,
+                boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
+            mInImageBytes = imageBytes;
+            mWPManager = WallpaperManager.getInstance(getApplicationContext());
+            init(cropBounds, outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
+        }
+
+        public BitmapCropTask(Uri inUri,
+                RectF cropBounds, int outWidth, int outHeight,
+                boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
+            mInUri = inUri;
+            mWPManager = WallpaperManager.getInstance(getApplicationContext());
+            init(cropBounds, outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
+        }
+
+        public BitmapCropTask(Resources res, int inResId,
+                RectF cropBounds, int outWidth, int outHeight,
+                boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
+            mInResId = inResId;
+            mResources = res;
+            mWPManager = WallpaperManager.getInstance(getApplicationContext());
+            init(cropBounds, outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
+        }
+
+        private void init(RectF cropBounds, int outWidth, int outHeight,
+                boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
+            mCropBounds = cropBounds;
+            mOutWidth = outWidth;
+            mOutHeight = outHeight;
+            mSetWallpaper = setWallpaper;
+            mSaveCroppedBitmap = saveCroppedBitmap;
+            mOnEndRunnable = onEndRunnable;
+        }
+
+        public void setOnBitmapCropped(OnBitmapCroppedHandler handler) {
+            mOnBitmapCroppedHandler = handler;
+        }
+
+        public void setNoCrop(boolean value) {
+            mNoCrop = value;
+        }
+
+        public void setOnEndRunnable(Runnable onEndRunnable) {
+            mOnEndRunnable = onEndRunnable;
+        }
+
+        // Helper to setup input stream
+        private void regenerateInputStream() {
+            if (mInUri == null && mInResId == 0 && mInFilePath == null && mInImageBytes == null) {
+                Log.w(LOGTAG, "cannot read original file, no input URI, resource ID, or " +
+                        "image byte array given");
+            } else {
+                Utils.closeSilently(mInStream);
+                try {
+                    if (mInUri != null) {
+                        mInStream = new BufferedInputStream(
+                                getContentResolver().openInputStream(mInUri));
+                    } else if (mInFilePath != null) {
+                        mInStream = mContext.openFileInput(mInFilePath);
+                    } else if (mInImageBytes != null) {
+                        mInStream = new BufferedInputStream(
+                                new ByteArrayInputStream(mInImageBytes));
+                    } else {
+                        mInStream = new BufferedInputStream(
+                                mResources.openRawResource(mInResId));
+                    }
+                } catch (FileNotFoundException e) {
+                    Log.w(LOGTAG, "cannot read file: " + mInUri.toString(), e);
+                }
+            }
+        }
+
+        public Point getImageBounds() {
+            regenerateInputStream();
+            if (mInStream != null) {
+                BitmapFactory.Options options = new BitmapFactory.Options();
+                options.inJustDecodeBounds = true;
+                BitmapFactory.decodeStream(mInStream, null, options);
+                if (options.outWidth != 0 && options.outHeight != 0) {
+                    return new Point(options.outWidth, options.outHeight);
+                }
+            }
+            return null;
+        }
+
+        public void setCropBounds(RectF cropBounds) {
+            mCropBounds = cropBounds;
+        }
+
+        public Bitmap getCroppedBitmap() {
+            return mCroppedBitmap;
+        }
+        public boolean cropBitmap() {
+            boolean failure = false;
+
+            regenerateInputStream();
+
+            if (mNoCrop && mInStream != null) {
+                try {
+                    mWPManager.setStream(mInStream);
+                } catch (IOException e) {
+                    Log.w(LOGTAG, "cannot write stream to wallpaper", e);
+                    failure = true;
+                }
+                if (mOnEndRunnable != null) {
+                    mOnEndRunnable.run();
+                }
+                return !failure;
+            }
+            if (mInStream != null) {
+                // Find crop bounds (scaled to original image size)
+                Rect roundedTrueCrop = new Rect();
+                mCropBounds.roundOut(roundedTrueCrop);
+
+                if (roundedTrueCrop.width() <= 0 || roundedTrueCrop.height() <= 0) {
+                    Log.w(LOGTAG, "crop has bad values for full size image");
+                    failure = true;
+                    return false;
+                }
+
+                // See how much we're reducing the size of the image
+                int scaleDownSampleSize = Math.min(roundedTrueCrop.width() / mOutWidth,
+                        roundedTrueCrop.height() / mOutHeight);
+
+                // Attempt to open a region decoder
+                BitmapRegionDecoder decoder = null;
+                try {
+                    decoder = BitmapRegionDecoder.newInstance(mInStream, true);
+                } catch (IOException e) {
+                    Log.w(LOGTAG, "cannot open region decoder for file: " + mInUri.toString(), e);
+                }
+
+                Bitmap crop = null;
+                if (decoder != null) {
+                    // Do region decoding to get crop bitmap
+                    BitmapFactory.Options options = new BitmapFactory.Options();
+                    if (scaleDownSampleSize > 1) {
+                        options.inSampleSize = scaleDownSampleSize;
+                    }
+                    crop = decoder.decodeRegion(roundedTrueCrop, options);
+                    decoder.recycle();
+                }
+
+                if (crop == null) {
+                    // BitmapRegionDecoder has failed, try to crop in-memory
+                    regenerateInputStream();
+                    Bitmap fullSize = null;
+                    if (mInStream != null) {
+                        BitmapFactory.Options options = new BitmapFactory.Options();
+                        if (scaleDownSampleSize > 1) {
+                            options.inSampleSize = scaleDownSampleSize;
+                        }
+                        fullSize = BitmapFactory.decodeStream(mInStream, null, options);
+                    }
+                    if (fullSize != null) {
+                        crop = Bitmap.createBitmap(fullSize, roundedTrueCrop.left,
+                                roundedTrueCrop.top, roundedTrueCrop.width(),
+                                roundedTrueCrop.height());
+                    }
+                }
+
+                if (crop == null) {
+                    Log.w(LOGTAG, "cannot decode file: " + mInUri.toString());
+                    failure = true;
+                    return false;
+                }
+                if (mOutWidth > 0 && mOutHeight > 0) {
+                    Matrix m = new Matrix();
+                    RectF cropRect = new RectF(0, 0, crop.getWidth(), crop.getHeight());
+                    if (mRotation > 0) {
+                        m.setRotate(mRotation);
+                        m.mapRect(cropRect);
+                    }
+                    RectF returnRect = new RectF(0, 0, mOutWidth, mOutHeight);
+                    m.setRectToRect(cropRect, returnRect, Matrix.ScaleToFit.FILL);
+                    m.preRotate(mRotation);
+                    Bitmap tmp = Bitmap.createBitmap((int) returnRect.width(),
+                            (int) returnRect.height(), Bitmap.Config.ARGB_8888);
+                    if (tmp != null) {
+                        Canvas c = new Canvas(tmp);
+                        c.drawBitmap(crop, m, new Paint());
+                        crop = tmp;
+                    }
+                } else if (mRotation > 0) {
+                    Matrix m = new Matrix();
+                    m.setRotate(mRotation);
+                    Bitmap tmp = Bitmap.createBitmap(crop, 0, 0, crop.getWidth(),
+                            crop.getHeight(), m, true);
+                    if (tmp != null) {
+                        crop = tmp;
+                    }
+                }
+
+                if (mSaveCroppedBitmap) {
+                    mCroppedBitmap = crop;
+                }
+
+                // Get output compression format
+                CompressFormat cf =
+                        convertExtensionToCompressFormat(getFileExtension(mOutputFormat));
+
+                // Compress to byte array
+                ByteArrayOutputStream tmpOut = new ByteArrayOutputStream(2048);
+                if (crop.compress(cf, DEFAULT_COMPRESS_QUALITY, tmpOut)) {
+                    // If we need to set to the wallpaper, set it
+                    if (mSetWallpaper && mWPManager != null) {
+                        if (mWPManager == null) {
+                            Log.w(LOGTAG, "no wallpaper manager");
+                            failure = true;
+                        } else {
+                            try {
+                                byte[] outByteArray = tmpOut.toByteArray();
+                                mWPManager.setStream(new ByteArrayInputStream(outByteArray));
+                                if (mOnBitmapCroppedHandler != null) {
+                                    mOnBitmapCroppedHandler.onBitmapCropped(outByteArray);
+                                }
+                            } catch (IOException e) {
+                                Log.w(LOGTAG, "cannot write stream to wallpaper", e);
+                                failure = true;
+                            }
+                        }
+                    }
+                    if (mOnEndRunnable != null) {
+                        mOnEndRunnable.run();
+                    }
+                } else {
+                    Log.w(LOGTAG, "cannot compress bitmap");
+                    failure = true;
+                }
+            }
+            return !failure; // True if any of the operations failed
+        }
+
+        @Override
+        protected Boolean doInBackground(Void... params) {
+            return cropBitmap();
+        }
+
+        @Override
+        protected void onPostExecute(Boolean result) {
+            setResult(Activity.RESULT_OK);
+            finish();
+        }
+    }
+
+    protected void updateWallpaperDimensions(int width, int height) {
+        String spKey = getSharedPreferencesKey();
+        SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE);
+        SharedPreferences.Editor editor = sp.edit();
+        if (width != 0 && height != 0) {
+            editor.putInt(WALLPAPER_WIDTH_KEY, width);
+            editor.putInt(WALLPAPER_HEIGHT_KEY, height);
+        } else {
+            editor.remove(WALLPAPER_WIDTH_KEY);
+            editor.remove(WALLPAPER_HEIGHT_KEY);
+        }
+        editor.commit();
+
+        suggestWallpaperDimension(getResources(),
+                sp, getWindowManager(), WallpaperManager.getInstance(this));
+    }
+
+    static public void suggestWallpaperDimension(Resources res,
+            final SharedPreferences sharedPrefs,
+            WindowManager windowManager,
+            final WallpaperManager wallpaperManager) {
+        final Point defaultWallpaperSize =
+                WallpaperCropActivity.getDefaultWallpaperSize(res, windowManager);
+
+        new Thread("suggestWallpaperDimension") {
+            public void run() {
+                // If we have saved a wallpaper width/height, use that instead
+                int savedWidth = sharedPrefs.getInt(WALLPAPER_WIDTH_KEY, defaultWallpaperSize.x);
+                int savedHeight = sharedPrefs.getInt(WALLPAPER_HEIGHT_KEY, defaultWallpaperSize.y);
+                wallpaperManager.suggestDesiredDimensions(savedWidth, savedHeight);
+            }
+        }.start();
+    }
+
+
+    protected static RectF getMaxCropRect(
+            int inWidth, int inHeight, int outWidth, int outHeight, boolean leftAligned) {
+        RectF cropRect = new RectF();
+        // Get a crop rect that will fit this
+        if (inWidth / (float) inHeight > outWidth / (float) outHeight) {
+             cropRect.top = 0;
+             cropRect.bottom = inHeight;
+             cropRect.left = (inWidth - (outWidth / (float) outHeight) * inHeight) / 2;
+             cropRect.right = inWidth - cropRect.left;
+             if (leftAligned) {
+                 cropRect.right -= cropRect.left;
+                 cropRect.left = 0;
+             }
+        } else {
+            cropRect.left = 0;
+            cropRect.right = inWidth;
+            cropRect.top = (inHeight - (outHeight / (float) outWidth) * inWidth) / 2;
+            cropRect.bottom = inHeight - cropRect.top;
+        }
+        return cropRect;
+    }
+
+    protected static CompressFormat convertExtensionToCompressFormat(String extension) {
+        return extension.equals("png") ? CompressFormat.PNG : CompressFormat.JPEG;
+    }
+
+    protected static String getFileExtension(String requestFormat) {
+        String outputFormat = (requestFormat == null)
+                ? "jpg"
+                : requestFormat;
+        outputFormat = outputFormat.toLowerCase();
+        return (outputFormat.equals("png") || outputFormat.equals("gif"))
+                ? "png" // We don't support gif compression.
+                : "jpg";
+    }
+}
diff --git a/packages/services/PacProcessor/Android.mk b/packages/services/PacProcessor/Android.mk
new file mode 100644
index 0000000..d9566d5
--- /dev/null
+++ b/packages/services/PacProcessor/Android.mk
@@ -0,0 +1,32 @@
+#
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := PacProcessor
+LOCAL_CERTIFICATE := platform
+
+LOCAL_REQUIRED_MODULES := libjni_pacprocessor
+
+include $(BUILD_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/services/PacProcessor/AndroidManifest.xml b/packages/services/PacProcessor/AndroidManifest.xml
new file mode 100644
index 0000000..6740c16
--- /dev/null
+++ b/packages/services/PacProcessor/AndroidManifest.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.pacprocessor">
+
+    <uses-permission android:name="android.permission.INTERNET" />
+
+    <application
+        android:label="@string/app_name">
+
+        <service android:name=".PacService"
+            android:exported="true">
+        </service>
+
+    </application>
+
+</manifest>
diff --git a/packages/services/PacProcessor/com/android/net/IProxyService.aidl b/packages/services/PacProcessor/com/android/net/IProxyService.aidl
new file mode 100644
index 0000000..4e54aba
--- /dev/null
+++ b/packages/services/PacProcessor/com/android/net/IProxyService.aidl
@@ -0,0 +1,27 @@
+/**
+ * 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.net;
+
+/** @hide */
+interface IProxyService
+{
+    String resolvePacFile(String host, String url);
+
+    oneway void setPacFile(String scriptContents);
+
+    oneway void startPacSystem();
+    oneway void stopPacSystem();
+}
diff --git a/packages/services/PacProcessor/jni/Android.mk b/packages/services/PacProcessor/jni/Android.mk
new file mode 100644
index 0000000..f16c90b
--- /dev/null
+++ b/packages/services/PacProcessor/jni/Android.mk
@@ -0,0 +1,41 @@
+#
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+    jni_init.cpp \
+    com_android_pacprocessor_PacNative.cpp
+
+LOCAL_C_INCLUDES += \
+    external/chromium-libpac/src
+
+LOCAL_SHARED_LIBRARIES := \
+    libandroidfw \
+    libandroid_runtime \
+    liblog \
+    libutils \
+    libnativehelper \
+    libpac
+
+LOCAL_MODULE := libjni_pacprocessor
+LOCAL_MODULE_TAGS := optional
+
+include external/stlport/libstlport.mk
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/packages/services/PacProcessor/jni/com_android_pacprocessor_PacNative.cpp b/packages/services/PacProcessor/jni/com_android_pacprocessor_PacNative.cpp
new file mode 100644
index 0000000..c5aa13b
--- /dev/null
+++ b/packages/services/PacProcessor/jni/com_android_pacprocessor_PacNative.cpp
@@ -0,0 +1,148 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "PacProcessor"
+
+#include <utils/Log.h>
+#include <utils/Mutex.h>
+#include "android_runtime/AndroidRuntime.h"
+
+#include "jni.h"
+#include "JNIHelp.h"
+
+#include "proxy_resolver_v8.h"
+
+namespace android {
+
+class ProxyErrorLogger : public net::ProxyErrorListener {
+public:
+    ~ProxyErrorLogger() {
+
+    }
+    void AlertMessage(String16 message) {
+        String8 str(message);
+        ALOGD("Alert: %s", str.string());
+    }
+    void ErrorMessage(String16 message) {
+        String8 str(message);
+        ALOGE("Error: %s", str.string());
+    }
+};
+
+net::ProxyResolverV8* proxyResolver = NULL;
+ProxyErrorLogger* logger = NULL;
+bool pacSet = false;
+
+String16 jstringToString16(JNIEnv* env, jstring jstr) {
+    const jchar* str = env->GetStringCritical(jstr, 0);
+    String16 str16(str, env->GetStringLength(jstr));
+    env->ReleaseStringCritical(jstr, str);
+    return str16;
+}
+
+jstring string16ToJstring(JNIEnv* env, String16 string) {
+    const char16_t* str = string.string();
+    size_t len = string.size();
+
+    return env->NewString(str, len);
+}
+
+static jboolean com_android_pacprocessor_PacNative_createV8ParserNativeLocked(JNIEnv* env, 
+        jobject) {
+    if (proxyResolver == NULL) {
+        logger = new ProxyErrorLogger();
+        proxyResolver = new net::ProxyResolverV8(net::ProxyResolverJSBindings::CreateDefault(),
+                logger);
+        pacSet = false;
+        return JNI_FALSE;
+    }
+    return JNI_TRUE;
+}
+
+static jboolean com_android_pacprocessor_PacNative_destroyV8ParserNativeLocked(JNIEnv* env, 
+        jobject) {
+    if (proxyResolver != NULL) {
+        delete logger;
+        delete proxyResolver;
+        logger = NULL;
+        proxyResolver = NULL;
+        return JNI_FALSE;
+    }
+    return JNI_TRUE;
+}
+
+static jboolean com_android_pacprocessor_PacNative_setProxyScriptNativeLocked(JNIEnv* env, jobject,
+        jstring script) {
+    String16 script16 = jstringToString16(env, script);
+
+    if (proxyResolver == NULL) {
+        ALOGE("V8 Parser not started when setting PAC script");
+        return JNI_TRUE;
+    }
+
+    if (proxyResolver->SetPacScript(script16) != OK) {
+        ALOGE("Unable to set PAC script");
+        return JNI_TRUE;
+    }
+    pacSet = true;
+
+    return JNI_FALSE;
+}
+
+static jstring com_android_pacprocessor_PacNative_makeProxyRequestNativeLocked(JNIEnv* env, jobject,
+        jstring url, jstring host) {
+    String16 url16 = jstringToString16(env, url);
+    String16 host16 = jstringToString16(env, host);
+    String16 ret;
+
+    if (proxyResolver == NULL) {
+        ALOGE("V8 Parser not initialized when running PAC script");
+        return NULL;
+    }
+
+    if (!pacSet) {
+        ALOGW("Attempting to run PAC with no script set");
+        return NULL;
+    }
+
+    if (proxyResolver->GetProxyForURL(url16, host16, &ret) != OK) {
+        String8 ret8(ret);
+        ALOGE("Error Running PAC: %s", ret8.string());
+        return NULL;
+    }
+
+    jstring jret = string16ToJstring(env, ret);
+
+    return jret;
+}
+
+static JNINativeMethod gMethods[] = {
+    { "createV8ParserNativeLocked", "()Z",
+        (void*)com_android_pacprocessor_PacNative_createV8ParserNativeLocked},
+    { "destroyV8ParserNativeLocked", "()Z",
+        (void*)com_android_pacprocessor_PacNative_destroyV8ParserNativeLocked},
+    { "setProxyScriptNativeLocked", "(Ljava/lang/String;)Z",
+        (void*)com_android_pacprocessor_PacNative_setProxyScriptNativeLocked},
+    { "makeProxyRequestNativeLocked", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
+        (void*)com_android_pacprocessor_PacNative_makeProxyRequestNativeLocked},
+};
+
+int register_com_android_pacprocessor_PacNative(JNIEnv* env) {
+    return jniRegisterNativeMethods(env, "com/android/pacprocessor/PacNative",
+            gMethods, NELEM(gMethods));
+}
+
+} /* namespace android */
diff --git a/packages/services/PacProcessor/jni/jni_init.cpp b/packages/services/PacProcessor/jni/jni_init.cpp
new file mode 100644
index 0000000..bda33fb
--- /dev/null
+++ b/packages/services/PacProcessor/jni/jni_init.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "PacProcessor"
+
+#include <utils/Log.h>
+#include "jni.h"
+
+namespace android {
+    extern int register_com_android_pacprocessor_PacNative(JNIEnv *env);
+}
+
+using namespace android;
+
+extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved) {
+    JNIEnv *env;
+    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+        ALOGE("ERROR: GetEnv failed");
+        return -1;
+    }
+
+    register_com_android_pacprocessor_PacNative(env);
+
+    return JNI_VERSION_1_6;
+}
diff --git a/packages/services/PacProcessor/res/values/strings.xml b/packages/services/PacProcessor/res/values/strings.xml
new file mode 100644
index 0000000..301a2b6
--- /dev/null
+++ b/packages/services/PacProcessor/res/values/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <string name="app_name">PacProcessor</string>
+
+</resources>
diff --git a/packages/services/PacProcessor/src/com/android/pacprocessor/PacNative.java b/packages/services/PacProcessor/src/com/android/pacprocessor/PacNative.java
new file mode 100644
index 0000000..c67fe9f
--- /dev/null
+++ b/packages/services/PacProcessor/src/com/android/pacprocessor/PacNative.java
@@ -0,0 +1,86 @@
+/**
+ * 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.pacprocessor;
+
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class PacNative {
+    private static final String TAG = "PacProxy";
+
+    private String mCurrentPac;
+
+    private boolean mIsActive;
+
+    // Only make native calls from inside synchronized blocks.
+    private native boolean createV8ParserNativeLocked();
+    private native boolean destroyV8ParserNativeLocked();
+
+    private native boolean setProxyScriptNativeLocked(String script);
+
+    private native String makeProxyRequestNativeLocked(String url, String host);
+
+    static {
+        System.loadLibrary("jni_pacprocessor");
+    }
+
+    PacNative() {
+
+    }
+
+    public synchronized boolean startPacSupport() {
+        if (createV8ParserNativeLocked()) {
+            Log.e(TAG, "Unable to Create v8 Proxy Parser.");
+            return true;
+        }
+        mIsActive = true;
+        return false;
+    }
+
+    public synchronized boolean stopPacSupport() {
+        if (mIsActive) {
+            if (destroyV8ParserNativeLocked()) {
+                Log.e(TAG, "Unable to Destroy v8 Proxy Parser.");
+                return true;
+            }
+            mIsActive = false;
+        }
+        return false;
+    }
+
+    public synchronized boolean setCurrentProxyScript(String script) {
+        if (setProxyScriptNativeLocked(script)) {
+            Log.e(TAG, "Unable to parse proxy script.");
+            return true;
+        }
+        return false;
+    }
+
+    public synchronized String makeProxyRequest(String url, String host) {
+        String ret = makeProxyRequestNativeLocked(url, host);
+        if ((ret == null) || (ret.length() == 0)) {
+            Log.e(TAG, "v8 Proxy request failed.");
+            ret = null;
+        }
+        return ret;
+    }
+
+    public synchronized boolean isActive() {
+        return mIsActive;
+    }
+}
diff --git a/packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java b/packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java
new file mode 100644
index 0000000..c6b76f1
--- /dev/null
+++ b/packages/services/PacProcessor/src/com/android/pacprocessor/PacService.java
@@ -0,0 +1,115 @@
+/**
+ * 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.pacprocessor;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Process;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.net.IProxyService;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+public class PacService extends Service {
+    private static final String TAG = "PacService";
+
+    private PacNative mPacNative;
+    private ProxyServiceStub mStub;
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        if (mPacNative == null) {
+            mPacNative = new PacNative();
+            mStub = new ProxyServiceStub(mPacNative);
+        }
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        if (mPacNative != null) {
+            mPacNative.stopPacSupport();
+            mPacNative = null;
+            mStub = null;
+        }
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        if (mPacNative == null) {
+            mPacNative = new PacNative();
+            mStub = new ProxyServiceStub(mPacNative);
+        }
+        return mStub;
+    }
+
+    private static class ProxyServiceStub extends IProxyService.Stub {
+        private final PacNative mPacNative;
+
+        public ProxyServiceStub(PacNative pacNative) {
+            mPacNative = pacNative;
+        }
+
+        @Override
+        public String resolvePacFile(String host, String url) throws RemoteException {
+            try {
+                // Check for characters that could be used for an injection attack.
+                new URL(url);
+                for (char c : host.toCharArray()) {
+                    if (!Character.isLetterOrDigit(c) && (c != '.') && (c != '-')) {
+                        throw new RemoteException("Invalid host was passed");
+                    }
+                }
+                return mPacNative.makeProxyRequest(url, host);
+            } catch (MalformedURLException e) {
+                throw new RemoteException("Invalid URL was passed");
+            }
+        }
+
+        @Override
+        public void setPacFile(String script) throws RemoteException {
+            if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+                Log.e(TAG, "Only system user is allowed to call setPacFile");
+                throw new SecurityException();
+            }
+            mPacNative.setCurrentProxyScript(script);
+        }
+
+        @Override
+        public void startPacSystem() throws RemoteException {
+            if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+                Log.e(TAG, "Only system user is allowed to call startPacSystem");
+                throw new SecurityException();
+            }
+            mPacNative.startPacSupport();
+        }
+
+        @Override
+        public void stopPacSystem() throws RemoteException {
+            if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+                Log.e(TAG, "Only system user is allowed to call stopPacSystem");
+                throw new SecurityException();
+            }
+            mPacNative.stopPacSupport();
+        }
+    }
+}
diff --git a/packages/services/Proxy/Android.mk b/packages/services/Proxy/Android.mk
new file mode 100644
index 0000000..d5546b2
--- /dev/null
+++ b/packages/services/Proxy/Android.mk
@@ -0,0 +1,14 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := ProxyHandler
+LOCAL_CERTIFICATE := platform
+LOCAL_PRIVILEGED_MODULE := true
+
+include $(BUILD_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/services/Proxy/AndroidManifest.xml b/packages/services/Proxy/AndroidManifest.xml
new file mode 100644
index 0000000..bbcd6b9
--- /dev/null
+++ b/packages/services/Proxy/AndroidManifest.xml
@@ -0,0 +1,17 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+        package="com.android.proxyhandler"
+        coreApp="true">
+
+    <uses-permission android:name="android.permission.INTERNET" />
+
+    <application
+        android:label="@string/app_label"
+        android:process="com.android.proxyhandler">
+
+        <service android:name=".ProxyService"
+            android:exported="true">
+        </service>
+
+    </application>
+</manifest>
diff --git a/packages/services/Proxy/com/android/net/IProxyCallback.aidl b/packages/services/Proxy/com/android/net/IProxyCallback.aidl
new file mode 100644
index 0000000..26b2a3f
--- /dev/null
+++ b/packages/services/Proxy/com/android/net/IProxyCallback.aidl
@@ -0,0 +1,22 @@
+/**
+ * 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.net;
+
+/** @hide */
+interface IProxyCallback
+{
+    oneway void getProxyPort(IBinder callback);
+}
diff --git a/packages/services/Proxy/com/android/net/IProxyPortListener.aidl b/packages/services/Proxy/com/android/net/IProxyPortListener.aidl
new file mode 100644
index 0000000..fa4caf3
--- /dev/null
+++ b/packages/services/Proxy/com/android/net/IProxyPortListener.aidl
@@ -0,0 +1,22 @@
+/**
+ * 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.net;
+
+/** @hide */
+interface IProxyPortListener
+{
+    oneway void setProxyPort(int port);
+}
diff --git a/packages/services/Proxy/res/values/strings.xml b/packages/services/Proxy/res/values/strings.xml
new file mode 100644
index 0000000..6188d79
--- /dev/null
+++ b/packages/services/Proxy/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?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="app_label">ProxyHandler</string>
+
+</resources>
diff --git a/packages/services/Proxy/src/com/android/proxyhandler/ProxyServer.java b/packages/services/Proxy/src/com/android/proxyhandler/ProxyServer.java
new file mode 100644
index 0000000..4bf1db8
--- /dev/null
+++ b/packages/services/Proxy/src/com/android/proxyhandler/ProxyServer.java
@@ -0,0 +1,264 @@
+/**
+ * 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.proxyhandler;
+
+import android.net.ProxyProperties;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.net.IProxyPortListener;
+import com.google.android.collect.Lists;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.ProxySelector;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * @hide
+ */
+public class ProxyServer extends Thread {
+
+    private static final String CONNECT = "CONNECT";
+    private static final String HTTP_OK = "HTTP/1.1 200 OK\n";
+
+    private static final String TAG = "ProxyServer";
+
+    private ExecutorService threadExecutor;
+
+    public boolean mIsRunning = false;
+
+    private ServerSocket serverSocket;
+    private int mPort;
+    private IProxyPortListener mCallback;
+
+    private class ProxyConnection implements Runnable {
+        private Socket connection;
+
+        private ProxyConnection(Socket connection) {
+            this.connection = connection;
+        }
+
+        @Override
+        public void run() {
+            try {
+                String requestLine = getLine(connection.getInputStream());
+                if (requestLine == null) {
+                    connection.close();
+                    return;
+                }
+                String[] splitLine = requestLine.split(" ");
+                if (splitLine.length < 3) {
+                    connection.close();
+                    return;
+                }
+                String requestType = splitLine[0];
+                String urlString = splitLine[1];
+
+                String host = "";
+                int port = 80;
+
+                if (requestType.equals(CONNECT)) {
+                    String[] hostPortSplit = urlString.split(":");
+                    host = hostPortSplit[0];
+                    try {
+                        port = Integer.parseInt(hostPortSplit[1]);
+                    } catch (NumberFormatException nfe) {
+                        port = 443;
+                    }
+                    urlString = "Https://" + host + ":" + port;
+                } else {
+                    try {
+                        URI url = new URI(urlString);
+                        host = url.getHost();
+                        port = url.getPort();
+                        if (port < 0) {
+                            port = 80;
+                        }
+                    } catch (URISyntaxException e) {
+                        connection.close();
+                        return;
+                    }
+                }
+
+                List<Proxy> list = Lists.newArrayList();
+                try {
+                    list = ProxySelector.getDefault().select(new URI(urlString));
+                } catch (URISyntaxException e) {
+                    e.printStackTrace();
+                }
+                Socket server = null;
+                for (Proxy proxy : list) {
+                    try {
+                        if (!proxy.equals(Proxy.NO_PROXY)) {
+                            // Only Inets created by PacProxySelector.
+                            InetSocketAddress inetSocketAddress =
+                                    (InetSocketAddress)list.get(0).address();
+                            server = new Socket(inetSocketAddress.getAddress(),
+                                    inetSocketAddress.getPort());
+                            sendLine(server, requestLine);
+                        } else {
+                            server = new Socket(host, port);
+                            if (requestType.equals(CONNECT)) {
+                                while (getLine(connection.getInputStream()).length() != 0);
+                                // No proxy to respond so we must.
+                                sendLine(connection, HTTP_OK);
+                            } else {
+                                sendLine(server, requestLine);
+                            }
+                        }
+                    } catch (IOException ioe) {
+
+                    }
+                    if (server != null) {
+                        break;
+                    }
+                }
+                if (server == null) {
+                    server = new Socket(host, port);
+                    if (requestType.equals(CONNECT)) {
+                        while (getLine(connection.getInputStream()).length() != 0);
+                        // No proxy to respond so we must.
+                        sendLine(connection, HTTP_OK);
+                    } else {
+                        sendLine(server, requestLine);
+                    }
+                }
+                // Pass data back and forth until complete.
+                SocketConnect.connect(connection, server);
+            } catch (IOException e) {
+                Log.d(TAG, "Problem Proxying", e);
+            }
+            try {
+                connection.close();
+            } catch (IOException ioe) {
+
+            }
+        }
+
+        private String getLine(InputStream inputStream) throws IOException {
+            StringBuffer buffer = new StringBuffer();
+            int byteBuffer = inputStream.read();
+            if (byteBuffer < 0) return "";
+            do {
+                if (byteBuffer != '\r') {
+                    buffer.append((char)byteBuffer);
+                }
+                byteBuffer = inputStream.read();
+            } while ((byteBuffer != '\n') && (byteBuffer >= 0));
+
+            return buffer.toString();
+        }
+
+        private void sendLine(Socket socket, String line) throws IOException {
+            OutputStream os = socket.getOutputStream();
+            os.write(line.getBytes());
+            os.write('\r');
+            os.write('\n');
+            os.flush();
+        }
+    }
+
+    public ProxyServer() {
+        threadExecutor = Executors.newCachedThreadPool();
+        mPort = -1;
+        mCallback = null;
+    }
+
+    @Override
+    public void run() {
+        try {
+            serverSocket = new ServerSocket(0);
+
+            if (serverSocket != null) {
+                setPort(serverSocket.getLocalPort());
+
+                while (mIsRunning) {
+                    try {
+                        ProxyConnection parser = new ProxyConnection(serverSocket.accept());
+
+                        threadExecutor.execute(parser);
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        } catch (SocketException e) {
+            Log.e(TAG, "Failed to start proxy server", e);
+        } catch (IOException e1) {
+            Log.e(TAG, "Failed to start proxy server", e1);
+        }
+
+        mIsRunning = false;
+    }
+
+    public synchronized void setPort(int port) {
+        if (mCallback != null) {
+            try {
+                mCallback.setProxyPort(port);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Proxy failed to report port to PacManager", e);
+            }
+        }
+        mPort = port;
+    }
+
+    public synchronized void setCallback(IProxyPortListener callback) {
+        if (mPort != -1) {
+            try {
+                callback.setProxyPort(mPort);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Proxy failed to report port to PacManager", e);
+            }
+        }
+        mCallback = callback;
+    }
+
+    public synchronized void startServer() {
+        mIsRunning = true;
+        start();
+    }
+
+    public synchronized void stopServer() {
+        mIsRunning = false;
+        if (serverSocket != null) {
+            try {
+                serverSocket.close();
+                serverSocket = null;
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    public boolean isBound() {
+        return (mPort != -1);
+    }
+
+    public int getPort() {
+        return mPort;
+    }
+}
diff --git a/packages/services/Proxy/src/com/android/proxyhandler/ProxyService.java b/packages/services/Proxy/src/com/android/proxyhandler/ProxyService.java
new file mode 100644
index 0000000..109435c
--- /dev/null
+++ b/packages/services/Proxy/src/com/android/proxyhandler/ProxyService.java
@@ -0,0 +1,75 @@
+/**
+ * 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.proxyhandler;
+
+import android.app.Service;
+import android.content.Intent;
+import android.net.Proxy;
+import android.net.ProxyProperties;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.text.TextUtils;
+
+import com.android.net.IProxyCallback;
+import com.android.net.IProxyPortListener;
+
+/**
+ * @hide
+ */
+public class ProxyService extends Service {
+
+    private static ProxyServer server = null;
+
+    /** Keep these values up-to-date with PacManager.java */
+    public static final String KEY_PROXY = "keyProxy";
+    public static final String HOST = "localhost";
+    // STOPSHIP This being a static port means it can be hijacked by other apps.
+    public static final int PORT = 8182;
+    public static final String EXCL_LIST = "";
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        if (server == null) {
+            server = new ProxyServer();
+            server.startServer();
+        }
+    }
+
+    @Override
+    public void onDestroy() {
+        if (server != null) {
+            server.stopServer();
+            server = null;
+        }
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return new IProxyCallback.Stub() {
+            @Override
+            public void getProxyPort(IBinder callback) throws RemoteException {
+                if (server != null) {
+                    IProxyPortListener portListener = IProxyPortListener.Stub.asInterface(callback);
+                    if (portListener != null) {
+                        server.setCallback(portListener);
+                    }
+                }
+            }
+        };
+    }
+}
\ No newline at end of file
diff --git a/packages/services/Proxy/src/com/android/proxyhandler/SocketConnect.java b/packages/services/Proxy/src/com/android/proxyhandler/SocketConnect.java
new file mode 100644
index 0000000..0d7df7f
--- /dev/null
+++ b/packages/services/Proxy/src/com/android/proxyhandler/SocketConnect.java
@@ -0,0 +1,59 @@
+package com.android.proxyhandler;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+
+/**
+ * @hide
+ */
+public class SocketConnect extends Thread {
+
+    private InputStream from;
+    private OutputStream to;
+
+    public SocketConnect(Socket from, Socket to) throws IOException {
+        this.from = from.getInputStream();
+        this.to = to.getOutputStream();
+        start();
+    }
+
+    @Override
+    public void run() {
+        final byte[] buffer = new byte[512];
+
+        try {
+            while (true) {
+                int r = from.read(buffer);
+                if (r < 0) {
+                    break;
+                }
+                to.write(buffer, 0, r);
+            }
+            from.close();
+            to.close();
+        } catch (IOException io) {
+
+        }
+    }
+
+    public static void connect(Socket first, Socket second) {
+        try {
+            SocketConnect sc1 = new SocketConnect(first, second);
+            SocketConnect sc2 = new SocketConnect(second, first);
+            try {
+                sc1.join();
+            } catch (InterruptedException e) {
+            }
+            try {
+                sc2.join();
+            } catch (InterruptedException e) {
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+
+}
diff --git a/policy/src/com/android/internal/policy/impl/BarController.java b/policy/src/com/android/internal/policy/impl/BarController.java
new file mode 100644
index 0000000..57c9675
--- /dev/null
+++ b/policy/src/com/android/internal/policy/impl/BarController.java
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.policy.impl;
+
+import android.app.StatusBarManager;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.util.Slog;
+import android.view.View;
+import android.view.WindowManagerPolicy.WindowState;
+
+import com.android.internal.statusbar.IStatusBarService;
+
+import java.io.PrintWriter;
+
+/**
+ * Controls state/behavior specific to a system bar window.
+ */
+public class BarController {
+    private static final boolean DEBUG = false;
+
+    private static final int TRANSIENT_BAR_NONE = 0;
+    private static final int TRANSIENT_BAR_SHOWING = 1;
+    private static final int TRANSIENT_BAR_HIDING = 2;
+
+    private static final int TRANSPARENT_ANIMATION_DELAY_MS = 1000;
+
+    private final String mTag;
+    private final int mTransientFlag;
+    private final int mUnhideFlag;
+    private final int mTransparentFlag;
+    private final int mStatusBarManagerId;
+    private final Handler mHandler;
+    private final Object mServiceAquireLock = new Object();
+    private IStatusBarService mStatusBarService;
+
+    private WindowState mWin;
+    private int mState = StatusBarManager.WINDOW_STATE_SHOWING;
+    private int mTransientBarState;
+    private boolean mPendingShow;
+    private long mLastTransparent;
+
+    public BarController(String tag, int transientFlag, int unhideFlag, int transparentFlag,
+            int statusBarManagerId) {
+        mTag = "BarController." + tag;
+        mTransientFlag = transientFlag;
+        mUnhideFlag = unhideFlag;
+        mTransparentFlag = transparentFlag;
+        mStatusBarManagerId = statusBarManagerId;
+        mHandler = new Handler();
+    }
+
+    public void setWindow(WindowState win) {
+        mWin = win;
+    }
+
+    public boolean isHidden() {
+        return mState == StatusBarManager.WINDOW_STATE_HIDDEN;
+    }
+
+    public void showTransient() {
+        if (mWin != null) {
+            setTransientBarState(TRANSIENT_BAR_SHOWING);
+        }
+    }
+
+    public boolean isTransientShowing() {
+        return mTransientBarState == TRANSIENT_BAR_SHOWING;
+    }
+
+    public boolean wasRecentlyTransparent() {
+        return (SystemClock.uptimeMillis() - mLastTransparent) < TRANSPARENT_ANIMATION_DELAY_MS;
+    }
+
+    public void adjustSystemUiVisibilityLw(int oldVis, int vis) {
+        if (mWin != null && mTransientBarState == TRANSIENT_BAR_SHOWING &&
+                (vis & mTransientFlag) == 0) {
+            // sysui requests hide
+            setTransientBarState(TRANSIENT_BAR_HIDING);
+            setBarShowingLw(false);
+        } else if (mWin != null && (oldVis & mUnhideFlag) != 0 && (vis & mUnhideFlag) == 0) {
+            // sysui ready to unhide
+            setBarShowingLw(true);
+        }
+    }
+
+    public boolean setBarShowingLw(final boolean show) {
+        if (mWin == null) return false;
+        if (show && mTransientBarState == TRANSIENT_BAR_HIDING) {
+            mPendingShow = true;
+            return false;
+        }
+        final boolean wasVis = mWin.isVisibleLw();
+        final boolean wasAnim = mWin.isAnimatingLw();
+        final boolean change = show ? mWin.showLw(true) : mWin.hideLw(true);
+        final int state = computeStateLw(wasVis, wasAnim, mWin, change);
+        updateStateLw(state);
+        return change;
+    }
+
+    private int computeStateLw(boolean wasVis, boolean wasAnim, WindowState win, boolean change) {
+        if (win.hasDrawnLw()) {
+            final boolean vis = win.isVisibleLw();
+            final boolean anim = win.isAnimatingLw();
+            if (mState == StatusBarManager.WINDOW_STATE_HIDING && !change && !vis) {
+                return StatusBarManager.WINDOW_STATE_HIDDEN;
+            } else if (change) {
+                if (wasVis && vis && !wasAnim && anim) {
+                    return StatusBarManager.WINDOW_STATE_HIDING;
+                } else {
+                    return StatusBarManager.WINDOW_STATE_SHOWING;
+                }
+            }
+        }
+        return mState;
+    }
+
+    private void updateStateLw(final int state) {
+        if (state != mState) {
+            mState = state;
+            if (DEBUG) Slog.d(mTag, "mState: " + StatusBarManager.windowStateToString(state));
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        IStatusBarService statusbar = getStatusBarService();
+                        if (statusbar != null) {
+                            statusbar.setWindowState(mStatusBarManagerId, state);
+                        }
+                    } catch (RemoteException e) {
+                        if (DEBUG) Slog.w(mTag, "Error posting window state", e);
+                        // re-acquire status bar service next time it is needed.
+                        mStatusBarService = null;
+                    }
+                }
+            });
+        }
+    }
+
+    public boolean checkHiddenLw() {
+        if (mWin != null && mWin.hasDrawnLw()) {
+            if (!mWin.isVisibleLw() && !mWin.isAnimatingLw()) {
+                updateStateLw(StatusBarManager.WINDOW_STATE_HIDDEN);
+            }
+            if (mTransientBarState == TRANSIENT_BAR_HIDING && !mWin.isVisibleLw()) {
+                // Finished animating out, clean up and reset style
+                setTransientBarState(TRANSIENT_BAR_NONE);
+                if (mPendingShow) {
+                    setBarShowingLw(true);
+                    mPendingShow = false;
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public boolean checkShowTransientBarLw() {
+        if (mTransientBarState == TRANSIENT_BAR_SHOWING) {
+            if (DEBUG) Slog.d(mTag, "Not showing transient bar, already shown");
+            return false;
+        } else if (mWin == null) {
+            if (DEBUG) Slog.d(mTag, "Not showing transient bar, bar doesn't exist");
+            return false;
+        } else if (mWin.isDisplayedLw()) {
+            if (DEBUG) Slog.d(mTag, "Not showing transient bar, bar already visible");
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    public int updateVisibilityLw(boolean allowed, int oldVis, int vis) {
+        if (mWin == null) return vis;
+        if (mTransientBarState == TRANSIENT_BAR_SHOWING) { // transient bar requested
+            if (allowed) {
+                vis |= mTransientFlag;
+                if ((oldVis & mTransientFlag) == 0) {
+                    vis |= mUnhideFlag;  // tell sysui we're ready to unhide
+                }
+            } else {
+                setTransientBarState(TRANSIENT_BAR_NONE);  // request denied
+            }
+        }
+        if (mTransientBarState != TRANSIENT_BAR_NONE) {
+            vis |= mTransientFlag;  // ignore clear requests until transition completes
+            vis &= ~View.SYSTEM_UI_FLAG_LOW_PROFILE;  // never show transient bars in low profile
+        }
+        if ((vis & mTransparentFlag) != 0 || (oldVis & mTransparentFlag) != 0) {
+            mLastTransparent = SystemClock.uptimeMillis();
+        }
+        return vis;
+    }
+
+    private void setTransientBarState(int state) {
+        if (mWin != null && state != mTransientBarState) {
+            if (mTransientBarState == TRANSIENT_BAR_SHOWING || state == TRANSIENT_BAR_SHOWING) {
+                mLastTransparent = SystemClock.uptimeMillis();
+            }
+            mTransientBarState = state;
+            if (DEBUG) Slog.d(mTag, "mTransientBarState: " + transientBarStateToString(state));
+        }
+    }
+
+    private IStatusBarService getStatusBarService() {
+        synchronized (mServiceAquireLock) {
+            if (mStatusBarService == null) {
+                mStatusBarService = IStatusBarService.Stub.asInterface(
+                        ServiceManager.getService("statusbar"));
+            }
+            return mStatusBarService;
+        }
+    }
+
+    private static String transientBarStateToString(int state) {
+        if (state == TRANSIENT_BAR_HIDING) return "TRANSIENT_BAR_HIDING";
+        if (state == TRANSIENT_BAR_SHOWING) return "TRANSIENT_BAR_SHOWING";
+        if (state == TRANSIENT_BAR_NONE) return "TRANSIENT_BAR_NONE";
+        throw new IllegalArgumentException("Unknown state " + state);
+    }
+
+    public void dump(PrintWriter pw, String prefix) {
+        if (mWin != null) {
+            pw.print(prefix); pw.println(mTag);
+            pw.print(prefix); pw.print("  "); pw.print("mState"); pw.print('=');
+            pw.println(StatusBarManager.windowStateToString(mState));
+            pw.print(prefix); pw.print("  "); pw.print("mTransientBar"); pw.print('=');
+            pw.println(transientBarStateToString(mTransientBarState));
+        }
+    }
+}
diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java
index a2ac8fe..884f57e 100644
--- a/policy/src/com/android/internal/policy/impl/GlobalActions.java
+++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java
@@ -265,7 +265,7 @@
 
         // next: bug report, if enabled
         if (Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.BUGREPORT_IN_POWER_MENU, 0) != 0) {
+                Settings.Global.BUGREPORT_IN_POWER_MENU, 0) != 0 && isCurrentUserOwner()) {
             mItems.add(
                 new SinglePressAction(com.android.internal.R.drawable.stat_sys_adb,
                         R.string.global_action_bug_report) {
@@ -349,16 +349,24 @@
         return dialog;
     }
 
+    private UserInfo getCurrentUser() {
+        try {
+            return ActivityManagerNative.getDefault().getCurrentUser();
+        } catch (RemoteException re) {
+            return null;
+        }
+    }
+
+    private boolean isCurrentUserOwner() {
+        UserInfo currentUser = getCurrentUser();
+        return currentUser == null || currentUser.isPrimary();
+    }
+
     private void addUsersToMenu(ArrayList<Action> items) {
         List<UserInfo> users = ((UserManager) mContext.getSystemService(Context.USER_SERVICE))
                 .getUsers();
         if (users.size() > 1) {
-            UserInfo currentUser;
-            try {
-                currentUser = ActivityManagerNative.getDefault().getCurrentUser();
-            } catch (RemoteException re) {
-                currentUser = null;
-            }
+            UserInfo currentUser = getCurrentUser();
             for (final UserInfo user : users) {
                 boolean isCurrentUser = currentUser == null
                         ? user.id == 0 : (currentUser.id == user.id);
diff --git a/policy/src/com/android/internal/policy/impl/PhoneFallbackEventHandler.java b/policy/src/com/android/internal/policy/impl/PhoneFallbackEventHandler.java
index b72bb2b..417527c 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneFallbackEventHandler.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneFallbackEventHandler.java
@@ -102,7 +102,8 @@
             case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
             case KeyEvent.KEYCODE_MEDIA_REWIND:
             case KeyEvent.KEYCODE_MEDIA_RECORD:
-            case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: {
+            case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
+            case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: {
                 handleMediaKeyEvent(event);
                 return true;
             }
@@ -215,7 +216,8 @@
             case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
             case KeyEvent.KEYCODE_MEDIA_REWIND:
             case KeyEvent.KEYCODE_MEDIA_RECORD:
-            case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: {
+            case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
+            case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: {
                 handleMediaKeyEvent(event);
                 return true;
             }
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 6b28e8e..11913ee 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -22,6 +22,7 @@
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 import static android.view.WindowManager.LayoutParams.*;
 
+import android.view.ViewConfiguration;
 import com.android.internal.view.RootViewSurfaceTaker;
 import com.android.internal.view.StandaloneActionMode;
 import com.android.internal.view.menu.ContextMenuBuilder;
@@ -49,6 +50,7 @@
 import android.media.AudioManager;
 import android.net.Uri;
 import android.os.Bundle;
+import android.os.Debug;
 import android.os.Handler;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -58,6 +60,7 @@
 import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.Log;
+import android.util.Slog;
 import android.util.SparseArray;
 import android.util.TypedValue;
 import android.view.ActionMode;
@@ -65,6 +68,7 @@
 import android.view.Gravity;
 import android.view.IRotationWatcher;
 import android.view.IWindowManager;
+import android.view.InputEvent;
 import android.view.InputQueue;
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
@@ -77,6 +81,7 @@
 import android.view.ViewGroup;
 import android.view.ViewManager;
 import android.view.ViewParent;
+import android.view.ViewRootImpl;
 import android.view.ViewStub;
 import android.view.Window;
 import android.view.WindowManager;
@@ -139,6 +144,22 @@
     private ActionMenuPresenterCallback mActionMenuPresenterCallback;
     private PanelMenuPresenterCallback mPanelMenuPresenterCallback;
 
+    // The icon resource has been explicitly set elsewhere
+    // and should not be overwritten with a default.
+    static final int FLAG_RESOURCE_SET_ICON = 1 << 0;
+
+    // The logo resource has been explicitly set elsewhere
+    // and should not be overwritten with a default.
+    static final int FLAG_RESOURCE_SET_LOGO = 1 << 1;
+
+    // The icon resource is currently configured to use the system fallback
+    // as no default was previously specified. Anything can override this.
+    static final int FLAG_RESOURCE_SET_ICON_FALLBACK = 1 << 2;
+
+    int mResourcesSetFlags;
+    int mIconRes;
+    int mLogoRes;
+
     private DrawableFeatureState[] mDrawables;
 
     private PanelFeatureState[] mPanels;
@@ -520,7 +541,8 @@
     @Override
     public final void openPanel(int featureId, KeyEvent event) {
         if (featureId == FEATURE_OPTIONS_PANEL && mActionBar != null &&
-                mActionBar.isOverflowReserved()) {
+                mActionBar.isOverflowReserved() &&
+                !ViewConfiguration.get(getContext()).hasPermanentMenuKey()) {
             if (mActionBar.getVisibility() == View.VISIBLE) {
                 mActionBar.showOverflowMenu();
             }
@@ -529,7 +551,7 @@
         }
     }
 
-    private void openPanel(PanelFeatureState st, KeyEvent event) {
+    private void openPanel(final PanelFeatureState st, KeyEvent event) {
         // System.out.println("Open panel: isOpen=" + st.isOpen);
 
         // Already open, return
@@ -627,7 +649,6 @@
             }
         }
 
-        st.isOpen = true;
         st.isHandled = false;
 
         WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
@@ -645,15 +666,17 @@
         }
 
         lp.windowAnimations = st.windowAnimations;
-        
+
         wm.addView(st.decorView, lp);
+        st.isOpen = true;
         // Log.v(TAG, "Adding main menu to window manager.");
     }
 
     @Override
     public final void closePanel(int featureId) {
         if (featureId == FEATURE_OPTIONS_PANEL && mActionBar != null &&
-                mActionBar.isOverflowReserved()) {
+                mActionBar.isOverflowReserved() &&
+                !ViewConfiguration.get(getContext()).hasPermanentMenuKey()) {
             mActionBar.hideOverflowMenu();
         } else if (featureId == FEATURE_CONTEXT_MENU) {
             closeContextMenu();
@@ -816,7 +839,8 @@
             boolean playSoundEffect = false;
             final PanelFeatureState st = getPanelState(featureId, true);
             if (featureId == FEATURE_OPTIONS_PANEL && mActionBar != null &&
-                    mActionBar.isOverflowReserved()) {
+                    mActionBar.isOverflowReserved() &&
+                    !ViewConfiguration.get(getContext()).hasPermanentMenuKey()) {
                 if (mActionBar.getVisibility() == View.VISIBLE) {
                     if (!mActionBar.isOverflowMenuShowing()) {
                         if (!isDestroyed() && preparePanel(st, event)) {
@@ -994,7 +1018,9 @@
     }
 
     private void reopenMenu(boolean toggleMenuMode) {
-        if (mActionBar != null && mActionBar.isOverflowReserved()) {
+        if (mActionBar != null && mActionBar.isOverflowReserved() &&
+                (!ViewConfiguration.get(getContext()).hasPermanentMenuKey() ||
+                        mActionBar.isOverflowMenuShowPending())) {
             final Callback cb = getCallback();
             if (!mActionBar.isOverflowMenuShowing() || !toggleMenuMode) {
                 if (cb != null && !isDestroyed() && mActionBar.getVisibility() == View.VISIBLE) {
@@ -1393,6 +1419,75 @@
         }
     }
 
+    @Override
+    public void setIcon(int resId) {
+        mIconRes = resId;
+        mResourcesSetFlags |= FLAG_RESOURCE_SET_ICON;
+        mResourcesSetFlags &= ~FLAG_RESOURCE_SET_ICON_FALLBACK;
+        if (mActionBar != null) {
+            mActionBar.setIcon(resId);
+        }
+    }
+
+    @Override
+    public void setDefaultIcon(int resId) {
+        if ((mResourcesSetFlags & FLAG_RESOURCE_SET_ICON) != 0) {
+            return;
+        }
+        mIconRes = resId;
+        if (mActionBar != null && (!mActionBar.hasIcon() ||
+                (mResourcesSetFlags & FLAG_RESOURCE_SET_ICON_FALLBACK) != 0)) {
+            if (resId != 0) {
+                mActionBar.setIcon(resId);
+                mResourcesSetFlags &= ~FLAG_RESOURCE_SET_ICON_FALLBACK;
+            } else {
+                mActionBar.setIcon(getContext().getPackageManager().getDefaultActivityIcon());
+                mResourcesSetFlags |= FLAG_RESOURCE_SET_ICON_FALLBACK;
+            }
+        }
+    }
+
+    @Override
+    public void setLogo(int resId) {
+        mLogoRes = resId;
+        mResourcesSetFlags |= FLAG_RESOURCE_SET_LOGO;
+        if (mActionBar != null) {
+            mActionBar.setLogo(resId);
+        }
+    }
+
+    @Override
+    public void setDefaultLogo(int resId) {
+        if ((mResourcesSetFlags & FLAG_RESOURCE_SET_LOGO) != 0) {
+            return;
+        }
+        mLogoRes = resId;
+        if (mActionBar != null && !mActionBar.hasLogo()) {
+            mActionBar.setLogo(resId);
+        }
+    }
+
+    @Override
+    public void setLocalFocus(boolean hasFocus, boolean inTouchMode) {
+        getViewRootImpl().windowFocusChanged(hasFocus, inTouchMode);
+
+    }
+
+    @Override
+    public void injectInputEvent(InputEvent event) {
+        getViewRootImpl().dispatchInputEvent(event);
+    }
+
+    private ViewRootImpl getViewRootImpl() {
+        if (mDecor != null) {
+            ViewRootImpl viewRootImpl = mDecor.getViewRootImpl();
+            if (viewRootImpl != null) {
+                return viewRootImpl;
+            }
+        }
+        throw new IllegalStateException("view not added");
+    }
+
     /**
      * Request that key events come to this activity. Use this if your activity
      * has no views with focus, but the activity still wants a chance to process
@@ -2919,6 +3014,13 @@
                         mActionBar.initIndeterminateProgress();
                     }
 
+                    final ActionBarOverlayLayout abol = (ActionBarOverlayLayout) findViewById(
+                            com.android.internal.R.id.action_bar_overlay_layout);
+                    if (abol != null) {
+                        abol.setOverlayMode(
+                                (localFeatures & (1 << FEATURE_ACTION_BAR_OVERLAY)) != 0);
+                    }
+
                     boolean splitActionBar = false;
                     final boolean splitWhenNarrow =
                             (mUiOptions & ActivityInfo.UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW) != 0;
@@ -2946,6 +3048,20 @@
                                 "incompatible window decor! Ignoring request.");
                     }
 
+                    if ((mResourcesSetFlags & FLAG_RESOURCE_SET_ICON) != 0 ||
+                            (mIconRes != 0 && !mActionBar.hasIcon())) {
+                        mActionBar.setIcon(mIconRes);
+                    } else if ((mResourcesSetFlags & FLAG_RESOURCE_SET_ICON) == 0 &&
+                            mIconRes == 0 && !mActionBar.hasIcon()) {
+                        mActionBar.setIcon(
+                                getContext().getPackageManager().getDefaultActivityIcon());
+                        mResourcesSetFlags |= FLAG_RESOURCE_SET_ICON_FALLBACK;
+                    }
+                    if ((mResourcesSetFlags & FLAG_RESOURCE_SET_LOGO) != 0 ||
+                            (mLogoRes != 0 && !mActionBar.hasLogo())) {
+                        mActionBar.setLogo(mLogoRes);
+                    }
+
                     // Post the panel invalidate for later; avoid application onCreateOptionsMenu
                     // being called in the middle of onCreate or similar.
                     mDecor.post(new Runnable() {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index b0cd11ae..ba8671a 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -21,6 +21,7 @@
 import android.app.IUiModeManager;
 import android.app.ProgressDialog;
 import android.app.SearchManager;
+import android.app.StatusBarManager;
 import android.app.UiModeManager;
 import android.content.ActivityNotFoundException;
 import android.content.BroadcastReceiver;
@@ -33,6 +34,7 @@
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.content.pm.UserInfo;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -94,8 +96,7 @@
 
 import com.android.internal.R;
 import com.android.internal.policy.PolicyManager;
-import com.android.internal.policy.impl.keyguard.KeyguardViewManager;
-import com.android.internal.policy.impl.keyguard.KeyguardViewMediator;
+import com.android.internal.policy.impl.keyguard.KeyguardServiceDelegate;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.telephony.ITelephony;
 import com.android.internal.widget.PointerLocationView;
@@ -104,6 +105,7 @@
 import java.io.FileReader;
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.util.HashSet;
 
 import static android.view.WindowManager.LayoutParams.*;
 import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_ABSENT;
@@ -114,7 +116,7 @@
  * WindowManagerPolicy implementation for the Android phone UI.  This
  * introduces a new method suffix, Lp, for an internal lock of the
  * PhoneWindowManager.  This is used to protect some internal state, and
- * can be acquired with either thw Lw and Li lock held, so has the restrictions
+ * can be acquired with either the Lw and Li lock held, so has the restrictions
  * of both of those when held.
  */
 public class PhoneWindowManager implements WindowManagerPolicy {
@@ -162,7 +164,15 @@
      * of the screen to change.
      */
     static final int SYSTEM_UI_CHANGING_LAYOUT =
-            View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN;
+              View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+            | View.SYSTEM_UI_FLAG_FULLSCREEN
+            | View.SYSTEM_UI_FLAG_TRANSPARENT_STATUS
+            | View.SYSTEM_UI_FLAG_TRANSPARENT_NAVIGATION;
+
+    /**
+     * Keyguard stuff
+     */
+    private WindowState mKeyguardScrim;
 
     /* Table of Application Launch keys.  Maps from key codes to intent categories.
      *
@@ -209,13 +219,13 @@
 
     // Vibrator pattern for haptic feedback of virtual key press.
     long[] mVirtualKeyVibePattern;
-    
+
     // Vibrator pattern for a short vibration.
     long[] mKeyboardTapVibePattern;
 
     // 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;
 
@@ -225,7 +235,6 @@
     boolean mHeadless;
     boolean mSafeMode;
     WindowState mStatusBar = null;
-    boolean mHasSystemNavBar;
     int mStatusBarHeight;
     WindowState mNavigationBar = null;
     boolean mHasNavigationBar = false;
@@ -236,7 +245,7 @@
     int[] mNavigationBarWidthForRotation = new int[4];
 
     WindowState mKeyguard = null;
-    KeyguardViewMediator mKeyguardMediator;
+    KeyguardServiceDelegate mKeyguardDelegate;
     GlobalActions mGlobalActions;
     volatile boolean mPowerKeyHandled; // accessed from input reader and handler thread
     boolean mPendingPowerKeyUpCanceled;
@@ -268,6 +277,10 @@
     int mDemoHdmiRotation;
     boolean mDemoHdmiRotationLock;
 
+    // Default display does not rotate, apps that require non-default orientation will have to
+    // have the orientation emulated.
+    private boolean mForceDefaultOrientation = false;
+
     int mUserRotationMode = WindowManagerPolicy.USER_ROTATION_FREE;
     int mUserRotation = Surface.ROTATION_0;
     boolean mAccelerometerDefault;
@@ -284,42 +297,25 @@
     boolean mOrientationSensorEnabled = false;
     int mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
     boolean mHasSoftInput = false;
-    
+
     int mPointerLocationMode = 0; // guarded by mLock
 
     // The last window we were told about in focusChanged.
     WindowState mFocusedWindow;
     IApplicationToken mFocusedApp;
 
-    private static final class PointerLocationInputEventReceiver extends InputEventReceiver {
-        private final PointerLocationView mView;
-
-        public PointerLocationInputEventReceiver(InputChannel inputChannel, Looper looper,
-                PointerLocationView view) {
-            super(inputChannel, looper);
-            mView = view;
-        }
-
+    private final class PointerLocationPointerEventListener implements PointerEventListener {
         @Override
-        public void onInputEvent(InputEvent event) {
-            boolean handled = false;
-            try {
-                if (event instanceof MotionEvent
-                        && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
-                    final MotionEvent motionEvent = (MotionEvent)event;
-                    mView.addPointerEvent(motionEvent);
-                    handled = true;
-                }
-            } finally {
-                finishInputEvent(event, handled);
+        public void onPointerEvent(MotionEvent motionEvent) {
+            if (mPointerLocationView != null) {
+                mPointerLocationView.addPointerEvent(motionEvent);
             }
         }
     }
 
     // Pointer location view state, only modified on the mHandler Looper.
-    PointerLocationInputEventReceiver mPointerLocationInputEventReceiver;
+    PointerLocationPointerEventListener mPointerLocationPointerEventListener;
     PointerLocationView mPointerLocationView;
-    InputChannel mPointerLocationInputChannel;
 
     // The current size of the screen; really; extends into the overscan area of
     // the screen and doesn't account for any system elements like the status bar.
@@ -381,7 +377,7 @@
     static final Rect mTmpContentFrame = new Rect();
     static final Rect mTmpVisibleFrame = new Rect();
     static final Rect mTmpNavigationFrame = new Rect();
-    
+
     WindowState mTopFullscreenOpaqueWindowState;
     boolean mTopIsFullscreen;
     boolean mForceStatusBar;
@@ -456,11 +452,16 @@
     private boolean mPowerKeyTriggered;
     private long mPowerKeyTime;
 
+    /* The number of steps between min and max brightness */
+    private static final int BRIGHTNESS_STEPS = 10;
+
     SettingsObserver mSettingsObserver;
     ShortcutManager mShortcutManager;
     PowerManager.WakeLock mBroadcastWakeLock;
     boolean mHavePendingMediaKeyRepeatWithWakeLock;
 
+    private int mCurrentUserId;
+
     // Maps global key codes to the components that will handle them.
     private GlobalKeyManager mGlobalKeyManager;
 
@@ -530,7 +531,7 @@
                     Settings.Secure.DEFAULT_INPUT_METHOD), false, this,
                     UserHandle.USER_ALL);
             resolver.registerContentObserver(Settings.System.getUriFor(
-                    "fancy_rotation_anim"), false, this,
+                    ImmersiveModeTesting.ENABLED_SETTING), false, this,
                     UserHandle.USER_ALL);
             updateSettings();
         }
@@ -540,20 +541,36 @@
             updateRotation(false);
         }
     }
-    
+
     class MyOrientationListener extends WindowOrientationListener {
         MyOrientationListener(Context context, Handler handler) {
             super(context, handler);
         }
-        
+
         @Override
         public void onProposedRotationChanged(int rotation) {
-            if (localLOGV) Log.v(TAG, "onProposedRotationChanged, rotation=" + rotation);
+            if (localLOGV) Slog.v(TAG, "onProposedRotationChanged, rotation=" + rotation);
             updateRotation(false);
         }
     }
     MyOrientationListener mOrientationListener;
 
+    private final BarController mStatusBarController = new BarController("StatusBar",
+            View.STATUS_BAR_TRANSIENT,
+            View.STATUS_BAR_UNHIDE,
+            View.SYSTEM_UI_FLAG_TRANSPARENT_STATUS,
+            StatusBarManager.WINDOW_STATUS_BAR);
+
+    private final BarController mNavigationBarController = new BarController("NavigationBar",
+            View.NAVIGATION_BAR_TRANSIENT,
+            View.NAVIGATION_BAR_UNHIDE,
+            View.SYSTEM_UI_FLAG_TRANSPARENT_NAVIGATION,
+            StatusBarManager.WINDOW_NAVIGATION_BAR);
+
+    private TransientNavigationConfirmation mTransientNavigationConfirmation;
+
+    private SystemGesturesPointerEventListener mSystemGestures;
+
     IStatusBarService getStatusBarService() {
         synchronized (mServiceAquireLock) {
             if (mStatusBarService == null) {
@@ -599,11 +616,11 @@
         }
         return true;
     }
-    
+
     /*
      * Various use cases for invoking this function
      * screen turning off, should always disable listeners if already enabled
-     * screen turned on and current app has sensor based orientation, enable listeners 
+     * screen turned on and current app has sensor based orientation, enable listeners
      * if not already enabled
      * screen turned on and current app does not have sensor orientation, disable listeners if
      * already enabled
@@ -617,7 +634,7 @@
         }
         //Could have been invoked due to screen turning on or off or
         //change of the currently visible window's orientation
-        if (localLOGV) Log.v(TAG, "Screen status="+mScreenOnEarly+
+        if (localLOGV) Slog.v(TAG, "Screen status="+mScreenOnEarly+
                 ", current orientation="+mCurrentAppOrientation+
                 ", SensorEnabled="+mOrientationSensorEnabled);
         boolean disable = true;
@@ -627,15 +644,15 @@
                 //enable listener if not already enabled
                 if (!mOrientationSensorEnabled) {
                     mOrientationListener.enable();
-                    if(localLOGV) Log.v(TAG, "Enabling listeners");
+                    if(localLOGV) Slog.v(TAG, "Enabling listeners");
                     mOrientationSensorEnabled = true;
                 }
-            } 
-        } 
+            }
+        }
         //check if sensors need to be disabled
         if (disable && mOrientationSensorEnabled) {
             mOrientationListener.disable();
-            if(localLOGV) Log.v(TAG, "Disabling listeners");
+            if(localLOGV) Slog.v(TAG, "Disabling listeners");
             mOrientationSensorEnabled = false;
         }
     }
@@ -679,7 +696,7 @@
     }
 
     private long getScreenshotChordLongPressDelay() {
-        if (mKeyguardMediator.isShowing()) {
+        if (mKeyguardDelegate.isShowing()) {
             // Double the time it takes to take a screenshot from the keyguard
             return (long) (KEYGUARD_SCREENSHOT_CHORD_DELAY_MULTIPLIER *
                     ViewConfiguration.getGlobalActionKeyTimeout());
@@ -742,7 +759,7 @@
         if (keyguardShowing) {
             // since it took two seconds of long press to bring this up,
             // poke the wake lock so they have some time to see the dialog.
-            mKeyguardMediator.userActivity();
+            mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
         }
     }
 
@@ -835,10 +852,6 @@
         mWindowManager = windowManager;
         mWindowManagerFuncs = windowManagerFuncs;
         mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
-        if (!mHeadless) {
-            // don't create KeyguardViewMediator if headless
-            mKeyguardMediator = new KeyguardViewMediator(context, null);
-        }
         mHandler = new PolicyHandler();
         mOrientationListener = new MyOrientationListener(mContext, mHandler);
         try {
@@ -911,6 +924,37 @@
         filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
         context.registerReceiver(mMultiuserReceiver, filter);
 
+        // monitor for system gestures
+        mSystemGestures = new SystemGesturesPointerEventListener(context,
+                new SystemGesturesPointerEventListener.Callbacks() {
+                    @Override
+                    public void onSwipeFromTop() {
+                        if (mStatusBar != null) {
+                            requestTransientBars(mStatusBar);
+                        }
+                    }
+                    @Override
+                    public void onSwipeFromBottom() {
+                        if (mNavigationBar != null && mNavigationBarOnBottom) {
+                            requestTransientBars(mNavigationBar);
+                        }
+                    }
+                    @Override
+                    public void onSwipeFromRight() {
+                        if (mNavigationBar != null && !mNavigationBarOnBottom) {
+                            requestTransientBars(mNavigationBar);
+                        }
+                    }
+                    @Override
+                    public void onDebug() {
+                        if (ImmersiveModeTesting.enabled) {
+                            ImmersiveModeTesting.toggleForceImmersiveMode(mFocusedWindow, mContext);
+                        }
+                    }
+                });
+        mTransientNavigationConfirmation = new TransientNavigationConfirmation(mContext);
+        mWindowManagerFuncs.registerPointerEventListener(mSystemGestures);
+
         mVibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
         mLongPressVibePattern = getLongIntArray(mContext.getResources(),
                 com.android.internal.R.array.config_longPressVibePattern);
@@ -962,19 +1006,21 @@
 
     @Override
     public void setInitialDisplaySize(Display display, int width, int height, int density) {
-        if (display.getDisplayId() != Display.DEFAULT_DISPLAY) {
-            throw new IllegalArgumentException("Can only set the default display");
+        // This method might be called before the policy has been fully initialized
+        // or for other displays we don't care about.
+        if (mContext == null || display.getDisplayId() != Display.DEFAULT_DISPLAY) {
+            return;
         }
         mDisplay = display;
 
+        final Resources res = mContext.getResources();
         int shortSize, longSize;
         if (width > height) {
             shortSize = height;
             longSize = width;
             mLandscapeRotation = Surface.ROTATION_0;
             mSeascapeRotation = Surface.ROTATION_180;
-            if (mContext.getResources().getBoolean(
-                    com.android.internal.R.bool.config_reverseDefaultRotation)) {
+            if (res.getBoolean(com.android.internal.R.bool.config_reverseDefaultRotation)) {
                 mPortraitRotation = Surface.ROTATION_90;
                 mUpsideDownRotation = Surface.ROTATION_270;
             } else {
@@ -986,8 +1032,7 @@
             longSize = height;
             mPortraitRotation = Surface.ROTATION_0;
             mUpsideDownRotation = Surface.ROTATION_180;
-            if (mContext.getResources().getBoolean(
-                    com.android.internal.R.bool.config_reverseDefaultRotation)) {
+            if (res.getBoolean(com.android.internal.R.bool.config_reverseDefaultRotation)) {
                 mLandscapeRotation = Surface.ROTATION_270;
                 mSeascapeRotation = Surface.ROTATION_90;
             } else {
@@ -996,68 +1041,42 @@
             }
         }
 
-        mStatusBarHeight = mContext.getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.status_bar_height);
+        mStatusBarHeight =
+                res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
 
         // Height of the navigation bar when presented horizontally at bottom
         mNavigationBarHeightForRotation[mPortraitRotation] =
         mNavigationBarHeightForRotation[mUpsideDownRotation] =
-                mContext.getResources().getDimensionPixelSize(
-                        com.android.internal.R.dimen.navigation_bar_height);
+                res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_height);
         mNavigationBarHeightForRotation[mLandscapeRotation] =
-        mNavigationBarHeightForRotation[mSeascapeRotation] =
-                mContext.getResources().getDimensionPixelSize(
-                        com.android.internal.R.dimen.navigation_bar_height_landscape);
+        mNavigationBarHeightForRotation[mSeascapeRotation] = res.getDimensionPixelSize(
+                com.android.internal.R.dimen.navigation_bar_height_landscape);
 
         // Width of the navigation bar when presented vertically along one side
         mNavigationBarWidthForRotation[mPortraitRotation] =
         mNavigationBarWidthForRotation[mUpsideDownRotation] =
         mNavigationBarWidthForRotation[mLandscapeRotation] =
         mNavigationBarWidthForRotation[mSeascapeRotation] =
-                mContext.getResources().getDimensionPixelSize(
-                        com.android.internal.R.dimen.navigation_bar_width);
+                res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_width);
 
         // SystemUI (status bar) layout policy
         int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / density;
+        int longSizeDp = longSize * DisplayMetrics.DENSITY_DEFAULT / density;
 
-        if (shortSizeDp < 600) {
-            // 0-599dp: "phone" UI with a separate status & navigation bar
-            mHasSystemNavBar = false;
-            mNavigationBarCanMove = true;
-        } else if (shortSizeDp < 720) {
-            // 600+dp: "phone" UI with modifications for larger screens
-            mHasSystemNavBar = false;
-            mNavigationBarCanMove = false;
-        }
+        // Allow the navigation bar to move on small devices (phones).
+        mNavigationBarCanMove = shortSizeDp < 600;
 
-        if (!mHasSystemNavBar) {
-            mHasNavigationBar = mContext.getResources().getBoolean(
-                    com.android.internal.R.bool.config_showNavigationBar);
-            // Allow a system property to override this. Used by the emulator.
-            // See also hasNavigationBar().
-            String navBarOverride = SystemProperties.get("qemu.hw.mainkeys");
-            if (! "".equals(navBarOverride)) {
-                if      (navBarOverride.equals("1")) mHasNavigationBar = false;
-                else if (navBarOverride.equals("0")) mHasNavigationBar = true;
-            }
-        } else {
+        mHasNavigationBar = res.getBoolean(com.android.internal.R.bool.config_showNavigationBar);
+        // Allow a system property to override this. Used by the emulator.
+        // See also hasNavigationBar().
+        String navBarOverride = SystemProperties.get("qemu.hw.mainkeys");
+        if ("1".equals(navBarOverride)) {
             mHasNavigationBar = false;
+        } else if ("0".equals(navBarOverride)) {
+            mHasNavigationBar = true;
         }
 
-        if (mHasSystemNavBar) {
-            // The system bar is always at the bottom.  If you are watching
-            // a video in landscape, we don't need to hide it if we can still
-            // show a 16:9 aspect ratio with it.
-            int longSizeDp = longSize * DisplayMetrics.DENSITY_DEFAULT / density;
-            int barHeightDp = mNavigationBarHeightForRotation[mLandscapeRotation]
-                    * DisplayMetrics.DENSITY_DEFAULT / density;
-            int aspect = ((shortSizeDp-barHeightDp) * 16) / longSizeDp;
-            // We have computed the aspect ratio with the bar height taken
-            // out to be 16:aspect.  If this is less than 9, then hiding
-            // the navigation bar will provide more useful space for wide
-            // screen movies.
-            mCanHideNavigationBar = aspect < 9;
-        } else if (mHasNavigationBar) {
+        if (mHasNavigationBar) {
             // The navigation bar is at the right in landscape; it seems always
             // useful to hide it for showing a video.
             mCanHideNavigationBar = true;
@@ -1073,6 +1092,20 @@
             mDemoHdmiRotation = mLandscapeRotation;
         }
         mDemoHdmiRotationLock = SystemProperties.getBoolean("persist.demo.hdmirotationlock", false);
+
+        // Only force the default orientation if the screen is xlarge, at least 960dp x 720dp, per
+        // http://developer.android.com/guide/practices/screens_support.html#range
+        mForceDefaultOrientation = longSizeDp >= 960 && shortSizeDp >= 720 &&
+                res.getBoolean(com.android.internal.R.bool.config_forceDefaultOrientation) &&
+                // For debug purposes the next line turns this feature off with:
+                // $ adb shell setprop config.override_forced_orient true
+                // $ adb shell wm size reset
+                !"true".equals(SystemProperties.get("config.override_forced_orient"));
+    }
+
+    @Override
+    public boolean isDefaultOrientationForced() {
+        return mForceDefaultOrientation;
     }
 
     @Override
@@ -1135,6 +1168,8 @@
                 mHasSoftInput = hasSoftInput;
                 updateRotation = true;
             }
+            ImmersiveModeTesting.enabled = Settings.System.getIntForUser(resolver,
+                    ImmersiveModeTesting.ENABLED_SETTING, 0, UserHandle.USER_CURRENT) != 0;
         }
         if (updateRotation) {
             updateRotation(true);
@@ -1166,23 +1201,16 @@
             lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
             wm.addView(mPointerLocationView, lp);
 
-            mPointerLocationInputChannel =
-                    mWindowManagerFuncs.monitorInput("PointerLocationView");
-            mPointerLocationInputEventReceiver =
-                    new PointerLocationInputEventReceiver(mPointerLocationInputChannel,
-                            Looper.myLooper(), mPointerLocationView);
+            mPointerLocationPointerEventListener = new PointerLocationPointerEventListener();
+            mWindowManagerFuncs.registerPointerEventListener(mPointerLocationPointerEventListener);
         }
     }
 
     private void disablePointerLocation() {
-        if (mPointerLocationInputEventReceiver != null) {
-            mPointerLocationInputEventReceiver.dispose();
-            mPointerLocationInputEventReceiver = null;
-        }
-
-        if (mPointerLocationInputChannel != null) {
-            mPointerLocationInputChannel.dispose();
-            mPointerLocationInputChannel = null;
+        if (mPointerLocationPointerEventListener != null) {
+            mWindowManagerFuncs.unregisterPointerEventListener(
+                    mPointerLocationPointerEventListener);
+            mPointerLocationPointerEventListener = null;
         }
 
         if (mPointerLocationView != null) {
@@ -1233,6 +1261,7 @@
             case TYPE_DREAM:
             case TYPE_INPUT_METHOD:
             case TYPE_WALLPAPER:
+            case TYPE_PRIVATE_PRESENTATION:
                 // The window manager will check these.
                 break;
             case TYPE_PHONE:
@@ -1279,6 +1308,7 @@
             case TYPE_DISPLAY_OVERLAY:
             case TYPE_HIDDEN_NAV_CONSUMER:
             case TYPE_KEYGUARD:
+            case TYPE_KEYGUARD_SCRIM:
             case TYPE_KEYGUARD_DIALOG:
             case TYPE_MAGNIFICATION_OVERLAY:
             case TYPE_NAVIGATION_BAR:
@@ -1294,6 +1324,7 @@
             case TYPE_SYSTEM_DIALOG:
             case TYPE_UNIVERSE_BACKGROUND:
             case TYPE_VOLUME_OVERLAY:
+            case TYPE_PRIVATE_PRESENTATION:
                 break;
         }
 
@@ -1303,11 +1334,11 @@
                         != PackageManager.PERMISSION_GRANTED;
     }
 
+    @Override
     public void adjustWindowParamsLw(WindowManager.LayoutParams attrs) {
         switch (attrs.type) {
             case TYPE_SYSTEM_OVERLAY:
             case TYPE_SECURE_SYSTEM_OVERLAY:
-            case TYPE_TOAST:
                 // These types of windows can't receive input events.
                 attrs.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                         | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
@@ -1331,11 +1362,8 @@
         }
     }
 
-    private boolean isBuiltInKeyboardVisible() {
-        return mHaveBuiltInKeyboard && !isHidden(mLidKeyboardAccessibility);
-    }
-
     /** {@inheritDoc} */
+    @Override
     public void adjustConfigurationLw(Configuration config, int keyboardPresence,
             int navigationPresence) {
         mHaveBuiltInKeyboard = (keyboardPresence & PRESENCE_INTERNAL) != 0;
@@ -1361,6 +1389,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public int windowTypeToLayerLw(int type) {
         if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
             return 2;
@@ -1368,6 +1397,8 @@
         switch (type) {
         case TYPE_UNIVERSE_BACKGROUND:
             return 1;
+        case TYPE_PRIVATE_PRESENTATION:
+            return 2;
         case TYPE_WALLPAPER:
             // wallpaper is at the bottom, though the window manager may move it.
             return 2;
@@ -1396,60 +1427,64 @@
         case TYPE_INPUT_METHOD_DIALOG:
             // on-screen keyboards and other such input method user interfaces go here.
             return 11;
+        case TYPE_KEYGUARD_SCRIM:
+            // the safety window that shows behind keyguard while keyguard is starting
+            return 12;
         case TYPE_KEYGUARD:
             // the keyguard; nothing on top of these can take focus, since they are
             // responsible for power management when displayed.
-            return 12;
-        case TYPE_KEYGUARD_DIALOG:
             return 13;
-        case TYPE_STATUS_BAR_SUB_PANEL:
+        case TYPE_KEYGUARD_DIALOG:
             return 14;
-        case TYPE_STATUS_BAR:
+        case TYPE_STATUS_BAR_SUB_PANEL:
             return 15;
-        case TYPE_STATUS_BAR_PANEL:
+        case TYPE_STATUS_BAR:
             return 16;
+        case TYPE_STATUS_BAR_PANEL:
+            return 17;
         case TYPE_VOLUME_OVERLAY:
             // the on-screen volume indicator and controller shown when the user
             // changes the device volume
-            return 17;
+            return 18;
         case TYPE_SYSTEM_OVERLAY:
             // the on-screen volume indicator and controller shown when the user
             // changes the device volume
-            return 18;
+            return 19;
         case TYPE_NAVIGATION_BAR:
             // the navigation bar, if available, shows atop most things
-            return 19;
+            return 20;
         case TYPE_NAVIGATION_BAR_PANEL:
             // some panels (e.g. search) need to show on top of the navigation bar
-            return 20;
+            return 21;
         case TYPE_SYSTEM_ERROR:
             // system-level error dialogs
-            return 21;
+            return 22;
         case TYPE_MAGNIFICATION_OVERLAY:
             // used to highlight the magnified portion of a display
-            return 22;
+            return 23;
         case TYPE_DISPLAY_OVERLAY:
             // used to simulate secondary display devices
-            return 23;
+            return 24;
         case TYPE_DRAG:
             // the drag layer: input for drag-and-drop is associated with this window,
             // which sits above all other focusable windows
-            return 24;
-        case TYPE_SECURE_SYSTEM_OVERLAY:
             return 25;
-        case TYPE_BOOT_PROGRESS:
+        case TYPE_SECURE_SYSTEM_OVERLAY:
             return 26;
+        case TYPE_BOOT_PROGRESS:
+            return 27;
         case TYPE_POINTER:
             // the (mouse) pointer layer
-            return 27;
-        case TYPE_HIDDEN_NAV_CONSUMER:
             return 28;
+        case TYPE_HIDDEN_NAV_CONSUMER:
+            return 29;
         }
         Log.e(TAG, "Unknown window type: " + type);
         return 2;
     }
 
     /** {@inheritDoc} */
+    @Override
     public int subWindowTypeToLayerLw(int type) {
         switch (type) {
         case TYPE_APPLICATION_PANEL:
@@ -1466,18 +1501,16 @@
         return 0;
     }
 
+    @Override
     public int getMaxWallpaperLayer() {
         return windowTypeToLayerLw(TYPE_STATUS_BAR);
     }
 
+    @Override
     public int getAboveUniverseLayer() {
         return windowTypeToLayerLw(TYPE_SYSTEM_ERROR);
     }
 
-    public boolean hasSystemNavBar() {
-        return mHasSystemNavBar;
-    }
-
     public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation) {
         if (mHasNavigationBar) {
             // For a basic navigation bar, when we are in landscape mode we place
@@ -1490,10 +1523,6 @@
     }
 
     public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation) {
-        if (mHasSystemNavBar) {
-            // For the system navigation bar, we always place it at the bottom.
-            return fullHeight - mNavigationBarHeightForRotation[rotation];
-        }
         if (mHasNavigationBar) {
             // For a basic navigation bar, when we are in portrait mode we place
             // the navigation bar to the bottom.
@@ -1509,15 +1538,11 @@
     }
 
     public int getConfigDisplayHeight(int fullWidth, int fullHeight, int rotation) {
-        // If we don't have a system nav bar, then there is a separate status
-        // bar at the top of the display.  We don't count that as part of the
-        // fixed decor, since it can hide; however, for purposes of configurations,
+        // There is a separate status bar at the top of the display.  We don't count that as part
+        // of the fixed decor, since it can hide; however, for purposes of configurations,
         // we do want to exclude it since applications can't generally use that part
         // of the screen.
-        if (!mHasSystemNavBar) {
-            return getNonDecorDisplayHeight(fullWidth, fullHeight, rotation) - mStatusBarHeight;
-        }
-        return getNonDecorDisplayHeight(fullWidth, fullHeight, rotation);
+        return getNonDecorDisplayHeight(fullWidth, fullHeight, rotation) - mStatusBarHeight;
     }
 
     @Override
@@ -1534,6 +1559,7 @@
             case TYPE_DREAM:
             case TYPE_UNIVERSE_BACKGROUND:
             case TYPE_KEYGUARD:
+            case TYPE_KEYGUARD_SCRIM:
                 return false;
             default:
                 return true;
@@ -1544,7 +1570,7 @@
     @Override
     public View addStartingWindow(IBinder appToken, String packageName, int theme,
             CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes,
-            int icon, int windowFlags) {
+            int icon, int logo, int windowFlags) {
         if (!SHOW_STARTING_ANIMATIONS) {
             return null;
         }
@@ -1601,6 +1627,9 @@
                 win.addFlags(WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW);
             }
 
+            win.setDefaultIcon(icon);
+            win.setDefaultLogo(logo);
+
             win.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
                     WindowManager.LayoutParams.MATCH_PARENT);
 
@@ -1696,6 +1725,7 @@
                     }
                 }
                 mStatusBar = win;
+                mStatusBarController.setWindow(win);
                 break;
             case TYPE_NAVIGATION_BAR:
                 mContext.enforceCallingOrSelfPermission(
@@ -1707,7 +1737,8 @@
                     }
                 }
                 mNavigationBar = win;
-                if (DEBUG_LAYOUT) Log.i(TAG, "NAVIGATION BAR: " + mNavigationBar);
+                mNavigationBarController.setWindow(win);
+                if (DEBUG_LAYOUT) Slog.i(TAG, "NAVIGATION BAR: " + mNavigationBar);
                 break;
             case TYPE_NAVIGATION_BAR_PANEL:
                 mContext.enforceCallingOrSelfPermission(
@@ -1730,6 +1761,13 @@
                 }
                 mKeyguard = win;
                 break;
+            case TYPE_KEYGUARD_SCRIM:
+                if (mKeyguardScrim != null) {
+                    return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
+                }
+                mKeyguardScrim = win;
+                break;
+
         }
         return WindowManagerGlobal.ADD_OKAY;
     }
@@ -1738,10 +1776,17 @@
     public void removeWindowLw(WindowState win) {
         if (mStatusBar == win) {
             mStatusBar = null;
+            mStatusBarController.setWindow(null);
         } else if (mKeyguard == win) {
+            Log.v(TAG, "Removing keyguard window (Did it crash?)");
             mKeyguard = null;
-        } else if (mNavigationBar == win) {
+            mKeyguardDelegate.showScrim();
+        } else if (mKeyguardScrim == win) {
+            Log.v(TAG, "Removing keyguard scrim");
+            mKeyguardScrim = null;
+        } if (mNavigationBar == win) {
             mNavigationBar = null;
+            mNavigationBarController.setWindow(null);
         }
     }
 
@@ -1980,6 +2025,7 @@
             if (attrs != null) {
                 final int type = attrs.type;
                 if (type == WindowManager.LayoutParams.TYPE_KEYGUARD
+                        || type == WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM
                         || type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG) {
                     // the "app" is keyguard, so give it the key
                     return 0;
@@ -2085,6 +2131,43 @@
                 mHandler.post(mScreenshotRunnable);
             }
             return -1;
+        } else if (keyCode == KeyEvent.KEYCODE_BRIGHTNESS_UP
+                || keyCode == KeyEvent.KEYCODE_BRIGHTNESS_DOWN) {
+            if (down) {
+                int direction = keyCode == KeyEvent.KEYCODE_BRIGHTNESS_UP ? 1 : -1;
+
+                // Disable autobrightness if it's on
+                int auto = Settings.System.getIntForUser(
+                        mContext.getContentResolver(),
+                        Settings.System.SCREEN_BRIGHTNESS_MODE,
+                        Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL,
+                        UserHandle.USER_CURRENT_OR_SELF);
+                if (auto != 0) {
+                    Settings.System.putIntForUser(mContext.getContentResolver(),
+                            Settings.System.SCREEN_BRIGHTNESS_MODE,
+                            Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL,
+                            UserHandle.USER_CURRENT_OR_SELF);
+                }
+
+                int min = mPowerManager.getMinimumScreenBrightnessSetting();
+                int max = mPowerManager.getMaximumScreenBrightnessSetting();
+                int step = (max - min + BRIGHTNESS_STEPS - 1) / BRIGHTNESS_STEPS * direction;
+                int brightness = Settings.System.getIntForUser(mContext.getContentResolver(),
+                        Settings.System.SCREEN_BRIGHTNESS,
+                        mPowerManager.getDefaultScreenBrightnessSetting(),
+                        UserHandle.USER_CURRENT_OR_SELF);
+                brightness += step;
+                // Make sure we don't go beyond the limits.
+                brightness = Math.min(max, brightness);
+                brightness = Math.max(min, brightness);
+
+                Settings.System.putIntForUser(mContext.getContentResolver(),
+                        Settings.System.SCREEN_BRIGHTNESS, brightness,
+                        UserHandle.USER_CURRENT_OR_SELF);
+                Intent intent = new Intent(Intent.ACTION_SHOW_BRIGHTNESS_DIALOG);
+                mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT_OR_SELF);
+            }
+            return -1;
         }
 
         // Shortcuts are invoked through Search+key, so intercept those here
@@ -2102,7 +2185,7 @@
                     if (shortcutIntent != null) {
                         shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                         try {
-                            mContext.startActivity(shortcutIntent);
+                            mContext.startActivityAsUser(shortcutIntent, UserHandle.CURRENT);
                         } catch (ActivityNotFoundException ex) {
                             Slog.w(TAG, "Dropping shortcut key combination because "
                                     + "the activity to which it is registered was not found: "
@@ -2128,7 +2211,7 @@
                 if (shortcutIntent != null) {
                     shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                     try {
-                        mContext.startActivity(shortcutIntent);
+                        mContext.startActivityAsUser(shortcutIntent, UserHandle.CURRENT);
                     } catch (ActivityNotFoundException ex) {
                         Slog.w(TAG, "Dropping shortcut key combination because "
                                 + "the activity to which it is registered was not found: "
@@ -2146,7 +2229,7 @@
                 Intent intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, category);
                 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                 try {
-                    mContext.startActivity(intent);
+                    mContext.startActivityAsUser(intent, UserHandle.CURRENT);
                 } catch (ActivityNotFoundException ex) {
                     Slog.w(TAG, "Dropping application launch key because "
                             + "the activity to which it is registered was not found: "
@@ -2293,7 +2376,7 @@
             if (searchManager != null) {
                 searchManager.stopSearch();
             }
-            mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
+            mContext.startActivityAsUser(intent, UserHandle.CURRENT);
         } catch (ActivityNotFoundException e) {
             Slog.w(TAG, "No activity to handle assist long press action.", e);
         }
@@ -2308,7 +2391,7 @@
                     | Intent.FLAG_ACTIVITY_SINGLE_TOP
                     | Intent.FLAG_ACTIVITY_CLEAR_TOP);
             try {
-                mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
+                mContext.startActivityAsUser(intent, UserHandle.CURRENT);
             } catch (ActivityNotFoundException e) {
                 Slog.w(TAG, "No activity to handle assist action.", e);
             }
@@ -2372,12 +2455,12 @@
      * given the situation with the keyguard.
      */
     void launchHomeFromHotKey() {
-        if (mKeyguardMediator != null && mKeyguardMediator.isShowingAndNotHidden()) {
+        if (mKeyguardDelegate != null && mKeyguardDelegate.isShowingAndNotHidden()) {
             // don't launch home if keyguard showing
-        } else if (!mHideLockScreen && mKeyguardMediator.isInputRestricted()) {
+        } else if (!mHideLockScreen && mKeyguardDelegate.isInputRestricted()) {
             // when in keyguard restricted mode, must first verify unlock
             // before launching home
-            mKeyguardMediator.verifyUnlock(new OnKeyguardExitResult() {
+            mKeyguardDelegate.verifyUnlock(new OnKeyguardExitResult() {
                 public void onKeyguardExitResult(boolean success) {
                     if (success) {
                         try {
@@ -2400,13 +2483,15 @@
         }
     }
 
-    /**
-     * A delayed callback use to determine when it is okay to re-allow applications
-     * to use certain system UI flags.  This is used to prevent applications from
-     * spamming system UI changes that prevent the navigation bar from being shown.
-     */
-    final Runnable mAllowSystemUiDelay = new Runnable() {
-        @Override public void run() {
+    private final Runnable mClearHideNavigationFlag = new Runnable() {
+        @Override
+        public void run() {
+            synchronized (mWindowManagerFuncs.getWindowManagerLock()) {
+                // Clear flags.
+                mForceClearedSystemUiFlags &=
+                        ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
+            }
+            mWindowManagerFuncs.reevaluateStatusBarVisibility();
         }
     };
 
@@ -2430,7 +2515,7 @@
                     if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
                         // When the user taps down, we re-show the nav bar.
                         boolean changed = false;
-                        synchronized (mLock) {
+                        synchronized (mWindowManagerFuncs.getWindowManagerLock()) {
                             // Any user activity always causes us to show the
                             // navigation controls, if they had been hidden.
                             // We also clear the low profile and only content
@@ -2452,16 +2537,7 @@
                             if (mForceClearedSystemUiFlags != newVal) {
                                 mForceClearedSystemUiFlags = newVal;
                                 changed = true;
-                                mHandler.postDelayed(new Runnable() {
-                                    @Override public void run() {
-                                        synchronized (mLock) {
-                                            // Clear flags.
-                                            mForceClearedSystemUiFlags &=
-                                                    ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
-                                        }
-                                        mWindowManagerFuncs.reevaluateStatusBarVisibility();
-                                    }
-                                }, 1000);
+                                mHandler.postDelayed(mClearHideNavigationFlag, 1000);
                             }
                         }
                         if (changed) {
@@ -2485,6 +2561,9 @@
 
     @Override
     public int adjustSystemUiVisibilityLw(int visibility) {
+        mStatusBarController.adjustSystemUiVisibilityLw(mLastSystemUiFlags, visibility);
+        mNavigationBarController.adjustSystemUiVisibilityLw(mLastSystemUiFlags, visibility);
+
         // Reset any bits in mForceClearingStatusBarVisibility that
         // are now clear.
         mResettingSystemUiFlags &= visibility;
@@ -2586,8 +2665,8 @@
         mUnrestrictedScreenHeight = displayHeight - overscanTop - overscanBottom;
         mRestrictedScreenLeft = mUnrestrictedScreenLeft;
         mRestrictedScreenTop = mUnrestrictedScreenTop;
-        mRestrictedScreenWidth = mUnrestrictedScreenWidth;
-        mRestrictedScreenHeight = mUnrestrictedScreenHeight;
+        mRestrictedScreenWidth = mSystemGestures.screenWidth = mUnrestrictedScreenWidth;
+        mRestrictedScreenHeight = mSystemGestures.screenHeight = mUnrestrictedScreenHeight;
         mDockLeft = mContentLeft = mStableLeft = mStableFullscreenLeft
                 = mCurLeft = mUnrestrictedScreenLeft;
         mDockTop = mContentTop = mStableTop = mStableFullscreenTop
@@ -2612,13 +2691,17 @@
         if (isDefaultDisplay) {
             // For purposes of putting out fake window up to steal focus, we will
             // drive nav being hidden only by whether it is requested.
-            boolean navVisible = (mLastSystemUiFlags&View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
+            final int sysui = mLastSystemUiFlags;
+            boolean navVisible = (sysui & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
+            boolean navTransparent = (sysui & View.SYSTEM_UI_FLAG_TRANSPARENT_NAVIGATION) != 0;
+            boolean transientAllowed = (sysui & View.SYSTEM_UI_FLAG_IMMERSIVE) != 0;
+            navTransparent &= !transientAllowed;  // transient trumps transparent
 
             // When the navigation bar isn't visible, we put up a fake
             // input window to catch all touch events.  This way we can
             // detect when the user presses anywhere to bring back the nav
             // bar and ensure the application doesn't see the event.
-            if (navVisible) {
+            if (navVisible || transientAllowed) {
                 if (mHideNavFakeWindow != null) {
                     mHideNavFakeWindow.dismiss();
                     mHideNavFakeWindow = null;
@@ -2635,7 +2718,9 @@
             // then take that into account.
             navVisible |= !mCanHideNavigationBar;
 
+            boolean updateSysUiVisibility = false;
             if (mNavigationBar != null) {
+                boolean transientNavBarShowing = mNavigationBarController.isTransientShowing();
                 // Force the navigation bar to its appropriate place and
                 // size.  We need to do this directly, instead of relying on
                 // it to bubble up from the nav bar, because this needs to
@@ -2647,17 +2732,20 @@
                             - mNavigationBarHeightForRotation[displayRotation];
                     mTmpNavigationFrame.set(0, top, displayWidth, displayHeight - overscanBottom);
                     mStableBottom = mStableFullscreenBottom = mTmpNavigationFrame.top;
-                    if (navVisible) {
-                        mNavigationBar.showLw(true);
+                    if (transientNavBarShowing || navTransparent) {
+                        mNavigationBarController.setBarShowingLw(true);
+                    } else if (navVisible) {
+                        mNavigationBarController.setBarShowingLw(true);
                         mDockBottom = mTmpNavigationFrame.top;
                         mRestrictedScreenHeight = mDockBottom - mRestrictedScreenTop;
                         mRestrictedOverscanScreenHeight = mDockBottom - mRestrictedOverscanScreenTop;
                     } else {
                         // We currently want to hide the navigation UI.
-                        mNavigationBar.hideLw(true);
+                        mNavigationBarController.setBarShowingLw(false);
                     }
-                    if (navVisible && !mNavigationBar.isAnimatingLw()) {
-                        // If the nav bar is currently requested to be visible,
+                    if (navVisible && !navTransparent && !mNavigationBar.isAnimatingLw()
+                            && !mNavigationBarController.wasRecentlyTransparent()) {
+                        // If the opaque nav bar is currently requested to be visible,
                         // and not in the process of animating on or off, then
                         // we can tell the app that it is covered by it.
                         mSystemBottom = mTmpNavigationFrame.top;
@@ -2668,16 +2756,19 @@
                             - mNavigationBarWidthForRotation[displayRotation];
                     mTmpNavigationFrame.set(left, 0, displayWidth - overscanRight, displayHeight);
                     mStableRight = mStableFullscreenRight = mTmpNavigationFrame.left;
-                    if (navVisible) {
-                        mNavigationBar.showLw(true);
+                    if (transientNavBarShowing || navTransparent) {
+                        mNavigationBarController.setBarShowingLw(true);
+                    } else if (navVisible) {
+                        mNavigationBarController.setBarShowingLw(true);
                         mDockRight = mTmpNavigationFrame.left;
                         mRestrictedScreenWidth = mDockRight - mRestrictedScreenLeft;
                         mRestrictedOverscanScreenWidth = mDockRight - mRestrictedOverscanScreenLeft;
                     } else {
                         // We currently want to hide the navigation UI.
-                        mNavigationBar.hideLw(true);
+                        mNavigationBarController.setBarShowingLw(false);
                     }
-                    if (navVisible && !mNavigationBar.isAnimatingLw()) {
+                    if (navVisible && !navTransparent && !mNavigationBar.isAnimatingLw()
+                            && !mNavigationBarController.wasRecentlyTransparent()) {
                         // If the nav bar is currently requested to be visible,
                         // and not in the process of animating on or off, then
                         // we can tell the app that it is covered by it.
@@ -2694,9 +2785,12 @@
                 // And compute the final frame.
                 mNavigationBar.computeFrameLw(mTmpNavigationFrame, mTmpNavigationFrame,
                         mTmpNavigationFrame, mTmpNavigationFrame, mTmpNavigationFrame);
-                if (DEBUG_LAYOUT) Log.i(TAG, "mNavigationBar frame: " + mTmpNavigationFrame);
+                if (DEBUG_LAYOUT) Slog.i(TAG, "mNavigationBar frame: " + mTmpNavigationFrame);
+                if (mNavigationBarController.checkHiddenLw()) {
+                    updateSysUiVisibility = true;
+                }
             }
-            if (DEBUG_LAYOUT) Log.i(TAG, String.format("mDock rect: (%d,%d - %d,%d)",
+            if (DEBUG_LAYOUT) Slog.i(TAG, String.format("mDock rect: (%d,%d - %d,%d)",
                     mDockLeft, mDockTop, mDockRight, mDockBottom));
 
             // decide where the status bar goes ahead of time
@@ -2720,9 +2814,12 @@
                 // For layout, the status bar is always at the top with our fixed height.
                 mStableTop = mUnrestrictedScreenTop + mStatusBarHeight;
 
+                boolean statusBarTransient = (sysui & View.STATUS_BAR_TRANSIENT) != 0;
+                boolean statusBarTransparent = (sysui & View.SYSTEM_UI_FLAG_TRANSPARENT_STATUS) != 0;
+
                 // If the status bar is hidden, we don't want to cause
                 // windows behind it to scroll.
-                if (mStatusBar.isVisibleLw()) {
+                if (mStatusBar.isVisibleLw() && !statusBarTransient) {
                     // Status bar may go away, so the screen area it occupies
                     // is available to apps but just covering them when the
                     // status bar is visible.
@@ -2733,24 +2830,33 @@
                     mContentLeft = mCurLeft = mDockLeft;
                     mContentRight = mCurRight = mDockRight;
 
-                    if (DEBUG_LAYOUT) Log.v(TAG, "Status bar: " +
+                    if (DEBUG_LAYOUT) Slog.v(TAG, "Status bar: " +
                         String.format(
                             "dock=[%d,%d][%d,%d] content=[%d,%d][%d,%d] cur=[%d,%d][%d,%d]",
                             mDockLeft, mDockTop, mDockRight, mDockBottom,
                             mContentLeft, mContentTop, mContentRight, mContentBottom,
                             mCurLeft, mCurTop, mCurRight, mCurBottom));
                 }
-                if (mStatusBar.isVisibleLw() && !mStatusBar.isAnimatingLw()) {
-                    // If the status bar is currently requested to be visible,
+                if (mStatusBar.isVisibleLw() && !mStatusBar.isAnimatingLw()
+                        && !statusBarTransient && !statusBarTransparent
+                        && !mStatusBarController.wasRecentlyTransparent()) {
+                    // If the opaque status bar is currently requested to be visible,
                     // and not in the process of animating on or off, then
                     // we can tell the app that it is covered by it.
                     mSystemTop = mUnrestrictedScreenTop + mStatusBarHeight;
                 }
+                if (mStatusBarController.checkHiddenLw()) {
+                    updateSysUiVisibility = true;
+                }
+            }
+            if (updateSysUiVisibility) {
+                updateSystemUiVisibilityLw();
             }
         }
     }
 
     /** {@inheritDoc} */
+    @Override
     public int getSystemDecorRectLw(Rect systemRect) {
         systemRect.left = mSystemLeft;
         systemRect.top = mSystemTop;
@@ -2761,6 +2867,11 @@
         return 0;
     }
 
+    @Override
+    public void getContentRectLw(Rect r) {
+        r.set(mContentLeft, mContentTop, mContentRight, mContentBottom);
+    }
+
     void setAttachedWindowFrames(WindowState win, int fl, int adjust, WindowState attached,
             boolean insetDecors, Rect pf, Rect df, Rect of, Rect cf, Rect vf) {
         if (win.getSurfaceLayer() > mDockLayer && attached.getSurfaceLayer() < mDockLayer) {
@@ -2840,9 +2951,7 @@
         final boolean needsToOffsetInputMethodTarget = isDefaultDisplay &&
                 (win == mLastInputMethodTargetWindow && mLastInputMethodWindow != null);
         if (needsToOffsetInputMethodTarget) {
-            if (DEBUG_LAYOUT) {
-                Slog.i(TAG, "Offset ime target window by the last ime window state");
-            }
+            if (DEBUG_LAYOUT) Slog.i(TAG, "Offset ime target window by the last ime window state");
             offsetInputMethodWindowLw(mLastInputMethodWindow);
         }
 
@@ -2879,15 +2988,15 @@
             pf.left = df.left = of.left = cf.left = vf.left = mDockLeft;
             pf.top = df.top = of.top = cf.top = vf.top = mDockTop;
             pf.right = df.right = of.right = cf.right = vf.right = mDockRight;
-            pf.bottom = df.bottom = of.bottom = cf.bottom = vf.bottom = mDockBottom;
+            // IM dock windows always go above the nav bar.
+            pf.bottom = df.bottom = of.bottom = cf.bottom = vf.bottom = mStableBottom;
             // IM dock windows always go to the bottom of the screen.
             attrs.gravity = Gravity.BOTTOM;
             mDockLayer = win.getSurfaceLayer();
         } else {
             if ((fl & (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR))
                     == (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) {
-                if (DEBUG_LAYOUT)
-                    Log.v(TAG, "layoutWindowLw(" + attrs.getTitle() 
+                if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle() 
                             + "): IN_SCREEN, INSET_DECOR");
                 // This is the case for a normal activity window: we want it
                 // to cover all of the screen space, and it can take care of
@@ -2917,11 +3026,9 @@
                                 ? mRestrictedScreenTop+mRestrictedScreenHeight
                                 : mUnrestrictedScreenTop + mUnrestrictedScreenHeight;
 
-                        if (DEBUG_LAYOUT) {
-                            Log.v(TAG, String.format(
+                        if (DEBUG_LAYOUT) Slog.v(TAG, String.format(
                                         "Laying out status bar window: (%d,%d - %d,%d)",
                                         pf.left, pf.top, pf.right, pf.bottom));
-                        }
                     } else if ((attrs.flags&FLAG_LAYOUT_IN_OVERSCAN) != 0
                             && attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW
                             && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
@@ -3003,8 +3110,8 @@
             } else if ((fl & FLAG_LAYOUT_IN_SCREEN) != 0 || (sysUiFl
                     & (View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                             | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION)) != 0) {
-                if (DEBUG_LAYOUT)
-                    Log.v(TAG, "layoutWindowLw(" + attrs.getTitle() + "): IN_SCREEN");
+                if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle() +
+                        "): IN_SCREEN");
                 // A window that has requested to fill the entire screen just
                 // gets everything, period.
                 if (attrs.type == TYPE_STATUS_BAR_PANEL
@@ -3018,11 +3125,9 @@
                     pf.bottom = df.bottom = of.bottom = cf.bottom = hasNavBar
                                           ? mRestrictedScreenTop+mRestrictedScreenHeight
                                           : mUnrestrictedScreenTop + mUnrestrictedScreenHeight;
-                    if (DEBUG_LAYOUT) {
-                        Log.v(TAG, String.format(
+                    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_NAVIGATION_BAR
                         || attrs.type == TYPE_NAVIGATION_BAR_PANEL) {
                     // The navigation bar has Real Ultimate Power.
@@ -3032,11 +3137,9 @@
                             + mUnrestrictedScreenWidth;
                     pf.bottom = df.bottom = of.bottom = mUnrestrictedScreenTop
                             + mUnrestrictedScreenHeight;
-                    if (DEBUG_LAYOUT) {
-                        Log.v(TAG, String.format(
+                    if (DEBUG_LAYOUT) Slog.v(TAG, String.format(
                                     "Laying out navigation bar window: (%d,%d - %d,%d)",
                                     pf.left, pf.top, pf.right, pf.bottom));
-                    }
                 } else if ((attrs.type == TYPE_SECURE_SYSTEM_OVERLAY
                                 || attrs.type == TYPE_BOOT_PROGRESS)
                         && ((fl & FLAG_FULLSCREEN) != 0)) {
@@ -3056,14 +3159,14 @@
                             + mOverscanScreenWidth;
                     pf.bottom = df.bottom = of.bottom = cf.bottom = mOverscanScreenTop
                             + mOverscanScreenHeight;
-                } else if (attrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER) {
-                    // The wallpaper mostly goes into the overscan region.
-                    pf.left = df.left = of.left = cf.left = mRestrictedOverscanScreenLeft;
-                    pf.top = df.top = of.top = cf.top = mRestrictedOverscanScreenTop;
+                } else if (attrs.type == TYPE_WALLPAPER) {
+                    // The wallpaper also has Real Ultimate Power.
+                    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
-                            = mRestrictedOverscanScreenLeft + mRestrictedOverscanScreenWidth;
+                            = mUnrestrictedScreenLeft + mUnrestrictedScreenWidth;
                     pf.bottom = df.bottom = of.bottom = cf.bottom
-                            = mRestrictedOverscanScreenTop + mRestrictedOverscanScreenHeight;
+                            = mUnrestrictedScreenTop + mUnrestrictedScreenHeight;
                 } else if ((attrs.flags & FLAG_LAYOUT_IN_OVERSCAN) != 0
                         && attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW
                         && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
@@ -3077,11 +3180,12 @@
                             = mOverscanScreenTop + mOverscanScreenHeight;
                 } else if (mCanHideNavigationBar
                         && (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0
-                        && attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW
-                        && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
+                        && (attrs.type == TYPE_TOAST
+                            || (attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW
+                            && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW))) {
                     // Asking for layout as if the nav bar is hidden, lets the
                     // application extend into the unrestricted screen area.  We
-                    // only do this for application windows to ensure no window that
+                    // only do this for application windows (or toasts) to ensure no window that
                     // can be above the nav bar can do this.
                     // XXX This assumes that an app asking for this will also
                     // ask for layout in only content.  We can't currently figure out
@@ -3112,14 +3216,14 @@
                     vf.set(cf);
                 }
             } else if (attached != null) {
-                if (DEBUG_LAYOUT)
-                    Log.v(TAG, "layoutWindowLw(" + attrs.getTitle() + "): attached to " + attached);
+                if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle() +
+                        "): attached to " + attached);
                 // A child window should be placed inside of the same visible
                 // frame that its parent had.
                 setAttachedWindowFrames(win, fl, adjust, attached, false, pf, df, of, cf, vf);
             } else {
-                if (DEBUG_LAYOUT)
-                    Log.v(TAG, "layoutWindowLw(" + attrs.getTitle() + "): normal window");
+                if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle() +
+                        "): normal window");
                 // Otherwise, a normal window must be placed inside the content
                 // of all screen decorations.
                 if (attrs.type == TYPE_STATUS_BAR_PANEL) {
@@ -3161,13 +3265,14 @@
             }
         }
 
-        if ((fl & FLAG_LAYOUT_NO_LIMITS) != 0) {
+        // TYPE_SYSTEM_ERROR is above the NavigationBar so it can't be allowed to extend over it.
+        if ((fl & FLAG_LAYOUT_NO_LIMITS) != 0 && attrs.type != TYPE_SYSTEM_ERROR) {
             df.left = df.top = of.left = of.top = cf.left = cf.top = vf.left = vf.top = -10000;
             df.right = df.bottom = of.right = of.bottom = cf.right = cf.bottom
                     = vf.right = vf.bottom = 10000;
         }
 
-        if (DEBUG_LAYOUT) Log.v(TAG, "Compute frame " + attrs.getTitle()
+        if (DEBUG_LAYOUT) Slog.v(TAG, "Compute frame " + attrs.getTitle()
                 + ": sim=#" + Integer.toHexString(sim)
                 + " attach=" + attached + " type=" + attrs.type 
                 + String.format(" flags=0x%08x", fl)
@@ -3197,7 +3302,7 @@
         if (mCurBottom > top) {
             mCurBottom = top;
         }
-        if (DEBUG_LAYOUT) Log.v(TAG, "Input method: mDockBottom="
+        if (DEBUG_LAYOUT) Slog.v(TAG, "Input method: mDockBottom="
                 + mDockBottom + " mContentBottom="
                 + mContentBottom + " mCurBottom=" + mCurBottom);
     }
@@ -3231,7 +3336,8 @@
         if (DEBUG_LAYOUT) Slog.i(TAG, "Win " + win + ": isVisibleOrBehindKeyguardLw="
                 + win.isVisibleOrBehindKeyguardLw());
         if (mTopFullscreenOpaqueWindowState == null && (win.getAttrs().privateFlags
-                &WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_NAV_BAR) != 0) {
+                &WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_NAV_BAR) != 0
+                || (win.isVisibleLw() && attrs.type == TYPE_INPUT_METHOD)) {
             if (mForcingShowNavBarLayer < 0) {
                 mForcingShowNavBar = true;
                 mForcingShowNavBarLayer = win.getSurfaceLayer();
@@ -3264,21 +3370,20 @@
                     && attrs.x == 0 && attrs.y == 0
                     && attrs.width == WindowManager.LayoutParams.MATCH_PARENT
                     && attrs.height == WindowManager.LayoutParams.MATCH_PARENT) {
-                if (DEBUG_LAYOUT) Log.v(TAG, "Fullscreen window: " + win);
+                if (DEBUG_LAYOUT) Slog.v(TAG, "Fullscreen window: " + win);
                 mTopFullscreenOpaqueWindowState = win;
                 if ((attrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0) {
-                    if (DEBUG_LAYOUT) Log.v(TAG, "Setting mHideLockScreen to true by win " + win);
+                    if (DEBUG_LAYOUT) Slog.v(TAG, "Setting mHideLockScreen to true by win " + win);
                     mHideLockScreen = true;
                     mForceStatusBarFromKeyguard = false;
                 }
                 if ((attrs.flags & FLAG_DISMISS_KEYGUARD) != 0
                         && mDismissKeyguard == DISMISS_KEYGUARD_NONE) {
-                    if (DEBUG_LAYOUT) Log.v(TAG, "Setting mDismissKeyguard to true by win " + win);
+                    if (DEBUG_LAYOUT) Slog.v(TAG, "Setting mDismissKeyguard true by win " + win);
                     mDismissKeyguard = mWinDismissingKeyguard == win ?
                             DISMISS_KEYGUARD_CONTINUE : DISMISS_KEYGUARD_START;
                     mWinDismissingKeyguard = win;
-                    mForceStatusBarFromKeyguard =
-                            mShowingLockscreen && mKeyguardMediator.isSecure();
+                    mForceStatusBarFromKeyguard = mShowingLockscreen && isKeyguardSecure();
                 }
                 if ((attrs.flags & FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) != 0) {
                     mAllowLockscreenWhenOn = true;
@@ -3306,17 +3411,19 @@
         }
 
         if (mStatusBar != null) {
-            if (DEBUG_LAYOUT) Log.i(TAG, "force=" + mForceStatusBar
+            if (DEBUG_LAYOUT) Slog.i(TAG, "force=" + mForceStatusBar
                     + " forcefkg=" + mForceStatusBarFromKeyguard
                     + " top=" + mTopFullscreenOpaqueWindowState);
             if (mForceStatusBar || mForceStatusBarFromKeyguard) {
-                if (DEBUG_LAYOUT) Log.v(TAG, "Showing status bar: forced");
-                if (mStatusBar.showLw(true)) changes |= FINISH_LAYOUT_REDO_LAYOUT;
+                if (DEBUG_LAYOUT) Slog.v(TAG, "Showing status bar: forced");
+                if (mStatusBarController.setBarShowingLw(true)) {
+                    changes |= FINISH_LAYOUT_REDO_LAYOUT;
+                }
             } else if (mTopFullscreenOpaqueWindowState != null) {
                 if (localLOGV) {
-                    Log.d(TAG, "frame: " + mTopFullscreenOpaqueWindowState.getFrameLw()
+                    Slog.d(TAG, "frame: " + mTopFullscreenOpaqueWindowState.getFrameLw()
                             + " shown frame: " + mTopFullscreenOpaqueWindowState.getShownFrameLw());
-                    Log.d(TAG, "attr: " + mTopFullscreenOpaqueWindowState.getAttrs()
+                    Slog.d(TAG, "attr: " + mTopFullscreenOpaqueWindowState.getAttrs()
                             + " lp.flags=0x" + Integer.toHexString(lp.flags));
                 }
                 topIsFullscreen = (lp.flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0
@@ -3325,30 +3432,22 @@
                 // and mTopIsFullscreen is that that mTopIsFullscreen is set only if the window
                 // has the FLAG_FULLSCREEN set.  Not sure if there is another way that to be the
                 // case though.
-                if (topIsFullscreen) {
-                    if (DEBUG_LAYOUT) Log.v(TAG, "** HIDING status bar");
-                    if (mStatusBar.hideLw(true)) {
+                if (mStatusBarController.isTransientShowing()) {
+                    if (mStatusBarController.setBarShowingLw(true)) {
                         changes |= FINISH_LAYOUT_REDO_LAYOUT;
-
-                        mHandler.post(new Runnable() {
-                            @Override
-                            public void run() {
-                            try {
-                                IStatusBarService statusbar = getStatusBarService();
-                                if (statusbar != null) {
-                                    statusbar.collapsePanels();
-                                }
-                            } catch (RemoteException ex) {
-                                // re-acquire status bar service next time it is needed.
-                                mStatusBarService = null;
-                            }
-                        }});
-                    } else if (DEBUG_LAYOUT) {
-                        Log.v(TAG, "Preventing status bar from hiding by policy");
+                    }
+                } else if (topIsFullscreen) {
+                    if (DEBUG_LAYOUT) Slog.v(TAG, "** HIDING status bar");
+                    if (mStatusBarController.setBarShowingLw(false)) {
+                        changes |= FINISH_LAYOUT_REDO_LAYOUT;
+                    } else {
+                        if (DEBUG_LAYOUT) Slog.v(TAG, "Status bar already hiding");
                     }
                 } else {
-                    if (DEBUG_LAYOUT) Log.v(TAG, "** SHOWING status bar: top is not fullscreen");
-                    if (mStatusBar.showLw(true)) changes |= FINISH_LAYOUT_REDO_LAYOUT;
+                    if (DEBUG_LAYOUT) Slog.v(TAG, "** SHOWING status bar: top is not fullscreen");
+                    if (mStatusBarController.setBarShowingLw(true)) {
+                        changes |= FINISH_LAYOUT_REDO_LAYOUT;
+                    }
                 }
             }
         }
@@ -3358,19 +3457,19 @@
         // Hide the key guard if a visible window explicitly specifies that it wants to be
         // displayed when the screen is locked.
         if (mKeyguard != null) {
-            if (localLOGV) Log.v(TAG, "finishPostLayoutPolicyLw: mHideKeyguard="
+            if (localLOGV) Slog.v(TAG, "finishPostLayoutPolicyLw: mHideKeyguard="
                     + mHideLockScreen);
-            if (mDismissKeyguard != DISMISS_KEYGUARD_NONE && !mKeyguardMediator.isSecure()) {
+            if (mDismissKeyguard != DISMISS_KEYGUARD_NONE && !mKeyguardDelegate.isSecure()) {
                 if (mKeyguard.hideLw(true)) {
                     changes |= FINISH_LAYOUT_REDO_LAYOUT
                             | FINISH_LAYOUT_REDO_CONFIG
                             | FINISH_LAYOUT_REDO_WALLPAPER;
                 }
-                if (mKeyguardMediator.isShowing()) {
+                if (mKeyguardDelegate.isShowing()) {
                     mHandler.post(new Runnable() {
                         @Override
                         public void run() {
-                            mKeyguardMediator.keyguardDone(false, false);
+                            mKeyguardDelegate.keyguardDone(false, false);
                         }
                     });
                 }
@@ -3380,7 +3479,7 @@
                             | FINISH_LAYOUT_REDO_CONFIG
                             | FINISH_LAYOUT_REDO_WALLPAPER;
                 }
-                mKeyguardMediator.setHidden(true);
+                mKeyguardDelegate.setHidden(true);
             } else if (mDismissKeyguard != DISMISS_KEYGUARD_NONE) {
                 // This is the case of keyguard isSecure() and not mHideLockScreen.
                 if (mDismissKeyguard == DISMISS_KEYGUARD_START) {
@@ -3390,11 +3489,11 @@
                                 | FINISH_LAYOUT_REDO_CONFIG
                                 | FINISH_LAYOUT_REDO_WALLPAPER;
                     }
-                    mKeyguardMediator.setHidden(false);
+                    mKeyguardDelegate.setHidden(false);
                     mHandler.post(new Runnable() {
                         @Override
                         public void run() {
-                            mKeyguardMediator.dismiss();
+                            mKeyguardDelegate.dismiss();
                         }
                     });
                 }
@@ -3405,7 +3504,7 @@
                             | FINISH_LAYOUT_REDO_CONFIG
                             | FINISH_LAYOUT_REDO_WALLPAPER;
                 }
-                mKeyguardMediator.setHidden(false);
+                mKeyguardDelegate.setHidden(false);
             }
         }
 
@@ -3455,11 +3554,7 @@
         updateRotation(true);
 
         if (lidOpen) {
-            if (keyguardIsShowingTq()) {
-                mKeyguardMediator.onWakeKeyWhenKeyguardShowingTq(KeyEvent.KEYCODE_POWER);
-            } else {
-                mPowerManager.wakeUp(SystemClock.uptimeMillis());
-            }
+            mPowerManager.wakeUp(SystemClock.uptimeMillis());
         } else if (!mLidControlsSleep) {
             mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
         }
@@ -3541,7 +3636,8 @@
                 keycode == KeyEvent.KEYCODE_VOLUME_UP
                             ? AudioManager.ADJUST_RAISE
                             : AudioManager.ADJUST_LOWER,
-                    0);
+                    0,
+                    mContext.getOpPackageName());
         } catch (RemoteException e) {
             Log.w(TAG, "IAudioService.adjustStreamVolume() threw RemoteException " + e);
         } finally {
@@ -3636,10 +3732,10 @@
         // the same as if it were open and in front.
         // This will prevent any keys other than the power button from waking the screen
         // when the keyguard is hidden by another activity.
-        final boolean keyguardActive = (mKeyguardMediator == null ? false :
+        final boolean keyguardActive = (mKeyguardDelegate == null ? false :
                                             (isScreenOn ?
-                                                mKeyguardMediator.isShowingAndNotHidden() :
-                                                mKeyguardMediator.isShowing()));
+                                                mKeyguardDelegate.isShowingAndNotHidden() :
+                                                mKeyguardDelegate.isShowing()));
 
         if (keyCode == KeyEvent.KEYCODE_POWER) {
             policyFlags |= WindowManagerPolicy.FLAG_WAKE;
@@ -3676,13 +3772,7 @@
             // to wake the device but don't pass the key to the application.
             result = 0;
             if (down && isWakeKey && isWakeKeyWhenScreenOff(keyCode)) {
-                if (keyguardActive) {
-                    // If the keyguard is showing, let it wake the device when ready.
-                    mKeyguardMediator.onWakeKeyWhenKeyguardShowingTq(keyCode);
-                } else {
-                    // Otherwise, wake the device ourselves.
-                    result |= ACTION_WAKE_UP;
-                }
+                result |= ACTION_WAKE_UP;
             }
         }
 
@@ -3802,6 +3892,9 @@
             case KeyEvent.KEYCODE_POWER: {
                 result &= ~ACTION_PASS_TO_USER;
                 if (down) {
+                    if (isScreenOn && isTransientNavigationAllowed(mLastSystemUiFlags)) {
+                        mTransientNavigationConfirmation.unconfirmLastPackage();
+                    }
                     if (isScreenOn && !mPowerKeyTriggered
                             && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
                         mPowerKeyTriggered = true;
@@ -3865,7 +3958,8 @@
             case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
             case KeyEvent.KEYCODE_MEDIA_REWIND:
             case KeyEvent.KEYCODE_MEDIA_RECORD:
-            case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: {
+            case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
+            case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: {
                 if ((result & ACTION_PASS_TO_USER) == 0) {
                     // Only do this if we would otherwise not pass it to the user. In that
                     // case, the PhoneWindow class will do the same thing, except it will
@@ -3933,6 +4027,7 @@
             case KeyEvent.KEYCODE_MEDIA_REWIND:
             case KeyEvent.KEYCODE_MEDIA_RECORD:
             case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
+            case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK:
             case KeyEvent.KEYCODE_CAMERA:
                 return false;
         }
@@ -3948,13 +4043,7 @@
         final boolean isWakeMotion = (policyFlags
                 & (WindowManagerPolicy.FLAG_WAKE | WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0;
         if (isWakeMotion) {
-            if (mKeyguardMediator != null && mKeyguardMediator.isShowing()) {
-                // If the keyguard is showing, let it decide what to do with the wake motion.
-                mKeyguardMediator.onWakeMotionWhenKeyguardShowingTq();
-            } else {
-                // Otherwise, wake the device ourselves.
-                result |= ACTION_WAKE_UP;
-            }
+            result |= ACTION_WAKE_UP;
         }
         return result;
     }
@@ -4040,12 +4129,12 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             if (Intent.ACTION_DREAMING_STARTED.equals(intent.getAction())) {
-                if (mKeyguardMediator != null) {
-                    mKeyguardMediator.onDreamingStarted();
+                if (mKeyguardDelegate != null) {
+                    mKeyguardDelegate.onDreamingStarted();
                 }
             } else if (Intent.ACTION_DREAMING_STOPPED.equals(intent.getAction())) {
-                if (mKeyguardMediator != null) {
-                    mKeyguardMediator.onDreamingStopped();
+                if (mKeyguardDelegate != null) {
+                    mKeyguardDelegate.onDreamingStopped();
                 }
             }
         }
@@ -4064,7 +4153,7 @@
                 // force a re-application of focused window sysui visibility.
                 // the window may never have been shown for this user
                 // e.g. the keyguard when going through the new-user setup flow
-                synchronized(mLock) {
+                synchronized (mWindowManagerFuncs.getWindowManagerLock()) {
                     mLastSystemUiFlags = 0;
                     updateSystemUiVisibilityLw();
                 }
@@ -4072,6 +4161,23 @@
         }
     };
 
+    private void requestTransientBars(WindowState swipeTarget) {
+        synchronized (mWindowManagerFuncs.getWindowManagerLock()) {
+            boolean sb = mStatusBarController.checkShowTransientBarLw();
+            boolean nb = mNavigationBarController.checkShowTransientBarLw();
+            if (sb || nb) {
+                WindowState barTarget = sb ? mStatusBar : mNavigationBar;
+                if (sb ^ nb && barTarget != swipeTarget) {
+                    if (DEBUG) Slog.d(TAG, "Not showing transient bar, wrong swipe target");
+                    return;
+                }
+                if (sb) mStatusBarController.showTransient();
+                if (nb) mNavigationBarController.showTransient();
+                updateSystemUiVisibilityLw();
+            }
+        }
+    }
+
     @Override
     public void screenTurnedOff(int why) {
         EventLog.writeEvent(70000, 0);
@@ -4079,8 +4185,8 @@
             mScreenOnEarly = false;
             mScreenOnFully = false;
         }
-        if (mKeyguardMediator != null) {
-            mKeyguardMediator.onScreenTurnedOff(why);
+        if (mKeyguardDelegate != null) {
+            mKeyguardDelegate.onScreenTurnedOff(why);
         }
         synchronized (mLock) {
             updateOrientationListenerLp();
@@ -4107,9 +4213,9 @@
     }
 
     private void waitForKeyguard(final ScreenOnListener screenOnListener) {
-        if (mKeyguardMediator != null) {
+        if (mKeyguardDelegate != null) {
             if (screenOnListener != null) {
-                mKeyguardMediator.onScreenTurnedOn(new KeyguardViewManager.ShowListener() {
+                mKeyguardDelegate.onScreenTurnedOn(new KeyguardServiceDelegate.ShowListener() {
                     @Override
                     public void onShown(IBinder windowToken) {
                         waitForKeyguardWindowDrawn(windowToken, screenOnListener);
@@ -4117,10 +4223,10 @@
                 });
                 return;
             } else {
-                mKeyguardMediator.onScreenTurnedOn(null);
+                mKeyguardDelegate.onScreenTurnedOn(null);
             }
         } else {
-            Slog.i(TAG, "No keyguard mediator!");
+            Slog.i(TAG, "No keyguard interface!");
         }
         finishScreenTurningOn(screenOnListener);
     }
@@ -4175,21 +4281,21 @@
 
     /** {@inheritDoc} */
     public void enableKeyguard(boolean enabled) {
-        if (mKeyguardMediator != null) {
-            mKeyguardMediator.setKeyguardEnabled(enabled);
+        if (mKeyguardDelegate != null) {
+            mKeyguardDelegate.setKeyguardEnabled(enabled);
         }
     }
 
     /** {@inheritDoc} */
     public void exitKeyguardSecurely(OnKeyguardExitResult callback) {
-        if (mKeyguardMediator != null) {
-            mKeyguardMediator.verifyUnlock(callback);
+        if (mKeyguardDelegate != null) {
+            mKeyguardDelegate.verifyUnlock(callback);
         }
     }
 
     private boolean keyguardIsShowingTq() {
-        if (mKeyguardMediator == null) return false;
-        return mKeyguardMediator.isShowingAndNotHidden();
+        if (mKeyguardDelegate == null) return false;
+        return mKeyguardDelegate.isShowingAndNotHidden();
     }
 
 
@@ -4200,26 +4306,26 @@
 
     /** {@inheritDoc} */
     public boolean isKeyguardSecure() {
-        if (mKeyguardMediator == null) return false;
-        return mKeyguardMediator.isSecure();
+        if (mKeyguardDelegate == null) return false;
+        return mKeyguardDelegate.isSecure();
     }
 
     /** {@inheritDoc} */
     public boolean inKeyguardRestrictedKeyInputMode() {
-        if (mKeyguardMediator == null) return false;
-        return mKeyguardMediator.isInputRestricted();
+        if (mKeyguardDelegate == null) return false;
+        return mKeyguardDelegate.isInputRestricted();
     }
 
     public void dismissKeyguardLw() {
-        if (mKeyguardMediator.isShowing()) {
+        if (mKeyguardDelegate != null && mKeyguardDelegate.isShowing()) { 
             mHandler.post(new Runnable() {
                 public void run() {
-                    if (mKeyguardMediator.isDismissable()) {
+                    if (mKeyguardDelegate.isDismissable()) {
                         // Can we just finish the keyguard straight away?
-                        mKeyguardMediator.keyguardDone(false, true);
+                        mKeyguardDelegate.keyguardDone(false, true);
                     } else {
                         // ask the keyguard to prompt the user to authenticate if necessary
-                        mKeyguardMediator.dismiss();
+                        mKeyguardDelegate.dismiss();
                     }
                 }
             });
@@ -4254,6 +4360,10 @@
                         );
         }
 
+        if (mForceDefaultOrientation) {
+            return Surface.ROTATION_0;
+        }
+
         synchronized (mLock) {
             int sensorRotation = mOrientationListener.getProposedRotation(); // may be -1
             if (sensorRotation < 0) {
@@ -4462,7 +4572,7 @@
                 ? HapticFeedbackConstants.SAFE_MODE_ENABLED
                 : HapticFeedbackConstants.SAFE_MODE_DISABLED, true);
     }
-    
+
     static long[] getLongIntArray(Resources r, int resid) {
         int[] ar = r.getIntArray(resid);
         if (ar == null) {
@@ -4474,17 +4584,19 @@
         }
         return out;
     }
-    
+
     /** {@inheritDoc} */
+    @Override
     public void systemReady() {
-        if (mKeyguardMediator != null) {
-            // tell the keyguard
-            mKeyguardMediator.onSystemReady();
+        if (!mHeadless) {
+            mKeyguardDelegate = new KeyguardServiceDelegate(mContext, null);
+            mKeyguardDelegate.onSystemReady();
         }
         synchronized (mLock) {
             updateOrientationListenerLp();
             mSystemReady = true;
             mHandler.post(new Runnable() {
+                @Override
                 public void run() {
                     updateSettings();
                 }
@@ -4591,8 +4703,8 @@
         public void run() {
             synchronized (this) {
                 if (localLOGV) Log.v(TAG, "mScreenLockTimeout activating keyguard");
-                if (mKeyguardMediator != null) {
-                    mKeyguardMediator.doKeyguardTimeout(options);
+                if (mKeyguardDelegate != null) {
+                    mKeyguardDelegate.doKeyguardTimeout(options);
                 }
                 mLockScreenTimerActive = false;
                 options = null;
@@ -4620,7 +4732,7 @@
     private void updateLockScreenTimeout() {
         synchronized (mScreenLockTimeout) {
             boolean enable = (mAllowLockscreenWhenOn && mScreenOnEarly &&
-                    mKeyguardMediator != null && mKeyguardMediator.isSecure());
+                    mKeyguardDelegate != null && mKeyguardDelegate.isSecure());
             if (mLockScreenTimerActive != enable) {
                 if (enable) {
                     if (localLOGV) Log.v(TAG, "setting lockscreen timer");
@@ -4635,6 +4747,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public void enableScreenAfterBoot() {
         readLidState();
         applyLidSwitchState();
@@ -4676,7 +4789,7 @@
      *  <li>The device is in car mode but there's no CAR_DOCK app with METADATA_DOCK_HOME
      *  <li>The device is in desk mode but there's no DESK_DOCK app with METADATA_DOCK_HOME
      * </ul>
-     * @return
+     * @return A dock intent.
      */
     Intent createHomeDockIntent() {
         Intent intent = null;
@@ -4701,8 +4814,8 @@
         ActivityInfo ai = null;
         ResolveInfo info = mContext.getPackageManager().resolveActivityAsUser(
                 intent,
-                PackageManager.MATCH_DEFAULT_ONLY,
-                UserHandle.USER_CURRENT);
+                PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA,
+                mCurrentUserId);
         if (info != null) {
             ai = info.activityInfo;
         }
@@ -4731,7 +4844,7 @@
 
         mContext.startActivityAsUser(mHomeIntent, UserHandle.CURRENT);
     }
-    
+
     /**
      * goes to the home screen
      * @return whether it did anything
@@ -4783,7 +4896,8 @@
         }
         return true;
     }
-    
+
+    @Override
     public void setCurrentOrientationLw(int newOrientation) {
         synchronized (mLock) {
             if (newOrientation != mCurrentAppOrientation) {
@@ -4807,18 +4921,20 @@
         ringTone.setStreamType(AudioManager.STREAM_MUSIC);
         ringTone.play();
     }
+
     private boolean isGlobalAccessibilityGestureEnabled() {
         return Settings.Global.getInt(mContext.getContentResolver(),
                 Settings.Global.ENABLE_ACCESSIBILITY_GLOBAL_GESTURE_ENABLED, 0) == 1;
     }
 
+    @Override
     public boolean performHapticFeedbackLw(WindowState win, int effectId, boolean always) {
         if (!mVibrator.hasVibrator()) {
             return false;
         }
         final boolean hapticsDisabled = Settings.System.getIntForUser(mContext.getContentResolver(),
                 Settings.System.HAPTIC_FEEDBACK_ENABLED, 0, UserHandle.USER_CURRENT) == 0;
-        if (!always && (hapticsDisabled || mKeyguardMediator.isShowingAndNotHidden())) {
+        if (!always && (hapticsDisabled || mKeyguardDelegate.isShowingAndNotHidden())) {
             return false;
         }
         long[] pattern = null;
@@ -4848,7 +4964,7 @@
             owningPackage = win.getOwningPackage();
         } else {
             owningUid = android.os.Process.myUid();
-            owningPackage = mContext.getBasePackageName();
+            owningPackage = mContext.getOpPackageName();
         }
         if (pattern.length == 1) {
             // One-shot vibration
@@ -4866,9 +4982,9 @@
 
     @Override
     public void keepScreenOnStoppedLw() {
-        if (mKeyguardMediator != null && !mKeyguardMediator.isShowingAndNotHidden()) {
+        if (mKeyguardDelegate != null && !mKeyguardDelegate.isShowingAndNotHidden()) {
             long curTime = SystemClock.uptimeMillis();
-            mPowerManager.userActivity(curTime, false);
+            mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
         }
     }
 
@@ -4887,14 +5003,15 @@
             // will quickly lose focus once it correctly gets hidden.
             return 0;
         }
+
         int tmpVisibility = mFocusedWindow.getSystemUiVisibility()
                 & ~mResettingSystemUiFlags
                 & ~mForceClearedSystemUiFlags;
         if (mForcingShowNavBar && mFocusedWindow.getSurfaceLayer() < mForcingShowNavBarLayer) {
             tmpVisibility &= ~View.SYSTEM_UI_CLEARABLE_FLAGS;
         }
-        final int visibility = tmpVisibility;
-        int diff = visibility ^ mLastSystemUiFlags;
+        final int visibility = updateSystemBarsLw(mLastSystemUiFlags, tmpVisibility);
+        final int diff = visibility ^ mLastSystemUiFlags;
         final boolean needsMenu = mFocusedWindow.getNeedsMenuLw(mTopFullscreenOpaqueWindowState);
         if (diff == 0 && mLastFocusNeedsMenu == needsMenu
                 && mFocusedApp == mFocusedWindow.getAppToken()) {
@@ -4904,6 +5021,7 @@
         mLastFocusNeedsMenu = needsMenu;
         mFocusedApp = mFocusedWindow.getAppToken();
         mHandler.post(new Runnable() {
+                @Override
                 public void run() {
                     try {
                         IStatusBarService statusbar = getStatusBarService();
@@ -4920,8 +5038,122 @@
         return diff;
     }
 
+    private int updateSystemBarsLw(int oldVis, int vis) {
+        if (ImmersiveModeTesting.enabled) {
+            vis = ImmersiveModeTesting.applyForced(mFocusedWindow, vis);
+        }
+
+        // prevent status bar interaction from clearing certain flags
+        boolean statusBarHasFocus = mFocusedWindow.getAttrs().type == TYPE_STATUS_BAR;
+        if (statusBarHasFocus) {
+            int flags = View.SYSTEM_UI_FLAG_FULLSCREEN
+                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+                    | View.SYSTEM_UI_FLAG_IMMERSIVE
+                    | View.SYSTEM_UI_FLAG_TRANSPARENT_STATUS
+                    | View.SYSTEM_UI_FLAG_TRANSPARENT_NAVIGATION;
+            vis = (vis & ~flags) | (mLastSystemUiFlags & flags);
+        }
+
+        // update status bar
+        boolean transientAllowed =
+                (vis & View.SYSTEM_UI_FLAG_IMMERSIVE) != 0;
+        boolean hideStatusBarWM =
+                (mFocusedWindow.getAttrs().flags
+                        & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0;
+        boolean hideStatusBarSysui =
+                (vis & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0;
+
+        boolean transientStatusBarAllowed =
+                mStatusBar != null && (
+                hideStatusBarWM
+                || (hideStatusBarSysui && transientAllowed)
+                || statusBarHasFocus);
+
+        if (mStatusBarController.isTransientShowing()
+                && !transientStatusBarAllowed && hideStatusBarSysui) {
+            // clear the clearable flags instead
+            int newVal = mResettingSystemUiFlags | View.SYSTEM_UI_CLEARABLE_FLAGS;
+            if (newVal != mResettingSystemUiFlags) {
+                mResettingSystemUiFlags = newVal;
+                mWindowManagerFuncs.reevaluateStatusBarVisibility();
+            }
+        }
+
+        vis = mStatusBarController.updateVisibilityLw(transientStatusBarAllowed, oldVis, vis);
+
+        // update navigation bar
+        boolean oldTransientNav = isTransientNavigationAllowed(oldVis);
+        boolean isTransientNav = isTransientNavigationAllowed(vis);
+        if (mFocusedWindow != null && oldTransientNav != isTransientNav) {
+            final String pkg = mFocusedWindow.getOwningPackage();
+            mTransientNavigationConfirmation.transientNavigationChanged(mCurrentUserId, pkg,
+                    isTransientNav);
+        }
+        vis = mNavigationBarController.updateVisibilityLw(isTransientNav, oldVis, vis);
+
+        // don't send low profile updates if the system bars are hidden
+        if (mStatusBarController.isHidden() && mNavigationBarController.isHidden()) {
+            vis &= ~View.SYSTEM_UI_FLAG_LOW_PROFILE;
+        }
+        return vis;
+    }
+
+    private boolean isTransientNavigationAllowed(int vis) {
+        return mNavigationBar != null
+                && (vis & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0
+                && (vis & View.SYSTEM_UI_FLAG_IMMERSIVE) != 0;
+    }
+
+    // Temporary helper that allows testing immersive mode on existing apps
+    // TODO remove
+    private static final class ImmersiveModeTesting {
+        static String ENABLED_SETTING = "immersive_mode_testing_enabled";
+        static boolean enabled = false;
+        private static final HashSet<String> sForced = new HashSet<String>();
+
+        private static String parseActivity(WindowState win) {
+            if (win != null && win.getAppToken() != null) {
+                String str = win.getAppToken().toString();
+                int end = str.lastIndexOf(' ');
+                if (end > 0) {
+                    int start = str.lastIndexOf(' ', end - 1);
+                    if (start > -1) {
+                        return str.substring(start + 1, end);
+                    }
+                }
+            }
+            return null;
+        }
+
+        public static int applyForced(WindowState focused, int vis) {
+            if (sForced.contains(parseActivity(focused))) {
+                vis |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
+                       View.SYSTEM_UI_FLAG_FULLSCREEN |
+                       View.SYSTEM_UI_FLAG_IMMERSIVE;
+            }
+            return vis;
+        }
+
+        public static void toggleForceImmersiveMode(WindowState focused, Context context) {
+            String activity = parseActivity(focused);
+            if (activity != null) {
+                String action;
+                if (sForced.contains(activity)) {
+                    sForced.remove(activity);
+                    action = "Force immersive mode disabled";
+                } else {
+                    sForced.add(activity);
+                    action = "Force immersive mode enabled";
+                }
+                android.widget.Toast.makeText(context,
+                        action + " for " + activity, android.widget.Toast.LENGTH_SHORT).show();
+            }
+        }
+    }
+
     // Use this instead of checking config_showNavigationBar so that it can be consistently
     // overridden by qemu.hw.mainkeys in the emulator.
+    @Override
     public boolean hasNavigationBar() {
         return mHasNavigationBar;
     }
@@ -4934,8 +5166,9 @@
 
     @Override
     public void setCurrentUserLw(int newUserId) {
-        if (mKeyguardMediator != null) {
-            mKeyguardMediator.setCurrentUser(newUserId);
+        mCurrentUserId = newUserId;
+        if (mKeyguardDelegate != null) {
+            mKeyguardDelegate.setCurrentUser(newUserId);
         }
         if (mStatusBarService != null) {
             try {
@@ -4949,7 +5182,7 @@
 
     @Override
     public void showAssistant() {
-        mKeyguardMediator.showAssistant();
+        mKeyguardDelegate.showAssistant();
     }
 
     @Override
@@ -5132,5 +5365,7 @@
         pw.print(prefix); pw.print("mDemoHdmiRotation="); pw.print(mDemoHdmiRotation);
                 pw.print(" mDemoHdmiRotationLock="); pw.println(mDemoHdmiRotationLock);
         pw.print(prefix); pw.print("mUndockedHdmiRotation="); pw.println(mUndockedHdmiRotation);
+        mStatusBarController.dump(pw, prefix);
+        mNavigationBarController.dump(pw, prefix);
     }
 }
diff --git a/policy/src/com/android/internal/policy/impl/SystemGesturesPointerEventListener.java b/policy/src/com/android/internal/policy/impl/SystemGesturesPointerEventListener.java
new file mode 100644
index 0000000..4ff9315
--- /dev/null
+++ b/policy/src/com/android/internal/policy/impl/SystemGesturesPointerEventListener.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.policy.impl;
+
+import android.content.Context;
+import android.util.Slog;
+import android.view.MotionEvent;
+import android.view.WindowManagerPolicy.PointerEventListener;
+
+/*
+ * Listens for system-wide input gestures, firing callbacks when detected.
+ * @hide
+ */
+public class SystemGesturesPointerEventListener implements PointerEventListener {
+    private static final String TAG = "SystemGestures";
+    private static final boolean DEBUG = false;
+    private static final long SWIPE_TIMEOUT_MS = 500;
+    private static final int MAX_TRACKED_POINTERS = 32;  // max per input system
+    private static final int UNTRACKED_POINTER = -1;
+
+    private static final int SWIPE_NONE = 0;
+    private static final int SWIPE_FROM_TOP = 1;
+    private static final int SWIPE_FROM_BOTTOM = 2;
+    private static final int SWIPE_FROM_RIGHT = 3;
+
+    private final int mSwipeStartThreshold;
+    private final int mSwipeDistanceThreshold;
+    private final Callbacks mCallbacks;
+    private final int[] mDownPointerId = new int[MAX_TRACKED_POINTERS];
+    private final float[] mDownX = new float[MAX_TRACKED_POINTERS];
+    private final float[] mDownY = new float[MAX_TRACKED_POINTERS];
+    private final long[] mDownTime = new long[MAX_TRACKED_POINTERS];
+
+    int screenHeight;
+    int screenWidth;
+    private int mDownPointers;
+    private boolean mSwipeFireable;
+    private boolean mDebugFireable;
+
+    public SystemGesturesPointerEventListener(Context context, Callbacks callbacks) {
+        mCallbacks = checkNull("callbacks", callbacks);
+        mSwipeStartThreshold = checkNull("context", context).getResources()
+                .getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
+        mSwipeDistanceThreshold = mSwipeStartThreshold;
+        if (DEBUG) Slog.d(TAG,  "mSwipeStartThreshold=" + mSwipeStartThreshold
+                + " mSwipeDistanceThreshold=" + mSwipeDistanceThreshold);
+    }
+
+    private static <T> T checkNull(String name, T arg) {
+        if (arg == null) {
+            throw new IllegalArgumentException(name + " must not be null");
+        }
+        return arg;
+    }
+
+    @Override
+    public void onPointerEvent(MotionEvent event) {
+        switch (event.getActionMasked()) {
+            case MotionEvent.ACTION_DOWN:
+                mSwipeFireable = true;
+                mDebugFireable = true;
+                mDownPointers = 0;
+                captureDown(event, 0);
+                break;
+            case MotionEvent.ACTION_POINTER_DOWN:
+                captureDown(event, event.getActionIndex());
+                if (mDebugFireable) {
+                    mDebugFireable = event.getPointerCount() < 5;
+                    if (!mDebugFireable) {
+                        if (DEBUG) Slog.d(TAG, "Firing debug");
+                        mCallbacks.onDebug();
+                    }
+                }
+                break;
+            case MotionEvent.ACTION_MOVE:
+                if (mSwipeFireable) {
+                    final int swipe = detectSwipe(event);
+                    mSwipeFireable = swipe == SWIPE_NONE;
+                    if (swipe == SWIPE_FROM_TOP) {
+                        if (DEBUG) Slog.d(TAG, "Firing onSwipeFromTop");
+                        mCallbacks.onSwipeFromTop();
+                    } else if (swipe == SWIPE_FROM_BOTTOM) {
+                        if (DEBUG) Slog.d(TAG, "Firing onSwipeFromBottom");
+                        mCallbacks.onSwipeFromBottom();
+                    } else if (swipe == SWIPE_FROM_RIGHT) {
+                        if (DEBUG) Slog.d(TAG, "Firing onSwipeFromRight");
+                        mCallbacks.onSwipeFromRight();
+                    }
+                }
+                break;
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_CANCEL:
+                mSwipeFireable = false;
+                mDebugFireable = false;
+                break;
+            default:
+                if (DEBUG) Slog.d(TAG, "Ignoring " + event);
+        }
+    }
+
+    private void captureDown(MotionEvent event, int pointerIndex) {
+        final int pointerId = event.getPointerId(pointerIndex);
+        final int i = findIndex(pointerId);
+        if (DEBUG) Slog.d(TAG, "pointer " + pointerId +
+                " down pointerIndex=" + pointerIndex + " trackingIndex=" + i);
+        if (i != UNTRACKED_POINTER) {
+            mDownX[i] = event.getX(pointerIndex);
+            mDownY[i] = event.getY(pointerIndex);
+            mDownTime[i] = event.getEventTime();
+            if (DEBUG) Slog.d(TAG, "pointer " + pointerId +
+                    " down x=" + mDownX[i] + " y=" + mDownY[i]);
+        }
+    }
+
+    private int findIndex(int pointerId) {
+        for (int i = 0; i < mDownPointers; i++) {
+            if (mDownPointerId[i] == pointerId) {
+                return i;
+            }
+        }
+        if (mDownPointers == MAX_TRACKED_POINTERS || pointerId == MotionEvent.INVALID_POINTER_ID) {
+            return UNTRACKED_POINTER;
+        }
+        mDownPointerId[mDownPointers++] = pointerId;
+        return mDownPointers - 1;
+    }
+
+    private int detectSwipe(MotionEvent move) {
+        final int historySize = move.getHistorySize();
+        final int pointerCount = move.getPointerCount();
+        for (int p = 0; p < pointerCount; p++) {
+            final int pointerId = move.getPointerId(p);
+            final int i = findIndex(pointerId);
+            if (i != UNTRACKED_POINTER) {
+                for (int h = 0; h < historySize; h++) {
+                    final long time = move.getHistoricalEventTime(h);
+                    final float x = move.getHistoricalX(p, h);
+                    final float y = move.getHistoricalY(p,  h);
+                    final int swipe = detectSwipe(i, time, x, y);
+                    if (swipe != SWIPE_NONE) {
+                        return swipe;
+                    }
+                }
+                final int swipe = detectSwipe(i, move.getEventTime(), move.getX(p), move.getY(p));
+                if (swipe != SWIPE_NONE) {
+                    return swipe;
+                }
+            }
+        }
+        return SWIPE_NONE;
+    }
+
+    private int detectSwipe(int i, long time, float x, float y) {
+        final float fromX = mDownX[i];
+        final float fromY = mDownY[i];
+        final long elapsed = time - mDownTime[i];
+        if (DEBUG) Slog.d(TAG, "pointer " + mDownPointerId[i]
+                + " moved (" + fromX + "->" + x + "," + fromY + "->" + y + ") in " + elapsed);
+        if (fromY <= mSwipeStartThreshold
+                && y > fromY + mSwipeDistanceThreshold
+                && elapsed < SWIPE_TIMEOUT_MS) {
+            return SWIPE_FROM_TOP;
+        }
+        if (fromY >= screenHeight - mSwipeStartThreshold
+                && y < fromY - mSwipeDistanceThreshold
+                && elapsed < SWIPE_TIMEOUT_MS) {
+            return SWIPE_FROM_BOTTOM;
+        }
+        if (fromX >= screenWidth - mSwipeStartThreshold
+                && x < fromX - mSwipeDistanceThreshold
+                && elapsed < SWIPE_TIMEOUT_MS) {
+            return SWIPE_FROM_RIGHT;
+        }
+        return SWIPE_NONE;
+    }
+
+    interface Callbacks {
+        void onSwipeFromTop();
+        void onSwipeFromBottom();
+        void onSwipeFromRight();
+        void onDebug();
+    }
+}
diff --git a/policy/src/com/android/internal/policy/impl/TransientNavigationConfirmation.java b/policy/src/com/android/internal/policy/impl/TransientNavigationConfirmation.java
new file mode 100644
index 0000000..3c4f092
--- /dev/null
+++ b/policy/src/com/android/internal/policy/impl/TransientNavigationConfirmation.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.policy.impl;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.Message;
+import android.util.ArraySet;
+import android.util.Slog;
+import android.view.View;
+import android.view.animation.Animation;
+import android.view.animation.AnimationSet;
+import android.view.animation.AnimationUtils;
+import android.widget.Toast;
+
+import com.android.internal.R;
+
+/**
+ *  Helper to manage showing/hiding a confirmation prompt when the transient navigation bar
+ *  is hidden.
+ */
+public class TransientNavigationConfirmation {
+    private static final String TAG = "TransientNavigationConfirmation";
+    private static final boolean DEBUG = false;
+
+    private final Context mContext;
+    private final H mHandler;
+    private final ArraySet<String> mConfirmedUserPackages = new ArraySet<String>();
+    private final long mShowDelayMs;
+
+    private Toast mToast;
+    private String mLastUserPackage;
+
+    public TransientNavigationConfirmation(Context context) {
+        mContext = context;
+        mHandler = new H();
+        mShowDelayMs = getNavBarExitDuration() * 3;
+    }
+
+    private long getNavBarExitDuration() {
+        Animation exit = AnimationUtils.loadAnimation(mContext, R.anim.dock_bottom_exit);
+        return exit != null ? exit.getDuration() : 0;
+    }
+
+    public void transientNavigationChanged(int userId, String pkg, boolean isNavTransient) {
+        if (pkg == null) {
+            return;
+        }
+        String userPkg = userId + ":" + pkg;
+        mHandler.removeMessages(H.SHOW);
+        if (isNavTransient) {
+            mLastUserPackage = userPkg;
+            if (!mConfirmedUserPackages.contains(userPkg)) {
+                if (DEBUG) Slog.d(TAG, "Showing transient navigation confirmation for " + userPkg);
+                mHandler.sendMessageDelayed(mHandler.obtainMessage(H.SHOW, userPkg), mShowDelayMs);
+            }
+        } else {
+            mLastUserPackage = null;
+            if (DEBUG) Slog.d(TAG, "Hiding transient navigation confirmation for " + userPkg);
+            mHandler.sendEmptyMessage(H.HIDE);
+        }
+    }
+
+    public void unconfirmLastPackage() {
+        if (mLastUserPackage != null) {
+            if (DEBUG) Slog.d(TAG, "Unconfirming transient navigation for " + mLastUserPackage);
+            mConfirmedUserPackages.remove(mLastUserPackage);
+        }
+    }
+
+    private void handleHide() {
+        if (mToast != null) {
+            mToast.cancel();
+            mToast = null;
+        }
+    }
+
+    private void handleShow(String userPkg) {
+        // create the confirmation toast bar
+        final int msg = R.string.transient_navigation_confirmation;
+        mToast = Toast.makeBar(mContext, msg, Toast.LENGTH_INFINITE);
+        mToast.setAction(R.string.ok, confirmAction(userPkg));
+
+        // we will be hiding the nav bar, so layout as if it's already hidden
+        mToast.getView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
+
+        // show the confirmation
+        mToast.show();
+    }
+
+    private Runnable confirmAction(final String userPkg) {
+        return new Runnable() {
+            @Override
+            public void run() {
+                mConfirmedUserPackages.add(userPkg);
+                handleHide();
+            }
+        };
+    }
+
+    private final class H extends Handler {
+        private static final int SHOW = 0;
+        private static final int HIDE = 1;
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch(msg.what) {
+                case SHOW:
+                    handleShow((String)msg.obj);
+                    break;
+                case HIDE:
+                    handleHide();
+                    break;
+            }
+        }
+    }
+}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/BiometricSensorUnlock.java b/policy/src/com/android/internal/policy/impl/keyguard/BiometricSensorUnlock.java
deleted file mode 100644
index e65a716f..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/BiometricSensorUnlock.java
+++ /dev/null
@@ -1,68 +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.internal.policy.impl.keyguard;
-
-import android.view.View;
-
-interface BiometricSensorUnlock {
-    /**
-     * Initializes the view provided for the biometric unlock UI to work within.  The provided area
-     * completely covers the backup unlock mechanism.
-     * @param biometricUnlockView View provided for the biometric unlock UI.
-     */
-    public void initializeView(View biometricUnlockView);
-
-    /**
-     * Indicates whether the biometric unlock is running.  Before
-     * {@link BiometricSensorUnlock#start} is called, isRunning() returns false.  After a successful
-     * call to {@link BiometricSensorUnlock#start}, isRunning() returns true until the biometric
-     * unlock completes, {@link BiometricSensorUnlock#stop} has been called, or an error has
-     * forced the biometric unlock to stop.
-     * @return whether the biometric unlock is currently running.
-     */
-    public boolean isRunning();
-
-    /**
-     * Stops and removes the biometric unlock and shows the backup unlock
-     */
-    public void stopAndShowBackup();
-
-    /**
-     * Binds to the biometric unlock service and starts the unlock procedure.  Called on the UI
-     * thread.
-     * @return false if it can't be started or the backup should be used.
-     */
-    public boolean start();
-
-    /**
-     * Stops the biometric unlock procedure and unbinds from the service.  Called on the UI thread.
-     * @return whether the biometric unlock was running when called.
-     */
-    public boolean stop();
-
-    /**
-     * Cleans up any resources used by the biometric unlock.
-     */
-    public void cleanUp();
-
-    /**
-     * Gets the Device Policy Manager quality of the biometric unlock sensor
-     * (e.g., PASSWORD_QUALITY_BIOMETRIC_WEAK).
-     * @return biometric unlock sensor quality, as defined by Device Policy Manager.
-     */
-    public int getQuality();
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java b/policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java
deleted file mode 100644
index 762711d..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java
+++ /dev/null
@@ -1,458 +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.internal.policy.impl.keyguard;
-
-import android.content.Context;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.graphics.Color;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.os.Handler;
-import android.os.SystemClock;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.ImageView.ScaleType;
-
-import com.android.internal.R;
-import com.android.internal.policy.impl.keyguard.KeyguardActivityLauncher.CameraWidgetInfo;
-
-public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnClickListener {
-    private static final String TAG = CameraWidgetFrame.class.getSimpleName();
-    private static final boolean DEBUG = KeyguardHostView.DEBUG;
-    private static final int WIDGET_ANIMATION_DURATION = 250; // ms
-    private static final int WIDGET_WAIT_DURATION = 650; // ms
-    private static final int RECOVERY_DELAY = 1000; // ms
-
-    interface Callbacks {
-        void onLaunchingCamera();
-        void onCameraLaunchedSuccessfully();
-        void onCameraLaunchedUnsuccessfully();
-    }
-
-    private final Handler mHandler = new Handler();
-    private final KeyguardActivityLauncher mActivityLauncher;
-    private final Callbacks mCallbacks;
-    private final CameraWidgetInfo mWidgetInfo;
-    private final WindowManager mWindowManager;
-    private final Point mRenderedSize = new Point();
-    private final int[] mTmpLoc = new int[2];
-    private final Rect mTmpRect = new Rect();
-
-    private long mLaunchCameraStart;
-    private boolean mActive;
-    private boolean mTransitioning;
-    private boolean mDown;
-
-    private FixedSizeFrameLayout mPreview;
-    private View mFullscreenPreview;
-
-    private final Runnable mTransitionToCameraRunnable = new Runnable() {
-        @Override
-        public void run() {
-            transitionToCamera();
-        }};
-
-    private final Runnable mTransitionToCameraEndAction = new Runnable() {
-        @Override
-        public void run() {
-            if (!mTransitioning)
-                return;
-            Handler worker =  getWorkerHandler() != null ? getWorkerHandler() : mHandler;
-            mLaunchCameraStart = SystemClock.uptimeMillis();
-            if (DEBUG) Log.d(TAG, "Launching camera at " + mLaunchCameraStart);
-            mActivityLauncher.launchCamera(worker, mSecureCameraActivityStartedRunnable);
-        }};
-
-    private final Runnable mPostTransitionToCameraEndAction = new Runnable() {
-        @Override
-        public void run() {
-            mHandler.post(mTransitionToCameraEndAction);
-        }};
-
-    private final Runnable mRecoverRunnable = new Runnable() {
-        @Override
-        public void run() {
-            recover();
-        }};
-
-    private final Runnable mRenderRunnable = new Runnable() {
-        @Override
-        public void run() {
-            render();
-        }};
-
-    private final Runnable mSecureCameraActivityStartedRunnable = new Runnable() {
-        @Override
-        public void run() {
-            onSecureCameraActivityStarted();
-        }
-    };
-
-    private final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() {
-        private boolean mShowing;
-        void onKeyguardVisibilityChanged(boolean showing) {
-            if (mShowing == showing)
-                return;
-            mShowing = showing;
-            CameraWidgetFrame.this.onKeyguardVisibilityChanged(mShowing);
-        };
-    };
-
-    private static final class FixedSizeFrameLayout extends FrameLayout {
-        int width;
-        int height;
-
-        FixedSizeFrameLayout(Context context) {
-            super(context);
-        }
-
-        @Override
-        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-            measureChildren(
-                    MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
-                    MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
-            setMeasuredDimension(width, height);
-        }
-    }
-
-    private CameraWidgetFrame(Context context, Callbacks callbacks,
-            KeyguardActivityLauncher activityLauncher,
-            CameraWidgetInfo widgetInfo, View previewWidget) {
-        super(context);
-        mCallbacks = callbacks;
-        mActivityLauncher = activityLauncher;
-        mWidgetInfo = widgetInfo;
-        mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
-        KeyguardUpdateMonitor.getInstance(context).registerCallback(mCallback);
-
-        mPreview = new FixedSizeFrameLayout(context);
-        mPreview.addView(previewWidget);
-        addView(mPreview);
-
-        View clickBlocker = new View(context);
-        clickBlocker.setBackgroundColor(Color.TRANSPARENT);
-        clickBlocker.setOnClickListener(this);
-        addView(clickBlocker);
-
-        setContentDescription(context.getString(R.string.keyguard_accessibility_camera));
-        if (DEBUG) Log.d(TAG, "new CameraWidgetFrame instance " + instanceId());
-    }
-
-    public static CameraWidgetFrame create(Context context, Callbacks callbacks,
-            KeyguardActivityLauncher launcher) {
-        if (context == null || callbacks == null || launcher == null)
-            return null;
-
-        CameraWidgetInfo widgetInfo = launcher.getCameraWidgetInfo();
-        if (widgetInfo == null)
-            return null;
-        View previewWidget = getPreviewWidget(context, widgetInfo);
-        if (previewWidget == null)
-            return null;
-
-        return new CameraWidgetFrame(context, callbacks, launcher, widgetInfo, previewWidget);
-    }
-
-    private static View getPreviewWidget(Context context, CameraWidgetInfo widgetInfo) {
-        return widgetInfo.layoutId > 0 ?
-                inflateWidgetView(context, widgetInfo) :
-                inflateGenericWidgetView(context);
-    }
-
-    private static View inflateWidgetView(Context context, CameraWidgetInfo widgetInfo) {
-        if (DEBUG) Log.d(TAG, "inflateWidgetView: " + widgetInfo.contextPackage);
-        View widgetView = null;
-        Exception exception = null;
-        try {
-            Context cameraContext = context.createPackageContext(
-                    widgetInfo.contextPackage, Context.CONTEXT_RESTRICTED);
-            LayoutInflater cameraInflater = (LayoutInflater)
-                    cameraContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-            cameraInflater = cameraInflater.cloneInContext(cameraContext);
-            widgetView = cameraInflater.inflate(widgetInfo.layoutId, null, false);
-        } catch (NameNotFoundException e) {
-            exception = e;
-        } catch (RuntimeException e) {
-            exception = e;
-        }
-        if (exception != null) {
-            Log.w(TAG, "Error creating camera widget view", exception);
-        }
-        return widgetView;
-    }
-
-    private static View inflateGenericWidgetView(Context context) {
-        if (DEBUG) Log.d(TAG, "inflateGenericWidgetView");
-        ImageView iv = new ImageView(context);
-        iv.setImageResource(com.android.internal.R.drawable.ic_lockscreen_camera);
-        iv.setScaleType(ScaleType.CENTER);
-        iv.setBackgroundColor(Color.argb(127, 0, 0, 0));
-        return iv;
-    }
-
-    private void render() {
-        final View root = getRootView();
-        final int width = root.getWidth();
-        final int height = root.getHeight();
-        if (mRenderedSize.x == width && mRenderedSize.y == height) {
-            if (DEBUG) Log.d(TAG, String.format("Already rendered at size=%sx%s", width, height));
-            return;
-        }
-        if (width == 0 || height == 0) {
-            return;
-        }
-
-        mPreview.width = width;
-        mPreview.height = height;
-        mPreview.requestLayout();
-
-        final int thisWidth = getWidth() - getPaddingLeft() - getPaddingRight();
-        final int thisHeight = getHeight() - getPaddingTop() - getPaddingBottom();
-
-        final float pvScaleX = (float) thisWidth / width;
-        final float pvScaleY = (float) thisHeight / height;
-        final float pvScale = Math.min(pvScaleX, pvScaleY);
-
-        final int pvWidth = (int) (pvScale * width);
-        final int pvHeight = (int) (pvScale * height);
-
-        final float pvTransX = pvWidth < thisWidth ? (thisWidth - pvWidth) / 2 : 0;
-        final float pvTransY = pvHeight < thisHeight ? (thisHeight - pvHeight) / 2 : 0;
-
-        mPreview.setPivotX(0);
-        mPreview.setPivotY(0);
-        mPreview.setScaleX(pvScale);
-        mPreview.setScaleY(pvScale);
-        mPreview.setTranslationX(pvTransX);
-        mPreview.setTranslationY(pvTransY);
-
-        mRenderedSize.set(width, height);
-        if (DEBUG) Log.d(TAG, String.format("Rendered camera widget size=%sx%s instance=%s",
-                width, height, instanceId()));
-    }
-
-    private void transitionToCamera() {
-        if (mTransitioning || mDown) return;
-
-        mTransitioning = true;
-
-        enableWindowExitAnimation(false);
-
-        mPreview.getLocationInWindow(mTmpLoc);
-        final float pvHeight = mPreview.getHeight() * mPreview.getScaleY();
-        final float pvCenter = mTmpLoc[1] + pvHeight / 2f;
-
-        final ViewGroup root = (ViewGroup) getRootView();
-        if (mFullscreenPreview == null) {
-            mFullscreenPreview = getPreviewWidget(mContext, mWidgetInfo);
-            mFullscreenPreview.setClickable(false);
-            root.addView(mFullscreenPreview);
-        }
-
-        root.getWindowVisibleDisplayFrame(mTmpRect);
-        final float fsHeight = mTmpRect.height();
-        final float fsCenter = mTmpRect.top + fsHeight / 2;
-
-        final float fsScaleY = pvHeight / fsHeight;
-        final float fsTransY = pvCenter - fsCenter;
-        final float fsScaleX = mPreview.getScaleX();
-
-        mPreview.setVisibility(View.GONE);
-        mFullscreenPreview.setVisibility(View.VISIBLE);
-        mFullscreenPreview.setTranslationY(fsTransY);
-        mFullscreenPreview.setScaleX(fsScaleX);
-        mFullscreenPreview.setScaleY(fsScaleY);
-        mFullscreenPreview
-            .animate()
-            .scaleX(1)
-            .scaleY(1)
-            .translationX(0)
-            .translationY(0)
-            .setDuration(WIDGET_ANIMATION_DURATION)
-            .withEndAction(mPostTransitionToCameraEndAction)
-            .start();
-        mCallbacks.onLaunchingCamera();
-    }
-
-    private void recover() {
-        if (DEBUG) Log.d(TAG, "recovering at " + SystemClock.uptimeMillis());
-        mCallbacks.onCameraLaunchedUnsuccessfully();
-        reset();
-    }
-
-    @Override
-    public void setOnLongClickListener(OnLongClickListener l) {
-        // ignore
-    }
-
-    @Override
-    public void onClick(View v) {
-        if (DEBUG) Log.d(TAG, "clicked");
-        if (mTransitioning) return;
-        if (mActive) {
-            cancelTransitionToCamera();
-            transitionToCamera();
-        }
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        if (DEBUG) Log.d(TAG, "onDetachedFromWindow: instance " + instanceId()
-                + " at " + SystemClock.uptimeMillis());
-        super.onDetachedFromWindow();
-        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mCallback);
-        cancelTransitionToCamera();
-        mHandler.removeCallbacks(mRecoverRunnable);
-    }
-
-    @Override
-    public void onActive(boolean isActive) {
-        mActive = isActive;
-        if (mActive) {
-            rescheduleTransitionToCamera();
-        } else {
-            reset();
-        }
-    }
-
-    @Override
-    public boolean onUserInteraction(MotionEvent event) {
-        if (mTransitioning) {
-            if (DEBUG) Log.d(TAG, "onUserInteraction eaten: mTransitioning");
-            return true;
-        }
-
-        getLocationOnScreen(mTmpLoc);
-        int rawBottom = mTmpLoc[1] + getHeight();
-        if (event.getRawY() > rawBottom) {
-            if (DEBUG) Log.d(TAG, "onUserInteraction eaten: below widget");
-            return true;
-        }
-
-        int action = event.getAction();
-        mDown = action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE;
-        if (mActive) {
-            rescheduleTransitionToCamera();
-        }
-        if (DEBUG) Log.d(TAG, "onUserInteraction observed, not eaten");
-        return false;
-    }
-
-    @Override
-    protected void onFocusLost() {
-        if (DEBUG) Log.d(TAG, "onFocusLost at " + SystemClock.uptimeMillis());
-        cancelTransitionToCamera();
-        super.onFocusLost();
-    }
-
-    public void onScreenTurnedOff() {
-        if (DEBUG) Log.d(TAG, "onScreenTurnedOff");
-        reset();
-    }
-
-    private void rescheduleTransitionToCamera() {
-        if (DEBUG) Log.d(TAG, "rescheduleTransitionToCamera at " + SystemClock.uptimeMillis());
-        mHandler.removeCallbacks(mTransitionToCameraRunnable);
-        mHandler.postDelayed(mTransitionToCameraRunnable, WIDGET_WAIT_DURATION);
-    }
-
-    private void cancelTransitionToCamera() {
-        if (DEBUG) Log.d(TAG, "cancelTransitionToCamera at " + SystemClock.uptimeMillis());
-        mHandler.removeCallbacks(mTransitionToCameraRunnable);
-    }
-
-    private void onCameraLaunched() {
-        mCallbacks.onCameraLaunchedSuccessfully();
-        reset();
-    }
-
-    private void reset() {
-        if (DEBUG) Log.d(TAG, "reset at " + SystemClock.uptimeMillis());
-        mLaunchCameraStart = 0;
-        mTransitioning = false;
-        mDown = false;
-        cancelTransitionToCamera();
-        mHandler.removeCallbacks(mRecoverRunnable);
-        mPreview.setVisibility(View.VISIBLE);
-        if (mFullscreenPreview != null) {
-            mFullscreenPreview.animate().cancel();
-            mFullscreenPreview.setVisibility(View.GONE);
-        }
-        enableWindowExitAnimation(true);
-    }
-
-    @Override
-    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
-        if (DEBUG) Log.d(TAG, String.format("onSizeChanged new=%sx%s old=%sx%s at %s",
-                w, h, oldw, oldh, SystemClock.uptimeMillis()));
-        mHandler.post(mRenderRunnable);
-        super.onSizeChanged(w, h, oldw, oldh);
-    }
-
-    @Override
-    public void onBouncerShowing(boolean showing) {
-        if (showing) {
-            mTransitioning = false;
-            mHandler.post(mRecoverRunnable);
-        }
-    }
-
-    private void enableWindowExitAnimation(boolean isEnabled) {
-        View root = getRootView();
-        ViewGroup.LayoutParams lp = root.getLayoutParams();
-        if (!(lp instanceof WindowManager.LayoutParams))
-            return;
-        WindowManager.LayoutParams wlp = (WindowManager.LayoutParams) lp;
-        int newWindowAnimations = isEnabled ? com.android.internal.R.style.Animation_LockScreen : 0;
-        if (newWindowAnimations != wlp.windowAnimations) {
-            if (DEBUG) Log.d(TAG, "setting windowAnimations to: " + newWindowAnimations
-                    + " at " + SystemClock.uptimeMillis());
-            wlp.windowAnimations = newWindowAnimations;
-            mWindowManager.updateViewLayout(root, wlp);
-        }
-    }
-
-    private void onKeyguardVisibilityChanged(boolean showing) {
-        if (DEBUG) Log.d(TAG, "onKeyguardVisibilityChanged " + showing
-                + " at " + SystemClock.uptimeMillis());
-        if (mTransitioning && !showing) {
-            mTransitioning = false;
-            mHandler.removeCallbacks(mRecoverRunnable);
-            if (mLaunchCameraStart > 0) {
-                long launchTime = SystemClock.uptimeMillis() - mLaunchCameraStart;
-                if (DEBUG) Log.d(TAG, String.format("Camera took %sms to launch", launchTime));
-                mLaunchCameraStart = 0;
-                onCameraLaunched();
-            }
-        }
-    }
-
-    private void onSecureCameraActivityStarted() {
-        if (DEBUG) Log.d(TAG, "onSecureCameraActivityStarted at " + SystemClock.uptimeMillis());
-        mHandler.postDelayed(mRecoverRunnable, RECOVERY_DELAY);
-    }
-
-    private String instanceId() {
-        return Integer.toHexString(hashCode());
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/CarrierText.java b/policy/src/com/android/internal/policy/impl/keyguard/CarrierText.java
deleted file mode 100644
index a38e86d..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/CarrierText.java
+++ /dev/null
@@ -1,258 +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.internal.policy.impl.keyguard;
-
-import android.content.Context;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.widget.TextView;
-
-import com.android.internal.R;
-import com.android.internal.telephony.IccCardConstants;
-import com.android.internal.telephony.IccCardConstants.State;
-import com.android.internal.widget.LockPatternUtils;
-
-public class CarrierText extends TextView {
-    private static CharSequence mSeparator;
-
-    private LockPatternUtils mLockPatternUtils;
-
-    private KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() {
-        private CharSequence mPlmn;
-        private CharSequence mSpn;
-        private State mSimState;
-
-        @Override
-        public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) {
-            mPlmn = plmn;
-            mSpn = spn;
-            updateCarrierText(mSimState, mPlmn, mSpn);
-        }
-
-        @Override
-        public void onSimStateChanged(IccCardConstants.State simState) {
-            mSimState = simState;
-            updateCarrierText(mSimState, mPlmn, mSpn);
-        }
-    };
-    /**
-     * The status of this lock screen. Primarily used for widgets on LockScreen.
-     */
-    private static enum StatusMode {
-        Normal, // Normal case (sim card present, it's not locked)
-        NetworkLocked, // SIM card is 'network locked'.
-        SimMissing, // SIM card is missing.
-        SimMissingLocked, // SIM card is missing, and device isn't provisioned; don't allow access
-        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.
-    }
-
-    public CarrierText(Context context) {
-        this(context, null);
-    }
-
-    public CarrierText(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        mLockPatternUtils = new LockPatternUtils(mContext);
-    }
-
-    protected void updateCarrierText(State simState, CharSequence plmn, CharSequence spn) {
-        CharSequence text = getCarrierTextForSimState(simState, plmn, spn);
-        if (KeyguardViewManager.USE_UPPER_CASE) {
-            setText(text != null ? text.toString().toUpperCase() : null);
-        } else {
-            setText(text);
-        }
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-        mSeparator = getResources().getString(R.string.kg_text_message_separator);
-        setSelected(true); // Allow marquee to work.
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mCallback);
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mCallback);
-    }
-
-    /**
-     * Top-level function for creating carrier text. Makes text based on simState, PLMN
-     * and SPN as well as device capabilities, such as being emergency call capable.
-     *
-     * @param simState
-     * @param plmn
-     * @param spn
-     * @return
-     */
-    private CharSequence getCarrierTextForSimState(IccCardConstants.State simState,
-            CharSequence plmn, CharSequence spn) {
-        CharSequence carrierText = null;
-        StatusMode status = getStatusForIccState(simState);
-        switch (status) {
-            case Normal:
-                carrierText = concatenate(plmn, spn);
-                break;
-
-            case SimNotReady:
-                carrierText = null; // nothing to display yet.
-                break;
-
-            case NetworkLocked:
-                carrierText = makeCarrierStringOnEmergencyCapable(
-                        mContext.getText(R.string.lockscreen_network_locked_message), plmn);
-                break;
-
-            case SimMissing:
-                // Shows "No SIM card | Emergency calls only" on devices that are voice-capable.
-                // This depends on mPlmn containing the text "Emergency calls only" when the radio
-                // has some connectivity. Otherwise, it should be null or empty and just show
-                // "No SIM card"
-                carrierText =  makeCarrierStringOnEmergencyCapable(
-                        getContext().getText(R.string.lockscreen_missing_sim_message_short),
-                        plmn);
-                break;
-
-            case SimPermDisabled:
-                carrierText = getContext().getText(
-                        R.string.lockscreen_permanent_disabled_sim_message_short);
-                break;
-
-            case SimMissingLocked:
-                carrierText =  makeCarrierStringOnEmergencyCapable(
-                        getContext().getText(R.string.lockscreen_missing_sim_message_short),
-                        plmn);
-                break;
-
-            case SimLocked:
-                carrierText = makeCarrierStringOnEmergencyCapable(
-                        getContext().getText(R.string.lockscreen_sim_locked_message),
-                        plmn);
-                break;
-
-            case SimPukLocked:
-                carrierText = makeCarrierStringOnEmergencyCapable(
-                        getContext().getText(R.string.lockscreen_sim_puk_locked_message),
-                        plmn);
-                break;
-        }
-
-        return carrierText;
-    }
-
-    /*
-     * Add emergencyCallMessage to carrier string only if phone supports emergency calls.
-     */
-    private CharSequence makeCarrierStringOnEmergencyCapable(
-            CharSequence simMessage, CharSequence emergencyCallMessage) {
-        if (mLockPatternUtils.isEmergencyCallCapable()) {
-            return concatenate(simMessage, emergencyCallMessage);
-        }
-        return simMessage;
-    }
-
-    /**
-     * Determine the current status of the lock screen given the SIM state and other stuff.
-     */
-    private StatusMode getStatusForIccState(IccCardConstants.State simState) {
-        // Since reading the SIM may take a while, we assume it is present until told otherwise.
-        if (simState == null) {
-            return StatusMode.Normal;
-        }
-
-        final boolean missingAndNotProvisioned =
-                !KeyguardUpdateMonitor.getInstance(mContext).isDeviceProvisioned()
-                && (simState == IccCardConstants.State.ABSENT ||
-                        simState == IccCardConstants.State.PERM_DISABLED);
-
-        // Assume we're NETWORK_LOCKED if not provisioned
-        simState = missingAndNotProvisioned ? IccCardConstants.State.NETWORK_LOCKED : simState;
-        switch (simState) {
-            case ABSENT:
-                return StatusMode.SimMissing;
-            case NETWORK_LOCKED:
-                return StatusMode.SimMissingLocked;
-            case NOT_READY:
-                return StatusMode.SimNotReady;
-            case PIN_REQUIRED:
-                return StatusMode.SimLocked;
-            case PUK_REQUIRED:
-                return StatusMode.SimPukLocked;
-            case READY:
-                return StatusMode.Normal;
-            case PERM_DISABLED:
-                return StatusMode.SimPermDisabled;
-            case UNKNOWN:
-                return StatusMode.SimMissing;
-        }
-        return StatusMode.SimMissing;
-    }
-
-    private static CharSequence concatenate(CharSequence plmn, CharSequence spn) {
-        final boolean plmnValid = !TextUtils.isEmpty(plmn);
-        final boolean spnValid = !TextUtils.isEmpty(spn);
-        if (plmnValid && spnValid) {
-            return new StringBuilder().append(plmn).append(mSeparator).append(spn).toString();
-        } else if (plmnValid) {
-            return plmn;
-        } else if (spnValid) {
-            return spn;
-        } else {
-            return "";
-        }
-    }
-
-    private CharSequence getCarrierHelpTextForSimState(IccCardConstants.State simState,
-            String plmn, String spn) {
-        int carrierHelpTextId = 0;
-        StatusMode status = getStatusForIccState(simState);
-        switch (status) {
-            case NetworkLocked:
-                carrierHelpTextId = R.string.lockscreen_instructions_when_pattern_disabled;
-                break;
-
-            case SimMissing:
-                carrierHelpTextId = R.string.lockscreen_missing_sim_instructions_long;
-                break;
-
-            case SimPermDisabled:
-                carrierHelpTextId = R.string.lockscreen_permanent_disabled_sim_instructions;
-                break;
-
-            case SimMissingLocked:
-                carrierHelpTextId = R.string.lockscreen_missing_sim_instructions;
-                break;
-
-            case Normal:
-            case SimLocked:
-            case SimPukLocked:
-                break;
-        }
-
-        return mContext.getText(carrierHelpTextId);
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/ChallengeLayout.java b/policy/src/com/android/internal/policy/impl/keyguard/ChallengeLayout.java
deleted file mode 100644
index 8ece559..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/ChallengeLayout.java
+++ /dev/null
@@ -1,97 +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.internal.policy.impl.keyguard;
-
-/**
- * Interface implemented by ViewGroup-derived layouts that implement
- * special logic for presenting security challenges to the user.
- */
-public interface ChallengeLayout {
-    /**
-     * @return true if the security challenge area of this layout is currently visible
-     */
-    boolean isChallengeShowing();
-
-    /**
-     * @return true if the challenge area significantly overlaps other content
-     */
-    boolean isChallengeOverlapping();
-
-    /**
-     * Show or hide the challenge layout.
-     *
-     * If you want to show the challenge layout in bouncer mode where applicable,
-     * use {@link #showBouncer()} instead.
-     *
-     * @param b true to show, false to hide
-     */
-    void showChallenge(boolean b);
-
-    /**
-     * Show the bouncer challenge. This may block access to other child views.
-     */
-    void showBouncer();
-
-    /**
-     * Hide the bouncer challenge if it is currently showing.
-     * This may restore previously blocked access to other child views.
-     */
-    void hideBouncer();
-
-    /**
-     * Returns true if the challenge is currently in bouncer mode,
-     * potentially blocking access to other child views.
-     */
-    boolean isBouncing();
-
-    /**
-     * Returns the duration of the bounce animation.
-     */
-    int getBouncerAnimationDuration();
-
-    /**
-     * Set a listener that will respond to changes in bouncer state.
-     *
-     * @param listener listener to register
-     */
-    void setOnBouncerStateChangedListener(OnBouncerStateChangedListener listener);
-
-    /**
-     * Listener interface that reports changes in bouncer state.
-     * The bouncer is
-     */
-    public interface OnBouncerStateChangedListener {
-        /**
-         * Called when the bouncer state changes.
-         * The bouncer is activated when the user must pass a security challenge
-         * to proceed with the requested action.
-         *
-         * <p>This differs from simply showing or hiding the security challenge
-         * as the bouncer will prevent interaction with other elements of the UI.
-         * If the user attempts to escape from the bouncer, it will be dismissed,
-         * this method will be called with false as the parameter, and the action
-         * should be canceled. If the security component reports a successful
-         * authentication and the containing code calls hideBouncer() as a result,
-         * this method will also be called with a false parameter. It is up to the
-         * caller of hideBouncer to be ready for this.</p>
-         *
-         * @param bouncerActive true if the bouncer is now active,
-         *                      false if the bouncer was dismissed.
-         */
-        public void onBouncerStateChanged(boolean bouncerActive);
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/CheckLongPressHelper.java b/policy/src/com/android/internal/policy/impl/keyguard/CheckLongPressHelper.java
deleted file mode 100644
index 4825e23..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/CheckLongPressHelper.java
+++ /dev/null
@@ -1,82 +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.internal.policy.impl.keyguard;
-
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewConfiguration;
-
-public class CheckLongPressHelper {
-    private View mView;
-    private boolean mHasPerformedLongPress;
-    private CheckForLongPress mPendingCheckForLongPress;
-    private float mDownX, mDownY;
-    private int mLongPressTimeout;
-    private int mScaledTouchSlop;
-
-    class CheckForLongPress implements Runnable {
-        public void run() {
-            if ((mView.getParent() != null) && mView.hasWindowFocus()
-                    && !mHasPerformedLongPress) {
-                if (mView.performLongClick()) {
-                    mView.setPressed(false);
-                    mHasPerformedLongPress = true;
-                }
-            }
-        }
-    }
-
-    public CheckLongPressHelper(View v) {
-        mScaledTouchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();
-        mLongPressTimeout = ViewConfiguration.getLongPressTimeout();
-        mView = v;
-    }
-
-    public void postCheckForLongPress(MotionEvent ev) {
-        mDownX = ev.getX();
-        mDownY = ev.getY();
-        mHasPerformedLongPress = false;
-
-        if (mPendingCheckForLongPress == null) {
-            mPendingCheckForLongPress = new CheckForLongPress();
-        }
-        mView.postDelayed(mPendingCheckForLongPress, mLongPressTimeout);
-    }
-
-    public void onMove(MotionEvent ev) {
-        float x = ev.getX();
-        float y = ev.getY();
-        boolean xMoved = Math.abs(mDownX - x) > mScaledTouchSlop;
-        boolean yMoved = Math.abs(mDownY - y) > mScaledTouchSlop;
-
-        if (xMoved || yMoved) {
-            cancelLongPress();
-        }
-    }
-
-    public void cancelLongPress() {
-        mHasPerformedLongPress = false;
-        if (mPendingCheckForLongPress != null) {
-            mView.removeCallbacks(mPendingCheckForLongPress);
-            mPendingCheckForLongPress = null;
-        }
-    }
-
-    public boolean hasPerformedLongPress() {
-        return mHasPerformedLongPress;
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/ClockView.java b/policy/src/com/android/internal/policy/impl/keyguard/ClockView.java
deleted file mode 100644
index 34bf6e7..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/ClockView.java
+++ /dev/null
@@ -1,224 +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.internal.policy.impl.keyguard;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.database.ContentObserver;
-import android.graphics.Typeface;
-import android.os.Handler;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.text.format.DateFormat;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
-
-import java.lang.ref.WeakReference;
-import java.text.DateFormatSymbols;
-import java.util.Calendar;
-import com.android.internal.R;
-
-/**
- * Displays the time
- */
-public class ClockView extends RelativeLayout {
-    private static final String ANDROID_CLOCK_FONT_FILE = "/system/fonts/AndroidClock.ttf";
-    private final static String M12 = "h:mm";
-    private final static String M24 = "HH:mm";
-
-    private Calendar mCalendar;
-    private String mFormat;
-    private TextView mTimeView;
-    private AmPm mAmPm;
-    private ContentObserver mFormatChangeObserver;
-    private int mAttached = 0; // for debugging - tells us whether attach/detach is unbalanced
-
-    /* called by system on minute ticks */
-    private final Handler mHandler = new Handler();
-    private BroadcastReceiver mIntentReceiver;
-
-    private static class TimeChangedReceiver extends BroadcastReceiver {
-        private WeakReference<ClockView> mClock;
-        private Context mContext;
-
-        public TimeChangedReceiver(ClockView clock) {
-            mClock = new WeakReference<ClockView>(clock);
-            mContext = clock.getContext();
-        }
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            // Post a runnable to avoid blocking the broadcast.
-            final boolean timezoneChanged =
-                    intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED);
-            final ClockView clock = mClock.get();
-            if (clock != null) {
-                clock.mHandler.post(new Runnable() {
-                    public void run() {
-                        if (timezoneChanged) {
-                            clock.mCalendar = Calendar.getInstance();
-                        }
-                        clock.updateTime();
-                    }
-                });
-            } else {
-                try {
-                    mContext.unregisterReceiver(this);
-                } catch (RuntimeException e) {
-                    // Shouldn't happen
-                }
-            }
-        }
-    };
-
-    static class AmPm {
-        private TextView mAmPmTextView;
-        private String mAmString, mPmString;
-
-        AmPm(View parent, Typeface tf) {
-            // No longer used, uncomment if we decide to use AM/PM indicator again
-            // mAmPmTextView = (TextView) parent.findViewById(R.id.am_pm);
-            if (mAmPmTextView != null && tf != null) {
-                mAmPmTextView.setTypeface(tf);
-            }
-
-            String[] ampm = new DateFormatSymbols().getAmPmStrings();
-            mAmString = ampm[0];
-            mPmString = ampm[1];
-        }
-
-        void setShowAmPm(boolean show) {
-            if (mAmPmTextView != null) {
-                mAmPmTextView.setVisibility(show ? View.VISIBLE : View.GONE);
-            }
-        }
-
-        void setIsMorning(boolean isMorning) {
-            if (mAmPmTextView != null) {
-                mAmPmTextView.setText(isMorning ? mAmString : mPmString);
-            }
-        }
-    }
-
-    private static class FormatChangeObserver extends ContentObserver {
-        private WeakReference<ClockView> mClock;
-        private Context mContext;
-        public FormatChangeObserver(ClockView clock) {
-            super(new Handler());
-            mClock = new WeakReference<ClockView>(clock);
-            mContext = clock.getContext();
-        }
-        @Override
-        public void onChange(boolean selfChange) {
-            ClockView digitalClock = mClock.get();
-            if (digitalClock != null) {
-                digitalClock.setDateFormat();
-                digitalClock.updateTime();
-            } else {
-                try {
-                    mContext.getContentResolver().unregisterContentObserver(this);
-                } catch (RuntimeException e) {
-                    // Shouldn't happen
-                }
-            }
-        }
-    }
-
-    public ClockView(Context context) {
-        this(context, null);
-    }
-
-    public ClockView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-        mTimeView = (TextView) findViewById(R.id.clock_text);
-        mTimeView.setTypeface(Typeface.createFromFile(ANDROID_CLOCK_FONT_FILE));
-        mAmPm = new AmPm(this, null);
-        mCalendar = Calendar.getInstance();
-        setDateFormat();
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-
-        mAttached++;
-
-        /* monitor time ticks, time changed, timezone */
-        if (mIntentReceiver == null) {
-            mIntentReceiver = new TimeChangedReceiver(this);
-            IntentFilter filter = new IntentFilter();
-            filter.addAction(Intent.ACTION_TIME_TICK);
-            filter.addAction(Intent.ACTION_TIME_CHANGED);
-            filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
-            mContext.registerReceiverAsUser(mIntentReceiver, UserHandle.OWNER, filter, null, null );
-        }
-
-        /* monitor 12/24-hour display preference */
-        if (mFormatChangeObserver == null) {
-            mFormatChangeObserver = new FormatChangeObserver(this);
-            mContext.getContentResolver().registerContentObserver(
-                    Settings.System.CONTENT_URI, true, mFormatChangeObserver);
-        }
-
-        updateTime();
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-
-        mAttached--;
-
-        if (mIntentReceiver != null) {
-            mContext.unregisterReceiver(mIntentReceiver);
-        }
-        if (mFormatChangeObserver != null) {
-            mContext.getContentResolver().unregisterContentObserver(
-                    mFormatChangeObserver);
-        }
-
-        mFormatChangeObserver = null;
-        mIntentReceiver = null;
-    }
-
-    void updateTime(Calendar c) {
-        mCalendar = c;
-        updateTime();
-    }
-
-    public void updateTime() {
-        mCalendar.setTimeInMillis(System.currentTimeMillis());
-
-        CharSequence newTime = DateFormat.format(mFormat, mCalendar);
-        mTimeView.setText(newTime);
-        mAmPm.setIsMorning(mCalendar.get(Calendar.AM_PM) == 0);
-    }
-
-    private void setDateFormat() {
-        mFormat = android.text.format.DateFormat.is24HourFormat(getContext()) ? M24 : M12;
-        mAmPm.setShowAmPm(mFormat.equals(M12));
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/EmergencyButton.java b/policy/src/com/android/internal/policy/impl/keyguard/EmergencyButton.java
deleted file mode 100644
index c68bab5..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/EmergencyButton.java
+++ /dev/null
@@ -1,132 +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.internal.policy.impl.keyguard;
-
-import android.content.Context;
-import android.content.Intent;
-import android.os.PowerManager;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.telephony.TelephonyManager;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.Button;
-
-import com.android.internal.telephony.IccCardConstants.State;
-import com.android.internal.widget.LockPatternUtils;
-
-/**
- * This class implements a smart emergency button that updates itself based
- * on telephony state.  When the phone is idle, it is an emergency call button.
- * When there's a call in progress, it presents an appropriate message and
- * allows the user to return to the call.
- */
-public class EmergencyButton extends Button {
-
-    private static final int EMERGENCY_CALL_TIMEOUT = 10000; // screen timeout after starting e.d.
-    private static final String ACTION_EMERGENCY_DIAL = "com.android.phone.EmergencyDialer.DIAL";
-
-    KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
-
-        @Override
-        public void onSimStateChanged(State simState) {
-            int phoneState = KeyguardUpdateMonitor.getInstance(mContext).getPhoneState();
-            updateEmergencyCallButton(simState, phoneState);
-        }
-
-        void onPhoneStateChanged(int phoneState) {
-            State simState = KeyguardUpdateMonitor.getInstance(mContext).getSimState();
-            updateEmergencyCallButton(simState, phoneState);
-        };
-    };
-    private LockPatternUtils mLockPatternUtils;
-    private PowerManager mPowerManager;
-
-    public EmergencyButton(Context context) {
-        this(context, null);
-    }
-
-    public EmergencyButton(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mInfoCallback);
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mInfoCallback);
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-        mLockPatternUtils = new LockPatternUtils(mContext);
-        mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
-        setOnClickListener(new OnClickListener() {
-            public void onClick(View v) {
-                takeEmergencyCallAction();
-            }
-        });
-        int phoneState = KeyguardUpdateMonitor.getInstance(mContext).getPhoneState();
-        State simState = KeyguardUpdateMonitor.getInstance(mContext).getSimState();
-        updateEmergencyCallButton(simState, phoneState);
-    }
-
-    /**
-     * Shows the emergency dialer or returns the user to the existing call.
-     */
-    public void takeEmergencyCallAction() {
-        // TODO: implement a shorter timeout once new PowerManager API is ready.
-        // should be the equivalent to the old userActivity(EMERGENCY_CALL_TIMEOUT)
-        mPowerManager.userActivity(SystemClock.uptimeMillis(), true);
-        if (TelephonyManager.getDefault().getCallState()
-                == TelephonyManager.CALL_STATE_OFFHOOK) {
-            mLockPatternUtils.resumeCall();
-        } else {
-            Intent intent = new Intent(ACTION_EMERGENCY_DIAL);
-            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-            getContext().startActivityAsUser(intent,
-                    new UserHandle(mLockPatternUtils.getCurrentUser()));
-        }
-    }
-
-    private void updateEmergencyCallButton(State simState, int phoneState) {
-        boolean enabled = false;
-        if (phoneState == TelephonyManager.CALL_STATE_OFFHOOK) {
-            enabled = true; // always show "return to call" if phone is off-hook
-        } else if (mLockPatternUtils.isEmergencyCallCapable()) {
-            boolean simLocked = KeyguardUpdateMonitor.getInstance(mContext).isSimLocked();
-            if (simLocked) {
-                // Some countries can't handle emergency calls while SIM is locked.
-                enabled = mLockPatternUtils.isEmergencyCallEnabledWhileSimLocked();
-            } else {
-                // True if we need to show a secure screen (pin/pattern/SIM pin/SIM puk);
-                // hides emergency button on "Slide" screen if device is not secure.
-                enabled = mLockPatternUtils.isSecure();
-            }
-        }
-        mLockPatternUtils.updateEmergencyCallButtonState(this, phoneState, enabled,
-                KeyguardViewManager.USE_UPPER_CASE, false);
-    }
-
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/EmergencyCarrierArea.java b/policy/src/com/android/internal/policy/impl/keyguard/EmergencyCarrierArea.java
deleted file mode 100644
index cfe1ef4..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/EmergencyCarrierArea.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.policy.impl.keyguard;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.widget.LinearLayout;
-
-import com.android.internal.R;
-
-public class EmergencyCarrierArea extends LinearLayout {
-
-    private CarrierText mCarrierText;
-    private EmergencyButton mEmergencyButton;
-
-    public EmergencyCarrierArea(Context context) {
-        super(context);
-    }
-
-    public EmergencyCarrierArea(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-        mCarrierText = (CarrierText) findViewById(R.id.carrier_text);
-        mEmergencyButton = (EmergencyButton) findViewById(R.id.emergency_call_button);
-
-        // The emergency button overlaps the carrier text, only noticeable when highlighted.
-        // So temporarily hide the carrier text while the emergency button is pressed.
-        mEmergencyButton.setOnTouchListener(new OnTouchListener(){
-            @Override
-            public boolean onTouch(View v, MotionEvent event) {
-                switch(event.getAction()) {
-                    case MotionEvent.ACTION_DOWN:
-                        mCarrierText.animate().alpha(0);
-                        break;
-                    case MotionEvent.ACTION_UP:
-                        mCarrierText.animate().alpha(1);
-                        break;
-                }
-                return false;
-            }});
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/FaceUnlock.java b/policy/src/com/android/internal/policy/impl/keyguard/FaceUnlock.java
deleted file mode 100644
index e58eb5b..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/FaceUnlock.java
+++ /dev/null
@@ -1,462 +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.internal.policy.impl.keyguard;
-
-import com.android.internal.policy.IFaceLockCallback;
-import com.android.internal.policy.IFaceLockInterface;
-import com.android.internal.widget.LockPatternUtils;
-
-import android.app.admin.DevicePolicyManager;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.util.Log;
-import android.view.View;
-
-public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback {
-
-    private static final boolean DEBUG = false;
-    private static final String TAG = "FULLockscreen";
-
-    private final Context mContext;
-    private final LockPatternUtils mLockPatternUtils;
-
-    // TODO: is mServiceRunning needed or can we just use mIsRunning or check if mService is null?
-    private boolean mServiceRunning = false;
-    // TODO: now that the code has been restructure to do almost all operations from a handler, this
-    // lock may no longer be necessary.
-    private final Object mServiceRunningLock = new Object();
-    private IFaceLockInterface mService;
-    private boolean mBoundToService = false;
-    private View mFaceUnlockView;
-
-    private Handler mHandler;
-    private final int MSG_SERVICE_CONNECTED = 0;
-    private final int MSG_SERVICE_DISCONNECTED = 1;
-    private final int MSG_UNLOCK = 2;
-    private final int MSG_CANCEL = 3;
-    private final int MSG_REPORT_FAILED_ATTEMPT = 4;
-    private final int MSG_POKE_WAKELOCK = 5;
-
-    // TODO: This was added for the purpose of adhering to what the biometric interface expects
-    // the isRunning() function to return.  However, it is probably not necessary to have both
-    // mRunning and mServiceRunning.  I'd just rather wait to change that logic.
-    private volatile boolean mIsRunning = false;
-
-    // So the user has a consistent amount of time when brought to the backup method from Face
-    // Unlock
-    private final int BACKUP_LOCK_TIMEOUT = 5000;
-
-    KeyguardSecurityCallback mKeyguardScreenCallback;
-
-    /**
-     * Stores some of the structures that Face Unlock will need to access and creates the handler
-     * will be used to execute messages on the UI thread.
-     */
-    public FaceUnlock(Context context) {
-        mContext = context;
-        mLockPatternUtils = new LockPatternUtils(context);
-        mHandler = new Handler(this);
-    }
-
-    public void setKeyguardCallback(KeyguardSecurityCallback keyguardScreenCallback) {
-        mKeyguardScreenCallback = keyguardScreenCallback;
-    }
-
-    /**
-     * Stores and displays the view that Face Unlock is allowed to draw within.
-     * TODO: since the layout object will eventually be shared by multiple biometric unlock
-     * methods, we will have to add our other views (background, cancel button) here.
-     */
-    public void initializeView(View biometricUnlockView) {
-        Log.d(TAG, "initializeView()");
-        mFaceUnlockView = biometricUnlockView;
-    }
-
-    /**
-     * Indicates whether Face Unlock is currently running.
-     */
-    public boolean isRunning() {
-        return mIsRunning;
-    }
-
-    /**
-     * Dismisses face unlock and goes to the backup lock
-     */
-    public void stopAndShowBackup() {
-        if (DEBUG) Log.d(TAG, "stopAndShowBackup()");
-        mHandler.sendEmptyMessage(MSG_CANCEL);
-    }
-
-    /**
-     * Binds to the Face Unlock service.  Face Unlock will be started when the bind completes.  The
-     * Face Unlock view is displayed to hide the backup lock while the service is starting up.
-     * Called on the UI thread.
-     */
-    public boolean start() {
-        if (DEBUG) Log.d(TAG, "start()");
-        if (mHandler.getLooper() != Looper.myLooper()) {
-            Log.e(TAG, "start() called off of the UI thread");
-        }
-
-        if (mIsRunning) {
-            Log.w(TAG, "start() called when already running");
-        }
-
-        if (!mBoundToService) {
-            Log.d(TAG, "Binding to Face Unlock service for user="
-                    + mLockPatternUtils.getCurrentUser());
-            mContext.bindServiceAsUser(new Intent(IFaceLockInterface.class.getName()),
-                    mConnection,
-                    Context.BIND_AUTO_CREATE,
-                    new UserHandle(mLockPatternUtils.getCurrentUser()));
-            mBoundToService = true;
-        } else {
-            Log.w(TAG, "Attempt to bind to Face Unlock when already bound");
-        }
-
-        mIsRunning = true;
-        return true;
-    }
-
-    /**
-     * Stops Face Unlock and unbinds from the service.  Called on the UI thread.
-     */
-    public boolean stop() {
-        if (DEBUG) Log.d(TAG, "stop()");
-        if (mHandler.getLooper() != Looper.myLooper()) {
-            Log.e(TAG, "stop() called from non-UI thread");
-        }
-
-        // Clearing any old service connected messages.
-        mHandler.removeMessages(MSG_SERVICE_CONNECTED);
-
-        boolean mWasRunning = mIsRunning;
-
-        stopUi();
-
-        if (mBoundToService) {
-            if (mService != null) {
-                try {
-                    mService.unregisterCallback(mFaceUnlockCallback);
-                } catch (RemoteException e) {
-                    // Not much we can do
-                }
-            }
-            Log.d(TAG, "Unbinding from Face Unlock service");
-            mContext.unbindService(mConnection);
-            mBoundToService = false;
-        } else {
-            // This is usually not an error when this happens.  Sometimes we will tell it to
-            // unbind multiple times because it's called from both onWindowFocusChanged and
-            // onDetachedFromWindow.
-            if (DEBUG) Log.d(TAG, "Attempt to unbind from Face Unlock when not bound");
-        }
-        mIsRunning = false;
-        return mWasRunning;
-    }
-
-    /**
-     * Frees up resources used by Face Unlock and stops it if it is still running.
-     */
-    public void cleanUp() {
-        if (DEBUG) Log.d(TAG, "cleanUp()");
-        if (mService != null) {
-            try {
-                mService.unregisterCallback(mFaceUnlockCallback);
-            } catch (RemoteException e) {
-                // Not much we can do
-            }
-            stopUi();
-            mService = null;
-        }
-    }
-
-    /**
-     * Returns the Device Policy Manager quality for Face Unlock, which is BIOMETRIC_WEAK.
-     */
-    public int getQuality() {
-        return DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK;
-    }
-
-    /**
-     * Handles messages such that everything happens on the UI thread in a deterministic order.
-     * Calls from the Face Unlock service come from binder threads.  Calls from lockscreen typically
-     * come from the UI thread.  This makes sure there are no race conditions between those calls.
-     */
-    public boolean handleMessage(Message msg) {
-        switch (msg.what) {
-            case MSG_SERVICE_CONNECTED:
-                handleServiceConnected();
-                break;
-            case MSG_SERVICE_DISCONNECTED:
-                handleServiceDisconnected();
-                break;
-            case MSG_UNLOCK:
-                handleUnlock(msg.arg1);
-                break;
-            case MSG_CANCEL:
-                handleCancel();
-                break;
-            case MSG_REPORT_FAILED_ATTEMPT:
-                handleReportFailedAttempt();
-                break;
-            case MSG_POKE_WAKELOCK:
-                handlePokeWakelock(msg.arg1);
-                break;
-            default:
-                Log.e(TAG, "Unhandled message");
-                return false;
-        }
-        return true;
-    }
-
-    /**
-     * Tells the service to start its UI via an AIDL interface.  Called when the
-     * onServiceConnected() callback is received.
-     */
-    void handleServiceConnected() {
-        Log.d(TAG, "handleServiceConnected()");
-
-        // It is possible that an unbind has occurred in the time between the bind and when this
-        // function is reached.  If an unbind has already occurred, proceeding on to call startUi()
-        // can result in a fatal error.  Note that the onServiceConnected() callback is
-        // asynchronous, so this possibility would still exist if we executed this directly in
-        // onServiceConnected() rather than using a handler.
-        if (!mBoundToService) {
-            Log.d(TAG, "Dropping startUi() in handleServiceConnected() because no longer bound");
-            return;
-        }
-
-        try {
-            mService.registerCallback(mFaceUnlockCallback);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Caught exception connecting to Face Unlock: " + e.toString());
-            mService = null;
-            mBoundToService = false;
-            mIsRunning = false;
-            return;
-        }
-
-        if (mFaceUnlockView != null) {
-            IBinder windowToken = mFaceUnlockView.getWindowToken();
-            if (windowToken != null) {
-                // When switching between portrait and landscape view while Face Unlock is running,
-                // the screen will eventually go dark unless we poke the wakelock when Face Unlock
-                // is restarted.
-                mKeyguardScreenCallback.userActivity(0);
-
-                int[] position;
-                position = new int[2];
-                mFaceUnlockView.getLocationInWindow(position);
-                startUi(windowToken, position[0], position[1], mFaceUnlockView.getWidth(),
-                        mFaceUnlockView.getHeight());
-            } else {
-                Log.e(TAG, "windowToken is null in handleServiceConnected()");
-            }
-        }
-    }
-
-    /**
-     * Called when the onServiceDisconnected() callback is received.  This should not happen during
-     * normal operation.  It indicates an error has occurred.
-     */
-    void handleServiceDisconnected() {
-        Log.e(TAG, "handleServiceDisconnected()");
-        // TODO: this lock may no longer be needed now that everything is being called from a
-        // handler
-        synchronized (mServiceRunningLock) {
-            mService = null;
-            mServiceRunning = false;
-        }
-        mBoundToService = false;
-        mIsRunning = false;
-    }
-
-    /**
-     * Stops the Face Unlock service and tells the device to grant access to the user.
-     */
-    void handleUnlock(int authenticatedUserId) {
-        if (DEBUG) Log.d(TAG, "handleUnlock()");
-        stop();
-        int currentUserId = mLockPatternUtils.getCurrentUser();
-        if (authenticatedUserId == currentUserId) {
-            if (DEBUG) Log.d(TAG, "Unlocking for user " + authenticatedUserId);
-            mKeyguardScreenCallback.reportSuccessfulUnlockAttempt();
-            mKeyguardScreenCallback.dismiss(true);
-        } else {
-            Log.d(TAG, "Ignoring unlock for authenticated user (" + authenticatedUserId +
-                    ") because the current user is " + currentUserId);
-        }
-    }
-
-    /**
-     * Stops the Face Unlock service and goes to the backup lock.
-     */
-    void handleCancel() {
-        if (DEBUG) Log.d(TAG, "handleCancel()");
-        // We are going to the backup method, so we don't want to see Face Unlock again until the
-        // next time the user visits keyguard.
-        KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(false);
-
-        mKeyguardScreenCallback.showBackupSecurity();
-        stop();
-        mKeyguardScreenCallback.userActivity(BACKUP_LOCK_TIMEOUT);
-    }
-
-    /**
-     * Increments the number of failed Face Unlock attempts.
-     */
-    void handleReportFailedAttempt() {
-        if (DEBUG) Log.d(TAG, "handleReportFailedAttempt()");
-        // We are going to the backup method, so we don't want to see Face Unlock again until the
-        // next time the user visits keyguard.
-        KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(false);
-
-        mKeyguardScreenCallback.reportFailedUnlockAttempt();
-    }
-
-    /**
-     * If the screen is on, pokes the wakelock to keep the screen alive and active for a specific
-     * amount of time.
-     */
-    void handlePokeWakelock(int millis) {
-      PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
-      if (powerManager.isScreenOn()) {
-        mKeyguardScreenCallback.userActivity(millis);
-      }
-    }
-
-    /**
-     * Implements service connection methods.
-     */
-    private ServiceConnection mConnection = new ServiceConnection() {
-        /**
-         * Called when the Face Unlock service connects after calling bind().
-         */
-        public void onServiceConnected(ComponentName className, IBinder iservice) {
-            Log.d(TAG, "Connected to Face Unlock service");
-            mService = IFaceLockInterface.Stub.asInterface(iservice);
-            mHandler.sendEmptyMessage(MSG_SERVICE_CONNECTED);
-        }
-
-        /**
-         * Called if the Face Unlock service unexpectedly disconnects.  This indicates an error.
-         */
-        public void onServiceDisconnected(ComponentName className) {
-            Log.e(TAG, "Unexpected disconnect from Face Unlock service");
-            mHandler.sendEmptyMessage(MSG_SERVICE_DISCONNECTED);
-        }
-    };
-
-    /**
-     * Tells the Face Unlock service to start displaying its UI and start processing.
-     */
-    private void startUi(IBinder windowToken, int x, int y, int w, int h) {
-        if (DEBUG) Log.d(TAG, "startUi()");
-        synchronized (mServiceRunningLock) {
-            if (!mServiceRunning) {
-                Log.d(TAG, "Starting Face Unlock");
-                try {
-                    mService.startUi(windowToken, x, y, w, h,
-                            mLockPatternUtils.isBiometricWeakLivelinessEnabled());
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Caught exception starting Face Unlock: " + e.toString());
-                    return;
-                }
-                mServiceRunning = true;
-            } else {
-                Log.w(TAG, "startUi() attempted while running");
-            }
-        }
-    }
-
-    /**
-     * Tells the Face Unlock service to stop displaying its UI and stop processing.
-     */
-    private void stopUi() {
-        if (DEBUG) Log.d(TAG, "stopUi()");
-        // Note that attempting to stop Face Unlock when it's not running is not an issue.
-        // Face Unlock can return, which stops it and then we try to stop it when the
-        // screen is turned off.  That's why we check.
-        synchronized (mServiceRunningLock) {
-            if (mServiceRunning) {
-                Log.d(TAG, "Stopping Face Unlock");
-                try {
-                    mService.stopUi();
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Caught exception stopping Face Unlock: " + e.toString());
-                }
-                mServiceRunning = false;
-            } else {
-                // This is usually not an error when this happens.  Sometimes we will tell it to
-                // stop multiple times because it's called from both onWindowFocusChanged and
-                // onDetachedFromWindow.
-                if (DEBUG) Log.d(TAG, "stopUi() attempted while not running");
-            }
-        }
-    }
-
-    /**
-     * Implements the AIDL biometric unlock service callback interface.
-     */
-    private final IFaceLockCallback mFaceUnlockCallback = new IFaceLockCallback.Stub() {
-        /**
-         * Called when Face Unlock wants to grant access to the user.
-         */
-        public void unlock() {
-            if (DEBUG) Log.d(TAG, "unlock()");
-            Message message = mHandler.obtainMessage(MSG_UNLOCK, UserHandle.getCallingUserId(), -1);
-            mHandler.sendMessage(message);
-        }
-
-        /**
-         * Called when Face Unlock wants to go to the backup.
-         */
-        public void cancel() {
-            if (DEBUG) Log.d(TAG, "cancel()");
-            mHandler.sendEmptyMessage(MSG_CANCEL);
-        }
-
-        /**
-         * Called when Face Unlock wants to increment the number of failed attempts.
-         */
-        public void reportFailedAttempt() {
-            if (DEBUG) Log.d(TAG, "reportFailedAttempt()");
-            mHandler.sendEmptyMessage(MSG_REPORT_FAILED_ATTEMPT);
-        }
-
-        /**
-         * Called when Face Unlock wants to keep the screen alive and active for a specific amount
-         * of time.
-         */
-        public void pokeWakelock(int millis) {
-            if (DEBUG) Log.d(TAG, "pokeWakelock() for " + millis + "ms");
-            Message message = mHandler.obtainMessage(MSG_POKE_WAKELOCK, millis, -1);
-            mHandler.sendMessage(message);
-        }
-
-    };
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAbsKeyInputView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAbsKeyInputView.java
deleted file mode 100644
index cc520dc..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAbsKeyInputView.java
+++ /dev/null
@@ -1,263 +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.internal.policy.impl.keyguard;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.os.CountDownTimer;
-import android.os.SystemClock;
-import android.text.Editable;
-import android.text.TextWatcher;
-import android.util.AttributeSet;
-import android.view.HapticFeedbackConstants;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.inputmethod.EditorInfo;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-import android.widget.TextView.OnEditorActionListener;
-
-import com.android.internal.R;
-import com.android.internal.widget.LockPatternUtils;
-
-/**
- * Base class for PIN and password unlock screens.
- */
-public abstract class KeyguardAbsKeyInputView extends LinearLayout
-        implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
-    protected KeyguardSecurityCallback mCallback;
-    protected TextView mPasswordEntry;
-    protected LockPatternUtils mLockPatternUtils;
-    protected SecurityMessageDisplay mSecurityMessageDisplay;
-    protected View mEcaView;
-    private Drawable mBouncerFrame;
-    protected boolean mEnableHaptics;
-
-    // To avoid accidental lockout due to events while the device in in the pocket, ignore
-    // any passwords with length less than or equal to this length.
-    protected static final int MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT = 3;
-
-    public KeyguardAbsKeyInputView(Context context) {
-        this(context, null);
-    }
-
-    public KeyguardAbsKeyInputView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public void setKeyguardCallback(KeyguardSecurityCallback callback) {
-        mCallback = callback;
-    }
-
-    public void setLockPatternUtils(LockPatternUtils utils) {
-        mLockPatternUtils = utils;
-        mEnableHaptics = mLockPatternUtils.isTactileFeedbackEnabled();
-    }
-
-    @Override
-    public void onWindowFocusChanged(boolean hasWindowFocus) {
-        if (hasWindowFocus) {
-            reset();
-        }
-    }
-
-    public void reset() {
-        // start fresh
-        mPasswordEntry.setText("");
-        mPasswordEntry.requestFocus();
-
-        // if the user is currently locked out, enforce it.
-        long deadline = mLockPatternUtils.getLockoutAttemptDeadline();
-        if (deadline != 0) {
-            handleAttemptLockout(deadline);
-        } else {
-            resetState();
-        }
-    }
-
-    protected abstract int getPasswordTextViewId();
-    protected abstract void resetState();
-
-    @Override
-    protected void onFinishInflate() {
-        mLockPatternUtils = new LockPatternUtils(mContext);
-
-        mPasswordEntry = (TextView) findViewById(getPasswordTextViewId());
-        mPasswordEntry.setOnEditorActionListener(this);
-        mPasswordEntry.addTextChangedListener(this);
-
-        // Set selected property on so the view can send accessibility events.
-        mPasswordEntry.setSelected(true);
-
-        // Poke the wakelock any time the text is selected or modified
-        mPasswordEntry.setOnClickListener(new OnClickListener() {
-            public void onClick(View v) {
-                mCallback.userActivity(0); // TODO: customize timeout for text?
-            }
-        });
-
-        mPasswordEntry.addTextChangedListener(new TextWatcher() {
-            public void onTextChanged(CharSequence s, int start, int before, int count) {
-            }
-
-            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-            }
-
-            public void afterTextChanged(Editable s) {
-                if (mCallback != null) {
-                    mCallback.userActivity(0);
-                }
-            }
-        });
-        mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
-        mEcaView = findViewById(R.id.keyguard_selector_fade_container);
-        View bouncerFrameView = findViewById(R.id.keyguard_bouncer_frame);
-        if (bouncerFrameView != null) {
-            mBouncerFrame = bouncerFrameView.getBackground();
-        }
-    }
-
-    @Override
-    protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
-        // send focus to the password field
-        return mPasswordEntry.requestFocus(direction, previouslyFocusedRect);
-    }
-
-    /*
-     * Override this if you have a different string for "wrong password"
-     *
-     * Note that PIN/PUK have their own implementation of verifyPasswordAndUnlock and so don't need this
-     */
-    protected int getWrongPasswordStringId() {
-        return R.string.kg_wrong_password;
-    }
-
-    protected void verifyPasswordAndUnlock() {
-        String entry = mPasswordEntry.getText().toString();
-        if (mLockPatternUtils.checkPassword(entry)) {
-            mCallback.reportSuccessfulUnlockAttempt();
-            mCallback.dismiss(true);
-        } else if (entry.length() > MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT ) {
-            // to avoid accidental lockout, only count attempts that are long enough to be a
-            // real password. This may require some tweaking.
-            mCallback.reportFailedUnlockAttempt();
-            if (0 == (mCallback.getFailedAttempts()
-                    % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT)) {
-                long deadline = mLockPatternUtils.setLockoutAttemptDeadline();
-                handleAttemptLockout(deadline);
-            }
-            mSecurityMessageDisplay.setMessage(getWrongPasswordStringId(), true);
-        }
-        mPasswordEntry.setText("");
-    }
-
-    // Prevent user from using the PIN/Password entry until scheduled deadline.
-    protected void handleAttemptLockout(long elapsedRealtimeDeadline) {
-        mPasswordEntry.setEnabled(false);
-        long elapsedRealtime = SystemClock.elapsedRealtime();
-        new CountDownTimer(elapsedRealtimeDeadline - elapsedRealtime, 1000) {
-
-            @Override
-            public void onTick(long millisUntilFinished) {
-                int secondsRemaining = (int) (millisUntilFinished / 1000);
-                mSecurityMessageDisplay.setMessage(
-                        R.string.kg_too_many_failed_attempts_countdown, true, secondsRemaining);
-            }
-
-            @Override
-            public void onFinish() {
-                mSecurityMessageDisplay.setMessage("", false);
-                resetState();
-            }
-        }.start();
-    }
-
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        mCallback.userActivity(0);
-        return false;
-    }
-
-    @Override
-    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
-        // Check if this was the result of hitting the enter key
-        if (actionId == EditorInfo.IME_NULL || actionId == EditorInfo.IME_ACTION_DONE
-                || actionId == EditorInfo.IME_ACTION_NEXT) {
-            verifyPasswordAndUnlock();
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public boolean needsInput() {
-        return false;
-    }
-
-    @Override
-    public void onPause() {
-
-    }
-
-    @Override
-    public void onResume(int reason) {
-        reset();
-    }
-
-    @Override
-    public KeyguardSecurityCallback getCallback() {
-        return mCallback;
-    }
-
-    @Override
-    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-        if (mCallback != null) {
-            mCallback.userActivity(KeyguardViewManager.DIGIT_PRESS_WAKE_MILLIS);
-        }
-    }
-
-    @Override
-    public void onTextChanged(CharSequence s, int start, int before, int count) {
-    }
-
-    @Override
-    public void afterTextChanged(Editable s) {
-    }
-
-    // Cause a VIRTUAL_KEY vibration
-    public void doHapticKeyClick() {
-        if (mEnableHaptics) {
-            performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
-                    HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING
-                    | HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
-        }
-    }
-
-    @Override
-    public void showBouncer(int duration) {
-        KeyguardSecurityViewHelper.
-                showBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration);
-    }
-
-    @Override
-    public void hideBouncer(int duration) {
-        KeyguardSecurityViewHelper.
-                hideBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration);
-    }
-}
-
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAccountView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAccountView.java
deleted file mode 100644
index e0e7128..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAccountView.java
+++ /dev/null
@@ -1,333 +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.internal.policy.impl.keyguard;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.accounts.AccountManagerCallback;
-import android.accounts.AccountManagerFuture;
-import android.accounts.AuthenticatorException;
-import android.accounts.OperationCanceledException;
-import android.app.Dialog;
-import android.app.ProgressDialog;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.text.Editable;
-import android.text.InputFilter;
-import android.text.LoginFilter;
-import android.text.TextWatcher;
-import android.util.AttributeSet;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.WindowManager;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.LinearLayout;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.R;
-
-import java.io.IOException;
-
-/**
- * When the user forgets their password a bunch of times, we fall back on their
- * account's login/password to unlock the phone (and reset their lock pattern).
- */
-public class KeyguardAccountView extends LinearLayout implements KeyguardSecurityView,
-        View.OnClickListener, TextWatcher {
-    private static final int AWAKE_POKE_MILLIS = 30000;
-    private static final String LOCK_PATTERN_PACKAGE = "com.android.settings";
-    private static final String LOCK_PATTERN_CLASS = LOCK_PATTERN_PACKAGE + ".ChooseLockGeneric";
-
-    private KeyguardSecurityCallback mCallback;
-    private LockPatternUtils mLockPatternUtils;
-    private EditText mLogin;
-    private EditText mPassword;
-    private Button mOk;
-    public boolean mEnableFallback;
-    private SecurityMessageDisplay mSecurityMessageDisplay;
-
-    /**
-     * Shown while making asynchronous check of password.
-     */
-    private ProgressDialog mCheckingDialog;
-
-    public KeyguardAccountView(Context context) {
-        this(context, null, 0);
-    }
-
-    public KeyguardAccountView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public KeyguardAccountView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        mLockPatternUtils = new LockPatternUtils(getContext());
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-
-        mLogin = (EditText) findViewById(R.id.login);
-        mLogin.setFilters(new InputFilter[] { new LoginFilter.UsernameFilterGeneric() } );
-        mLogin.addTextChangedListener(this);
-
-        mPassword = (EditText) findViewById(R.id.password);
-        mPassword.addTextChangedListener(this);
-
-        mOk = (Button) findViewById(R.id.ok);
-        mOk.setOnClickListener(this);
-
-        mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
-        reset();
-    }
-
-    public void setKeyguardCallback(KeyguardSecurityCallback callback) {
-        mCallback = callback;
-    }
-
-    public void setLockPatternUtils(LockPatternUtils utils) {
-        mLockPatternUtils = utils;
-    }
-
-    public KeyguardSecurityCallback getCallback() {
-        return mCallback;
-    }
-
-
-    public void afterTextChanged(Editable s) {
-    }
-
-    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-    }
-
-    public void onTextChanged(CharSequence s, int start, int before, int count) {
-        if (mCallback != null) {
-            mCallback.userActivity(AWAKE_POKE_MILLIS);
-        }
-    }
-
-    @Override
-    protected boolean onRequestFocusInDescendants(int direction,
-            Rect previouslyFocusedRect) {
-        // send focus to the login field
-        return mLogin.requestFocus(direction, previouslyFocusedRect);
-    }
-
-    public boolean needsInput() {
-        return true;
-    }
-
-    public void reset() {
-        // start fresh
-        mLogin.setText("");
-        mPassword.setText("");
-        mLogin.requestFocus();
-        boolean permLocked = mLockPatternUtils.isPermanentlyLocked();
-        mSecurityMessageDisplay.setMessage(permLocked ? R.string.kg_login_too_many_attempts :
-            R.string.kg_login_instructions, permLocked ? true : false);
-    }
-
-    /** {@inheritDoc} */
-    public void cleanUp() {
-        if (mCheckingDialog != null) {
-            mCheckingDialog.hide();
-        }
-        mCallback = null;
-        mLockPatternUtils = null;
-    }
-
-    public void onClick(View v) {
-        mCallback.userActivity(0);
-        if (v == mOk) {
-            asyncCheckPassword();
-        }
-    }
-
-    private void postOnCheckPasswordResult(final boolean success) {
-        // ensure this runs on UI thread
-        mLogin.post(new Runnable() {
-            public void run() {
-                if (success) {
-                    // clear out forgotten password
-                    mLockPatternUtils.setPermanentlyLocked(false);
-                    mLockPatternUtils.setLockPatternEnabled(false);
-                    mLockPatternUtils.saveLockPattern(null);
-
-                    // launch the 'choose lock pattern' activity so
-                    // the user can pick a new one if they want to
-                    Intent intent = new Intent();
-                    intent.setClassName(LOCK_PATTERN_PACKAGE, LOCK_PATTERN_CLASS);
-                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                    mContext.startActivityAsUser(intent,
-                            new UserHandle(mLockPatternUtils.getCurrentUser()));
-                    mCallback.reportSuccessfulUnlockAttempt();
-
-                    // dismiss keyguard
-                    mCallback.dismiss(true);
-                } else {
-                    mSecurityMessageDisplay.setMessage(R.string.kg_login_invalid_input, true);
-                    mPassword.setText("");
-                    mCallback.reportFailedUnlockAttempt();
-                }
-            }
-        });
-    }
-
-    @Override
-    public boolean dispatchKeyEvent(KeyEvent event) {
-        if (event.getAction() == KeyEvent.ACTION_DOWN
-                && event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
-            if (mLockPatternUtils.isPermanentlyLocked()) {
-                mCallback.dismiss(false);
-            } else {
-                // TODO: mCallback.forgotPattern(false);
-            }
-            return true;
-        }
-        return super.dispatchKeyEvent(event);
-    }
-
-    /**
-     * Given the string the user entered in the 'username' field, find
-     * the stored account that they probably intended.  Prefer, in order:
-     *
-     *   - an exact match for what was typed, or
-     *   - a case-insensitive match for what was typed, or
-     *   - if they didn't include a domain, an exact match of the username, or
-     *   - if they didn't include a domain, a case-insensitive
-     *     match of the username.
-     *
-     * If there is a tie for the best match, choose neither --
-     * the user needs to be more specific.
-     *
-     * @return an account name from the database, or null if we can't
-     * find a single best match.
-     */
-    private Account findIntendedAccount(String username) {
-        Account[] accounts = AccountManager.get(mContext).getAccountsByTypeAsUser("com.google",
-                new UserHandle(mLockPatternUtils.getCurrentUser()));
-
-        // Try to figure out which account they meant if they
-        // typed only the username (and not the domain), or got
-        // the case wrong.
-
-        Account bestAccount = null;
-        int bestScore = 0;
-        for (Account a: accounts) {
-            int score = 0;
-            if (username.equals(a.name)) {
-                score = 4;
-            } else if (username.equalsIgnoreCase(a.name)) {
-                score = 3;
-            } else if (username.indexOf('@') < 0) {
-                int i = a.name.indexOf('@');
-                if (i >= 0) {
-                    String aUsername = a.name.substring(0, i);
-                    if (username.equals(aUsername)) {
-                        score = 2;
-                    } else if (username.equalsIgnoreCase(aUsername)) {
-                        score = 1;
-                    }
-                }
-            }
-            if (score > bestScore) {
-                bestAccount = a;
-                bestScore = score;
-            } else if (score == bestScore) {
-                bestAccount = null;
-            }
-        }
-        return bestAccount;
-    }
-
-    private void asyncCheckPassword() {
-        mCallback.userActivity(AWAKE_POKE_MILLIS);
-        final String login = mLogin.getText().toString();
-        final String password = mPassword.getText().toString();
-        Account account = findIntendedAccount(login);
-        if (account == null) {
-            postOnCheckPasswordResult(false);
-            return;
-        }
-        getProgressDialog().show();
-        Bundle options = new Bundle();
-        options.putString(AccountManager.KEY_PASSWORD, password);
-        AccountManager.get(mContext).confirmCredentialsAsUser(account, options, null /* activity */,
-                new AccountManagerCallback<Bundle>() {
-            public void run(AccountManagerFuture<Bundle> future) {
-                try {
-                    mCallback.userActivity(AWAKE_POKE_MILLIS);
-                    final Bundle result = future.getResult();
-                    final boolean verified = result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT);
-                    postOnCheckPasswordResult(verified);
-                } catch (OperationCanceledException e) {
-                    postOnCheckPasswordResult(false);
-                } catch (IOException e) {
-                    postOnCheckPasswordResult(false);
-                } catch (AuthenticatorException e) {
-                    postOnCheckPasswordResult(false);
-                } finally {
-                    mLogin.post(new Runnable() {
-                        public void run() {
-                            getProgressDialog().hide();
-                        }
-                    });
-                }
-            }
-        }, null /* handler */, new UserHandle(mLockPatternUtils.getCurrentUser()));
-    }
-
-    private Dialog getProgressDialog() {
-        if (mCheckingDialog == null) {
-            mCheckingDialog = new ProgressDialog(mContext);
-            mCheckingDialog.setMessage(
-                    mContext.getString(R.string.kg_login_checking_password));
-            mCheckingDialog.setIndeterminate(true);
-            mCheckingDialog.setCancelable(false);
-            mCheckingDialog.getWindow().setType(
-                    WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
-        }
-        return mCheckingDialog;
-    }
-
-    @Override
-    public void onPause() {
-
-    }
-
-    @Override
-    public void onResume(int reason) {
-        reset();
-    }
-
-    @Override
-    public void showUsabilityHint() {
-    }
-
-    @Override
-    public void showBouncer(int duration) {
-    }
-
-    @Override
-    public void hideBouncer(int duration) {
-    }
-}
-
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardActivityLauncher.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardActivityLauncher.java
deleted file mode 100644
index 6539db3..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardActivityLauncher.java
+++ /dev/null
@@ -1,273 +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.internal.policy.impl.keyguard;
-
-import android.app.ActivityManagerNative;
-import android.app.ActivityOptions;
-import android.app.IActivityManager.WaitResult;
-import android.appwidget.AppWidgetManager;
-import android.appwidget.AppWidgetProviderInfo;
-import android.content.ActivityNotFoundException;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.provider.MediaStore;
-import android.util.Log;
-import android.view.WindowManager;
-
-import com.android.internal.policy.impl.keyguard.KeyguardHostView.OnDismissAction;
-import com.android.internal.widget.LockPatternUtils;
-
-import java.util.List;
-
-public abstract class KeyguardActivityLauncher {
-    private static final String TAG = KeyguardActivityLauncher.class.getSimpleName();
-    private static final boolean DEBUG = KeyguardHostView.DEBUG;
-    private static final String META_DATA_KEYGUARD_LAYOUT = "com.android.keyguard.layout";
-    private static final Intent SECURE_CAMERA_INTENT =
-            new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE)
-                    .addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-    private static final Intent INSECURE_CAMERA_INTENT =
-            new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
-
-    abstract Context getContext();
-
-    abstract KeyguardSecurityCallback getCallback();
-
-    abstract LockPatternUtils getLockPatternUtils();
-
-    public static class CameraWidgetInfo {
-        public String contextPackage;
-        public int layoutId;
-    }
-
-    public CameraWidgetInfo getCameraWidgetInfo() {
-        CameraWidgetInfo info = new CameraWidgetInfo();
-        Intent intent = getCameraIntent();
-        PackageManager packageManager = getContext().getPackageManager();
-        final List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser(
-                intent, PackageManager.MATCH_DEFAULT_ONLY, getLockPatternUtils().getCurrentUser());
-        if (appList.size() == 0) {
-            if (DEBUG) Log.d(TAG, "getCameraWidgetInfo(): Nothing found");
-            return null;
-        }
-        ResolveInfo resolved = packageManager.resolveActivityAsUser(intent,
-                PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA,
-                getLockPatternUtils().getCurrentUser());
-        if (DEBUG) Log.d(TAG, "getCameraWidgetInfo(): resolved: " + resolved);
-        if (wouldLaunchResolverActivity(resolved, appList)) {
-            if (DEBUG) Log.d(TAG, "getCameraWidgetInfo(): Would launch resolver");
-            return info;
-        }
-        if (resolved == null || resolved.activityInfo == null) {
-            return null;
-        }
-        if (resolved.activityInfo.metaData == null || resolved.activityInfo.metaData.isEmpty()) {
-            if (DEBUG) Log.d(TAG, "getCameraWidgetInfo(): no metadata found");
-            return info;
-        }
-        int layoutId = resolved.activityInfo.metaData.getInt(META_DATA_KEYGUARD_LAYOUT);
-        if (layoutId == 0) {
-            if (DEBUG) Log.d(TAG, "getCameraWidgetInfo(): no layout specified");
-            return info;
-        }
-        info.contextPackage = resolved.activityInfo.packageName;
-        info.layoutId = layoutId;
-        return info;
-    }
-
-    public void launchCamera(Handler worker, Runnable onSecureCameraStarted) {
-        LockPatternUtils lockPatternUtils = getLockPatternUtils();
-        if (lockPatternUtils.isSecure()) {
-            // Launch the secure version of the camera
-            if (wouldLaunchResolverActivity(SECURE_CAMERA_INTENT)) {
-                // TODO: Show disambiguation dialog instead.
-                // For now, we'll treat this like launching any other app from secure keyguard.
-                // When they do, user sees the system's ResolverActivity which lets them choose
-                // which secure camera to use.
-                launchActivity(SECURE_CAMERA_INTENT, false, false, null, null);
-            } else {
-                launchActivity(SECURE_CAMERA_INTENT, true, false, worker, onSecureCameraStarted);
-            }
-        } else {
-            // Launch the normal camera
-            launchActivity(INSECURE_CAMERA_INTENT, false, false, null, null);
-        }
-    }
-
-    public void launchWidgetPicker(int appWidgetId) {
-        Intent pickIntent = new Intent(AppWidgetManager.ACTION_KEYGUARD_APPWIDGET_PICK);
-
-        pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
-        pickIntent.putExtra(AppWidgetManager.EXTRA_CUSTOM_SORT, false);
-        pickIntent.putExtra(AppWidgetManager.EXTRA_CATEGORY_FILTER,
-                AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD);
-
-        Bundle options = new Bundle();
-        options.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,
-                AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD);
-        pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);
-        pickIntent.addFlags(
-                Intent.FLAG_ACTIVITY_NEW_TASK
-                | Intent.FLAG_ACTIVITY_SINGLE_TOP
-                | Intent.FLAG_ACTIVITY_CLEAR_TOP
-                | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-
-        launchActivity(pickIntent, false, false, null, null);
-    }
-
-    /**
-     * Launches the said intent for the current foreground user.
-     *
-     * @param intent
-     * @param showsWhileLocked true if the activity can be run on top of keyguard.
-     *   See {@link WindowManager#FLAG_SHOW_WHEN_LOCKED}
-     * @param useDefaultAnimations true if default transitions should be used, else suppressed.
-     * @param worker if supplied along with onStarted, used to launch the blocking activity call.
-     * @param onStarted if supplied along with worker, called after activity is started.
-     */
-    public void launchActivity(final Intent intent,
-            boolean showsWhileLocked,
-            boolean useDefaultAnimations,
-            final Handler worker,
-            final Runnable onStarted) {
-
-        final Context context = getContext();
-        final Bundle animation = useDefaultAnimations ? null
-                : ActivityOptions.makeCustomAnimation(context, 0, 0).toBundle();
-        launchActivityWithAnimation(intent, showsWhileLocked, animation, worker, onStarted);
-    }
-
-    public void launchActivityWithAnimation(final Intent intent,
-            boolean showsWhileLocked,
-            final Bundle animation,
-            final Handler worker,
-            final Runnable onStarted) {
-
-        LockPatternUtils lockPatternUtils = getLockPatternUtils();
-        intent.addFlags(
-                Intent.FLAG_ACTIVITY_NEW_TASK
-                | Intent.FLAG_ACTIVITY_SINGLE_TOP
-                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
-        boolean isSecure = lockPatternUtils.isSecure();
-        if (!isSecure || showsWhileLocked) {
-            if (!isSecure) {
-                dismissKeyguardOnNextActivity();
-            }
-            try {
-                if (DEBUG) Log.d(TAG, String.format("Starting activity for intent %s at %s",
-                        intent, SystemClock.uptimeMillis()));
-                startActivityForCurrentUser(intent, animation, worker, onStarted);
-            } catch (ActivityNotFoundException e) {
-                Log.w(TAG, "Activity not found for intent + " + intent.getAction());
-            }
-        } else {
-            // Create a runnable to start the activity and ask the user to enter their
-            // credentials.
-            KeyguardSecurityCallback callback = getCallback();
-            callback.setOnDismissAction(new OnDismissAction() {
-                @Override
-                public boolean onDismiss() {
-                    dismissKeyguardOnNextActivity();
-                    startActivityForCurrentUser(intent, animation, worker, onStarted);
-                    return true;
-                }
-            });
-            callback.dismiss(false);
-        }
-    }
-
-    private void dismissKeyguardOnNextActivity() {
-        try {
-            ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
-        } catch (RemoteException e) {
-            Log.w(TAG, "can't dismiss keyguard on launch");
-        }
-    }
-
-    private void startActivityForCurrentUser(final Intent intent, final Bundle options,
-            Handler worker, final Runnable onStarted) {
-        final UserHandle user = new UserHandle(UserHandle.USER_CURRENT);
-        if (worker == null || onStarted == null) {
-            getContext().startActivityAsUser(intent, options, user);
-            return;
-        }
-        // if worker + onStarted are supplied, run blocking activity launch call in the background
-        worker.post(new Runnable(){
-            @Override
-            public void run() {
-                try {
-                    WaitResult result = ActivityManagerNative.getDefault().startActivityAndWait(
-                            null /*caller*/,
-                            null /*caller pkg*/,
-                            intent,
-                            intent.resolveTypeIfNeeded(getContext().getContentResolver()),
-                            null /*resultTo*/,
-                            null /*resultWho*/,
-                            0 /*requestCode*/,
-                            Intent.FLAG_ACTIVITY_NEW_TASK,
-                            null /*profileFile*/,
-                            null /*profileFd*/,
-                            options,
-                            user.getIdentifier());
-                    if (DEBUG) Log.d(TAG, String.format("waitResult[%s,%s,%s,%s] at %s",
-                            result.result, result.thisTime, result.totalTime, result.who,
-                            SystemClock.uptimeMillis()));
-                } catch (RemoteException e) {
-                    Log.w(TAG, "Error starting activity", e);
-                    return;
-                }
-                try {
-                    onStarted.run();
-                } catch (Throwable t) {
-                    Log.w(TAG, "Error running onStarted callback", t);
-                }
-            }});
-    }
-
-    private Intent getCameraIntent() {
-        return getLockPatternUtils().isSecure() ? SECURE_CAMERA_INTENT : INSECURE_CAMERA_INTENT;
-    }
-
-    private boolean wouldLaunchResolverActivity(Intent intent) {
-        PackageManager packageManager = getContext().getPackageManager();
-        ResolveInfo resolved = packageManager.resolveActivityAsUser(intent,
-                PackageManager.MATCH_DEFAULT_ONLY, getLockPatternUtils().getCurrentUser());
-        List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser(
-                intent, PackageManager.MATCH_DEFAULT_ONLY, getLockPatternUtils().getCurrentUser());
-        return wouldLaunchResolverActivity(resolved, appList);
-    }
-
-    private boolean wouldLaunchResolverActivity(ResolveInfo resolved, List<ResolveInfo> appList) {
-        // If the list contains the above resolved activity, then it can't be
-        // ResolverActivity itself.
-        for (int i = 0; i < appList.size(); i++) {
-            ResolveInfo tmp = appList.get(i);
-            if (tmp.activityInfo.name.equals(resolved.activityInfo.name)
-                    && tmp.activityInfo.packageName.equals(resolved.activityInfo.packageName)) {
-                return false;
-            }
-        }
-        return true;
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardCircleFramedDrawable.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardCircleFramedDrawable.java
deleted file mode 100644
index fe32099..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardCircleFramedDrawable.java
+++ /dev/null
@@ -1,175 +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.internal.policy.impl.keyguard;
-
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.ColorFilter;
-import android.graphics.Paint;
-import android.graphics.Path;
-import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffXfermode;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.drawable.Drawable;
-
-import android.util.Log;
-
-class KeyguardCircleFramedDrawable extends Drawable {
-
-    private final Bitmap mBitmap;
-    private final int mSize;
-    private final Paint mPaint;
-    private final float mShadowRadius;
-    private final float mStrokeWidth;
-    private final int mFrameColor;
-    private final int mHighlightColor;
-    private final int mFrameShadowColor;
-
-    private float mScale;
-    private Path mFramePath;
-    private Rect mSrcRect;
-    private RectF mDstRect;
-    private RectF mFrameRect;
-    private boolean mPressed;
-
-    public KeyguardCircleFramedDrawable(Bitmap bitmap, int size,
-            int frameColor, float strokeWidth,
-            int frameShadowColor, float shadowRadius,
-            int highlightColor) {
-        super();
-        mSize = size;
-        mShadowRadius = shadowRadius;
-        mFrameColor = frameColor;
-        mFrameShadowColor = frameShadowColor;
-        mStrokeWidth = strokeWidth;
-        mHighlightColor = highlightColor;
-
-        mBitmap = Bitmap.createBitmap(mSize, mSize, Bitmap.Config.ARGB_8888);
-        final Canvas canvas = new Canvas(mBitmap);
-
-        final int width = bitmap.getWidth();
-        final int height = bitmap.getHeight();
-        final int square = Math.min(width, height);
-
-        final Rect cropRect = new Rect((width - square) / 2, (height - square) / 2, square, square);
-        final RectF circleRect = new RectF(0f, 0f, mSize, mSize);
-        circleRect.inset(mStrokeWidth / 2f, mStrokeWidth / 2f);
-        circleRect.inset(mShadowRadius, mShadowRadius);
-
-        final Path fillPath = new Path();
-        fillPath.addArc(circleRect, 0f, 360f);
-
-        canvas.drawColor(0, PorterDuff.Mode.CLEAR);
-
-        // opaque circle matte
-        mPaint = new Paint();
-        mPaint.setAntiAlias(true);
-        mPaint.setColor(Color.BLACK);
-        mPaint.setStyle(Paint.Style.FILL);
-        canvas.drawPath(fillPath, mPaint);
-
-        // mask in the icon where the bitmap is opaque
-        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
-        canvas.drawBitmap(bitmap, cropRect, circleRect, mPaint);
-
-        // prepare paint for frame drawing
-        mPaint.setXfermode(null);
-
-        mScale = 1f;
-
-        mSrcRect = new Rect(0, 0, mSize, mSize);
-        mDstRect = new RectF(0, 0, mSize, mSize);
-        mFrameRect = new RectF(mDstRect);
-        mFramePath = new Path();
-    }
-
-    public void reset() {
-        mScale = 1f;
-        mPressed = false;
-    }
-
-    @Override
-    public void draw(Canvas canvas) {
-        // clear background
-        final float outside = Math.min(canvas.getWidth(), canvas.getHeight());
-        final float inside = mScale * outside;
-        final float pad = (outside - inside) / 2f;
-
-        mDstRect.set(pad, pad, outside - pad, outside - pad);
-        canvas.drawBitmap(mBitmap, mSrcRect, mDstRect, null);
-
-        mFrameRect.set(mDstRect);
-        mFrameRect.inset(mStrokeWidth / 2f, mStrokeWidth / 2f);
-        mFrameRect.inset(mShadowRadius, mShadowRadius);
-
-        mFramePath.reset();
-        mFramePath.addArc(mFrameRect, 0f, 360f);
-
-        // white frame
-        if (mPressed) {
-            mPaint.setStyle(Paint.Style.FILL);
-            mPaint.setColor(Color.argb((int) (0.33f * 255),
-                            Color.red(mHighlightColor),
-                            Color.green(mHighlightColor),
-                            Color.blue(mHighlightColor)));
-            canvas.drawPath(mFramePath, mPaint);
-        }
-        mPaint.setStrokeWidth(mStrokeWidth);
-        mPaint.setStyle(Paint.Style.STROKE);
-        mPaint.setColor(mPressed ? mHighlightColor : mFrameColor);
-        mPaint.setShadowLayer(mShadowRadius, 0f, 0f, mFrameShadowColor);
-        canvas.drawPath(mFramePath, mPaint);
-    }
-
-    public void setScale(float scale) {
-        mScale = scale;
-    }
-
-    public float getScale() {
-        return mScale;
-    }
-
-    public void setPressed(boolean pressed) {
-        mPressed = pressed;
-    }
-
-    @Override
-    public int getOpacity() {
-        return PixelFormat.TRANSLUCENT;
-    }
-
-    @Override
-    public void setAlpha(int alpha) {
-    }
-
-    @Override
-    public void setColorFilter(ColorFilter cf) {
-    }
-
-    public boolean verifyParams(float iconSize, int frameColor, float stroke,
-            int frameShadowColor, float shadowRadius, int highlightColor) {
-        return mSize == iconSize
-                && mFrameColor == frameColor
-                && mStrokeWidth == stroke
-                && mFrameShadowColor == frameShadowColor
-                && mShadowRadius == shadowRadius
-                && mHighlightColor == highlightColor;
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java
deleted file mode 100644
index 7315aad..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java
+++ /dev/null
@@ -1,317 +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.internal.policy.impl.keyguard;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.os.PowerManager;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.telephony.TelephonyManager;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.IRotationWatcher;
-import android.view.IWindowManager;
-import android.view.View;
-import android.widget.ImageButton;
-import android.widget.LinearLayout;
-
-import com.android.internal.R;
-import com.android.internal.widget.LockPatternUtils;
-
-import java.lang.Math;
-
-public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecurityView {
-
-    private static final String TAG = "FULKeyguardFaceUnlockView";
-    private static final boolean DEBUG = false;
-    private KeyguardSecurityCallback mKeyguardSecurityCallback;
-    private LockPatternUtils mLockPatternUtils;
-    private BiometricSensorUnlock mBiometricUnlock;
-    private View mFaceUnlockAreaView;
-    private ImageButton mCancelButton;
-    private SecurityMessageDisplay mSecurityMessageDisplay;
-    private View mEcaView;
-    private Drawable mBouncerFrame;
-
-    private boolean mIsShowing = false;
-    private final Object mIsShowingLock = new Object();
-
-    private int mLastRotation;
-    private boolean mWatchingRotation;
-    private final IWindowManager mWindowManager =
-            IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
-
-    private final IRotationWatcher mRotationWatcher = new IRotationWatcher.Stub() {
-        public void onRotationChanged(int rotation) {
-            if (DEBUG) Log.d(TAG, "onRotationChanged(): " + mLastRotation + "->" + rotation);
-
-            // If the difference between the new rotation value and the previous rotation value is
-            // equal to 2, the rotation change was 180 degrees.  This stops the biometric unlock
-            // and starts it in the new position.  This is not performed for 90 degree rotations
-            // since a 90 degree rotation is a configuration change, which takes care of this for
-            // us.
-            if (Math.abs(rotation - mLastRotation) == 2) {
-                if (mBiometricUnlock != null) {
-                    mBiometricUnlock.stop();
-                    maybeStartBiometricUnlock();
-                }
-            }
-            mLastRotation = rotation;
-        }
-    };
-
-    public KeyguardFaceUnlockView(Context context) {
-        this(context, null);
-    }
-
-    public KeyguardFaceUnlockView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-
-        initializeBiometricUnlockView();
-
-        mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
-        mEcaView = findViewById(R.id.keyguard_selector_fade_container);
-        View bouncerFrameView = findViewById(R.id.keyguard_bouncer_frame);
-        if (bouncerFrameView != null) {
-            mBouncerFrame = bouncerFrameView.getBackground();
-        }
-    }
-
-    @Override
-    public void setKeyguardCallback(KeyguardSecurityCallback callback) {
-        mKeyguardSecurityCallback = callback;
-        // TODO: formalize this in the interface or factor it out
-        ((FaceUnlock)mBiometricUnlock).setKeyguardCallback(callback);
-    }
-
-    @Override
-    public void setLockPatternUtils(LockPatternUtils utils) {
-        mLockPatternUtils = utils;
-    }
-
-    @Override
-    public void reset() {
-
-    }
-
-    @Override
-    public void onDetachedFromWindow() {
-        if (DEBUG) Log.d(TAG, "onDetachedFromWindow()");
-        if (mBiometricUnlock != null) {
-            mBiometricUnlock.stop();
-        }
-        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateCallback);
-        if (mWatchingRotation) {
-            try {
-                mWindowManager.removeRotationWatcher(mRotationWatcher);
-                mWatchingRotation = false;
-            } catch (RemoteException e) {
-                Log.e(TAG, "Remote exception when removing rotation watcher");
-            }
-        }
-    }
-
-    @Override
-    public void onPause() {
-        if (DEBUG) Log.d(TAG, "onPause()");
-        if (mBiometricUnlock != null) {
-            mBiometricUnlock.stop();
-        }
-        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateCallback);
-        if (mWatchingRotation) {
-            try {
-                mWindowManager.removeRotationWatcher(mRotationWatcher);
-                mWatchingRotation = false;
-            } catch (RemoteException e) {
-                Log.e(TAG, "Remote exception when removing rotation watcher");
-            }
-        }
-    }
-
-    @Override
-    public void onResume(int reason) {
-        if (DEBUG) Log.d(TAG, "onResume()");
-        mIsShowing = KeyguardUpdateMonitor.getInstance(mContext).isKeyguardVisible();
-        if (!KeyguardUpdateMonitor.getInstance(mContext).isSwitchingUser()) {
-          maybeStartBiometricUnlock();
-        }
-        KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateCallback);
-
-        // Registers a callback which handles stopping the biometric unlock and restarting it in
-        // the new position for a 180 degree rotation change.
-        if (!mWatchingRotation) {
-            try {
-                mLastRotation = mWindowManager.watchRotation(mRotationWatcher);
-                mWatchingRotation = true;
-            } catch (RemoteException e) {
-                Log.e(TAG, "Remote exception when adding rotation watcher");
-            }
-        }
-    }
-
-    @Override
-    public boolean needsInput() {
-        return false;
-    }
-
-    @Override
-    public KeyguardSecurityCallback getCallback() {
-        return mKeyguardSecurityCallback;
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int l, int t, int r, int b) {
-        super.onLayout(changed, l, t, r, b);
-        mBiometricUnlock.initializeView(mFaceUnlockAreaView);
-    }
-
-    private void initializeBiometricUnlockView() {
-        if (DEBUG) Log.d(TAG, "initializeBiometricUnlockView()");
-        mFaceUnlockAreaView = findViewById(R.id.face_unlock_area_view);
-        if (mFaceUnlockAreaView != null) {
-            mBiometricUnlock = new FaceUnlock(mContext);
-
-            mCancelButton = (ImageButton) findViewById(R.id.face_unlock_cancel_button);
-            mCancelButton.setOnClickListener(new OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    mBiometricUnlock.stopAndShowBackup();
-                }
-            });
-        } else {
-            Log.w(TAG, "Couldn't find biometric unlock view");
-        }
-    }
-
-    /**
-     * Starts the biometric unlock if it should be started based on a number of factors.  If it
-     * should not be started, it either goes to the back up, or remains showing to prepare for
-     * it being started later.
-     */
-    private void maybeStartBiometricUnlock() {
-        if (DEBUG) Log.d(TAG, "maybeStartBiometricUnlock()");
-        if (mBiometricUnlock != null) {
-            KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
-            final boolean backupIsTimedOut = (
-                    monitor.getFailedUnlockAttempts() >=
-                    LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT);
-            PowerManager powerManager = (PowerManager) mContext.getSystemService(
-                    Context.POWER_SERVICE);
-
-            boolean isShowing;
-            synchronized(mIsShowingLock) {
-                isShowing = mIsShowing;
-            }
-
-            // Don't start it if the screen is off or if it's not showing, but keep this view up
-            // because we want it here and ready for when the screen turns on or when it does start
-            // showing.
-            if (!powerManager.isScreenOn() || !isShowing) {
-                mBiometricUnlock.stop(); // It shouldn't be running but calling this can't hurt.
-                return;
-            }
-
-            // Although these same conditions are handled in KeyguardSecurityModel, they are still
-            // necessary here.  When a tablet is rotated 90 degrees, a configuration change is
-            // triggered and everything is torn down and reconstructed.  That means
-            // KeyguardSecurityModel gets a chance to take care of the logic and doesn't even
-            // reconstruct KeyguardFaceUnlockView if the biometric unlock should be suppressed.
-            // However, for a 180 degree rotation, no configuration change is triggered, so only
-            // the logic here is capable of suppressing Face Unlock.
-            if (monitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE
-                    && monitor.isAlternateUnlockEnabled()
-                    && !monitor.getMaxBiometricUnlockAttemptsReached()
-                    && !backupIsTimedOut) {
-                mBiometricUnlock.start();
-            } else {
-                mBiometricUnlock.stopAndShowBackup();
-            }
-        }
-    }
-
-    KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() {
-        // We need to stop the biometric unlock when a phone call comes in
-        @Override
-        public void onPhoneStateChanged(int phoneState) {
-            if (DEBUG) Log.d(TAG, "onPhoneStateChanged(" + phoneState + ")");
-            if (phoneState == TelephonyManager.CALL_STATE_RINGING) {
-                if (mBiometricUnlock != null) {
-                    mBiometricUnlock.stopAndShowBackup();
-                }
-            }
-        }
-
-        @Override
-        public void onUserSwitching(int userId) {
-            if (DEBUG) Log.d(TAG, "onUserSwitched(" + userId + ")");
-            if (mBiometricUnlock != null) {
-                mBiometricUnlock.stop();
-            }
-            // No longer required; static value set by KeyguardViewMediator
-            // mLockPatternUtils.setCurrentUser(userId);
-        }
-
-        @Override
-        public void onUserSwitchComplete(int userId) {
-            if (DEBUG) Log.d(TAG, "onUserSwitchComplete(" + userId + ")");
-            if (mBiometricUnlock != null) {
-                maybeStartBiometricUnlock();
-            }
-        }
-
-        @Override
-        public void onKeyguardVisibilityChanged(boolean showing) {
-            if (DEBUG) Log.d(TAG, "onKeyguardVisibilityChanged(" + showing + ")");
-            boolean wasShowing = false;
-            synchronized(mIsShowingLock) {
-                wasShowing = mIsShowing;
-                mIsShowing = showing;
-            }
-            PowerManager powerManager = (PowerManager) mContext.getSystemService(
-                    Context.POWER_SERVICE);
-            if (mBiometricUnlock != null) {
-                if (!showing && wasShowing) {
-                    mBiometricUnlock.stop();
-                } else if (showing && powerManager.isScreenOn() && !wasShowing) {
-                    maybeStartBiometricUnlock();
-                }
-            }
-        }
-    };
-
-    @Override
-    public void showUsabilityHint() {
-    }
-
-    @Override
-    public void showBouncer(int duration) {
-        KeyguardSecurityViewHelper.
-                showBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration);
-    }
-
-    @Override
-    public void hideBouncer(int duration) {
-        KeyguardSecurityViewHelper.
-                hideBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration);
-    }
-
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardGlowStripView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardGlowStripView.java
deleted file mode 100644
index e1c95f0..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardGlowStripView.java
+++ /dev/null
@@ -1,139 +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.internal.policy.impl.keyguard;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.view.animation.DecelerateInterpolator;
-import android.view.animation.Interpolator;
-import android.view.animation.LinearInterpolator;
-import android.widget.LinearLayout;
-
-import com.android.internal.R;
-
-/**
- * A layout which animates a strip of horizontal, pulsing dots on request. This is used
- * to indicate the presence of pages to the left / right.
- */
-public class KeyguardGlowStripView extends LinearLayout {
-    private static final int DURATION = 500;
-
-    private static final float SLIDING_WINDOW_SIZE = 0.4f;
-    private int mDotStripTop;
-    private int mHorizontalDotGap;
-
-    private int mDotSize;
-    private int mNumDots;
-    private Drawable mDotDrawable;
-    private boolean mLeftToRight = true;
-
-    private float mAnimationProgress = 0f;
-    private boolean mDrawDots = false;
-    private ValueAnimator mAnimator;
-    private Interpolator mDotAlphaInterpolator = new DecelerateInterpolator(0.5f);
-
-    public KeyguardGlowStripView(Context context) {
-        this(context, null, 0);
-    }
-
-    public KeyguardGlowStripView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public KeyguardGlowStripView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.KeyguardGlowStripView);
-        mDotSize = a.getDimensionPixelSize(R.styleable.KeyguardGlowStripView_dotSize, mDotSize);
-        mNumDots = a.getInt(R.styleable.KeyguardGlowStripView_numDots, mNumDots);
-        mDotDrawable = a.getDrawable(R.styleable.KeyguardGlowStripView_glowDot);
-        mLeftToRight = a.getBoolean(R.styleable.KeyguardGlowStripView_leftToRight, mLeftToRight);
-    }
-
-    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
-        int availableWidth = w - getPaddingLeft() - getPaddingRight();
-        mHorizontalDotGap = (availableWidth - mDotSize * mNumDots) /  (mNumDots - 1);
-        mDotStripTop = getPaddingTop();
-        invalidate();
-    }
-
-    @Override
-    protected void dispatchDraw(Canvas canvas) {
-        super.dispatchDraw(canvas);
-
-        if (!mDrawDots) return;
-
-        int xOffset = getPaddingLeft();
-        mDotDrawable.setBounds(0, 0, mDotSize, mDotSize);
-
-        for (int i = 0; i < mNumDots; i++) {
-            // We fudge the relative position to provide a fade in of the first dot and a fade
-            // out of the final dot.
-            float relativeDotPosition = SLIDING_WINDOW_SIZE / 2 + ((1.0f * i) / (mNumDots - 1)) *
-                    (1 - SLIDING_WINDOW_SIZE);
-            float distance = Math.abs(relativeDotPosition - mAnimationProgress);
-            float alpha = Math.max(0, 1 - distance / (SLIDING_WINDOW_SIZE / 2));
-
-            alpha = mDotAlphaInterpolator.getInterpolation(alpha);
-
-            canvas.save();
-            canvas.translate(xOffset, mDotStripTop);
-            mDotDrawable.setAlpha((int) (alpha * 255));
-            mDotDrawable.draw(canvas);
-            canvas.restore();
-            xOffset += mDotSize + mHorizontalDotGap;
-        }
-    }
-
-    public void makeEmGo() {
-        if (mAnimator != null) {
-            mAnimator.cancel();
-        }
-        float from = mLeftToRight ? 0f : 1f;
-        float to = mLeftToRight ? 1f : 0f;
-        mAnimator = ValueAnimator.ofFloat(from, to);
-        mAnimator.setDuration(DURATION);
-        mAnimator.setInterpolator(new LinearInterpolator());
-        mAnimator.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                mDrawDots = false;
-                // make sure we draw one frame at the end with everything gone.
-                invalidate();
-            }
-
-            @Override
-            public void onAnimationStart(Animator animation) {
-                mDrawDots = true;
-            }
-        });
-        mAnimator.addUpdateListener(new AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator animation) {
-                mAnimationProgress = (Float) animation.getAnimatedValue();
-                invalidate();
-            }
-        });
-        mAnimator.start();
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
deleted file mode 100644
index c3077c7..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
+++ /dev/null
@@ -1,1684 +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.internal.policy.impl.keyguard;
-
-import android.app.Activity;
-import android.app.ActivityManager;
-import android.app.ActivityOptions;
-import android.app.AlertDialog;
-import android.app.SearchManager;
-import android.app.admin.DevicePolicyManager;
-import android.appwidget.AppWidgetHost;
-import android.appwidget.AppWidgetHostView;
-import android.appwidget.AppWidgetManager;
-import android.appwidget.AppWidgetProviderInfo;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentSender;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.UserInfo;
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.media.RemoteControlClient;
-import android.os.Looper;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.provider.Settings;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.Slog;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.WindowManager;
-import android.view.animation.AnimationUtils;
-import android.widget.RemoteViews.OnClickHandler;
-
-import com.android.internal.R;
-import com.android.internal.policy.impl.keyguard.KeyguardSecurityModel.SecurityMode;
-import com.android.internal.policy.impl.keyguard.KeyguardUpdateMonitor.DisplayClientState;
-import com.android.internal.widget.LockPatternUtils;
-
-import java.io.File;
-import java.util.List;
-
-public class KeyguardHostView extends KeyguardViewBase {
-    private static final String TAG = "KeyguardHostView";
-    // Transport control states.
-    static final int TRANSPORT_GONE = 0;
-    static final int TRANSPORT_INVISIBLE = 1;
-    static final int TRANSPORT_VISIBLE = 2;
-
-    private int mTransportState = TRANSPORT_GONE;
-
-    // Use this to debug all of keyguard
-    public static boolean DEBUG = KeyguardViewMediator.DEBUG;
-    public static boolean DEBUGXPORT = true; // debug music transport control
-
-    // Found in KeyguardAppWidgetPickActivity.java
-    static final int APPWIDGET_HOST_ID = 0x4B455947;
-
-    private final int MAX_WIDGETS = 5;
-
-    private AppWidgetHost mAppWidgetHost;
-    private AppWidgetManager mAppWidgetManager;
-    private KeyguardWidgetPager mAppWidgetContainer;
-    private KeyguardSecurityViewFlipper mSecurityViewContainer;
-    private KeyguardSelectorView mKeyguardSelectorView;
-    private KeyguardTransportControlView mTransportControl;
-    private boolean mIsVerifyUnlockOnly;
-    private boolean mEnableFallback; // TODO: This should get the value from KeyguardPatternView
-    private SecurityMode mCurrentSecuritySelection = SecurityMode.Invalid;
-    private int mAppWidgetToShow;
-
-    private boolean mCheckAppWidgetConsistencyOnBootCompleted = false;
-    private boolean mCleanupAppWidgetsOnBootCompleted = false;
-
-    protected OnDismissAction mDismissAction;
-
-    protected int mFailedAttempts;
-    private LockPatternUtils mLockPatternUtils;
-
-    private KeyguardSecurityModel mSecurityModel;
-    private KeyguardViewStateManager mViewStateManager;
-
-    private Rect mTempRect = new Rect();
-
-    private int mDisabledFeatures;
-
-    private boolean mCameraDisabled;
-
-    private boolean mSafeModeEnabled;
-
-    private boolean mUserSetupCompleted;
-
-    // User for whom this host view was created.  Final because we should never change the
-    // id without reconstructing an instance of KeyguardHostView. See note below...
-    private final int mUserId;
-
-    private KeyguardMultiUserSelectorView mKeyguardMultiUserSelectorView;
-
-    protected int mClientGeneration;
-
-    /*package*/ interface UserSwitcherCallback {
-        void hideSecurityView(int duration);
-        void showSecurityView();
-        void showUnlockHint();
-        void userActivity();
-    }
-
-    /*package*/ interface OnDismissAction {
-        /* returns true if the dismiss should be deferred */
-        boolean onDismiss();
-    }
-
-    public KeyguardHostView(Context context) {
-        this(context, null);
-    }
-
-    public KeyguardHostView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-
-        if (DEBUG) Log.e(TAG, "KeyguardHostView()");
-
-        mLockPatternUtils = new LockPatternUtils(context);
-
-        // Note: This depends on KeyguardHostView getting reconstructed every time the
-        // user switches, since mUserId will be used for the entire session.
-        // Once created, keyguard should *never* re-use this instance with another user.
-        // In other words, mUserId should never change - hence it's marked final.
-        mUserId = mLockPatternUtils.getCurrentUser();
-
-        DevicePolicyManager dpm =
-                (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
-        if (dpm != null) {
-            mDisabledFeatures = getDisabledFeatures(dpm);
-            mCameraDisabled = dpm.getCameraDisabled(null);
-        }
-
-        mSafeModeEnabled = LockPatternUtils.isSafeModeEnabled();
-
-        // These need to be created with the user context...
-        Context userContext = null;
-        try {
-            final String packageName = "system";
-            userContext = mContext.createPackageContextAsUser(packageName, 0,
-                    new UserHandle(mUserId));
-
-        } catch (NameNotFoundException e) {
-            e.printStackTrace();
-            // This should never happen, but it's better to have no widgets than to crash.
-            userContext = context;
-        }
-
-        mAppWidgetHost = new AppWidgetHost(userContext, APPWIDGET_HOST_ID, mOnClickHandler,
-                Looper.myLooper());
-
-        cleanupAppWidgetIds();
-
-        mAppWidgetManager = AppWidgetManager.getInstance(userContext);
-
-        mSecurityModel = new KeyguardSecurityModel(context);
-
-        mViewStateManager = new KeyguardViewStateManager(this);
-
-        mUserSetupCompleted = Settings.Secure.getIntForUser(mContext.getContentResolver(),
-                Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
-
-        // Ensure we have the current state *before* we call showAppropriateWidgetPage()
-        getInitialTransportState();
-
-        if (mSafeModeEnabled) {
-            Log.v(TAG, "Keyguard widgets disabled by safe mode");
-        }
-        if ((mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL) != 0) {
-            Log.v(TAG, "Keyguard widgets disabled by DPM");
-        }
-        if ((mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0) {
-            Log.v(TAG, "Keyguard secure camera disabled by DPM");
-        }
-    }
-
-    private void getInitialTransportState() {
-        DisplayClientState dcs = KeyguardUpdateMonitor.getInstance(mContext)
-                .getCachedDisplayClientState();
-        mTransportState = (dcs.clearing ? TRANSPORT_GONE :
-            (isMusicPlaying(dcs.playbackState) ? TRANSPORT_VISIBLE : TRANSPORT_INVISIBLE));
-
-        if (DEBUG) Log.v(TAG, "Initial transport state: "
-                + mTransportState + ", pbstate=" + dcs.playbackState);
-    }
-
-    private void cleanupAppWidgetIds() {
-        // Since this method may delete a widget (which we can't do until boot completed) we
-        // may have to defer it until after boot complete.
-        if (!KeyguardUpdateMonitor.getInstance(mContext).hasBootCompleted()) {
-            mCleanupAppWidgetsOnBootCompleted = true;
-            return;
-        }
-        if (!mSafeModeEnabled && !widgetsDisabledByDpm()) {
-            // Clean up appWidgetIds that are bound to lockscreen, but not actually used
-            // This is only to clean up after another bug: we used to not call
-            // deleteAppWidgetId when a user manually deleted a widget in keyguard. This code
-            // shouldn't have to run more than once per user. AppWidgetProviders rely on callbacks
-            // that are triggered by deleteAppWidgetId, which is why we're doing this
-            int[] appWidgetIdsInKeyguardSettings = mLockPatternUtils.getAppWidgets();
-            int[] appWidgetIdsBoundToHost = mAppWidgetHost.getAppWidgetIds();
-            for (int i = 0; i < appWidgetIdsBoundToHost.length; i++) {
-                int appWidgetId = appWidgetIdsBoundToHost[i];
-                if (!contains(appWidgetIdsInKeyguardSettings, appWidgetId)) {
-                    Log.d(TAG, "Found a appWidgetId that's not being used by keyguard, deleting id "
-                            + appWidgetId);
-                    mAppWidgetHost.deleteAppWidgetId(appWidgetId);
-                }
-            }
-        }
-    }
-
-    private static boolean contains(int[] array, int target) {
-        for (int value : array) {
-            if (value == target) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private KeyguardUpdateMonitorCallback mUpdateMonitorCallbacks =
-            new KeyguardUpdateMonitorCallback() {
-        @Override
-        public void onBootCompleted() {
-            if (mCheckAppWidgetConsistencyOnBootCompleted) {
-                checkAppWidgetConsistency();
-                mSwitchPageRunnable.run();
-                mCheckAppWidgetConsistencyOnBootCompleted = false;
-            }
-            if (mCleanupAppWidgetsOnBootCompleted) {
-                cleanupAppWidgetIds();
-                mCleanupAppWidgetsOnBootCompleted = false;
-            }
-        }
-        @Override
-        public void onUserSwitchComplete(int userId) {
-            if (mKeyguardMultiUserSelectorView != null) {
-                mKeyguardMultiUserSelectorView.finalizeActiveUserView(true);
-            }
-        }
-        @Override
-        void onMusicClientIdChanged(
-                int clientGeneration, boolean clearing, android.app.PendingIntent intent) {
-            // Set transport state to invisible until we know music is playing (below)
-            if (DEBUGXPORT && (mClientGeneration != clientGeneration || clearing)) {
-                Log.v(TAG, (clearing ? "hide" : "show") + " transport, gen:" + clientGeneration);
-            }
-            mClientGeneration = clientGeneration;
-            final int newState = (clearing ? TRANSPORT_GONE
-                    : (mTransportState == TRANSPORT_VISIBLE ?
-                    TRANSPORT_VISIBLE : TRANSPORT_INVISIBLE));
-            if (newState != mTransportState) {
-                mTransportState = newState;
-                if (DEBUGXPORT) Log.v(TAG, "update widget: transport state changed");
-                KeyguardHostView.this.post(mSwitchPageRunnable);
-            }
-        }
-        @Override
-        public void onMusicPlaybackStateChanged(int playbackState, long eventTime) {
-            if (DEBUGXPORT) Log.v(TAG, "music state changed: " + playbackState);
-            if (mTransportState != TRANSPORT_GONE) {
-                final int newState = (isMusicPlaying(playbackState) ?
-                        TRANSPORT_VISIBLE : TRANSPORT_INVISIBLE);
-                if (newState != mTransportState) {
-                    mTransportState = newState;
-                    if (DEBUGXPORT) Log.v(TAG, "update widget: play state changed");
-                    KeyguardHostView.this.post(mSwitchPageRunnable);
-                }
-            }
-        }
-    };
-
-    private static final boolean isMusicPlaying(int playbackState) {
-        // This should agree with the list in AudioService.isPlaystateActive()
-        switch (playbackState) {
-            case RemoteControlClient.PLAYSTATE_PLAYING:
-            case RemoteControlClient.PLAYSTATE_BUFFERING:
-            case RemoteControlClient.PLAYSTATE_FAST_FORWARDING:
-            case RemoteControlClient.PLAYSTATE_REWINDING:
-            case RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS:
-            case RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS:
-                return true;
-            default:
-                return false;
-        }
-    }
-
-    private SlidingChallengeLayout mSlidingChallengeLayout;
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev) {
-        boolean result = super.onTouchEvent(ev);
-        mTempRect.set(0, 0, 0, 0);
-        offsetRectIntoDescendantCoords(mSecurityViewContainer, mTempRect);
-        ev.offsetLocation(mTempRect.left, mTempRect.top);
-        result = mSecurityViewContainer.dispatchTouchEvent(ev) || result;
-        ev.offsetLocation(-mTempRect.left, -mTempRect.top);
-        return result;
-    }
-
-    @Override
-    protected void dispatchDraw(Canvas canvas) {
-        super.dispatchDraw(canvas);
-        if (mViewMediatorCallback != null) {
-            mViewMediatorCallback.keyguardDoneDrawing();
-        }
-    }
-
-    private int getWidgetPosition(int id) {
-        final KeyguardWidgetPager appWidgetContainer = mAppWidgetContainer;
-        final int children = appWidgetContainer.getChildCount();
-        for (int i = 0; i < children; i++) {
-            final View content = appWidgetContainer.getWidgetPageAt(i).getContent();
-            if (content != null && content.getId() == id) {
-                return i;
-            } else if (content == null) {
-                // Attempt to track down bug #8886916
-                Log.w(TAG, "*** Null content at " + "i=" + i + ",id=" + id + ",N=" + children);
-            }
-        }
-        return -1;
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        // Grab instances of and make any necessary changes to the main layouts. Create
-        // view state manager and wire up necessary listeners / callbacks.
-        View deleteDropTarget = findViewById(R.id.keyguard_widget_pager_delete_target);
-        mAppWidgetContainer = (KeyguardWidgetPager) findViewById(R.id.app_widget_container);
-        mAppWidgetContainer.setVisibility(VISIBLE);
-        mAppWidgetContainer.setCallbacks(mWidgetCallbacks);
-        mAppWidgetContainer.setDeleteDropTarget(deleteDropTarget);
-        mAppWidgetContainer.setMinScale(0.5f);
-
-        mSlidingChallengeLayout = (SlidingChallengeLayout) findViewById(R.id.sliding_layout);
-        if (mSlidingChallengeLayout != null) {
-            mSlidingChallengeLayout.setOnChallengeScrolledListener(mViewStateManager);
-        }
-        mAppWidgetContainer.setViewStateManager(mViewStateManager);
-        mAppWidgetContainer.setLockPatternUtils(mLockPatternUtils);
-
-        ChallengeLayout challenge = mSlidingChallengeLayout != null ? mSlidingChallengeLayout :
-            (ChallengeLayout) findViewById(R.id.multi_pane_challenge);
-        challenge.setOnBouncerStateChangedListener(mViewStateManager);
-        mAppWidgetContainer.setBouncerAnimationDuration(challenge.getBouncerAnimationDuration());
-        mViewStateManager.setPagedView(mAppWidgetContainer);
-        mViewStateManager.setChallengeLayout(challenge);
-        mSecurityViewContainer = (KeyguardSecurityViewFlipper) findViewById(R.id.view_flipper);
-        mKeyguardSelectorView = (KeyguardSelectorView) findViewById(R.id.keyguard_selector_view);
-        mViewStateManager.setSecurityViewContainer(mSecurityViewContainer);
-
-        setBackButtonEnabled(false);
-
-        addDefaultWidgets();
-
-        addWidgetsFromSettings();
-        if (!shouldEnableAddWidget()) {
-            mAppWidgetContainer.setAddWidgetEnabled(false);
-        }
-        checkAppWidgetConsistency();
-        mSwitchPageRunnable.run();
-        // This needs to be called after the pages are all added.
-        mViewStateManager.showUsabilityHints();
-
-        showPrimarySecurityScreen(false);
-        updateSecurityViews();
-    }
-
-    private void setBackButtonEnabled(boolean enabled) {
-        if (mContext instanceof Activity) return;  // always enabled in activity mode
-        setSystemUiVisibility(enabled ?
-                getSystemUiVisibility() & ~View.STATUS_BAR_DISABLE_BACK :
-                getSystemUiVisibility() | View.STATUS_BAR_DISABLE_BACK);
-    }
-
-    private boolean shouldEnableAddWidget() {
-        return numWidgets() < MAX_WIDGETS && mUserSetupCompleted;
-    }
-
-    private int getDisabledFeatures(DevicePolicyManager dpm) {
-        int disabledFeatures = DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE;
-        if (dpm != null) {
-            final int currentUser = mLockPatternUtils.getCurrentUser();
-            disabledFeatures = dpm.getKeyguardDisabledFeatures(null, currentUser);
-        }
-        return disabledFeatures;
-    }
-
-    private boolean widgetsDisabledByDpm() {
-        return (mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL) != 0;
-    }
-
-    private boolean cameraDisabledByDpm() {
-        return mCameraDisabled
-                || (mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0;
-    }
-
-    private void updateSecurityViews() {
-        int children = mSecurityViewContainer.getChildCount();
-        for (int i = 0; i < children; i++) {
-            updateSecurityView(mSecurityViewContainer.getChildAt(i));
-        }
-    }
-
-    private void updateSecurityView(View view) {
-        if (view instanceof KeyguardSecurityView) {
-            KeyguardSecurityView ksv = (KeyguardSecurityView) view;
-            ksv.setKeyguardCallback(mCallback);
-            ksv.setLockPatternUtils(mLockPatternUtils);
-            if (mViewStateManager.isBouncing()) {
-                ksv.showBouncer(0);
-            } else {
-                ksv.hideBouncer(0);
-            }
-        } else {
-            Log.w(TAG, "View " + view + " is not a KeyguardSecurityView");
-        }
-    }
-
-    void setLockPatternUtils(LockPatternUtils utils) {
-        mSecurityModel.setLockPatternUtils(utils);
-        mLockPatternUtils = utils;
-        updateSecurityViews();
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        mAppWidgetHost.startListening();
-        KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallbacks);
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        mAppWidgetHost.stopListening();
-        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateMonitorCallbacks);
-    }
-
-    void addWidget(AppWidgetHostView view, int pageIndex) {
-        mAppWidgetContainer.addWidget(view, pageIndex);
-    }
-
-    private KeyguardWidgetPager.Callbacks mWidgetCallbacks
-            = new KeyguardWidgetPager.Callbacks() {
-        @Override
-        public void userActivity() {
-            KeyguardHostView.this.userActivity();
-        }
-
-        @Override
-        public void onUserActivityTimeoutChanged() {
-            KeyguardHostView.this.onUserActivityTimeoutChanged();
-        }
-
-        @Override
-        public void onAddView(View v) {
-            if (!shouldEnableAddWidget()) {
-                mAppWidgetContainer.setAddWidgetEnabled(false);
-            }
-        }
-
-        @Override
-        public void onRemoveView(View v, boolean deletePermanently) {
-            if (deletePermanently) {
-                final int appWidgetId = ((KeyguardWidgetFrame) v).getContentAppWidgetId();
-                if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID &&
-                        appWidgetId != LockPatternUtils.ID_DEFAULT_STATUS_WIDGET) {
-                    mAppWidgetHost.deleteAppWidgetId(appWidgetId);
-                }
-            }
-        }
-
-        @Override
-        public void onRemoveViewAnimationCompleted() {
-            if (shouldEnableAddWidget()) {
-                mAppWidgetContainer.setAddWidgetEnabled(true);
-            }
-        }
-    };
-
-    public void initializeSwitchingUserState(boolean switching) {
-        if (!switching && mKeyguardMultiUserSelectorView != null) {
-            mKeyguardMultiUserSelectorView.finalizeActiveUserView(false);
-        }
-    }
-
-    public void userActivity() {
-        if (mViewMediatorCallback != null) {
-            mViewMediatorCallback.userActivity();
-        }
-    }
-
-    public void onUserActivityTimeoutChanged() {
-        if (mViewMediatorCallback != null) {
-            mViewMediatorCallback.onUserActivityTimeoutChanged();
-        }
-    }
-
-    @Override
-    public long getUserActivityTimeout() {
-        // Currently only considering user activity timeouts needed by widgets.
-        // Could also take into account longer timeouts for certain security views.
-        if (mAppWidgetContainer != null) {
-            return mAppWidgetContainer.getUserActivityTimeout();
-        }
-        return -1;
-    }
-
-    private KeyguardSecurityCallback mCallback = new KeyguardSecurityCallback() {
-
-        public void userActivity(long timeout) {
-            if (mViewMediatorCallback != null) {
-                mViewMediatorCallback.userActivity(timeout);
-            }
-        }
-
-        public void dismiss(boolean authenticated) {
-            showNextSecurityScreenOrFinish(authenticated);
-        }
-
-        public boolean isVerifyUnlockOnly() {
-            return mIsVerifyUnlockOnly;
-        }
-
-        public void reportSuccessfulUnlockAttempt() {
-            KeyguardUpdateMonitor.getInstance(mContext).clearFailedUnlockAttempts();
-            mLockPatternUtils.reportSuccessfulPasswordAttempt();
-        }
-
-        public void reportFailedUnlockAttempt() {
-            if (mCurrentSecuritySelection == SecurityMode.Biometric) {
-                KeyguardUpdateMonitor.getInstance(mContext).reportFailedBiometricUnlockAttempt();
-            } else {
-                KeyguardHostView.this.reportFailedUnlockAttempt();
-            }
-        }
-
-        public int getFailedAttempts() {
-            return KeyguardUpdateMonitor.getInstance(mContext).getFailedUnlockAttempts();
-        }
-
-        @Override
-        public void showBackupSecurity() {
-            KeyguardHostView.this.showBackupSecurityScreen();
-        }
-
-        @Override
-        public void setOnDismissAction(OnDismissAction action) {
-            KeyguardHostView.this.setOnDismissAction(action);
-        }
-
-    };
-
-    private void showDialog(String title, String message) {
-        final AlertDialog dialog = new AlertDialog.Builder(mContext)
-            .setTitle(title)
-            .setMessage(message)
-            .setNeutralButton(com.android.internal.R.string.ok, null)
-            .create();
-        if (!(mContext instanceof Activity)) {
-            dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
-        }
-        dialog.show();
-    }
-
-    private void showTimeoutDialog() {
-        int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000;
-        int messageId = 0;
-
-        switch (mSecurityModel.getSecurityMode()) {
-            case Pattern:
-                messageId = R.string.kg_too_many_failed_pattern_attempts_dialog_message;
-                break;
-            case PIN:
-                messageId = R.string.kg_too_many_failed_pin_attempts_dialog_message;
-                break;
-            case Password:
-                messageId = R.string.kg_too_many_failed_password_attempts_dialog_message;
-                break;
-        }
-
-        if (messageId != 0) {
-            final String message = mContext.getString(messageId,
-                    KeyguardUpdateMonitor.getInstance(mContext).getFailedUnlockAttempts(),
-                    timeoutInSeconds);
-            showDialog(null, message);
-        }
-    }
-
-    private void showAlmostAtWipeDialog(int attempts, int remaining) {
-        int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000;
-        String message = mContext.getString(R.string.kg_failed_attempts_almost_at_wipe,
-                attempts, remaining);
-        showDialog(null, message);
-    }
-
-    private void showWipeDialog(int attempts) {
-        String message = mContext.getString(R.string.kg_failed_attempts_now_wiping, attempts);
-        showDialog(null, message);
-    }
-
-    private void showAlmostAtAccountLoginDialog() {
-        final int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000;
-        final int count = LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET
-                - LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT;
-        String message = mContext.getString(R.string.kg_failed_attempts_almost_at_login,
-                count, LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT, timeoutInSeconds);
-        showDialog(null, message);
-    }
-
-    private void reportFailedUnlockAttempt() {
-        final KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
-        final int failedAttempts = monitor.getFailedUnlockAttempts() + 1; // +1 for this time
-
-        if (DEBUG) Log.d(TAG, "reportFailedPatternAttempt: #" + failedAttempts);
-
-        SecurityMode mode = mSecurityModel.getSecurityMode();
-        final boolean usingPattern = mode == KeyguardSecurityModel.SecurityMode.Pattern;
-
-        final int failedAttemptsBeforeWipe = mLockPatternUtils.getDevicePolicyManager()
-                .getMaximumFailedPasswordsForWipe(null, mLockPatternUtils.getCurrentUser());
-
-        final int failedAttemptWarning = LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET
-                - LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT;
-
-        final int remainingBeforeWipe = failedAttemptsBeforeWipe > 0 ?
-                (failedAttemptsBeforeWipe - failedAttempts)
-                : Integer.MAX_VALUE; // because DPM returns 0 if no restriction
-
-        boolean showTimeout = false;
-        if (remainingBeforeWipe < LockPatternUtils.FAILED_ATTEMPTS_BEFORE_WIPE_GRACE) {
-            // If we reach this code, it means the user has installed a DevicePolicyManager
-            // that requests device wipe after N attempts.  Once we get below the grace
-            // period, we'll post this dialog every time as a clear warning until the
-            // bombshell hits and the device is wiped.
-            if (remainingBeforeWipe > 0) {
-                showAlmostAtWipeDialog(failedAttempts, remainingBeforeWipe);
-            } else {
-                // Too many attempts. The device will be wiped shortly.
-                Slog.i(TAG, "Too many unlock attempts; device will be wiped!");
-                showWipeDialog(failedAttempts);
-            }
-        } else {
-            showTimeout =
-                (failedAttempts % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) == 0;
-            if (usingPattern && mEnableFallback) {
-                if (failedAttempts == failedAttemptWarning) {
-                    showAlmostAtAccountLoginDialog();
-                    showTimeout = false; // don't show both dialogs
-                } else if (failedAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET) {
-                    mLockPatternUtils.setPermanentlyLocked(true);
-                    showSecurityScreen(SecurityMode.Account);
-                    // don't show timeout dialog because we show account unlock screen next
-                    showTimeout = false;
-                }
-            }
-        }
-        monitor.reportFailedUnlockAttempt();
-        mLockPatternUtils.reportFailedPasswordAttempt();
-        if (showTimeout) {
-            showTimeoutDialog();
-        }
-    }
-
-    /**
-     * Shows the primary security screen for the user. This will be either the multi-selector
-     * or the user's security method.
-     * @param turningOff true if the device is being turned off
-     */
-    void showPrimarySecurityScreen(boolean turningOff) {
-        SecurityMode securityMode = mSecurityModel.getSecurityMode();
-        if (DEBUG) Log.v(TAG, "showPrimarySecurityScreen(turningOff=" + turningOff + ")");
-        if (!turningOff &&
-                KeyguardUpdateMonitor.getInstance(mContext).isAlternateUnlockEnabled()) {
-            // If we're not turning off, then allow biometric alternate.
-            // We'll reload it when the device comes back on.
-            securityMode = mSecurityModel.getAlternateFor(securityMode);
-        }
-        showSecurityScreen(securityMode);
-    }
-
-    /**
-     * Shows the backup security screen for the current security mode.  This could be used for
-     * password recovery screens but is currently only used for pattern unlock to show the
-     * account unlock screen and biometric unlock to show the user's normal unlock.
-     */
-    private void showBackupSecurityScreen() {
-        if (DEBUG) Log.d(TAG, "showBackupSecurity()");
-        SecurityMode backup = mSecurityModel.getBackupSecurityMode(mCurrentSecuritySelection);
-        showSecurityScreen(backup);
-    }
-
-    public boolean showNextSecurityScreenIfPresent() {
-        SecurityMode securityMode = mSecurityModel.getSecurityMode();
-        // Allow an alternate, such as biometric unlock
-        securityMode = mSecurityModel.getAlternateFor(securityMode);
-        if (SecurityMode.None == securityMode) {
-            return false;
-        } else {
-            showSecurityScreen(securityMode); // switch to the alternate security view
-            return true;
-        }
-    }
-
-    private void showNextSecurityScreenOrFinish(boolean authenticated) {
-        if (DEBUG) Log.d(TAG, "showNextSecurityScreenOrFinish(" + authenticated + ")");
-        boolean finish = false;
-        if (SecurityMode.None == mCurrentSecuritySelection) {
-            SecurityMode securityMode = mSecurityModel.getSecurityMode();
-            // Allow an alternate, such as biometric unlock
-            securityMode = mSecurityModel.getAlternateFor(securityMode);
-            if (SecurityMode.None == securityMode) {
-                finish = true; // no security required
-            } else {
-                showSecurityScreen(securityMode); // switch to the alternate security view
-            }
-        } else if (authenticated) {
-            switch (mCurrentSecuritySelection) {
-                case Pattern:
-                case Password:
-                case PIN:
-                case Account:
-                case Biometric:
-                    finish = true;
-                    break;
-
-                case SimPin:
-                case SimPuk:
-                    // Shortcut for SIM PIN/PUK to go to directly to user's security screen or home
-                    SecurityMode securityMode = mSecurityModel.getSecurityMode();
-                    if (securityMode != SecurityMode.None) {
-                        showSecurityScreen(securityMode);
-                    } else {
-                        finish = true;
-                    }
-                    break;
-
-                default:
-                    Log.v(TAG, "Bad security screen " + mCurrentSecuritySelection + ", fail safe");
-                    showPrimarySecurityScreen(false);
-                    break;
-            }
-        } else {
-            showPrimarySecurityScreen(false);
-        }
-        if (finish) {
-            // If the alternate unlock was suppressed, it can now be safely
-            // enabled because the user has left keyguard.
-            KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true);
-
-            // If there's a pending runnable because the user interacted with a widget
-            // and we're leaving keyguard, then run it.
-            boolean deferKeyguardDone = false;
-            if (mDismissAction != null) {
-                deferKeyguardDone = mDismissAction.onDismiss();
-                mDismissAction = null;
-            }
-            if (mViewMediatorCallback != null) {
-                if (deferKeyguardDone) {
-                    mViewMediatorCallback.keyguardDonePending();
-                } else {
-                    mViewMediatorCallback.keyguardDone(true);
-                }
-            }
-        } else {
-            mViewStateManager.showBouncer(true);
-        }
-    }
-
-    private OnClickHandler mOnClickHandler = new OnClickHandler() {
-        @Override
-        public boolean onClickHandler(final View view,
-                final android.app.PendingIntent pendingIntent,
-                final Intent fillInIntent) {
-            if (pendingIntent.isActivity()) {
-                setOnDismissAction(new OnDismissAction() {
-                    public boolean onDismiss() {
-                        try {
-                              // TODO: Unregister this handler if PendingIntent.FLAG_ONE_SHOT?
-                              Context context = view.getContext();
-                              ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(view,
-                                      0, 0,
-                                      view.getMeasuredWidth(), view.getMeasuredHeight());
-                              context.startIntentSender(
-                                      pendingIntent.getIntentSender(), fillInIntent,
-                                      Intent.FLAG_ACTIVITY_NEW_TASK,
-                                      Intent.FLAG_ACTIVITY_NEW_TASK, 0, opts.toBundle());
-                        } catch (IntentSender.SendIntentException e) {
-                            android.util.Log.e(TAG, "Cannot send pending intent: ", e);
-                        } catch (Exception e) {
-                            android.util.Log.e(TAG, "Cannot send pending intent due to " +
-                                    "unknown exception: ", e);
-                        }
-                        return false;
-                    }
-                });
-
-                if (mViewStateManager.isChallengeShowing()) {
-                    mViewStateManager.showBouncer(true);
-                } else {
-                    mCallback.dismiss(false);
-                }
-                return true;
-            } else {
-                return super.onClickHandler(view, pendingIntent, fillInIntent);
-            }
-        };
-    };
-
-    // Used to ignore callbacks from methods that are no longer current (e.g. face unlock).
-    // This avoids unwanted asynchronous events from messing with the state.
-    private KeyguardSecurityCallback mNullCallback = new KeyguardSecurityCallback() {
-
-        @Override
-        public void userActivity(long timeout) {
-        }
-
-        @Override
-        public void showBackupSecurity() {
-        }
-
-        @Override
-        public void setOnDismissAction(OnDismissAction action) {
-        }
-
-        @Override
-        public void reportSuccessfulUnlockAttempt() {
-        }
-
-        @Override
-        public void reportFailedUnlockAttempt() {
-        }
-
-        @Override
-        public boolean isVerifyUnlockOnly() {
-            return false;
-        }
-
-        @Override
-        public int getFailedAttempts() {
-            return 0;
-        }
-
-        @Override
-        public void dismiss(boolean securityVerified) {
-        }
-    };
-
-    protected boolean mShowSecurityWhenReturn;
-
-    @Override
-    public void reset() {
-        mIsVerifyUnlockOnly = false;
-        mAppWidgetContainer.setCurrentPage(getWidgetPosition(R.id.keyguard_status_view));
-    }
-
-    /**
-     * Sets an action to perform when keyguard is dismissed.
-     * @param action
-     */
-    protected void setOnDismissAction(OnDismissAction action) {
-        mDismissAction = action;
-    }
-
-    private KeyguardSecurityView getSecurityView(SecurityMode securityMode) {
-        final int securityViewIdForMode = getSecurityViewIdForMode(securityMode);
-        KeyguardSecurityView view = null;
-        final int children = mSecurityViewContainer.getChildCount();
-        for (int child = 0; child < children; child++) {
-            if (mSecurityViewContainer.getChildAt(child).getId() == securityViewIdForMode) {
-                view = ((KeyguardSecurityView)mSecurityViewContainer.getChildAt(child));
-                break;
-            }
-        }
-        int layoutId = getLayoutIdFor(securityMode);
-        if (view == null && layoutId != 0) {
-            final LayoutInflater inflater = LayoutInflater.from(mContext);
-            if (DEBUG) Log.v(TAG, "inflating id = " + layoutId);
-            View v = inflater.inflate(layoutId, mSecurityViewContainer, false);
-            mSecurityViewContainer.addView(v);
-            updateSecurityView(v);
-            view = (KeyguardSecurityView)v;
-        }
-
-        if (view instanceof KeyguardSelectorView) {
-            KeyguardSelectorView selectorView = (KeyguardSelectorView) view;
-            View carrierText = selectorView.findViewById(R.id.keyguard_selector_fade_container);
-            selectorView.setCarrierArea(carrierText);
-        }
-
-        return view;
-    }
-
-    /**
-     * Switches to the given security view unless it's already being shown, in which case
-     * this is a no-op.
-     *
-     * @param securityMode
-     */
-    private void showSecurityScreen(SecurityMode securityMode) {
-        if (DEBUG) Log.d(TAG, "showSecurityScreen(" + securityMode + ")");
-
-        if (securityMode == mCurrentSecuritySelection) return;
-
-        KeyguardSecurityView oldView = getSecurityView(mCurrentSecuritySelection);
-        KeyguardSecurityView newView = getSecurityView(securityMode);
-
-        // Enter full screen mode if we're in SIM or Account screen
-        boolean fullScreenEnabled = getResources().getBoolean(
-                com.android.internal.R.bool.kg_sim_puk_account_full_screen);
-        boolean isSimOrAccount = securityMode == SecurityMode.SimPin
-                || securityMode == SecurityMode.SimPuk
-                || securityMode == SecurityMode.Account;
-        mAppWidgetContainer.setVisibility(
-                isSimOrAccount && fullScreenEnabled ? View.GONE : View.VISIBLE);
-
-        if (mSlidingChallengeLayout != null) {
-            mSlidingChallengeLayout.setChallengeInteractive(!fullScreenEnabled);
-        }
-
-        // Emulate Activity life cycle
-        if (oldView != null) {
-            oldView.onPause();
-            oldView.setKeyguardCallback(mNullCallback); // ignore requests from old view
-        }
-        newView.onResume(KeyguardSecurityView.VIEW_REVEALED);
-        newView.setKeyguardCallback(mCallback);
-
-        final boolean needsInput = newView.needsInput();
-        if (mViewMediatorCallback != null) {
-            mViewMediatorCallback.setNeedsInput(needsInput);
-        }
-
-        // Find and show this child.
-        final int childCount = mSecurityViewContainer.getChildCount();
-
-        mSecurityViewContainer.setInAnimation(
-                AnimationUtils.loadAnimation(mContext, R.anim.keyguard_security_fade_in));
-        mSecurityViewContainer.setOutAnimation(
-                AnimationUtils.loadAnimation(mContext, R.anim.keyguard_security_fade_out));
-        final int securityViewIdForMode = getSecurityViewIdForMode(securityMode);
-        for (int i = 0; i < childCount; i++) {
-            if (mSecurityViewContainer.getChildAt(i).getId() == securityViewIdForMode) {
-                mSecurityViewContainer.setDisplayedChild(i);
-                break;
-            }
-        }
-
-        if (securityMode == SecurityMode.None) {
-            // Discard current runnable if we're switching back to the selector view
-            setOnDismissAction(null);
-        }
-        if (securityMode == SecurityMode.Account && !mLockPatternUtils.isPermanentlyLocked()) {
-            // we're showing account as a backup, provide a way to get back to primary
-            setBackButtonEnabled(true);
-        }
-        mCurrentSecuritySelection = securityMode;
-    }
-
-    @Override
-    public void onScreenTurnedOn() {
-        if (DEBUG) Log.d(TAG, "screen on, instance " + Integer.toHexString(hashCode()));
-        showPrimarySecurityScreen(false);
-        getSecurityView(mCurrentSecuritySelection).onResume(KeyguardSecurityView.SCREEN_ON);
-
-        // This is a an attempt to fix bug 7137389 where the device comes back on but the entire
-        // layout is blank but forcing a layout causes it to reappear (e.g. with with
-        // hierarchyviewer).
-        requestLayout();
-
-        if (mViewStateManager != null) {
-            mViewStateManager.showUsabilityHints();
-        }
-        requestFocus();
-    }
-
-    @Override
-    public void onScreenTurnedOff() {
-        if (DEBUG) Log.d(TAG, String.format("screen off, instance %s at %s",
-                Integer.toHexString(hashCode()), SystemClock.uptimeMillis()));
-        // Once the screen turns off, we no longer consider this to be first boot and we want the
-        // biometric unlock to start next time keyguard is shown.
-        KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true);
-        // We use mAppWidgetToShow to show a particular widget after you add it-- once the screen
-        // turns off we reset that behavior
-        clearAppWidgetToShow();
-        checkAppWidgetConsistency();
-        showPrimarySecurityScreen(true);
-        getSecurityView(mCurrentSecuritySelection).onPause();
-        CameraWidgetFrame cameraPage = findCameraPage();
-        if (cameraPage != null) {
-            cameraPage.onScreenTurnedOff();
-        }
-        clearFocus();
-    }
-
-    public void clearAppWidgetToShow() {
-        mAppWidgetToShow = AppWidgetManager.INVALID_APPWIDGET_ID;
-    }
-
-    @Override
-    public void show() {
-        if (DEBUG) Log.d(TAG, "show()");
-        showPrimarySecurityScreen(false);
-    }
-
-    private boolean isSecure() {
-        SecurityMode mode = mSecurityModel.getSecurityMode();
-        switch (mode) {
-            case Pattern:
-                return mLockPatternUtils.isLockPatternEnabled();
-            case Password:
-            case PIN:
-                return mLockPatternUtils.isLockPasswordEnabled();
-            case SimPin:
-            case SimPuk:
-            case Account:
-                return true;
-            case None:
-                return false;
-            default:
-                throw new IllegalStateException("Unknown security mode " + mode);
-        }
-    }
-
-    @Override
-    public void wakeWhenReadyTq(int keyCode) {
-        if (DEBUG) Log.d(TAG, "onWakeKey");
-        if (keyCode == KeyEvent.KEYCODE_MENU && isSecure()) {
-            if (DEBUG) Log.d(TAG, "switching screens to unlock screen because wake key was MENU");
-            showSecurityScreen(SecurityMode.None);
-        } else {
-            if (DEBUG) Log.d(TAG, "poking wake lock immediately");
-        }
-        if (mViewMediatorCallback != null) {
-            mViewMediatorCallback.wakeUp();
-        }
-    }
-
-    @Override
-    public void verifyUnlock() {
-        SecurityMode securityMode = mSecurityModel.getSecurityMode();
-        if (securityMode == KeyguardSecurityModel.SecurityMode.None) {
-            if (mViewMediatorCallback != null) {
-                mViewMediatorCallback.keyguardDone(true);
-            }
-        } else if (securityMode != KeyguardSecurityModel.SecurityMode.Pattern
-                && securityMode != KeyguardSecurityModel.SecurityMode.PIN
-                && securityMode != KeyguardSecurityModel.SecurityMode.Password) {
-            // can only verify unlock when in pattern/password mode
-            if (mViewMediatorCallback != null) {
-                mViewMediatorCallback.keyguardDone(false);
-            }
-        } else {
-            // otherwise, go to the unlock screen, see if they can verify it
-            mIsVerifyUnlockOnly = true;
-            showSecurityScreen(securityMode);
-        }
-    }
-
-    private int getSecurityViewIdForMode(SecurityMode securityMode) {
-        switch (securityMode) {
-            case None: return R.id.keyguard_selector_view;
-            case Pattern: return R.id.keyguard_pattern_view;
-            case PIN: return R.id.keyguard_pin_view;
-            case Password: return R.id.keyguard_password_view;
-            case Biometric: return R.id.keyguard_face_unlock_view;
-            case Account: return R.id.keyguard_account_view;
-            case SimPin: return R.id.keyguard_sim_pin_view;
-            case SimPuk: return R.id.keyguard_sim_puk_view;
-        }
-        return 0;
-    }
-
-    private int getLayoutIdFor(SecurityMode securityMode) {
-        switch (securityMode) {
-            case None: return R.layout.keyguard_selector_view;
-            case Pattern: return R.layout.keyguard_pattern_view;
-            case PIN: return R.layout.keyguard_pin_view;
-            case Password: return R.layout.keyguard_password_view;
-            case Biometric: return R.layout.keyguard_face_unlock_view;
-            case Account: return R.layout.keyguard_account_view;
-            case SimPin: return R.layout.keyguard_sim_pin_view;
-            case SimPuk: return R.layout.keyguard_sim_puk_view;
-            default:
-                return 0;
-        }
-    }
-
-    private boolean addWidget(int appId, int pageIndex, boolean updateDbIfFailed) {
-        AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appId);
-        if (appWidgetInfo != null) {
-            AppWidgetHostView view = mAppWidgetHost.createView(mContext, appId, appWidgetInfo);
-            addWidget(view, pageIndex);
-            return true;
-        } else {
-            if (updateDbIfFailed) {
-                Log.w(TAG, "*** AppWidgetInfo for app widget id " + appId + "  was null for user"
-                        + mUserId + ", deleting");
-                mAppWidgetHost.deleteAppWidgetId(appId);
-                mLockPatternUtils.removeAppWidget(appId);
-            }
-            return false;
-        }
-    }
-
-    private final CameraWidgetFrame.Callbacks mCameraWidgetCallbacks =
-        new CameraWidgetFrame.Callbacks() {
-            @Override
-            public void onLaunchingCamera() {
-                setSliderHandleAlpha(0);
-            }
-
-            @Override
-            public void onCameraLaunchedSuccessfully() {
-                if (mAppWidgetContainer.isCameraPage(mAppWidgetContainer.getCurrentPage())) {
-                    mAppWidgetContainer.scrollLeft();
-                }
-                setSliderHandleAlpha(1);
-                mShowSecurityWhenReturn = true;
-            }
-
-            @Override
-            public void onCameraLaunchedUnsuccessfully() {
-                setSliderHandleAlpha(1);
-            }
-
-            private void setSliderHandleAlpha(float alpha) {
-                SlidingChallengeLayout slider =
-                        (SlidingChallengeLayout) findViewById(R.id.sliding_layout);
-                if (slider != null) {
-                    slider.setHandleAlpha(alpha);
-                }
-            }
-        };
-
-    private final KeyguardActivityLauncher mActivityLauncher = new KeyguardActivityLauncher() {
-        @Override
-        Context getContext() {
-            return mContext;
-        }
-
-        @Override
-        KeyguardSecurityCallback getCallback() {
-            return mCallback;
-        }
-
-        @Override
-        LockPatternUtils getLockPatternUtils() {
-            return mLockPatternUtils;
-        }
-    };
-
-    private int numWidgets() {
-        final int childCount = mAppWidgetContainer.getChildCount();
-        int widgetCount = 0;
-        for (int i = 0; i < childCount; i++) {
-            if (mAppWidgetContainer.isWidgetPage(i)) {
-                widgetCount++;
-            }
-        }
-        return widgetCount;
-    }
-
-    private void addDefaultWidgets() {
-        if (!mSafeModeEnabled && !widgetsDisabledByDpm()) {
-            LayoutInflater inflater = LayoutInflater.from(mContext);
-            View addWidget = inflater.inflate(R.layout.keyguard_add_widget, this, false);
-            mAppWidgetContainer.addWidget(addWidget, 0);
-            View addWidgetButton = addWidget.findViewById(R.id.keyguard_add_widget_view);
-            addWidgetButton.setOnClickListener(new OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    // Pass in an invalid widget id... the picker will allocate an ID for us
-                    mActivityLauncher.launchWidgetPicker(AppWidgetManager.INVALID_APPWIDGET_ID);
-                }
-            });
-        }
-
-        // We currently disable cameras in safe mode because we support loading 3rd party
-        // cameras we can't trust.  TODO: plumb safe mode into camera creation code and only
-        // inflate system-provided camera?
-        if (!mSafeModeEnabled && !cameraDisabledByDpm() && mUserSetupCompleted
-                && mContext.getResources().getBoolean(R.bool.kg_enable_camera_default_widget)) {
-            View cameraWidget =
-                    CameraWidgetFrame.create(mContext, mCameraWidgetCallbacks, mActivityLauncher);
-            if (cameraWidget != null) {
-                mAppWidgetContainer.addWidget(cameraWidget);
-            }
-        }
-
-        enableUserSelectorIfNecessary();
-    }
-
-    /**
-     * Create KeyguardTransportControlView on demand.
-     * @return
-     */
-    private KeyguardTransportControlView getOrCreateTransportControl() {
-        if (mTransportControl == null) {
-            LayoutInflater inflater = LayoutInflater.from(mContext);
-            mTransportControl = (KeyguardTransportControlView)
-                    inflater.inflate(R.layout.keyguard_transport_control_view, this, false);
-        }
-        return mTransportControl;
-    }
-
-    private int getInsertPageIndex() {
-        View addWidget = mAppWidgetContainer.findViewById(R.id.keyguard_add_widget);
-        int insertionIndex = mAppWidgetContainer.indexOfChild(addWidget);
-        if (insertionIndex < 0) {
-            insertionIndex = 0; // no add widget page found
-        } else {
-            insertionIndex++; // place after add widget
-        }
-        return insertionIndex;
-    }
-
-    private void addDefaultStatusWidget(int index) {
-        LayoutInflater inflater = LayoutInflater.from(mContext);
-        View statusWidget = inflater.inflate(R.layout.keyguard_status_view, null, true);
-        mAppWidgetContainer.addWidget(statusWidget, index);
-    }
-
-    private void addWidgetsFromSettings() {
-        if (mSafeModeEnabled || widgetsDisabledByDpm()) {
-            return;
-        }
-
-        int insertionIndex = getInsertPageIndex();
-
-        // Add user-selected widget
-        final int[] widgets = mLockPatternUtils.getAppWidgets();
-
-        if (widgets == null) {
-            Log.d(TAG, "Problem reading widgets");
-        } else {
-            for (int i = widgets.length -1; i >= 0; i--) {
-                if (widgets[i] == LockPatternUtils.ID_DEFAULT_STATUS_WIDGET) {
-                    addDefaultStatusWidget(insertionIndex);
-                } else {
-                    // We add the widgets from left to right, starting after the first page after
-                    // the add page. We count down, since the order will be persisted from right
-                    // to left, starting after camera.
-                    addWidget(widgets[i], insertionIndex, true);
-                }
-            }
-        }
-    }
-
-    private int allocateIdForDefaultAppWidget() {
-        int appWidgetId;
-        Resources res = getContext().getResources();
-        ComponentName defaultAppWidget = new ComponentName(
-                res.getString(R.string.widget_default_package_name),
-                res.getString(R.string.widget_default_class_name));
-
-        // Note: we don't support configuring the widget
-        appWidgetId = mAppWidgetHost.allocateAppWidgetId();
-
-        try {
-            mAppWidgetManager.bindAppWidgetId(appWidgetId, defaultAppWidget);
-
-        } catch (IllegalArgumentException e) {
-            Log.e(TAG, "Error when trying to bind default AppWidget: " + e);
-            mAppWidgetHost.deleteAppWidgetId(appWidgetId);
-            appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
-        }
-        return appWidgetId;
-    }
-    public void checkAppWidgetConsistency() {
-        // Since this method may bind a widget (which we can't do until boot completed) we
-        // may have to defer it until after boot complete.
-        if (!KeyguardUpdateMonitor.getInstance(mContext).hasBootCompleted()) {
-            mCheckAppWidgetConsistencyOnBootCompleted = true;
-            return;
-        }
-        final int childCount = mAppWidgetContainer.getChildCount();
-        boolean widgetPageExists = false;
-        for (int i = 0; i < childCount; i++) {
-            if (mAppWidgetContainer.isWidgetPage(i)) {
-                widgetPageExists = true;
-                break;
-            }
-        }
-        if (!widgetPageExists) {
-            final int insertPageIndex = getInsertPageIndex();
-
-            final boolean userAddedWidgetsEnabled = !widgetsDisabledByDpm();
-            boolean addedDefaultAppWidget = false;
-
-            if (!mSafeModeEnabled) {
-                if (userAddedWidgetsEnabled) {
-                    int appWidgetId = allocateIdForDefaultAppWidget();
-                    if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
-                        addedDefaultAppWidget = addWidget(appWidgetId, insertPageIndex, true);
-                    }
-                } else {
-                    // note: even if widgetsDisabledByDpm() returns true, we still bind/create
-                    // the default appwidget if possible
-                    int appWidgetId = mLockPatternUtils.getFallbackAppWidgetId();
-                    if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
-                        appWidgetId = allocateIdForDefaultAppWidget();
-                        if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
-                            mLockPatternUtils.writeFallbackAppWidgetId(appWidgetId);
-                        }
-                    }
-                    if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
-                        addedDefaultAppWidget = addWidget(appWidgetId, insertPageIndex, false);
-                        if (!addedDefaultAppWidget) {
-                            mAppWidgetHost.deleteAppWidgetId(appWidgetId);
-                            mLockPatternUtils.writeFallbackAppWidgetId(
-                                    AppWidgetManager.INVALID_APPWIDGET_ID);
-                        }
-                    }
-                }
-            }
-
-            // Use the built-in status/clock view if we can't inflate the default widget
-            if (!addedDefaultAppWidget) {
-                addDefaultStatusWidget(insertPageIndex);
-            }
-
-            // trigger DB updates only if user-added widgets are enabled
-            if (!mSafeModeEnabled && userAddedWidgetsEnabled) {
-                mAppWidgetContainer.onAddView(
-                        mAppWidgetContainer.getChildAt(insertPageIndex), insertPageIndex);
-            }
-        }
-    }
-
-    Runnable mSwitchPageRunnable = new Runnable() {
-        @Override
-        public void run() {
-           showAppropriateWidgetPage();
-        }
-    };
-
-    static class SavedState extends BaseSavedState {
-        int transportState;
-        int appWidgetToShow = AppWidgetManager.INVALID_APPWIDGET_ID;
-
-        SavedState(Parcelable superState) {
-            super(superState);
-        }
-
-        private SavedState(Parcel in) {
-            super(in);
-            this.transportState = in.readInt();
-            this.appWidgetToShow = in.readInt();
-        }
-
-        @Override
-        public void writeToParcel(Parcel out, int flags) {
-            super.writeToParcel(out, flags);
-            out.writeInt(this.transportState);
-            out.writeInt(this.appWidgetToShow);
-        }
-
-        public static final Parcelable.Creator<SavedState> CREATOR
-                = new Parcelable.Creator<SavedState>() {
-            public SavedState createFromParcel(Parcel in) {
-                return new SavedState(in);
-            }
-
-            public SavedState[] newArray(int size) {
-                return new SavedState[size];
-            }
-        };
-    }
-
-    @Override
-    public Parcelable onSaveInstanceState() {
-        if (DEBUG) Log.d(TAG, "onSaveInstanceState, tstate=" + mTransportState);
-        Parcelable superState = super.onSaveInstanceState();
-        SavedState ss = new SavedState(superState);
-        // If the transport is showing, force it to show it on restore.
-        final boolean showing = mTransportControl != null
-                && mAppWidgetContainer.getWidgetPageIndex(mTransportControl) >= 0;
-        ss.transportState =  showing ? TRANSPORT_VISIBLE : mTransportState;
-        ss.appWidgetToShow = mAppWidgetToShow;
-        return ss;
-    }
-
-    @Override
-    public void onRestoreInstanceState(Parcelable state) {
-        if (!(state instanceof SavedState)) {
-            super.onRestoreInstanceState(state);
-            return;
-        }
-        SavedState ss = (SavedState) state;
-        super.onRestoreInstanceState(ss.getSuperState());
-        mTransportState = (ss.transportState);
-        mAppWidgetToShow = ss.appWidgetToShow;
-        if (DEBUG) Log.d(TAG, "onRestoreInstanceState, transport=" + mTransportState);
-        post(mSwitchPageRunnable);
-    }
-
-    @Override
-    public void onWindowFocusChanged(boolean hasWindowFocus) {
-        super.onWindowFocusChanged(hasWindowFocus);
-        if (DEBUG) Log.d(TAG, "Window is " + (hasWindowFocus ? "focused" : "unfocused"));
-        if (hasWindowFocus && mShowSecurityWhenReturn) {
-            SlidingChallengeLayout slider =
-                (SlidingChallengeLayout) findViewById(R.id.sliding_layout);
-            if (slider != null) {
-                slider.setHandleAlpha(1);
-                slider.showChallenge(true);
-            }
-            mShowSecurityWhenReturn = false;
-        }
-    }
-
-    private void showAppropriateWidgetPage() {
-        int state = mTransportState;
-        ensureTransportPresentOrRemoved(state);
-        int pageToShow = getAppropriateWidgetPage(state);
-        mAppWidgetContainer.setCurrentPage(pageToShow);
-    }
-
-    /**
-     * Examines the current state and adds the transport to the widget pager when the state changes.
-     *
-     * Showing the initial transport and keeping it around is a bit tricky because the signals
-     * coming from music players aren't always clear. Here's how the states are handled:
-     *
-     * {@link TRANSPORT_GONE} means we have no reason to show the transport - remove it if present.
-     *
-     * {@link TRANSPORT_INVISIBLE} means we have potential to show the transport because a music
-     * player is registered but not currently playing music (or we don't know the state yet). The
-     * code adds it conditionally on play state.
-     *
-     * {@link #TRANSPORT_VISIBLE} means a music player is active and transport should be showing.
-     *
-     * Once the transport is showing, we always show it until keyguard is dismissed. This state is
-     * maintained by onSave/RestoreInstanceState(). This state is cleared in
-     * {@link KeyguardViewManager#hide} when keyguard is dismissed, which causes the transport to be
-     * gone when keyguard is restarted until we get an update with the current state.
-     *
-     * @param state
-     */
-    private void ensureTransportPresentOrRemoved(int state) {
-        final boolean showing = getWidgetPosition(R.id.keyguard_transport_control) != -1;
-        final boolean visible = state == TRANSPORT_VISIBLE;
-        final boolean shouldBeVisible = state == TRANSPORT_INVISIBLE && isMusicPlaying(state);
-        if (!showing && (visible || shouldBeVisible)) {
-            if (DEBUGXPORT) Log.v(TAG, "add transport");
-            // insert to left of camera if it exists, otherwise after right-most widget
-            int lastWidget = mAppWidgetContainer.getChildCount() - 1;
-            int position = 0; // handle no widget case
-            if (lastWidget >= 0) {
-                position = mAppWidgetContainer.isCameraPage(lastWidget) ?
-                        lastWidget : lastWidget + 1;
-            }
-            mAppWidgetContainer.addWidget(getOrCreateTransportControl(), position);
-        } else if (showing && state == TRANSPORT_GONE) {
-            if (DEBUGXPORT) Log.v(TAG, "remove transport");
-            mAppWidgetContainer.removeWidget(getOrCreateTransportControl());
-            mTransportControl = null;
-        }
-    }
-
-    private CameraWidgetFrame findCameraPage() {
-        for (int i = mAppWidgetContainer.getChildCount() - 1; i >= 0; i--) {
-            if (mAppWidgetContainer.isCameraPage(i)) {
-                return (CameraWidgetFrame) mAppWidgetContainer.getChildAt(i);
-            }
-        }
-        return null;
-    }
-
-    boolean isMusicPage(int pageIndex) {
-        return pageIndex >= 0 && pageIndex == getWidgetPosition(R.id.keyguard_transport_control);
-    }
-
-    private int getAppropriateWidgetPage(int musicTransportState) {
-        // assumes at least one widget (besides camera + add)
-        if (mAppWidgetToShow != AppWidgetManager.INVALID_APPWIDGET_ID) {
-            final int childCount = mAppWidgetContainer.getChildCount();
-            for (int i = 0; i < childCount; i++) {
-                if (mAppWidgetContainer.getWidgetPageAt(i).getContentAppWidgetId()
-                        == mAppWidgetToShow) {
-                    return i;
-                }
-            }
-            mAppWidgetToShow = AppWidgetManager.INVALID_APPWIDGET_ID;
-        }
-        // if music playing, show transport
-        if (musicTransportState == TRANSPORT_VISIBLE) {
-            if (DEBUG) Log.d(TAG, "Music playing, show transport");
-            return mAppWidgetContainer.getWidgetPageIndex(getOrCreateTransportControl());
-        }
-
-        // else show the right-most widget (except for camera)
-        int rightMost = mAppWidgetContainer.getChildCount() - 1;
-        if (mAppWidgetContainer.isCameraPage(rightMost)) {
-            rightMost--;
-        }
-        if (DEBUG) Log.d(TAG, "Show right-most page " + rightMost);
-        return rightMost;
-    }
-
-    private void enableUserSelectorIfNecessary() {
-        if (!UserManager.supportsMultipleUsers()) {
-            return; // device doesn't support multi-user mode
-        }
-        final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
-        if (um == null) {
-            Throwable t = new Throwable();
-            t.fillInStackTrace();
-            Log.e(TAG, "user service is null.", t);
-            return;
-        }
-
-        // if there are multiple users, we need to enable to multi-user switcher
-        final List<UserInfo> users = um.getUsers(true);
-        if (users == null) {
-            Throwable t = new Throwable();
-            t.fillInStackTrace();
-            Log.e(TAG, "list of users is null.", t);
-            return;
-        }
-
-        final View multiUserView = findViewById(R.id.keyguard_user_selector);
-        if (multiUserView == null) {
-            Throwable t = new Throwable();
-            t.fillInStackTrace();
-            Log.e(TAG, "can't find user_selector in layout.", t);
-            return;
-        }
-
-        if (users.size() > 1) {
-            if (multiUserView instanceof KeyguardMultiUserSelectorView) {
-                mKeyguardMultiUserSelectorView = (KeyguardMultiUserSelectorView) multiUserView;
-                mKeyguardMultiUserSelectorView.setVisibility(View.VISIBLE);
-                mKeyguardMultiUserSelectorView.addUsers(users);
-                UserSwitcherCallback callback = new UserSwitcherCallback() {
-                    @Override
-                    public void hideSecurityView(int duration) {
-                        mSecurityViewContainer.animate().alpha(0).setDuration(duration);
-                    }
-
-                    @Override
-                    public void showSecurityView() {
-                        mSecurityViewContainer.setAlpha(1.0f);
-                    }
-
-                    @Override
-                    public void showUnlockHint() {
-                        if (mKeyguardSelectorView != null) {
-                            mKeyguardSelectorView.showUsabilityHint();
-                        }
-                    }
-
-                    @Override
-                    public void userActivity() {
-                        if (mViewMediatorCallback != null) {
-                            mViewMediatorCallback.userActivity();
-                        }
-                    }
-                };
-                mKeyguardMultiUserSelectorView.setCallback(callback);
-            } else {
-                Throwable t = new Throwable();
-                t.fillInStackTrace();
-                if (multiUserView == null) {
-                    Log.e(TAG, "could not find the user_selector.", t);
-                } else {
-                    Log.e(TAG, "user_selector is the wrong type.", t);
-                }
-            }
-        }
-    }
-
-    @Override
-    public void cleanUp() {
-        // Make sure we let go of all widgets and their package contexts promptly. If we don't do
-        // this, and the associated application is uninstalled, it can cause a soft reboot.
-        int count = mAppWidgetContainer.getChildCount();
-        for (int i = 0; i < count; i++) {
-            KeyguardWidgetFrame frame = mAppWidgetContainer.getWidgetPageAt(i);
-            frame.removeAllViews();
-        }
-    }
-
-    /**
-     * In general, we enable unlocking the insecure keyguard with the menu key. However, there are
-     * some cases where we wish to disable it, notably when the menu button placement or technology
-     * is prone to false positives.
-     *
-     * @return true if the menu key should be enabled
-     */
-    private static final String ENABLE_MENU_KEY_FILE = "/data/local/enable_menu_key";
-    private boolean shouldEnableMenuKey() {
-        final Resources res = getResources();
-        final boolean configDisabled = res.getBoolean(
-                com.android.internal.R.bool.config_disableMenuKeyInLockScreen);
-        final boolean isTestHarness = ActivityManager.isRunningInTestHarness();
-        final boolean fileOverride = (new File(ENABLE_MENU_KEY_FILE)).exists();
-        return !configDisabled || isTestHarness || fileOverride;
-    }
-
-    public void goToUserSwitcher() {
-        mAppWidgetContainer.setCurrentPage(getWidgetPosition(R.id.keyguard_multi_user_selector));
-    }
-
-    public void goToWidget(int appWidgetId) {
-        mAppWidgetToShow = appWidgetId;
-        mSwitchPageRunnable.run();
-    }
-
-    public boolean handleMenuKey() {
-        // The following enables the MENU key to work for testing automation
-        if (shouldEnableMenuKey()) {
-            showNextSecurityScreenOrFinish(false);
-            return true;
-        }
-        return false;
-    }
-
-    public boolean handleBackKey() {
-        if (mCurrentSecuritySelection == SecurityMode.Account) {
-            // go back to primary screen and re-disable back
-            setBackButtonEnabled(false);
-            showPrimarySecurityScreen(false /*turningOff*/);
-            return true;
-        }
-        if (mCurrentSecuritySelection != SecurityMode.None) {
-            mCallback.dismiss(false);
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     *  Dismisses the keyguard by going to the next screen or making it gone.
-     */
-    public void dismiss() {
-        showNextSecurityScreenOrFinish(false);
-    }
-
-    public void showAssistant() {
-        final Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
-          .getAssistIntent(mContext, true, UserHandle.USER_CURRENT);
-
-        if (intent == null) return;
-
-        final ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext,
-                R.anim.keyguard_action_assist_enter, R.anim.keyguard_action_assist_exit,
-                getHandler(), null);
-
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-        mActivityLauncher.launchActivityWithAnimation(
-                intent, false, opts.toBundle(), null, null);
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardLinearLayout.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardLinearLayout.java
deleted file mode 100644
index 0fc54cd..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardLinearLayout.java
+++ /dev/null
@@ -1,46 +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.internal.policy.impl.keyguard;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.LinearLayout;
-
-/**
- * A layout that arranges its children into a special type of grid.
- */
-public class KeyguardLinearLayout extends LinearLayout {
-    int mTopChild = 0;
-
-    public KeyguardLinearLayout(Context context) {
-        this(context, null, 0);
-    }
-
-    public KeyguardLinearLayout(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public KeyguardLinearLayout(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    public void setTopChild(View child) {
-        int top = indexOfChild(child);
-        mTopChild = top;
-        invalidate();
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMessageArea.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMessageArea.java
deleted file mode 100644
index 9b58803..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMessageArea.java
+++ /dev/null
@@ -1,321 +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.policy.impl.keyguard;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.os.BatteryManager;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.util.Slog;
-import android.view.View;
-import android.widget.TextView;
-
-import libcore.util.MutableInt;
-
-import java.lang.ref.WeakReference;
-
-import com.android.internal.R;
-import com.android.internal.widget.ILockSettings;
-import com.android.internal.widget.LockPatternUtils;
-
-/***
- * Manages a number of views inside of the given layout. See below for a list of widgets.
- */
-class KeyguardMessageArea extends TextView {
-    /** Handler token posted with accessibility announcement runnables. */
-    private static final Object ANNOUNCE_TOKEN = new Object();
-
-    /**
-     * Delay before speaking an accessibility announcement. Used to prevent
-     * lift-to-type from interrupting itself.
-     */
-    private static final long ANNOUNCEMENT_DELAY = 250;
-
-    static final int CHARGING_ICON = 0; //R.drawable.ic_lock_idle_charging;
-    static final int BATTERY_LOW_ICON = 0; //R.drawable.ic_lock_idle_low_battery;
-
-    static final int SECURITY_MESSAGE_DURATION = 5000;
-    protected static final int FADE_DURATION = 750;
-
-    private static final String TAG = "KeyguardMessageArea";
-
-    // are we showing battery information?
-    boolean mShowingBatteryInfo = false;
-
-    // is the bouncer up?
-    boolean mShowingBouncer = false;
-
-    // last known plugged in state
-    boolean mCharging = false;
-
-    // last known battery level
-    int mBatteryLevel = 100;
-
-    KeyguardUpdateMonitor mUpdateMonitor;
-
-    // Timeout before we reset the message to show charging/owner info
-    long mTimeout = SECURITY_MESSAGE_DURATION;
-
-    // Shadowed text values
-    protected boolean mBatteryCharged;
-    protected boolean mBatteryIsLow;
-
-    private Handler mHandler;
-
-    CharSequence mMessage;
-    boolean mShowingMessage;
-    private CharSequence mSeparator;
-    private LockPatternUtils mLockPatternUtils;
-
-    Runnable mClearMessageRunnable = new Runnable() {
-        @Override
-        public void run() {
-            mMessage = null;
-            mShowingMessage = false;
-            if (mShowingBouncer) {
-                hideMessage(FADE_DURATION, true);
-            } else {
-                update();
-            }
-        }
-    };
-
-    public static class Helper implements SecurityMessageDisplay {
-        KeyguardMessageArea mMessageArea;
-        Helper(View v) {
-            mMessageArea = (KeyguardMessageArea) v.findViewById(R.id.keyguard_message_area);
-            if (mMessageArea == null) {
-                throw new RuntimeException("Can't find keyguard_message_area in " + v.getClass());
-            }
-        }
-
-        public void setMessage(CharSequence msg, boolean important) {
-            if (!TextUtils.isEmpty(msg) && important) {
-                mMessageArea.mMessage = msg;
-                mMessageArea.securityMessageChanged();
-            }
-        }
-
-        public void setMessage(int resId, boolean important) {
-            if (resId != 0 && important) {
-                mMessageArea.mMessage = mMessageArea.getContext().getResources().getText(resId);
-                mMessageArea.securityMessageChanged();
-            }
-        }
-
-        public void setMessage(int resId, boolean important, Object... formatArgs) {
-            if (resId != 0 && important) {
-                mMessageArea.mMessage = mMessageArea.getContext().getString(resId, formatArgs);
-                mMessageArea.securityMessageChanged();
-            }
-        }
-
-        @Override
-        public void showBouncer(int duration) {
-            mMessageArea.hideMessage(duration, false);
-            mMessageArea.mShowingBouncer = true;
-        }
-
-        @Override
-        public void hideBouncer(int duration) {
-            mMessageArea.showMessage(duration);
-            mMessageArea.mShowingBouncer = false;
-        }
-
-        @Override
-        public void setTimeout(int timeoutMs) {
-            mMessageArea.mTimeout = timeoutMs;
-        }
-    }
-
-    private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
-        @Override
-        public void onRefreshBatteryInfo(KeyguardUpdateMonitor.BatteryStatus status) {
-            mShowingBatteryInfo = status.isPluggedIn() || status.isBatteryLow();
-            mCharging = status.status == BatteryManager.BATTERY_STATUS_CHARGING
-                     || status.status == BatteryManager.BATTERY_STATUS_FULL;
-            mBatteryLevel = status.level;
-            mBatteryCharged = status.isCharged();
-            mBatteryIsLow = status.isBatteryLow();
-            update();
-        }
-    };
-
-    public KeyguardMessageArea(Context context) {
-        this(context, null);
-    }
-
-    public KeyguardMessageArea(Context context, AttributeSet attrs) {
-        super(context, attrs);
-
-        mLockPatternUtils = new LockPatternUtils(context);
-
-        // This is required to ensure marquee works
-        setSelected(true);
-
-        // Registering this callback immediately updates the battery state, among other things.
-        mUpdateMonitor = KeyguardUpdateMonitor.getInstance(getContext());
-        mUpdateMonitor.registerCallback(mInfoCallback);
-        mHandler = new Handler(Looper.myLooper());
-
-        mSeparator = getResources().getString(R.string.kg_text_message_separator);
-
-        update();
-    }
-
-    public void securityMessageChanged() {
-        setAlpha(1f);
-        mShowingMessage = true;
-        update();
-        mHandler.removeCallbacks(mClearMessageRunnable);
-        if (mTimeout > 0) {
-            mHandler.postDelayed(mClearMessageRunnable, mTimeout);
-        }
-        mHandler.removeCallbacksAndMessages(ANNOUNCE_TOKEN);
-        mHandler.postAtTime(new AnnounceRunnable(this, getText()), ANNOUNCE_TOKEN,
-                (SystemClock.uptimeMillis() + ANNOUNCEMENT_DELAY));
-    }
-
-    /**
-     * Update the status lines based on these rules:
-     * AlarmStatus: Alarm state always gets it's own line.
-     * Status1 is shared between help, battery status and generic unlock instructions,
-     * prioritized in that order.
-     * @param showStatusLines status lines are shown if true
-     */
-    void update() {
-        MutableInt icon = new MutableInt(0);
-        CharSequence status = concat(getChargeInfo(icon), getOwnerInfo(), getCurrentMessage());
-        setCompoundDrawablesWithIntrinsicBounds(icon.value, 0, 0, 0);
-        setText(status);
-    }
-
-    private CharSequence concat(CharSequence... args) {
-        StringBuilder b = new StringBuilder();
-        if (!TextUtils.isEmpty(args[0])) {
-            b.append(args[0]);
-        }
-        for (int i = 1; i < args.length; i++) {
-            CharSequence text = args[i];
-            if (!TextUtils.isEmpty(text)) {
-                if (b.length() > 0) {
-                    b.append(mSeparator);
-                }
-                b.append(text);
-            }
-        }
-        return b.toString();
-    }
-
-    CharSequence getCurrentMessage() {
-        return mShowingMessage ? mMessage : null;
-    }
-
-    String getOwnerInfo() {
-        ContentResolver res = getContext().getContentResolver();
-        String info = null;
-        final boolean ownerInfoEnabled = mLockPatternUtils.isOwnerInfoEnabled();
-        if (ownerInfoEnabled && !mShowingMessage) {
-            info = mLockPatternUtils.getOwnerInfo(mLockPatternUtils.getCurrentUser());
-        }
-        return info;
-    }
-
-    private CharSequence getChargeInfo(MutableInt icon) {
-        CharSequence string = null;
-        if (mShowingBatteryInfo && !mShowingMessage) {
-            // Battery status
-            if (mCharging) {
-                // Charging, charged or waiting to charge.
-                string = getContext().getString(mBatteryCharged
-                        ? com.android.internal.R.string.lockscreen_charged
-                        : com.android.internal.R.string.lockscreen_plugged_in, mBatteryLevel);
-                icon.value = CHARGING_ICON;
-            } else if (mBatteryIsLow) {
-                // Battery is low
-                string = getContext().getString(
-                        com.android.internal.R.string.lockscreen_low_battery);
-                icon.value = BATTERY_LOW_ICON;
-            }
-        }
-        return string;
-    }
-
-    private void hideMessage(int duration, boolean thenUpdate) {
-        if (duration > 0) {
-            Animator anim = ObjectAnimator.ofFloat(this, "alpha", 0f);
-            anim.setDuration(duration);
-            if (thenUpdate) {
-                anim.addListener(new AnimatorListenerAdapter() {
-                        @Override
-                            public void onAnimationEnd(Animator animation) {
-                            update();
-                        }
-                });
-            }
-            anim.start();
-        } else {
-            setAlpha(0f);
-            if (thenUpdate) {
-                update();
-            }
-        }
-    }
-
-    private void showMessage(int duration) {
-        if (duration > 0) {
-            Animator anim = ObjectAnimator.ofFloat(this, "alpha", 1f);
-            anim.setDuration(duration);
-            anim.start();
-        } else {
-            setAlpha(1f);
-        }
-    }
-
-    /**
-     * Runnable used to delay accessibility announcements.
-     */
-    private static class AnnounceRunnable implements Runnable {
-        private final WeakReference<View> mHost;
-        private final CharSequence mTextToAnnounce;
-
-        public AnnounceRunnable(View host, CharSequence textToAnnounce) {
-            mHost = new WeakReference<View>(host);
-            mTextToAnnounce = textToAnnounce;
-        }
-
-        @Override
-        public void run() {
-            final View host = mHost.get();
-            if (host != null) {
-                host.announceForAccessibility(mTextToAnnounce);
-            }
-        }
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserAvatar.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserAvatar.java
deleted file mode 100644
index 387e0ce..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserAvatar.java
+++ /dev/null
@@ -1,247 +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.internal.policy.impl.keyguard;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.content.pm.UserInfo;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Color;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import com.android.internal.R;
-
-class KeyguardMultiUserAvatar extends FrameLayout {
-    private static final String TAG = KeyguardMultiUserAvatar.class.getSimpleName();
-    private static final boolean DEBUG = KeyguardHostView.DEBUG;
-
-    private ImageView mUserImage;
-    private TextView mUserName;
-    private UserInfo mUserInfo;
-    private static final float ACTIVE_ALPHA = 1.0f;
-    private static final float INACTIVE_ALPHA = 1.0f;
-    private static final float ACTIVE_SCALE = 1.5f;
-    private static final float ACTIVE_TEXT_ALPHA = 0f;
-    private static final float INACTIVE_TEXT_ALPHA = 0.5f;
-    private static final int SWITCH_ANIMATION_DURATION = 150;
-
-    private final float mActiveAlpha;
-    private final float mActiveScale;
-    private final float mActiveTextAlpha;
-    private final float mInactiveAlpha;
-    private final float mInactiveTextAlpha;
-    private final float mShadowRadius;
-    private final float mStroke;
-    private final float mIconSize;
-    private final int mFrameColor;
-    private final int mFrameShadowColor;
-    private final int mTextColor;
-    private final int mHighlightColor;
-
-    private boolean mTouched;
-
-    private boolean mActive;
-    private boolean mInit = true;
-    private KeyguardMultiUserSelectorView mUserSelector;
-    private KeyguardCircleFramedDrawable mFramed;
-    private boolean mPressLock;
-
-    public static KeyguardMultiUserAvatar fromXml(int resId, Context context,
-            KeyguardMultiUserSelectorView userSelector, UserInfo info) {
-        KeyguardMultiUserAvatar icon = (KeyguardMultiUserAvatar)
-                LayoutInflater.from(context).inflate(resId, userSelector, false);
-
-        icon.init(info, userSelector);
-        return icon;
-    }
-
-    public KeyguardMultiUserAvatar(Context context) {
-        this(context, null, 0);
-    }
-
-    public KeyguardMultiUserAvatar(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public KeyguardMultiUserAvatar(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-
-        Resources res = mContext.getResources();
-        mTextColor = res.getColor(R.color.keyguard_avatar_nick_color);
-        mIconSize = res.getDimension(R.dimen.keyguard_avatar_size);
-        mStroke = res.getDimension(R.dimen.keyguard_avatar_frame_stroke_width);
-        mShadowRadius = res.getDimension(R.dimen.keyguard_avatar_frame_shadow_radius);
-        mFrameColor = res.getColor(R.color.keyguard_avatar_frame_color);
-        mFrameShadowColor = res.getColor(R.color.keyguard_avatar_frame_shadow_color);
-        mHighlightColor = res.getColor(R.color.keyguard_avatar_frame_pressed_color);
-        mActiveTextAlpha = ACTIVE_TEXT_ALPHA;
-        mInactiveTextAlpha = INACTIVE_TEXT_ALPHA;
-        mActiveScale = ACTIVE_SCALE;
-        mActiveAlpha = ACTIVE_ALPHA;
-        mInactiveAlpha = INACTIVE_ALPHA;
-
-        mTouched = false;
-
-        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
-    }
-
-    protected String rewriteIconPath(String path) {
-        if (!this.getClass().getName().contains("internal")) {
-            return path.replace("system", "data");
-        }
-        return path;
-    }
-
-    public void init(UserInfo user, KeyguardMultiUserSelectorView userSelector) {
-        mUserInfo = user;
-        mUserSelector = userSelector;
-
-        mUserImage = (ImageView) findViewById(R.id.keyguard_user_avatar);
-        mUserName = (TextView) findViewById(R.id.keyguard_user_name);
-
-        mFramed = (KeyguardCircleFramedDrawable)
-                KeyguardViewMediator.getAvatarCache().get(user.id);
-
-        // If we can't find it or the params don't match, create the drawable again
-        if (mFramed == null
-                || !mFramed.verifyParams(mIconSize, mFrameColor, mStroke, mFrameShadowColor,
-                        mShadowRadius, mHighlightColor)) {
-            Bitmap icon = null;
-            try {
-                icon = BitmapFactory.decodeFile(rewriteIconPath(user.iconPath));
-            } catch (Exception e) {
-                if (DEBUG) Log.d(TAG, "failed to open profile icon " + user.iconPath, e);
-            }
-
-            if (icon == null) {
-                icon = BitmapFactory.decodeResource(mContext.getResources(),
-                        com.android.internal.R.drawable.ic_contact_picture);
-            }
-
-            mFramed = new KeyguardCircleFramedDrawable(icon, (int) mIconSize, mFrameColor, mStroke,
-                    mFrameShadowColor, mShadowRadius, mHighlightColor);
-            KeyguardViewMediator.getAvatarCache().put(user.id, mFramed);
-        }
-
-        mFramed.reset();
-
-        mUserImage.setImageDrawable(mFramed);
-        mUserName.setText(mUserInfo.name);
-        setOnClickListener(mUserSelector);
-        mInit = false;
-    }
-
-    public void setActive(boolean active, boolean animate, final Runnable onComplete) {
-        if (mActive != active || mInit) {
-            mActive = active;
-
-            if (active) {
-                KeyguardLinearLayout parent = (KeyguardLinearLayout) getParent();
-                parent.setTopChild(this);
-                // TODO: Create an appropriate asset when string changes are possible.
-                setContentDescription(mUserName.getText()
-                        + ". " + mContext.getString(R.string.user_switched, ""));
-            } else {
-                setContentDescription(mUserName.getText());
-            }
-        }
-        updateVisualsForActive(mActive, animate, SWITCH_ANIMATION_DURATION, onComplete);
-    }
-
-    void updateVisualsForActive(boolean active, boolean animate, int duration,
-            final Runnable onComplete) {
-        final float finalAlpha = active ? mActiveAlpha : mInactiveAlpha;
-        final float initAlpha = active ? mInactiveAlpha : mActiveAlpha;
-        final float finalScale = active ? 1f : 1f / mActiveScale;
-        final float initScale = mFramed.getScale();
-        final int finalTextAlpha = active ? (int) (mActiveTextAlpha * 255) :
-                (int) (mInactiveTextAlpha * 255);
-        final int initTextAlpha = active ? (int) (mInactiveTextAlpha * 255) :
-                (int) (mActiveTextAlpha * 255);
-        int textColor = mTextColor;
-        mUserName.setTextColor(textColor);
-
-        if (animate && mTouched) {
-            ValueAnimator va = ValueAnimator.ofFloat(0f, 1f);
-            va.addUpdateListener(new AnimatorUpdateListener() {
-                @Override
-                public void onAnimationUpdate(ValueAnimator animation) {
-                    float r = animation.getAnimatedFraction();
-                    float scale = (1 - r) * initScale + r * finalScale;
-                    float alpha = (1 - r) * initAlpha + r * finalAlpha;
-                    int textAlpha = (int) ((1 - r) * initTextAlpha + r * finalTextAlpha);
-                    mFramed.setScale(scale);
-                    mUserImage.setAlpha(alpha);
-                    mUserName.setTextColor(Color.argb(textAlpha, 255, 255, 255));
-                    mUserImage.invalidate();
-                }
-            });
-            va.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    if (onComplete != null) {
-                        onComplete.run();
-                    }
-                }
-            });
-            va.setDuration(duration);
-            va.start();
-        } else {
-            mFramed.setScale(finalScale);
-            mUserImage.setAlpha(finalAlpha);
-            mUserName.setTextColor(Color.argb(finalTextAlpha, 255, 255, 255));
-            if (onComplete != null) {
-                post(onComplete);
-            }
-        }
-
-        mTouched = true;
-    }
-
-    @Override
-    public void setPressed(boolean pressed) {
-        if (mPressLock && !pressed) {
-            return;
-        }
-
-        if (mPressLock || !pressed || isClickable()) {
-            super.setPressed(pressed);
-            mFramed.setPressed(pressed);
-            mUserImage.invalidate();
-        }
-    }
-
-    public void lockPressed(boolean pressed) {
-        mPressLock = pressed;
-        setPressed(pressed);
-    }
-
-    public UserInfo getUserInfo() {
-        return mUserInfo;
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserSelectorView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserSelectorView.java
deleted file mode 100644
index f9ea5bb..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMultiUserSelectorView.java
+++ /dev/null
@@ -1,172 +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.internal.policy.impl.keyguard;
-
-import android.app.ActivityManagerNative;
-import android.content.Context;
-import android.content.pm.UserInfo;
-import android.os.RemoteException;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-
-import com.android.internal.R;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-
-public class KeyguardMultiUserSelectorView extends FrameLayout implements View.OnClickListener {
-    private static final String TAG = "KeyguardMultiUserSelectorView";
-
-    private ViewGroup mUsersGrid;
-    private KeyguardMultiUserAvatar mActiveUserAvatar;
-    private KeyguardHostView.UserSwitcherCallback mCallback;
-    private static final int FADE_OUT_ANIMATION_DURATION = 100;
-
-    public KeyguardMultiUserSelectorView(Context context) {
-        this(context, null, 0);
-    }
-
-    public KeyguardMultiUserSelectorView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public KeyguardMultiUserSelectorView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    protected void onFinishInflate () {
-        mUsersGrid = (ViewGroup) findViewById(R.id.keyguard_users_grid);
-        mUsersGrid.removeAllViews();
-        setClipChildren(false);
-        setClipToPadding(false);
-
-    }
-
-    public void setCallback(KeyguardHostView.UserSwitcherCallback callback) {
-        mCallback = callback;
-    }
-
-    public void addUsers(Collection<UserInfo> userList) {
-        UserInfo activeUser;
-        try {
-            activeUser = ActivityManagerNative.getDefault().getCurrentUser();
-        } catch (RemoteException re) {
-            activeUser = null;
-        }
-
-        ArrayList<UserInfo> users = new ArrayList<UserInfo>(userList);
-        Collections.sort(users, mOrderAddedComparator);
-
-        for (UserInfo user: users) {
-            KeyguardMultiUserAvatar uv = createAndAddUser(user);
-            if (user.id == activeUser.id) {
-                mActiveUserAvatar = uv;
-            }
-            uv.setActive(false, false, null);
-        }
-        mActiveUserAvatar.lockPressed(true);
-    }
-
-    public void finalizeActiveUserView(boolean animate) {
-        if (animate) {
-            getHandler().postDelayed(new Runnable() {
-                    @Override
-                        public void run() {
-                        finalizeActiveUserNow(true);
-                    }
-                }, 500);
-        } else {
-            finalizeActiveUserNow(animate);
-        }
-    }
-
-    void finalizeActiveUserNow(boolean animate) {
-        mActiveUserAvatar.lockPressed(false);
-        mActiveUserAvatar.setActive(true, animate, null);
-    }
-
-    Comparator<UserInfo> mOrderAddedComparator = new Comparator<UserInfo>() {
-        @Override
-        public int compare(UserInfo lhs, UserInfo rhs) {
-            return (lhs.serialNumber - rhs.serialNumber);
-        }
-    };
-
-    private KeyguardMultiUserAvatar createAndAddUser(UserInfo user) {
-        KeyguardMultiUserAvatar uv = KeyguardMultiUserAvatar.fromXml(
-                R.layout.keyguard_multi_user_avatar, mContext, this, user);
-        mUsersGrid.addView(uv);
-        return uv;
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent event) {
-        if(event.getActionMasked() != MotionEvent.ACTION_CANCEL && mCallback != null) {
-            mCallback.userActivity();
-        }
-        return false;
-    }
-
-    private void setAllClickable(boolean clickable)
-    {
-        for(int i = 0; i < mUsersGrid.getChildCount(); i++) {
-            View v = mUsersGrid.getChildAt(i);
-            v.setClickable(clickable);
-            v.setPressed(false);
-        }
-    }
-
-    @Override
-    public void onClick(View v) {
-        if (!(v instanceof KeyguardMultiUserAvatar)) return;
-        final KeyguardMultiUserAvatar avatar = (KeyguardMultiUserAvatar) v;
-        if (avatar.isClickable()) { // catch race conditions
-            if (mActiveUserAvatar == avatar) {
-                // If they click the currently active user, show the unlock hint
-                mCallback.showUnlockHint();
-                return;
-            } else {
-                // Reset the previously active user to appear inactive
-                mCallback.hideSecurityView(FADE_OUT_ANIMATION_DURATION);
-                setAllClickable(false);
-                avatar.lockPressed(true);
-                mActiveUserAvatar.setActive(false, true, new Runnable() {
-                    @Override
-                    public void run() {
-                        mActiveUserAvatar = avatar;
-                        if (this.getClass().getName().contains("internal")) {
-                            try {
-                                ActivityManagerNative.getDefault()
-                                        .switchUser(avatar.getUserInfo().id);
-                            } catch (RemoteException re) {
-                                Log.e(TAG, "Couldn't switch user " + re);
-                            }
-                        } else {
-                            setAllClickable(true);
-                        }
-                    }
-                });
-            }
-        }
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPINView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPINView.java
deleted file mode 100644
index fa80352..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPINView.java
+++ /dev/null
@@ -1,120 +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.internal.policy.impl.keyguard;
-
-import android.content.Context;
-import android.text.Editable;
-import android.text.InputType;
-import android.text.TextWatcher;
-import android.text.method.DigitsKeyListener;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.TextView.OnEditorActionListener;
-
-import com.android.internal.R;
-
-/**
- * Displays a PIN pad for unlocking.
- */
-public class KeyguardPINView extends KeyguardAbsKeyInputView
-        implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
-
-    public KeyguardPINView(Context context) {
-        this(context, null);
-    }
-
-    public KeyguardPINView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    protected void resetState() {
-        if (KeyguardUpdateMonitor.getInstance(mContext).getMaxBiometricUnlockAttemptsReached()) {
-            mSecurityMessageDisplay.setMessage(R.string.faceunlock_multiple_failures, true);
-        } else {
-            mSecurityMessageDisplay.setMessage(R.string.kg_pin_instructions, false);
-        }
-        mPasswordEntry.setEnabled(true);
-    }
-
-    @Override
-    protected int getPasswordTextViewId() {
-        return R.id.pinEntry;
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-
-        final View ok = findViewById(R.id.key_enter);
-        if (ok != null) {
-            ok.setOnClickListener(new View.OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    doHapticKeyClick();
-                    if (mPasswordEntry.isEnabled()) {
-                        verifyPasswordAndUnlock();
-                    }
-                }
-            });
-            ok.setOnHoverListener(new LiftToActivateListener(getContext()));
-        }
-
-        // The delete button is of the PIN keyboard itself in some (e.g. tablet) layouts,
-        // not a separate view
-        View pinDelete = findViewById(R.id.delete_button);
-        if (pinDelete != null) {
-            pinDelete.setVisibility(View.VISIBLE);
-            pinDelete.setOnClickListener(new OnClickListener() {
-                public void onClick(View v) {
-                    // check for time-based lockouts
-                    if (mPasswordEntry.isEnabled()) {
-                        CharSequence str = mPasswordEntry.getText();
-                        if (str.length() > 0) {
-                            mPasswordEntry.setText(str.subSequence(0, str.length()-1));
-                        }
-                    }
-                    doHapticKeyClick();
-                }
-            });
-            pinDelete.setOnLongClickListener(new View.OnLongClickListener() {
-                public boolean onLongClick(View v) {
-                    // check for time-based lockouts
-                    if (mPasswordEntry.isEnabled()) {
-                        mPasswordEntry.setText("");
-                    }
-                    doHapticKeyClick();
-                    return true;
-                }
-            });
-        }
-
-        mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance());
-        mPasswordEntry.setInputType(InputType.TYPE_CLASS_NUMBER
-                | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
-
-        mPasswordEntry.requestFocus();
-    }
-
-    @Override
-    public void showUsabilityHint() {
-    }
-
-    @Override
-    public int getWrongPasswordStringId() {
-        return R.string.kg_wrong_pin;
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPasswordView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPasswordView.java
deleted file mode 100644
index d52c993..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPasswordView.java
+++ /dev/null
@@ -1,208 +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.internal.policy.impl.keyguard;
-
-import android.app.admin.DevicePolicyManager;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.text.Editable;
-import android.text.InputType;
-import android.text.TextWatcher;
-import android.text.method.DigitsKeyListener;
-import android.text.method.TextKeyListener;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.inputmethod.InputMethodInfo;
-import android.view.inputmethod.InputMethodManager;
-import android.view.inputmethod.InputMethodSubtype;
-import android.widget.TextView.OnEditorActionListener;
-
-import com.android.internal.R;
-import com.android.internal.widget.PasswordEntryKeyboardHelper;
-import com.android.internal.widget.PasswordEntryKeyboardView;
-
-import java.util.List;
-/**
- * Displays an alphanumeric (latin-1) key entry for the user to enter
- * an unlock password
- */
-
-public class KeyguardPasswordView extends KeyguardAbsKeyInputView
-        implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
-
-    private final boolean mShowImeAtScreenOn;
-
-    InputMethodManager mImm;
-
-    public KeyguardPasswordView(Context context) {
-        this(context, null);
-    }
-
-    public KeyguardPasswordView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        mShowImeAtScreenOn = context.getResources().
-                getBoolean(R.bool.kg_show_ime_at_screen_on);
-    }
-
-    protected void resetState() {
-        mSecurityMessageDisplay.setMessage(R.string.kg_password_instructions, false);
-        mPasswordEntry.setEnabled(true);
-    }
-
-    @Override
-    protected int getPasswordTextViewId() {
-        return R.id.passwordEntry;
-    }
-
-    @Override
-    public boolean needsInput() {
-        return true;
-    }
-
-    @Override
-    public void onResume(int reason) {
-        super.onResume(reason);
-        mPasswordEntry.requestFocus();
-        if (reason != KeyguardSecurityView.SCREEN_ON || mShowImeAtScreenOn) {
-            mImm.showSoftInput(mPasswordEntry, InputMethodManager.SHOW_IMPLICIT);
-        }
-    }
-
-    @Override
-    public void onPause() {
-        super.onPause();
-        mImm.hideSoftInputFromWindow(getWindowToken(), 0);
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-
-        boolean imeOrDeleteButtonVisible = false;
-
-        mImm = (InputMethodManager) getContext().getSystemService(
-                Context.INPUT_METHOD_SERVICE);
-
-        mPasswordEntry.setKeyListener(TextKeyListener.getInstance());
-        mPasswordEntry.setInputType(InputType.TYPE_CLASS_TEXT
-                | InputType.TYPE_TEXT_VARIATION_PASSWORD);
-
-        // Poke the wakelock any time the text is selected or modified
-        mPasswordEntry.setOnClickListener(new OnClickListener() {
-            public void onClick(View v) {
-                mCallback.userActivity(0); // TODO: customize timeout for text?
-            }
-        });
-
-        mPasswordEntry.addTextChangedListener(new TextWatcher() {
-            public void onTextChanged(CharSequence s, int start, int before, int count) {
-            }
-
-            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-            }
-
-            public void afterTextChanged(Editable s) {
-                if (mCallback != null) {
-                    mCallback.userActivity(0);
-                }
-            }
-        });
-
-        mPasswordEntry.requestFocus();
-
-        // If there's more than one IME, enable the IME switcher button
-        View switchImeButton = findViewById(R.id.switch_ime_button);
-        if (switchImeButton != null && hasMultipleEnabledIMEsOrSubtypes(mImm, false)) {
-            switchImeButton.setVisibility(View.VISIBLE);
-            imeOrDeleteButtonVisible = true;
-            switchImeButton.setOnClickListener(new OnClickListener() {
-                public void onClick(View v) {
-                    mCallback.userActivity(0); // Leave the screen on a bit longer
-                    mImm.showInputMethodPicker();
-                }
-            });
-        }
-
-        // If no icon is visible, reset the start margin on the password field so the text is
-        // still centered.
-        if (!imeOrDeleteButtonVisible) {
-            android.view.ViewGroup.LayoutParams params = mPasswordEntry.getLayoutParams();
-            if (params instanceof MarginLayoutParams) {
-                final MarginLayoutParams mlp = (MarginLayoutParams) params;
-                mlp.setMarginStart(0);
-                mPasswordEntry.setLayoutParams(params);
-            }
-        }
-    }
-
-    /**
-     * Method adapted from com.android.inputmethod.latin.Utils
-     *
-     * @param imm The input method manager
-     * @param shouldIncludeAuxiliarySubtypes
-     * @return true if we have multiple IMEs to choose from
-     */
-    private boolean hasMultipleEnabledIMEsOrSubtypes(InputMethodManager imm,
-            final boolean shouldIncludeAuxiliarySubtypes) {
-        final List<InputMethodInfo> enabledImis = imm.getEnabledInputMethodList();
-
-        // Number of the filtered IMEs
-        int filteredImisCount = 0;
-
-        for (InputMethodInfo imi : enabledImis) {
-            // We can return true immediately after we find two or more filtered IMEs.
-            if (filteredImisCount > 1) return true;
-            final List<InputMethodSubtype> subtypes =
-                    imm.getEnabledInputMethodSubtypeList(imi, true);
-            // IMEs that have no subtypes should be counted.
-            if (subtypes.isEmpty()) {
-                ++filteredImisCount;
-                continue;
-            }
-
-            int auxCount = 0;
-            for (InputMethodSubtype subtype : subtypes) {
-                if (subtype.isAuxiliary()) {
-                    ++auxCount;
-                }
-            }
-            final int nonAuxCount = subtypes.size() - auxCount;
-
-            // IMEs that have one or more non-auxiliary subtypes should be counted.
-            // If shouldIncludeAuxiliarySubtypes is true, IMEs that have two or more auxiliary
-            // subtypes should be counted as well.
-            if (nonAuxCount > 0 || (shouldIncludeAuxiliarySubtypes && auxCount > 1)) {
-                ++filteredImisCount;
-                continue;
-            }
-        }
-
-        return filteredImisCount > 1
-        // imm.getEnabledInputMethodSubtypeList(null, false) will return the current IME's enabled
-        // input method subtype (The current IME should be LatinIME.)
-                || imm.getEnabledInputMethodSubtypeList(null, false).size() > 1;
-    }
-
-    @Override
-    public void showUsabilityHint() {
-    }
-
-    @Override
-    public int getWrongPasswordStringId() {
-        return R.string.kg_wrong_password;
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java
deleted file mode 100644
index e114b78..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java
+++ /dev/null
@@ -1,412 +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.internal.policy.impl.keyguard;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.accounts.AccountManagerCallback;
-import android.accounts.AccountManagerFuture;
-import android.accounts.AuthenticatorException;
-import android.accounts.OperationCanceledException;
-import android.content.Context;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.os.CountDownTimer;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.MotionEvent;
-import android.view.View;
-import android.widget.Button;
-import android.widget.LinearLayout;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.LockPatternView;
-import com.android.internal.R;
-
-import java.io.IOException;
-import java.util.List;
-
-public class KeyguardPatternView extends LinearLayout implements KeyguardSecurityView {
-
-    private static final String TAG = "SecurityPatternView";
-    private static final boolean DEBUG = false;
-
-    // how long before we clear the wrong pattern
-    private static final int PATTERN_CLEAR_TIMEOUT_MS = 2000;
-
-    // how long we stay awake after each key beyond MIN_PATTERN_BEFORE_POKE_WAKELOCK
-    private static final int UNLOCK_PATTERN_WAKE_INTERVAL_MS = 7000;
-
-    // how long we stay awake after the user hits the first dot.
-    private static final int UNLOCK_PATTERN_WAKE_INTERVAL_FIRST_DOTS_MS = 2000;
-
-    // how many cells the user has to cross before we poke the wakelock
-    private static final int MIN_PATTERN_BEFORE_POKE_WAKELOCK = 2;
-
-    private int mFailedPatternAttemptsSinceLastTimeout = 0;
-    private int mTotalFailedPatternAttempts = 0;
-    private CountDownTimer mCountdownTimer = null;
-    private LockPatternUtils mLockPatternUtils;
-    private LockPatternView mLockPatternView;
-    private Button mForgotPatternButton;
-    private KeyguardSecurityCallback mCallback;
-    private boolean mEnableFallback;
-
-    /**
-     * Keeps track of the last time we poked the wake lock during dispatching of the touch event.
-     * Initialized to something guaranteed to make us poke the wakelock when the user starts
-     * drawing the pattern.
-     * @see #dispatchTouchEvent(android.view.MotionEvent)
-     */
-    private long mLastPokeTime = -UNLOCK_PATTERN_WAKE_INTERVAL_MS;
-
-    /**
-     * Useful for clearing out the wrong pattern after a delay
-     */
-    private Runnable mCancelPatternRunnable = new Runnable() {
-        public void run() {
-            mLockPatternView.clearPattern();
-        }
-    };
-    private Rect mTempRect = new Rect();
-    private SecurityMessageDisplay mSecurityMessageDisplay;
-    private View mEcaView;
-    private Drawable mBouncerFrame;
-
-    enum FooterMode {
-        Normal,
-        ForgotLockPattern,
-        VerifyUnlocked
-    }
-
-    public KeyguardPatternView(Context context) {
-        this(context, null);
-    }
-
-    public KeyguardPatternView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public void setKeyguardCallback(KeyguardSecurityCallback callback) {
-        mCallback = callback;
-    }
-
-    public void setLockPatternUtils(LockPatternUtils utils) {
-        mLockPatternUtils = utils;
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-        mLockPatternUtils = mLockPatternUtils == null
-                ? new LockPatternUtils(mContext) : mLockPatternUtils;
-
-        mLockPatternView = (LockPatternView) findViewById(R.id.lockPatternView);
-        mLockPatternView.setSaveEnabled(false);
-        mLockPatternView.setFocusable(false);
-        mLockPatternView.setOnPatternListener(new UnlockPatternListener());
-
-        // stealth mode will be the same for the life of this screen
-        mLockPatternView.setInStealthMode(!mLockPatternUtils.isVisiblePatternEnabled());
-
-        // vibrate mode will be the same for the life of this screen
-        mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled());
-
-        mForgotPatternButton = (Button) findViewById(R.id.forgot_password_button);
-        // note: some configurations don't have an emergency call area
-        if (mForgotPatternButton != null) {
-            mForgotPatternButton.setText(R.string.kg_forgot_pattern_button_text);
-            mForgotPatternButton.setOnClickListener(new OnClickListener() {
-                public void onClick(View v) {
-                    mCallback.showBackupSecurity();
-                }
-            });
-        }
-
-        setFocusableInTouchMode(true);
-
-        maybeEnableFallback(mContext);
-        mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
-        mEcaView = findViewById(R.id.keyguard_selector_fade_container);
-        View bouncerFrameView = findViewById(R.id.keyguard_bouncer_frame);
-        if (bouncerFrameView != null) {
-            mBouncerFrame = bouncerFrameView.getBackground();
-        }
-    }
-
-    private void updateFooter(FooterMode mode) {
-        if (mForgotPatternButton == null) return; // no ECA? no footer
-
-        switch (mode) {
-            case Normal:
-                if (DEBUG) Log.d(TAG, "mode normal");
-                mForgotPatternButton.setVisibility(View.GONE);
-                break;
-            case ForgotLockPattern:
-                if (DEBUG) Log.d(TAG, "mode ForgotLockPattern");
-                mForgotPatternButton.setVisibility(View.VISIBLE);
-                break;
-            case VerifyUnlocked:
-                if (DEBUG) Log.d(TAG, "mode VerifyUnlocked");
-                mForgotPatternButton.setVisibility(View.GONE);
-        }
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev) {
-        boolean result = super.onTouchEvent(ev);
-        // as long as the user is entering a pattern (i.e sending a touch event that was handled
-        // by this screen), keep poking the wake lock so that the screen will stay on.
-        final long elapsed = SystemClock.elapsedRealtime() - mLastPokeTime;
-        if (result && (elapsed > (UNLOCK_PATTERN_WAKE_INTERVAL_MS - 100))) {
-            mLastPokeTime = SystemClock.elapsedRealtime();
-        }
-        mTempRect.set(0, 0, 0, 0);
-        offsetRectIntoDescendantCoords(mLockPatternView, mTempRect);
-        ev.offsetLocation(mTempRect.left, mTempRect.top);
-        result = mLockPatternView.dispatchTouchEvent(ev) || result;
-        ev.offsetLocation(-mTempRect.left, -mTempRect.top);
-        return result;
-    }
-
-    public void reset() {
-        // reset lock pattern
-        mLockPatternView.enableInput();
-        mLockPatternView.setEnabled(true);
-        mLockPatternView.clearPattern();
-
-        // if the user is currently locked out, enforce it.
-        long deadline = mLockPatternUtils.getLockoutAttemptDeadline();
-        if (deadline != 0) {
-            handleAttemptLockout(deadline);
-        } else {
-            displayDefaultSecurityMessage();
-        }
-
-        // the footer depends on how many total attempts the user has failed
-        if (mCallback.isVerifyUnlockOnly()) {
-            updateFooter(FooterMode.VerifyUnlocked);
-        } else if (mEnableFallback &&
-                (mTotalFailedPatternAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT)) {
-            updateFooter(FooterMode.ForgotLockPattern);
-        } else {
-            updateFooter(FooterMode.Normal);
-        }
-
-    }
-
-    private void displayDefaultSecurityMessage() {
-        if (KeyguardUpdateMonitor.getInstance(mContext).getMaxBiometricUnlockAttemptsReached()) {
-            mSecurityMessageDisplay.setMessage(R.string.faceunlock_multiple_failures, true);
-        } else {
-            mSecurityMessageDisplay.setMessage(R.string.kg_pattern_instructions, false);
-        }
-    }
-
-    @Override
-    public void showUsabilityHint() {
-    }
-
-    /** TODO: hook this up */
-    public void cleanUp() {
-        if (DEBUG) Log.v(TAG, "Cleanup() called on " + this);
-        mLockPatternUtils = null;
-        mLockPatternView.setOnPatternListener(null);
-    }
-
-    @Override
-    public void onWindowFocusChanged(boolean hasWindowFocus) {
-        super.onWindowFocusChanged(hasWindowFocus);
-        if (hasWindowFocus) {
-            // when timeout dialog closes we want to update our state
-            reset();
-        }
-    }
-
-    private class UnlockPatternListener implements LockPatternView.OnPatternListener {
-
-        public void onPatternStart() {
-            mLockPatternView.removeCallbacks(mCancelPatternRunnable);
-        }
-
-        public void onPatternCleared() {
-        }
-
-        public void onPatternCellAdded(List<LockPatternView.Cell> pattern) {
-            // To guard against accidental poking of the wakelock, look for
-            // the user actually trying to draw a pattern of some minimal length.
-            if (pattern.size() > MIN_PATTERN_BEFORE_POKE_WAKELOCK) {
-                mCallback.userActivity(UNLOCK_PATTERN_WAKE_INTERVAL_MS);
-            } else {
-                // Give just a little extra time if they hit one of the first few dots
-                mCallback.userActivity(UNLOCK_PATTERN_WAKE_INTERVAL_FIRST_DOTS_MS);
-            }
-        }
-
-        public void onPatternDetected(List<LockPatternView.Cell> pattern) {
-            if (mLockPatternUtils.checkPattern(pattern)) {
-                mCallback.reportSuccessfulUnlockAttempt();
-                mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Correct);
-                mTotalFailedPatternAttempts = 0;
-                mCallback.dismiss(true);
-            } else {
-                if (pattern.size() > MIN_PATTERN_BEFORE_POKE_WAKELOCK) {
-                    mCallback.userActivity(UNLOCK_PATTERN_WAKE_INTERVAL_MS);
-                }
-                mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Wrong);
-                if (pattern.size() >= LockPatternUtils.MIN_PATTERN_REGISTER_FAIL) {
-                    mTotalFailedPatternAttempts++;
-                    mFailedPatternAttemptsSinceLastTimeout++;
-                    mCallback.reportFailedUnlockAttempt();
-                }
-                if (mFailedPatternAttemptsSinceLastTimeout
-                        >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) {
-                    long deadline = mLockPatternUtils.setLockoutAttemptDeadline();
-                    handleAttemptLockout(deadline);
-                } else {
-                    mSecurityMessageDisplay.setMessage(R.string.kg_wrong_pattern, true);
-                    mLockPatternView.postDelayed(mCancelPatternRunnable, PATTERN_CLEAR_TIMEOUT_MS);
-                }
-            }
-        }
-    }
-
-    private void maybeEnableFallback(Context context) {
-        // Ask the account manager if we have an account that can be used as a
-        // fallback in case the user forgets his pattern.
-        AccountAnalyzer accountAnalyzer = new AccountAnalyzer(AccountManager.get(context));
-        accountAnalyzer.start();
-    }
-
-    private class AccountAnalyzer implements AccountManagerCallback<Bundle> {
-        private final AccountManager mAccountManager;
-        private final Account[] mAccounts;
-        private int mAccountIndex;
-
-        private AccountAnalyzer(AccountManager accountManager) {
-            mAccountManager = accountManager;
-            mAccounts = accountManager.getAccountsByTypeAsUser("com.google",
-                    new UserHandle(mLockPatternUtils.getCurrentUser()));
-        }
-
-        private void next() {
-            // if we are ready to enable the fallback or if we depleted the list of accounts
-            // then finish and get out
-            if (mEnableFallback || mAccountIndex >= mAccounts.length) {
-                return;
-            }
-
-            // lookup the confirmCredentials intent for the current account
-            mAccountManager.confirmCredentialsAsUser(mAccounts[mAccountIndex], null, null, this,
-                    null, new UserHandle(mLockPatternUtils.getCurrentUser()));
-        }
-
-        public void start() {
-            mEnableFallback = false;
-            mAccountIndex = 0;
-            next();
-        }
-
-        public void run(AccountManagerFuture<Bundle> future) {
-            try {
-                Bundle result = future.getResult();
-                if (result.getParcelable(AccountManager.KEY_INTENT) != null) {
-                    mEnableFallback = true;
-                }
-            } catch (OperationCanceledException e) {
-                // just skip the account if we are unable to query it
-            } catch (IOException e) {
-                // just skip the account if we are unable to query it
-            } catch (AuthenticatorException e) {
-                // just skip the account if we are unable to query it
-            } finally {
-                mAccountIndex++;
-                next();
-            }
-        }
-    }
-
-    private void handleAttemptLockout(long elapsedRealtimeDeadline) {
-        mLockPatternView.clearPattern();
-        mLockPatternView.setEnabled(false);
-        final long elapsedRealtime = SystemClock.elapsedRealtime();
-        if (mEnableFallback) {
-            updateFooter(FooterMode.ForgotLockPattern);
-        }
-
-        mCountdownTimer = new CountDownTimer(elapsedRealtimeDeadline - elapsedRealtime, 1000) {
-
-            @Override
-            public void onTick(long millisUntilFinished) {
-                final int secondsRemaining = (int) (millisUntilFinished / 1000);
-                mSecurityMessageDisplay.setMessage(
-                        R.string.kg_too_many_failed_attempts_countdown, true, secondsRemaining);
-            }
-
-            @Override
-            public void onFinish() {
-                mLockPatternView.setEnabled(true);
-                displayDefaultSecurityMessage();
-                // TODO mUnlockIcon.setVisibility(View.VISIBLE);
-                mFailedPatternAttemptsSinceLastTimeout = 0;
-                if (mEnableFallback) {
-                    updateFooter(FooterMode.ForgotLockPattern);
-                } else {
-                    updateFooter(FooterMode.Normal);
-                }
-            }
-
-        }.start();
-    }
-
-    @Override
-    public boolean needsInput() {
-        return false;
-    }
-
-    @Override
-    public void onPause() {
-        if (mCountdownTimer != null) {
-            mCountdownTimer.cancel();
-            mCountdownTimer = null;
-        }
-    }
-
-    @Override
-    public void onResume(int reason) {
-        reset();
-    }
-
-    @Override
-    public KeyguardSecurityCallback getCallback() {
-        return mCallback;
-    }
-
-    @Override
-    public void showBouncer(int duration) {
-        KeyguardSecurityViewHelper.
-                showBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration);
-    }
-
-    @Override
-    public void hideBouncer(int duration) {
-        KeyguardSecurityViewHelper.
-                hideBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration);
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityCallback.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityCallback.java
deleted file mode 100644
index 7e6c108..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityCallback.java
+++ /dev/null
@@ -1,68 +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.internal.policy.impl.keyguard;
-
-import com.android.internal.policy.impl.keyguard.KeyguardHostView.OnDismissAction;
-
-public interface KeyguardSecurityCallback {
-
-    /**
-     * Dismiss the given security screen.
-     * @param securityVerified true if the user correctly entered credentials for the given screen.
-     */
-    void dismiss(boolean securityVerified);
-
-    /**
-     * Manually report user activity to keep the device awake. If timeout is 0,
-     * uses user-defined timeout.
-     * @param timeout
-     */
-    void userActivity(long timeout);
-
-    /**
-     * Checks if keyguard is in "verify credentials" mode.
-     * @return true if user has been asked to verify security.
-     */
-    boolean isVerifyUnlockOnly();
-
-    /**
-     * Call when user correctly enters their credentials
-     */
-    void reportSuccessfulUnlockAttempt();
-
-    /**
-     * Call when the user incorrectly enters their credentials
-     */
-    void reportFailedUnlockAttempt();
-
-    /**
-     * Gets the number of attempts thus far as reported by {@link #reportFailedUnlockAttempt()}
-     * @return number of failed attempts
-     */
-    int getFailedAttempts();
-
-    /**
-     * Shows the backup security for the current method.  If none available, this call is a no-op.
-     */
-    void showBackupSecurity();
-
-    /**
-     * Sets an action to perform after the user successfully enters their credentials.
-     * @param action
-     */
-    void setOnDismissAction(OnDismissAction action);
-
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityContainer.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityContainer.java
deleted file mode 100644
index 375a96a..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityContainer.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package com.android.internal.policy.impl.keyguard;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.FrameLayout;
-
-import com.android.internal.R;
-
-public class KeyguardSecurityContainer extends FrameLayout {
-    public KeyguardSecurityContainer(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public KeyguardSecurityContainer(Context context) {
-        this(null, null, 0);
-    }
-
-    public KeyguardSecurityContainer(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    KeyguardSecurityViewFlipper getFlipper() {
-        for (int i = 0; i < getChildCount(); i++) {
-            View child = getChildAt(i);
-            if (child instanceof KeyguardSecurityViewFlipper) {
-                return (KeyguardSecurityViewFlipper) child;
-            }
-        }
-        return null;
-    }
-
-    public void showBouncer(int duration) {
-        KeyguardSecurityViewFlipper flipper = getFlipper();
-        if (flipper != null) {
-            flipper.showBouncer(duration);
-        }
-    }
-
-    public void hideBouncer(int duration) {
-        KeyguardSecurityViewFlipper flipper = getFlipper();
-        if (flipper != null) {
-            flipper.hideBouncer(duration);
-        }
-    }
-}
-
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityModel.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityModel.java
deleted file mode 100644
index 7a69586..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityModel.java
+++ /dev/null
@@ -1,147 +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.internal.policy.impl.keyguard;
-
-import android.app.admin.DevicePolicyManager;
-import android.content.Context;
-import android.telephony.TelephonyManager;
-
-import com.android.internal.telephony.IccCardConstants;
-import com.android.internal.widget.LockPatternUtils;
-
-public class KeyguardSecurityModel {
-    /**
-     * The different types of security available for {@link Mode#UnlockScreen}.
-     * @see com.android.internal.policy.impl.LockPatternKeyguardView#getUnlockMode()
-     */
-    enum SecurityMode {
-        Invalid, // NULL state
-        None, // No security enabled
-        Pattern, // Unlock by drawing a pattern.
-        Password, // Unlock by entering an alphanumeric password
-        PIN, // Strictly numeric password
-        Biometric, // Unlock with a biometric key (e.g. finger print or face unlock)
-        Account, // Unlock by entering an account's login and password.
-        SimPin, // Unlock by entering a sim pin.
-        SimPuk // Unlock by entering a sim puk
-    }
-
-    private Context mContext;
-    private LockPatternUtils mLockPatternUtils;
-
-    KeyguardSecurityModel(Context context) {
-        mContext = context;
-        mLockPatternUtils = new LockPatternUtils(context);
-    }
-
-    void setLockPatternUtils(LockPatternUtils utils) {
-        mLockPatternUtils = utils;
-    }
-
-    /**
-     * Returns true if biometric unlock is installed and selected.  If this returns false there is
-     * no need to even construct the biometric unlock.
-     */
-    boolean isBiometricUnlockEnabled() {
-        return mLockPatternUtils.usingBiometricWeak()
-                && mLockPatternUtils.isBiometricWeakInstalled();
-    }
-
-    /**
-     * Returns true if a condition is currently suppressing the biometric unlock.  If this returns
-     * true there is no need to even construct the biometric unlock.
-     */
-    private boolean isBiometricUnlockSuppressed() {
-        KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
-        final boolean backupIsTimedOut = monitor.getFailedUnlockAttempts() >=
-                LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT;
-        return monitor.getMaxBiometricUnlockAttemptsReached() || backupIsTimedOut
-                || !monitor.isAlternateUnlockEnabled()
-                || monitor.getPhoneState() != TelephonyManager.CALL_STATE_IDLE;
-    }
-
-    SecurityMode getSecurityMode() {
-        KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
-        final IccCardConstants.State simState = updateMonitor.getSimState();
-        SecurityMode mode = SecurityMode.None;
-        if (simState == IccCardConstants.State.PIN_REQUIRED) {
-            mode = SecurityMode.SimPin;
-        } else if (simState == IccCardConstants.State.PUK_REQUIRED
-                && mLockPatternUtils.isPukUnlockScreenEnable()) {
-            mode = SecurityMode.SimPuk;
-        } else {
-            final int security = mLockPatternUtils.getKeyguardStoredPasswordQuality();
-            switch (security) {
-                case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
-                    mode = mLockPatternUtils.isLockPasswordEnabled() ?
-                            SecurityMode.PIN : SecurityMode.None;
-                    break;
-                case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
-                case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
-                case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
-                    mode = mLockPatternUtils.isLockPasswordEnabled() ?
-                            SecurityMode.Password : SecurityMode.None;
-                    break;
-
-                case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
-                case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED:
-                    if (mLockPatternUtils.isLockPatternEnabled()) {
-                        mode = mLockPatternUtils.isPermanentlyLocked() ?
-                            SecurityMode.Account : SecurityMode.Pattern;
-                    }
-                    break;
-
-                default:
-                    throw new IllegalStateException("Unknown unlock mode:" + mode);
-            }
-        }
-        return mode;
-    }
-
-    /**
-     * Some unlock methods can have an alternate, such as biometric unlocks (e.g. face unlock).
-     * This function decides if an alternate unlock is available and returns it. Otherwise,
-     * returns @param mode.
-     *
-     * @param mode the mode we want the alternate for
-     * @return alternate or the given mode
-     */
-    SecurityMode getAlternateFor(SecurityMode mode) {
-        if (isBiometricUnlockEnabled() && !isBiometricUnlockSuppressed()
-                && (mode == SecurityMode.Password
-                        || mode == SecurityMode.PIN
-                        || mode == SecurityMode.Pattern)) {
-            return SecurityMode.Biometric;
-        }
-        return mode; // no alternate, return what was given
-    }
-
-    /**
-     * Some unlock methods can have a backup which gives the user another way to get into
-     * the device. This is currently only supported for Biometric and Pattern unlock.
-     *
-     * @return backup method or current security mode
-     */
-    SecurityMode getBackupSecurityMode(SecurityMode mode) {
-        switch(mode) {
-            case Biometric:
-                return getSecurityMode();
-            case Pattern:
-                return SecurityMode.Account;
-        }
-        return mode; // no backup, return current security mode
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityView.java
deleted file mode 100644
index a3ac39c..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityView.java
+++ /dev/null
@@ -1,87 +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.internal.policy.impl.keyguard;
-
-import com.android.internal.widget.LockPatternUtils;
-
-public interface KeyguardSecurityView {
-    static public final int SCREEN_ON = 1;
-    static public final int VIEW_REVEALED = 2;
-
-    /**
-     * Interface back to keyguard to tell it when security
-     * @param callback
-     */
-    void setKeyguardCallback(KeyguardSecurityCallback callback);
-
-    /**
-     * Set {@link LockPatternUtils} object. Useful for providing a mock interface.
-     * @param utils
-     */
-    void setLockPatternUtils(LockPatternUtils utils);
-
-    /**
-     * Reset the view and prepare to take input. This should do things like clearing the
-     * password or pattern and clear error messages.
-     */
-    void reset();
-
-    /**
-     * Emulate activity life cycle within the view. When called, the view should clean up
-     * and prepare to be removed.
-     */
-    void onPause();
-
-    /**
-     * Emulate activity life cycle within this view.  When called, the view should prepare itself
-     * to be shown.
-     * @param reason the root cause of the event.
-     */
-    void onResume(int reason);
-
-    /**
-     * Inquire whether this view requires IME (keyboard) interaction.
-     *
-     * @return true if IME interaction is required.
-     */
-    boolean needsInput();
-
-    /**
-     * Get {@link KeyguardSecurityCallback} for the given object
-     * @return KeyguardSecurityCallback
-     */
-    KeyguardSecurityCallback getCallback();
-
-    /**
-     * Instruct the view to show usability hints, if any.
-     *
-     */
-    void showUsabilityHint();
-
-    /**
-     * Place the security view into bouncer mode.
-     * Animate transisiton if duration is non-zero.
-     * @param duration millisends for the transisiton animation.
-     */
-    void showBouncer(int duration);
-
-    /**
-     * Place the security view into non-bouncer mode.
-     * Animate transisiton if duration is non-zero.
-     * @param duration millisends for the transisiton animation.
-     */
-    void hideBouncer(int duration);
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewFlipper.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewFlipper.java
deleted file mode 100644
index aa31b00..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewFlipper.java
+++ /dev/null
@@ -1,279 +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.internal.policy.impl.keyguard;
-
-import com.android.internal.R;
-import com.android.internal.widget.LockPatternUtils;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewDebug;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.widget.FrameLayout;
-import android.widget.ViewFlipper;
-
-/**
- * Subclass of the current view flipper that allows us to overload dispatchTouchEvent() so
- * we can emulate {@link WindowManager.LayoutParams#FLAG_SLIPPERY} within a view hierarchy.
- *
- */
-public class KeyguardSecurityViewFlipper extends ViewFlipper implements KeyguardSecurityView {
-    private static final String TAG = "KeyguardSecurityViewFlipper";
-    private static final boolean DEBUG = false;
-
-    private Rect mTempRect = new Rect();
-
-    public KeyguardSecurityViewFlipper(Context context) {
-        this(context, null);
-    }
-
-    public KeyguardSecurityViewFlipper(Context context, AttributeSet attr) {
-        super(context, attr);
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev) {
-        boolean result = super.onTouchEvent(ev);
-        mTempRect.set(0, 0, 0, 0);
-        for (int i = 0; i < getChildCount(); i++) {
-            View child = getChildAt(i);
-            if (child.getVisibility() == View.VISIBLE) {
-                offsetRectIntoDescendantCoords(child, mTempRect);
-                ev.offsetLocation(mTempRect.left, mTempRect.top);
-                result = child.dispatchTouchEvent(ev) || result;
-                ev.offsetLocation(-mTempRect.left, -mTempRect.top);
-            }
-        }
-        return result;
-    }
-
-    KeyguardSecurityView getSecurityView() {
-        View child = getChildAt(getDisplayedChild());
-        if (child instanceof KeyguardSecurityView) {
-            return (KeyguardSecurityView) child;
-        }
-        return null;
-    }
-
-    @Override
-    public void setKeyguardCallback(KeyguardSecurityCallback callback) {
-        KeyguardSecurityView ksv = getSecurityView();
-        if (ksv != null) {
-            ksv.setKeyguardCallback(callback);
-        }
-    }
-
-    @Override
-    public void setLockPatternUtils(LockPatternUtils utils) {
-        KeyguardSecurityView ksv = getSecurityView();
-        if (ksv != null) {
-            ksv.setLockPatternUtils(utils);
-        }
-    }
-
-    @Override
-    public void reset() {
-        KeyguardSecurityView ksv = getSecurityView();
-        if (ksv != null) {
-            ksv.reset();
-        }
-    }
-
-    @Override
-    public void onPause() {
-        KeyguardSecurityView ksv = getSecurityView();
-        if (ksv != null) {
-            ksv.onPause();
-        }
-    }
-
-    @Override
-    public void onResume(int reason) {
-        KeyguardSecurityView ksv = getSecurityView();
-        if (ksv != null) {
-            ksv.onResume(reason);
-        }
-    }
-
-    @Override
-    public boolean needsInput() {
-        KeyguardSecurityView ksv = getSecurityView();
-        return (ksv != null) ? ksv.needsInput() : false;
-    }
-
-    @Override
-    public KeyguardSecurityCallback getCallback() {
-        KeyguardSecurityView ksv = getSecurityView();
-        return (ksv != null) ? ksv.getCallback() : null;
-    }
-
-    @Override
-    public void showUsabilityHint() {
-        KeyguardSecurityView ksv = getSecurityView();
-        if (ksv != null) {
-            ksv.showUsabilityHint();
-        }
-    }
-
-    @Override
-    public void showBouncer(int duration) {
-        KeyguardSecurityView active = getSecurityView();
-        for (int i = 0; i < getChildCount(); i++) {
-            View child = getChildAt(i);
-            if (child instanceof KeyguardSecurityView) {
-                KeyguardSecurityView ksv = (KeyguardSecurityView) child;
-                ksv.showBouncer(ksv == active ? duration : 0);
-            }
-        }
-    }
-
-    @Override
-    public void hideBouncer(int duration) {
-        KeyguardSecurityView active = getSecurityView();
-        for (int i = 0; i < getChildCount(); i++) {
-            View child = getChildAt(i);
-            if (child instanceof KeyguardSecurityView) {
-                KeyguardSecurityView ksv = (KeyguardSecurityView) child;
-                ksv.hideBouncer(ksv == active ? duration : 0);
-            }
-        }
-    }
-
-    @Override
-    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
-        return p instanceof LayoutParams;
-    }
-
-    @Override
-    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
-        return p instanceof LayoutParams ? new LayoutParams((LayoutParams) p) : new LayoutParams(p);
-    }
-
-    @Override
-    public LayoutParams generateLayoutParams(AttributeSet attrs) {
-        return new LayoutParams(getContext(), attrs);
-    }
-
-    @Override
-    protected void onMeasure(int widthSpec, int heightSpec) {
-        final int widthMode = MeasureSpec.getMode(widthSpec);
-        final int heightMode = MeasureSpec.getMode(heightSpec);
-        if (DEBUG && widthMode != MeasureSpec.AT_MOST) {
-            Log.w(TAG, "onMeasure: widthSpec " + MeasureSpec.toString(widthSpec) +
-                    " should be AT_MOST");
-        }
-        if (DEBUG && heightMode != MeasureSpec.AT_MOST) {
-            Log.w(TAG, "onMeasure: heightSpec " + MeasureSpec.toString(heightSpec) +
-                    " should be AT_MOST");
-        }
-
-        final int widthSize = MeasureSpec.getSize(widthSpec);
-        final int heightSize = MeasureSpec.getSize(heightSpec);
-        int maxWidth = widthSize;
-        int maxHeight = heightSize;
-        final int count = getChildCount();
-        for (int i = 0; i < count; i++) {
-            final View child = getChildAt(i);
-            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
-
-            if (lp.maxWidth > 0 && lp.maxWidth < maxWidth) {
-                maxWidth = lp.maxWidth;
-            }
-            if (lp.maxHeight > 0 && lp.maxHeight < maxHeight) {
-                maxHeight = lp.maxHeight;
-            }
-        }
-
-        final int wPadding = getPaddingLeft() + getPaddingRight();
-        final int hPadding = getPaddingTop() + getPaddingBottom();
-        maxWidth -= wPadding;
-        maxHeight -= hPadding;
-
-        int width = widthMode == MeasureSpec.EXACTLY ? widthSize : 0;
-        int height = heightMode == MeasureSpec.EXACTLY ? heightSize : 0;
-        for (int i = 0; i < count; i++) {
-            final View child = getChildAt(i);
-            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
-
-            final int childWidthSpec = makeChildMeasureSpec(maxWidth, lp.width);
-            final int childHeightSpec = makeChildMeasureSpec(maxHeight, lp.height);
-
-            child.measure(childWidthSpec, childHeightSpec);
-
-            width = Math.max(width, Math.min(child.getMeasuredWidth(), widthSize - wPadding));
-            height = Math.max(height, Math.min(child.getMeasuredHeight(), heightSize - hPadding));
-        }
-        setMeasuredDimension(width + wPadding, height + hPadding);
-    }
-
-    private int makeChildMeasureSpec(int maxSize, int childDimen) {
-        final int mode;
-        final int size;
-        switch (childDimen) {
-            case LayoutParams.WRAP_CONTENT:
-                mode = MeasureSpec.AT_MOST;
-                size = maxSize;
-                break;
-            case LayoutParams.MATCH_PARENT:
-                mode = MeasureSpec.EXACTLY;
-                size = maxSize;
-                break;
-            default:
-                mode = MeasureSpec.EXACTLY;
-                size = Math.min(maxSize, childDimen);
-                break;
-        }
-        return MeasureSpec.makeMeasureSpec(size, mode);
-    }
-
-    public static class LayoutParams extends FrameLayout.LayoutParams {
-        @ViewDebug.ExportedProperty(category = "layout")
-        public int maxWidth;
-
-        @ViewDebug.ExportedProperty(category = "layout")
-        public int maxHeight;
-
-        public LayoutParams(ViewGroup.LayoutParams other) {
-            super(other);
-        }
-
-        public LayoutParams(LayoutParams other) {
-            super(other);
-
-            maxWidth = other.maxWidth;
-            maxHeight = other.maxHeight;
-        }
-
-        public LayoutParams(Context c, AttributeSet attrs) {
-            super(c, attrs);
-
-            final TypedArray a = c.obtainStyledAttributes(attrs,
-                    R.styleable.KeyguardSecurityViewFlipper_Layout, 0, 0);
-            maxWidth = a.getDimensionPixelSize(
-                    R.styleable.KeyguardSecurityViewFlipper_Layout_layout_maxWidth, 0);
-            maxHeight = a.getDimensionPixelSize(
-                    R.styleable.KeyguardSecurityViewFlipper_Layout_layout_maxHeight, 0);
-            a.recycle();
-        }
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewHelper.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewHelper.java
deleted file mode 100644
index 3d59f8d..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewHelper.java
+++ /dev/null
@@ -1,94 +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.internal.policy.impl.keyguard;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
-import android.graphics.drawable.Drawable;
-import android.view.View;
-
-/**
- * Some common functions that are useful for KeyguardSecurityViews.
- */
-public class KeyguardSecurityViewHelper {
-
-    public static void showBouncer(SecurityMessageDisplay securityMessageDisplay,
-            final View ecaView, Drawable bouncerFrame, int duration) {
-        if (securityMessageDisplay != null) {
-            securityMessageDisplay.showBouncer(duration);
-        }
-        if (ecaView != null) {
-            if (duration > 0) {
-                Animator anim = ObjectAnimator.ofFloat(ecaView, "alpha", 0f);
-                anim.setDuration(duration);
-                anim.addListener(new AnimatorListenerAdapter() {
-                    private boolean mCanceled;
-                    @Override
-                    public void onAnimationCancel(Animator animation) {
-                        // Fail safe and show the emergency button in onAnimationEnd()
-                        mCanceled = true;
-                        ecaView.setAlpha(1f);
-                    }
-                    @Override
-                    public void onAnimationEnd(Animator animation) {
-                        ecaView.setVisibility(mCanceled ? View.VISIBLE : View.INVISIBLE);
-                    }
-                });
-                anim.start();
-            } else {
-                ecaView.setAlpha(0f);
-                ecaView.setVisibility(View.INVISIBLE);
-            }
-        }
-        if (bouncerFrame != null) {
-            if (duration > 0) {
-                Animator anim = ObjectAnimator.ofInt(bouncerFrame, "alpha", 0, 255);
-                anim.setDuration(duration);
-                anim.start();
-            } else {
-                bouncerFrame.setAlpha(255);
-            }
-        }
-    }
-
-    public static void hideBouncer(SecurityMessageDisplay securityMessageDisplay,
-            View ecaView, Drawable bouncerFrame, int duration) {
-        if (securityMessageDisplay != null) {
-            securityMessageDisplay.hideBouncer(duration);
-        }
-        if (ecaView != null) {
-            ecaView.setVisibility(View.VISIBLE);
-            if (duration > 0) {
-                Animator anim = ObjectAnimator.ofFloat(ecaView, "alpha", 1f);
-                anim.setDuration(duration);
-                anim.start();
-            } else {
-                ecaView.setAlpha(1f);
-            }
-        }
-        if (bouncerFrame != null) {
-            if (duration > 0) {
-                Animator anim = ObjectAnimator.ofInt(bouncerFrame, "alpha", 255, 0);
-                anim.setDuration(duration);
-                anim.start();
-            } else {
-                bouncerFrame.setAlpha(0);
-            }
-        }
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java
deleted file mode 100644
index 6859042..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java
+++ /dev/null
@@ -1,288 +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.internal.policy.impl.keyguard;
-
-import android.animation.ObjectAnimator;
-import android.app.SearchManager;
-import android.app.admin.DevicePolicyManager;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.drawable.Drawable;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.Slog;
-import android.view.View;
-import android.widget.LinearLayout;
-
-import com.android.internal.telephony.IccCardConstants.State;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.multiwaveview.GlowPadView;
-import com.android.internal.widget.multiwaveview.GlowPadView.OnTriggerListener;
-import com.android.internal.R;
-
-public class KeyguardSelectorView extends LinearLayout implements KeyguardSecurityView {
-    private static final boolean DEBUG = KeyguardHostView.DEBUG;
-    private static final String TAG = "SecuritySelectorView";
-    private static final String ASSIST_ICON_METADATA_NAME =
-        "com.android.systemui.action_assist_icon";
-
-    private KeyguardSecurityCallback mCallback;
-    private GlowPadView mGlowPadView;
-    private ObjectAnimator mAnim;
-    private View mFadeView;
-    private boolean mIsBouncing;
-    private boolean mCameraDisabled;
-    private boolean mSearchDisabled;
-    private LockPatternUtils mLockPatternUtils;
-    private SecurityMessageDisplay mSecurityMessageDisplay;
-    private Drawable mBouncerFrame;
-
-    OnTriggerListener mOnTriggerListener = new OnTriggerListener() {
-
-        public void onTrigger(View v, int target) {
-            final int resId = mGlowPadView.getResourceIdForTarget(target);
-            switch (resId) {
-                case com.android.internal.R.drawable.ic_action_assist_generic:
-                    Intent assistIntent =
-                            ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
-                            .getAssistIntent(mContext, true, UserHandle.USER_CURRENT);
-                    if (assistIntent != null) {
-                        mActivityLauncher.launchActivity(assistIntent, false, true, null, null);
-                    } else {
-                        Log.w(TAG, "Failed to get intent for assist activity");
-                    }
-                    mCallback.userActivity(0);
-                    break;
-
-                case com.android.internal.R.drawable.ic_lockscreen_camera:
-                    mActivityLauncher.launchCamera(null, null);
-                    mCallback.userActivity(0);
-                    break;
-
-                case com.android.internal.R.drawable.ic_lockscreen_unlock_phantom:
-                case com.android.internal.R.drawable.ic_lockscreen_unlock:
-                    mCallback.userActivity(0);
-                    mCallback.dismiss(false);
-                break;
-            }
-        }
-
-        public void onReleased(View v, int handle) {
-            if (!mIsBouncing) {
-                doTransition(mFadeView, 1.0f);
-            }
-        }
-
-        public void onGrabbed(View v, int handle) {
-            mCallback.userActivity(0);
-            doTransition(mFadeView, 0.0f);
-        }
-
-        public void onGrabbedStateChange(View v, int handle) {
-
-        }
-
-        public void onFinishFinalAnimation() {
-
-        }
-
-    };
-
-    KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
-
-        @Override
-        public void onDevicePolicyManagerStateChanged() {
-            updateTargets();
-        }
-
-        @Override
-        public void onSimStateChanged(State simState) {
-            updateTargets();
-        }
-    };
-
-    private final KeyguardActivityLauncher mActivityLauncher = new KeyguardActivityLauncher() {
-
-        @Override
-        KeyguardSecurityCallback getCallback() {
-            return mCallback;
-        }
-
-        @Override
-        LockPatternUtils getLockPatternUtils() {
-            return mLockPatternUtils;
-        }
-
-        @Override
-        Context getContext() {
-            return mContext;
-        }};
-
-    public KeyguardSelectorView(Context context) {
-        this(context, null);
-    }
-
-    public KeyguardSelectorView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        mLockPatternUtils = new LockPatternUtils(getContext());
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-        mGlowPadView = (GlowPadView) findViewById(R.id.glow_pad_view);
-        mGlowPadView.setOnTriggerListener(mOnTriggerListener);
-        updateTargets();
-
-        mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
-        View bouncerFrameView = findViewById(R.id.keyguard_selector_view_frame);
-        mBouncerFrame = bouncerFrameView.getBackground();
-    }
-
-    public void setCarrierArea(View carrierArea) {
-        mFadeView = carrierArea;
-    }
-
-    public boolean isTargetPresent(int resId) {
-        return mGlowPadView.getTargetPosition(resId) != -1;
-    }
-
-    @Override
-    public void showUsabilityHint() {
-        mGlowPadView.ping();
-    }
-
-    private void updateTargets() {
-        int currentUserHandle = mLockPatternUtils.getCurrentUser();
-        DevicePolicyManager dpm = mLockPatternUtils.getDevicePolicyManager();
-        int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, currentUserHandle);
-        boolean secureCameraDisabled = mLockPatternUtils.isSecure()
-                && (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0;
-        boolean cameraDisabledByAdmin = dpm.getCameraDisabled(null, currentUserHandle)
-                || secureCameraDisabled;
-        final KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(getContext());
-        boolean disabledBySimState = monitor.isSimLocked();
-        boolean cameraTargetPresent =
-            isTargetPresent(com.android.internal.R.drawable.ic_lockscreen_camera);
-        boolean searchTargetPresent =
-            isTargetPresent(com.android.internal.R.drawable.ic_action_assist_generic);
-
-        if (cameraDisabledByAdmin) {
-            Log.v(TAG, "Camera disabled by Device Policy");
-        } else if (disabledBySimState) {
-            Log.v(TAG, "Camera disabled by Sim State");
-        }
-        boolean currentUserSetup = 0 != Settings.Secure.getIntForUser(
-                mContext.getContentResolver(),
-                Settings.Secure.USER_SETUP_COMPLETE,
-                0 /*default */,
-                currentUserHandle);
-        boolean searchActionAvailable =
-                ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
-                .getAssistIntent(mContext, false, UserHandle.USER_CURRENT) != null;
-        mCameraDisabled = cameraDisabledByAdmin || disabledBySimState || !cameraTargetPresent
-                || !currentUserSetup;
-        mSearchDisabled = disabledBySimState || !searchActionAvailable || !searchTargetPresent
-                || !currentUserSetup;
-        updateResources();
-    }
-
-    public void updateResources() {
-        // Update the search icon with drawable from the search .apk
-        if (!mSearchDisabled) {
-            Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
-                    .getAssistIntent(mContext, false, UserHandle.USER_CURRENT);
-            if (intent != null) {
-                // XXX Hack. We need to substitute the icon here but haven't formalized
-                // the public API. The "_google" metadata will be going away, so
-                // DON'T USE IT!
-                ComponentName component = intent.getComponent();
-                boolean replaced = mGlowPadView.replaceTargetDrawablesIfPresent(component,
-                        ASSIST_ICON_METADATA_NAME + "_google",
-                        com.android.internal.R.drawable.ic_action_assist_generic);
-
-                if (!replaced && !mGlowPadView.replaceTargetDrawablesIfPresent(component,
-                            ASSIST_ICON_METADATA_NAME,
-                            com.android.internal.R.drawable.ic_action_assist_generic)) {
-                        Slog.w(TAG, "Couldn't grab icon from package " + component);
-                }
-            }
-        }
-
-        mGlowPadView.setEnableTarget(com.android.internal.R.drawable
-                .ic_lockscreen_camera, !mCameraDisabled);
-        mGlowPadView.setEnableTarget(com.android.internal.R.drawable
-                .ic_action_assist_generic, !mSearchDisabled);
-    }
-
-    void doTransition(View view, float to) {
-        if (mAnim != null) {
-            mAnim.cancel();
-        }
-        mAnim = ObjectAnimator.ofFloat(view, "alpha", to);
-        mAnim.start();
-    }
-
-    public void setKeyguardCallback(KeyguardSecurityCallback callback) {
-        mCallback = callback;
-    }
-
-    public void setLockPatternUtils(LockPatternUtils utils) {
-        mLockPatternUtils = utils;
-    }
-
-    @Override
-    public void reset() {
-        mGlowPadView.reset(false);
-    }
-
-    @Override
-    public boolean needsInput() {
-        return false;
-    }
-
-    @Override
-    public void onPause() {
-        KeyguardUpdateMonitor.getInstance(getContext()).removeCallback(mInfoCallback);
-    }
-
-    @Override
-    public void onResume(int reason) {
-        KeyguardUpdateMonitor.getInstance(getContext()).registerCallback(mInfoCallback);
-    }
-
-    @Override
-    public KeyguardSecurityCallback getCallback() {
-        return mCallback;
-    }
-
-    @Override
-    public void showBouncer(int duration) {
-        mIsBouncing = true;
-        KeyguardSecurityViewHelper.
-                showBouncer(mSecurityMessageDisplay, mFadeView, mBouncerFrame, duration);
-    }
-
-    @Override
-    public void hideBouncer(int duration) {
-        mIsBouncing = false;
-        KeyguardSecurityViewHelper.
-                hideBouncer(mSecurityMessageDisplay, mFadeView, mBouncerFrame, duration);
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
new file mode 100644
index 0000000..874076a
--- /dev/null
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
@@ -0,0 +1,306 @@
+package com.android.internal.policy.impl.keyguard;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.ActivityInfo;
+import android.graphics.PixelFormat;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Log;
+import android.util.Slog;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.view.WindowManagerPolicy.OnKeyguardExitResult;
+
+import com.android.internal.policy.IKeyguardExitCallback;
+import com.android.internal.policy.IKeyguardShowCallback;
+import com.android.internal.policy.IKeyguardService;
+import com.android.internal.widget.LockPatternUtils;
+
+/**
+ * A local class that keeps a cache of keyguard state that can be restored in the event
+ * keyguard crashes. It currently also allows runtime-selectable
+ * local or remote instances of keyguard.
+ */
+public class KeyguardServiceDelegate {
+    private static final String KEYGUARD_PACKAGE = "com.android.keyguard";
+    private static final String KEYGUARD_CLASS = "com.android.keyguard.KeyguardService";
+    private static final String TAG = "KeyguardServiceDelegate";
+    private static final boolean DEBUG = true;
+    protected KeyguardServiceWrapper mKeyguardService;
+    private View mScrim; // shown if keyguard crashes
+    private KeyguardState mKeyguardState = new KeyguardState();
+
+    /* package */ static final class KeyguardState {
+        boolean showing;
+        boolean showingAndNotHidden;
+        boolean inputRestricted;
+        boolean hidden;
+        boolean secure;
+        boolean dreaming;
+        boolean systemIsReady;
+        public boolean enabled;
+        public boolean dismissable;
+        public int offReason;
+        public int currentUser;
+        public boolean screenIsOn;
+    };
+
+    public interface ShowListener {
+        public void onShown(IBinder windowToken);
+    }
+
+    // A delegate class to map a particular invocation with a ShowListener object.
+    private final class KeyguardShowDelegate extends IKeyguardShowCallback.Stub {
+        private ShowListener mShowListener;
+
+        KeyguardShowDelegate(ShowListener showListener) {
+            mShowListener = showListener;
+        }
+
+        @Override
+        public void onShown(IBinder windowToken) throws RemoteException {
+            if (DEBUG) Log.v(TAG, "**** SHOWN CALLED ****");
+            if (mShowListener != null) {
+                mShowListener.onShown(windowToken);
+            }
+            hideScrim();
+        }
+    };
+
+    // A delegate class to map a particular invocation with an OnKeyguardExitResult object.
+    private final class KeyguardExitDelegate extends IKeyguardExitCallback.Stub {
+        private OnKeyguardExitResult mOnKeyguardExitResult;
+
+        KeyguardExitDelegate(OnKeyguardExitResult onKeyguardExitResult) {
+            mOnKeyguardExitResult = onKeyguardExitResult;
+        }
+
+        @Override
+        public void onKeyguardExitResult(boolean success) throws RemoteException {
+            if (DEBUG) Log.v(TAG, "**** onKeyguardExitResult(" + success +") CALLED ****");
+            if (mOnKeyguardExitResult != null) {
+                mOnKeyguardExitResult.onKeyguardExitResult(success);
+            }
+        }
+    };
+
+    public KeyguardServiceDelegate(Context context, LockPatternUtils lockPatternUtils) {
+        Intent intent = new Intent();
+        intent.setClassName(KEYGUARD_PACKAGE, KEYGUARD_CLASS);
+        mScrim = createScrim(context);
+        if (!context.bindServiceAsUser(intent, mKeyguardConnection,
+                Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
+            if (DEBUG) Log.v(TAG, "*** Keyguard: can't bind to " + KEYGUARD_CLASS);
+        } else {
+            if (DEBUG) Log.v(TAG, "*** Keyguard started");
+        }
+    }
+
+    private final ServiceConnection mKeyguardConnection = new ServiceConnection() {
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            if (DEBUG) Log.v(TAG, "*** Keyguard connected (yay!)");
+            mKeyguardService = new KeyguardServiceWrapper(
+                    IKeyguardService.Stub.asInterface(service));
+            if (mKeyguardState.systemIsReady) {
+                // If the system is ready, it means keyguard crashed and restarted.
+                mKeyguardService.onSystemReady();
+                // This is used to hide the scrim once keyguard displays.
+                mKeyguardService.onScreenTurnedOn(new KeyguardShowDelegate(null));
+            }
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            if (DEBUG) Log.v(TAG, "*** Keyguard disconnected (boo!)");
+            mKeyguardService = null;
+        }
+
+    };
+
+    public boolean isShowing() {
+        if (mKeyguardService != null) {
+            mKeyguardState.showing = mKeyguardService.isShowing();
+        }
+        return mKeyguardState.showing;
+    }
+
+    public boolean isShowingAndNotHidden() {
+        if (mKeyguardService != null) {
+            mKeyguardState.showingAndNotHidden = mKeyguardService.isShowingAndNotHidden();
+        }
+        return mKeyguardState.showingAndNotHidden;
+    }
+
+    public boolean isInputRestricted() {
+        if (mKeyguardService != null) {
+            mKeyguardState.inputRestricted = mKeyguardService.isInputRestricted();
+        }
+        return mKeyguardState.inputRestricted;
+    }
+
+    public void verifyUnlock(final OnKeyguardExitResult onKeyguardExitResult) {
+        if (mKeyguardService != null) {
+            mKeyguardService.verifyUnlock(new KeyguardExitDelegate(onKeyguardExitResult));
+        }
+    }
+
+    public void keyguardDone(boolean authenticated, boolean wakeup) {
+        if (mKeyguardService != null) {
+            mKeyguardService.keyguardDone(authenticated, wakeup);
+        }
+    }
+
+    public void setHidden(boolean isHidden) {
+        if (mKeyguardService != null) {
+            mKeyguardService.setHidden(isHidden);
+        }
+        mKeyguardState.hidden = isHidden;
+    }
+
+    public void dismiss() {
+        if (mKeyguardService != null) {
+            mKeyguardService.dismiss();
+        }
+    }
+
+    public boolean isSecure() {
+        if (mKeyguardService != null) {
+            mKeyguardState.secure = mKeyguardService.isSecure();
+        }
+        return mKeyguardState.secure;
+    }
+
+    public void onDreamingStarted() {
+        if (mKeyguardService != null) {
+            mKeyguardService.onDreamingStarted();
+        }
+        mKeyguardState.dreaming = true;
+    }
+
+    public void onDreamingStopped() {
+        if (mKeyguardService != null) {
+            mKeyguardService.onDreamingStopped();
+        }
+        mKeyguardState.dreaming = false;
+    }
+
+    public void onScreenTurnedOn(final ShowListener showListener) {
+        if (mKeyguardService != null) {
+            if (DEBUG) Log.v(TAG, "onScreenTurnedOn(showListener = " + showListener + ")");
+            mKeyguardService.onScreenTurnedOn(new KeyguardShowDelegate(showListener));
+        } else {
+            // try again when we establish a connection
+            Slog.w(TAG, "onScreenTurnedOn(): no keyguard service!");
+            // This shouldn't happen, but if it does, invoke the listener immediately
+            // to avoid a dark screen...
+            showListener.onShown(null);
+        }
+        mKeyguardState.screenIsOn = true;
+    }
+
+    public void onScreenTurnedOff(int why) {
+        if (mKeyguardService != null) {
+            mKeyguardService.onScreenTurnedOff(why);
+        }
+        mKeyguardState.offReason = why;
+        mKeyguardState.screenIsOn = false;
+    }
+
+    public void setKeyguardEnabled(boolean enabled) {
+        if (mKeyguardService != null) {
+            mKeyguardService.setKeyguardEnabled(enabled);
+        }
+        mKeyguardState.enabled = enabled;
+    }
+
+    public boolean isDismissable() {
+        if (mKeyguardService != null) {
+            mKeyguardState.dismissable = mKeyguardService.isDismissable();
+        }
+        return mKeyguardState.dismissable;
+    }
+
+    public void onSystemReady() {
+        if (mKeyguardService != null) {
+            mKeyguardService.onSystemReady();
+        } else {
+            if (DEBUG) Log.v(TAG, "onSystemReady() called before keyguard service was ready");
+            mKeyguardState.systemIsReady = true;
+        }
+    }
+
+    public void doKeyguardTimeout(Bundle options) {
+        if (mKeyguardService != null) {
+            mKeyguardService.doKeyguardTimeout(options);
+        }
+    }
+
+    public void showAssistant() {
+        if (mKeyguardService != null) {
+            mKeyguardService.showAssistant();
+        }
+    }
+
+    public void setCurrentUser(int newUserId) {
+        if (mKeyguardService != null) {
+            mKeyguardService.setCurrentUser(newUserId);
+        }
+        mKeyguardState.currentUser = newUserId;
+    }
+
+    private static final View createScrim(Context context) {
+        View view = new View(context);
+
+        int flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
+                | WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN
+                | WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER
+                ;
+
+        final int stretch = ViewGroup.LayoutParams.MATCH_PARENT;
+        final int type = WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM;
+        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+                stretch, stretch, type, flags, PixelFormat.TRANSLUCENT);
+        lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
+        lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
+        lp.setTitle("KeyguardScrim");
+        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+        wm.addView(view, lp);
+        view.setVisibility(View.GONE);
+        // Disable pretty much everything in statusbar until keyguard comes back and we know
+        // the state of the world.
+        view.setSystemUiVisibility(View.STATUS_BAR_DISABLE_HOME
+                | View.STATUS_BAR_DISABLE_BACK
+                | View.STATUS_BAR_DISABLE_RECENT
+                | View.STATUS_BAR_DISABLE_EXPAND
+                | View.STATUS_BAR_DISABLE_SEARCH);
+        return view;
+    }
+
+    public void showScrim() {
+        mScrim.post(new Runnable() {
+            @Override
+            public void run() {
+                mScrim.setVisibility(View.VISIBLE);
+            }
+        });
+    }
+
+    public void hideScrim() {
+        mScrim.post(new Runnable() {
+            @Override
+            public void run() {
+                mScrim.setVisibility(View.GONE);
+            }
+        });
+    }
+
+}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java
new file mode 100644
index 0000000..6b9c7df
--- /dev/null
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.policy.impl.keyguard;
+
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Slog;
+
+import com.android.internal.policy.IKeyguardShowCallback;
+import com.android.internal.policy.IKeyguardExitCallback;
+import com.android.internal.policy.IKeyguardService;
+
+/**
+ * A wrapper class for KeyguardService.  It implements IKeyguardService to ensure the interface
+ * remains consistent.
+ *
+ */
+public class KeyguardServiceWrapper implements IKeyguardService {
+    private IKeyguardService mService;
+    private String TAG = "KeyguardServiceWrapper";
+
+    public KeyguardServiceWrapper(IKeyguardService service) {
+        mService = service;
+    }
+
+    public boolean isShowing() {
+        try {
+            return mService.isShowing();
+        } catch (RemoteException e) {
+            Slog.w(TAG , "Remote Exception", e);
+        }
+        return false;
+    }
+
+    public boolean isSecure() {
+        try {
+            return mService.isSecure();
+        } catch (RemoteException e) {
+            Slog.w(TAG , "Remote Exception", e);
+        }
+        return false; // TODO cache state
+    }
+
+    public boolean isShowingAndNotHidden() {
+        try {
+            return mService.isShowingAndNotHidden();
+        } catch (RemoteException e) {
+            Slog.w(TAG , "Remote Exception", e);
+        }
+        return false; // TODO cache state
+    }
+
+    public boolean isInputRestricted() {
+        try {
+            return mService.isInputRestricted();
+        } catch (RemoteException e) {
+            Slog.w(TAG , "Remote Exception", e);
+        }
+        return false; // TODO cache state
+    }
+
+    public boolean isDismissable() {
+        try {
+            return mService.isDismissable();
+        } catch (RemoteException e) {
+            Slog.w(TAG , "Remote Exception", e);
+        }
+        return true; // TODO cache state
+    }
+
+    public void verifyUnlock(IKeyguardExitCallback callback) {
+        try {
+            mService.verifyUnlock(callback);
+        } catch (RemoteException e) {
+            Slog.w(TAG , "Remote Exception", e);
+        }
+    }
+
+    public void keyguardDone(boolean authenticated, boolean wakeup) {
+        try {
+            mService.keyguardDone(authenticated, wakeup);
+        } catch (RemoteException e) {
+            Slog.w(TAG , "Remote Exception", e);
+        }
+    }
+
+    public void setHidden(boolean isHidden) {
+        try {
+            mService.setHidden(isHidden);
+        } catch (RemoteException e) {
+            Slog.w(TAG , "Remote Exception", e);
+        }
+    }
+
+    public void dismiss() {
+        try {
+            mService.dismiss();
+        } catch (RemoteException e) {
+            Slog.w(TAG , "Remote Exception", e);
+        }
+    }
+
+    public void onDreamingStarted() {
+        try {
+            mService.onDreamingStarted();
+        } catch (RemoteException e) {
+            Slog.w(TAG , "Remote Exception", e);
+        }
+    }
+
+    public void onDreamingStopped() {
+        try {
+            mService.onDreamingStopped();
+        } catch (RemoteException e) {
+            Slog.w(TAG , "Remote Exception", e);
+        }
+    }
+
+    public void onScreenTurnedOff(int reason) {
+        try {
+            mService.onScreenTurnedOff(reason);
+        } catch (RemoteException e) {
+            Slog.w(TAG , "Remote Exception", e);
+        }
+    }
+
+    public void onScreenTurnedOn(IKeyguardShowCallback result) {
+        try {
+            mService.onScreenTurnedOn(result);
+        } catch (RemoteException e) {
+            Slog.w(TAG , "Remote Exception", e);
+        }
+    }
+
+    public void setKeyguardEnabled(boolean enabled) {
+        try {
+            mService.setKeyguardEnabled(enabled);
+        } catch (RemoteException e) {
+            Slog.w(TAG , "Remote Exception", e);
+        }
+    }
+
+    public void onSystemReady() {
+        try {
+            mService.onSystemReady();
+        } catch (RemoteException e) {
+            Slog.w(TAG , "Remote Exception", e);
+        }
+    }
+
+    public void doKeyguardTimeout(Bundle options) {
+        try {
+            mService.doKeyguardTimeout(options);
+        } catch (RemoteException e) {
+            Slog.w(TAG , "Remote Exception", e);
+        }
+    }
+
+    public void setCurrentUser(int userId) {
+        try {
+            mService.setCurrentUser(userId);
+        } catch (RemoteException e) {
+            Slog.w(TAG , "Remote Exception", e);
+        }
+    }
+
+    public void showAssistant() {
+        try {
+            mService.showAssistant();
+        } catch (RemoteException e) {
+            Slog.w(TAG , "Remote Exception", e);
+        }
+    }
+
+    @Override
+    public IBinder asBinder() {
+        return mService.asBinder();
+    }
+
+}
\ No newline at end of file
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPinView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPinView.java
deleted file mode 100644
index ab364ee..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPinView.java
+++ /dev/null
@@ -1,213 +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.internal.policy.impl.keyguard;
-
-import com.android.internal.telephony.ITelephony;
-
-import android.content.Context;
-import android.app.Activity;
-import android.app.Dialog;
-import android.app.ProgressDialog;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.text.Editable;
-import android.text.InputType;
-import android.text.TextWatcher;
-import android.text.method.DigitsKeyListener;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.WindowManager;
-import android.widget.TextView.OnEditorActionListener;
-
-import com.android.internal.R;
-
-/**
- * Displays a PIN pad for unlocking.
- */
-public class KeyguardSimPinView extends KeyguardAbsKeyInputView
-        implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
-
-    private ProgressDialog mSimUnlockProgressDialog = null;
-    private volatile boolean mSimCheckInProgress;
-
-    public KeyguardSimPinView(Context context) {
-        this(context, null);
-    }
-
-    public KeyguardSimPinView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public void resetState() {
-        mSecurityMessageDisplay.setMessage(R.string.kg_sim_pin_instructions, true);
-        mPasswordEntry.setEnabled(true);
-    }
-
-    @Override
-    protected int getPasswordTextViewId() {
-        return R.id.pinEntry;
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-
-        final View ok = findViewById(R.id.key_enter);
-        if (ok != null) {
-            ok.setOnClickListener(new View.OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    doHapticKeyClick();
-                    verifyPasswordAndUnlock();
-                }
-            });
-        }
-
-        // The delete button is of the PIN keyboard itself in some (e.g. tablet) layouts,
-        // not a separate view
-        View pinDelete = findViewById(R.id.delete_button);
-        if (pinDelete != null) {
-            pinDelete.setVisibility(View.VISIBLE);
-            pinDelete.setOnClickListener(new OnClickListener() {
-                public void onClick(View v) {
-                    CharSequence str = mPasswordEntry.getText();
-                    if (str.length() > 0) {
-                        mPasswordEntry.setText(str.subSequence(0, str.length()-1));
-                    }
-                    doHapticKeyClick();
-                }
-            });
-            pinDelete.setOnLongClickListener(new View.OnLongClickListener() {
-                public boolean onLongClick(View v) {
-                    mPasswordEntry.setText("");
-                    doHapticKeyClick();
-                    return true;
-                }
-            });
-        }
-
-        mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance());
-        mPasswordEntry.setInputType(InputType.TYPE_CLASS_NUMBER
-                | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
-
-        mPasswordEntry.requestFocus();
-    }
-
-    @Override
-    public void showUsabilityHint() {
-    }
-
-    @Override
-    public void onPause() {
-        // dismiss the dialog.
-        if (mSimUnlockProgressDialog != null) {
-            mSimUnlockProgressDialog.dismiss();
-            mSimUnlockProgressDialog = null;
-        }
-    }
-
-    /**
-     * Since the IPC can block, we want to run the request in a separate thread
-     * with a callback.
-     */
-    private abstract class CheckSimPin extends Thread {
-        private final String mPin;
-
-        protected CheckSimPin(String pin) {
-            mPin = pin;
-        }
-
-        abstract void onSimCheckResponse(boolean success);
-
-        @Override
-        public void run() {
-            try {
-                final boolean result = ITelephony.Stub.asInterface(ServiceManager
-                        .checkService("phone")).supplyPin(mPin);
-                post(new Runnable() {
-                    public void run() {
-                        onSimCheckResponse(result);
-                    }
-                });
-            } catch (RemoteException e) {
-                post(new Runnable() {
-                    public void run() {
-                        onSimCheckResponse(false);
-                    }
-                });
-            }
-        }
-    }
-
-    private Dialog getSimUnlockProgressDialog() {
-        if (mSimUnlockProgressDialog == null) {
-            mSimUnlockProgressDialog = new ProgressDialog(mContext);
-            mSimUnlockProgressDialog.setMessage(
-                    mContext.getString(R.string.kg_sim_unlock_progress_dialog_message));
-            mSimUnlockProgressDialog.setIndeterminate(true);
-            mSimUnlockProgressDialog.setCancelable(false);
-            if (!(mContext instanceof Activity)) {
-                mSimUnlockProgressDialog.getWindow().setType(
-                        WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
-            }
-        }
-        return mSimUnlockProgressDialog;
-    }
-
-    @Override
-    protected void verifyPasswordAndUnlock() {
-        String entry = mPasswordEntry.getText().toString();
-        
-        if (entry.length() < 4) {
-            // otherwise, display a message to the user, and don't submit.
-            mSecurityMessageDisplay.setMessage(R.string.kg_invalid_sim_pin_hint, true);
-            mPasswordEntry.setText("");
-            mCallback.userActivity(0);
-            return;
-        }
-
-        getSimUnlockProgressDialog().show();
-
-        if (!mSimCheckInProgress) {
-            mSimCheckInProgress = true; // there should be only one
-            new CheckSimPin(mPasswordEntry.getText().toString()) {
-                void onSimCheckResponse(final boolean success) {
-                    post(new Runnable() {
-                        public void run() {
-                            if (mSimUnlockProgressDialog != null) {
-                                mSimUnlockProgressDialog.hide();
-                            }
-                            if (success) {
-                                // before closing the keyguard, report back that the sim is unlocked
-                                // so it knows right away.
-                                KeyguardUpdateMonitor.getInstance(getContext()).reportSimUnlocked();
-                                mCallback.dismiss(true);
-                            } else {
-                                mSecurityMessageDisplay.setMessage
-                                    (R.string.kg_password_wrong_pin_code, true);
-                                mPasswordEntry.setText("");
-                            }
-                            mCallback.userActivity(0);
-                            mSimCheckInProgress = false;
-                        }
-                    });
-                }
-            }.start();
-        }
-    }
-}
-
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPukView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPukView.java
deleted file mode 100644
index e5b4b73..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPukView.java
+++ /dev/null
@@ -1,282 +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.internal.policy.impl.keyguard;
-
-import android.app.Activity;
-import android.app.Dialog;
-import android.app.ProgressDialog;
-import android.content.Context;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.text.Editable;
-import android.text.InputType;
-import android.text.TextWatcher;
-import android.text.method.DigitsKeyListener;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.WindowManager;
-import android.widget.TextView.OnEditorActionListener;
-
-import com.android.internal.telephony.ITelephony;
-
-import com.android.internal.R;
-
-/**
- * Displays a PIN pad for entering a PUK (Pin Unlock Kode) provided by a carrier.
- */
-public class KeyguardSimPukView extends KeyguardAbsKeyInputView
-        implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
-
-    private ProgressDialog mSimUnlockProgressDialog = null;
-    private volatile boolean mCheckInProgress;
-    private String mPukText;
-    private String mPinText;
-    private StateMachine mStateMachine = new StateMachine();
-
-    private class StateMachine {
-        final int ENTER_PUK = 0;
-        final int ENTER_PIN = 1;
-        final int CONFIRM_PIN = 2;
-        final int DONE = 3;
-        private int state = ENTER_PUK;
-
-        public void next() {
-            int msg = 0;
-            if (state == ENTER_PUK) {
-                if (checkPuk()) {
-                    state = ENTER_PIN;
-                    msg = R.string.kg_puk_enter_pin_hint;
-                } else {
-                    msg = R.string.kg_invalid_sim_puk_hint;
-                }
-            } else if (state == ENTER_PIN) {
-                if (checkPin()) {
-                    state = CONFIRM_PIN;
-                    msg = R.string.kg_enter_confirm_pin_hint;
-                } else {
-                    msg = R.string.kg_invalid_sim_pin_hint;
-                }
-            } else if (state == CONFIRM_PIN) {
-                if (confirmPin()) {
-                    state = DONE;
-                    msg =
-                        com.android.internal.R.string.lockscreen_sim_unlock_progress_dialog_message;
-                    updateSim();
-                } else {
-                    state = ENTER_PIN; // try again?
-                    msg = R.string.kg_invalid_confirm_pin_hint;
-                }
-            }
-            mPasswordEntry.setText(null);
-            if (msg != 0) {
-                mSecurityMessageDisplay.setMessage(msg, true);
-            }
-        }
-
-        void reset() {
-            mPinText="";
-            mPukText="";
-            state = ENTER_PUK;
-            mSecurityMessageDisplay.setMessage(R.string.kg_puk_enter_puk_hint, true);
-            mPasswordEntry.requestFocus();
-        }
-    }
-
-    public KeyguardSimPukView(Context context) {
-        this(context, null);
-    }
-
-    public KeyguardSimPukView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public void resetState() {
-        mStateMachine.reset();
-        mPasswordEntry.setEnabled(true);
-    }
-
-    @Override
-    protected int getPasswordTextViewId() {
-        return R.id.pinEntry;
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-
-        final View ok = findViewById(R.id.key_enter);
-        if (ok != null) {
-            ok.setOnClickListener(new View.OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    doHapticKeyClick();
-                    verifyPasswordAndUnlock();
-                }
-            });
-        }
-
-        // The delete button is of the PIN keyboard itself in some (e.g. tablet) layouts,
-        // not a separate view
-        View pinDelete = findViewById(R.id.delete_button);
-        if (pinDelete != null) {
-            pinDelete.setVisibility(View.VISIBLE);
-            pinDelete.setOnClickListener(new OnClickListener() {
-                public void onClick(View v) {
-                    CharSequence str = mPasswordEntry.getText();
-                    if (str.length() > 0) {
-                        mPasswordEntry.setText(str.subSequence(0, str.length()-1));
-                    }
-                    doHapticKeyClick();
-                }
-            });
-            pinDelete.setOnLongClickListener(new View.OnLongClickListener() {
-                public boolean onLongClick(View v) {
-                    mPasswordEntry.setText("");
-                    doHapticKeyClick();
-                    return true;
-                }
-            });
-        }
-
-        mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance());
-        mPasswordEntry.setInputType(InputType.TYPE_CLASS_NUMBER
-                | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
-
-        mPasswordEntry.requestFocus();
-
-        mSecurityMessageDisplay.setTimeout(0); // don't show ownerinfo/charging status by default
-    }
-
-    @Override
-    public void showUsabilityHint() {
-    }
-
-    @Override
-    public void onPause() {
-        // dismiss the dialog.
-        if (mSimUnlockProgressDialog != null) {
-            mSimUnlockProgressDialog.dismiss();
-            mSimUnlockProgressDialog = null;
-        }
-    }
-
-    /**
-     * Since the IPC can block, we want to run the request in a separate thread
-     * with a callback.
-     */
-    private abstract class CheckSimPuk extends Thread {
-
-        private final String mPin, mPuk;
-
-        protected CheckSimPuk(String puk, String pin) {
-            mPuk = puk;
-            mPin = pin;
-        }
-
-        abstract void onSimLockChangedResponse(boolean success);
-
-        @Override
-        public void run() {
-            try {
-                final boolean result = ITelephony.Stub.asInterface(ServiceManager
-                        .checkService("phone")).supplyPuk(mPuk, mPin);
-
-                post(new Runnable() {
-                    public void run() {
-                        onSimLockChangedResponse(result);
-                    }
-                });
-            } catch (RemoteException e) {
-                post(new Runnable() {
-                    public void run() {
-                        onSimLockChangedResponse(false);
-                    }
-                });
-            }
-        }
-    }
-
-    private Dialog getSimUnlockProgressDialog() {
-        if (mSimUnlockProgressDialog == null) {
-            mSimUnlockProgressDialog = new ProgressDialog(mContext);
-            mSimUnlockProgressDialog.setMessage(
-                    mContext.getString(R.string.kg_sim_unlock_progress_dialog_message));
-            mSimUnlockProgressDialog.setIndeterminate(true);
-            mSimUnlockProgressDialog.setCancelable(false);
-            if (!(mContext instanceof Activity)) {
-                mSimUnlockProgressDialog.getWindow().setType(
-                        WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
-            }
-        }
-        return mSimUnlockProgressDialog;
-    }
-
-    private boolean checkPuk() {
-        // make sure the puk is at least 8 digits long.
-        if (mPasswordEntry.getText().length() >= 8) {
-            mPukText = mPasswordEntry.getText().toString();
-            return true;
-        }
-        return false;
-    }
-
-    private boolean checkPin() {
-        // make sure the PIN is between 4 and 8 digits
-        int length = mPasswordEntry.getText().length();
-        if (length >= 4 && length <= 8) {
-            mPinText = mPasswordEntry.getText().toString();
-            return true;
-        }
-        return false;
-    }
-
-    public boolean confirmPin() {
-        return mPinText.equals(mPasswordEntry.getText().toString());
-    }
-
-    private void updateSim() {
-        getSimUnlockProgressDialog().show();
-
-        if (!mCheckInProgress) {
-            mCheckInProgress = true;
-            new CheckSimPuk(mPukText, mPinText) {
-                void onSimLockChangedResponse(final boolean success) {
-                    post(new Runnable() {
-                        public void run() {
-                            if (mSimUnlockProgressDialog != null) {
-                                mSimUnlockProgressDialog.hide();
-                            }
-                            if (success) {
-                                mCallback.dismiss(true);
-                            } else {
-                                mStateMachine.reset();
-                                mSecurityMessageDisplay.setMessage(R.string.kg_invalid_puk, true);
-                            }
-                            mCheckInProgress = false;
-                        }
-                    });
-                }
-            }.start();
-        }
-    }
-
-    @Override
-    protected void verifyPasswordAndUnlock() {
-        mStateMachine.next();
-    }
-}
-
-
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusView.java
deleted file mode 100644
index d938cec..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusView.java
+++ /dev/null
@@ -1,156 +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.internal.policy.impl.keyguard;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Typeface;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.util.Slog;
-import android.view.View;
-import android.widget.GridLayout;
-import android.widget.TextView;
-
-import com.android.internal.R;
-import com.android.internal.widget.LockPatternUtils;
-
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Locale;
-
-import libcore.icu.ICU;
-
-public class KeyguardStatusView extends GridLayout {
-    private static final boolean DEBUG = KeyguardViewMediator.DEBUG;
-    private static final String TAG = "KeyguardStatusView";
-
-    public static final int LOCK_ICON = 0; // R.drawable.ic_lock_idle_lock;
-    public static final int ALARM_ICON = com.android.internal.R.drawable.ic_lock_idle_alarm;
-    public static final int CHARGING_ICON = 0; //R.drawable.ic_lock_idle_charging;
-    public static final int BATTERY_LOW_ICON = 0; //R.drawable.ic_lock_idle_low_battery;
-
-    private SimpleDateFormat mDateFormat;
-    private LockPatternUtils mLockPatternUtils;
-
-    private TextView mDateView;
-    private TextView mAlarmStatusView;
-    private ClockView mClockView;
-
-    private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
-
-        @Override
-        public void onTimeChanged() {
-            refresh();
-        }
-
-        @Override
-        void onKeyguardVisibilityChanged(boolean showing) {
-            if (showing) {
-                if (DEBUG) Slog.v(TAG, "refresh statusview showing:" + showing);
-                refresh();
-            }
-        };
-    };
-
-    public KeyguardStatusView(Context context) {
-        this(context, null, 0);
-    }
-
-    public KeyguardStatusView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public KeyguardStatusView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-        Resources res = getContext().getResources();
-        final Locale locale = Locale.getDefault();
-        final String datePattern =
-                res.getString(com.android.internal.R.string.system_ui_date_pattern);
-        final String bestFormat = ICU.getBestDateTimePattern(datePattern, locale.toString());
-        mDateFormat = new SimpleDateFormat(bestFormat, locale);
-        mDateView = (TextView) findViewById(R.id.date);
-        mAlarmStatusView = (TextView) findViewById(R.id.alarm_status);
-        mClockView = (ClockView) findViewById(R.id.clock_view);
-        mLockPatternUtils = new LockPatternUtils(getContext());
-
-        // Use custom font in mDateView
-        mDateView.setTypeface(Typeface.SANS_SERIF, Typeface.BOLD);
-
-        // Required to get Marquee to work.
-        final View marqueeViews[] = { mDateView, mAlarmStatusView };
-        for (int i = 0; i < marqueeViews.length; i++) {
-            View v = marqueeViews[i];
-            if (v == null) {
-                throw new RuntimeException("Can't find widget at index " + i);
-            }
-            v.setSelected(true);
-        }
-        refresh();
-    }
-
-    protected void refresh() {
-        mClockView.updateTime();
-        refreshDate();
-        refreshAlarmStatus(); // might as well
-    }
-
-    void refreshAlarmStatus() {
-        // Update Alarm status
-        String nextAlarm = mLockPatternUtils.getNextAlarm();
-        if (!TextUtils.isEmpty(nextAlarm)) {
-            maybeSetUpperCaseText(mAlarmStatusView, nextAlarm);
-            mAlarmStatusView.setCompoundDrawablesWithIntrinsicBounds(ALARM_ICON, 0, 0, 0);
-            mAlarmStatusView.setVisibility(View.VISIBLE);
-        } else {
-            mAlarmStatusView.setVisibility(View.GONE);
-        }
-    }
-
-    void refreshDate() {
-        maybeSetUpperCaseText(mDateView, mDateFormat.format(new Date()));
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mInfoCallback);
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mInfoCallback);
-    }
-
-    public int getAppWidgetId() {
-        return LockPatternUtils.ID_DEFAULT_STATUS_WIDGET;
-    }
-
-    private void maybeSetUpperCaseText(TextView textView, CharSequence text) {
-        if (KeyguardViewManager.USE_UPPER_CASE) {
-            textView.setText(text != null ? text.toString().toUpperCase() : null);
-        } else {
-            textView.setText(text);
-        }
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardTransportControlView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardTransportControlView.java
deleted file mode 100644
index 5e3b7da..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardTransportControlView.java
+++ /dev/null
@@ -1,470 +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.policy.impl.keyguard;
-
-import android.app.PendingIntent;
-import android.app.PendingIntent.CanceledException;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.media.AudioManager;
-import android.media.IRemoteControlDisplay;
-import android.media.MediaMetadataRetriever;
-import android.media.RemoteControlClient;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.text.Spannable;
-import android.text.TextUtils;
-import android.text.style.ForegroundColorSpan;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import com.android.internal.R;
-
-import java.lang.ref.WeakReference;
-/**
- * This is the widget responsible for showing music controls in keyguard.
- */
-public class KeyguardTransportControlView extends FrameLayout implements OnClickListener {
-
-    private static final int MSG_UPDATE_STATE = 100;
-    private static final int MSG_SET_METADATA = 101;
-    private static final int MSG_SET_TRANSPORT_CONTROLS = 102;
-    private static final int MSG_SET_ARTWORK = 103;
-    private static final int MSG_SET_GENERATION_ID = 104;
-    private static final int DISPLAY_TIMEOUT_MS = 5000; // 5s
-    protected static final boolean DEBUG = false;
-    protected static final String TAG = "TransportControlView";
-
-    private ImageView mAlbumArt;
-    private TextView mTrackTitle;
-    private ImageView mBtnPrev;
-    private ImageView mBtnPlay;
-    private ImageView mBtnNext;
-    private int mClientGeneration;
-    private Metadata mMetadata = new Metadata();
-    private boolean mAttached;
-    private PendingIntent mClientIntent;
-    private int mTransportControlFlags;
-    private int mCurrentPlayState;
-    private AudioManager mAudioManager;
-    private IRemoteControlDisplayWeak mIRCD;
-
-    /**
-     * The metadata which should be populated into the view once we've been attached
-     */
-    private Bundle mPopulateMetadataWhenAttached = null;
-
-    // This handler is required to ensure messages from IRCD are handled in sequence and on
-    // the UI thread.
-    private Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-            case MSG_UPDATE_STATE:
-                if (mClientGeneration == msg.arg1) updatePlayPauseState(msg.arg2);
-                break;
-
-            case MSG_SET_METADATA:
-                if (mClientGeneration == msg.arg1) updateMetadata((Bundle) msg.obj);
-                break;
-
-            case MSG_SET_TRANSPORT_CONTROLS:
-                if (mClientGeneration == msg.arg1) updateTransportControls(msg.arg2);
-                break;
-
-            case MSG_SET_ARTWORK:
-                if (mClientGeneration == msg.arg1) {
-                    if (mMetadata.bitmap != null) {
-                        mMetadata.bitmap.recycle();
-                    }
-                    mMetadata.bitmap = (Bitmap) msg.obj;
-                    mAlbumArt.setImageBitmap(mMetadata.bitmap);
-                }
-                break;
-
-            case MSG_SET_GENERATION_ID:
-                if (DEBUG) Log.v(TAG, "New genId = " + msg.arg1 + ", clearing = " + msg.arg2);
-                mClientGeneration = msg.arg1;
-                mClientIntent = (PendingIntent) msg.obj;
-                break;
-
-            }
-        }
-    };
-
-    /**
-     * This class is required to have weak linkage to the current TransportControlView
-     * because the remote process can hold a strong reference to this binder object and
-     * we can't predict when it will be GC'd in the remote process. Without this code, it
-     * would allow a heavyweight object to be held on this side of the binder when there's
-     * no requirement to run a GC on the other side.
-     */
-    private static class IRemoteControlDisplayWeak extends IRemoteControlDisplay.Stub {
-        private WeakReference<Handler> mLocalHandler;
-
-        IRemoteControlDisplayWeak(Handler handler) {
-            mLocalHandler = new WeakReference<Handler>(handler);
-        }
-
-        public void setPlaybackState(int generationId, int state, long stateChangeTimeMs,
-                long currentPosMs, float speed) {
-            Handler handler = mLocalHandler.get();
-            if (handler != null) {
-                handler.obtainMessage(MSG_UPDATE_STATE, generationId, state).sendToTarget();
-            }
-        }
-
-        public void setMetadata(int generationId, Bundle metadata) {
-            Handler handler = mLocalHandler.get();
-            if (handler != null) {
-                handler.obtainMessage(MSG_SET_METADATA, generationId, 0, metadata).sendToTarget();
-            }
-        }
-
-        public void setTransportControlInfo(int generationId, int flags, int posCapabilities) {
-            Handler handler = mLocalHandler.get();
-            if (handler != null) {
-                handler.obtainMessage(MSG_SET_TRANSPORT_CONTROLS, generationId, flags)
-                        .sendToTarget();
-            }
-        }
-
-        public void setArtwork(int generationId, Bitmap bitmap) {
-            Handler handler = mLocalHandler.get();
-            if (handler != null) {
-                handler.obtainMessage(MSG_SET_ARTWORK, generationId, 0, bitmap).sendToTarget();
-            }
-        }
-
-        public void setAllMetadata(int generationId, Bundle metadata, Bitmap bitmap) {
-            Handler handler = mLocalHandler.get();
-            if (handler != null) {
-                handler.obtainMessage(MSG_SET_METADATA, generationId, 0, metadata).sendToTarget();
-                handler.obtainMessage(MSG_SET_ARTWORK, generationId, 0, bitmap).sendToTarget();
-            }
-        }
-
-        public void setCurrentClientId(int clientGeneration, PendingIntent mediaIntent,
-                boolean clearing) throws RemoteException {
-            Handler handler = mLocalHandler.get();
-            if (handler != null) {
-                handler.obtainMessage(MSG_SET_GENERATION_ID,
-                    clientGeneration, (clearing ? 1 : 0), mediaIntent).sendToTarget();
-            }
-        }
-    };
-
-    public KeyguardTransportControlView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        if (DEBUG) Log.v(TAG, "Create TCV " + this);
-        mAudioManager = new AudioManager(mContext);
-        mCurrentPlayState = RemoteControlClient.PLAYSTATE_NONE; // until we get a callback
-        mIRCD = new IRemoteControlDisplayWeak(mHandler);
-    }
-
-    private void updateTransportControls(int transportControlFlags) {
-        mTransportControlFlags = transportControlFlags;
-    }
-
-    @Override
-    public void onFinishInflate() {
-        super.onFinishInflate();
-        mTrackTitle = (TextView) findViewById(R.id.title);
-        mTrackTitle.setSelected(true); // enable marquee
-        mAlbumArt = (ImageView) findViewById(R.id.albumart);
-        mBtnPrev = (ImageView) findViewById(R.id.btn_prev);
-        mBtnPlay = (ImageView) findViewById(R.id.btn_play);
-        mBtnNext = (ImageView) findViewById(R.id.btn_next);
-        final View buttons[] = { mBtnPrev, mBtnPlay, mBtnNext };
-        for (View view : buttons) {
-            view.setOnClickListener(this);
-        }
-    }
-
-    @Override
-    public void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        if (DEBUG) Log.v(TAG, "onAttachToWindow()");
-        if (mPopulateMetadataWhenAttached != null) {
-            updateMetadata(mPopulateMetadataWhenAttached);
-            mPopulateMetadataWhenAttached = null;
-        }
-        if (!mAttached) {
-            if (DEBUG) Log.v(TAG, "Registering TCV " + this);
-            mAudioManager.registerRemoteControlDisplay(mIRCD);
-        }
-        mAttached = true;
-    }
-
-    @Override
-    protected void onSizeChanged (int w, int h, int oldw, int oldh) {
-        if (mAttached) {
-            int dim = Math.min(512, Math.max(w, h));
-            if (DEBUG) Log.v(TAG, "TCV uses bitmap size=" + dim);
-            mAudioManager.remoteControlDisplayUsesBitmapSize(mIRCD, dim, dim);
-        }
-    }
-
-    @Override
-    public void onDetachedFromWindow() {
-        if (DEBUG) Log.v(TAG, "onDetachFromWindow()");
-        super.onDetachedFromWindow();
-        if (mAttached) {
-            if (DEBUG) Log.v(TAG, "Unregistering TCV " + this);
-            mAudioManager.unregisterRemoteControlDisplay(mIRCD);
-        }
-        mAttached = false;
-    }
-
-    class Metadata {
-        private String artist;
-        private String trackTitle;
-        private String albumTitle;
-        private Bitmap bitmap;
-
-        public String toString() {
-            return "Metadata[artist=" + artist + " trackTitle=" + trackTitle + " albumTitle=" + albumTitle + "]";
-        }
-    }
-
-    private String getMdString(Bundle data, int id) {
-        return data.getString(Integer.toString(id));
-    }
-
-    private void updateMetadata(Bundle data) {
-        if (mAttached) {
-            mMetadata.artist = getMdString(data, MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST);
-            mMetadata.trackTitle = getMdString(data, MediaMetadataRetriever.METADATA_KEY_TITLE);
-            mMetadata.albumTitle = getMdString(data, MediaMetadataRetriever.METADATA_KEY_ALBUM);
-            populateMetadata();
-        } else {
-            mPopulateMetadataWhenAttached = data;
-        }
-    }
-
-    /**
-     * Populates the given metadata into the view
-     */
-    private void populateMetadata() {
-        StringBuilder sb = new StringBuilder();
-        int trackTitleLength = 0;
-        if (!TextUtils.isEmpty(mMetadata.trackTitle)) {
-            sb.append(mMetadata.trackTitle);
-            trackTitleLength = mMetadata.trackTitle.length();
-        }
-        if (!TextUtils.isEmpty(mMetadata.artist)) {
-            if (sb.length() != 0) {
-                sb.append(" - ");
-            }
-            sb.append(mMetadata.artist);
-        }
-        if (!TextUtils.isEmpty(mMetadata.albumTitle)) {
-            if (sb.length() != 0) {
-                sb.append(" - ");
-            }
-            sb.append(mMetadata.albumTitle);
-        }
-        mTrackTitle.setText(sb.toString(), TextView.BufferType.SPANNABLE);
-        Spannable str = (Spannable) mTrackTitle.getText();
-        if (trackTitleLength != 0) {
-            str.setSpan(new ForegroundColorSpan(0xffffffff), 0, trackTitleLength,
-                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
-            trackTitleLength++;
-        }
-        if (sb.length() > trackTitleLength) {
-            str.setSpan(new ForegroundColorSpan(0x7fffffff), trackTitleLength, sb.length(),
-                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
-        }
-
-        mAlbumArt.setImageBitmap(mMetadata.bitmap);
-        final int flags = mTransportControlFlags;
-        setVisibilityBasedOnFlag(mBtnPrev, flags, RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS);
-        setVisibilityBasedOnFlag(mBtnNext, flags, RemoteControlClient.FLAG_KEY_MEDIA_NEXT);
-        setVisibilityBasedOnFlag(mBtnPlay, flags,
-                RemoteControlClient.FLAG_KEY_MEDIA_PLAY
-                | RemoteControlClient.FLAG_KEY_MEDIA_PAUSE
-                | RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE
-                | RemoteControlClient.FLAG_KEY_MEDIA_STOP);
-
-        updatePlayPauseState(mCurrentPlayState);
-    }
-
-    private static void setVisibilityBasedOnFlag(View view, int flags, int flag) {
-        if ((flags & flag) != 0) {
-            view.setVisibility(View.VISIBLE);
-        } else {
-            view.setVisibility(View.GONE);
-        }
-    }
-
-    private void updatePlayPauseState(int state) {
-        if (DEBUG) Log.v(TAG,
-                "updatePlayPauseState(), old=" + mCurrentPlayState + ", state=" + state);
-        if (state == mCurrentPlayState) {
-            return;
-        }
-        final int imageResId;
-        final int imageDescId;
-        switch (state) {
-            case RemoteControlClient.PLAYSTATE_ERROR:
-                imageResId = com.android.internal.R.drawable.stat_sys_warning;
-                // TODO use more specific image description string for warning, but here the "play"
-                //      message is still valid because this button triggers a play command.
-                imageDescId = com.android.internal.R.string.lockscreen_transport_play_description;
-                break;
-
-            case RemoteControlClient.PLAYSTATE_PLAYING:
-                imageResId = com.android.internal.R.drawable.ic_media_pause;
-                imageDescId = com.android.internal.R.string.lockscreen_transport_pause_description;
-                break;
-
-            case RemoteControlClient.PLAYSTATE_BUFFERING:
-                imageResId = com.android.internal.R.drawable.ic_media_stop;
-                imageDescId = com.android.internal.R.string.lockscreen_transport_stop_description;
-                break;
-
-            case RemoteControlClient.PLAYSTATE_PAUSED:
-            default:
-                imageResId = com.android.internal.R.drawable.ic_media_play;
-                imageDescId = com.android.internal.R.string.lockscreen_transport_play_description;
-                break;
-        }
-        mBtnPlay.setImageResource(imageResId);
-        mBtnPlay.setContentDescription(getResources().getString(imageDescId));
-        mCurrentPlayState = state;
-    }
-
-    static class SavedState extends BaseSavedState {
-        boolean clientPresent;
-
-        SavedState(Parcelable superState) {
-            super(superState);
-        }
-
-        private SavedState(Parcel in) {
-            super(in);
-            this.clientPresent = in.readInt() != 0;
-        }
-
-        @Override
-        public void writeToParcel(Parcel out, int flags) {
-            super.writeToParcel(out, flags);
-            out.writeInt(this.clientPresent ? 1 : 0);
-        }
-
-        public static final Parcelable.Creator<SavedState> CREATOR
-                = new Parcelable.Creator<SavedState>() {
-            public SavedState createFromParcel(Parcel in) {
-                return new SavedState(in);
-            }
-
-            public SavedState[] newArray(int size) {
-                return new SavedState[size];
-            }
-        };
-    }
-
-    public void onClick(View v) {
-        int keyCode = -1;
-        if (v == mBtnPrev) {
-            keyCode = KeyEvent.KEYCODE_MEDIA_PREVIOUS;
-        } else if (v == mBtnNext) {
-            keyCode = KeyEvent.KEYCODE_MEDIA_NEXT;
-        } else if (v == mBtnPlay) {
-            keyCode = KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE;
-
-        }
-        if (keyCode != -1) {
-            sendMediaButtonClick(keyCode);
-        }
-    }
-
-    private void sendMediaButtonClick(int keyCode) {
-        if (mClientIntent == null) {
-            // Shouldn't be possible because this view should be hidden in this case.
-            Log.e(TAG, "sendMediaButtonClick(): No client is currently registered");
-            return;
-        }
-        // use the registered PendingIntent that will be processed by the registered
-        //    media button event receiver, which is the component of mClientIntent
-        KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
-        Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
-        intent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
-        try {
-            mClientIntent.send(getContext(), 0, intent);
-        } catch (CanceledException e) {
-            Log.e(TAG, "Error sending intent for media button down: "+e);
-            e.printStackTrace();
-        }
-
-        keyEvent = new KeyEvent(KeyEvent.ACTION_UP, keyCode);
-        intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
-        intent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
-        try {
-            mClientIntent.send(getContext(), 0, intent);
-        } catch (CanceledException e) {
-            Log.e(TAG, "Error sending intent for media button up: "+e);
-            e.printStackTrace();
-        }
-    }
-
-    public boolean providesClock() {
-        return false;
-    }
-
-    private boolean wasPlayingRecently(int state, long stateChangeTimeMs) {
-        switch (state) {
-            case RemoteControlClient.PLAYSTATE_PLAYING:
-            case RemoteControlClient.PLAYSTATE_FAST_FORWARDING:
-            case RemoteControlClient.PLAYSTATE_REWINDING:
-            case RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS:
-            case RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS:
-            case RemoteControlClient.PLAYSTATE_BUFFERING:
-                // actively playing or about to play
-                return true;
-            case RemoteControlClient.PLAYSTATE_NONE:
-                return false;
-            case RemoteControlClient.PLAYSTATE_STOPPED:
-            case RemoteControlClient.PLAYSTATE_PAUSED:
-            case RemoteControlClient.PLAYSTATE_ERROR:
-                // we have stopped playing, check how long ago
-                if (DEBUG) {
-                    if ((SystemClock.elapsedRealtime() - stateChangeTimeMs) < DISPLAY_TIMEOUT_MS) {
-                        Log.v(TAG, "wasPlayingRecently: time < TIMEOUT was playing recently");
-                    } else {
-                        Log.v(TAG, "wasPlayingRecently: time > TIMEOUT");
-                    }
-                }
-                return ((SystemClock.elapsedRealtime() - stateChangeTimeMs) < DISPLAY_TIMEOUT_MS);
-            default:
-                Log.e(TAG, "Unknown playback state " + state + " in wasPlayingRecently()");
-                return false;
-        }
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
deleted file mode 100644
index 5a64586..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
+++ /dev/null
@@ -1,983 +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.internal.policy.impl.keyguard;
-
-import android.app.ActivityManagerNative;
-import android.app.IUserSwitchObserver;
-import android.app.PendingIntent;
-import android.app.admin.DevicePolicyManager;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.database.ContentObserver;
-import android.graphics.Bitmap;
-
-import static android.os.BatteryManager.BATTERY_STATUS_FULL;
-import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
-import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
-import static android.os.BatteryManager.EXTRA_STATUS;
-import static android.os.BatteryManager.EXTRA_PLUGGED;
-import static android.os.BatteryManager.EXTRA_LEVEL;
-import static android.os.BatteryManager.EXTRA_HEALTH;
-import android.media.AudioManager;
-import android.media.IRemoteControlDisplay;
-import android.os.BatteryManager;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IRemoteCallback;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.provider.Settings;
-
-import com.android.internal.telephony.IccCardConstants;
-import com.android.internal.telephony.TelephonyIntents;
-
-import android.telephony.TelephonyManager;
-import android.util.Log;
-import com.android.internal.R;
-import com.google.android.collect.Lists;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-
-/**
- * Watches for updates that may be interesting to the keyguard, and provides
- * the up to date information as well as a registration for callbacks that care
- * to be updated.
- *
- * Note: under time crunch, this has been extended to include some stuff that
- * doesn't really belong here.  see {@link #handleBatteryUpdate} where it shutdowns
- * the device, and {@link #getFailedUnlockAttempts()}, {@link #reportFailedAttempt()}
- * and {@link #clearFailedUnlockAttempts()}.  Maybe we should rename this 'KeyguardContext'...
- */
-public class KeyguardUpdateMonitor {
-
-    private static final String TAG = "KeyguardUpdateMonitor";
-    private static final boolean DEBUG = false;
-    private static final boolean DEBUG_SIM_STATES = DEBUG || false;
-    private static final int FAILED_BIOMETRIC_UNLOCK_ATTEMPTS_BEFORE_BACKUP = 3;
-    private static final int LOW_BATTERY_THRESHOLD = 20;
-
-    // Callback messages
-    private static final int MSG_TIME_UPDATE = 301;
-    private static final int MSG_BATTERY_UPDATE = 302;
-    private static final int MSG_CARRIER_INFO_UPDATE = 303;
-    private static final int MSG_SIM_STATE_CHANGE = 304;
-    private static final int MSG_RINGER_MODE_CHANGED = 305;
-    private static final int MSG_PHONE_STATE_CHANGED = 306;
-    private static final int MSG_CLOCK_VISIBILITY_CHANGED = 307;
-    private static final int MSG_DEVICE_PROVISIONED = 308;
-    private static final int MSG_DPM_STATE_CHANGED = 309;
-    private static final int MSG_USER_SWITCHING = 310;
-    private static final int MSG_USER_REMOVED = 311;
-    private static final int MSG_KEYGUARD_VISIBILITY_CHANGED = 312;
-    protected static final int MSG_BOOT_COMPLETED = 313;
-    private static final int MSG_USER_SWITCH_COMPLETE = 314;
-    private static final int MSG_SET_CURRENT_CLIENT_ID = 315;
-    protected static final int MSG_SET_PLAYBACK_STATE = 316;
-    protected static final int MSG_USER_INFO_CHANGED = 317;
-
-
-    private static KeyguardUpdateMonitor sInstance;
-
-    private final Context mContext;
-
-    // Telephony state
-    private IccCardConstants.State mSimState = IccCardConstants.State.READY;
-    private CharSequence mTelephonyPlmn;
-    private CharSequence mTelephonySpn;
-    private int mRingMode;
-    private int mPhoneState;
-    private boolean mKeyguardIsVisible;
-    private boolean mBootCompleted;
-
-    // Device provisioning state
-    private boolean mDeviceProvisioned;
-
-    // Battery status
-    private BatteryStatus mBatteryStatus;
-
-    // Password attempts
-    private int mFailedAttempts = 0;
-    private int mFailedBiometricUnlockAttempts = 0;
-
-    private boolean mAlternateUnlockEnabled;
-
-    private boolean mClockVisible;
-
-    private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
-            mCallbacks = Lists.newArrayList();
-    private ContentObserver mDeviceProvisionedObserver;
-
-    private boolean mSwitchingUser;
-
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_TIME_UPDATE:
-                    handleTimeUpdate();
-                    break;
-                case MSG_BATTERY_UPDATE:
-                    handleBatteryUpdate((BatteryStatus) msg.obj);
-                    break;
-                case MSG_CARRIER_INFO_UPDATE:
-                    handleCarrierInfoUpdate();
-                    break;
-                case MSG_SIM_STATE_CHANGE:
-                    handleSimStateChange((SimArgs) msg.obj);
-                    break;
-                case MSG_RINGER_MODE_CHANGED:
-                    handleRingerModeChange(msg.arg1);
-                    break;
-                case MSG_PHONE_STATE_CHANGED:
-                    handlePhoneStateChanged((String)msg.obj);
-                    break;
-                case MSG_CLOCK_VISIBILITY_CHANGED:
-                    handleClockVisibilityChanged();
-                    break;
-                case MSG_DEVICE_PROVISIONED:
-                    handleDeviceProvisioned();
-                    break;
-                case MSG_DPM_STATE_CHANGED:
-                    handleDevicePolicyManagerStateChanged();
-                    break;
-                case MSG_USER_SWITCHING:
-                    handleUserSwitching(msg.arg1, (IRemoteCallback)msg.obj);
-                    break;
-                case MSG_USER_SWITCH_COMPLETE:
-                    handleUserSwitchComplete(msg.arg1);
-                    break;
-                case MSG_USER_REMOVED:
-                    handleUserRemoved(msg.arg1);
-                    break;
-                case MSG_KEYGUARD_VISIBILITY_CHANGED:
-                    handleKeyguardVisibilityChanged(msg.arg1);
-                    break;
-                case MSG_BOOT_COMPLETED:
-                    handleBootCompleted();
-                    break;
-                case MSG_SET_CURRENT_CLIENT_ID:
-                    handleSetGenerationId(msg.arg1, msg.arg2 != 0, (PendingIntent) msg.obj);
-                    break;
-                case MSG_SET_PLAYBACK_STATE:
-                    handleSetPlaybackState(msg.arg1, msg.arg2, (Long) msg.obj);
-                    break;
-                case MSG_USER_INFO_CHANGED:
-                    handleUserInfoChanged(msg.arg1);
-                    break;
-            }
-        }
-    };
-
-    private AudioManager mAudioManager;
-
-    static class DisplayClientState {
-        public int clientGeneration;
-        public boolean clearing;
-        public PendingIntent intent;
-        public int playbackState;
-        public long playbackEventTime;
-    }
-
-    private DisplayClientState mDisplayClientState = new DisplayClientState();
-
-    /**
-     * This currently implements the bare minimum required to enable showing and hiding
-     * KeyguardTransportControl.  There's a lot of client state to maintain which is why
-     * KeyguardTransportControl maintains an independent connection while it's showing.
-     */
-    private final IRemoteControlDisplay.Stub mRemoteControlDisplay =
-                new IRemoteControlDisplay.Stub() {
-
-        public void setPlaybackState(int generationId, int state, long stateChangeTimeMs,
-                long currentPosMs, float speed) {
-            Message msg = mHandler.obtainMessage(MSG_SET_PLAYBACK_STATE,
-                    generationId, state, stateChangeTimeMs);
-            mHandler.sendMessage(msg);
-        }
-
-        public void setMetadata(int generationId, Bundle metadata) {
-
-        }
-
-        public void setTransportControlInfo(int generationId, int flags, int posCapabilities) {
-
-        }
-
-        public void setArtwork(int generationId, Bitmap bitmap) {
-
-        }
-
-        public void setAllMetadata(int generationId, Bundle metadata, Bitmap bitmap) {
-
-        }
-
-        public void setCurrentClientId(int clientGeneration, PendingIntent mediaIntent,
-                boolean clearing) throws RemoteException {
-            Message msg = mHandler.obtainMessage(MSG_SET_CURRENT_CLIENT_ID,
-                        clientGeneration, (clearing ? 1 : 0), mediaIntent);
-            mHandler.sendMessage(msg);
-        }
-    };
-
-    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-
-        public void onReceive(Context context, Intent intent) {
-            final String action = intent.getAction();
-            if (DEBUG) Log.d(TAG, "received broadcast " + action);
-
-            if (Intent.ACTION_TIME_TICK.equals(action)
-                    || Intent.ACTION_TIME_CHANGED.equals(action)
-                    || Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
-                mHandler.sendMessage(mHandler.obtainMessage(MSG_TIME_UPDATE));
-            } else if (TelephonyIntents.SPN_STRINGS_UPDATED_ACTION.equals(action)) {
-                mTelephonyPlmn = getTelephonyPlmnFrom(intent);
-                mTelephonySpn = getTelephonySpnFrom(intent);
-                mHandler.sendMessage(mHandler.obtainMessage(MSG_CARRIER_INFO_UPDATE));
-            } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
-                final int status = intent.getIntExtra(EXTRA_STATUS, BATTERY_STATUS_UNKNOWN);
-                final int plugged = intent.getIntExtra(EXTRA_PLUGGED, 0);
-                final int level = intent.getIntExtra(EXTRA_LEVEL, 0);
-                final int health = intent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
-                final Message msg = mHandler.obtainMessage(
-                        MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health));
-                mHandler.sendMessage(msg);
-            } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
-                if (DEBUG_SIM_STATES) {
-                    Log.v(TAG, "action " + action + " state" +
-                        intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE));
-                }
-                mHandler.sendMessage(mHandler.obtainMessage(
-                        MSG_SIM_STATE_CHANGE, SimArgs.fromIntent(intent)));
-            } else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
-                mHandler.sendMessage(mHandler.obtainMessage(MSG_RINGER_MODE_CHANGED,
-                        intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1), 0));
-            } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
-                String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
-                mHandler.sendMessage(mHandler.obtainMessage(MSG_PHONE_STATE_CHANGED, state));
-            } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
-                    .equals(action)) {
-                mHandler.sendMessage(mHandler.obtainMessage(MSG_DPM_STATE_CHANGED));
-            } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
-                mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_REMOVED,
-                       intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0), 0));
-            } else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
-                mHandler.sendMessage(mHandler.obtainMessage(MSG_BOOT_COMPLETED));
-            }
-        }
-    };
-
-    private final BroadcastReceiver mBroadcastAllReceiver = new BroadcastReceiver() {
-
-        public void onReceive(Context context, Intent intent) {
-            final String action = intent.getAction();
-            if (Intent.ACTION_USER_INFO_CHANGED.equals(action)) {
-                mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_INFO_CHANGED,
-                        intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId()), 0));
-            }
-        }
-    };
-
-    /**
-     * When we receive a
-     * {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast,
-     * and then pass a result via our handler to {@link KeyguardUpdateMonitor#handleSimStateChange},
-     * we need a single object to pass to the handler.  This class helps decode
-     * the intent and provide a {@link SimCard.State} result.
-     */
-    private static class SimArgs {
-        public final IccCardConstants.State simState;
-
-        SimArgs(IccCardConstants.State state) {
-            simState = state;
-        }
-
-        static SimArgs fromIntent(Intent intent) {
-            IccCardConstants.State state;
-            if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
-                throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
-            }
-            String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
-            if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
-                final String absentReason = intent
-                    .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
-
-                if (IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
-                        absentReason)) {
-                    state = IccCardConstants.State.PERM_DISABLED;
-                } else {
-                    state = IccCardConstants.State.ABSENT;
-                }
-            } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
-                state = IccCardConstants.State.READY;
-            } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
-                final String lockedReason = intent
-                        .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
-                if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
-                    state = IccCardConstants.State.PIN_REQUIRED;
-                } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
-                    state = IccCardConstants.State.PUK_REQUIRED;
-                } else {
-                    state = IccCardConstants.State.UNKNOWN;
-                }
-            } else if (IccCardConstants.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
-                state = IccCardConstants.State.NETWORK_LOCKED;
-            } 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
-                // these state transitions. See bug 7197471.
-                state = IccCardConstants.State.READY;
-            } else {
-                state = IccCardConstants.State.UNKNOWN;
-            }
-            return new SimArgs(state);
-        }
-
-        public String toString() {
-            return simState.toString();
-        }
-    }
-
-    /* package */ static class BatteryStatus {
-        public final int status;
-        public final int level;
-        public final int plugged;
-        public final int health;
-        public BatteryStatus(int status, int level, int plugged, int health) {
-            this.status = status;
-            this.level = level;
-            this.plugged = plugged;
-            this.health = health;
-        }
-
-        /**
-         * Determine whether the device is plugged in (USB, power, or wireless).
-         * @return true if the device is plugged in.
-         */
-        boolean isPluggedIn() {
-            return plugged == BatteryManager.BATTERY_PLUGGED_AC
-                    || plugged == BatteryManager.BATTERY_PLUGGED_USB
-                    || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
-        }
-
-        /**
-         * Whether or not the device is charged. Note that some devices never return 100% for
-         * battery level, so this allows either battery level or status to determine if the
-         * battery is charged.
-         * @return true if the device is charged
-         */
-        public boolean isCharged() {
-            return status == BATTERY_STATUS_FULL || level >= 100;
-        }
-
-        /**
-         * Whether battery is low and needs to be charged.
-         * @return true if battery is low
-         */
-        public boolean isBatteryLow() {
-            return level < LOW_BATTERY_THRESHOLD;
-        }
-
-    }
-
-    public static KeyguardUpdateMonitor getInstance(Context context) {
-        if (sInstance == null) {
-            sInstance = new KeyguardUpdateMonitor(context);
-        }
-        return sInstance;
-    }
-
-    protected void handleSetGenerationId(int clientGeneration, boolean clearing, PendingIntent p) {
-        mDisplayClientState.clientGeneration = clientGeneration;
-        mDisplayClientState.clearing = clearing;
-        mDisplayClientState.intent = p;
-        if (DEBUG)
-            Log.v(TAG, "handleSetGenerationId(g=" + clientGeneration + ", clear=" + clearing + ")");
-        for (int i = 0; i < mCallbacks.size(); i++) {
-            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
-            if (cb != null) {
-                cb.onMusicClientIdChanged(clientGeneration, clearing, p);
-            }
-        }
-    }
-
-    protected void handleSetPlaybackState(int generationId, int playbackState, long eventTime) {
-        if (DEBUG)
-            Log.v(TAG, "handleSetPlaybackState(gen=" + generationId
-                + ", state=" + playbackState + ", t=" + eventTime + ")");
-        mDisplayClientState.playbackState = playbackState;
-        mDisplayClientState.playbackEventTime = eventTime;
-        if (generationId == mDisplayClientState.clientGeneration) {
-            for (int i = 0; i < mCallbacks.size(); i++) {
-                KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
-                if (cb != null) {
-                    cb.onMusicPlaybackStateChanged(playbackState, eventTime);
-                }
-            }
-        } else {
-            Log.w(TAG, "Ignoring generation id " + generationId + " because it's not current");
-        }
-    }
-
-    private void handleUserInfoChanged(int userId) {
-        for (int i = 0; i < mCallbacks.size(); i++) {
-            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
-            if (cb != null) {
-                cb.onUserInfoChanged(userId);
-            }
-        }
-    }
-
-    private KeyguardUpdateMonitor(Context context) {
-        mContext = context;
-
-        mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
-        // Since device can't be un-provisioned, we only need to register a content observer
-        // to update mDeviceProvisioned when we are...
-        if (!mDeviceProvisioned) {
-            watchForDeviceProvisioning();
-        }
-
-        // Take a guess at initial SIM state, battery status and PLMN until we get an update
-        mSimState = IccCardConstants.State.NOT_READY;
-        mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0);
-        mTelephonyPlmn = getDefaultPlmn();
-
-        // Watch for interesting updates
-        final IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_TIME_TICK);
-        filter.addAction(Intent.ACTION_TIME_CHANGED);
-        filter.addAction(Intent.ACTION_BATTERY_CHANGED);
-        filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
-        filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
-        filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
-        filter.addAction(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION);
-        filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
-        filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
-        filter.addAction(Intent.ACTION_USER_REMOVED);
-        context.registerReceiver(mBroadcastReceiver, filter);
-
-        final IntentFilter bootCompleteFilter = new IntentFilter();
-        bootCompleteFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
-        bootCompleteFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
-        context.registerReceiver(mBroadcastReceiver, bootCompleteFilter);
-
-        final IntentFilter userInfoFilter = new IntentFilter(Intent.ACTION_USER_INFO_CHANGED);
-        context.registerReceiverAsUser(mBroadcastAllReceiver, UserHandle.ALL, userInfoFilter,
-                null, null);
-
-        try {
-            ActivityManagerNative.getDefault().registerUserSwitchObserver(
-                    new IUserSwitchObserver.Stub() {
-                        @Override
-                        public void onUserSwitching(int newUserId, IRemoteCallback reply) {
-                            mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHING,
-                                    newUserId, 0, reply));
-                            mSwitchingUser = true;
-                        }
-                        @Override
-                        public void onUserSwitchComplete(int newUserId) throws RemoteException {
-                            mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCH_COMPLETE,
-                                    newUserId));
-                            mSwitchingUser = false;
-                        }
-                    });
-        } catch (RemoteException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
-        }
-    }
-
-    private boolean isDeviceProvisionedInSettingsDb() {
-        return Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.DEVICE_PROVISIONED, 0) != 0;
-    }
-
-    private void watchForDeviceProvisioning() {
-        mDeviceProvisionedObserver = new ContentObserver(mHandler) {
-            @Override
-            public void onChange(boolean selfChange) {
-                super.onChange(selfChange);
-                mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
-                if (mDeviceProvisioned) {
-                    mHandler.sendMessage(mHandler.obtainMessage(MSG_DEVICE_PROVISIONED));
-                }
-                if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned);
-            }
-        };
-
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
-                false, mDeviceProvisionedObserver);
-
-        // prevent a race condition between where we check the flag and where we register the
-        // observer by grabbing the value once again...
-        boolean provisioned = isDeviceProvisionedInSettingsDb();
-        if (provisioned != mDeviceProvisioned) {
-            mDeviceProvisioned = provisioned;
-            if (mDeviceProvisioned) {
-                mHandler.sendMessage(mHandler.obtainMessage(MSG_DEVICE_PROVISIONED));
-            }
-        }
-    }
-
-    /**
-     * Handle {@link #MSG_DPM_STATE_CHANGED}
-     */
-    protected void handleDevicePolicyManagerStateChanged() {
-        for (int i = mCallbacks.size() - 1; i >= 0; i--) {
-            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
-            if (cb != null) {
-                cb.onDevicePolicyManagerStateChanged();
-            }
-        }
-    }
-
-    /**
-     * Handle {@link #MSG_USER_SWITCHING}
-     */
-    protected void handleUserSwitching(int userId, IRemoteCallback reply) {
-        for (int i = 0; i < mCallbacks.size(); i++) {
-            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
-            if (cb != null) {
-                cb.onUserSwitching(userId);
-            }
-        }
-        try {
-            reply.sendResult(null);
-        } catch (RemoteException e) {
-        }
-    }
-
-    /**
-     * Handle {@link #MSG_USER_SWITCH_COMPLETE}
-     */
-    protected void handleUserSwitchComplete(int userId) {
-        for (int i = 0; i < mCallbacks.size(); i++) {
-            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
-            if (cb != null) {
-                cb.onUserSwitchComplete(userId);
-            }
-        }
-    }
-
-    /**
-     * Handle {@link #MSG_BOOT_COMPLETED}
-     */
-    protected void handleBootCompleted() {
-        mBootCompleted = true;
-        mAudioManager = new AudioManager(mContext);
-        mAudioManager.registerRemoteControlDisplay(mRemoteControlDisplay);
-        for (int i = 0; i < mCallbacks.size(); i++) {
-            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
-            if (cb != null) {
-                cb.onBootCompleted();
-            }
-        }
-    }
-
-    /**
-     * We need to store this state in the KeyguardUpdateMonitor since this class will not be
-     * destroyed.
-     */
-    public boolean hasBootCompleted() {
-        return mBootCompleted;
-    }
-
-    /**
-     * Handle {@link #MSG_USER_REMOVED}
-     */
-    protected void handleUserRemoved(int userId) {
-        for (int i = 0; i < mCallbacks.size(); i++) {
-            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
-            if (cb != null) {
-                cb.onUserRemoved(userId);
-            }
-        }
-    }
-
-    /**
-     * Handle {@link #MSG_DEVICE_PROVISIONED}
-     */
-    protected void handleDeviceProvisioned() {
-        for (int i = 0; i < mCallbacks.size(); i++) {
-            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
-            if (cb != null) {
-                cb.onDeviceProvisioned();
-            }
-        }
-        if (mDeviceProvisionedObserver != null) {
-            // We don't need the observer anymore...
-            mContext.getContentResolver().unregisterContentObserver(mDeviceProvisionedObserver);
-            mDeviceProvisionedObserver = null;
-        }
-    }
-
-    /**
-     * Handle {@link #MSG_PHONE_STATE_CHANGED}
-     */
-    protected void handlePhoneStateChanged(String newState) {
-        if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")");
-        if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) {
-            mPhoneState = TelephonyManager.CALL_STATE_IDLE;
-        } else if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(newState)) {
-            mPhoneState = TelephonyManager.CALL_STATE_OFFHOOK;
-        } else if (TelephonyManager.EXTRA_STATE_RINGING.equals(newState)) {
-            mPhoneState = TelephonyManager.CALL_STATE_RINGING;
-        }
-        for (int i = 0; i < mCallbacks.size(); i++) {
-            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
-            if (cb != null) {
-                cb.onPhoneStateChanged(mPhoneState);
-            }
-        }
-    }
-
-    /**
-     * Handle {@link #MSG_RINGER_MODE_CHANGED}
-     */
-    protected void handleRingerModeChange(int mode) {
-        if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")");
-        mRingMode = mode;
-        for (int i = 0; i < mCallbacks.size(); i++) {
-            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
-            if (cb != null) {
-                cb.onRingerModeChanged(mode);
-            }
-        }
-    }
-
-    /**
-     * Handle {@link #MSG_TIME_UPDATE}
-     */
-    private void handleTimeUpdate() {
-        if (DEBUG) Log.d(TAG, "handleTimeUpdate");
-        for (int i = 0; i < mCallbacks.size(); i++) {
-            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
-            if (cb != null) {
-                cb.onTimeChanged();
-            }
-        }
-    }
-
-    /**
-     * Handle {@link #MSG_BATTERY_UPDATE}
-     */
-    private void handleBatteryUpdate(BatteryStatus status) {
-        if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
-        final boolean batteryUpdateInteresting = isBatteryUpdateInteresting(mBatteryStatus, status);
-        mBatteryStatus = status;
-        if (batteryUpdateInteresting) {
-            for (int i = 0; i < mCallbacks.size(); i++) {
-                KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
-                if (cb != null) {
-                    cb.onRefreshBatteryInfo(status);
-                }
-            }
-        }
-    }
-
-    /**
-     * Handle {@link #MSG_CARRIER_INFO_UPDATE}
-     */
-    private void handleCarrierInfoUpdate() {
-        if (DEBUG) Log.d(TAG, "handleCarrierInfoUpdate: plmn = " + mTelephonyPlmn
-            + ", spn = " + mTelephonySpn);
-
-        for (int i = 0; i < mCallbacks.size(); i++) {
-            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
-            if (cb != null) {
-                cb.onRefreshCarrierInfo(mTelephonyPlmn, mTelephonySpn);
-            }
-        }
-    }
-
-    /**
-     * Handle {@link #MSG_SIM_STATE_CHANGE}
-     */
-    private void handleSimStateChange(SimArgs simArgs) {
-        final IccCardConstants.State state = simArgs.simState;
-
-        if (DEBUG) {
-            Log.d(TAG, "handleSimStateChange: intentValue = " + simArgs + " "
-                    + "state resolved to " + state.toString());
-        }
-
-        if (state != IccCardConstants.State.UNKNOWN && state != mSimState) {
-            mSimState = state;
-            for (int i = 0; i < mCallbacks.size(); i++) {
-                KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
-                if (cb != null) {
-                    cb.onSimStateChanged(state);
-                }
-            }
-        }
-    }
-
-    /**
-     * Handle {@link #MSG_CLOCK_VISIBILITY_CHANGED}
-     */
-    private void handleClockVisibilityChanged() {
-        if (DEBUG) Log.d(TAG, "handleClockVisibilityChanged()");
-        for (int i = 0; i < mCallbacks.size(); i++) {
-            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
-            if (cb != null) {
-                cb.onClockVisibilityChanged();
-            }
-        }
-    }
-
-    /**
-     * Handle {@link #MSG_KEYGUARD_VISIBILITY_CHANGED}
-     */
-    private void handleKeyguardVisibilityChanged(int showing) {
-        if (DEBUG) Log.d(TAG, "handleKeyguardVisibilityChanged(" + showing + ")");
-        boolean isShowing = (showing == 1);
-        mKeyguardIsVisible = isShowing;
-        for (int i = 0; i < mCallbacks.size(); i++) {
-            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
-            if (cb != null) {
-                cb.onKeyguardVisibilityChanged(isShowing);
-            }
-        }
-    }
-
-    public boolean isKeyguardVisible() {
-        return mKeyguardIsVisible;
-    }
-
-    public boolean isSwitchingUser() {
-        return mSwitchingUser;
-    }
-
-    private static boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) {
-        final boolean nowPluggedIn = current.isPluggedIn();
-        final boolean wasPluggedIn = old.isPluggedIn();
-        final boolean stateChangedWhilePluggedIn =
-            wasPluggedIn == true && nowPluggedIn == true
-            && (old.status != current.status);
-
-        // change in plug state is always interesting
-        if (wasPluggedIn != nowPluggedIn || stateChangedWhilePluggedIn) {
-            return true;
-        }
-
-        // change in battery level while plugged in
-        if (nowPluggedIn && old.level != current.level) {
-            return true;
-        }
-
-        // change where battery needs charging
-        if (!nowPluggedIn && current.isBatteryLow() && current.level != old.level) {
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * @param intent The intent with action {@link TelephonyIntents#SPN_STRINGS_UPDATED_ACTION}
-     * @return The string to use for the plmn, or null if it should not be shown.
-     */
-    private CharSequence getTelephonyPlmnFrom(Intent intent) {
-        if (intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_PLMN, false)) {
-            final String plmn = intent.getStringExtra(TelephonyIntents.EXTRA_PLMN);
-            return (plmn != null) ? plmn : getDefaultPlmn();
-        }
-        return null;
-    }
-
-    /**
-     * @return The default plmn (no service)
-     */
-    private CharSequence getDefaultPlmn() {
-        return mContext.getResources().getText(R.string.lockscreen_carrier_default);
-    }
-
-    /**
-     * @param intent The intent with action {@link Telephony.Intents#SPN_STRINGS_UPDATED_ACTION}
-     * @return The string to use for the plmn, or null if it should not be shown.
-     */
-    private CharSequence getTelephonySpnFrom(Intent intent) {
-        if (intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_SPN, false)) {
-            final String spn = intent.getStringExtra(TelephonyIntents.EXTRA_SPN);
-            if (spn != null) {
-                return spn;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Remove the given observer's callback.
-     *
-     * @param callback The callback to remove
-     */
-    public void removeCallback(KeyguardUpdateMonitorCallback callback) {
-        if (DEBUG) Log.v(TAG, "*** unregister callback for " + callback);
-        for (int i = mCallbacks.size() - 1; i >= 0; i--) {
-            if (mCallbacks.get(i).get() == callback) {
-                mCallbacks.remove(i);
-            }
-        }
-    }
-
-    /**
-     * Register to receive notifications about general keyguard information
-     * (see {@link InfoCallback}.
-     * @param callback The callback to register
-     */
-    public void registerCallback(KeyguardUpdateMonitorCallback callback) {
-        if (DEBUG) Log.v(TAG, "*** register callback for " + callback);
-        // Prevent adding duplicate callbacks
-        for (int i = 0; i < mCallbacks.size(); i++) {
-            if (mCallbacks.get(i).get() == callback) {
-                if (DEBUG) Log.e(TAG, "Object tried to add another callback",
-                        new Exception("Called by"));
-                return;
-            }
-        }
-        mCallbacks.add(new WeakReference<KeyguardUpdateMonitorCallback>(callback));
-        removeCallback(null); // remove unused references
-        sendUpdates(callback);
-    }
-
-    private void sendUpdates(KeyguardUpdateMonitorCallback callback) {
-        // Notify listener of the current state
-        callback.onRefreshBatteryInfo(mBatteryStatus);
-        callback.onTimeChanged();
-        callback.onRingerModeChanged(mRingMode);
-        callback.onPhoneStateChanged(mPhoneState);
-        callback.onRefreshCarrierInfo(mTelephonyPlmn, mTelephonySpn);
-        callback.onClockVisibilityChanged();
-        callback.onSimStateChanged(mSimState);
-        callback.onMusicClientIdChanged(
-                mDisplayClientState.clientGeneration,
-                mDisplayClientState.clearing,
-                mDisplayClientState.intent);
-        callback.onMusicPlaybackStateChanged(mDisplayClientState.playbackState,
-                mDisplayClientState.playbackEventTime);
-    }
-
-    public void sendKeyguardVisibilityChanged(boolean showing) {
-        if (DEBUG) Log.d(TAG, "sendKeyguardVisibilityChanged(" + showing + ")");
-        Message message = mHandler.obtainMessage(MSG_KEYGUARD_VISIBILITY_CHANGED);
-        message.arg1 = showing ? 1 : 0;
-        message.sendToTarget();
-    }
-
-    public void reportClockVisible(boolean visible) {
-        mClockVisible = visible;
-        mHandler.obtainMessage(MSG_CLOCK_VISIBILITY_CHANGED).sendToTarget();
-    }
-
-    public IccCardConstants.State getSimState() {
-        return mSimState;
-    }
-
-    /**
-     * Report that the user successfully entered the SIM PIN or PUK/SIM PIN so we
-     * have the information earlier than waiting for the intent
-     * broadcast from the telephony code.
-     *
-     * NOTE: Because handleSimStateChange() invokes callbacks immediately without going
-     * through mHandler, this *must* be called from the UI thread.
-     */
-    public void reportSimUnlocked() {
-        handleSimStateChange(new SimArgs(IccCardConstants.State.READY));
-    }
-
-    public CharSequence getTelephonyPlmn() {
-        return mTelephonyPlmn;
-    }
-
-    public CharSequence getTelephonySpn() {
-        return mTelephonySpn;
-    }
-
-    /**
-     * @return Whether the device is provisioned (whether they have gone through
-     *   the setup wizard)
-     */
-    public boolean isDeviceProvisioned() {
-        return mDeviceProvisioned;
-    }
-
-    public int getFailedUnlockAttempts() {
-        return mFailedAttempts;
-    }
-
-    public void clearFailedUnlockAttempts() {
-        mFailedAttempts = 0;
-        mFailedBiometricUnlockAttempts = 0;
-    }
-
-    public void reportFailedUnlockAttempt() {
-        mFailedAttempts++;
-    }
-
-    public boolean isClockVisible() {
-        return mClockVisible;
-    }
-
-    public int getPhoneState() {
-        return mPhoneState;
-    }
-
-    public void reportFailedBiometricUnlockAttempt() {
-        mFailedBiometricUnlockAttempts++;
-    }
-
-    public boolean getMaxBiometricUnlockAttemptsReached() {
-        return mFailedBiometricUnlockAttempts >= FAILED_BIOMETRIC_UNLOCK_ATTEMPTS_BEFORE_BACKUP;
-    }
-
-    public boolean isAlternateUnlockEnabled() {
-        return mAlternateUnlockEnabled;
-    }
-
-    public void setAlternateUnlockEnabled(boolean enabled) {
-        mAlternateUnlockEnabled = enabled;
-    }
-
-    public boolean isSimLocked() {
-        return isSimLocked(mSimState);
-    }
-
-    public static boolean isSimLocked(IccCardConstants.State state) {
-        return state == IccCardConstants.State.PIN_REQUIRED
-        || state == IccCardConstants.State.PUK_REQUIRED
-        || state == IccCardConstants.State.PERM_DISABLED;
-    }
-
-    public boolean isSimPinSecure() {
-        return isSimPinSecure(mSimState);
-    }
-
-    public static boolean isSimPinSecure(IccCardConstants.State state) {
-        final IccCardConstants.State simState = state;
-        return (simState == IccCardConstants.State.PIN_REQUIRED
-                || simState == IccCardConstants.State.PUK_REQUIRED
-                || simState == IccCardConstants.State.PERM_DISABLED);
-    }
-
-    public DisplayClientState getCachedDisplayClientState() {
-        return mDisplayClientState;
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitorCallback.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitorCallback.java
deleted file mode 100644
index 41816db..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitorCallback.java
+++ /dev/null
@@ -1,134 +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.internal.policy.impl.keyguard;
-
-import android.app.PendingIntent;
-import android.app.admin.DevicePolicyManager;
-import android.media.AudioManager;
-
-import com.android.internal.telephony.IccCardConstants;
-
-/**
- * Callback for general information relevant to lock screen.
- */
-class KeyguardUpdateMonitorCallback {
-    /**
-     * Called when the battery status changes, e.g. when plugged in or unplugged, charge
-     * level, etc. changes.
-     *
-     * @param status current battery status
-     */
-    void onRefreshBatteryInfo(KeyguardUpdateMonitor.BatteryStatus status) { }
-
-    /**
-     * Called once per minute or when the time changes.
-     */
-    void onTimeChanged() { }
-
-    /**
-     * Called when the carrier PLMN or SPN changes.
-     *
-     * @param plmn The operator name of the registered network.  May be null if it shouldn't
-     *   be displayed.
-     * @param spn The service provider name.  May be null if it shouldn't be displayed.
-     */
-    void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) { }
-
-    /**
-     * Called when the ringer mode changes.
-     * @param state the current ringer state, as defined in
-     * {@link AudioManager#RINGER_MODE_CHANGED_ACTION}
-     */
-    void onRingerModeChanged(int state) { }
-
-    /**
-     * Called when the phone state changes. String will be one of:
-     * {@link TelephonyManager#EXTRA_STATE_IDLE}
-     * {@link TelephonyManager@EXTRA_STATE_RINGING}
-     * {@link TelephonyManager#EXTRA_STATE_OFFHOOK
-     */
-    void onPhoneStateChanged(int phoneState) { }
-
-    /**
-     * Called when the visibility of the keyguard changes.
-     * @param showing Indicates if the keyguard is now visible.
-     */
-    void onKeyguardVisibilityChanged(boolean showing) { }
-
-    /**
-     * Called when visibility of lockscreen clock changes, such as when
-     * obscured by a widget.
-     */
-    void onClockVisibilityChanged() { }
-
-    /**
-     * Called when the device becomes provisioned
-     */
-    void onDeviceProvisioned() { }
-
-    /**
-     * Called when the device policy changes.
-     * See {@link DevicePolicyManager#ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED}
-     */
-    void onDevicePolicyManagerStateChanged() { }
-
-    /**
-     * Called when the user change begins.
-     */
-    void onUserSwitching(int userId) { }
-
-    /**
-     * Called when the user change is complete.
-     */
-    void onUserSwitchComplete(int userId) { }
-
-    /**
-     * Called when the SIM state changes.
-     * @param simState
-     */
-    void onSimStateChanged(IccCardConstants.State simState) { }
-
-    /**
-     * Called when a user is removed.
-     */
-    void onUserRemoved(int userId) { }
-
-    /**
-     * Called when the user's info changed.
-     */
-    void onUserInfoChanged(int userId) { }
-
-    /**
-     * Called when boot completed.
-     *
-     * Note, this callback will only be received if boot complete occurs after registering with
-     * KeyguardUpdateMonitor.
-     */
-    void onBootCompleted() { }
-
-    /**
-     * Called when audio client attaches or detaches from AudioManager.
-     */
-    void onMusicClientIdChanged(int clientGeneration, boolean clearing, PendingIntent intent) { }
-
-    /**
-     * Called when the audio playback state changes.
-     * @param playbackState
-     * @param eventTime
-     */
-    public void onMusicPlaybackStateChanged(int playbackState, long eventTime) { }
-
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewBase.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewBase.java
deleted file mode 100644
index 6fcacd3..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewBase.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.policy.impl.keyguard;
-
-import android.app.Activity;
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.ColorFilter;
-import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
-import android.graphics.drawable.Drawable;
-import android.media.AudioManager;
-import android.media.IAudioService;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.telephony.TelephonyManager;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.Slog;
-import android.view.KeyEvent;
-import android.widget.FrameLayout;
-
-/**
- * Base class for keyguard view.  {@link #reset} is where you should
- * reset the state of your view.  Use the {@link KeyguardViewCallback} via
- * {@link #getCallback()} to send information back (such as poking the wake lock,
- * or finishing the keyguard).
- *
- * Handles intercepting of media keys that still work when the keyguard is
- * showing.
- */
-public abstract class KeyguardViewBase extends FrameLayout {
-
-    private static final int BACKGROUND_COLOR = 0x70000000;
-    private AudioManager mAudioManager;
-    private TelephonyManager mTelephonyManager = null;
-    protected KeyguardViewMediator.ViewMediatorCallback mViewMediatorCallback;
-
-    // Whether the volume keys should be handled by keyguard. If true, then
-    // they will be handled here for specific media types such as music, otherwise
-    // the audio service will bring up the volume dialog.
-    private static final boolean KEYGUARD_MANAGES_VOLUME = true;
-
-    // This is a faster way to draw the background on devices without hardware acceleration
-    private static final Drawable mBackgroundDrawable = new Drawable() {
-        @Override
-        public void draw(Canvas canvas) {
-            canvas.drawColor(BACKGROUND_COLOR, PorterDuff.Mode.SRC);
-        }
-
-        @Override
-        public void setAlpha(int alpha) {
-        }
-
-        @Override
-        public void setColorFilter(ColorFilter cf) {
-        }
-
-        @Override
-        public int getOpacity() {
-            return PixelFormat.TRANSLUCENT;
-        }
-    };
-
-    public KeyguardViewBase(Context context) {
-        this(context, null);
-    }
-
-    public KeyguardViewBase(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        resetBackground();
-    }
-
-    public void resetBackground() {
-        setBackground(mBackgroundDrawable);
-    }
-
-    /**
-     * Called when you need to reset the state of your view.
-     */
-    abstract public void reset();
-
-    /**
-     * Called when the screen turned off.
-     */
-    abstract public void onScreenTurnedOff();
-
-    /**
-     * Called when the screen turned on.
-     */
-    abstract public void onScreenTurnedOn();
-
-    /**
-     * Called when the view needs to be shown.
-     */
-    abstract public void show();
-
-    /**
-     * Called when a key has woken the device to give us a chance to adjust our
-     * state according the the key.  We are responsible for waking the device
-     * (by poking the wake lock) once we are ready.
-     *
-     * The 'Tq' suffix is per the documentation in {@link android.view.WindowManagerPolicy}.
-     * Be sure not to take any action that takes a long time; any significant
-     * action should be posted to a handler.
-     *
-     * @param keyCode The wake key, which may be relevant for configuring the
-     *   keyguard.  May be {@link KeyEvent#KEYCODE_UNKNOWN} if waking for a reason
-     *   other than a key press.
-     */
-    abstract public void wakeWhenReadyTq(int keyCode);
-
-    /**
-     * Verify that the user can get past the keyguard securely.  This is called,
-     * for example, when the phone disables the keyguard but then wants to launch
-     * something else that requires secure access.
-     *
-     * The result will be propogated back via {@link KeyguardViewCallback#keyguardDone(boolean)}
-     */
-    abstract public void verifyUnlock();
-
-    /**
-     * Called before this view is being removed.
-     */
-    abstract public void cleanUp();
-
-    /**
-     * Gets the desired user activity timeout in milliseconds, or -1 if the
-     * default should be used.
-     */
-    abstract public long getUserActivityTimeout();
-
-    @Override
-    public boolean dispatchKeyEvent(KeyEvent event) {
-        if (interceptMediaKey(event)) {
-            return true;
-        }
-        return super.dispatchKeyEvent(event);
-    }
-
-    /**
-     * Allows the media keys to work when the keyguard is showing.
-     * The media keys should be of no interest to the actual keyguard view(s),
-     * so intercepting them here should not be of any harm.
-     * @param event The key event
-     * @return whether the event was consumed as a media key.
-     */
-    private boolean interceptMediaKey(KeyEvent event) {
-        final int keyCode = event.getKeyCode();
-        if (event.getAction() == KeyEvent.ACTION_DOWN) {
-            switch (keyCode) {
-                case KeyEvent.KEYCODE_MEDIA_PLAY:
-                case KeyEvent.KEYCODE_MEDIA_PAUSE:
-                case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
-                    /* Suppress PLAY/PAUSE toggle when phone is ringing or
-                     * in-call to avoid music playback */
-                    if (mTelephonyManager == null) {
-                        mTelephonyManager = (TelephonyManager) getContext().getSystemService(
-                                Context.TELEPHONY_SERVICE);
-                    }
-                    if (mTelephonyManager != null &&
-                            mTelephonyManager.getCallState() != TelephonyManager.CALL_STATE_IDLE) {
-                        return true;  // suppress key event
-                    }
-                case KeyEvent.KEYCODE_MUTE:
-                case KeyEvent.KEYCODE_HEADSETHOOK:
-                case KeyEvent.KEYCODE_MEDIA_STOP:
-                case KeyEvent.KEYCODE_MEDIA_NEXT:
-                case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
-                case KeyEvent.KEYCODE_MEDIA_REWIND:
-                case KeyEvent.KEYCODE_MEDIA_RECORD:
-                case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: {
-                    handleMediaKeyEvent(event);
-                    return true;
-                }
-
-                case KeyEvent.KEYCODE_VOLUME_UP:
-                case KeyEvent.KEYCODE_VOLUME_DOWN:
-                case KeyEvent.KEYCODE_VOLUME_MUTE: {
-                    if (KEYGUARD_MANAGES_VOLUME) {
-                        synchronized (this) {
-                            if (mAudioManager == null) {
-                                mAudioManager = (AudioManager) getContext().getSystemService(
-                                        Context.AUDIO_SERVICE);
-                            }
-                        }
-                        // Volume buttons should only function for music (local or remote).
-                        // TODO: Actually handle MUTE.
-                        mAudioManager.adjustLocalOrRemoteStreamVolume(
-                                AudioManager.STREAM_MUSIC,
-                                keyCode == KeyEvent.KEYCODE_VOLUME_UP
-                                        ? AudioManager.ADJUST_RAISE
-                                        : AudioManager.ADJUST_LOWER);
-                        // Don't execute default volume behavior
-                        return true;
-                    } else {
-                        return false;
-                    }
-                }
-            }
-        } else if (event.getAction() == KeyEvent.ACTION_UP) {
-            switch (keyCode) {
-                case KeyEvent.KEYCODE_MUTE:
-                case KeyEvent.KEYCODE_HEADSETHOOK:
-                case KeyEvent.KEYCODE_MEDIA_PLAY:
-                case KeyEvent.KEYCODE_MEDIA_PAUSE:
-                case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
-                case KeyEvent.KEYCODE_MEDIA_STOP:
-                case KeyEvent.KEYCODE_MEDIA_NEXT:
-                case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
-                case KeyEvent.KEYCODE_MEDIA_REWIND:
-                case KeyEvent.KEYCODE_MEDIA_RECORD:
-                case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: {
-                    handleMediaKeyEvent(event);
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    void handleMediaKeyEvent(KeyEvent keyEvent) {
-        IAudioService audioService = IAudioService.Stub.asInterface(
-                ServiceManager.checkService(Context.AUDIO_SERVICE));
-        if (audioService != null) {
-            try {
-                audioService.dispatchMediaKeyEvent(keyEvent);
-            } catch (RemoteException e) {
-                Log.e("KeyguardViewBase", "dispatchMediaKeyEvent threw exception " + e);
-            }
-        } else {
-            Slog.w("KeyguardViewBase", "Unable to find IAudioService for media key event");
-        }
-    }
-
-    @Override
-    public void dispatchSystemUiVisibilityChanged(int visibility) {
-        super.dispatchSystemUiVisibilityChanged(visibility);
-
-        if (!(mContext instanceof Activity)) {
-            setSystemUiVisibility(STATUS_BAR_DISABLE_BACK);
-        }
-    }
-
-    public void setViewMediatorCallback(
-            KeyguardViewMediator.ViewMediatorCallback viewMediatorCallback) {
-        mViewMediatorCallback = viewMediatorCallback;
-    }
-
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java
deleted file mode 100644
index 30c95fb..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.policy.impl.keyguard;
-
-import android.app.Activity;
-import android.app.ActivityManager;
-import android.appwidget.AppWidgetManager;
-import android.content.Context;
-import android.content.pm.ActivityInfo;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.graphics.PixelFormat;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.Parcelable;
-import android.os.SystemProperties;
-import android.util.Log;
-import android.util.Slog;
-import android.util.SparseArray;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewManager;
-import android.view.WindowManager;
-import android.widget.FrameLayout;
-
-import com.android.internal.R;
-import com.android.internal.widget.LockPatternUtils;
-
-/**
- * Manages creating, showing, hiding and resetting the keyguard.  Calls back
- * via {@link KeyguardViewMediator.ViewMediatorCallback} to poke
- * the wake lock and report that the keyguard is done, which is in turn,
- * reported to this class by the current {@link KeyguardViewBase}.
- */
-public class KeyguardViewManager {
-    private final static boolean DEBUG = KeyguardViewMediator.DEBUG;
-    private static String TAG = "KeyguardViewManager";
-    public static boolean USE_UPPER_CASE = true;
-    public final static String IS_SWITCHING_USER = "is_switching_user";
-
-    // Timeout used for keypresses
-    static final int DIGIT_PRESS_WAKE_MILLIS = 5000;
-
-    private final Context mContext;
-    private final ViewManager mViewManager;
-    private final KeyguardViewMediator.ViewMediatorCallback mViewMediatorCallback;
-
-    private WindowManager.LayoutParams mWindowLayoutParams;
-    private boolean mNeedsInput = false;
-
-    private FrameLayout mKeyguardHost;
-    private KeyguardHostView mKeyguardView;
-
-    private boolean mScreenOn = false;
-    private LockPatternUtils mLockPatternUtils;
-
-    public interface ShowListener {
-        void onShown(IBinder windowToken);
-    };
-
-    /**
-     * @param context Used to create views.
-     * @param viewManager Keyguard will be attached to this.
-     * @param callback Used to notify of changes.
-     * @param lockPatternUtils
-     */
-    public KeyguardViewManager(Context context, ViewManager viewManager,
-            KeyguardViewMediator.ViewMediatorCallback callback,
-            LockPatternUtils lockPatternUtils) {
-        mContext = context;
-        mViewManager = viewManager;
-        mViewMediatorCallback = callback;
-        mLockPatternUtils = lockPatternUtils;
-    }
-
-    /**
-     * Show the keyguard.  Will handle creating and attaching to the view manager
-     * lazily.
-     */
-    public synchronized void show(Bundle options) {
-        if (DEBUG) Log.d(TAG, "show(); mKeyguardView==" + mKeyguardView);
-
-        boolean enableScreenRotation = shouldEnableScreenRotation();
-
-        maybeCreateKeyguardLocked(enableScreenRotation, false, options);
-        maybeEnableScreenRotation(enableScreenRotation);
-
-        // Disable common aspects of the system/status/navigation bars that are not appropriate or
-        // useful on any keyguard screen but can be re-shown by dialogs or SHOW_WHEN_LOCKED
-        // activities. Other disabled bits are handled by the KeyguardViewMediator talking
-        // directly to the status bar service.
-        final int visFlags = View.STATUS_BAR_DISABLE_HOME;
-        if (DEBUG) Log.v(TAG, "show:setSystemUiVisibility(" + Integer.toHexString(visFlags)+")");
-        mKeyguardHost.setSystemUiVisibility(visFlags);
-
-        mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
-        mKeyguardHost.setVisibility(View.VISIBLE);
-        mKeyguardView.show();
-        mKeyguardView.requestFocus();
-    }
-
-    private boolean shouldEnableScreenRotation() {
-        Resources res = mContext.getResources();
-        return SystemProperties.getBoolean("lockscreen.rot_override",false)
-                || res.getBoolean(com.android.internal.R.bool.config_enableLockScreenRotation);
-    }
-
-    class ViewManagerHost extends FrameLayout {
-        public ViewManagerHost(Context context) {
-            super(context);
-            setFitsSystemWindows(true);
-        }
-
-        @Override
-        protected boolean fitSystemWindows(Rect insets) {
-            Log.v("TAG", "bug 7643792: fitSystemWindows(" + insets.toShortString() + ")");
-            return super.fitSystemWindows(insets);
-        }
-
-        @Override
-        protected void onConfigurationChanged(Configuration newConfig) {
-            super.onConfigurationChanged(newConfig);
-            if (mKeyguardHost.getVisibility() == View.VISIBLE) {
-                // only propagate configuration messages if we're currently showing
-                maybeCreateKeyguardLocked(shouldEnableScreenRotation(), true, null);
-            } else {
-                if (DEBUG) Log.v(TAG, "onConfigurationChanged: view not visible");
-            }
-        }
-
-        @Override
-        public boolean dispatchKeyEvent(KeyEvent event) {
-            if (mKeyguardView != null) {
-                // Always process back and menu keys, regardless of focus
-                if (event.getAction() == KeyEvent.ACTION_DOWN) {
-                    int keyCode = event.getKeyCode();
-                    if (keyCode == KeyEvent.KEYCODE_BACK && mKeyguardView.handleBackKey()) {
-                        return true;
-                    } else if (keyCode == KeyEvent.KEYCODE_MENU && mKeyguardView.handleMenuKey()) {
-                        return true;
-                    }
-                }
-                // Always process media keys, regardless of focus
-                if (mKeyguardView.dispatchKeyEvent(event)) {
-                    return true;
-                }
-            }
-            return super.dispatchKeyEvent(event);
-        }
-    }
-
-    SparseArray<Parcelable> mStateContainer = new SparseArray<Parcelable>();
-
-    private void maybeCreateKeyguardLocked(boolean enableScreenRotation, boolean force,
-            Bundle options) {
-        final boolean isActivity = (mContext instanceof Activity); // for test activity
-
-        if (mKeyguardHost != null) {
-            mKeyguardHost.saveHierarchyState(mStateContainer);
-        }
-
-        if (mKeyguardHost == null) {
-            if (DEBUG) Log.d(TAG, "keyguard host is null, creating it...");
-
-            mKeyguardHost = new ViewManagerHost(mContext);
-
-            int flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-                    | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
-                    | WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN
-                    | WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
-
-            if (!mNeedsInput) {
-                flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
-            }
-            if (ActivityManager.isHighEndGfx()) {
-                flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
-            }
-
-            final int stretch = ViewGroup.LayoutParams.MATCH_PARENT;
-            final int type = isActivity ? WindowManager.LayoutParams.TYPE_APPLICATION
-                    : WindowManager.LayoutParams.TYPE_KEYGUARD;
-            WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
-                    stretch, stretch, type, flags, PixelFormat.TRANSLUCENT);
-            lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
-            lp.windowAnimations = com.android.internal.R.style.Animation_LockScreen;
-            lp.screenOrientation = enableScreenRotation ?
-                    ActivityInfo.SCREEN_ORIENTATION_USER : ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
-
-            if (ActivityManager.isHighEndGfx()) {
-                lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
-                lp.privateFlags |=
-                        WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED;
-            }
-            lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SET_NEEDS_MENU_KEY;
-            if (isActivity) {
-                lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
-            }
-            lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY;
-            lp.setTitle(isActivity ? "KeyguardMock" : "Keyguard");
-            mWindowLayoutParams = lp;
-            mViewManager.addView(mKeyguardHost, lp);
-        }
-
-        if (force || mKeyguardView == null) {
-            inflateKeyguardView(options);
-            mKeyguardView.requestFocus();
-        }
-        updateUserActivityTimeoutInWindowLayoutParams();
-        mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
-
-        mKeyguardHost.restoreHierarchyState(mStateContainer);
-    }
-
-    private void inflateKeyguardView(Bundle options) {
-        View v = mKeyguardHost.findViewById(R.id.keyguard_host_view);
-        if (v != null) {
-            mKeyguardHost.removeView(v);
-        }
-        // TODO: Remove once b/7094175 is fixed
-        if (false) Slog.d(TAG, "inflateKeyguardView: b/7094175 mContext.config="
-                + mContext.getResources().getConfiguration());
-        final LayoutInflater inflater = LayoutInflater.from(mContext);
-        View view = inflater.inflate(R.layout.keyguard_host_view, mKeyguardHost, true);
-        mKeyguardView = (KeyguardHostView) view.findViewById(R.id.keyguard_host_view);
-        mKeyguardView.setLockPatternUtils(mLockPatternUtils);
-        mKeyguardView.setViewMediatorCallback(mViewMediatorCallback);
-        mKeyguardView.initializeSwitchingUserState(options != null &&
-                options.getBoolean(IS_SWITCHING_USER));
-
-        // HACK
-        // The keyguard view will have set up window flags in onFinishInflate before we set
-        // the view mediator callback. Make sure it knows the correct IME state.
-        if (mViewMediatorCallback != null) {
-            KeyguardPasswordView kpv = (KeyguardPasswordView) mKeyguardView.findViewById(
-                    R.id.keyguard_password_view);
-
-            if (kpv != null) {
-                mViewMediatorCallback.setNeedsInput(kpv.needsInput());
-            }
-        }
-
-        if (options != null) {
-            int widgetToShow = options.getInt(LockPatternUtils.KEYGUARD_SHOW_APPWIDGET,
-                    AppWidgetManager.INVALID_APPWIDGET_ID);
-            if (widgetToShow != AppWidgetManager.INVALID_APPWIDGET_ID) {
-                mKeyguardView.goToWidget(widgetToShow);
-            }
-        }
-    }
-
-    public void updateUserActivityTimeout() {
-        updateUserActivityTimeoutInWindowLayoutParams();
-        mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
-    }
-
-    private void updateUserActivityTimeoutInWindowLayoutParams() {
-        // Use the user activity timeout requested by the keyguard view, if any.
-        if (mKeyguardView != null) {
-            long timeout = mKeyguardView.getUserActivityTimeout();
-            if (timeout >= 0) {
-                mWindowLayoutParams.userActivityTimeout = timeout;
-                return;
-            }
-        }
-
-        // Otherwise, use the default timeout.
-        mWindowLayoutParams.userActivityTimeout = KeyguardViewMediator.AWAKE_INTERVAL_DEFAULT_MS;
-    }
-
-    private void maybeEnableScreenRotation(boolean enableScreenRotation) {
-        // TODO: move this outside
-        if (enableScreenRotation) {
-            if (DEBUG) Log.d(TAG, "Rotation sensor for lock screen On!");
-            mWindowLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_USER;
-        } else {
-            if (DEBUG) Log.d(TAG, "Rotation sensor for lock screen Off!");
-            mWindowLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
-        }
-        mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
-    }
-
-    public void setNeedsInput(boolean needsInput) {
-        mNeedsInput = needsInput;
-        if (mWindowLayoutParams != null) {
-            if (needsInput) {
-                mWindowLayoutParams.flags &=
-                    ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
-            } else {
-                mWindowLayoutParams.flags |=
-                    WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
-            }
-
-            try {
-                mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
-            } catch (java.lang.IllegalArgumentException e) {
-                // TODO: Ensure this method isn't called on views that are changing...
-                Log.w(TAG,"Can't update input method on " + mKeyguardHost + " window not attached");
-            }
-        }
-    }
-
-    /**
-     * Reset the state of the view.
-     */
-    public synchronized void reset(Bundle options) {
-        if (DEBUG) Log.d(TAG, "reset()");
-        // User might have switched, check if we need to go back to keyguard
-        // TODO: It's preferable to stay and show the correct lockscreen or unlock if none
-        maybeCreateKeyguardLocked(shouldEnableScreenRotation(), true, options);
-    }
-
-    public synchronized void onScreenTurnedOff() {
-        if (DEBUG) Log.d(TAG, "onScreenTurnedOff()");
-        mScreenOn = false;
-        if (mKeyguardView != null) {
-            mKeyguardView.onScreenTurnedOff();
-        }
-    }
-
-    public synchronized void onScreenTurnedOn(
-            final KeyguardViewManager.ShowListener showListener) {
-        if (DEBUG) Log.d(TAG, "onScreenTurnedOn()");
-        mScreenOn = true;
-        if (mKeyguardView != null) {
-            mKeyguardView.onScreenTurnedOn();
-
-            // Caller should wait for this window to be shown before turning
-            // on the screen.
-            if (showListener != null) {
-                if (mKeyguardHost.getVisibility() == View.VISIBLE) {
-                    // Keyguard may be in the process of being shown, but not yet
-                    // updated with the window manager...  give it a chance to do so.
-                    mKeyguardHost.post(new Runnable() {
-                        @Override
-                        public void run() {
-                            if (mKeyguardHost.getVisibility() == View.VISIBLE) {
-                                showListener.onShown(mKeyguardHost.getWindowToken());
-                            } else {
-                                showListener.onShown(null);
-                            }
-                        }
-                    });
-                } else {
-                    showListener.onShown(null);
-                }
-            }
-        } else if (showListener != null) {
-            showListener.onShown(null);
-        }
-    }
-
-    public synchronized void verifyUnlock() {
-        if (DEBUG) Log.d(TAG, "verifyUnlock()");
-        show(null);
-        mKeyguardView.verifyUnlock();
-    }
-
-    /**
-     * A key has woken the device.  We use this to potentially adjust the state
-     * of the lock screen based on the key.
-     *
-     * The 'Tq' suffix is per the documentation in {@link android.view.WindowManagerPolicy}.
-     * Be sure not to take any action that takes a long time; any significant
-     * action should be posted to a handler.
-     *
-     * @param keyCode The wake key.  May be {@link KeyEvent#KEYCODE_UNKNOWN} if waking
-     * for a reason other than a key press.
-     */
-    public boolean wakeWhenReadyTq(int keyCode) {
-        if (DEBUG) Log.d(TAG, "wakeWhenReady(" + keyCode + ")");
-        if (mKeyguardView != null) {
-            mKeyguardView.wakeWhenReadyTq(keyCode);
-            return true;
-        }
-        Log.w(TAG, "mKeyguardView is null in wakeWhenReadyTq");
-        return false;
-    }
-
-    /**
-     * Hides the keyguard view
-     */
-    public synchronized void hide() {
-        if (DEBUG) Log.d(TAG, "hide()");
-
-        if (mKeyguardHost != null) {
-            mKeyguardHost.setVisibility(View.GONE);
-
-            // We really only want to preserve keyguard state for configuration changes. Hence
-            // we should clear state of widgets (e.g. Music) when we hide keyguard so it can
-            // start with a fresh state when we return.
-            mStateContainer.clear();
-
-            // Don't do this right away, so we can let the view continue to animate
-            // as it goes away.
-            if (mKeyguardView != null) {
-                final KeyguardViewBase lastView = mKeyguardView;
-                mKeyguardView = null;
-                mKeyguardHost.postDelayed(new Runnable() {
-                    @Override
-                    public void run() {
-                        synchronized (KeyguardViewManager.this) {
-                            lastView.cleanUp();
-                            mKeyguardHost.removeView(lastView);
-                        }
-                    }
-                }, 500);
-            }
-        }
-    }
-
-    /**
-     * Dismisses the keyguard by going to the next screen or making it gone.
-     */
-    public synchronized void dismiss() {
-        if (mScreenOn) {
-            mKeyguardView.dismiss();
-        }
-    }
-
-    /**
-     * @return Whether the keyguard is showing
-     */
-    public synchronized boolean isShowing() {
-        return (mKeyguardHost != null && mKeyguardHost.getVisibility() == View.VISIBLE);
-    }
-
-    public void showAssistant() {
-        if (mKeyguardView != null) {
-            mKeyguardView.showAssistant();
-        }
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
deleted file mode 100644
index 885cb45..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
+++ /dev/null
@@ -1,1449 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.policy.impl.keyguard;
-
-import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
-
-import android.app.Activity;
-import android.app.ActivityManagerNative;
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.app.SearchManager;
-import android.app.StatusBarManager;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.media.AudioManager;
-import android.media.SoundPool;
-import android.os.Bundle;
-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.Settings;
-import android.telephony.TelephonyManager;
-import android.util.EventLog;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.WindowManager;
-import android.view.WindowManagerPolicy;
-
-import com.android.internal.telephony.IccCardConstants;
-import com.android.internal.widget.LockPatternUtils;
-
-
-/**
- * Mediates requests related to the keyguard.  This includes queries about the
- * state of the keyguard, power management events that effect whether the keyguard
- * should be shown or reset, callbacks to the phone window manager to notify
- * it of when the keyguard is showing, and events from the keyguard view itself
- * stating that the keyguard was succesfully unlocked.
- *
- * Note that the keyguard view is shown when the screen is off (as appropriate)
- * so that once the screen comes on, it will be ready immediately.
- *
- * Example queries about the keyguard:
- * - is {movement, key} one that should wake the keygaurd?
- * - is the keyguard showing?
- * - are input events restricted due to the state of the keyguard?
- *
- * Callbacks to the phone window manager:
- * - the keyguard is showing
- *
- * Example external events that translate to keyguard view changes:
- * - screen turned off -> reset the keyguard, and show it so it will be ready
- *   next time the screen turns on
- * - keyboard is slid open -> if the keyguard is not secure, hide it
- *
- * Events from the keyguard view:
- * - user succesfully unlocked keyguard -> hide keyguard view, and no longer
- *   restrict input events.
- *
- * Note: in addition to normal power managment events that effect the state of
- * whether the keyguard should be showing, external apps and services may request
- * that the keyguard be disabled via {@link #setKeyguardEnabled(boolean)}.  When
- * false, this will override all other conditions for turning on the keyguard.
- *
- * Threading and synchronization:
- * This class is created by the initialization routine of the {@link WindowManagerPolicy},
- * and runs on its thread.  The keyguard UI is created from that thread in the
- * constructor of this class.  The apis may be called from other threads, including the
- * {@link com.android.server.input.InputManagerService}'s and {@link android.view.WindowManager}'s.
- * Therefore, methods on this class are synchronized, and any action that is pointed
- * directly to the keyguard UI is posted to a {@link Handler} to ensure it is taken on the UI
- * thread of the keyguard.
- */
-public class KeyguardViewMediator {
-    private static final int KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT = 30000;
-    final static boolean DEBUG = false;
-    private final static boolean DBG_WAKE = false;
-
-    private final static String TAG = "KeyguardViewMediator";
-
-    private static final String DELAYED_KEYGUARD_ACTION =
-        "com.android.internal.policy.impl.PhoneWindowManager.DELAYED_KEYGUARD";
-
-    // used for handler messages
-    private static final int SHOW = 2;
-    private static final int HIDE = 3;
-    private static final int RESET = 4;
-    private static final int VERIFY_UNLOCK = 5;
-    private static final int NOTIFY_SCREEN_OFF = 6;
-    private static final int NOTIFY_SCREEN_ON = 7;
-    private static final int WAKE_WHEN_READY = 8;
-    private static final int KEYGUARD_DONE = 9;
-    private static final int KEYGUARD_DONE_DRAWING = 10;
-    private static final int KEYGUARD_DONE_AUTHENTICATING = 11;
-    private static final int SET_HIDDEN = 12;
-    private static final int KEYGUARD_TIMEOUT = 13;
-    private static final int SHOW_ASSISTANT = 14;
-
-    /**
-     * The default amount of time we stay awake (used for all key input)
-     */
-    protected static final int AWAKE_INTERVAL_DEFAULT_MS = 10000;
-
-    /**
-     * How long to wait after the screen turns off due to timeout before
-     * turning on the keyguard (i.e, the user has this much time to turn
-     * the screen back on without having to face the keyguard).
-     */
-    private static final int KEYGUARD_LOCK_AFTER_DELAY_DEFAULT = 5000;
-
-    /**
-     * How long we'll wait for the {@link ViewMediatorCallback#keyguardDoneDrawing()}
-     * callback before unblocking a call to {@link #setKeyguardEnabled(boolean)}
-     * that is reenabling the keyguard.
-     */
-    private static final int KEYGUARD_DONE_DRAWING_TIMEOUT_MS = 2000;
-
-    /**
-     * Allow the user to expand the status bar when the keyguard is engaged
-     * (without a pattern or password).
-     */
-    private static final boolean ENABLE_INSECURE_STATUS_BAR_EXPAND = true;
-
-    /** The stream type that the lock sounds are tied to. */
-    private int mMasterStreamType;
-
-    private Context mContext;
-    private AlarmManager mAlarmManager;
-    private AudioManager mAudioManager;
-    private StatusBarManager mStatusBarManager;
-    private boolean mShowLockIcon;
-    private boolean mShowingLockIcon;
-    private boolean mSwitchingUser;
-
-    private boolean mSystemReady;
-
-    // Whether the next call to playSounds() should be skipped.  Defaults to
-    // true because the first lock (on boot) should be silent.
-    private boolean mSuppressNextLockSound = true;
-
-
-    /** High level access to the power manager for WakeLocks */
-    private PowerManager mPM;
-
-    /** UserManager for querying number of users */
-    private UserManager mUserManager;
-
-    /** SearchManager for determining whether or not search assistant is available */
-    private SearchManager mSearchManager;
-
-    /**
-     * Used to keep the device awake while to ensure the keyguard finishes opening before
-     * we sleep.
-     */
-    private PowerManager.WakeLock mShowKeyguardWakeLock;
-
-    /**
-     * Does not turn on screen, held while a call to {@link KeyguardViewManager#wakeWhenReadyTq(int)}
-     * is called to make sure the device doesn't sleep before it has a chance to poke
-     * the wake lock.
-     * @see #wakeWhenReady(int)
-     */
-    private PowerManager.WakeLock mWakeAndHandOff;
-
-    private KeyguardViewManager mKeyguardViewManager;
-
-    // these are protected by synchronized (this)
-
-    /**
-     * External apps (like the phone app) can tell us to disable the keygaurd.
-     */
-    private boolean mExternallyEnabled = true;
-
-    /**
-     * Remember if an external call to {@link #setKeyguardEnabled} with value
-     * false caused us to hide the keyguard, so that we need to reshow it once
-     * the keygaurd is reenabled with another call with value true.
-     */
-    private boolean mNeedToReshowWhenReenabled = false;
-
-    // cached value of whether we are showing (need to know this to quickly
-    // answer whether the input should be restricted)
-    private boolean mShowing = false;
-
-    // true if the keyguard is hidden by another window
-    private boolean mHidden = false;
-
-    /**
-     * Helps remember whether the screen has turned on since the last time
-     * it turned off due to timeout. see {@link #onScreenTurnedOff(int)}
-     */
-    private int mDelayedShowingSequence;
-
-    /**
-     * If the user has disabled the keyguard, then requests to exit, this is
-     * how we'll ultimately let them know whether it was successful.  We use this
-     * var being non-null as an indicator that there is an in progress request.
-     */
-    private WindowManagerPolicy.OnKeyguardExitResult mExitSecureCallback;
-
-    // the properties of the keyguard
-
-    private KeyguardUpdateMonitor mUpdateMonitor;
-
-    private boolean mScreenOn;
-
-    // last known state of the cellular connection
-    private String mPhoneState = TelephonyManager.EXTRA_STATE_IDLE;
-
-    /**
-     * we send this intent when the keyguard is dismissed.
-     */
-    private Intent mUserPresentIntent;
-
-    /**
-     * {@link #setKeyguardEnabled} waits on this condition when it reenables
-     * the keyguard.
-     */
-    private boolean mWaitingUntilKeyguardVisible = false;
-    private LockPatternUtils mLockPatternUtils;
-    private boolean mKeyguardDonePending = false;
-
-    private SoundPool mLockSounds;
-    private int mLockSoundId;
-    private int mUnlockSoundId;
-    private int mLockSoundStreamId;
-
-    /**
-     * The volume applied to the lock/unlock sounds.
-     */
-    private final float mLockSoundVolume;
-
-    /**
-     * Cache of avatar drawables, for use by KeyguardMultiUserAvatar.
-     */
-    private static MultiUserAvatarCache sMultiUserAvatarCache = new MultiUserAvatarCache();
-
-    /**
-     * The callback used by the keyguard view to tell the {@link KeyguardViewMediator}
-     * various things.
-     */
-    public interface ViewMediatorCallback {
-
-        /**
-         * Wake the device immediately.
-         */
-        void wakeUp();
-
-        /**
-         * Reports user activity and requests that the screen stay on.
-         */
-        void userActivity();
-
-        /**
-         * Reports user activity and requests that the screen stay on for at least
-         * the specified amount of time.
-         * @param millis The amount of time in millis.  This value is currently ignored.
-         */
-        void userActivity(long millis);
-
-        /**
-         * Report that the keyguard is done.
-         * @param authenticated Whether the user securely got past the keyguard.
-         *   the only reason for this to be false is if the keyguard was instructed
-         *   to appear temporarily to verify the user is supposed to get past the
-         *   keyguard, and the user fails to do so.
-         */
-        void keyguardDone(boolean authenticated);
-
-        /**
-         * Report that the keyguard is done drawing.
-         */
-        void keyguardDoneDrawing();
-
-        /**
-         * Tell ViewMediator that the current view needs IME input
-         * @param needsInput
-         */
-        void setNeedsInput(boolean needsInput);
-
-        /**
-         * Tell view mediator that the keyguard view's desired user activity timeout
-         * has changed and needs to be reapplied to the window.
-         */
-        void onUserActivityTimeoutChanged();
-
-        /**
-         * Report that the keyguard is dismissable, pending the next keyguardDone call.
-         */
-        void keyguardDonePending();
-    }
-
-    KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() {
-
-        @Override
-        public void onUserSwitching(int userId) {
-            // Note that the mLockPatternUtils user has already been updated from setCurrentUser.
-            // We need to force a reset of the views, since lockNow (called by
-            // ActivityManagerService) will not reconstruct the keyguard if it is already showing.
-            synchronized (KeyguardViewMediator.this) {
-                mSwitchingUser = true;
-                resetStateLocked(null);
-                adjustStatusBarLocked();
-                // When we switch users we want to bring the new user to the biometric unlock even
-                // if the current user has gone to the backup.
-                KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true);
-            }
-        }
-
-        @Override
-        public void onUserSwitchComplete(int userId) {
-            mSwitchingUser = false;
-        }
-
-        @Override
-        public void onUserRemoved(int userId) {
-            mLockPatternUtils.removeUser(userId);
-            sMultiUserAvatarCache.clear(userId);
-        }
-
-        @Override
-        public void onUserInfoChanged(int userId) {
-            sMultiUserAvatarCache.clear(userId);
-        }
-
-        @Override
-        void onPhoneStateChanged(int phoneState) {
-            synchronized (KeyguardViewMediator.this) {
-                if (TelephonyManager.CALL_STATE_IDLE == phoneState  // call ending
-                        && !mScreenOn                           // screen off
-                        && mExternallyEnabled) {                // not disabled by any app
-
-                    // note: this is a way to gracefully reenable the keyguard when the call
-                    // ends and the screen is off without always reenabling the keyguard
-                    // each time the screen turns off while in call (and having an occasional ugly
-                    // flicker while turning back on the screen and disabling the keyguard again).
-                    if (DEBUG) Log.d(TAG, "screen is off and call ended, let's make sure the "
-                            + "keyguard is showing");
-                    doKeyguardLocked();
-                }
-            }
-        };
-
-        @Override
-        public void onClockVisibilityChanged() {
-            adjustStatusBarLocked();
-        }
-
-        @Override
-        public void onDeviceProvisioned() {
-            sendUserPresentBroadcast();
-        }
-
-        @Override
-        public void onSimStateChanged(IccCardConstants.State simState) {
-            if (DEBUG) Log.d(TAG, "onSimStateChanged: " + simState);
-
-            switch (simState) {
-                case NOT_READY:
-                case ABSENT:
-                    // only force lock screen in case of missing sim if user hasn't
-                    // gone through setup wizard
-                    synchronized (this) {
-                        if (!mUpdateMonitor.isDeviceProvisioned()) {
-                            if (!isShowing()) {
-                                if (DEBUG) Log.d(TAG, "ICC_ABSENT isn't showing,"
-                                        + " we need to show the keyguard since the "
-                                        + "device isn't provisioned yet.");
-                                doKeyguardLocked();
-                            } else {
-                                resetStateLocked(null);
-                            }
-                        }
-                    }
-                    break;
-                case PIN_REQUIRED:
-                case PUK_REQUIRED:
-                    synchronized (this) {
-                        if (!isShowing()) {
-                            if (DEBUG) Log.d(TAG, "INTENT_VALUE_ICC_LOCKED and keygaurd isn't "
-                                    + "showing; need to show keyguard so user can enter sim pin");
-                            doKeyguardLocked();
-                        } else {
-                            resetStateLocked(null);
-                        }
-                    }
-                    break;
-                case PERM_DISABLED:
-                    synchronized (this) {
-                        if (!isShowing()) {
-                            if (DEBUG) Log.d(TAG, "PERM_DISABLED and "
-                                  + "keygaurd isn't showing.");
-                            doKeyguardLocked();
-                        } else {
-                            if (DEBUG) Log.d(TAG, "PERM_DISABLED, resetStateLocked to"
-                                  + "show permanently disabled message in lockscreen.");
-                            resetStateLocked(null);
-                        }
-                    }
-                    break;
-                case READY:
-                    synchronized (this) {
-                        if (isShowing()) {
-                            resetStateLocked(null);
-                        }
-                    }
-                    break;
-            }
-        }
-
-    };
-
-    ViewMediatorCallback mViewMediatorCallback = new ViewMediatorCallback() {
-        public void wakeUp() {
-            KeyguardViewMediator.this.wakeUp();
-        }
-
-        public void userActivity() {
-            KeyguardViewMediator.this.userActivity();
-        }
-
-        public void userActivity(long holdMs) {
-            KeyguardViewMediator.this.userActivity(holdMs);
-        }
-
-        public void keyguardDone(boolean authenticated) {
-            KeyguardViewMediator.this.keyguardDone(authenticated, true);
-        }
-
-        public void keyguardDoneDrawing() {
-            mHandler.sendEmptyMessage(KEYGUARD_DONE_DRAWING);
-        }
-
-        @Override
-        public void setNeedsInput(boolean needsInput) {
-            mKeyguardViewManager.setNeedsInput(needsInput);
-        }
-
-        @Override
-        public void onUserActivityTimeoutChanged() {
-            mKeyguardViewManager.updateUserActivityTimeout();
-        }
-
-        @Override
-        public void keyguardDonePending() {
-            mKeyguardDonePending = true;
-        }
-    };
-
-    public void wakeUp() {
-        mPM.wakeUp(SystemClock.uptimeMillis());
-    }
-
-    public void userActivity() {
-        userActivity(AWAKE_INTERVAL_DEFAULT_MS);
-    }
-
-    public void userActivity(long holdMs) {
-        // We ignore the hold time.  Eventually we should remove it.
-        // Instead, the keyguard window has an explicit user activity timeout set on it.
-        mPM.userActivity(SystemClock.uptimeMillis(), false);
-    }
-
-    /**
-     * Construct a KeyguardViewMediator
-     * @param context
-     * @param lockPatternUtils optional mock interface for LockPatternUtils
-     */
-    public KeyguardViewMediator(Context context, LockPatternUtils lockPatternUtils) {
-        mContext = context;
-        mPM = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
-        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
-        mShowKeyguardWakeLock = mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "show keyguard");
-        mShowKeyguardWakeLock.setReferenceCounted(false);
-
-        mWakeAndHandOff = mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "keyguardWakeAndHandOff");
-        mWakeAndHandOff.setReferenceCounted(false);
-
-        mContext.registerReceiver(mBroadcastReceiver, new IntentFilter(DELAYED_KEYGUARD_ACTION));
-
-        mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
-
-        mUpdateMonitor = KeyguardUpdateMonitor.getInstance(context);
-
-        mLockPatternUtils = lockPatternUtils != null
-                ? lockPatternUtils : new LockPatternUtils(mContext);
-        mLockPatternUtils.setCurrentUser(UserHandle.USER_OWNER);
-
-        WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
-
-        mKeyguardViewManager = new KeyguardViewManager(context, wm, mViewMediatorCallback,
-                mLockPatternUtils);
-
-        mUserPresentIntent = new Intent(Intent.ACTION_USER_PRESENT);
-        mUserPresentIntent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
-                | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-
-        final ContentResolver cr = mContext.getContentResolver();
-        mShowLockIcon = (Settings.System.getInt(cr, "show_status_bar_lock", 0) == 1);
-
-        mScreenOn = mPM.isScreenOn();
-
-        mLockSounds = new SoundPool(1, AudioManager.STREAM_SYSTEM, 0);
-        String soundPath = Settings.Global.getString(cr, Settings.Global.LOCK_SOUND);
-        if (soundPath != null) {
-            mLockSoundId = mLockSounds.load(soundPath, 1);
-        }
-        if (soundPath == null || mLockSoundId == 0) {
-            Log.w(TAG, "failed to load lock sound from " + soundPath);
-        }
-        soundPath = Settings.Global.getString(cr, Settings.Global.UNLOCK_SOUND);
-        if (soundPath != null) {
-            mUnlockSoundId = mLockSounds.load(soundPath, 1);
-        }
-        if (soundPath == null || mUnlockSoundId == 0) {
-            Log.w(TAG, "failed to load unlock sound from " + soundPath);
-        }
-        int lockSoundDefaultAttenuation = context.getResources().getInteger(
-                com.android.internal.R.integer.config_lockSoundVolumeDb);
-        mLockSoundVolume = (float)Math.pow(10, (float)lockSoundDefaultAttenuation/20);
-    }
-
-    /**
-     * Let us know that the system is ready after startup.
-     */
-    public void onSystemReady() {
-        mSearchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE);
-        synchronized (this) {
-            if (DEBUG) Log.d(TAG, "onSystemReady");
-            mSystemReady = true;
-            mUpdateMonitor.registerCallback(mUpdateCallback);
-
-            // Suppress biometric unlock right after boot until things have settled if it is the
-            // selected security method, otherwise unsuppress it.  It must be unsuppressed if it is
-            // not the selected security method for the following reason:  if the user starts
-            // without a screen lock selected, the biometric unlock would be suppressed the first
-            // time they try to use it.
-            //
-            // Note that the biometric unlock will still not show if it is not the selected method.
-            // Calling setAlternateUnlockEnabled(true) simply says don't suppress it if it is the
-            // selected method.
-            if (mLockPatternUtils.usingBiometricWeak()
-                    && mLockPatternUtils.isBiometricWeakInstalled()) {
-                if (DEBUG) Log.d(TAG, "suppressing biometric unlock during boot");
-                mUpdateMonitor.setAlternateUnlockEnabled(false);
-            } else {
-                mUpdateMonitor.setAlternateUnlockEnabled(true);
-            }
-
-            doKeyguardLocked();
-        }
-        // Most services aren't available until the system reaches the ready state, so we
-        // send it here when the device first boots.
-        maybeSendUserPresentBroadcast();
-    }
-
-    /**
-     * Called to let us know the screen was turned off.
-     * @param why either {@link WindowManagerPolicy#OFF_BECAUSE_OF_USER},
-     *   {@link WindowManagerPolicy#OFF_BECAUSE_OF_TIMEOUT} or
-     *   {@link WindowManagerPolicy#OFF_BECAUSE_OF_PROX_SENSOR}.
-     */
-    public void onScreenTurnedOff(int why) {
-        synchronized (this) {
-            mScreenOn = false;
-            if (DEBUG) Log.d(TAG, "onScreenTurnedOff(" + why + ")");
-
-            mKeyguardDonePending = false;
-
-            // Lock immediately based on setting if secure (user has a pin/pattern/password).
-            // This also "locks" the device when not secure to provide easy access to the
-            // camera while preventing unwanted input.
-            final boolean lockImmediately =
-                mLockPatternUtils.getPowerButtonInstantlyLocks() || !mLockPatternUtils.isSecure();
-
-            if (mExitSecureCallback != null) {
-                if (DEBUG) Log.d(TAG, "pending exit secure callback cancelled");
-                mExitSecureCallback.onKeyguardExitResult(false);
-                mExitSecureCallback = null;
-                if (!mExternallyEnabled) {
-                    hideLocked();
-                }
-            } else if (mShowing) {
-                notifyScreenOffLocked();
-                resetStateLocked(null);
-            } else if (why == WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT
-                   || (why == WindowManagerPolicy.OFF_BECAUSE_OF_USER && !lockImmediately)) {
-                doKeyguardLaterLocked();
-            } else if (why == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR) {
-                // Do not enable the keyguard if the prox sensor forced the screen off.
-            } else {
-                doKeyguardLocked();
-            }
-        }
-    }
-
-    private void doKeyguardLaterLocked() {
-        // if the screen turned off because of timeout or the user hit the power button
-        // and we don't need to lock immediately, set an alarm
-        // to enable it a little bit later (i.e, give the user a chance
-        // to turn the screen back on within a certain window without
-        // having to unlock the screen)
-        final ContentResolver cr = mContext.getContentResolver();
-
-        // From DisplaySettings
-        long displayTimeout = Settings.System.getInt(cr, SCREEN_OFF_TIMEOUT,
-                KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT);
-
-        // From SecuritySettings
-        final long lockAfterTimeout = Settings.Secure.getInt(cr,
-                Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT,
-                KEYGUARD_LOCK_AFTER_DELAY_DEFAULT);
-
-        // From DevicePolicyAdmin
-        final long policyTimeout = mLockPatternUtils.getDevicePolicyManager()
-                .getMaximumTimeToLock(null, mLockPatternUtils.getCurrentUser());
-
-        long timeout;
-        if (policyTimeout > 0) {
-            // policy in effect. Make sure we don't go beyond policy limit.
-            displayTimeout = Math.max(displayTimeout, 0); // ignore negative values
-            timeout = Math.min(policyTimeout - displayTimeout, lockAfterTimeout);
-        } else {
-            timeout = lockAfterTimeout;
-        }
-
-        if (timeout <= 0) {
-            // Lock now
-            mSuppressNextLockSound = true;
-            doKeyguardLocked();
-        } else {
-            // Lock in the future
-            long when = SystemClock.elapsedRealtime() + timeout;
-            Intent intent = new Intent(DELAYED_KEYGUARD_ACTION);
-            intent.putExtra("seq", mDelayedShowingSequence);
-            PendingIntent sender = PendingIntent.getBroadcast(mContext,
-                    0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
-            mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, when, sender);
-            if (DEBUG) Log.d(TAG, "setting alarm to turn off keyguard, seq = "
-                             + mDelayedShowingSequence);
-        }
-    }
-
-    private void cancelDoKeyguardLaterLocked() {
-        mDelayedShowingSequence++;
-    }
-
-    /**
-     * Let's us know the screen was turned on.
-     */
-    public void onScreenTurnedOn(KeyguardViewManager.ShowListener showListener) {
-        synchronized (this) {
-            mScreenOn = true;
-            cancelDoKeyguardLaterLocked();
-            if (DEBUG) Log.d(TAG, "onScreenTurnedOn, seq = " + mDelayedShowingSequence);
-            if (showListener != null) {
-                notifyScreenOnLocked(showListener);
-            }
-        }
-        maybeSendUserPresentBroadcast();
-    }
-
-    private void maybeSendUserPresentBroadcast() {
-        if (mSystemReady && mLockPatternUtils.isLockScreenDisabled()
-                && mUserManager.getUsers(true).size() == 1) {
-            // Lock screen is disabled because the user has set the preference to "None".
-            // In this case, send out ACTION_USER_PRESENT here instead of in
-            // handleKeyguardDone()
-            sendUserPresentBroadcast();
-        }
-    }
-
-    /**
-     * A dream started.  We should lock after the usual screen-off lock timeout but only
-     * if there is a secure lock pattern.
-     */
-    public void onDreamingStarted() {
-        synchronized (this) {
-            if (mScreenOn && mLockPatternUtils.isSecure()) {
-                doKeyguardLaterLocked();
-            }
-        }
-    }
-
-    /**
-     * A dream stopped.
-     */
-    public void onDreamingStopped() {
-        synchronized (this) {
-            if (mScreenOn) {
-                cancelDoKeyguardLaterLocked();
-            }
-        }
-    }
-
-    /**
-     * Same semantics as {@link WindowManagerPolicy#enableKeyguard}; provide
-     * a way for external stuff to override normal keyguard behavior.  For instance
-     * the phone app disables the keyguard when it receives incoming calls.
-     */
-    public void setKeyguardEnabled(boolean enabled) {
-        synchronized (this) {
-            if (DEBUG) Log.d(TAG, "setKeyguardEnabled(" + enabled + ")");
-
-            mExternallyEnabled = enabled;
-
-            if (!enabled && mShowing) {
-                if (mExitSecureCallback != null) {
-                    if (DEBUG) Log.d(TAG, "in process of verifyUnlock request, ignoring");
-                    // we're in the process of handling a request to verify the user
-                    // can get past the keyguard. ignore extraneous requests to disable / reenable
-                    return;
-                }
-
-                // hiding keyguard that is showing, remember to reshow later
-                if (DEBUG) Log.d(TAG, "remembering to reshow, hiding keyguard, "
-                        + "disabling status bar expansion");
-                mNeedToReshowWhenReenabled = true;
-                hideLocked();
-            } else if (enabled && mNeedToReshowWhenReenabled) {
-                // reenabled after previously hidden, reshow
-                if (DEBUG) Log.d(TAG, "previously hidden, reshowing, reenabling "
-                        + "status bar expansion");
-                mNeedToReshowWhenReenabled = false;
-
-                if (mExitSecureCallback != null) {
-                    if (DEBUG) Log.d(TAG, "onKeyguardExitResult(false), resetting");
-                    mExitSecureCallback.onKeyguardExitResult(false);
-                    mExitSecureCallback = null;
-                    resetStateLocked(null);
-                } else {
-                    showLocked(null);
-
-                    // block until we know the keygaurd is done drawing (and post a message
-                    // to unblock us after a timeout so we don't risk blocking too long
-                    // and causing an ANR).
-                    mWaitingUntilKeyguardVisible = true;
-                    mHandler.sendEmptyMessageDelayed(KEYGUARD_DONE_DRAWING, KEYGUARD_DONE_DRAWING_TIMEOUT_MS);
-                    if (DEBUG) Log.d(TAG, "waiting until mWaitingUntilKeyguardVisible is false");
-                    while (mWaitingUntilKeyguardVisible) {
-                        try {
-                            wait();
-                        } catch (InterruptedException e) {
-                            Thread.currentThread().interrupt();
-                        }
-                    }
-                    if (DEBUG) Log.d(TAG, "done waiting for mWaitingUntilKeyguardVisible");
-                }
-            }
-        }
-    }
-
-    /**
-     * @see android.app.KeyguardManager#exitKeyguardSecurely
-     */
-    public void verifyUnlock(WindowManagerPolicy.OnKeyguardExitResult callback) {
-        synchronized (this) {
-            if (DEBUG) Log.d(TAG, "verifyUnlock");
-            if (!mUpdateMonitor.isDeviceProvisioned()) {
-                // don't allow this api when the device isn't provisioned
-                if (DEBUG) Log.d(TAG, "ignoring because device isn't provisioned");
-                callback.onKeyguardExitResult(false);
-            } else if (mExternallyEnabled) {
-                // this only applies when the user has externally disabled the
-                // keyguard.  this is unexpected and means the user is not
-                // using the api properly.
-                Log.w(TAG, "verifyUnlock called when not externally disabled");
-                callback.onKeyguardExitResult(false);
-            } else if (mExitSecureCallback != null) {
-                // already in progress with someone else
-                callback.onKeyguardExitResult(false);
-            } else {
-                mExitSecureCallback = callback;
-                verifyUnlockLocked();
-            }
-        }
-    }
-
-    /**
-     * Is the keyguard currently showing?
-     */
-    public boolean isShowing() {
-        return mShowing;
-    }
-
-    /**
-     * Is the keyguard currently showing and not being force hidden?
-     */
-    public boolean isShowingAndNotHidden() {
-        return mShowing && !mHidden;
-    }
-
-    /**
-     * Notify us when the keyguard is hidden by another window
-     */
-    public void setHidden(boolean isHidden) {
-        if (DEBUG) Log.d(TAG, "setHidden " + isHidden);
-        mUpdateMonitor.sendKeyguardVisibilityChanged(!isHidden);
-        mHandler.removeMessages(SET_HIDDEN);
-        Message msg = mHandler.obtainMessage(SET_HIDDEN, (isHidden ? 1 : 0), 0);
-        mHandler.sendMessage(msg);
-    }
-
-    /**
-     * Handles SET_HIDDEN message sent by setHidden()
-     */
-    private void handleSetHidden(boolean isHidden) {
-        synchronized (KeyguardViewMediator.this) {
-            if (mHidden != isHidden) {
-                mHidden = isHidden;
-                updateActivityLockScreenState();
-                adjustStatusBarLocked();
-            }
-        }
-    }
-
-    /**
-     * Used by PhoneWindowManager to enable the keyguard due to a user activity timeout.
-     * This must be safe to call from any thread and with any window manager locks held.
-     */
-    public void doKeyguardTimeout(Bundle options) {
-        mHandler.removeMessages(KEYGUARD_TIMEOUT);
-        Message msg = mHandler.obtainMessage(KEYGUARD_TIMEOUT, options);
-        mHandler.sendMessage(msg);
-    }
-
-    /**
-     * Given the state of the keyguard, is the input restricted?
-     * Input is restricted when the keyguard is showing, or when the keyguard
-     * was suppressed by an app that disabled the keyguard or we haven't been provisioned yet.
-     */
-    public boolean isInputRestricted() {
-        return mShowing || mNeedToReshowWhenReenabled || !mUpdateMonitor.isDeviceProvisioned();
-    }
-
-    private void doKeyguardLocked() {
-        doKeyguardLocked(null);
-    }
-
-    /**
-     * Enable the keyguard if the settings are appropriate.
-     */
-    private void doKeyguardLocked(Bundle options) {
-        // if another app is disabling us, don't show
-        if (!mExternallyEnabled) {
-            if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled");
-
-            // note: we *should* set mNeedToReshowWhenReenabled=true here, but that makes
-            // for an occasional ugly flicker in this situation:
-            // 1) receive a call with the screen on (no keyguard) or make a call
-            // 2) screen times out
-            // 3) user hits key to turn screen back on
-            // instead, we reenable the keyguard when we know the screen is off and the call
-            // ends (see the broadcast receiver below)
-            // TODO: clean this up when we have better support at the window manager level
-            // for apps that wish to be on top of the keyguard
-            return;
-        }
-
-        // if the keyguard is already showing, don't bother
-        if (mKeyguardViewManager.isShowing()) {
-            if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing");
-            return;
-        }
-
-        // if the setup wizard hasn't run yet, don't show
-        final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim",
-                false);
-        final boolean provisioned = mUpdateMonitor.isDeviceProvisioned();
-        final IccCardConstants.State state = mUpdateMonitor.getSimState();
-        final boolean lockedOrMissing = state.isPinLocked()
-                || ((state == IccCardConstants.State.ABSENT
-                || state == IccCardConstants.State.PERM_DISABLED)
-                && requireSim);
-
-        if (!lockedOrMissing && !provisioned) {
-            if (DEBUG) Log.d(TAG, "doKeyguard: not showing because device isn't provisioned"
-                    + " and the sim is not locked or missing");
-            return;
-        }
-
-        if (mUserManager.getUsers(true).size() < 2
-                && mLockPatternUtils.isLockScreenDisabled() && !lockedOrMissing) {
-            if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off");
-            return;
-        }
-
-        if (DEBUG) Log.d(TAG, "doKeyguard: showing the lock screen");
-        showLocked(options);
-    }
-
-    /**
-     * Dismiss the keyguard through the security layers.
-     */
-    public void dismiss() {
-        if (mShowing && !mHidden) {
-            mKeyguardViewManager.dismiss();
-        }
-    }
-
-    /**
-     * Send message to keyguard telling it to reset its state.
-     * @param options options about how to show the keyguard
-     * @see #handleReset()
-     */
-    private void resetStateLocked(Bundle options) {
-        if (DEBUG) Log.e(TAG, "resetStateLocked");
-        Message msg = mHandler.obtainMessage(RESET, options);
-        mHandler.sendMessage(msg);
-    }
-
-    /**
-     * Send message to keyguard telling it to verify unlock
-     * @see #handleVerifyUnlock()
-     */
-    private void verifyUnlockLocked() {
-        if (DEBUG) Log.d(TAG, "verifyUnlockLocked");
-        mHandler.sendEmptyMessage(VERIFY_UNLOCK);
-    }
-
-
-    /**
-     * Send a message to keyguard telling it the screen just turned on.
-     * @see #onScreenTurnedOff(int)
-     * @see #handleNotifyScreenOff
-     */
-    private void notifyScreenOffLocked() {
-        if (DEBUG) Log.d(TAG, "notifyScreenOffLocked");
-        mHandler.sendEmptyMessage(NOTIFY_SCREEN_OFF);
-    }
-
-    /**
-     * Send a message to keyguard telling it the screen just turned on.
-     * @see #onScreenTurnedOn()
-     * @see #handleNotifyScreenOn
-     */
-    private void notifyScreenOnLocked(KeyguardViewManager.ShowListener showListener) {
-        if (DEBUG) Log.d(TAG, "notifyScreenOnLocked");
-        Message msg = mHandler.obtainMessage(NOTIFY_SCREEN_ON, showListener);
-        mHandler.sendMessage(msg);
-    }
-
-    /**
-     * Send message to keyguard telling it about a wake key so it can adjust
-     * its state accordingly and then poke the wake lock when it is ready.
-     * @param keyCode The wake key.
-     * @see #handleWakeWhenReady
-     * @see #onWakeKeyWhenKeyguardShowingTq(int)
-     */
-    private void wakeWhenReady(int keyCode) {
-        if (DBG_WAKE) Log.d(TAG, "wakeWhenReady(" + keyCode + ")");
-
-        /**
-         * acquire the handoff lock that will keep the cpu running.  this will
-         * be released once the keyguard has set itself up and poked the other wakelock
-         * in {@link #handleWakeWhenReady(int)}
-         */
-        mWakeAndHandOff.acquire();
-
-        Message msg = mHandler.obtainMessage(WAKE_WHEN_READY, keyCode, 0);
-        mHandler.sendMessage(msg);
-    }
-
-    /**
-     * Send message to keyguard telling it to show itself
-     * @see #handleShow()
-     */
-    private void showLocked(Bundle options) {
-        if (DEBUG) Log.d(TAG, "showLocked");
-        // ensure we stay awake until we are finished displaying the keyguard
-        mShowKeyguardWakeLock.acquire();
-        Message msg = mHandler.obtainMessage(SHOW, options);
-        mHandler.sendMessage(msg);
-    }
-
-    /**
-     * Send message to keyguard telling it to hide itself
-     * @see #handleHide()
-     */
-    private void hideLocked() {
-        if (DEBUG) Log.d(TAG, "hideLocked");
-        Message msg = mHandler.obtainMessage(HIDE);
-        mHandler.sendMessage(msg);
-    }
-
-    public boolean isSecure() {
-        return mLockPatternUtils.isSecure()
-            || KeyguardUpdateMonitor.getInstance(mContext).isSimPinSecure();
-    }
-
-    /**
-     * Update the newUserId. Call while holding WindowManagerService lock.
-     * NOTE: Should only be called by KeyguardViewMediator in response to the user id changing.
-     *
-     * @param newUserId The id of the incoming user.
-     */
-    public void setCurrentUser(int newUserId) {
-        mLockPatternUtils.setCurrentUser(newUserId);
-    }
-
-    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (DELAYED_KEYGUARD_ACTION.equals(intent.getAction())) {
-                final int sequence = intent.getIntExtra("seq", 0);
-                if (DEBUG) Log.d(TAG, "received DELAYED_KEYGUARD_ACTION with seq = "
-                        + sequence + ", mDelayedShowingSequence = " + mDelayedShowingSequence);
-                synchronized (KeyguardViewMediator.this) {
-                    if (mDelayedShowingSequence == sequence) {
-                        // Don't play lockscreen SFX if the screen went off due to timeout.
-                        mSuppressNextLockSound = true;
-                        doKeyguardLocked();
-                    }
-                }
-            }
-        }
-    };
-
-    /**
-     * When a key is received when the screen is off and the keyguard is showing,
-     * we need to decide whether to actually turn on the screen, and if so, tell
-     * the keyguard to prepare itself and poke the wake lock when it is ready.
-     *
-     * The 'Tq' suffix is per the documentation in {@link WindowManagerPolicy}.
-     * Be sure not to take any action that takes a long time; any significant
-     * action should be posted to a handler.
-     *
-     * @param keyCode The keycode of the key that woke the device
-     */
-    public void onWakeKeyWhenKeyguardShowingTq(int keyCode) {
-        if (DEBUG) Log.d(TAG, "onWakeKeyWhenKeyguardShowing(" + keyCode + ")");
-
-        // give the keyguard view manager a chance to adjust the state of the
-        // keyguard based on the key that woke the device before poking
-        // the wake lock
-        wakeWhenReady(keyCode);
-    }
-
-    /**
-     * When a wake motion such as an external mouse movement is received when the screen
-     * is off and the keyguard is showing, we need to decide whether to actually turn
-     * on the screen, and if so, tell the keyguard to prepare itself and poke the wake
-     * lock when it is ready.
-     *
-     * The 'Tq' suffix is per the documentation in {@link WindowManagerPolicy}.
-     * Be sure not to take any action that takes a long time; any significant
-     * action should be posted to a handler.
-     */
-    public void onWakeMotionWhenKeyguardShowingTq() {
-        if (DEBUG) Log.d(TAG, "onWakeMotionWhenKeyguardShowing()");
-
-        // give the keyguard view manager a chance to adjust the state of the
-        // keyguard based on the key that woke the device before poking
-        // the wake lock
-        wakeWhenReady(KeyEvent.KEYCODE_UNKNOWN);
-    }
-
-    public void keyguardDone(boolean authenticated, boolean wakeup) {
-        mKeyguardDonePending = false;
-        synchronized (this) {
-            EventLog.writeEvent(70000, 2);
-            if (DEBUG) Log.d(TAG, "keyguardDone(" + authenticated + ")");
-            Message msg = mHandler.obtainMessage(KEYGUARD_DONE);
-            msg.arg1 = wakeup ? 1 : 0;
-            mHandler.sendMessage(msg);
-
-            if (authenticated) {
-                mUpdateMonitor.clearFailedUnlockAttempts();
-            }
-
-            if (mExitSecureCallback != null) {
-                mExitSecureCallback.onKeyguardExitResult(authenticated);
-                mExitSecureCallback = null;
-
-                if (authenticated) {
-                    // after succesfully exiting securely, no need to reshow
-                    // the keyguard when they've released the lock
-                    mExternallyEnabled = true;
-                    mNeedToReshowWhenReenabled = false;
-                }
-            }
-        }
-    }
-
-    /**
-     * This handler will be associated with the policy thread, which will also
-     * be the UI thread of the keyguard.  Since the apis of the policy, and therefore
-     * this class, can be called by other threads, any action that directly
-     * interacts with the keyguard ui should be posted to this handler, rather
-     * than called directly.
-     */
-    private Handler mHandler = new Handler(Looper.myLooper(), null, true /*async*/) {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case SHOW:
-                    handleShow((Bundle) msg.obj);
-                    return ;
-                case HIDE:
-                    handleHide();
-                    return ;
-                case RESET:
-                    handleReset((Bundle) msg.obj);
-                    return ;
-                case VERIFY_UNLOCK:
-                    handleVerifyUnlock();
-                    return;
-                case NOTIFY_SCREEN_OFF:
-                    handleNotifyScreenOff();
-                    return;
-                case NOTIFY_SCREEN_ON:
-                    handleNotifyScreenOn((KeyguardViewManager.ShowListener)msg.obj);
-                    return;
-                case WAKE_WHEN_READY:
-                    handleWakeWhenReady(msg.arg1);
-                    return;
-                case KEYGUARD_DONE:
-                    handleKeyguardDone(msg.arg1 != 0);
-                    return;
-                case KEYGUARD_DONE_DRAWING:
-                    handleKeyguardDoneDrawing();
-                    return;
-                case KEYGUARD_DONE_AUTHENTICATING:
-                    keyguardDone(true, true);
-                    return;
-                case SET_HIDDEN:
-                    handleSetHidden(msg.arg1 != 0);
-                    break;
-                case KEYGUARD_TIMEOUT:
-                    synchronized (KeyguardViewMediator.this) {
-                        doKeyguardLocked((Bundle) msg.obj);
-                    }
-                    break;
-                case SHOW_ASSISTANT:
-                    handleShowAssistant();
-                    break;
-            }
-        }
-    };
-
-    /**
-     * @see #keyguardDone
-     * @see #KEYGUARD_DONE
-     */
-    private void handleKeyguardDone(boolean wakeup) {
-        if (DEBUG) Log.d(TAG, "handleKeyguardDone");
-        handleHide();
-        if (wakeup) {
-            wakeUp();
-        }
-
-        sendUserPresentBroadcast();
-    }
-
-    private void sendUserPresentBroadcast() {
-        if (!(mContext instanceof Activity)) {
-            final UserHandle currentUser = new UserHandle(mLockPatternUtils.getCurrentUser());
-            mContext.sendBroadcastAsUser(mUserPresentIntent, currentUser);
-        }
-    }
-
-    /**
-     * @see #keyguardDoneDrawing
-     * @see #KEYGUARD_DONE_DRAWING
-     */
-    private void handleKeyguardDoneDrawing() {
-        synchronized(this) {
-            if (false) Log.d(TAG, "handleKeyguardDoneDrawing");
-            if (mWaitingUntilKeyguardVisible) {
-                if (DEBUG) Log.d(TAG, "handleKeyguardDoneDrawing: notifying mWaitingUntilKeyguardVisible");
-                mWaitingUntilKeyguardVisible = false;
-                notifyAll();
-
-                // there will usually be two of these sent, one as a timeout, and one
-                // as a result of the callback, so remove any remaining messages from
-                // the queue
-                mHandler.removeMessages(KEYGUARD_DONE_DRAWING);
-            }
-        }
-    }
-
-    private void playSounds(boolean locked) {
-        // User feedback for keyguard.
-
-        if (mSuppressNextLockSound) {
-            mSuppressNextLockSound = false;
-            return;
-        }
-
-        final ContentResolver cr = mContext.getContentResolver();
-        if (Settings.System.getInt(cr, Settings.System.LOCKSCREEN_SOUNDS_ENABLED, 1) == 1) {
-            final int whichSound = locked
-                ? mLockSoundId
-                : mUnlockSoundId;
-            mLockSounds.stop(mLockSoundStreamId);
-            // Init mAudioManager
-            if (mAudioManager == null) {
-                mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
-                if (mAudioManager == null) return;
-                mMasterStreamType = mAudioManager.getMasterStreamType();
-            }
-            // If the stream is muted, don't play the sound
-            if (mAudioManager.isStreamMute(mMasterStreamType)) return;
-
-            mLockSoundStreamId = mLockSounds.play(whichSound,
-                    mLockSoundVolume, mLockSoundVolume, 1/*priortiy*/, 0/*loop*/, 1.0f/*rate*/);
-        }
-    }
-
-    private void updateActivityLockScreenState() {
-        try {
-            ActivityManagerNative.getDefault().setLockScreenShown(
-                    mShowing && !mHidden);
-        } catch (RemoteException e) {
-        }
-    }
-
-    /**
-     * Handle message sent by {@link #showLocked}.
-     * @see #SHOW
-     */
-    private void handleShow(Bundle options) {
-        synchronized (KeyguardViewMediator.this) {
-            if (DEBUG) Log.d(TAG, "handleShow");
-            if (!mSystemReady) return;
-
-            mKeyguardViewManager.show(options);
-            mShowing = true;
-            mKeyguardDonePending = false;
-            updateActivityLockScreenState();
-            adjustStatusBarLocked();
-            userActivity();
-            try {
-                ActivityManagerNative.getDefault().closeSystemDialogs("lock");
-            } catch (RemoteException e) {
-            }
-
-            // Do this at the end to not slow down display of the keyguard.
-            playSounds(true);
-
-            mShowKeyguardWakeLock.release();
-        }
-    }
-
-    /**
-     * Handle message sent by {@link #hideLocked()}
-     * @see #HIDE
-     */
-    private void handleHide() {
-        synchronized (KeyguardViewMediator.this) {
-            if (DEBUG) Log.d(TAG, "handleHide");
-            if (mWakeAndHandOff.isHeld()) {
-                Log.w(TAG, "attempt to hide the keyguard while waking, ignored");
-                return;
-            }
-
-            // only play "unlock" noises if not on a call (since the incall UI
-            // disables the keyguard)
-            if (TelephonyManager.EXTRA_STATE_IDLE.equals(mPhoneState)) {
-                playSounds(false);
-            }
-
-            mKeyguardViewManager.hide();
-            mShowing = false;
-            mKeyguardDonePending = false;
-            updateActivityLockScreenState();
-            adjustStatusBarLocked();
-        }
-    }
-
-    private void adjustStatusBarLocked() {
-        if (mStatusBarManager == null) {
-            mStatusBarManager = (StatusBarManager)
-                    mContext.getSystemService(Context.STATUS_BAR_SERVICE);
-        }
-        if (mStatusBarManager == null) {
-            Log.w(TAG, "Could not get status bar manager");
-        } else {
-            if (mShowLockIcon) {
-                // Give feedback to user when secure keyguard is active and engaged
-                if (mShowing && isSecure()) {
-                    if (!mShowingLockIcon) {
-                        String contentDescription = mContext.getString(
-                                com.android.internal.R.string.status_bar_device_locked);
-                        mStatusBarManager.setIcon("secure",
-                                com.android.internal.R.drawable.stat_sys_secure, 0,
-                                contentDescription);
-                        mShowingLockIcon = true;
-                    }
-                } else {
-                    if (mShowingLockIcon) {
-                        mStatusBarManager.removeIcon("secure");
-                        mShowingLockIcon = false;
-                    }
-                }
-            }
-
-            // Disable aspects of the system/status/navigation bars that must not be re-enabled by
-            // windows that appear on top, ever
-            int flags = StatusBarManager.DISABLE_NONE;
-            if (mShowing) {
-                // Permanently disable components not available when keyguard is enabled
-                // (like recents). Temporary enable/disable (e.g. the "back" button) are
-                // done in KeyguardHostView.
-                flags |= StatusBarManager.DISABLE_RECENT;
-                if (isSecure() || !ENABLE_INSECURE_STATUS_BAR_EXPAND) {
-                    // showing secure lockscreen; disable expanding.
-                    flags |= StatusBarManager.DISABLE_EXPAND;
-                }
-                if (isSecure()) {
-                    // showing secure lockscreen; disable ticker.
-                    flags |= StatusBarManager.DISABLE_NOTIFICATION_TICKER;
-                }
-                if (!isAssistantAvailable()) {
-                    flags |= StatusBarManager.DISABLE_SEARCH;
-                }
-            }
-
-            if (DEBUG) {
-                Log.d(TAG, "adjustStatusBarLocked: mShowing=" + mShowing + " mHidden=" + mHidden
-                        + " isSecure=" + isSecure() + " --> flags=0x" + Integer.toHexString(flags));
-            }
-
-            if (!(mContext instanceof Activity)) {
-                mStatusBarManager.disable(flags);
-            }
-        }
-    }
-
-    /**
-     * Handle message sent by {@link #wakeWhenReady(int)}
-     * @param keyCode The key that woke the device.
-     * @see #WAKE_WHEN_READY
-     */
-    private void handleWakeWhenReady(int keyCode) {
-        synchronized (KeyguardViewMediator.this) {
-            if (DBG_WAKE) Log.d(TAG, "handleWakeWhenReady(" + keyCode + ")");
-
-            // this should result in a call to 'poke wakelock' which will set a timeout
-            // on releasing the wakelock
-            if (!mKeyguardViewManager.wakeWhenReadyTq(keyCode)) {
-                // poke wakelock ourselves if keyguard is no longer active
-                Log.w(TAG, "mKeyguardViewManager.wakeWhenReadyTq did not poke wake lock, so poke it ourselves");
-                userActivity();
-            }
-
-            /**
-             * Now that the keyguard is ready and has poked the wake lock, we can
-             * release the handoff wakelock
-             */
-            mWakeAndHandOff.release();
-        }
-    }
-
-    /**
-     * Handle message sent by {@link #resetStateLocked(Bundle)}
-     * @see #RESET
-     */
-    private void handleReset(Bundle options) {
-        if (options == null) {
-            options = new Bundle();
-        }
-        options.putBoolean(KeyguardViewManager.IS_SWITCHING_USER, mSwitchingUser);
-        synchronized (KeyguardViewMediator.this) {
-            if (DEBUG) Log.d(TAG, "handleReset");
-            mKeyguardViewManager.reset(options);
-        }
-    }
-
-    /**
-     * Handle message sent by {@link #verifyUnlock}
-     * @see #VERIFY_UNLOCK
-     */
-    private void handleVerifyUnlock() {
-        synchronized (KeyguardViewMediator.this) {
-            if (DEBUG) Log.d(TAG, "handleVerifyUnlock");
-            mKeyguardViewManager.verifyUnlock();
-            mShowing = true;
-            updateActivityLockScreenState();
-        }
-    }
-
-    /**
-     * Handle message sent by {@link #notifyScreenOffLocked()}
-     * @see #NOTIFY_SCREEN_OFF
-     */
-    private void handleNotifyScreenOff() {
-        synchronized (KeyguardViewMediator.this) {
-            if (DEBUG) Log.d(TAG, "handleNotifyScreenOff");
-            mKeyguardViewManager.onScreenTurnedOff();
-        }
-    }
-
-    /**
-     * Handle message sent by {@link #notifyScreenOnLocked()}
-     * @see #NOTIFY_SCREEN_ON
-     */
-    private void handleNotifyScreenOn(KeyguardViewManager.ShowListener showListener) {
-        synchronized (KeyguardViewMediator.this) {
-            if (DEBUG) Log.d(TAG, "handleNotifyScreenOn");
-            mKeyguardViewManager.onScreenTurnedOn(showListener);
-        }
-    }
-
-    public boolean isDismissable() {
-        return mKeyguardDonePending || !isSecure();
-    }
-
-    public void showAssistant() {
-        Message msg = mHandler.obtainMessage(SHOW_ASSISTANT);
-        mHandler.sendMessage(msg);
-    }
-
-    public void handleShowAssistant() {
-        mKeyguardViewManager.showAssistant();
-    }
-
-    private boolean isAssistantAvailable() {
-        return mSearchManager != null
-                && mSearchManager.getAssistIntent(mContext, false, UserHandle.USER_CURRENT) != null;
-    }
-
-    public static MultiUserAvatarCache getAvatarCache() {
-        return sMultiUserAvatarCache;
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java
deleted file mode 100644
index 4410063..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java
+++ /dev/null
@@ -1,317 +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.internal.policy.impl.keyguard;
-
-import android.os.Handler;
-import android.os.Looper;
-import android.view.View;
-
-public class KeyguardViewStateManager implements
-        SlidingChallengeLayout.OnChallengeScrolledListener,
-        ChallengeLayout.OnBouncerStateChangedListener {
-
-    private KeyguardWidgetPager mKeyguardWidgetPager;
-    private ChallengeLayout mChallengeLayout;
-    private KeyguardHostView mKeyguardHostView;
-    private int[] mTmpPoint = new int[2];
-    private int[] mTmpLoc = new int[2];
-
-    private KeyguardSecurityView mKeyguardSecurityContainer;
-    private static final int SCREEN_ON_HINT_DURATION = 1000;
-    private static final int SCREEN_ON_RING_HINT_DELAY = 300;
-    Handler mMainQueue = new Handler(Looper.myLooper());
-
-    int mLastScrollState = SlidingChallengeLayout.SCROLL_STATE_IDLE;
-
-    // Paged view state
-    private int mPageListeningToSlider = -1;
-    private int mCurrentPage = -1;
-    private int mPageIndexOnPageBeginMoving = -1;
-
-    int mChallengeTop = 0;
-
-    public KeyguardViewStateManager(KeyguardHostView hostView) {
-        mKeyguardHostView = hostView;
-    }
-
-    public void setPagedView(KeyguardWidgetPager pagedView) {
-        mKeyguardWidgetPager = pagedView;
-        updateEdgeSwiping();
-    }
-
-    public void setChallengeLayout(ChallengeLayout layout) {
-        mChallengeLayout = layout;
-        updateEdgeSwiping();
-    }
-
-    private void updateEdgeSwiping() {
-        if (mChallengeLayout != null && mKeyguardWidgetPager != null) {
-            if (mChallengeLayout.isChallengeOverlapping()) {
-                mKeyguardWidgetPager.setOnlyAllowEdgeSwipes(true);
-            } else {
-                mKeyguardWidgetPager.setOnlyAllowEdgeSwipes(false);
-            }
-        }
-    }
-
-    public boolean isChallengeShowing() {
-        if (mChallengeLayout != null) {
-            return mChallengeLayout.isChallengeShowing();
-        }
-        return false;
-    }
-
-    public boolean isChallengeOverlapping() {
-        if (mChallengeLayout != null) {
-            return mChallengeLayout.isChallengeOverlapping();
-        }
-        return false;
-    }
-
-    public void setSecurityViewContainer(KeyguardSecurityView container) {
-        mKeyguardSecurityContainer = container;
-    }
-
-    public void showBouncer(boolean show) {
-        mChallengeLayout.showBouncer();
-    }
-
-    public boolean isBouncing() {
-        return mChallengeLayout.isBouncing();
-    }
-
-    public void fadeOutSecurity(int duration) {
-        ((View) mKeyguardSecurityContainer).animate().alpha(0).setDuration(duration);
-    }
-
-    public void fadeInSecurity(int duration) {
-        ((View) mKeyguardSecurityContainer).animate().alpha(1f).setDuration(duration);
-    }
-
-    public void onPageBeginMoving() {
-        if (mChallengeLayout.isChallengeOverlapping() &&
-                mChallengeLayout instanceof SlidingChallengeLayout) {
-            SlidingChallengeLayout scl = (SlidingChallengeLayout) mChallengeLayout;
-            scl.fadeOutChallenge();
-            mPageIndexOnPageBeginMoving = mKeyguardWidgetPager.getCurrentPage();
-        }
-        // We use mAppWidgetToShow to show a particular widget after you add it--
-        // once the user swipes a page we clear that behavior
-        if (mKeyguardHostView != null) {
-            mKeyguardHostView.clearAppWidgetToShow();
-            mKeyguardHostView.setOnDismissAction(null);
-        }
-        if (mHideHintsRunnable != null) {
-            mMainQueue.removeCallbacks(mHideHintsRunnable);
-            mHideHintsRunnable = null;
-        }
-    }
-
-    public void onPageEndMoving() {
-        mPageIndexOnPageBeginMoving = -1;
-    }
-
-    public void onPageSwitching(View newPage, int newPageIndex) {
-        if (mKeyguardWidgetPager != null && mChallengeLayout instanceof SlidingChallengeLayout) {
-            boolean isCameraPage = newPage instanceof CameraWidgetFrame;
-            ((SlidingChallengeLayout) mChallengeLayout).setChallengeInteractive(!isCameraPage);
-        }
-
-        // If the page we're settling to is the same as we started on, and the action of
-        // moving the page hid the security, we restore it immediately.
-        if (mPageIndexOnPageBeginMoving == mKeyguardWidgetPager.getNextPage() &&
-                mChallengeLayout instanceof SlidingChallengeLayout) {
-            SlidingChallengeLayout scl = (SlidingChallengeLayout) mChallengeLayout;
-            scl.fadeInChallenge();
-            mKeyguardWidgetPager.setWidgetToResetOnPageFadeOut(-1);
-        }
-        mPageIndexOnPageBeginMoving = -1;
-    }
-
-    public void onPageSwitched(View newPage, int newPageIndex) {
-        // Reset the previous page size and ensure the current page is sized appropriately.
-        // We only modify the page state if it is not currently under control by the slider.
-        // This prevents conflicts.
-
-        // If the page hasn't switched, don't bother with any of this
-        if (mCurrentPage == newPageIndex) return;
-
-        if (mKeyguardWidgetPager != null && mChallengeLayout != null) {
-            KeyguardWidgetFrame prevPage = mKeyguardWidgetPager.getWidgetPageAt(mCurrentPage);
-            if (prevPage != null && mCurrentPage != mPageListeningToSlider && mCurrentPage
-                    != mKeyguardWidgetPager.getWidgetToResetOnPageFadeOut()) {
-                prevPage.resetSize();
-            }
-
-            KeyguardWidgetFrame newCurPage = mKeyguardWidgetPager.getWidgetPageAt(newPageIndex);
-            boolean challengeOverlapping = mChallengeLayout.isChallengeOverlapping();
-            if (challengeOverlapping && !newCurPage.isSmall()
-                    && mPageListeningToSlider != newPageIndex) {
-                newCurPage.shrinkWidget();
-            }
-        }
-
-        mCurrentPage = newPageIndex;
-    }
-
-    private int getChallengeTopRelativeToFrame(KeyguardWidgetFrame frame, int top) {
-        mTmpPoint[0] = 0;
-        mTmpPoint[1] = top;
-        mapPoint((View) mChallengeLayout, frame, mTmpPoint);
-        return mTmpPoint[1];
-    }
-
-    /**
-     * Simple method to map a point from one view's coordinates to another's. Note: this method
-     * doesn't account for transforms, so if the views will be transformed, this should not be used.
-     *
-     * @param fromView The view to which the point is relative
-     * @param toView The view into which the point should be mapped
-     * @param pt The point
-     */
-    private void mapPoint(View fromView, View toView, int pt[]) {
-        fromView.getLocationInWindow(mTmpLoc);
-
-        int x = mTmpLoc[0];
-        int y = mTmpLoc[1];
-
-        toView.getLocationInWindow(mTmpLoc);
-        int vX = mTmpLoc[0];
-        int vY = mTmpLoc[1];
-
-        pt[0] += x - vX;
-        pt[1] += y - vY;
-    }
-
-    private void userActivity() {
-        if (mKeyguardHostView != null) {
-            mKeyguardHostView.onUserActivityTimeoutChanged();
-            mKeyguardHostView.userActivity();
-        }
-    }
-
-    @Override
-    public void onScrollStateChanged(int scrollState) {
-        if (mKeyguardWidgetPager == null || mChallengeLayout == null) return;
-
-        boolean challengeOverlapping = mChallengeLayout.isChallengeOverlapping();
-
-        if (scrollState == SlidingChallengeLayout.SCROLL_STATE_IDLE) {
-            KeyguardWidgetFrame frame = mKeyguardWidgetPager.getWidgetPageAt(mPageListeningToSlider);
-            if (frame == null) return;
-
-            if (!challengeOverlapping) {
-                if (!mKeyguardWidgetPager.isPageMoving()) {
-                    frame.resetSize();
-                    userActivity();
-                } else {
-                    mKeyguardWidgetPager.setWidgetToResetOnPageFadeOut(mPageListeningToSlider);
-                }
-            }
-            if (frame.isSmall()) {
-                // This is to make sure that if the scroller animation gets cut off midway
-                // that the frame doesn't stay in a partial down position.
-                frame.setFrameHeight(frame.getSmallFrameHeight());
-            }
-            if (scrollState != SlidingChallengeLayout.SCROLL_STATE_FADING) {
-                frame.hideFrame(this);
-            }
-            updateEdgeSwiping();
-
-            if (mChallengeLayout.isChallengeShowing()) {
-                mKeyguardSecurityContainer.onResume(KeyguardSecurityView.VIEW_REVEALED);
-            } else {
-                mKeyguardSecurityContainer.onPause();
-            }
-            mPageListeningToSlider = -1;
-        } else if (mLastScrollState == SlidingChallengeLayout.SCROLL_STATE_IDLE) {
-            // Whether dragging or settling, if the last state was idle, we use this signal
-            // to update the current page who will receive events from the sliding challenge.
-            // We resize the frame as appropriate.
-            mPageListeningToSlider = mKeyguardWidgetPager.getNextPage();
-            KeyguardWidgetFrame frame = mKeyguardWidgetPager.getWidgetPageAt(mPageListeningToSlider);
-            if (frame == null) return;
-
-            // Skip showing the frame and shrinking the widget if we are
-            if (!mChallengeLayout.isBouncing()) {
-                if (scrollState != SlidingChallengeLayout.SCROLL_STATE_FADING) {
-                    frame.showFrame(this);
-                }
-
-                // As soon as the security begins sliding, the widget becomes small (if it wasn't
-                // small to begin with).
-                if (!frame.isSmall()) {
-                    // We need to fetch the final page, in case the pages are in motion.
-                    mPageListeningToSlider = mKeyguardWidgetPager.getNextPage();
-                    frame.shrinkWidget(false);
-                }
-            } else {
-                if (!frame.isSmall()) {
-                    // We need to fetch the final page, in case the pages are in motion.
-                    mPageListeningToSlider = mKeyguardWidgetPager.getNextPage();
-                }
-            }
-
-            // View is on the move.  Pause the security view until it completes.
-            mKeyguardSecurityContainer.onPause();
-        }
-        mLastScrollState = scrollState;
-    }
-
-    @Override
-    public void onScrollPositionChanged(float scrollPosition, int challengeTop) {
-        mChallengeTop = challengeTop;
-        KeyguardWidgetFrame frame = mKeyguardWidgetPager.getWidgetPageAt(mPageListeningToSlider);
-        if (frame != null && mLastScrollState != SlidingChallengeLayout.SCROLL_STATE_FADING) {
-            frame.adjustFrame(getChallengeTopRelativeToFrame(frame, mChallengeTop));
-        }
-    }
-
-    private Runnable mHideHintsRunnable = new Runnable() {
-        @Override
-        public void run() {
-            if (mKeyguardWidgetPager != null) {
-                mKeyguardWidgetPager.hideOutlinesAndSidePages();
-            }
-        }
-    };
-
-    public void showUsabilityHints() {
-        mMainQueue.postDelayed( new Runnable() {
-            @Override
-            public void run() {
-                mKeyguardSecurityContainer.showUsabilityHint();
-            }
-        } , SCREEN_ON_RING_HINT_DELAY);
-        mKeyguardWidgetPager.showInitialPageHints();
-        if (mHideHintsRunnable != null) {
-            mMainQueue.postDelayed(mHideHintsRunnable, SCREEN_ON_HINT_DURATION);
-        }
-    }
-
-    // ChallengeLayout.OnBouncerStateChangedListener
-    @Override
-    public void onBouncerStateChanged(boolean bouncerActive) {
-        if (bouncerActive) {
-            mKeyguardWidgetPager.zoomOutToBouncer();
-        } else {
-            mKeyguardWidgetPager.zoomInFromBouncer();
-            if (mKeyguardHostView != null) {
-                mKeyguardHostView.setOnDismissAction(null);
-            }
-        }
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetCarousel.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetCarousel.java
deleted file mode 100644
index 257fd27..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetCarousel.java
+++ /dev/null
@@ -1,290 +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.internal.policy.impl.keyguard;
-
-import android.animation.Animator;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.animation.PropertyValuesHolder;
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.animation.AccelerateInterpolator;
-import android.view.animation.DecelerateInterpolator;
-import android.view.animation.Interpolator;
-
-import com.android.internal.R;
-
-import java.util.ArrayList;
-
-public class KeyguardWidgetCarousel extends KeyguardWidgetPager {
-
-    private float mAdjacentPagesAngle;
-    private static float MAX_SCROLL_PROGRESS = 1.3f;
-    private static float CAMERA_DISTANCE = 10000;
-    protected AnimatorSet mChildrenTransformsAnimator;
-    float[] mTmpTransform = new float[3];
-
-    public KeyguardWidgetCarousel(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public KeyguardWidgetCarousel(Context context) {
-        this(context, null, 0);
-    }
-
-    public KeyguardWidgetCarousel(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        mAdjacentPagesAngle = context.getResources().getInteger(R.integer.kg_carousel_angle);
-    }
-
-    protected float getMaxScrollProgress() {
-        return MAX_SCROLL_PROGRESS;
-    }
-
-    public float getAlphaForPage(int screenCenter, int index, boolean showSidePages) {
-        View child = getChildAt(index);
-        if (child == null) return 0f;
-
-        boolean inVisibleRange = index >= getNextPage() - 1 && index <= getNextPage() + 1;
-        float scrollProgress = getScrollProgress(screenCenter, child, index);
-
-        if (isOverScrollChild(index, scrollProgress)) {
-            return 1.0f;
-        } else if ((showSidePages && inVisibleRange) || index == getNextPage()) {
-            scrollProgress = getBoundedScrollProgress(screenCenter, child, index);
-            float alpha = 1.0f - 1.0f * Math.abs(scrollProgress / MAX_SCROLL_PROGRESS);
-            return alpha;
-        } else {
-            return 0f;
-        }
-    }
-
-    public float getOutlineAlphaForPage(int screenCenter, int index, boolean showSidePages) {
-        boolean inVisibleRange = index >= getNextPage() - 1 && index <= getNextPage() + 1;
-        if (inVisibleRange) {
-            return super.getOutlineAlphaForPage(screenCenter, index, showSidePages);
-        } else {
-            return 0f;
-        }
-    }
-
-    private void updatePageAlphaValues(int screenCenter) {
-        if (mChildrenOutlineFadeAnimation != null) {
-            mChildrenOutlineFadeAnimation.cancel();
-            mChildrenOutlineFadeAnimation = null;
-        }
-        boolean showSidePages = mShowingInitialHints || isPageMoving();
-        if (!isReordering(false)) {
-            for (int i = 0; i < getChildCount(); i++) {
-                KeyguardWidgetFrame child = getWidgetPageAt(i);
-                if (child != null) {
-                    float outlineAlpha = getOutlineAlphaForPage(screenCenter, i, showSidePages);
-                    float contentAlpha = getAlphaForPage(screenCenter, i,showSidePages);
-                    child.setBackgroundAlpha(outlineAlpha);
-                    child.setContentAlpha(contentAlpha);
-                }
-            }
-        }
-    }
-
-    public void showInitialPageHints() {
-        mShowingInitialHints = true;
-        int count = getChildCount();
-        for (int i = 0; i < count; i++) {
-            boolean inVisibleRange = i >= getNextPage() - 1 && i <= getNextPage() + 1;
-            KeyguardWidgetFrame child = getWidgetPageAt(i);
-            if (inVisibleRange) {
-                child.setBackgroundAlpha(KeyguardWidgetFrame.OUTLINE_ALPHA_MULTIPLIER);
-                child.setContentAlpha(1f);
-            } else {
-                child.setBackgroundAlpha(0f);
-                child.setContentAlpha(0f);
-            }
-        }
-    }
-
-    @Override
-    protected void screenScrolled(int screenCenter) {
-        mScreenCenter = screenCenter;
-        updatePageAlphaValues(screenCenter);
-        if (isReordering(false)) return;
-        for (int i = 0; i < getChildCount(); i++) {
-            KeyguardWidgetFrame v = getWidgetPageAt(i);
-            float scrollProgress = getScrollProgress(screenCenter, v, i);
-            float boundedProgress = getBoundedScrollProgress(screenCenter, v, i);
-            if (v == mDragView || v == null) continue;
-            v.setCameraDistance(CAMERA_DISTANCE);
-
-            if (isOverScrollChild(i, scrollProgress)) {
-                v.setRotationY(- OVERSCROLL_MAX_ROTATION * scrollProgress);
-                v.setOverScrollAmount(Math.abs(scrollProgress), scrollProgress < 0);
-            } else {
-                int width = v.getMeasuredWidth();
-                float pivotX = (width / 2f) + boundedProgress * (width / 2f);
-                float pivotY = v.getMeasuredHeight() / 2;
-                float rotationY = - mAdjacentPagesAngle * boundedProgress;
-                v.setPivotX(pivotX);
-                v.setPivotY(pivotY);
-                v.setRotationY(rotationY);
-                v.setOverScrollAmount(0f, false);
-            }
-            float alpha = v.getAlpha();
-            // If the view has 0 alpha, we set it to be invisible so as to prevent
-            // it from accepting touches
-            if (alpha == 0) {
-                v.setVisibility(INVISIBLE);
-            } else if (v.getVisibility() != VISIBLE) {
-                v.setVisibility(VISIBLE);
-            }
-        }
-    }
-
-    void animatePagesToNeutral() {
-        if (mChildrenTransformsAnimator != null) {
-            mChildrenTransformsAnimator.cancel();
-            mChildrenTransformsAnimator = null;
-        }
-
-        int count = getChildCount();
-        PropertyValuesHolder alpha;
-        PropertyValuesHolder outlineAlpha;
-        PropertyValuesHolder rotationY;
-        ArrayList<Animator> anims = new ArrayList<Animator>();
-
-        for (int i = 0; i < count; i++) {
-            KeyguardWidgetFrame child = getWidgetPageAt(i);
-            boolean inVisibleRange = (i >= mCurrentPage - 1 && i <= mCurrentPage + 1);
-            if (!inVisibleRange) {
-                child.setRotationY(0f);
-            }
-            alpha = PropertyValuesHolder.ofFloat("contentAlpha", 1.0f);
-            outlineAlpha = PropertyValuesHolder.ofFloat("backgroundAlpha",
-                    KeyguardWidgetFrame.OUTLINE_ALPHA_MULTIPLIER);
-            rotationY = PropertyValuesHolder.ofFloat("rotationY", 0f);
-            ObjectAnimator a = ObjectAnimator.ofPropertyValuesHolder(child, alpha, outlineAlpha, rotationY);
-            child.setVisibility(VISIBLE);
-            if (!inVisibleRange) {
-                a.setInterpolator(mSlowFadeInterpolator);
-            }
-            anims.add(a);
-        }
-
-        int duration = REORDERING_ZOOM_IN_OUT_DURATION;
-        mChildrenTransformsAnimator = new AnimatorSet();
-        mChildrenTransformsAnimator.playTogether(anims);
-
-        mChildrenTransformsAnimator.setDuration(duration);
-        mChildrenTransformsAnimator.start();
-    }
-
-    private void getTransformForPage(int screenCenter, int index, float[] transform) {
-        View child = getChildAt(index);
-        float boundedProgress = getBoundedScrollProgress(screenCenter, child, index);
-        float rotationY = - mAdjacentPagesAngle * boundedProgress;
-        int width = child.getMeasuredWidth();
-        float pivotX = (width / 2f) + boundedProgress * (width / 2f);
-        float pivotY = child.getMeasuredHeight() / 2;
-
-        transform[0] = pivotX;
-        transform[1] = pivotY;
-        transform[2] = rotationY;
-    }
-
-    Interpolator mFastFadeInterpolator = new Interpolator() {
-        Interpolator mInternal = new DecelerateInterpolator(1.5f);
-        float mFactor = 2.5f;
-        @Override
-        public float getInterpolation(float input) {
-            return mInternal.getInterpolation(Math.min(mFactor * input, 1f));
-        }
-    };
-
-    Interpolator mSlowFadeInterpolator = new Interpolator() {
-        Interpolator mInternal = new AccelerateInterpolator(1.5f);
-        float mFactor = 1.3f;
-        @Override
-        public float getInterpolation(float input) {
-            input -= (1 - 1 / mFactor);
-            input = mFactor * Math.max(input, 0f);
-            return mInternal.getInterpolation(input);
-        }
-    };
-
-    void animatePagesToCarousel() {
-        if (mChildrenTransformsAnimator != null) {
-            mChildrenTransformsAnimator.cancel();
-            mChildrenTransformsAnimator = null;
-        }
-
-        int count = getChildCount();
-        PropertyValuesHolder alpha;
-        PropertyValuesHolder outlineAlpha;
-        PropertyValuesHolder rotationY;
-        PropertyValuesHolder pivotX;
-        PropertyValuesHolder pivotY;
-        ArrayList<Animator> anims = new ArrayList<Animator>();
-
-        for (int i = 0; i < count; i++) {
-            KeyguardWidgetFrame child = getWidgetPageAt(i);
-            float finalAlpha = getAlphaForPage(mScreenCenter, i, true);
-            float finalOutlineAlpha = getOutlineAlphaForPage(mScreenCenter, i, true);
-            getTransformForPage(mScreenCenter, i, mTmpTransform);
-
-            boolean inVisibleRange = (i >= mCurrentPage - 1 && i <= mCurrentPage + 1);
-
-            ObjectAnimator a;
-            alpha = PropertyValuesHolder.ofFloat("contentAlpha", finalAlpha);
-            outlineAlpha = PropertyValuesHolder.ofFloat("backgroundAlpha", finalOutlineAlpha);
-            pivotX = PropertyValuesHolder.ofFloat("pivotX", mTmpTransform[0]);
-            pivotY = PropertyValuesHolder.ofFloat("pivotY", mTmpTransform[1]);
-            rotationY = PropertyValuesHolder.ofFloat("rotationY", mTmpTransform[2]);
-
-            if (inVisibleRange) {
-                // for the central pages we animate into a rotated state
-                a = ObjectAnimator.ofPropertyValuesHolder(child, alpha, outlineAlpha,
-                        pivotX, pivotY, rotationY);
-            } else {
-                a = ObjectAnimator.ofPropertyValuesHolder(child, alpha, outlineAlpha);
-                a.setInterpolator(mFastFadeInterpolator);
-            }
-            anims.add(a);
-        }
-
-        int duration = REORDERING_ZOOM_IN_OUT_DURATION;
-        mChildrenTransformsAnimator = new AnimatorSet();
-        mChildrenTransformsAnimator.playTogether(anims);
-
-        mChildrenTransformsAnimator.setDuration(duration);
-        mChildrenTransformsAnimator.start();
-    }
-
-    protected void reorderStarting() {
-        mViewStateManager.fadeOutSecurity(REORDERING_ZOOM_IN_OUT_DURATION);
-        animatePagesToNeutral();
-    }
-
-    protected boolean zoomIn(final Runnable onCompleteRunnable) {
-        animatePagesToCarousel();
-        return super.zoomIn(onCompleteRunnable);
-    }
-
-    @Override
-    protected void onEndReordering() {
-        super.onEndReordering();
-        mViewStateManager.fadeInSecurity(REORDERING_ZOOM_IN_OUT_DURATION);
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java
deleted file mode 100644
index babb9cb..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java
+++ /dev/null
@@ -1,529 +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.internal.policy.impl.keyguard;
-
-import android.animation.Animator;
-import android.animation.ObjectAnimator;
-import android.animation.PropertyValuesHolder;
-import android.appwidget.AppWidgetHostView;
-import android.appwidget.AppWidgetManager;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.LinearGradient;
-import android.graphics.Paint;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffXfermode;
-import android.graphics.Rect;
-import android.graphics.Shader;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.widget.FrameLayout;
-
-import com.android.internal.R;
-
-public class KeyguardWidgetFrame extends FrameLayout {
-    private final static PorterDuffXfermode sAddBlendMode =
-            new PorterDuffXfermode(PorterDuff.Mode.ADD);
-
-    static final float OUTLINE_ALPHA_MULTIPLIER = 0.6f;
-    static final int HOVER_OVER_DELETE_DROP_TARGET_OVERLAY_COLOR = 0x99FF0000;
-
-    // Temporarily disable this for the time being until we know why the gfx is messing up
-    static final boolean ENABLE_HOVER_OVER_DELETE_DROP_TARGET_OVERLAY = true;
-
-    private int mGradientColor;
-    private LinearGradient mForegroundGradient;
-    private LinearGradient mLeftToRightGradient;
-    private LinearGradient mRightToLeftGradient;
-    private Paint mGradientPaint = new Paint();
-    boolean mLeftToRight = true;
-
-    private float mOverScrollAmount = 0f;
-    private final Rect mForegroundRect = new Rect();
-    private int mForegroundAlpha = 0;
-    private CheckLongPressHelper mLongPressHelper;
-    private Animator mFrameFade;
-    private boolean mIsSmall = false;
-    private Handler mWorkerHandler;
-
-    private float mBackgroundAlpha;
-    private float mContentAlpha;
-    private float mBackgroundAlphaMultiplier = 1.0f;
-    private Drawable mBackgroundDrawable;
-    private Rect mBackgroundRect = new Rect();
-
-    // These variables are all needed in order to size things properly before we're actually
-    // measured.
-    private int mSmallWidgetHeight;
-    private int mSmallFrameHeight;
-    private boolean mWidgetLockedSmall = false;
-    private int mMaxChallengeTop = -1;
-    private int mFrameStrokeAdjustment;
-    private boolean mPerformAppWidgetSizeUpdateOnBootComplete;
-
-    // This will hold the width value before we've actually been measured
-    private int mFrameHeight;
-
-    private boolean mIsHoveringOverDeleteDropTarget;
-
-    // Multiple callers may try and adjust the alpha of the frame. When a caller shows
-    // the outlines, we give that caller control, and nobody else can fade them out.
-    // This prevents animation conflicts.
-    private Object mBgAlphaController;
-
-    public KeyguardWidgetFrame(Context context) {
-        this(context, null, 0);
-    }
-
-    public KeyguardWidgetFrame(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public KeyguardWidgetFrame(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-
-        mLongPressHelper = new CheckLongPressHelper(this);
-
-        Resources res = context.getResources();
-        // TODO: this padding should really correspond to the padding embedded in the background
-        // drawable (ie. outlines).
-        float density = res.getDisplayMetrics().density;
-        int padding = (int) (res.getDisplayMetrics().density * 8);
-        setPadding(padding, padding, padding, padding);
-
-        mFrameStrokeAdjustment = 2 + (int) (2 * density);
-
-        // This will be overriden on phones based on the current security mode, however on tablets
-        // we need to specify a height.
-        mSmallWidgetHeight =
-                res.getDimensionPixelSize(com.android.internal.R.dimen.kg_small_widget_height);
-        mBackgroundDrawable = res.getDrawable(R.drawable.kg_widget_bg_padded);
-        mGradientColor = res.getColor(com.android.internal.R.color.kg_widget_pager_gradient);
-        mGradientPaint.setXfermode(sAddBlendMode);
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        cancelLongPress();
-        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateMonitorCallbacks);
-
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallbacks);
-    }
-
-    private KeyguardUpdateMonitorCallback mUpdateMonitorCallbacks =
-            new KeyguardUpdateMonitorCallback() {
-        @Override
-        public void onBootCompleted() {
-            if (mPerformAppWidgetSizeUpdateOnBootComplete) {
-                performAppWidgetSizeCallbacksIfNecessary();
-                mPerformAppWidgetSizeUpdateOnBootComplete = false;
-            }
-        }
-    };
-
-    void setIsHoveringOverDeleteDropTarget(boolean isHovering) {
-        if (ENABLE_HOVER_OVER_DELETE_DROP_TARGET_OVERLAY) {
-            if (mIsHoveringOverDeleteDropTarget != isHovering) {
-                mIsHoveringOverDeleteDropTarget = isHovering;
-                invalidate();
-            }
-        }
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-        // Watch for longpress events at this level to make sure
-        // users can always pick up this widget
-        switch (ev.getAction()) {
-            case MotionEvent.ACTION_DOWN:
-                mLongPressHelper.postCheckForLongPress(ev);
-                break;
-            case MotionEvent.ACTION_MOVE:
-                mLongPressHelper.onMove(ev);
-                break;
-            case MotionEvent.ACTION_POINTER_DOWN:
-            case MotionEvent.ACTION_UP:
-            case MotionEvent.ACTION_CANCEL:
-                mLongPressHelper.cancelLongPress();
-                break;
-        }
-
-        // Otherwise continue letting touch events fall through to children
-        return false;
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev) {
-        // Watch for longpress events at this level to make sure
-        // users can always pick up this widget
-        switch (ev.getAction()) {
-            case MotionEvent.ACTION_MOVE:
-                mLongPressHelper.onMove(ev);
-                break;
-            case MotionEvent.ACTION_POINTER_DOWN:
-            case MotionEvent.ACTION_UP:
-            case MotionEvent.ACTION_CANCEL:
-                mLongPressHelper.cancelLongPress();
-                break;
-        }
-
-        // We return true here to ensure that we will get cancel / up signal
-        // even if none of our children have requested touch.
-        return true;
-    }
-
-    @Override
-    public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
-        super.requestDisallowInterceptTouchEvent(disallowIntercept);
-        cancelLongPress();
-    }
-
-    @Override
-    public void cancelLongPress() {
-        super.cancelLongPress();
-        mLongPressHelper.cancelLongPress();
-    }
-
-
-    private void drawGradientOverlay(Canvas c) {
-        mGradientPaint.setShader(mForegroundGradient);
-        mGradientPaint.setAlpha(mForegroundAlpha);
-        c.drawRect(mForegroundRect, mGradientPaint);
-    }
-
-    private void drawHoveringOverDeleteOverlay(Canvas c) {
-        if (mIsHoveringOverDeleteDropTarget) {
-            c.drawColor(HOVER_OVER_DELETE_DROP_TARGET_OVERLAY_COLOR);
-        }
-    }
-
-    protected void drawBg(Canvas canvas) {
-        if (mBackgroundAlpha > 0.0f) {
-            Drawable bg = mBackgroundDrawable;
-
-            bg.setAlpha((int) (mBackgroundAlpha * mBackgroundAlphaMultiplier * 255));
-            bg.setBounds(mBackgroundRect);
-            bg.draw(canvas);
-        }
-    }
-
-    @Override
-    protected void dispatchDraw(Canvas canvas) {
-        if (ENABLE_HOVER_OVER_DELETE_DROP_TARGET_OVERLAY) {
-            canvas.save();
-        }
-        drawBg(canvas);
-        super.dispatchDraw(canvas);
-        drawGradientOverlay(canvas);
-        if (ENABLE_HOVER_OVER_DELETE_DROP_TARGET_OVERLAY) {
-            drawHoveringOverDeleteOverlay(canvas);
-            canvas.restore();
-        }
-    }
-
-    /**
-     * Because this view has fading outlines, it is essential that we enable hardware
-     * layers on the content (child) so that updating the alpha of the outlines doesn't
-     * result in the content layer being recreated.
-     */
-    public void enableHardwareLayersForContent() {
-        View widget = getContent();
-        if (widget != null) {
-            widget.setLayerType(LAYER_TYPE_HARDWARE, null);
-        }
-    }
-
-    /**
-     * Because this view has fading outlines, it is essential that we enable hardware
-     * layers on the content (child) so that updating the alpha of the outlines doesn't
-     * result in the content layer being recreated.
-     */
-    public void disableHardwareLayersForContent() {
-        View widget = getContent();
-        if (widget != null) {
-            widget.setLayerType(LAYER_TYPE_NONE, null);
-        }
-    }
-
-    public void enableHardwareLayers() {
-        setLayerType(LAYER_TYPE_HARDWARE, null);
-    }
-
-    public void disableHardwareLayers() {
-        setLayerType(LAYER_TYPE_NONE, null);
-    }
-
-    public View getContent() {
-        return getChildAt(0);
-    }
-
-    public int getContentAppWidgetId() {
-        View content = getContent();
-        if (content instanceof AppWidgetHostView) {
-            return ((AppWidgetHostView) content).getAppWidgetId();
-        } else if (content instanceof KeyguardStatusView) {
-            return ((KeyguardStatusView) content).getAppWidgetId();
-        } else {
-            return AppWidgetManager.INVALID_APPWIDGET_ID;
-        }
-    }
-
-    public float getBackgroundAlpha() {
-        return mBackgroundAlpha;
-    }
-
-    public void setBackgroundAlphaMultiplier(float multiplier) {
-        if (Float.compare(mBackgroundAlphaMultiplier, multiplier) != 0) {
-            mBackgroundAlphaMultiplier = multiplier;
-            invalidate();
-        }
-    }
-
-    public float getBackgroundAlphaMultiplier() {
-        return mBackgroundAlphaMultiplier;
-    }
-
-    public void setBackgroundAlpha(float alpha) {
-        if (Float.compare(mBackgroundAlpha, alpha) != 0) {
-            mBackgroundAlpha = alpha;
-            invalidate();
-        }
-    }
-
-    public float getContentAlpha() {
-        return mContentAlpha;
-    }
-
-    public void setContentAlpha(float alpha) {
-        mContentAlpha = alpha;
-        View content = getContent();
-        if (content != null) {
-            content.setAlpha(alpha);
-        }
-    }
-
-    /**
-     * Depending on whether the security is up, the widget size needs to change
-     * 
-     * @param height The height of the widget, -1 for full height
-     */
-    private void setWidgetHeight(int height) {
-        boolean needLayout = false;
-        View widget = getContent();
-        if (widget != null) {
-            LayoutParams lp = (LayoutParams) widget.getLayoutParams();
-            if (lp.height != height) {
-                needLayout = true;
-                lp.height = height;
-            }
-        }
-        if (needLayout) {
-            requestLayout();
-        }
-    }
-
-    public void setMaxChallengeTop(int top) {
-        boolean dirty = mMaxChallengeTop != top;
-        mMaxChallengeTop = top;
-        mSmallWidgetHeight = top - getPaddingTop();
-        mSmallFrameHeight = top + getPaddingBottom();
-        if (dirty && mIsSmall) {
-            setWidgetHeight(mSmallWidgetHeight);
-            setFrameHeight(mSmallFrameHeight);
-        } else if (dirty && mWidgetLockedSmall) {
-            setWidgetHeight(mSmallWidgetHeight);
-        }
-    }
-
-    public boolean isSmall() {
-        return mIsSmall;
-    }
-
-    public void adjustFrame(int challengeTop) {
-        int frameHeight = challengeTop + getPaddingBottom();
-        setFrameHeight(frameHeight);
-    }
-
-    public void shrinkWidget(boolean alsoShrinkFrame) {
-        mIsSmall = true;
-        setWidgetHeight(mSmallWidgetHeight);
-
-        if (alsoShrinkFrame) {
-            setFrameHeight(mSmallFrameHeight);
-        }
-    }
-
-    public int getSmallFrameHeight() {
-        return mSmallFrameHeight;
-    }
-
-    public void shrinkWidget() {
-        shrinkWidget(true);
-    }
-
-    public void setWidgetLockedSmall(boolean locked) {
-        if (locked) {
-            setWidgetHeight(mSmallWidgetHeight);
-        }
-        mWidgetLockedSmall = locked;
-    }
-
-    public void resetSize() {
-        mIsSmall = false;
-        if (!mWidgetLockedSmall) {
-            setWidgetHeight(LayoutParams.MATCH_PARENT);
-        }
-        setFrameHeight(getMeasuredHeight());
-    }
-
-    public void setFrameHeight(int height) {
-        mFrameHeight = height;
-        mBackgroundRect.set(0, 0, getMeasuredWidth(), Math.min(mFrameHeight, getMeasuredHeight()));
-        mForegroundRect.set(mFrameStrokeAdjustment, mFrameStrokeAdjustment,getMeasuredWidth() -
-                mFrameStrokeAdjustment, Math.min(getMeasuredHeight(), mFrameHeight) -
-                mFrameStrokeAdjustment);
-        updateGradient();
-        invalidate();
-    }
-
-    public void hideFrame(Object caller) {
-        fadeFrame(caller, false, 0f, KeyguardWidgetPager.CHILDREN_OUTLINE_FADE_OUT_DURATION);
-    }
-
-    public void showFrame(Object caller) {
-        fadeFrame(caller, true, OUTLINE_ALPHA_MULTIPLIER,
-                KeyguardWidgetPager.CHILDREN_OUTLINE_FADE_IN_DURATION);
-    }
-
-    public void fadeFrame(Object caller, boolean takeControl, float alpha, int duration) {
-        if (takeControl) {
-            mBgAlphaController = caller;
-        }
-
-        if (mBgAlphaController != caller && mBgAlphaController != null) {
-            return;
-        }
-
-        if (mFrameFade != null) {
-            mFrameFade.cancel();
-            mFrameFade = null;
-        }
-        PropertyValuesHolder bgAlpha = PropertyValuesHolder.ofFloat("backgroundAlpha", alpha);
-        mFrameFade = ObjectAnimator.ofPropertyValuesHolder(this, bgAlpha);
-        mFrameFade.setDuration(duration);
-        mFrameFade.start();
-    }
-
-    private void updateGradient() {
-        float x0 = mLeftToRight ? 0 : mForegroundRect.width();
-        float x1 = mLeftToRight ? mForegroundRect.width(): 0;
-        mLeftToRightGradient = new LinearGradient(x0, 0f, x1, 0f,
-                mGradientColor, 0, Shader.TileMode.CLAMP);
-        mRightToLeftGradient = new LinearGradient(x1, 0f, x0, 0f,
-                mGradientColor, 0, Shader.TileMode.CLAMP);
-    }
-
-    @Override
-    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
-        super.onSizeChanged(w, h, oldw, oldh);
-
-        if (!mIsSmall) {
-            mFrameHeight = h;
-        }
-
-        // mFrameStrokeAdjustment is a cludge to prevent the overlay from drawing outside the
-        // rounded rect background.
-        mForegroundRect.set(mFrameStrokeAdjustment, mFrameStrokeAdjustment,
-                w - mFrameStrokeAdjustment, Math.min(h, mFrameHeight) - mFrameStrokeAdjustment);
-
-        mBackgroundRect.set(0, 0, getMeasuredWidth(), Math.min(h, mFrameHeight));
-        updateGradient();
-        invalidate();
-    }
-
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        performAppWidgetSizeCallbacksIfNecessary();
-    }
-
-    private void performAppWidgetSizeCallbacksIfNecessary() {
-        View content = getContent();
-        if (!(content instanceof AppWidgetHostView)) return;
-
-        if (!KeyguardUpdateMonitor.getInstance(mContext).hasBootCompleted()) {
-            mPerformAppWidgetSizeUpdateOnBootComplete = true;
-            return;
-        }
-
-        // TODO: there's no reason to force the AppWidgetHostView to catch duplicate size calls.
-        // We can do that even more cheaply here. It's not an issue right now since we're in the
-        // system process and hence no binder calls.
-        AppWidgetHostView awhv = (AppWidgetHostView) content;
-        float density = getResources().getDisplayMetrics().density;
-
-        int width = (int) (content.getMeasuredWidth() / density);
-        int height = (int) (content.getMeasuredHeight() / density);
-        awhv.updateAppWidgetSize(null, width, height, width, height, true);
-    }
-
-    void setOverScrollAmount(float r, boolean left) {
-        if (Float.compare(mOverScrollAmount, r) != 0) {
-            mOverScrollAmount = r;
-            mForegroundGradient = left ? mLeftToRightGradient : mRightToLeftGradient;
-            mForegroundAlpha = (int) Math.round((0.5f * r * 255));
-
-            // We bump up the alpha of the outline to hide the fact that the overlay is drawing
-            // over the rounded part of the frame.
-            float bgAlpha = Math.min(OUTLINE_ALPHA_MULTIPLIER + r * (1 - OUTLINE_ALPHA_MULTIPLIER),
-                    1f);
-            setBackgroundAlpha(bgAlpha);
-            invalidate();
-        }
-    }
-
-    public void onActive(boolean isActive) {
-        // hook for subclasses
-    }
-
-    public boolean onUserInteraction(MotionEvent event) {
-        // hook for subclasses
-        return false;
-    }
-
-    public void onBouncerShowing(boolean showing) {
-        // hook for subclasses
-    }
-
-    public void setWorkerHandler(Handler workerHandler) {
-        mWorkerHandler = workerHandler;
-    }
-
-    public Handler getWorkerHandler() {
-        return mWorkerHandler;
-    }
-
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
deleted file mode 100644
index 770fafc..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
+++ /dev/null
@@ -1,926 +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.internal.policy.impl.keyguard;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.animation.PropertyValuesHolder;
-import android.animation.TimeInterpolator;
-import android.appwidget.AppWidgetHostView;
-import android.appwidget.AppWidgetManager;
-import android.appwidget.AppWidgetProviderInfo;
-import android.content.Context;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.text.format.DateFormat;
-import android.util.AttributeSet;
-import android.util.Slog;
-import android.view.Gravity;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.View.OnLongClickListener;
-import android.view.ViewGroup;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
-import android.view.animation.DecelerateInterpolator;
-import android.widget.FrameLayout;
-import android.widget.TextClock;
-
-import com.android.internal.widget.LockPatternUtils;
-
-import java.util.ArrayList;
-import java.util.TimeZone;
-
-public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwitchListener,
-        OnLongClickListener, ChallengeLayout.OnBouncerStateChangedListener {
-
-    ZInterpolator mZInterpolator = new ZInterpolator(0.5f);
-    private static float CAMERA_DISTANCE = 10000;
-    protected static float OVERSCROLL_MAX_ROTATION = 30;
-    private static final boolean PERFORM_OVERSCROLL_ROTATION = true;
-
-    private static final int FLAG_HAS_LOCAL_HOUR = 0x1;
-    private static final int FLAG_HAS_LOCAL_MINUTE = 0x2;
-
-    protected KeyguardViewStateManager mViewStateManager;
-    private LockPatternUtils mLockPatternUtils;
-
-    // Related to the fading in / out background outlines
-    public static final int CHILDREN_OUTLINE_FADE_OUT_DURATION = 375;
-    public static final int CHILDREN_OUTLINE_FADE_IN_DURATION = 100;
-    protected AnimatorSet mChildrenOutlineFadeAnimation;
-    protected int mScreenCenter;
-    private boolean mHasMeasure = false;
-    boolean showHintsAfterLayout = false;
-
-    private static final long CUSTOM_WIDGET_USER_ACTIVITY_TIMEOUT = 30000;
-    private static final String TAG = "KeyguardWidgetPager";
-    private boolean mCenterSmallWidgetsVertically;
-
-    private int mPage = 0;
-    private Callbacks mCallbacks;
-
-    private int mWidgetToResetAfterFadeOut;
-    protected boolean mShowingInitialHints = false;
-
-    // A temporary handle to the Add-Widget view
-    private View mAddWidgetView;
-    private int mLastWidthMeasureSpec;
-    private int mLastHeightMeasureSpec;
-
-    // Bouncer
-    private int mBouncerZoomInOutDuration = 250;
-    private float BOUNCER_SCALE_FACTOR = 0.67f;
-
-    // Background worker thread: used here for persistence, also made available to widget frames
-    private final HandlerThread mBackgroundWorkerThread;
-    private final Handler mBackgroundWorkerHandler;
-
-    public KeyguardWidgetPager(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public KeyguardWidgetPager(Context context) {
-        this(null, null, 0);
-    }
-
-    public KeyguardWidgetPager(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        if (getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
-            setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
-        }
-
-        setPageSwitchListener(this);
-
-        mBackgroundWorkerThread = new HandlerThread("KeyguardWidgetPager Worker");
-        mBackgroundWorkerThread.start();
-        mBackgroundWorkerHandler = new Handler(mBackgroundWorkerThread.getLooper());
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-
-        // Clean up the worker thread
-        mBackgroundWorkerThread.quit();
-    }
-
-    public void setViewStateManager(KeyguardViewStateManager viewStateManager) {
-        mViewStateManager = viewStateManager;
-    }
-
-    public void setLockPatternUtils(LockPatternUtils l) {
-        mLockPatternUtils = l;
-    }
-
-    @Override
-    public void onPageSwitching(View newPage, int newPageIndex) {
-        if (mViewStateManager != null) {
-            mViewStateManager.onPageSwitching(newPage, newPageIndex);
-        }
-    }
-
-    @Override
-    public void onPageSwitched(View newPage, int newPageIndex) {
-        boolean showingClock = false;
-        if (newPage instanceof ViewGroup) {
-            ViewGroup vg = (ViewGroup) newPage;
-            if (vg.getChildAt(0) instanceof KeyguardStatusView) {
-                showingClock = true;
-            }
-        }
-
-        if (newPage != null &&
-                findClockInHierarchy(newPage) == (FLAG_HAS_LOCAL_HOUR | FLAG_HAS_LOCAL_MINUTE)) {
-            showingClock = true;
-        }
-
-        // Disable the status bar clock if we're showing the default status widget
-        if (showingClock) {
-            setSystemUiVisibility(getSystemUiVisibility() | View.STATUS_BAR_DISABLE_CLOCK);
-        } else {
-            setSystemUiVisibility(getSystemUiVisibility() & ~View.STATUS_BAR_DISABLE_CLOCK);
-        }
-
-        // Extend the display timeout if the user switches pages
-        if (mPage != newPageIndex) {
-            int oldPageIndex = mPage;
-            mPage = newPageIndex;
-            userActivity();
-            KeyguardWidgetFrame oldWidgetPage = getWidgetPageAt(oldPageIndex);
-            if (oldWidgetPage != null) {
-                oldWidgetPage.onActive(false);
-            }
-            KeyguardWidgetFrame newWidgetPage = getWidgetPageAt(newPageIndex);
-            if (newWidgetPage != null) {
-                newWidgetPage.onActive(true);
-                newWidgetPage.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
-                newWidgetPage.requestAccessibilityFocus();
-            }
-            if (mParent != null && AccessibilityManager.getInstance(mContext).isEnabled()) {
-                AccessibilityEvent event = AccessibilityEvent.obtain(
-                        AccessibilityEvent.TYPE_VIEW_SCROLLED);
-                onInitializeAccessibilityEvent(event);
-                onPopulateAccessibilityEvent(event);
-                mParent.requestSendAccessibilityEvent(this, event);
-            }
-        }
-        if (mViewStateManager != null) {
-            mViewStateManager.onPageSwitched(newPage, newPageIndex);
-        }
-    }
-
-    @Override
-    public void sendAccessibilityEvent(int eventType) {
-        if (eventType != AccessibilityEvent.TYPE_VIEW_SCROLLED || isPageMoving()) {
-            super.sendAccessibilityEvent(eventType);
-        }
-    }
-
-    private void updateWidgetFramesImportantForAccessibility() {
-        final int pageCount = getPageCount();
-        for (int i = 0; i < pageCount; i++) {
-            KeyguardWidgetFrame frame = getWidgetPageAt(i);
-            updateWidgetFrameImportantForAccessibility(frame);
-        }
-    }
-
-    private void updateWidgetFrameImportantForAccessibility(KeyguardWidgetFrame frame) {
-        if (frame.getContentAlpha() <= 0) {
-            frame.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
-        } else {
-            frame.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
-        }
-    }
-
-    private void userActivity() {
-        if (mCallbacks != null) {
-            mCallbacks.onUserActivityTimeoutChanged();
-            mCallbacks.userActivity();
-        }
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev) {
-        return captureUserInteraction(ev) || super.onTouchEvent(ev);
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-        return captureUserInteraction(ev) || super.onInterceptTouchEvent(ev);
-    }
-
-    private boolean captureUserInteraction(MotionEvent ev) {
-        KeyguardWidgetFrame currentWidgetPage = getWidgetPageAt(getCurrentPage());
-        return currentWidgetPage != null && currentWidgetPage.onUserInteraction(ev);
-    }
-
-    public void showPagingFeedback() {
-        // Nothing yet.
-    }
-
-    public long getUserActivityTimeout() {
-        View page = getPageAt(mPage);
-        if (page instanceof ViewGroup) {
-            ViewGroup vg = (ViewGroup) page;
-            View view = vg.getChildAt(0);
-            if (!(view instanceof KeyguardStatusView)
-                    && !(view instanceof KeyguardMultiUserSelectorView)) {
-                return CUSTOM_WIDGET_USER_ACTIVITY_TIMEOUT;
-            }
-        }
-        return -1;
-    }
-
-    public void setCallbacks(Callbacks callbacks) {
-        mCallbacks = callbacks;
-    }
-
-    public interface Callbacks {
-        public void userActivity();
-        public void onUserActivityTimeoutChanged();
-        public void onAddView(View v);
-        public void onRemoveView(View v, boolean deletePermanently);
-        public void onRemoveViewAnimationCompleted();
-    }
-
-    public void addWidget(View widget) {
-        addWidget(widget, -1);
-    }
-
-    public void onRemoveView(View v, final boolean deletePermanently) {
-        final int appWidgetId = ((KeyguardWidgetFrame) v).getContentAppWidgetId();
-        if (mCallbacks != null) {
-            mCallbacks.onRemoveView(v, deletePermanently);
-        }
-        mBackgroundWorkerHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                mLockPatternUtils.removeAppWidget(appWidgetId);
-            }
-        });
-    }
-
-    @Override
-    public void onRemoveViewAnimationCompleted() {
-        if (mCallbacks != null) {
-            mCallbacks.onRemoveViewAnimationCompleted();
-        }
-    }
-
-    public void onAddView(View v, final int index) {
-        final int appWidgetId = ((KeyguardWidgetFrame) v).getContentAppWidgetId();
-        final int[] pagesRange = new int[mTempVisiblePagesRange.length];
-        getVisiblePages(pagesRange);
-        boundByReorderablePages(true, pagesRange);
-        if (mCallbacks != null) {
-            mCallbacks.onAddView(v);
-        }
-        // Subtract from the index to take into account pages before the reorderable
-        // pages (e.g. the "add widget" page)
-        mBackgroundWorkerHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                mLockPatternUtils.addAppWidget(appWidgetId, index - pagesRange[0]);
-            }
-        });
-    }
-
-    /*
-     * We wrap widgets in a special frame which handles drawing the over scroll foreground.
-     */
-    public void addWidget(View widget, int pageIndex) {
-        KeyguardWidgetFrame frame;
-        // All views contained herein should be wrapped in a KeyguardWidgetFrame
-        if (!(widget instanceof KeyguardWidgetFrame)) {
-            frame = new KeyguardWidgetFrame(getContext());
-            FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
-                    LayoutParams.MATCH_PARENT);
-            lp.gravity = Gravity.TOP;
-
-            // The framework adds a default padding to AppWidgetHostView. We don't need this padding
-            // for the Keyguard, so we override it to be 0.
-            widget.setPadding(0,  0, 0, 0);
-            frame.addView(widget, lp);
-
-            // We set whether or not this widget supports vertical resizing.
-            if (widget instanceof AppWidgetHostView) {
-                AppWidgetHostView awhv = (AppWidgetHostView) widget;
-                AppWidgetProviderInfo info = awhv.getAppWidgetInfo();
-                if ((info.resizeMode & AppWidgetProviderInfo.RESIZE_VERTICAL) != 0) {
-                    frame.setWidgetLockedSmall(false);
-                } else {
-                    // Lock the widget to be small.
-                    frame.setWidgetLockedSmall(true);
-                    if (mCenterSmallWidgetsVertically) {
-                        lp.gravity = Gravity.CENTER;
-                    }
-                }
-            }
-        } else {
-            frame = (KeyguardWidgetFrame) widget;
-        }
-
-        ViewGroup.LayoutParams pageLp = new ViewGroup.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
-        frame.setOnLongClickListener(this);
-        frame.setWorkerHandler(mBackgroundWorkerHandler);
-
-        if (pageIndex == -1) {
-            addView(frame, pageLp);
-        } else {
-            addView(frame, pageIndex, pageLp);
-        }
-
-        // Update the frame content description.
-        View content = (widget == frame) ?  frame.getContent() : widget;
-        if (content != null) {
-            String contentDescription = mContext.getString(
-                com.android.internal.R.string.keyguard_accessibility_widget,
-                content.getContentDescription());
-            frame.setContentDescription(contentDescription);
-        }
-        updateWidgetFrameImportantForAccessibility(frame);
-    }
-
-    /**
-     * Use addWidget() instead.
-     * @deprecated
-     */
-    @Override
-    public void addView(View child, int index) {
-        enforceKeyguardWidgetFrame(child);
-        super.addView(child, index);
-    }
-
-    /**
-     * Use addWidget() instead.
-     * @deprecated
-     */
-    @Override
-    public void addView(View child, int width, int height) {
-        enforceKeyguardWidgetFrame(child);
-        super.addView(child, width, height);
-    }
-
-    /**
-     * Use addWidget() instead.
-     * @deprecated
-     */
-    @Override
-    public void addView(View child, LayoutParams params) {
-        enforceKeyguardWidgetFrame(child);
-        super.addView(child, params);
-    }
-
-    /**
-     * Use addWidget() instead.
-     * @deprecated
-     */
-    @Override
-    public void addView(View child, int index, LayoutParams params) {
-        enforceKeyguardWidgetFrame(child);
-        super.addView(child, index, params);
-    }
-
-    private void enforceKeyguardWidgetFrame(View child) {
-        if (!(child instanceof KeyguardWidgetFrame)) {
-            throw new IllegalArgumentException(
-                    "KeyguardWidgetPager children must be KeyguardWidgetFrames");
-        }
-    }
-
-    public KeyguardWidgetFrame getWidgetPageAt(int index) {
-        // This is always a valid cast as we've guarded the ability to
-        return (KeyguardWidgetFrame) getChildAt(index);
-    }
-
-    protected void onUnhandledTap(MotionEvent ev) {
-        showPagingFeedback();
-    }
-
-    @Override
-    protected void onPageBeginMoving() {
-        if (mViewStateManager != null) {
-            mViewStateManager.onPageBeginMoving();
-        }
-        if (!isReordering(false)) {
-            showOutlinesAndSidePages();
-        }
-        userActivity();
-    }
-
-    @Override
-    protected void onPageEndMoving() {
-        if (mViewStateManager != null) {
-            mViewStateManager.onPageEndMoving();
-        }
-
-        // In the reordering case, the pages will be faded appropriately on completion
-        // of the zoom in animation.
-        if (!isReordering(false)) {
-            hideOutlinesAndSidePages();
-        }
-    }
-
-    protected void enablePageContentLayers() {
-        int children = getChildCount();
-        for (int i = 0; i < children; i++) {
-            getWidgetPageAt(i).enableHardwareLayersForContent();
-        }
-    }
-
-    protected void disablePageContentLayers() {
-        int children = getChildCount();
-        for (int i = 0; i < children; i++) {
-            getWidgetPageAt(i).disableHardwareLayersForContent();
-        }
-    }
-
-    /*
-     * This interpolator emulates the rate at which the perceived scale of an object changes
-     * as its distance from a camera increases. When this interpolator is applied to a scale
-     * animation on a view, it evokes the sense that the object is shrinking due to moving away
-     * from the camera.
-     */
-    static class ZInterpolator implements TimeInterpolator {
-        private float focalLength;
-
-        public ZInterpolator(float foc) {
-            focalLength = foc;
-        }
-
-        public float getInterpolation(float input) {
-            return (1.0f - focalLength / (focalLength + input)) /
-                (1.0f - focalLength / (focalLength + 1.0f));
-        }
-    }
-
-    @Override
-    protected void overScroll(float amount) {
-        acceleratedOverScroll(amount);
-    }
-
-    float backgroundAlphaInterpolator(float r) {
-        return Math.min(1f, r);
-    }
-
-    private void updatePageAlphaValues(int screenCenter) {
-    }
-
-    public float getAlphaForPage(int screenCenter, int index, boolean showSidePages) {
-        if (showSidePages) {
-            return 1f;
-        } else {
-            return index == mCurrentPage ? 1.0f : 0f;
-        }
-    }
-
-    public float getOutlineAlphaForPage(int screenCenter, int index, boolean showSidePages) {
-        if (showSidePages) {
-            return getAlphaForPage(screenCenter, index, showSidePages)
-                    * KeyguardWidgetFrame.OUTLINE_ALPHA_MULTIPLIER;
-        } else {
-            return 0f;
-        }
-    }
-
-    protected boolean isOverScrollChild(int index, float scrollProgress) {
-        boolean isInOverscroll = mOverScrollX < 0 || mOverScrollX > mMaxScrollX;
-        return (isInOverscroll && (index == 0 && scrollProgress < 0 ||
-                index == getChildCount() - 1 && scrollProgress > 0));
-    }
-
-    @Override
-    protected void screenScrolled(int screenCenter) {
-        mScreenCenter = screenCenter;
-        updatePageAlphaValues(screenCenter);
-        for (int i = 0; i < getChildCount(); i++) {
-            KeyguardWidgetFrame v = getWidgetPageAt(i);
-            if (v == mDragView) continue;
-            if (v != null) {
-                float scrollProgress = getScrollProgress(screenCenter, v, i);
-
-                v.setCameraDistance(mDensity * CAMERA_DISTANCE);
-
-                if (isOverScrollChild(i, scrollProgress) && PERFORM_OVERSCROLL_ROTATION) {
-                    float pivotX = v.getMeasuredWidth() / 2;
-                    float pivotY = v.getMeasuredHeight() / 2;
-                    v.setPivotX(pivotX);
-                    v.setPivotY(pivotY);
-                    v.setRotationY(- OVERSCROLL_MAX_ROTATION * scrollProgress);
-                    v.setOverScrollAmount(Math.abs(scrollProgress), scrollProgress < 0);
-                } else {
-                    v.setRotationY(0f);
-                    v.setOverScrollAmount(0, false);
-                }
-
-                float alpha = v.getAlpha();
-                // If the view has 0 alpha, we set it to be invisible so as to prevent
-                // it from accepting touches
-                if (alpha == 0) {
-                    v.setVisibility(INVISIBLE);
-                } else if (v.getVisibility() != VISIBLE) {
-                    v.setVisibility(VISIBLE);
-                }
-            }
-        }
-    }
-
-    public boolean isWidgetPage(int pageIndex) {
-        if (pageIndex < 0 || pageIndex >= getChildCount()) {
-            return false;
-        }
-        View v = getChildAt(pageIndex);
-        if (v != null && v instanceof KeyguardWidgetFrame) {
-            KeyguardWidgetFrame kwf = (KeyguardWidgetFrame) v;
-            return kwf.getContentAppWidgetId() != AppWidgetManager.INVALID_APPWIDGET_ID;
-        }
-        return false;
-    }
-
-    /**
-     * Returns the bounded set of pages that are re-orderable.  The range is fully inclusive.
-     */
-    @Override
-    void boundByReorderablePages(boolean isReordering, int[] range) {
-        if (isReordering) {
-            // Remove non-widget pages from the range
-            while (range[1] >= range[0] && !isWidgetPage(range[1])) {
-                range[1]--;
-            }
-            while (range[0] <= range[1] && !isWidgetPage(range[0])) {
-                range[0]++;
-            }
-        }
-    }
-
-    protected void reorderStarting() {
-        showOutlinesAndSidePages();
-    }
-
-    @Override
-    protected void onStartReordering() {
-        super.onStartReordering();
-        enablePageContentLayers();
-        reorderStarting();
-    }
-
-    @Override
-    protected void onEndReordering() {
-        super.onEndReordering();
-        hideOutlinesAndSidePages();
-    }
-
-    void showOutlinesAndSidePages() {
-        animateOutlinesAndSidePages(true);
-    }
-
-    void hideOutlinesAndSidePages() {
-        animateOutlinesAndSidePages(false);
-    }
-
-    void updateChildrenContentAlpha(float sidePageAlpha) {
-        int count = getChildCount();
-        for (int i = 0; i < count; i++) {
-            KeyguardWidgetFrame child = getWidgetPageAt(i);
-            if (i != mCurrentPage) {
-                child.setBackgroundAlpha(sidePageAlpha);
-                child.setContentAlpha(0f);
-            } else {
-                child.setBackgroundAlpha(0f);
-                child.setContentAlpha(1f);
-            }
-        }
-    }
-
-    public void showInitialPageHints() {
-        mShowingInitialHints = true;
-        updateChildrenContentAlpha(KeyguardWidgetFrame.OUTLINE_ALPHA_MULTIPLIER);
-    }
-
-    @Override
-    void setCurrentPage(int currentPage) {
-        super.setCurrentPage(currentPage);
-        updateChildrenContentAlpha(0.0f);
-        updateWidgetFramesImportantForAccessibility();
-    }
-
-    @Override
-    public void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        mHasMeasure = false;
-    }
-
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        mLastWidthMeasureSpec = widthMeasureSpec;
-        mLastHeightMeasureSpec = heightMeasureSpec;
-
-        int maxChallengeTop = -1;
-        View parent = (View) getParent();
-        boolean challengeShowing = false;
-        // Widget pages need to know where the top of the sliding challenge is so that they
-        // now how big the widget should be when the challenge is up. We compute it here and
-        // then propagate it to each of our children.
-        if (parent.getParent() instanceof SlidingChallengeLayout) {
-            SlidingChallengeLayout scl = (SlidingChallengeLayout) parent.getParent();
-            int top = scl.getMaxChallengeTop();
-
-            // This is a bit evil, but we need to map a coordinate relative to the SCL into a
-            // coordinate relative to our children, hence we subtract the top padding.s
-            maxChallengeTop = top - getPaddingTop();
-            challengeShowing = scl.isChallengeShowing();
-
-            int count = getChildCount();
-            for (int i = 0; i < count; i++) {
-                KeyguardWidgetFrame frame = getWidgetPageAt(i);
-                frame.setMaxChallengeTop(maxChallengeTop);
-                // On the very first measure pass, if the challenge is showing, we need to make sure
-                // that the widget on the current page is small.
-                if (challengeShowing && i == mCurrentPage && !mHasMeasure) {
-                    frame.shrinkWidget();
-                }
-            }
-        }
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        mHasMeasure = true;
-    }
-
-    void animateOutlinesAndSidePages(final boolean show) {
-        animateOutlinesAndSidePages(show, -1);
-    }
-
-    public void setWidgetToResetOnPageFadeOut(int widget) {
-        mWidgetToResetAfterFadeOut = widget;
-    }
-
-    public int getWidgetToResetOnPageFadeOut() {
-        return mWidgetToResetAfterFadeOut;
-    }
-
-    void animateOutlinesAndSidePages(final boolean show, int duration) {
-        if (mChildrenOutlineFadeAnimation != null) {
-            mChildrenOutlineFadeAnimation.cancel();
-            mChildrenOutlineFadeAnimation = null;
-        }
-        int count = getChildCount();
-        PropertyValuesHolder alpha;
-        ArrayList<Animator> anims = new ArrayList<Animator>();
-
-        if (duration == -1) {
-            duration = show ? CHILDREN_OUTLINE_FADE_IN_DURATION :
-                CHILDREN_OUTLINE_FADE_OUT_DURATION;
-        }
-
-        int curPage = getNextPage();
-        for (int i = 0; i < count; i++) {
-            float finalContentAlpha;
-            if (show) {
-                finalContentAlpha = getAlphaForPage(mScreenCenter, i, true);
-            } else if (!show && i == curPage) {
-                finalContentAlpha = 1f;
-            } else {
-                finalContentAlpha = 0f;
-            }
-            KeyguardWidgetFrame child = getWidgetPageAt(i);
-
-            alpha = PropertyValuesHolder.ofFloat("contentAlpha", finalContentAlpha);
-            ObjectAnimator a = ObjectAnimator.ofPropertyValuesHolder(child, alpha);
-            anims.add(a);
-
-            float finalOutlineAlpha = show ? getOutlineAlphaForPage(mScreenCenter, i, true) : 0f;
-            child.fadeFrame(this, show, finalOutlineAlpha, duration);
-        }
-
-        mChildrenOutlineFadeAnimation = new AnimatorSet();
-        mChildrenOutlineFadeAnimation.playTogether(anims);
-
-        mChildrenOutlineFadeAnimation.setDuration(duration);
-        mChildrenOutlineFadeAnimation.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationStart(Animator animation) {
-                if (show) {
-                    enablePageContentLayers();
-                }
-            }
-
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                if (!show) {
-                    disablePageContentLayers();
-                    KeyguardWidgetFrame frame = getWidgetPageAt(mWidgetToResetAfterFadeOut);
-                    if (frame != null && !(frame == getWidgetPageAt(mCurrentPage) &&
-                            mViewStateManager.isChallengeOverlapping())) {
-                        frame.resetSize();
-                    }
-                    mWidgetToResetAfterFadeOut = -1;
-                    mShowingInitialHints = false;
-                }
-                updateWidgetFramesImportantForAccessibility();
-            }
-        });
-        mChildrenOutlineFadeAnimation.start();
-    }
-
-    @Override
-    public boolean onLongClick(View v) {
-        // Disallow long pressing to reorder if the challenge is showing
-        boolean isChallengeOverlapping = mViewStateManager.isChallengeShowing() &&
-                mViewStateManager.isChallengeOverlapping();
-        if (!isChallengeOverlapping && startReordering()) {
-            return true;
-        }
-        return false;
-    }
-
-    public void removeWidget(View view) {
-        if (view instanceof KeyguardWidgetFrame) {
-            removeView(view);
-        } else {
-            // Assume view was wrapped by a KeyguardWidgetFrame in KeyguardWidgetPager#addWidget().
-            // This supports legacy hard-coded "widgets" like KeyguardTransportControlView.
-            int pos = getWidgetPageIndex(view);
-            if (pos != -1) {
-                KeyguardWidgetFrame frame = (KeyguardWidgetFrame) getChildAt(pos);
-                frame.removeView(view);
-                removeView(frame);
-            } else {
-                Slog.w(TAG, "removeWidget() can't find:" + view);
-            }
-        }
-    }
-
-    public int getWidgetPageIndex(View view) {
-        if (view instanceof KeyguardWidgetFrame) {
-            return indexOfChild(view);
-        } else {
-            // View was wrapped by a KeyguardWidgetFrame by KeyguardWidgetPager#addWidget()
-            return indexOfChild((KeyguardWidgetFrame)view.getParent());
-        }
-    }
-
-    @Override
-    protected void setPageHoveringOverDeleteDropTarget(int viewIndex, boolean isHovering) {
-        KeyguardWidgetFrame child = getWidgetPageAt(viewIndex);
-        child.setIsHoveringOverDeleteDropTarget(isHovering);
-    }
-
-    // ChallengeLayout.OnBouncerStateChangedListener
-    @Override
-    public void onBouncerStateChanged(boolean bouncerActive) {
-        if (bouncerActive) {
-            zoomOutToBouncer();
-        } else {
-            zoomInFromBouncer();
-        }
-    }
-
-    void setBouncerAnimationDuration(int duration) {
-        mBouncerZoomInOutDuration = duration;
-    }
-
-    // Zoom in after the bouncer is dismissed
-    void zoomInFromBouncer() {
-        if (mZoomInOutAnim != null && mZoomInOutAnim.isRunning()) {
-            mZoomInOutAnim.cancel();
-        }
-        final View currentPage = getPageAt(getCurrentPage());
-        if (currentPage.getScaleX() < 1f || currentPage.getScaleY() < 1f) {
-            mZoomInOutAnim = new AnimatorSet();
-            mZoomInOutAnim.playTogether(
-                    ObjectAnimator.ofFloat(currentPage, "scaleX", 1f),
-                    ObjectAnimator.ofFloat(currentPage , "scaleY", 1f));
-            mZoomInOutAnim.setDuration(mBouncerZoomInOutDuration);
-            mZoomInOutAnim.setInterpolator(new DecelerateInterpolator(1.5f));
-            mZoomInOutAnim.start();
-        }
-        if (currentPage instanceof KeyguardWidgetFrame) {
-            ((KeyguardWidgetFrame)currentPage).onBouncerShowing(false);
-        }
-    }
-
-    // Zoom out after the bouncer is initiated
-    void zoomOutToBouncer() {
-        if (mZoomInOutAnim != null && mZoomInOutAnim.isRunning()) {
-            mZoomInOutAnim.cancel();
-        }
-        int curPage = getCurrentPage();
-        View currentPage = getPageAt(curPage);
-        if (shouldSetTopAlignedPivotForWidget(curPage)) {
-            currentPage.setPivotY(0);
-            // Note: we are working around the issue that setting the x-pivot to the same value as it
-            //       was does not actually work.
-            currentPage.setPivotX(0);
-            currentPage.setPivotX(currentPage.getMeasuredWidth() / 2);
-        }
-        if (!(currentPage.getScaleX() < 1f || currentPage.getScaleY() < 1f)) {
-            mZoomInOutAnim = new AnimatorSet();
-            mZoomInOutAnim.playTogether(
-                    ObjectAnimator.ofFloat(currentPage, "scaleX", BOUNCER_SCALE_FACTOR),
-                    ObjectAnimator.ofFloat(currentPage, "scaleY", BOUNCER_SCALE_FACTOR));
-            mZoomInOutAnim.setDuration(mBouncerZoomInOutDuration);
-            mZoomInOutAnim.setInterpolator(new DecelerateInterpolator(1.5f));
-            mZoomInOutAnim.start();
-        }
-        if (currentPage instanceof KeyguardWidgetFrame) {
-            ((KeyguardWidgetFrame)currentPage).onBouncerShowing(true);
-        }
-    }
-
-    void setAddWidgetEnabled(boolean enabled) {
-        if (mAddWidgetView != null && enabled) {
-            addView(mAddWidgetView, 0);
-            // We need to force measure the PagedView so that the calls to update the scroll
-            // position below work
-            measure(mLastWidthMeasureSpec, mLastHeightMeasureSpec);
-            // Bump up the current page to account for the addition of the new page
-            setCurrentPage(mCurrentPage + 1);
-            mAddWidgetView = null;
-        } else if (mAddWidgetView == null && !enabled) {
-            View addWidget = findViewById(com.android.internal.R.id.keyguard_add_widget);
-            if (addWidget != null) {
-                mAddWidgetView = addWidget;
-                removeView(addWidget);
-            }
-        }
-    }
-
-    boolean isAddPage(int pageIndex) {
-        View v = getChildAt(pageIndex);
-        return v != null && v.getId() == com.android.internal.R.id.keyguard_add_widget;
-    }
-
-    boolean isCameraPage(int pageIndex) {
-        View v = getChildAt(pageIndex);
-        return v != null && v instanceof CameraWidgetFrame;
-    }
-
-    @Override
-    protected boolean shouldSetTopAlignedPivotForWidget(int childIndex) {
-        return !isCameraPage(childIndex) && super.shouldSetTopAlignedPivotForWidget(childIndex);
-    }
-
-    /**
-     * Search given {@link View} hierarchy for {@link TextClock} instances that
-     * show various time components. Returns combination of
-     * {@link #FLAG_HAS_LOCAL_HOUR} and {@link #FLAG_HAS_LOCAL_MINUTE}.
-     */
-    private static int findClockInHierarchy(View view) {
-        if (view instanceof TextClock) {
-            return getClockFlags((TextClock) view);
-        } else if (view instanceof ViewGroup) {
-            int flags = 0;
-            final ViewGroup group = (ViewGroup) view;
-            final int size = group.getChildCount();
-            for (int i = 0; i < size; i++) {
-                flags |= findClockInHierarchy(group.getChildAt(i));
-            }
-            return flags;
-        } else {
-            return 0;
-        }
-    }
-
-    /**
-     * Return combination of {@link #FLAG_HAS_LOCAL_HOUR} and
-     * {@link #FLAG_HAS_LOCAL_MINUTE} describing the time represented described
-     * by the given {@link TextClock}.
-     */
-    private static int getClockFlags(TextClock clock) {
-        int flags = 0;
-
-        final String timeZone = clock.getTimeZone();
-        if (timeZone != null && !TimeZone.getDefault().equals(TimeZone.getTimeZone(timeZone))) {
-            // Ignore clocks showing another timezone
-            return 0;
-        }
-
-        final CharSequence format = clock.getFormat();
-        final char hour = clock.is24HourModeEnabled() ? DateFormat.HOUR_OF_DAY
-                : DateFormat.HOUR;
-
-        if (DateFormat.hasDesignator(format, hour)) {
-            flags |= FLAG_HAS_LOCAL_HOUR;
-        }
-        if (DateFormat.hasDesignator(format, DateFormat.MINUTE)) {
-            flags |= FLAG_HAS_LOCAL_MINUTE;
-        }
-
-        return flags;
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/LiftToActivateListener.java b/policy/src/com/android/internal/policy/impl/keyguard/LiftToActivateListener.java
deleted file mode 100644
index 818108c..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/LiftToActivateListener.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.policy.impl.keyguard;
-
-import android.content.Context;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.accessibility.AccessibilityManager;
-
-/**
- * Hover listener that implements lift-to-activate interaction for
- * accessibility. May be added to multiple views.
- */
-class LiftToActivateListener implements View.OnHoverListener {
-    /** Manager used to query accessibility enabled state. */
-    private final AccessibilityManager mAccessibilityManager;
-
-    private boolean mCachedClickableState;
-
-    public LiftToActivateListener(Context context) {
-        mAccessibilityManager = (AccessibilityManager) context.getSystemService(
-                Context.ACCESSIBILITY_SERVICE);
-    }
-
-    @Override
-    public boolean onHover(View v, MotionEvent event) {
-        // When touch exploration is turned on, lifting a finger while
-        // inside the view bounds should perform a click action.
-        if (mAccessibilityManager.isEnabled()
-                && mAccessibilityManager.isTouchExplorationEnabled()) {
-            switch (event.getActionMasked()) {
-                case MotionEvent.ACTION_HOVER_ENTER:
-                    // Lift-to-type temporarily disables double-tap
-                    // activation by setting the view as not clickable.
-                    mCachedClickableState = v.isClickable();
-                    v.setClickable(false);
-                    break;
-                case MotionEvent.ACTION_HOVER_EXIT:
-                    final int x = (int) event.getX();
-                    final int y = (int) event.getY();
-                    if ((x > v.getPaddingLeft()) && (y > v.getPaddingTop())
-                            && (x < v.getWidth() - v.getPaddingRight())
-                            && (y < v.getHeight() - v.getPaddingBottom())) {
-                        v.performClick();
-                    }
-                    v.setClickable(mCachedClickableState);
-                    break;
-            }
-        }
-
-        // Pass the event to View.onHoverEvent() to handle accessibility.
-        v.onHoverEvent(event);
-
-        // Consume the event so it doesn't fall through to other views.
-        return true;
-    }
-}
\ No newline at end of file
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/MultiPaneChallengeLayout.java b/policy/src/com/android/internal/policy/impl/keyguard/MultiPaneChallengeLayout.java
deleted file mode 100644
index 0ca46c3..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/MultiPaneChallengeLayout.java
+++ /dev/null
@@ -1,566 +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.internal.policy.impl.keyguard;
-
-import com.android.internal.R;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
-import android.content.Context;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.view.Gravity;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.LinearLayout;
-
-public class MultiPaneChallengeLayout extends ViewGroup implements ChallengeLayout {
-    private static final String TAG = "MultiPaneChallengeLayout";
-
-    final int mOrientation;
-    private boolean mIsBouncing;
-
-    public static final int HORIZONTAL = LinearLayout.HORIZONTAL;
-    public static final int VERTICAL = LinearLayout.VERTICAL;
-    public static final int ANIMATE_BOUNCE_DURATION = 350;
-
-    private KeyguardSecurityContainer mChallengeView;
-    private View mUserSwitcherView;
-    private View mScrimView;
-    private OnBouncerStateChangedListener mBouncerListener;
-
-    private final Rect mTempRect = new Rect();
-    private final Rect mZeroPadding = new Rect();
-
-    private final DisplayMetrics mDisplayMetrics;
-
-    private final OnClickListener mScrimClickListener = new OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            hideBouncer();
-        }
-    };
-
-    public MultiPaneChallengeLayout(Context context) {
-        this(context, null);
-    }
-
-    public MultiPaneChallengeLayout(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public MultiPaneChallengeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-
-        final TypedArray a = context.obtainStyledAttributes(attrs,
-                R.styleable.MultiPaneChallengeLayout, defStyleAttr, 0);
-        mOrientation = a.getInt(R.styleable.MultiPaneChallengeLayout_orientation,
-                HORIZONTAL);
-        a.recycle();
-
-        final Resources res = getResources();
-        mDisplayMetrics = res.getDisplayMetrics();
-
-        setSystemUiVisibility(SYSTEM_UI_FLAG_LAYOUT_STABLE);
-    }
-
-    @Override
-    public boolean isChallengeShowing() {
-        return true;
-    }
-
-    @Override
-    public boolean isChallengeOverlapping() {
-        return false;
-    }
-
-    @Override
-    public void showChallenge(boolean b) {
-    }
-
-    @Override
-    public int getBouncerAnimationDuration() {
-        return ANIMATE_BOUNCE_DURATION;
-    }
-
-    @Override
-    public void showBouncer() {
-        if (mIsBouncing) return;
-        mIsBouncing = true;
-        if (mScrimView != null) {
-            if (mChallengeView != null) {
-                mChallengeView.showBouncer(ANIMATE_BOUNCE_DURATION);
-            }
-
-            Animator anim = ObjectAnimator.ofFloat(mScrimView, "alpha", 1f);
-            anim.setDuration(ANIMATE_BOUNCE_DURATION);
-            anim.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationStart(Animator animation) {
-                    mScrimView.setVisibility(VISIBLE);
-                }
-            });
-            anim.start();
-        }
-        if (mBouncerListener != null) {
-            mBouncerListener.onBouncerStateChanged(true);
-        }
-    }
-
-    @Override
-    public void hideBouncer() {
-        if (!mIsBouncing) return;
-        mIsBouncing = false;
-        if (mScrimView != null) {
-            if (mChallengeView != null) {
-                mChallengeView.hideBouncer(ANIMATE_BOUNCE_DURATION);
-            }
-
-            Animator anim = ObjectAnimator.ofFloat(mScrimView, "alpha", 0f);
-            anim.setDuration(ANIMATE_BOUNCE_DURATION);
-            anim.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    mScrimView.setVisibility(INVISIBLE);
-                }
-            });
-            anim.start();
-        }
-        if (mBouncerListener != null) {
-            mBouncerListener.onBouncerStateChanged(false);
-        }
-    }
-
-    @Override
-    public boolean isBouncing() {
-        return mIsBouncing;
-    }
-
-    @Override
-    public void setOnBouncerStateChangedListener(OnBouncerStateChangedListener listener) {
-        mBouncerListener = listener;
-    }
-
-    @Override
-    public void requestChildFocus(View child, View focused) {
-        if (mIsBouncing && child != mChallengeView) {
-            // Clear out of the bouncer if the user tries to move focus outside of
-            // the security challenge view.
-            hideBouncer();
-        }
-        super.requestChildFocus(child, focused);
-    }
-
-    void setScrimView(View scrim) {
-        if (mScrimView != null) {
-            mScrimView.setOnClickListener(null);
-        }
-        mScrimView = scrim;
-        mScrimView.setAlpha(mIsBouncing ? 1.0f : 0.0f);
-        mScrimView.setVisibility(mIsBouncing ? VISIBLE : INVISIBLE);
-        mScrimView.setFocusable(true);
-        mScrimView.setOnClickListener(mScrimClickListener);
-    }
-
-    private int getVirtualHeight(LayoutParams lp, int height, int heightUsed) {
-        int virtualHeight = height;
-        final View root = getRootView();
-        if (root != null) {
-            // This calculation is super dodgy and relies on several assumptions.
-            // Specifically that the root of the window will be padded in for insets
-            // and that the window is LAYOUT_IN_SCREEN.
-            virtualHeight = mDisplayMetrics.heightPixels - root.getPaddingTop();
-        }
-        if (lp.childType == LayoutParams.CHILD_TYPE_WIDGET ||
-                lp.childType == LayoutParams.CHILD_TYPE_USER_SWITCHER) {
-            // Always measure the widget pager/user switcher as if there were no IME insets
-            // on the window. We want to avoid resizing widgets when possible as it can
-            // be ugly/expensive. This lets us simply clip them instead.
-            return virtualHeight - heightUsed;
-        } else if (lp.childType == LayoutParams.CHILD_TYPE_PAGE_DELETE_DROP_TARGET) {
-            return height;
-        }
-        return Math.min(virtualHeight - heightUsed, height);
-    }
-
-    @Override
-    protected void onMeasure(final int widthSpec, final int heightSpec) {
-        if (MeasureSpec.getMode(widthSpec) != MeasureSpec.EXACTLY ||
-                MeasureSpec.getMode(heightSpec) != MeasureSpec.EXACTLY) {
-            throw new IllegalArgumentException(
-                    "MultiPaneChallengeLayout must be measured with an exact size");
-        }
-
-        final int width = MeasureSpec.getSize(widthSpec);
-        final int height = MeasureSpec.getSize(heightSpec);
-        setMeasuredDimension(width, height);
-
-        int widthUsed = 0;
-        int heightUsed = 0;
-
-        // First pass. Find the challenge view and measure the user switcher,
-        // which consumes space in the layout.
-        mChallengeView = null;
-        mUserSwitcherView = null;
-        final int count = getChildCount();
-        for (int i = 0; i < count; i++) {
-            final View child = getChildAt(i);
-            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
-
-            if (lp.childType == LayoutParams.CHILD_TYPE_CHALLENGE) {
-                if (mChallengeView != null) {
-                    throw new IllegalStateException(
-                            "There may only be one child of type challenge");
-                }
-                if (!(child instanceof KeyguardSecurityContainer)) {
-                    throw new IllegalArgumentException(
-                            "Challenge must be a KeyguardSecurityContainer");
-                }
-                mChallengeView = (KeyguardSecurityContainer) child;
-            } else if (lp.childType == LayoutParams.CHILD_TYPE_USER_SWITCHER) {
-                if (mUserSwitcherView != null) {
-                    throw new IllegalStateException(
-                            "There may only be one child of type userSwitcher");
-                }
-                mUserSwitcherView = child;
-
-                if (child.getVisibility() == GONE) continue;
-
-                int adjustedWidthSpec = widthSpec;
-                int adjustedHeightSpec = heightSpec;
-                if (lp.maxWidth >= 0) {
-                    adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
-                            Math.min(lp.maxWidth, width), MeasureSpec.EXACTLY);
-                }
-                if (lp.maxHeight >= 0) {
-                    adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
-                            Math.min(lp.maxHeight, height), MeasureSpec.EXACTLY);
-                }
-                // measureChildWithMargins will resolve layout direction for the LayoutParams
-                measureChildWithMargins(child, adjustedWidthSpec, 0, adjustedHeightSpec, 0);
-
-                // Only subtract out space from one dimension. Favor vertical.
-                // Offset by 1.5x to add some balance along the other edge.
-                if (Gravity.isVertical(lp.gravity)) {
-                    heightUsed += child.getMeasuredHeight() * 1.5f;
-                } else if (Gravity.isHorizontal(lp.gravity)) {
-                    widthUsed += child.getMeasuredWidth() * 1.5f;
-                }
-            } else if (lp.childType == LayoutParams.CHILD_TYPE_SCRIM) {
-                setScrimView(child);
-                child.measure(widthSpec, heightSpec);
-            }
-        }
-
-        // Second pass. Measure everything that's left.
-        for (int i = 0; i < count; i++) {
-            final View child = getChildAt(i);
-            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
-
-            if (lp.childType == LayoutParams.CHILD_TYPE_USER_SWITCHER ||
-                    lp.childType == LayoutParams.CHILD_TYPE_SCRIM ||
-                    child.getVisibility() == GONE) {
-                // Don't need to measure GONE children, and the user switcher was already measured.
-                continue;
-            }
-
-            final int virtualHeight = getVirtualHeight(lp, height, heightUsed);
-
-            int adjustedWidthSpec;
-            int adjustedHeightSpec;
-            if (lp.centerWithinArea > 0) {
-                if (mOrientation == HORIZONTAL) {
-                    adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
-                            (int) ((width - widthUsed) * lp.centerWithinArea + 0.5f),
-                            MeasureSpec.EXACTLY);
-                    adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
-                            virtualHeight, MeasureSpec.EXACTLY);
-                } else {
-                    adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
-                            width - widthUsed, MeasureSpec.EXACTLY);
-                    adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
-                            (int) (virtualHeight * lp.centerWithinArea + 0.5f),
-                            MeasureSpec.EXACTLY);
-                }
-            } else {
-                adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
-                        width - widthUsed, MeasureSpec.EXACTLY);
-                adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
-                        virtualHeight, MeasureSpec.EXACTLY);
-            }
-            if (lp.maxWidth >= 0) {
-                adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
-                        Math.min(lp.maxWidth, MeasureSpec.getSize(adjustedWidthSpec)),
-                        MeasureSpec.EXACTLY);
-            }
-            if (lp.maxHeight >= 0) {
-                adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
-                        Math.min(lp.maxHeight, MeasureSpec.getSize(adjustedHeightSpec)),
-                        MeasureSpec.EXACTLY);
-            }
-
-            measureChildWithMargins(child, adjustedWidthSpec, 0, adjustedHeightSpec, 0);
-        }
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int l, int t, int r, int b) {
-        final Rect padding = mTempRect;
-        padding.left = getPaddingLeft();
-        padding.top = getPaddingTop();
-        padding.right = getPaddingRight();
-        padding.bottom = getPaddingBottom();
-        final int width = r - l;
-        final int height = b - t;
-
-        // Reserve extra space in layout for the user switcher by modifying
-        // local padding during this layout pass
-        if (mUserSwitcherView != null && mUserSwitcherView.getVisibility() != GONE) {
-            layoutWithGravity(width, height, mUserSwitcherView, padding, true);
-        }
-
-        final int count = getChildCount();
-        for (int i = 0; i < count; i++) {
-            final View child = getChildAt(i);
-            LayoutParams lp = (LayoutParams) child.getLayoutParams();
-
-            // We did the user switcher above if we have one.
-            if (child == mUserSwitcherView || child.getVisibility() == GONE) continue;
-
-            if (child == mScrimView) {
-                child.layout(0, 0, width, height);
-                continue;
-            } else if (lp.childType == LayoutParams.CHILD_TYPE_PAGE_DELETE_DROP_TARGET) {
-                layoutWithGravity(width, height, child, mZeroPadding, false);
-                continue;
-            }
-
-            layoutWithGravity(width, height, child, padding, false);
-        }
-    }
-
-    private void layoutWithGravity(int width, int height, View child, Rect padding,
-            boolean adjustPadding) {
-        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
-
-        final int heightUsed = padding.top + padding.bottom - getPaddingTop() - getPaddingBottom();
-        height = getVirtualHeight(lp, height, heightUsed);
-
-        final int gravity = Gravity.getAbsoluteGravity(lp.gravity, getLayoutDirection());
-
-        final boolean fixedLayoutSize = lp.centerWithinArea > 0;
-        final boolean fixedLayoutHorizontal = fixedLayoutSize && mOrientation == HORIZONTAL;
-        final boolean fixedLayoutVertical = fixedLayoutSize && mOrientation == VERTICAL;
-
-        final int adjustedWidth;
-        final int adjustedHeight;
-        if (fixedLayoutHorizontal) {
-            final int paddedWidth = width - padding.left - padding.right;
-            adjustedWidth = (int) (paddedWidth * lp.centerWithinArea + 0.5f);
-            adjustedHeight = height;
-        } else if (fixedLayoutVertical) {
-            final int paddedHeight = height - getPaddingTop() - getPaddingBottom();
-            adjustedWidth = width;
-            adjustedHeight = (int) (paddedHeight * lp.centerWithinArea + 0.5f);
-        } else {
-            adjustedWidth = width;
-            adjustedHeight = height;
-        }
-
-        final boolean isVertical = Gravity.isVertical(gravity);
-        final boolean isHorizontal = Gravity.isHorizontal(gravity);
-        final int childWidth = child.getMeasuredWidth();
-        final int childHeight = child.getMeasuredHeight();
-
-        int left = padding.left;
-        int top = padding.top;
-        int right = left + childWidth;
-        int bottom = top + childHeight;
-        switch (gravity & Gravity.VERTICAL_GRAVITY_MASK) {
-            case Gravity.TOP:
-                top = fixedLayoutVertical ?
-                        padding.top + (adjustedHeight - childHeight) / 2 : padding.top;
-                bottom = top + childHeight;
-                if (adjustPadding && isVertical) {
-                    padding.top = bottom;
-                    padding.bottom += childHeight / 2;
-                }
-                break;
-            case Gravity.BOTTOM:
-                bottom = fixedLayoutVertical
-                        ? padding.top + height - (adjustedHeight - childHeight) / 2
-                        : padding.top + height;
-                top = bottom - childHeight;
-                if (adjustPadding && isVertical) {
-                    padding.bottom = height - top;
-                    padding.top += childHeight / 2;
-                }
-                break;
-            case Gravity.CENTER_VERTICAL:
-                top = padding.top + (height - childHeight) / 2;
-                bottom = top + childHeight;
-                break;
-        }
-        switch (gravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
-            case Gravity.LEFT:
-                left = fixedLayoutHorizontal ?
-                        padding.left + (adjustedWidth - childWidth) / 2 : padding.left;
-                right = left + childWidth;
-                if (adjustPadding && isHorizontal && !isVertical) {
-                    padding.left = right;
-                    padding.right += childWidth / 2;
-                }
-                break;
-            case Gravity.RIGHT:
-                right = fixedLayoutHorizontal
-                        ? width - padding.right - (adjustedWidth - childWidth) / 2
-                        : width - padding.right;
-                left = right - childWidth;
-                if (adjustPadding && isHorizontal && !isVertical) {
-                    padding.right = width - left;
-                    padding.left += childWidth / 2;
-                }
-                break;
-            case Gravity.CENTER_HORIZONTAL:
-                final int paddedWidth = width - padding.left - padding.right;
-                left = (paddedWidth - childWidth) / 2;
-                right = left + childWidth;
-                break;
-        }
-        child.layout(left, top, right, bottom);
-    }
-
-    @Override
-    public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
-        return new LayoutParams(getContext(), attrs, this);
-    }
-
-    @Override
-    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
-        return p instanceof LayoutParams ? new LayoutParams((LayoutParams) p) :
-                p instanceof MarginLayoutParams ? new LayoutParams((MarginLayoutParams) p) :
-                new LayoutParams(p);
-    }
-
-    @Override
-    protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
-        return new LayoutParams();
-    }
-
-    @Override
-    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
-        return p instanceof LayoutParams;
-    }
-
-    public static class LayoutParams extends MarginLayoutParams {
-
-        public float centerWithinArea = 0;
-
-        public int childType = 0;
-
-        public static final int CHILD_TYPE_NONE = 0;
-        public static final int CHILD_TYPE_WIDGET = 1;
-        public static final int CHILD_TYPE_CHALLENGE = 2;
-        public static final int CHILD_TYPE_USER_SWITCHER = 3;
-        public static final int CHILD_TYPE_SCRIM = 4;
-        public static final int CHILD_TYPE_PAGE_DELETE_DROP_TARGET = 7;
-
-        public int gravity = Gravity.NO_GRAVITY;
-
-        public int maxWidth = -1;
-        public int maxHeight = -1;
-
-        public LayoutParams() {
-            this(WRAP_CONTENT, WRAP_CONTENT);
-        }
-
-        LayoutParams(Context c, AttributeSet attrs, MultiPaneChallengeLayout parent) {
-            super(c, attrs);
-
-            final TypedArray a = c.obtainStyledAttributes(attrs,
-                    R.styleable.MultiPaneChallengeLayout_Layout);
-
-            centerWithinArea = a.getFloat(
-                    R.styleable.MultiPaneChallengeLayout_Layout_layout_centerWithinArea, 0);
-            childType = a.getInt(R.styleable.MultiPaneChallengeLayout_Layout_layout_childType,
-                    CHILD_TYPE_NONE);
-            gravity = a.getInt(R.styleable.MultiPaneChallengeLayout_Layout_layout_gravity,
-                    Gravity.NO_GRAVITY);
-            maxWidth = a.getDimensionPixelSize(
-                    R.styleable.MultiPaneChallengeLayout_Layout_layout_maxWidth, -1);
-            maxHeight = a.getDimensionPixelSize(
-                    R.styleable.MultiPaneChallengeLayout_Layout_layout_maxHeight, -1);
-
-            // Default gravity settings based on type and parent orientation
-            if (gravity == Gravity.NO_GRAVITY) {
-                if (parent.mOrientation == HORIZONTAL) {
-                    switch (childType) {
-                        case CHILD_TYPE_WIDGET:
-                            gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL;
-                            break;
-                        case CHILD_TYPE_CHALLENGE:
-                            gravity = Gravity.RIGHT | Gravity.CENTER_VERTICAL;
-                            break;
-                        case CHILD_TYPE_USER_SWITCHER:
-                            gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
-                            break;
-                    }
-                } else {
-                    switch (childType) {
-                        case CHILD_TYPE_WIDGET:
-                            gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
-                            break;
-                        case CHILD_TYPE_CHALLENGE:
-                            gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
-                            break;
-                        case CHILD_TYPE_USER_SWITCHER:
-                            gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
-                            break;
-                    }
-                }
-            }
-
-            a.recycle();
-        }
-
-        public LayoutParams(int width, int height) {
-            super(width, height);
-        }
-
-        public LayoutParams(ViewGroup.LayoutParams source) {
-            super(source);
-        }
-
-        public LayoutParams(MarginLayoutParams source) {
-            super(source);
-        }
-
-        public LayoutParams(LayoutParams source) {
-            this((MarginLayoutParams) source);
-
-            centerWithinArea = source.centerWithinArea;
-            childType = source.childType;
-            gravity = source.gravity;
-            maxWidth = source.maxWidth;
-            maxHeight = source.maxHeight;
-        }
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/MultiUserAvatarCache.java b/policy/src/com/android/internal/policy/impl/keyguard/MultiUserAvatarCache.java
deleted file mode 100644
index 7969c7d..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/MultiUserAvatarCache.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 com.android.internal.policy.impl.keyguard;
-
-import android.graphics.drawable.Drawable;
-
-import java.util.HashMap;
-
-public class MultiUserAvatarCache {
-
-    private final HashMap<Integer, Drawable> mCache;
-
-    public MultiUserAvatarCache() {
-        mCache = new HashMap<Integer, Drawable>();
-    }
-
-    public void clear(int userId) {
-        mCache.remove(userId);
-    }
-
-    public Drawable get(int userId) {
-        return mCache.get(userId);
-    }
-
-    public void put(int userId, Drawable image) {
-        mCache.put(userId, image);
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/NumPadKey.java b/policy/src/com/android/internal/policy/impl/keyguard/NumPadKey.java
deleted file mode 100644
index a0038bc..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/NumPadKey.java
+++ /dev/null
@@ -1,128 +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.internal.policy.impl.keyguard;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.text.SpannableStringBuilder;
-import android.text.style.TextAppearanceSpan;
-import android.util.AttributeSet;
-import android.view.HapticFeedbackConstants;
-import android.view.View;
-import android.widget.Button;
-import android.widget.TextView;
-
-import com.android.internal.R;
-import com.android.internal.widget.LockPatternUtils;
-
-public class NumPadKey extends Button {
-    // list of "ABC", etc per digit, starting with '0'
-    static String sKlondike[];
-
-    int mDigit = -1;
-    int mTextViewResId;
-    TextView mTextView = null;
-    boolean mEnableHaptics;
-
-    private View.OnClickListener mListener = new View.OnClickListener() {
-        @Override
-        public void onClick(View thisView) {
-            if (mTextView == null) {
-                if (mTextViewResId > 0) {
-                    final View v = NumPadKey.this.getRootView().findViewById(mTextViewResId);
-                    if (v != null && v instanceof TextView) {
-                        mTextView = (TextView) v;
-                    }
-                }
-            }
-            // check for time-based lockouts
-            if (mTextView != null && mTextView.isEnabled()) {
-                mTextView.append(String.valueOf(mDigit));
-            }
-            doHapticKeyClick();
-        }
-    };
-
-    public NumPadKey(Context context) {
-        this(context, null);
-    }
-
-    public NumPadKey(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public NumPadKey(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NumPadKey);
-        mDigit = a.getInt(R.styleable.NumPadKey_digit, mDigit);
-        setTextViewResId(a.getResourceId(R.styleable.NumPadKey_textView, 0));
-
-        setOnClickListener(mListener);
-        setOnHoverListener(new LiftToActivateListener(context));
-        setAccessibilityDelegate(new ObscureSpeechDelegate(context));
-
-        mEnableHaptics = new LockPatternUtils(context).isTactileFeedbackEnabled();
-
-        SpannableStringBuilder builder = new SpannableStringBuilder();
-        builder.append(String.valueOf(mDigit));
-        if (mDigit >= 0) {
-            if (sKlondike == null) {
-                sKlondike = context.getResources().getStringArray(
-                        R.array.lockscreen_num_pad_klondike);
-            }
-            if (sKlondike != null && sKlondike.length > mDigit) {
-                final String extra = sKlondike[mDigit];
-                final int extraLen = extra.length();
-                if (extraLen > 0) {
-                    builder.append(" ");
-                    builder.append(extra);
-                    builder.setSpan(
-                        new TextAppearanceSpan(context, R.style.TextAppearance_NumPadKey_Klondike),
-                        builder.length()-extraLen, builder.length(), 0);
-                }
-            }
-        }
-        setText(builder);
-    }
-
-    @Override
-    public void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-
-        // Reset the "announced headset" flag when detached.
-        ObscureSpeechDelegate.sAnnouncedHeadset = false;
-    }
-
-    public void setTextView(TextView tv) {
-        mTextView = tv;
-    }
-
-    public void setTextViewResId(int resId) {
-        mTextView = null;
-        mTextViewResId = resId;
-    }
-
-    // Cause a VIRTUAL_KEY vibration
-    public void doHapticKeyClick() {
-        if (mEnableHaptics) {
-            performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
-                    HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING
-                    | HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
-        }
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/ObscureSpeechDelegate.java b/policy/src/com/android/internal/policy/impl/keyguard/ObscureSpeechDelegate.java
deleted file mode 100644
index af043ab..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/ObscureSpeechDelegate.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.policy.impl.keyguard;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.media.AudioManager;
-import android.provider.Settings;
-import android.view.View;
-import android.view.View.AccessibilityDelegate;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityNodeInfo;
-
-import com.android.internal.R;
-
-/**
- * Accessibility delegate that obscures speech for a view when the user has
- * not turned on the "speak passwords" preference and is not listening
- * through headphones.
- */
-class ObscureSpeechDelegate extends AccessibilityDelegate {
-    /** Whether any client has announced the "headset" notification. */
-    static boolean sAnnouncedHeadset = false;
-
-    private final ContentResolver mContentResolver;
-    private final AudioManager mAudioManager;
-
-    public ObscureSpeechDelegate(Context context) {
-        mContentResolver = context.getContentResolver();
-        mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
-    }
-
-    @Override
-    public void sendAccessibilityEvent(View host, int eventType) {
-        super.sendAccessibilityEvent(host, eventType);
-
-        // Play the "headset required" announcement the first time the user
-        // places accessibility focus on a key.
-        if ((eventType == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED)
-                && !sAnnouncedHeadset && shouldObscureSpeech()) {
-            sAnnouncedHeadset = true;
-            host.announceForAccessibility(host.getContext().getString(
-                    R.string.keyboard_headset_required_to_hear_password));
-        }
-    }
-
-    @Override
-    public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
-        super.onPopulateAccessibilityEvent(host, event);
-
-        if ((event.getEventType() != AccessibilityEvent.TYPE_ANNOUNCEMENT)
-                && shouldObscureSpeech()) {
-            event.getText().clear();
-            event.setContentDescription(host.getContext().getString(
-                    R.string.keyboard_password_character_no_headset));
-        }
-    }
-
-    @Override
-    public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
-        super.onInitializeAccessibilityNodeInfo(host, info);
-
-        if (shouldObscureSpeech()) {
-            final Context ctx = host.getContext();
-            info.setText(null);
-            info.setContentDescription(
-                    ctx.getString(R.string.keyboard_password_character_no_headset));
-        }
-    }
-
-    @SuppressWarnings("deprecation")
-    private boolean shouldObscureSpeech() {
-        // The user can optionally force speaking passwords.
-        if (Settings.Secure.getInt(mContentResolver,
-                Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD, 0) != 0) {
-            return false;
-        }
-
-        // Always speak if the user is listening through headphones.
-        if (mAudioManager.isWiredHeadsetOn() || mAudioManager.isBluetoothA2dpOn()) {
-            return false;
-        }
-
-        // Don't speak since this key is used to type a password.
-        return true;
-    }
-}
\ No newline at end of file
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java b/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java
deleted file mode 100644
index 10562e8..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java
+++ /dev/null
@@ -1,2569 +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.internal.policy.impl.keyguard;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.animation.TimeInterpolator;
-import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
-import android.content.Context;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.Matrix;
-import android.graphics.PointF;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.view.InputDevice;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.VelocityTracker;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.ViewGroup;
-import android.view.ViewParent;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
-import android.view.accessibility.AccessibilityNodeInfo;
-import android.view.animation.AnimationUtils;
-import android.view.animation.DecelerateInterpolator;
-import android.view.animation.Interpolator;
-import android.view.animation.LinearInterpolator;
-import android.widget.Scroller;
-
-import com.android.internal.R;
-
-import java.util.ArrayList;
-
-/**
- * An abstraction of the original Workspace which supports browsing through a
- * sequential list of "pages"
- */
-public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarchyChangeListener {
-    private static final String TAG = "WidgetPagedView";
-    private static final boolean DEBUG = false;
-    protected static final int INVALID_PAGE = -1;
-
-    // the min drag distance for a fling to register, to prevent random page shifts
-    private static final int MIN_LENGTH_FOR_FLING = 25;
-
-    protected static final int PAGE_SNAP_ANIMATION_DURATION = 750;
-    protected static final int SLOW_PAGE_SNAP_ANIMATION_DURATION = 950;
-    protected static final float NANOTIME_DIV = 1000000000.0f;
-
-    private static final float OVERSCROLL_ACCELERATE_FACTOR = 2;
-    private static final float OVERSCROLL_DAMP_FACTOR = 0.14f;
-
-    private static final float RETURN_TO_ORIGINAL_PAGE_THRESHOLD = 0.33f;
-    // The page is moved more than halfway, automatically move to the next page on touch up.
-    private static final float SIGNIFICANT_MOVE_THRESHOLD = 0.4f;
-
-    // The following constants need to be scaled based on density. The scaled versions will be
-    // assigned to the corresponding member variables below.
-    private static final int FLING_THRESHOLD_VELOCITY = 500;
-    private static final int MIN_SNAP_VELOCITY = 1500;
-    private static final int MIN_FLING_VELOCITY = 250;
-
-    // We are disabling touch interaction of the widget region for factory ROM.
-    private static final boolean DISABLE_TOUCH_INTERACTION = false;
-    private static final boolean DISABLE_TOUCH_SIDE_PAGES = true;
-    private static final boolean DISABLE_FLING_TO_DELETE = false;
-
-    static final int AUTOMATIC_PAGE_SPACING = -1;
-
-    protected int mFlingThresholdVelocity;
-    protected int mMinFlingVelocity;
-    protected int mMinSnapVelocity;
-
-    protected float mDensity;
-    protected float mSmoothingTime;
-    protected float mTouchX;
-
-    protected boolean mFirstLayout = true;
-
-    protected int mCurrentPage;
-    protected int mChildCountOnLastMeasure;
-
-    protected int mNextPage = INVALID_PAGE;
-    protected int mMaxScrollX;
-    protected Scroller mScroller;
-    private VelocityTracker mVelocityTracker;
-
-    private float mParentDownMotionX;
-    private float mParentDownMotionY;
-    private float mDownMotionX;
-    private float mDownMotionY;
-    private float mDownScrollX;
-    protected float mLastMotionX;
-    protected float mLastMotionXRemainder;
-    protected float mLastMotionY;
-    protected float mTotalMotionX;
-    private int mLastScreenCenter = -1;
-    private int[] mChildOffsets;
-    private int[] mChildRelativeOffsets;
-    private int[] mChildOffsetsWithLayoutScale;
-
-    protected final static int TOUCH_STATE_REST = 0;
-    protected final static int TOUCH_STATE_SCROLLING = 1;
-    protected final static int TOUCH_STATE_PREV_PAGE = 2;
-    protected final static int TOUCH_STATE_NEXT_PAGE = 3;
-    protected final static int TOUCH_STATE_REORDERING = 4;
-
-    protected final static float ALPHA_QUANTIZE_LEVEL = 0.0001f;
-
-    protected int mTouchState = TOUCH_STATE_REST;
-    protected boolean mForceScreenScrolled = false;
-
-    protected OnLongClickListener mLongClickListener;
-
-    protected int mTouchSlop;
-    private int mPagingTouchSlop;
-    private int mMaximumVelocity;
-    private int mMinimumWidth;
-    protected int mPageSpacing;
-    protected int mCellCountX = 0;
-    protected int mCellCountY = 0;
-    protected boolean mAllowOverScroll = true;
-    protected int mUnboundedScrollX;
-    protected int[] mTempVisiblePagesRange = new int[2];
-    protected boolean mForceDrawAllChildrenNextFrame;
-
-    // mOverScrollX is equal to getScrollX() when we're within the normal scroll range. Otherwise
-    // it is equal to the scaled overscroll position. We use a separate value so as to prevent
-    // the screens from continuing to translate beyond the normal bounds.
-    protected int mOverScrollX;
-
-    // parameter that adjusts the layout to be optimized for pages with that scale factor
-    protected float mLayoutScale = 1.0f;
-
-    protected static final int INVALID_POINTER = -1;
-
-    protected int mActivePointerId = INVALID_POINTER;
-
-    private PageSwitchListener mPageSwitchListener;
-
-    protected ArrayList<Boolean> mDirtyPageContent;
-
-    // If true, syncPages and syncPageItems will be called to refresh pages
-    protected boolean mContentIsRefreshable = true;
-
-    // If true, modify alpha of neighboring pages as user scrolls left/right
-    protected boolean mFadeInAdjacentScreens = false;
-
-    // It true, use a different slop parameter (pagingTouchSlop = 2 * touchSlop) for deciding
-    // to switch to a new page
-    protected boolean mUsePagingTouchSlop = true;
-
-    // If true, the subclass should directly update scrollX itself in its computeScroll method
-    // (SmoothPagedView does this)
-    protected boolean mDeferScrollUpdate = false;
-
-    protected boolean mIsPageMoving = false;
-
-    // All syncs and layout passes are deferred until data is ready.
-    protected boolean mIsDataReady = true;
-
-    // Scrolling indicator
-    private ValueAnimator mScrollIndicatorAnimator;
-    private View mScrollIndicator;
-    private int mScrollIndicatorPaddingLeft;
-    private int mScrollIndicatorPaddingRight;
-    private boolean mShouldShowScrollIndicator = false;
-    private boolean mShouldShowScrollIndicatorImmediately = false;
-    protected static final int sScrollIndicatorFadeInDuration = 150;
-    protected static final int sScrollIndicatorFadeOutDuration = 650;
-    protected static final int sScrollIndicatorFlashDuration = 650;
-
-    // The viewport whether the pages are to be contained (the actual view may be larger than the
-    // viewport)
-    private Rect mViewport = new Rect();
-
-    // Reordering
-    // We use the min scale to determine how much to expand the actually PagedView measured
-    // dimensions such that when we are zoomed out, the view is not clipped
-    private int REORDERING_DROP_REPOSITION_DURATION = 200;
-    protected int REORDERING_REORDER_REPOSITION_DURATION = 300;
-    protected int REORDERING_ZOOM_IN_OUT_DURATION = 250;
-    private int REORDERING_SIDE_PAGE_HOVER_TIMEOUT = 300;
-    private float REORDERING_SIDE_PAGE_BUFFER_PERCENTAGE = 0.1f;
-    private long REORDERING_DELETE_DROP_TARGET_FADE_DURATION = 150;
-    private float mMinScale = 1f;
-    protected View mDragView;
-    protected AnimatorSet mZoomInOutAnim;
-    private Runnable mSidePageHoverRunnable;
-    private int mSidePageHoverIndex = -1;
-    // This variable's scope is only for the duration of startReordering() and endReordering()
-    private boolean mReorderingStarted = false;
-    // This variable's scope is for the duration of startReordering() and after the zoomIn()
-    // animation after endReordering()
-    private boolean mIsReordering;
-    // The runnable that settles the page after snapToPage and animateDragViewToOriginalPosition
-    private int NUM_ANIMATIONS_RUNNING_BEFORE_ZOOM_OUT = 2;
-    private int mPostReorderingPreZoomInRemainingAnimationCount;
-    private Runnable mPostReorderingPreZoomInRunnable;
-
-    // Edge swiping
-    private boolean mOnlyAllowEdgeSwipes = false;
-    private boolean mDownEventOnEdge = false;
-    private int mEdgeSwipeRegionSize = 0;
-
-    // Convenience/caching
-    private Matrix mTmpInvMatrix = new Matrix();
-    private float[] mTmpPoint = new float[2];
-    private Rect mTmpRect = new Rect();
-    private Rect mAltTmpRect = new Rect();
-
-    // Fling to delete
-    private int FLING_TO_DELETE_FADE_OUT_DURATION = 350;
-    private float FLING_TO_DELETE_FRICTION = 0.035f;
-    // The degrees specifies how much deviation from the up vector to still consider a fling "up"
-    private float FLING_TO_DELETE_MAX_FLING_DEGREES = 65f;
-    protected int mFlingToDeleteThresholdVelocity = -1400;
-    // Drag to delete
-    private boolean mDeferringForDelete = false;
-    private int DELETE_SLIDE_IN_SIDE_PAGE_DURATION = 250;
-    private int DRAG_TO_DELETE_FADE_OUT_DURATION = 350;
-
-    // Drop to delete
-    private View mDeleteDropTarget;
-
-    // Bouncer
-    private boolean mTopAlignPageWhenShrinkingForBouncer = false;
-
-    public interface PageSwitchListener {
-        void onPageSwitching(View newPage, int newPageIndex);
-        void onPageSwitched(View newPage, int newPageIndex);
-    }
-
-    public PagedView(Context context) {
-        this(context, null);
-    }
-
-    public PagedView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public PagedView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                R.styleable.PagedView, defStyle, 0);
-        setPageSpacing(a.getDimensionPixelSize(R.styleable.PagedView_pageSpacing, 0));
-        mScrollIndicatorPaddingLeft =
-            a.getDimensionPixelSize(R.styleable.PagedView_scrollIndicatorPaddingLeft, 0);
-        mScrollIndicatorPaddingRight =
-                a.getDimensionPixelSize(R.styleable.PagedView_scrollIndicatorPaddingRight, 0);
-        a.recycle();
-
-        Resources r = getResources();
-        mEdgeSwipeRegionSize = r.getDimensionPixelSize(R.dimen.kg_edge_swipe_region_size);
-        mTopAlignPageWhenShrinkingForBouncer =
-                r.getBoolean(R.bool.kg_top_align_page_shrink_on_bouncer_visible);
-
-        setHapticFeedbackEnabled(false);
-        init();
-    }
-
-    /**
-     * Initializes various states for this workspace.
-     */
-    protected void init() {
-        mDirtyPageContent = new ArrayList<Boolean>();
-        mDirtyPageContent.ensureCapacity(32);
-        mScroller = new Scroller(getContext(), new ScrollInterpolator());
-        mCurrentPage = 0;
-
-        final ViewConfiguration configuration = ViewConfiguration.get(getContext());
-        mTouchSlop = configuration.getScaledTouchSlop();
-        mPagingTouchSlop = configuration.getScaledPagingTouchSlop();
-        mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
-        mDensity = getResources().getDisplayMetrics().density;
-
-        // Scale the fling-to-delete threshold by the density
-        mFlingToDeleteThresholdVelocity =
-                (int) (mFlingToDeleteThresholdVelocity * mDensity);
-
-        mFlingThresholdVelocity = (int) (FLING_THRESHOLD_VELOCITY * mDensity);
-        mMinFlingVelocity = (int) (MIN_FLING_VELOCITY * mDensity);
-        mMinSnapVelocity = (int) (MIN_SNAP_VELOCITY * mDensity);
-        setOnHierarchyChangeListener(this);
-    }
-
-    void setDeleteDropTarget(View v) {
-        mDeleteDropTarget = v;
-    }
-
-    // Convenience methods to map points from self to parent and vice versa
-    float[] mapPointFromViewToParent(View v, float x, float y) {
-        mTmpPoint[0] = x;
-        mTmpPoint[1] = y;
-        v.getMatrix().mapPoints(mTmpPoint);
-        mTmpPoint[0] += v.getLeft();
-        mTmpPoint[1] += v.getTop();
-        return mTmpPoint;
-    }
-    float[] mapPointFromParentToView(View v, float x, float y) {
-        mTmpPoint[0] = x - v.getLeft();
-        mTmpPoint[1] = y - v.getTop();
-        v.getMatrix().invert(mTmpInvMatrix);
-        mTmpInvMatrix.mapPoints(mTmpPoint);
-        return mTmpPoint;
-    }
-
-    void updateDragViewTranslationDuringDrag() {
-        float x = mLastMotionX - mDownMotionX + getScrollX() - mDownScrollX;
-        float y = mLastMotionY - mDownMotionY;
-        mDragView.setTranslationX(x);
-        mDragView.setTranslationY(y);
-
-        if (DEBUG) Log.d(TAG, "PagedView.updateDragViewTranslationDuringDrag(): " + x + ", " + y);
-    }
-
-    public void setMinScale(float f) {
-        mMinScale = f;
-        requestLayout();
-    }
-
-    @Override
-    public void setScaleX(float scaleX) {
-        super.setScaleX(scaleX);
-        if (isReordering(true)) {
-            float[] p = mapPointFromParentToView(this, mParentDownMotionX, mParentDownMotionY);
-            mLastMotionX = p[0];
-            mLastMotionY = p[1];
-            updateDragViewTranslationDuringDrag();
-        }
-    }
-
-    // Convenience methods to get the actual width/height of the PagedView (since it is measured
-    // to be larger to account for the minimum possible scale)
-    int getViewportWidth() {
-        return mViewport.width();
-    }
-    int getViewportHeight() {
-        return mViewport.height();
-    }
-
-    // Convenience methods to get the offset ASSUMING that we are centering the pages in the
-    // PagedView both horizontally and vertically
-    int getViewportOffsetX() {
-        return (getMeasuredWidth() - getViewportWidth()) / 2;
-    }
-    int getViewportOffsetY() {
-        return (getMeasuredHeight() - getViewportHeight()) / 2;
-    }
-
-    public void setPageSwitchListener(PageSwitchListener pageSwitchListener) {
-        mPageSwitchListener = pageSwitchListener;
-        if (mPageSwitchListener != null) {
-            mPageSwitchListener.onPageSwitched(getPageAt(mCurrentPage), mCurrentPage);
-        }
-    }
-
-    /**
-     * Called by subclasses to mark that data is ready, and that we can begin loading and laying
-     * out pages.
-     */
-    protected void setDataIsReady() {
-        mIsDataReady = true;
-    }
-
-    protected boolean isDataReady() {
-        return mIsDataReady;
-    }
-
-    /**
-     * Returns the index of the currently displayed page.
-     *
-     * @return The index of the currently displayed page.
-     */
-    int getCurrentPage() {
-        return mCurrentPage;
-    }
-
-    int getNextPage() {
-        return (mNextPage != INVALID_PAGE) ? mNextPage : mCurrentPage;
-    }
-
-    int getPageCount() {
-        return getChildCount();
-    }
-
-    View getPageAt(int index) {
-        return getChildAt(index);
-    }
-
-    protected int indexToPage(int index) {
-        return index;
-    }
-
-    /**
-     * Updates the scroll of the current page immediately to its final scroll position.  We use this
-     * in CustomizePagedView to allow tabs to share the same PagedView while resetting the scroll of
-     * the previous tab page.
-     */
-    protected void updateCurrentPageScroll() {
-        int offset = getChildOffset(mCurrentPage);
-        int relOffset = getRelativeChildOffset(mCurrentPage);
-        int newX = offset - relOffset;
-        scrollTo(newX, 0);
-        mScroller.setFinalX(newX);
-        mScroller.forceFinished(true);
-    }
-
-    /**
-     * Sets the current page.
-     */
-    void setCurrentPage(int currentPage) {
-        notifyPageSwitching(currentPage);
-        if (!mScroller.isFinished()) {
-            mScroller.abortAnimation();
-        }
-        // don't introduce any checks like mCurrentPage == currentPage here-- if we change the
-        // the default
-        if (getChildCount() == 0) {
-            return;
-        }
-
-        mForceScreenScrolled = true;
-        mCurrentPage = Math.max(0, Math.min(currentPage, getPageCount() - 1));
-        updateCurrentPageScroll();
-        updateScrollingIndicator();
-        notifyPageSwitched();
-        invalidate();
-    }
-
-    public void setOnlyAllowEdgeSwipes(boolean enable) {
-        mOnlyAllowEdgeSwipes = enable;
-    }
-
-    protected void notifyPageSwitching(int whichPage) {
-        if (mPageSwitchListener != null) {
-            mPageSwitchListener.onPageSwitching(getPageAt(whichPage), whichPage);
-        }
-    }
-
-    protected void notifyPageSwitched() {
-        if (mPageSwitchListener != null) {
-            mPageSwitchListener.onPageSwitched(getPageAt(mCurrentPage), mCurrentPage);
-        }
-    }
-
-    protected void pageBeginMoving() {
-        if (!mIsPageMoving) {
-            mIsPageMoving = true;
-            onPageBeginMoving();
-        }
-    }
-
-    protected void pageEndMoving() {
-        if (mIsPageMoving) {
-            mIsPageMoving = false;
-            onPageEndMoving();
-        }
-    }
-
-    protected boolean isPageMoving() {
-        return mIsPageMoving;
-    }
-
-    // a method that subclasses can override to add behavior
-    protected void onPageBeginMoving() {
-    }
-
-    // a method that subclasses can override to add behavior
-    protected void onPageEndMoving() {
-    }
-
-    /**
-     * Registers the specified listener on each page contained in this workspace.
-     *
-     * @param l The listener used to respond to long clicks.
-     */
-    @Override
-    public void setOnLongClickListener(OnLongClickListener l) {
-        mLongClickListener = l;
-        final int count = getPageCount();
-        for (int i = 0; i < count; i++) {
-            getPageAt(i).setOnLongClickListener(l);
-        }
-    }
-
-    @Override
-    public void scrollBy(int x, int y) {
-        scrollTo(mUnboundedScrollX + x, getScrollY() + y);
-    }
-
-    @Override
-    public void scrollTo(int x, int y) {
-        mUnboundedScrollX = x;
-
-        if (x < 0) {
-            super.scrollTo(0, y);
-            if (mAllowOverScroll) {
-                overScroll(x);
-            }
-        } else if (x > mMaxScrollX) {
-            super.scrollTo(mMaxScrollX, y);
-            if (mAllowOverScroll) {
-                overScroll(x - mMaxScrollX);
-            }
-        } else {
-            mOverScrollX = x;
-            super.scrollTo(x, y);
-        }
-
-        mTouchX = x;
-        mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
-
-        // Update the last motion events when scrolling
-        if (isReordering(true)) {
-            float[] p = mapPointFromParentToView(this, mParentDownMotionX, mParentDownMotionY);
-            mLastMotionX = p[0];
-            mLastMotionY = p[1];
-            updateDragViewTranslationDuringDrag();
-        }
-    }
-
-    // we moved this functionality to a helper function so SmoothPagedView can reuse it
-    protected boolean computeScrollHelper() {
-        if (mScroller.computeScrollOffset()) {
-            // Don't bother scrolling if the page does not need to be moved
-            if (getScrollX() != mScroller.getCurrX()
-                || getScrollY() != mScroller.getCurrY()
-                || mOverScrollX != mScroller.getCurrX()) {
-                scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
-            }
-            invalidate();
-            return true;
-        } else if (mNextPage != INVALID_PAGE) {
-            mCurrentPage = Math.max(0, Math.min(mNextPage, getPageCount() - 1));
-            mNextPage = INVALID_PAGE;
-            notifyPageSwitched();
-
-            // We don't want to trigger a page end moving unless the page has settled
-            // and the user has stopped scrolling
-            if (mTouchState == TOUCH_STATE_REST) {
-                pageEndMoving();
-            }
-
-            onPostReorderingAnimationCompleted();
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public void computeScroll() {
-        computeScrollHelper();
-    }
-
-    protected boolean shouldSetTopAlignedPivotForWidget(int childIndex) {
-        return mTopAlignPageWhenShrinkingForBouncer;
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        if (!mIsDataReady || getChildCount() == 0) {
-            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-            return;
-        }
-
-        // We measure the dimensions of the PagedView to be larger than the pages so that when we
-        // zoom out (and scale down), the view is still contained in the parent
-        View parent = (View) getParent();
-        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
-        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
-        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
-        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
-        // NOTE: We multiply by 1.5f to account for the fact that depending on the offset of the
-        // viewport, we can be at most one and a half screens offset once we scale down
-        DisplayMetrics dm = getResources().getDisplayMetrics();
-        int maxSize = Math.max(dm.widthPixels, dm.heightPixels);
-        int parentWidthSize = (int) (1.5f * maxSize);
-        int parentHeightSize = maxSize;
-        int scaledWidthSize = (int) (parentWidthSize / mMinScale);
-        int scaledHeightSize = (int) (parentHeightSize / mMinScale);
-        mViewport.set(0, 0, widthSize, heightSize);
-
-        if (widthMode == MeasureSpec.UNSPECIFIED || heightMode == MeasureSpec.UNSPECIFIED) {
-            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-            return;
-        }
-
-        // Return early if we aren't given a proper dimension
-        if (widthSize <= 0 || heightSize <= 0) {
-            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-            return;
-        }
-
-        /* Allow the height to be set as WRAP_CONTENT. This allows the particular case
-         * of the All apps view on XLarge displays to not take up more space then it needs. Width
-         * is still not allowed to be set as WRAP_CONTENT since many parts of the code expect
-         * each page to have the same width.
-         */
-        final int verticalPadding = getPaddingTop() + getPaddingBottom();
-        final int horizontalPadding = getPaddingLeft() + getPaddingRight();
-
-        // The children are given the same width and height as the workspace
-        // unless they were set to WRAP_CONTENT
-        if (DEBUG) Log.d(TAG, "PagedView.onMeasure(): " + widthSize + ", " + heightSize);
-        if (DEBUG) Log.d(TAG, "PagedView.scaledSize: " + scaledWidthSize + ", " + scaledHeightSize);
-        if (DEBUG) Log.d(TAG, "PagedView.parentSize: " + parentWidthSize + ", " + parentHeightSize);
-        if (DEBUG) Log.d(TAG, "PagedView.horizontalPadding: " + horizontalPadding);
-        if (DEBUG) Log.d(TAG, "PagedView.verticalPadding: " + verticalPadding);
-        final int childCount = getChildCount();
-        for (int i = 0; i < childCount; i++) {
-            // disallowing padding in paged view (just pass 0)
-            final View child = getPageAt(i);
-            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
-
-            int childWidthMode;
-            if (lp.width == LayoutParams.WRAP_CONTENT) {
-                childWidthMode = MeasureSpec.AT_MOST;
-            } else {
-                childWidthMode = MeasureSpec.EXACTLY;
-            }
-
-            int childHeightMode;
-            if (lp.height == LayoutParams.WRAP_CONTENT) {
-                childHeightMode = MeasureSpec.AT_MOST;
-            } else {
-                childHeightMode = MeasureSpec.EXACTLY;
-            }
-
-            final int childWidthMeasureSpec =
-                MeasureSpec.makeMeasureSpec(widthSize - horizontalPadding, childWidthMode);
-            final int childHeightMeasureSpec =
-                MeasureSpec.makeMeasureSpec(heightSize - verticalPadding, childHeightMode);
-
-            child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
-        }
-        setMeasuredDimension(scaledWidthSize, scaledHeightSize);
-
-        // We can't call getChildOffset/getRelativeChildOffset until we set the measured dimensions.
-        // We also wait until we set the measured dimensions before flushing the cache as well, to
-        // ensure that the cache is filled with good values.
-        invalidateCachedOffsets();
-
-        if (mChildCountOnLastMeasure != getChildCount() && !mDeferringForDelete) {
-            setCurrentPage(mCurrentPage);
-        }
-        mChildCountOnLastMeasure = getChildCount();
-
-        if (childCount > 0) {
-            if (DEBUG) Log.d(TAG, "getRelativeChildOffset(): " + getViewportWidth() + ", "
-                    + getChildWidth(0));
-
-            // Calculate the variable page spacing if necessary
-            if (mPageSpacing == AUTOMATIC_PAGE_SPACING) {
-                // The gap between pages in the PagedView should be equal to the gap from the page
-                // to the edge of the screen (so it is not visible in the current screen).  To
-                // account for unequal padding on each side of the paged view, we take the maximum
-                // of the left/right gap and use that as the gap between each page.
-                int offset = getRelativeChildOffset(0);
-                int spacing = Math.max(offset, widthSize - offset -
-                        getChildAt(0).getMeasuredWidth());
-                setPageSpacing(spacing);
-            }
-        }
-
-        updateScrollingIndicatorPosition();
-
-        if (childCount > 0) {
-            mMaxScrollX = getChildOffset(childCount - 1) - getRelativeChildOffset(childCount - 1);
-        } else {
-            mMaxScrollX = 0;
-        }
-    }
-
-    public void setPageSpacing(int pageSpacing) {
-        mPageSpacing = pageSpacing;
-        invalidateCachedOffsets();
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        if (!mIsDataReady || getChildCount() == 0) {
-            return;
-        }
-
-        if (DEBUG) Log.d(TAG, "PagedView.onLayout()");
-        final int childCount = getChildCount();
-
-        int offsetX = getViewportOffsetX();
-        int offsetY = getViewportOffsetY();
-
-        // Update the viewport offsets
-        mViewport.offset(offsetX,  offsetY);
-
-        int childLeft = offsetX + getRelativeChildOffset(0);
-        for (int i = 0; i < childCount; i++) {
-            final View child = getPageAt(i);
-            int childTop = offsetY + getPaddingTop();
-            if (child.getVisibility() != View.GONE) {
-                final int childWidth = getScaledMeasuredWidth(child);
-                final int childHeight = child.getMeasuredHeight();
-
-                if (DEBUG) Log.d(TAG, "\tlayout-child" + i + ": " + childLeft + ", " + childTop);
-                child.layout(childLeft, childTop,
-                        childLeft + child.getMeasuredWidth(), childTop + childHeight);
-                childLeft += childWidth + mPageSpacing;
-            }
-        }
-
-        if (mFirstLayout && mCurrentPage >= 0 && mCurrentPage < getChildCount()) {
-            setHorizontalScrollBarEnabled(false);
-            updateCurrentPageScroll();
-            setHorizontalScrollBarEnabled(true);
-            mFirstLayout = false;
-        }
-    }
-
-    protected void screenScrolled(int screenCenter) {
-    }
-
-    @Override
-    public void onChildViewAdded(View parent, View child) {
-        // This ensures that when children are added, they get the correct transforms / alphas
-        // in accordance with any scroll effects.
-        mForceScreenScrolled = true;
-        invalidate();
-        invalidateCachedOffsets();
-    }
-
-    @Override
-    public void onChildViewRemoved(View parent, View child) {
-        mForceScreenScrolled = true;
-        invalidate();
-        invalidateCachedOffsets();
-    }
-
-    protected void invalidateCachedOffsets() {
-        int count = getChildCount();
-        if (count == 0) {
-            mChildOffsets = null;
-            mChildRelativeOffsets = null;
-            mChildOffsetsWithLayoutScale = null;
-            return;
-        }
-
-        mChildOffsets = new int[count];
-        mChildRelativeOffsets = new int[count];
-        mChildOffsetsWithLayoutScale = new int[count];
-        for (int i = 0; i < count; i++) {
-            mChildOffsets[i] = -1;
-            mChildRelativeOffsets[i] = -1;
-            mChildOffsetsWithLayoutScale[i] = -1;
-        }
-    }
-
-    protected int getChildOffset(int index) {
-        if (index < 0 || index > getChildCount() - 1) return 0;
-
-        int[] childOffsets = Float.compare(mLayoutScale, 1f) == 0 ?
-                mChildOffsets : mChildOffsetsWithLayoutScale;
-
-        if (childOffsets != null && childOffsets[index] != -1) {
-            return childOffsets[index];
-        } else {
-            if (getChildCount() == 0)
-                return 0;
-
-            int offset = getRelativeChildOffset(0);
-            for (int i = 0; i < index; ++i) {
-                offset += getScaledMeasuredWidth(getPageAt(i)) + mPageSpacing;
-            }
-            if (childOffsets != null) {
-                childOffsets[index] = offset;
-            }
-            return offset;
-        }
-    }
-
-    protected int getRelativeChildOffset(int index) {
-        if (index < 0 || index > getChildCount() - 1) return 0;
-
-        if (mChildRelativeOffsets != null && mChildRelativeOffsets[index] != -1) {
-            return mChildRelativeOffsets[index];
-        } else {
-            final int padding = getPaddingLeft() + getPaddingRight();
-            final int offset = getPaddingLeft() +
-                    (getViewportWidth() - padding - getChildWidth(index)) / 2;
-            if (mChildRelativeOffsets != null) {
-                mChildRelativeOffsets[index] = offset;
-            }
-            return offset;
-        }
-    }
-
-    protected int getScaledMeasuredWidth(View child) {
-        // This functions are called enough times that it actually makes a difference in the
-        // profiler -- so just inline the max() here
-        final int measuredWidth = child.getMeasuredWidth();
-        final int minWidth = mMinimumWidth;
-        final int maxWidth = (minWidth > measuredWidth) ? minWidth : measuredWidth;
-        return (int) (maxWidth * mLayoutScale + 0.5f);
-    }
-
-    void boundByReorderablePages(boolean isReordering, int[] range) {
-        // Do nothing
-    }
-
-    // TODO: Fix this
-    protected void getVisiblePages(int[] range) {
-        range[0] = 0;
-        range[1] = getPageCount() - 1;
-
-        /*
-        final int pageCount = getChildCount();
-
-        if (pageCount > 0) {
-            final int screenWidth = getViewportWidth();
-            int leftScreen = 0;
-            int rightScreen = 0;
-            int offsetX = getViewportOffsetX() + getScrollX();
-            View currPage = getPageAt(leftScreen);
-            while (leftScreen < pageCount - 1 &&
-                    currPage.getX() + currPage.getWidth() -
-                    currPage.getPaddingRight() < offsetX) {
-                leftScreen++;
-                currPage = getPageAt(leftScreen);
-            }
-            rightScreen = leftScreen;
-            currPage = getPageAt(rightScreen + 1);
-            while (rightScreen < pageCount - 1 &&
-                    currPage.getX() - currPage.getPaddingLeft() < offsetX + screenWidth) {
-                rightScreen++;
-                currPage = getPageAt(rightScreen + 1);
-            }
-
-            // TEMP: this is a hacky way to ensure that animations to new pages are not clipped
-            // because we don't draw them while scrolling?
-            range[0] = Math.max(0, leftScreen - 1);
-            range[1] = Math.min(rightScreen + 1, getChildCount() - 1);
-        } else {
-            range[0] = -1;
-            range[1] = -1;
-        }
-        */
-    }
-
-    protected boolean shouldDrawChild(View child) {
-        return child.getAlpha() > 0;
-    }
-
-    @Override
-    protected void dispatchDraw(Canvas canvas) {
-        int halfScreenSize = getViewportWidth() / 2;
-        // mOverScrollX is equal to getScrollX() when we're within the normal scroll range.
-        // Otherwise it is equal to the scaled overscroll position.
-        int screenCenter = mOverScrollX + halfScreenSize;
-
-        if (screenCenter != mLastScreenCenter || mForceScreenScrolled) {
-            // set mForceScreenScrolled before calling screenScrolled so that screenScrolled can
-            // set it for the next frame
-            mForceScreenScrolled = false;
-            screenScrolled(screenCenter);
-            mLastScreenCenter = screenCenter;
-        }
-
-        // Find out which screens are visible; as an optimization we only call draw on them
-        final int pageCount = getChildCount();
-        if (pageCount > 0) {
-            getVisiblePages(mTempVisiblePagesRange);
-            final int leftScreen = mTempVisiblePagesRange[0];
-            final int rightScreen = mTempVisiblePagesRange[1];
-            if (leftScreen != -1 && rightScreen != -1) {
-                final long drawingTime = getDrawingTime();
-                // Clip to the bounds
-                canvas.save();
-                canvas.clipRect(getScrollX(), getScrollY(), getScrollX() + getRight() - getLeft(),
-                        getScrollY() + getBottom() - getTop());
-
-                // Draw all the children, leaving the drag view for last
-                for (int i = pageCount - 1; i >= 0; i--) {
-                    final View v = getPageAt(i);
-                    if (v == mDragView) continue;
-                    if (mForceDrawAllChildrenNextFrame ||
-                               (leftScreen <= i && i <= rightScreen && shouldDrawChild(v))) {
-                        drawChild(canvas, v, drawingTime);
-                    }
-                }
-                // Draw the drag view on top (if there is one)
-                if (mDragView != null) {
-                    drawChild(canvas, mDragView, drawingTime);
-                }
-
-                mForceDrawAllChildrenNextFrame = false;
-                canvas.restore();
-            }
-        }
-    }
-
-    @Override
-    public boolean requestChildRectangleOnScreen(View child, Rect rectangle, boolean immediate) {
-        int page = indexToPage(indexOfChild(child));
-        if (page != mCurrentPage || !mScroller.isFinished()) {
-            snapToPage(page);
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
-        int focusablePage;
-        if (mNextPage != INVALID_PAGE) {
-            focusablePage = mNextPage;
-        } else {
-            focusablePage = mCurrentPage;
-        }
-        View v = getPageAt(focusablePage);
-        if (v != null) {
-            return v.requestFocus(direction, previouslyFocusedRect);
-        }
-        return false;
-    }
-
-    @Override
-    public boolean dispatchUnhandledMove(View focused, int direction) {
-        if (direction == View.FOCUS_LEFT) {
-            if (getCurrentPage() > 0) {
-                snapToPage(getCurrentPage() - 1);
-                return true;
-            }
-        } else if (direction == View.FOCUS_RIGHT) {
-            if (getCurrentPage() < getPageCount() - 1) {
-                snapToPage(getCurrentPage() + 1);
-                return true;
-            }
-        }
-        return super.dispatchUnhandledMove(focused, direction);
-    }
-
-    @Override
-    public void addFocusables(ArrayList<View> views, int direction, int focusableMode) {
-        if (mCurrentPage >= 0 && mCurrentPage < getPageCount()) {
-            getPageAt(mCurrentPage).addFocusables(views, direction, focusableMode);
-        }
-        if (direction == View.FOCUS_LEFT) {
-            if (mCurrentPage > 0) {
-                getPageAt(mCurrentPage - 1).addFocusables(views, direction, focusableMode);
-            }
-        } else if (direction == View.FOCUS_RIGHT){
-            if (mCurrentPage < getPageCount() - 1) {
-                getPageAt(mCurrentPage + 1).addFocusables(views, direction, focusableMode);
-            }
-        }
-    }
-
-    /**
-     * If one of our descendant views decides that it could be focused now, only
-     * pass that along if it's on the current page.
-     *
-     * This happens when live folders requery, and if they're off page, they
-     * end up calling requestFocus, which pulls it on page.
-     */
-    @Override
-    public void focusableViewAvailable(View focused) {
-        View current = getPageAt(mCurrentPage);
-        View v = focused;
-        while (true) {
-            if (v == current) {
-                super.focusableViewAvailable(focused);
-                return;
-            }
-            if (v == this) {
-                return;
-            }
-            ViewParent parent = v.getParent();
-            if (parent instanceof View) {
-                v = (View)v.getParent();
-            } else {
-                return;
-            }
-        }
-    }
-
-    /**
-     * Return true if a tap at (x, y) should trigger a flip to the previous page.
-     */
-    protected boolean hitsPreviousPage(float x, float y) {
-        return (x < getViewportOffsetX() + getRelativeChildOffset(mCurrentPage) - mPageSpacing);
-    }
-
-    /**
-     * Return true if a tap at (x, y) should trigger a flip to the next page.
-     */
-    protected boolean hitsNextPage(float x, float y) {
-        return  (x > (getViewportOffsetX() + getViewportWidth() - getRelativeChildOffset(mCurrentPage) + mPageSpacing));
-    }
-
-    /** Returns whether x and y originated within the buffered viewport */
-    private boolean isTouchPointInViewportWithBuffer(int x, int y) {
-        mTmpRect.set(mViewport.left - mViewport.width() / 2, mViewport.top,
-                mViewport.right + mViewport.width() / 2, mViewport.bottom);
-        return mTmpRect.contains(x, y);
-    }
-
-    /** Returns whether x and y originated within the current page view bounds */
-    private boolean isTouchPointInCurrentPage(int x, int y) {
-        View v = getPageAt(getCurrentPage());
-        if (v != null) {
-            mTmpRect.set((v.getLeft() - getScrollX()), 0, (v.getRight() - getScrollX()),
-                    v.getBottom());
-            return mTmpRect.contains(x, y);
-        }
-        return false;
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-        if (DISABLE_TOUCH_INTERACTION) {
-            return false;
-        }
-
-        /*
-         * This method JUST determines whether we want to intercept the motion.
-         * If we return true, onTouchEvent will be called and we do the actual
-         * scrolling there.
-         */
-        acquireVelocityTrackerAndAddMovement(ev);
-
-        // Skip touch handling if there are no pages to swipe
-        if (getChildCount() <= 0) return super.onInterceptTouchEvent(ev);
-
-        /*
-         * Shortcut the most recurring case: the user is in the dragging
-         * state and he is moving his finger.  We want to intercept this
-         * motion.
-         */
-        final int action = ev.getAction();
-        if ((action == MotionEvent.ACTION_MOVE) &&
-                (mTouchState == TOUCH_STATE_SCROLLING)) {
-            return true;
-        }
-
-        switch (action & MotionEvent.ACTION_MASK) {
-            case MotionEvent.ACTION_MOVE: {
-                /*
-                 * mIsBeingDragged == false, otherwise the shortcut would have caught it. Check
-                 * whether the user has moved far enough from his original down touch.
-                 */
-                if (mActivePointerId != INVALID_POINTER) {
-                    determineScrollingStart(ev);
-                    break;
-                }
-                // if mActivePointerId is INVALID_POINTER, then we must have missed an ACTION_DOWN
-                // event. in that case, treat the first occurence of a move event as a ACTION_DOWN
-                // i.e. fall through to the next case (don't break)
-                // (We sometimes miss ACTION_DOWN events in Workspace because it ignores all events
-                // while it's small- this was causing a crash before we checked for INVALID_POINTER)
-            }
-
-            case MotionEvent.ACTION_DOWN: {
-                final float x = ev.getX();
-                final float y = ev.getY();
-                // Remember location of down touch
-                mDownMotionX = x;
-                mDownMotionY = y;
-                mDownScrollX = getScrollX();
-                mLastMotionX = x;
-                mLastMotionY = y;
-                float[] p = mapPointFromViewToParent(this, x, y);
-                mParentDownMotionX = p[0];
-                mParentDownMotionY = p[1];
-                mLastMotionXRemainder = 0;
-                mTotalMotionX = 0;
-                mActivePointerId = ev.getPointerId(0);
-
-                // Determine if the down event is within the threshold to be an edge swipe
-                int leftEdgeBoundary = getViewportOffsetX() + mEdgeSwipeRegionSize;
-                int rightEdgeBoundary = getMeasuredWidth() - getViewportOffsetX() - mEdgeSwipeRegionSize;
-                if ((mDownMotionX <= leftEdgeBoundary || mDownMotionX >= rightEdgeBoundary)) {
-                    mDownEventOnEdge = true;
-                }
-
-                /*
-                 * If being flinged and user touches the screen, initiate drag;
-                 * otherwise don't.  mScroller.isFinished should be false when
-                 * being flinged.
-                 */
-                final int xDist = Math.abs(mScroller.getFinalX() - mScroller.getCurrX());
-                final boolean finishedScrolling = (mScroller.isFinished() || xDist < mTouchSlop);
-                if (finishedScrolling) {
-                    mTouchState = TOUCH_STATE_REST;
-                    mScroller.abortAnimation();
-                } else {
-                    if (isTouchPointInViewportWithBuffer((int) mDownMotionX, (int) mDownMotionY)) {
-                        mTouchState = TOUCH_STATE_SCROLLING;
-                    } else {
-                        mTouchState = TOUCH_STATE_REST;
-                    }
-                }
-
-                // check if this can be the beginning of a tap on the side of the pages
-                // to scroll the current page
-                if (!DISABLE_TOUCH_SIDE_PAGES) {
-                    if (mTouchState != TOUCH_STATE_PREV_PAGE && mTouchState != TOUCH_STATE_NEXT_PAGE) {
-                        if (getChildCount() > 0) {
-                            if (hitsPreviousPage(x, y)) {
-                                mTouchState = TOUCH_STATE_PREV_PAGE;
-                            } else if (hitsNextPage(x, y)) {
-                                mTouchState = TOUCH_STATE_NEXT_PAGE;
-                            }
-                        }
-                    }
-                }
-                break;
-            }
-
-            case MotionEvent.ACTION_UP:
-            case MotionEvent.ACTION_CANCEL:
-                resetTouchState();
-                // Just intercept the touch event on up if we tap outside the strict viewport
-                if (!isTouchPointInCurrentPage((int) mLastMotionX, (int) mLastMotionY)) {
-                    return true;
-                }
-                break;
-
-            case MotionEvent.ACTION_POINTER_UP:
-                onSecondaryPointerUp(ev);
-                releaseVelocityTracker();
-                break;
-        }
-
-        /*
-         * The only time we want to intercept motion events is if we are in the
-         * drag mode.
-         */
-        return mTouchState != TOUCH_STATE_REST;
-    }
-
-    protected void determineScrollingStart(MotionEvent ev) {
-        determineScrollingStart(ev, 1.0f);
-    }
-
-    /*
-     * Determines if we should change the touch state to start scrolling after the
-     * user moves their touch point too far.
-     */
-    protected void determineScrollingStart(MotionEvent ev, float touchSlopScale) {
-        // Disallow scrolling if we don't have a valid pointer index
-        final int pointerIndex = ev.findPointerIndex(mActivePointerId);
-        if (pointerIndex == -1) return;
-
-        // Disallow scrolling if we started the gesture from outside the viewport
-        final float x = ev.getX(pointerIndex);
-        final float y = ev.getY(pointerIndex);
-        if (!isTouchPointInViewportWithBuffer((int) x, (int) y)) return;
-
-        // If we're only allowing edge swipes, we break out early if the down event wasn't
-        // at the edge.
-        if (mOnlyAllowEdgeSwipes && !mDownEventOnEdge) return;
-
-        final int xDiff = (int) Math.abs(x - mLastMotionX);
-        final int yDiff = (int) Math.abs(y - mLastMotionY);
-
-        final int touchSlop = Math.round(touchSlopScale * mTouchSlop);
-        boolean xPaged = xDiff > mPagingTouchSlop;
-        boolean xMoved = xDiff > touchSlop;
-        boolean yMoved = yDiff > touchSlop;
-
-        if (xMoved || xPaged || yMoved) {
-            if (mUsePagingTouchSlop ? xPaged : xMoved) {
-                // Scroll if the user moved far enough along the X axis
-                mTouchState = TOUCH_STATE_SCROLLING;
-                mTotalMotionX += Math.abs(mLastMotionX - x);
-                mLastMotionX = x;
-                mLastMotionXRemainder = 0;
-                mTouchX = getViewportOffsetX() + getScrollX();
-                mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
-                pageBeginMoving();
-            }
-        }
-    }
-
-    protected float getMaxScrollProgress() {
-        return 1.0f;
-    }
-
-    protected float getBoundedScrollProgress(int screenCenter, View v, int page) {
-        final int halfScreenSize = getViewportWidth() / 2;
-
-        screenCenter = Math.min(mScrollX + halfScreenSize, screenCenter);
-        screenCenter = Math.max(halfScreenSize,  screenCenter);
-
-        return getScrollProgress(screenCenter, v, page);
-    }
-
-    protected float getScrollProgress(int screenCenter, View v, int page) {
-        final int halfScreenSize = getViewportWidth() / 2;
-
-        int totalDistance = getScaledMeasuredWidth(v) + mPageSpacing;
-        int delta = screenCenter - (getChildOffset(page) -
-                getRelativeChildOffset(page) + halfScreenSize);
-
-        float scrollProgress = delta / (totalDistance * 1.0f);
-        scrollProgress = Math.min(scrollProgress, getMaxScrollProgress());
-        scrollProgress = Math.max(scrollProgress, - getMaxScrollProgress());
-        return scrollProgress;
-    }
-
-    // This curve determines how the effect of scrolling over the limits of the page dimishes
-    // as the user pulls further and further from the bounds
-    private float overScrollInfluenceCurve(float f) {
-        f -= 1.0f;
-        return f * f * f + 1.0f;
-    }
-
-    protected void acceleratedOverScroll(float amount) {
-        int screenSize = getViewportWidth();
-
-        // We want to reach the max over scroll effect when the user has
-        // over scrolled half the size of the screen
-        float f = OVERSCROLL_ACCELERATE_FACTOR * (amount / screenSize);
-
-        if (f == 0) return;
-
-        // Clamp this factor, f, to -1 < f < 1
-        if (Math.abs(f) >= 1) {
-            f /= Math.abs(f);
-        }
-
-        int overScrollAmount = (int) Math.round(f * screenSize);
-        if (amount < 0) {
-            mOverScrollX = overScrollAmount;
-            super.scrollTo(0, getScrollY());
-        } else {
-            mOverScrollX = mMaxScrollX + overScrollAmount;
-            super.scrollTo(mMaxScrollX, getScrollY());
-        }
-        invalidate();
-    }
-
-    protected void dampedOverScroll(float amount) {
-        int screenSize = getViewportWidth();
-
-        float f = (amount / screenSize);
-
-        if (f == 0) return;
-        f = f / (Math.abs(f)) * (overScrollInfluenceCurve(Math.abs(f)));
-
-        // Clamp this factor, f, to -1 < f < 1
-        if (Math.abs(f) >= 1) {
-            f /= Math.abs(f);
-        }
-
-        int overScrollAmount = (int) Math.round(OVERSCROLL_DAMP_FACTOR * f * screenSize);
-        if (amount < 0) {
-            mOverScrollX = overScrollAmount;
-            super.scrollTo(0, getScrollY());
-        } else {
-            mOverScrollX = mMaxScrollX + overScrollAmount;
-            super.scrollTo(mMaxScrollX, getScrollY());
-        }
-        invalidate();
-    }
-
-    protected void overScroll(float amount) {
-        dampedOverScroll(amount);
-    }
-
-    protected float maxOverScroll() {
-        // Using the formula in overScroll, assuming that f = 1.0 (which it should generally not
-        // exceed). Used to find out how much extra wallpaper we need for the over scroll effect
-        float f = 1.0f;
-        f = f / (Math.abs(f)) * (overScrollInfluenceCurve(Math.abs(f)));
-        return OVERSCROLL_DAMP_FACTOR * f;
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev) {
-        if (DISABLE_TOUCH_INTERACTION) {
-            return false;
-        }
-
-        // Skip touch handling if there are no pages to swipe
-        if (getChildCount() <= 0) return super.onTouchEvent(ev);
-
-        acquireVelocityTrackerAndAddMovement(ev);
-
-        final int action = ev.getAction();
-
-        switch (action & MotionEvent.ACTION_MASK) {
-        case MotionEvent.ACTION_DOWN:
-            /*
-             * If being flinged and user touches, stop the fling. isFinished
-             * will be false if being flinged.
-             */
-            if (!mScroller.isFinished()) {
-                mScroller.abortAnimation();
-            }
-
-            // Remember where the motion event started
-            mDownMotionX = mLastMotionX = ev.getX();
-            mDownMotionY = mLastMotionY = ev.getY();
-            mDownScrollX = getScrollX();
-            float[] p = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY);
-            mParentDownMotionX = p[0];
-            mParentDownMotionY = p[1];
-            mLastMotionXRemainder = 0;
-            mTotalMotionX = 0;
-            mActivePointerId = ev.getPointerId(0);
-
-            // Determine if the down event is within the threshold to be an edge swipe
-            int leftEdgeBoundary = getViewportOffsetX() + mEdgeSwipeRegionSize;
-            int rightEdgeBoundary = getMeasuredWidth() - getViewportOffsetX() - mEdgeSwipeRegionSize;
-            if ((mDownMotionX <= leftEdgeBoundary || mDownMotionX >= rightEdgeBoundary)) {
-                mDownEventOnEdge = true;
-            }
-
-            if (mTouchState == TOUCH_STATE_SCROLLING) {
-                pageBeginMoving();
-            }
-            break;
-
-        case MotionEvent.ACTION_MOVE:
-            if (mTouchState == TOUCH_STATE_SCROLLING) {
-                // Scroll to follow the motion event
-                final int pointerIndex = ev.findPointerIndex(mActivePointerId);
-
-                if (pointerIndex == -1) return true;
-
-                final float x = ev.getX(pointerIndex);
-                final float deltaX = mLastMotionX + mLastMotionXRemainder - x;
-
-                mTotalMotionX += Math.abs(deltaX);
-
-                // Only scroll and update mLastMotionX if we have moved some discrete amount.  We
-                // keep the remainder because we are actually testing if we've moved from the last
-                // scrolled position (which is discrete).
-                if (Math.abs(deltaX) >= 1.0f) {
-                    mTouchX += deltaX;
-                    mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
-                    if (!mDeferScrollUpdate) {
-                        scrollBy((int) deltaX, 0);
-                        if (DEBUG) Log.d(TAG, "onTouchEvent().Scrolling: " + deltaX);
-                    } else {
-                        invalidate();
-                    }
-                    mLastMotionX = x;
-                    mLastMotionXRemainder = deltaX - (int) deltaX;
-                } else {
-                    awakenScrollBars();
-                }
-            } else if (mTouchState == TOUCH_STATE_REORDERING) {
-                // Update the last motion position
-                mLastMotionX = ev.getX();
-                mLastMotionY = ev.getY();
-
-                // Update the parent down so that our zoom animations take this new movement into
-                // account
-                float[] pt = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY);
-                mParentDownMotionX = pt[0];
-                mParentDownMotionY = pt[1];
-                updateDragViewTranslationDuringDrag();
-
-                // Find the closest page to the touch point
-                final int dragViewIndex = indexOfChild(mDragView);
-                int bufferSize = (int) (REORDERING_SIDE_PAGE_BUFFER_PERCENTAGE *
-                    getViewportWidth());
-                int leftBufferEdge = (int) (mapPointFromViewToParent(this, mViewport.left, 0)[0]
-                        + bufferSize);
-                int rightBufferEdge = (int) (mapPointFromViewToParent(this, mViewport.right, 0)[0]
-                        - bufferSize);
-
-                // Change the drag view if we are hovering over the drop target
-                boolean isHoveringOverDelete = isHoveringOverDeleteDropTarget(
-                        (int) mParentDownMotionX, (int) mParentDownMotionY);
-                setPageHoveringOverDeleteDropTarget(dragViewIndex, isHoveringOverDelete);
-
-                if (DEBUG) Log.d(TAG, "leftBufferEdge: " + leftBufferEdge);
-                if (DEBUG) Log.d(TAG, "rightBufferEdge: " + rightBufferEdge);
-                if (DEBUG) Log.d(TAG, "mLastMotionX: " + mLastMotionX);
-                if (DEBUG) Log.d(TAG, "mLastMotionY: " + mLastMotionY);
-                if (DEBUG) Log.d(TAG, "mParentDownMotionX: " + mParentDownMotionX);
-                if (DEBUG) Log.d(TAG, "mParentDownMotionY: " + mParentDownMotionY);
-
-                float parentX = mParentDownMotionX;
-                int pageIndexToSnapTo = -1;
-                if (parentX < leftBufferEdge && dragViewIndex > 0) {
-                    pageIndexToSnapTo = dragViewIndex - 1;
-                } else if (parentX > rightBufferEdge && dragViewIndex < getChildCount() - 1) {
-                    pageIndexToSnapTo = dragViewIndex + 1;
-                }
-
-                final int pageUnderPointIndex = pageIndexToSnapTo;
-                if (pageUnderPointIndex > -1 && !isHoveringOverDelete) {
-                    mTempVisiblePagesRange[0] = 0;
-                    mTempVisiblePagesRange[1] = getPageCount() - 1;
-                    boundByReorderablePages(true, mTempVisiblePagesRange);
-                    if (mTempVisiblePagesRange[0] <= pageUnderPointIndex &&
-                            pageUnderPointIndex <= mTempVisiblePagesRange[1] &&
-                            pageUnderPointIndex != mSidePageHoverIndex && mScroller.isFinished()) {
-                        mSidePageHoverIndex = pageUnderPointIndex;
-                        mSidePageHoverRunnable = new Runnable() {
-                            @Override
-                            public void run() {
-                                // Update the down scroll position to account for the fact that the
-                                // current page is moved
-                                mDownScrollX = getChildOffset(pageUnderPointIndex)
-                                        - getRelativeChildOffset(pageUnderPointIndex);
-
-                                // Setup the scroll to the correct page before we swap the views
-                                snapToPage(pageUnderPointIndex);
-
-                                // For each of the pages between the paged view and the drag view,
-                                // animate them from the previous position to the new position in
-                                // the layout (as a result of the drag view moving in the layout)
-                                int shiftDelta = (dragViewIndex < pageUnderPointIndex) ? -1 : 1;
-                                int lowerIndex = (dragViewIndex < pageUnderPointIndex) ?
-                                        dragViewIndex + 1 : pageUnderPointIndex;
-                                int upperIndex = (dragViewIndex > pageUnderPointIndex) ?
-                                        dragViewIndex - 1 : pageUnderPointIndex;
-                                for (int i = lowerIndex; i <= upperIndex; ++i) {
-                                    View v = getChildAt(i);
-                                    // dragViewIndex < pageUnderPointIndex, so after we remove the
-                                    // drag view all subsequent views to pageUnderPointIndex will
-                                    // shift down.
-                                    int oldX = getViewportOffsetX() + getChildOffset(i);
-                                    int newX = getViewportOffsetX() + getChildOffset(i + shiftDelta);
-
-                                    // Animate the view translation from its old position to its new
-                                    // position
-                                    AnimatorSet anim = (AnimatorSet) v.getTag();
-                                    if (anim != null) {
-                                        anim.cancel();
-                                    }
-
-                                    v.setTranslationX(oldX - newX);
-                                    anim = new AnimatorSet();
-                                    anim.setDuration(REORDERING_REORDER_REPOSITION_DURATION);
-                                    anim.playTogether(
-                                            ObjectAnimator.ofFloat(v, "translationX", 0f));
-                                    anim.start();
-                                    v.setTag(anim);
-                                }
-
-                                removeView(mDragView);
-                                onRemoveView(mDragView, false);
-                                addView(mDragView, pageUnderPointIndex);
-                                onAddView(mDragView, pageUnderPointIndex);
-                                mSidePageHoverIndex = -1;
-                            }
-                        };
-                        postDelayed(mSidePageHoverRunnable, REORDERING_SIDE_PAGE_HOVER_TIMEOUT);
-                    }
-                } else {
-                    removeCallbacks(mSidePageHoverRunnable);
-                    mSidePageHoverIndex = -1;
-                }
-            } else {
-                determineScrollingStart(ev);
-            }
-            break;
-
-        case MotionEvent.ACTION_UP:
-            if (mTouchState == TOUCH_STATE_SCROLLING) {
-                final int activePointerId = mActivePointerId;
-                final int pointerIndex = ev.findPointerIndex(activePointerId);
-                final float x = ev.getX(pointerIndex);
-                final VelocityTracker velocityTracker = mVelocityTracker;
-                velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
-                int velocityX = (int) velocityTracker.getXVelocity(activePointerId);
-                final int deltaX = (int) (x - mDownMotionX);
-                final int pageWidth = getScaledMeasuredWidth(getPageAt(mCurrentPage));
-                boolean isSignificantMove = Math.abs(deltaX) > pageWidth *
-                        SIGNIFICANT_MOVE_THRESHOLD;
-
-                mTotalMotionX += Math.abs(mLastMotionX + mLastMotionXRemainder - x);
-
-                boolean isFling = mTotalMotionX > MIN_LENGTH_FOR_FLING &&
-                        Math.abs(velocityX) > mFlingThresholdVelocity;
-
-                // In the case that the page is moved far to one direction and then is flung
-                // in the opposite direction, we use a threshold to determine whether we should
-                // just return to the starting page, or if we should skip one further.
-                boolean returnToOriginalPage = false;
-                if (Math.abs(deltaX) > pageWidth * RETURN_TO_ORIGINAL_PAGE_THRESHOLD &&
-                        Math.signum(velocityX) != Math.signum(deltaX) && isFling) {
-                    returnToOriginalPage = true;
-                }
-
-                int finalPage;
-                // We give flings precedence over large moves, which is why we short-circuit our
-                // test for a large move if a fling has been registered. That is, a large
-                // move to the left and fling to the right will register as a fling to the right.
-                if (((isSignificantMove && deltaX > 0 && !isFling) ||
-                        (isFling && velocityX > 0)) && mCurrentPage > 0) {
-                    finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage - 1;
-                    snapToPageWithVelocity(finalPage, velocityX);
-                } else if (((isSignificantMove && deltaX < 0 && !isFling) ||
-                        (isFling && velocityX < 0)) &&
-                        mCurrentPage < getChildCount() - 1) {
-                    finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage + 1;
-                    snapToPageWithVelocity(finalPage, velocityX);
-                } else {
-                    snapToDestination();
-                }
-            } else if (mTouchState == TOUCH_STATE_PREV_PAGE) {
-                // at this point we have not moved beyond the touch slop
-                // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so
-                // we can just page
-                int nextPage = Math.max(0, mCurrentPage - 1);
-                if (nextPage != mCurrentPage) {
-                    snapToPage(nextPage);
-                } else {
-                    snapToDestination();
-                }
-            } else if (mTouchState == TOUCH_STATE_NEXT_PAGE) {
-                // at this point we have not moved beyond the touch slop
-                // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so
-                // we can just page
-                int nextPage = Math.min(getChildCount() - 1, mCurrentPage + 1);
-                if (nextPage != mCurrentPage) {
-                    snapToPage(nextPage);
-                } else {
-                    snapToDestination();
-                }
-            } else if (mTouchState == TOUCH_STATE_REORDERING) {
-                // Update the last motion position
-                mLastMotionX = ev.getX();
-                mLastMotionY = ev.getY();
-
-                // Update the parent down so that our zoom animations take this new movement into
-                // account
-                float[] pt = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY);
-                mParentDownMotionX = pt[0];
-                mParentDownMotionY = pt[1];
-                updateDragViewTranslationDuringDrag();
-                boolean handledFling = false;
-                if (!DISABLE_FLING_TO_DELETE) {
-                    // Check the velocity and see if we are flinging-to-delete
-                    PointF flingToDeleteVector = isFlingingToDelete();
-                    if (flingToDeleteVector != null) {
-                        onFlingToDelete(flingToDeleteVector);
-                        handledFling = true;
-                    }
-                }
-                if (!handledFling && isHoveringOverDeleteDropTarget((int) mParentDownMotionX,
-                        (int) mParentDownMotionY)) {
-                    onDropToDelete();
-                }
-            } else {
-                onUnhandledTap(ev);
-            }
-
-            // Remove the callback to wait for the side page hover timeout
-            removeCallbacks(mSidePageHoverRunnable);
-            // End any intermediate reordering states
-            resetTouchState();
-            break;
-
-        case MotionEvent.ACTION_CANCEL:
-            if (mTouchState == TOUCH_STATE_SCROLLING) {
-                snapToDestination();
-            }
-            resetTouchState();
-            break;
-
-        case MotionEvent.ACTION_POINTER_UP:
-            onSecondaryPointerUp(ev);
-            break;
-        }
-
-        return true;
-    }
-
-    //public abstract void onFlingToDelete(View v);
-    public abstract void onRemoveView(View v, boolean deletePermanently);
-    public abstract void onRemoveViewAnimationCompleted();
-    public abstract void onAddView(View v, int index);
-
-    private void resetTouchState() {
-        releaseVelocityTracker();
-        endReordering();
-        mTouchState = TOUCH_STATE_REST;
-        mActivePointerId = INVALID_POINTER;
-        mDownEventOnEdge = false;
-    }
-
-    protected void onUnhandledTap(MotionEvent ev) {}
-
-    @Override
-    public boolean onGenericMotionEvent(MotionEvent event) {
-        if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
-            switch (event.getAction()) {
-                case MotionEvent.ACTION_SCROLL: {
-                    // Handle mouse (or ext. device) by shifting the page depending on the scroll
-                    final float vscroll;
-                    final float hscroll;
-                    if ((event.getMetaState() & KeyEvent.META_SHIFT_ON) != 0) {
-                        vscroll = 0;
-                        hscroll = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
-                    } else {
-                        vscroll = -event.getAxisValue(MotionEvent.AXIS_VSCROLL);
-                        hscroll = event.getAxisValue(MotionEvent.AXIS_HSCROLL);
-                    }
-                    if (hscroll != 0 || vscroll != 0) {
-                        if (hscroll > 0 || vscroll > 0) {
-                            scrollRight();
-                        } else {
-                            scrollLeft();
-                        }
-                        return true;
-                    }
-                }
-            }
-        }
-        return super.onGenericMotionEvent(event);
-    }
-
-    private void acquireVelocityTrackerAndAddMovement(MotionEvent ev) {
-        if (mVelocityTracker == null) {
-            mVelocityTracker = VelocityTracker.obtain();
-        }
-        mVelocityTracker.addMovement(ev);
-    }
-
-    private void releaseVelocityTracker() {
-        if (mVelocityTracker != null) {
-            mVelocityTracker.recycle();
-            mVelocityTracker = null;
-        }
-    }
-
-    private void onSecondaryPointerUp(MotionEvent ev) {
-        final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >>
-                MotionEvent.ACTION_POINTER_INDEX_SHIFT;
-        final int pointerId = ev.getPointerId(pointerIndex);
-        if (pointerId == mActivePointerId) {
-            // This was our active pointer going up. Choose a new
-            // active pointer and adjust accordingly.
-            // TODO: Make this decision more intelligent.
-            final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
-            mLastMotionX = mDownMotionX = ev.getX(newPointerIndex);
-            mLastMotionY = ev.getY(newPointerIndex);
-            mLastMotionXRemainder = 0;
-            mActivePointerId = ev.getPointerId(newPointerIndex);
-            if (mVelocityTracker != null) {
-                mVelocityTracker.clear();
-            }
-        }
-    }
-
-    @Override
-    public void requestChildFocus(View child, View focused) {
-        super.requestChildFocus(child, focused);
-        int page = indexToPage(indexOfChild(child));
-        if (page >= 0 && page != getCurrentPage() && !isInTouchMode()) {
-            snapToPage(page);
-        }
-    }
-
-    protected int getChildIndexForRelativeOffset(int relativeOffset) {
-        final int childCount = getChildCount();
-        int left;
-        int right;
-        for (int i = 0; i < childCount; ++i) {
-            left = getRelativeChildOffset(i);
-            right = (left + getScaledMeasuredWidth(getPageAt(i)));
-            if (left <= relativeOffset && relativeOffset <= right) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    protected int getChildWidth(int index) {
-        // This functions are called enough times that it actually makes a difference in the
-        // profiler -- so just inline the max() here
-        final int measuredWidth = getPageAt(index).getMeasuredWidth();
-        final int minWidth = mMinimumWidth;
-        return (minWidth > measuredWidth) ? minWidth : measuredWidth;
-    }
-
-    int getPageNearestToPoint(float x) {
-        int index = 0;
-        for (int i = 0; i < getChildCount(); ++i) {
-            if (x < getChildAt(i).getRight() - getScrollX()) {
-                return index;
-            } else {
-                index++;
-            }
-        }
-        return Math.min(index, getChildCount() - 1);
-    }
-
-    int getPageNearestToCenterOfScreen() {
-        int minDistanceFromScreenCenter = Integer.MAX_VALUE;
-        int minDistanceFromScreenCenterIndex = -1;
-        int screenCenter = getViewportOffsetX() + getScrollX() + (getViewportWidth() / 2);
-        final int childCount = getChildCount();
-        for (int i = 0; i < childCount; ++i) {
-            View layout = (View) getPageAt(i);
-            int childWidth = getScaledMeasuredWidth(layout);
-            int halfChildWidth = (childWidth / 2);
-            int childCenter = getViewportOffsetX() + getChildOffset(i) + halfChildWidth;
-            int distanceFromScreenCenter = Math.abs(childCenter - screenCenter);
-            if (distanceFromScreenCenter < minDistanceFromScreenCenter) {
-                minDistanceFromScreenCenter = distanceFromScreenCenter;
-                minDistanceFromScreenCenterIndex = i;
-            }
-        }
-        return minDistanceFromScreenCenterIndex;
-    }
-
-    protected void snapToDestination() {
-        snapToPage(getPageNearestToCenterOfScreen(), PAGE_SNAP_ANIMATION_DURATION);
-    }
-
-    private static class ScrollInterpolator implements Interpolator {
-        public ScrollInterpolator() {
-        }
-
-        public float getInterpolation(float t) {
-            t -= 1.0f;
-            return t*t*t*t*t + 1;
-        }
-    }
-
-    // We want the duration of the page snap animation to be influenced by the distance that
-    // the screen has to travel, however, we don't want this duration to be effected in a
-    // purely linear fashion. Instead, we use this method to moderate the effect that the distance
-    // of travel has on the overall snap duration.
-    float distanceInfluenceForSnapDuration(float f) {
-        f -= 0.5f; // center the values about 0.
-        f *= 0.3f * Math.PI / 2.0f;
-        return (float) Math.sin(f);
-    }
-
-    protected void snapToPageWithVelocity(int whichPage, int velocity) {
-        whichPage = Math.max(0, Math.min(whichPage, getChildCount() - 1));
-        int halfScreenSize = getViewportWidth() / 2;
-
-        if (DEBUG) Log.d(TAG, "snapToPage.getChildOffset(): " + getChildOffset(whichPage));
-        if (DEBUG) Log.d(TAG, "snapToPageWithVelocity.getRelativeChildOffset(): "
-                + getViewportWidth() + ", " + getChildWidth(whichPage));
-        final int newX = getChildOffset(whichPage) - getRelativeChildOffset(whichPage);
-        int delta = newX - mUnboundedScrollX;
-        int duration = 0;
-
-        if (Math.abs(velocity) < mMinFlingVelocity) {
-            // If the velocity is low enough, then treat this more as an automatic page advance
-            // as opposed to an apparent physical response to flinging
-            snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION);
-            return;
-        }
-
-        // Here we compute a "distance" that will be used in the computation of the overall
-        // snap duration. This is a function of the actual distance that needs to be traveled;
-        // we keep this value close to half screen size in order to reduce the variance in snap
-        // duration as a function of the distance the page needs to travel.
-        float distanceRatio = Math.min(1f, 1.0f * Math.abs(delta) / (2 * halfScreenSize));
-        float distance = halfScreenSize + halfScreenSize *
-                distanceInfluenceForSnapDuration(distanceRatio);
-
-        velocity = Math.abs(velocity);
-        velocity = Math.max(mMinSnapVelocity, velocity);
-
-        // we want the page's snap velocity to approximately match the velocity at which the
-        // user flings, so we scale the duration by a value near to the derivative of the scroll
-        // interpolator at zero, ie. 5. We use 4 to make it a little slower.
-        duration = 4 * Math.round(1000 * Math.abs(distance / velocity));
-
-        snapToPage(whichPage, delta, duration);
-    }
-
-    protected void snapToPage(int whichPage) {
-        snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION);
-    }
-    protected void snapToPageImmediately(int whichPage) {
-        snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION, true);
-    }
-
-    protected void snapToPage(int whichPage, int duration) {
-        snapToPage(whichPage, duration, false);
-    }
-    protected void snapToPage(int whichPage, int duration, boolean immediate) {
-        whichPage = Math.max(0, Math.min(whichPage, getPageCount() - 1));
-
-        if (DEBUG) Log.d(TAG, "snapToPage.getChildOffset(): " + getChildOffset(whichPage));
-        if (DEBUG) Log.d(TAG, "snapToPage.getRelativeChildOffset(): " + getViewportWidth() + ", "
-                + getChildWidth(whichPage));
-        int newX = getChildOffset(whichPage) - getRelativeChildOffset(whichPage);
-        final int sX = mUnboundedScrollX;
-        final int delta = newX - sX;
-        snapToPage(whichPage, delta, duration, immediate);
-    }
-
-    protected void snapToPage(int whichPage, int delta, int duration) {
-        snapToPage(whichPage, delta, duration, false);
-    }
-    protected void snapToPage(int whichPage, int delta, int duration, boolean immediate) {
-        mNextPage = whichPage;
-        notifyPageSwitching(whichPage);
-        View focusedChild = getFocusedChild();
-        if (focusedChild != null && whichPage != mCurrentPage &&
-                focusedChild == getPageAt(mCurrentPage)) {
-            focusedChild.clearFocus();
-        }
-
-        pageBeginMoving();
-        awakenScrollBars(duration);
-        if (immediate) {
-            duration = 0;
-        } else if (duration == 0) {
-            duration = Math.abs(delta);
-        }
-
-        if (!mScroller.isFinished()) mScroller.abortAnimation();
-        mScroller.startScroll(mUnboundedScrollX, 0, delta, 0, duration);
-
-        notifyPageSwitched();
-
-        // Trigger a compute() to finish switching pages if necessary
-        if (immediate) {
-            computeScroll();
-        }
-
-        mForceScreenScrolled = true;
-        invalidate();
-    }
-
-    public void scrollLeft() {
-        if (mScroller.isFinished()) {
-            if (mCurrentPage > 0) snapToPage(mCurrentPage - 1);
-        } else {
-            if (mNextPage > 0) snapToPage(mNextPage - 1);
-        }
-    }
-
-    public void scrollRight() {
-        if (mScroller.isFinished()) {
-            if (mCurrentPage < getChildCount() -1) snapToPage(mCurrentPage + 1);
-        } else {
-            if (mNextPage < getChildCount() -1) snapToPage(mNextPage + 1);
-        }
-    }
-
-    public int getPageForView(View v) {
-        int result = -1;
-        if (v != null) {
-            ViewParent vp = v.getParent();
-            int count = getChildCount();
-            for (int i = 0; i < count; i++) {
-                if (vp == getPageAt(i)) {
-                    return i;
-                }
-            }
-        }
-        return result;
-    }
-
-    public static class SavedState extends BaseSavedState {
-        int currentPage = -1;
-
-        SavedState(Parcelable superState) {
-            super(superState);
-        }
-
-        private SavedState(Parcel in) {
-            super(in);
-            currentPage = in.readInt();
-        }
-
-        @Override
-        public void writeToParcel(Parcel out, int flags) {
-            super.writeToParcel(out, flags);
-            out.writeInt(currentPage);
-        }
-
-        public static final Parcelable.Creator<SavedState> CREATOR =
-                new Parcelable.Creator<SavedState>() {
-            public SavedState createFromParcel(Parcel in) {
-                return new SavedState(in);
-            }
-
-            public SavedState[] newArray(int size) {
-                return new SavedState[size];
-            }
-        };
-    }
-
-    protected View getScrollingIndicator() {
-        return null;
-    }
-
-    protected boolean isScrollingIndicatorEnabled() {
-        return false;
-    }
-
-    Runnable hideScrollingIndicatorRunnable = new Runnable() {
-        @Override
-        public void run() {
-            hideScrollingIndicator(false);
-        }
-    };
-
-    protected void flashScrollingIndicator(boolean animated) {
-        removeCallbacks(hideScrollingIndicatorRunnable);
-        showScrollingIndicator(!animated);
-        postDelayed(hideScrollingIndicatorRunnable, sScrollIndicatorFlashDuration);
-    }
-
-    protected void showScrollingIndicator(boolean immediately) {
-        mShouldShowScrollIndicator = true;
-        mShouldShowScrollIndicatorImmediately = true;
-        if (getChildCount() <= 1) return;
-        if (!isScrollingIndicatorEnabled()) return;
-
-        mShouldShowScrollIndicator = false;
-        getScrollingIndicator();
-        if (mScrollIndicator != null) {
-            // Fade the indicator in
-            updateScrollingIndicatorPosition();
-            mScrollIndicator.setVisibility(View.VISIBLE);
-            cancelScrollingIndicatorAnimations();
-            if (immediately) {
-                mScrollIndicator.setAlpha(1f);
-            } else {
-                mScrollIndicatorAnimator = ObjectAnimator.ofFloat(mScrollIndicator, "alpha", 1f);
-                mScrollIndicatorAnimator.setDuration(sScrollIndicatorFadeInDuration);
-                mScrollIndicatorAnimator.start();
-            }
-        }
-    }
-
-    protected void cancelScrollingIndicatorAnimations() {
-        if (mScrollIndicatorAnimator != null) {
-            mScrollIndicatorAnimator.cancel();
-        }
-    }
-
-    protected void hideScrollingIndicator(boolean immediately) {
-        if (getChildCount() <= 1) return;
-        if (!isScrollingIndicatorEnabled()) return;
-
-        getScrollingIndicator();
-        if (mScrollIndicator != null) {
-            // Fade the indicator out
-            updateScrollingIndicatorPosition();
-            cancelScrollingIndicatorAnimations();
-            if (immediately) {
-                mScrollIndicator.setVisibility(View.INVISIBLE);
-                mScrollIndicator.setAlpha(0f);
-            } else {
-                mScrollIndicatorAnimator = ObjectAnimator.ofFloat(mScrollIndicator, "alpha", 0f);
-                mScrollIndicatorAnimator.setDuration(sScrollIndicatorFadeOutDuration);
-                mScrollIndicatorAnimator.addListener(new AnimatorListenerAdapter() {
-                    private boolean cancelled = false;
-                    @Override
-                    public void onAnimationCancel(android.animation.Animator animation) {
-                        cancelled = true;
-                    }
-                    @Override
-                    public void onAnimationEnd(Animator animation) {
-                        if (!cancelled) {
-                            mScrollIndicator.setVisibility(View.INVISIBLE);
-                        }
-                    }
-                });
-                mScrollIndicatorAnimator.start();
-            }
-        }
-    }
-
-    /**
-     * To be overridden by subclasses to determine whether the scroll indicator should stretch to
-     * fill its space on the track or not.
-     */
-    protected boolean hasElasticScrollIndicator() {
-        return true;
-    }
-
-    private void updateScrollingIndicator() {
-        if (getChildCount() <= 1) return;
-        if (!isScrollingIndicatorEnabled()) return;
-
-        getScrollingIndicator();
-        if (mScrollIndicator != null) {
-            updateScrollingIndicatorPosition();
-        }
-        if (mShouldShowScrollIndicator) {
-            showScrollingIndicator(mShouldShowScrollIndicatorImmediately);
-        }
-    }
-
-    private void updateScrollingIndicatorPosition() {
-        if (!isScrollingIndicatorEnabled()) return;
-        if (mScrollIndicator == null) return;
-        int numPages = getChildCount();
-        int pageWidth = getViewportWidth();
-        int lastChildIndex = Math.max(0, getChildCount() - 1);
-        int maxScrollX = getChildOffset(lastChildIndex) - getRelativeChildOffset(lastChildIndex);
-        int trackWidth = pageWidth - mScrollIndicatorPaddingLeft - mScrollIndicatorPaddingRight;
-        int indicatorWidth = mScrollIndicator.getMeasuredWidth() -
-                mScrollIndicator.getPaddingLeft() - mScrollIndicator.getPaddingRight();
-
-        float offset = Math.max(0f, Math.min(1f, (float) getScrollX() / maxScrollX));
-        int indicatorSpace = trackWidth / numPages;
-        int indicatorPos = (int) (offset * (trackWidth - indicatorSpace)) + mScrollIndicatorPaddingLeft;
-        if (hasElasticScrollIndicator()) {
-            if (mScrollIndicator.getMeasuredWidth() != indicatorSpace) {
-                mScrollIndicator.getLayoutParams().width = indicatorSpace;
-                mScrollIndicator.requestLayout();
-            }
-        } else {
-            int indicatorCenterOffset = indicatorSpace / 2 - indicatorWidth / 2;
-            indicatorPos += indicatorCenterOffset;
-        }
-        mScrollIndicator.setTranslationX(indicatorPos);
-    }
-
-    // Animate the drag view back to the original position
-    void animateDragViewToOriginalPosition() {
-        if (mDragView != null) {
-            AnimatorSet anim = new AnimatorSet();
-            anim.setDuration(REORDERING_DROP_REPOSITION_DURATION);
-            anim.playTogether(
-                    ObjectAnimator.ofFloat(mDragView, "translationX", 0f),
-                    ObjectAnimator.ofFloat(mDragView, "translationY", 0f));
-            anim.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    onPostReorderingAnimationCompleted();
-                }
-            });
-            anim.start();
-        }
-    }
-
-    // "Zooms out" the PagedView to reveal more side pages
-    protected boolean zoomOut() {
-        if (mZoomInOutAnim != null && mZoomInOutAnim.isRunning()) {
-            mZoomInOutAnim.cancel();
-        }
-
-        if (!(getScaleX() < 1f || getScaleY() < 1f)) {
-            mZoomInOutAnim = new AnimatorSet();
-            mZoomInOutAnim.setDuration(REORDERING_ZOOM_IN_OUT_DURATION);
-            mZoomInOutAnim.playTogether(
-                    ObjectAnimator.ofFloat(this, "scaleX", mMinScale),
-                    ObjectAnimator.ofFloat(this, "scaleY", mMinScale));
-            mZoomInOutAnim.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationStart(Animator animation) {
-                    // Show the delete drop target
-                    if (mDeleteDropTarget != null) {
-                        mDeleteDropTarget.setVisibility(View.VISIBLE);
-                        mDeleteDropTarget.animate().alpha(1f)
-                            .setDuration(REORDERING_DELETE_DROP_TARGET_FADE_DURATION)
-                            .setListener(new AnimatorListenerAdapter() {
-                                @Override
-                                public void onAnimationStart(Animator animation) {
-                                    mDeleteDropTarget.setAlpha(0f);
-                                }
-                            });
-                    }
-                }
-            });
-            mZoomInOutAnim.start();
-            return true;
-        }
-        return false;
-    }
-
-    protected void onStartReordering() {
-        if (AccessibilityManager.getInstance(mContext).isEnabled()) {
-            announceForAccessibility(mContext.getString(
-                    R.string.keyguard_accessibility_widget_reorder_start));
-        }
-
-        // Set the touch state to reordering (allows snapping to pages, dragging a child, etc.)
-        mTouchState = TOUCH_STATE_REORDERING;
-        mIsReordering = true;
-
-        // Mark all the non-widget pages as invisible
-        getVisiblePages(mTempVisiblePagesRange);
-        boundByReorderablePages(true, mTempVisiblePagesRange);
-        for (int i = 0; i < getPageCount(); ++i) {
-            if (i < mTempVisiblePagesRange[0] || i > mTempVisiblePagesRange[1]) {
-                getPageAt(i).setAlpha(0f);
-            }
-        }
-
-        // We must invalidate to trigger a redraw to update the layers such that the drag view
-        // is always drawn on top
-        invalidate();
-    }
-
-    private void onPostReorderingAnimationCompleted() {
-        // Trigger the callback when reordering has settled
-        --mPostReorderingPreZoomInRemainingAnimationCount;
-        if (mPostReorderingPreZoomInRunnable != null &&
-                mPostReorderingPreZoomInRemainingAnimationCount == 0) {
-            mPostReorderingPreZoomInRunnable.run();
-            mPostReorderingPreZoomInRunnable = null;
-        }
-    }
-
-    protected void onEndReordering() {
-        if (AccessibilityManager.getInstance(mContext).isEnabled()) {
-            announceForAccessibility(mContext.getString(
-                    R.string.keyguard_accessibility_widget_reorder_end));
-        }
-        mIsReordering = false;
-
-        // Mark all the non-widget pages as visible again
-        getVisiblePages(mTempVisiblePagesRange);
-        boundByReorderablePages(true, mTempVisiblePagesRange);
-        for (int i = 0; i < getPageCount(); ++i) {
-            if (i < mTempVisiblePagesRange[0] || i > mTempVisiblePagesRange[1]) {
-                getPageAt(i).setAlpha(1f);
-            }
-        }
-    }
-
-    public boolean startReordering() {
-        int dragViewIndex = getPageNearestToCenterOfScreen();
-        mTempVisiblePagesRange[0] = 0;
-        mTempVisiblePagesRange[1] = getPageCount() - 1;
-        boundByReorderablePages(true, mTempVisiblePagesRange);
-        mReorderingStarted = true;
-
-        // Check if we are within the reordering range
-        if (mTempVisiblePagesRange[0] <= dragViewIndex &&
-                dragViewIndex <= mTempVisiblePagesRange[1]) {
-            if (zoomOut()) {
-                // Find the drag view under the pointer
-                mDragView = getChildAt(dragViewIndex);
-
-                onStartReordering();
-            }
-            return true;
-        }
-        return false;
-    }
-
-    boolean isReordering(boolean testTouchState) {
-        boolean state = mIsReordering;
-        if (testTouchState) {
-            state &= (mTouchState == TOUCH_STATE_REORDERING);
-        }
-        return state;
-    }
-    void endReordering() {
-        // For simplicity, we call endReordering sometimes even if reordering was never started.
-        // In that case, we don't want to do anything.
-        if (!mReorderingStarted) return;
-        mReorderingStarted = false;
-
-        // If we haven't flung-to-delete the current child, then we just animate the drag view
-        // back into position
-        final Runnable onCompleteRunnable = new Runnable() {
-            @Override
-            public void run() {
-                onEndReordering();
-            }
-        };
-        if (!mDeferringForDelete) {
-            mPostReorderingPreZoomInRunnable = new Runnable() {
-                public void run() {
-                    zoomIn(onCompleteRunnable);
-                };
-            };
-
-            mPostReorderingPreZoomInRemainingAnimationCount =
-                    NUM_ANIMATIONS_RUNNING_BEFORE_ZOOM_OUT;
-            // Snap to the current page
-            snapToPage(indexOfChild(mDragView), 0);
-            // Animate the drag view back to the front position
-            animateDragViewToOriginalPosition();
-        } else {
-            // Handled in post-delete-animation-callbacks
-        }
-    }
-
-    // "Zooms in" the PagedView to highlight the current page
-    protected boolean zoomIn(final Runnable onCompleteRunnable) {
-        if (mZoomInOutAnim != null && mZoomInOutAnim.isRunning()) {
-            mZoomInOutAnim.cancel();
-        }
-        if (getScaleX() < 1f || getScaleY() < 1f) {
-            mZoomInOutAnim = new AnimatorSet();
-            mZoomInOutAnim.setDuration(REORDERING_ZOOM_IN_OUT_DURATION);
-            mZoomInOutAnim.playTogether(
-                    ObjectAnimator.ofFloat(this, "scaleX", 1f),
-                    ObjectAnimator.ofFloat(this, "scaleY", 1f));
-            mZoomInOutAnim.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationStart(Animator animation) {
-                    // Hide the delete drop target
-                    if (mDeleteDropTarget != null) {
-                        mDeleteDropTarget.animate().alpha(0f)
-                            .setDuration(REORDERING_DELETE_DROP_TARGET_FADE_DURATION)
-                            .setListener(new AnimatorListenerAdapter() {
-                                @Override
-                                public void onAnimationEnd(Animator animation) {
-                                    mDeleteDropTarget.setVisibility(View.GONE);
-                                }
-                            });
-                    }
-                }
-                @Override
-                public void onAnimationCancel(Animator animation) {
-                    mDragView = null;
-                }
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    mDragView = null;
-                    if (onCompleteRunnable != null) {
-                        onCompleteRunnable.run();
-                    }
-                }
-            });
-            mZoomInOutAnim.start();
-            return true;
-        } else {
-            if (onCompleteRunnable != null) {
-                onCompleteRunnable.run();
-            }
-        }
-        return false;
-    }
-
-    /*
-     * Flinging to delete - IN PROGRESS
-     */
-    private PointF isFlingingToDelete() {
-        ViewConfiguration config = ViewConfiguration.get(getContext());
-        mVelocityTracker.computeCurrentVelocity(1000, config.getScaledMaximumFlingVelocity());
-
-        if (mVelocityTracker.getYVelocity() < mFlingToDeleteThresholdVelocity) {
-            // Do a quick dot product test to ensure that we are flinging upwards
-            PointF vel = new PointF(mVelocityTracker.getXVelocity(),
-                    mVelocityTracker.getYVelocity());
-            PointF upVec = new PointF(0f, -1f);
-            float theta = (float) Math.acos(((vel.x * upVec.x) + (vel.y * upVec.y)) /
-                    (vel.length() * upVec.length()));
-            if (theta <= Math.toRadians(FLING_TO_DELETE_MAX_FLING_DEGREES)) {
-                return vel;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Creates an animation from the current drag view along its current velocity vector.
-     * For this animation, the alpha runs for a fixed duration and we update the position
-     * progressively.
-     */
-    private static class FlingAlongVectorAnimatorUpdateListener implements AnimatorUpdateListener {
-        private View mDragView;
-        private PointF mVelocity;
-        private Rect mFrom;
-        private long mPrevTime;
-        private float mFriction;
-
-        private final TimeInterpolator mAlphaInterpolator = new DecelerateInterpolator(0.75f);
-
-        public FlingAlongVectorAnimatorUpdateListener(View dragView, PointF vel, Rect from,
-                long startTime, float friction) {
-            mDragView = dragView;
-            mVelocity = vel;
-            mFrom = from;
-            mPrevTime = startTime;
-            mFriction = 1f - (mDragView.getResources().getDisplayMetrics().density * friction);
-        }
-
-        @Override
-        public void onAnimationUpdate(ValueAnimator animation) {
-            float t = ((Float) animation.getAnimatedValue()).floatValue();
-            long curTime = AnimationUtils.currentAnimationTimeMillis();
-
-            mFrom.left += (mVelocity.x * (curTime - mPrevTime) / 1000f);
-            mFrom.top += (mVelocity.y * (curTime - mPrevTime) / 1000f);
-
-            mDragView.setTranslationX(mFrom.left);
-            mDragView.setTranslationY(mFrom.top);
-            mDragView.setAlpha(1f - mAlphaInterpolator.getInterpolation(t));
-
-            mVelocity.x *= mFriction;
-            mVelocity.y *= mFriction;
-            mPrevTime = curTime;
-        }
-    };
-
-    private Runnable createPostDeleteAnimationRunnable(final View dragView) {
-        return new Runnable() {
-            @Override
-            public void run() {
-                int dragViewIndex = indexOfChild(dragView);
-
-                // For each of the pages around the drag view, animate them from the previous
-                // position to the new position in the layout (as a result of the drag view moving
-                // in the layout)
-                // NOTE: We can make an assumption here because we have side-bound pages that we
-                //       will always have pages to animate in from the left
-                getVisiblePages(mTempVisiblePagesRange);
-                boundByReorderablePages(true, mTempVisiblePagesRange);
-                boolean isLastWidgetPage = (mTempVisiblePagesRange[0] == mTempVisiblePagesRange[1]);
-                boolean slideFromLeft = (isLastWidgetPage ||
-                        dragViewIndex > mTempVisiblePagesRange[0]);
-
-                // Setup the scroll to the correct page before we swap the views
-                if (slideFromLeft) {
-                    snapToPageImmediately(dragViewIndex - 1);
-                }
-
-                int firstIndex = (isLastWidgetPage ? 0 : mTempVisiblePagesRange[0]);
-                int lastIndex = Math.min(mTempVisiblePagesRange[1], getPageCount() - 1);
-                int lowerIndex = (slideFromLeft ? firstIndex : dragViewIndex + 1 );
-                int upperIndex = (slideFromLeft ? dragViewIndex - 1 : lastIndex);
-                ArrayList<Animator> animations = new ArrayList<Animator>();
-                for (int i = lowerIndex; i <= upperIndex; ++i) {
-                    View v = getChildAt(i);
-                    // dragViewIndex < pageUnderPointIndex, so after we remove the
-                    // drag view all subsequent views to pageUnderPointIndex will
-                    // shift down.
-                    int oldX = 0;
-                    int newX = 0;
-                    if (slideFromLeft) {
-                        if (i == 0) {
-                            // Simulate the page being offscreen with the page spacing
-                            oldX = getViewportOffsetX() + getChildOffset(i) - getChildWidth(i)
-                                    - mPageSpacing;
-                        } else {
-                            oldX = getViewportOffsetX() + getChildOffset(i - 1);
-                        }
-                        newX = getViewportOffsetX() + getChildOffset(i);
-                    } else {
-                        oldX = getChildOffset(i) - getChildOffset(i - 1);
-                        newX = 0;
-                    }
-
-                    // Animate the view translation from its old position to its new
-                    // position
-                    AnimatorSet anim = (AnimatorSet) v.getTag();
-                    if (anim != null) {
-                        anim.cancel();
-                    }
-
-                    // Note: Hacky, but we want to skip any optimizations to not draw completely
-                    // hidden views
-                    v.setAlpha(Math.max(v.getAlpha(), 0.01f));
-                    v.setTranslationX(oldX - newX);
-                    anim = new AnimatorSet();
-                    anim.playTogether(
-                            ObjectAnimator.ofFloat(v, "translationX", 0f),
-                            ObjectAnimator.ofFloat(v, "alpha", 1f));
-                    animations.add(anim);
-                    v.setTag(anim);
-                }
-
-                AnimatorSet slideAnimations = new AnimatorSet();
-                slideAnimations.playTogether(animations);
-                slideAnimations.setDuration(DELETE_SLIDE_IN_SIDE_PAGE_DURATION);
-                slideAnimations.addListener(new AnimatorListenerAdapter() {
-                    @Override
-                    public void onAnimationEnd(Animator animation) {
-                        final Runnable onCompleteRunnable = new Runnable() {
-                            @Override
-                            public void run() {
-                                mDeferringForDelete = false;
-                                onEndReordering();
-                                onRemoveViewAnimationCompleted();
-                            }
-                        };
-                        zoomIn(onCompleteRunnable);
-                    }
-                });
-                slideAnimations.start();
-
-                removeView(dragView);
-                onRemoveView(dragView, true);
-            }
-        };
-    }
-
-    public void onFlingToDelete(PointF vel) {
-        final long startTime = AnimationUtils.currentAnimationTimeMillis();
-
-        // NOTE: Because it takes time for the first frame of animation to actually be
-        // called and we expect the animation to be a continuation of the fling, we have
-        // to account for the time that has elapsed since the fling finished.  And since
-        // we don't have a startDelay, we will always get call to update when we call
-        // start() (which we want to ignore).
-        final TimeInterpolator tInterpolator = new TimeInterpolator() {
-            private int mCount = -1;
-            private long mStartTime;
-            private float mOffset;
-            /* Anonymous inner class ctor */ {
-                mStartTime = startTime;
-            }
-
-            @Override
-            public float getInterpolation(float t) {
-                if (mCount < 0) {
-                    mCount++;
-                } else if (mCount == 0) {
-                    mOffset = Math.min(0.5f, (float) (AnimationUtils.currentAnimationTimeMillis() -
-                            mStartTime) / FLING_TO_DELETE_FADE_OUT_DURATION);
-                    mCount++;
-                }
-                return Math.min(1f, mOffset + t);
-            }
-        };
-
-        final Rect from = new Rect();
-        final View dragView = mDragView;
-        from.left = (int) dragView.getTranslationX();
-        from.top = (int) dragView.getTranslationY();
-        AnimatorUpdateListener updateCb = new FlingAlongVectorAnimatorUpdateListener(dragView, vel,
-                from, startTime, FLING_TO_DELETE_FRICTION);
-
-        final Runnable onAnimationEndRunnable = createPostDeleteAnimationRunnable(dragView);
-
-        // Create and start the animation
-        ValueAnimator mDropAnim = new ValueAnimator();
-        mDropAnim.setInterpolator(tInterpolator);
-        mDropAnim.setDuration(FLING_TO_DELETE_FADE_OUT_DURATION);
-        mDropAnim.setFloatValues(0f, 1f);
-        mDropAnim.addUpdateListener(updateCb);
-        mDropAnim.addListener(new AnimatorListenerAdapter() {
-            public void onAnimationEnd(Animator animation) {
-                onAnimationEndRunnable.run();
-            }
-        });
-        mDropAnim.start();
-        mDeferringForDelete = true;
-    }
-
-    /* Drag to delete */
-    private boolean isHoveringOverDeleteDropTarget(int x, int y) {
-        if (mDeleteDropTarget != null) {
-            mAltTmpRect.set(0, 0, 0, 0);
-            View parent = (View) mDeleteDropTarget.getParent();
-            if (parent != null) {
-                parent.getGlobalVisibleRect(mAltTmpRect);
-            }
-            mDeleteDropTarget.getGlobalVisibleRect(mTmpRect);
-            mTmpRect.offset(-mAltTmpRect.left, -mAltTmpRect.top);
-            return mTmpRect.contains(x, y);
-        }
-        return false;
-    }
-
-    protected void setPageHoveringOverDeleteDropTarget(int viewIndex, boolean isHovering) {}
-
-    private void onDropToDelete() {
-        final View dragView = mDragView;
-
-        final float toScale = 0f;
-        final float toAlpha = 0f;
-
-        // Create and start the complex animation
-        ArrayList<Animator> animations = new ArrayList<Animator>();
-        AnimatorSet motionAnim = new AnimatorSet();
-        motionAnim.setInterpolator(new DecelerateInterpolator(2));
-        motionAnim.playTogether(
-                ObjectAnimator.ofFloat(dragView, "scaleX", toScale),
-                ObjectAnimator.ofFloat(dragView, "scaleY", toScale));
-        animations.add(motionAnim);
-
-        AnimatorSet alphaAnim = new AnimatorSet();
-        alphaAnim.setInterpolator(new LinearInterpolator());
-        alphaAnim.playTogether(
-                ObjectAnimator.ofFloat(dragView, "alpha", toAlpha));
-        animations.add(alphaAnim);
-
-        final Runnable onAnimationEndRunnable = createPostDeleteAnimationRunnable(dragView);
-
-        AnimatorSet anim = new AnimatorSet();
-        anim.playTogether(animations);
-        anim.setDuration(DRAG_TO_DELETE_FADE_OUT_DURATION);
-        anim.addListener(new AnimatorListenerAdapter() {
-            public void onAnimationEnd(Animator animation) {
-                onAnimationEndRunnable.run();
-            }
-        });
-        anim.start();
-
-        mDeferringForDelete = true;
-    }
-
-    /* Accessibility */
-    @Override
-    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
-        super.onInitializeAccessibilityNodeInfo(info);
-        info.setScrollable(getPageCount() > 1);
-        if (getCurrentPage() < getPageCount() - 1) {
-            info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
-        }
-        if (getCurrentPage() > 0) {
-            info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
-        }
-    }
-
-    @Override
-    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
-        super.onInitializeAccessibilityEvent(event);
-        event.setScrollable(true);
-        if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
-            event.setFromIndex(mCurrentPage);
-            event.setToIndex(mCurrentPage);
-            event.setItemCount(getChildCount());
-        }
-    }
-
-    @Override
-    public boolean performAccessibilityAction(int action, Bundle arguments) {
-        if (super.performAccessibilityAction(action, arguments)) {
-            return true;
-        }
-        switch (action) {
-            case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: {
-                if (getCurrentPage() < getPageCount() - 1) {
-                    scrollRight();
-                    return true;
-                }
-            } break;
-            case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: {
-                if (getCurrentPage() > 0) {
-                    scrollLeft();
-                    return true;
-                }
-            } break;
-        }
-        return false;
-    }
-
-    @Override
-    public boolean onHoverEvent(android.view.MotionEvent event) {
-        return true;
-    }
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/SecurityMessageDisplay.java b/policy/src/com/android/internal/policy/impl/keyguard/SecurityMessageDisplay.java
deleted file mode 100644
index 7760279..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/SecurityMessageDisplay.java
+++ /dev/null
@@ -1,31 +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.internal.policy.impl.keyguard;
-
-public interface SecurityMessageDisplay {
-    public void setMessage(CharSequence msg, boolean important);
-
-    public void setMessage(int resId, boolean important);
-
-    public void setMessage(int resId, boolean important, Object... formatArgs);
-
-    public void setTimeout(int timeout_ms);
-
-    public void showBouncer(int animationDuration);
-
-    public void hideBouncer(int animationDuration);
-}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java b/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java
deleted file mode 100644
index 073225f..0000000
--- a/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java
+++ /dev/null
@@ -1,1244 +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.internal.policy.impl.keyguard;
-
-import com.android.internal.R;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
-import android.content.Context;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.FloatProperty;
-import android.util.Log;
-import android.util.Property;
-import android.view.MotionEvent;
-import android.view.VelocityTracker;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.ViewGroup;
-import android.view.accessibility.AccessibilityManager;
-import android.view.animation.Interpolator;
-import android.widget.Scroller;
-
-/**
- * This layout handles interaction with the sliding security challenge views
- * that overlay/resize other keyguard contents.
- */
-public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout {
-    private static final String TAG = "SlidingChallengeLayout";
-    private static final boolean DEBUG = false;
-
-    // The drag handle is measured in dp above & below the top edge of the
-    // challenge view; these parameters change based on whether the challenge 
-    // is open or closed.
-    private static final int DRAG_HANDLE_CLOSED_ABOVE = 8; // dp
-    private static final int DRAG_HANDLE_CLOSED_BELOW = 0; // dp
-    private static final int DRAG_HANDLE_OPEN_ABOVE = 8; // dp
-    private static final int DRAG_HANDLE_OPEN_BELOW = 0; // dp
-
-    private static final int HANDLE_ANIMATE_DURATION = 250; // ms
-
-    // Drawn to show the drag handle in closed state; crossfades to the challenge view
-    // when challenge is fully visible
-    private boolean mEdgeCaptured;
-
-    private DisplayMetrics mDisplayMetrics;
-
-    // Initialized during measurement from child layoutparams
-    private View mExpandChallengeView;
-    private KeyguardSecurityContainer mChallengeView;
-    private View mScrimView;
-    private View mWidgetsView;
-
-    // Range: 0 (fully hidden) to 1 (fully visible)
-    private float mChallengeOffset = 1.f;
-    private boolean mChallengeShowing = true;
-    private boolean mChallengeShowingTargetState = true;
-    private boolean mWasChallengeShowing = true;
-    private boolean mIsBouncing = false;
-
-    private final Scroller mScroller;
-    private ObjectAnimator mFader;
-    private int mScrollState;
-    private OnChallengeScrolledListener mScrollListener;
-    private OnBouncerStateChangedListener mBouncerListener;
-
-    public static final int SCROLL_STATE_IDLE = 0;
-    public static final int SCROLL_STATE_DRAGGING = 1;
-    public static final int SCROLL_STATE_SETTLING = 2;
-    public static final int SCROLL_STATE_FADING = 3;
-
-    private static final int CHALLENGE_FADE_OUT_DURATION = 100;
-    private static final int CHALLENGE_FADE_IN_DURATION = 160;
-
-    private static final int MAX_SETTLE_DURATION = 600; // ms
-
-    // ID of the pointer in charge of a current drag
-    private int mActivePointerId = INVALID_POINTER;
-    private static final int INVALID_POINTER = -1;
-
-    // True if the user is currently dragging the slider
-    private boolean mDragging;
-    // True if the user may not drag until a new gesture begins
-    private boolean mBlockDrag;
-
-    private VelocityTracker mVelocityTracker;
-    private int mMinVelocity;
-    private int mMaxVelocity;
-    private float mGestureStartX, mGestureStartY; // where did you first touch the screen?
-    private int mGestureStartChallengeBottom; // where was the challenge at that time?
-
-    private int mDragHandleClosedBelow; // handle hitrect extension into the challenge view
-    private int mDragHandleClosedAbove; // extend the handle's hitrect this far above the line
-    private int mDragHandleOpenBelow; // handle hitrect extension into the challenge view
-    private int mDragHandleOpenAbove; // extend the handle's hitrect this far above the line
-
-    private int mDragHandleEdgeSlop;
-    private int mChallengeBottomBound; // Number of pixels from the top of the challenge view
-                                       // that should remain on-screen
-
-    private int mTouchSlop;
-    private int mTouchSlopSquare;
-
-    float mHandleAlpha;
-    float mFrameAlpha;
-    float mFrameAnimationTarget = Float.MIN_VALUE;
-    private ObjectAnimator mHandleAnimation;
-    private ObjectAnimator mFrameAnimation;
-
-    private boolean mHasGlowpad;
-
-    // We have an internal and external version, and we and them together.
-    private boolean mChallengeInteractiveExternal = true;
-    private boolean mChallengeInteractiveInternal = true;
-
-    static final Property<SlidingChallengeLayout, Float> HANDLE_ALPHA =
-            new FloatProperty<SlidingChallengeLayout>("handleAlpha") {
-        @Override
-        public void setValue(SlidingChallengeLayout view, float value) {
-            view.mHandleAlpha = value;
-            view.invalidate();
-        }
-
-        @Override
-        public Float get(SlidingChallengeLayout view) {
-            return view.mHandleAlpha;
-        }
-    };
-
-    // True if at least one layout pass has happened since the view was attached.
-    private boolean mHasLayout;
-
-    private static final Interpolator sMotionInterpolator = new Interpolator() {
-        public float getInterpolation(float t) {
-            t -= 1.0f;
-            return t * t * t * t * t + 1.0f;
-        }
-    };
-
-    private static final Interpolator sHandleFadeInterpolator = new Interpolator() {
-        public float getInterpolation(float t) {
-            return t * t;
-        }
-    };
-
-    private final Runnable mEndScrollRunnable = new Runnable () {
-        public void run() {
-            completeChallengeScroll();
-        }
-    };
-
-    private final OnClickListener mScrimClickListener = new OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            hideBouncer();
-        }
-    };
-
-    private final OnClickListener mExpandChallengeClickListener = new OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            if (!isChallengeShowing()) {
-                showChallenge(true);
-            }
-        }
-    };
-
-    /**
-     * Listener interface that reports changes in scroll state of the challenge area.
-     */
-    public interface OnChallengeScrolledListener {
-        /**
-         * The scroll state itself changed.
-         *
-         * <p>scrollState will be one of the following:</p>
-         *
-         * <ul>
-         * <li><code>SCROLL_STATE_IDLE</code> - The challenge area is stationary.</li>
-         * <li><code>SCROLL_STATE_DRAGGING</code> - The user is actively dragging
-         * the challenge area.</li>
-         * <li><code>SCROLL_STATE_SETTLING</code> - The challenge area is animating
-         * into place.</li>
-         * </ul>
-         *
-         * <p>Do not perform expensive operations (e.g. layout)
-         * while the scroll state is not <code>SCROLL_STATE_IDLE</code>.</p>
-         *
-         * @param scrollState The new scroll state of the challenge area.
-         */
-        public void onScrollStateChanged(int scrollState);
-
-        /**
-         * The precise position of the challenge area has changed.
-         *
-         * <p>NOTE: It is NOT safe to modify layout or call any View methods that may
-         * result in a requestLayout anywhere in your view hierarchy as a result of this call.
-         * It may be called during drawing.</p>
-         *
-         * @param scrollPosition New relative position of the challenge area.
-         *                       1.f = fully visible/ready to be interacted with.
-         *                       0.f = fully invisible/inaccessible to the user.
-         * @param challengeTop Position of the top edge of the challenge view in px in the
-         *                     SlidingChallengeLayout's coordinate system.
-         */
-        public void onScrollPositionChanged(float scrollPosition, int challengeTop);
-    }
-
-    public SlidingChallengeLayout(Context context) {
-        this(context, null);
-    }
-
-    public SlidingChallengeLayout(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public SlidingChallengeLayout(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-
-        mScroller = new Scroller(context, sMotionInterpolator);
-
-        final ViewConfiguration vc = ViewConfiguration.get(context);
-        mMinVelocity = vc.getScaledMinimumFlingVelocity();
-        mMaxVelocity = vc.getScaledMaximumFlingVelocity();
-
-        final Resources res = getResources();
-        mDragHandleEdgeSlop = res.getDimensionPixelSize(R.dimen.kg_edge_swipe_region_size);
-
-        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
-        mTouchSlopSquare = mTouchSlop * mTouchSlop;
-
-        mDisplayMetrics = res.getDisplayMetrics();
-        final float density = mDisplayMetrics.density;
-
-        // top half of the lock icon, plus another 25% to be sure
-        mDragHandleClosedAbove = (int) (DRAG_HANDLE_CLOSED_ABOVE * density + 0.5f);
-        mDragHandleClosedBelow = (int) (DRAG_HANDLE_CLOSED_BELOW * density + 0.5f);
-        mDragHandleOpenAbove = (int) (DRAG_HANDLE_OPEN_ABOVE * density + 0.5f);
-        mDragHandleOpenBelow = (int) (DRAG_HANDLE_OPEN_BELOW * density + 0.5f);
-
-        // how much space to account for in the handle when closed
-        mChallengeBottomBound = res.getDimensionPixelSize(R.dimen.kg_widget_pager_bottom_padding);
-
-        setWillNotDraw(false);
-        setSystemUiVisibility(SYSTEM_UI_FLAG_LAYOUT_STABLE);
-    }
-
-    public void setHandleAlpha(float alpha) {
-        if (mExpandChallengeView != null) {
-            mExpandChallengeView.setAlpha(alpha);
-        }
-    }
-
-    public void setChallengeInteractive(boolean interactive) {
-        mChallengeInteractiveExternal = interactive;
-        if (mExpandChallengeView != null) {
-            mExpandChallengeView.setEnabled(interactive);
-        }
-    }
-
-    void animateHandle(boolean visible) {
-        if (mHandleAnimation != null) {
-            mHandleAnimation.cancel();
-            mHandleAnimation = null;
-        }
-        final float targetAlpha = visible ? 1.f : 0.f;
-        if (targetAlpha == mHandleAlpha) {
-            return;
-        }
-        mHandleAnimation = ObjectAnimator.ofFloat(this, HANDLE_ALPHA, targetAlpha);
-        mHandleAnimation.setInterpolator(sHandleFadeInterpolator);
-        mHandleAnimation.setDuration(HANDLE_ANIMATE_DURATION);
-        mHandleAnimation.start();
-    }
-
-    private void sendInitialListenerUpdates() {
-        if (mScrollListener != null) {
-            int challengeTop = mChallengeView != null ? mChallengeView.getTop() : 0;
-            mScrollListener.onScrollPositionChanged(mChallengeOffset, challengeTop);
-            mScrollListener.onScrollStateChanged(mScrollState);
-        }
-    }
-
-    public void setOnChallengeScrolledListener(OnChallengeScrolledListener listener) {
-        mScrollListener = listener;
-        if (mHasLayout) {
-            sendInitialListenerUpdates();
-        }
-    }
-
-    public void setOnBouncerStateChangedListener(OnBouncerStateChangedListener listener) {
-        mBouncerListener = listener;
-    }
-
-    @Override
-    public void onAttachedToWindow() {
-        super.onAttachedToWindow();
-
-        mHasLayout = false;
-    }
-
-    @Override
-    public void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-
-        removeCallbacks(mEndScrollRunnable);
-        mHasLayout = false;
-    }
-
-    @Override
-    public void requestChildFocus(View child, View focused) {
-        if (mIsBouncing && child != mChallengeView) {
-            // Clear out of the bouncer if the user tries to move focus outside of
-            // the security challenge view.
-            hideBouncer();
-        }
-        super.requestChildFocus(child, focused);
-    }
-
-    // We want the duration of the page snap animation to be influenced by the distance that
-    // the screen has to travel, however, we don't want this duration to be effected in a
-    // purely linear fashion. Instead, we use this method to moderate the effect that the distance
-    // of travel has on the overall snap duration.
-    float distanceInfluenceForSnapDuration(float f) {
-        f -= 0.5f; // center the values about 0.
-        f *= 0.3f * Math.PI / 2.0f;
-        return (float) Math.sin(f);
-    }
-
-    void setScrollState(int state) {
-        if (mScrollState != state) {
-            mScrollState = state;
-
-            animateHandle(state == SCROLL_STATE_IDLE && !mChallengeShowing);
-            if (mScrollListener != null) {
-                mScrollListener.onScrollStateChanged(state);
-            }
-        }
-    }
-
-    void completeChallengeScroll() {
-        setChallengeShowing(mChallengeShowingTargetState);
-        mChallengeOffset = mChallengeShowing ? 1.f : 0.f;
-        setScrollState(SCROLL_STATE_IDLE);
-        mChallengeInteractiveInternal = true;
-        mChallengeView.setLayerType(LAYER_TYPE_NONE, null);
-    }
-
-    void setScrimView(View scrim) {
-        if (mScrimView != null) {
-            mScrimView.setOnClickListener(null);
-        }
-        mScrimView = scrim;
-        mScrimView.setVisibility(mIsBouncing ? VISIBLE : GONE);
-        mScrimView.setFocusable(true);
-        mScrimView.setOnClickListener(mScrimClickListener);
-    }
-
-    /**
-     * Animate the bottom edge of the challenge view to the given position.
-     *
-     * @param y desired final position for the bottom edge of the challenge view in px
-     * @param velocity velocity in
-     */
-    void animateChallengeTo(int y, int velocity) {
-        if (mChallengeView == null) {
-            // Nothing to do.
-            return;
-        }
-
-        cancelTransitionsInProgress();
-
-        mChallengeInteractiveInternal = false;
-        mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null);
-        final int sy = mChallengeView.getBottom();
-        final int dy = y - sy;
-        if (dy == 0) {
-            completeChallengeScroll();
-            return;
-        }
-
-        setScrollState(SCROLL_STATE_SETTLING);
-
-        final int childHeight = mChallengeView.getHeight();
-        final int halfHeight = childHeight / 2;
-        final float distanceRatio = Math.min(1f, 1.0f * Math.abs(dy) / childHeight);
-        final float distance = halfHeight + halfHeight *
-                distanceInfluenceForSnapDuration(distanceRatio);
-
-        int duration = 0;
-        velocity = Math.abs(velocity);
-        if (velocity > 0) {
-            duration = 4 * Math.round(1000 * Math.abs(distance / velocity));
-        } else {
-            final float childDelta = (float) Math.abs(dy) / childHeight;
-            duration = (int) ((childDelta + 1) * 100);
-        }
-        duration = Math.min(duration, MAX_SETTLE_DURATION);
-
-        mScroller.startScroll(0, sy, 0, dy, duration);
-        postInvalidateOnAnimation();
-    }
-
-    private void setChallengeShowing(boolean showChallenge) {
-        if (mChallengeShowing == showChallenge) {
-            return;
-        }
-        mChallengeShowing = showChallenge;
-
-        if (mExpandChallengeView == null || mChallengeView == null) {
-            // These might not be here yet if we haven't been through layout.
-            // If we haven't, the first layout pass will set everything up correctly
-            // based on mChallengeShowing as set above.
-            return;
-        }
-
-        if (mChallengeShowing) {
-            mExpandChallengeView.setVisibility(View.INVISIBLE);
-            mChallengeView.setVisibility(View.VISIBLE);
-            if (AccessibilityManager.getInstance(mContext).isEnabled()) {
-                mChallengeView.requestAccessibilityFocus();
-                mChallengeView.announceForAccessibility(mContext.getString(
-                        R.string.keyguard_accessibility_unlock_area_expanded));
-            }
-        } else {
-            mExpandChallengeView.setVisibility(View.VISIBLE);
-            mChallengeView.setVisibility(View.INVISIBLE);
-            if (AccessibilityManager.getInstance(mContext).isEnabled()) {
-                mExpandChallengeView.requestAccessibilityFocus();
-                mChallengeView.announceForAccessibility(mContext.getString(
-                        R.string.keyguard_accessibility_unlock_area_collapsed));
-            }
-        }
-    }
-
-    /**
-     * @return true if the challenge is at all visible.
-     */
-    public boolean isChallengeShowing() {
-        return mChallengeShowing;
-    }
-
-    @Override
-    public boolean isChallengeOverlapping() {
-        return mChallengeShowing;
-    }
-
-    @Override
-    public boolean isBouncing() {
-        return mIsBouncing;
-    }
-
-    @Override
-    public int getBouncerAnimationDuration() {
-        return HANDLE_ANIMATE_DURATION;
-    }
-
-    @Override
-    public void showBouncer() {
-        if (mIsBouncing) return;
-        mWasChallengeShowing = mChallengeShowing;
-        mIsBouncing = true;
-        showChallenge(true);
-        if (mScrimView != null) {
-            Animator anim = ObjectAnimator.ofFloat(mScrimView, "alpha", 1f);
-            anim.setDuration(HANDLE_ANIMATE_DURATION);
-            anim.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationStart(Animator animation) {
-                    mScrimView.setVisibility(VISIBLE);
-                }
-            });
-            anim.start();
-        }
-        if (mChallengeView != null) {
-            mChallengeView.showBouncer(HANDLE_ANIMATE_DURATION);
-        }
-
-        if (mBouncerListener != null) {
-            mBouncerListener.onBouncerStateChanged(true);
-        }
-    }
-
-    @Override
-    public void hideBouncer() {
-        if (!mIsBouncing) return;
-        if (!mWasChallengeShowing) showChallenge(false);
-        mIsBouncing = false;
-
-        if (mScrimView != null) {
-            Animator anim = ObjectAnimator.ofFloat(mScrimView, "alpha", 0f);
-            anim.setDuration(HANDLE_ANIMATE_DURATION);
-            anim.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    mScrimView.setVisibility(GONE);
-                }
-            });
-            anim.start();
-        }
-        if (mChallengeView != null) {
-            mChallengeView.hideBouncer(HANDLE_ANIMATE_DURATION);
-        }
-        if (mBouncerListener != null) {
-            mBouncerListener.onBouncerStateChanged(false);
-        }
-    }
-
-    private int getChallengeMargin(boolean expanded) {
-        return expanded && mHasGlowpad ? 0 : mDragHandleEdgeSlop;
-    }
-
-    private float getChallengeAlpha() {
-        float x = mChallengeOffset - 1;
-        return x * x * x + 1.f;
-    }
-
-    @Override
-    public void requestDisallowInterceptTouchEvent(boolean allowIntercept) {
-        // We'll intercept whoever we feel like! ...as long as it isn't a challenge view.
-        // If there are one or more pointers in the challenge view before we take over
-        // touch events, onInterceptTouchEvent will set mBlockDrag.
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-        if (mVelocityTracker == null) {
-            mVelocityTracker = VelocityTracker.obtain();
-        }
-        mVelocityTracker.addMovement(ev);
-
-        final int action = ev.getActionMasked();
-        switch (action) {
-            case MotionEvent.ACTION_DOWN:
-                mGestureStartX = ev.getX();
-                mGestureStartY = ev.getY();
-                mBlockDrag = false;
-                break;
-
-            case MotionEvent.ACTION_CANCEL:
-            case MotionEvent.ACTION_UP:
-                resetTouch();
-                break;
-
-            case MotionEvent.ACTION_MOVE:
-                final int count = ev.getPointerCount();
-                for (int i = 0; i < count; i++) {
-                    final float x = ev.getX(i);
-                    final float y = ev.getY(i);
-                    if (!mIsBouncing && mActivePointerId == INVALID_POINTER
-                                && (crossedDragHandle(x, y, mGestureStartY)
-                                || (isInChallengeView(x, y) &&
-                                        mScrollState == SCROLL_STATE_SETTLING))) {
-                        mActivePointerId = ev.getPointerId(i);
-                        mGestureStartX = x;
-                        mGestureStartY = y;
-                        mGestureStartChallengeBottom = getChallengeBottom();
-                        mDragging = true;
-                        mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null);
-                    } else if (mChallengeShowing && isInChallengeView(x, y)) {
-                        mBlockDrag = true;
-                    }
-                }
-                break;
-        }
-
-        if (mBlockDrag || isChallengeInteractionBlocked()) {
-            mActivePointerId = INVALID_POINTER;
-            mDragging = false;
-        }
-
-        return mDragging;
-    }
-
-    private boolean isChallengeInteractionBlocked() {
-        return !mChallengeInteractiveExternal || !mChallengeInteractiveInternal;
-    }
-
-    private void resetTouch() {
-        mVelocityTracker.recycle();
-        mVelocityTracker = null;
-        mActivePointerId = INVALID_POINTER;
-        mDragging = mBlockDrag = false;
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev) {
-        if (mVelocityTracker == null) {
-            mVelocityTracker = VelocityTracker.obtain();
-        }
-        mVelocityTracker.addMovement(ev);
-
-        final int action = ev.getActionMasked();
-        switch (action) {
-            case MotionEvent.ACTION_DOWN:
-                mBlockDrag = false;
-                mGestureStartX = ev.getX();
-                mGestureStartY = ev.getY();
-                break;
-
-            case MotionEvent.ACTION_CANCEL:
-                if (mDragging && !isChallengeInteractionBlocked()) {
-                    showChallenge(0);
-                }
-                resetTouch();
-                break;
-
-            case MotionEvent.ACTION_POINTER_UP:
-                if (mActivePointerId != ev.getPointerId(ev.getActionIndex())) {
-                    break;
-                }
-            case MotionEvent.ACTION_UP:
-                if (mDragging && !isChallengeInteractionBlocked()) {
-                    mVelocityTracker.computeCurrentVelocity(1000, mMaxVelocity);
-                    showChallenge((int) mVelocityTracker.getYVelocity(mActivePointerId));
-                }
-                resetTouch();
-                break;
-
-            case MotionEvent.ACTION_MOVE:
-                if (!mDragging && !mBlockDrag && !mIsBouncing) {
-                    final int count = ev.getPointerCount();
-                    for (int i = 0; i < count; i++) {
-                        final float x = ev.getX(i);
-                        final float y = ev.getY(i);
-
-                        if ((isInDragHandle(x, y) || crossedDragHandle(x, y, mGestureStartY) ||
-                                (isInChallengeView(x, y) && mScrollState == SCROLL_STATE_SETTLING))
-                                && mActivePointerId == INVALID_POINTER
-                                && !isChallengeInteractionBlocked()) {
-                            mGestureStartX = x;
-                            mGestureStartY = y;
-                            mActivePointerId = ev.getPointerId(i);
-                            mGestureStartChallengeBottom = getChallengeBottom();
-                            mDragging = true;
-                            mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null);
-                            break;
-                        }
-                    }
-                }
-                // Not an else; this can be set above.
-                if (mDragging) {
-                    // No-op if already in this state, but set it here in case we arrived
-                    // at this point from either intercept or the above.
-                    setScrollState(SCROLL_STATE_DRAGGING);
-
-                    final int index = ev.findPointerIndex(mActivePointerId);
-                    if (index < 0) {
-                        // Oops, bogus state. We lost some touch events somewhere.
-                        // Just drop it with no velocity and let things settle.
-                        resetTouch();
-                        showChallenge(0);
-                        return true;
-                    }
-                    final float y = ev.getY(index);
-                    final float pos = Math.min(y - mGestureStartY,
-                            getLayoutBottom() - mChallengeBottomBound);
-
-                    moveChallengeTo(mGestureStartChallengeBottom + (int) pos);
-                }
-                break;
-        }
-        return true;
-    }
-
-    /**
-     * The lifecycle of touch events is subtle and it's very easy to do something
-     * that will cause bugs that will be nasty to track when overriding this method.
-     * Normally one should always override onInterceptTouchEvent instead.
-     *
-     * To put it another way, don't try this at home.
-     */
-    @Override
-    public boolean dispatchTouchEvent(MotionEvent ev) {
-        final int action = ev.getActionMasked();
-        boolean handled = false;
-        if (action == MotionEvent.ACTION_DOWN) {
-            // Defensive programming: if we didn't get the UP or CANCEL, reset anyway.
-            mEdgeCaptured = false;
-        }
-        if (mWidgetsView != null && !mIsBouncing && (mEdgeCaptured || isEdgeSwipeBeginEvent(ev))) {
-            // Normally we would need to do a lot of extra stuff here.
-            // We can only get away with this because we haven't padded in
-            // the widget pager or otherwise transformed it during layout.
-            // We also don't support things like splitting MotionEvents.
-
-            // We set handled to captured even if dispatch is returning false here so that
-            // we don't send a different view a busted or incomplete event stream.
-            handled = mEdgeCaptured |= mWidgetsView.dispatchTouchEvent(ev);
-        }
-
-        if (!handled && !mEdgeCaptured) {
-            handled = super.dispatchTouchEvent(ev);
-        }
-
-        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
-            mEdgeCaptured = false;
-        }
-
-        return handled;
-    }
-
-    private boolean isEdgeSwipeBeginEvent(MotionEvent ev) {
-        if (ev.getActionMasked() != MotionEvent.ACTION_DOWN) {
-            return false;
-        }
-
-        final float x = ev.getX();
-        return x < mDragHandleEdgeSlop || x >= getWidth() - mDragHandleEdgeSlop;
-    }
-
-    /**
-     * We only want to add additional vertical space to the drag handle when the panel is fully
-     * closed.
-     */
-    private int getDragHandleSizeAbove() {
-        return isChallengeShowing() ? mDragHandleOpenAbove : mDragHandleClosedAbove;
-    }
-    private int getDragHandleSizeBelow() {
-        return isChallengeShowing() ? mDragHandleOpenBelow : mDragHandleClosedBelow;
-    }
-
-    private boolean isInChallengeView(float x, float y) {
-        return isPointInView(x, y, mChallengeView);
-    }
-
-    private boolean isInDragHandle(float x, float y) {
-        return isPointInView(x, y, mExpandChallengeView);
-    }
-
-    private boolean isPointInView(float x, float y, View view) {
-        if (view == null) {
-            return false;
-        }
-        return x >= view.getLeft() && y >= view.getTop()
-                && x < view.getRight() && y < view.getBottom();
-    }
-
-    private boolean crossedDragHandle(float x, float y, float initialY) {
-
-        final int challengeTop = mChallengeView.getTop();
-        final boolean horizOk = x >= 0 && x < getWidth();
-
-        final boolean vertOk;
-        if (mChallengeShowing) {
-            vertOk = initialY < (challengeTop - getDragHandleSizeAbove()) &&
-                    y > challengeTop + getDragHandleSizeBelow();
-        } else {
-            vertOk = initialY > challengeTop + getDragHandleSizeBelow() &&
-                    y < challengeTop - getDragHandleSizeAbove();
-        }
-        return horizOk && vertOk;
-    }
-
-    private int makeChildMeasureSpec(int maxSize, int childDimen) {
-        final int mode;
-        final int size;
-        switch (childDimen) {
-            case LayoutParams.WRAP_CONTENT:
-                mode = MeasureSpec.AT_MOST;
-                size = maxSize;
-                break;
-            case LayoutParams.MATCH_PARENT:
-                mode = MeasureSpec.EXACTLY;
-                size = maxSize;
-                break;
-            default:
-                mode = MeasureSpec.EXACTLY;
-                size = Math.min(maxSize, childDimen);
-                break;
-        }
-        return MeasureSpec.makeMeasureSpec(size, mode);
-    }
-
-    @Override
-    protected void onMeasure(int widthSpec, int heightSpec) {
-        if (MeasureSpec.getMode(widthSpec) != MeasureSpec.EXACTLY ||
-                MeasureSpec.getMode(heightSpec) != MeasureSpec.EXACTLY) {
-            throw new IllegalArgumentException(
-                    "SlidingChallengeLayout must be measured with an exact size");
-        }
-
-        final int width = MeasureSpec.getSize(widthSpec);
-        final int height = MeasureSpec.getSize(heightSpec);
-        setMeasuredDimension(width, height);
-
-        // Find one and only one challenge view.
-        final View oldChallengeView = mChallengeView;
-        final View oldExpandChallengeView = mChallengeView;
-        mChallengeView = null;
-        mExpandChallengeView = null;
-        final int count = getChildCount();
-
-        // First iteration through the children finds special children and sets any associated
-        // state.
-        for (int i = 0; i < count; i++) {
-            final View child = getChildAt(i);
-            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
-            if (lp.childType == LayoutParams.CHILD_TYPE_CHALLENGE) {
-                if (mChallengeView != null) {
-                    throw new IllegalStateException(
-                            "There may only be one child with layout_isChallenge=\"true\"");
-                }
-                if (!(child instanceof KeyguardSecurityContainer)) {
-                            throw new IllegalArgumentException(
-                                    "Challenge must be a KeyguardSecurityContainer");
-                }
-                mChallengeView = (KeyguardSecurityContainer) child;
-                if (mChallengeView != oldChallengeView) {
-                    mChallengeView.setVisibility(mChallengeShowing ? VISIBLE : INVISIBLE);
-                }
-                // We're going to play silly games with the frame's background drawable later.
-                if (!mHasLayout) {
-                    // Set up the margin correctly based on our content for the first run.
-                    mHasGlowpad = child.findViewById(R.id.keyguard_selector_view) != null;
-                    lp.leftMargin = lp.rightMargin = getChallengeMargin(true);
-                }
-            } else if (lp.childType == LayoutParams.CHILD_TYPE_EXPAND_CHALLENGE_HANDLE) {
-                if (mExpandChallengeView != null) {
-                    throw new IllegalStateException(
-                            "There may only be one child with layout_childType"
-                            + "=\"expandChallengeHandle\"");
-                }
-                mExpandChallengeView = child;
-                if (mExpandChallengeView != oldExpandChallengeView) {
-                    mExpandChallengeView.setVisibility(mChallengeShowing ? INVISIBLE : VISIBLE);
-                    mExpandChallengeView.setOnClickListener(mExpandChallengeClickListener);
-                }
-            } else if (lp.childType == LayoutParams.CHILD_TYPE_SCRIM) {
-                setScrimView(child);
-            } else if (lp.childType == LayoutParams.CHILD_TYPE_WIDGETS) {
-                mWidgetsView = child;
-            }
-        }
-
-        // We want to measure the challenge view first, since the KeyguardWidgetPager
-        // needs to do things its measure pass that are dependent on the challenge view
-        // having been measured.
-        if (mChallengeView != null && mChallengeView.getVisibility() != View.GONE) {
-            // This one's a little funny. If the IME is present - reported in the form
-            // of insets on the root view - we only give the challenge the space it would
-            // have had if the IME wasn't there in order to keep the rest of the layout stable.
-            // We base this on the layout_maxHeight on the challenge view. If it comes out
-            // negative or zero, either we didn't have a maxHeight or we're totally out of space,
-            // so give up and measure as if this rule weren't there.
-            int challengeHeightSpec = heightSpec;
-            final View root = getRootView();
-            if (root != null) {
-                final LayoutParams lp = (LayoutParams) mChallengeView.getLayoutParams();
-                final int specSize = MeasureSpec.getSize(heightSpec);
-                final int windowHeight = mDisplayMetrics.heightPixels - root.getPaddingTop();
-                final int diff = windowHeight - specSize;
-                final int maxChallengeHeight = lp.maxHeight - diff;
-                if (maxChallengeHeight > 0) {
-                    challengeHeightSpec = makeChildMeasureSpec(maxChallengeHeight, lp.height);
-                }
-            }
-            measureChildWithMargins(mChallengeView, widthSpec, 0, challengeHeightSpec, 0);
-        }
-
-        // Measure the rest of the children
-        for (int i = 0; i < count; i++) {
-            final View child = getChildAt(i);
-            if (child.getVisibility() == GONE) {
-                continue;
-            }
-            // Don't measure the challenge view twice!
-            if (child == mChallengeView) continue;
-
-            // Measure children. Widget frame measures special, so that we can ignore
-            // insets for the IME.
-            int parentWidthSpec = widthSpec, parentHeightSpec = heightSpec;
-            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
-            if (lp.childType == LayoutParams.CHILD_TYPE_WIDGETS) {
-                final View root = getRootView();
-                if (root != null) {
-                    // This calculation is super dodgy and relies on several assumptions.
-                    // Specifically that the root of the window will be padded in for insets
-                    // and that the window is LAYOUT_IN_SCREEN.
-                    final int windowWidth = mDisplayMetrics.widthPixels;
-                    final int windowHeight = mDisplayMetrics.heightPixels - root.getPaddingTop();
-                    parentWidthSpec = MeasureSpec.makeMeasureSpec(
-                            windowWidth, MeasureSpec.EXACTLY);
-                    parentHeightSpec = MeasureSpec.makeMeasureSpec(
-                            windowHeight, MeasureSpec.EXACTLY);
-                }
-            }
-            measureChildWithMargins(child, parentWidthSpec, 0, parentHeightSpec, 0);
-        }
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int l, int t, int r, int b) {
-        final int paddingLeft = getPaddingLeft();
-        final int paddingTop = getPaddingTop();
-        final int paddingRight = getPaddingRight();
-        final int paddingBottom = getPaddingBottom();
-        final int width = r - l;
-        final int height = b - t;
-
-        final int count = getChildCount();
-        for (int i = 0; i < count; i++) {
-            final View child = getChildAt(i);
-
-            if (child.getVisibility() == GONE) continue;
-
-            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
-
-            if (lp.childType == LayoutParams.CHILD_TYPE_CHALLENGE) {
-                // Challenge views pin to the bottom, offset by a portion of their height,
-                // and center horizontally.
-                final int center = (paddingLeft + width - paddingRight) / 2;
-                final int childWidth = child.getMeasuredWidth();
-                final int childHeight = child.getMeasuredHeight();
-                final int left = center - childWidth / 2;
-                final int layoutBottom = height - paddingBottom - lp.bottomMargin;
-                // We use the top of the challenge view to position the handle, so
-                // we never want less than the handle size showing at the bottom.
-                final int bottom = layoutBottom + (int) ((childHeight - mChallengeBottomBound)
-                        * (1 - mChallengeOffset));
-                child.setAlpha(getChallengeAlpha());
-                child.layout(left, bottom - childHeight, left + childWidth, bottom);
-            } else if (lp.childType == LayoutParams.CHILD_TYPE_EXPAND_CHALLENGE_HANDLE) {
-                final int center = (paddingLeft + width - paddingRight) / 2;
-                final int left = center - child.getMeasuredWidth() / 2;
-                final int right = left + child.getMeasuredWidth();
-                final int bottom = height - paddingBottom - lp.bottomMargin;
-                final int top = bottom - child.getMeasuredHeight();
-                child.layout(left, top, right, bottom);
-            } else {
-                // Non-challenge views lay out from the upper left, layered.
-                child.layout(paddingLeft + lp.leftMargin,
-                        paddingTop + lp.topMargin,
-                        paddingLeft + child.getMeasuredWidth(),
-                        paddingTop + child.getMeasuredHeight());
-            }
-        }
-
-        if (!mHasLayout) {
-            mHasLayout = true;
-        }
-    }
-
-    @Override
-    public void draw(Canvas c) {
-        super.draw(c);
-        if (DEBUG) {
-            final Paint debugPaint = new Paint();
-            debugPaint.setColor(0x40FF00CC);
-            // show the isInDragHandle() rect
-            c.drawRect(mDragHandleEdgeSlop,
-                    mChallengeView.getTop() - getDragHandleSizeAbove(),
-                    getWidth() - mDragHandleEdgeSlop,
-                    mChallengeView.getTop() + getDragHandleSizeBelow(),
-                    debugPaint);
-        }
-    }
-
-    public void computeScroll() {
-        super.computeScroll();
-
-        if (!mScroller.isFinished()) {
-            if (mChallengeView == null) {
-                // Can't scroll if the view is missing.
-                Log.e(TAG, "Challenge view missing in computeScroll");
-                mScroller.abortAnimation();
-                return;
-            }
-
-            mScroller.computeScrollOffset();
-            moveChallengeTo(mScroller.getCurrY());
-
-            if (mScroller.isFinished()) {
-                post(mEndScrollRunnable);
-            }
-        }
-    }
-
-    private void cancelTransitionsInProgress() {
-        if (!mScroller.isFinished()) {
-            mScroller.abortAnimation();
-            completeChallengeScroll();
-        }
-        if (mFader != null) {
-            mFader.cancel();
-        }
-    }
-
-    public void fadeInChallenge() {
-        fadeChallenge(true);
-    }
-
-    public void fadeOutChallenge() {
-        fadeChallenge(false);
-    }
-
-    public void fadeChallenge(final boolean show) {
-        if (mChallengeView != null) {
-
-            cancelTransitionsInProgress();
-            float alpha = show ? 1f : 0f;
-            int duration = show ? CHALLENGE_FADE_IN_DURATION : CHALLENGE_FADE_OUT_DURATION;
-            mFader = ObjectAnimator.ofFloat(mChallengeView, "alpha", alpha);
-            mFader.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationStart(Animator animation) {
-                    onFadeStart(show);
-                }
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    onFadeEnd(show);
-                }
-            });
-            mFader.setDuration(duration);
-            mFader.start();
-        }
-    }
-
-    private int getMaxChallengeBottom() {
-        if (mChallengeView == null) return 0;
-        final int layoutBottom = getLayoutBottom();
-        final int challengeHeight = mChallengeView.getMeasuredHeight();
-
-        return (layoutBottom + challengeHeight - mChallengeBottomBound);
-    }
-
-    private int getMinChallengeBottom() {
-        return getLayoutBottom();
-    }
-
-
-    private void onFadeStart(boolean show) {
-        mChallengeInteractiveInternal = false;
-        mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null);
-
-        if (show) {
-            moveChallengeTo(getMinChallengeBottom());
-        }
-
-        setScrollState(SCROLL_STATE_FADING);
-    }
-
-    private void onFadeEnd(boolean show) {
-        mChallengeInteractiveInternal = true;
-        setChallengeShowing(show);
-
-        if (!show) {
-            moveChallengeTo(getMaxChallengeBottom());
-        }
-
-        mChallengeView.setLayerType(LAYER_TYPE_NONE, null);
-        mFader = null;
-        setScrollState(SCROLL_STATE_IDLE);
-    }
-
-    public int getMaxChallengeTop() {
-        if (mChallengeView == null) return 0;
-
-        final int layoutBottom = getLayoutBottom();
-        final int challengeHeight = mChallengeView.getMeasuredHeight();
-        return layoutBottom - challengeHeight;
-    }
-
-    /**
-     * Move the bottom edge of mChallengeView to a new position and notify the listener
-     * if it represents a change in position. Changes made through this method will
-     * be stable across layout passes. If this method is called before first layout of
-     * this SlidingChallengeLayout it will have no effect.
-     *
-     * @param bottom New bottom edge in px in this SlidingChallengeLayout's coordinate system.
-     * @return true if the challenge view was moved
-     */
-    private boolean moveChallengeTo(int bottom) {
-        if (mChallengeView == null || !mHasLayout) {
-            return false;
-        }
-
-        final int layoutBottom = getLayoutBottom();
-        final int challengeHeight = mChallengeView.getHeight();
-
-        bottom = Math.max(getMinChallengeBottom(),
-                Math.min(bottom, getMaxChallengeBottom()));
-
-        float offset = 1.f - (float) (bottom - layoutBottom) /
-                (challengeHeight - mChallengeBottomBound);
-        mChallengeOffset = offset;
-        if (offset > 0 && !mChallengeShowing) {
-            setChallengeShowing(true);
-        }
-
-        mChallengeView.layout(mChallengeView.getLeft(),
-                bottom - mChallengeView.getHeight(), mChallengeView.getRight(), bottom);
-
-        mChallengeView.setAlpha(getChallengeAlpha());
-        if (mScrollListener != null) {
-            mScrollListener.onScrollPositionChanged(offset, mChallengeView.getTop());
-        }
-        postInvalidateOnAnimation();
-        return true;
-    }
-
-    /**
-     * The bottom edge of this SlidingChallengeLayout's coordinate system; will coincide with
-     * the bottom edge of mChallengeView when the challenge is fully opened.
-     */
-    private int getLayoutBottom() {
-        final int bottomMargin = (mChallengeView == null)
-                ? 0
-                : ((LayoutParams) mChallengeView.getLayoutParams()).bottomMargin;
-        final int layoutBottom = getMeasuredHeight() - getPaddingBottom() - bottomMargin;
-        return layoutBottom;
-    }
-
-    /**
-     * The bottom edge of mChallengeView; essentially, where the sliding challenge 'is'.
-     */
-    private int getChallengeBottom() {
-        if (mChallengeView == null) return 0;
-
-        return mChallengeView.getBottom();
-    }
-
-    /**
-     * Show or hide the challenge view, animating it if necessary.
-     * @param show true to show, false to hide
-     */
-    public void showChallenge(boolean show) {
-        showChallenge(show, 0);
-        if (!show) {
-            // Block any drags in progress so that callers can use this to disable dragging
-            // for other touch interactions.
-            mBlockDrag = true;
-        }
-    }
-
-    private void showChallenge(int velocity) {
-        boolean show = false;
-        if (Math.abs(velocity) > mMinVelocity) {
-            show = velocity < 0;
-        } else {
-            show = mChallengeOffset >= 0.5f;
-        }
-        showChallenge(show, velocity);
-    }
-
-    private void showChallenge(boolean show, int velocity) {
-        if (mChallengeView == null) {
-            setChallengeShowing(false);
-            return;
-        }
-
-        if (mHasLayout) {
-            mChallengeShowingTargetState = show;
-            final int layoutBottom = getLayoutBottom();
-            animateChallengeTo(show ? layoutBottom :
-                    layoutBottom + mChallengeView.getHeight() - mChallengeBottomBound, velocity);
-        }
-    }
-
-    @Override
-    public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
-        return new LayoutParams(getContext(), attrs);
-    }
-
-    @Override
-    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
-        return p instanceof LayoutParams ? new LayoutParams((LayoutParams) p) :
-                p instanceof MarginLayoutParams ? new LayoutParams((MarginLayoutParams) p) :
-                new LayoutParams(p);
-    }
-
-    @Override
-    protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
-        return new LayoutParams();
-    }
-
-    @Override
-    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
-        return p instanceof LayoutParams;
-    }
-
-    public static class LayoutParams extends MarginLayoutParams {
-        public int childType = CHILD_TYPE_NONE;
-        public static final int CHILD_TYPE_NONE = 0;
-        public static final int CHILD_TYPE_CHALLENGE = 2;
-        public static final int CHILD_TYPE_SCRIM = 4;
-        public static final int CHILD_TYPE_WIDGETS = 5;
-        public static final int CHILD_TYPE_EXPAND_CHALLENGE_HANDLE = 6;
-
-        public int maxHeight;
-
-        public LayoutParams() {
-            this(MATCH_PARENT, WRAP_CONTENT);
-        }
-
-        public LayoutParams(int width, int height) {
-            super(width, height);
-        }
-
-        public LayoutParams(android.view.ViewGroup.LayoutParams source) {
-            super(source);
-        }
-
-        public LayoutParams(MarginLayoutParams source) {
-            super(source);
-        }
-
-        public LayoutParams(LayoutParams source) {
-            super(source);
-
-            childType = source.childType;
-        }
-
-        public LayoutParams(Context c, AttributeSet attrs) {
-            super(c, attrs);
-
-            final TypedArray a = c.obtainStyledAttributes(attrs,
-                    R.styleable.SlidingChallengeLayout_Layout);
-            childType = a.getInt(R.styleable.SlidingChallengeLayout_Layout_layout_childType,
-                    CHILD_TYPE_NONE);
-            maxHeight = a.getDimensionPixelSize(
-                    R.styleable.SlidingChallengeLayout_Layout_layout_maxHeight, 0);
-            a.recycle();
-        }
-    }
-}
diff --git a/preloaded-classes b/preloaded-classes
index 8d1d1a5..cb2ace3 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -663,8 +663,8 @@
 android.net.wifi.WifiManager
 android.net.wifi.WifiManager$ServiceHandler
 android.net.wifi.WifiNative
-android.nfc.INdefPushCallback
-android.nfc.INdefPushCallback$Stub
+android.nfc.IAppCallback
+android.nfc.IAppCallback$Stub
 android.nfc.INfcAdapter
 android.nfc.INfcAdapter$Stub
 android.nfc.INfcAdapter$Stub$Proxy
@@ -1209,18 +1209,13 @@
 android.webkit.BrowserFrame$ConfigCallback
 android.webkit.CallbackProxy
 android.webkit.CookieManager
-android.webkit.CookieManagerClassic
 android.webkit.CookieSyncManager
 android.webkit.DeviceMotionAndOrientationManager
 android.webkit.GeolocationPermissions
-android.webkit.GeolocationPermissionsClassic
-android.webkit.GeolocationPermissionsClassic$1
-android.webkit.GeolocationPermissionsClassic$2
 android.webkit.HTML5Audio
 android.webkit.HTML5VideoViewProxy
 android.webkit.JWebCoreJavaBridge
 android.webkit.JavascriptInterface
-android.webkit.JniUtil
 android.webkit.L10nUtils
 android.webkit.MockGeolocation
 android.webkit.OverScrollGlow
@@ -1232,44 +1227,20 @@
 android.webkit.ViewManager$3
 android.webkit.ViewStateSerializer
 android.webkit.WebBackForwardList
-android.webkit.WebBackForwardListClassic
 android.webkit.WebCoreThreadWatchdog
 android.webkit.WebHistoryItem
-android.webkit.WebHistoryItemClassic
 android.webkit.WebIconDatabase
-android.webkit.WebIconDatabaseClassic
-android.webkit.WebIconDatabaseClassic$EventHandler
-android.webkit.WebIconDatabaseClassic$EventHandler$1
 android.webkit.WebSettings
 android.webkit.WebSettings$LayoutAlgorithm
 android.webkit.WebSettings$PluginState
 android.webkit.WebSettings$RenderPriority
 android.webkit.WebSettings$ZoomDensity
-android.webkit.WebSettingsClassic
-android.webkit.WebSettingsClassic$AutoFillProfile
-android.webkit.WebSettingsClassic$EventHandler
-android.webkit.WebSettingsClassic$EventHandler$1
 android.webkit.WebStorage
-android.webkit.WebStorageClassic
-android.webkit.WebStorageClassic$1
-android.webkit.WebStorageClassic$2
 android.webkit.WebSyncManager
 android.webkit.WebSyncManager$SyncHandler
 android.webkit.WebView
 android.webkit.WebView$PrivateAccess
-android.webkit.WebViewClassic
-android.webkit.WebViewClassic$Factory
-android.webkit.WebViewClassic$OnTrimMemoryListener
-android.webkit.WebViewClassic$PackageListener
-android.webkit.WebViewClassic$PageSwapDelegate
-android.webkit.WebViewClassic$PrivateHandler
-android.webkit.WebViewClassic$ProxyReceiver
-android.webkit.WebViewClassic$SelectionHandleAlpha
-android.webkit.WebViewClassic$TitleBarDelegate
-android.webkit.WebViewClassic$TrustStorageListener
-android.webkit.WebViewClassic$ViewSizeData
 android.webkit.WebViewClient
-android.webkit.WebViewCore
 android.webkit.WebViewCore$AutoFillData
 android.webkit.WebViewCore$DrawData
 android.webkit.WebViewCore$EventHub
@@ -1280,9 +1251,8 @@
 android.webkit.WebViewCore$WebCoreThread
 android.webkit.WebViewCore$WebCoreThread$1
 android.webkit.WebViewDatabase
-android.webkit.WebViewDatabaseClassic
-android.webkit.WebViewDatabaseClassic$1
 android.webkit.WebViewFactory
+android.webkit.WebViewFactory$Preloader
 android.webkit.WebViewFactoryProvider
 android.webkit.WebViewFactoryProvider$Statics
 android.webkit.WebViewInputDispatcher
diff --git a/services/input/Android.mk b/services/input/Android.mk
index 5d913f3..6e944ef 100644
--- a/services/input/Android.mk
+++ b/services/input/Android.mk
@@ -36,12 +36,13 @@
     libhardware_legacy \
     libskia \
     libgui \
-    libui
+    libui \
+    libinput
 
 LOCAL_C_INCLUDES := \
     external/skia/include/core
 
-LOCAL_MODULE:= libinput
+LOCAL_MODULE:= libinputservice
 
 LOCAL_MODULE_TAGS := optional
 
diff --git a/services/input/EventHub.cpp b/services/input/EventHub.cpp
index f4e1cec..4d70d5f 100644
--- a/services/input/EventHub.cpp
+++ b/services/input/EventHub.cpp
@@ -36,9 +36,9 @@
 #include <errno.h>
 #include <assert.h>
 
-#include <androidfw/KeyLayoutMap.h>
-#include <androidfw/KeyCharacterMap.h>
-#include <androidfw/VirtualKeyMap.h>
+#include <input/KeyLayoutMap.h>
+#include <input/KeyCharacterMap.h>
+#include <input/VirtualKeyMap.h>
 
 #include <string.h>
 #include <stdint.h>
@@ -162,7 +162,7 @@
         next(NULL),
         fd(fd), id(id), path(path), identifier(identifier),
         classes(0), configuration(NULL), virtualKeyMap(NULL),
-        ffEffectPlaying(false), ffEffectId(-1),
+        ffEffectPlaying(false), ffEffectId(-1), controllerNumber(0),
         timestampOverrideSec(0), timestampOverrideUsec(0) {
     memset(keyBitmask, 0, sizeof(keyBitmask));
     memset(absBitmask, 0, sizeof(absBitmask));
@@ -195,7 +195,7 @@
 const int EventHub::EPOLL_MAX_EVENTS;
 
 EventHub::EventHub(void) :
-        mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD), mNextDeviceId(1),
+        mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD), mNextDeviceId(1), mControllerNumbers(),
         mOpeningDevices(0), mClosingDevices(0),
         mNeedToSendFinishedDeviceScan(false),
         mNeedToReopenDevices(false), mNeedToScanDevices(true),
@@ -269,6 +269,13 @@
     return device->classes;
 }
 
+int32_t EventHub::getDeviceControllerNumber(int32_t deviceId) const {
+    AutoMutex _l(mLock);
+    Device* device = getDeviceLocked(deviceId);
+    if (device == NULL) return 0;
+    return device->controllerNumber;
+}
+
 void EventHub::getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const {
     AutoMutex _l(mLock);
     Device* device = getDeviceLocked(deviceId);
@@ -1230,6 +1237,10 @@
         device->classes |= INPUT_DEVICE_CLASS_EXTERNAL;
     }
 
+    if (device->classes & (INPUT_DEVICE_CLASS_JOYSTICK | INPUT_DEVICE_CLASS_GAMEPAD)) {
+        device->controllerNumber = getNextControllerNumberLocked(device);
+    }
+
     // Register with epoll.
     struct epoll_event eventItem;
     memset(&eventItem, 0, sizeof(eventItem));
@@ -1341,6 +1352,27 @@
     return device->identifier.bus == BUS_USB || device->identifier.bus == BUS_BLUETOOTH;
 }
 
+int32_t EventHub::getNextControllerNumberLocked(Device* device) {
+    if (mControllerNumbers.isFull()) {
+        ALOGI("Maximum number of controllers reached, assigning controller number 0 to device %s",
+                device->identifier.name.string());
+        return 0;
+    }
+    // Since the controller number 0 is reserved for non-controllers, translate all numbers up by
+    // one
+    return static_cast<int32_t>(mControllerNumbers.markFirstUnmarkedBit() + 1);
+}
+
+void EventHub::releaseControllerNumberLocked(Device* device) {
+    int32_t num = device->controllerNumber;
+    device->controllerNumber= 0;
+    if (num == 0) {
+        return;
+    }
+    mControllerNumbers.clearBit(static_cast<uint32_t>(num - 1));
+}
+
+
 bool EventHub::hasKeycodeLocked(Device* device, int keycode) const {
     if (!device->keyMap.haveKeyLayout() || !device->keyBitmask) {
         return false;
@@ -1392,6 +1424,8 @@
         }
     }
 
+    releaseControllerNumberLocked(device);
+
     mDevices.removeItem(device->id);
     device->close();
 
@@ -1521,6 +1555,7 @@
             dump.appendFormat(INDENT3 "Path: %s\n", device->path.string());
             dump.appendFormat(INDENT3 "Descriptor: %s\n", device->identifier.descriptor.string());
             dump.appendFormat(INDENT3 "Location: %s\n", device->identifier.location.string());
+            dump.appendFormat(INDENT3 "ControllerNumber: %d\n", device->controllerNumber);
             dump.appendFormat(INDENT3 "UniqueId: %s\n", device->identifier.uniqueId.string());
             dump.appendFormat(INDENT3 "Identifier: bus=0x%04x, vendor=0x%04x, "
                     "product=0x%04x, version=0x%04x\n",
diff --git a/services/input/EventHub.h b/services/input/EventHub.h
index c93fc7a..ae28f01 100644
--- a/services/input/EventHub.h
+++ b/services/input/EventHub.h
@@ -18,12 +18,12 @@
 #ifndef _RUNTIME_EVENT_HUB_H
 #define _RUNTIME_EVENT_HUB_H
 
-#include <androidfw/Input.h>
-#include <androidfw/InputDevice.h>
-#include <androidfw/Keyboard.h>
-#include <androidfw/KeyLayoutMap.h>
-#include <androidfw/KeyCharacterMap.h>
-#include <androidfw/VirtualKeyMap.h>
+#include <input/Input.h>
+#include <input/InputDevice.h>
+#include <input/Keyboard.h>
+#include <input/KeyLayoutMap.h>
+#include <input/KeyCharacterMap.h>
+#include <input/VirtualKeyMap.h>
 #include <utils/String8.h>
 #include <utils/threads.h>
 #include <utils/Log.h>
@@ -33,6 +33,7 @@
 #include <utils/PropertyMap.h>
 #include <utils/Vector.h>
 #include <utils/KeyedVector.h>
+#include <utils/BitSet.h>
 
 #include <linux/input.h>
 #include <sys/epoll.h>
@@ -179,6 +180,8 @@
 
     virtual InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const = 0;
 
+    virtual int32_t getDeviceControllerNumber(int32_t deviceId) const = 0;
+
     virtual void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const = 0;
 
     virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
@@ -263,6 +266,8 @@
 
     virtual InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const;
 
+    virtual int32_t getDeviceControllerNumber(int32_t deviceId) const;
+
     virtual void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const;
 
     virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
@@ -343,6 +348,8 @@
         bool ffEffectPlaying;
         int16_t ffEffectId; // initially -1
 
+        int32_t controllerNumber;
+
         int32_t timestampOverrideSec;
         int32_t timestampOverrideUsec;
 
@@ -384,6 +391,9 @@
 
     bool isExternalDeviceLocked(Device* device);
 
+    int32_t getNextControllerNumberLocked(Device* device);
+    void releaseControllerNumberLocked(Device* device);
+
     // Protect all internal state.
     mutable Mutex mLock;
 
@@ -398,6 +408,8 @@
 
     int32_t mNextDeviceId;
 
+    BitSet32 mControllerNumbers;
+
     KeyedVector<int32_t, Device*> mDevices;
 
     Device *mOpeningDevices;
diff --git a/services/input/InputApplication.h b/services/input/InputApplication.h
index c04a935..1f5504c 100644
--- a/services/input/InputApplication.h
+++ b/services/input/InputApplication.h
@@ -17,7 +17,7 @@
 #ifndef _UI_INPUT_APPLICATION_H
 #define _UI_INPUT_APPLICATION_H
 
-#include <androidfw/Input.h>
+#include <input/Input.h>
 
 #include <utils/RefBase.h>
 #include <utils/Timers.h>
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index 23a846b..9e7a15d 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -84,6 +84,8 @@
 // Log a warning when an event takes longer than this to process, even if an ANR does not occur.
 const nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
 
+// Number of recent events to keep for debugging purposes.
+const size_t RECENT_QUEUE_MAX_SIZE = 10;
 
 static inline nsecs_t now() {
     return systemTime(SYSTEM_TIME_MONOTONIC);
@@ -455,6 +457,14 @@
     return needWake;
 }
 
+void InputDispatcher::addRecentEventLocked(EventEntry* entry) {
+    entry->refCount += 1;
+    mRecentQueue.enqueueAtTail(entry);
+    if (mRecentQueue.count() > RECENT_QUEUE_MAX_SIZE) {
+        mRecentQueue.dequeueAtHead()->release();
+    }
+}
+
 sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId,
         int32_t x, int32_t y) {
     // Traverse windows from front to back to find touched window.
@@ -624,6 +634,7 @@
     if (entry == mNextUnblockedEvent) {
         mNextUnblockedEvent = NULL;
     }
+    addRecentEventLocked(entry);
     entry->release();
 }
 
@@ -1264,21 +1275,7 @@
             // Try to assign the pointer to the first foreground window we find, if there is one.
             newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
             if (newTouchedWindowHandle == NULL) {
-                // There is no touched window.  If this is an initial down event
-                // then wait for a window to appear that will handle the touch.  This is
-                // to ensure that we report an ANR in the case where an application has started
-                // but not yet put up a window and the user is starting to get impatient.
-                if (maskedAction == AMOTION_EVENT_ACTION_DOWN
-                        && mFocusedApplicationHandle != NULL) {
-                    injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
-                            mFocusedApplicationHandle, NULL, nextWakeupTime,
-                            "Waiting because there is no touchable window that can "
-                            "handle the event but there is focused application that may "
-                            "eventually add a new window when it finishes starting up.");
-                    goto Unresponsive;
-                }
-
-                ALOGI("Dropping event because there is no touched window.");
+                ALOGI("Dropping event because there is no touchable window at (%d, %d).", x, y);
                 injectionResult = INPUT_EVENT_INJECTION_FAILED;
                 goto Failed;
             }
@@ -3161,6 +3158,31 @@
 
     nsecs_t currentTime = now();
 
+    // Dump recently dispatched or dropped events from oldest to newest.
+    if (!mRecentQueue.isEmpty()) {
+        dump.appendFormat(INDENT "RecentQueue: length=%u\n", mRecentQueue.count());
+        for (EventEntry* entry = mRecentQueue.head; entry; entry = entry->next) {
+            dump.append(INDENT2);
+            entry->appendDescription(dump);
+            dump.appendFormat(", age=%0.1fms\n",
+                    (currentTime - entry->eventTime) * 0.000001f);
+        }
+    } else {
+        dump.append(INDENT "RecentQueue: <empty>\n");
+    }
+
+    // Dump event currently being dispatched.
+    if (mPendingEvent) {
+        dump.append(INDENT "PendingEvent:\n");
+        dump.append(INDENT2);
+        mPendingEvent->appendDescription(dump);
+        dump.appendFormat(", age=%0.1fms\n",
+                (currentTime - mPendingEvent->eventTime) * 0.000001f);
+    } else {
+        dump.append(INDENT "PendingEvent: <none>\n");
+    }
+
+    // Dump inbound events from oldest to newest.
     if (!mInboundQueue.isEmpty()) {
         dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
         for (EventEntry* entry = mInboundQueue.head; entry; entry = entry->next) {
@@ -3383,6 +3405,7 @@
             & InputDispatcher::doNotifyANRLockedInterruptible);
     commandEntry->inputApplicationHandle = applicationHandle;
     commandEntry->inputWindowHandle = windowHandle;
+    commandEntry->reason = reason;
 }
 
 void InputDispatcher::doNotifyConfigurationChangedInterruptible(
@@ -3412,7 +3435,8 @@
     mLock.unlock();
 
     nsecs_t newTimeout = mPolicy->notifyANR(
-            commandEntry->inputApplicationHandle, commandEntry->inputWindowHandle);
+            commandEntry->inputApplicationHandle, commandEntry->inputWindowHandle,
+            commandEntry->reason);
 
     mLock.lock();
 
@@ -3809,7 +3833,8 @@
 }
 
 void InputDispatcher::ConfigurationChangedEntry::appendDescription(String8& msg) const {
-    msg.append("ConfigurationChangedEvent()");
+    msg.append("ConfigurationChangedEvent(), policyFlags=0x%08x",
+            policyFlags);
 }
 
 
@@ -3824,7 +3849,8 @@
 }
 
 void InputDispatcher::DeviceResetEntry::appendDescription(String8& msg) const {
-    msg.appendFormat("DeviceResetEvent(deviceId=%d)", deviceId);
+    msg.appendFormat("DeviceResetEvent(deviceId=%d), policyFlags=0x%08x",
+            deviceId, policyFlags);
 }
 
 
@@ -3846,8 +3872,11 @@
 }
 
 void InputDispatcher::KeyEntry::appendDescription(String8& msg) const {
-    msg.appendFormat("KeyEvent(action=%d, deviceId=%d, source=0x%08x)",
-            action, deviceId, source);
+    msg.appendFormat("KeyEvent(deviceId=%d, source=0x%08x, action=%d, "
+            "flags=0x%08x, keyCode=%d, scanCode=%d, metaState=0x%08x, "
+            "repeatCount=%d), policyFlags=0x%08x",
+            deviceId, source, action, flags, keyCode, scanCode, metaState,
+            repeatCount, policyFlags);
 }
 
 void InputDispatcher::KeyEntry::recycle() {
@@ -3884,8 +3913,19 @@
 }
 
 void InputDispatcher::MotionEntry::appendDescription(String8& msg) const {
-    msg.appendFormat("MotionEvent(action=%d, deviceId=%d, source=0x%08x, displayId=%d)",
-            action, deviceId, source, displayId);
+    msg.appendFormat("MotionEvent(deviceId=%d, source=0x%08x, action=%d, "
+            "flags=0x%08x, metaState=0x%08x, buttonState=0x%08x, edgeFlags=0x%08x, "
+            "xPrecision=%.1f, yPrecision=%.1f, displayId=%d, pointers=[",
+            deviceId, source, action, flags, metaState, buttonState, edgeFlags,
+            xPrecision, yPrecision, displayId);
+    for (uint32_t i = 0; i < pointerCount; i++) {
+        if (i) {
+            msg.append(", ");
+        }
+        msg.appendFormat("%d: (%.1f, %.1f)", pointerProperties[i].id,
+                pointerCoords[i].getX(), pointerCoords[i].getY());
+    }
+    msg.appendFormat("]), policyFlags=0x%08x", policyFlags);
 }
 
 
diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h
index 430721e..190e7b2 100644
--- a/services/input/InputDispatcher.h
+++ b/services/input/InputDispatcher.h
@@ -17,8 +17,8 @@
 #ifndef _UI_INPUT_DISPATCHER_H
 #define _UI_INPUT_DISPATCHER_H
 
-#include <androidfw/Input.h>
-#include <androidfw/InputTransport.h>
+#include <input/Input.h>
+#include <input/InputTransport.h>
 #include <utils/KeyedVector.h>
 #include <utils/Vector.h>
 #include <utils/threads.h>
@@ -202,7 +202,8 @@
     /* Notifies the system that an application is not responding.
      * Returns a new timeout to continue waiting, or 0 to abort dispatch. */
     virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
-            const sp<InputWindowHandle>& inputWindowHandle) = 0;
+            const sp<InputWindowHandle>& inputWindowHandle,
+            const String8& reason) = 0;
 
     /* Notifies the system that an input channel is unrecoverably broken. */
     virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) = 0;
@@ -596,6 +597,7 @@
         KeyEntry* keyEntry;
         sp<InputApplicationHandle> inputApplicationHandle;
         sp<InputWindowHandle> inputWindowHandle;
+        String8 reason;
         int32_t userActivityEventType;
         uint32_t seq;
         bool handled;
@@ -846,6 +848,7 @@
 
     EventEntry* mPendingEvent;
     Queue<EventEntry> mInboundQueue;
+    Queue<EventEntry> mRecentQueue;
     Queue<CommandEntry> mCommandQueue;
 
     void dispatchOnceInnerLocked(nsecs_t* nextWakeupTime);
@@ -856,6 +859,9 @@
     // Cleans up input state when dropping an inbound event.
     void dropInboundEventLocked(EventEntry* entry, DropReason dropReason);
 
+    // Adds an event to a queue of recent events for debugging purposes.
+    void addRecentEventLocked(EventEntry* entry);
+
     // App switch latency optimization.
     bool mAppSwitchSawKeyDown;
     nsecs_t mAppSwitchDueTime;
diff --git a/services/input/InputListener.h b/services/input/InputListener.h
index cd7c25a..78ae10f 100644
--- a/services/input/InputListener.h
+++ b/services/input/InputListener.h
@@ -17,7 +17,7 @@
 #ifndef _UI_INPUT_LISTENER_H
 #define _UI_INPUT_LISTENER_H
 
-#include <androidfw/Input.h>
+#include <input/Input.h>
 #include <utils/RefBase.h>
 #include <utils/Vector.h>
 
diff --git a/services/input/InputManager.h b/services/input/InputManager.h
index 29584c9..a213b2d 100644
--- a/services/input/InputManager.h
+++ b/services/input/InputManager.h
@@ -25,8 +25,8 @@
 #include "InputReader.h"
 #include "InputDispatcher.h"
 
-#include <androidfw/Input.h>
-#include <androidfw/InputTransport.h>
+#include <input/Input.h>
+#include <input/InputTransport.h>
 #include <utils/Errors.h>
 #include <utils/Vector.h>
 #include <utils/Timers.h>
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index e229755..feed31c 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -42,8 +42,8 @@
 #include "InputReader.h"
 
 #include <cutils/log.h>
-#include <androidfw/Keyboard.h>
-#include <androidfw/VirtualKeyMap.h>
+#include <input/Keyboard.h>
+#include <input/VirtualKeyMap.h>
 
 #include <stddef.h>
 #include <stdlib.h>
@@ -354,8 +354,9 @@
 
     InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(deviceId);
     uint32_t classes = mEventHub->getDeviceClasses(deviceId);
+    int32_t controllerNumber = mEventHub->getDeviceControllerNumber(deviceId);
 
-    InputDevice* device = createDeviceLocked(deviceId, identifier, classes);
+    InputDevice* device = createDeviceLocked(deviceId, controllerNumber, identifier, classes);
     device->configure(when, &mConfig, 0);
     device->reset(when);
 
@@ -395,10 +396,10 @@
     delete device;
 }
 
-InputDevice* InputReader::createDeviceLocked(int32_t deviceId,
+InputDevice* InputReader::createDeviceLocked(int32_t deviceId, int32_t controllerNumber,
         const InputDeviceIdentifier& identifier, uint32_t classes) {
     InputDevice* device = new InputDevice(&mContext, deviceId, bumpGenerationLocked(),
-            identifier, classes);
+            controllerNumber, identifier, classes);
 
     // External devices.
     if (classes & INPUT_DEVICE_CLASS_EXTERNAL) {
@@ -843,8 +844,8 @@
 // --- InputDevice ---
 
 InputDevice::InputDevice(InputReaderContext* context, int32_t id, int32_t generation,
-        const InputDeviceIdentifier& identifier, uint32_t classes) :
-        mContext(context), mId(id), mGeneration(generation),
+        int32_t controllerNumber, const InputDeviceIdentifier& identifier, uint32_t classes) :
+        mContext(context), mId(id), mGeneration(generation), mControllerNumber(controllerNumber),
         mIdentifier(identifier), mClasses(classes),
         mSources(0), mIsExternal(false), mDropUntilNextSync(false) {
 }
@@ -995,7 +996,8 @@
 }
 
 void InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) {
-    outDeviceInfo->initialize(mId, mGeneration, mIdentifier, mAlias, mIsExternal);
+    outDeviceInfo->initialize(mId, mGeneration, mControllerNumber, mIdentifier, mAlias,
+            mIsExternal);
 
     size_t numMappers = mMappers.size();
     for (size_t i = 0; i < numMappers; i++) {
@@ -2631,6 +2633,7 @@
             info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_4, mSource, y.min, y.max, y.flat,
                     y.fuzz, y.resolution);
         }
+        info->setButtonUnderPad(mParameters.hasButtonUnderPad);
     }
 }
 
@@ -2796,6 +2799,9 @@
         mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
     }
 
+    mParameters.hasButtonUnderPad=
+            getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_BUTTONPAD);
+
     String8 deviceTypeString;
     if (getDevice()->getConfiguration().tryGetProperty(String8("touch.deviceType"),
             deviceTypeString)) {
@@ -4650,6 +4656,14 @@
                 mCurrentFingerIdBits, positions);
     }
 
+    // If the gesture ever enters a mode other than TAP, HOVER or TAP_DRAG, without first returning
+    // to NEUTRAL, then we should not generate tap event.
+    if (mPointerGesture.lastGestureMode != PointerGesture::HOVER
+            && mPointerGesture.lastGestureMode != PointerGesture::TAP
+            && mPointerGesture.lastGestureMode != PointerGesture::TAP_DRAG) {
+        mPointerGesture.resetTap();
+    }
+
     // Pick a new active touch id if needed.
     // Choose an arbitrary pointer that just went down, if there is one.
     // Otherwise choose an arbitrary remaining pointer.
@@ -4858,8 +4872,12 @@
                 }
             } else {
 #if DEBUG_GESTURES
-                ALOGD("Gestures: Not a TAP, %0.3fms since down",
-                        (when - mPointerGesture.tapDownTime) * 0.000001f);
+                if (mPointerGesture.tapDownTime != LLONG_MIN) {
+                    ALOGD("Gestures: Not a TAP, %0.3fms since down",
+                            (when - mPointerGesture.tapDownTime) * 0.000001f);
+                } else {
+                    ALOGD("Gestures: Not a TAP, incompatible mode transitions");
+                }
 #endif
             }
         }
diff --git a/services/input/InputReader.h b/services/input/InputReader.h
index 0189ba7..a8bb636 100644
--- a/services/input/InputReader.h
+++ b/services/input/InputReader.h
@@ -21,9 +21,9 @@
 #include "PointerController.h"
 #include "InputListener.h"
 
-#include <androidfw/Input.h>
-#include <androidfw/VelocityControl.h>
-#include <androidfw/VelocityTracker.h>
+#include <input/Input.h>
+#include <input/VelocityControl.h>
+#include <input/VelocityTracker.h>
 #include <utils/KeyedVector.h>
 #include <utils/threads.h>
 #include <utils/Timers.h>
@@ -409,7 +409,7 @@
 
 protected:
     // These members are protected so they can be instrumented by test cases.
-    virtual InputDevice* createDeviceLocked(int32_t deviceId,
+    virtual InputDevice* createDeviceLocked(int32_t deviceId, int32_t controllerNumber,
             const InputDeviceIdentifier& identifier, uint32_t classes);
 
     class ContextImpl : public InputReaderContext {
@@ -507,16 +507,17 @@
 /* Represents the state of a single input device. */
 class InputDevice {
 public:
-    InputDevice(InputReaderContext* context, int32_t id, int32_t generation,
-            const InputDeviceIdentifier& identifier, uint32_t classes);
+    InputDevice(InputReaderContext* context, int32_t id, int32_t generation, int32_t
+            controllerNumber, const InputDeviceIdentifier& identifier, uint32_t classes);
     ~InputDevice();
 
     inline InputReaderContext* getContext() { return mContext; }
-    inline int32_t getId() { return mId; }
-    inline int32_t getGeneration() { return mGeneration; }
-    inline const String8& getName() { return mIdentifier.name; }
-    inline uint32_t getClasses() { return mClasses; }
-    inline uint32_t getSources() { return mSources; }
+    inline int32_t getId() const { return mId; }
+    inline int32_t getControllerNumber() const { return mControllerNumber; }
+    inline int32_t getGeneration() const { return mGeneration; }
+    inline const String8& getName() const { return mIdentifier.name; }
+    inline uint32_t getClasses() const { return mClasses; }
+    inline uint32_t getSources() const { return mSources; }
 
     inline bool isExternal() { return mIsExternal; }
     inline void setExternal(bool external) { mIsExternal = external; }
@@ -573,6 +574,7 @@
 private:
     InputReaderContext* mContext;
     int32_t mId;
+    int32_t mControllerNumber;
     int32_t mGeneration;
     InputDeviceIdentifier mIdentifier;
     String8 mAlias;
@@ -1205,6 +1207,7 @@
         bool hasAssociatedDisplay;
         bool associatedDisplayIsExternal;
         bool orientationAware;
+        bool hasButtonUnderPad;
 
         enum GestureMode {
             GESTURE_MODE_POINTER,
@@ -1282,6 +1285,9 @@
             if (haveSizeBias) {
                 *outSize += sizeBias;
             }
+            if (*outSize < 0) {
+                *outSize = 0;
+            }
         }
     } mCalibration;
 
diff --git a/services/input/InputWindow.h b/services/input/InputWindow.h
index 7bd3af7..136870a 100644
--- a/services/input/InputWindow.h
+++ b/services/input/InputWindow.h
@@ -17,8 +17,8 @@
 #ifndef _UI_INPUT_WINDOW_H
 #define _UI_INPUT_WINDOW_H
 
-#include <androidfw/Input.h>
-#include <androidfw/InputTransport.h>
+#include <input/Input.h>
+#include <input/InputTransport.h>
 #include <utils/RefBase.h>
 #include <utils/Timers.h>
 #include <utils/String8.h>
diff --git a/services/input/PointerController.h b/services/input/PointerController.h
index fd68b61..790c0bb 100644
--- a/services/input/PointerController.h
+++ b/services/input/PointerController.h
@@ -20,7 +20,7 @@
 #include "SpriteController.h"
 
 #include <ui/DisplayInfo.h>
-#include <androidfw/Input.h>
+#include <input/Input.h>
 #include <utils/BitSet.h>
 #include <utils/RefBase.h>
 #include <utils/Looper.h>
diff --git a/services/input/tests/Android.mk b/services/input/tests/Android.mk
index 211e64b..9278f41 100644
--- a/services/input/tests/Android.mk
+++ b/services/input/tests/Android.mk
@@ -17,7 +17,8 @@
     libui \
     libskia \
     libstlport \
-    libinput
+    libinput \
+    libinputservice
 
 static_libraries := \
     libgtest \
@@ -40,7 +41,7 @@
     $(eval LOCAL_SRC_FILES := $(file)) \
     $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
     $(eval LOCAL_MODULE_TAGS := $(module_tags)) \
-    $(eval include $(BUILD_EXECUTABLE)) \
+    $(eval include $(BUILD_NATIVE_TEST)) \
 )
 
 # Build the manual test programs.
diff --git a/services/input/tests/InputDispatcher_test.cpp b/services/input/tests/InputDispatcher_test.cpp
index ed2b4a5..26b4fab 100644
--- a/services/input/tests/InputDispatcher_test.cpp
+++ b/services/input/tests/InputDispatcher_test.cpp
@@ -50,7 +50,8 @@
     }
 
     virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
-            const sp<InputWindowHandle>& inputWindowHandle) {
+            const sp<InputWindowHandle>& inputWindowHandle,
+            const String8& reason) {
         return 0;
     }
 
diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp
index 14065d2..f068732 100644
--- a/services/input/tests/InputReader_test.cpp
+++ b/services/input/tests/InputReader_test.cpp
@@ -472,6 +472,10 @@
         return device ? device->identifier : InputDeviceIdentifier();
     }
 
+    virtual int32_t getDeviceControllerNumber(int32_t deviceId) const {
+        return 0;
+    }
+
     virtual void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const {
         Device* device = getDevice(deviceId);
         if (device) {
@@ -928,22 +932,24 @@
         mNextDevice = device;
     }
 
-    InputDevice* newDevice(int32_t deviceId, const String8& name, uint32_t classes) {
+    InputDevice* newDevice(int32_t deviceId, int32_t controllerNumber, const String8& name,
+            uint32_t classes) {
         InputDeviceIdentifier identifier;
         identifier.name = name;
         int32_t generation = deviceId + 1;
-        return new InputDevice(&mContext, deviceId, generation, identifier, classes);
+        return new InputDevice(&mContext, deviceId, generation, controllerNumber, identifier,
+                classes);
     }
 
 protected:
-    virtual InputDevice* createDeviceLocked(int32_t deviceId,
+    virtual InputDevice* createDeviceLocked(int32_t deviceId, int32_t controllerNumber,
             const InputDeviceIdentifier& identifier, uint32_t classes) {
         if (mNextDevice) {
             InputDevice* device = mNextDevice;
             mNextDevice = NULL;
             return device;
         }
-        return InputReader::createDeviceLocked(deviceId, identifier, classes);
+        return InputReader::createDeviceLocked(deviceId, controllerNumber, identifier, classes);
     }
 
     friend class InputReaderTest;
@@ -988,10 +994,10 @@
         mFakeEventHub->assertQueueIsEmpty();
     }
 
-    FakeInputMapper* addDeviceWithFakeInputMapper(int32_t deviceId,
+    FakeInputMapper* addDeviceWithFakeInputMapper(int32_t deviceId, int32_t controllerNumber,
             const String8& name, uint32_t classes, uint32_t sources,
             const PropertyMap* configuration) {
-        InputDevice* device = mReader->newDevice(deviceId, name, classes);
+        InputDevice* device = mReader->newDevice(deviceId, controllerNumber, name, classes);
         FakeInputMapper* mapper = new FakeInputMapper(device, sources);
         device->addMapper(mapper);
         mReader->setNextDevice(device);
@@ -1028,7 +1034,7 @@
 
 TEST_F(InputReaderTest, GetKeyCodeState_ForwardsRequestsToMappers) {
     FakeInputMapper* mapper = NULL;
-    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"),
+    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, String8("fake"),
             INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, NULL));
     mapper->setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
 
@@ -1055,7 +1061,7 @@
 
 TEST_F(InputReaderTest, GetScanCodeState_ForwardsRequestsToMappers) {
     FakeInputMapper* mapper = NULL;
-    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"),
+    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, String8("fake"),
             INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, NULL));
     mapper->setScanCodeState(KEY_A, AKEY_STATE_DOWN);
 
@@ -1082,7 +1088,7 @@
 
 TEST_F(InputReaderTest, GetSwitchState_ForwardsRequestsToMappers) {
     FakeInputMapper* mapper = NULL;
-    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"),
+    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, String8("fake"),
             INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, NULL));
     mapper->setSwitchState(SW_LID, AKEY_STATE_DOWN);
 
@@ -1109,7 +1115,7 @@
 
 TEST_F(InputReaderTest, MarkSupportedKeyCodes_ForwardsRequestsToMappers) {
     FakeInputMapper* mapper = NULL;
-    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"),
+    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, String8("fake"),
             INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, NULL));
     mapper->addSupportedKeyCode(AKEYCODE_A);
     mapper->addSupportedKeyCode(AKEYCODE_B);
@@ -1153,7 +1159,7 @@
 
 TEST_F(InputReaderTest, LoopOnce_ForwardsRawEventsToMappers) {
     FakeInputMapper* mapper = NULL;
-    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"),
+    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, String8("fake"),
             INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, NULL));
 
     mFakeEventHub->enqueueEvent(0, 1, EV_KEY, KEY_A, 1);
@@ -1177,6 +1183,7 @@
     static const char* DEVICE_NAME;
     static const int32_t DEVICE_ID;
     static const int32_t DEVICE_GENERATION;
+    static const int32_t DEVICE_CONTROLLER_NUMBER;
     static const uint32_t DEVICE_CLASSES;
 
     sp<FakeEventHub> mFakeEventHub;
@@ -1196,7 +1203,7 @@
         InputDeviceIdentifier identifier;
         identifier.name = DEVICE_NAME;
         mDevice = new InputDevice(mFakeContext, DEVICE_ID, DEVICE_GENERATION,
-                identifier, DEVICE_CLASSES);
+                DEVICE_CONTROLLER_NUMBER, identifier, DEVICE_CLASSES);
     }
 
     virtual void TearDown() {
@@ -1212,6 +1219,7 @@
 const char* InputDeviceTest::DEVICE_NAME = "device";
 const int32_t InputDeviceTest::DEVICE_ID = 1;
 const int32_t InputDeviceTest::DEVICE_GENERATION = 2;
+const int32_t InputDeviceTest::DEVICE_CONTROLLER_NUMBER = 0;
 const uint32_t InputDeviceTest::DEVICE_CLASSES = INPUT_DEVICE_CLASS_KEYBOARD
         | INPUT_DEVICE_CLASS_TOUCH | INPUT_DEVICE_CLASS_JOYSTICK;
 
@@ -1365,6 +1373,7 @@
     static const char* DEVICE_NAME;
     static const int32_t DEVICE_ID;
     static const int32_t DEVICE_GENERATION;
+    static const int32_t DEVICE_CONTROLLER_NUMBER;
     static const uint32_t DEVICE_CLASSES;
 
     sp<FakeEventHub> mFakeEventHub;
@@ -1381,7 +1390,7 @@
         InputDeviceIdentifier identifier;
         identifier.name = DEVICE_NAME;
         mDevice = new InputDevice(mFakeContext, DEVICE_ID, DEVICE_GENERATION,
-                identifier, DEVICE_CLASSES);
+                DEVICE_CONTROLLER_NUMBER, identifier, DEVICE_CLASSES);
 
         mFakeEventHub->addDevice(DEVICE_ID, String8(DEVICE_NAME), 0);
     }
@@ -1461,6 +1470,7 @@
 const char* InputMapperTest::DEVICE_NAME = "device";
 const int32_t InputMapperTest::DEVICE_ID = 1;
 const int32_t InputMapperTest::DEVICE_GENERATION = 2;
+const int32_t InputMapperTest::DEVICE_CONTROLLER_NUMBER = 0;
 const uint32_t InputMapperTest::DEVICE_CLASSES = 0; // not needed for current tests
 
 
diff --git a/services/java/Android.mk b/services/java/Android.mk
index 95b28d9..8c3d0f0 100644
--- a/services/java/Android.mk
+++ b/services/java/Android.mk
@@ -11,7 +11,7 @@
 
 LOCAL_MODULE:= services
 
-LOCAL_JAVA_LIBRARIES := android.policy telephony-common
+LOCAL_JAVA_LIBRARIES := android.policy conscrypt telephony-common
 
 include $(BUILD_JAVA_LIBRARY)
 
diff --git a/services/java/com/android/server/AlarmManagerService.java b/services/java/com/android/server/AlarmManagerService.java
index fa758a8..98b5f66 100644
--- a/services/java/com/android/server/AlarmManagerService.java
+++ b/services/java/com/android/server/AlarmManagerService.java
@@ -38,11 +38,11 @@
 import android.os.UserHandle;
 import android.os.WorkSource;
 import android.text.TextUtils;
-import android.text.format.Time;
 import android.util.Pair;
 import android.util.Slog;
 import android.util.TimeUtils;
 
+import java.io.ByteArrayOutputStream;
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.text.SimpleDateFormat;
@@ -53,48 +53,55 @@
 import java.util.Comparator;
 import java.util.Date;
 import java.util.HashMap;
-import java.util.Iterator;
+import java.util.LinkedList;
 import java.util.Map;
 import java.util.TimeZone;
 
+import static android.app.AlarmManager.RTC_WAKEUP;
+import static android.app.AlarmManager.RTC;
+import static android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP;
+import static android.app.AlarmManager.ELAPSED_REALTIME;
+
 import com.android.internal.util.LocalLog;
 
 class AlarmManagerService extends IAlarmManager.Stub {
     // The threshold for how long an alarm can be late before we print a
     // warning message.  The time duration is in milliseconds.
     private static final long LATE_ALARM_THRESHOLD = 10 * 1000;
-    
-    private static final int RTC_WAKEUP_MASK = 1 << AlarmManager.RTC_WAKEUP;
-    private static final int RTC_MASK = 1 << AlarmManager.RTC;
-    private static final int ELAPSED_REALTIME_WAKEUP_MASK = 1 << AlarmManager.ELAPSED_REALTIME_WAKEUP; 
-    private static final int ELAPSED_REALTIME_MASK = 1 << AlarmManager.ELAPSED_REALTIME;
-    private static final int TIME_CHANGED_MASK = 1 << 16;
 
-    // Alignment quantum for inexact repeating alarms
-    private static final long QUANTUM = AlarmManager.INTERVAL_FIFTEEN_MINUTES;
+    private static final int RTC_WAKEUP_MASK = 1 << RTC_WAKEUP;
+    private static final int RTC_MASK = 1 << RTC;
+    private static final int ELAPSED_REALTIME_WAKEUP_MASK = 1 << ELAPSED_REALTIME_WAKEUP; 
+    private static final int ELAPSED_REALTIME_MASK = 1 << ELAPSED_REALTIME;
+    private static final int TIME_CHANGED_MASK = 1 << 16;
+    private static final int IS_WAKEUP_MASK = RTC_WAKEUP_MASK|ELAPSED_REALTIME_WAKEUP_MASK;
+
+    // Mask for testing whether a given alarm type is wakeup vs non-wakeup
+    private static final int TYPE_NONWAKEUP_MASK = 0x1; // low bit => non-wakeup
 
     private static final String TAG = "AlarmManager";
     private static final String ClockReceiver_TAG = "ClockReceiver";
     private static final boolean localLOGV = false;
+    private static final boolean DEBUG_BATCH = localLOGV || false;
+    private static final boolean DEBUG_VALIDATE = localLOGV || false;
     private static final int ALARM_EVENT = 1;
     private static final String TIMEZONE_PROPERTY = "persist.sys.timezone";
     
     private static final Intent mBackgroundIntent
             = new Intent().addFlags(Intent.FLAG_FROM_BACKGROUND);
+    private static final IncreasingTimeOrder sIncreasingTimeOrder = new IncreasingTimeOrder();
     
+    private static final boolean WAKEUP_STATS = false;
+
     private final Context mContext;
 
     private final LocalLog mLog = new LocalLog(TAG);
 
     private Object mLock = new Object();
-    
-    private final ArrayList<Alarm> mRtcWakeupAlarms = new ArrayList<Alarm>();
-    private final ArrayList<Alarm> mRtcAlarms = new ArrayList<Alarm>();
-    private final ArrayList<Alarm> mElapsedRealtimeWakeupAlarms = new ArrayList<Alarm>();
-    private final ArrayList<Alarm> mElapsedRealtimeAlarms = new ArrayList<Alarm>();
-    private final IncreasingTimeOrder mIncreasingTimeOrder = new IncreasingTimeOrder();
-    
+
     private int mDescriptor;
+    private long mNextWakeup;
+    private long mNextNonWakeup;
     private int mBroadcastRefCount = 0;
     private PowerManager.WakeLock mWakeLock;
     private ArrayList<InFlight> mInFlight = new ArrayList<InFlight>();
@@ -106,14 +113,297 @@
     private final PendingIntent mTimeTickSender;
     private final PendingIntent mDateChangeSender;
 
+    class WakeupEvent {
+        public long when;
+        public int uid;
+        public String action;
+
+        public WakeupEvent(long theTime, int theUid, String theAction) {
+            when = theTime;
+            uid = theUid;
+            action = theAction;
+        }
+    }
+
+    private final LinkedList<WakeupEvent> mRecentWakeups = new LinkedList<WakeupEvent>();
+    private final long RECENT_WAKEUP_PERIOD = 1000L * 60 * 60 * 24; // one day
+
+    static final class Batch {
+        long start;     // These endpoints are always in ELAPSED
+        long end;
+        boolean standalone; // certain "batches" don't participate in coalescing
+
+        final ArrayList<Alarm> alarms = new ArrayList<Alarm>();
+
+        Batch() {
+            start = 0;
+            end = Long.MAX_VALUE;
+        }
+
+        Batch(Alarm seed) {
+            start = seed.whenElapsed;
+            end = seed.maxWhen;
+            alarms.add(seed);
+        }
+
+        int size() {
+            return alarms.size();
+        }
+
+        Alarm get(int index) {
+            return alarms.get(index);
+        }
+
+        boolean canHold(long whenElapsed, long maxWhen) {
+            return (end >= whenElapsed) && (start <= maxWhen);
+        }
+
+        boolean add(Alarm alarm) {
+            boolean newStart = false;
+            // narrows the batch if necessary; presumes that canHold(alarm) is true
+            int index = Collections.binarySearch(alarms, alarm, sIncreasingTimeOrder);
+            if (index < 0) {
+                index = 0 - index - 1;
+            }
+            alarms.add(index, alarm);
+            if (DEBUG_BATCH) {
+                Slog.v(TAG, "Adding " + alarm + " to " + this);
+            }
+            if (alarm.whenElapsed > start) {
+                start = alarm.whenElapsed;
+                newStart = true;
+            }
+            if (alarm.maxWhen < end) {
+                end = alarm.maxWhen;
+            }
+
+            if (DEBUG_BATCH) {
+                Slog.v(TAG, "    => now " + this);
+            }
+            return newStart;
+        }
+
+        boolean remove(final PendingIntent operation) {
+            boolean didRemove = false;
+            long newStart = 0;  // recalculate endpoints as we go
+            long newEnd = Long.MAX_VALUE;
+            for (int i = 0; i < alarms.size(); i++) {
+                Alarm alarm = alarms.get(i);
+                if (alarm.operation.equals(operation)) {
+                    alarms.remove(i);
+                    didRemove = true;
+                } else {
+                    if (alarm.whenElapsed > newStart) {
+                        newStart = alarm.whenElapsed;
+                    }
+                    if (alarm.maxWhen < newEnd) {
+                        newEnd = alarm.maxWhen;
+                    }
+                    i++;
+                }
+            }
+            if (didRemove) {
+                // commit the new batch bounds
+                start = newStart;
+                end = newEnd;
+            }
+            return didRemove;
+        }
+
+        boolean remove(final String packageName) {
+            boolean didRemove = false;
+            long newStart = 0;  // recalculate endpoints as we go
+            long newEnd = Long.MAX_VALUE;
+            for (int i = 0; i < alarms.size(); i++) {
+                Alarm alarm = alarms.get(i);
+                if (alarm.operation.getTargetPackage().equals(packageName)) {
+                    alarms.remove(i);
+                    didRemove = true;
+                } else {
+                    if (alarm.whenElapsed > newStart) {
+                        newStart = alarm.whenElapsed;
+                    }
+                    if (alarm.maxWhen < newEnd) {
+                        newEnd = alarm.maxWhen;
+                    }
+                    i++;
+                }
+            }
+            if (didRemove) {
+                // commit the new batch bounds
+                start = newStart;
+                end = newEnd;
+            }
+            return didRemove;
+        }
+
+        boolean remove(final int userHandle) {
+            boolean didRemove = false;
+            long newStart = 0;  // recalculate endpoints as we go
+            long newEnd = Long.MAX_VALUE;
+            for (int i = 0; i < alarms.size(); i++) {
+                Alarm alarm = alarms.get(i);
+                if (UserHandle.getUserId(alarm.operation.getCreatorUid()) == userHandle) {
+                    alarms.remove(i);
+                    didRemove = true;
+                } else {
+                    if (alarm.whenElapsed > newStart) {
+                        newStart = alarm.whenElapsed;
+                    }
+                    if (alarm.maxWhen < newEnd) {
+                        newEnd = alarm.maxWhen;
+                    }
+                    i++;
+                }
+            }
+            if (didRemove) {
+                // commit the new batch bounds
+                start = newStart;
+                end = newEnd;
+            }
+            return didRemove;
+        }
+
+        boolean hasPackage(final String packageName) {
+            final int N = alarms.size();
+            for (int i = 0; i < N; i++) {
+                Alarm a = alarms.get(i);
+                if (a.operation.getTargetPackage().equals(packageName)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        boolean hasWakeups() {
+            final int N = alarms.size();
+            for (int i = 0; i < N; i++) {
+                Alarm a = alarms.get(i);
+                // non-wakeup alarms are types 1 and 3, i.e. have the low bit set
+                if ((a.type & TYPE_NONWAKEUP_MASK) == 0) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder b = new StringBuilder(40);
+            b.append("Batch{"); b.append(Integer.toHexString(this.hashCode()));
+            b.append(" num="); b.append(size());
+            b.append(" start="); b.append(start);
+            b.append(" end="); b.append(end);
+            if (standalone) {
+                b.append(" STANDALONE");
+            }
+            b.append('}');
+            return b.toString();
+        }
+    }
+
+    static class BatchTimeOrder implements Comparator<Batch> {
+        public int compare(Batch b1, Batch b2) {
+            long when1 = b1.start;
+            long when2 = b2.start;
+            if (when1 - when2 > 0) {
+                return 1;
+            }
+            if (when1 - when2 < 0) {
+                return -1;
+            }
+            return 0;
+        }
+    }
+    
+    // minimum recurrence period or alarm futurity for us to be able to fuzz it
+    private static final long MIN_FUZZABLE_INTERVAL = 10000;
+    private static final BatchTimeOrder sBatchOrder = new BatchTimeOrder();
+    private final ArrayList<Batch> mAlarmBatches = new ArrayList<Batch>();
+
+    static long convertToElapsed(long when, int type) {
+        final boolean isRtc = (type == RTC || type == RTC_WAKEUP);
+        if (isRtc) {
+            when -= System.currentTimeMillis() - SystemClock.elapsedRealtime();
+        }
+        return when;
+    }
+
+    // Apply a heuristic to { recurrence interval, futurity of the trigger time } to
+    // calculate the end of our nominal delivery window for the alarm.
+    static long maxTriggerTime(long now, long triggerAtTime, long interval) {
+        // Current heuristic: batchable window is 75% of either the recurrence interval
+        // [for a periodic alarm] or of the time from now to the desired delivery time,
+        // with a minimum delay/interval of 10 seconds, under which we will simply not
+        // defer the alarm.
+        long futurity = (interval == 0)
+                ? (triggerAtTime - now)
+                : interval;
+        if (futurity < MIN_FUZZABLE_INTERVAL) {
+            futurity = 0;
+        }
+        return triggerAtTime + (long)(.75 * futurity);
+    }
+
+    // returns true if the batch was added at the head
+    static boolean addBatchLocked(ArrayList<Batch> list, Batch newBatch) {
+        int index = Collections.binarySearch(list, newBatch, sBatchOrder);
+        if (index < 0) {
+            index = 0 - index - 1;
+        }
+        list.add(index, newBatch);
+        return (index == 0);
+    }
+
+    // Return the index of the matching batch, or -1 if none found.
+    int attemptCoalesceLocked(long whenElapsed, long maxWhen) {
+        final int N = mAlarmBatches.size();
+        for (int i = 0; i < N; i++) {
+            Batch b = mAlarmBatches.get(i);
+            if (!b.standalone && b.canHold(whenElapsed, maxWhen)) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    // The RTC clock has moved arbitrarily, so we need to recalculate all the batching
+    void rebatchAllAlarms() {
+        synchronized (mLock) {
+            rebatchAllAlarmsLocked(true);
+        }
+    }
+
+    void rebatchAllAlarmsLocked(boolean doValidate) {
+        ArrayList<Batch> oldSet = (ArrayList<Batch>) mAlarmBatches.clone();
+        mAlarmBatches.clear();
+        final long nowElapsed = SystemClock.elapsedRealtime();
+        final int oldBatches = oldSet.size();
+        for (int batchNum = 0; batchNum < oldBatches; batchNum++) {
+            Batch batch = oldSet.get(batchNum);
+            final int N = batch.size();
+            for (int i = 0; i < N; i++) {
+                Alarm a = batch.get(i);
+                long whenElapsed = convertToElapsed(a.when, a.type);
+                long maxElapsed = (a.whenElapsed == a.maxWhen)
+                        ? whenElapsed
+                                : maxTriggerTime(nowElapsed, whenElapsed, a.repeatInterval);
+                setImplLocked(a.type, a.when, whenElapsed, maxElapsed,
+                        a.repeatInterval, a.operation, batch.standalone, doValidate, a.workSource);
+            }
+        }
+    }
+
     private static final class InFlight extends Intent {
         final PendingIntent mPendingIntent;
+        final WorkSource mWorkSource;
         final Pair<String, ComponentName> mTarget;
         final BroadcastStats mBroadcastStats;
         final FilterStats mFilterStats;
 
-        InFlight(AlarmManagerService service, PendingIntent pendingIntent) {
+        InFlight(AlarmManagerService service, PendingIntent pendingIntent, WorkSource workSource) {
             mPendingIntent = pendingIntent;
+            mWorkSource = workSource;
             Intent intent = pendingIntent.getIntent();
             mTarget = intent != null
                     ? new Pair<String, ComponentName>(intent.getAction(), intent.getComponent())
@@ -166,6 +456,7 @@
     public AlarmManagerService(Context context) {
         mContext = context;
         mDescriptor = init();
+        mNextWakeup = mNextNonWakeup = 0;
 
         // We have to set current TimeZone info to kernel
         // because kernel doesn't keep this after reboot
@@ -206,77 +497,170 @@
             super.finalize();
         }
     }
-    
-    public void set(int type, long triggerAtTime, PendingIntent operation) {
-        setRepeating(type, triggerAtTime, 0, operation);
+
+    @Override
+    public void set(int type, long triggerAtTime, long windowLength, long interval,
+            PendingIntent operation, WorkSource workSource) {
+        if (workSource != null) {
+            mContext.enforceCallingPermission(
+                    android.Manifest.permission.UPDATE_DEVICE_STATS,
+                    "AlarmManager.set");
+        }
+
+        set(type, triggerAtTime, windowLength, interval, operation, false, workSource);
     }
-    
-    public void setRepeating(int type, long triggerAtTime, long interval, 
-            PendingIntent operation) {
+
+    public void set(int type, long triggerAtTime, long windowLength, long interval,
+            PendingIntent operation, boolean isStandalone, WorkSource workSource) {
         if (operation == null) {
             Slog.w(TAG, "set/setRepeating ignored because there is no intent");
             return;
         }
+
+        // Sanity check the window length.  This will catch people mistakenly
+        // trying to pass an end-of-window timestamp rather than a duration.
+        if (windowLength > AlarmManager.INTERVAL_HALF_DAY) {
+            Slog.w(TAG, "Window length " + windowLength
+                    + "ms suspiciously long; limiting to 1 hour");
+            windowLength = AlarmManager.INTERVAL_HOUR;
+        }
+
+        if (type < RTC_WAKEUP || type > ELAPSED_REALTIME) {
+            throw new IllegalArgumentException("Invalid alarm type " + type);
+        }
+
+        if (triggerAtTime < 0) {
+            final long who = Binder.getCallingUid();
+            final long what = Binder.getCallingPid();
+            Slog.w(TAG, "Invalid alarm trigger time! " + triggerAtTime + " from uid=" + who
+                    + " pid=" + what);
+            triggerAtTime = 0;
+        }
+
+        final long nowElapsed = SystemClock.elapsedRealtime();
+        final long triggerElapsed = convertToElapsed(triggerAtTime, type);
+        final long maxElapsed;
+        if (windowLength == AlarmManager.WINDOW_EXACT) {
+            maxElapsed = triggerElapsed;
+        } else if (windowLength < 0) {
+            maxElapsed = maxTriggerTime(nowElapsed, triggerElapsed, interval);
+        } else {
+            maxElapsed = triggerElapsed + windowLength;
+        }
+
         synchronized (mLock) {
-            Alarm alarm = new Alarm();
-            alarm.type = type;
-            alarm.when = triggerAtTime;
-            alarm.repeatInterval = interval;
-            alarm.operation = operation;
-
-            // Remove this alarm if already scheduled.
-            removeLocked(operation);
-
-            if (localLOGV) Slog.v(TAG, "set: " + alarm);
-
-            int index = addAlarmLocked(alarm);
-            if (index == 0) {
-                setLocked(alarm);
+            if (DEBUG_BATCH) {
+                Slog.v(TAG, "set(" + operation + ") : type=" + type
+                        + " triggerAtTime=" + triggerAtTime + " win=" + windowLength
+                        + " tElapsed=" + triggerElapsed + " maxElapsed=" + maxElapsed
+                        + " interval=" + interval + " standalone=" + isStandalone);
             }
+            setImplLocked(type, triggerAtTime, triggerElapsed, maxElapsed,
+                    interval, operation, isStandalone, true, workSource);
         }
     }
-    
-    public void setInexactRepeating(int type, long triggerAtTime, long interval, 
-            PendingIntent operation) {
-        if (operation == null) {
-            Slog.w(TAG, "setInexactRepeating ignored because there is no intent");
-            return;
-        }
 
-        if (interval <= 0) {
-            Slog.w(TAG, "setInexactRepeating ignored because interval " + interval
-                    + " is invalid");
-            return;
-        }
+    private void setImplLocked(int type, long when, long whenElapsed, long maxWhen, long interval,
+            PendingIntent operation, boolean isStandalone, boolean doValidate,
+            WorkSource workSource) {
+        Alarm a = new Alarm(type, when, whenElapsed, maxWhen, interval, operation, workSource);
+        removeLocked(operation);
 
-        // If the requested interval isn't a multiple of 15 minutes, just treat it as exact
-        if (interval % QUANTUM != 0) {
-            if (localLOGV) Slog.v(TAG, "Interval " + interval + " not a quantum multiple");
-            setRepeating(type, triggerAtTime, interval, operation);
-            return;
-        }
-
-        // Translate times into the ELAPSED timebase for alignment purposes so that
-        // alignment never tries to match against wall clock times.
-        final boolean isRtc = (type == AlarmManager.RTC || type == AlarmManager.RTC_WAKEUP);
-        final long skew = (isRtc)
-                ? System.currentTimeMillis() - SystemClock.elapsedRealtime()
-                : 0;
-
-        // Slip forward to the next ELAPSED-timebase quantum after the stated time.  If
-        // we're *at* a quantum point, leave it alone.
-        final long adjustedTriggerTime;
-        long offset = (triggerAtTime - skew) % QUANTUM;
-        if (offset != 0) {
-            adjustedTriggerTime = triggerAtTime - offset + QUANTUM;
+        boolean reschedule;
+        int whichBatch = (isStandalone) ? -1 : attemptCoalesceLocked(whenElapsed, maxWhen);
+        if (whichBatch < 0) {
+            Batch batch = new Batch(a);
+            batch.standalone = isStandalone;
+            reschedule = addBatchLocked(mAlarmBatches, batch);
         } else {
-            adjustedTriggerTime = triggerAtTime;
+            Batch batch = mAlarmBatches.get(whichBatch);
+            reschedule = batch.add(a);
+            if (reschedule) {
+                // The start time of this batch advanced, so batch ordering may
+                // have just been broken.  Move it to where it now belongs.
+                mAlarmBatches.remove(whichBatch);
+                addBatchLocked(mAlarmBatches, batch);
+            }
         }
 
-        // Set the alarm based on the quantum-aligned start time
-        if (localLOGV) Slog.v(TAG, "setInexactRepeating: type=" + type + " interval=" + interval
-                + " trigger=" + adjustedTriggerTime + " orig=" + triggerAtTime);
-        setRepeating(type, adjustedTriggerTime, interval, operation);
+        if (DEBUG_VALIDATE) {
+            if (doValidate && !validateConsistencyLocked()) {
+                Slog.v(TAG, "Tipping-point operation: type=" + type + " when=" + when
+                        + " when(hex)=" + Long.toHexString(when)
+                        + " whenElapsed=" + whenElapsed + " maxWhen=" + maxWhen
+                        + " interval=" + interval + " op=" + operation
+                        + " standalone=" + isStandalone);
+                rebatchAllAlarmsLocked(false);
+                reschedule = true;
+            }
+        }
+
+        if (reschedule) {
+            rescheduleKernelAlarmsLocked();
+        }
+    }
+
+    private void logBatchesLocked() {
+        ByteArrayOutputStream bs = new ByteArrayOutputStream(2048);
+        PrintWriter pw = new PrintWriter(bs);
+        final long nowRTC = System.currentTimeMillis();
+        final long nowELAPSED = SystemClock.elapsedRealtime();
+        final int NZ = mAlarmBatches.size();
+        for (int iz = 0; iz < NZ; iz++) {
+            Batch bz = mAlarmBatches.get(iz);
+            pw.append("Batch "); pw.print(iz); pw.append(": "); pw.println(bz);
+            dumpAlarmList(pw, bz.alarms, "  ", nowELAPSED, nowRTC);
+            pw.flush();
+            Slog.v(TAG, bs.toString());
+            bs.reset();
+        }
+    }
+
+    private boolean validateConsistencyLocked() {
+        if (DEBUG_VALIDATE) {
+            long lastTime = Long.MIN_VALUE;
+            final int N = mAlarmBatches.size();
+            for (int i = 0; i < N; i++) {
+                Batch b = mAlarmBatches.get(i);
+                if (b.start >= lastTime) {
+                    // duplicate start times are okay because of standalone batches
+                    lastTime = b.start;
+                } else {
+                    Slog.e(TAG, "CONSISTENCY FAILURE: Batch " + i + " is out of order");
+                    logBatchesLocked();
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    private Batch findFirstWakeupBatchLocked() {
+        final int N = mAlarmBatches.size();
+        for (int i = 0; i < N; i++) {
+            Batch b = mAlarmBatches.get(i);
+            if (b.hasWakeups()) {
+                return b;
+            }
+        }
+        return null;
+    }
+
+    private void rescheduleKernelAlarmsLocked() {
+        // Schedule the next upcoming wakeup alarm.  If there is a deliverable batch
+        // prior to that which contains no wakeups, we schedule that as well.
+        if (mAlarmBatches.size() > 0) {
+            final Batch firstWakeup = findFirstWakeupBatchLocked();
+            final Batch firstBatch = mAlarmBatches.get(0);
+            if (firstWakeup != null && mNextWakeup != firstWakeup.start) {
+                mNextWakeup = firstWakeup.start;
+                setLocked(ELAPSED_REALTIME_WAKEUP, firstWakeup.start);
+            }
+            if (firstBatch != firstWakeup && mNextNonWakeup != firstBatch.start) {
+                mNextNonWakeup = firstBatch.start;
+                setLocked(ELAPSED_REALTIME, firstBatch.start);
+            }
+        }
     }
 
     public void setTime(long millis) {
@@ -338,163 +722,88 @@
     }
     
     public void removeLocked(PendingIntent operation) {
-        removeLocked(mRtcWakeupAlarms, operation);
-        removeLocked(mRtcAlarms, operation);
-        removeLocked(mElapsedRealtimeWakeupAlarms, operation);
-        removeLocked(mElapsedRealtimeAlarms, operation);
-    }
-
-    private void removeLocked(ArrayList<Alarm> alarmList,
-            PendingIntent operation) {
-        if (alarmList.size() <= 0) {
-            return;
+        boolean didRemove = false;
+        for (int i = mAlarmBatches.size() - 1; i >= 0; i--) {
+            Batch b = mAlarmBatches.get(i);
+            didRemove |= b.remove(operation);
+            if (b.size() == 0) {
+                mAlarmBatches.remove(i);
+            }
         }
 
-        // iterator over the list removing any it where the intent match
-        Iterator<Alarm> it = alarmList.iterator();
-        
-        while (it.hasNext()) {
-            Alarm alarm = it.next();
-            if (alarm.operation.equals(operation)) {
-                it.remove();
+        if (didRemove) {
+            if (DEBUG_BATCH) {
+                Slog.v(TAG, "remove(operation) changed bounds; rebatching");
             }
+            rebatchAllAlarmsLocked(true);
+            rescheduleKernelAlarmsLocked();
         }
     }
 
     public void removeLocked(String packageName) {
-        removeLocked(mRtcWakeupAlarms, packageName);
-        removeLocked(mRtcAlarms, packageName);
-        removeLocked(mElapsedRealtimeWakeupAlarms, packageName);
-        removeLocked(mElapsedRealtimeAlarms, packageName);
-    }
-
-    private void removeLocked(ArrayList<Alarm> alarmList,
-            String packageName) {
-        if (alarmList.size() <= 0) {
-            return;
+        boolean didRemove = false;
+        for (int i = mAlarmBatches.size() - 1; i >= 0; i--) {
+            Batch b = mAlarmBatches.get(i);
+            didRemove |= b.remove(packageName);
+            if (b.size() == 0) {
+                mAlarmBatches.remove(i);
+            }
         }
 
-        // iterator over the list removing any it where the intent match
-        Iterator<Alarm> it = alarmList.iterator();
-        
-        while (it.hasNext()) {
-            Alarm alarm = it.next();
-            if (alarm.operation.getTargetPackage().equals(packageName)) {
-                it.remove();
+        if (didRemove) {
+            if (DEBUG_BATCH) {
+                Slog.v(TAG, "remove(package) changed bounds; rebatching");
             }
+            rebatchAllAlarmsLocked(true);
+            rescheduleKernelAlarmsLocked();
         }
     }
 
     public void removeUserLocked(int userHandle) {
-        removeUserLocked(mRtcWakeupAlarms, userHandle);
-        removeUserLocked(mRtcAlarms, userHandle);
-        removeUserLocked(mElapsedRealtimeWakeupAlarms, userHandle);
-        removeUserLocked(mElapsedRealtimeAlarms, userHandle);
-    }
-
-    private void removeUserLocked(ArrayList<Alarm> alarmList, int userHandle) {
-        if (alarmList.size() <= 0) {
-            return;
-        }
-
-        // iterator over the list removing any it where the intent match
-        Iterator<Alarm> it = alarmList.iterator();
-
-        while (it.hasNext()) {
-            Alarm alarm = it.next();
-            if (UserHandle.getUserId(alarm.operation.getCreatorUid()) == userHandle) {
-                it.remove();
+        boolean didRemove = false;
+        for (int i = mAlarmBatches.size() - 1; i >= 0; i--) {
+            Batch b = mAlarmBatches.get(i);
+            didRemove |= b.remove(userHandle);
+            if (b.size() == 0) {
+                mAlarmBatches.remove(i);
             }
         }
-    }
-    
-    public boolean lookForPackageLocked(String packageName) {
-        return lookForPackageLocked(mRtcWakeupAlarms, packageName)
-                || lookForPackageLocked(mRtcAlarms, packageName)
-                || lookForPackageLocked(mElapsedRealtimeWakeupAlarms, packageName)
-                || lookForPackageLocked(mElapsedRealtimeAlarms, packageName);
+
+        if (didRemove) {
+            if (DEBUG_BATCH) {
+                Slog.v(TAG, "remove(user) changed bounds; rebatching");
+            }
+            rebatchAllAlarmsLocked(true);
+            rescheduleKernelAlarmsLocked();
+        }
     }
 
-    private boolean lookForPackageLocked(ArrayList<Alarm> alarmList, String packageName) {
-        for (int i=alarmList.size()-1; i>=0; i--) {
-            if (alarmList.get(i).operation.getTargetPackage().equals(packageName)) {
+    public boolean lookForPackageLocked(String packageName) {
+        for (int i = 0; i < mAlarmBatches.size(); i++) {
+            Batch b = mAlarmBatches.get(i);
+            if (b.hasPackage(packageName)) {
                 return true;
             }
         }
         return false;
     }
-    
-    private ArrayList<Alarm> getAlarmList(int type) {
-        switch (type) {
-            case AlarmManager.RTC_WAKEUP:              return mRtcWakeupAlarms;
-            case AlarmManager.RTC:                     return mRtcAlarms;
-            case AlarmManager.ELAPSED_REALTIME_WAKEUP: return mElapsedRealtimeWakeupAlarms;
-            case AlarmManager.ELAPSED_REALTIME:        return mElapsedRealtimeAlarms;
-        }
-        
-        return null;
-    }
-    
-    private int addAlarmLocked(Alarm alarm) {
-        ArrayList<Alarm> alarmList = getAlarmList(alarm.type);
-        
-        int index = Collections.binarySearch(alarmList, alarm, mIncreasingTimeOrder);
-        if (index < 0) {
-            index = 0 - index - 1;
-        }
-        if (localLOGV) Slog.v(TAG, "Adding alarm " + alarm + " at " + index);
-        alarmList.add(index, alarm);
 
-        if (localLOGV) {
-            // Display the list of alarms for this alarm type
-            Slog.v(TAG, "alarms: " + alarmList.size() + " type: " + alarm.type);
-            int position = 0;
-            for (Alarm a : alarmList) {
-                Time time = new Time();
-                time.set(a.when);
-                String timeStr = time.format("%b %d %I:%M:%S %p");
-                Slog.v(TAG, position + ": " + timeStr
-                        + " " + a.operation.getTargetPackage());
-                position += 1;
-            }
-        }
-        
-        return index;
-    }
-    
-    public long timeToNextAlarm() {
-        long nextAlarm = Long.MAX_VALUE;
-        synchronized (mLock) {
-            for (int i=AlarmManager.RTC_WAKEUP;
-                    i<=AlarmManager.ELAPSED_REALTIME; i++) {
-                ArrayList<Alarm> alarmList = getAlarmList(i);
-                if (alarmList.size() > 0) {
-                    Alarm a = alarmList.get(0);
-                    if (a.when < nextAlarm) {
-                        nextAlarm = a.when;
-                    }
-                }
-            }
-        }
-        return nextAlarm;
-    }
-    
-    private void setLocked(Alarm alarm)
+    private void setLocked(int type, long when)
     {
         if (mDescriptor != -1)
         {
             // The kernel never triggers alarms with negative wakeup times
             // so we ensure they are positive.
             long alarmSeconds, alarmNanoseconds;
-            if (alarm.when < 0) {
+            if (when < 0) {
                 alarmSeconds = 0;
                 alarmNanoseconds = 0;
             } else {
-                alarmSeconds = alarm.when / 1000;
-                alarmNanoseconds = (alarm.when % 1000) * 1000 * 1000;
+                alarmSeconds = when / 1000;
+                alarmNanoseconds = (when % 1000) * 1000 * 1000;
             }
             
-            set(mDescriptor, alarm.type, alarmSeconds, alarmNanoseconds);
+            set(mDescriptor, type, alarmSeconds, alarmNanoseconds);
         }
         else
         {
@@ -502,7 +811,7 @@
             msg.what = ALARM_EVENT;
             
             mHandler.removeMessages(ALARM_EVENT);
-            mHandler.sendMessageAtTime(msg, alarm.when);
+            mHandler.sendMessageAtTime(msg, when);
         }
     }
     
@@ -518,29 +827,28 @@
         
         synchronized (mLock) {
             pw.println("Current Alarm Manager state:");
-            if (mRtcWakeupAlarms.size() > 0 || mRtcAlarms.size() > 0) {
-                final long now = System.currentTimeMillis();
-                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-                pw.println(" ");
-                pw.print("  Realtime wakeup (now=");
-                        pw.print(sdf.format(new Date(now))); pw.println("):");
-                if (mRtcWakeupAlarms.size() > 0) {
-                    dumpAlarmList(pw, mRtcWakeupAlarms, "  ", "RTC_WAKEUP", now);
-                }
-                if (mRtcAlarms.size() > 0) {
-                    dumpAlarmList(pw, mRtcAlarms, "  ", "RTC", now);
-                }
-            }
-            if (mElapsedRealtimeWakeupAlarms.size() > 0 || mElapsedRealtimeAlarms.size() > 0) {
-                final long now = SystemClock.elapsedRealtime();
-                pw.println(" ");
-                pw.print("  Elapsed realtime wakeup (now=");
-                        TimeUtils.formatDuration(now, pw); pw.println("):");
-                if (mElapsedRealtimeWakeupAlarms.size() > 0) {
-                    dumpAlarmList(pw, mElapsedRealtimeWakeupAlarms, "  ", "ELAPSED_WAKEUP", now);
-                }
-                if (mElapsedRealtimeAlarms.size() > 0) {
-                    dumpAlarmList(pw, mElapsedRealtimeAlarms, "  ", "ELAPSED", now);
+            final long nowRTC = System.currentTimeMillis();
+            final long nowELAPSED = SystemClock.elapsedRealtime();
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+            pw.print("nowRTC="); pw.print(nowRTC);
+            pw.print("="); pw.print(sdf.format(new Date(nowRTC)));
+            pw.print(" nowELAPSED="); pw.println(nowELAPSED);
+
+            long nextWakeupRTC = mNextWakeup + (nowRTC - nowELAPSED);
+            long nextNonWakeupRTC = mNextNonWakeup + (nowRTC - nowELAPSED);
+            pw.print("Next alarm: "); pw.print(mNextNonWakeup);
+                    pw.print(" = "); pw.println(sdf.format(new Date(nextNonWakeupRTC)));
+            pw.print("Next wakeup: "); pw.print(mNextWakeup);
+                    pw.print(" = "); pw.println(sdf.format(new Date(nextWakeupRTC)));
+
+            if (mAlarmBatches.size() > 0) {
+                pw.println();
+                pw.print("Pending alarm batches: ");
+                pw.println(mAlarmBatches.size());
+                for (Batch b : mAlarmBatches) {
+                    pw.print(b); pw.println(':');
+                    dumpAlarmList(pw, b.alarms, "  ", nowELAPSED, nowRTC);
                 }
             }
 
@@ -643,6 +951,26 @@
                             pw.println();
                 }
             }
+
+            if (WAKEUP_STATS) {
+                pw.println();
+                pw.println("  Recent Wakeup History:");
+                long last = -1;
+                for (WakeupEvent event : mRecentWakeups) {
+                    pw.print("    "); pw.print(sdf.format(new Date(event.when)));
+                    pw.print('|');
+                    if (last < 0) {
+                        pw.print('0');
+                    } else {
+                        pw.print(event.when - last);
+                    }
+                    last = event.when;
+                    pw.print('|'); pw.print(event.uid);
+                    pw.print('|'); pw.print(event.action);
+                    pw.println();
+                }
+                pw.println();
+            }
         }
     }
 
@@ -655,74 +983,79 @@
             a.dump(pw, prefix + "  ", now);
         }
     }
-    
+
+    private static final String labelForType(int type) {
+        switch (type) {
+        case RTC: return "RTC";
+        case RTC_WAKEUP : return "RTC_WAKEUP";
+        case ELAPSED_REALTIME : return "ELAPSED";
+        case ELAPSED_REALTIME_WAKEUP: return "ELAPSED_WAKEUP";
+        default:
+            break;
+        }
+        return "--unknown--";
+    }
+
+    private static final void dumpAlarmList(PrintWriter pw, ArrayList<Alarm> list,
+            String prefix, long nowELAPSED, long nowRTC) {
+        for (int i=list.size()-1; i>=0; i--) {
+            Alarm a = list.get(i);
+            final String label = labelForType(a.type);
+            long now = (a.type <= RTC) ? nowRTC : nowELAPSED;
+            pw.print(prefix); pw.print(label); pw.print(" #"); pw.print(i);
+                    pw.print(": "); pw.println(a);
+            a.dump(pw, prefix + "  ", now);
+        }
+    }
+
     private native int init();
     private native void close(int fd);
     private native void set(int fd, int type, long seconds, long nanoseconds);
     private native int waitForAlarm(int fd);
     private native int setKernelTimezone(int fd, int minuteswest);
 
-    private void triggerAlarmsLocked(ArrayList<Alarm> alarmList,
-                                     ArrayList<Alarm> triggerList,
-                                     long now)
-    {
-        Iterator<Alarm> it = alarmList.iterator();
-        ArrayList<Alarm> repeats = new ArrayList<Alarm>();
-        
-        while (it.hasNext())
-        {
-            Alarm alarm = it.next();
+    private void triggerAlarmsLocked(ArrayList<Alarm> triggerList, long nowELAPSED, long nowRTC) {
+        Batch batch;
 
-            if (localLOGV) Slog.v(TAG, "Checking active alarm when=" + alarm.when + " " + alarm);
-
-            if (alarm.when > now) {
-                // don't fire alarms in the future
+        // batches are temporally sorted, so we need only pull from the
+        // start of the list until we either empty it or hit a batch
+        // that is not yet deliverable
+        while ((batch = mAlarmBatches.get(0)) != null) {
+            if (batch.start > nowELAPSED) {
+                // Everything else is scheduled for the future
                 break;
             }
-            
-            // If the alarm is late, then print a warning message.
-            // Note that this can happen if the user creates a new event on
-            // the Calendar app with a reminder that is in the past. In that
-            // case, the reminder alarm will fire immediately.
-            if (localLOGV && now - alarm.when > LATE_ALARM_THRESHOLD) {
-                Slog.v(TAG, "alarm is late! alarm time: " + alarm.when
-                        + " now: " + now + " delay (in seconds): "
-                        + (now - alarm.when) / 1000);
-            }
 
-            // Recurring alarms may have passed several alarm intervals while the
-            // phone was asleep or off, so pass a trigger count when sending them.
-            if (localLOGV) Slog.v(TAG, "Alarm triggering: " + alarm);
-            alarm.count = 1;
-            if (alarm.repeatInterval > 0) {
-                // this adjustment will be zero if we're late by
-                // less than one full repeat interval
-                alarm.count += (now - alarm.when) / alarm.repeatInterval;
-            }
-            triggerList.add(alarm);
-            
-            // remove the alarm from the list
-            it.remove();
-            
-            // if it repeats queue it up to be read-added to the list
-            if (alarm.repeatInterval > 0) {
-                repeats.add(alarm);
-            }
-        }
+            // We will (re)schedule some alarms now; don't let that interfere
+            // with delivery of this current batch
+            mAlarmBatches.remove(0);
 
-        // reset any repeating alarms.
-        it = repeats.iterator();
-        while (it.hasNext()) {
-            Alarm alarm = it.next();
-            alarm.when += alarm.count * alarm.repeatInterval;
-            addAlarmLocked(alarm);
-        }
-        
-        if (alarmList.size() > 0) {
-            setLocked(alarmList.get(0));
+            final int N = batch.size();
+            for (int i = 0; i < N; i++) {
+                Alarm alarm = batch.get(i);
+                alarm.count = 1;
+                triggerList.add(alarm);
+
+                // Recurring alarms may have passed several alarm intervals while the
+                // phone was asleep or off, so pass a trigger count when sending them.
+                if (alarm.repeatInterval > 0) {
+                    // this adjustment will be zero if we're late by
+                    // less than one full repeat interval
+                    alarm.count += (nowELAPSED - alarm.whenElapsed) / alarm.repeatInterval;
+
+                    // Also schedule its next recurrence
+                    final long delta = alarm.count * alarm.repeatInterval;
+                    final long nextElapsed = alarm.whenElapsed + delta;
+                    setImplLocked(alarm.type, alarm.when + delta, nextElapsed,
+                            maxTriggerTime(nowELAPSED, nextElapsed, alarm.repeatInterval),
+                            alarm.repeatInterval, alarm.operation, batch.standalone, true,
+                            alarm.workSource);
+                }
+
+            }
         }
     }
-    
+
     /**
      * This Comparator sorts Alarms into increasing time order.
      */
@@ -744,15 +1077,23 @@
         public int type;
         public int count;
         public long when;
+        public long whenElapsed;    // 'when' in the elapsed time base
+        public long maxWhen;        // also in the elapsed time base
         public long repeatInterval;
         public PendingIntent operation;
+        public WorkSource workSource;
         
-        public Alarm() {
-            when = 0;
-            repeatInterval = 0;
-            operation = null;
+        public Alarm(int _type, long _when, long _whenElapsed, long _maxWhen,
+                long _interval, PendingIntent _op, WorkSource _ws) {
+            type = _type;
+            when = _when;
+            whenElapsed = _whenElapsed;
+            maxWhen = _maxWhen;
+            repeatInterval = _interval;
+            operation = _op;
+            workSource = _ws;
         }
-        
+
         @Override
         public String toString()
         {
@@ -769,13 +1110,33 @@
 
         public void dump(PrintWriter pw, String prefix, long now) {
             pw.print(prefix); pw.print("type="); pw.print(type);
+                    pw.print(" whenElapsed="); pw.print(whenElapsed);
                     pw.print(" when="); TimeUtils.formatDuration(when, now, pw);
                     pw.print(" repeatInterval="); pw.print(repeatInterval);
                     pw.print(" count="); pw.println(count);
             pw.print(prefix); pw.print("operation="); pw.println(operation);
         }
     }
-    
+
+    void recordWakeupAlarms(ArrayList<Batch> batches, long nowELAPSED, long nowRTC) {
+        final int numBatches = batches.size();
+        for (int nextBatch = 0; nextBatch < numBatches; nextBatch++) {
+            Batch b = batches.get(nextBatch);
+            if (b.start > nowELAPSED) {
+                break;
+            }
+
+            final int numAlarms = b.alarms.size();
+            for (int nextAlarm = 0; nextAlarm < numAlarms; nextAlarm++) {
+                Alarm a = b.alarms.get(nextAlarm);
+                WakeupEvent e = new WakeupEvent(nowRTC,
+                        a.operation.getCreatorUid(),
+                        a.operation.getIntent().getAction());
+                mRecentWakeups.add(e);
+            }
+        }
+    }
+
     private class AlarmThread extends Thread
     {
         public AlarmThread()
@@ -785,14 +1146,20 @@
         
         public void run()
         {
+            ArrayList<Alarm> triggerList = new ArrayList<Alarm>();
+
             while (true)
             {
                 int result = waitForAlarm(mDescriptor);
-                
-                ArrayList<Alarm> triggerList = new ArrayList<Alarm>();
-                
+
+                triggerList.clear();
+
                 if ((result & TIME_CHANGED_MASK) != 0) {
+                    if (DEBUG_BATCH) {
+                        Slog.v(TAG, "Time changed notification from kernel; rebatching");
+                    }
                     remove(mTimeTickSender);
+                    rebatchAllAlarms();
                     mClockReceiver.scheduleTimeTickEvent();
                     Intent intent = new Intent(Intent.ACTION_TIME_CHANGED);
                     intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
@@ -807,22 +1174,28 @@
                         TAG, "Checking for alarms... rtc=" + nowRTC
                         + ", elapsed=" + nowELAPSED);
 
-                    if ((result & RTC_WAKEUP_MASK) != 0)
-                        triggerAlarmsLocked(mRtcWakeupAlarms, triggerList, nowRTC);
-                    
-                    if ((result & RTC_MASK) != 0)
-                        triggerAlarmsLocked(mRtcAlarms, triggerList, nowRTC);
-                    
-                    if ((result & ELAPSED_REALTIME_WAKEUP_MASK) != 0)
-                        triggerAlarmsLocked(mElapsedRealtimeWakeupAlarms, triggerList, nowELAPSED);
-                    
-                    if ((result & ELAPSED_REALTIME_MASK) != 0)
-                        triggerAlarmsLocked(mElapsedRealtimeAlarms, triggerList, nowELAPSED);
-                    
-                    // now trigger the alarms
-                    Iterator<Alarm> it = triggerList.iterator();
-                    while (it.hasNext()) {
-                        Alarm alarm = it.next();
+                    if (WAKEUP_STATS) {
+                        if ((result & IS_WAKEUP_MASK) != 0) {
+                            long newEarliest = nowRTC - RECENT_WAKEUP_PERIOD;
+                            int n = 0;
+                            for (WakeupEvent event : mRecentWakeups) {
+                                if (event.when > newEarliest) break;
+                                n++; // number of now-stale entries at the list head
+                            }
+                            for (int i = 0; i < n; i++) {
+                                mRecentWakeups.remove();
+                            }
+
+                            recordWakeupAlarms(mAlarmBatches, nowELAPSED, nowRTC);
+                        }
+                    }
+
+                    triggerAlarmsLocked(triggerList, nowELAPSED, nowRTC);
+                    rescheduleKernelAlarmsLocked();
+
+                    // now deliver the alarm intents
+                    for (int i=0; i<triggerList.size(); i++) {
+                        Alarm alarm = triggerList.get(i);
                         try {
                             if (localLOGV) Slog.v(TAG, "sending alarm " + alarm);
                             alarm.operation.send(mContext, 0,
@@ -832,11 +1205,11 @@
                             
                             // we have an active broadcast so stay awake.
                             if (mBroadcastRefCount == 0) {
-                                setWakelockWorkSource(alarm.operation);
+                                setWakelockWorkSource(alarm.operation, alarm.workSource);
                                 mWakeLock.acquire();
                             }
                             final InFlight inflight = new InFlight(AlarmManagerService.this,
-                                    alarm.operation);
+                                    alarm.operation, alarm.workSource);
                             mInFlight.add(inflight);
                             mBroadcastRefCount++;
 
@@ -856,8 +1229,8 @@
                             } else {
                                 fs.nesting++;
                             }
-                            if (alarm.type == AlarmManager.ELAPSED_REALTIME_WAKEUP
-                                    || alarm.type == AlarmManager.RTC_WAKEUP) {
+                            if (alarm.type == ELAPSED_REALTIME_WAKEUP
+                                    || alarm.type == RTC_WAKEUP) {
                                 bs.numWakeup++;
                                 fs.numWakeup++;
                                 ActivityManagerNative.noteWakeupAlarm(
@@ -878,8 +1251,18 @@
         }
     }
 
-    void setWakelockWorkSource(PendingIntent pi) {
+    /**
+     * Attribute blame for a WakeLock.
+     * @param pi PendingIntent to attribute blame to if ws is null.
+     * @param ws WorkSource to attribute blame.
+     */
+    void setWakelockWorkSource(PendingIntent pi, WorkSource ws) {
         try {
+            if (ws != null) {
+                mWakeLock.setWorkSource(ws);
+                return;
+            }
+
             final int uid = ActivityManagerNative.getDefault()
                     .getUidForIntentSender(pi.getTarget());
             if (uid >= 0) {
@@ -906,17 +1289,13 @@
                 ArrayList<Alarm> triggerList = new ArrayList<Alarm>();
                 synchronized (mLock) {
                     final long nowRTC = System.currentTimeMillis();
-                    triggerAlarmsLocked(mRtcWakeupAlarms, triggerList, nowRTC);
-                    triggerAlarmsLocked(mRtcAlarms, triggerList, nowRTC);
-                    triggerAlarmsLocked(mElapsedRealtimeWakeupAlarms, triggerList, nowRTC);
-                    triggerAlarmsLocked(mElapsedRealtimeAlarms, triggerList, nowRTC);
+                    final long nowELAPSED = SystemClock.elapsedRealtime();
+                    triggerAlarmsLocked(triggerList, nowELAPSED, nowRTC);
                 }
                 
                 // now trigger the alarms without the lock held
-                Iterator<Alarm> it = triggerList.iterator();
-                while (it.hasNext())
-                {
-                    Alarm alarm = it.next();
+                for (int i=0; i<triggerList.size(); i++) {
+                    Alarm alarm = triggerList.get(i);
                     try {
                         alarm.operation.send();
                     } catch (PendingIntent.CanceledException e) {
@@ -942,7 +1321,10 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             if (intent.getAction().equals(Intent.ACTION_TIME_TICK)) {
-            	scheduleTimeTickEvent();
+                if (DEBUG_BATCH) {
+                    Slog.v(TAG, "Received TIME_TICK alarm; rescheduling");
+                }
+                scheduleTimeTickEvent();
             } else if (intent.getAction().equals(Intent.ACTION_DATE_CHANGED)) {
                 // Since the kernel does not keep track of DST, we need to
                 // reset the TZ information at the beginning of each day
@@ -951,7 +1333,7 @@
                 TimeZone zone = TimeZone.getTimeZone(SystemProperties.get(TIMEZONE_PROPERTY));
                 int gmtOffset = zone.getOffset(System.currentTimeMillis());
                 setKernelTimezone(mDescriptor, -(gmtOffset / 60000));
-            	scheduleDateChangedEvent();
+                scheduleDateChangedEvent();
             }
         }
         
@@ -963,10 +1345,11 @@
             // the top of the next minute.
             final long tickEventDelay = nextTime - currentTime;
 
-            set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + tickEventDelay,
-                    mTimeTickSender);
+            final WorkSource workSource = null; // Let system take blame for time tick events.
+            set(ELAPSED_REALTIME, SystemClock.elapsedRealtime() + tickEventDelay, 0,
+                    0, mTimeTickSender, true, workSource);
         }
-	
+
         public void scheduleDateChangedEvent() {
             Calendar calendar = Calendar.getInstance();
             calendar.setTimeInMillis(System.currentTimeMillis());
@@ -975,8 +1358,9 @@
             calendar.set(Calendar.SECOND, 0);
             calendar.set(Calendar.MILLISECOND, 0);
             calendar.add(Calendar.DAY_OF_MONTH, 1);
-      
-            set(AlarmManager.RTC, calendar.getTimeInMillis(), mDateChangeSender);
+
+            final WorkSource workSource = null; // Let system take blame for date change events.
+            set(RTC, calendar.getTimeInMillis(), 0, 0, mDateChangeSender, true, workSource);
         }
     }
     
@@ -1092,7 +1476,8 @@
                 } else {
                     // the next of our alarms is now in flight.  reattribute the wakelock.
                     if (mInFlight.size() > 0) {
-                        setWakelockWorkSource(mInFlight.get(0).mPendingIntent);
+                        InFlight inFlight = mInFlight.get(0);
+                        setWakelockWorkSource(inFlight.mPendingIntent, inFlight.mWorkSource);
                     } else {
                         // should never happen
                         mLog.w("Alarm wakelock still held but sent queue empty");
diff --git a/services/java/com/android/server/AppOpsService.java b/services/java/com/android/server/AppOpsService.java
index a55fddc..c6c4a94 100644
--- a/services/java/com/android/server/AppOpsService.java
+++ b/services/java/com/android/server/AppOpsService.java
@@ -41,6 +41,7 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
+import android.util.ArrayMap;
 import android.util.AtomicFile;
 import android.util.Log;
 import android.util.Pair;
@@ -99,6 +100,8 @@
     }
 
     public final static class Op {
+        public final int uid;
+        public final String packageName;
         public final int op;
         public int mode;
         public int duration;
@@ -106,7 +109,9 @@
         public long rejectTime;
         public int nesting;
 
-        public Op(int _op) {
+        public Op(int _uid, String _packageName, int _op) {
+            uid = _uid;
+            packageName = _packageName;
             op = _op;
             mode = AppOpsManager.MODE_ALLOWED;
         }
@@ -114,10 +119,10 @@
 
     final SparseArray<ArrayList<Callback>> mOpModeWatchers
             = new SparseArray<ArrayList<Callback>>();
-    final HashMap<String, ArrayList<Callback>> mPackageModeWatchers
-            = new HashMap<String, ArrayList<Callback>>();
-    final HashMap<IBinder, Callback> mModeWatchers
-            = new HashMap<IBinder, Callback>();
+    final ArrayMap<String, ArrayList<Callback>> mPackageModeWatchers
+            = new ArrayMap<String, ArrayList<Callback>>();
+    final ArrayMap<IBinder, Callback> mModeWatchers
+            = new ArrayMap<IBinder, Callback>();
 
     public final class Callback implements DeathRecipient {
         final IAppOpsCallback mCallback;
@@ -140,6 +145,47 @@
         }
     }
 
+    final ArrayMap<IBinder, ClientState> mClients = new ArrayMap<IBinder, ClientState>();
+
+    public final class ClientState extends Binder implements DeathRecipient {
+        final IBinder mAppToken;
+        final int mPid;
+        final ArrayList<Op> mStartedOps;
+
+        public ClientState(IBinder appToken) {
+            mAppToken = appToken;
+            mPid = Binder.getCallingPid();
+            if (appToken instanceof Binder) {
+                // For local clients, there is no reason to track them.
+                mStartedOps = null;
+            } else {
+                mStartedOps = new ArrayList<Op>();
+                try {
+                    mAppToken.linkToDeath(this, 0);
+                } catch (RemoteException e) {
+                }
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "ClientState{" +
+                    "mAppToken=" + mAppToken +
+                    ", " + (mStartedOps != null ? ("pid=" + mPid) : "local") +
+                    '}';
+        }
+
+        @Override
+        public void binderDied() {
+            synchronized (AppOpsService.this) {
+                for (int i=mStartedOps.size()-1; i>=0; i--) {
+                    finishOperationLocked(mStartedOps.get(i));
+                }
+                mClients.remove(mAppToken);
+            }
+        }
+    }
+
     public AppOpsService(File storagePath) {
         mFile = new AtomicFile(storagePath);
         mHandler = new Handler();
@@ -462,21 +508,18 @@
             Callback cb = mModeWatchers.remove(callback.asBinder());
             if (cb != null) {
                 cb.unlinkToDeath();
-                for (int i=0; i<mOpModeWatchers.size(); i++) {
+                for (int i=mOpModeWatchers.size()-1; i>=0; i--) {
                     ArrayList<Callback> cbs = mOpModeWatchers.valueAt(i);
                     cbs.remove(cb);
                     if (cbs.size() <= 0) {
                         mOpModeWatchers.removeAt(i);
                     }
                 }
-                if (mPackageModeWatchers.size() > 0) {
-                    Iterator<ArrayList<Callback>> it = mPackageModeWatchers.values().iterator();
-                    while (it.hasNext()) {
-                        ArrayList<Callback> cbs = it.next();
-                        cbs.remove(cb);
-                        if (cbs.size() <= 0) {
-                            it.remove();
-                        }
+                for (int i=mPackageModeWatchers.size()-1; i>=0; i--) {
+                    ArrayList<Callback> cbs = mPackageModeWatchers.valueAt(i);
+                    cbs.remove(cb);
+                    if (cbs.size() <= 0) {
+                        mPackageModeWatchers.removeAt(i);
                     }
                 }
             }
@@ -484,6 +527,18 @@
     }
 
     @Override
+    public IBinder getToken(IBinder clientToken) {
+        synchronized (this) {
+            ClientState cs = mClients.get(clientToken);
+            if (cs == null) {
+                cs = new ClientState(clientToken);
+                mClients.put(clientToken, cs);
+            }
+            return cs;
+        }
+    }
+
+    @Override
     public int checkOperation(int code, int uid, String packageName) {
         verifyIncomingUid(uid);
         verifyIncomingOp(code);
@@ -497,6 +552,17 @@
     }
 
     @Override
+    public int checkPackage(int uid, String packageName) {
+        synchronized (this) {
+            if (getOpsLocked(uid, packageName, true) != null) {
+                return AppOpsManager.MODE_ALLOWED;
+            } else {
+                return AppOpsManager.MODE_ERRORED;
+            }
+        }
+    }
+
+    @Override
     public int noteOperation(int code, int uid, String packageName) {
         verifyIncomingUid(uid);
         verifyIncomingOp(code);
@@ -505,7 +571,7 @@
             if (ops == null) {
                 if (DEBUG) Log.d(TAG, "noteOperation: no op for code " + code + " uid " + uid
                         + " package " + packageName);
-                return AppOpsManager.MODE_IGNORED;
+                return AppOpsManager.MODE_ERRORED;
             }
             Op op = getOpLocked(ops, code, true);
             if (op.duration == -1) {
@@ -530,15 +596,16 @@
     }
 
     @Override
-    public int startOperation(int code, int uid, String packageName) {
+    public int startOperation(IBinder token, int code, int uid, String packageName) {
         verifyIncomingUid(uid);
         verifyIncomingOp(code);
+        ClientState client = (ClientState)token;
         synchronized (this) {
             Ops ops = getOpsLocked(uid, packageName, true);
             if (ops == null) {
                 if (DEBUG) Log.d(TAG, "startOperation: no op for code " + code + " uid " + uid
                         + " package " + packageName);
-                return AppOpsManager.MODE_IGNORED;
+                return AppOpsManager.MODE_ERRORED;
             }
             Op op = getOpLocked(ops, code, true);
             final int switchCode = AppOpsManager.opToSwitch(code);
@@ -557,32 +624,46 @@
                 op.duration = -1;
             }
             op.nesting++;
+            if (client.mStartedOps != null) {
+                client.mStartedOps.add(op);
+            }
             return AppOpsManager.MODE_ALLOWED;
         }
     }
 
     @Override
-    public void finishOperation(int code, int uid, String packageName) {
+    public void finishOperation(IBinder token, int code, int uid, String packageName) {
         verifyIncomingUid(uid);
         verifyIncomingOp(code);
+        ClientState client = (ClientState)token;
         synchronized (this) {
             Op op = getOpLocked(code, uid, packageName, true);
             if (op == null) {
                 return;
             }
-            if (op.nesting <= 1) {
-                if (op.nesting == 1) {
-                    op.duration = (int)(System.currentTimeMillis() - op.time);
-                    op.time += op.duration;
-                } else {
-                    Slog.w(TAG, "Finishing op nesting under-run: uid " + uid + " pkg " + packageName
-                        + " code " + code + " time=" + op.time + " duration=" + op.duration
-                        + " nesting=" + op.nesting);
+            if (client.mStartedOps != null) {
+                if (!client.mStartedOps.remove(op)) {
+                    throw new IllegalStateException("Operation not started: uid" + op.uid
+                            + " pkg=" + op.packageName + " op=" + op.op);
                 }
-                op.nesting = 0;
-            } else {
-                op.nesting--;
             }
+            finishOperationLocked(op);
+        }
+    }
+
+    void finishOperationLocked(Op op) {
+        if (op.nesting <= 1) {
+            if (op.nesting == 1) {
+                op.duration = (int)(System.currentTimeMillis() - op.time);
+                op.time += op.duration;
+            } else {
+                Slog.w(TAG, "Finishing op nesting under-run: uid " + op.uid + " pkg "
+                        + op.packageName + " code " + op.op + " time=" + op.time
+                        + " duration=" + op.duration + " nesting=" + op.nesting);
+            }
+            op.nesting = 0;
+        } else {
+            op.nesting--;
         }
     }
 
@@ -633,6 +714,9 @@
                         pkgUid = mContext.getPackageManager().getPackageUid(packageName,
                                 UserHandle.getUserId(uid));
                     } catch (NameNotFoundException e) {
+                        if ("media".equals(packageName)) {
+                            pkgUid = Process.MEDIA_UID;
+                        }
                     }
                     if (pkgUid != uid) {
                         // Oops!  The package name is not valid for the uid they are calling
@@ -680,7 +764,7 @@
             if (!edit) {
                 return null;
             }
-            op = new Op(code);
+            op = new Op(ops.uid, ops.packageName, code);
             ops.put(code, op);
         }
         if (edit) {
@@ -790,7 +874,7 @@
 
             String tagName = parser.getName();
             if (tagName.equals("op")) {
-                Op op = new Op(Integer.parseInt(parser.getAttributeValue(null, "n")));
+                Op op = new Op(uid, pkgName, Integer.parseInt(parser.getAttributeValue(null, "n")));
                 String mode = parser.getAttributeValue(null, "m");
                 if (mode != null) {
                     op.mode = Integer.parseInt(mode);
@@ -910,6 +994,62 @@
         synchronized (this) {
             pw.println("Current AppOps Service state:");
             final long now = System.currentTimeMillis();
+            boolean needSep = false;
+            if (mOpModeWatchers.size() > 0) {
+                needSep = true;
+                pw.println("  Op mode watchers:");
+                for (int i=0; i<mOpModeWatchers.size(); i++) {
+                    pw.print("    Op "); pw.print(AppOpsManager.opToName(mOpModeWatchers.keyAt(i)));
+                    pw.println(":");
+                    ArrayList<Callback> callbacks = mOpModeWatchers.valueAt(i);
+                    for (int j=0; j<callbacks.size(); j++) {
+                        pw.print("      #"); pw.print(j); pw.print(": ");
+                        pw.println(callbacks.get(j));
+                    }
+                }
+            }
+            if (mPackageModeWatchers.size() > 0) {
+                needSep = true;
+                pw.println("  Package mode watchers:");
+                for (int i=0; i<mPackageModeWatchers.size(); i++) {
+                    pw.print("    Pkg "); pw.print(mPackageModeWatchers.keyAt(i));
+                    pw.println(":");
+                    ArrayList<Callback> callbacks = mPackageModeWatchers.valueAt(i);
+                    for (int j=0; j<callbacks.size(); j++) {
+                        pw.print("      #"); pw.print(j); pw.print(": ");
+                        pw.println(callbacks.get(j));
+                    }
+                }
+            }
+            if (mModeWatchers.size() > 0) {
+                needSep = true;
+                pw.println("  All mode watchers:");
+                for (int i=0; i<mModeWatchers.size(); i++) {
+                    pw.print("    "); pw.print(mModeWatchers.keyAt(i));
+                    pw.print(" -> "); pw.println(mModeWatchers.valueAt(i));
+                }
+            }
+            if (mClients.size() > 0) {
+                needSep = true;
+                pw.println("  Clients:");
+                for (int i=0; i<mClients.size(); i++) {
+                    pw.print("    "); pw.print(mClients.keyAt(i)); pw.println(":");
+                    ClientState cs = mClients.valueAt(i);
+                    pw.print("      "); pw.println(cs);
+                    if (cs.mStartedOps != null && cs.mStartedOps.size() > 0) {
+                        pw.println("      Started ops:");
+                        for (int j=0; j<cs.mStartedOps.size(); j++) {
+                            Op op = cs.mStartedOps.get(j);
+                            pw.print("        "); pw.print("uid="); pw.print(op.uid);
+                            pw.print(" pkg="); pw.print(op.packageName);
+                            pw.print(" op="); pw.println(AppOpsManager.opToName(op.op));
+                        }
+                    }
+                }
+            }
+            if (needSep) {
+                pw.println();
+            }
             for (int i=0; i<mUidOps.size(); i++) {
                 pw.print("  Uid "); UserHandle.formatUid(pw, mUidOps.keyAt(i)); pw.println(":");
                 HashMap<String, Ops> pkgOps = mUidOps.valueAt(i);
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index d5715a5..203cca6 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -27,7 +27,6 @@
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
-import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -37,6 +36,7 @@
 
 import com.android.internal.appwidget.IAppWidgetHost;
 import com.android.internal.appwidget.IAppWidgetService;
+import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.IndentingPrintWriter;
 
 import java.io.FileDescriptor;
@@ -63,16 +63,14 @@
     AppWidgetService(Context context) {
         mContext = context;
 
-        HandlerThread handlerThread = new HandlerThread("AppWidgetService -- Save state");
-        handlerThread.start();
-        mSaveStateHandler = new Handler(handlerThread.getLooper());
+        mSaveStateHandler = BackgroundThread.getHandler();
 
         mAppWidgetServices = new SparseArray<AppWidgetServiceImpl>(5);
         AppWidgetServiceImpl primary = new AppWidgetServiceImpl(context, 0, mSaveStateHandler);
         mAppWidgetServices.append(0, primary);
     }
 
-    public void systemReady(boolean safeMode) {
+    public void systemRunning(boolean safeMode) {
         mSafeMode = safeMode;
 
         mAppWidgetServices.get(0).systemReady(safeMode);
diff --git a/services/java/com/android/server/AppWidgetServiceImpl.java b/services/java/com/android/server/AppWidgetServiceImpl.java
index fb2828b..69ae846 100644
--- a/services/java/com/android/server/AppWidgetServiceImpl.java
+++ b/services/java/com/android/server/AppWidgetServiceImpl.java
@@ -86,9 +86,12 @@
 
 class AppWidgetServiceImpl {
 
+    private static final String KEYGUARD_HOST_PACKAGE = "com.android.keyguard";
+    private static final int KEYGUARD_HOST_ID = 0x4b455947;
     private static final String TAG = "AppWidgetServiceImpl";
     private static final String SETTINGS_FILENAME = "appwidgets.xml";
     private static final int MIN_UPDATE_PERIOD = 30 * 60 * 1000; // 30 minutes
+    private static final int CURRENT_VERSION = 1; // Bump if the stored widgets need to be upgraded.
 
     private static boolean DBG = false;
 
@@ -1654,7 +1657,7 @@
             out.setOutput(stream, "utf-8");
             out.startDocument(null, true);
             out.startTag(null, "gs");
-
+            out.attribute(null, "version", String.valueOf(CURRENT_VERSION));
             int providerIndex = 0;
             N = mInstalledProviders.size();
             for (int i = 0; i < N; i++) {
@@ -1723,6 +1726,7 @@
     @SuppressWarnings("unused")
     void readStateFromFileLocked(FileInputStream stream) {
         boolean success = false;
+        int version = 0;
         try {
             XmlPullParser parser = Xml.newPullParser();
             parser.setInput(stream, null);
@@ -1734,7 +1738,14 @@
                 type = parser.next();
                 if (type == XmlPullParser.START_TAG) {
                     String tag = parser.getName();
-                    if ("p".equals(tag)) {
+                    if ("gs".equals(tag)) {
+                        String attributeValue = parser.getAttributeValue(null, "version");
+                        try {
+                            version = Integer.parseInt(attributeValue);
+                        } catch (NumberFormatException e) {
+                            version = 0;
+                        }
+                    } else if ("p".equals(tag)) {
                         // TODO: do we need to check that this package has the same signature
                         // as before?
                         String pkg = parser.getAttributeValue(null, "pkg");
@@ -1873,6 +1884,8 @@
             for (int i = mHosts.size() - 1; i >= 0; i--) {
                 pruneHostLocked(mHosts.get(i));
             }
+            // upgrade the database if needed
+            performUpgrade(version);
         } else {
             // failed reading, clean up
             Slog.w(TAG, "Failed to read state, clearing widgets and hosts.");
@@ -1886,6 +1899,31 @@
         }
     }
 
+    private void performUpgrade(int fromVersion) {
+        if (fromVersion < CURRENT_VERSION) {
+            Slog.v(TAG, "Upgrading widget database from " + fromVersion + " to " + CURRENT_VERSION
+                    + " for user " + mUserId);
+        }
+
+        int version = fromVersion;
+
+        // Update 1: keyguard moved from package "android" to "com.android.keyguard"
+        if (version == 0) {
+            for (int i = 0; i < mHosts.size(); i++) {
+                Host host = mHosts.get(i);
+                if (host != null && "android".equals(host.packageName)
+                        && host.hostId == KEYGUARD_HOST_ID) {
+                    host.packageName = KEYGUARD_HOST_PACKAGE;
+                }
+            }
+            version = 1;
+        }
+
+        if (version != CURRENT_VERSION) {
+            throw new IllegalStateException("Failed to upgrade widget database");
+        }
+    }
+
     static File getSettingsFile(int userId) {
         return new File(Environment.getUserSystemDirectory(userId), SETTINGS_FILENAME);
     }
diff --git a/services/java/com/android/server/AssetAtlasService.java b/services/java/com/android/server/AssetAtlasService.java
new file mode 100644
index 0000000..26b4652
--- /dev/null
+++ b/services/java/com/android/server/AssetAtlasService.java
@@ -0,0 +1,735 @@
+/*
+ * 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.server;
+
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.graphics.Atlas;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.drawable.Drawable;
+import android.os.Environment;
+import android.os.RemoteException;
+import android.os.SystemProperties;
+import android.util.Log;
+import android.util.LongSparseArray;
+import android.view.GraphicBuffer;
+import android.view.IAssetAtlas;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * This service is responsible for packing preloaded bitmaps into a single
+ * atlas texture. The resulting texture can be shared across processes to
+ * reduce overall memory usage.
+ *
+ * @hide
+ */
+public class AssetAtlasService extends IAssetAtlas.Stub {
+    /**
+     * Name of the <code>AssetAtlasService</code>.
+     */
+    public static final String ASSET_ATLAS_SERVICE = "assetatlas";
+
+    private static final String LOG_TAG = "Atlas";
+
+    // Turns debug logs on/off. Debug logs are kept to a minimum and should
+    // remain on to diagnose issues
+    private static final boolean DEBUG_ATLAS = true;
+
+    // When set to true the content of the atlas will be saved to disk
+    // in /data/system/atlas.png. The shared GraphicBuffer may be empty
+    private static final boolean DEBUG_ATLAS_TEXTURE = false;
+
+    // Minimum size in pixels to consider for the resulting texture
+    private static final int MIN_SIZE = 768;
+    // Maximum size in pixels to consider for the resulting texture
+    private static final int MAX_SIZE = 2048;
+    // Increment in number of pixels between size variants when looking
+    // for the best texture dimensions
+    private static final int STEP = 64;
+
+    // This percentage of the total number of pixels represents the minimum
+    // number of pixels we want to be able to pack in the atlas
+    private static final float PACKING_THRESHOLD = 0.8f;
+
+    // Defines the number of int fields used to represent a single entry
+    // in the atlas map. This number defines the size of the array returned
+    // by the getMap(). See the mAtlasMap field for more information
+    private static final int ATLAS_MAP_ENTRY_FIELD_COUNT = 4;
+
+    // Specifies how our GraphicBuffer will be used. To get proper swizzling
+    // the buffer will be written to using OpenGL (from JNI) so we can leave
+    // the software flag set to "never"
+    private static final int GRAPHIC_BUFFER_USAGE = GraphicBuffer.USAGE_SW_READ_NEVER |
+            GraphicBuffer.USAGE_SW_WRITE_NEVER | GraphicBuffer.USAGE_HW_TEXTURE;
+
+    // This boolean is set to true if an atlas was successfully
+    // computed and rendered
+    private final AtomicBoolean mAtlasReady = new AtomicBoolean(false);
+
+    private final Context mContext;
+
+    // Version name of the current build, used to identify changes to assets list
+    private final String mVersionName;
+
+    // Holds the atlas' data. This buffer can be mapped to
+    // OpenGL using an EGLImage
+    private GraphicBuffer mBuffer;
+
+    // Describes how bitmaps are placed in the atlas. Each bitmap is
+    // represented by several entries in the array:
+    // int0: SkBitmap*, the native bitmap object
+    // int1: x position
+    // int2: y position
+    // int3: rotated, 1 if the bitmap must be rotated, 0 otherwise
+    // NOTE: This will need to be handled differently to support 64 bit pointers
+    private int[] mAtlasMap;
+
+    /**
+     * Creates a new service. Upon creating, the service will gather the list of
+     * assets to consider for packing into the atlas and spawn a new thread to
+     * start the packing work.
+     *
+     * @param context The context giving access to preloaded resources
+     */
+    public AssetAtlasService(Context context) {
+        mContext = context;
+        mVersionName = queryVersionName(context);
+
+        ArrayList<Bitmap> bitmaps = new ArrayList<Bitmap>(300);
+        int totalPixelCount = 0;
+
+        // We only care about drawables that hold bitmaps
+        final Resources resources = context.getResources();
+        final LongSparseArray<Drawable.ConstantState> drawables = resources.getPreloadedDrawables();
+
+        final int count = drawables.size();
+        for (int i = 0; i < count; i++) {
+            final Bitmap bitmap = drawables.valueAt(i).getBitmap();
+            if (bitmap != null && bitmap.getConfig() == Bitmap.Config.ARGB_8888) {
+                bitmaps.add(bitmap);
+                totalPixelCount += bitmap.getWidth() * bitmap.getHeight();
+            }
+        }
+
+        // Our algorithms perform better when the bitmaps are first sorted
+        // The comparator will sort the bitmap by width first, then by height
+        Collections.sort(bitmaps, new Comparator<Bitmap>() {
+            @Override
+            public int compare(Bitmap b1, Bitmap b2) {
+                if (b1.getWidth() == b2.getWidth()) {
+                    return b2.getHeight() - b1.getHeight();
+                }
+                return b2.getWidth() - b1.getWidth();
+            }
+        });
+
+        // Kick off the packing work on a worker thread
+        new Thread(new Renderer(bitmaps, totalPixelCount)).start();
+    }
+
+    /**
+     * Queries the version name stored in framework's AndroidManifest.
+     * The version name can be used to identify possible changes to
+     * framework resources.
+     *
+     * @see #getBuildIdentifier(String)
+     */
+    private static String queryVersionName(Context context) {
+        try {
+            String packageName = context.getPackageName();
+            PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);
+            return info.versionName;
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.w(LOG_TAG, "Could not get package info", e);
+        }
+        return null;
+    }
+
+    /**
+     * Callback invoked by the server thread to indicate we can now run
+     * 3rd party code.
+     */
+    public void systemRunning() {
+    }
+
+    /**
+     * The renderer does all the work:
+     */
+    private class Renderer implements Runnable {
+        private final ArrayList<Bitmap> mBitmaps;
+        private final int mPixelCount;
+
+        private int mNativeBitmap;
+
+        // Used for debugging only
+        private Bitmap mAtlasBitmap;
+
+        Renderer(ArrayList<Bitmap> bitmaps, int pixelCount) {
+            mBitmaps = bitmaps;
+            mPixelCount = pixelCount;
+        }
+
+        /**
+         * 1. On first boot or after every update, brute-force through all the
+         *    possible atlas configurations and look for the best one (maximimize
+         *    number of packed assets and minimize texture size)
+         *    a. If a best configuration was computed, write it out to disk for
+         *       future use
+         * 2. Read best configuration from disk
+         * 3. Compute the packing using the best configuration
+         * 4. Allocate a GraphicBuffer
+         * 5. Render assets in the buffer
+         */
+        @Override
+        public void run() {
+            Configuration config = chooseConfiguration(mBitmaps, mPixelCount, mVersionName);
+            if (DEBUG_ATLAS) Log.d(LOG_TAG, "Loaded configuration: " + config);
+
+            if (config != null) {
+                mBuffer = GraphicBuffer.create(config.width, config.height,
+                        PixelFormat.RGBA_8888, GRAPHIC_BUFFER_USAGE);
+
+                if (mBuffer != null) {
+                    Atlas atlas = new Atlas(config.type, config.width, config.height, config.flags);
+                    if (renderAtlas(mBuffer, atlas, config.count)) {
+                        mAtlasReady.set(true);
+                    }
+                }
+            }
+        }
+
+        /**
+         * Renders a list of bitmaps into the atlas. The position of each bitmap
+         * was decided by the packing algorithm and will be honored by this
+         * method. If need be this method will also rotate bitmaps.
+         *
+         * @param buffer The buffer to render the atlas entries into
+         * @param atlas The atlas to pack the bitmaps into
+         * @param packCount The number of bitmaps that will be packed in the atlas
+         *
+         * @return true if the atlas was rendered, false otherwise
+         */
+        @SuppressWarnings("MismatchedReadAndWriteOfArray")
+        private boolean renderAtlas(GraphicBuffer buffer, Atlas atlas, int packCount) {
+            // Use a Source blend mode to improve performance, the target bitmap
+            // will be zero'd out so there's no need to waste time applying blending
+            final Paint paint = new Paint();
+            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
+
+            // We always render the atlas into a bitmap. This bitmap is then
+            // uploaded into the GraphicBuffer using OpenGL to swizzle the content
+            final Canvas canvas = acquireCanvas(buffer.getWidth(), buffer.getHeight());
+            if (canvas == null) return false;
+
+            final Atlas.Entry entry = new Atlas.Entry();
+
+            mAtlasMap = new int[packCount * ATLAS_MAP_ENTRY_FIELD_COUNT];
+            int[] atlasMap = mAtlasMap;
+            int mapIndex = 0;
+
+            boolean result = false;
+            try {
+                final long startRender = System.nanoTime();
+                final int count = mBitmaps.size();
+
+                for (int i = 0; i < count; i++) {
+                    final Bitmap bitmap = mBitmaps.get(i);
+                    if (atlas.pack(bitmap.getWidth(), bitmap.getHeight(), entry) != null) {
+                        // We have more bitmaps to pack than the current configuration
+                        // says, we were most likely not able to detect a change in the
+                        // list of preloaded drawables, abort and delete the configuration
+                        if (mapIndex >= mAtlasMap.length) {
+                            deleteDataFile();
+                            break;
+                        }
+
+                        canvas.save();
+                        canvas.translate(entry.x, entry.y);
+                        if (entry.rotated) {
+                            canvas.translate(bitmap.getHeight(), 0.0f);
+                            canvas.rotate(90.0f);
+                        }
+                        canvas.drawBitmap(bitmap, 0.0f, 0.0f, null);
+                        canvas.restore();
+
+                        atlasMap[mapIndex++] = bitmap.mNativeBitmap;
+                        atlasMap[mapIndex++] = entry.x;
+                        atlasMap[mapIndex++] = entry.y;
+                        atlasMap[mapIndex++] = entry.rotated ? 1 : 0;
+                    }
+                }
+
+                final long endRender = System.nanoTime();
+                if (mNativeBitmap != 0) {
+                    result = nUploadAtlas(buffer, mNativeBitmap);
+                }
+
+                final long endUpload = System.nanoTime();
+                if (DEBUG_ATLAS) {
+                    float renderDuration = (endRender - startRender) / 1000.0f / 1000.0f;
+                    float uploadDuration = (endUpload - endRender) / 1000.0f / 1000.0f;
+                    Log.d(LOG_TAG, String.format("Rendered atlas in %.2fms (%.2f+%.2fms)",
+                            renderDuration + uploadDuration, renderDuration, uploadDuration));
+                }
+
+            } finally {
+                releaseCanvas(canvas);
+            }
+
+            return result;
+        }
+
+        /**
+         * Returns a Canvas for the specified buffer. If {@link #DEBUG_ATLAS_TEXTURE}
+         * is turned on, the returned Canvas will render into a local bitmap that
+         * will then be saved out to disk for debugging purposes.
+         * @param width
+         * @param height
+         */
+        private Canvas acquireCanvas(int width, int height) {
+            if (DEBUG_ATLAS_TEXTURE) {
+                mAtlasBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+                return new Canvas(mAtlasBitmap);
+            } else {
+                Canvas canvas = new Canvas();
+                mNativeBitmap = nAcquireAtlasCanvas(canvas, width, height);
+                return canvas;
+            }
+        }
+
+        /**
+         * Releases the canvas used to render into the buffer. Calling this method
+         * will release any resource previously acquired. If {@link #DEBUG_ATLAS_TEXTURE}
+         * is turend on, calling this method will write the content of the atlas
+         * to disk in /data/system/atlas.png for debugging.
+         */
+        private void releaseCanvas(Canvas canvas) {
+            if (DEBUG_ATLAS_TEXTURE) {
+                canvas.setBitmap(null);
+
+                File systemDirectory = new File(Environment.getDataDirectory(), "system");
+                File dataFile = new File(systemDirectory, "atlas.png");
+
+                try {
+                    FileOutputStream out = new FileOutputStream(dataFile);
+                    mAtlasBitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
+                    out.close();
+                } catch (FileNotFoundException e) {
+                    // Ignore
+                } catch (IOException e) {
+                    // Ignore
+                }
+
+                mAtlasBitmap.recycle();
+                mAtlasBitmap = null;
+            } else {
+                nReleaseAtlasCanvas(canvas, mNativeBitmap);
+            }
+        }
+    }
+
+    private static native int nAcquireAtlasCanvas(Canvas canvas, int width, int height);
+    private static native void nReleaseAtlasCanvas(Canvas canvas, int bitmap);
+    private static native boolean nUploadAtlas(GraphicBuffer buffer, int bitmap);
+
+    @Override
+    public boolean isCompatible(int ppid) {
+        return ppid == android.os.Process.myPpid();
+    }
+
+    @Override
+    public GraphicBuffer getBuffer() throws RemoteException {
+        return mAtlasReady.get() ? mBuffer : null;
+    }
+
+    @Override
+    public int[] getMap() throws RemoteException {
+        return mAtlasReady.get() ? mAtlasMap : null;
+    }
+
+    /**
+     * Finds the best atlas configuration to pack the list of supplied bitmaps.
+     * This method takes advantage of multi-core systems by spawning a number
+     * of threads equal to the number of available cores.
+     */
+    private static Configuration computeBestConfiguration(
+            ArrayList<Bitmap> bitmaps, int pixelCount) {
+        if (DEBUG_ATLAS) Log.d(LOG_TAG, "Computing best atlas configuration...");
+
+        long begin = System.nanoTime();
+        List<WorkerResult> results = Collections.synchronizedList(new ArrayList<WorkerResult>());
+
+        // Don't bother with an extra thread if there's only one processor
+        int cpuCount = Runtime.getRuntime().availableProcessors();
+        if (cpuCount == 1) {
+            new ComputeWorker(MIN_SIZE, MAX_SIZE, STEP, bitmaps, pixelCount, results, null).run();
+        } else {
+            int start = MIN_SIZE;
+            int end = MAX_SIZE - (cpuCount - 1) * STEP;
+            int step = STEP * cpuCount;
+
+            final CountDownLatch signal = new CountDownLatch(cpuCount);
+
+            for (int i = 0; i < cpuCount; i++, start += STEP, end += STEP) {
+                ComputeWorker worker = new ComputeWorker(start, end, step,
+                        bitmaps, pixelCount, results, signal);
+                new Thread(worker, "Atlas Worker #" + (i + 1)).start();
+            }
+
+            try {
+                signal.await(10, TimeUnit.SECONDS);
+            } catch (InterruptedException e) {
+                Log.w(LOG_TAG, "Could not complete configuration computation");
+                return null;
+            }
+        }
+
+        // Maximize the number of packed bitmaps, minimize the texture size
+        Collections.sort(results, new Comparator<WorkerResult>() {
+            @Override
+            public int compare(WorkerResult r1, WorkerResult r2) {
+                int delta = r2.count - r1.count;
+                if (delta != 0) return delta;
+                return r1.width * r1.height - r2.width * r2.height;
+            }
+        });
+
+        if (DEBUG_ATLAS) {
+            float delay = (System.nanoTime() - begin) / 1000.0f / 1000.0f / 1000.0f;
+            Log.d(LOG_TAG, String.format("Found best atlas configuration in %.2fs", delay));
+        }
+
+        WorkerResult result = results.get(0);
+        return new Configuration(result.type, result.width, result.height, result.count);
+    }
+
+    /**
+     * Returns the path to the file containing the best computed
+     * atlas configuration.
+     */
+    private static File getDataFile() {
+        File systemDirectory = new File(Environment.getDataDirectory(), "system");
+        return new File(systemDirectory, "framework_atlas.config");
+    }
+
+    private static void deleteDataFile() {
+        Log.w(LOG_TAG, "Current configuration inconsistent with assets list");
+        if (!getDataFile().delete()) {
+            Log.w(LOG_TAG, "Could not delete the current configuration");
+        }
+    }
+
+    private File getFrameworkResourcesFile() {
+        return new File(mContext.getApplicationInfo().sourceDir);
+    }
+
+    /**
+     * Returns the best known atlas configuration. This method will either
+     * read the configuration from disk or start a brute-force search
+     * and save the result out to disk.
+     */
+    private Configuration chooseConfiguration(ArrayList<Bitmap> bitmaps, int pixelCount,
+            String versionName) {
+        Configuration config = null;
+
+        final File dataFile = getDataFile();
+        if (dataFile.exists()) {
+            config = readConfiguration(dataFile, versionName);
+        }
+
+        if (config == null) {
+            config = computeBestConfiguration(bitmaps, pixelCount);
+            if (config != null) writeConfiguration(config, dataFile, versionName);
+        }
+
+        return config;
+    }
+
+    /**
+     * Writes the specified atlas configuration to the specified file.
+     */
+    private void writeConfiguration(Configuration config, File file, String versionName) {
+        BufferedWriter writer = null;
+        try {
+            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file)));
+            writer.write(getBuildIdentifier(versionName));
+            writer.newLine();
+            writer.write(config.type.toString());
+            writer.newLine();
+            writer.write(String.valueOf(config.width));
+            writer.newLine();
+            writer.write(String.valueOf(config.height));
+            writer.newLine();
+            writer.write(String.valueOf(config.count));
+            writer.newLine();
+            writer.write(String.valueOf(config.flags));
+            writer.newLine();
+        } catch (FileNotFoundException e) {
+            Log.w(LOG_TAG, "Could not write " + file, e);
+        } catch (IOException e) {
+            Log.w(LOG_TAG, "Could not write " + file, e);
+        } finally {
+            if (writer != null) {
+                try {
+                    writer.close();
+                } catch (IOException e) {
+                    // Ignore
+                }
+            }
+        }
+    }
+
+    /**
+     * Reads an atlas configuration from the specified file. This method
+     * returns null if an error occurs or if the configuration is invalid.
+     */
+    private Configuration readConfiguration(File file, String versionName) {
+        BufferedReader reader = null;
+        Configuration config = null;
+        try {
+            reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
+
+            if (checkBuildIdentifier(reader, versionName)) {
+                Atlas.Type type = Atlas.Type.valueOf(reader.readLine());
+                int width = readInt(reader, MIN_SIZE, MAX_SIZE);
+                int height = readInt(reader, MIN_SIZE, MAX_SIZE);
+                int count = readInt(reader, 0, Integer.MAX_VALUE);
+                int flags = readInt(reader, Integer.MIN_VALUE, Integer.MAX_VALUE);
+
+                config = new Configuration(type, width, height, count, flags);
+            }
+        } catch (IllegalArgumentException e) {
+            Log.w(LOG_TAG, "Invalid parameter value in " + file, e);
+        } catch (FileNotFoundException e) {
+            Log.w(LOG_TAG, "Could not read " + file, e);
+        } catch (IOException e) {
+            Log.w(LOG_TAG, "Could not read " + file, e);
+        } finally {
+            if (reader != null) {
+                try {
+                    reader.close();
+                } catch (IOException e) {
+                    // Ignore
+                }
+            }
+        }
+        return config;
+    }
+
+    private static int readInt(BufferedReader reader, int min, int max) throws IOException {
+        return Math.max(min, Math.min(max, Integer.parseInt(reader.readLine())));
+    }
+
+    /**
+     * Compares the next line in the specified buffered reader to the current
+     * build identifier. Returns whether the two values are equal.
+     *
+     * @see #getBuildIdentifier(String)
+     */
+    private boolean checkBuildIdentifier(BufferedReader reader, String versionName)
+            throws IOException {
+        String deviceBuildId = getBuildIdentifier(versionName);
+        String buildId = reader.readLine();
+        return deviceBuildId.equals(buildId);
+    }
+
+    /**
+     * Returns an identifier for the current build that can be used to detect
+     * likely changes to framework resources. The build identifier is made of
+     * several distinct values:
+     *
+     * build fingerprint/framework version name/file size of framework resources apk
+     *
+     * Only the build fingerprint should be necessary on user builds but
+     * the other values are useful to detect changes on eng builds during
+     * development.
+     *
+     * This identifier does not attempt to be exact: a new identifier does not
+     * necessarily mean the preloaded drawables have changed. It is important
+     * however that whenever the list of preloaded drawables changes, this
+     * identifier changes as well.
+     *
+     * @see #checkBuildIdentifier(java.io.BufferedReader, String)
+     */
+    private String getBuildIdentifier(String versionName) {
+        return SystemProperties.get("ro.build.fingerprint", "") + '/' + versionName + '/' +
+                String.valueOf(getFrameworkResourcesFile().length());
+    }
+
+    /**
+     * Atlas configuration. Specifies the algorithm, dimensions and flags to use.
+     */
+    private static class Configuration {
+        final Atlas.Type type;
+        final int width;
+        final int height;
+        final int count;
+        final int flags;
+
+        Configuration(Atlas.Type type, int width, int height, int count) {
+            this(type, width, height, count, Atlas.FLAG_DEFAULTS);
+        }
+
+        Configuration(Atlas.Type type, int width, int height, int count, int flags) {
+            this.type = type;
+            this.width = width;
+            this.height = height;
+            this.count = count;
+            this.flags = flags;
+        }
+
+        @Override
+        public String toString() {
+            return type.toString() + " (" + width + "x" + height + ") flags=0x" +
+                    Integer.toHexString(flags) + " count=" + count;
+        }
+    }
+
+    /**
+     * Used during the brute-force search to gather information about each
+     * variant of the packing algorithm.
+     */
+    private static class WorkerResult {
+        Atlas.Type type;
+        int width;
+        int height;
+        int count;
+
+        WorkerResult(Atlas.Type type, int width, int height, int count) {
+            this.type = type;
+            this.width = width;
+            this.height = height;
+            this.count = count;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("%s %dx%d", type.toString(), width, height);
+        }
+    }
+
+    /**
+     * A compute worker will try a finite number of variations of the packing
+     * algorithms and save the results in a supplied list.
+     */
+    private static class ComputeWorker implements Runnable {
+        private final int mStart;
+        private final int mEnd;
+        private final int mStep;
+        private final List<Bitmap> mBitmaps;
+        private final List<WorkerResult> mResults;
+        private final CountDownLatch mSignal;
+        private final int mThreshold;
+
+        /**
+         * Creates a new compute worker to brute-force through a range of
+         * packing algorithms variants.
+         *
+         * @param start The minimum texture width to try
+         * @param end The maximum texture width to try
+         * @param step The number of pixels to increment the texture width by at each step
+         * @param bitmaps The list of bitmaps to pack in the atlas
+         * @param pixelCount The total number of pixels occupied by the list of bitmaps
+         * @param results The list of results in which to save the brute-force search results
+         * @param signal Latch to decrement when this worker is done, may be null
+         */
+        ComputeWorker(int start, int end, int step, List<Bitmap> bitmaps, int pixelCount,
+                List<WorkerResult> results, CountDownLatch signal) {
+            mStart = start;
+            mEnd = end;
+            mStep = step;
+            mBitmaps = bitmaps;
+            mResults = results;
+            mSignal = signal;
+
+            // Minimum number of pixels we want to be able to pack
+            int threshold = (int) (pixelCount * PACKING_THRESHOLD);
+            // Make sure we can find at least one configuration
+            while (threshold > MAX_SIZE * MAX_SIZE) {
+                threshold >>= 1;
+            }
+            mThreshold = threshold;
+        }
+
+        @Override
+        public void run() {
+            if (DEBUG_ATLAS) Log.d(LOG_TAG, "Running " + Thread.currentThread().getName());
+
+            Atlas.Entry entry = new Atlas.Entry();
+            for (Atlas.Type type : Atlas.Type.values()) {
+                for (int width = mStart; width < mEnd; width += mStep) {
+                    for (int height = MIN_SIZE; height < MAX_SIZE; height += STEP) {
+                        // If the atlas is not big enough, skip it
+                        if (width * height <= mThreshold) continue;
+
+                        final int count = packBitmaps(type, width, height, entry);
+                        if (count > 0) {
+                            mResults.add(new WorkerResult(type, width, height, count));
+                            // If we were able to pack everything let's stop here
+                            // Increasing the height further won't make things better
+                            if (count == mBitmaps.size()) {
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+
+            if (mSignal != null) {
+                mSignal.countDown();
+            }
+        }
+
+        private int packBitmaps(Atlas.Type type, int width, int height, Atlas.Entry entry) {
+            int total = 0;
+            Atlas atlas = new Atlas(type, width, height);
+
+            final int count = mBitmaps.size();
+            for (int i = 0; i < count; i++) {
+                final Bitmap bitmap = mBitmaps.get(i);
+                if (atlas.pack(bitmap.getWidth(), bitmap.getHeight(), entry) != null) {
+                    total++;
+                }
+            }
+
+            return total;
+        }
+    }
+}
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index a537e99..c4eb7a4 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -2877,7 +2877,7 @@
             // Save associated .obb content if it exists and we did save the apk
             // check for .obb and save those too
             final UserEnvironment userEnv = new UserEnvironment(UserHandle.USER_OWNER);
-            final File obbDir = userEnv.getExternalStorageAppObbDirectory(pkg.packageName);
+            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();
@@ -5358,47 +5358,53 @@
     }
 
     // Enable/disable the backup service
+    @Override
     public void setBackupEnabled(boolean enable) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "setBackupEnabled");
 
         Slog.i(TAG, "Backup enabled => " + enable);
 
-        boolean wasEnabled = mEnabled;
-        synchronized (this) {
-            Settings.Secure.putInt(mContext.getContentResolver(),
-                    Settings.Secure.BACKUP_ENABLED, enable ? 1 : 0);
-            mEnabled = enable;
-        }
+        long oldId = Binder.clearCallingIdentity();
+        try {
+            boolean wasEnabled = mEnabled;
+            synchronized (this) {
+                Settings.Secure.putInt(mContext.getContentResolver(),
+                        Settings.Secure.BACKUP_ENABLED, enable ? 1 : 0);
+                mEnabled = enable;
+            }
 
-        synchronized (mQueueLock) {
-            if (enable && !wasEnabled && mProvisioned) {
-                // if we've just been enabled, start scheduling backup passes
-                startBackupAlarmsLocked(BACKUP_INTERVAL);
-            } else if (!enable) {
-                // No longer enabled, so stop running backups
-                if (DEBUG) Slog.i(TAG, "Opting out of backup");
+            synchronized (mQueueLock) {
+                if (enable && !wasEnabled && mProvisioned) {
+                    // if we've just been enabled, start scheduling backup passes
+                    startBackupAlarmsLocked(BACKUP_INTERVAL);
+                } else if (!enable) {
+                    // No longer enabled, so stop running backups
+                    if (DEBUG) Slog.i(TAG, "Opting out of backup");
 
-                mAlarmManager.cancel(mRunBackupIntent);
+                    mAlarmManager.cancel(mRunBackupIntent);
 
-                // 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.
-                    HashSet<String> allTransports;
-                    synchronized (mTransports) {
-                        allTransports = new HashSet<String>(mTransports.keySet());
+                    // 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.
+                        HashSet<String> allTransports;
+                        synchronized (mTransports) {
+                            allTransports = new HashSet<String>(mTransports.keySet());
+                        }
+                        // 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);
                     }
-                    // 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);
         }
     }
 
diff --git a/services/java/com/android/server/BatteryService.java b/services/java/com/android/server/BatteryService.java
index 1f2947d..5f3f894 100644
--- a/services/java/com/android/server/BatteryService.java
+++ b/services/java/com/android/server/BatteryService.java
@@ -16,6 +16,7 @@
 
 package com.android.server;
 
+import android.os.BatteryStats;
 import com.android.internal.app.IBatteryStats;
 import com.android.server.am.BatteryStatsService;
 
@@ -25,9 +26,12 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.os.BatteryManager;
+import android.os.BatteryProperties;
 import android.os.Binder;
 import android.os.FileUtils;
 import android.os.Handler;
+import android.os.IBatteryPropertiesListener;
+import android.os.IBatteryPropertiesRegistrar;
 import android.os.IBinder;
 import android.os.DropBoxManager;
 import android.os.RemoteException;
@@ -88,8 +92,7 @@
     private int mCriticalBatteryLevel;
 
     private static final int DUMP_MAX_LENGTH = 24 * 1024;
-    private static final String[] DUMPSYS_ARGS = new String[] { "--checkin", "-u" };
-    private static final String BATTERY_STATS_SERVICE_NAME = "batteryinfo";
+    private static final String[] DUMPSYS_ARGS = new String[] { "--checkin", "--unplugged" };
 
     private static final String DUMPSYS_DATA_PATH = "/data/system/";
 
@@ -102,20 +105,8 @@
 
     private final Object mLock = new Object();
 
-    /* Begin native fields: All of these fields are set by native code. */
-    private boolean mAcOnline;
-    private boolean mUsbOnline;
-    private boolean mWirelessOnline;
-    private int mBatteryStatus;
-    private int mBatteryHealth;
-    private boolean mBatteryPresent;
-    private int mBatteryLevel;
-    private int mBatteryVoltage;
-    private int mBatteryTemperature;
-    private String mBatteryTechnology;
+    private BatteryProperties mBatteryProps;
     private boolean mBatteryLevelCritical;
-    /* End native fields. */
-
     private int mLastBatteryStatus;
     private int mLastBatteryHealth;
     private boolean mLastBatteryPresent;
@@ -143,7 +134,8 @@
 
     private boolean mSentLowBatteryBroadcast = false;
 
-    private native void native_update();
+    private BatteryListener mBatteryPropertiesListener;
+    private IBatteryPropertiesRegistrar mBatteryPropertiesRegistrar;
 
     public BatteryService(Context context, LightsService lights) {
         mContext = context;
@@ -160,17 +152,21 @@
         mShutdownBatteryTemperature = mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_shutdownBatteryTemperature);
 
-        mPowerSupplyObserver.startObserving("SUBSYSTEM=power_supply");
-
         // watch for invalid charger messages if the invalid_charger switch exists
         if (new File("/sys/devices/virtual/switch/invalid_charger/state").exists()) {
             mInvalidChargerObserver.startObserving(
                     "DEVPATH=/devices/virtual/switch/invalid_charger");
         }
 
-        // set initial status
-        synchronized (mLock) {
-            updateLocked();
+        mBatteryPropertiesListener = new BatteryListener();
+
+        IBinder b = ServiceManager.getService("batterypropreg");
+        mBatteryPropertiesRegistrar = IBatteryPropertiesRegistrar.Stub.asInterface(b);
+
+        try {
+            mBatteryPropertiesRegistrar.registerListener(mBatteryPropertiesListener);
+        } catch (RemoteException e) {
+            // Should never happen.
         }
     }
 
@@ -194,16 +190,16 @@
     private boolean isPoweredLocked(int plugTypeSet) {
         // assume we are powered if battery state is unknown so
         // the "stay on while plugged in" option will work.
-        if (mBatteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN) {
+        if (mBatteryProps.batteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN) {
             return true;
         }
-        if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_AC) != 0 && mAcOnline) {
+        if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_AC) != 0 && mBatteryProps.chargerAcOnline) {
             return true;
         }
-        if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_USB) != 0 && mUsbOnline) {
+        if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_USB) != 0 && mBatteryProps.chargerUsbOnline) {
             return true;
         }
-        if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0 && mWirelessOnline) {
+        if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0 && mBatteryProps.chargerWirelessOnline) {
             return true;
         }
         return false;
@@ -223,7 +219,7 @@
      */
     public int getBatteryLevel() {
         synchronized (mLock) {
-            return mBatteryLevel;
+            return mBatteryProps.batteryLevel;
         }
     }
 
@@ -232,7 +228,7 @@
      */
     public boolean isBatteryLow() {
         synchronized (mLock) {
-            return mBatteryPresent && mBatteryLevel <= mLowBatteryWarningLevel;
+            return mBatteryProps.batteryPresent && mBatteryProps.batteryLevel <= mLowBatteryWarningLevel;
         }
     }
 
@@ -248,7 +244,7 @@
     private void shutdownIfNoPowerLocked() {
         // shut down gracefully if our battery is critically low and we are not powered.
         // wait until the system has booted before attempting to display the shutdown dialog.
-        if (mBatteryLevel == 0 && !isPoweredLocked(BatteryManager.BATTERY_PLUGGED_ANY)) {
+        if (mBatteryProps.batteryLevel == 0 && !isPoweredLocked(BatteryManager.BATTERY_PLUGGED_ANY)) {
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
@@ -267,7 +263,7 @@
         // shut down gracefully if temperature is too high (> 68.0C by default)
         // wait until the system has booted before attempting to display the
         // shutdown dialog.
-        if (mBatteryTemperature > mShutdownBatteryTemperature) {
+        if (mBatteryProps.batteryTemperature > mShutdownBatteryTemperature) {
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
@@ -282,13 +278,13 @@
         }
     }
 
-    private void updateLocked() {
-        if (!mUpdatesStopped) {
-            // Update the values of mAcOnline, et. all.
-            native_update();
-
-            // Process the new values.
-            processValuesLocked();
+    private void update(BatteryProperties props) {
+        synchronized (mLock) {
+            if (!mUpdatesStopped) {
+                mBatteryProps = props;
+                // Process the new values.
+                processValuesLocked();
+            }
         }
     }
 
@@ -296,12 +292,12 @@
         boolean logOutlier = false;
         long dischargeDuration = 0;
 
-        mBatteryLevelCritical = (mBatteryLevel <= mCriticalBatteryLevel);
-        if (mAcOnline) {
+        mBatteryLevelCritical = (mBatteryProps.batteryLevel <= mCriticalBatteryLevel);
+        if (mBatteryProps.chargerAcOnline) {
             mPlugType = BatteryManager.BATTERY_PLUGGED_AC;
-        } else if (mUsbOnline) {
+        } else if (mBatteryProps.chargerUsbOnline) {
             mPlugType = BatteryManager.BATTERY_PLUGGED_USB;
-        } else if (mWirelessOnline) {
+        } else if (mBatteryProps.chargerWirelessOnline) {
             mPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS;
         } else {
             mPlugType = BATTERY_PLUGGED_NONE;
@@ -309,25 +305,27 @@
 
         if (DEBUG) {
             Slog.d(TAG, "Processing new values: "
-                    + "mAcOnline=" + mAcOnline
-                    + ", mUsbOnline=" + mUsbOnline
-                    + ", mWirelessOnline=" + mWirelessOnline
-                    + ", mBatteryStatus=" + mBatteryStatus
-                    + ", mBatteryHealth=" + mBatteryHealth
-                    + ", mBatteryPresent=" + mBatteryPresent
-                    + ", mBatteryLevel=" + mBatteryLevel
-                    + ", mBatteryTechnology=" + mBatteryTechnology
-                    + ", mBatteryVoltage=" + mBatteryVoltage
-                    + ", mBatteryTemperature=" + mBatteryTemperature
+                    + "chargerAcOnline=" + mBatteryProps.chargerAcOnline
+                    + ", chargerUsbOnline=" + mBatteryProps.chargerUsbOnline
+                    + ", chargerWirelessOnline=" + mBatteryProps.chargerWirelessOnline
+                    + ", batteryStatus=" + mBatteryProps.batteryStatus
+                    + ", batteryHealth=" + mBatteryProps.batteryHealth
+                    + ", batteryPresent=" + mBatteryProps.batteryPresent
+                    + ", batteryLevel=" + mBatteryProps.batteryLevel
+                    + ", batteryTechnology=" + mBatteryProps.batteryTechnology
+                    + ", batteryVoltage=" + mBatteryProps.batteryVoltage
+                    + ", batteryCurrentNow=" + mBatteryProps.batteryCurrentNow
+                    + ", batteryChargeCounter=" + mBatteryProps.batteryChargeCounter
+                    + ", batteryTemperature=" + mBatteryProps.batteryTemperature
                     + ", mBatteryLevelCritical=" + mBatteryLevelCritical
                     + ", mPlugType=" + mPlugType);
         }
 
         // Let the battery stats keep track of the current level.
         try {
-            mBatteryStats.setBatteryState(mBatteryStatus, mBatteryHealth,
-                    mPlugType, mBatteryLevel, mBatteryTemperature,
-                    mBatteryVoltage);
+            mBatteryStats.setBatteryState(mBatteryProps.batteryStatus, mBatteryProps.batteryHealth,
+                    mPlugType, mBatteryProps.batteryLevel, mBatteryProps.batteryTemperature,
+                    mBatteryProps.batteryVoltage);
         } catch (RemoteException e) {
             // Should never happen.
         }
@@ -335,13 +333,13 @@
         shutdownIfNoPowerLocked();
         shutdownIfOverTempLocked();
 
-        if (mBatteryStatus != mLastBatteryStatus ||
-                mBatteryHealth != mLastBatteryHealth ||
-                mBatteryPresent != mLastBatteryPresent ||
-                mBatteryLevel != mLastBatteryLevel ||
+        if (mBatteryProps.batteryStatus != mLastBatteryStatus ||
+                mBatteryProps.batteryHealth != mLastBatteryHealth ||
+                mBatteryProps.batteryPresent != mLastBatteryPresent ||
+                mBatteryProps.batteryLevel != mLastBatteryLevel ||
                 mPlugType != mLastPlugType ||
-                mBatteryVoltage != mLastBatteryVoltage ||
-                mBatteryTemperature != mLastBatteryTemperature ||
+                mBatteryProps.batteryVoltage != mLastBatteryVoltage ||
+                mBatteryProps.batteryTemperature != mLastBatteryTemperature ||
                 mInvalidCharger != mLastInvalidCharger) {
 
             if (mPlugType != mLastPlugType) {
@@ -350,33 +348,33 @@
 
                     // There's no value in this data unless we've discharged at least once and the
                     // battery level has changed; so don't log until it does.
-                    if (mDischargeStartTime != 0 && mDischargeStartLevel != mBatteryLevel) {
+                    if (mDischargeStartTime != 0 && mDischargeStartLevel != mBatteryProps.batteryLevel) {
                         dischargeDuration = SystemClock.elapsedRealtime() - mDischargeStartTime;
                         logOutlier = true;
                         EventLog.writeEvent(EventLogTags.BATTERY_DISCHARGE, dischargeDuration,
-                                mDischargeStartLevel, mBatteryLevel);
+                                mDischargeStartLevel, mBatteryProps.batteryLevel);
                         // make sure we see a discharge event before logging again
                         mDischargeStartTime = 0;
                     }
                 } else if (mPlugType == BATTERY_PLUGGED_NONE) {
                     // charging -> discharging or we just powered up
                     mDischargeStartTime = SystemClock.elapsedRealtime();
-                    mDischargeStartLevel = mBatteryLevel;
+                    mDischargeStartLevel = mBatteryProps.batteryLevel;
                 }
             }
-            if (mBatteryStatus != mLastBatteryStatus ||
-                    mBatteryHealth != mLastBatteryHealth ||
-                    mBatteryPresent != mLastBatteryPresent ||
+            if (mBatteryProps.batteryStatus != mLastBatteryStatus ||
+                    mBatteryProps.batteryHealth != mLastBatteryHealth ||
+                    mBatteryProps.batteryPresent != mLastBatteryPresent ||
                     mPlugType != mLastPlugType) {
                 EventLog.writeEvent(EventLogTags.BATTERY_STATUS,
-                        mBatteryStatus, mBatteryHealth, mBatteryPresent ? 1 : 0,
-                        mPlugType, mBatteryTechnology);
+                        mBatteryProps.batteryStatus, mBatteryProps.batteryHealth, mBatteryProps.batteryPresent ? 1 : 0,
+                        mPlugType, mBatteryProps.batteryTechnology);
             }
-            if (mBatteryLevel != mLastBatteryLevel ||
-                    mBatteryVoltage != mLastBatteryVoltage ||
-                    mBatteryTemperature != mLastBatteryTemperature) {
+            if (mBatteryProps.batteryLevel != mLastBatteryLevel) {
+                // Don't do this just from voltage or temperature changes, that is
+                // too noisy.
                 EventLog.writeEvent(EventLogTags.BATTERY_LEVEL,
-                        mBatteryLevel, mBatteryVoltage, mBatteryTemperature);
+                        mBatteryProps.batteryLevel, mBatteryProps.batteryVoltage, mBatteryProps.batteryTemperature);
             }
             if (mBatteryLevelCritical && !mLastBatteryLevelCritical &&
                     mPlugType == BATTERY_PLUGGED_NONE) {
@@ -396,8 +394,8 @@
              *   (becomes <= mLowBatteryWarningLevel).
              */
             final boolean sendBatteryLow = !plugged
-                    && mBatteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN
-                    && mBatteryLevel <= mLowBatteryWarningLevel
+                    && mBatteryProps.batteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN
+                    && mBatteryProps.batteryLevel <= mLowBatteryWarningLevel
                     && (oldPlugged || mLastBatteryLevel > mLowBatteryWarningLevel);
 
             sendIntentLocked();
@@ -456,13 +454,13 @@
                 logOutlierLocked(dischargeDuration);
             }
 
-            mLastBatteryStatus = mBatteryStatus;
-            mLastBatteryHealth = mBatteryHealth;
-            mLastBatteryPresent = mBatteryPresent;
-            mLastBatteryLevel = mBatteryLevel;
+            mLastBatteryStatus = mBatteryProps.batteryStatus;
+            mLastBatteryHealth = mBatteryProps.batteryHealth;
+            mLastBatteryPresent = mBatteryProps.batteryPresent;
+            mLastBatteryLevel = mBatteryProps.batteryLevel;
             mLastPlugType = mPlugType;
-            mLastBatteryVoltage = mBatteryVoltage;
-            mLastBatteryTemperature = mBatteryTemperature;
+            mLastBatteryVoltage = mBatteryProps.batteryVoltage;
+            mLastBatteryTemperature = mBatteryProps.batteryTemperature;
             mLastBatteryLevelCritical = mBatteryLevelCritical;
             mLastInvalidCharger = mInvalidCharger;
         }
@@ -474,29 +472,29 @@
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
                 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
 
-        int icon = getIconLocked(mBatteryLevel);
+        int icon = getIconLocked(mBatteryProps.batteryLevel);
 
-        intent.putExtra(BatteryManager.EXTRA_STATUS, mBatteryStatus);
-        intent.putExtra(BatteryManager.EXTRA_HEALTH, mBatteryHealth);
-        intent.putExtra(BatteryManager.EXTRA_PRESENT, mBatteryPresent);
-        intent.putExtra(BatteryManager.EXTRA_LEVEL, mBatteryLevel);
+        intent.putExtra(BatteryManager.EXTRA_STATUS, mBatteryProps.batteryStatus);
+        intent.putExtra(BatteryManager.EXTRA_HEALTH, mBatteryProps.batteryHealth);
+        intent.putExtra(BatteryManager.EXTRA_PRESENT, mBatteryProps.batteryPresent);
+        intent.putExtra(BatteryManager.EXTRA_LEVEL, mBatteryProps.batteryLevel);
         intent.putExtra(BatteryManager.EXTRA_SCALE, BATTERY_SCALE);
         intent.putExtra(BatteryManager.EXTRA_ICON_SMALL, icon);
         intent.putExtra(BatteryManager.EXTRA_PLUGGED, mPlugType);
-        intent.putExtra(BatteryManager.EXTRA_VOLTAGE, mBatteryVoltage);
-        intent.putExtra(BatteryManager.EXTRA_TEMPERATURE, mBatteryTemperature);
-        intent.putExtra(BatteryManager.EXTRA_TECHNOLOGY, mBatteryTechnology);
+        intent.putExtra(BatteryManager.EXTRA_VOLTAGE, mBatteryProps.batteryVoltage);
+        intent.putExtra(BatteryManager.EXTRA_TEMPERATURE, mBatteryProps.batteryTemperature);
+        intent.putExtra(BatteryManager.EXTRA_TECHNOLOGY, mBatteryProps.batteryTechnology);
         intent.putExtra(BatteryManager.EXTRA_INVALID_CHARGER, mInvalidCharger);
 
         if (DEBUG) {
-            Slog.d(TAG, "Sending ACTION_BATTERY_CHANGED.  level:" + mBatteryLevel +
-                    ", scale:" + BATTERY_SCALE + ", status:" + mBatteryStatus +
-                    ", health:" + mBatteryHealth +  ", present:" + mBatteryPresent +
-                    ", voltage: " + mBatteryVoltage +
-                    ", temperature: " + mBatteryTemperature +
-                    ", technology: " + mBatteryTechnology +
-                    ", AC powered:" + mAcOnline + ", USB powered:" + mUsbOnline +
-                    ", Wireless powered:" + mWirelessOnline +
+            Slog.d(TAG, "Sending ACTION_BATTERY_CHANGED.  level:" + mBatteryProps.batteryLevel +
+                    ", scale:" + BATTERY_SCALE + ", status:" + mBatteryProps.batteryStatus +
+                    ", health:" + mBatteryProps.batteryHealth +  ", present:" + mBatteryProps.batteryPresent +
+                    ", voltage: " + mBatteryProps.batteryVoltage +
+                    ", temperature: " + mBatteryProps.batteryTemperature +
+                    ", technology: " + mBatteryProps.batteryTechnology +
+                    ", AC powered:" + mBatteryProps.chargerAcOnline + ", USB powered:" + mBatteryProps.chargerUsbOnline +
+                    ", Wireless powered:" + mBatteryProps.chargerWirelessOnline +
                     ", icon:" + icon  + ", invalid charger:" + mInvalidCharger);
         }
 
@@ -509,7 +507,7 @@
     }
 
     private void logBatteryStatsLocked() {
-        IBinder batteryInfoService = ServiceManager.getService(BATTERY_STATS_SERVICE_NAME);
+        IBinder batteryInfoService = ServiceManager.getService(BatteryStats.SERVICE_NAME);
         if (batteryInfoService == null) return;
 
         DropBoxManager db = (DropBoxManager) mContext.getSystemService(Context.DROPBOX_SERVICE);
@@ -519,7 +517,7 @@
         FileOutputStream dumpStream = null;
         try {
             // dump the service to a file
-            dumpFile = new File(DUMPSYS_DATA_PATH + BATTERY_STATS_SERVICE_NAME + ".dump");
+            dumpFile = new File(DUMPSYS_DATA_PATH + BatteryStats.SERVICE_NAME + ".dump");
             dumpStream = new FileOutputStream(dumpFile);
             batteryInfoService.dump(dumpStream.getFD(), DUMPSYS_ARGS);
             FileUtils.sync(dumpStream);
@@ -558,14 +556,14 @@
                 long durationThreshold = Long.parseLong(durationThresholdString);
                 int dischargeThreshold = Integer.parseInt(dischargeThresholdString);
                 if (duration <= durationThreshold &&
-                        mDischargeStartLevel - mBatteryLevel >= dischargeThreshold) {
+                        mDischargeStartLevel - mBatteryProps.batteryLevel >= dischargeThreshold) {
                     // If the discharge cycle is bad enough we want to know about it.
                     logBatteryStatsLocked();
                 }
                 if (DEBUG) Slog.v(TAG, "duration threshold: " + durationThreshold +
                         " discharge threshold: " + dischargeThreshold);
                 if (DEBUG) Slog.v(TAG, "duration: " + duration + " discharge: " +
-                        (mDischargeStartLevel - mBatteryLevel));
+                        (mDischargeStartLevel - mBatteryProps.batteryLevel));
             } catch (NumberFormatException e) {
                 Slog.e(TAG, "Invalid DischargeThresholds GService string: " +
                         durationThresholdString + " or " + dischargeThresholdString);
@@ -575,14 +573,14 @@
     }
 
     private int getIconLocked(int level) {
-        if (mBatteryStatus == BatteryManager.BATTERY_STATUS_CHARGING) {
+        if (mBatteryProps.batteryStatus == BatteryManager.BATTERY_STATUS_CHARGING) {
             return com.android.internal.R.drawable.stat_sys_battery_charge;
-        } else if (mBatteryStatus == BatteryManager.BATTERY_STATUS_DISCHARGING) {
+        } else if (mBatteryProps.batteryStatus == BatteryManager.BATTERY_STATUS_DISCHARGING) {
             return com.android.internal.R.drawable.stat_sys_battery;
-        } else if (mBatteryStatus == BatteryManager.BATTERY_STATUS_NOT_CHARGING
-                || mBatteryStatus == BatteryManager.BATTERY_STATUS_FULL) {
+        } else if (mBatteryProps.batteryStatus == BatteryManager.BATTERY_STATUS_NOT_CHARGING
+                || mBatteryProps.batteryStatus == BatteryManager.BATTERY_STATUS_FULL) {
             if (isPoweredLocked(BatteryManager.BATTERY_PLUGGED_ANY)
-                    && mBatteryLevel >= 100) {
+                    && mBatteryProps.batteryLevel >= 100) {
                 return com.android.internal.R.drawable.stat_sys_battery_charge;
             } else {
                 return com.android.internal.R.drawable.stat_sys_battery;
@@ -609,32 +607,41 @@
                 if (mUpdatesStopped) {
                     pw.println("  (UPDATES STOPPED -- use 'reset' to restart)");
                 }
-                pw.println("  AC powered: " + mAcOnline);
-                pw.println("  USB powered: " + mUsbOnline);
-                pw.println("  Wireless powered: " + mWirelessOnline);
-                pw.println("  status: " + mBatteryStatus);
-                pw.println("  health: " + mBatteryHealth);
-                pw.println("  present: " + mBatteryPresent);
-                pw.println("  level: " + mBatteryLevel);
+                pw.println("  AC powered: " + mBatteryProps.chargerAcOnline);
+                pw.println("  USB powered: " + mBatteryProps.chargerUsbOnline);
+                pw.println("  Wireless powered: " + mBatteryProps.chargerWirelessOnline);
+                pw.println("  status: " + mBatteryProps.batteryStatus);
+                pw.println("  health: " + mBatteryProps.batteryHealth);
+                pw.println("  present: " + mBatteryProps.batteryPresent);
+                pw.println("  level: " + mBatteryProps.batteryLevel);
                 pw.println("  scale: " + BATTERY_SCALE);
-                pw.println("  voltage:" + mBatteryVoltage);
-                pw.println("  temperature: " + mBatteryTemperature);
-                pw.println("  technology: " + mBatteryTechnology);
+                pw.println("  voltage: " + mBatteryProps.batteryVoltage);
+
+                if (mBatteryProps.batteryCurrentNow != Integer.MIN_VALUE) {
+                    pw.println("  current now: " + mBatteryProps.batteryCurrentNow);
+                }
+
+                if (mBatteryProps.batteryChargeCounter != Integer.MIN_VALUE) {
+                    pw.println("  charge counter: " + mBatteryProps.batteryChargeCounter);
+                }
+
+                pw.println("  temperature: " + mBatteryProps.batteryTemperature);
+                pw.println("  technology: " + mBatteryProps.batteryTechnology);
             } else if (args.length == 3 && "set".equals(args[0])) {
                 String key = args[1];
                 String value = args[2];
                 try {
                     boolean update = true;
                     if ("ac".equals(key)) {
-                        mAcOnline = Integer.parseInt(value) != 0;
+                        mBatteryProps.chargerAcOnline = Integer.parseInt(value) != 0;
                     } else if ("usb".equals(key)) {
-                        mUsbOnline = Integer.parseInt(value) != 0;
+                        mBatteryProps.chargerUsbOnline = Integer.parseInt(value) != 0;
                     } else if ("wireless".equals(key)) {
-                        mWirelessOnline = Integer.parseInt(value) != 0;
+                        mBatteryProps.chargerWirelessOnline = Integer.parseInt(value) != 0;
                     } else if ("status".equals(key)) {
-                        mBatteryStatus = Integer.parseInt(value);
+                        mBatteryProps.batteryStatus = Integer.parseInt(value);
                     } else if ("level".equals(key)) {
-                        mBatteryLevel = Integer.parseInt(value);
+                        mBatteryProps.batteryLevel = Integer.parseInt(value);
                     } else if ("invalid".equals(key)) {
                         mInvalidCharger = Integer.parseInt(value);
                     } else {
@@ -642,15 +649,24 @@
                         update = false;
                     }
                     if (update) {
-                        mUpdatesStopped = true;
-                        processValuesLocked();
+                        long ident = Binder.clearCallingIdentity();
+                        try {
+                            mUpdatesStopped = true;
+                            processValuesLocked();
+                        } finally {
+                            Binder.restoreCallingIdentity(ident);
+                        }
                     }
                 } catch (NumberFormatException ex) {
                     pw.println("Bad value: " + value);
                 }
             } else if (args.length == 1 && "reset".equals(args[0])) {
-                mUpdatesStopped = false;
-                updateLocked();
+                long ident = Binder.clearCallingIdentity();
+                try {
+                    mUpdatesStopped = false;
+                } finally {
+                    Binder.restoreCallingIdentity(ident);
+                }
             } else {
                 pw.println("Dump current battery state, or:");
                 pw.println("  set ac|usb|wireless|status|level|invalid <value>");
@@ -659,15 +675,6 @@
         }
     }
 
-    private final UEventObserver mPowerSupplyObserver = new UEventObserver() {
-        @Override
-        public void onUEvent(UEventObserver.UEvent event) {
-            synchronized (mLock) {
-                updateLocked();
-            }
-        }
-    };
-
     private final UEventObserver mInvalidChargerObserver = new UEventObserver() {
         @Override
         public void onUEvent(UEventObserver.UEvent event) {
@@ -675,7 +682,6 @@
             synchronized (mLock) {
                 if (mInvalidCharger != invalidCharger) {
                     mInvalidCharger = invalidCharger;
-                    updateLocked();
                 }
             }
         }
@@ -709,8 +715,8 @@
          * Synchronize on BatteryService.
          */
         public void updateLightsLocked() {
-            final int level = mBatteryLevel;
-            final int status = mBatteryStatus;
+            final int level = mBatteryProps.batteryLevel;
+            final int status = mBatteryProps.batteryStatus;
             if (level < mLowBatteryWarningLevel) {
                 if (status == BatteryManager.BATTERY_STATUS_CHARGING) {
                     // Solid red when battery is charging
@@ -735,4 +741,10 @@
             }
         }
     }
+
+    private final class BatteryListener extends IBatteryPropertiesListener.Stub {
+        public void batteryPropertiesChanged(BatteryProperties props) {
+            BatteryService.this.update(props);
+       }
+    }
 }
diff --git a/services/java/com/android/server/BluetoothManagerService.java b/services/java/com/android/server/BluetoothManagerService.java
index bea2cca..d2d5280 100644
--- a/services/java/com/android/server/BluetoothManagerService.java
+++ b/services/java/com/android/server/BluetoothManagerService.java
@@ -34,7 +34,6 @@
 import android.content.pm.PackageManager;
 import android.os.Binder;
 import android.os.Handler;
-import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
@@ -120,7 +119,6 @@
     // used inside handler thread
     private boolean mEnable;
     private int mState;
-    private HandlerThread mThread;
     private final BluetoothHandler mHandler;
     private int mErrorRecoveryRetryCounter;
 
@@ -194,9 +192,7 @@
     };
 
     BluetoothManagerService(Context context) {
-        mThread = new HandlerThread("BluetoothManager");
-        mThread.start();
-        mHandler = new BluetoothHandler(mThread.getLooper());
+        mHandler = new BluetoothHandler(IoThread.get().getLooper());
 
         mContext = context;
         mBluetooth = null;
@@ -647,10 +643,9 @@
                             Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
                             mHandler.sendMessageDelayed(timeoutMsg,TIMEOUT_BIND_MS);
                             Intent i = new Intent(IBluetooth.class.getName());
-                            if (!mContext.bindServiceAsUser(i, mConnection,
-                                  Context.BIND_AUTO_CREATE, UserHandle.CURRENT)) {
+                            if (!doBind(i, mConnection,
+                                    Context.BIND_AUTO_CREATE, UserHandle.CURRENT)) {
                                 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
-                                Log.e(TAG, "fail to bind to: " + IBluetooth.class.getName());
                             } else {
                                 mBinding = true;
                             }
@@ -792,11 +787,21 @@
                         } // else must be SERVICE_IBLUETOOTH
 
                         //Remove timeout
-                            mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
+                        mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
 
                         mBinding = false;
                         mBluetooth = IBluetooth.Stub.asInterface(service);
 
+                        try {
+                            boolean enableHciSnoopLog = (Settings.Secure.getInt(mContentResolver,
+                                Settings.Secure.BLUETOOTH_HCI_LOG, 0) == 1);
+                            if (!mBluetooth.configHciSnoopLog(enableHciSnoopLog)) {
+                                Log.e(TAG,"IBluetooth.configHciSnoopLog return false");
+                            }
+                        } catch (RemoteException e) {
+                            Log.e(TAG,"Unable to call configHciSnoopLog", e);
+                        }
+
                         if (mConnection.isGetNameAddressOnly()) {
                             //Request GET NAME AND ADDRESS
                             Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
@@ -1022,10 +1027,8 @@
                 mHandler.sendMessageDelayed(timeoutMsg,TIMEOUT_BIND_MS);
                 mConnection.setGetNameAddressOnly(false);
                 Intent i = new Intent(IBluetooth.class.getName());
-                if (!mContext.bindServiceAsUser(i, mConnection,Context.BIND_AUTO_CREATE,
-                                          UserHandle.CURRENT)) {
+                if (!doBind(i, mConnection,Context.BIND_AUTO_CREATE, UserHandle.CURRENT)) {
                     mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
-                    Log.e(TAG, "Fail to bind to: " + IBluetooth.class.getName());
                 } else {
                     mBinding = true;
                 }
@@ -1064,6 +1067,16 @@
         }
     }
 
+    boolean doBind(Intent intent, ServiceConnection conn, int flags, UserHandle user) {
+        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+        intent.setComponent(comp);
+        if (comp == null || !mContext.bindServiceAsUser(intent, conn, flags, user)) {
+            Log.e(TAG, "Fail to bind to: " + intent);
+            return false;
+        }
+        return true;
+    }
+
     private void handleDisable() {
         synchronized(mConnection) {
             // don't need to disable if GetNameAddressOnly is set,
@@ -1116,10 +1129,7 @@
                     if (mContext.getPackageManager().hasSystemFeature(
                                                      PackageManager.FEATURE_BLUETOOTH_LE)) {
                         Intent i = new Intent(IBluetoothGatt.class.getName());
-                        if (!mContext.bindServiceAsUser(i, mConnection, Context.BIND_AUTO_CREATE,
-                                                        UserHandle.CURRENT)) {
-                            Log.e(TAG, "Fail to bind to: " + IBluetoothGatt.class.getName());
-                        }
+                        doBind(i, mConnection, Context.BIND_AUTO_CREATE, UserHandle.CURRENT);
                     }
                 } else {
                     //If Bluetooth is off, send service down event to proxy objects, and unbind
diff --git a/services/java/com/android/server/CommonTimeManagementService.java b/services/java/com/android/server/CommonTimeManagementService.java
index c316733..710fb9d 100644
--- a/services/java/com/android/server/CommonTimeManagementService.java
+++ b/services/java/com/android/server/CommonTimeManagementService.java
@@ -40,6 +40,8 @@
 import android.os.SystemProperties;
 import android.util.Log;
 
+import com.android.server.net.BaseNetworkObserver;
+
 /**
  * @hide
  * <p>CommonTimeManagementService manages the configuration of the native Common Time service,
@@ -104,9 +106,7 @@
     /*
      * Callback handler implementations.
      */
-    private INetworkManagementEventObserver mIfaceObserver =
-        new INetworkManagementEventObserver.Stub() {
-
+    private INetworkManagementEventObserver mIfaceObserver = new BaseNetworkObserver() {
         public void interfaceStatusChanged(String iface, boolean up) {
             reevaluateServiceState();
         }
@@ -119,9 +119,6 @@
         public void interfaceRemoved(String iface) {
             reevaluateServiceState();
         }
-        public void limitReached(String limitName, String iface) { }
-
-        public void interfaceClassDataActivityChanged(String label, boolean active) {}
     };
 
     private BroadcastReceiver mConnectivityMangerObserver = new BroadcastReceiver() {
@@ -153,7 +150,7 @@
         mContext = context;
     }
 
-    void systemReady() {
+    void systemRunning() {
         if (ServiceManager.checkService(CommonTimeConfig.SERVICE_NAME) == null) {
             Log.i(TAG, "No common time service detected on this platform.  " +
                        "Common time services will be unavailable.");
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index a022fb1..3f13f3a 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -31,6 +31,7 @@
 import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
 import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
 
+import android.app.AlarmManager;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
@@ -57,13 +58,12 @@
 import android.net.INetworkStatsService;
 import android.net.LinkAddress;
 import android.net.LinkProperties;
-import android.net.Uri;
 import android.net.LinkProperties.CompareResult;
+import android.net.LinkQualityInfo;
 import android.net.MobileDataStateTracker;
 import android.net.NetworkConfig;
 import android.net.NetworkInfo;
 import android.net.NetworkInfo.DetailedState;
-import android.net.NetworkInfo.State;
 import android.net.NetworkQuotaInfo;
 import android.net.NetworkState;
 import android.net.NetworkStateTracker;
@@ -71,6 +71,8 @@
 import android.net.Proxy;
 import android.net.ProxyProperties;
 import android.net.RouteInfo;
+import android.net.SamplingDataTracker;
+import android.net.Uri;
 import android.net.wifi.WifiStateTracker;
 import android.net.wimax.WimaxManagerConstants;
 import android.os.AsyncTask;
@@ -87,7 +89,6 @@
 import android.os.PowerManager;
 import android.os.Process;
 import android.os.RemoteException;
-import android.os.ResultReceiver;
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.SystemProperties;
@@ -98,10 +99,12 @@
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Slog;
+import android.util.SparseArray;
 import android.util.SparseIntArray;
 import android.util.Xml;
 
 import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.net.LegacyVpnInfo;
 import com.android.internal.net.VpnConfig;
 import com.android.internal.net.VpnProfile;
@@ -111,7 +114,9 @@
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.XmlUtils;
 import com.android.server.am.BatteryStatsService;
+import com.android.server.connectivity.DataConnectionStats;
 import com.android.server.connectivity.Nat464Xlat;
+import com.android.server.connectivity.PacManager;
 import com.android.server.connectivity.Tethering;
 import com.android.server.connectivity.Vpn;
 import com.android.server.net.BaseNetworkObserver;
@@ -141,8 +146,10 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.GregorianCalendar;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Random;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -172,6 +179,23 @@
     private static final String FAIL_FAST_TIME_MS =
             "persist.radio.fail_fast_time_ms";
 
+    private static final String ACTION_PKT_CNT_SAMPLE_INTERVAL_ELAPSED =
+            "android.net.ConnectivityService.action.PKT_CNT_SAMPLE_INTERVAL_ELAPSED";
+
+    private static final int SAMPLE_INTERVAL_ELAPSED_REQUEST_CODE = 0;
+
+    private PendingIntent mSampleIntervalElapsedIntent;
+
+    // Set network sampling interval at 12 minutes, this way, even if the timers get
+    // aggregated, it will fire at around 15 minutes, which should allow us to
+    // aggregate this timer with other timers (specially the socket keep alive timers)
+    private static final int DEFAULT_SAMPLING_INTERVAL_IN_SECONDS = (VDBG ? 30 : 12 * 60);
+
+    // start network sampling a minute after booting ...
+    private static final int DEFAULT_START_SAMPLING_INTERVAL_IN_SECONDS = (VDBG ? 30 : 60);
+
+    AlarmManager mAlarmManager;
+
     // used in recursive route setting to add gateways for the host for which
     // a host route was requested.
     private static final int MAX_HOSTROUTE_CYCLE_COUNT = 10;
@@ -180,7 +204,8 @@
 
     private KeyStore mKeyStore;
 
-    private Vpn mVpn;
+    @GuardedBy("mVpns")
+    private final SparseArray<Vpn> mVpns = new SparseArray<Vpn>();
     private VpnCallback mVpnCallback = new VpnCallback();
 
     private boolean mLockdownEnabled;
@@ -232,7 +257,6 @@
 
     private Object mDnsLock = new Object();
     private int mNumDnsEntries;
-    private boolean mDnsOverridden = false;
 
     private boolean mTestMode;
     private static ConnectivityService sServiceInstance;
@@ -249,6 +273,9 @@
     private static final boolean TO_DEFAULT_TABLE = true;
     private static final boolean TO_SECONDARY_TABLE = false;
 
+    private static final boolean EXEMPT = true;
+    private static final boolean UNEXEMPT = false;
+
     /**
      * used internally as a delayed event to make us switch back to the
      * default network
@@ -304,28 +331,27 @@
     private static final int EVENT_SET_DEPENDENCY_MET = 10;
 
     /**
-     * used internally to restore DNS properties back to the
-     * default network
-     */
-    private static final int EVENT_RESTORE_DNS = 11;
-
-    /**
      * used internally to send a sticky broadcast delayed.
      */
-    private static final int EVENT_SEND_STICKY_BROADCAST_INTENT = 12;
+    private static final int EVENT_SEND_STICKY_BROADCAST_INTENT = 11;
 
     /**
      * Used internally to
      * {@link NetworkStateTracker#setPolicyDataEnable(boolean)}.
      */
-    private static final int EVENT_SET_POLICY_DATA_ENABLE = 13;
+    private static final int EVENT_SET_POLICY_DATA_ENABLE = 12;
 
-    private static final int EVENT_VPN_STATE_CHANGED = 14;
+    private static final int EVENT_VPN_STATE_CHANGED = 13;
 
     /**
      * Used internally to disable fail fast of mobile data
      */
-    private static final int EVENT_ENABLE_FAIL_FAST_MOBILE_DATA = 15;
+    private static final int EVENT_ENABLE_FAIL_FAST_MOBILE_DATA = 14;
+
+    /**
+     * user internally to indicate that data sampling interval is up
+     */
+    private static final int EVENT_SAMPLE_INTERVAL_ELAPSED = 15;
 
     /** Handler used for internal events. */
     private InternalHandler mHandler;
@@ -346,10 +372,19 @@
 
     private InetAddress mDefaultDns;
 
+    // Lock for protecting access to mAddedRoutes and mExemptAddresses
+    private final Object mRoutesLock = new Object();
+
     // this collection is used to refcount the added routes - if there are none left
     // it's time to remove the route from the route table
+    @GuardedBy("mRoutesLock")
     private Collection<RouteInfo> mAddedRoutes = new ArrayList<RouteInfo>();
 
+    // this collection corresponds to the entries of mAddedRoutes that have routing exemptions
+    // used to handle cleanup of exempt rules
+    @GuardedBy("mRoutesLock")
+    private Collection<LinkAddress> mExemptAddresses = new ArrayList<LinkAddress>();
+
     // used in DBG mode to track inet condition reports
     private static final int INET_CONDITION_LOG_MAX_SIZE = 15;
     private ArrayList mInetLog;
@@ -362,6 +397,8 @@
     // track the global proxy.
     private ProxyProperties mGlobalProxy = null;
 
+    private PacManager mPacManager = null;
+
     private SettingsObserver mSettingsObserver;
 
     NetworkConfig[] mNetConfigs;
@@ -381,6 +418,8 @@
     // the set of network types that can only be enabled by system/sig apps
     List mProtectedNetworks;
 
+    private DataConnectionStats mDataConnectionStats;
+
     private AtomicInteger mEnableFailFastMobileDataTag = new AtomicInteger(0);
 
     TelephonyManager mTelephonyManager;
@@ -460,6 +499,7 @@
                 com.android.internal.R.array.radioAttributes);
         for (String raString : raStrings) {
             RadioAttributes r = new RadioAttributes(raString);
+            if (VDBG) log("raString=" + raString + " r=" + r);
             if (r.mType > ConnectivityManager.MAX_RADIO_TYPE) {
                 loge("Error in radioAttributes - ignoring attempt to define type " + r.mType);
                 continue;
@@ -480,6 +520,7 @@
         for (String naString : naStrings) {
             try {
                 NetworkConfig n = new NetworkConfig(naString);
+                if (VDBG) log("naString=" + naString + " config=" + n);
                 if (n.type > ConnectivityManager.MAX_NETWORK_TYPE) {
                     loge("Error in networkAttributes - ignoring attempt to define type " +
                             n.type);
@@ -506,6 +547,7 @@
                 // ignore it - leave the entry null
             }
         }
+        if (VDBG) log("mNetworksDefined=" + mNetworksDefined);
 
         mProtectedNetworks = new ArrayList<Integer>();
         int[] protectedNetworks = context.getResources().getIntArray(
@@ -588,9 +630,12 @@
 
         mTethering = new Tethering(mContext, mNetd, statsService, this, mHandler.getLooper());
 
-        mVpn = new Vpn(mContext, mVpnCallback, mNetd, this);
-        mVpn.startMonitoring(mContext, mTrackerHandler);
-
+        //set up the listener for user state for creating user VPNs
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(Intent.ACTION_USER_STARTING);
+        intentFilter.addAction(Intent.ACTION_USER_STOPPING);
+        mContext.registerReceiverAsUser(
+                mUserIntentReceiver, UserHandle.ALL, intentFilter, null, null);
         mClat = new Nat464Xlat(mContext, mNetd, this, mTrackerHandler);
 
         try {
@@ -608,7 +653,35 @@
         mSettingsObserver = new SettingsObserver(mHandler, EVENT_APPLY_GLOBAL_HTTP_PROXY);
         mSettingsObserver.observe(mContext);
 
+        mDataConnectionStats = new DataConnectionStats(mContext);
+        mDataConnectionStats.startMonitoring();
+
+        // start network sampling ..
+        Intent intent = new Intent(ACTION_PKT_CNT_SAMPLE_INTERVAL_ELAPSED, null);
+        mSampleIntervalElapsedIntent = PendingIntent.getBroadcast(mContext,
+                SAMPLE_INTERVAL_ELAPSED_REQUEST_CODE, intent, 0);
+
+        mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
+        setAlarm(DEFAULT_START_SAMPLING_INTERVAL_IN_SECONDS * 1000, mSampleIntervalElapsedIntent);
+
         IntentFilter filter = new IntentFilter();
+        filter.addAction(ACTION_PKT_CNT_SAMPLE_INTERVAL_ELAPSED);
+        mContext.registerReceiver(
+                new BroadcastReceiver() {
+                    @Override
+                    public void onReceive(Context context, Intent intent) {
+                        String action = intent.getAction();
+                        if (action.equals(ACTION_PKT_CNT_SAMPLE_INTERVAL_ELAPSED)) {
+                            mHandler.sendMessage(mHandler.obtainMessage
+                                    (EVENT_SAMPLE_INTERVAL_ELAPSED));
+                        }
+                    }
+                },
+                new IntentFilter(filter));
+
+        mPacManager = new PacManager(mContext);
+
+        filter = new IntentFilter();
         filter.addAction(CONNECTED_TO_PROVISIONING_NETWORK_ACTION);
         mContext.registerReceiver(mProvisioningReceiver, filter);
     }
@@ -1502,7 +1575,7 @@
         try {
             InetAddress addr = InetAddress.getByAddress(hostAddress);
             LinkProperties lp = tracker.getLinkProperties();
-            boolean ok = addRouteToAddress(lp, addr);
+            boolean ok = addRouteToAddress(lp, addr, EXEMPT);
             if (DBG) log("requestRouteToHostAddress ok=" + ok);
             return ok;
         } catch (UnknownHostException e) {
@@ -1514,24 +1587,25 @@
         return false;
     }
 
-    private boolean addRoute(LinkProperties p, RouteInfo r, boolean toDefaultTable) {
-        return modifyRoute(p, r, 0, ADD, toDefaultTable);
+    private boolean addRoute(LinkProperties p, RouteInfo r, boolean toDefaultTable,
+            boolean exempt) {
+        return modifyRoute(p, r, 0, ADD, toDefaultTable, exempt);
     }
 
     private boolean removeRoute(LinkProperties p, RouteInfo r, boolean toDefaultTable) {
-        return modifyRoute(p, r, 0, REMOVE, toDefaultTable);
+        return modifyRoute(p, r, 0, REMOVE, toDefaultTable, UNEXEMPT);
     }
 
-    private boolean addRouteToAddress(LinkProperties lp, InetAddress addr) {
-        return modifyRouteToAddress(lp, addr, ADD, TO_DEFAULT_TABLE);
+    private boolean addRouteToAddress(LinkProperties lp, InetAddress addr, boolean exempt) {
+        return modifyRouteToAddress(lp, addr, ADD, TO_DEFAULT_TABLE, exempt);
     }
 
     private boolean removeRouteToAddress(LinkProperties lp, InetAddress addr) {
-        return modifyRouteToAddress(lp, addr, REMOVE, TO_DEFAULT_TABLE);
+        return modifyRouteToAddress(lp, addr, REMOVE, TO_DEFAULT_TABLE, UNEXEMPT);
     }
 
     private boolean modifyRouteToAddress(LinkProperties lp, InetAddress addr, boolean doAdd,
-            boolean toDefaultTable) {
+            boolean toDefaultTable, boolean exempt) {
         RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getAllRoutes(), addr);
         if (bestRoute == null) {
             bestRoute = RouteInfo.makeHostRoute(addr, lp.getInterfaceName());
@@ -1546,11 +1620,11 @@
                 bestRoute = RouteInfo.makeHostRoute(addr, bestRoute.getGateway(), iface);
             }
         }
-        return modifyRoute(lp, bestRoute, 0, doAdd, toDefaultTable);
+        return modifyRoute(lp, bestRoute, 0, doAdd, toDefaultTable, exempt);
     }
 
     private boolean modifyRoute(LinkProperties lp, RouteInfo r, int cycleCount, boolean doAdd,
-            boolean toDefaultTable) {
+            boolean toDefaultTable, boolean exempt) {
         if ((lp == null) || (r == null)) {
             if (DBG) log("modifyRoute got unexpected null: " + lp + ", " + r);
             return false;
@@ -1579,15 +1653,25 @@
                                                         bestRoute.getGateway(),
                                                         ifaceName);
                 }
-                modifyRoute(lp, bestRoute, cycleCount+1, doAdd, toDefaultTable);
+                modifyRoute(lp, bestRoute, cycleCount+1, doAdd, toDefaultTable, exempt);
             }
         }
         if (doAdd) {
             if (VDBG) log("Adding " + r + " for interface " + ifaceName);
             try {
                 if (toDefaultTable) {
-                    mAddedRoutes.add(r);  // only track default table - only one apps can effect
-                    mNetd.addRoute(ifaceName, r);
+                    synchronized (mRoutesLock) {
+                        // only track default table - only one apps can effect
+                        mAddedRoutes.add(r);
+                        mNetd.addRoute(ifaceName, r);
+                        if (exempt) {
+                            LinkAddress dest = r.getDestination();
+                            if (!mExemptAddresses.contains(dest)) {
+                                mNetd.setHostExemption(dest);
+                                mExemptAddresses.add(dest);
+                            }
+                        }
+                    }
                 } else {
                     mNetd.addSecondaryRoute(ifaceName, r);
                 }
@@ -1600,18 +1684,25 @@
             // if we remove this one and there are no more like it, then refcount==0 and
             // we can remove it from the table
             if (toDefaultTable) {
-                mAddedRoutes.remove(r);
-                if (mAddedRoutes.contains(r) == false) {
-                    if (VDBG) log("Removing " + r + " for interface " + ifaceName);
-                    try {
-                        mNetd.removeRoute(ifaceName, r);
-                    } catch (Exception e) {
-                        // never crash - catch them all
-                        if (VDBG) loge("Exception trying to remove a route: " + e);
-                        return false;
+                synchronized (mRoutesLock) {
+                    mAddedRoutes.remove(r);
+                    if (mAddedRoutes.contains(r) == false) {
+                        if (VDBG) log("Removing " + r + " for interface " + ifaceName);
+                        try {
+                            mNetd.removeRoute(ifaceName, r);
+                            LinkAddress dest = r.getDestination();
+                            if (mExemptAddresses.contains(dest)) {
+                                mNetd.clearHostExemption(dest);
+                                mExemptAddresses.remove(dest);
+                            }
+                        } catch (Exception e) {
+                            // never crash - catch them all
+                            if (VDBG) loge("Exception trying to remove a route: " + e);
+                            return false;
+                        }
+                    } else {
+                        if (VDBG) log("not removing " + r + " as it's still in use");
                     }
-                } else {
-                    if (VDBG) log("not removing " + r + " as it's still in use");
                 }
             } else {
                 if (VDBG) log("Removing " + r + " for interface " + ifaceName);
@@ -1788,6 +1879,16 @@
                 "ConnectivityService");
     }
 
+    private void enforceMarkNetworkSocketPermission() {
+        //Media server special case
+        if (Binder.getCallingUid() == Process.MEDIA_UID) {
+            return;
+        }
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.MARK_NETWORK_SOCKET,
+                "ConnectivityService");
+    }
+
     /**
      * Handle a {@code DISCONNECTED} event. If this pertains to the non-active
      * network, we ignore it. If it is for the active network, we send out a
@@ -1906,6 +2007,7 @@
 //            if (mActiveDefaultNetwork != -1) {
 //                currentPriority = mNetConfigs[mActiveDefaultNetwork].mPriority;
 //            }
+
             for (int checkType=0; checkType <= ConnectivityManager.MAX_NETWORK_TYPE; checkType++) {
                 if (checkType == prevNetType) continue;
                 if (mNetConfigs[checkType] == null) continue;
@@ -1920,6 +2022,7 @@
 // optimization should work and we need to investigate why it doesn't work.
 // This could be related to how DEACTIVATE_DATA_CALL is reporting its
 // complete before it is really complete.
+
 //                if (!mNetTrackers[checkType].isAvailable()) continue;
 
 //                if (currentPriority >= mNetConfigs[checkType].mPriority) continue;
@@ -2194,6 +2297,7 @@
         }
         thisNet.setTeardownRequested(false);
         updateNetworkSettings(thisNet);
+        updateMtuSizeSettings(thisNet);
         handleConnectivityChange(newNetType, false);
         sendConnectedBroadcastDelayed(info, getConnectivityChangeDelay());
 
@@ -2305,6 +2409,7 @@
      */
     private void handleConnectivityChange(int netType, boolean doReset) {
         int resetMask = doReset ? NetworkUtils.RESET_ALL_ADDRESSES : 0;
+        boolean exempt = ConnectivityManager.isNetworkTypeExempt(netType);
         if (VDBG) {
             log("handleConnectivityChange: netType=" + netType + " doReset=" + doReset
                     + " resetMask=" + resetMask);
@@ -2373,7 +2478,7 @@
             }
         }
         mCurrentLinkProperties[netType] = newLp;
-        boolean resetDns = updateRoutes(newLp, curLp, mNetConfigs[netType].isDefault());
+        boolean resetDns = updateRoutes(newLp, curLp, mNetConfigs[netType].isDefault(), exempt);
 
         if (resetMask != 0 || resetDns) {
             if (VDBG) log("handleConnectivityChange: resetting");
@@ -2388,7 +2493,11 @@
                             // Tell VPN the interface is down. It is a temporary
                             // but effective fix to make VPN aware of the change.
                             if ((resetMask & NetworkUtils.RESET_IPV4_ADDRESSES) != 0) {
-                                mVpn.interfaceStatusChanged(iface, false);
+                                synchronized(mVpns) {
+                                    for (int i = 0; i < mVpns.size(); i++) {
+                                        mVpns.valueAt(i).interfaceStatusChanged(iface, false);
+                                    }
+                                }
                             }
                         }
                         if (resetDns) {
@@ -2448,13 +2557,13 @@
      * returns a boolean indicating the routes changed
      */
     private boolean updateRoutes(LinkProperties newLp, LinkProperties curLp,
-            boolean isLinkDefault) {
+            boolean isLinkDefault, boolean exempt) {
         Collection<RouteInfo> routesToAdd = null;
         CompareResult<InetAddress> dnsDiff = new CompareResult<InetAddress>();
         CompareResult<RouteInfo> routeDiff = new CompareResult<RouteInfo>();
         if (curLp != null) {
             // check for the delta between the current set and the new
-            routeDiff = curLp.compareRoutes(newLp);
+            routeDiff = curLp.compareAllRoutes(newLp);
             dnsDiff = curLp.compareDnses(newLp);
         } else if (newLp != null) {
             routeDiff.added = newLp.getAllRoutes();
@@ -2485,7 +2594,7 @@
                 }
                 if (newLp != null) {
                     for (InetAddress newDns : newLp.getDnses()) {
-                        addRouteToAddress(newLp, newDns);
+                        addRouteToAddress(newLp, newDns, exempt);
                     }
                 }
             } else {
@@ -2494,27 +2603,30 @@
                     removeRouteToAddress(curLp, oldDns);
                 }
                 for (InetAddress newDns : dnsDiff.added) {
-                    addRouteToAddress(newLp, newDns);
+                    addRouteToAddress(newLp, newDns, exempt);
                 }
             }
         }
 
         for (RouteInfo r :  routeDiff.added) {
             if (isLinkDefault || ! r.isDefaultRoute()) {
-                addRoute(newLp, r, TO_DEFAULT_TABLE);
+                addRoute(newLp, r, TO_DEFAULT_TABLE, exempt);
             } else {
                 // add to a secondary route table
-                addRoute(newLp, r, TO_SECONDARY_TABLE);
+                addRoute(newLp, r, TO_SECONDARY_TABLE, UNEXEMPT);
 
                 // many radios add a default route even when we don't want one.
                 // remove the default route unless somebody else has asked for it
                 String ifaceName = newLp.getInterfaceName();
-                if (TextUtils.isEmpty(ifaceName) == false && mAddedRoutes.contains(r) == false) {
-                    try {
-                        mNetd.removeRoute(ifaceName, r);
-                    } catch (Exception e) {
-                        // never crash - catch them all
-                        if (DBG) loge("Exception trying to remove a route: " + e);
+                synchronized (mRoutesLock) {
+                    if (!TextUtils.isEmpty(ifaceName) && !mAddedRoutes.contains(r)) {
+                        if (VDBG) log("Removing " + r + " for interface " + ifaceName);
+                        try {
+                            mNetd.removeRoute(ifaceName, r);
+                        } catch (Exception e) {
+                            // never crash - catch them all
+                            if (DBG) loge("Exception trying to remove a route: " + e);
+                        }
                     }
                 }
             }
@@ -2523,13 +2635,33 @@
         return routesChanged;
     }
 
-
    /**
+     * Reads the network specific MTU size from reources.
+     * and set it on it's iface.
+     */
+   private void updateMtuSizeSettings(NetworkStateTracker nt) {
+       final String iface = nt.getLinkProperties().getInterfaceName();
+       final int mtu = nt.getLinkProperties().getMtu();
+
+       if (mtu < 68 || mtu > 10000) {
+           loge("Unexpected mtu value: " + nt);
+           return;
+       }
+
+       try {
+           if (VDBG) log("Setting MTU size: " + iface + ", " + mtu);
+           mNetd.setMtu(iface, mtu);
+       } catch (Exception e) {
+           Slog.e(TAG, "exception in setMtu()" + e);
+       }
+   }
+
+    /**
      * Reads the network specific TCP buffer sizes from SystemProperties
      * net.tcp.buffersize.[default|wifi|umts|edge|gprs] and set them for system
      * wide use
      */
-   private void updateNetworkSettings(NetworkStateTracker nt) {
+    private void updateNetworkSettings(NetworkStateTracker nt) {
         String key = nt.getTcpBufferSizesPropName();
         String bufferSizes = key == null ? null : SystemProperties.get(key);
 
@@ -2551,7 +2683,7 @@
         }
     }
 
-   /**
+    /**
      * Writes TCP buffer sizes to /sys/kernel/ipv4/tcp_[r/w]mem_[min/def/max]
      * which maps to /proc/sys/net/ipv4/tcp_rmem and tcpwmem
      *
@@ -2634,7 +2766,7 @@
 
     // Caller must grab mDnsLock.
     private void updateDnsLocked(String network, String iface,
-            Collection<InetAddress> dnses, String domains) {
+            Collection<InetAddress> dnses, String domains, boolean defaultDns) {
         int last = 0;
         if (dnses.size() == 0 && mDefaultDns != null) {
             dnses = new ArrayList();
@@ -2646,7 +2778,10 @@
 
         try {
             mNetd.setDnsServersForInterface(iface, NetworkUtils.makeStrings(dnses), domains);
-            mNetd.setDefaultInterfaceForDns(iface);
+            if (defaultDns) {
+                mNetd.setDefaultInterfaceForDns(iface);
+            }
+
             for (InetAddress dns : dnses) {
                 ++last;
                 String key = "net.dns" + last;
@@ -2673,9 +2808,7 @@
             if (mNetConfigs[netType].isDefault()) {
                 String network = nt.getNetworkInfo().getTypeName();
                 synchronized (mDnsLock) {
-                    if (!mDnsOverridden) {
-                        updateDnsLocked(network, p.getInterfaceName(), dnses, p.getDomains());
-                    }
+                    updateDnsLocked(network, p.getInterfaceName(), dnses, p.getDomains(), true);
                 }
             } else {
                 try {
@@ -2820,8 +2953,11 @@
                     if (ConnectivityManager.isNetworkTypeMobile(info.getType())
                             && (0 != Settings.Global.getInt(mContext.getContentResolver(),
                                         Settings.Global.DEVICE_PROVISIONED, 0))
-                            && ((state == NetworkInfo.State.CONNECTED)
-                                    || info.isConnectedToProvisioningNetwork())) {
+                            && (((state == NetworkInfo.State.CONNECTED)
+                                    && (info.getType() == ConnectivityManager.TYPE_MOBILE))
+                                || info.isConnectedToProvisioningNetwork())) {
+                        log("ConnectivityChange checkMobileProvisioning for"
+                                + " TYPE_MOBILE or ProvisioningNetwork");
                         checkMobileProvisioning(CheckMp.MAX_TIMEOUT_MS);
                     }
 
@@ -2903,7 +3039,7 @@
         public void handleMessage(Message msg) {
             NetworkInfo info;
             switch (msg.what) {
-                case EVENT_CLEAR_NET_TRANSITION_WAKELOCK:
+                case EVENT_CLEAR_NET_TRANSITION_WAKELOCK: {
                     String causedBy = null;
                     synchronized (ConnectivityService.this) {
                         if (msg.arg1 == mNetTransitionWakeLockSerialNumber &&
@@ -2916,56 +3052,44 @@
                         log("NetTransition Wakelock for " + causedBy + " released by timeout");
                     }
                     break;
-                case EVENT_RESTORE_DEFAULT_NETWORK:
+                }
+                case EVENT_RESTORE_DEFAULT_NETWORK: {
                     FeatureUser u = (FeatureUser)msg.obj;
                     u.expire();
                     break;
-                case EVENT_INET_CONDITION_CHANGE:
-                {
+                }
+                case EVENT_INET_CONDITION_CHANGE: {
                     int netType = msg.arg1;
                     int condition = msg.arg2;
                     handleInetConditionChange(netType, condition);
                     break;
                 }
-                case EVENT_INET_CONDITION_HOLD_END:
-                {
+                case EVENT_INET_CONDITION_HOLD_END: {
                     int netType = msg.arg1;
                     int sequence = msg.arg2;
                     handleInetConditionHoldEnd(netType, sequence);
                     break;
                 }
-                case EVENT_SET_NETWORK_PREFERENCE:
-                {
+                case EVENT_SET_NETWORK_PREFERENCE: {
                     int preference = msg.arg1;
                     handleSetNetworkPreference(preference);
                     break;
                 }
-                case EVENT_SET_MOBILE_DATA:
-                {
+                case EVENT_SET_MOBILE_DATA: {
                     boolean enabled = (msg.arg1 == ENABLED);
                     handleSetMobileData(enabled);
                     break;
                 }
-                case EVENT_APPLY_GLOBAL_HTTP_PROXY:
-                {
+                case EVENT_APPLY_GLOBAL_HTTP_PROXY: {
                     handleDeprecatedGlobalHttpProxy();
                     break;
                 }
-                case EVENT_SET_DEPENDENCY_MET:
-                {
+                case EVENT_SET_DEPENDENCY_MET: {
                     boolean met = (msg.arg1 == ENABLED);
                     handleSetDependencyMet(msg.arg2, met);
                     break;
                 }
-                case EVENT_RESTORE_DNS:
-                {
-                    if (mActiveDefaultNetwork != -1) {
-                        handleDnsConfigurationChange(mActiveDefaultNetwork);
-                    }
-                    break;
-                }
-                case EVENT_SEND_STICKY_BROADCAST_INTENT:
-                {
+                case EVENT_SEND_STICKY_BROADCAST_INTENT: {
                     Intent intent = (Intent)msg.obj;
                     sendStickyBroadcast(intent);
                     break;
@@ -2994,6 +3118,11 @@
                         log("EVENT_ENABLE_FAIL_FAST_MOBILE_DATA: stale arg1:" + msg.arg1
                                 + " != tag:" + tag);
                     }
+                    break;
+                }
+                case EVENT_SAMPLE_INTERVAL_ELAPSED: {
+                    handleNetworkSamplingTimeout();
+                    break;
                 }
             }
         }
@@ -3081,12 +3210,6 @@
         return mTethering.getTetheredIfaces();
     }
 
-    @Override
-    public String[] getTetheredIfacePairs() {
-        enforceTetherAccessPermission();
-        return mTethering.getTetheredIfacePairs();
-    }
-
     public String[] getTetheringErroredIfaces() {
         enforceTetherAccessPermission();
         return mTethering.getErroredIfaces();
@@ -3222,13 +3345,15 @@
         // of proxy info to all the JVMs.
         // enforceAccessPermission();
         synchronized (mProxyLock) {
-            if (mGlobalProxy != null) return mGlobalProxy;
-            return (mDefaultProxyDisabled ? null : mDefaultProxy);
+            ProxyProperties ret = mGlobalProxy;
+            if ((ret == null) && !mDefaultProxyDisabled) ret = mDefaultProxy;
+            return ret;
         }
     }
 
     public void setGlobalProxy(ProxyProperties proxyProperties) {
         enforceConnectivityInternalPermission();
+
         synchronized (mProxyLock) {
             if (proxyProperties == mGlobalProxy) return;
             if (proxyProperties != null && proxyProperties.equals(mGlobalProxy)) return;
@@ -3237,11 +3362,16 @@
             String host = "";
             int port = 0;
             String exclList = "";
-            if (proxyProperties != null && !TextUtils.isEmpty(proxyProperties.getHost())) {
+            String pacFileUrl = "";
+            if (proxyProperties != null && (!TextUtils.isEmpty(proxyProperties.getHost()) ||
+                    !TextUtils.isEmpty(proxyProperties.getPacFileUrl()))) {
                 mGlobalProxy = new ProxyProperties(proxyProperties);
                 host = mGlobalProxy.getHost();
                 port = mGlobalProxy.getPort();
                 exclList = mGlobalProxy.getExclusionList();
+                if (proxyProperties.getPacFileUrl() != null) {
+                    pacFileUrl = proxyProperties.getPacFileUrl();
+                }
             } else {
                 mGlobalProxy = null;
             }
@@ -3252,6 +3382,7 @@
                 Settings.Global.putInt(res, Settings.Global.GLOBAL_HTTP_PROXY_PORT, port);
                 Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST,
                         exclList);
+                Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_PAC, pacFileUrl);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
@@ -3269,8 +3400,14 @@
         int port = Settings.Global.getInt(res, Settings.Global.GLOBAL_HTTP_PROXY_PORT, 0);
         String exclList = Settings.Global.getString(res,
                 Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST);
-        if (!TextUtils.isEmpty(host)) {
-            ProxyProperties proxyProperties = new ProxyProperties(host, port, exclList);
+        String pacFileUrl = Settings.Global.getString(res, Settings.Global.GLOBAL_HTTP_PROXY_PAC);
+        if (!TextUtils.isEmpty(host) || !TextUtils.isEmpty(pacFileUrl)) {
+            ProxyProperties proxyProperties;
+            if (!TextUtils.isEmpty(pacFileUrl)) {
+                proxyProperties = new ProxyProperties(pacFileUrl);
+            } else {
+                proxyProperties = new ProxyProperties(host, port, exclList);
+            }
             synchronized (mProxyLock) {
                 mGlobalProxy = proxyProperties;
             }
@@ -3288,7 +3425,8 @@
     }
 
     private void handleApplyDefaultProxy(ProxyProperties proxy) {
-        if (proxy != null && TextUtils.isEmpty(proxy.getHost())) {
+        if (proxy != null && TextUtils.isEmpty(proxy.getHost())
+                && TextUtils.isEmpty(proxy.getPacFileUrl())) {
             proxy = null;
         }
         synchronized (mProxyLock) {
@@ -3308,6 +3446,10 @@
                 Settings.Global.HTTP_PROXY);
         if (!TextUtils.isEmpty(proxy)) {
             String data[] = proxy.split(":");
+            if (data.length == 0) {
+                return;
+            }
+
             String proxyHost =  data[0];
             int proxyPort = 8080;
             if (data.length > 1) {
@@ -3324,6 +3466,7 @@
 
     private void sendProxyBroadcast(ProxyProperties proxy) {
         if (proxy == null) proxy = new ProxyProperties("", 0, "");
+        if (mPacManager.setCurrentProxyScriptUrl(proxy)) return;
         if (DBG) log("sending Proxy Broadcast for " + proxy);
         Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
         intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING |
@@ -3418,8 +3561,12 @@
         throwIfLockdownEnabled();
         try {
             int type = mActiveDefaultNetwork;
+            int user = UserHandle.getUserId(Binder.getCallingUid());
             if (ConnectivityManager.isNetworkTypeValid(type) && mNetTrackers[type] != null) {
-                mVpn.protect(socket, mNetTrackers[type].getLinkProperties().getInterfaceName());
+                synchronized(mVpns) {
+                    mVpns.get(user).protect(socket,
+                            mNetTrackers[type].getLinkProperties().getInterfaceName());
+                }
                 return true;
             }
         } catch (Exception e) {
@@ -3443,7 +3590,27 @@
     @Override
     public boolean prepareVpn(String oldPackage, String newPackage) {
         throwIfLockdownEnabled();
-        return mVpn.prepare(oldPackage, newPackage);
+        int user = UserHandle.getUserId(Binder.getCallingUid());
+        synchronized(mVpns) {
+            return mVpns.get(user).prepare(oldPackage, newPackage);
+        }
+    }
+
+    @Override
+    public void markSocketAsUser(ParcelFileDescriptor socket, int uid) {
+        enforceMarkNetworkSocketPermission();
+        final long token = Binder.clearCallingIdentity();
+        try {
+            int mark = mNetd.getMarkForUid(uid);
+            // Clear the mark on the socket if no mark is needed to prevent socket reuse issues
+            if (mark == -1) {
+                mark = 0;
+            }
+            NetworkUtils.markSocket(socket.getFd(), mark);
+        } catch (RemoteException e) {
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
     }
 
     /**
@@ -3456,7 +3623,10 @@
     @Override
     public ParcelFileDescriptor establishVpn(VpnConfig config) {
         throwIfLockdownEnabled();
-        return mVpn.establish(config);
+        int user = UserHandle.getUserId(Binder.getCallingUid());
+        synchronized(mVpns) {
+            return mVpns.get(user).establish(config);
+        }
     }
 
     /**
@@ -3470,7 +3640,10 @@
         if (egress == null) {
             throw new IllegalStateException("Missing active network connection");
         }
-        mVpn.startLegacyVpn(profile, mKeyStore, egress);
+        int user = UserHandle.getUserId(Binder.getCallingUid());
+        synchronized(mVpns) {
+            mVpns.get(user).startLegacyVpn(profile, mKeyStore, egress);
+        }
     }
 
     /**
@@ -3482,7 +3655,24 @@
     @Override
     public LegacyVpnInfo getLegacyVpnInfo() {
         throwIfLockdownEnabled();
-        return mVpn.getLegacyVpnInfo();
+        int user = UserHandle.getUserId(Binder.getCallingUid());
+        synchronized(mVpns) {
+            return mVpns.get(user).getLegacyVpnInfo();
+        }
+    }
+
+    /**
+     * Returns the information of the ongoing VPN. This method is used by VpnDialogs and
+     * not available in ConnectivityManager.
+     * Permissions are checked in Vpn class.
+     * @hide
+     */
+    @Override
+    public VpnConfig getVpnConfig() {
+        int user = UserHandle.getUserId(Binder.getCallingUid());
+        synchronized(mVpns) {
+            return mVpns.get(user).getVpnConfig();
+        }
     }
 
     /**
@@ -3503,7 +3693,7 @@
             mHandler.obtainMessage(EVENT_VPN_STATE_CHANGED, info).sendToTarget();
         }
 
-        public void override(List<String> dnsServers, List<String> searchDomains) {
+        public void override(String iface, List<String> dnsServers, List<String> searchDomains) {
             if (dnsServers == null) {
                 restore();
                 return;
@@ -3535,8 +3725,7 @@
 
             // Apply DNS changes.
             synchronized (mDnsLock) {
-                updateDnsLocked("VPN", "VPN", addresses, domains);
-                mDnsOverridden = true;
+                updateDnsLocked("VPN", iface, addresses, domains, false);
             }
 
             // Temporarily disable the default proxy (not global).
@@ -3551,12 +3740,6 @@
         }
 
         public void restore() {
-            synchronized (mDnsLock) {
-                if (mDnsOverridden) {
-                    mDnsOverridden = false;
-                    mHandler.sendEmptyMessage(EVENT_RESTORE_DNS);
-                }
-            }
             synchronized (mProxyLock) {
                 mDefaultProxyDisabled = false;
                 if (mGlobalProxy == null && mDefaultProxy != null) {
@@ -3564,6 +3747,67 @@
                 }
             }
         }
+
+        public void protect(ParcelFileDescriptor socket) {
+            try {
+                final int mark = mNetd.getMarkForProtect();
+                NetworkUtils.markSocket(socket.getFd(), mark);
+            } catch (RemoteException e) {
+            }
+        }
+
+        public void setRoutes(String interfaze, List<RouteInfo> routes) {
+            for (RouteInfo route : routes) {
+                try {
+                    mNetd.setMarkedForwardingRoute(interfaze, route);
+                } catch (RemoteException e) {
+                }
+            }
+        }
+
+        public void setMarkedForwarding(String interfaze) {
+            try {
+                mNetd.setMarkedForwarding(interfaze);
+            } catch (RemoteException e) {
+            }
+        }
+
+        public void clearMarkedForwarding(String interfaze) {
+            try {
+                mNetd.clearMarkedForwarding(interfaze);
+            } catch (RemoteException e) {
+            }
+        }
+
+        public void addUserForwarding(String interfaze, int uid) {
+            int uidStart = uid * UserHandle.PER_USER_RANGE;
+            int uidEnd = uidStart + UserHandle.PER_USER_RANGE - 1;
+            addUidForwarding(interfaze, uidStart, uidEnd);
+        }
+
+        public void clearUserForwarding(String interfaze, int uid) {
+            int uidStart = uid * UserHandle.PER_USER_RANGE;
+            int uidEnd = uidStart + UserHandle.PER_USER_RANGE - 1;
+            clearUidForwarding(interfaze, uidStart, uidEnd);
+        }
+
+        public void addUidForwarding(String interfaze, int uidStart, int uidEnd) {
+            try {
+                mNetd.setUidRangeRoute(interfaze,uidStart, uidEnd);
+                mNetd.setDnsInterfaceForUidRange(interfaze, uidStart, uidEnd);
+            } catch (RemoteException e) {
+            }
+
+        }
+
+        public void clearUidForwarding(String interfaze, int uidStart, int uidEnd) {
+            try {
+                mNetd.clearUidRangeRoute(interfaze, uidStart, uidEnd);
+                mNetd.clearDnsInterfaceForUidRange(uidStart, uidEnd);
+            } catch (RemoteException e) {
+            }
+
+        }
     }
 
     @Override
@@ -3584,7 +3828,11 @@
             final String profileName = new String(mKeyStore.get(Credentials.LOCKDOWN_VPN));
             final VpnProfile profile = VpnProfile.decode(
                     profileName, mKeyStore.get(Credentials.VPN + profileName));
-            setLockdownTracker(new LockdownVpnTracker(mContext, mNetd, this, mVpn, profile));
+            int user = UserHandle.getUserId(Binder.getCallingUid());
+            synchronized(mVpns) {
+                setLockdownTracker(new LockdownVpnTracker(mContext, mNetd, this, mVpns.get(user),
+                            profile));
+            }
         } else {
             setLockdownTracker(null);
         }
@@ -3676,39 +3924,41 @@
 
     /**
      * No connection was possible to the network.
+     * This is NOT a warm sim.
      */
-    public static final int CMP_RESULT_CODE_NO_CONNECTION = 0;
+    private static final int CMP_RESULT_CODE_NO_CONNECTION = 0;
 
     /**
      * A connection was made to the internet, all is well.
+     * This is NOT a warm sim.
      */
-    public static final int CMP_RESULT_CODE_CONNECTABLE = 1;
-
-    /**
-     * A connection was made but there was a redirection, we appear to be in walled garden.
-     * This is an indication of a warm sim on a mobile network.
-     */
-    public static final int CMP_RESULT_CODE_REDIRECTED = 2;
+    private static final int CMP_RESULT_CODE_CONNECTABLE = 1;
 
     /**
      * A connection was made but no dns server was available to resolve a name to address.
-     * This is an indication of a warm sim on a mobile network.
+     * This is NOT a warm sim since provisioning network is supported.
      */
-    public static final int CMP_RESULT_CODE_NO_DNS = 3;
+    private static final int CMP_RESULT_CODE_NO_DNS = 2;
 
     /**
      * A connection was made but could not open a TCP connection.
-     * This is an indication of a warm sim on a mobile network.
+     * This is NOT a warm sim since provisioning network is supported.
      */
-    public static final int CMP_RESULT_CODE_NO_TCP_CONNECTION = 4;
+    private static final int CMP_RESULT_CODE_NO_TCP_CONNECTION = 3;
+
+    /**
+     * A connection was made but there was a redirection, we appear to be in walled garden.
+     * This is an indication of a warm sim on a mobile network such as T-Mobile.
+     */
+    private static final int CMP_RESULT_CODE_REDIRECTED = 4;
 
     /**
      * The mobile network is a provisioning network.
-     * This is an indication of a warm sim on a mobile network.
+     * This is an indication of a warm sim on a mobile network such as AT&T.
      */
-    public static final int CMP_RESULT_CODE_PROVISIONING_NETWORK = 5;
+    private static final int CMP_RESULT_CODE_PROVISIONING_NETWORK = 5;
 
-    AtomicBoolean mIsCheckingMobileProvisioning = new AtomicBoolean(false);
+    private AtomicBoolean mIsCheckingMobileProvisioning = new AtomicBoolean(false);
 
     @Override
     public int checkMobileProvisioning(int suggestedTimeOutMs) {
@@ -3740,40 +3990,6 @@
             // Start off with notification off
             setProvNotificationVisible(false, ConnectivityManager.TYPE_NONE, null, null);
 
-            // See if we've alreadying determined if we've got a provsioning connection
-            // if so we don't need to do anything active
-            MobileDataStateTracker mdstDefault = (MobileDataStateTracker)
-                    mNetTrackers[ConnectivityManager.TYPE_MOBILE];
-            boolean isDefaultProvisioning = mdstDefault.isProvisioningNetwork();
-
-            MobileDataStateTracker mdstHipri = (MobileDataStateTracker)
-                    mNetTrackers[ConnectivityManager.TYPE_MOBILE_HIPRI];
-            boolean isHipriProvisioning = mdstHipri.isProvisioningNetwork();
-
-            if (isDefaultProvisioning || isHipriProvisioning) {
-                if (mIsNotificationVisible) {
-                    if (DBG) {
-                        log("checkMobileProvisioning: provisioning-ignore notification is visible");
-                    }
-                } else {
-                    NetworkInfo ni = null;
-                    if (isDefaultProvisioning) {
-                        ni = mdstDefault.getNetworkInfo();
-                    }
-                    if (isHipriProvisioning) {
-                        ni = mdstHipri.getNetworkInfo();
-                    }
-                    String url = getMobileProvisioningUrl();
-                    if ((ni != null) && (!TextUtils.isEmpty(url))) {
-                        setProvNotificationVisible(true, ni.getType(), ni.getExtraInfo(), url);
-                    } else {
-                        if (DBG) log("checkMobileProvisioning: provisioning but no url, ignore");
-                    }
-                }
-                mIsCheckingMobileProvisioning.set(false);
-                return timeOutMs;
-            }
-
             CheckMp checkMp = new CheckMp(mContext, this);
             CheckMp.CallBack cb = new CheckMp.CallBack() {
                 @Override
@@ -3783,7 +3999,9 @@
                             mNetTrackers[ConnectivityManager.TYPE_MOBILE_HIPRI].getNetworkInfo();
                     switch(result) {
                         case CMP_RESULT_CODE_CONNECTABLE:
-                        case CMP_RESULT_CODE_NO_CONNECTION: {
+                        case CMP_RESULT_CODE_NO_CONNECTION:
+                        case CMP_RESULT_CODE_NO_DNS:
+                        case CMP_RESULT_CODE_NO_TCP_CONNECTION: {
                             if (DBG) log("CheckMp.onComplete: ignore, connected or no connection");
                             break;
                         }
@@ -3802,8 +4020,7 @@
                             }
                             break;
                         }
-                        case CMP_RESULT_CODE_NO_DNS:
-                        case CMP_RESULT_CODE_NO_TCP_CONNECTION: {
+                        case CMP_RESULT_CODE_PROVISIONING_NETWORK: {
                             String url = getMobileProvisioningUrl();
                             if (TextUtils.isEmpty(url) == false) {
                                 if (DBG) log("CheckMp.onComplete: warm (no dns/tcp), url=" + url);
@@ -3906,8 +4123,26 @@
             mParams = params;
 
             if (mCs.isNetworkSupported(ConnectivityManager.TYPE_MOBILE) == false) {
-                log("isMobileOk: not mobile capable");
                 result = CMP_RESULT_CODE_NO_CONNECTION;
+                log("isMobileOk: X not mobile capable result=" + result);
+                return result;
+            }
+
+            // See if we've already determined we've got a provisioning connection,
+            // if so we don't need to do anything active.
+            MobileDataStateTracker mdstDefault = (MobileDataStateTracker)
+                    mCs.mNetTrackers[ConnectivityManager.TYPE_MOBILE];
+            boolean isDefaultProvisioning = mdstDefault.isProvisioningNetwork();
+            log("isMobileOk: isDefaultProvisioning=" + isDefaultProvisioning);
+
+            MobileDataStateTracker mdstHipri = (MobileDataStateTracker)
+                    mCs.mNetTrackers[ConnectivityManager.TYPE_MOBILE_HIPRI];
+            boolean isHipriProvisioning = mdstHipri.isProvisioningNetwork();
+            log("isMobileOk: isHipriProvisioning=" + isHipriProvisioning);
+
+            if (isDefaultProvisioning || isHipriProvisioning) {
+                result = CMP_RESULT_CODE_PROVISIONING_NETWORK;
+                log("isMobileOk: X default || hipri is provisioning result=" + result);
                 return result;
             }
 
@@ -3969,8 +4204,8 @@
                         MobileDataStateTracker mdst = (MobileDataStateTracker)
                                 mCs.mNetTrackers[ConnectivityManager.TYPE_MOBILE_HIPRI];
                         if (mdst.isProvisioningNetwork()) {
-                            if (DBG) log("isMobileOk: isProvisioningNetwork is true, no TCP conn");
-                            result = CMP_RESULT_CODE_NO_TCP_CONNECTION;
+                            result = CMP_RESULT_CODE_PROVISIONING_NETWORK;
+                            if (DBG) log("isMobileOk: X isProvisioningNetwork result=" + result);
                             return result;
                         } else {
                             if (DBG) log("isMobileOk: isProvisioningNetwork is false, continue");
@@ -3985,8 +4220,8 @@
                         try {
                             addresses = InetAddress.getAllByName(orgUri.getHost());
                         } catch (UnknownHostException e) {
-                            log("isMobileOk: UnknownHostException");
                             result = CMP_RESULT_CODE_NO_DNS;
+                            log("isMobileOk: X UnknownHostException result=" + result);
                             return result;
                         }
                         log("isMobileOk: addresses=" + inetAddressesToString(addresses));
@@ -3994,8 +4229,8 @@
                         // Get the type of addresses supported by this link
                         LinkProperties lp = mCs.getLinkProperties(
                                 ConnectivityManager.TYPE_MOBILE_HIPRI);
-                        boolean linkHasIpv4 = hasIPv4Address(lp);
-                        boolean linkHasIpv6 = hasIPv6Address(lp);
+                        boolean linkHasIpv4 = lp.hasIPv4Address();
+                        boolean linkHasIpv6 = lp.hasIPv6Address();
                         log("isMobileOk: linkHasIpv4=" + linkHasIpv4
                                 + " linkHasIpv6=" + linkHasIpv6);
 
@@ -4050,25 +4285,38 @@
                                 urlConn.setAllowUserInteraction(false);
                                 urlConn.setRequestProperty("Connection", "close");
                                 int responseCode = urlConn.getResponseCode();
-                                if (responseCode == 204) {
-                                    result = CMP_RESULT_CODE_CONNECTABLE;
-                                } else {
-                                    result = CMP_RESULT_CODE_REDIRECTED;
-                                }
-                                log("isMobileOk: connected responseCode=" + responseCode);
+
+                                // For debug display the headers
+                                Map<String, List<String>> headers = urlConn.getHeaderFields();
+                                log("isMobileOk: headers=" + headers);
+
+                                // Close the connection
                                 urlConn.disconnect();
                                 urlConn = null;
-                                return result;
+
+                                if (responseCode == 204) {
+                                    // Return
+                                    result = CMP_RESULT_CODE_CONNECTABLE;
+                                    log("isMobileOk: X expected responseCode=" + responseCode
+                                            + " result=" + result);
+                                    return result;
+                                } else {
+                                    // Retry to be sure this was redirected, we've gotten
+                                    // occasions where a server returned 200 even though
+                                    // the device didn't have a "warm" sim.
+                                    log("isMobileOk: not expected responseCode=" + responseCode);
+                                    result = CMP_RESULT_CODE_REDIRECTED;
+                                }
                             } catch (Exception e) {
                                 log("isMobileOk: HttpURLConnection Exception e=" + e);
+                                result = CMP_RESULT_CODE_NO_TCP_CONNECTION;
                                 if (urlConn != null) {
                                     urlConn.disconnect();
                                     urlConn = null;
                                 }
                             }
                         }
-                        result = CMP_RESULT_CODE_NO_TCP_CONNECTION;
-                        log("isMobileOk: loops|timed out");
+                        log("isMobileOk: X loops|timed out result=" + result);
                         return result;
                     } catch (Exception e) {
                         log("isMobileOk: Exception e=" + e);
@@ -4158,20 +4406,6 @@
             }
         }
 
-        public boolean hasIPv4Address(LinkProperties lp) {
-            return lp.hasIPv4Address();
-        }
-
-        // Not implemented in LinkProperties, do it here.
-        public boolean hasIPv6Address(LinkProperties lp) {
-            for (LinkAddress address : lp.getLinkAddresses()) {
-              if (address.getAddress() instanceof Inet6Address) {
-                return true;
-              }
-            }
-            return false;
-        }
-
         private void log(String s) {
             Slog.d(ConnectivityService.TAG, "[" + CHECKMP_TAG + "] " + s);
         }
@@ -4426,4 +4660,145 @@
         enforceConnectivityInternalPermission();
         setProvNotificationVisible(visible, networkType, extraInfo, url);
     }
+
+    @Override
+    public void setAirplaneMode(boolean enable) {
+        enforceConnectivityInternalPermission();
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            final ContentResolver cr = mContext.getContentResolver();
+            Settings.Global.putInt(cr, Settings.Global.AIRPLANE_MODE_ON, enable ? 1 : 0);
+            Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+            intent.putExtra("state", enable);
+            mContext.sendBroadcast(intent);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    private void onUserStart(int userId) {
+        synchronized(mVpns) {
+            Vpn userVpn = mVpns.get(userId);
+            if (userVpn != null) {
+                loge("Starting user already has a VPN");
+                return;
+            }
+            userVpn = new Vpn(mContext, mVpnCallback, mNetd, this, userId);
+            mVpns.put(userId, userVpn);
+            userVpn.startMonitoring(mContext, mTrackerHandler);
+        }
+    }
+
+    private void onUserStop(int userId) {
+        synchronized(mVpns) {
+            Vpn userVpn = mVpns.get(userId);
+            if (userVpn == null) {
+                loge("Stopping user has no VPN");
+                return;
+            }
+            mVpns.delete(userId);
+        }
+    }
+
+    private BroadcastReceiver mUserIntentReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final String action = intent.getAction();
+            final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
+            if (userId == UserHandle.USER_NULL) return;
+
+            if (Intent.ACTION_USER_STARTING.equals(action)) {
+                onUserStart(userId);
+            } else if (Intent.ACTION_USER_STOPPING.equals(action)) {
+                onUserStop(userId);
+            }
+        }
+    };
+
+    @Override
+    public LinkQualityInfo getLinkQualityInfo(int networkType) {
+        enforceAccessPermission();
+        if (isNetworkTypeValid(networkType)) {
+            return mNetTrackers[networkType].getLinkQualityInfo();
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public LinkQualityInfo getActiveLinkQualityInfo() {
+        enforceAccessPermission();
+        if (isNetworkTypeValid(mActiveDefaultNetwork)) {
+            return mNetTrackers[mActiveDefaultNetwork].getLinkQualityInfo();
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public LinkQualityInfo[] getAllLinkQualityInfo() {
+        enforceAccessPermission();
+        final ArrayList<LinkQualityInfo> result = Lists.newArrayList();
+        for (NetworkStateTracker tracker : mNetTrackers) {
+            if (tracker != null) {
+                LinkQualityInfo li = tracker.getLinkQualityInfo();
+                if (li != null) {
+                    result.add(li);
+                }
+            }
+        }
+
+        return result.toArray(new LinkQualityInfo[result.size()]);
+    }
+
+    /* Infrastructure for network sampling */
+
+    private void handleNetworkSamplingTimeout() {
+
+        log("Sampling interval elapsed, updating statistics ..");
+
+        // initialize list of interfaces ..
+        Map<String, SamplingDataTracker.SamplingSnapshot> mapIfaceToSample =
+                new HashMap<String, SamplingDataTracker.SamplingSnapshot>();
+        for (NetworkStateTracker tracker : mNetTrackers) {
+            if (tracker != null) {
+                String ifaceName = tracker.getNetworkInterfaceName();
+                if (ifaceName != null) {
+                    mapIfaceToSample.put(ifaceName, null);
+                }
+            }
+        }
+
+        // Read samples for all interfaces
+        SamplingDataTracker.getSamplingSnapshots(mapIfaceToSample);
+
+        // process samples for all networks
+        for (NetworkStateTracker tracker : mNetTrackers) {
+            if (tracker != null) {
+                String ifaceName = tracker.getNetworkInterfaceName();
+                SamplingDataTracker.SamplingSnapshot ss = mapIfaceToSample.get(ifaceName);
+                if (ss != null) {
+                    // end the previous sampling cycle
+                    tracker.stopSampling(ss);
+                    // start a new sampling cycle ..
+                    tracker.startSampling(ss);
+                }
+            }
+        }
+
+        log("Done.");
+
+        int samplingIntervalInSeconds = Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.CONNECTIVITY_SAMPLING_INTERVAL_IN_SECONDS,
+                DEFAULT_SAMPLING_INTERVAL_IN_SECONDS);
+
+        if (DBG) log("Setting timer for " + String.valueOf(samplingIntervalInSeconds) + "seconds");
+
+        setAlarm(samplingIntervalInSeconds * 1000, mSampleIntervalElapsedIntent);
+    }
+
+    void setAlarm(int timeoutInMilliseconds, PendingIntent intent) {
+        long wakeupTime = SystemClock.elapsedRealtime() + timeoutInMilliseconds;
+        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, wakeupTime, intent);
+    }
 }
diff --git a/services/java/com/android/server/ConsumerIrService.java b/services/java/com/android/server/ConsumerIrService.java
new file mode 100644
index 0000000..07f2a41
--- /dev/null
+++ b/services/java/com/android/server/ConsumerIrService.java
@@ -0,0 +1,130 @@
+/*
+ * 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.server;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.database.ContentObserver;
+import android.hardware.input.InputManager;
+import android.hardware.IConsumerIrService;
+import android.os.Handler;
+import android.os.PowerManager;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.IBinder;
+import android.os.Binder;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.os.WorkSource;
+import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
+import android.util.Slog;
+import android.view.InputDevice;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.ListIterator;
+
+public class ConsumerIrService extends IConsumerIrService.Stub {
+    private static final String TAG = "ConsumerIrService";
+
+    private static final int MAX_XMIT_TIME = 2000000; /* in microseconds */
+
+    private static native int halOpen();
+    private static native int halTransmit(int halObject, int carrierFrequency, int[] pattern);
+    private static native int[] halGetCarrierFrequencies(int halObject);
+
+    private final Context mContext;
+    private final PowerManager.WakeLock mWakeLock;
+    private final int mHal;
+    private final Object mHalLock = new Object();
+
+    ConsumerIrService(Context context) {
+        mContext = context;
+        PowerManager pm = (PowerManager)context.getSystemService(
+                Context.POWER_SERVICE);
+        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
+        mWakeLock.setReferenceCounted(true);
+
+        mHal = halOpen();
+        if (mHal == 0) {
+            Slog.w(TAG, "No IR HAL loaded");
+        }
+    }
+
+    @Override
+    public boolean hasIrEmitter() {
+        return mHal != 0;
+    }
+
+    private void throwIfNoIrEmitter() {
+        if (mHal == 0) {
+            throw new UnsupportedOperationException("IR emitter not available");
+        }
+    }
+
+
+    @Override
+    public void transmit(String packageName, int carrierFrequency, int[] pattern) {
+        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.TRANSMIT_IR)
+                != PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException("Requires TRANSMIT_IR permission");
+        }
+
+        long totalXmitTime = 0;
+
+        for (int slice : pattern) {
+            if (slice <= 0) {
+                throw new IllegalArgumentException("Non-positive IR slice");
+            }
+            totalXmitTime += slice;
+        }
+
+        if (totalXmitTime > MAX_XMIT_TIME ) {
+            throw new IllegalArgumentException("IR pattern too long");
+        }
+
+        throwIfNoIrEmitter();
+
+        // Right now there is no mechanism to ensure fair queing of IR requests
+        synchronized (mHalLock) {
+            int err = halTransmit(mHal, carrierFrequency, pattern);
+
+            if (err < 0) {
+                Slog.e(TAG, "Error transmitting: " + err);
+            }
+        }
+    }
+
+    @Override
+    public int[] getCarrierFrequencies() {
+        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.TRANSMIT_IR)
+                != PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException("Requires TRANSMIT_IR permission");
+        }
+
+        throwIfNoIrEmitter();
+
+        synchronized(mHalLock) {
+            return halGetCarrierFrequencies(mHal);
+        }
+    }
+}
diff --git a/services/java/com/android/server/CountryDetectorService.java b/services/java/com/android/server/CountryDetectorService.java
index fc76277..a478b2f 100644
--- a/services/java/com/android/server/CountryDetectorService.java
+++ b/services/java/com/android/server/CountryDetectorService.java
@@ -20,6 +20,7 @@
 import java.io.PrintWriter;
 import java.util.HashMap;
 
+import com.android.internal.os.BackgroundThread;
 import com.android.server.location.ComprehensiveCountryDetector;
 
 import android.content.Context;
@@ -29,8 +30,6 @@
 import android.location.ICountryListener;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.Looper;
-import android.os.Process;
 import android.os.RemoteException;
 import android.util.PrintWriterPrinter;
 import android.util.Printer;
@@ -98,11 +97,12 @@
     }
 
     @Override
-    public Country detectCountry() throws RemoteException {
+    public Country detectCountry() {
         if (!mSystemReady) {
-            throw new RemoteException();
+            return null;   // server not yet active
+        } else {
+            return mCountryDetector.detectCountry();
         }
-        return mCountryDetector.detectCountry();
     }
 
     /**
@@ -167,10 +167,9 @@
         }
     }
 
-    void systemReady() {
+    void systemRunning() {
         // Shall we wait for the initialization finish.
-        Thread thread = new Thread(this, "CountryDetectorService");
-        thread.start();
+        BackgroundThread.getHandler().post(this);
     }
 
     private void initialize() {
@@ -187,12 +186,9 @@
     }
 
     public void run() {
-        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
-        Looper.prepare();
         mHandler = new Handler();
         initialize();
         mSystemReady = true;
-        Looper.loop();
     }
 
     protected void setCountryListener(final CountryListener listener) {
diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java
index 7ecd2c0..2bca759 100644
--- a/services/java/com/android/server/DevicePolicyManagerService.java
+++ b/services/java/com/android/server/DevicePolicyManagerService.java
@@ -16,11 +16,15 @@
 
 package com.android.server;
 
+import static android.Manifest.permission.MANAGE_CA_CERTIFICATES;
+
+import com.android.internal.R;
 import com.android.internal.os.storage.ExternalStorageFormatter;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.JournaledFile;
 import com.android.internal.util.XmlUtils;
 import com.android.internal.widget.LockPatternUtils;
+import com.android.org.conscrypt.TrustedCertificateStore;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -30,6 +34,9 @@
 import android.app.ActivityManagerNative;
 import android.app.AlarmManager;
 import android.app.AppGlobals;
+import android.app.INotificationManager;
+import android.app.Notification;
+import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.admin.DeviceAdminInfo;
 import android.app.admin.DeviceAdminReceiver;
@@ -48,7 +55,9 @@
 import android.content.pm.Signature;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
+import android.content.pm.UserInfo;
 import android.net.Uri;
+import android.os.AsyncTask;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Environment;
@@ -66,7 +75,12 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
+import android.security.Credentials;
+import android.security.IKeyChainService;
+import android.security.KeyChain;
+import android.security.KeyChain.KeyChainConnection;
 import android.util.AtomicFile;
+import android.util.Log;
 import android.util.PrintWriterPrinter;
 import android.util.Printer;
 import android.util.Slog;
@@ -75,6 +89,7 @@
 import android.view.IWindowManager;
 import android.view.WindowManagerPolicy;
 
+import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
@@ -82,8 +97,14 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.security.KeyStore.TrustedCertificateEntry;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
 import java.text.DateFormat;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
@@ -107,6 +128,8 @@
     protected static final String ACTION_EXPIRED_PASSWORD_NOTIFICATION
             = "com.android.server.ACTION_EXPIRED_PASSWORD_NOTIFICATION";
 
+    private static final int MONITORING_CERT_NOTIFICATION_ID = R.string.ssl_ca_cert_warning;
+
     private static final boolean DBG = false;
 
     final Context mContext;
@@ -114,6 +137,7 @@
 
     IPowerManager mIPowerManager;
     IWindowManager mIWindowManager;
+    NotificationManager mNotificationManager;
 
     private DeviceOwner mDeviceOwner;
 
@@ -161,7 +185,12 @@
                         handlePasswordExpirationNotification(getUserData(userHandle));
                     }
                 });
-            } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
+            }
+            if (Intent.ACTION_BOOT_COMPLETED.equals(action)
+                    || KeyChain.ACTION_STORAGE_CHANGED.equals(action)) {
+                manageMonitoringCertificateNotification(intent);
+            }
+            if (Intent.ACTION_USER_REMOVED.equals(action)) {
                 removeUserData(userHandle);
             } else if (Intent.ACTION_USER_STARTED.equals(action)
                     || Intent.ACTION_PACKAGE_CHANGED.equals(action)
@@ -510,6 +539,7 @@
         filter.addAction(ACTION_EXPIRED_PASSWORD_NOTIFICATION);
         filter.addAction(Intent.ACTION_USER_REMOVED);
         filter.addAction(Intent.ACTION_USER_STARTED);
+        filter.addAction(KeyChain.ACTION_STORAGE_CHANGED);
         context.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, mHandler);
         filter = new IntentFilter();
         filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
@@ -619,6 +649,14 @@
         return mIWindowManager;
     }
 
+    private NotificationManager getNotificationManager() {
+        if (mNotificationManager == null) {
+            mNotificationManager =
+                    (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+        }
+        return mNotificationManager;
+    }
+
     ActiveAdmin getActiveAdminUncheckedLocked(ComponentName who, int userHandle) {
         ActiveAdmin admin = getUserData(userHandle).mAdminMap.get(who);
         if (admin != null
@@ -1037,13 +1075,70 @@
         }
     }
 
+    private void manageMonitoringCertificateNotification(Intent intent) {
+        final NotificationManager notificationManager = getNotificationManager();
+
+        final boolean hasCert = DevicePolicyManager.hasAnyCaCertsInstalled();
+        if (! hasCert) {
+            if (intent.getAction().equals(KeyChain.ACTION_STORAGE_CHANGED)) {
+                UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+                for (UserInfo user : um.getUsers()) {
+                    notificationManager.cancelAsUser(
+                            null, MONITORING_CERT_NOTIFICATION_ID, user.getUserHandle());
+                }
+            }
+            return;
+        }
+        final boolean isManaged = getDeviceOwner() != null;
+        int smallIconId;
+        String contentText;
+        if (isManaged) {
+            contentText = mContext.getString(R.string.ssl_ca_cert_noti_managed,
+                    getDeviceOwnerName());
+            smallIconId = R.drawable.stat_sys_certificate_info;
+        } else {
+            contentText = mContext.getString(R.string.ssl_ca_cert_noti_by_unknown);
+            smallIconId = android.R.drawable.stat_sys_warning;
+        }
+
+        Intent dialogIntent = new Intent(Settings.ACTION_MONITORING_CERT_INFO);
+        dialogIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+        dialogIntent.setPackage("com.android.settings");
+        // Notification will be sent individually to all users. The activity should start as
+        // whichever user is current when it starts.
+        PendingIntent notifyIntent = PendingIntent.getActivityAsUser(mContext, 0, dialogIntent,
+                PendingIntent.FLAG_UPDATE_CURRENT, null, UserHandle.CURRENT);
+
+        Notification noti = new Notification.Builder(mContext)
+            .setSmallIcon(smallIconId)
+            .setContentTitle(mContext.getString(R.string.ssl_ca_cert_warning))
+            .setContentText(contentText)
+            .setContentIntent(notifyIntent)
+            .setPriority(Notification.PRIORITY_HIGH)
+            .setShowWhen(false)
+            .build();
+
+        // If this is a boot intent, this will fire for each user. But if this is a storage changed
+        // intent, it will fire once, so we need to notify all users.
+        if (intent.getAction().equals(KeyChain.ACTION_STORAGE_CHANGED)) {
+            UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+            for (UserInfo user : um.getUsers()) {
+                notificationManager.notifyAsUser(
+                        null, MONITORING_CERT_NOTIFICATION_ID, noti, user.getUserHandle());
+            }
+        } else {
+            notificationManager.notifyAsUser(
+                    null, MONITORING_CERT_NOTIFICATION_ID, noti, UserHandle.CURRENT);
+        }
+    }
+
     /**
      * @param adminReceiver The admin to add
      * @param refreshing true = update an active admin, no error
      */
     public void setActiveAdmin(ComponentName adminReceiver, boolean refreshing, int userHandle) {
         mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.BIND_DEVICE_ADMIN, null);
+                android.Manifest.permission.MANAGE_DEVICE_ADMINS, null);
         enforceCrossUserPermission(userHandle);
 
         DevicePolicyData policy = getUserData(userHandle);
@@ -1146,7 +1241,7 @@
                     return;
                 }
                 mContext.enforceCallingOrSelfPermission(
-                        android.Manifest.permission.BIND_DEVICE_ADMIN, null);
+                        android.Manifest.permission.MANAGE_DEVICE_ADMINS, null);
             }
             long ident = Binder.clearCallingIdentity();
             try {
@@ -1870,6 +1965,76 @@
         return !"".equals(state);
     }
 
+    public boolean installCaCert(byte[] certBuffer) throws RemoteException {
+        mContext.enforceCallingOrSelfPermission(MANAGE_CA_CERTIFICATES, null);
+        KeyChainConnection keyChainConnection = null;
+        byte[] pemCert;
+        try {
+            X509Certificate cert = parseCert(certBuffer);
+            pemCert =  Credentials.convertToPem(cert);
+        } catch (CertificateException ce) {
+            Log.e(TAG, "Problem converting cert", ce);
+            return false;
+        } catch (IOException ioe) {
+            Log.e(TAG, "Problem reading cert", ioe);
+            return false;
+        }
+        try {
+            keyChainConnection = KeyChain.bind(mContext);
+            try {
+                keyChainConnection.getService().installCaCertificate(pemCert);
+                return true;
+            } finally {
+                if (keyChainConnection != null) {
+                    keyChainConnection.close();
+                    keyChainConnection = null;
+                }
+            }
+        } catch (InterruptedException e1) {
+            Log.w(TAG, "installCaCertsToKeyChain(): ", e1);
+            Thread.currentThread().interrupt();
+        }
+        return false;
+    }
+
+    private static X509Certificate parseCert(byte[] certBuffer)
+            throws CertificateException, IOException {
+        CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
+        return (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(
+                certBuffer));
+    }
+
+    public void uninstallCaCert(final byte[] certBuffer) {
+        mContext.enforceCallingOrSelfPermission(MANAGE_CA_CERTIFICATES, null);
+        TrustedCertificateStore certStore = new TrustedCertificateStore();
+        String alias = null;
+        try {
+            X509Certificate cert = parseCert(certBuffer);
+            alias = certStore.getCertificateAlias(cert);
+        } catch (CertificateException ce) {
+            Log.e(TAG, "Problem creating X509Certificate", ce);
+            return;
+        } catch (IOException ioe) {
+            Log.e(TAG, "Problem reading certificate", ioe);
+            return;
+        }
+        try {
+            KeyChainConnection keyChainConnection = KeyChain.bind(mContext);
+            IKeyChainService service = keyChainConnection.getService();
+            try {
+                service.deleteCaCertificate(alias);
+            } catch (RemoteException e) {
+                Log.e(TAG, "from CaCertUninstaller: ", e);
+            } finally {
+                keyChainConnection.close();
+                keyChainConnection = null;
+            }
+        } catch (InterruptedException ie) {
+            Log.w(TAG, "CaCertUninstaller: ", ie);
+            Thread.currentThread().interrupt();
+        }
+    }
+
     void wipeDataLocked(int flags) {
         // If the SD card is encrypted and non-removable, we have to force a wipe.
         boolean forceExtWipe = !Environment.isExternalStorageRemovable() && isExtStorageEncrypted();
@@ -2378,7 +2543,7 @@
     }
 
     @Override
-    public boolean setDeviceOwner(String packageName) {
+    public boolean setDeviceOwner(String packageName, String ownerName) {
         if (packageName == null
                 || !DeviceOwner.isInstalled(packageName, mContext.getPackageManager())) {
             throw new IllegalArgumentException("Invalid package name " + packageName
@@ -2386,7 +2551,7 @@
         }
         synchronized (this) {
             if (mDeviceOwner == null && !isDeviceProvisioned()) {
-                mDeviceOwner = new DeviceOwner(packageName);
+                mDeviceOwner = new DeviceOwner(packageName, ownerName);
                 mDeviceOwner.writeOwnerFile();
                 return true;
             } else {
@@ -2415,6 +2580,17 @@
         return null;
     }
 
+    @Override
+    public String getDeviceOwnerName() {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
+        synchronized (this) {
+            if (mDeviceOwner != null) {
+                return mDeviceOwner.getName();
+            }
+        }
+        return null;
+    }
+
     private boolean isDeviceProvisioned() {
         return Settings.Global.getInt(mContext.getContentResolver(),
                 Settings.Global.DEVICE_PROVISIONED, 0) > 0;
@@ -2488,15 +2664,18 @@
     static class DeviceOwner {
         private static final String DEVICE_OWNER_XML = "device_owner.xml";
         private static final String TAG_DEVICE_OWNER = "device-owner";
+        private static final String ATTR_NAME = "name";
         private static final String ATTR_PACKAGE = "package";
         private String mPackageName;
+        private String mOwnerName;
 
         DeviceOwner() {
             readOwnerFile();
         }
 
-        DeviceOwner(String packageName) {
+        DeviceOwner(String packageName, String ownerName) {
             this.mPackageName = packageName;
+            this.mOwnerName = ownerName;
         }
 
         static boolean isRegistered() {
@@ -2508,6 +2687,10 @@
             return mPackageName;
         }
 
+        String getName() {
+            return mOwnerName;
+        }
+
         static boolean isInstalled(String packageName, PackageManager pm) {
             try {
                 PackageInfo pi;
@@ -2539,6 +2722,7 @@
                             "Device Owner file does not start with device-owner tag: found " + tag);
                 }
                 mPackageName = parser.getAttributeValue(null, ATTR_PACKAGE);
+                mOwnerName = parser.getAttributeValue(null, ATTR_NAME);
                 input.close();
             } catch (XmlPullParserException xppe) {
                 Slog.e(TAG, "Error parsing device-owner file\n" + xppe);
@@ -2563,6 +2747,9 @@
                 out.startDocument(null, true);
                 out.startTag(null, TAG_DEVICE_OWNER);
                 out.attribute(null, ATTR_PACKAGE, mPackageName);
+                if (mOwnerName != null) {
+                    out.attribute(null, ATTR_NAME, mOwnerName);
+                }
                 out.endTag(null, TAG_DEVICE_OWNER);
                 out.endDocument();
                 out.flush();
diff --git a/services/java/com/android/server/DropBoxManagerService.java b/services/java/com/android/server/DropBoxManagerService.java
index 5008270..29b04da 100644
--- a/services/java/com/android/server/DropBoxManagerService.java
+++ b/services/java/com/android/server/DropBoxManagerService.java
@@ -24,6 +24,7 @@
 import android.content.pm.PackageManager;
 import android.database.ContentObserver;
 import android.net.Uri;
+import android.os.Binder;
 import android.os.Debug;
 import android.os.DropBoxManager;
 import android.os.FileUtils;
@@ -265,8 +266,13 @@
     }
 
     public boolean isTagEnabled(String tag) {
-        return !"disabled".equals(Settings.Global.getString(
-                mContentResolver, Settings.Global.DROPBOX_TAG_PREFIX + tag));
+        final long token = Binder.clearCallingIdentity();
+        try {
+            return !"disabled".equals(Settings.Global.getString(
+                    mContentResolver, Settings.Global.DROPBOX_TAG_PREFIX + tag));
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
     }
 
     public synchronized DropBoxManager.Entry getNextEntry(String tag, long millis) {
diff --git a/services/java/com/android/server/FgThread.java b/services/java/com/android/server/FgThread.java
new file mode 100644
index 0000000..3b655f2
--- /dev/null
+++ b/services/java/com/android/server/FgThread.java
@@ -0,0 +1,65 @@
+/*
+ * 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.server;
+
+import android.os.Handler;
+import android.os.HandlerThread;
+
+/**
+ * Shared singleton foreground thread for the system.  This is a thread for regular
+ * foreground service operations, which shouldn't be blocked by anything running in
+ * the background.  In particular, the shared background thread could be doing
+ * relatively long-running operations like saving state to disk (in addition to
+ * simply being a background priority), which can cause operations scheduled on it
+ * to be delayed for a user-noticeable amount of time.
+ */
+public final class FgThread extends HandlerThread {
+    private static FgThread sInstance;
+    private static Handler sHandler;
+
+    private FgThread() {
+        super("android.fg", android.os.Process.THREAD_PRIORITY_DEFAULT);
+    }
+
+    private static void ensureThreadLocked() {
+        if (sInstance == null) {
+            sInstance = new FgThread();
+            sInstance.start();
+            sHandler = new Handler(sInstance.getLooper());
+            sHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    android.os.Process.setCanSelfBackground(false);
+                }
+            });
+        }
+    }
+
+    public static FgThread get() {
+        synchronized (UiThread.class) {
+            ensureThreadLocked();
+            return sInstance;
+        }
+    }
+
+    public static Handler getHandler() {
+        synchronized (UiThread.class) {
+            ensureThreadLocked();
+            return sHandler;
+        }
+    }
+}
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index c916857..45c614f 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -791,6 +791,11 @@
         // InputMethodFileManager should be reset when the user is changed
         mFileManager = new InputMethodFileManager(mMethodMap, newUserId);
         final String defaultImiId = mSettings.getSelectedInputMethod();
+        // For secondary users, the list of enabled IMEs may not have been updated since the
+        // callbacks to PackageMonitor are ignored for the secondary user. Here, defaultImiId may
+        // not be empty even if the IME has been uninstalled by the primary user.
+        // Even in such cases, IMMS works fine because it will find the most applicable
+        // IME for that user.
         final boolean initialUserSwitch = TextUtils.isEmpty(defaultImiId);
         if (DEBUG) {
             Slog.d(TAG, "Switch user: " + newUserId + " current ime = " + defaultImiId);
@@ -818,7 +823,7 @@
         }
     }
 
-    public void systemReady(StatusBarManagerService statusBar) {
+    public void systemRunning(StatusBarManagerService statusBar) {
         synchronized (mMethodMap) {
             if (DEBUG) {
                 Slog.d(TAG, "--- systemReady");
@@ -894,7 +899,8 @@
             Slog.d(TAG, "--- calledFromForegroundUserOrSystemProcess ? "
                     + "calling uid = " + uid + " system uid = " + Process.SYSTEM_UID
                     + " calling userId = " + userId + ", foreground user id = "
-                    + mSettings.getCurrentUserId() + ", calling pid = " + Binder.getCallingPid());
+                    + mSettings.getCurrentUserId() + ", calling pid = " + Binder.getCallingPid()
+                    + InputMethodUtils.getApiCallStack());
         }
         if (uid == Process.SYSTEM_UID || userId == mSettings.getCurrentUserId()) {
             return true;
@@ -914,7 +920,8 @@
             }
             return true;
         }
-        Slog.w(TAG, "--- IPC called from background users. Ignore. \n" + getStackTrace());
+        Slog.w(TAG, "--- IPC called from background users. Ignore. \n"
+                + InputMethodUtils.getStackTrace());
         return false;
     }
 
@@ -962,19 +969,25 @@
     }
 
     /**
-     * @param imi if null, returns enabled subtypes for the current imi
+     * @param imiId if null, returns enabled subtypes for the current imi
      * @return enabled subtypes of the specified imi
      */
     @Override
-    public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(InputMethodInfo imi,
+    public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(String imiId,
             boolean allowsImplicitlySelectedSubtypes) {
         // TODO: Make this work even for non-current users?
         if (!calledFromValidUser()) {
-            return Collections.emptyList();
+            return Collections.<InputMethodSubtype>emptyList();
         }
         synchronized (mMethodMap) {
-            if (imi == null && mCurMethodId != null) {
+            final InputMethodInfo imi;
+            if (imiId == null && mCurMethodId != null) {
                 imi = mMethodMap.get(mCurMethodId);
+            } else {
+                imi = mMethodMap.get(imiId);
+            }
+            if (imi == null) {
+                return Collections.<InputMethodSubtype>emptyList();
             }
             return mSettings.getEnabledInputMethodSubtypeListLocked(
                     mContext, imi, allowsImplicitlySelectedSubtypes);
@@ -1205,7 +1218,7 @@
         mCurIntent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
                 mContext, 0, new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS), 0));
         if (bindCurrentInputMethodService(mCurIntent, this, Context.BIND_AUTO_CREATE
-                | Context.BIND_NOT_VISIBLE)) {
+                | Context.BIND_NOT_VISIBLE | Context.BIND_SHOWING_UI)) {
             mLastBindTime = SystemClock.uptimeMillis();
             mHaveConnection = true;
             mCurId = info.getId();
@@ -1506,23 +1519,16 @@
                 final InputMethodInfo imi = mMethodMap.get(mCurMethodId);
                 if (imi != null && iconVisibility && needsToShowImeSwitchOngoingNotification()) {
                     // Used to load label
-                    final PackageManager pm = mContext.getPackageManager();
                     final CharSequence title = mRes.getText(
                             com.android.internal.R.string.select_input_method);
-                    final CharSequence imiLabel = imi.loadLabel(pm);
-                    final CharSequence summary = mCurrentSubtype != null
-                            ? TextUtils.concat(mCurrentSubtype.getDisplayName(mContext,
-                                        imi.getPackageName(), imi.getServiceInfo().applicationInfo),
-                                                (TextUtils.isEmpty(imiLabel) ?
-                                                        "" : " - " + imiLabel))
-                            : imiLabel;
+                    final CharSequence summary = InputMethodUtils.getImeAndSubtypeDisplayName(
+                            mContext, imi, mCurrentSubtype);
 
                     mImeSwitcherNotification.setLatestEventInfo(
                             mContext, title, summary, mImeSwitchPendingIntent);
                     if (mNotificationManager != null) {
                         if (DEBUG) {
-                            Slog.d(TAG, "--- show notification: label =  " + imiLabel
-                                    + ", summary = " + summary);
+                            Slog.d(TAG, "--- show notification: label =  " + summary);
                         }
                         mNotificationManager.notifyAsUser(null,
                                 com.android.internal.R.string.select_input_method,
@@ -2153,6 +2159,21 @@
     }
 
     @Override
+    public boolean shouldOfferSwitchingToNextInputMethod(IBinder token) {
+        if (!calledFromValidUser()) {
+            return false;
+        }
+        synchronized (mMethodMap) {
+            final ImeSubtypeListItem nextSubtype = mImListManager.getNextInputMethod(
+                    false /* onlyCurrentIme */, mMethodMap.get(mCurMethodId), mCurrentSubtype);
+            if (nextSubtype == null) {
+                return false;
+            }
+            return true;
+        }
+    }
+
+    @Override
     public InputMethodSubtype getLastInputMethodSubtype() {
         if (!calledFromValidUser()) {
             return null;
@@ -2475,7 +2496,7 @@
             HashMap<String, InputMethodInfo> map, boolean resetDefaultEnabledIme) {
         if (DEBUG) {
             Slog.d(TAG, "--- re-buildInputMethodList reset = " + resetDefaultEnabledIme
-                    + " \n ------ \n" + getStackTrace());
+                    + " \n ------ \n" + InputMethodUtils.getStackTrace());
         }
         list.clear();
         map.clear();
@@ -3470,22 +3491,6 @@
         }
     }
 
-    // ----------------------------------------------------------------------
-    // Utilities for debug
-    private static String getStackTrace() {
-        final StringBuilder sb = new StringBuilder();
-        try {
-            throw new RuntimeException();
-        } catch (RuntimeException e) {
-            final StackTraceElement[] frames = e.getStackTrace();
-            // Start at 1 because the first frame is here and we don't care about it
-            for (int j = 1; j < frames.length; ++j) {
-                sb.append(frames[j].toString() + "\n");
-            }
-        }
-        return sb.toString();
-    }
-
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
diff --git a/services/java/com/android/server/IntentResolver.java b/services/java/com/android/server/IntentResolver.java
index 35345f5..3a35f3f 100644
--- a/services/java/com/android/server/IntentResolver.java
+++ b/services/java/com/android/server/IntentResolver.java
@@ -20,7 +20,6 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -29,12 +28,12 @@
 
 import android.net.Uri;
 import android.util.FastImmutableArraySet;
+import android.util.ArrayMap;
 import android.util.Log;
 import android.util.PrintWriterPrinter;
 import android.util.Slog;
 import android.util.LogPrinter;
 import android.util.Printer;
-import android.util.StringBuilderPrinter;
 
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -46,7 +45,6 @@
     final private static String TAG = "IntentResolver";
     final private static boolean DEBUG = false;
     final private static boolean localLOGV = DEBUG || false;
-    final private static boolean VALIDATE = false;
 
     public void addFilter(F f) {
         if (localLOGV) {
@@ -67,21 +65,11 @@
             register_intent_filter(f, f.actionsIterator(),
                     mTypedActionToFilter, "      TypedAction: ");
         }
-
-        if (VALIDATE) {
-            mOldResolver.addFilter(f);
-            verifyDataStructures(f);
-        }
     }
 
     public void removeFilter(F f) {
         removeFilterInternal(f);
         mFilters.remove(f);
-
-        if (VALIDATE) {
-            mOldResolver.removeFilter(f);
-            verifyDataStructures(f);
-        }
     }
 
     void removeFilterInternal(F f) {
@@ -319,16 +307,6 @@
         }
         sortResults(finalList);
 
-        if (VALIDATE) {
-            List<R> oldList = mOldResolver.queryIntent(intent, resolvedType, defaultOnly, userId);
-            if (oldList.size() != finalList.size()) {
-                ValidationFailure here = new ValidationFailure();
-                here.fillInStackTrace();
-                Log.wtf(TAG, "Query result " + intent + " size is " + finalList.size()
-                        + "; old implementation is " + oldList.size(), here);
-            }
-        }
-
         if (debug) {
             Slog.v(TAG, "Final result list:");
             for (R r : finalList) {
@@ -379,7 +357,7 @@
         out.print(prefix); out.println(filter);
     }
 
-    private final void addFilter(HashMap<String, F[]> map, String name, F filter) {
+    private final void addFilter(ArrayMap<String, F[]> map, String name, F filter) {
         F[] array = map.get(name);
         if (array == null) {
             array = newArray(2);
@@ -464,7 +442,7 @@
     }
 
     private final int register_intent_filter(F filter, Iterator<String> i,
-            HashMap<String, F[]> dest, String prefix) {
+            ArrayMap<String, F[]> dest, String prefix) {
         if (i == null) {
             return 0;
         }
@@ -480,7 +458,7 @@
     }
 
     private final int unregister_intent_filter(F filter, Iterator<String> i,
-            HashMap<String, F[]> dest, String prefix) {
+            ArrayMap<String, F[]> dest, String prefix) {
         if (i == null) {
             return 0;
         }
@@ -495,7 +473,7 @@
         return num;
     }
 
-    private final void remove_all_objects(HashMap<String, F[]> map, String name,
+    private final void remove_all_objects(ArrayMap<String, F[]> map, String name,
             Object object) {
         F[] array = map.get(name);
         if (array != null) {
@@ -613,120 +591,6 @@
         }
     };
 
-    static class ValidationFailure extends RuntimeException {
-    }
-
-    private void verifyDataStructures(IntentFilter src) {
-        compareMaps(src, "mTypeToFilter", mTypeToFilter, mOldResolver.mTypeToFilter);
-        compareMaps(src, "mBaseTypeToFilter", mBaseTypeToFilter, mOldResolver.mBaseTypeToFilter);
-        compareMaps(src, "mWildTypeToFilter", mWildTypeToFilter, mOldResolver.mWildTypeToFilter);
-        compareMaps(src, "mSchemeToFilter", mSchemeToFilter, mOldResolver.mSchemeToFilter);
-        compareMaps(src, "mActionToFilter", mActionToFilter, mOldResolver.mActionToFilter);
-        compareMaps(src, "mTypedActionToFilter", mTypedActionToFilter, mOldResolver.mTypedActionToFilter);
-    }
-
-    private void compareMaps(IntentFilter src, String name, HashMap<String, F[]> cur,
-            HashMap<String, ArrayList<F>> old) {
-        if (cur.size() != old.size()) {
-            StringBuilder missing = new StringBuilder(128);
-            for (Map.Entry<String, ArrayList<F>> e : old.entrySet()) {
-                final F[] curArray = cur.get(e.getKey());
-                if (curArray == null) {
-                    if (missing.length() > 0) {
-                        missing.append(' ');
-                    }
-                    missing.append(e.getKey());
-                }
-            }
-            StringBuilder extra = new StringBuilder(128);
-            for (Map.Entry<String, F[]> e : cur.entrySet()) {
-                if (old.get(e.getKey()) == null) {
-                    if (extra.length() > 0) {
-                        extra.append(' ');
-                    }
-                    extra.append(e.getKey());
-                }
-            }
-            StringBuilder srcStr = new StringBuilder(1024);
-            StringBuilderPrinter printer = new StringBuilderPrinter(srcStr);
-            src.dump(printer, "");
-            ValidationFailure here = new ValidationFailure();
-            here.fillInStackTrace();
-            Log.wtf(TAG, "New map " + name + " size is " + cur.size()
-                    + "; old implementation is " + old.size()
-                    + "; missing: " + missing.toString()
-                    + "; extra: " + extra.toString()
-                    + "; src: " + srcStr.toString(), here);
-            return;
-        }
-        for (Map.Entry<String, ArrayList<F>> e : old.entrySet()) {
-            final F[] curArray = cur.get(e.getKey());
-            int curLen = curArray != null ? curArray.length : 0;
-            if (curLen == 0) {
-                ValidationFailure here = new ValidationFailure();
-                here.fillInStackTrace();
-                Log.wtf(TAG, "New map " + name + " doesn't contain expected key "
-                        + e.getKey() + " (array=" + curArray + ")");
-                return;
-            }
-            while (curLen > 0 && curArray[curLen-1] == null) {
-                curLen--;
-            }
-            final ArrayList<F> oldArray = e.getValue();
-            final int oldLen = oldArray.size();
-            if (curLen != oldLen) {
-                ValidationFailure here = new ValidationFailure();
-                here.fillInStackTrace();
-                Log.wtf(TAG, "New map " + name + " entry " + e.getKey() + " size is "
-                        + curLen + "; old implementation is " + oldLen, here);
-                return;
-            }
-            for (int i=0; i<oldLen; i++) {
-                F f = oldArray.get(i);
-                boolean found = false;
-                for (int j=0; j<curLen; j++) {
-                    if (curArray[j] == f) {
-                        found = true;
-                        break;
-                    }
-                }
-                if (!found) {
-                    ValidationFailure here = new ValidationFailure();
-                    here.fillInStackTrace();
-                    Log.wtf(TAG, "New map " + name + " entry + " + e.getKey()
-                            + " doesn't contain expected filter " + f, here);
-                }
-            }
-            for (int i=0; i<curLen; i++) {
-                if (curArray[i] == null) {
-                    ValidationFailure here = new ValidationFailure();
-                    here.fillInStackTrace();
-                    Log.wtf(TAG, "New map " + name + " entry + " + e.getKey()
-                            + " has unexpected null at " + i + "; array: " + curArray, here);
-                    break;
-                }
-            }
-        }
-    }
-
-    private final IntentResolverOld<F, R> mOldResolver = new IntentResolverOld<F, R>() {
-        @Override protected boolean isPackageForFilter(String packageName, F filter) {
-            return IntentResolver.this.isPackageForFilter(packageName, filter);
-        }
-        @Override protected boolean allowFilterResult(F filter, List<R> dest) {
-            return IntentResolver.this.allowFilterResult(filter, dest);
-        }
-        @Override protected boolean isFilterStopped(F filter, int userId) {
-            return IntentResolver.this.isFilterStopped(filter, userId);
-        }
-        @Override protected R newResult(F filter, int match, int userId) {
-            return IntentResolver.this.newResult(filter, match, userId);
-        }
-        @Override protected void sortResults(List<R> results) {
-            IntentResolver.this.sortResults(results);
-        }
-    };
-
     /**
      * All filters that have been registered.
      */
@@ -736,14 +600,14 @@
      * All of the MIME types that have been registered, such as "image/jpeg",
      * "image/*", or "{@literal *}/*".
      */
-    private final HashMap<String, F[]> mTypeToFilter = new HashMap<String, F[]>();
+    private final ArrayMap<String, F[]> mTypeToFilter = new ArrayMap<String, F[]>();
 
     /**
      * The base names of all of all fully qualified MIME types that have been
      * registered, such as "image" or "*".  Wild card MIME types such as
      * "image/*" will not be here.
      */
-    private final HashMap<String, F[]> mBaseTypeToFilter = new HashMap<String, F[]>();
+    private final ArrayMap<String, F[]> mBaseTypeToFilter = new ArrayMap<String, F[]>();
 
     /**
      * The base names of all of the MIME types with a sub-type wildcard that
@@ -752,21 +616,21 @@
      * included here.  This also includes the "*" for the "{@literal *}/*"
      * MIME type.
      */
-    private final HashMap<String, F[]> mWildTypeToFilter = new HashMap<String, F[]>();
+    private final ArrayMap<String, F[]> mWildTypeToFilter = new ArrayMap<String, F[]>();
 
     /**
      * All of the URI schemes (such as http) that have been registered.
      */
-    private final HashMap<String, F[]> mSchemeToFilter = new HashMap<String, F[]>();
+    private final ArrayMap<String, F[]> mSchemeToFilter = new ArrayMap<String, F[]>();
 
     /**
      * All of the actions that have been registered, but only those that did
      * not specify data.
      */
-    private final HashMap<String, F[]> mActionToFilter = new HashMap<String, F[]>();
+    private final ArrayMap<String, F[]> mActionToFilter = new ArrayMap<String, F[]>();
 
     /**
      * All of the actions that have been registered and specified a MIME type.
      */
-    private final HashMap<String, F[]> mTypedActionToFilter = new HashMap<String, F[]>();
+    private final ArrayMap<String, F[]> mTypedActionToFilter = new ArrayMap<String, F[]>();
 }
diff --git a/services/java/com/android/server/IntentResolverOld.java b/services/java/com/android/server/IntentResolverOld.java
deleted file mode 100644
index 94a2379..0000000
--- a/services/java/com/android/server/IntentResolverOld.java
+++ /dev/null
@@ -1,638 +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 com.android.server;
-
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import android.net.Uri;
-import android.util.FastImmutableArraySet;
-import android.util.Log;
-import android.util.PrintWriterPrinter;
-import android.util.Slog;
-import android.util.LogPrinter;
-import android.util.Printer;
-
-import android.content.Intent;
-import android.content.IntentFilter;
-
-/**
- * Temporary for verification of new implementation.
- * {@hide}
- */
-public abstract class IntentResolverOld<F extends IntentFilter, R extends Object> {
-    final private static String TAG = "IntentResolver";
-    final private static boolean DEBUG = false;
-    final private static boolean localLOGV = DEBUG || false;
-
-    public void addFilter(F f) {
-        if (localLOGV) {
-            Slog.v(TAG, "Adding filter: " + f);
-            f.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "      ");
-            Slog.v(TAG, "    Building Lookup Maps:");
-        }
-
-        mFilters.add(f);
-        int numS = register_intent_filter(f, f.schemesIterator(),
-                mSchemeToFilter, "      Scheme: ");
-        int numT = register_mime_types(f, "      Type: ");
-        if (numS == 0 && numT == 0) {
-            register_intent_filter(f, f.actionsIterator(),
-                    mActionToFilter, "      Action: ");
-        }
-        if (numT != 0) {
-            register_intent_filter(f, f.actionsIterator(),
-                    mTypedActionToFilter, "      TypedAction: ");
-        }
-    }
-
-    public void removeFilter(F f) {
-        removeFilterInternal(f);
-        mFilters.remove(f);
-    }
-
-    void removeFilterInternal(F f) {
-        if (localLOGV) {
-            Slog.v(TAG, "Removing filter: " + f);
-            f.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "      ");
-            Slog.v(TAG, "    Cleaning Lookup Maps:");
-        }
-
-        int numS = unregister_intent_filter(f, f.schemesIterator(),
-                mSchemeToFilter, "      Scheme: ");
-        int numT = unregister_mime_types(f, "      Type: ");
-        if (numS == 0 && numT == 0) {
-            unregister_intent_filter(f, f.actionsIterator(),
-                    mActionToFilter, "      Action: ");
-        }
-        if (numT != 0) {
-            unregister_intent_filter(f, f.actionsIterator(),
-                    mTypedActionToFilter, "      TypedAction: ");
-        }
-    }
-
-    boolean dumpMap(PrintWriter out, String titlePrefix, String title,
-            String prefix, Map<String, ArrayList<F>> map, String packageName,
-            boolean printFilter) {
-        String eprefix = prefix + "  ";
-        String fprefix = prefix + "    ";
-        boolean printedSomething = false;
-        Printer printer = null;
-        for (Map.Entry<String, ArrayList<F>> e : map.entrySet()) {
-            ArrayList<F> a = e.getValue();
-            final int N = a.size();
-            boolean printedHeader = false;
-            for (int i=0; i<N; i++) {
-                F filter = a.get(i);
-                if (packageName != null && !isPackageForFilter(packageName, filter)) {
-                    continue;
-                }
-                if (title != null) {
-                    out.print(titlePrefix); out.println(title);
-                    title = null;
-                }
-                if (!printedHeader) {
-                    out.print(eprefix); out.print(e.getKey()); out.println(":");
-                    printedHeader = true;
-                }
-                printedSomething = true;
-                dumpFilter(out, fprefix, filter);
-                if (printFilter) {
-                    if (printer == null) {
-                        printer = new PrintWriterPrinter(out);
-                    }
-                    filter.dump(printer, fprefix + "  ");
-                }
-            }
-        }
-        return printedSomething;
-    }
-
-    public boolean dump(PrintWriter out, String title, String prefix, String packageName,
-            boolean printFilter) {
-        String innerPrefix = prefix + "  ";
-        String sepPrefix = "\n" + prefix;
-        String curPrefix = title + "\n" + prefix;
-        if (dumpMap(out, curPrefix, "Full MIME Types:", innerPrefix,
-                mTypeToFilter, packageName, printFilter)) {
-            curPrefix = sepPrefix;
-        }
-        if (dumpMap(out, curPrefix, "Base MIME Types:", innerPrefix,
-                mBaseTypeToFilter, packageName, printFilter)) {
-            curPrefix = sepPrefix;
-        }
-        if (dumpMap(out, curPrefix, "Wild MIME Types:", innerPrefix,
-                mWildTypeToFilter, packageName, printFilter)) {
-            curPrefix = sepPrefix;
-        }
-        if (dumpMap(out, curPrefix, "Schemes:", innerPrefix,
-                mSchemeToFilter, packageName, printFilter)) {
-            curPrefix = sepPrefix;
-        }
-        if (dumpMap(out, curPrefix, "Non-Data Actions:", innerPrefix,
-                mActionToFilter, packageName, printFilter)) {
-            curPrefix = sepPrefix;
-        }
-        if (dumpMap(out, curPrefix, "MIME Typed Actions:", innerPrefix,
-                mTypedActionToFilter, packageName, printFilter)) {
-            curPrefix = sepPrefix;
-        }
-        return curPrefix == sepPrefix;
-    }
-
-    private class IteratorWrapper implements Iterator<F> {
-        private final Iterator<F> mI;
-        private F mCur;
-
-        IteratorWrapper(Iterator<F> it) {
-            mI = it;
-        }
-
-        public boolean hasNext() {
-            return mI.hasNext();
-        }
-
-        public F next() {
-            return (mCur = mI.next());
-        }
-
-        public void remove() {
-            if (mCur != null) {
-                removeFilterInternal(mCur);
-            }
-            mI.remove();
-        }
-
-    }
-
-    /**
-     * Returns an iterator allowing filters to be removed.
-     */
-    public Iterator<F> filterIterator() {
-        return new IteratorWrapper(mFilters.iterator());
-    }
-
-    /**
-     * Returns a read-only set of the filters.
-     */
-    public Set<F> filterSet() {
-        return Collections.unmodifiableSet(mFilters);
-    }
-
-    public List<R> queryIntentFromList(Intent intent, String resolvedType, 
-            boolean defaultOnly, ArrayList<ArrayList<F>> listCut, int userId) {
-        ArrayList<R> resultList = new ArrayList<R>();
-
-        final boolean debug = localLOGV ||
-                ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
-
-        FastImmutableArraySet<String> categories = getFastIntentCategories(intent);
-        final String scheme = intent.getScheme();
-        int N = listCut.size();
-        for (int i = 0; i < N; ++i) {
-            buildResolveList(intent, categories, debug, defaultOnly,
-                    resolvedType, scheme, listCut.get(i), resultList, userId);
-        }
-        sortResults(resultList);
-        return resultList;
-    }
-
-    public List<R> queryIntent(Intent intent, String resolvedType, boolean defaultOnly,
-            int userId) {
-        String scheme = intent.getScheme();
-
-        ArrayList<R> finalList = new ArrayList<R>();
-
-        final boolean debug = localLOGV ||
-                ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
-
-        if (debug) Slog.v(
-            TAG, "Resolving type " + resolvedType + " scheme " + scheme
-            + " of intent " + intent);
-
-        ArrayList<F> firstTypeCut = null;
-        ArrayList<F> secondTypeCut = null;
-        ArrayList<F> thirdTypeCut = null;
-        ArrayList<F> schemeCut = null;
-
-        // If the intent includes a MIME type, then we want to collect all of
-        // the filters that match that MIME type.
-        if (resolvedType != null) {
-            int slashpos = resolvedType.indexOf('/');
-            if (slashpos > 0) {
-                final String baseType = resolvedType.substring(0, slashpos);
-                if (!baseType.equals("*")) {
-                    if (resolvedType.length() != slashpos+2
-                            || resolvedType.charAt(slashpos+1) != '*') {
-                        // Not a wild card, so we can just look for all filters that
-                        // completely match or wildcards whose base type matches.
-                        firstTypeCut = mTypeToFilter.get(resolvedType);
-                        if (debug) Slog.v(TAG, "First type cut: " + firstTypeCut);
-                        secondTypeCut = mWildTypeToFilter.get(baseType);
-                        if (debug) Slog.v(TAG, "Second type cut: " + secondTypeCut);
-                    } else {
-                        // We can match anything with our base type.
-                        firstTypeCut = mBaseTypeToFilter.get(baseType);
-                        if (debug) Slog.v(TAG, "First type cut: " + firstTypeCut);
-                        secondTypeCut = mWildTypeToFilter.get(baseType);
-                        if (debug) Slog.v(TAG, "Second type cut: " + secondTypeCut);
-                    }
-                    // Any */* types always apply, but we only need to do this
-                    // if the intent type was not already */*.
-                    thirdTypeCut = mWildTypeToFilter.get("*");
-                    if (debug) Slog.v(TAG, "Third type cut: " + thirdTypeCut);
-                } else if (intent.getAction() != null) {
-                    // The intent specified any type ({@literal *}/*).  This
-                    // can be a whole heck of a lot of things, so as a first
-                    // cut let's use the action instead.
-                    firstTypeCut = mTypedActionToFilter.get(intent.getAction());
-                    if (debug) Slog.v(TAG, "Typed Action list: " + firstTypeCut);
-                }
-            }
-        }
-
-        // If the intent includes a data URI, then we want to collect all of
-        // the filters that match its scheme (we will further refine matches
-        // on the authority and path by directly matching each resulting filter).
-        if (scheme != null) {
-            schemeCut = mSchemeToFilter.get(scheme);
-            if (debug) Slog.v(TAG, "Scheme list: " + schemeCut);
-        }
-
-        // If the intent does not specify any data -- either a MIME type or
-        // a URI -- then we will only be looking for matches against empty
-        // data.
-        if (resolvedType == null && scheme == null && intent.getAction() != null) {
-            firstTypeCut = mActionToFilter.get(intent.getAction());
-            if (debug) Slog.v(TAG, "Action list: " + firstTypeCut);
-        }
-
-        FastImmutableArraySet<String> categories = getFastIntentCategories(intent);
-        if (firstTypeCut != null) {
-            buildResolveList(intent, categories, debug, defaultOnly,
-                    resolvedType, scheme, firstTypeCut, finalList, userId);
-        }
-        if (secondTypeCut != null) {
-            buildResolveList(intent, categories, debug, defaultOnly,
-                    resolvedType, scheme, secondTypeCut, finalList, userId);
-        }
-        if (thirdTypeCut != null) {
-            buildResolveList(intent, categories, debug, defaultOnly,
-                    resolvedType, scheme, thirdTypeCut, finalList, userId);
-        }
-        if (schemeCut != null) {
-            buildResolveList(intent, categories, debug, defaultOnly,
-                    resolvedType, scheme, schemeCut, finalList, userId);
-        }
-        sortResults(finalList);
-
-        if (debug) {
-            Slog.v(TAG, "Final result list:");
-            for (R r : finalList) {
-                Slog.v(TAG, "  " + r);
-            }
-        }
-        return finalList;
-    }
-
-    /**
-     * Control whether the given filter is allowed to go into the result
-     * list.  Mainly intended to prevent adding multiple filters for the
-     * same target object.
-     */
-    protected boolean allowFilterResult(F filter, List<R> dest) {
-        return true;
-    }
-
-    /**
-     * Returns whether the object associated with the given filter is
-     * "stopped," that is whether it should not be included in the result
-     * if the intent requests to excluded stopped objects.
-     */
-    protected boolean isFilterStopped(F filter, int userId) {
-        return false;
-    }
-
-    /**
-     * Returns whether this filter is owned by this package. This must be
-     * implemented to provide correct filtering of Intents that have
-     * specified a package name they are to be delivered to.
-     */
-    protected abstract boolean isPackageForFilter(String packageName, F filter);
-    
-    @SuppressWarnings("unchecked")
-    protected R newResult(F filter, int match, int userId) {
-        return (R)filter;
-    }
-
-    @SuppressWarnings("unchecked")
-    protected void sortResults(List<R> results) {
-        Collections.sort(results, mResolvePrioritySorter);
-    }
-
-    protected void dumpFilter(PrintWriter out, String prefix, F filter) {
-        out.print(prefix); out.println(filter);
-    }
-
-    private final int register_mime_types(F filter, String prefix) {
-        final Iterator<String> i = filter.typesIterator();
-        if (i == null) {
-            return 0;
-        }
-
-        int num = 0;
-        while (i.hasNext()) {
-            String name = i.next();
-            num++;
-            if (localLOGV) Slog.v(TAG, prefix + name);
-            String baseName = name;
-            final int slashpos = name.indexOf('/');
-            if (slashpos > 0) {
-                baseName = name.substring(0, slashpos).intern();
-            } else {
-                name = name + "/*";
-            }
-
-            ArrayList<F> array = mTypeToFilter.get(name);
-            if (array == null) {
-                //Slog.v(TAG, "Creating new array for " + name);
-                array = new ArrayList<F>();
-                mTypeToFilter.put(name, array);
-            }
-            array.add(filter);
-
-            if (slashpos > 0) {
-                array = mBaseTypeToFilter.get(baseName);
-                if (array == null) {
-                    //Slog.v(TAG, "Creating new array for " + name);
-                    array = new ArrayList<F>();
-                    mBaseTypeToFilter.put(baseName, array);
-                }
-                array.add(filter);
-            } else {
-                array = mWildTypeToFilter.get(baseName);
-                if (array == null) {
-                    //Slog.v(TAG, "Creating new array for " + name);
-                    array = new ArrayList<F>();
-                    mWildTypeToFilter.put(baseName, array);
-                }
-                array.add(filter);
-            }
-        }
-
-        return num;
-    }
-
-    private final int unregister_mime_types(F filter, String prefix) {
-        final Iterator<String> i = filter.typesIterator();
-        if (i == null) {
-            return 0;
-        }
-
-        int num = 0;
-        while (i.hasNext()) {
-            String name = i.next();
-            num++;
-            if (localLOGV) Slog.v(TAG, prefix + name);
-            String baseName = name;
-            final int slashpos = name.indexOf('/');
-            if (slashpos > 0) {
-                baseName = name.substring(0, slashpos).intern();
-            } else {
-                name = name + "/*";
-            }
-
-            if (!remove_all_objects(mTypeToFilter.get(name), filter)) {
-                mTypeToFilter.remove(name);
-            }
-
-            if (slashpos > 0) {
-                if (!remove_all_objects(mBaseTypeToFilter.get(baseName), filter)) {
-                    mBaseTypeToFilter.remove(baseName);
-                }
-            } else {
-                if (!remove_all_objects(mWildTypeToFilter.get(baseName), filter)) {
-                    mWildTypeToFilter.remove(baseName);
-                }
-            }
-        }
-        return num;
-    }
-
-    private final int register_intent_filter(F filter, Iterator<String> i,
-            HashMap<String, ArrayList<F>> dest, String prefix) {
-        if (i == null) {
-            return 0;
-        }
-
-        int num = 0;
-        while (i.hasNext()) {
-            String name = i.next();
-            num++;
-            if (localLOGV) Slog.v(TAG, prefix + name);
-            ArrayList<F> array = dest.get(name);
-            if (array == null) {
-                //Slog.v(TAG, "Creating new array for " + name);
-                array = new ArrayList<F>();
-                dest.put(name, array);
-            }
-            array.add(filter);
-        }
-        return num;
-    }
-
-    private final int unregister_intent_filter(F filter, Iterator<String> i,
-            HashMap<String, ArrayList<F>> dest, String prefix) {
-        if (i == null) {
-            return 0;
-        }
-
-        int num = 0;
-        while (i.hasNext()) {
-            String name = i.next();
-            num++;
-            if (localLOGV) Slog.v(TAG, prefix + name);
-            if (!remove_all_objects(dest.get(name), filter)) {
-                dest.remove(name);
-            }
-        }
-        return num;
-    }
-
-    private final boolean remove_all_objects(List<F> list, Object object) {
-        if (list != null) {
-            int N = list.size();
-            for (int idx=0; idx<N; idx++) {
-                if (list.get(idx) == object) {
-                    list.remove(idx);
-                    idx--;
-                    N--;
-                }
-            }
-            return N > 0;
-        }
-        return false;
-    }
-
-    private static FastImmutableArraySet<String> getFastIntentCategories(Intent intent) {
-        final Set<String> categories = intent.getCategories();
-        if (categories == null) {
-            return null;
-        }
-        return new FastImmutableArraySet<String>(categories.toArray(new String[categories.size()]));
-    }
-
-    private void buildResolveList(Intent intent, FastImmutableArraySet<String> categories,
-            boolean debug, boolean defaultOnly,
-            String resolvedType, String scheme, List<F> src, List<R> dest, int userId) {
-        final String action = intent.getAction();
-        final Uri data = intent.getData();
-        final String packageName = intent.getPackage();
-
-        final boolean excludingStopped = intent.isExcludingStopped();
-
-        final int N = src != null ? src.size() : 0;
-        boolean hasNonDefaults = false;
-        int i;
-        for (i=0; i<N; i++) {
-            F filter = src.get(i);
-            int match;
-            if (debug) Slog.v(TAG, "Matching against filter " + filter);
-
-            if (excludingStopped && isFilterStopped(filter, userId)) {
-                if (debug) {
-                    Slog.v(TAG, "  Filter's target is stopped; skipping");
-                }
-                continue;
-            }
-
-            // Is delivery being limited to filters owned by a particular package?
-            if (packageName != null && !isPackageForFilter(packageName, filter)) {
-                if (debug) {
-                    Slog.v(TAG, "  Filter is not from package " + packageName + "; skipping");
-                }
-                continue;
-            }
-
-            // Do we already have this one?
-            if (!allowFilterResult(filter, dest)) {
-                if (debug) {
-                    Slog.v(TAG, "  Filter's target already added");
-                }
-                continue;
-            }
-
-            match = filter.match(action, resolvedType, scheme, data, categories, TAG);
-            if (match >= 0) {
-                if (debug) Slog.v(TAG, "  Filter matched!  match=0x" +
-                        Integer.toHexString(match));
-                if (!defaultOnly || filter.hasCategory(Intent.CATEGORY_DEFAULT)) {
-                    final R oneResult = newResult(filter, match, userId);
-                    if (oneResult != null) {
-                        dest.add(oneResult);
-                    }
-                } else {
-                    hasNonDefaults = true;
-                }
-            } else {
-                if (debug) {
-                    String reason;
-                    switch (match) {
-                        case IntentFilter.NO_MATCH_ACTION: reason = "action"; break;
-                        case IntentFilter.NO_MATCH_CATEGORY: reason = "category"; break;
-                        case IntentFilter.NO_MATCH_DATA: reason = "data"; break;
-                        case IntentFilter.NO_MATCH_TYPE: reason = "type"; break;
-                        default: reason = "unknown reason"; break;
-                    }
-                    Slog.v(TAG, "  Filter did not match: " + reason);
-                }
-            }
-        }
-
-        if (dest.size() == 0 && hasNonDefaults) {
-            Slog.w(TAG, "resolveIntent failed: found match, but none with Intent.CATEGORY_DEFAULT");
-        }
-    }
-
-    // Sorts a List of IntentFilter objects into descending priority order.
-    @SuppressWarnings("rawtypes")
-    private static final Comparator mResolvePrioritySorter = new Comparator() {
-        public int compare(Object o1, Object o2) {
-            final int q1 = ((IntentFilter) o1).getPriority();
-            final int q2 = ((IntentFilter) o2).getPriority();
-            return (q1 > q2) ? -1 : ((q1 < q2) ? 1 : 0);
-        }
-    };
-
-    /**
-     * All filters that have been registered.
-     */
-    final HashSet<F> mFilters = new HashSet<F>();
-
-    /**
-     * All of the MIME types that have been registered, such as "image/jpeg",
-     * "image/*", or "{@literal *}/*".
-     */
-    final HashMap<String, ArrayList<F>> mTypeToFilter
-            = new HashMap<String, ArrayList<F>>();
-
-    /**
-     * The base names of all of all fully qualified MIME types that have been
-     * registered, such as "image" or "*".  Wild card MIME types such as
-     * "image/*" will not be here.
-     */
-    final HashMap<String, ArrayList<F>> mBaseTypeToFilter
-            = new HashMap<String, ArrayList<F>>();
-
-    /**
-     * The base names of all of the MIME types with a sub-type wildcard that
-     * have been registered.  For example, a filter with "image/*" will be
-     * included here as "image" but one with "image/jpeg" will not be
-     * included here.  This also includes the "*" for the "{@literal *}/*"
-     * MIME type.
-     */
-    final HashMap<String, ArrayList<F>> mWildTypeToFilter
-            = new HashMap<String, ArrayList<F>>();
-
-    /**
-     * All of the URI schemes (such as http) that have been registered.
-     */
-    final HashMap<String, ArrayList<F>> mSchemeToFilter
-            = new HashMap<String, ArrayList<F>>();
-
-    /**
-     * All of the actions that have been registered, but only those that did
-     * not specify data.
-     */
-    final HashMap<String, ArrayList<F>> mActionToFilter
-            = new HashMap<String, ArrayList<F>>();
-
-    /**
-     * All of the actions that have been registered and specified a MIME type.
-     */
-    final HashMap<String, ArrayList<F>> mTypedActionToFilter
-            = new HashMap<String, ArrayList<F>>();
-}
-
diff --git a/services/java/com/android/server/IoThread.java b/services/java/com/android/server/IoThread.java
new file mode 100644
index 0000000..09f2af7
--- /dev/null
+++ b/services/java/com/android/server/IoThread.java
@@ -0,0 +1,62 @@
+/*
+ * 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.server;
+
+import android.os.Handler;
+import android.os.HandlerThread;
+
+/**
+ * Shared singleton I/O thread for the system.  This is a thread for non-background
+ * service operations that can potential block briefly on network IO operations
+ * (not waiting for data itself, but communicating with network daemons).
+ */
+public final class IoThread extends HandlerThread {
+    private static IoThread sInstance;
+    private static Handler sHandler;
+
+    private IoThread() {
+        super("android.io", android.os.Process.THREAD_PRIORITY_DEFAULT);
+    }
+
+    private static void ensureThreadLocked() {
+        if (sInstance == null) {
+            sInstance = new IoThread();
+            sInstance.start();
+            sHandler = new Handler(sInstance.getLooper());
+            sHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    android.os.Process.setCanSelfBackground(false);
+                }
+            });
+        }
+    }
+
+    public static IoThread get() {
+        synchronized (IoThread.class) {
+            ensureThreadLocked();
+            return sInstance;
+        }
+    }
+
+    public static Handler getHandler() {
+        synchronized (IoThread.class) {
+            ensureThreadLocked();
+            return sHandler;
+        }
+    }
+}
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index f784030..f70f4db 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -47,7 +47,6 @@
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
-import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
@@ -63,6 +62,9 @@
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.location.ProviderProperties;
 import com.android.internal.location.ProviderRequest;
+import com.android.internal.os.BackgroundThread;
+import com.android.server.location.FlpHardwareProvider;
+import com.android.server.location.FusedProxy;
 import com.android.server.location.GeocoderProxy;
 import com.android.server.location.GeofenceProxy;
 import com.android.server.location.GeofenceManager;
@@ -93,7 +95,6 @@
     public static final boolean D = Log.isLoggable(TAG, Log.DEBUG);
 
     private static final String WAKELOCK_KEY = TAG;
-    private static final String THREAD_NAME = TAG;
 
     // Location resolution level: no location data whatsoever
     private static final int RESOLUTION_LEVEL_NONE = 0;
@@ -110,7 +111,7 @@
             android.Manifest.permission.INSTALL_LOCATION_PROVIDER;
 
     private static final String NETWORK_LOCATION_SERVICE_ACTION =
-            "com.android.location.service.v2.NetworkLocationProvider";
+            "com.android.location.service.v3.NetworkLocationProvider";
     private static final String FUSED_LOCATION_SERVICE_ACTION =
             "com.android.location.service.FusedLocationProvider";
 
@@ -118,6 +119,9 @@
 
     private static final long NANOS_PER_MILLI = 1000000L;
 
+    // The maximum interval a location request can have and still be considered "high power".
+    private static final long HIGH_POWER_INTERVAL_MS = 5 * 60 * 1000;
+
     // Location Providers may sometimes deliver location updates
     // slightly faster that requested - provide grace period so
     // we don't unnecessarily filter events that are otherwise on
@@ -143,7 +147,6 @@
     private LocationWorkerHandler mLocationHandler;
     private PassiveProvider mPassiveProvider;  // track passive provider for special cases
     private LocationBlacklist mBlacklist;
-    private HandlerThread mHandlerThread;
 
     // --- fields below are protected by mLock ---
     // Set of providers that are explicitly enabled
@@ -200,7 +203,7 @@
         // most startup is deferred until systemReady()
     }
 
-    public void systemReady() {
+    public void systemRunning() {
         synchronized (mLock) {
             if (D) Log.d(TAG, "systemReady()");
 
@@ -211,9 +214,7 @@
             mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
 
             // prepare worker thread
-            mHandlerThread = new HandlerThread(THREAD_NAME, Process.THREAD_PRIORITY_BACKGROUND);
-            mHandlerThread.start();
-            mLocationHandler = new LocationWorkerHandler(mHandlerThread.getLooper());
+            mLocationHandler = new LocationWorkerHandler(BackgroundThread.get().getLooper());
 
             // prepare mLocationHandler's dependents
             mLocationFudger = new LocationFudger(mContext, mLocationHandler);
@@ -225,6 +226,9 @@
             AppOpsManager.Callback callback = new AppOpsManager.Callback() {
                 public void opChanged(int op, String packageName) {
                     synchronized (mLock) {
+                        for (Receiver receiver : mReceivers.values()) {
+                            receiver.updateMonitoring(true);
+                        }
                         applyAllProviderRequirementsLocked();
                     }
                 }
@@ -416,17 +420,30 @@
             Slog.e(TAG,  "no geocoder provider found");
         }
 
+        // bind to fused provider
+        FlpHardwareProvider flpHardwareProvider = FlpHardwareProvider.getInstance(mContext);
+        FusedProxy fusedProxy = FusedProxy.createAndBind(
+                mContext,
+                mLocationHandler,
+                flpHardwareProvider.getLocationHardware(),
+                com.android.internal.R.bool.config_enableFusedLocationOverlay,
+                com.android.internal.R.string.config_fusedLocationProviderPackageName,
+                com.android.internal.R.array.config_locationProviderPackageNames);
+        if(fusedProxy == null) {
+            Slog.e(TAG, "No FusedProvider found.");
+        }
+
         // bind to geofence provider
         GeofenceProxy provider = GeofenceProxy.createAndBind(mContext,
                 com.android.internal.R.bool.config_enableGeofenceOverlay,
                 com.android.internal.R.string.config_geofenceProviderPackageName,
                 com.android.internal.R.array.config_locationProviderPackageNames,
                 mLocationHandler,
-                gpsProvider.getGpsGeofenceProxy());
+                gpsProvider.getGpsGeofenceProxy(),
+                flpHardwareProvider.getGeofenceHardware());
         if (provider == null) {
             Slog.e(TAG,  "no geofence provider found");
         }
-
     }
 
     /**
@@ -459,15 +476,21 @@
 
         final ILocationListener mListener;
         final PendingIntent mPendingIntent;
+        final WorkSource mWorkSource; // WorkSource for battery blame, or null to assign to caller.
+        final boolean mHideFromAppOps; // True if AppOps should not monitor this receiver.
         final Object mKey;
 
         final HashMap<String,UpdateRecord> mUpdateRecords = new HashMap<String,UpdateRecord>();
 
+        // True if app ops has started monitoring this receiver for locations.
+        boolean mOpMonitoring;
+        // True if app ops has started monitoring this receiver for high power (gps) locations.
+        boolean mOpHighPowerMonitoring;
         int mPendingBroadcasts;
         PowerManager.WakeLock mWakeLock;
 
         Receiver(ILocationListener listener, PendingIntent intent, int pid, int uid,
-                String packageName) {
+                String packageName, WorkSource workSource, boolean hideFromAppOps) {
             mListener = listener;
             mPendingIntent = intent;
             if (listener != null) {
@@ -479,10 +502,20 @@
             mUid = uid;
             mPid = pid;
             mPackageName = packageName;
+            if (workSource != null && workSource.size() <= 0) {
+                workSource = null;
+            }
+            mWorkSource = workSource;
+            mHideFromAppOps = hideFromAppOps;
+
+            updateMonitoring(true);
 
             // construct/configure wakelock
             mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
-            mWakeLock.setWorkSource(new WorkSource(mUid, mPackageName));
+            if (workSource == null) {
+                workSource = new WorkSource(mUid, mPackageName);
+            }
+            mWakeLock.setWorkSource(workSource);
         }
 
         @Override
@@ -515,6 +548,83 @@
             return s.toString();
         }
 
+        /**
+         * Update AppOp monitoring for this receiver.
+         *
+         * @param allow If true receiver is currently active, if false it's been removed.
+         */
+        public void updateMonitoring(boolean allow) {
+            if (mHideFromAppOps) {
+                return;
+            }
+
+            boolean requestingLocation = false;
+            boolean requestingHighPowerLocation = false;
+            if (allow) {
+                // See if receiver has any enabled update records.  Also note if any update records
+                // are high power (has a high power provider with an interval under a threshold).
+                for (UpdateRecord updateRecord : mUpdateRecords.values()) {
+                    if (isAllowedByCurrentUserSettingsLocked(updateRecord.mProvider)) {
+                        requestingLocation = true;
+                        LocationProviderInterface locationProvider
+                            = mProvidersByName.get(updateRecord.mProvider);
+                        ProviderProperties properties = locationProvider != null
+                                ? locationProvider.getProperties() : null;
+                        if (properties != null
+                                && properties.mPowerRequirement == Criteria.POWER_HIGH
+                                && updateRecord.mRequest.getInterval() < HIGH_POWER_INTERVAL_MS) {
+                            requestingHighPowerLocation = true;
+                            break;
+                        }
+                    }
+                }
+            }
+
+            // First update monitoring of any location request (including high power).
+            mOpMonitoring = updateMonitoring(
+                    requestingLocation,
+                    mOpMonitoring,
+                    AppOpsManager.OP_MONITOR_LOCATION);
+
+            // Now update monitoring of high power requests only.
+            boolean wasHighPowerMonitoring = mOpHighPowerMonitoring;
+            mOpHighPowerMonitoring = updateMonitoring(
+                    requestingHighPowerLocation,
+                    mOpHighPowerMonitoring,
+                    AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION);
+            if (mOpHighPowerMonitoring != wasHighPowerMonitoring) {
+                // Send an intent to notify that a high power request has been added/removed.
+                Intent intent = new Intent(LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION);
+                mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
+            }
+        }
+
+        /**
+         * Update AppOps monitoring for a single location request and op type.
+         *
+         * @param allowMonitoring True if monitoring is allowed for this request/op.
+         * @param currentlyMonitoring True if AppOps is currently monitoring this request/op.
+         * @param op AppOps code for the op to update.
+         * @return True if monitoring is on for this request/op after updating.
+         */
+        private boolean updateMonitoring(boolean allowMonitoring, boolean currentlyMonitoring,
+                int op) {
+            if (!currentlyMonitoring) {
+                if (allowMonitoring) {
+                    return mAppOps.startOpNoThrow(op, mUid, mPackageName)
+                            == AppOpsManager.MODE_ALLOWED;
+                }
+            } else {
+                if (!allowMonitoring || mAppOps.checkOpNoThrow(op, mUid, mPackageName)
+                        != AppOpsManager.MODE_ALLOWED) {
+                    mAppOps.finishOp(op, mUid, mPackageName);
+                    return false;
+                }
+            }
+
+            return currentlyMonitoring;
+        }
+
         public boolean isListener() {
             return mListener != null;
         }
@@ -600,6 +710,10 @@
         }
 
         public boolean callProviderEnabledLocked(String provider, boolean enabled) {
+            // First update AppOp monitoring.
+            // An app may get/lose location access as providers are enabled/disabled.
+            updateMonitoring(true);
+
             if (mListener != null) {
                 try {
                     synchronized (this) {
@@ -866,6 +980,20 @@
         }
     }
 
+    /**
+     * Throw SecurityException if WorkSource use is not allowed (i.e. can't blame other packages
+     * for battery).
+     */
+    private void checkDeviceStatsAllowed() {
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.UPDATE_DEVICE_STATS, null);
+    }
+
+    private void checkUpdateAppOpsAllowed() {
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.UPDATE_APP_OPS_STATS, null);
+    }
+
     public static int resolutionLevelToOp(int allowedResolutionLevel) {
         if (allowedResolutionLevel != RESOLUTION_LEVEL_NONE) {
             if (allowedResolutionLevel == RESOLUTION_LEVEL_COARSE) {
@@ -1028,6 +1156,8 @@
         if (changesMade) {
             mContext.sendBroadcastAsUser(new Intent(LocationManager.PROVIDERS_CHANGED_ACTION),
                     UserHandle.ALL);
+            mContext.sendBroadcastAsUser(new Intent(LocationManager.MODE_CHANGED_ACTION),
+                    UserHandle.ALL);
         }
     }
 
@@ -1107,7 +1237,18 @@
                     if (UserHandle.getUserId(record.mReceiver.mUid) == mCurrentUserId) {
                         LocationRequest locationRequest = record.mRequest;
                         if (locationRequest.getInterval() <= thresholdInterval) {
-                            worksource.add(record.mReceiver.mUid, record.mReceiver.mPackageName);
+                            if (record.mReceiver.mWorkSource != null
+                                    && record.mReceiver.mWorkSource.size() > 0
+                                    && record.mReceiver.mWorkSource.getName(0) != null) {
+                                // Assign blame to another work source.
+                                // Can only assign blame if the WorkSource contains names.
+                                worksource.add(record.mReceiver.mWorkSource);
+                            } else {
+                                // Assign blame to caller.
+                                worksource.add(
+                                        record.mReceiver.mUid,
+                                        record.mReceiver.mPackageName);
+                            }
                         }
                     }
                 }
@@ -1182,11 +1323,12 @@
     }
 
     private Receiver getReceiverLocked(ILocationListener listener, int pid, int uid,
-            String packageName) {
+            String packageName, WorkSource workSource, boolean hideFromAppOps) {
         IBinder binder = listener.asBinder();
         Receiver receiver = mReceivers.get(binder);
         if (receiver == null) {
-            receiver = new Receiver(listener, null, pid, uid, packageName);
+            receiver = new Receiver(listener, null, pid, uid, packageName, workSource,
+                    hideFromAppOps);
             mReceivers.put(binder, receiver);
 
             try {
@@ -1199,10 +1341,12 @@
         return receiver;
     }
 
-    private Receiver getReceiverLocked(PendingIntent intent, int pid, int uid, String packageName) {
+    private Receiver getReceiverLocked(PendingIntent intent, int pid, int uid, String packageName,
+            WorkSource workSource, boolean hideFromAppOps) {
         Receiver receiver = mReceivers.get(intent);
         if (receiver == null) {
-            receiver = new Receiver(null, intent, pid, uid, packageName);
+            receiver = new Receiver(null, intent, pid, uid, packageName, workSource,
+                    hideFromAppOps);
             mReceivers.put(intent, receiver);
         }
         return receiver;
@@ -1264,16 +1408,16 @@
     }
 
     private Receiver checkListenerOrIntentLocked(ILocationListener listener, PendingIntent intent,
-            int pid, int uid, String packageName) {
+            int pid, int uid, String packageName, WorkSource workSource, boolean hideFromAppOps) {
         if (intent == null && listener == null) {
             throw new IllegalArgumentException("need either listener or intent");
         } else if (intent != null && listener != null) {
             throw new IllegalArgumentException("cannot register both listener and intent");
         } else if (intent != null) {
             checkPendingIntent(intent);
-            return getReceiverLocked(intent, pid, uid, packageName);
+            return getReceiverLocked(intent, pid, uid, packageName, workSource, hideFromAppOps);
         } else {
-            return getReceiverLocked(listener, pid, uid, packageName);
+            return getReceiverLocked(listener, pid, uid, packageName, workSource, hideFromAppOps);
         }
     }
 
@@ -1285,6 +1429,14 @@
         int allowedResolutionLevel = getCallerAllowedResolutionLevel();
         checkResolutionLevelIsSufficientForProviderUse(allowedResolutionLevel,
                 request.getProvider());
+        WorkSource workSource = request.getWorkSource();
+        if (workSource != null && workSource.size() > 0) {
+            checkDeviceStatsAllowed();
+        }
+        boolean hideFromAppOps = request.getHideFromAppOps();
+        if (hideFromAppOps) {
+            checkUpdateAppOpsAllowed();
+        }
         LocationRequest sanitizedRequest = createSanitizedRequest(request, allowedResolutionLevel);
 
         final int pid = Binder.getCallingPid();
@@ -1298,7 +1450,7 @@
 
             synchronized (mLock) {
                 Receiver recevier = checkListenerOrIntentLocked(listener, intent, pid, uid,
-                        packageName);
+                        packageName, workSource, hideFromAppOps);
                 requestLocationUpdatesLocked(sanitizedRequest, recevier, pid, uid, packageName);
             }
         } finally {
@@ -1336,6 +1488,9 @@
             // Notify the listener that updates are currently disabled
             receiver.callProviderEnabledLocked(name, false);
         }
+        // Update the monitoring here just in case multiple location requests were added to the
+        // same receiver (this request may be high power and the initial might not have been).
+        receiver.updateMonitoring(true);
     }
 
     @Override
@@ -1347,7 +1502,10 @@
         final int uid = Binder.getCallingUid();
 
         synchronized (mLock) {
-            Receiver receiver = checkListenerOrIntentLocked(listener, intent, pid, uid, packageName);
+            WorkSource workSource = null;
+            boolean hideFromAppOps = false;
+            Receiver receiver = checkListenerOrIntentLocked(listener, intent, pid, uid,
+                    packageName, workSource, hideFromAppOps);
 
             // providers may use public location API's, need to clear identity
             long identity = Binder.clearCallingIdentity();
@@ -1369,6 +1527,8 @@
             }
         }
 
+        receiver.updateMonitoring(false);
+
         // Record which providers were associated with this listener
         HashSet<String> providers = new HashSet<String>();
         HashMap<String, UpdateRecord> oldRecords = receiver.mUpdateRecords;
@@ -1613,8 +1773,12 @@
 
     @Override
     public boolean isProviderEnabled(String provider) {
+        // TODO: remove this check in next release, see b/10696351
         checkResolutionLevelIsSufficientForProviderUse(getCallerAllowedResolutionLevel(),
                 provider);
+
+        // Fused provider is accessed indirectly via criteria rather than the provider-based APIs,
+        // so we discourage its use
         if (LocationManager.FUSED_PROVIDER.equals(provider)) return false;
 
         int uid = Binder.getCallingUid();
diff --git a/services/java/com/android/server/LockSettingsService.java b/services/java/com/android/server/LockSettingsService.java
index d52a8e2..c5555c8 100644
--- a/services/java/com/android/server/LockSettingsService.java
+++ b/services/java/com/android/server/LockSettingsService.java
@@ -16,6 +16,7 @@
 
 package com.android.server;
 
+import android.app.ActivityManagerNative;
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
@@ -27,6 +28,9 @@
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteStatement;
+import android.media.AudioManager;
+import android.media.AudioService;
 import android.os.Binder;
 import android.os.Environment;
 import android.os.RemoteException;
@@ -37,6 +41,7 @@
 import android.provider.Settings.Secure;
 import android.provider.Settings.SettingNotFoundException;
 import android.text.TextUtils;
+import android.util.Log;
 import android.util.Slog;
 
 import com.android.internal.widget.ILockSettings;
@@ -57,6 +62,7 @@
  */
 public class LockSettingsService extends ILockSettings.Stub {
 
+    private static final String PERMISSION = "android.permission.ACCESS_KEYGUARD_SECURE_STORAGE";
     private final DatabaseHelper mOpenHelper;
     private static final String TAG = "LockSettingsService";
 
@@ -143,20 +149,12 @@
         }
     }
 
-    private static final void checkWritePermission(int userId) {
-        final int callingUid = Binder.getCallingUid();
-        if (UserHandle.getAppId(callingUid) != android.os.Process.SYSTEM_UID) {
-            throw new SecurityException("uid=" + callingUid
-                    + " not authorized to write lock settings");
-        }
+    private final void checkWritePermission(int userId) {
+        mContext.checkCallingOrSelfPermission(PERMISSION);
     }
 
-    private static final void checkPasswordReadPermission(int userId) {
-        final int callingUid = Binder.getCallingUid();
-        if (UserHandle.getAppId(callingUid) != android.os.Process.SYSTEM_UID) {
-            throw new SecurityException("uid=" + callingUid
-                    + " not authorized to read lock password");
-        }
+    private final void checkPasswordReadPermission(int userId) {
+        mContext.checkCallingOrSelfPermission(PERMISSION);
     }
 
     private final void checkReadPermission(String requestedKey, int userId) {
@@ -398,7 +396,7 @@
         private static final String TAG = "LockSettingsDB";
         private static final String DATABASE_NAME = "locksettings.db";
 
-        private static final int DATABASE_VERSION = 1;
+        private static final int DATABASE_VERSION = 2;
 
         public DatabaseHelper(Context context) {
             super(context, DATABASE_NAME, null, DATABASE_VERSION);
@@ -431,7 +429,45 @@
 
         @Override
         public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
-            // Nothing yet
+            int upgradeVersion = oldVersion;
+            if (upgradeVersion == 1) {
+                // Set the initial value for {@link LockPatternUtils#LOCKSCREEN_WIDGETS_ENABLED}
+                // during upgrade based on whether each user previously had widgets in keyguard.
+                maybeEnableWidgetSettingForUsers(db);
+                upgradeVersion = 2;
+            }
+
+            if (upgradeVersion != DATABASE_VERSION) {
+                Log.w(TAG, "Failed to upgrade database!");
+            }
+        }
+
+        private void maybeEnableWidgetSettingForUsers(SQLiteDatabase db) {
+            final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
+            final ContentResolver cr = mContext.getContentResolver();
+            final LockPatternUtils utils = new LockPatternUtils(mContext);
+            final List<UserInfo> users = um.getUsers();
+            for (int i = 0; i < users.size(); i++) {
+                final int userId = users.get(i).id;
+                final boolean enabled = utils.hasWidgetsEnabledInKeyguard(userId);
+                Log.v(TAG, "Widget upgrade uid=" + userId + ", enabled="
+                        + enabled + ", w[]=" + utils.getAppWidgets());
+                loadSetting(db, LockPatternUtils.LOCKSCREEN_WIDGETS_ENABLED, userId, enabled);
+            }
+        }
+
+        private void loadSetting(SQLiteDatabase db, String key, int userId, boolean value) {
+            SQLiteStatement stmt = null;
+            try {
+                stmt = db.compileStatement(
+                        "INSERT OR REPLACE INTO locksettings(name,user,value) VALUES(?,?,?);");
+                stmt.bindString(1, key);
+                stmt.bindLong(2, userId);
+                stmt.bindLong(3, value ? 1 : 0);
+                stmt.execute();
+            } finally {
+                if (stmt != null) stmt.close();
+            }
         }
     }
 
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index e670ef9..1facb80 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -190,6 +190,8 @@
     /** When defined, base template for user-specific {@link StorageVolume}. */
     private StorageVolume mEmulatedTemplate;
 
+    // TODO: separate storage volumes on per-user basis
+
     @GuardedBy("mVolumesLock")
     private final ArrayList<StorageVolume> mVolumes = Lists.newArrayList();
     /** Map from path to {@link StorageVolume} */
@@ -492,7 +494,6 @@
         }
     };
 
-    private final HandlerThread mHandlerThread;
     private final Handler mHandler;
 
     void waitForAsecScan() {
@@ -828,7 +829,7 @@
             }
 
             if (code == VoldResponseCode.VolumeDiskInserted) {
-                new Thread() {
+                new Thread("MountService#VolumeDiskInserted") {
                     @Override
                     public void run() {
                         try {
@@ -1115,7 +1116,7 @@
             /*
              * USB mass storage disconnected while enabled
              */
-            new Thread() {
+            new Thread("MountService#AvailabilityChange") {
                 @Override
                 public void run() {
                     try {
@@ -1314,9 +1315,9 @@
         // XXX: This will go away soon in favor of IMountServiceObserver
         mPms = (PackageManagerService) ServiceManager.getService("package");
 
-        mHandlerThread = new HandlerThread("MountService");
-        mHandlerThread.start();
-        mHandler = new MountServiceHandler(mHandlerThread.getLooper());
+        HandlerThread hthread = new HandlerThread(TAG);
+        hthread.start();
+        mHandler = new MountServiceHandler(hthread.getLooper());
 
         // Watch for user changes
         final IntentFilter userFilter = new IntentFilter();
@@ -1338,7 +1339,7 @@
                 idleMaintenanceFilter, null, mHandler);
 
         // Add OBB Action Handler to MountService thread.
-        mObbActionHandler = new ObbActionHandler(mHandlerThread.getLooper());
+        mObbActionHandler = new ObbActionHandler(IoThread.get().getLooper());
 
         /*
          * Create the connection to vold with a maximum queue of twice the
@@ -2606,6 +2607,7 @@
     @VisibleForTesting
     public static String buildObbPath(final String canonicalPath, int userId, boolean forVold) {
         // TODO: allow caller to provide Environment for full testing
+        // TODO: extend to support OBB mounts on secondary external storage
 
         // Only adjust paths when storage is emulated
         if (!Environment.isExternalStorageEmulated()) {
@@ -2618,10 +2620,10 @@
         final UserEnvironment userEnv = new UserEnvironment(userId);
 
         // /storage/emulated/0
-        final String externalPath = userEnv.getExternalStorageDirectory().toString();
+        final String externalPath = userEnv.getExternalStorageDirectory().getAbsolutePath();
         // /storage/emulated_legacy
         final String legacyExternalPath = Environment.getLegacyExternalStorageDirectory()
-                .toString();
+                .getAbsolutePath();
 
         if (path.startsWith(externalPath)) {
             path = path.substring(externalPath.length() + 1);
@@ -2637,18 +2639,19 @@
             path = path.substring(obbPath.length() + 1);
 
             if (forVold) {
-                return new File(Environment.getEmulatedStorageObbSource(), path).toString();
+                return new File(Environment.getEmulatedStorageObbSource(), path).getAbsolutePath();
             } else {
                 final UserEnvironment ownerEnv = new UserEnvironment(UserHandle.USER_OWNER);
-                return new File(ownerEnv.getExternalStorageObbDirectory(), path).toString();
+                return new File(ownerEnv.buildExternalStorageAndroidObbDirs()[0], path)
+                        .getAbsolutePath();
             }
         }
 
         // Handle normal external storage paths
         if (forVold) {
-            return new File(Environment.getEmulatedStorageSource(userId), path).toString();
+            return new File(Environment.getEmulatedStorageSource(userId), path).getAbsolutePath();
         } else {
-            return new File(userEnv.getExternalStorageDirectory(), path).toString();
+            return new File(userEnv.getExternalDirs()[0], path).getAbsolutePath();
         }
     }
 
diff --git a/services/java/com/android/server/NativeDaemonConnector.java b/services/java/com/android/server/NativeDaemonConnector.java
index 0a91919..417d6d8 100644
--- a/services/java/com/android/server/NativeDaemonConnector.java
+++ b/services/java/com/android/server/NativeDaemonConnector.java
@@ -18,8 +18,8 @@
 
 import android.net.LocalSocket;
 import android.net.LocalSocketAddress;
+import android.os.Build;
 import android.os.Handler;
-import android.os.HandlerThread;
 import android.os.Message;
 import android.os.SystemClock;
 import android.util.LocalLog;
@@ -81,9 +81,7 @@
 
     @Override
     public void run() {
-        HandlerThread thread = new HandlerThread(TAG + ".CallbackHandler");
-        thread.start();
-        mCallbackHandler = new Handler(thread.getLooper(), this);
+        mCallbackHandler = new Handler(FgThread.get().getLooper(), this);
 
         while (true) {
             try {
@@ -108,13 +106,24 @@
         return true;
     }
 
+    private LocalSocketAddress determineSocketAddress() {
+        // If we're testing, set up a socket in a namespace that's accessible to test code.
+        // In order to ensure that unprivileged apps aren't able to impersonate native daemons on
+        // production devices, even if said native daemons ill-advisedly pick a socket name that
+        // starts with __test__, only allow this on debug builds.
+        if (mSocket.startsWith("__test__") && Build.IS_DEBUGGABLE) {
+            return new LocalSocketAddress(mSocket);
+        } else {
+            return new LocalSocketAddress(mSocket, LocalSocketAddress.Namespace.RESERVED);
+        }
+    }
+
     private void listenToSocket() throws IOException {
         LocalSocket socket = null;
 
         try {
             socket = new LocalSocket();
-            LocalSocketAddress address = new LocalSocketAddress(mSocket,
-                    LocalSocketAddress.Namespace.RESERVED);
+            LocalSocketAddress address = determineSocketAddress();
 
             socket.connect(address);
 
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 3b84c732..92f99c2 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -24,13 +24,14 @@
 import static android.net.NetworkStats.UID_ALL;
 import static android.net.TrafficStats.UID_TETHERING;
 import static com.android.server.NetworkManagementService.NetdResponseCode.ClatdStatusResult;
+import static com.android.server.NetworkManagementService.NetdResponseCode.GetMarkResult;
 import static com.android.server.NetworkManagementService.NetdResponseCode.InterfaceGetCfgResult;
 import static com.android.server.NetworkManagementService.NetdResponseCode.InterfaceListResult;
 import static com.android.server.NetworkManagementService.NetdResponseCode.IpFwdStatusResult;
 import static com.android.server.NetworkManagementService.NetdResponseCode.TetherDnsFwdTgtListResult;
 import static com.android.server.NetworkManagementService.NetdResponseCode.TetherInterfaceListResult;
 import static com.android.server.NetworkManagementService.NetdResponseCode.TetherStatusResult;
-import static com.android.server.NetworkManagementService.NetdResponseCode.TetheringStatsResult;
+import static com.android.server.NetworkManagementService.NetdResponseCode.TetheringStatsListResult;
 import static com.android.server.NetworkManagementService.NetdResponseCode.TtyListResult;
 import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
 
@@ -43,18 +44,21 @@
 import android.net.RouteInfo;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiConfiguration.KeyMgmt;
+import android.os.BatteryStats;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.INetworkManagementService;
 import android.os.Process;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseBooleanArray;
 
+import com.android.internal.app.IBatteryStats;
 import com.android.internal.net.NetworkStatsFactory;
 import com.android.internal.util.Preconditions;
 import com.android.server.NativeDaemonConnector.Command;
@@ -91,6 +95,7 @@
     private static final String TAG = "NetworkManagementService";
     private static final boolean DBG = false;
     private static final String NETD_TAG = "NetdConnector";
+    private static final String NETD_SOCKET_NAME = "netd";
 
     private static final String ADD = "add";
     private static final String REMOVE = "remove";
@@ -113,6 +118,7 @@
         public static final int TetherInterfaceListResult = 111;
         public static final int TetherDnsFwdTgtListResult = 112;
         public static final int TtyListResult             = 113;
+        public static final int TetheringStatsListResult  = 114;
 
         public static final int TetherStatusResult        = 210;
         public static final int IpFwdStatusResult         = 211;
@@ -124,10 +130,12 @@
         public static final int TetheringStatsResult      = 221;
         public static final int DnsProxyQueryResult       = 222;
         public static final int ClatdStatusResult         = 223;
+        public static final int GetMarkResult             = 225;
 
         public static final int InterfaceChange           = 600;
         public static final int BandwidthControl          = 601;
         public static final int InterfaceClassActivity    = 613;
+        public static final int InterfaceAddressChange    = 614;
     }
 
     /**
@@ -181,7 +189,7 @@
      *
      * @param context  Binder context for this service
      */
-    private NetworkManagementService(Context context) {
+    private NetworkManagementService(Context context, String socket) {
         mContext = context;
 
         if ("simulator".equals(SystemProperties.get("ro.product.device"))) {
@@ -189,15 +197,16 @@
         }
 
         mConnector = new NativeDaemonConnector(
-                new NetdCallbackReceiver(), "netd", 10, NETD_TAG, 160);
+                new NetdCallbackReceiver(), socket, 10, NETD_TAG, 160);
         mThread = new Thread(mConnector, NETD_TAG);
 
         // Add ourself to the Watchdog monitors.
         Watchdog.getInstance().addMonitor(this);
     }
 
-    public static NetworkManagementService create(Context context) throws InterruptedException {
-        final NetworkManagementService service = new NetworkManagementService(context);
+    static NetworkManagementService create(Context context,
+            String socket) throws InterruptedException {
+        final NetworkManagementService service = new NetworkManagementService(context, socket);
         final CountDownLatch connectedSignal = service.mConnectedSignal;
         if (DBG) Slog.d(TAG, "Creating NetworkManagementService");
         service.mThread.start();
@@ -207,6 +216,10 @@
         return service;
     }
 
+    public static NetworkManagementService create(Context context) throws InterruptedException {
+        return create(context, NETD_SOCKET_NAME);
+    }
+
     public void systemReady() {
         prepareNativeDaemon();
         if (DBG) Slog.d(TAG, "Prepared");
@@ -343,6 +356,14 @@
 
         SystemProperties.set(PROP_QTAGUID_ENABLED, mBandwidthControlEnabled ? "1" : "0");
 
+        if (mBandwidthControlEnabled) {
+            try {
+                IBatteryStats.Stub.asInterface(ServiceManager.getService(BatteryStats.SERVICE_NAME))
+                        .noteNetworkStatsEnabled();
+            } catch (RemoteException e) {
+            }
+        }
+
         // push any existing quota or UID rules
         synchronized (mQuotaLock) {
             int size = mActiveQuotas.size();
@@ -380,6 +401,36 @@
         setFirewallEnabled(mFirewallEnabled || LockdownVpnTracker.isEnabled());
     }
 
+    /**
+     * Notify our observers of a new or updated interface address.
+     */
+    private void notifyAddressUpdated(String address, String iface, int flags, int scope) {
+        final int length = mObservers.beginBroadcast();
+        for (int i = 0; i < length; i++) {
+            try {
+                mObservers.getBroadcastItem(i).addressUpdated(address, iface, flags, scope);
+            } catch (RemoteException e) {
+            } catch (RuntimeException e) {
+            }
+        }
+        mObservers.finishBroadcast();
+    }
+
+    /**
+     * Notify our observers of a deleted interface address.
+     */
+    private void notifyAddressRemoved(String address, String iface, int flags, int scope) {
+        final int length = mObservers.beginBroadcast();
+        for (int i = 0; i < length; i++) {
+            try {
+                mObservers.getBroadcastItem(i).addressRemoved(address, iface, flags, scope);
+            } catch (RemoteException e) {
+            } catch (RuntimeException e) {
+            }
+        }
+        mObservers.finishBroadcast();
+    }
+
     //
     // Netd Callback handling
     //
@@ -462,6 +513,33 @@
                     notifyInterfaceClassActivity(cooked[3], isActive);
                     return true;
                     // break;
+            case NetdResponseCode.InterfaceAddressChange:
+                    /*
+                     * A network address change occurred
+                     * Format: "NNN Address updated <addr> <iface> <flags> <scope>"
+                     *         "NNN Address removed <addr> <iface> <flags> <scope>"
+                     */
+                    String msg = String.format("Invalid event from daemon (%s)", raw);
+                    if (cooked.length < 6 || !cooked[1].equals("Address")) {
+                        throw new IllegalStateException(msg);
+                    }
+
+                    int flags;
+                    int scope;
+                    try {
+                        flags = Integer.parseInt(cooked[5]);
+                        scope = Integer.parseInt(cooked[6]);
+                    } catch(NumberFormatException e) {
+                        throw new IllegalStateException(msg);
+                    }
+
+                    if (cooked[2].equals("updated")) {
+                        notifyAddressUpdated(cooked[3], cooked[4], flags, scope);
+                    } else {
+                        notifyAddressRemoved(cooked[3], cooked[4], flags, scope);
+                    }
+                    return true;
+                    // break;
             default: break;
             }
             return false;
@@ -762,6 +840,18 @@
     }
 
     @Override
+    public void setMtu(String iface, int mtu) {
+        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+
+        final NativeDaemonEvent event;
+        try {
+            event = mConnector.execute("interface", "setmtu", iface, mtu);
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
+    @Override
     public void shutdown() {
         // TODO: remove from aidl if nobody calls externally
         mContext.enforceCallingOrSelfPermission(SHUTDOWN, TAG);
@@ -990,7 +1080,8 @@
                 mConnector.execute("softap", "set", wlanIface);
             } else {
                 mConnector.execute("softap", "set", wlanIface, wifiConfig.SSID,
-                        getSecurityType(wifiConfig), new SensitiveArg(wifiConfig.preSharedKey));
+                                   "broadcast", "6", getSecurityType(wifiConfig),
+                                   new SensitiveArg(wifiConfig.preSharedKey));
             }
             mConnector.execute("softap", "startap");
         } catch (NativeDaemonConnectorException e) {
@@ -1039,7 +1130,8 @@
                 mConnector.execute("softap", "set", wlanIface);
             } else {
                 mConnector.execute("softap", "set", wlanIface, wifiConfig.SSID,
-                        getSecurityType(wifiConfig), new SensitiveArg(wifiConfig.preSharedKey));
+                                   "broadcast", "6", getSecurityType(wifiConfig),
+                                   new SensitiveArg(wifiConfig.preSharedKey));
             }
         } catch (NativeDaemonConnectorException e) {
             throw e.rethrowAsParcelableException();
@@ -1283,55 +1375,42 @@
     }
 
     @Override
-    public NetworkStats getNetworkStatsTethering(String[] ifacePairs) {
+    public NetworkStats getNetworkStatsTethering() {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
-        if (ifacePairs.length % 2 != 0) {
-            throw new IllegalArgumentException(
-                    "unexpected ifacePairs; length=" + ifacePairs.length);
-        }
-
         final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1);
-        for (int i = 0; i < ifacePairs.length; i += 2) {
-            final String ifaceIn = ifacePairs[i];
-            final String ifaceOut = ifacePairs[i + 1];
-            if (ifaceIn != null && ifaceOut != null) {
-                stats.combineValues(getNetworkStatsTethering(ifaceIn, ifaceOut));
-            }
-        }
-        return stats;
-    }
-
-    private NetworkStats.Entry getNetworkStatsTethering(String ifaceIn, String ifaceOut) {
-        final NativeDaemonEvent event;
         try {
-            event = mConnector.execute("bandwidth", "gettetherstats", ifaceIn, ifaceOut);
+            final NativeDaemonEvent[] events = mConnector.executeForList(
+                    "bandwidth", "gettetherstats");
+            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());
+                try {
+                    final String ifaceIn = tok.nextToken();
+                    final String ifaceOut = tok.nextToken();
+
+                    final NetworkStats.Entry entry = new NetworkStats.Entry();
+                    entry.iface = ifaceOut;
+                    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());
+                    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 (NativeDaemonConnectorException e) {
             throw e.rethrowAsParcelableException();
         }
-
-        event.checkCode(TetheringStatsResult);
-
-        // 221 ifaceIn ifaceOut rx_bytes rx_packets tx_bytes tx_packets
-        final StringTokenizer tok = new StringTokenizer(event.getMessage());
-        tok.nextToken();
-        tok.nextToken();
-
-        try {
-            final NetworkStats.Entry entry = new NetworkStats.Entry();
-            entry.iface = ifaceIn;
-            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());
-            return entry;
-        } catch (NumberFormatException e) {
-            throw new IllegalStateException(
-                    "problem parsing tethering stats for " + ifaceIn + " " + ifaceOut + ": " + e);
-        }
+        return stats;
     }
 
     @Override
@@ -1366,6 +1445,149 @@
     }
 
     @Override
+    public void setUidRangeRoute(String iface, int uid_start, int uid_end) {
+        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+        try {
+            mConnector.execute("interface", "fwmark",
+                    "uid", "add", iface, uid_start, uid_end);
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
+    @Override
+    public void clearUidRangeRoute(String iface, int uid_start, int uid_end) {
+        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+        try {
+            mConnector.execute("interface", "fwmark",
+                    "uid", "remove", iface, uid_start, uid_end);
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
+    @Override
+    public void setMarkedForwarding(String iface) {
+        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+        try {
+            mConnector.execute("interface", "fwmark", "rule", "add", iface);
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
+    @Override
+    public void clearMarkedForwarding(String iface) {
+        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+        try {
+            mConnector.execute("interface", "fwmark", "rule", "remove", iface);
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
+    @Override
+    public int getMarkForUid(int uid) {
+        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+        final NativeDaemonEvent event;
+        try {
+            event = mConnector.execute("interface", "fwmark", "get", "mark", uid);
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+        event.checkCode(GetMarkResult);
+        return Integer.parseInt(event.getMessage());
+    }
+
+    @Override
+    public int getMarkForProtect() {
+        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+        final NativeDaemonEvent event;
+        try {
+            event = mConnector.execute("interface", "fwmark", "get", "protect");
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+        event.checkCode(GetMarkResult);
+        return Integer.parseInt(event.getMessage());
+    }
+
+    @Override
+    public void setMarkedForwardingRoute(String iface, RouteInfo route) {
+        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+        try {
+            LinkAddress dest = route.getDestination();
+            mConnector.execute("interface", "fwmark", "route", "add", iface,
+                    dest.getAddress().getHostAddress(), dest.getNetworkPrefixLength());
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
+    @Override
+    public void clearMarkedForwardingRoute(String iface, RouteInfo route) {
+        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+        try {
+            LinkAddress dest = route.getDestination();
+            mConnector.execute("interface", "fwmark", "route", "remove", iface,
+                    dest.getAddress().getHostAddress(), dest.getNetworkPrefixLength());
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
+    @Override
+    public void setHostExemption(LinkAddress host) {
+        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+        try {
+            mConnector.execute("interface", "fwmark", "exempt", "add", host);
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
+    @Override
+    public void clearHostExemption(LinkAddress host) {
+        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+        try {
+            mConnector.execute("interface", "fwmark", "exempt", "remove", host);
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
+    @Override
+    public void setDnsInterfaceForUidRange(String iface, int uid_start, int uid_end) {
+        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+        try {
+            mConnector.execute("resolver", "setifaceforuidrange", iface, uid_start, uid_end);
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
+    @Override
+    public void clearDnsInterfaceForUidRange(int uid_start, int uid_end) {
+        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+        try {
+            mConnector.execute("resolver", "clearifaceforuidrange", uid_start, uid_end);
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
+    @Override
+    public void clearDnsInterfaceMaps() {
+        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+        try {
+            mConnector.execute("resolver", "clearifacemapping");
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
+
+    @Override
     public void flushDefaultDnsCache() {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
         try {
diff --git a/services/java/com/android/server/NetworkTimeUpdateService.java b/services/java/com/android/server/NetworkTimeUpdateService.java
index 3bfd190..cbddf67 100644
--- a/services/java/com/android/server/NetworkTimeUpdateService.java
+++ b/services/java/com/android/server/NetworkTimeUpdateService.java
@@ -27,7 +27,6 @@
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
 import android.os.Handler;
-import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.Message;
 import android.os.SystemClock;
@@ -36,6 +35,7 @@
 import android.util.NtpTrustedTime;
 import android.util.TrustedTime;
 
+import com.android.internal.os.BackgroundThread;
 import com.android.internal.telephony.TelephonyIntents;
 
 /**
@@ -71,7 +71,6 @@
 
     // NTP lookup is done on this thread and handler
     private Handler mHandler;
-    private HandlerThread mThread;
     private AlarmManager mAlarmManager;
     private PendingIntent mPendingPollIntent;
     private SettingsObserver mSettingsObserver;
@@ -109,14 +108,12 @@
     }
 
     /** Initialize the receivers and initiate the first NTP request */
-    public void systemReady() {
+    public void systemRunning() {
         registerForTelephonyIntents();
         registerForAlarms();
         registerForConnectivityIntents();
 
-        mThread = new HandlerThread(TAG);
-        mThread.start();
-        mHandler = new MyHandler(mThread.getLooper());
+        mHandler = new MyHandler(BackgroundThread.get().getLooper());
         // Check the network time on the new thread
         mHandler.obtainMessage(EVENT_POLL_NETWORK_TIME).sendToTarget();
 
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 29780c0..b881934 100644
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -75,6 +75,9 @@
 import android.view.accessibility.AccessibilityManager;
 import android.widget.Toast;
 
+import com.android.internal.R;
+
+import com.android.internal.notification.NotificationScorer;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -199,6 +202,8 @@
     private static final String TAG_PACKAGE = "package";
     private static final String ATTR_NAME = "name";
 
+    private final ArrayList<NotificationScorer> mScorers = new ArrayList<NotificationScorer>();
+
     private class NotificationListenerInfo implements DeathRecipient {
         INotificationListener listener;
         ComponentName component;
@@ -707,7 +712,7 @@
             intent.setComponent(name);
 
             intent.putExtra(Intent.EXTRA_CLIENT_LABEL,
-                    com.android.internal.R.string.notification_listener_binding_label);
+                    R.string.notification_listener_binding_label);
             intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
                     mContext, 0, new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS), 0));
 
@@ -1297,19 +1302,19 @@
 
         Resources resources = mContext.getResources();
         mDefaultNotificationColor = resources.getColor(
-                com.android.internal.R.color.config_defaultNotificationColor);
+                R.color.config_defaultNotificationColor);
         mDefaultNotificationLedOn = resources.getInteger(
-                com.android.internal.R.integer.config_defaultNotificationLedOn);
+                R.integer.config_defaultNotificationLedOn);
         mDefaultNotificationLedOff = resources.getInteger(
-                com.android.internal.R.integer.config_defaultNotificationLedOff);
+                R.integer.config_defaultNotificationLedOff);
 
         mDefaultVibrationPattern = getLongArray(resources,
-                com.android.internal.R.array.config_defaultNotificationVibePattern,
+                R.array.config_defaultNotificationVibePattern,
                 VIBRATE_PATTERN_MAXLEN,
                 DEFAULT_VIBRATE_PATTERN);
 
         mFallbackVibrationPattern = getLongArray(resources,
-                com.android.internal.R.array.config_notificationFallbackVibePattern,
+                R.array.config_notificationFallbackVibePattern,
                 VIBRATE_PATTERN_MAXLEN,
                 DEFAULT_VIBRATE_PATTERN);
 
@@ -1344,6 +1349,24 @@
 
         mSettingsObserver = new SettingsObserver(mHandler);
         mSettingsObserver.observe();
+
+        // spin up NotificationScorers
+        String[] notificationScorerNames = resources.getStringArray(
+                R.array.config_notificationScorers);
+        for (String scorerName : notificationScorerNames) {
+            try {
+                Class<?> scorerClass = mContext.getClassLoader().loadClass(scorerName);
+                NotificationScorer scorer = (NotificationScorer) scorerClass.newInstance();
+                scorer.initialize(mContext);
+                mScorers.add(scorer);
+            } catch (ClassNotFoundException e) {
+                Slog.w(TAG, "Couldn't find scorer " + scorerName + ".", e);
+            } catch (InstantiationException e) {
+                Slog.w(TAG, "Couldn't instantiate scorer " + scorerName + ".", e);
+            } catch (IllegalAccessException e) {
+                Slog.w(TAG, "Problem accessing scorer " + scorerName + ".", e);
+            }
+        }
     }
 
     /**
@@ -1476,7 +1499,7 @@
             if (DBG) Slog.d(TAG, "Show pkg=" + record.pkg + " callback=" + record.callback);
             try {
                 record.callback.show();
-                scheduleTimeoutLocked(record, false);
+                scheduleTimeoutLocked(record);
                 return;
             } catch (RemoteException e) {
                 Slog.w(TAG, "Object died trying to show notification " + record.callback
@@ -1516,12 +1539,14 @@
         }
     }
 
-    private void scheduleTimeoutLocked(ToastRecord r, boolean immediate)
+    private void scheduleTimeoutLocked(ToastRecord r)
     {
-        Message m = Message.obtain(mHandler, MESSAGE_TIMEOUT, r);
-        long delay = immediate ? 0 : (r.duration == Toast.LENGTH_LONG ? LONG_DELAY : SHORT_DELAY);
         mHandler.removeCallbacksAndMessages(r);
-        mHandler.sendMessageDelayed(m, delay);
+        if (r.duration != Toast.LENGTH_INFINITE) {
+            Message m = Message.obtain(mHandler, MESSAGE_TIMEOUT, r);
+            long delay = r.duration == Toast.LENGTH_LONG ? LONG_DELAY : SHORT_DELAY;
+            mHandler.sendMessageDelayed(m, delay);
+        }
     }
 
     private void handleTimeout(ToastRecord record)
@@ -1599,8 +1624,10 @@
 
     // Not exposed via Binder; for system use only (otherwise malicious apps could spoof the
     // uid/pid of another application)
-    public void enqueueNotificationInternal(String pkg, String basePkg, int callingUid,
-            int callingPid, String tag, int id, Notification notification, int[] idOut, int userId)
+
+    public void enqueueNotificationInternal(final String pkg, String basePkg, final int callingUid,
+            final int callingPid, final String tag, final int id, final Notification notification,
+            int[] idOut, int incomingUserId)
     {
         if (DBG) {
             Slog.v(TAG, "enqueueNotificationInternal: pkg=" + pkg + " id=" + id + " notification=" + notification);
@@ -1608,8 +1635,8 @@
         checkCallerIsSystemOrSameApp(pkg);
         final boolean isSystemNotification = isUidSystem(callingUid) || ("android".equals(pkg));
 
-        userId = ActivityManager.handleIncomingUser(callingPid,
-                callingUid, userId, true, false, "enqueueNotification", pkg);
+        final int userId = ActivityManager.handleIncomingUser(callingPid,
+                callingUid, incomingUserId, true, false, "enqueueNotification", pkg);
         final UserHandle user = new UserHandle(userId);
 
         // Limit the number of notifications that any given package except the android
@@ -1651,244 +1678,284 @@
             }
         }
 
-        // === Scoring ===
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
 
-        // 0. Sanitize inputs
-        notification.priority = clamp(notification.priority, Notification.PRIORITY_MIN, Notification.PRIORITY_MAX);
-        // Migrate notification flags to scores
-        if (0 != (notification.flags & Notification.FLAG_HIGH_PRIORITY)) {
-            if (notification.priority < Notification.PRIORITY_MAX) notification.priority = Notification.PRIORITY_MAX;
-        } else if (SCORE_ONGOING_HIGHER && 0 != (notification.flags & Notification.FLAG_ONGOING_EVENT)) {
-            if (notification.priority < Notification.PRIORITY_HIGH) notification.priority = Notification.PRIORITY_HIGH;
-        }
+                // === Scoring ===
 
-        // 1. initial score: buckets of 10, around the app 
-        int score = notification.priority * NOTIFICATION_PRIORITY_MULTIPLIER; //[-20..20]
-
-        // 2. Consult external heuristics (TBD)
-
-        // 3. Apply local rules
-
-        // blocked apps
-        if (ENABLE_BLOCKED_NOTIFICATIONS && !noteNotificationOp(pkg, callingUid)) {
-            if (!isSystemNotification) {
-                score = JUNK_SCORE;
-                Slog.e(TAG, "Suppressing notification from package " + pkg + " by user request.");
-            }
-        }
-
-        if (DBG) {
-            Slog.v(TAG, "Assigned score=" + score + " to " + notification);
-        }
-
-        if (score < SCORE_DISPLAY_THRESHOLD) {
-            // Notification will be blocked because the score is too low.
-            return;
-        }
-
-        // Should this notification make noise, vibe, or use the LED?
-        final boolean canInterrupt = (score >= SCORE_INTERRUPTION_THRESHOLD);
-
-        synchronized (mNotificationList) {
-            final StatusBarNotification n = new StatusBarNotification(
-                    pkg, id, tag, callingUid, callingPid, score, notification, user);
-            NotificationRecord r = new NotificationRecord(n);
-            NotificationRecord old = null;
-
-            int index = indexOfNotificationLocked(pkg, tag, id, userId);
-            if (index < 0) {
-                mNotificationList.add(r);
-            } else {
-                old = mNotificationList.remove(index);
-                mNotificationList.add(index, r);
-                // Make sure we don't lose the foreground service state.
-                if (old != null) {
-                    notification.flags |=
-                        old.getNotification().flags&Notification.FLAG_FOREGROUND_SERVICE;
+                // 0. Sanitize inputs
+                notification.priority = clamp(notification.priority, Notification.PRIORITY_MIN,
+                        Notification.PRIORITY_MAX);
+                // Migrate notification flags to scores
+                if (0 != (notification.flags & Notification.FLAG_HIGH_PRIORITY)) {
+                    if (notification.priority < Notification.PRIORITY_MAX) {
+                        notification.priority = Notification.PRIORITY_MAX;
+                    }
+                } else if (SCORE_ONGOING_HIGHER &&
+                        0 != (notification.flags & Notification.FLAG_ONGOING_EVENT)) {
+                    if (notification.priority < Notification.PRIORITY_HIGH) {
+                        notification.priority = Notification.PRIORITY_HIGH;
+                    }
                 }
-            }
 
-            // Ensure if this is a foreground service that the proper additional
-            // flags are set.
-            if ((notification.flags&Notification.FLAG_FOREGROUND_SERVICE) != 0) {
-                notification.flags |= Notification.FLAG_ONGOING_EVENT
-                        | Notification.FLAG_NO_CLEAR;
-            }
+                // 1. initial score: buckets of 10, around the app
+                int score = notification.priority * NOTIFICATION_PRIORITY_MULTIPLIER; //[-20..20]
 
-            final int currentUser;
-            final long token = Binder.clearCallingIdentity();
-            try {
-                currentUser = ActivityManager.getCurrentUser();
-            } finally {
-                Binder.restoreCallingIdentity(token);
-            }
+                // 2. Consult external heuristics (TBD)
 
-            if (notification.icon != 0) {
-                if (old != null && old.statusBarKey != null) {
-                    r.statusBarKey = old.statusBarKey;
-                    long identity = Binder.clearCallingIdentity();
-                    try {
-                        mStatusBar.updateNotification(r.statusBarKey, n);
-                    }
-                    finally {
-                        Binder.restoreCallingIdentity(identity);
-                    }
-                } else {
-                    long identity = Binder.clearCallingIdentity();
-                    try {
-                        r.statusBarKey = mStatusBar.addNotification(n);
-                        if ((n.getNotification().flags & Notification.FLAG_SHOW_LIGHTS) != 0
-                                && canInterrupt) {
-                            mAttentionLight.pulse();
+                // 3. Apply local rules
+
+                int initialScore = score;
+                if (!mScorers.isEmpty()) {
+                    if (DBG) Slog.v(TAG, "Initial score is " + score + ".");
+                    for (NotificationScorer scorer : mScorers) {
+                        try {
+                            score = scorer.getScore(notification, score);
+                        } catch (Throwable t) {
+                            Slog.w(TAG, "Scorer threw on .getScore.", t);
                         }
                     }
-                    finally {
-                        Binder.restoreCallingIdentity(identity);
+                    if (DBG) Slog.v(TAG, "Final score is " + score + ".");
+                }
+
+                // add extra to indicate score modified by NotificationScorer
+                notification.extras.putBoolean(Notification.EXTRA_SCORE_MODIFIED,
+                        score != initialScore);
+
+                // blocked apps
+                if (ENABLE_BLOCKED_NOTIFICATIONS && !noteNotificationOp(pkg, callingUid)) {
+                    if (!isSystemNotification) {
+                        score = JUNK_SCORE;
+                        Slog.e(TAG, "Suppressing notification from package " + pkg
+                                + " by user request.");
                     }
                 }
-                // Send accessibility events only for the current user.
-                if (currentUser == userId) {
-                    sendAccessibilityEvent(notification, pkg);
+
+                if (DBG) {
+                    Slog.v(TAG, "Assigned score=" + score + " to " + notification);
                 }
 
-                notifyPostedLocked(r);
-            } else {
-                Slog.e(TAG, "Not posting notification with icon==0: " + notification);
-                if (old != null && old.statusBarKey != null) {
-                    long identity = Binder.clearCallingIdentity();
-                    try {
-                        mStatusBar.removeNotification(old.statusBarKey);
-                    }
-                    finally {
-                        Binder.restoreCallingIdentity(identity);
-                    }
-
-                    notifyRemovedLocked(r);
-                }
-                // ATTENTION: in a future release we will bail out here
-                // so that we do not play sounds, show lights, etc. for invalid notifications
-                Slog.e(TAG, "WARNING: In a future release this will crash the app: " + n.getPackageName());
-            }
-
-            // If we're not supposed to beep, vibrate, etc. then don't.
-            if (((mDisabledNotifications & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) == 0)
-                    && (!(old != null
-                        && (notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0 ))
-                    && (r.getUserId() == UserHandle.USER_ALL ||
-                        (r.getUserId() == userId && r.getUserId() == currentUser))
-                    && canInterrupt
-                    && mSystemReady) {
-
-                final AudioManager audioManager = (AudioManager) mContext
-                .getSystemService(Context.AUDIO_SERVICE);
-
-                // sound
-
-                // should we use the default notification sound? (indicated either by DEFAULT_SOUND
-                // or because notification.sound is pointing at Settings.System.NOTIFICATION_SOUND)
-                final boolean useDefaultSound =
-                       (notification.defaults & Notification.DEFAULT_SOUND) != 0
-                    || Settings.System.DEFAULT_NOTIFICATION_URI.equals(notification.sound);
-
-                Uri soundUri = null;
-                boolean hasValidSound = false;
-
-                if (useDefaultSound) {
-                    soundUri = Settings.System.DEFAULT_NOTIFICATION_URI;
-
-                    // check to see if the default notification sound is silent
-                    ContentResolver resolver = mContext.getContentResolver();
-                    hasValidSound = Settings.System.getString(resolver,
-                           Settings.System.NOTIFICATION_SOUND) != null;
-                } else if (notification.sound != null) {
-                    soundUri = notification.sound;
-                    hasValidSound = (soundUri != null);
+                if (score < SCORE_DISPLAY_THRESHOLD) {
+                    // Notification will be blocked because the score is too low.
+                    return;
                 }
 
-                if (hasValidSound) {
-                    boolean looping = (notification.flags & Notification.FLAG_INSISTENT) != 0;
-                    int audioStreamType;
-                    if (notification.audioStreamType >= 0) {
-                        audioStreamType = notification.audioStreamType;
+                // Should this notification make noise, vibe, or use the LED?
+                final boolean canInterrupt = (score >= SCORE_INTERRUPTION_THRESHOLD);
+
+                synchronized (mNotificationList) {
+                    final StatusBarNotification n = new StatusBarNotification(
+                            pkg, id, tag, callingUid, callingPid, score, notification, user);
+                    NotificationRecord r = new NotificationRecord(n);
+                    NotificationRecord old = null;
+
+                    int index = indexOfNotificationLocked(pkg, tag, id, userId);
+                    if (index < 0) {
+                        mNotificationList.add(r);
                     } else {
-                        audioStreamType = DEFAULT_STREAM_TYPE;
+                        old = mNotificationList.remove(index);
+                        mNotificationList.add(index, r);
+                        // Make sure we don't lose the foreground service state.
+                        if (old != null) {
+                            notification.flags |=
+                                old.getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE;
+                        }
                     }
-                    mSoundNotification = r;
-                    // do not play notifications if stream volume is 0
-                    // (typically because ringer mode is silent) or if speech recognition is active.
-                    if ((audioManager.getStreamVolume(audioStreamType) != 0)
-                            && !audioManager.isSpeechRecognitionActive()) {
-                        final long identity = Binder.clearCallingIdentity();
-                        try {
-                            final IRingtonePlayer player = mAudioService.getRingtonePlayer();
-                            if (player != null) {
-                                player.playAsync(soundUri, user, looping, audioStreamType);
+
+                    // Ensure if this is a foreground service that the proper additional
+                    // flags are set.
+                    if ((notification.flags&Notification.FLAG_FOREGROUND_SERVICE) != 0) {
+                        notification.flags |= Notification.FLAG_ONGOING_EVENT
+                                | Notification.FLAG_NO_CLEAR;
+                    }
+
+                    final int currentUser;
+                    final long token = Binder.clearCallingIdentity();
+                    try {
+                        currentUser = ActivityManager.getCurrentUser();
+                    } finally {
+                        Binder.restoreCallingIdentity(token);
+                    }
+
+                    if (notification.icon != 0) {
+                        if (old != null && old.statusBarKey != null) {
+                            r.statusBarKey = old.statusBarKey;
+                            long identity = Binder.clearCallingIdentity();
+                            try {
+                                mStatusBar.updateNotification(r.statusBarKey, n);
                             }
-                        } catch (RemoteException e) {
-                        } finally {
-                            Binder.restoreCallingIdentity(identity);
+                            finally {
+                                Binder.restoreCallingIdentity(identity);
+                            }
+                        } else {
+                            long identity = Binder.clearCallingIdentity();
+                            try {
+                                r.statusBarKey = mStatusBar.addNotification(n);
+                                if ((n.getNotification().flags & Notification.FLAG_SHOW_LIGHTS) != 0
+                                        && canInterrupt) {
+                                    mAttentionLight.pulse();
+                                }
+                            }
+                            finally {
+                                Binder.restoreCallingIdentity(identity);
+                            }
+                        }
+                        // Send accessibility events only for the current user.
+                        if (currentUser == userId) {
+                            sendAccessibilityEvent(notification, pkg);
+                        }
+
+                        notifyPostedLocked(r);
+                    } else {
+                        Slog.e(TAG, "Not posting notification with icon==0: " + notification);
+                        if (old != null && old.statusBarKey != null) {
+                            long identity = Binder.clearCallingIdentity();
+                            try {
+                                mStatusBar.removeNotification(old.statusBarKey);
+                            }
+                            finally {
+                                Binder.restoreCallingIdentity(identity);
+                            }
+
+                            notifyRemovedLocked(r);
+                        }
+                        // ATTENTION: in a future release we will bail out here
+                        // so that we do not play sounds, show lights, etc. for invalid notifications
+                        Slog.e(TAG, "WARNING: In a future release this will crash the app: "
+                                + n.getPackageName());
+                    }
+
+                    // If we're not supposed to beep, vibrate, etc. then don't.
+                    if (((mDisabledNotifications & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) == 0)
+                            && (!(old != null
+                                && (notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0 ))
+                            && (r.getUserId() == UserHandle.USER_ALL ||
+                                (r.getUserId() == userId && r.getUserId() == currentUser))
+                            && canInterrupt
+                            && mSystemReady) {
+
+                        final AudioManager audioManager = (AudioManager) mContext
+                        .getSystemService(Context.AUDIO_SERVICE);
+
+                        // sound
+
+                        // should we use the default notification sound? (indicated either by
+                        // DEFAULT_SOUND or because notification.sound is pointing at
+                        // Settings.System.NOTIFICATION_SOUND)
+                        final boolean useDefaultSound =
+                               (notification.defaults & Notification.DEFAULT_SOUND) != 0 ||
+                                       Settings.System.DEFAULT_NOTIFICATION_URI
+                                               .equals(notification.sound);
+
+                        Uri soundUri = null;
+                        boolean hasValidSound = false;
+
+                        if (useDefaultSound) {
+                            soundUri = Settings.System.DEFAULT_NOTIFICATION_URI;
+
+                            // check to see if the default notification sound is silent
+                            ContentResolver resolver = mContext.getContentResolver();
+                            hasValidSound = Settings.System.getString(resolver,
+                                   Settings.System.NOTIFICATION_SOUND) != null;
+                        } else if (notification.sound != null) {
+                            soundUri = notification.sound;
+                            hasValidSound = (soundUri != null);
+                        }
+
+                        if (hasValidSound) {
+                            boolean looping = (notification.flags & Notification.FLAG_INSISTENT) != 0;
+                            int audioStreamType;
+                            if (notification.audioStreamType >= 0) {
+                                audioStreamType = notification.audioStreamType;
+                            } else {
+                                audioStreamType = DEFAULT_STREAM_TYPE;
+                            }
+                            mSoundNotification = r;
+                            // do not play notifications if stream volume is 0 (typically because
+                            // ringer mode is silent) or if there is a user of exclusive audio focus
+                            if ((audioManager.getStreamVolume(audioStreamType) != 0)
+                                    && !audioManager.isAudioFocusExclusive()) {
+                                final long identity = Binder.clearCallingIdentity();
+                                try {
+                                    final IRingtonePlayer player = mAudioService.getRingtonePlayer();
+                                    if (player != null) {
+                                        player.playAsync(soundUri, user, looping, audioStreamType);
+                                    }
+                                } catch (RemoteException e) {
+                                } finally {
+                                    Binder.restoreCallingIdentity(identity);
+                                }
+                            }
+                        }
+
+                        // vibrate
+                        // Does the notification want to specify its own vibration?
+                        final boolean hasCustomVibrate = notification.vibrate != null;
+
+                        // new in 4.2: if there was supposed to be a sound and we're in vibrate
+                        // mode, and no other vibration is specified, we fall back to vibration
+                        final boolean convertSoundToVibration =
+                                   !hasCustomVibrate
+                                && hasValidSound
+                                && (audioManager.getRingerMode()
+                                           == AudioManager.RINGER_MODE_VIBRATE);
+
+                        // The DEFAULT_VIBRATE flag trumps any custom vibration AND the fallback.
+                        final boolean useDefaultVibrate =
+                                (notification.defaults & Notification.DEFAULT_VIBRATE) != 0;
+
+                        if ((useDefaultVibrate || convertSoundToVibration || hasCustomVibrate)
+                                && !(audioManager.getRingerMode()
+                                        == AudioManager.RINGER_MODE_SILENT)) {
+                            mVibrateNotification = r;
+
+                            if (useDefaultVibrate || convertSoundToVibration) {
+                                // Escalate privileges so we can use the vibrator even if the
+                                // notifying app does not have the VIBRATE permission.
+                                long identity = Binder.clearCallingIdentity();
+                                try {
+                                    mVibrator.vibrate(r.sbn.getUid(), r.sbn.getBasePkg(),
+                                        useDefaultVibrate ? mDefaultVibrationPattern
+                                            : mFallbackVibrationPattern,
+                                        ((notification.flags & Notification.FLAG_INSISTENT) != 0)
+                                                ? 0: -1);
+                                } finally {
+                                    Binder.restoreCallingIdentity(identity);
+                                }
+                            } else if (notification.vibrate.length > 1) {
+                                // If you want your own vibration pattern, you need the VIBRATE
+                                // permission
+                                mVibrator.vibrate(r.sbn.getUid(), r.sbn.getBasePkg(),
+                                        notification.vibrate,
+                                    ((notification.flags & Notification.FLAG_INSISTENT) != 0)
+                                            ? 0: -1);
+                            }
+                        }
+                    }
+
+                    // light
+                    // the most recent thing gets the light
+                    mLights.remove(old);
+                    if (mLedNotification == old) {
+                        mLedNotification = null;
+                    }
+                    //Slog.i(TAG, "notification.lights="
+                    //        + ((old.notification.lights.flags & Notification.FLAG_SHOW_LIGHTS)
+                    //                  != 0));
+                    if ((notification.flags & Notification.FLAG_SHOW_LIGHTS) != 0
+                            && canInterrupt) {
+                        mLights.add(r);
+                        updateLightsLocked();
+                    } else {
+                        if (old != null
+                                && ((old.getFlags() & Notification.FLAG_SHOW_LIGHTS) != 0)) {
+                            updateLightsLocked();
                         }
                     }
                 }
-
-                // vibrate
-                // Does the notification want to specify its own vibration?
-                final boolean hasCustomVibrate = notification.vibrate != null;
-
-                // new in 4.2: if there was supposed to be a sound and we're in vibrate mode,
-                // and no other vibration is specified, we fall back to vibration
-                final boolean convertSoundToVibration =
-                           !hasCustomVibrate
-                        && hasValidSound
-                        && (audioManager.getRingerMode() == AudioManager.RINGER_MODE_VIBRATE);
-
-                // The DEFAULT_VIBRATE flag trumps any custom vibration AND the fallback.
-                final boolean useDefaultVibrate =
-                        (notification.defaults & Notification.DEFAULT_VIBRATE) != 0;
-
-                if ((useDefaultVibrate || convertSoundToVibration || hasCustomVibrate)
-                        && !(audioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT)) {
-                    mVibrateNotification = r;
-
-                    if (useDefaultVibrate || convertSoundToVibration) {
-                        // Escalate privileges so we can use the vibrator even if the notifying app
-                        // does not have the VIBRATE permission.
-                        long identity = Binder.clearCallingIdentity();
-                        try {
-                            mVibrator.vibrate(r.sbn.getUid(), r.sbn.getBasePkg(),
-                                useDefaultVibrate ? mDefaultVibrationPattern
-                                    : mFallbackVibrationPattern,
-                                ((notification.flags & Notification.FLAG_INSISTENT) != 0) ? 0: -1);
-                        } finally {
-                            Binder.restoreCallingIdentity(identity);
-                        }
-                    } else if (notification.vibrate.length > 1) {
-                        // If you want your own vibration pattern, you need the VIBRATE permission
-                        mVibrator.vibrate(r.sbn.getUid(), r.sbn.getBasePkg(), notification.vibrate,
-                            ((notification.flags & Notification.FLAG_INSISTENT) != 0) ? 0: -1);
-                    }
-                }
             }
-
-            // light
-            // the most recent thing gets the light
-            mLights.remove(old);
-            if (mLedNotification == old) {
-                mLedNotification = null;
-            }
-            //Slog.i(TAG, "notification.lights="
-            //        + ((old.notification.lights.flags & Notification.FLAG_SHOW_LIGHTS) != 0));
-            if ((notification.flags & Notification.FLAG_SHOW_LIGHTS) != 0
-                    && canInterrupt) {
-                mLights.add(r);
-                updateLightsLocked();
-            } else {
-                if (old != null
-                        && ((old.getFlags() & Notification.FLAG_SHOW_LIGHTS) != 0)) {
-                    updateLightsLocked();
-                }
-            }
-        }
+        });
 
         idOut[0] = id;
     }
@@ -1980,29 +2047,39 @@
      * Cancels a notification ONLY if it has all of the {@code mustHaveFlags}
      * and none of the {@code mustNotHaveFlags}.
      */
-    private void cancelNotification(String pkg, String tag, int id, int mustHaveFlags,
-            int mustNotHaveFlags, boolean sendDelete, int userId) {
-        EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL, pkg, id, tag, userId,
-                mustHaveFlags, mustNotHaveFlags);
+    private void cancelNotification(final String pkg, final String tag, final int id,
+            final int mustHaveFlags, final int mustNotHaveFlags, final boolean sendDelete,
+            final int userId) {
+        // In enqueueNotificationInternal notifications are added by scheduling the
+        // work on the worker handler. Hence, we also schedule the cancel on this
+        // handler to avoid a scenario where an add notification call followed by a
+        // remove notification call ends up in not removing the notification.
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL, pkg, id, tag, userId,
+                        mustHaveFlags, mustNotHaveFlags);
 
-        synchronized (mNotificationList) {
-            int index = indexOfNotificationLocked(pkg, tag, id, userId);
-            if (index >= 0) {
-                NotificationRecord r = mNotificationList.get(index);
+                synchronized (mNotificationList) {
+                    int index = indexOfNotificationLocked(pkg, tag, id, userId);
+                    if (index >= 0) {
+                        NotificationRecord r = mNotificationList.get(index);
 
-                if ((r.getNotification().flags & mustHaveFlags) != mustHaveFlags) {
-                    return;
+                        if ((r.getNotification().flags & mustHaveFlags) != mustHaveFlags) {
+                            return;
+                        }
+                        if ((r.getNotification().flags & mustNotHaveFlags) != 0) {
+                            return;
+                        }
+
+                        mNotificationList.remove(index);
+
+                        cancelNotificationLocked(r, sendDelete);
+                        updateLightsLocked();
+                    }
                 }
-                if ((r.getNotification().flags & mustNotHaveFlags) != 0) {
-                    return;
-                }
-
-                mNotificationList.remove(index);
-
-                cancelNotificationLocked(r, sendDelete);
-                updateLightsLocked();
             }
-        }
+        });
     }
 
     /**
diff --git a/services/java/com/android/server/NsdService.java b/services/java/com/android/server/NsdService.java
index faa72a2..e0f415b 100644
--- a/services/java/com/android/server/NsdService.java
+++ b/services/java/com/android/server/NsdService.java
@@ -417,7 +417,15 @@
                 int keyId = clientInfo.mClientIds.indexOfValue(id);
                 if (keyId != -1) {
                     clientId = clientInfo.mClientIds.keyAt(keyId);
+                } else {
+                    // This can happen because of race conditions. For example,
+                    // SERVICE_FOUND may race with STOP_SERVICE_DISCOVERY,
+                    // and we may get in this situation.
+                    Slog.d(TAG, "Notification for a listener that is no longer active: " + id);
+                    handled = false;
+                    return handled;
                 }
+
                 switch (code) {
                     case NativeResponseCode.SERVICE_FOUND:
                         /* NNN uniqueId serviceName regType domain */
diff --git a/services/java/com/android/server/PreferredComponent.java b/services/java/com/android/server/PreferredComponent.java
index bb22545..134b198 100644
--- a/services/java/com/android/server/PreferredComponent.java
+++ b/services/java/com/android/server/PreferredComponent.java
@@ -33,8 +33,16 @@
 import java.util.List;
 
 public class PreferredComponent {
+    private static final String TAG_SET = "set";
+    private static final String ATTR_ALWAYS = "always"; // boolean
+    private static final String ATTR_MATCH = "match"; // number
+    private static final String ATTR_NAME = "name"; // component name
+    private static final String ATTR_SET = "set"; // number
+
     public final int mMatch;
     public final ComponentName mComponent;
+    // Whether this is to be the one that's always chosen. If false, it's the most recently chosen.
+    public boolean mAlways;
 
     private final String[] mSetPackages;
     private final String[] mSetClasses;
@@ -50,10 +58,11 @@
     }
 
     public PreferredComponent(Callbacks callbacks, int match, ComponentName[] set,
-            ComponentName component) {
+            ComponentName component, boolean always) {
         mCallbacks = callbacks;
         mMatch = match&IntentFilter.MATCH_CATEGORY_MASK;
         mComponent = component;
+        mAlways = always;
         mShortComponent = component.flattenToShortString();
         mParseError = null;
         if (set != null) {
@@ -86,15 +95,17 @@
     public PreferredComponent(Callbacks callbacks, XmlPullParser parser)
             throws XmlPullParserException, IOException {
         mCallbacks = callbacks;
-        mShortComponent = parser.getAttributeValue(null, "name");
+        mShortComponent = parser.getAttributeValue(null, ATTR_NAME);
         mComponent = ComponentName.unflattenFromString(mShortComponent);
         if (mComponent == null) {
             mParseError = "Bad activity name " + mShortComponent;
         }
-        String matchStr = parser.getAttributeValue(null, "match");
+        String matchStr = parser.getAttributeValue(null, ATTR_MATCH);
         mMatch = matchStr != null ? Integer.parseInt(matchStr, 16) : 0;
-        String setCountStr = parser.getAttributeValue(null, "set");
+        String setCountStr = parser.getAttributeValue(null, ATTR_SET);
         int setCount = setCountStr != null ? Integer.parseInt(setCountStr) : 0;
+        String alwaysStr = parser.getAttributeValue(null, ATTR_ALWAYS);
+        mAlways = alwaysStr != null ? Boolean.parseBoolean(alwaysStr) : true;
 
         String[] myPackages = setCount > 0 ? new String[setCount] : null;
         String[] myClasses = setCount > 0 ? new String[setCount] : null;
@@ -115,8 +126,8 @@
             String tagName = parser.getName();
             //Log.i(TAG, "Parse outerDepth=" + outerDepth + " depth="
             //        + parser.getDepth() + " tag=" + tagName);
-            if (tagName.equals("set")) {
-                String name = parser.getAttributeValue(null, "name");
+            if (tagName.equals(TAG_SET)) {
+                String name = parser.getAttributeValue(null, ATTR_NAME);
                 if (name == null) {
                     if (mParseError == null) {
                         mParseError = "No name in set tag in preferred activity "
@@ -166,16 +177,17 @@
 
     public void writeToXml(XmlSerializer serializer, boolean full) throws IOException {
         final int NS = mSetClasses != null ? mSetClasses.length : 0;
-        serializer.attribute(null, "name", mShortComponent);
+        serializer.attribute(null, ATTR_NAME, mShortComponent);
         if (full) {
             if (mMatch != 0) {
-                serializer.attribute(null, "match", Integer.toHexString(mMatch));
+                serializer.attribute(null, ATTR_MATCH, Integer.toHexString(mMatch));
             }
-            serializer.attribute(null, "set", Integer.toString(NS));
+            serializer.attribute(null, ATTR_ALWAYS, Boolean.toString(mAlways));
+            serializer.attribute(null, ATTR_SET, Integer.toString(NS));
             for (int s=0; s<NS; s++) {
-                serializer.startTag(null, "set");
-                serializer.attribute(null, "name", mSetComponents[s]);
-                serializer.endTag(null, "set");
+                serializer.startTag(null, TAG_SET);
+                serializer.attribute(null, ATTR_NAME, mSetComponents[s]);
+                serializer.endTag(null, TAG_SET);
             }
         }
     }
diff --git a/services/java/com/android/server/ProcessMap.java b/services/java/com/android/server/ProcessMap.java
deleted file mode 100644
index 6b26403..0000000
--- a/services/java/com/android/server/ProcessMap.java
+++ /dev/null
@@ -1,56 +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 com.android.server;
-
-import android.util.SparseArray;
-
-import java.util.HashMap;
-
-public class ProcessMap<E> {
-    final HashMap<String, SparseArray<E>> mMap
-            = new HashMap<String, SparseArray<E>>();
-    
-    public E get(String name, int uid) {
-        SparseArray<E> uids = mMap.get(name);
-        if (uids == null) return null;
-        return uids.get(uid);
-    }
-    
-    public E put(String name, int uid, E value) {
-        SparseArray<E> uids = mMap.get(name);
-        if (uids == null) {
-            uids = new SparseArray<E>(2);
-            mMap.put(name, uids);
-        }
-        uids.put(uid, value);
-        return value;
-    }
-    
-    public void remove(String name, int uid) {
-        SparseArray<E> uids = mMap.get(name);
-        if (uids != null) {
-            uids.remove(uid);
-            if (uids.size() == 0) {
-                mMap.remove(name);
-            }
-        }
-    }
-    
-    public HashMap<String, SparseArray<E>> getMap() {
-        return mMap;
-    }
-}
diff --git a/services/java/com/android/server/StatusBarManagerService.java b/services/java/com/android/server/StatusBarManagerService.java
index c21d8c6..f207c08 100644
--- a/services/java/com/android/server/StatusBarManagerService.java
+++ b/services/java/com/android/server/StatusBarManagerService.java
@@ -399,6 +399,15 @@
         mCurrentUserId = newUserId;
     }
 
+    @Override
+    public void setWindowState(int window, int state) {
+        if (mBar != null) {
+            try {
+                mBar.setWindowState(window, state);
+            } catch (RemoteException ex) {}
+        }
+    }
+
     private void enforceStatusBar() {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR,
                 "StatusBarManagerService");
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 9455017..d38756f 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -44,6 +44,7 @@
 import android.util.Slog;
 import android.view.WindowManager;
 
+import com.android.internal.R;
 import com.android.internal.os.BinderInternal;
 import com.android.internal.os.SamplingProfilerIntegration;
 import com.android.server.accessibility.AccessibilityManagerService;
@@ -62,6 +63,7 @@
 import com.android.server.pm.UserManagerService;
 import com.android.server.power.PowerManagerService;
 import com.android.server.power.ShutdownThread;
+import com.android.server.print.PrintManagerService;
 import com.android.server.search.SearchManagerService;
 import com.android.server.usb.UsbService;
 import com.android.server.wifi.WifiService;
@@ -74,7 +76,7 @@
 import java.util.Timer;
 import java.util.TimerTask;
 
-class ServerThread extends Thread {
+class ServerThread {
     private static final String TAG = "SystemServer";
     private static final String ENCRYPTING_STATE = "trigger_restart_min_framework";
     private static final String ENCRYPTED_STATE = "1";
@@ -86,8 +88,7 @@
         Log.wtf(TAG, "BOOT FAILURE " + msg, e);
     }
 
-    @Override
-    public void run() {
+    public void initAndLoop() {
         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN,
             SystemClock.uptimeMillis());
 
@@ -153,30 +154,7 @@
         CommonTimeManagementService commonTimeMgmtService = null;
         InputManagerService inputManager = null;
         TelephonyRegistry telephonyRegistry = null;
-
-        // Create a shared handler thread for UI within the system server.
-        // This thread is used by at least the following components:
-        // - WindowManagerPolicy
-        // - KeyguardViewManager
-        // - DisplayManagerService
-        HandlerThread uiHandlerThread = new HandlerThread("UI");
-        uiHandlerThread.start();
-        Handler uiHandler = new Handler(uiHandlerThread.getLooper());
-        uiHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                //Looper.myLooper().setMessageLogging(new LogPrinter(
-                //        Log.VERBOSE, "WindowManagerPolicy", Log.LOG_ID_SYSTEM));
-                android.os.Process.setThreadPriority(
-                        android.os.Process.THREAD_PRIORITY_FOREGROUND);
-                android.os.Process.setCanSelfBackground(false);
-
-                // For debug builds, log event loop stalls to dropbox for analysis.
-                if (StrictMode.conditionallyEnableDebugLogging()) {
-                    Slog.i(TAG, "Enabled StrictMode logging for UI Looper");
-                }
-            }
-        });
+        ConsumerIrService consumerIr = null;
 
         // Create a handler thread just for the window manager to enjoy.
         HandlerThread wmHandlerThread = new HandlerThread("WindowManager");
@@ -198,8 +176,9 @@
             }
         });
 
-        // Critical services...
+        // bootstrap services
         boolean onlyCore = false;
+        boolean firstBoot = false;
         try {
             // Wait for installd to finished starting up so that it has a chance to
             // create critical directories such as /data/user with the appropriate
@@ -214,9 +193,23 @@
 
             Slog.i(TAG, "Activity Manager");
             context = ActivityManagerService.main(factoryTest);
+        } catch (RuntimeException e) {
+            Slog.e("System", "******************************************");
+            Slog.e("System", "************ Failure starting bootstrap service", e);
+        }
 
+        boolean disableStorage = SystemProperties.getBoolean("config.disable_storage", false);
+        boolean disableMedia = SystemProperties.getBoolean("config.disable_media", false);
+        boolean disableBluetooth = SystemProperties.getBoolean("config.disable_bluetooth", false);
+        boolean disableTelephony = SystemProperties.getBoolean("config.disable_telephony", false);
+        boolean disableLocation = SystemProperties.getBoolean("config.disable_location", false);
+        boolean disableSystemUI = SystemProperties.getBoolean("config.disable_systemui", false);
+        boolean disableNonCoreServices = SystemProperties.getBoolean("config.disable_noncore", false);
+        boolean disableNetwork = SystemProperties.getBoolean("config.disable_network", false);
+
+        try {
             Slog.i(TAG, "Display Manager");
-            display = new DisplayManagerService(context, wmHandler, uiHandler);
+            display = new DisplayManagerService(context, wmHandler);
             ServiceManager.addService(Context.DISPLAY_SERVICE, display, true);
 
             Slog.i(TAG, "Telephony Registry");
@@ -248,7 +241,6 @@
             pm = PackageManagerService.main(context, installer,
                     factoryTest != SystemServer.FACTORY_TEST_OFF,
                     onlyCore);
-            boolean firstBoot = false;
             try {
                 firstBoot = pm.isFirstBoot();
             } catch (RemoteException e) {
@@ -267,6 +259,7 @@
 
             // The AccountManager must come before the ContentService
             try {
+                // TODO: seems like this should be disable-able, but req'd by ContentService
                 Slog.i(TAG, "Account Manager");
                 accountManager = new AccountManagerService(context);
                 ServiceManager.addService(Context.ACCOUNT_SERVICE, accountManager);
@@ -292,10 +285,15 @@
             vibrator = new VibratorService(context);
             ServiceManager.addService("vibrator", vibrator);
 
+            Slog.i(TAG, "Consumer IR Service");
+            consumerIr = new ConsumerIrService(context);
+            ServiceManager.addService(Context.CONSUMER_IR_SERVICE, consumerIr);
+
             // only initialize the power service after we have started the
             // lights service, content providers and the battery service.
             power.init(context, lights, ActivityManagerService.self(), battery,
-                    BatteryStatsService.getService(), display);
+                    BatteryStatsService.getService(),
+                    ActivityManagerService.self().getAppOpsService(), display);
 
             Slog.i(TAG, "Alarm Manager");
             alarm = new AlarmManagerService(context);
@@ -304,14 +302,14 @@
             Slog.i(TAG, "Init Watchdog");
             Watchdog.getInstance().init(context, battery, power, alarm,
                     ActivityManagerService.self());
+            Watchdog.getInstance().addThread(wmHandler, "WindowManager thread");
 
             Slog.i(TAG, "Input Manager");
             inputManager = new InputManagerService(context, wmHandler);
 
             Slog.i(TAG, "Window Manager");
             wm = WindowManagerService.main(context, power, display, inputManager,
-                    uiHandler, wmHandler,
-                    factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL,
+                    wmHandler, factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL,
                     !firstBoot, onlyCore);
             ServiceManager.addService(Context.WINDOW_SERVICE, wm);
             ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
@@ -334,12 +332,13 @@
             } else if (!context.getPackageManager().hasSystemFeature
                        (PackageManager.FEATURE_BLUETOOTH)) {
                 Slog.i(TAG, "No Bluetooth Service (Bluetooth Hardware Not Present)");
+            } else if (disableBluetooth) {
+                Slog.i(TAG, "Bluetooth Service disabled by config");
             } else {
                 Slog.i(TAG, "Bluetooth Manager Service");
                 bluetooth = new BluetoothManagerService(context);
                 ServiceManager.addService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, bluetooth);
             }
-
         } catch (RuntimeException e) {
             Slog.e("System", "******************************************");
             Slog.e("System", "************ Failure starting core service", e);
@@ -356,23 +355,28 @@
         TextServicesManagerService tsms = null;
         LockSettingsService lockSettings = null;
         DreamManagerService dreamy = null;
+        AssetAtlasService atlas = null;
+        PrintManagerService printManager = null;
 
         // Bring up services needed for UI.
         if (factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
-            try {
-                Slog.i(TAG, "Input Method Service");
-                imm = new InputMethodManagerService(context, wm);
-                ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);
-            } catch (Throwable e) {
-                reportWtf("starting Input Manager Service", e);
-            }
+            //if (!disableNonCoreServices) { // TODO: View depends on these; mock them?
+            if (true) {
+                try {
+                    Slog.i(TAG, "Input Method Service");
+                    imm = new InputMethodManagerService(context, wm);
+                    ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);
+                } catch (Throwable e) {
+                    reportWtf("starting Input Manager Service", e);
+                }
 
-            try {
-                Slog.i(TAG, "Accessibility Manager");
-                ServiceManager.addService(Context.ACCESSIBILITY_SERVICE,
-                        new AccessibilityManagerService(context));
-            } catch (Throwable e) {
-                reportWtf("starting Accessibility Manager", e);
+                try {
+                    Slog.i(TAG, "Accessibility Manager");
+                    ServiceManager.addService(Context.ACCESSIBILITY_SERVICE,
+                            new AccessibilityManagerService(context));
+                } catch (Throwable e) {
+                    reportWtf("starting Accessibility Manager", e);
+                }
             }
         }
 
@@ -397,7 +401,8 @@
         }
 
         if (factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
-            if (!"0".equals(SystemProperties.get("system_init.startmountservice"))) {
+            if (!disableStorage &&
+                !"0".equals(SystemProperties.get("system_init.startmountservice"))) {
                 try {
                     /*
                      * NotificationManagerService is dependant on MountService,
@@ -411,116 +416,130 @@
                 }
             }
 
-            try {
-                Slog.i(TAG,  "LockSettingsService");
-                lockSettings = new LockSettingsService(context);
-                ServiceManager.addService("lock_settings", lockSettings);
-            } catch (Throwable e) {
-                reportWtf("starting LockSettingsService service", e);
+            if (!disableNonCoreServices) {
+                try {
+                    Slog.i(TAG,  "LockSettingsService");
+                    lockSettings = new LockSettingsService(context);
+                    ServiceManager.addService("lock_settings", lockSettings);
+                } catch (Throwable e) {
+                    reportWtf("starting LockSettingsService service", e);
+                }
+
+                try {
+                    Slog.i(TAG, "Device Policy");
+                    devicePolicy = new DevicePolicyManagerService(context);
+                    ServiceManager.addService(Context.DEVICE_POLICY_SERVICE, devicePolicy);
+                } catch (Throwable e) {
+                    reportWtf("starting DevicePolicyService", e);
+                }
             }
 
-            try {
-                Slog.i(TAG, "Device Policy");
-                devicePolicy = new DevicePolicyManagerService(context);
-                ServiceManager.addService(Context.DEVICE_POLICY_SERVICE, devicePolicy);
-            } catch (Throwable e) {
-                reportWtf("starting DevicePolicyService", e);
+            if (!disableSystemUI) {
+                try {
+                    Slog.i(TAG, "Status Bar");
+                    statusBar = new StatusBarManagerService(context, wm);
+                    ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);
+                } catch (Throwable e) {
+                    reportWtf("starting StatusBarManagerService", e);
+                }
             }
 
-            try {
-                Slog.i(TAG, "Status Bar");
-                statusBar = new StatusBarManagerService(context, wm);
-                ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);
-            } catch (Throwable e) {
-                reportWtf("starting StatusBarManagerService", e);
+            if (!disableNonCoreServices) {
+                try {
+                    Slog.i(TAG, "Clipboard Service");
+                    ServiceManager.addService(Context.CLIPBOARD_SERVICE,
+                            new ClipboardService(context));
+                } catch (Throwable e) {
+                    reportWtf("starting Clipboard Service", e);
+                }
             }
 
-            try {
-                Slog.i(TAG, "Clipboard Service");
-                ServiceManager.addService(Context.CLIPBOARD_SERVICE,
-                        new ClipboardService(context));
-            } catch (Throwable e) {
-                reportWtf("starting Clipboard Service", e);
+            if (!disableNetwork) {
+                try {
+                    Slog.i(TAG, "NetworkManagement Service");
+                    networkManagement = NetworkManagementService.create(context);
+                    ServiceManager.addService(Context.NETWORKMANAGEMENT_SERVICE, networkManagement);
+                } catch (Throwable e) {
+                    reportWtf("starting NetworkManagement Service", e);
+                }
             }
 
-            try {
-                Slog.i(TAG, "NetworkManagement Service");
-                networkManagement = NetworkManagementService.create(context);
-                ServiceManager.addService(Context.NETWORKMANAGEMENT_SERVICE, networkManagement);
-            } catch (Throwable e) {
-                reportWtf("starting NetworkManagement Service", e);
+            if (!disableNonCoreServices) {
+                try {
+                    Slog.i(TAG, "Text Service Manager Service");
+                    tsms = new TextServicesManagerService(context);
+                    ServiceManager.addService(Context.TEXT_SERVICES_MANAGER_SERVICE, tsms);
+                } catch (Throwable e) {
+                    reportWtf("starting Text Service Manager Service", e);
+                }
             }
 
-            try {
-                Slog.i(TAG, "Text Service Manager Service");
-                tsms = new TextServicesManagerService(context);
-                ServiceManager.addService(Context.TEXT_SERVICES_MANAGER_SERVICE, tsms);
-            } catch (Throwable e) {
-                reportWtf("starting Text Service Manager Service", e);
+            if (!disableNetwork) {
+                try {
+                    Slog.i(TAG, "NetworkStats Service");
+                    networkStats = new NetworkStatsService(context, networkManagement, alarm);
+                    ServiceManager.addService(Context.NETWORK_STATS_SERVICE, networkStats);
+                } catch (Throwable e) {
+                    reportWtf("starting NetworkStats Service", e);
+                }
+
+                try {
+                    Slog.i(TAG, "NetworkPolicy Service");
+                    networkPolicy = new NetworkPolicyManagerService(
+                            context, ActivityManagerService.self(), power,
+                            networkStats, networkManagement);
+                    ServiceManager.addService(Context.NETWORK_POLICY_SERVICE, networkPolicy);
+                } catch (Throwable e) {
+                    reportWtf("starting NetworkPolicy Service", e);
+                }
+
+               try {
+                    Slog.i(TAG, "Wi-Fi P2pService");
+                    wifiP2p = new WifiP2pService(context);
+                    ServiceManager.addService(Context.WIFI_P2P_SERVICE, wifiP2p);
+                } catch (Throwable e) {
+                    reportWtf("starting Wi-Fi P2pService", e);
+                }
+
+               try {
+                    Slog.i(TAG, "Wi-Fi Service");
+                    wifi = new WifiService(context);
+                    ServiceManager.addService(Context.WIFI_SERVICE, wifi);
+                } catch (Throwable e) {
+                    reportWtf("starting Wi-Fi Service", e);
+                }
+
+                try {
+                    Slog.i(TAG, "Connectivity Service");
+                    connectivity = new ConnectivityService(
+                            context, networkManagement, networkStats, networkPolicy);
+                    ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);
+                    networkStats.bindConnectivityManager(connectivity);
+                    networkPolicy.bindConnectivityManager(connectivity);
+                    wifi.checkAndStartWifi();
+                    wifiP2p.connectivityServiceReady();
+                } catch (Throwable e) {
+                    reportWtf("starting Connectivity Service", e);
+                }
+
+                try {
+                    Slog.i(TAG, "Network Service Discovery Service");
+                    serviceDiscovery = NsdService.create(context);
+                    ServiceManager.addService(
+                            Context.NSD_SERVICE, serviceDiscovery);
+                } catch (Throwable e) {
+                    reportWtf("starting Service Discovery Service", e);
+                }
             }
 
-            try {
-                Slog.i(TAG, "NetworkStats Service");
-                networkStats = new NetworkStatsService(context, networkManagement, alarm);
-                ServiceManager.addService(Context.NETWORK_STATS_SERVICE, networkStats);
-            } catch (Throwable e) {
-                reportWtf("starting NetworkStats Service", e);
-            }
-
-            try {
-                Slog.i(TAG, "NetworkPolicy Service");
-                networkPolicy = new NetworkPolicyManagerService(
-                        context, ActivityManagerService.self(), power,
-                        networkStats, networkManagement);
-                ServiceManager.addService(Context.NETWORK_POLICY_SERVICE, networkPolicy);
-            } catch (Throwable e) {
-                reportWtf("starting NetworkPolicy Service", e);
-            }
-
-           try {
-                Slog.i(TAG, "Wi-Fi P2pService");
-                wifiP2p = new WifiP2pService(context);
-                ServiceManager.addService(Context.WIFI_P2P_SERVICE, wifiP2p);
-            } catch (Throwable e) {
-                reportWtf("starting Wi-Fi P2pService", e);
-            }
-
-           try {
-                Slog.i(TAG, "Wi-Fi Service");
-                wifi = new WifiService(context);
-                ServiceManager.addService(Context.WIFI_SERVICE, wifi);
-            } catch (Throwable e) {
-                reportWtf("starting Wi-Fi Service", e);
-            }
-
-            try {
-                Slog.i(TAG, "Connectivity Service");
-                connectivity = new ConnectivityService(
-                        context, networkManagement, networkStats, networkPolicy);
-                ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);
-                networkStats.bindConnectivityManager(connectivity);
-                networkPolicy.bindConnectivityManager(connectivity);
-                wifi.checkAndStartWifi();
-                wifiP2p.connectivityServiceReady();
-            } catch (Throwable e) {
-                reportWtf("starting Connectivity Service", e);
-            }
-
-            try {
-                Slog.i(TAG, "Network Service Discovery Service");
-                serviceDiscovery = NsdService.create(context);
-                ServiceManager.addService(
-                        Context.NSD_SERVICE, serviceDiscovery);
-            } catch (Throwable e) {
-                reportWtf("starting Service Discovery Service", e);
-            }
-
-            try {
-                Slog.i(TAG, "UpdateLock Service");
-                ServiceManager.addService(Context.UPDATE_LOCK_SERVICE,
-                        new UpdateLockService(context));
-            } catch (Throwable e) {
-                reportWtf("starting UpdateLockService", e);
+            if (!disableNonCoreServices) {
+                try {
+                    Slog.i(TAG, "UpdateLock Service");
+                    ServiceManager.addService(Context.UPDATE_LOCK_SERVICE,
+                            new UpdateLockService(context));
+                } catch (Throwable e) {
+                    reportWtf("starting UpdateLockService", e);
+                }
             }
 
             /*
@@ -528,7 +547,7 @@
              * AppWidget Provider. Make sure MountService is completely started
              * first before continuing.
              */
-            if (mountService != null) {
+            if (mountService != null && !onlyCore) {
                 mountService.waitForAsecScan();
             }
 
@@ -563,28 +582,32 @@
                 reportWtf("starting DeviceStorageMonitor service", e);
             }
 
-            try {
-                Slog.i(TAG, "Location Manager");
-                location = new LocationManagerService(context);
-                ServiceManager.addService(Context.LOCATION_SERVICE, location);
-            } catch (Throwable e) {
-                reportWtf("starting Location Manager", e);
+            if (!disableLocation) {
+                try {
+                    Slog.i(TAG, "Location Manager");
+                    location = new LocationManagerService(context);
+                    ServiceManager.addService(Context.LOCATION_SERVICE, location);
+                } catch (Throwable e) {
+                    reportWtf("starting Location Manager", e);
+                }
+
+                try {
+                    Slog.i(TAG, "Country Detector");
+                    countryDetector = new CountryDetectorService(context);
+                    ServiceManager.addService(Context.COUNTRY_DETECTOR, countryDetector);
+                } catch (Throwable e) {
+                    reportWtf("starting Country Detector", e);
+                }
             }
 
-            try {
-                Slog.i(TAG, "Country Detector");
-                countryDetector = new CountryDetectorService(context);
-                ServiceManager.addService(Context.COUNTRY_DETECTOR, countryDetector);
-            } catch (Throwable e) {
-                reportWtf("starting Country Detector", e);
-            }
-
-            try {
-                Slog.i(TAG, "Search Service");
-                ServiceManager.addService(Context.SEARCH_SERVICE,
-                        new SearchManagerService(context));
-            } catch (Throwable e) {
-                reportWtf("starting Search Service", e);
+            if (!disableNonCoreServices) {
+                try {
+                    Slog.i(TAG, "Search Service");
+                    ServiceManager.addService(Context.SEARCH_SERVICE,
+                            new SearchManagerService(context));
+                } catch (Throwable e) {
+                    reportWtf("starting Search Service", e);
+                }
             }
 
             try {
@@ -595,8 +618,8 @@
                 reportWtf("starting DropBoxManagerService", e);
             }
 
-            if (context.getResources().getBoolean(
-                        com.android.internal.R.bool.config_enableWallpaperService)) {
+            if (!disableNonCoreServices && context.getResources().getBoolean(
+                        R.bool.config_enableWallpaperService)) {
                 try {
                     Slog.i(TAG, "Wallpaper Service");
                     if (!headless) {
@@ -608,7 +631,7 @@
                 }
             }
 
-            if (!"0".equals(SystemProperties.get("system_init.startaudioservice"))) {
+            if (!disableMedia && !"0".equals(SystemProperties.get("system_init.startaudioservice"))) {
                 try {
                     Slog.i(TAG, "Audio Service");
                     ServiceManager.addService(Context.AUDIO_SERVICE, new AudioService(context));
@@ -617,39 +640,45 @@
                 }
             }
 
-            try {
-                Slog.i(TAG, "Dock Observer");
-                // Listen for dock station changes
-                dock = new DockObserver(context);
-            } catch (Throwable e) {
-                reportWtf("starting DockObserver", e);
+            if (!disableNonCoreServices) {
+                try {
+                    Slog.i(TAG, "Dock Observer");
+                    // Listen for dock station changes
+                    dock = new DockObserver(context);
+                } catch (Throwable e) {
+                    reportWtf("starting DockObserver", e);
+                }
             }
 
-            try {
-                Slog.i(TAG, "Wired Accessory Manager");
-                // Listen for wired headset changes
-                inputManager.setWiredAccessoryCallbacks(
-                        new WiredAccessoryManager(context, inputManager));
-            } catch (Throwable e) {
-                reportWtf("starting WiredAccessoryManager", e);
+            if (!disableMedia) {
+                try {
+                    Slog.i(TAG, "Wired Accessory Manager");
+                    // Listen for wired headset changes
+                    inputManager.setWiredAccessoryCallbacks(
+                            new WiredAccessoryManager(context, inputManager));
+                } catch (Throwable e) {
+                    reportWtf("starting WiredAccessoryManager", e);
+                }
             }
 
-            try {
-                Slog.i(TAG, "USB Service");
-                // Manage USB host and device support
-                usb = new UsbService(context);
-                ServiceManager.addService(Context.USB_SERVICE, usb);
-            } catch (Throwable e) {
-                reportWtf("starting UsbService", e);
-            }
+            if (!disableNonCoreServices) {
+                try {
+                    Slog.i(TAG, "USB Service");
+                    // Manage USB host and device support
+                    usb = new UsbService(context);
+                    ServiceManager.addService(Context.USB_SERVICE, usb);
+                } catch (Throwable e) {
+                    reportWtf("starting UsbService", e);
+                }
 
-            try {
-                Slog.i(TAG, "Serial Service");
-                // Serial port support
-                serial = new SerialService(context);
-                ServiceManager.addService(Context.SERIAL_SERVICE, serial);
-            } catch (Throwable e) {
-                Slog.e(TAG, "Failure starting SerialService", e);
+                try {
+                    Slog.i(TAG, "Serial Service");
+                    // Serial port support
+                    serial = new SerialService(context);
+                    ServiceManager.addService(Context.SERIAL_SERVICE, serial);
+                } catch (Throwable e) {
+                    Slog.e(TAG, "Failure starting SerialService", e);
+                }
             }
 
             try {
@@ -667,27 +696,29 @@
                 reportWtf("starting UiModeManagerService", e);
             }
 
-            try {
-                Slog.i(TAG, "Backup Service");
-                ServiceManager.addService(Context.BACKUP_SERVICE,
-                        new BackupManagerService(context));
-            } catch (Throwable e) {
-                Slog.e(TAG, "Failure starting Backup Service", e);
-            }
+            if (!disableNonCoreServices) {
+                try {
+                    Slog.i(TAG, "Backup Service");
+                    ServiceManager.addService(Context.BACKUP_SERVICE,
+                            new BackupManagerService(context));
+                } catch (Throwable e) {
+                    Slog.e(TAG, "Failure starting Backup Service", e);
+                }
 
-            try {
-                Slog.i(TAG, "AppWidget Service");
-                appWidget = new AppWidgetService(context);
-                ServiceManager.addService(Context.APPWIDGET_SERVICE, appWidget);
-            } catch (Throwable e) {
-                reportWtf("starting AppWidget Service", e);
-            }
+                try {
+                    Slog.i(TAG, "AppWidget Service");
+                    appWidget = new AppWidgetService(context);
+                    ServiceManager.addService(Context.APPWIDGET_SERVICE, appWidget);
+                } catch (Throwable e) {
+                    reportWtf("starting AppWidget Service", e);
+                }
 
-            try {
-                Slog.i(TAG, "Recognition Service");
-                recognition = new RecognitionManagerService(context);
-            } catch (Throwable e) {
-                reportWtf("starting Recognition Service", e);
+                try {
+                    Slog.i(TAG, "Recognition Service");
+                    recognition = new RecognitionManagerService(context);
+                } catch (Throwable e) {
+                    reportWtf("starting Recognition Service", e);
+                }
             }
 
             try {
@@ -709,30 +740,36 @@
                 reportWtf("starting SamplingProfiler Service", e);
             }
 
-            try {
-                Slog.i(TAG, "NetworkTimeUpdateService");
-                networkTimeUpdater = new NetworkTimeUpdateService(context);
-            } catch (Throwable e) {
-                reportWtf("starting NetworkTimeUpdate service", e);
+            if (!disableNetwork) {
+                try {
+                    Slog.i(TAG, "NetworkTimeUpdateService");
+                    networkTimeUpdater = new NetworkTimeUpdateService(context);
+                } catch (Throwable e) {
+                    reportWtf("starting NetworkTimeUpdate service", e);
+                }
             }
 
-            try {
-                Slog.i(TAG, "CommonTimeManagementService");
-                commonTimeMgmtService = new CommonTimeManagementService(context);
-                ServiceManager.addService("commontime_management", commonTimeMgmtService);
-            } catch (Throwable e) {
-                reportWtf("starting CommonTimeManagementService service", e);
+            if (!disableMedia) {
+                try {
+                    Slog.i(TAG, "CommonTimeManagementService");
+                    commonTimeMgmtService = new CommonTimeManagementService(context);
+                    ServiceManager.addService("commontime_management", commonTimeMgmtService);
+                } catch (Throwable e) {
+                    reportWtf("starting CommonTimeManagementService service", e);
+                }
             }
 
-            try {
-                Slog.i(TAG, "CertBlacklister");
-                CertBlacklister blacklister = new CertBlacklister(context);
-            } catch (Throwable e) {
-                reportWtf("starting CertBlacklister", e);
+            if (!disableNetwork) {
+                try {
+                    Slog.i(TAG, "CertBlacklister");
+                    CertBlacklister blacklister = new CertBlacklister(context);
+                } catch (Throwable e) {
+                    reportWtf("starting CertBlacklister", e);
+                }
             }
-            
-            if (context.getResources().getBoolean(
-                    com.android.internal.R.bool.config_dreamsSupported)) {
+
+            if (!disableNonCoreServices && 
+                context.getResources().getBoolean(R.bool.config_dreamsSupported)) {
                 try {
                     Slog.i(TAG, "Dreams Service");
                     // Dreams (interactive idle-time views, a/k/a screen savers)
@@ -743,12 +780,30 @@
                 }
             }
 
+            if (!disableNonCoreServices) {
+                try {
+                    Slog.i(TAG, "Assets Atlas Service");
+                    atlas = new AssetAtlasService(context);
+                    ServiceManager.addService(AssetAtlasService.ASSET_ATLAS_SERVICE, atlas);
+                } catch (Throwable e) {
+                    reportWtf("starting AssetAtlasService", e);
+                }
+            }
+
             try {
                 Slog.i(TAG, "IdleMaintenanceService");
                 new IdleMaintenanceService(context, battery);
             } catch (Throwable e) {
                 reportWtf("starting IdleMaintenanceService", e);
             }
+
+            try {
+                Slog.i(TAG, "Print Service");
+                printManager = new PrintManagerService(context);
+                ServiceManager.addService(Context.PRINT_SERVICE, printManager);
+            } catch (Throwable e) {
+                reportWtf("starting Print Service", e);
+            }
         }
 
         // Before things start rolling, be sure we have decided whether
@@ -773,10 +828,12 @@
             reportWtf("making Vibrator Service ready", e);
         }
 
-        try {
-            lockSettings.systemReady();
-        } catch (Throwable e) {
-            reportWtf("making Lock Settings Service ready", e);
+        if (lockSettings != null) {
+            try {
+                lockSettings.systemReady();
+            } catch (Throwable e) {
+                reportWtf("making Lock Settings Service ready", e);
+            }
         }
 
         if (devicePolicy != null) {
@@ -855,8 +912,10 @@
         final TextServicesManagerService textServiceManagerServiceF = tsms;
         final StatusBarManagerService statusBarF = statusBar;
         final DreamManagerService dreamyF = dreamy;
+        final AssetAtlasService atlasF = atlas;
         final InputManagerService inputManagerF = inputManager;
         final TelephonyRegistry telephonyRegistryF = telephonyRegistry;
+        final PrintManagerService printManagerF = printManager;
 
         // We now tell the activity manager it is okay to run third party
         // code.  It will call back into us once it has gotten to the state
@@ -872,7 +931,9 @@
                 } catch (Throwable e) {
                     reportWtf("observing native crashes", e);
                 }
-                if (!headless) startSystemUi(contextF);
+                if (!headless) {
+                    startSystemUi(contextF);
+                }
                 try {
                     if (mountServiceF != null) mountServiceF.systemReady();
                 } catch (Throwable e) {
@@ -934,60 +995,73 @@
                 // third party code...
 
                 try {
-                    if (appWidgetF != null) appWidgetF.systemReady(safeMode);
+                    if (appWidgetF != null) appWidgetF.systemRunning(safeMode);
                 } catch (Throwable e) {
-                    reportWtf("making App Widget Service ready", e);
+                    reportWtf("Notifying AppWidgetService running", e);
                 }
                 try {
-                    if (wallpaperF != null) wallpaperF.systemReady();
+                    if (wallpaperF != null) wallpaperF.systemRunning();
                 } catch (Throwable e) {
-                    reportWtf("making Wallpaper Service ready", e);
+                    reportWtf("Notifying WallpaperService running", e);
                 }
                 try {
-                    if (immF != null) immF.systemReady(statusBarF);
+                    if (immF != null) immF.systemRunning(statusBarF);
                 } catch (Throwable e) {
-                    reportWtf("making Input Method Service ready", e);
+                    reportWtf("Notifying InputMethodService running", e);
                 }
                 try {
-                    if (locationF != null) locationF.systemReady();
+                    if (locationF != null) locationF.systemRunning();
                 } catch (Throwable e) {
-                    reportWtf("making Location Service ready", e);
+                    reportWtf("Notifying Location Service running", e);
                 }
                 try {
-                    if (countryDetectorF != null) countryDetectorF.systemReady();
+                    if (countryDetectorF != null) countryDetectorF.systemRunning();
                 } catch (Throwable e) {
-                    reportWtf("making Country Detector Service ready", e);
+                    reportWtf("Notifying CountryDetectorService running", e);
                 }
                 try {
-                    if (networkTimeUpdaterF != null) networkTimeUpdaterF.systemReady();
+                    if (networkTimeUpdaterF != null) networkTimeUpdaterF.systemRunning();
                 } catch (Throwable e) {
-                    reportWtf("making Network Time Service ready", e);
+                    reportWtf("Notifying NetworkTimeService running", e);
                 }
                 try {
-                    if (commonTimeMgmtServiceF != null) commonTimeMgmtServiceF.systemReady();
+                    if (commonTimeMgmtServiceF != null) commonTimeMgmtServiceF.systemRunning();
                 } catch (Throwable e) {
-                    reportWtf("making Common time management service ready", e);
+                    reportWtf("Notifying CommonTimeManagementService running", e);
                 }
                 try {
-                    if (textServiceManagerServiceF != null) textServiceManagerServiceF.systemReady();
+                    if (textServiceManagerServiceF != null)
+                        textServiceManagerServiceF.systemRunning();
                 } catch (Throwable e) {
-                    reportWtf("making Text Services Manager Service ready", e);
+                    reportWtf("Notifying TextServicesManagerService running", e);
                 }
                 try {
-                    if (dreamyF != null) dreamyF.systemReady();
+                    if (dreamyF != null) dreamyF.systemRunning();
                 } catch (Throwable e) {
-                    reportWtf("making DreamManagerService ready", e);
+                    reportWtf("Notifying DreamManagerService running", e);
+                }
+                try {
+                    if (atlasF != null) atlasF.systemRunning();
+                } catch (Throwable e) {
+                    reportWtf("Notifying AssetAtlasService running", e);
                 }
                 try {
                     // TODO(BT) Pass parameter to input manager
-                    if (inputManagerF != null) inputManagerF.systemReady();
+                    if (inputManagerF != null) inputManagerF.systemRunning();
                 } catch (Throwable e) {
-                    reportWtf("making InputManagerService ready", e);
+                    reportWtf("Notifying InputManagerService running", e);
                 }
+
                 try {
-                    if (telephonyRegistryF != null) telephonyRegistryF.systemReady();
+                    if (telephonyRegistryF != null) telephonyRegistryF.systemRunning();
                 } catch (Throwable e) {
-                    reportWtf("making TelephonyRegistry ready", e);
+                    reportWtf("Notifying TelephonyRegistry running", e);
+                }
+
+                try {
+                    if (printManagerF != null) printManagerF.systemRuning();
+                } catch (Throwable e) {
+                    reportWtf("Notifying PrintManagerService running", e);
                 }
             }
         });
@@ -1025,11 +1099,9 @@
     private static final long EARLIEST_SUPPORTED_TIME = 86400 * 1000;
 
     /**
-     * This method is called from Zygote to initialize the system. This will cause the native
-     * services (SurfaceFlinger, AudioFlinger, etc..) to be started. After that it will call back
-     * up into init2() to start the Android services.
+     * Called to initialize native system services.
      */
-    native public static void init1(String[] args);
+    private static native void nativeInit();
 
     public static void main(String[] args) {
         if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
@@ -1063,13 +1135,15 @@
         Environment.setUserRequired(true);
 
         System.loadLibrary("android_servers");
-        init1(args);
-    }
 
-    public static final void init2() {
         Slog.i(TAG, "Entered the Android system server!");
-        Thread thr = new ServerThread();
-        thr.setName("android.server.ServerThread");
-        thr.start();
+
+        // Initialize native services.
+        nativeInit();
+
+        // This used to be its own separate thread, but now it is
+        // just the loop we run on the main thread.
+        ServerThread thr = new ServerThread();
+        thr.initAndLoop();
     }
 }
diff --git a/services/java/com/android/server/TelephonyRegistry.java b/services/java/com/android/server/TelephonyRegistry.java
index 17260d5..699d79e 100644
--- a/services/java/com/android/server/TelephonyRegistry.java
+++ b/services/java/com/android/server/TelephonyRegistry.java
@@ -178,7 +178,7 @@
         mConnectedApns = new ArrayList<String>();
     }
 
-    public void systemReady() {
+    public void systemRunning() {
         // Watch for interesting updates
         final IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_USER_SWITCHED);
diff --git a/services/java/com/android/server/TextServicesManagerService.java b/services/java/com/android/server/TextServicesManagerService.java
index 7dd9988..0964767 100644
--- a/services/java/com/android/server/TextServicesManagerService.java
+++ b/services/java/com/android/server/TextServicesManagerService.java
@@ -76,7 +76,7 @@
             new HashMap<String, SpellCheckerBindGroup>();
     private final TextServicesSettings mSettings;
 
-    public void systemReady() {
+    public void systemRunning() {
         if (!mSystemReady) {
             mSystemReady = true;
         }
@@ -154,6 +154,8 @@
                         mContext, mSpellCheckerList, mSpellCheckerMap, mSettings);
                 // TODO: Update for each locale
                 SpellCheckerInfo sci = getCurrentSpellChecker(null);
+                // If no spell checker is enabled, just return. The user should explicitly
+                // enable the spell checker.
                 if (sci == null) return;
                 final String packageName = sci.getPackageName();
                 final int change = isPackageDisappearing(packageName);
diff --git a/services/java/com/android/server/TwilightService.java b/services/java/com/android/server/TwilightService.java
index 154de1c..0356faa 100644
--- a/services/java/com/android/server/TwilightService.java
+++ b/services/java/com/android/server/TwilightService.java
@@ -520,7 +520,7 @@
             Intent updateIntent = new Intent(ACTION_UPDATE_TWILIGHT_STATE);
             PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, updateIntent, 0);
             mAlarmManager.cancel(pendingIntent);
-            mAlarmManager.set(AlarmManager.RTC_WAKEUP, nextUpdate, pendingIntent);
+            mAlarmManager.setExact(AlarmManager.RTC, nextUpdate, pendingIntent);
         }
     };
 
diff --git a/services/java/com/android/server/UiThread.java b/services/java/com/android/server/UiThread.java
new file mode 100644
index 0000000..60d73aa
--- /dev/null
+++ b/services/java/com/android/server/UiThread.java
@@ -0,0 +1,71 @@
+/*
+ * 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.server;
+
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.StrictMode;
+import android.util.Slog;
+
+/**
+ * Shared singleton thread for showing UI.  This is a foreground thread, and in
+ * additional should not have operations that can take more than a few ms scheduled
+ * on it to avoid UI jank.
+ */
+public final class UiThread extends HandlerThread {
+    private static UiThread sInstance;
+    private static Handler sHandler;
+
+    private UiThread() {
+        super("android.ui", android.os.Process.THREAD_PRIORITY_FOREGROUND);
+    }
+
+    private static void ensureThreadLocked() {
+        if (sInstance == null) {
+            sInstance = new UiThread();
+            sInstance.start();
+            sHandler = new Handler(sInstance.getLooper());
+            sHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    //Looper.myLooper().setMessageLogging(new LogPrinter(
+                    //        Log.VERBOSE, "WindowManagerPolicy", Log.LOG_ID_SYSTEM));
+                    android.os.Process.setCanSelfBackground(false);
+
+                    // For debug builds, log event loop stalls to dropbox for analysis.
+                    if (StrictMode.conditionallyEnableDebugLogging()) {
+                        Slog.i("UiThread", "Enabled StrictMode logging for UI thread");
+                    }
+                }
+            });
+        }
+    }
+
+    public static UiThread get() {
+        synchronized (UiThread.class) {
+            ensureThreadLocked();
+            return sInstance;
+        }
+    }
+
+    public static Handler getHandler() {
+        synchronized (UiThread.class) {
+            ensureThreadLocked();
+            return sHandler;
+        }
+    }
+}
diff --git a/services/java/com/android/server/VibratorService.java b/services/java/com/android/server/VibratorService.java
index 21d3111..28eb948 100644
--- a/services/java/com/android/server/VibratorService.java
+++ b/services/java/com/android/server/VibratorService.java
@@ -24,6 +24,7 @@
 import android.content.pm.PackageManager;
 import android.database.ContentObserver;
 import android.hardware.input.InputManager;
+import android.os.BatteryStats;
 import android.os.Handler;
 import android.os.IVibratorService;
 import android.os.PowerManager;
@@ -143,7 +144,8 @@
         mWakeLock.setReferenceCounted(true);
 
         mAppOpsService = IAppOpsService.Stub.asInterface(ServiceManager.getService(Context.APP_OPS_SERVICE));
-        mBatteryStatsService = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo"));
+        mBatteryStatsService = IBatteryStats.Stub.asInterface(ServiceManager.getService(
+                BatteryStats.SERVICE_NAME));
 
         mVibrations = new LinkedList<Vibration>();
 
@@ -340,7 +342,8 @@
     // Lock held on mVibrations
     private void startVibrationLocked(final Vibration vib) {
         try {
-            int mode = mAppOpsService.startOperation(AppOpsManager.OP_VIBRATE, vib.mUid, vib.mPackageName);
+            int mode = mAppOpsService.startOperation(AppOpsManager.getToken(mAppOpsService),
+                    AppOpsManager.OP_VIBRATE, vib.mUid, vib.mPackageName);
             if (mode != AppOpsManager.MODE_ALLOWED) {
                 if (mode == AppOpsManager.MODE_ERRORED) {
                     Slog.w(TAG, "Would be an error: vibrate from uid " + vib.mUid);
@@ -364,7 +367,8 @@
     private void reportFinishVibrationLocked() {
         if (mCurrentVibration != null) {
             try {
-                mAppOpsService.finishOperation(AppOpsManager.OP_VIBRATE, mCurrentVibration.mUid,
+                mAppOpsService.finishOperation(AppOpsManager.getToken(mAppOpsService),
+                        AppOpsManager.OP_VIBRATE, mCurrentVibration.mUid,
                         mCurrentVibration.mPackageName);
             } catch (RemoteException e) {
             }
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index 6823f136..162add4 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -449,7 +449,7 @@
         }
     }
 
-    public void systemReady() {
+    public void systemRunning() {
         if (DEBUG) Slog.v(TAG, "systemReady");
         WallpaperData wallpaper = mWallpaperMap.get(UserHandle.USER_OWNER);
         switchWallpaper(wallpaper, null);
@@ -821,6 +821,11 @@
             int serviceUserId = wallpaper.userId;
             ServiceInfo si = mIPackageManager.getServiceInfo(componentName,
                     PackageManager.GET_META_DATA | PackageManager.GET_PERMISSIONS, serviceUserId);
+            if (si == null) {
+                // The wallpaper component we're trying to use doesn't exist
+                Slog.w(TAG, "Attempted wallpaper " + componentName + " is unavailable");
+                return false;
+            }
             if (!android.Manifest.permission.BIND_WALLPAPER.equals(si.permission)) {
                 String msg = "Selected service does not require "
                         + android.Manifest.permission.BIND_WALLPAPER
@@ -885,7 +890,8 @@
                     Intent.createChooser(new Intent(Intent.ACTION_SET_WALLPAPER),
                             mContext.getText(com.android.internal.R.string.chooser_wallpaper)),
                     0, null, new UserHandle(serviceUserId)));
-            if (!mContext.bindServiceAsUser(intent, newConn, Context.BIND_AUTO_CREATE,
+            if (!mContext.bindServiceAsUser(intent, newConn,
+                    Context.BIND_AUTO_CREATE | Context.BIND_SHOWING_UI,
                     new UserHandle(serviceUserId))) {
                 String msg = "Unable to bind service: "
                         + componentName;
diff --git a/services/java/com/android/server/Watchdog.java b/services/java/com/android/server/Watchdog.java
index 3aec4ea..616090e 100644
--- a/services/java/com/android/server/Watchdog.java
+++ b/services/java/com/android/server/Watchdog.java
@@ -33,7 +33,6 @@
 import android.os.Debug;
 import android.os.Handler;
 import android.os.Looper;
-import android.os.Message;
 import android.os.Process;
 import android.os.ServiceManager;
 import android.os.SystemClock;
@@ -59,20 +58,7 @@
     // Set this to true to have the watchdog record kernel thread stacks when it fires
     static final boolean RECORD_KERNEL_THREADS = true;
 
-    static final int MONITOR = 2718;
-
-    static final int TIME_TO_RESTART = DB ? 15*1000 : 60*1000;
-    static final int TIME_TO_WAIT = TIME_TO_RESTART / 2;
-
-    static final int MEMCHECK_DEFAULT_MIN_SCREEN_OFF = DB ? 1*60 : 5*60;   // 5 minutes
-    static final int MEMCHECK_DEFAULT_MIN_ALARM = DB ? 1*60 : 3*60;        // 3 minutes
-    static final int MEMCHECK_DEFAULT_RECHECK_INTERVAL = DB ? 1*60 : 5*60; // 5 minutes
-
-    static final int REBOOT_DEFAULT_INTERVAL = DB ? 1 : 0;                 // never force reboot
-    static final int REBOOT_DEFAULT_START_TIME = 3*60*60;                  // 3:00am
-    static final int REBOOT_DEFAULT_WINDOW = 60*60;                        // within 1 hour
-
-    static final String REBOOT_ACTION = "com.android.service.Watchdog.REBOOT";
+    static final int TIME_TO_WAIT = DB ? 5*1000 : 30*1000;
 
     static final String[] NATIVE_STACKS_OF_INTEREST = new String[] {
         "/system/bin/mediaserver",
@@ -83,100 +69,99 @@
     static Watchdog sWatchdog;
 
     /* This handler will be used to post message back onto the main thread */
-    final Handler mHandler;
-    final ArrayList<Monitor> mMonitors = new ArrayList<Monitor>();
+    final ArrayList<HandlerChecker> mHandlerCheckers = new ArrayList<HandlerChecker>();
+    final HandlerChecker mMonitorChecker;
     ContentResolver mResolver;
     BatteryService mBattery;
     PowerManagerService mPower;
     AlarmManagerService mAlarm;
     ActivityManagerService mActivity;
-    boolean mCompleted;
-    Monitor mCurrentMonitor;
 
     int mPhonePid;
     IActivityController mController;
     boolean mAllowRestart = true;
 
-    final Calendar mCalendar = Calendar.getInstance();
-    int mMinScreenOff = MEMCHECK_DEFAULT_MIN_SCREEN_OFF;
-    int mMinAlarm = MEMCHECK_DEFAULT_MIN_ALARM;
-    boolean mNeedScheduledCheck;
-    PendingIntent mCheckupIntent;
-    PendingIntent mRebootIntent;
-
-    long mBootTime;
-    int mRebootInterval;
-
-    boolean mReqRebootNoWait;     // should wait for one interval before reboot?
-    int mReqRebootInterval = -1;  // >= 0 if a reboot has been requested
-    int mReqRebootStartTime = -1; // >= 0 if a specific start time has been requested
-    int mReqRebootWindow = -1;    // >= 0 if a specific window has been requested
-    int mReqMinScreenOff = -1;    // >= 0 if a specific screen off time has been requested
-    int mReqMinNextAlarm = -1;    // >= 0 if specific time to next alarm has been requested
-    int mReqRecheckInterval= -1;  // >= 0 if a specific recheck interval has been requested
-
     /**
-     * Used for scheduling monitor callbacks and checking memory usage.
+     * Used for checking status of handle threads and scheduling monitor callbacks.
      */
-    final class HeartbeatHandler extends Handler {
-        HeartbeatHandler(Looper looper) {
-            super(looper);
+    public final class HandlerChecker implements Runnable {
+        private final Handler mHandler;
+        private final String mName;
+        private final ArrayList<Monitor> mMonitors = new ArrayList<Monitor>();
+        private boolean mCompleted;
+        private Monitor mCurrentMonitor;
+
+        HandlerChecker(Handler handler, String name) {
+            mHandler = handler;
+            mName = name;
         }
 
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MONITOR: {
-                    // See if we should force a reboot.
-                    int rebootInterval = mReqRebootInterval >= 0
-                            ? mReqRebootInterval : REBOOT_DEFAULT_INTERVAL;
-                    if (mRebootInterval != rebootInterval) {
-                        mRebootInterval = rebootInterval;
-                        // We have been running long enough that a reboot can
-                        // be considered...
-                        checkReboot(false);
-                    }
+        public void addMonitor(Monitor monitor) {
+            mMonitors.add(monitor);
+        }
 
-                    final int size = mMonitors.size();
-                    for (int i = 0 ; i < size ; i++) {
-                        synchronized (Watchdog.this) {
-                            mCurrentMonitor = mMonitors.get(i);
-                        }
-                        mCurrentMonitor.monitor();
-                    }
+        public void scheduleCheckLocked() {
+            if (mMonitors.size() == 0 && mHandler.getLooper().isIdling()) {
+                // If the target looper is or just recently was idling, then
+                // there is no reason to enqueue our checker on it since that
+                // is as good as it not being deadlocked.  This avoid having
+                // to do a context switch to check the thread.  Note that we
+                // only do this if mCheckReboot is false and we have no
+                // monitors, since those would need to be executed at this point.
+                mCompleted = true;
+                return;
+            }
+            mCompleted = false;
+            mCurrentMonitor = null;
+            mHandler.postAtFrontOfQueue(this);
+        }
 
-                    synchronized (Watchdog.this) {
-                        mCompleted = true;
-                        mCurrentMonitor = null;
-                    }
-                } break;
+        public boolean isCompletedLocked() {
+            return mCompleted;
+        }
+
+        public Thread getThread() {
+            return mHandler.getLooper().getThread();
+        }
+
+        public String getName() {
+            return mName;
+        }
+
+        public String describeBlockedStateLocked() {
+            if (mCurrentMonitor == null) {
+                return "Blocked in handler on " + mName + " (" + getThread().getName() + ")";
+            } else {
+                return "Blocked in monitor " + mCurrentMonitor.getClass().getName()
+                        + " on " + mName + " (" + getThread().getName() + ")";
             }
         }
-    }
 
-    final class RebootReceiver extends BroadcastReceiver {
         @Override
-        public void onReceive(Context c, Intent intent) {
-            if (localLOGV) Slog.v(TAG, "Alarm went off, checking reboot.");
-            checkReboot(true);
+        public void run() {
+            final int size = mMonitors.size();
+            for (int i = 0 ; i < size ; i++) {
+                synchronized (Watchdog.this) {
+                    mCurrentMonitor = mMonitors.get(i);
+                }
+                mCurrentMonitor.monitor();
+            }
+
+            synchronized (Watchdog.this) {
+                mCompleted = true;
+                mCurrentMonitor = null;
+            }
         }
     }
 
     final class RebootRequestReceiver extends BroadcastReceiver {
         @Override
         public void onReceive(Context c, Intent intent) {
-            mReqRebootNoWait = intent.getIntExtra("nowait", 0) != 0;
-            mReqRebootInterval = intent.getIntExtra("interval", -1);
-            mReqRebootStartTime = intent.getIntExtra("startTime", -1);
-            mReqRebootWindow = intent.getIntExtra("window", -1);
-            mReqMinScreenOff = intent.getIntExtra("minScreenOff", -1);
-            mReqMinNextAlarm = intent.getIntExtra("minNextAlarm", -1);
-            mReqRecheckInterval = intent.getIntExtra("recheckInterval", -1);
-            EventLog.writeEvent(EventLogTags.WATCHDOG_REQUESTED_REBOOT,
-                    mReqRebootNoWait ? 1 : 0, mReqRebootInterval,
-                            mReqRecheckInterval, mReqRebootStartTime,
-                    mReqRebootWindow, mReqMinScreenOff, mReqMinNextAlarm);
-            checkReboot(true);
+            if (intent.getIntExtra("nowait", 0) != 0) {
+                rebootSystem("Received ACTION_REBOOT broadcast");
+                return;
+            }
+            Slog.w(TAG, "Unsupported ACTION_REBOOT broadcast: " + intent);
         }
     }
 
@@ -194,9 +179,23 @@
 
     private Watchdog() {
         super("watchdog");
-        // Explicitly bind the HeartbeatHandler to run on the ServerThread, so
-        // that it can't get accidentally bound to another thread.
-        mHandler = new HeartbeatHandler(Looper.getMainLooper());
+        // Initialize handler checkers for each common thread we want to check.  Note
+        // that we are not currently checking the background thread, since it can
+        // potentially hold longer running operations with no guarantees about the timeliness
+        // of operations there.
+
+        // The shared foreground thread is the main checker.  It is where we
+        // will also dispatch monitor checks and do other work.
+        mMonitorChecker = new HandlerChecker(FgThread.getHandler(), "foreground thread");
+        mHandlerCheckers.add(mMonitorChecker);
+        // Add checker for main thread.  We only do a quick check since there
+        // can be UI running on the thread.
+        mHandlerCheckers.add(new HandlerChecker(new Handler(Looper.getMainLooper()),
+                "main thread"));
+        // Add checker for shared UI thread.
+        mHandlerCheckers.add(new HandlerChecker(UiThread.getHandler(), "ui thread"));
+        // And also check IO thread.
+        mHandlerCheckers.add(new HandlerChecker(IoThread.getHandler(), "i/o thread"));
     }
 
     public void init(Context context, BatteryService battery,
@@ -208,16 +207,9 @@
         mAlarm = alarm;
         mActivity = activity;
 
-        context.registerReceiver(new RebootReceiver(),
-                new IntentFilter(REBOOT_ACTION));
-        mRebootIntent = PendingIntent.getBroadcast(context,
-                0, new Intent(REBOOT_ACTION), 0);
-
         context.registerReceiver(new RebootRequestReceiver(),
                 new IntentFilter(Intent.ACTION_REBOOT),
                 android.Manifest.permission.REBOOT, null);
-
-        mBootTime = System.currentTimeMillis();
     }
 
     public void processStarted(String name, int pid) {
@@ -243,87 +235,19 @@
     public void addMonitor(Monitor monitor) {
         synchronized (this) {
             if (isAlive()) {
-                throw new RuntimeException("Monitors can't be added while the Watchdog is running");
+                throw new RuntimeException("Monitors can't be added once the Watchdog is running");
             }
-            mMonitors.add(monitor);
+            mMonitorChecker.addMonitor(monitor);
         }
     }
 
-    void checkReboot(boolean fromAlarm) {
-        int rebootInterval = mReqRebootInterval >= 0 ? mReqRebootInterval
-                : REBOOT_DEFAULT_INTERVAL;
-        mRebootInterval = rebootInterval;
-        if (rebootInterval <= 0) {
-            // No reboot interval requested.
-            if (localLOGV) Slog.v(TAG, "No need to schedule a reboot alarm!");
-            mAlarm.remove(mRebootIntent);
-            return;
-        }
-
-        long rebootStartTime = mReqRebootStartTime >= 0 ? mReqRebootStartTime
-                : REBOOT_DEFAULT_START_TIME;
-        long rebootWindowMillis = (mReqRebootWindow >= 0 ? mReqRebootWindow
-                : REBOOT_DEFAULT_WINDOW) * 1000;
-        long recheckInterval = (mReqRecheckInterval >= 0 ? mReqRecheckInterval
-                : MEMCHECK_DEFAULT_RECHECK_INTERVAL) * 1000;
-
-        retrieveBrutalityAmount();
-
-        long realStartTime;
-        long now;
-
+    public void addThread(Handler thread, String name) {
         synchronized (this) {
-            now = System.currentTimeMillis();
-            realStartTime = computeCalendarTime(mCalendar, now,
-                    rebootStartTime);
-
-            long rebootIntervalMillis = rebootInterval*24*60*60*1000;
-            if (DB || mReqRebootNoWait ||
-                    (now-mBootTime) >= (rebootIntervalMillis-rebootWindowMillis)) {
-                if (fromAlarm && rebootWindowMillis <= 0) {
-                    // No reboot window -- just immediately reboot.
-                    EventLog.writeEvent(EventLogTags.WATCHDOG_SCHEDULED_REBOOT, now,
-                            (int)rebootIntervalMillis, (int)rebootStartTime*1000,
-                            (int)rebootWindowMillis, "");
-                    rebootSystem("Checkin scheduled forced");
-                    return;
-                }
-
-                // Are we within the reboot window?
-                if (now < realStartTime) {
-                    // Schedule alarm for next check interval.
-                    realStartTime = computeCalendarTime(mCalendar,
-                            now, rebootStartTime);
-                } else if (now < (realStartTime+rebootWindowMillis)) {
-                    String doit = shouldWeBeBrutalLocked(now);
-                    EventLog.writeEvent(EventLogTags.WATCHDOG_SCHEDULED_REBOOT, now,
-                            (int)rebootInterval, (int)rebootStartTime*1000,
-                            (int)rebootWindowMillis, doit != null ? doit : "");
-                    if (doit == null) {
-                        rebootSystem("Checked scheduled range");
-                        return;
-                    }
-
-                    // Schedule next alarm either within the window or in the
-                    // next interval.
-                    if ((now+recheckInterval) >= (realStartTime+rebootWindowMillis)) {
-                        realStartTime = computeCalendarTime(mCalendar,
-                                now + rebootIntervalMillis, rebootStartTime);
-                    } else {
-                        realStartTime = now + recheckInterval;
-                    }
-                } else {
-                    // Schedule alarm for next check interval.
-                    realStartTime = computeCalendarTime(mCalendar,
-                            now + rebootIntervalMillis, rebootStartTime);
-                }
+            if (isAlive()) {
+                throw new RuntimeException("Threads can't be added once the Watchdog is running");
             }
+            mHandlerCheckers.add(new HandlerChecker(thread, name));
         }
-
-        if (localLOGV) Slog.v(TAG, "Scheduling next reboot alarm for "
-                + ((realStartTime-now)/1000/60) + "m from now");
-        mAlarm.remove(mRebootIntent);
-        mAlarm.set(AlarmManager.RTC_WAKEUP, realStartTime, mRebootIntent);
     }
 
     /**
@@ -335,82 +259,55 @@
         pms.reboot(false, reason, false);
     }
 
-    /**
-     * Load the current Gservices settings for when
-     * {@link #shouldWeBeBrutalLocked} will allow the brutality to happen.
-     * Must not be called with the lock held.
-     */
-    void retrieveBrutalityAmount() {
-        mMinScreenOff = (mReqMinScreenOff >= 0 ? mReqMinScreenOff
-                : MEMCHECK_DEFAULT_MIN_SCREEN_OFF) * 1000;
-        mMinAlarm = (mReqMinNextAlarm >= 0 ? mReqMinNextAlarm
-                : MEMCHECK_DEFAULT_MIN_ALARM) * 1000;
+    private boolean haveAllCheckersCompletedLocked() {
+        for (int i=0; i<mHandlerCheckers.size(); i++) {
+            HandlerChecker hc = mHandlerCheckers.get(i);
+            if (!hc.isCompletedLocked()) {
+                return false;
+            }
+        }
+        return true;
     }
 
-    /**
-     * Determine whether it is a good time to kill, crash, or otherwise
-     * plunder the current situation for the overall long-term benefit of
-     * the world.
-     *
-     * @param curTime The current system time.
-     * @return Returns null if this is a good time, else a String with the
-     * text of why it is not a good time.
-     */
-    String shouldWeBeBrutalLocked(long curTime) {
-        if (mBattery == null || !mBattery.isPowered(BatteryManager.BATTERY_PLUGGED_ANY)) {
-            return "battery";
+    private ArrayList<HandlerChecker> getBlockedCheckersLocked() {
+        ArrayList<HandlerChecker> checkers = new ArrayList<HandlerChecker>();
+        for (int i=0; i<mHandlerCheckers.size(); i++) {
+            HandlerChecker hc = mHandlerCheckers.get(i);
+            if (!hc.isCompletedLocked()) {
+                checkers.add(hc);
+            }
         }
-
-        if (mMinScreenOff >= 0 && (mPower == null ||
-                mPower.timeSinceScreenWasLastOn() < mMinScreenOff)) {
-            return "screen";
-        }
-
-        if (mMinAlarm >= 0 && (mAlarm == null ||
-                mAlarm.timeToNextAlarm() < mMinAlarm)) {
-            return "alarm";
-        }
-
-        return null;
+        return checkers;
     }
 
-    static long computeCalendarTime(Calendar c, long curTime,
-            long secondsSinceMidnight) {
-
-        // start with now
-        c.setTimeInMillis(curTime);
-
-        int val = (int)secondsSinceMidnight / (60*60);
-        c.set(Calendar.HOUR_OF_DAY, val);
-        secondsSinceMidnight -= val * (60*60);
-        val = (int)secondsSinceMidnight / 60;
-        c.set(Calendar.MINUTE, val);
-        c.set(Calendar.SECOND, (int)secondsSinceMidnight - (val*60));
-        c.set(Calendar.MILLISECOND, 0);
-
-        long newTime = c.getTimeInMillis();
-        if (newTime < curTime) {
-            // The given time (in seconds since midnight) has already passed for today, so advance
-            // by one day (due to daylight savings, etc., the delta may differ from 24 hours).
-            c.add(Calendar.DAY_OF_MONTH, 1);
-            newTime = c.getTimeInMillis();
+    private String describeCheckersLocked(ArrayList<HandlerChecker> checkers) {
+        StringBuilder builder = new StringBuilder(128);
+        for (int i=0; i<checkers.size(); i++) {
+            if (builder.length() > 0) {
+                builder.append(", ");
+            }
+            builder.append(checkers.get(i).describeBlockedStateLocked());
         }
-
-        return newTime;
+        return builder.toString();
     }
 
     @Override
     public void run() {
         boolean waitedHalf = false;
         while (true) {
-            mCompleted = false;
-            mHandler.sendEmptyMessage(MONITOR);
-
-
-            final String name;
+            final ArrayList<HandlerChecker> blockedCheckers;
+            final String subject;
             final boolean allowRestart;
             synchronized (this) {
                 long timeout = TIME_TO_WAIT;
+                if (!waitedHalf) {
+                    // If we are not at the half-point of waiting, perform a
+                    // new set of checks.  Otherwise we are still waiting for a previous set.
+                    for (int i=0; i<mHandlerCheckers.size(); i++) {
+                        HandlerChecker hc = mHandlerCheckers.get(i);
+                        hc.scheduleCheckLocked();
+                    }
+                }
 
                 // NOTE: We use uptimeMillis() here because we do not want to increment the time we
                 // wait while asleep. If the device is asleep then the thing that we are waiting
@@ -426,7 +323,7 @@
                     timeout = TIME_TO_WAIT - (SystemClock.uptimeMillis() - start);
                 }
 
-                if (mCompleted) {
+                if (haveAllCheckersCompletedLocked()) {
                     // The monitors have returned.
                     waitedHalf = false;
                     continue;
@@ -443,15 +340,15 @@
                     continue;
                 }
 
-                name = (mCurrentMonitor != null) ?
-                    mCurrentMonitor.getClass().getName() : "null";
+                blockedCheckers = getBlockedCheckersLocked();
+                subject = describeCheckersLocked(blockedCheckers);
                 allowRestart = mAllowRestart;
             }
 
             // If we got here, that means that the system is most likely hung.
             // First collect stack traces from all threads of the system process.
             // Then kill this process so that the system will restart.
-            EventLog.writeEvent(EventLogTags.WATCHDOG, name);
+            EventLog.writeEvent(EventLogTags.WATCHDOG, subject);
 
             ArrayList<Integer> pids = new ArrayList<Integer>();
             pids.add(Process.myPid());
@@ -487,7 +384,7 @@
                     public void run() {
                         mActivity.addErrorToDropBox(
                                 "watchdog", null, "system_server", null, null,
-                                name, null, stack, null);
+                                subject, null, stack, null);
                     }
                 };
             dropboxThread.start();
@@ -504,7 +401,7 @@
                 try {
                     Binder.setDumpDisabled("Service dumps disabled due to hung system process.");
                     // 1 = keep waiting, -1 = kill system
-                    int res = controller.systemNotResponding(name);
+                    int res = controller.systemNotResponding(subject);
                     if (res >= 0) {
                         Slog.i(TAG, "Activity controller requested to coninue to wait");
                         waitedHalf = false;
@@ -520,7 +417,16 @@
             } else if (!allowRestart) {
                 Slog.w(TAG, "Restart not allowed: Watchdog is *not* killing the system process");
             } else {
-                Slog.w(TAG, "*** WATCHDOG KILLING SYSTEM PROCESS: " + name);
+                Slog.w(TAG, "*** WATCHDOG KILLING SYSTEM PROCESS: " + subject);
+                for (int i=0; i<blockedCheckers.size(); i++) {
+                    Slog.w(TAG, blockedCheckers.get(i).getName() + " stack trace:");
+                    StackTraceElement[] stackTrace
+                            = blockedCheckers.get(i).getThread().getStackTrace();
+                    for (StackTraceElement element: stackTrace) {
+                        Slog.w(TAG, "    at " + element);
+                    }
+                }
+                Slog.w(TAG, "*** GOODBYE!");
                 Process.killProcess(Process.myPid());
                 System.exit(10);
             }
diff --git a/services/java/com/android/server/WiredAccessoryManager.java b/services/java/com/android/server/WiredAccessoryManager.java
index d5c9c8f..415fcc1 100644
--- a/services/java/com/android/server/WiredAccessoryManager.java
+++ b/services/java/com/android/server/WiredAccessoryManager.java
@@ -44,6 +44,7 @@
 import java.io.FileNotFoundException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Locale;
 
 /**
  * <p>WiredAccessoryManager monitors for a wired headset on the main board or dock using
@@ -408,11 +409,11 @@
             public String getDevName() { return mDevName; }
 
             public String getDevPath() {
-                return String.format("/devices/virtual/switch/%s", mDevName);
+                return String.format(Locale.US, "/devices/virtual/switch/%s", mDevName);
             }
 
             public String getSwitchStatePath() {
-                return String.format("/sys/class/switch/%s/state", mDevName);
+                return String.format(Locale.US, "/sys/class/switch/%s/state", mDevName);
             }
 
             public boolean checkSwitchExists() {
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index f1e4b0c..83e69d6f 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -2694,7 +2694,10 @@
             | AccessibilityNodeInfo.ACTION_COPY
             | AccessibilityNodeInfo.ACTION_PASTE
             | AccessibilityNodeInfo.ACTION_CUT
-            | AccessibilityNodeInfo.ACTION_SET_SELECTION;
+            | AccessibilityNodeInfo.ACTION_SET_SELECTION
+            | AccessibilityNodeInfo.ACTION_EXPAND
+            | AccessibilityNodeInfo.ACTION_COLLAPSE
+            | AccessibilityNodeInfo.ACTION_DISMISS;
 
         private static final int RETRIEVAL_ALLOWING_EVENT_TYPES =
             AccessibilityEvent.TYPE_VIEW_CLICKED
@@ -2817,7 +2820,8 @@
 
         public int resolveCallingUserIdEnforcingPermissionsLocked(int userId) {
             final int callingUid = Binder.getCallingUid();
-            if (callingUid == Process.SYSTEM_UID
+            if (callingUid == 0
+                    || callingUid == Process.SYSTEM_UID
                     || callingUid == Process.SHELL_UID) {
                 return mCurrentUserId;
             }
diff --git a/services/java/com/android/server/accessibility/TouchExplorer.java b/services/java/com/android/server/accessibility/TouchExplorer.java
index 18b46fb..1b8876d 100644
--- a/services/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/java/com/android/server/accessibility/TouchExplorer.java
@@ -41,6 +41,7 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 
 /**
  * This class is a strategy for performing touch exploration. It
@@ -52,10 +53,8 @@
  *   <li>2. One finger moving fast around performs gestures.</li>
  *   <li>3. Two close fingers moving in the same direction perform a drag.</li>
  *   <li>4. Multi-finger gestures are delivered to view hierarchy.</li>
- *   <li>5. Pointers that have not moved more than a specified distance after they
- *          went down are considered inactive.</li>
- *   <li>6. Two fingers moving in different directions are considered a multi-finger gesture.</li>
- *   <li>7. Double tapping clicks on the on the last touch explored location of it was in
+ *   <li>5. Two fingers moving in different directions are considered a multi-finger gesture.</li>
+ *   <li>7. Double tapping clicks on the on the last touch explored location if it was in
  *          a window that does not take focus, otherwise the click is within the accessibility
  *          focused rectangle.</li>
  *   <li>7. Tapping and holding for a while performs a long press in a similar fashion
@@ -102,9 +101,6 @@
     // The timeout after which we are no longer trying to detect a gesture.
     private static final int EXIT_GESTURE_DETECTION_TIMEOUT = 2000;
 
-    // Temporary array for storing pointer IDs.
-    private final int[] mTempPointerIds = new int[MAX_POINTER_COUNT];
-
     // Timeout before trying to decide what the user is trying to do.
     private final int mDetermineUserIntentTimeout;
 
@@ -129,11 +125,11 @@
     // Handler for performing asynchronous operations.
     private final Handler mHandler;
 
-    // Command for delayed sending of a hover enter event.
-    private final SendHoverDelayed mSendHoverEnterDelayed;
+    // Command for delayed sending of a hover enter and move event.
+    private final SendHoverEnterAndMoveDelayed mSendHoverEnterAndMoveDelayed;
 
     // Command for delayed sending of a hover exit event.
-    private final SendHoverDelayed mSendHoverExitDelayed;
+    private final SendHoverExitDelayed mSendHoverExitDelayed;
 
     // Command for delayed sending of touch exploration end events.
     private final SendAccessibilityEventDelayed mSendTouchExplorationEndDelayed;
@@ -220,7 +216,7 @@
     public TouchExplorer(Context context, AccessibilityManagerService service) {
         mContext = context;
         mAms = service;
-        mReceivedPointerTracker = new ReceivedPointerTracker(context);
+        mReceivedPointerTracker = new ReceivedPointerTracker();
         mInjectedPointerTracker = new InjectedPointerTracker();
         mTapTimeout = ViewConfiguration.getTapTimeout();
         mDetermineUserIntentTimeout = ViewConfiguration.getDoubleTapTimeout();
@@ -234,8 +230,8 @@
         mGestureLibrary.setOrientationStyle(8);
         mGestureLibrary.setSequenceType(GestureStore.SEQUENCE_SENSITIVE);
         mGestureLibrary.load();
-        mSendHoverEnterDelayed = new SendHoverDelayed(MotionEvent.ACTION_HOVER_ENTER, true);
-        mSendHoverExitDelayed = new SendHoverDelayed(MotionEvent.ACTION_HOVER_EXIT, false);
+        mSendHoverEnterAndMoveDelayed = new SendHoverEnterAndMoveDelayed();
+        mSendHoverExitDelayed = new SendHoverExitDelayed();
         mSendTouchExplorationEndDelayed = new SendAccessibilityEventDelayed(
                 AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END,
                 mDetermineUserIntentTimeout);
@@ -283,12 +279,12 @@
             } break;
         }
         // Remove all pending callbacks.
-        mSendHoverEnterDelayed.remove();
-        mSendHoverExitDelayed.remove();
-        mPerformLongPressDelayed.remove();
-        mExitGestureDetectionModeDelayed.remove();
-        mSendTouchExplorationEndDelayed.remove();
-        mSendTouchInteractionEndDelayed.remove();
+        mSendHoverEnterAndMoveDelayed.cancel();
+        mSendHoverExitDelayed.cancel();
+        mPerformLongPressDelayed.cancel();
+        mExitGestureDetectionModeDelayed.cancel();
+        mSendTouchExplorationEndDelayed.cancel();
+        mSendTouchInteractionEndDelayed.cancel();
         // Reset the pointer trackers.
         mReceivedPointerTracker.clear();
         mInjectedPointerTracker.clear();
@@ -347,7 +343,7 @@
         // last hover exit event.
         if (mSendTouchExplorationEndDelayed.isPending()
                 && eventType == AccessibilityEvent.TYPE_VIEW_HOVER_EXIT) {
-                    mSendTouchExplorationEndDelayed.remove();
+                    mSendTouchExplorationEndDelayed.cancel();
             sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END);
         }
 
@@ -355,7 +351,7 @@
         // last hover exit and the touch exploration gesture end events.
         if (mSendTouchInteractionEndDelayed.isPending()
                 && eventType == AccessibilityEvent.TYPE_VIEW_HOVER_EXIT) {
-            mSendTouchInteractionEndDelayed.remove();
+            mSendTouchInteractionEndDelayed.cancel();
             sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_END);
         }
 
@@ -390,95 +386,82 @@
     private void handleMotionEventStateTouchExploring(MotionEvent event, MotionEvent rawEvent,
             int policyFlags) {
         ReceivedPointerTracker receivedTracker = mReceivedPointerTracker;
-        final int activePointerCount = receivedTracker.getActivePointerCount();
 
         mVelocityTracker.addMovement(rawEvent);
 
         mDoubleTapDetector.onMotionEvent(event, policyFlags);
 
         switch (event.getActionMasked()) {
-            case MotionEvent.ACTION_DOWN:
+            case MotionEvent.ACTION_DOWN: {
                 mAms.onTouchInteractionStart();
+
                 // Pre-feed the motion events to the gesture detector since we
                 // have a distance slop before getting into gesture detection
                 // mode and not using the points within this slop significantly
                 // decreases the quality of gesture recognition.
                 handleMotionEventGestureDetecting(rawEvent, policyFlags);
-                //$FALL-THROUGH$
-            case MotionEvent.ACTION_POINTER_DOWN: {
-                switch (activePointerCount) {
-                    case 0: {
-                        throw new IllegalStateException("The must always be one active pointer in"
-                                + "touch exploring state!");
+                sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_START);
+
+                // If we still have not notified the user for the last
+                // touch, we figure out what to do. If were waiting
+                // we resent the delayed callback and wait again.
+                mSendHoverEnterAndMoveDelayed.cancel();
+                mSendHoverExitDelayed.cancel();
+                mPerformLongPressDelayed.cancel();
+
+                if (mSendTouchExplorationEndDelayed.isPending()) {
+                    mSendTouchExplorationEndDelayed.forceSendAndRemove();
+                }
+
+                if (mSendTouchInteractionEndDelayed.isPending()) {
+                    mSendTouchInteractionEndDelayed.forceSendAndRemove();
+                }
+
+                // If we have the first tap, schedule a long press and break
+                // since we do not want to schedule hover enter because
+                // the delayed callback will kick in before the long click.
+                // This would lead to a state transition resulting in long
+                // pressing the item below the double taped area which is
+                // not necessary where accessibility focus is.
+                if (mDoubleTapDetector.firstTapDetected()) {
+                    // We got a tap now post a long press action.
+                    mPerformLongPressDelayed.post(event, policyFlags);
+                    break;
+                }
+                if (!mTouchExplorationInProgress) {
+                    if (!mSendHoverEnterAndMoveDelayed.isPending()) {
+                        // Deliver hover enter with a delay to have a chance
+                        // to detect what the user is trying to do.
+                        final int pointerId = receivedTracker.getPrimaryPointerId();
+                        final int pointerIdBits = (1 << pointerId);
+                        mSendHoverEnterAndMoveDelayed.post(event, true, pointerIdBits,
+                                policyFlags);
                     }
-                    case 1: {
-                        // If we still have not notified the user for the last
-                        // touch, we figure out what to do. If were waiting
-                        // we resent the delayed callback and wait again.
-                        if (mSendHoverEnterDelayed.isPending()) {
-                            mSendHoverEnterDelayed.remove();
-                            mSendHoverExitDelayed.remove();
-                        }
-
-                        if (mSendTouchExplorationEndDelayed.isPending()) {
-                            mSendTouchExplorationEndDelayed.forceSendAndRemove();
-                        }
-
-                        if (mSendTouchInteractionEndDelayed.isPending()) {
-                            mSendTouchInteractionEndDelayed.forceSendAndRemove();
-                        }
-
-                        // Every pointer that goes down is active until it moves or
-                        // another one goes down. Hence, having more than one pointer
-                        // down we have already send the interaction start event.
-                        if (event.getPointerCount() == 1) {
-                            sendAccessibilityEvent(
-                                    AccessibilityEvent.TYPE_TOUCH_INTERACTION_START);
-                        }
-
-                        mPerformLongPressDelayed.remove();
-
-                        // If we have the first tap schedule a long press and break
-                        // since we do not want to schedule hover enter because
-                        // the delayed callback will kick in before the long click.
-                        // This would lead to a state transition resulting in long
-                        // pressing the item below the double taped area which is
-                        // not necessary where accessibility focus is.
-                        if (mDoubleTapDetector.firstTapDetected()) {
-                            // We got a tap now post a long press action.
-                            mPerformLongPressDelayed.post(event, policyFlags);
-                            break;
-                        }
-                        if (!mTouchExplorationInProgress) {
-                            // Deliver hover enter with a delay to have a chance
-                            // to detect what the user is trying to do.
-                            final int pointerId = receivedTracker.getPrimaryActivePointerId();
-                            final int pointerIdBits = (1 << pointerId);
-                            mSendHoverEnterDelayed.post(event, true, pointerIdBits, policyFlags);
-                        }
-                    } break;
-                    default: {
-                        /* do nothing - let the code for ACTION_MOVE decide what to do */
-                    } break;
+                    // Cache the event until we discern exploration from gesturing.
+                    mSendHoverEnterAndMoveDelayed.addEvent(event);
                 }
             } break;
+            case MotionEvent.ACTION_POINTER_DOWN: {
+                /* do nothing - let the code for ACTION_MOVE decide what to do */
+            } break;
             case MotionEvent.ACTION_MOVE: {
-                final int pointerId = receivedTracker.getPrimaryActivePointerId();
+                final int pointerId = receivedTracker.getPrimaryPointerId();
                 final int pointerIndex = event.findPointerIndex(pointerId);
                 final int pointerIdBits = (1 << pointerId);
-                switch (activePointerCount) {
-                    case 0: {
-                        /* do nothing - no active pointers so we swallow the event */
-                    } break;
+                switch (event.getPointerCount()) {
                     case 1: {
                         // We have not started sending events since we try to
                         // figure out what the user is doing.
-                        if (mSendHoverEnterDelayed.isPending()) {
+                        if (mSendHoverEnterAndMoveDelayed.isPending()) {
                             // Pre-feed the motion events to the gesture detector since we
                             // have a distance slop before getting into gesture detection
                             // mode and not using the points within this slop significantly
                             // decreases the quality of gesture recognition.
                             handleMotionEventGestureDetecting(rawEvent, policyFlags);
+
+                            // Cache the event until we discern exploration from gesturing.
+                            mSendHoverEnterAndMoveDelayed.addEvent(event);
+
                             // It is *important* to use the distance traveled by the pointers
                             // on the screen which may or may not be magnified.
                             final float deltaX = receivedTracker.getReceivedPointerDownX(pointerId)
@@ -500,9 +483,9 @@
                                     // clear the current state and try to detect.
                                     mCurrentState = STATE_GESTURE_DETECTING;
                                     mVelocityTracker.clear();
-                                    mSendHoverEnterDelayed.remove();
-                                    mSendHoverExitDelayed.remove();
-                                    mPerformLongPressDelayed.remove();
+                                    mSendHoverEnterAndMoveDelayed.cancel();
+                                    mSendHoverExitDelayed.cancel();
+                                    mPerformLongPressDelayed.cancel();
                                     mExitGestureDetectionModeDelayed.post();
                                     // Send accessibility event to announce the start
                                     // of gesture recognition.
@@ -511,9 +494,9 @@
                                 } else {
                                     // We have just decided that the user is touch,
                                     // exploring so start sending events.
-                                    mSendHoverEnterDelayed.forceSendAndRemove();
-                                    mSendHoverExitDelayed.remove();
-                                    mPerformLongPressDelayed.remove();
+                                    mSendHoverEnterAndMoveDelayed.forceSendAndRemove();
+                                    mSendHoverExitDelayed.cancel();
+                                    mPerformLongPressDelayed.cancel();
                                     sendMotionEvent(event, MotionEvent.ACTION_HOVER_MOVE,
                                             pointerIdBits, policyFlags);
                                 }
@@ -532,11 +515,11 @@
                                 final double moveDelta = Math.hypot(deltaX, deltaY);
                                 // The user has moved enough for us to decide.
                                 if (moveDelta > mTouchSlop) {
-                                    mPerformLongPressDelayed.remove();
+                                    mPerformLongPressDelayed.cancel();
                                 }
                             }
-                            // The user is wither double tapping or performing long
-                            // press so do not send move events yet.
+                            // The user is either double tapping or performing a long
+                            // press, so do not send move events yet.
                             if (mDoubleTapDetector.firstTapDetected()) {
                                 break;
                             }
@@ -548,14 +531,14 @@
                     case 2: {
                         // More than one pointer so the user is not touch exploring
                         // and now we have to decide whether to delegate or drag.
-                        if (mSendHoverEnterDelayed.isPending()) {
+                        if (mSendHoverEnterAndMoveDelayed.isPending()) {
                             // We have not started sending events so cancel
                             // scheduled sending events.
-                            mSendHoverEnterDelayed.remove();
-                            mSendHoverExitDelayed.remove();
-                            mPerformLongPressDelayed.remove();
+                            mSendHoverEnterAndMoveDelayed.cancel();
+                            mSendHoverExitDelayed.cancel();
+                            mPerformLongPressDelayed.cancel();
                         } else {
-                            mPerformLongPressDelayed.remove();
+                            mPerformLongPressDelayed.cancel();
                             // If the user is touch exploring the second pointer may be
                             // performing a double tap to activate an item without need
                             // for the user to lift his exploring finger.
@@ -590,21 +573,21 @@
                         } else {
                             // Two pointers moving arbitrary are delegated to the view hierarchy.
                             mCurrentState = STATE_DELEGATING;
-                            sendDownForAllActiveNotInjectedPointers(event, policyFlags);
+                            sendDownForAllNotInjectedPointers(event, policyFlags);
                         }
                         mVelocityTracker.clear();
                     } break;
                     default: {
                         // More than one pointer so the user is not touch exploring
                         // and now we have to decide whether to delegate or drag.
-                        if (mSendHoverEnterDelayed.isPending()) {
+                        if (mSendHoverEnterAndMoveDelayed.isPending()) {
                             // We have not started sending events so cancel
                             // scheduled sending events.
-                            mSendHoverEnterDelayed.remove();
-                            mSendHoverExitDelayed.remove();
-                            mPerformLongPressDelayed.remove();
+                            mSendHoverEnterAndMoveDelayed.cancel();
+                            mSendHoverExitDelayed.cancel();
+                            mPerformLongPressDelayed.cancel();
                         } else {
-                            mPerformLongPressDelayed.remove();
+                            mPerformLongPressDelayed.cancel();
                             // We are sending events so send exit and gesture
                             // end since we transition to another state.
                             sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
@@ -612,43 +595,34 @@
 
                         // More than two pointers are delegated to the view hierarchy.
                         mCurrentState = STATE_DELEGATING;
-                        sendDownForAllActiveNotInjectedPointers(event, policyFlags);
+                        sendDownForAllNotInjectedPointers(event, policyFlags);
                         mVelocityTracker.clear();
                     }
                 }
             } break;
-            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_UP: {
                 mAms.onTouchInteractionEnd();
                 // We know that we do not need the pre-fed gesture points are not
                 // needed anymore since the last pointer just went up.
                 mStrokeBuffer.clear();
-                //$FALL-THROUGH$
-            case MotionEvent.ACTION_POINTER_UP: {
-                final int pointerId = receivedTracker.getLastReceivedUpPointerId();
+                final int pointerId = event.getPointerId(event.getActionIndex());
                 final int pointerIdBits = (1 << pointerId);
-                switch (activePointerCount) {
-                    case 0: {
-                        // If the pointer that went up was not active we have nothing to do.
-                        if (!receivedTracker.wasLastReceivedUpPointerActive()) {
-                            break;
-                        }
 
-                        mPerformLongPressDelayed.remove();
-
-                        // If we have not delivered the enter schedule exit.
-                        if (mSendHoverEnterDelayed.isPending()) {
-                            mSendHoverExitDelayed.post(event, false, pointerIdBits, policyFlags);
-                        } else {
-                            // The user is touch exploring so we send events for end.
-                            sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
-                        }
-
-                        if (!mSendTouchInteractionEndDelayed.isPending()) {
-                            mSendTouchInteractionEndDelayed.post();
-                        }
-                    } break;
-                }
+                mPerformLongPressDelayed.cancel();
                 mVelocityTracker.clear();
+
+                if (mSendHoverEnterAndMoveDelayed.isPending()) {
+                    // If we have not delivered the enter schedule an exit.
+                    mSendHoverExitDelayed.post(event, pointerIdBits, policyFlags);
+                } else {
+                    // The user is touch exploring so we send events for end.
+                    sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
+                }
+
+                if (!mSendTouchInteractionEndDelayed.isPending()) {
+                    mSendTouchInteractionEndDelayed.post();
+                }
+
             } break;
             case MotionEvent.ACTION_CANCEL: {
                 clear(event, policyFlags);
@@ -676,29 +650,19 @@
                 if (mDraggingPointerId != INVALID_POINTER_ID) {
                     sendMotionEvent(event, MotionEvent.ACTION_UP, pointerIdBits, policyFlags);
                 }
-                sendDownForAllActiveNotInjectedPointers(event, policyFlags);
+                sendDownForAllNotInjectedPointers(event, policyFlags);
             } break;
             case MotionEvent.ACTION_MOVE: {
-                final int activePointerCount = mReceivedPointerTracker.getActivePointerCount();
-                switch (activePointerCount) {
+                switch (event.getPointerCount()) {
                     case 1: {
                         // do nothing
                     } break;
                     case 2: {
                         if (isDraggingGesture(event)) {
-                            // If the dragging pointer are closer that a given distance we
-                            // use the location of the primary one. Otherwise, we take the
-                            // middle between the pointers.
-                            int[] pointerIds = mTempPointerIds;
-                            mReceivedPointerTracker.populateActivePointerIds(pointerIds);
-
-                            final int firstPtrIndex = event.findPointerIndex(pointerIds[0]);
-                            final int secondPtrIndex = event.findPointerIndex(pointerIds[1]);
-
-                            final float firstPtrX = event.getX(firstPtrIndex);
-                            final float firstPtrY = event.getY(firstPtrIndex);
-                            final float secondPtrX = event.getX(secondPtrIndex);
-                            final float secondPtrY = event.getY(secondPtrIndex);
+                            final float firstPtrX = event.getX(0);
+                            final float firstPtrY = event.getY(0);
+                            final float secondPtrX = event.getX(1);
+                            final float secondPtrY = event.getY(1);
 
                             final float deltaX = firstPtrX - secondPtrX;
                             final float deltaY = firstPtrY - secondPtrY;
@@ -718,8 +682,8 @@
                             // Send an event to the end of the drag gesture.
                             sendMotionEvent(event, MotionEvent.ACTION_UP, pointerIdBits,
                                     policyFlags);
-                            // Deliver all active pointers to the view hierarchy.
-                            sendDownForAllActiveNotInjectedPointers(event, policyFlags);
+                            // Deliver all pointers to the view hierarchy.
+                            sendDownForAllNotInjectedPointers(event, policyFlags);
                         }
                     } break;
                     default: {
@@ -727,8 +691,8 @@
                         // Send an event to the end of the drag gesture.
                         sendMotionEvent(event, MotionEvent.ACTION_UP, pointerIdBits,
                                 policyFlags);
-                        // Deliver all active pointers to the view hierarchy.
-                        sendDownForAllActiveNotInjectedPointers(event, policyFlags);
+                        // Deliver all pointers to the view hierarchy.
+                        sendDownForAllNotInjectedPointers(event, policyFlags);
                     }
                 }
             } break;
@@ -771,37 +735,21 @@
                 throw new IllegalStateException("Delegating state can only be reached if "
                         + "there is at least one pointer down!");
             }
-            case MotionEvent.ACTION_MOVE: {
-                // Check  whether some other pointer became active because they have moved
-                // a given distance and if such exist send them to the view hierarchy
-                final int notInjectedCount = getNotInjectedActivePointerCount(
-                        mReceivedPointerTracker, mInjectedPointerTracker);
-                if (notInjectedCount > 0) {
-                    MotionEvent prototype = MotionEvent.obtain(event);
-                    sendDownForAllActiveNotInjectedPointers(prototype, policyFlags);
-                }
-            } break;
-            case MotionEvent.ACTION_UP:
-                // Announce the end of a new touch interaction.
-                sendAccessibilityEvent(
-                        AccessibilityEvent.TYPE_TOUCH_INTERACTION_END);
-                //$FALL-THROUGH$
-            case MotionEvent.ACTION_POINTER_UP: {
+            case MotionEvent.ACTION_UP: {
+                // Announce the end of a the touch interaction.
+                sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_END);
                 mAms.onTouchInteractionEnd();
                 mLongPressingPointerId = -1;
                 mLongPressingPointerDeltaX = 0;
                 mLongPressingPointerDeltaY = 0;
-                // No active pointers => go to initial state.
-                if (mReceivedPointerTracker.getActivePointerCount() == 0) {
-                    mCurrentState = STATE_TOUCH_EXPLORING;
-                }
+                mCurrentState = STATE_TOUCH_EXPLORING;
             } break;
             case MotionEvent.ACTION_CANCEL: {
                 clear(event, policyFlags);
             } break;
         }
-        // Deliver the event striping out inactive pointers.
-        sendMotionEventStripInactivePointers(event, policyFlags);
+        // Deliver the event.
+        sendMotionEvent(event, event.getAction(), ALL_POINTER_ID_BITS, policyFlags);
     }
 
     private void handleMotionEventGestureDetecting(MotionEvent event, int policyFlags) {
@@ -826,12 +774,10 @@
             } break;
             case MotionEvent.ACTION_UP: {
                 mAms.onTouchInteractionEnd();
-                // Announce the end of gesture recognition.
-                sendAccessibilityEvent(
-                        AccessibilityEvent.TYPE_GESTURE_DETECTION_END);
-                // Announce the end of a new touch interaction.
-                sendAccessibilityEvent(
-                        AccessibilityEvent.TYPE_TOUCH_INTERACTION_END);
+                // Announce the end of the gesture recognition.
+                sendAccessibilityEvent(AccessibilityEvent.TYPE_GESTURE_DETECTION_END);
+                // Announce the end of a the touch interaction.
+                sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_END);
 
                 float x = event.getX();
                 float y = event.getY();
@@ -858,7 +804,7 @@
                 }
 
                 mStrokeBuffer.clear();
-                mExitGestureDetectionModeDelayed.remove();
+                mExitGestureDetectionModeDelayed.cancel();
                 mCurrentState = STATE_TOUCH_EXPLORING;
             } break;
             case MotionEvent.ACTION_CANCEL: {
@@ -889,40 +835,26 @@
     }
 
     /**
-     * Sends down events to the view hierarchy for all active pointers which are
+     * Sends down events to the view hierarchy for all pointers which are
      * not already being delivered i.e. pointers that are not yet injected.
      *
      * @param prototype The prototype from which to create the injected events.
      * @param policyFlags The policy flags associated with the event.
      */
-    private void sendDownForAllActiveNotInjectedPointers(MotionEvent prototype, int policyFlags) {
-        ReceivedPointerTracker receivedPointers = mReceivedPointerTracker;
+    private void sendDownForAllNotInjectedPointers(MotionEvent prototype, int policyFlags) {
         InjectedPointerTracker injectedPointers = mInjectedPointerTracker;
+
+        // Inject the injected pointers.
         int pointerIdBits = 0;
         final int pointerCount = prototype.getPointerCount();
-
-        // Find which pointers are already injected.
         for (int i = 0; i < pointerCount; i++) {
             final int pointerId = prototype.getPointerId(i);
-            if (injectedPointers.isInjectedPointerDown(pointerId)) {
-                pointerIdBits |= (1 << pointerId);
-            }
-        }
-
-        // Inject the active and not injected pointers.
-        for (int i = 0; i < pointerCount; i++) {
-            final int pointerId = prototype.getPointerId(i);
-            // Skip inactive pointers.
-            if (!receivedPointers.isActivePointer(pointerId)) {
-                continue;
-            }
             // Do not send event for already delivered pointers.
-            if (injectedPointers.isInjectedPointerDown(pointerId)) {
-                continue;
+            if (!injectedPointers.isInjectedPointerDown(pointerId)) {
+                pointerIdBits |= (1 << pointerId);
+                final int action = computeInjectionAction(MotionEvent.ACTION_DOWN, i);
+                sendMotionEvent(prototype, action, pointerIdBits, policyFlags);
             }
-            pointerIdBits |= (1 << pointerId);
-            final int action = computeInjectionAction(MotionEvent.ACTION_DOWN, i);
-            sendMotionEvent(prototype, action, pointerIdBits, policyFlags);
         }
     }
 
@@ -959,7 +891,7 @@
     }
 
     /**
-     * Sends up events to the view hierarchy for all active pointers which are
+     * Sends up events to the view hierarchy for all pointers which are
      * already being delivered i.e. pointers that are injected.
      *
      * @param prototype The prototype from which to create the injected events.
@@ -982,58 +914,13 @@
     }
 
     /**
-     * Sends a motion event by first stripping the inactive pointers.
-     *
-     * @param prototype The prototype from which to create the injected event.
-     * @param policyFlags The policy flags associated with the event.
-     */
-    private void sendMotionEventStripInactivePointers(MotionEvent prototype, int policyFlags) {
-        ReceivedPointerTracker receivedTracker = mReceivedPointerTracker;
-
-        // All pointers active therefore we just inject the event as is.
-        if (prototype.getPointerCount() == receivedTracker.getActivePointerCount()) {
-            sendMotionEvent(prototype, prototype.getAction(), ALL_POINTER_ID_BITS, policyFlags);
-            return;
-        }
-
-        // No active pointers and the one that just went up was not
-        // active, therefore we have nothing to do.
-        if (receivedTracker.getActivePointerCount() == 0
-                && !receivedTracker.wasLastReceivedUpPointerActive()) {
-            return;
-        }
-
-        // If the action pointer going up/down is not active we have nothing to do.
-        // However, for moves we keep going to report moves of active pointers.
-        final int actionMasked = prototype.getActionMasked();
-        final int actionPointerId = prototype.getPointerId(prototype.getActionIndex());
-        if (actionMasked != MotionEvent.ACTION_MOVE) {
-            if (!receivedTracker.isActiveOrWasLastActiveUpPointer(actionPointerId)) {
-                return;
-            }
-        }
-
-        // If the pointer is active or the pointer that just went up
-        // was active we keep the pointer data in the event.
-        int pointerIdBits = 0;
-        final int pointerCount = prototype.getPointerCount();
-        for (int pointerIndex = 0; pointerIndex < pointerCount; pointerIndex++) {
-            final int pointerId = prototype.getPointerId(pointerIndex);
-            if (receivedTracker.isActiveOrWasLastActiveUpPointer(pointerId)) {
-                pointerIdBits |= (1 << pointerId);
-            }
-        }
-        sendMotionEvent(prototype, prototype.getAction(), pointerIdBits, policyFlags);
-    }
-
-    /**
      * Sends an up and down events.
      *
      * @param prototype The prototype from which to create the injected events.
      * @param policyFlags The policy flags associated with the event.
      */
     private void sendActionDownAndUp(MotionEvent prototype, int policyFlags) {
-        // Tap with the pointer that last explored - we may have inactive pointers.
+        // Tap with the pointer that last explored.
         final int pointerId = prototype.getPointerId(prototype.getActionIndex());
         final int pointerIdBits = (1 << pointerId);
         sendMotionEvent(prototype, MotionEvent.ACTION_DOWN, pointerIdBits, policyFlags);
@@ -1215,9 +1102,9 @@
             }
 
             // Remove pending event deliveries.
-            mSendHoverEnterDelayed.remove();
-            mSendHoverExitDelayed.remove();
-            mPerformLongPressDelayed.remove();
+            mSendHoverEnterAndMoveDelayed.cancel();
+            mSendHoverExitDelayed.cancel();
+            mPerformLongPressDelayed.cancel();
 
             if (mSendTouchExplorationEndDelayed.isPending()) {
                 mSendTouchExplorationEndDelayed.forceSendAndRemove();
@@ -1307,21 +1194,16 @@
      */
     private boolean isDraggingGesture(MotionEvent event) {
         ReceivedPointerTracker receivedTracker = mReceivedPointerTracker;
-        int[] pointerIds = mTempPointerIds;
-        receivedTracker.populateActivePointerIds(pointerIds);
 
-        final int firstPtrIndex = event.findPointerIndex(pointerIds[0]);
-        final int secondPtrIndex = event.findPointerIndex(pointerIds[1]);
+        final float firstPtrX = event.getX(0);
+        final float firstPtrY = event.getY(0);
+        final float secondPtrX = event.getX(1);
+        final float secondPtrY = event.getY(1);
 
-        final float firstPtrX = event.getX(firstPtrIndex);
-        final float firstPtrY = event.getY(firstPtrIndex);
-        final float secondPtrX = event.getX(secondPtrIndex);
-        final float secondPtrY = event.getY(secondPtrIndex);
-
-        final float firstPtrDownX = receivedTracker.getReceivedPointerDownX(firstPtrIndex);
-        final float firstPtrDownY = receivedTracker.getReceivedPointerDownY(firstPtrIndex);
-        final float secondPtrDownX = receivedTracker.getReceivedPointerDownX(secondPtrIndex);
-        final float secondPtrDownY = receivedTracker.getReceivedPointerDownY(secondPtrIndex);
+        final float firstPtrDownX = receivedTracker.getReceivedPointerDownX(0);
+        final float firstPtrDownY = receivedTracker.getReceivedPointerDownY(0);
+        final float secondPtrDownX = receivedTracker.getReceivedPointerDownX(1);
+        final float secondPtrDownY = receivedTracker.getReceivedPointerDownY(1);
 
         return GestureUtils.isDraggingGesture(firstPtrDownX, firstPtrDownY, secondPtrDownX,
                 secondPtrDownY, firstPtrX, firstPtrY, secondPtrX, secondPtrY,
@@ -1350,16 +1232,6 @@
     }
 
     /**
-     * @return The number of non injected active pointers.
-     */
-    private int getNotInjectedActivePointerCount(ReceivedPointerTracker receivedTracker,
-            InjectedPointerTracker injectedTracker) {
-        final int pointerState = receivedTracker.getActivePointers()
-                & ~injectedTracker.getInjectedPointersDown();
-        return Integer.bitCount(pointerState);
-    }
-
-    /**
      * Class for delayed exiting from gesture detecting mode.
      */
     private final class ExitGestureDetectionModeDelayed implements Runnable {
@@ -1368,7 +1240,7 @@
             mHandler.postDelayed(this, EXIT_GESTURE_DETECTION_TIMEOUT);
         }
 
-        public void remove() {
+        public void cancel() {
             mHandler.removeCallbacks(this);
         }
 
@@ -1396,21 +1268,21 @@
             mHandler.postDelayed(this, ViewConfiguration.getLongPressTimeout());
         }
 
-        public void remove() {
-            if (isPending()) {
+        public void cancel() {
+            if (mEvent != null) {
                 mHandler.removeCallbacks(this);
                 clear();
             }
         }
 
-        public boolean isPending() {
-            return (mEvent != null);
+        private boolean isPending() {
+            return mHandler.hasCallbacks(this);
         }
 
         @Override
         public void run() {
-            // Active pointers should not be zero when running this command.
-            if (mReceivedPointerTracker.getActivePointerCount() == 0) {
+            // Pointers should not be zero when running this command.
+            if (mReceivedPointerTracker.getLastReceivedEvent().getPointerCount() == 0) {
                 return;
             }
 
@@ -1461,14 +1333,11 @@
             sendHoverExitAndTouchExplorationGestureEndIfNeeded(mPolicyFlags);
 
             mCurrentState = STATE_DELEGATING;
-            sendDownForAllActiveNotInjectedPointers(mEvent, mPolicyFlags);
+            sendDownForAllNotInjectedPointers(mEvent, mPolicyFlags);
             clear();
         }
 
         private void clear() {
-            if (!isPending()) {
-                return;
-            }
             mEvent.recycle();
             mEvent = null;
             mPolicyFlags = 0;
@@ -1476,59 +1345,114 @@
     }
 
     /**
-     * Class for delayed sending of hover events.
+     * Class for delayed sending of hover enter and move events.
      */
-    class SendHoverDelayed implements Runnable {
-        private final String LOG_TAG_SEND_HOVER_DELAYED = SendHoverDelayed.class.getName();
+    class SendHoverEnterAndMoveDelayed implements Runnable {
+        private final String LOG_TAG_SEND_HOVER_DELAYED = "SendHoverEnterAndMoveDelayed";
 
-        private final int mHoverAction;
-        private final boolean mGestureStarted;
+        private final List<MotionEvent> mEvents = new ArrayList<MotionEvent>();
+
+        private int mPointerIdBits;
+        private int mPolicyFlags;
+
+        public void post(MotionEvent event, boolean touchExplorationInProgress,
+                int pointerIdBits, int policyFlags) {
+            cancel();
+            addEvent(event);
+            mPointerIdBits = pointerIdBits;
+            mPolicyFlags = policyFlags;
+            mHandler.postDelayed(this, mDetermineUserIntentTimeout);
+        }
+
+        public void addEvent(MotionEvent event) {
+            mEvents.add(MotionEvent.obtain(event));
+        }
+
+        public void cancel() {
+            if (isPending()) {
+                mHandler.removeCallbacks(this);
+                clear();
+            }
+        }
+
+        private boolean isPending() {
+            return mHandler.hasCallbacks(this);
+        }
+
+        private void clear() {
+            mPointerIdBits = -1;
+            mPolicyFlags = 0;
+            final int eventCount = mEvents.size();
+            for (int i = eventCount - 1; i >= 0; i--) {
+                mEvents.remove(i).recycle();
+            }
+        }
+
+        public void forceSendAndRemove() {
+            if (isPending()) {
+                run();
+                cancel();
+            }
+        }
+
+        public void run() {
+            // Send an accessibility event to announce the touch exploration start.
+            sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START);
+
+            if (!mEvents.isEmpty()) {
+                // Deliver a down event.
+                sendMotionEvent(mEvents.get(0), MotionEvent.ACTION_HOVER_ENTER,
+                        mPointerIdBits, mPolicyFlags);
+                if (DEBUG) {
+                    Slog.d(LOG_TAG_SEND_HOVER_DELAYED,
+                            "Injecting motion event: ACTION_HOVER_ENTER");
+                }
+
+                // Deliver move events.
+                final int eventCount = mEvents.size();
+                for (int i = 1; i < eventCount; i++) {
+                    sendMotionEvent(mEvents.get(i), MotionEvent.ACTION_HOVER_MOVE,
+                            mPointerIdBits, mPolicyFlags);
+                    if (DEBUG) {
+                        Slog.d(LOG_TAG_SEND_HOVER_DELAYED,
+                                "Injecting motion event: ACTION_HOVER_MOVE");
+                    }
+                }
+            }
+            clear();
+        }
+    }
+
+    /**
+     * Class for delayed sending of hover exit events.
+     */
+    class SendHoverExitDelayed implements Runnable {
+        private final String LOG_TAG_SEND_HOVER_DELAYED = "SendHoverExitDelayed";
 
         private MotionEvent mPrototype;
         private int mPointerIdBits;
         private int mPolicyFlags;
 
-        public SendHoverDelayed(int hoverAction, boolean gestureStarted) {
-            mHoverAction = hoverAction;
-            mGestureStarted = gestureStarted;
-        }
-
-        public void post(MotionEvent prototype, boolean touchExplorationInProgress,
-                int pointerIdBits, int policyFlags) {
-            remove();
+        public void post(MotionEvent prototype, int pointerIdBits, int policyFlags) {
+            cancel();
             mPrototype = MotionEvent.obtain(prototype);
             mPointerIdBits = pointerIdBits;
             mPolicyFlags = policyFlags;
             mHandler.postDelayed(this, mDetermineUserIntentTimeout);
         }
 
-        public float getX() {
+        public void cancel() {
             if (isPending()) {
-                return mPrototype.getX();
+                mHandler.removeCallbacks(this);
+                clear();
             }
-            return 0;
-        }
-
-        public float getY() {
-            if (isPending()) {
-                return mPrototype.getY();
-            }
-            return 0;
-        }
-
-        public void remove() {
-            mHandler.removeCallbacks(this);
-            clear();
         }
 
         private boolean isPending() {
-            return (mPrototype != null);
+            return mHandler.hasCallbacks(this);
         }
 
         private void clear() {
-            if (!isPending()) {
-                return;
-            }
             mPrototype.recycle();
             mPrototype = null;
             mPointerIdBits = -1;
@@ -1538,29 +1462,25 @@
         public void forceSendAndRemove() {
             if (isPending()) {
                 run();
-                remove();
+                cancel();
             }
         }
 
         public void run() {
             if (DEBUG) {
-                Slog.d(LOG_TAG_SEND_HOVER_DELAYED, "Injecting motion event: "
-                        + MotionEvent.actionToString(mHoverAction));
-                Slog.d(LOG_TAG_SEND_HOVER_DELAYED, mGestureStarted ?
-                        "touchExplorationGestureStarted" : "touchExplorationGestureEnded");
+                Slog.d(LOG_TAG_SEND_HOVER_DELAYED, "Injecting motion event:"
+                        + " ACTION_HOVER_EXIT");
             }
-            if (mGestureStarted) {
-                sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START);
-            } else {
-                if (!mSendTouchExplorationEndDelayed.isPending()) {
-                    mSendTouchExplorationEndDelayed.post();
-                }
-                if (mSendTouchInteractionEndDelayed.isPending()) {
-                    mSendTouchInteractionEndDelayed.remove();
-                    mSendTouchInteractionEndDelayed.post();
-                }
+            sendMotionEvent(mPrototype, MotionEvent.ACTION_HOVER_EXIT,
+                    mPointerIdBits, mPolicyFlags);
+            if (!mSendTouchExplorationEndDelayed.isPending()) {
+                mSendTouchExplorationEndDelayed.cancel();
+                mSendTouchExplorationEndDelayed.post();
             }
-            sendMotionEvent(mPrototype, mHoverAction, mPointerIdBits, mPolicyFlags);
+            if (mSendTouchInteractionEndDelayed.isPending()) {
+                  mSendTouchInteractionEndDelayed.cancel();
+                mSendTouchInteractionEndDelayed.post();
+            }
             clear();
         }
     }
@@ -1574,7 +1494,7 @@
             mDelay = delay;
         }
 
-        public void remove() {
+        public void cancel() {
             mHandler.removeCallbacks(this);
         }
 
@@ -1589,7 +1509,7 @@
         public void forceSendAndRemove() {
             if (isPending()) {
                 run();
-                remove();
+                cancel();
             }
         }
 
@@ -1736,15 +1656,6 @@
     class ReceivedPointerTracker {
         private static final String LOG_TAG_RECEIVED_POINTER_TRACKER = "ReceivedPointerTracker";
 
-        // The coefficient by which to multiply
-        // ViewConfiguration.#getScaledTouchSlop()
-        // to compute #mThresholdActivePointer.
-        private static final int COEFFICIENT_ACTIVE_POINTER = 2;
-
-        // Pointers that moved less than mThresholdActivePointer
-        // are considered active i.e. are ignored.
-        private final double mThresholdActivePointer;
-
         // Keep track of where and when a pointer went down.
         private final float[] mReceivedPointerDownX = new float[MAX_POINTER_COUNT];
         private final float[] mReceivedPointerDownY = new float[MAX_POINTER_COUNT];
@@ -1756,36 +1667,19 @@
         // The edge flags of the last received down event.
         private int mLastReceivedDownEdgeFlags;
 
-        // Which down pointers are active.
-        private int mActivePointers;
-
-        // Primary active pointer which is either the first that went down
-        // or if it goes up the next active that most recently went down.
-        private int mPrimaryActivePointerId;
-
-        // Flag indicating that there is at least one active pointer moving.
-        private boolean mHasMovingActivePointer;
+        // Primary pointer which is either the first that went down
+        // or if it goes up the next one that most recently went down.
+        private int mPrimaryPointerId;
 
         // Keep track of the last up pointer data.
         private long mLastReceivedUpPointerDownTime;
         private int mLastReceivedUpPointerId;
-        private boolean mLastReceivedUpPointerActive;
         private float mLastReceivedUpPointerDownX;
         private float mLastReceivedUpPointerDownY;
 
         private MotionEvent mLastReceivedEvent;
 
         /**
-         * Creates a new instance.
-         *
-         * @param context Context for looking up resources.
-         */
-        public ReceivedPointerTracker(Context context) {
-            mThresholdActivePointer =
-                ViewConfiguration.get(context).getScaledTouchSlop() * COEFFICIENT_ACTIVE_POINTER;
-        }
-
-        /**
          * Clears the internals state.
          */
         public void clear() {
@@ -1793,12 +1687,9 @@
             Arrays.fill(mReceivedPointerDownY, 0);
             Arrays.fill(mReceivedPointerDownTime, 0);
             mReceivedPointersDown = 0;
-            mActivePointers = 0;
-            mPrimaryActivePointerId = 0;
-            mHasMovingActivePointer = false;
+            mPrimaryPointerId = 0;
             mLastReceivedUpPointerDownTime = 0;
             mLastReceivedUpPointerId = 0;
-            mLastReceivedUpPointerActive = false;
             mLastReceivedUpPointerDownX = 0;
             mLastReceivedUpPointerDownY = 0;
         }
@@ -1822,9 +1713,6 @@
                 case MotionEvent.ACTION_POINTER_DOWN: {
                     handleReceivedPointerDown(event.getActionIndex(), event);
                 } break;
-                case MotionEvent.ACTION_MOVE: {
-                    handleReceivedPointerMove(event);
-                } break;
                 case MotionEvent.ACTION_UP: {
                     handleReceivedPointerUp(event.getActionIndex(), event);
                 } break;
@@ -1833,7 +1721,7 @@
                 } break;
             }
             if (DEBUG) {
-                Slog.i(LOG_TAG_RECEIVED_POINTER_TRACKER, "Received pointer: " + toString());
+                Slog.i(LOG_TAG_RECEIVED_POINTER_TRACKER, "Received pointer:\n" + toString());
             }
         }
 
@@ -1852,20 +1740,6 @@
         }
 
         /**
-         * @return The bits of the pointers that are active.
-         */
-        public int getActivePointers() {
-            return mActivePointers;
-        }
-
-        /**
-         * @return The number of down input  pointers that are active.
-         */
-        public int getActivePointerCount() {
-            return Integer.bitCount(mActivePointers);
-        }
-
-        /**
          * Whether an received pointer is down.
          *
          * @param pointerId The unique pointer id.
@@ -1877,17 +1751,6 @@
         }
 
         /**
-         * Whether an input pointer is active.
-         *
-         * @param pointerId The unique pointer id.
-         * @return True if the pointer is active.
-         */
-        public boolean isActivePointer(int pointerId) {
-            final int pointerFlag = (1 << pointerId);
-            return (mActivePointers & pointerFlag) != 0;
-        }
-
-        /**
          * @param pointerId The unique pointer id.
          * @return The X coordinate where the pointer went down.
          */
@@ -1914,11 +1777,11 @@
         /**
          * @return The id of the primary pointer.
          */
-        public int getPrimaryActivePointerId() {
-            if (mPrimaryActivePointerId == INVALID_POINTER_ID) {
-                mPrimaryActivePointerId = findPrimaryActivePointer();
+        public int getPrimaryPointerId() {
+            if (mPrimaryPointerId == INVALID_POINTER_ID) {
+                mPrimaryPointerId = findPrimaryPointerId();
             }
-            return mPrimaryActivePointerId;
+            return mPrimaryPointerId;
         }
 
         /**
@@ -1929,14 +1792,6 @@
         }
 
         /**
-         * @return The id of the last received pointer that went up.
-         */
-        public int getLastReceivedUpPointerId() {
-            return mLastReceivedUpPointerId;
-        }
-
-
-        /**
          * @return The down X of the last received pointer that went up.
          */
         public float getLastReceivedUpPointerDownX() {
@@ -1958,39 +1813,6 @@
         }
 
         /**
-         * @return Whether the last received pointer that went up was active.
-         */
-        public boolean wasLastReceivedUpPointerActive() {
-            return mLastReceivedUpPointerActive;
-        }
-        /**
-         * Populates the active pointer IDs to the given array.
-         * <p>
-         * Note: The client is responsible for providing large enough array.
-         *
-         * @param outPointerIds The array to which to write the active pointers.
-         */
-        public void populateActivePointerIds(int[] outPointerIds) {
-            int index = 0;
-            for (int idBits = mActivePointers; idBits != 0; ) {
-                final int id = Integer.numberOfTrailingZeros(idBits);
-                idBits &= ~(1 << id);
-                outPointerIds[index] = id;
-                index++;
-            }
-        }
-
-        /**
-         * @param pointerId The unique pointer id.
-         * @return Whether the pointer is active or was the last active than went up.
-         */
-        public boolean isActiveOrWasLastActiveUpPointer(int pointerId) {
-            return (isActivePointer(pointerId)
-                    || (mLastReceivedUpPointerId == pointerId
-                            && mLastReceivedUpPointerActive));
-        }
-
-        /**
          * Handles a received pointer down event.
          *
          * @param pointerIndex The index of the pointer that has changed.
@@ -2002,7 +1824,6 @@
 
             mLastReceivedUpPointerId = 0;
             mLastReceivedUpPointerDownTime = 0;
-            mLastReceivedUpPointerActive = false;
             mLastReceivedUpPointerDownX = 0;
             mLastReceivedUpPointerDownX = 0;
 
@@ -2013,25 +1834,7 @@
             mReceivedPointerDownY[pointerId] = event.getY(pointerIndex);
             mReceivedPointerDownTime[pointerId] = event.getEventTime();
 
-            if (!mHasMovingActivePointer) {
-                // If still no moving active pointers every
-                // down pointer is the only active one.
-                mActivePointers = pointerFlag;
-                mPrimaryActivePointerId = pointerId;
-            } else {
-                // If at least one moving active pointer every
-                // subsequent down pointer is active.
-                mActivePointers |= pointerFlag;
-            }
-        }
-
-        /**
-         * Handles a received pointer move event.
-         *
-         * @param event The event to be handled.
-         */
-        private void handleReceivedPointerMove(MotionEvent event) {
-            detectActivePointers(event);
+            mPrimaryPointerId = pointerId;
         }
 
         /**
@@ -2046,80 +1849,38 @@
 
             mLastReceivedUpPointerId = pointerId;
             mLastReceivedUpPointerDownTime = getReceivedPointerDownTime(pointerId);
-            mLastReceivedUpPointerActive = isActivePointer(pointerId);
             mLastReceivedUpPointerDownX = mReceivedPointerDownX[pointerId];
             mLastReceivedUpPointerDownY = mReceivedPointerDownY[pointerId];
 
             mReceivedPointersDown &= ~pointerFlag;
-            mActivePointers &= ~pointerFlag;
             mReceivedPointerDownX[pointerId] = 0;
             mReceivedPointerDownY[pointerId] = 0;
             mReceivedPointerDownTime[pointerId] = 0;
 
-            if (mActivePointers == 0) {
-                mHasMovingActivePointer = false;
-            }
-            if (mPrimaryActivePointerId == pointerId) {
-                mPrimaryActivePointerId = INVALID_POINTER_ID;
+            if (mPrimaryPointerId == pointerId) {
+                mPrimaryPointerId = INVALID_POINTER_ID;
             }
         }
 
         /**
-         * Detects the active pointers in an event.
-         *
-         * @param event The event to examine.
+         * @return The primary pointer id.
          */
-        private void detectActivePointers(MotionEvent event) {
-            for (int i = 0, count = event.getPointerCount(); i < count; i++) {
-                final int pointerId = event.getPointerId(i);
-                if (mHasMovingActivePointer) {
-                    // If already active => nothing to do.
-                    if (isActivePointer(pointerId)) {
-                        continue;
-                    }
-                }
-                // Active pointers are ones that moved more than a given threshold.
-                final float pointerDeltaMove = computePointerDeltaMove(i, event);
-                if (pointerDeltaMove > mThresholdActivePointer) {
-                    final int pointerFlag = (1 << pointerId);
-                    mActivePointers |= pointerFlag;
-                    mHasMovingActivePointer = true;
-                }
-            }
-        }
-
-        /**
-         * @return The primary active pointer.
-         */
-        private int findPrimaryActivePointer() {
-            int primaryActivePointerId = INVALID_POINTER_ID;
+        private int findPrimaryPointerId() {
+            int primaryPointerId = INVALID_POINTER_ID;
             long minDownTime = Long.MAX_VALUE;
-            // Find the active pointer that went down first.
-            for (int i = 0, count = mReceivedPointerDownTime.length; i < count; i++) {
-                if (isActivePointer(i)) {
-                    final long downPointerTime = mReceivedPointerDownTime[i];
-                    if (downPointerTime < minDownTime) {
-                        minDownTime = downPointerTime;
-                        primaryActivePointerId = i;
-                    }
+
+            // Find the pointer that went down first.
+            int pointerIdBits = mReceivedPointersDown;
+            while (pointerIdBits > 0) {
+                final int pointerId = Integer.numberOfTrailingZeros(pointerIdBits);
+                pointerIdBits &= ~(1 << pointerId);
+                final long downPointerTime = mReceivedPointerDownTime[pointerId];
+                if (downPointerTime < minDownTime) {
+                    minDownTime = downPointerTime;
+                    primaryPointerId = pointerId;
                 }
             }
-            return primaryActivePointerId;
-        }
-
-        /**
-         * Computes the move for a given action pointer index since the
-         * corresponding pointer went down.
-         *
-         * @param pointerIndex The action pointer index.
-         * @param event The event to examine.
-         * @return The distance the pointer has moved.
-         */
-        private float computePointerDeltaMove(int pointerIndex, MotionEvent event) {
-            final int pointerId = event.getPointerId(pointerIndex);
-            final float deltaX = event.getX(pointerIndex) - mReceivedPointerDownX[pointerId];
-            final float deltaY = event.getY(pointerIndex) - mReceivedPointerDownY[pointerId];
-            return (float) Math.hypot(deltaX, deltaY);
+            return primaryPointerId;
         }
 
         @Override
@@ -2136,18 +1897,8 @@
                 }
             }
             builder.append("]");
-            builder.append("\nActive pointers #");
-            builder.append(getActivePointerCount());
-            builder.append(" [ ");
-            for (int i = 0; i < MAX_POINTER_COUNT; i++) {
-                if (isActivePointer(i)) {
-                    builder.append(i);
-                    builder.append(" ");
-                }
-            }
-            builder.append("]");
-            builder.append("\nPrimary active pointer id [ ");
-            builder.append(getPrimaryActivePointerId());
+            builder.append("\nPrimary pointer id [ ");
+            builder.append(getPrimaryPointerId());
             builder.append(" ]");
             builder.append("\n=========================");
             return builder.toString();
diff --git a/services/java/com/android/server/accounts/AccountManagerService.java b/services/java/com/android/server/accounts/AccountManagerService.java
index 0fbde37..2145b76 100644
--- a/services/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/java/com/android/server/accounts/AccountManagerService.java
@@ -56,7 +56,6 @@
 import android.os.Bundle;
 import android.os.Environment;
 import android.os.Handler;
-import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
@@ -74,6 +73,7 @@
 import com.android.internal.R;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.FgThread;
 import com.google.android.collect.Lists;
 import com.google.android.collect.Sets;
 
@@ -113,7 +113,6 @@
     private final PackageManager mPackageManager;
     private UserManager mUserManager;
 
-    private HandlerThread mMessageThread;
     private final MessageHandler mMessageHandler;
 
     // Messages that can be sent on mHandler
@@ -234,9 +233,7 @@
         mContext = context;
         mPackageManager = packageManager;
 
-        mMessageThread = new HandlerThread("AccountManagerService");
-        mMessageThread.start();
-        mMessageHandler = new MessageHandler(mMessageThread.getLooper());
+        mMessageHandler = new MessageHandler(FgThread.get().getLooper());
 
         mAuthenticatorCache = authenticatorCache;
         mAuthenticatorCache.setListener(this, null /* Handler */);
@@ -1510,7 +1507,10 @@
             int userId) {
         // Only allow the system process to read accounts of other users
         if (userId != UserHandle.getCallingUserId()
-                && Binder.getCallingUid() != Process.myUid()) {
+                && Binder.getCallingUid() != Process.myUid()
+                && mContext.checkCallingOrSelfPermission(
+                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
+                    != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("User " + UserHandle.getCallingUserId()
                     + " trying to confirm account credentials for " + userId);
         }
@@ -1779,7 +1779,10 @@
         int callingUid = Binder.getCallingUid();
         // Only allow the system process to read accounts of other users
         if (userId != UserHandle.getCallingUserId()
-                && callingUid != Process.myUid()) {
+                && callingUid != Process.myUid()
+                && mContext.checkCallingOrSelfPermission(
+                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
+                    != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("User " + UserHandle.getCallingUserId()
                     + " trying to get account for " + userId);
         }
@@ -2537,7 +2540,7 @@
         return userId;
     }
 
-    private boolean inSystemImage(int callingUid) {
+    private boolean isPrivileged(int callingUid) {
         final int callingUserId = UserHandle.getUserId(callingUid);
 
         final PackageManager userPackageManager;
@@ -2553,7 +2556,7 @@
             try {
                 PackageInfo packageInfo = userPackageManager.getPackageInfo(name, 0 /* flags */);
                 if (packageInfo != null
-                        && (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+                        && (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_PRIVILEGED) != 0) {
                     return true;
                 }
             } catch (PackageManager.NameNotFoundException e) {
@@ -2564,7 +2567,7 @@
     }
 
     private boolean permissionIsGranted(Account account, String authTokenType, int callerUid) {
-        final boolean inSystemImage = inSystemImage(callerUid);
+        final boolean isPrivileged = isPrivileged(callerUid);
         final boolean fromAuthenticator = account != null
                 && hasAuthenticatorUid(account.type, callerUid);
         final boolean hasExplicitGrants = account != null
@@ -2575,7 +2578,7 @@
                     + ": is authenticator? " + fromAuthenticator
                     + ", has explicit permission? " + hasExplicitGrants);
         }
-        return fromAuthenticator || hasExplicitGrants || inSystemImage;
+        return fromAuthenticator || hasExplicitGrants || isPrivileged;
     }
 
     private boolean hasAuthenticatorUid(String accountType, int callingUid) {
diff --git a/services/java/com/android/server/am/ActiveServices.java b/services/java/com/android/server/am/ActiveServices.java
index 5c24e67..b75eab4 100644
--- a/services/java/com/android/server/am/ActiveServices.java
+++ b/services/java/com/android/server/am/ActiveServices.java
@@ -20,13 +20,15 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 
+import android.os.Handler;
+import android.util.ArrayMap;
+import com.android.internal.app.ProcessStats;
 import com.android.internal.os.BatteryStatsImpl;
+import com.android.internal.os.TransferPipe;
 import com.android.server.am.ActivityManagerService.ItemMatcher;
 import com.android.server.am.ActivityManagerService.NeededUriGrants;
 
@@ -52,14 +54,15 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.util.EventLog;
-import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.TimeUtils;
 
-public class ActiveServices {
+public final class ActiveServices {
     static final boolean DEBUG_SERVICE = ActivityManagerService.DEBUG_SERVICE;
     static final boolean DEBUG_SERVICE_EXECUTING = ActivityManagerService.DEBUG_SERVICE_EXECUTING;
+    static final boolean DEBUG_DELAYED_SERVICE = ActivityManagerService.DEBUG_SERVICE;
+    static final boolean DEBUG_DELAYED_STATS = DEBUG_DELAYED_SERVICE;
     static final boolean DEBUG_MU = ActivityManagerService.DEBUG_MU;
     static final String TAG = ActivityManagerService.TAG;
     static final String TAG_MU = ActivityManagerService.TAG_MU;
@@ -67,6 +70,9 @@
     // How long we wait for a service to finish executing.
     static final int SERVICE_TIMEOUT = 20*1000;
 
+    // How long we wait for a service to finish executing.
+    static final int SERVICE_BACKGROUND_TIMEOUT = SERVICE_TIMEOUT * 10;
+
     // How long a service needs to be running until restarting its process
     // is no longer considered to be a relaunch of the service.
     static final int SERVICE_RESTART_DURATION = 5*1000;
@@ -89,16 +95,24 @@
     // LRU background list.
     static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
 
+    // How long we wait for a background started service to stop itself before
+    // allowing the next pending start to run.
+    static final int BG_START_TIMEOUT = 15*1000;
+
     final ActivityManagerService mAm;
 
-    final ServiceMap mServiceMap = new ServiceMap();
+    // Maximum number of services that we allow to start in the background
+    // at the same time.
+    final int mMaxStartingBackground;
+
+    final SparseArray<ServiceMap> mServiceMap = new SparseArray<ServiceMap>();
 
     /**
      * All currently bound service connections.  Keys are the IBinder of
      * the client's IServiceConnection.
      */
-    final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
-            = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
+    final ArrayMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
+            = new ArrayMap<IBinder, ArrayList<ConnectionRecord>>();
 
     /**
      * List of services that we have been asked to start,
@@ -121,99 +135,130 @@
     final ArrayList<ServiceRecord> mStoppingServices
             = new ArrayList<ServiceRecord>();
 
-    static class ServiceMap {
+    static final class DelayingProcess extends ArrayList<ServiceRecord> {
+        long timeoout;
+    }
 
-        private final SparseArray<HashMap<ComponentName, ServiceRecord>> mServicesByNamePerUser
-                = new SparseArray<HashMap<ComponentName, ServiceRecord>>();
-        private final SparseArray<HashMap<Intent.FilterComparison, ServiceRecord>>
-                mServicesByIntentPerUser = new SparseArray<
-                    HashMap<Intent.FilterComparison, ServiceRecord>>();
+    /**
+     * Information about services for a single user.
+     */
+    class ServiceMap extends Handler {
+        final ArrayMap<ComponentName, ServiceRecord> mServicesByName
+                = new ArrayMap<ComponentName, ServiceRecord>();
+        final ArrayMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent
+                = new ArrayMap<Intent.FilterComparison, ServiceRecord>();
 
-        ServiceRecord getServiceByName(ComponentName name, int callingUser) {
-            // TODO: Deal with global services
-            if (DEBUG_MU)
-                Slog.v(TAG_MU, "getServiceByName(" + name + "), callingUser = " + callingUser);
-            return getServices(callingUser).get(name);
-        }
+        final ArrayList<ServiceRecord> mDelayedStartList
+                = new ArrayList<ServiceRecord>();
+        /* XXX eventually I'd like to have this based on processes instead of services.
+         * That is, if we try to start two services in a row both running in the same
+         * process, this should be one entry in mStartingBackground for that one process
+         * that remains until all services in it are done.
+        final ArrayMap<ProcessRecord, DelayingProcess> mStartingBackgroundMap
+                = new ArrayMap<ProcessRecord, DelayingProcess>();
+        final ArrayList<DelayingProcess> mStartingProcessList
+                = new ArrayList<DelayingProcess>();
+        */
 
-        ServiceRecord getServiceByName(ComponentName name) {
-            return getServiceByName(name, -1);
-        }
+        final ArrayList<ServiceRecord> mStartingBackground
+                = new ArrayList<ServiceRecord>();
 
-        ServiceRecord getServiceByIntent(Intent.FilterComparison filter, int callingUser) {
-            // TODO: Deal with global services
-            if (DEBUG_MU)
-                Slog.v(TAG_MU, "getServiceByIntent(" + filter + "), callingUser = " + callingUser);
-            return getServicesByIntent(callingUser).get(filter);
-        }
+        static final int MSG_BG_START_TIMEOUT = 1;
 
-        ServiceRecord getServiceByIntent(Intent.FilterComparison filter) {
-            return getServiceByIntent(filter, -1);
-        }
-
-        void putServiceByName(ComponentName name, int callingUser, ServiceRecord value) {
-            // TODO: Deal with global services
-            getServices(callingUser).put(name, value);
-        }
-
-        void putServiceByIntent(Intent.FilterComparison filter, int callingUser,
-                ServiceRecord value) {
-            // TODO: Deal with global services
-            getServicesByIntent(callingUser).put(filter, value);
-        }
-
-        void removeServiceByName(ComponentName name, int callingUser) {
-            // TODO: Deal with global services
-            ServiceRecord removed = getServices(callingUser).remove(name);
-            if (DEBUG_MU)
-                Slog.v(TAG, "removeServiceByName user=" + callingUser + " name=" + name
-                        + " removed=" + removed);
-        }
-
-        void removeServiceByIntent(Intent.FilterComparison filter, int callingUser) {
-            // TODO: Deal with global services
-            ServiceRecord removed = getServicesByIntent(callingUser).remove(filter);
-            if (DEBUG_MU)
-                Slog.v(TAG_MU, "removeServiceByIntent user=" + callingUser + " intent=" + filter
-                        + " removed=" + removed);
-        }
-
-        Collection<ServiceRecord> getAllServices(int callingUser) {
-            // TODO: Deal with global services
-            return getServices(callingUser).values();
-        }
-
-        private HashMap<ComponentName, ServiceRecord> getServices(int callingUser) {
-            HashMap<ComponentName, ServiceRecord> map = mServicesByNamePerUser.get(callingUser);
-            if (map == null) {
-                map = new HashMap<ComponentName, ServiceRecord>();
-                mServicesByNamePerUser.put(callingUser, map);
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_BG_START_TIMEOUT: {
+                    synchronized (mAm) {
+                        rescheduleDelayedStarts();
+                    }
+                } break;
             }
-            return map;
         }
 
-        private HashMap<Intent.FilterComparison, ServiceRecord> getServicesByIntent(
-                int callingUser) {
-            HashMap<Intent.FilterComparison, ServiceRecord> map
-                    = mServicesByIntentPerUser.get(callingUser);
-            if (map == null) {
-                map = new HashMap<Intent.FilterComparison, ServiceRecord>();
-                mServicesByIntentPerUser.put(callingUser, map);
+        void ensureNotStartingBackground(ServiceRecord r) {
+            if (mStartingBackground.remove(r)) {
+                if (DEBUG_DELAYED_STATS) Slog.v(TAG, "No longer background starting: " + r);
+                rescheduleDelayedStarts();
             }
-            return map;
+            if (mDelayedStartList.remove(r)) {
+                if (DEBUG_DELAYED_STATS) Slog.v(TAG, "No longer delaying start: " + r);
+            }
+        }
+
+        void rescheduleDelayedStarts() {
+            removeMessages(MSG_BG_START_TIMEOUT);
+            final long now = SystemClock.uptimeMillis();
+            for (int i=0, N=mStartingBackground.size(); i<N; i++) {
+                ServiceRecord r = mStartingBackground.get(i);
+                if (r.startingBgTimeout <= now) {
+                    Slog.i(TAG, "Waited long enough for: " + r);
+                    mStartingBackground.remove(i);
+                    N--;
+                }
+            }
+            while (mDelayedStartList.size() > 0
+                    && mStartingBackground.size() < mMaxStartingBackground) {
+                ServiceRecord r = mDelayedStartList.remove(0);
+                if (DEBUG_DELAYED_STATS) Slog.v(TAG, "REM FR DELAY LIST (exec next): " + r);
+                if (r.pendingStarts.size() <= 0) {
+                    Slog.w(TAG, "**** NO PENDING STARTS! " + r + " startReq=" + r.startRequested
+                            + " delayedStop=" + r.delayedStop);
+                }
+                if (DEBUG_DELAYED_SERVICE) {
+                    if (mDelayedStartList.size() > 0) {
+                        Slog.v(TAG, "Remaining delayed list:");
+                        for (int i=0; i<mDelayedStartList.size(); i++) {
+                            Slog.v(TAG, "  #" + i + ": " + mDelayedStartList.get(i));
+                        }
+                    }
+                }
+                r.delayed = false;
+                startServiceInnerLocked(this, r.pendingStarts.get(0).intent, r, false, true);
+            }
+            if (mStartingBackground.size() > 0) {
+                ServiceRecord next = mStartingBackground.get(0);
+                long when = next.startingBgTimeout > now ? next.startingBgTimeout : now;
+                if (DEBUG_DELAYED_SERVICE) Slog.v(TAG, "Top bg start is " + next
+                        + ", can delay others up to " + when);
+                Message msg = obtainMessage(MSG_BG_START_TIMEOUT);
+                sendMessageAtTime(msg, when);
+            }
         }
     }
 
     public ActiveServices(ActivityManagerService service) {
         mAm = service;
+        mMaxStartingBackground = ActivityManager.isLowRamDeviceStatic() ? 1 : 3;
+    }
+
+    ServiceRecord getServiceByName(ComponentName name, int callingUser) {
+        // TODO: Deal with global services
+        if (DEBUG_MU)
+            Slog.v(TAG_MU, "getServiceByName(" + name + "), callingUser = " + callingUser);
+        return getServiceMap(callingUser).mServicesByName.get(name);
+    }
+
+    private ServiceMap getServiceMap(int callingUser) {
+        ServiceMap smap = mServiceMap.get(callingUser);
+        if (smap == null) {
+            smap = new ServiceMap();
+            mServiceMap.put(callingUser, smap);
+        }
+        return smap;
+    }
+
+    ArrayMap<ComponentName, ServiceRecord> getServices(int callingUser) {
+        return getServiceMap(callingUser).mServicesByName;
     }
 
     ComponentName startServiceLocked(IApplicationThread caller,
             Intent service, String resolvedType,
             int callingPid, int callingUid, int userId) {
-        if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
+        if (DEBUG_DELAYED_STATS) Slog.v(TAG, "startService: " + service
                 + " type=" + resolvedType + " args=" + service.getExtras());
 
+        final boolean callerFg;
         if (caller != null) {
             final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
             if (callerApp == null) {
@@ -222,11 +267,15 @@
                         + " (pid=" + Binder.getCallingPid()
                         + ") when starting service " + service);
             }
+            callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
+        } else {
+            callerFg = true;
         }
 
+
         ServiceLookupResult res =
             retrieveServiceLocked(service, resolvedType,
-                    callingPid, callingUid, userId, true);
+                    callingPid, callingUid, userId, true, callerFg);
         if (res == null) {
             return null;
         }
@@ -240,28 +289,126 @@
         if (unscheduleServiceRestartLocked(r)) {
             if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
         }
+        r.lastActivity = SystemClock.uptimeMillis();
         r.startRequested = true;
-        r.callStart = false;
+        r.delayedStop = false;
         r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
                 service, neededGrants));
-        r.lastActivity = SystemClock.uptimeMillis();
+
+        final ServiceMap smap = getServiceMap(r.userId);
+        boolean addToStarting = false;
+        if (!callerFg && r.app == null && mAm.mStartedUsers.get(r.userId) != null) {
+            ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid);
+            if (proc == null || proc.curProcState >= ActivityManager.PROCESS_STATE_RECEIVER) {
+                // If this is not coming from a foreground caller, then we may want
+                // to delay the start if there are already other background services
+                // that are starting.  This is to avoid process start spam when lots
+                // of applications are all handling things like connectivity broadcasts.
+                if (DEBUG_DELAYED_SERVICE) Slog.v(TAG, "Potential start delay of " + r + " in "
+                        + proc);
+                if (r.delayed) {
+                    // This service is already scheduled for a delayed start; just leave
+                    // it still waiting.
+                    if (DEBUG_DELAYED_STATS) Slog.v(TAG, "Continuing to delay: " + r);
+                    return r.name;
+                }
+                if (smap.mStartingBackground.size() >= mMaxStartingBackground) {
+                    // Something else is starting, delay!
+                    Slog.i(TAG, "Delaying start of: " + r);
+                    smap.mDelayedStartList.add(r);
+                    r.delayed = true;
+                    return r.name;
+                }
+                if (DEBUG_DELAYED_STATS) Slog.v(TAG, "Not delaying: " + r);
+                addToStarting = true;
+            } else if (proc.curProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
+                // We slightly loosen when we will enqueue this new service as a background
+                // starting service we are waiting for, to also include processes that are
+                // currently running other services.
+                addToStarting = true;
+                if (DEBUG_DELAYED_STATS) Slog.v(TAG, "Not delaying, but counting as bg: " + r);
+            } else if (DEBUG_DELAYED_STATS) {
+                StringBuilder sb = new StringBuilder(128);
+                sb.append("Not potential delay (state=").append(proc.curProcState)
+                        .append(' ').append(proc.adjType);
+                String reason = proc.makeAdjReason();
+                if (reason != null) {
+                    sb.append(' ');
+                    sb.append(reason);
+                }
+                sb.append("): ");
+                sb.append(r.toString());
+                Slog.v(TAG, sb.toString());
+            }
+        } else if (DEBUG_DELAYED_STATS) {
+            if (callerFg) {
+                Slog.v(TAG, "Not potential delay (callerFg=" + callerFg + " uid="
+                        + callingUid + " pid=" + callingPid + "): " + r);
+            } else if (r.app != null) {
+                Slog.v(TAG, "Not potential delay (cur app=" + r.app + "): " + r);
+            } else {
+                Slog.v(TAG, "Not potential delay (user " + r.userId + " not started): " + r);
+            }
+        }
+
+        return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
+    }
+
+    ComponentName startServiceInnerLocked(ServiceMap smap, Intent service,
+            ServiceRecord r, boolean callerFg, boolean addToStarting) {
+        ProcessStats.ServiceState stracker = r.getTracker();
+        if (stracker != null) {
+            stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
+        }
+        r.callStart = false;
         synchronized (r.stats.getBatteryStats()) {
             r.stats.startRunningLocked();
         }
-        String error = bringUpServiceLocked(r, service.getFlags(), false);
+        String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false);
         if (error != null) {
             return new ComponentName("!!", error);
         }
+
+        if (r.startRequested && addToStarting) {
+            boolean first = smap.mStartingBackground.size() == 0;
+            smap.mStartingBackground.add(r);
+            r.startingBgTimeout = SystemClock.uptimeMillis() + BG_START_TIMEOUT;
+            if (DEBUG_DELAYED_SERVICE) {
+                RuntimeException here = new RuntimeException("here");
+                here.fillInStackTrace();
+                Slog.v(TAG, "Starting background (first=" + first + "): " + r, here);
+            } else if (DEBUG_DELAYED_STATS) {
+                Slog.v(TAG, "Starting background (first=" + first + "): " + r);
+            }
+            if (first) {
+                smap.rescheduleDelayedStarts();
+            }
+        } else if (callerFg) {
+            smap.ensureNotStartingBackground(r);
+        }
+
         return r.name;
     }
 
     private void stopServiceLocked(ServiceRecord service) {
+        if (service.delayed) {
+            // If service isn't actually running, but is is being held in the
+            // delayed list, then we need to keep it started but note that it
+            // should be stopped once no longer delayed.
+            if (DEBUG_DELAYED_STATS) Slog.v(TAG, "Delaying stop of pending: " + service);
+            service.delayedStop = true;
+            return;
+        }
         synchronized (service.stats.getBatteryStats()) {
             service.stats.stopRunningLocked();
         }
         service.startRequested = false;
+        if (service.tracker != null) {
+            service.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
+                    SystemClock.uptimeMillis());
+        }
         service.callStart = false;
-        bringDownServiceLocked(service, false);
+        bringDownServiceIfNeededLocked(service, false, false);
     }
 
     int stopServiceLocked(IApplicationThread caller, Intent service,
@@ -279,7 +426,7 @@
 
         // If this service is active, make sure it is stopped.
         ServiceLookupResult r = retrieveServiceLocked(service, resolvedType,
-                Binder.getCallingPid(), Binder.getCallingUid(), userId, false);
+                Binder.getCallingPid(), Binder.getCallingUid(), userId, false, false);
         if (r != null) {
             if (r.record != null) {
                 final long origId = Binder.clearCallingIdentity();
@@ -299,7 +446,7 @@
     IBinder peekServiceLocked(Intent service, String resolvedType) {
         ServiceLookupResult r = retrieveServiceLocked(service, resolvedType,
                 Binder.getCallingPid(), Binder.getCallingUid(),
-                UserHandle.getCallingUserId(), false);
+                UserHandle.getCallingUserId(), false, false);
 
         IBinder ret = null;
         if (r != null) {
@@ -354,11 +501,15 @@
 
             synchronized (r.stats.getBatteryStats()) {
                 r.stats.stopRunningLocked();
-                r.startRequested = false;
-                r.callStart = false;
             }
+            r.startRequested = false;
+            if (r.tracker != null) {
+                r.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
+                        SystemClock.uptimeMillis());
+            }
+            r.callStart = false;
             final long origId = Binder.clearCallingIdentity();
-            bringDownServiceLocked(r, false);
+            bringDownServiceIfNeededLocked(r, false, false);
             Binder.restoreCallingIdentity(origId);
             return true;
         }
@@ -387,6 +538,7 @@
                     if (r.app != null) {
                         updateServiceForegroundLocked(r.app, true);
                     }
+                    getServiceMap(r.userId).ensureNotStartingBackground(r);
                 } else {
                     if (r.isForeground) {
                         r.isForeground = false;
@@ -409,7 +561,8 @@
 
     private void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
         boolean anyForeground = false;
-        for (ServiceRecord sr : proc.services) {
+        for (int i=proc.services.size()-1; i>=0; i--) {
+            ServiceRecord sr = proc.services.valueAt(i);
             if (sr.isForeground) {
                 anyForeground = true;
                 break;
@@ -439,7 +592,7 @@
 
         ActivityRecord activity = null;
         if (token != null) {
-            activity = mAm.mMainStack.isInStackLocked(token);
+            activity = ActivityRecord.isInStackLocked(token);
             if (activity == null) {
                 Slog.w(TAG, "Binding with unknown activity: " + token);
                 return 0;
@@ -469,9 +622,11 @@
             }
         }
 
+        final boolean callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
+
         ServiceLookupResult res =
             retrieveServiceLocked(service, resolvedType,
-                    Binder.getCallingPid(), Binder.getCallingUid(), userId, true);
+                    Binder.getCallingPid(), Binder.getCallingUid(), userId, true, callerFg);
         if (res == null) {
             return 0;
         }
@@ -488,6 +643,18 @@
                         + s);
             }
 
+            if ((flags&Context.BIND_AUTO_CREATE) != 0) {
+                s.lastActivity = SystemClock.uptimeMillis();
+                if (!s.hasAutoCreateConnections()) {
+                    // This is the first binding, let the tracker know.
+                    ProcessStats.ServiceState stracker = s.getTracker();
+                    if (stracker != null) {
+                        stracker.setBound(true, mAm.mProcessStats.getMemFactorLocked(),
+                                s.lastActivity);
+                    }
+                }
+            }
+
             AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
             ConnectionRecord c = new ConnectionRecord(b, activity,
                     connection, flags, clientLabel, clientIntent);
@@ -519,7 +686,7 @@
 
             if ((flags&Context.BIND_AUTO_CREATE) != 0) {
                 s.lastActivity = SystemClock.uptimeMillis();
-                if (bringUpServiceLocked(s, service.getFlags(), false) != null) {
+                if (bringUpServiceLocked(s, service.getFlags(), callerFg, false) != null) {
                     return 0;
                 }
             }
@@ -549,11 +716,14 @@
                 // and the service had previously asked to be told when
                 // rebound, then do so.
                 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
-                    requestServiceBindingLocked(s, b.intent, true);
+                    requestServiceBindingLocked(s, b.intent, callerFg, true);
                 }
             } else if (!b.intent.requested) {
-                requestServiceBindingLocked(s, b.intent, false);
+                requestServiceBindingLocked(s, b.intent, callerFg, false);
             }
+
+            getServiceMap(s.userId).ensureNotStartingBackground(s);
+
         } finally {
             Binder.restoreCallingIdentity(origId);
         }
@@ -574,30 +744,26 @@
                     b.binder = service;
                     b.requested = true;
                     b.received = true;
-                    if (r.connections.size() > 0) {
-                        Iterator<ArrayList<ConnectionRecord>> it
-                                = r.connections.values().iterator();
-                        while (it.hasNext()) {
-                            ArrayList<ConnectionRecord> clist = it.next();
-                            for (int i=0; i<clist.size(); i++) {
-                                ConnectionRecord c = clist.get(i);
-                                if (!filter.equals(c.binding.intent.intent)) {
-                                    if (DEBUG_SERVICE) Slog.v(
-                                            TAG, "Not publishing to: " + c);
-                                    if (DEBUG_SERVICE) Slog.v(
-                                            TAG, "Bound intent: " + c.binding.intent.intent);
-                                    if (DEBUG_SERVICE) Slog.v(
-                                            TAG, "Published intent: " + intent);
-                                    continue;
-                                }
-                                if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
-                                try {
-                                    c.conn.connected(r.name, service);
-                                } catch (Exception e) {
-                                    Slog.w(TAG, "Failure sending service " + r.name +
-                                          " to connection " + c.conn.asBinder() +
-                                          " (in " + c.binding.client.processName + ")", e);
-                                }
+                    for (int conni=r.connections.size()-1; conni>=0; conni--) {
+                        ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
+                        for (int i=0; i<clist.size(); i++) {
+                            ConnectionRecord c = clist.get(i);
+                            if (!filter.equals(c.binding.intent.intent)) {
+                                if (DEBUG_SERVICE) Slog.v(
+                                        TAG, "Not publishing to: " + c);
+                                if (DEBUG_SERVICE) Slog.v(
+                                        TAG, "Bound intent: " + c.binding.intent.intent);
+                                if (DEBUG_SERVICE) Slog.v(
+                                        TAG, "Published intent: " + intent);
+                                continue;
+                            }
+                            if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
+                            try {
+                                c.conn.connected(r.name, service);
+                            } catch (Exception e) {
+                                Slog.w(TAG, "Failure sending service " + r.name +
+                                      " to connection " + c.conn.asBinder() +
+                                      " (in " + c.binding.client.processName + ")", e);
                             }
                         }
                     }
@@ -654,7 +820,16 @@
                     if (b.apps.size() > 0 && !inStopping) {
                         // Applications have already bound since the last
                         // unbind, so just rebind right here.
-                        requestServiceBindingLocked(r, b, true);
+                        boolean inFg = false;
+                        for (int i=b.apps.size()-1; i>=0; i--) {
+                            ProcessRecord client = b.apps.valueAt(i).client;
+                            if (client != null && client.setSchedGroup
+                                    != Process.THREAD_GROUP_BG_NONINTERACTIVE) {
+                                inFg = true;
+                                break;
+                            }
+                        }
+                        requestServiceBindingLocked(r, b, inFg, true);
                     } else {
                         // Note to tell the service the next time there is
                         // a new client.
@@ -671,7 +846,7 @@
 
     private final ServiceRecord findServiceLocked(ComponentName name,
             IBinder token, int userId) {
-        ServiceRecord r = mServiceMap.getServiceByName(name, userId);
+        ServiceRecord r = getServiceByName(name, userId);
         return r == token ? r : null;
     }
 
@@ -701,7 +876,7 @@
 
     private ServiceLookupResult retrieveServiceLocked(Intent service,
             String resolvedType, int callingPid, int callingUid, int userId,
-            boolean createIfNeeded) {
+            boolean createIfNeeded, boolean callingFromFg) {
         ServiceRecord r = null;
         if (DEBUG_SERVICE) Slog.v(TAG, "retrieveServiceLocked: " + service
                 + " type=" + resolvedType + " callingUid=" + callingUid);
@@ -709,12 +884,14 @@
         userId = mAm.handleIncomingUser(callingPid, callingUid, userId,
                 false, true, "service", null);
 
-        if (service.getComponent() != null) {
-            r = mServiceMap.getServiceByName(service.getComponent(), userId);
+        ServiceMap smap = getServiceMap(userId);
+        final ComponentName comp = service.getComponent();
+        if (comp != null) {
+            r = smap.mServicesByName.get(comp);
         }
         if (r == null) {
             Intent.FilterComparison filter = new Intent.FilterComparison(service);
-            r = mServiceMap.getServiceByIntent(filter, userId);
+            r = smap.mServicesByIntent.get(filter);
         }
         if (r == null) {
             try {
@@ -735,14 +912,15 @@
                     if (mAm.isSingleton(sInfo.processName, sInfo.applicationInfo,
                             sInfo.name, sInfo.flags)) {
                         userId = 0;
+                        smap = getServiceMap(0);
                     }
                     sInfo = new ServiceInfo(sInfo);
                     sInfo.applicationInfo = mAm.getAppInfoForUser(sInfo.applicationInfo, userId);
                 }
-                r = mServiceMap.getServiceByName(name, userId);
+                r = smap.mServicesByName.get(name);
                 if (r == null && createIfNeeded) {
-                    Intent.FilterComparison filter = new Intent.FilterComparison(
-                            service.cloneFilter());
+                    Intent.FilterComparison filter
+                            = new Intent.FilterComparison(service.cloneFilter());
                     ServiceRestarter res = new ServiceRestarter();
                     BatteryStatsImpl.Uid.Pkg.Serv ss = null;
                     BatteryStatsImpl stats = mAm.mBatteryStatsService.getActiveStatistics();
@@ -751,10 +929,10 @@
                                 sInfo.applicationInfo.uid, sInfo.packageName,
                                 sInfo.name);
                     }
-                    r = new ServiceRecord(mAm, ss, name, filter, sInfo, res);
+                    r = new ServiceRecord(mAm, ss, name, filter, sInfo, callingFromFg, res);
                     res.setService(r);
-                    mServiceMap.putServiceByName(name, UserHandle.getUserId(r.appInfo.uid), r);
-                    mServiceMap.putServiceByIntent(filter, UserHandle.getUserId(r.appInfo.uid), r);
+                    smap.mServicesByName.put(name, r);
+                    smap.mServicesByIntent.put(filter, r);
 
                     // Make sure this component isn't in the pending list.
                     int N = mPendingServices.size();
@@ -790,40 +968,63 @@
                         + " requires " + r.permission);
                 return new ServiceLookupResult(null, r.permission);
             }
+            if (!mAm.mIntentFirewall.checkService(r.name, service, callingUid, callingPid,
+                    resolvedType, r.appInfo)) {
+                return null;
+            }
             return new ServiceLookupResult(r, null);
         }
         return null;
     }
 
-    private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
-        if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
+    private final void bumpServiceExecutingLocked(ServiceRecord r, boolean fg, String why) {
+        if (DEBUG_SERVICE) Slog.v(TAG, ">>> EXECUTING "
                 + why + " of " + r + " in app " + r.app);
-        else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
+        else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, ">>> EXECUTING "
                 + why + " of " + r.shortName);
         long now = SystemClock.uptimeMillis();
-        if (r.executeNesting == 0 && r.app != null) {
-            if (r.app.executingServices.size() == 0) {
-                Message msg = mAm.mHandler.obtainMessage(
-                        ActivityManagerService.SERVICE_TIMEOUT_MSG);
-                msg.obj = r.app;
-                mAm.mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
+        if (r.executeNesting == 0) {
+            r.executeFg = fg;
+            ProcessStats.ServiceState stracker = r.getTracker();
+            if (stracker != null) {
+                stracker.setExecuting(true, mAm.mProcessStats.getMemFactorLocked(), now);
             }
-            r.app.executingServices.add(r);
+            if (r.app != null) {
+                if (r.app.executingServices.size() == 0) {
+                    Message msg = mAm.mHandler.obtainMessage(
+                            ActivityManagerService.SERVICE_TIMEOUT_MSG);
+                    msg.obj = r.app;
+                    mAm.mHandler.sendMessageAtTime(msg,
+                            fg ? (now+SERVICE_TIMEOUT) : (now+ SERVICE_BACKGROUND_TIMEOUT));
+                }
+                r.app.executingServices.add(r);
+                r.app.execServicesFg |= fg;
+            }
+        } else if (r.app != null && fg && !r.app.execServicesFg) {
+            mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG);
+            Message msg = mAm.mHandler.obtainMessage(
+                    ActivityManagerService.SERVICE_TIMEOUT_MSG);
+            msg.obj = r.app;
+            mAm.mHandler.sendMessageAtTime(msg,now+SERVICE_TIMEOUT);
+            r.app.execServicesFg = true;
         }
+        r.executeFg |= fg;
         r.executeNesting++;
         r.executingStart = now;
     }
 
     private final boolean requestServiceBindingLocked(ServiceRecord r,
-            IntentBindRecord i, boolean rebind) {
+            IntentBindRecord i, boolean execInFg, boolean rebind) {
         if (r.app == null || r.app.thread == null) {
             // If service is not currently running, can't yet bind.
             return false;
         }
         if ((!i.requested || rebind) && i.apps.size() > 0) {
             try {
-                bumpServiceExecutingLocked(r, "bind");
-                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
+                bumpServiceExecutingLocked(r, execInFg, "bind");
+                r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
+                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
+                        r.app.repProcState);
                 if (!rebind) {
                     i.requested = true;
                 }
@@ -932,6 +1133,7 @@
         }
 
         if (!mRestartingServices.contains(r)) {
+            r.createdFromFg = false;
             mRestartingServices.add(r);
         }
 
@@ -952,7 +1154,7 @@
         if (!mRestartingServices.contains(r)) {
             return;
         }
-        bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
+        bringUpServiceLocked(r, r.intent.getIntent().getFlags(), r.createdFromFg, true);
     }
 
     private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
@@ -966,12 +1168,12 @@
     }
 
     private final String bringUpServiceLocked(ServiceRecord r,
-            int intentFlags, boolean whileRestarting) {
+            int intentFlags, boolean execInFg, boolean whileRestarting) {
         //Slog.i(TAG, "Bring up service:");
         //r.dump("  ");
 
         if (r.app != null && r.app.thread != null) {
-            sendServiceArgsLocked(r, false);
+            sendServiceArgsLocked(r, execInFg, false);
             return null;
         }
 
@@ -986,6 +1188,13 @@
         // restarting state.
         mRestartingServices.remove(r);
 
+        // Make sure this service is no longer considered delayed, we are starting it now.
+        if (r.delayed) {
+            if (DEBUG_DELAYED_STATS) Slog.v(TAG, "REM FR DELAY LIST (bring up): " + r);
+            getServiceMap(r.userId).mDelayedStartList.remove(r);
+            r.delayed = false;
+        }
+
         // Make sure that the user who owns this service is started.  If not,
         // we don't want to allow it to run.
         if (mAm.mStartedUsers.get(r.userId) == null) {
@@ -994,7 +1203,7 @@
                     + r.appInfo.uid + " for service "
                     + r.intent.getIntent() + ": user " + r.userId + " is stopped";
             Slog.w(TAG, msg);
-            bringDownServiceLocked(r, true);
+            bringDownServiceLocked(r);
             return msg;
         }
 
@@ -1018,8 +1227,8 @@
                 Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid + " app=" + app);
             if (app != null && app.thread != null) {
                 try {
-                    app.addPackage(r.appInfo.packageName);
-                    realStartServiceLocked(r, app);
+                    app.addPackage(r.appInfo.packageName, mAm.mProcessStats);
+                    realStartServiceLocked(r, app, execInFg);
                     return null;
                 } catch (RemoteException e) {
                     Slog.w(TAG, "Exception when starting service " + r.shortName, e);
@@ -1048,7 +1257,7 @@
                         + r.appInfo.uid + " for service "
                         + r.intent.getIntent() + ": process is bad";
                 Slog.w(TAG, msg);
-                bringDownServiceLocked(r, true);
+                bringDownServiceLocked(r);
                 return msg;
             }
             if (isolated) {
@@ -1060,21 +1269,29 @@
             mPendingServices.add(r);
         }
 
+        if (r.delayedStop) {
+            // Oh and hey we've already been asked to stop!
+            r.delayedStop = false;
+            if (r.startRequested) {
+                if (DEBUG_DELAYED_STATS) Slog.v(TAG, "Applying delayed stop (in bring up): " + r);
+                stopServiceLocked(r);
+            }
+        }
+
         return null;
     }
 
-    private final void requestServiceBindingsLocked(ServiceRecord r) {
-        Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
-        while (bindings.hasNext()) {
-            IntentBindRecord i = bindings.next();
-            if (!requestServiceBindingLocked(r, i, false)) {
+    private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg) {
+        for (int i=r.bindings.size()-1; i>=0; i--) {
+            IntentBindRecord ibr = r.bindings.valueAt(i);
+            if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {
                 break;
             }
         }
     }
 
     private final void realStartServiceLocked(ServiceRecord r,
-            ProcessRecord app) throws RemoteException {
+            ProcessRecord app, boolean execInFg) throws RemoteException {
         if (app.thread == null) {
             throw new RemoteException();
         }
@@ -1085,19 +1302,24 @@
         r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
 
         app.services.add(r);
-        bumpServiceExecutingLocked(r, "create");
+        bumpServiceExecutingLocked(r, execInFg, "create");
         mAm.updateLruProcessLocked(app, true);
 
         boolean created = false;
         try {
+            String nameTerm;
+            int lastPeriod = r.shortName.lastIndexOf('.');
+            nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName;
             EventLogTags.writeAmCreateService(
-                    r.userId, System.identityHashCode(r), r.shortName, r.app.pid);
+                    r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid);
             synchronized (r.stats.getBatteryStats()) {
                 r.stats.startLaunchedLocked();
             }
             mAm.ensurePackageDexOpt(r.serviceInfo.packageName);
+            app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
             app.thread.scheduleCreateService(r, r.serviceInfo,
-                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
+                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
+                    app.repProcState);
             r.postNotification();
             created = true;
         } finally {
@@ -1107,7 +1329,7 @@
             }
         }
 
-        requestServiceBindingsLocked(r);
+        requestServiceBindingsLocked(r, execInFg);
 
         // If the service is in the started state, and there are no
         // pending arguments, then fake up one so its onStartCommand() will
@@ -1117,10 +1339,25 @@
                     null, null));
         }
 
-        sendServiceArgsLocked(r, true);
+        sendServiceArgsLocked(r, execInFg, true);
+
+        if (r.delayed) {
+            if (DEBUG_DELAYED_STATS) Slog.v(TAG, "REM FR DELAY LIST (new proc): " + r);
+            getServiceMap(r.userId).mDelayedStartList.remove(r);
+            r.delayed = false;
+        }
+
+        if (r.delayedStop) {
+            // Oh and hey we've already been asked to stop!
+            r.delayedStop = false;
+            if (r.startRequested) {
+                if (DEBUG_DELAYED_STATS) Slog.v(TAG, "Applying delayed stop (from start): " + r);
+                stopServiceLocked(r);
+            }
+        }
     }
 
-    private final void sendServiceArgsLocked(ServiceRecord r,
+    private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
             boolean oomAdjusted) {
         final int N = r.pendingStarts.size();
         if (N == 0) {
@@ -1146,7 +1383,7 @@
                     mAm.grantUriPermissionUncheckedFromIntentLocked(si.neededGrants,
                             si.getUriPermissionsLocked());
                 }
-                bumpServiceExecutingLocked(r, "start");
+                bumpServiceExecutingLocked(r, execInFg, "start");
                 if (!oomAdjusted) {
                     oomAdjusted = true;
                     mAm.updateOomAdjLocked(r.app);
@@ -1171,60 +1408,64 @@
         }
     }
 
-    private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
+    private final void bringDownServiceIfNeededLocked(ServiceRecord r, boolean knowConn,
+            boolean hasConn) {
         //Slog.i(TAG, "Bring down service:");
         //r.dump("  ");
 
-        // Does it still need to run?
-        if (!force && r.startRequested) {
+        // Are we still explicitly being asked to run?
+        if (r.startRequested) {
             return;
         }
-        if (r.connections.size() > 0) {
-            if (!force) {
-                // XXX should probably keep a count of the number of auto-create
-                // connections directly in the service.
-                Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
-                while (it.hasNext()) {
-                    ArrayList<ConnectionRecord> cr = it.next();
-                    for (int i=0; i<cr.size(); i++) {
-                        if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
-                            return;
-                        }
-                    }
-                }
-            }
 
-            // Report to all of the connections that the service is no longer
-            // available.
-            Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
-            while (it.hasNext()) {
-                ArrayList<ConnectionRecord> c = it.next();
-                for (int i=0; i<c.size(); i++) {
-                    ConnectionRecord cr = c.get(i);
-                    // There is still a connection to the service that is
-                    // being brought down.  Mark it as dead.
-                    cr.serviceDead = true;
-                    try {
-                        cr.conn.connected(r.name, null);
-                    } catch (Exception e) {
-                        Slog.w(TAG, "Failure disconnecting service " + r.name +
-                              " to connection " + c.get(i).conn.asBinder() +
-                              " (in " + c.get(i).binding.client.processName + ")", e);
-                    }
+        // Is someone still bound to us keepign us running?
+        if (!knowConn) {
+            hasConn = r.hasAutoCreateConnections();
+        }
+        if (hasConn) {
+            return;
+        }
+
+        // Are we in the process of launching?
+        if (mPendingServices.contains(r)) {
+            return;
+        }
+
+        bringDownServiceLocked(r);
+    }
+
+    private final void bringDownServiceLocked(ServiceRecord r) {
+        //Slog.i(TAG, "Bring down service:");
+        //r.dump("  ");
+
+        // Report to all of the connections that the service is no longer
+        // available.
+        for (int conni=r.connections.size()-1; conni>=0; conni--) {
+            ArrayList<ConnectionRecord> c = r.connections.valueAt(conni);
+            for (int i=0; i<c.size(); i++) {
+                ConnectionRecord cr = c.get(i);
+                // There is still a connection to the service that is
+                // being brought down.  Mark it as dead.
+                cr.serviceDead = true;
+                try {
+                    cr.conn.connected(r.name, null);
+                } catch (Exception e) {
+                    Slog.w(TAG, "Failure disconnecting service " + r.name +
+                          " to connection " + c.get(i).conn.asBinder() +
+                          " (in " + c.get(i).binding.client.processName + ")", e);
                 }
             }
         }
 
         // Tell the service that it has been unbound.
-        if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
-            Iterator<IntentBindRecord> it = r.bindings.values().iterator();
-            while (it.hasNext()) {
-                IntentBindRecord ibr = it.next();
+        if (r.app != null && r.app.thread != null) {
+            for (int i=r.bindings.size()-1; i>=0; i--) {
+                IntentBindRecord ibr = r.bindings.valueAt(i);
                 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
                         + ": hasBound=" + ibr.hasBound);
-                if (r.app != null && r.app.thread != null && ibr.hasBound) {
+                if (ibr.hasBound) {
                     try {
-                        bumpServiceExecutingLocked(r, "bring down unbind");
+                        bumpServiceExecutingLocked(r, false, "bring down unbind");
                         mAm.updateOomAdjLocked(r.app);
                         ibr.hasBound = false;
                         r.app.thread.scheduleUnbindService(r,
@@ -1242,8 +1483,9 @@
         EventLogTags.writeAmDestroyService(
                 r.userId, System.identityHashCode(r), (r.app != null) ? r.app.pid : -1);
 
-        mServiceMap.removeServiceByName(r.name, r.userId);
-        mServiceMap.removeServiceByIntent(r.intent, r.userId);
+        final ServiceMap smap = getServiceMap(r.userId);
+        smap.mServicesByName.remove(r.name);
+        smap.mServicesByIntent.remove(r.intent);
         r.totalRestartCount = 0;
         unscheduleServiceRestartLocked(r);
 
@@ -1274,7 +1516,7 @@
             r.app.services.remove(r);
             if (r.app.thread != null) {
                 try {
-                    bumpServiceExecutingLocked(r, "stop");
+                    bumpServiceExecutingLocked(r, false, "stop");
                     mStoppingServices.add(r);
                     mAm.updateOomAdjLocked(r.app);
                     r.app.thread.scheduleStopService(r);
@@ -1300,6 +1542,19 @@
         if (r.restarter instanceof ServiceRestarter) {
            ((ServiceRestarter)r.restarter).setService(null);
         }
+
+        int memFactor = mAm.mProcessStats.getMemFactorLocked();
+        long now = SystemClock.uptimeMillis();
+        if (r.tracker != null) {
+            r.tracker.setStarted(false, memFactor, now);
+            r.tracker.setBound(false, memFactor, now);
+            if (r.executeNesting == 0) {
+                r.tracker.makeInactive();
+                r.tracker = null;
+            }
+        }
+
+        smap.ensureNotStartingBackground(r);
     }
 
     void removeConnectionLocked(
@@ -1344,7 +1599,7 @@
             if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
                     && b.intent.hasBound) {
                 try {
-                    bumpServiceExecutingLocked(s, "unbind");
+                    bumpServiceExecutingLocked(s, false, "unbind");
                     mAm.updateOomAdjLocked(s.app);
                     b.intent.hasBound = false;
                     // Assume the client doesn't want to know about a rebind;
@@ -1358,7 +1613,14 @@
             }
 
             if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
-                bringDownServiceLocked(s, false);
+                boolean hasAutoCreate = s.hasAutoCreateConnections();
+                if (!hasAutoCreate) {
+                    if (s.tracker != null) {
+                        s.tracker.setBound(false, mAm.mProcessStats.getMemFactorLocked(),
+                                SystemClock.uptimeMillis());
+                    }
+                }
+                bringDownServiceIfNeededLocked(s, true, hasAutoCreate);
             }
         }
     }
@@ -1431,22 +1693,42 @@
                 + ", inStopping=" + inStopping + ", app=" + r.app);
         else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
         r.executeNesting--;
-        if (r.executeNesting <= 0 && r.app != null) {
-            if (DEBUG_SERVICE) Slog.v(TAG,
-                    "Nesting at 0 of " + r.shortName);
-            r.app.executingServices.remove(r);
-            if (r.app.executingServices.size() == 0) {
-                if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
-                        "No more executingServices of " + r.shortName);
-                mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);
-            }
-            if (inStopping) {
+        if (r.executeNesting <= 0) {
+            if (r.app != null) {
                 if (DEBUG_SERVICE) Slog.v(TAG,
-                        "doneExecuting remove stopping " + r);
-                mStoppingServices.remove(r);
-                r.bindings.clear();
+                        "Nesting at 0 of " + r.shortName);
+                r.app.execServicesFg = false;
+                r.app.executingServices.remove(r);
+                if (r.app.executingServices.size() == 0) {
+                    if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
+                            "No more executingServices of " + r.shortName);
+                    mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);
+                } else if (r.executeFg) {
+                    // Need to re-evaluate whether the app still needs to be in the foreground.
+                    for (int i=r.app.executingServices.size()-1; i>=0; i--) {
+                        if (r.app.executingServices.valueAt(i).executeFg) {
+                            r.app.execServicesFg = true;
+                            break;
+                        }
+                    }
+                }
+                if (inStopping) {
+                    if (DEBUG_SERVICE) Slog.v(TAG,
+                            "doneExecuting remove stopping " + r);
+                    mStoppingServices.remove(r);
+                    r.bindings.clear();
+                }
+                mAm.updateOomAdjLocked(r.app);
             }
-            mAm.updateOomAdjLocked(r.app);
+            r.executeFg = false;
+            if (r.tracker != null) {
+                r.tracker.setExecuting(false, mAm.mProcessStats.getMemFactorLocked(),
+                        SystemClock.uptimeMillis());
+                if (inStopping) {
+                    r.tracker.makeInactive();
+                    r.tracker = null;
+                }
+            }
         }
     }
 
@@ -1465,7 +1747,8 @@
 
                     mPendingServices.remove(i);
                     i--;
-                    realStartServiceLocked(sr, proc);
+                    proc.addPackage(sr.appInfo.packageName, mAm.mProcessStats);
+                    realStartServiceLocked(sr, proc, sr.createdFromFg);
                     didSomething = true;
                 }
             } catch (Exception e) {
@@ -1503,17 +1786,18 @@
                 sr.isolatedProc = null;
                 mPendingServices.remove(i);
                 i--;
-                bringDownServiceLocked(sr, true);
+                bringDownServiceLocked(sr);
             }
         }
     }
 
     private boolean collectForceStopServicesLocked(String name, int userId,
             boolean evenPersistent, boolean doit,
-            HashMap<ComponentName, ServiceRecord> services,
+            ArrayMap<ComponentName, ServiceRecord> services,
             ArrayList<ServiceRecord> result) {
         boolean didSomething = false;
-        for (ServiceRecord service : services.values()) {
+        for (int i=0; i<services.size(); i++) {
+            ServiceRecord service = services.valueAt(i);
             if ((name == null || service.packageName.equals(name))
                     && (service.app == null || evenPersistent || !service.app.persistent)) {
                 if (!doit) {
@@ -1536,17 +1820,17 @@
         boolean didSomething = false;
         ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
         if (userId == UserHandle.USER_ALL) {
-            for (int i=0; i<mServiceMap.mServicesByNamePerUser.size(); i++) {
+            for (int i=0; i<mServiceMap.size(); i++) {
                 didSomething |= collectForceStopServicesLocked(name, userId, evenPersistent,
-                        doit, mServiceMap.mServicesByNamePerUser.valueAt(i), services);
+                        doit, mServiceMap.valueAt(i).mServicesByName, services);
                 if (!doit && didSomething) {
                     return true;
                 }
             }
         } else {
-            HashMap<ComponentName, ServiceRecord> items
-                    = mServiceMap.mServicesByNamePerUser.get(userId);
-            if (items != null) {
+            ServiceMap smap = mServiceMap.valueAt(userId);
+            if (smap != null) {
+                ArrayMap<ComponentName, ServiceRecord> items = smap.mServicesByName;
                 didSomething = collectForceStopServicesLocked(name, userId, evenPersistent,
                         doit, items, services);
             }
@@ -1554,14 +1838,16 @@
 
         int N = services.size();
         for (int i=0; i<N; i++) {
-            bringDownServiceLocked(services.get(i), true);
+            bringDownServiceLocked(services.get(i));
         }
         return didSomething;
     }
 
     void cleanUpRemovedTaskLocked(TaskRecord tr, ComponentName component, Intent baseIntent) {
         ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
-        for (ServiceRecord sr : mServiceMap.getAllServices(tr.userId)) {
+        ArrayMap<ComponentName, ServiceRecord> alls = getServices(tr.userId);
+        for (int i=0; i<alls.size(); i++) {
+            ServiceRecord sr = alls.valueAt(i);
             if (sr.packageName.equals(component.getPackageName())) {
                 services.add(sr);
             }
@@ -1578,7 +1864,9 @@
                     sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
                             sr.makeNextStartId(), baseIntent, null));
                     if (sr.app != null && sr.app.thread != null) {
-                        sendServiceArgsLocked(sr, false);
+                        // We always run in the foreground, since this is called as
+                        // part of the "remove task" UI operation.
+                        sendServiceArgsLocked(sr, true, false);
                     }
                 }
             }
@@ -1595,22 +1883,18 @@
                 Iterator<ServiceRecord> it = app.services.iterator();
                 while (it.hasNext()) {
                     ServiceRecord r = it.next();
-                    if (r.connections.size() > 0) {
-                        Iterator<ArrayList<ConnectionRecord>> jt
-                                = r.connections.values().iterator();
-                        while (jt.hasNext()) {
-                            ArrayList<ConnectionRecord> cl = jt.next();
-                            for (int i=0; i<cl.size(); i++) {
-                                ConnectionRecord c = cl.get(i);
-                                if (c.binding.client != app) {
-                                    try {
-                                        //c.conn.connected(r.className, null);
-                                    } catch (Exception e) {
-                                        // todo: this should be asynchronous!
-                                        Slog.w(TAG, "Exception thrown disconnected servce "
-                                              + r.shortName
-                                              + " from app " + app.processName, e);
-                                    }
+                    for (int conni=r.connections.size()-1; conni>=0; conni--) {
+                        ArrayList<ConnectionRecord> cl = r.connections.valueAt(conni);
+                        for (int i=0; i<cl.size(); i++) {
+                            ConnectionRecord c = cl.get(i);
+                            if (c.binding.client != app) {
+                                try {
+                                    //c.conn.connected(r.className, null);
+                                } catch (Exception e) {
+                                    // todo: this should be asynchronous!
+                                    Slog.w(TAG, "Exception thrown disconnected servce "
+                                          + r.shortName
+                                          + " from app " + app.processName, e);
                                 }
                             }
                         }
@@ -1620,74 +1904,72 @@
         }
 
         // Clean up any connections this application has to other services.
-        if (app.connections.size() > 0) {
-            Iterator<ConnectionRecord> it = app.connections.iterator();
-            while (it.hasNext()) {
-                ConnectionRecord r = it.next();
-                removeConnectionLocked(r, app, null);
-            }
+        for (int i=app.connections.size()-1; i>=0; i--) {
+            ConnectionRecord r = app.connections.valueAt(i);
+            removeConnectionLocked(r, app, null);
         }
         app.connections.clear();
 
-        if (app.services.size() != 0) {
+        for (int i=app.services.size()-1; i>=0; i--) {
             // Any services running in the application need to be placed
             // back in the pending list.
-            Iterator<ServiceRecord> it = app.services.iterator();
-            while (it.hasNext()) {
-                ServiceRecord sr = it.next();
-                synchronized (sr.stats.getBatteryStats()) {
-                    sr.stats.stopLaunchedLocked();
-                }
-                sr.app = null;
-                sr.isolatedProc = null;
-                sr.executeNesting = 0;
-                if (mStoppingServices.remove(sr)) {
-                    if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
-                }
+            ServiceRecord sr = app.services.valueAt(i);
+            synchronized (sr.stats.getBatteryStats()) {
+                sr.stats.stopLaunchedLocked();
+            }
+            sr.app = null;
+            sr.isolatedProc = null;
+            sr.executeNesting = 0;
+            if (sr.tracker != null) {
+                sr.tracker.setExecuting(false, mAm.mProcessStats.getMemFactorLocked(),
+                        SystemClock.uptimeMillis());
+            }
+            if (mStoppingServices.remove(sr)) {
+                if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
+            }
 
-                boolean hasClients = sr.bindings.size() > 0;
-                if (hasClients) {
-                    Iterator<IntentBindRecord> bindings
-                            = sr.bindings.values().iterator();
-                    while (bindings.hasNext()) {
-                        IntentBindRecord b = bindings.next();
-                        if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
-                                + ": shouldUnbind=" + b.hasBound);
-                        b.binder = null;
-                        b.requested = b.received = b.hasBound = false;
-                    }
-                }
+            final int numClients = sr.bindings.size();
+            for (int bindingi=numClients-1; bindingi>=0; bindingi--) {
+                IntentBindRecord b = sr.bindings.valueAt(bindingi);
+                if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
+                        + ": shouldUnbind=" + b.hasBound);
+                b.binder = null;
+                b.requested = b.received = b.hasBound = false;
+            }
 
-                if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
-                        &ApplicationInfo.FLAG_PERSISTENT) == 0) {
-                    Slog.w(TAG, "Service crashed " + sr.crashCount
-                            + " times, stopping: " + sr);
-                    EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
-                            sr.userId, sr.crashCount, sr.shortName, app.pid);
-                    bringDownServiceLocked(sr, true);
-                } else if (!allowRestart) {
-                    bringDownServiceLocked(sr, true);
-                } else {
-                    boolean canceled = scheduleServiceRestartLocked(sr, true);
+            if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
+                    &ApplicationInfo.FLAG_PERSISTENT) == 0) {
+                Slog.w(TAG, "Service crashed " + sr.crashCount
+                        + " times, stopping: " + sr);
+                EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
+                        sr.userId, sr.crashCount, sr.shortName, app.pid);
+                bringDownServiceLocked(sr);
+            } else if (!allowRestart) {
+                bringDownServiceLocked(sr);
+            } else {
+                boolean canceled = scheduleServiceRestartLocked(sr, true);
 
-                    // Should the service remain running?  Note that in the
-                    // extreme case of so many attempts to deliver a command
-                    // that it failed we also will stop it here.
-                    if (sr.startRequested && (sr.stopIfKilled || canceled)) {
-                        if (sr.pendingStarts.size() == 0) {
-                            sr.startRequested = false;
-                            if (!hasClients) {
-                                // Whoops, no reason to restart!
-                                bringDownServiceLocked(sr, true);
-                            }
+                // Should the service remain running?  Note that in the
+                // extreme case of so many attempts to deliver a command
+                // that it failed we also will stop it here.
+                if (sr.startRequested && (sr.stopIfKilled || canceled)) {
+                    if (sr.pendingStarts.size() == 0) {
+                        sr.startRequested = false;
+                        if (sr.tracker != null) {
+                            sr.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
+                                    SystemClock.uptimeMillis());
+                        }
+                        if (!sr.hasAutoCreateConnections()) {
+                            // Whoops, no reason to restart!
+                            bringDownServiceLocked(sr);
                         }
                     }
                 }
             }
+        }
 
-            if (!allowRestart) {
-                app.services.clear();
-            }
+        if (!allowRestart) {
+            app.services.clear();
         }
 
         // Make sure we have no more records on the stopping list.
@@ -1732,7 +2014,8 @@
             info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
         }
 
-        for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
+        for (int conni=r.connections.size()-1; conni>=0; conni--) {
+            ArrayList<ConnectionRecord> connl = r.connections.valueAt(conni);
             for (int i=0; i<connl.size(); i++) {
                 ConnectionRecord conn = connl.get(i);
                 if (conn.clientLabel != 0) {
@@ -1758,12 +2041,10 @@
                     uid) == PackageManager.PERMISSION_GRANTED) {
                 int[] users = mAm.getUsersLocked();
                 for (int ui=0; ui<users.length && res.size() < maxNum; ui++) {
-                    if (mServiceMap.getAllServices(users[ui]).size() > 0) {
-                        Iterator<ServiceRecord> it = mServiceMap.getAllServices(
-                                users[ui]).iterator();
-                        while (it.hasNext() && res.size() < maxNum) {
-                            res.add(makeRunningServiceInfoLocked(it.next()));
-                        }
+                    ArrayMap<ComponentName, ServiceRecord> alls = getServices(users[ui]);
+                    for (int i=0; i<alls.size() && res.size() < maxNum; i++) {
+                        ServiceRecord sr = alls.valueAt(i);
+                        res.add(makeRunningServiceInfoLocked(sr));
                     }
                 }
 
@@ -1776,12 +2057,10 @@
                 }
             } else {
                 int userId = UserHandle.getUserId(uid);
-                if (mServiceMap.getAllServices(userId).size() > 0) {
-                    Iterator<ServiceRecord> it
-                            = mServiceMap.getAllServices(userId).iterator();
-                    while (it.hasNext() && res.size() < maxNum) {
-                        res.add(makeRunningServiceInfoLocked(it.next()));
-                    }
+                ArrayMap<ComponentName, ServiceRecord> alls = getServices(userId);
+                for (int i=0; i<alls.size() && res.size() < maxNum; i++) {
+                    ServiceRecord sr = alls.valueAt(i);
+                    res.add(makeRunningServiceInfoLocked(sr));
                 }
 
                 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
@@ -1803,9 +2082,10 @@
 
     public PendingIntent getRunningServiceControlPanelLocked(ComponentName name) {
         int userId = UserHandle.getUserId(Binder.getCallingUid());
-        ServiceRecord r = mServiceMap.getServiceByName(name, userId);
+        ServiceRecord r = getServiceByName(name, userId);
         if (r != null) {
-            for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
+            for (int conni=r.connections.size()-1; conni>=0; conni--) {
+                ArrayList<ConnectionRecord> conn = r.connections.valueAt(conni);
                 for (int i=0; i<conn.size(); i++) {
                     if (conn.get(i).clientIntent != null) {
                         return conn.get(i).clientIntent;
@@ -1823,12 +2103,12 @@
             if (proc.executingServices.size() == 0 || proc.thread == null) {
                 return;
             }
-            long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
-            Iterator<ServiceRecord> it = proc.executingServices.iterator();
+            long maxTime = SystemClock.uptimeMillis() -
+                    (proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
             ServiceRecord timeout = null;
             long nextTime = 0;
-            while (it.hasNext()) {
-                ServiceRecord sr = it.next();
+            for (int i=proc.executingServices.size()-1; i>=0; i--) {
+                ServiceRecord sr = proc.executingServices.valueAt(i);
                 if (sr.executingStart < maxTime) {
                     timeout = sr;
                     break;
@@ -1844,7 +2124,8 @@
                 Message msg = mAm.mHandler.obtainMessage(
                         ActivityManagerService.SERVICE_TIMEOUT_MSG);
                 msg.obj = proc;
-                mAm.mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
+                mAm.mHandler.sendMessageAtTime(msg, proc.execServicesFg
+                        ? (nextTime+SERVICE_TIMEOUT) : (nextTime+ SERVICE_BACKGROUND_TIMEOUT));
             }
         }
 
@@ -1856,9 +2137,10 @@
     /**
      * Prints a list of ServiceRecords (dumpsys activity services)
      */
-    boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
+    void dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
         boolean needSep = false;
+        boolean printedAnything = false;
 
         ItemMatcher matcher = new ItemMatcher();
         matcher.build(args, opti);
@@ -1867,14 +2149,13 @@
         try {
             int[] users = mAm.getUsersLocked();
             for (int user : users) {
-                if (mServiceMap.getAllServices(user).size() > 0) {
-                    boolean printed = false;
+                ServiceMap smap = getServiceMap(user);
+                boolean printed = false;
+                if (smap.mServicesByName.size() > 0) {
                     long nowReal = SystemClock.elapsedRealtime();
-                    Iterator<ServiceRecord> it = mServiceMap.getAllServices(
-                            user).iterator();
                     needSep = false;
-                    while (it.hasNext()) {
-                        ServiceRecord r = it.next();
+                    for (int si=0; si<smap.mServicesByName.size(); si++) {
+                        ServiceRecord r = smap.mServicesByName.valueAt(si);
                         if (!matcher.match(r, r.name)) {
                             continue;
                         }
@@ -1882,12 +2163,13 @@
                             continue;
                         }
                         if (!printed) {
-                            if (user != 0) {
+                            if (printedAnything) {
                                 pw.println();
                             }
                             pw.println("  User " + user + " active services:");
                             printed = true;
                         }
+                        printedAnything = true;
                         if (needSep) {
                             pw.println();
                         }
@@ -1907,7 +2189,8 @@
                             pw.println(r.connections.size());
                             if (r.connections.size() > 0) {
                                 pw.println("    Connections:");
-                                for (ArrayList<ConnectionRecord> clist : r.connections.values()) {
+                                for (int conni=0; conni<r.connections.size(); conni++) {
+                                    ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
                                     for (int i = 0; i < clist.size(); i++) {
                                         ConnectionRecord conn = clist.get(i);
                                         pw.print("      ");
@@ -1943,11 +2226,49 @@
                             needSep = true;
                         }
                     }
-                    needSep = printed;
+                    needSep |= printed;
+                }
+                printed = false;
+                for (int si=0, SN=smap.mDelayedStartList.size(); si<SN; si++) {
+                    ServiceRecord r = smap.mDelayedStartList.get(si);
+                    if (!matcher.match(r, r.name)) {
+                        continue;
+                    }
+                    if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
+                        continue;
+                    }
+                    if (!printed) {
+                        if (printedAnything) {
+                            pw.println();
+                        }
+                        pw.println("  User " + user + " delayed start services:");
+                        printed = true;
+                    }
+                    printedAnything = true;
+                    pw.print("  * Delayed start "); pw.println(r);
+                }
+                printed = false;
+                for (int si=0, SN=smap.mStartingBackground.size(); si<SN; si++) {
+                    ServiceRecord r = smap.mStartingBackground.get(si);
+                    if (!matcher.match(r, r.name)) {
+                        continue;
+                    }
+                    if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
+                        continue;
+                    }
+                    if (!printed) {
+                        if (printedAnything) {
+                            pw.println();
+                        }
+                        pw.println("  User " + user + " starting in background:");
+                        printed = true;
+                    }
+                    printedAnything = true;
+                    pw.print("  * Starting bg "); pw.println(r);
                 }
             }
         } catch (Exception e) {
-            Log.w(TAG, "Exception in dumpServicesLocked: " + e);
+            Slog.w(TAG, "Exception in dumpServicesLocked", e);
         }
 
         if (mPendingServices.size() > 0) {
@@ -1960,8 +2281,9 @@
                 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
                     continue;
                 }
+                printedAnything = true;
                 if (!printed) {
-                    if (needSep) pw.println(" ");
+                    if (needSep) pw.println();
                     needSep = true;
                     pw.println("  Pending services:");
                     printed = true;
@@ -1982,8 +2304,9 @@
                 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
                     continue;
                 }
+                printedAnything = true;
                 if (!printed) {
-                    if (needSep) pw.println(" ");
+                    if (needSep) pw.println();
                     needSep = true;
                     pw.println("  Restarting services:");
                     printed = true;
@@ -2004,8 +2327,9 @@
                 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
                     continue;
                 }
+                printedAnything = true;
                 if (!printed) {
-                    if (needSep) pw.println(" ");
+                    if (needSep) pw.println();
                     needSep = true;
                     pw.println("  Stopping services:");
                     printed = true;
@@ -2017,36 +2341,34 @@
         }
 
         if (dumpAll) {
-            if (mServiceConnections.size() > 0) {
-                boolean printed = false;
-                Iterator<ArrayList<ConnectionRecord>> it
-                        = mServiceConnections.values().iterator();
-                while (it.hasNext()) {
-                    ArrayList<ConnectionRecord> r = it.next();
-                    for (int i=0; i<r.size(); i++) {
-                        ConnectionRecord cr = r.get(i);
-                        if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
-                            continue;
-                        }
-                        if (dumpPackage != null && (cr.binding.client == null
-                                || !dumpPackage.equals(cr.binding.client.info.packageName))) {
-                            continue;
-                        }
-                        if (!printed) {
-                            if (needSep) pw.println(" ");
-                            needSep = true;
-                            pw.println("  Connection bindings to services:");
-                            printed = true;
-                        }
-                        pw.print("  * "); pw.println(cr);
-                        cr.dump(pw, "    ");
+            boolean printed = false;
+            for (int ic=0; ic<mServiceConnections.size(); ic++) {
+                ArrayList<ConnectionRecord> r = mServiceConnections.valueAt(ic);
+                for (int i=0; i<r.size(); i++) {
+                    ConnectionRecord cr = r.get(i);
+                    if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
+                        continue;
                     }
+                    if (dumpPackage != null && (cr.binding.client == null
+                            || !dumpPackage.equals(cr.binding.client.info.packageName))) {
+                        continue;
+                    }
+                    printedAnything = true;
+                    if (!printed) {
+                        if (needSep) pw.println();
+                        needSep = true;
+                        pw.println("  Connection bindings to services:");
+                        printed = true;
+                    }
+                    pw.print("  * "); pw.println(cr);
+                    cr.dump(pw, "    ");
                 }
-                needSep = true;
             }
         }
 
-        return needSep;
+        if (!printedAnything) {
+            pw.println("  (nothing)");
+        }
     }
 
     /**
@@ -2065,7 +2387,9 @@
             int[] users = mAm.getUsersLocked();
             if ("all".equals(name)) {
                 for (int user : users) {
-                    for (ServiceRecord r1 : mServiceMap.getAllServices(user)) {
+                    ArrayMap<ComponentName, ServiceRecord> alls = getServices(user);
+                    for (int i=0; i<alls.size(); i++) {
+                        ServiceRecord r1 = alls.valueAt(i);
                         services.add(r1);
                     }
                 }
@@ -2084,7 +2408,9 @@
                 }
 
                 for (int user : users) {
-                    for (ServiceRecord r1 : mServiceMap.getAllServices(user)) {
+                    ArrayMap<ComponentName, ServiceRecord> alls = getServices(user);
+                    for (int i=0; i<alls.size(); i++) {
+                        ServiceRecord r1 = alls.valueAt(i);
                         if (componentName != null) {
                             if (r1.name.equals(componentName)) {
                                 services.add(r1);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index db01655..e208f10 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -17,28 +17,58 @@
 package com.android.server.am;
 
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static com.android.internal.util.XmlUtils.readIntAttribute;
+import static com.android.internal.util.XmlUtils.writeIntAttribute;
+import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
+import static org.xmlpull.v1.XmlPullParser.START_TAG;
+import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
 
 import android.app.AppOpsManager;
 import android.appwidget.AppWidgetManager;
+import android.util.ArrayMap;
+
 import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.app.IAppOpsService;
+import com.android.internal.app.ProcessStats;
+import com.android.internal.app.ResolverActivity;
+import com.android.internal.os.BackgroundThread;
 import com.android.internal.os.BatteryStatsImpl;
-import com.android.internal.os.ProcessStats;
+import com.android.internal.os.ProcessCpuTracker;
+import com.android.internal.os.TransferPipe;
+import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.FastPrintWriter;
+import com.android.internal.util.FastXmlSerializer;
+import com.android.internal.util.MemInfoReader;
 import com.android.server.AppOpsService;
 import com.android.server.AttributeCache;
 import com.android.server.IntentResolver;
-import com.android.server.ProcessMap;
+import com.android.internal.app.ProcessMap;
 import com.android.server.SystemServer;
 import com.android.server.Watchdog;
 import com.android.server.am.ActivityStack.ActivityState;
 import com.android.server.firewall.IntentFirewall;
 import com.android.server.pm.UserManagerService;
 import com.android.server.wm.AppTransition;
+import com.android.server.wm.StackBox;
 import com.android.server.wm.WindowManagerService;
 
+import com.google.android.collect.Lists;
+import com.google.android.collect.Maps;
+
 import dalvik.system.Zygote;
 
+import libcore.io.IoUtils;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
 import android.app.Activity;
 import android.app.ActivityManager;
+import android.app.ActivityManager.RunningTaskInfo;
+import android.app.ActivityManager.StackBoxInfo;
+import android.app.ActivityManager.StackInfo;
 import android.app.ActivityManagerNative;
 import android.app.ActivityOptions;
 import android.app.ActivityThread;
@@ -125,6 +155,8 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.text.format.Time;
+import android.util.ArraySet;
+import android.util.AtomicFile;
 import android.util.EventLog;
 import android.util.Log;
 import android.util.Pair;
@@ -132,6 +164,7 @@
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.TimeUtils;
+import android.util.Xml;
 import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -166,41 +199,44 @@
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicLong;
 
-public final class ActivityManagerService  extends ActivityManagerNative
+public final class ActivityManagerService extends ActivityManagerNative
         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
     private static final String USER_DATA_DIR = "/data/user/";
     static final String TAG = "ActivityManager";
     static final String TAG_MU = "ActivityManagerServiceMU";
     static final boolean DEBUG = false;
     static final boolean localLOGV = DEBUG;
+    static final boolean DEBUG_BACKUP = localLOGV || false;
+    static final boolean DEBUG_BROADCAST = localLOGV || false;
+    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
+    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
+    static final boolean DEBUG_CLEANUP = localLOGV || false;
+    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
+    static final boolean DEBUG_FOCUS = false;
+    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
+    static final boolean DEBUG_MU = localLOGV || false;
+    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
+    static final boolean DEBUG_PAUSE = localLOGV || false;
+    static final boolean DEBUG_POWER = localLOGV || false;
+    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
+    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
+    static final boolean DEBUG_PROCESSES = localLOGV || false;
+    static final boolean DEBUG_PROVIDER = localLOGV || false;
+    static final boolean DEBUG_RESULTS = localLOGV || false;
+    static final boolean DEBUG_SERVICE = localLOGV || false;
+    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
+    static final boolean DEBUG_STACK = localLOGV || false;
     static final boolean DEBUG_SWITCH = localLOGV || false;
     static final boolean DEBUG_TASKS = localLOGV || false;
     static final boolean DEBUG_THUMBNAILS = localLOGV || false;
-    static final boolean DEBUG_PAUSE = localLOGV || false;
-    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
     static final boolean DEBUG_TRANSITION = localLOGV || false;
-    static final boolean DEBUG_BROADCAST = localLOGV || false;
-    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
-    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
-    static final boolean DEBUG_SERVICE = localLOGV || false;
-    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
-    static final boolean DEBUG_VISBILITY = localLOGV || false;
-    static final boolean DEBUG_PROCESSES = localLOGV || false;
-    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
-    static final boolean DEBUG_CLEANUP = localLOGV || false;
-    static final boolean DEBUG_PROVIDER = localLOGV || false;
     static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
     static final boolean DEBUG_USER_LEAVING = localLOGV || false;
-    static final boolean DEBUG_RESULTS = localLOGV || false;
-    static final boolean DEBUG_BACKUP = localLOGV || false;
-    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
-    static final boolean DEBUG_POWER = localLOGV || false;
-    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
-    static final boolean DEBUG_MU = localLOGV || false;
-    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
-    static final boolean VALIDATE_TOKENS = false;
+    static final boolean DEBUG_VISBILITY = localLOGV || false;
+    static final boolean DEBUG_PSS = localLOGV || false;
+    static final boolean VALIDATE_TOKENS = true;
     static final boolean SHOW_ACTIVITY_START_TIME = true;
-    
+
     // Control over CPU and battery monitoring.
     static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
     static final boolean MONITOR_CPU_USAGE = true;
@@ -210,14 +246,14 @@
 
     // The flags that are set for all calls we make to the package manager.
     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
-    
+
     private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
 
     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
 
     // Maximum number of recent tasks that we can remember.
     static final int MAX_RECENT_TASKS = 20;
-    
+
     // Amount of time after a call to stopAppSwitches() during which we will
     // prevent further untrusted switches from happening.
     static final long APP_SWITCH_DELAY_TIME = 5*1000;
@@ -238,6 +274,13 @@
     // The minimum amount of time between successive GC requests for a process.
     static final int GC_MIN_INTERVAL = 60*1000;
 
+    // The minimum amount of time between successive PSS requests for a process.
+    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
+
+    // The minimum amount of time between successive PSS requests for a process
+    // when the request is due to the memory state being lowered.
+    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
+
     // The rate at which we check for apps using excessive power -- 15 mins.
     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
 
@@ -266,14 +309,16 @@
     // Maximum number of users we allow to be running at a time.
     static final int MAX_RUNNING_USERS = 3;
 
-    // How long to wait in getTopActivityExtras for the activity to respond with the result.
-    static final int PENDING_ACTIVITY_RESULT_TIMEOUT = 2*2000;
+    // How long to wait in getAssistContextExtras for the activity and foreground services
+    // to respond with the result.
+    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
 
     static final int MY_PID = Process.myPid();
-    
+
     static final String[] EMPTY_STRING_ARRAY = new String[0];
 
-    public ActivityStack mMainStack;
+    /** Run all ActivityStacks through this */
+    ActivityStackSupervisor mStackSupervisor;
 
     public IntentFirewall mIntentFirewall;
 
@@ -289,14 +334,22 @@
      * due to app switches being disabled.
      */
     static class PendingActivityLaunch {
-        ActivityRecord r;
-        ActivityRecord sourceRecord;
-        int startFlags;
+        final ActivityRecord r;
+        final ActivityRecord sourceRecord;
+        final int startFlags;
+        final ActivityStack stack;
+
+        public PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
+                int _startFlags, ActivityStack _stack) {
+            r = _r;
+            sourceRecord = _sourceRecord;
+            startFlags = _startFlags;
+            stack = _stack;
+        }
     }
-    
+
     final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
             = new ArrayList<PendingActivityLaunch>();
-    
 
     BroadcastQueue mFgBroadcastQueue;
     BroadcastQueue mBgBroadcastQueue;
@@ -332,18 +385,18 @@
     /**
      * List of intents that were used to start the most recent tasks.
      */
-    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
+    private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
 
-    public class PendingActivityExtras extends Binder implements Runnable {
+    public class PendingAssistExtras extends Binder implements Runnable {
         public final ActivityRecord activity;
         public boolean haveResult = false;
         public Bundle result = null;
-        public PendingActivityExtras(ActivityRecord _activity) {
+        public PendingAssistExtras(ActivityRecord _activity) {
             activity = _activity;
         }
         @Override
         public void run() {
-            Slog.w(TAG, "getTopActivityExtras failed: timeout retrieving from " + activity);
+            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
             synchronized (this) {
                 haveResult = true;
                 notifyAll();
@@ -351,8 +404,8 @@
         }
     }
 
-    final ArrayList<PendingActivityExtras> mPendingActivityExtras
-            = new ArrayList<PendingActivityExtras>();
+    final ArrayList<PendingAssistExtras> mPendingAssistExtras
+            = new ArrayList<PendingAssistExtras>();
 
     /**
      * Process management.
@@ -368,6 +421,12 @@
     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
 
     /**
+     * Tracking long-term execution of processes to look for abuse and other
+     * bad app behavior.
+     */
+    final ProcessStatsService mProcessStats;
+
+    /**
      * The currently running isolated processes.
      */
     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
@@ -382,7 +441,7 @@
      * The currently running heavy-weight process, if any.
      */
     ProcessRecord mHeavyWeightProcess = null;
-    
+
     /**
      * The last time that various processes have crashed.
      */
@@ -416,51 +475,53 @@
         int pid;
         IBinder token;
     }
-    final SparseArray<ForegroundToken> mForegroundProcesses
-            = new SparseArray<ForegroundToken>();
-    
+    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
+
     /**
      * List of records for processes that someone had tried to start before the
      * system was ready.  We don't start them at that point, but ensure they
      * are started by the time booting is complete.
      */
-    final ArrayList<ProcessRecord> mProcessesOnHold
-            = new ArrayList<ProcessRecord>();
+    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
 
     /**
      * List of persistent applications that are in the process
      * of being started.
      */
-    final ArrayList<ProcessRecord> mPersistentStartingProcesses
-            = new ArrayList<ProcessRecord>();
+    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
 
     /**
      * Processes that are being forcibly torn down.
      */
-    final ArrayList<ProcessRecord> mRemovedProcesses
-            = new ArrayList<ProcessRecord>();
+    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
 
     /**
      * List of running applications, sorted by recent usage.
      * The first entry in the list is the least recently used.
-     * It contains ApplicationRecord objects.  This list does NOT include
-     * any persistent application records (since we never want to exit them).
      */
-    final ArrayList<ProcessRecord> mLruProcesses
-            = new ArrayList<ProcessRecord>();
+    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
 
     /**
      * List of processes that should gc as soon as things are idle.
      */
-    final ArrayList<ProcessRecord> mProcessesToGc
-            = new ArrayList<ProcessRecord>();
+    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
+
+    /**
+     * Processes we want to collect PSS data from.
+     */
+    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
+
+    /**
+     * Last time we requested PSS data of all processes.
+     */
+    long mLastFullPssTime = SystemClock.uptimeMillis();
 
     /**
      * This is the process holding what we currently consider to be
      * the "home" activity.
      */
-    ProcessRecord mHomeProcess;
-    
+    ArraySet<ProcessRecord> mHomeProcess = new ArraySet<ProcessRecord>();
+
     /**
      * This is the process holding the activity the user last visited that
      * is in a different process from the one they are currently in.
@@ -505,11 +566,6 @@
     final CompatModePackages mCompatModePackages;
 
     /**
-     * Set of PendingResultRecord objects that are currently active.
-     */
-    final HashSet mPendingResultRecords = new HashSet();
-
-    /**
      * Set of IntentSenderRecord objects that are currently active.
      */
     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
@@ -538,7 +594,8 @@
      * broadcasts.  Hash keys are the receiver IBinder, hash value is
      * a ReceiverList.
      */
-    final HashMap mRegisteredReceivers = new HashMap();
+    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
+            new HashMap<IBinder, ReceiverList>();
 
     /**
      * Resolver for broadcast intents to registered receivers.
@@ -585,8 +642,8 @@
      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
      * for stickies that are sent to all users.
      */
-    final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts =
-            new SparseArray<HashMap<String, ArrayList<Intent>>>();
+    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
+            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
 
     final ActiveServices mServices;
 
@@ -600,13 +657,8 @@
      * List of PendingThumbnailsRecord objects of clients who are still
      * waiting to receive all of the thumbnails for a task.
      */
-    final ArrayList mPendingThumbnails = new ArrayList();
-
-    /**
-     * List of HistoryRecord objects that have been finished and must
-     * still report back to a pending thumbnail receiver.
-     */
-    final ArrayList mCancelledThumbnails = new ArrayList();
+    final ArrayList<PendingThumbnailsRecord> mPendingThumbnails =
+            new ArrayList<PendingThumbnailsRecord>();
 
     final ProviderMap mProviderMap;
 
@@ -619,10 +671,27 @@
             = new ArrayList<ContentProviderRecord>();
 
     /**
-     * Global set of specific Uri permissions that have been granted.
+     * File storing persisted {@link #mGrantedUriPermissions}.
      */
-    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
-            = new SparseArray<HashMap<Uri, UriPermission>>();
+    private final AtomicFile mGrantFile;
+
+    /** XML constants used in {@link #mGrantFile} */
+    private static final String TAG_URI_GRANTS = "uri-grants";
+    private static final String TAG_URI_GRANT = "uri-grant";
+    private static final String ATTR_USER_HANDLE = "userHandle";
+    private static final String ATTR_SOURCE_PKG = "sourcePkg";
+    private static final String ATTR_TARGET_PKG = "targetPkg";
+    private static final String ATTR_URI = "uri";
+    private static final String ATTR_MODE_FLAGS = "modeFlags";
+
+    /**
+     * Global set of specific {@link Uri} permissions that have been granted.
+     * This optimized lookup structure maps from {@link UriPermission#targetUid}
+     * to {@link UriPermission#uri} to {@link UriPermission}.
+     */
+    @GuardedBy("this")
+    private final SparseArray<ArrayMap<Uri, UriPermission>>
+            mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>();
 
     CoreSettingsObserver mCoreSettingsObserver;
 
@@ -647,12 +716,12 @@
      * any user id that can impact battery performance.
      */
     final BatteryStatsService mBatteryStatsService;
-    
+
     /**
      * Information about component usage
      */
     final UsageStatsService mUsageStatsService;
-    
+
     /**
      * Information about and control over application operations
      */
@@ -670,7 +739,7 @@
      * configurations.
      */
     int mConfigurationSeq = 0;
-    
+
     /**
      * Hardware-reported OpenGLES version.
      */
@@ -686,7 +755,7 @@
      * Temporary to avoid allocations.  Protected by main lock.
      */
     final StringBuilder mStringBuilder = new StringBuilder(256);
-    
+
     /**
      * Used to control how we initialize the service.
      */
@@ -707,7 +776,7 @@
     int mFactoryTest;
 
     boolean mCheckedForSetup;
-    
+
     /**
      * The time at which we will allow normal application switches again,
      * after a call to {@link #stopAppSwitches()}.
@@ -719,7 +788,7 @@
      * is set; any switches after that will clear the time.
      */
     boolean mDidAppSwitch;
-    
+
     /**
      * Last time (in realtime) at which we checked for power usage.
      */
@@ -752,14 +821,6 @@
     boolean mShuttingDown = false;
 
     /**
-     * Task identifier that activities are currently being started
-     * in.  Incremented each time a new task is created.
-     * todo: Replace this with a TokenSpace class that generates non-repeating
-     * integers that won't wrap.
-     */
-    int mCurTask = 1;
-
-    /**
      * Current sequence id for oom_adj computation traversal.
      */
     int mAdjSeq = 0;
@@ -770,16 +831,16 @@
     int mLruSeq = 0;
 
     /**
-     * Keep track of the non-hidden/empty process we last found, to help
-     * determine how to distribute hidden/empty processes next time.
+     * Keep track of the non-cached/empty process we last found, to help
+     * determine how to distribute cached/empty processes next time.
      */
-    int mNumNonHiddenProcs = 0;
+    int mNumNonCachedProcs = 0;
 
     /**
-     * Keep track of the number of hidden procs, to balance oom adj
+     * Keep track of the number of cached hidden procs, to balance oom adj
      * distribution between those and empty procs.
      */
-    int mNumHiddenProcs = 0;
+    int mNumCachedHiddenProcs = 0;
 
     /**
      * Keep track of the number of service processes we last found, to
@@ -793,13 +854,13 @@
      * N procs were started.
      */
     int[] mProcDeaths = new int[20];
-    
+
     /**
      * This is set if we had to do a delayed dexopt of an app before launching
      * it, to increasing the ANR timeouts in that case.
      */
     boolean mDidDexOpt;
-    
+
     String mDebugApp = null;
     boolean mWaitForDebugger = false;
     boolean mDebugTransient = false;
@@ -835,19 +896,19 @@
             = new ArrayList<ProcessChangeItem>();
 
     /**
-     * Runtime statistics collection thread.  This object's lock is used to
+     * Runtime CPU use collection thread.  This object's lock is used to
      * protect all related state.
      */
-    final Thread mProcessStatsThread;
-    
+    final Thread mProcessCpuThread;
+
     /**
      * Used to collect process stats when showing not responding dialog.
-     * Protected by mProcessStatsThread.
+     * Protected by mProcessCpuThread.
      */
-    final ProcessStats mProcessStats = new ProcessStats(
+    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
             MONITOR_THREAD_CPU_USAGE);
     final AtomicLong mLastCpuTime = new AtomicLong(0);
-    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
+    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
 
     long mLastWriteTime = 0;
 
@@ -862,7 +923,7 @@
      */
     boolean mBooted = false;
 
-    int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
+    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
     int mProcessLimitOverride = -1;
 
     WindowManagerService mWindowManager;
@@ -870,8 +931,7 @@
     static ActivityManagerService mSelf;
     static ActivityThread mSystemThread;
 
-    private int mCurrentUserId = 0;
-    private int[] mCurrentUserArray = new int[] { 0 };
+    int mCurrentUserId = 0;
     private UserManagerService mUserManager;
 
     private final class AppDeathRecipient implements IBinder.DeathRecipient {
@@ -889,6 +949,7 @@
             mAppThread = thread;
         }
 
+        @Override
         public void binderDied() {
             if (localLOGV) Slog.v(
                 TAG, "Death received in " + this
@@ -927,10 +988,12 @@
     static final int CONTINUE_USER_SWITCH_MSG = 35;
     static final int USER_SWITCH_TIMEOUT_MSG = 36;
     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
+    static final int PERSIST_URI_GRANTS = 38;
 
     static final int FIRST_ACTIVITY_STACK_MSG = 100;
     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
     static final int FIRST_COMPAT_MODE_MSG = 300;
+    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
 
     AlertDialog mUidAlert;
     CompatModeDialog mCompatModeDialog;
@@ -947,10 +1010,11 @@
         //    if (localLOGV) Slog.v(TAG, "Handler started!");
         //}
 
+        @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
             case SHOW_ERROR_MSG: {
-                HashMap data = (HashMap) msg.obj;
+                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
                 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
                         Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
                 synchronized (ActivityManagerService.this) {
@@ -985,18 +1049,18 @@
                         }
                     }
                 }
-                
+
                 ensureBootCompleted();
             } break;
             case SHOW_NOT_RESPONDING_MSG: {
                 synchronized (ActivityManagerService.this) {
-                    HashMap data = (HashMap) msg.obj;
+                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
                     ProcessRecord proc = (ProcessRecord)data.get("app");
                     if (proc != null && proc.anrDialog != null) {
                         Slog.e(TAG, "App already has anr dialog: " + proc);
                         return;
                     }
-                    
+
                     Intent intent = new Intent("android.intent.action.ANR");
                     if (!mProcessesReady) {
                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
@@ -1017,7 +1081,7 @@
                         killAppAtUsersRequest(proc, null);
                     }
                 }
-                
+
                 ensureBootCompleted();
             } break;
             case SHOW_STRICT_MODE_VIOLATION_MSG: {
@@ -1124,17 +1188,19 @@
                 String host = "";
                 String port = "";
                 String exclList = "";
+                String pacFileUrl = null;
                 if (proxy != null) {
                     host = proxy.getHost();
                     port = Integer.toString(proxy.getPort());
                     exclList = proxy.getExclusionList();
+                    pacFileUrl = proxy.getPacFileUrl();
                 }
                 synchronized (ActivityManagerService.this) {
                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
                         ProcessRecord r = mLruProcesses.get(i);
                         if (r.thread != null) {
                             try {
-                                r.thread.setHttpProxy(host, port, exclList);
+                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
                             } catch (RemoteException ex) {
                                 Slog.w(TAG, "Failed to update http proxy for: " +
                                         r.info.processName);
@@ -1189,9 +1255,11 @@
                 synchronized (ActivityManagerService.this) {
                     int appid = msg.arg1;
                     boolean restart = (msg.arg2 == 1);
-                    String pkg = (String) msg.obj;
+                    Bundle bundle = (Bundle)msg.obj;
+                    String pkg = bundle.getString("pkg");
+                    String reason = bundle.getString("reason");
                     forceStopPackageLocked(pkg, appid, restart, false, true, false,
-                            UserHandle.USER_ALL);
+                            UserHandle.USER_ALL, reason);
                 }
             } break;
             case FINALIZE_PENDING_INTENT_MSG: {
@@ -1202,13 +1270,13 @@
                 if (inm == null) {
                     return;
                 }
-                
+
                 ActivityRecord root = (ActivityRecord)msg.obj;
                 ProcessRecord process = root.app;
                 if (process == null) {
                     return;
                 }
-                
+
                 try {
                     Context context = mContext.createPackageContext(process.info.packageName, 0);
                     String text = mContext.getString(R.string.heavy_weight_notification,
@@ -1226,7 +1294,7 @@
                             PendingIntent.getActivityAsUser(mContext, 0, root.intent,
                                     PendingIntent.FLAG_CANCEL_CURRENT, null,
                                     new UserHandle(root.userId)));
-                    
+
                     try {
                         int[] outId = new int[1];
                         inm.enqueueNotificationWithTag("android", "android", null,
@@ -1302,63 +1370,167 @@
                 break;
             }
             case REPORT_MEM_USAGE: {
-                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
-                if (!isDebuggable) {
-                    return;
-                }
-                synchronized (ActivityManagerService.this) {
-                    long now = SystemClock.uptimeMillis();
-                    if (now < (mLastMemUsageReportTime+5*60*1000)) {
-                        // Don't report more than every 5 minutes to somewhat
-                        // avoid spamming.
-                        return;
-                    }
-                    mLastMemUsageReportTime = now;
-                }
+                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
                 Thread thread = new Thread() {
                     @Override public void run() {
-                        StringBuilder dropBuilder = new StringBuilder(1024);
-                        StringBuilder logBuilder = new StringBuilder(1024);
-                        StringWriter oomSw = new StringWriter();
-                        PrintWriter oomPw = new PrintWriter(oomSw);
-                        StringWriter catSw = new StringWriter();
-                        PrintWriter catPw = new PrintWriter(catSw);
-                        String[] emptyArgs = new String[] { };
+                        final SparseArray<ProcessMemInfo> infoMap
+                                = new SparseArray<ProcessMemInfo>(memInfos.size());
+                        for (int i=0, N=memInfos.size(); i<N; i++) {
+                            ProcessMemInfo mi = memInfos.get(i);
+                            infoMap.put(mi.pid, mi);
+                        }
+                        updateCpuStatsNow();
+                        synchronized (mProcessCpuThread) {
+                            final int N = mProcessCpuTracker.countStats();
+                            for (int i=0; i<N; i++) {
+                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
+                                if (st.vsize > 0) {
+                                    long pss = Debug.getPss(st.pid, null);
+                                    if (pss > 0) {
+                                        if (infoMap.indexOfKey(st.pid) < 0) {
+                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
+                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
+                                            mi.pss = pss;
+                                            memInfos.add(mi);
+                                        }
+                                    }
+                                }
+                            }
+                        }
+
+                        long totalPss = 0;
+                        for (int i=0, N=memInfos.size(); i<N; i++) {
+                            ProcessMemInfo mi = memInfos.get(i);
+                            if (mi.pss == 0) {
+                                mi.pss = Debug.getPss(mi.pid, null);
+                            }
+                            totalPss += mi.pss;
+                        }
+                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
+                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
+                                if (lhs.oomAdj != rhs.oomAdj) {
+                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
+                                }
+                                if (lhs.pss != rhs.pss) {
+                                    return lhs.pss < rhs.pss ? 1 : -1;
+                                }
+                                return 0;
+                            }
+                        });
+
                         StringBuilder tag = new StringBuilder(128);
                         StringBuilder stack = new StringBuilder(128);
                         tag.append("Low on memory -- ");
-                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
-                                tag, stack);
+                        appendMemBucket(tag, totalPss, "total", false);
+                        appendMemBucket(stack, totalPss, "total", true);
+
+                        StringBuilder logBuilder = new StringBuilder(1024);
+                        logBuilder.append("Low on memory:\n");
+
+                        boolean firstLine = true;
+                        int lastOomAdj = Integer.MIN_VALUE;
+                        for (int i=0, N=memInfos.size(); i<N; i++) {
+                            ProcessMemInfo mi = memInfos.get(i);
+
+                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
+                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
+                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
+                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
+                                if (lastOomAdj != mi.oomAdj) {
+                                    lastOomAdj = mi.oomAdj;
+                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
+                                        tag.append(" / ");
+                                    }
+                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
+                                        if (firstLine) {
+                                            stack.append(":");
+                                            firstLine = false;
+                                        }
+                                        stack.append("\n\t at ");
+                                    } else {
+                                        stack.append("$");
+                                    }
+                                } else {
+                                    tag.append(" ");
+                                    stack.append("$");
+                                }
+                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
+                                    appendMemBucket(tag, mi.pss, mi.name, false);
+                                }
+                                appendMemBucket(stack, mi.pss, mi.name, true);
+                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
+                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
+                                    stack.append("(");
+                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
+                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
+                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
+                                            stack.append(":");
+                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
+                                        }
+                                    }
+                                    stack.append(")");
+                                }
+                            }
+
+                            logBuilder.append("  ");
+                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
+                            logBuilder.append(' ');
+                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
+                            logBuilder.append(' ');
+                            ProcessList.appendRamKb(logBuilder, mi.pss);
+                            logBuilder.append(" kB: ");
+                            logBuilder.append(mi.name);
+                            logBuilder.append(" (");
+                            logBuilder.append(mi.pid);
+                            logBuilder.append(") ");
+                            logBuilder.append(mi.adjType);
+                            logBuilder.append('\n');
+                            if (mi.adjReason != null) {
+                                logBuilder.append("                      ");
+                                logBuilder.append(mi.adjReason);
+                                logBuilder.append('\n');
+                            }
+                        }
+
+                        logBuilder.append("           ");
+                        ProcessList.appendRamKb(logBuilder, totalPss);
+                        logBuilder.append(" kB: TOTAL\n");
+
+                        long[] infos = new long[Debug.MEMINFO_COUNT];
+                        Debug.getMemInfo(infos);
+                        logBuilder.append("  MemInfo: ");
+                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
+                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
+                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
+                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
+                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
+
+                        Slog.i(TAG, logBuilder.toString());
+
+                        StringBuilder dropBuilder = new StringBuilder(1024);
+                        /*
+                        StringWriter oomSw = new StringWriter();
+                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
+                        StringWriter catSw = new StringWriter();
+                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
+                        String[] emptyArgs = new String[] { };
+                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
+                        oomPw.flush();
+                        String oomString = oomSw.toString();
+                        */
                         dropBuilder.append(stack);
                         dropBuilder.append('\n');
                         dropBuilder.append('\n');
-                        String oomString = oomSw.toString();
+                        dropBuilder.append(logBuilder);
+                        dropBuilder.append('\n');
+                        /*
                         dropBuilder.append(oomString);
                         dropBuilder.append('\n');
-                        logBuilder.append(oomString);
-                        try {
-                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
-                                    "procrank", });
-                            final InputStreamReader converter = new InputStreamReader(
-                                    proc.getInputStream());
-                            BufferedReader in = new BufferedReader(converter);
-                            String line;
-                            while (true) {
-                                line = in.readLine();
-                                if (line == null) {
-                                    break;
-                                }
-                                if (line.length() > 0) {
-                                    logBuilder.append(line);
-                                    logBuilder.append('\n');
-                                }
-                                dropBuilder.append(line);
-                                dropBuilder.append('\n');
-                            }
-                            converter.close();
-                        } catch (IOException e) {
-                        }
+                        */
+                        StringWriter catSw = new StringWriter();
                         synchronized (ActivityManagerService.this) {
+                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
+                            String[] emptyArgs = new String[] { };
                             catPw.println();
                             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
                             catPw.println();
@@ -1366,11 +1538,13 @@
                                     false, false, null);
                             catPw.println();
                             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
+                            catPw.flush();
                         }
                         dropBuilder.append(catSw.toString());
                         addErrorToDropBox("lowmem", null, "system_server", null,
                                 null, tag.toString(), dropBuilder.toString(), null, null);
-                        Slog.i(TAG, logBuilder.toString());
+                        //Slog.i(TAG, "Sent to dropbox:");
+                        //Slog.i(TAG, dropBuilder.toString());
                         synchronized (ActivityManagerService.this) {
                             long now = SystemClock.uptimeMillis();
                             if (mLastMemUsageReportTime < now) {
@@ -1409,6 +1583,58 @@
                 }
                 break;
             }
+            case PERSIST_URI_GRANTS: {
+                writeGrantedUriPermissions();
+                break;
+            }
+            }
+        }
+    };
+
+    static final int COLLECT_PSS_BG_MSG = 1;
+
+    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+            case COLLECT_PSS_BG_MSG: {
+                int i=0, num=0;
+                long start = SystemClock.uptimeMillis();
+                long[] tmp = new long[1];
+                do {
+                    ProcessRecord proc;
+                    int procState;
+                    int pid;
+                    synchronized (ActivityManagerService.this) {
+                        if (i >= mPendingPssProcesses.size()) {
+                            if (DEBUG_PSS) Slog.i(TAG, "Collected PSS of " + num + " of " + i
+                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
+                            mPendingPssProcesses.clear();
+                            return;
+                        }
+                        proc = mPendingPssProcesses.get(i);
+                        procState = proc.pssProcState;
+                        if (proc.thread != null && procState == proc.setProcState) {
+                            pid = proc.pid;
+                        } else {
+                            proc = null;
+                            pid = 0;
+                        }
+                        i++;
+                    }
+                    if (proc != null) {
+                        long pss = Debug.getPss(pid, tmp);
+                        synchronized (ActivityManagerService.this) {
+                            if (proc.thread != null && proc.setProcState == procState
+                                    && proc.pid == pid) {
+                                num++;
+                                proc.lastPssTime = SystemClock.uptimeMillis();
+                                proc.baseProcessTracker.addPss(pss, tmp[0], true);
+                            }
+                        }
+                    }
+                } while (true);
+            }
             }
         }
     };
@@ -1417,7 +1643,8 @@
         try {
             ActivityManagerService m = mSelf;
 
-            ServiceManager.addService("activity", m, true);
+            ServiceManager.addService(Context.ACTIVITY_SERVICE, m, true);
+            ServiceManager.addService(ProcessStats.SERVICE_NAME, m.mProcessStats);
             ServiceManager.addService("meminfo", new MemBinder(m));
             ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
             ServiceManager.addService("dbinfo", new DbBinder(m));
@@ -1430,14 +1657,14 @@
                 mSelf.mContext.getPackageManager().getApplicationInfo(
                             "android", STOCK_PM_FLAGS);
             mSystemThread.installSystemApplicationInfo(info);
-       
+
             synchronized (mSelf) {
-                ProcessRecord app = mSelf.newProcessRecordLocked(
-                        mSystemThread.getApplicationThread(), info,
+                ProcessRecord app = mSelf.newProcessRecordLocked(info,
                         info.processName, false);
                 app.persistent = true;
                 app.pid = MY_PID;
                 app.maxAdj = ProcessList.SYSTEM_ADJ;
+                app.makeActive(mSystemThread.getApplicationThread(), mSelf.mProcessStats);
                 mSelf.mProcessNames.put(app.processName, app.uid, app);
                 synchronized (mSelf.mPidsSelfLocked) {
                     mSelf.mPidsSelfLocked.put(app.pid, app);
@@ -1452,6 +1679,8 @@
 
     public void setWindowManager(WindowManagerService wm) {
         mWindowManager = wm;
+        mStackSupervisor.setWindowManager(wm);
+        wm.createStack(HOME_STACK_ID, -1, StackBox.TASK_STACK_GOES_OVER, 1.0f);
     }
 
     public void startObservingNativeCrashes() {
@@ -1480,9 +1709,10 @@
         context.setTheme(android.R.style.Theme_Holo);
         m.mContext = context;
         m.mFactoryTest = factoryTest;
-        m.mMainStack = new ActivityStack(m, context, true, thr.mLooper);
         m.mIntentFirewall = new IntentFirewall(m.new IntentFirewallInterface());
 
+        m.mStackSupervisor = new ActivityStackSupervisor(m, context, thr.mLooper);
+
         m.mBatteryStatsService.publish(context);
         m.mUsageStatsService.publish(context);
         m.mAppOpsService.publish(context);
@@ -1493,14 +1723,18 @@
         }
 
         m.startRunning(null, null, null, null);
-        
+
         return context;
     }
 
     public static ActivityManagerService self() {
         return mSelf;
     }
-    
+
+    public IAppOpsService getAppOpsService() {
+        return mAppOpsService;
+    }
+
     static class AThread extends Thread {
         ActivityManagerService mService;
         Looper mLooper;
@@ -1510,6 +1744,7 @@
             super("ActivityManager");
         }
 
+        @Override
         public void run() {
             Looper.prepare();
 
@@ -1522,6 +1757,7 @@
             synchronized (this) {
                 mService = m;
                 mLooper = Looper.myLooper();
+                Watchdog.getInstance().addThread(new Handler(mLooper), getName());
                 notifyAll();
             }
 
@@ -1559,8 +1795,7 @@
                 return;
             }
 
-            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
-                    false, null, null, null);
+            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
         }
     }
 
@@ -1620,9 +1855,9 @@
                 return;
             }
 
-            synchronized (mActivityManagerService.mProcessStatsThread) {
-                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
-                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
+            synchronized (mActivityManagerService.mProcessCpuThread) {
+                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
+                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
                         SystemClock.uptimeMillis()));
             }
         }
@@ -1630,7 +1865,7 @@
 
     private ActivityManagerService() {
         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
-        
+
         mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
         mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
         mBroadcastQueues[0] = mFgBroadcastQueue;
@@ -1650,9 +1885,13 @@
                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
         mBatteryStatsService.getActiveStatistics().setCallback(this);
 
-        mUsageStatsService = new UsageStatsService(new File(
-                systemDir, "usagestats").toString());
+        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
+
+        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"));
+
+        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
+
         mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
 
         // User 0 is the first and only user that runs at boot.
@@ -1667,14 +1906,15 @@
         mConfiguration.setLocale(Locale.getDefault());
 
         mConfigurationSeq = mConfiguration.seq = 1;
-        mProcessStats.init();
-        
+        mProcessCpuTracker.init();
+
         mCompatModePackages = new CompatModePackages(this, systemDir);
 
         // Add ourself to the Watchdog monitors.
         Watchdog.getInstance().addMonitor(this);
 
-        mProcessStatsThread = new Thread("ProcessStats") {
+        mProcessCpuThread = new Thread("CpuTracker") {
+            @Override
             public void run() {
                 while (true) {
                     try {
@@ -1689,7 +1929,7 @@
                                     nextCpuDelay = nextWriteDelay;
                                 }
                                 if (nextCpuDelay > 0) {
-                                    mProcessStatsMutexFree.set(true);
+                                    mProcessCpuMutexFree.set(true);
                                     this.wait(nextCpuDelay);
                                 }
                             }
@@ -1702,7 +1942,7 @@
                 }
             }
         };
-        mProcessStatsThread.start();
+        mProcessCpuThread.start();
     }
 
     @Override
@@ -1712,7 +1952,9 @@
             // We need to tell all apps about the system property change.
             ArrayList<IBinder> procs = new ArrayList<IBinder>();
             synchronized(this) {
-                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
+                final int NP = mProcessNames.getMap().size();
+                for (int ip=0; ip<NP; ip++) {
+                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
                     final int NA = apps.size();
                     for (int ia=0; ia<NA; ia++) {
                         ProcessRecord app = apps.valueAt(ia);
@@ -1750,16 +1992,16 @@
         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
             return;
         }
-        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
-            synchronized (mProcessStatsThread) {
-                mProcessStatsThread.notify();
+        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
+            synchronized (mProcessCpuThread) {
+                mProcessCpuThread.notify();
             }
         }
     }
 
     void updateCpuStatsNow() {
-        synchronized (mProcessStatsThread) {
-            mProcessStatsMutexFree.set(false);
+        synchronized (mProcessCpuThread) {
+            mProcessCpuMutexFree.set(false);
             final long now = SystemClock.uptimeMillis();
             boolean haveNewCpuStats = false;
 
@@ -1767,19 +2009,19 @@
                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
                 mLastCpuTime.set(now);
                 haveNewCpuStats = true;
-                mProcessStats.update();
-                //Slog.i(TAG, mProcessStats.printCurrentState());
+                mProcessCpuTracker.update();
+                //Slog.i(TAG, mProcessCpu.printCurrentState());
                 //Slog.i(TAG, "Total CPU usage: "
-                //        + mProcessStats.getTotalCpuPercent() + "%");
+                //        + mProcessCpu.getTotalCpuPercent() + "%");
 
                 // Slog the cpu usage if the property is set.
                 if ("true".equals(SystemProperties.get("events.cpu"))) {
-                    int user = mProcessStats.getLastUserTime();
-                    int system = mProcessStats.getLastSystemTime();
-                    int iowait = mProcessStats.getLastIoWaitTime();
-                    int irq = mProcessStats.getLastIrqTime();
-                    int softIrq = mProcessStats.getLastSoftIrqTime();
-                    int idle = mProcessStats.getLastIdleTime();
+                    int user = mProcessCpuTracker.getLastUserTime();
+                    int system = mProcessCpuTracker.getLastSystemTime();
+                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
+                    int irq = mProcessCpuTracker.getLastIrqTime();
+                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
+                    int idle = mProcessCpuTracker.getLastIdleTime();
 
                     int total = user + system + iowait + irq + softIrq + idle;
                     if (total == 0) total = 1;
@@ -1793,8 +2035,8 @@
                             (softIrq * 100) / total);
                 }
             }
-            
-            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
+
+            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
             synchronized(bstats) {
                 synchronized(mPidsSelfLocked) {
@@ -1803,9 +2045,9 @@
                             int perc = bstats.startAddingCpuLocked();
                             int totalUTime = 0;
                             int totalSTime = 0;
-                            final int N = mProcessStats.countStats();
+                            final int N = mProcessCpuTracker.countStats();
                             for (int i=0; i<N; i++) {
-                                ProcessStats.Stats st = mProcessStats.getStats(i);
+                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
                                 if (!st.working) {
                                     continue;
                                 }
@@ -1820,6 +2062,15 @@
                                             st.rel_stime-otherSTime);
                                     ps.addSpeedStepTimes(cpuSpeedTimes);
                                     pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
+                                } else if (st.uid >= Process.FIRST_APPLICATION_UID) {
+                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
+                                    if (ps == null) {
+                                        st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid,
+                                                "(Unknown)");
+                                    }
+                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
+                                            st.rel_stime-otherSTime);
+                                    ps.addSpeedStepTimes(cpuSpeedTimes);
                                 } else {
                                     BatteryStatsImpl.Uid.Proc ps =
                                             bstats.getProcessStatsLocked(st.name, st.pid);
@@ -1843,7 +2094,7 @@
             }
         }
     }
-    
+
     @Override
     public void batteryNeedsCpuUpdate() {
         updateCpuStatsNow();
@@ -1881,7 +2132,9 @@
 
     final void setFocusedActivityLocked(ActivityRecord r) {
         if (mFocusedActivity != r) {
+            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
             mFocusedActivity = r;
+            mStackSupervisor.setFocusedStack(r);
             if (r != null) {
                 mWindowManager.setFocusedApp(r.appToken, true);
             }
@@ -1889,6 +2142,31 @@
         }
     }
 
+    @Override
+    public void setFocusedStack(int stackId) {
+        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
+        synchronized (ActivityManagerService.this) {
+            ActivityStack stack = mStackSupervisor.getStack(stackId);
+            if (stack != null) {
+                ActivityRecord r = stack.topRunningActivityLocked(null);
+                if (r != null) {
+                    setFocusedActivityLocked(r);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void notifyActivityDrawn(IBinder token) {
+        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
+        synchronized (this) {
+            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
+            if (r != null) {
+                r.task.stack.notifyActivityDrawnLocked(r);
+            }
+        }
+    }
+
     final void applyUpdateLockStateLocked(ActivityRecord r) {
         // Modifications to the UpdateLock state are done on our handler, outside
         // the activity manager's locks.  The new state is determined based on the
@@ -1899,16 +2177,23 @@
                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
     }
 
+    final void showAskCompatModeDialogLocked(ActivityRecord r) {
+        Message msg = Message.obtain();
+        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
+        msg.obj = r.task.askedCompatMode ? null : r;
+        mHandler.sendMessage(msg);
+    }
+
     private final void updateLruProcessInternalLocked(ProcessRecord app, int bestPos) {
         // put it on the LRU to keep track of when it should be exited.
         int lrui = mLruProcesses.indexOf(app);
         if (lrui >= 0) mLruProcesses.remove(lrui);
-        
+
         int i = mLruProcesses.size()-1;
         int skipTop = 0;
-        
+
         app.lruSeq = mLruSeq;
-        
+
         // compute the new weight for this process.
         app.lastActivityTime = SystemClock.uptimeMillis();
         if (app.activities.size() > 0) {
@@ -1919,22 +2204,22 @@
             // If this process contains content providers, we want to keep
             // it a little more strongly.
             app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
-            // Also don't let it kick out the first few "real" hidden processes.
-            skipTop = ProcessList.MIN_HIDDEN_APPS;
+            // Also don't let it kick out the first few "real" cached processes.
+            skipTop = ProcessList.MIN_CACHED_APPS;
         } else {
             // If this process doesn't have activities, we less strongly
             // want to keep it around, and generally want to avoid getting
             // in front of any very recently used activities.
             app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
-            // Also don't let it kick out the first few "real" hidden processes.
-            skipTop = ProcessList.MIN_HIDDEN_APPS;
+            // Also don't let it kick out the first few "real" cached processes.
+            skipTop = ProcessList.MIN_CACHED_APPS;
         }
 
         while (i >= 0) {
             ProcessRecord p = mLruProcesses.get(i);
             // If this app shouldn't be in front of the first N background
-            // apps, then skip over that many that are currently hidden.
-            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
+            // apps, then skip over that many that are currently cached.
+            if (skipTop > 0 && p.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
                 skipTop--;
             }
             if (p.lruWeight <= app.lruWeight || i < bestPos) {
@@ -1946,16 +2231,15 @@
         if (i < 0) {
             mLruProcesses.add(0, app);
         }
-        
+
         // If the app is currently using a content provider or service,
         // bump those processes as well.
-        if (app.connections.size() > 0) {
-            for (ConnectionRecord cr : app.connections) {
-                if (cr.binding != null && cr.binding.service != null
-                        && cr.binding.service.app != null
-                        && cr.binding.service.app.lruSeq != mLruSeq) {
-                    updateLruProcessInternalLocked(cr.binding.service.app, i+1);
-                }
+        for (int j=app.connections.size()-1; j>=0; j--) {
+            ConnectionRecord cr = app.connections.valueAt(j);
+            if (cr.binding != null && cr.binding.service != null
+                    && cr.binding.service.app != null
+                    && cr.binding.service.app.lruSeq != mLruSeq) {
+                updateLruProcessInternalLocked(cr.binding.service.app, i+1);
             }
         }
         for (int j=app.conProviders.size()-1; j>=0; j--) {
@@ -2004,14 +2288,14 @@
         } catch (RemoteException e) {
         }
     }
-    
+
     boolean isNextTransitionForward() {
         int transit = mWindowManager.getPendingAppTransition();
         return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
                 || transit == AppTransition.TRANSIT_TASK_OPEN
                 || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
     }
-    
+
     final ProcessRecord startProcessLocked(String processName,
             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
@@ -2039,14 +2323,14 @@
                 // come up (we have a pid but not yet its thread), so keep it.
                 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
                 // If this is a new package in the process, add the package to the list
-                app.addPackage(info.packageName);
+                app.addPackage(info.packageName, mProcessStats);
                 return app;
-            } else {
-                // An application record is attached to a previous process,
-                // clean it up now.
-                if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
-                handleAppDiedLocked(app, true, true);
             }
+
+            // An application record is attached to a previous process,
+            // clean it up now.
+            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
+            handleAppDiedLocked(app, true, true);
         }
 
         String hostingNameStr = hostingName != null
@@ -2082,7 +2366,7 @@
         }
 
         if (app == null) {
-            app = newProcessRecordLocked(null, info, processName, isolated);
+            app = newProcessRecordLocked(info, processName, isolated);
             if (app == null) {
                 Slog.w(TAG, "Failed making new process record for "
                         + processName + "/" + info.uid + " isolated=" + isolated);
@@ -2094,7 +2378,7 @@
             }
         } else {
             // If this is a new package in the process, add the package to the list
-            app.addPackage(info.packageName);
+            app.addPackage(info.packageName, mProcessStats);
         }
 
         // If the system is not ready yet, then hold off on starting this
@@ -2116,7 +2400,7 @@
     boolean isAllowedWhileBooting(ApplicationInfo ai) {
         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
     }
-    
+
     private final void startProcessLocked(ProcessRecord app,
             String hostingType, String hostingNameStr) {
         if (app.pid > 0 && app.pid != MY_PID) {
@@ -2132,10 +2416,10 @@
         mProcessesOnHold.remove(app);
 
         updateCpuStats();
-        
+
         System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
         mProcDeaths[0] = 0;
-        
+
         try {
             int uid = app.uid;
 
@@ -2218,16 +2502,16 @@
                     app.batteryStats.incStartsLocked();
                 }
             }
-            
+
             EventLog.writeEvent(EventLogTags.AM_PROC_START,
                     UserHandle.getUserId(uid), startResult.pid, uid,
                     app.processName, hostingType,
                     hostingNameStr != null ? hostingNameStr : "");
-            
+
             if (app.persistent) {
                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
             }
-            
+
             StringBuilder buf = mStringBuilder;
             buf.setLength(0);
             buf.append("Start proc ");
@@ -2269,14 +2553,43 @@
         }
     }
 
-    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
+    void updateUsageStats(ActivityRecord component, boolean resumed) {
+        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
+        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
         if (resumed) {
-            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
+            mUsageStatsService.noteResumeComponent(component.realActivity);
+            synchronized (stats) {
+                stats.noteActivityResumedLocked(component.app.uid);
+            }
         } else {
-            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
+            mUsageStatsService.notePauseComponent(component.realActivity);
+            synchronized (stats) {
+                stats.noteActivityPausedLocked(component.app.uid);
+            }
         }
     }
 
+    Intent getHomeIntent() {
+        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
+        intent.setComponent(mTopComponent);
+        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
+            intent.addCategory(Intent.CATEGORY_HOME);
+        }
+        return intent;
+    }
+
+    String getHomePackageName() {
+        Intent intent = getHomeIntent();
+        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, mCurrentUserId);
+        if (aInfo != null) {
+            final String homePackageName = aInfo.applicationInfo.packageName;
+            if (!ResolverActivity.class.getName().equals(homePackageName)) {
+                return homePackageName;
+            }
+        }
+        return null;
+    }
+
     boolean startHomeActivityLocked(int userId) {
         if (mHeadless) {
             // Added because none of the other calls to ensureBootCompleted seem to fire
@@ -2292,13 +2605,7 @@
             // error message and don't try to start anything.
             return false;
         }
-        Intent intent = new Intent(
-            mTopAction,
-            mTopData != null ? Uri.parse(mTopData) : null);
-        intent.setComponent(mTopComponent);
-        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
-            intent.addCategory(Intent.CATEGORY_HOME);
-        }
+        Intent intent = getHomeIntent();
         ActivityInfo aInfo =
             resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
         if (aInfo != null) {
@@ -2312,8 +2619,7 @@
                     aInfo.applicationInfo.uid);
             if (app == null || app.instrumentationClass == null) {
                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
-                mMainStack.startActivityLocked(null, intent, null, aInfo,
-                        null, null, 0, 0, 0, null, 0, null, false, null);
+                mStackSupervisor.startHomeActivity(intent, aInfo);
             }
         }
 
@@ -2331,7 +2637,7 @@
                         intent,
                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
                             flags, userId);
-    
+
                 if (info != null) {
                     ai = info.activityInfo;
                 }
@@ -2351,7 +2657,7 @@
         if (mCheckedForSetup) {
             return;
         }
-        
+
         // We will show this screen if the current one is a different
         // version than the last one shown, and we are not running in
         // low-level factory test mode.
@@ -2360,12 +2666,12 @@
                 Settings.Global.getInt(resolver,
                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
             mCheckedForSetup = true;
-            
+
             // See if we should be showing the platform update setup UI.
             Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
             List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
                     .queryIntentActivities(intent, PackageManager.GET_META_DATA);
-            
+
             // We don't allow third party apps to replace this.
             ResolveInfo ri = null;
             for (int i=0; ris != null && i<ris.size(); i++) {
@@ -2375,7 +2681,7 @@
                     break;
                 }
             }
-            
+
             if (ri != null) {
                 String vers = ri.activityInfo.metaData != null
                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
@@ -2390,13 +2696,13 @@
                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                     intent.setComponent(new ComponentName(
                             ri.activityInfo.packageName, ri.activityInfo.name));
-                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
+                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
                             null, null, 0, 0, 0, null, 0, null, false, null);
                 }
             }
         }
     }
-    
+
     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
     }
@@ -2407,6 +2713,7 @@
         }
     }
 
+    @Override
     public int getFrontActivityScreenCompatMode() {
         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
         synchronized (this) {
@@ -2414,6 +2721,7 @@
         }
     }
 
+    @Override
     public void setFrontActivityScreenCompatMode(int mode) {
         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
                 "setFrontActivityScreenCompatMode");
@@ -2422,6 +2730,7 @@
         }
     }
 
+    @Override
     public int getPackageScreenCompatMode(String packageName) {
         enforceNotIsolatedCaller("getPackageScreenCompatMode");
         synchronized (this) {
@@ -2429,6 +2738,7 @@
         }
     }
 
+    @Override
     public void setPackageScreenCompatMode(String packageName, int mode) {
         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
                 "setPackageScreenCompatMode");
@@ -2437,6 +2747,7 @@
         }
     }
 
+    @Override
     public boolean getPackageAskScreenCompat(String packageName) {
         enforceNotIsolatedCaller("getPackageAskScreenCompat");
         synchronized (this) {
@@ -2444,6 +2755,7 @@
         }
     }
 
+    @Override
     public void setPackageAskScreenCompat(String packageName, boolean ask) {
         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
                 "setPackageAskScreenCompat");
@@ -2452,11 +2764,6 @@
         }
     }
 
-    void reportResumedActivityLocked(ActivityRecord r) {
-        //Slog.i(TAG, "**** REPORT RESUME: " + r);
-        updateUsageStats(r, true);
-    }
-
     private void dispatchProcessesChanged() {
         int N;
         synchronized (this) {
@@ -2469,6 +2776,7 @@
             mPendingProcessChanges.clear();
             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
         }
+
         int i = mProcessObservers.beginBroadcast();
         while (i > 0) {
             i--;
@@ -2520,12 +2828,13 @@
         }
         for (int i=0; i<N; i++) {
             PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
-            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
-                    pal.startFlags, doResume && i == (N-1), null);
+            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
+                    doResume && i == (N-1), null);
         }
         mPendingActivityLaunches.clear();
     }
 
+    @Override
     public final int startActivity(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo,
             String resultWho, int requestCode, int startFlags,
@@ -2535,6 +2844,7 @@
                 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
     }
 
+    @Override
     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo,
             String resultWho, int requestCode, int startFlags,
@@ -2542,11 +2852,13 @@
         enforceNotIsolatedCaller("startActivity");
         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                 false, true, "startActivity", null);
-        return mMainStack.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
+        // TODO: Switch to user app stacks here.
+        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
                 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
                 null, null, options, userId);
     }
 
+    @Override
     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo,
             String resultWho, int requestCode, int startFlags, String profileFile,
@@ -2555,12 +2867,14 @@
         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                 false, true, "startActivityAndWait", null);
         WaitResult res = new WaitResult();
-        mMainStack.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
+        // TODO: Switch to user app stacks here.
+        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
                 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
                 res, null, options, UserHandle.getCallingUserId());
         return res;
     }
 
+    @Override
     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo,
             String resultWho, int requestCode, int startFlags, Configuration config,
@@ -2568,12 +2882,14 @@
         enforceNotIsolatedCaller("startActivityWithConfig");
         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                 false, true, "startActivityWithConfig", null);
-        int ret = mMainStack.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
-                resultTo, resultWho, requestCode, startFlags,
+        // TODO: Switch to user app stacks here.
+        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
+                resolvedType, resultTo, resultWho, requestCode, startFlags,
                 null, null, null, config, options, userId);
         return ret;
     }
 
+    @Override
     public int startActivityIntentSender(IApplicationThread caller,
             IntentSender intent, Intent fillInIntent, String resolvedType,
             IBinder resultTo, String resultWho, int requestCode,
@@ -2583,20 +2899,20 @@
         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
             throw new IllegalArgumentException("File descriptors passed in Intent");
         }
-        
+
         IIntentSender sender = intent.getTarget();
         if (!(sender instanceof PendingIntentRecord)) {
             throw new IllegalArgumentException("Bad PendingIntent object");
         }
-        
+
         PendingIntentRecord pir = (PendingIntentRecord)sender;
-        
+
         synchronized (this) {
             // If this is coming from the currently resumed activity, it is
             // effectively saying that app switches are allowed at this point.
-            if (mMainStack.mResumedActivity != null
-                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
-                            Binder.getCallingUid()) {
+            final ActivityStack stack = getFocusedStack();
+            if (stack.mResumedActivity != null &&
+                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
                 mAppSwitchesAllowedTime = 0;
             }
         }
@@ -2604,7 +2920,8 @@
                 resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
         return ret;
     }
-    
+
+    @Override
     public boolean startNextMatchingActivity(IBinder callingActivity,
             Intent intent, Bundle options) {
         // Refuse possible leaked file descriptors
@@ -2613,7 +2930,7 @@
         }
 
         synchronized (this) {
-            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
+            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
             if (r == null) {
                 ActivityOptions.abort(options);
                 return false;
@@ -2687,7 +3004,7 @@
             }
 
             final long origId = Binder.clearCallingIdentity();
-            int res = mMainStack.startActivityLocked(r.app.thread, intent,
+            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
                     r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
                     resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
                     options, false, null);
@@ -2708,19 +3025,22 @@
         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                 false, true, "startActivityInPackage", null);
 
-        int ret = mMainStack.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
+        // TODO: Switch to user app stacks here.
+        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
                 resultTo, resultWho, requestCode, startFlags,
                 null, null, null, null, options, userId);
         return ret;
     }
 
+    @Override
     public final int startActivities(IApplicationThread caller, String callingPackage,
             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
             int userId) {
         enforceNotIsolatedCaller("startActivities");
         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                 false, true, "startActivity", null);
-        int ret = mMainStack.startActivities(caller, -1, callingPackage, intents,
+        // TODO: Switch to user app stacks here.
+        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
                 resolvedTypes, resultTo, options, userId);
         return ret;
     }
@@ -2731,7 +3051,8 @@
 
         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                 false, true, "startActivityInPackage", null);
-        int ret = mMainStack.startActivities(null, uid, callingPackage, intents, resolvedTypes,
+        // TODO: Switch to user app stacks here.
+        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
                 resultTo, options, userId);
         return ret;
     }
@@ -2764,31 +3085,42 @@
         mRecentTasks.add(0, task);
     }
 
-    public void setRequestedOrientation(IBinder token,
-            int requestedOrientation) {
+    @Override
+    public void reportActivityFullyDrawn(IBinder token) {
         synchronized (this) {
-            ActivityRecord r = mMainStack.isInStackLocked(token);
+            ActivityRecord r = ActivityRecord.isInStackLocked(token);
+            if (r == null) {
+                return;
+            }
+            r.reportFullyDrawnLocked();
+        }
+    }
+
+    @Override
+    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
+        synchronized (this) {
+            ActivityRecord r = ActivityRecord.isInStackLocked(token);
             if (r == null) {
                 return;
             }
             final long origId = Binder.clearCallingIdentity();
             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
             Configuration config = mWindowManager.updateOrientationFromAppTokens(
-                    mConfiguration,
-                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
+                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
             if (config != null) {
                 r.frozenBeforeDestroy = true;
                 if (!updateConfigurationLocked(config, r, false, false)) {
-                    mMainStack.resumeTopActivityLocked(null);
+                    mStackSupervisor.resumeTopActivitiesLocked();
                 }
             }
             Binder.restoreCallingIdentity(origId);
         }
     }
 
+    @Override
     public int getRequestedOrientation(IBinder token) {
         synchronized (this) {
-            ActivityRecord r = mMainStack.isInStackLocked(token);
+            ActivityRecord r = ActivityRecord.isInStackLocked(token);
             if (r == null) {
                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
             }
@@ -2798,13 +3130,14 @@
 
     /**
      * This is the internal entry point for handling Activity.finish().
-     * 
+     *
      * @param token The Binder token referencing the Activity we want to finish.
      * @param resultCode Result code, if any, from this Activity.
      * @param resultData Result data (Intent), if any, from this Activity.
-     * 
+     *
      * @return Returns true if the activity successfully finished, or false if it is still running.
      */
+    @Override
     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
         // Refuse possible leaked file descriptors
         if (resultData != null && resultData.hasFileDescriptors() == true) {
@@ -2812,9 +3145,13 @@
         }
 
         synchronized(this) {
+            ActivityRecord r = ActivityRecord.isInStackLocked(token);
+            if (r == null) {
+                return true;
+            }
             if (mController != null) {
                 // Find the first activity that is not finishing.
-                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
+                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
                 if (next != null) {
                     // ask watcher if this is allowed
                     boolean resumeOK = true;
@@ -2824,20 +3161,21 @@
                         mController = null;
                         Watchdog.getInstance().setActivityController(null);
                     }
-    
+
                     if (!resumeOK) {
                         return false;
                     }
                 }
             }
             final long origId = Binder.clearCallingIdentity();
-            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
+            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
                     resultData, "app-request", true);
             Binder.restoreCallingIdentity(origId);
             return res;
         }
     }
 
+    @Override
     public final void finishHeavyWeightApp() {
         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
                 != PackageManager.PERMISSION_GRANTED) {
@@ -2848,31 +3186,29 @@
             Slog.w(TAG, msg);
             throw new SecurityException(msg);
         }
-        
+
         synchronized(this) {
             if (mHeavyWeightProcess == null) {
                 return;
             }
-            
+
             ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
                     mHeavyWeightProcess.activities);
             for (int i=0; i<activities.size(); i++) {
                 ActivityRecord r = activities.get(i);
                 if (!r.finishing) {
-                    int index = mMainStack.indexOfTokenLocked(r.appToken);
-                    if (index >= 0) {
-                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
-                                null, "finish-heavy", true);
-                    }
+                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
+                            null, "finish-heavy", true);
                 }
             }
-            
+
             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
                     mHeavyWeightProcess.userId, 0));
             mHeavyWeightProcess = null;
         }
     }
-    
+
+    @Override
     public void crashApplication(int uid, int initialPid, String packageName,
             String message) {
         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
@@ -2884,10 +3220,10 @@
             Slog.w(TAG, msg);
             throw new SecurityException(msg);
         }
-        
+
         synchronized(this) {
             ProcessRecord proc = null;
-            
+
             // Figure out which process to kill.  We don't trust that initialPid
             // still has any relation to current pids, so must scan through the
             // list.
@@ -2901,21 +3237,19 @@
                         proc = p;
                         break;
                     }
-                    for (String str : p.pkgList) {
-                        if (str.equals(packageName)) {
-                            proc = p;
-                        }
+                    if (p.pkgList.containsKey(packageName)) {
+                        proc = p;
                     }
                 }
             }
-            
+
             if (proc == null) {
                 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
                         + " initialPid=" + initialPid
                         + " packageName=" + packageName);
                 return;
             }
-            
+
             if (proc.thread != null) {
                 if (proc.pid == Process.myPid()) {
                     Log.w(TAG, "crashApplication: trying to crash self!");
@@ -2930,61 +3264,66 @@
             }
         }
     }
-    
+
+    @Override
     public final void finishSubActivity(IBinder token, String resultWho,
             int requestCode) {
         synchronized(this) {
             final long origId = Binder.clearCallingIdentity();
-            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
+            ActivityRecord r = ActivityRecord.isInStackLocked(token);
+            if (r != null) {
+                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
+            }
             Binder.restoreCallingIdentity(origId);
         }
     }
 
+    @Override
     public boolean finishActivityAffinity(IBinder token) {
         synchronized(this) {
             final long origId = Binder.clearCallingIdentity();
-            boolean res = mMainStack.finishActivityAffinityLocked(token);
+            ActivityRecord r = ActivityRecord.isInStackLocked(token);
+            boolean res = false;
+            if (r != null) {
+                res = r.task.stack.finishActivityAffinityLocked(r);
+            }
             Binder.restoreCallingIdentity(origId);
             return res;
         }
     }
 
+    @Override
     public boolean willActivityBeVisible(IBinder token) {
         synchronized(this) {
-            int i;
-            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
-                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
-                if (r.appToken == token) {
-                    return true;
-                }
-                if (r.fullscreen && !r.finishing) {
-                    return false;
-                }
+            ActivityStack stack = ActivityRecord.getStackLocked(token);
+            if (stack != null) {
+                return stack.willActivityBeVisibleLocked(token);
             }
-            return true;
+            return false;
         }
     }
-    
+
+    @Override
     public void overridePendingTransition(IBinder token, String packageName,
             int enterAnim, int exitAnim) {
         synchronized(this) {
-            ActivityRecord self = mMainStack.isInStackLocked(token);
+            ActivityRecord self = ActivityRecord.isInStackLocked(token);
             if (self == null) {
                 return;
             }
 
             final long origId = Binder.clearCallingIdentity();
-            
+
             if (self.state == ActivityState.RESUMED
                     || self.state == ActivityState.PAUSING) {
                 mWindowManager.overridePendingAppTransition(packageName,
                         enterAnim, exitAnim, null);
             }
-            
+
             Binder.restoreCallingIdentity(origId);
         }
     }
-    
+
     /**
      * Main function for removing an existing process from the activity manager
      * as a result of that process going away.  Clears out all connections
@@ -3001,21 +3340,10 @@
             clearProfilerLocked();
         }
 
-        // Just in case...
-        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
-            if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG,
-                    "App died while pausing: " + mMainStack.mPausingActivity);
-            mMainStack.mPausingActivity = null;
-        }
-        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
-            mMainStack.mLastPausedActivity = null;
-        }
-
-        // Remove this application's activities from active lists.
-        boolean hasVisibleActivities = mMainStack.removeHistoryRecordsForAppLocked(app);
+        mStackSupervisor.handleAppDiedLocked(app, restarting);
 
         app.activities.clear();
-        
+
         if (app.instrumentationClass != null) {
             Slog.w(TAG, "Crash of app " + app.processName
                   + " running instrumentation " + app.instrumentationClass);
@@ -3023,19 +3351,6 @@
             info.putString("shortMsg", "Process crashed.");
             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
         }
-
-        if (!restarting) {
-            if (!mMainStack.resumeTopActivityLocked(null)) {
-                // If there was nothing to resume, and we are not already
-                // restarting this process, but there is a visible activity that
-                // is hosted by the process...  then make sure all visible
-                // activities are running, taking care of restarting this
-                // process.
-                if (hasVisibleActivities) {
-                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
-                }
-            }
-        }
     }
 
     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
@@ -3060,11 +3375,71 @@
         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
     }
 
+    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
+        // If there are no longer any background processes running,
+        // and the app that died was not running instrumentation,
+        // then tell everyone we are now low on memory.
+        boolean haveBg = false;
+        for (int i=mLruProcesses.size()-1; i>=0; i--) {
+            ProcessRecord rec = mLruProcesses.get(i);
+            if (rec.thread != null
+                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
+                haveBg = true;
+                break;
+            }
+        }
+
+        if (!haveBg) {
+            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
+            if (doReport) {
+                long now = SystemClock.uptimeMillis();
+                if (now < (mLastMemUsageReportTime+5*60*1000)) {
+                    doReport = false;
+                } else {
+                    mLastMemUsageReportTime = now;
+                }
+            }
+            final ArrayList<ProcessMemInfo> memInfos
+                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
+            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
+            long now = SystemClock.uptimeMillis();
+            for (int i=mLruProcesses.size()-1; i>=0; i--) {
+                ProcessRecord rec = mLruProcesses.get(i);
+                if (rec == dyingProc || rec.thread == null) {
+                    continue;
+                }
+                if (doReport) {
+                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
+                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
+                }
+                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
+                    // The low memory report is overriding any current
+                    // state for a GC request.  Make sure to do
+                    // heavy/important/visible/foreground processes first.
+                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
+                        rec.lastRequestedGc = 0;
+                    } else {
+                        rec.lastRequestedGc = rec.lastLowMemory;
+                    }
+                    rec.reportLowMemory = true;
+                    rec.lastLowMemory = now;
+                    mProcessesToGc.remove(rec);
+                    addProcessToGcListLocked(rec);
+                }
+            }
+            if (doReport) {
+                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE, memInfos);
+                mHandler.sendMessage(msg);
+            }
+            scheduleAppGcsLocked();
+        }
+    }
+
     final void appDiedLocked(ProcessRecord app, int pid,
             IApplicationThread thread) {
 
         mProcDeaths[0]++;
-        
+
         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
         synchronized (stats) {
             stats.noteProcessDiedLocked(app.info.uid, pid);
@@ -3085,42 +3460,7 @@
             handleAppDiedLocked(app, false, true);
 
             if (doLowMem) {
-                // If there are no longer any background processes running,
-                // and the app that died was not running instrumentation,
-                // then tell everyone we are now low on memory.
-                boolean haveBg = false;
-                for (int i=mLruProcesses.size()-1; i>=0; i--) {
-                    ProcessRecord rec = mLruProcesses.get(i);
-                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
-                        haveBg = true;
-                        break;
-                    }
-                }
-                
-                if (!haveBg) {
-                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
-                    long now = SystemClock.uptimeMillis();
-                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
-                        ProcessRecord rec = mLruProcesses.get(i);
-                        if (rec != app && rec.thread != null &&
-                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
-                            // The low memory report is overriding any current
-                            // state for a GC request.  Make sure to do
-                            // heavy/important/visible/foreground processes first.
-                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
-                                rec.lastRequestedGc = 0;
-                            } else {
-                                rec.lastRequestedGc = rec.lastLowMemory;
-                            }
-                            rec.reportLowMemory = true;
-                            rec.lastLowMemory = now;
-                            mProcessesToGc.remove(rec);
-                            addProcessToGcListLocked(rec);
-                        }
-                    }
-                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
-                    scheduleAppGcsLocked();
-                }
+                doLowMemReportIfNeededLocked(app);
             }
         } else if (app.pid != pid) {
             // A new process has already been started.
@@ -3144,7 +3484,7 @@
      * @return file containing stack traces, or null if no dump file is configured
      */
     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
-            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
+            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
         if (tracesPath == null || tracesPath.length() == 0) {
             return null;
@@ -3169,15 +3509,16 @@
             return null;
         }
 
-        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
+        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
         return tracesFile;
     }
 
     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
-            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
+            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
         // Use a FileObserver to detect when traces finish writing.
         // The order of traces is considered important to maintain for legibility.
         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
+            @Override
             public synchronized void onEvent(int event, String path) { notify(); }
         };
 
@@ -3200,23 +3541,23 @@
             }
 
             // Next measure CPU usage.
-            if (processStats != null) {
-                processStats.init();
+            if (processCpuTracker != null) {
+                processCpuTracker.init();
                 System.gc();
-                processStats.update();
+                processCpuTracker.update();
                 try {
-                    synchronized (processStats) {
-                        processStats.wait(500); // measure over 1/2 second.
+                    synchronized (processCpuTracker) {
+                        processCpuTracker.wait(500); // measure over 1/2 second.
                     }
                 } catch (InterruptedException e) {
                 }
-                processStats.update();
+                processCpuTracker.update();
 
                 // We'll take the stack crawls of just the top apps using CPU.
-                final int N = processStats.countWorkingStats();
+                final int N = processCpuTracker.countWorkingStats();
                 int numProcs = 0;
                 for (int i=0; i<N && numProcs<5; i++) {
-                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
+                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
                     if (lastPids.indexOfKey(stats.pid) >= 0) {
                         numProcs++;
                         try {
@@ -3303,7 +3644,7 @@
             File lastTracesFile = null;
             File curTracesFile = null;
             for (int i=9; i>=0; i--) {
-                String name = String.format("slow%02d.txt", i);
+                String name = String.format(Locale.US, "slow%02d.txt", i);
                 curTracesFile = new File(tracesDir, name);
                 if (curTracesFile.exists()) {
                     if (lastTracesFile != null) {
@@ -3343,7 +3684,7 @@
         if (MONITOR_CPU_USAGE) {
             updateCpuStatsNow();
         }
-        
+
         synchronized (this) {
             // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
             if (mShuttingDown) {
@@ -3356,7 +3697,7 @@
                 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
                 return;
             }
-            
+
             // In case we come through here for the same app before completing
             // this one, mark as anring now so we will bail out.
             app.notResponding = true;
@@ -3367,11 +3708,11 @@
 
             // Dump thread traces as quickly as we can, starting with "interesting" processes.
             firstPids.add(app.pid);
-    
+
             int parentPid = app.pid;
             if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
             if (parentPid != app.pid) firstPids.add(parentPid);
-    
+
             if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
 
             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
@@ -3397,6 +3738,7 @@
             info.append(" (").append(activity.shortComponentName).append(")");
         }
         info.append("\n");
+        info.append("PID: ").append(app.pid).append("\n");
         if (annotation != null) {
             info.append("Reason: ").append(annotation).append("\n");
         }
@@ -3404,21 +3746,21 @@
             info.append("Parent: ").append(parent.shortComponentName).append("\n");
         }
 
-        final ProcessStats processStats = new ProcessStats(true);
+        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
 
-        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
+        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, null);
 
         String cpuInfo = null;
         if (MONITOR_CPU_USAGE) {
             updateCpuStatsNow();
-            synchronized (mProcessStatsThread) {
-                cpuInfo = mProcessStats.printCurrentState(anrTime);
+            synchronized (mProcessCpuThread) {
+                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
             }
-            info.append(processStats.printCurrentLoad());
+            info.append(processCpuTracker.printCurrentLoad());
             info.append(cpuInfo);
         }
 
-        info.append(processStats.printCurrentState(anrTime));
+        info.append(processCpuTracker.printCurrentState(anrTime));
 
         Slog.e(TAG, info.toString());
         if (tracesFile == null) {
@@ -3446,7 +3788,7 @@
         // Unless configured otherwise, swallow ANRs in background processes & kill the process.
         boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
                 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
-        
+
         synchronized (this) {
             if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
                 Slog.w(TAG, "Killing " + app + ": background ANR");
@@ -3455,16 +3797,16 @@
                 Process.killProcessQuiet(app.pid);
                 return;
             }
-    
+
             // Set the app's notResponding state, and look up the errorReportReceiver
             makeAppNotRespondingLocked(app,
                     activity != null ? activity.shortComponentName : null,
                     annotation != null ? "ANR " + annotation : "ANR",
                     info.toString());
-    
+
             // Bring up the infamous App Not Responding dialog
             Message msg = Message.obtain();
-            HashMap map = new HashMap();
+            HashMap<String, Object> map = new HashMap<String, Object>();
             msg.what = SHOW_NOT_RESPONDING_MSG;
             msg.obj = map;
             msg.arg1 = aboveSystem ? 1 : 0;
@@ -3472,7 +3814,7 @@
             if (activity != null) {
                 map.put("activity", activity);
             }
-    
+
             mHandler.sendMessage(msg);
         }
     }
@@ -3500,7 +3842,8 @@
             });
         }
     }
-    
+
+    @Override
     public boolean clearApplicationUserData(final String packageName,
             final IPackageDataObserver observer, int userId) {
         enforceNotIsolatedCaller("clearApplicationUserData");
@@ -3532,17 +3875,21 @@
                         android.Manifest.permission.CLEAR_APP_USER_DATA,
                         pid, uid, -1, true)
                         == PackageManager.PERMISSION_GRANTED) {
-                    forceStopPackageLocked(packageName, pkgUid);
+                    forceStopPackageLocked(packageName, pkgUid, "clear data");
                 } else {
                     throw new SecurityException(pid+" does not have permission:"+
                             android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
                                     "for process:"+packageName);
                 }
             }
-            
+
             try {
-                //clear application user data
+                // Clear application user data
                 pm.clearApplicationUserData(packageName, observer, userId);
+
+                // Remove all permissions granted from/to this package
+                removeUriPermissionsForPackageLocked(packageName, userId, true);
+
                 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
                         Uri.fromParts("package", packageName, null));
                 intent.putExtra(Intent.EXTRA_UID, pkgUid);
@@ -3556,6 +3903,7 @@
         return true;
     }
 
+    @Override
     public void killBackgroundProcesses(final String packageName, int userId) {
         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
                 != PackageManager.PERMISSION_GRANTED &&
@@ -3592,6 +3940,7 @@
         }
     }
 
+    @Override
     public void killAllBackgroundProcesses() {
         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
                 != PackageManager.PERMISSION_GRANTED) {
@@ -3602,12 +3951,14 @@
             Slog.w(TAG, msg);
             throw new SecurityException(msg);
         }
-        
+
         long callingId = Binder.clearCallingIdentity();
         try {
             synchronized(this) {
                 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
-                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
+                final int NP = mProcessNames.getMap().size();
+                for (int ip=0; ip<NP; ip++) {
+                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
                     final int NA = apps.size();
                     for (int ia=0; ia<NA; ia++) {
                         ProcessRecord app = apps.valueAt(ia);
@@ -3617,23 +3968,26 @@
                         }
                         if (app.removed) {
                             procs.add(app);
-                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
+                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
                             app.removed = true;
                             procs.add(app);
                         }
                     }
                 }
-                
+
                 int N = procs.size();
                 for (int i=0; i<N; i++) {
                     removeProcessLocked(procs.get(i), false, true, "kill all background");
                 }
+                updateOomAdjLocked();
+                doLowMemReportIfNeededLocked(null);
             }
         } finally {
             Binder.restoreCallingIdentity(callingId);
         }
     }
 
+    @Override
     public void forceStopPackage(final String packageName, int userId) {
         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
                 != PackageManager.PERMISSION_GRANTED) {
@@ -3644,7 +3998,8 @@
             Slog.w(TAG, msg);
             throw new SecurityException(msg);
         }
-        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
+        final int callingPid = Binder.getCallingPid();
+        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
                 userId, true, true, "forceStopPackage", null);
         long callingId = Binder.clearCallingIdentity();
         try {
@@ -3670,7 +4025,7 @@
                                 + packageName + ": " + e);
                     }
                     if (isUserRunningLocked(user, false)) {
-                        forceStopPackageLocked(packageName, pkgUid);
+                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
                     }
                 }
             }
@@ -3682,7 +4037,8 @@
     /*
      * The pkg name and app id have to be specified.
      */
-    public void killApplicationWithAppId(String pkg, int appid) {
+    @Override
+    public void killApplicationWithAppId(String pkg, int appid, String reason) {
         if (pkg == null) {
             return;
         }
@@ -3698,7 +4054,10 @@
             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
             msg.arg1 = appid;
             msg.arg2 = 0;
-            msg.obj = pkg;
+            Bundle bundle = new Bundle();
+            bundle.putString("pkg", pkg);
+            bundle.putString("reason", reason);
+            msg.obj = bundle;
             mHandler.sendMessage(msg);
         } else {
             throw new SecurityException(callerUid + " cannot kill pkg: " +
@@ -3706,6 +4065,7 @@
         }
     }
 
+    @Override
     public void closeSystemDialogs(String reason) {
         enforceNotIsolatedCaller("closeSystemDialogs");
 
@@ -3743,39 +4103,69 @@
         }
         mWindowManager.closeSystemDialogs(reason);
 
-        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
-            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
-            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
-                r.stack.finishActivityLocked(r, i,
-                        Activity.RESULT_CANCELED, null, "close-sys", true);
-            }
-        }
+        mStackSupervisor.closeSystemDialogsLocked();
 
         broadcastIntentLocked(null, null, intent, null,
                 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
                 Process.SYSTEM_UID, UserHandle.USER_ALL);
     }
 
-    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
-            throws RemoteException {
+    @Override
+    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
         enforceNotIsolatedCaller("getProcessMemoryInfo");
         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
         for (int i=pids.length-1; i>=0; i--) {
+            ProcessRecord proc;
+            int oomAdj;
+            synchronized (this) {
+                synchronized (mPidsSelfLocked) {
+                    proc = mPidsSelfLocked.get(pids[i]);
+                    oomAdj = proc != null ? proc.setAdj : 0;
+                }
+            }
             infos[i] = new Debug.MemoryInfo();
             Debug.getMemoryInfo(pids[i], infos[i]);
+            if (proc != null) {
+                synchronized (this) {
+                    if (proc.thread != null && proc.setAdj == oomAdj) {
+                        // Record this for posterity if the process has been stable.
+                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
+                                infos[i].getTotalUss(), false);
+                    }
+                }
+            }
         }
         return infos;
     }
 
-    public long[] getProcessPss(int[] pids) throws RemoteException {
+    @Override
+    public long[] getProcessPss(int[] pids) {
         enforceNotIsolatedCaller("getProcessPss");
         long[] pss = new long[pids.length];
         for (int i=pids.length-1; i>=0; i--) {
-            pss[i] = Debug.getPss(pids[i]);
+            ProcessRecord proc;
+            int oomAdj;
+            synchronized (this) {
+                synchronized (mPidsSelfLocked) {
+                    proc = mPidsSelfLocked.get(pids[i]);
+                    oomAdj = proc != null ? proc.setAdj : 0;
+                }
+            }
+            long[] tmpUss = new long[1];
+            pss[i] = Debug.getPss(pids[i], tmpUss);
+            if (proc != null) {
+                synchronized (this) {
+                    if (proc.thread != null && proc.setAdj == oomAdj) {
+                        // Record this for posterity if the process has been stable.
+                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false);
+                    }
+                }
+            }
         }
         return pss;
     }
 
+    @Override
     public void killApplicationProcess(String processName, int uid) {
         if (processName == null) {
             return;
@@ -3803,9 +4193,9 @@
         }
     }
 
-    private void forceStopPackageLocked(final String packageName, int uid) {
+    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
-                false, true, false, UserHandle.getUserId(uid));
+                false, true, false, UserHandle.getUserId(uid), reason);
         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
                 Uri.fromParts("package", packageName, null));
         if (!mProcessesReady) {
@@ -3820,8 +4210,8 @@
                 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
     }
 
-    private void forceStopUserLocked(int userId) {
-        forceStopPackageLocked(null, -1, false, false, true, false, userId);
+    private void forceStopUserLocked(int userId, String reason) {
+        forceStopPackageLocked(null, -1, false, false, true, false, userId, reason);
         Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
                 | Intent.FLAG_RECEIVER_FOREGROUND);
@@ -3841,7 +4231,9 @@
         // same UID (except for the system or root user), and all whose name
         // matches the package name.
         final String procNamePrefix = packageName != null ? (packageName + ":") : null;
-        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
+        final int NP = mProcessNames.getMap().size();
+        for (int ip=0; ip<NP; ip++) {
+            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
             final int NA = apps.size();
             for (int ia=0; ia<NA; ia++) {
                 ProcessRecord app = apps.valueAt(ia);
@@ -3880,7 +4272,7 @@
                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
                         continue;
                     }
-                    if (!app.pkgList.contains(packageName)) {
+                    if (!app.pkgList.containsKey(packageName)) {
                         continue;
                     }
                 }
@@ -3893,17 +4285,18 @@
                 procs.add(app);
             }
         }
-        
+
         int N = procs.size();
         for (int i=0; i<N; i++) {
             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
         }
+        updateOomAdjLocked();
         return N > 0;
     }
 
     private final boolean forceStopPackageLocked(String name, int appId,
             boolean callerWillRestart, boolean purgeCache, boolean doit,
-            boolean evenPersistent, int userId) {
+            boolean evenPersistent, int userId, String reason) {
         int i;
         int N;
 
@@ -3921,15 +4314,15 @@
 
         if (doit) {
             if (name != null) {
-                Slog.i(TAG, "Force stopping package " + name + " appid=" + appId
-                        + " user=" + userId);
+                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
+                        + " user=" + userId + ": " + reason);
             } else {
-                Slog.i(TAG, "Force stopping user " + userId);
+                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
             }
 
-            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
-            while (badApps.hasNext()) {
-                SparseArray<Long> ba = badApps.next();
+            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
+            for (int ip=pmap.size()-1; ip>=0; ip--) {
+                SparseArray<Long> ba = pmap.valueAt(ip);
                 for (i=ba.size()-1; i>=0; i--) {
                     boolean remove = false;
                     final int entUid = ba.keyAt(i);
@@ -3951,45 +4344,20 @@
                     }
                 }
                 if (ba.size() == 0) {
-                    badApps.remove();
+                    pmap.removeAt(ip);
                 }
             }
         }
 
         boolean didSomething = killPackageProcessesLocked(name, appId, userId,
                 -100, callerWillRestart, true, doit, evenPersistent,
-                name == null ? ("force stop user " + userId) : ("force stop " + name));
-        
-        TaskRecord lastTask = null;
-        for (i=0; i<mMainStack.mHistory.size(); i++) {
-            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
-            final boolean samePackage = r.packageName.equals(name)
-                    || (name == null && r.userId == userId);
-            if ((userId == UserHandle.USER_ALL || r.userId == userId)
-                    && (samePackage || r.task == lastTask)
-                    && (r.app == null || evenPersistent || !r.app.persistent)) {
-                if (!doit) {
-                    if (r.finishing) {
-                        // If this activity is just finishing, then it is not
-                        // interesting as far as something to stop.
-                        continue;
-                    }
-                    return true;
-                }
-                didSomething = true;
-                Slog.i(TAG, "  Force finishing activity " + r);
-                if (samePackage) {
-                    if (r.app != null) {
-                        r.app.removed = true;
-                    }
-                    r.app = null;
-                }
-                lastTask = r.task;
-                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
-                        null, "force-stop", true)) {
-                    i--;
-                }
+                name == null ? ("stop user " + userId) : ("stop " + name));
+
+        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
+            if (!doit) {
+                return true;
             }
+            didSomething = true;
         }
 
         if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
@@ -4017,6 +4385,9 @@
             removeDyingProviderLocked(null, providers.get(i), true);
         }
 
+        // Remove transient permissions granted from/to this package/user
+        removeUriPermissionsForPackageLocked(name, userId, false);
+
         if (name == null) {
             // Remove pending intents.  For now we only do this when force
             // stopping users, because we have some problems when doing this
@@ -4077,11 +4448,11 @@
                 }
             }
             if (mBooted) {
-                mMainStack.resumeTopActivityLocked(null);
-                mMainStack.scheduleIdleLocked();
+                mStackSupervisor.resumeTopActivitiesLocked();
+                mStackSupervisor.scheduleIdleLocked();
             }
         }
-        
+
         return didSomething;
     }
 
@@ -4111,7 +4482,7 @@
             handleAppDiedLocked(app, true, allowRestart);
             mLruProcesses.remove(app);
             Process.killProcessQuiet(pid);
-            
+
             if (app.persistent && !app.isolated) {
                 if (!callerWillRestart) {
                     addAppLocked(app.info, false);
@@ -4122,7 +4493,7 @@
         } else {
             mRemovedProcesses.add(app);
         }
-        
+
         return needRestart;
     }
 
@@ -4134,9 +4505,9 @@
             if (knownApp != null && knownApp.thread == null) {
                 mPidsSelfLocked.remove(pid);
                 gone = true;
-            }        
+            }
         }
-        
+
         if (gone) {
             Slog.w(TAG, "Process " + app + " failed to attach");
             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
@@ -4216,38 +4587,38 @@
         if (localLOGV) Slog.v(
                 TAG, "Binding process pid " + pid + " to record " + app);
 
-        String processName = app.processName;
+        final String processName = app.processName;
         try {
             AppDeathRecipient adr = new AppDeathRecipient(
                     app, pid, thread);
             thread.asBinder().linkToDeath(adr, 0);
             app.deathRecipient = adr;
         } catch (RemoteException e) {
-            app.resetPackageList();
+            app.resetPackageList(mProcessStats);
             startProcessLocked(app, "link fail", processName);
             return false;
         }
 
         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
-        
-        app.thread = thread;
+
+        app.makeActive(thread, mProcessStats);
         app.curAdj = app.setAdj = -100;
-        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
-        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
+        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
         app.forcingToForeground = null;
         app.foregroundServices = false;
         app.hasShownUi = false;
         app.debugging = false;
+        app.cached = false;
 
         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
 
         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
-        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
+        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
 
         if (!normalMode) {
             Slog.i(TAG, "Launching preboot mode app: " + app);
         }
-        
+
         if (localLOGV) Slog.v(
             TAG, "New app record " + app
             + " thread=" + thread.asBinder() + " pid=" + pid);
@@ -4285,7 +4656,7 @@
                         || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
                         || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
             }
-            
+
             ensurePackageDexOpt(app.instrumentationInfo != null
                     ? app.instrumentationInfo.packageName
                     : app.info.packageName);
@@ -4315,7 +4686,7 @@
             // an infinite loop of restarting processes...
             Slog.w(TAG, "Exception thrown during bind!", e);
 
-            app.resetPackageList();
+            app.resetPackageList(mProcessStats);
             app.unlinkDeathRecipient();
             startProcessLocked(app, "bind fail", processName);
             return false;
@@ -4331,23 +4702,13 @@
         boolean didSomething = false;
 
         // See if the top visible activity is waiting to run in this process...
-        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
-        if (hr != null && normalMode) {
-            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
-                    && processName.equals(hr.processName)) {
-                try {
-                    if (mHeadless) {
-                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
-                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
-                        didSomething = true;
-                    }
-                } catch (Exception e) {
-                    Slog.w(TAG, "Exception in new application when starting activity "
-                          + hr.intent.getComponent().flattenToShortString(), e);
-                    badApp = true;
+        if (normalMode) {
+            try {
+                if (mStackSupervisor.attachApplicationLocked(app, mHeadless)) {
+                    didSomething = true;
                 }
-            } else {
-                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
+            } catch (Exception e) {
+                badApp = true;
             }
         }
 
@@ -4363,7 +4724,7 @@
         // Check if a next-broadcast receiver is in this process...
         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
             try {
-                didSomething = sendPendingBroadcastsLocked(app);
+                didSomething |= sendPendingBroadcastsLocked(app);
             } catch (Exception e) {
                 // If the app died trying to launch the receiver we declare it 'bad'
                 badApp = true;
@@ -4398,6 +4759,7 @@
         return true;
     }
 
+    @Override
     public final void attachApplication(IApplicationThread thread) {
         synchronized (this) {
             int callingPid = Binder.getCallingPid();
@@ -4407,13 +4769,16 @@
         }
     }
 
+    @Override
     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
         final long origId = Binder.clearCallingIdentity();
-        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
-        if (stopProfiling) {
-            synchronized (this) {
-                if (mProfileProc == r.app) {
-                    if (mProfileFd != null) {
+        synchronized (this) {
+            ActivityStack stack = ActivityRecord.getStackLocked(token);
+            if (stack != null) {
+                ActivityRecord r =
+                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
+                if (stopProfiling) {
+                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
                         try {
                             mProfileFd.close();
                         } catch (IOException e) {
@@ -4436,11 +4801,13 @@
         }
     }
 
+    @Override
     public void showBootMessage(final CharSequence msg, final boolean always) {
         enforceNotIsolatedCaller("showBootMessage");
         mWindowManager.showBootMessage(msg, always);
     }
 
+    @Override
     public void dismissKeyguardOnNextActivity() {
         enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
         final long token = Binder.clearCallingIdentity();
@@ -4450,7 +4817,7 @@
                     mLockScreenShown = false;
                     comeOutOfSleepIfNeededLocked();
                 }
-                mMainStack.dismissKeyguardOnNextActivityLocked();
+                mStackSupervisor.setDismissKeyguard(true);
             }
         } finally {
             Binder.restoreCallingIdentity(token);
@@ -4468,7 +4835,8 @@
                 if (pkgs != null) {
                     for (String pkg : pkgs) {
                         synchronized (ActivityManagerService.this) {
-                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
+                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0,
+                                    "finished booting")) {
                                 setResultCode(Activity.RESULT_OK);
                                 return;
                             }
@@ -4506,8 +4874,19 @@
                         final int userId = mStartedUsers.keyAt(i);
                         Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
                         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
-                        broadcastIntentLocked(null, null, intent,
-                                null, null, 0, null, null,
+                        broadcastIntentLocked(null, null, intent, null,
+                                new IIntentReceiver.Stub() {
+                                    @Override
+                                    public void performReceive(Intent intent, int resultCode,
+                                            String data, Bundle extras, boolean ordered,
+                                            boolean sticky, int sendingUser) {
+                                        synchronized (ActivityManagerService.this) {
+                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
+                                                    true, false);
+                                        }
+                                    }
+                                },
+                                0, null, null,
                                 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
                                 AppOpsManager.OP_NONE, false, false, MY_PID, Process.SYSTEM_UID,
                                 userId);
@@ -4536,18 +4915,31 @@
         }
     }
 
+    @Override
     public final void activityResumed(IBinder token) {
         final long origId = Binder.clearCallingIdentity();
-        mMainStack.activityResumed(token);
+        synchronized(this) {
+            ActivityStack stack = ActivityRecord.getStackLocked(token);
+            if (stack != null) {
+                ActivityRecord.activityResumedLocked(token);
+            }
+        }
         Binder.restoreCallingIdentity(origId);
     }
 
+    @Override
     public final void activityPaused(IBinder token) {
         final long origId = Binder.clearCallingIdentity();
-        mMainStack.activityPaused(token, false);
+        synchronized(this) {
+            ActivityStack stack = ActivityRecord.getStackLocked(token);
+            if (stack != null) {
+                stack.activityPausedLocked(token, false);
+            }
+        }
         Binder.restoreCallingIdentity(origId);
     }
 
+    @Override
     public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
             CharSequence description) {
         if (localLOGV) Slog.v(
@@ -4563,9 +4955,9 @@
         final long origId = Binder.clearCallingIdentity();
 
         synchronized (this) {
-            r = mMainStack.isInStackLocked(token);
+            r = ActivityRecord.isInStackLocked(token);
             if (r != null) {
-                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
+                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
             }
         }
 
@@ -4578,11 +4970,18 @@
         Binder.restoreCallingIdentity(origId);
     }
 
+    @Override
     public final void activityDestroyed(IBinder token) {
         if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
-        mMainStack.activityDestroyed(token);
+        synchronized (this) {
+            ActivityStack stack = ActivityRecord.getStackLocked(token);
+            if (stack != null) {
+                stack.activityDestroyedLocked(token);
+            }
+        }
     }
     
+    @Override
     public String getCallingPackage(IBinder token) {
         synchronized (this) {
             ActivityRecord r = getCallingRecordLocked(token);
@@ -4590,6 +4989,7 @@
         }
     }
 
+    @Override
     public ComponentName getCallingActivity(IBinder token) {
         synchronized (this) {
             ActivityRecord r = getCallingRecordLocked(token);
@@ -4598,16 +4998,17 @@
     }
 
     private ActivityRecord getCallingRecordLocked(IBinder token) {
-        ActivityRecord r = mMainStack.isInStackLocked(token);
+        ActivityRecord r = ActivityRecord.isInStackLocked(token);
         if (r == null) {
             return null;
         }
         return r.resultTo;
     }
 
+    @Override
     public ComponentName getActivityClassForToken(IBinder token) {
         synchronized(this) {
-            ActivityRecord r = mMainStack.isInStackLocked(token);
+            ActivityRecord r = ActivityRecord.isInStackLocked(token);
             if (r == null) {
                 return null;
             }
@@ -4615,9 +5016,10 @@
         }
     }
 
+    @Override
     public String getPackageForToken(IBinder token) {
         synchronized(this) {
-            ActivityRecord r = mMainStack.isInStackLocked(token);
+            ActivityRecord r = ActivityRecord.isInStackLocked(token);
             if (r == null) {
                 return null;
             }
@@ -4625,6 +5027,7 @@
         }
     }
 
+    @Override
     public IIntentSender getIntentSender(int type,
             String packageName, IBinder token, String resultWho,
             int requestCode, Intent[] intents, String[] resolvedTypes,
@@ -4695,7 +5098,7 @@
             }
         }
     }
-    
+
     IIntentSender getIntentSenderLocked(int type, String packageName,
             int callingUid, int userId, IBinder token, String resultWho,
             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
@@ -4704,7 +5107,7 @@
             Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
         ActivityRecord activity = null;
         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
-            activity = mMainStack.isInStackLocked(token);
+            activity = ActivityRecord.isInStackLocked(token);
             if (activity == null) {
                 return null;
             }
@@ -4761,6 +5164,7 @@
         return rec;
     }
 
+    @Override
     public void cancelIntentSender(IIntentSender sender) {
         if (!(sender instanceof PendingIntentRecord)) {
             return;
@@ -4794,6 +5198,7 @@
         }
     }
 
+    @Override
     public String getPackageForIntentSender(IIntentSender pendingResult) {
         if (!(pendingResult instanceof PendingIntentRecord)) {
             return null;
@@ -4806,6 +5211,7 @@
         return null;
     }
 
+    @Override
     public int getUidForIntentSender(IIntentSender sender) {
         if (sender instanceof PendingIntentRecord) {
             try {
@@ -4817,6 +5223,7 @@
         return -1;
     }
 
+    @Override
     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
         if (!(pendingResult instanceof PendingIntentRecord)) {
             return false;
@@ -4838,6 +5245,7 @@
         return false;
     }
 
+    @Override
     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
         if (!(pendingResult instanceof PendingIntentRecord)) {
             return false;
@@ -4853,6 +5261,7 @@
         return false;
     }
 
+    @Override
     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
         if (!(pendingResult instanceof PendingIntentRecord)) {
             return null;
@@ -4865,16 +5274,18 @@
         return null;
     }
 
+    @Override
     public void setProcessLimit(int max) {
         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
                 "setProcessLimit()");
         synchronized (this) {
-            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
+            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
             mProcessLimitOverride = max;
         }
         trimApplications();
     }
 
+    @Override
     public int getProcessLimit() {
         synchronized (this) {
             return mProcessLimitOverride;
@@ -4900,7 +5311,8 @@
             updateOomAdjLocked();
         }
     }
-    
+
+    @Override
     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
                 "setProcessForeground()");
@@ -4924,6 +5336,7 @@
                 }
                 if (isForeground && token != null) {
                     ForegroundToken newToken = new ForegroundToken() {
+                        @Override
                         public void binderDied() {
                             foregroundTokenDied(this);
                         }
@@ -4958,6 +5371,7 @@
             mActivityManagerService = activityManagerService;
         }
 
+        @Override
         public boolean checkPermission(String permission, int pid, int uid) {
             return mActivityManagerService.checkPermission(permission, pid,
                     uid) == PackageManager.PERMISSION_GRANTED;
@@ -4965,12 +5379,14 @@
     }
 
     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
+        @Override
         public int checkComponentPermission(String permission, int pid, int uid,
                 int owningUid, boolean exported) {
             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
                     owningUid, exported);
         }
 
+        @Override
         public Object getAMSLock() {
             return ActivityManagerService.this;
         }
@@ -5009,6 +5425,7 @@
      * 
      * This can be called with or without the global lock held.
      */
+    @Override
     public int checkPermission(String permission, int pid, int uid) {
         if (permission == null) {
             return PackageManager.PERMISSION_DENIED;
@@ -5130,19 +5547,52 @@
         return readMet && writeMet;
     }
 
+    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
+        ProviderInfo pi = null;
+        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
+        if (cpr != null) {
+            pi = cpr.info;
+        } else {
+            try {
+                pi = AppGlobals.getPackageManager().resolveContentProvider(
+                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
+            } catch (RemoteException ex) {
+            }
+        }
+        return pi;
+    }
+
+    private UriPermission findOrCreateUriPermissionLocked(
+            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
+        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
+        if (targetUris == null) {
+            targetUris = Maps.newArrayMap();
+            mGrantedUriPermissions.put(targetUid, targetUris);
+        }
+
+        UriPermission perm = targetUris.get(uri);
+        if (perm == null) {
+            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
+            targetUris.put(uri, perm);
+        }
+
+        return perm;
+    }
+
     private final boolean checkUriPermissionLocked(Uri uri, int uid,
             int modeFlags) {
         // Root gets to do everything.
         if (uid == 0) {
             return true;
         }
-        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
+        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
         if (perms == null) return false;
         UriPermission perm = perms.get(uri);
         if (perm == null) return false;
         return (modeFlags&perm.modeFlags) == modeFlags;
     }
 
+    @Override
     public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
         enforceNotIsolatedCaller("checkUriPermission");
 
@@ -5176,6 +5626,7 @@
      */
     int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
             Uri uri, int modeFlags, int lastTargetUid) {
+        final boolean persist = (modeFlags & Intent.FLAG_PERSIST_GRANT_URI_PERMISSION) != 0;
         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
         if (modeFlags == 0) {
@@ -5196,20 +5647,8 @@
             return -1;
         }
 
-        String name = uri.getAuthority();
-        ProviderInfo pi = null;
-        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
-                UserHandle.getUserId(callingUid));
-        if (cpr != null) {
-            pi = cpr.info;
-        } else {
-            try {
-                pi = pm.resolveContentProvider(name,
-                        PackageManager.GET_URI_PERMISSION_PATTERNS,
-                        UserHandle.getUserId(callingUid));
-            } catch (RemoteException ex) {
-            }
-        }
+        final String authority = uri.getAuthority();
+        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
         if (pi == null) {
             Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
             return -1;
@@ -5231,7 +5670,7 @@
 
         if (targetUid >= 0) {
             // First...  does the target actually need this permission?
-            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
+            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags) && !persist) {
                 // No need to grant the target this permission.
                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
                         "Target " + targetPkg + " already has full permission to " + uri);
@@ -5250,7 +5689,7 @@
                     allowed = false;
                 }
             }
-            if (allowed) {
+            if (allowed && !persist) {
                 return -1;
             }
         }
@@ -5294,6 +5733,7 @@
         return targetUid;
     }
 
+    @Override
     public int checkGrantUriPermission(int callingUid, String targetPkg,
             Uri uri, int modeFlags) {
         enforceNotIsolatedCaller("checkGrantUriPermission");
@@ -5302,8 +5742,9 @@
         }
     }
 
-    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
-            Uri uri, int modeFlags, UriPermissionOwner owner) {
+    void grantUriPermissionUncheckedLocked(
+            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
+        final boolean persist = (modeFlags & Intent.FLAG_PERSIST_GRANT_URI_PERMISSION) != 0;
         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
         if (modeFlags == 0) {
@@ -5316,32 +5757,20 @@
 
         if (DEBUG_URI_PERMISSION) Slog.v(TAG, 
                 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
-        
-        HashMap<Uri, UriPermission> targetUris
-                = mGrantedUriPermissions.get(targetUid);
-        if (targetUris == null) {
-            targetUris = new HashMap<Uri, UriPermission>();
-            mGrantedUriPermissions.put(targetUid, targetUris);
+
+        final String authority = uri.getAuthority();
+        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
+        if (pi == null) {
+            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
+            return;
         }
 
-        UriPermission perm = targetUris.get(uri);
-        if (perm == null) {
-            perm = new UriPermission(targetUid, uri);
-            targetUris.put(uri, perm);
-        }
-
-        perm.modeFlags |= modeFlags;
-        if (owner == null) {
-            perm.globalModeFlags |= modeFlags;
-        } else {
-            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
-                 perm.readOwners.add(owner);
-                 owner.addReadPermission(perm);
-            }
-            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
-                 perm.writeOwners.add(owner);
-                 owner.addWritePermission(perm);
-            }
+        final UriPermission perm = findOrCreateUriPermissionLocked(
+                pi.packageName, targetPkg, targetUid, uri);
+        final boolean persistChanged = perm.grantModes(modeFlags, persist, owner);
+        if (persistChanged) {
+            mHandler.removeMessages(PERSIST_URI_GRANTS);
+            mHandler.obtainMessage(PERSIST_URI_GRANTS).sendToTarget();
         }
     }
 
@@ -5364,10 +5793,10 @@
         final int targetUid;
         final int flags;
 
-        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
-            targetPkg = _targetPkg;
-            targetUid = _targetUid;
-            flags = _flags;
+        NeededUriGrants(String targetPkg, int targetUid, int flags) {
+            this.targetPkg = targetPkg;
+            this.targetUid = targetUid;
+            this.flags = flags;
         }
     }
 
@@ -5395,11 +5824,11 @@
             return null;
         }
         if (data != null) {
-            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
+            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
                 mode, needed != null ? needed.targetUid : -1);
-            if (target > 0) {
+            if (targetUid > 0) {
                 if (needed == null) {
-                    needed = new NeededUriGrants(targetPkg, target, mode);
+                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
                 }
                 needed.add(data);
             }
@@ -5408,12 +5837,12 @@
             for (int i=0; i<clip.getItemCount(); i++) {
                 Uri uri = clip.getItemAt(i).getUri();
                 if (uri != null) {
-                    int target = -1;
-                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
+                    int targetUid = -1;
+                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
                             mode, needed != null ? needed.targetUid : -1);
-                    if (target > 0) {
+                    if (targetUid > 0) {
                         if (needed == null) {
-                            needed = new NeededUriGrants(targetPkg, target, mode);
+                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
                         }
                         needed.add(uri);
                     }
@@ -5457,6 +5886,7 @@
         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
     }
 
+    @Override
     public void grantUriPermission(IApplicationThread caller, String targetPkg,
             Uri uri, int modeFlags) {
         enforceNotIsolatedCaller("grantUriPermission");
@@ -5482,45 +5912,26 @@
     void removeUriPermissionIfNeededLocked(UriPermission perm) {
         if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
                 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
-            HashMap<Uri, UriPermission> perms
-                    = mGrantedUriPermissions.get(perm.uid);
+            ArrayMap<Uri, UriPermission> perms
+                    = mGrantedUriPermissions.get(perm.targetUid);
             if (perms != null) {
                 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 
-                        "Removing " + perm.uid + " permission to " + perm.uri);
+                        "Removing " + perm.targetUid + " permission to " + perm.uri);
                 perms.remove(perm.uri);
                 if (perms.size() == 0) {
-                    mGrantedUriPermissions.remove(perm.uid);
+                    mGrantedUriPermissions.remove(perm.targetUid);
                 }
             }
         }
     }
 
-    private void revokeUriPermissionLocked(int callingUid, Uri uri,
-            int modeFlags) {
-        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
-                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
-        if (modeFlags == 0) {
-            return;
-        }
+    private void revokeUriPermissionLocked(
+            int callingUid, Uri uri, int modeFlags, boolean persist) {
+        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
 
-        if (DEBUG_URI_PERMISSION) Slog.v(TAG, 
-                "Revoking all granted permissions to " + uri);
-        
         final IPackageManager pm = AppGlobals.getPackageManager();
-
         final String authority = uri.getAuthority();
-        ProviderInfo pi = null;
-        int userId = UserHandle.getUserId(callingUid);
-        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
-        if (cpr != null) {
-            pi = cpr.info;
-        } else {
-            try {
-                pi = pm.resolveContentProvider(authority,
-                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
-            } catch (RemoteException ex) {
-            }
-        }
+        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
         if (pi == null) {
             Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
             return;
@@ -5536,13 +5947,15 @@
             //}
         }
 
+        boolean persistChanged = false;
+
         // Go through all of the permissions and remove any that match.
         final List<String> SEGMENTS = uri.getPathSegments();
         if (SEGMENTS != null) {
             final int NS = SEGMENTS.size();
             int N = mGrantedUriPermissions.size();
             for (int i=0; i<N; i++) {
-                HashMap<Uri, UriPermission> perms
+                ArrayMap<Uri, UriPermission> perms
                         = mGrantedUriPermissions.valueAt(i);
                 Iterator<UriPermission> it = perms.values().iterator();
             toploop:
@@ -5565,8 +5978,8 @@
                         }
                     }
                     if (DEBUG_URI_PERMISSION) Slog.v(TAG, 
-                            "Revoking " + perm.uid + " permission to " + perm.uri);
-                    perm.clearModes(modeFlags);
+                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
+                    persistChanged |= perm.clearModes(modeFlags, persist);
                     if (perm.modeFlags == 0) {
                         it.remove();
                     }
@@ -5579,8 +5992,14 @@
                 }
             }
         }
+
+        if (persistChanged) {
+            mHandler.removeMessages(PERSIST_URI_GRANTS);
+            mHandler.obtainMessage(PERSIST_URI_GRANTS).sendToTarget();
+        }
     }
 
+    @Override
     public void revokeUriPermission(IApplicationThread caller, Uri uri,
             int modeFlags) {
         enforceNotIsolatedCaller("revokeUriPermission");
@@ -5596,6 +6015,7 @@
                 return;
             }
 
+            final boolean persist = (modeFlags & Intent.FLAG_PERSIST_GRANT_URI_PERMISSION) != 0;
             modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
             if (modeFlags == 0) {
@@ -5603,26 +6023,64 @@
             }
 
             final IPackageManager pm = AppGlobals.getPackageManager();
-
             final String authority = uri.getAuthority();
-            ProviderInfo pi = null;
-            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
-            if (cpr != null) {
-                pi = cpr.info;
-            } else {
-                try {
-                    pi = pm.resolveContentProvider(authority,
-                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
-                } catch (RemoteException ex) {
-                }
-            }
+            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
             if (pi == null) {
                 Slog.w(TAG, "No content provider found for permission revoke: "
                         + uri.toSafeString());
                 return;
             }
 
-            revokeUriPermissionLocked(r.uid, uri, modeFlags);
+            revokeUriPermissionLocked(r.uid, uri, modeFlags, persist);
+        }
+    }
+
+    /**
+     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
+     * given package.
+     *
+     * @param packageName Package name to match, or {@code null} to apply to all
+     *            packages.
+     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
+     *            to all users.
+     * @param persist If persistent grants should be removed.
+     */
+    private void removeUriPermissionsForPackageLocked(
+            String packageName, int userHandle, boolean persist) {
+        if (userHandle == UserHandle.USER_ALL && packageName == null) {
+            throw new IllegalArgumentException("Must narrow by either package or user");
+        }
+
+        boolean persistChanged = false;
+
+        final int size = mGrantedUriPermissions.size();
+        for (int i = 0; i < size; i++) {
+            // Only inspect grants matching user
+            if (userHandle == UserHandle.USER_ALL
+                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
+                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
+                        .values().iterator();
+                while (it.hasNext()) {
+                    final UriPermission perm = it.next();
+
+                    // Only inspect grants matching package
+                    if (packageName == null || perm.sourcePkg.equals(packageName)
+                            || perm.targetPkg.equals(packageName)) {
+                        persistChanged |= perm.clearModes(~0, persist);
+
+                        // Only remove when no modes remain; any persisted grants
+                        // will keep this alive.
+                        if (perm.modeFlags == 0) {
+                            it.remove();
+                        }
+                    }
+                }
+            }
+        }
+
+        if (persistChanged) {
+            mHandler.removeMessages(PERSIST_URI_GRANTS);
+            mHandler.obtainMessage(PERSIST_URI_GRANTS).sendToTarget();
         }
     }
 
@@ -5677,6 +6135,149 @@
         }
     }
 
+    private void writeGrantedUriPermissions() {
+        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
+
+        // Snapshot permissions so we can persist without lock
+        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
+        synchronized (this) {
+            final int size = mGrantedUriPermissions.size();
+            for (int i = 0 ; i < size; i++) {
+                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
+                    if (perm.persistedModeFlags != 0) {
+                        persist.add(perm.snapshot());
+                    }
+                }
+            }
+        }
+
+        FileOutputStream fos = null;
+        try {
+            fos = mGrantFile.startWrite();
+
+            XmlSerializer out = new FastXmlSerializer();
+            out.setOutput(fos, "utf-8");
+            out.startDocument(null, true);
+            out.startTag(null, TAG_URI_GRANTS);
+            for (UriPermission.Snapshot perm : persist) {
+                out.startTag(null, TAG_URI_GRANT);
+                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
+                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
+                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
+                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
+                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
+                out.endTag(null, TAG_URI_GRANT);
+            }
+            out.endTag(null, TAG_URI_GRANTS);
+            out.endDocument();
+
+            mGrantFile.finishWrite(fos);
+        } catch (IOException e) {
+            if (fos != null) {
+                mGrantFile.failWrite(fos);
+            }
+        }
+    }
+
+    private void readGrantedUriPermissionsLocked() {
+        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
+
+        FileInputStream fis = null;
+        try {
+            fis = mGrantFile.openRead();
+            final XmlPullParser in = Xml.newPullParser();
+            in.setInput(fis, null);
+
+            int type;
+            while ((type = in.next()) != END_DOCUMENT) {
+                final String tag = in.getName();
+                if (type == START_TAG) {
+                    if (TAG_URI_GRANT.equals(tag)) {
+                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
+                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
+                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
+                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
+                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
+
+                        // Sanity check that provider still belongs to source package
+                        final ProviderInfo pi = getProviderInfoLocked(
+                                uri.getAuthority(), userHandle);
+                        if (pi != null && sourcePkg.equals(pi.packageName)) {
+                            int targetUid = -1;
+                            try {
+                                targetUid = AppGlobals.getPackageManager()
+                                        .getPackageUid(targetPkg, userHandle);
+                            } catch (RemoteException e) {
+                            }
+                            if (targetUid != -1) {
+                                final UriPermission perm = findOrCreateUriPermissionLocked(
+                                        sourcePkg, targetPkg, targetUid, uri);
+                                perm.grantModes(modeFlags, true, null);
+                            }
+                        } else {
+                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
+                                    + " but instead found " + pi);
+                        }
+                    }
+                }
+            }
+        } catch (FileNotFoundException e) {
+            // Missing grants is okay
+        } catch (IOException e) {
+            Log.wtf(TAG, "Failed reading Uri grants", e);
+        } catch (XmlPullParserException e) {
+            Log.wtf(TAG, "Failed reading Uri grants", e);
+        } finally {
+            IoUtils.closeQuietly(fis);
+        }
+    }
+
+    @Override
+    public Uri[] getGrantedUriPermissions(
+            String sourcePackage, String targetPackage, int modeFlags, int modeMask) {
+        enforceNotIsolatedCaller("getGrantedUriPermissions");
+        synchronized (this) {
+            // Verify that caller owns at least one of the requested packages
+            final int uid = Binder.getCallingUid();
+            final IPackageManager pm = AppGlobals.getPackageManager();
+            final String[] callerPackages;
+            try {
+                callerPackages = pm.getPackagesForUid(uid);
+            } catch (RemoteException e) {
+                throw new SecurityException("Failed to find packages for UID " + uid);
+            }
+            final boolean callerOwnsSource = sourcePackage != null
+                    && ArrayUtils.contains(callerPackages, sourcePackage);
+            final boolean callerOwnsTarget = targetPackage != null
+                    && ArrayUtils.contains(callerPackages, targetPackage);
+            if (!(callerOwnsSource || callerOwnsTarget)) {
+                throw new SecurityException("Caller " + Arrays.toString(callerPackages)
+                        + " doesn't own " + sourcePackage + " or " + targetPackage);
+            }
+
+            final ArrayList<Uri> result = Lists.newArrayList();
+            final int size = mGrantedUriPermissions.size();
+            for (int i = 0; i < size; i++) {
+                final ArrayMap<Uri, UriPermission> map = mGrantedUriPermissions.valueAt(i);
+                final int mapSize = map.size();
+                for (int j = 0; j < mapSize; j++) {
+                    final UriPermission perm = map.valueAt(j);
+                    final boolean sourceMatch = sourcePackage == null
+                            || sourcePackage.equals(perm.sourcePkg);
+                    final boolean targetMatch = targetPackage == null
+                            || targetPackage.equals(perm.targetPkg);
+                    final boolean modeMatch = (perm.modeFlags & modeMask) == modeFlags;
+                    if (sourceMatch && targetMatch && modeMatch) {
+                        result.add(perm.uri);
+                    }
+                }
+            }
+
+            return result.toArray(new Uri[result.size()]);
+        }
+    }
+
+    @Override
     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
         synchronized (this) {
             ProcessRecord app =
@@ -5691,14 +6292,15 @@
         }
     }
 
+    @Override
     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
-        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
+        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
         outInfo.availMem = Process.getFreeMemory();
         outInfo.totalMem = Process.getTotalMemory();
         outInfo.threshold = homeAppMem;
-        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
-        outInfo.hiddenAppThreshold = hiddenAppMem;
+        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
+        outInfo.hiddenAppThreshold = cachedAppMem;
         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
                 ProcessList.SERVICE_ADJ);
         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
@@ -5711,12 +6313,12 @@
     // TASK MANAGEMENT
     // =========================================================
 
-    public List getTasks(int maxNum, int flags,
+    @Override
+    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
                          IThumbnailReceiver receiver) {
-        ArrayList list = new ArrayList();
+        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
 
-        PendingThumbnailsRecord pending = null;
-        IApplicationThread topThumbnail = null;
+        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
         ActivityRecord topRecord = null;
 
         synchronized(this) {
@@ -5742,88 +6344,20 @@
                 throw new SecurityException(msg);
             }
 
-            int pos = mMainStack.mHistory.size()-1;
-            ActivityRecord next =
-                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
-            ActivityRecord top = null;
-            TaskRecord curTask = null;
-            int numActivities = 0;
-            int numRunning = 0;
-            while (pos >= 0 && maxNum > 0) {
-                final ActivityRecord r = next;
-                pos--;
-                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
+            // TODO: Improve with MRU list from all ActivityStacks.
+            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
 
-                // Initialize state for next task if needed.
-                if (top == null ||
-                        (top.state == ActivityState.INITIALIZING
-                            && top.task == r.task)) {
-                    top = r;
-                    curTask = r.task;
-                    numActivities = numRunning = 0;
-                }
-
-                // Add 'r' into the current task.
-                numActivities++;
-                if (r.app != null && r.app.thread != null) {
-                    numRunning++;
-                }
-
-                if (localLOGV) Slog.v(
-                    TAG, r.intent.getComponent().flattenToShortString()
-                    + ": task=" + r.task);
-
-                // If the next one is a different task, generate a new
-                // TaskInfo entry for what we have.
-                if (next == null || next.task != curTask) {
-                    ActivityManager.RunningTaskInfo ci
-                            = new ActivityManager.RunningTaskInfo();
-                    ci.id = curTask.taskId;
-                    ci.baseActivity = r.intent.getComponent();
-                    ci.topActivity = top.intent.getComponent();
-                    if (top.thumbHolder != null) {
-                        ci.description = top.thumbHolder.lastDescription;
-                    }
-                    ci.numActivities = numActivities;
-                    ci.numRunning = numRunning;
-                    //System.out.println(
-                    //    "#" + maxNum + ": " + " descr=" + ci.description);
-                    if (ci.thumbnail == null && receiver != null) {
-                        if (localLOGV) Slog.v(
-                            TAG, "State=" + top.state + "Idle=" + top.idle
-                            + " app=" + top.app
-                            + " thr=" + (top.app != null ? top.app.thread : null));
-                        if (top.state == ActivityState.RESUMED
-                                || top.state == ActivityState.PAUSING) {
-                            if (top.idle && top.app != null
-                                && top.app.thread != null) {
-                                topRecord = top;
-                                topThumbnail = top.app.thread;
-                            } else {
-                                top.thumbnailNeeded = true;
-                            }
-                        }
-                        if (pending == null) {
-                            pending = new PendingThumbnailsRecord(receiver);
-                        }
-                        pending.pendingRecords.add(top);
-                    }
-                    list.add(ci);
-                    maxNum--;
-                    top = null;
-                }
-            }
-
-            if (pending != null) {
+            if (!pending.pendingRecords.isEmpty()) {
                 mPendingThumbnails.add(pending);
             }
         }
 
         if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
 
-        if (topThumbnail != null) {
+        if (topRecord != null) {
             if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
             try {
+                IApplicationThread topThumbnail = topRecord.app.thread;
                 topThumbnail.requestThumbnail(topRecord.appToken);
             } catch (Exception e) {
                 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
@@ -5845,6 +6379,7 @@
         return list;
     }
 
+    @Override
     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
             int flags, int userId) {
         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
@@ -5889,7 +6424,8 @@
                     }
                     rti.origActivity = tr.origActivity;
                     rti.description = tr.lastDescription;
-                    
+                    rti.stackId = tr.stack.mStackId;
+
                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
                         // Check whether this activity is currently available.
                         try {
@@ -5917,49 +6453,55 @@
         }
     }
 
-    private TaskRecord taskForIdLocked(int id) {
+    private TaskRecord recentTaskForIdLocked(int id) {
         final int N = mRecentTasks.size();
-        for (int i=0; i<N; i++) {
-            TaskRecord tr = mRecentTasks.get(i);
-            if (tr.taskId == id) {
-                return tr;
+            for (int i=0; i<N; i++) {
+                TaskRecord tr = mRecentTasks.get(i);
+                if (tr.taskId == id) {
+                    return tr;
+                }
             }
-        }
-        return null;
+            return null;
     }
 
+    @Override
     public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
         synchronized (this) {
             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
                     "getTaskThumbnails()");
-            TaskRecord tr = taskForIdLocked(id);
+            TaskRecord tr = recentTaskForIdLocked(id);
             if (tr != null) {
-                return mMainStack.getTaskThumbnailsLocked(tr);
+                return tr.getTaskThumbnailsLocked();
             }
         }
         return null;
     }
 
+    @Override
     public Bitmap getTaskTopThumbnail(int id) {
         synchronized (this) {
             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
                     "getTaskTopThumbnail()");
-            TaskRecord tr = taskForIdLocked(id);
+            TaskRecord tr = recentTaskForIdLocked(id);
             if (tr != null) {
-                return mMainStack.getTaskTopThumbnailLocked(tr);
+                return tr.getTaskTopThumbnailLocked();
             }
         }
         return null;
     }
 
+    @Override
     public boolean removeSubTask(int taskId, int subTaskIndex) {
         synchronized (this) {
             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
                     "removeSubTask()");
             long ident = Binder.clearCallingIdentity();
             try {
-                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
-                        true) != null;
+                TaskRecord tr = recentTaskForIdLocked(taskId);
+                if (tr != null) {
+                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
+                }
+                return false;
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -5967,6 +6509,8 @@
     }
 
     private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
+        mRecentTasks.remove(tr);
+        mStackSupervisor.removeTask(tr);
         final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
         Intent baseIntent = new Intent(
                 tr.intent != null ? tr.intent : tr.affinityIntent);
@@ -5983,14 +6527,15 @@
             // Find any running processes associated with this app.
             final String pkg = component.getPackageName();
             ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
-            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
-            for (SparseArray<ProcessRecord> uids : pmap.values()) {
-                for (int i=0; i<uids.size(); i++) {
-                    ProcessRecord proc = uids.valueAt(i);
+            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
+            for (int i=0; i<pmap.size(); i++) {
+                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
+                for (int j=0; j<uids.size(); j++) {
+                    ProcessRecord proc = uids.valueAt(j);
                     if (proc.userId != tr.userId) {
                         continue;
                     }
-                    if (!proc.pkgList.contains(pkg)) {
+                    if (!proc.pkgList.containsKey(pkg)) {
                         continue;
                     }
                     procs.add(proc);
@@ -6013,43 +6558,30 @@
         }
     }
 
+    @Override
     public boolean removeTask(int taskId, int flags) {
         synchronized (this) {
             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
                     "removeTask()");
             long ident = Binder.clearCallingIdentity();
             try {
-                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
-                        false);
-                if (r != null) {
-                    mRecentTasks.remove(r.task);
-                    cleanUpRemovedTaskLocked(r.task, flags);
-                    return true;
-                } else {
-                    TaskRecord tr = null;
-                    int i=0;
-                    while (i < mRecentTasks.size()) {
-                        TaskRecord t = mRecentTasks.get(i);
-                        if (t.taskId == taskId) {
-                            tr = t;
-                            break;
-                        }
-                        i++;
+                TaskRecord tr = recentTaskForIdLocked(taskId);
+                if (tr != null) {
+                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
+                    if (r != null) {
+                        cleanUpRemovedTaskLocked(tr, flags);
+                        return true;
                     }
-                    if (tr != null) {
-                        if (tr.numActivities <= 0) {
-                            // Caller is just removing a recent task that is
-                            // not actively running.  That is easy!
-                            mRecentTasks.remove(i);
-                            cleanUpRemovedTaskLocked(tr, flags);
-                            return true;
-                        } else {
-                            Slog.w(TAG, "removeTask: task " + taskId
-                                    + " does not have activities to remove, "
-                                    + " but numActivities=" + tr.numActivities
-                                    + ": " + tr);
-                        }
+                    if (tr.mActivities.size() == 0) {
+                        // Caller is just removing a recent task that is
+                        // not actively running.  That is easy!
+                        cleanUpRemovedTaskLocked(tr, flags);
+                        return true;
                     }
+                    Slog.w(TAG, "removeTask: task " + taskId
+                            + " does not have activities to remove, "
+                            + " but numActivities=" + tr.numActivities
+                            + ": " + tr);
                 }
             } finally {
                 Binder.restoreCallingIdentity(ident);
@@ -6058,50 +6590,15 @@
         return false;
     }
     
-    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
-        int j;
-        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; 
-        TaskRecord jt = startTask;
-        
-        // First look backwards
-        for (j=startIndex-1; j>=0; j--) {
-            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
-            if (r.task != jt) {
-                jt = r.task;
-                if (affinity.equals(jt.affinity)) {
-                    return j;
-                }
-            }
-        }
-        
-        // Now look forwards
-        final int N = mMainStack.mHistory.size();
-        jt = startTask;
-        for (j=startIndex+1; j<N; j++) {
-            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
-            if (r.task != jt) {
-                if (affinity.equals(jt.affinity)) {
-                    return j;
-                }
-                jt = r.task;
-            }
-        }
-        
-        // Might it be at the top?
-        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
-            return N-1;
-        }
-        
-        return -1;
-    }
-    
     /**
      * TODO: Add mController hook
      */
+    @Override
     public void moveTaskToFront(int task, int flags, Bundle options) {
         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
                 "moveTaskToFront()");
 
+        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task);
         synchronized(this) {
             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
                     Binder.getCallingUid(), "Task to front")) {
@@ -6110,34 +6607,7 @@
             }
             final long origId = Binder.clearCallingIdentity();
             try {
-                TaskRecord tr = taskForIdLocked(task);
-                if (tr != null) {
-                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
-                        mMainStack.mUserLeaving = true;
-                    }
-                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
-                        // Caller wants the home activity moved with it.  To accomplish this,
-                        // we'll just move the home task to the top first.
-                        mMainStack.moveHomeToFrontLocked();
-                    }
-                    mMainStack.moveTaskToFrontLocked(tr, null, options);
-                    return;
-                }
-                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
-                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
-                    if (hr.task.taskId == task) {
-                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
-                            mMainStack.mUserLeaving = true;
-                        }
-                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
-                            // Caller wants the home activity moved with it.  To accomplish this,
-                            // we'll just move the home task to the top first.
-                            mMainStack.moveHomeToFrontLocked();
-                        }
-                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
-                        return;
-                    }
-                }
+                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
             } finally {
                 Binder.restoreCallingIdentity(origId);
             }
@@ -6145,21 +6615,29 @@
         }
     }
 
-    public void moveTaskToBack(int task) {
+    @Override
+    public void moveTaskToBack(int taskId) {
         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
                 "moveTaskToBack()");
 
         synchronized(this) {
-            if (mMainStack.mResumedActivity != null
-                    && mMainStack.mResumedActivity.task.taskId == task) {
-                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
-                        Binder.getCallingUid(), "Task to back")) {
-                    return;
+            TaskRecord tr = recentTaskForIdLocked(taskId);
+            if (tr != null) {
+                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
+                ActivityStack stack = tr.stack;
+                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
+                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
+                            Binder.getCallingUid(), "Task to back")) {
+                        return;
+                    }
+                }
+                final long origId = Binder.clearCallingIdentity();
+                try {
+                    stack.moveTaskToBackLocked(taskId, null);
+                } finally {
+                    Binder.restoreCallingIdentity(origId);
                 }
             }
-            final long origId = Binder.clearCallingIdentity();
-            mMainStack.moveTaskToBackLocked(task, null);
-            Binder.restoreCallingIdentity(origId);
         }
     }
 
@@ -6172,19 +6650,21 @@
      *                of a task; if true it will work for any activity in a task.
      * @return Returns true if the move completed, false if not.
      */
+    @Override
     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
         enforceNotIsolatedCaller("moveActivityTaskToBack");
         synchronized(this) {
             final long origId = Binder.clearCallingIdentity();
-            int taskId = getTaskForActivityLocked(token, !nonRoot);
+            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
             if (taskId >= 0) {
-                return mMainStack.moveTaskToBackLocked(taskId, null);
+                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
             }
             Binder.restoreCallingIdentity(origId);
         }
         return false;
     }
 
+    @Override
     public void moveTaskBackwards(int task) {
         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
                 "moveTaskBackwards()");
@@ -6204,27 +6684,151 @@
         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
     }
 
-    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
-        synchronized(this) {
-            return getTaskForActivityLocked(token, onlyRoot);
+    @Override
+    public int createStack(int taskId, int relativeStackBoxId, int position, float weight) {
+        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
+                "createStack()");
+        if (DEBUG_STACK) Slog.d(TAG, "createStack: taskId=" + taskId + " relStackBoxId=" +
+                relativeStackBoxId + " position=" + position + " weight=" + weight);
+        synchronized (this) {
+            long ident = Binder.clearCallingIdentity();
+            try {
+                int stackId = mStackSupervisor.createStack();
+                mWindowManager.createStack(stackId, relativeStackBoxId, position, weight);
+                if (taskId > 0) {
+                    moveTaskToStack(taskId, stackId, true);
+                }
+                return stackId;
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
         }
     }
 
-    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
-        final int N = mMainStack.mHistory.size();
-        TaskRecord lastTask = null;
-        for (int i=0; i<N; i++) {
-            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
-            if (r.appToken == token) {
-                if (!onlyRoot || lastTask != r.task) {
-                    return r.task.taskId;
-                }
-                return -1;
-            }
-            lastTask = r.task;
+    @Override
+    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
+        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
+                "moveTaskToStack()");
+        if (stackId == HOME_STACK_ID) {
+            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
+                    new RuntimeException("here").fillInStackTrace());
         }
+        synchronized (this) {
+            long ident = Binder.clearCallingIdentity();
+            try {
+                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
+                        + stackId + " toTop=" + toTop);
+                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+    }
 
-        return -1;
+    @Override
+    public void resizeStackBox(int stackBoxId, float weight) {
+        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
+                "resizeStackBox()");
+        long ident = Binder.clearCallingIdentity();
+        try {
+            mWindowManager.resizeStackBox(stackBoxId, weight);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    private ArrayList<StackInfo> getStacks() {
+        synchronized (this) {
+            ArrayList<ActivityManager.StackInfo> list = new ArrayList<ActivityManager.StackInfo>();
+            ArrayList<ActivityStack> stacks = mStackSupervisor.getStacks();
+            for (ActivityStack stack : stacks) {
+                ActivityManager.StackInfo stackInfo = new ActivityManager.StackInfo();
+                int stackId = stack.mStackId;
+                stackInfo.stackId = stackId;
+                stackInfo.bounds = mWindowManager.getStackBounds(stackId);
+                ArrayList<TaskRecord> tasks = stack.getAllTasks();
+                final int numTasks = tasks.size();
+                int[] taskIds = new int[numTasks];
+                String[] taskNames = new String[numTasks];
+                for (int i = 0; i < numTasks; ++i) {
+                    final TaskRecord task = tasks.get(i);
+                    taskIds[i] = task.taskId;
+                    taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
+                            : task.realActivity != null ? task.realActivity.flattenToString()
+                            : task.getTopActivity() != null ? task.getTopActivity().packageName
+                            : "unknown";
+                }
+                stackInfo.taskIds = taskIds;
+                stackInfo.taskNames = taskNames;
+                list.add(stackInfo);
+            }
+            return list;
+        }
+    }
+
+    private void addStackInfoToStackBoxInfo(StackBoxInfo stackBoxInfo, List<StackInfo> stackInfos) {
+        final int stackId = stackBoxInfo.stackId;
+        if (stackId >= 0) {
+            for (StackInfo stackInfo : stackInfos) {
+                if (stackId == stackInfo.stackId) {
+                    stackBoxInfo.stack = stackInfo;
+                    stackInfos.remove(stackInfo);
+                    return;
+                }
+            }
+        } else {
+            addStackInfoToStackBoxInfo(stackBoxInfo.children[0], stackInfos);
+            addStackInfoToStackBoxInfo(stackBoxInfo.children[1], stackInfos);
+        }
+    }
+
+    @Override
+    public List<StackBoxInfo> getStackBoxes() {
+        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
+                "getStackBoxes()");
+        long ident = Binder.clearCallingIdentity();
+        try {
+            List<StackBoxInfo> stackBoxInfos = mWindowManager.getStackBoxInfos();
+            synchronized (this) {
+                List<StackInfo> stackInfos = getStacks();
+                for (StackBoxInfo stackBoxInfo : stackBoxInfos) {
+                    addStackInfoToStackBoxInfo(stackBoxInfo, stackInfos);
+                }
+            }
+            return stackBoxInfos;
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    @Override
+    public StackBoxInfo getStackBoxInfo(int stackBoxId) {
+        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
+                "getStackBoxInfo()");
+        long ident = Binder.clearCallingIdentity();
+        try {
+            List<StackBoxInfo> stackBoxInfos = mWindowManager.getStackBoxInfos();
+            StackBoxInfo info = null;
+            synchronized (this) {
+                List<StackInfo> stackInfos = getStacks();
+                for (StackBoxInfo stackBoxInfo : stackBoxInfos) {
+                    addStackInfoToStackBoxInfo(stackBoxInfo, stackInfos);
+                    if (stackBoxInfo.stackBoxId == stackBoxId) {
+                        info = stackBoxInfo;
+                    }
+                }
+            }
+            return info;
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    @Override
+    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
+        synchronized(this) {
+            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
+        }
     }
 
     // =========================================================
@@ -6241,14 +6845,14 @@
 
     final void sendPendingThumbnail(ActivityRecord r, IBinder token,
             Bitmap thumbnail, CharSequence description, boolean always) {
-        TaskRecord task = null;
-        ArrayList receivers = null;
+        TaskRecord task;
+        ArrayList<PendingThumbnailsRecord> receivers = null;
 
         //System.out.println("Send pending thumbnail: " + r);
 
         synchronized(this) {
             if (r == null) {
-                r = mMainStack.isInStackLocked(token);
+                r = ActivityRecord.isInStackLocked(token);
                 if (r == null) {
                     return;
                 }
@@ -6268,12 +6872,11 @@
             int N = mPendingThumbnails.size();
             int i=0;
             while (i<N) {
-                PendingThumbnailsRecord pr =
-                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
+                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
                 //System.out.println("Looking in " + pr.pendingRecords);
                 if (pr.pendingRecords.remove(r)) {
                     if (receivers == null) {
-                        receivers = new ArrayList();
+                        receivers = new ArrayList<PendingThumbnailsRecord>();
                     }
                     receivers.add(pr);
                     if (pr.pendingRecords.size() == 0) {
@@ -6291,8 +6894,7 @@
             final int N = receivers.size();
             for (int i=0; i<N; i++) {
                 try {
-                    PendingThumbnailsRecord pr =
-                        (PendingThumbnailsRecord)receivers.get(i);
+                    PendingThumbnailsRecord pr = receivers.get(i);
                     pr.receiver.newThumbnail(
                         task != null ? task.taskId : -1, thumbnail, description);
                     if (pr.finished) {
@@ -6322,6 +6924,7 @@
         int userId = app.userId;
         if (providers != null) {
             int N = providers.size();
+            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
             for (int i=0; i<N; i++) {
                 ProviderInfo cpi =
                     (ProviderInfo)providers.get(i);
@@ -6347,7 +6950,7 @@
                 if (DEBUG_MU)
                     Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
                 app.pubProviders.put(cpi.name, cpr);
-                app.addPackage(cpi.applicationInfo.packageName);
+                app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
                 ensurePackageDexOpt(cpi.applicationInfo.packageName);
             }
         }
@@ -6393,7 +6996,7 @@
             }
         }
         
-        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
+        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
         if (perms != null) {
             for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
                 if (uri.getKey().getAuthority().equals(cpi.authority)) {
@@ -6647,7 +7250,7 @@
 
                 if (DEBUG_PROVIDER) {
                     RuntimeException e = new RuntimeException("here");
-                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
+                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
                           + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
                 }
 
@@ -7055,8 +7658,8 @@
     // GLOBAL MANAGEMENT
     // =========================================================
 
-    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
-            ApplicationInfo info, String customProcess, boolean isolated) {
+    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
+            boolean isolated) {
         String proc = customProcess != null ? customProcess : info.processName;
         BatteryStatsImpl.Uid.Proc ps = null;
         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
@@ -7064,7 +7667,6 @@
         if (isolated) {
             int userId = UserHandle.getUserId(uid);
             int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
-            uid = 0;
             while (true) {
                 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
                         || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
@@ -7085,7 +7687,7 @@
         synchronized (stats) {
             ps = stats.getProcessStatsLocked(info.uid, proc);
         }
-        return new ProcessRecord(ps, thread, info, proc, uid);
+        return new ProcessRecord(ps, info, proc, uid);
     }
 
     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
@@ -7097,7 +7699,7 @@
         }
 
         if (app == null) {
-            app = newProcessRecordLocked(null, info, null, isolated);
+            app = newProcessRecordLocked(info, null, isolated);
             mProcessNames.put(info.processName, app.uid, app);
             if (isolated) {
                 mIsolatedProcesses.put(app.uid, app);
@@ -7133,13 +7735,10 @@
                 "unhandledBack()");
 
         synchronized(this) {
-            int count = mMainStack.mHistory.size();
-            if (DEBUG_SWITCH) Slog.d(
-                TAG, "Performing unhandledBack(): stack size = " + count);
-            if (count > 1) {
-                final long origId = Binder.clearCallingIdentity();
-                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
-                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true);
+            final long origId = Binder.clearCallingIdentity();
+            try {
+                getFocusedStack().unhandledBackLocked();
+            } finally {
                 Binder.restoreCallingIdentity(origId);
             }
         }
@@ -7162,7 +7761,7 @@
             sCallerIdentity.set(new Identity(
                     Binder.getCallingPid(), Binder.getCallingUid()));
             try {
-                pfd = cph.provider.openFile(null, uri, "r");
+                pfd = cph.provider.openFile(null, uri, "r", null);
             } catch (FileNotFoundException e) {
                 // do nothing; pfd will be returned null
             } finally {
@@ -7180,7 +7779,7 @@
 
     // Actually is sleeping or shutting down or whatever else in the future
     // is an inactive state.
-    public boolean isSleeping() {
+    public boolean isSleepingOrShuttingDown() {
         return mSleeping || mShuttingDown;
     }
 
@@ -7197,7 +7796,7 @@
 
             if (!mSleeping) {
                 mSleeping = true;
-                mMainStack.stopIfSleepingLocked();
+                mStackSupervisor.goingToSleepLocked();
 
                 // Initialize the wake times of all processes.
                 checkExcessivePowerUsageLocked(false);
@@ -7208,57 +7807,41 @@
         }
     }
 
+    @Override
     public boolean shutdown(int timeout) {
         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
                 != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Requires permission "
                     + android.Manifest.permission.SHUTDOWN);
         }
-        
+
         boolean timedout = false;
-        
+
         synchronized(this) {
             mShuttingDown = true;
             updateEventDispatchingLocked();
-
-            if (mMainStack.mResumedActivity != null) {
-                mMainStack.stopIfSleepingLocked();
-                final long endTime = System.currentTimeMillis() + timeout;
-                while (mMainStack.mResumedActivity != null
-                        || mMainStack.mPausingActivity != null) {
-                    long delay = endTime - System.currentTimeMillis();
-                    if (delay <= 0) {
-                        Slog.w(TAG, "Activity manager shutdown timed out");
-                        timedout = true;
-                        break;
-                    }
-                    try {
-                        this.wait();
-                    } catch (InterruptedException e) {
-                    }
-                }
-            }
+            timedout = mStackSupervisor.shutdownLocked(timeout);
         }
 
         mAppOpsService.shutdown();
         mUsageStatsService.shutdown();
         mBatteryStatsService.shutdown();
-        
+        synchronized (this) {
+            mProcessStats.shutdownLocked();
+        }
+
         return timedout;
     }
     
     public final void activitySlept(IBinder token) {
-        if (localLOGV) Slog.v(
-            TAG, "Activity slept: token=" + token);
-
-        ActivityRecord r = null;
+        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
 
         final long origId = Binder.clearCallingIdentity();
 
         synchronized (this) {
-            r = mMainStack.isInStackLocked(token);
+            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
             if (r != null) {
-                mMainStack.activitySleptLocked(r);
+                mStackSupervisor.activitySleptLocked(r);
             }
         }
 
@@ -7269,8 +7852,7 @@
         if (!mWentToSleep && !mLockScreenShown) {
             if (mSleeping) {
                 mSleeping = false;
-                mMainStack.awakeFromSleepingLocked();
-                mMainStack.resumeTopActivityLocked(null);
+                mStackSupervisor.comeOutOfSleepIfNeededLocked();
             }
         }
     }
@@ -7301,8 +7883,13 @@
         }
 
         synchronized(this) {
-            mLockScreenShown = shown;
-            comeOutOfSleepIfNeededLocked();
+            long ident = Binder.clearCallingIdentity();
+            try {
+                mLockScreenShown = shown;
+                comeOutOfSleepIfNeededLocked();
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
         }
     }
 
@@ -7360,33 +7947,36 @@
         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
                 "setDebugApp()");
 
-        // Note that this is not really thread safe if there are multiple
-        // callers into it at the same time, but that's not a situation we
-        // care about.
-        if (persistent) {
-            final ContentResolver resolver = mContext.getContentResolver();
-            Settings.Global.putString(
-                resolver, Settings.Global.DEBUG_APP,
-                packageName);
-            Settings.Global.putInt(
-                resolver, Settings.Global.WAIT_FOR_DEBUGGER,
-                waitForDebugger ? 1 : 0);
-        }
+        long ident = Binder.clearCallingIdentity();
+        try {
+            // Note that this is not really thread safe if there are multiple
+            // callers into it at the same time, but that's not a situation we
+            // care about.
+            if (persistent) {
+                final ContentResolver resolver = mContext.getContentResolver();
+                Settings.Global.putString(
+                    resolver, Settings.Global.DEBUG_APP,
+                    packageName);
+                Settings.Global.putInt(
+                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
+                    waitForDebugger ? 1 : 0);
+            }
 
-        synchronized (this) {
-            if (!persistent) {
-                mOrigDebugApp = mDebugApp;
-                mOrigWaitForDebugger = mWaitForDebugger;
+            synchronized (this) {
+                if (!persistent) {
+                    mOrigDebugApp = mDebugApp;
+                    mOrigWaitForDebugger = mWaitForDebugger;
+                }
+                mDebugApp = packageName;
+                mWaitForDebugger = waitForDebugger;
+                mDebugTransient = !persistent;
+                if (packageName != null) {
+                    forceStopPackageLocked(packageName, -1, false, false, true, true,
+                            UserHandle.USER_ALL, "set debug app");
+                }
             }
-            mDebugApp = packageName;
-            mWaitForDebugger = waitForDebugger;
-            mDebugTransient = !persistent;
-            if (packageName != null) {
-                final long origId = Binder.clearCallingIdentity();
-                forceStopPackageLocked(packageName, -1, false, false, true, true,
-                        UserHandle.USER_ALL);
-                Binder.restoreCallingIdentity(origId);
-            }
+        } finally {
+            Binder.restoreCallingIdentity(ident);
         }
     }
 
@@ -7427,6 +8017,7 @@
         }
     }
 
+    @Override
     public void setAlwaysFinish(boolean enabled) {
         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
                 "setAlwaysFinish()");
@@ -7440,6 +8031,7 @@
         }
     }
 
+    @Override
     public void setActivityController(IActivityController controller) {
         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
                 "setActivityController()");
@@ -7449,6 +8041,7 @@
         }
     }
 
+    @Override
     public void setUserIsMonkey(boolean userIsMonkey) {
         synchronized (this) {
             synchronized (mPidsSelfLocked) {
@@ -7466,6 +8059,7 @@
         }
     }
 
+    @Override
     public boolean isUserAMonkey() {
         synchronized (this) {
             // If there is a controller also implies the user is a monkey.
@@ -7489,8 +8083,8 @@
         return KEY_DISPATCHING_TIMEOUT;
     }
 
-
-    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem) {
+    @Override
+    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
                 != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Requires permission "
@@ -7505,7 +8099,7 @@
             timeout = getInputDispatchingTimeoutLocked(proc);
         }
 
-        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem)) {
+        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
             return -1;
         }
 
@@ -7518,13 +8112,20 @@
      */
     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
             final ActivityRecord activity, final ActivityRecord parent,
-            final boolean aboveSystem) {
+            final boolean aboveSystem, String reason) {
         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
                 != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Requires permission "
                     + android.Manifest.permission.FILTER_EVENTS);
         }
 
+        final String annotation;
+        if (reason == null) {
+            annotation = "Input dispatching timed out";
+        } else {
+            annotation = "Input dispatching timed out (" + reason + ")";
+        }
+
         if (proc != null) {
             synchronized (this) {
                 if (proc.debugging) {
@@ -7540,7 +8141,7 @@
                 if (proc.instrumentationClass != null) {
                     Bundle info = new Bundle();
                     info.putString("shortMsg", "keyDispatchingTimedOut");
-                    info.putString("longMsg", "Timed out while dispatching key event");
+                    info.putString("longMsg", annotation);
                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
                     return true;
                 }
@@ -7548,7 +8149,7 @@
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
-                    appNotResponding(proc, activity, parent, aboveSystem, "keyDispatchingTimedOut");
+                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
                 }
             });
         }
@@ -7556,33 +8157,34 @@
         return true;
     }
 
-    public Bundle getTopActivityExtras(int requestType) {
+    public Bundle getAssistContextExtras(int requestType) {
         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
-                "getTopActivityExtras()");
-        PendingActivityExtras pae;
+                "getAssistContextExtras()");
+        PendingAssistExtras pae;
         Bundle extras = new Bundle();
         synchronized (this) {
-            ActivityRecord activity = mMainStack.mResumedActivity;
+            ActivityRecord activity = getFocusedStack().mResumedActivity;
             if (activity == null) {
-                Slog.w(TAG, "getTopActivityExtras failed: no resumed activity");
+                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
                 return null;
             }
             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
             if (activity.app == null || activity.app.thread == null) {
-                Slog.w(TAG, "getTopActivityExtras failed: no process for " + activity);
+                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
                 return extras;
             }
             if (activity.app.pid == Binder.getCallingPid()) {
-                Slog.w(TAG, "getTopActivityExtras failed: request process same as " + activity);
+                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
                 return extras;
             }
-            pae = new PendingActivityExtras(activity);
+            pae = new PendingAssistExtras(activity);
             try {
-                activity.app.thread.requestActivityExtras(activity.appToken, pae, requestType);
-                mPendingActivityExtras.add(pae);
-                mHandler.postDelayed(pae, PENDING_ACTIVITY_RESULT_TIMEOUT);
+                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
+                        requestType);
+                mPendingAssistExtras.add(pae);
+                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
             } catch (RemoteException e) {
-                Slog.w(TAG, "getTopActivityExtras failed: crash calling " + activity);
+                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
                 return extras;
             }
         }
@@ -7598,14 +8200,14 @@
             }
         }
         synchronized (this) {
-            mPendingActivityExtras.remove(pae);
+            mPendingAssistExtras.remove(pae);
             mHandler.removeCallbacks(pae);
         }
         return extras;
     }
 
-    public void reportTopActivityExtras(IBinder token, Bundle extras) {
-        PendingActivityExtras pae = (PendingActivityExtras)token;
+    public void reportAssistContextExtras(IBinder token, Bundle extras) {
+        PendingAssistExtras pae = (PendingAssistExtras)token;
         synchronized (pae) {
             pae.result = extras;
             pae.haveResult = true;
@@ -7621,15 +8223,60 @@
         }
     }
 
+    @Override
     public void unregisterProcessObserver(IProcessObserver observer) {
         synchronized (this) {
             mProcessObservers.unregister(observer);
         }
     }
 
+    @Override
+    public boolean convertFromTranslucent(IBinder token) {
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (this) {
+                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+                if (r == null) {
+                    return false;
+                }
+                if (r.changeWindowTranslucency(true)) {
+                    mWindowManager.setAppFullscreen(token, true);
+                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
+                    return true;
+                }
+                return false;
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
+    @Override
+    public boolean convertToTranslucent(IBinder token) {
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (this) {
+                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+                if (r == null) {
+                    return false;
+                }
+                if (r.changeWindowTranslucency(false)) {
+                    r.task.stack.convertToTranslucent(r);
+                    mWindowManager.setAppFullscreen(token, false);
+                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
+                    return true;
+                }
+                return false;
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
+    @Override
     public void setImmersive(IBinder token, boolean immersive) {
         synchronized(this) {
-            final ActivityRecord r = mMainStack.isInStackLocked(token);
+            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
             if (r == null) {
                 throw new IllegalArgumentException();
             }
@@ -7645,9 +8292,10 @@
         }
     }
 
+    @Override
     public boolean isImmersive(IBinder token) {
         synchronized (this) {
-            ActivityRecord r = mMainStack.isInStackLocked(token);
+            ActivityRecord r = ActivityRecord.isInStackLocked(token);
             if (r == null) {
                 throw new IllegalArgumentException();
             }
@@ -7658,7 +8306,7 @@
     public boolean isTopActivityImmersive() {
         enforceNotIsolatedCaller("startActivity");
         synchronized (this) {
-            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
+            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
             return (r != null) ? r.immersive : false;
         }
     }
@@ -7717,7 +8365,7 @@
         String reason = (pReason == null) ? "Unknown" : pReason;
         // XXX Note: don't acquire main activity lock here, because the window
         // manager calls in with its locks held.
-        
+
         boolean killed = false;
         synchronized (mPidsSelfLocked) {
             int[] types = new int[pids.length];
@@ -7732,12 +8380,12 @@
                     }
                 }
             }
-            
-            // If the worst oom_adj is somewhere in the hidden proc LRU range,
-            // then constrain it so we will kill all hidden procs.
-            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
-                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
-                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
+
+            // If the worst oom_adj is somewhere in the cached proc LRU range,
+            // then constrain it so we will kill all cached procs.
+            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
+                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
+                worstType = ProcessList.CACHED_APP_MIN_ADJ;
             }
 
             // If this is not a secure call, don't let it kill processes that
@@ -7853,6 +8501,38 @@
         }
     }
 
+    @Override
+    public void restart() {
+        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
+                != PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException("Requires permission "
+                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
+        }
+
+        Log.i(TAG, "Sending shutdown broadcast...");
+
+        BroadcastReceiver br = new BroadcastReceiver() {
+            @Override public void onReceive(Context context, Intent intent) {
+                // Now the broadcast is done, finish up the low-level shutdown.
+                Log.i(TAG, "Shutting down activity manager...");
+                shutdown(10000);
+                Log.i(TAG, "Shutdown complete, restarting!");
+                Process.killProcess(Process.myPid());
+                System.exit(10);
+            }
+        };
+
+        // First send the high-level shut down broadcast.
+        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
+        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
+        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
+        mContext.sendOrderedBroadcastAsUser(intent,
+                UserHandle.ALL, null, br, mHandler, 0, null, null);
+        */
+        br.onReceive(mContext, intent);
+    }
+
     public final void startRunning(String pkg, String cls, String action,
             String data) {
         synchronized(this) {
@@ -7880,9 +8560,17 @@
             resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
         boolean alwaysFinishActivities = Settings.Global.getInt(
             resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
+        boolean forceRtl = Settings.Global.getInt(
+                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
+        // Transfer any global setting for forcing RTL layout, into a System Property
+        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
 
         Configuration configuration = new Configuration();
         Settings.System.getConfiguration(resolver, configuration);
+        if (forceRtl) {
+            // This will take care of setting the correct layout direction flags
+            configuration.setLayoutDirection(configuration.locale);
+        }
 
         synchronized (this) {
             mDebugApp = mOrigDebugApp = debugApp;
@@ -7899,7 +8587,7 @@
         // no need to synchronize(this) just to read & return the value
         return mSystemReady;
     }
-    
+
     private static File getCalledPreBootReceiversFile() {
         File dataDir = Environment.getDataDirectory();
         File systemDir = new File(dataDir, "system");
@@ -8146,6 +8834,10 @@
 
         retrieveSettings();
 
+        synchronized (this) {
+            readGrantedUriPermissionsLocked();
+        }
+
         if (goingCallback != null) goingCallback.run();
         
         synchronized (this) {
@@ -8207,7 +8899,7 @@
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
-            mMainStack.resumeTopActivityLocked(null);
+            mStackSupervisor.resumeTopActivitiesLocked();
             sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
         }
     }
@@ -8302,15 +8994,7 @@
                     + " has crashed too many times: killing!");
             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
                     app.userId, app.info.processName, app.uid);
-            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
-                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
-                if (r.app == app) {
-                    Slog.w(TAG, "  Force finishing activity "
-                        + r.intent.getComponent().flattenToShortString());
-                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
-                            null, "crashed", false);
-                }
-            }
+            mStackSupervisor.handleAppCrashLocked(app);
             if (!app.persistent) {
                 // We don't want to start this process again until the user
                 // explicitly does so...  but for persistent process, we really
@@ -8330,61 +9014,32 @@
                 // annoy the user repeatedly.  Unless it is persistent, since those
                 // processes run critical code.
                 removeProcessLocked(app, false, false, "crash");
-                mMainStack.resumeTopActivityLocked(null);
+                mStackSupervisor.resumeTopActivitiesLocked();
                 return false;
             }
-            mMainStack.resumeTopActivityLocked(null);
+            mStackSupervisor.resumeTopActivitiesLocked();
         } else {
-            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
-            if (r != null && r.app == app) {
-                // If the top running activity is from this crashing
-                // process, then terminate it to avoid getting in a loop.
-                Slog.w(TAG, "  Force finishing activity "
-                        + r.intent.getComponent().flattenToShortString());
-                int index = mMainStack.indexOfActivityLocked(r);
-                r.stack.finishActivityLocked(r, index,
-                        Activity.RESULT_CANCELED, null, "crashed", false);
-                // Also terminate any activities below it that aren't yet
-                // stopped, to avoid a situation where one will get
-                // re-start our crashing activity once it gets resumed again.
-                index--;
-                if (index >= 0) {
-                    r = (ActivityRecord)mMainStack.mHistory.get(index);
-                    if (r.state == ActivityState.RESUMED
-                            || r.state == ActivityState.PAUSING
-                            || r.state == ActivityState.PAUSED) {
-                        if (!r.isHomeActivity || mHomeProcess != r.app) {
-                            Slog.w(TAG, "  Force finishing activity "
-                                    + r.intent.getComponent().flattenToShortString());
-                            r.stack.finishActivityLocked(r, index,
-                                    Activity.RESULT_CANCELED, null, "crashed", false);
-                        }
-                    }
-                }
-            }
+            mStackSupervisor.finishTopRunningActivityLocked(app);
         }
 
         // Bump up the crash count of any services currently running in the proc.
-        if (app.services.size() != 0) {
+        for (int i=app.services.size()-1; i>=0; i--) {
             // Any services running in the application need to be placed
             // back in the pending list.
-            Iterator<ServiceRecord> it = app.services.iterator();
-            while (it.hasNext()) {
-                ServiceRecord sr = it.next();
-                sr.crashCount++;
-            }
+            ServiceRecord sr = app.services.valueAt(i);
+            sr.crashCount++;
         }
 
         // If the crashing process is what we consider to be the "home process" and it has been
         // replaced by a third-party app, clear the package preferred activities from packages
         // with a home activity running in the process to prevent a repeatedly crashing app
         // from blocking the user to manually clear the list.
-        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
-                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
-            Iterator it = mHomeProcess.activities.iterator();
-            while (it.hasNext()) {
-                ActivityRecord r = (ActivityRecord)it.next();
-                if (r.isHomeActivity) {
+        final ArrayList<ActivityRecord> activities = app.activities;
+        if (mHomeProcess.contains(app) && activities.size() > 0
+                    && (app.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+                final ActivityRecord r = activities.get(activityNdx);
+                if (r.isHomeActivity()) {
                     Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
                     try {
                         ActivityThread.getPackageManager()
@@ -8670,7 +9325,9 @@
         }
 
         synchronized (this) {
-            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
+            final int NP = mProcessNames.getMap().size();
+            for (int ip=0; ip<NP; ip++) {
+                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
                 final int NA = apps.size();
                 for (int ia=0; ia<NA; ia++) {
                     ProcessRecord p = apps.valueAt(ia);
@@ -8711,7 +9368,8 @@
             int flags = process.info.flags;
             IPackageManager pm = AppGlobals.getPackageManager();
             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
-            for (String pkg : process.pkgList) {
+            for (int ip=0; ip<process.pkgList.size(); ip++) {
+                String pkg = process.pkgList.keyAt(ip);
                 sb.append("Package: ").append(pkg);
                 try {
                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
@@ -9029,9 +9687,9 @@
     }
 
     static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
-        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
+        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
             if (currApp != null) {
-                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
+                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
             }
             return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
         } else if (adj >= ProcessList.SERVICE_B_ADJ) {
@@ -9344,39 +10002,28 @@
 
         // No piece of data specified, dump everything.
         synchronized (this) {
-            boolean needSep;
-            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
-            if (needSep) {
-                pw.println(" ");
-            }
+            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
+            pw.println();
             if (dumpAll) {
                 pw.println("-------------------------------------------------------------------------------");
             }
-            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
-            if (needSep) {
-                pw.println(" ");
-            }
+            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
+            pw.println();
             if (dumpAll) {
                 pw.println("-------------------------------------------------------------------------------");
             }
-            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
-            if (needSep) {
-                pw.println(" ");
-            }
+            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
+            pw.println();
             if (dumpAll) {
                 pw.println("-------------------------------------------------------------------------------");
             }
-            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
-            if (needSep) {
-                pw.println(" ");
-            }
+            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
+            pw.println();
             if (dumpAll) {
                 pw.println("-------------------------------------------------------------------------------");
             }
-            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
-            if (needSep) {
-                pw.println(" ");
-            }
+            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
+            pw.println();
             if (dumpAll) {
                 pw.println("-------------------------------------------------------------------------------");
             }
@@ -9385,57 +10032,32 @@
         Binder.restoreCallingIdentity(origId);
     }
 
-    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
+    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
-        pw.println("  Main stack:");
-        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
+
+        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
                 dumpPackage);
-        pw.println(" ");
-        pw.println("  Running activities (most recent first):");
-        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
-                dumpPackage);
-        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
-            pw.println(" ");
-            pw.println("  Activities waiting for another to become visible:");
-            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
-                    !dumpAll, false, dumpPackage);
-        }
-        if (mMainStack.mStoppingActivities.size() > 0) {
-            pw.println(" ");
-            pw.println("  Activities waiting to stop:");
-            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
-                    !dumpAll, false, dumpPackage);
-        }
-        if (mMainStack.mGoingToSleepActivities.size() > 0) {
-            pw.println(" ");
-            pw.println("  Activities waiting to sleep:");
-            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
-                    !dumpAll, false, dumpPackage);
-        }
-        if (mMainStack.mFinishingActivities.size() > 0) {
-            pw.println(" ");
-            pw.println("  Activities waiting to finish:");
-            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
-                    !dumpAll, false, dumpPackage);
+        boolean needSep = printedAnything;
+
+        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
+                dumpPackage, needSep, "  mFocusedActivity: ");
+        if (printed) {
+            printedAnything = true;
+            needSep = false;
         }
 
-        pw.println(" ");
-        if (mMainStack.mPausingActivity != null) {
-            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
-        }
-        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
-        pw.println("  mFocusedActivity: " + mFocusedActivity);
-        if (dumpAll) {
-            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
-            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
-            pw.println("  mDismissKeyguardOnNextActivity: "
-                    + mMainStack.mDismissKeyguardOnNextActivity);
+        if (dumpPackage == null) {
+            if (needSep) {
+                pw.println();
+            }
+            needSep = true;
+            printedAnything = true;
+            mStackSupervisor.dump(pw, "  ");
         }
 
         if (mRecentTasks.size() > 0) {
-            pw.println();
-            pw.println("  Recent tasks:");
+            boolean printedHeader = false;
 
             final int N = mRecentTasks.size();
             for (int i=0; i<N; i++) {
@@ -9446,6 +10068,14 @@
                         continue;
                     }
                 }
+                if (!printedHeader) {
+                    if (needSep) {
+                        pw.println();
+                    }
+                    pw.println("  Recent tasks:");
+                    printedHeader = true;
+                    printedAnything = true;
+                }
                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
                         pw.println(tr);
                 if (dumpAll) {
@@ -9453,33 +10083,34 @@
                 }
             }
         }
-        
-        if (dumpAll) {
-            pw.println(" ");
-            pw.println("  mCurTask: " + mCurTask);
+
+        if (!printedAnything) {
+            pw.println("  (nothing)");
         }
-        
-        return true;
     }
 
-    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
+    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
             int opti, boolean dumpAll, String dumpPackage) {
         boolean needSep = false;
+        boolean printedAnything = false;
         int numPers = 0;
 
         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
 
         if (dumpAll) {
-            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
+            final int NP = mProcessNames.getMap().size();
+            for (int ip=0; ip<NP; ip++) {
+                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
                 final int NA = procs.size();
                 for (int ia=0; ia<NA; ia++) {
                     ProcessRecord r = procs.valueAt(ia);
-                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
+                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
                         continue;
                     }
                     if (!needSep) {
                         pw.println("  All known processes:");
                         needSep = true;
+                        printedAnything = true;
                     }
                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
                         pw.print(" UID "); pw.print(procs.keyAt(ia));
@@ -9493,41 +10124,50 @@
         }
 
         if (mIsolatedProcesses.size() > 0) {
-            if (needSep) pw.println(" ");
-            needSep = true;
-            pw.println("  Isolated process list (sorted by uid):");
+            boolean printed = false;
             for (int i=0; i<mIsolatedProcesses.size(); i++) {
                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
-                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
+                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
                     continue;
                 }
+                if (!printed) {
+                    if (needSep) {
+                        pw.println();
+                    }
+                    pw.println("  Isolated process list (sorted by uid):");
+                    printedAnything = true;
+                    printed = true;
+                    needSep = true;
+                }
                 pw.println(String.format("%sIsolated #%2d: %s",
                         "    ", i, r.toString()));
             }
         }
 
         if (mLruProcesses.size() > 0) {
-            if (needSep) pw.println(" ");
-            needSep = true;
-            pw.println("  Process LRU list (sorted by oom_adj):");
-            dumpProcessOomList(pw, this, mLruProcesses, "    ",
-                    "Proc", "PERS", false, dumpPackage);
-            needSep = true;
+            boolean printed = dumpProcessOomList(pw, this, mLruProcesses, "    ",
+                    "Proc", "PERS", false, dumpPackage, needSep,
+                    "  Process LRU list (sorted by oom_adj):");
+            if (printed) {
+                needSep = true;
+                printedAnything = true;
+            }
         }
 
-        if (dumpAll) {
+        if (dumpAll || dumpPackage != null) {
             synchronized (mPidsSelfLocked) {
                 boolean printed = false;
                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
-                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
+                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
                         continue;
                     }
                     if (!printed) {
-                        if (needSep) pw.println(" ");
+                        if (needSep) pw.println();
                         needSep = true;
                         pw.println("  PID mappings:");
                         printed = true;
+                        printedAnything = true;
                     }
                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
@@ -9542,14 +10182,15 @@
                     ProcessRecord r = mPidsSelfLocked.get( 
                             mForegroundProcesses.valueAt(i).pid);
                     if (dumpPackage != null && (r == null
-                            || !dumpPackage.equals(r.info.packageName))) {
+                            || !r.pkgList.containsKey(dumpPackage))) {
                         continue;
                     }
                     if (!printed) {
-                        if (needSep) pw.println(" ");
+                        if (needSep) pw.println();
                         needSep = true;
                         pw.println("  Foreground Processes:");
                         printed = true;
+                        printedAnything = true;
                     }
                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
@@ -9558,24 +10199,27 @@
         }
         
         if (mPersistentStartingProcesses.size() > 0) {
-            if (needSep) pw.println(" ");
+            if (needSep) pw.println();
             needSep = true;
+            printedAnything = true;
             pw.println("  Persisent processes that are starting:");
             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
                     "Starting Norm", "Restarting PERS", dumpPackage);
         }
 
         if (mRemovedProcesses.size() > 0) {
-            if (needSep) pw.println(" ");
+            if (needSep) pw.println();
             needSep = true;
+            printedAnything = true;
             pw.println("  Processes that are being removed:");
             dumpProcessList(pw, this, mRemovedProcesses, "    ",
                     "Removed Norm", "Removed PERS", dumpPackage);
         }
         
         if (mProcessesOnHold.size() > 0) {
-            if (needSep) pw.println(" ");
+            if (needSep) pw.println();
             needSep = true;
+            printedAnything = true;
             pw.println("  Processes that are on old until the system is ready:");
             dumpProcessList(pw, this, mProcessesOnHold, "    ",
                     "OnHold Norm", "OnHold PERS", dumpPackage);
@@ -9586,23 +10230,25 @@
         if (mProcessCrashTimes.getMap().size() > 0) {
             boolean printed = false;
             long now = SystemClock.uptimeMillis();
-            for (Map.Entry<String, SparseArray<Long>> procs
-                    : mProcessCrashTimes.getMap().entrySet()) {
-                String pname = procs.getKey();
-                SparseArray<Long> uids = procs.getValue();
+            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
+            final int NP = pmap.size();
+            for (int ip=0; ip<NP; ip++) {
+                String pname = pmap.keyAt(ip);
+                SparseArray<Long> uids = pmap.valueAt(ip);
                 final int N = uids.size();
                 for (int i=0; i<N; i++) {
                     int puid = uids.keyAt(i);
                     ProcessRecord r = mProcessNames.get(pname, puid);
                     if (dumpPackage != null && (r == null
-                            || !dumpPackage.equals(r.info.packageName))) {
+                            || !r.pkgList.containsKey(dumpPackage))) {
                         continue;
                     }
                     if (!printed) {
-                        if (needSep) pw.println(" ");
+                        if (needSep) pw.println();
                         needSep = true;
                         pw.println("  Time since processes crashed:");
                         printed = true;
+                        printedAnything = true;
                     }
                     pw.print("    Process "); pw.print(pname);
                             pw.print(" uid "); pw.print(puid);
@@ -9615,22 +10261,24 @@
 
         if (mBadProcesses.getMap().size() > 0) {
             boolean printed = false;
-            for (Map.Entry<String, SparseArray<Long>> procs
-                    : mBadProcesses.getMap().entrySet()) {
-                String pname = procs.getKey();
-                SparseArray<Long> uids = procs.getValue();
+            final ArrayMap<String, SparseArray<Long>> pmap = mBadProcesses.getMap();
+            final int NP = pmap.size();
+            for (int ip=0; ip<NP; ip++) {
+                String pname = pmap.keyAt(ip);
+                SparseArray<Long> uids = pmap.valueAt(ip);
                 final int N = uids.size();
                 for (int i=0; i<N; i++) {
                     int puid = uids.keyAt(i);
                     ProcessRecord r = mProcessNames.get(pname, puid);
                     if (dumpPackage != null && (r == null
-                            || !dumpPackage.equals(r.info.packageName))) {
+                            || !r.pkgList.containsKey(dumpPackage))) {
                         continue;
                     }
                     if (!printed) {
-                        if (needSep) pw.println(" ");
+                        if (needSep) pw.println();
                         needSep = true;
                         pw.println("  Bad processes:");
+                        printedAnything = true;
                     }
                     pw.print("    Bad process "); pw.print(pname);
                             pw.print(" uid "); pw.print(puid);
@@ -9640,42 +10288,73 @@
             }
         }
 
-        pw.println();
-        pw.println("  mStartedUsers:");
-        for (int i=0; i<mStartedUsers.size(); i++) {
-            UserStartedState uss = mStartedUsers.valueAt(i);
-            pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
-                    pw.print(": "); uss.dump("", pw);
+        if (dumpPackage == null) {
+            pw.println();
+            needSep = false;
+            pw.println("  mStartedUsers:");
+            for (int i=0; i<mStartedUsers.size(); i++) {
+                UserStartedState uss = mStartedUsers.valueAt(i);
+                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
+                        pw.print(": "); uss.dump("", pw);
+            }
+            pw.print("  mStartedUserArray: [");
+            for (int i=0; i<mStartedUserArray.length; i++) {
+                if (i > 0) pw.print(", ");
+                pw.print(mStartedUserArray[i]);
+            }
+            pw.println("]");
+            pw.print("  mUserLru: [");
+            for (int i=0; i<mUserLru.size(); i++) {
+                if (i > 0) pw.print(", ");
+                pw.print(mUserLru.get(i));
+            }
+            pw.println("]");
+            if (dumpAll) {
+                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
+            }
         }
-        pw.print("  mStartedUserArray: [");
-        for (int i=0; i<mStartedUserArray.length; i++) {
-            if (i > 0) pw.print(", ");
-            pw.print(mStartedUserArray[i]);
+        if (!mHomeProcess.isEmpty()) {
+            final int size = mHomeProcess.size();
+            ProcessRecord[] processes = new ProcessRecord[size];
+            mHomeProcess.toArray(processes);
+            for (int processNdx = 0; processNdx < size; ++processNdx) {
+                final ProcessRecord app = processes[processNdx];
+                if (dumpPackage == null || app.pkgList.containsKey(dumpPackage)) {
+                    if (needSep) {
+                        pw.println();
+                        needSep = false;
+                    }
+                    pw.println("  mHomeProcess[" + processNdx + "]: " + app);
+                }
+            }
         }
-        pw.println("]");
-        pw.print("  mUserLru: [");
-        for (int i=0; i<mUserLru.size(); i++) {
-            if (i > 0) pw.print(", ");
-            pw.print(mUserLru.get(i));
+        if (mPreviousProcess != null && (dumpPackage == null
+                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
+            if (needSep) {
+                pw.println();
+                needSep = false;
+            }
+            pw.println("  mPreviousProcess: " + mPreviousProcess);
         }
-        pw.println("]");
-        if (dumpAll) {
-            pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
-        }
-        pw.println("  mHomeProcess: " + mHomeProcess);
-        pw.println("  mPreviousProcess: " + mPreviousProcess);
         if (dumpAll) {
             StringBuilder sb = new StringBuilder(128);
             sb.append("  mPreviousProcessVisibleTime: ");
             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
             pw.println(sb);
         }
-        if (mHeavyWeightProcess != null) {
+        if (mHeavyWeightProcess != null && (dumpPackage == null
+                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
+            if (needSep) {
+                pw.println();
+                needSep = false;
+            }
             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
         }
-        pw.println("  mConfiguration: " + mConfiguration);
+        if (dumpPackage == null) {
+            pw.println("  mConfiguration: " + mConfiguration);
+        }
         if (dumpAll) {
-            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
+            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
             if (mCompatModePackages.getPackages().size() > 0) {
                 boolean printed = false;
                 for (Map.Entry<String, Integer> entry
@@ -9694,57 +10373,83 @@
                 }
             }
         }
-        if (mSleeping || mWentToSleep || mLockScreenShown) {
-            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
-                    + " mLockScreenShown " + mLockScreenShown);
-        }
-        if (mShuttingDown) {
-            pw.println("  mShuttingDown=" + mShuttingDown);
+        if (dumpPackage == null) {
+            if (mSleeping || mWentToSleep || mLockScreenShown) {
+                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
+                        + " mLockScreenShown " + mLockScreenShown);
+            }
+            if (mShuttingDown) {
+                pw.println("  mShuttingDown=" + mShuttingDown);
+            }
         }
         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
                 || mOrigWaitForDebugger) {
-            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
-                    + " mDebugTransient=" + mDebugTransient
-                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
+            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
+                    || dumpPackage.equals(mOrigDebugApp)) {
+                if (needSep) {
+                    pw.println();
+                    needSep = false;
+                }
+                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
+                        + " mDebugTransient=" + mDebugTransient
+                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
+            }
         }
         if (mOpenGlTraceApp != null) {
-            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
+            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
+                if (needSep) {
+                    pw.println();
+                    needSep = false;
+                }
+                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
+            }
         }
         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
                 || mProfileFd != null) {
-            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
-            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
-            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
-                    + mAutoStopProfiler);
+            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
+                if (needSep) {
+                    pw.println();
+                    needSep = false;
+                }
+                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
+                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
+                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
+                        + mAutoStopProfiler);
+            }
         }
-        if (mAlwaysFinishActivities || mController != null) {
-            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
-                    + " mController=" + mController);
+        if (dumpPackage == null) {
+            if (mAlwaysFinishActivities || mController != null) {
+                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
+                        + " mController=" + mController);
+            }
+            if (dumpAll) {
+                pw.println("  Total persistent processes: " + numPers);
+                pw.println("  mStartRunning=" + mStartRunning
+                        + " mProcessesReady=" + mProcessesReady
+                        + " mSystemReady=" + mSystemReady);
+                pw.println("  mBooting=" + mBooting
+                        + " mBooted=" + mBooted
+                        + " mFactoryTest=" + mFactoryTest);
+                pw.print("  mLastPowerCheckRealtime=");
+                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
+                        pw.println("");
+                pw.print("  mLastPowerCheckUptime=");
+                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
+                        pw.println("");
+                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
+                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
+                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
+                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
+                        + " (" + mLruProcesses.size() + " total)"
+                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
+                        + " mNumServiceProcs=" + mNumServiceProcs
+                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
+            }
         }
-        if (dumpAll) {
-            pw.println("  Total persistent processes: " + numPers);
-            pw.println("  mStartRunning=" + mStartRunning
-                    + " mProcessesReady=" + mProcessesReady
-                    + " mSystemReady=" + mSystemReady);
-            pw.println("  mBooting=" + mBooting
-                    + " mBooted=" + mBooted
-                    + " mFactoryTest=" + mFactoryTest);
-            pw.print("  mLastPowerCheckRealtime=");
-                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
-                    pw.println("");
-            pw.print("  mLastPowerCheckUptime=");
-                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
-                    pw.println("");
-            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
-            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
-            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
-            pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
-                    + " mNumHiddenProcs=" + mNumHiddenProcs
-                    + " mNumServiceProcs=" + mNumServiceProcs
-                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
+
+        if (!printedAnything) {
+            pw.println("  (nothing)");
         }
-        
-        return true;
     }
 
     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
@@ -9758,7 +10463,7 @@
                     continue;
                 }
                 if (!printed) {
-                    if (needSep) pw.println(" ");
+                    if (needSep) pw.println();
                     needSep = true;
                     pw.println("  Processes that are waiting to GC:");
                     printed = true;
@@ -9776,33 +10481,49 @@
         return needSep;
     }
 
+    void printOomLevel(PrintWriter pw, String name, int adj) {
+        pw.print("    ");
+        if (adj >= 0) {
+            pw.print(' ');
+            if (adj < 10) pw.print(' ');
+        } else {
+            if (adj > -10) pw.print(' ');
+        }
+        pw.print(adj);
+        pw.print(": ");
+        pw.print(name);
+        pw.print(" (");
+        pw.print(mProcessList.getMemLevel(adj)/1024);
+        pw.println(" kB)");
+    }
+
     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
             int opti, boolean dumpAll) {
         boolean needSep = false;
 
         if (mLruProcesses.size() > 0) {
-            if (needSep) pw.println(" ");
+            if (needSep) pw.println();
             needSep = true;
             pw.println("  OOM levels:");
-            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
-            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
-            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
-            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
-            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
-            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
-            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
-            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
-            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
-            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
-            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
-            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
-            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
+            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
+            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
+            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
+            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
+            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
+            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
+            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
+            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
+            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
+            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
+            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
+            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
+            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
 
-            if (needSep) pw.println(" ");
+            if (needSep) pw.println();
             needSep = true;
             pw.println("  Process OOM control:");
             dumpProcessOomList(pw, this, mLruProcesses, "    ",
-                    "Proc", "PERS", true, null);
+                    "Proc", "PERS", true, null, false, null);
             needSep = true;
         }
 
@@ -9920,32 +10641,10 @@
      */
     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
             int opti, boolean dumpAll) {
-        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
-
-        if ("all".equals(name)) {
-            synchronized (this) {
-                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
-                    activities.add(r1);
-                }
-            }
-        } else if ("top".equals(name)) {
-            synchronized (this) {
-                final int N = mMainStack.mHistory.size();
-                if (N > 0) {
-                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
-                }
-            }
-        } else {
-            ItemMatcher matcher = new ItemMatcher();
-            matcher.build(name);
-
-            synchronized (this) {
-                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
-                    if (matcher.match(r1, r1.intent.getComponent())) {
-                        activities.add(r1);
-                    }
-                }
-            }
+        ArrayList<ActivityRecord> activities;
+        
+        synchronized (this) {
+            activities = mStackSupervisor.getDumpActivitiesLocked(name);
         }
 
         if (activities.size() <= 0) {
@@ -9953,12 +10652,12 @@
         }
 
         String[] newArgs = new String[args.length - opti];
-        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
+        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
 
         TaskRecord lastTask = null;
         boolean needSep = false;
         for (int i=activities.size()-1; i>=0; i--) {
-            ActivityRecord r = (ActivityRecord)activities.get(i);
+            ActivityRecord r = activities.get(i);
             if (needSep) {
                 pw.println();
             }
@@ -10016,10 +10715,11 @@
         }
     }
 
-    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
+    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
             int opti, boolean dumpAll, String dumpPackage) {
         boolean needSep = false;
         boolean onlyHistory = false;
+        boolean printedAnything = false;
 
         if ("history".equals(dumpPackage)) {
             if (opti < args.length && "-s".equals(args[opti])) {
@@ -10044,6 +10744,7 @@
                         pw.println("  Registered Receivers:");
                         needSep = true;
                         printed = true;
+                        printedAnything = true;
                     }
                     pw.print("  * "); pw.println(r);
                     r.dump(pw, "    ");
@@ -10054,11 +10755,13 @@
                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
                     "    ", dumpPackage, false)) {
                 needSep = true;
+                printedAnything = true;
             }
         }
 
         for (BroadcastQueue q : mBroadcastQueues) {
             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
+            printedAnything |= needSep;
         }
 
         needSep = true;
@@ -10069,6 +10772,7 @@
                     pw.println();
                 }
                 needSep = true;
+                printedAnything = true;
                 pw.print("  Sticky broadcasts for user ");
                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
                 StringBuilder sb = new StringBuilder(128);
@@ -10106,21 +10810,26 @@
             pw.println("  mHandler:");
             mHandler.dump(new PrintWriterPrinter(pw), "    ");
             needSep = true;
+            printedAnything = true;
         }
         
-        return needSep;
+        if (!printedAnything) {
+            pw.println("  (nothing)");
+        }
     }
 
-    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
+    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
             int opti, boolean dumpAll, String dumpPackage) {
-        boolean needSep = true;
+        boolean needSep;
+        boolean printedAnything = false;
 
         ItemMatcher matcher = new ItemMatcher();
         matcher.build(args, opti);
 
         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
 
-        mProviderMap.dumpProvidersLocked(pw, dumpAll);
+        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
+        printedAnything |= needSep;
 
         if (mLaunchingProviders.size() > 0) {
             boolean printed = false;
@@ -10130,10 +10839,11 @@
                     continue;
                 }
                 if (!printed) {
-                    if (needSep) pw.println(" ");
+                    if (needSep) pw.println();
                     needSep = true;
                     pw.println("  Launching content providers:");
                     printed = true;
+                    printedAnything = true;
                 }
                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
                         pw.println(r);
@@ -10141,13 +10851,29 @@
         }
 
         if (mGrantedUriPermissions.size() > 0) {
-            if (needSep) pw.println();
-            needSep = true;
-            pw.println("Granted Uri Permissions:");
+            boolean printed = false;
+            int dumpUid = -2;
+            if (dumpPackage != null) {
+                try {
+                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
+                } catch (NameNotFoundException e) {
+                    dumpUid = -1;
+                }
+            }
             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
                 int uid = mGrantedUriPermissions.keyAt(i);
-                HashMap<Uri, UriPermission> perms
+                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
+                    continue;
+                }
+                ArrayMap<Uri, UriPermission> perms
                         = mGrantedUriPermissions.valueAt(i);
+                if (!printed) {
+                    if (needSep) pw.println();
+                    needSep = true;
+                    pw.println("  Granted Uri Permissions:");
+                    printed = true;
+                    printedAnything = true;
+                }
                 pw.print("  * UID "); pw.print(uid);
                         pw.println(" holds:");
                 for (UriPermission perm : perms.values()) {
@@ -10157,18 +10883,20 @@
                     }
                 }
             }
-            needSep = true;
         }
-        
-        return needSep;
+
+        if (!printedAnything) {
+            pw.println("  (nothing)");
+        }
     }
 
-    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
+    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
             int opti, boolean dumpAll, String dumpPackage) {
-        boolean needSep = false;
-        
+        boolean printed = false;
+
+        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
+
         if (mIntentSenderRecords.size() > 0) {
-            boolean printed = false;
             Iterator<WeakReference<PendingIntentRecord>> it
                     = mIntentSenderRecords.values().iterator();
             while (it.hasNext()) {
@@ -10178,11 +10906,7 @@
                         || !dumpPackage.equals(rec.key.packageName))) {
                     continue;
                 }
-                if (!printed) {
-                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
-                    printed = true;
-                }
-                needSep = true;
+                printed = true;
                 if (rec != null) {
                     pw.print("  * "); pw.println(rec);
                     if (dumpAll) {
@@ -10193,87 +10917,12 @@
                 }
             }
         }
-        
-        return needSep;
-    }
 
-    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
-            String prefix, String label, boolean complete, boolean brief, boolean client,
-            String dumpPackage) {
-        TaskRecord lastTask = null;
-        boolean needNL = false;
-        final String innerPrefix = prefix + "      ";
-        final String[] args = new String[0];
-        for (int i=list.size()-1; i>=0; i--) {
-            final ActivityRecord r = (ActivityRecord)list.get(i);
-            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
-                continue;
-            }
-            final boolean full = !brief && (complete || !r.isInHistory());
-            if (needNL) {
-                pw.println(" ");
-                needNL = false;
-            }
-            if (lastTask != r.task) {
-                lastTask = r.task;
-                pw.print(prefix);
-                pw.print(full ? "* " : "  ");
-                pw.println(lastTask);
-                if (full) {
-                    lastTask.dump(pw, prefix + "  ");
-                } else if (complete) {
-                    // Complete + brief == give a summary.  Isn't that obvious?!?
-                    if (lastTask.intent != null) {
-                        pw.print(prefix); pw.print("  ");
-                                pw.println(lastTask.intent.toInsecureStringWithClip());
-                    }
-                }
-            }
-            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
-            pw.print(" #"); pw.print(i); pw.print(": ");
-            pw.println(r);
-            if (full) {
-                r.dump(pw, innerPrefix);
-            } else if (complete) {
-                // Complete + brief == give a summary.  Isn't that obvious?!?
-                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
-                if (r.app != null) {
-                    pw.print(innerPrefix); pw.println(r.app);
-                }
-            }
-            if (client && r.app != null && r.app.thread != null) {
-                // flush anything that is already in the PrintWriter since the thread is going
-                // to write to the file descriptor directly
-                pw.flush();
-                try {
-                    TransferPipe tp = new TransferPipe();
-                    try {
-                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
-                                r.appToken, innerPrefix, args);
-                        // Short timeout, since blocking here can
-                        // deadlock with the application.
-                        tp.go(fd, 2000);
-                    } finally {
-                        tp.kill();
-                    }
-                } catch (IOException e) {
-                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
-                } catch (RemoteException e) {
-                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
-                }
-                needNL = true;
-            }
+        if (!printed) {
+            pw.println("  (nothing)");
         }
     }
 
-    private static String buildOomTag(String prefix, String space, int val, int base) {
-        if (val == base) {
-            if (space == null) return prefix;
-            return prefix + "  ";
-        }
-        return prefix + "+" + Integer.toString(val-base);
-    }
-    
     private static final int dumpProcessList(PrintWriter pw,
             ActivityManagerService service, List list,
             String prefix, String normalLabel, String persistentLabel,
@@ -10298,13 +10947,13 @@
     private static final boolean dumpProcessOomList(PrintWriter pw,
             ActivityManagerService service, List<ProcessRecord> origList,
             String prefix, String normalLabel, String persistentLabel,
-            boolean inclDetails, String dumpPackage) {
+            boolean inclDetails, String dumpPackage, boolean needSep, String header) {
 
         ArrayList<Pair<ProcessRecord, Integer>> list
                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
         for (int i=0; i<origList.size(); i++) {
             ProcessRecord r = origList.get(i);
-            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
+            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
                 continue;
             }
             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
@@ -10313,7 +10962,14 @@
         if (list.size() <= 0) {
             return false;
         }
- 
+
+        if (header != null) {
+            if (needSep) {
+                pw.println();
+            }
+            pw.println(header);
+        }
+
         Comparator<Pair<ProcessRecord, Integer>> comparator
                 = new Comparator<Pair<ProcessRecord, Integer>>() {
             @Override
@@ -10338,58 +10994,50 @@
 
         for (int i=list.size()-1; i>=0; i--) {
             ProcessRecord r = list.get(i).first;
-            String oomAdj;
-            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
-                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
-            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
-                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
-            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
-                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
-            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
-                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
-            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
-                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
-            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
-                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
-            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
-                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
-            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
-                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
-            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
-                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
-            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
-                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
-            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
-                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
-            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
-                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
-            } else {
-                oomAdj = Integer.toString(r.setAdj);
-            }
-            String schedGroup;
+            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
+            char schedGroup;
             switch (r.setSchedGroup) {
                 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
-                    schedGroup = "B";
+                    schedGroup = 'B';
                     break;
                 case Process.THREAD_GROUP_DEFAULT:
-                    schedGroup = "F";
+                    schedGroup = 'F';
                     break;
                 default:
-                    schedGroup = Integer.toString(r.setSchedGroup);
+                    schedGroup = '?';
                     break;
             }
-            String foreground;
+            char foreground;
             if (r.foregroundActivities) {
-                foreground = "A";
+                foreground = 'A';
             } else if (r.foregroundServices) {
-                foreground = "S";
+                foreground = 'S';
             } else {
-                foreground = " ";
+                foreground = ' ';
             }
-            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
-                    prefix, (r.persistent ? persistentLabel : normalLabel),
-                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
-                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
+            String procState = ProcessList.makeProcStateString(r.curProcState);
+            pw.print(prefix);
+            pw.print(r.persistent ? persistentLabel : normalLabel);
+            pw.print(" #");
+            int num = (origList.size()-1)-list.get(i).second;
+            if (num < 10) pw.print(' ');
+            pw.print(num);
+            pw.print(": ");
+            pw.print(oomAdj);
+            pw.print(' ');
+            pw.print(schedGroup);
+            pw.print('/');
+            pw.print(foreground);
+            pw.print('/');
+            pw.print(procState);
+            pw.print(" trm:");
+            if (r.trimMemoryLevel < 10) pw.print(' ');
+            pw.print(r.trimMemoryLevel);
+            pw.print(' ');
+            pw.print(r.toShortString());
+            pw.print(" (");
+            pw.print(r.adjType);
+            pw.println(')');
             if (r.adjSource != null || r.adjTarget != null) {
                 pw.print(prefix);
                 pw.print("    ");
@@ -10415,9 +11063,6 @@
                 pw.print(prefix);
                 pw.print("    ");
                 pw.print("oom: max="); pw.print(r.maxAdj);
-                pw.print(" hidden="); pw.print(r.hiddenAdj);
-                pw.print(" client="); pw.print(r.clientHiddenAdj);
-                pw.print(" empty="); pw.print(r.emptyAdj);
                 pw.print(" curRaw="); pw.print(r.curRawAdj);
                 pw.print(" setRaw="); pw.print(r.setRawAdj);
                 pw.print(" cur="); pw.print(r.curAdj);
@@ -10425,7 +11070,7 @@
                 pw.print(prefix);
                 pw.print("    ");
                 pw.print("keeping="); pw.print(r.keeping);
-                pw.print(" hidden="); pw.print(r.hidden);
+                pw.print(" cached="); pw.print(r.cached);
                 pw.print(" empty="); pw.print(r.empty);
                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
 
@@ -10566,23 +11211,37 @@
     }
 
     final static class MemItem {
+        final boolean isProc;
         final String label;
         final String shortLabel;
         final long pss;
         final int id;
+        final boolean hasActivities;
         ArrayList<MemItem> subitems;
 
-        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
+        public MemItem(String _label, String _shortLabel, long _pss, int _id,
+                boolean _hasActivities) {
+            isProc = true;
             label = _label;
             shortLabel = _shortLabel;
             pss = _pss;
             id = _id;
+            hasActivities = _hasActivities;
+        }
+
+        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
+            isProc = false;
+            label = _label;
+            shortLabel = _shortLabel;
+            pss = _pss;
+            id = _id;
+            hasActivities = false;
         }
     }
 
-    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
-            boolean sort) {
-        if (sort) {
+    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
+            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
+        if (sort && !isCompact) {
             Collections.sort(items, new Comparator<MemItem>() {
                 @Override
                 public int compare(MemItem lhs, MemItem rhs) {
@@ -10598,9 +11257,19 @@
 
         for (int i=0; i<items.size(); i++) {
             MemItem mi = items.get(i);
-            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
+            if (!isCompact) {
+                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
+            } else if (mi.isProc) {
+                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
+                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
+                pw.println(mi.hasActivities ? ",a" : ",e");
+            } else {
+                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
+                pw.println(mi.pss);
+            }
             if (mi.subitems != null) {
-                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
+                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
+                        true, isCompact);
             }
         }
     }
@@ -10634,23 +11303,36 @@
     }
 
     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
+            ProcessList.NATIVE_ADJ,
             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
-            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
-            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
-            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
+            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
+            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
+            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
+            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
     };
     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
+            "Native",
             "System", "Persistent", "Foreground",
-            "Visible", "Perceptible", "Heavy Weight",
-            "Backup", "A Services", "Home", "Previous",
-            "B Services", "Background"
+            "Visible", "Perceptible",
+            "Heavy Weight", "Backup",
+            "A Services", "Home",
+            "Previous", "B Services", "Cached"
+    };
+    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
+            "native",
+            "sys", "pers", "fore",
+            "vis", "percept",
+            "heavy", "backup",
+            "servicea", "home",
+            "prev", "serviceb", "cached"
     };
 
     final void dumpApplicationMemoryUsage(FileDescriptor fd,
-            PrintWriter pw, String prefix, String[] args, boolean brief,
-            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
-        boolean dumpAll = false;
+            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
+        boolean dumpDetails = false;
+        boolean dumpDalvik = false;
         boolean oomOnly = false;
+        boolean isCompact = false;
         
         int opti = 0;
         while (opti < args.length) {
@@ -10660,12 +11342,19 @@
             }
             opti++;
             if ("-a".equals(opt)) {
-                dumpAll = true;
+                dumpDetails = true;
+                dumpDalvik = true;
+            } else if ("-d".equals(opt)) {
+                dumpDalvik = true;
+            } else if ("-c".equals(opt)) {
+                isCompact = true;
             } else if ("--oom".equals(opt)) {
                 oomOnly = true;
             } else if ("-h".equals(opt)) {
-                pw.println("meminfo dump options: [-a] [--oom] [process]");
+                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
                 pw.println("  -a: include all available information for each process.");
+                pw.println("  -d: include dalvik details when dumping process details.");
+                pw.println("  -c: dump in a compact machine-parseable representation.");
                 pw.println("  --oom: only show processes organized by oom adj.");
                 pw.println("If [process] is specified it can be the name or ");
                 pw.println("pid of a specific process to dump.");
@@ -10684,14 +11373,13 @@
         long uptime = SystemClock.uptimeMillis();
         long realtime = SystemClock.elapsedRealtime();
 
-        if (procs.size() == 1 || isCheckinRequest) {
-            dumpAll = true;
+        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
+            dumpDetails = true;
         }
 
-        if (isCheckinRequest) {
+        if (isCheckinRequest || isCompact) {
             // short checkin version
-            pw.println(uptime + "," + realtime);
-            pw.flush();
+            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
         } else {
             pw.println("Applications Memory Usage (kB):");
             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
@@ -10701,26 +11389,40 @@
         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
 
         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
+        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
         long nativePss=0, dalvikPss=0, otherPss=0;
         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
 
         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
+        final long[] tmpLong = new long[1];
 
         long totalPss = 0;
+        long cachedPss = 0;
 
+        Debug.MemoryInfo mi = null;
         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
-            ProcessRecord r = procs.get(i);
-            if (r.thread != null) {
-                if (!isCheckinRequest && dumpAll) {
-                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
-                    pw.flush();
+            final ProcessRecord r = procs.get(i);
+            final IApplicationThread thread;
+            final int pid;
+            final int oomAdj;
+            final boolean hasActivities;
+            synchronized (this) {
+                thread = r.thread;
+                pid = r.pid;
+                oomAdj = r.getSetAdjWithServices();
+                hasActivities = r.hasActivities;
+            }
+            if (thread != null) {
+                if (!isCheckinRequest && dumpDetails) {
+                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
                 }
-                Debug.MemoryInfo mi = null;
-                if (dumpAll) {
+                if (dumpDetails) {
                     try {
-                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
+                        pw.flush();
+                        mi = null;
+                        mi = thread.dumpMemInfo(fd, isCheckinRequest, true, dumpDalvik, innerArgs);
                     } catch (RemoteException e) {
                         if (!isCheckinRequest) {
                             pw.println("Got RemoteException!");
@@ -10728,16 +11430,34 @@
                         }
                     }
                 } else {
-                    mi = new Debug.MemoryInfo();
-                    Debug.getMemoryInfo(r.pid, mi);
+                    if (mi == null) {
+                        mi = new Debug.MemoryInfo();
+                    }
+                    if (!brief && !oomOnly) {
+                        Debug.getMemoryInfo(pid, mi);
+                    } else {
+                        mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
+                        mi.dalvikPrivateDirty = (int)tmpLong[0];
+                    }
+                }
+
+                final long myTotalPss = mi.getTotalPss();
+                final long myTotalUss = mi.getTotalUss();
+
+                synchronized (this) {
+                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
+                        // Record this for posterity if the process has been stable.
+                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true);
+                    }
                 }
 
                 if (!isCheckinRequest && mi != null) {
-                    long myTotalPss = mi.getTotalPss();
                     totalPss += myTotalPss;
-                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
-                            r.processName, myTotalPss, 0);
+                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
+                            (hasActivities ? " / activities)" : ")"),
+                            r.processName, myTotalPss, pid, hasActivities);
                     procMems.add(pssItem);
+                    procMemsMap.put(pid, pssItem);
 
                     nativePss += mi.nativePss;
                     dalvikPss += mi.dalvikPss;
@@ -10748,8 +11468,12 @@
                         otherPss -= mem;
                     }
 
+                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
+                        cachedPss += myTotalPss;
+                    }
+
                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
-                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
+                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
                                 || oomIndex == (oomPss.length-1)) {
                             oomPss[oomIndex] += myTotalPss;
                             if (oomProcs[oomIndex] == null) {
@@ -10764,6 +11488,48 @@
         }
 
         if (!isCheckinRequest && procs.size() > 1) {
+            // If we are showing aggregations, also look for native processes to
+            // include so that our aggregations are more accurate.
+            updateCpuStatsNow();
+            synchronized (mProcessCpuThread) {
+                final int N = mProcessCpuTracker.countStats();
+                for (int i=0; i<N; i++) {
+                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
+                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
+                        if (mi == null) {
+                            mi = new Debug.MemoryInfo();
+                        }
+                        if (!brief && !oomOnly) {
+                            Debug.getMemoryInfo(st.pid, mi);
+                        } else {
+                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
+                            mi.nativePrivateDirty = (int)tmpLong[0];
+                        }
+
+                        final long myTotalPss = mi.getTotalPss();
+                        totalPss += myTotalPss;
+
+                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
+                                st.name, myTotalPss, st.pid, false);
+                        procMems.add(pssItem);
+
+                        nativePss += mi.nativePss;
+                        dalvikPss += mi.dalvikPss;
+                        otherPss += mi.otherPss;
+                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
+                            long mem = mi.getOtherPss(j);
+                            miscPss[j] += mem;
+                            otherPss -= mem;
+                        }
+                        oomPss[0] += myTotalPss;
+                        if (oomProcs[0] == null) {
+                            oomProcs[0] = new ArrayList<MemItem>();
+                        }
+                        oomProcs[0].add(pssItem);
+                    }
+                }
+            }
+
             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
 
             catMems.add(new MemItem("Native", "Native", nativePss, -1));
@@ -10777,7 +11543,8 @@
             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
             for (int j=0; j<oomPss.length; j++) {
                 if (oomPss[j] != 0) {
-                    String label = DUMP_MEM_OOM_LABEL[j];
+                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
+                            : DUMP_MEM_OOM_LABEL[j];
                     MemItem item = new MemItem(label, label, oomPss[j],
                             DUMP_MEM_OOM_ADJ[j]);
                     item.subitems = oomProcs[j];
@@ -10785,107 +11552,106 @@
                 }
             }
 
-            if (outTag != null || outStack != null) {
-                if (outTag != null) {
-                    appendMemBucket(outTag, totalPss, "total", false);
-                }
-                if (outStack != null) {
-                    appendMemBucket(outStack, totalPss, "total", true);
-                }
-                boolean firstLine = true;
-                for (int i=0; i<oomMems.size(); i++) {
-                    MemItem miCat = oomMems.get(i);
-                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
-                        continue;
-                    }
-                    if (miCat.id < ProcessList.SERVICE_ADJ
-                            || miCat.id == ProcessList.HOME_APP_ADJ
-                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
-                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
-                            outTag.append(" / ");
-                        }
-                        if (outStack != null) {
-                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
-                                if (firstLine) {
-                                    outStack.append(":");
-                                    firstLine = false;
-                                }
-                                outStack.append("\n\t at ");
-                            } else {
-                                outStack.append("$");
-                            }
-                        }
-                        for (int j=0; j<miCat.subitems.size(); j++) {
-                            MemItem mi = miCat.subitems.get(j);
-                            if (j > 0) {
-                                if (outTag != null) {
-                                    outTag.append(" ");
-                                }
-                                if (outStack != null) {
-                                    outStack.append("$");
-                                }
-                            }
-                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
-                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
-                            }
-                            if (outStack != null) {
-                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
-                            }
-                        }
-                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
-                            outStack.append("(");
-                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
-                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
-                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
-                                    outStack.append(":");
-                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
-                                }
-                            }
-                            outStack.append(")");
-                        }
-                    }
-                }
-            }
-
-            if (!brief && !oomOnly) {
+            if (!brief && !oomOnly && !isCompact) {
                 pw.println();
                 pw.println("Total PSS by process:");
-                dumpMemItems(pw, "  ", procMems, true);
+                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
                 pw.println();
             }
-            pw.println("Total PSS by OOM adjustment:");
-            dumpMemItems(pw, "  ", oomMems, false);
-            if (!oomOnly) {
-                PrintWriter out = categoryPw != null ? categoryPw : pw;
-                out.println();
-                out.println("Total PSS by category:");
-                dumpMemItems(out, "  ", catMems, true);
+            if (!isCompact) {
+                pw.println("Total PSS by OOM adjustment:");
             }
-            pw.println();
-            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
-            final int[] SINGLE_LONG_FORMAT = new int[] {
-                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
-            };
-            long[] longOut = new long[1];
-            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
-                    SINGLE_LONG_FORMAT, null, longOut, null);
-            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
-            longOut[0] = 0;
-            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
-                    SINGLE_LONG_FORMAT, null, longOut, null);
-            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
-            longOut[0] = 0;
-            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
-                    SINGLE_LONG_FORMAT, null, longOut, null);
-            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
-            longOut[0] = 0;
-            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
-                    SINGLE_LONG_FORMAT, null, longOut, null);
-            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
-            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
-                    pw.print(shared); pw.println(" kB");
-            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
-                    pw.print(voltile); pw.println(" kB volatile");
+            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
+            if (!brief && !oomOnly) {
+                PrintWriter out = categoryPw != null ? categoryPw : pw;
+                if (!isCompact) {
+                    out.println();
+                    out.println("Total PSS by category:");
+                }
+                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
+            }
+            if (!isCompact) {
+                pw.println();
+            }
+            if (!brief) {
+                MemInfoReader memInfo = new MemInfoReader();
+                memInfo.readMemInfo();
+                if (!isCompact) {
+                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSize()/1024);
+                    pw.println(" kB");
+                    pw.print(" Free RAM: "); pw.print(cachedPss + (memInfo.getCachedSize()/1024)
+                            + (memInfo.getFreeSize()/1024)); pw.println(" kB");
+                } else {
+                    pw.print("ram,"); pw.print(memInfo.getTotalSize()/1024); pw.print(",");
+                    pw.print(cachedPss + (memInfo.getCachedSize()/1024)
+                            + (memInfo.getFreeSize()/1024)); pw.print(",");
+                    pw.println(totalPss - cachedPss);
+                }
+            }
+            if (!isCompact) {
+                pw.print(" Used PSS: "); pw.print(totalPss - cachedPss); pw.println(" kB");
+            }
+            if (!brief) {
+                final int[] SINGLE_LONG_FORMAT = new int[] {
+                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
+                };
+                long[] longOut = new long[1];
+                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
+                        SINGLE_LONG_FORMAT, null, longOut, null);
+                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
+                longOut[0] = 0;
+                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
+                        SINGLE_LONG_FORMAT, null, longOut, null);
+                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
+                longOut[0] = 0;
+                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
+                        SINGLE_LONG_FORMAT, null, longOut, null);
+                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
+                longOut[0] = 0;
+                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
+                        SINGLE_LONG_FORMAT, null, longOut, null);
+                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
+                if (!isCompact) {
+                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
+                        pw.print("      KSM: "); pw.print(sharing);
+                                pw.print(" kB saved from shared ");
+                                pw.print(shared); pw.println(" kB");
+                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
+                                pw.print(voltile); pw.println(" kB volatile");
+                    }
+                    pw.print("   Tuning: ");
+                    pw.print(ActivityManager.staticGetMemoryClass());
+                    pw.print(" (large ");
+                    pw.print(ActivityManager.staticGetLargeMemoryClass());
+                    pw.print("), oom ");
+                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
+                    pw.print(" kB");
+                    if (ActivityManager.isLowRamDeviceStatic()) {
+                        pw.print(" (low-ram)");
+                    }
+                    if (ActivityManager.isHighEndGfx()) {
+                        pw.print(" (high-end-gfx)");
+                    }
+                    pw.println();
+                } else {
+                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
+                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
+                    pw.println(voltile);
+                    pw.print("tuning,");
+                    pw.print(ActivityManager.staticGetMemoryClass());
+                    pw.print(',');
+                    pw.print(ActivityManager.staticGetLargeMemoryClass());
+                    pw.print(',');
+                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
+                    if (ActivityManager.isLowRamDeviceStatic()) {
+                        pw.print(",low-ram");
+                    }
+                    if (ActivityManager.isHighEndGfx()) {
+                        pw.print(",high-end-gfx");
+                    }
+                    pw.println();
+                }
+            }
         }
     }
 
@@ -10963,10 +11729,10 @@
         }
         return inLaunching;
     }
-    
+
     /**
      * Main code for cleaning up a process when it has gone away.  This is
-     * called both as a result of the process dying, or directly when stopping 
+     * called both as a result of the process dying, or directly when stopping
      * a process when running in single process mode.
      */
     private final void cleanUpApplicationRecordLocked(ProcessRecord app,
@@ -10976,7 +11742,8 @@
         }
 
         mProcessesToGc.remove(app);
-        
+        mPendingPssProcesses.remove(app);
+
         // Dismiss any open dialogs.
         if (app.crashDialog != null && !app.forceCrashReport) {
             app.crashDialog.dismiss();
@@ -10993,10 +11760,10 @@
 
         app.crashing = false;
         app.notResponding = false;
-        
-        app.resetPackageList();
+
+        app.resetPackageList(mProcessStats);
         app.unlinkDeathRecipient();
-        app.thread = null;
+        app.makeInactive(mProcessStats);
         app.forcingToForeground = null;
         app.foregroundServices = false;
         app.foregroundActivities = false;
@@ -11008,29 +11775,25 @@
         boolean restart = false;
 
         // Remove published content providers.
-        if (!app.pubProviders.isEmpty()) {
-            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
-            while (it.hasNext()) {
-                ContentProviderRecord cpr = it.next();
-
-                final boolean always = app.bad || !allowRestart;
-                if (removeDyingProviderLocked(app, cpr, always) || always) {
-                    // We left the provider in the launching list, need to
-                    // restart it.
-                    restart = true;
-                }
-
-                cpr.provider = null;
-                cpr.proc = null;
+        for (int i=app.pubProviders.size()-1; i>=0; i--) {
+            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
+            final boolean always = app.bad || !allowRestart;
+            if (removeDyingProviderLocked(app, cpr, always) || always) {
+                // We left the provider in the launching list, need to
+                // restart it.
+                restart = true;
             }
-            app.pubProviders.clear();
+
+            cpr.provider = null;
+            cpr.proc = null;
         }
-        
+        app.pubProviders.clear();
+
         // Take care of any launching providers waiting for this process.
         if (checkAppInLaunchingProvidersLocked(app, false)) {
             restart = true;
         }
-        
+
         // Unregister from connected content providers.
         if (!app.conProviders.isEmpty()) {
             for (int i=0; i<app.conProviders.size(); i++) {
@@ -11057,18 +11820,15 @@
                 }
             }
         }
-        
+
         skipCurrentReceiverLocked(app);
 
         // Unregister any receivers.
-        if (app.receivers.size() > 0) {
-            Iterator<ReceiverList> it = app.receivers.iterator();
-            while (it.hasNext()) {
-                removeReceiverLocked(it.next());
-            }
-            app.receivers.clear();
+        for (int i=app.receivers.size()-1; i>=0; i--) {
+            removeReceiverLocked(app.receivers.valueAt(i));
         }
-        
+        app.receivers.clear();
+
         // If the app is undergoing backup, tell the backup manager about it
         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
@@ -11091,6 +11851,8 @@
         }
         mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
 
+        mHomeProcess.remove(app);
+
         // If the caller is restarting this app, then leave it in its
         // current lists and let the caller take care of it.
         if (restarting) {
@@ -11120,8 +11882,8 @@
                 "Clean-up removing on hold: " + app);
         mProcessesOnHold.remove(app);
 
-        if (app == mHomeProcess) {
-            mHomeProcess = null;
+        if (mHomeProcess.contains(app)) {
+            mHomeProcess.remove(app);
         }
         if (app == mPreviousProcess) {
             mPreviousProcess = null;
@@ -11555,7 +12317,7 @@
     private final List getStickiesLocked(String action, IntentFilter filter,
             List cur, int userId) {
         final ContentResolver resolver = mContext.getContentResolver();
-        HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
+        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
         if (stickies == null) {
             return cur;
         }
@@ -11613,7 +12375,7 @@
                             + ") when registering receiver " + receiver);
                 }
                 if (callerApp.info.uid != Process.SYSTEM_UID &&
-                        !callerApp.pkgList.contains(callerPackage)) {
+                        !callerApp.pkgList.containsKey(callerPackage)) {
                     throw new SecurityException("Given caller package " + callerPackage
                             + " is not running in process " + callerApp);
                 }
@@ -11706,7 +12468,7 @@
                     Intent intent = (Intent)allSticky.get(i);
                     BroadcastQueue queue = broadcastQueueForIntent(intent);
                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
-                            null, -1, -1, null, AppOpsManager.OP_NONE, receivers, null, 0,
+                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
                             null, null, false, true, true, -1);
                     queue.enqueueParallelBroadcastLocked(r);
                     queue.scheduleBroadcastsLocked();
@@ -11967,7 +12729,8 @@
                         String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
                         if (list != null && (list.length > 0)) {
                             for (String pkg : list) {
-                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
+                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId,
+                                        "storage unmount");
                             }
                             sendPackageBroadcastLocked(
                                     IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
@@ -11976,17 +12739,22 @@
                         Uri data = intent.getData();
                         String ssp;
                         if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
+                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
+                                    intent.getAction());
                             if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
                                 forceStopPackageLocked(ssp,
                                         intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
-                                        false, userId);
+                                        false, userId, removed ? "pkg removed" : "pkg changed");
                             }
-                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
+                            if (removed) {
                                 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
                                         new String[] {ssp}, userId);
                                 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
                                     mAppOpsService.packageRemoved(
                                             intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
+
+                                    // Remove all permissions granted from/to this package
+                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
                                 }
                             }
                         }
@@ -12057,7 +12825,7 @@
                 // But first, if this is not a broadcast to all users, then
                 // make sure it doesn't conflict with an existing broadcast to
                 // all users.
-                HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
+                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
                         UserHandle.USER_ALL);
                 if (stickies != null) {
                     ArrayList<Intent> list = stickies.get(intent.getAction());
@@ -12074,9 +12842,9 @@
                     }
                 }
             }
-            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
+            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
             if (stickies == null) {
-                stickies = new HashMap<String, ArrayList<Intent>>();
+                stickies = new ArrayMap<String, ArrayList<Intent>>();
                 mStickyBroadcasts.put(userId, stickies);
             }
             ArrayList<Intent> list = stickies.get(intent.getAction());
@@ -12133,8 +12901,8 @@
             // components to be launched.
             final BroadcastQueue queue = broadcastQueueForIntent(intent);
             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
-                    callerPackage, callingPid, callingUid, requiredPermission, appOp,
-                    registeredReceivers, resultTo, resultCode, resultData, map,
+                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
+                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
                     ordered, sticky, false, userId);
             if (DEBUG_BROADCAST) Slog.v(
                     TAG, "Enqueueing parallel broadcast " + r);
@@ -12223,9 +12991,9 @@
                 || resultTo != null) {
             BroadcastQueue queue = broadcastQueueForIntent(intent);
             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
-                    callerPackage, callingPid, callingUid, requiredPermission, appOp,
-                    receivers, resultTo, resultCode, resultData, map, ordered,
-                    sticky, false, userId);
+                    callerPackage, callingPid, callingUid, resolvedType,
+                    requiredPermission, appOp, receivers, resultTo, resultCode,
+                    resultData, map, ordered, sticky, false, userId);
             if (DEBUG_BROADCAST) Slog.v(
                     TAG, "Enqueueing ordered broadcast " + r
                     + ": prev had " + queue.mOrderedBroadcasts.size());
@@ -12329,7 +13097,7 @@
                 Slog.w(TAG, msg);
                 throw new SecurityException(msg);
             }
-            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
+            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
             if (stickies != null) {
                 ArrayList<Intent> list = stickies.get(intent.getAction());
                 if (list != null) {
@@ -12450,7 +13218,8 @@
 
             final long origId = Binder.clearCallingIdentity();
             // Instrumentation can kill and relaunch even persistent processes
-            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
+            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId,
+                    "start instr");
             ProcessRecord app = addAppLocked(ai, false);
             app.instrumentationClass = className;
             app.instrumentationInfo = ai;
@@ -12517,7 +13286,8 @@
         app.instrumentationProfileFile = null;
         app.instrumentationArguments = null;
 
-        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId);
+        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId,
+                "finished inst");
     }
 
     public void finishInstrumentation(IApplicationThread target,
@@ -12563,6 +13333,10 @@
         return config;
     }
 
+    ActivityStack getFocusedStack() {
+        return mStackSupervisor.getFocusedStack();
+    }
+
     public Configuration getConfiguration() {
         Configuration ci;
         synchronized(this) {
@@ -12624,9 +13398,7 @@
         if (mHeadless) return true;
 
         int changes = 0;
-        
-        boolean kept = true;
-        
+
         if (values != null) {
             Configuration newConfig = new Configuration(mConfiguration);
             changes = newConfig.updateFrom(values);
@@ -12704,25 +13476,27 @@
                 }
             }
         }
-        
+
+        boolean kept = true;
+        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
         if (changes != 0 && starting == null) {
             // If the configuration changed, and the caller is not already
             // in the process of starting an activity, then find the top
             // activity to check if its configuration needs to change.
-            starting = mMainStack.topRunningActivityLocked(null);
+            starting = mainStack.topRunningActivityLocked(null);
         }
-        
+
         if (starting != null) {
-            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
+            kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
             // And we need to make sure at this point that all other activities
             // are made visible with the correct configuration.
-            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
+            mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
         }
-        
+
         if (values != null && mWindowManager != null) {
             mWindowManager.setNewConfiguration(mConfiguration);
         }
-        
+
         return kept;
     }
 
@@ -12738,7 +13512,7 @@
         return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
                 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
     }
-    
+
     /**
      * Save the locale.  You must be inside a synchronized (this) block.
      */
@@ -12764,96 +13538,13 @@
 
     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
             Intent resultData) {
-        ComponentName dest = destIntent.getComponent();
 
         synchronized (this) {
-            ActivityRecord srec = ActivityRecord.forToken(token);
-            if (srec == null) {
-                return false;
+            final ActivityStack stack = ActivityRecord.getStackLocked(token);
+            if (stack != null) {
+                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
             }
-            ArrayList<ActivityRecord> history = srec.stack.mHistory;
-            final int start = history.indexOf(srec);
-            if (start < 0) {
-                // Current activity is not in history stack; do nothing.
-                return false;
-            }
-            int finishTo = start - 1;
-            ActivityRecord parent = null;
-            boolean foundParentInTask = false;
-            if (dest != null) {
-                TaskRecord tr = srec.task;
-                for (int i = start - 1; i >= 0; i--) {
-                    ActivityRecord r = history.get(i);
-                    if (tr != r.task) {
-                        // Couldn't find parent in the same task; stop at the one above this.
-                        // (Root of current task; in-app "home" behavior)
-                        // Always at least finish the current activity.
-                        finishTo = Math.min(start - 1, i + 1);
-                        parent = history.get(finishTo);
-                        break;
-                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
-                            r.info.name.equals(dest.getClassName())) {
-                        finishTo = i;
-                        parent = r;
-                        foundParentInTask = true;
-                        break;
-                    }
-                }
-            }
-
-            if (mController != null) {
-                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
-                if (next != null) {
-                    // ask watcher if this is allowed
-                    boolean resumeOK = true;
-                    try {
-                        resumeOK = mController.activityResuming(next.packageName);
-                    } catch (RemoteException e) {
-                        mController = null;
-                        Watchdog.getInstance().setActivityController(null);
-                    }
-
-                    if (!resumeOK) {
-                        return false;
-                    }
-                }
-            }
-            final long origId = Binder.clearCallingIdentity();
-            for (int i = start; i > finishTo; i--) {
-                ActivityRecord r = history.get(i);
-                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
-                        "navigate-up", true);
-                // Only return the supplied result for the first activity finished
-                resultCode = Activity.RESULT_CANCELED;
-                resultData = null;
-            }
-
-            if (parent != null && foundParentInTask) {
-                final int parentLaunchMode = parent.info.launchMode;
-                final int destIntentFlags = destIntent.getFlags();
-                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
-                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
-                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
-                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
-                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
-                } else {
-                    try {
-                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
-                                destIntent.getComponent(), 0, srec.userId);
-                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
-                                null, aInfo, parent.appToken, null,
-                                0, -1, parent.launchedFromUid, parent.launchedFromPackage,
-                                0, null, true, null);
-                        foundParentInTask = res == ActivityManager.START_SUCCESS;
-                    } catch (RemoteException e) {
-                        foundParentInTask = false;
-                    }
-                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
-                            resultData, "navigate-up", true);
-                }
-            }
-            Binder.restoreCallingIdentity(origId);
-            return foundParentInTask;
+            return false;
         }
     }
 
@@ -12899,36 +13590,25 @@
         return null;
     }
 
-    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, int clientHiddenAdj,
-            int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
+    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
+            boolean doingAll, long now) {
         if (mAdjSeq == app.adjSeq) {
-            // This adjustment has already been computed.  If we are calling
-            // from the top, we may have already computed our adjustment with
-            // an earlier hidden adjustment that isn't really for us... if
-            // so, use the new hidden adjustment.
-            if (!recursed && app.hidden) {
-                if (app.hasActivities) {
-                    app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj;
-                } else if (app.hasClientActivities) {
-                    app.curAdj = app.curRawAdj = app.nonStoppingAdj = clientHiddenAdj;
-                } else {
-                    app.curAdj = app.curRawAdj = app.nonStoppingAdj = emptyAdj;
-                }
-            }
+            // This adjustment has already been computed.
             return app.curRawAdj;
         }
 
         if (app.thread == null) {
             app.adjSeq = mAdjSeq;
             app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
-            return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
+            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
+            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
         }
 
         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
         app.adjSource = null;
         app.adjTarget = null;
         app.empty = false;
-        app.hidden = false;
+        app.cached = false;
         app.hasClientActivities = false;
 
         final int activitiesSize = app.activities.size();
@@ -12938,11 +13618,12 @@
             // below foreground, so it is not worth doing work for it.
             app.adjType = "fixed";
             app.adjSeq = mAdjSeq;
-            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
+            app.curRawAdj = app.maxAdj;
             app.hasActivities = false;
             app.foregroundActivities = false;
             app.keeping = true;
             app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
+            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
             // System process can do UI, and when they do we want to have
             // them trim their memory after the user leaves the UI.  To
             // facilitate this, here we need to determine whether or not it
@@ -12962,6 +13643,9 @@
                     }
                 }
             }
+            if (!app.systemNoUi) {
+                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
+            }
             return (app.curAdj=app.maxAdj);
         }
 
@@ -12973,6 +13657,7 @@
         // important to least, and assign an appropriate OOM adjustment.
         int adj;
         int schedGroup;
+        int procState;
         boolean foregroundActivities = false;
         boolean interesting = false;
         BroadcastQueue queue;
@@ -12984,12 +13669,14 @@
             foregroundActivities = true;
             interesting = true;
             app.hasActivities = true;
+            procState = ActivityManager.PROCESS_STATE_TOP;
         } else if (app.instrumentationClass != null) {
             // Don't want to kill running instrumentation.
             adj = ProcessList.FOREGROUND_APP_ADJ;
             schedGroup = Process.THREAD_GROUP_DEFAULT;
             app.adjType = "instrumentation";
             interesting = true;
+            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
         } else if ((queue = isReceivingBroadcast(app)) != null) {
             // An app that is currently receiving a broadcast also
             // counts as being in the foreground for OOM killer purposes.
@@ -12999,36 +13686,50 @@
             schedGroup = (queue == mFgBroadcastQueue)
                     ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
             app.adjType = "broadcast";
+            procState = ActivityManager.PROCESS_STATE_RECEIVER;
         } else if (app.executingServices.size() > 0) {
             // An app that is currently executing a service callback also
             // counts as being in the foreground.
             adj = ProcessList.FOREGROUND_APP_ADJ;
-            schedGroup = Process.THREAD_GROUP_DEFAULT;
+            schedGroup = app.execServicesFg ?
+                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
             app.adjType = "exec-service";
+            procState = ActivityManager.PROCESS_STATE_SERVICE;
+            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
         } else {
-            // Assume process is hidden (has activities); we will correct
-            // later if this is not the case.
-            adj = hiddenAdj;
+            // As far as we know the process is empty.  We may change our mind later.
             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
-            app.hidden = true;
-            app.adjType = "bg-act";
+            // At this point we don't actually know the adjustment.  Use the cached adj
+            // value that the caller wants us to.
+            adj = cachedAdj;
+            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
+            app.cached = true;
+            app.empty = true;
+            app.adjType = "cch-empty";
         }
 
-        boolean hasStoppingActivities = false;
-
         // Examine all activities if not already foreground.
         if (!foregroundActivities && activitiesSize > 0) {
             for (int j = 0; j < activitiesSize; j++) {
                 final ActivityRecord r = app.activities.get(j);
+                if (r.app != app) {
+                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
+                            + app + "?!?");
+                    continue;
+                }
+                app.hasActivities = true;
                 if (r.visible) {
                     // App has a visible activity; only upgrade adjustment.
                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
                         adj = ProcessList.VISIBLE_APP_ADJ;
                         app.adjType = "visible";
                     }
+                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
+                        procState = ActivityManager.PROCESS_STATE_TOP;
+                    }
                     schedGroup = Process.THREAD_GROUP_DEFAULT;
-                    app.hidden = false;
-                    app.hasActivities = true;
+                    app.cached = false;
+                    app.empty = false;
                     foregroundActivities = true;
                     break;
                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
@@ -13036,32 +13737,39 @@
                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
                         app.adjType = "pausing";
                     }
-                    app.hidden = false;
+                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
+                        procState = ActivityManager.PROCESS_STATE_TOP;
+                    }
+                    schedGroup = Process.THREAD_GROUP_DEFAULT;
+                    app.cached = false;
+                    app.empty = false;
                     foregroundActivities = true;
                 } else if (r.state == ActivityState.STOPPING) {
-                    // We will apply the actual adjustment later, because
-                    // we want to allow this process to immediately go through
-                    // any memory trimming that is in effect.
-                    app.hidden = false;
+                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
+                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
+                        app.adjType = "stopping";
+                    }
+                    // For the process state, we will at this point consider the
+                    // process to be cached.  It will be cached either as an activity
+                    // or empty depending on whether the activity is finishing.  We do
+                    // this so that we can treat the process as cached for purposes of
+                    // memory trimming (determing current memory level, trim command to
+                    // send to process) since there can be an arbitrary number of stopping
+                    // processes and they should soon all go into the cached state.
+                    if (!r.finishing) {
+                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
+                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
+                        }
+                    }
+                    app.cached = false;
+                    app.empty = false;
                     foregroundActivities = true;
-                    hasStoppingActivities = true;
+                } else {
+                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
+                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
+                        app.adjType = "cch-act";
+                    }
                 }
-                if (r.app == app) {
-                    app.hasActivities = true;
-                }
-            }
-        }
-
-        if (adj == hiddenAdj && !app.hasActivities) {
-            if (app.hasClientActivities) {
-                adj = clientHiddenAdj;
-                app.adjType = "bg-client-act";
-            } else {
-                // Whoops, this process is completely empty as far as we know
-                // at this point.
-                adj = emptyAdj;
-                app.empty = true;
-                app.adjType = "bg-empty";
             }
         }
 
@@ -13069,13 +13777,15 @@
             if (app.foregroundServices) {
                 // The user is aware of this app, so make it visible.
                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
-                app.hidden = false;
+                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+                app.cached = false;
                 app.adjType = "fg-service";
                 schedGroup = Process.THREAD_GROUP_DEFAULT;
             } else if (app.forcingToForeground != null) {
                 // The user is aware of this app, so make it visible.
                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
-                app.hidden = false;
+                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+                app.cached = false;
                 app.adjType = "force-fg";
                 app.adjSource = app.forcingToForeground;
                 schedGroup = Process.THREAD_GROUP_DEFAULT;
@@ -13086,32 +13796,46 @@
             interesting = true;
         }
 
-        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
-            // We don't want to kill the current heavy-weight process.
-            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
-            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
-            app.hidden = false;
-            app.adjType = "heavy";
+        if (app == mHeavyWeightProcess) {
+            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
+                // We don't want to kill the current heavy-weight process.
+                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
+                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
+                app.cached = false;
+                app.adjType = "heavy";
+            }
+            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
+                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
+            }
         }
 
-        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
-            // This process is hosting what we currently consider to be the
-            // home app, so we don't want to let it go into the background.
-            adj = ProcessList.HOME_APP_ADJ;
-            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
-            app.hidden = false;
-            app.adjType = "home";
+        if (mHomeProcess.contains(app)) {
+            if (adj > ProcessList.HOME_APP_ADJ) {
+                // This process is hosting what we currently consider to be the
+                // home app, so we don't want to let it go into the background.
+                adj = ProcessList.HOME_APP_ADJ;
+                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
+                app.cached = false;
+                app.adjType = "home";
+            }
+            if (procState > ActivityManager.PROCESS_STATE_HOME) {
+                procState = ActivityManager.PROCESS_STATE_HOME;
+            }
         }
 
-        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
-                && app.activities.size() > 0) {
-            // This was the previous process that showed UI to the user.
-            // We want to try to keep it around more aggressively, to give
-            // a good experience around switching between two apps.
-            adj = ProcessList.PREVIOUS_APP_ADJ;
-            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
-            app.hidden = false;
-            app.adjType = "previous";
+        if (app == mPreviousProcess && app.activities.size() > 0) {
+            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
+                // This was the previous process that showed UI to the user.
+                // We want to try to keep it around more aggressively, to give
+                // a good experience around switching between two apps.
+                adj = ProcessList.PREVIOUS_APP_ADJ;
+                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
+                app.cached = false;
+                app.adjType = "previous";
+            }
+            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
+                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
+            }
         }
 
         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
@@ -13122,306 +13846,318 @@
         // this gives us a baseline and makes sure we don't get into an
         // infinite recursion.
         app.adjSeq = mAdjSeq;
-        app.curRawAdj = app.nonStoppingAdj = adj;
+        app.curRawAdj = adj;
+        app.hasStartedServices = false;
 
         if (mBackupTarget != null && app == mBackupTarget.app) {
             // If possible we want to avoid killing apps while they're being backed up
             if (adj > ProcessList.BACKUP_APP_ADJ) {
                 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
                 adj = ProcessList.BACKUP_APP_ADJ;
+                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
+                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
+                }
                 app.adjType = "backup";
-                app.hidden = false;
+                app.cached = false;
+            }
+            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
+                procState = ActivityManager.PROCESS_STATE_BACKUP;
             }
         }
 
-        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
-                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
-            final long now = SystemClock.uptimeMillis();
-            // This process is more important if the top activity is
-            // bound to the service.
-            Iterator<ServiceRecord> jt = app.services.iterator();
-            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
-                ServiceRecord s = jt.next();
-                if (s.startRequested) {
-                    if (app.hasShownUi && app != mHomeProcess) {
-                        // If this process has shown some UI, let it immediately
-                        // go to the LRU list because it may be pretty heavy with
-                        // UI stuff.  We'll tag it with a label just to help
-                        // debug and understand what is going on.
+        for (int is = app.services.size()-1;
+                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
+                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
+                        || procState > ActivityManager.PROCESS_STATE_TOP);
+                is--) {
+            ServiceRecord s = app.services.valueAt(is);
+            if (s.startRequested) {
+                app.hasStartedServices = true;
+                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
+                    procState = ActivityManager.PROCESS_STATE_SERVICE;
+                }
+                if (app.hasShownUi && !mHomeProcess.contains(app)) {
+                    // If this process has shown some UI, let it immediately
+                    // go to the LRU list because it may be pretty heavy with
+                    // UI stuff.  We'll tag it with a label just to help
+                    // debug and understand what is going on.
+                    if (adj > ProcessList.SERVICE_ADJ) {
+                        app.adjType = "cch-started-ui-services";
+                    }
+                } else {
+                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
+                        // This service has seen some activity within
+                        // recent memory, so we will keep its process ahead
+                        // of the background processes.
                         if (adj > ProcessList.SERVICE_ADJ) {
-                            app.adjType = "started-bg-ui-services";
-                        }
-                    } else {
-                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
-                            // This service has seen some activity within
-                            // recent memory, so we will keep its process ahead
-                            // of the background processes.
-                            if (adj > ProcessList.SERVICE_ADJ) {
-                                adj = ProcessList.SERVICE_ADJ;
-                                app.adjType = "started-services";
-                                app.hidden = false;
-                            }
-                        }
-                        // If we have let the service slide into the background
-                        // state, still have some text describing what it is doing
-                        // even though the service no longer has an impact.
-                        if (adj > ProcessList.SERVICE_ADJ) {
-                            app.adjType = "started-bg-services";
+                            adj = ProcessList.SERVICE_ADJ;
+                            app.adjType = "started-services";
+                            app.cached = false;
                         }
                     }
-                    // Don't kill this process because it is doing work; it
-                    // has said it is doing work.
-                    app.keeping = true;
-                }
-                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
-                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
-                    Iterator<ArrayList<ConnectionRecord>> kt
-                            = s.connections.values().iterator();
-                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
-                        ArrayList<ConnectionRecord> clist = kt.next();
-                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
-                            // XXX should compute this based on the max of
-                            // all connected clients.
-                            ConnectionRecord cr = clist.get(i);
-                            if (cr.binding.client == app) {
-                                // Binding to ourself is not interesting.
-                                continue;
-                            }
-                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
-                                ProcessRecord client = cr.binding.client;
-                                int clientAdj = adj;
-                                int myHiddenAdj = hiddenAdj;
-                                if (myHiddenAdj > client.hiddenAdj) {
-                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
-                                        myHiddenAdj = client.hiddenAdj;
-                                    } else {
-                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
-                                    }
-                                }
-                                int myClientHiddenAdj = clientHiddenAdj;
-                                if (myClientHiddenAdj > client.clientHiddenAdj) {
-                                    if (client.clientHiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
-                                        myClientHiddenAdj = client.clientHiddenAdj;
-                                    } else {
-                                        myClientHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
-                                    }
-                                }
-                                int myEmptyAdj = emptyAdj;
-                                if (myEmptyAdj > client.emptyAdj) {
-                                    if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
-                                        myEmptyAdj = client.emptyAdj;
-                                    } else {
-                                        myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
-                                    }
-                                }
-                                clientAdj = computeOomAdjLocked(client, myHiddenAdj,
-                                        myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
-                                String adjType = null;
-                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
-                                    // Not doing bind OOM management, so treat
-                                    // this guy more like a started service.
-                                    if (app.hasShownUi && app != mHomeProcess) {
-                                        // If this process has shown some UI, let it immediately
-                                        // go to the LRU list because it may be pretty heavy with
-                                        // UI stuff.  We'll tag it with a label just to help
-                                        // debug and understand what is going on.
-                                        if (adj > clientAdj) {
-                                            adjType = "bound-bg-ui-services";
-                                        }
-                                        app.hidden = false;
-                                        clientAdj = adj;
-                                    } else {
-                                        if (now >= (s.lastActivity
-                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
-                                            // This service has not seen activity within
-                                            // recent memory, so allow it to drop to the
-                                            // LRU list if there is no other reason to keep
-                                            // it around.  We'll also tag it with a label just
-                                            // to help debug and undertand what is going on.
-                                            if (adj > clientAdj) {
-                                                adjType = "bound-bg-services";
-                                            }
-                                            clientAdj = adj;
-                                        }
-                                    }
-                                } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
-                                    if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) {
-                                        // If this connection is keeping the service
-                                        // created, then we want to try to better follow
-                                        // its memory management semantics for activities.
-                                        // That is, if it is sitting in the background
-                                        // LRU list as a hidden process (with activities),
-                                        // we don't want the service it is connected to
-                                        // to go into the empty LRU and quickly get killed,
-                                        // because I'll we'll do is just end up restarting
-                                        // the service.
-                                        app.hasClientActivities |= client.hasActivities;
-                                    }
-                                }
-                                if (adj > clientAdj) {
-                                    // If this process has recently shown UI, and
-                                    // the process that is binding to it is less
-                                    // important than being visible, then we don't
-                                    // care about the binding as much as we care
-                                    // about letting this process get into the LRU
-                                    // list to be killed and restarted if needed for
-                                    // memory.
-                                    if (app.hasShownUi && app != mHomeProcess
-                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
-                                        adjType = "bound-bg-ui-services";
-                                    } else {
-                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
-                                                |Context.BIND_IMPORTANT)) != 0) {
-                                            adj = clientAdj;
-                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
-                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
-                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
-                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
-                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
-                                            adj = clientAdj;
-                                        } else {
-                                            app.pendingUiClean = true;
-                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
-                                                adj = ProcessList.VISIBLE_APP_ADJ;
-                                            }
-                                        }
-                                        if (!client.hidden) {
-                                            app.hidden = false;
-                                        }
-                                        if (client.keeping) {
-                                            app.keeping = true;
-                                        }
-                                        adjType = "service";
-                                    }
-                                }
-                                if (adjType != null) {
-                                    app.adjType = adjType;
-                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
-                                            .REASON_SERVICE_IN_USE;
-                                    app.adjSource = cr.binding.client;
-                                    app.adjSourceOom = clientAdj;
-                                    app.adjTarget = s.name;
-                                }
-                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
-                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
-                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
-                                    }
-                                }
-                            }
-                            final ActivityRecord a = cr.activity;
-                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
-                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
-                                        (a.visible || a.state == ActivityState.RESUMED
-                                         || a.state == ActivityState.PAUSING)) {
-                                    adj = ProcessList.FOREGROUND_APP_ADJ;
-                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
-                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
-                                    }
-                                    app.hidden = false;
-                                    app.adjType = "service";
-                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
-                                            .REASON_SERVICE_IN_USE;
-                                    app.adjSource = a;
-                                    app.adjSourceOom = adj;
-                                    app.adjTarget = s.name;
-                                }
-                            }
-                        }
+                    // If we have let the service slide into the background
+                    // state, still have some text describing what it is doing
+                    // even though the service no longer has an impact.
+                    if (adj > ProcessList.SERVICE_ADJ) {
+                        app.adjType = "cch-started-services";
                     }
                 }
+                // Don't kill this process because it is doing work; it
+                // has said it is doing work.
+                app.keeping = true;
             }
-            
-            // Finally, if this process has active services running in it, we
-            // would like to avoid killing it unless it would prevent the current
-            // application from running.  By default we put the process in
-            // with the rest of the background processes; as we scan through
-            // its services we may bump it up from there.
-            if (adj > hiddenAdj) {
-                adj = hiddenAdj;
-                app.hidden = false;
-                app.adjType = "bg-services";
-            }
-        }
-
-        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
-                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
-            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
-            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
-                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
-                ContentProviderRecord cpr = jt.next();
-                for (int i = cpr.connections.size()-1;
-                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
-                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
-                        i--) {
-                    ContentProviderConnection conn = cpr.connections.get(i);
-                    ProcessRecord client = conn.client;
-                    if (client == app) {
-                        // Being our own client is not interesting.
+            for (int conni = s.connections.size()-1;
+                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
+                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
+                            || procState > ActivityManager.PROCESS_STATE_TOP);
+                    conni--) {
+                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
+                for (int i = 0;
+                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
+                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
+                                || procState > ActivityManager.PROCESS_STATE_TOP);
+                        i++) {
+                    // XXX should compute this based on the max of
+                    // all connected clients.
+                    ConnectionRecord cr = clist.get(i);
+                    if (cr.binding.client == app) {
+                        // Binding to ourself is not interesting.
                         continue;
                     }
-                    int myHiddenAdj = hiddenAdj;
-                    if (myHiddenAdj > client.hiddenAdj) {
-                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
-                            myHiddenAdj = client.hiddenAdj;
+                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
+                        ProcessRecord client = cr.binding.client;
+                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
+                                TOP_APP, doingAll, now);
+                        int clientProcState = client.curProcState;
+                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
+                            // If the other app is cached for any reason, for purposes here
+                            // we are going to consider it empty.  The specific cached state
+                            // doesn't propagate except under certain conditions.
+                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
+                        }
+                        String adjType = null;
+                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
+                            // Not doing bind OOM management, so treat
+                            // this guy more like a started service.
+                            if (app.hasShownUi && !mHomeProcess.contains(app)) {
+                                // If this process has shown some UI, let it immediately
+                                // go to the LRU list because it may be pretty heavy with
+                                // UI stuff.  We'll tag it with a label just to help
+                                // debug and understand what is going on.
+                                if (adj > clientAdj) {
+                                    adjType = "cch-bound-ui-services";
+                                }
+                                app.cached = false;
+                                clientAdj = adj;
+                                clientProcState = procState;
+                            } else {
+                                if (now >= (s.lastActivity
+                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
+                                    // This service has not seen activity within
+                                    // recent memory, so allow it to drop to the
+                                    // LRU list if there is no other reason to keep
+                                    // it around.  We'll also tag it with a label just
+                                    // to help debug and undertand what is going on.
+                                    if (adj > clientAdj) {
+                                        adjType = "cch-bound-services";
+                                    }
+                                    clientAdj = adj;
+                                }
+                            }
+                        } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
+                            if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) {
+                                // If this connection is keeping the service
+                                // created, then we want to try to better follow
+                                // its memory management semantics for activities.
+                                // That is, if it is sitting in the background
+                                // LRU list as a cached process (with activities),
+                                // we don't want the service it is connected to
+                                // to go into the empty LRU and quickly get killed,
+                                // because all we'll do is just end up restarting
+                                // the service.
+                                if (client.hasActivities) {
+                                    if (procState >
+                                            ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT) {
+                                        procState =
+                                                ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
+                                        app.adjType = "cch-client-act";
+                                    }
+                                    app.hasClientActivities = true;
+                                }
+                            }
+                        }
+                        if (adj > clientAdj) {
+                            // If this process has recently shown UI, and
+                            // the process that is binding to it is less
+                            // important than being visible, then we don't
+                            // care about the binding as much as we care
+                            // about letting this process get into the LRU
+                            // list to be killed and restarted if needed for
+                            // memory.
+                            if (app.hasShownUi && !mHomeProcess.contains(app)
+                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
+                                adjType = "cch-bound-ui-services";
+                            } else {
+                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
+                                        |Context.BIND_IMPORTANT)) != 0) {
+                                    adj = clientAdj;
+                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
+                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
+                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
+                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
+                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
+                                    adj = clientAdj;
+                                } else {
+                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
+                                        adj = ProcessList.VISIBLE_APP_ADJ;
+                                    }
+                                }
+                                if (!client.cached) {
+                                    app.cached = false;
+                                }
+                                if (client.keeping) {
+                                    app.keeping = true;
+                                }
+                                adjType = "service";
+                            }
+                        }
+                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
+                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
+                                schedGroup = Process.THREAD_GROUP_DEFAULT;
+                            }
+                            if (clientProcState <=
+                                    ActivityManager.PROCESS_STATE_PERSISTENT_UI &&
+                                    clientProcState >=
+                                            ActivityManager.PROCESS_STATE_PERSISTENT) {
+                                // Persistent processes don't allow us to become top.
+                                // However the top process DOES allow us to become top,
+                                // because in that case we are running because the current
+                                // top process wants us, so we should be counted as part
+                                // of the top set and not just running for some random
+                                // unknown reason in the background.
+                                clientProcState =
+                                        ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+                            }
                         } else {
-                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
+                            if (clientProcState <
+                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
+                                clientProcState =
+                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
+                            }
+                        }
+                        if (procState > clientProcState) {
+                            procState = clientProcState;
+                        }
+                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
+                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
+                            app.pendingUiClean = true;
+                        }
+                        if (adjType != null) {
+                            app.adjType = adjType;
+                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
+                                    .REASON_SERVICE_IN_USE;
+                            app.adjSource = cr.binding.client;
+                            app.adjSourceOom = clientAdj;
+                            app.adjTarget = s.name;
                         }
                     }
-                    int myClientHiddenAdj = clientHiddenAdj;
-                    if (myClientHiddenAdj > client.clientHiddenAdj) {
-                        if (client.clientHiddenAdj >= ProcessList.FOREGROUND_APP_ADJ) {
-                            myClientHiddenAdj = client.clientHiddenAdj;
-                        } else {
-                            myClientHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
+                    final ActivityRecord a = cr.activity;
+                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
+                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
+                                (a.visible || a.state == ActivityState.RESUMED
+                                 || a.state == ActivityState.PAUSING)) {
+                            adj = ProcessList.FOREGROUND_APP_ADJ;
+                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
+                                schedGroup = Process.THREAD_GROUP_DEFAULT;
+                            }
+                            app.cached = false;
+                            app.adjType = "service";
+                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
+                                    .REASON_SERVICE_IN_USE;
+                            app.adjSource = a;
+                            app.adjSourceOom = adj;
+                            app.adjTarget = s.name;
                         }
                     }
-                    int myEmptyAdj = emptyAdj;
-                    if (myEmptyAdj > client.emptyAdj) {
-                        if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
-                            myEmptyAdj = client.emptyAdj;
-                        } else {
-                            myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
-                        }
-                    }
-                    int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
-                            myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
-                    if (adj > clientAdj) {
-                        if (app.hasShownUi && app != mHomeProcess
-                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
-                            app.adjType = "bg-ui-provider";
-                        } else {
-                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
-                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
-                            app.adjType = "provider";
-                        }
-                        if (!client.hidden) {
-                            app.hidden = false;
-                        }
-                        if (client.keeping) {
-                            app.keeping = true;
-                        }
-                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
-                                .REASON_PROVIDER_IN_USE;
-                        app.adjSource = client;
-                        app.adjSourceOom = clientAdj;
-                        app.adjTarget = cpr.name;
-                    }
-                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
-                        schedGroup = Process.THREAD_GROUP_DEFAULT;
-                    }
                 }
-                // If the provider has external (non-framework) process
-                // dependencies, ensure that its adjustment is at least
-                // FOREGROUND_APP_ADJ.
-                if (cpr.hasExternalProcessHandles()) {
-                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
-                        adj = ProcessList.FOREGROUND_APP_ADJ;
-                        schedGroup = Process.THREAD_GROUP_DEFAULT;
-                        app.hidden = false;
-                        app.keeping = true;
+            }
+        }
+
+        for (int provi = app.pubProviders.size()-1;
+                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
+                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
+                        || procState > ActivityManager.PROCESS_STATE_TOP);
+                provi--) {
+            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
+            for (int i = cpr.connections.size()-1;
+                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
+                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
+                            || procState > ActivityManager.PROCESS_STATE_TOP);
+                    i--) {
+                ContentProviderConnection conn = cpr.connections.get(i);
+                ProcessRecord client = conn.client;
+                if (client == app) {
+                    // Being our own client is not interesting.
+                    continue;
+                }
+                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
+                int clientProcState = client.curProcState;
+                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
+                    // If the other app is cached for any reason, for purposes here
+                    // we are going to consider it empty.
+                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
+                }
+                if (adj > clientAdj) {
+                    if (app.hasShownUi && !mHomeProcess.contains(app)
+                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
+                        app.adjType = "cch-ui-provider";
+                    } else {
+                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
+                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
                         app.adjType = "provider";
-                        app.adjTarget = cpr.name;
                     }
+                    app.cached &= client.cached;
+                    app.keeping |= client.keeping;
+                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
+                            .REASON_PROVIDER_IN_USE;
+                    app.adjSource = client;
+                    app.adjSourceOom = clientAdj;
+                    app.adjTarget = cpr.name;
+                }
+                if (clientProcState <=
+                        ActivityManager.PROCESS_STATE_PERSISTENT_UI &&
+                        clientProcState >=
+                                ActivityManager.PROCESS_STATE_PERSISTENT) {
+                    // Persistent processes don't allow us to become top.
+                    // However the top process DOES allow us to become top,
+                    // because in that case we are running because the current
+                    // top process wants us, so we should be counted as part
+                    // of the top set and not just running for some random
+                    // unknown reason in the background.
+                    clientProcState =
+                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+                }
+                if (procState > clientProcState) {
+                    procState = clientProcState;
+                }
+                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
+                    schedGroup = Process.THREAD_GROUP_DEFAULT;
+                }
+            }
+            // If the provider has external (non-framework) process
+            // dependencies, ensure that its adjustment is at least
+            // FOREGROUND_APP_ADJ.
+            if (cpr.hasExternalProcessHandles()) {
+                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
+                    adj = ProcessList.FOREGROUND_APP_ADJ;
+                    schedGroup = Process.THREAD_GROUP_DEFAULT;
+                    app.cached = false;
+                    app.keeping = true;
+                    app.adjType = "provider";
+                    app.adjTarget = cpr.name;
+                }
+                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
+                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
                 }
             }
         }
@@ -13438,16 +14174,6 @@
             app.serviceb = false;
         }
 
-        app.nonStoppingAdj = adj;
-
-        if (hasStoppingActivities) {
-            // Only upgrade adjustment.
-            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
-                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
-                app.adjType = "stopping";
-            }
-        }
-
         app.curRawAdj = adj;
         
         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
@@ -13458,28 +14184,18 @@
                 schedGroup = Process.THREAD_GROUP_DEFAULT;
             }
         }
-        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
+        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
             app.keeping = true;
         }
 
-        if (app.hasAboveClient) {
-            // If this process has bound to any services with BIND_ABOVE_CLIENT,
-            // then we need to drop its adjustment to be lower than the service's
-            // in order to honor the request.  We want to drop it by one adjustment
-            // level...  but there is special meaning applied to various levels so
-            // we will skip some of them.
-            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
-                // System process will not get dropped, ever
-            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
-                adj = ProcessList.VISIBLE_APP_ADJ;
-            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
-                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
-            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
-                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
-            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
-                adj++;
-            }
-        }
+        // Do final modification to adj.  Everything we do between here and applying
+        // the final setAdj must be done in this function, because we will also use
+        // it when computing the final cached adj later.  Note that we don't need to
+        // worry about this for max adj above, since max adj will always be used to
+        // keep it out of the cached vaues.
+        adj = app.modifyRawOomAdj(adj);
+
+        app.curProcState = procState;
 
         int importance = app.memImportance;
         if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
@@ -13490,7 +14206,7 @@
                 // interesting in this process then we will push it to the
                 // background importance.
                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
-            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
+            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
                 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
             } else if (adj >= ProcessList.SERVICE_B_ADJ) {
                 importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
@@ -13565,6 +14281,47 @@
     }
 
     /**
+     * Schedule PSS collection of a process.
+     */
+    void requestPssLocked(ProcessRecord proc, int procState) {
+        if (mPendingPssProcesses.contains(proc)) {
+            return;
+        }
+        if (mPendingPssProcesses.size() == 0) {
+            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
+        }
+        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
+        proc.pssProcState = procState;
+        mPendingPssProcesses.add(proc);
+    }
+
+    /**
+     * Schedule PSS collection of all processes.
+     */
+    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
+        if (!always) {
+            if (now < (mLastFullPssTime +
+                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
+                return;
+            }
+        }
+        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
+        mLastFullPssTime = now;
+        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
+        mPendingPssProcesses.clear();
+        for (int i=mLruProcesses.size()-1; i>=0; i--) {
+            ProcessRecord app = mLruProcesses.get(i);
+            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
+                app.pssProcState = app.setProcState;
+                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
+                        mSleeping, now);
+                mPendingPssProcesses.add(app);
+            }
+        }
+        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
+    }
+
+    /**
      * Ask a given process to GC right now.
      */
     final void performAppGcLocked(ProcessRecord app) {
@@ -13594,8 +14351,7 @@
             }
         }
         return !processingBroadcasts
-                && (mSleeping || (mMainStack.mResumedActivity != null &&
-                        mMainStack.mResumedActivity.idle));
+                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
     }
     
     /**
@@ -13776,6 +14532,7 @@
                             + " during " + realtimeSince);
                     EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
                             app.processName, app.setAdj, "excessive wake lock");
+                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
                     Process.killProcessQuiet(app.pid);
                 } else if (doCpuKills && uptimeSince > 0
                         && ((cputimeUsed*100)/uptimeSince) >= 50) {
@@ -13788,6 +14545,7 @@
                             + " during " + uptimeSince);
                     EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
                             app.processName, app.setAdj, "excessive cpu");
+                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
                     Process.killProcessQuiet(app.pid);
                 } else {
                     app.lastWakeTime = wtime;
@@ -13797,22 +14555,10 @@
         }
     }
 
-    private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
-            int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
-        app.hiddenAdj = hiddenAdj;
-        app.clientHiddenAdj = clientHiddenAdj;
-        app.emptyAdj = emptyAdj;
-
-        if (app.thread == null) {
-            return false;
-        }
-
-        final boolean wasKeeping = app.keeping;
-
+    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
+            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
         boolean success = true;
 
-        computeOomAdjLocked(app, hiddenAdj, clientHiddenAdj, emptyAdj, TOP_APP, false, doingAll);
-
         if (app.curRawAdj != app.setRawAdj) {
             if (wasKeeping && !app.keeping) {
                 // This app is no longer something we want to keep.  Note
@@ -13873,37 +14619,98 @@
                         }
                     }
                 }
+                Process.setSwappiness(app.pid,
+                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
+            }
+        }
+        if (app.repProcState != app.curProcState) {
+            app.repProcState = app.curProcState;
+            if (!reportingProcessState && app.thread != null) {
+                try {
+                    if (false) {
+                        //RuntimeException h = new RuntimeException("here");
+                        Slog.i(TAG, "Sending new process state " + app.repProcState
+                                + " to " + app /*, h*/);
+                    }
+                    app.thread.setProcessState(app.repProcState);
+                } catch (RemoteException e) {
+                }
+            }
+        }
+        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
+                app.setProcState)) {
+            if (DEBUG_PSS) Slog.d(TAG, "Process state change from " + app.setProcState
+                    + " to " + app.curProcState + ": " + app);
+            app.lastStateTime = now;
+            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
+                    mSleeping, now);
+        } else {
+            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
+                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
+                requestPssLocked(app, app.setProcState);
+                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
+                        mSleeping, now);
+            }
+        }
+        if (app.setProcState != app.curProcState) {
+            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
+                    "Proc state change of " + app.processName
+                    + " to " + app.curProcState);
+            app.setProcState = app.curProcState;
+            if (!doingAll) {
+                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
+            } else {
+                app.procStateChanged = true;
             }
         }
         return success;
     }
 
-    private final ActivityRecord resumedAppLocked() {
-        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
-        if (resumedActivity == null || resumedActivity.app == null) {
-            resumedActivity = mMainStack.mPausingActivity;
-            if (resumedActivity == null || resumedActivity.app == null) {
-                resumedActivity = mMainStack.topRunningActivityLocked(null);
-            }
+    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
+        if (proc.thread != null) {
+            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
         }
-        return resumedActivity;
+    }
+
+    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
+            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
+        if (app.thread == null) {
+            return false;
+        }
+
+        final boolean wasKeeping = app.keeping;
+
+        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
+
+        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
+                reportingProcessState, now);
+    }
+
+    private final ActivityRecord resumedAppLocked() {
+        return mStackSupervisor.resumedAppLocked();
     }
 
     final boolean updateOomAdjLocked(ProcessRecord app) {
+        return updateOomAdjLocked(app, false);
+    }
+
+    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
         final ActivityRecord TOP_ACT = resumedAppLocked();
         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
-        int curAdj = app.curAdj;
-        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
-            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
+        final boolean wasCached = app.cached;
 
         mAdjSeq++;
 
-        boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.clientHiddenAdj,
-                app.emptyAdj, TOP_APP, false);
-        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
-            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
-        if (nowHidden != wasHidden) {
-            // Changed to/from hidden state, so apps after it in the LRU
+        // This is the desired cached adjusment we want to tell it to use.
+        // If our app is currently cached, we know it, and that is it.  Otherwise,
+        // we don't know it yet, and it needs to now be cached we will then
+        // need to do a complete oom adj.
+        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
+                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
+        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
+                SystemClock.uptimeMillis());
+        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
+            // Changed to/from cached state, so apps after it in the LRU
             // list may also be changed.
             updateOomAdjLocked();
         }
@@ -13913,7 +14720,9 @@
     final void updateOomAdjLocked() {
         final ActivityRecord TOP_ACT = resumedAppLocked();
         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
-        final long oldTime = SystemClock.uptimeMillis() - ProcessList.MAX_EMPTY_TIME;
+        final long now = SystemClock.uptimeMillis();
+        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
+        final int N = mLruProcesses.size();
 
         if (false) {
             RuntimeException e = new RuntimeException();
@@ -13925,118 +14734,139 @@
         mNewNumServiceProcs = 0;
 
         final int emptyProcessLimit;
-        final int hiddenProcessLimit;
+        final int cachedProcessLimit;
         if (mProcessLimit <= 0) {
-            emptyProcessLimit = hiddenProcessLimit = 0;
+            emptyProcessLimit = cachedProcessLimit = 0;
         } else if (mProcessLimit == 1) {
             emptyProcessLimit = 1;
-            hiddenProcessLimit = 0;
+            cachedProcessLimit = 0;
         } else {
-            emptyProcessLimit = (mProcessLimit*2)/3;
-            hiddenProcessLimit = mProcessLimit - emptyProcessLimit;
+            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
+            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
         }
 
         // Let's determine how many processes we have running vs.
         // how many slots we have for background processes; we may want
         // to put multiple processes in a slot of there are enough of
         // them.
-        int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
-                - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
-        int numEmptyProcs = mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs;
-        if (numEmptyProcs > hiddenProcessLimit) {
-            // If there are more empty processes than our limit on hidden
-            // processes, then use the hidden process limit for the factor.
+        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
+                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
+        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
+        if (numEmptyProcs > cachedProcessLimit) {
+            // If there are more empty processes than our limit on cached
+            // processes, then use the cached process limit for the factor.
             // This ensures that the really old empty processes get pushed
             // down to the bottom, so if we are running low on memory we will
-            // have a better chance at keeping around more hidden processes
+            // have a better chance at keeping around more cached processes
             // instead of a gazillion empty processes.
-            numEmptyProcs = hiddenProcessLimit;
+            numEmptyProcs = cachedProcessLimit;
         }
         int emptyFactor = numEmptyProcs/numSlots;
         if (emptyFactor < 1) emptyFactor = 1;
-        int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
-        if (hiddenFactor < 1) hiddenFactor = 1;
-        int stepHidden = 0;
+        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
+        if (cachedFactor < 1) cachedFactor = 1;
+        int stepCached = 0;
         int stepEmpty = 0;
-        int numHidden = 0;
+        int numCached = 0;
         int numEmpty = 0;
         int numTrimming = 0;
 
-        mNumNonHiddenProcs = 0;
-        mNumHiddenProcs = 0;
+        mNumNonCachedProcs = 0;
+        mNumCachedHiddenProcs = 0;
 
         // First update the OOM adjustment for each of the
         // application processes based on their current state.
-        int i = mLruProcesses.size();
-        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
-        int nextHiddenAdj = curHiddenAdj+1;
-        int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
+        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
+        int nextCachedAdj = curCachedAdj+1;
+        int curClientCachedAdj = curCachedAdj+1;
+        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
         int nextEmptyAdj = curEmptyAdj+2;
-        int curClientHiddenAdj = curEmptyAdj;
-        while (i > 0) {
-            i--;
+        for (int i=N-1; i>=0; i--) {
             ProcessRecord app = mLruProcesses.get(i);
-            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
-            updateOomAdjLocked(app, curHiddenAdj, curClientHiddenAdj, curEmptyAdj, TOP_APP, true);
-            if (!app.killedBackground) {
-                if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
-                    // This process was assigned as a hidden process...  step the
-                    // hidden level.
-                    mNumHiddenProcs++;
-                    if (curHiddenAdj != nextHiddenAdj) {
-                        stepHidden++;
-                        if (stepHidden >= hiddenFactor) {
-                            stepHidden = 0;
-                            curHiddenAdj = nextHiddenAdj;
-                            nextHiddenAdj += 2;
-                            if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
-                                nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
-                            }
-                            if (curClientHiddenAdj <= curHiddenAdj) {
-                                curClientHiddenAdj = curHiddenAdj + 1;
-                                if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
-                                    curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
+            if (!app.killedBackground && app.thread != null) {
+                app.procStateChanged = false;
+                final boolean wasKeeping = app.keeping;
+                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
+
+                // If we haven't yet assigned the final cached adj
+                // to the process, do that now.
+                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
+                    switch (app.curProcState) {
+                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
+                            // This process is a cached process holding activities...
+                            // assign it the next cached value for that type, and then
+                            // step that cached level.
+                            app.curRawAdj = curCachedAdj;
+                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
+                            if (curCachedAdj != nextCachedAdj) {
+                                stepCached++;
+                                if (stepCached >= cachedFactor) {
+                                    stepCached = 0;
+                                    curCachedAdj = nextCachedAdj;
+                                    nextCachedAdj += 2;
+                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
+                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
+                                    }
+                                    if (curClientCachedAdj <= curCachedAdj) {
+                                        curClientCachedAdj = curCachedAdj + 1;
+                                        if (curClientCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
+                                            curClientCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
+                                        }
+                                    }
                                 }
                             }
-                        }
-                    }
-                    numHidden++;
-                    if (numHidden > hiddenProcessLimit) {
-                        Slog.i(TAG, "No longer want " + app.processName
-                                + " (pid " + app.pid + "): hidden #" + numHidden);
-                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
-                                app.processName, app.setAdj, "too many background");
-                        app.killedBackground = true;
-                        Process.killProcessQuiet(app.pid);
-                    }
-                } else if (app.curRawAdj == curHiddenAdj && app.hasClientActivities) {
-                    // This process has a client that has activities.  We will have
-                    // given it the current hidden adj; here we will just leave it
-                    // without stepping the hidden adj.
-                    curClientHiddenAdj++;
-                    if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
-                        curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
-                    }
-                } else {
-                    if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
-                        // This process was assigned as an empty process...  step the
-                        // empty level.
-                        if (curEmptyAdj != nextEmptyAdj) {
-                            stepEmpty++;
-                            if (stepEmpty >= emptyFactor) {
-                                stepEmpty = 0;
-                                curEmptyAdj = nextEmptyAdj;
-                                nextEmptyAdj += 2;
-                                if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
-                                    nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
+                            break;
+                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
+                            // Special case for cached client processes...  just step
+                            // down from after regular cached processes.
+                            app.curRawAdj = curClientCachedAdj;
+                            app.curAdj = app.modifyRawOomAdj(curClientCachedAdj);
+                            curClientCachedAdj++;
+                            if (curClientCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
+                                curClientCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
+                            }
+                            break;
+                        default:
+                            // For everything else, assign next empty cached process
+                            // level and bump that up.  Note that this means that
+                            // long-running services that have dropped down to the
+                            // cached level will be treated as empty (since their process
+                            // state is still as a service), which is what we want.
+                            app.curRawAdj = curEmptyAdj;
+                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
+                            if (curEmptyAdj != nextEmptyAdj) {
+                                stepEmpty++;
+                                if (stepEmpty >= emptyFactor) {
+                                    stepEmpty = 0;
+                                    curEmptyAdj = nextEmptyAdj;
+                                    nextEmptyAdj += 2;
+                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
+                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
+                                    }
                                 }
                             }
-                        }
-                    } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
-                        mNumNonHiddenProcs++;
+                            break;
                     }
-                    if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
-                            && !app.hasClientActivities) {
+                }
+
+                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
+
+                // Count the number of process types.
+                switch (app.curProcState) {
+                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
+                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
+                        mNumCachedHiddenProcs++;
+                        numCached++;
+                        if (numCached > cachedProcessLimit) {
+                            Slog.i(TAG, "No longer want " + app.processName
+                                    + " (pid " + app.pid + "): cached #" + numCached);
+                            EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
+                                    app.processName, app.setAdj, "too many background");
+                            app.killedBackground = true;
+                            Process.killProcessQuiet(app.pid);
+                        }
+                        break;
+                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
                                 && app.lastActivityTime < oldTime) {
                             Slog.i(TAG, "No longer want " + app.processName
@@ -14058,8 +14888,12 @@
                                 Process.killProcessQuiet(app.pid);
                             }
                         }
-                    }
+                        break;
+                    default:
+                        mNumNonCachedProcs++;
+                        break;
                 }
+
                 if (app.isolated && app.services.size() <= 0) {
                     // If this is an isolated process, and there are no
                     // services running in it, then the process is no longer
@@ -14074,8 +14908,8 @@
                     app.killedBackground = true;
                     Process.killProcessQuiet(app.pid);
                 }
-                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
-                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
+
+                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
                         && !app.killedBackground) {
                     numTrimming++;
                 }
@@ -14090,10 +14924,10 @@
         // are managing to keep around is less than half the maximum we desire;
         // if we are keeping a good number around, we'll let them use whatever
         // memory they want.
-        if (numHidden <= ProcessList.TRIM_HIDDEN_APPS
+        boolean allChanged;
+        if (numCached <= ProcessList.TRIM_CACHED_APPS
                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
-            final int numHiddenAndEmpty = numHidden + numEmpty;
-            final int N = mLruProcesses.size();
+            final int numCachedAndEmpty = numCached + numEmpty;
             int factor = numTrimming/3;
             int minFactor = 2;
             if (mHomeProcess != null) minFactor++;
@@ -14101,21 +14935,33 @@
             if (factor < minFactor) factor = minFactor;
             int step = 0;
             int fgTrimLevel;
-            if (numHiddenAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
+            int memFactor;
+            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
                 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
-            } else if (numHiddenAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
+                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
+            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
                 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
+                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
             } else {
                 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
+                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
             }
             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
-            for (i=0; i<N; i++) {
+            allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
+            final int trackerMemFactor = mProcessStats.getMemFactorLocked();
+            for (int i=N-1; i>=0; i--) {
                 ProcessRecord app = mLruProcesses.get(i);
-                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
-                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
+                if (allChanged || app.procStateChanged) {
+                    setProcessTrackerState(app, trackerMemFactor, now);
+                    app.procStateChanged = false;
+                }
+                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
                         && !app.killedBackground) {
                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
                         try {
+                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
+                                    "Trimming memory of " + app.processName
+                                    + " to " + curLevel);
                             app.thread.scheduleTrimMemory(curLevel);
                         } catch (RemoteException e) {
                         }
@@ -14124,12 +14970,12 @@
                             // to be good enough at this point that destroying
                             // activities causes more harm than good.
                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
-                                    && app != mHomeProcess && app != mPreviousProcess) {
+                                    && !mHomeProcess.contains(app) && app != mPreviousProcess) {
                                 // Need to do this on its own message because the stack may not
                                 // be in a consistent state at this point.
                                 // For these apps we will also finish their activities
                                 // to help them free memory.
-                                mMainStack.scheduleDestroyActivities(app, false, "trim");
+                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
                             }
                         }
                     }
@@ -14146,10 +14992,13 @@
                                 break;
                         }
                     }
-                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
+                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
                             && app.thread != null) {
                         try {
+                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
+                                    "Trimming memory of heavy-weight " + app.processName
+                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
                             app.thread.scheduleTrimMemory(
                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
                         } catch (RemoteException e) {
@@ -14157,14 +15006,17 @@
                     }
                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
                 } else {
-                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
-                            && app.pendingUiClean) {
+                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
+                            || app.systemNoUi) && app.pendingUiClean) {
                         // If this application is now in the background and it
                         // had done UI, then give it the special trim level to
                         // have it free UI resources.
                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
                         if (app.trimMemoryLevel < level && app.thread != null) {
                             try {
+                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
+                                        "Trimming memory of bg-ui " + app.processName
+                                        + " to " + level);
                                 app.thread.scheduleTrimMemory(level);
                             } catch (RemoteException e) {
                             }
@@ -14173,6 +15025,9 @@
                     }
                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
                         try {
+                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
+                                    "Trimming memory of fg " + app.processName
+                                    + " to " + fgTrimLevel);
                             app.thread.scheduleTrimMemory(fgTrimLevel);
                         } catch (RemoteException e) {
                         }
@@ -14181,14 +15036,23 @@
                 }
             }
         } else {
-            final int N = mLruProcesses.size();
-            for (i=0; i<N; i++) {
+            allChanged = mProcessStats.setMemFactorLocked(
+                    ProcessStats.ADJ_MEM_FACTOR_NORMAL, !mSleeping, now);
+            final int trackerMemFactor = mProcessStats.getMemFactorLocked();
+            for (int i=N-1; i>=0; i--) {
                 ProcessRecord app = mLruProcesses.get(i);
-                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
-                        && app.pendingUiClean) {
+                if (allChanged || app.procStateChanged) {
+                    setProcessTrackerState(app, trackerMemFactor, now);
+                    app.procStateChanged = false;
+                }
+                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
+                        || app.systemNoUi) && app.pendingUiClean) {
                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
                             && app.thread != null) {
                         try {
+                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
+                                    "Trimming memory of ui hidden " + app.processName
+                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
                             app.thread.scheduleTrimMemory(
                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
                         } catch (RemoteException e) {
@@ -14203,7 +15067,25 @@
         if (mAlwaysFinishActivities) {
             // Need to do this on its own message because the stack may not
             // be in a consistent state at this point.
-            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
+            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
+        }
+
+        if (allChanged) {
+            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
+        }
+
+        if (mProcessStats.shouldWriteNowLocked(now)) {
+            mHandler.post(new Runnable() {
+                @Override public void run() {
+                    synchronized (ActivityManagerService.this) {
+                        mProcessStats.writeStateAsyncLocked();
+                    }
+                }
+            });
+        }
+
+        if (DEBUG_OOM_ADJ) {
+            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
         }
     }
 
@@ -14378,7 +15260,7 @@
         }
 
         if (proc == null) {
-            HashMap<String, SparseArray<ProcessRecord>> all
+            ArrayMap<String, SparseArray<ProcessRecord>> all
                     = mProcessNames.getMap();
             SparseArray<ProcessRecord> procs = all.get(process);
             if (procs != null && procs.size() > 0) {
@@ -14503,7 +15385,6 @@
                 }
 
                 mCurrentUserId = userId;
-                mCurrentUserArray = new int[] { userId };
                 final Integer userIdInt = Integer.valueOf(userId);
                 mUserLru.remove(userIdInt);
                 mUserLru.add(userIdInt);
@@ -14569,7 +15450,7 @@
                     }
                 }
 
-                boolean haveActivities = mMainStack.switchUserLocked(userId, uss);
+                boolean haveActivities = mStackSupervisor.switchUserLocked(userId, uss);
                 if (!haveActivities) {
                     startHomeActivityLocked(userId);
                 }
@@ -14825,6 +15706,7 @@
                 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
                 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
                 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
+                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
                 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
                 // This is the result receiver for the final shutdown broadcast.
                 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
@@ -14884,7 +15766,7 @@
 
                 // Clean up all state and processes associated with the user.
                 // Kill all the processes for the user.
-                forceStopUserLocked(userId);
+                forceStopUserLocked(userId, "finish user");
             }
         }
 
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index aa82be3..6e50808 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -16,12 +16,14 @@
 
 package com.android.server.am;
 
+import android.os.Trace;
+import com.android.internal.R.styleable;
 import com.android.internal.app.ResolverActivity;
 import com.android.server.AttributeCache;
 import com.android.server.am.ActivityStack.ActivityState;
 
-import android.app.Activity;
 import android.app.ActivityOptions;
+import android.app.ResultInfo;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
@@ -54,8 +56,10 @@
  * An entry in the history stack, representing an activity.
  */
 final class ActivityRecord {
+    static final String TAG = ActivityManagerService.TAG;
+    static final boolean DEBUG_SAVED_STATE = ActivityStackSupervisor.DEBUG_SAVED_STATE;
+
     final ActivityManagerService service; // owner
-    final ActivityStack stack; // owner
     final IApplicationToken.Stub appToken; // window manager token
     final ActivityInfo info; // all about me
     final int launchedFromUid; // always the uid who started the activity.
@@ -69,22 +73,29 @@
     final String processName; // process where this component wants to run
     final String taskAffinity; // as per ActivityInfo.taskAffinity
     final boolean stateNotNeeded; // As per ActivityInfo.flags
-    final boolean fullscreen; // covers the full screen?
+    boolean fullscreen; // covers the full screen?
     final boolean noDisplay;  // activity is not displayed?
     final boolean componentSpecified;  // did caller specifiy an explicit component?
-    final boolean isHomeActivity; // do we consider this to be a home activity?
+
+    static final int APPLICATION_ACTIVITY_TYPE = 0;
+    static final int HOME_ACTIVITY_TYPE = 1;
+    static final int RECENTS_ACTIVITY_TYPE = 2;
+    int mActivityType;
+
     final String baseDir;   // where activity source (resources etc) located
     final String resDir;   // where public activity source (public resources etc) located
     final String dataDir;   // where activity data should go
     CharSequence nonLocalizedLabel;  // the label information from the package mgr.
     int labelRes;           // the label information from the package mgr.
     int icon;               // resource identifier of activity's icon.
+    int logo;               // resource identifier of activity's logo.
     int theme;              // resource identifier of activity's theme.
     int realTheme;          // actual theme resource we will use, never 0.
     int windowFlags;        // custom window flags for preview window.
     TaskRecord task;        // the task this is in.
     ThumbnailHolder thumbHolder; // where our thumbnails should go.
-    long launchTime;        // when we starting launching this activity
+    long displayStartTime;  // when we started launching this activity
+    long fullyDrawnStartTime; // when we started launching this activity
     long startTime;         // last time this activity was started
     long lastVisibleTime;   // last time this activity became visible
     long cpuTimeAtResume;   // the cpu time of host process at the time of resuming activity
@@ -95,9 +106,9 @@
     ActivityRecord resultTo; // who started this entry, so will get our reply
     final String resultWho; // additional identifier for use by resultTo.
     final int requestCode;  // code given by requester (resultTo)
-    ArrayList results;      // pending ActivityResult objs we have received
+    ArrayList<ResultInfo> results; // pending ActivityResult objs we have received
     HashSet<WeakReference<PendingIntentRecord>> pendingResults; // all pending intents for this act
-    ArrayList newIntents;   // any pending new intents for single-top mode
+    ArrayList<Intent> newIntents; // any pending new intents for single-top mode
     ActivityOptions pendingOptions; // most recently given options
     HashSet<ConnectionRecord> connections; // All ConnectionRecord we hold
     UriPermissionOwner uriPermissions; // current special URI access perms.
@@ -128,15 +139,19 @@
     long lastLaunchTime;    // time of last lauch of this activity
 
     String stringName;      // for caching of toString().
-    
+
     private boolean inHistory;  // are we in the history stack?
+    final ActivityStackSupervisor mStackSupervisor;
+
+    /** Launch the home activity rather than the activity at the top of stack */
+    boolean mLaunchHomeTaskNext;
 
     void dump(PrintWriter pw, String prefix) {
         final long now = SystemClock.uptimeMillis();
         pw.print(prefix); pw.print("packageName="); pw.print(packageName);
                 pw.print(" processName="); pw.println(processName);
         pw.print(prefix); pw.print("launchedFromUid="); pw.print(launchedFromUid);
-                pw.print(" launchedFromPackage="); pw.println(launchedFromPackage);
+                pw.print(" launchedFromPackage="); pw.print(launchedFromPackage);
                 pw.print(" userId="); pw.println(userId);
         pw.print(prefix); pw.print("app="); pw.println(app);
         pw.print(prefix); pw.println(intent.toInsecureStringWithClip());
@@ -152,7 +167,7 @@
         pw.print(prefix); pw.print("dataDir="); pw.println(dataDir);
         pw.print(prefix); pw.print("stateNotNeeded="); pw.print(stateNotNeeded);
                 pw.print(" componentSpecified="); pw.print(componentSpecified);
-                pw.print(" isHomeActivity="); pw.println(isHomeActivity);
+                pw.print(" mActivityType="); pw.println(mActivityType);
         pw.print(prefix); pw.print("compat="); pw.print(compat);
                 pw.print(" labelRes=0x"); pw.print(Integer.toHexString(labelRes));
                 pw.print(" icon=0x"); pw.print(Integer.toHexString(icon));
@@ -182,7 +197,7 @@
         if (newIntents != null && newIntents.size() > 0) {
             pw.print(prefix); pw.println("Pending New Intents:");
             for (int i=0; i<newIntents.size(); i++) {
-                Intent intent = (Intent)newIntents.get(i);
+                Intent intent = newIntents.get(i);
                 pw.print(prefix); pw.print("  - ");
                 if (intent == null) {
                     pw.println("null");
@@ -210,7 +225,7 @@
                 if (lastLaunchTime == 0) pw.print("0");
                 else TimeUtils.formatDuration(lastLaunchTime, now, pw);
                 pw.println();
-        pw.print(prefix); pw.print(" haveState="); pw.print(haveState);
+        pw.print(prefix); pw.print("haveState="); pw.print(haveState);
                 pw.print(" icicle="); pw.println(icicle);
         pw.print(prefix); pw.print("state="); pw.print(state);
                 pw.print(" stopped="); pw.print(stopped);
@@ -235,10 +250,10 @@
                     pw.print(" desc="); pw.print(thumbHolder.lastDescription);
                 }
                 pw.println();
-        if (launchTime != 0 || startTime != 0) {
-            pw.print(prefix); pw.print("launchTime=");
-                    if (launchTime == 0) pw.print("0");
-                    else TimeUtils.formatDuration(launchTime, now, pw);
+        if (displayStartTime != 0 || startTime != 0) {
+            pw.print(prefix); pw.print("displayStartTime=");
+                    if (displayStartTime == 0) pw.print("0");
+                    else TimeUtils.formatDuration(displayStartTime, now, pw);
                     pw.print(" startTime=");
                     if (startTime == 0) pw.print("0");
                     else TimeUtils.formatDuration(startTime, now, pw);
@@ -269,36 +284,33 @@
             weakActivity = new WeakReference<ActivityRecord>(activity);
         }
 
-        @Override public void windowsDrawn() throws RemoteException {
+        @Override public void windowsDrawn() {
             ActivityRecord activity = weakActivity.get();
             if (activity != null) {
                 activity.windowsDrawn();
             }
         }
 
-        @Override public void windowsVisible() throws RemoteException {
+        @Override public void windowsVisible() {
             ActivityRecord activity = weakActivity.get();
             if (activity != null) {
                 activity.windowsVisible();
             }
         }
 
-        @Override public void windowsGone() throws RemoteException {
+        @Override public void windowsGone() {
             ActivityRecord activity = weakActivity.get();
             if (activity != null) {
                 activity.windowsGone();
             }
         }
 
-        @Override public boolean keyDispatchingTimedOut() throws RemoteException {
+        @Override public boolean keyDispatchingTimedOut(String reason) {
             ActivityRecord activity = weakActivity.get();
-            if (activity != null) {
-                return activity.keyDispatchingTimedOut();
-            }
-            return false;
+            return activity != null && activity.keyDispatchingTimedOut(reason);
         }
 
-        @Override public long getKeyDispatchingTimeout() throws RemoteException {
+        @Override public long getKeyDispatchingTimeout() {
             ActivityRecord activity = weakActivity.get();
             if (activity != null) {
                 return activity.getKeyDispatchingTimeout();
@@ -306,6 +318,7 @@
             return 0;
         }
 
+        @Override
         public String toString() {
             StringBuilder sb = new StringBuilder(128);
             sb.append("Token{");
@@ -326,13 +339,16 @@
         }
     }
 
-    ActivityRecord(ActivityManagerService _service, ActivityStack _stack, ProcessRecord _caller,
+    boolean isNotResolverActivity() {
+        return !ResolverActivity.class.getName().equals(realActivity.getClassName());
+    }
+
+    ActivityRecord(ActivityManagerService _service, ProcessRecord _caller,
             int _launchedFromUid, String _launchedFromPackage, Intent _intent, String _resolvedType,
             ActivityInfo aInfo, Configuration _configuration,
             ActivityRecord _resultTo, String _resultWho, int _reqCode,
-            boolean _componentSpecified) {
+            boolean _componentSpecified, ActivityStackSupervisor supervisor) {
         service = _service;
-        stack = _stack;
         appToken = new Token(this);
         info = aInfo;
         launchedFromUid = _launchedFromUid;
@@ -361,6 +377,7 @@
         thumbnailNeeded = false;
         idle = false;
         hasBeenLaunched = false;
+        mStackSupervisor = supervisor;
 
         // This starts out true, since the initial state of an activity
         // is that we have everything, and we shouldn't never consider it
@@ -390,6 +407,7 @@
                 labelRes = app.labelRes;
             }
             icon = aInfo.getIconResource();
+            logo = aInfo.getLogoResource();
             theme = aInfo.getThemeResource();
             realTheme = theme;
             if (realTheme == 0) {
@@ -413,10 +431,10 @@
             if (intent != null && (aInfo.flags & ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS) != 0) {
                 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
             }
-            
+
             packageName = aInfo.applicationInfo.packageName;
             launchMode = aInfo.launchMode;
-            
+
             AttributeCache.Entry ent = AttributeCache.instance().get(packageName,
                     realTheme, com.android.internal.R.styleable.Window, userId);
             fullscreen = ent != null && !ent.array.getBoolean(
@@ -425,29 +443,29 @@
                     com.android.internal.R.styleable.Window_windowIsTranslucent, false);
             noDisplay = ent != null && ent.array.getBoolean(
                     com.android.internal.R.styleable.Window_windowNoDisplay, false);
-            
-            if (!_componentSpecified || _launchedFromUid == Process.myUid()
-                    || _launchedFromUid == 0) {
-                // If we know the system has determined the component, then
-                // we can consider this to be a home activity...
-                if (Intent.ACTION_MAIN.equals(_intent.getAction()) &&
-                        _intent.hasCategory(Intent.CATEGORY_HOME) &&
-                        _intent.getCategories().size() == 1 &&
-                        _intent.getData() == null &&
-                        _intent.getType() == null &&
-                        (intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
-                        !ResolverActivity.class.getName().equals(realActivity.getClassName())) {
-                    // This sure looks like a home activity!
-                    // Note the last check is so we don't count the resolver
-                    // activity as being home...  really, we don't care about
-                    // doing anything special with something that comes from
-                    // the core framework package.
-                    isHomeActivity = true;
-                } else {
-                    isHomeActivity = false;
+
+            // If we know the system has determined the component, then
+            // we can consider this to be a home activity...
+            String homePackageName = supervisor.getHomePackageName();
+            if (homePackageName != null && homePackageName.equals(packageName)) {
+                mActivityType = HOME_ACTIVITY_TYPE;
+            } else if ((!_componentSpecified || _launchedFromUid == Process.myUid()
+                    || _launchedFromUid == 0) &&
+                    Intent.ACTION_MAIN.equals(_intent.getAction()) &&
+                    _intent.hasCategory(Intent.CATEGORY_HOME) &&
+                    _intent.getCategories().size() == 1 &&
+                    _intent.getData() == null &&
+                    _intent.getType() == null &&
+                    (intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
+                // This sure looks like a home activity!
+                mActivityType = HOME_ACTIVITY_TYPE;
+                if (isNotResolverActivity()) {
+                    supervisor.setHomePackageName(userId, packageName);
                 }
+            } else if (realActivity.getClassName().contains("com.android.systemui.recent")) {
+                mActivityType = RECENTS_ACTIVITY_TYPE;
             } else {
-                isHomeActivity = false;
+                mActivityType = APPLICATION_ACTIVITY_TYPE;
             }
 
             immersive = (aInfo.flags & ActivityInfo.FLAG_IMMERSIVE) != 0;
@@ -462,12 +480,15 @@
             packageName = null;
             fullscreen = true;
             noDisplay = false;
-            isHomeActivity = false;
+            mActivityType = APPLICATION_ACTIVITY_TYPE;
             immersive = false;
         }
     }
 
     void setTask(TaskRecord newTask, ThumbnailHolder newThumbHolder, boolean isRoot) {
+        if (task != null && task.removeActivity(this)) {
+            mStackSupervisor.removeTask(task);
+        }
         if (inHistory && !finishing) {
             if (task != null) {
                 task.numActivities--;
@@ -490,6 +511,25 @@
         }
     }
 
+    boolean changeWindowTranslucency(boolean toOpaque) {
+        if (fullscreen == toOpaque) {
+            return false;
+        }
+        AttributeCache.Entry ent =
+                AttributeCache.instance().get(packageName, realTheme, styleable.Window, userId);
+        if (ent == null
+                || !ent.array.getBoolean(styleable.Window_windowIsTranslucent, false)
+                || ent.array.getBoolean(styleable.Window_windowIsFloating, false)) {
+            return false;
+        }
+
+        // Keep track of the number of fullscreen activities in this task.
+        task.numFullscreen += toOpaque ? +1 : -1;
+
+        fullscreen = toOpaque;
+        return true;
+    }
+
     void putInHistory() {
         if (!inHistory) {
             inHistory = true;
@@ -504,6 +544,7 @@
             inHistory = false;
             if (task != null && !finishing) {
                 task.numActivities--;
+                task = null;
             }
             clearOptionsLocked();
         }
@@ -513,6 +554,18 @@
         return inHistory;
     }
 
+    boolean isHomeActivity() {
+        return mActivityType == HOME_ACTIVITY_TYPE;
+    }
+
+    boolean isRecentsActivity() {
+        return mActivityType == RECENTS_ACTIVITY_TYPE;
+    }
+
+    boolean isApplicationActivity() {
+        return mActivityType == APPLICATION_ACTIVITY_TYPE;
+    }
+
     void makeFinishing() {
         if (!finishing) {
             finishing = true;
@@ -525,6 +578,11 @@
         }
     }
 
+    boolean isRootActivity() {
+        ArrayList<ActivityRecord> activities = task.mActivities;
+        return activities.size() == 0 || this == task.mActivities.get(0);
+    }
+
     UriPermissionOwner getUriPermissionsLocked() {
         if (uriPermissions == null) {
             uriPermissions = new UriPermissionOwner(service, this);
@@ -538,7 +596,7 @@
         ActivityResult r = new ActivityResult(from, resultWho,
         		requestCode, resultCode, resultData);
         if (results == null) {
-            results = new ArrayList();
+            results = new ArrayList<ResultInfo>();
         }
         results.add(r);
     }
@@ -563,17 +621,16 @@
 
     void addNewIntentLocked(Intent intent) {
         if (newIntents == null) {
-            newIntents = new ArrayList();
+            newIntents = new ArrayList<Intent>();
         }
         newIntents.add(intent);
     }
-    
+
     /**
      * Deliver a new Intent to an existing activity, so that its onNewIntent()
      * method will be called at the proper time.
      */
     final void deliverNewIntentLocked(int callingUid, Intent intent) {
-        boolean sent = false;
         // The activity now gets access to the data associated with this Intent.
         service.grantUriPermissionFromIntentLocked(callingUid, packageName,
                 intent, getUriPermissionsLocked());
@@ -582,15 +639,16 @@
         // device is sleeping, then all activities are stopped, so in that
         // case we will deliver it if this is the current top activity on its
         // stack.
+        boolean unsent = true;
         if ((state == ActivityState.RESUMED || (service.mSleeping
-                        && stack.topRunningActivityLocked(null) == this))
+                        && task.stack.topRunningActivityLocked(null) == this))
                 && app != null && app.thread != null) {
             try {
                 ArrayList<Intent> ar = new ArrayList<Intent>();
                 intent = new Intent(intent);
                 ar.add(intent);
                 app.thread.scheduleNewIntent(ar, appToken);
-                sent = true;
+                unsent = false;
             } catch (RemoteException e) {
                 Slog.w(ActivityManagerService.TAG,
                         "Exception thrown sending new intent to " + this, e);
@@ -599,7 +657,7 @@
                         "Exception thrown sending new intent to " + this, e);
             }
         }
-        if (!sent) {
+        if (unsent) {
             addNewIntentLocked(new Intent(intent));
         }
     }
@@ -701,9 +759,6 @@
     }
 
     void updateThumbnail(Bitmap newThumbnail, CharSequence description) {
-        if ((intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
-            // This is a logical break in the task; it repre
-        }
         if (thumbHolder != null) {
             if (newThumbnail != null) {
                 if (ActivityManagerService.DEBUG_THUMBNAILS) Slog.i(ActivityManagerService.TAG,
@@ -727,8 +782,8 @@
 
     boolean continueLaunchTickingLocked() {
         if (launchTickTime != 0) {
-            Message msg = stack.mHandler.obtainMessage(ActivityStack.LAUNCH_TICK_MSG);
-            msg.obj = this;
+            final ActivityStack stack = task.stack;
+            Message msg = stack.mHandler.obtainMessage(ActivityStack.LAUNCH_TICK_MSG, this);
             stack.mHandler.removeMessages(ActivityStack.LAUNCH_TICK_MSG);
             stack.mHandler.sendMessageDelayed(msg, ActivityStack.LAUNCH_TICK);
             return true;
@@ -738,7 +793,7 @@
 
     void finishLaunchTickingLocked() {
         launchTickTime = 0;
-        stack.mHandler.removeMessages(ActivityStack.LAUNCH_TICK_MSG);
+        task.stack.mHandler.removeMessages(ActivityStack.LAUNCH_TICK_MSG);
     }
 
     // IApplicationToken
@@ -750,50 +805,91 @@
         // so it is best to leave as-is.
         return app != null && !app.crashing && !app.notResponding;
     }
-    
+
     public void startFreezingScreenLocked(ProcessRecord app, int configChanges) {
         if (mayFreezeScreenLocked(app)) {
             service.mWindowManager.startAppFreezingScreen(appToken, configChanges);
         }
     }
-    
+
     public void stopFreezingScreenLocked(boolean force) {
         if (force || frozenBeforeDestroy) {
             frozenBeforeDestroy = false;
             service.mWindowManager.stopAppFreezingScreen(appToken, force);
         }
     }
-    
+
+    public void reportFullyDrawnLocked() {
+        final long curTime = SystemClock.uptimeMillis();
+        if (displayStartTime != 0) {
+            reportLaunchTimeLocked(curTime);
+        }
+        if (fullyDrawnStartTime != 0) {
+            final ActivityStack stack = task.stack;
+            final long thisTime = curTime - fullyDrawnStartTime;
+            final long totalTime = stack.mFullyDrawnStartTime != 0
+                    ? (curTime - stack.mFullyDrawnStartTime) : thisTime;
+            if (ActivityManagerService.SHOW_ACTIVITY_START_TIME) {
+                Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
+                EventLog.writeEvent(EventLogTags.AM_ACTIVITY_FULLY_DRAWN_TIME,
+                        userId, System.identityHashCode(this), shortComponentName,
+                        thisTime, totalTime);
+                StringBuilder sb = service.mStringBuilder;
+                sb.setLength(0);
+                sb.append("Fully drawn ");
+                sb.append(shortComponentName);
+                sb.append(": ");
+                TimeUtils.formatDuration(thisTime, sb);
+                if (thisTime != totalTime) {
+                    sb.append(" (total ");
+                    TimeUtils.formatDuration(totalTime, sb);
+                    sb.append(")");
+                }
+                Log.i(ActivityManagerService.TAG, sb.toString());
+            }
+            if (totalTime > 0) {
+                service.mUsageStatsService.noteFullyDrawnTime(realActivity, (int) totalTime);
+            }
+            fullyDrawnStartTime = 0;
+            stack.mFullyDrawnStartTime = 0;
+        }
+    }
+
+    private void reportLaunchTimeLocked(final long curTime) {
+        final ActivityStack stack = task.stack;
+        final long thisTime = curTime - displayStartTime;
+        final long totalTime = stack.mLaunchStartTime != 0
+                ? (curTime - stack.mLaunchStartTime) : thisTime;
+        if (ActivityManagerService.SHOW_ACTIVITY_START_TIME) {
+            Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "launching", 0);
+            EventLog.writeEvent(EventLogTags.AM_ACTIVITY_LAUNCH_TIME,
+                    userId, System.identityHashCode(this), shortComponentName,
+                    thisTime, totalTime);
+            StringBuilder sb = service.mStringBuilder;
+            sb.setLength(0);
+            sb.append("Displayed ");
+            sb.append(shortComponentName);
+            sb.append(": ");
+            TimeUtils.formatDuration(thisTime, sb);
+            if (thisTime != totalTime) {
+                sb.append(" (total ");
+                TimeUtils.formatDuration(totalTime, sb);
+                sb.append(")");
+            }
+            Log.i(ActivityManagerService.TAG, sb.toString());
+        }
+        mStackSupervisor.reportActivityLaunchedLocked(false, this, thisTime, totalTime);
+        if (totalTime > 0) {
+            service.mUsageStatsService.noteLaunchTime(realActivity, (int)totalTime);
+        }
+        displayStartTime = 0;
+        stack.mLaunchStartTime = 0;
+    }
+
     public void windowsDrawn() {
         synchronized(service) {
-            if (launchTime != 0) {
-                final long curTime = SystemClock.uptimeMillis();
-                final long thisTime = curTime - launchTime;
-                final long totalTime = stack.mInitialStartTime != 0
-                        ? (curTime - stack.mInitialStartTime) : thisTime;
-                if (ActivityManagerService.SHOW_ACTIVITY_START_TIME) {
-                    EventLog.writeEvent(EventLogTags.AM_ACTIVITY_LAUNCH_TIME,
-                            userId, System.identityHashCode(this), shortComponentName,
-                            thisTime, totalTime);
-                    StringBuilder sb = service.mStringBuilder;
-                    sb.setLength(0);
-                    sb.append("Displayed ");
-                    sb.append(shortComponentName);
-                    sb.append(": ");
-                    TimeUtils.formatDuration(thisTime, sb);
-                    if (thisTime != totalTime) {
-                        sb.append(" (total ");
-                        TimeUtils.formatDuration(totalTime, sb);
-                        sb.append(")");
-                    }
-                    Log.i(ActivityManagerService.TAG, sb.toString());
-                }
-                stack.reportActivityLaunchedLocked(false, this, thisTime, totalTime);
-                if (totalTime > 0) {
-                    service.mUsageStatsService.noteLaunchTime(realActivity, (int)totalTime);
-                }
-                launchTime = 0;
-                stack.mInitialStartTime = 0;
+            if (displayStartTime != 0) {
+                reportLaunchTimeLocked(SystemClock.uptimeMillis());
             }
             startTime = 0;
             finishLaunchTickingLocked();
@@ -802,7 +898,7 @@
 
     public void windowsVisible() {
         synchronized(service) {
-            stack.reportActivityVisibleLocked(this);
+            mStackSupervisor.reportActivityVisibleLocked(this);
             if (ActivityManagerService.DEBUG_SWITCH) Log.v(
                     ActivityManagerService.TAG, "windowsVisible(): " + this);
             if (!nowVisible) {
@@ -812,27 +908,24 @@
                     // Instead of doing the full stop routine here, let's just
                     // hide any activities we now can, and let them stop when
                     // the normal idle happens.
-                    stack.processStoppingActivitiesLocked(false);
+                    mStackSupervisor.processStoppingActivitiesLocked(false);
                 } else {
                     // If this activity was already idle, then we now need to
                     // make sure we perform the full stop of any activities
                     // that are waiting to do so.  This is because we won't
                     // do that while they are still waiting for this one to
                     // become visible.
-                    final int N = stack.mWaitingVisibleActivities.size();
+                    final int N = mStackSupervisor.mWaitingVisibleActivities.size();
                     if (N > 0) {
                         for (int i=0; i<N; i++) {
-                            ActivityRecord r = (ActivityRecord)
-                                stack.mWaitingVisibleActivities.get(i);
+                            ActivityRecord r = mStackSupervisor.mWaitingVisibleActivities.get(i);
                             r.waitingVisible = false;
                             if (ActivityManagerService.DEBUG_SWITCH) Log.v(
                                     ActivityManagerService.TAG,
                                     "Was waiting for visible: " + r);
                         }
-                        stack.mWaitingVisibleActivities.clear();
-                        Message msg = Message.obtain();
-                        msg.what = ActivityStack.IDLE_NOW_MSG;
-                        stack.mHandler.sendMessage(msg);
+                        mStackSupervisor.mWaitingVisibleActivities.clear();
+                        mStackSupervisor.scheduleIdleLocked();
                     }
                 }
                 service.scheduleAppGcsLocked();
@@ -845,12 +938,13 @@
                 ActivityManagerService.TAG, "windowsGone(): " + this);
         nowVisible = false;
     }
-    
+
     private ActivityRecord getWaitingHistoryRecordLocked() {
         // First find the real culprit...  if we are waiting
         // for another app to start, then we have paused dispatching
         // for this activity.
         ActivityRecord r = this;
+        final ActivityStack stack = task.stack;
         if (r.waitingVisible) {
             // Hmmm, who might we be waiting for?
             r = stack.mResumedActivity;
@@ -862,20 +956,20 @@
                 r = this;
             }
         }
-        
+
         return r;
     }
 
-    public boolean keyDispatchingTimedOut() {
+    public boolean keyDispatchingTimedOut(String reason) {
         ActivityRecord r;
         ProcessRecord anrApp;
         synchronized(service) {
             r = getWaitingHistoryRecordLocked();
             anrApp = r != null ? r.app : null;
         }
-        return service.inputDispatchingTimedOut(anrApp, r, this, false);
+        return service.inputDispatchingTimedOut(anrApp, r, this, false, reason);
     }
-    
+
     /** Returns the key dispatching timeout for this application token. */
     public long getKeyDispatchingTimeout() {
         synchronized(service) {
@@ -889,7 +983,7 @@
      * currently pausing, or is resumed.
      */
     public boolean isInterestingToUserLocked() {
-        return visible || nowVisible || state == ActivityState.PAUSING || 
+        return visible || nowVisible || state == ActivityState.PAUSING ||
                 state == ActivityState.RESUMED;
     }
 
@@ -900,20 +994,57 @@
         if (app != null && app.thread != null) {
             try {
                 app.thread.scheduleSleeping(appToken, _sleeping);
-                if (sleeping && !stack.mGoingToSleepActivities.contains(this)) {
-                    stack.mGoingToSleepActivities.add(this);
+                if (_sleeping && !mStackSupervisor.mGoingToSleepActivities.contains(this)) {
+                    mStackSupervisor.mGoingToSleepActivities.add(this);
                 }
                 sleeping = _sleeping;
             } catch (RemoteException e) {
-                Slog.w(ActivityStack.TAG, "Exception thrown when sleeping: "
-                        + intent.getComponent(), e);
+                Slog.w(TAG, "Exception thrown when sleeping: " + intent.getComponent(), e);
             }
         }
     }
-    
+
+    static void activityResumedLocked(IBinder token) {
+        final ActivityRecord r = ActivityRecord.forToken(token);
+        if (DEBUG_SAVED_STATE) Slog.i(TAG, "Resumed activity; dropping state of: " + r);
+        r.icicle = null;
+        r.haveState = false;
+    }
+
+    static int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
+        final ActivityRecord r = ActivityRecord.forToken(token);
+        if (r == null) {
+            return -1;
+        }
+        final TaskRecord task = r.task;
+        switch (task.mActivities.indexOf(r)) {
+            case -1: return -1;
+            case 0: return task.taskId;
+            default: return onlyRoot ? -1 : task.taskId;
+        }
+    }
+
+    static ActivityRecord isInStackLocked(IBinder token) {
+        final ActivityRecord r = ActivityRecord.forToken(token);
+        if (r != null) {
+            return r.task.stack.isInStackLocked(token);
+        }
+        return null;
+    }
+
+    static ActivityStack getStackLocked(IBinder token) {
+        final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+        if (r != null) {
+            return r.task.stack;
+        }
+        return null;
+    }
+
+    @Override
     public String toString() {
         if (stringName != null) {
-            return stringName;
+            return stringName + " t" + (task == null ? -1 : task.taskId) +
+                    (finishing ? " f}" : "}");
         }
         StringBuilder sb = new StringBuilder(128);
         sb.append("ActivityRecord{");
@@ -922,7 +1053,7 @@
         sb.append(userId);
         sb.append(' ');
         sb.append(intent.getComponent().flattenToShortString());
-        sb.append('}');
-        return stringName = sb.toString();
+        stringName = sb.toString();
+        return toString();
     }
 }
diff --git a/services/java/com/android/server/am/ActivityResult.java b/services/java/com/android/server/am/ActivityResult.java
index 12eba34..6d5bdeb 100644
--- a/services/java/com/android/server/am/ActivityResult.java
+++ b/services/java/com/android/server/am/ActivityResult.java
@@ -23,7 +23,7 @@
 /**
  * Pending result information to send back to an activity.
  */
-class ActivityResult extends ResultInfo {
+final class ActivityResult extends ResultInfo {
     final ActivityRecord mFrom;
     
     public ActivityResult(ActivityRecord from, String resultWho,
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index c344023..064b3a8 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -16,33 +16,48 @@
 
 package com.android.server.am;
 
-import static android.Manifest.permission.START_ANY_ACTIVITY;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static com.android.server.am.ActivityManagerService.TAG;
+import static com.android.server.am.ActivityManagerService.localLOGV;
+import static com.android.server.am.ActivityManagerService.DEBUG_CLEANUP;
+import static com.android.server.am.ActivityManagerService.DEBUG_CONFIGURATION;
+import static com.android.server.am.ActivityManagerService.DEBUG_PAUSE;
+import static com.android.server.am.ActivityManagerService.DEBUG_RESULTS;
+import static com.android.server.am.ActivityManagerService.DEBUG_STACK;
+import static com.android.server.am.ActivityManagerService.DEBUG_SWITCH;
+import static com.android.server.am.ActivityManagerService.DEBUG_TASKS;
+import static com.android.server.am.ActivityManagerService.DEBUG_TRANSITION;
+import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING;
+import static com.android.server.am.ActivityManagerService.DEBUG_VISBILITY;
+import static com.android.server.am.ActivityManagerService.VALIDATE_TOKENS;
 
-import com.android.internal.app.HeavyWeightSwitcherActivity;
+import static com.android.server.am.ActivityStackSupervisor.DEBUG_ADD_REMOVE;
+import static com.android.server.am.ActivityStackSupervisor.DEBUG_APP;
+import static com.android.server.am.ActivityStackSupervisor.DEBUG_SAVED_STATE;
+import static com.android.server.am.ActivityStackSupervisor.DEBUG_STATES;
+import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
+
+import android.os.Trace;
 import com.android.internal.os.BatteryStatsImpl;
-import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
+import com.android.internal.util.Objects;
+import com.android.server.Watchdog;
+import com.android.server.am.ActivityManagerService.ItemMatcher;
 import com.android.server.wm.AppTransition;
+import com.android.server.wm.TaskGroup;
+import com.android.server.wm.WindowManagerService;
 
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityOptions;
 import android.app.AppGlobals;
-import android.app.IActivityManager;
-import android.app.IThumbnailRetriever;
-import android.app.IApplicationThread;
-import android.app.PendingIntent;
+import android.app.IActivityController;
+import android.app.IThumbnailReceiver;
 import android.app.ResultInfo;
-import android.app.IActivityManager.WaitResult;
+import android.app.ActivityManager.RunningTaskInfo;
 import android.content.ComponentName;
 import android.content.Context;
-import android.content.IIntentSender;
 import android.content.Intent;
-import android.content.IntentSender;
 import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
@@ -54,17 +69,16 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
-import android.os.ParcelFileDescriptor;
 import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.util.EventLog;
-import android.util.Log;
 import android.util.Slog;
 import android.view.Display;
 
-import java.io.IOException;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.Iterator;
@@ -74,28 +88,6 @@
  * State and management of a single stack of activities.
  */
 final class ActivityStack {
-    static final String TAG = ActivityManagerService.TAG;
-    static final boolean localLOGV = ActivityManagerService.localLOGV;
-    static final boolean DEBUG_SWITCH = ActivityManagerService.DEBUG_SWITCH;
-    static final boolean DEBUG_PAUSE = ActivityManagerService.DEBUG_PAUSE;
-    static final boolean DEBUG_VISBILITY = ActivityManagerService.DEBUG_VISBILITY;
-    static final boolean DEBUG_USER_LEAVING = ActivityManagerService.DEBUG_USER_LEAVING;
-    static final boolean DEBUG_TRANSITION = ActivityManagerService.DEBUG_TRANSITION;
-    static final boolean DEBUG_RESULTS = ActivityManagerService.DEBUG_RESULTS;
-    static final boolean DEBUG_CONFIGURATION = ActivityManagerService.DEBUG_CONFIGURATION;
-    static final boolean DEBUG_TASKS = ActivityManagerService.DEBUG_TASKS;
-    static final boolean DEBUG_CLEANUP = ActivityManagerService.DEBUG_CLEANUP;
-    
-    static final boolean DEBUG_STATES = false;
-    static final boolean DEBUG_ADD_REMOVE = false;
-    static final boolean DEBUG_SAVED_STATE = false;
-    static final boolean DEBUG_APP = false;
-
-    static final boolean VALIDATE_TOKENS = ActivityManagerService.VALIDATE_TOKENS;
-    
-    // How long we wait until giving up on the last activity telling us it
-    // is idle.
-    static final int IDLE_TIMEOUT = 10*1000;
 
     // Ticks during which we check progress while waiting for an app to launch.
     static final int LAUNCH_TICK = 500;
@@ -110,28 +102,26 @@
     // from the application in order to get its saved state.
     static final int STOP_TIMEOUT = 10*1000;
 
-    // How long we can hold the sleep wake lock before giving up.
-    static final int SLEEP_TIMEOUT = 5*1000;
-
-    // How long we can hold the launch wake lock before giving up.
-    static final int LAUNCH_TIMEOUT = 10*1000;
-
     // How long we wait until giving up on an activity telling us it has
     // finished destroying itself.
     static final int DESTROY_TIMEOUT = 10*1000;
-    
+
     // How long until we reset a task when the user returns to it.  Currently
     // disabled.
     static final long ACTIVITY_INACTIVE_RESET_TIME = 0;
-    
+
     // How long between activity launches that we consider safe to not warn
     // the user about an unexpected activity being launched on top.
     static final long START_WARN_TIME = 5*1000;
-    
+
     // Set to false to disable the preview that is shown while a new activity
     // is being started.
     static final boolean SHOW_APP_STARTING_PREVIEW = true;
-    
+
+    // How long to wait for all background Activities to redraw following a call to
+    // convertToTranslucent().
+    static final long TRANSLUCENT_CONVERSION_TIMEOUT = 2000;
+
     enum ActivityState {
         INITIALIZING,
         RESUMED,
@@ -145,20 +135,20 @@
     }
 
     final ActivityManagerService mService;
-    final boolean mMainStack;
-    
+    final WindowManagerService mWindowManager;
+
     final Context mContext;
-    
+
     /**
      * The back history of all previous (and possibly still
-     * running) activities.  It contains HistoryRecord objects.
+     * running) activities.  It contains #TaskRecord objects.
      */
-    final ArrayList<ActivityRecord> mHistory = new ArrayList<ActivityRecord>();
+    private ArrayList<TaskRecord> mTaskHistory = new ArrayList<TaskRecord>();
 
     /**
      * Used for validating app tokens with window manager.
      */
-    final ArrayList<IBinder> mValidateAppTokens = new ArrayList<IBinder>();
+    final ArrayList<TaskGroup> mValidateAppTokens = new ArrayList<TaskGroup>();
 
     /**
      * List of running activities, sorted by recent usage.
@@ -168,71 +158,10 @@
     final ArrayList<ActivityRecord> mLRUActivities = new ArrayList<ActivityRecord>();
 
     /**
-     * List of activities that are waiting for a new activity
-     * to become visible before completing whatever operation they are
-     * supposed to do.
-     */
-    final ArrayList<ActivityRecord> mWaitingVisibleActivities
-            = new ArrayList<ActivityRecord>();
-
-    /**
-     * List of activities that are ready to be stopped, but waiting
-     * for the next activity to settle down before doing so.  It contains
-     * HistoryRecord objects.
-     */
-    final ArrayList<ActivityRecord> mStoppingActivities
-            = new ArrayList<ActivityRecord>();
-
-    /**
-     * List of activities that are in the process of going to sleep.
-     */
-    final ArrayList<ActivityRecord> mGoingToSleepActivities
-            = new ArrayList<ActivityRecord>();
-
-    /**
      * Animations that for the current transition have requested not to
      * be considered for the transition animation.
      */
-    final ArrayList<ActivityRecord> mNoAnimActivities
-            = new ArrayList<ActivityRecord>();
-
-    /**
-     * List of activities that are ready to be finished, but waiting
-     * for the previous activity to settle down before doing so.  It contains
-     * HistoryRecord objects.
-     */
-    final ArrayList<ActivityRecord> mFinishingActivities
-            = new ArrayList<ActivityRecord>();
-    
-    /**
-     * List of people waiting to find out about the next launched activity.
-     */
-    final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched
-            = new ArrayList<IActivityManager.WaitResult>();
-    
-    /**
-     * List of people waiting to find out about the next visible activity.
-     */
-    final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible
-            = new ArrayList<IActivityManager.WaitResult>();
-
-    final ArrayList<UserStartedState> mStartingUsers
-            = new ArrayList<UserStartedState>();
-
-    /**
-     * Set when the system is going to sleep, until we have
-     * successfully paused the current activity and released our wake lock.
-     * At that point the system is allowed to actually sleep.
-     */
-    final PowerManager.WakeLock mGoingToSleep;
-
-    /**
-     * We don't want to allow the device to go to sleep while in the process
-     * of launching an activity.  This is primarily to allow alarm intent
-     * receivers to launch an activity and get that to run before the device
-     * goes back to sleep.
-     */
-    final PowerManager.WakeLock mLaunchingActivity;
+    final ArrayList<ActivityRecord> mNoAnimActivities = new ArrayList<ActivityRecord>();
 
     /**
      * When we are in the process of pausing an activity, before starting the
@@ -248,40 +177,42 @@
     ActivityRecord mLastPausedActivity = null;
 
     /**
+     * Activities that specify No History must be removed once the user navigates away from them.
+     * If the device goes to sleep with such an activity in the paused state then we save it here
+     * and finish it later if another activity replaces it on wakeup.
+     */
+    ActivityRecord mLastNoHistoryActivity = null;
+
+    /**
      * Current activity that is resumed, or null if there is none.
      */
     ActivityRecord mResumedActivity = null;
-    
+
     /**
      * This is the last activity that has been started.  It is only used to
      * identify when multiple activities are started at once so that the user
      * can be warned they may not be in the activity they think they are.
      */
     ActivityRecord mLastStartedActivity = null;
-    
+
+    // The topmost Activity passed to convertToTranslucent(). When non-null it means we are
+    // waiting for all Activities in mUndrawnActivitiesBelowTopTranslucent to be removed as they
+    // are drawn. When the last member of mUndrawnActivitiesBelowTopTranslucent is removed the
+    // Activity in mTranslucentActivityWaiting is notified via
+    // Activity.onTranslucentConversionComplete(false). If a timeout occurs prior to the last
+    // background activity being drawn then the same call will be made with a true value.
+    ActivityRecord mTranslucentActivityWaiting = null;
+    ArrayList<ActivityRecord> mUndrawnActivitiesBelowTopTranslucent =
+            new ArrayList<ActivityRecord>();
+
     /**
      * Set when we know we are going to be calling updateConfiguration()
      * soon, so want to skip intermediate config checks.
      */
     boolean mConfigWillChange;
 
-    /**
-     * Set to indicate whether to issue an onUserLeaving callback when a
-     * newly launched activity is being brought in front of us.
-     */
-    boolean mUserLeaving = false;
-    
-    long mInitialStartTime = 0;
-    
-    /**
-     * Set when we have taken too long waiting to go to sleep.
-     */
-    boolean mSleepTimeout = false;
-
-    /**
-     * Dismiss the keyguard after the next activity is displayed?
-     */
-    boolean mDismissKeyguardOnNextActivity = false;
+    long mLaunchStartTime = 0;
+    long mFullyDrawnStartTime = 0;
 
     /**
      * Save the most recent screenshot for reuse. This keeps Recents from taking two identical
@@ -293,18 +224,19 @@
     int mThumbnailWidth = -1;
     int mThumbnailHeight = -1;
 
-    private int mCurrentUser;
+    int mCurrentUser;
 
-    static final int SLEEP_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG;
+    final int mStackId;
+
+    /** Run all ActivityStacks through this */
+    final ActivityStackSupervisor mStackSupervisor;
+
     static final int PAUSE_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 1;
-    static final int IDLE_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 2;
-    static final int IDLE_NOW_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 3;
-    static final int LAUNCH_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 4;
-    static final int DESTROY_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 5;
-    static final int RESUME_TOP_ACTIVITY_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 6;
-    static final int LAUNCH_TICK_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 7;
-    static final int STOP_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 8;
-    static final int DESTROY_ACTIVITIES_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 9;
+    static final int DESTROY_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 2;
+    static final int LAUNCH_TICK_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 3;
+    static final int STOP_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 4;
+    static final int DESTROY_ACTIVITIES_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 5;
+    static final int TRANSLUCENT_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 6;
 
     static class ScheduleDestroyArgs {
         final ProcessRecord mOwner;
@@ -323,22 +255,13 @@
         //public Handler() {
         //    if (localLOGV) Slog.v(TAG, "Handler started!");
         //}
-        public ActivityStackHandler(Looper looper) {
+        ActivityStackHandler(Looper looper) {
             super(looper);
         }
 
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
-                case SLEEP_TIMEOUT_MSG: {
-                    synchronized (mService) {
-                        if (mService.isSleeping()) {
-                            Slog.w(TAG, "Sleep timeout!  Sleeping now.");
-                            mSleepTimeout = true;
-                            checkReadyForSleepLocked();
-                        }
-                    }
-                } break;
                 case PAUSE_TIMEOUT_MSG: {
                     ActivityRecord r = (ActivityRecord)msg.obj;
                     // We don't at this point know if the activity is fullscreen,
@@ -346,33 +269,16 @@
                     Slog.w(TAG, "Activity pause timeout for " + r);
                     synchronized (mService) {
                         if (r.app != null) {
-                            mService.logAppTooSlow(r.app, r.pauseTime,
-                                    "pausing " + r);
+                            mService.logAppTooSlow(r.app, r.pauseTime, "pausing " + r);
                         }
+                        activityPausedLocked(r.appToken, true);
                     }
-
-                    activityPaused(r != null ? r.appToken : null, true);
-                } break;
-                case IDLE_TIMEOUT_MSG: {
-                    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.
-                    ActivityRecord r = (ActivityRecord)msg.obj;
-                    Slog.w(TAG, "Activity idle timeout for " + r);
-                    activityIdleInternal(r != null ? r.appToken : null, true, null);
                 } break;
                 case LAUNCH_TICK_MSG: {
                     ActivityRecord r = (ActivityRecord)msg.obj;
                     synchronized (mService) {
                         if (r.continueLaunchTickingLocked()) {
-                            mService.logAppTooSlow(r.app, r.launchTickTime,
-                                    "launching " + r);
+                            mService.logAppTooSlow(r.app, r.launchTickTime, "launching " + r);
                         }
                     }
                 } break;
@@ -381,29 +287,8 @@
                     // We don't at this point know if the activity is fullscreen,
                     // so we need to be conservative and assume it isn't.
                     Slog.w(TAG, "Activity destroy timeout for " + r);
-                    activityDestroyed(r != null ? r.appToken : null);
-                } break;
-                case IDLE_NOW_MSG: {
-                    ActivityRecord r = (ActivityRecord)msg.obj;
-                    activityIdleInternal(r != null ? r.appToken : null, false, null);
-                } break;
-                case LAUNCH_TIMEOUT_MSG: {
-                    if (mService.mDidDexOpt) {
-                        mService.mDidDexOpt = false;
-                        Message nmsg = mHandler.obtainMessage(LAUNCH_TIMEOUT_MSG);
-                        mHandler.sendMessageDelayed(nmsg, LAUNCH_TIMEOUT);
-                        return;
-                    }
                     synchronized (mService) {
-                        if (mLaunchingActivity.isHeld()) {
-                            Slog.w(TAG, "Launch timeout has expired, giving up wake lock!");
-                            mLaunchingActivity.release();
-                        }
-                    }
-                } break;
-                case RESUME_TOP_ACTIVITY_MSG: {
-                    synchronized (mService) {
-                        resumeTopActivityLocked(null);
+                        activityDestroyedLocked(r != null ? r.appToken : null);
                     }
                 } break;
                 case STOP_TIMEOUT_MSG: {
@@ -422,21 +307,32 @@
                     synchronized (mService) {
                         destroyActivitiesLocked(args.mOwner, args.mOomAdj, args.mReason);
                     }
-                }
+                } break;
+                case TRANSLUCENT_TIMEOUT_MSG: {
+                    synchronized (mService) {
+                        notifyActivityDrawnLocked(null);
+                    }
+                } break;
             }
         }
     }
 
-    ActivityStack(ActivityManagerService service, Context context, boolean mainStack, Looper looper) {
+    private int numActivities() {
+        int count = 0;
+        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+            count += mTaskHistory.get(taskNdx).mActivities.size();
+        }
+        return count;
+    }
+
+    ActivityStack(ActivityManagerService service, Context context, Looper looper, int stackId) {
         mHandler = new ActivityStackHandler(looper);
         mService = service;
+        mWindowManager = service.mWindowManager;
+        mStackSupervisor = service.mStackSupervisor;
         mContext = context;
-        mMainStack = mainStack;
-        PowerManager pm =
-            (PowerManager)context.getSystemService(Context.POWER_SERVICE);
-        mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
-        mLaunchingActivity = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
-        mLaunchingActivity.setReferenceCounted(false);
+        mStackId = stackId;
+        mCurrentUser = service.mCurrentUserId;
     }
 
     private boolean okToShow(ActivityRecord r) {
@@ -445,25 +341,29 @@
     }
 
     final ActivityRecord topRunningActivityLocked(ActivityRecord notTop) {
-        int i = mHistory.size()-1;
-        while (i >= 0) {
-            ActivityRecord r = mHistory.get(i);
-            if (!r.finishing && r != notTop && okToShow(r)) {
-                return r;
+        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+            final TaskRecord task = mTaskHistory.get(taskNdx);
+            final ArrayList<ActivityRecord> activities = task.mActivities;
+            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+                ActivityRecord r = activities.get(activityNdx);
+                if (!r.finishing && r != notTop && okToShow(r)) {
+                    return r;
+                }
             }
-            i--;
         }
         return null;
     }
 
     final ActivityRecord topRunningNonDelayedActivityLocked(ActivityRecord notTop) {
-        int i = mHistory.size()-1;
-        while (i >= 0) {
-            ActivityRecord r = mHistory.get(i);
-            if (!r.finishing && !r.delayedResume && r != notTop && okToShow(r)) {
-                return r;
+        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+            final TaskRecord task = mTaskHistory.get(taskNdx);
+            final ArrayList<ActivityRecord> activities = task.mActivities;
+            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+                ActivityRecord r = activities.get(activityNdx);
+                if (!r.finishing && !r.delayedResume && r != notTop && okToShow(r)) {
+                    return r;
+                }
             }
-            i--;
         }
         return null;
     }
@@ -471,88 +371,146 @@
     /**
      * This is a simplified version of topRunningActivityLocked that provides a number of
      * optional skip-over modes.  It is intended for use with the ActivityController hook only.
-     * 
+     *
      * @param token If non-null, any history records matching this token will be skipped.
      * @param taskId If non-zero, we'll attempt to skip over records with the same task ID.
-     * 
+     *
      * @return Returns the HistoryRecord of the next activity on the stack.
      */
     final ActivityRecord topRunningActivityLocked(IBinder token, int taskId) {
-        int i = mHistory.size()-1;
-        while (i >= 0) {
-            ActivityRecord r = mHistory.get(i);
-            // Note: the taskId check depends on real taskId fields being non-zero
-            if (!r.finishing && (token != r.appToken) && (taskId != r.task.taskId)
-                    && okToShow(r)) {
+        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+            TaskRecord task = mTaskHistory.get(taskNdx);
+            if (task.taskId == taskId) {
+                continue;
+            }
+            ArrayList<ActivityRecord> activities = task.mActivities;
+            for (int i = activities.size() - 1; i >= 0; --i) {
+                final ActivityRecord r = activities.get(i);
+                // Note: the taskId check depends on real taskId fields being non-zero
+                if (!r.finishing && (token != r.appToken) && okToShow(r)) {
+                    return r;
+                }
+            }
+        }
+        return null;
+    }
+
+    final ActivityRecord topActivity() {
+        // Iterate to find the first non-empty task stack. Note that this code can
+        // be simplified once we stop storing tasks with empty mActivities lists.
+        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+            ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
+            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+                return activities.get(activityNdx);
+            }
+        }
+        return null;
+    }
+
+    final TaskRecord topTask() {
+        final int size = mTaskHistory.size();
+        if (size > 0) {
+            return mTaskHistory.get(size - 1);
+        }
+        return null;
+    }
+
+    TaskRecord taskForIdLocked(int id) {
+        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+            final TaskRecord task = mTaskHistory.get(taskNdx);
+            if (task.taskId == id) {
+                return task;
+            }
+        }
+        return null;
+    }
+
+    ActivityRecord isInStackLocked(IBinder token) {
+        final ActivityRecord r = ActivityRecord.forToken(token);
+        if (r != null) {
+            final TaskRecord task = r.task;
+            if (task.mActivities.contains(r) && mTaskHistory.contains(task)) {
+                if (task.stack != this) Slog.w(TAG,
+                    "Illegal state! task does not point to stack it is in.");
                 return r;
             }
-            i--;
         }
         return null;
     }
 
-    final int indexOfTokenLocked(IBinder token) {
-        return mHistory.indexOf(ActivityRecord.forToken(token));
-    }
-
-    final int indexOfActivityLocked(ActivityRecord r) {
-        return mHistory.indexOf(r);
-    }
-
-    final ActivityRecord isInStackLocked(IBinder token) {
-        ActivityRecord r = ActivityRecord.forToken(token);
-        if (mHistory.contains(r)) {
-            return r;
+    boolean containsApp(ProcessRecord app) {
+        if (app == null) {
+            return false;
         }
-        return null;
+        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
+            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+                final ActivityRecord r = activities.get(activityNdx);
+                if (r.finishing) {
+                    continue;
+                }
+                if (r.app == app) {
+                    return true;
+                }
+            }
+        }
+        return false;
     }
 
-    private final boolean updateLRUListLocked(ActivityRecord r) {
+    final boolean updateLRUListLocked(ActivityRecord r) {
         final boolean hadit = mLRUActivities.remove(r);
         mLRUActivities.add(r);
         return hadit;
     }
 
+    final boolean isHomeStack() {
+        return mStackId == HOME_STACK_ID;
+    }
+
     /**
      * Returns the top activity in any existing task matching the given
      * Intent.  Returns null if no such task is found.
      */
-    private ActivityRecord findTaskLocked(Intent intent, ActivityInfo info) {
+    ActivityRecord findTaskLocked(ActivityRecord target) {
+        Intent intent = target.intent;
+        ActivityInfo info = target.info;
         ComponentName cls = intent.getComponent();
         if (info.targetActivity != null) {
             cls = new ComponentName(info.packageName, info.targetActivity);
         }
-
-        TaskRecord cp = null;
-
         final int userId = UserHandle.getUserId(info.applicationInfo.uid);
-        final int N = mHistory.size();
-        for (int i=(N-1); i>=0; i--) {
-            ActivityRecord r = mHistory.get(i);
-            if (!r.finishing && r.task != cp && r.userId == userId
-                    && r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
-                cp = r.task;
-                //Slog.i(TAG, "Comparing existing cls=" + r.task.intent.getComponent().flattenToShortString()
-                //        + "/aff=" + r.task.affinity + " to new cls="
-                //        + intent.getComponent().flattenToShortString() + "/aff=" + taskAffinity);
-                if (r.task.affinity != null) {
-                    if (r.task.affinity.equals(info.taskAffinity)) {
-                        //Slog.i(TAG, "Found matching affinity!");
-                        return r;
-                    }
-                } else if (r.task.intent != null
-                        && r.task.intent.getComponent().equals(cls)) {
-                    //Slog.i(TAG, "Found matching class!");
-                    //dump();
-                    //Slog.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
-                    return r;
-                } else if (r.task.affinityIntent != null
-                        && r.task.affinityIntent.getComponent().equals(cls)) {
-                    //Slog.i(TAG, "Found matching class!");
-                    //dump();
-                    //Slog.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
+
+        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+            final TaskRecord task = mTaskHistory.get(taskNdx);
+            if (task.userId != userId) {
+                // Looking for a different task.
+                continue;
+            }
+            final ActivityRecord r = task.getTopActivity();
+            if (r == null || r.finishing || r.userId != userId ||
+                    r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
+                continue;
+            }
+
+            //Slog.i(TAG, "Comparing existing cls=" + r.task.intent.getComponent().flattenToShortString()
+            //        + "/aff=" + r.task.affinity + " to new cls="
+            //        + intent.getComponent().flattenToShortString() + "/aff=" + taskAffinity);
+            if (task.affinity != null) {
+                if (task.affinity.equals(info.taskAffinity)) {
+                    //Slog.i(TAG, "Found matching affinity!");
                     return r;
                 }
+            } else if (task.intent != null && task.intent.getComponent().equals(cls)) {
+                //Slog.i(TAG, "Found matching class!");
+                //dump();
+                //Slog.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
+                return r;
+            } else if (task.affinityIntent != null
+                    && task.affinityIntent.getComponent().equals(cls)) {
+                //Slog.i(TAG, "Found matching class!");
+                //dump();
+                //Slog.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
+                return r;
             }
         }
 
@@ -564,18 +522,22 @@
      * is the same as the given activity.  Returns null if no such activity
      * is found.
      */
-    private ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
+    ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
         ComponentName cls = intent.getComponent();
         if (info.targetActivity != null) {
             cls = new ComponentName(info.packageName, info.targetActivity);
         }
         final int userId = UserHandle.getUserId(info.applicationInfo.uid);
 
-        final int N = mHistory.size();
-        for (int i=(N-1); i>=0; i--) {
-            ActivityRecord r = mHistory.get(i);
-            if (!r.finishing) {
-                if (r.intent.getComponent().equals(cls) && r.userId == userId) {
+        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+            TaskRecord task = mTaskHistory.get(taskNdx);
+            if (task.userId != mCurrentUser) {
+                return null;
+            }
+            final ArrayList<ActivityRecord> activities = task.mActivities;
+            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+                ActivityRecord r = activities.get(activityNdx);
+                if (!r.finishing && r.intent.getComponent().equals(cls) && r.userId == userId) {
                     //Slog.i(TAG, "Found matching class!");
                     //dump();
                     //Slog.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
@@ -587,343 +549,129 @@
         return null;
     }
 
-    final void showAskCompatModeDialogLocked(ActivityRecord r) {
-        Message msg = Message.obtain();
-        msg.what = ActivityManagerService.SHOW_COMPAT_MODE_DIALOG_MSG;
-        msg.obj = r.task.askedCompatMode ? null : r;
-        mService.mHandler.sendMessage(msg);
-    }
-
     /*
      * Move the activities around in the stack to bring a user to the foreground.
      * @return whether there are any activities for the specified user.
      */
-    final boolean switchUserLocked(int userId, UserStartedState uss) {
+    final boolean switchUserLocked(int userId) {
+        if (VALIDATE_TOKENS) {
+            validateAppTokensLocked();
+        }
+        if (mCurrentUser == userId) {
+            return true;
+        }
         mCurrentUser = userId;
-        mStartingUsers.add(uss);
 
-        // Only one activity? Nothing to do...
-        if (mHistory.size() < 2)
-            return false;
-
+        // Move userId's tasks to the top.
         boolean haveActivities = false;
-        // Check if the top activity is from the new user.
-        ActivityRecord top = mHistory.get(mHistory.size() - 1);
-        if (top.userId == userId) return true;
-        // Otherwise, move the user's activities to the top.
-        int N = mHistory.size();
-        int i = 0;
-        while (i < N) {
-            ActivityRecord r = mHistory.get(i);
-            if (r.userId == userId) {
-                ActivityRecord moveToTop = mHistory.remove(i);
-                mHistory.add(moveToTop);
-                // No need to check the top one now
-                N--;
+        int index = mTaskHistory.size();
+        for (int i = 0; i < index; ++i) {
+            TaskRecord task = mTaskHistory.get(i);
+            if (task.userId == userId) {
                 haveActivities = true;
-            } else {
-                i++;
+                mTaskHistory.remove(i);
+                mTaskHistory.add(task);
+                --index;
             }
         }
-        // Transition from the old top to the new top
-        resumeTopActivityLocked(top);
+
         return haveActivities;
     }
 
-    final boolean realStartActivityLocked(ActivityRecord r,
-            ProcessRecord app, boolean andResume, boolean checkConfig)
-            throws RemoteException {
+    void minimalResumeActivityLocked(ActivityRecord r) {
+        r.state = ActivityState.RESUMED;
+        if (DEBUG_STATES) Slog.v(TAG, "Moving to RESUMED: " + r
+                + " (starting new instance)");
+        r.stopped = false;
+        mResumedActivity = r;
+        r.task.touchActiveTime();
+        mService.addRecentTaskLocked(r.task);
+        completeResumeLocked(r);
+        mStackSupervisor.checkReadyForSleepLocked();
+        if (DEBUG_SAVED_STATE) Slog.i(TAG, "Launch completed; removing icicle of " + r.icicle);
+    }
 
-        r.startFreezingScreenLocked(app, 0);
-        mService.mWindowManager.setAppVisibility(r.appToken, true);
-
-        // schedule launch ticks to collect information about slow apps.
-        r.startLaunchTickingLocked();
-
-        // Have the window manager re-evaluate the orientation of
-        // the screen based on the new activity order.  Note that
-        // as a result of this, it can call back into the activity
-        // manager with a new orientation.  We don't care about that,
-        // because the activity is not currently running so we are
-        // just restarting it anyway.
-        if (checkConfig) {
-            Configuration config = mService.mWindowManager.updateOrientationFromAppTokens(
-                    mService.mConfiguration,
-                    r.mayFreezeScreenLocked(app) ? r.appToken : null);
-            mService.updateConfigurationLocked(config, r, false, false);
+    private void startLaunchTraces() {
+        if (mFullyDrawnStartTime != 0)  {
+            Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
         }
+        Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "launching", 0);
+        Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
+    }
 
-        r.app = app;
-        app.waitingToKill = null;
-        r.launchCount++;
-        r.lastLaunchTime = SystemClock.uptimeMillis();
-
-        if (localLOGV) Slog.v(TAG, "Launching: " + r);
-
-        int idx = app.activities.indexOf(r);
-        if (idx < 0) {
-            app.activities.add(r);
+    private void stopFullyDrawnTraceIfNeeded() {
+        if (mFullyDrawnStartTime != 0 && mLaunchStartTime == 0) {
+            Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
+            mFullyDrawnStartTime = 0;
         }
-        mService.updateLruProcessLocked(app, true);
+    }
 
-        try {
-            if (app.thread == null) {
-                throw new RemoteException();
+    void setLaunchTime(ActivityRecord r) {
+        if (r.displayStartTime == 0) {
+            r.fullyDrawnStartTime = r.displayStartTime = SystemClock.uptimeMillis();
+            if (mLaunchStartTime == 0) {
+                startLaunchTraces();
+                mLaunchStartTime = mFullyDrawnStartTime = r.displayStartTime;
             }
-            List<ResultInfo> results = null;
-            List<Intent> newIntents = null;
-            if (andResume) {
-                results = r.results;
-                newIntents = r.newIntents;
-            }
-            if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r
-                    + " icicle=" + r.icicle
-                    + " with results=" + results + " newIntents=" + newIntents
-                    + " andResume=" + andResume);
-            if (andResume) {
-                EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
-                        r.userId, System.identityHashCode(r),
-                        r.task.taskId, r.shortComponentName);
-            }
-            if (r.isHomeActivity) {
-                mService.mHomeProcess = app;
-            }
-            mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
-            r.sleeping = false;
-            r.forceNewConfig = false;
-            showAskCompatModeDialogLocked(r);
-            r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
-            String profileFile = null;
-            ParcelFileDescriptor profileFd = null;
-            boolean profileAutoStop = false;
-            if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
-                if (mService.mProfileProc == null || mService.mProfileProc == app) {
-                    mService.mProfileProc = app;
-                    profileFile = mService.mProfileFile;
-                    profileFd = mService.mProfileFd;
-                    profileAutoStop = mService.mAutoStopProfiler;
-                }
-            }
-            app.hasShownUi = true;
-            app.pendingUiClean = true;
-            if (profileFd != null) {
-                try {
-                    profileFd = profileFd.dup();
-                } catch (IOException e) {
-                    profileFd = null;
-                }
-            }
-            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
-                    System.identityHashCode(r), r.info,
-                    new Configuration(mService.mConfiguration),
-                    r.compat, r.icicle, results, newIntents, !andResume,
-                    mService.isNextTransitionForward(), profileFile, profileFd,
-                    profileAutoStop);
-            
-            if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
-                // This may be a heavy-weight process!  Note that the package
-                // manager will ensure that only activity can run in the main
-                // process of the .apk, which is the only thing that will be
-                // considered heavy-weight.
-                if (app.processName.equals(app.info.packageName)) {
-                    if (mService.mHeavyWeightProcess != null
-                            && mService.mHeavyWeightProcess != app) {
-                        Log.w(TAG, "Starting new heavy weight process " + app
-                                + " when already running "
-                                + mService.mHeavyWeightProcess);
-                    }
-                    mService.mHeavyWeightProcess = app;
-                    Message msg = mService.mHandler.obtainMessage(
-                            ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
-                    msg.obj = r;
-                    mService.mHandler.sendMessage(msg);
-                }
-            }
-            
-        } catch (RemoteException e) {
-            if (r.launchFailed) {
-                // This is the second time we failed -- finish activity
-                // and give up.
-                Slog.e(TAG, "Second failure launching "
-                      + r.intent.getComponent().flattenToShortString()
-                      + ", giving up", e);
-                mService.appDiedLocked(app, app.pid, app.thread);
-                requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
-                        "2nd-crash", false);
-                return false;
-            }
-
-            // This is the first time we failed -- restart process and
-            // retry.
-            app.activities.remove(r);
-            throw e;
+        } else if (mLaunchStartTime == 0) {
+            startLaunchTraces();
+            mLaunchStartTime = mFullyDrawnStartTime = SystemClock.uptimeMillis();
         }
+    }
 
-        r.launchFailed = false;
-        if (updateLRUListLocked(r)) {
-            Slog.w(TAG, "Activity " + r
-                  + " being launched, but already in LRU list");
-        }
-
-        if (andResume) {
-            // As part of the process of launching, ActivityThread also performs
-            // a resume.
-            r.state = ActivityState.RESUMED;
-            if (DEBUG_STATES) Slog.v(TAG, "Moving to RESUMED: " + r
-                    + " (starting new instance)");
-            r.stopped = false;
-            mResumedActivity = r;
-            r.task.touchActiveTime();
-            if (mMainStack) {
-                mService.addRecentTaskLocked(r.task);
-            }
-            completeResumeLocked(r);
-            checkReadyForSleepLocked();
-            if (DEBUG_SAVED_STATE) Slog.i(TAG, "Launch completed; removing icicle of " + r.icicle);
+    void clearLaunchTime(ActivityRecord r) {
+        // Make sure that there is no activity waiting for this to launch.
+        if (mStackSupervisor.mWaitingActivityLaunched.isEmpty()) {
+            r.displayStartTime = r.fullyDrawnStartTime = 0;
         } else {
-            // This activity is not starting in the resumed state... which
-            // should look like we asked it to pause+stop (but remain visible),
-            // and it has done so and reported back the current icicle and
-            // other state.
-            if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
-                    + " (starting in stopped state)");
-            r.state = ActivityState.STOPPED;
-            r.stopped = true;
-        }
-
-        // Launch the new version setup screen if needed.  We do this -after-
-        // launching the initial activity (that is, home), so that it can have
-        // a chance to initialize itself while in the background, making the
-        // switch back to it faster and look better.
-        if (mMainStack) {
-            mService.startSetupActivityLocked();
-        }
-        
-        return true;
-    }
-
-    private final void startSpecificActivityLocked(ActivityRecord r,
-            boolean andResume, boolean checkConfig) {
-        // Is this activity's application already running?
-        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
-                r.info.applicationInfo.uid);
-
-        if (r.launchTime == 0) {
-            r.launchTime = SystemClock.uptimeMillis();
-            if (mInitialStartTime == 0) {
-                mInitialStartTime = r.launchTime;
-            }
-        } else if (mInitialStartTime == 0) {
-            mInitialStartTime = SystemClock.uptimeMillis();
-        }
-        
-        if (app != null && app.thread != null) {
-            try {
-                app.addPackage(r.info.packageName);
-                realStartActivityLocked(r, app, andResume, checkConfig);
-                return;
-            } catch (RemoteException e) {
-                Slog.w(TAG, "Exception when starting activity "
-                        + r.intent.getComponent().flattenToShortString(), e);
-            }
-
-            // If a dead object exception was thrown -- fall through to
-            // restart the application.
-        }
-
-        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
-                "activity", r.intent.getComponent(), false, false);
-    }
-    
-    void stopIfSleepingLocked() {
-        if (mService.isSleeping()) {
-            if (!mGoingToSleep.isHeld()) {
-                mGoingToSleep.acquire();
-                if (mLaunchingActivity.isHeld()) {
-                    mLaunchingActivity.release();
-                    mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
-                }
-            }
-            mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
-            Message msg = mHandler.obtainMessage(SLEEP_TIMEOUT_MSG);
-            mHandler.sendMessageDelayed(msg, SLEEP_TIMEOUT);
-            checkReadyForSleepLocked();
+            mStackSupervisor.removeTimeoutsForActivityLocked(r);
+            mStackSupervisor.scheduleIdleTimeoutLocked(r);
         }
     }
 
     void awakeFromSleepingLocked() {
-        mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
-        mSleepTimeout = false;
-        if (mGoingToSleep.isHeld()) {
-            mGoingToSleep.release();
-        }
         // Ensure activities are no longer sleeping.
-        for (int i=mHistory.size()-1; i>=0; i--) {
-            ActivityRecord r = mHistory.get(i);
-            r.setSleeping(false);
+        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
+            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+                activities.get(activityNdx).setSleeping(false);
+            }
         }
-        mGoingToSleepActivities.clear();
     }
 
-    void activitySleptLocked(ActivityRecord r) {
-        mGoingToSleepActivities.remove(r);
-        checkReadyForSleepLocked();
-    }
-
-    void checkReadyForSleepLocked() {
-        if (!mService.isSleeping()) {
-            // Do not care.
-            return;
+    /**
+     * @return true if something must be done before going to sleep.
+     */
+    boolean checkReadyForSleepLocked() {
+        if (mResumedActivity != null) {
+            // Still have something resumed; can't sleep until it is paused.
+            if (DEBUG_PAUSE) Slog.v(TAG, "Sleep needs to pause " + mResumedActivity);
+            if (DEBUG_USER_LEAVING) Slog.v(TAG, "Sleep => pause with userLeaving=false");
+            startPausingLocked(false, true);
+            return true;
+        }
+        if (mPausingActivity != null) {
+            // Still waiting for something to pause; can't sleep yet.
+            if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still waiting to pause " + mPausingActivity);
+            return true;
         }
 
-        if (!mSleepTimeout) {
-            if (mResumedActivity != null) {
-                // Still have something resumed; can't sleep until it is paused.
-                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep needs to pause " + mResumedActivity);
-                if (DEBUG_USER_LEAVING) Slog.v(TAG, "Sleep => pause with userLeaving=false");
-                startPausingLocked(false, true);
-                return;
-            }
-            if (mPausingActivity != null) {
-                // Still waiting for something to pause; can't sleep yet.
-                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still waiting to pause " + mPausingActivity);
-                return;
-            }
+        return false;
+    }
 
-            if (mStoppingActivities.size() > 0) {
-                // Still need to tell some activities to stop; can't sleep yet.
-                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
-                        + mStoppingActivities.size() + " activities");
-                scheduleIdleLocked();
-                return;
-            }
+    void goToSleep() {
+        ensureActivitiesVisibleLocked(null, 0);
 
-            ensureActivitiesVisibleLocked(null, 0);
-
-            // Make sure any stopped but visible activities are now sleeping.
-            // This ensures that the activity's onStop() is called.
-            for (int i=mHistory.size()-1; i>=0; i--) {
-                ActivityRecord r = mHistory.get(i);
+        // Make sure any stopped but visible activities are now sleeping.
+        // This ensures that the activity's onStop() is called.
+        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
+            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+                final ActivityRecord r = activities.get(activityNdx);
                 if (r.state == ActivityState.STOPPING || r.state == ActivityState.STOPPED) {
                     r.setSleeping(true);
                 }
             }
-
-            if (mGoingToSleepActivities.size() > 0) {
-                // Still need to tell some activities to sleep; can't sleep yet.
-                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
-                        + mGoingToSleepActivities.size() + " activities");
-                return;
-            }
-        }
-
-        mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
-
-        if (mGoingToSleep.isHeld()) {
-            mGoingToSleep.release();
-        }
-        if (mService.mShuttingDown) {
-            mService.notifyAll();
         }
     }
 
@@ -931,7 +679,7 @@
         if (who.noDisplay) {
             return null;
         }
-        
+
         Resources res = mService.mContext.getResources();
         int w = mThumbnailWidth;
         int h = mThumbnailHeight;
@@ -947,7 +695,7 @@
                     || mLastScreenshotBitmap.getWidth() != w
                     || mLastScreenshotBitmap.getHeight() != h) {
                 mLastScreenshotActivity = who;
-                mLastScreenshotBitmap = mService.mWindowManager.screenshotApplications(
+                mLastScreenshotBitmap = mWindowManager.screenshotApplications(
                         who.appToken, Display.DEFAULT_DISPLAY, w, h);
             }
             if (mLastScreenshotBitmap != null) {
@@ -957,17 +705,16 @@
         return null;
     }
 
-    private final void startPausingLocked(boolean userLeaving, boolean uiSleeping) {
+    final void startPausingLocked(boolean userLeaving, boolean uiSleeping) {
         if (mPausingActivity != null) {
-            RuntimeException e = new RuntimeException();
             Slog.e(TAG, "Trying to pause when pause is already pending for "
-                  + mPausingActivity, e);
+                  + mPausingActivity, new RuntimeException("here").fillInStackTrace());
         }
         ActivityRecord prev = mResumedActivity;
         if (prev == null) {
-            RuntimeException e = new RuntimeException();
-            Slog.e(TAG, "Trying to pause when nothing is resumed", e);
-            resumeTopActivityLocked(null);
+            Slog.e(TAG, "Trying to pause when nothing is resumed",
+                    new RuntimeException("here").fillInStackTrace());
+            mStackSupervisor.resumeTopActivitiesLocked();
             return;
         }
         if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSING: " + prev);
@@ -975,46 +722,44 @@
         mResumedActivity = null;
         mPausingActivity = prev;
         mLastPausedActivity = prev;
+        mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
+                || (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
         prev.state = ActivityState.PAUSING;
         prev.task.touchActiveTime();
+        clearLaunchTime(prev);
         prev.updateThumbnail(screenshotActivities(prev), null);
+        stopFullyDrawnTraceIfNeeded();
 
         mService.updateCpuStats();
-        
+
         if (prev.app != null && prev.app.thread != null) {
             if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending pause: " + prev);
             try {
                 EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
                         prev.userId, System.identityHashCode(prev),
                         prev.shortComponentName);
+                mService.updateUsageStats(prev, false);
                 prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                         userLeaving, prev.configChangeFlags);
-                if (mMainStack) {
-                    mService.updateUsageStats(prev, false);
-                }
             } catch (Exception e) {
                 // Ignore exception, if process died other code will cleanup.
                 Slog.w(TAG, "Exception thrown during pause", e);
                 mPausingActivity = null;
                 mLastPausedActivity = null;
+                mLastNoHistoryActivity = null;
             }
         } else {
             mPausingActivity = null;
             mLastPausedActivity = null;
+            mLastNoHistoryActivity = null;
         }
 
         // If we are not going to sleep, we want to ensure the device is
         // awake until the next activity is started.
-        if (!mService.mSleeping && !mService.mShuttingDown) {
-            mLaunchingActivity.acquire();
-            if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
-                // To be safe, don't allow the wake lock to be held for too long.
-                Message msg = mHandler.obtainMessage(LAUNCH_TIMEOUT_MSG);
-                mHandler.sendMessageDelayed(msg, LAUNCH_TIMEOUT);
-            }
+        if (!mService.isSleepingOrShuttingDown()) {
+            mStackSupervisor.acquireLaunchWakelock();
         }
 
-
         if (mPausingActivity != null) {
             // Have the window manager pause its key dispatching until the new
             // activity has started.  If we're pausing the activity just because
@@ -1038,46 +783,27 @@
             // This activity failed to schedule the
             // pause, so just treat it as being paused now.
             if (DEBUG_PAUSE) Slog.v(TAG, "Activity not running, resuming next.");
-            resumeTopActivityLocked(null);
+            mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null);
         }
     }
 
-    final void activityResumed(IBinder token) {
-        ActivityRecord r = null;
-
-        synchronized (mService) {
-            int index = indexOfTokenLocked(token);
-            if (index >= 0) {
-                r = mHistory.get(index);
-                if (DEBUG_SAVED_STATE) Slog.i(TAG, "Resumed activity; dropping state of: " + r);
-                r.icicle = null;
-                r.haveState = false;
-            }
-        }
-    }
-
-    final void activityPaused(IBinder token, boolean timeout) {
+    final void activityPausedLocked(IBinder token, boolean timeout) {
         if (DEBUG_PAUSE) Slog.v(
             TAG, "Activity paused: token=" + token + ", timeout=" + timeout);
 
-        ActivityRecord r = null;
-
-        synchronized (mService) {
-            int index = indexOfTokenLocked(token);
-            if (index >= 0) {
-                r = mHistory.get(index);
-                mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
-                if (mPausingActivity == r) {
-                    if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSED: " + r
-                            + (timeout ? " (due to timeout)" : " (pause complete)"));
-                    r.state = ActivityState.PAUSED;
-                    completePauseLocked();
-                } else {
-                    EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
-                            r.userId, System.identityHashCode(r), r.shortComponentName, 
-                            mPausingActivity != null
-                                ? mPausingActivity.shortComponentName : "(none)");
-                }
+        final ActivityRecord r = isInStackLocked(token);
+        if (r != null) {
+            mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
+            if (mPausingActivity == r) {
+                if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSED: " + r
+                        + (timeout ? " (due to timeout)" : " (pause complete)"));
+                r.state = ActivityState.PAUSED;
+                completePauseLocked();
+            } else {
+                EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
+                        r.userId, System.identityHashCode(r), r.shortComponentName,
+                        mPausingActivity != null
+                            ? mPausingActivity.shortComponentName : "(none)");
             }
         }
     }
@@ -1108,32 +834,18 @@
             } else {
                 if (r.configDestroy) {
                     destroyActivityLocked(r, true, false, "stop-config");
-                    resumeTopActivityLocked(null);
+                    mStackSupervisor.resumeTopActivitiesLocked();
                 } else {
-                    // Now that this process has stopped, we may want to consider
-                    // it to be the previous app to try to keep around in case
-                    // the user wants to return to it.
-                    ProcessRecord fgApp = null;
-                    if (mResumedActivity != null) {
-                        fgApp = mResumedActivity.app;
-                    } else if (mPausingActivity != null) {
-                        fgApp = mPausingActivity.app;
-                    }
-                    if (r.app != null && fgApp != null && r.app != fgApp
-                            && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
-                            && r.app != mService.mHomeProcess) {
-                        mService.mPreviousProcess = r.app;
-                        mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
-                    }
+                    mStackSupervisor.updatePreviousProcessLocked(r);
                 }
             }
         }
     }
 
-    private final void completePauseLocked() {
+    private void completePauseLocked() {
         ActivityRecord prev = mPausingActivity;
         if (DEBUG_PAUSE) Slog.v(TAG, "Complete pause: " + prev);
-        
+
         if (prev != null) {
             if (prev.finishing) {
                 if (DEBUG_PAUSE) Slog.v(TAG, "Executing finish of activity: " + prev);
@@ -1142,7 +854,7 @@
                 if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending stop: " + prev);
                 if (prev.waitingVisible) {
                     prev.waitingVisible = false;
-                    mWaitingVisibleActivities.remove(prev);
+                    mStackSupervisor.mWaitingVisibleActivities.remove(prev);
                     if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(
                             TAG, "Complete pause, no longer waiting: " + prev);
                 }
@@ -1155,15 +867,17 @@
                     if (DEBUG_PAUSE) Slog.v(TAG, "Destroying after pause: " + prev);
                     destroyActivityLocked(prev, true, false, "pause-config");
                 } else {
-                    mStoppingActivities.add(prev);
-                    if (mStoppingActivities.size() > 3) {
+                    mStackSupervisor.mStoppingActivities.add(prev);
+                    if (mStackSupervisor.mStoppingActivities.size() > 3 ||
+                            prev.frontOfTask && mTaskHistory.size() <= 1) {
                         // If we already have a few activities waiting to stop,
                         // then give up on things going idle and start clearing
-                        // them out.
+                        // them out. Or if r is the last of activity of the last task the stack
+                        // will be empty and must be cleared immediately.
                         if (DEBUG_PAUSE) Slog.v(TAG, "To many pending stops, forcing idle");
-                        scheduleIdleLocked();
+                        mStackSupervisor.scheduleIdleLocked();
                     } else {
-                        checkReadyForSleepLocked();
+                        mStackSupervisor.checkReadyForSleepLocked();
                     }
                 }
             } else {
@@ -1173,45 +887,46 @@
             mPausingActivity = null;
         }
 
-        if (!mService.isSleeping()) {
-            resumeTopActivityLocked(prev);
+        final ActivityStack topStack = mStackSupervisor.getFocusedStack();
+        if (!mService.isSleepingOrShuttingDown()) {
+            mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null);
         } else {
-            checkReadyForSleepLocked();
-            ActivityRecord top = topRunningActivityLocked(null);
+            mStackSupervisor.checkReadyForSleepLocked();
+            ActivityRecord top = topStack.topRunningActivityLocked(null);
             if (top == null || (prev != null && top != prev)) {
                 // If there are no more activities available to run,
                 // do resume anyway to start something.  Also if the top
                 // activity on the stack is not the just paused activity,
                 // we need to go ahead and resume it to ensure we complete
                 // an in-flight app switch.
-                resumeTopActivityLocked(null);
+                mStackSupervisor.resumeTopActivitiesLocked(topStack, null, null);
             }
         }
-        
-        if (prev != null) {
-            prev.resumeKeyDispatchingLocked();
-        }
 
-        if (prev.app != null && prev.cpuTimeAtResume > 0
-                && mService.mBatteryStatsService.isOnBattery()) {
-            long diff = 0;
-            synchronized (mService.mProcessStatsThread) {
-                diff = mService.mProcessStats.getCpuTimeForPid(prev.app.pid)
-                        - prev.cpuTimeAtResume;
-            }
-            if (diff > 0) {
-                BatteryStatsImpl bsi = mService.mBatteryStatsService.getActiveStatistics();
-                synchronized (bsi) {
-                    BatteryStatsImpl.Uid.Proc ps =
-                            bsi.getProcessStatsLocked(prev.info.applicationInfo.uid,
-                            prev.info.packageName);
-                    if (ps != null) {
-                        ps.addForegroundTimeLocked(diff);
+        if (prev != null) {
+            prev.resumeKeyDispatchingLocked();
+
+            if (prev.app != null && prev.cpuTimeAtResume > 0
+                    && mService.mBatteryStatsService.isOnBattery()) {
+                long diff;
+                synchronized (mService.mProcessCpuThread) {
+                    diff = mService.mProcessCpuTracker.getCpuTimeForPid(prev.app.pid)
+                            - prev.cpuTimeAtResume;
+                }
+                if (diff > 0) {
+                    BatteryStatsImpl bsi = mService.mBatteryStatsService.getActiveStatistics();
+                    synchronized (bsi) {
+                        BatteryStatsImpl.Uid.Proc ps =
+                                bsi.getProcessStatsLocked(prev.info.applicationInfo.uid,
+                                        prev.info.packageName);
+                        if (ps != null) {
+                            ps.addForegroundTimeLocked(diff);
+                        }
                     }
                 }
             }
+            prev.cpuTimeAtResume = 0; // reset it
         }
-        prev.cpuTimeAtResume = 0; // reset it
     }
 
     /**
@@ -1219,44 +934,25 @@
      * the resumed state (either by launching it or explicitly telling it),
      * this function updates the rest of our state to match that fact.
      */
-    private final void completeResumeLocked(ActivityRecord next) {
+    private void completeResumeLocked(ActivityRecord next) {
         next.idle = false;
         next.results = null;
         next.newIntents = null;
 
         // schedule an idle timeout in case the app doesn't do it for us.
-        Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
-        msg.obj = next;
-        mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
+        mStackSupervisor.scheduleIdleTimeoutLocked(next);
 
-        if (false) {
-            // The activity was never told to pause, so just keep
-            // things going as-is.  To maintain our own state,
-            // we need to emulate it coming back and saying it is
-            // idle.
-            msg = mHandler.obtainMessage(IDLE_NOW_MSG);
-            msg.obj = next;
-            mHandler.sendMessage(msg);
-        }
+        mStackSupervisor.reportResumedActivityLocked(next);
 
-        if (mMainStack) {
-            mService.reportResumedActivityLocked(next);
-        }
-
-        if (mMainStack) {
-            mService.setFocusedActivityLocked(next);
-        }
         next.resumeKeyDispatchingLocked();
-        ensureActivitiesVisibleLocked(null, 0);
-        mService.mWindowManager.executeAppTransition();
         mNoAnimActivities.clear();
 
         // Mark the point when the activity is resuming
         // TODO: To be more accurate, the mark should be before the onCreate,
         //       not after the onResume. But for subsequent starts, onResume is fine.
         if (next.app != null) {
-            synchronized (mService.mProcessStatsThread) {
-                next.cpuTimeAtResume = mService.mProcessStats.getCpuTimeForPid(next.app.pid);
+            synchronized (mService.mProcessCpuThread) {
+                next.cpuTimeAtResume = mService.mProcessCpuTracker.getCpuTimeForPid(next.app.pid);
             }
         } else {
             next.cpuTimeAtResume = 0; // Couldn't get the cpu time of process
@@ -1264,129 +960,170 @@
     }
 
     /**
+     * Version of ensureActivitiesVisible that can easily be called anywhere.
+     */
+    final boolean ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
+        return ensureActivitiesVisibleLocked(starting, configChanges, false);
+    }
+
+    final boolean ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
+            boolean forceHomeShown) {
+        ActivityRecord r = topRunningActivityLocked(null);
+        return r != null &&
+                ensureActivitiesVisibleLocked(r, starting, null, configChanges, forceHomeShown);
+    }
+
+    /**
      * Make sure that all activities that need to be visible (that is, they
      * currently can be seen by the user) actually are.
      */
-    final void ensureActivitiesVisibleLocked(ActivityRecord top,
-            ActivityRecord starting, String onlyThisProcess, int configChanges) {
+    final boolean ensureActivitiesVisibleLocked(ActivityRecord top, ActivityRecord starting,
+            String onlyThisProcess, int configChanges, boolean forceHomeShown) {
         if (DEBUG_VISBILITY) Slog.v(
                 TAG, "ensureActivitiesVisible behind " + top
                 + " configChanges=0x" + Integer.toHexString(configChanges));
 
+        if (mTranslucentActivityWaiting != top) {
+            mUndrawnActivitiesBelowTopTranslucent.clear();
+            if (mTranslucentActivityWaiting != null) {
+                // Call the callback with a timeout indication.
+                notifyActivityDrawnLocked(null);
+                mTranslucentActivityWaiting = null;
+            }
+            mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG);
+        }
+
         // If the top activity is not fullscreen, then we need to
         // make sure any activities under it are now visible.
-        final int count = mHistory.size();
-        int i = count-1;
-        while (mHistory.get(i) != top) {
-            i--;
-        }
-        ActivityRecord r;
-        boolean behindFullscreen = false;
-        for (; i>=0; i--) {
-            r = mHistory.get(i);
-            if (DEBUG_VISBILITY) Slog.v(
-                    TAG, "Make visible? " + r + " finishing=" + r.finishing
-                    + " state=" + r.state);
-            if (r.finishing) {
-                continue;
-            }
-            
-            final boolean doThisProcess = onlyThisProcess == null
-                    || onlyThisProcess.equals(r.processName);
-            
-            // First: if this is not the current activity being started, make
-            // sure it matches the current configuration.
-            if (r != starting && doThisProcess) {
-                ensureActivityConfigurationLocked(r, 0);
-            }
-            
-            if (r.app == null || r.app.thread == null) {
-                if (onlyThisProcess == null
-                        || onlyThisProcess.equals(r.processName)) {
-                    // This activity needs to be visible, but isn't even
-                    // running...  get it started, but don't resume it
-                    // at this point.
-                    if (DEBUG_VISBILITY) Slog.v(
-                            TAG, "Start and freeze screen for " + r);
-                    if (r != starting) {
-                        r.startFreezingScreenLocked(r.app, configChanges);
-                    }
-                    if (!r.visible) {
-                        if (DEBUG_VISBILITY) Slog.v(
-                                TAG, "Starting and making visible: " + r);
-                        mService.mWindowManager.setAppVisibility(r.appToken, true);
-                    }
-                    if (r != starting) {
-                        startSpecificActivityLocked(r, false, false);
-                    }
+        boolean aboveTop = true;
+        boolean showHomeBehindStack = false;
+        boolean behindFullscreen = !mStackSupervisor.isFrontStack(this) &&
+                !(forceHomeShown && isHomeStack());
+        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
+            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+                final ActivityRecord r = activities.get(activityNdx);
+                if (r.finishing) {
+                    continue;
                 }
-
-            } else if (r.visible) {
-                // If this activity is already visible, then there is nothing
-                // else to do here.
-                if (DEBUG_VISBILITY) Slog.v(
-                        TAG, "Skipping: already visible at " + r);
-                r.stopFreezingScreenLocked(false);
-
-            } else if (onlyThisProcess == null) {
-                // This activity is not currently visible, but is running.
-                // Tell it to become visible.
-                r.visible = true;
-                if (r.state != ActivityState.RESUMED && r != starting) {
-                    // If this activity is paused, tell it
-                    // to now show its window.
+                if (aboveTop && r != top) {
+                    continue;
+                }
+                aboveTop = false;
+                if (!behindFullscreen) {
                     if (DEBUG_VISBILITY) Slog.v(
-                            TAG, "Making visible and scheduling visibility: " + r);
-                    try {
-                        mService.mWindowManager.setAppVisibility(r.appToken, true);
-                        r.sleeping = false;
-                        r.app.pendingUiClean = true;
-                        r.app.thread.scheduleWindowVisibility(r.appToken, true);
+                            TAG, "Make visible? " + r + " finishing=" + r.finishing
+                            + " state=" + r.state);
+
+                    final boolean doThisProcess = onlyThisProcess == null
+                            || onlyThisProcess.equals(r.processName);
+
+                    // First: if this is not the current activity being started, make
+                    // sure it matches the current configuration.
+                    if (r != starting && doThisProcess) {
+                        ensureActivityConfigurationLocked(r, 0);
+                    }
+
+                    if (r.app == null || r.app.thread == null) {
+                        if (onlyThisProcess == null || onlyThisProcess.equals(r.processName)) {
+                            // This activity needs to be visible, but isn't even
+                            // running...  get it started, but don't resume it
+                            // at this point.
+                            if (DEBUG_VISBILITY) Slog.v(TAG, "Start and freeze screen for " + r);
+                            if (r != starting) {
+                                r.startFreezingScreenLocked(r.app, configChanges);
+                            }
+                            if (!r.visible) {
+                                if (DEBUG_VISBILITY) Slog.v(
+                                        TAG, "Starting and making visible: " + r);
+                                mWindowManager.setAppVisibility(r.appToken, true);
+                            }
+                            if (r != starting) {
+                                mStackSupervisor.startSpecificActivityLocked(r, false, false);
+                            }
+                        }
+
+                    } else if (r.visible) {
+                        // If this activity is already visible, then there is nothing
+                        // else to do here.
+                        if (DEBUG_VISBILITY) Slog.v(TAG, "Skipping: already visible at " + r);
                         r.stopFreezingScreenLocked(false);
-                    } catch (Exception e) {
-                        // Just skip on any failure; we'll make it
-                        // visible when it next restarts.
-                        Slog.w(TAG, "Exception thrown making visibile: "
-                                + r.intent.getComponent(), e);
+
+                    } else if (onlyThisProcess == null) {
+                        // This activity is not currently visible, but is running.
+                        // Tell it to become visible.
+                        r.visible = true;
+                        if (r.state != ActivityState.RESUMED && r != starting) {
+                            // If this activity is paused, tell it
+                            // to now show its window.
+                            if (DEBUG_VISBILITY) Slog.v(
+                                    TAG, "Making visible and scheduling visibility: " + r);
+                            try {
+                                if (mTranslucentActivityWaiting != null) {
+                                    mUndrawnActivitiesBelowTopTranslucent.add(r);
+                                }
+                                mWindowManager.setAppVisibility(r.appToken, true);
+                                r.sleeping = false;
+                                r.app.pendingUiClean = true;
+                                r.app.thread.scheduleWindowVisibility(r.appToken, true);
+                                r.stopFreezingScreenLocked(false);
+                            } catch (Exception e) {
+                                // Just skip on any failure; we'll make it
+                                // visible when it next restarts.
+                                Slog.w(TAG, "Exception thrown making visibile: "
+                                        + r.intent.getComponent(), e);
+                            }
+                        }
                     }
-                }
-            }
 
-            // Aggregate current change flags.
-            configChanges |= r.configChangeFlags;
+                    // Aggregate current change flags.
+                    configChanges |= r.configChangeFlags;
 
-            if (r.fullscreen) {
-                // At this point, nothing else needs to be shown
-                if (DEBUG_VISBILITY) Slog.v(
-                        TAG, "Stopping: fullscreen at " + r);
-                behindFullscreen = true;
-                i--;
-                break;
-            }
-        }
-
-        // Now for any activities that aren't visible to the user, make
-        // sure they no longer are keeping the screen frozen.
-        while (i >= 0) {
-            r = mHistory.get(i);
-            if (DEBUG_VISBILITY) Slog.v(
-                    TAG, "Make invisible? " + r + " finishing=" + r.finishing
-                    + " state=" + r.state
-                    + " behindFullscreen=" + behindFullscreen);
-            if (!r.finishing) {
-                if (behindFullscreen) {
+                    if (r.fullscreen) {
+                        // At this point, nothing else needs to be shown
+                        if (DEBUG_VISBILITY) Slog.v(TAG, "Fullscreen: at " + r);
+                        behindFullscreen = true;
+                    } else if (r.mLaunchHomeTaskNext) {
+                        if (DEBUG_VISBILITY) Slog.v(TAG, "Showing home: at " + r);
+                        showHomeBehindStack = true;
+                        behindFullscreen = true;
+                    }
+                } else {
+                    if (DEBUG_VISBILITY) Slog.v(
+                        TAG, "Make invisible? " + r + " finishing=" + r.finishing
+                        + " state=" + r.state
+                        + " behindFullscreen=" + behindFullscreen);
+                    // Now for any activities that aren't visible to the user, make
+                    // sure they no longer are keeping the screen frozen.
                     if (r.visible) {
-                        if (DEBUG_VISBILITY) Slog.v(
-                                TAG, "Making invisible: " + r);
+                        if (DEBUG_VISBILITY) Slog.v(TAG, "Making invisible: " + r);
                         r.visible = false;
                         try {
-                            mService.mWindowManager.setAppVisibility(r.appToken, false);
-                            if ((r.state == ActivityState.STOPPING
-                                    || r.state == ActivityState.STOPPED)
-                                    && r.app != null && r.app.thread != null) {
-                                if (DEBUG_VISBILITY) Slog.v(
-                                        TAG, "Scheduling invisibility: " + r);
-                                r.app.thread.scheduleWindowVisibility(r.appToken, false);
+                            mWindowManager.setAppVisibility(r.appToken, false);
+                            switch (r.state) {
+                                case STOPPING:
+                                case STOPPED:
+                                    if (r.app != null && r.app.thread != null) {
+                                        if (DEBUG_VISBILITY) Slog.v(
+                                                TAG, "Scheduling invisibility: " + r);
+                                        r.app.thread.scheduleWindowVisibility(r.appToken, false);
+                                    }
+                                    break;
+
+                                case INITIALIZING:
+                                case RESUMED:
+                                case PAUSING:
+                                case PAUSED:
+                                    // This case created for transitioning activities from
+                                    // translucent to opaque {@link Activity#convertToOpaque}.
+                                    if (!mStackSupervisor.mStoppingActivities.contains(r)) {
+                                        mStackSupervisor.mStoppingActivities.add(r);
+                                    }
+                                    mStackSupervisor.scheduleIdleLocked();
+                                    break;
+
+                                default:
+                                    break;
                             }
                         } catch (Exception e) {
                             // Just skip on any failure; we'll make it
@@ -1395,30 +1132,50 @@
                                     + r.intent.getComponent(), e);
                         }
                     } else {
-                        if (DEBUG_VISBILITY) Slog.v(
-                                TAG, "Already invisible: " + r);
+                        if (DEBUG_VISBILITY) Slog.v(TAG, "Already invisible: " + r);
                     }
-                } else if (r.fullscreen) {
-                    if (DEBUG_VISBILITY) Slog.v(
-                            TAG, "Now behindFullscreen: " + r);
-                    behindFullscreen = true;
                 }
             }
-            i--;
         }
+        return showHomeBehindStack;
+    }
+
+    void convertToTranslucent(ActivityRecord r) {
+        mTranslucentActivityWaiting = r;
+        mUndrawnActivitiesBelowTopTranslucent.clear();
+        mHandler.sendEmptyMessageDelayed(TRANSLUCENT_TIMEOUT_MSG, TRANSLUCENT_CONVERSION_TIMEOUT);
     }
 
     /**
-     * Version of ensureActivitiesVisible that can easily be called anywhere.
+     * Called as activities below the top translucent activity are redrawn. When the last one is
+     * redrawn notify the top activity by calling
+     * {@link Activity#onTranslucentConversionComplete}.
+     *
+     * @param r The most recent background activity to be drawn. Or, if r is null then a timeout
+     * occurred and the activity will be notified immediately.
      */
-    final void ensureActivitiesVisibleLocked(ActivityRecord starting,
-            int configChanges) {
-        ActivityRecord r = topRunningActivityLocked(null);
-        if (r != null) {
-            ensureActivitiesVisibleLocked(r, starting, null, configChanges);
+    void notifyActivityDrawnLocked(ActivityRecord r) {
+        if ((r == null)
+                || (mUndrawnActivitiesBelowTopTranslucent.remove(r) &&
+                        mUndrawnActivitiesBelowTopTranslucent.isEmpty())) {
+            // The last undrawn activity below the top has just been drawn. If there is an
+            // opaque activity at the top, notify it that it can become translucent safely now.
+            final ActivityRecord waitingActivity = mTranslucentActivityWaiting;
+            mTranslucentActivityWaiting = null;
+            mUndrawnActivitiesBelowTopTranslucent.clear();
+            mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG);
+
+            if (waitingActivity != null && waitingActivity.app != null &&
+                    waitingActivity.app.thread != null) {
+                try {
+                    waitingActivity.app.thread.scheduleTranslucentConversionComplete(
+                            waitingActivity.appToken, r != null);
+                } catch (RemoteException e) {
+                }
+            }
         }
     }
-    
+
     /**
      * Ensure that the top activity in the stack is resumed.
      *
@@ -1438,42 +1195,73 @@
 
         // Remember how we'll process this pause/resume situation, and ensure
         // that the state is reset however we wind up proceeding.
-        final boolean userLeaving = mUserLeaving;
-        mUserLeaving = false;
+        final boolean userLeaving = mStackSupervisor.mUserLeaving;
+        mStackSupervisor.mUserLeaving = false;
 
         if (next == null) {
             // There are no more activities!  Let's just start up the
             // Launcher...
-            if (mMainStack) {
-                ActivityOptions.abort(options);
-                return mService.startHomeActivityLocked(mCurrentUser);
-            }
+            ActivityOptions.abort(options);
+            if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: No more activities go home");
+            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
+            return mStackSupervisor.resumeHomeActivity(prev);
         }
 
         next.delayedResume = false;
-        
+
         // If the top activity is the resumed one, nothing to do.
-        if (mResumedActivity == next && next.state == ActivityState.RESUMED) {
+        if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
+                    mStackSupervisor.allResumedActivitiesComplete()) {
             // Make sure we have executed any pending transitions, since there
             // should be nothing left to do at this point.
-            mService.mWindowManager.executeAppTransition();
+            mWindowManager.executeAppTransition();
             mNoAnimActivities.clear();
             ActivityOptions.abort(options);
+            if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Top activity resumed " + next);
+            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
             return false;
         }
 
+        final TaskRecord nextTask = next.task;
+        final TaskRecord prevTask = prev != null ? prev.task : null;
+        if (prevTask != null && prev.mLaunchHomeTaskNext && prev.finishing && prev.frontOfTask) {
+            if (DEBUG_STACK)  mStackSupervisor.validateTopActivitiesLocked();
+            if (prevTask == nextTask) {
+                ArrayList<ActivityRecord> activities = prevTask.mActivities;
+                final int numActivities = activities.size();
+                for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
+                    final ActivityRecord r = activities.get(activityNdx);
+                    // r is usually the same as next, but what if two activities were launched
+                    // before prev finished?
+                    if (!r.finishing) {
+                        r.mLaunchHomeTaskNext = true;
+                        r.frontOfTask = true;
+                        break;
+                    }
+                }
+            } else if (prevTask != topTask()) {
+                // This task is going away but it was supposed to return to the home task.
+                // Now the task above it has to return to the home task instead.
+                final int taskNdx = mTaskHistory.indexOf(prevTask) + 1;
+                mTaskHistory.get(taskNdx).mActivities.get(0).mLaunchHomeTaskNext = true;
+            } else {
+                if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Launching home next");
+                return mStackSupervisor.resumeHomeActivity(prev);
+            }
+        }
+
         // If we are sleeping, and there is no resumed activity, and the top
         // activity is paused, well that is the state we want.
-        if ((mService.mSleeping || mService.mShuttingDown)
+        if ((mService.isSleepingOrShuttingDown())
                 && mLastPausedActivity == next
-                && (next.state == ActivityState.PAUSED
-                    || next.state == ActivityState.STOPPED
-                    || next.state == ActivityState.STOPPING)) {
+                && mStackSupervisor.allPausedActivitiesComplete()) {
             // Make sure we have executed any pending transitions, since there
             // should be nothing left to do at this point.
-            mService.mWindowManager.executeAppTransition();
+            mWindowManager.executeAppTransition();
             mNoAnimActivities.clear();
             ActivityOptions.abort(options);
+            if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Going to sleep and all paused");
+            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
             return false;
         }
 
@@ -1483,15 +1271,16 @@
         if (mService.mStartedUsers.get(next.userId) == null) {
             Slog.w(TAG, "Skipping resume of top activity " + next
                     + ": user " + next.userId + " is stopped");
+            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
             return false;
         }
 
         // The activity may be waiting for stop, but that is no longer
         // appropriate for it.
-        mStoppingActivities.remove(next);
-        mGoingToSleepActivities.remove(next);
+        mStackSupervisor.mStoppingActivities.remove(next);
+        mStackSupervisor.mGoingToSleepActivities.remove(next);
         next.sleeping = false;
-        mWaitingVisibleActivities.remove(next);
+        mStackSupervisor.mWaitingVisibleActivities.remove(next);
 
         next.updateOptionsLocked(options);
 
@@ -1499,9 +1288,10 @@
 
         // If we are currently pausing an activity, then don't do anything
         // until that is done.
-        if (mPausingActivity != null) {
-            if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(TAG,
-                    "Skip resume: pausing=" + mPausingActivity);
+        if (!mStackSupervisor.allPausedActivitiesComplete()) {
+            if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG,
+                    "resumeTopActivityLocked: Skip resume: some activity pausing.");
+            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
             return false;
         }
 
@@ -1533,11 +1323,18 @@
                 mLastStartedActivity = next;
             }
         }
-        
+
         // We need to start pausing the current activity so the top one
         // can be resumed...
+        boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving);
         if (mResumedActivity != null) {
-            if (DEBUG_SWITCH) Slog.v(TAG, "Skip resume: need to start pausing");
+            pausing = true;
+            startPausingLocked(userLeaving, false);
+            if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Pausing " + mResumedActivity);
+        }
+        if (pausing) {
+            if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG,
+                    "resumeTopActivityLocked: Skip resume: need to start pausing");
             // At this point we want to put the upcoming activity's process
             // at the top of the LRU list, since we know we will be needing it
             // very soon and it would be a waste to let it get killed if it
@@ -1547,29 +1344,26 @@
                 // happen whenever it needs to later.
                 mService.updateLruProcessLocked(next.app, false);
             }
-            startPausingLocked(userLeaving, false);
+            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
             return true;
         }
 
         // If the most recent activity was noHistory but was only stopped rather
         // than stopped+finished because the device went to sleep, we need to make
         // sure to finish it as we're making a new activity topmost.
-        final ActivityRecord last = mLastPausedActivity;
-        if (mService.mSleeping && last != null && !last.finishing) {
-            if ((last.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
-                    || (last.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {
-                if (DEBUG_STATES) {
-                    Slog.d(TAG, "no-history finish of " + last + " on new resume");
-                }
-                requestFinishActivityLocked(last.appToken, Activity.RESULT_CANCELED, null,
-                        "no-history", false);
-            }
+        if (mService.mSleeping && mLastNoHistoryActivity != null &&
+                !mLastNoHistoryActivity.finishing) {
+            if (DEBUG_STATES) Slog.d(TAG, "no-history finish of " + mLastNoHistoryActivity +
+                    " on new resume");
+            requestFinishActivityLocked(mLastNoHistoryActivity.appToken, Activity.RESULT_CANCELED,
+                    null, "no-history", false);
+            mLastNoHistoryActivity = null;
         }
 
         if (prev != null && prev != next) {
             if (!prev.waitingVisible && next != null && !next.nowVisible) {
                 prev.waitingVisible = true;
-                mWaitingVisibleActivities.add(prev);
+                mStackSupervisor.mWaitingVisibleActivities.add(prev);
                 if (DEBUG_SWITCH) Slog.v(
                         TAG, "Resuming top, waiting visible to hide: " + prev);
             } else {
@@ -1582,7 +1376,7 @@
                 // previous should actually be hidden depending on whether the
                 // new one is found to be full-screen or not.
                 if (prev.finishing) {
-                    mService.mWindowManager.setAppVisibility(prev.appToken, false);
+                    mWindowManager.setAppVisibility(prev.appToken, false);
                     if (DEBUG_SWITCH) Slog.v(TAG, "Not waiting for visible to hide: "
                             + prev + ", waitingVisible="
                             + (prev != null ? prev.waitingVisible : null)
@@ -1610,120 +1404,114 @@
         // We are starting up the next activity, so tell the window manager
         // that the previous one will be hidden soon.  This way it can know
         // to ignore it when computing the desired screen orientation.
-        boolean noAnim = false;
+        boolean anim = true;
         if (prev != null) {
             if (prev.finishing) {
                 if (DEBUG_TRANSITION) Slog.v(TAG,
                         "Prepare close transition: prev=" + prev);
                 if (mNoAnimActivities.contains(prev)) {
-                    mService.mWindowManager.prepareAppTransition(
-                            AppTransition.TRANSIT_NONE, false);
+                    anim = false;
+                    mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
                 } else {
-                    mService.mWindowManager.prepareAppTransition(prev.task == next.task
+                    mWindowManager.prepareAppTransition(prev.task == next.task
                             ? AppTransition.TRANSIT_ACTIVITY_CLOSE
                             : AppTransition.TRANSIT_TASK_CLOSE, false);
                 }
-                mService.mWindowManager.setAppWillBeHidden(prev.appToken);
-                mService.mWindowManager.setAppVisibility(prev.appToken, false);
+                mWindowManager.setAppWillBeHidden(prev.appToken);
+                mWindowManager.setAppVisibility(prev.appToken, false);
             } else {
-                if (DEBUG_TRANSITION) Slog.v(TAG,
-                        "Prepare open transition: prev=" + prev);
+                if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare open transition: prev=" + prev);
                 if (mNoAnimActivities.contains(next)) {
-                    noAnim = true;
-                    mService.mWindowManager.prepareAppTransition(
-                            AppTransition.TRANSIT_NONE, false);
+                    anim = false;
+                    mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
                 } else {
-                    mService.mWindowManager.prepareAppTransition(prev.task == next.task
+                    mWindowManager.prepareAppTransition(prev.task == next.task
                             ? AppTransition.TRANSIT_ACTIVITY_OPEN
                             : AppTransition.TRANSIT_TASK_OPEN, false);
                 }
             }
             if (false) {
-                mService.mWindowManager.setAppWillBeHidden(prev.appToken);
-                mService.mWindowManager.setAppVisibility(prev.appToken, false);
+                mWindowManager.setAppWillBeHidden(prev.appToken);
+                mWindowManager.setAppVisibility(prev.appToken, false);
             }
-        } else if (mHistory.size() > 1) {
-            if (DEBUG_TRANSITION) Slog.v(TAG,
-                    "Prepare open transition: no previous");
+        } else {
+            if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare open transition: no previous");
             if (mNoAnimActivities.contains(next)) {
-                noAnim = true;
-                mService.mWindowManager.prepareAppTransition(
-                        AppTransition.TRANSIT_NONE, false);
+                anim = false;
+                mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
             } else {
-                mService.mWindowManager.prepareAppTransition(
-                        AppTransition.TRANSIT_ACTIVITY_OPEN, false);
+                mWindowManager.prepareAppTransition(AppTransition.TRANSIT_ACTIVITY_OPEN, false);
             }
         }
-        if (!noAnim) {
+        if (anim) {
             next.applyOptionsLocked();
         } else {
             next.clearOptionsLocked();
         }
 
+        ActivityStack lastStack = mStackSupervisor.getLastStack();
         if (next.app != null && next.app.thread != null) {
             if (DEBUG_SWITCH) Slog.v(TAG, "Resume running: " + next);
 
             // This activity is now becoming visible.
-            mService.mWindowManager.setAppVisibility(next.appToken, true);
+            mWindowManager.setAppVisibility(next.appToken, true);
 
             // schedule launch ticks to collect information about slow apps.
             next.startLaunchTickingLocked();
 
-            ActivityRecord lastResumedActivity = mResumedActivity;
+            ActivityRecord lastResumedActivity =
+                    lastStack == null ? null :lastStack.mResumedActivity;
             ActivityState lastState = next.state;
 
             mService.updateCpuStats();
-            
+
             if (DEBUG_STATES) Slog.v(TAG, "Moving to RESUMED: " + next + " (in existing)");
             next.state = ActivityState.RESUMED;
             mResumedActivity = next;
             next.task.touchActiveTime();
-            if (mMainStack) {
-                mService.addRecentTaskLocked(next.task);
-            }
+            mService.addRecentTaskLocked(next.task);
             mService.updateLruProcessLocked(next.app, true);
             updateLRUListLocked(next);
 
             // Have the window manager re-evaluate the orientation of
             // the screen based on the new activity order.
-            boolean updated = false;
-            if (mMainStack) {
-                synchronized (mService) {
-                    Configuration config = mService.mWindowManager.updateOrientationFromAppTokens(
-                            mService.mConfiguration,
-                            next.mayFreezeScreenLocked(next.app) ? next.appToken : null);
-                    if (config != null) {
-                        next.frozenBeforeDestroy = true;
-                    }
-                    updated = mService.updateConfigurationLocked(config, next, false, false);
+            boolean notUpdated = true;
+            if (mStackSupervisor.isFrontStack(this)) {
+                Configuration config = mWindowManager.updateOrientationFromAppTokens(
+                        mService.mConfiguration,
+                        next.mayFreezeScreenLocked(next.app) ? next.appToken : null);
+                if (config != null) {
+                    next.frozenBeforeDestroy = true;
                 }
+                notUpdated = !mService.updateConfigurationLocked(config, next, false, false);
             }
-            if (!updated) {
+
+            if (notUpdated) {
                 // The configuration update wasn't able to keep the existing
                 // instance of the activity, and instead started a new one.
                 // We should be all done, but let's just make sure our activity
                 // is still at the top and schedule another run if something
                 // weird happened.
                 ActivityRecord nextNext = topRunningActivityLocked(null);
-                if (DEBUG_SWITCH) Slog.i(TAG,
+                if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG,
                         "Activity config changed during resume: " + next
                         + ", new next: " + nextNext);
                 if (nextNext != next) {
                     // Do over!
-                    mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
+                    mStackSupervisor.scheduleResumeTopActivities();
                 }
-                if (mMainStack) {
-                    mService.setFocusedActivityLocked(next);
+                if (mStackSupervisor.reportResumedActivityLocked(next)) {
+                    mNoAnimActivities.clear();
+                    if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
+                    return true;
                 }
-                ensureActivitiesVisibleLocked(null, 0);
-                mService.mWindowManager.executeAppTransition();
-                mNoAnimActivities.clear();
-                return true;
+                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
+                return false;
             }
-            
+
             try {
                 // Deliver all pending results.
-                ArrayList a = next.results;
+                ArrayList<ResultInfo> a = next.results;
                 if (a != null) {
                     final int N = a.size();
                     if (!next.finishing && N > 0) {
@@ -1741,36 +1529,38 @@
                 EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY,
                         next.userId, System.identityHashCode(next),
                         next.task.taskId, next.shortComponentName);
-                
-                next.sleeping = false;
-                showAskCompatModeDialogLocked(next);
-                next.app.pendingUiClean = true;
-                next.app.thread.scheduleResumeActivity(next.appToken,
-                        mService.isNextTransitionForward());
-                
-                checkReadyForSleepLocked();
 
+                next.sleeping = false;
+                mService.showAskCompatModeDialogLocked(next);
+                next.app.pendingUiClean = true;
+                next.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
+                next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
+                        mService.isNextTransitionForward());
+
+                mStackSupervisor.checkReadyForSleepLocked();
+
+                if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Resumed " + next);
             } catch (Exception e) {
                 // Whoops, need to restart this activity!
                 if (DEBUG_STATES) Slog.v(TAG, "Resume failed; resetting state to "
                         + lastState + ": " + next);
                 next.state = lastState;
-                mResumedActivity = lastResumedActivity;
+                if (lastStack != null) {
+                    lastStack.mResumedActivity = lastResumedActivity;
+                }
                 Slog.i(TAG, "Restarting because process died: " + next);
                 if (!next.hasBeenLaunched) {
                     next.hasBeenLaunched = true;
-                } else {
-                    if (SHOW_APP_STARTING_PREVIEW && mMainStack) {
-                        mService.mWindowManager.setAppStartingWindow(
-                                next.appToken, next.packageName, next.theme,
-                                mService.compatibilityInfoForPackageLocked(
-                                        next.info.applicationInfo),
-                                next.nonLocalizedLabel,
-                                next.labelRes, next.icon, next.windowFlags,
-                                null, true);
-                    }
+                } else  if (SHOW_APP_STARTING_PREVIEW && lastStack != null &&
+                        mStackSupervisor.isFrontStack(lastStack)) {
+                    mWindowManager.setAppStartingWindow(
+                            next.appToken, next.packageName, next.theme,
+                            mService.compatibilityInfoForPackageLocked(next.info.applicationInfo),
+                            next.nonLocalizedLabel, next.labelRes, next.icon, next.logo,
+                            next.windowFlags, null, true);
                 }
-                startSpecificActivityLocked(next, true, false);
+                mStackSupervisor.startSpecificActivityLocked(next, true, false);
+                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
                 return true;
             }
 
@@ -1785,6 +1575,7 @@
                 Slog.w(TAG, "Exception thrown during resume of " + next, e);
                 requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED, null,
                         "resume-exception", true);
+                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
                 return true;
             }
             next.stopped = false;
@@ -1795,53 +1586,70 @@
                 next.hasBeenLaunched = true;
             } else {
                 if (SHOW_APP_STARTING_PREVIEW) {
-                    mService.mWindowManager.setAppStartingWindow(
+                    mWindowManager.setAppStartingWindow(
                             next.appToken, next.packageName, next.theme,
                             mService.compatibilityInfoForPackageLocked(
                                     next.info.applicationInfo),
                             next.nonLocalizedLabel,
-                            next.labelRes, next.icon, next.windowFlags,
+                            next.labelRes, next.icon, next.logo, next.windowFlags,
                             null, true);
                 }
                 if (DEBUG_SWITCH) Slog.v(TAG, "Restarting: " + next);
             }
-            startSpecificActivityLocked(next, true, true);
+            if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Restarting " + next);
+            mStackSupervisor.startSpecificActivityLocked(next, true, true);
         }
 
+        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
         return true;
     }
 
-    private final void startActivityLocked(ActivityRecord r, boolean newTask,
-            boolean doResume, boolean keepCurTransition, Bundle options) {
-        final int NH = mHistory.size();
+    private void insertTaskAtTop(TaskRecord task) {
+        mTaskHistory.remove(task);
+        // Now put task at top.
+        int stackNdx = mTaskHistory.size();
+        if (task.userId != mCurrentUser) {
+            // Put non-current user tasks below current user tasks.
+            while (--stackNdx >= 0) {
+                if (mTaskHistory.get(stackNdx).userId != mCurrentUser) {
+                    break;
+                }
+            }
+            ++stackNdx;
+        }
+        mTaskHistory.add(stackNdx, task);
+    }
 
-        int addPos = -1;
-        
+    final void startActivityLocked(ActivityRecord r, boolean newTask,
+            boolean doResume, boolean keepCurTransition, Bundle options) {
+        TaskRecord rTask = r.task;
+        final int taskId = rTask.taskId;
+        if (taskForIdLocked(taskId) == null || newTask) {
+            // Last activity in task had been removed or ActivityManagerService is reusing task.
+            // Insert or replace.
+            // Might not even be in.
+            insertTaskAtTop(rTask);
+            mWindowManager.moveTaskToTop(taskId);
+        }
+        TaskRecord task = null;
         if (!newTask) {
             // If starting in an existing task, find where that is...
             boolean startIt = true;
-            for (int i = NH-1; i >= 0; i--) {
-                ActivityRecord p = mHistory.get(i);
-                if (p.finishing) {
-                    continue;
-                }
-                if (p.task == r.task) {
+            for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+                task = mTaskHistory.get(taskNdx);
+                if (task == r.task) {
                     // Here it is!  Now, if this is not yet visible to the
                     // user, then just add it without starting; it will
                     // get started when the user navigates back to it.
-                    addPos = i+1;
                     if (!startIt) {
-                        if (DEBUG_ADD_REMOVE) {
-                            RuntimeException here = new RuntimeException("here");
-                            here.fillInStackTrace();
-                            Slog.i(TAG, "Adding activity " + r + " to stack at " + addPos,
-                                    here);
-                        }
-                        mHistory.add(addPos, r);
+                        if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task "
+                                + task, new RuntimeException("here").fillInStackTrace());
+                        task.addActivityToTop(r);
                         r.putInHistory();
-                        mService.mWindowManager.addAppToken(addPos, r.appToken, r.task.taskId,
-                                r.info.screenOrientation, r.fullscreen,
-                                (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0);
+                        mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
+                                r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
+                                (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0,
+                                r.userId);
                         if (VALIDATE_TOKENS) {
                             validateAppTokensLocked();
                         }
@@ -1849,8 +1657,7 @@
                         return;
                     }
                     break;
-                }
-                if (p.fullscreen) {
+                } else if (task.numFullscreen > 0) {
                     startIt = false;
                 }
             }
@@ -1858,28 +1665,26 @@
 
         // Place a new activity at top of stack, so it is next to interact
         // with the user.
-        if (addPos < 0) {
-            addPos = NH;
-        }
-        
+
         // If we are not placing the new activity frontmost, we do not want
         // to deliver the onUserLeaving callback to the actual frontmost
         // activity
-        if (addPos < NH) {
-            mUserLeaving = false;
-            if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() behind front, mUserLeaving=false");
+        if (task == r.task && mTaskHistory.indexOf(task) != (mTaskHistory.size() - 1)) {
+            mStackSupervisor.mUserLeaving = false;
+            if (DEBUG_USER_LEAVING) Slog.v(TAG,
+                    "startActivity() behind front, mUserLeaving=false");
         }
-        
+
+        task = r.task;
+
         // Slot the activity into the history stack and proceed
-        if (DEBUG_ADD_REMOVE) {
-            RuntimeException here = new RuntimeException("here");
-            here.fillInStackTrace();
-            Slog.i(TAG, "Adding activity " + r + " to stack at " + addPos, here);
-        }
-        mHistory.add(addPos, r);
+        if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to stack to task " + task,
+                new RuntimeException("here").fillInStackTrace());
+        task.addActivityToTop(r);
+
         r.putInHistory();
         r.frontOfTask = newTask;
-        if (NH > 0) {
+        if (!isHomeStack() || numActivities() > 0) {
             // We want to show the starting preview window if we are
             // switching to a new task, or the next activity's process is
             // not currently running.
@@ -1894,19 +1699,18 @@
             if (DEBUG_TRANSITION) Slog.v(TAG,
                     "Prepare open transition: starting " + r);
             if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
-                mService.mWindowManager.prepareAppTransition(
-                        AppTransition.TRANSIT_NONE, keepCurTransition);
+                mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, keepCurTransition);
                 mNoAnimActivities.add(r);
             } else {
-                mService.mWindowManager.prepareAppTransition(newTask
+                mWindowManager.prepareAppTransition(newTask
                         ? AppTransition.TRANSIT_TASK_OPEN
                         : AppTransition.TRANSIT_ACTIVITY_OPEN, keepCurTransition);
                 mNoAnimActivities.remove(r);
             }
             r.updateOptionsLocked(options);
-            mService.mWindowManager.addAppToken(
-                    addPos, r.appToken, r.task.taskId, r.info.screenOrientation, r.fullscreen,
-                    (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0);
+            mWindowManager.addAppToken(task.mActivities.indexOf(r),
+                    r.appToken, r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
+                    (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, r.userId);
             boolean doShow = true;
             if (newTask) {
                 // Even though this activity is starting fresh, we still need
@@ -1929,23 +1733,27 @@
                 if (prev != null) {
                     // We don't want to reuse the previous starting preview if:
                     // (1) The current activity is in a different task.
-                    if (prev.task != r.task) prev = null;
+                    if (prev.task != r.task) {
+                        prev = null;
+                    }
                     // (2) The current activity is already displayed.
-                    else if (prev.nowVisible) prev = null;
+                    else if (prev.nowVisible) {
+                        prev = null;
+                    }
                 }
-                mService.mWindowManager.setAppStartingWindow(
+                mWindowManager.setAppStartingWindow(
                         r.appToken, r.packageName, r.theme,
                         mService.compatibilityInfoForPackageLocked(
                                 r.info.applicationInfo), r.nonLocalizedLabel,
-                        r.labelRes, r.icon, r.windowFlags,
+                        r.labelRes, r.icon, r.logo, r.windowFlags,
                         prev != null ? prev.appToken : null, showStartingIcon);
             }
         } else {
             // If this is the first activity, don't do any fancy animations,
             // because there is nothing for it to animate on top of.
-            mService.mWindowManager.addAppToken(addPos, r.appToken, r.task.taskId,
-                    r.info.screenOrientation, r.fullscreen,
-                    (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0);
+            mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
+                    r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
+                    (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, r.userId);
             ActivityOptions.abort(options);
         }
         if (VALIDATE_TOKENS) {
@@ -1953,233 +1761,68 @@
         }
 
         if (doResume) {
-            resumeTopActivityLocked(null);
+            mStackSupervisor.resumeTopActivitiesLocked();
         }
     }
 
     final void validateAppTokensLocked() {
         mValidateAppTokens.clear();
-        mValidateAppTokens.ensureCapacity(mHistory.size());
-        for (int i=0; i<mHistory.size(); i++) {
-            mValidateAppTokens.add(mHistory.get(i).appToken);
+        mValidateAppTokens.ensureCapacity(numActivities());
+        final int numTasks = mTaskHistory.size();
+        for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
+            TaskRecord task = mTaskHistory.get(taskNdx);
+            final ArrayList<ActivityRecord> activities = task.mActivities;
+            if (activities.isEmpty()) {
+                continue;
+            }
+            TaskGroup group = new TaskGroup();
+            group.taskId = task.taskId;
+            mValidateAppTokens.add(group);
+            final int numActivities = activities.size();
+            for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
+                final ActivityRecord r = activities.get(activityNdx);
+                group.tokens.add(r.appToken);
+            }
         }
-        mService.mWindowManager.validateAppTokens(mValidateAppTokens);
+        mWindowManager.validateAppTokens(mStackId, mValidateAppTokens);
     }
 
     /**
      * Perform a reset of the given task, if needed as part of launching it.
      * Returns the new HistoryRecord at the top of the task.
      */
-    private final ActivityRecord resetTaskIfNeededLocked(ActivityRecord taskTop,
-            ActivityRecord newActivity) {
-        boolean forceReset = (newActivity.info.flags
-                &ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0;
-        if (ACTIVITY_INACTIVE_RESET_TIME > 0
-                && taskTop.task.getInactiveDuration() > ACTIVITY_INACTIVE_RESET_TIME) {
-            if ((newActivity.info.flags
-                    &ActivityInfo.FLAG_ALWAYS_RETAIN_TASK_STATE) == 0) {
-                forceReset = true;
-            }
-        }
-        
-        final TaskRecord task = taskTop.task;
-        
-        // We are going to move through the history list so that we can look
-        // at each activity 'target' with 'below' either the interesting
-        // activity immediately below it in the stack or null.
-        ActivityRecord target = null;
-        int targetI = 0;
-        int taskTopI = -1;
-        int replyChainEnd = -1;
-        int lastReparentPos = -1;
+    /**
+     * Helper method for #resetTaskIfNeededLocked.
+     * We are inside of the task being reset...  we'll either finish this activity, push it out
+     * for another task, or leave it as-is.
+     * @param task The task containing the Activity (taskTop) that might be reset.
+     * @param forceReset
+     * @return An ActivityOptions that needs to be processed.
+     */
+    final ActivityOptions resetTargetTaskIfNeededLocked(TaskRecord task, boolean forceReset) {
         ActivityOptions topOptions = null;
-        boolean canMoveOptions = true;
-        for (int i=mHistory.size()-1; i>=-1; i--) {
-            ActivityRecord below = i >= 0 ? mHistory.get(i) : null;
-            
-            if (below != null && below.finishing) {
-                continue;
-            }
-            // Don't check any lower in the stack if we're crossing a user boundary.
-            if (below != null && below.userId != taskTop.userId) {
-                break;
-            }
-            if (target == null) {
-                target = below;
-                targetI = i;
-                // If we were in the middle of a reply chain before this
-                // task, it doesn't appear like the root of the chain wants
-                // anything interesting, so drop it.
-                replyChainEnd = -1;
-                continue;
-            }
-        
-            final int flags = target.info.flags;
-            
-            final boolean finishOnTaskLaunch =
-                (flags&ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0;
-            final boolean allowTaskReparenting =
-                (flags&ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0;
-            
-            if (target.task == task) {
-                // We are inside of the task being reset...  we'll either
-                // finish this activity, push it out for another task,
-                // or leave it as-is.  We only do this
-                // for activities that are not the root of the task (since
-                // if we finish the root, we may no longer have the task!).
-                if (taskTopI < 0) {
-                    taskTopI = targetI;
-                }
-                if (below != null && below.task == task) {
-                    final boolean clearWhenTaskReset =
-                            (target.intent.getFlags()
-                                    &Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0;
-                    if (!finishOnTaskLaunch && !clearWhenTaskReset && target.resultTo != null) {
-                        // If this activity is sending a reply to a previous
-                        // activity, we can't do anything with it now until
-                        // we reach the start of the reply chain.
-                        // XXX note that we are assuming the result is always
-                        // to the previous activity, which is almost always
-                        // the case but we really shouldn't count on.
-                        if (replyChainEnd < 0) {
-                            replyChainEnd = targetI;
-                        }
-                    } else if (!finishOnTaskLaunch && !clearWhenTaskReset && allowTaskReparenting
-                            && target.taskAffinity != null
-                            && !target.taskAffinity.equals(task.affinity)) {
-                        // If this activity has an affinity for another
-                        // task, then we need to move it out of here.  We will
-                        // move it as far out of the way as possible, to the
-                        // bottom of the activity stack.  This also keeps it
-                        // correctly ordered with any activities we previously
-                        // moved.
-                        ActivityRecord p = mHistory.get(0);
-                        if (target.taskAffinity != null
-                                && target.taskAffinity.equals(p.task.affinity)) {
-                            // If the activity currently at the bottom has the
-                            // same task affinity as the one we are moving,
-                            // then merge it into the same task.
-                            target.setTask(p.task, p.thumbHolder, false);
-                            if (DEBUG_TASKS) Slog.v(TAG, "Start pushing activity " + target
-                                    + " out to bottom task " + p.task);
-                        } else {
-                            mService.mCurTask++;
-                            if (mService.mCurTask <= 0) {
-                                mService.mCurTask = 1;
-                            }
-                            target.setTask(new TaskRecord(mService.mCurTask, target.info, null),
-                                    null, false);
-                            target.task.affinityIntent = target.intent;
-                            if (DEBUG_TASKS) Slog.v(TAG, "Start pushing activity " + target
-                                    + " out to new task " + target.task);
-                        }
-                        mService.mWindowManager.setAppGroupId(target.appToken, task.taskId);
-                        if (replyChainEnd < 0) {
-                            replyChainEnd = targetI;
-                        }
-                        int dstPos = 0;
-                        ThumbnailHolder curThumbHolder = target.thumbHolder;
-                        boolean gotOptions = !canMoveOptions;
-                        for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
-                            p = mHistory.get(srcPos);
-                            if (p.finishing) {
-                                continue;
-                            }
-                            if (DEBUG_TASKS) Slog.v(TAG, "Pushing next activity " + p
-                                    + " out to target's task " + target.task);
-                            p.setTask(target.task, curThumbHolder, false);
-                            curThumbHolder = p.thumbHolder;
-                            canMoveOptions = false;
-                            if (!gotOptions && topOptions == null) {
-                                topOptions = p.takeOptionsLocked();
-                                if (topOptions != null) {
-                                    gotOptions = true;
-                                }
-                            }
-                            if (DEBUG_ADD_REMOVE) {
-                                RuntimeException here = new RuntimeException("here");
-                                here.fillInStackTrace();
-                                Slog.i(TAG, "Removing and adding activity " + p + " to stack at "
-                                        + dstPos, here);
-                            }
-                            mHistory.remove(srcPos);
-                            mHistory.add(dstPos, p);
-                            mService.mWindowManager.moveAppToken(dstPos, p.appToken);
-                            mService.mWindowManager.setAppGroupId(p.appToken, p.task.taskId);
-                            dstPos++;
-                            if (VALIDATE_TOKENS) {
-                                validateAppTokensLocked();
-                            }
-                            i++;
-                        }
-                        if (taskTop == p) {
-                            taskTop = below;
-                        }
-                        if (taskTopI == replyChainEnd) {
-                            taskTopI = -1;
-                        }
-                        replyChainEnd = -1;
-                    } else if (forceReset || finishOnTaskLaunch
-                            || clearWhenTaskReset) {
-                        // If the activity should just be removed -- either
-                        // because it asks for it, or the task should be
-                        // cleared -- then finish it and anything that is
-                        // part of its reply chain.
-                        if (clearWhenTaskReset) {
-                            // In this case, we want to finish this activity
-                            // and everything above it, so be sneaky and pretend
-                            // like these are all in the reply chain.
-                            replyChainEnd = targetI+1;
-                            while (replyChainEnd < mHistory.size() &&
-                                    (mHistory.get(
-                                                replyChainEnd)).task == task) {
-                                replyChainEnd++;
-                            }
-                            replyChainEnd--;
-                        } else if (replyChainEnd < 0) {
-                            replyChainEnd = targetI;
-                        }
-                        ActivityRecord p = null;
-                        boolean gotOptions = !canMoveOptions;
-                        for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
-                            p = mHistory.get(srcPos);
-                            if (p.finishing) {
-                                continue;
-                            }
-                            canMoveOptions = false;
-                            if (!gotOptions && topOptions == null) {
-                                topOptions = p.takeOptionsLocked();
-                                if (topOptions != null) {
-                                    gotOptions = true;
-                                }
-                            }
-                            if (finishActivityLocked(p, srcPos,
-                                    Activity.RESULT_CANCELED, null, "reset", false)) {
-                                replyChainEnd--;
-                                srcPos--;
-                            }
-                        }
-                        if (taskTop == p) {
-                            taskTop = below;
-                        }
-                        if (taskTopI == replyChainEnd) {
-                            taskTopI = -1;
-                        }
-                        replyChainEnd = -1;
-                    } else {
-                        // If we were in the middle of a chain, well the
-                        // activity that started it all doesn't want anything
-                        // special, so leave it all as-is.
-                        replyChainEnd = -1;
-                    }
-                } else {
-                    // Reached the bottom of the task -- any reply chain
-                    // should be left as-is.
-                    replyChainEnd = -1;
-                }
 
-            } else if (target.resultTo != null && (below == null
-                    || below.task == target.task)) {
+        int replyChainEnd = -1;
+        boolean canMoveOptions = true;
+
+        // We only do this for activities that are not the root of the task (since if we finish
+        // the root, we may no longer have the task!).
+        final ArrayList<ActivityRecord> activities = task.mActivities;
+        final int numActivities = activities.size();
+        for (int i = numActivities - 1; i > 0; --i ) {
+            ActivityRecord target = activities.get(i);
+
+            final int flags = target.info.flags;
+            final boolean finishOnTaskLaunch =
+                    (flags & ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0;
+            final boolean allowTaskReparenting =
+                    (flags & ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0;
+            final boolean clearWhenTaskReset =
+                    (target.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0;
+
+            if (!finishOnTaskLaunch
+                    && !clearWhenTaskReset
+                    && target.resultTo != null) {
                 // If this activity is sending a reply to a previous
                 // activity, we can't do anything with it now until
                 // we reach the start of the reply chain.
@@ -2187,14 +1830,161 @@
                 // to the previous activity, which is almost always
                 // the case but we really shouldn't count on.
                 if (replyChainEnd < 0) {
-                    replyChainEnd = targetI;
+                    replyChainEnd = i;
+                }
+            } else if (!finishOnTaskLaunch
+                    && !clearWhenTaskReset
+                    && allowTaskReparenting
+                    && target.taskAffinity != null
+                    && !target.taskAffinity.equals(task.affinity)) {
+                // If this activity has an affinity for another
+                // task, then we need to move it out of here.  We will
+                // move it as far out of the way as possible, to the
+                // bottom of the activity stack.  This also keeps it
+                // correctly ordered with any activities we previously
+                // moved.
+                TaskRecord bottomTask = mTaskHistory.get(0);
+                ActivityRecord p = bottomTask.mActivities.get(0);
+                if (target.taskAffinity != null
+                        && target.taskAffinity.equals(p.task.affinity)) {
+                    // If the activity currently at the bottom has the
+                    // same task affinity as the one we are moving,
+                    // then merge it into the same task.
+                    target.setTask(p.task, p.thumbHolder, false);
+                    if (DEBUG_TASKS) Slog.v(TAG, "Start pushing activity " + target
+                            + " out to bottom task " + p.task);
+                } else {
+                    target.setTask(createTaskRecord(mStackSupervisor.getNextTaskId(), target.info,
+                            null, false), null, false);
+                    target.task.affinityIntent = target.intent;
+                    if (DEBUG_TASKS) Slog.v(TAG, "Start pushing activity " + target
+                            + " out to new task " + target.task);
                 }
 
-            } else if (taskTopI >= 0 && allowTaskReparenting
-                    && task.affinity != null
-                    && task.affinity.equals(target.taskAffinity)) {
-                // We are inside of another task...  if this activity has
-                // an affinity for our task, then either remove it if we are
+                final TaskRecord targetTask = target.task;
+                final int targetTaskId = targetTask.taskId;
+                mWindowManager.setAppGroupId(target.appToken, targetTaskId);
+
+                boolean noOptions = canMoveOptions;
+                final int start = replyChainEnd < 0 ? i : replyChainEnd;
+                for (int srcPos = start; srcPos >= i; --srcPos) {
+                    p = activities.get(srcPos);
+                    if (p.finishing) {
+                        continue;
+                    }
+
+                    ThumbnailHolder curThumbHolder = p.thumbHolder;
+                    canMoveOptions = false;
+                    if (noOptions && topOptions == null) {
+                        topOptions = p.takeOptionsLocked();
+                        if (topOptions != null) {
+                            noOptions = false;
+                        }
+                    }
+                    if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Removing activity " + p + " from task="
+                            + task + " adding to task=" + targetTask,
+                            new RuntimeException("here").fillInStackTrace());
+                    if (DEBUG_TASKS) Slog.v(TAG, "Pushing next activity " + p
+                            + " out to target's task " + target.task);
+                    p.setTask(targetTask, curThumbHolder, false);
+                    targetTask.addActivityAtBottom(p);
+
+                    mWindowManager.setAppGroupId(p.appToken, targetTaskId);
+                }
+
+                mWindowManager.moveTaskToBottom(targetTaskId);
+                if (VALIDATE_TOKENS) {
+                    validateAppTokensLocked();
+                }
+
+                replyChainEnd = -1;
+            } else if (forceReset || finishOnTaskLaunch || clearWhenTaskReset) {
+                // If the activity should just be removed -- either
+                // because it asks for it, or the task should be
+                // cleared -- then finish it and anything that is
+                // part of its reply chain.
+                int end;
+                if (clearWhenTaskReset) {
+                    // In this case, we want to finish this activity
+                    // and everything above it, so be sneaky and pretend
+                    // like these are all in the reply chain.
+                    end = numActivities - 1;
+                } else if (replyChainEnd < 0) {
+                    end = i;
+                } else {
+                    end = replyChainEnd;
+                }
+                boolean noOptions = canMoveOptions;
+                for (int srcPos = i; srcPos <= end; srcPos++) {
+                    ActivityRecord p = activities.get(srcPos);
+                    if (p.finishing) {
+                        continue;
+                    }
+                    canMoveOptions = false;
+                    if (noOptions && topOptions == null) {
+                        topOptions = p.takeOptionsLocked();
+                        if (topOptions != null) {
+                            noOptions = false;
+                        }
+                    }
+                    if (DEBUG_TASKS) Slog.w(TAG,
+                            "resetTaskIntendedTask: calling finishActivity on " + p);
+                    if (finishActivityLocked(p, Activity.RESULT_CANCELED, null, "reset", false)) {
+                        end--;
+                        srcPos--;
+                    }
+                }
+                replyChainEnd = -1;
+            } else {
+                // If we were in the middle of a chain, well the
+                // activity that started it all doesn't want anything
+                // special, so leave it all as-is.
+                replyChainEnd = -1;
+            }
+        }
+
+        return topOptions;
+    }
+
+    /**
+     * Helper method for #resetTaskIfNeededLocked. Processes all of the activities in a given
+     * TaskRecord looking for an affinity with the task of resetTaskIfNeededLocked.taskTop.
+     * @param affinityTask The task we are looking for an affinity to.
+     * @param task Task that resetTaskIfNeededLocked.taskTop belongs to.
+     * @param topTaskIsHigher True if #task has already been processed by resetTaskIfNeededLocked.
+     * @param forceReset Flag passed in to resetTaskIfNeededLocked.
+     */
+    private int resetAffinityTaskIfNeededLocked(TaskRecord affinityTask, TaskRecord task,
+            boolean topTaskIsHigher, boolean forceReset, int taskInsertionPoint) {
+        int replyChainEnd = -1;
+        final int taskId = task.taskId;
+        final String taskAffinity = task.affinity;
+
+        final ArrayList<ActivityRecord> activities = affinityTask.mActivities;
+        final int numActivities = activities.size();
+        // Do not operate on the root Activity.
+        for (int i = numActivities - 1; i > 0; --i) {
+            ActivityRecord target = activities.get(i);
+
+            final int flags = target.info.flags;
+            boolean finishOnTaskLaunch = (flags & ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0;
+            boolean allowTaskReparenting = (flags & ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0;
+
+            if (target.resultTo != null) {
+                // If this activity is sending a reply to a previous
+                // activity, we can't do anything with it now until
+                // we reach the start of the reply chain.
+                // XXX note that we are assuming the result is always
+                // to the previous activity, which is almost always
+                // the case but we really shouldn't count on.
+                if (replyChainEnd < 0) {
+                    replyChainEnd = i;
+                }
+            } else if (topTaskIsHigher
+                    && allowTaskReparenting
+                    && taskAffinity != null
+                    && taskAffinity.equals(target.taskAffinity)) {
+                // This activity has an affinity for our task. Either remove it if we are
                 // clearing or move it over to our task.  Note that
                 // we currently punt on the case where we are resetting a
                 // task that is not at the top but who has activities above
@@ -2205,93 +1995,103 @@
                 // someone starts an activity in a new task from an activity
                 // in a task that is not currently on top.)
                 if (forceReset || finishOnTaskLaunch) {
-                    if (replyChainEnd < 0) {
-                        replyChainEnd = targetI;
-                    }
-                    ActivityRecord p = null;
-                    if (DEBUG_TASKS) Slog.v(TAG, "Finishing task at index "
-                            + targetI + " to " + replyChainEnd);
-                    for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
-                        p = mHistory.get(srcPos);
+                    final int start = replyChainEnd >= 0 ? replyChainEnd : i;
+                    if (DEBUG_TASKS) Slog.v(TAG, "Finishing task at index " + start + " to " + i);
+                    for (int srcPos = start; srcPos >= i; --srcPos) {
+                        final ActivityRecord p = activities.get(srcPos);
                         if (p.finishing) {
                             continue;
                         }
-                        if (finishActivityLocked(p, srcPos,
-                                Activity.RESULT_CANCELED, null, "reset", false)) {
-                            taskTopI--;
-                            lastReparentPos--;
-                            replyChainEnd--;
-                            srcPos--;
-                        }
+                        finishActivityLocked(p, Activity.RESULT_CANCELED, null, "reset", false);
                     }
-                    replyChainEnd = -1;
                 } else {
-                    if (replyChainEnd < 0) {
-                        replyChainEnd = targetI;
+                    if (taskInsertionPoint < 0) {
+                        taskInsertionPoint = task.mActivities.size();
+
                     }
-                    if (DEBUG_TASKS) Slog.v(TAG, "Reparenting task at index "
-                            + targetI + " to " + replyChainEnd);
-                    for (int srcPos=replyChainEnd; srcPos>=targetI; srcPos--) {
-                        ActivityRecord p = mHistory.get(srcPos);
-                        if (p.finishing) {
-                            continue;
-                        }
-                        if (lastReparentPos < 0) {
-                            lastReparentPos = taskTopI;
-                            taskTop = p;
-                        } else {
-                            lastReparentPos--;
-                        }
-                        if (DEBUG_ADD_REMOVE) {
-                            RuntimeException here = new RuntimeException("here");
-                            here.fillInStackTrace();
-                            Slog.i(TAG, "Removing and adding activity " + p + " to stack at "
-                                    + lastReparentPos, here);
-                        }
-                        mHistory.remove(srcPos);
+
+                    final int start = replyChainEnd >= 0 ? replyChainEnd : i;
+                    if (DEBUG_TASKS) Slog.v(TAG, "Reparenting from task=" + affinityTask + ":"
+                            + start + "-" + i + " to task=" + task + ":" + taskInsertionPoint);
+                    for (int srcPos = start; srcPos >= i; --srcPos) {
+                        final ActivityRecord p = activities.get(srcPos);
                         p.setTask(task, null, false);
-                        mHistory.add(lastReparentPos, p);
-                        if (DEBUG_TASKS) Slog.v(TAG, "Pulling activity " + p
-                                + " from " + srcPos + " to " + lastReparentPos
+                        task.addActivityAtIndex(taskInsertionPoint, p);
+
+                        if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Removing and adding activity " + p
+                                + " to stack at " + task,
+                                new RuntimeException("here").fillInStackTrace());
+                        if (DEBUG_TASKS) Slog.v(TAG, "Pulling activity " + p + " from " + srcPos
                                 + " in to resetting task " + task);
-                        mService.mWindowManager.moveAppToken(lastReparentPos, p.appToken);
-                        mService.mWindowManager.setAppGroupId(p.appToken, p.task.taskId);
-                        if (VALIDATE_TOKENS) {
-                            validateAppTokensLocked();
-                        }
+                        mWindowManager.setAppGroupId(p.appToken, taskId);
                     }
-                    replyChainEnd = -1;
-                    
+                    mWindowManager.moveTaskToTop(taskId);
+                    if (VALIDATE_TOKENS) {
+                        validateAppTokensLocked();
+                    }
+
                     // Now we've moved it in to place...  but what if this is
                     // a singleTop activity and we have put it on top of another
                     // instance of the same activity?  Then we drop the instance
                     // below so it remains singleTop.
                     if (target.info.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
-                        for (int j=lastReparentPos-1; j>=0; j--) {
-                            ActivityRecord p = mHistory.get(j);
-                            if (p.finishing) {
-                                continue;
-                            }
+                        ArrayList<ActivityRecord> taskActivities = task.mActivities;
+                        int targetNdx = taskActivities.indexOf(target);
+                        if (targetNdx > 0) {
+                            ActivityRecord p = taskActivities.get(targetNdx - 1);
                             if (p.intent.getComponent().equals(target.intent.getComponent())) {
-                                if (finishActivityLocked(p, j,
-                                        Activity.RESULT_CANCELED, null, "replace", false)) {
-                                    taskTopI--;
-                                    lastReparentPos--;
-                                }
+                                finishActivityLocked(p, Activity.RESULT_CANCELED, null, "replace",
+                                        false);
                             }
                         }
                     }
                 }
 
-            } else if (below != null && below.task != target.task) {
-                // We hit the botton of a task; the reply chain can't
-                // pass through it.
                 replyChainEnd = -1;
             }
-            
-            target = below;
-            targetI = i;
         }
+        return taskInsertionPoint;
+    }
+
+    final ActivityRecord resetTaskIfNeededLocked(ActivityRecord taskTop,
+            ActivityRecord newActivity) {
+        boolean forceReset =
+                (newActivity.info.flags & ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0;
+        if (ACTIVITY_INACTIVE_RESET_TIME > 0
+                && taskTop.task.getInactiveDuration() > ACTIVITY_INACTIVE_RESET_TIME) {
+            if ((newActivity.info.flags & ActivityInfo.FLAG_ALWAYS_RETAIN_TASK_STATE) == 0) {
+                forceReset = true;
+            }
+        }
+
+        final TaskRecord task = taskTop.task;
+
+        /** False until we evaluate the TaskRecord associated with taskTop. Switches to true
+         * for remaining tasks. Used for later tasks to reparent to task. */
+        boolean taskFound = false;
+
+        /** If ActivityOptions are moved out and need to be aborted or moved to taskTop. */
+        ActivityOptions topOptions = null;
+
+        // Preserve the location for reparenting in the new task.
+        int reparentInsertionPoint = -1;
+
+        for (int i = mTaskHistory.size() - 1; i >= 0; --i) {
+            final TaskRecord targetTask = mTaskHistory.get(i);
+
+            if (targetTask == task) {
+                topOptions = resetTargetTaskIfNeededLocked(task, forceReset);
+                taskFound = true;
+            } else {
+                reparentInsertionPoint = resetAffinityTaskIfNeededLocked(targetTask, task,
+                        taskFound, forceReset, reparentInsertionPoint);
+            }
+        }
+
+        int taskNdx = mTaskHistory.indexOf(task);
+        do {
+            taskTop = mTaskHistory.get(taskNdx--).getTopActivity();
+        } while (taskTop == null && taskNdx >= 0);
 
         if (topOptions != null) {
             // If we got some ActivityOptions from an activity on top that
@@ -2305,1068 +2105,6 @@
 
         return taskTop;
     }
-    
-    /**
-     * Perform clear operation as requested by
-     * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the
-     * stack to the given task, then look for
-     * an instance of that activity in the stack and, if found, finish all
-     * activities on top of it and return the instance.
-     *
-     * @param newR Description of the new activity being started.
-     * @return Returns the old activity that should be continued to be used,
-     * or null if none was found.
-     */
-    private final ActivityRecord performClearTaskLocked(int taskId,
-            ActivityRecord newR, int launchFlags) {
-        int i = mHistory.size();
-        
-        // First find the requested task.
-        while (i > 0) {
-            i--;
-            ActivityRecord r = mHistory.get(i);
-            if (r.task.taskId == taskId) {
-                i++;
-                break;
-            }
-        }
-        
-        // Now clear it.
-        while (i > 0) {
-            i--;
-            ActivityRecord r = mHistory.get(i);
-            if (r.finishing) {
-                continue;
-            }
-            if (r.task.taskId != taskId) {
-                return null;
-            }
-            if (r.realActivity.equals(newR.realActivity)) {
-                // Here it is!  Now finish everything in front...
-                ActivityRecord ret = r;
-                while (i < (mHistory.size()-1)) {
-                    i++;
-                    r = mHistory.get(i);
-                    if (r.task.taskId != taskId) {
-                        break;
-                    }
-                    if (r.finishing) {
-                        continue;
-                    }
-                    ActivityOptions opts = r.takeOptionsLocked();
-                    if (opts != null) {
-                        ret.updateOptionsLocked(opts);
-                    }
-                    if (finishActivityLocked(r, i, Activity.RESULT_CANCELED,
-                            null, "clear", false)) {
-                        i--;
-                    }
-                }
-                
-                // Finally, if this is a normal launch mode (that is, not
-                // expecting onNewIntent()), then we will finish the current
-                // instance of the activity so a new fresh one can be started.
-                if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
-                        && (launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0) {
-                    if (!ret.finishing) {
-                        int index = indexOfTokenLocked(ret.appToken);
-                        if (index >= 0) {
-                            finishActivityLocked(ret, index, Activity.RESULT_CANCELED,
-                                    null, "clear", false);
-                        }
-                        return null;
-                    }
-                }
-                
-                return ret;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Completely remove all activities associated with an existing
-     * task starting at a specified index.
-     */
-    private final void performClearTaskAtIndexLocked(int taskId, int i) {
-        while (i < mHistory.size()) {
-            ActivityRecord r = mHistory.get(i);
-            if (r.task.taskId != taskId) {
-                // Whoops hit the end.
-                return;
-            }
-            if (r.finishing) {
-                i++;
-                continue;
-            }
-            if (!finishActivityLocked(r, i, Activity.RESULT_CANCELED,
-                    null, "clear", false)) {
-                i++;
-            }
-        }
-    }
-
-    /**
-     * Completely remove all activities associated with an existing task.
-     */
-    private final void performClearTaskLocked(int taskId) {
-        int i = mHistory.size();
-
-        // First find the requested task.
-        while (i > 0) {
-            i--;
-            ActivityRecord r = mHistory.get(i);
-            if (r.task.taskId == taskId) {
-                i++;
-                break;
-            }
-        }
-
-        // Now find the start and clear it.
-        while (i > 0) {
-            i--;
-            ActivityRecord r = mHistory.get(i);
-            if (r.finishing) {
-                continue;
-            }
-            if (r.task.taskId != taskId) {
-                // We hit the bottom.  Now finish it all...
-                performClearTaskAtIndexLocked(taskId, i+1);
-                return;
-            }
-        }
-    }
-
-    /**
-     * 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.
-     */
-    private final int findActivityInHistoryLocked(ActivityRecord r, int task) {
-        int i = mHistory.size();
-        while (i > 0) {
-            i--;
-            ActivityRecord candidate = mHistory.get(i);
-            if (candidate.finishing) {
-                continue;
-            }
-            if (candidate.task.taskId != task) {
-                break;
-            }
-            if (candidate.realActivity.equals(r.realActivity)) {
-                return i;
-            }
-        }
-
-        return -1;
-    }
-
-    /**
-     * Reorder the history stack so that the activity at the given index is
-     * brought to the front.
-     */
-    private final ActivityRecord moveActivityToFrontLocked(int where) {
-        ActivityRecord newTop = mHistory.remove(where);
-        int top = mHistory.size();
-        ActivityRecord oldTop = mHistory.get(top-1);
-        if (DEBUG_ADD_REMOVE) {
-            RuntimeException here = new RuntimeException("here");
-            here.fillInStackTrace();
-            Slog.i(TAG, "Removing and adding activity " + newTop + " to stack at "
-                    + top, here);
-        }
-        mHistory.add(top, newTop);
-        oldTop.frontOfTask = false;
-        newTop.frontOfTask = true;
-        return newTop;
-    }
-
-    final int startActivityLocked(IApplicationThread caller,
-            Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
-            String resultWho, int requestCode,
-            int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
-            boolean componentSpecified, ActivityRecord[] outActivity) {
-
-        int err = ActivityManager.START_SUCCESS;
-
-        ProcessRecord callerApp = null;
-
-        if (caller != null) {
-            callerApp = mService.getRecordForAppLocked(caller);
-            if (callerApp != null) {
-                callingPid = callerApp.pid;
-                callingUid = callerApp.info.uid;
-            } else {
-                Slog.w(TAG, "Unable to find app for caller " + caller
-                      + " (pid=" + callingPid + ") when starting: "
-                      + intent.toString());
-                err = ActivityManager.START_PERMISSION_DENIED;
-            }
-        }
-
-        if (err == ActivityManager.START_SUCCESS) {
-            final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
-            Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
-                    + "} from pid " + (callerApp != null ? callerApp.pid : callingPid));
-        }
-
-        ActivityRecord sourceRecord = null;
-        ActivityRecord resultRecord = null;
-        if (resultTo != null) {
-            int index = indexOfTokenLocked(resultTo);
-            if (DEBUG_RESULTS) Slog.v(
-                TAG, "Will send result to " + resultTo + " (index " + index + ")");
-            if (index >= 0) {
-                sourceRecord = mHistory.get(index);
-                if (requestCode >= 0 && !sourceRecord.finishing) {
-                    resultRecord = sourceRecord;
-                }
-            }
-        }
-
-        int launchFlags = intent.getFlags();
-
-        if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
-                && sourceRecord != null) {
-            // Transfer the result target from the source activity to the new
-            // one being started, including any failures.
-            if (requestCode >= 0) {
-                ActivityOptions.abort(options);
-                return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
-            }
-            resultRecord = sourceRecord.resultTo;
-            resultWho = sourceRecord.resultWho;
-            requestCode = sourceRecord.requestCode;
-            sourceRecord.resultTo = null;
-            if (resultRecord != null) {
-                resultRecord.removeResultsLocked(
-                    sourceRecord, resultWho, requestCode);
-            }
-        }
-
-        if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
-            // We couldn't find a class that can handle the given Intent.
-            // That's the end of that!
-            err = ActivityManager.START_INTENT_NOT_RESOLVED;
-        }
-
-        if (err == ActivityManager.START_SUCCESS && aInfo == null) {
-            // We couldn't find the specific class specified in the Intent.
-            // Also the end of the line.
-            err = ActivityManager.START_CLASS_NOT_FOUND;
-        }
-
-        if (err != ActivityManager.START_SUCCESS) {
-            if (resultRecord != null) {
-                sendActivityResultLocked(-1,
-                    resultRecord, resultWho, requestCode,
-                    Activity.RESULT_CANCELED, null);
-            }
-            mDismissKeyguardOnNextActivity = false;
-            ActivityOptions.abort(options);
-            return err;
-        }
-
-        final int startAnyPerm = mService.checkPermission(
-                START_ANY_ACTIVITY, callingPid, callingUid);
-        final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
-                callingUid, aInfo.applicationInfo.uid, aInfo.exported);
-        if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
-            if (resultRecord != null) {
-                sendActivityResultLocked(-1,
-                    resultRecord, resultWho, requestCode,
-                    Activity.RESULT_CANCELED, null);
-            }
-            mDismissKeyguardOnNextActivity = false;
-            String msg;
-            if (!aInfo.exported) {
-                msg = "Permission Denial: starting " + intent.toString()
-                        + " from " + callerApp + " (pid=" + callingPid
-                        + ", uid=" + callingUid + ")"
-                        + " not exported from uid " + aInfo.applicationInfo.uid;
-            } else {
-                msg = "Permission Denial: starting " + intent.toString()
-                        + " from " + callerApp + " (pid=" + callingPid
-                        + ", uid=" + callingUid + ")"
-                        + " requires " + aInfo.permission;
-            }
-            Slog.w(TAG, msg);
-            throw new SecurityException(msg);
-        }
-
-        boolean abort = !mService.mIntentFirewall.checkStartActivity(intent,
-                callerApp==null?null:callerApp.info, callingUid, callingPid, resolvedType, aInfo);
-
-        if (mMainStack) {
-            if (mService.mController != null) {
-                try {
-                    // The Intent we give to the watcher has the extra data
-                    // stripped off, since it can contain private information.
-                    Intent watchIntent = intent.cloneFilter();
-                    abort |= !mService.mController.activityStarting(watchIntent,
-                            aInfo.applicationInfo.packageName);
-                } catch (RemoteException e) {
-                    mService.mController = null;
-                }
-            }
-        }
-
-        if (abort) {
-            if (resultRecord != null) {
-                sendActivityResultLocked(-1,
-                    resultRecord, resultWho, requestCode,
-                    Activity.RESULT_CANCELED, null);
-            }
-            // We pretend to the caller that it was really started, but
-            // they will just get a cancel result.
-            mDismissKeyguardOnNextActivity = false;
-            ActivityOptions.abort(options);
-            return ActivityManager.START_SUCCESS;
-        }
-
-        ActivityRecord r = new ActivityRecord(mService, this, callerApp, callingUid, callingPackage,
-                intent, resolvedType, aInfo, mService.mConfiguration,
-                resultRecord, resultWho, requestCode, componentSpecified);
-        if (outActivity != null) {
-            outActivity[0] = r;
-        }
-
-        if (mMainStack) {
-            if (mResumedActivity == null
-                    || mResumedActivity.info.applicationInfo.uid != callingUid) {
-                if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
-                    PendingActivityLaunch pal = new PendingActivityLaunch();
-                    pal.r = r;
-                    pal.sourceRecord = sourceRecord;
-                    pal.startFlags = startFlags;
-                    mService.mPendingActivityLaunches.add(pal);
-                    mDismissKeyguardOnNextActivity = false;
-                    ActivityOptions.abort(options);
-                    return ActivityManager.START_SWITCHES_CANCELED;
-                }
-            }
-        
-            if (mService.mDidAppSwitch) {
-                // This is the second allowed switch since we stopped switches,
-                // so now just generally allow switches.  Use case: user presses
-                // home (switches disabled, switch to home, mDidAppSwitch now true);
-                // user taps a home icon (coming from home so allowed, we hit here
-                // and now allow anyone to switch again).
-                mService.mAppSwitchesAllowedTime = 0;
-            } else {
-                mService.mDidAppSwitch = true;
-            }
-         
-            mService.doPendingActivityLaunchesLocked(false);
-        }
-        
-        err = startActivityUncheckedLocked(r, sourceRecord,
-                startFlags, true, options);
-        if (mDismissKeyguardOnNextActivity && mPausingActivity == null) {
-            // Someone asked to have the keyguard dismissed on the next
-            // activity start, but we are not actually doing an activity
-            // switch...  just dismiss the keyguard now, because we
-            // probably want to see whatever is behind it.
-            mDismissKeyguardOnNextActivity = false;
-            mService.mWindowManager.dismissKeyguard();
-        }
-        return err;
-    }
-  
-    final void moveHomeToFrontFromLaunchLocked(int launchFlags) {
-        if ((launchFlags &
-                (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
-                == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
-            // Caller wants to appear on home activity, so before starting
-            // their own activity we will bring home to the front.
-            moveHomeToFrontLocked();
-        }
-    }
-
-    final int startActivityUncheckedLocked(ActivityRecord r,
-            ActivityRecord sourceRecord, int startFlags, boolean doResume,
-            Bundle options) {
-        final Intent intent = r.intent;
-        final int callingUid = r.launchedFromUid;
-
-        int launchFlags = intent.getFlags();
-        
-        // We'll invoke onUserLeaving before onPause only if the launching
-        // activity did not explicitly state that this is an automated launch.
-        mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
-        if (DEBUG_USER_LEAVING) Slog.v(TAG,
-                "startActivity() => mUserLeaving=" + mUserLeaving);
-        
-        // If the caller has asked not to resume at this point, we make note
-        // of this in the record so that we can skip it when trying to find
-        // the top running activity.
-        if (!doResume) {
-            r.delayedResume = true;
-        }
-        
-        ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)
-                != 0 ? r : null;
-
-        // If the onlyIfNeeded flag is set, then we can do this if the activity
-        // being launched is the same as the one making the call...  or, as
-        // a special case, if we do not know the caller then we count the
-        // current top activity as the caller.
-        if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
-            ActivityRecord checkedCaller = sourceRecord;
-            if (checkedCaller == null) {
-                checkedCaller = topRunningNonDelayedActivityLocked(notTop);
-            }
-            if (!checkedCaller.realActivity.equals(r.realActivity)) {
-                // Caller is not the same as launcher, so always needed.
-                startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
-            }
-        }
-
-        if (sourceRecord == null) {
-            // This activity is not being started from another...  in this
-            // case we -always- start a new task.
-            if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
-                Slog.w(TAG, "startActivity called from non-Activity context; forcing Intent.FLAG_ACTIVITY_NEW_TASK for: "
-                      + intent);
-                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
-            }
-        } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
-            // The original activity who is starting us is running as a single
-            // instance...  this new activity it is starting must go on its
-            // own task.
-            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
-        } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
-                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
-            // The activity being started is a single instance...  it always
-            // gets launched into its own task.
-            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
-        }
-
-        if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
-            // For whatever reason this activity is being launched into a new
-            // task...  yet the caller has requested a result back.  Well, that
-            // is pretty messed up, so instead immediately send back a cancel
-            // and let the new task continue launched as normal without a
-            // dependency on its originator.
-            Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
-            sendActivityResultLocked(-1,
-                    r.resultTo, r.resultWho, r.requestCode,
-                Activity.RESULT_CANCELED, null);
-            r.resultTo = null;
-        }
-
-        boolean addingToTask = false;
-        boolean movedHome = false;
-        TaskRecord reuseTask = null;
-        if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
-                (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
-                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
-                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
-            // If bring to front is requested, and no result is requested, and
-            // we can find a task that was started with this same
-            // component, then instead of launching bring that one to the front.
-            if (r.resultTo == null) {
-                // See if there is a task to bring to the front.  If this is
-                // a SINGLE_INSTANCE activity, there can be one and only one
-                // instance of it in the history, and it is always in its own
-                // unique task, so we do a special search.
-                ActivityRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
-                        ? findTaskLocked(intent, r.info)
-                        : findActivityLocked(intent, r.info);
-                if (taskTop != null) {
-                    if (taskTop.task.intent == null) {
-                        // This task was started because of movement of
-                        // the activity based on affinity...  now that we
-                        // are actually launching it, we can assign the
-                        // base intent.
-                        taskTop.task.setIntent(intent, r.info);
-                    }
-                    // If the target task is not in the front, then we need
-                    // to bring it to the front...  except...  well, with
-                    // SINGLE_TASK_LAUNCH it's not entirely clear.  We'd like
-                    // to have the same behavior as if a new instance was
-                    // being started, which means not bringing it to the front
-                    // if the caller is not itself in the front.
-                    ActivityRecord curTop = topRunningNonDelayedActivityLocked(notTop);
-                    if (curTop != null && curTop.task != taskTop.task) {
-                        r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
-                        boolean callerAtFront = sourceRecord == null
-                                || curTop.task == sourceRecord.task;
-                        if (callerAtFront) {
-                            // We really do want to push this one into the
-                            // user's face, right now.
-                            movedHome = true;
-                            moveHomeToFrontFromLaunchLocked(launchFlags);
-                            moveTaskToFrontLocked(taskTop.task, r, options);
-                            options = null;
-                        }
-                    }
-                    // If the caller has requested that the target task be
-                    // reset, then do so.
-                    if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
-                        taskTop = resetTaskIfNeededLocked(taskTop, r);
-                    }
-                    if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED)  != 0) {
-                        // We don't need to start a new activity, and
-                        // the client said not to do anything if that
-                        // is the case, so this is it!  And for paranoia, make
-                        // sure we have correctly resumed the top activity.
-                        if (doResume) {
-                            resumeTopActivityLocked(null, options);
-                        } else {
-                            ActivityOptions.abort(options);
-                        }
-                        return ActivityManager.START_RETURN_INTENT_TO_CALLER;
-                    }
-                    if ((launchFlags &
-                            (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
-                            == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
-                        // The caller has requested to completely replace any
-                        // existing task with its new activity.  Well that should
-                        // not be too hard...
-                        reuseTask = taskTop.task;
-                        performClearTaskLocked(taskTop.task.taskId);
-                        reuseTask.setIntent(r.intent, r.info);
-                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
-                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
-                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
-                        // In this situation we want to remove all activities
-                        // from the task up to the one being started.  In most
-                        // cases this means we are resetting the task to its
-                        // initial state.
-                        ActivityRecord top = performClearTaskLocked(
-                                taskTop.task.taskId, r, launchFlags);
-                        if (top != null) {
-                            if (top.frontOfTask) {
-                                // Activity aliases may mean we use different
-                                // intents for the top activity, so make sure
-                                // the task now has the identity of the new
-                                // intent.
-                                top.task.setIntent(r.intent, r.info);
-                            }
-                            logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
-                            top.deliverNewIntentLocked(callingUid, r.intent);
-                        } else {
-                            // A special case: we need to
-                            // start the activity because it is not currently
-                            // running, and the caller has asked to clear the
-                            // current task to have this activity at the top.
-                            addingToTask = true;
-                            // Now pretend like this activity is being started
-                            // by the top of its task, so it is put in the
-                            // right place.
-                            sourceRecord = taskTop;
-                        }
-                    } else if (r.realActivity.equals(taskTop.task.realActivity)) {
-                        // In this case the top activity on the task is the
-                        // same as the one being launched, so we take that
-                        // as a request to bring the task to the foreground.
-                        // If the top activity in the task is the root
-                        // activity, deliver this new intent to it if it
-                        // desires.
-                        if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
-                                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
-                                && taskTop.realActivity.equals(r.realActivity)) {
-                            logStartActivity(EventLogTags.AM_NEW_INTENT, r, taskTop.task);
-                            if (taskTop.frontOfTask) {
-                                taskTop.task.setIntent(r.intent, r.info);
-                            }
-                            taskTop.deliverNewIntentLocked(callingUid, r.intent);
-                        } else if (!r.intent.filterEquals(taskTop.task.intent)) {
-                            // In this case we are launching the root activity
-                            // of the task, but with a different intent.  We
-                            // should start a new instance on top.
-                            addingToTask = true;
-                            sourceRecord = taskTop;
-                        }
-                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
-                        // In this case an activity is being launched in to an
-                        // existing task, without resetting that task.  This
-                        // is typically the situation of launching an activity
-                        // from a notification or shortcut.  We want to place
-                        // the new activity on top of the current task.
-                        addingToTask = true;
-                        sourceRecord = taskTop;
-                    } else if (!taskTop.task.rootWasReset) {
-                        // In this case we are launching in to an existing task
-                        // that has not yet been started from its front door.
-                        // The current task has been brought to the front.
-                        // Ideally, we'd probably like to place this new task
-                        // at the bottom of its stack, but that's a little hard
-                        // to do with the current organization of the code so
-                        // for now we'll just drop it.
-                        taskTop.task.setIntent(r.intent, r.info);
-                    }
-                    if (!addingToTask && reuseTask == null) {
-                        // We didn't do anything...  but it was needed (a.k.a., client
-                        // don't use that intent!)  And for paranoia, make
-                        // sure we have correctly resumed the top activity.
-                        if (doResume) {
-                            resumeTopActivityLocked(null, options);
-                        } else {
-                            ActivityOptions.abort(options);
-                        }
-                        return ActivityManager.START_TASK_TO_FRONT;
-                    }
-                }
-            }
-        }
-
-        //String uri = r.intent.toURI();
-        //Intent intent2 = new Intent(uri);
-        //Slog.i(TAG, "Given intent: " + r.intent);
-        //Slog.i(TAG, "URI is: " + uri);
-        //Slog.i(TAG, "To intent: " + intent2);
-
-        if (r.packageName != null) {
-            // If the activity being launched is the same as the one currently
-            // at the top, then we need to check if it should only be launched
-            // once.
-            ActivityRecord top = topRunningNonDelayedActivityLocked(notTop);
-            if (top != null && r.resultTo == null) {
-                if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
-                    if (top.app != null && top.app.thread != null) {
-                        if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
-                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
-                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
-                            logStartActivity(EventLogTags.AM_NEW_INTENT, top, top.task);
-                            // For paranoia, make sure we have correctly
-                            // resumed the top activity.
-                            if (doResume) {
-                                resumeTopActivityLocked(null);
-                            }
-                            ActivityOptions.abort(options);
-                            if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
-                                // We don't need to start a new activity, and
-                                // the client said not to do anything if that
-                                // is the case, so this is it!
-                                return ActivityManager.START_RETURN_INTENT_TO_CALLER;
-                            }
-                            top.deliverNewIntentLocked(callingUid, r.intent);
-                            return ActivityManager.START_DELIVERED_TO_TOP;
-                        }
-                    }
-                }
-            }
-
-        } else {
-            if (r.resultTo != null) {
-                sendActivityResultLocked(-1,
-                        r.resultTo, r.resultWho, r.requestCode,
-                    Activity.RESULT_CANCELED, null);
-            }
-            ActivityOptions.abort(options);
-            return ActivityManager.START_CLASS_NOT_FOUND;
-        }
-
-        boolean newTask = false;
-        boolean keepCurTransition = false;
-
-        // Should this be considered a new task?
-        if (r.resultTo == null && !addingToTask
-                && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
-            if (reuseTask == null) {
-                // todo: should do better management of integers.
-                mService.mCurTask++;
-                if (mService.mCurTask <= 0) {
-                    mService.mCurTask = 1;
-                }
-                r.setTask(new TaskRecord(mService.mCurTask, r.info, intent), null, true);
-                if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
-                        + " in new task " + r.task);
-            } else {
-                r.setTask(reuseTask, reuseTask, true);
-            }
-            newTask = true;
-            if (!movedHome) {
-                moveHomeToFrontFromLaunchLocked(launchFlags);
-            }
-            
-        } else if (sourceRecord != null) {
-            if (!addingToTask &&
-                    (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
-                // In this case, we are adding the activity to an existing
-                // task, but the caller has asked to clear that task if the
-                // activity is already running.
-                ActivityRecord top = performClearTaskLocked(
-                        sourceRecord.task.taskId, r, launchFlags);
-                keepCurTransition = true;
-                if (top != null) {
-                    logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
-                    top.deliverNewIntentLocked(callingUid, r.intent);
-                    // For paranoia, make sure we have correctly
-                    // resumed the top activity.
-                    if (doResume) {
-                        resumeTopActivityLocked(null);
-                    }
-                    ActivityOptions.abort(options);
-                    return ActivityManager.START_DELIVERED_TO_TOP;
-                }
-            } else if (!addingToTask &&
-                    (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
-                // In this case, we are launching an activity in our own task
-                // that may already be running somewhere in the history, and
-                // we want to shuffle it to the front of the stack if so.
-                int where = findActivityInHistoryLocked(r, sourceRecord.task.taskId);
-                if (where >= 0) {
-                    ActivityRecord top = moveActivityToFrontLocked(where);
-                    logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
-                    top.updateOptionsLocked(options);
-                    top.deliverNewIntentLocked(callingUid, r.intent);
-                    if (doResume) {
-                        resumeTopActivityLocked(null);
-                    }
-                    return ActivityManager.START_DELIVERED_TO_TOP;
-                }
-            }
-            // An existing activity is starting this new activity, so we want
-            // to keep the new one in the same task as the one that is starting
-            // it.
-            r.setTask(sourceRecord.task, sourceRecord.thumbHolder, false);
-            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
-                    + " in existing task " + r.task);
-
-        } else {
-            // This not being started from an existing activity, and not part
-            // of a new task...  just put it in the top task, though these days
-            // this case should never happen.
-            final int N = mHistory.size();
-            ActivityRecord prev =
-                N > 0 ? mHistory.get(N-1) : null;
-            r.setTask(prev != null
-                    ? prev.task
-                    : new TaskRecord(mService.mCurTask, r.info, intent), null, true);
-            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
-                    + " in new guessed " + r.task);
-        }
-
-        mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
-                intent, r.getUriPermissionsLocked());
-
-        if (newTask) {
-            EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
-        }
-        logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
-        startActivityLocked(r, newTask, doResume, keepCurTransition, options);
-        return ActivityManager.START_SUCCESS;
-    }
-
-    ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
-            String profileFile, ParcelFileDescriptor profileFd, int userId) {
-        // Collect information about the target of the Intent.
-        ActivityInfo aInfo;
-        try {
-            ResolveInfo rInfo =
-                AppGlobals.getPackageManager().resolveIntent(
-                        intent, resolvedType,
-                        PackageManager.MATCH_DEFAULT_ONLY
-                                    | ActivityManagerService.STOCK_PM_FLAGS, userId);
-            aInfo = rInfo != null ? rInfo.activityInfo : null;
-        } catch (RemoteException e) {
-            aInfo = null;
-        }
-
-        if (aInfo != null) {
-            // Store the found target back into the intent, because now that
-            // we have it we never want to do this again.  For example, if the
-            // user navigates back to this point in the history, we should
-            // always restart the exact same activity.
-            intent.setComponent(new ComponentName(
-                    aInfo.applicationInfo.packageName, aInfo.name));
-
-            // Don't debug things in the system process
-            if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {
-                if (!aInfo.processName.equals("system")) {
-                    mService.setDebugApp(aInfo.processName, true, false);
-                }
-            }
-
-            if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {
-                if (!aInfo.processName.equals("system")) {
-                    mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);
-                }
-            }
-
-            if (profileFile != null) {
-                if (!aInfo.processName.equals("system")) {
-                    mService.setProfileApp(aInfo.applicationInfo, aInfo.processName,
-                            profileFile, profileFd,
-                            (startFlags&ActivityManager.START_FLAG_AUTO_STOP_PROFILER) != 0);
-                }
-            }
-        }
-        return aInfo;
-    }
-
-    final int startActivityMayWait(IApplicationThread caller, int callingUid,
-            String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
-            String resultWho, int requestCode, int startFlags, String profileFile,
-            ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
-            Bundle options, int userId) {
-        // Refuse possible leaked file descriptors
-        if (intent != null && intent.hasFileDescriptors()) {
-            throw new IllegalArgumentException("File descriptors passed in Intent");
-        }
-        boolean componentSpecified = intent.getComponent() != null;
-
-        // Don't modify the client's object!
-        intent = new Intent(intent);
-
-        // Collect information about the target of the Intent.
-        ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
-                profileFile, profileFd, userId);
-
-        synchronized (mService) {
-            int callingPid;
-            if (callingUid >= 0) {
-                callingPid = -1;
-            } else if (caller == null) {
-                callingPid = Binder.getCallingPid();
-                callingUid = Binder.getCallingUid();
-            } else {
-                callingPid = callingUid = -1;
-            }
-            
-            mConfigWillChange = config != null
-                    && mService.mConfiguration.diff(config) != 0;
-            if (DEBUG_CONFIGURATION) Slog.v(TAG,
-                    "Starting activity when config will change = " + mConfigWillChange);
-            
-            final long origId = Binder.clearCallingIdentity();
-            
-            if (mMainStack && aInfo != null &&
-                    (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
-                // This may be a heavy-weight process!  Check to see if we already
-                // have another, different heavy-weight process running.
-                if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
-                    if (mService.mHeavyWeightProcess != null &&
-                            (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
-                            !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
-                        int realCallingPid = callingPid;
-                        int realCallingUid = callingUid;
-                        if (caller != null) {
-                            ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
-                            if (callerApp != null) {
-                                realCallingPid = callerApp.pid;
-                                realCallingUid = callerApp.info.uid;
-                            } else {
-                                Slog.w(TAG, "Unable to find app for caller " + caller
-                                      + " (pid=" + realCallingPid + ") when starting: "
-                                      + intent.toString());
-                                ActivityOptions.abort(options);
-                                return ActivityManager.START_PERMISSION_DENIED;
-                            }
-                        }
-                        
-                        IIntentSender target = mService.getIntentSenderLocked(
-                                ActivityManager.INTENT_SENDER_ACTIVITY, "android",
-                                realCallingUid, userId, null, null, 0, new Intent[] { intent },
-                                new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
-                                | PendingIntent.FLAG_ONE_SHOT, null);
-                        
-                        Intent newIntent = new Intent();
-                        if (requestCode >= 0) {
-                            // Caller is requesting a result.
-                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
-                        }
-                        newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
-                                new IntentSender(target));
-                        if (mService.mHeavyWeightProcess.activities.size() > 0) {
-                            ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0);
-                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
-                                    hist.packageName);
-                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
-                                    hist.task.taskId);
-                        }
-                        newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
-                                aInfo.packageName);
-                        newIntent.setFlags(intent.getFlags());
-                        newIntent.setClassName("android",
-                                HeavyWeightSwitcherActivity.class.getName());
-                        intent = newIntent;
-                        resolvedType = null;
-                        caller = null;
-                        callingUid = Binder.getCallingUid();
-                        callingPid = Binder.getCallingPid();
-                        componentSpecified = true;
-                        try {
-                            ResolveInfo rInfo =
-                                AppGlobals.getPackageManager().resolveIntent(
-                                        intent, null,
-                                        PackageManager.MATCH_DEFAULT_ONLY
-                                        | ActivityManagerService.STOCK_PM_FLAGS, userId);
-                            aInfo = rInfo != null ? rInfo.activityInfo : null;
-                            aInfo = mService.getActivityInfoForUser(aInfo, userId);
-                        } catch (RemoteException e) {
-                            aInfo = null;
-                        }
-                    }
-                }
-            }
-            
-            int res = startActivityLocked(caller, intent, resolvedType,
-                    aInfo, resultTo, resultWho, requestCode, callingPid, callingUid,
-                    callingPackage, startFlags, options, componentSpecified, null);
-            
-            if (mConfigWillChange && mMainStack) {
-                // If the caller also wants to switch to a new configuration,
-                // do so now.  This allows a clean switch, as we are waiting
-                // for the current activity to pause (so we will not destroy
-                // it), and have not yet started the next activity.
-                mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
-                        "updateConfiguration()");
-                mConfigWillChange = false;
-                if (DEBUG_CONFIGURATION) Slog.v(TAG,
-                        "Updating to new configuration after starting activity.");
-                mService.updateConfigurationLocked(config, null, false, false);
-            }
-            
-            Binder.restoreCallingIdentity(origId);
-            
-            if (outResult != null) {
-                outResult.result = res;
-                if (res == ActivityManager.START_SUCCESS) {
-                    mWaitingActivityLaunched.add(outResult);
-                    do {
-                        try {
-                            mService.wait();
-                        } catch (InterruptedException e) {
-                        }
-                    } while (!outResult.timeout && outResult.who == null);
-                } else if (res == ActivityManager.START_TASK_TO_FRONT) {
-                    ActivityRecord r = this.topRunningActivityLocked(null);
-                    if (r.nowVisible) {
-                        outResult.timeout = false;
-                        outResult.who = new ComponentName(r.info.packageName, r.info.name);
-                        outResult.totalTime = 0;
-                        outResult.thisTime = 0;
-                    } else {
-                        outResult.thisTime = SystemClock.uptimeMillis();
-                        mWaitingActivityVisible.add(outResult);
-                        do {
-                            try {
-                                mService.wait();
-                            } catch (InterruptedException e) {
-                            }
-                        } while (!outResult.timeout && outResult.who == null);
-                    }
-                }
-            }
-            
-            return res;
-        }
-    }
-    
-    final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
-            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
-            Bundle options, int userId) {
-        if (intents == null) {
-            throw new NullPointerException("intents is null");
-        }
-        if (resolvedTypes == null) {
-            throw new NullPointerException("resolvedTypes is null");
-        }
-        if (intents.length != resolvedTypes.length) {
-            throw new IllegalArgumentException("intents are length different than resolvedTypes");
-        }
-
-        ActivityRecord[] outActivity = new ActivityRecord[1];
-
-        int callingPid;
-        if (callingUid >= 0) {
-            callingPid = -1;
-        } else if (caller == null) {
-            callingPid = Binder.getCallingPid();
-            callingUid = Binder.getCallingUid();
-        } else {
-            callingPid = callingUid = -1;
-        }
-        final long origId = Binder.clearCallingIdentity();
-        try {
-            synchronized (mService) {
-
-                for (int i=0; i<intents.length; i++) {
-                    Intent intent = intents[i];
-                    if (intent == null) {
-                        continue;
-                    }
-
-                    // Refuse possible leaked file descriptors
-                    if (intent != null && intent.hasFileDescriptors()) {
-                        throw new IllegalArgumentException("File descriptors passed in Intent");
-                    }
-
-                    boolean componentSpecified = intent.getComponent() != null;
-
-                    // Don't modify the client's object!
-                    intent = new Intent(intent);
-
-                    // Collect information about the target of the Intent.
-                    ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i],
-                            0, null, null, userId);
-                    // TODO: New, check if this is correct
-                    aInfo = mService.getActivityInfoForUser(aInfo, userId);
-
-                    if (mMainStack && aInfo != null && (aInfo.applicationInfo.flags
-                            & ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
-                        throw new IllegalArgumentException(
-                                "FLAG_CANT_SAVE_STATE not supported here");
-                    }
-
-                    Bundle theseOptions;
-                    if (options != null && i == intents.length-1) {
-                        theseOptions = options;
-                    } else {
-                        theseOptions = null;
-                    }
-                    int res = startActivityLocked(caller, intent, resolvedTypes[i],
-                            aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage,
-                            0, theseOptions, componentSpecified, outActivity);
-                    if (res < 0) {
-                        return res;
-                    }
-
-                    resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
-                }
-            }
-        } finally {
-            Binder.restoreCallingIdentity(origId);
-        }
-
-        return ActivityManager.START_SUCCESS;
-    }
-
-    void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
-            long thisTime, long totalTime) {
-        for (int i=mWaitingActivityLaunched.size()-1; i>=0; i--) {
-            WaitResult w = mWaitingActivityLaunched.get(i);
-            w.timeout = timeout;
-            if (r != null) {
-                w.who = new ComponentName(r.info.packageName, r.info.name);
-            }
-            w.thisTime = thisTime;
-            w.totalTime = totalTime;
-        }
-        mService.notifyAll();
-    }
-    
-    void reportActivityVisibleLocked(ActivityRecord r) {
-        for (int i=mWaitingActivityVisible.size()-1; i>=0; i--) {
-            WaitResult w = mWaitingActivityVisible.get(i);
-            w.timeout = false;
-            if (r != null) {
-                w.who = new ComponentName(r.info.packageName, r.info.name);
-            }
-            w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
-            w.thisTime = w.totalTime;
-        }
-        mService.notifyAll();
-
-        if (mDismissKeyguardOnNextActivity) {
-            mDismissKeyguardOnNextActivity = false;
-            mService.mWindowManager.dismissKeyguard();
-        }
-    }
 
     void sendActivityResultLocked(int callingUid, ActivityRecord r,
             String resultWho, int requestCode, int resultCode, Intent data) {
@@ -3394,7 +2132,7 @@
         r.addResultLocked(null, resultWho, requestCode, resultCode, data);
     }
 
-    private final void stopActivityLocked(ActivityRecord r) {
+    final void stopActivityLocked(ActivityRecord r) {
         if (DEBUG_SWITCH) Slog.d(TAG, "Stopping: " + r);
         if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
                 || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {
@@ -3413,7 +2151,7 @@
         }
 
         if (r.app != null && r.app.thread != null) {
-            if (mMainStack) {
+            if (mStackSupervisor.isFrontStack(this)) {
                 if (mService.mFocusedActivity == r) {
                     mService.setFocusedActivityLocked(topRunningActivityLocked(null));
                 }
@@ -3427,14 +2165,13 @@
                 if (DEBUG_VISBILITY) Slog.v(
                         TAG, "Stopping visible=" + r.visible + " for " + r);
                 if (!r.visible) {
-                    mService.mWindowManager.setAppVisibility(r.appToken, false);
+                    mWindowManager.setAppVisibility(r.appToken, false);
                 }
                 r.app.thread.scheduleStopActivity(r.appToken, r.visible, r.configChangeFlags);
-                if (mService.isSleeping()) {
+                if (mService.isSleepingOrShuttingDown()) {
                     r.setSleeping(true);
                 }
-                Message msg = mHandler.obtainMessage(STOP_TIMEOUT_MSG);
-                msg.obj = r;
+                Message msg = mHandler.obtainMessage(STOP_TIMEOUT_MSG, r);
                 mHandler.sendMessageDelayed(msg, STOP_TIMEOUT);
             } catch (Exception e) {
                 // Maybe just ignore exceptions here...  if the process
@@ -3451,217 +2188,6 @@
             }
         }
     }
-    
-    final ArrayList<ActivityRecord> processStoppingActivitiesLocked(
-            boolean remove) {
-        int N = mStoppingActivities.size();
-        if (N <= 0) return null;
-
-        ArrayList<ActivityRecord> stops = null;
-
-        final boolean nowVisible = mResumedActivity != null
-                && mResumedActivity.nowVisible
-                && !mResumedActivity.waitingVisible;
-        for (int i=0; i<N; i++) {
-            ActivityRecord s = mStoppingActivities.get(i);
-            if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
-                    + nowVisible + " waitingVisible=" + s.waitingVisible
-                    + " finishing=" + s.finishing);
-            if (s.waitingVisible && nowVisible) {
-                mWaitingVisibleActivities.remove(s);
-                s.waitingVisible = false;
-                if (s.finishing) {
-                    // If this activity is finishing, it is sitting on top of
-                    // everyone else but we now know it is no longer needed...
-                    // so get rid of it.  Otherwise, we need to go through the
-                    // normal flow and hide it once we determine that it is
-                    // hidden by the activities in front of it.
-                    if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
-                    mService.mWindowManager.setAppVisibility(s.appToken, false);
-                }
-            }
-            if ((!s.waitingVisible || mService.isSleeping()) && remove) {
-                if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
-                if (stops == null) {
-                    stops = new ArrayList<ActivityRecord>();
-                }
-                stops.add(s);
-                mStoppingActivities.remove(i);
-                N--;
-                i--;
-            }
-        }
-
-        return stops;
-    }
-
-    final void scheduleIdleLocked() {
-        Message msg = Message.obtain();
-        msg.what = IDLE_NOW_MSG;
-        mHandler.sendMessage(msg);
-    }
-
-    final ActivityRecord activityIdleInternal(IBinder token, boolean fromTimeout,
-            Configuration config) {
-        if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
-
-        ActivityRecord res = null;
-
-        ArrayList<ActivityRecord> stops = null;
-        ArrayList<ActivityRecord> finishes = null;
-        ArrayList<ActivityRecord> thumbnails = null;
-        ArrayList<UserStartedState> startingUsers = null;
-        int NS = 0;
-        int NF = 0;
-        int NT = 0;
-        IApplicationThread sendThumbnail = null;
-        boolean booting = false;
-        boolean enableScreen = false;
-        boolean activityRemoved = false;
-
-        synchronized (mService) {
-            ActivityRecord r = ActivityRecord.forToken(token);
-            if (r != null) {
-                mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
-                r.finishLaunchTickingLocked();
-            }
-
-            // Get the activity record.
-            int index = indexOfActivityLocked(r);
-            if (index >= 0) {
-                res = r;
-
-                if (fromTimeout) {
-                    reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
-                }
-                
-                // This is a hack to semi-deal with a race condition
-                // in the client where it can be constructed with a
-                // newer configuration from when we asked it to launch.
-                // We'll update with whatever configuration it now says
-                // it used to launch.
-                if (config != null) {
-                    r.configuration = config;
-                }
-                
-                // No longer need to keep the device awake.
-                if (mResumedActivity == r && mLaunchingActivity.isHeld()) {
-                    mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
-                    mLaunchingActivity.release();
-                }
-
-                // We are now idle.  If someone is waiting for a thumbnail from
-                // us, we can now deliver.
-                r.idle = true;
-                mService.scheduleAppGcsLocked();
-                if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
-                    sendThumbnail = r.app.thread;
-                    r.thumbnailNeeded = false;
-                }
-
-                // If this activity is fullscreen, set up to hide those under it.
-
-                if (DEBUG_VISBILITY) Slog.v(TAG, "Idle activity for " + r);
-                ensureActivitiesVisibleLocked(null, 0);
-
-                //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
-                if (mMainStack) {
-                    if (!mService.mBooted) {
-                        mService.mBooted = true;
-                        enableScreen = true;
-                    }
-                }
-                
-            } else if (fromTimeout) {
-                reportActivityLaunchedLocked(fromTimeout, null, -1, -1);
-            }
-
-            // Atomically retrieve all of the other things to do.
-            stops = processStoppingActivitiesLocked(true);
-            NS = stops != null ? stops.size() : 0;
-            if ((NF=mFinishingActivities.size()) > 0) {
-                finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
-                mFinishingActivities.clear();
-            }
-            if ((NT=mService.mCancelledThumbnails.size()) > 0) {
-                thumbnails = new ArrayList<ActivityRecord>(mService.mCancelledThumbnails);
-                mService.mCancelledThumbnails.clear();
-            }
-
-            if (mMainStack) {
-                booting = mService.mBooting;
-                mService.mBooting = false;
-            }
-            if (mStartingUsers.size() > 0) {
-                startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
-                mStartingUsers.clear();
-            }
-        }
-
-        int i;
-
-        // Send thumbnail if requested.
-        if (sendThumbnail != null) {
-            try {
-                sendThumbnail.requestThumbnail(token);
-            } catch (Exception e) {
-                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
-                mService.sendPendingThumbnail(null, token, null, null, true);
-            }
-        }
-
-        // Stop any activities that are scheduled to do so but have been
-        // waiting for the next one to start.
-        for (i=0; i<NS; i++) {
-            ActivityRecord r = (ActivityRecord)stops.get(i);
-            synchronized (mService) {
-                if (r.finishing) {
-                    finishCurrentActivityLocked(r, FINISH_IMMEDIATELY, false);
-                } else {
-                    stopActivityLocked(r);
-                }
-            }
-        }
-
-        // Finish any activities that are scheduled to do so but have been
-        // waiting for the next one to start.
-        for (i=0; i<NF; i++) {
-            ActivityRecord r = (ActivityRecord)finishes.get(i);
-            synchronized (mService) {
-                activityRemoved = destroyActivityLocked(r, true, false, "finish-idle");
-            }
-        }
-
-        // Report back to any thumbnail receivers.
-        for (i=0; i<NT; i++) {
-            ActivityRecord r = (ActivityRecord)thumbnails.get(i);
-            mService.sendPendingThumbnail(r, null, null, null, true);
-        }
-
-        if (booting) {
-            mService.finishBooting();
-        } else if (startingUsers != null) {
-            for (i=0; i<startingUsers.size(); i++) {
-                mService.finishUserSwitch(startingUsers.get(i));
-            }
-        }
-
-        mService.trimApplications();
-        //dump();
-        //mWindowManager.dump();
-
-        if (enableScreen) {
-            mService.enableScreenAfterBoot();
-        }
-
-        if (activityRemoved) {
-            synchronized (mService) {
-                resumeTopActivityLocked(null);
-            }
-        }
-
-        return res;
-    }
 
     /**
      * @return Returns true if the activity is being finished, false if for
@@ -3669,63 +2195,82 @@
      */
     final boolean requestFinishActivityLocked(IBinder token, int resultCode,
             Intent resultData, String reason, boolean oomAdj) {
-        int index = indexOfTokenLocked(token);
+        ActivityRecord r = isInStackLocked(token);
         if (DEBUG_RESULTS || DEBUG_STATES) Slog.v(
-                TAG, "Finishing activity @" + index + ": token=" + token
+                TAG, "Finishing activity token=" + token + " r="
                 + ", result=" + resultCode + ", data=" + resultData
                 + ", reason=" + reason);
-        if (index < 0) {
+        if (r == null) {
             return false;
         }
-        ActivityRecord r = mHistory.get(index);
 
-        finishActivityLocked(r, index, resultCode, resultData, reason, oomAdj);
+        finishActivityLocked(r, resultCode, resultData, reason, oomAdj);
         return true;
     }
 
-    final void finishSubActivityLocked(IBinder token, String resultWho, int requestCode) {
-        ActivityRecord self = isInStackLocked(token);
-        if (self == null) {
-            return;
-        }
-
-        int i;
-        for (i=mHistory.size()-1; i>=0; i--) {
-            ActivityRecord r = (ActivityRecord)mHistory.get(i);
-            if (r.resultTo == self && r.requestCode == requestCode) {
-                if ((r.resultWho == null && resultWho == null) ||
-                    (r.resultWho != null && r.resultWho.equals(resultWho))) {
-                    finishActivityLocked(r, i,
-                            Activity.RESULT_CANCELED, null, "request-sub", false);
+    final void finishSubActivityLocked(ActivityRecord self, String resultWho, int requestCode) {
+        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+            ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
+            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+                ActivityRecord r = activities.get(activityNdx);
+                if (r.resultTo == self && r.requestCode == requestCode) {
+                    if ((r.resultWho == null && resultWho == null) ||
+                        (r.resultWho != null && r.resultWho.equals(resultWho))) {
+                        finishActivityLocked(r, Activity.RESULT_CANCELED, null, "request-sub",
+                                false);
+                    }
                 }
             }
         }
         mService.updateOomAdjLocked();
     }
 
-    final boolean finishActivityAffinityLocked(IBinder token) {
-        int index = indexOfTokenLocked(token);
-        if (DEBUG_RESULTS) Slog.v(
-                TAG, "Finishing activity affinity @" + index + ": token=" + token);
-        if (index < 0) {
-            return false;
+    final void finishTopRunningActivityLocked(ProcessRecord app) {
+        ActivityRecord r = topRunningActivityLocked(null);
+        if (r != null && r.app == app) {
+            // If the top running activity is from this crashing
+            // process, then terminate it to avoid getting in a loop.
+            Slog.w(TAG, "  Force finishing activity "
+                    + r.intent.getComponent().flattenToShortString());
+            int taskNdx = mTaskHistory.indexOf(r.task);
+            int activityNdx = r.task.mActivities.indexOf(r);
+            finishActivityLocked(r, Activity.RESULT_CANCELED, null, "crashed", false);
+            // Also terminate any activities below it that aren't yet
+            // stopped, to avoid a situation where one will get
+            // re-start our crashing activity once it gets resumed again.
+            --activityNdx;
+            if (activityNdx < 0) {
+                do {
+                    --taskNdx;
+                    if (taskNdx < 0) {
+                        break;
+                    }
+                    activityNdx = mTaskHistory.get(taskNdx).mActivities.size() - 1;
+                } while (activityNdx < 0);
+            }
+            if (activityNdx >= 0) {
+                r = mTaskHistory.get(taskNdx).mActivities.get(activityNdx);
+                if (r.state == ActivityState.RESUMED
+                        || r.state == ActivityState.PAUSING
+                        || r.state == ActivityState.PAUSED) {
+                    if (!r.isHomeActivity() || !mService.mHomeProcess.contains(r.app)) {
+                        Slog.w(TAG, "  Force finishing activity "
+                                + r.intent.getComponent().flattenToShortString());
+                        finishActivityLocked(r, Activity.RESULT_CANCELED, null, "crashed", false);
+                    }
+                }
+            }
         }
-        ActivityRecord r = mHistory.get(index);
+    }
 
-        while (index >= 0) {
-            ActivityRecord cur = mHistory.get(index);
-            if (cur.task != r.task) {
+    final boolean finishActivityAffinityLocked(ActivityRecord r) {
+        ArrayList<ActivityRecord> activities = r.task.mActivities;
+        for (int index = activities.indexOf(r); index >= 0; --index) {
+            ActivityRecord cur = activities.get(index);
+            if (!Objects.equal(cur.taskAffinity, r.taskAffinity)) {
                 break;
             }
-            if (cur.taskAffinity == null && r.taskAffinity != null) {
-                break;
-            }
-            if (cur.taskAffinity != null && !cur.taskAffinity.equals(r.taskAffinity)) {
-                break;
-            }
-            finishActivityLocked(cur, index, Activity.RESULT_CANCELED, null,
-                    "request-affinity", true);
-            index--;
+            finishActivityLocked(cur, Activity.RESULT_CANCELED, null, "request-affinity", true);
         }
         return true;
     }
@@ -3761,17 +2306,8 @@
      * @return Returns true if this activity has been removed from the history
      * list, or false if it is still in the list and will be removed later.
      */
-    final boolean finishActivityLocked(ActivityRecord r, int index,
-            int resultCode, Intent resultData, String reason, boolean oomAdj) {
-        return finishActivityLocked(r, index, resultCode, resultData, reason, false, oomAdj);
-    }
-
-    /**
-     * @return Returns true if this activity has been removed from the history
-     * list, or false if it is still in the list and will be removed later.
-     */
-    final boolean finishActivityLocked(ActivityRecord r, int index, int resultCode,
-            Intent resultData, String reason, boolean immediate, boolean oomAdj) {
+    final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
+            String reason, boolean oomAdj) {
         if (r.finishing) {
             Slog.w(TAG, "Duplicate finish request for " + r);
             return false;
@@ -3781,53 +2317,49 @@
         EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
                 r.userId, System.identityHashCode(r),
                 r.task.taskId, r.shortComponentName, reason);
-        if (index < (mHistory.size()-1)) {
-            ActivityRecord next = mHistory.get(index+1);
-            if (next.task == r.task) {
-                if (r.frontOfTask) {
-                    // The next activity is now the front of the task.
-                    next.frontOfTask = true;
-                }
-                if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
-                    // If the caller asked that this activity (and all above it)
-                    // be cleared when the task is reset, don't lose that information,
-                    // but propagate it up to the next activity.
-                    next.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
-                }
+        final ArrayList<ActivityRecord> activities = r.task.mActivities;
+        final int index = activities.indexOf(r);
+        if (index < (activities.size() - 1)) {
+            ActivityRecord next = activities.get(index+1);
+            if (r.frontOfTask) {
+                // The next activity is now the front of the task.
+                next.frontOfTask = true;
+            }
+            if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
+                // If the caller asked that this activity (and all above it)
+                // be cleared when the task is reset, don't lose that information,
+                // but propagate it up to the next activity.
+                next.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
             }
         }
 
         r.pauseKeyDispatchingLocked();
-        if (mMainStack) {
+        if (mStackSupervisor.isFrontStack(this)) {
             if (mService.mFocusedActivity == r) {
-                mService.setFocusedActivityLocked(topRunningActivityLocked(null));
+                mService.setFocusedActivityLocked(mStackSupervisor.topRunningActivityLocked());
             }
         }
 
         finishActivityResultsLocked(r, resultCode, resultData);
-        
-        if (mService.mPendingThumbnails.size() > 0) {
+
+        if (!mService.mPendingThumbnails.isEmpty()) {
             // There are clients waiting to receive thumbnails so, in case
             // this is an activity that someone is waiting for, add it
             // to the pending list so we can correctly update the clients.
-            mService.mCancelledThumbnails.add(r);
+            mStackSupervisor.mCancelledThumbnails.add(r);
         }
 
-        if (immediate) {
-            return finishCurrentActivityLocked(r, index,
-                    FINISH_IMMEDIATELY, oomAdj) == null;
-        } else if (mResumedActivity == r) {
-            boolean endTask = index <= 0
-                    || (mHistory.get(index-1)).task != r.task;
+        if (mResumedActivity == r) {
+            boolean endTask = index <= 0;
             if (DEBUG_TRANSITION) Slog.v(TAG,
                     "Prepare close transition: finishing " + r);
-            mService.mWindowManager.prepareAppTransition(endTask
+            mWindowManager.prepareAppTransition(endTask
                     ? AppTransition.TRANSIT_TASK_CLOSE
                     : AppTransition.TRANSIT_ACTIVITY_CLOSE, false);
-    
+
             // Tell window manager to prepare for this one to be removed.
-            mService.mWindowManager.setAppVisibility(r.appToken, false);
-                
+            mWindowManager.setAppVisibility(r.appToken, false);
+
             if (mPausingActivity == null) {
                 if (DEBUG_PAUSE) Slog.v(TAG, "Finish needs to pause: " + r);
                 if (DEBUG_USER_LEAVING) Slog.v(TAG, "finish() => pause with userLeaving=false");
@@ -3838,8 +2370,7 @@
             // If the activity is PAUSING, we will complete the finish once
             // it is done pausing; else we can just directly finish it here.
             if (DEBUG_PAUSE) Slog.v(TAG, "Finish not pausing: " + r);
-            return finishCurrentActivityLocked(r, index,
-                    FINISH_AFTER_PAUSE, oomAdj) == null;
+            return finishCurrentActivityLocked(r, FINISH_AFTER_PAUSE, oomAdj) == null;
         } else {
             if (DEBUG_PAUSE) Slog.v(TAG, "Finish waiting for pause of: " + r);
         }
@@ -3847,35 +2378,26 @@
         return false;
     }
 
-    private static final int FINISH_IMMEDIATELY = 0;
-    private static final int FINISH_AFTER_PAUSE = 1;
-    private static final int FINISH_AFTER_VISIBLE = 2;
+    static final int FINISH_IMMEDIATELY = 0;
+    static final int FINISH_AFTER_PAUSE = 1;
+    static final int FINISH_AFTER_VISIBLE = 2;
 
-    private final ActivityRecord finishCurrentActivityLocked(ActivityRecord r,
-            int mode, boolean oomAdj) {
-        final int index = indexOfActivityLocked(r);
-        if (index < 0) {
-            return null;
-        }
-
-        return finishCurrentActivityLocked(r, index, mode, oomAdj);
-    }
-
-    private final ActivityRecord finishCurrentActivityLocked(ActivityRecord r,
-            int index, int mode, boolean oomAdj) {
+    final ActivityRecord finishCurrentActivityLocked(ActivityRecord r, int mode, boolean oomAdj) {
         // First things first: if this activity is currently visible,
         // and the resumed activity is not yet visible, then hold off on
         // finishing until the resumed one becomes visible.
         if (mode == FINISH_AFTER_VISIBLE && r.nowVisible) {
-            if (!mStoppingActivities.contains(r)) {
-                mStoppingActivities.add(r);
-                if (mStoppingActivities.size() > 3) {
+            if (!mStackSupervisor.mStoppingActivities.contains(r)) {
+                mStackSupervisor.mStoppingActivities.add(r);
+                if (mStackSupervisor.mStoppingActivities.size() > 3
+                        || r.frontOfTask && mTaskHistory.size() <= 1) {
                     // If we already have a few activities waiting to stop,
                     // then give up on things going idle and start clearing
-                    // them out.
-                    scheduleIdleLocked();
+                    // them out. Or if r is the last of activity of the last task the stack
+                    // will be empty and must be cleared immediately.
+                    mStackSupervisor.scheduleIdleLocked();
                 } else {
-                    checkReadyForSleepLocked();
+                    mStackSupervisor.checkReadyForSleepLocked();
                 }
             }
             if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPING: " + r
@@ -3888,9 +2410,9 @@
         }
 
         // make sure the record is cleaned out of other places.
-        mStoppingActivities.remove(r);
-        mGoingToSleepActivities.remove(r);
-        mWaitingVisibleActivities.remove(r);
+        mStackSupervisor.mStoppingActivities.remove(r);
+        mStackSupervisor.mGoingToSleepActivities.remove(r);
+        mStackSupervisor.mWaitingVisibleActivities.remove(r);
         if (mResumedActivity == r) {
             mResumedActivity = null;
         }
@@ -3906,19 +2428,99 @@
             boolean activityRemoved = destroyActivityLocked(r, true,
                     oomAdj, "finish-imm");
             if (activityRemoved) {
-                resumeTopActivityLocked(null);
+                mStackSupervisor.resumeTopActivitiesLocked();
             }
             return activityRemoved ? null : r;
-        } else {
-            // Need to go through the full pause cycle to get this
-            // activity into the stopped state and then finish it.
-            if (localLOGV) Slog.v(TAG, "Enqueueing pending finish: " + r);
-            mFinishingActivities.add(r);
-            resumeTopActivityLocked(null);
         }
+
+        // Need to go through the full pause cycle to get this
+        // activity into the stopped state and then finish it.
+        if (localLOGV) Slog.v(TAG, "Enqueueing pending finish: " + r);
+        mStackSupervisor.mFinishingActivities.add(r);
+        mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null);
         return r;
     }
 
+    final boolean navigateUpToLocked(IBinder token, Intent destIntent, int resultCode,
+            Intent resultData) {
+        final ActivityRecord srec = ActivityRecord.forToken(token);
+        final TaskRecord task = srec.task;
+        final ArrayList<ActivityRecord> activities = task.mActivities;
+        final int start = activities.indexOf(srec);
+        if (!mTaskHistory.contains(task) || (start < 0)) {
+            return false;
+        }
+        int finishTo = start - 1;
+        ActivityRecord parent = finishTo < 0 ? null : activities.get(finishTo);
+        boolean foundParentInTask = false;
+        final ComponentName dest = destIntent.getComponent();
+        if (start > 0 && dest != null) {
+            for (int i = finishTo; i >= 0; i--) {
+                ActivityRecord r = activities.get(i);
+                if (r.info.packageName.equals(dest.getPackageName()) &&
+                        r.info.name.equals(dest.getClassName())) {
+                    finishTo = i;
+                    parent = r;
+                    foundParentInTask = true;
+                    break;
+                }
+            }
+        }
+
+        IActivityController controller = mService.mController;
+        if (controller != null) {
+            ActivityRecord next = topRunningActivityLocked(srec.appToken, 0);
+            if (next != null) {
+                // ask watcher if this is allowed
+                boolean resumeOK = true;
+                try {
+                    resumeOK = controller.activityResuming(next.packageName);
+                } catch (RemoteException e) {
+                    mService.mController = null;
+                    Watchdog.getInstance().setActivityController(null);
+                }
+
+                if (!resumeOK) {
+                    return false;
+                }
+            }
+        }
+        final long origId = Binder.clearCallingIdentity();
+        for (int i = start; i > finishTo; i--) {
+            ActivityRecord r = activities.get(i);
+            requestFinishActivityLocked(r.appToken, resultCode, resultData, "navigate-up", true);
+            // Only return the supplied result for the first activity finished
+            resultCode = Activity.RESULT_CANCELED;
+            resultData = null;
+        }
+
+        if (parent != null && foundParentInTask) {
+            final int parentLaunchMode = parent.info.launchMode;
+            final int destIntentFlags = destIntent.getFlags();
+            if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
+                    parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
+                    parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
+                    (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
+                parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
+            } else {
+                try {
+                    ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
+                            destIntent.getComponent(), 0, srec.userId);
+                    int res = mStackSupervisor.startActivityLocked(srec.app.thread, destIntent,
+                            null, aInfo, parent.appToken, null,
+                            0, -1, parent.launchedFromUid, parent.launchedFromPackage,
+                            0, null, true, null);
+                    foundParentInTask = res == ActivityManager.START_SUCCESS;
+                } catch (RemoteException e) {
+                    foundParentInTask = false;
+                }
+                requestFinishActivityLocked(parent.appToken, resultCode,
+                        resultData, "navigate-up", true);
+            }
+        }
+        Binder.restoreCallingIdentity(origId);
+        return foundParentInTask;
+    }
     /**
      * Perform the common clean-up of an activity record.  This is called both
      * as part of destroyActivityLocked() (when destroying the client-side
@@ -3948,9 +2550,9 @@
         // Make sure this record is no longer in the pending finishes list.
         // This could happen, for example, if we are trimming activities
         // down to the max limit while they are still waiting to finish.
-        mFinishingActivities.remove(r);
-        mWaitingVisibleActivities.remove(r);
-        
+        mStackSupervisor.mFinishingActivities.remove(r);
+        mStackSupervisor.mWaitingVisibleActivities.remove(r);
+
         // Remove any pending results.
         if (r.finishing && r.pendingResults != null) {
             for (WeakReference<PendingIntentRecord> apr : r.pendingResults) {
@@ -3963,14 +2565,14 @@
         }
 
         if (cleanServices) {
-            cleanUpActivityServicesLocked(r);            
+            cleanUpActivityServicesLocked(r);
         }
 
-        if (mService.mPendingThumbnails.size() > 0) {
+        if (!mService.mPendingThumbnails.isEmpty()) {
             // There are clients waiting to receive thumbnails so, in case
             // this is an activity that someone is waiting for, add it
             // to the pending list so we can correctly update the clients.
-            mService.mCancelledThumbnails.add(r);
+            mStackSupervisor.mCancelledThumbnails.add(r);
         }
 
         // Get rid of any pending idle timeouts.
@@ -3978,9 +2580,9 @@
     }
 
     private void removeTimeoutsForActivityLocked(ActivityRecord r) {
+        mStackSupervisor.removeTimeoutsForActivityLocked(r);
         mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
         mHandler.removeMessages(STOP_TIMEOUT_MSG, r);
-        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
         mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r);
         r.finishLaunchTickingLocked();
     }
@@ -3993,22 +2595,26 @@
             here.fillInStackTrace();
             Slog.i(TAG, "Removing activity " + r + " from stack");
         }
-        mHistory.remove(r);
+        final TaskRecord task = r.task;
+        if (task != null && task.removeActivity(r)) {
+            if (DEBUG_STACK) Slog.i(TAG,
+                    "removeActivityFromHistoryLocked: last activity removed from " + this);
+            mStackSupervisor.removeTask(task);
+        }
         r.takeFromHistory();
         removeTimeoutsForActivityLocked(r);
-        if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYED: " + r
-                + " (removed from history)");
+        if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYED: " + r + " (removed from history)");
         r.state = ActivityState.DESTROYED;
         if (DEBUG_APP) Slog.v(TAG, "Clearing app during remove for activity " + r);
         r.app = null;
-        mService.mWindowManager.removeAppToken(r.appToken);
+        mWindowManager.removeAppToken(r.appToken);
         if (VALIDATE_TOKENS) {
             validateAppTokensLocked();
         }
         cleanUpActivityServicesLocked(r);
         r.removeUriPermissionsLocked();
     }
-    
+
     /**
      * Perform clean-up of service connections in an activity record.
      */
@@ -4033,36 +2639,40 @@
     final void destroyActivitiesLocked(ProcessRecord owner, boolean oomAdj, String reason) {
         boolean lastIsOpaque = false;
         boolean activityRemoved = false;
-        for (int i=mHistory.size()-1; i>=0; i--) {
-            ActivityRecord r = mHistory.get(i);
-            if (r.finishing) {
-                continue;
-            }
-            if (r.fullscreen) {
-                lastIsOpaque = true;
-            }
-            if (owner != null && r.app != owner) {
-                continue;
-            }
-            if (!lastIsOpaque) {
-                continue;
-            }
-            // We can destroy this one if we have its icicle saved and
-            // it is not in the process of pausing/stopping/finishing.
-            if (r.app != null && r != mResumedActivity && r != mPausingActivity
-                    && r.haveState && !r.visible && r.stopped
-                    && r.state != ActivityState.DESTROYING
-                    && r.state != ActivityState.DESTROYED) {
-                if (DEBUG_SWITCH) Slog.v(TAG, "Destroying " + r + " in state " + r.state
-                        + " resumed=" + mResumedActivity
-                        + " pausing=" + mPausingActivity);
-                if (destroyActivityLocked(r, true, oomAdj, reason)) {
-                    activityRemoved = true;
+        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
+            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+                final ActivityRecord r = activities.get(activityNdx);
+                if (r.finishing) {
+                    continue;
+                }
+                if (r.fullscreen) {
+                    lastIsOpaque = true;
+                }
+                if (owner != null && r.app != owner) {
+                    continue;
+                }
+                if (!lastIsOpaque) {
+                    continue;
+                }
+                // We can destroy this one if we have its icicle saved and
+                // it is not in the process of pausing/stopping/finishing.
+                if (r.app != null && r != mResumedActivity && r != mPausingActivity
+                        && r.haveState && !r.visible && r.stopped
+                        && r.state != ActivityState.DESTROYING
+                        && r.state != ActivityState.DESTROYED) {
+                    if (DEBUG_SWITCH) Slog.v(TAG, "Destroying " + r + " in state " + r.state
+                            + " resumed=" + mResumedActivity
+                            + " pausing=" + mPausingActivity);
+                    if (destroyActivityLocked(r, true, oomAdj, reason)) {
+                        activityRemoved = true;
+                    }
                 }
             }
         }
         if (activityRemoved) {
-            resumeTopActivityLocked(null);
+            mStackSupervisor.resumeTopActivitiesLocked();
+
         }
     }
 
@@ -4089,23 +2699,20 @@
 
         if (hadApp) {
             if (removeFromApp) {
-                int idx = r.app.activities.indexOf(r);
-                if (idx >= 0) {
-                    r.app.activities.remove(idx);
-                }
+                r.app.activities.remove(r);
                 if (mService.mHeavyWeightProcess == r.app && r.app.activities.size() <= 0) {
                     mService.mHeavyWeightProcess = null;
                     mService.mHandler.sendEmptyMessage(
                             ActivityManagerService.CANCEL_HEAVY_NOTIFICATION_MSG);
                 }
-                if (r.app.activities.size() == 0) {
+                if (r.app.activities.isEmpty()) {
                     // No longer have activities, so update oom adj.
                     mService.updateOomAdjLocked();
                 }
             }
 
             boolean skipDestroy = false;
-            
+
             try {
                 if (DEBUG_SWITCH) Slog.i(TAG, "Destroying: " + r);
                 r.app.thread.scheduleDestroyActivity(r.appToken, r.finishing,
@@ -4123,7 +2730,7 @@
             }
 
             r.nowVisible = false;
-            
+
             // If the activity is finishing, we need to wait on removing it
             // from the list to give it a chance to do its cleanup.  During
             // that time it may make calls back with its token so we need to
@@ -4135,12 +2742,10 @@
                 if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYING: " + r
                         + " (destroy requested)");
                 r.state = ActivityState.DESTROYING;
-                Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG);
-                msg.obj = r;
+                Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG, r);
                 mHandler.sendMessageDelayed(msg, DESTROY_TIMEOUT);
             } else {
-                if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYED: " + r
-                        + " (destroy skipped)");
+                if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYED: " + r + " (destroy skipped)");
                 r.state = ActivityState.DESTROYED;
                 if (DEBUG_APP) Slog.v(TAG, "Clearing app during destroy for activity " + r);
                 r.app = null;
@@ -4151,8 +2756,7 @@
                 removeActivityFromHistoryLocked(r);
                 removedFromHistory = true;
             } else {
-                if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYED: " + r
-                        + " (no app)");
+                if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYED: " + r + " (no app)");
                 r.state = ActivityState.DESTROYED;
                 if (DEBUG_APP) Slog.v(TAG, "Clearing app during destroy for activity " + r);
                 r.app = null;
@@ -4160,46 +2764,43 @@
         }
 
         r.configChangeFlags = 0;
-        
+
         if (!mLRUActivities.remove(r) && hadApp) {
             Slog.w(TAG, "Activity " + r + " being finished, but not in LRU list");
         }
-        
+
         return removedFromHistory;
     }
 
-    final void activityDestroyed(IBinder token) {
-        synchronized (mService) {
-            final long origId = Binder.clearCallingIdentity();
-            try {
-                ActivityRecord r = ActivityRecord.forToken(token);
-                if (r != null) {
-                    mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r);
-                }
-
-                int index = indexOfActivityLocked(r);
-                if (index >= 0) {
-                    if (r.state == ActivityState.DESTROYING) {
-                        cleanUpActivityLocked(r, true, false);
-                        removeActivityFromHistoryLocked(r);
-                    }
-                }
-                resumeTopActivityLocked(null);
-            } finally {
-                Binder.restoreCallingIdentity(origId);
+    final void activityDestroyedLocked(IBinder token) {
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            ActivityRecord r = ActivityRecord.forToken(token);
+            if (r != null) {
+                mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r);
             }
+
+            if (isInStackLocked(token) != null) {
+                if (r.state == ActivityState.DESTROYING) {
+                    cleanUpActivityLocked(r, true, false);
+                    removeActivityFromHistoryLocked(r);
+                }
+            }
+            mStackSupervisor.resumeTopActivitiesLocked();
+        } finally {
+            Binder.restoreCallingIdentity(origId);
         }
     }
-    
-    private void removeHistoryRecordsForAppLocked(ArrayList list, ProcessRecord app,
-            String listName) {
+
+    private void removeHistoryRecordsForAppLocked(ArrayList<ActivityRecord> list,
+            ProcessRecord app, String listName) {
         int i = list.size();
         if (DEBUG_CLEANUP) Slog.v(
             TAG, "Removing app " + app + " from list " + listName
             + " with " + i + " entries");
         while (i > 0) {
             i--;
-            ActivityRecord r = (ActivityRecord)list.get(i);
+            ActivityRecord r = list.get(i);
             if (DEBUG_CLEANUP) Slog.v(TAG, "Record #" + i + " " + r);
             if (r.app == app) {
                 if (DEBUG_CLEANUP) Slog.v(TAG, "---> REMOVING this entry!");
@@ -4211,100 +2812,91 @@
 
     boolean removeHistoryRecordsForAppLocked(ProcessRecord app) {
         removeHistoryRecordsForAppLocked(mLRUActivities, app, "mLRUActivities");
-        removeHistoryRecordsForAppLocked(mStoppingActivities, app, "mStoppingActivities");
-        removeHistoryRecordsForAppLocked(mGoingToSleepActivities, app, "mGoingToSleepActivities");
-        removeHistoryRecordsForAppLocked(mWaitingVisibleActivities, app,
+        removeHistoryRecordsForAppLocked(mStackSupervisor.mStoppingActivities, app,
+                "mStoppingActivities");
+        removeHistoryRecordsForAppLocked(mStackSupervisor.mGoingToSleepActivities, app,
+                "mGoingToSleepActivities");
+        removeHistoryRecordsForAppLocked(mStackSupervisor.mWaitingVisibleActivities, app,
                 "mWaitingVisibleActivities");
-        removeHistoryRecordsForAppLocked(mFinishingActivities, app, "mFinishingActivities");
+        removeHistoryRecordsForAppLocked(mStackSupervisor.mFinishingActivities, app,
+                "mFinishingActivities");
 
         boolean hasVisibleActivities = false;
 
         // Clean out the history list.
-        int i = mHistory.size();
+        int i = numActivities();
         if (DEBUG_CLEANUP) Slog.v(
             TAG, "Removing app " + app + " from history with " + i + " entries");
-        while (i > 0) {
-            i--;
-            ActivityRecord r = (ActivityRecord)mHistory.get(i);
-            if (DEBUG_CLEANUP) Slog.v(
-                TAG, "Record #" + i + " " + r + ": app=" + r.app);
-            if (r.app == app) {
-                boolean remove;
-                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
-                    // Don't currently have state for the activity, or
-                    // it is finishing -- always remove it.
-                    remove = true;
-                } else if (r.launchCount > 2 &&
-                        r.lastLaunchTime > (SystemClock.uptimeMillis()-60000)) {
-                    // We have launched this activity too many times since it was
-                    // able to run, so give up and remove it.
-                    remove = true;
-                } else {
-                    // The process may be gone, but the activity lives on!
-                    remove = false;
-                }
-                if (remove) {
-                    if (ActivityStack.DEBUG_ADD_REMOVE || DEBUG_CLEANUP) {
-                        RuntimeException here = new RuntimeException("here");
-                        here.fillInStackTrace();
-                        Slog.i(TAG, "Removing activity " + r + " from stack at " + i
-                                + ": haveState=" + r.haveState
-                                + " stateNotNeeded=" + r.stateNotNeeded
-                                + " finishing=" + r.finishing
-                                + " state=" + r.state, here);
+        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
+            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+                final ActivityRecord r = activities.get(activityNdx);
+                --i;
+                if (DEBUG_CLEANUP) Slog.v(
+                    TAG, "Record #" + i + " " + r + ": app=" + r.app);
+                if (r.app == app) {
+                    boolean remove;
+                    if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
+                        // Don't currently have state for the activity, or
+                        // it is finishing -- always remove it.
+                        remove = true;
+                    } else if (r.launchCount > 2 &&
+                            r.lastLaunchTime > (SystemClock.uptimeMillis()-60000)) {
+                        // We have launched this activity too many times since it was
+                        // able to run, so give up and remove it.
+                        remove = true;
+                    } else {
+                        // The process may be gone, but the activity lives on!
+                        remove = false;
                     }
-                    if (!r.finishing) {
-                        Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
-                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
-                                r.userId, System.identityHashCode(r),
-                                r.task.taskId, r.shortComponentName,
-                                "proc died without state saved");
-                    }
-                    removeActivityFromHistoryLocked(r);
+                    if (remove) {
+                        if (DEBUG_ADD_REMOVE || DEBUG_CLEANUP) {
+                            RuntimeException here = new RuntimeException("here");
+                            here.fillInStackTrace();
+                            Slog.i(TAG, "Removing activity " + r + " from stack at " + i
+                                    + ": haveState=" + r.haveState
+                                    + " stateNotNeeded=" + r.stateNotNeeded
+                                    + " finishing=" + r.finishing
+                                    + " state=" + r.state, here);
+                        }
+                        if (!r.finishing) {
+                            Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
+                            EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
+                                    r.userId, System.identityHashCode(r),
+                                    r.task.taskId, r.shortComponentName,
+                                    "proc died without state saved");
+                            if (r.state == ActivityState.RESUMED) {
+                                mService.updateUsageStats(r, false);
+                            }
+                        }
+                        removeActivityFromHistoryLocked(r);
 
-                } else {
-                    // We have the current state for this activity, so
-                    // it can be restarted later when needed.
-                    if (localLOGV) Slog.v(
-                        TAG, "Keeping entry, setting app to null");
-                    if (r.visible) {
-                        hasVisibleActivities = true;
+                    } else {
+                        // We have the current state for this activity, so
+                        // it can be restarted later when needed.
+                        if (localLOGV) Slog.v(
+                            TAG, "Keeping entry, setting app to null");
+                        if (r.visible) {
+                            hasVisibleActivities = true;
+                        }
+                        if (DEBUG_APP) Slog.v(TAG, "Clearing app during removeHistory for activity "
+                                + r);
+                        r.app = null;
+                        r.nowVisible = false;
+                        if (!r.haveState) {
+                            if (DEBUG_SAVED_STATE) Slog.i(TAG,
+                                    "App died, clearing saved state of " + r);
+                            r.icicle = null;
+                        }
                     }
-                    if (DEBUG_APP) Slog.v(TAG, "Clearing app during removeHistory for activity "
-                            + r);
-                    r.app = null;
-                    r.nowVisible = false;
-                    if (!r.haveState) {
-                        if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
-                                "App died, clearing saved state of " + r);
-                        r.icicle = null;
-                    }
-                }
 
-                r.stack.cleanUpActivityLocked(r, true, true);
+                    cleanUpActivityLocked(r, true, true);
+                }
             }
         }
 
         return hasVisibleActivities;
     }
-    
-    /**
-     * Move the current home activity's task (if one exists) to the front
-     * of the stack.
-     */
-    final void moveHomeToFrontLocked() {
-        TaskRecord homeTask = null;
-        for (int i=mHistory.size()-1; i>=0; i--) {
-            ActivityRecord hr = mHistory.get(i);
-            if (hr.isHomeActivity) {
-                homeTask = hr.task;
-                break;
-            }
-        }
-        if (homeTask != null) {
-            moveTaskToFrontLocked(homeTask, null, null);
-        }
-    }
 
     final void updateTransitLocked(int transit, Bundle options) {
         if (options != null) {
@@ -4315,16 +2907,45 @@
                 ActivityOptions.abort(options);
             }
         }
-        mService.mWindowManager.prepareAppTransition(transit, false);
+        mWindowManager.prepareAppTransition(transit, false);
+    }
+
+    void moveHomeTaskToTop() {
+        final int top = mTaskHistory.size() - 1;
+        for (int taskNdx = top; taskNdx >= 0; --taskNdx) {
+            final TaskRecord task = mTaskHistory.get(taskNdx);
+            if (task.isHomeTask()) {
+                mTaskHistory.remove(taskNdx);
+                mTaskHistory.add(top, task);
+                mWindowManager.moveTaskToTop(task.taskId);
+                return;
+            }
+        }
+    }
+
+    final boolean findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
+        final TaskRecord task = taskForIdLocked(taskId);
+        if (task != null) {
+            if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
+                mStackSupervisor.mUserLeaving = true;
+            }
+            if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
+                // Caller wants the home activity moved with it.  To accomplish this,
+                // we'll just indicate that this task returns to the home task.
+                task.mActivities.get(0).mLaunchHomeTaskNext = true;
+            }
+            moveTaskToFrontLocked(task, null, options);
+            return true;
+        }
+        return false;
     }
 
     final void moveTaskToFrontLocked(TaskRecord tr, ActivityRecord reason, Bundle options) {
         if (DEBUG_SWITCH) Slog.v(TAG, "moveTaskToFront: " + tr);
 
-        final int task = tr.taskId;
-        int top = mHistory.size()-1;
-
-        if (top < 0 || (mHistory.get(top)).task.taskId == task) {
+        final int numTasks = mTaskHistory.size();
+        final int index = mTaskHistory.indexOf(tr);
+        if (numTasks == 0 || index < 0)  {
             // nothing to do!
             if (reason != null &&
                     (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
@@ -4335,40 +2956,16 @@
             return;
         }
 
-        ArrayList<IBinder> moved = new ArrayList<IBinder>();
-
-        // Applying the affinities may have removed entries from the history,
-        // so get the size again.
-        top = mHistory.size()-1;
-        int pos = top;
+        mStackSupervisor.moveHomeStack(isHomeStack());
 
         // Shift all activities with this task up to the top
         // of the stack, keeping them in the same internal order.
-        while (pos >= 0) {
-            ActivityRecord r = mHistory.get(pos);
-            if (localLOGV) Slog.v(
-                TAG, "At " + pos + " ckp " + r.task + ": " + r);
-            if (r.task.taskId == task) {
-                if (localLOGV) Slog.v(TAG, "Removing and adding at " + top);
-                if (DEBUG_ADD_REMOVE) {
-                    RuntimeException here = new RuntimeException("here");
-                    here.fillInStackTrace();
-                    Slog.i(TAG, "Removing and adding activity " + r + " to stack at " + top, here);
-                }
-                mHistory.remove(pos);
-                mHistory.add(top, r);
-                moved.add(0, r.appToken);
-                top--;
-            }
-            pos--;
-        }
+        insertTaskAtTop(tr);
 
-        if (DEBUG_TRANSITION) Slog.v(TAG,
-                "Prepare to front transition: task=" + tr);
+        if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare to front transition: task=" + tr);
         if (reason != null &&
                 (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
-            mService.mWindowManager.prepareAppTransition(
-                    AppTransition.TRANSIT_NONE, false);
+            mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
             ActivityRecord r = topRunningActivityLocked(null);
             if (r != null) {
                 mNoAnimActivities.add(r);
@@ -4377,38 +2974,35 @@
         } else {
             updateTransitLocked(AppTransition.TRANSIT_TASK_TO_FRONT, options);
         }
-        
-        mService.mWindowManager.moveAppTokensToTop(moved);
+
+        mWindowManager.moveTaskToTop(tr.taskId);
+
+        mStackSupervisor.resumeTopActivitiesLocked();
+        EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, tr.taskId);
+
         if (VALIDATE_TOKENS) {
             validateAppTokensLocked();
         }
-
-        finishTaskMoveLocked(task);
-        EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, task);
-    }
-
-    private final void finishTaskMoveLocked(int task) {
-        resumeTopActivityLocked(null);
     }
 
     /**
-     * Worker method for rearranging history stack.  Implements the function of moving all 
-     * activities for a specific task (gathering them if disjoint) into a single group at the 
+     * Worker method for rearranging history stack. Implements the function of moving all
+     * activities for a specific task (gathering them if disjoint) into a single group at the
      * bottom of the stack.
-     * 
+     *
      * If a watcher is installed, the action is preflighted and the watcher has an opportunity
      * to premeptively cancel the move.
-     * 
+     *
      * @param task The taskId to collect and move to the bottom.
      * @return Returns true if the move completed, false if not.
      */
     final boolean moveTaskToBackLocked(int task, ActivityRecord reason) {
         Slog.i(TAG, "moveTaskToBack: " + task);
-        
+
         // If we have a watcher, preflight the move before committing to it.  First check
         // for *other* available tasks, but if none are available, then try again allowing the
         // current task to be selected.
-        if (mMainStack && mService.mController != null) {
+        if (mStackSupervisor.isFrontStack(this) && mService.mController != null) {
             ActivityRecord next = topRunningActivityLocked(null, task);
             if (next == null) {
                 next = topRunningActivityLocked(null, 0);
@@ -4420,6 +3014,7 @@
                     moveOK = mService.mController.activityResuming(next.packageName);
                 } catch (RemoteException e) {
                     mService.mController = null;
+                    Watchdog.getInstance().setActivityController(null);
                 }
                 if (!moveOK) {
                     return false;
@@ -4427,181 +3022,72 @@
             }
         }
 
-        ArrayList<IBinder> moved = new ArrayList<IBinder>();
-
         if (DEBUG_TRANSITION) Slog.v(TAG,
                 "Prepare to back transition: task=" + task);
-        
-        final int N = mHistory.size();
-        int bottom = 0;
-        int pos = 0;
 
-        // Shift all activities with this task down to the bottom
-        // of the stack, keeping them in the same internal order.
-        while (pos < N) {
-            ActivityRecord r = mHistory.get(pos);
-            if (localLOGV) Slog.v(
-                TAG, "At " + pos + " ckp " + r.task + ": " + r);
-            if (r.task.taskId == task) {
-                if (localLOGV) Slog.v(TAG, "Removing and adding at " + (N-1));
-                if (DEBUG_ADD_REMOVE) {
-                    RuntimeException here = new RuntimeException("here");
-                    here.fillInStackTrace();
-                    Slog.i(TAG, "Removing and adding activity " + r + " to stack at "
-                            + bottom, here);
+        final TaskRecord tr = taskForIdLocked(task);
+        if (tr == null) {
+            return false;
+        }
+
+        mTaskHistory.remove(tr);
+        mTaskHistory.add(0, tr);
+
+        // There is an assumption that moving a task to the back moves it behind the home activity.
+        // We make sure here that some activity in the stack will launch home.
+        ActivityRecord lastActivity = null;
+        int numTasks = mTaskHistory.size();
+        int taskNdx;
+        for (taskNdx = numTasks - 1; taskNdx >= 1; --taskNdx) {
+            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
+            int activityNdx;
+            for (activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+                final ActivityRecord r = activities.get(activityNdx);
+                if (r.mLaunchHomeTaskNext) {
+                    break;
                 }
-                mHistory.remove(pos);
-                mHistory.add(bottom, r);
-                moved.add(r.appToken);
-                bottom++;
+                if (taskNdx == 1 && activityNdx == 0) {
+                    // Final activity before tr task.
+                    lastActivity = r;
+                }
             }
-            pos++;
+            if (activityNdx >= 0) {
+                // Early exit, we found an activity that will launchHomeTaskNext.
+                break;
+            }
+        }
+        if (lastActivity != null) {
+            // No early exit, we did not find an activity that will launchHomeTaskNext, set one.
+            lastActivity.mLaunchHomeTaskNext = true;
         }
 
         if (reason != null &&
-                (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
-            mService.mWindowManager.prepareAppTransition(
-                    AppTransition.TRANSIT_NONE, false);
+                (reason.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
+            mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
             ActivityRecord r = topRunningActivityLocked(null);
             if (r != null) {
                 mNoAnimActivities.add(r);
             }
         } else {
-            mService.mWindowManager.prepareAppTransition(
-                    AppTransition.TRANSIT_TASK_TO_BACK, false);
+            mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_TO_BACK, false);
         }
-        mService.mWindowManager.moveAppTokensToBottom(moved);
+        mWindowManager.moveTaskToBottom(task);
+
         if (VALIDATE_TOKENS) {
             validateAppTokensLocked();
         }
 
-        finishTaskMoveLocked(task);
+        if (numTasks <= 1 || (mResumedActivity != null && mResumedActivity.task == tr &&
+                mResumedActivity.mLaunchHomeTaskNext)) {
+            mResumedActivity.mLaunchHomeTaskNext = false;
+            return mStackSupervisor.resumeHomeActivity(null);
+        }
+
+        mStackSupervisor.resumeTopActivitiesLocked();
         return true;
     }
 
-    public ActivityManager.TaskThumbnails getTaskThumbnailsLocked(TaskRecord tr) {
-        TaskAccessInfo info = getTaskAccessInfoLocked(tr.taskId, true);
-        ActivityRecord resumed = mResumedActivity;
-        if (resumed != null && resumed.thumbHolder == tr) {
-            info.mainThumbnail = resumed.stack.screenshotActivities(resumed);
-        }
-        if (info.mainThumbnail == null) {
-            info.mainThumbnail = tr.lastThumbnail;
-        }
-        return info;
-    }
-
-    public Bitmap getTaskTopThumbnailLocked(TaskRecord tr) {
-        ActivityRecord resumed = mResumedActivity;
-        if (resumed != null && resumed.task == tr) {
-            // This task is the current resumed task, we just need to take
-            // a screenshot of it and return that.
-            return resumed.stack.screenshotActivities(resumed);
-        }
-        // Return the information about the task, to figure out the top
-        // thumbnail to return.
-        TaskAccessInfo info = getTaskAccessInfoLocked(tr.taskId, true);
-        if (info.numSubThumbbails <= 0) {
-            return info.mainThumbnail != null ? info.mainThumbnail : tr.lastThumbnail;
-        } else {
-            return info.subtasks.get(info.numSubThumbbails-1).holder.lastThumbnail;
-        }
-    }
-
-    public ActivityRecord removeTaskActivitiesLocked(int taskId, int subTaskIndex,
-            boolean taskRequired) {
-        TaskAccessInfo info = getTaskAccessInfoLocked(taskId, false);
-        if (info.root == null) {
-            if (taskRequired) {
-                Slog.w(TAG, "removeTaskLocked: unknown taskId " + taskId);
-            }
-            return null;
-        }
-
-        if (subTaskIndex < 0) {
-            // Just remove the entire task.
-            performClearTaskAtIndexLocked(taskId, info.rootIndex);
-            return info.root;
-        }
-
-        if (subTaskIndex >= info.subtasks.size()) {
-            if (taskRequired) {
-                Slog.w(TAG, "removeTaskLocked: unknown subTaskIndex " + subTaskIndex);
-            }
-            return null;
-        }
-
-        // Remove all of this task's activities starting at the sub task.
-        TaskAccessInfo.SubTask subtask = info.subtasks.get(subTaskIndex);
-        performClearTaskAtIndexLocked(taskId, subtask.index);
-        return subtask.activity;
-    }
-
-    public TaskAccessInfo getTaskAccessInfoLocked(int taskId, boolean inclThumbs) {
-        final TaskAccessInfo thumbs = new TaskAccessInfo();
-        // How many different sub-thumbnails?
-        final int NA = mHistory.size();
-        int j = 0;
-        ThumbnailHolder holder = null;
-        while (j < NA) {
-            ActivityRecord ar = mHistory.get(j);
-            if (!ar.finishing && ar.task.taskId == taskId) {
-                thumbs.root = ar;
-                thumbs.rootIndex = j;
-                holder = ar.thumbHolder;
-                if (holder != null) {
-                    thumbs.mainThumbnail = holder.lastThumbnail;
-                }
-                j++;
-                break;
-            }
-            j++;
-        }
-
-        if (j >= NA) {
-            return thumbs;
-        }
-
-        ArrayList<TaskAccessInfo.SubTask> subtasks = new ArrayList<TaskAccessInfo.SubTask>();
-        thumbs.subtasks = subtasks;
-        while (j < NA) {
-            ActivityRecord ar = mHistory.get(j);
-            j++;
-            if (ar.finishing) {
-                continue;
-            }
-            if (ar.task.taskId != taskId) {
-                break;
-            }
-            if (ar.thumbHolder != holder && holder != null) {
-                thumbs.numSubThumbbails++;
-                holder = ar.thumbHolder;
-                TaskAccessInfo.SubTask sub = new TaskAccessInfo.SubTask();
-                sub.holder = holder;
-                sub.activity = ar;
-                sub.index = j-1;
-                subtasks.add(sub);
-            }
-        }
-        if (thumbs.numSubThumbbails > 0) {
-            thumbs.retriever = new IThumbnailRetriever.Stub() {
-                public Bitmap getThumbnail(int index) {
-                    if (index < 0 || index >= thumbs.subtasks.size()) {
-                        return null;
-                    }
-                    TaskAccessInfo.SubTask sub = thumbs.subtasks.get(index);
-                    ActivityRecord resumed = mResumedActivity;
-                    if (resumed != null && resumed.thumbHolder == sub.holder) {
-                        return resumed.stack.screenshotActivities(resumed);
-                    }
-                    return sub.holder.lastThumbnail;
-                }
-            };
-        }
-        return thumbs;
-    }
-
-    private final void logStartActivity(int tag, ActivityRecord r,
+    static final void logStartActivity(int tag, ActivityRecord r,
             TaskRecord task) {
         final Uri data = r.intent.getData();
         final String strData = data != null ? data.toSafeString() : null;
@@ -4626,10 +3112,10 @@
                     "Skipping config check (will change): " + r);
             return true;
         }
-        
+
         if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
                 "Ensuring correct configuration: " + r);
-        
+
         // Short circuit: if the two configurations are the exact same
         // object (the common case), then there is nothing to do.
         Configuration newConfig = mService.mConfiguration;
@@ -4638,7 +3124,7 @@
                     "Configuration unchanged in " + r);
             return true;
         }
-        
+
         // We don't worry about activities that are finishing.
         if (r.finishing) {
             if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
@@ -4646,7 +3132,7 @@
             r.stopFreezingScreenLocked(false);
             return true;
         }
-        
+
         // Okay we now are going to make this activity have the new config.
         // But then we need to figure out how it needs to deal with that.
         Configuration oldConfig = r.configuration;
@@ -4672,7 +3158,7 @@
             r.forceNewConfig = false;
             return true;
         }
-        
+
         // Figure out how to handle the changes between the configurations.
         if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
             Slog.v(TAG, "Checking to restart " + r.info.name + ": changed=0x"
@@ -4712,12 +3198,12 @@
                 relaunchActivityLocked(r, r.configChangeFlags, false);
                 r.configChangeFlags = 0;
             }
-            
+
             // All done...  tell the caller we weren't able to keep this
             // activity around.
             return false;
         }
-        
+
         // Default case: the activity can handle this new configuration, so
         // hand it over.  Note that we don't need to give it the new
         // configuration, since we always send configuration changes to all
@@ -4732,11 +3218,11 @@
             }
         }
         r.stopFreezingScreenLocked(false);
-        
+
         return true;
     }
 
-    private final boolean relaunchActivityLocked(ActivityRecord r,
+    private boolean relaunchActivityLocked(ActivityRecord r,
             int changes, boolean andResume) {
         List<ResultInfo> results = null;
         List<Intent> newIntents = null;
@@ -4750,9 +3236,9 @@
         EventLog.writeEvent(andResume ? EventLogTags.AM_RELAUNCH_RESUME_ACTIVITY
                 : EventLogTags.AM_RELAUNCH_ACTIVITY, r.userId, System.identityHashCode(r),
                 r.task.taskId, r.shortComponentName);
-        
+
         r.startFreezingScreenLocked(r.app, 0);
-        
+
         try {
             if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG,
                     (andResume ? "Relaunching to RESUMED " : "Relaunching to PAUSED ")
@@ -4770,9 +3256,6 @@
         if (andResume) {
             r.results = null;
             r.newIntents = null;
-            if (mMainStack) {
-                mService.reportResumedActivityLocked(r);
-            }
             r.state = ActivityState.RESUMED;
         } else {
             mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
@@ -4781,8 +3264,304 @@
 
         return true;
     }
-    
-    public void dismissKeyguardOnNextActivityLocked() {
-        mDismissKeyguardOnNextActivity = true;
+
+    boolean willActivityBeVisibleLocked(IBinder token) {
+        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
+            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+                final ActivityRecord r = activities.get(activityNdx);
+                if (r.appToken == token) {
+                        return true;
+                }
+                if (r.fullscreen && !r.finishing) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    void closeSystemDialogsLocked() {
+        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
+            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+                final ActivityRecord r = activities.get(activityNdx);
+                if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
+                    finishActivityLocked(r, Activity.RESULT_CANCELED, null, "close-sys", true);
+                }
+            }
+        }
+    }
+
+    boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
+        boolean didSomething = false;
+        TaskRecord lastTask = null;
+        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
+            int numActivities = activities.size();
+            for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
+                ActivityRecord r = activities.get(activityNdx);
+                final boolean samePackage = r.packageName.equals(name)
+                        || (name == null && r.userId == userId);
+                if ((userId == UserHandle.USER_ALL || r.userId == userId)
+                        && (samePackage || r.task == lastTask)
+                        && (r.app == null || evenPersistent || !r.app.persistent)) {
+                    if (!doit) {
+                        if (r.finishing) {
+                            // If this activity is just finishing, then it is not
+                            // interesting as far as something to stop.
+                            continue;
+                        }
+                        return true;
+                    }
+                    didSomething = true;
+                    Slog.i(TAG, "  Force finishing activity " + r);
+                    if (samePackage) {
+                        if (r.app != null) {
+                            r.app.removed = true;
+                        }
+                        r.app = null;
+                    }
+                    lastTask = r.task;
+                    if (finishActivityLocked(r, Activity.RESULT_CANCELED, null, "force-stop",
+                            true)) {
+                        // r has been deleted from mActivities, accommodate.
+                        --numActivities;
+                        --activityNdx;
+                    }
+                }
+            }
+        }
+        return didSomething;
+    }
+
+    ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver,
+            PendingThumbnailsRecord pending, List<RunningTaskInfo> list) {
+        ActivityRecord topRecord = null;
+        for (int taskNdx = mTaskHistory.size() - 1; maxNum > 0 && taskNdx >= 0;
+                --maxNum, --taskNdx) {
+            final TaskRecord task = mTaskHistory.get(taskNdx);
+            ActivityRecord r = null;
+            ActivityRecord top = null;
+            int numActivities = 0;
+            int numRunning = 0;
+            final ArrayList<ActivityRecord> activities = task.mActivities;
+            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+                r = activities.get(activityNdx);
+
+                // Initialize state for next task if needed.
+                if (top == null || (top.state == ActivityState.INITIALIZING)) {
+                    top = r;
+                    numActivities = numRunning = 0;
+                }
+
+                // Add 'r' into the current task.
+                numActivities++;
+                if (r.app != null && r.app.thread != null) {
+                    numRunning++;
+                }
+
+                if (localLOGV) Slog.v(
+                    TAG, r.intent.getComponent().flattenToShortString()
+                    + ": task=" + r.task);
+            }
+
+            RunningTaskInfo ci = new RunningTaskInfo();
+            ci.id = task.taskId;
+            ci.baseActivity = r.intent.getComponent();
+            ci.topActivity = top.intent.getComponent();
+            if (top.thumbHolder != null) {
+                ci.description = top.thumbHolder.lastDescription;
+            }
+            ci.numActivities = numActivities;
+            ci.numRunning = numRunning;
+            //System.out.println(
+            //    "#" + maxNum + ": " + " descr=" + ci.description);
+            if (receiver != null) {
+                if (localLOGV) Slog.v(
+                    TAG, "State=" + top.state + "Idle=" + top.idle
+                    + " app=" + top.app
+                    + " thr=" + (top.app != null ? top.app.thread : null));
+                if (top.state == ActivityState.RESUMED || top.state == ActivityState.PAUSING) {
+                    if (top.idle && top.app != null && top.app.thread != null) {
+                        topRecord = top;
+                    } else {
+                        top.thumbnailNeeded = true;
+                    }
+                }
+                pending.pendingRecords.add(top);
+            }
+            list.add(ci);
+        }
+        return topRecord;
+    }
+
+    public void unhandledBackLocked() {
+        final int top = mTaskHistory.size() - 1;
+        if (DEBUG_SWITCH) Slog.d(
+            TAG, "Performing unhandledBack(): top activity at " + top);
+        if (top >= 0) {
+            final ArrayList<ActivityRecord> activities = mTaskHistory.get(top).mActivities;
+            int activityTop = activities.size() - 1;
+            if (activityTop > 0) {
+                finishActivityLocked(activities.get(activityTop), Activity.RESULT_CANCELED, null,
+                        "unhandled-back", true);
+            }
+        }
+    }
+
+    void handleAppDiedLocked(ProcessRecord app, boolean restarting) {
+        if (!containsApp(app)) {
+            return;
+        }
+        // TODO: handle the case where an app spans multiple stacks.
+        if (mPausingActivity != null && mPausingActivity.app == app) {
+            if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG,
+                    "App died while pausing: " + mPausingActivity);
+            mPausingActivity = null;
+        }
+        if (mLastPausedActivity != null && mLastPausedActivity.app == app) {
+            mLastPausedActivity = null;
+            mLastNoHistoryActivity = null;
+        }
+        final ActivityRecord top = topRunningActivityLocked(null);
+        final boolean launchHomeTaskNext =
+                top != null && top.app == app && top.mLaunchHomeTaskNext;
+
+        // Remove this application's activities from active lists.
+        boolean hasVisibleActivities = removeHistoryRecordsForAppLocked(app);
+
+        if (!restarting) {
+            ActivityStack stack = mStackSupervisor.getFocusedStack();
+            if (stack == null || launchHomeTaskNext) {
+                mStackSupervisor.resumeHomeActivity(null);
+            } else if (!mStackSupervisor.resumeTopActivitiesLocked(stack, null, null)) {
+                // If there was nothing to resume, and we are not already
+                // restarting this process, but there is a visible activity that
+                // is hosted by the process...  then make sure all visible
+                // activities are running, taking care of restarting this
+                // process.
+                if (hasVisibleActivities) {
+                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
+                }
+            }
+        }
+    }
+
+    void handleAppCrashLocked(ProcessRecord app) {
+        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
+            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+                final ActivityRecord r = activities.get(activityNdx);
+                if (r.app == app) {
+                    Slog.w(TAG, "  Force finishing activity "
+                            + r.intent.getComponent().flattenToShortString());
+                    finishActivityLocked(r, Activity.RESULT_CANCELED, null, "crashed", false);
+                }
+            }
+        }
+    }
+
+    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
+            boolean dumpClient, String dumpPackage, boolean needSep, String header) {
+        boolean printed = false;
+        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+            final TaskRecord task = mTaskHistory.get(taskNdx);
+            printed |= ActivityStackSupervisor.dumpHistoryList(fd, pw,
+                    mTaskHistory.get(taskNdx).mActivities, "    ", "Hist", true, !dumpAll,
+                    dumpClient, dumpPackage, needSep, header,
+                    "    Task id #" + task.taskId);
+            if (printed) {
+                header = null;
+            }
+        }
+        return printed;
+    }
+
+    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
+        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
+
+        if ("all".equals(name)) {
+            for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+                activities.addAll(mTaskHistory.get(taskNdx).mActivities);
+            }
+        } else if ("top".equals(name)) {
+            final int top = mTaskHistory.size() - 1;
+            if (top >= 0) {
+                final ArrayList<ActivityRecord> list = mTaskHistory.get(top).mActivities;
+                int listTop = list.size() - 1;
+                if (listTop >= 0) {
+                    activities.add(list.get(listTop));
+                }
+            }
+        } else {
+            ItemMatcher matcher = new ItemMatcher();
+            matcher.build(name);
+
+            for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+                for (ActivityRecord r1 : mTaskHistory.get(taskNdx).mActivities) {
+                    if (matcher.match(r1, r1.intent.getComponent())) {
+                        activities.add(r1);
+                    }
+                }
+            }
+        }
+
+        return activities;
+    }
+
+    ActivityRecord restartPackage(String packageName) {
+        ActivityRecord starting = topRunningActivityLocked(null);
+
+        // All activities that came from the package must be
+        // restarted as if there was a config change.
+        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+            final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
+            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+                final ActivityRecord a = activities.get(activityNdx);
+                if (a.info.packageName.equals(packageName)) {
+                    a.forceNewConfig = true;
+                    if (starting != null && a == starting && a.visible) {
+                        a.startFreezingScreenLocked(starting.app,
+                                ActivityInfo.CONFIG_SCREEN_LAYOUT);
+                    }
+                }
+            }
+        }
+
+        return starting;
+    }
+
+    boolean removeTask(TaskRecord task) {
+        mTaskHistory.remove(task);
+        return mTaskHistory.isEmpty();
+    }
+
+    TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent, boolean toTop) {
+        TaskRecord task = new TaskRecord(taskId, info, intent);
+        addTask(task, toTop);
+        return task;
+    }
+
+    ArrayList<TaskRecord> getAllTasks() {
+        return new ArrayList<TaskRecord>(mTaskHistory);
+    }
+
+    void addTask(final TaskRecord task, final boolean toTop) {
+        task.stack = this;
+        if (toTop) {
+            insertTaskAtTop(task);
+        } else {
+            mTaskHistory.add(0, task);
+        }
+    }
+
+    public int getStackId() {
+        return mStackId;
+    }
+
+    @Override
+    public String toString() {
+        return "stackId=" + mStackId + " tasks=" + mTaskHistory;
     }
 }
diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java
new file mode 100644
index 0000000..e0eb2c4
--- /dev/null
+++ b/services/java/com/android/server/am/ActivityStackSupervisor.java
@@ -0,0 +1,2609 @@
+/*
+ * 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.server.am;
+
+import static android.Manifest.permission.START_ANY_ACTIVITY;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static com.android.server.am.ActivityManagerService.localLOGV;
+import static com.android.server.am.ActivityManagerService.DEBUG_CONFIGURATION;
+import static com.android.server.am.ActivityManagerService.DEBUG_FOCUS;
+import static com.android.server.am.ActivityManagerService.DEBUG_PAUSE;
+import static com.android.server.am.ActivityManagerService.DEBUG_RESULTS;
+import static com.android.server.am.ActivityManagerService.DEBUG_STACK;
+import static com.android.server.am.ActivityManagerService.DEBUG_SWITCH;
+import static com.android.server.am.ActivityManagerService.DEBUG_TASKS;
+import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING;
+import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
+import static com.android.server.am.ActivityManagerService.TAG;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.ActivityOptions;
+import android.app.AppGlobals;
+import android.app.IActivityManager;
+import android.app.IApplicationThread;
+import android.app.IThumbnailReceiver;
+import android.app.PendingIntent;
+import android.app.ActivityManager.RunningTaskInfo;
+import android.app.IActivityManager.WaitResult;
+import android.app.ResultInfo;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.IIntentSender;
+import android.content.Intent;
+import android.content.IntentSender;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.Configuration;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Debug;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.ParcelFileDescriptor;
+import android.os.PowerManager;
+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 android.util.SparseArray;
+
+import com.android.internal.app.HeavyWeightSwitcherActivity;
+import com.android.internal.os.TransferPipe;
+import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
+import com.android.server.am.ActivityStack.ActivityState;
+import com.android.server.wm.StackBox;
+import com.android.server.wm.WindowManagerService;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+public final class ActivityStackSupervisor {
+    static final boolean DEBUG = ActivityManagerService.DEBUG || false;
+    static final boolean DEBUG_ADD_REMOVE = DEBUG || false;
+    static final boolean DEBUG_APP = DEBUG || false;
+    static final boolean DEBUG_SAVED_STATE = DEBUG || false;
+    static final boolean DEBUG_STATES = DEBUG || false;
+    static final boolean DEBUG_IDLE = DEBUG || false;
+
+    public static final int HOME_STACK_ID = 0;
+
+    /** How long we wait until giving up on the last activity telling us it is idle. */
+    static final int IDLE_TIMEOUT = 10*1000;
+
+    /** How long we can hold the sleep wake lock before giving up. */
+    static final int SLEEP_TIMEOUT = 5*1000;
+
+    // How long we can hold the launch wake lock before giving up.
+    static final int LAUNCH_TIMEOUT = 10*1000;
+
+    static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
+    static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
+    static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
+    static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
+    static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4;
+
+    // For debugging to make sure the caller when acquiring/releasing our
+    // wake lock is the system process.
+    static final boolean VALIDATE_WAKE_LOCK_CALLER = false;
+
+    final ActivityManagerService mService;
+    final Context mContext;
+    final Looper mLooper;
+
+    final ActivityStackSupervisorHandler mHandler;
+
+    /** Short cut */
+    WindowManagerService mWindowManager;
+
+    /** Dismiss the keyguard after the next activity is displayed? */
+    private boolean mDismissKeyguardOnNextActivity = false;
+
+    /** Identifier counter for all ActivityStacks */
+    private int mLastStackId = HOME_STACK_ID;
+
+    /** Task identifier that activities are currently being started in.  Incremented each time a
+     * new task is created. */
+    private int mCurTaskId = 0;
+
+    /** The current user */
+    private int mCurrentUser;
+
+    /** The stack containing the launcher app */
+    private ActivityStack mHomeStack;
+
+    /** The non-home stack currently receiving input or launching the next activity. If home is
+     * in front then mHomeStack overrides mFocusedStack.
+     * DO NOT ACCESS DIRECTLY - It may be null, use getFocusedStack() */
+    private ActivityStack mFocusedStack;
+
+    /** All the non-launcher stacks */
+    private ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
+
+    private static final int STACK_STATE_HOME_IN_FRONT = 0;
+    private static final int STACK_STATE_HOME_TO_BACK = 1;
+    private static final int STACK_STATE_HOME_IN_BACK = 2;
+    private static final int STACK_STATE_HOME_TO_FRONT = 3;
+    private int mStackState = STACK_STATE_HOME_IN_FRONT;
+
+    /** List of activities that are waiting for a new activity to become visible before completing
+     * whatever operation they are supposed to do. */
+    final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<ActivityRecord>();
+
+    /** List of processes waiting to find out about the next visible activity. */
+    final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible =
+            new ArrayList<IActivityManager.WaitResult>();
+
+    /** List of processes waiting to find out about the next launched activity. */
+    final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched =
+            new ArrayList<IActivityManager.WaitResult>();
+
+    /** List of activities that are ready to be stopped, but waiting for the next activity to
+     * settle down before doing so. */
+    final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<ActivityRecord>();
+
+    /** List of activities that are ready to be finished, but waiting for the previous activity to
+     * settle down before doing so.  It contains ActivityRecord objects. */
+    final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<ActivityRecord>();
+
+    /** List of activities that are in the process of going to sleep. */
+    final ArrayList<ActivityRecord> mGoingToSleepActivities = new ArrayList<ActivityRecord>();
+
+    /** List of ActivityRecord objects that have been finished and must still report back to a
+     * pending thumbnail receiver. */
+    final ArrayList<ActivityRecord> mCancelledThumbnails = new ArrayList<ActivityRecord>();
+
+    /** Used on user changes */
+    final ArrayList<UserStartedState> mStartingUsers = new ArrayList<UserStartedState>();
+
+    /** Set to indicate whether to issue an onUserLeaving callback when a newly launched activity
+     * is being brought in front of us. */
+    boolean mUserLeaving = false;
+
+    /** Set when we have taken too long waiting to go to sleep. */
+    boolean mSleepTimeout = false;
+
+    /**
+     * We don't want to allow the device to go to sleep while in the process
+     * of launching an activity.  This is primarily to allow alarm intent
+     * receivers to launch an activity and get that to run before the device
+     * goes back to sleep.
+     */
+    final PowerManager.WakeLock mLaunchingActivity;
+
+    /**
+     * Set when the system is going to sleep, until we have
+     * successfully paused the current activity and released our wake lock.
+     * At that point the system is allowed to actually sleep.
+     */
+    final PowerManager.WakeLock mGoingToSleep;
+
+    /**
+     * The name of the current home activity for each user.
+     * TODO: Remove entries when user is deleted.
+     */
+    final SparseArray<String> mHomePackageNames = new SparseArray<String>();
+
+    public ActivityStackSupervisor(ActivityManagerService service, Context context,
+            Looper looper) {
+        mService = service;
+        mContext = context;
+        mLooper = looper;
+        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
+        mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
+        mHandler = new ActivityStackSupervisorHandler(looper);
+        if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
+            throw new IllegalStateException("Calling must be system uid");
+        }
+        mLaunchingActivity =
+                pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
+        mLaunchingActivity.setReferenceCounted(false);
+    }
+
+    void setWindowManager(WindowManagerService wm) {
+        mWindowManager = wm;
+        mHomeStack = new ActivityStack(mService, mContext, mLooper, HOME_STACK_ID);
+        mStacks.add(mHomeStack);
+    }
+
+    void dismissKeyguard() {
+        if (mDismissKeyguardOnNextActivity) {
+            mDismissKeyguardOnNextActivity = false;
+            mWindowManager.dismissKeyguard();
+        }
+    }
+
+    ActivityStack getFocusedStack() {
+        if (mFocusedStack == null) {
+            return mHomeStack;
+        }
+        switch (mStackState) {
+            case STACK_STATE_HOME_IN_FRONT:
+            case STACK_STATE_HOME_TO_FRONT:
+                return mHomeStack;
+            case STACK_STATE_HOME_IN_BACK:
+            case STACK_STATE_HOME_TO_BACK:
+            default:
+                return mFocusedStack;
+        }
+    }
+
+    ActivityStack getLastStack() {
+        switch (mStackState) {
+            case STACK_STATE_HOME_IN_FRONT:
+            case STACK_STATE_HOME_TO_BACK:
+                return mHomeStack;
+            case STACK_STATE_HOME_TO_FRONT:
+            case STACK_STATE_HOME_IN_BACK:
+            default:
+                return mFocusedStack;
+        }
+    }
+
+    boolean isFrontStack(ActivityStack stack) {
+        return !(stack.isHomeStack() ^ getFocusedStack().isHomeStack());
+    }
+
+    void moveHomeStack(boolean toFront) {
+        final boolean homeInFront = isFrontStack(mHomeStack);
+        if (homeInFront ^ toFront) {
+            if (DEBUG_STACK) Slog.d(TAG, "moveHomeTask: mStackState old=" +
+                    stackStateToString(mStackState) + " new=" + stackStateToString(homeInFront ?
+                    STACK_STATE_HOME_TO_BACK : STACK_STATE_HOME_TO_FRONT));
+            mStackState = homeInFront ? STACK_STATE_HOME_TO_BACK : STACK_STATE_HOME_TO_FRONT;
+        }
+    }
+
+    boolean resumeHomeActivity(ActivityRecord prev) {
+        moveHomeStack(true);
+        if (prev != null) {
+            prev.mLaunchHomeTaskNext = false;
+        }
+        mHomeStack.moveHomeTaskToTop();
+        ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
+        if (r != null) {
+            mService.setFocusedActivityLocked(r);
+            return resumeTopActivitiesLocked(mHomeStack, prev, null);
+        }
+        return mService.startHomeActivityLocked(mCurrentUser);
+    }
+
+    final void setLaunchHomeTaskNextFlag(ActivityRecord sourceRecord, ActivityRecord r,
+            ActivityStack stack) {
+        if (stack == mHomeStack) {
+            return;
+        }
+        if ((sourceRecord == null && getLastStack() == mHomeStack) ||
+                (sourceRecord != null && sourceRecord.isHomeActivity())) {
+            if (r == null) {
+                r = stack.topRunningActivityLocked(null);
+            }
+            if (r != null && !r.isHomeActivity() && r.isRootActivity()) {
+                r.mLaunchHomeTaskNext = true;
+            }
+        }
+    }
+
+    void setDismissKeyguard(boolean dismiss) {
+        mDismissKeyguardOnNextActivity = dismiss;
+    }
+
+    TaskRecord anyTaskForIdLocked(int id) {
+        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            ActivityStack stack = mStacks.get(stackNdx);
+            TaskRecord task = stack.taskForIdLocked(id);
+            if (task != null) {
+                return task;
+            }
+        }
+        return null;
+    }
+
+    ActivityRecord isInAnyStackLocked(IBinder token) {
+        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            final ActivityRecord r = mStacks.get(stackNdx).isInStackLocked(token);
+            if (r != null) {
+                return r;
+            }
+        }
+        return null;
+    }
+
+    int getNextTaskId() {
+        do {
+            mCurTaskId++;
+            if (mCurTaskId <= 0) {
+                mCurTaskId = 1;
+            }
+        } while (anyTaskForIdLocked(mCurTaskId) != null);
+        return mCurTaskId;
+    }
+
+    void removeTask(TaskRecord task) {
+        mWindowManager.removeTask(task.taskId);
+        final ActivityStack stack = task.stack;
+        final ActivityRecord r = stack.mResumedActivity;
+        if (r != null && r.task == task) {
+            stack.mResumedActivity = null;
+        }
+        if (stack.removeTask(task) && !stack.isHomeStack()) {
+            if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing stack " + stack);
+            mStacks.remove(stack);
+            final int stackId = stack.mStackId;
+            final int nextStackId = mWindowManager.removeStack(stackId);
+            // TODO: Perhaps we need to let the ActivityManager determine the next focus...
+            if (mFocusedStack == null || mFocusedStack.mStackId == stackId) {
+                // If this is the last app stack, set mFocusedStack to null.
+                mFocusedStack = nextStackId == HOME_STACK_ID ? null : getStack(nextStackId);
+            }
+        }
+    }
+
+    ActivityRecord resumedAppLocked() {
+        ActivityStack stack = getFocusedStack();
+        if (stack == null) {
+            return null;
+        }
+        ActivityRecord resumedActivity = stack.mResumedActivity;
+        if (resumedActivity == null || resumedActivity.app == null) {
+            resumedActivity = stack.mPausingActivity;
+            if (resumedActivity == null || resumedActivity.app == null) {
+                resumedActivity = stack.topRunningActivityLocked(null);
+            }
+        }
+        return resumedActivity;
+    }
+
+    boolean attachApplicationLocked(ProcessRecord app, boolean headless) throws Exception {
+        boolean didSomething = false;
+        final String processName = app.processName;
+        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            final ActivityStack stack = mStacks.get(stackNdx);
+            if (!isFrontStack(stack)) {
+                continue;
+            }
+            ActivityRecord hr = stack.topRunningActivityLocked(null);
+            if (hr != null) {
+                if (hr.app == null && app.uid == hr.info.applicationInfo.uid
+                        && processName.equals(hr.processName)) {
+                    try {
+                        if (headless) {
+                            Slog.e(TAG, "Starting activities not supported on headless device: "
+                                    + hr);
+                        } else if (realStartActivityLocked(hr, app, true, true)) {
+                            didSomething = true;
+                        }
+                    } catch (Exception e) {
+                        Slog.w(TAG, "Exception in new application when starting activity "
+                              + hr.intent.getComponent().flattenToShortString(), e);
+                        throw e;
+                    }
+                }
+            }
+        }
+        if (!didSomething) {
+            ensureActivitiesVisibleLocked(null, 0);
+        }
+        return didSomething;
+    }
+
+    boolean allResumedActivitiesIdle() {
+        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            final ActivityStack stack = mStacks.get(stackNdx);
+            if (!isFrontStack(stack)) {
+                continue;
+            }
+            final ActivityRecord resumedActivity = stack.mResumedActivity;
+            if (resumedActivity == null || !resumedActivity.idle) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    boolean allResumedActivitiesComplete() {
+        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            final ActivityStack stack = mStacks.get(stackNdx);
+            if (isFrontStack(stack)) {
+                final ActivityRecord r = stack.mResumedActivity;
+                if (r != null && r.state != ActivityState.RESUMED) {
+                    return false;
+                }
+            }
+        }
+        // TODO: Not sure if this should check if all Paused are complete too.
+        switch (mStackState) {
+            case STACK_STATE_HOME_TO_BACK:
+                if (DEBUG_STACK) Slog.d(TAG, "allResumedActivitiesComplete: mStackState old=" +
+                        stackStateToString(STACK_STATE_HOME_TO_BACK) + " new=" +
+                        stackStateToString(STACK_STATE_HOME_IN_BACK));
+                mStackState = STACK_STATE_HOME_IN_BACK;
+                break;
+            case STACK_STATE_HOME_TO_FRONT:
+                if (DEBUG_STACK) Slog.d(TAG, "allResumedActivitiesComplete: mStackState old=" +
+                        stackStateToString(STACK_STATE_HOME_TO_FRONT) + " new=" +
+                        stackStateToString(STACK_STATE_HOME_IN_FRONT));
+                mStackState = STACK_STATE_HOME_IN_FRONT;
+                break;
+        }
+        return true;
+    }
+
+    boolean allResumedActivitiesVisible() {
+        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            final ActivityStack stack = mStacks.get(stackNdx);
+            final ActivityRecord r = stack.mResumedActivity;
+            if (r != null && (!r.nowVisible || r.waitingVisible)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    boolean pauseBackStacks(boolean userLeaving) {
+        boolean someActivityPaused = false;
+        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            final ActivityStack stack = mStacks.get(stackNdx);
+            if (!isFrontStack(stack) && stack.mResumedActivity != null) {
+                if (DEBUG_STATES) Slog.d(TAG, "pauseBackStacks: stack=" + stack +
+                        " mResumedActivity=" + stack.mResumedActivity);
+                stack.startPausingLocked(userLeaving, false);
+                someActivityPaused = true;
+            }
+        }
+        return someActivityPaused;
+    }
+
+    boolean allPausedActivitiesComplete() {
+        boolean pausing = true;
+        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            final ActivityStack stack = mStacks.get(stackNdx);
+            final ActivityRecord r = stack.mPausingActivity;
+            if (r != null && r.state != ActivityState.PAUSED
+                    && r.state != ActivityState.STOPPED
+                    && r.state != ActivityState.STOPPING) {
+                if (DEBUG_STATES) {
+                    Slog.d(TAG, "allPausedActivitiesComplete: r=" + r + " state=" + r.state);
+                    pausing = false;
+                } else {
+                    return false;
+                }
+            }
+        }
+        return pausing;
+    }
+
+    void reportActivityVisibleLocked(ActivityRecord r) {
+        for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) {
+            WaitResult w = mWaitingActivityVisible.get(i);
+            w.timeout = false;
+            if (r != null) {
+                w.who = new ComponentName(r.info.packageName, r.info.name);
+            }
+            w.totalTime = SystemClock.uptimeMillis() - w.thisTime;
+            w.thisTime = w.totalTime;
+        }
+        mService.notifyAll();
+        dismissKeyguard();
+    }
+
+    void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r,
+            long thisTime, long totalTime) {
+        for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
+            WaitResult w = mWaitingActivityLaunched.remove(i);
+            w.timeout = timeout;
+            if (r != null) {
+                w.who = new ComponentName(r.info.packageName, r.info.name);
+            }
+            w.thisTime = thisTime;
+            w.totalTime = totalTime;
+        }
+        mService.notifyAll();
+    }
+
+    ActivityRecord topRunningActivityLocked() {
+        final ActivityStack focusedStack = getFocusedStack();
+        ActivityRecord r = focusedStack.topRunningActivityLocked(null);
+        if (r != null) {
+            return r;
+        }
+
+        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            final ActivityStack stack = mStacks.get(stackNdx);
+            if (stack != focusedStack && isFrontStack(stack)) {
+                r = stack.topRunningActivityLocked(null);
+                if (r != null) {
+                    return r;
+                }
+            }
+        }
+        return null;
+    }
+
+    ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver,
+            PendingThumbnailsRecord pending, List<RunningTaskInfo> list) {
+        ActivityRecord r = null;
+        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            final ActivityStack stack = mStacks.get(stackNdx);
+            final ActivityRecord ar =
+                    stack.getTasksLocked(maxNum - list.size(), receiver, pending, list);
+            if (isFrontStack(stack)) {
+                r = ar;
+            }
+        }
+        return r;
+    }
+
+    ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
+            String profileFile, ParcelFileDescriptor profileFd, int userId) {
+        // Collect information about the target of the Intent.
+        ActivityInfo aInfo;
+        try {
+            ResolveInfo rInfo =
+                AppGlobals.getPackageManager().resolveIntent(
+                        intent, resolvedType,
+                        PackageManager.MATCH_DEFAULT_ONLY
+                                    | ActivityManagerService.STOCK_PM_FLAGS, userId);
+            aInfo = rInfo != null ? rInfo.activityInfo : null;
+        } catch (RemoteException e) {
+            aInfo = null;
+        }
+
+        if (aInfo != null) {
+            // Store the found target back into the intent, because now that
+            // we have it we never want to do this again.  For example, if the
+            // user navigates back to this point in the history, we should
+            // always restart the exact same activity.
+            intent.setComponent(new ComponentName(
+                    aInfo.applicationInfo.packageName, aInfo.name));
+
+            // Don't debug things in the system process
+            if ((startFlags&ActivityManager.START_FLAG_DEBUG) != 0) {
+                if (!aInfo.processName.equals("system")) {
+                    mService.setDebugApp(aInfo.processName, true, false);
+                }
+            }
+
+            if ((startFlags&ActivityManager.START_FLAG_OPENGL_TRACES) != 0) {
+                if (!aInfo.processName.equals("system")) {
+                    mService.setOpenGlTraceApp(aInfo.applicationInfo, aInfo.processName);
+                }
+            }
+
+            if (profileFile != null) {
+                if (!aInfo.processName.equals("system")) {
+                    mService.setProfileApp(aInfo.applicationInfo, aInfo.processName,
+                            profileFile, profileFd,
+                            (startFlags&ActivityManager.START_FLAG_AUTO_STOP_PROFILER) != 0);
+                }
+            }
+        }
+        return aInfo;
+    }
+
+    void startHomeActivity(Intent intent, ActivityInfo aInfo) {
+        moveHomeStack(true);
+        startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0,
+                null, false, null);
+    }
+
+    final int startActivityMayWait(IApplicationThread caller, int callingUid,
+            String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
+            String resultWho, int requestCode, int startFlags, String profileFile,
+            ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
+            Bundle options, int userId) {
+        // Refuse possible leaked file descriptors
+        if (intent != null && intent.hasFileDescriptors()) {
+            throw new IllegalArgumentException("File descriptors passed in Intent");
+        }
+        boolean componentSpecified = intent.getComponent() != null;
+
+        // Don't modify the client's object!
+        intent = new Intent(intent);
+
+        // Collect information about the target of the Intent.
+        ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
+                profileFile, profileFd, userId);
+
+        synchronized (mService) {
+            int callingPid;
+            if (callingUid >= 0) {
+                callingPid = -1;
+            } else if (caller == null) {
+                callingPid = Binder.getCallingPid();
+                callingUid = Binder.getCallingUid();
+            } else {
+                callingPid = callingUid = -1;
+            }
+
+            final ActivityStack stack = getFocusedStack();
+            stack.mConfigWillChange = config != null
+                    && mService.mConfiguration.diff(config) != 0;
+            if (DEBUG_CONFIGURATION) Slog.v(TAG,
+                    "Starting activity when config will change = " + stack.mConfigWillChange);
+
+            final long origId = Binder.clearCallingIdentity();
+
+            if (aInfo != null &&
+                    (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
+                // This may be a heavy-weight process!  Check to see if we already
+                // have another, different heavy-weight process running.
+                if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
+                    if (mService.mHeavyWeightProcess != null &&
+                            (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
+                            !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
+                        int realCallingUid = callingUid;
+                        if (caller != null) {
+                            ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
+                            if (callerApp != null) {
+                                realCallingUid = callerApp.info.uid;
+                            } else {
+                                Slog.w(TAG, "Unable to find app for caller " + caller
+                                      + " (pid=" + callingPid + ") when starting: "
+                                      + intent.toString());
+                                ActivityOptions.abort(options);
+                                return ActivityManager.START_PERMISSION_DENIED;
+                            }
+                        }
+
+                        IIntentSender target = mService.getIntentSenderLocked(
+                                ActivityManager.INTENT_SENDER_ACTIVITY, "android",
+                                realCallingUid, userId, null, null, 0, new Intent[] { intent },
+                                new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
+                                | PendingIntent.FLAG_ONE_SHOT, null);
+
+                        Intent newIntent = new Intent();
+                        if (requestCode >= 0) {
+                            // Caller is requesting a result.
+                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
+                        }
+                        newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
+                                new IntentSender(target));
+                        if (mService.mHeavyWeightProcess.activities.size() > 0) {
+                            ActivityRecord hist = mService.mHeavyWeightProcess.activities.get(0);
+                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
+                                    hist.packageName);
+                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
+                                    hist.task.taskId);
+                        }
+                        newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
+                                aInfo.packageName);
+                        newIntent.setFlags(intent.getFlags());
+                        newIntent.setClassName("android",
+                                HeavyWeightSwitcherActivity.class.getName());
+                        intent = newIntent;
+                        resolvedType = null;
+                        caller = null;
+                        callingUid = Binder.getCallingUid();
+                        callingPid = Binder.getCallingPid();
+                        componentSpecified = true;
+                        try {
+                            ResolveInfo rInfo =
+                                AppGlobals.getPackageManager().resolveIntent(
+                                        intent, null,
+                                        PackageManager.MATCH_DEFAULT_ONLY
+                                        | ActivityManagerService.STOCK_PM_FLAGS, userId);
+                            aInfo = rInfo != null ? rInfo.activityInfo : null;
+                            aInfo = mService.getActivityInfoForUser(aInfo, userId);
+                        } catch (RemoteException e) {
+                            aInfo = null;
+                        }
+                    }
+                }
+            }
+
+            int res = startActivityLocked(caller, intent, resolvedType,
+                    aInfo, resultTo, resultWho, requestCode, callingPid, callingUid,
+                    callingPackage, startFlags, options, componentSpecified, null);
+
+            if (stack.mConfigWillChange) {
+                // If the caller also wants to switch to a new configuration,
+                // do so now.  This allows a clean switch, as we are waiting
+                // for the current activity to pause (so we will not destroy
+                // it), and have not yet started the next activity.
+                mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
+                        "updateConfiguration()");
+                stack.mConfigWillChange = false;
+                if (DEBUG_CONFIGURATION) Slog.v(TAG,
+                        "Updating to new configuration after starting activity.");
+                mService.updateConfigurationLocked(config, null, false, false);
+            }
+
+            Binder.restoreCallingIdentity(origId);
+
+            if (outResult != null) {
+                outResult.result = res;
+                if (res == ActivityManager.START_SUCCESS) {
+                    mWaitingActivityLaunched.add(outResult);
+                    do {
+                        try {
+                            mService.wait();
+                        } catch (InterruptedException e) {
+                        }
+                    } while (!outResult.timeout && outResult.who == null);
+                } else if (res == ActivityManager.START_TASK_TO_FRONT) {
+                    ActivityRecord r = stack.topRunningActivityLocked(null);
+                    if (r.nowVisible) {
+                        outResult.timeout = false;
+                        outResult.who = new ComponentName(r.info.packageName, r.info.name);
+                        outResult.totalTime = 0;
+                        outResult.thisTime = 0;
+                    } else {
+                        outResult.thisTime = SystemClock.uptimeMillis();
+                        mWaitingActivityVisible.add(outResult);
+                        do {
+                            try {
+                                mService.wait();
+                            } catch (InterruptedException e) {
+                            }
+                        } while (!outResult.timeout && outResult.who == null);
+                    }
+                }
+            }
+
+            return res;
+        }
+    }
+
+    final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
+            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
+            Bundle options, int userId) {
+        if (intents == null) {
+            throw new NullPointerException("intents is null");
+        }
+        if (resolvedTypes == null) {
+            throw new NullPointerException("resolvedTypes is null");
+        }
+        if (intents.length != resolvedTypes.length) {
+            throw new IllegalArgumentException("intents are length different than resolvedTypes");
+        }
+
+
+        int callingPid;
+        if (callingUid >= 0) {
+            callingPid = -1;
+        } else if (caller == null) {
+            callingPid = Binder.getCallingPid();
+            callingUid = Binder.getCallingUid();
+        } else {
+            callingPid = callingUid = -1;
+        }
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (mService) {
+                ActivityRecord[] outActivity = new ActivityRecord[1];
+                for (int i=0; i<intents.length; i++) {
+                    Intent intent = intents[i];
+                    if (intent == null) {
+                        continue;
+                    }
+
+                    // Refuse possible leaked file descriptors
+                    if (intent != null && intent.hasFileDescriptors()) {
+                        throw new IllegalArgumentException("File descriptors passed in Intent");
+                    }
+
+                    boolean componentSpecified = intent.getComponent() != null;
+
+                    // Don't modify the client's object!
+                    intent = new Intent(intent);
+
+                    // Collect information about the target of the Intent.
+                    ActivityInfo aInfo = resolveActivity(intent, resolvedTypes[i],
+                            0, null, null, userId);
+                    // TODO: New, check if this is correct
+                    aInfo = mService.getActivityInfoForUser(aInfo, userId);
+
+                    if (aInfo != null &&
+                            (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE)
+                                    != 0) {
+                        throw new IllegalArgumentException(
+                                "FLAG_CANT_SAVE_STATE not supported here");
+                    }
+
+                    Bundle theseOptions;
+                    if (options != null && i == intents.length-1) {
+                        theseOptions = options;
+                    } else {
+                        theseOptions = null;
+                    }
+                    int res = startActivityLocked(caller, intent, resolvedTypes[i],
+                            aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage,
+                            0, theseOptions, componentSpecified, outActivity);
+                    if (res < 0) {
+                        return res;
+                    }
+
+                    resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+
+        return ActivityManager.START_SUCCESS;
+    }
+
+    final boolean realStartActivityLocked(ActivityRecord r,
+            ProcessRecord app, boolean andResume, boolean checkConfig)
+            throws RemoteException {
+
+        r.startFreezingScreenLocked(app, 0);
+        mWindowManager.setAppVisibility(r.appToken, true);
+
+        // schedule launch ticks to collect information about slow apps.
+        r.startLaunchTickingLocked();
+
+        // Have the window manager re-evaluate the orientation of
+        // the screen based on the new activity order.  Note that
+        // as a result of this, it can call back into the activity
+        // manager with a new orientation.  We don't care about that,
+        // because the activity is not currently running so we are
+        // just restarting it anyway.
+        if (checkConfig) {
+            Configuration config = mWindowManager.updateOrientationFromAppTokens(
+                    mService.mConfiguration,
+                    r.mayFreezeScreenLocked(app) ? r.appToken : null);
+            mService.updateConfigurationLocked(config, r, false, false);
+        }
+
+        r.app = app;
+        app.waitingToKill = null;
+        r.launchCount++;
+        r.lastLaunchTime = SystemClock.uptimeMillis();
+
+        if (localLOGV) Slog.v(TAG, "Launching: " + r);
+
+        int idx = app.activities.indexOf(r);
+        if (idx < 0) {
+            app.activities.add(r);
+        }
+        mService.updateLruProcessLocked(app, true);
+
+        final ActivityStack stack = r.task.stack;
+        try {
+            if (app.thread == null) {
+                throw new RemoteException();
+            }
+            List<ResultInfo> results = null;
+            List<Intent> newIntents = null;
+            if (andResume) {
+                results = r.results;
+                newIntents = r.newIntents;
+            }
+            if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r
+                    + " icicle=" + r.icicle
+                    + " with results=" + results + " newIntents=" + newIntents
+                    + " andResume=" + andResume);
+            if (andResume) {
+                EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
+                        r.userId, System.identityHashCode(r),
+                        r.task.taskId, r.shortComponentName);
+            }
+            if (r.isHomeActivity() && r.isNotResolverActivity()) {
+                mService.mHomeProcess.add(app);
+            }
+            mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
+            r.sleeping = false;
+            r.forceNewConfig = false;
+            mService.showAskCompatModeDialogLocked(r);
+            r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
+            String profileFile = null;
+            ParcelFileDescriptor profileFd = null;
+            boolean profileAutoStop = false;
+            if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
+                if (mService.mProfileProc == null || mService.mProfileProc == app) {
+                    mService.mProfileProc = app;
+                    profileFile = mService.mProfileFile;
+                    profileFd = mService.mProfileFd;
+                    profileAutoStop = mService.mAutoStopProfiler;
+                }
+            }
+            app.hasShownUi = true;
+            app.pendingUiClean = true;
+            if (profileFd != null) {
+                try {
+                    profileFd = profileFd.dup();
+                } catch (IOException e) {
+                    if (profileFd != null) {
+                        try {
+                            profileFd.close();
+                        } catch (IOException o) {
+                        }
+                        profileFd = null;
+                    }
+                }
+            }
+            app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
+            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
+                    System.identityHashCode(r), r.info,
+                    new Configuration(mService.mConfiguration), r.compat,
+                    app.repProcState, r.icicle, results, newIntents, !andResume,
+                    mService.isNextTransitionForward(), profileFile, profileFd,
+                    profileAutoStop);
+
+            if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
+                // This may be a heavy-weight process!  Note that the package
+                // manager will ensure that only activity can run in the main
+                // process of the .apk, which is the only thing that will be
+                // considered heavy-weight.
+                if (app.processName.equals(app.info.packageName)) {
+                    if (mService.mHeavyWeightProcess != null
+                            && mService.mHeavyWeightProcess != app) {
+                        Slog.w(TAG, "Starting new heavy weight process " + app
+                                + " when already running "
+                                + mService.mHeavyWeightProcess);
+                    }
+                    mService.mHeavyWeightProcess = app;
+                    Message msg = mService.mHandler.obtainMessage(
+                            ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
+                    msg.obj = r;
+                    mService.mHandler.sendMessage(msg);
+                }
+            }
+
+        } catch (RemoteException e) {
+            if (r.launchFailed) {
+                // This is the second time we failed -- finish activity
+                // and give up.
+                Slog.e(TAG, "Second failure launching "
+                      + r.intent.getComponent().flattenToShortString()
+                      + ", giving up", e);
+                mService.appDiedLocked(app, app.pid, app.thread);
+                stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
+                        "2nd-crash", false);
+                return false;
+            }
+
+            // This is the first time we failed -- restart process and
+            // retry.
+            app.activities.remove(r);
+            throw e;
+        }
+
+        r.launchFailed = false;
+        if (stack.updateLRUListLocked(r)) {
+            Slog.w(TAG, "Activity " + r
+                  + " being launched, but already in LRU list");
+        }
+
+        if (andResume) {
+            // As part of the process of launching, ActivityThread also performs
+            // a resume.
+            stack.minimalResumeActivityLocked(r);
+        } else {
+            // This activity is not starting in the resumed state... which
+            // should look like we asked it to pause+stop (but remain visible),
+            // and it has done so and reported back the current icicle and
+            // other state.
+            if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
+                    + " (starting in stopped state)");
+            r.state = ActivityState.STOPPED;
+            r.stopped = true;
+        }
+
+        // Launch the new version setup screen if needed.  We do this -after-
+        // launching the initial activity (that is, home), so that it can have
+        // a chance to initialize itself while in the background, making the
+        // switch back to it faster and look better.
+        if (isFrontStack(stack)) {
+            mService.startSetupActivityLocked();
+        }
+
+        return true;
+    }
+
+    void startSpecificActivityLocked(ActivityRecord r,
+            boolean andResume, boolean checkConfig) {
+        // Is this activity's application already running?
+        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
+                r.info.applicationInfo.uid);
+
+        r.task.stack.setLaunchTime(r);
+
+        if (app != null && app.thread != null) {
+            try {
+                app.addPackage(r.info.packageName, mService.mProcessStats);
+                realStartActivityLocked(r, app, andResume, checkConfig);
+                return;
+            } catch (RemoteException e) {
+                Slog.w(TAG, "Exception when starting activity "
+                        + r.intent.getComponent().flattenToShortString(), e);
+            }
+
+            // If a dead object exception was thrown -- fall through to
+            // restart the application.
+        }
+
+        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
+                "activity", r.intent.getComponent(), false, false);
+    }
+
+    final int startActivityLocked(IApplicationThread caller,
+            Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
+            String resultWho, int requestCode,
+            int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
+            boolean componentSpecified, ActivityRecord[] outActivity) {
+        int err = ActivityManager.START_SUCCESS;
+
+        ProcessRecord callerApp = null;
+        if (caller != null) {
+            callerApp = mService.getRecordForAppLocked(caller);
+            if (callerApp != null) {
+                callingPid = callerApp.pid;
+                callingUid = callerApp.info.uid;
+            } else {
+                Slog.w(TAG, "Unable to find app for caller " + caller
+                      + " (pid=" + callingPid + ") when starting: "
+                      + intent.toString());
+                err = ActivityManager.START_PERMISSION_DENIED;
+            }
+        }
+
+        if (err == ActivityManager.START_SUCCESS) {
+            final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
+            Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
+                    + "} from pid " + (callerApp != null ? callerApp.pid : callingPid));
+        }
+
+        ActivityRecord sourceRecord = null;
+        ActivityRecord resultRecord = null;
+        if (resultTo != null) {
+            sourceRecord = isInAnyStackLocked(resultTo);
+            if (DEBUG_RESULTS) Slog.v(
+                TAG, "Will send result to " + resultTo + " " + sourceRecord);
+            if (sourceRecord != null) {
+                if (requestCode >= 0 && !sourceRecord.finishing) {
+                    resultRecord = sourceRecord;
+                }
+            }
+        }
+        ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
+
+        int launchFlags = intent.getFlags();
+
+        if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
+                && sourceRecord != null) {
+            // Transfer the result target from the source activity to the new
+            // one being started, including any failures.
+            if (requestCode >= 0) {
+                ActivityOptions.abort(options);
+                return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
+            }
+            resultRecord = sourceRecord.resultTo;
+            resultWho = sourceRecord.resultWho;
+            requestCode = sourceRecord.requestCode;
+            sourceRecord.resultTo = null;
+            if (resultRecord != null) {
+                resultRecord.removeResultsLocked(
+                    sourceRecord, resultWho, requestCode);
+            }
+        }
+
+        if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
+            // We couldn't find a class that can handle the given Intent.
+            // That's the end of that!
+            err = ActivityManager.START_INTENT_NOT_RESOLVED;
+        }
+
+        if (err == ActivityManager.START_SUCCESS && aInfo == null) {
+            // We couldn't find the specific class specified in the Intent.
+            // Also the end of the line.
+            err = ActivityManager.START_CLASS_NOT_FOUND;
+        }
+
+        if (err != ActivityManager.START_SUCCESS) {
+            if (resultRecord != null) {
+                resultStack.sendActivityResultLocked(-1,
+                    resultRecord, resultWho, requestCode,
+                    Activity.RESULT_CANCELED, null);
+            }
+            setDismissKeyguard(false);
+            ActivityOptions.abort(options);
+            return err;
+        }
+
+        final int startAnyPerm = mService.checkPermission(
+                START_ANY_ACTIVITY, callingPid, callingUid);
+        final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
+                callingUid, aInfo.applicationInfo.uid, aInfo.exported);
+        if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
+            if (resultRecord != null) {
+                resultStack.sendActivityResultLocked(-1,
+                    resultRecord, resultWho, requestCode,
+                    Activity.RESULT_CANCELED, null);
+            }
+            setDismissKeyguard(false);
+            String msg;
+            if (!aInfo.exported) {
+                msg = "Permission Denial: starting " + intent.toString()
+                        + " from " + callerApp + " (pid=" + callingPid
+                        + ", uid=" + callingUid + ")"
+                        + " not exported from uid " + aInfo.applicationInfo.uid;
+            } else {
+                msg = "Permission Denial: starting " + intent.toString()
+                        + " from " + callerApp + " (pid=" + callingPid
+                        + ", uid=" + callingUid + ")"
+                        + " requires " + aInfo.permission;
+            }
+            Slog.w(TAG, msg);
+            throw new SecurityException(msg);
+        }
+
+        boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
+                callingPid, resolvedType, aInfo.applicationInfo);
+
+        if (mService.mController != null) {
+            try {
+                // The Intent we give to the watcher has the extra data
+                // stripped off, since it can contain private information.
+                Intent watchIntent = intent.cloneFilter();
+                abort |= !mService.mController.activityStarting(watchIntent,
+                        aInfo.applicationInfo.packageName);
+            } catch (RemoteException e) {
+                mService.mController = null;
+            }
+        }
+
+        if (abort) {
+            if (resultRecord != null) {
+                resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
+                        Activity.RESULT_CANCELED, null);
+            }
+            // We pretend to the caller that it was really started, but
+            // they will just get a cancel result.
+            setDismissKeyguard(false);
+            ActivityOptions.abort(options);
+            return ActivityManager.START_SUCCESS;
+        }
+
+        ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
+                intent, resolvedType, aInfo, mService.mConfiguration,
+                resultRecord, resultWho, requestCode, componentSpecified, this);
+        if (outActivity != null) {
+            outActivity[0] = r;
+        }
+
+        final ActivityStack stack = getFocusedStack();
+        if (stack.mResumedActivity == null
+                || stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
+            if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
+                PendingActivityLaunch pal =
+                        new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
+                mService.mPendingActivityLaunches.add(pal);
+                setDismissKeyguard(false);
+                ActivityOptions.abort(options);
+                return ActivityManager.START_SWITCHES_CANCELED;
+            }
+        }
+
+        if (mService.mDidAppSwitch) {
+            // This is the second allowed switch since we stopped switches,
+            // so now just generally allow switches.  Use case: user presses
+            // home (switches disabled, switch to home, mDidAppSwitch now true);
+            // user taps a home icon (coming from home so allowed, we hit here
+            // and now allow anyone to switch again).
+            mService.mAppSwitchesAllowedTime = 0;
+        } else {
+            mService.mDidAppSwitch = true;
+        }
+
+        mService.doPendingActivityLaunchesLocked(false);
+
+        err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
+        if (stack.mPausingActivity == null) {
+            // Someone asked to have the keyguard dismissed on the next
+            // activity start, but we are not actually doing an activity
+            // switch...  just dismiss the keyguard now, because we
+            // probably want to see whatever is behind it.
+            dismissKeyguard();
+        }
+        return err;
+    }
+
+    ActivityStack adjustStackFocus(ActivityRecord r) {
+        final TaskRecord task = r.task;
+        if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {
+            if (task != null) {
+                if (mFocusedStack != task.stack) {
+                    if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
+                            "adjustStackFocus: Setting focused stack to r=" + r + " task=" + task);
+                    mFocusedStack = task.stack;
+                } else {
+                    if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
+                        "adjustStackFocus: Focused stack already=" + mFocusedStack);
+                }
+                return mFocusedStack;
+            }
+
+            if (mFocusedStack != null) {
+                if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
+                        "adjustStackFocus: Have a focused stack=" + mFocusedStack);
+                return mFocusedStack;
+            }
+
+            for (int stackNdx = mStacks.size() - 1; stackNdx > 0; --stackNdx) {
+                ActivityStack stack = mStacks.get(stackNdx);
+                if (!stack.isHomeStack()) {
+                    if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
+                            "adjustStackFocus: Setting focused stack=" + stack);
+                    mFocusedStack = stack;
+                    return mFocusedStack;
+                }
+            }
+
+            // Time to create the first app stack for this user.
+            int stackId = mService.createStack(-1, HOME_STACK_ID,
+                StackBox.TASK_STACK_GOES_OVER, 1.0f);
+            if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
+                    " stackId=" + stackId);
+            mFocusedStack = getStack(stackId);
+            return mFocusedStack;
+        }
+        return mHomeStack;
+    }
+
+    void setFocusedStack(ActivityRecord r) {
+        if (r == null) {
+            return;
+        }
+        if (!r.isApplicationActivity() || (r.task != null && !r.task.isApplicationTask())) {
+            if (mStackState != STACK_STATE_HOME_IN_FRONT) {
+                if (DEBUG_STACK || DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: mStackState old=" +
+                        stackStateToString(mStackState) + " new=" +
+                        stackStateToString(STACK_STATE_HOME_TO_FRONT) +
+                        " Callers=" + Debug.getCallers(3));
+                mStackState = STACK_STATE_HOME_TO_FRONT;
+            }
+        } else {
+            if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
+                    "setFocusedStack: Setting focused stack to r=" + r + " task=" + r.task +
+                    " Callers=" + Debug.getCallers(3));
+            mFocusedStack = r.task.stack;
+            if (mStackState != STACK_STATE_HOME_IN_BACK) {
+                if (DEBUG_STACK) Slog.d(TAG, "setFocusedStack: mStackState old=" +
+                        stackStateToString(mStackState) + " new=" +
+                        stackStateToString(STACK_STATE_HOME_TO_BACK) +
+                        " Callers=" + Debug.getCallers(3));
+                mStackState = STACK_STATE_HOME_TO_BACK;
+            }
+        }
+    }
+
+    final int startActivityUncheckedLocked(ActivityRecord r,
+            ActivityRecord sourceRecord, int startFlags, boolean doResume,
+            Bundle options) {
+        final Intent intent = r.intent;
+        final int callingUid = r.launchedFromUid;
+
+        int launchFlags = intent.getFlags();
+
+        // We'll invoke onUserLeaving before onPause only if the launching
+        // activity did not explicitly state that this is an automated launch.
+        mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
+        if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
+
+        // If the caller has asked not to resume at this point, we make note
+        // of this in the record so that we can skip it when trying to find
+        // the top running activity.
+        if (!doResume) {
+            r.delayedResume = true;
+        }
+
+        ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
+
+        // If the onlyIfNeeded flag is set, then we can do this if the activity
+        // being launched is the same as the one making the call...  or, as
+        // a special case, if we do not know the caller then we count the
+        // current top activity as the caller.
+        if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
+            ActivityRecord checkedCaller = sourceRecord;
+            if (checkedCaller == null) {
+                checkedCaller = getFocusedStack().topRunningNonDelayedActivityLocked(notTop);
+            }
+            if (!checkedCaller.realActivity.equals(r.realActivity)) {
+                // Caller is not the same as launcher, so always needed.
+                startFlags &= ~ActivityManager.START_FLAG_ONLY_IF_NEEDED;
+            }
+        }
+
+        if (sourceRecord == null) {
+            // This activity is not being started from another...  in this
+            // case we -always- start a new task.
+            if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
+                Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
+                        "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
+                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
+            }
+        } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
+            // The original activity who is starting us is running as a single
+            // instance...  this new activity it is starting must go on its
+            // own task.
+            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
+        } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
+                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
+            // The activity being started is a single instance...  it always
+            // gets launched into its own task.
+            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
+        }
+
+        final ActivityStack sourceStack;
+        TaskRecord sourceTask;
+        if (sourceRecord != null) {
+            sourceTask = sourceRecord.task;
+            sourceStack = sourceTask.stack;
+        } else {
+            sourceTask = null;
+            sourceStack = null;
+        }
+
+        if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
+            // For whatever reason this activity is being launched into a new
+            // task...  yet the caller has requested a result back.  Well, that
+            // is pretty messed up, so instead immediately send back a cancel
+            // and let the new task continue launched as normal without a
+            // dependency on its originator.
+            Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
+            r.resultTo.task.stack.sendActivityResultLocked(-1,
+                    r.resultTo, r.resultWho, r.requestCode,
+                Activity.RESULT_CANCELED, null);
+            r.resultTo = null;
+        }
+
+        boolean addingToTask = false;
+        boolean movedHome = false;
+        TaskRecord reuseTask = null;
+        ActivityStack targetStack;
+        if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
+                (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
+                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
+                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
+            // If bring to front is requested, and no result is requested, and
+            // we can find a task that was started with this same
+            // component, then instead of launching bring that one to the front.
+            if (r.resultTo == null) {
+                // See if there is a task to bring to the front.  If this is
+                // a SINGLE_INSTANCE activity, there can be one and only one
+                // instance of it in the history, and it is always in its own
+                // unique task, so we do a special search.
+                ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
+                        ? findTaskLocked(r)
+                        : findActivityLocked(intent, r.info);
+                if (intentActivity != null) {
+                    if (r.task == null) {
+                        r.task = intentActivity.task;
+                    }
+                    targetStack = intentActivity.task.stack;
+                    targetStack.mLastPausedActivity = null;
+                    moveHomeStack(targetStack.isHomeStack());
+                    if (intentActivity.task.intent == null) {
+                        // This task was started because of movement of
+                        // the activity based on affinity...  now that we
+                        // are actually launching it, we can assign the
+                        // base intent.
+                        intentActivity.task.setIntent(intent, r.info);
+                    }
+                    // If the target task is not in the front, then we need
+                    // to bring it to the front...  except...  well, with
+                    // SINGLE_TASK_LAUNCH it's not entirely clear.  We'd like
+                    // to have the same behavior as if a new instance was
+                    // being started, which means not bringing it to the front
+                    // if the caller is not itself in the front.
+                    final ActivityStack lastStack = getLastStack();
+                    ActivityRecord curTop = lastStack == null?
+                            null : lastStack.topRunningNonDelayedActivityLocked(notTop);
+                    if (curTop != null && curTop.task != intentActivity.task) {
+                        r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
+                        if (sourceRecord == null || (sourceStack.topActivity() != null &&
+                                sourceStack.topActivity().task == sourceRecord.task)) {
+                            // We really do want to push this one into the
+                            // user's face, right now.
+                            movedHome = true;
+                            if ((launchFlags &
+                                    (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
+                                    == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
+                                // Caller wants to appear on home activity.
+                                r.mLaunchHomeTaskNext = true;
+                            }
+                            targetStack.moveTaskToFrontLocked(intentActivity.task, r, options);
+                            options = null;
+                        }
+                    }
+                    // If the caller has requested that the target task be
+                    // reset, then do so.
+                    if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
+                        intentActivity = targetStack.resetTaskIfNeededLocked(intentActivity, r);
+                    }
+                    if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
+                        // We don't need to start a new activity, and
+                        // the client said not to do anything if that
+                        // is the case, so this is it!  And for paranoia, make
+                        // sure we have correctly resumed the top activity.
+                        if (doResume) {
+                            setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
+                            resumeTopActivitiesLocked(targetStack, null, options);
+                        } else {
+                            ActivityOptions.abort(options);
+                        }
+                        if (r.task == null)  Slog.v(TAG,
+                                "startActivityUncheckedLocked: task left null",
+                                new RuntimeException("here").fillInStackTrace());
+                        return ActivityManager.START_RETURN_INTENT_TO_CALLER;
+                    }
+                    if ((launchFlags &
+                            (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
+                            == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
+                        // The caller has requested to completely replace any
+                        // existing task with its new activity.  Well that should
+                        // not be too hard...
+                        reuseTask = intentActivity.task;
+                        reuseTask.performClearTaskLocked();
+                        reuseTask.setIntent(r.intent, r.info);
+                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
+                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
+                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
+                        // In this situation we want to remove all activities
+                        // from the task up to the one being started.  In most
+                        // cases this means we are resetting the task to its
+                        // initial state.
+                        ActivityRecord top =
+                                intentActivity.task.performClearTaskLocked(r, launchFlags);
+                        if (top != null) {
+                            if (top.frontOfTask) {
+                                // Activity aliases may mean we use different
+                                // intents for the top activity, so make sure
+                                // the task now has the identity of the new
+                                // intent.
+                                top.task.setIntent(r.intent, r.info);
+                            }
+                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,
+                                    r, top.task);
+                            top.deliverNewIntentLocked(callingUid, r.intent);
+                        } else {
+                            // A special case: we need to
+                            // start the activity because it is not currently
+                            // running, and the caller has asked to clear the
+                            // current task to have this activity at the top.
+                            addingToTask = true;
+                            // Now pretend like this activity is being started
+                            // by the top of its task, so it is put in the
+                            // right place.
+                            sourceRecord = intentActivity;
+                        }
+                    } else if (r.realActivity.equals(intentActivity.task.realActivity)) {
+                        // In this case the top activity on the task is the
+                        // same as the one being launched, so we take that
+                        // as a request to bring the task to the foreground.
+                        // If the top activity in the task is the root
+                        // activity, deliver this new intent to it if it
+                        // desires.
+                        if (((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
+                                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP)
+                                && intentActivity.realActivity.equals(r.realActivity)) {
+                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r,
+                                    intentActivity.task);
+                            if (intentActivity.frontOfTask) {
+                                intentActivity.task.setIntent(r.intent, r.info);
+                            }
+                            intentActivity.deliverNewIntentLocked(callingUid, r.intent);
+                        } else if (!r.intent.filterEquals(intentActivity.task.intent)) {
+                            // In this case we are launching the root activity
+                            // of the task, but with a different intent.  We
+                            // should start a new instance on top.
+                            addingToTask = true;
+                            sourceRecord = intentActivity;
+                        }
+                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
+                        // In this case an activity is being launched in to an
+                        // existing task, without resetting that task.  This
+                        // is typically the situation of launching an activity
+                        // from a notification or shortcut.  We want to place
+                        // the new activity on top of the current task.
+                        addingToTask = true;
+                        sourceRecord = intentActivity;
+                    } else if (!intentActivity.task.rootWasReset) {
+                        // In this case we are launching in to an existing task
+                        // that has not yet been started from its front door.
+                        // The current task has been brought to the front.
+                        // Ideally, we'd probably like to place this new task
+                        // at the bottom of its stack, but that's a little hard
+                        // to do with the current organization of the code so
+                        // for now we'll just drop it.
+                        intentActivity.task.setIntent(r.intent, r.info);
+                    }
+                    if (!addingToTask && reuseTask == null) {
+                        // We didn't do anything...  but it was needed (a.k.a., client
+                        // don't use that intent!)  And for paranoia, make
+                        // sure we have correctly resumed the top activity.
+                        if (doResume) {
+                            // Reset flag so it gets correctly reevaluated.
+                            intentActivity.mLaunchHomeTaskNext = false;
+                            setLaunchHomeTaskNextFlag(sourceRecord, intentActivity, targetStack);
+                            targetStack.resumeTopActivityLocked(null, options);
+                        } else {
+                            ActivityOptions.abort(options);
+                        }
+                        if (r.task == null)  Slog.v(TAG,
+                            "startActivityUncheckedLocked: task left null",
+                            new RuntimeException("here").fillInStackTrace());
+                        return ActivityManager.START_TASK_TO_FRONT;
+                    }
+                }
+            }
+        }
+
+        //String uri = r.intent.toURI();
+        //Intent intent2 = new Intent(uri);
+        //Slog.i(TAG, "Given intent: " + r.intent);
+        //Slog.i(TAG, "URI is: " + uri);
+        //Slog.i(TAG, "To intent: " + intent2);
+
+        if (r.packageName != null) {
+            // If the activity being launched is the same as the one currently
+            // at the top, then we need to check if it should only be launched
+            // once.
+            ActivityStack topStack = getFocusedStack();
+            ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
+            if (top != null && r.resultTo == null) {
+                if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
+                    if (top.app != null && top.app.thread != null) {
+                        if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
+                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
+                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
+                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
+                                    top.task);
+                            // For paranoia, make sure we have correctly
+                            // resumed the top activity.
+                            topStack.mLastPausedActivity = null;
+                            if (doResume) {
+                                setLaunchHomeTaskNextFlag(sourceRecord, null, topStack);
+                                resumeTopActivitiesLocked();
+                            }
+                            ActivityOptions.abort(options);
+                            if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
+                                // We don't need to start a new activity, and
+                                // the client said not to do anything if that
+                                // is the case, so this is it!
+                                if (r.task == null)  Slog.v(TAG,
+                                    "startActivityUncheckedLocked: task left null",
+                                    new RuntimeException("here").fillInStackTrace());
+                                return ActivityManager.START_RETURN_INTENT_TO_CALLER;
+                            }
+                            top.deliverNewIntentLocked(callingUid, r.intent);
+                            if (r.task == null)  Slog.v(TAG,
+                                "startActivityUncheckedLocked: task left null",
+                                new RuntimeException("here").fillInStackTrace());
+                            return ActivityManager.START_DELIVERED_TO_TOP;
+                        }
+                    }
+                }
+            }
+
+        } else {
+            if (r.resultTo != null) {
+                r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
+                        r.requestCode, Activity.RESULT_CANCELED, null);
+            }
+            ActivityOptions.abort(options);
+            if (r.task == null)  Slog.v(TAG,
+                "startActivityUncheckedLocked: task left null",
+                new RuntimeException("here").fillInStackTrace());
+            return ActivityManager.START_CLASS_NOT_FOUND;
+        }
+
+        boolean newTask = false;
+        boolean keepCurTransition = false;
+
+        // Should this be considered a new task?
+        if (r.resultTo == null && !addingToTask
+                && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
+            targetStack = adjustStackFocus(r);
+            moveHomeStack(targetStack.isHomeStack());
+            if (reuseTask == null) {
+                r.setTask(targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
+                        null, true);
+                if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
+                        r.task);
+            } else {
+                r.setTask(reuseTask, reuseTask, true);
+            }
+            newTask = true;
+            if (!movedHome) {
+                if ((launchFlags &
+                        (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
+                        == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
+                    // Caller wants to appear on home activity, so before starting
+                    // their own activity we will bring home to the front.
+                    r.mLaunchHomeTaskNext = true;
+                }
+            }
+        } else if (sourceRecord != null) {
+            sourceTask = sourceRecord.task;
+            targetStack = sourceTask.stack;
+            moveHomeStack(targetStack.isHomeStack());
+            if (!addingToTask &&
+                    (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
+                // In this case, we are adding the activity to an existing
+                // task, but the caller has asked to clear that task if the
+                // activity is already running.
+                ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
+                keepCurTransition = true;
+                if (top != null) {
+                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
+                    top.deliverNewIntentLocked(callingUid, r.intent);
+                    // For paranoia, make sure we have correctly
+                    // resumed the top activity.
+                    targetStack.mLastPausedActivity = null;
+                    if (doResume) {
+                        setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
+                        targetStack.resumeTopActivityLocked(null);
+                    }
+                    ActivityOptions.abort(options);
+                    if (r.task == null)  Slog.v(TAG,
+                        "startActivityUncheckedLocked: task left null",
+                        new RuntimeException("here").fillInStackTrace());
+                    return ActivityManager.START_DELIVERED_TO_TOP;
+                }
+            } else if (!addingToTask &&
+                    (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
+                // In this case, we are launching an activity in our own task
+                // that may already be running somewhere in the history, and
+                // we want to shuffle it to the front of the stack if so.
+                final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r);
+                if (top != null) {
+                    final TaskRecord task = top.task;
+                    task.moveActivityToFrontLocked(top);
+                    ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task);
+                    top.updateOptionsLocked(options);
+                    top.deliverNewIntentLocked(callingUid, r.intent);
+                    targetStack.mLastPausedActivity = null;
+                    if (doResume) {
+                        setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
+                        targetStack.resumeTopActivityLocked(null);
+                    }
+                    return ActivityManager.START_DELIVERED_TO_TOP;
+                }
+            }
+            // An existing activity is starting this new activity, so we want
+            // to keep the new one in the same task as the one that is starting
+            // it.
+            r.setTask(sourceTask, sourceRecord.thumbHolder, false);
+            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
+                    + " in existing task " + r.task);
+
+        } else {
+            // This not being started from an existing activity, and not part
+            // of a new task...  just put it in the top task, though these days
+            // this case should never happen.
+            targetStack = adjustStackFocus(r);
+            moveHomeStack(targetStack.isHomeStack());
+            ActivityRecord prev = targetStack.topActivity();
+            r.setTask(prev != null ? prev.task
+                    : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
+                    null, true);
+            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
+                    + " in new guessed " + r.task);
+        }
+
+        mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
+                intent, r.getUriPermissionsLocked());
+
+        if (newTask) {
+            EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
+        }
+        ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
+        setLaunchHomeTaskNextFlag(sourceRecord, r, targetStack);
+        targetStack.mLastPausedActivity = null;
+        targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
+        mService.setFocusedActivityLocked(r);
+        return ActivityManager.START_SUCCESS;
+    }
+
+    void acquireLaunchWakelock() {
+        if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
+            throw new IllegalStateException("Calling must be system uid");
+        }
+        mLaunchingActivity.acquire();
+        if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
+            // To be safe, don't allow the wake lock to be held for too long.
+            mHandler.sendEmptyMessageDelayed(LAUNCH_TIMEOUT_MSG, LAUNCH_TIMEOUT);
+        }
+    }
+
+    // Checked.
+    final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
+            Configuration config) {
+        if (localLOGV) Slog.v(TAG, "Activity idle: " + token);
+
+        ArrayList<ActivityRecord> stops = null;
+        ArrayList<ActivityRecord> finishes = null;
+        ArrayList<UserStartedState> startingUsers = null;
+        int NS = 0;
+        int NF = 0;
+        IApplicationThread sendThumbnail = null;
+        boolean booting = false;
+        boolean enableScreen = false;
+        boolean activityRemoved = false;
+
+        ActivityRecord r = ActivityRecord.forToken(token);
+        if (r != null) {
+            if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
+                    Debug.getCallers(4));
+            mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
+            r.finishLaunchTickingLocked();
+            if (fromTimeout) {
+                reportActivityLaunchedLocked(fromTimeout, r, -1, -1);
+            }
+
+            // This is a hack to semi-deal with a race condition
+            // in the client where it can be constructed with a
+            // newer configuration from when we asked it to launch.
+            // We'll update with whatever configuration it now says
+            // it used to launch.
+            if (config != null) {
+                r.configuration = config;
+            }
+
+            // We are now idle.  If someone is waiting for a thumbnail from
+            // us, we can now deliver.
+            r.idle = true;
+
+            if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
+                sendThumbnail = r.app.thread;
+                r.thumbnailNeeded = false;
+            }
+
+            //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
+            if (!mService.mBooted && isFrontStack(r.task.stack)) {
+                mService.mBooted = true;
+                enableScreen = true;
+            }
+        }
+
+        if (allResumedActivitiesIdle()) {
+            if (r != null) {
+                mService.scheduleAppGcsLocked();
+            }
+
+            if (mLaunchingActivity.isHeld()) {
+                mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
+                if (VALIDATE_WAKE_LOCK_CALLER &&
+                        Binder.getCallingUid() != Process.myUid()) {
+                    throw new IllegalStateException("Calling must be system uid");
+                }
+                mLaunchingActivity.release();
+            }
+            ensureActivitiesVisibleLocked(null, 0);
+        }
+
+        // Atomically retrieve all of the other things to do.
+        stops = processStoppingActivitiesLocked(true);
+        NS = stops != null ? stops.size() : 0;
+        if ((NF=mFinishingActivities.size()) > 0) {
+            finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
+            mFinishingActivities.clear();
+        }
+
+        final ArrayList<ActivityRecord> thumbnails;
+        final int NT = mCancelledThumbnails.size();
+        if (NT > 0) {
+            thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
+            mCancelledThumbnails.clear();
+        } else {
+            thumbnails = null;
+        }
+
+        if (isFrontStack(mHomeStack)) {
+            booting = mService.mBooting;
+            mService.mBooting = false;
+        }
+
+        if (mStartingUsers.size() > 0) {
+            startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
+            mStartingUsers.clear();
+        }
+
+        // Perform the following actions from unsynchronized state.
+        final IApplicationThread thumbnailThread = sendThumbnail;
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                if (thumbnailThread != null) {
+                    try {
+                        thumbnailThread.requestThumbnail(token);
+                    } catch (Exception e) {
+                        Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
+                        mService.sendPendingThumbnail(null, token, null, null, true);
+                    }
+                }
+
+                // Report back to any thumbnail receivers.
+                for (int i = 0; i < NT; i++) {
+                    ActivityRecord r = thumbnails.get(i);
+                    mService.sendPendingThumbnail(r, null, null, null, true);
+                }
+            }
+        });
+
+        // Stop any activities that are scheduled to do so but have been
+        // waiting for the next one to start.
+        for (int i = 0; i < NS; i++) {
+            r = stops.get(i);
+            final ActivityStack stack = r.task.stack;
+            if (r.finishing) {
+                stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
+            } else {
+                stack.stopActivityLocked(r);
+            }
+        }
+
+        // Finish any activities that are scheduled to do so but have been
+        // waiting for the next one to start.
+        for (int i = 0; i < NF; i++) {
+            r = finishes.get(i);
+            activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
+        }
+
+        if (booting) {
+            mService.finishBooting();
+        } else if (startingUsers != null) {
+            for (int i = 0; i < startingUsers.size(); i++) {
+                mService.finishUserSwitch(startingUsers.get(i));
+            }
+        }
+
+        mService.trimApplications();
+        //dump();
+        //mWindowManager.dump();
+
+        if (enableScreen) {
+            mService.enableScreenAfterBoot();
+        }
+
+        if (activityRemoved) {
+            resumeTopActivitiesLocked();
+        }
+
+        return r;
+    }
+
+    void handleAppDiedLocked(ProcessRecord app, boolean restarting) {
+        // Just in case.
+        final int numStacks = mStacks.size();
+        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
+            mStacks.get(stackNdx).handleAppDiedLocked(app, restarting);
+        }
+    }
+
+    void closeSystemDialogsLocked() {
+        final int numStacks = mStacks.size();
+        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
+            final ActivityStack stack = mStacks.get(stackNdx);
+            stack.closeSystemDialogsLocked();
+        }
+    }
+
+    /**
+     * @return true if some activity was finished (or would have finished if doit were true).
+     */
+    boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) {
+        boolean didSomething = false;
+        final int numStacks = mStacks.size();
+        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
+            final ActivityStack stack = mStacks.get(stackNdx);
+            if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
+                didSomething = true;
+            }
+        }
+        return didSomething;
+    }
+
+    void updatePreviousProcessLocked(ActivityRecord r) {
+        // Now that this process has stopped, we may want to consider
+        // it to be the previous app to try to keep around in case
+        // the user wants to return to it.
+
+        // First, found out what is currently the foreground app, so that
+        // we don't blow away the previous app if this activity is being
+        // hosted by the process that is actually still the foreground.
+        ProcessRecord fgApp = null;
+        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            final ActivityStack stack = mStacks.get(stackNdx);
+            if (isFrontStack(stack)) {
+                if (stack.mResumedActivity != null) {
+                    fgApp = stack.mResumedActivity.app;
+                } else if (stack.mPausingActivity != null) {
+                    fgApp = stack.mPausingActivity.app;
+                }
+                break;
+            }
+        }
+
+        // Now set this one as the previous process, only if that really
+        // makes sense to.
+        if (r.app != null && fgApp != null && r.app != fgApp
+                && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
+                && !mService.mHomeProcess.contains(r.app)) {
+            mService.mPreviousProcess = r.app;
+            mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
+        }
+    }
+
+    boolean resumeTopActivitiesLocked() {
+        return resumeTopActivitiesLocked(null, null, null);
+    }
+
+    boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
+            Bundle targetOptions) {
+        if (targetStack == null) {
+            targetStack = getFocusedStack();
+        }
+        boolean result = false;
+        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            final ActivityStack stack = mStacks.get(stackNdx);
+            if (isFrontStack(stack)) {
+                if (stack == targetStack) {
+                    result = stack.resumeTopActivityLocked(target, targetOptions);
+                } else {
+                    stack.resumeTopActivityLocked(null);
+                }
+            }
+        }
+        return result;
+    }
+
+    void finishTopRunningActivityLocked(ProcessRecord app) {
+        final int numStacks = mStacks.size();
+        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
+            final ActivityStack stack = mStacks.get(stackNdx);
+            stack.finishTopRunningActivityLocked(app);
+        }
+    }
+
+    void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
+        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            if (mStacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
+                if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack=" +
+                        mStacks.get(stackNdx));
+                return;
+            }
+        }
+    }
+
+    ActivityStack getStack(int stackId) {
+        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            final ActivityStack stack = mStacks.get(stackNdx);
+            if (stack.getStackId() == stackId) {
+                return stack;
+            }
+        }
+        return null;
+    }
+
+    ArrayList<ActivityStack> getStacks() {
+        return new ArrayList<ActivityStack>(mStacks);
+    }
+
+    int createStack() {
+        while (true) {
+            if (++mLastStackId <= HOME_STACK_ID) {
+                mLastStackId = HOME_STACK_ID + 1;
+            }
+            if (getStack(mLastStackId) == null) {
+                break;
+            }
+        }
+        mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId));
+        return mLastStackId;
+    }
+
+    void moveTaskToStack(int taskId, int stackId, boolean toTop) {
+        final TaskRecord task = anyTaskForIdLocked(taskId);
+        if (task == null) {
+            return;
+        }
+        final ActivityStack stack = getStack(stackId);
+        if (stack == null) {
+            Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
+            return;
+        }
+        removeTask(task);
+        stack.addTask(task, toTop);
+        mWindowManager.addTask(taskId, stackId, toTop);
+        resumeTopActivitiesLocked();
+    }
+
+    ActivityRecord findTaskLocked(ActivityRecord r) {
+        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            final ActivityStack stack = mStacks.get(stackNdx);
+            if (!r.isApplicationActivity() && !stack.isHomeStack()) {
+                continue;
+            }
+            final ActivityRecord ar = stack.findTaskLocked(r);
+            if (ar != null) {
+                return ar;
+            }
+        }
+        return null;
+    }
+
+    ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {
+        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            final ActivityRecord ar = mStacks.get(stackNdx).findActivityLocked(intent, info);
+            if (ar != null) {
+                return ar;
+            }
+        }
+        return null;
+    }
+
+    void goingToSleepLocked() {
+        scheduleSleepTimeout();
+        if (!mGoingToSleep.isHeld()) {
+            mGoingToSleep.acquire();
+            if (mLaunchingActivity.isHeld()) {
+                if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
+                    throw new IllegalStateException("Calling must be system uid");
+                }
+                mLaunchingActivity.release();
+                mService.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
+            }
+        }
+    }
+
+    boolean shutdownLocked(int timeout) {
+        boolean timedout = false;
+        goingToSleepLocked();
+        checkReadyForSleepLocked();
+
+        final long endTime = System.currentTimeMillis() + timeout;
+        while (true) {
+            boolean cantShutdown = false;
+            for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+                cantShutdown |= mStacks.get(stackNdx).checkReadyForSleepLocked();
+            }
+            if (cantShutdown) {
+                long timeRemaining = endTime - System.currentTimeMillis();
+                if (timeRemaining > 0) {
+                    try {
+                        mService.wait(timeRemaining);
+                    } catch (InterruptedException e) {
+                    }
+                } else {
+                    Slog.w(TAG, "Activity manager shutdown timed out");
+                    timedout = true;
+                    break;
+                }
+            } else {
+                break;
+            }
+        }
+
+        // Force checkReadyForSleep to complete.
+        mSleepTimeout = true;
+        checkReadyForSleepLocked();
+
+        return timedout;
+    }
+
+    void comeOutOfSleepIfNeededLocked() {
+        removeSleepTimeouts();
+        if (mGoingToSleep.isHeld()) {
+            mGoingToSleep.release();
+        }
+        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            final ActivityStack stack = mStacks.get(stackNdx);
+            stack.awakeFromSleepingLocked();
+            if (isFrontStack(stack)) {
+                resumeTopActivitiesLocked();
+            }
+        }
+        mGoingToSleepActivities.clear();
+    }
+
+    void activitySleptLocked(ActivityRecord r) {
+        mGoingToSleepActivities.remove(r);
+        checkReadyForSleepLocked();
+    }
+
+    void checkReadyForSleepLocked() {
+        if (!mService.isSleepingOrShuttingDown()) {
+            // Do not care.
+            return;
+        }
+
+        if (!mSleepTimeout) {
+            boolean dontSleep = false;
+            for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+                dontSleep |= mStacks.get(stackNdx).checkReadyForSleepLocked();
+            }
+
+            if (mStoppingActivities.size() > 0) {
+                // Still need to tell some activities to stop; can't sleep yet.
+                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to stop "
+                        + mStoppingActivities.size() + " activities");
+                scheduleIdleLocked();
+                dontSleep = true;
+            }
+
+            if (mGoingToSleepActivities.size() > 0) {
+                // Still need to tell some activities to sleep; can't sleep yet.
+                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still need to sleep "
+                        + mGoingToSleepActivities.size() + " activities");
+                dontSleep = true;
+            }
+
+            if (dontSleep) {
+                return;
+            }
+        }
+
+        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            mStacks.get(stackNdx).goToSleep();
+        }
+
+        removeSleepTimeouts();
+
+        if (mGoingToSleep.isHeld()) {
+            mGoingToSleep.release();
+        }
+        if (mService.mShuttingDown) {
+            mService.notifyAll();
+        }
+    }
+
+    boolean reportResumedActivityLocked(ActivityRecord r) {
+        final ActivityStack stack = r.task.stack;
+        if (isFrontStack(stack)) {
+            mService.updateUsageStats(r, true);
+        }
+        if (allResumedActivitiesComplete()) {
+            ensureActivitiesVisibleLocked(null, 0);
+            mWindowManager.executeAppTransition();
+            return true;
+        }
+        return false;
+    }
+
+    void handleAppCrashLocked(ProcessRecord app) {
+        final int numStacks = mStacks.size();
+        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
+            final ActivityStack stack = mStacks.get(stackNdx);
+            stack.handleAppCrashLocked(app);
+        }
+    }
+
+    void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges) {
+        // First the front stacks. In case any are not fullscreen and are in front of home.
+        boolean showHomeBehindStack = false;
+        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            final ActivityStack stack = mStacks.get(stackNdx);
+            if (isFrontStack(stack)) {
+                showHomeBehindStack =
+                        stack.ensureActivitiesVisibleLocked(starting, configChanges);
+            }
+        }
+        // Now do back stacks.
+        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            final ActivityStack stack = mStacks.get(stackNdx);
+            if (!isFrontStack(stack)) {
+                stack.ensureActivitiesVisibleLocked(starting, configChanges, showHomeBehindStack);
+            }
+        }
+    }
+
+    void scheduleDestroyAllActivities(ProcessRecord app, String reason) {
+        final int numStacks = mStacks.size();
+        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
+            final ActivityStack stack = mStacks.get(stackNdx);
+            stack.scheduleDestroyActivities(app, false, reason);
+        }
+    }
+
+    boolean switchUserLocked(int userId, UserStartedState uss) {
+        mCurrentUser = userId;
+
+        final String homePackageName = mService.getHomePackageName();
+        if (homePackageName != null) {
+            setHomePackageName(mCurrentUser, homePackageName);
+        }
+
+        mStartingUsers.add(uss);
+        boolean haveActivities = false;
+        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            haveActivities |= mStacks.get(stackNdx).switchUserLocked(userId);
+        }
+
+        resumeTopActivitiesLocked();
+
+        return haveActivities;
+    }
+
+    final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) {
+        int N = mStoppingActivities.size();
+        if (N <= 0) return null;
+
+        ArrayList<ActivityRecord> stops = null;
+
+        final boolean nowVisible = allResumedActivitiesVisible();
+        for (int i=0; i<N; i++) {
+            ActivityRecord s = mStoppingActivities.get(i);
+            if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible="
+                    + nowVisible + " waitingVisible=" + s.waitingVisible
+                    + " finishing=" + s.finishing);
+            if (s.waitingVisible && nowVisible) {
+                mWaitingVisibleActivities.remove(s);
+                s.waitingVisible = false;
+                if (s.finishing) {
+                    // If this activity is finishing, it is sitting on top of
+                    // everyone else but we now know it is no longer needed...
+                    // so get rid of it.  Otherwise, we need to go through the
+                    // normal flow and hide it once we determine that it is
+                    // hidden by the activities in front of it.
+                    if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
+                    mWindowManager.setAppVisibility(s.appToken, false);
+                }
+            }
+            if ((!s.waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
+                if (localLOGV) Slog.v(TAG, "Ready to stop: " + s);
+                if (stops == null) {
+                    stops = new ArrayList<ActivityRecord>();
+                }
+                stops.add(s);
+                mStoppingActivities.remove(i);
+                N--;
+                i--;
+            }
+        }
+
+        return stops;
+    }
+
+    void validateTopActivitiesLocked() {
+        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            final ActivityStack stack = mStacks.get(stackNdx);
+            final ActivityRecord r = stack.topRunningActivityLocked(null);
+            final ActivityState state = r == null ? ActivityState.DESTROYED : r.state;
+            if (isFrontStack(stack)) {
+                if (r == null) {
+                    Slog.e(TAG, "validateTop...: null top activity, stack=" + stack);
+                } else {
+                    final ActivityRecord pausing = stack.mPausingActivity;
+                    if (pausing != null && pausing == r) {
+                        Slog.e(TAG, "validateTop...: top stack has pausing activity r=" + r +
+                            " state=" + state);
+                    }
+                    if (state != ActivityState.INITIALIZING && state != ActivityState.RESUMED) {
+                        Slog.e(TAG, "validateTop...: activity in front not resumed r=" + r +
+                                " state=" + state);
+                    }
+                }
+            } else {
+                final ActivityRecord resumed = stack.mResumedActivity;
+                if (resumed != null && resumed == r) {
+                    Slog.e(TAG, "validateTop...: back stack has resumed activity r=" + r +
+                        " state=" + state);
+                }
+                if (r != null && (state == ActivityState.INITIALIZING
+                        || state == ActivityState.RESUMED)) {
+                    Slog.e(TAG, "validateTop...: activity in back resumed r=" + r +
+                            " state=" + state);
+                }
+            }
+        }
+    }
+
+    private static String stackStateToString(int stackState) {
+        switch (stackState) {
+            case STACK_STATE_HOME_IN_FRONT: return "STACK_STATE_HOME_IN_FRONT";
+            case STACK_STATE_HOME_TO_BACK: return "STACK_STATE_HOME_TO_BACK";
+            case STACK_STATE_HOME_IN_BACK: return "STACK_STATE_HOME_IN_BACK";
+            case STACK_STATE_HOME_TO_FRONT: return "STACK_STATE_HOME_TO_FRONT";
+            default: return "Unknown stackState=" + stackState;
+        }
+    }
+
+    public void dump(PrintWriter pw, String prefix) {
+        pw.print(prefix); pw.print("mDismissKeyguardOnNextActivity:");
+                pw.println(mDismissKeyguardOnNextActivity);
+        pw.print(prefix); pw.print("mStackState="); pw.println(stackStateToString(mStackState));
+        pw.print(prefix); pw.println("mSleepTimeout: " + mSleepTimeout);
+        pw.print(prefix); pw.println("mCurTaskId: " + mCurTaskId);
+        pw.print(prefix); pw.print("mHomePackageNames:");
+                for (int i = 0; i < mHomePackageNames.size(); ++i) {
+                    pw.print(" ("); pw.print(mHomePackageNames.keyAt(i)); pw.print(",");
+                    pw.print(mHomePackageNames.valueAt(i)); pw.print(")");
+                }
+                pw.println();
+    }
+
+    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
+        return getFocusedStack().getDumpActivitiesLocked(name);
+    }
+
+    static boolean printThisActivity(PrintWriter pw, ActivityRecord activity, String dumpPackage,
+            boolean needSep, String prefix) {
+        if (activity != null) {
+            if (dumpPackage == null || dumpPackage.equals(activity.packageName)) {
+                if (needSep) {
+                    pw.println();
+                }
+                pw.print(prefix);
+                pw.println(activity);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
+            boolean dumpClient, String dumpPackage) {
+        boolean printed = false;
+        boolean needSep = false;
+        final int numStacks = mStacks.size();
+        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
+            final ActivityStack stack = mStacks.get(stackNdx);
+            StringBuilder stackHeader = new StringBuilder(128);
+            stackHeader.append("  Stack #");
+            stackHeader.append(mStacks.indexOf(stack));
+            stackHeader.append(":");
+            printed |= stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage, needSep,
+                    stackHeader.toString());
+            printed |= dumpHistoryList(fd, pw, stack.mLRUActivities, "    ", "Run", false, !dumpAll,
+                    false, dumpPackage, true, "    Running activities (most recent first):", null);
+
+            needSep = printed;
+            boolean pr = printThisActivity(pw, stack.mPausingActivity, dumpPackage, needSep,
+                    "    mPausingActivity: ");
+            if (pr) {
+                printed = true;
+                needSep = false;
+            }
+            pr = printThisActivity(pw, stack.mResumedActivity, dumpPackage, needSep,
+                    "    mResumedActivity: ");
+            if (pr) {
+                printed = true;
+                needSep = false;
+            }
+            if (dumpAll) {
+                pr = printThisActivity(pw, stack.mLastPausedActivity, dumpPackage, needSep,
+                        "    mLastPausedActivity: ");
+                if (pr) {
+                    printed = true;
+                    needSep = true;
+                }
+                printed |= printThisActivity(pw, stack.mLastNoHistoryActivity, dumpPackage,
+                        needSep, "    mLastNoHistoryActivity: ");
+            }
+            needSep = printed;
+        }
+
+        printed |= dumpHistoryList(fd, pw, mFinishingActivities, "  ", "Fin", false, !dumpAll,
+                false, dumpPackage, true, "  Activities waiting to finish:", null);
+        printed |= dumpHistoryList(fd, pw, mStoppingActivities, "  ", "Stop", false, !dumpAll,
+                false, dumpPackage, true, "  Activities waiting to stop:", null);
+        printed |= dumpHistoryList(fd, pw, mWaitingVisibleActivities, "  ", "Wait", false, !dumpAll,
+                false, dumpPackage, true, "  Activities waiting for another to become visible:",
+                null);
+        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
+                false, dumpPackage, true, "  Activities waiting to sleep:", null);
+        printed |= dumpHistoryList(fd, pw, mGoingToSleepActivities, "  ", "Sleep", false, !dumpAll,
+                false, dumpPackage, true, "  Activities waiting to sleep:", null);
+
+        return printed;
+    }
+
+    static boolean dumpHistoryList(FileDescriptor fd, PrintWriter pw, List<ActivityRecord> list,
+            String prefix, String label, boolean complete, boolean brief, boolean client,
+            String dumpPackage, boolean needNL, String header1, String header2) {
+        TaskRecord lastTask = null;
+        String innerPrefix = null;
+        String[] args = null;
+        boolean printed = false;
+        for (int i=list.size()-1; i>=0; i--) {
+            final ActivityRecord r = list.get(i);
+            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
+                continue;
+            }
+            if (innerPrefix == null) {
+                innerPrefix = prefix + "      ";
+                args = new String[0];
+            }
+            printed = true;
+            final boolean full = !brief && (complete || !r.isInHistory());
+            if (needNL) {
+                pw.println("");
+                needNL = false;
+            }
+            if (header1 != null) {
+                pw.println(header1);
+                header1 = null;
+            }
+            if (header2 != null) {
+                pw.println(header2);
+                header2 = null;
+            }
+            if (lastTask != r.task) {
+                lastTask = r.task;
+                pw.print(prefix);
+                pw.print(full ? "* " : "  ");
+                pw.println(lastTask);
+                if (full) {
+                    lastTask.dump(pw, prefix + "  ");
+                } else if (complete) {
+                    // Complete + brief == give a summary.  Isn't that obvious?!?
+                    if (lastTask.intent != null) {
+                        pw.print(prefix); pw.print("  ");
+                                pw.println(lastTask.intent.toInsecureStringWithClip());
+                    }
+                }
+            }
+            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
+            pw.print(" #"); pw.print(i); pw.print(": ");
+            pw.println(r);
+            if (full) {
+                r.dump(pw, innerPrefix);
+            } else if (complete) {
+                // Complete + brief == give a summary.  Isn't that obvious?!?
+                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
+                if (r.app != null) {
+                    pw.print(innerPrefix); pw.println(r.app);
+                }
+            }
+            if (client && r.app != null && r.app.thread != null) {
+                // flush anything that is already in the PrintWriter since the thread is going
+                // to write to the file descriptor directly
+                pw.flush();
+                try {
+                    TransferPipe tp = new TransferPipe();
+                    try {
+                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
+                                r.appToken, innerPrefix, args);
+                        // Short timeout, since blocking here can
+                        // deadlock with the application.
+                        tp.go(fd, 2000);
+                    } finally {
+                        tp.kill();
+                    }
+                } catch (IOException e) {
+                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
+                } catch (RemoteException e) {
+                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
+                }
+                needNL = true;
+            }
+        }
+        return printed;
+    }
+
+    void scheduleIdleTimeoutLocked(ActivityRecord next) {
+        if (DEBUG_IDLE) Slog.d(TAG, "scheduleIdleTimeoutLocked: Callers=" + Debug.getCallers(4));
+        Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next);
+        mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
+    }
+
+    final void scheduleIdleLocked() {
+        mHandler.sendEmptyMessage(IDLE_NOW_MSG);
+    }
+
+    void removeTimeoutsForActivityLocked(ActivityRecord r) {
+        if (DEBUG_IDLE) Slog.d(TAG, "removeTimeoutsForActivity: Callers=" + Debug.getCallers(4));
+        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
+    }
+
+    final void scheduleResumeTopActivities() {
+        mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
+    }
+
+    void removeSleepTimeouts() {
+        mSleepTimeout = false;
+        mHandler.removeMessages(SLEEP_TIMEOUT_MSG);
+    }
+
+    final void scheduleSleepTimeout() {
+        removeSleepTimeouts();
+        mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
+    }
+
+    private final class ActivityStackSupervisorHandler extends Handler {
+
+        public ActivityStackSupervisorHandler(Looper looper) {
+            super(looper);
+        }
+
+        void activityIdleInternal(ActivityRecord r) {
+            synchronized (mService) {
+                activityIdleInternalLocked(r != null ? r.appToken : null, true, null);
+            }
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case IDLE_TIMEOUT_MSG: {
+                    if (DEBUG_IDLE) Slog.d(TAG, "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);
+                } break;
+                case IDLE_NOW_MSG: {
+                    if (DEBUG_IDLE) Slog.d(TAG, "handleMessage: IDLE_NOW_MSG: r=" + msg.obj);
+                    activityIdleInternal((ActivityRecord)msg.obj);
+                } break;
+                case RESUME_TOP_ACTIVITY_MSG: {
+                    synchronized (mService) {
+                        resumeTopActivitiesLocked();
+                    }
+                } break;
+                case SLEEP_TIMEOUT_MSG: {
+                    synchronized (mService) {
+                        if (mService.isSleepingOrShuttingDown()) {
+                            Slog.w(TAG, "Sleep timeout!  Sleeping now.");
+                            mSleepTimeout = true;
+                            checkReadyForSleepLocked();
+                        }
+                    }
+                } 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!");
+                            if (VALIDATE_WAKE_LOCK_CALLER
+                                    && Binder.getCallingUid() != Process.myUid()) {
+                                throw new IllegalStateException("Calling must be system uid");
+                            }
+                            mLaunchingActivity.release();
+                        }
+                    }
+                } break;
+            }
+        }
+    }
+
+    String getHomePackageName() {
+        return mHomePackageNames.get(mCurrentUser);
+    }
+
+    void setHomePackageName(int userId, String homePackageName) {
+        if (DEBUG_SWITCH) Slog.d(TAG, "setHomePackageName: user=" + userId + " package="
+                + homePackageName);
+        mHomePackageNames.put(userId, homePackageName);
+    }
+}
diff --git a/services/java/com/android/server/am/AppBindRecord.java b/services/java/com/android/server/am/AppBindRecord.java
index f1c54fa..06265fd 100644
--- a/services/java/com/android/server/am/AppBindRecord.java
+++ b/services/java/com/android/server/am/AppBindRecord.java
@@ -23,7 +23,7 @@
 /**
  * An association between a service and one of its client applications.
  */
-class AppBindRecord {
+final class AppBindRecord {
     final ServiceRecord service;    // The running service.
     final IntentBindRecord intent;  // The intent we are bound to.
     final ProcessRecord client;     // Who has started/bound the service.
diff --git a/services/java/com/android/server/am/AppErrorDialog.java b/services/java/com/android/server/am/AppErrorDialog.java
index ffa1e92..bfc86b0 100644
--- a/services/java/com/android/server/am/AppErrorDialog.java
+++ b/services/java/com/android/server/am/AppErrorDialog.java
@@ -25,7 +25,7 @@
 import android.os.Message;
 import android.view.WindowManager;
 
-class AppErrorDialog extends BaseErrorDialog {
+final class AppErrorDialog extends BaseErrorDialog {
     private final ActivityManagerService mService;
     private final AppErrorResult mResult;
     private final ProcessRecord mProc;
diff --git a/services/java/com/android/server/am/AppErrorResult.java b/services/java/com/android/server/am/AppErrorResult.java
index ebfcfe2..c6a5720 100644
--- a/services/java/com/android/server/am/AppErrorResult.java
+++ b/services/java/com/android/server/am/AppErrorResult.java
@@ -16,8 +16,7 @@
 
 package com.android.server.am;
 
-
-class AppErrorResult {
+final class AppErrorResult {
     public void set(int res) {
         synchronized (this) {
             mHasResult = true;
diff --git a/services/java/com/android/server/am/AppNotRespondingDialog.java b/services/java/com/android/server/am/AppNotRespondingDialog.java
index af61c9b..b5e0715 100644
--- a/services/java/com/android/server/am/AppNotRespondingDialog.java
+++ b/services/java/com/android/server/am/AppNotRespondingDialog.java
@@ -28,7 +28,7 @@
 import android.util.Slog;
 import android.view.WindowManager;
 
-class AppNotRespondingDialog extends BaseErrorDialog {
+final class AppNotRespondingDialog extends BaseErrorDialog {
     private static final String TAG = "AppNotRespondingDialog";
 
     // Event 'what' codes
diff --git a/services/java/com/android/server/am/AppWaitingForDebuggerDialog.java b/services/java/com/android/server/am/AppWaitingForDebuggerDialog.java
index d08bb10..27865a8 100644
--- a/services/java/com/android/server/am/AppWaitingForDebuggerDialog.java
+++ b/services/java/com/android/server/am/AppWaitingForDebuggerDialog.java
@@ -22,7 +22,7 @@
 import android.os.Message;
 import android.view.WindowManager;
 
-class AppWaitingForDebuggerDialog extends BaseErrorDialog {
+final class AppWaitingForDebuggerDialog extends BaseErrorDialog {
     final ActivityManagerService mService;
     final ProcessRecord mProc;
     private CharSequence mAppName;
diff --git a/services/java/com/android/server/am/BackupRecord.java b/services/java/com/android/server/am/BackupRecord.java
index 7e73106..5fa7e6a 100644
--- a/services/java/com/android/server/am/BackupRecord.java
+++ b/services/java/com/android/server/am/BackupRecord.java
@@ -21,7 +21,7 @@
 import android.content.pm.ApplicationInfo;
 
 /** @hide */
-class BackupRecord {
+final class BackupRecord {
     // backup/restore modes
     public static final int BACKUP_NORMAL = 0;
     public static final int BACKUP_FULL = 1;
diff --git a/services/java/com/android/server/am/BatteryStatsService.java b/services/java/com/android/server/am/BatteryStatsService.java
index d19c7f6..0dd950e 100644
--- a/services/java/com/android/server/am/BatteryStatsService.java
+++ b/services/java/com/android/server/am/BatteryStatsService.java
@@ -22,11 +22,13 @@
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
+import android.os.BatteryStats;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Process;
 import android.os.ServiceManager;
+import android.os.UserHandle;
 import android.os.WorkSource;
 import android.telephony.SignalStrength;
 import android.telephony.TelephonyManager;
@@ -58,7 +60,7 @@
     
     public void publish(Context context) {
         mContext = context;
-        ServiceManager.addService("batteryinfo", asBinder());
+        ServiceManager.addService(BatteryStats.SERVICE_NAME, asBinder());
         mStats.setNumSpeedSteps(new PowerProfile(mContext).getNumSpeedSteps());
         mStats.setRadioScanningTimeout(mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_radioScanningTimeout)
@@ -76,7 +78,7 @@
         if (sService != null) {
             return sService;
         }
-        IBinder b = ServiceManager.getService("batteryinfo");
+        IBinder b = ServiceManager.getService(BatteryStats.SERVICE_NAME);
         sService = asInterface(b);
         return sService;
     }
@@ -431,6 +433,7 @@
         }
     }
 
+    @Override
     public void noteNetworkInterfaceType(String iface, int type) {
         enforceCallingPermission();
         synchronized (mStats) {
@@ -438,6 +441,14 @@
         }
     }
 
+    @Override
+    public void noteNetworkStatsEnabled() {
+        enforceCallingPermission();
+        synchronized (mStats) {
+            mStats.noteNetworkStatsEnabledLocked();
+        }
+    }
+
     public boolean isOnBattery() {
         return mStats.isOnBattery();
     }
@@ -469,12 +480,14 @@
     }
     
     private void dumpHelp(PrintWriter pw) {
-        pw.println("Battery stats (batteryinfo) dump options:");
-        pw.println("  [--checkin] [--reset] [--write] [-h]");
+        pw.println("Battery stats (batterystats) dump options:");
+        pw.println("  [--checkin] [-c] [--unplugged] [--reset] [--write] [-h] [<package.name>]");
         pw.println("  --checkin: format output for a checkin report.");
+        pw.println("  --unplugged: only output data since last unplugged.");
         pw.println("  --reset: reset the stats, clearing all current data.");
         pw.println("  --write: force write current collected stats to disk.");
         pw.println("  -h: print this help text.");
+        pw.println("  <package.name>: optional name of package to filter output by.");
     }
 
     @Override
@@ -488,11 +501,19 @@
         }
 
         boolean isCheckin = false;
+        boolean includeHistory = false;
+        boolean isUnpluggedOnly = false;
         boolean noOutput = false;
+        int reqUid = -1;
         if (args != null) {
             for (String arg : args) {
                 if ("--checkin".equals(arg)) {
                     isCheckin = true;
+                } else if ("-c".equals(arg)) {
+                    isCheckin = true;
+                    includeHistory = true;
+                } else if ("--unplugged".equals(arg)) {
+                    isUnpluggedOnly = true;
                 } else if ("--reset".equals(arg)) {
                     synchronized (mStats) {
                         mStats.resetAllStatsLocked();
@@ -510,9 +531,20 @@
                     return;
                 } else if ("-a".equals(arg)) {
                     // fall through
-                } else {
+                } else if (arg.length() > 0 && arg.charAt(0) == '-'){
                     pw.println("Unknown option: " + arg);
                     dumpHelp(pw);
+                    return;
+                } else {
+                    // Not an option, last argument must be a package name.
+                    try {
+                        reqUid = mContext.getPackageManager().getPackageUid(arg,
+                                UserHandle.getCallingUserId());
+                    } catch (PackageManager.NameNotFoundException e) {
+                        pw.println("Unknown package: " + arg);
+                        dumpHelp(pw);
+                        return;
+                    }
                 }
             }
         }
@@ -522,11 +554,11 @@
         if (isCheckin) {
             List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(0);
             synchronized (mStats) {
-                mStats.dumpCheckinLocked(pw, args, apps);
+                mStats.dumpCheckinLocked(pw, apps, isUnpluggedOnly, includeHistory);
             }
         } else {
             synchronized (mStats) {
-                mStats.dumpLocked(pw);
+                mStats.dumpLocked(pw, isUnpluggedOnly, reqUid);
             }
         }
     }
diff --git a/services/java/com/android/server/am/BroadcastFilter.java b/services/java/com/android/server/am/BroadcastFilter.java
index c631b6e..986b8ea 100644
--- a/services/java/com/android/server/am/BroadcastFilter.java
+++ b/services/java/com/android/server/am/BroadcastFilter.java
@@ -22,7 +22,7 @@
 
 import java.io.PrintWriter;
 
-class BroadcastFilter extends IntentFilter {
+final class BroadcastFilter extends IntentFilter {
     // Back-pointer to the list this filter is in.
     final ReceiverList receiverList;
     final String packageName;
diff --git a/services/java/com/android/server/am/BroadcastQueue.java b/services/java/com/android/server/am/BroadcastQueue.java
index ac7eb89..254a219 100644
--- a/services/java/com/android/server/am/BroadcastQueue.java
+++ b/services/java/com/android/server/am/BroadcastQueue.java
@@ -47,7 +47,7 @@
  * We keep two broadcast queues and associated bookkeeping, one for those at
  * foreground priority, and one for normal (background-priority) broadcasts.
  */
-public class BroadcastQueue {
+public final class BroadcastQueue {
     static final String TAG = "BroadcastQueue";
     static final String TAG_MU = ActivityManagerService.TAG_MU;
     static final boolean DEBUG_BROADCAST = ActivityManagerService.DEBUG_BROADCAST;
@@ -217,6 +217,7 @@
         r.receiver = app.thread.asBinder();
         r.curApp = app;
         app.curReceiver = r;
+        app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_RECEIVER);
         mService.updateLruProcessLocked(app, true);
 
         // Tell the application to launch this receiver.
@@ -230,7 +231,8 @@
             mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
             app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
                     mService.compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
-                    r.resultCode, r.resultData, r.resultExtras, r.ordered, r.userId);
+                    r.resultCode, r.resultData, r.resultExtras, r.ordered, r.userId,
+                    app.repProcState);
             if (DEBUG_BROADCAST)  Slog.v(TAG,
                     "Process cur broadcast " + r + " DELIVERED for app " + app);
             started = true;
@@ -371,7 +373,7 @@
             // If we have an app thread, do the call through that so it is
             // correctly ordered with other one-way calls.
             app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
-                    data, extras, ordered, sticky, sendingUser);
+                    data, extras, ordered, sticky, sendingUser, app.repProcState);
         } else {
             receiver.performReceive(intent, resultCode, data, extras, ordered,
                     sticky, sendingUser);
@@ -410,7 +412,7 @@
             }
         }
         if (r.appOp != AppOpsManager.OP_NONE) {
-            int mode = mService.mAppOpsService.checkOperation(r.appOp,
+            int mode = mService.mAppOpsService.noteOperation(r.appOp,
                     filter.receiverList.uid, filter.packageName);
             if (mode != AppOpsManager.MODE_ALLOWED) {
                 if (DEBUG_BROADCAST)  Slog.v(TAG,
@@ -419,6 +421,10 @@
                 skip = true;
             }
         }
+        if (!skip) {
+            skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
+                    r.callingPid, r.resolvedType, filter.receiverList.uid);
+        }
 
         if (!skip) {
             // If this is not being sent as an ordered broadcast, then we
@@ -437,7 +443,7 @@
                     // are already core system stuff so don't matter for this.
                     r.curApp = filter.receiverList.app;
                     filter.receiverList.app.curReceiver = r;
-                    mService.updateOomAdjLocked();
+                    mService.updateOomAdjLocked(r.curApp, true);
                 }
             }
             try {
@@ -717,7 +723,7 @@
                 }
             }
             if (r.appOp != AppOpsManager.OP_NONE) {
-                int mode = mService.mAppOpsService.checkOperation(r.appOp,
+                int mode = mService.mAppOpsService.noteOperation(r.appOp,
                         info.activityInfo.applicationInfo.uid, info.activityInfo.packageName);
                 if (mode != AppOpsManager.MODE_ALLOWED) {
                     if (DEBUG_BROADCAST)  Slog.v(TAG,
@@ -727,6 +733,10 @@
                     skip = true;
                 }
             }
+            if (!skip) {
+                skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
+                        r.callingPid, r.resolvedType, info.activityInfo.applicationInfo.uid);
+            }
             boolean isSingleton = false;
             try {
                 isSingleton = mService.isSingleton(info.activityInfo.processName,
@@ -795,7 +805,7 @@
                     info.activityInfo.applicationInfo.uid);
             if (app != null && app.thread != null) {
                 try {
-                    app.addPackage(info.activityInfo.packageName);
+                    app.addPackage(info.activityInfo.packageName, mService.mProcessStats);
                     processCurBroadcastLocked(r, app);
                     return;
                 } catch (RemoteException e) {
diff --git a/services/java/com/android/server/am/BroadcastRecord.java b/services/java/com/android/server/am/BroadcastRecord.java
index 83cc0ea..db61e88 100644
--- a/services/java/com/android/server/am/BroadcastRecord.java
+++ b/services/java/com/android/server/am/BroadcastRecord.java
@@ -36,7 +36,7 @@
 /**
  * An active intent broadcast.
  */
-class BroadcastRecord extends Binder {
+final class BroadcastRecord extends Binder {
     final Intent intent;    // the original intent that generated us
     final ComponentName targetComp; // original component name set on the intent
     final ProcessRecord callerApp; // process that sent this
@@ -47,6 +47,7 @@
     final boolean sticky;   // originated from existing sticky data?
     final boolean initialSticky; // initial broadcast from register to sticky?
     final int userId;       // user id this broadcast was for
+    final String resolvedType; // the resolved data type
     final String requiredPermission; // a permission the caller has required
     final int appOp;        // an app op that is associated with this broadcast
     final List receivers;   // contains BroadcastFilter and ResolveInfo
@@ -171,8 +172,8 @@
 
     BroadcastRecord(BroadcastQueue _queue,
             Intent _intent, ProcessRecord _callerApp, String _callerPackage,
-            int _callingPid, int _callingUid, String _requiredPermission, int _appOp,
-            List _receivers, IIntentReceiver _resultTo, int _resultCode,
+            int _callingPid, int _callingUid, String _resolvedType, String _requiredPermission,
+            int _appOp, List _receivers, IIntentReceiver _resultTo, int _resultCode,
             String _resultData, Bundle _resultExtras, boolean _serialized,
             boolean _sticky, boolean _initialSticky,
             int _userId) {
@@ -183,6 +184,7 @@
         callerPackage = _callerPackage;
         callingPid = _callingPid;
         callingUid = _callingUid;
+        resolvedType = _resolvedType;
         requiredPermission = _requiredPermission;
         appOp = _appOp;
         receivers = _receivers;
diff --git a/services/java/com/android/server/am/CompatModeDialog.java b/services/java/com/android/server/am/CompatModeDialog.java
index 0442bda..202cc7c 100644
--- a/services/java/com/android/server/am/CompatModeDialog.java
+++ b/services/java/com/android/server/am/CompatModeDialog.java
@@ -28,7 +28,7 @@
 import android.widget.CompoundButton;
 import android.widget.Switch;
 
-public class CompatModeDialog extends Dialog {
+public final class CompatModeDialog extends Dialog {
     final ActivityManagerService mService;
     final ApplicationInfo mAppInfo;
 
diff --git a/services/java/com/android/server/am/CompatModePackages.java b/services/java/com/android/server/am/CompatModePackages.java
index 3a6492e..59e6787 100644
--- a/services/java/com/android/server/am/CompatModePackages.java
+++ b/services/java/com/android/server/am/CompatModePackages.java
@@ -15,7 +15,6 @@
 
 import android.app.ActivityManager;
 import android.app.AppGlobals;
-import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.res.CompatibilityInfo;
@@ -26,7 +25,7 @@
 import android.util.Slog;
 import android.util.Xml;
 
-public class CompatModePackages {
+public final class CompatModePackages {
     private final String TAG = ActivityManagerService.TAG;
     private final boolean DEBUG_CONFIGURATION = ActivityManagerService.DEBUG_CONFIGURATION;
 
@@ -166,7 +165,7 @@
     }
 
     public boolean getFrontActivityAskCompatModeLocked() {
-        ActivityRecord r = mService.mMainStack.topRunningActivityLocked(null);
+        ActivityRecord r = mService.getFocusedStack().topRunningActivityLocked(null);
         if (r == null) {
             return false;
         }
@@ -178,7 +177,7 @@
     }
 
     public void setFrontActivityAskCompatModeLocked(boolean ask) {
-        ActivityRecord r = mService.mMainStack.topRunningActivityLocked(null);
+        ActivityRecord r = mService.getFocusedStack().topRunningActivityLocked(null);
         if (r != null) {
             setPackageAskCompatModeLocked(r.packageName, ask);
         }
@@ -200,7 +199,7 @@
     }
 
     public int getFrontActivityScreenCompatModeLocked() {
-        ActivityRecord r = mService.mMainStack.topRunningActivityLocked(null);
+        ActivityRecord r = mService.getFocusedStack().topRunningActivityLocked(null);
         if (r == null) {
             return ActivityManager.COMPAT_MODE_UNKNOWN;
         }
@@ -208,7 +207,7 @@
     }
 
     public void setFrontActivityScreenCompatModeLocked(int mode) {
-        ActivityRecord r = mService.mMainStack.topRunningActivityLocked(null);
+        ActivityRecord r = mService.getFocusedStack().topRunningActivityLocked(null);
         if (r == null) {
             Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
             return;
@@ -295,25 +294,13 @@
             Message msg = mHandler.obtainMessage(MSG_WRITE);
             mHandler.sendMessageDelayed(msg, 10000);
 
-            ActivityRecord starting = mService.mMainStack.topRunningActivityLocked(null);
-
-            // All activities that came from the package must be
-            // restarted as if there was a config change.
-            for (int i=mService.mMainStack.mHistory.size()-1; i>=0; i--) {
-                ActivityRecord a = (ActivityRecord)mService.mMainStack.mHistory.get(i);
-                if (a.info.packageName.equals(packageName)) {
-                    a.forceNewConfig = true;
-                    if (starting != null && a == starting && a.visible) {
-                        a.startFreezingScreenLocked(starting.app,
-                                ActivityInfo.CONFIG_SCREEN_LAYOUT);
-                    }
-                }
-            }
+            final ActivityStack stack = mService.getFocusedStack();
+            ActivityRecord starting = stack.restartPackage(packageName);
 
             // Tell all processes that loaded this package about the change.
             for (int i=mService.mLruProcesses.size()-1; i>=0; i--) {
                 ProcessRecord app = mService.mLruProcesses.get(i);
-                if (!app.pkgList.contains(packageName)) {
+                if (!app.pkgList.containsKey(packageName)) {
                     continue;
                 }
                 try {
@@ -327,10 +314,10 @@
             }
 
             if (starting != null) {
-                mService.mMainStack.ensureActivityConfigurationLocked(starting, 0);
+                stack.ensureActivityConfigurationLocked(starting, 0);
                 // And we need to make sure at this point that all other activities
                 // are made visible with the correct configuration.
-                mService.mMainStack.ensureActivitiesVisibleLocked(starting, 0);
+                stack.ensureActivitiesVisibleLocked(starting, 0);
             }
         }
     }
diff --git a/services/java/com/android/server/am/ConnectionRecord.java b/services/java/com/android/server/am/ConnectionRecord.java
index 4ed3c31..576adc2 100644
--- a/services/java/com/android/server/am/ConnectionRecord.java
+++ b/services/java/com/android/server/am/ConnectionRecord.java
@@ -25,7 +25,7 @@
 /**
  * Description of a single binding to a service.
  */
-class ConnectionRecord {
+final class ConnectionRecord {
     final AppBindRecord binding;    // The application/service binding.
     final ActivityRecord activity;   // If non-null, the owning activity.
     final IServiceConnection conn;  // The client connection.
@@ -89,12 +89,15 @@
         if ((flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
             sb.append("ACT ");
         }
-        if ((flags&Context.BIND_NOT_VISIBLE) != 0) {
-            sb.append("!VIS ");
-        }
         if ((flags&Context.BIND_VISIBLE) != 0) {
             sb.append("VIS ");
         }
+        if ((flags&Context.BIND_SHOWING_UI) != 0) {
+            sb.append("UI ");
+        }
+        if ((flags&Context.BIND_NOT_VISIBLE) != 0) {
+            sb.append("!VIS ");
+        }
         if (serviceDead) {
             sb.append("DEAD ");
         }
diff --git a/services/java/com/android/server/am/ContentProviderConnection.java b/services/java/com/android/server/am/ContentProviderConnection.java
index 7f69b24..f2c9e2f 100644
--- a/services/java/com/android/server/am/ContentProviderConnection.java
+++ b/services/java/com/android/server/am/ContentProviderConnection.java
@@ -23,7 +23,7 @@
 /**
  * Represents a link between a content provider and client.
  */
-public class ContentProviderConnection extends Binder {
+public final class ContentProviderConnection extends Binder {
     public final ContentProviderRecord provider;
     public final ProcessRecord client;
     public final long createTime;
diff --git a/services/java/com/android/server/am/ContentProviderRecord.java b/services/java/com/android/server/am/ContentProviderRecord.java
index 8fb6a93..646b7d2 100644
--- a/services/java/com/android/server/am/ContentProviderRecord.java
+++ b/services/java/com/android/server/am/ContentProviderRecord.java
@@ -33,7 +33,7 @@
 import java.util.HashMap;
 import java.util.HashSet;
 
-class ContentProviderRecord {
+final class ContentProviderRecord {
     final ActivityManagerService service;
     public final ProviderInfo info;
     final int uid;
diff --git a/services/java/com/android/server/am/CoreSettingsObserver.java b/services/java/com/android/server/am/CoreSettingsObserver.java
index 585cf2b..10ea67c 100644
--- a/services/java/com/android/server/am/CoreSettingsObserver.java
+++ b/services/java/com/android/server/am/CoreSettingsObserver.java
@@ -33,7 +33,7 @@
  * disk I/O operations. Note: This class assumes that all core settings reside
  * in {@link Settings.Secure}.
  */
-class CoreSettingsObserver extends ContentObserver {
+final class CoreSettingsObserver extends ContentObserver {
     private static final String LOG_TAG = CoreSettingsObserver.class.getSimpleName();
 
     // mapping form property name to its type
diff --git a/services/java/com/android/server/am/DeviceMonitor.java b/services/java/com/android/server/am/DeviceMonitor.java
deleted file mode 100644
index 21e7252..0000000
--- a/services/java/com/android/server/am/DeviceMonitor.java
+++ /dev/null
@@ -1,234 +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.server.am;
-
-import android.os.SELinux;
-import android.util.Slog;
-
-import java.io.*;
-import java.util.Arrays;
-
-/**
- * Monitors device resources periodically for some period of time. Useful for
- * tracking down performance problems.
- */
-class DeviceMonitor {
-
-    private static final String LOG_TAG = DeviceMonitor.class.getName();
-
-    /** Number of samples to take. */
-    private static final int SAMPLE_COUNT = 10;
-
-    /** Time to wait in ms between samples. */
-    private static final int INTERVAL = 1000;
-
-    /** Time to wait in ms between samples. */
-    private static final int MAX_FILES = 30;
-
-    private final byte[] buffer = new byte[1024];
-
-    /** Is the monitor currently running? */
-    private boolean running = false;
-
-    private DeviceMonitor() {
-        new Thread() {
-            public void run() {
-                monitor();
-            }
-        }.start();
-    }
-
-    /**
-     * Loops continuously. Pauses until someone tells us to start monitoring.
-     */
-    @SuppressWarnings("InfiniteLoopStatement")
-    private void monitor() {
-        while (true) {
-            waitForStart();
-
-            purge();
-
-            for (int i = 0; i < SAMPLE_COUNT; i++) {
-                try {
-                    dump();
-                } catch (IOException e) {
-                    Slog.w(LOG_TAG, "Dump failed.", e);
-                }
-                pause();
-            }
-
-            stop();
-        }
-    }
-
-    private static final File PROC = new File("/proc");
-    private static final File BASE = new File("/data/anr/");
-    static {
-        if (!BASE.isDirectory() && !BASE.mkdirs()) {
-            throw new AssertionError("Couldn't create " + BASE + ".");
-        }
-        if (!SELinux.restorecon(BASE)) {
-            throw new AssertionError("Couldn't restorecon " + BASE + ".");
-        }
-    }
-
-    private static final File[] PATHS = {
-        new File(PROC, "zoneinfo"),
-        new File(PROC, "interrupts"),
-        new File(PROC, "meminfo"),
-        new File(PROC, "slabinfo"),
-    };
-
-
-    /**
-     * Deletes old files.
-     */
-    private void purge() {
-        File[] files = BASE.listFiles();
-        int count = files.length - MAX_FILES;
-        if (count > 0) {
-            Arrays.sort(files);
-            for (int i = 0; i < count; i++) {
-                if (!files[i].delete()) {
-                    Slog.w(LOG_TAG, "Couldn't delete " + files[i] + ".");
-                }
-            }
-        }
-    }
-
-    /**
-     * Dumps the current device stats to a new file.
-     */
-    private void dump() throws IOException {
-        OutputStream out = new FileOutputStream(
-                new File(BASE, String.valueOf(System.currentTimeMillis())));
-        try {
-            // Copy /proc/*/stat
-            for (File processDirectory : PROC.listFiles()) {
-                if (isProcessDirectory(processDirectory)) {
-                    dump(new File(processDirectory, "stat"), out);
-                }
-            }
-
-            // Copy other files.
-            for (File file : PATHS) {
-                dump(file, out);
-            }
-        } finally {
-            closeQuietly(out);
-        }
-    }
-
-    /**
-     * Returns true if the given file represents a process directory.
-     */
-    private static boolean isProcessDirectory(File file) {
-        try {
-            Integer.parseInt(file.getName());
-            return file.isDirectory();
-        } catch (NumberFormatException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Copies from a file to an output stream.
-     */
-    private void dump(File from, OutputStream out) throws IOException {
-        writeHeader(from, out);
-        
-        FileInputStream in = null;
-        try {
-            in = new FileInputStream(from);
-            int count;
-            while ((count = in.read(buffer)) != -1) {
-                out.write(buffer, 0, count);
-            }
-        } finally {
-            closeQuietly(in);
-        }
-    }
-
-    /**
-     * Writes a header for the given file.
-     */
-    private static void writeHeader(File file, OutputStream out)
-            throws IOException {
-        String header = "*** " + file.toString() + "\n";
-        out.write(header.getBytes());
-    }
-
-    /**
-     * Closes the given resource. Logs exceptions.
-     * @param closeable
-     */
-    private static void closeQuietly(Closeable closeable) {
-        try {
-            if (closeable != null) {
-                closeable.close();
-            }
-        } catch (IOException e) {
-            Slog.w(LOG_TAG, e);
-        }
-    }
-
-    /**
-     * Pauses momentarily before we start the next dump.
-     */
-    private void pause() {
-        try {
-            Thread.sleep(INTERVAL);
-        } catch (InterruptedException e) { /* ignore */ }
-    }
-
-    /**
-     * Stops dumping.
-     */
-    private synchronized void stop() {
-        running = false;        
-    }
-
-    /**
-     * Waits until someone starts us.
-     */
-    private synchronized void waitForStart() {
-        while (!running) {
-            try {
-                wait();
-            } catch (InterruptedException e) { /* ignore */ }
-        }
-    }
-
-    /**
-     * Instructs the monitoring to start if it hasn't already.
-     */
-    private synchronized void startMonitoring() {
-        if (!running) {
-            running = true;
-            notifyAll();
-        }
-    }
-
-    private static DeviceMonitor instance = new DeviceMonitor();
-
-    /**
-     * Starts monitoring if it hasn't started already.
-     */
-    static void start() {
-        instance.startMonitoring();
-    }
-}
diff --git a/services/java/com/android/server/am/EventLogTags.logtags b/services/java/com/android/server/am/EventLogTags.logtags
index f784861..d3cc56b 100644
--- a/services/java/com/android/server/am/EventLogTags.logtags
+++ b/services/java/com/android/server/am/EventLogTags.logtags
@@ -63,7 +63,7 @@
 30024 am_broadcast_discard_filter (User|1|5),(Broadcast|1|5),(Action|3),(Receiver Number|1|1),(BroadcastFilter|1|5)
 30025 am_broadcast_discard_app (User|1|5),(Broadcast|1|5),(Action|3),(Receiver Number|1|1),(App|3)
 # A service is being created
-30030 am_create_service (User|1|5),(Service Record|1|5),(Name|3),(PID|1|5)
+30030 am_create_service (User|1|5),(Service Record|1|5),(Name|3),(UID|1|5),(PID|1|5)
 # A service is being destroyed
 30031 am_destroy_service (User|1|5),(Service Record|1|5),(PID|1|5)
 # A process has crashed too many times, it is being cleared
@@ -86,3 +86,6 @@
 
 # User switched
 30041 am_switch_user (id|1|5)
+
+# Activity fully drawn time
+30042 am_activity_fully_drawn_time (User|1|5),(Token|1|5),(Component Name|3),(time|2|3)
diff --git a/services/java/com/android/server/am/FactoryErrorDialog.java b/services/java/com/android/server/am/FactoryErrorDialog.java
index 0ffb588..f4632c1 100644
--- a/services/java/com/android/server/am/FactoryErrorDialog.java
+++ b/services/java/com/android/server/am/FactoryErrorDialog.java
@@ -22,7 +22,7 @@
 import android.os.Message;
 import android.view.WindowManager;
 
-class FactoryErrorDialog extends BaseErrorDialog {
+final class FactoryErrorDialog extends BaseErrorDialog {
     public FactoryErrorDialog(Context context, CharSequence msg) {
         super(context);
         setCancelable(false);
diff --git a/services/java/com/android/server/am/IntentBindRecord.java b/services/java/com/android/server/am/IntentBindRecord.java
index 0a92964..21cf266 100644
--- a/services/java/com/android/server/am/IntentBindRecord.java
+++ b/services/java/com/android/server/am/IntentBindRecord.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.os.IBinder;
+import android.util.ArrayMap;
 
 import java.io.PrintWriter;
 import java.util.HashMap;
@@ -27,14 +28,14 @@
 /**
  * A particular Intent that has been bound to a Service.
  */
-class IntentBindRecord {
+final class IntentBindRecord {
     /** The running service. */
     final ServiceRecord service;
     /** The intent that is bound.*/
     final Intent.FilterComparison intent; // 
     /** All apps that have bound to this Intent. */
-    final HashMap<ProcessRecord, AppBindRecord> apps
-            = new HashMap<ProcessRecord, AppBindRecord>();
+    final ArrayMap<ProcessRecord, AppBindRecord> apps
+            = new ArrayMap<ProcessRecord, AppBindRecord>();
     /** Binder published from service. */
     IBinder binder;
     /** Set when we have initiated a request for this binder. */
@@ -62,15 +63,12 @@
                 pw.print(" received="); pw.print(received);
                 pw.print(" hasBound="); pw.print(hasBound);
                 pw.print(" doRebind="); pw.println(doRebind);
-        if (apps.size() > 0) {
-            Iterator<AppBindRecord> it = apps.values().iterator();
-            while (it.hasNext()) {
-                AppBindRecord a = it.next();
-                pw.print(prefix); pw.print("* Client AppBindRecord{");
-                        pw.print(Integer.toHexString(System.identityHashCode(a)));
-                        pw.print(' '); pw.print(a.client); pw.println('}');
-                a.dumpInIntentBind(pw, prefix + "  ");
-            }
+        for (int i=0; i<apps.size(); i++) {
+            AppBindRecord a = apps.valueAt(i);
+            pw.print(prefix); pw.print("* Client AppBindRecord{");
+                    pw.print(Integer.toHexString(System.identityHashCode(a)));
+                    pw.print(' '); pw.print(a.client); pw.println('}');
+            a.dumpInIntentBind(pw, prefix + "  ");
         }
     }
 
@@ -81,12 +79,11 @@
 
     int collectFlags() {
         int flags = 0;
-        if (apps.size() > 0) {
-            for (AppBindRecord app : apps.values()) {
-                if (app.connections.size() > 0) {
-                    for (ConnectionRecord conn : app.connections) {
-                        flags |= conn.flags;
-                    }
+        for (int i=apps.size()-1; i>=0; i--) {
+            AppBindRecord app = apps.valueAt(i);
+            if (app.connections.size() > 0) {
+                for (ConnectionRecord conn : app.connections) {
+                    flags |= conn.flags;
                 }
             }
         }
diff --git a/services/java/com/android/server/am/LaunchWarningWindow.java b/services/java/com/android/server/am/LaunchWarningWindow.java
index cb2b7bb..30c3066 100644
--- a/services/java/com/android/server/am/LaunchWarningWindow.java
+++ b/services/java/com/android/server/am/LaunchWarningWindow.java
@@ -26,7 +26,7 @@
 import android.widget.ImageView;
 import android.widget.TextView;
 
-public class LaunchWarningWindow extends Dialog {
+public final class LaunchWarningWindow extends Dialog {
     public LaunchWarningWindow(Context context, ActivityRecord cur, ActivityRecord next) {
         super(context, R.style.Theme_Toast);
 
diff --git a/services/java/com/android/server/am/NativeCrashListener.java b/services/java/com/android/server/am/NativeCrashListener.java
index a9454bd..2c7f1f1 100644
--- a/services/java/com/android/server/am/NativeCrashListener.java
+++ b/services/java/com/android/server/am/NativeCrashListener.java
@@ -40,7 +40,7 @@
  *
  * Note that this component runs in a separate thread.
  */
-class NativeCrashListener extends Thread {
+final class NativeCrashListener extends Thread {
     static final String TAG = "NativeCrashListener";
     static final boolean DEBUG = false;
     static final boolean MORE_DEBUG = DEBUG && false;
@@ -152,6 +152,13 @@
                                 Slog.d(TAG, "Exception writing ack: " + e.getMessage());
                             }
                         }
+                        try {
+                            Libcore.os.close(peerFd);
+                        } catch (ErrnoException e) {
+                            if (MORE_DEBUG) {
+                                Slog.d(TAG, "Exception closing socket: " + e.getMessage());
+                            }
+                        }
                     }
                 }
             }
diff --git a/services/java/com/android/server/am/PendingIntentRecord.java b/services/java/com/android/server/am/PendingIntentRecord.java
index 8ab71dd..17f24a9 100644
--- a/services/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/java/com/android/server/am/PendingIntentRecord.java
@@ -31,7 +31,7 @@
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
 
-class PendingIntentRecord extends IIntentSender.Stub {
+final class PendingIntentRecord extends IIntentSender.Stub {
     final ActivityManagerService owner;
     final Key key;
     final int uid;
@@ -259,7 +259,7 @@
                         }
                         break;
                     case ActivityManager.INTENT_SENDER_ACTIVITY_RESULT:
-                        key.activity.stack.sendActivityResultLocked(-1, key.activity,
+                        key.activity.task.stack.sendActivityResultLocked(-1, key.activity,
                                 key.who, key.requestCode, code, finalIntent);
                         break;
                     case ActivityManager.INTENT_SENDER_BROADCAST:
diff --git a/services/java/com/android/server/am/PendingThumbnailsRecord.java b/services/java/com/android/server/am/PendingThumbnailsRecord.java
index ed478c9..e4eb4d0 100644
--- a/services/java/com/android/server/am/PendingThumbnailsRecord.java
+++ b/services/java/com/android/server/am/PendingThumbnailsRecord.java
@@ -24,16 +24,16 @@
  * This class keeps track of calls to getTasks() that are still
  * waiting for thumbnail images.
  */
-class PendingThumbnailsRecord
+final class PendingThumbnailsRecord
 {
     final IThumbnailReceiver receiver;   // who is waiting.
-    HashSet pendingRecords; // HistoryRecord objects we still wait for.
+    final HashSet<ActivityRecord> pendingRecords; // HistoryRecord objects we still wait for.
     boolean finished;       // Is pendingRecords empty?
 
     PendingThumbnailsRecord(IThumbnailReceiver _receiver)
     {
         receiver = _receiver;
-        pendingRecords = new HashSet();
+        pendingRecords = new HashSet<ActivityRecord>();
         finished = false;
     }
 }
diff --git a/services/java/com/android/server/am/ProcessList.java b/services/java/com/android/server/am/ProcessList.java
index 1a635a9..54593aa 100644
--- a/services/java/com/android/server/am/ProcessList.java
+++ b/services/java/com/android/server/am/ProcessList.java
@@ -19,27 +19,35 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 
+import android.app.ActivityManager;
 import com.android.internal.util.MemInfoReader;
 import com.android.server.wm.WindowManagerService;
 
+import android.content.res.Resources;
 import android.graphics.Point;
+import android.os.SystemProperties;
 import android.util.Slog;
 import android.view.Display;
 
 /**
  * Activity manager code dealing with processes.
  */
-class ProcessList {
+final class ProcessList {
     // The minimum time we allow between crashes, for us to consider this
     // application to be bad and stop and its services and reject broadcasts.
     static final int MIN_CRASH_INTERVAL = 60*1000;
 
     // OOM adjustments for processes in various states:
 
+    // Adjustment used in certain places where we don't know it yet.
+    // (Generally this is something that is going to be cached, but we
+    // don't know the exact value in the cached range to assign yet.)
+    static final int UNKNOWN_ADJ = 16;
+
     // This is a process only hosting activities that are not visible,
     // so it can be killed without any disruption.
-    static final int HIDDEN_APP_MAX_ADJ = 15;
-    static int HIDDEN_APP_MIN_ADJ = 9;
+    static final int CACHED_APP_MAX_ADJ = 15;
+    static final int CACHED_APP_MIN_ADJ = 9;
 
     // The B list of SERVICE_ADJ -- these are the old and decrepit
     // services that aren't as shiny and interesting as the ones in the A list.
@@ -62,14 +70,14 @@
     // have much of an impact as far as the user is concerned.
     static final int SERVICE_ADJ = 5;
 
-    // This is a process currently hosting a backup operation.  Killing it
-    // is not entirely fatal but is generally a bad idea.
-    static final int BACKUP_APP_ADJ = 4;
-
     // This is a process with a heavy-weight application.  It is in the
     // background, but we want to try to avoid killing it.  Value set in
     // system/rootdir/init.rc on startup.
-    static final int HEAVY_WEIGHT_APP_ADJ = 3;
+    static final int HEAVY_WEIGHT_APP_ADJ = 4;
+
+    // This is a process currently hosting a backup operation.  Killing it
+    // is not entirely fatal but is generally a bad idea.
+    static final int BACKUP_APP_ADJ = 3;
 
     // This is a process only hosting components that are perceptible to the
     // user, and we really want to avoid killing them, but they are not
@@ -91,40 +99,53 @@
     // The system process runs at the default adjustment.
     static final int SYSTEM_ADJ = -16;
 
+    // Special code for native processes that are not being managed by the system (so
+    // don't have an oom adj assigned by the system).
+    static final int NATIVE_ADJ = -17;
+
     // Memory pages are 4K.
     static final int PAGE_SIZE = 4*1024;
 
-    // The minimum number of hidden apps we want to be able to keep around,
+    // The minimum number of cached apps we want to be able to keep around,
     // without empty apps being able to push them out of memory.
-    static final int MIN_HIDDEN_APPS = 2;
+    static final int MIN_CACHED_APPS = 2;
 
-    // The maximum number of hidden processes we will keep around before
-    // killing them; this is just a control to not let us go too crazy with
-    // keeping around processes on devices with large amounts of RAM.
-    static final int MAX_HIDDEN_APPS = 24;
+    // The maximum number of cached processes we will keep around before killing them.
+    // NOTE: this constant is *only* a control to not let us go too crazy with
+    // keeping around processes on devices with large amounts of RAM.  For devices that
+    // are tighter on RAM, the out of memory killer is responsible for killing background
+    // processes as RAM is needed, and we should *never* be relying on this limit to
+    // kill them.  Also note that this limit only applies to cached background processes;
+    // we have no limit on the number of service, visible, foreground, or other such
+    // processes and the number of those processes does not count against the cached
+    // process limit.
+    static final int MAX_CACHED_APPS = 24;
 
     // We allow empty processes to stick around for at most 30 minutes.
     static final long MAX_EMPTY_TIME = 30*60*1000;
 
-    // The number of hidden at which we don't consider it necessary to do
-    // memory trimming.
-    static final int TRIM_HIDDEN_APPS = 3;
+    // The maximum number of empty app processes we will let sit around.
+    private static final int MAX_EMPTY_APPS = computeEmptyProcessLimit(MAX_CACHED_APPS);
 
     // The number of empty apps at which we don't consider it necessary to do
     // memory trimming.
-    static final int TRIM_EMPTY_APPS = 3;
+    static final int TRIM_EMPTY_APPS = MAX_EMPTY_APPS/2;
 
-    // Threshold of number of hidden+empty where we consider memory critical.
+    // The number of cached at which we don't consider it necessary to do
+    // memory trimming.
+    static final int TRIM_CACHED_APPS = (MAX_CACHED_APPS-MAX_EMPTY_APPS)/2;
+
+    // Threshold of number of cached+empty where we consider memory critical.
     static final int TRIM_CRITICAL_THRESHOLD = 3;
 
-    // Threshold of number of hidden+empty where we consider memory critical.
+    // Threshold of number of cached+empty where we consider memory critical.
     static final int TRIM_LOW_THRESHOLD = 5;
 
-    // We put empty content processes after any hidden processes that have
+    // We put empty content processes after any cached processes that have
     // been idle for less than 15 seconds.
     static final long CONTENT_APP_IDLE_OFFSET = 15*1000;
 
-    // We put empty content processes after any hidden processes that have
+    // We put empty content processes after any cached processes that have
     // been idle for less than 120 seconds.
     static final long EMPTY_APP_IDLE_OFFSET = 120*1000;
 
@@ -133,7 +154,7 @@
     // can't give it a different value for every possible kind of process.
     private final int[] mOomAdj = new int[] {
             FOREGROUND_APP_ADJ, VISIBLE_APP_ADJ, PERCEPTIBLE_APP_ADJ,
-            BACKUP_APP_ADJ, HIDDEN_APP_MIN_ADJ, HIDDEN_APP_MAX_ADJ
+            BACKUP_APP_ADJ, CACHED_APP_MIN_ADJ, CACHED_APP_MAX_ADJ
     };
     // These are the low-end OOM level limits.  This is appropriate for an
     // HVGA or smaller phone with less than 512MB.  Values are in KB.
@@ -164,7 +185,7 @@
     void applyDisplaySize(WindowManagerService wm) {
         if (!mHaveDisplaySize) {
             Point p = new Point();
-            wm.getInitialDisplaySize(Display.DEFAULT_DISPLAY, p);
+            wm.getBaseDisplaySize(Display.DEFAULT_DISPLAY, p);
             if (p.x != 0 && p.y != 0) {
                 updateOomLevels(p.x, p.y, true);
                 mHaveDisplaySize = true;
@@ -178,10 +199,14 @@
         float scaleMem = ((float)(mTotalMemMb-300))/(700-300);
 
         // Scale buckets from screen size.
-        int minSize = 320*480;  //  153600
+        int minSize = 480*800;  //  384000
         int maxSize = 1280*800; // 1024000  230400 870400  .264
         float scaleDisp = ((float)(displayWidth*displayHeight)-minSize)/(maxSize-minSize);
-        //Slog.i("XXXXXX", "scaleDisp=" + scaleDisp + " dw=" + displayWidth + " dh=" + displayHeight);
+        if (false) {
+            Slog.i("XXXXXX", "scaleMem=" + scaleMem);
+            Slog.i("XXXXXX", "scaleDisp=" + scaleDisp + " dw=" + displayWidth
+                    + " dh=" + displayHeight);
+        }
 
         StringBuilder adjString = new StringBuilder();
         StringBuilder memString = new StringBuilder();
@@ -189,11 +214,36 @@
         float scale = scaleMem > scaleDisp ? scaleMem : scaleDisp;
         if (scale < 0) scale = 0;
         else if (scale > 1) scale = 1;
+        int minfree_adj = Resources.getSystem().getInteger(
+                com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAdjust);
+        int minfree_abs = Resources.getSystem().getInteger(
+                com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAbsolute);
+        if (false) {
+            Slog.i("XXXXXX", "minfree_adj=" + minfree_adj + " minfree_abs=" + minfree_abs);
+        }
+
         for (int i=0; i<mOomAdj.length; i++) {
             long low = mOomMinFreeLow[i];
             long high = mOomMinFreeHigh[i];
             mOomMinFree[i] = (long)(low + ((high-low)*scale));
+        }
 
+        if (minfree_abs >= 0) {
+            for (int i=0; i<mOomAdj.length; i++) {
+                mOomMinFree[i] = (long)((float)minfree_abs * mOomMinFree[i] / mOomMinFree[mOomAdj.length - 1]);
+            }
+        }
+
+        if (minfree_adj != 0) {
+            for (int i=0; i<mOomAdj.length; i++) {
+                mOomMinFree[i] += (long)((float)minfree_adj * mOomMinFree[i] / mOomMinFree[mOomAdj.length - 1]);
+                if (mOomMinFree[i] < 0) {
+                    mOomMinFree[i] = 0;
+                }
+            }
+        }
+
+        for (int i=0; i<mOomAdj.length; i++) {
             if (i > 0) {
                 adjString.append(',');
                 memString.append(',');
@@ -202,15 +252,241 @@
             memString.append((mOomMinFree[i]*1024)/PAGE_SIZE);
         }
 
+        // Ask the kernel to try to keep enough memory free to allocate 3 full
+        // screen 32bpp buffers without entering direct reclaim.
+        int reserve = displayWidth * displayHeight * 4 * 3 / 1024;
+        int reserve_adj = Resources.getSystem().getInteger(com.android.internal.R.integer.config_extraFreeKbytesAdjust);
+        int reserve_abs = Resources.getSystem().getInteger(com.android.internal.R.integer.config_extraFreeKbytesAbsolute);
+
+        if (reserve_abs >= 0) {
+            reserve = reserve_abs;
+        }
+
+        if (reserve_adj != 0) {
+            reserve += reserve_adj;
+            if (reserve < 0) {
+                reserve = 0;
+            }
+        }
+
         //Slog.i("XXXXXXX", "******************************* MINFREE: " + memString);
         if (write) {
             writeFile("/sys/module/lowmemorykiller/parameters/adj", adjString.toString());
             writeFile("/sys/module/lowmemorykiller/parameters/minfree", memString.toString());
+            SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve));
         }
         // GB: 2048,3072,4096,6144,7168,8192
         // HC: 8192,10240,12288,14336,16384,20480
     }
 
+    public static int computeEmptyProcessLimit(int totalProcessLimit) {
+        return (totalProcessLimit*2)/3;
+    }
+
+    private static String buildOomTag(String prefix, String space, int val, int base) {
+        if (val == base) {
+            if (space == null) return prefix;
+            return prefix + "  ";
+        }
+        return prefix + "+" + Integer.toString(val-base);
+    }
+
+    public static String makeOomAdjString(int setAdj) {
+        if (setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
+            return buildOomTag("cch", "  ", setAdj, ProcessList.CACHED_APP_MIN_ADJ);
+        } else if (setAdj >= ProcessList.SERVICE_B_ADJ) {
+            return buildOomTag("svcb ", null, setAdj, ProcessList.SERVICE_B_ADJ);
+        } else if (setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
+            return buildOomTag("prev ", null, setAdj, ProcessList.PREVIOUS_APP_ADJ);
+        } else if (setAdj >= ProcessList.HOME_APP_ADJ) {
+            return buildOomTag("home ", null, setAdj, ProcessList.HOME_APP_ADJ);
+        } else if (setAdj >= ProcessList.SERVICE_ADJ) {
+            return buildOomTag("svc  ", null, setAdj, ProcessList.SERVICE_ADJ);
+        } else if (setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
+            return buildOomTag("hvy  ", null, setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
+        } else if (setAdj >= ProcessList.BACKUP_APP_ADJ) {
+            return buildOomTag("bkup ", null, setAdj, ProcessList.BACKUP_APP_ADJ);
+        } else if (setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
+            return buildOomTag("prcp ", null, setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
+        } else if (setAdj >= ProcessList.VISIBLE_APP_ADJ) {
+            return buildOomTag("vis  ", null, setAdj, ProcessList.VISIBLE_APP_ADJ);
+        } else if (setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
+            return buildOomTag("fore ", null, setAdj, ProcessList.FOREGROUND_APP_ADJ);
+        } else if (setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
+            return buildOomTag("pers ", null, setAdj, ProcessList.PERSISTENT_PROC_ADJ);
+        } else if (setAdj >= ProcessList.SYSTEM_ADJ) {
+            return buildOomTag("sys  ", null, setAdj, ProcessList.SYSTEM_ADJ);
+        } else if (setAdj >= ProcessList.NATIVE_ADJ) {
+            return buildOomTag("ntv  ", null, setAdj, ProcessList.NATIVE_ADJ);
+        } else {
+            return Integer.toString(setAdj);
+        }
+    }
+
+    // The minimum amount of time after a state change it is safe ro collect PSS.
+    public static final int PSS_MIN_TIME_FROM_STATE_CHANGE = 15*1000;
+
+    // The maximum amount of time we want to go between PSS collections.
+    public static final int PSS_MAX_INTERVAL = 30*60*1000;
+
+    // The minimum amount of time between successive PSS requests for *all* processes.
+    public static final int PSS_ALL_INTERVAL = 10*60*1000;
+
+    // The minimum amount of time between successive PSS requests for a process.
+    private static final int PSS_SHORT_INTERVAL = 2*60*1000;
+
+    // The amount of time until PSS when a process first becomes top.
+    private static final int PSS_FIRST_TOP_INTERVAL = 15*1000;
+
+    // The amount of time until PSS when a process first becomes cached.
+    private static final int PSS_FIRST_CACHED_INTERVAL = 5*60*1000;
+
+    // The amount of time until PSS when an important process stays in the same state.
+    private static final int PSS_SAME_IMPORTANT_INTERVAL = 15*60*1000;
+
+    // The amount of time until PSS when a service process stays in the same state.
+    private static final int PSS_SAME_SERVICE_INTERVAL = 20*60*1000;
+
+    // The amount of time until PSS when a cached process stays in the same state.
+    private static final int PSS_SAME_CACHED_INTERVAL = 30*60*1000;
+
+    public static final int PROC_MEM_PERSISTENT = 0;
+    public static final int PROC_MEM_TOP = 1;
+    public static final int PROC_MEM_IMPORTANT = 2;
+    public static final int PROC_MEM_SERVICE = 3;
+    public static final int PROC_MEM_CACHED = 4;
+
+    private static final int[] sProcStateToProcMem = new int[] {
+        PROC_MEM_PERSISTENT,            // ActivityManager.PROCESS_STATE_PERSISTENT
+        PROC_MEM_PERSISTENT,            // ActivityManager.PROCESS_STATE_PERSISTENT_UI
+        PROC_MEM_TOP,                   // ActivityManager.PROCESS_STATE_TOP
+        PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
+        PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
+        PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_BACKUP
+        PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
+        PROC_MEM_SERVICE,               // ActivityManager.PROCESS_STATE_SERVICE
+        PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_RECEIVER
+        PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_HOME
+        PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
+        PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
+        PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
+        PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_CACHED_EMPTY
+    };
+
+    private static final long[] sFirstAwakePssTimes = new long[] {
+        PSS_SHORT_INTERVAL,             // ActivityManager.PROCESS_STATE_PERSISTENT
+        PSS_SHORT_INTERVAL,             // ActivityManager.PROCESS_STATE_PERSISTENT_UI
+        PSS_FIRST_TOP_INTERVAL,         // ActivityManager.PROCESS_STATE_TOP
+        PSS_SHORT_INTERVAL,             // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
+        PSS_SHORT_INTERVAL,             // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
+        PSS_SHORT_INTERVAL,             // ActivityManager.PROCESS_STATE_BACKUP
+        PSS_SHORT_INTERVAL,             // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
+        PSS_SHORT_INTERVAL,             // ActivityManager.PROCESS_STATE_SERVICE
+        PSS_SHORT_INTERVAL,             // ActivityManager.PROCESS_STATE_RECEIVER
+        PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_HOME
+        PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
+        PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
+        PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
+        PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_CACHED_EMPTY
+    };
+
+    private static final long[] sSameAwakePssTimes = new long[] {
+        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_PERSISTENT
+        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_PERSISTENT_UI
+        PSS_SHORT_INTERVAL,             // ActivityManager.PROCESS_STATE_TOP
+        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
+        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
+        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_BACKUP
+        PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
+        PSS_SAME_SERVICE_INTERVAL,      // ActivityManager.PROCESS_STATE_SERVICE
+        PSS_SAME_SERVICE_INTERVAL,      // ActivityManager.PROCESS_STATE_RECEIVER
+        PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_HOME
+        PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
+        PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
+        PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
+        PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_EMPTY
+    };
+
+    public static boolean procStatesDifferForMem(int procState1, int procState2) {
+        return sProcStateToProcMem[procState1] != sProcStateToProcMem[procState2];
+    }
+
+    public static String makeProcStateString(int curProcState) {
+        String procState;
+        switch (curProcState) {
+            case -1:
+                procState = "N ";
+                break;
+            case ActivityManager.PROCESS_STATE_PERSISTENT:
+                procState = "P ";
+                break;
+            case ActivityManager.PROCESS_STATE_PERSISTENT_UI:
+                procState = "PU";
+                break;
+            case ActivityManager.PROCESS_STATE_TOP:
+                procState = "T ";
+                break;
+            case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
+                procState = "IF";
+                break;
+            case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
+                procState = "IB";
+                break;
+            case ActivityManager.PROCESS_STATE_BACKUP:
+                procState = "BU";
+                break;
+            case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT:
+                procState = "HW";
+                break;
+            case ActivityManager.PROCESS_STATE_SERVICE:
+                procState = "S ";
+                break;
+            case ActivityManager.PROCESS_STATE_RECEIVER:
+                procState = "R ";
+                break;
+            case ActivityManager.PROCESS_STATE_HOME:
+                procState = "HO";
+                break;
+            case ActivityManager.PROCESS_STATE_LAST_ACTIVITY:
+                procState = "LA";
+                break;
+            case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
+                procState = "CA";
+                break;
+            case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
+                procState = "Ca";
+                break;
+            case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
+                procState = "CE";
+                break;
+            default:
+                procState = "??";
+                break;
+        }
+        return procState;
+    }
+
+    public static void appendRamKb(StringBuilder sb, long ramKb) {
+        for (int j=0, fact=10; j<6; j++, fact*=10) {
+            if (ramKb < fact) {
+                sb.append(' ');
+            }
+        }
+        sb.append(ramKb);
+    }
+
+    public static long computeNextPssTime(int procState, boolean first, boolean sleeping,
+            long now) {
+        final long[] table = sleeping
+                ? (first
+                        ? sFirstAwakePssTimes
+                        : sSameAwakePssTimes)
+                : (first
+                        ? sFirstAwakePssTimes
+                        : sSameAwakePssTimes);
+        return now + table[procState];
+    }
+
     long getMemLevel(int adjustment) {
         for (int i=0; i<mOomAdj.length; i++) {
             if (adjustment <= mOomAdj[i]) {
diff --git a/services/java/com/android/server/am/ProcessMemInfo.java b/services/java/com/android/server/am/ProcessMemInfo.java
new file mode 100644
index 0000000..c94694e
--- /dev/null
+++ b/services/java/com/android/server/am/ProcessMemInfo.java
@@ -0,0 +1,37 @@
+/*
+ * 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.server.am;
+
+public class ProcessMemInfo {
+    final String name;
+    final int pid;
+    final int oomAdj;
+    final int procState;
+    final String adjType;
+    final String adjReason;
+    long pss;
+
+    public ProcessMemInfo(String _name, int _pid, int _oomAdj, int _procState,
+            String _adjType, String _adjReason) {
+        name = _name;
+        pid = _pid;
+        oomAdj = _oomAdj;
+        procState = _procState;
+        adjType = _adjType;
+        adjReason = _adjReason;
+    }
+}
diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java
index 7929f96..35e06b6 100644
--- a/services/java/com/android/server/am/ProcessRecord.java
+++ b/services/java/com/android/server/am/ProcessRecord.java
@@ -16,6 +16,8 @@
 
 package com.android.server.am;
 
+import android.util.ArraySet;
+import com.android.internal.app.ProcessStats;
 import com.android.internal.os.BatteryStatsImpl;
 
 import android.app.ActivityManager;
@@ -32,19 +34,18 @@
 import android.os.Process;
 import android.os.SystemClock;
 import android.os.UserHandle;
+import android.util.ArrayMap;
 import android.util.PrintWriterPrinter;
 import android.util.TimeUtils;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
 
 /**
  * Full information about a particular process that
  * is currently running.
  */
-class ProcessRecord {
+final class ProcessRecord {
     final BatteryStatsImpl.Uid.Proc batteryStats; // where to collect runtime statistics
     final ApplicationInfo info; // all about the first app in the process
     final boolean isolated;     // true if this is a special isolated process
@@ -52,32 +53,38 @@
     final int userId;           // user of process.
     final String processName;   // name of the process
     // List of packages running in the process
-    final HashSet<String> pkgList = new HashSet<String>();
+    final ArrayMap<String, ProcessStats.ProcessState> pkgList
+            = new ArrayMap<String, ProcessStats.ProcessState>();
     IApplicationThread thread;  // the actual proc...  may be null only if
                                 // 'persistent' is true (in which case we
                                 // are in the process of launching the app)
+    ProcessStats.ProcessState baseProcessTracker;
     int pid;                    // The process of this application; 0 if none
     boolean starting;           // True if the process is being started
     long lastActivityTime;      // For managing the LRU list
     long lruWeight;             // Weight for ordering in LRU list
+    long lastPssTime;           // Last time we retrieved PSS data
+    long nextPssTime;           // Next time we want to request PSS data
+    long lastStateTime;         // Last time setProcState changed
     int maxAdj;                 // Maximum OOM adjustment for this process
-    int hiddenAdj;              // If hidden, this is the adjustment to use
-    int clientHiddenAdj;        // If empty but hidden client, this is the adjustment to use
-    int emptyAdj;               // If empty, this is the adjustment to use
     int curRawAdj;              // Current OOM unlimited adjustment for this process
     int setRawAdj;              // Last set OOM unlimited adjustment for this process
-    int nonStoppingAdj;         // Adjustment not counting any stopping activities
     int curAdj;                 // Current OOM adjustment for this process
     int setAdj;                 // Last set OOM adjustment for this process
     int curSchedGroup;          // Currently desired scheduling class
     int setSchedGroup;          // Last set to background scheduling class
     int trimMemoryLevel;        // Last selected memory trimming level
     int memImportance;          // Importance constant computed from curAdj
+    int curProcState = -1;      // Currently computed process state: ActivityManager.PROCESS_STATE_*
+    int repProcState = -1;      // Last reported process state
+    int setProcState = -1;      // Last set process state in process tracker
+    int pssProcState = -1;      // The proc state we are currently requesting pss for
     boolean serviceb;           // Process currently is on the service B list
     boolean keeping;            // Actively running code so don't kill due to that?
     boolean setIsForeground;    // Running foreground UI when last set?
     boolean hasActivities;      // Are there any activities running in this process?
     boolean hasClientActivities;  // Are there any client services with activities?
+    boolean hasStartedServices; // Are there any started services running in this process?
     boolean foregroundServices; // Running any services that are foreground?
     boolean foregroundActivities; // Running any activities that are foreground?
     boolean systemNoUi;         // This is a system process, but not currently showing UI.
@@ -86,6 +93,7 @@
     boolean hasAboveClient;     // Bound using BIND_ABOVE_CLIENT, so want to be lower
     boolean bad;                // True if disabled in the bad process list
     boolean killedBackground;   // True when proc has been killed due to too many bg
+    boolean procStateChanged;   // Keep track of whether we changed 'setAdj'.
     String waitingToKill;       // Process is waiting to be killed when in the bg; reason
     IBinder forcingToForeground;// Token that is forcing this process to be foreground
     int adjSeq;                 // Sequence id for identifying oom_adj assignment cycles
@@ -108,8 +116,7 @@
     long lastLowMemory;         // When we last told the app that memory is low
     boolean reportLowMemory;    // Set to true when waiting to report low mem
     boolean empty;              // Is this an empty background process?
-    boolean hidden;             // Is this a hidden process?
-    int lastPss;                // Last pss size reported by app.
+    boolean cached;             // Is this a cached process?
     String adjType;             // Debugging: primary thing impacting oom_adj.
     int adjTypeCode;            // Debugging: adj code to report to app.
     Object adjSource;           // Debugging: option dependent object.
@@ -119,22 +126,23 @@
     // contains HistoryRecord objects
     final ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
     // all ServiceRecord running in this process
-    final HashSet<ServiceRecord> services = new HashSet<ServiceRecord>();
+    final ArraySet<ServiceRecord> services = new ArraySet<ServiceRecord>();
     // services that are currently executing code (need to remain foreground).
-    final HashSet<ServiceRecord> executingServices
-             = new HashSet<ServiceRecord>();
+    final ArraySet<ServiceRecord> executingServices
+             = new ArraySet<ServiceRecord>();
     // All ConnectionRecord this process holds
-    final HashSet<ConnectionRecord> connections
-            = new HashSet<ConnectionRecord>();  
+    final ArraySet<ConnectionRecord> connections
+            = new ArraySet<ConnectionRecord>();
     // all IIntentReceivers that are registered from this process.
-    final HashSet<ReceiverList> receivers = new HashSet<ReceiverList>();
+    final ArraySet<ReceiverList> receivers = new ArraySet<ReceiverList>();
     // class (String) -> ContentProviderRecord
-    final HashMap<String, ContentProviderRecord> pubProviders
-            = new HashMap<String, ContentProviderRecord>(); 
+    final ArrayMap<String, ContentProviderRecord> pubProviders
+            = new ArrayMap<String, ContentProviderRecord>();
     // All ContentProviderRecord process is using
     final ArrayList<ContentProviderConnection> conProviders
             = new ArrayList<ContentProviderConnection>();
-    
+
+    boolean execServicesFg;     // do we need to be executing services in the foreground?
     boolean persistent;         // always keep this application running?
     boolean crashing;           // are we in the process of crashing?
     Dialog crashDialog;         // dialog being displayed due to crash.
@@ -177,7 +185,12 @@
         pw.print(prefix); pw.print("dir="); pw.print(info.sourceDir);
                 pw.print(" publicDir="); pw.print(info.publicSourceDir);
                 pw.print(" data="); pw.println(info.dataDir);
-        pw.print(prefix); pw.print("packageList="); pw.println(pkgList);
+        pw.print(prefix); pw.print("packageList={");
+        for (int i=0; i<pkgList.size(); i++) {
+            if (i > 0) pw.print(", ");
+            pw.print(pkgList.keyAt(i));
+        }
+        pw.println("}");
         pw.print(prefix); pw.print("compat="); pw.println(compat);
         if (instrumentationClass != null || instrumentationProfileFile != null
                 || instrumentationArguments != null) {
@@ -195,29 +208,37 @@
         }
         pw.print(prefix); pw.print("thread="); pw.println(thread);
         pw.print(prefix); pw.print("pid="); pw.print(pid); pw.print(" starting=");
-                pw.print(starting); pw.print(" lastPss="); pw.println(lastPss);
+                pw.println(starting);
         pw.print(prefix); pw.print("lastActivityTime=");
                 TimeUtils.formatDuration(lastActivityTime, now, pw);
-                pw.print(" lruWeight="); pw.print(lruWeight);
-                pw.print(" serviceb="); pw.print(serviceb);
+                pw.print(" lruWeight="); pw.println(lruWeight);
+        pw.print(prefix); pw.print("serviceb="); pw.print(serviceb);
                 pw.print(" keeping="); pw.print(keeping);
-                pw.print(" hidden="); pw.print(hidden);
+                pw.print(" cached="); pw.print(cached);
                 pw.print(" empty="); pw.println(empty);
         pw.print(prefix); pw.print("oom: max="); pw.print(maxAdj);
-                pw.print(" hidden="); pw.print(hiddenAdj);
-                pw.print(" client="); pw.print(clientHiddenAdj);
-                pw.print(" empty="); pw.print(emptyAdj);
                 pw.print(" curRaw="); pw.print(curRawAdj);
                 pw.print(" setRaw="); pw.print(setRawAdj);
-                pw.print(" nonStopping="); pw.print(nonStoppingAdj);
                 pw.print(" cur="); pw.print(curAdj);
                 pw.print(" set="); pw.println(setAdj);
         pw.print(prefix); pw.print("curSchedGroup="); pw.print(curSchedGroup);
                 pw.print(" setSchedGroup="); pw.print(setSchedGroup);
                 pw.print(" systemNoUi="); pw.print(systemNoUi);
                 pw.print(" trimMemoryLevel="); pw.println(trimMemoryLevel);
+        pw.print(prefix); pw.print("curProcState="); pw.print(curProcState);
+                pw.print(" repProcState="); pw.print(repProcState);
+                pw.print(" pssProcState="); pw.print(pssProcState);
+                pw.print(" setProcState="); pw.print(setProcState);
+                pw.print(" lastStateTime=");
+                TimeUtils.formatDuration(lastStateTime, now, pw);
+                pw.println();
         pw.print(prefix); pw.print("adjSeq="); pw.print(adjSeq);
-                pw.print(" lruSeq="); pw.println(lruSeq);
+                pw.print(" lruSeq="); pw.print(lruSeq);
+                pw.print(" lastPssTime=");
+                TimeUtils.formatDuration(lastPssTime, now, pw);
+                pw.print(" nextPssTime=");
+                TimeUtils.formatDuration(nextPssTime, now, pw);
+                pw.println();
         if (hasShownUi || pendingUiClean || hasAboveClient) {
             pw.print(prefix); pw.print("hasShownUi="); pw.print(hasShownUi);
                     pw.print(" pendingUiClean="); pw.print(pendingUiClean);
@@ -237,6 +258,9 @@
                     pw.print(" hasClientActivities="); pw.print(hasClientActivities);
                     pw.print(" foregroundActivities="); pw.println(foregroundActivities);
         }
+        if (hasStartedServices) {
+            pw.print(prefix); pw.print("hasStartedServices="); pw.println(hasStartedServices);
+        }
         if (!keeping) {
             long wtime;
             synchronized (batteryStats.getBatteryStats()) {
@@ -284,27 +308,28 @@
         }
         if (services.size() > 0) {
             pw.print(prefix); pw.println("Services:");
-            for (ServiceRecord sr : services) {
-                pw.print(prefix); pw.print("  - "); pw.println(sr);
+            for (int i=0; i<services.size(); i++) {
+                pw.print(prefix); pw.print("  - "); pw.println(services.valueAt(i));
             }
         }
         if (executingServices.size() > 0) {
-            pw.print(prefix); pw.println("Executing Services:");
-            for (ServiceRecord sr : executingServices) {
-                pw.print(prefix); pw.print("  - "); pw.println(sr);
+            pw.print(prefix); pw.print("Executing Services (fg=");
+            pw.print(execServicesFg); pw.println(")");
+            for (int i=0; i<executingServices.size(); i++) {
+                pw.print(prefix); pw.print("  - "); pw.println(executingServices.valueAt(i));
             }
         }
         if (connections.size() > 0) {
             pw.print(prefix); pw.println("Connections:");
-            for (ConnectionRecord cr : connections) {
-                pw.print(prefix); pw.print("  - "); pw.println(cr);
+            for (int i=0; i<connections.size(); i++) {
+                pw.print(prefix); pw.print("  - "); pw.println(connections.valueAt(i));
             }
         }
         if (pubProviders.size() > 0) {
             pw.print(prefix); pw.println("Published Providers:");
-            for (HashMap.Entry<String, ContentProviderRecord> ent : pubProviders.entrySet()) {
-                pw.print(prefix); pw.print("  - "); pw.println(ent.getKey());
-                pw.print(prefix); pw.print("    -> "); pw.println(ent.getValue());
+            for (int i=0; i<pubProviders.size(); i++) {
+                pw.print(prefix); pw.print("  - "); pw.println(pubProviders.keyAt(i));
+                pw.print(prefix); pw.print("    -> "); pw.println(pubProviders.valueAt(i));
             }
         }
         if (conProviders.size() > 0) {
@@ -318,28 +343,27 @@
         }
         if (receivers.size() > 0) {
             pw.print(prefix); pw.println("Receivers:");
-            for (ReceiverList rl : receivers) {
-                pw.print(prefix); pw.print("  - "); pw.println(rl);
+            for (int i=0; i<receivers.size(); i++) {
+                pw.print(prefix); pw.print("  - "); pw.println(receivers.valueAt(i));
             }
         }
     }
     
-    ProcessRecord(BatteryStatsImpl.Uid.Proc _batteryStats, IApplicationThread _thread,
-            ApplicationInfo _info, String _processName, int _uid) {
+    ProcessRecord(BatteryStatsImpl.Uid.Proc _batteryStats, ApplicationInfo _info,
+            String _processName, int _uid) {
         batteryStats = _batteryStats;
         info = _info;
         isolated = _info.uid != _uid;
         uid = _uid;
         userId = UserHandle.getUserId(_uid);
         processName = _processName;
-        pkgList.add(_info.packageName);
-        thread = _thread;
-        maxAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
-        hiddenAdj = clientHiddenAdj = emptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
+        pkgList.put(_info.packageName, null);
+        maxAdj = ProcessList.UNKNOWN_ADJ;
         curRawAdj = setRawAdj = -100;
         curAdj = setAdj = -100;
         persistent = false;
         removed = false;
+        lastStateTime = lastPssTime = nextPssTime = SystemClock.uptimeMillis();
     }
 
     public void setPid(int _pid) {
@@ -347,7 +371,53 @@
         shortStringName = null;
         stringName = null;
     }
-    
+
+    public void makeActive(IApplicationThread _thread, ProcessStatsService tracker) {
+        if (thread == null) {
+            final ProcessStats.ProcessState origBase = baseProcessTracker;
+            if (origBase != null) {
+                origBase.setState(ProcessStats.STATE_NOTHING,
+                        tracker.getMemFactorLocked(), SystemClock.uptimeMillis(), pkgList);
+                origBase.makeInactive();
+            }
+            baseProcessTracker = tracker.getProcessStateLocked(info.packageName, info.uid,
+                    processName);
+            baseProcessTracker.makeActive();
+            for (int i=0; i<pkgList.size(); i++) {
+                ProcessStats.ProcessState ps = pkgList.valueAt(i);
+                if (ps != null && ps != origBase) {
+                    ps.makeInactive();
+                }
+                ps = tracker.getProcessStateLocked(pkgList.keyAt(i), info.uid, processName);
+                if (ps != baseProcessTracker) {
+                    ps.makeActive();
+                }
+                pkgList.setValueAt(i, ps);
+            }
+        }
+        thread = _thread;
+    }
+
+    public void makeInactive(ProcessStatsService tracker) {
+        if (thread != null) {
+            thread = null;
+            final ProcessStats.ProcessState origBase = baseProcessTracker;
+            if (origBase != null) {
+                origBase.setState(ProcessStats.STATE_NOTHING,
+                        tracker.getMemFactorLocked(), SystemClock.uptimeMillis(), pkgList);
+                origBase.makeInactive();
+            }
+            baseProcessTracker = null;
+            for (int i=0; i<pkgList.size(); i++) {
+                ProcessStats.ProcessState ps = pkgList.valueAt(i);
+                if (ps != null && ps != origBase) {
+                    ps.makeInactive();
+                }
+                pkgList.setValueAt(i, null);
+            }
+        }
+    }
+
     /**
      * This method returns true if any of the activities within the process record are interesting
      * to the user. See HistoryRecord.isInterestingToUserLocked()
@@ -380,16 +450,37 @@
 
     void updateHasAboveClientLocked() {
         hasAboveClient = false;
-        if (connections.size() > 0) {
-            for (ConnectionRecord cr : connections) {
-                if ((cr.flags&Context.BIND_ABOVE_CLIENT) != 0) {
-                    hasAboveClient = true;
-                    break;
-                }
+        for (int i=connections.size()-1; i>=0; i--) {
+            ConnectionRecord cr = connections.valueAt(i);
+            if ((cr.flags&Context.BIND_ABOVE_CLIENT) != 0) {
+                hasAboveClient = true;
+                break;
             }
         }
     }
 
+    int modifyRawOomAdj(int adj) {
+        if (hasAboveClient) {
+            // If this process has bound to any services with BIND_ABOVE_CLIENT,
+            // then we need to drop its adjustment to be lower than the service's
+            // in order to honor the request.  We want to drop it by one adjustment
+            // level...  but there is special meaning applied to various levels so
+            // we will skip some of them.
+            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
+                // System process will not get dropped, ever
+            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
+                adj = ProcessList.VISIBLE_APP_ADJ;
+            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
+                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
+            } else if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
+                adj = ProcessList.CACHED_APP_MIN_ADJ;
+            } else if (adj < ProcessList.CACHED_APP_MAX_ADJ) {
+                adj++;
+            }
+        }
+        return adj;
+    }
+
     public String toShortString() {
         if (shortStringName != null) {
             return shortStringName;
@@ -409,8 +500,14 @@
         } else {
             sb.append('u');
             sb.append(userId);
-            sb.append('a');
-            sb.append(UserHandle.getAppId(info.uid));
+            int appId = UserHandle.getAppId(info.uid);
+            if (appId >= Process.FIRST_APPLICATION_UID) {
+                sb.append('a');
+                sb.append(appId - Process.FIRST_APPLICATION_UID);
+            } else {
+                sb.append('s');
+                sb.append(appId);
+            }
             if (uid != info.uid) {
                 sb.append('i');
                 sb.append(UserHandle.getAppId(uid) - Process.FIRST_ISOLATED_UID);
@@ -430,24 +527,83 @@
         sb.append('}');
         return stringName = sb.toString();
     }
-    
+
+    public String makeAdjReason() {
+        if (adjSource != null || adjTarget != null) {
+            StringBuilder sb = new StringBuilder(128);
+            sb.append(' ');
+            if (adjTarget instanceof ComponentName) {
+                sb.append(((ComponentName)adjTarget).flattenToShortString());
+            } else if (adjTarget != null) {
+                sb.append(adjTarget.toString());
+            } else {
+                sb.append("{null}");
+            }
+            sb.append("<=");
+            if (adjSource instanceof ProcessRecord) {
+                sb.append("Proc{");
+                sb.append(((ProcessRecord)adjSource).toShortString());
+                sb.append("}");
+            } else if (adjSource != null) {
+                sb.append(adjSource.toString());
+            } else {
+                sb.append("{null}");
+            }
+            return sb.toString();
+        }
+        return null;
+    }
+
     /*
      *  Return true if package has been added false if not
      */
-    public boolean addPackage(String pkg) {
-        if (!pkgList.contains(pkg)) {
-            pkgList.add(pkg);
+    public boolean addPackage(String pkg, ProcessStatsService tracker) {
+        if (!pkgList.containsKey(pkg)) {
+            pkgList.put(pkg, tracker.getProcessStateLocked(pkg, info.uid, processName));
             return true;
         }
         return false;
     }
-    
+
+    public int getSetAdjWithServices() {
+        if (setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
+            if (hasStartedServices) {
+                return ProcessList.SERVICE_B_ADJ;
+            }
+        }
+        return setAdj;
+    }
+
+    public void forceProcessStateUpTo(int newState) {
+        if (repProcState > newState) {
+            curProcState = repProcState = newState;
+        }
+    }
+
     /*
      *  Delete all packages from list except the package indicated in info
      */
-    public void resetPackageList() {
-        pkgList.clear();
-        pkgList.add(info.packageName);
+    public void resetPackageList(ProcessStatsService tracker) {
+        long now = SystemClock.uptimeMillis();
+        baseProcessTracker.setState(ProcessStats.STATE_NOTHING,
+                tracker.getMemFactorLocked(), now, pkgList);
+        final int N = pkgList.size();
+        if (N != 1) {
+            for (int i=0; i<N; i++) {
+                ProcessStats.ProcessState ps = pkgList.valueAt(i);
+                if (ps != null && ps != baseProcessTracker) {
+                    ps.makeInactive();
+                }
+
+            }
+            pkgList.clear();
+            ProcessStats.ProcessState ps = tracker.getProcessStateLocked(
+                    info.packageName, info.uid, processName);
+            pkgList.put(info.packageName, ps);
+            if (thread != null && ps != baseProcessTracker) {
+                ps.makeActive();
+            }
+        }
     }
     
     public String[] getPackageList() {
@@ -456,7 +612,9 @@
             return null;
         }
         String list[] = new String[size];
-        pkgList.toArray(list);
+        for (int i=0; i<pkgList.size(); i++) {
+            list[i] = pkgList.keyAt(i);
+        }
         return list;
     }
 }
diff --git a/services/java/com/android/server/am/ProcessStatsService.java b/services/java/com/android/server/am/ProcessStatsService.java
new file mode 100644
index 0000000..c180f6e
--- /dev/null
+++ b/services/java/com/android/server/am/ProcessStatsService.java
@@ -0,0 +1,721 @@
+/*
+ * 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.server.am;
+
+import android.app.AppGlobals;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
+import android.os.Binder;
+import android.os.Parcel;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.util.ArrayMap;
+import android.util.AtomicFile;
+import android.util.Slog;
+import android.util.SparseArray;
+import com.android.internal.app.IProcessStats;
+import com.android.internal.app.ProcessStats;
+import com.android.internal.os.BackgroundThread;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.locks.ReentrantLock;
+
+public final class ProcessStatsService extends IProcessStats.Stub {
+    static final String TAG = "ProcessStatsService";
+    static final boolean DEBUG = false;
+
+    // Most data is kept in a sparse data structure: an integer array which integer
+    // holds the type of the entry, and the identifier for a long array that data
+    // exists in and the offset into the array to find it.  The constants below
+    // define the encoding of that data in an integer.
+
+    static final int MAX_HISTORIC_STATES = 6;   // Maximum number of historic states we will keep.
+    static final String STATE_FILE_PREFIX = "state-"; // Prefix to use for state filenames.
+    static final String STATE_FILE_SUFFIX = ".bin"; // Suffix to use for state filenames.
+    static final String STATE_FILE_CHECKIN_SUFFIX = ".ci"; // State files that have checked in.
+    static long WRITE_PERIOD = 30*60*1000;      // Write file every 30 minutes or so.
+    static long COMMIT_PERIOD = 12*60*60*1000;  // Commit current stats every 12 hours.
+
+    final ActivityManagerService mAm;
+    final File mBaseDir;
+    ProcessStats mProcessStats;
+    AtomicFile mFile;
+    boolean mCommitPending;
+    boolean mShuttingDown;
+    int mLastMemOnlyState = -1;
+    boolean mMemFactorLowered;
+
+    final ReentrantLock mWriteLock = new ReentrantLock();
+    final Object mPendingWriteLock = new Object();
+    AtomicFile mPendingWriteFile;
+    Parcel mPendingWrite;
+    boolean mPendingWriteCommitted;
+    long mLastWriteTime;
+
+    public ProcessStatsService(ActivityManagerService am, File file) {
+        mAm = am;
+        mBaseDir = file;
+        mBaseDir.mkdirs();
+        mProcessStats = new ProcessStats(true);
+        updateFile();
+        SystemProperties.addChangeCallback(new Runnable() {
+            @Override public void run() {
+                synchronized (mAm) {
+                    if (mProcessStats.evaluateSystemProperties(false)) {
+                        mProcessStats.mFlags |= ProcessStats.FLAG_SYSPROPS;
+                        writeStateLocked(true, true);
+                        mProcessStats.evaluateSystemProperties(true);
+                    }
+                }
+            }
+        });
+    }
+
+    public ProcessStats.ProcessState getProcessStateLocked(String packageName,
+            int uid, String processName) {
+        return mProcessStats.getProcessStateLocked(packageName, uid, processName);
+    }
+
+    public ProcessStats.ServiceState getServiceStateLocked(String packageName, int uid,
+            String processName, String className) {
+        return mProcessStats.getServiceStateLocked(packageName, uid, processName, className);
+    }
+
+    public boolean isMemFactorLowered() {
+        return mMemFactorLowered;
+    }
+
+    public boolean setMemFactorLocked(int memFactor, boolean screenOn, long now) {
+        mMemFactorLowered = memFactor < mLastMemOnlyState;
+        mLastMemOnlyState = memFactor;
+        if (screenOn) {
+            memFactor += ProcessStats.ADJ_SCREEN_ON;
+        }
+        if (memFactor != mProcessStats.mMemFactor) {
+            if (mProcessStats.mMemFactor != ProcessStats.STATE_NOTHING) {
+                mProcessStats.mMemFactorDurations[mProcessStats.mMemFactor]
+                        += now - mProcessStats.mStartTime;
+            }
+            mProcessStats.mMemFactor = memFactor;
+            mProcessStats.mStartTime = now;
+            ArrayMap<String, SparseArray<ProcessStats.PackageState>> pmap
+                    = mProcessStats.mPackages.getMap();
+            for (int i=0; i<pmap.size(); i++) {
+                SparseArray<ProcessStats.PackageState> uids = pmap.valueAt(i);
+                for (int j=0; j<uids.size(); j++) {
+                    ProcessStats.PackageState pkg = uids.valueAt(j);
+                    ArrayMap<String, ProcessStats.ServiceState> services = pkg.mServices;
+                    for (int k=0; k<services.size(); k++) {
+                        ProcessStats.ServiceState service = services.valueAt(k);
+                        if (service.isInUse()) {
+                            if (service.mStartedState != ProcessStats.STATE_NOTHING) {
+                                service.setStarted(true, memFactor, now);
+                            }
+                            if (service.mBoundState != ProcessStats.STATE_NOTHING) {
+                                service.setBound(true, memFactor, now);
+                            }
+                            if (service.mExecState != ProcessStats.STATE_NOTHING) {
+                                service.setExecuting(true, memFactor, now);
+                            }
+                        }
+                    }
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    public int getMemFactorLocked() {
+        return mProcessStats.mMemFactor != ProcessStats.STATE_NOTHING ? mProcessStats.mMemFactor : 0;
+    }
+
+    public boolean shouldWriteNowLocked(long now) {
+        if (now > (mLastWriteTime+WRITE_PERIOD)) {
+            if (SystemClock.elapsedRealtime()
+                    > (mProcessStats.mTimePeriodStartRealtime+COMMIT_PERIOD)) {
+                mCommitPending = true;
+            }
+            return true;
+        }
+        return false;
+    }
+
+    public void shutdownLocked() {
+        Slog.w(TAG, "Writing process stats before shutdown...");
+        mProcessStats.mFlags |= ProcessStats.FLAG_SHUTDOWN;
+        writeStateSyncLocked();
+        mShuttingDown = true;
+    }
+
+    public void writeStateAsyncLocked() {
+        writeStateLocked(false);
+    }
+
+    public void writeStateSyncLocked() {
+        writeStateLocked(true);
+    }
+
+    private void writeStateLocked(boolean sync) {
+        if (mShuttingDown) {
+            return;
+        }
+        boolean commitPending = mCommitPending;
+        mCommitPending = false;
+        writeStateLocked(sync, commitPending);
+    }
+
+    public void writeStateLocked(boolean sync, final boolean commit) {
+        synchronized (mPendingWriteLock) {
+            long now = SystemClock.uptimeMillis();
+            if (mPendingWrite == null || !mPendingWriteCommitted) {
+                mPendingWrite = Parcel.obtain();
+                mProcessStats.mTimePeriodEndRealtime = SystemClock.elapsedRealtime();
+                if (commit) {
+                    mProcessStats.mFlags |= ProcessStats.FLAG_COMPLETE;
+                }
+                mProcessStats.writeToParcel(mPendingWrite, 0);
+                mPendingWriteFile = new AtomicFile(mFile.getBaseFile());
+                mPendingWriteCommitted = commit;
+            }
+            if (commit) {
+                mProcessStats.resetSafely();
+                updateFile();
+            }
+            mLastWriteTime = SystemClock.uptimeMillis();
+            Slog.i(TAG, "Prepared write state in " + (SystemClock.uptimeMillis()-now) + "ms");
+            if (!sync) {
+                BackgroundThread.getHandler().post(new Runnable() {
+                    @Override public void run() {
+                        performWriteState();
+                    }
+                });
+                return;
+            }
+        }
+
+        performWriteState();
+    }
+
+    private void updateFile() {
+        mFile = new AtomicFile(new File(mBaseDir, STATE_FILE_PREFIX
+                + mProcessStats.mTimePeriodStartClockStr + STATE_FILE_SUFFIX));
+        mLastWriteTime = SystemClock.uptimeMillis();
+    }
+
+    void performWriteState() {
+        if (DEBUG) Slog.d(TAG, "Performing write to " + mFile.getBaseFile());
+        Parcel data;
+        AtomicFile file;
+        synchronized (mPendingWriteLock) {
+            data = mPendingWrite;
+            file = mPendingWriteFile;
+            mPendingWriteCommitted = false;
+            if (data == null) {
+                return;
+            }
+            mPendingWrite = null;
+            mPendingWriteFile = null;
+            mWriteLock.lock();
+        }
+
+        FileOutputStream stream = null;
+        try {
+            stream = file.startWrite();
+            stream.write(data.marshall());
+            stream.flush();
+            file.finishWrite(stream);
+            if (DEBUG) Slog.d(TAG, "Write completed successfully!");
+        } catch (IOException e) {
+            Slog.w(TAG, "Error writing process statistics", e);
+            file.failWrite(stream);
+        } finally {
+            data.recycle();
+            trimHistoricStatesWriteLocked();
+            mWriteLock.unlock();
+        }
+    }
+
+    boolean readLocked(ProcessStats stats, AtomicFile file) {
+        try {
+            FileInputStream stream = file.openRead();
+            stats.read(stream);
+            stream.close();
+            if (stats.mReadError != null) {
+                Slog.w(TAG, "Ignoring existing stats; " + stats.mReadError);
+                if (DEBUG) {
+                    ArrayMap<String, SparseArray<ProcessStats.ProcessState>> procMap
+                            = stats.mProcesses.getMap();
+                    final int NPROC = procMap.size();
+                    for (int ip=0; ip<NPROC; ip++) {
+                        Slog.w(TAG, "Process: " + procMap.keyAt(ip));
+                        SparseArray<ProcessStats.ProcessState> uids = procMap.valueAt(ip);
+                        final int NUID = uids.size();
+                        for (int iu=0; iu<NUID; iu++) {
+                            Slog.w(TAG, "  Uid " + uids.keyAt(iu) + ": " + uids.valueAt(iu));
+                        }
+                    }
+                    ArrayMap<String, SparseArray<ProcessStats.PackageState>> pkgMap
+                            = stats.mPackages.getMap();
+                    final int NPKG = pkgMap.size();
+                    for (int ip=0; ip<NPKG; ip++) {
+                        Slog.w(TAG, "Package: " + pkgMap.keyAt(ip));
+                        SparseArray<ProcessStats.PackageState> uids = pkgMap.valueAt(ip);
+                        final int NUID = uids.size();
+                        for (int iu=0; iu<NUID; iu++) {
+                            Slog.w(TAG, "  Uid: " + uids.keyAt(iu));
+                            ProcessStats.PackageState pkgState = uids.valueAt(iu);
+                            final int NPROCS = pkgState.mProcesses.size();
+                            for (int iproc=0; iproc<NPROCS; iproc++) {
+                                Slog.w(TAG, "    Process " + pkgState.mProcesses.keyAt(iproc)
+                                        + ": " + pkgState.mProcesses.valueAt(iproc));
+                            }
+                            final int NSRVS = pkgState.mServices.size();
+                            for (int isvc=0; isvc<NSRVS; isvc++) {
+                                Slog.w(TAG, "    Service " + pkgState.mServices.keyAt(isvc)
+                                        + ": " + pkgState.mServices.valueAt(isvc));
+                            }
+                        }
+                    }
+                }
+                return false;
+            }
+        } catch (Throwable e) {
+            stats.mReadError = "caught exception: " + e;
+            Slog.e(TAG, "Error reading process statistics", e);
+            return false;
+        }
+        return true;
+    }
+
+    private ArrayList<String> getCommittedFiles(int minNum, boolean inclAll) {
+        File[] files = mBaseDir.listFiles();
+        if (files == null || files.length <= minNum) {
+            return null;
+        }
+        ArrayList<String> filesArray = new ArrayList<String>(files.length);
+        String currentFile = mFile.getBaseFile().getPath();
+        if (DEBUG) Slog.d(TAG, "Collecting " + files.length + " files except: " + currentFile);
+        for (int i=0; i<files.length; i++) {
+            File file = files[i];
+            String fileStr = file.getPath();
+            if (DEBUG) Slog.d(TAG, "Collecting: " + fileStr);
+            if (!inclAll && fileStr.endsWith(STATE_FILE_CHECKIN_SUFFIX)) {
+                if (DEBUG) Slog.d(TAG, "Skipping: already checked in");
+                continue;
+            }
+            if (fileStr.equals(currentFile)) {
+                if (DEBUG) Slog.d(TAG, "Skipping: current stats");
+                continue;
+            }
+            filesArray.add(fileStr);
+        }
+        Collections.sort(filesArray);
+        return filesArray;
+    }
+
+    public void trimHistoricStatesWriteLocked() {
+        ArrayList<String> filesArray = getCommittedFiles(MAX_HISTORIC_STATES, true);
+        if (filesArray == null) {
+            return;
+        }
+        while (filesArray.size() > MAX_HISTORIC_STATES) {
+            String file = filesArray.remove(0);
+            Slog.i(TAG, "Pruning old procstats: " + file);
+            (new File(file)).delete();
+        }
+    }
+
+    boolean dumpFilteredProcessesCsvLocked(PrintWriter pw, String header,
+            boolean sepScreenStates, int[] screenStates, boolean sepMemStates, int[] memStates,
+            boolean sepProcStates, int[] procStates, long now, String reqPackage) {
+        ArrayList<ProcessStats.ProcessState> procs = mProcessStats.collectProcessesLocked(
+                screenStates, memStates, procStates, now, reqPackage);
+        if (procs.size() > 0) {
+            if (header != null) {
+                pw.println(header);
+            }
+            ProcessStats.dumpProcessListCsv(pw, procs, sepScreenStates, screenStates,
+                    sepMemStates, memStates, sepProcStates, procStates, now);
+            return true;
+        }
+        return false;
+    }
+
+    static int[] parseStateList(String[] states, int mult, String arg, boolean[] outSep,
+            String[] outError) {
+        ArrayList<Integer> res = new ArrayList<Integer>();
+        int lastPos = 0;
+        for (int i=0; i<=arg.length(); i++) {
+            char c = i < arg.length() ? arg.charAt(i) : 0;
+            if (c != ',' && c != '+' && c != ' ' && c != 0) {
+                continue;
+            }
+            boolean isSep = c == ',';
+            if (lastPos == 0) {
+                // We now know the type of op.
+                outSep[0] = isSep;
+            } else if (c != 0 && outSep[0] != isSep) {
+                outError[0] = "inconsistent separators (can't mix ',' with '+')";
+                return null;
+            }
+            if (lastPos < (i-1)) {
+                String str = arg.substring(lastPos, i);
+                for (int j=0; j<states.length; j++) {
+                    if (str.equals(states[j])) {
+                        res.add(j);
+                        str = null;
+                        break;
+                    }
+                }
+                if (str != null) {
+                    outError[0] = "invalid word \"" + str + "\"";
+                    return null;
+                }
+            }
+            lastPos = i + 1;
+        }
+
+        int[] finalRes = new int[res.size()];
+        for (int i=0; i<res.size(); i++) {
+            finalRes[i] = res.get(i) * mult;
+        }
+        return finalRes;
+    }
+
+    public byte[] getCurrentStats(List<ParcelFileDescriptor> historic) {
+        Parcel current = Parcel.obtain();
+        mWriteLock.lock();
+        try {
+            synchronized (mAm) {
+                mProcessStats.mTimePeriodEndRealtime = SystemClock.elapsedRealtime();
+                mProcessStats.writeToParcel(current, 0);
+            }
+            if (historic != null) {
+                ArrayList<String> files = getCommittedFiles(0, true);
+                if (files != null) {
+                    for (int i=files.size()-1; i>=0; i--) {
+                        try {
+                            ParcelFileDescriptor pfd = ParcelFileDescriptor.open(
+                                    new File(files.get(i)), ParcelFileDescriptor.MODE_READ_ONLY);
+                            historic.add(pfd);
+                        } catch (IOException e) {
+                            Slog.w(TAG, "Failure opening procstat file " + files.get(i), e);
+                        }
+                    }
+                }
+            }
+        } finally {
+            mWriteLock.unlock();
+        }
+        return current.marshall();
+    }
+
+    public int getCurrentMemoryState() {
+        synchronized (mAm) {
+            return mLastMemOnlyState;
+        }
+    }
+
+    static private void dumpHelp(PrintWriter pw) {
+        pw.println("Process stats (procstats) dump options:");
+        pw.println("    [--checkin|-c|--csv] [--csv-screen] [--csv-proc] [--csv-mem]");
+        pw.println("    [--details] [--current] [--commit] [--write] [-h] [<package.name>]");
+        pw.println("  --checkin: perform a checkin: print and delete old committed states.");
+        pw.println("  --c: print only state in checkin format.");
+        pw.println("  --csv: output data suitable for putting in a spreadsheet.");
+        pw.println("  --csv-screen: on, off.");
+        pw.println("  --csv-mem: norm, mod, low, crit.");
+        pw.println("  --csv-proc: pers, top, fore, vis, precept, backup,");
+        pw.println("    service, home, prev, cached");
+        pw.println("  --details: dump all execution details, not just summary.");
+        pw.println("  --current: only dump current state.");
+        pw.println("  --commit: commit current stats to disk and reset to start new stats.");
+        pw.println("  --write: write current in-memory stats to disk.");
+        pw.println("  --read: replace current stats with last-written stats.");
+        pw.println("  -a: print everything.");
+        pw.println("  -h: print this help text.");
+        pw.println("  <package.name>: optional name of package to filter output by.");
+    }
+
+    @Override
+    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (mAm.checkCallingPermission(android.Manifest.permission.DUMP)
+                != PackageManager.PERMISSION_GRANTED) {
+            pw.println("Permission Denial: can't dump procstats from from pid="
+                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
+                    + " without permission " + android.Manifest.permission.DUMP);
+            return;
+        }
+
+        final long now = SystemClock.uptimeMillis();
+
+        boolean isCheckin = false;
+        boolean isCompact = false;
+        boolean isCsv = false;
+        boolean currentOnly = false;
+        boolean dumpDetails = false;
+        boolean dumpAll = false;
+        String reqPackage = null;
+        boolean csvSepScreenStats = false;
+        int[] csvScreenStats = new int[] { ProcessStats.ADJ_SCREEN_OFF, ProcessStats.ADJ_SCREEN_ON};
+        boolean csvSepMemStats = false;
+        int[] csvMemStats = new int[] { ProcessStats.ADJ_MEM_FACTOR_CRITICAL};
+        boolean csvSepProcStats = true;
+        int[] csvProcStats = ProcessStats.ALL_PROC_STATES;
+        if (args != null) {
+            for (int i=0; i<args.length; i++) {
+                String arg = args[i];
+                if ("--checkin".equals(arg)) {
+                    isCheckin = true;
+                } else if ("-c".equals(arg)) {
+                    isCompact = true;
+                } else if ("--csv".equals(arg)) {
+                    isCsv = true;
+                } else if ("--csv-screen".equals(arg)) {
+                    i++;
+                    if (i >= args.length) {
+                        pw.println("Error: argument required for --csv-screen");
+                        dumpHelp(pw);
+                        return;
+                    }
+                    boolean[] sep = new boolean[1];
+                    String[] error = new String[1];
+                    csvScreenStats = parseStateList(ProcessStats.ADJ_SCREEN_NAMES_CSV, ProcessStats.ADJ_SCREEN_MOD,
+                            args[i], sep, error);
+                    if (csvScreenStats == null) {
+                        pw.println("Error in \"" + args[i] + "\": " + error[0]);
+                        dumpHelp(pw);
+                        return;
+                    }
+                    csvSepScreenStats = sep[0];
+                } else if ("--csv-mem".equals(arg)) {
+                    i++;
+                    if (i >= args.length) {
+                        pw.println("Error: argument required for --csv-mem");
+                        dumpHelp(pw);
+                        return;
+                    }
+                    boolean[] sep = new boolean[1];
+                    String[] error = new String[1];
+                    csvMemStats = parseStateList(ProcessStats.ADJ_MEM_NAMES_CSV, 1, args[i], sep, error);
+                    if (csvMemStats == null) {
+                        pw.println("Error in \"" + args[i] + "\": " + error[0]);
+                        dumpHelp(pw);
+                        return;
+                    }
+                    csvSepMemStats = sep[0];
+                } else if ("--csv-proc".equals(arg)) {
+                    i++;
+                    if (i >= args.length) {
+                        pw.println("Error: argument required for --csv-proc");
+                        dumpHelp(pw);
+                        return;
+                    }
+                    boolean[] sep = new boolean[1];
+                    String[] error = new String[1];
+                    csvProcStats = parseStateList(ProcessStats.STATE_NAMES_CSV, 1, args[i], sep, error);
+                    if (csvProcStats == null) {
+                        pw.println("Error in \"" + args[i] + "\": " + error[0]);
+                        dumpHelp(pw);
+                        return;
+                    }
+                    csvSepProcStats = sep[0];
+                } else if ("--details".equals(arg)) {
+                    dumpDetails = true;
+                } else if ("--current".equals(arg)) {
+                    currentOnly = true;
+                } else if ("--commit".equals(arg)) {
+                    mProcessStats.mFlags |= ProcessStats.FLAG_COMPLETE;
+                    writeStateLocked(true, true);
+                    pw.println("Process stats committed.");
+                    return;
+                } else if ("--write".equals(arg)) {
+                    writeStateSyncLocked();
+                    pw.println("Process stats written.");
+                    return;
+                } else if ("--read".equals(arg)) {
+                    readLocked(mProcessStats, mFile);
+                    pw.println("Process stats read.");
+                    return;
+                } else if ("-h".equals(arg)) {
+                    dumpHelp(pw);
+                    return;
+                } else if ("-a".equals(arg)) {
+                    dumpDetails = true;
+                    dumpAll = true;
+                } else if (arg.length() > 0 && arg.charAt(0) == '-'){
+                    pw.println("Unknown option: " + arg);
+                    dumpHelp(pw);
+                    return;
+                } else {
+                    // Not an option, last argument must be a package name.
+                    try {
+                        IPackageManager pm = AppGlobals.getPackageManager();
+                        if (pm.getPackageUid(arg, UserHandle.getCallingUserId()) >= 0) {
+                            reqPackage = arg;
+                            // Include all details, since we know we are only going to
+                            // be dumping a smaller set of data.  In fact only the details
+                            // container per-package data, so that are needed to be able
+                            // to dump anything at all when filtering by package.
+                            dumpDetails = true;
+                        }
+                    } catch (RemoteException e) {
+                    }
+                    if (reqPackage == null) {
+                        pw.println("Unknown package: " + arg);
+                        dumpHelp(pw);
+                        return;
+                    }
+                }
+            }
+        }
+
+        if (isCsv) {
+            pw.print("Processes running summed over");
+            if (!csvSepScreenStats) {
+                for (int i=0; i<csvScreenStats.length; i++) {
+                    pw.print(" ");
+                    ProcessStats.printScreenLabelCsv(pw, csvScreenStats[i]);
+                }
+            }
+            if (!csvSepMemStats) {
+                for (int i=0; i<csvMemStats.length; i++) {
+                    pw.print(" ");
+                    ProcessStats.printMemLabelCsv(pw, csvMemStats[i]);
+                }
+            }
+            if (!csvSepProcStats) {
+                for (int i=0; i<csvProcStats.length; i++) {
+                    pw.print(" ");
+                    pw.print(ProcessStats.STATE_NAMES_CSV[csvProcStats[i]]);
+                }
+            }
+            pw.println();
+            synchronized (mAm) {
+                dumpFilteredProcessesCsvLocked(pw, null,
+                        csvSepScreenStats, csvScreenStats, csvSepMemStats, csvMemStats,
+                        csvSepProcStats, csvProcStats, now, reqPackage);
+                /*
+                dumpFilteredProcessesCsvLocked(pw, "Processes running while critical mem:",
+                        false, new int[] {ADJ_SCREEN_OFF, ADJ_SCREEN_ON},
+                        true, new int[] {ADJ_MEM_FACTOR_CRITICAL},
+                        true, new int[] {STATE_PERSISTENT, STATE_TOP, STATE_FOREGROUND, STATE_VISIBLE,
+                                STATE_PERCEPTIBLE, STATE_BACKUP, STATE_SERVICE, STATE_HOME,
+                                STATE_PREVIOUS, STATE_CACHED},
+                        now, reqPackage);
+                dumpFilteredProcessesCsvLocked(pw, "Processes running over all mem:",
+                        false, new int[] {ADJ_SCREEN_OFF, ADJ_SCREEN_ON},
+                        false, new int[] {ADJ_MEM_FACTOR_CRITICAL, ADJ_MEM_FACTOR_LOW,
+                                ADJ_MEM_FACTOR_MODERATE, ADJ_MEM_FACTOR_MODERATE},
+                        true, new int[] {STATE_PERSISTENT, STATE_TOP, STATE_FOREGROUND, STATE_VISIBLE,
+                                STATE_PERCEPTIBLE, STATE_BACKUP, STATE_SERVICE, STATE_HOME,
+                                STATE_PREVIOUS, STATE_CACHED},
+                        now, reqPackage);
+                */
+            }
+            return;
+        }
+
+        boolean sepNeeded = false;
+        if (!currentOnly || isCheckin) {
+            mWriteLock.lock();
+            try {
+                ArrayList<String> files = getCommittedFiles(0, !isCheckin);
+                if (files != null) {
+                    for (int i=0; i<files.size(); i++) {
+                        if (DEBUG) Slog.d(TAG, "Retrieving state: " + files.get(i));
+                        try {
+                            AtomicFile file = new AtomicFile(new File(files.get(i)));
+                            ProcessStats processStats = new ProcessStats(false);
+                            readLocked(processStats, file);
+                            if (processStats.mReadError != null) {
+                                if (isCheckin || isCompact) pw.print("err,");
+                                pw.print("Failure reading "); pw.print(files.get(i));
+                                pw.print("; "); pw.println(processStats.mReadError);
+                                if (DEBUG) Slog.d(TAG, "Deleting state: " + files.get(i));
+                                (new File(files.get(i))).delete();
+                                continue;
+                            }
+                            String fileStr = file.getBaseFile().getPath();
+                            boolean checkedIn = fileStr.endsWith(STATE_FILE_CHECKIN_SUFFIX);
+                            if (isCheckin || isCompact) {
+                                // Don't really need to lock because we uniquely own this object.
+                                processStats.dumpCheckinLocked(pw, reqPackage);
+                            } else {
+                                if (sepNeeded) {
+                                    pw.println();
+                                } else {
+                                    sepNeeded = true;
+                                }
+                                pw.print("COMMITTED STATS FROM ");
+                                pw.print(processStats.mTimePeriodStartClockStr);
+                                if (checkedIn) pw.print(" (checked in)");
+                                pw.println(":");
+                                // Don't really need to lock because we uniquely own this object.
+                                // Always dump summary here, dumping all details is just too
+                                // much crud.
+                                processStats.dumpSummaryLocked(pw, reqPackage, now);
+                            }
+                            if (isCheckin) {
+                                // Rename file suffix to mark that it has checked in.
+                                file.getBaseFile().renameTo(new File(
+                                        fileStr + STATE_FILE_CHECKIN_SUFFIX));
+                            }
+                        } catch (Throwable e) {
+                            pw.print("**** FAILURE DUMPING STATE: "); pw.println(files.get(i));
+                            e.printStackTrace(pw);
+                        }
+                    }
+                }
+            } finally {
+                mWriteLock.unlock();
+            }
+        }
+        if (!isCheckin) {
+            synchronized (mAm) {
+                if (isCompact) {
+                    mProcessStats.dumpCheckinLocked(pw, reqPackage);
+                } else {
+                    if (sepNeeded) {
+                        pw.println();
+                        pw.println("CURRENT STATS:");
+                    }
+                    if (dumpDetails) {
+                        mProcessStats.dumpLocked(pw, reqPackage, now, dumpAll);
+                        if (dumpAll) {
+                            pw.print("  mFile="); pw.println(mFile.getBaseFile());
+                        }
+                    } else {
+                        mProcessStats.dumpSummaryLocked(pw, reqPackage, now);
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/services/java/com/android/server/am/ProviderMap.java b/services/java/com/android/server/am/ProviderMap.java
index 9dbf5f5..7da8c48 100644
--- a/services/java/com/android/server/am/ProviderMap.java
+++ b/services/java/com/android/server/am/ProviderMap.java
@@ -22,6 +22,7 @@
 import android.os.UserHandle;
 import android.util.Slog;
 import android.util.SparseArray;
+import com.android.internal.os.TransferPipe;
 
 import java.io.FileDescriptor;
 import java.io.IOException;
@@ -35,7 +36,7 @@
  * Keeps track of content providers by authority (name) and class. It separates the mapping by
  * user and ones that are not user-specific (system providers).
  */
-public class ProviderMap {
+public final class ProviderMap {
 
     private static final String TAG = "ProviderMap";
 
@@ -230,58 +231,87 @@
         return didSomething;
     }
 
-    private void dumpProvidersByClassLocked(PrintWriter pw, boolean dumpAll,
-            HashMap<ComponentName, ContentProviderRecord> map) {
+    private boolean dumpProvidersByClassLocked(PrintWriter pw, boolean dumpAll, String dumpPackage,
+            String header, boolean needSep, HashMap<ComponentName, ContentProviderRecord> map) {
         Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it = map.entrySet().iterator();
+        boolean written = false;
         while (it.hasNext()) {
             Map.Entry<ComponentName, ContentProviderRecord> e = it.next();
             ContentProviderRecord r = e.getValue();
+            if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
+                continue;
+            }
+            if (needSep) {
+                pw.println("");
+                needSep = false;
+            }
+            if (header != null) {
+                pw.println(header);
+                header = null;
+            }
+            written = true;
             pw.print("  * ");
             pw.println(r);
             r.dump(pw, "    ", dumpAll);
         }
+        return written;
     }
 
-    private void dumpProvidersByNameLocked(PrintWriter pw,
-            HashMap<String, ContentProviderRecord> map) {
+    private boolean dumpProvidersByNameLocked(PrintWriter pw, String dumpPackage,
+            String header, boolean needSep, HashMap<String, ContentProviderRecord> map) {
         Iterator<Map.Entry<String, ContentProviderRecord>> it = map.entrySet().iterator();
+        boolean written = false;
         while (it.hasNext()) {
             Map.Entry<String, ContentProviderRecord> e = it.next();
             ContentProviderRecord r = e.getValue();
+            if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
+                continue;
+            }
+            if (needSep) {
+                pw.println("");
+                needSep = false;
+            }
+            if (header != null) {
+                pw.println(header);
+                header = null;
+            }
+            written = true;
             pw.print("  ");
             pw.print(e.getKey());
             pw.print(": ");
             pw.println(r.toShortString());
         }
+        return written;
     }
 
-    void dumpProvidersLocked(PrintWriter pw, boolean dumpAll) {
+    boolean dumpProvidersLocked(PrintWriter pw, boolean dumpAll, String dumpPackage) {
+        boolean needSep = false;
+
         if (mSingletonByClass.size() > 0) {
-            pw.println("  Published single-user content providers (by class):");
-            dumpProvidersByClassLocked(pw, dumpAll, mSingletonByClass);
+            needSep |= dumpProvidersByClassLocked(pw, dumpAll, dumpPackage,
+                    "  Published single-user content providers (by class):", needSep,
+                    mSingletonByClass);
         }
 
-        pw.println("");
         for (int i = 0; i < mProvidersByClassPerUser.size(); i++) {
             HashMap<ComponentName, ContentProviderRecord> map = mProvidersByClassPerUser.valueAt(i);
-            pw.println("");
-            pw.println("  Published user " + mProvidersByClassPerUser.keyAt(i)
-                    + " content providers (by class):");
-            dumpProvidersByClassLocked(pw, dumpAll, map);
+            needSep |= dumpProvidersByClassLocked(pw, dumpAll, dumpPackage,
+                    "  Published user " + mProvidersByClassPerUser.keyAt(i)
+                            + " content providers (by class):", needSep, map);
         }
 
         if (dumpAll) {
-            pw.println("");
-            pw.println("  Single-user authority to provider mappings:");
-            dumpProvidersByNameLocked(pw, mSingletonByName);
+            needSep |= dumpProvidersByNameLocked(pw, dumpPackage,
+                    "  Single-user authority to provider mappings:", needSep, mSingletonByName);
 
             for (int i = 0; i < mProvidersByNamePerUser.size(); i++) {
-                pw.println("");
-                pw.println("  User " + mProvidersByNamePerUser.keyAt(i)
-                        + " authority to provider mappings:");
-                dumpProvidersByNameLocked(pw, mProvidersByNamePerUser.valueAt(i));
+                needSep |= dumpProvidersByNameLocked(pw, dumpPackage,
+                        "  User " + mProvidersByNamePerUser.keyAt(i)
+                                + " authority to provider mappings:", needSep,
+                        mProvidersByNamePerUser.valueAt(i));
             }
         }
+        return needSep;
     }
 
     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
diff --git a/services/java/com/android/server/am/ReceiverList.java b/services/java/com/android/server/am/ReceiverList.java
index 9b6701e..fa8c1df 100644
--- a/services/java/com/android/server/am/ReceiverList.java
+++ b/services/java/com/android/server/am/ReceiverList.java
@@ -32,7 +32,7 @@
  * A receiver object that has registered for one or more broadcasts.
  * The ArrayList holds BroadcastFilter objects.
  */
-class ReceiverList extends ArrayList<BroadcastFilter>
+final class ReceiverList extends ArrayList<BroadcastFilter>
         implements IBinder.DeathRecipient {
     final ActivityManagerService owner;
     public final IIntentReceiver receiver;
@@ -69,7 +69,7 @@
     }
     
     void dumpLocal(PrintWriter pw, String prefix) {
-        pw.print(prefix); pw.print("app="); pw.print(app.toShortString());
+        pw.print(prefix); pw.print("app="); pw.print(app != null ? app.toShortString() : null);
             pw.print(" pid="); pw.print(pid); pw.print(" uid="); pw.print(uid);
             pw.print(" user="); pw.println(userId);
         if (curBroadcast != null || linkedToDeath) {
diff --git a/services/java/com/android/server/am/ServiceRecord.java b/services/java/com/android/server/am/ServiceRecord.java
index 9fdd293..448117e 100644
--- a/services/java/com/android/server/am/ServiceRecord.java
+++ b/services/java/com/android/server/am/ServiceRecord.java
@@ -16,40 +16,39 @@
 
 package com.android.server.am;
 
-import android.app.PendingIntent;
-import android.net.Uri;
-import android.provider.Settings;
+import com.android.internal.app.ProcessStats;
 import com.android.internal.os.BatteryStatsImpl;
 import com.android.server.NotificationManagerService;
 
 import android.app.INotificationManager;
 import android.app.Notification;
 import android.app.NotificationManager;
+import android.app.PendingIntent;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
+import android.net.Uri;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.ArrayMap;
 import android.util.Slog;
 import android.util.TimeUtils;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
 
 /**
  * A running application service.
  */
-class ServiceRecord extends Binder {
+final class ServiceRecord extends Binder {
     // Maximum number of delivery attempts before giving up.
     static final int MAX_DELIVERY_COUNT = 3;
 
@@ -76,24 +75,30 @@
     final boolean exported; // from ServiceInfo.exported
     final Runnable restarter; // used to schedule retries of starting the service
     final long createTime;  // when this service was created
-    final HashMap<Intent.FilterComparison, IntentBindRecord> bindings
-            = new HashMap<Intent.FilterComparison, IntentBindRecord>();
+    final ArrayMap<Intent.FilterComparison, IntentBindRecord> bindings
+            = new ArrayMap<Intent.FilterComparison, IntentBindRecord>();
                             // All active bindings to the service.
-    final HashMap<IBinder, ArrayList<ConnectionRecord>> connections
-            = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
+    final ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections
+            = new ArrayMap<IBinder, ArrayList<ConnectionRecord>>();
                             // IBinder -> ConnectionRecord of all bound clients
 
     ProcessRecord app;      // where this service is running or null.
     ProcessRecord isolatedProc; // keep track of isolated process, if requested
+    ProcessStats.ServiceState tracker; // tracking service execution, may be null
+    boolean delayed;        // are we waiting to start this service in the background?
     boolean isForeground;   // is service currently in foreground mode?
     int foregroundId;       // Notification ID of last foreground req.
     Notification foregroundNoti; // Notification record of foreground state.
     long lastActivity;      // last time there was some activity on the service.
+    long startingBgTimeout;  // time at which we scheduled this for a delayed start.
     boolean startRequested; // someone explicitly called start?
+    boolean delayedStop;    // service has been stopped but is in a delayed start?
     boolean stopIfKilled;   // last onStart() said to stop if service killed?
     boolean callStart;      // last onStart() has asked to alway be called on restart.
     int executeNesting;     // number of outstanding operations keeping foreground.
+    boolean executeFg;      // should we be executing in the foreground?
     long executingStart;    // start time of last execute request.
+    boolean createdFromFg;  // was this service last created due to a foreground process call?
     int crashCount;         // number of times proc has crashed with service running
     int totalRestartCount;  // number of times we have had to restart.
     int restartCount;       // number of restarts performed in a row.
@@ -218,6 +223,9 @@
         if (isolatedProc != null) {
             pw.print(prefix); pw.print("isolatedProc="); pw.println(isolatedProc);
         }
+        if (delayed) {
+            pw.print(prefix); pw.print("delayed="); pw.println(delayed);
+        }
         if (isForeground || foregroundId != 0) {
             pw.print(prefix); pw.print("isForeground="); pw.print(isForeground);
                     pw.print(" foregroundId="); pw.print(foregroundId);
@@ -225,24 +233,30 @@
         }
         pw.print(prefix); pw.print("createTime=");
                 TimeUtils.formatDuration(createTime, nowReal, pw);
-                pw.print(" lastActivity=");
+                pw.print(" startingBgTimeout=");
+                TimeUtils.formatDuration(startingBgTimeout, now, pw);
+                pw.println();
+        pw.print(prefix); pw.print("lastActivity=");
                 TimeUtils.formatDuration(lastActivity, now, pw);
-                pw.println("");
-        pw.print(prefix); pw.print("executingStart=");
-                TimeUtils.formatDuration(executingStart, now, pw);
                 pw.print(" restartTime=");
                 TimeUtils.formatDuration(restartTime, now, pw);
-                pw.println("");
-        if (startRequested || lastStartId != 0) {
+                pw.print(" createdFromFg="); pw.println(createdFromFg);
+        if (startRequested || delayedStop || lastStartId != 0) {
             pw.print(prefix); pw.print("startRequested="); pw.print(startRequested);
+                    pw.print(" delayedStop="); pw.print(delayedStop);
                     pw.print(" stopIfKilled="); pw.print(stopIfKilled);
                     pw.print(" callStart="); pw.print(callStart);
                     pw.print(" lastStartId="); pw.println(lastStartId);
         }
-        if (executeNesting != 0 || crashCount != 0 || restartCount != 0
-                || restartDelay != 0 || nextRestartTime != 0) {
+        if (executeNesting != 0) {
             pw.print(prefix); pw.print("executeNesting="); pw.print(executeNesting);
-                    pw.print(" restartCount="); pw.print(restartCount);
+                    pw.print(" executeFg="); pw.print(executeFg);
+                    pw.print(" executingStart=");
+                    TimeUtils.formatDuration(executingStart, now, pw);
+        }
+        if (crashCount != 0 || restartCount != 0
+                || restartDelay != 0 || nextRestartTime != 0) {
+            pw.print(prefix); pw.print("restartCount="); pw.print(restartCount);
                     pw.print(" restartDelay=");
                     TimeUtils.formatDuration(restartDelay, now, pw);
                     pw.print(" nextRestartTime=");
@@ -258,10 +272,9 @@
             dumpStartList(pw, prefix, pendingStarts, 0);
         }
         if (bindings.size() > 0) {
-            Iterator<IntentBindRecord> it = bindings.values().iterator();
             pw.print(prefix); pw.println("Bindings:");
-            while (it.hasNext()) {
-                IntentBindRecord b = it.next();
+            for (int i=0; i<bindings.size(); i++) {
+                IntentBindRecord b = bindings.valueAt(i);
                 pw.print(prefix); pw.print("* IntentBindRecord{");
                         pw.print(Integer.toHexString(System.identityHashCode(b)));
                         if ((b.collectFlags()&Context.BIND_AUTO_CREATE) != 0) {
@@ -273,9 +286,8 @@
         }
         if (connections.size() > 0) {
             pw.print(prefix); pw.println("All Connections:");
-            Iterator<ArrayList<ConnectionRecord>> it = connections.values().iterator();
-            while (it.hasNext()) {
-                ArrayList<ConnectionRecord> c = it.next();
+            for (int conni=0; conni<connections.size(); conni++) {
+                ArrayList<ConnectionRecord> c = connections.valueAt(conni);
                 for (int i=0; i<c.size(); i++) {
                     pw.print(prefix); pw.print("  "); pw.println(c.get(i));
                 }
@@ -285,7 +297,8 @@
 
     ServiceRecord(ActivityManagerService ams,
             BatteryStatsImpl.Uid.Pkg.Serv servStats, ComponentName name,
-            Intent.FilterComparison intent, ServiceInfo sInfo, Runnable restarter) {
+            Intent.FilterComparison intent, ServiceInfo sInfo, boolean callerIsFg,
+            Runnable restarter) {
         this.ams = ams;
         this.stats = servStats;
         this.name = name;
@@ -304,6 +317,19 @@
         createTime = SystemClock.elapsedRealtime();
         lastActivity = SystemClock.uptimeMillis();
         userId = UserHandle.getUserId(appInfo.uid);
+        createdFromFg = callerIsFg;
+    }
+
+    public ProcessStats.ServiceState getTracker() {
+        if (tracker != null) {
+            return tracker;
+        }
+        if ((serviceInfo.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) == 0) {
+            tracker = ams.mProcessStats.getServiceStateLocked(serviceInfo.packageName,
+                    serviceInfo.applicationInfo.uid, serviceInfo.processName, serviceInfo.name);
+            tracker.makeActive();
+        }
+        return tracker;
     }
 
     public AppBindRecord retrieveAppBindingLocked(Intent intent,
@@ -323,6 +349,20 @@
         return a;
     }
 
+    public boolean hasAutoCreateConnections() {
+        // XXX should probably keep a count of the number of auto-create
+        // connections directly in the service.
+        for (int conni=connections.size()-1; conni>=0; conni--) {
+            ArrayList<ConnectionRecord> cr = connections.valueAt(conni);
+            for (int i=0; i<cr.size(); i++) {
+                if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
     public void resetRestartCounter() {
         restartCount = 0;
         restartDelay = 0;
diff --git a/services/java/com/android/server/am/StrictModeViolationDialog.java b/services/java/com/android/server/am/StrictModeViolationDialog.java
index 35d50a1..b6d0daa 100644
--- a/services/java/com/android/server/am/StrictModeViolationDialog.java
+++ b/services/java/com/android/server/am/StrictModeViolationDialog.java
@@ -25,7 +25,7 @@
 import android.os.Message;
 import android.util.Slog;
 
-class StrictModeViolationDialog extends BaseErrorDialog {
+final class StrictModeViolationDialog extends BaseErrorDialog {
     private final static String TAG = "StrictModeViolationDialog";
 
     private final ActivityManagerService mService;
diff --git a/services/java/com/android/server/am/TaskRecord.java b/services/java/com/android/server/am/TaskRecord.java
index 1bae9ca..479665c 100644
--- a/services/java/com/android/server/am/TaskRecord.java
+++ b/services/java/com/android/server/am/TaskRecord.java
@@ -16,15 +16,24 @@
 
 package com.android.server.am;
 
+import static com.android.server.am.ActivityManagerService.TAG;
+import static com.android.server.am.ActivityStackSupervisor.DEBUG_ADD_REMOVE;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.ActivityOptions;
+import android.app.IThumbnailRetriever;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
+import android.graphics.Bitmap;
 import android.os.UserHandle;
 import android.util.Slog;
 
 import java.io.PrintWriter;
+import java.util.ArrayList;
 
-class TaskRecord extends ThumbnailHolder {
+final class TaskRecord extends ThumbnailHolder {
     final int taskId;       // Unique identifier for this task.
     final String affinity;  // The affinity name for this task, or null.
     Intent intent;          // The original intent that started the task.
@@ -39,7 +48,18 @@
 
     String stringName;      // caching of toString() result.
     int userId;             // user for which this task was created
-    
+
+    int numFullscreen;      // Number of fullscreen activities.
+
+    /** List of all activities in the task arranged in history order */
+    final ArrayList<ActivityRecord> mActivities = new ArrayList<ActivityRecord>();
+
+    /** Current stack */
+    ActivityStack stack;
+
+    /** Takes on same set of values as ActivityRecord.mActivityType */
+    private int mTaskType;
+
     TaskRecord(int _taskId, ActivityInfo info, Intent _intent) {
         taskId = _taskId;
         affinity = info.taskAffinity;
@@ -49,11 +69,11 @@
     void touchActiveTime() {
         lastActiveTime = android.os.SystemClock.elapsedRealtime();
     }
-    
+
     long getInactiveDuration() {
         return android.os.SystemClock.elapsedRealtime() - lastActiveTime;
     }
-    
+
     void setIntent(Intent _intent, ActivityInfo info) {
         stringName = null;
 
@@ -104,12 +124,298 @@
             userId = UserHandle.getUserId(info.applicationInfo.uid);
         }
     }
-    
+
+    ActivityRecord getTopActivity() {
+        for (int i = mActivities.size() - 1; i >= 0; --i) {
+            final ActivityRecord r = mActivities.get(i);
+            if (r.finishing) {
+                continue;
+            }
+            return r;
+        }
+        return null;
+    }
+
+    /**
+     * Reorder the history stack so that the activity at the given index is
+     * brought to the front.
+     */
+    final void moveActivityToFrontLocked(ActivityRecord newTop) {
+        if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Removing and adding activity " + newTop
+            + " to stack at top", new RuntimeException("here").fillInStackTrace());
+
+        getTopActivity().frontOfTask = false;
+        mActivities.remove(newTop);
+        mActivities.add(newTop);
+        newTop.frontOfTask = true;
+    }
+
+    void addActivityAtBottom(ActivityRecord r) {
+        addActivityAtIndex(0, r);
+    }
+
+    void addActivityToTop(ActivityRecord r) {
+        addActivityAtIndex(mActivities.size(), r);
+    }
+
+    void addActivityAtIndex(int index, ActivityRecord r) {
+        // Remove r first, and if it wasn't already in the list and it's fullscreen, count it.
+        if (!mActivities.remove(r) && r.fullscreen) {
+            // Was not previously in list.
+            numFullscreen++;
+        }
+        // Only set this based on the first activity
+        if (mActivities.isEmpty()) {
+            mTaskType = r.mActivityType;
+        } else {
+            // Otherwise make all added activities match this one.
+            r.mActivityType = mTaskType;
+        }
+        mActivities.add(index, r);
+    }
+
+    /** @return true if this was the last activity in the task */
+    boolean removeActivity(ActivityRecord r) {
+        if (mActivities.remove(r) && r.fullscreen) {
+            // Was previously in list.
+            numFullscreen--;
+        }
+        return mActivities.size() == 0;
+    }
+
+    /**
+     * Completely remove all activities associated with an existing
+     * task starting at a specified index.
+     */
+    final void performClearTaskAtIndexLocked(int activityNdx) {
+        int numActivities = mActivities.size();
+        for ( ; activityNdx < numActivities; ++activityNdx) {
+            final ActivityRecord r = mActivities.get(activityNdx);
+            if (r.finishing) {
+                continue;
+            }
+            if (stack.finishActivityLocked(r, Activity.RESULT_CANCELED, null, "clear", false)) {
+                --activityNdx;
+                --numActivities;
+            }
+        }
+    }
+
+    /**
+     * Completely remove all activities associated with an existing task.
+     */
+    final void performClearTaskLocked() {
+        performClearTaskAtIndexLocked(0);
+    }
+
+    /**
+     * Perform clear operation as requested by
+     * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the
+     * stack to the given task, then look for
+     * an instance of that activity in the stack and, if found, finish all
+     * activities on top of it and return the instance.
+     *
+     * @param newR Description of the new activity being started.
+     * @return Returns the old activity that should be continued to be used,
+     * or null if none was found.
+     */
+    final ActivityRecord performClearTaskLocked(ActivityRecord newR, int launchFlags) {
+        int numActivities = mActivities.size();
+        for (int activityNdx = numActivities - 1; activityNdx >= 0; --activityNdx) {
+            ActivityRecord r = mActivities.get(activityNdx);
+            if (r.finishing) {
+                continue;
+            }
+            if (r.realActivity.equals(newR.realActivity)) {
+                // Here it is!  Now finish everything in front...
+                final ActivityRecord ret = r;
+
+                for (++activityNdx; activityNdx < numActivities; ++activityNdx) {
+                    r = mActivities.get(activityNdx);
+                    if (r.finishing) {
+                        continue;
+                    }
+                    ActivityOptions opts = r.takeOptionsLocked();
+                    if (opts != null) {
+                        ret.updateOptionsLocked(opts);
+                    }
+                    if (stack.finishActivityLocked(r, Activity.RESULT_CANCELED, null, "clear",
+                            false)) {
+                        --activityNdx;
+                        --numActivities;
+                    }
+                }
+
+                // Finally, if this is a normal launch mode (that is, not
+                // expecting onNewIntent()), then we will finish the current
+                // instance of the activity so a new fresh one can be started.
+                if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
+                        && (launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0) {
+                    if (!ret.finishing) {
+                        stack.finishActivityLocked(ret, Activity.RESULT_CANCELED, null,
+                                "clear", false);
+                        return null;
+                    }
+                }
+
+                return ret;
+            }
+        }
+
+        return null;
+    }
+
+    public ActivityManager.TaskThumbnails getTaskThumbnailsLocked() {
+        TaskAccessInfo info = getTaskAccessInfoLocked(true);
+        final ActivityRecord resumedActivity = stack.mResumedActivity;
+        if (resumedActivity != null && resumedActivity.thumbHolder == this) {
+            info.mainThumbnail = stack.screenshotActivities(resumedActivity);
+        }
+        if (info.mainThumbnail == null) {
+            info.mainThumbnail = lastThumbnail;
+        }
+        return info;
+    }
+
+    public Bitmap getTaskTopThumbnailLocked() {
+        final ActivityRecord resumedActivity = stack.mResumedActivity;
+        if (resumedActivity != null && resumedActivity.task == this) {
+            // This task is the current resumed task, we just need to take
+            // a screenshot of it and return that.
+            return stack.screenshotActivities(resumedActivity);
+        }
+        // Return the information about the task, to figure out the top
+        // thumbnail to return.
+        TaskAccessInfo info = getTaskAccessInfoLocked(true);
+        if (info.numSubThumbbails <= 0) {
+            return info.mainThumbnail != null ? info.mainThumbnail : lastThumbnail;
+        }
+        return info.subtasks.get(info.numSubThumbbails-1).holder.lastThumbnail;
+    }
+
+    public ActivityRecord removeTaskActivitiesLocked(int subTaskIndex,
+            boolean taskRequired) {
+        TaskAccessInfo info = getTaskAccessInfoLocked(false);
+        if (info.root == null) {
+            if (taskRequired) {
+                Slog.w(TAG, "removeTaskLocked: unknown taskId " + taskId);
+            }
+            return null;
+        }
+
+        if (subTaskIndex < 0) {
+            // Just remove the entire task.
+            performClearTaskAtIndexLocked(info.rootIndex);
+            return info.root;
+        }
+
+        if (subTaskIndex >= info.subtasks.size()) {
+            if (taskRequired) {
+                Slog.w(TAG, "removeTaskLocked: unknown subTaskIndex " + subTaskIndex);
+            }
+            return null;
+        }
+
+        // Remove all of this task's activities starting at the sub task.
+        TaskAccessInfo.SubTask subtask = info.subtasks.get(subTaskIndex);
+        performClearTaskAtIndexLocked(subtask.index);
+        return subtask.activity;
+    }
+
+    boolean isHomeTask() {
+        return mTaskType == ActivityRecord.HOME_ACTIVITY_TYPE;
+    }
+
+    boolean isApplicationTask() {
+        return mTaskType == ActivityRecord.APPLICATION_ACTIVITY_TYPE;
+    }
+
+    public TaskAccessInfo getTaskAccessInfoLocked(boolean inclThumbs) {
+        final TaskAccessInfo thumbs = new TaskAccessInfo();
+        // How many different sub-thumbnails?
+        final int NA = mActivities.size();
+        int j = 0;
+        ThumbnailHolder holder = null;
+        while (j < NA) {
+            ActivityRecord ar = mActivities.get(j);
+            if (!ar.finishing) {
+                thumbs.root = ar;
+                thumbs.rootIndex = j;
+                holder = ar.thumbHolder;
+                if (holder != null) {
+                    thumbs.mainThumbnail = holder.lastThumbnail;
+                }
+                j++;
+                break;
+            }
+            j++;
+        }
+
+        if (j >= NA) {
+            return thumbs;
+        }
+
+        ArrayList<TaskAccessInfo.SubTask> subtasks = new ArrayList<TaskAccessInfo.SubTask>();
+        thumbs.subtasks = subtasks;
+        while (j < NA) {
+            ActivityRecord ar = mActivities.get(j);
+            j++;
+            if (ar.finishing) {
+                continue;
+            }
+            if (ar.thumbHolder != holder && holder != null) {
+                thumbs.numSubThumbbails++;
+                holder = ar.thumbHolder;
+                TaskAccessInfo.SubTask sub = new TaskAccessInfo.SubTask();
+                sub.holder = holder;
+                sub.activity = ar;
+                sub.index = j-1;
+                subtasks.add(sub);
+            }
+        }
+        if (thumbs.numSubThumbbails > 0) {
+            thumbs.retriever = new IThumbnailRetriever.Stub() {
+                @Override
+                public Bitmap getThumbnail(int index) {
+                    if (index < 0 || index >= thumbs.subtasks.size()) {
+                        return null;
+                    }
+                    TaskAccessInfo.SubTask sub = thumbs.subtasks.get(index);
+                    ActivityRecord resumedActivity = stack.mResumedActivity;
+                    if (resumedActivity != null && resumedActivity.thumbHolder == sub.holder) {
+                        return stack.screenshotActivities(resumedActivity);
+                    }
+                    return sub.holder.lastThumbnail;
+                }
+            };
+        }
+        return thumbs;
+    }
+
+    /**
+     * 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.
+     */
+    final ActivityRecord findActivityInHistoryLocked(ActivityRecord r) {
+        final ComponentName realActivity = r.realActivity;
+        for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
+            ActivityRecord candidate = mActivities.get(activityNdx);
+            if (candidate.finishing) {
+                continue;
+            }
+            if (candidate.realActivity.equals(realActivity)) {
+                return candidate;
+            }
+        }
+        return null;
+    }
+
     void dump(PrintWriter pw, String prefix) {
         if (numActivities != 0 || rootWasReset || userId != 0) {
             pw.print(prefix); pw.print("numActivities="); pw.print(numActivities);
                     pw.print(" rootWasReset="); pw.print(rootWasReset);
-                    pw.print(" userId="); pw.println(userId);
+                    pw.print(" userId="); pw.print(userId);
+                    pw.print(" numFullscreen="); pw.println(numFullscreen);
         }
         if (affinity != null) {
             pw.print(prefix); pw.print("affinity="); pw.println(affinity);
@@ -136,6 +442,7 @@
             pw.print(prefix); pw.print("realActivity=");
             pw.println(realActivity.flattenToShortString());
         }
+        pw.print(prefix); pw.print("Activities="); pw.println(mActivities);
         if (!askedCompatMode) {
             pw.print(prefix); pw.print("askedCompatMode="); pw.println(askedCompatMode);
         }
@@ -146,30 +453,35 @@
                 pw.print((getInactiveDuration()/1000)); pw.println("s)");
     }
 
+    @Override
     public String toString() {
-        if (stringName != null) {
-            return stringName;
-        }
         StringBuilder sb = new StringBuilder(128);
+        if (stringName != null) {
+            sb.append(stringName);
+            sb.append(" U=");
+            sb.append(userId);
+            sb.append(" sz=");
+            sb.append(mActivities.size());
+            sb.append('}');
+            return sb.toString();
+        }
         sb.append("TaskRecord{");
         sb.append(Integer.toHexString(System.identityHashCode(this)));
         sb.append(" #");
         sb.append(taskId);
         if (affinity != null) {
-            sb.append(" A ");
+            sb.append(" A=");
             sb.append(affinity);
         } else if (intent != null) {
-            sb.append(" I ");
+            sb.append(" I=");
             sb.append(intent.getComponent().flattenToShortString());
         } else if (affinityIntent != null) {
-            sb.append(" aI ");
+            sb.append(" aI=");
             sb.append(affinityIntent.getComponent().flattenToShortString());
         } else {
             sb.append(" ??");
         }
-        sb.append(" U ");
-        sb.append(userId);
-        sb.append('}');
-        return stringName = sb.toString();
+        stringName = sb.toString();
+        return toString();
     }
 }
diff --git a/services/java/com/android/server/am/TransferPipe.java b/services/java/com/android/server/am/TransferPipe.java
deleted file mode 100644
index c3f4f93..0000000
--- a/services/java/com/android/server/am/TransferPipe.java
+++ /dev/null
@@ -1,242 +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.server.am;
-
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-
-import android.os.Binder;
-import android.os.IBinder;
-import android.os.IInterface;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.util.Slog;
-
-/**
- * Helper for transferring data through a pipe from a client app.
- */
-class TransferPipe implements Runnable {
-    static final String TAG = "TransferPipe";
-    static final boolean DEBUG = false;
-
-    static final long DEFAULT_TIMEOUT = 5000;  // 5 seconds
-
-    final Thread mThread;;
-    final ParcelFileDescriptor[] mFds;
-
-    FileDescriptor mOutFd;
-    long mEndTime;
-    String mFailure;
-    boolean mComplete;
-
-    String mBufferPrefix;
-
-    interface Caller {
-        void go(IInterface iface, FileDescriptor fd, String prefix,
-                String[] args) throws RemoteException;
-    }
-
-    TransferPipe() throws IOException {
-        mThread = new Thread(this, "TransferPipe");
-        mFds = ParcelFileDescriptor.createPipe();
-    }
-
-    ParcelFileDescriptor getReadFd() {
-        return mFds[0];
-    }
-
-    ParcelFileDescriptor getWriteFd() {
-        return mFds[1];
-    }
-
-    void setBufferPrefix(String prefix) {
-        mBufferPrefix = prefix;
-    }
-
-    static void go(Caller caller, IInterface iface, FileDescriptor out,
-            String prefix, String[] args) throws IOException, RemoteException {
-        go(caller, iface, out, prefix, args, DEFAULT_TIMEOUT);
-    }
-
-    static void go(Caller caller, IInterface iface, FileDescriptor out,
-            String prefix, String[] args, long timeout) throws IOException, RemoteException {
-        if ((iface.asBinder()) instanceof Binder) {
-            // This is a local object...  just call it directly.
-            try {
-                caller.go(iface, out, prefix, args);
-            } catch (RemoteException e) {
-            }
-            return;
-        }
-
-        TransferPipe tp = new TransferPipe();
-        try {
-            caller.go(iface, tp.getWriteFd().getFileDescriptor(), prefix, args);
-            tp.go(out, timeout);
-        } finally {
-            tp.kill();
-        }
-    }
-
-    static void goDump(IBinder binder, FileDescriptor out,
-            String[] args) throws IOException, RemoteException {
-        goDump(binder, out, args, DEFAULT_TIMEOUT);
-    }
-
-    static void goDump(IBinder binder, FileDescriptor out,
-            String[] args, long timeout) throws IOException, RemoteException {
-        if (binder instanceof Binder) {
-            // This is a local object...  just call it directly.
-            try {
-                binder.dump(out, args);
-            } catch (RemoteException e) {
-            }
-            return;
-        }
-
-        TransferPipe tp = new TransferPipe();
-        try {
-            binder.dumpAsync(tp.getWriteFd().getFileDescriptor(), args);
-            tp.go(out, timeout);
-        } finally {
-            tp.kill();
-        }
-    }
-
-    void go(FileDescriptor out) throws IOException {
-        go(out, DEFAULT_TIMEOUT);
-    }
-
-    void go(FileDescriptor out, long timeout) throws IOException {
-        try {
-            synchronized (this) {
-                mOutFd = out;
-                mEndTime = SystemClock.uptimeMillis() + timeout;
-
-                if (DEBUG) Slog.i(TAG, "read=" + getReadFd() + " write=" + getWriteFd()
-                        + " out=" + out);
-
-                // Close the write fd, so we know when the other side is done.
-                closeFd(1);
-
-                mThread.start();
-
-                while (mFailure == null && !mComplete) {
-                    long waitTime = mEndTime - SystemClock.uptimeMillis();
-                    if (waitTime <= 0) {
-                        if (DEBUG) Slog.i(TAG, "TIMEOUT!");
-                        mThread.interrupt();
-                        throw new IOException("Timeout");
-                    }
-
-                    try {
-                        wait(waitTime);
-                    } catch (InterruptedException e) {
-                    }
-                }
-
-                if (DEBUG) Slog.i(TAG, "Finished: " + mFailure);
-                if (mFailure != null) {
-                    throw new IOException(mFailure);
-                }
-            }
-        } finally {
-            kill();
-        }
-    }
-
-    void closeFd(int num) {
-        if (mFds[num] != null) {
-            if (DEBUG) Slog.i(TAG, "Closing: " + mFds[num]);
-            try {
-                mFds[num].close();
-            } catch (IOException e) {
-            }
-            mFds[num] = null;
-        }
-    }
-
-    void kill() {
-        closeFd(0);
-        closeFd(1);
-    }
-
-    @Override
-    public void run() {
-        final byte[] buffer = new byte[1024];
-        final FileInputStream fis = new FileInputStream(getReadFd().getFileDescriptor());
-        final FileOutputStream fos = new FileOutputStream(mOutFd);
-
-        if (DEBUG) Slog.i(TAG, "Ready to read pipe...");
-        byte[] bufferPrefix = null;
-        boolean needPrefix = true;
-        if (mBufferPrefix != null) {
-            bufferPrefix = mBufferPrefix.getBytes();
-        }
-
-        int size;
-        try {
-            while ((size=fis.read(buffer)) > 0) {
-                if (DEBUG) Slog.i(TAG, "Got " + size + " bytes");
-                if (bufferPrefix == null) {
-                    fos.write(buffer, 0, size);
-                } else {
-                    int start = 0;
-                    for (int i=0; i<size; i++) {
-                        if (buffer[i] != '\n') {
-                            if (i > start) {
-                                fos.write(buffer, start, i-start);
-                            }
-                            start = i;
-                            if (needPrefix) {
-                                fos.write(bufferPrefix);
-                                needPrefix = false;
-                            }
-                            do {
-                                i++;
-                            } while (i<size && buffer[i] != '\n');
-                            if (i < size) {
-                                needPrefix = true;
-                            }
-                        }
-                    }
-                    if (size > start) {
-                        fos.write(buffer, start, size-start);
-                    }
-                }
-            }
-            if (DEBUG) Slog.i(TAG, "End of pipe: size=" + size);
-            if (mThread.isInterrupted()) {
-                if (DEBUG) Slog.i(TAG, "Interrupted!");
-            }
-        } catch (IOException e) {
-            synchronized (this) {
-                mFailure = e.toString();
-                notifyAll();
-                return;
-            }
-        }
-
-        synchronized (this) {
-            mComplete = true;
-            notifyAll();
-        }
-    }
-}
diff --git a/services/java/com/android/server/am/UriPermission.java b/services/java/com/android/server/am/UriPermission.java
index c5b1c7b..5e2ad009 100644
--- a/services/java/com/android/server/am/UriPermission.java
+++ b/services/java/com/android/server/am/UriPermission.java
@@ -18,6 +18,11 @@
 
 import android.content.Intent;
 import android.net.Uri;
+import android.os.UserHandle;
+import android.util.Log;
+
+import com.android.internal.util.IndentingPrintWriter;
+import com.google.android.collect.Sets;
 
 import java.io.PrintWriter;
 import java.util.HashSet;
@@ -30,44 +35,172 @@
  * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
  *      src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
  */
-class UriPermission {
-    final int uid;
+final class UriPermission {
+    private static final String TAG = "UriPermission";
+
+    final int userHandle;
+    final String sourcePkg;
+    final String targetPkg;
+
+    /** Cached UID of {@link #targetPkg}; should not be persisted */
+    final int targetUid;
+
     final Uri uri;
+
+    /**
+     * Allowed modes. All permission enforcement should use this field. Must
+     * always be a superset of {@link #globalModeFlags},
+     * {@link #persistedModeFlags}, {@link #mReadOwners}, and
+     * {@link #mWriteOwners}. Mutations should only be performed by the owning
+     * class.
+     */
     int modeFlags = 0;
+
+    /**
+     * Allowed modes without explicit owner. Must always be a superset of
+     * {@link #persistedModeFlags}. Mutations should only be performed by the
+     * owning class.
+     */
     int globalModeFlags = 0;
-    final HashSet<UriPermissionOwner> readOwners = new HashSet<UriPermissionOwner>();
-    final HashSet<UriPermissionOwner> writeOwners = new HashSet<UriPermissionOwner>();
-    
-    String stringName;
-    
-    UriPermission(int _uid, Uri _uri) {
-        uid = _uid;
-        uri = _uri;
+
+    /**
+     * Allowed modes that should be persisted across device boots. These modes
+     * have no explicit owners. Mutations should only be performed by the owning
+     * class.
+     */
+    int persistedModeFlags = 0;
+
+    private HashSet<UriPermissionOwner> mReadOwners;
+    private HashSet<UriPermissionOwner> mWriteOwners;
+
+    private String stringName;
+
+    UriPermission(String sourcePkg, String targetPkg, int targetUid, Uri uri) {
+        this.userHandle = UserHandle.getUserId(targetUid);
+        this.sourcePkg = sourcePkg;
+        this.targetPkg = targetPkg;
+        this.targetUid = targetUid;
+        this.uri = uri;
+    }
+
+    /**
+     * @return If mode changes should trigger persisting.
+     */
+    boolean grantModes(int modeFlagsToGrant, boolean persist, UriPermissionOwner owner) {
+        boolean persistChanged = false;
+
+        modeFlags |= modeFlagsToGrant;
+
+        if (persist) {
+            final int before = persistedModeFlags;
+            persistedModeFlags |= modeFlagsToGrant;
+            persistChanged = persistedModeFlags != before;
+
+            // Treat persisted grants as global (ownerless)
+            owner = null;
+        }
+
+        if (owner == null) {
+            globalModeFlags |= modeFlags;
+        } else {
+            if ((modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
+                addReadOwner(owner);
+                owner.addReadPermission(this);
+            }
+            if ((modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
+                addWriteOwner(owner);
+                owner.addWritePermission(this);
+            }
+        }
+
+        return persistChanged;
     }
     
-    void clearModes(int modeFlagsToClear) {
-        if ((modeFlagsToClear&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
+    /**
+     * @return If mode changes should trigger persisting.
+     */
+    boolean clearModes(int modeFlagsToClear, boolean persist) {
+        final int before = persistedModeFlags;
+
+        if ((modeFlagsToClear & Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
+            if (persist) {
+                persistedModeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION;
+            }
             globalModeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION;
             modeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION;
-            if (readOwners.size() > 0) {
-                for (UriPermissionOwner r : readOwners) {
+            if (mReadOwners != null) {
+                for (UriPermissionOwner r : mReadOwners) {
                     r.removeReadPermission(this);
                 }
-                readOwners.clear();
+                mReadOwners = null;
             }
         }
-        if ((modeFlagsToClear&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
+        if ((modeFlagsToClear & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
+            if (persist) {
+                persistedModeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
+            }
             globalModeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
             modeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
-            if (writeOwners.size() > 0) {
-                for (UriPermissionOwner r : writeOwners) {
+            if (mWriteOwners != null) {
+                for (UriPermissionOwner r : mWriteOwners) {
                     r.removeWritePermission(this);
                 }
-                writeOwners.clear();
+                mWriteOwners = null;
+            }
+        }
+
+        // Mode flags always bubble up
+        globalModeFlags |= persistedModeFlags;
+        modeFlags |= globalModeFlags;
+
+        return persistedModeFlags != before;
+    }
+
+    private void addReadOwner(UriPermissionOwner owner) {
+        if (mReadOwners == null) {
+            mReadOwners = Sets.newHashSet();
+        }
+        mReadOwners.add(owner);
+    }
+
+    /**
+     * Remove given read owner, updating {@Link #modeFlags} as needed.
+     */
+    void removeReadOwner(UriPermissionOwner owner) {
+        if (!mReadOwners.remove(owner)) {
+            Log.wtf(TAG, "Unknown read owner " + owner + " in " + this);
+        }
+        if (mReadOwners.size() == 0) {
+            mReadOwners = null;
+            if ((globalModeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0) {
+                modeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION;
             }
         }
     }
-    
+
+    private void addWriteOwner(UriPermissionOwner owner) {
+        if (mWriteOwners == null) {
+            mWriteOwners = Sets.newHashSet();
+        }
+        mWriteOwners.add(owner);
+    }
+
+    /**
+     * Remove given write owner, updating {@Link #modeFlags} as needed.
+     */
+    void removeWriteOwner(UriPermissionOwner owner) {
+        if (!mWriteOwners.remove(owner)) {
+            Log.wtf(TAG, "Unknown write owner " + owner + " in " + this);
+        }
+        if (mWriteOwners.size() == 0) {
+            mWriteOwners = null;
+            if ((globalModeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0) {
+                modeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
+            }
+        }
+    }
+
+    @Override
     public String toString() {
         if (stringName != null) {
             return stringName;
@@ -82,22 +215,55 @@
     }
 
     void dump(PrintWriter pw, String prefix) {
-        pw.print(prefix); pw.print("modeFlags=0x");
-                pw.print(Integer.toHexString(modeFlags));
-                pw.print(" uid="); pw.print(uid); 
-                pw.print(" globalModeFlags=0x");
-                pw.println(Integer.toHexString(globalModeFlags));
-        if (readOwners.size() != 0) {
-            pw.print(prefix); pw.println("readOwners:");
-            for (UriPermissionOwner owner : readOwners) {
-                pw.print(prefix); pw.print("  * "); pw.println(owner);
+        pw.print(prefix);
+        pw.print("userHandle=" + userHandle);
+        pw.print(" sourcePkg=" + sourcePkg);
+        pw.println(" targetPkg=" + targetPkg);
+
+        pw.print(prefix);
+        pw.print("modeFlags=0x" + Integer.toHexString(modeFlags));
+        pw.print(" globalModeFlags=0x" + Integer.toHexString(globalModeFlags));
+        pw.println(" persistedModeFlags=0x" + Integer.toHexString(persistedModeFlags));
+
+        if (mReadOwners != null) {
+            pw.print(prefix);
+            pw.println("readOwners:");
+            for (UriPermissionOwner owner : mReadOwners) {
+                pw.print(prefix);
+                pw.println("  * " + owner);
             }
         }
-        if (writeOwners.size() != 0) {
-            pw.print(prefix); pw.println("writeOwners:");
-            for (UriPermissionOwner owner : writeOwners) {
-                pw.print(prefix); pw.print("  * "); pw.println(owner);
+        if (mWriteOwners != null) {
+            pw.print(prefix);
+            pw.println("writeOwners:");
+            for (UriPermissionOwner owner : mReadOwners) {
+                pw.print(prefix);
+                pw.println("  * " + owner);
             }
         }
     }
+
+    /**
+     * Snapshot of {@link UriPermission} with frozen
+     * {@link UriPermission#persistedModeFlags} state.
+     */
+    public static class Snapshot {
+        final int userHandle;
+        final String sourcePkg;
+        final String targetPkg;
+        final Uri uri;
+        final int persistedModeFlags;
+
+        private Snapshot(UriPermission perm) {
+            this.userHandle = perm.userHandle;
+            this.sourcePkg = perm.sourcePkg;
+            this.targetPkg = perm.targetPkg;
+            this.uri = perm.uri;
+            this.persistedModeFlags = perm.persistedModeFlags;
+        }
+    }
+
+    public Snapshot snapshot() {
+        return new Snapshot(this);
+    }
 }
diff --git a/services/java/com/android/server/am/UriPermissionOwner.java b/services/java/com/android/server/am/UriPermissionOwner.java
index 68a2e0f..7bbd3bc 100644
--- a/services/java/com/android/server/am/UriPermissionOwner.java
+++ b/services/java/com/android/server/am/UriPermissionOwner.java
@@ -24,7 +24,7 @@
 import java.util.HashSet;
 import java.util.Iterator;
 
-class UriPermissionOwner {
+final class UriPermissionOwner {
     final ActivityManagerService service;
     final Object owner;
 
@@ -67,24 +67,16 @@
         if ((mode&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0
                 && readUriPermissions != null) {
             for (UriPermission perm : readUriPermissions) {
-                perm.readOwners.remove(this);
-                if (perm.readOwners.size() == 0 && (perm.globalModeFlags
-                        &Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0) {
-                    perm.modeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION;
-                    service.removeUriPermissionIfNeededLocked(perm);
-                }
+                perm.removeReadOwner(this);
+                service.removeUriPermissionIfNeededLocked(perm);
             }
             readUriPermissions = null;
         }
         if ((mode&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0
                 && writeUriPermissions != null) {
             for (UriPermission perm : writeUriPermissions) {
-                perm.writeOwners.remove(this);
-                if (perm.writeOwners.size() == 0 && (perm.globalModeFlags
-                        &Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0) {
-                    perm.modeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
-                    service.removeUriPermissionIfNeededLocked(perm);
-                }
+                perm.removeWriteOwner(this);
+                service.removeUriPermissionIfNeededLocked(perm);
             }
             writeUriPermissions = null;
         }
@@ -97,12 +89,8 @@
             while (it.hasNext()) {
                 UriPermission perm = it.next();
                 if (uri.equals(perm.uri)) {
-                    perm.readOwners.remove(this);
-                    if (perm.readOwners.size() == 0 && (perm.globalModeFlags
-                            &Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0) {
-                        perm.modeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION;
-                        service.removeUriPermissionIfNeededLocked(perm);
-                    }
+                    perm.removeReadOwner(this);
+                    service.removeUriPermissionIfNeededLocked(perm);
                     it.remove();
                 }
             }
@@ -116,12 +104,8 @@
             while (it.hasNext()) {
                 UriPermission perm = it.next();
                 if (uri.equals(perm.uri)) {
-                    perm.writeOwners.remove(this);
-                    if (perm.writeOwners.size() == 0 && (perm.globalModeFlags
-                            &Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0) {
-                        perm.modeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
-                        service.removeUriPermissionIfNeededLocked(perm);
-                    }
+                    perm.removeWriteOwner(this);
+                    service.removeUriPermissionIfNeededLocked(perm);
                     it.remove();
                 }
             }
diff --git a/services/java/com/android/server/am/UsageStatsService.java b/services/java/com/android/server/am/UsageStatsService.java
index 6dae4aa..e96d8b1 100644
--- a/services/java/com/android/server/am/UsageStatsService.java
+++ b/services/java/com/android/server/am/UsageStatsService.java
@@ -16,8 +16,10 @@
 
 package com.android.server.am;
 
+import android.app.AppGlobals;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.pm.IPackageManager;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.os.Binder;
@@ -25,8 +27,10 @@
 import android.os.FileUtils;
 import android.os.Parcel;
 import android.os.Process;
+import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
+import android.util.ArrayMap;
 import android.util.AtomicFile;
 import android.util.Slog;
 import android.util.Xml;
@@ -73,7 +77,7 @@
     private static final String TAG = "UsageStats";
     
     // Current on-disk Parcel version
-    private static final int VERSION = 1007;
+    private static final int VERSION = 1008;
 
     private static final int CHECKIN_VERSION = 4;
     
@@ -93,10 +97,10 @@
     static IUsageStats sService;
     private Context mContext;
     // structure used to maintain statistics since the last checkin.
-    final private Map<String, PkgUsageStatsExtended> mStats;
+    final private ArrayMap<String, PkgUsageStatsExtended> mStats;
 
     // Maintains the last time any component was resumed, for all time.
-    final private Map<String, Map<String, Long>> mLastResumeTimes;
+    final private ArrayMap<String, ArrayMap<String, Long>> mLastResumeTimes;
 
     // To remove last-resume time stats when a pacakge is removed.
     private PackageMonitor mPackageMonitor;
@@ -162,8 +166,10 @@
     }
     
     private class PkgUsageStatsExtended {
-        final HashMap<String, TimeStats> mLaunchTimes
-                = new HashMap<String, TimeStats>();
+        final ArrayMap<String, TimeStats> mLaunchTimes
+                = new ArrayMap<String, TimeStats>();
+        final ArrayMap<String, TimeStats> mFullyDrawnTimes
+                = new ArrayMap<String, TimeStats>();
         int mLaunchCount;
         long mUsageTime;
         long mPausedTime;
@@ -180,14 +186,25 @@
             if (localLOGV) Slog.v(TAG, "Launch count: " + mLaunchCount
                     + ", Usage time:" + mUsageTime);
             
-            final int numTimeStats = in.readInt();
-            if (localLOGV) Slog.v(TAG, "Reading comps: " + numTimeStats);
-            for (int i=0; i<numTimeStats; i++) {
+            final int numLaunchTimeStats = in.readInt();
+            if (localLOGV) Slog.v(TAG, "Reading launch times: " + numLaunchTimeStats);
+            mLaunchTimes.ensureCapacity(numLaunchTimeStats);
+            for (int i=0; i<numLaunchTimeStats; i++) {
                 String comp = in.readString();
                 if (localLOGV) Slog.v(TAG, "Component: " + comp);
                 TimeStats times = new TimeStats(in);
                 mLaunchTimes.put(comp, times);
             }
+
+            final int numFullyDrawnTimeStats = in.readInt();
+            if (localLOGV) Slog.v(TAG, "Reading fully drawn times: " + numFullyDrawnTimeStats);
+            mFullyDrawnTimes.ensureCapacity(numFullyDrawnTimeStats);
+            for (int i=0; i<numFullyDrawnTimeStats; i++) {
+                String comp = in.readString();
+                if (localLOGV) Slog.v(TAG, "Component: " + comp);
+                TimeStats times = new TimeStats(in);
+                mFullyDrawnTimes.put(comp, times);
+            }
         }
 
         void updateResume(String comp, boolean launched) {
@@ -219,31 +236,44 @@
             }
             times.add(millis);
         }
-        
+
+        void addFullyDrawnTime(String comp, int millis) {
+            TimeStats times = mFullyDrawnTimes.get(comp);
+            if (times == null) {
+                times = new TimeStats();
+                mFullyDrawnTimes.put(comp, times);
+            }
+            times.add(millis);
+        }
+
         void writeToParcel(Parcel out) {
             out.writeInt(mLaunchCount);
             out.writeLong(mUsageTime);
-            final int numTimeStats = mLaunchTimes.size();
-            out.writeInt(numTimeStats);
-            if (numTimeStats > 0) {
-                for (Map.Entry<String, TimeStats> ent : mLaunchTimes.entrySet()) {
-                    out.writeString(ent.getKey());
-                    TimeStats times = ent.getValue();
-                    times.writeToParcel(out);
-                }
+            final int numLaunchTimeStats = mLaunchTimes.size();
+            out.writeInt(numLaunchTimeStats);
+            for (int i=0; i<numLaunchTimeStats; i++) {
+                out.writeString(mLaunchTimes.keyAt(i));
+                mLaunchTimes.valueAt(i).writeToParcel(out);
+            }
+            final int numFullyDrawnTimeStats = mFullyDrawnTimes.size();
+            out.writeInt(numFullyDrawnTimeStats);
+            for (int i=0; i<numFullyDrawnTimeStats; i++) {
+                out.writeString(mFullyDrawnTimes.keyAt(i));
+                mFullyDrawnTimes.valueAt(i).writeToParcel(out);
             }
         }
         
         void clear() {
             mLaunchTimes.clear();
+            mFullyDrawnTimes.clear();
             mLaunchCount = 0;
             mUsageTime = 0;
         }
     }
     
     UsageStatsService(String dir) {
-        mStats = new HashMap<String, PkgUsageStatsExtended>();
-        mLastResumeTimes = new HashMap<String, Map<String, Long>>();
+        mStats = new ArrayMap<String, PkgUsageStatsExtended>();
+        mLastResumeTimes = new ArrayMap<String, ArrayMap<String, Long>>();
         mStatsLock = new Object();
         mFileLock = new Object();
         mDir = new File(dir);
@@ -386,9 +416,9 @@
                                 try {
                                     long lastResumeTime = Long.parseLong(lastResumeTimeStr);
                                     synchronized (mStatsLock) {
-                                        Map<String, Long> lrt = mLastResumeTimes.get(pkg);
+                                        ArrayMap<String, Long> lrt = mLastResumeTimes.get(pkg);
                                         if (lrt == null) {
-                                            lrt = new HashMap<String, Long>();
+                                            lrt = new ArrayMap<String, Long>();
                                             mLastResumeTimes.put(pkg, lrt);
                                         }
                                         lrt.put(comp, lastResumeTime);
@@ -591,14 +621,15 @@
     /** Filter out stats for any packages which aren't present anymore. */
     private void filterHistoryStats() {
         synchronized (mStatsLock) {
-            // Copy and clear the last resume times map, then copy back stats
-            // for all installed packages.
-            Map<String, Map<String, Long>> tmpLastResumeTimes =
-                new HashMap<String, Map<String, Long>>(mLastResumeTimes);
-            mLastResumeTimes.clear();
-            for (PackageInfo info : mContext.getPackageManager().getInstalledPackages(0)) {
-                if (tmpLastResumeTimes.containsKey(info.packageName)) {
-                    mLastResumeTimes.put(info.packageName, tmpLastResumeTimes.get(info.packageName));
+            IPackageManager pm = AppGlobals.getPackageManager();
+            for (int i=0; i<mLastResumeTimes.size(); i++) {
+                String pkg = mLastResumeTimes.keyAt(i);
+                try {
+                    if (pm.getPackageUid(pkg, 0) < 0) {
+                        mLastResumeTimes.removeAt(i);
+                        i--;
+                    }
+                } catch (RemoteException e) {
                 }
             }
         }
@@ -614,13 +645,14 @@
             out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
             out.startTag(null, "usage-history");
             synchronized (mStatsLock) {
-                for (Map.Entry<String, Map<String, Long>> pkgEntry : mLastResumeTimes.entrySet()) {
+                for (int i=0; i<mLastResumeTimes.size(); i++) {
                     out.startTag(null, "pkg");
-                    out.attribute(null, "name", pkgEntry.getKey());
-                    for (Map.Entry<String, Long> compEntry : pkgEntry.getValue().entrySet()) {
+                    out.attribute(null, "name", mLastResumeTimes.keyAt(i));
+                    ArrayMap<String, Long> comp = mLastResumeTimes.valueAt(i);
+                    for (int j=0; j<comp.size(); j++) {
                         out.startTag(null, "comp");
-                        out.attribute(null, "name", compEntry.getKey());
-                        out.attribute(null, "lrt", compEntry.getValue().toString());
+                        out.attribute(null, "name", comp.keyAt(j));
+                        out.attribute(null, "lrt", comp.valueAt(j).toString());
                         out.endTag(null, "comp");
                     }
                     out.endTag(null, "pkg");
@@ -718,9 +750,9 @@
                 pus.addLaunchCount(mLastResumedComp);
             }
 
-            Map<String, Long> componentResumeTimes = mLastResumeTimes.get(pkgName);
+            ArrayMap<String, Long> componentResumeTimes = mLastResumeTimes.get(pkgName);
             if (componentResumeTimes == null) {
-                componentResumeTimes = new HashMap<String, Long>();
+                componentResumeTimes = new ArrayMap<String, Long>();
                 mLastResumeTimes.put(pkgName, componentResumeTimes);
             }
             componentResumeTimes.put(mLastResumedComp, System.currentTimeMillis());
@@ -777,6 +809,25 @@
         }
     }
     
+    public void noteFullyDrawnTime(ComponentName componentName, int millis) {
+        enforceCallingPermission();
+        String pkgName;
+        if ((componentName == null) ||
+                ((pkgName = componentName.getPackageName()) == null)) {
+            return;
+        }
+
+        // Persist current data to file if needed.
+        writeStatsToFile(false, false);
+
+        synchronized (mStatsLock) {
+            PkgUsageStatsExtended pus = mStats.get(pkgName);
+            if (pus != null) {
+                pus.addFullyDrawnTime(componentName.getClassName(), millis);
+            }
+        }
+    }
+
     public void enforceCallingPermission() {
         if (Binder.getCallingPid() == Process.myPid()) {
             return;
@@ -814,9 +865,8 @@
                 return null;
             }
             PkgUsageStats retArr[] = new PkgUsageStats[size];
-            int i = 0;
-            for (Map.Entry<String, Map<String, Long>> entry : mLastResumeTimes.entrySet()) {
-                String pkg = entry.getKey();
+            for (int i=0; i<size; i++) {
+                String pkg = mLastResumeTimes.keyAt(i);
                 long usageTime = 0;
                 int launchCount = 0;
 
@@ -825,8 +875,8 @@
                     usageTime = pus.mUsageTime;
                     launchCount = pus.mLaunchCount;
                 }
-                retArr[i] = new PkgUsageStats(pkg, launchCount, usageTime, entry.getValue());
-                i++;
+                retArr[i] = new PkgUsageStats(pkg, launchCount, usageTime,
+                        mLastResumeTimes.valueAt(i));
             }
             return retArr;
         }
@@ -866,6 +916,11 @@
             }
             File dFile = new File(mDir, file);
             String dateStr = file.substring(FILE_PREFIX.length());
+            if (dateStr.length() > 0 && (dateStr.charAt(0) <= '0' || dateStr.charAt(0) >= '9')) {
+                // If the remainder does not start with a number, it is not a date,
+                // so we should ignore it for purposes here.
+                continue;
+            }
             try {
                 Parcel in = getParcelForFile(dFile);
                 collectDumpInfoFromParcelFLOCK(in, pw, dateStr, isCompactOutput,
@@ -925,29 +980,33 @@
                 sb.append(',');
                 sb.append(pus.mUsageTime);
                 sb.append('\n');
-                final int NC = pus.mLaunchTimes.size();
-                if (NC > 0) {
-                    for (Map.Entry<String, TimeStats> ent : pus.mLaunchTimes.entrySet()) {
-                        sb.append("A:");
-                        String activity = ent.getKey();
-                        if (activity.startsWith(pkgName)) {
-                            sb.append('*');
-                            sb.append(activity.substring(
-                                    pkgName.length(), activity.length()));
-                        } else {
-                            sb.append(activity);
-                        }
-                        TimeStats times = ent.getValue();
-                        sb.append(',');
-                        sb.append(times.count);
-                        for (int i=0; i<NUM_LAUNCH_TIME_BINS; i++) {
-                            sb.append(",");
-                            sb.append(times.times[i]);
-                        }
-                        sb.append('\n');
+                final int NLT = pus.mLaunchTimes.size();
+                for (int i=0; i<NLT; i++) {
+                    sb.append("A:");
+                    String activity = pus.mLaunchTimes.keyAt(i);
+                    sb.append(activity);
+                    TimeStats times = pus.mLaunchTimes.valueAt(i);
+                    sb.append(',');
+                    sb.append(times.count);
+                    for (int j=0; j<NUM_LAUNCH_TIME_BINS; j++) {
+                        sb.append(",");
+                        sb.append(times.times[j]);
                     }
+                    sb.append('\n');
                 }
-                
+                final int NFDT = pus.mFullyDrawnTimes.size();
+                for (int i=0; i<NFDT; i++) {
+                    sb.append("A:");
+                    String activity = pus.mFullyDrawnTimes.keyAt(i);
+                    sb.append(activity);
+                    TimeStats times = pus.mFullyDrawnTimes.valueAt(i);
+                    for (int j=0; j<NUM_LAUNCH_TIME_BINS; j++) {
+                        sb.append(",");
+                        sb.append(times.times[j]);
+                    }
+                    sb.append('\n');
+                }
+
             } else {
                 sb.append("  ");
                 sb.append(pkgName);
@@ -957,36 +1016,68 @@
                 sb.append(pus.mUsageTime);
                 sb.append(" ms");
                 sb.append('\n');
-                final int NC = pus.mLaunchTimes.size();
-                if (NC > 0) {
-                    for (Map.Entry<String, TimeStats> ent : pus.mLaunchTimes.entrySet()) {
-                        sb.append("    ");
-                        sb.append(ent.getKey());
-                        TimeStats times = ent.getValue();
-                        sb.append(": ");
-                        sb.append(times.count);
-                        sb.append(" starts");
-                        int lastBin = 0;
-                        for (int i=0; i<NUM_LAUNCH_TIME_BINS-1; i++) {
-                            if (times.times[i] != 0) {
-                                sb.append(", ");
-                                sb.append(lastBin);
-                                sb.append('-');
-                                sb.append(LAUNCH_TIME_BINS[i]);
-                                sb.append("ms=");
-                                sb.append(times.times[i]);
-                            }
-                            lastBin = LAUNCH_TIME_BINS[i];
-                        }
-                        if (times.times[NUM_LAUNCH_TIME_BINS-1] != 0) {
+                final int NLT = pus.mLaunchTimes.size();
+                for (int i=0; i<NLT; i++) {
+                    sb.append("    ");
+                    sb.append(pus.mLaunchTimes.keyAt(i));
+                    TimeStats times = pus.mLaunchTimes.valueAt(i);
+                    sb.append(": ");
+                    sb.append(times.count);
+                    sb.append(" starts");
+                    int lastBin = 0;
+                    for (int j=0; j<NUM_LAUNCH_TIME_BINS-1; j++) {
+                        if (times.times[j] != 0) {
                             sb.append(", ");
-                            sb.append(">=");
                             sb.append(lastBin);
+                            sb.append('-');
+                            sb.append(LAUNCH_TIME_BINS[j]);
                             sb.append("ms=");
-                            sb.append(times.times[NUM_LAUNCH_TIME_BINS-1]);
+                            sb.append(times.times[j]);
                         }
-                        sb.append('\n');
+                        lastBin = LAUNCH_TIME_BINS[j];
                     }
+                    if (times.times[NUM_LAUNCH_TIME_BINS-1] != 0) {
+                        sb.append(", ");
+                        sb.append(">=");
+                        sb.append(lastBin);
+                        sb.append("ms=");
+                        sb.append(times.times[NUM_LAUNCH_TIME_BINS-1]);
+                    }
+                    sb.append('\n');
+                }
+                final int NFDT = pus.mFullyDrawnTimes.size();
+                for (int i=0; i<NFDT; i++) {
+                    sb.append("    ");
+                    sb.append(pus.mFullyDrawnTimes.keyAt(i));
+                    TimeStats times = pus.mFullyDrawnTimes.valueAt(i);
+                    sb.append(": fully drawn ");
+                    boolean needComma = false;
+                    int lastBin = 0;
+                    for (int j=0; j<NUM_LAUNCH_TIME_BINS-1; j++) {
+                        if (times.times[j] != 0) {
+                            if (needComma) {
+                                sb.append(", ");
+                            } else {
+                                needComma = true;
+                            }
+                            sb.append(lastBin);
+                            sb.append('-');
+                            sb.append(LAUNCH_TIME_BINS[j]);
+                            sb.append("ms=");
+                            sb.append(times.times[j]);
+                        }
+                        lastBin = LAUNCH_TIME_BINS[j];
+                    }
+                    if (times.times[NUM_LAUNCH_TIME_BINS-1] != 0) {
+                        if (needComma) {
+                            sb.append(", ");
+                        }
+                        sb.append(">=");
+                        sb.append(lastBin);
+                        sb.append("ms=");
+                        sb.append(times.times[NUM_LAUNCH_TIME_BINS-1]);
+                    }
+                    sb.append('\n');
                 }
             }
             
diff --git a/services/java/com/android/server/am/UserStartedState.java b/services/java/com/android/server/am/UserStartedState.java
index 0e71f81..d3e73d5 100644
--- a/services/java/com/android/server/am/UserStartedState.java
+++ b/services/java/com/android/server/am/UserStartedState.java
@@ -22,7 +22,7 @@
 import android.app.IStopUserCallback;
 import android.os.UserHandle;
 
-public class UserStartedState {
+public final class UserStartedState {
     // User is first coming up.
     public final static int STATE_BOOTING = 0;
     // User is in the normal running state.
diff --git a/services/java/com/android/server/connectivity/DataConnectionStats.java b/services/java/com/android/server/connectivity/DataConnectionStats.java
new file mode 100644
index 0000000..227ab23
--- /dev/null
+++ b/services/java/com/android/server/connectivity/DataConnectionStats.java
@@ -0,0 +1,154 @@
+/*
+ * 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.server.connectivity;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.ConnectivityManager;
+import android.os.RemoteException;
+import android.telephony.PhoneStateListener;
+import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+
+import com.android.internal.app.IBatteryStats;
+import com.android.internal.telephony.IccCardConstants;
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.server.am.BatteryStatsService;
+
+public class DataConnectionStats extends BroadcastReceiver {
+    private static final String TAG = "DataConnectionStats";
+    private static final boolean DEBUG = false;
+
+    private final Context mContext;
+    private final IBatteryStats mBatteryStats;
+
+    private IccCardConstants.State mSimState = IccCardConstants.State.READY;
+    private SignalStrength mSignalStrength;
+    private ServiceState mServiceState;
+    private int mDataState = TelephonyManager.DATA_DISCONNECTED;
+
+    public DataConnectionStats(Context context) {
+        mContext = context;
+        mBatteryStats = BatteryStatsService.getService();
+    }
+
+    public void startMonitoring() {
+        TelephonyManager phone =
+                (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE);
+        phone.listen(mPhoneStateListener,
+                PhoneStateListener.LISTEN_SERVICE_STATE
+              | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
+              | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
+              | PhoneStateListener.LISTEN_DATA_ACTIVITY);
+
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
+        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+        filter.addAction(ConnectivityManager.INET_CONDITION_ACTION);
+        mContext.registerReceiver(this, filter);
+    }
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        final String action = intent.getAction();
+        if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
+            updateSimState(intent);
+            notePhoneDataConnectionState();
+        } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION) ||
+                action.equals(ConnectivityManager.INET_CONDITION_ACTION)) {
+            notePhoneDataConnectionState();
+       }
+    }
+
+    private void notePhoneDataConnectionState() {
+        if (mServiceState == null) {
+            return;
+        }
+        boolean simReadyOrUnknown = mSimState == IccCardConstants.State.READY
+                || mSimState == IccCardConstants.State.UNKNOWN;
+        boolean visible = (simReadyOrUnknown || isCdma()) // we only check the sim state for GSM
+                && hasService()
+                && mDataState == TelephonyManager.DATA_CONNECTED;
+        int networkType = mServiceState.getDataNetworkType();
+        if (DEBUG) Log.d(TAG, String.format("Noting data connection for network type %s: %svisible",
+                networkType, visible ? "" : "not "));
+        try {
+            mBatteryStats.notePhoneDataConnectionState(networkType, visible);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Error noting data connection state", e);
+        }
+    }
+
+    private final void updateSimState(Intent intent) {
+        String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
+        if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
+            mSimState = IccCardConstants.State.ABSENT;
+        } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
+            mSimState = IccCardConstants.State.READY;
+        } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
+            final String lockedReason =
+                    intent.getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
+            if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
+                mSimState = IccCardConstants.State.PIN_REQUIRED;
+            } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
+                mSimState = IccCardConstants.State.PUK_REQUIRED;
+            } else {
+                mSimState = IccCardConstants.State.NETWORK_LOCKED;
+            }
+        } else {
+            mSimState = IccCardConstants.State.UNKNOWN;
+        }
+    }
+
+    private boolean isCdma() {
+        return mSignalStrength != null && !mSignalStrength.isGsm();
+    }
+
+    private boolean hasService() {
+        return mServiceState != null
+                && mServiceState.getState() != ServiceState.STATE_OUT_OF_SERVICE
+                && mServiceState.getState() != ServiceState.STATE_POWER_OFF;
+    }
+
+    private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
+        @Override
+        public void onSignalStrengthsChanged(SignalStrength signalStrength) {
+            mSignalStrength = signalStrength;
+        }
+
+        @Override
+        public void onServiceStateChanged(ServiceState state) {
+            mServiceState = state;
+            notePhoneDataConnectionState();
+        }
+
+        @Override
+        public void onDataConnectionStateChanged(int state, int networkType) {
+            mDataState = state;
+            notePhoneDataConnectionState();
+        }
+
+        @Override
+        public void onDataActivity(int direction) {
+            notePhoneDataConnectionState();
+        }
+    };
+}
diff --git a/services/java/com/android/server/connectivity/PacManager.java b/services/java/com/android/server/connectivity/PacManager.java
new file mode 100644
index 0000000..772921a
--- /dev/null
+++ b/services/java/com/android/server/connectivity/PacManager.java
@@ -0,0 +1,353 @@
+/**
+ * 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.server.connectivity;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+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.ServiceConnection;
+import android.net.Proxy;
+import android.net.ProxyProperties;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.net.IProxyCallback;
+import com.android.net.IProxyPortListener;
+import com.android.net.IProxyService;
+import com.android.server.IoThread;
+
+import libcore.io.Streams;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+
+/**
+ * @hide
+ */
+public class PacManager {
+    public static final String PAC_PACKAGE = "com.android.pacprocessor";
+    public static final String PAC_SERVICE = "com.android.pacprocessor.PacService";
+    public static final String PAC_SERVICE_NAME = "com.android.net.IProxyService";
+
+    public static final String PROXY_PACKAGE = "com.android.proxyhandler";
+    public static final String PROXY_SERVICE = "com.android.proxyhandler.ProxyService";
+
+    private static final String TAG = "PacManager";
+
+    private static final String ACTION_PAC_REFRESH = "android.net.proxy.PAC_REFRESH";
+
+    private static final String DEFAULT_DELAYS = "8 32 120 14400 43200";
+    private static final int DELAY_1 = 0;
+    private static final int DELAY_4 = 3;
+    private static final int DELAY_LONG = 4;
+
+    /** Keep these values up-to-date with ProxyService.java */
+    public static final String KEY_PROXY = "keyProxy";
+    private String mCurrentPac;
+    @GuardedBy("mProxyLock")
+    private String mPacUrl;
+
+    private AlarmManager mAlarmManager;
+    @GuardedBy("mProxyLock")
+    private IProxyService mProxyService;
+    private PendingIntent mPacRefreshIntent;
+    private ServiceConnection mConnection;
+    private ServiceConnection mProxyConnection;
+    private Context mContext;
+
+    private int mCurrentDelay;
+    private int mLastPort;
+
+    /**
+     * Used for locking when setting mProxyService and all references to mPacUrl or mCurrentPac.
+     */
+    private final Object mProxyLock = new Object();
+
+    private Runnable mPacDownloader = new Runnable() {
+        @Override
+        public void run() {
+            String file;
+            synchronized (mProxyLock) {
+                if (mPacUrl == null) return;
+                try {
+                    file = get(mPacUrl);
+                } catch (IOException ioe) {
+                    file = null;
+                    Log.w(TAG, "Failed to load PAC file: " + ioe);
+                }
+            }
+            if (file != null) {
+                synchronized (mProxyLock) {
+                    if (!file.equals(mCurrentPac)) {
+                        setCurrentProxyScript(file);
+                    }
+                }
+                longSchedule();
+            } else {
+                reschedule();
+            }
+        }
+    };
+
+    class PacRefreshIntentReceiver extends BroadcastReceiver {
+        public void onReceive(Context context, Intent intent) {
+            IoThread.getHandler().post(mPacDownloader);
+        }
+    }
+
+    public PacManager(Context context) {
+        mContext = context;
+        mLastPort = -1;
+
+        mPacRefreshIntent = PendingIntent.getBroadcast(
+                context, 0, new Intent(ACTION_PAC_REFRESH), 0);
+        context.registerReceiver(new PacRefreshIntentReceiver(),
+                new IntentFilter(ACTION_PAC_REFRESH));
+    }
+
+    private AlarmManager getAlarmManager() {
+        if (mAlarmManager == null) {
+            mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
+        }
+        return mAlarmManager;
+    }
+
+    /**
+     * Updates the PAC Manager with current Proxy information. This is called by
+     * the ConnectivityService directly before a broadcast takes place to allow
+     * the PacManager to indicate that the broadcast should not be sent and the
+     * PacManager will trigger a new broadcast when it is ready.
+     *
+     * @param proxy Proxy information that is about to be broadcast.
+     * @return Returns true when the broadcast should not be sent
+     */
+    public synchronized boolean setCurrentProxyScriptUrl(ProxyProperties proxy) {
+        if (!TextUtils.isEmpty(proxy.getPacFileUrl())) {
+            synchronized (mProxyLock) {
+                mPacUrl = proxy.getPacFileUrl();
+            }
+            mCurrentDelay = DELAY_1;
+            getAlarmManager().cancel(mPacRefreshIntent);
+            bind();
+            return true;
+        } else {
+            getAlarmManager().cancel(mPacRefreshIntent);
+            synchronized (mProxyLock) {
+                mPacUrl = null;
+                mCurrentPac = null;
+                if (mProxyService != null) {
+                    try {
+                        mProxyService.stopPacSystem();
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "Failed to stop PAC service", e);
+                    } finally {
+                        unbind();
+                    }
+                }
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Does a post and reports back the status code.
+     *
+     * @throws IOException
+     */
+    private static String get(String urlString) throws IOException {
+        URL url = new URL(urlString);
+        URLConnection urlConnection = url.openConnection(java.net.Proxy.NO_PROXY);
+        return new String(Streams.readFully(urlConnection.getInputStream()));
+    }
+
+    private int getNextDelay(int currentDelay) {
+       if (++currentDelay > DELAY_4) {
+           return DELAY_4;
+       }
+       return currentDelay;
+    }
+
+    private void longSchedule() {
+        mCurrentDelay = DELAY_1;
+        setDownloadIn(DELAY_LONG);
+    }
+
+    private void reschedule() {
+        mCurrentDelay = getNextDelay(mCurrentDelay);
+        setDownloadIn(mCurrentDelay);
+    }
+
+    private String getPacChangeDelay() {
+        final ContentResolver cr = mContext.getContentResolver();
+
+        /** Check system properties for the default value then use secure settings value, if any. */
+        String defaultDelay = SystemProperties.get(
+                "conn." + Settings.Global.PAC_CHANGE_DELAY,
+                DEFAULT_DELAYS);
+        String val = Settings.Global.getString(cr, Settings.Global.PAC_CHANGE_DELAY);
+        return (val == null) ? defaultDelay : val;
+    }
+
+    private long getDownloadDelay(int delayIndex) {
+        String[] list = getPacChangeDelay().split(" ");
+        if (delayIndex < list.length) {
+            return Long.parseLong(list[delayIndex]);
+        }
+        return 0;
+    }
+
+    private void setDownloadIn(int delayIndex) {
+        long delay = getDownloadDelay(delayIndex);
+        long timeTillTrigger = 1000 * delay + SystemClock.elapsedRealtime();
+        getAlarmManager().set(AlarmManager.ELAPSED_REALTIME, timeTillTrigger, mPacRefreshIntent);
+    }
+
+    private boolean setCurrentProxyScript(String script) {
+        if (mProxyService == null) {
+            Log.e(TAG, "setCurrentProxyScript: no proxy service");
+            return false;
+        }
+        try {
+            mProxyService.setPacFile(script);
+            mCurrentPac = script;
+        } catch (RemoteException e) {
+            Log.e(TAG, "Unable to set PAC file", e);
+        }
+        return true;
+    }
+
+    private void bind() {
+        if (mContext == null) {
+            Log.e(TAG, "No context for binding");
+            return;
+        }
+        Intent intent = new Intent();
+        intent.setClassName(PAC_PACKAGE, PAC_SERVICE);
+        // Already bound no need to bind again.
+        if (mProxyConnection != null) {
+            if (mLastPort != -1) {
+                sendPacBroadcast(new ProxyProperties(mPacUrl, mLastPort));
+            } else {
+                Log.e(TAG, "Received invalid port from Local Proxy,"
+                        + " PAC will not be operational");
+            }
+            return;
+        }
+        mConnection = new ServiceConnection() {
+            @Override
+            public void onServiceDisconnected(ComponentName component) {
+                synchronized (mProxyLock) {
+                    mProxyService = null;
+                }
+            }
+
+            @Override
+            public void onServiceConnected(ComponentName component, IBinder binder) {
+                synchronized (mProxyLock) {
+                    try {
+                        Log.d(TAG, "Adding service " + PAC_SERVICE_NAME + " "
+                                + binder.getInterfaceDescriptor());
+                    } catch (RemoteException e1) {
+                        Log.e(TAG, "Remote Exception", e1);
+                    }
+                    ServiceManager.addService(PAC_SERVICE_NAME, binder);
+                    mProxyService = IProxyService.Stub.asInterface(binder);
+                    if (mProxyService == null) {
+                        Log.e(TAG, "No proxy service");
+                    } else {
+                        try {
+                            mProxyService.startPacSystem();
+                        } catch (RemoteException e) {
+                            Log.e(TAG, "Unable to reach ProxyService - PAC will not be started", e);
+                        }
+                        IoThread.getHandler().post(mPacDownloader);
+                    }
+                }
+            }
+        };
+        mContext.bindService(intent, mConnection,
+                Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND | Context.BIND_NOT_VISIBLE);
+
+        intent = new Intent();
+        intent.setClassName(PROXY_PACKAGE, PROXY_SERVICE);
+        mProxyConnection = new ServiceConnection() {
+            @Override
+            public void onServiceDisconnected(ComponentName component) {
+            }
+
+            @Override
+            public void onServiceConnected(ComponentName component, IBinder binder) {
+                IProxyCallback callbackService = IProxyCallback.Stub.asInterface(binder);
+                if (callbackService != null) {
+                    try {
+                        callbackService.getProxyPort(new IProxyPortListener.Stub() {
+                            @Override
+                            public void setProxyPort(int port) throws RemoteException {
+                                mLastPort = port;
+                                if (port != -1) {
+                                    Log.d(TAG, "Local proxy is bound on " + port);
+                                    sendPacBroadcast(new ProxyProperties(mPacUrl, port));
+                                } else {
+                                    Log.e(TAG, "Received invalid port from Local Proxy,"
+                                            + " PAC will not be operational");
+                                }
+                            }
+                        });
+                    } catch (RemoteException e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        };
+        mContext.bindService(intent, mProxyConnection,
+                Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND | Context.BIND_NOT_VISIBLE);
+    }
+
+    private void unbind() {
+        mContext.unbindService(mConnection);
+        mContext.unbindService(mProxyConnection);
+        mConnection = null;
+        mProxyConnection = null;
+    }
+
+    private void sendPacBroadcast(ProxyProperties proxy) {
+        Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
+        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING |
+            Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+        intent.putExtra(Proxy.EXTRA_PROXY_INFO, proxy);
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+}
diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java
index b83d885..231a40a 100644
--- a/services/java/com/android/server/connectivity/Tethering.java
+++ b/services/java/com/android/server/connectivity/Tethering.java
@@ -37,13 +37,10 @@
 import android.net.NetworkUtils;
 import android.net.RouteInfo;
 import android.os.Binder;
-import android.os.HandlerThread;
-import android.os.IBinder;
 import android.os.INetworkManagementService;
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.Log;
@@ -53,6 +50,7 @@
 import com.android.internal.util.IState;
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
+import com.android.server.IoThread;
 import com.google.android.collect.Lists;
 
 import java.io.FileDescriptor;
@@ -100,7 +98,6 @@
     private final INetworkStatsService mStatsService;
     private final IConnectivityManager mConnService;
     private Looper mLooper;
-    private HandlerThread mThread;
 
     private HashMap<String, TetherInterfaceSM> mIfaces; // all tethered/tetherable ifaces
 
@@ -147,9 +144,7 @@
         mIfaces = new HashMap<String, TetherInterfaceSM>();
 
         // make our own thread so we don't anr the system
-        mThread = new HandlerThread("Tethering");
-        mThread.start();
-        mLooper = mThread.getLooper();
+        mLooper = IoThread.get().getLooper();
         mTetherMasterSM = new TetherMasterSM("TetherMaster", mLooper);
         mTetherMasterSM.start();
 
@@ -320,6 +315,10 @@
         }
     }
 
+    public void addressUpdated(String address, String iface, int flags, int scope) {}
+
+    public void addressRemoved(String address, String iface, int flags, int scope) {}
+
     public void limitReached(String limitName, String iface) {}
 
     public void interfaceClassDataActivityChanged(String label, boolean active) {}
@@ -689,19 +688,6 @@
         return retVal;
     }
 
-    public String[] getTetheredIfacePairs() {
-        final ArrayList<String> list = Lists.newArrayList();
-        synchronized (mPublicSync) {
-            for (TetherInterfaceSM sm : mIfaces.values()) {
-                if (sm.isTethered()) {
-                    list.add(sm.mMyUpstreamIfaceName);
-                    list.add(sm.mIfaceName);
-                }
-            }
-        }
-        return list.toArray(new String[list.size()]);
-    }
-
     public String[] getTetherableIfaces() {
         ArrayList<String> list = new ArrayList<String>();
         synchronized (mPublicSync) {
diff --git a/services/java/com/android/server/connectivity/Vpn.java b/services/java/com/android/server/connectivity/Vpn.java
index 63d3958..8cc5b4f 100644
--- a/services/java/com/android/server/connectivity/Vpn.java
+++ b/services/java/com/android/server/connectivity/Vpn.java
@@ -18,6 +18,7 @@
 
 import static android.Manifest.permission.BIND_VPN_SERVICE;
 
+import android.app.AppGlobals;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
@@ -28,8 +29,10 @@
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.content.pm.UserInfo;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.drawable.Drawable;
@@ -37,6 +40,7 @@
 import android.net.ConnectivityManager;
 import android.net.IConnectivityManager;
 import android.net.INetworkManagementEventObserver;
+import android.net.LinkAddress;
 import android.net.LinkProperties;
 import android.net.LocalSocket;
 import android.net.LocalSocketAddress;
@@ -54,11 +58,14 @@
 import android.os.SystemClock;
 import android.os.SystemService;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.security.Credentials;
 import android.security.KeyStore;
 import android.util.Log;
+import android.util.SparseBooleanArray;
 import android.widget.Toast;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.R;
 import com.android.internal.net.LegacyVpnInfo;
 import com.android.internal.net.VpnConfig;
@@ -74,6 +81,7 @@
 import java.net.InetAddress;
 import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
+import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import libcore.io.IoUtils;
@@ -98,20 +106,53 @@
     private volatile boolean mEnableNotif = true;
     private volatile boolean mEnableTeardown = true;
     private final IConnectivityManager mConnService;
+    private VpnConfig mConfig;
+
+    /* list of users using this VPN. */
+    @GuardedBy("this")
+    private SparseBooleanArray mVpnUsers = null;
+    private BroadcastReceiver mUserIntentReceiver = null;
+
+    private final int mUserId;
 
     public Vpn(Context context, VpnCallback callback, INetworkManagementService netService,
-            IConnectivityManager connService) {
+            IConnectivityManager connService, int userId) {
         // TODO: create dedicated TYPE_VPN network type
         super(ConnectivityManager.TYPE_DUMMY);
         mContext = context;
         mCallback = callback;
         mConnService = connService;
+        mUserId = userId;
 
         try {
             netService.registerObserver(mObserver);
         } catch (RemoteException e) {
             Log.wtf(TAG, "Problem registering observer", e);
         }
+        if (userId == UserHandle.USER_OWNER) {
+            // Owner's VPN also needs to handle restricted users
+            mUserIntentReceiver = new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    final String action = intent.getAction();
+                    final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
+                            UserHandle.USER_NULL);
+                    if (userId == UserHandle.USER_NULL) return;
+
+                    if (Intent.ACTION_USER_ADDED.equals(action)) {
+                        onUserAdded(userId);
+                    } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
+                        onUserRemoved(userId);
+                    }
+                }
+            };
+
+            IntentFilter intentFilter = new IntentFilter();
+            intentFilter.addAction(Intent.ACTION_USER_ADDED);
+            intentFilter.addAction(Intent.ACTION_USER_REMOVED);
+            mContext.registerReceiverAsUser(
+                    mUserIntentReceiver, UserHandle.ALL, intentFilter, null, null);
+        }
     }
 
     /**
@@ -197,15 +238,23 @@
 
         // Reset the interface and hide the notification.
         if (mInterface != null) {
-            jniReset(mInterface);
             final long token = Binder.clearCallingIdentity();
             try {
                 mCallback.restore();
-                hideNotification();
+                final int size = mVpnUsers.size();
+                for (int i = 0; i < size; i++) {
+                    int user = mVpnUsers.keyAt(i);
+                    mCallback.clearUserForwarding(mInterface, user);
+                    hideNotification(user);
+                }
+
+                mCallback.clearMarkedForwarding(mInterface);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
+            jniReset(mInterface);
             mInterface = null;
+            mVpnUsers = null;
         }
 
         // Revoke the connection or stop LegacyVpnRunner.
@@ -225,6 +274,7 @@
 
         Log.i(TAG, "Switched from " + mPackage + " to " + newPackage);
         mPackage = newPackage;
+        mConfig = null;
         updateState(DetailedState.IDLE, "prepare");
         return true;
     }
@@ -237,12 +287,22 @@
      * @param interfaze The name of the interface.
      */
     public void protect(ParcelFileDescriptor socket, String interfaze) throws Exception {
+
         PackageManager pm = mContext.getPackageManager();
-        ApplicationInfo app = pm.getApplicationInfo(mPackage, 0);
-        if (Binder.getCallingUid() != app.uid) {
+        int appUid = pm.getPackageUid(mPackage, mUserId);
+        if (Binder.getCallingUid() != appUid) {
             throw new SecurityException("Unauthorized Caller");
         }
+        // protect the socket from routing rules
+        final long token = Binder.clearCallingIdentity();
+        try {
+            mCallback.protect(socket);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+        // bind the socket to the interface
         jniProtect(socket.getFd(), interfaze);
+
     }
 
     /**
@@ -255,44 +315,40 @@
      */
     public synchronized ParcelFileDescriptor establish(VpnConfig config) {
         // Check if the caller is already prepared.
+        UserManager mgr = UserManager.get(mContext);
         PackageManager pm = mContext.getPackageManager();
         ApplicationInfo app = null;
         try {
-            app = pm.getApplicationInfo(mPackage, 0);
+            app = AppGlobals.getPackageManager().getApplicationInfo(mPackage, 0, mUserId);
+            if (Binder.getCallingUid() != app.uid) {
+                return null;
+            }
         } catch (Exception e) {
             return null;
         }
-        if (Binder.getCallingUid() != app.uid) {
-            return null;
-        }
-
         // Check if the service is properly declared.
         Intent intent = new Intent(VpnConfig.SERVICE_INTERFACE);
         intent.setClassName(mPackage, config.user);
-        ResolveInfo info = pm.resolveService(intent, 0);
-        if (info == null) {
-            throw new SecurityException("Cannot find " + config.user);
-        }
-        if (!BIND_VPN_SERVICE.equals(info.serviceInfo.permission)) {
-            throw new SecurityException(config.user + " does not require " + BIND_VPN_SERVICE);
-        }
+        long token = Binder.clearCallingIdentity();
+        try {
+            // Restricted users are not allowed to create VPNs, they are tied to Owner
+            UserInfo user = mgr.getUserInfo(mUserId);
+            if (user.isRestricted()) {
+                throw new SecurityException("Restricted users cannot establish VPNs");
+            }
 
-        // Load the label.
-        String label = app.loadLabel(pm).toString();
-
-        // Load the icon and convert it into a bitmap.
-        Drawable icon = app.loadIcon(pm);
-        Bitmap bitmap = null;
-        if (icon.getIntrinsicWidth() > 0 && icon.getIntrinsicHeight() > 0) {
-            int width = mContext.getResources().getDimensionPixelSize(
-                    android.R.dimen.notification_large_icon_width);
-            int height = mContext.getResources().getDimensionPixelSize(
-                    android.R.dimen.notification_large_icon_height);
-            icon.setBounds(0, 0, width, height);
-            bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
-            Canvas c = new Canvas(bitmap);
-            icon.draw(c);
-            c.setBitmap(null);
+            ResolveInfo info = AppGlobals.getPackageManager().resolveService(intent,
+                                                                        null, 0, mUserId);
+            if (info == null) {
+                throw new SecurityException("Cannot find " + config.user);
+            }
+            if (!BIND_VPN_SERVICE.equals(info.serviceInfo.permission)) {
+                throw new SecurityException(config.user + " does not require " + BIND_VPN_SERVICE);
+            }
+        } catch (RemoteException e) {
+                throw new SecurityException("Cannot find " + config.user);
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
 
         // Configure the interface. Abort if any of these steps fails.
@@ -300,14 +356,18 @@
         try {
             updateState(DetailedState.CONNECTING, "establish");
             String interfaze = jniGetName(tun.getFd());
-            if (jniSetAddresses(interfaze, config.addresses) < 1) {
+
+            // TEMP use the old jni calls until there is support for netd address setting
+            StringBuilder builder = new StringBuilder();
+            for (LinkAddress address : config.addresses) {
+                builder.append(" " + address);
+            }
+            if (jniSetAddresses(interfaze, builder.toString()) < 1) {
                 throw new IllegalArgumentException("At least one address must be specified");
             }
-            if (config.routes != null) {
-                jniSetRoutes(interfaze, config.routes);
-            }
             Connection connection = new Connection();
-            if (!mContext.bindService(intent, connection, Context.BIND_AUTO_CREATE)) {
+            if (!mContext.bindServiceAsUser(intent, connection, Context.BIND_AUTO_CREATE,
+                        new UserHandle(mUserId))) {
                 throw new IllegalStateException("Cannot bind " + config.user);
             }
             if (mConnection != null) {
@@ -318,30 +378,155 @@
             }
             mConnection = connection;
             mInterface = interfaze;
+
+            // Fill more values.
+            config.user = mPackage;
+            config.interfaze = mInterface;
+            config.startTime = SystemClock.elapsedRealtime();
+            mConfig = config;
+            // Set up forwarding and DNS rules.
+            mVpnUsers = new SparseBooleanArray();
+            token = Binder.clearCallingIdentity();
+            try {
+                mCallback.setMarkedForwarding(mInterface);
+                mCallback.setRoutes(interfaze, config.routes);
+                mCallback.override(mInterface, config.dnsServers, config.searchDomains);
+                addVpnUserLocked(mUserId);
+
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+
         } catch (RuntimeException e) {
             updateState(DetailedState.FAILED, "establish");
             IoUtils.closeQuietly(tun);
+            // make sure marked forwarding is cleared if it was set
+            try {
+                mCallback.clearMarkedForwarding(mInterface);
+            } catch (Exception ingored) {
+                // ignored
+            }
             throw e;
         }
         Log.i(TAG, "Established by " + config.user + " on " + mInterface);
 
-        // Fill more values.
-        config.user = mPackage;
-        config.interfaze = mInterface;
 
-        // Override DNS servers and show the notification.
-        final long token = Binder.clearCallingIdentity();
-        try {
-            mCallback.override(config.dnsServers, config.searchDomains);
-            showNotification(config, label, bitmap);
-        } finally {
-            Binder.restoreCallingIdentity(token);
+        // If we are owner assign all Restricted Users to this VPN
+        if (mUserId == UserHandle.USER_OWNER) {
+            token = Binder.clearCallingIdentity();
+            try {
+                for (UserInfo user : mgr.getUsers()) {
+                    if (user.isRestricted()) {
+                        try {
+                            addVpnUserLocked(user.id);
+                        } catch (Exception e) {
+                            Log.wtf(TAG, "Failed to add user " + user.id + " to owner's VPN");
+                        }
+                    }
+                }
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
         // TODO: ensure that contract class eventually marks as connected
         updateState(DetailedState.AUTHENTICATING, "establish");
         return tun;
     }
 
+    private boolean isRunningLocked() {
+        return mVpnUsers != null;
+    }
+
+    private void addVpnUserLocked(int user) {
+        enforceControlPermission();
+
+        if (!isRunningLocked()) {
+            throw new IllegalStateException("VPN is not active");
+        }
+        // add the user
+        mCallback.addUserForwarding(mInterface, user);
+        mVpnUsers.put(user, true);
+
+        // show the notification
+        if (!mPackage.equals(VpnConfig.LEGACY_VPN)) {
+            // Load everything for the user's notification
+            PackageManager pm = mContext.getPackageManager();
+            ApplicationInfo app = null;
+            try {
+                app = AppGlobals.getPackageManager().getApplicationInfo(mPackage, 0, mUserId);
+            } catch (RemoteException e) {
+                throw new IllegalStateException("Invalid application");
+            }
+            String label = app.loadLabel(pm).toString();
+            // Load the icon and convert it into a bitmap.
+            Drawable icon = app.loadIcon(pm);
+            Bitmap bitmap = null;
+            if (icon.getIntrinsicWidth() > 0 && icon.getIntrinsicHeight() > 0) {
+                int width = mContext.getResources().getDimensionPixelSize(
+                        android.R.dimen.notification_large_icon_width);
+                int height = mContext.getResources().getDimensionPixelSize(
+                        android.R.dimen.notification_large_icon_height);
+                icon.setBounds(0, 0, width, height);
+                bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+                Canvas c = new Canvas(bitmap);
+                icon.draw(c);
+                c.setBitmap(null);
+            }
+            showNotification(label, bitmap, user);
+        } else {
+            showNotification(null, null, user);
+        }
+    }
+
+    private void removeVpnUserLocked(int user) {
+            enforceControlPermission();
+
+            if (!isRunningLocked()) {
+                throw new IllegalStateException("VPN is not active");
+            }
+            mCallback.clearUserForwarding(mInterface, user);
+            mVpnUsers.delete(user);
+            hideNotification(user);
+    }
+
+    private void onUserAdded(int userId) {
+        // If the user is restricted tie them to the owner's VPN
+        synchronized(Vpn.this) {
+            UserManager mgr = UserManager.get(mContext);
+            UserInfo user = mgr.getUserInfo(userId);
+            if (user.isRestricted()) {
+                try {
+                    addVpnUserLocked(userId);
+                } catch (Exception e) {
+                    Log.wtf(TAG, "Failed to add restricted user to owner", e);
+                }
+            }
+        }
+    }
+
+    private void onUserRemoved(int userId) {
+        // clean up if restricted
+        synchronized(Vpn.this) {
+            UserManager mgr = UserManager.get(mContext);
+            UserInfo user = mgr.getUserInfo(userId);
+            if (user.isRestricted()) {
+                try {
+                    removeVpnUserLocked(userId);
+                } catch (Exception e) {
+                    Log.wtf(TAG, "Failed to remove restricted user to owner", e);
+                }
+            }
+        }
+    }
+
+    /**
+     * Return the configuration of the currently running VPN.
+     */
+    public VpnConfig getVpnConfig() {
+        enforceControlPermission();
+        return mConfig;
+    }
+
     @Deprecated
     public synchronized void interfaceStatusChanged(String iface, boolean up) {
         try {
@@ -367,8 +552,16 @@
                 if (interfaze.equals(mInterface) && jniCheck(interfaze) == 0) {
                     final long token = Binder.clearCallingIdentity();
                     try {
+                        final int size = mVpnUsers.size();
+                        for (int i = 0; i < size; i++) {
+                            int user = mVpnUsers.keyAt(i);
+                            mCallback.clearUserForwarding(mInterface, user);
+                            hideNotification(user);
+                        }
+                        mVpnUsers = null;
+                        mCallback.clearMarkedForwarding(mInterface);
+
                         mCallback.restore();
-                        hideNotification();
                     } finally {
                         Binder.restoreCallingIdentity(token);
                     }
@@ -391,16 +584,19 @@
         if (Binder.getCallingUid() == Process.SYSTEM_UID) {
             return;
         }
-
+        int appId = UserHandle.getAppId(Binder.getCallingUid());
+        final long token = Binder.clearCallingIdentity();
         try {
             // System dialogs are also allowed to control VPN.
             PackageManager pm = mContext.getPackageManager();
             ApplicationInfo app = pm.getApplicationInfo(VpnConfig.DIALOGS_PACKAGE, 0);
-            if (Binder.getCallingUid() == app.uid) {
+            if (appId == app.uid) {
                 return;
             }
         } catch (Exception e) {
             // ignore
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
 
         throw new SecurityException("Unauthorized Caller");
@@ -420,9 +616,9 @@
         }
     }
 
-    private void showNotification(VpnConfig config, String label, Bitmap icon) {
+    private void showNotification(String label, Bitmap icon, int user) {
         if (!mEnableNotif) return;
-        mStatusIntent = VpnConfig.getIntentForStatusPanel(mContext, config);
+        mStatusIntent = VpnConfig.getIntentForStatusPanel(mContext);
 
         NotificationManager nm = (NotificationManager)
                 mContext.getSystemService(Context.NOTIFICATION_SERVICE);
@@ -430,9 +626,8 @@
         if (nm != null) {
             String title = (label == null) ? mContext.getString(R.string.vpn_title) :
                     mContext.getString(R.string.vpn_title_long, label);
-            String text = (config.session == null) ? mContext.getString(R.string.vpn_text) :
-                    mContext.getString(R.string.vpn_text_long, config.session);
-            config.startTime = SystemClock.elapsedRealtime();
+            String text = (mConfig.session == null) ? mContext.getString(R.string.vpn_text) :
+                    mContext.getString(R.string.vpn_text_long, mConfig.session);
 
             Notification notification = new Notification.Builder(mContext)
                     .setSmallIcon(R.drawable.vpn_connected)
@@ -443,11 +638,11 @@
                     .setDefaults(0)
                     .setOngoing(true)
                     .build();
-            nm.notifyAsUser(null, R.drawable.vpn_connected, notification, UserHandle.ALL);
+            nm.notifyAsUser(null, R.drawable.vpn_connected, notification, new UserHandle(user));
         }
     }
 
-    private void hideNotification() {
+    private void hideNotification(int user) {
         if (!mEnableNotif) return;
         mStatusIntent = null;
 
@@ -455,7 +650,7 @@
                 mContext.getSystemService(Context.NOTIFICATION_SERVICE);
 
         if (nm != null) {
-            nm.cancelAsUser(null, R.drawable.vpn_connected, UserHandle.ALL);
+            nm.cancelAsUser(null, R.drawable.vpn_connected, new UserHandle(user));
         }
     }
 
@@ -577,7 +772,8 @@
         config.user = profile.key;
         config.interfaze = iface;
         config.session = profile.name;
-        config.routes = profile.routes;
+
+        config.addLegacyRoutes(profile.routes);
         if (!profile.dnsServers.isEmpty()) {
             config.dnsServers = Arrays.asList(profile.dnsServers.split(" +"));
         }
@@ -620,7 +816,7 @@
         if (mLegacyVpnRunner == null) return null;
 
         final LegacyVpnInfo info = new LegacyVpnInfo();
-        info.key = mLegacyVpnRunner.mConfig.user;
+        info.key = mConfig.user;
         info.state = LegacyVpnInfo.stateFromNetworkInfo(mNetworkInfo);
         if (mNetworkInfo.isConnected()) {
             info.intent = mStatusIntent;
@@ -630,7 +826,7 @@
 
     public VpnConfig getLegacyVpnConfig() {
         if (mLegacyVpnRunner != null) {
-            return mLegacyVpnRunner.mConfig;
+            return mConfig;
         } else {
             return null;
         }
@@ -646,7 +842,6 @@
     private class LegacyVpnRunner extends Thread {
         private static final String TAG = "LegacyVpnRunner";
 
-        private final VpnConfig mConfig;
         private final String[] mDaemons;
         private final String[][] mArguments;
         private final LocalSocket[] mSockets;
@@ -691,7 +886,7 @@
             // mConfig.interfaze will change to point to OUR
             // internal interface soon. TODO - add inner/outer to mconfig
             // TODO - we have a race - if the outer iface goes away/disconnects before we hit this
-            // we will leave the VPN up.  We should check that it's still there/connected after 
+            // we will leave the VPN up.  We should check that it's still there/connected after
             // registering
             mOuterInterface = mConfig.interfaze;
 
@@ -867,11 +1062,11 @@
 
                 // Set the interface and the addresses in the config.
                 mConfig.interfaze = parameters[0].trim();
-                mConfig.addresses = parameters[1].trim();
 
+                mConfig.addLegacyAddresses(parameters[1]);
                 // Set the routes if they are not set in the config.
                 if (mConfig.routes == null || mConfig.routes.isEmpty()) {
-                    mConfig.routes = parameters[2].trim();
+                    mConfig.addLegacyRoutes(parameters[2]);
                 }
 
                 // Set the DNS servers if they are not set in the config.
@@ -891,7 +1086,13 @@
                 }
 
                 // Set the routes.
-                jniSetRoutes(mConfig.interfaze, mConfig.routes);
+                long token = Binder.clearCallingIdentity();
+                try {
+                    mCallback.setMarkedForwarding(mConfig.interfaze);
+                    mCallback.setRoutes(mConfig.interfaze, mConfig.routes);
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
 
                 // Here is the last step and it must be done synchronously.
                 synchronized (Vpn.this) {
@@ -905,14 +1106,44 @@
 
                     // Now INetworkManagementEventObserver is watching our back.
                     mInterface = mConfig.interfaze;
-                    mCallback.override(mConfig.dnsServers, mConfig.searchDomains);
-                    showNotification(mConfig, null, null);
+                    mVpnUsers = new SparseBooleanArray();
 
+                    token = Binder.clearCallingIdentity();
+                    try {
+                        mCallback.override(mInterface, mConfig.dnsServers, mConfig.searchDomains);
+                        addVpnUserLocked(mUserId);
+                    } finally {
+                        Binder.restoreCallingIdentity(token);
+                    }
+
+                    // Assign all restircted users to this VPN
+                    // (Legacy VPNs are Owner only)
+                    UserManager mgr = UserManager.get(mContext);
+                    token = Binder.clearCallingIdentity();
+                    try {
+                        for (UserInfo user : mgr.getUsers()) {
+                            if (user.isRestricted()) {
+                                try {
+                                    addVpnUserLocked(user.id);
+                                } catch (Exception e) {
+                                    Log.wtf(TAG, "Failed to add user " + user.id
+                                            + " to owner's VPN");
+                                }
+                            }
+                        }
+                    } finally {
+                        Binder.restoreCallingIdentity(token);
+                    }
                     Log.i(TAG, "Connected!");
                     updateState(DetailedState.CONNECTED, "execute");
                 }
             } catch (Exception e) {
                 Log.i(TAG, "Aborting", e);
+                // make sure the routing is cleared
+                try {
+                    mCallback.clearMarkedForwarding(mConfig.interfaze);
+                } catch (Exception ignored) {
+                }
                 exit();
             } finally {
                 // Kill the daemons if they fail to stop.
diff --git a/services/java/com/android/server/content/ContentService.java b/services/java/com/android/server/content/ContentService.java
index f82cf01..7c82821 100644
--- a/services/java/com/android/server/content/ContentService.java
+++ b/services/java/com/android/server/content/ContentService.java
@@ -26,6 +26,7 @@
 import android.content.PeriodicSync;
 import android.content.SyncAdapterType;
 import android.content.SyncInfo;
+import android.content.SyncRequest;
 import android.content.SyncStatusInfo;
 import android.database.IContentObserver;
 import android.database.sqlite.SQLiteException;
@@ -36,8 +37,10 @@
 import android.os.Parcel;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.util.Log;
+import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseIntArray;
 
@@ -61,6 +64,10 @@
     private final Object mSyncManagerLock = new Object();
 
     private SyncManager getSyncManager() {
+        if (SystemProperties.getBoolean("config.disable_network", false)) {
+            return null;
+        }
+
         synchronized(mSyncManagerLock) {
             try {
                 // Try to create the SyncManager, return null if it fails (e.g. the disk is full).
@@ -307,6 +314,7 @@
         }
     }
 
+    @Override
     public void requestSync(Account account, String authority, Bundle extras) {
         ContentResolver.validateSyncExtrasBundle(extras);
         int userId = UserHandle.getCallingUserId();
@@ -318,7 +326,8 @@
         try {
             SyncManager syncManager = getSyncManager();
             if (syncManager != null) {
-                syncManager.scheduleSync(account, userId, uId, authority, extras, 0 /* no delay */,
+                syncManager.scheduleSync(account, userId, uId, authority, extras,
+                        0 /* no delay */, 0 /* no delay */,
                         false /* onlyThoseWithUnkownSyncableState */);
             }
         } finally {
@@ -327,11 +336,70 @@
     }
 
     /**
+     * Request a sync with a generic {@link android.content.SyncRequest} object. This will be
+     * either:
+     *   periodic OR one-off sync.
+     * and
+     *   anonymous OR provider sync.
+     * Depending on the request, we enqueue to suit in the SyncManager.
+     * @param request
+     */
+    @Override
+    public void sync(SyncRequest request) {
+        Bundle extras = request.getBundle();
+        ContentResolver.validateSyncExtrasBundle(extras);
+
+        long flextime = request.getSyncFlexTime();
+        long runAtTime = request.getSyncRunTime();
+        int userId = UserHandle.getCallingUserId();
+        int uId = Binder.getCallingUid();
+
+        // 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.
+        long identityToken = clearCallingIdentity();
+        try {
+            SyncManager syncManager = getSyncManager();
+            if (syncManager != null) {
+                if (request.hasAuthority()) {
+                    // Sync Adapter registered with the system - old API.
+                    final  Account account = request.getAccount();
+                    final String provider = request.getProvider();
+                    if (request.isPeriodic()) {
+                        mContext.enforceCallingOrSelfPermission(
+                                Manifest.permission.WRITE_SYNC_SETTINGS,
+                                "no permission to write the sync settings");
+                        if (runAtTime < 60) {
+                            Slog.w(TAG, "Requested poll frequency of " + runAtTime
+                                    + " seconds being rounded up to 60 seconds.");
+                            runAtTime = 60;
+                        }
+                        PeriodicSync syncToAdd =
+                                new PeriodicSync(account, provider, extras, runAtTime, flextime);
+                        getSyncManager().getSyncStorageEngine().addPeriodicSync(syncToAdd, userId);
+                    } else {
+                        long beforeRuntimeMillis = (flextime) * 1000;
+                        long runtimeMillis = runAtTime * 1000;
+                        syncManager.scheduleSync(
+                                account, userId, uId, provider, extras,
+                                beforeRuntimeMillis, runtimeMillis,
+                                false /* onlyThoseWithUnknownSyncableState */);
+                    }
+                } else {
+                    Log.w(TAG, "Unrecognised sync parameters, doing nothing.");
+                }
+            }
+        } finally {
+            restoreCallingIdentity(identityToken);
+        }
+    }
+
+    /**
      * Clear all scheduled sync operations that match the uri and cancel the active sync
      * if they match the authority and account, if they are present.
      * @param account filter the pending and active syncs to cancel using this account
      * @param authority filter the pending and active syncs to cancel using this authority
      */
+    @Override
     public void cancelSync(Account account, String authority) {
         int userId = UserHandle.getCallingUserId();
 
@@ -353,6 +421,7 @@
      * Get information about the SyncAdapters that are known to the system.
      * @return an array of SyncAdapters that have registered with the system
      */
+    @Override
     public SyncAdapterType[] getSyncAdapterTypes() {
         // 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.
@@ -366,6 +435,7 @@
         }
     }
 
+    @Override
     public boolean getSyncAutomatically(Account account, String providerName) {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
                 "no permission to read the sync settings");
@@ -384,6 +454,7 @@
         return false;
     }
 
+    @Override
     public void setSyncAutomatically(Account account, String providerName, boolean sync) {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
                 "no permission to write the sync settings");
@@ -401,6 +472,10 @@
         }
     }
 
+    /**
+     * Old API. Schedule periodic sync with default flex time.
+     */
+    @Override
     public void addPeriodicSync(Account account, String authority, Bundle extras,
             long pollFrequency) {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
@@ -415,13 +490,18 @@
 
         long identityToken = clearCallingIdentity();
         try {
-            getSyncManager().getSyncStorageEngine().addPeriodicSync(
-                    account, userId, authority, extras, pollFrequency);
+            // Add default flex time to this sync.
+            PeriodicSync syncToAdd =
+                    new PeriodicSync(account, authority, extras,
+                            pollFrequency,
+                            SyncStorageEngine.calculateDefaultFlexTime(pollFrequency));
+            getSyncManager().getSyncStorageEngine().addPeriodicSync(syncToAdd, userId);
         } finally {
             restoreCallingIdentity(identityToken);
         }
     }
 
+    @Override
     public void removePeriodicSync(Account account, String authority, Bundle extras) {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
                 "no permission to write the sync settings");
@@ -429,13 +509,23 @@
 
         long identityToken = clearCallingIdentity();
         try {
-            getSyncManager().getSyncStorageEngine().removePeriodicSync(account, userId, authority,
-                    extras);
+            PeriodicSync syncToRemove = new PeriodicSync(account, authority, extras,
+                    0 /* Not read for removal */, 0 /* Not read for removal */);
+            getSyncManager().getSyncStorageEngine().removePeriodicSync(syncToRemove, userId);
         } finally {
             restoreCallingIdentity(identityToken);
         }
     }
 
+    /**
+     * TODO: Implement.
+     * @param request Sync to remove.
+     */
+    public void removeSync(SyncRequest request) {
+
+    }
+
+    @Override
     public List<PeriodicSync> getPeriodicSyncs(Account account, String providerName) {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
                 "no permission to read the sync settings");
@@ -468,6 +558,7 @@
         return -1;
     }
 
+    @Override
     public void setIsSyncable(Account account, String providerName, int syncable) {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
                 "no permission to write the sync settings");
@@ -485,6 +576,7 @@
         }
     }
 
+    @Override
     public boolean getMasterSyncAutomatically() {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
                 "no permission to read the sync settings");
@@ -502,6 +594,7 @@
         return false;
     }
 
+    @Override
     public void setMasterSyncAutomatically(boolean flag) {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
                 "no permission to write the sync settings");
diff --git a/services/java/com/android/server/content/SyncManager.java b/services/java/com/android/server/content/SyncManager.java
index ff1281e..9a41166 100644
--- a/services/java/com/android/server/content/SyncManager.java
+++ b/services/java/com/android/server/content/SyncManager.java
@@ -34,6 +34,7 @@
 import android.content.ISyncStatusObserver;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.PeriodicSync;
 import android.content.ServiceConnection;
 import android.content.SyncActivityTooManyDeletes;
 import android.content.SyncAdapterType;
@@ -53,12 +54,10 @@
 import android.net.NetworkInfo;
 import android.os.Bundle;
 import android.os.Handler;
-import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
 import android.os.PowerManager;
-import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.SystemProperties;
@@ -74,18 +73,21 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.accounts.AccountManagerService;
+import com.android.server.content.SyncStorageEngine.AuthorityInfo;
 import com.android.server.content.SyncStorageEngine.OnSyncRequestListener;
 import com.google.android.collect.Lists;
 import com.google.android.collect.Maps;
 import com.google.android.collect.Sets;
 
 import java.io.FileDescriptor;
-import java.io.PrintStream;
 import java.io.PrintWriter;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
@@ -114,7 +116,7 @@
     private static final long MAX_TIME_PER_SYNC;
 
     static {
-        final boolean isLargeRAM = ActivityManager.isLargeRAM();
+        final boolean isLargeRAM = !ActivityManager.isLowRamDeviceStatic();
         int defaultMaxInitSyncs = isLargeRAM ? 5 : 2;
         int defaultMaxRegularSyncs = isLargeRAM ? 2 : 1;
         MAX_SIMULTANEOUS_INITIALIZATION_SYNCS =
@@ -191,6 +193,7 @@
 
     private BroadcastReceiver mStorageIntentReceiver =
             new BroadcastReceiver() {
+                @Override
                 public void onReceive(Context context, Intent intent) {
                     String action = intent.getAction();
                     if (Intent.ACTION_DEVICE_STORAGE_LOW.equals(action)) {
@@ -211,36 +214,39 @@
             };
 
     private BroadcastReceiver mBootCompletedReceiver = new BroadcastReceiver() {
+        @Override
         public void onReceive(Context context, Intent intent) {
             mSyncHandler.onBootCompleted();
         }
     };
 
     private BroadcastReceiver mBackgroundDataSettingChanged = new BroadcastReceiver() {
+        @Override
         public void onReceive(Context context, Intent intent) {
             if (getConnectivityManager().getBackgroundDataSetting()) {
                 scheduleSync(null /* account */, UserHandle.USER_ALL,
                         SyncOperation.REASON_BACKGROUND_DATA_SETTINGS_CHANGED,
                         null /* authority */,
-                        new Bundle(), 0 /* delay */,
+                        new Bundle(), 0 /* delay */, 0 /* delay */,
                         false /* onlyThoseWithUnknownSyncableState */);
             }
         }
     };
 
     private BroadcastReceiver mAccountsUpdatedReceiver = new BroadcastReceiver() {
+        @Override
         public void onReceive(Context context, Intent intent) {
             updateRunningAccounts();
 
             // Kick off sync for everyone, since this was a radical account change
             scheduleSync(null, UserHandle.USER_ALL, SyncOperation.REASON_ACCOUNTS_UPDATED, null,
-                    null, 0 /* no delay */, false);
+                    null, 0 /* no delay */, 0/* no delay */, false);
         }
     };
 
     private final PowerManager mPowerManager;
 
-    // Use this as a random offset to seed all periodic syncs
+    // Use this as a random offset to seed all periodic syncs.
     private int mSyncRandomOffsetMillis;
 
     private final UserManager mUserManager;
@@ -297,6 +303,7 @@
 
     private BroadcastReceiver mConnectivityIntentReceiver =
             new BroadcastReceiver() {
+        @Override
         public void onReceive(Context context, Intent intent) {
             final boolean wasConnected = mDataConnectionIsConnected;
 
@@ -322,6 +329,7 @@
 
     private BroadcastReceiver mShutdownIntentReceiver =
             new BroadcastReceiver() {
+        @Override
         public void onReceive(Context context, Intent intent) {
             Log.w(TAG, "Writing sync state before shutdown...");
             getSyncStorageEngine().writeAllState();
@@ -372,19 +380,20 @@
         SyncStorageEngine.init(context);
         mSyncStorageEngine = SyncStorageEngine.getSingleton();
         mSyncStorageEngine.setOnSyncRequestListener(new OnSyncRequestListener() {
+            @Override
             public void onSyncRequest(Account account, int userId, int reason, String authority,
                     Bundle extras) {
-                scheduleSync(account, userId, reason, authority, extras, 0, false);
+                scheduleSync(account, userId, reason, authority, extras,
+                    0 /* no delay */,
+                    0 /* no delay */,
+                    false);
             }
         });
 
         mSyncAdapters = new SyncAdaptersCache(mContext);
         mSyncQueue = new SyncQueue(mContext.getPackageManager(), mSyncStorageEngine, mSyncAdapters);
 
-        HandlerThread syncThread = new HandlerThread("SyncHandlerThread",
-                Process.THREAD_PRIORITY_BACKGROUND);
-        syncThread.start();
-        mSyncHandler = new SyncHandler(syncThread.getLooper());
+        mSyncHandler = new SyncHandler(BackgroundThread.get().getLooper());
 
         mSyncAdapters.setListener(new RegisteredServicesCacheListener<SyncAdapterType>() {
             @Override
@@ -392,7 +401,7 @@
                 if (!removed) {
                     scheduleSync(null, UserHandle.USER_ALL,
                             SyncOperation.REASON_SERVICE_CHANGED,
-                            type.authority, null, 0 /* no delay */,
+                            type.authority, null, 0 /* no delay */, 0 /* no delay */,
                             false /* onlyThoseWithUnkownSyncableState */);
                 }
             }
@@ -457,6 +466,7 @@
 
         mSyncStorageEngine.addStatusChangeListener(
                 ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, new ISyncStatusObserver.Stub() {
+            @Override
             public void onStatusChanged(int which) {
                 // force the sync loop to run if the settings change
                 sendCheckAlarmsMessage();
@@ -566,22 +576,28 @@
      * @param extras a Map of SyncAdapter-specific information to control
      *          syncs of a specific provider. Can be null. Is ignored
      *          if the url is null.
-     * @param delay how many milliseconds in the future to wait before performing this
-     * @param onlyThoseWithUnkownSyncableState
+     * @param beforeRuntimeMillis milliseconds before runtimeMillis that this sync can run.
+     * @param runtimeMillis maximum milliseconds in the future to wait before performing sync.
+     * @param onlyThoseWithUnkownSyncableState Only sync authorities that have unknown state.
      */
     public void scheduleSync(Account requestedAccount, int userId, int reason,
-            String requestedAuthority, Bundle extras, long delay,
-            boolean onlyThoseWithUnkownSyncableState) {
+            String requestedAuthority, Bundle extras, long beforeRuntimeMillis,
+            long runtimeMillis, boolean onlyThoseWithUnkownSyncableState) {
         boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
 
         final boolean backgroundDataUsageAllowed = !mBootCompleted ||
                 getConnectivityManager().getBackgroundDataSetting();
 
-        if (extras == null) extras = new Bundle();
-
+        if (extras == null) {
+            extras = new Bundle();
+        }
+        if (isLoggable) {
+            Log.d(TAG, "one-time sync for: " + requestedAccount + " " + extras.toString() + " "
+                    + requestedAuthority);
+        }
         Boolean expedited = extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false);
         if (expedited) {
-            delay = -1; // this means schedule at the front of the queue
+            runtimeMillis = -1; // this means schedule at the front of the queue
         }
 
         AccountAndUser[] accounts;
@@ -686,11 +702,13 @@
                         account.userId, authority);
                 final long backoffTime = backoff != null ? backoff.first : 0;
                 if (isSyncable < 0) {
+                    // Initialisation sync.
                     Bundle newExtras = new Bundle();
                     newExtras.putBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, true);
                     if (isLoggable) {
-                        Log.v(TAG, "scheduleSync:"
-                                + " delay " + delay
+                        Log.v(TAG, "schedule initialisation Sync:"
+                                + ", delay until " + delayUntil
+                                + ", run by " + 0
                                 + ", source " + source
                                 + ", account " + account
                                 + ", authority " + authority
@@ -698,13 +716,15 @@
                     }
                     scheduleSyncOperation(
                             new SyncOperation(account.account, account.userId, reason, source,
-                                    authority, newExtras, 0, backoffTime, delayUntil,
-                                    allowParallelSyncs));
+                                    authority, newExtras, 0 /* immediate */, 0 /* No flex time*/,
+                                    backoffTime, delayUntil, allowParallelSyncs));
                 }
                 if (!onlyThoseWithUnkownSyncableState) {
                     if (isLoggable) {
                         Log.v(TAG, "scheduleSync:"
-                                + " delay " + delay
+                                + " delay until " + delayUntil
+                                + " run by " + runtimeMillis
+                                + " flex " + beforeRuntimeMillis
                                 + ", source " + source
                                 + ", account " + account
                                 + ", authority " + authority
@@ -712,17 +732,23 @@
                     }
                     scheduleSyncOperation(
                             new SyncOperation(account.account, account.userId, reason, source,
-                                    authority, extras, delay, backoffTime, delayUntil,
-                                    allowParallelSyncs));
+                                    authority, extras, runtimeMillis, beforeRuntimeMillis,
+                                    backoffTime, delayUntil, allowParallelSyncs));
                 }
             }
         }
     }
 
+    /**
+     * Schedule sync based on local changes to a provider. Occurs within interval
+     * [LOCAL_SYNC_DELAY, 2*LOCAL_SYNC_DELAY].
+     */
     public void scheduleLocalSync(Account account, int userId, int reason, String authority) {
         final Bundle extras = new Bundle();
         extras.putBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, true);
-        scheduleSync(account, userId, reason, authority, extras, LOCAL_SYNC_DELAY,
+        scheduleSync(account, userId, reason, authority, extras,
+                LOCAL_SYNC_DELAY /* earliest run time */,
+                2 * LOCAL_SYNC_DELAY /* latest sync time. */,
                 false /* onlyThoseWithUnkownSyncableState */);
     }
 
@@ -779,6 +805,7 @@
     }
 
     class SyncAlarmIntentReceiver extends BroadcastReceiver {
+        @Override
         public void onReceive(Context context, Intent intent) {
             mHandleAlarmWakeLock.acquire();
             sendSyncAlarmMessage();
@@ -947,11 +974,13 @@
                 Log.d(TAG, "retrying sync operation that failed because there was already a "
                         + "sync in progress: " + operation);
             }
-            scheduleSyncOperation(new SyncOperation(operation.account, operation.userId,
+            scheduleSyncOperation(
+                new SyncOperation(
+                    operation.account, operation.userId,
                     operation.reason,
                     operation.syncSource,
                     operation.authority, operation.extras,
-                    DELAY_RETRY_SYNC_IN_PROGRESS_IN_SECONDS * 1000,
+                    DELAY_RETRY_SYNC_IN_PROGRESS_IN_SECONDS * 1000, operation.flexTime,
                     operation.backoff, operation.delayUntil, operation.allowParallelSyncs));
         } else if (syncResult.hasSoftError()) {
             if (isLoggable) {
@@ -981,7 +1010,8 @@
         final Account[] accounts = AccountManagerService.getSingleton().getAccounts(userId);
         for (Account account : accounts) {
             scheduleSync(account, userId, SyncOperation.REASON_USER_START, null, null,
-                    0 /* no delay */, true /* onlyThoseWithUnknownSyncableState */);
+                    0 /* no delay */, 0 /* No flex */,
+                    true /* onlyThoseWithUnknownSyncableState */);
         }
 
         sendCheckAlarmsMessage();
@@ -1208,7 +1238,10 @@
         synchronized (mSyncQueue) {
             sb.setLength(0);
             mSyncQueue.dump(sb);
+            // Dump Pending Operations.
+            getSyncStorageEngine().dumpPendingOperations(sb);
         }
+
         pw.println();
         pw.print(sb.toString());
 
@@ -1253,10 +1286,11 @@
                     continue;
                 }
                 int row = table.getNumRows();
-                SyncStorageEngine.AuthorityInfo settings =
-                        mSyncStorageEngine.getOrCreateAuthority(
+                Pair<AuthorityInfo, SyncStatusInfo> syncAuthoritySyncStatus = 
+                        mSyncStorageEngine.getCopyOfAuthorityWithSyncStatus(
                                 account.account, account.userId, syncAdapterType.type.authority);
-                SyncStatusInfo status = mSyncStorageEngine.getOrCreateSyncStatus(settings);
+                SyncStorageEngine.AuthorityInfo settings = syncAuthoritySyncStatus.first;
+                SyncStatusInfo status = syncAuthoritySyncStatus.second;
 
                 String authority = settings.authority;
                 if (authority.length() > 50) {
@@ -1274,12 +1308,15 @@
 
 
                 for (int i = 0; i < settings.periodicSyncs.size(); i++) {
-                    final Pair<Bundle, Long> pair = settings.periodicSyncs.get(0);
-                    final String period = String.valueOf(pair.second);
-                    final String extras = pair.first.size() > 0 ? pair.first.toString() : "";
-                    final String next = formatTime(status.getPeriodicSyncTime(0)
-                            + pair.second * 1000);
-                    table.set(row + i * 2, 12, period + extras);
+                    final PeriodicSync sync = settings.periodicSyncs.get(i);
+                    final String period =
+                            String.format("[p:%d s, f: %d s]", sync.period, sync.flexTime);
+                    final String extras =
+                            sync.extras.size() > 0 ?
+                                    sync.extras.toString() : "Bundle[]";
+                    final String next = "Next sync: " + formatTime(status.getPeriodicSyncTime(i)
+                            + sync.period * 1000);
+                    table.set(row + i * 2, 12, period + " " + extras);
                     table.set(row + i * 2 + 1, 12, next);
                 }
 
@@ -1763,7 +1800,8 @@
             final Pair<Account, String> wakeLockKey = Pair.create(account, authority);
             PowerManager.WakeLock wakeLock = mWakeLocks.get(wakeLockKey);
             if (wakeLock == null) {
-                final String name = SYNC_WAKE_LOCK_PREFIX + "_" + authority + "_" + account;
+                final String name = SYNC_WAKE_LOCK_PREFIX + "/" + authority + "/" + account.type
+                        + "/" + account.name;
                 wakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, name);
                 wakeLock.setReferenceCounted(false);
                 mWakeLocks.put(wakeLockKey, wakeLock);
@@ -1812,6 +1850,7 @@
             super(looper);
         }
 
+        @Override
         public void handleMessage(Message msg) {
             long earliestFuturePollTime = Long.MAX_VALUE;
             long nextPendingSyncTime = Long.MAX_VALUE;
@@ -1829,7 +1868,7 @@
                 earliestFuturePollTime = scheduleReadyPeriodicSyncs();
                 switch (msg.what) {
                     case SyncHandler.MESSAGE_CANCEL: {
-                        Pair<Account, String> payload = (Pair<Account, String>)msg.obj;
+                        Pair<Account, String> payload = (Pair<Account, String>) msg.obj;
                         if (Log.isLoggable(TAG, Log.VERBOSE)) {
                             Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_SERVICE_CANCEL: "
                                     + payload.first + ", " + payload.second);
@@ -1936,6 +1975,10 @@
          * in milliseconds since boot
          */
         private long scheduleReadyPeriodicSyncs() {
+            final boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
+            if (isLoggable) {
+                Log.v(TAG, "scheduleReadyPeriodicSyncs");
+            }
             final boolean backgroundDataUsageAllowed =
                     getConnectivityManager().getBackgroundDataSetting();
             long earliestFuturePollTime = Long.MAX_VALUE;
@@ -1947,83 +1990,117 @@
 
             final long nowAbsolute = System.currentTimeMillis();
             final long shiftedNowAbsolute = (0 < nowAbsolute - mSyncRandomOffsetMillis)
-                                               ? (nowAbsolute  - mSyncRandomOffsetMillis) : 0;
+                    ? (nowAbsolute - mSyncRandomOffsetMillis) : 0;
 
-            ArrayList<SyncStorageEngine.AuthorityInfo> infos = mSyncStorageEngine.getAuthorities();
-            for (SyncStorageEngine.AuthorityInfo info : infos) {
-                // skip the sync if the account of this operation no longer exists
-                if (!containsAccountAndUser(accounts, info.account, info.userId)) {
+            ArrayList<Pair<AuthorityInfo, SyncStatusInfo>> infos = mSyncStorageEngine
+                    .getCopyOfAllAuthoritiesWithSyncStatus();
+            for (Pair<AuthorityInfo, SyncStatusInfo> info : infos) {
+                final AuthorityInfo authorityInfo = info.first;
+                final SyncStatusInfo status = info.second;
+                // skip the sync if the account of this operation no longer
+                // exists
+                if (!containsAccountAndUser(
+                        accounts, authorityInfo.account, authorityInfo.userId)) {
                     continue;
                 }
 
-                if (!mSyncStorageEngine.getMasterSyncAutomatically(info.userId)
-                        || !mSyncStorageEngine.getSyncAutomatically(info.account, info.userId,
-                                info.authority)) {
+                if (!mSyncStorageEngine.getMasterSyncAutomatically(authorityInfo.userId)
+                        || !mSyncStorageEngine.getSyncAutomatically(
+                                authorityInfo.account, authorityInfo.userId,
+                                authorityInfo.authority)) {
                     continue;
                 }
 
-                if (getIsSyncable(info.account, info.userId, info.authority)
+                if (getIsSyncable(
+                        authorityInfo.account, authorityInfo.userId, authorityInfo.authority)
                         == 0) {
                     continue;
                 }
 
-                SyncStatusInfo status = mSyncStorageEngine.getOrCreateSyncStatus(info);
-                for (int i = 0, N = info.periodicSyncs.size(); i < N; i++) {
-                    final Bundle extras = info.periodicSyncs.get(i).first;
-                    final Long periodInMillis = info.periodicSyncs.get(i).second * 1000;
-                    // Skip if the period is invalid
+                for (int i = 0, N = authorityInfo.periodicSyncs.size(); i < N; i++) {
+                    final PeriodicSync sync = authorityInfo.periodicSyncs.get(i);
+                    final Bundle extras = sync.extras;
+                    final long periodInMillis = sync.period * 1000;
+                    final long flexInMillis = sync.flexTime * 1000;
+                    // Skip if the period is invalid.
                     if (periodInMillis <= 0) {
                         continue;
                     }
-                    // find when this periodic sync was last scheduled to run
+                    // Find when this periodic sync was last scheduled to run.
                     final long lastPollTimeAbsolute = status.getPeriodicSyncTime(i);
-
                     long remainingMillis
-                            = periodInMillis - (shiftedNowAbsolute % periodInMillis);
-
+                        = periodInMillis - (shiftedNowAbsolute % periodInMillis);
+                    long timeSinceLastRunMillis
+                        = (nowAbsolute - lastPollTimeAbsolute);
+                    // Schedule this periodic sync to run early if it's close enough to its next
+                    // runtime, and far enough from its last run time.
+                    // If we are early, there will still be time remaining in this period.
+                    boolean runEarly = remainingMillis <= flexInMillis
+                            && timeSinceLastRunMillis > periodInMillis - flexInMillis;
+                    if (isLoggable) {
+                        Log.v(TAG, "sync: " + i + " for " + authorityInfo.authority + "."
+                        + " period: " + (periodInMillis)
+                        + " flex: " + (flexInMillis)
+                        + " remaining: " + (remainingMillis)
+                        + " time_since_last: " + timeSinceLastRunMillis
+                        + " last poll absol: " + lastPollTimeAbsolute
+                        + " shifted now: " + shiftedNowAbsolute
+                        + " run_early: " + runEarly);
+                    }
                     /*
-                     * Sync scheduling strategy:
-                     *    Set the next periodic sync based on a random offset (in seconds).
-                     *
-                     *    Also sync right now if any of the following cases hold
-                     *    and mark it as having been scheduled
-                     *
-                     * Case 1:  This sync is ready to run now.
-                     * Case 2:  If the lastPollTimeAbsolute is in the future,
-                     *          sync now and reinitialize. This can happen for
-                     *          example if the user changed the time, synced and
-                     *          changed back.
-                     * Case 3:  If we failed to sync at the last scheduled time
+                     * Sync scheduling strategy: Set the next periodic sync
+                     * based on a random offset (in seconds). Also sync right
+                     * now if any of the following cases hold and mark it as
+                     * having been scheduled
+                     * Case 1: This sync is ready to run now.
+                     * Case 2: If the lastPollTimeAbsolute is in the
+                     * future, sync now and reinitialize. This can happen for
+                     * example if the user changed the time, synced and changed
+                     * back.
+                     * Case 3: If we failed to sync at the last scheduled
+                     * time.
+                     * Case 4: This sync is close enough to the time that we can schedule it.
                      */
-                    if (remainingMillis == periodInMillis  // Case 1
+                    if (runEarly // Case 4
+                            || remainingMillis == periodInMillis // Case 1
                             || lastPollTimeAbsolute > nowAbsolute // Case 2
-                            || (nowAbsolute - lastPollTimeAbsolute
-                                    >= periodInMillis)) { // Case 3
+                            || timeSinceLastRunMillis >= periodInMillis) { // Case 3
                         // Sync now
+                        
                         final Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff(
-                                info.account, info.userId, info.authority);
+                                authorityInfo.account, authorityInfo.userId,
+                                authorityInfo.authority);
                         final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo;
                         syncAdapterInfo = mSyncAdapters.getServiceInfo(
-                                SyncAdapterType.newKey(info.authority, info.account.type),
-                                info.userId);
+                                SyncAdapterType.newKey(
+                                        authorityInfo.authority, authorityInfo.account.type),
+                                authorityInfo.userId);
                         if (syncAdapterInfo == null) {
                             continue;
                         }
+                        mSyncStorageEngine.setPeriodicSyncTime(authorityInfo.ident,
+                                authorityInfo.periodicSyncs.get(i), nowAbsolute);
                         scheduleSyncOperation(
-                                new SyncOperation(info.account, info.userId,
+                                new SyncOperation(authorityInfo.account, authorityInfo.userId,
                                         SyncOperation.REASON_PERIODIC,
                                         SyncStorageEngine.SOURCE_PERIODIC,
-                                        info.authority, extras, 0 /* delay */,
-                                        backoff != null ? backoff.first : 0,
+                                        authorityInfo.authority, extras,
+                                        0 /* runtime */, 0 /* flex */,
+                                                backoff != null ? backoff.first : 0,
                                         mSyncStorageEngine.getDelayUntilTime(
-                                                info.account, info.userId, info.authority),
+                                                authorityInfo.account, authorityInfo.userId,
+                                                authorityInfo.authority),
                                         syncAdapterInfo.type.allowParallelSyncs()));
-                        status.setPeriodicSyncTime(i, nowAbsolute);
+                        
                     }
-                    // Compute when this periodic sync should next run
-                    final long nextPollTimeAbsolute = nowAbsolute + remainingMillis;
-
-                    // remember this time if it is earlier than earliestFuturePollTime
+                    // Compute when this periodic sync should next run.
+                    long nextPollTimeAbsolute;
+                    if (runEarly) {
+                        // Add the time remaining so we don't get out of phase.
+                        nextPollTimeAbsolute = nowAbsolute + periodInMillis + remainingMillis;
+                    } else {
+                        nextPollTimeAbsolute = nowAbsolute + remainingMillis;
+                    }
                     if (nextPollTimeAbsolute < earliestFuturePollTime) {
                         earliestFuturePollTime = nextPollTimeAbsolute;
                     }
@@ -2035,10 +2112,9 @@
             }
 
             // convert absolute time to elapsed time
-            return SystemClock.elapsedRealtime()
-                    + ((earliestFuturePollTime < nowAbsolute)
-                      ? 0
-                      : (earliestFuturePollTime - nowAbsolute));
+            return SystemClock.elapsedRealtime() +
+                ((earliestFuturePollTime < nowAbsolute) ?
+                    0 : (earliestFuturePollTime - nowAbsolute));
         }
 
         private long maybeStartNextSyncLocked() {
@@ -2088,8 +2164,8 @@
                     Log.v(TAG, "build the operation array, syncQueue size is "
                         + mSyncQueue.getOperations().size());
                 }
-                final Iterator<SyncOperation> operationIterator = mSyncQueue.getOperations()
-                        .iterator();
+                final Iterator<SyncOperation> operationIterator =
+                        mSyncQueue.getOperations().iterator();
 
                 final ActivityManager activityManager
                         = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
@@ -2097,40 +2173,61 @@
                 while (operationIterator.hasNext()) {
                     final SyncOperation op = operationIterator.next();
 
-                    // drop the sync if the account of this operation no longer exists
+                    // Drop the sync if the account of this operation no longer exists.
                     if (!containsAccountAndUser(accounts, op.account, op.userId)) {
                         operationIterator.remove();
                         mSyncStorageEngine.deleteFromPending(op.pendingOperation);
+                        if (isLoggable) {
+                            Log.v(TAG, "    Dropping sync operation: account doesn't exist.");
+                        }
                         continue;
                     }
 
-                    // drop this sync request if it isn't syncable
+                    // Drop this sync request if it isn't syncable.
                     int syncableState = getIsSyncable(
                             op.account, op.userId, op.authority);
                     if (syncableState == 0) {
                         operationIterator.remove();
                         mSyncStorageEngine.deleteFromPending(op.pendingOperation);
+                        if (isLoggable) {
+                            Log.v(TAG, "    Dropping sync operation: isSyncable == 0.");
+                        }
                         continue;
                     }
 
-                    // if the user in not running, drop the request
+                    // If the user is not running, drop the request.
                     if (!activityManager.isUserRunning(op.userId)) {
                         final UserInfo userInfo = mUserManager.getUserInfo(op.userId);
                         if (userInfo == null) {
                             removedUsers.add(op.userId);
                         }
-                        continue;
-                    }
-
-                    // if the next run time is in the future, meaning there are no syncs ready
-                    // to run, return the time
-                    if (op.effectiveRunTime > now) {
-                        if (nextReadyToRunTime > op.effectiveRunTime) {
-                            nextReadyToRunTime = op.effectiveRunTime;
+                        if (isLoggable) {
+                            Log.v(TAG, "    Dropping sync operation: user not running.");
                         }
                         continue;
                     }
 
+                    // If the next run time is in the future, even given the flexible scheduling,
+                    // return the time.
+                    if (op.effectiveRunTime - op.flexTime > now) {
+                        if (nextReadyToRunTime > op.effectiveRunTime) {
+                            nextReadyToRunTime = op.effectiveRunTime;
+                        }
+                        if (isLoggable) {
+                            Log.v(TAG, "    Dropping sync operation: Sync too far in future.");
+                        }
+                        continue;
+                    }
+
+                    // If the op isn't allowed on metered networks and we're on one, drop it.
+                    if (getConnectivityManager().isActiveNetworkMetered()
+                            && op.isMeteredDisallowed()) {
+                        operationIterator.remove();
+                        mSyncStorageEngine.deleteFromPending(op.pendingOperation);
+                        continue;
+                    }
+
+                    // TODO: change this behaviour for non-registered syncs.
                     final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo;
                     syncAdapterInfo = mSyncAdapters.getServiceInfo(
                             SyncAdapterType.newKey(op.authority, op.account.type), op.userId);
@@ -2171,7 +2268,7 @@
             }
 
             // find the next operation to dispatch, if one is ready
-            // iterate from the top, keep issuing (while potentially cancelling existing syncs)
+            // iterate from the top, keep issuing (while potentially canceling existing syncs)
             // until the quotas are filled.
             // once the quotas are filled iterate once more to find when the next one would be
             // (also considering pre-emption reasons).
@@ -2451,11 +2548,13 @@
             }
 
             if (syncResult != null && syncResult.fullSyncRequested) {
-                scheduleSyncOperation(new SyncOperation(syncOperation.account, syncOperation.userId,
-                        syncOperation.reason,
-                        syncOperation.syncSource, syncOperation.authority, new Bundle(), 0,
-                        syncOperation.backoff, syncOperation.delayUntil,
-                        syncOperation.allowParallelSyncs));
+                scheduleSyncOperation(
+                        new SyncOperation(syncOperation.account, syncOperation.userId,
+                            syncOperation.reason,
+                            syncOperation.syncSource, syncOperation.authority, new Bundle(),
+                            0 /* delay */, 0 /* flex */,
+                            syncOperation.backoff, syncOperation.delayUntil,
+                            syncOperation.allowParallelSyncs));
             }
             // no need to schedule an alarm, as that will be done by our caller.
         }
@@ -2625,9 +2724,12 @@
             // determine if we need to set or cancel the alarm
             boolean shouldSet = false;
             boolean shouldCancel = false;
-            final boolean alarmIsActive = mAlarmScheduleTime != null;
+            final boolean alarmIsActive = (mAlarmScheduleTime != null) && (now < mAlarmScheduleTime);
             final boolean needAlarm = alarmTime != Long.MAX_VALUE;
             if (needAlarm) {
+                // Need the alarm if
+                //  - it's currently not set
+                //  - if the alarm is set in the past.
                 if (!alarmIsActive || alarmTime < mAlarmScheduleTime) {
                     shouldSet = true;
                 }
@@ -2635,7 +2737,7 @@
                 shouldCancel = alarmIsActive;
             }
 
-            // set or cancel the alarm as directed
+            // Set or cancel the alarm as directed.
             ensureAlarmService();
             if (shouldSet) {
                 if (Log.isLoggable(TAG, Log.VERBOSE)) {
@@ -2644,7 +2746,7 @@
                             + " secs from now");
                 }
                 mAlarmScheduleTime = alarmTime;
-                mAlarmService.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, alarmTime,
+                mAlarmService.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, alarmTime,
                         mSyncAlarmIntent);
             } else if (shouldCancel) {
                 mAlarmScheduleTime = null;
diff --git a/services/java/com/android/server/content/SyncOperation.java b/services/java/com/android/server/content/SyncOperation.java
index eaad982..48567478 100644
--- a/services/java/com/android/server/content/SyncOperation.java
+++ b/services/java/com/android/server/content/SyncOperation.java
@@ -18,13 +18,18 @@
 
 import android.accounts.Account;
 import android.content.pm.PackageManager;
+import android.content.ComponentName;
 import android.content.ContentResolver;
+import android.content.SyncRequest;
 import android.os.Bundle;
 import android.os.SystemClock;
+import android.util.Pair;
 
 /**
  * Value type that represents a sync operation.
- * @hide
+ * TODO: This is the class to flesh out with all the scheduling data - metered/unmetered,
+ * transfer-size, etc.
+ * {@hide}
  */
 public class SyncOperation implements Comparable {
     public static final int REASON_BACKGROUND_DATA_SETTINGS_CHANGED = -1;
@@ -32,7 +37,9 @@
     public static final int REASON_SERVICE_CHANGED = -3;
     public static final int REASON_PERIODIC = -4;
     public static final int REASON_IS_SYNCABLE = -5;
+    /** Sync started because it has just been set to sync automatically. */
     public static final int REASON_SYNC_AUTO = -6;
+    /** Sync started because master sync automatically has been set to true. */
     public static final int REASON_MASTER_SYNC_AUTO = -7;
     public static final int REASON_USER_START = -8;
 
@@ -47,75 +54,109 @@
             "UserStart",
     };
 
+    /** Account info to identify a SyncAdapter registered with the system. */
     public final Account account;
+    /** Authority info to identify a SyncAdapter registered with the system. */
+    public final String authority;
+    /** Service to which this operation will bind to perform the sync. */
+    public final ComponentName service;
     public final int userId;
     public final int reason;
     public int syncSource;
-    public String authority;
     public final boolean allowParallelSyncs;
     public Bundle extras;
     public final String key;
-    public long earliestRunTime;
     public boolean expedited;
     public SyncStorageEngine.PendingOperation pendingOperation;
+    /** Elapsed real time in millis at which to run this sync. */
+    public long latestRunTime;
+    /** Set by the SyncManager in order to delay retries. */
     public Long backoff;
+    /** Specified by the adapter to delay subsequent sync operations. */
     public long delayUntil;
+    /**
+     * Elapsed real time in millis when this sync will be run.
+     * Depends on max(backoff, latestRunTime, and delayUntil).
+     */
     public long effectiveRunTime;
+    /** Amount of time before {@link effectiveRunTime} from which this sync can run. */
+    public long flexTime;
 
     public SyncOperation(Account account, int userId, int reason, int source, String authority,
-            Bundle extras, long delayInMs, long backoff, long delayUntil,
-            boolean allowParallelSyncs) {
+            Bundle extras, long runTimeFromNow, long flexTime, long backoff,
+            long delayUntil, boolean allowParallelSyncs) {
+        this.service = null;
         this.account = account;
+        this.authority = authority;
         this.userId = userId;
         this.reason = reason;
         this.syncSource = source;
-        this.authority = authority;
         this.allowParallelSyncs = allowParallelSyncs;
         this.extras = new Bundle(extras);
-        removeFalseExtra(ContentResolver.SYNC_EXTRAS_UPLOAD);
-        removeFalseExtra(ContentResolver.SYNC_EXTRAS_MANUAL);
-        removeFalseExtra(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS);
-        removeFalseExtra(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF);
-        removeFalseExtra(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY);
-        removeFalseExtra(ContentResolver.SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS);
-        removeFalseExtra(ContentResolver.SYNC_EXTRAS_EXPEDITED);
-        removeFalseExtra(ContentResolver.SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS);
+        cleanBundle(this.extras);
         this.delayUntil = delayUntil;
         this.backoff = backoff;
         final long now = SystemClock.elapsedRealtime();
-        if (delayInMs < 0) {
+        // Checks the extras bundle. Must occur after we set the internal bundle.
+        if (runTimeFromNow < 0 || isExpedited()) {
             this.expedited = true;
-            this.earliestRunTime = now;
+            this.latestRunTime = now;
+            this.flexTime = 0;
         } else {
             this.expedited = false;
-            this.earliestRunTime = now + delayInMs;
+            this.latestRunTime = now + runTimeFromNow;
+            this.flexTime = flexTime;
         }
         updateEffectiveRunTime();
         this.key = toKey();
     }
 
-    private void removeFalseExtra(String extraName) {
-        if (!extras.getBoolean(extraName, false)) {
-            extras.remove(extraName);
+    /**
+     * Make sure the bundle attached to this SyncOperation doesn't have unnecessary
+     * flags set.
+     * @param bundle to clean.
+     */
+    private void cleanBundle(Bundle bundle) {
+        removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_UPLOAD);
+        removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_MANUAL);
+        removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS);
+        removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF);
+        removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY);
+        removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS);
+        removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_EXPEDITED);
+        removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS);
+        removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_DISALLOW_METERED);
+
+        // Remove Config data.
+        bundle.remove(ContentResolver.SYNC_EXTRAS_EXPECTED_UPLOAD);
+        bundle.remove(ContentResolver.SYNC_EXTRAS_EXPECTED_DOWNLOAD);
+    }
+
+    private void removeFalseExtra(Bundle bundle, String extraName) {
+        if (!bundle.getBoolean(extraName, false)) {
+            bundle.remove(extraName);
         }
     }
 
+    /** Only used to immediately reschedule a sync. */
     SyncOperation(SyncOperation other) {
+        this.service = other.service;
         this.account = other.account;
+        this.authority = other.authority;
         this.userId = other.userId;
         this.reason = other.reason;
         this.syncSource = other.syncSource;
-        this.authority = other.authority;
         this.extras = new Bundle(other.extras);
         this.expedited = other.expedited;
-        this.earliestRunTime = SystemClock.elapsedRealtime();
+        this.latestRunTime = SystemClock.elapsedRealtime();
+        this.flexTime = 0L;
         this.backoff = other.backoff;
-        this.delayUntil = other.delayUntil;
         this.allowParallelSyncs = other.allowParallelSyncs;
         this.updateEffectiveRunTime();
         this.key = toKey();
     }
 
+    @Override
     public String toString() {
         return dump(null, true);
     }
@@ -131,8 +172,8 @@
                 .append(authority)
                 .append(", ")
                 .append(SyncStorageEngine.SOURCES[syncSource])
-                .append(", earliestRunTime ")
-                .append(earliestRunTime);
+                .append(", latestRunTime ")
+                .append(latestRunTime);
         if (expedited) {
             sb.append(", EXPEDITED");
         }
@@ -170,23 +211,38 @@
         }
     }
 
+    public boolean isMeteredDisallowed() {
+        return extras.getBoolean(ContentResolver.SYNC_EXTRAS_DISALLOW_METERED, false);
+    }
+
     public boolean isInitialization() {
         return extras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false);
     }
 
     public boolean isExpedited() {
-        return extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false);
+        return extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false) || expedited;
     }
 
     public boolean ignoreBackoff() {
         return extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, false);
     }
 
+    /** Changed in V3. */
     private String toKey() {
         StringBuilder sb = new StringBuilder();
-        sb.append("authority: ").append(authority);
-        sb.append(" account {name=" + account.name + ", user=" + userId + ", type=" + account.type
-                + "}");
+        if (service == null) {
+            sb.append("authority: ").append(authority);
+            sb.append(" account {name=" + account.name + ", user=" + userId + ", type=" + account.type
+                    + "}");
+        } else {
+            sb.append("service {package=" )
+                .append(service.getPackageName())
+                .append(" user=")
+                .append(userId)
+                .append(", class=")
+                .append(service.getClassName())
+                .append("}");
+        }
         sb.append(" extras: ");
         extrasToStringBuilder(extras, sb);
         return sb.toString();
@@ -200,25 +256,39 @@
         sb.append("]");
     }
 
+    /**
+     * Update the effective run time of this Operation based on latestRunTime (specified at
+     * creation time of sync), delayUntil (specified by SyncAdapter), or backoff (specified by
+     * SyncManager on soft failures).
+     */
     public void updateEffectiveRunTime() {
-        effectiveRunTime = ignoreBackoff()
-                ? earliestRunTime
-                : Math.max(
-                    Math.max(earliestRunTime, delayUntil),
-                    backoff);
+        // Regardless of whether we're in backoff or honouring a delayUntil, we still incorporate
+        // the flex time provided by the developer.
+        effectiveRunTime = ignoreBackoff() ?
+                latestRunTime :
+                    Math.max(Math.max(latestRunTime, delayUntil), backoff);
     }
 
+    /**
+     * SyncOperations are sorted based on their earliest effective run time.
+     * This comparator is used to sort the SyncOps at a given time when
+     * deciding which to run, so earliest run time is the best criteria.
+     */
+    @Override
     public int compareTo(Object o) {
-        SyncOperation other = (SyncOperation)o;
-
+        SyncOperation other = (SyncOperation) o;
         if (expedited != other.expedited) {
             return expedited ? -1 : 1;
         }
-
-        if (effectiveRunTime == other.effectiveRunTime) {
+        long thisIntervalStart = Math.max(effectiveRunTime - flexTime, 0);
+        long otherIntervalStart = Math.max(
+            other.effectiveRunTime - other.flexTime, 0);
+        if (thisIntervalStart < otherIntervalStart) {
+            return -1;
+        } else if (otherIntervalStart < thisIntervalStart) {
+            return 1;
+        } else {
             return 0;
         }
-
-        return effectiveRunTime < other.effectiveRunTime ? -1 : 1;
     }
 }
diff --git a/services/java/com/android/server/content/SyncQueue.java b/services/java/com/android/server/content/SyncQueue.java
index 951e92c..6f3fe6e 100644
--- a/services/java/com/android/server/content/SyncQueue.java
+++ b/services/java/com/android/server/content/SyncQueue.java
@@ -73,7 +73,7 @@
             }
             SyncOperation syncOperation = new SyncOperation(
                     op.account, op.userId, op.reason, op.syncSource, op.authority, op.extras,
-                    0 /* delay */, backoff != null ? backoff.first : 0,
+                    0 /* delay */, 0 /* flex */, backoff != null ? backoff.first : 0,
                     mSyncStorageEngine.getDelayUntilTime(op.account, op.userId, op.authority),
                     syncAdapterInfo.type.allowParallelSyncs());
             syncOperation.expedited = op.expedited;
@@ -86,35 +86,40 @@
         return add(operation, null /* this is not coming from the database */);
     }
 
+    /**
+     * Adds a SyncOperation to the queue and creates a PendingOperation object to track that sync.
+     * If an operation is added that already exists, the existing operation is updated if the newly
+     * added operation occurs before (or the interval overlaps).
+     */
     private boolean add(SyncOperation operation,
             SyncStorageEngine.PendingOperation pop) {
-        // - if an operation with the same key exists and this one should run earlier,
-        //   update the earliestRunTime of the existing to the new time
-        // - if an operation with the same key exists and if this one should run
-        //   later, ignore it
-        // - if no operation exists then add the new one
+        // If an operation with the same key exists and this one should run sooner/overlaps,
+        // replace the run interval of the existing operation with this new one.
+        // Complications: what if the existing operation is expedited but the new operation has an
+        // earlier run time? Will not be a problem for periodic syncs (no expedited flag), and for
+        // one-off syncs we only change it if the new sync is sooner.
         final String operationKey = operation.key;
         final SyncOperation existingOperation = mOperationsMap.get(operationKey);
 
         if (existingOperation != null) {
             boolean changed = false;
-            if (existingOperation.expedited == operation.expedited) {
-                final long newRunTime =
-                        Math.min(existingOperation.earliestRunTime, operation.earliestRunTime);
-                if (existingOperation.earliestRunTime != newRunTime) {
-                    existingOperation.earliestRunTime = newRunTime;
-                    changed = true;
-                }
-            } else {
-                if (operation.expedited) {
-                    existingOperation.expedited = true;
-                    changed = true;
-                }
+            if (operation.compareTo(existingOperation) <= 0 ) {
+                existingOperation.expedited = operation.expedited;
+                long newRunTime =
+                        Math.min(existingOperation.latestRunTime, operation.latestRunTime);
+                // Take smaller runtime.
+                existingOperation.latestRunTime = newRunTime;
+                // Take newer flextime.
+                existingOperation.flexTime = operation.flexTime;
+                changed = true;
             }
             return changed;
         }
 
         operation.pendingOperation = pop;
+        // Don't update the PendingOp if one already exists. This really is just a placeholder,
+        // no actual scheduling info is placed here.
+        // TODO: Change this to support service components.
         if (operation.pendingOperation == null) {
             pop = new SyncStorageEngine.PendingOperation(
                     operation.account, operation.userId, operation.reason, operation.syncSource,
diff --git a/services/java/com/android/server/content/SyncStorageEngine.java b/services/java/com/android/server/content/SyncStorageEngine.java
index 5b8d26f..1b9ed98 100644
--- a/services/java/com/android/server/content/SyncStorageEngine.java
+++ b/services/java/com/android/server/content/SyncStorageEngine.java
@@ -18,6 +18,7 @@
 
 import android.accounts.Account;
 import android.accounts.AccountAndUser;
+import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.ISyncStatusObserver;
@@ -52,6 +53,7 @@
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.HashMap;
@@ -70,7 +72,7 @@
 
     private static final String TAG = "SyncManager";
     private static final boolean DEBUG = false;
-    private static final boolean DEBUG_FILE = false;
+    private static final String TAG_FILE = "SyncManagerFile";
 
     private static final String XML_ATTR_NEXT_AUTHORITY_ID = "nextAuthorityId";
     private static final String XML_ATTR_LISTEN_FOR_TICKLES = "listen-for-tickles";
@@ -79,8 +81,15 @@
     private static final String XML_ATTR_USER = "user";
     private static final String XML_TAG_LISTEN_FOR_TICKLES = "listenForTickles";
 
+    /** Default time for a periodic sync. */
     private static final long DEFAULT_POLL_FREQUENCY_SECONDS = 60 * 60 * 24; // One day
 
+    /** Percentage of period that is flex by default, if no flex is set. */
+    private static final double DEFAULT_FLEX_PERCENT_SYNC = 0.04;
+
+    /** Lower bound on sync time from which we assign a default flex time. */
+    private static final long DEFAULT_MIN_FLEX_ALLOWED_SECS = 5;
+
     @VisibleForTesting
     static final long MILLIS_IN_4WEEKS = 1000L * 60 * 60 * 24 * 7 * 4;
 
@@ -153,12 +162,13 @@
         final int syncSource;
         final String authority;
         final Bundle extras;        // note: read-only.
+        final ComponentName serviceName;
         final boolean expedited;
 
         int authorityId;
         byte[] flatExtras;
 
-        PendingOperation(Account account, int userId, int reason,int source,
+        PendingOperation(Account account, int userId, int reason, int source,
                 String authority, Bundle extras, boolean expedited) {
             this.account = account;
             this.userId = userId;
@@ -168,6 +178,7 @@
             this.extras = extras != null ? new Bundle(extras) : extras;
             this.expedited = expedited;
             this.authorityId = -1;
+            this.serviceName = null;
         }
 
         PendingOperation(PendingOperation other) {
@@ -179,6 +190,7 @@
             this.extras = other.extras;
             this.authorityId = other.authorityId;
             this.expedited = other.expedited;
+            this.serviceName = other.serviceName;
         }
     }
 
@@ -193,6 +205,7 @@
     }
 
     public static class AuthorityInfo {
+        final ComponentName service;
         final Account account;
         final int userId;
         final String authority;
@@ -202,7 +215,7 @@
         long backoffTime;
         long backoffDelay;
         long delayUntil;
-        final ArrayList<Pair<Bundle, Long>> periodicSyncs;
+        final ArrayList<PeriodicSync> periodicSyncs;
 
         /**
          * Copy constructor for making deep-ish copies. Only the bundles stored
@@ -214,30 +227,70 @@
             account = toCopy.account;
             userId = toCopy.userId;
             authority = toCopy.authority;
+            service = toCopy.service;
             ident = toCopy.ident;
             enabled = toCopy.enabled;
             syncable = toCopy.syncable;
             backoffTime = toCopy.backoffTime;
             backoffDelay = toCopy.backoffDelay;
             delayUntil = toCopy.delayUntil;
-            periodicSyncs = new ArrayList<Pair<Bundle, Long>>();
-            for (Pair<Bundle, Long> sync : toCopy.periodicSyncs) {
+            periodicSyncs = new ArrayList<PeriodicSync>();
+            for (PeriodicSync sync : toCopy.periodicSyncs) {
                 // Still not a perfect copy, because we are just copying the mappings.
-                periodicSyncs.add(Pair.create(new Bundle(sync.first), sync.second));
+                periodicSyncs.add(new PeriodicSync(sync));
             }
         }
 
+        /**
+         * Create an authority with one periodic sync scheduled with an empty bundle and syncing
+         * every day. An empty bundle is considered equal to any other bundle see
+         * {@link PeriodicSync.syncExtrasEquals}.
+         * @param account Account that this authority syncs.
+         * @param userId which user this sync is registered for.
+         * @param userId user for which this authority is registered.
+         * @param ident id of this authority.
+         */
         AuthorityInfo(Account account, int userId, String authority, int ident) {
             this.account = account;
             this.userId = userId;
             this.authority = authority;
+            this.service = null;
             this.ident = ident;
             enabled = SYNC_ENABLED_DEFAULT;
             syncable = -1; // default to "unknown"
             backoffTime = -1; // if < 0 then we aren't in backoff mode
             backoffDelay = -1; // if < 0 then we aren't in backoff mode
-            periodicSyncs = new ArrayList<Pair<Bundle, Long>>();
-            periodicSyncs.add(Pair.create(new Bundle(), DEFAULT_POLL_FREQUENCY_SECONDS));
+            periodicSyncs = new ArrayList<PeriodicSync>();
+            // Old version adds one periodic sync a day.
+            periodicSyncs.add(new PeriodicSync(account, authority,
+                                new Bundle(),
+                                DEFAULT_POLL_FREQUENCY_SECONDS,
+                                calculateDefaultFlexTime(DEFAULT_POLL_FREQUENCY_SECONDS)));
+        }
+
+        /**
+         * Create an authority with one periodic sync scheduled with an empty bundle and syncing
+         * every day using a sync service.
+         * @param cname sync service identifier.
+         * @param userId user for which this authority is registered.
+         * @param ident id of this authority.
+         */
+        AuthorityInfo(ComponentName cname, int userId, int ident) {
+            this.account = null;
+            this.userId = userId;
+            this.authority = null;
+            this.service = cname;
+            this.ident = ident;
+            // Sync service is always enabled.
+            enabled = true;
+            syncable = -1; // default to "unknown"
+            backoffTime = -1; // if < 0 then we aren't in backoff mode
+            backoffDelay = -1; // if < 0 then we aren't in backoff mode
+            periodicSyncs = new ArrayList<PeriodicSync>();
+            periodicSyncs.add(new PeriodicSync(account, authority,
+                                new Bundle(),
+                                DEFAULT_POLL_FREQUENCY_SECONDS,
+                                calculateDefaultFlexTime(DEFAULT_POLL_FREQUENCY_SECONDS)));
         }
     }
 
@@ -303,6 +356,10 @@
     private final RemoteCallbackList<ISyncStatusObserver> mChangeListeners
             = new RemoteCallbackList<ISyncStatusObserver>();
 
+    /** Reverse mapping for component name -> <userid -> authority id>. */
+    private final HashMap<ComponentName, SparseArray<AuthorityInfo>> mServices =
+            new HashMap<ComponentName, SparseArray<AuthorityInfo>>();
+
     private int mNextAuthorityId = 0;
 
     // We keep 4 weeks of stats.
@@ -364,9 +421,12 @@
         File systemDir = new File(dataDir, "system");
         File syncDir = new File(systemDir, "sync");
         syncDir.mkdirs();
+
+        maybeDeleteLegacyPendingInfoLocked(syncDir);
+
         mAccountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml"));
         mStatusFile = new AtomicFile(new File(syncDir, "status.bin"));
-        mPendingFile = new AtomicFile(new File(syncDir, "pending.bin"));
+        mPendingFile = new AtomicFile(new File(syncDir, "pending.xml"));
         mStatisticsFile = new AtomicFile(new File(syncDir, "stats.bin"));
 
         readAccountInfoLocked();
@@ -435,6 +495,28 @@
         }
     }
 
+    /**
+     * Figure out a reasonable flex time for cases where none is provided (old api calls).
+     * @param syncTimeSeconds requested sync time from now.
+     * @return amount of seconds before syncTimeSeconds that the sync can occur.
+     *      I.e.
+     *      earliest_sync_time = syncTimeSeconds - calculateDefaultFlexTime(syncTimeSeconds)
+     * The flex time is capped at a percentage of the {@link DEFAULT_POLL_FREQUENCY_SECONDS}.
+     */
+    public static long calculateDefaultFlexTime(long syncTimeSeconds) {
+        if (syncTimeSeconds < DEFAULT_MIN_FLEX_ALLOWED_SECS) {
+            // Small enough sync request time that we don't add flex time - developer probably
+            // wants to wait for an operation to occur before syncing so we honour the
+            // request time.
+            return 0L;
+        } else if (syncTimeSeconds < DEFAULT_POLL_FREQUENCY_SECONDS) {
+            return (long) (syncTimeSeconds * DEFAULT_FLEX_PERCENT_SYNC);
+        } else {
+            // Large enough sync request time that we cap the flex time.
+            return (long) (DEFAULT_POLL_FREQUENCY_SECONDS * DEFAULT_FLEX_PERCENT_SYNC);
+        }
+    }
+
     private void reportChange(int which) {
         ArrayList<ISyncStatusObserver> reports = null;
         synchronized (mAuthorities) {
@@ -552,8 +634,8 @@
                     + ", user " + userId + " -> " + syncable);
         }
         synchronized (mAuthorities) {
-            AuthorityInfo authority = getOrCreateAuthorityLocked(account, userId, providerName, -1,
-                    false);
+            AuthorityInfo authority =
+                    getOrCreateAuthorityLocked(account, userId, providerName, -1, false);
             if (authority.syncable == syncable) {
                 if (DEBUG) {
                     Log.d(TAG, "setIsSyncable: already set to " + syncable + ", doing nothing");
@@ -598,7 +680,8 @@
                         continue;
                     }
                     for (AuthorityInfo authorityInfo : accountInfo.authorities.values()) {
-                        if (providerName != null && !providerName.equals(authorityInfo.authority)) {
+                        if (providerName != null
+                                && !providerName.equals(authorityInfo.authority)) {
                             continue;
                         }
                         if (authorityInfo.backoffTime != nextSyncTime
@@ -688,62 +771,68 @@
         }
     }
 
-    private void updateOrRemovePeriodicSync(Account account, int userId, String providerName,
-            Bundle extras,
-            long period, boolean add) {
-        if (period <= 0) {
-            period = 0;
-        }
-        if (extras == null) {
-            extras = new Bundle();
-        }
+    private void updateOrRemovePeriodicSync(PeriodicSync toUpdate, int userId, boolean add) {
         if (DEBUG) {
-            Log.v(TAG, "addOrRemovePeriodicSync: " + account + ", user " + userId
-                    + ", provider " + providerName
-                    + " -> period " + period + ", extras " + extras);
+            Log.v(TAG, "addOrRemovePeriodicSync: " + toUpdate.account + ", user " + userId
+                    + ", provider " + toUpdate.authority
+                    + " -> period " + toUpdate.period + ", extras " + toUpdate.extras);
         }
         synchronized (mAuthorities) {
+            if (toUpdate.period <= 0 && add) {
+                Log.e(TAG, "period < 0, should never happen in updateOrRemovePeriodicSync: add-"
+                        + add);
+            }
+            if (toUpdate.extras == null) {
+                Log.e(TAG, "null extras, should never happen in updateOrRemovePeriodicSync: add-"
+                        + add);
+            }
             try {
                 AuthorityInfo authority =
-                        getOrCreateAuthorityLocked(account, userId, providerName, -1, false);
+                        getOrCreateAuthorityLocked(toUpdate.account, userId, toUpdate.authority,
+                                -1, false);
                 if (add) {
-                    // add this periodic sync if one with the same extras doesn't already
-                    // exist in the periodicSyncs array
+                    // add this periodic sync if an equivalent periodic doesn't already exist.
                     boolean alreadyPresent = false;
                     for (int i = 0, N = authority.periodicSyncs.size(); i < N; i++) {
-                        Pair<Bundle, Long> syncInfo = authority.periodicSyncs.get(i);
-                        final Bundle existingExtras = syncInfo.first;
-                        if (PeriodicSync.syncExtrasEquals(existingExtras, extras)) {
-                            if (syncInfo.second == period) {
+                        PeriodicSync syncInfo = authority.periodicSyncs.get(i);
+                        if (PeriodicSync.syncExtrasEquals(
+                                toUpdate.extras,
+                                syncInfo.extras)) {
+                            if (toUpdate.period == syncInfo.period &&
+                                    toUpdate.flexTime == syncInfo.flexTime) {
+                                // Absolutely the same.
                                 return;
                             }
-                            authority.periodicSyncs.set(i, Pair.create(extras, period));
+                            authority.periodicSyncs.set(i, new PeriodicSync(toUpdate));
                             alreadyPresent = true;
                             break;
                         }
                     }
-                    // if we added an entry to the periodicSyncs array also add an entry to
-                    // the periodic syncs status to correspond to it
+                    // If we added an entry to the periodicSyncs array also add an entry to
+                    // the periodic syncs status to correspond to it.
                     if (!alreadyPresent) {
-                        authority.periodicSyncs.add(Pair.create(extras, period));
+                        authority.periodicSyncs.add(new PeriodicSync(toUpdate));
                         SyncStatusInfo status = getOrCreateSyncStatusLocked(authority.ident);
-                        status.setPeriodicSyncTime(authority.periodicSyncs.size() - 1, 0);
+                        status.setPeriodicSyncTime(authority.periodicSyncs.size() - 1, 0L);
                     }
                 } else {
-                    // remove any periodic syncs that match the authority and extras
+                    // Remove any periodic syncs that match the authority and extras.
                     SyncStatusInfo status = mSyncStatus.get(authority.ident);
                     boolean changed = false;
-                    Iterator<Pair<Bundle, Long>> iterator = authority.periodicSyncs.iterator();
+                    Iterator<PeriodicSync> iterator = authority.periodicSyncs.iterator();
                     int i = 0;
                     while (iterator.hasNext()) {
-                        Pair<Bundle, Long> syncInfo = iterator.next();
-                        if (PeriodicSync.syncExtrasEquals(syncInfo.first, extras)) {
+                        PeriodicSync syncInfo = iterator.next();
+                        if (PeriodicSync.syncExtrasEquals(syncInfo.extras, toUpdate.extras)) {
                             iterator.remove();
                             changed = true;
-                            // if we removed an entry from the periodicSyncs array also
+                            // If we removed an entry from the periodicSyncs array also
                             // remove the corresponding entry from the status
                             if (status != null) {
                                 status.removePeriodicSyncTime(i);
+                            } else {
+                                Log.e(TAG, "Tried removing sync status on remove periodic sync but"
+                                        + "did not find it.");
                             }
                         } else {
                             i++;
@@ -762,16 +851,12 @@
         reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
     }
 
-    public void addPeriodicSync(Account account, int userId, String providerName, Bundle extras,
-            long pollFrequency) {
-        updateOrRemovePeriodicSync(account, userId, providerName, extras, pollFrequency,
-                true /* add */);
+    public void addPeriodicSync(PeriodicSync toAdd, int userId) {
+        updateOrRemovePeriodicSync(toAdd, userId, true /* add */);
     }
 
-    public void removePeriodicSync(Account account, int userId, String providerName,
-            Bundle extras) {
-        updateOrRemovePeriodicSync(account, userId, providerName, extras, 0 /* period, ignored */,
-                false /* remove */);
+    public void removePeriodicSync(PeriodicSync toRemove, int userId) {
+        updateOrRemovePeriodicSync(toRemove, userId, false /* remove */);
     }
 
     public List<PeriodicSync> getPeriodicSyncs(Account account, int userId, String providerName) {
@@ -780,9 +865,9 @@
             AuthorityInfo authority = getAuthorityLocked(account, userId, providerName,
                     "getPeriodicSyncs");
             if (authority != null) {
-                for (Pair<Bundle, Long> item : authority.periodicSyncs) {
-                    syncs.add(new PeriodicSync(account, providerName, item.first,
-                            item.second));
+                for (PeriodicSync item : authority.periodicSyncs) {
+                    // Copy and send out. Necessary for thread-safety although it's parceled.
+                    syncs.add(new PeriodicSync(item));
                 }
             }
         }
@@ -813,14 +898,6 @@
         }
     }
 
-    public AuthorityInfo getOrCreateAuthority(Account account, int userId, String authority) {
-        synchronized (mAuthorities) {
-            return getOrCreateAuthorityLocked(account, userId, authority,
-                    -1 /* assign a new identifier if creating a new authority */,
-                    true /* write to storage if this results in a change */);
-        }
-    }
-
     public void removeAuthority(Account account, int userId, String authority) {
         synchronized (mAuthorities) {
             removeAuthorityLocked(account, userId, authority, true /* doWrite */);
@@ -883,6 +960,14 @@
         return op;
     }
 
+    /**
+     * Remove from list of pending operations. If successful, search through list for matching
+     * authorities. If there are no more pending syncs for the same authority/account/userid,
+     * update the SyncStatusInfo for that authority(authority here is the internal representation
+     * of a 'sync operation'.
+     * @param op
+     * @return
+     */
     public boolean deleteFromPending(PendingOperation op) {
         boolean res = false;
         synchronized (mAuthorities) {
@@ -905,7 +990,7 @@
                 AuthorityInfo authority = getAuthorityLocked(op.account, op.userId, op.authority,
                         "deleteFromPending");
                 if (authority != null) {
-                    if (DEBUG) Log.v(TAG, "removing - " + authority);
+                    if (DEBUG) Log.v(TAG, "removing - " + authority.toString());
                     final int N = mPendingOperations.size();
                     boolean morePending = false;
                     for (int i=0; i<N; i++) {
@@ -1238,17 +1323,27 @@
     }
 
     /**
-     * Return an array of the current authorities. Note
-     * that the objects inside the array are the real, live objects,
-     * so be careful what you do with them.
+     * Return a copy of the specified authority with the corresponding sync status
      */
-    public ArrayList<AuthorityInfo> getAuthorities() {
+    public Pair<AuthorityInfo, SyncStatusInfo> getCopyOfAuthorityWithSyncStatus(
+            Account account, int userId, String authority) {
         synchronized (mAuthorities) {
-            final int N = mAuthorities.size();
-            ArrayList<AuthorityInfo> infos = new ArrayList<AuthorityInfo>(N);
-            for (int i=0; i<N; i++) {
-                // Make deep copy because AuthorityInfo syncs are liable to change.
-                infos.add(new AuthorityInfo(mAuthorities.valueAt(i)));
+            AuthorityInfo authorityInfo = getOrCreateAuthorityLocked(account, userId, authority,
+                    -1 /* assign a new identifier if creating a new authority */,
+                    true /* write to storage if this results in a change */);
+            return createCopyPairOfAuthorityWithSyncStatusLocked(authorityInfo);
+        }
+    }
+
+    /**
+     * Return a copy of all authorities with their corresponding sync status
+     */
+    public ArrayList<Pair<AuthorityInfo, SyncStatusInfo>> getCopyOfAllAuthoritiesWithSyncStatus() {
+        synchronized (mAuthorities) {
+            ArrayList<Pair<AuthorityInfo, SyncStatusInfo>> infos =
+                    new ArrayList<Pair<AuthorityInfo, SyncStatusInfo>>(mAuthorities.size());
+            for (int i = 0; i < mAuthorities.size(); i++) {
+                infos.add(createCopyPairOfAuthorityWithSyncStatusLocked(mAuthorities.valueAt(i)));
             }
             return infos;
         }
@@ -1337,6 +1432,12 @@
         }
     }
 
+    private Pair<AuthorityInfo, SyncStatusInfo> createCopyPairOfAuthorityWithSyncStatusLocked(
+            AuthorityInfo authorityInfo) {
+        SyncStatusInfo syncStatusInfo = getOrCreateSyncStatusLocked(authorityInfo.ident);
+        return Pair.create(new AuthorityInfo(authorityInfo), new SyncStatusInfo(syncStatusInfo));
+    }
+
     private int getCurrentDayLocked() {
         mCal.setTimeInMillis(System.currentTimeMillis());
         final int dayOfYear = mCal.get(Calendar.DAY_OF_YEAR);
@@ -1382,6 +1483,65 @@
         return authority;
     }
 
+    /**
+     * Retrieve an authority, returning null if one does not exist.
+     *
+     * @param service The service name used for this sync.
+     * @param userId The user for whom this sync is scheduled.
+     * @param tag If non-null, this will be used in a log message if the
+     * requested authority does not exist.
+     */
+    private AuthorityInfo getAuthorityLocked(ComponentName service, int userId, String tag) {
+        AuthorityInfo authority = mServices.get(service).get(userId);
+        if (authority == null) {
+            if (tag != null) {
+                if (DEBUG) {
+                    Log.v(TAG, tag + " No authority info found for " + service + " for user "
+                            + userId);
+                }
+            }
+            return null;
+        }
+        return authority;
+    }
+
+    /**
+     * @param cname identifier for the service.
+     * @param userId for the syncs corresponding to this authority.
+     * @param ident unique identifier for authority. -1 for none.
+     * @param doWrite if true, update the accounts.xml file on the disk.
+     * @return the authority that corresponds to the provided sync service, creating it if none
+     * exists.
+     */
+    private AuthorityInfo getOrCreateAuthorityLocked(ComponentName cname, int userId, int ident,
+            boolean doWrite) {
+        SparseArray<AuthorityInfo> aInfo = mServices.get(cname);
+        if (aInfo == null) {
+            aInfo = new SparseArray<AuthorityInfo>();
+            mServices.put(cname, aInfo);
+        }
+        AuthorityInfo authority = aInfo.get(userId);
+        if (authority == null) {
+            if (ident < 0) {
+                ident = mNextAuthorityId;
+                mNextAuthorityId++;
+                doWrite = true;
+            }
+            if (DEBUG) {
+                Log.v(TAG, "created a new AuthorityInfo for " + cname.getPackageName()
+                        + ", " + cname.getClassName()
+                        + ", user: " + userId);
+            }
+            authority = new AuthorityInfo(cname, userId, ident);
+            aInfo.put(userId, authority);
+            mAuthorities.put(ident, authority);
+            if (doWrite) {
+                writeAccountInfoLocked();
+            }
+        }
+        return authority;
+    }
+
     private AuthorityInfo getOrCreateAuthorityLocked(Account accountName, int userId,
             String authorityName, int ident, boolean doWrite) {
         AccountAndUser au = new AccountAndUser(accountName, userId);
@@ -1427,9 +1587,28 @@
         }
     }
 
-    public SyncStatusInfo getOrCreateSyncStatus(AuthorityInfo authority) {
+    /**
+     * Updates (in a synchronized way) the periodic sync time of the specified
+     * authority id and target periodic sync
+     */
+    public void setPeriodicSyncTime(
+            int authorityId, PeriodicSync targetPeriodicSync, long when) {
+        boolean found = false;
+        final AuthorityInfo authorityInfo;
         synchronized (mAuthorities) {
-            return getOrCreateSyncStatusLocked(authority.ident);
+            authorityInfo = mAuthorities.get(authorityId);
+            for (int i = 0; i < authorityInfo.periodicSyncs.size(); i++) {
+                PeriodicSync periodicSync = authorityInfo.periodicSyncs.get(i);
+                if (targetPeriodicSync.equals(periodicSync)) {
+                    mSyncStatus.get(authorityId).setPeriodicSyncTime(i, when);
+                    found = true;
+                    break;
+                }
+            }
+        }
+        if (!found) {
+            Log.w(TAG, "Ignoring setPeriodicSyncTime request for a sync that does not exist. " +
+                    "Authority: " + authorityInfo.authority);
         }
     }
 
@@ -1464,6 +1643,7 @@
         synchronized (mAuthorities) {
             mAuthorities.clear();
             mAccounts.clear();
+            mServices.clear();
             mPendingOperations.clear();
             mSyncStatus.clear();
             mSyncHistory.clear();
@@ -1488,7 +1668,9 @@
         FileInputStream fis = null;
         try {
             fis = mAccountInfoFile.openRead();
-            if (DEBUG_FILE) Log.v(TAG, "Reading " + mAccountInfoFile.getBaseFile());
+            if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+                Log.v(TAG, "Reading " + mAccountInfoFile.getBaseFile());
+            }
             XmlPullParser parser = Xml.newPullParser();
             parser.setInput(fis, null);
             int eventType = parser.getEventType();
@@ -1525,7 +1707,7 @@
                 mMasterSyncAutomatically.put(0, listen == null || Boolean.parseBoolean(listen));
                 eventType = parser.next();
                 AuthorityInfo authority = null;
-                Pair<Bundle, Long> periodicSync = null;
+                PeriodicSync periodicSync = null;
                 do {
                     if (eventType == XmlPullParser.START_TAG) {
                         tagName = parser.getName();
@@ -1545,7 +1727,7 @@
                             }
                         } else if (parser.getDepth() == 4 && periodicSync != null) {
                             if ("extra".equals(tagName)) {
-                                parseExtra(parser, periodicSync);
+                                parseExtra(parser, periodicSync.extras);
                             }
                         }
                     }
@@ -1573,6 +1755,20 @@
     }
 
     /**
+     * Ensure the old pending.bin is deleted, as it has been changed to pending.xml.
+     * pending.xml was used starting in KLP.
+     * @param syncDir directory where the sync files are located.
+     */
+    private void maybeDeleteLegacyPendingInfoLocked(File syncDir) {
+        File file = new File(syncDir, "pending.bin");
+        if (!file.exists()) {
+            return;
+        } else {
+            file.delete();
+        }
+    }
+
+    /**
      * some authority names have changed. copy over their settings and delete the old ones
      * @return true if a change was made
      */
@@ -1639,8 +1835,7 @@
         AuthorityInfo authority = null;
         int id = -1;
         try {
-            id = Integer.parseInt(parser.getAttributeValue(
-                    null, "id"));
+            id = Integer.parseInt(parser.getAttributeValue(null, "id"));
         } catch (NumberFormatException e) {
             Log.e(TAG, "error parsing the id of the authority", e);
         } catch (NullPointerException e) {
@@ -1653,24 +1848,36 @@
             String accountName = parser.getAttributeValue(null, "account");
             String accountType = parser.getAttributeValue(null, "type");
             String user = parser.getAttributeValue(null, XML_ATTR_USER);
+            String packageName = parser.getAttributeValue(null, "package");
+            String className = parser.getAttributeValue(null, "class");
             int userId = user == null ? 0 : Integer.parseInt(user);
             if (accountType == null) {
                 accountType = "com.google";
                 syncable = "unknown";
             }
             authority = mAuthorities.get(id);
-            if (DEBUG_FILE) Log.v(TAG, "Adding authority: account="
-                    + accountName + " auth=" + authorityName
-                    + " user=" + userId
-                    + " enabled=" + enabled
-                    + " syncable=" + syncable);
+            if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+                Log.v(TAG, "Adding authority: account="
+                        + accountName + " auth=" + authorityName
+                        + " user=" + userId
+                        + " enabled=" + enabled
+                        + " syncable=" + syncable);
+            }
             if (authority == null) {
-                if (DEBUG_FILE) Log.v(TAG, "Creating entry");
-                authority = getOrCreateAuthorityLocked(
-                        new Account(accountName, accountType), userId, authorityName, id, false);
+                if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+                    Log.v(TAG, "Creating entry");
+                }
+                if (accountName != null && accountType != null) {
+                    authority = getOrCreateAuthorityLocked(
+                            new Account(accountName, accountType), userId, authorityName, id,
+                                false);
+                } else {
+                    authority = getOrCreateAuthorityLocked(
+                            new ComponentName(packageName, className), userId, id, false);
+                }
                 // If the version is 0 then we are upgrading from a file format that did not
                 // know about periodic syncs. In that case don't clear the list since we
-                // want the default, which is a daily periodioc sync.
+                // want the default, which is a daily periodic sync.
                 // Otherwise clear out this default list since we will populate it later with
                 // the periodic sync descriptions that are read from the configuration file.
                 if (version > 0) {
@@ -1692,14 +1899,18 @@
                         + " syncable=" + syncable);
             }
         }
-
         return authority;
     }
 
-    private Pair<Bundle, Long> parsePeriodicSync(XmlPullParser parser, AuthorityInfo authority) {
-        Bundle extras = new Bundle();
+    /**
+     * Parse a periodic sync from accounts.xml. Sets the bundle to be empty.
+     */
+    private PeriodicSync parsePeriodicSync(XmlPullParser parser, AuthorityInfo authority) {
+        Bundle extras = new Bundle(); // Gets filled in later.
         String periodValue = parser.getAttributeValue(null, "period");
+        String flexValue = parser.getAttributeValue(null, "flex");
         final long period;
+        long flextime;
         try {
             period = Long.parseLong(periodValue);
         } catch (NumberFormatException e) {
@@ -1709,14 +1920,24 @@
             Log.e(TAG, "the period of a periodic sync is null", e);
             return null;
         }
-        final Pair<Bundle, Long> periodicSync = Pair.create(extras, period);
+        try {
+            flextime = Long.parseLong(flexValue);
+        } catch (NumberFormatException e) {
+            Log.e(TAG, "Error formatting value parsed for periodic sync flex: " + flexValue);
+            flextime = calculateDefaultFlexTime(period);
+        } catch (NullPointerException expected) {
+            flextime = calculateDefaultFlexTime(period);
+            Log.d(TAG, "No flex time specified for this sync, using a default. period: "
+            + period + " flex: " + flextime);
+        }
+        final PeriodicSync periodicSync =
+                new PeriodicSync(authority.account, authority.authority, extras,
+                        period, flextime);
         authority.periodicSyncs.add(periodicSync);
-
         return periodicSync;
     }
 
-    private void parseExtra(XmlPullParser parser, Pair<Bundle, Long> periodicSync) {
-        final Bundle extras = periodicSync.first;
+    private void parseExtra(XmlPullParser parser, Bundle extras) {
         String name = parser.getAttributeValue(null, "name");
         String type = parser.getAttributeValue(null, "type");
         String value1 = parser.getAttributeValue(null, "value1");
@@ -1749,7 +1970,9 @@
      * Write all account information to the account file.
      */
     private void writeAccountInfoLocked() {
-        if (DEBUG_FILE) Log.v(TAG, "Writing new " + mAccountInfoFile.getBaseFile());
+        if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+            Log.v(TAG, "Writing new " + mAccountInfoFile.getBaseFile());
+        }
         FileOutputStream fos = null;
 
         try {
@@ -1776,62 +1999,37 @@
             }
 
             final int N = mAuthorities.size();
-            for (int i=0; i<N; i++) {
+            for (int i = 0; i < N; i++) {
                 AuthorityInfo authority = mAuthorities.valueAt(i);
                 out.startTag(null, "authority");
                 out.attribute(null, "id", Integer.toString(authority.ident));
-                out.attribute(null, "account", authority.account.name);
                 out.attribute(null, XML_ATTR_USER, Integer.toString(authority.userId));
-                out.attribute(null, "type", authority.account.type);
-                out.attribute(null, "authority", authority.authority);
                 out.attribute(null, XML_ATTR_ENABLED, Boolean.toString(authority.enabled));
+                if (authority.service == null) {
+                    out.attribute(null, "account", authority.account.name);
+                    out.attribute(null, "type", authority.account.type);
+                    out.attribute(null, "authority", authority.authority);
+                } else {
+                    out.attribute(null, "package", authority.service.getPackageName());
+                    out.attribute(null, "class", authority.service.getClassName());
+                }
                 if (authority.syncable < 0) {
                     out.attribute(null, "syncable", "unknown");
                 } else {
                     out.attribute(null, "syncable", Boolean.toString(authority.syncable != 0));
                 }
-                for (Pair<Bundle, Long> periodicSync : authority.periodicSyncs) {
+                for (PeriodicSync periodicSync : authority.periodicSyncs) {
                     out.startTag(null, "periodicSync");
-                    out.attribute(null, "period", Long.toString(periodicSync.second));
-                    final Bundle extras = periodicSync.first;
-                    for (String key : extras.keySet()) {
-                        out.startTag(null, "extra");
-                        out.attribute(null, "name", key);
-                        final Object value = extras.get(key);
-                        if (value instanceof Long) {
-                            out.attribute(null, "type", "long");
-                            out.attribute(null, "value1", value.toString());
-                        } else if (value instanceof Integer) {
-                            out.attribute(null, "type", "integer");
-                            out.attribute(null, "value1", value.toString());
-                        } else if (value instanceof Boolean) {
-                            out.attribute(null, "type", "boolean");
-                            out.attribute(null, "value1", value.toString());
-                        } else if (value instanceof Float) {
-                            out.attribute(null, "type", "float");
-                            out.attribute(null, "value1", value.toString());
-                        } else if (value instanceof Double) {
-                            out.attribute(null, "type", "double");
-                            out.attribute(null, "value1", value.toString());
-                        } else if (value instanceof String) {
-                            out.attribute(null, "type", "string");
-                            out.attribute(null, "value1", value.toString());
-                        } else if (value instanceof Account) {
-                            out.attribute(null, "type", "account");
-                            out.attribute(null, "value1", ((Account)value).name);
-                            out.attribute(null, "value2", ((Account)value).type);
-                        }
-                        out.endTag(null, "extra");
-                    }
+                    out.attribute(null, "period", Long.toString(periodicSync.period));
+                    out.attribute(null, "flex", Long.toString(periodicSync.flexTime));
+                    final Bundle extras = periodicSync.extras;
+                    extrasToXml(out, extras);
                     out.endTag(null, "periodicSync");
                 }
                 out.endTag(null, "authority");
             }
-
             out.endTag(null, "accounts");
-
             out.endDocument();
-
             mAccountInfoFile.finishWrite(fos);
         } catch (java.io.IOException e1) {
             Log.w(TAG, "Error writing accounts", e1);
@@ -1872,7 +2070,9 @@
             final boolean hasType = db.getVersion() >= 11;
 
             // Copy in all of the status information, as well as accounts.
-            if (DEBUG_FILE) Log.v(TAG, "Reading legacy sync accounts db");
+            if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+                Log.v(TAG, "Reading legacy sync accounts db");
+            }
             SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
             qb.setTables("stats, status");
             HashMap<String,String> map = new HashMap<String,String>();
@@ -1982,7 +2182,9 @@
      * Read all sync status back in to the initial engine state.
      */
     private void readStatusLocked() {
-        if (DEBUG_FILE) Log.v(TAG, "Reading " + mStatusFile.getBaseFile());
+        if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+            Log.v(TAG, "Reading " + mStatusFile.getBaseFile());
+        }
         try {
             byte[] data = mStatusFile.readFully();
             Parcel in = Parcel.obtain();
@@ -1994,8 +2196,10 @@
                     SyncStatusInfo status = new SyncStatusInfo(in);
                     if (mAuthorities.indexOfKey(status.authorityId) >= 0) {
                         status.pending = false;
-                        if (DEBUG_FILE) Log.v(TAG, "Adding status for id "
-                                + status.authorityId);
+                        if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+                            Log.v(TAG, "Adding status for id "
+                                    + status.authorityId);
+                        }
                         mSyncStatus.put(status.authorityId, status);
                     }
                 } else {
@@ -2013,7 +2217,9 @@
      * Write all sync status to the sync status file.
      */
     private void writeStatusLocked() {
-        if (DEBUG_FILE) Log.v(TAG, "Writing new " + mStatusFile.getBaseFile());
+        if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+            Log.v(TAG, "Writing new " + mStatusFile.getBaseFile());
+        }
 
         // The file is being written, so we don't need to have a scheduled
         // write until the next change.
@@ -2044,74 +2250,109 @@
 
     public static final int PENDING_OPERATION_VERSION = 3;
 
-    /**
-     * Read all pending operations back in to the initial engine state.
-     */
+    /** Read all pending operations back in to the initial engine state. */
     private void readPendingOperationsLocked() {
-        if (DEBUG_FILE) Log.v(TAG, "Reading " + mPendingFile.getBaseFile());
-        try {
-            byte[] data = mPendingFile.readFully();
-            Parcel in = Parcel.obtain();
-            in.unmarshall(data, 0, data.length);
-            in.setDataPosition(0);
-            final int SIZE = in.dataSize();
-            while (in.dataPosition() < SIZE) {
-                int version = in.readInt();
-                if (version != PENDING_OPERATION_VERSION && version != 1) {
-                    Log.w(TAG, "Unknown pending operation version "
-                            + version + "; dropping all ops");
-                    break;
-                }
-                int authorityId = in.readInt();
-                int syncSource = in.readInt();
-                byte[] flatExtras = in.createByteArray();
-                boolean expedited;
-                if (version == PENDING_OPERATION_VERSION) {
-                    expedited = in.readInt() != 0;
-                } else {
-                    expedited = false;
-                }
-                int reason = in.readInt();
-                AuthorityInfo authority = mAuthorities.get(authorityId);
-                if (authority != null) {
-                    Bundle extras;
-                    if (flatExtras != null) {
-                        extras = unflattenBundle(flatExtras);
-                    } else {
-                        // if we are unable to parse the extras for whatever reason convert this
-                        // to a regular sync by creating an empty extras
-                        extras = new Bundle();
-                    }
-                    PendingOperation op = new PendingOperation(
-                            authority.account, authority.userId, reason, syncSource,
-                            authority.authority, extras, expedited);
-                    op.authorityId = authorityId;
-                    op.flatExtras = flatExtras;
-                    if (DEBUG_FILE) Log.v(TAG, "Adding pending op: account=" + op.account
-                            + " auth=" + op.authority
-                            + " src=" + op.syncSource
-                            + " reason=" + op.reason
-                            + " expedited=" + op.expedited
-                            + " extras=" + op.extras);
-                    mPendingOperations.add(op);
-                }
+        FileInputStream fis = null;
+        if (!mPendingFile.getBaseFile().exists()) {
+            if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+                Log.v(TAG_FILE, "No pending operation file.");
+                return;
             }
+        }
+        try {
+            fis = mPendingFile.openRead();
+            XmlPullParser parser;
+            parser = Xml.newPullParser();
+            parser.setInput(fis, null);
+
+            int eventType = parser.getEventType();
+            while (eventType != XmlPullParser.START_TAG &&
+                    eventType != XmlPullParser.END_DOCUMENT) {
+                eventType = parser.next();
+            }
+            if (eventType == XmlPullParser.END_DOCUMENT) return; // Nothing to read.
+
+            String tagName = parser.getName();
+            do {
+                PendingOperation pop = null;
+                if (eventType == XmlPullParser.START_TAG) {
+                    try {
+                        tagName = parser.getName();
+                        if (parser.getDepth() == 1 && "op".equals(tagName)) {
+                            // Verify version.
+                            String versionString =
+                                    parser.getAttributeValue(null, XML_ATTR_VERSION);
+                            if (versionString == null ||
+                                    Integer.parseInt(versionString) != PENDING_OPERATION_VERSION) {
+                                Log.w(TAG, "Unknown pending operation version " + versionString);
+                                throw new java.io.IOException("Unknown version.");
+                            }
+                            int authorityId = Integer.valueOf(parser.getAttributeValue(
+                                    null, XML_ATTR_AUTHORITYID));
+                            boolean expedited = Boolean.valueOf(parser.getAttributeValue(
+                                    null, XML_ATTR_EXPEDITED));
+                            int syncSource = Integer.valueOf(parser.getAttributeValue(
+                                    null, XML_ATTR_SOURCE));
+                            int reason = Integer.valueOf(parser.getAttributeValue(
+                                    null, XML_ATTR_REASON));
+                            AuthorityInfo authority = mAuthorities.get(authorityId);
+                            if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+                                Log.v(TAG_FILE, authorityId + " " + expedited + " " + syncSource + " "
+                                        + reason);
+                            }
+                            if (authority != null) {
+                                pop = new PendingOperation(
+                                        authority.account, authority.userId, reason,
+                                        syncSource, authority.authority, new Bundle(),
+                                        expedited);
+                                pop.flatExtras = null; // No longer used.
+                                mPendingOperations.add(pop);
+                                if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+                                    Log.v(TAG_FILE, "Adding pending op: "
+                                            + pop.authority
+                                            + " src=" + pop.syncSource
+                                            + " reason=" + pop.reason
+                                            + " expedited=" + pop.expedited);
+                                }
+                            } else {
+                                // Skip non-existent authority.
+                                pop = null;
+                                if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+                                    Log.v(TAG_FILE, "No authority found for " + authorityId
+                                            + ", skipping");
+                                }
+                            }
+                        } else if (parser.getDepth() == 2 &&
+                                pop != null &&
+                                "extra".equals(tagName)) {
+                            parseExtra(parser, pop.extras);
+                        }
+                    } catch (NumberFormatException e) {
+                        Log.d(TAG, "Invalid data in xml file.", e);
+                    }
+                }
+                eventType = parser.next();
+            } while(eventType != XmlPullParser.END_DOCUMENT);
         } catch (java.io.IOException e) {
-            Log.i(TAG, "No initial pending operations");
+            Log.w(TAG_FILE, "Error reading pending data.", e);
+        } catch (XmlPullParserException e) {
+            if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+                Log.w(TAG_FILE, "Error parsing pending ops xml.", e);
+            }
+        } finally {
+            if (fis != null) {
+                try {
+                    fis.close();
+                } catch (java.io.IOException e1) {}
+            }
         }
     }
 
-    private void writePendingOperationLocked(PendingOperation op, Parcel out) {
-        out.writeInt(PENDING_OPERATION_VERSION);
-        out.writeInt(op.authorityId);
-        out.writeInt(op.syncSource);
-        if (op.flatExtras == null && op.extras != null) {
-            op.flatExtras = flattenBundle(op.extras);
-        }
-        out.writeByteArray(op.flatExtras);
-        out.writeInt(op.expedited ? 1 : 0);
-        out.writeInt(op.reason);
-    }
+    private static final String XML_ATTR_AUTHORITYID = "authority_id";
+    private static final String XML_ATTR_SOURCE = "source";
+    private static final String XML_ATTR_EXPEDITED = "expedited";
+    private static final String XML_ATTR_REASON = "reason";
+    private static final String XML_ATTR_VERSION = "version";
 
     /**
      * Write all currently pending ops to the pending ops file.
@@ -2121,22 +2362,24 @@
         FileOutputStream fos = null;
         try {
             if (N == 0) {
-                if (DEBUG_FILE) Log.v(TAG, "Truncating " + mPendingFile.getBaseFile());
+                if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+                    Log.v(TAG_FILE, "Truncating " + mPendingFile.getBaseFile());
+                }
                 mPendingFile.truncate();
                 return;
             }
-
-            if (DEBUG_FILE) Log.v(TAG, "Writing new " + mPendingFile.getBaseFile());
-            fos = mPendingFile.startWrite();
-
-            Parcel out = Parcel.obtain();
-            for (int i=0; i<N; i++) {
-                PendingOperation op = mPendingOperations.get(i);
-                writePendingOperationLocked(op, out);
+            if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+                Log.v(TAG_FILE, "Writing new " + mPendingFile.getBaseFile());
             }
-            fos.write(out.marshall());
-            out.recycle();
+            fos = mPendingFile.startWrite();
+            XmlSerializer out = new FastXmlSerializer();
+            out.setOutput(fos, "utf-8");
 
+            for (int i = 0; i < N; i++) {
+                PendingOperation pop = mPendingOperations.get(i);
+                writePendingOperationLocked(pop, out);
+            }
+            out.endDocument();
             mPendingFile.finishWrite(fos);
         } catch (java.io.IOException e1) {
             Log.w(TAG, "Error writing pending operations", e1);
@@ -2146,33 +2389,54 @@
         }
     }
 
+    /** Write all currently pending ops to the pending ops file. */
+     private void writePendingOperationLocked(PendingOperation pop, XmlSerializer out)
+             throws IOException {
+         // Pending operation.
+         out.startTag(null, "op");
+
+         out.attribute(null, XML_ATTR_VERSION, Integer.toString(PENDING_OPERATION_VERSION));
+         out.attribute(null, XML_ATTR_AUTHORITYID, Integer.toString(pop.authorityId));
+         out.attribute(null, XML_ATTR_SOURCE, Integer.toString(pop.syncSource));
+         out.attribute(null, XML_ATTR_EXPEDITED, Boolean.toString(pop.expedited));
+         out.attribute(null, XML_ATTR_REASON, Integer.toString(pop.reason));
+         extrasToXml(out, pop.extras);
+
+         out.endTag(null, "op");
+     }
+
     /**
      * Append the given operation to the pending ops file; if unable to,
      * write all pending ops.
      */
     private void appendPendingOperationLocked(PendingOperation op) {
-        if (DEBUG_FILE) Log.v(TAG, "Appending to " + mPendingFile.getBaseFile());
+        if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+            Log.v(TAG, "Appending to " + mPendingFile.getBaseFile());
+        }
         FileOutputStream fos = null;
         try {
             fos = mPendingFile.openAppend();
         } catch (java.io.IOException e) {
-            if (DEBUG_FILE) Log.v(TAG, "Failed append; writing full file");
+            if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+                Log.v(TAG, "Failed append; writing full file");
+            }
             writePendingOperationsLocked();
             return;
         }
 
         try {
-            Parcel out = Parcel.obtain();
+            XmlSerializer out = new FastXmlSerializer();
+            out.setOutput(fos, "utf-8");
             writePendingOperationLocked(op, out);
-            fos.write(out.marshall());
-            out.recycle();
+            out.endDocument();
+            mPendingFile.finishWrite(fos);
         } catch (java.io.IOException e1) {
-            Log.w(TAG, "Error writing pending operations", e1);
+            Log.w(TAG, "Error writing appending operation", e1);
+            mPendingFile.failWrite(fos);
         } finally {
             try {
                 fos.close();
-            } catch (java.io.IOException e2) {
-            }
+            } catch (IOException e) {}
         }
     }
 
@@ -2205,6 +2469,38 @@
         return bundle;
     }
 
+    private void extrasToXml(XmlSerializer out, Bundle extras) throws java.io.IOException {
+        for (String key : extras.keySet()) {
+            out.startTag(null, "extra");
+            out.attribute(null, "name", key);
+            final Object value = extras.get(key);
+            if (value instanceof Long) {
+                out.attribute(null, "type", "long");
+                out.attribute(null, "value1", value.toString());
+            } else if (value instanceof Integer) {
+                out.attribute(null, "type", "integer");
+                out.attribute(null, "value1", value.toString());
+            } else if (value instanceof Boolean) {
+                out.attribute(null, "type", "boolean");
+                out.attribute(null, "value1", value.toString());
+            } else if (value instanceof Float) {
+                out.attribute(null, "type", "float");
+                out.attribute(null, "value1", value.toString());
+            } else if (value instanceof Double) {
+                out.attribute(null, "type", "double");
+                out.attribute(null, "value1", value.toString());
+            } else if (value instanceof String) {
+                out.attribute(null, "type", "string");
+                out.attribute(null, "value1", value.toString());
+            } else if (value instanceof Account) {
+                out.attribute(null, "type", "account");
+                out.attribute(null, "value1", ((Account)value).name);
+                out.attribute(null, "value2", ((Account)value).type);
+            }
+            out.endTag(null, "extra");
+        }
+    }
+
     private void requestSync(Account account, int userId, int reason, String authority,
             Bundle extras) {
         // If this is happening in the system process, then call the syncrequest listener
@@ -2265,7 +2561,9 @@
      * Write all sync statistics to the sync status file.
      */
     private void writeStatisticsLocked() {
-        if (DEBUG_FILE) Log.v(TAG, "Writing new " + mStatisticsFile.getBaseFile());
+        if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+            Log.v(TAG, "Writing new " + mStatisticsFile.getBaseFile());
+        }
 
         // The file is being written, so we don't need to have a scheduled
         // write until the next change.
@@ -2300,4 +2598,18 @@
             }
         }
     }
+
+    /**
+     * Dump state of PendingOperations.
+     */
+    public void dumpPendingOperations(StringBuilder sb) {
+        sb.append("Pending Ops: ").append(mPendingOperations.size()).append(" operation(s)\n");
+        for (PendingOperation pop : mPendingOperations) {
+            sb.append("(" + pop.account)
+                .append(", u" + pop.userId)
+                .append(", " + pop.authority)
+                .append(", " + pop.extras)
+                .append(")\n");
+        }
+    }
 }
diff --git a/services/java/com/android/server/display/DisplayDeviceInfo.java b/services/java/com/android/server/display/DisplayDeviceInfo.java
index 247d8a0..11c5d87 100644
--- a/services/java/com/android/server/display/DisplayDeviceInfo.java
+++ b/services/java/com/android/server/display/DisplayDeviceInfo.java
@@ -61,6 +61,23 @@
     public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 1 << 3;
 
     /**
+     * Flag: Indicates that the display device is owned by a particular application
+     * and that no other application should be able to interact with it.
+     */
+    public static final int FLAG_PRIVATE = 1 << 4;
+
+    /**
+     * Flag: Indicates that the display device is not blanked automatically by
+     * the power manager.
+     */
+    public static final int FLAG_NEVER_BLANK = 1 << 5;
+
+    /**
+     * Flag: Indicates that the display is suitable for presentations.
+     */
+    public static final int FLAG_PRESENTATION = 1 << 6;
+
+    /**
      * Touch attachment: Display does not receive touch.
      */
     public static final int TOUCH_NONE = 0;
@@ -150,6 +167,23 @@
      */
     public String address;
 
+    /**
+     * The UID of the application that owns this display, or zero if it is owned by the system.
+     * <p>
+     * If the display is private, then only the owner can use it.
+     * </p>
+     */
+    public int ownerUid;
+
+    /**
+     * The package name of the application that owns this display, or null if it is
+     * owned by the system.
+     * <p>
+     * If the display is private, then only the owner can use it.
+     * </p>
+     */
+    public String ownerPackageName;
+
     public void setAssumedDensityForExternalDisplay(int width, int height) {
         densityDpi = Math.min(width, height) * DisplayMetrics.DENSITY_XHIGH / 1080;
         // Technically, these values should be smaller than the apparent density
@@ -176,7 +210,9 @@
                 && touch == other.touch
                 && rotation == other.rotation
                 && type == other.type
-                && Objects.equal(address, other.address);
+                && Objects.equal(address, other.address)
+                && ownerUid == other.ownerUid
+                && Objects.equal(ownerPackageName, other.ownerPackageName);
     }
 
     @Override
@@ -197,19 +233,32 @@
         rotation = other.rotation;
         type = other.type;
         address = other.address;
+        ownerUid = other.ownerUid;
+        ownerPackageName = other.ownerPackageName;
     }
 
     // For debugging purposes
     @Override
     public String toString() {
-        return "DisplayDeviceInfo{\"" + name + "\": " + width + " x " + height + ", "
-                + refreshRate + " fps, "
-                + "density " + densityDpi + ", " + xDpi + " x " + yDpi + " dpi"
-                + ", touch " + touchToString(touch) + flagsToString(flags)
-                + ", rotation " + rotation
-                + ", type " + Display.typeToString(type)
-                + ", address " + address
-                + "}";
+        StringBuilder sb = new StringBuilder();
+        sb.append("DisplayDeviceInfo{\"");
+        sb.append(name).append("\": ").append(width).append(" x ").append(height);
+        sb.append(", ").append(refreshRate).append(" fps, ");
+        sb.append("density ").append(densityDpi);
+        sb.append(", ").append(xDpi).append(" x ").append(yDpi).append(" dpi");
+        sb.append(", touch ").append(touchToString(touch));
+        sb.append(", rotation ").append(rotation);
+        sb.append(", type ").append(Display.typeToString(type));
+        if (address != null) {
+            sb.append(", address ").append(address);
+        }
+        if (ownerUid != 0 || ownerPackageName != null) {
+            sb.append(", owner ").append(ownerPackageName);
+            sb.append(" (uid ").append(ownerUid).append(")");
+        }
+        sb.append(flagsToString(flags));
+        sb.append("}");
+        return sb.toString();
     }
 
     private static String touchToString(int touch) {
@@ -239,6 +288,15 @@
         if ((flags & FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) {
             msg.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS");
         }
+        if ((flags & FLAG_PRIVATE) != 0) {
+            msg.append(", FLAG_PRIVATE");
+        }
+        if ((flags & FLAG_NEVER_BLANK) != 0) {
+            msg.append(", FLAG_NEVER_BLANK");
+        }
+        if ((flags & FLAG_PRESENTATION) != 0) {
+            msg.append(", FLAG_PRESENTATION");
+        }
         return msg.toString();
     }
 }
diff --git a/services/java/com/android/server/display/DisplayManagerService.java b/services/java/com/android/server/display/DisplayManagerService.java
index 17b0662..249c8b0 100644
--- a/services/java/com/android/server/display/DisplayManagerService.java
+++ b/services/java/com/android/server/display/DisplayManagerService.java
@@ -21,6 +21,7 @@
 import android.Manifest;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManagerGlobal;
 import android.hardware.display.IDisplayManager;
 import android.hardware.display.IDisplayManagerCallback;
@@ -33,14 +34,19 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.SystemProperties;
+import android.text.TextUtils;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.view.Display;
 import android.view.DisplayInfo;
+import android.view.Surface;
+
+import com.android.server.UiThread;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.concurrent.CopyOnWriteArrayList;
 
 /**
@@ -148,9 +154,6 @@
     // List of all currently connected display devices.
     private final ArrayList<DisplayDevice> mDisplayDevices = new ArrayList<DisplayDevice>();
 
-    // List of all removed display devices.
-    private final ArrayList<DisplayDevice> mRemovedDisplayDevices = new ArrayList<DisplayDevice>();
-
     // List of all logical displays indexed by logical display id.
     private final SparseArray<LogicalDisplay> mLogicalDisplays =
             new SparseArray<LogicalDisplay>();
@@ -170,6 +173,9 @@
     // The Wifi display adapter, or null if not registered.
     private WifiDisplayAdapter mWifiDisplayAdapter;
 
+    // The virtual display adapter, or null if not registered.
+    private VirtualDisplayAdapter mVirtualDisplayAdapter;
+
     // Viewports of the default display and the display that should receive touch
     // input from an external source.  Used by the input system.
     private final DisplayViewport mDefaultViewport = new DisplayViewport();
@@ -190,12 +196,12 @@
     private final DisplayViewport mTempDefaultViewport = new DisplayViewport();
     private final DisplayViewport mTempExternalTouchViewport = new DisplayViewport();
 
-    public DisplayManagerService(Context context, Handler mainHandler, Handler uiHandler) {
+    public DisplayManagerService(Context context, Handler mainHandler) {
         mContext = context;
         mHeadless = SystemProperties.get(SYSTEM_HEADLESS).equals("1");
 
         mHandler = new DisplayManagerHandler(mainHandler.getLooper());
-        mUiHandler = uiHandler;
+        mUiHandler = UiThread.getHandler();
         mDisplayAdapterListener = new DisplayAdapterListener();
         mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false);
 
@@ -305,6 +311,9 @@
      * to the display information synchronously so that applications will immediately
      * observe the new state.
      *
+     * NOTE: This method must be the only entry point by which the window manager
+     * influences the logical configuration of displays.
+     *
      * @param displayId The logical display id.
      * @param info The new data to be stored.
      */
@@ -313,9 +322,7 @@
         synchronized (mSyncRoot) {
             LogicalDisplay display = mLogicalDisplays.get(displayId);
             if (display != null) {
-                mTempDisplayInfo.copyFrom(display.getDisplayInfoLocked());
-                display.setDisplayInfoOverrideFromWindowManagerLocked(info);
-                if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) {
+                if (display.setDisplayInfoOverrideFromWindowManagerLocked(info)) {
                     sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
                     scheduleTraversalLocked(false);
                 }
@@ -324,18 +331,6 @@
     }
 
     /**
-     * Sets the overscan insets for a particular display.
-     */
-    public void setOverscan(int displayId, int left, int top, int right, int bottom) {
-        synchronized (mSyncRoot) {
-            LogicalDisplay display = mLogicalDisplays.get(displayId);
-            if (display != null) {
-                display.setOverscan(left, top, right, bottom);
-            }
-        }
-    }
-
-    /**
      * Called by the window manager to perform traversals while holding a
      * surface flinger transaction.
      */
@@ -362,13 +357,7 @@
         synchronized (mSyncRoot) {
             if (mAllDisplayBlankStateFromPowerManager != DISPLAY_BLANK_STATE_BLANKED) {
                 mAllDisplayBlankStateFromPowerManager = DISPLAY_BLANK_STATE_BLANKED;
-
-                final int count = mDisplayDevices.size();
-                for (int i = 0; i < count; i++) {
-                    DisplayDevice device = mDisplayDevices.get(i);
-                    device.blankLocked();
-                }
-
+                updateAllDisplayBlankingLocked();
                 scheduleTraversalLocked(false);
             }
         }
@@ -381,13 +370,7 @@
         synchronized (mSyncRoot) {
             if (mAllDisplayBlankStateFromPowerManager != DISPLAY_BLANK_STATE_UNBLANKED) {
                 mAllDisplayBlankStateFromPowerManager = DISPLAY_BLANK_STATE_UNBLANKED;
-
-                final int count = mDisplayDevices.size();
-                for (int i = 0; i < count; i++) {
-                    DisplayDevice device = mDisplayDevices.get(i);
-                    device.unblankLocked();
-                }
-
+                updateAllDisplayBlankingLocked();
                 scheduleTraversalLocked(false);
             }
         }
@@ -402,12 +385,21 @@
      */
     @Override // Binder call
     public DisplayInfo getDisplayInfo(int displayId) {
-        synchronized (mSyncRoot) {
-            LogicalDisplay display = mLogicalDisplays.get(displayId);
-            if (display != null) {
-                return display.getDisplayInfoLocked();
+        final int callingUid = Binder.getCallingUid();
+        final long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mSyncRoot) {
+                LogicalDisplay display = mLogicalDisplays.get(displayId);
+                if (display != null) {
+                    DisplayInfo info = display.getDisplayInfoLocked();
+                    if (info.hasAccess(callingUid)) {
+                        return info;
+                    }
+                }
+                return null;
             }
-            return null;
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
     }
 
@@ -416,13 +408,27 @@
      */
     @Override // Binder call
     public int[] getDisplayIds() {
-        synchronized (mSyncRoot) {
-            final int count = mLogicalDisplays.size();
-            int[] displayIds = new int[count];
-            for (int i = 0; i < count; i++) {
-                displayIds[i] = mLogicalDisplays.keyAt(i);
+        final int callingUid = Binder.getCallingUid();
+        final long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mSyncRoot) {
+                final int count = mLogicalDisplays.size();
+                int[] displayIds = new int[count];
+                int n = 0;
+                for (int i = 0; i < count; i++) {
+                    LogicalDisplay display = mLogicalDisplays.valueAt(i);
+                    DisplayInfo info = display.getDisplayInfoLocked();
+                    if (info.hasAccess(callingUid)) {
+                        displayIds[n++] = mLogicalDisplays.keyAt(i);
+                    }
+                }
+                if (n != count) {
+                    displayIds = Arrays.copyOfRange(displayIds, 0, n);
+                }
+                return displayIds;
             }
-            return displayIds;
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
     }
 
@@ -491,6 +497,48 @@
         }
     }
 
+    @Override
+    public void pauseWifiDisplay() {
+        if (mContext.checkCallingPermission(
+                android.Manifest.permission.CONFIGURE_WIFI_DISPLAY)
+                        != PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException("Requires CONFIGURE_WIFI_DISPLAY"
+                    + "permission to pause a wifi display session.");
+        }
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mSyncRoot) {
+                if (mWifiDisplayAdapter != null) {
+                    mWifiDisplayAdapter.requestPauseLocked();
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    @Override
+    public void resumeWifiDisplay() {
+        if (mContext.checkCallingPermission(
+                android.Manifest.permission.CONFIGURE_WIFI_DISPLAY)
+                        != PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException("Requires CONFIGURE_WIFI_DISPLAY"
+                    + "permission to resume a wifi display session.");
+        }
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mSyncRoot) {
+                if (mWifiDisplayAdapter != null) {
+                    mWifiDisplayAdapter.requestResumeLocked();
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
     @Override // Binder call
     public void disconnectWifiDisplay() {
         final long token = Binder.clearCallingIdentity();
@@ -569,6 +617,114 @@
                 == PackageManager.PERMISSION_GRANTED;
     }
 
+    @Override // Binder call
+    public int createVirtualDisplay(IBinder appToken, String packageName,
+            String name, int width, int height, int densityDpi, Surface surface, int flags) {
+        final int callingUid = Binder.getCallingUid();
+        if (!validatePackageName(callingUid, packageName)) {
+            throw new SecurityException("packageName must match the calling uid");
+        }
+        if (appToken == null) {
+            throw new IllegalArgumentException("appToken must not be null");
+        }
+        if (TextUtils.isEmpty(name)) {
+            throw new IllegalArgumentException("name must be non-null and non-empty");
+        }
+        if (width <= 0 || height <= 0 || densityDpi <= 0) {
+            throw new IllegalArgumentException("width, height, and densityDpi must be "
+                    + "greater than 0");
+        }
+        if (surface == null) {
+            throw new IllegalArgumentException("surface must not be null");
+        }
+        if ((flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) {
+            if (mContext.checkCallingPermission(android.Manifest.permission.CAPTURE_VIDEO_OUTPUT)
+                    != PackageManager.PERMISSION_GRANTED
+                    && mContext.checkCallingPermission(
+                            android.Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT)
+                            != PackageManager.PERMISSION_GRANTED) {
+                throw new SecurityException("Requires CAPTURE_VIDEO_OUTPUT or "
+                        + "CAPTURE_SECURE_VIDEO_OUTPUT permission to create a "
+                        + "public virtual display.");
+            }
+        }
+        if ((flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE) != 0) {
+            if (mContext.checkCallingPermission(
+                    android.Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT)
+                    != PackageManager.PERMISSION_GRANTED) {
+                throw new SecurityException("Requires CAPTURE_SECURE_VIDEO_OUTPUT "
+                        + "to create a secure virtual display.");
+            }
+        }
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mSyncRoot) {
+                if (mVirtualDisplayAdapter == null) {
+                    Slog.w(TAG, "Rejecting request to create private virtual display "
+                            + "because the virtual display adapter is not available.");
+                    return -1;
+                }
+
+                DisplayDevice device = mVirtualDisplayAdapter.createVirtualDisplayLocked(
+                        appToken, callingUid, packageName, name, width, height, densityDpi,
+                        surface, flags);
+                if (device == null) {
+                    return -1;
+                }
+
+                handleDisplayDeviceAddedLocked(device);
+                LogicalDisplay display = findLogicalDisplayForDeviceLocked(device);
+                if (display != null) {
+                    return display.getDisplayIdLocked();
+                }
+
+                // Something weird happened and the logical display was not created.
+                Slog.w(TAG, "Rejecting request to create virtual display "
+                        + "because the logical display was not created.");
+                mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken);
+                handleDisplayDeviceRemovedLocked(device);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+        return -1;
+    }
+
+    @Override // Binder call
+    public void releaseVirtualDisplay(IBinder appToken) {
+        final long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mSyncRoot) {
+                if (mVirtualDisplayAdapter == null) {
+                    return;
+                }
+
+                DisplayDevice device =
+                        mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken);
+                if (device != null) {
+                    handleDisplayDeviceRemovedLocked(device);
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    private boolean validatePackageName(int uid, String packageName) {
+        if (packageName != null) {
+            String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid);
+            if (packageNames != null) {
+                for (String n : packageNames) {
+                    if (n.equals(packageName)) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
     private void registerDefaultDisplayAdapter() {
         // Register default display adapter.
         synchronized (mSyncRoot) {
@@ -587,6 +743,7 @@
             if (shouldRegisterNonEssentialDisplayAdaptersLocked()) {
                 registerOverlayDisplayAdapterLocked();
                 registerWifiDisplayAdapterLocked();
+                registerVirtualDisplayAdapterLocked();
             }
         }
     }
@@ -607,6 +764,12 @@
         }
     }
 
+    private void registerVirtualDisplayAdapterLocked() {
+        mVirtualDisplayAdapter = new VirtualDisplayAdapter(
+                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
@@ -624,31 +787,25 @@
 
     private void handleDisplayDeviceAdded(DisplayDevice device) {
         synchronized (mSyncRoot) {
-            if (mDisplayDevices.contains(device)) {
-                Slog.w(TAG, "Attempted to add already added display device: "
-                        + device.getDisplayDeviceInfoLocked());
-                return;
-            }
-
-            Slog.i(TAG, "Display device added: " + device.getDisplayDeviceInfoLocked());
-
-            mDisplayDevices.add(device);
-            addLogicalDisplayLocked(device);
-            scheduleTraversalLocked(false);
-
-            // Blank or unblank the display immediately to match the state requested
-            // by the power manager (if known).
-            switch (mAllDisplayBlankStateFromPowerManager) {
-                case DISPLAY_BLANK_STATE_BLANKED:
-                    device.blankLocked();
-                    break;
-                case DISPLAY_BLANK_STATE_UNBLANKED:
-                    device.unblankLocked();
-                    break;
-            }
+            handleDisplayDeviceAddedLocked(device);
         }
     }
 
+    private void handleDisplayDeviceAddedLocked(DisplayDevice device) {
+        if (mDisplayDevices.contains(device)) {
+            Slog.w(TAG, "Attempted to add already added display device: "
+                    + device.getDisplayDeviceInfoLocked());
+            return;
+        }
+
+        Slog.i(TAG, "Display device added: " + device.getDisplayDeviceInfoLocked());
+
+        mDisplayDevices.add(device);
+        addLogicalDisplayLocked(device);
+        updateDisplayBlankingLocked(device);
+        scheduleTraversalLocked(false);
+    }
+
     private void handleDisplayDeviceChanged(DisplayDevice device) {
         synchronized (mSyncRoot) {
             if (!mDisplayDevices.contains(device)) {
@@ -668,17 +825,43 @@
 
     private void handleDisplayDeviceRemoved(DisplayDevice device) {
         synchronized (mSyncRoot) {
-            if (!mDisplayDevices.remove(device)) {
-                Slog.w(TAG, "Attempted to remove non-existent display device: "
-                        + device.getDisplayDeviceInfoLocked());
-                return;
+            handleDisplayDeviceRemovedLocked(device);
+        }
+    }
+    private void handleDisplayDeviceRemovedLocked(DisplayDevice device) {
+        if (!mDisplayDevices.remove(device)) {
+            Slog.w(TAG, "Attempted to remove non-existent display device: "
+                    + device.getDisplayDeviceInfoLocked());
+            return;
+        }
+
+        Slog.i(TAG, "Display device removed: " + device.getDisplayDeviceInfoLocked());
+
+        updateLogicalDisplaysLocked();
+        scheduleTraversalLocked(false);
+    }
+
+    private void updateAllDisplayBlankingLocked() {
+        final int count = mDisplayDevices.size();
+        for (int i = 0; i < count; i++) {
+            DisplayDevice device = mDisplayDevices.get(i);
+            updateDisplayBlankingLocked(device);
+        }
+    }
+
+    private void updateDisplayBlankingLocked(DisplayDevice device) {
+        // Blank or unblank the display immediately to match the state requested
+        // by the power manager (if known).
+        DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
+        if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) {
+            switch (mAllDisplayBlankStateFromPowerManager) {
+                case DISPLAY_BLANK_STATE_BLANKED:
+                    device.blankLocked();
+                    break;
+                case DISPLAY_BLANK_STATE_UNBLANKED:
+                    device.unblankLocked();
+                    break;
             }
-
-            Slog.i(TAG, "Display device removed: " + device.getDisplayDeviceInfoLocked());
-
-            mRemovedDisplayDevices.add(device);
-            updateLogicalDisplaysLocked();
-            scheduleTraversalLocked(false);
         }
     }
 
@@ -755,14 +938,6 @@
     }
 
     private void performTraversalInTransactionLocked() {
-        // Perform one last traversal for each removed display device.
-        final int removedCount = mRemovedDisplayDevices.size();
-        for (int i = 0; i < removedCount; i++) {
-            DisplayDevice device = mRemovedDisplayDevices.get(i);
-            device.performTraversalInTransactionLocked();
-        }
-        mRemovedDisplayDevices.clear();
-
         // Clear all viewports before configuring displays so that we can keep
         // track of which ones we have configured.
         clearViewportsLocked();
@@ -799,6 +974,11 @@
         synchronized (mSyncRoot) {
             LogicalDisplay display = mLogicalDisplays.get(displayId);
             if (display != null && display.hasContentLocked() != hasContent) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Display " + displayId + " hasContent flag changed: "
+                            + "hasContent=" + hasContent + ", inTraversal=" + inTraversal);
+                }
+
                 display.setHasContentLocked(hasContent);
                 scheduleTraversalLocked(inTraversal);
             }
@@ -811,13 +991,21 @@
     }
 
     private void configureDisplayInTransactionLocked(DisplayDevice device) {
+        DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
+        boolean isPrivate = (info.flags & DisplayDeviceInfo.FLAG_PRIVATE) != 0;
+
         // Find the logical display that the display device is showing.
+        // Private displays never mirror other displays.
         LogicalDisplay display = findLogicalDisplayForDeviceLocked(device);
-        if (display != null && !display.hasContentLocked()) {
-            display = null;
-        }
-        if (display == null) {
-            display = mLogicalDisplays.get(Display.DEFAULT_DISPLAY);
+        if (!isPrivate) {
+            if (display != null && !display.hasContentLocked()) {
+                // If the display does not have any content of its own, then
+                // automatically mirror the default logical display contents.
+                display = null;
+            }
+            if (display == null) {
+                display = mLogicalDisplays.get(Display.DEFAULT_DISPLAY);
+            }
         }
 
         // Apply the logical display configuration to the display device.
@@ -827,11 +1015,11 @@
                     + device.getDisplayDeviceInfoLocked());
             return;
         }
-        boolean isBlanked = (mAllDisplayBlankStateFromPowerManager == DISPLAY_BLANK_STATE_BLANKED);
+        boolean isBlanked = (mAllDisplayBlankStateFromPowerManager == DISPLAY_BLANK_STATE_BLANKED)
+                && (info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0;
         display.configureDisplayInTransactionLocked(device, isBlanked);
 
         // Update the viewports if needed.
-        DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
         if (!mDefaultViewport.valid
                 && (info.flags & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) {
             setViewportLocked(mDefaultViewport, display, device);
diff --git a/services/java/com/android/server/display/LocalDisplayAdapter.java b/services/java/com/android/server/display/LocalDisplayAdapter.java
index 475f27b..cb8f3e2 100644
--- a/services/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/java/com/android/server/display/LocalDisplayAdapter.java
@@ -155,6 +155,7 @@
                     mInfo.touch = DisplayDeviceInfo.TOUCH_INTERNAL;
                 } else {
                     mInfo.type = Display.TYPE_HDMI;
+                    mInfo.flags |= DisplayDeviceInfo.FLAG_PRESENTATION;
                     mInfo.name = getContext().getResources().getString(
                             com.android.internal.R.string.display_manager_hdmi_display_name);
                     mInfo.touch = DisplayDeviceInfo.TOUCH_EXTERNAL;
diff --git a/services/java/com/android/server/display/LogicalDisplay.java b/services/java/com/android/server/display/LogicalDisplay.java
index 424ec36..7e357c0 100644
--- a/services/java/com/android/server/display/LogicalDisplay.java
+++ b/services/java/com/android/server/display/LogicalDisplay.java
@@ -128,32 +128,24 @@
      *
      * @param info The logical display information, may be null.
      */
-    public void setDisplayInfoOverrideFromWindowManagerLocked(DisplayInfo info) {
+    public boolean setDisplayInfoOverrideFromWindowManagerLocked(DisplayInfo info) {
         if (info != null) {
             if (mOverrideDisplayInfo == null) {
                 mOverrideDisplayInfo = new DisplayInfo(info);
                 mInfo = null;
-            } else if (!mOverrideDisplayInfo.equals(info)) {
+                return true;
+            }
+            if (!mOverrideDisplayInfo.equals(info)) {
                 mOverrideDisplayInfo.copyFrom(info);
                 mInfo = null;
+                return true;
             }
         } else if (mOverrideDisplayInfo != null) {
             mOverrideDisplayInfo = null;
             mInfo = null;
+            return true;
         }
-    }
-
-    public void setOverscan(int left, int top, int right, int bottom) {
-        mInfo.overscanLeft = left;
-        mInfo.overscanTop = top;
-        mInfo.overscanRight = right;
-        mInfo.overscanBottom = bottom;
-        if (mOverrideDisplayInfo != null) {
-            mOverrideDisplayInfo.overscanLeft = left;
-            mOverrideDisplayInfo.overscanTop = top;
-            mOverrideDisplayInfo.overscanRight = right;
-            mOverrideDisplayInfo.overscanBottom = bottom;
-        }
+        return false;
     }
 
     /**
@@ -202,6 +194,12 @@
             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_SECURE) != 0) {
                 mBaseDisplayInfo.flags |= Display.FLAG_SECURE;
             }
+            if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_PRIVATE) != 0) {
+                mBaseDisplayInfo.flags |= Display.FLAG_PRIVATE;
+            }
+            if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_PRESENTATION) != 0) {
+                mBaseDisplayInfo.flags |= Display.FLAG_PRESENTATION;
+            }
             mBaseDisplayInfo.type = deviceInfo.type;
             mBaseDisplayInfo.address = deviceInfo.address;
             mBaseDisplayInfo.name = deviceInfo.name;
@@ -218,6 +216,8 @@
             mBaseDisplayInfo.smallestNominalAppHeight = deviceInfo.height;
             mBaseDisplayInfo.largestNominalAppWidth = deviceInfo.width;
             mBaseDisplayInfo.largestNominalAppHeight = deviceInfo.height;
+            mBaseDisplayInfo.ownerUid = deviceInfo.ownerUid;
+            mBaseDisplayInfo.ownerPackageName = deviceInfo.ownerPackageName;
 
             mPrimaryDisplayDeviceInfo = deviceInfo;
             mInfo = null;
diff --git a/services/java/com/android/server/display/OverlayDisplayAdapter.java b/services/java/com/android/server/display/OverlayDisplayAdapter.java
index a18352c..007acf7 100644
--- a/services/java/com/android/server/display/OverlayDisplayAdapter.java
+++ b/services/java/com/android/server/display/OverlayDisplayAdapter.java
@@ -59,7 +59,7 @@
     private static final int MAX_HEIGHT = 4096;
 
     private static final Pattern SETTING_PATTERN =
-            Pattern.compile("(\\d+)x(\\d+)/(\\d+)");
+            Pattern.compile("(\\d+)x(\\d+)/(\\d+)(,[a-z]+)*");
 
     private final Handler mUiHandler;
     private final ArrayList<OverlayDisplayHandle> mOverlays =
@@ -143,6 +143,7 @@
                     int width = Integer.parseInt(matcher.group(1), 10);
                     int height = Integer.parseInt(matcher.group(2), 10);
                     int densityDpi = Integer.parseInt(matcher.group(3), 10);
+                    String flagString = matcher.group(4);
                     if (width >= MIN_WIDTH && width <= MAX_WIDTH
                             && height >= MIN_HEIGHT && height <= MAX_HEIGHT
                             && densityDpi >= DisplayMetrics.DENSITY_LOW
@@ -152,13 +153,14 @@
                                 com.android.internal.R.string.display_manager_overlay_display_name,
                                 number);
                         int gravity = chooseOverlayGravity(number);
+                        boolean secure = flagString != null && flagString.contains(",secure");
 
                         Slog.i(TAG, "Showing overlay display device #" + number
                                 + ": name=" + name + ", width=" + width + ", height=" + height
-                                + ", densityDpi=" + densityDpi);
+                                + ", densityDpi=" + densityDpi + ", secure=" + secure);
 
                         mOverlays.add(new OverlayDisplayHandle(name,
-                                width, height, densityDpi, gravity));
+                                width, height, densityDpi, gravity, secure));
                         continue;
                     }
                 } catch (NumberFormatException ex) {
@@ -190,13 +192,14 @@
         private final int mHeight;
         private final float mRefreshRate;
         private final int mDensityDpi;
+        private final boolean mSecure;
 
         private Surface mSurface;
         private SurfaceTexture mSurfaceTexture;
         private DisplayDeviceInfo mInfo;
 
         public OverlayDisplayDevice(IBinder displayToken, String name,
-                int width, int height, float refreshRate, int densityDpi,
+                int width, int height, float refreshRate, int densityDpi, boolean secure,
                 SurfaceTexture surfaceTexture) {
             super(OverlayDisplayAdapter.this, displayToken);
             mName = name;
@@ -204,14 +207,17 @@
             mHeight = height;
             mRefreshRate = refreshRate;
             mDensityDpi = densityDpi;
+            mSecure = secure;
             mSurfaceTexture = surfaceTexture;
         }
 
-        public void clearSurfaceTextureLocked() {
-            if (mSurfaceTexture != null) {
-                mSurfaceTexture = null;
+        public void destroyLocked() {
+            mSurfaceTexture = null;
+            if (mSurface != null) {
+                mSurface.release();
+                mSurface = null;
             }
-            sendTraversalRequestLocked();
+            SurfaceControl.destroyDisplay(getDisplayTokenLocked());
         }
 
         @Override
@@ -221,12 +227,6 @@
                     mSurface = new Surface(mSurfaceTexture);
                 }
                 setSurfaceInTransactionLocked(mSurface);
-            } else {
-                setSurfaceInTransactionLocked(null);
-                if (mSurface != null) {
-                    mSurface.destroy();
-                    mSurface = null;
-                }
             }
         }
 
@@ -241,7 +241,10 @@
                 mInfo.densityDpi = mDensityDpi;
                 mInfo.xDpi = mDensityDpi;
                 mInfo.yDpi = mDensityDpi;
-                mInfo.flags = 0;
+                mInfo.flags = DisplayDeviceInfo.FLAG_PRESENTATION;
+                if (mSecure) {
+                    mInfo.flags |= DisplayDeviceInfo.FLAG_SECURE;
+                }
                 mInfo.type = Display.TYPE_OVERLAY;
                 mInfo.touch = DisplayDeviceInfo.TOUCH_NONE;
             }
@@ -261,17 +264,19 @@
         private final int mHeight;
         private final int mDensityDpi;
         private final int mGravity;
+        private final boolean mSecure;
 
         private OverlayDisplayWindow mWindow;
         private OverlayDisplayDevice mDevice;
 
         public OverlayDisplayHandle(String name,
-                int width, int height, int densityDpi, int gravity) {
+                int width, int height, int densityDpi, int gravity, boolean secure) {
             mName = name;
             mWidth = width;
             mHeight = height;
             mDensityDpi = densityDpi;
             mGravity = gravity;
+            mSecure = secure;
 
             mUiHandler.post(mShowRunnable);
         }
@@ -285,9 +290,9 @@
         @Override
         public void onWindowCreated(SurfaceTexture surfaceTexture, float refreshRate) {
             synchronized (getSyncRoot()) {
-                IBinder displayToken = SurfaceControl.createDisplay(mName, false);
+                IBinder displayToken = SurfaceControl.createDisplay(mName, mSecure);
                 mDevice = new OverlayDisplayDevice(displayToken, mName,
-                        mWidth, mHeight, refreshRate, mDensityDpi, surfaceTexture);
+                        mWidth, mHeight, refreshRate, mDensityDpi, mSecure, surfaceTexture);
 
                 sendDisplayDeviceEventLocked(mDevice, DISPLAY_DEVICE_EVENT_ADDED);
             }
@@ -298,7 +303,7 @@
         public void onWindowDestroyed() {
             synchronized (getSyncRoot()) {
                 if (mDevice != null) {
-                    mDevice.clearSurfaceTextureLocked();
+                    mDevice.destroyLocked();
                     sendDisplayDeviceEventLocked(mDevice, DISPLAY_DEVICE_EVENT_REMOVED);
                 }
             }
@@ -310,6 +315,7 @@
             pw.println("    mHeight=" + mHeight);
             pw.println("    mDensityDpi=" + mDensityDpi);
             pw.println("    mGravity=" + mGravity);
+            pw.println("    mSecure=" + mSecure);
 
             // Try to dump the window state.
             if (mWindow != null) {
@@ -324,7 +330,7 @@
             @Override
             public void run() {
                 OverlayDisplayWindow window = new OverlayDisplayWindow(getContext(),
-                        mName, mWidth, mHeight, mDensityDpi, mGravity,
+                        mName, mWidth, mHeight, mDensityDpi, mGravity, mSecure,
                         OverlayDisplayHandle.this);
                 window.show();
 
diff --git a/services/java/com/android/server/display/OverlayDisplayWindow.java b/services/java/com/android/server/display/OverlayDisplayWindow.java
index a0edced..f1dd60a 100644
--- a/services/java/com/android/server/display/OverlayDisplayWindow.java
+++ b/services/java/com/android/server/display/OverlayDisplayWindow.java
@@ -64,8 +64,9 @@
     private final int mHeight;
     private final int mDensityDpi;
     private final int mGravity;
+    private final boolean mSecure;
     private final Listener mListener;
-    private final String mTitle;
+    private String mTitle;
 
     private final DisplayManager mDisplayManager;
     private final WindowManager mWindowManager;
@@ -92,17 +93,23 @@
     private float mLiveScale = 1.0f;
 
     public OverlayDisplayWindow(Context context, String name,
-            int width, int height, int densityDpi, int gravity, Listener listener) {
+            int width, int height, int densityDpi, int gravity, boolean secure,
+            Listener listener) {
         mContext = context;
         mName = name;
         mWidth = width;
         mHeight = height;
         mDensityDpi = densityDpi;
         mGravity = gravity;
+        mSecure = secure;
         mListener = listener;
         mTitle = context.getResources().getString(
                 com.android.internal.R.string.display_manager_overlay_display_title,
                 mName, mWidth, mHeight, mDensityDpi);
+        if (secure) {
+            mTitle += context.getResources().getString(
+                    com.android.internal.R.string.display_manager_overlay_display_secure_suffix);
+        }
 
         mDisplayManager = (DisplayManager)context.getSystemService(
                 Context.DISPLAY_SERVICE);
@@ -197,6 +204,9 @@
                 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                 | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+        if (mSecure) {
+            mWindowParams.flags |= WindowManager.LayoutParams.FLAG_SECURE;
+        }
         if (DISABLE_MOVE_AND_RESIZE) {
             mWindowParams.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
         }
diff --git a/services/java/com/android/server/display/PersistentDataStore.java b/services/java/com/android/server/display/PersistentDataStore.java
index 105c253..67b3695 100644
--- a/services/java/com/android/server/display/PersistentDataStore.java
+++ b/services/java/com/android/server/display/PersistentDataStore.java
@@ -105,7 +105,8 @@
                 alias = mRememberedWifiDisplays.get(index).getDeviceAlias();
             }
             if (!Objects.equal(display.getDeviceAlias(), alias)) {
-                return new WifiDisplay(display.getDeviceAddress(), display.getDeviceName(), alias);
+                return new WifiDisplay(display.getDeviceAddress(), display.getDeviceName(),
+                        alias, display.isAvailable(), display.canConnect(), display.isRemembered());
             }
         }
         return display;
@@ -259,7 +260,8 @@
                 }
 
                 mRememberedWifiDisplays.add(
-                        new WifiDisplay(deviceAddress, deviceName, deviceAlias));
+                        new WifiDisplay(deviceAddress, deviceName, deviceAlias,
+                                false, false, false));
             }
         }
     }
diff --git a/services/java/com/android/server/display/VirtualDisplayAdapter.java b/services/java/com/android/server/display/VirtualDisplayAdapter.java
new file mode 100644
index 0000000..46d473c
--- /dev/null
+++ b/services/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -0,0 +1,177 @@
+/*
+ * 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.server.display;
+
+import android.content.Context;
+import android.hardware.display.DisplayManager;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.IBinder.DeathRecipient;
+import android.os.RemoteException;
+import android.util.ArrayMap;
+import android.util.Slog;
+import android.view.Display;
+import android.view.Surface;
+import android.view.SurfaceControl;
+
+/**
+ * A display adapter that provides virtual displays on behalf of applications.
+ * <p>
+ * Display adapters are guarded by the {@link DisplayManagerService.SyncRoot} lock.
+ * </p>
+ */
+final class VirtualDisplayAdapter extends DisplayAdapter {
+    static final String TAG = "VirtualDisplayAdapter";
+    static final boolean DEBUG = false;
+
+    private final ArrayMap<IBinder, VirtualDisplayDevice> mVirtualDisplayDevices =
+            new ArrayMap<IBinder, VirtualDisplayDevice>();
+
+    // Called with SyncRoot lock held.
+    public VirtualDisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
+            Context context, Handler handler, Listener listener) {
+        super(syncRoot, context, handler, listener, TAG);
+    }
+
+    public DisplayDevice createVirtualDisplayLocked(IBinder appToken,
+            int ownerUid, String ownerPackageName,
+            String name, int width, int height, int densityDpi, Surface surface, int flags) {
+        boolean secure = (flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE) != 0;
+        IBinder displayToken = SurfaceControl.createDisplay(name, secure);
+        VirtualDisplayDevice device = new VirtualDisplayDevice(displayToken, appToken,
+                ownerUid, ownerPackageName, name, width, height, densityDpi, surface, flags);
+
+        try {
+            appToken.linkToDeath(device, 0);
+        } catch (RemoteException ex) {
+            device.destroyLocked();
+            return null;
+        }
+
+        mVirtualDisplayDevices.put(appToken, device);
+
+        // Return the display device without actually sending the event indicating
+        // that it was added.  The caller will handle it.
+        return device;
+    }
+
+    public DisplayDevice releaseVirtualDisplayLocked(IBinder appToken) {
+        VirtualDisplayDevice device = mVirtualDisplayDevices.remove(appToken);
+        if (device != null) {
+            device.destroyLocked();
+            appToken.unlinkToDeath(device, 0);
+        }
+
+        // Return the display device that was removed without actually sending the
+        // event indicating that it was removed.  The caller will handle it.
+        return device;
+    }
+
+    private void handleBinderDiedLocked(IBinder appToken) {
+        VirtualDisplayDevice device = mVirtualDisplayDevices.remove(appToken);
+        if (device != null) {
+            Slog.i(TAG, "Virtual display device released because application token died: "
+                    + device.mOwnerPackageName);
+            device.destroyLocked();
+            sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_REMOVED);
+        }
+    }
+
+    private final class VirtualDisplayDevice extends DisplayDevice
+            implements DeathRecipient {
+        private final IBinder mAppToken;
+        private final int mOwnerUid;
+        final String mOwnerPackageName;
+        private final String mName;
+        private final int mWidth;
+        private final int mHeight;
+        private final int mDensityDpi;
+        private final int mFlags;
+
+        private Surface mSurface;
+        private DisplayDeviceInfo mInfo;
+
+        public VirtualDisplayDevice(IBinder displayToken,
+                IBinder appToken, int ownerUid, String ownerPackageName,
+                String name, int width, int height, int densityDpi, Surface surface, int flags) {
+            super(VirtualDisplayAdapter.this, displayToken);
+            mAppToken = appToken;
+            mOwnerUid = ownerUid;
+            mOwnerPackageName = ownerPackageName;
+            mName = name;
+            mWidth = width;
+            mHeight = height;
+            mDensityDpi = densityDpi;
+            mSurface = surface;
+            mFlags = flags;
+        }
+
+        @Override
+        public void binderDied() {
+            synchronized (getSyncRoot()) {
+                if (mSurface != null) {
+                    handleBinderDiedLocked(mAppToken);
+                }
+            }
+        }
+
+        public void destroyLocked() {
+            if (mSurface != null) {
+                mSurface.release();
+                mSurface = null;
+            }
+            SurfaceControl.destroyDisplay(getDisplayTokenLocked());
+        }
+
+        @Override
+        public void performTraversalInTransactionLocked() {
+            if (mSurface != null) {
+                setSurfaceInTransactionLocked(mSurface);
+            }
+        }
+
+        @Override
+        public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
+            if (mInfo == null) {
+                mInfo = new DisplayDeviceInfo();
+                mInfo.name = mName;
+                mInfo.width = mWidth;
+                mInfo.height = mHeight;
+                mInfo.refreshRate = 60;
+                mInfo.densityDpi = mDensityDpi;
+                mInfo.xDpi = mDensityDpi;
+                mInfo.yDpi = mDensityDpi;
+                mInfo.flags = 0;
+                if ((mFlags & DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC) == 0) {
+                    mInfo.flags |= DisplayDeviceInfo.FLAG_PRIVATE |
+                            DisplayDeviceInfo.FLAG_NEVER_BLANK;
+                }
+                if ((mFlags & DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE) != 0) {
+                    mInfo.flags |= DisplayDeviceInfo.FLAG_SECURE;
+                }
+                if ((mFlags & DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION) != 0) {
+                    mInfo.flags |= DisplayDeviceInfo.FLAG_PRESENTATION;
+                }
+                mInfo.type = Display.TYPE_VIRTUAL;
+                mInfo.touch = DisplayDeviceInfo.TOUCH_NONE;
+                mInfo.ownerUid = mOwnerUid;
+                mInfo.ownerPackageName = mOwnerPackageName;
+            }
+            return mInfo;
+        }
+    }
+}
diff --git a/services/java/com/android/server/display/WifiDisplayAdapter.java b/services/java/com/android/server/display/WifiDisplayAdapter.java
index b655b3a..f7bbdf8 100644
--- a/services/java/com/android/server/display/WifiDisplayAdapter.java
+++ b/services/java/com/android/server/display/WifiDisplayAdapter.java
@@ -30,6 +30,7 @@
 import android.content.res.Resources;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.WifiDisplay;
+import android.hardware.display.WifiDisplaySessionInfo;
 import android.hardware.display.WifiDisplayStatus;
 import android.media.RemoteDisplay;
 import android.os.Handler;
@@ -45,6 +46,8 @@
 
 import java.io.PrintWriter;
 import java.util.Arrays;
+import java.util.List;
+import java.util.ArrayList;
 
 import libcore.util.Objects;
 
@@ -88,8 +91,10 @@
     private int mScanState;
     private int mActiveDisplayState;
     private WifiDisplay mActiveDisplay;
+    private WifiDisplay[] mDisplays = WifiDisplay.EMPTY_ARRAY;
     private WifiDisplay[] mAvailableDisplays = WifiDisplay.EMPTY_ARRAY;
     private WifiDisplay[] mRememberedDisplays = WifiDisplay.EMPTY_ARRAY;
+    private WifiDisplaySessionInfo mSessionInfo;
 
     private boolean mPendingStatusChangeBroadcast;
     private boolean mPendingNotificationUpdate;
@@ -116,6 +121,7 @@
         pw.println("mScanState=" + mScanState);
         pw.println("mActiveDisplayState=" + mActiveDisplayState);
         pw.println("mActiveDisplay=" + mActiveDisplay);
+        pw.println("mDisplays=" + Arrays.toString(mDisplays));
         pw.println("mAvailableDisplays=" + Arrays.toString(mAvailableDisplays));
         pw.println("mRememberedDisplays=" + Arrays.toString(mRememberedDisplays));
         pw.println("mPendingStatusChangeBroadcast=" + mPendingStatusChangeBroadcast);
@@ -200,6 +206,36 @@
         return false;
     }
 
+    public void requestPauseLocked() {
+        if (DEBUG) {
+            Slog.d(TAG, "requestPauseLocked");
+        }
+
+        getHandler().post(new Runnable() {
+            @Override
+            public void run() {
+                if (mDisplayController != null) {
+                    mDisplayController.requestPause();
+                }
+            }
+        });
+      }
+
+    public void requestResumeLocked() {
+        if (DEBUG) {
+            Slog.d(TAG, "requestResumeLocked");
+        }
+
+        getHandler().post(new Runnable() {
+            @Override
+            public void run() {
+                if (mDisplayController != null) {
+                    mDisplayController.requestResume();
+                }
+            }
+        });
+    }
+
     public void requestDisconnectLocked() {
         if (DEBUG) {
             Slog.d(TAG, "requestDisconnectedLocked");
@@ -229,7 +265,8 @@
 
         WifiDisplay display = mPersistentDataStore.getRememberedWifiDisplay(address);
         if (display != null && !Objects.equal(display.getDeviceAlias(), alias)) {
-            display = new WifiDisplay(address, display.getDeviceName(), alias);
+            display = new WifiDisplay(address, display.getDeviceName(), alias,
+                    false, false, false);
             if (mPersistentDataStore.rememberWifiDisplay(display)) {
                 mPersistentDataStore.saveIfNeeded();
                 updateRememberedDisplaysLocked();
@@ -262,7 +299,7 @@
         if (mCurrentStatus == null) {
             mCurrentStatus = new WifiDisplayStatus(
                     mFeatureState, mScanState, mActiveDisplayState,
-                    mActiveDisplay, mAvailableDisplays, mRememberedDisplays);
+                    mActiveDisplay, mDisplays, mSessionInfo);
         }
 
         if (DEBUG) {
@@ -271,10 +308,36 @@
         return mCurrentStatus;
     }
 
+    private void updateDisplaysLocked() {
+        List<WifiDisplay> displays = new ArrayList<WifiDisplay>(
+                mAvailableDisplays.length + mRememberedDisplays.length);
+        boolean[] remembered = new boolean[mAvailableDisplays.length];
+        for (WifiDisplay d : mRememberedDisplays) {
+            boolean available = false;
+            for (int i = 0; i < mAvailableDisplays.length; i++) {
+                if (d.equals(mAvailableDisplays[i])) {
+                    remembered[i] = available = true;
+                    break;
+                }
+            }
+            if (!available) {
+                displays.add(new WifiDisplay(d.getDeviceAddress(), d.getDeviceName(),
+                        d.getDeviceAlias(), false, false, true));
+            }
+        }
+        for (int i = 0; i < mAvailableDisplays.length; i++) {
+            WifiDisplay d = mAvailableDisplays[i];
+            displays.add(new WifiDisplay(d.getDeviceAddress(), d.getDeviceName(),
+                    d.getDeviceAlias(), true, d.canConnect(), remembered[i]));
+        }
+        mDisplays = displays.toArray(WifiDisplay.EMPTY_ARRAY);
+    }
+
     private void updateRememberedDisplaysLocked() {
         mRememberedDisplays = mPersistentDataStore.getRememberedWifiDisplays();
         mActiveDisplay = mPersistentDataStore.applyWifiDisplayAlias(mActiveDisplay);
         mAvailableDisplays = mPersistentDataStore.applyWifiDisplayAliases(mAvailableDisplays);
+        updateDisplaysLocked();
     }
 
     private void fixRememberedDisplayNamesFromAvailableDisplaysLocked() {
@@ -321,7 +384,7 @@
         }
 
         boolean secure = (flags & RemoteDisplay.DISPLAY_FLAG_SECURE) != 0;
-        int deviceFlags = 0;
+        int deviceFlags = DisplayDeviceInfo.FLAG_PRESENTATION;
         if (secure) {
             deviceFlags |= DisplayDeviceInfo.FLAG_SECURE;
             if (mSupportsProtectedBuffers) {
@@ -343,7 +406,7 @@
 
     private void removeDisplayDeviceLocked() {
         if (mDisplayDevice != null) {
-            mDisplayDevice.clearSurfaceLocked();
+            mDisplayDevice.destroyLocked();
             sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_REMOVED);
             mDisplayDevice = null;
 
@@ -487,11 +550,18 @@
                 availableDisplays = mPersistentDataStore.applyWifiDisplayAliases(
                         availableDisplays);
 
-                if (mScanState != WifiDisplayStatus.SCAN_STATE_NOT_SCANNING
-                        || !Arrays.equals(mAvailableDisplays, availableDisplays)) {
+                // check if any of the available displays changed canConnect status
+                boolean changed = !Arrays.equals(mAvailableDisplays, availableDisplays);
+                for (int i = 0; !changed && i<availableDisplays.length; i++) {
+                    changed = availableDisplays[i].canConnect()
+                            != mAvailableDisplays[i].canConnect();
+                }
+
+                if (mScanState != WifiDisplayStatus.SCAN_STATE_NOT_SCANNING || changed) {
                     mScanState = WifiDisplayStatus.SCAN_STATE_NOT_SCANNING;
                     mAvailableDisplays = availableDisplays;
                     fixRememberedDisplayNamesFromAvailableDisplaysLocked();
+                    updateDisplaysLocked();
                     scheduleStatusChangedBroadcastLocked();
                 }
             }
@@ -542,6 +612,14 @@
         }
 
         @Override
+        public void onDisplaySessionInfo(WifiDisplaySessionInfo sessionInfo) {
+            synchronized (getSyncRoot()) {
+                mSessionInfo = sessionInfo;
+                scheduleStatusChangedBroadcastLocked();
+            }
+        }
+
+        @Override
         public void onDisplayChanged(WifiDisplay display) {
             synchronized (getSyncRoot()) {
                 display = mPersistentDataStore.applyWifiDisplayAlias(display);
@@ -595,9 +673,12 @@
             mSurface = surface;
         }
 
-        public void clearSurfaceLocked() {
-            mSurface = null;
-            sendTraversalRequestLocked();
+        public void destroyLocked() {
+            if (mSurface != null) {
+                mSurface.release();
+                mSurface = null;
+            }
+            SurfaceControl.destroyDisplay(getDisplayTokenLocked());
         }
 
         public void setNameLocked(String name) {
@@ -607,7 +688,9 @@
 
         @Override
         public void performTraversalInTransactionLocked() {
-            setSurfaceInTransactionLocked(mSurface);
+            if (mSurface != null) {
+                setSurfaceInTransactionLocked(mSurface);
+            }
         }
 
         @Override
diff --git a/services/java/com/android/server/display/WifiDisplayController.java b/services/java/com/android/server/display/WifiDisplayController.java
index 8c8b360..9a4cfb7 100644
--- a/services/java/com/android/server/display/WifiDisplayController.java
+++ b/services/java/com/android/server/display/WifiDisplayController.java
@@ -25,6 +25,7 @@
 import android.content.IntentFilter;
 import android.database.ContentObserver;
 import android.hardware.display.WifiDisplay;
+import android.hardware.display.WifiDisplaySessionInfo;
 import android.hardware.display.WifiDisplayStatus;
 import android.media.AudioManager;
 import android.media.RemoteDisplay;
@@ -76,6 +77,7 @@
     private static final int MAX_THROUGHPUT = 50;
     private static final int CONNECTION_TIMEOUT_SECONDS = 60;
     private static final int RTSP_TIMEOUT_SECONDS = 15;
+    private static final int RTSP_TIMEOUT_SECONDS_CERT_MODE = 120;
 
     private static final int DISCOVER_PEERS_MAX_RETRIES = 10;
     private static final int DISCOVER_PEERS_RETRY_DELAY_MILLIS = 500;
@@ -83,11 +85,6 @@
     private static final int CONNECT_MAX_RETRIES = 3;
     private static final int CONNECT_RETRY_DELAY_MILLIS = 500;
 
-    // A unique token to identify the remote submix that is managed by Wifi display.
-    // It must match what the media server uses when it starts recording the submix
-    // for transmission.  We use 0 although the actual value is currently ignored.
-    private static final int REMOTE_SUBMIX_ADDRESS = 0;
-
     private final Context mContext;
     private final Handler mHandler;
     private final Listener mListener;
@@ -95,8 +92,6 @@
     private final WifiP2pManager mWifiP2pManager;
     private final Channel mWifiP2pChannel;
 
-    private final AudioManager mAudioManager;
-
     private boolean mWifiP2pEnabled;
     private boolean mWfdEnabled;
     private boolean mWfdEnabling;
@@ -146,9 +141,6 @@
     // True if RTSP has connected.
     private boolean mRemoteDisplayConnected;
 
-    // True if the remote submix is enabled.
-    private boolean mRemoteSubmixOn;
-
     // The information we have most recently told WifiDisplayAdapter about.
     private WifiDisplay mAdvertisedDisplay;
     private Surface mAdvertisedDisplaySurface;
@@ -156,6 +148,12 @@
     private int mAdvertisedDisplayHeight;
     private int mAdvertisedDisplayFlags;
 
+    // Certification
+    private boolean mWifiDisplayCertMode;
+    private int mWifiDisplayWpsConfig = WpsInfo.INVALID;
+
+    private WifiP2pDevice mThisDevice;
+
     public WifiDisplayController(Context context, Handler handler, Listener listener) {
         mContext = context;
         mHandler = handler;
@@ -164,12 +162,11 @@
         mWifiP2pManager = (WifiP2pManager)context.getSystemService(Context.WIFI_P2P_SERVICE);
         mWifiP2pChannel = mWifiP2pManager.initialize(context, handler.getLooper(), null);
 
-        mAudioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
-
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
         intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
         intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
+        intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
         context.registerReceiver(mWifiP2pReceiver, intentFilter, null, mHandler);
 
         ContentObserver settingsObserver = new ContentObserver(mHandler) {
@@ -182,6 +179,10 @@
         final ContentResolver resolver = mContext.getContentResolver();
         resolver.registerContentObserver(Settings.Global.getUriFor(
                 Settings.Global.WIFI_DISPLAY_ON), false, settingsObserver);
+        resolver.registerContentObserver(Settings.Global.getUriFor(
+                Settings.Global.WIFI_DISPLAY_CERTIFICATION_ON), false, settingsObserver);
+        resolver.registerContentObserver(Settings.Global.getUriFor(
+                Settings.Global.WIFI_DISPLAY_WPS_CONFIG), false, settingsObserver);
         updateSettings();
     }
 
@@ -189,6 +190,14 @@
         final ContentResolver resolver = mContext.getContentResolver();
         mWifiDisplayOnSetting = Settings.Global.getInt(resolver,
                 Settings.Global.WIFI_DISPLAY_ON, 0) != 0;
+        mWifiDisplayCertMode = Settings.Global.getInt(resolver,
+                Settings.Global.WIFI_DISPLAY_CERTIFICATION_ON, 0) != 0;
+
+        mWifiDisplayWpsConfig = WpsInfo.INVALID;
+        if (mWifiDisplayCertMode) {
+            mWifiDisplayWpsConfig = Settings.Global.getInt(resolver,
+                  Settings.Global.WIFI_DISPLAY_WPS_CONFIG, WpsInfo.INVALID);
+        }
 
         updateWfdEnableState();
     }
@@ -211,7 +220,6 @@
         pw.println("mRemoteDisplay=" + mRemoteDisplay);
         pw.println("mRemoteDisplayInterface=" + mRemoteDisplayInterface);
         pw.println("mRemoteDisplayConnected=" + mRemoteDisplayConnected);
-        pw.println("mRemoteSubmixOn=" + mRemoteSubmixOn);
         pw.println("mAdvertisedDisplay=" + mAdvertisedDisplay);
         pw.println("mAdvertisedDisplaySurface=" + mAdvertisedDisplaySurface);
         pw.println("mAdvertisedDisplayWidth=" + mAdvertisedDisplayWidth);
@@ -236,6 +244,18 @@
         }
     }
 
+    public void requestPause() {
+        if (mRemoteDisplay != null) {
+            mRemoteDisplay.pause();
+        }
+    }
+
+    public void requestResume() {
+        if (mRemoteDisplay != null) {
+            mRemoteDisplay.resume();
+        }
+    }
+
     public void requestDisconnect() {
         disconnect();
     }
@@ -276,6 +296,25 @@
             }
         } else {
             // WFD should be disabled.
+            if (mWfdEnabled || mWfdEnabling) {
+                WifiP2pWfdInfo wfdInfo = new WifiP2pWfdInfo();
+                wfdInfo.setWfdEnabled(false);
+                mWifiP2pManager.setWFDInfo(mWifiP2pChannel, wfdInfo, new ActionListener() {
+                    @Override
+                    public void onSuccess() {
+                        if (DEBUG) {
+                            Slog.d(TAG, "Successfully set WFD info.");
+                        }
+                    }
+
+                    @Override
+                    public void onFailure(int reason) {
+                        if (DEBUG) {
+                            Slog.d(TAG, "Failed to set WFD info with reason " + reason + ".");
+                        }
+                    }
+                });
+            }
             mWfdEnabling = false;
             mWfdEnabled = false;
             reportFeatureState();
@@ -482,7 +521,6 @@
             mHandler.removeCallbacks(mRtspTimeout);
 
             mWifiP2pManager.setMiracastMode(WifiP2pManager.MIRACAST_DISABLED);
-            setRemoteSubmixOn(false);
             unadvertiseDisplay();
 
             // continue to next step
@@ -496,6 +534,7 @@
             Slog.i(TAG, "Disconnecting from Wifi display: " + mConnectedDevice.deviceName);
             mDisconnectingDevice = mConnectedDevice;
             mConnectedDevice = null;
+            mConnectedDeviceGroupInfo = null;
 
             unadvertiseDisplay();
 
@@ -562,8 +601,12 @@
             return; // wait for asynchronous callback
         }
 
-        // Step 4. If we wanted to disconnect, then mission accomplished.
+        // Step 4. If we wanted to disconnect, or we're updating after starting an
+        // autonomous GO, then mission accomplished.
         if (mDesiredDevice == null) {
+            if (mWifiDisplayCertMode) {
+                mListener.onDisplaySessionInfo(getSessionInfo(mConnectedDeviceGroupInfo, 0));
+            }
             unadvertiseDisplay();
             return; // done
         }
@@ -575,7 +618,9 @@
             mConnectingDevice = mDesiredDevice;
             WifiP2pConfig config = new WifiP2pConfig();
             WpsInfo wps = new WpsInfo();
-            if (mConnectingDevice.wpsPbcSupported()) {
+            if (mWifiDisplayWpsConfig != WpsInfo.INVALID) {
+                wps.setup = mWifiDisplayWpsConfig;
+            } else if (mConnectingDevice.wpsPbcSupported()) {
                 wps.setup = WpsInfo.PBC;
             } else if (mConnectingDevice.wpsDisplaySupported()) {
                 // We do keypad if peer does display
@@ -626,7 +671,6 @@
                 return; // done
             }
 
-            setRemoteSubmixOn(true);
             mWifiP2pManager.setMiracastMode(WifiP2pManager.MIRACAST_SOURCE);
 
             final WifiP2pDevice oldDevice = mConnectedDevice;
@@ -640,13 +684,18 @@
             mRemoteDisplay = RemoteDisplay.listen(iface, new RemoteDisplay.Listener() {
                 @Override
                 public void onDisplayConnected(Surface surface,
-                        int width, int height, int flags) {
+                        int width, int height, int flags, int session) {
                     if (mConnectedDevice == oldDevice && !mRemoteDisplayConnected) {
                         Slog.i(TAG, "Opened RTSP connection with Wifi display: "
                                 + mConnectedDevice.deviceName);
                         mRemoteDisplayConnected = true;
                         mHandler.removeCallbacks(mRtspTimeout);
 
+                        if (mWifiDisplayCertMode) {
+                            mListener.onDisplaySessionInfo(
+                                    getSessionInfo(mConnectedDeviceGroupInfo, session));
+                        }
+
                         final WifiDisplay display = createWifiDisplay(mConnectedDevice);
                         advertiseDisplay(display, surface, width, height, flags);
                     }
@@ -673,15 +722,29 @@
                 }
             }, mHandler);
 
-            mHandler.postDelayed(mRtspTimeout, RTSP_TIMEOUT_SECONDS * 1000);
+            // Use extended timeout value for certification, as some tests require user inputs
+            int rtspTimeout = mWifiDisplayCertMode ?
+                    RTSP_TIMEOUT_SECONDS_CERT_MODE : RTSP_TIMEOUT_SECONDS;
+
+            mHandler.postDelayed(mRtspTimeout, rtspTimeout * 1000);
         }
     }
 
-    private void setRemoteSubmixOn(boolean on) {
-        if (mRemoteSubmixOn != on) {
-            mRemoteSubmixOn = on;
-            mAudioManager.setRemoteSubmixOn(on, REMOTE_SUBMIX_ADDRESS);
+    private WifiDisplaySessionInfo getSessionInfo(WifiP2pGroup info, int session) {
+        if (info == null) {
+            return null;
         }
+        Inet4Address addr = getInterfaceAddress(info);
+        WifiDisplaySessionInfo sessionInfo = new WifiDisplaySessionInfo(
+                !info.getOwner().deviceAddress.equals(mThisDevice.deviceAddress),
+                session,
+                info.getOwner().deviceAddress + " " + info.getNetworkName(),
+                info.getPassphrase(),
+                (addr != null) ? addr.getHostAddress() : "");
+        if (DEBUG) {
+            Slog.d(TAG, sessionInfo.toString());
+        }
+        return sessionInfo;
     }
 
     private void handleStateChanged(boolean enabled) {
@@ -698,7 +761,7 @@
     private void handleConnectionChanged(NetworkInfo networkInfo) {
         mNetworkInfo = networkInfo;
         if (mWfdEnabled && networkInfo.isConnected()) {
-            if (mDesiredDevice != null) {
+            if (mDesiredDevice != null || mWifiDisplayCertMode) {
                 mWifiP2pManager.requestGroupInfo(mWifiP2pChannel, new GroupInfoListener() {
                     @Override
                     public void onGroupInfoAvailable(WifiP2pGroup info) {
@@ -720,6 +783,25 @@
                             return;
                         }
 
+                        if (mWifiDisplayCertMode) {
+                            boolean owner = info.getOwner().deviceAddress
+                                    .equals(mThisDevice.deviceAddress);
+                            if (owner && info.getClientList().isEmpty()) {
+                                // this is the case when we started Autonomous GO,
+                                // and no client has connected, save group info
+                                // and updateConnection()
+                                mConnectingDevice = mDesiredDevice = null;
+                                mConnectedDeviceGroupInfo = info;
+                                updateConnection();
+                            } else if (mConnectingDevice == null && mDesiredDevice == null) {
+                                // this is the case when we received an incoming connection
+                                // from the sink, update both mConnectingDevice and mDesiredDevice
+                                // then proceed to updateConnection() below
+                                mConnectingDevice = mDesiredDevice = owner ?
+                                        info.getClientList().iterator().next() : info.getOwner();
+                            }
+                        }
+
                         if (mConnectingDevice != null && mConnectingDevice == mDesiredDevice) {
                             Slog.i(TAG, "Connected to Wifi display: "
                                     + mConnectingDevice.deviceName);
@@ -734,6 +816,7 @@
                 });
             }
         } else {
+            mConnectedDeviceGroupInfo = null;
             disconnect();
 
             // After disconnection for a group, for some reason we have a tendency
@@ -897,7 +980,8 @@
     }
 
     private static WifiDisplay createWifiDisplay(WifiP2pDevice device) {
-        return new WifiDisplay(device.deviceAddress, device.deviceName, null);
+        return new WifiDisplay(device.deviceAddress, device.deviceName, null,
+                true, device.wfdInfo.isSessionAvailable(), false);
     }
 
     private final BroadcastReceiver mWifiP2pReceiver = new BroadcastReceiver() {
@@ -931,6 +1015,13 @@
                 }
 
                 handleConnectionChanged(networkInfo);
+            } else if (action.equals(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION)) {
+                mThisDevice = (WifiP2pDevice) intent.getParcelableExtra(
+                        WifiP2pManager.EXTRA_WIFI_P2P_DEVICE);
+                if (DEBUG) {
+                    Slog.d(TAG, "Received WIFI_P2P_THIS_DEVICE_CHANGED_ACTION: mThisDevice= "
+                            + mThisDevice);
+                }
             }
         }
     };
@@ -949,6 +1040,7 @@
         void onDisplayChanged(WifiDisplay display);
         void onDisplayConnected(WifiDisplay display,
                 Surface surface, int width, int height, int flags);
+        void onDisplaySessionInfo(WifiDisplaySessionInfo sessionInfo);
         void onDisplayDisconnected();
     }
 }
diff --git a/services/java/com/android/server/dreams/DreamManagerService.java b/services/java/com/android/server/dreams/DreamManagerService.java
index c9e0da5..b6e7781 100644
--- a/services/java/com/android/server/dreams/DreamManagerService.java
+++ b/services/java/com/android/server/dreams/DreamManagerService.java
@@ -73,7 +73,7 @@
         mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
     }
 
-    public void systemReady() {
+    public void systemRunning() {
         mContext.registerReceiver(new BroadcastReceiver() {
             @Override
             public void onReceive(Context context, Intent intent) {
@@ -86,7 +86,13 @@
 
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+        if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
+                != PackageManager.PERMISSION_GRANTED) {
+            pw.println("Permission Denial: can't dump DreamManager from pid="
+                    + Binder.getCallingPid()
+                    + ", uid=" + Binder.getCallingUid());
+            return;
+        }
 
         pw.println("DREAM MANAGER (dumpsys dreams)");
         pw.println();
diff --git a/services/java/com/android/server/firewall/AndFilter.java b/services/java/com/android/server/firewall/AndFilter.java
index e4276d0..13551de 100644
--- a/services/java/com/android/server/firewall/AndFilter.java
+++ b/services/java/com/android/server/firewall/AndFilter.java
@@ -16,8 +16,8 @@
 
 package com.android.server.firewall;
 
+import android.content.ComponentName;
 import android.content.Intent;
-import android.content.pm.ApplicationInfo;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -25,11 +25,11 @@
 
 class AndFilter extends FilterList {
     @Override
-    public boolean matches(IntentFirewall ifw, Intent intent, ApplicationInfo callerApp,
-            int callerUid, int callerPid, String resolvedType, ApplicationInfo resolvedApp) {
+    public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
+            int callerUid, int callerPid, String resolvedType, int receivingUid) {
         for (int i=0; i<children.size(); i++) {
-            if (!children.get(i).matches(ifw, intent, callerApp, callerUid, callerPid, resolvedType,
-                    resolvedApp)) {
+            if (!children.get(i).matches(ifw, resolvedComponent, intent, callerUid, callerPid,
+                    resolvedType, receivingUid)) {
                 return false;
             }
         }
diff --git a/services/java/com/android/server/firewall/CategoryFilter.java b/services/java/com/android/server/firewall/CategoryFilter.java
index 4938cb8..246c096 100644
--- a/services/java/com/android/server/firewall/CategoryFilter.java
+++ b/services/java/com/android/server/firewall/CategoryFilter.java
@@ -16,8 +16,8 @@
 
 package com.android.server.firewall;
 
+import android.content.ComponentName;
 import android.content.Intent;
-import android.content.pm.ApplicationInfo;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -34,8 +34,8 @@
     }
 
     @Override
-    public boolean matches(IntentFirewall ifw, Intent intent, ApplicationInfo callerApp,
-            int callerUid, int callerPid, String resolvedType, ApplicationInfo resolvedApp) {
+    public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
+            int callerUid, int callerPid, String resolvedType, int receivingUid) {
         Set<String> categories = intent.getCategories();
         if (categories == null) {
             return false;
diff --git a/services/java/com/android/server/firewall/Filter.java b/services/java/com/android/server/firewall/Filter.java
index 0e783e8..0a124f7 100644
--- a/services/java/com/android/server/firewall/Filter.java
+++ b/services/java/com/android/server/firewall/Filter.java
@@ -16,24 +16,21 @@
 
 package com.android.server.firewall;
 
+import android.content.ComponentName;
 import android.content.Intent;
-import android.content.pm.ApplicationInfo;
 
 interface Filter {
     /**
      * Does the given intent + context info match this filter?
      *
      * @param ifw The IntentFirewall instance
+     * @param resolvedComponent The actual component that the intent was resolved to
      * @param intent The intent being started/bound/broadcast
-     * @param callerApp An ApplicationInfo of an application in the caller's process. This may not
-     *                  be the specific app that is actually sending the intent. This also may be
-     *                  null, if the caller is the system process, or an unrecognized process (e.g.
-     *                  am start)
-     * @param callerUid
-     * @param callerPid
+     * @param callerUid The uid of the caller
+     * @param callerPid The pid of the caller
      * @param resolvedType The resolved mime type of the intent
-     * @param resolvedApp The application that contains the resolved component that the intent is
+     * @param receivingUid The uid of the component receiving the intent
      */
-    boolean matches(IntentFirewall ifw, Intent intent, ApplicationInfo callerApp,
-            int callerUid, int callerPid, String resolvedType, ApplicationInfo resolvedApp);
+    boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
+            int callerUid, int callerPid, String resolvedType, int receivingUid);
 }
diff --git a/services/java/com/android/server/firewall/IntentFirewall.java b/services/java/com/android/server/firewall/IntentFirewall.java
index 4496aae..aaa0b58 100644
--- a/services/java/com/android/server/firewall/IntentFirewall.java
+++ b/services/java/com/android/server/firewall/IntentFirewall.java
@@ -20,7 +20,6 @@
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
@@ -29,8 +28,10 @@
 import android.os.Handler;
 import android.os.Message;
 import android.os.RemoteException;
+import android.util.ArrayMap;
 import android.util.Slog;
 import android.util.Xml;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.XmlUtils;
 import com.android.server.EventLogTags;
 import com.android.server.IntentResolver;
@@ -42,15 +43,15 @@
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 
 public class IntentFirewall {
-    private static final String TAG = "IntentFirewall";
+    static final String TAG = "IntentFirewall";
 
-    // e.g. /data/system/ifw/ifw.xml or /data/secure/system/ifw/ifw.xml
-    private static final File RULES_FILE =
-            new File(Environment.getSystemSecureDirectory(), "ifw/ifw.xml");
+    // e.g. /data/system/ifw or /data/secure/system/ifw
+    private static final File RULES_DIR = new File(Environment.getSystemSecureDirectory(), "ifw");
 
     private static final int LOG_PACKAGES_MAX_LENGTH = 150;
     private static final int LOG_PACKAGES_SUFFICIENT_LENGTH = 125;
@@ -87,6 +88,7 @@
                 StringFilter.DATA,
                 StringFilter.HOST,
                 StringFilter.MIME_TYPE,
+                StringFilter.SCHEME,
                 StringFilter.PATH,
                 StringFilter.SSP,
 
@@ -106,12 +108,12 @@
 
     public IntentFirewall(AMSInterface ams) {
         mAms = ams;
-        File rulesFile = getRulesFile();
-        rulesFile.getParentFile().mkdirs();
+        File rulesDir = getRulesDir();
+        rulesDir.mkdirs();
 
-        readRules(rulesFile);
+        readRulesDir(rulesDir);
 
-        mObserver = new RuleObserver(rulesFile);
+        mObserver = new RuleObserver(rulesDir);
         mObserver.startWatching();
     }
 
@@ -119,16 +121,45 @@
      * This is called from ActivityManager to check if a start activity intent should be allowed.
      * It is assumed the caller is already holding the global ActivityManagerService lock.
      */
-    public boolean checkStartActivity(Intent intent, ApplicationInfo callerApp, int callerUid,
-            int callerPid, String resolvedType, ActivityInfo resolvedActivity) {
-        List<Rule> matchingRules = mActivityResolver.queryIntent(intent, resolvedType, false, 0);
+    public boolean checkStartActivity(Intent intent, int callerUid, int callerPid,
+            String resolvedType, ApplicationInfo resolvedApp) {
+        return checkIntent(mActivityResolver, intent.getComponent(), TYPE_ACTIVITY, intent,
+                callerUid, callerPid, resolvedType, resolvedApp.uid);
+    }
+
+    public boolean checkService(ComponentName resolvedService, Intent intent, int callerUid,
+            int callerPid, String resolvedType, ApplicationInfo resolvedApp) {
+        return checkIntent(mServiceResolver, resolvedService, TYPE_SERVICE, intent, callerUid,
+                callerPid, resolvedType, resolvedApp.uid);
+    }
+
+    public boolean checkBroadcast(Intent intent, int callerUid, int callerPid,
+            String resolvedType, int receivingUid) {
+        return checkIntent(mBroadcastResolver, intent.getComponent(), TYPE_BROADCAST, intent,
+                callerUid, callerPid, resolvedType, receivingUid);
+    }
+
+    public boolean checkIntent(FirewallIntentResolver resolver, ComponentName resolvedComponent,
+            int intentType, Intent intent, int callerUid, int callerPid, String resolvedType,
+            int receivingUid) {
         boolean log = false;
         boolean block = false;
 
-        for (int i=0; i< matchingRules.size(); i++) {
-            Rule rule = matchingRules.get(i);
-            if (rule.matches(this, intent, callerApp, callerUid, callerPid, resolvedType,
-                    resolvedActivity.applicationInfo)) {
+        // For the first pass, find all the rules that have at least one intent-filter or
+        // component-filter that matches this intent
+        List<Rule> candidateRules;
+        candidateRules = resolver.queryIntent(intent, resolvedType, false, 0);
+        if (candidateRules == null) {
+            candidateRules = new ArrayList<Rule>();
+        }
+        resolver.queryByComponent(resolvedComponent, candidateRules);
+
+        // For the second pass, try to match the potentially more specific conditions in each
+        // rule against the intent
+        for (int i=0; i<candidateRules.size(); i++) {
+            Rule rule = candidateRules.get(i);
+            if (rule.matches(this, resolvedComponent, intent, callerUid, callerPid, resolvedType,
+                    receivingUid)) {
                 block |= rule.getBlock();
                 log |= rule.getLog();
 
@@ -141,7 +172,7 @@
         }
 
         if (log) {
-            logIntent(TYPE_ACTIVITY, intent, callerUid, resolvedType);
+            logIntent(intentType, intent, callerUid, resolvedType);
         }
 
         return !block;
@@ -216,22 +247,58 @@
         return null;
     }
 
-    public static File getRulesFile() {
-        return RULES_FILE;
+    public static File getRulesDir() {
+        return RULES_DIR;
     }
 
     /**
-     * Reads rules from the given file and replaces our set of rules with the newly read rules
+     * Reads rules from all xml files (*.xml) in the given directory, and replaces our set of rules
+     * with the newly read rules.
+     *
+     * We only check for files ending in ".xml", to allow for temporary files that are atomically
+     * renamed to .xml
      *
      * All calls to this method from the file observer come through a handler and are inherently
      * serialized
      */
-    private void readRules(File rulesFile) {
+    private void readRulesDir(File rulesDir) {
         FirewallIntentResolver[] resolvers = new FirewallIntentResolver[3];
         for (int i=0; i<resolvers.length; i++) {
             resolvers[i] = new FirewallIntentResolver();
         }
 
+        File[] files = rulesDir.listFiles();
+        for (int i=0; i<files.length; i++) {
+            File file = files[i];
+
+            if (file.getName().endsWith(".xml")) {
+                readRules(file, resolvers);
+            }
+        }
+
+        Slog.i(TAG, "Read new rules (A:" + resolvers[TYPE_ACTIVITY].filterSet().size() +
+                " B:" + resolvers[TYPE_BROADCAST].filterSet().size() +
+                " S:" + resolvers[TYPE_SERVICE].filterSet().size() + ")");
+
+        synchronized (mAms.getAMSLock()) {
+            mActivityResolver = resolvers[TYPE_ACTIVITY];
+            mBroadcastResolver = resolvers[TYPE_BROADCAST];
+            mServiceResolver = resolvers[TYPE_SERVICE];
+        }
+    }
+
+    /**
+     * Reads rules from the given file and add them to the given resolvers
+     */
+    private void readRules(File rulesFile, FirewallIntentResolver[] resolvers) {
+        // some temporary lists to hold the rules while we parse the xml file, so that we can
+        // add the rules all at once, after we know there weren't any major structural problems
+        // with the xml file
+        List<List<Rule>> rulesByType = new ArrayList<List<Rule>>(3);
+        for (int i=0; i<3; i++) {
+            rulesByType.add(new ArrayList<Rule>());
+        }
+
         FileInputStream fis;
         try {
             fis = new FileInputStream(rulesFile);
@@ -247,8 +314,6 @@
 
             XmlUtils.beginDocument(parser, TAG_RULES);
 
-            int[] numRules = new int[3];
-
             int outerDepth = parser.getDepth();
             while (XmlUtils.nextElementWithin(parser, outerDepth)) {
                 int ruleType = -1;
@@ -265,41 +330,28 @@
                 if (ruleType != -1) {
                     Rule rule = new Rule();
 
-                    FirewallIntentResolver resolver = resolvers[ruleType];
+                    List<Rule> rules = rulesByType.get(ruleType);
 
                     // if we get an error while parsing a particular rule, we'll just ignore
                     // that rule and continue on with the next rule
                     try {
                         rule.readFromXml(parser);
                     } catch (XmlPullParserException ex) {
-                        Slog.e(TAG, "Error reading intent firewall rule", ex);
+                        Slog.e(TAG, "Error reading an intent firewall rule from " + rulesFile, ex);
                         continue;
                     }
 
-                    numRules[ruleType]++;
-
-                    for (int i=0; i<rule.getIntentFilterCount(); i++) {
-                        resolver.addFilter(rule.getIntentFilter(i));
-                    }
+                    rules.add(rule);
                 }
             }
-
-            Slog.i(TAG, "Read new rules (A:" + numRules[TYPE_ACTIVITY] +
-                    " B:" + numRules[TYPE_BROADCAST] + " S:" + numRules[TYPE_SERVICE] + ")");
-
-            synchronized (mAms.getAMSLock()) {
-                mActivityResolver = resolvers[TYPE_ACTIVITY];
-                mBroadcastResolver = resolvers[TYPE_BROADCAST];
-                mServiceResolver = resolvers[TYPE_SERVICE];
-            }
         } catch (XmlPullParserException ex) {
             // if there was an error outside of a specific rule, then there are probably
             // structural problems with the xml file, and we should completely ignore it
-            Slog.e(TAG, "Error reading intent firewall rules", ex);
-            clearRules();
+            Slog.e(TAG, "Error reading intent firewall rules from " + rulesFile, ex);
+            return;
         } catch (IOException ex) {
-            Slog.e(TAG, "Error reading intent firewall rules", ex);
-            clearRules();
+            Slog.e(TAG, "Error reading intent firewall rules from " + rulesFile, ex);
+            return;
         } finally {
             try {
                 fis.close();
@@ -307,21 +359,20 @@
                 Slog.e(TAG, "Error while closing " + rulesFile, ex);
             }
         }
-    }
 
-    /**
-     * Clears out all of our rules
-     *
-     * All calls to this method from the file observer come through a handler and are inherently
-     * serialized
-     */
-    private void clearRules() {
-        Slog.i(TAG, "Clearing all rules");
+        for (int ruleType=0; ruleType<rulesByType.size(); ruleType++) {
+            List<Rule> rules = rulesByType.get(ruleType);
+            FirewallIntentResolver resolver = resolvers[ruleType];
 
-        synchronized (mAms.getAMSLock())  {
-            mActivityResolver = new FirewallIntentResolver();
-            mBroadcastResolver = new FirewallIntentResolver();
-            mServiceResolver = new FirewallIntentResolver();
+            for (int ruleIndex=0; ruleIndex<rules.size(); ruleIndex++) {
+                Rule rule = rules.get(ruleIndex);
+                for (int i=0; i<rule.getIntentFilterCount(); i++) {
+                    resolver.addFilter(rule.getIntentFilter(i));
+                }
+                for (int i=0; i<rule.getComponentFilterCount(); i++) {
+                    resolver.addComponentFilter(rule.getComponentFilter(i), rule);
+                }
+            }
         }
     }
 
@@ -336,14 +387,35 @@
         return factory.newFilter(parser);
     }
 
+    /**
+     * Represents a single activity/service/broadcast rule within one of the xml files.
+     *
+     * Rules are matched against an incoming intent in two phases. The goal of the first phase
+     * is to select a subset of rules that might match a given intent.
+     *
+     * For the first phase, we use a combination of intent filters (via an IntentResolver)
+     * and component filters to select which rules to check. If a rule has multiple intent or
+     * component filters, only a single filter must match for the rule to be passed on to the
+     * second phase.
+     *
+     * In the second phase, we check the specific conditions in each rule against the values in the
+     * intent. All top level conditions (but not filters) in the rule must match for the rule as a
+     * whole to match.
+     *
+     * If the rule matches, then we block or log the intent, as specified by the rule. If multiple
+     * rules match, we combine the block/log flags from any matching rule.
+     */
     private static class Rule extends AndFilter {
         private static final String TAG_INTENT_FILTER = "intent-filter";
+        private static final String TAG_COMPONENT_FILTER = "component-filter";
+        private static final String ATTR_NAME = "name";
 
         private static final String ATTR_BLOCK = "block";
         private static final String ATTR_LOG = "log";
 
         private final ArrayList<FirewallIntentFilter> mIntentFilters =
                 new ArrayList<FirewallIntentFilter>(1);
+        private final ArrayList<ComponentName> mComponentFilters = new ArrayList<ComponentName>(0);
         private boolean block;
         private boolean log;
 
@@ -358,10 +430,25 @@
 
         @Override
         protected void readChild(XmlPullParser parser) throws IOException, XmlPullParserException {
-            if (parser.getName().equals(TAG_INTENT_FILTER)) {
+            String currentTag = parser.getName();
+
+            if (currentTag.equals(TAG_INTENT_FILTER)) {
                 FirewallIntentFilter intentFilter = new FirewallIntentFilter(this);
                 intentFilter.readFromXml(parser);
                 mIntentFilters.add(intentFilter);
+            } else if (currentTag.equals(TAG_COMPONENT_FILTER)) {
+                String componentStr = parser.getAttributeValue(null, ATTR_NAME);
+                if (componentStr == null) {
+                    throw new XmlPullParserException("Component name must be specified.",
+                            parser, null);
+                }
+
+                ComponentName componentName = ComponentName.unflattenFromString(componentStr);
+                if (componentName == null) {
+                    throw new XmlPullParserException("Invalid component name: " + componentStr);
+                }
+
+                mComponentFilters.add(componentName);
             } else {
                 super.readChild(parser);
             }
@@ -375,6 +462,13 @@
             return mIntentFilters.get(index);
         }
 
+        public int getComponentFilterCount() {
+            return mComponentFilters.size();
+        }
+
+        public ComponentName getComponentFilter(int index) {
+            return mComponentFilters.get(index);
+        }
         public boolean getBlock() {
             return block;
         }
@@ -419,56 +513,50 @@
             // there's no need to sort the results
             return;
         }
-    }
 
-    private static final int READ_RULES = 0;
-    private static final int CLEAR_RULES = 1;
+        public void queryByComponent(ComponentName componentName, List<Rule> candidateRules) {
+            Rule[] rules = mRulesByComponent.get(componentName);
+            if (rules != null) {
+                candidateRules.addAll(Arrays.asList(rules));
+            }
+        }
+
+        public void addComponentFilter(ComponentName componentName, Rule rule) {
+            Rule[] rules = mRulesByComponent.get(componentName);
+            rules = ArrayUtils.appendElement(Rule.class, rules, rule);
+            mRulesByComponent.put(componentName, rules);
+        }
+
+        private final ArrayMap<ComponentName, Rule[]> mRulesByComponent =
+                new ArrayMap<ComponentName, Rule[]>(0);
+    }
 
     final Handler mHandler = new Handler() {
         @Override
         public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case READ_RULES:
-                    readRules(getRulesFile());
-                    break;
-                case CLEAR_RULES:
-                    clearRules();
-                    break;
-            }
+            readRulesDir(getRulesDir());
         }
     };
 
     /**
-     * Monitors for the creation/deletion/modification of the rule file
+     * Monitors for the creation/deletion/modification of any .xml files in the rule directory
      */
     private class RuleObserver extends FileObserver {
-        // The file name we're monitoring, with no path component
-        private final String mMonitoredFile;
+        private static final int MONITORED_EVENTS = FileObserver.CREATE|FileObserver.MOVED_TO|
+                FileObserver.CLOSE_WRITE|FileObserver.DELETE|FileObserver.MOVED_FROM;
 
-        private static final int CREATED_FLAGS = FileObserver.CREATE|FileObserver.MOVED_TO|
-                FileObserver.CLOSE_WRITE;
-        private static final int DELETED_FLAGS = FileObserver.DELETE|FileObserver.MOVED_FROM;
-
-        public RuleObserver(File monitoredFile) {
-            super(monitoredFile.getParentFile().getAbsolutePath(), CREATED_FLAGS|DELETED_FLAGS);
-            mMonitoredFile = monitoredFile.getName();
+        public RuleObserver(File monitoredDir) {
+            super(monitoredDir.getAbsolutePath(), MONITORED_EVENTS);
         }
 
         @Override
         public void onEvent(int event, String path) {
-            if (path.equals(mMonitoredFile)) {
+            if (path.endsWith(".xml")) {
                 // we wait 250ms before taking any action on an event, in order to dedup multiple
                 // events. E.g. a delete event followed by a create event followed by a subsequent
-                // write+close event;
-                if ((event & CREATED_FLAGS) != 0) {
-                    mHandler.removeMessages(READ_RULES);
-                    mHandler.removeMessages(CLEAR_RULES);
-                    mHandler.sendEmptyMessageDelayed(READ_RULES, 250);
-                } else if ((event & DELETED_FLAGS) != 0) {
-                    mHandler.removeMessages(READ_RULES);
-                    mHandler.removeMessages(CLEAR_RULES);
-                    mHandler.sendEmptyMessageDelayed(CLEAR_RULES, 250);
-                }
+                // write+close event
+                mHandler.removeMessages(0);
+                mHandler.sendEmptyMessageDelayed(0, 250);
             }
         }
     }
@@ -509,4 +597,5 @@
             return false;
         }
     }
+
 }
diff --git a/services/java/com/android/server/firewall/NotFilter.java b/services/java/com/android/server/firewall/NotFilter.java
index f0fc337..09bf629 100644
--- a/services/java/com/android/server/firewall/NotFilter.java
+++ b/services/java/com/android/server/firewall/NotFilter.java
@@ -16,8 +16,8 @@
 
 package com.android.server.firewall;
 
+import android.content.ComponentName;
 import android.content.Intent;
-import android.content.pm.ApplicationInfo;
 import com.android.internal.util.XmlUtils;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -32,10 +32,10 @@
     }
 
     @Override
-    public boolean matches(IntentFirewall ifw, Intent intent, ApplicationInfo callerApp,
-            int callerUid, int callerPid, String resolvedType, ApplicationInfo resolvedApp) {
-        return !mChild.matches(ifw, intent, callerApp, callerUid, callerPid, resolvedType,
-                resolvedApp);
+    public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
+            int callerUid, int callerPid, String resolvedType, int receivingUid) {
+        return !mChild.matches(ifw, resolvedComponent, intent, callerUid, callerPid, resolvedType,
+                receivingUid);
     }
 
     public static final FilterFactory FACTORY = new FilterFactory("not") {
diff --git a/services/java/com/android/server/firewall/OrFilter.java b/services/java/com/android/server/firewall/OrFilter.java
index 72db31e..f6a6f22 100644
--- a/services/java/com/android/server/firewall/OrFilter.java
+++ b/services/java/com/android/server/firewall/OrFilter.java
@@ -16,8 +16,8 @@
 
 package com.android.server.firewall;
 
+import android.content.ComponentName;
 import android.content.Intent;
-import android.content.pm.ApplicationInfo;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -25,11 +25,11 @@
 
 class OrFilter extends FilterList {
     @Override
-    public boolean matches(IntentFirewall ifw, Intent intent, ApplicationInfo callerApp,
-            int callerUid, int callerPid, String resolvedType, ApplicationInfo resolvedApp) {
+    public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
+            int callerUid, int callerPid, String resolvedType, int receivingUid) {
         for (int i=0; i<children.size(); i++) {
-            if (children.get(i).matches(ifw, intent, callerApp, callerUid, callerPid, resolvedType,
-                    resolvedApp)) {
+            if (children.get(i).matches(ifw, resolvedComponent, intent, callerUid, callerPid,
+                    resolvedType, receivingUid)) {
                 return true;
             }
         }
diff --git a/services/java/com/android/server/firewall/PortFilter.java b/services/java/com/android/server/firewall/PortFilter.java
index fe7e085..84ace553 100644
--- a/services/java/com/android/server/firewall/PortFilter.java
+++ b/services/java/com/android/server/firewall/PortFilter.java
@@ -16,8 +16,8 @@
 
 package com.android.server.firewall;
 
+import android.content.ComponentName;
 import android.content.Intent;
-import android.content.pm.ApplicationInfo;
 import android.net.Uri;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -41,8 +41,8 @@
     }
 
     @Override
-    public boolean matches(IntentFirewall ifw, Intent intent, ApplicationInfo callerApp,
-            int callerUid, int callerPid, String resolvedType, ApplicationInfo resolvedApp) {
+    public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
+            int callerUid, int callerPid, String resolvedType, int receivingUid) {
         int port = -1;
         Uri uri = intent.getData();
         if (uri != null) {
diff --git a/services/java/com/android/server/firewall/SenderFilter.java b/services/java/com/android/server/firewall/SenderFilter.java
index 58bdd73..c0eee69 100644
--- a/services/java/com/android/server/firewall/SenderFilter.java
+++ b/services/java/com/android/server/firewall/SenderFilter.java
@@ -16,9 +16,14 @@
 
 package com.android.server.firewall;
 
+import android.app.AppGlobals;
+import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
 import android.os.Process;
+import android.os.RemoteException;
+import android.util.Slog;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -32,15 +37,21 @@
     private static final String VAL_SYSTEM_OR_SIGNATURE = "system|signature";
     private static final String VAL_USER_ID = "userId";
 
-    static boolean isSystemApp(ApplicationInfo callerApp, int callerUid, int callerPid) {
-        if (callerUid == Process.SYSTEM_UID ||
-                callerPid == Process.myPid()) {
+    static boolean isPrivilegedApp(int callerUid, int callerPid) {
+        if (callerUid == Process.SYSTEM_UID || callerUid == 0 ||
+                callerPid == Process.myPid() || callerPid == 0) {
             return true;
         }
-        if (callerApp == null) {
-            return false;
+
+        IPackageManager pm = AppGlobals.getPackageManager();
+        try {
+            return (pm.getFlagsForUid(callerUid) & ApplicationInfo.FLAG_PRIVILEGED) != 0;
+        } catch (RemoteException ex) {
+            Slog.e(IntentFirewall.TAG, "Remote exception while retrieving uid flags",
+                    ex);
         }
-        return (callerApp.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
+
+        return false;
     }
 
     public static final FilterFactory FACTORY = new FilterFactory("sender") {
@@ -67,45 +78,38 @@
 
     private static final Filter SIGNATURE = new Filter() {
         @Override
-        public boolean matches(IntentFirewall ifw, Intent intent, ApplicationInfo callerApp,
-                int callerUid, int callerPid, String resolvedType, ApplicationInfo resolvedApp) {
-            if (callerApp == null) {
-                return false;
-            }
-            return ifw.signaturesMatch(callerUid, resolvedApp.uid);
+        public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
+                int callerUid, int callerPid, String resolvedType, int receivingUid) {
+            return ifw.signaturesMatch(callerUid, receivingUid);
         }
     };
 
     private static final Filter SYSTEM = new Filter() {
         @Override
-        public boolean matches(IntentFirewall ifw, Intent intent, ApplicationInfo callerApp,
-                int callerUid, int callerPid, String resolvedType, ApplicationInfo resolvedApp) {
-            if (callerApp == null) {
-                // if callerApp is null, the caller is the system process
-                return false;
-            }
-            return isSystemApp(callerApp, callerUid, callerPid);
+        public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
+                int callerUid, int callerPid, String resolvedType, int receivingUid) {
+            return isPrivilegedApp(callerUid, callerPid);
         }
     };
 
     private static final Filter SYSTEM_OR_SIGNATURE = new Filter() {
         @Override
-        public boolean matches(IntentFirewall ifw, Intent intent, ApplicationInfo callerApp,
-                int callerUid, int callerPid, String resolvedType, ApplicationInfo resolvedApp) {
-            return isSystemApp(callerApp, callerUid, callerPid) ||
-                    ifw.signaturesMatch(callerUid, resolvedApp.uid);
+        public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
+                int callerUid, int callerPid, String resolvedType, int receivingUid) {
+            return isPrivilegedApp(callerUid, callerPid) ||
+                    ifw.signaturesMatch(callerUid, receivingUid);
         }
     };
 
     private static final Filter USER_ID = new Filter() {
         @Override
-        public boolean matches(IntentFirewall ifw, Intent intent, ApplicationInfo callerApp,
-                int callerUid, int callerPid, String resolvedType, ApplicationInfo resolvedApp) {
+        public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
+                int callerUid, int callerPid, String resolvedType, int receivingUid) {
             // This checks whether the caller is either the system process, or has the same user id
             // I.e. the same app, or an app that uses the same shared user id.
             // This is the same set of applications that would be able to access the component if
             // it wasn't exported.
-            return ifw.checkComponentPermission(null, callerPid, callerUid, resolvedApp.uid, false);
+            return ifw.checkComponentPermission(null, callerPid, callerUid, receivingUid, false);
         }
     };
 }
diff --git a/services/java/com/android/server/firewall/SenderPermissionFilter.java b/services/java/com/android/server/firewall/SenderPermissionFilter.java
index 310da20..caa65f3 100644
--- a/services/java/com/android/server/firewall/SenderPermissionFilter.java
+++ b/services/java/com/android/server/firewall/SenderPermissionFilter.java
@@ -16,8 +16,8 @@
 
 package com.android.server.firewall;
 
+import android.content.ComponentName;
 import android.content.Intent;
-import android.content.pm.ApplicationInfo;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -33,12 +33,12 @@
     }
 
     @Override
-    public boolean matches(IntentFirewall ifw, Intent intent, ApplicationInfo callerApp,
-            int callerUid, int callerPid, String resolvedType, ApplicationInfo resolvedApp) {
+    public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
+            int callerUid, int callerPid, String resolvedType, int receivingUid) {
         // We assume the component is exported here. If the component is not exported, then
         // ActivityManager would only resolve to this component for callers from the same uid.
         // In this case, it doesn't matter whether the component is exported or not.
-        return ifw.checkComponentPermission(mPermission, callerPid, callerUid, resolvedApp.uid,
+        return ifw.checkComponentPermission(mPermission, callerPid, callerUid, receivingUid,
                 true);
     }
 
diff --git a/services/java/com/android/server/firewall/StringFilter.java b/services/java/com/android/server/firewall/StringFilter.java
index ed5d3f3..28e99b3 100644
--- a/services/java/com/android/server/firewall/StringFilter.java
+++ b/services/java/com/android/server/firewall/StringFilter.java
@@ -18,7 +18,6 @@
 
 import android.content.ComponentName;
 import android.content.Intent;
-import android.content.pm.ApplicationInfo;
 import android.net.Uri;
 import android.os.PatternMatcher;
 import org.xmlpull.v1.XmlPullParser;
@@ -119,9 +118,9 @@
     protected abstract boolean matchesValue(String value);
 
     @Override
-    public boolean matches(IntentFirewall ifw, Intent intent, ApplicationInfo callerApp,
-            int callerUid, int callerPid, String resolvedType, ApplicationInfo resolvedApp) {
-        String value = mValueProvider.getValue(intent, callerApp, resolvedType, resolvedApp);
+    public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
+            int callerUid, int callerPid, String resolvedType, int receivingUid) {
+        String value = mValueProvider.getValue(resolvedComponent, intent, resolvedType);
         return matchesValue(value);
     }
 
@@ -135,8 +134,8 @@
             return StringFilter.readFromXml(this, parser);
         }
 
-        public abstract String getValue(Intent intent, ApplicationInfo callerApp,
-                String resolvedType, ApplicationInfo resolvedApp);
+        public abstract String getValue(ComponentName resolvedComponent, Intent intent,
+                String resolvedType);
     }
 
     private static class EqualsFilter extends StringFilter {
@@ -230,11 +229,10 @@
 
     public static final ValueProvider COMPONENT = new ValueProvider("component") {
         @Override
-        public String getValue(Intent intent, ApplicationInfo callerApp, String resolvedType,
-                ApplicationInfo resolvedApp) {
-            ComponentName cn = intent.getComponent();
-            if (cn != null) {
-                return cn.flattenToString();
+        public String getValue(ComponentName resolvedComponent, Intent intent,
+                String resolvedType) {
+            if (resolvedComponent != null) {
+                return resolvedComponent.flattenToString();
             }
             return null;
         }
@@ -242,11 +240,10 @@
 
     public static final ValueProvider COMPONENT_NAME = new ValueProvider("component-name") {
         @Override
-        public String getValue(Intent intent, ApplicationInfo callerApp, String resolvedType,
-                ApplicationInfo resolvedApp) {
-            ComponentName cn = intent.getComponent();
-            if (cn != null) {
-                return cn.getClassName();
+        public String getValue(ComponentName resolvedComponent, Intent intent,
+                String resolvedType) {
+            if (resolvedComponent != null) {
+                return resolvedComponent.getClassName();
             }
             return null;
         }
@@ -254,11 +251,10 @@
 
     public static final ValueProvider COMPONENT_PACKAGE = new ValueProvider("component-package") {
         @Override
-        public String getValue(Intent intent, ApplicationInfo callerApp, String resolvedType,
-                ApplicationInfo resolvedApp) {
-            ComponentName cn = intent.getComponent();
-            if (cn != null) {
-                return cn.getPackageName();
+        public String getValue(ComponentName resolvedComponent, Intent intent,
+                String resolvedType) {
+            if (resolvedComponent != null) {
+                return resolvedComponent.getPackageName();
             }
             return null;
         }
@@ -266,16 +262,16 @@
 
     public static final FilterFactory ACTION = new ValueProvider("action") {
         @Override
-        public String getValue(Intent intent, ApplicationInfo callerApp, String resolvedType,
-                ApplicationInfo resolvedApp) {
+        public String getValue(ComponentName resolvedComponent, Intent intent,
+                String resolvedType) {
             return intent.getAction();
         }
     };
 
     public static final ValueProvider DATA = new ValueProvider("data") {
         @Override
-        public String getValue(Intent intent, ApplicationInfo callerApp, String resolvedType,
-                ApplicationInfo resolvedApp) {
+        public String getValue(ComponentName resolvedComponent, Intent intent,
+                String resolvedType) {
             Uri data = intent.getData();
             if (data != null) {
                 return data.toString();
@@ -286,16 +282,16 @@
 
     public static final ValueProvider MIME_TYPE = new ValueProvider("mime-type") {
         @Override
-        public String getValue(Intent intent, ApplicationInfo callerApp, String resolvedType,
-                ApplicationInfo resolvedApp) {
+        public String getValue(ComponentName resolvedComponent, Intent intent,
+                String resolvedType) {
             return resolvedType;
         }
     };
 
     public static final ValueProvider SCHEME = new ValueProvider("scheme") {
         @Override
-        public String getValue(Intent intent, ApplicationInfo callerApp, String resolvedType,
-                ApplicationInfo resolvedApp) {
+        public String getValue(ComponentName resolvedComponent, Intent intent,
+                String resolvedType) {
             Uri data = intent.getData();
             if (data != null) {
                 return data.getScheme();
@@ -306,8 +302,8 @@
 
     public static final ValueProvider SSP = new ValueProvider("scheme-specific-part") {
         @Override
-        public String getValue(Intent intent, ApplicationInfo callerApp, String resolvedType,
-                ApplicationInfo resolvedApp) {
+        public String getValue(ComponentName resolvedComponent, Intent intent,
+                String resolvedType) {
             Uri data = intent.getData();
             if (data != null) {
                 return data.getSchemeSpecificPart();
@@ -318,8 +314,8 @@
 
     public static final ValueProvider HOST = new ValueProvider("host") {
         @Override
-        public String getValue(Intent intent, ApplicationInfo callerApp, String resolvedType,
-                ApplicationInfo resolvedApp) {
+        public String getValue(ComponentName resolvedComponent, Intent intent,
+                String resolvedType) {
             Uri data = intent.getData();
             if (data != null) {
                 return data.getHost();
@@ -330,8 +326,8 @@
 
     public static final ValueProvider PATH = new ValueProvider("path") {
         @Override
-        public String getValue(Intent intent, ApplicationInfo callerApp, String resolvedType,
-                ApplicationInfo resolvedApp) {
+        public String getValue(ComponentName resolvedComponent, Intent intent,
+                String resolvedType) {
             Uri data = intent.getData();
             if (data != null) {
                 return data.getPath();
diff --git a/services/java/com/android/server/input/InputManagerService.java b/services/java/com/android/server/input/InputManagerService.java
index 5e4907e..d749e6c 100644
--- a/services/java/com/android/server/input/InputManagerService.java
+++ b/services/java/com/android/server/input/InputManagerService.java
@@ -283,7 +283,7 @@
     }
 
     // TODO(BT) Pass in paramter for bluetooth system
-    public void systemReady() {
+    public void systemRunning() {
         if (DEBUG) {
             Slog.d(TAG, "System ready.");
         }
@@ -1292,8 +1292,9 @@
 
     // Native callback.
     private long notifyANR(InputApplicationHandle inputApplicationHandle,
-            InputWindowHandle inputWindowHandle) {
-        return mWindowManagerCallbacks.notifyANR(inputApplicationHandle, inputWindowHandle);
+            InputWindowHandle inputWindowHandle, String reason) {
+        return mWindowManagerCallbacks.notifyANR(
+                inputApplicationHandle, inputWindowHandle, reason);
     }
 
     // Native callback.
@@ -1477,7 +1478,7 @@
         public void notifyInputChannelBroken(InputWindowHandle inputWindowHandle);
 
         public long notifyANR(InputApplicationHandle inputApplicationHandle,
-                InputWindowHandle inputWindowHandle);
+                InputWindowHandle inputWindowHandle, String reason);
 
         public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn);
 
diff --git a/services/java/com/android/server/location/FlpHardwareProvider.java b/services/java/com/android/server/location/FlpHardwareProvider.java
new file mode 100644
index 0000000..fab84a8
--- /dev/null
+++ b/services/java/com/android/server/location/FlpHardwareProvider.java
@@ -0,0 +1,427 @@
+/*
+ * 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.server.location;
+
+import android.hardware.location.GeofenceHardware;
+import android.hardware.location.GeofenceHardwareImpl;
+import android.hardware.location.GeofenceHardwareRequestParcelable;
+import android.hardware.location.IFusedLocationHardware;
+import android.hardware.location.IFusedLocationHardwareSink;
+import android.location.IFusedGeofenceHardware;
+import android.location.FusedBatchOptions;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.location.LocationRequest;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.util.Log;
+
+/**
+ * This class is an interop layer for JVM types and the JNI code that interacts
+ * with the FLP HAL implementation.
+ *
+ * {@hide}
+ */
+public class FlpHardwareProvider {
+    private GeofenceHardwareImpl mGeofenceHardwareSink = null;
+    private IFusedLocationHardwareSink mLocationSink = null;
+
+    private static FlpHardwareProvider sSingletonInstance = null;
+
+    private final static String TAG = "FlpHardwareProvider";
+    private final Context mContext;
+    private final Object mLocationSinkLock = new Object();
+
+    // FlpHal result codes, they must be equal to the ones in fused_location.h
+    private static final int FLP_RESULT_SUCCESS = 0;
+    private static final int FLP_RESULT_ERROR = -1;
+    private static final int FLP_RESULT_INSUFFICIENT_MEMORY = -2;
+    private static final int FLP_RESULT_TOO_MANY_GEOFENCES = -3;
+    private static final int FLP_RESULT_ID_EXISTS = -4;
+    private static final int FLP_RESULT_ID_UNKNOWN = -5;
+    private static final int FLP_RESULT_INVALID_GEOFENCE_TRANSITION = -6;
+
+    public static FlpHardwareProvider getInstance(Context context) {
+        if (sSingletonInstance == null) {
+            sSingletonInstance = new FlpHardwareProvider(context);
+        }
+
+        return sSingletonInstance;
+    }
+
+    private FlpHardwareProvider(Context context) {
+        mContext = context;
+
+        // register for listening for passive provider data
+        LocationManager manager = (LocationManager) mContext.getSystemService(
+                Context.LOCATION_SERVICE);
+        final long minTime = 0;
+        final float minDistance = 0;
+        final boolean oneShot = false;
+        LocationRequest request = LocationRequest.createFromDeprecatedProvider(
+                LocationManager.PASSIVE_PROVIDER,
+                minTime,
+                minDistance,
+                oneShot);
+        // Don't keep track of this request since it's done on behalf of other clients
+        // (which are kept track of separately).
+        request.setHideFromAppOps(true);
+        manager.requestLocationUpdates(
+                request,
+                new NetworkLocationListener(),
+                Looper.myLooper());
+    }
+
+    public static boolean isSupported() {
+        return nativeIsSupported();
+    }
+
+    /**
+     * Private callback functions used by FLP HAL.
+     */
+    // FlpCallbacks members
+    private void onLocationReport(Location[] locations) {
+        for (Location location : locations) {
+            location.setProvider(LocationManager.FUSED_PROVIDER);
+            // set the elapsed time-stamp just as GPS provider does
+            location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
+        }
+
+        IFusedLocationHardwareSink sink;
+        synchronized (mLocationSinkLock) {
+            sink = mLocationSink;
+        }
+        try {
+            if (sink != null) {
+                sink.onLocationAvailable(locations);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "RemoteException calling onLocationAvailable");
+        }
+    }
+
+    // FlpDiagnosticCallbacks members
+    private void onDataReport(String data) {
+        IFusedLocationHardwareSink sink;
+        synchronized (mLocationSinkLock) {
+            sink = mLocationSink;
+        }
+        try {
+            if (mLocationSink != null) {
+                sink.onDiagnosticDataAvailable(data);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "RemoteException calling onDiagnosticDataAvailable");
+        }
+    }
+
+    // FlpGeofenceCallbacks members
+    private void onGeofenceTransition(
+            int geofenceId,
+            Location location,
+            int transition,
+            long timestamp,
+            int sourcesUsed) {
+        getGeofenceHardwareSink().reportGeofenceTransition(
+                geofenceId,
+                updateLocationInformation(location),
+                transition,
+                timestamp,
+                GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE,
+                sourcesUsed);
+    }
+
+    private void onGeofenceMonitorStatus(int status, int source, Location location) {
+        // allow the location to be optional in this event
+        Location updatedLocation = null;
+        if(location != null) {
+            updatedLocation = updateLocationInformation(location);
+        }
+
+        getGeofenceHardwareSink().reportGeofenceMonitorStatus(
+                GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE,
+                status,
+                updatedLocation,
+                source);
+    }
+
+    private void onGeofenceAdd(int geofenceId, int result) {
+        getGeofenceHardwareSink().reportGeofenceAddStatus(
+                geofenceId,
+                translateToGeofenceHardwareStatus(result));
+    }
+
+    private void onGeofenceRemove(int geofenceId, int result) {
+        getGeofenceHardwareSink().reportGeofenceRemoveStatus(
+                geofenceId,
+                translateToGeofenceHardwareStatus(result));
+    }
+
+    private void onGeofencePause(int geofenceId, int result) {
+        getGeofenceHardwareSink().reportGeofencePauseStatus(
+                geofenceId,
+                translateToGeofenceHardwareStatus(result));
+    }
+
+    private void onGeofenceResume(int geofenceId, int result) {
+        getGeofenceHardwareSink().reportGeofenceResumeStatus(
+                geofenceId,
+                translateToGeofenceHardwareStatus(result));
+    }
+
+    /**
+     * Private native methods accessing FLP HAL.
+     */
+    static { nativeClassInit(); }
+
+    // Core members
+    private static native void nativeClassInit();
+    private static native boolean nativeIsSupported();
+
+    // FlpLocationInterface members
+    private native void nativeInit();
+    private native int nativeGetBatchSize();
+    private native void nativeStartBatching(int requestId, FusedBatchOptions options);
+    private native void nativeUpdateBatchingOptions(int requestId, FusedBatchOptions optionsObject);
+    private native void nativeStopBatching(int id);
+    private native void nativeRequestBatchedLocation(int lastNLocations);
+    private native void nativeInjectLocation(Location location);
+    // TODO [Fix] sort out the lifetime of the instance
+    private native void nativeCleanup();
+
+    // FlpDiagnosticsInterface members
+    private native boolean nativeIsDiagnosticSupported();
+    private native void nativeInjectDiagnosticData(String data);
+
+    // FlpDeviceContextInterface members
+    private native boolean nativeIsDeviceContextSupported();
+    private native void nativeInjectDeviceContext(int deviceEnabledContext);
+
+    // FlpGeofencingInterface members
+    private native boolean nativeIsGeofencingSupported();
+    private native void nativeAddGeofences(
+            GeofenceHardwareRequestParcelable[] geofenceRequestsArray);
+    private native void nativePauseGeofence(int geofenceId);
+    private native void  nativeResumeGeofence(int geofenceId, int monitorTransitions);
+    private native void nativeModifyGeofenceOption(
+        int geofenceId,
+        int lastTransition,
+        int monitorTransitions,
+        int notificationResponsiveness,
+        int unknownTimer,
+        int sourcesToUse);
+    private native void nativeRemoveGeofences(int[] geofenceIdsArray);
+
+    /**
+     * Interface implementations for services built on top of this functionality.
+     */
+    public static final String LOCATION = "Location";
+    public static final String GEOFENCING = "Geofencing";
+
+    public IFusedLocationHardware getLocationHardware() {
+        nativeInit();
+        return mLocationHardware;
+    }
+
+    public IFusedGeofenceHardware getGeofenceHardware() {
+        nativeInit();
+        return mGeofenceHardwareService;
+    }
+
+    private final IFusedLocationHardware mLocationHardware = new IFusedLocationHardware.Stub() {
+        @Override
+        public void registerSink(IFusedLocationHardwareSink eventSink) {
+            synchronized (mLocationSinkLock) {
+                // only one sink is allowed at the moment
+                if (mLocationSink != null) {
+                    throw new RuntimeException(
+                            "IFusedLocationHardware does not support multiple sinks");
+                }
+
+                mLocationSink = eventSink;
+            }
+        }
+
+        @Override
+        public void unregisterSink(IFusedLocationHardwareSink eventSink) {
+            synchronized (mLocationSinkLock) {
+                // don't throw if the sink is not registered, simply make it a no-op
+                if (mLocationSink == eventSink) {
+                    mLocationSink = null;
+                }
+            }
+        }
+
+        @Override
+        public int getSupportedBatchSize() {
+            return nativeGetBatchSize();
+        }
+
+        @Override
+        public void startBatching(int requestId, FusedBatchOptions options) {
+            nativeStartBatching(requestId, options);
+        }
+
+        @Override
+        public void stopBatching(int requestId) {
+            nativeStopBatching(requestId);
+        }
+
+        @Override
+        public void updateBatchingOptions(int requestId, FusedBatchOptions options) {
+            nativeUpdateBatchingOptions(requestId, options);
+        }
+
+        @Override
+        public void requestBatchOfLocations(int batchSizeRequested) {
+            nativeRequestBatchedLocation(batchSizeRequested);
+        }
+
+        @Override
+        public boolean supportsDiagnosticDataInjection() {
+            return nativeIsDiagnosticSupported();
+        }
+
+        @Override
+        public void injectDiagnosticData(String data) {
+            nativeInjectDiagnosticData(data);
+        }
+
+        @Override
+        public boolean supportsDeviceContextInjection() {
+            return nativeIsDeviceContextSupported();
+        }
+
+        @Override
+        public void injectDeviceContext(int deviceEnabledContext) {
+            nativeInjectDeviceContext(deviceEnabledContext);
+        }
+    };
+
+    private final IFusedGeofenceHardware mGeofenceHardwareService =
+            new IFusedGeofenceHardware.Stub() {
+        @Override
+        public boolean isSupported() {
+            return nativeIsGeofencingSupported();
+        }
+
+        @Override
+        public void addGeofences(GeofenceHardwareRequestParcelable[] geofenceRequestsArray) {
+            nativeAddGeofences(geofenceRequestsArray);
+        }
+
+        @Override
+        public void removeGeofences(int[] geofenceIds) {
+            nativeRemoveGeofences(geofenceIds);
+        }
+
+        @Override
+        public void pauseMonitoringGeofence(int geofenceId) {
+            nativePauseGeofence(geofenceId);
+        }
+
+        @Override
+        public void resumeMonitoringGeofence(int geofenceId, int monitorTransitions) {
+            nativeResumeGeofence(geofenceId, monitorTransitions);
+        }
+
+        @Override
+        public void modifyGeofenceOptions(int geofenceId,
+                int lastTransition,
+                int monitorTransitions,
+                int notificationResponsiveness,
+                int unknownTimer,
+                int sourcesToUse) {
+            nativeModifyGeofenceOption(
+                    geofenceId,
+                    lastTransition,
+                    monitorTransitions,
+                    notificationResponsiveness,
+                    unknownTimer,
+                    sourcesToUse);
+        }
+    };
+
+    /**
+     * Internal classes and functions used by the provider.
+     */
+    private final class NetworkLocationListener implements LocationListener {
+        @Override
+        public void onLocationChanged(Location location) {
+            if (
+                !LocationManager.NETWORK_PROVIDER.equals(location.getProvider()) ||
+                !location.hasAccuracy()
+                ) {
+                return;
+            }
+
+            nativeInjectLocation(location);
+        }
+
+        @Override
+        public void onStatusChanged(String provider, int status, Bundle extras) { }
+
+        @Override
+        public void onProviderEnabled(String provider) { }
+
+        @Override
+        public void onProviderDisabled(String provider) { }
+    }
+
+    private GeofenceHardwareImpl getGeofenceHardwareSink() {
+        if (mGeofenceHardwareSink == null) {
+            mGeofenceHardwareSink = GeofenceHardwareImpl.getInstance(mContext);
+        }
+
+        return mGeofenceHardwareSink;
+    }
+
+    private static int translateToGeofenceHardwareStatus(int flpHalResult) {
+        switch(flpHalResult) {
+            case FLP_RESULT_SUCCESS:
+                return GeofenceHardware.GEOFENCE_SUCCESS;
+            case FLP_RESULT_ERROR:
+                return GeofenceHardware.GEOFENCE_FAILURE;
+            // TODO: uncomment this once the ERROR definition is marked public
+            //case FLP_RESULT_INSUFFICIENT_MEMORY:
+            //    return GeofenceHardware.GEOFENCE_ERROR_INSUFFICIENT_MEMORY;
+            case FLP_RESULT_TOO_MANY_GEOFENCES:
+                return GeofenceHardware.GEOFENCE_ERROR_TOO_MANY_GEOFENCES;
+            case FLP_RESULT_ID_EXISTS:
+                return GeofenceHardware.GEOFENCE_ERROR_ID_EXISTS;
+            case FLP_RESULT_ID_UNKNOWN:
+                return GeofenceHardware.GEOFENCE_ERROR_ID_UNKNOWN;
+            case FLP_RESULT_INVALID_GEOFENCE_TRANSITION:
+                return GeofenceHardware.GEOFENCE_ERROR_INVALID_TRANSITION;
+            default:
+                Log.e(TAG, String.format("Invalid FlpHal result code: %d", flpHalResult));
+                return GeofenceHardware.GEOFENCE_FAILURE;
+        }
+    }
+
+    private Location updateLocationInformation(Location location) {
+        location.setProvider(LocationManager.FUSED_PROVIDER);
+        // set the elapsed time-stamp just as GPS provider does
+        location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
+        return location;
+    }
+}
diff --git a/services/java/com/android/server/location/FusedLocationHardwareSecure.java b/services/java/com/android/server/location/FusedLocationHardwareSecure.java
new file mode 100644
index 0000000..389bd24
--- /dev/null
+++ b/services/java/com/android/server/location/FusedLocationHardwareSecure.java
@@ -0,0 +1,119 @@
+/*
+ * 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.server.location;
+
+import android.content.Context;
+import android.hardware.location.IFusedLocationHardware;
+import android.hardware.location.IFusedLocationHardwareSink;
+import android.location.FusedBatchOptions;
+import android.os.RemoteException;
+
+/**
+ * FusedLocationHardware decorator that adds permission checking.
+ * @hide
+ */
+public class FusedLocationHardwareSecure extends IFusedLocationHardware.Stub {
+    private final IFusedLocationHardware mLocationHardware;
+    private final Context mContext;
+    private final String mPermissionId;
+
+    public FusedLocationHardwareSecure(
+            IFusedLocationHardware locationHardware,
+            Context context,
+            String permissionId) {
+        mLocationHardware = locationHardware;
+        mContext = context;
+        mPermissionId = permissionId;
+    }
+
+    private void checkPermissions() {
+        mContext.enforceCallingPermission(
+                mPermissionId,
+                String.format(
+                        "Permission '%s' not granted to access FusedLocationHardware",
+                        mPermissionId));
+    }
+
+    @Override
+    public void registerSink(IFusedLocationHardwareSink eventSink) throws RemoteException {
+        checkPermissions();
+        mLocationHardware.registerSink(eventSink);
+    }
+
+    @Override
+    public void unregisterSink(IFusedLocationHardwareSink eventSink) throws RemoteException {
+        checkPermissions();
+        mLocationHardware.unregisterSink(eventSink);
+    }
+
+    @Override
+    public int getSupportedBatchSize() throws RemoteException {
+        checkPermissions();
+        return mLocationHardware.getSupportedBatchSize();
+    }
+
+    @Override
+    public void startBatching(int id, FusedBatchOptions batchOptions) throws RemoteException {
+        checkPermissions();
+        mLocationHardware.startBatching(id, batchOptions);
+    }
+
+    @Override
+    public void stopBatching(int id) throws RemoteException {
+        checkPermissions();
+        mLocationHardware.stopBatching(id);
+    }
+
+    @Override
+    public void updateBatchingOptions(
+            int id,
+            FusedBatchOptions batchoOptions
+            ) throws RemoteException {
+        checkPermissions();
+        mLocationHardware.updateBatchingOptions(id, batchoOptions);
+    }
+
+    @Override
+    public void requestBatchOfLocations(int batchSizeRequested) throws RemoteException {
+        checkPermissions();
+        mLocationHardware.requestBatchOfLocations(batchSizeRequested);
+    }
+
+    @Override
+    public boolean supportsDiagnosticDataInjection() throws RemoteException {
+        checkPermissions();
+        return mLocationHardware.supportsDiagnosticDataInjection();
+    }
+
+    @Override
+    public void injectDiagnosticData(String data) throws RemoteException {
+        checkPermissions();
+        mLocationHardware.injectDiagnosticData(data);
+    }
+
+    @Override
+    public boolean supportsDeviceContextInjection() throws RemoteException {
+        checkPermissions();
+        return mLocationHardware.supportsDeviceContextInjection();
+    }
+
+    @Override
+    public void injectDeviceContext(int deviceEnabledContext) throws RemoteException {
+        checkPermissions();
+        mLocationHardware.injectDeviceContext(deviceEnabledContext);
+    }
+}
diff --git a/services/java/com/android/server/location/FusedProxy.java b/services/java/com/android/server/location/FusedProxy.java
new file mode 100644
index 0000000..f7fac77
--- /dev/null
+++ b/services/java/com/android/server/location/FusedProxy.java
@@ -0,0 +1,128 @@
+/*
+ * 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 law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.location;
+
+import com.android.server.ServiceWatcher;
+
+import android.Manifest;
+import android.content.Context;
+import android.hardware.location.IFusedLocationHardware;
+import android.location.IFusedProvider;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * Proxy that helps bind GCore FusedProvider implementations to the Fused Hardware instances.
+ *
+ * @hide
+ */
+public final class FusedProxy {
+    private final String TAG = "FusedProxy";
+    private final ServiceWatcher mServiceWatcher;
+    private final FusedLocationHardwareSecure mLocationHardware;
+
+    /**
+     * Constructor of the class.
+     * This is private as the class follows a factory pattern for construction.
+     *
+     * @param context           The context needed for construction.
+     * @param handler           The handler needed for construction.
+     * @param locationHardware  The instance of the Fused location hardware assigned to the proxy.
+     */
+    private FusedProxy(
+            Context context,
+            Handler handler,
+            IFusedLocationHardware locationHardware,
+            int overlaySwitchResId,
+            int defaultServicePackageNameResId,
+            int initialPackageNameResId) {
+        mLocationHardware = new FusedLocationHardwareSecure(
+                locationHardware,
+                context,
+                Manifest.permission.LOCATION_HARDWARE);
+        Runnable newServiceWork = new Runnable() {
+            @Override
+            public void run() {
+                bindProvider(mLocationHardware);
+            }
+        };
+
+        // prepare the connection to the provider
+        mServiceWatcher = new ServiceWatcher(
+                context,
+                TAG,
+                "com.android.location.service.FusedProvider",
+                overlaySwitchResId,
+                defaultServicePackageNameResId,
+                initialPackageNameResId,
+                newServiceWork,
+                handler);
+    }
+
+    /**
+     * Creates an instance of the proxy and binds it to the appropriate FusedProvider.
+     *
+     * @param context           The context needed for construction.
+     * @param handler           The handler needed for construction.
+     * @param locationHardware  The instance of the Fused location hardware assigned to the proxy.
+     *
+     * @return An instance of the proxy if it could be bound, null otherwise.
+     */
+    public static FusedProxy createAndBind(
+            Context context,
+            Handler handler,
+            IFusedLocationHardware locationHardware,
+            int overlaySwitchResId,
+            int defaultServicePackageNameResId,
+            int initialPackageNameResId) {
+        FusedProxy fusedProxy = new FusedProxy(
+                context,
+                handler,
+                locationHardware,
+                overlaySwitchResId,
+                defaultServicePackageNameResId,
+                initialPackageNameResId);
+
+        // try to bind the Fused provider
+        if (!fusedProxy.mServiceWatcher.start()) {
+            return null;
+        }
+
+        return fusedProxy;
+    }
+
+    /**
+     * Helper function to bind the FusedLocationHardware to the appropriate FusedProvider instance.
+     *
+     * @param locationHardware  The FusedLocationHardware instance to use for the binding operation.
+     */
+    private void bindProvider(IFusedLocationHardware locationHardware) {
+        IFusedProvider provider = IFusedProvider.Stub.asInterface(mServiceWatcher.getBinder());
+
+        if (provider == null) {
+            Log.e(TAG, "No instance of FusedProvider found on FusedLocationHardware connected.");
+            return;
+        }
+
+        try {
+            provider.onFusedLocationHardwareChange(locationHardware);
+        } catch (RemoteException e) {
+            Log.e(TAG, e.toString());
+        }
+    }
+}
diff --git a/services/java/com/android/server/location/GeofenceProxy.java b/services/java/com/android/server/location/GeofenceProxy.java
index f6be27b..bbc1f47 100644
--- a/services/java/com/android/server/location/GeofenceProxy.java
+++ b/services/java/com/android/server/location/GeofenceProxy.java
@@ -22,6 +22,7 @@
 import android.hardware.location.IGeofenceHardware;
 import android.location.IGeofenceProvider;
 import android.location.IGpsGeofenceHardware;
+import android.location.IFusedGeofenceHardware;
 import android.content.Context;
 import android.os.Handler;
 import android.os.IBinder;
@@ -40,10 +41,15 @@
     private static final String TAG = "GeofenceProxy";
     private static final String SERVICE_ACTION =
             "com.android.location.service.GeofenceProvider";
-    private ServiceWatcher mServiceWatcher;
-    private Context mContext;
+    private final ServiceWatcher mServiceWatcher;
+    private final Context mContext;
+    private final IGpsGeofenceHardware mGpsGeofenceHardware;
+    private final IFusedGeofenceHardware mFusedGeofenceHardware;
+
+    private final Object mLock = new Object();
+
+    // Access to mGeofenceHardware needs to be synchronized by mLock.
     private IGeofenceHardware mGeofenceHardware;
-    private IGpsGeofenceHardware mGpsGeofenceHardware;
 
     private static final int GEOFENCE_PROVIDER_CONNECTED = 1;
     private static final int GEOFENCE_HARDWARE_CONNECTED = 2;
@@ -60,9 +66,11 @@
 
     public static GeofenceProxy createAndBind(Context context,
             int overlaySwitchResId, int defaultServicePackageNameResId,
-            int initialPackageNamesResId, Handler handler, IGpsGeofenceHardware gpsGeofence) {
+            int initialPackageNamesResId, Handler handler, IGpsGeofenceHardware gpsGeofence,
+            IFusedGeofenceHardware fusedGeofenceHardware) {
         GeofenceProxy proxy = new GeofenceProxy(context, overlaySwitchResId,
-            defaultServicePackageNameResId, initialPackageNamesResId, handler, gpsGeofence);
+            defaultServicePackageNameResId, initialPackageNamesResId, handler, gpsGeofence,
+            fusedGeofenceHardware);
         if (proxy.bindGeofenceProvider()) {
             return proxy;
         } else {
@@ -72,11 +80,13 @@
 
     private GeofenceProxy(Context context,
             int overlaySwitchResId, int defaultServicePackageNameResId,
-            int initialPackageNamesResId, Handler handler, IGpsGeofenceHardware gpsGeofence) {
+            int initialPackageNamesResId, Handler handler, IGpsGeofenceHardware gpsGeofence,
+            IFusedGeofenceHardware fusedGeofenceHardware) {
         mContext = context;
         mServiceWatcher = new ServiceWatcher(context, TAG, SERVICE_ACTION, overlaySwitchResId,
             defaultServicePackageNameResId, initialPackageNamesResId, mRunnable, handler);
         mGpsGeofenceHardware = gpsGeofence;
+        mFusedGeofenceHardware = fusedGeofenceHardware;
         bindHardwareGeofence();
     }
 
@@ -84,10 +94,6 @@
         return mServiceWatcher.start();
     }
 
-    private IGeofenceProvider getGeofenceProviderService() {
-        return IGeofenceProvider.Stub.asInterface(mServiceWatcher.getBinder());
-    }
-
     private void bindHardwareGeofence() {
         mContext.bindServiceAsUser(new Intent(mContext, GeofenceHardwareService.class),
                 mServiceConnection, Context.BIND_AUTO_CREATE, UserHandle.OWNER);
@@ -96,26 +102,34 @@
     private ServiceConnection mServiceConnection = new ServiceConnection() {
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {
-            mGeofenceHardware = IGeofenceHardware.Stub.asInterface(service);
-            mHandler.sendEmptyMessage(GEOFENCE_HARDWARE_CONNECTED);
+            synchronized (mLock) {
+                mGeofenceHardware = IGeofenceHardware.Stub.asInterface(service);
+                mHandler.sendEmptyMessage(GEOFENCE_HARDWARE_CONNECTED);
+            }
         }
 
         @Override
         public void onServiceDisconnected(ComponentName name) {
-            mGeofenceHardware = null;
-            mHandler.sendEmptyMessage(GEOFENCE_HARDWARE_DISCONNECTED);
+            synchronized (mLock) {
+                mGeofenceHardware = null;
+                mHandler.sendEmptyMessage(GEOFENCE_HARDWARE_DISCONNECTED);
+            }
         }
     };
 
-    private void setGeofenceHardwareInProvider() {
+    private void setGeofenceHardwareInProviderLocked() {
         try {
-            getGeofenceProviderService().setGeofenceHardware(mGeofenceHardware);
+            IGeofenceProvider provider = IGeofenceProvider.Stub.asInterface(
+                      mServiceWatcher.getBinder());
+            if (provider != null) {
+                provider.setGeofenceHardware(mGeofenceHardware);
+            }
         } catch (RemoteException e) {
-            Log.e(TAG, "Remote Exception: setGeofenceHardwareInProvider: " + e);
+            Log.e(TAG, "Remote Exception: setGeofenceHardwareInProviderLocked: " + e);
         }
     }
 
-    private void setGpsGeofence() {
+    private void setGpsGeofenceLocked() {
         try {
             mGeofenceHardware.setGpsGeofenceHardware(mGpsGeofenceHardware);
         } catch (RemoteException e) {
@@ -123,33 +137,48 @@
         }
     }
 
+    private void setFusedGeofenceLocked() {
+        try {
+            mGeofenceHardware.setFusedGeofenceHardware(mFusedGeofenceHardware);
+        } catch(RemoteException e) {
+            Log.e(TAG, "Error while connecting to GeofenceHardwareService");
+        }
+    }
 
     // This needs to be reworked, when more services get added,
     // Might need a state machine or add a framework utility class,
     private Handler mHandler = new Handler() {
-        private boolean mGeofenceHardwareConnected = false;
-        private boolean mGeofenceProviderConnected = false;
-
 
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case GEOFENCE_PROVIDER_CONNECTED:
-                    mGeofenceProviderConnected = true;
-                    if (mGeofenceHardwareConnected) {
-                        setGeofenceHardwareInProvider();
+                    synchronized (mLock) {
+                        if (mGeofenceHardware != null) {
+                            setGeofenceHardwareInProviderLocked();
+                        }
+                        // else: the geofence provider will be notified when the connection to
+                        // GeofenceHardwareService is established.
                     }
                     break;
                 case GEOFENCE_HARDWARE_CONNECTED:
-                    setGpsGeofence();
-                    mGeofenceHardwareConnected = true;
-                    if (mGeofenceProviderConnected) {
-                        setGeofenceHardwareInProvider();
+                    synchronized (mLock) {
+                        // Theoretically this won't happen because once the GeofenceHardwareService
+                        // is connected to, we won't lose connection to it because it's a system
+                        // service. But this check does make the code more robust.
+                        if (mGeofenceHardware != null) {
+                            setGpsGeofenceLocked();
+                            setFusedGeofenceLocked();
+                            setGeofenceHardwareInProviderLocked();
+                        }
                     }
                     break;
                 case GEOFENCE_HARDWARE_DISCONNECTED:
-                    mGeofenceHardwareConnected = false;
-                    setGeofenceHardwareInProvider();
+                    synchronized (mLock) {
+                        if (mGeofenceHardware == null) {
+                            setGeofenceHardwareInProviderLocked();
+                        }
+                    }
                     break;
             }
         }
diff --git a/services/java/com/android/server/location/GpsLocationProvider.java b/services/java/com/android/server/location/GpsLocationProvider.java
index 8c88cab..9c76c19 100644
--- a/services/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/java/com/android/server/location/GpsLocationProvider.java
@@ -24,9 +24,10 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.database.Cursor;
+import android.hardware.location.GeofenceHardware;
 import android.hardware.location.GeofenceHardwareImpl;
-import android.hardware.location.IGeofenceHardware;
 import android.location.Criteria;
+import android.location.FusedBatchOptions;
 import android.location.IGpsGeofenceHardware;
 import android.location.IGpsStatusListener;
 import android.location.IGpsStatusProvider;
@@ -41,6 +42,7 @@
 import android.net.NetworkInfo;
 import android.net.Uri;
 import android.os.AsyncTask;
+import android.os.BatteryStats;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
@@ -194,6 +196,17 @@
 
     private static final String PROPERTIES_FILE = "/etc/gps.conf";
 
+    private static final int GPS_GEOFENCE_UNAVAILABLE = 1<<0L;
+    private static final int GPS_GEOFENCE_AVAILABLE = 1<<1L;
+
+    // GPS Geofence errors. Should match gps.h constants.
+    private static final int GPS_GEOFENCE_OPERATION_SUCCESS = 0;
+    private static final int GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES = 100;
+    private static final int GPS_GEOFENCE_ERROR_ID_EXISTS  = -101;
+    private static final int GPS_GEOFENCE_ERROR_ID_UNKNOWN = -102;
+    private static final int GPS_GEOFENCE_ERROR_INVALID_TRANSITION = -103;
+    private static final int GPS_GEOFENCE_ERROR_GENERIC = -149;
+
     /** simpler wrapper for ProviderRequest + Worksource */
     private static class GpsRequest {
         public ProviderRequest request;
@@ -456,7 +469,8 @@
                 Context.APP_OPS_SERVICE));
 
         // Battery statistics service to be notified when GPS turns on or off
-        mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo"));
+        mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
+                BatteryStats.SERVICE_NAME));
 
         mProperties = new Properties();
         try {
@@ -498,8 +512,21 @@
             public void run() {
                 LocationManager locManager =
                         (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
-                locManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER,
-                        0, 0, new NetworkLocationListener(), mHandler.getLooper());                
+                final long minTime = 0;
+                final float minDistance = 0;
+                final boolean oneShot = false;
+                LocationRequest request = LocationRequest.createFromDeprecatedProvider(
+                        LocationManager.PASSIVE_PROVIDER,
+                        minTime,
+                        minDistance,
+                        oneShot);
+                // Don't keep track of this request since it's done on behalf of other clients
+                // (which are kept track of separately).
+                request.setHideFromAppOps(true);
+                locManager.requestLocationUpdates(
+                        request,
+                        new NetworkLocationListener(),
+                        mHandler.getLooper());
             }
         });
     }
@@ -890,7 +917,8 @@
             for (int i=0; i<newWork.size(); i++) {
                 try {
                     int uid = newWork.get(i);
-                    mAppOpsService.startOperation(AppOpsManager.OP_GPS, uid, newWork.getName(i));
+                    mAppOpsService.startOperation(AppOpsManager.getToken(mAppOpsService),
+                            AppOpsManager.OP_GPS, uid, newWork.getName(i));
                     if (uid != lastuid) {
                         lastuid = uid;
                         mBatteryStats.noteStartGps(uid);
@@ -907,7 +935,8 @@
             for (int i=0; i<goneWork.size(); i++) {
                 try {
                     int uid = goneWork.get(i);
-                    mAppOpsService.finishOperation(AppOpsManager.OP_GPS, uid, goneWork.getName(i));
+                    mAppOpsService.finishOperation(AppOpsManager.getToken(mAppOpsService),
+                            AppOpsManager.OP_GPS, uid, goneWork.getName(i));
                     if (uid != lastuid) {
                         lastuid = uid;
                         mBatteryStats.noteStopGps(uid);
@@ -1401,6 +1430,62 @@
     }
 
     /**
+     * Helper method to construct a location object.
+     */
+    private Location buildLocation(
+            int flags,
+            double latitude,
+            double longitude,
+            double altitude,
+            float speed,
+            float bearing,
+            float accuracy,
+            long timestamp) {
+        Location location = new Location(LocationManager.GPS_PROVIDER);
+        if((flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) {
+            location.setLatitude(latitude);
+            location.setLongitude(longitude);
+            location.setTime(timestamp);
+            location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
+        }
+        if((flags & LOCATION_HAS_ALTITUDE) == LOCATION_HAS_ALTITUDE) {
+            location.setAltitude(altitude);
+        }
+        if((flags & LOCATION_HAS_SPEED) == LOCATION_HAS_SPEED) {
+            location.setSpeed(speed);
+        }
+        if((flags & LOCATION_HAS_BEARING) == LOCATION_HAS_BEARING) {
+            location.setBearing(bearing);
+        }
+        if((flags & LOCATION_HAS_ACCURACY) == LOCATION_HAS_ACCURACY) {
+            location.setAccuracy(accuracy);
+        }
+        return location;
+    }
+
+    /**
+     * Converts the GPS HAL status to the internal Geofence Hardware status.
+     */
+    private int getGeofenceStatus(int status) {
+        switch(status) {
+            case GPS_GEOFENCE_OPERATION_SUCCESS:
+                return GeofenceHardware.GEOFENCE_SUCCESS;
+            case GPS_GEOFENCE_ERROR_GENERIC:
+                return GeofenceHardware.GEOFENCE_FAILURE;
+            case GPS_GEOFENCE_ERROR_ID_EXISTS:
+                return GeofenceHardware.GEOFENCE_ERROR_ID_EXISTS;
+            case GPS_GEOFENCE_ERROR_INVALID_TRANSITION:
+                return GeofenceHardware.GEOFENCE_ERROR_INVALID_TRANSITION;
+            case GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES:
+                return GeofenceHardware.GEOFENCE_ERROR_TOO_MANY_GEOFENCES;
+            case GPS_GEOFENCE_ERROR_ID_UNKNOWN:
+                return GeofenceHardware.GEOFENCE_ERROR_ID_UNKNOWN;
+            default:
+                return -1;
+        }
+    }
+
+    /**
      * Called from native to report GPS Geofence transition
      * All geofence callbacks are called on the same thread
      */
@@ -1410,8 +1495,22 @@
         if (mGeofenceHardwareImpl == null) {
             mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
         }
-        mGeofenceHardwareImpl.reportGpsGeofenceTransition(geofenceId, flags, latitude, longitude,
-           altitude, speed, bearing, accuracy, timestamp, transition, transitionTimestamp);
+        Location location = buildLocation(
+                flags,
+                latitude,
+                longitude,
+                altitude,
+                speed,
+                bearing,
+                accuracy,
+                timestamp);
+        mGeofenceHardwareImpl.reportGeofenceTransition(
+                geofenceId,
+                location,
+                transition,
+                transitionTimestamp,
+                GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
+                FusedBatchOptions.SourceTechnologies.GNSS);
     }
 
     /**
@@ -1423,8 +1522,24 @@
         if (mGeofenceHardwareImpl == null) {
             mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
         }
-        mGeofenceHardwareImpl.reportGpsGeofenceStatus(status, flags, latitude, longitude, altitude,
-            speed, bearing, accuracy, timestamp);
+        Location location = buildLocation(
+                flags,
+                latitude,
+                longitude,
+                altitude,
+                speed,
+                bearing,
+                accuracy,
+                timestamp);
+        int monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_UNAVAILABLE;
+        if(status == GPS_GEOFENCE_AVAILABLE) {
+            monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE;
+        }
+        mGeofenceHardwareImpl.reportGeofenceMonitorStatus(
+                GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
+                monitorStatus,
+                location,
+                FusedBatchOptions.SourceTechnologies.GNSS);
     }
 
     /**
@@ -1434,7 +1549,7 @@
         if (mGeofenceHardwareImpl == null) {
             mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
         }
-        mGeofenceHardwareImpl.reportGpsGeofenceAddStatus(geofenceId, status);
+        mGeofenceHardwareImpl.reportGeofenceAddStatus(geofenceId, getGeofenceStatus(status));
     }
 
     /**
@@ -1444,7 +1559,7 @@
         if (mGeofenceHardwareImpl == null) {
             mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
         }
-        mGeofenceHardwareImpl.reportGpsGeofenceRemoveStatus(geofenceId, status);
+        mGeofenceHardwareImpl.reportGeofenceRemoveStatus(geofenceId, getGeofenceStatus(status));
     }
 
     /**
@@ -1454,7 +1569,7 @@
         if (mGeofenceHardwareImpl == null) {
             mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
         }
-        mGeofenceHardwareImpl.reportGpsGeofencePauseStatus(geofenceId, status);
+        mGeofenceHardwareImpl.reportGeofencePauseStatus(geofenceId, getGeofenceStatus(status));
     }
 
     /**
@@ -1464,7 +1579,7 @@
         if (mGeofenceHardwareImpl == null) {
             mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
         }
-        mGeofenceHardwareImpl.reportGpsGeofenceResumeStatus(geofenceId, status);
+        mGeofenceHardwareImpl.reportGeofenceResumeStatus(geofenceId, getGeofenceStatus(status));
     }
 
     //=============================================================
diff --git a/services/java/com/android/server/net/BaseNetworkObserver.java b/services/java/com/android/server/net/BaseNetworkObserver.java
deleted file mode 100644
index 8b2aa5d..0000000
--- a/services/java/com/android/server/net/BaseNetworkObserver.java
+++ /dev/null
@@ -1,57 +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.server.net;
-
-import android.net.INetworkManagementEventObserver;
-
-/**
- * Base {@link INetworkManagementEventObserver} that provides no-op
- * implementations which can be overridden.
- *
- * @hide
- */
-public class BaseNetworkObserver extends INetworkManagementEventObserver.Stub {
-    @Override
-    public void interfaceStatusChanged(String iface, boolean up) {
-        // default no-op
-    }
-
-    @Override
-    public void interfaceRemoved(String iface) {
-        // default no-op
-    }
-
-    @Override
-    public void interfaceLinkStateChanged(String iface, boolean up) {
-        // default no-op
-    }
-
-    @Override
-    public void interfaceAdded(String iface) {
-        // default no-op
-    }
-
-    @Override
-    public void interfaceClassDataActivityChanged(String label, boolean active) {
-        // default no-op
-    }
-
-    @Override
-    public void limitReached(String limitName, String iface) {
-        // default no-op
-    }
-}
diff --git a/services/java/com/android/server/net/LockdownVpnTracker.java b/services/java/com/android/server/net/LockdownVpnTracker.java
index e251925..a2e9d676 100644
--- a/services/java/com/android/server/net/LockdownVpnTracker.java
+++ b/services/java/com/android/server/net/LockdownVpnTracker.java
@@ -26,6 +26,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.net.LinkProperties;
+import android.net.LinkAddress;
 import android.net.NetworkInfo;
 import android.net.NetworkInfo.DetailedState;
 import android.net.NetworkInfo.State;
@@ -44,6 +45,8 @@
 import com.android.server.EventLogTags;
 import com.android.server.connectivity.Vpn;
 
+import java.util.List;
+
 /**
  * State tracker for lockdown mode. Watches for normal {@link NetworkInfo} to be
  * connected and kicks off VPN connection, managing any required {@code netd}
@@ -73,7 +76,7 @@
 
     private String mAcceptedEgressIface;
     private String mAcceptedIface;
-    private String mAcceptedSourceAddr;
+    private List<LinkAddress> mAcceptedSourceAddr;
 
     private int mErrorCount;
 
@@ -148,8 +151,13 @@
                 showNotification(R.string.vpn_lockdown_connecting, R.drawable.vpn_disconnected);
 
                 mAcceptedEgressIface = egressProp.getInterfaceName();
-                mVpn.startLegacyVpn(mProfile, KeyStore.getInstance(), egressProp);
-
+                try {
+                    mVpn.startLegacyVpn(mProfile, KeyStore.getInstance(), egressProp);
+                } catch (IllegalStateException e) {
+                    mAcceptedEgressIface = null;
+                    Slog.e(TAG, "Failed to start VPN", e);
+                    showNotification(R.string.vpn_lockdown_error, R.drawable.vpn_disconnected);
+                }
             } else {
                 Slog.e(TAG, "Invalid VPN profile; requires IP-based server and DNS");
                 showNotification(R.string.vpn_lockdown_error, R.drawable.vpn_disconnected);
@@ -157,14 +165,15 @@
 
         } else if (vpnInfo.isConnected() && vpnConfig != null) {
             final String iface = vpnConfig.interfaze;
-            final String sourceAddr = vpnConfig.addresses;
+            final List<LinkAddress> sourceAddrs = vpnConfig.addresses;
 
             if (TextUtils.equals(iface, mAcceptedIface)
-                    && TextUtils.equals(sourceAddr, mAcceptedSourceAddr)) {
+                  && sourceAddrs.equals(mAcceptedSourceAddr)) {
                 return;
             }
 
-            Slog.d(TAG, "VPN connected using iface=" + iface + ", sourceAddr=" + sourceAddr);
+            Slog.d(TAG, "VPN connected using iface=" + iface +
+                    ", sourceAddr=" + sourceAddrs.toString());
             EventLogTags.writeLockdownVpnConnected(egressType);
             showNotification(R.string.vpn_lockdown_connected, R.drawable.vpn_connected);
 
@@ -172,11 +181,13 @@
                 clearSourceRulesLocked();
 
                 mNetService.setFirewallInterfaceRule(iface, true);
-                mNetService.setFirewallEgressSourceRule(sourceAddr, true);
+                for (LinkAddress addr : sourceAddrs) {
+                    mNetService.setFirewallEgressSourceRule(addr.toString(), true);
+                }
 
                 mErrorCount = 0;
                 mAcceptedIface = iface;
-                mAcceptedSourceAddr = sourceAddr;
+                mAcceptedSourceAddr = sourceAddrs;
             } catch (RemoteException e) {
                 throw new RuntimeException("Problem setting firewall rules", e);
             }
@@ -258,7 +269,9 @@
                 mAcceptedIface = null;
             }
             if (mAcceptedSourceAddr != null) {
-                mNetService.setFirewallEgressSourceRule(mAcceptedSourceAddr, false);
+                for (LinkAddress addr : mAcceptedSourceAddr) {
+                    mNetService.setFirewallEgressSourceRule(addr.toString(), false);
+                }
                 mAcceptedSourceAddr = null;
             }
         } catch (RemoteException e) {
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index a82f421..5ca7242 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -106,7 +106,6 @@
 import android.os.Binder;
 import android.os.Environment;
 import android.os.Handler;
-import android.os.HandlerThread;
 import android.os.INetworkManagementService;
 import android.os.IPowerManager;
 import android.os.Message;
@@ -134,6 +133,7 @@
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Objects;
+import com.android.server.IoThread;
 import com.google.android.collect.Lists;
 import com.google.android.collect.Maps;
 import com.google.android.collect.Sets;
@@ -274,7 +274,6 @@
     private final RemoteCallbackList<INetworkPolicyListener> mListeners = new RemoteCallbackList<
             INetworkPolicyListener>();
 
-    private final HandlerThread mHandlerThread;
     private final Handler mHandler;
 
     private final AtomicFile mPolicyFile;
@@ -306,9 +305,7 @@
         mNetworkManager = checkNotNull(networkManagement, "missing networkManagement");
         mTime = checkNotNull(time, "missing TrustedTime");
 
-        mHandlerThread = new HandlerThread(TAG);
-        mHandlerThread.start();
-        mHandler = new Handler(mHandlerThread.getLooper(), mHandlerCallback);
+        mHandler = new Handler(IoThread.get().getLooper(), mHandlerCallback);
 
         mSuppressDefaultPolicy = suppressDefaultPolicy;
 
diff --git a/services/java/com/android/server/net/NetworkStatsRecorder.java b/services/java/com/android/server/net/NetworkStatsRecorder.java
index 2b32b41..cea084b 100644
--- a/services/java/com/android/server/net/NetworkStatsRecorder.java
+++ b/services/java/com/android/server/net/NetworkStatsRecorder.java
@@ -135,6 +135,9 @@
             } catch (IOException e) {
                 Log.wtf(TAG, "problem completely reading network stats", e);
                 recoverFromWtf();
+            } catch (OutOfMemoryError e) {
+                Log.wtf(TAG, "problem completely reading network stats", e);
+                recoverFromWtf();
             }
         }
         return complete;
@@ -226,6 +229,9 @@
             } catch (IOException e) {
                 Log.wtf(TAG, "problem persisting pending stats", e);
                 recoverFromWtf();
+            } catch (OutOfMemoryError e) {
+                Log.wtf(TAG, "problem persisting pending stats", e);
+                recoverFromWtf();
             }
         }
     }
@@ -241,6 +247,9 @@
         } catch (IOException e) {
             Log.wtf(TAG, "problem removing UIDs " + Arrays.toString(uids), e);
             recoverFromWtf();
+        } catch (OutOfMemoryError e) {
+            Log.wtf(TAG, "problem removing UIDs " + Arrays.toString(uids), e);
+            recoverFromWtf();
         }
 
         // Remove any pending stats
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index 74be472..1e8a7b0 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -96,7 +96,6 @@
 import android.os.DropBoxManager;
 import android.os.Environment;
 import android.os.Handler;
-import android.os.HandlerThread;
 import android.os.INetworkManagementService;
 import android.os.Message;
 import android.os.PowerManager;
@@ -120,6 +119,7 @@
 import com.android.internal.util.FileRotator;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.EventLogTags;
+import com.android.server.IoThread;
 import com.android.server.connectivity.Tethering;
 import com.google.android.collect.Maps;
 
@@ -154,7 +154,7 @@
 
     private final Context mContext;
     private final INetworkManagementService mNetworkManager;
-    private final IAlarmManager mAlarmManager;
+    private final AlarmManager mAlarmManager;
     private final TrustedTime mTime;
     private final TelephonyManager mTeleManager;
     private final NetworkStatsSettings mSettings;
@@ -240,7 +240,6 @@
     /** Data layer operation counters for splicing into other structures. */
     private NetworkStats mUidOperations = new NetworkStats(0L, 10);
 
-    private final HandlerThread mHandlerThread;
     private final Handler mHandler;
 
     private boolean mSystemReady;
@@ -262,18 +261,16 @@
             NetworkStatsSettings settings) {
         mContext = checkNotNull(context, "missing Context");
         mNetworkManager = checkNotNull(networkManager, "missing INetworkManagementService");
-        mAlarmManager = checkNotNull(alarmManager, "missing IAlarmManager");
         mTime = checkNotNull(time, "missing TrustedTime");
         mTeleManager = checkNotNull(TelephonyManager.getDefault(), "missing TelephonyManager");
         mSettings = checkNotNull(settings, "missing NetworkStatsSettings");
+        mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
 
         final PowerManager powerManager = (PowerManager) context.getSystemService(
                 Context.POWER_SERVICE);
         mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
 
-        mHandlerThread = new HandlerThread(TAG);
-        mHandlerThread.start();
-        mHandler = new Handler(mHandlerThread.getLooper(), mHandlerCallback);
+        mHandler = new Handler(IoThread.get().getLooper(), mHandlerCallback);
 
         mSystemDir = checkNotNull(systemDir);
         mBaseDir = new File(systemDir, "netstats");
@@ -415,6 +412,8 @@
             }
         } catch (IOException e) {
             Log.wtf(TAG, "problem during legacy upgrade", e);
+        } catch (OutOfMemoryError e) {
+            Log.wtf(TAG, "problem during legacy upgrade", e);
         }
     }
 
@@ -423,20 +422,16 @@
      * reschedule based on current {@link NetworkStatsSettings#getPollInterval()}.
      */
     private void registerPollAlarmLocked() {
-        try {
-            if (mPollIntent != null) {
-                mAlarmManager.remove(mPollIntent);
-            }
-
-            mPollIntent = PendingIntent.getBroadcast(
-                    mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL), 0);
-
-            final long currentRealtime = SystemClock.elapsedRealtime();
-            mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
-                    mSettings.getPollInterval(), mPollIntent);
-        } catch (RemoteException e) {
-            // ignored; service lives in system_server
+        if (mPollIntent != null) {
+            mAlarmManager.cancel(mPollIntent);
         }
+
+        mPollIntent = PendingIntent.getBroadcast(
+                mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL), 0);
+
+        final long currentRealtime = SystemClock.elapsedRealtime();
+        mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
+                mSettings.getPollInterval(), mPollIntent);
     }
 
     /**
@@ -1193,8 +1188,7 @@
      */
     private NetworkStats getNetworkStatsTethering() throws RemoteException {
         try {
-            final String[] tetheredIfacePairs = mConnManager.getTetheredIfacePairs();
-            return mNetworkManager.getNetworkStatsTethering(tetheredIfacePairs);
+            return mNetworkManager.getNetworkStatsTethering();
         } catch (IllegalStateException e) {
             Log.wtf(TAG, "problem reading network stats", e);
             return new NetworkStats(0L, 10);
diff --git a/services/java/com/android/server/pm/GrantedPermissions.java b/services/java/com/android/server/pm/GrantedPermissions.java
index c7629b9..14258a4 100644
--- a/services/java/com/android/server/pm/GrantedPermissions.java
+++ b/services/java/com/android/server/pm/GrantedPermissions.java
@@ -44,6 +44,7 @@
     void setFlags(int pkgFlags) {
         this.pkgFlags = pkgFlags
                 & (ApplicationInfo.FLAG_SYSTEM
+                        | ApplicationInfo.FLAG_PRIVILEGED
                         | ApplicationInfo.FLAG_FORWARD_LOCK
                         | ApplicationInfo.FLAG_EXTERNAL_STORAGE);
     }
diff --git a/services/java/com/android/server/pm/KeySetManager.java b/services/java/com/android/server/pm/KeySetManager.java
new file mode 100644
index 0000000..93992c2
--- /dev/null
+++ b/services/java/com/android/server/pm/KeySetManager.java
@@ -0,0 +1,586 @@
+/*
+ * 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.server.pm;
+
+import android.content.pm.KeySet;
+import android.content.pm.PackageParser;
+import android.os.Binder;
+import android.util.Base64;
+import android.util.Log;
+import android.util.LongSparseArray;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.security.PublicKey;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+/*
+ * Manages system-wide KeySet state.
+ */
+public class KeySetManager {
+
+    static final String TAG = "KeySetManager";
+
+    /** Sentinel value returned when a {@code KeySet} is not found. */
+    public static final long KEYSET_NOT_FOUND = -1;
+
+    /** Sentinel value returned when public key is not found. */
+    private static final long PUBLIC_KEY_NOT_FOUND = -1;
+
+    private final Object mLockObject = new Object();
+
+    private final LongSparseArray<KeySet> mKeySets;
+
+    private final LongSparseArray<PublicKey> mPublicKeys;
+
+    private final LongSparseArray<Set<Long>> mKeySetMapping;
+
+    private final Map<String, PackageSetting> mPackages;
+
+    private static long lastIssuedKeySetId = 0;
+
+    private static long lastIssuedKeyId = 0;
+
+    public KeySetManager(Map<String, PackageSetting> packages) {
+        mKeySets = new LongSparseArray<KeySet>();
+        mPublicKeys = new LongSparseArray<PublicKey>();
+        mKeySetMapping = new LongSparseArray<Set<Long>>();
+        mPackages = packages;
+    }
+
+    /**
+     * Determine if a package is signed by the given KeySet.
+     *
+     * Returns false if the package was not signed by all the
+     * keys in the KeySet.
+     *
+     * Returns true if the package was signed by at least the
+     * keys in the given KeySet.
+     *
+     * Note that this can return true for multiple KeySets.
+     */
+    public boolean packageIsSignedBy(String packageName, KeySet ks) {
+        synchronized (mLockObject) {
+            PackageSetting pkg = mPackages.get(packageName);
+            if (pkg == null) {
+                throw new NullPointerException("Invalid package name");
+            }
+            if (pkg.keySetData == null) {
+                throw new NullPointerException("Package has no KeySet data");
+            }
+            long id = getIdByKeySetLocked(ks);
+            return pkg.keySetData.packageIsSignedBy(id);
+        }
+    }
+
+    /**
+     * This informs the system that the given package has defined a KeySet
+     * in its manifest that a) contains the given keys and b) is named
+     * alias by that package.
+     */
+    public void addDefinedKeySetToPackage(String packageName,
+            Set<PublicKey> keys, String alias) {
+        if ((packageName == null) || (keys == null) || (alias == null)) {
+            Log.d(TAG, "Got null argument for a defined keyset, ignoring!");
+            return;
+        }
+        synchronized (mLockObject) {
+            KeySet ks = addKeySetLocked(keys);
+            PackageSetting pkg = mPackages.get(packageName);
+            if (pkg == null) {
+                throw new NullPointerException("Unknown package");
+            }
+            long id = getIdByKeySetLocked(ks);
+            pkg.keySetData.addDefinedKeySet(id, alias);
+        }
+    }
+
+    /**
+     * Similar to the above, this informs the system that the given package
+     * was signed by the provided KeySet.
+     */
+    public void addSigningKeySetToPackage(String packageName,
+            Set<PublicKey> signingKeys) {
+        if ((packageName == null) || (signingKeys == null)) {
+            Log.d(TAG, "Got null argument for a signing keyset, ignoring!");
+            return;
+        }
+        synchronized (mLockObject) {
+            // add the signing KeySet
+            KeySet ks = addKeySetLocked(signingKeys);
+            long id = getIdByKeySetLocked(ks);
+            Set<Long> publicKeyIds = mKeySetMapping.get(id);
+            if (publicKeyIds == null) {
+                throw new NullPointerException("Got invalid KeySet id");
+            }
+
+            // attach it to the package
+            PackageSetting pkg = mPackages.get(packageName);
+            if (pkg == null) {
+                throw new NullPointerException("No such package!");
+            }
+            pkg.keySetData.addSigningKeySet(id);
+
+            // for each KeySet the package defines which is a subset of
+            // the one above, add the KeySet id to the package's signing KeySets
+            for (Long keySetID : pkg.keySetData.getDefinedKeySets()) {
+                Set<Long> definedKeys = mKeySetMapping.get(keySetID);
+                if (publicKeyIds.contains(definedKeys)) {
+                    pkg.keySetData.addSigningKeySet(keySetID);
+                }
+            }
+        }
+    }
+
+    /**
+     * Fetches the stable identifier associated with the given KeySet. Returns
+     * {@link #KEYSET_NOT_FOUND} if the KeySet... wasn't found.
+     */
+    public long getIdByKeySet(KeySet ks) {
+        synchronized (mLockObject) {
+            return getIdByKeySetLocked(ks);
+        }
+    }
+
+    private long getIdByKeySetLocked(KeySet ks) {
+        for (int keySetIndex = 0; keySetIndex < mKeySets.size(); keySetIndex++) {
+            KeySet value = mKeySets.valueAt(keySetIndex);
+            if (ks.equals(value)) {
+                return mKeySets.keyAt(keySetIndex);
+            }
+        }
+        return KEYSET_NOT_FOUND;
+    }
+
+    /**
+     * Fetches the KeySet corresponding to the given stable identifier.
+     *
+     * Returns {@link #KEYSET_NOT_FOUND} if the identifier doesn't
+     * identify a {@link KeySet}.
+     */
+    public KeySet getKeySetById(long id) {
+        synchronized (mLockObject) {
+            return mKeySets.get(id);
+        }
+    }
+
+    /**
+     * Fetches the KeySet that a given package refers to by the provided alias.
+     *
+     * If the package isn't known to us, throws an IllegalArgumentException.
+     * Returns null if the alias isn't known to us.
+     */
+    public KeySet getKeySetByAliasAndPackageName(String packageName, String alias) {
+        synchronized (mLockObject) {
+            PackageSetting p = mPackages.get(packageName);
+            if (p == null) {
+                throw new NullPointerException("Unknown package");
+            }
+            if (p.keySetData == null) {
+                throw new IllegalArgumentException("Package has no keySet data");
+            }
+            long keySetId = p.keySetData.getAliases().get(alias);
+            return mKeySets.get(keySetId);
+        }
+    }
+
+    /**
+     * Fetches all the known {@link KeySet KeySets} that signed the given
+     * package. Returns {@code null} if package is unknown.
+     */
+    public Set<KeySet> getSigningKeySetsByPackageName(String packageName) {
+        synchronized (mLockObject) {
+            Set<KeySet> signingKeySets = new HashSet<KeySet>();
+            PackageSetting p = mPackages.get(packageName);
+            if (p == null) {
+                throw new NullPointerException("Unknown package");
+            }
+            if (p.keySetData == null) {
+                throw new IllegalArgumentException("Package has no keySet data");
+            }
+            for (long l : p.keySetData.getSigningKeySets()) {
+                signingKeySets.add(mKeySets.get(l));
+            }
+            return signingKeySets;
+        }
+    }
+
+    /**
+     * Creates a new KeySet corresponding to the given keys.
+     *
+     * If the {@link PublicKey PublicKeys} aren't known to the system, this
+     * adds them. Otherwise, they're deduped.
+     *
+     * If the KeySet isn't known to the system, this adds that and creates the
+     * mapping to the PublicKeys. If it is known, then it's deduped.
+     *
+     * Throws if the provided set is {@code null}.
+     */
+    private KeySet addKeySetLocked(Set<PublicKey> keys) {
+        if (keys == null) {
+            throw new NullPointerException("Provided keys cannot be null");
+        }
+        // add each of the keys in the provided set
+        Set<Long> addedKeyIds = new HashSet<Long>(keys.size());
+        for (PublicKey k : keys) {
+            long id = addPublicKeyLocked(k);
+            addedKeyIds.add(id);
+        }
+
+        // check to see if the resulting keyset is new
+        long existingKeySetId = getIdFromKeyIdsLocked(addedKeyIds);
+        if (existingKeySetId != KEYSET_NOT_FOUND) {
+            return mKeySets.get(existingKeySetId);
+        }
+
+        // create the KeySet object
+        KeySet ks = new KeySet(new Binder());
+        // get the first unoccupied slot in mKeySets
+        long id = getFreeKeySetIDLocked();
+        // add the KeySet object to it
+        mKeySets.put(id, ks);
+        // add the stable key ids to the mapping
+        mKeySetMapping.put(id, addedKeyIds);
+        // go home
+        return ks;
+    }
+
+    /**
+     * Adds the given PublicKey to the system, deduping as it goes.
+     */
+    private long addPublicKeyLocked(PublicKey key) {
+        // check if the public key is new
+        long existingKeyId = getIdForPublicKeyLocked(key);
+        if (existingKeyId != PUBLIC_KEY_NOT_FOUND) {
+            return existingKeyId;
+        }
+        // if it's new find the first unoccupied slot in the public keys
+        long id = getFreePublicKeyIdLocked();
+        // add the public key to it
+        mPublicKeys.put(id, key);
+        // return the stable identifier
+        return id;
+    }
+
+    /**
+     * Finds the stable identifier for a KeySet based on a set of PublicKey stable IDs.
+     *
+     * Returns KEYSET_NOT_FOUND if there isn't one.
+     */
+    private long getIdFromKeyIdsLocked(Set<Long> publicKeyIds) {
+        for (int keyMapIndex = 0; keyMapIndex < mKeySetMapping.size(); keyMapIndex++) {
+            Set<Long> value = mKeySetMapping.valueAt(keyMapIndex);
+            if (value.equals(publicKeyIds)) {
+                return mKeySetMapping.keyAt(keyMapIndex);
+            }
+        }
+        return KEYSET_NOT_FOUND;
+    }
+
+    /**
+     * Finds the stable identifier for a PublicKey or PUBLIC_KEY_NOT_FOUND.
+     */
+    private long getIdForPublicKeyLocked(PublicKey k) {
+        String encodedPublicKey = new String(k.getEncoded());
+        for (int publicKeyIndex = 0; publicKeyIndex < mPublicKeys.size(); publicKeyIndex++) {
+            PublicKey value = mPublicKeys.valueAt(publicKeyIndex);
+            String encodedExistingKey = new String(value.getEncoded());
+            if (encodedPublicKey.equals(encodedExistingKey)) {
+                return mPublicKeys.keyAt(publicKeyIndex);
+            }
+        }
+        return PUBLIC_KEY_NOT_FOUND;
+    }
+
+    /**
+     * Gets an unused stable identifier for a KeySet.
+     */
+    private long getFreeKeySetIDLocked() {
+        lastIssuedKeySetId += 1;
+        return lastIssuedKeySetId;
+    }
+
+    /**
+     * Same as above, but for public keys.
+     */
+    private long getFreePublicKeyIdLocked() {
+        lastIssuedKeyId += 1;
+        return lastIssuedKeyId;
+    }
+
+    public void removeAppKeySetData(String packageName) {
+        synchronized (mLockObject) {
+            // Get the package's known keys and KeySets
+            Set<Long> deletableKeySets = getKnownKeySetsByPackageNameLocked(packageName);
+            Set<Long> deletableKeys = new HashSet<Long>();
+            Set<Long> knownKeys = null;
+            for (Long ks : deletableKeySets) {
+                knownKeys = mKeySetMapping.get(ks);
+                if (knownKeys != null) {
+                    deletableKeys.addAll(knownKeys);
+                }
+            }
+
+            // Now remove the keys and KeySets known to any other package
+            for (String pkgName : mPackages.keySet()) {
+                if (pkgName.equals(packageName)) {
+                    continue;
+                }
+                Set<Long> knownKeySets = getKnownKeySetsByPackageNameLocked(pkgName);
+                deletableKeySets.removeAll(knownKeySets);
+                knownKeys = new HashSet<Long>();
+                for (Long ks : knownKeySets) {
+                    knownKeys = mKeySetMapping.get(ks);
+                    if (knownKeys != null) {
+                        deletableKeys.removeAll(knownKeys);
+                    }
+                }
+            }
+
+            // The remaining keys and KeySets are not known to any other
+            // application and so can be safely deleted.
+            for (Long ks : deletableKeySets) {
+                mKeySets.delete(ks);
+                mKeySetMapping.delete(ks);
+            }
+            for (Long keyId : deletableKeys) {
+                mPublicKeys.delete(keyId);
+            }
+
+            // Now remove them from the KeySets known to each package
+            for (String pkgName : mPackages.keySet()) {
+                PackageSetting p = mPackages.get(pkgName);
+                for (Long ks : deletableKeySets) {
+                    p.keySetData.removeSigningKeySet(ks);
+                    p.keySetData.removeDefinedKeySet(ks);
+                }
+            }
+        }
+    }
+
+    private Set<Long> getKnownKeySetsByPackageNameLocked(String packageName) {
+        PackageSetting p = mPackages.get(packageName);
+        if (p == null) {
+            throw new NullPointerException("Unknown package");
+        }
+        if (p.keySetData == null) {
+            throw new IllegalArgumentException("Package has no keySet data");
+        }
+        Set<Long> knownKeySets = new HashSet<Long>();
+        for (long ks : p.keySetData.getSigningKeySets()) {
+            knownKeySets.add(ks);
+        }
+        for (long ks : p.keySetData.getDefinedKeySets()) {
+            knownKeySets.add(ks);
+        }
+        return knownKeySets;
+    }
+
+    public String encodePublicKey(PublicKey k) throws IOException {
+        return new String(Base64.encode(k.getEncoded(), 0));
+    }
+
+    public void dump(PrintWriter pw, String packageName,
+            PackageManagerService.DumpState dumpState) {
+        synchronized (mLockObject) {
+            boolean printedHeader = false;
+            for (Map.Entry<String, PackageSetting> e : mPackages.entrySet()) {
+                String keySetPackage = e.getKey();
+                if (packageName != null && !packageName.equals(keySetPackage)) {
+                    continue;
+                }
+                if (!printedHeader) {
+                    if (dumpState.onTitlePrinted())
+                        pw.println();
+                    pw.println("Key Set Manager:");
+                    printedHeader = true;
+                }
+                PackageSetting pkg = e.getValue();
+                pw.print("  ["); pw.print(keySetPackage); pw.println("]");
+                if (pkg.keySetData != null) {
+                    boolean printedLabel = false;
+                    for (Map.Entry<String, Long> entry : pkg.keySetData.getAliases().entrySet()) {
+                        if (!printedLabel) {
+                            pw.print("      KeySets Aliases: ");
+                            printedLabel = true;
+                        } else {
+                            pw.print(", ");
+                        }
+                        pw.print(entry.getKey());
+                        pw.print('=');
+                        pw.print(Long.toString(entry.getValue()));
+                    }
+                    if (printedLabel) {
+                        pw.println("");
+                    }
+                    printedLabel = false;
+                    for (long keySetId : pkg.keySetData.getDefinedKeySets()) {
+                        if (!printedLabel) {
+                            pw.print("      Defined KeySets: ");
+                            printedLabel = true;
+                        } else {
+                            pw.print(", ");
+                        }
+                        pw.print(Long.toString(keySetId));
+                    }
+                    if (printedLabel) {
+                        pw.println("");
+                    }
+                    printedLabel = false;
+                    for (long keySetId : pkg.keySetData.getSigningKeySets()) {
+                        if (!printedLabel) {
+                            pw.print("      Signing KeySets: ");
+                            printedLabel = true;
+                        } else {
+                            pw.print(", ");
+                        }
+                        pw.print(Long.toString(keySetId));
+                    }
+                    if (printedLabel) {
+                        pw.println("");
+                    }
+                }
+            }
+        }
+    }
+
+    void writeKeySetManagerLPr(XmlSerializer serializer) throws IOException {
+        serializer.startTag(null, "keyset-settings");
+        writePublicKeysLPr(serializer);
+        writeKeySetsLPr(serializer);
+        serializer.startTag(null, "lastIssuedKeyId");
+        serializer.attribute(null, "value", Long.toString(lastIssuedKeyId));
+        serializer.endTag(null, "lastIssuedKeyId");
+        serializer.startTag(null, "lastIssuedKeySetId");
+        serializer.attribute(null, "value", Long.toString(lastIssuedKeySetId));
+        serializer.endTag(null, "lastIssuedKeySetId");
+        serializer.endTag(null, "keyset-settings");
+    }
+
+    void writePublicKeysLPr(XmlSerializer serializer) throws IOException {
+        serializer.startTag(null, "keys");
+        for (int pKeyIndex = 0; pKeyIndex < mPublicKeys.size(); pKeyIndex++) {
+            long id = mPublicKeys.keyAt(pKeyIndex);
+            PublicKey key = mPublicKeys.valueAt(pKeyIndex);
+            String encodedKey = encodePublicKey(key);
+            serializer.startTag(null, "public-key");
+            serializer.attribute(null, "identifier", Long.toString(id));
+            serializer.attribute(null, "value", encodedKey);
+            serializer.endTag(null, "public-key");
+        }
+        serializer.endTag(null, "keys");
+    }
+
+    void writeKeySetsLPr(XmlSerializer serializer) throws IOException {
+        serializer.startTag(null, "keysets");
+        for (int keySetIndex = 0; keySetIndex < mKeySetMapping.size(); keySetIndex++) {
+            long id = mKeySetMapping.keyAt(keySetIndex);
+            Set<Long> keys = mKeySetMapping.valueAt(keySetIndex);
+            serializer.startTag(null, "keyset");
+            serializer.attribute(null, "identifier", Long.toString(id));
+            for (long keyId : keys) {
+                serializer.startTag(null, "key-id");
+                serializer.attribute(null, "identifier", Long.toString(keyId));
+                serializer.endTag(null, "key-id");
+            }
+            serializer.endTag(null, "keyset");
+        }
+        serializer.endTag(null, "keysets");
+    }
+
+    void readKeySetsLPw(XmlPullParser parser)
+            throws XmlPullParserException, IOException {
+        int type;
+        long currentKeySetId = 0;
+        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
+            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+                continue;
+            }
+            final String tagName = parser.getName();
+            if (tagName.equals("keys")) {
+                readKeysLPw(parser);
+            } else if (tagName.equals("keysets")) {
+                readKeySetListLPw(parser);
+            }
+        }
+    }
+
+    void readKeysLPw(XmlPullParser parser)
+            throws XmlPullParserException, IOException {
+        int outerDepth = parser.getDepth();
+        int type;
+        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+                continue;
+            }
+            final String tagName = parser.getName();
+            if (tagName.equals("public-key")) {
+                readPublicKeyLPw(parser);
+            } else if (tagName.equals("lastIssuedKeyId")) {
+                lastIssuedKeyId = Long.parseLong(parser.getAttributeValue(null, "value"));
+            } else if (tagName.equals("lastIssuedKeySetId")) {
+                lastIssuedKeySetId = Long.parseLong(parser.getAttributeValue(null, "value"));
+            }
+        }
+    }
+
+    void readKeySetListLPw(XmlPullParser parser)
+            throws XmlPullParserException, IOException {
+        int outerDepth = parser.getDepth();
+        int type;
+        long currentKeySetId = 0;
+        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+                continue;
+            }
+            final String tagName = parser.getName();
+            if (tagName.equals("keyset")) {
+                currentKeySetId = readIdentifierLPw(parser);
+                mKeySets.put(currentKeySetId, new KeySet(new Binder()));
+                mKeySetMapping.put(currentKeySetId, new HashSet<Long>());
+            } else if (tagName.equals("key-id")) {
+                long id = readIdentifierLPw(parser);
+                mKeySetMapping.get(currentKeySetId).add(id);
+            }
+        }
+    }
+
+    long readIdentifierLPw(XmlPullParser parser)
+            throws XmlPullParserException {
+        return Long.parseLong(parser.getAttributeValue(null, "identifier"));
+    }
+
+    void readPublicKeyLPw(XmlPullParser parser)
+            throws XmlPullParserException {
+        String encodedID = parser.getAttributeValue(null, "identifier");
+        long identifier = Long.parseLong(encodedID);
+        String encodedPublicKey = parser.getAttributeValue(null, "value");
+        PublicKey pub = PackageParser.parsePublicKey(encodedPublicKey);
+        if (pub != null) {
+            mPublicKeys.put(identifier, pub);
+        }
+    }
+}
diff --git a/services/java/com/android/server/pm/PackageKeySetData.java b/services/java/com/android/server/pm/PackageKeySetData.java
new file mode 100644
index 0000000..cb60621
--- /dev/null
+++ b/services/java/com/android/server/pm/PackageKeySetData.java
@@ -0,0 +1,125 @@
+/*
+ * 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.server.pm;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+public class PackageKeySetData {
+
+    private long[] mSigningKeySets;
+
+    private long[] mDefinedKeySets;
+
+    private final Map<String, Long> mKeySetAliases;
+
+    PackageKeySetData() {
+        mSigningKeySets = new long[0];
+        mDefinedKeySets = new long[0];
+        mKeySetAliases =  new HashMap<String, Long>();
+    }
+
+    PackageKeySetData(PackageKeySetData original) {
+        mSigningKeySets = original.getSigningKeySets().clone();
+        mDefinedKeySets = original.getDefinedKeySets().clone();
+        mKeySetAliases = new HashMap<String, Long>();
+        mKeySetAliases.putAll(original.getAliases());
+    }
+
+    public void addSigningKeySet(long ks) {
+        // deduplicate
+        for (long knownKeySet : mSigningKeySets) {
+            if (ks == knownKeySet) {
+                return;
+            }
+        }
+        int end = mSigningKeySets.length;
+        mSigningKeySets = Arrays.copyOf(mSigningKeySets, end + 1);
+        mSigningKeySets[end] = ks;
+    }
+
+    public void removeSigningKeySet(long ks) {
+        if (packageIsSignedBy(ks)) {
+            long[] keysets = new long[mSigningKeySets.length - 1];
+            int index = 0;
+            for (long signingKeySet : mSigningKeySets) {
+                if (signingKeySet != ks) {
+                    keysets[index] = signingKeySet;
+                    index += 1;
+                }
+            }
+            mSigningKeySets = keysets;
+        }
+    }
+
+    public void addDefinedKeySet(long ks, String alias) {
+        // deduplicate
+        for (long knownKeySet : mDefinedKeySets) {
+            if (ks == knownKeySet) {
+                return;
+            }
+        }
+        int end = mDefinedKeySets.length;
+        mDefinedKeySets = Arrays.copyOf(mDefinedKeySets, end + 1);
+        mDefinedKeySets[end] = ks;
+        mKeySetAliases.put(alias, ks);
+    }
+
+    public void removeDefinedKeySet(long ks) {
+        if (mKeySetAliases.containsValue(ks)) {
+            long[] keysets = new long[mDefinedKeySets.length - 1];
+            int index = 0;
+            for (long definedKeySet : mDefinedKeySets) {
+                if (definedKeySet != ks) {
+                    keysets[index] = definedKeySet;
+                    index += 1;
+                }
+            }
+            mDefinedKeySets = keysets;
+            for (String alias : mKeySetAliases.keySet()) {
+                if (mKeySetAliases.get(alias) == ks) {
+                    mKeySetAliases.remove(alias);
+                    break;
+                }
+            }
+        }
+    }
+
+    public boolean packageIsSignedBy(long ks) {
+        for (long signingKeySet : mSigningKeySets) {
+            if (ks == signingKeySet) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public long[] getSigningKeySets() {
+        return mSigningKeySets;
+    }
+
+    public long[] getDefinedKeySets() {
+        return mDefinedKeySets;
+    }
+
+    public Map<String, Long> getAliases() {
+        return mKeySetAliases;
+    }
+}
\ No newline at end of file
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 8cdca1f..decda96 100755
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -35,12 +35,14 @@
 import com.android.internal.app.ResolverActivity;
 import com.android.internal.content.NativeLibraryHelper;
 import com.android.internal.content.PackageHelper;
+import com.android.internal.util.FastPrintWriter;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.XmlUtils;
 import com.android.server.DeviceStorageMonitorService;
 import com.android.server.EventLogTags;
 import com.android.server.IntentResolver;
 
+import com.android.server.Watchdog;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
@@ -89,6 +91,7 @@
 import android.content.pm.VerificationParams;
 import android.content.pm.VerifierDeviceIdentity;
 import android.content.pm.VerifierInfo;
+import android.content.res.Resources;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Build;
@@ -112,13 +115,14 @@
 import android.os.UserHandle;
 import android.os.Environment.UserEnvironment;
 import android.os.UserManager;
-import android.provider.Settings.Secure;
 import android.security.KeyStore;
 import android.security.SystemKeyStore;
+import android.text.TextUtils;
 import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.Log;
 import android.util.LogPrinter;
+import android.util.PrintStreamPrinter;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.Xml;
@@ -157,6 +161,8 @@
 import libcore.io.Libcore;
 import libcore.io.StructStat;
 
+import com.android.internal.R;
+
 /**
  * Keep track of all those .apks everywhere.
  * 
@@ -276,6 +282,9 @@
     // This is the object monitoring the system app dir.
     final FileObserver mSystemInstallObserver;
 
+    // This is the object monitoring the privileged system app dir.
+    final FileObserver mPrivilegedInstallObserver;
+
     // This is the object monitoring the system app dir.
     final FileObserver mVendorInstallObserver;
 
@@ -289,11 +298,7 @@
     // LOCK HELD.  Can be called with mInstallLock held.
     final Installer mInstaller;
 
-    final File mFrameworkDir;
-    final File mSystemAppDir;
-    final File mVendorAppDir;
     final File mAppInstallDir;
-    final File mDalvikCacheDir;
 
     /**
      * Directory to which applications installed internally have native
@@ -420,6 +425,9 @@
     final ResolveInfo mResolveInfo = new ResolveInfo();
     ComponentName mResolveComponentName;
     PackageParser.Package mPlatformPackage;
+    ComponentName mCustomResolverComponentName;
+
+    boolean mResolverReplaced = false;
 
     // Set of pending broadcasts for aggregating enable/disable of components.
     static class PendingPackageBroadcasts {
@@ -427,7 +435,7 @@
         final SparseArray<HashMap<String, ArrayList<String>>> mUidMap;
 
         public PendingPackageBroadcasts() {
-            mUidMap = new SparseArray<HashMap<String, ArrayList<String>>>();
+            mUidMap = new SparseArray<HashMap<String, ArrayList<String>>>(2);
         }
 
         public ArrayList<String> get(int userId, String packageName) {
@@ -1054,13 +1062,18 @@
         mNoDexOpt = "eng".equals(SystemProperties.get("ro.build.type"));
         mMetrics = new DisplayMetrics();
         mSettings = new Settings(context);
-        mSettings.addSharedUserLPw("android.uid.system",
-                Process.SYSTEM_UID, ApplicationInfo.FLAG_SYSTEM);
-        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, ApplicationInfo.FLAG_SYSTEM);
-        mSettings.addSharedUserLPw("android.uid.log", LOG_UID, ApplicationInfo.FLAG_SYSTEM);
-        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, ApplicationInfo.FLAG_SYSTEM);
-        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, ApplicationInfo.FLAG_SYSTEM);
-        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID, ApplicationInfo.FLAG_SYSTEM);
+        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
+                ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
+        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
+                ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
+        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
+                ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
+        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
+                ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
+        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
+                ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
+        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
+                ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
 
         String separateProcesses = SystemProperties.get("debug.separate_processes");
         if (separateProcesses != null && separateProcesses.length() > 0) {
@@ -1090,6 +1103,7 @@
         synchronized (mPackages) {
             mHandlerThread.start();
             mHandler = new PackageHandler(mHandlerThread.getLooper());
+            Watchdog.getInstance().addThread(mHandler, mHandlerThread.getName());
 
             File dataDir = Environment.getDataDirectory();
             mAppDataDir = new File(dataDir, "data");
@@ -1109,6 +1123,15 @@
             mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false),
                     mSdkVersion, mOnlyCore);
 
+            String customResolverActivity = Resources.getSystem().getString(
+                    R.string.config_customResolverActivity);
+            if (TextUtils.isEmpty(customResolverActivity)) {
+                customResolverActivity = null;
+            } else {
+                mCustomResolverComponentName = ComponentName.unflattenFromString(
+                        customResolverActivity);
+            }
+
             long startTime = SystemClock.uptimeMillis();
 
             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
@@ -1122,40 +1145,27 @@
                 scanMode |= SCAN_NO_DEX;
             }
 
-            final HashSet<String> libFiles = new HashSet<String>();
-
-            mFrameworkDir = new File(Environment.getRootDirectory(), "framework");
-            mDalvikCacheDir = new File(dataDir, "dalvik-cache");
-
-            boolean didDexOpt = false;
+            final HashSet<String> alreadyDexOpted = new HashSet<String>();
 
             /**
-             * Out of paranoia, ensure that everything in the boot class
-             * path has been dexed.
+             * Add everything in the in the boot class path to the
+             * list of process files because dexopt will have been run
+             * if necessary during zygote startup.
              */
             String bootClassPath = System.getProperty("java.boot.class.path");
             if (bootClassPath != null) {
                 String[] paths = splitString(bootClassPath, ':');
                 for (int i=0; i<paths.length; i++) {
-                    try {
-                        if (dalvik.system.DexFile.isDexOptNeeded(paths[i])) {
-                            libFiles.add(paths[i]);
-                            mInstaller.dexopt(paths[i], Process.SYSTEM_UID, true);
-                            didDexOpt = true;
-                        }
-                    } catch (FileNotFoundException e) {
-                        Slog.w(TAG, "Boot class path not found: " + paths[i]);
-                    } catch (IOException e) {
-                        Slog.w(TAG, "Cannot dexopt " + paths[i] + "; is it an APK or JAR? "
-                                + e.getMessage());
-                    }
+                    alreadyDexOpted.add(paths[i]);
                 }
             } else {
                 Slog.w(TAG, "No BOOTCLASSPATH found!");
             }
 
+            boolean didDexOpt = false;
+
             /**
-             * Also ensure all external libraries have had dexopt run on them.
+             * Ensure all external libraries have had dexopt run on them.
              */
             if (mSharedLibraries.size() > 0) {
                 Iterator<SharedLibraryEntry> libs = mSharedLibraries.values().iterator();
@@ -1166,7 +1176,7 @@
                     }
                     try {
                         if (dalvik.system.DexFile.isDexOptNeeded(lib)) {
-                            libFiles.add(lib);
+                            alreadyDexOpted.add(lib);
                             mInstaller.dexopt(lib, Process.SYSTEM_UID, true);
                             didDexOpt = true;
                         }
@@ -1179,22 +1189,29 @@
                 }
             }
 
+            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
+
             // Gross hack for now: we know this file doesn't contain any
             // code, so don't dexopt it to avoid the resulting log spew.
-            libFiles.add(mFrameworkDir.getPath() + "/framework-res.apk");
+            alreadyDexOpted.add(frameworkDir.getPath() + "/framework-res.apk");
+
+            // Gross hack for now: we know this file is only part of
+            // the boot class path for art, so don't dexopt it to
+            // avoid the resulting log spew.
+            alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar");
 
             /**
              * And there are a number of commands implemented in Java, which
              * we currently need to do the dexopt on so that they can be
              * run from a non-root shell.
              */
-            String[] frameworkFiles = mFrameworkDir.list();
+            String[] frameworkFiles = frameworkDir.list();
             if (frameworkFiles != null) {
                 for (int i=0; i<frameworkFiles.length; i++) {
-                    File libPath = new File(mFrameworkDir, frameworkFiles[i]);
+                    File libPath = new File(frameworkDir, frameworkFiles[i]);
                     String path = libPath.getPath();
                     // Skip the file if we alrady did it.
-                    if (libFiles.contains(path)) {
+                    if (alreadyDexOpted.contains(path)) {
                         continue;
                     }
                     // Skip the file if it is not a type we want to dexopt.
@@ -1215,19 +1232,21 @@
             }
 
             if (didDexOpt) {
+                File dalvikCacheDir = new File(dataDir, "dalvik-cache");
+
                 // If we had to do a dexopt of one of the previous
                 // things, then something on the system has changed.
                 // Consider this significant, and wipe away all other
                 // existing dexopt files to ensure we don't leave any
                 // dangling around.
-                String[] files = mDalvikCacheDir.list();
+                String[] files = dalvikCacheDir.list();
                 if (files != null) {
                     for (int i=0; i<files.length; i++) {
                         String fn = files[i];
                         if (fn.startsWith("data@app@")
                                 || fn.startsWith("data@app-private@")) {
                             Slog.i(TAG, "Pruning dalvik file: " + fn);
-                            (new File(mDalvikCacheDir, fn)).delete();
+                            (new File(dalvikCacheDir, fn)).delete();
                         }
                     }
                 }
@@ -1235,26 +1254,35 @@
 
             // Find base frameworks (resource packages without code).
             mFrameworkInstallObserver = new AppDirObserver(
-                mFrameworkDir.getPath(), OBSERVER_EVENTS, true);
+                frameworkDir.getPath(), OBSERVER_EVENTS, true, false);
             mFrameworkInstallObserver.startWatching();
-            scanDirLI(mFrameworkDir, PackageParser.PARSE_IS_SYSTEM
+            scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM
                     | PackageParser.PARSE_IS_SYSTEM_DIR,
                     scanMode | SCAN_NO_DEX, 0);
 
-            // Collect all system packages.
-            mSystemAppDir = new File(Environment.getRootDirectory(), "app");
+            // Collected privileged system packages.
+            File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
+            mPrivilegedInstallObserver = new AppDirObserver(
+                    privilegedAppDir.getPath(), OBSERVER_EVENTS, true, true);
+            mPrivilegedInstallObserver.startWatching();
+                scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM
+                        | PackageParser.PARSE_IS_SYSTEM_DIR
+                        | PackageParser.PARSE_IS_PRIVILEGED, scanMode, 0);
+
+            // Collect ordinary system packages.
+            File systemAppDir = new File(Environment.getRootDirectory(), "app");
             mSystemInstallObserver = new AppDirObserver(
-                mSystemAppDir.getPath(), OBSERVER_EVENTS, true);
+                systemAppDir.getPath(), OBSERVER_EVENTS, true, false);
             mSystemInstallObserver.startWatching();
-            scanDirLI(mSystemAppDir, PackageParser.PARSE_IS_SYSTEM
+            scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM
                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
 
             // Collect all vendor packages.
-            mVendorAppDir = new File("/vendor/app");
+            File vendorAppDir = new File("/vendor/app");
             mVendorInstallObserver = new AppDirObserver(
-                mVendorAppDir.getPath(), OBSERVER_EVENTS, true);
+                vendorAppDir.getPath(), OBSERVER_EVENTS, true, false);
             mVendorInstallObserver.startWatching();
-            scanDirLI(mVendorAppDir, PackageParser.PARSE_IS_SYSTEM
+            scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM
                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
 
             if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");
@@ -1321,16 +1349,19 @@
             //delete tmp files
             deleteTempPackageFiles();
 
+            // Remove any shared userIDs that have no associated packages
+            mSettings.pruneSharedUsersLPw();
+
             if (!mOnlyCore) {
                 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
                         SystemClock.uptimeMillis());
                 mAppInstallObserver = new AppDirObserver(
-                    mAppInstallDir.getPath(), OBSERVER_EVENTS, false);
+                    mAppInstallDir.getPath(), OBSERVER_EVENTS, false, false);
                 mAppInstallObserver.startWatching();
                 scanDirLI(mAppInstallDir, 0, scanMode, 0);
     
                 mDrmAppInstallObserver = new AppDirObserver(
-                    mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false);
+                    mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false, false);
                 mDrmAppInstallObserver.startWatching();
                 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
                         scanMode, 0);
@@ -1781,8 +1812,8 @@
         }
     }
 
+    @Override
     public int[] getPackageGids(String packageName) {
-        final boolean enforcedDefault = isPermissionEnforcedDefault(READ_EXTERNAL_STORAGE);
         // reader
         synchronized (mPackages) {
             PackageParser.Package p = mPackages.get(packageName);
@@ -1790,17 +1821,7 @@
                 Log.v(TAG, "getPackageGids" + packageName + ": " + p);
             if (p != null) {
                 final PackageSetting ps = (PackageSetting)p.mExtras;
-                final SharedUserSetting suid = ps.sharedUser;
-                int[] gids = suid != null ? suid.gids : ps.gids;
-
-                // include GIDs for any unenforced permissions
-                if (!isPermissionEnforcedLocked(READ_EXTERNAL_STORAGE, enforcedDefault)) {
-                    final BasePermission basePerm = mSettings.mPermissions.get(
-                            READ_EXTERNAL_STORAGE);
-                    gids = appendInts(gids, basePerm.gids);
-                }
-
-                return gids;
+                return ps.getGids();
             }
         }
         // stupid thing to indicate an error.
@@ -1913,8 +1934,6 @@
                         getDataPathForPackage(packageName, 0).getPath();
                 pkg.applicationInfo.nativeLibraryDir = ps.nativeLibraryPathString;
             }
-            // pkg.mSetEnabled = ps.getEnabled(userId);
-            // pkg.mSetStopped = ps.getStopped(userId);
             return generatePackageInfo(pkg, flags, userId);
         }
         return null;
@@ -2123,7 +2142,6 @@
     }
 
     public int checkPermission(String permName, String pkgName) {
-        final boolean enforcedDefault = isPermissionEnforcedDefault(permName);
         synchronized (mPackages) {
             PackageParser.Package p = mPackages.get(pkgName);
             if (p != null && p.mExtras != null) {
@@ -2136,15 +2154,11 @@
                     return PackageManager.PERMISSION_GRANTED;
                 }
             }
-            if (!isPermissionEnforcedLocked(permName, enforcedDefault)) {
-                return PackageManager.PERMISSION_GRANTED;
-            }
         }
         return PackageManager.PERMISSION_DENIED;
     }
 
     public int checkUidPermission(String permName, int uid) {
-        final boolean enforcedDefault = isPermissionEnforcedDefault(permName);
         synchronized (mPackages) {
             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
             if (obj != null) {
@@ -2158,9 +2172,6 @@
                     return PackageManager.PERMISSION_GRANTED;
                 }
             }
-            if (!isPermissionEnforcedLocked(permName, enforcedDefault)) {
-                return PackageManager.PERMISSION_GRANTED;
-            }
         }
         return PackageManager.PERMISSION_DENIED;
     }
@@ -2565,6 +2576,20 @@
         }
     }
 
+    public int getFlagsForUid(int uid) {
+        synchronized (mPackages) {
+            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
+            if (obj instanceof SharedUserSetting) {
+                final SharedUserSetting sus = (SharedUserSetting) obj;
+                return sus.pkgFlags;
+            } else if (obj instanceof PackageSetting) {
+                final PackageSetting ps = (PackageSetting) obj;
+                return ps.pkgFlags;
+            }
+        }
+        return 0;
+    }
+
     @Override
     public ResolveInfo resolveIntent(Intent intent, String resolvedType,
             int flags, int userId) {
@@ -2574,6 +2599,37 @@
         return chooseBestActivity(intent, resolvedType, flags, query, userId);
     }
 
+    @Override
+    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
+            IntentFilter filter, int match, ComponentName activity) {
+        final int userId = UserHandle.getCallingUserId();
+        if (DEBUG_PREFERRED) {
+            Log.v(TAG, "setLastChosenActivity intent=" + intent
+                + " resolvedType=" + resolvedType
+                + " flags=" + flags
+                + " filter=" + filter
+                + " match=" + match
+                + " activity=" + activity);
+            filter.dump(new PrintStreamPrinter(System.out), "    ");
+        }
+        intent.setComponent(null);
+        List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
+        // Find any earlier preferred or last chosen entries and nuke them
+        findPreferredActivity(intent, resolvedType,
+                flags, query, 0, false, true, userId);
+        // Add the new activity as the last chosen for this filter
+        addPreferredActivityInternal(filter, match, null, activity, false, userId);
+    }
+
+    @Override
+    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
+        final int userId = UserHandle.getCallingUserId();
+        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
+        List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
+        return findPreferredActivity(intent, resolvedType, flags, query, 0,
+                false, false, userId);
+    }
+
     private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
             int flags, List<ResolveInfo> query, int userId) {
         if (query != null) {
@@ -2599,7 +2655,7 @@
                 // If we have saved a preference for a preferred activity for
                 // this Intent, use that.
                 ResolveInfo ri = findPreferredActivity(intent, resolvedType,
-                        flags, query, r0.priority, userId);
+                        flags, query, r0.priority, true, false, userId);
                 if (ri != null) {
                     return ri;
                 }
@@ -2618,16 +2674,18 @@
         return null;
     }
 
-    ResolveInfo findPreferredActivity(Intent intent, String resolvedType,
-            int flags, List<ResolveInfo> query, int priority, int userId) {
+    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
+            List<ResolveInfo> query, int priority, boolean always,
+            boolean removeMatches, int userId) {
         if (!sUserManager.exists(userId)) return null;
         // writer
         synchronized (mPackages) {
             if (intent.getSelector() != null) {
-                intent = intent.getSelector(); 
+                intent = intent.getSelector();
             }
             if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
+            // Get the list of preferred activities that handle the intent
             List<PreferredActivity> prefs = pir != null
                     ? pir.queryIntent(intent, resolvedType,
                             (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
@@ -2662,7 +2720,25 @@
                 final int M = prefs.size();
                 for (int i=0; i<M; i++) {
                     final PreferredActivity pa = prefs.get(i);
+                    if (DEBUG_PREFERRED) {
+                        Log.v(TAG, "Checking PreferredActivity ds="
+                                + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
+                                + "\n  component=" + pa.mPref.mComponent);
+                        pa.dump(new PrintStreamPrinter(System.out), "  ");
+                    }
                     if (pa.mPref.mMatch != match) {
+                        if (DEBUG_PREFERRED) {
+                            Log.v(TAG, "Skipping bad match "
+                                    + Integer.toHexString(pa.mPref.mMatch));
+                        }
+                        continue;
+                    }
+                    // If it's not an "always" type preferred activity and that's what we're
+                    // looking for, skip it.
+                    if (always && !pa.mPref.mAlways) {
+                        if (DEBUG_PREFERRED) {
+                            Log.v(TAG, "Skipping lastChosen entry");
+                        }
                         continue;
                     }
                     final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent,
@@ -2696,22 +2772,41 @@
                             continue;
                         }
 
-                        // Okay we found a previously set preferred app.
+                        if (removeMatches) {
+                            pir.removeFilter(pa);
+                            if (DEBUG_PREFERRED) {
+                                Log.v(TAG, "Removing match " + pa.mPref.mComponent);
+                            }
+                            break;
+                        }
+
+                        // Okay we found a previously set preferred or last chosen app.
                         // If the result set is different from when this
                         // was created, we need to clear it and re-ask the
-                        // user their preference.
-                        if (!pa.mPref.sameSet(query, priority)) {
+                        // user their preference, if we're looking for an "always" type entry.
+                        if (always && !pa.mPref.sameSet(query, priority)) {
                             Slog.i(TAG, "Result set changed, dropping preferred activity for "
                                     + intent + " type " + resolvedType);
+                            if (DEBUG_PREFERRED) {
+                                Log.v(TAG, "Removing preferred activity since set changed "
+                                        + pa.mPref.mComponent);
+                            }
                             pir.removeFilter(pa);
+                            // Re-add the filter as a "last chosen" entry (!always)
+                            PreferredActivity lastChosen = new PreferredActivity(
+                                    pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
+                            pir.addFilter(lastChosen);
+                            mSettings.writePackageRestrictionsLPr(userId);
                             return null;
                         }
 
-                        // Yay!
+                        // Yay! Either the set matched or we're looking for the last chosen
+                        mSettings.writePackageRestrictionsLPr(userId);
                         return ri;
                     }
                 }
             }
+            mSettings.writePackageRestrictionsLPr(userId);
         }
         return null;
     }
@@ -3235,7 +3330,6 @@
     public List<ProviderInfo> queryContentProviders(String processName,
             int uid, int flags) {
         ArrayList<ProviderInfo> finalList = null;
-
         // reader
         synchronized (mPackages) {
             final Iterator<PackageParser.Provider> i = mProvidersByComponent.values().iterator();
@@ -3311,7 +3405,8 @@
         }
 
         if (DEBUG_PACKAGE_SCANNING) {
-            Log.d(TAG, "Scanning app dir " + dir);
+            Log.d(TAG, "Scanning app dir " + dir + " scanMode=" + scanMode
+                    + " flags=0x" + Integer.toHexString(flags));
         }
 
         int i;
@@ -3344,7 +3439,7 @@
         try {
             File fname = getSettingsProblemFile();
             FileOutputStream out = new FileOutputStream(fname, true);
-            PrintWriter pw = new PrintWriter(out);
+            PrintWriter pw = new FastPrintWriter(out);
             SimpleDateFormat formatter = new SimpleDateFormat();
             String dateString = formatter.format(new Date(System.currentTimeMillis()));
             pw.println(dateString + ": " + msg);
@@ -3400,10 +3495,12 @@
         pp.setOnlyCoreApps(mOnlyCore);
         final PackageParser.Package pkg = pp.parsePackage(scanFile,
                 scanPath, mMetrics, parseFlags);
+
         if (pkg == null) {
             mLastScanError = pp.getParseError();
             return null;
         }
+
         PackageSetting ps = null;
         PackageSetting updatedPkg;
         // reader
@@ -3553,6 +3650,7 @@
         } else {
             resPath = pkg.mScanPath;
         }
+
         codePath = pkg.mScanPath;
         // Set application objects path explicitly.
         setApplicationInfoPaths(pkg, codePath, resPath);
@@ -3967,6 +4065,15 @@
             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
         }
 
+        if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
+            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_PRIVILEGED;
+        }
+
+        if (mCustomResolverComponentName != null &&
+                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
+            setUpCustomResolverActivity(pkg);
+        }
+
         if (pkg.packageName.equals("android")) {
             synchronized (mPackages) {
                 if (mAndroidApplication != null) {
@@ -3978,26 +4085,28 @@
                     return null;
                 }
 
-                // Set up information for our fall-back user intent resolution
-                // activity.
+                // Set up information for our fall-back user intent resolution activity.
                 mPlatformPackage = pkg;
                 pkg.mVersionCode = mSdkVersion;
                 mAndroidApplication = pkg.applicationInfo;
-                mResolveActivity.applicationInfo = mAndroidApplication;
-                mResolveActivity.name = ResolverActivity.class.getName();
-                mResolveActivity.packageName = mAndroidApplication.packageName;
-                mResolveActivity.processName = "system:ui";
-                mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
-                mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
-                mResolveActivity.theme = com.android.internal.R.style.Theme_Holo_Dialog_Alert;
-                mResolveActivity.exported = true;
-                mResolveActivity.enabled = true;
-                mResolveInfo.activityInfo = mResolveActivity;
-                mResolveInfo.priority = 0;
-                mResolveInfo.preferredOrder = 0;
-                mResolveInfo.match = 0;
-                mResolveComponentName = new ComponentName(
-                        mAndroidApplication.packageName, mResolveActivity.name);
+
+                if (!mResolverReplaced) {
+                    mResolveActivity.applicationInfo = mAndroidApplication;
+                    mResolveActivity.name = ResolverActivity.class.getName();
+                    mResolveActivity.packageName = mAndroidApplication.packageName;
+                    mResolveActivity.processName = "system:ui";
+                    mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
+                    mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
+                    mResolveActivity.theme = com.android.internal.R.style.Theme_Holo_Dialog_Alert;
+                    mResolveActivity.exported = true;
+                    mResolveActivity.enabled = true;
+                    mResolveInfo.activityInfo = mResolveActivity;
+                    mResolveInfo.priority = 0;
+                    mResolveInfo.preferredOrder = 0;
+                    mResolveInfo.match = 0;
+                    mResolveComponentName = new ComponentName(
+                            mAndroidApplication.packageName, mResolveActivity.name);
+                }
             }
         }
 
@@ -4042,8 +4151,7 @@
             }
 
             if (pkg.mSharedUserId != null) {
-                suid = mSettings.getSharedUserLPw(pkg.mSharedUserId,
-                        pkg.applicationInfo.flags, true);
+                suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, true);
                 if (suid == null) {
                     Slog.w(TAG, "Creating application package " + pkg.packageName
                             + " for shared user failed");
@@ -4540,7 +4648,7 @@
         // version of the application while the new one gets installed.
         if ((parseFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
             killApplication(pkg.applicationInfo.packageName,
-                        pkg.applicationInfo.uid);
+                        pkg.applicationInfo.uid, "update pkg");
         }
 
         // Also need to kill any apps that are dependent on the library.
@@ -4548,7 +4656,7 @@
             for (int i=0; i<clientLibPkgs.size(); i++) {
                 PackageParser.Package clientPkg = clientLibPkgs.get(i);
                 killApplication(clientPkg.applicationInfo.packageName,
-                        clientPkg.applicationInfo.uid);
+                        clientPkg.applicationInfo.uid, "update lib");
             }
         }
 
@@ -4589,6 +4697,24 @@
                 }
             }
 
+            // Add the package's KeySets to the global KeySetManager
+            KeySetManager ksm = mSettings.mKeySetManager;
+            try {
+                ksm.addSigningKeySetToPackage(pkg.packageName, pkg.mSigningKeys);
+                if (pkg.mKeySetMapping != null) {
+                    for (Map.Entry<String, Set<PublicKey>> entry : pkg.mKeySetMapping.entrySet()) {
+                        if (entry.getValue() != null) {
+                            ksm.addDefinedKeySetToPackage(pkg.packageName,
+                                entry.getValue(), entry.getKey());
+                        }
+                    }
+                }
+            } catch (NullPointerException e) {
+                Slog.e(TAG, "Could not add KeySet to " + pkg.packageName, e);
+            } catch (IllegalArgumentException e) {
+                Slog.e(TAG, "Could not add KeySet to malformed package" + pkg.packageName, e);
+            }
+
             int N = pkg.providers.size();
             StringBuilder r = null;
             int i;
@@ -4845,6 +4971,30 @@
         return pkg;
     }
 
+    private void setUpCustomResolverActivity(PackageParser.Package pkg) {
+        synchronized (mPackages) {
+            mResolverReplaced = true;
+            // Set up information for custom user intent resolution activity.
+            mResolveActivity.applicationInfo = pkg.applicationInfo;
+            mResolveActivity.name = mCustomResolverComponentName.getClassName();
+            mResolveActivity.packageName = pkg.applicationInfo.packageName;
+            mResolveActivity.processName = null;
+            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
+            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
+                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
+            mResolveActivity.theme = 0;
+            mResolveActivity.exported = true;
+            mResolveActivity.enabled = true;
+            mResolveInfo.activityInfo = mResolveActivity;
+            mResolveInfo.priority = 0;
+            mResolveInfo.preferredOrder = 0;
+            mResolveInfo.match = 0;
+            mResolveComponentName = mCustomResolverComponentName;
+            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
+                    mResolveComponentName);
+        }
+    }
+
     private void setInternalAppNativeLibraryPath(PackageParser.Package pkg,
             PackageSetting pkgSetting) {
         final String apkLibPath = getApkName(pkgSetting.codePathString);
@@ -4880,14 +5030,14 @@
         return NativeLibraryHelper.copyNativeBinariesIfNeededLI(scanFile, nativeLibraryDir);
     }
 
-    private void killApplication(String pkgName, int appId) {
+    private void killApplication(String pkgName, int appId, String reason) {
         // Request the ActivityManager to kill the process(only for existing packages)
         // so that we do not end up in a confused state while the user is still using the older
         // version of the application while the new one gets installed.
         IActivityManager am = ActivityManagerNative.getDefault();
         if (am != null) {
             try {
-                am.killApplicationWithAppId(pkgName, appId);
+                am.killApplicationWithAppId(pkgName, appId, reason);
             } catch (RemoteException e) {
             }
         }
@@ -5348,17 +5498,20 @@
                             .getDisabledSystemPkgLPr(pkg.packageName);
                     final GrantedPermissions origGp = sysPs.sharedUser != null
                             ? sysPs.sharedUser : sysPs;
+
                     if (origGp.grantedPermissions.contains(perm)) {
+                        // If the original was granted this permission, we take
+                        // that grant decision as read and propagate it to the
+                        // update.
                         allowed = true;
                     } else {
                         // The system apk may have been updated with an older
                         // version of the one on the data partition, but which
                         // granted a new system permission that it didn't have
                         // before.  In this case we do want to allow the app to
-                        // now get the new permission, because it is allowed by
-                        // the system image.
-                        allowed = false;
-                        if (sysPs.pkg != null) {
+                        // now get the new permission if the new system-partition
+                        // apk is privileged to get it.
+                        if (sysPs.pkg != null && isPrivilegedApp(pkg)) {
                             for (int j=0;
                                     j<sysPs.pkg.requestedPermissions.size(); j++) {
                                 if (perm.equals(
@@ -5370,7 +5523,7 @@
                         }
                     }
                 } else {
-                    allowed = true;
+                    allowed = isPrivilegedApp(pkg);
                 }
             }
         }
@@ -5929,10 +6082,11 @@
     }
     
     private final class AppDirObserver extends FileObserver {
-        public AppDirObserver(String path, int mask, boolean isrom) {
+        public AppDirObserver(String path, int mask, boolean isrom, boolean isPrivileged) {
             super(path, mask);
             mRootDir = path;
             mIsRom = isrom;
+            mIsPrivileged = isPrivileged;
         }
 
         public void onEvent(int event, String path) {
@@ -5993,11 +6147,15 @@
                 if ((event&ADD_EVENTS) != 0) {
                     if (p == null) {
                         if (DEBUG_INSTALL) Slog.d(TAG, "New file appeared: " + fullPath);
-                        p = scanPackageLI(fullPath,
-                                (mIsRom ? PackageParser.PARSE_IS_SYSTEM
-                                        | PackageParser.PARSE_IS_SYSTEM_DIR: 0) |
-                                PackageParser.PARSE_CHATTY |
-                                PackageParser.PARSE_MUST_BE_APK,
+                        int flags = PackageParser.PARSE_CHATTY | PackageParser.PARSE_MUST_BE_APK;
+                        if (mIsRom) {
+                            flags |= PackageParser.PARSE_IS_SYSTEM
+                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
+                            if (mIsPrivileged) {
+                                flags |= PackageParser.PARSE_IS_PRIVILEGED;
+                            }
+                        }
+                        p = scanPackageLI(fullPath, flags,
                                 SCAN_MONITOR | SCAN_NO_PATHS | SCAN_UPDATE_TIME,
                                 System.currentTimeMillis(), UserHandle.ALL);
                         if (p != null) {
@@ -6040,6 +6198,7 @@
 
         private final String mRootDir;
         private final boolean mIsRom;
+        private final boolean mIsPrivileged;
     }
 
     /* Called when a downloaded package installation has been confirmed by the user */
@@ -6107,6 +6266,122 @@
         mHandler.sendMessage(msg);
     }
 
+    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId) {
+        Bundle extras = new Bundle(1);
+        extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId));
+
+        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
+                packageName, extras, null, null, new int[] {userId});
+        try {
+            IActivityManager am = ActivityManagerNative.getDefault();
+            final boolean isSystem =
+                    isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
+            if (isSystem && am.isUserRunning(userId, false)) {
+                // The just-installed/enabled app is bundled on the system, so presumed
+                // to be able to run automatically without needing an explicit launch.
+                // Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
+                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED)
+                        .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
+                        .setPackage(packageName);
+                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null,
+                        android.app.AppOpsManager.OP_NONE, false, false, userId);
+            }
+        } catch (RemoteException e) {
+            // shouldn't happen
+            Slog.w(TAG, "Unable to bootstrap installed package", e);
+        }
+    }
+
+    @Override
+    public boolean setApplicationBlockedSettingAsUser(String packageName, boolean blocked,
+            int userId) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
+        PackageSetting pkgSetting;
+        final int uid = Binder.getCallingUid();
+        if (UserHandle.getUserId(uid) != userId) {
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
+                    "setApplicationBlockedSetting for user " + userId);
+        }
+
+        if (blocked && isPackageDeviceAdmin(packageName, userId)) {
+            Slog.w(TAG, "Not blocking package " + packageName + ": has active device admin");
+            return false;
+        }
+
+        long callingId = Binder.clearCallingIdentity();
+        try {
+            boolean sendAdded = false;
+            boolean sendRemoved = false;
+            // writer
+            synchronized (mPackages) {
+                pkgSetting = mSettings.mPackages.get(packageName);
+                if (pkgSetting == null) {
+                    return false;
+                }
+                if (pkgSetting.getBlocked(userId) != blocked) {
+                    pkgSetting.setBlocked(blocked, userId);
+                    mSettings.writePackageRestrictionsLPr(userId);
+                    if (blocked) {
+                        sendRemoved = true;
+                    } else {
+                        sendAdded = true;
+                    }
+                }
+            }
+            if (sendAdded) {
+                sendPackageAddedForUser(packageName, pkgSetting, userId);
+                return true;
+            }
+            if (sendRemoved) {
+                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
+                        "blocking pkg");
+                sendPackageBlockedForUser(packageName, pkgSetting, userId);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(callingId);
+        }
+        return false;
+    }
+
+    private void sendPackageBlockedForUser(String packageName, PackageSetting pkgSetting,
+            int userId) {
+        final PackageRemovedInfo info = new PackageRemovedInfo();
+        info.removedPackage = packageName;
+        info.removedUsers = new int[] {userId};
+        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
+        info.sendBroadcast(false, false, false);
+    }
+
+    /**
+     * Returns true if application is not found or there was an error. Otherwise it returns
+     * the blocked state of the package for the given user.
+     */
+    @Override
+    public boolean getApplicationBlockedSettingAsUser(String packageName, int userId) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
+        PackageSetting pkgSetting;
+        final int uid = Binder.getCallingUid();
+        if (UserHandle.getUserId(uid) != userId) {
+            mContext.enforceCallingPermission(
+                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
+                    "getApplicationBlocked for user " + userId);
+        }
+        long callingId = Binder.clearCallingIdentity();
+        try {
+            // writer
+            synchronized (mPackages) {
+                pkgSetting = mSettings.mPackages.get(packageName);
+                if (pkgSetting == null) {
+                    return true;
+                }
+                return pkgSetting.getBlocked(userId);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(callingId);
+        }
+    }
+
     /**
      * @hide
      */
@@ -6138,33 +6413,14 @@
                 }
                 if (!pkgSetting.getInstalled(userId)) {
                     pkgSetting.setInstalled(true, userId);
+                    pkgSetting.setBlocked(false, userId);
                     mSettings.writePackageRestrictionsLPr(userId);
-                    extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId));
                     sendAdded = true;
                 }
             }
 
             if (sendAdded) {
-                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
-                        packageName, extras, null, null, new int[] {userId});
-                try {
-                    IActivityManager am = ActivityManagerNative.getDefault();
-                    final boolean isSystem =
-                            isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
-                    if (isSystem && am.isUserRunning(userId, false)) {
-                        // The just-installed/enabled app is bundled on the system, so presumed
-                        // to be able to run automatically without needing an explicit launch.
-                        // Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
-                        Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED)
-                                .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
-                                .setPackage(packageName);
-                        am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null,
-                                android.app.AppOpsManager.OP_NONE, false, false, userId);
-                    }
-                } catch (RemoteException e) {
-                    // shouldn't happen
-                    Slog.w(TAG, "Unable to bootstrap installed package", e);
-                }
+                sendPackageAddedForUser(packageName, pkgSetting, userId);
             }
         } finally {
             Binder.restoreCallingIdentity(callingId);
@@ -6640,31 +6896,20 @@
             if (mounted) {
                 final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle);
 
-                final File externalCacheDir = userEnv
-                        .getExternalStorageAppCacheDirectory(mStats.packageName);
-                final long externalCacheSize = mContainerService
-                        .calculateDirectorySize(externalCacheDir.getPath());
-                mStats.externalCacheSize = externalCacheSize;
+                mStats.externalCacheSize = calculateDirectorySize(mContainerService,
+                        userEnv.buildExternalStorageAppCacheDirs(mStats.packageName));
 
-                final File externalDataDir = userEnv
-                        .getExternalStorageAppDataDirectory(mStats.packageName);
-                long externalDataSize = mContainerService.calculateDirectorySize(externalDataDir
-                        .getPath());
+                mStats.externalDataSize = calculateDirectorySize(mContainerService,
+                        userEnv.buildExternalStorageAppDataDirs(mStats.packageName));
 
-                if (externalCacheDir.getParentFile().equals(externalDataDir)) {
-                    externalDataSize -= externalCacheSize;
-                }
-                mStats.externalDataSize = externalDataSize;
+                // Always subtract cache size, since it's a subdirectory
+                mStats.externalDataSize -= mStats.externalCacheSize;
 
-                final File externalMediaDir = userEnv
-                        .getExternalStorageAppMediaDirectory(mStats.packageName);
-                mStats.externalMediaSize = mContainerService
-                        .calculateDirectorySize(externalMediaDir.getPath());
+                mStats.externalMediaSize = calculateDirectorySize(mContainerService,
+                        userEnv.buildExternalStorageAppMediaDirs(mStats.packageName));
 
-                final File externalObbDir = userEnv
-                        .getExternalStorageAppObbDirectory(mStats.packageName);
-                mStats.externalObbSize = mContainerService.calculateDirectorySize(externalObbDir
-                        .getPath());
+                mStats.externalObbSize = calculateDirectorySize(mContainerService,
+                        userEnv.buildExternalStorageAppObbDirs(mStats.packageName));
             }
         }
 
@@ -6686,6 +6931,24 @@
         }
     }
 
+    private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths)
+            throws RemoteException {
+        long result = 0;
+        for (File path : paths) {
+            result += mcs.calculateDirectorySize(path.getAbsolutePath());
+        }
+        return result;
+    }
+
+    private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
+        for (File path : paths) {
+            try {
+                mcs.clearDirectory(path.getAbsolutePath());
+            } catch (RemoteException e) {
+            }
+        }
+    }
+
     class InstallParams extends HandlerParams {
         final IPackageInstallObserver observer;
         int flags;
@@ -8231,6 +8494,9 @@
         boolean updatedSettings = false;
         parseFlags |= PackageManager.INSTALL_REPLACE_EXISTING |
                 PackageParser.PARSE_IS_SYSTEM;
+        if ((deletedPackage.applicationInfo.flags&ApplicationInfo.FLAG_PRIVILEGED) != 0) {
+            parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
+        }
         String packageName = deletedPackage.packageName;
         res.returnCode = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
         if (packageName == null) {
@@ -8250,7 +8516,7 @@
             }
         }
 
-        killApplication(packageName, oldPkg.applicationInfo.uid);
+        killApplication(packageName, oldPkg.applicationInfo.uid, "replace sys pkg");
 
         res.removedInfo.uid = oldPkg.applicationInfo.uid;
         res.removedInfo.removedPackage = packageName;
@@ -8543,6 +8809,10 @@
         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
     }
 
+    private static boolean isPrivilegedApp(PackageParser.Package pkg) {
+        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_PRIVILEGED) != 0;
+    }
+
     private static boolean isSystemApp(ApplicationInfo info) {
         return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
     }
@@ -8651,6 +8921,19 @@
         });
     }
 
+    private boolean isPackageDeviceAdmin(String packageName, int userId) {
+        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
+                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
+        try {
+            if (dpm != null && (dpm.packageHasActiveAdmins(packageName, userId)
+                    || dpm.isDeviceOwner(packageName))) {
+                return true;
+            }
+        } catch (RemoteException e) {
+        }
+        return false;
+    }
+
     /**
      *  This method is an internal method that could be get invoked either
      *  to delete an installed package or to clean up a failed installation.
@@ -8669,15 +8952,9 @@
         final PackageRemovedInfo info = new PackageRemovedInfo();
         final boolean res;
 
-        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
-                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
-        try {
-            if (dpm != null && (dpm.packageHasActiveAdmins(packageName, userId)
-                    || dpm.isDeviceOwner(packageName))) {
-                Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
-                return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
-            }
-        } catch (RemoteException e) {
+        if (isPackageDeviceAdmin(packageName, userId)) {
+            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
+            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
         }
 
         boolean removedForAllUsers = false;
@@ -8993,6 +9270,7 @@
                         false, //installed
                         true,  //stopped
                         true,  //notLaunched
+                        false, //blocked
                         null, null, null);
                 if (!isSystemApp(ps)) {
                     if (ps.isAnyInstalled(sUserManager.getUserIds())) {
@@ -9043,7 +9321,9 @@
             removePackageDataLI(ps, null, null, outInfo, flags, writeSettings);
             return true;
         }
+
         boolean ret = false;
+        mSettings.mKeySetManager.removeAppKeySetData(packageName);
         if (isSystemApp(ps)) {
             if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package:" + ps.name);
             // When an updated system application is deleted we delete the existing resources as well and
@@ -9053,11 +9333,12 @@
         } else {
             if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package:" + ps.name);
             // Kill application pre-emptively especially for apps on sd.
-            killApplication(packageName, ps.appId);
+            killApplication(packageName, ps.appId, "uninstall pkg");
             ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags,
                     allUserHandles, perUserInstalled,
                     outInfo, writeSettings);
         }
+
         return ret;
     }
 
@@ -9119,25 +9400,13 @@
                     }
 
                     final UserEnvironment userEnv = new UserEnvironment(curUser);
-                    final File externalCacheDir = userEnv
-                            .getExternalStorageAppCacheDirectory(packageName);
-                    try {
-                        conn.mContainerService.clearDirectory(externalCacheDir.toString());
-                    } catch (RemoteException e) {
-                    }
+                    clearDirectory(conn.mContainerService,
+                            userEnv.buildExternalStorageAppCacheDirs(packageName));
                     if (allData) {
-                        final File externalDataDir = userEnv
-                                .getExternalStorageAppDataDirectory(packageName);
-                        try {
-                            conn.mContainerService.clearDirectory(externalDataDir.toString());
-                        } catch (RemoteException e) {
-                        }
-                        final File externalMediaDir = userEnv
-                                .getExternalStorageAppMediaDirectory(packageName);
-                        try {
-                            conn.mContainerService.clearDirectory(externalMediaDir.toString());
-                        } catch (RemoteException e) {
-                        }
+                        clearDirectory(conn.mContainerService,
+                                userEnv.buildExternalStorageAppDataDirs(packageName));
+                        clearDirectory(conn.mContainerService,
+                                userEnv.buildExternalStorageAppMediaDirs(packageName));
                     }
                 }
             } finally {
@@ -9410,9 +9679,14 @@
         }
         return Build.VERSION_CODES.CUR_DEVELOPMENT;
     }
-    
+
     public void addPreferredActivity(IntentFilter filter, int match,
             ComponentName[] set, ComponentName activity, int userId) {
+        addPreferredActivityInternal(filter, match, set, activity, true, userId);
+    }
+
+    private void addPreferredActivityInternal(IntentFilter filter, int match,
+            ComponentName[] set, ComponentName activity, boolean always, int userId) {
         // writer
         int callingUid = Binder.getCallingUid();
         enforceCrossUserPermission(callingUid, userId, true, "add preferred activity");
@@ -9433,7 +9707,7 @@
             Slog.i(TAG, "Adding preferred activity " + activity + " for user " + userId + " :");
             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
             mSettings.editPreferredActivitiesLPw(userId).addFilter(
-                    new PreferredActivity(filter, match, set, activity));
+                    new PreferredActivity(filter, match, set, activity, always));
             mSettings.writePackageRestrictionsLPr(userId);
         }
     }
@@ -9444,10 +9718,6 @@
             throw new IllegalArgumentException(
                     "replacePreferredActivity expects filter to have only 1 action.");
         }
-        if (filter.countCategories() != 1) {
-            throw new IllegalArgumentException(
-                    "replacePreferredActivity expects filter to have only 1 category.");
-        }
         if (filter.countDataAuthorities() != 0
                 || filter.countDataPaths() != 0
                 || filter.countDataSchemes() != 0
@@ -9484,8 +9754,11 @@
                             removed = new ArrayList<PreferredActivity>();
                         }
                         removed.add(pa);
-                        Log.i(TAG, "Removing preferred activity " + pa.mPref.mComponent + ":");
-                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
+                        if (DEBUG_PREFERRED) {
+                            Slog.i(TAG, "Removing preferred activity "
+                                    + pa.mPref.mComponent + ":");
+                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
+                        }
                     }
                 }
                 if (removed != null) {
@@ -9495,7 +9768,7 @@
                     }
                 }
             }
-            addPreferredActivity(filter, match, set, activity, callingUserId);
+            addPreferredActivityInternal(filter, match, set, activity, true, callingUserId);
         }
     }
 
@@ -9540,8 +9813,11 @@
             Iterator<PreferredActivity> it = pir.filterIterator();
             while (it.hasNext()) {
                 PreferredActivity pa = it.next();
+                // Mark entry for removal only if it matches the package name
+                // and the entry is of type "always".
                 if (packageName == null ||
-                        pa.mPref.mComponent.getPackageName().equals(packageName)) {
+                        (pa.mPref.mComponent.getPackageName().equals(packageName)
+                                && pa.mPref.mAlways)) {
                     if (removed == null) {
                         removed = new ArrayList<PreferredActivity>();
                     }
@@ -9585,7 +9861,8 @@
                 while (it.hasNext()) {
                     final PreferredActivity pa = it.next();
                     if (packageName == null
-                            || pa.mPref.mComponent.getPackageName().equals(packageName)) {
+                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
+                                    && pa.mPref.mAlways)) {
                         if (outFilters != null) {
                             outFilters.add(new IntentFilter(pa));
                         }
@@ -9601,6 +9878,28 @@
     }
 
     @Override
+    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.addCategory(Intent.CATEGORY_HOME);
+
+        final int callingUserId = UserHandle.getCallingUserId();
+        List<ResolveInfo> list = queryIntentActivities(intent, null, 0, callingUserId);
+        ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
+                true, false, callingUserId);
+
+        allHomeCandidates.clear();
+        if (list != null) {
+            for (ResolveInfo ri : list) {
+                allHomeCandidates.add(ri);
+            }
+        }
+        return (preferred == null || preferred.activityInfo == null)
+                ? null
+                : new ComponentName(preferred.activityInfo.packageName,
+                        preferred.activityInfo.name);
+    }
+
+    @Override
     public void setApplicationEnabledSetting(String appPackageName,
             int newState, int flags, int userId, String callingPackage) {
         if (!sUserManager.exists(userId)) return;
@@ -9854,6 +10153,7 @@
                 }
             }
         }
+        sUserManager.systemReady();
     }
 
     public boolean isSafeMode() {
@@ -9900,6 +10200,8 @@
 
         public static final int DUMP_PREFERRED_XML = 1 << 10;
 
+        public static final int DUMP_KEYSETS = 1 << 11;
+
         public static final int OPTION_SHOW_FILTERS = 1 << 0;
 
         private int mTypes;
@@ -9997,6 +10299,7 @@
                 pw.println("    m[essages]: print collected runtime messages");
                 pw.println("    v[erifiers]: print package verifier info");
                 pw.println("    <package.name>: info about given package");
+                pw.println("    k[eysets]: print known keysets");
                 return;
             } else if ("-f".equals(opt)) {
                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
@@ -10012,6 +10315,9 @@
             // Is this a package name?
             if ("android".equals(cmd) || cmd.contains(".")) {
                 packageName = cmd;
+                // When dumping a single package, we always dump all of its
+                // filter information since the amount of data will be reasonable.
+                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
             } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
                 dumpState.setDump(DumpState.DUMP_LIBS);
             } else if ("f".equals(cmd) || "features".equals(cmd)) {
@@ -10038,6 +10344,8 @@
                 dumpState.setDump(DumpState.DUMP_MESSAGES);
             } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
                 dumpState.setDump(DumpState.DUMP_VERIFIERS);
+            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
+                dumpState.setDump(DumpState.DUMP_KEYSETS);
             }
         }
 
@@ -10045,7 +10353,7 @@
         synchronized (mPackages) {
             if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
                 if (dumpState.onTitlePrinted())
-                    pw.println(" ");
+                    pw.println();
                 pw.println("Verifiers:");
                 pw.print("  Required: ");
                 pw.print(mRequiredVerifierPackage);
@@ -10055,16 +10363,20 @@
             }
 
             if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
-                if (dumpState.onTitlePrinted())
-                    pw.println(" ");
-                pw.println("Libraries:");
+                boolean printedHeader = false;
                 final Iterator<String> it = mSharedLibraries.keySet().iterator();
                 while (it.hasNext()) {
                     String name = it.next();
+                    SharedLibraryEntry ent = mSharedLibraries.get(name);
+                    if (!printedHeader) {
+                        if (dumpState.onTitlePrinted())
+                            pw.println();
+                        pw.println("Libraries:");
+                        printedHeader = true;
+                    }
                     pw.print("  ");
                     pw.print(name);
                     pw.print(" -> ");
-                    SharedLibraryEntry ent = mSharedLibraries.get(name);
                     if (ent.path != null) {
                         pw.print("(jar) ");
                         pw.print(ent.path);
@@ -10078,7 +10390,7 @@
 
             if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
                 if (dumpState.onTitlePrinted())
-                    pw.println(" ");
+                    pw.println();
                 pw.println("Features:");
                 Iterator<String> it = mAvailableFeatures.keySet().iterator();
                 while (it.hasNext()) {
@@ -10154,7 +10466,7 @@
                     }
                     if (!printedSomething) {
                         if (dumpState.onTitlePrinted())
-                            pw.println(" ");
+                            pw.println();
                         pw.println("Registered ContentProviders:");
                         printedSomething = true;
                     }
@@ -10169,7 +10481,7 @@
                     }
                     if (!printedSomething) {
                         if (dumpState.onTitlePrinted())
-                            pw.println(" ");
+                            pw.println();
                         pw.println("ContentProvider Authorities:");
                         printedSomething = true;
                     }
@@ -10181,7 +10493,11 @@
                     }
                 }
             }
-            
+
+            if (dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
+                mSettings.mKeySetManager.dump(pw, packageName, dumpState);
+            }
+
             if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
                 mSettings.dumpPackagesLPr(pw, packageName, dumpState);
             }
@@ -10192,10 +10508,10 @@
 
             if (dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
                 if (dumpState.onTitlePrinted())
-                    pw.println(" ");
+                    pw.println();
                 mSettings.dumpReadMessagesLPr(pw, dumpState);
 
-                pw.println(" ");
+                pw.println();
                 pw.println("Package warning messages:");
                 final File fname = getSettingsProblemFile();
                 FileInputStream in = null;
@@ -10928,42 +11244,9 @@
     }
 
     @Override
+    @Deprecated
     public boolean isPermissionEnforced(String permission) {
-        final boolean enforcedDefault = isPermissionEnforcedDefault(permission);
-        synchronized (mPackages) {
-            return isPermissionEnforcedLocked(permission, enforcedDefault);
-        }
-    }
-
-    /**
-     * Check if given permission should be enforced by default. Should always be
-     * called outside of {@link #mPackages} lock.
-     */
-    private boolean isPermissionEnforcedDefault(String permission) {
-        if (READ_EXTERNAL_STORAGE.equals(permission)) {
-            return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
-                    android.provider.Settings.Global.READ_EXTERNAL_STORAGE_ENFORCED_DEFAULT, 0)
-                    != 0;
-        } else {
-            return true;
-        }
-    }
-
-    /**
-     * Check if user has requested that given permission be enforced, using
-     * given default if undefined.
-     */
-    private boolean isPermissionEnforcedLocked(String permission, boolean enforcedDefault) {
-        if (READ_EXTERNAL_STORAGE.equals(permission)) {
-            if (mSettings.mReadExternalStorageEnforced != null) {
-                return mSettings.mReadExternalStorageEnforced;
-            } else {
-                // User hasn't defined; fall back to secure default
-                return enforcedDefault;
-            }
-        } else {
-            return true;
-        }
+        return true;
     }
 
     public boolean isStorageLow() {
diff --git a/services/java/com/android/server/pm/PackageSetting.java b/services/java/com/android/server/pm/PackageSetting.java
index f7f0870..b6f9f5b 100644
--- a/services/java/com/android/server/pm/PackageSetting.java
+++ b/services/java/com/android/server/pm/PackageSetting.java
@@ -52,4 +52,8 @@
             + Integer.toHexString(System.identityHashCode(this))
             + " " + name + "/" + appId + "}";
     }
-}
\ No newline at end of file
+
+    public int[] getGids() {
+        return sharedUser != null ? sharedUser.gids : gids;
+    }
+}
diff --git a/services/java/com/android/server/pm/PackageSettingBase.java b/services/java/com/android/server/pm/PackageSettingBase.java
index e64ec6d..7747c8f 100644
--- a/services/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/java/com/android/server/pm/PackageSettingBase.java
@@ -65,6 +65,8 @@
     boolean permissionsFixed;
     boolean haveGids;
 
+    PackageKeySetData keySetData = new PackageKeySetData();
+
     private static final PackageUserState DEFAULT_USER_STATE = new PackageUserState();
 
     // Whether this package is currently stopped, thus can not be
@@ -120,6 +122,9 @@
         origPackage = base.origPackage;
 
         installerPackageName = base.installerPackageName;
+
+        keySetData = new PackageKeySetData(base.keySetData);
+
     }
 
     void init(File codePath, File resourcePath, String nativeLibraryPathString,
@@ -170,6 +175,7 @@
             userState.put(base.userState.keyAt(i), base.userState.valueAt(i));
         }
         installStatus = base.installStatus;
+        keySetData = base.keySetData;
     }
 
     private PackageUserState modifyUserState(int userId) {
@@ -254,14 +260,24 @@
         modifyUserState(userId).notLaunched = stop;
     }
 
+    boolean getBlocked(int userId) {
+        return readUserState(userId).blocked;
+    }
+
+    void setBlocked(boolean blocked, int userId) {
+        modifyUserState(userId).blocked = blocked;
+    }
+
     void setUserState(int userId, int enabled, boolean installed, boolean stopped,
-            boolean notLaunched, String lastDisableAppCaller, HashSet<String> enabledComponents,
+            boolean notLaunched, boolean blocked,
+            String lastDisableAppCaller, HashSet<String> enabledComponents,
             HashSet<String> disabledComponents) {
         PackageUserState state = modifyUserState(userId);
         state.enabled = enabled;
         state.installed = installed;
         state.stopped = stopped;
         state.notLaunched = notLaunched;
+        state.blocked = blocked;
         state.lastDisableAppCaller = lastDisableAppCaller;
         state.enabledComponents = enabledComponents;
         state.disabledComponents = disabledComponents;
diff --git a/services/java/com/android/server/pm/PreferredActivity.java b/services/java/com/android/server/pm/PreferredActivity.java
index c655bb1..963cbe4 100644
--- a/services/java/com/android/server/pm/PreferredActivity.java
+++ b/services/java/com/android/server/pm/PreferredActivity.java
@@ -33,13 +33,13 @@
     private static final String TAG = "PreferredActivity";
 
     private static final boolean DEBUG_FILTERS = false;
-    static final String ATTR_USER_ID = "userId";
 
     final PreferredComponent mPref;
 
-    PreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity) {
+    PreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity,
+            boolean always) {
         super(filter);
-        mPref = new PreferredComponent(this, match, set, activity);
+        mPref = new PreferredComponent(this, match, set, activity, always);
     }
 
     PreferredActivity(XmlPullParser parser) throws XmlPullParserException, IOException {
diff --git a/services/java/com/android/server/pm/PreferredIntentResolver.java b/services/java/com/android/server/pm/PreferredIntentResolver.java
index 7fe6a05..bce24d7 100644
--- a/services/java/com/android/server/pm/PreferredIntentResolver.java
+++ b/services/java/com/android/server/pm/PreferredIntentResolver.java
@@ -26,10 +26,12 @@
     protected PreferredActivity[] newArray(int size) {
         return new PreferredActivity[size];
     }
+
     @Override
     protected boolean isPackageForFilter(String packageName, PreferredActivity filter) {
         return packageName.equals(filter.mPref.mComponent.getPackageName());
     }
+
     @Override
     protected void dumpFilter(PrintWriter out, String prefix,
             PreferredActivity filter) {
diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java
index 2e48074..377c390 100644
--- a/services/java/com/android/server/pm/Settings.java
+++ b/services/java/com/android/server/pm/Settings.java
@@ -22,6 +22,8 @@
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
 import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
+import static android.os.Process.SYSTEM_UID;
+import static android.os.Process.PACKAGE_INFO_GID;
 
 import android.content.IntentFilter;
 import android.content.pm.ActivityInfo;
@@ -43,6 +45,7 @@
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ComponentInfo;
+import android.content.pm.KeySet;
 import android.content.pm.PackageCleanItem;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageParser;
@@ -57,6 +60,7 @@
 import android.os.Process;
 import android.os.UserHandle;
 import android.util.Log;
+import android.util.LongSparseArray;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.Xml;
@@ -67,6 +71,7 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.security.PublicKey;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -106,6 +111,7 @@
     private static final String ATTR_ENABLED = "enabled";
     private static final String ATTR_ENABLED_CALLER = "enabledCaller";
     private static final String ATTR_STOPPED = "stopped";
+    private static final String ATTR_BLOCKED = "blocked";
     private static final String ATTR_INSTALLED = "inst";
 
     private final File mSettingsFilename;
@@ -113,12 +119,15 @@
     private final File mPackageListFilename;
     private final File mStoppedPackagesFilename;
     private final File mBackupStoppedPackagesFilename;
+
     final HashMap<String, PackageSetting> mPackages =
             new HashMap<String, PackageSetting>();
     // List of replaced system applications
     private final HashMap<String, PackageSetting> mDisabledSysPackages =
         new HashMap<String, PackageSetting>();
 
+    private static int mFirstAvailableUid = 0;
+
     // These are the last platform API version we were using for
     // the apps installed on internal and external storage.  It is
     // used to grant newer permissions one time during a system upgrade.
@@ -177,6 +186,9 @@
     private final Context mContext;
 
     private final File mSystemDir;
+
+    public final KeySetManager mKeySetManager = new KeySetManager(mPackages);
+
     Settings(Context context) {
         this(context, Environment.getDataDirectory());
     }
@@ -192,6 +204,8 @@
         mSettingsFilename = new File(mSystemDir, "packages.xml");
         mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml");
         mPackageListFilename = new File(mSystemDir, "packages.list");
+        FileUtils.setPermissions(mPackageListFilename, 0660, SYSTEM_UID, PACKAGE_INFO_GID);
+
         // Deprecated: Needed for migration
         mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml");
         mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml");
@@ -337,6 +351,19 @@
         return null;
     }
 
+    void pruneSharedUsersLPw() {
+        ArrayList<String> removeStage = new ArrayList<String>();
+        for (Map.Entry<String,SharedUserSetting> entry : mSharedUsers.entrySet()) {
+            final SharedUserSetting sus = entry.getValue();
+            if (sus == null || sus.packages.size() == 0) {
+                removeStage.add(entry.getKey());
+            }
+        }
+        for (int i = 0; i < removeStage.size(); i++) {
+            mSharedUsers.remove(removeStage.get(i));
+        }
+    }
+
     // Transfer ownership of permissions from one package to another.
     void transferPermissionsLPw(String origPkg, String newPkg) {
         // Transfer ownership of permissions to the new package.
@@ -454,6 +481,7 @@
                                     installed,
                                     true, // stopped,
                                     true, // notLaunched
+                                    false, // blocked
                                     null, null, null);
                             writePackageRestrictionsLPr(user.id);
                         }
@@ -584,7 +612,7 @@
                         "Package " + p.name + " was user "
                         + p.sharedUser + " but is now " + sharedUser
                         + "; I am not changing its files so it will probably fail!");
-                p.sharedUser.packages.remove(p);
+                p.sharedUser.removePackage(p);
             } else if (p.appId != sharedUser.userId) {
                 PackageManagerService.reportSettingsProblem(Log.ERROR,
                     "Package " + p.name + " was user id " + p.appId
@@ -593,7 +621,7 @@
                     + "; I am not changing its files so it will probably fail!");
             }
 
-            sharedUser.packages.add(p);
+            sharedUser.addPackage(p);
             p.sharedUser = sharedUser;
             p.appId = sharedUser.userId;
         }
@@ -653,7 +681,7 @@
         if (p != null) {
             mPackages.remove(name);
             if (p.sharedUser != null) {
-                p.sharedUser.packages.remove(p);
+                p.sharedUser.removePackage(p);
                 if (p.sharedUser.packages.size() == 0) {
                     mSharedUsers.remove(p.sharedUser.name);
                     removeUserIdLPw(p.sharedUser.userId);
@@ -671,8 +699,8 @@
         final PackageSetting p = mPackages.get(name);
         if (p != null) {
             if (p.sharedUser != null) {
-                p.sharedUser.packages.remove(p);
-                p.sharedUser.packages.add(newp);
+                p.sharedUser.removePackage(p);
+                p.sharedUser.addPackage(newp);
             } else {
                 replaceUserIdLPw(p.appId, newp);
             }
@@ -729,6 +757,7 @@
         } else {
             mOtherUserIds.remove(uid);
         }
+        setFirstAvailableUid(uid+1);
     }
 
     private void replaceUserIdLPw(int uid, Object obj) {
@@ -851,6 +880,7 @@
                                 true,   // installed
                                 false,  // stopped
                                 false,  // notLaunched
+                                false,  // blocked
                                 null, null, null);
                     }
                     return;
@@ -904,6 +934,9 @@
                     final String stoppedStr = parser.getAttributeValue(null, ATTR_STOPPED);
                     final boolean stopped = stoppedStr == null
                             ? false : Boolean.parseBoolean(stoppedStr);
+                    final String blockedStr = parser.getAttributeValue(null, ATTR_BLOCKED);
+                    final boolean blocked = blockedStr == null
+                            ? false : Boolean.parseBoolean(blockedStr);
                     final String notLaunchedStr = parser.getAttributeValue(null, ATTR_NOT_LAUNCHED);
                     final boolean notLaunched = stoppedStr == null
                             ? false : Boolean.parseBoolean(notLaunchedStr);
@@ -927,7 +960,7 @@
                         }
                     }
 
-                    ps.setUserState(userId, enabled, installed, stopped, notLaunched,
+                    ps.setUserState(userId, enabled, installed, stopped, notLaunched, blocked,
                             enabledCaller, enabledComponents, disabledComponents);
                 } else if (tagName.equals("preferred-activities")) {
                     readPreferredActivitiesLPw(parser, userId);
@@ -1035,6 +1068,7 @@
                 PackageUserState ustate = pkg.readUserState(userId);
                 if (ustate.stopped || ustate.notLaunched || !ustate.installed
                         || ustate.enabled != COMPONENT_ENABLED_STATE_DEFAULT
+                        || ustate.blocked
                         || (ustate.enabledComponents != null
                                 && ustate.enabledComponents.size() > 0)
                         || (ustate.disabledComponents != null
@@ -1052,6 +1086,9 @@
                     if (ustate.notLaunched) {
                         serializer.attribute(null, ATTR_NOT_LAUNCHED, "true");
                     }
+                    if (ustate.blocked) {
+                        serializer.attribute(null, ATTR_BLOCKED, "true");
+                    }
                     if (ustate.enabled != COMPONENT_ENABLED_STATE_DEFAULT) {
                         serializer.attribute(null, ATTR_ENABLED,
                                 Integer.toString(ustate.enabled));
@@ -1331,6 +1368,8 @@
                 }
             }
             
+            mKeySetManager.writeKeySetManagerLPr(serializer);
+
             serializer.endTag(null, "packages");
 
             serializer.endDocument();
@@ -1348,22 +1387,29 @@
                     -1, -1);
 
             // Write package list file now, use a JournaledFile.
-            //
-            File tempFile = new File(mPackageListFilename.toString() + ".tmp");
+            File tempFile = new File(mPackageListFilename.getAbsolutePath() + ".tmp");
             JournaledFile journal = new JournaledFile(mPackageListFilename, tempFile);
 
-            fstr = new FileOutputStream(journal.chooseForWrite());
+            final File writeTarget = journal.chooseForWrite();
+            fstr = new FileOutputStream(writeTarget);
             str = new BufferedOutputStream(fstr);
             try {
+                FileUtils.setPermissions(fstr.getFD(), 0660, SYSTEM_UID, PACKAGE_INFO_GID);
+
                 StringBuilder sb = new StringBuilder();
                 for (final PackageSetting pkg : mPackages.values()) {
-                    ApplicationInfo ai = pkg.pkg.applicationInfo;
-                    String dataPath = ai.dataDir;
-                    boolean isDebug  = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
+                    if (pkg.pkg == null || pkg.pkg.applicationInfo == null) {
+                        Slog.w(TAG, "Skipping " + pkg + " due to missing metadata");
+                        continue;
+                    }
 
-                    // Avoid any application that has a space in its path
-                    // or that is handled by the system.
-                    if (dataPath.indexOf(" ") >= 0 || ai.uid < Process.FIRST_APPLICATION_UID)
+                    final ApplicationInfo ai = pkg.pkg.applicationInfo;
+                    final String dataPath = ai.dataDir;
+                    final boolean isDebug = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
+                    final int[] gids = pkg.getGids();
+
+                    // Avoid any application that has a space in its path.
+                    if (dataPath.indexOf(" ") >= 0)
                         continue;
 
                     // we store on each line the following information for now:
@@ -1373,12 +1419,14 @@
                     // debugFlag  - 0 or 1 if the package is debuggable.
                     // dataPath   - path to package's data path
                     // seinfo     - seinfo label for the app (assigned at install time)
+                    // gids       - supplementary gids this app launches with
                     //
                     // NOTE: We prefer not to expose all ApplicationInfo flags for now.
                     //
                     // DO NOT MODIFY THIS FORMAT UNLESS YOU CAN ALSO MODIFY ITS USERS
                     // FROM NATIVE CODE. AT THE MOMENT, LOOK AT THE FOLLOWING SOURCES:
                     //   system/core/run-as/run-as.c
+                    //   system/core/sdcard/sdcard.c
                     //
                     sb.setLength(0);
                     sb.append(ai.packageName);
@@ -1388,6 +1436,16 @@
                     sb.append(dataPath);
                     sb.append(" ");
                     sb.append(ai.seinfo);
+                    sb.append(" ");
+                    if (gids != null && gids.length > 0) {
+                        sb.append(gids[0]);
+                        for (int i = 1; i < gids.length; i++) {
+                            sb.append(",");
+                            sb.append(gids[i]);
+                        }
+                    } else {
+                        sb.append("none");
+                    }
                     sb.append("\n");
                     str.write(sb.toString().getBytes());
                 }
@@ -1396,15 +1454,11 @@
                 str.close();
                 journal.commit();
             } catch (Exception e) {
+                Log.wtf(TAG, "Failed to write packages.list", e);
                 IoUtils.closeQuietly(str);
                 journal.rollback();
             }
 
-            FileUtils.setPermissions(mPackageListFilename.toString(),
-                    FileUtils.S_IRUSR|FileUtils.S_IWUSR
-                    |FileUtils.S_IRGRP|FileUtils.S_IWGRP,
-                    -1, -1);
-
             writeAllUsersPackageRestrictionsLPr();
             return;
 
@@ -1521,9 +1575,31 @@
             serializer.endTag(null, "perms");
         }
 
+        writeSigningKeySetsLPr(serializer, pkg.keySetData);
+        writeKeySetAliasesLPr(serializer, pkg.keySetData);
+
         serializer.endTag(null, "package");
     }
 
+    void writeSigningKeySetsLPr(XmlSerializer serializer,
+            PackageKeySetData data) throws IOException {
+        for (long id : data.getSigningKeySets()) {
+            serializer.startTag(null, "signing-keyset");
+            serializer.attribute(null, "identifier", Long.toString(id));
+            serializer.endTag(null, "signing-keyset");
+        }
+    }
+
+    void writeKeySetAliasesLPr(XmlSerializer serializer,
+            PackageKeySetData data) throws IOException {
+        for (Map.Entry<String, Long> e: data.getAliases().entrySet()) {
+            serializer.startTag(null, "defined-keyset");
+            serializer.attribute(null, "alias", e.getKey());
+            serializer.attribute(null, "identifier", Long.toString(e.getValue()));
+            serializer.endTag(null, "defined-keyset");
+        }
+    }
+
     void writePermissionLPr(XmlSerializer serializer, BasePermission bp)
             throws XmlPullParserException, java.io.IOException {
         if (bp.type != BasePermission.TYPE_BUILTIN && bp.sourcePackage != null) {
@@ -1698,6 +1774,8 @@
                 } else if (TAG_READ_EXTERNAL_STORAGE.equals(tagName)) {
                     final String enforcement = parser.getAttributeValue(null, ATTR_ENFORCEMENT);
                     mReadExternalStorageEnforced = "1".equals(enforcement);
+                } else if (tagName.equals("keyset-settings")) {
+                    mKeySetManager.readKeySetsLPw(parser);
                 } else {
                     Slog.w(PackageManagerService.TAG, "Unknown element under <packages>: "
                             + parser.getName());
@@ -1785,6 +1863,20 @@
     }
 
     void readDefaultPreferredAppsLPw(PackageManagerService service, int userId) {
+        // First pull data from any pre-installed apps.
+        for (PackageSetting ps : mPackages.values()) {
+            if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0 && ps.pkg != null
+                    && ps.pkg.preferredActivityFilters != null) {
+                ArrayList<PackageParser.ActivityIntentInfo> intents
+                        = ps.pkg.preferredActivityFilters;
+                for (int i=0; i<intents.size(); i++) {
+                    PackageParser.ActivityIntentInfo aii = intents.get(i);
+                    applyDefaultPreferredActivityLPw(service, aii, new ComponentName(
+                            ps.name, aii.activity.className), userId);
+                }
+            }
+        }
+
         // Read preferred apps from .../etc/preferred-apps directory.
         File preferredDir = new File(Environment.getRootDirectory(), "etc/preferred-apps");
         if (!preferredDir.exists() || !preferredDir.isDirectory()) {
@@ -1844,6 +1936,166 @@
         }
     }
 
+    private void applyDefaultPreferredActivityLPw(PackageManagerService service,
+            IntentFilter tmpPa, ComponentName cn, int userId) {
+        // The initial preferences only specify the target activity
+        // component and intent-filter, not the set of matches.  So we
+        // now need to query for the matches to build the correct
+        // preferred activity entry.
+        if (PackageManagerService.DEBUG_PREFERRED) {
+            Log.d(TAG, "Processing preferred:");
+            tmpPa.dump(new LogPrinter(Log.DEBUG, TAG), "  ");
+        }
+        Intent intent = new Intent();
+        int flags = 0;
+        intent.setAction(tmpPa.getAction(0));
+        for (int i=0; i<tmpPa.countCategories(); i++) {
+            String cat = tmpPa.getCategory(i);
+            if (cat.equals(Intent.CATEGORY_DEFAULT)) {
+                flags |= PackageManager.MATCH_DEFAULT_ONLY;
+            } else {
+                intent.addCategory(cat);
+            }
+        }
+
+        boolean doNonData = true;
+
+        for (int ischeme=0; ischeme<tmpPa.countDataSchemes(); ischeme++) {
+            boolean doScheme = true;
+            String scheme = tmpPa.getDataScheme(ischeme);
+            for (int issp=0; issp<tmpPa.countDataSchemeSpecificParts(); issp++) {
+                Uri.Builder builder = new Uri.Builder();
+                builder.scheme(scheme);
+                PatternMatcher ssp = tmpPa.getDataSchemeSpecificPart(issp);
+                builder.opaquePart(ssp.getPath());
+                Intent finalIntent = new Intent(intent);
+                finalIntent.setData(builder.build());
+                applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
+                        scheme, ssp, null, null, null, userId);
+                doScheme = false;
+            }
+            for (int iauth=0; iauth<tmpPa.countDataAuthorities(); iauth++) {
+                boolean doAuth = true;
+                IntentFilter.AuthorityEntry auth = tmpPa.getDataAuthority(iauth);
+                for (int ipath=0; ipath<tmpPa.countDataPaths(); ipath++) {
+                    Uri.Builder builder = new Uri.Builder();
+                    builder.scheme(scheme);
+                    if (auth.getHost() != null) {
+                        builder.authority(auth.getHost());
+                    }
+                    PatternMatcher path = tmpPa.getDataPath(ipath);
+                    builder.path(path.getPath());
+                    Intent finalIntent = new Intent(intent);
+                    finalIntent.setData(builder.build());
+                    applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
+                            scheme, null, auth, path, null, userId);
+                    doAuth = doScheme = false;
+                }
+                if (doAuth) {
+                    Uri.Builder builder = new Uri.Builder();
+                    builder.scheme(scheme);
+                    if (auth.getHost() != null) {
+                        builder.authority(auth.getHost());
+                    }
+                    Intent finalIntent = new Intent(intent);
+                    finalIntent.setData(builder.build());
+                    applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
+                            scheme, null, auth, null, null, userId);
+                    doScheme = false;
+                }
+            }
+            if (doScheme) {
+                Uri.Builder builder = new Uri.Builder();
+                builder.scheme(scheme);
+                Intent finalIntent = new Intent(intent);
+                finalIntent.setData(builder.build());
+                applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
+                        scheme, null, null, null, null, userId);
+            }
+            doNonData = false;
+        }
+
+        for (int idata=0; idata<tmpPa.countDataTypes(); idata++) {
+            Intent finalIntent = new Intent(intent);
+            String mimeType = tmpPa.getDataType(idata);
+            finalIntent.setType(mimeType);
+            applyDefaultPreferredActivityLPw(service, finalIntent, flags, cn,
+                    null, null, null, null, mimeType, userId);
+            doNonData = false;
+        }
+
+        if (doNonData) {
+            applyDefaultPreferredActivityLPw(service, intent, flags, cn,
+                    null, null, null, null, null, userId);
+        }
+    }
+
+    private void applyDefaultPreferredActivityLPw(PackageManagerService service,
+            Intent intent, int flags, ComponentName cn, String scheme, PatternMatcher ssp,
+            IntentFilter.AuthorityEntry auth, PatternMatcher path, String mimeType,
+            int userId) {
+        List<ResolveInfo> ri = service.mActivities.queryIntent(intent,
+                intent.getType(), flags, 0);
+        if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Queried " + intent
+                + " results: " + ri);
+        int match = 0;
+        if (ri != null && ri.size() > 1) {
+            boolean haveAct = false;
+            boolean haveNonSys = false;
+            ComponentName[] set = new ComponentName[ri.size()];
+            for (int i=0; i<ri.size(); i++) {
+                ActivityInfo ai = ri.get(i).activityInfo;
+                set[i] = new ComponentName(ai.packageName, ai.name);
+                if ((ai.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
+                    // If any of the matches are not system apps, then
+                    // there is a third party app that is now an option...
+                    // so don't set a default since we don't want to hide it.
+                    if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
+                            + ai.packageName + "/" + ai.name + ": non-system!");
+                    haveNonSys = true;
+                    break;
+                } else if (cn.getPackageName().equals(ai.packageName)
+                        && cn.getClassName().equals(ai.name)) {
+                    if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
+                            + ai.packageName + "/" + ai.name + ": default!");
+                    haveAct = true;
+                    match = ri.get(i).match;
+                } else {
+                    if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
+                            + ai.packageName + "/" + ai.name + ": skipped");
+                }
+            }
+            if (haveAct && !haveNonSys) {
+                IntentFilter filter = new IntentFilter();
+                if (intent.getAction() != null) {
+                    filter.addAction(intent.getAction());
+                }
+                for (String cat : intent.getCategories()) {
+                    filter.addCategory(cat);
+                }
+                if ((flags&PackageManager.MATCH_DEFAULT_ONLY) != 0) {
+                    filter.addCategory(Intent.CATEGORY_DEFAULT);
+                }
+                if (scheme != null) {
+                    filter.addDataScheme(scheme);
+                }
+                if (ssp != null) {
+                    filter.addDataSchemeSpecificPart(ssp.getPath(), ssp.getType());
+                }
+                if (auth != null) {
+                    filter.addDataAuthority(auth);
+                }
+                if (path != null) {
+                    filter.addDataPath(path);
+                }
+                PreferredActivity pa = new PreferredActivity(filter, match, set, cn, true);
+                editPreferredActivitiesLPw(userId).addFilter(pa);
+            } else if (!haveNonSys) {
+                Slog.w(TAG, "No component found for default preferred activity " + cn);
+            }
+        }
+    }
+
     private void readDefaultPreferredActivitiesLPw(PackageManagerService service,
             XmlPullParser parser, int userId)
             throws XmlPullParserException, IOException {
@@ -1859,83 +2111,8 @@
             if (tagName.equals(TAG_ITEM)) {
                 PreferredActivity tmpPa = new PreferredActivity(parser);
                 if (tmpPa.mPref.getParseError() == null) {
-                    // The initial preferences only specify the target activity
-                    // component and intent-filter, not the set of matches.  So we
-                    // now need to query for the matches to build the correct
-                    // preferred activity entry.
-                    if (PackageManagerService.DEBUG_PREFERRED) {
-                        Log.d(TAG, "Processing preferred:");
-                        tmpPa.dump(new LogPrinter(Log.DEBUG, TAG), "  ");
-                    }
-                    final ComponentName cn = tmpPa.mPref.mComponent;
-                    Intent intent = new Intent();
-                    int flags = 0;
-                    intent.setAction(tmpPa.getAction(0));
-                    for (int i=0; i<tmpPa.countCategories(); i++) {
-                        String cat = tmpPa.getCategory(i);
-                        if (cat.equals(Intent.CATEGORY_DEFAULT)) {
-                            flags |= PackageManager.MATCH_DEFAULT_ONLY;
-                        } else {
-                            intent.addCategory(cat);
-                        }
-                    }
-                    if (tmpPa.countDataSchemes() > 0) {
-                        Uri.Builder builder = new Uri.Builder();
-                        builder.scheme(tmpPa.getDataScheme(0));
-                        if (tmpPa.countDataAuthorities() > 0) {
-                            IntentFilter.AuthorityEntry auth = tmpPa.getDataAuthority(0);
-                            if (auth.getHost() != null) {
-                                builder.authority(auth.getHost());
-                            }
-                        }
-                        if (tmpPa.countDataPaths() > 0) {
-                            PatternMatcher path = tmpPa.getDataPath(0);
-                            builder.path(path.getPath());
-                        }
-                        intent.setData(builder.build());
-                    } else if (tmpPa.countDataTypes() > 0) {
-                        intent.setType(tmpPa.getDataType(0));
-                    }
-                    List<ResolveInfo> ri = service.mActivities.queryIntent(intent,
-                            intent.getType(), flags, 0);
-                    if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Queried " + intent
-                            + " results: " + ri);
-                    int match = 0;
-                    if (ri != null && ri.size() > 1) {
-                        boolean haveAct = false;
-                        boolean haveNonSys = false;
-                        ComponentName[] set = new ComponentName[ri.size()];
-                        for (int i=0; i<ri.size(); i++) {
-                            ActivityInfo ai = ri.get(i).activityInfo;
-                            set[i] = new ComponentName(ai.packageName, ai.name);
-                            if ((ai.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
-                                // If any of the matches are not system apps, then
-                                // there is a third party app that is now an option...
-                                // so don't set a default since we don't want to hide it.
-                                if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
-                                        + ai.packageName + "/" + ai.name + ": non-system!");
-                                haveNonSys = true;
-                                break;
-                            } else if (cn.getPackageName().equals(ai.packageName)
-                                    && cn.getClassName().equals(ai.name)) {
-                                if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
-                                        + ai.packageName + "/" + ai.name + ": default!");
-                                haveAct = true;
-                                match = ri.get(i).match;
-                            } else {
-                                if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
-                                        + ai.packageName + "/" + ai.name + ": skipped");
-                            }
-                        }
-                        if (haveAct && !haveNonSys) {
-                            PreferredActivity pa = new PreferredActivity(tmpPa, match, set,
-                                    tmpPa.mPref.mComponent);
-                            editPreferredActivitiesLPw(userId).addFilter(pa);
-                        } else if (!haveNonSys) {
-                            Slog.w(TAG, "No component found for default preferred activity "
-                                    + tmpPa.mPref.mComponent);
-                        }
-                    }
+                    applyDefaultPreferredActivityLPw(service, tmpPa, tmpPa.mPref.mComponent,
+                            userId);
                 } else {
                     PackageManagerService.reportSettingsProblem(Log.WARN,
                             "Error in package manager settings: <preferred-activity> "
@@ -2293,12 +2470,22 @@
                 } else if (tagName.equals("perms")) {
                     readGrantedPermissionsLPw(parser, packageSetting.grantedPermissions);
                     packageSetting.permissionsFixed = true;
+                } else if (tagName.equals("signing-keyset")) {
+                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
+                    packageSetting.keySetData.addSigningKeySet(id);
+                    Slog.d(TAG, "Adding signing keyset " + Long.toString(id) + " to " + name);
+                } else if (tagName.equals("defined-keyset")) {
+                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
+                    String alias = parser.getAttributeValue(null, "alias");
+                    packageSetting.keySetData.addDefinedKeySet(id, alias);
                 } else {
                     PackageManagerService.reportSettingsProblem(Log.WARN,
                             "Unknown element under <package>: " + parser.getName());
                     XmlUtils.skipCurrentTag(parser);
                 }
             }
+
+
         } else {
             XmlUtils.skipCurrentTag(parser);
         }
@@ -2477,11 +2664,18 @@
         file.delete();
     }
 
+    // This should be called (at least) whenever an application is removed
+    private void setFirstAvailableUid(int uid) {
+        if (uid > mFirstAvailableUid) {
+            mFirstAvailableUid = uid;
+        }
+    }
+
     // Returns -1 if we could not find an available UserId to assign
     private int newUserIdLPw(Object obj) {
         // Let's be stupidly inefficient for now...
         final int N = mUserIds.size();
-        for (int i = 0; i < N; i++) {
+        for (int i = mFirstAvailableUid; i < N; i++) {
             if (mUserIds.get(i) == null) {
                 mUserIds.set(i, obj);
                 return Process.FIRST_APPLICATION_UID + i;
@@ -2659,6 +2853,7 @@
         ApplicationInfo.FLAG_RESTORE_ANY_VERSION, "RESTORE_ANY_VERSION",
         ApplicationInfo.FLAG_EXTERNAL_STORAGE, "EXTERNAL_STORAGE",
         ApplicationInfo.FLAG_LARGE_HEAP, "LARGE_HEAP",
+        ApplicationInfo.FLAG_PRIVILEGED, "PRIVILEGED",
         ApplicationInfo.FLAG_FORWARD_LOCK, "FORWARD_LOCK",
         ApplicationInfo.FLAG_CANT_SAVE_STATE, "CANT_SAVE_STATE",
     };
@@ -2790,6 +2985,8 @@
             pw.print(prefix); pw.print("  User "); pw.print(user.id); pw.print(": ");
             pw.print(" installed=");
             pw.print(ps.getInstalled(user.id));
+            pw.print(" blocked=");
+            pw.print(ps.getBlocked(user.id));
             pw.print(" stopped=");
             pw.print(ps.getStopped(user.id));
             pw.print(" notLaunched=");
@@ -2841,7 +3038,7 @@
 
             if (!printedSomething) {
                 if (dumpState.onTitlePrinted())
-                    pw.println(" ");
+                    pw.println();
                 pw.println("Packages:");
                 printedSomething = true;
             }
@@ -2857,7 +3054,7 @@
                 }
                 if (!printedSomething) {
                     if (dumpState.onTitlePrinted())
-                        pw.println(" ");
+                        pw.println();
                     pw.println("Renamed packages:");
                     printedSomething = true;
                 }
@@ -2877,7 +3074,7 @@
                 }
                 if (!printedSomething) {
                     if (dumpState.onTitlePrinted())
-                        pw.println(" ");
+                        pw.println();
                     pw.println("Hidden system packages:");
                     printedSomething = true;
                 }
@@ -2894,7 +3091,7 @@
             }
             if (!printedSomething) {
                 if (dumpState.onTitlePrinted())
-                    pw.println(" ");
+                    pw.println();
                 pw.println("Permissions:");
                 printedSomething = true;
             }
@@ -2928,7 +3125,7 @@
             }
             if (!printedSomething) {
                 if (dumpState.onTitlePrinted())
-                    pw.println(" ");
+                    pw.println();
                 pw.println("Shared users:");
                 printedSomething = true;
             }
diff --git a/services/java/com/android/server/pm/SharedUserSetting.java b/services/java/com/android/server/pm/SharedUserSetting.java
index 76826ea..ca1eeea 100644
--- a/services/java/com/android/server/pm/SharedUserSetting.java
+++ b/services/java/com/android/server/pm/SharedUserSetting.java
@@ -26,12 +26,16 @@
 
     int userId;
 
+    // flags that are associated with this uid, regardless of any package flags
+    int uidFlags;
+
     final HashSet<PackageSetting> packages = new HashSet<PackageSetting>();
 
     final PackageSignatures signatures = new PackageSignatures();
 
     SharedUserSetting(String _name, int _pkgFlags) {
         super(_pkgFlags);
+        uidFlags =  _pkgFlags;
         name = _name;
     }
 
@@ -40,4 +44,23 @@
         return "SharedUserSetting{" + Integer.toHexString(System.identityHashCode(this)) + " "
                 + name + "/" + userId + "}";
     }
+
+    void removePackage(PackageSetting packageSetting) {
+        if (packages.remove(packageSetting)) {
+            // recalculate the pkgFlags for this shared user if needed
+            if ((this.pkgFlags & packageSetting.pkgFlags) != 0) {
+                int aggregatedFlags = uidFlags;
+                for (PackageSetting ps : packages) {
+                    aggregatedFlags |= ps.pkgFlags;
+                }
+                setFlags(aggregatedFlags);
+            }
+        }
+    }
+
+    void addPackage(PackageSetting packageSetting) {
+        if (packages.add(packageSetting)) {
+            setFlags(this.pkgFlags | packageSetting.pkgFlags);
+        }
+    }
 }
diff --git a/services/java/com/android/server/pm/UserManagerService.java b/services/java/com/android/server/pm/UserManagerService.java
index 1323c93..d0e9fe1 100644
--- a/services/java/com/android/server/pm/UserManagerService.java
+++ b/services/java/com/android/server/pm/UserManagerService.java
@@ -21,11 +21,12 @@
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
+import android.app.ActivityThread;
 import android.app.IStopUserCallback;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
-import android.content.RestrictionEntry;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.UserInfo;
@@ -42,12 +43,14 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.AtomicFile;
+import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 import android.util.TimeUtils;
 import android.util.Xml;
 
+import com.android.internal.content.PackageMonitor;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FastXmlSerializer;
 
@@ -63,6 +66,9 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -78,6 +84,10 @@
     private static final String ATTR_ID = "id";
     private static final String ATTR_CREATION_TIME = "created";
     private static final String ATTR_LAST_LOGGED_IN_TIME = "lastLoggedIn";
+    private static final String ATTR_SALT = "salt";
+    private static final String ATTR_PIN_HASH = "pinHash";
+    private static final String ATTR_FAILED_ATTEMPTS = "failedAttempts";
+    private static final String ATTR_LAST_RETRY_MS = "lastAttemptMs";
     private static final String ATTR_SERIAL_NO = "serialNumber";
     private static final String ATTR_NEXT_SERIAL_NO = "nextSerialNumber";
     private static final String ATTR_PARTIAL = "partial";
@@ -103,10 +113,17 @@
 
     private static final int MIN_USER_ID = 10;
 
-    private static final int USER_VERSION = 2;
+    private static final int USER_VERSION = 4;
 
     private static final long EPOCH_PLUS_30_YEARS = 30L * 365 * 24 * 60 * 60 * 1000L; // ms
 
+    // Number of attempts before jumping to the next BACKOFF_TIMES slot
+    private static final int BACKOFF_INC_INTERVAL = 5;
+
+    // Amount of time to force the user to wait before entering the PIN again, after failing
+    // BACKOFF_INC_INTERVAL times.
+    private static final int[] BACKOFF_TIMES = { 0, 30*1000, 60*1000, 5*60*1000, 30*60*1000 };
+
     private final Context mContext;
     private final PackageManagerService mPm;
     private final Object mInstallLock;
@@ -121,6 +138,16 @@
     private final SparseArray<UserInfo> mUsers = new SparseArray<UserInfo>();
     private final SparseArray<Bundle> mUserRestrictions = new SparseArray<Bundle>();
 
+    class RestrictionsPinState {
+        long salt;
+        String pinHash;
+        int failedAttempts;
+        long lastAttemptTime;
+    }
+
+    private final SparseArray<RestrictionsPinState> mRestrictionsPinStates =
+            new SparseArray<RestrictionsPinState>();
+
     /**
      * Set of user IDs being actively removed. Removed IDs linger in this set
      * for several seconds to work around a VFS caching issue.
@@ -204,6 +231,13 @@
         }
     }
 
+    void systemReady() {
+        final Context context = ActivityThread.systemMain().getSystemContext();
+        mUserPackageMonitor.register(context,
+                null, UserHandle.ALL, false);
+        userForeground(UserHandle.USER_OWNER);
+    }
+
     @Override
     public List<UserInfo> getUsers(boolean excludeDying) {
         checkManageUsersPermission("query users");
@@ -379,8 +413,10 @@
     @Override
     public void setUserRestrictions(Bundle restrictions, int userId) {
         checkManageUsersPermission("setUserRestrictions");
+        if (restrictions == null) return;
 
         synchronized (mPackagesLock) {
+            mUserRestrictions.get(userId).clear();
             mUserRestrictions.get(userId).putAll(restrictions);
             writeUserLocked(mUsers.get(userId));
         }
@@ -452,12 +488,6 @@
         return mUserIds;
     }
 
-    private void readUserList() {
-        synchronized (mPackagesLock) {
-            readUserListLocked();
-        }
-    }
-
     private void readUserListLocked() {
         mGuestEnabled = false;
         if (!mUserListFile.exists()) {
@@ -511,7 +541,7 @@
                 }
             }
             updateUserIdsLocked();
-            upgradeIfNecessary();
+            upgradeIfNecessaryLocked();
         } catch (IOException ioe) {
             fallbackToSingleUserLocked();
         } catch (XmlPullParserException pe) {
@@ -529,7 +559,7 @@
     /**
      * Upgrade steps between versions, either for fixing bugs or changing the data format.
      */
-    private void upgradeIfNecessary() {
+    private void upgradeIfNecessaryLocked() {
         int userVersion = mUserVersion;
         if (userVersion < 1) {
             // Assign a proper name for the owner, if not initialized correctly before
@@ -551,6 +581,11 @@
             userVersion = 2;
         }
 
+
+        if (userVersion < 4) {
+            userVersion = 4;
+        }
+
         if (userVersion < USER_VERSION) {
             Slog.w(LOG_TAG, "User version " + mUserVersion + " didn't upgrade as expected to "
                     + USER_VERSION);
@@ -567,6 +602,7 @@
                 UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY | UserInfo.FLAG_INITIALIZED);
         mUsers.put(0, primary);
         mNextSerialNumber = MIN_USER_ID;
+        mUserVersion = USER_VERSION;
 
         Bundle restrictions = new Bundle();
         mUserRestrictions.append(UserHandle.USER_OWNER, restrictions);
@@ -604,6 +640,21 @@
             serializer.attribute(null, ATTR_CREATION_TIME, Long.toString(userInfo.creationTime));
             serializer.attribute(null, ATTR_LAST_LOGGED_IN_TIME,
                     Long.toString(userInfo.lastLoggedInTime));
+            RestrictionsPinState pinState = mRestrictionsPinStates.get(userInfo.id);
+            if (pinState != null) {
+                if (pinState.salt != 0) {
+                    serializer.attribute(null, ATTR_SALT, Long.toString(pinState.salt));
+                }
+                if (pinState.pinHash != null) {
+                    serializer.attribute(null, ATTR_PIN_HASH, pinState.pinHash);
+                }
+                if (pinState.failedAttempts != 0) {
+                    serializer.attribute(null, ATTR_FAILED_ATTEMPTS,
+                            Integer.toString(pinState.failedAttempts));
+                    serializer.attribute(null, ATTR_LAST_RETRY_MS,
+                            Long.toString(pinState.lastAttemptTime));
+                }
+            }
             if (userInfo.iconPath != null) {
                 serializer.attribute(null,  ATTR_ICON_PATH, userInfo.iconPath);
             }
@@ -690,6 +741,10 @@
         String iconPath = null;
         long creationTime = 0L;
         long lastLoggedInTime = 0L;
+        long salt = 0L;
+        String pinHash = null;
+        int failedAttempts = 0;
+        long lastAttemptTime = 0L;
         boolean partial = false;
         Bundle restrictions = new Bundle();
 
@@ -722,6 +777,10 @@
                 iconPath = parser.getAttributeValue(null, ATTR_ICON_PATH);
                 creationTime = readLongAttribute(parser, ATTR_CREATION_TIME, 0);
                 lastLoggedInTime = readLongAttribute(parser, ATTR_LAST_LOGGED_IN_TIME, 0);
+                salt = readLongAttribute(parser, ATTR_SALT, 0L);
+                pinHash = parser.getAttributeValue(null, ATTR_PIN_HASH);
+                failedAttempts = readIntAttribute(parser, ATTR_FAILED_ATTEMPTS, 0);
+                lastAttemptTime = readLongAttribute(parser, ATTR_LAST_RETRY_MS, 0L);
                 String valueString = parser.getAttributeValue(null, ATTR_PARTIAL);
                 if ("true".equals(valueString)) {
                     partial = true;
@@ -761,6 +820,17 @@
             userInfo.lastLoggedInTime = lastLoggedInTime;
             userInfo.partial = partial;
             mUserRestrictions.append(id, restrictions);
+            if (salt != 0L) {
+                RestrictionsPinState pinState = mRestrictionsPinStates.get(id);
+                if (pinState == null) {
+                    pinState = new RestrictionsPinState();
+                    mRestrictionsPinStates.put(id, pinState);
+                }
+                pinState.salt = salt;
+                pinState.pinHash = pinHash;
+                pinState.failedAttempts = failedAttempts;
+                pinState.lastAttemptTime = lastAttemptTime;
+            }
             return userInfo;
 
         } catch (IOException ioe) {
@@ -812,6 +882,57 @@
         }
     }
 
+    private boolean isPackageInstalled(String pkg, int userId) {
+        final ApplicationInfo info = mPm.getApplicationInfo(pkg,
+                PackageManager.GET_UNINSTALLED_PACKAGES,
+                userId);
+        if (info == null || (info.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Removes all the restrictions files (res_<packagename>) for a given user, if all is true,
+     * else removes only those packages that have been uninstalled.
+     * Does not do any permissions checking.
+     */
+    private void cleanAppRestrictions(int userId, boolean all) {
+        synchronized (mPackagesLock) {
+            File dir = Environment.getUserSystemDirectory(userId);
+            String[] files = dir.list();
+            if (files == null) return;
+            for (String fileName : files) {
+                if (fileName.startsWith(RESTRICTIONS_FILE_PREFIX)) {
+                    File resFile = new File(dir, fileName);
+                    if (resFile.exists()) {
+                        if (all) {
+                            resFile.delete();
+                        } else {
+                            String pkg = fileName.substring(RESTRICTIONS_FILE_PREFIX.length());
+                            if (!isPackageInstalled(pkg, userId)) {
+                                resFile.delete();
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Removes the app restrictions file for a specific package and user id, if it exists.
+     */
+    private void cleanAppRestrictionsForPackage(String pkg, int userId) {
+        synchronized (mPackagesLock) {
+            File dir = Environment.getUserSystemDirectory(userId);
+            File resFile = new File(dir, RESTRICTIONS_FILE_PREFIX + pkg);
+            if (resFile.exists()) {
+                resFile.delete();
+            }
+        }
+    }
+
     @Override
     public UserInfo createUser(String name, int flags) {
         checkManageUsersPermission("Only the system can create users");
@@ -949,6 +1070,7 @@
             }
         }, MINUTE_IN_MILLIS);
 
+        mRestrictionsPinStates.remove(userHandle);
         // Remove user file
         AtomicFile userFile = new AtomicFile(new File(mUsersDir, userHandle + ".xml"));
         userFile.delete();
@@ -999,6 +1121,171 @@
         }
     }
 
+    @Override
+    public boolean setRestrictionsChallenge(String newPin) {
+        checkManageUsersPermission("Only system can modify the restrictions pin");
+        int userId = UserHandle.getCallingUserId();
+        synchronized (mPackagesLock) {
+            RestrictionsPinState pinState = mRestrictionsPinStates.get(userId);
+            if (pinState == null) {
+                pinState = new RestrictionsPinState();
+            }
+            if (newPin == null) {
+                pinState.salt = 0;
+                pinState.pinHash = null;
+            } else {
+                try {
+                    pinState.salt = SecureRandom.getInstance("SHA1PRNG").nextLong();
+                } catch (NoSuchAlgorithmException e) {
+                    pinState.salt = (long) (Math.random() * Long.MAX_VALUE);
+                }
+                pinState.pinHash = passwordToHash(newPin, pinState.salt);
+                pinState.failedAttempts = 0;
+            }
+            mRestrictionsPinStates.put(userId, pinState);
+            writeUserLocked(mUsers.get(userId));
+        }
+        return true;
+    }
+
+    @Override
+    public int checkRestrictionsChallenge(String pin) {
+        checkManageUsersPermission("Only system can verify the restrictions pin");
+        int userId = UserHandle.getCallingUserId();
+        synchronized (mPackagesLock) {
+            RestrictionsPinState pinState = mRestrictionsPinStates.get(userId);
+            // If there's no pin set, return error code
+            if (pinState == null || pinState.salt == 0 || pinState.pinHash == null) {
+                return UserManager.PIN_VERIFICATION_FAILED_NOT_SET;
+            } else if (pin == null) {
+                // If just checking if user can be prompted, return remaining time
+                int waitTime = getRemainingTimeForPinAttempt(pinState);
+                Slog.d(LOG_TAG, "Remaining waittime peek=" + waitTime);
+                return waitTime;
+            } else {
+                int waitTime = getRemainingTimeForPinAttempt(pinState);
+                Slog.d(LOG_TAG, "Remaining waittime=" + waitTime);
+                if (waitTime > 0) {
+                    return waitTime;
+                }
+                if (passwordToHash(pin, pinState.salt).equals(pinState.pinHash)) {
+                    pinState.failedAttempts = 0;
+                    writeUserLocked(mUsers.get(userId));
+                    return UserManager.PIN_VERIFICATION_SUCCESS;
+                } else {
+                    pinState.failedAttempts++;
+                    pinState.lastAttemptTime = System.currentTimeMillis();
+                    writeUserLocked(mUsers.get(userId));
+                    return waitTime;
+                }
+            }
+        }
+    }
+
+    private int getRemainingTimeForPinAttempt(RestrictionsPinState pinState) {
+        int backoffIndex = Math.min(pinState.failedAttempts / BACKOFF_INC_INTERVAL,
+                BACKOFF_TIMES.length - 1);
+        int backoffTime = (pinState.failedAttempts % BACKOFF_INC_INTERVAL) == 0 ?
+                BACKOFF_TIMES[backoffIndex] : 0;
+        return (int) Math.max(backoffTime + pinState.lastAttemptTime - System.currentTimeMillis(),
+                0);
+    }
+
+    @Override
+    public boolean hasRestrictionsChallenge() {
+        int userId = UserHandle.getCallingUserId();
+        synchronized (mPackagesLock) {
+            return hasRestrictionsPinLocked(userId);
+        }
+    }
+
+    private boolean hasRestrictionsPinLocked(int userId) {
+        RestrictionsPinState pinState = mRestrictionsPinStates.get(userId);
+        if (pinState == null || pinState.salt == 0 || pinState.pinHash == null) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public void removeRestrictions() {
+        checkManageUsersPermission("Only system can remove restrictions");
+        final int userHandle = UserHandle.getCallingUserId();
+        removeRestrictionsForUser(userHandle, true);
+    }
+
+    private void removeRestrictionsForUser(final int userHandle, boolean unblockApps) {
+        synchronized (mPackagesLock) {
+            // Remove all user restrictions
+            setUserRestrictions(new Bundle(), userHandle);
+            // Remove restrictions pin
+            setRestrictionsChallenge(null);
+            // Remove any app restrictions
+            cleanAppRestrictions(userHandle, true);
+        }
+        if (unblockApps) {
+            unblockAllAppsForUser(userHandle);
+        }
+    }
+
+    private void unblockAllAppsForUser(final int userHandle) {
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                List<ApplicationInfo> apps =
+                        mPm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES,
+                                userHandle).getList();
+                final long ident = Binder.clearCallingIdentity();
+                try {
+                    for (ApplicationInfo appInfo : apps) {
+                        if ((appInfo.flags & ApplicationInfo.FLAG_INSTALLED) != 0
+                                && (appInfo.flags & ApplicationInfo.FLAG_BLOCKED) != 0) {
+                            mPm.setApplicationBlockedSettingAsUser(appInfo.packageName, false,
+                                    userHandle);
+                        }
+                    }
+                } finally {
+                    Binder.restoreCallingIdentity(ident);
+                }
+            }
+        });
+    }
+
+    /*
+     * Generate a hash for the given password. To avoid brute force attacks, we use a salted hash.
+     * Not the most secure, but it is at least a second level of protection. First level is that
+     * the file is in a location only readable by the system process.
+     * @param password the password.
+     * @param salt the randomly generated salt
+     * @return the hash of the pattern in a String.
+     */
+    private String passwordToHash(String password, long salt) {
+        if (password == null) {
+            return null;
+        }
+        String algo = null;
+        String hashed = salt + password;
+        try {
+            byte[] saltedPassword = (password + salt).getBytes();
+            byte[] sha1 = MessageDigest.getInstance(algo = "SHA-1").digest(saltedPassword);
+            byte[] md5 = MessageDigest.getInstance(algo = "MD5").digest(saltedPassword);
+            hashed = toHex(sha1) + toHex(md5);
+        } catch (NoSuchAlgorithmException e) {
+            Log.w(LOG_TAG, "Failed to encode string because of missing algorithm: " + algo);
+        }
+        return hashed;
+    }
+
+    private static String toHex(byte[] ary) {
+        final String hex = "0123456789ABCDEF";
+        String ret = "";
+        for (int i = 0; i < ary.length; i++) {
+            ret += hex.charAt((ary[i] >> 4) & 0xf);
+            ret += hex.charAt(ary[i] & 0xf);
+        }
+        return ret;
+    }
+
     private int getUidForPackage(String packageName) {
         long ident = Binder.clearCallingIdentity();
         try {
@@ -1168,7 +1455,7 @@
     }
 
     /**
-     * Make a note of the last started time of a user.
+     * Make a note of the last started time of a user and do some cleanup.
      * @param userId the user that was just foregrounded
      */
     public void userForeground(int userId) {
@@ -1183,6 +1470,12 @@
                 user.lastLoggedInTime = now;
                 writeUserLocked(user);
             }
+            // If this is not a restricted profile and there is no restrictions pin, clean up
+            // all restrictions files that might have been left behind, else clean up just the
+            // ones with uninstalled packages
+            RestrictionsPinState pinState = mRestrictionsPinStates.get(userId);
+            final long salt = pinState == null ? 0 : pinState.salt;
+            cleanAppRestrictions(userId, (!user.isRestricted() && salt == 0));
         }
     }
 
@@ -1249,4 +1542,17 @@
             }
         }
     }
+
+    private PackageMonitor mUserPackageMonitor = new PackageMonitor() {
+        @Override
+        public void onPackageRemoved(String pkg, int uid) {
+            final int userId = this.getChangingUserId();
+            // Package could be disappearing because it is being blocked, so also check if
+            // it has been uninstalled.
+            final boolean uninstalled = isPackageDisappearing(pkg) == PACKAGE_PERMANENT_CHANGE;
+            if (uninstalled && userId >= 0 && !isPackageInstalled(pkg, userId)) {
+                cleanAppRestrictionsForPackage(pkg, userId);
+            }
+        }
+    };
 }
diff --git a/services/java/com/android/server/power/DisplayPowerController.java b/services/java/com/android/server/power/DisplayPowerController.java
index b5010f2..976a328 100644
--- a/services/java/com/android/server/power/DisplayPowerController.java
+++ b/services/java/com/android/server/power/DisplayPowerController.java
@@ -29,7 +29,6 @@
 import android.hardware.SensorEvent;
 import android.hardware.SensorEventListener;
 import android.hardware.SensorManager;
-import android.hardware.SystemSensorManager;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
@@ -119,7 +118,7 @@
 
     // Proximity sensor debounce delay in milliseconds for positive or negative transitions.
     private static final int PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY = 0;
-    private static final int PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY = 500;
+    private static final int PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY = 250;
 
     // Trigger proximity if distance is less than 5 cm.
     private static final float TYPICAL_PROXIMITY_THRESHOLD = 5.0f;
@@ -164,6 +163,10 @@
     // Notifier for sending asynchronous notifications.
     private final Notifier mNotifier;
 
+    // The display suspend blocker.
+    // Held while there are pending state change notifications.
+    private final SuspendBlocker mDisplaySuspendBlocker;
+
     // The display blanker.
     private final DisplayBlanker mDisplayBlanker;
 
@@ -271,7 +274,7 @@
 
     // The raw non-debounced proximity sensor state.
     private int mPendingProximity = PROXIMITY_UNKNOWN;
-    private long mPendingProximityDebounceTime;
+    private long mPendingProximityDebounceTime = -1; // -1 if fully debounced
 
     // True if the screen was turned off because of the proximity sensor.
     // When the screen turns on again, we report user activity to the power manager.
@@ -346,10 +349,11 @@
     public DisplayPowerController(Looper looper, Context context, Notifier notifier,
             LightsService lights, TwilightService twilight, SensorManager sensorManager,
             DisplayManagerService displayManager,
-            DisplayBlanker displayBlanker,
+            SuspendBlocker displaySuspendBlocker, DisplayBlanker displayBlanker,
             Callbacks callbacks, Handler callbackHandler) {
         mHandler = new DisplayControllerHandler(looper);
         mNotifier = notifier;
+        mDisplaySuspendBlocker = displaySuspendBlocker;
         mDisplayBlanker = displayBlanker;
         mCallbacks = callbacks;
         mCallbackHandler = callbackHandler;
@@ -601,7 +605,7 @@
                 if (!mScreenOffBecauseOfProximity
                         && mProximity == PROXIMITY_POSITIVE) {
                     mScreenOffBecauseOfProximity = true;
-                    sendOnProximityPositive();
+                    sendOnProximityPositiveWithWakelock();
                     setScreenOn(false);
                 }
             } else if (mWaitingForNegativeProximity
@@ -616,7 +620,7 @@
             if (mScreenOffBecauseOfProximity
                     && mProximity != PROXIMITY_POSITIVE) {
                 mScreenOffBecauseOfProximity = false;
-                sendOnProximityNegative();
+                sendOnProximityNegativeWithWakelock();
             }
         } else {
             mWaitingForNegativeProximity = false;
@@ -737,7 +741,7 @@
                     }
                 }
             }
-            sendOnStateChanged();
+            sendOnStateChangedWithWakelock();
         }
     }
 
@@ -810,49 +814,67 @@
     private void setProximitySensorEnabled(boolean enable) {
         if (enable) {
             if (!mProximitySensorEnabled) {
+                // Register the listener.
+                // Proximity sensor state already cleared initially.
                 mProximitySensorEnabled = true;
-                mPendingProximity = PROXIMITY_UNKNOWN;
                 mSensorManager.registerListener(mProximitySensorListener, mProximitySensor,
                         SensorManager.SENSOR_DELAY_NORMAL, mHandler);
             }
         } else {
             if (mProximitySensorEnabled) {
+                // Unregister the listener.
+                // Clear the proximity sensor state for next time.
                 mProximitySensorEnabled = false;
                 mProximity = PROXIMITY_UNKNOWN;
+                mPendingProximity = PROXIMITY_UNKNOWN;
                 mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
                 mSensorManager.unregisterListener(mProximitySensorListener);
+                clearPendingProximityDebounceTime(); // release wake lock (must be last)
             }
         }
     }
 
     private void handleProximitySensorEvent(long time, boolean positive) {
-        if (mPendingProximity == PROXIMITY_NEGATIVE && !positive) {
-            return; // no change
-        }
-        if (mPendingProximity == PROXIMITY_POSITIVE && positive) {
-            return; // no change
-        }
+        if (mProximitySensorEnabled) {
+            if (mPendingProximity == PROXIMITY_NEGATIVE && !positive) {
+                return; // no change
+            }
+            if (mPendingProximity == PROXIMITY_POSITIVE && positive) {
+                return; // no change
+            }
 
-        // Only accept a proximity sensor reading if it remains
-        // stable for the entire debounce delay.
-        mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
-        if (positive) {
-            mPendingProximity = PROXIMITY_POSITIVE;
-            mPendingProximityDebounceTime = time + PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY;
-        } else {
-            mPendingProximity = PROXIMITY_NEGATIVE;
-            mPendingProximityDebounceTime = time + PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY;
+            // Only accept a proximity sensor reading if it remains
+            // stable for the entire debounce delay.  We hold a wake lock while
+            // debouncing the sensor.
+            mHandler.removeMessages(MSG_PROXIMITY_SENSOR_DEBOUNCED);
+            if (positive) {
+                mPendingProximity = PROXIMITY_POSITIVE;
+                setPendingProximityDebounceTime(
+                        time + PROXIMITY_SENSOR_POSITIVE_DEBOUNCE_DELAY); // acquire wake lock
+            } else {
+                mPendingProximity = PROXIMITY_NEGATIVE;
+                setPendingProximityDebounceTime(
+                        time + PROXIMITY_SENSOR_NEGATIVE_DEBOUNCE_DELAY); // acquire wake lock
+            }
+
+            // Debounce the new sensor reading.
+            debounceProximitySensor();
         }
-        debounceProximitySensor();
     }
 
     private void debounceProximitySensor() {
-        if (mPendingProximity != PROXIMITY_UNKNOWN) {
+        if (mProximitySensorEnabled
+                && mPendingProximity != PROXIMITY_UNKNOWN
+                && mPendingProximityDebounceTime >= 0) {
             final long now = SystemClock.uptimeMillis();
             if (mPendingProximityDebounceTime <= now) {
+                // Sensor reading accepted.  Apply the change then release the wake lock.
                 mProximity = mPendingProximity;
-                sendUpdatePowerState();
+                updatePowerState();
+                clearPendingProximityDebounceTime(); // release wake lock (must be last)
             } else {
+                // Need to wait a little longer.
+                // Debounce again later.  We continue holding a wake lock while waiting.
                 Message msg = mHandler.obtainMessage(MSG_PROXIMITY_SENSOR_DEBOUNCED);
                 msg.setAsynchronous(true);
                 mHandler.sendMessageAtTime(msg, mPendingProximityDebounceTime);
@@ -860,6 +882,20 @@
         }
     }
 
+    private void clearPendingProximityDebounceTime() {
+        if (mPendingProximityDebounceTime >= 0) {
+            mPendingProximityDebounceTime = -1;
+            mDisplaySuspendBlocker.release(); // release wake lock
+        }
+    }
+
+    private void setPendingProximityDebounceTime(long debounceTime) {
+        if (mPendingProximityDebounceTime < 0) {
+            mDisplaySuspendBlocker.acquire(); // acquire wake lock
+        }
+        mPendingProximityDebounceTime = debounceTime;
+    }
+
     private void setLightSensorEnabled(boolean enable, boolean updateAutoBrightness) {
         if (enable) {
             if (!mLightSensorEnabled) {
@@ -1120,7 +1156,8 @@
         return x + (y - x) * alpha;
     }
 
-    private void sendOnStateChanged() {
+    private void sendOnStateChangedWithWakelock() {
+        mDisplaySuspendBlocker.acquire();
         mCallbackHandler.post(mOnStateChangedRunnable);
     }
 
@@ -1128,10 +1165,12 @@
         @Override
         public void run() {
             mCallbacks.onStateChanged();
+            mDisplaySuspendBlocker.release();
         }
     };
 
-    private void sendOnProximityPositive() {
+    private void sendOnProximityPositiveWithWakelock() {
+        mDisplaySuspendBlocker.acquire();
         mCallbackHandler.post(mOnProximityPositiveRunnable);
     }
 
@@ -1139,10 +1178,12 @@
         @Override
         public void run() {
             mCallbacks.onProximityPositive();
+            mDisplaySuspendBlocker.release();
         }
     };
 
-    private void sendOnProximityNegative() {
+    private void sendOnProximityNegativeWithWakelock() {
+        mDisplaySuspendBlocker.acquire();
         mCallbackHandler.post(mOnProximityNegativeRunnable);
     }
 
@@ -1150,6 +1191,7 @@
         @Override
         public void run() {
             mCallbacks.onProximityNegative();
+            mDisplaySuspendBlocker.release();
         }
     };
 
diff --git a/services/java/com/android/server/power/ElectronBeam.java b/services/java/com/android/server/power/ElectronBeam.java
index 379e704..729bd16 100644
--- a/services/java/com/android/server/power/ElectronBeam.java
+++ b/services/java/com/android/server/power/ElectronBeam.java
@@ -35,6 +35,7 @@
 import android.util.Slog;
 import android.view.Display;
 import android.view.DisplayInfo;
+import android.view.Surface.OutOfResourcesException;
 import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
@@ -94,7 +95,7 @@
     // Texture names.  We only use one texture, which contains the screenshot.
     private final int[] mTexNames = new int[1];
     private boolean mTexNamesGenerated;
-    private float mTexMatrix[] = new float[16];
+    private final float mTexMatrix[] = new float[16];
 
     // Vertex and corresponding texture coordinates.
     // We have 4 2D vertices, so 8 elements.  The vertices form a quad.
@@ -319,10 +320,10 @@
 
     /**
      * Draws a frame where the electron beam has been stretched out into
-     * a thin white horizontal line that fades as it expands outwards.
+     * a thin white horizontal line that fades as it collapses inwards.
      *
-     * @param stretch The stretch factor.  0.0 is no stretch / no fade,
-     * 1.0 is maximum stretch / maximum fade.
+     * @param stretch The stretch factor.  0.0 is maximum stretch / no fade,
+     * 1.0 is collapsed / maximum fade.
      */
     private void drawHStretch(float stretch) {
         // compute interpolation scale factor
@@ -338,7 +339,7 @@
 
             // draw narrow fading white line
             setHStretchQuad(mVertexBuffer, mDisplayWidth, mDisplayHeight, ag);
-            GLES10.glColor4f(1.0f - ag, 1.0f - ag, 1.0f - ag, 1.0f);
+            GLES10.glColor4f(1.0f - ag*0.75f, 1.0f - ag*0.75f, 1.0f - ag*0.75f, 1.0f);
             GLES10.glDrawArrays(GLES10.GL_TRIANGLE_FAN, 0, 4);
 
             // clean up
@@ -355,7 +356,7 @@
     }
 
     private static void setHStretchQuad(FloatBuffer vtx, float dw, float dh, float a) {
-        final float w = dw + (dw * a);
+        final float w = 2 * dw * (1.0f - a);
         final float h = 1.0f;
         final float x = (dw - w) * 0.5f;
         final float y = (dh - h) * 0.5f;
@@ -515,7 +516,7 @@
                     mSurfaceControl = new SurfaceControl(mSurfaceSession,
                             "ElectronBeam", mDisplayWidth, mDisplayHeight,
                             PixelFormat.OPAQUE, flags);
-                } catch (SurfaceControl.OutOfResourcesException ex) {
+                } catch (OutOfResourcesException ex) {
                     Slog.e(TAG, "Unable to create surface.", ex);
                     return false;
                 }
@@ -525,7 +526,7 @@
             mSurfaceControl.setSize(mDisplayWidth, mDisplayHeight);
             mSurface = new Surface();
             mSurface.copyFrom(mSurfaceControl);
-            
+
             mSurfaceLayout = new NaturalSurfaceLayout(mDisplayManager, mSurfaceControl);
             mSurfaceLayout.onDisplayTransaction();
         } finally {
diff --git a/services/java/com/android/server/power/Notifier.java b/services/java/com/android/server/power/Notifier.java
index d99d523..264e2e9 100644
--- a/services/java/com/android/server/power/Notifier.java
+++ b/services/java/com/android/server/power/Notifier.java
@@ -16,6 +16,8 @@
 
 package com.android.server.power;
 
+import android.app.AppOpsManager;
+import com.android.internal.app.IAppOpsService;
 import com.android.internal.app.IBatteryStats;
 import com.android.server.EventLogTags;
 
@@ -75,6 +77,7 @@
 
     private final Context mContext;
     private final IBatteryStats mBatteryStats;
+    private final IAppOpsService mAppOps;
     private final SuspendBlocker mSuspendBlocker;
     private final ScreenOnBlocker mScreenOnBlocker;
     private final WindowManagerPolicy mPolicy;
@@ -104,10 +107,11 @@
     private boolean mScreenOnBlockerAcquired;
 
     public Notifier(Looper looper, Context context, IBatteryStats batteryStats,
-            SuspendBlocker suspendBlocker, ScreenOnBlocker screenOnBlocker,
+            IAppOpsService appOps, SuspendBlocker suspendBlocker, ScreenOnBlocker screenOnBlocker,
             WindowManagerPolicy policy) {
         mContext = context;
         mBatteryStats = batteryStats;
+        mAppOps = appOps;
         mSuspendBlocker = suspendBlocker;
         mScreenOnBlocker = screenOnBlocker;
         mPolicy = policy;
@@ -124,11 +128,12 @@
     /**
      * Called when a wake lock is acquired.
      */
-    public void onWakeLockAcquired(int flags, String tag, int ownerUid, int ownerPid,
-            WorkSource workSource) {
+    public void onWakeLockAcquired(int flags, String tag, String packageName,
+            int ownerUid, int ownerPid, WorkSource workSource) {
         if (DEBUG) {
             Slog.d(TAG, "onWakeLockAcquired: flags=" + flags + ", tag=\"" + tag
-                    + "\", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
+                    + "\", packageName=" + packageName
+                    + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
                     + ", workSource=" + workSource);
         }
 
@@ -138,6 +143,9 @@
                 mBatteryStats.noteStartWakelockFromSource(workSource, ownerPid, tag, monitorType);
             } else {
                 mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, monitorType);
+                // XXX need to deal with disabled operations.
+                mAppOps.startOperation(AppOpsManager.getToken(mAppOps),
+                        AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
             }
         } catch (RemoteException ex) {
             // Ignore
@@ -147,11 +155,12 @@
     /**
      * Called when a wake lock is released.
      */
-    public void onWakeLockReleased(int flags, String tag, int ownerUid, int ownerPid,
-            WorkSource workSource) {
+    public void onWakeLockReleased(int flags, String tag, String packageName,
+            int ownerUid, int ownerPid, WorkSource workSource) {
         if (DEBUG) {
             Slog.d(TAG, "onWakeLockReleased: flags=" + flags + ", tag=\"" + tag
-                    + "\", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
+                    + "\", packageName=" + packageName
+                    + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
                     + ", workSource=" + workSource);
         }
 
@@ -161,6 +170,8 @@
                 mBatteryStats.noteStopWakelockFromSource(workSource, ownerPid, tag, monitorType);
             } else {
                 mBatteryStats.noteStopWakelock(ownerUid, ownerPid, tag, monitorType);
+                mAppOps.finishOperation(AppOpsManager.getToken(mAppOps),
+                        AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
             }
         } catch (RemoteException ex) {
             // Ignore
diff --git a/services/java/com/android/server/power/PowerManagerService.java b/services/java/com/android/server/power/PowerManagerService.java
index 6f70712..fe09a33 100644
--- a/services/java/com/android/server/power/PowerManagerService.java
+++ b/services/java/com/android/server/power/PowerManagerService.java
@@ -16,6 +16,7 @@
 
 package com.android.server.power;
 
+import com.android.internal.app.IAppOpsService;
 import com.android.internal.app.IBatteryStats;
 import com.android.server.BatteryService;
 import com.android.server.EventLogTags;
@@ -50,6 +51,7 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
+import android.os.SystemProperties;
 import android.os.SystemService;
 import android.os.UserHandle;
 import android.os.WorkSource;
@@ -61,7 +63,6 @@
 import android.view.WindowManagerPolicy;
 
 import java.io.FileDescriptor;
-import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 
@@ -171,6 +172,7 @@
     private BatteryService mBatteryService;
     private DisplayManagerService mDisplayManagerService;
     private IBatteryStats mBatteryStats;
+    private IAppOpsService mAppOps;
     private HandlerThread mHandlerThread;
     private PowerManagerHandler mHandler;
     private WindowManagerPolicy mPolicy;
@@ -284,6 +286,9 @@
     // True if the device should wake up when plugged or unplugged.
     private boolean mWakeUpWhenPluggedOrUnpluggedConfig;
 
+    // True if the device should suspend when the screen is off due to proximity.
+    private boolean mSuspendWhenScreenOffDueToProximityConfig;
+
     // True if dreams are supported on this device.
     private boolean mDreamsSupportedConfig;
 
@@ -364,8 +369,6 @@
     private long mLastWarningAboutUserActivityPermission = Long.MIN_VALUE;
 
     private native void nativeInit();
-    private static native void nativeShutdown();
-    private static native void nativeReboot(String reason) throws IOException;
 
     private static native void nativeSetPowerState(boolean screenOn, boolean screenBright);
     private static native void nativeAcquireSuspendBlocker(String name);
@@ -395,17 +398,19 @@
      */
     public void init(Context context, LightsService ls,
             ActivityManagerService am, BatteryService bs, IBatteryStats bss,
-            DisplayManagerService dm) {
+            IAppOpsService appOps, DisplayManagerService dm) {
         mContext = context;
         mLightsService = ls;
         mBatteryService = bs;
         mBatteryStats = bss;
+        mAppOps = appOps;
         mDisplayManagerService = dm;
         mHandlerThread = new HandlerThread(TAG);
         mHandlerThread.start();
         mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
 
         Watchdog.getInstance().addMonitor(this);
+        Watchdog.getInstance().addThread(mHandler, mHandlerThread.getName());
 
         // Forcibly turn the screen on at boot so that it is in a known power state.
         // We do this in init() rather than in the constructor because setting the
@@ -437,14 +442,14 @@
             // The notifier runs on the system server's main looper so as not to interfere
             // with the animations and other critical functions of the power manager.
             mNotifier = new Notifier(Looper.getMainLooper(), mContext, mBatteryStats,
-                    createSuspendBlockerLocked("PowerManagerService.Broadcasts"),
+                    mAppOps, createSuspendBlockerLocked("PowerManagerService.Broadcasts"),
                     mScreenOnBlocker, mPolicy);
 
             // The display power controller runs on the power manager service's
             // own handler thread to ensure timely operation.
             mDisplayPowerController = new DisplayPowerController(mHandler.getLooper(),
                     mContext, mNotifier, mLightsService, twilight, sensorManager,
-                    mDisplayManagerService, mDisplayBlanker,
+                    mDisplayManagerService, mDisplaySuspendBlocker, mDisplayBlanker,
                     mDisplayPowerControllerCallbacks, mHandler);
 
             mWirelessChargerDetector = new WirelessChargerDetector(sensorManager,
@@ -511,6 +516,8 @@
 
         mWakeUpWhenPluggedOrUnpluggedConfig = resources.getBoolean(
                 com.android.internal.R.bool.config_unplugTurnsOnScreen);
+        mSuspendWhenScreenOffDueToProximityConfig = resources.getBoolean(
+                com.android.internal.R.bool.config_suspendWhenScreenOffDueToProximity);
         mDreamsSupportedConfig = resources.getBoolean(
                 com.android.internal.R.bool.config_dreamsSupported);
         mDreamsEnabledByDefaultConfig = resources.getBoolean(
@@ -572,10 +579,14 @@
     }
 
     @Override // Binder call
-    public void acquireWakeLock(IBinder lock, int flags, String tag, WorkSource ws) {
+    public void acquireWakeLock(IBinder lock, int flags, String tag, String packageName,
+            WorkSource ws) {
         if (lock == null) {
             throw new IllegalArgumentException("lock must not be null");
         }
+        if (packageName == null) {
+            throw new IllegalArgumentException("packageName must not be null");
+        }
         PowerManager.validateWakeLockParameters(flags, tag);
 
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
@@ -590,14 +601,14 @@
         final int pid = Binder.getCallingPid();
         final long ident = Binder.clearCallingIdentity();
         try {
-            acquireWakeLockInternal(lock, flags, tag, ws, uid, pid);
+            acquireWakeLockInternal(lock, flags, tag, packageName, ws, uid, pid);
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
     }
 
-    private void acquireWakeLockInternal(IBinder lock, int flags, String tag, WorkSource ws,
-            int uid, int pid) {
+    private void acquireWakeLockInternal(IBinder lock, int flags, String tag, String packageName,
+            WorkSource ws, int uid, int pid) {
         synchronized (mLock) {
             if (DEBUG_SPEW) {
                 Slog.d(TAG, "acquireWakeLockInternal: lock=" + Objects.hashCode(lock)
@@ -612,11 +623,11 @@
                 if (!wakeLock.hasSameProperties(flags, tag, ws, uid, pid)) {
                     // Update existing wake lock.  This shouldn't happen but is harmless.
                     notifyWakeLockReleasedLocked(wakeLock);
-                    wakeLock.updateProperties(flags, tag, ws, uid, pid);
+                    wakeLock.updateProperties(flags, tag, packageName, ws, uid, pid);
                     notifyWakeLockAcquiredLocked(wakeLock);
                 }
             } else {
-                wakeLock = new WakeLock(lock, flags, tag, ws, uid, pid);
+                wakeLock = new WakeLock(lock, flags, tag, packageName, ws, uid, pid);
                 try {
                     lock.linkToDeath(wakeLock, 0);
                 } catch (RemoteException ex) {
@@ -632,6 +643,7 @@
         }
     }
 
+    @SuppressWarnings("deprecation")
     private static boolean isScreenLock(final WakeLock wakeLock) {
         switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
             case PowerManager.FULL_WAKE_LOCK:
@@ -643,8 +655,8 @@
     }
 
     private void applyWakeLockFlagsOnAcquireLocked(WakeLock wakeLock) {
-        if ((wakeLock.mFlags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0 &&
-                isScreenLock(wakeLock)) {
+        if ((wakeLock.mFlags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0
+                && isScreenLock(wakeLock)) {
             wakeUpNoUpdateLocked(SystemClock.uptimeMillis());
         }
     }
@@ -718,7 +730,8 @@
     }
 
     private void applyWakeLockFlagsOnReleaseLocked(WakeLock wakeLock) {
-        if ((wakeLock.mFlags & PowerManager.ON_AFTER_RELEASE) != 0) {
+        if ((wakeLock.mFlags & PowerManager.ON_AFTER_RELEASE) != 0
+                && isScreenLock(wakeLock)) {
             userActivityNoUpdateLocked(SystemClock.uptimeMillis(),
                     PowerManager.USER_ACTIVITY_EVENT_OTHER,
                     PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS,
@@ -785,14 +798,16 @@
 
     private void notifyWakeLockAcquiredLocked(WakeLock wakeLock) {
         if (mSystemReady) {
-            mNotifier.onWakeLockAcquired(wakeLock.mFlags, wakeLock.mTag,
+            wakeLock.mNotifiedAcquired = true;
+            mNotifier.onWakeLockAcquired(wakeLock.mFlags, wakeLock.mTag, wakeLock.mPackageName,
                     wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource);
         }
     }
 
     private void notifyWakeLockReleasedLocked(WakeLock wakeLock) {
-        if (mSystemReady) {
-            mNotifier.onWakeLockReleased(wakeLock.mFlags, wakeLock.mTag,
+        if (mSystemReady && wakeLock.mNotifiedAcquired) {
+            wakeLock.mNotifiedAcquired = false;
+            mNotifier.onWakeLockReleased(wakeLock.mFlags, wakeLock.mTag, wakeLock.mPackageName,
                     wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource);
         }
     }
@@ -807,6 +822,7 @@
         }
     }
 
+    @SuppressWarnings("deprecation")
     private boolean isWakeLockLevelSupportedInternal(int level) {
         synchronized (mLock) {
             switch (level) {
@@ -995,6 +1011,7 @@
         }
     }
 
+    @SuppressWarnings("deprecation")
     private boolean goToSleepNoUpdateLocked(long eventTime, int reason) {
         if (DEBUG_SPEW) {
             Slog.d(TAG, "goToSleepNoUpdateLocked: eventTime=" + eventTime + ", reason=" + reason);
@@ -1251,6 +1268,7 @@
      *
      * This function must have no other side-effects.
      */
+    @SuppressWarnings("deprecation")
     private void updateWakeLockSummaryLocked(int dirty) {
         if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_WAKEFULNESS)) != 0) {
             mWakeLockSummary = 0;
@@ -1289,7 +1307,7 @@
                         break;
                     case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
                         if (mWakefulness != WAKEFULNESS_ASLEEP) {
-                            mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_PROXIMITY_SCREEN_OFF;
+                            mWakeLockSummary |= WAKE_LOCK_PROXIMITY_SCREEN_OFF;
                         }
                         break;
                 }
@@ -1448,7 +1466,11 @@
 
     /**
      * Returns true if the device is being kept awake by a wake lock, user activity
-     * or the stay on while powered setting.
+     * or the stay on while powered setting.  We also keep the phone awake when
+     * the proximity sensor returns a positive result so that the device does not
+     * lock while in a phone call.  This function only controls whether the device
+     * will go to sleep or dream which is independent of whether it will be allowed
+     * to suspend.
      */
     private boolean isBeingKeptAwakeLocked() {
         return mStayOn
@@ -1739,10 +1761,8 @@
      * This function must have no other side-effects.
      */
     private void updateSuspendBlockerLocked() {
-        final boolean needWakeLockSuspendBlocker = (mWakeLockSummary != 0);
-        final boolean needDisplaySuspendBlocker = (mUserActivitySummary != 0
-                || mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF
-                || !mDisplayReady || !mBootCompleted);
+        final boolean needWakeLockSuspendBlocker = ((mWakeLockSummary & WAKE_LOCK_CPU) != 0);
+        final boolean needDisplaySuspendBlocker = needDisplaySuspendBlocker();
 
         // First acquire suspend blockers if needed.
         if (needWakeLockSuspendBlocker && !mHoldingWakeLockSuspendBlocker) {
@@ -1765,6 +1785,27 @@
         }
     }
 
+    /**
+     * Return true if we must keep a suspend blocker active on behalf of the display.
+     * We do so if the screen is on or is in transition between states.
+     */
+    private boolean needDisplaySuspendBlocker() {
+        if (!mDisplayReady) {
+            return true;
+        }
+        if (mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF) {
+            // If we asked for the screen to be on but it is off due to the proximity
+            // sensor then we may suspend but only if the configuration allows it.
+            // On some hardware it may not be safe to suspend because the proximity
+            // sensor may not be correctly configured as a wake-up source.
+            if (!mDisplayPowerRequest.useProximitySensor || !mProximityPositive
+                    || !mSuspendWhenScreenOffDueToProximityConfig) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     @Override // Binder call
     public boolean isScreenOn() {
         final long ident = Binder.clearCallingIdentity();
@@ -2105,7 +2146,7 @@
      *
      * @param brightness The overridden brightness.
      *
-     * @see Settings.System#SCREEN_BRIGHTNESS
+     * @see android.provider.Settings.System#SCREEN_BRIGHTNESS
      */
     @Override // Binder call
     public void setTemporaryScreenBrightnessSettingOverride(int brightness) {
@@ -2170,18 +2211,26 @@
      * to be clean.  Most people should use {@link ShutdownThread} for a clean shutdown.
      */
     public static void lowLevelShutdown() {
-        nativeShutdown();
+        SystemProperties.set("sys.powerctl", "shutdown");
     }
 
     /**
-     * Low-level function to reboot the device.
+     * Low-level function to reboot the device. On success, this function
+     * doesn't return. If more than 5 seconds passes from the time,
+     * a reboot is requested, this method returns.
      *
      * @param reason code to pass to the kernel (e.g. "recovery"), or null.
-     * @throws IOException if reboot fails for some reason (eg, lack of
-     *         permission)
      */
-    public static void lowLevelReboot(String reason) throws IOException {
-        nativeReboot(reason);
+    public static void lowLevelReboot(String reason) {
+        if (reason == null) {
+            reason = "";
+        }
+        SystemProperties.set("sys.powerctl", "reboot," + reason);
+        try {
+            Thread.sleep(20000);
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+        }
     }
 
     @Override // Watchdog.Monitor implementation
@@ -2237,7 +2286,16 @@
 
             pw.println();
             pw.println("Settings and Configuration:");
+            pw.println("  mWakeUpWhenPluggedOrUnpluggedConfig="
+                    + mWakeUpWhenPluggedOrUnpluggedConfig);
+            pw.println("  mSuspendWhenScreenOffDueToProximityConfig="
+                    + mSuspendWhenScreenOffDueToProximityConfig);
             pw.println("  mDreamsSupportedConfig=" + mDreamsSupportedConfig);
+            pw.println("  mDreamsEnabledByDefaultConfig=" + mDreamsEnabledByDefaultConfig);
+            pw.println("  mDreamsActivatedOnSleepByDefaultConfig="
+                    + mDreamsActivatedOnSleepByDefaultConfig);
+            pw.println("  mDreamsActivatedOnDockByDefaultConfig="
+                    + mDreamsActivatedOnDockByDefaultConfig);
             pw.println("  mDreamsEnabledSetting=" + mDreamsEnabledSetting);
             pw.println("  mDreamsActivateOnSleepSetting=" + mDreamsActivateOnSleepSetting);
             pw.println("  mDreamsActivateOnDockSetting=" + mDreamsActivateOnDockSetting);
@@ -2426,15 +2484,18 @@
         public final IBinder mLock;
         public int mFlags;
         public String mTag;
+        public final String mPackageName;
         public WorkSource mWorkSource;
-        public int mOwnerUid;
-        public int mOwnerPid;
+        public final int mOwnerUid;
+        public final int mOwnerPid;
+        public boolean mNotifiedAcquired;
 
-        public WakeLock(IBinder lock, int flags, String tag, WorkSource workSource,
-                int ownerUid, int ownerPid) {
+        public WakeLock(IBinder lock, int flags, String tag, String packageName,
+                WorkSource workSource, int ownerUid, int ownerPid) {
             mLock = lock;
             mFlags = flags;
             mTag = tag;
+            mPackageName = packageName;
             mWorkSource = copyWorkSource(workSource);
             mOwnerUid = ownerUid;
             mOwnerPid = ownerPid;
@@ -2454,13 +2515,23 @@
                     && mOwnerPid == ownerPid;
         }
 
-        public void updateProperties(int flags, String tag, WorkSource workSource,
-                int ownerUid, int ownerPid) {
+        public void updateProperties(int flags, String tag, String packageName,
+                WorkSource workSource, int ownerUid, int ownerPid) {
+            if (!mPackageName.equals(packageName)) {
+                throw new IllegalStateException("Existing wake lock package name changed: "
+                        + mPackageName + " to " + packageName);
+            }
+            if (mOwnerUid != ownerUid) {
+                throw new IllegalStateException("Existing wake lock uid changed: "
+                        + mOwnerUid + " to " + ownerUid);
+            }
+            if (mOwnerPid != ownerPid) {
+                throw new IllegalStateException("Existing wake lock pid changed: "
+                        + mOwnerPid + " to " + ownerPid);
+            }
             mFlags = flags;
             mTag = tag;
             updateWorkSource(workSource);
-            mOwnerUid = ownerUid;
-            mOwnerPid = ownerPid;
         }
 
         public boolean hasSameWorkSource(WorkSource workSource) {
diff --git a/services/java/com/android/server/power/ShutdownThread.java b/services/java/com/android/server/power/ShutdownThread.java
index c084666..88a27f5 100644
--- a/services/java/com/android/server/power/ShutdownThread.java
+++ b/services/java/com/android/server/power/ShutdownThread.java
@@ -492,11 +492,8 @@
     public static void rebootOrShutdown(boolean reboot, String reason) {
         if (reboot) {
             Log.i(TAG, "Rebooting, reason: " + reason);
-            try {
-                PowerManagerService.lowLevelReboot(reason);
-            } catch (Exception e) {
-                Log.e(TAG, "Reboot failed, will attempt shutdown instead", e);
-            }
+            PowerManagerService.lowLevelReboot(reason);
+            Log.e(TAG, "Reboot failed, will attempt shutdown instead");
         } else if (SHUTDOWN_VIBRATE_MS > 0) {
             // vibrate before shutting down
             Vibrator vibrator = new SystemVibrator();
diff --git a/services/java/com/android/server/power/WirelessChargerDetector.java b/services/java/com/android/server/power/WirelessChargerDetector.java
index ac6dc3e..35920f7 100644
--- a/services/java/com/android/server/power/WirelessChargerDetector.java
+++ b/services/java/com/android/server/power/WirelessChargerDetector.java
@@ -21,6 +21,7 @@
 import android.hardware.SensorEventListener;
 import android.hardware.SensorManager;
 import android.os.BatteryManager;
+import android.os.SystemClock;
 import android.util.Slog;
 
 import java.io.PrintWriter;
@@ -130,6 +131,10 @@
     private long mFirstSampleTime;
     private float mFirstSampleX, mFirstSampleY, mFirstSampleZ;
 
+    // The time and value of the last sample that was collected (for debugging only).
+    private long mLastSampleTime;
+    private float mLastSampleX, mLastSampleY, mLastSampleZ;
+
     public WirelessChargerDetector(SensorManager sensorManager,
             SuspendBlocker suspendBlocker) {
         mSensorManager = sensorManager;
@@ -153,6 +158,9 @@
             pw.println("  mFirstSampleTime=" + mFirstSampleTime);
             pw.println("  mFirstSampleX=" + mFirstSampleX
                     + ", mFirstSampleY=" + mFirstSampleY + ", mFirstSampleZ=" + mFirstSampleZ);
+            pw.println("  mLastSampleTime=" + mLastSampleTime);
+            pw.println("  mLastSampleX=" + mLastSampleX
+                    + ", mLastSampleY=" + mLastSampleY + ", mLastSampleZ=" + mLastSampleZ);
         }
     }
 
@@ -224,6 +232,11 @@
                 return;
             }
 
+            mLastSampleTime = timeNanos;
+            mLastSampleX = x;
+            mLastSampleY = y;
+            mLastSampleZ = z;
+
             mTotalSamples += 1;
             if (mTotalSamples == 1) {
                 // Save information about the first sample collected.
@@ -310,7 +323,10 @@
     private final SensorEventListener mListener = new SensorEventListener() {
         @Override
         public void onSensorChanged(SensorEvent event) {
-            processSample(event.timestamp, event.values[0], event.values[1], event.values[2]);
+            // We use SystemClock.elapsedRealtimeNanos() instead of event.timestamp because
+            // on some devices the sensor HAL may produce timestamps that are not monotonic.
+            processSample(SystemClock.elapsedRealtimeNanos(),
+                    event.values[0], event.values[1], event.values[2]);
         }
 
         @Override
diff --git a/services/java/com/android/server/print/PrintManagerService.java b/services/java/com/android/server/print/PrintManagerService.java
new file mode 100644
index 0000000..c33bfb7
--- /dev/null
+++ b/services/java/com/android/server/print/PrintManagerService.java
@@ -0,0 +1,542 @@
+/*
+ * 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.server.print;
+
+import android.Manifest;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Process;
+import android.os.UserHandle;
+import android.print.IPrintClient;
+import android.print.IPrintDocumentAdapter;
+import android.print.IPrintManager;
+import android.print.IPrinterDiscoveryObserver;
+import android.print.PrintAttributes;
+import android.print.PrintJobInfo;
+import android.print.PrinterId;
+import android.printservice.PrintServiceInfo;
+import android.provider.Settings;
+import android.util.SparseArray;
+
+import com.android.internal.content.PackageMonitor;
+import com.android.internal.os.BackgroundThread;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+public final class PrintManagerService extends IPrintManager.Stub {
+
+    private static final char COMPONENT_NAME_SEPARATOR = ':';
+
+    private final Object mLock = new Object();
+
+    private final Context mContext;
+
+    private final SparseArray<UserState> mUserStates = new SparseArray<UserState>();
+
+    private int mCurrentUserId = UserHandle.USER_OWNER;
+
+    public PrintManagerService(Context context) {
+        mContext = context;
+        registerContentObservers();
+        registerBoradcastReceivers();
+    }
+
+    public void systemRuning() {
+        BackgroundThread.getHandler().post(new Runnable() {
+            @Override
+            public void run() {
+                synchronized (mLock) {
+                    UserState userState = getCurrentUserStateLocked();
+                    userState.updateIfNeededLocked();
+                    userState.getSpoolerLocked().start();
+                }
+            }
+        });
+    }
+
+    @Override
+    public PrintJobInfo print(String printJobName, IPrintClient client,
+            IPrintDocumentAdapter documentAdapter, PrintAttributes attributes, int appId,
+            int userId) {
+        final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
+        final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+        final UserState userState;
+        final RemotePrintSpooler spooler;
+        synchronized (mLock) {
+            userState = getOrCreateUserStateLocked(resolvedUserId);
+            spooler = userState.getSpoolerLocked();
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            return spooler.createPrintJob(printJobName, client, documentAdapter,
+                    attributes, resolvedAppId);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
+    public List<PrintJobInfo> getPrintJobInfos(int appId, int userId) {
+        final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
+        final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+        final UserState userState;
+        final RemotePrintSpooler spooler;
+        synchronized (mLock) {
+            userState = getOrCreateUserStateLocked(resolvedUserId);
+            spooler = userState.getSpoolerLocked();
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            return spooler.getPrintJobInfos(null, PrintJobInfo.STATE_ANY,
+                    resolvedAppId);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
+    public PrintJobInfo getPrintJobInfo(int printJobId, int appId, int userId) {
+        final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
+        final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+        final UserState userState;
+        final RemotePrintSpooler spooler;
+        synchronized (mLock) {
+            userState = getOrCreateUserStateLocked(resolvedUserId);
+            spooler = userState.getSpoolerLocked();
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            return spooler.getPrintJobInfo(printJobId, resolvedAppId);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
+    public void cancelPrintJob(int printJobId, int appId, int userId) {
+        final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
+        final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+        final UserState userState;
+        final RemotePrintSpooler spooler;
+        synchronized (mLock) {
+            userState = getOrCreateUserStateLocked(resolvedUserId);
+            spooler = userState.getSpoolerLocked();
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            PrintJobInfo printJobInfo = spooler.getPrintJobInfo(printJobId, resolvedAppId);
+            if (printJobInfo == null) {
+                return;
+            }
+            if (printJobInfo.getState() != PrintJobInfo.STATE_FAILED) {
+                ComponentName printServiceName = printJobInfo.getPrinterId().getServiceName();
+                RemotePrintService printService = null;
+                synchronized (mLock) {
+                    printService = userState.getActiveServicesLocked().get(printServiceName);
+                }
+                if (printService == null) {
+                    return;
+                }
+                printService.onRequestCancelPrintJob(printJobInfo);
+            } else {
+                // If the print job is failed we do not need cooperation
+                // from the print service.
+                spooler.setPrintJobState(printJobId, PrintJobInfo.STATE_CANCELED, null);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
+    public void restartPrintJob(int printJobId, int appId, int userId) {
+        final int resolvedAppId = resolveCallingAppEnforcingPermissions(appId);
+        final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+        final RemotePrintSpooler spooler;
+        synchronized (mLock) {
+            spooler = getOrCreateUserStateLocked(resolvedUserId).getSpoolerLocked();
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            PrintJobInfo printJobInfo = getPrintJobInfo(printJobId, resolvedAppId, resolvedUserId);
+            if (printJobInfo == null || printJobInfo.getState() != PrintJobInfo.STATE_FAILED) {
+                return;
+            }
+            spooler.setPrintJobState(printJobId, PrintJobInfo.STATE_QUEUED, null);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+
+    @Override
+    public List<PrintServiceInfo> getEnabledPrintServices(int userId) {
+        final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+        final UserState userState;
+        synchronized (mLock) {
+            userState = getOrCreateUserStateLocked(resolvedUserId);
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            return userState.getEnabledPrintServices();
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
+    public void createPrinterDiscoverySession(IPrinterDiscoveryObserver observer,
+            int userId) {
+        final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+        final UserState userState;
+        synchronized (mLock) {
+            userState = getOrCreateUserStateLocked(resolvedUserId);
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            userState.createPrinterDiscoverySession(observer);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
+    public void destroyPrinterDiscoverySession(IPrinterDiscoveryObserver observer,
+            int userId) {
+        final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+        final UserState userState;
+        synchronized (mLock) {
+            userState = getOrCreateUserStateLocked(resolvedUserId);
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            userState.destroyPrinterDiscoverySession(observer);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
+    public void startPrinterDiscovery(IPrinterDiscoveryObserver observer,
+            List<PrinterId> priorityList, int userId) {
+        final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+        final UserState userState;
+        synchronized (mLock) {
+            userState = getOrCreateUserStateLocked(resolvedUserId);
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            userState.startPrinterDiscovery(observer, priorityList);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
+    public void stopPrinterDiscovery(IPrinterDiscoveryObserver observer, int userId) {
+        final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+        final UserState userState;
+        synchronized (mLock) {
+            userState = getOrCreateUserStateLocked(resolvedUserId);
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            userState.stopPrinterDiscovery(observer);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
+    public void validatePrinters(List<PrinterId> printerIds, int userId) {
+        final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+        final UserState userState;
+        synchronized (mLock) {
+            userState = getOrCreateUserStateLocked(resolvedUserId);
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            userState.validatePrinters(printerIds);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
+    public void startPrinterStateTracking(PrinterId printerId, int userId) {
+        final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+        final UserState userState;
+        synchronized (mLock) {
+            userState = getOrCreateUserStateLocked(resolvedUserId);
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            userState.startPrinterStateTracking(printerId);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
+    public void stopPrinterStateTracking(PrinterId printerId, int userId) {
+        final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+        final UserState userState;
+        synchronized (mLock) {
+            userState = getOrCreateUserStateLocked(resolvedUserId);
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            userState.stopPrinterStateTracking(printerId);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
+                != PackageManager.PERMISSION_GRANTED) {
+            pw.println("Permission Denial: can't dump PrintManager from from pid="
+                    + Binder.getCallingPid()
+                    + ", uid=" + Binder.getCallingUid());
+            return;
+        }
+
+        synchronized (mLock) {
+            pw.println("PRINT MANAGER STATE (dumpsys print)");
+            final int userStateCount = mUserStates.size();
+            for (int i = 0; i < userStateCount; i++) {
+                UserState userState = mUserStates.get(i);
+                userState.dump(fd, pw, "");
+                pw.println();
+            }
+        }
+    }
+
+    private void registerContentObservers() {
+        final Uri enabledPrintServicesUri = Settings.Secure.getUriFor(
+                Settings.Secure.ENABLED_PRINT_SERVICES);
+
+        ContentObserver observer = new ContentObserver(BackgroundThread.getHandler()) {
+            @Override
+            public void onChange(boolean selfChange, Uri uri) {
+                if (enabledPrintServicesUri.equals(uri)) {
+                    synchronized (mLock) {
+                        UserState userState = getCurrentUserStateLocked();
+                        userState.updateIfNeededLocked();
+                    }
+                }
+            }
+        };
+
+        mContext.getContentResolver().registerContentObserver(enabledPrintServicesUri,
+                false, observer, UserHandle.USER_ALL);
+    }
+
+    private void registerBoradcastReceivers() {
+        PackageMonitor monitor = new PackageMonitor() {
+            @Override
+            public boolean onPackageChanged(String packageName, int uid, String[] components) {
+                synchronized (mLock) {
+                    UserState userState = getOrCreateUserStateLocked(getChangingUserId());
+                    Iterator<ComponentName> iterator = userState.getEnabledServices().iterator();
+                    while (iterator.hasNext()) {
+                        ComponentName componentName = iterator.next();
+                        if (packageName.equals(componentName.getPackageName())) {
+                            userState.updateIfNeededLocked();
+                            return true;
+                        }
+                    }
+                }
+                return false;
+            }
+
+            @Override
+            public void onPackageRemoved(String packageName, int uid) {
+                synchronized (mLock) {
+                    UserState userState = getOrCreateUserStateLocked(getChangingUserId());
+                    Iterator<ComponentName> iterator = userState.getEnabledServices().iterator();
+                    while (iterator.hasNext()) {
+                        ComponentName componentName = iterator.next();
+                        if (packageName.equals(componentName.getPackageName())) {
+                            iterator.remove();
+                            persistComponentNamesToSettingLocked(
+                                    Settings.Secure.ENABLED_PRINT_SERVICES,
+                                    userState.getEnabledServices(), getChangingUserId());
+                            userState.updateIfNeededLocked();
+                            return;
+                        }
+                    }
+                }
+            }
+
+            @Override
+            public boolean onHandleForceStop(Intent intent, String[] stoppedPackages,
+                    int uid, boolean doit) {
+                synchronized (mLock) {
+                    UserState userState = getOrCreateUserStateLocked(getChangingUserId());
+                    boolean stoppedSomePackages = false;
+                    Iterator<ComponentName> iterator = userState.getEnabledServices().iterator();
+                    while (iterator.hasNext()) {
+                        ComponentName componentName = iterator.next();
+                        String componentPackage = componentName.getPackageName();
+                        for (String stoppedPackage : stoppedPackages) {
+                            if (componentPackage.equals(stoppedPackage)) {
+                                if (!doit) {
+                                    return true;
+                                }
+                                stoppedSomePackages = true;
+                                break;
+                            }
+                        }
+                    }
+                    if (stoppedSomePackages) {
+                        userState.updateIfNeededLocked();
+                    }
+                    return false;
+                }
+            }
+
+            private void persistComponentNamesToSettingLocked(String settingName,
+                    Set<ComponentName> componentNames, int userId) {
+                StringBuilder builder = new StringBuilder();
+                for (ComponentName componentName : componentNames) {
+                    if (builder.length() > 0) {
+                        builder.append(COMPONENT_NAME_SEPARATOR);
+                    }
+                    builder.append(componentName.flattenToShortString());
+                }
+                Settings.Secure.putStringForUser(mContext.getContentResolver(),
+                        settingName, builder.toString(), userId);
+            }
+        };
+
+        // package changes
+        monitor.register(mContext, BackgroundThread.getHandler().getLooper(),
+                UserHandle.ALL, true);
+
+        // user changes
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
+
+        mContext.registerReceiverAsUser(new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                String action = intent.getAction();
+                if (Intent.ACTION_USER_SWITCHED.equals(action)) {
+                    switchUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
+                } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
+                    removeUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
+                }
+            }
+        }, UserHandle.ALL, intentFilter, null, BackgroundThread.getHandler());
+    }
+
+    private UserState getCurrentUserStateLocked() {
+        return getOrCreateUserStateLocked(mCurrentUserId);
+    }
+
+    private UserState getOrCreateUserStateLocked(int userId) {
+        UserState userState = mUserStates.get(userId);
+        if (userState == null) {
+            userState = new UserState(mContext, userId, mLock);
+            mUserStates.put(userId, userState);
+        }
+        return userState;
+    }
+
+    private void switchUser(int newUserId) {
+        synchronized (mLock) {
+            if (newUserId == mCurrentUserId) {
+                return;
+            }
+            mCurrentUserId = newUserId;
+            UserState userState = getCurrentUserStateLocked();
+            userState.updateIfNeededLocked();
+            userState.getSpoolerLocked().start();
+        }
+    }
+
+    private void removeUser(int removedUserId) {
+        synchronized (mLock) {
+            UserState userState = mUserStates.get(removedUserId);
+            if (userState != null) {
+                userState.destroyLocked();
+                mUserStates.remove(removedUserId);
+            }
+        }
+    }
+
+    private int resolveCallingAppEnforcingPermissions(int appId) {
+        final int callingUid = Binder.getCallingUid();
+        if (callingUid == 0 || callingUid == Process.SYSTEM_UID
+                || callingUid == Process.SHELL_UID) {
+            return appId;
+        }
+        final int callingAppId = UserHandle.getAppId(callingUid);
+        if (appId == callingAppId) {
+            return appId;
+        }
+        if (mContext.checkCallingPermission(
+                "com.android.printspooler.permission.ACCESS_ALL_PRINT_JOBS")
+                != PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException("Call from app " + callingAppId + " as app "
+                    + appId + " without com.android.printspooler.permission"
+                    + ".ACCESS_ALL_PRINT_JOBS");
+        }
+        return appId;
+    }
+
+    private int resolveCallingUserEnforcingPermissions(int userId) {
+        final int callingUid = Binder.getCallingUid();
+        if (callingUid == 0 || callingUid == Process.SYSTEM_UID
+                || callingUid == Process.SHELL_UID) {
+            return userId;
+        }
+        final int callingUserId = UserHandle.getUserId(callingUid);
+        if (callingUserId == userId) {
+            return userId;
+        }
+        if (mContext.checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL)
+                != PackageManager.PERMISSION_GRANTED
+            ||  mContext.checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS)
+                != PackageManager.PERMISSION_GRANTED) {
+            if (userId == UserHandle.USER_CURRENT_OR_SELF) {
+                return callingUserId;
+            }
+            throw new SecurityException("Call from user " + callingUserId + " as user "
+                + userId + " without permission INTERACT_ACROSS_USERS or "
+                + "INTERACT_ACROSS_USERS_FULL not allowed.");
+        }
+        if (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) {
+            return mCurrentUserId;
+        }
+        throw new IllegalArgumentException("Calling user can be changed to only "
+                + "UserHandle.USER_CURRENT or UserHandle.USER_CURRENT_OR_SELF.");
+    }
+}
diff --git a/services/java/com/android/server/print/RemotePrintService.java b/services/java/com/android/server/print/RemotePrintService.java
new file mode 100644
index 0000000..8869cbe
--- /dev/null
+++ b/services/java/com/android/server/print/RemotePrintService.java
@@ -0,0 +1,801 @@
+/*
+ * 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.server.print;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.IBinder.DeathRecipient;
+import android.os.Looper;
+import android.os.Message;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.print.PrintJobInfo;
+import android.print.PrintManager;
+import android.print.PrinterId;
+import android.print.PrinterInfo;
+import android.printservice.IPrintService;
+import android.printservice.IPrintServiceClient;
+import android.util.Slog;
+
+import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class represents a remote print service. It abstracts away the binding
+ * and unbinding from the remote implementation. Clients can call methods of
+ * this class without worrying about when and how to bind/unbind.
+ */
+final class RemotePrintService implements DeathRecipient {
+
+    private static final String LOG_TAG = "RemotePrintService";
+
+    private static final boolean DEBUG = false;
+
+    private final Context mContext;
+
+    private final ComponentName mComponentName;
+
+    private final Intent mIntent;
+
+    private final RemotePrintSpooler mSpooler;
+
+    private final PrintServiceCallbacks mCallbacks;
+
+    private final int mUserId;
+
+    private final List<Runnable> mPendingCommands = new ArrayList<Runnable>();
+
+    private final ServiceConnection mServiceConnection = new RemoteServiceConneciton();
+
+    private final RemotePrintServiceClient mPrintServiceClient;
+
+    private final Handler mHandler;
+
+    private IPrintService mPrintService;
+
+    private boolean mBinding;
+
+    private boolean mDestroyed;
+
+    private boolean mHasActivePrintJobs;
+
+    private boolean mHasPrinterDiscoverySession;
+
+    private boolean mServiceDead;
+
+    private List<PrinterId> mDiscoveryPriorityList;
+
+    private List<PrinterId> mTrackedPrinterList;
+
+    public static interface PrintServiceCallbacks {
+        public void onPrintersAdded(List<PrinterInfo> printers);
+        public void onPrintersRemoved(List<PrinterId> printerIds);
+        public void onServiceDied(RemotePrintService service);
+    }
+
+    public RemotePrintService(Context context, ComponentName componentName, int userId,
+            RemotePrintSpooler spooler, PrintServiceCallbacks callbacks) {
+        mContext = context;
+        mCallbacks = callbacks;
+        mComponentName = componentName;
+        mIntent = new Intent().setComponent(mComponentName);
+        mUserId = userId;
+        mSpooler = spooler;
+        mHandler = new MyHandler(context.getMainLooper());
+        mPrintServiceClient = new RemotePrintServiceClient(this);
+        mServiceDead = true;
+    }
+
+    public ComponentName getComponentName() {
+        return mComponentName;
+    }
+
+    public void destroy() {
+        mHandler.sendEmptyMessage(MyHandler.MSG_DESTROY);
+    }
+
+    private void handleDestroy() {
+        throwIfDestroyed();
+
+        // Stop tracking printers.
+        if (mTrackedPrinterList != null) {
+            final int trackedPrinterCount = mTrackedPrinterList.size();
+            for (int i = 0; i < trackedPrinterCount; i++) {
+                PrinterId printerId = mTrackedPrinterList.get(i);
+                if (printerId.getServiceName().equals(mComponentName)) {
+                    handleStopPrinterStateTracking(printerId);
+                }
+            }
+        }
+
+        // Stop printer discovery.
+        if (mDiscoveryPriorityList != null) {
+            handleStopPrinterDiscovery();
+        }
+
+        // Destroy the discovery session.
+        if (mHasPrinterDiscoverySession) {
+            handleDestroyPrinterDiscoverySession();
+        }
+
+        // Unbind.
+        ensureUnbound();
+
+        // Done
+        mDestroyed = true;
+    }
+
+    @Override
+    public void binderDied() {
+        mHandler.sendEmptyMessage(MyHandler.MSG_BINDER_DIED);
+    }
+
+    private void handleBinderDied() {
+        mPrintService.asBinder().unlinkToDeath(this, 0);
+        mPrintService = null;
+        mServiceDead = true;
+        mCallbacks.onServiceDied(this);
+    }
+
+    public void onAllPrintJobsHandled() {
+        mHandler.sendEmptyMessage(MyHandler.MSG_ON_ALL_PRINT_JOBS_HANDLED);
+    }
+
+    private void handleOnAllPrintJobsHandled() {
+        throwIfDestroyed();
+        mHasActivePrintJobs = false;
+        if (!isBound()) {
+            // The service is dead and neither has active jobs nor discovery
+            // session, so ensure we are unbound since the service has no work.
+            if (mServiceDead && !mHasPrinterDiscoverySession) {
+                ensureUnbound();
+                return;
+            }
+            ensureBound();
+            mPendingCommands.add(new Runnable() {
+                @Override
+                public void run() {
+                    handleOnAllPrintJobsHandled();
+                }
+            });
+        } else {
+            if (DEBUG) {
+                Slog.i(LOG_TAG, "[user: " + mUserId + "] onAllPrintJobsHandled()");
+            }
+            // If the service has a printer discovery session
+            // created we should not disconnect from it just yet.
+            if (!mHasPrinterDiscoverySession) {
+                ensureUnbound();
+            }
+        }
+    }
+
+    public void onRequestCancelPrintJob(PrintJobInfo printJob) {
+        mHandler.obtainMessage(MyHandler.MSG_ON_REQUEST_CANCEL_PRINT_JOB,
+                printJob).sendToTarget();
+    }
+
+    private void handleRequestCancelPrintJob(final PrintJobInfo printJob) {
+        throwIfDestroyed();
+        if (!isBound()) {
+            ensureBound();
+            mPendingCommands.add(new Runnable() {
+                @Override
+                public void run() {
+                    handleRequestCancelPrintJob(printJob);
+                }
+            });
+        } else {
+            if (DEBUG) {
+                Slog.i(LOG_TAG, "[user: " + mUserId + "] requestCancelPrintJob()");
+            }
+            try {
+                mPrintService.requestCancelPrintJob(printJob);
+            } catch (RemoteException re) {
+                Slog.e(LOG_TAG, "Error canceling a pring job.", re);
+            }
+        }
+    }
+
+    public void onPrintJobQueued(PrintJobInfo printJob) {
+        mHandler.obtainMessage(MyHandler.MSG_ON_PRINT_JOB_QUEUED,
+                printJob).sendToTarget();
+    }
+
+    private void handleOnPrintJobQueued(final PrintJobInfo printJob) {
+        throwIfDestroyed();
+        mHasActivePrintJobs = true;
+        if (!isBound()) {
+            ensureBound();
+            mPendingCommands.add(new Runnable() {
+                @Override
+                public void run() {
+                    handleOnPrintJobQueued(printJob);
+                }
+            });
+        } else {
+            if (DEBUG) {
+                Slog.i(LOG_TAG, "[user: " + mUserId + "] onPrintJobQueued()");
+            }
+            try {
+                mPrintService.onPrintJobQueued(printJob);
+            } catch (RemoteException re) {
+                Slog.e(LOG_TAG, "Error announcing queued pring job.", re);
+            }
+        }
+    }
+
+    public void createPrinterDiscoverySession() {
+        mHandler.sendEmptyMessage(MyHandler.MSG_CREATE_PRINTER_DISCOVERY_SESSION);
+    }
+
+    private void handleCreatePrinterDiscoverySession() {
+        throwIfDestroyed();
+        mHasPrinterDiscoverySession = true;
+        if (!isBound()) {
+            ensureBound();
+            mPendingCommands.add(new Runnable() {
+                @Override
+                public void run() {
+                    handleCreatePrinterDiscoverySession();
+                }
+            });
+        } else {
+            if (DEBUG) {
+                Slog.i(LOG_TAG, "[user: " + mUserId + "] createPrinterDiscoverySession()");
+            }
+            try {
+                mPrintService.createPrinterDiscoverySession();
+            } catch (RemoteException re) {
+                Slog.e(LOG_TAG, "Error creating printer dicovery session.", re);
+            }
+        }
+    }
+
+    public void destroyPrinterDiscoverySession() {
+        mHandler.sendEmptyMessage(MyHandler.MSG_DESTROY_PRINTER_DISCOVERY_SESSION);
+    }
+
+    private void handleDestroyPrinterDiscoverySession() {
+        throwIfDestroyed();
+        mHasPrinterDiscoverySession = false;
+        if (!isBound()) {
+            // The service is dead and neither has active jobs nor discovery
+            // session, so ensure we are unbound since the service has no work.
+            if (mServiceDead && !mHasActivePrintJobs) {
+                ensureUnbound();
+                return;
+            }
+            ensureBound();
+            mPendingCommands.add(new Runnable() {
+                @Override
+                public void run() {
+                    handleDestroyPrinterDiscoverySession();
+                }
+            });
+        } else {
+            if (DEBUG) {
+                Slog.i(LOG_TAG, "[user: " + mUserId + "] destroyPrinterDiscoverySession()");
+            }
+            try {
+                mPrintService.destroyPrinterDiscoverySession();
+            } catch (RemoteException re) {
+                Slog.e(LOG_TAG, "Error destroying printer dicovery session.", re);
+            }
+            // If the service has no print jobs and no active discovery
+            // session anymore we should disconnect from it.
+            if (!mHasActivePrintJobs) {
+                ensureUnbound();
+            }
+        }
+    }
+
+    public void startPrinterDiscovery(List<PrinterId> priorityList) {
+        mHandler.obtainMessage(MyHandler.MSG_START_PRINTER_DISCOVERY,
+                priorityList).sendToTarget();
+    }
+
+    private void handleStartPrinterDiscovery(final List<PrinterId> priorityList) {
+        throwIfDestroyed();
+        // Take a note that we are doing discovery.
+        mDiscoveryPriorityList = new ArrayList<PrinterId>();
+        if (priorityList != null) {
+            mDiscoveryPriorityList.addAll(priorityList);
+        }
+        if (!isBound()) {
+            ensureBound();
+            mPendingCommands.add(new Runnable() {
+                @Override
+                public void run() {
+                    handleStartPrinterDiscovery(priorityList);
+                }
+            });
+        } else {
+            if (DEBUG) {
+                Slog.i(LOG_TAG, "[user: " + mUserId + "] startPrinterDiscovery()");
+            }
+            try {
+                mPrintService.startPrinterDiscovery(priorityList);
+            } catch (RemoteException re) {
+                Slog.e(LOG_TAG, "Error starting printer dicovery.", re);
+            }
+        }
+    }
+
+    public void stopPrinterDiscovery() {
+        mHandler.sendEmptyMessage(MyHandler.MSG_STOP_PRINTER_DISCOVERY);
+    }
+
+    private void handleStopPrinterDiscovery() {
+        throwIfDestroyed();
+        // We are not doing discovery anymore.
+        mDiscoveryPriorityList = null;
+        if (!isBound()) {
+            ensureBound();
+            mPendingCommands.add(new Runnable() {
+                @Override
+                public void run() {
+                    handleStopPrinterDiscovery();
+                }
+            });
+        } else {
+            if (DEBUG) {
+                Slog.i(LOG_TAG, "[user: " + mUserId + "] stopPrinterDiscovery()");
+            }
+            try {
+                mPrintService.stopPrinterDiscovery();
+            } catch (RemoteException re) {
+                Slog.e(LOG_TAG, "Error stopping printer dicovery.", re);
+            }
+        }
+    }
+
+    public void validatePrinters(List<PrinterId> printerIds) {
+        mHandler.obtainMessage(MyHandler.MSG_VALIDATE_PRINTERS,
+                printerIds).sendToTarget();
+    }
+
+    private void handleValidatePrinters(final List<PrinterId> printerIds) {
+        throwIfDestroyed();
+        if (!isBound()) {
+            ensureBound();
+            mPendingCommands.add(new Runnable() {
+                @Override
+                public void run() {
+                    handleValidatePrinters(printerIds);
+                }
+            });
+        } else {
+            if (DEBUG) {
+                Slog.i(LOG_TAG, "[user: " + mUserId + "] validatePrinters()");
+            }
+            try {
+                mPrintService.validatePrinters(printerIds);
+            } catch (RemoteException re) {
+                Slog.e(LOG_TAG, "Error requesting printers validation.", re);
+            }
+        }
+    }
+
+    public void startPrinterStateTracking(PrinterId printerId) {
+        mHandler.obtainMessage(MyHandler.MSG_START_PRINTER_STATE_TRACKING,
+                printerId).sendToTarget();
+    }
+
+    private void handleStartPrinterStateTracking(final PrinterId printerId) {
+        throwIfDestroyed();
+        // Take a note we are tracking the printer.
+        if (mTrackedPrinterList == null) {
+            mTrackedPrinterList = new ArrayList<PrinterId>();
+        }
+        mTrackedPrinterList.add(printerId);
+        if (!isBound()) {
+            ensureBound();
+            mPendingCommands.add(new Runnable() {
+                @Override
+                public void run() {
+                    handleStartPrinterStateTracking(printerId);
+                }
+            });
+        } else {
+            if (DEBUG) {
+                Slog.i(LOG_TAG, "[user: " + mUserId + "] startPrinterTracking()");
+            }
+            try {
+                mPrintService.startPrinterStateTracking(printerId);
+            } catch (RemoteException re) {
+                Slog.e(LOG_TAG, "Error requesting start printer tracking.", re);
+            }
+        }
+    }
+
+    public void stopPrinterStateTracking(PrinterId printerId) {
+        mHandler.obtainMessage(MyHandler.MSG_STOP_PRINTER_STATE_TRACKING,
+                printerId).sendToTarget();
+    }
+
+    private void handleStopPrinterStateTracking(final PrinterId printerId) {
+        throwIfDestroyed();
+        // We are no longer tracking the printer.
+        if (mTrackedPrinterList == null || !mTrackedPrinterList.remove(printerId)) {
+            return;
+        }
+        if (mTrackedPrinterList.isEmpty()) {
+            mTrackedPrinterList = null;
+        }
+        if (!isBound()) {
+            ensureBound();
+            mPendingCommands.add(new Runnable() {
+                @Override
+                public void run() {
+                    handleStopPrinterStateTracking(printerId);
+                }
+            });
+        } else {
+            if (DEBUG) {
+                Slog.i(LOG_TAG, "[user: " + mUserId + "] stopPrinterTracking()");
+            }
+            try {
+                mPrintService.stopPrinterStateTracking(printerId);
+            } catch (RemoteException re) {
+                Slog.e(LOG_TAG, "Error requesting stop printer tracking.", re);
+            }
+        }
+    }
+
+    public void dump(PrintWriter pw, String prefix) {
+        String tab = "  ";
+        pw.append(prefix).append("service:").println();
+        pw.append(prefix).append(tab).append("componentName=")
+                .append(mComponentName.flattenToString()).println();
+        pw.append(prefix).append(tab).append("destroyed=")
+                .append(String.valueOf(mDestroyed)).println();
+        pw.append(prefix).append(tab).append("bound=")
+                .append(String.valueOf(isBound())).println();
+        pw.append(prefix).append(tab).append("hasDicoverySession=")
+                .append(String.valueOf(mHasPrinterDiscoverySession)).println();
+        pw.append(prefix).append(tab).append("hasActivePrintJobs=")
+                .append(String.valueOf(mHasActivePrintJobs)).println();
+        pw.append(prefix).append(tab).append("isDiscoveringPrinters=")
+                .append(String.valueOf(mDiscoveryPriorityList != null)).println();
+        pw.append(prefix).append(tab).append("trackedPrinters=")
+                .append((mTrackedPrinterList != null) ? mTrackedPrinterList.toString() : "null");
+    }
+
+    private boolean isBound() {
+        return mPrintService != null;
+    }
+
+    private void ensureBound() {
+        if (isBound() || mBinding) {
+            return;
+        }
+        if (DEBUG) {
+            Slog.i(LOG_TAG, "[user: " + mUserId + "] ensureBound()");
+        }
+        mBinding = true;
+        mContext.bindServiceAsUser(mIntent, mServiceConnection,
+                Context.BIND_AUTO_CREATE, new UserHandle(mUserId));
+    }
+
+    private void ensureUnbound() {
+        if (!isBound() && !mBinding) {
+            return;
+        }
+        if (DEBUG) {
+            Slog.i(LOG_TAG, "[user: " + mUserId + "] ensureUnbound()");
+        }
+        mBinding = false;
+        mPendingCommands.clear();
+        mHasActivePrintJobs = false;
+        mHasPrinterDiscoverySession = false;
+        mDiscoveryPriorityList = null;
+        mTrackedPrinterList = null;
+        if (isBound()) {
+            try {
+                mPrintService.setClient(null);
+            } catch (RemoteException re) {
+                /* ignore */
+            }
+            mPrintService.asBinder().unlinkToDeath(this, 0);
+            mPrintService = null;
+            mContext.unbindService(mServiceConnection);
+        }
+    }
+
+    private void throwIfDestroyed() {
+        if (mDestroyed) {
+            throw new IllegalStateException("Cannot interact with a destroyed service");
+        }
+    }
+
+    private class RemoteServiceConneciton implements ServiceConnection {
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            if (mDestroyed || !mBinding) {
+                mContext.unbindService(mServiceConnection);
+                return;
+            }
+            mBinding = false;
+            mPrintService = IPrintService.Stub.asInterface(service);
+            try {
+                service.linkToDeath(RemotePrintService.this, 0);
+            } catch (RemoteException re) {
+                handleBinderDied();
+                return;
+            }
+            try {
+                mPrintService.setClient(mPrintServiceClient);
+            } catch (RemoteException re) {
+                Slog.e(LOG_TAG, "Error setting client for: " + service, re);
+                handleBinderDied();
+                return;
+            }
+            // If the service died and there is a discovery session, recreate it.
+            if (mServiceDead && mHasPrinterDiscoverySession) {
+                handleCreatePrinterDiscoverySession();
+            }
+            // If the service died and there is discovery started, restart it.
+            if (mServiceDead && mDiscoveryPriorityList != null) {
+                handleStartPrinterDiscovery(mDiscoveryPriorityList);
+            }
+            // If the service died and printers were tracked, start tracking.
+            if (mServiceDead && mTrackedPrinterList != null) {
+                final int trackedPrinterCount = mTrackedPrinterList.size();
+                for (int i = 0; i < trackedPrinterCount; i++) {
+                    handleStartPrinterStateTracking(mTrackedPrinterList.get(i));
+                }
+            }
+            // Finally, do all the pending work.
+            while (!mPendingCommands.isEmpty()) {
+                Runnable pendingCommand = mPendingCommands.remove(0);
+                pendingCommand.run();
+            }
+            // We did a best effort to get to the last state if we crashed.
+            // If we do not have print jobs and no discovery is in progress,
+            // then no need to be bound.
+            if (!mHasPrinterDiscoverySession && !mHasActivePrintJobs) {
+                ensureUnbound();
+            }
+            mServiceDead = false;
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            mBinding = true;
+        }
+    }
+
+    private final class MyHandler extends Handler {
+        public static final int MSG_CREATE_PRINTER_DISCOVERY_SESSION = 1;
+        public static final int MSG_DESTROY_PRINTER_DISCOVERY_SESSION = 2;
+        public static final int MSG_START_PRINTER_DISCOVERY = 3;
+        public static final int MSG_STOP_PRINTER_DISCOVERY = 4;
+        public static final int MSG_VALIDATE_PRINTERS = 5;
+        public static final int MSG_START_PRINTER_STATE_TRACKING = 6;
+        public static final int MSG_STOP_PRINTER_STATE_TRACKING = 7;
+        public static final int MSG_ON_ALL_PRINT_JOBS_HANDLED = 8;
+        public static final int MSG_ON_REQUEST_CANCEL_PRINT_JOB = 9;
+        public static final int MSG_ON_PRINT_JOB_QUEUED = 10;
+        public static final int MSG_DESTROY = 11;
+        public static final int MSG_BINDER_DIED = 12;
+
+        public MyHandler(Looper looper) {
+            super(looper, null, false);
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public void handleMessage(Message message) {
+            switch (message.what) {
+                case MSG_CREATE_PRINTER_DISCOVERY_SESSION: {
+                    handleCreatePrinterDiscoverySession();
+                } break;
+
+                case MSG_DESTROY_PRINTER_DISCOVERY_SESSION: {
+                    handleDestroyPrinterDiscoverySession();
+                } break;
+
+                case MSG_START_PRINTER_DISCOVERY: {
+                    List<PrinterId> priorityList = (ArrayList<PrinterId>) message.obj;
+                    handleStartPrinterDiscovery(priorityList);
+                } break;
+
+                case MSG_STOP_PRINTER_DISCOVERY: {
+                    handleStopPrinterDiscovery();
+                } break;
+
+                case MSG_VALIDATE_PRINTERS: {
+                    List<PrinterId> printerIds = (List<PrinterId>) message.obj;
+                    handleValidatePrinters(printerIds);
+                } break;
+
+                case MSG_START_PRINTER_STATE_TRACKING: {
+                    PrinterId printerId = (PrinterId) message.obj;
+                    handleStartPrinterStateTracking(printerId);
+                } break;
+
+                case MSG_STOP_PRINTER_STATE_TRACKING: {
+                    PrinterId printerId = (PrinterId) message.obj;
+                    handleStopPrinterStateTracking(printerId);
+                } break;
+
+                case MSG_ON_ALL_PRINT_JOBS_HANDLED: {
+                    handleOnAllPrintJobsHandled();
+                } break;
+
+                case MSG_ON_REQUEST_CANCEL_PRINT_JOB: {
+                    PrintJobInfo printJob = (PrintJobInfo) message.obj;
+                    handleRequestCancelPrintJob(printJob);
+                } break;
+
+                case MSG_ON_PRINT_JOB_QUEUED: {
+                    PrintJobInfo printJob = (PrintJobInfo) message.obj;
+                    handleOnPrintJobQueued(printJob);
+                } break;
+
+                case MSG_DESTROY: {
+                    handleDestroy();
+                } break;
+
+                case MSG_BINDER_DIED: {
+                    handleBinderDied();
+                } break;
+            }
+        }
+    }
+
+    private static final class RemotePrintServiceClient extends IPrintServiceClient.Stub {
+        private final WeakReference<RemotePrintService> mWeakService;
+
+        public RemotePrintServiceClient(RemotePrintService service) {
+            mWeakService = new WeakReference<RemotePrintService>(service);
+        }
+
+        @Override
+        public List<PrintJobInfo> getPrintJobInfos() {
+            RemotePrintService service = mWeakService.get();
+            if (service != null) {
+                final long identity = Binder.clearCallingIdentity();
+                try {
+                    return service.mSpooler.getPrintJobInfos(service.mComponentName,
+                            PrintJobInfo.STATE_ANY_VISIBLE_TO_CLIENTS, PrintManager.APP_ID_ANY);
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            }
+            return null;
+        }
+
+        @Override
+        public PrintJobInfo getPrintJobInfo(int printJobId) {
+            RemotePrintService service = mWeakService.get();
+            if (service != null) {
+                final long identity = Binder.clearCallingIdentity();
+                try {
+                    return service.mSpooler.getPrintJobInfo(printJobId,
+                            PrintManager.APP_ID_ANY);
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            }
+            return null;
+        }
+
+        @Override
+        public boolean setPrintJobState(int printJobId, int state, String error) {
+            RemotePrintService service = mWeakService.get();
+            if (service != null) {
+                final long identity = Binder.clearCallingIdentity();
+                try {
+                    return service.mSpooler.setPrintJobState(printJobId, state, error);
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            }
+            return false;
+        }
+
+        @Override
+        public boolean setPrintJobTag(int printJobId, String tag) {
+            RemotePrintService service = mWeakService.get();
+            if (service != null) {
+                final long identity = Binder.clearCallingIdentity();
+                try {
+                    return service.mSpooler.setPrintJobTag(printJobId, tag);
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            }
+            return false;
+        }
+
+        @Override
+        public void writePrintJobData(ParcelFileDescriptor fd, int printJobId) {
+            RemotePrintService service = mWeakService.get();
+            if (service != null) {
+                final long identity = Binder.clearCallingIdentity();
+                try {
+                    service.mSpooler.writePrintJobData(fd, printJobId);
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            }
+        }
+
+        @Override
+        public void onPrintersAdded(List<PrinterInfo> printers) {
+            RemotePrintService service = mWeakService.get();
+            if (service != null) {
+                throwIfPrinterIdsForPrinterInfoTampered(service.mComponentName, printers);
+                final long identity = Binder.clearCallingIdentity();
+                try {
+                    service.mCallbacks.onPrintersAdded(printers);
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            }
+        }
+
+        @Override
+        public void onPrintersRemoved(List<PrinterId> printerIds) {
+            RemotePrintService service = mWeakService.get();
+            if (service != null) {
+                throwIfPrinterIdsTampered(service.mComponentName, printerIds);
+                final long identity = Binder.clearCallingIdentity();
+                try {
+                    service.mCallbacks.onPrintersRemoved(printerIds);
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            }
+        }
+
+        private void throwIfPrinterIdsForPrinterInfoTampered(ComponentName serviceName,
+                List<PrinterInfo> printerInfos) {
+            final int printerInfoCount = printerInfos.size();
+            for (int i = 0; i < printerInfoCount; i++) {
+                PrinterId printerId = printerInfos.get(i).getId();
+                throwIfPrinterIdTampered(serviceName, printerId);
+            }
+        }
+
+        private void throwIfPrinterIdsTampered(ComponentName serviceName,
+                List<PrinterId> printerIds) {
+            final int printerIdCount = printerIds.size();
+            for (int i = 0; i < printerIdCount; i++) {
+                PrinterId printerId = printerIds.get(i);
+                throwIfPrinterIdTampered(serviceName, printerId);
+            }
+        }
+
+        private void throwIfPrinterIdTampered(ComponentName serviceName, PrinterId printerId) {
+            if (printerId == null || printerId.getServiceName() == null
+                    || !printerId.getServiceName().equals(serviceName)) {
+                throw new IllegalArgumentException("Invalid printer id: " + printerId);
+            }
+        }
+    }
+}
diff --git a/services/java/com/android/server/print/RemotePrintSpooler.java b/services/java/com/android/server/print/RemotePrintSpooler.java
new file mode 100644
index 0000000..45469ac
--- /dev/null
+++ b/services/java/com/android/server/print/RemotePrintSpooler.java
@@ -0,0 +1,621 @@
+/*
+ * 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.server.print;
+
+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.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.print.IPrintClient;
+import android.print.IPrintDocumentAdapter;
+import android.print.IPrintSpooler;
+import android.print.IPrintSpoolerCallbacks;
+import android.print.IPrintSpoolerClient;
+import android.print.PrintAttributes;
+import android.print.PrintJobInfo;
+import android.print.PrintManager;
+import android.util.Slog;
+import android.util.TimedRemoteCaller;
+
+import libcore.io.IoUtils;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
+import java.util.List;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * This represents the remote print spooler as a local object to the
+ * PrintManagerSerivce. It is responsible to connecting to the remote
+ * spooler if needed, to make the timed remote calls, to handle
+ * remote exceptions, and to bind/unbind to the remote instance as
+ * needed.
+ */
+final class RemotePrintSpooler {
+
+    private static final String LOG_TAG = "RemotePrintSpooler";
+
+    private static final boolean DEBUG = false;
+
+    private static final long BIND_SPOOLER_SERVICE_TIMEOUT = 10000;
+
+    private final Object mLock = new Object();
+
+    private final GetPrintJobInfosCaller mGetPrintJobInfosCaller = new GetPrintJobInfosCaller();
+
+    private final CreatePrintJobCaller mCreatePrintJobCaller = new CreatePrintJobCaller();
+
+    private final GetPrintJobInfoCaller mGetPrintJobInfoCaller = new GetPrintJobInfoCaller();
+
+    private final SetPrintJobStateCaller mSetPrintJobStatusCaller = new SetPrintJobStateCaller();
+
+    private final SetPrintJobTagCaller mSetPrintJobTagCaller = new SetPrintJobTagCaller();
+
+    private final ServiceConnection mServiceConnection = new MyServiceConnection();
+
+    private final Context mContext;
+
+    private final UserHandle mUserHandle;
+
+    private final PrintSpoolerClient mClient;
+
+    private final Intent mIntent;
+
+    private final PrintSpoolerCallbacks mCallbacks;
+
+    private IPrintSpooler mRemoteInstance;
+
+    private boolean mDestroyed;
+
+    private boolean mCanUnbind;
+
+    public static interface PrintSpoolerCallbacks {
+        public void onPrintJobQueued(PrintJobInfo printJob);
+        public void onAllPrintJobsForServiceHandled(ComponentName printService);
+    }
+
+    public RemotePrintSpooler(Context context, int userId,
+            PrintSpoolerCallbacks callbacks) {
+        mContext = context;
+        mUserHandle = new UserHandle(userId);
+        mCallbacks = callbacks;
+        mClient = new PrintSpoolerClient(this);
+        mIntent = new Intent();
+        mIntent.setComponent(new ComponentName("com.android.printspooler",
+                "com.android.printspooler.PrintSpoolerService"));
+    }
+
+    public final List<PrintJobInfo> getPrintJobInfos(ComponentName componentName, int state,
+            int appId) {
+        throwIfCalledOnMainThread();
+        synchronized (mLock) {
+            throwIfDestroyedLocked();
+            mCanUnbind = false;
+        }
+        try {
+            return mGetPrintJobInfosCaller.getPrintJobInfos(getRemoteInstanceLazy(),
+                    componentName, state, appId);
+        } catch (RemoteException re) {
+            Slog.e(LOG_TAG, "Error getting print jobs.", re);
+        } catch (TimeoutException te) {
+            Slog.e(LOG_TAG, "Error getting print jobs.", te);
+        } finally {
+            if (DEBUG) {
+                Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] getPrintJobInfos()");
+            }
+            synchronized (mLock) {
+                mCanUnbind = true;
+                mLock.notifyAll();
+            }
+        }
+        return null;
+    }
+
+    public final PrintJobInfo createPrintJob(String printJobName, IPrintClient client,
+            IPrintDocumentAdapter documentAdapter, PrintAttributes attributes, int appId) {
+        throwIfCalledOnMainThread();
+        synchronized (mLock) {
+            throwIfDestroyedLocked();
+            mCanUnbind = false;
+        }
+        try {
+            return mCreatePrintJobCaller.createPrintJob(getRemoteInstanceLazy(),
+                    printJobName, client, documentAdapter, attributes, appId);
+        } catch (RemoteException re) {
+            Slog.e(LOG_TAG, "Error creating print job.", re);
+        } catch (TimeoutException te) {
+            Slog.e(LOG_TAG, "Error creating print job.", te);
+        } finally {
+            if (DEBUG) {
+                Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] createPrintJob()");
+            }
+            synchronized (mLock) {
+                mCanUnbind = true;
+                mLock.notifyAll();
+            }
+        }
+        return null;
+    }
+
+    public final void writePrintJobData(ParcelFileDescriptor fd, int printJobId) {
+        throwIfCalledOnMainThread();
+        synchronized (mLock) {
+            throwIfDestroyedLocked();
+            mCanUnbind = false;
+        }
+        try {
+            getRemoteInstanceLazy().writePrintJobData(fd, printJobId);
+        } catch (RemoteException re) {
+            Slog.e(LOG_TAG, "Error writing print job data.", re);
+        } catch (TimeoutException te) {
+            Slog.e(LOG_TAG, "Error writing print job data.", te);
+        } finally {
+            if (DEBUG) {
+                Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] writePrintJobData()");
+            }
+            // We passed the file descriptor across and now the other
+            // side is responsible to close it, so close the local copy.
+            IoUtils.closeQuietly(fd);
+            synchronized (mLock) {
+                mCanUnbind = true;
+                mLock.notifyAll();
+            }
+        }
+    }
+
+    public final PrintJobInfo getPrintJobInfo(int printJobId, int appId) {
+        throwIfCalledOnMainThread();
+        synchronized (mLock) {
+            throwIfDestroyedLocked();
+            mCanUnbind = false;
+        }
+        try {
+            return mGetPrintJobInfoCaller.getPrintJobInfo(getRemoteInstanceLazy(),
+                    printJobId, appId);
+        } catch (RemoteException re) {
+            Slog.e(LOG_TAG, "Error getting print job info.", re);
+        } catch (TimeoutException te) {
+            Slog.e(LOG_TAG, "Error getting print job info.", te);
+        } finally {
+            if (DEBUG) {
+                Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] getPrintJobInfo()");
+            }
+            synchronized (mLock) {
+                mCanUnbind = true;
+                mLock.notifyAll();
+            }
+        }
+        return null;
+    }
+
+    public final boolean setPrintJobState(int printJobId, int state, String error) {
+        throwIfCalledOnMainThread();
+        synchronized (mLock) {
+            throwIfDestroyedLocked();
+            mCanUnbind = false;
+        }
+        try {
+            return mSetPrintJobStatusCaller.setPrintJobState(getRemoteInstanceLazy(),
+                    printJobId, state, error);
+        } catch (RemoteException re) {
+            Slog.e(LOG_TAG, "Error setting print job state.", re);
+        } catch (TimeoutException te) {
+            Slog.e(LOG_TAG, "Error setting print job state.", te);
+        } finally {
+            if (DEBUG) {
+                Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setPrintJobState()");
+            }
+            synchronized (mLock) {
+                mCanUnbind = true;
+                mLock.notifyAll();
+            }
+        }
+        return false;
+    }
+
+    public final boolean setPrintJobTag(int printJobId, String tag) {
+        throwIfCalledOnMainThread();
+        synchronized (mLock) {
+            throwIfDestroyedLocked();
+            mCanUnbind = false;
+        }
+        try {
+            return mSetPrintJobTagCaller.setPrintJobTag(getRemoteInstanceLazy(),
+                    printJobId, tag);
+        } catch (RemoteException re) {
+            Slog.e(LOG_TAG, "Error setting print job tag.", re);
+        } catch (TimeoutException te) {
+            Slog.e(LOG_TAG, "Error setting print job tag.", te);
+        } finally {
+            if (DEBUG) {
+                Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setPrintJobTag()");
+            }
+            synchronized (mLock) {
+                mCanUnbind = true;
+                mLock.notifyAll();
+            }
+        }
+        return false;
+    }
+
+    public final void start() {
+        throwIfCalledOnMainThread();
+        synchronized (mLock) {
+            throwIfDestroyedLocked();
+            mCanUnbind = false;
+        }
+        try {
+            getRemoteInstanceLazy();
+        } catch (TimeoutException te) {
+            Slog.e(LOG_TAG, "Error starting the spooler.", te);
+        } finally {
+            if (DEBUG) {
+                Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] start()");
+            }
+            synchronized (mLock) {
+                mCanUnbind = true;
+                mLock.notifyAll();
+            }
+        }
+    }
+
+    public final void destroy() {
+        throwIfCalledOnMainThread();
+        if (DEBUG) {
+            Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] destroy()");
+        }
+        synchronized (mLock) {
+            throwIfDestroyedLocked();
+            unbindLocked();
+            mDestroyed = true;
+            mCanUnbind = false;
+        }
+    }
+
+    public void dump(FileDescriptor fd, PrintWriter pw, String prefix) {
+        synchronized (mLock) {
+            pw.append(prefix).append("destroyed=")
+                    .append(String.valueOf(mDestroyed)).println();
+            pw.append(prefix).append("bound=")
+                    .append((mRemoteInstance != null) ? "true" : "false").println();
+            pw.append(prefix).append("print jobs:").println();
+            if (mRemoteInstance != null) {
+                List<PrintJobInfo> printJobs = getPrintJobInfos(null,
+                        PrintJobInfo.STATE_ANY, PrintManager.APP_ID_ANY);
+                if (printJobs != null) {
+                    final int printJobCount = printJobs.size();
+                    for (int i = 0; i < printJobCount; i++) {
+                        PrintJobInfo printJob = printJobs.get(i);
+                        pw.append(prefix).append(prefix).append(printJob.toString());
+                        pw.println();
+                    }
+                }
+            }
+        }
+    }
+
+    private void onAllPrintJobsHandled() {
+        synchronized (mLock) {
+            throwIfDestroyedLocked();
+            unbindLocked();
+        }
+    }
+
+    private IPrintSpooler getRemoteInstanceLazy() throws TimeoutException {
+        synchronized (mLock) {
+            if (mRemoteInstance != null) {
+                return mRemoteInstance;
+            }
+            bindLocked();
+            return mRemoteInstance;
+        }
+    }
+
+    private void bindLocked() throws TimeoutException {
+        if (DEBUG) {
+            Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] bindLocked()");
+        }
+
+        mContext.bindServiceAsUser(mIntent, mServiceConnection,
+                Context.BIND_AUTO_CREATE, mUserHandle);
+
+        final long startMillis = SystemClock.uptimeMillis();
+        while (true) {
+            if (mRemoteInstance != null) {
+                break;
+            }
+            final long elapsedMillis = SystemClock.uptimeMillis() - startMillis;
+            final long remainingMillis = BIND_SPOOLER_SERVICE_TIMEOUT - elapsedMillis;
+            if (remainingMillis <= 0) {
+                throw new TimeoutException("Cannot get spooler!");
+            }
+            try {
+                mLock.wait(remainingMillis);
+            } catch (InterruptedException ie) {
+                /* ignore */
+            }
+        }
+
+        mCanUnbind = true;
+        mLock.notifyAll();
+    }
+
+    private void unbindLocked() {
+        while (true) {
+            if (mCanUnbind) {
+                if (DEBUG) {
+                    Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] unbindLocked()");
+                }
+                clearClientLocked();
+                mRemoteInstance = null;
+                mContext.unbindService(mServiceConnection);
+                return;
+            }
+            try {
+                mLock.wait();
+            } catch (InterruptedException ie) {
+                /* ignore */
+            }
+        }
+
+    }
+
+    private void setClientLocked() {
+        try {
+            mRemoteInstance.setClient(mClient);
+        } catch (RemoteException re) {
+            Slog.d(LOG_TAG, "Error setting print spooler client", re);
+        }
+    }
+
+    private void clearClientLocked() {
+        try {
+            mRemoteInstance.setClient(null);
+        } catch (RemoteException re) {
+            Slog.d(LOG_TAG, "Error clearing print spooler client", re);
+        }
+
+    }
+
+    private void throwIfDestroyedLocked() {
+        if (mDestroyed) {
+            throw new IllegalStateException("Cannot interact with a destroyed instance.");
+        }
+    }
+
+    private void throwIfCalledOnMainThread() {
+        if (Thread.currentThread() == mContext.getMainLooper().getThread()) {
+            throw new RuntimeException("Cannot invoke on the main thread");
+        }
+    }
+
+    private final class MyServiceConnection implements ServiceConnection {
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            synchronized (mLock) {
+                mRemoteInstance = IPrintSpooler.Stub.asInterface(service);
+                setClientLocked();
+                mLock.notifyAll();
+            }
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            synchronized (mLock) {
+                clearClientLocked();
+                mRemoteInstance = null;
+            }
+        }
+    }
+
+    private static final class GetPrintJobInfosCaller
+            extends TimedRemoteCaller<List<PrintJobInfo>> {
+        private final IPrintSpoolerCallbacks mCallback;
+
+        public GetPrintJobInfosCaller() {
+            super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS);
+            mCallback = new BasePrintSpoolerServiceCallbacks() {
+                @Override
+                public void onGetPrintJobInfosResult(List<PrintJobInfo> printJobs, int sequence) {
+                    onRemoteMethodResult(printJobs, sequence);
+                }
+            };
+        }
+
+        public List<PrintJobInfo> getPrintJobInfos(IPrintSpooler target,
+                ComponentName componentName, int state, int appId)
+                        throws RemoteException, TimeoutException {
+            final int sequence = onBeforeRemoteCall();
+            target.getPrintJobInfos(mCallback, componentName, state, appId, sequence);
+            return getResultTimed(sequence);
+        }
+    }
+
+    private static final class CreatePrintJobCaller extends TimedRemoteCaller<PrintJobInfo> {
+        private final IPrintSpoolerCallbacks mCallback;
+
+        public CreatePrintJobCaller() {
+            super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS);
+            mCallback = new BasePrintSpoolerServiceCallbacks() {
+                @Override
+                public void onCreatePrintJobResult(PrintJobInfo printJob, int sequence) {
+                    onRemoteMethodResult(printJob, sequence);
+                }
+            };
+        }
+
+        public PrintJobInfo createPrintJob(IPrintSpooler target, String printJobName,
+                IPrintClient client, IPrintDocumentAdapter documentAdapter,
+                PrintAttributes attributes, int appId) throws RemoteException, TimeoutException {
+            final int sequence = onBeforeRemoteCall();
+            target.createPrintJob(printJobName, client, documentAdapter, attributes,
+                    mCallback, appId, sequence);
+            return getResultTimed(sequence);
+        }
+    }
+
+    private static final class GetPrintJobInfoCaller extends TimedRemoteCaller<PrintJobInfo> {
+        private final IPrintSpoolerCallbacks mCallback;
+
+        public GetPrintJobInfoCaller() {
+            super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS);
+            mCallback = new BasePrintSpoolerServiceCallbacks() {
+                @Override
+                public void onGetPrintJobInfoResult(PrintJobInfo printJob, int sequence) {
+                    onRemoteMethodResult(printJob, sequence);
+                }
+            };
+        }
+
+        public PrintJobInfo getPrintJobInfo(IPrintSpooler target, int printJobId,
+                int appId) throws RemoteException, TimeoutException {
+            final int sequence = onBeforeRemoteCall();
+            target.getPrintJobInfo(printJobId, mCallback, appId, sequence);
+            return getResultTimed(sequence);
+        }
+    }
+
+    private static final class SetPrintJobStateCaller extends TimedRemoteCaller<Boolean> {
+        private final IPrintSpoolerCallbacks mCallback;
+
+        public SetPrintJobStateCaller() {
+            super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS);
+            mCallback = new BasePrintSpoolerServiceCallbacks() {
+                @Override
+                public void onSetPrintJobStateResult(boolean success, int sequence) {
+                    onRemoteMethodResult(success, sequence);
+                }
+            };
+        }
+
+        public boolean setPrintJobState(IPrintSpooler target, int printJobId,
+                int status, String error) throws RemoteException, TimeoutException {
+            final int sequence = onBeforeRemoteCall();
+            target.setPrintJobState(printJobId, status, error, mCallback, sequence);
+            return getResultTimed(sequence);
+        }
+    }
+
+    private static final class SetPrintJobTagCaller extends TimedRemoteCaller<Boolean> {
+        private final IPrintSpoolerCallbacks mCallback;
+
+        public SetPrintJobTagCaller() {
+            super(TimedRemoteCaller.DEFAULT_CALL_TIMEOUT_MILLIS);
+            mCallback = new BasePrintSpoolerServiceCallbacks() {
+                @Override
+                public void onSetPrintJobTagResult(boolean success, int sequence) {
+                    onRemoteMethodResult(success, sequence);
+                }
+            };
+        }
+
+        public boolean setPrintJobTag(IPrintSpooler target, int printJobId,
+                String tag) throws RemoteException, TimeoutException {
+            final int sequence = onBeforeRemoteCall();
+            target.setPrintJobTag(printJobId, tag, mCallback, sequence);
+            return getResultTimed(sequence);
+        }
+    }
+
+    private static abstract class BasePrintSpoolerServiceCallbacks
+            extends IPrintSpoolerCallbacks.Stub {
+        @Override
+        public void onGetPrintJobInfosResult(List<PrintJobInfo> printJobIds, int sequence) {
+            /* do nothing */
+        }
+
+        @Override
+        public void onGetPrintJobInfoResult(PrintJobInfo printJob, int sequence) {
+            /* do nothing */
+        }
+
+        @Override
+        public void onCreatePrintJobResult(PrintJobInfo printJob, int sequence) {
+            /* do nothing */
+        }
+
+        @Override
+        public void onCancelPrintJobResult(boolean canceled, int sequence) {
+            /* do nothing */
+        }
+
+        @Override
+        public void onSetPrintJobStateResult(boolean success, int sequece) {
+            /* do nothing */
+        }
+
+        @Override
+        public void onSetPrintJobTagResult(boolean success, int sequence) {
+            /* do nothing */
+        }
+    }
+
+    private static final class PrintSpoolerClient extends IPrintSpoolerClient.Stub {
+
+        private final WeakReference<RemotePrintSpooler> mWeakSpooler;
+
+        public PrintSpoolerClient(RemotePrintSpooler spooler) {
+            mWeakSpooler = new WeakReference<RemotePrintSpooler>(spooler);
+        }
+
+        @Override
+        public void onPrintJobQueued(PrintJobInfo printJob) {
+            RemotePrintSpooler spooler = mWeakSpooler.get();
+            if (spooler != null) {
+                final long identity = Binder.clearCallingIdentity();
+                try {
+                    spooler.mCallbacks.onPrintJobQueued(printJob);
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            }
+        }
+
+        @Override
+        public void onAllPrintJobsForServiceHandled(ComponentName printService) {
+            RemotePrintSpooler spooler = mWeakSpooler.get();
+            if (spooler != null) {
+                final long identity = Binder.clearCallingIdentity();
+                try {
+                    spooler.mCallbacks.onAllPrintJobsForServiceHandled(printService);
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            }
+        }
+
+        @Override
+        public void onAllPrintJobsHandled() {
+            RemotePrintSpooler spooler = mWeakSpooler.get();
+            if (spooler != null) {
+                final long identity = Binder.clearCallingIdentity();
+                try {
+                    spooler.onAllPrintJobsHandled();
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            }
+        }
+    }
+}
diff --git a/services/java/com/android/server/print/UserState.java b/services/java/com/android/server/print/UserState.java
new file mode 100644
index 0000000..7a56e6b
--- /dev/null
+++ b/services/java/com/android/server/print/UserState.java
@@ -0,0 +1,1258 @@
+/*
+ * 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.server.print;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.os.AsyncTask;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteCallbackList;
+import android.os.RemoteException;
+import android.print.IPrinterDiscoveryObserver;
+import android.print.PrintJobInfo;
+import android.print.PrintManager;
+import android.print.PrinterId;
+import android.print.PrinterInfo;
+import android.printservice.PrintServiceInfo;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.text.TextUtils.SimpleStringSplitter;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.Log;
+import android.util.Slog;
+
+import com.android.internal.R;
+import com.android.internal.os.SomeArgs;
+import com.android.server.print.RemotePrintService.PrintServiceCallbacks;
+import com.android.server.print.RemotePrintSpooler.PrintSpoolerCallbacks;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Represents the print state for a user.
+ */
+final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks {
+
+    private static final String LOG_TAG = "UserState";
+
+    private static final boolean DEBUG = false;
+
+    private static final int MAX_ITEMS_PER_CALLBACK = 50;
+
+    private static final char COMPONENT_NAME_SEPARATOR = ':';
+
+    private final SimpleStringSplitter mStringColonSplitter =
+            new SimpleStringSplitter(COMPONENT_NAME_SEPARATOR);
+
+    private final Intent mQueryIntent =
+            new Intent(android.printservice.PrintService.SERVICE_INTERFACE);
+
+    private final ArrayMap<ComponentName, RemotePrintService> mActiveServices =
+            new ArrayMap<ComponentName, RemotePrintService>();
+
+    private final List<PrintServiceInfo> mInstalledServices =
+            new ArrayList<PrintServiceInfo>();
+
+    private final Set<ComponentName> mEnabledServices =
+            new ArraySet<ComponentName>();
+
+    private final Object mLock;
+
+    private final Context mContext;
+
+    private final int mUserId;
+
+    private final RemotePrintSpooler mSpooler;
+
+    private PrinterDiscoverySessionMediator mPrinterDiscoverySession;
+
+    private boolean mDestroyed;
+
+    public UserState(Context context, int userId, Object lock) {
+        mContext = context;
+        mUserId = userId;
+        mLock = lock;
+        mSpooler = new RemotePrintSpooler(context, userId, this);
+        synchronized (mLock) {
+            enableSystemPrintServicesOnFirstBootLocked();
+        }
+    }
+
+    @Override
+    public void onPrintJobQueued(PrintJobInfo printJob) {
+        final RemotePrintService service;
+        synchronized (mLock) {
+            throwIfDestroyedLocked();
+            ComponentName printServiceName = printJob.getPrinterId().getServiceName();
+            service = mActiveServices.get(printServiceName);
+        }
+        if (service != null) {
+            service.onPrintJobQueued(printJob);
+        }
+    }
+
+    @Override
+    public void onAllPrintJobsForServiceHandled(ComponentName printService) {
+        final RemotePrintService service;
+        synchronized (mLock) {
+            throwIfDestroyedLocked();
+            service = mActiveServices.get(printService);
+        }
+        if (service != null) {
+            service.onAllPrintJobsHandled();
+        }
+    }
+
+    public List<PrintServiceInfo> getEnabledPrintServices() {
+        synchronized (mLock) {
+            List<PrintServiceInfo> enabledServices = null;
+            final int installedServiceCount = mInstalledServices.size();
+            for (int i = 0; i < installedServiceCount; i++) {
+                PrintServiceInfo installedService = mInstalledServices.get(i);
+                ComponentName componentName = new ComponentName(
+                        installedService.getResolveInfo().serviceInfo.packageName,
+                        installedService.getResolveInfo().serviceInfo.name);
+                if (mActiveServices.containsKey(componentName)) {
+                    if (enabledServices == null) {
+                        enabledServices = new ArrayList<PrintServiceInfo>();
+                    }
+                    enabledServices.add(installedService);
+                }
+            }
+            return enabledServices;
+        }
+    }
+
+    public void createPrinterDiscoverySession(IPrinterDiscoveryObserver observer) {
+        synchronized (mLock) {
+            throwIfDestroyedLocked();
+            if (mActiveServices.isEmpty()) {
+                return;
+            }
+            if (mPrinterDiscoverySession == null) {
+                // If we do not have a session, tell all service to create one.
+                mPrinterDiscoverySession = new PrinterDiscoverySessionMediator(mContext) {
+                    @Override
+                    public void onDestroyed() {
+                        mPrinterDiscoverySession = null;
+                    }
+                };
+                // Add the observer to the brand new session.
+                mPrinterDiscoverySession.addObserverLocked(observer);
+            } else {
+                // If services have created session, just add the observer.
+                mPrinterDiscoverySession.addObserverLocked(observer);
+            }
+        }
+    }
+
+    public void destroyPrinterDiscoverySession(IPrinterDiscoveryObserver observer) {
+        synchronized (mLock) {
+            // Already destroyed - nothing to do.
+            if (mPrinterDiscoverySession == null) {
+                return;
+            }
+            // Remove this observer.
+            mPrinterDiscoverySession.removeObserverLocked(observer);
+        }
+    }
+
+    public void startPrinterDiscovery(IPrinterDiscoveryObserver observer,
+            List<PrinterId> printerIds) {
+        synchronized (mLock) {
+            throwIfDestroyedLocked();
+            // No services - nothing to do.
+            if (mActiveServices.isEmpty()) {
+                return;
+            }
+            // No session - nothing to do.
+            if (mPrinterDiscoverySession == null) {
+                return;
+            }
+            // Kick of discovery.
+            mPrinterDiscoverySession.startPrinterDiscoveryLocked(observer,
+                    printerIds);
+        }
+    }
+
+    public void stopPrinterDiscovery(IPrinterDiscoveryObserver observer) {
+        synchronized (mLock) {
+            throwIfDestroyedLocked();
+            // No services - nothing to do.
+            if (mActiveServices.isEmpty()) {
+                return;
+            }
+            // No session - nothing to do.
+            if (mPrinterDiscoverySession == null) {
+                return;
+            }
+            // Kick of discovery.
+            mPrinterDiscoverySession.stopPrinterDiscoveryLocked(observer);
+        }
+    }
+
+    public void validatePrinters(List<PrinterId> printerIds) {
+        synchronized (mLock) {
+            throwIfDestroyedLocked();
+            // No services - nothing to do.
+            if (mActiveServices.isEmpty()) {
+                return;
+            }
+            // No session - nothing to do.
+            if (mPrinterDiscoverySession == null) {
+                return;
+            }
+            // Request an updated.
+            mPrinterDiscoverySession.validatePrintersLocked(printerIds);
+        }
+    }
+
+    public void startPrinterStateTracking(PrinterId printerId) {
+        synchronized (mLock) {
+            throwIfDestroyedLocked();
+            // No services - nothing to do.
+            if (mActiveServices.isEmpty()) {
+                return;
+            }
+            // No session - nothing to do.
+            if (mPrinterDiscoverySession == null) {
+                return;
+            }
+            // Request start tracking the printer.
+            mPrinterDiscoverySession.startPrinterStateTrackingLocked(printerId);
+        }
+    }
+
+    public void stopPrinterStateTracking(PrinterId printerId) {
+        synchronized (mLock) {
+            throwIfDestroyedLocked();
+            // No services - nothing to do.
+            if (mActiveServices.isEmpty()) {
+                return;
+            }
+            // No session - nothing to do.
+            if (mPrinterDiscoverySession == null) {
+                return;
+            }
+            // Request stop tracking the printer.
+            mPrinterDiscoverySession.stopPrinterStateTrackingLocked(printerId);
+        }
+    }
+
+    @Override
+    public void onPrintersAdded(List<PrinterInfo> printers) {
+        synchronized (mLock) {
+            throwIfDestroyedLocked();
+            // No services - nothing to do.
+            if (mActiveServices.isEmpty()) {
+                return;
+            }
+            // No session - nothing to do.
+            if (mPrinterDiscoverySession == null) {
+                return;
+            }
+            mPrinterDiscoverySession.onPrintersAddedLocked(printers);
+        }
+    }
+
+    @Override
+    public void onPrintersRemoved(List<PrinterId> printerIds) {
+        synchronized (mLock) {
+            throwIfDestroyedLocked();
+            // No services - nothing to do.
+            if (mActiveServices.isEmpty()) {
+                return;
+            }
+            // No session - nothing to do.
+            if (mPrinterDiscoverySession == null) {
+                return;
+            }
+            mPrinterDiscoverySession.onPrintersRemovedLocked(printerIds);
+        }
+    }
+
+    @Override
+    public void onServiceDied(RemotePrintService service) {
+        synchronized (mLock) {
+            throwIfDestroyedLocked();
+            // No services - nothing to do.
+            if (mActiveServices.isEmpty()) {
+                return;
+            }
+            // Fail all print jobs.
+            failActivePrintJobsForService(service.getComponentName());
+            service.onAllPrintJobsHandled();
+            // No session - nothing to do.
+            if (mPrinterDiscoverySession == null) {
+                return;
+            }
+            mPrinterDiscoverySession.onServiceDiedLocked(service);
+        }
+    }
+
+    public void updateIfNeededLocked() {
+        throwIfDestroyedLocked();
+        if (readConfigurationLocked()) {
+            onConfigurationChangedLocked();
+        }
+    }
+
+    public RemotePrintSpooler getSpoolerLocked() {
+        throwIfDestroyedLocked();
+        return mSpooler;
+    }
+
+    public Map<ComponentName, RemotePrintService> getActiveServicesLocked() {
+        synchronized(mLock) {
+            throwIfDestroyedLocked();
+            return mActiveServices;
+        }
+    }
+
+    public Set<ComponentName> getEnabledServices() {
+        synchronized(mLock) {
+            throwIfDestroyedLocked();
+            return mEnabledServices;
+        }
+    }
+
+    public void destroyLocked() {
+        throwIfDestroyedLocked();
+        mSpooler.destroy();
+        for (RemotePrintService service : mActiveServices.values()) {
+            service.destroy();
+        }
+        mActiveServices.clear();
+        mInstalledServices.clear();
+        mEnabledServices.clear();
+        if (mPrinterDiscoverySession != null) {
+            mPrinterDiscoverySession.destroyLocked();
+            mPrinterDiscoverySession = null;
+        }
+        mDestroyed = true;
+    }
+
+    public void dump(FileDescriptor fd, PrintWriter pw, String prefix) {
+        pw.append(prefix).append("user state ").append(String.valueOf(mUserId)).append(":");
+        pw.println();
+
+        String tab = "  ";
+
+        pw.append(prefix).append(tab).append("installed services:").println();
+        final int installedServiceCount = mInstalledServices.size();
+        for (int i = 0; i < installedServiceCount; i++) {
+            PrintServiceInfo installedService = mInstalledServices.get(i);
+            String installedServicePrefix = prefix + tab + tab;
+            pw.append(installedServicePrefix).append("service:").println();
+            ResolveInfo resolveInfo = installedService.getResolveInfo();
+            ComponentName componentName = new ComponentName(
+                    resolveInfo.serviceInfo.packageName,
+                    resolveInfo.serviceInfo.name);
+            pw.append(installedServicePrefix).append(tab).append("componentName=")
+                    .append(componentName.flattenToString()).println();
+            pw.append(installedServicePrefix).append(tab).append("settingsActivity=")
+                    .append(installedService.getSettingsActivityName()).println();
+            pw.append(installedServicePrefix).append(tab).append("addPrintersActivity=")
+                    .append(installedService.getAddPrintersActivityName()).println();
+        }
+
+        pw.append(prefix).append(tab).append("enabled services:").println();
+        for (ComponentName enabledService : mEnabledServices) {
+            String enabledServicePrefix = prefix + tab + tab;
+            pw.append(enabledServicePrefix).append("service:").println();
+            pw.append(enabledServicePrefix).append(tab).append("componentName=")
+                    .append(enabledService.flattenToString());
+            pw.println();
+        }
+
+        pw.append(prefix).append(tab).append("active services:").println();
+        final int activeServiceCount = mActiveServices.size();
+        for (int i = 0; i < activeServiceCount; i++) {
+            RemotePrintService activeService = mActiveServices.valueAt(i);
+            activeService.dump(pw, prefix + tab + tab);
+            pw.println();
+        }
+
+        pw.append(prefix).append(tab).append("discovery mediator:").println();
+        if (mPrinterDiscoverySession != null) {
+            mPrinterDiscoverySession.dump(pw, prefix + tab + tab);
+        }
+
+        pw.append(prefix).append(tab).append("print spooler:").println();
+        mSpooler.dump(fd, pw, prefix + tab + tab);
+        pw.println();
+    }
+
+    private boolean readConfigurationLocked() {
+        boolean somethingChanged = false;
+        somethingChanged |= readInstalledPrintServicesLocked();
+        somethingChanged |= readEnabledPrintServicesLocked();
+        return somethingChanged;
+    }
+
+    private boolean readInstalledPrintServicesLocked() {
+        Set<PrintServiceInfo> tempPrintServices = new HashSet<PrintServiceInfo>();
+
+        List<ResolveInfo> installedServices = mContext.getPackageManager()
+                .queryIntentServicesAsUser(mQueryIntent, PackageManager.GET_SERVICES
+                        | PackageManager.GET_META_DATA, mUserId);
+
+        final int installedCount = installedServices.size();
+        for (int i = 0, count = installedCount; i < count; i++) {
+            ResolveInfo installedService = installedServices.get(i);
+            if (!android.Manifest.permission.BIND_PRINT_SERVICE.equals(
+                    installedService.serviceInfo.permission)) {
+                ComponentName serviceName = new ComponentName(
+                        installedService.serviceInfo.packageName,
+                        installedService.serviceInfo.name);
+                Slog.w(LOG_TAG, "Skipping print service "
+                        + serviceName.flattenToShortString()
+                        + " since it does not require permission "
+                        + android.Manifest.permission.BIND_PRINT_SERVICE);
+                continue;
+            }
+            tempPrintServices.add(PrintServiceInfo.create(installedService, mContext));
+        }
+
+        if (!tempPrintServices.equals(mInstalledServices)) {
+            mInstalledServices.clear();
+            mInstalledServices.addAll(tempPrintServices);
+            return true;
+        }
+
+        return false;
+    }
+
+    private boolean readEnabledPrintServicesLocked() {
+        Set<ComponentName> tempEnabledServiceNameSet = new HashSet<ComponentName>();
+        readPrintServicesFromSettingLocked(Settings.Secure.ENABLED_PRINT_SERVICES,
+                tempEnabledServiceNameSet);
+        if (!tempEnabledServiceNameSet.equals(mEnabledServices)) {
+            mEnabledServices.clear();
+            mEnabledServices.addAll(tempEnabledServiceNameSet);
+            return true;
+        }
+        return false;
+    }
+
+    private void readPrintServicesFromSettingLocked(String setting,
+            Set<ComponentName> outServiceNames) {
+        String settingValue = Settings.Secure.getStringForUser(mContext.getContentResolver(),
+                setting, mUserId);
+        if (!TextUtils.isEmpty(settingValue)) {
+            TextUtils.SimpleStringSplitter splitter = mStringColonSplitter;
+            splitter.setString(settingValue);
+            while (splitter.hasNext()) {
+                String string = splitter.next();
+                if (TextUtils.isEmpty(string)) {
+                    continue;
+                }
+                ComponentName componentName = ComponentName.unflattenFromString(string);
+                if (componentName != null) {
+                    outServiceNames.add(componentName);
+                }
+            }
+        }
+    }
+
+    private void enableSystemPrintServicesOnFirstBootLocked() {
+        // Load enabled and installed services.
+        readEnabledPrintServicesLocked();
+        readInstalledPrintServicesLocked();
+
+        // Load the system services once enabled on first boot.
+        Set<ComponentName> enabledOnFirstBoot = new HashSet<ComponentName>();
+        readPrintServicesFromSettingLocked(
+                Settings.Secure.ENABLED_ON_FIRST_BOOT_SYSTEM_PRINT_SERVICES,
+                enabledOnFirstBoot);
+
+        StringBuilder builder = new StringBuilder();
+
+        final int serviceCount = mInstalledServices.size();
+        for (int i = 0; i < serviceCount; i++) {
+            ServiceInfo serviceInfo = mInstalledServices.get(i).getResolveInfo().serviceInfo;
+            // Enable system print services if we never did that and are not enabled.
+            if ((serviceInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+                ComponentName serviceName = new ComponentName(
+                        serviceInfo.packageName, serviceInfo.name);
+                if (!mEnabledServices.contains(serviceName)
+                        && !enabledOnFirstBoot.contains(serviceName)) {
+                    if (builder.length() > 0) {
+                        builder.append(":");
+                    }
+                    builder.append(serviceName.flattenToString());
+                }
+            }
+        }
+
+        // Nothing to be enabled - done.
+        if (builder.length() <= 0) {
+            return;
+        }
+
+        String servicesToEnable = builder.toString();
+
+        // Update the enabled services setting.
+        String enabledServices = Settings.Secure.getStringForUser(
+                mContext.getContentResolver(), Settings.Secure.ENABLED_PRINT_SERVICES, mUserId);
+        if (TextUtils.isEmpty(enabledServices)) {
+            enabledServices = servicesToEnable;
+        } else {
+            enabledServices = enabledServices + ":" + servicesToEnable;
+        }
+        Settings.Secure.putStringForUser(mContext.getContentResolver(),
+                Settings.Secure.ENABLED_PRINT_SERVICES, enabledServices, mUserId);
+
+        // Update the enabled on first boot services setting.
+        String enabledOnFirstBootServices = Settings.Secure.getStringForUser(
+                mContext.getContentResolver(),
+                Settings.Secure.ENABLED_ON_FIRST_BOOT_SYSTEM_PRINT_SERVICES, mUserId);
+        if (TextUtils.isEmpty(enabledOnFirstBootServices)) {
+            enabledOnFirstBootServices = servicesToEnable;
+        } else {
+            enabledOnFirstBootServices = enabledOnFirstBootServices + ":" + enabledServices;
+        }
+        Settings.Secure.putStringForUser(mContext.getContentResolver(),
+                Settings.Secure.ENABLED_ON_FIRST_BOOT_SYSTEM_PRINT_SERVICES,
+                enabledOnFirstBootServices, mUserId);
+    }
+
+    private void onConfigurationChangedLocked() {
+        final int installedCount = mInstalledServices.size();
+        for (int i = 0; i < installedCount; i++) {
+            ResolveInfo resolveInfo = mInstalledServices.get(i).getResolveInfo();
+            ComponentName serviceName = new ComponentName(resolveInfo.serviceInfo.packageName,
+                    resolveInfo.serviceInfo.name);
+            if (mEnabledServices.contains(serviceName)) {
+                if (!mActiveServices.containsKey(serviceName)) {
+                    RemotePrintService service = new RemotePrintService(
+                            mContext, serviceName, mUserId, mSpooler, this);
+                    addServiceLocked(service);
+                }
+            } else {
+                RemotePrintService service = mActiveServices.remove(serviceName);
+                if (service != null) {
+                    removeServiceLocked(service);
+                }
+            }
+        }
+    }
+
+    private void addServiceLocked(RemotePrintService service) {
+        mActiveServices.put(service.getComponentName(), service);
+        if (mPrinterDiscoverySession != null) {
+            mPrinterDiscoverySession.onServiceAddedLocked(service);
+        }
+    }
+
+    private void removeServiceLocked(RemotePrintService service) {
+        // Fail all print jobs.
+        failActivePrintJobsForService(service.getComponentName());
+        // If discovery is in progress, tear down the service.
+        if (mPrinterDiscoverySession != null) {
+            mPrinterDiscoverySession.onServiceRemovedLocked(service);
+        } else {
+            // Otherwise, just destroy it.
+            service.destroy();
+        }
+    }
+
+    private void failActivePrintJobsForService(final ComponentName serviceName) {
+        // Makes sure all active print jobs are failed since the service
+        // just died. Do this off the main thread since we do to allow
+        // calls into the spooler on the main thread.
+        if (Looper.getMainLooper().isCurrentThread()) {
+            new AsyncTask<Void, Void, Void>() {
+                @Override
+                protected Void doInBackground(Void... params) {
+                    failActivePrintJobsForServiceInternal(serviceName);
+                    return null;
+                }
+            }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
+        } else {
+            failActivePrintJobsForServiceInternal(serviceName);
+        }
+    }
+
+    private void failActivePrintJobsForServiceInternal(ComponentName serviceName) {
+        List<PrintJobInfo> printJobs = mSpooler.getPrintJobInfos(serviceName,
+                PrintJobInfo.STATE_ANY_ACTIVE, PrintManager.APP_ID_ANY);
+        if (printJobs == null) {
+            return;
+        }
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            final int printJobCount = printJobs.size();
+            for (int i = 0; i < printJobCount; i++) {
+                PrintJobInfo printJob = printJobs.get(i);
+                mSpooler.setPrintJobState(printJob.getId(), PrintJobInfo.STATE_FAILED,
+                        mContext.getString(R.string.reason_unknown));
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    private void throwIfDestroyedLocked() {
+        if (mDestroyed) {
+            throw new IllegalStateException("Cannot interact with a destroyed instance.");
+        }
+    }
+
+    private class PrinterDiscoverySessionMediator {
+        private final ArrayMap<PrinterId, PrinterInfo> mPrinters =
+                new ArrayMap<PrinterId, PrinterInfo>();
+
+        private final RemoteCallbackList<IPrinterDiscoveryObserver> mDiscoveryObservers =
+                new RemoteCallbackList<IPrinterDiscoveryObserver>() {
+            @Override
+            public void onCallbackDied(IPrinterDiscoveryObserver observer) {
+                synchronized (mLock) {
+                    stopPrinterDiscoveryLocked(observer);
+                    removeObserverLocked(observer);
+                }
+            }
+        };
+
+        private final List<IBinder> mStartedPrinterDiscoveryTokens = new ArrayList<IBinder>();
+
+        private final List<PrinterId> mStateTrackedPrinters = new ArrayList<PrinterId>();
+
+        private final Handler mHandler;
+
+        private boolean mIsDestroyed;
+
+        public PrinterDiscoverySessionMediator(Context context) {
+            mHandler = new SessionHandler(context.getMainLooper());
+            // Kick off the session creation.
+            List<RemotePrintService> services = new ArrayList<RemotePrintService>(
+                    mActiveServices.values());
+            mHandler.obtainMessage(SessionHandler
+                    .MSG_DISPATCH_CREATE_PRINTER_DISCOVERY_SESSION, services)
+                    .sendToTarget();
+        }
+
+        public void addObserverLocked(IPrinterDiscoveryObserver observer) {
+            // Add the observer.
+            mDiscoveryObservers.register(observer);
+
+            // Bring the added observer up to speed with the printers.
+            if (!mPrinters.isEmpty()) {
+                List<PrinterInfo> printers = new ArrayList<PrinterInfo>(mPrinters.values());
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = observer;
+                args.arg2 = printers;
+                mHandler.obtainMessage(SessionHandler.MSG_PRINTERS_ADDED,
+                        args).sendToTarget();
+            }
+        }
+
+        public void removeObserverLocked(IPrinterDiscoveryObserver observer) {
+            // Remove the observer.
+            mDiscoveryObservers.unregister(observer);
+            // No one else observing - then kill it.
+            if (mDiscoveryObservers.getRegisteredCallbackCount() == 0) {
+                destroyLocked();
+            }
+        }
+
+        public final void startPrinterDiscoveryLocked(IPrinterDiscoveryObserver observer,
+                List<PrinterId> priorityList) {
+            if (mIsDestroyed) {
+                Log.w(LOG_TAG, "Not starting dicovery - session destroyed");
+                return;
+            }
+
+            final boolean discoveryStarted = !mStartedPrinterDiscoveryTokens.isEmpty();
+
+            // Remember we got a start request to match with an end.
+            mStartedPrinterDiscoveryTokens.add(observer.asBinder());
+
+            // If printer discovery is ongoing and the start request has a list
+            // of printer to be checked, then we just request validating them.
+            if (discoveryStarted && priorityList != null && !priorityList.isEmpty()) {
+                validatePrinters(priorityList);
+                return;
+            }
+
+            // The service are already performing discovery - nothing to do.
+            if (mStartedPrinterDiscoveryTokens.size() > 1) {
+                return;
+            }
+
+            List<RemotePrintService> services = new ArrayList<RemotePrintService>(
+                    mActiveServices.values());
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = services;
+            args.arg2 = priorityList;
+            mHandler.obtainMessage(SessionHandler
+                    .MSG_DISPATCH_START_PRINTER_DISCOVERY, args)
+                    .sendToTarget();
+        }
+
+        public final void stopPrinterDiscoveryLocked(IPrinterDiscoveryObserver observer) {
+            if (mIsDestroyed) {
+                Log.w(LOG_TAG, "Not stopping dicovery - session destroyed");
+                return;
+            }
+            // This one did not make an active discovery request - nothing to do.
+            if (!mStartedPrinterDiscoveryTokens.remove(observer.asBinder())) {
+                return;
+            }
+            // There are other interested observers - do not stop discovery.
+            if (!mStartedPrinterDiscoveryTokens.isEmpty()) {
+                return;
+            }
+            List<RemotePrintService> services = new ArrayList<RemotePrintService>(
+                    mActiveServices.values());
+            mHandler.obtainMessage(SessionHandler
+                    .MSG_DISPATCH_STOP_PRINTER_DISCOVERY, services)
+                    .sendToTarget();
+        }
+
+        public void validatePrintersLocked(List<PrinterId> printerIds) {
+            if (mIsDestroyed) {
+                Log.w(LOG_TAG, "Not validating pritners - session destroyed");
+                return;
+            }
+
+            List<PrinterId> remainingList = new ArrayList<PrinterId>(printerIds);
+            while (!remainingList.isEmpty()) {
+                Iterator<PrinterId> iterator = remainingList.iterator();
+                // Gather the printers per service and request a validation.
+                List<PrinterId> updateList = new ArrayList<PrinterId>();
+                ComponentName serviceName = null;
+                while (iterator.hasNext()) {
+                    PrinterId printerId = iterator.next();
+                    if (updateList.isEmpty()) {
+                        updateList.add(printerId);
+                        serviceName = printerId.getServiceName();
+                        iterator.remove();
+                    } else if (printerId.getServiceName().equals(serviceName)) {
+                        updateList.add(printerId);
+                        iterator.remove();
+                    }
+                }
+                // Schedule a notification of the service.
+                RemotePrintService service = mActiveServices.get(serviceName);
+                if (service != null) {
+                    SomeArgs args = SomeArgs.obtain();
+                    args.arg1 = service;
+                    args.arg2 = updateList;
+                    mHandler.obtainMessage(SessionHandler
+                            .MSG_VALIDATE_PRINTERS, args)
+                            .sendToTarget();
+                }
+            }
+        }
+
+        public final void startPrinterStateTrackingLocked(PrinterId printerId) {
+            if (mIsDestroyed) {
+                Log.w(LOG_TAG, "Not starting printer state tracking - session destroyed");
+                return;
+            }
+            // If printer discovery is not started - nothing to do.
+            if (mStartedPrinterDiscoveryTokens.isEmpty()) {
+                return;
+            }
+            final boolean containedPrinterId = mStateTrackedPrinters.contains(printerId);
+            // Keep track of the number of requests to track this one.
+            mStateTrackedPrinters.add(printerId);
+            // If we were tracking this printer - nothing to do.
+            if (containedPrinterId) {
+                return;
+            }
+            // No service - nothing to do.
+            RemotePrintService service = mActiveServices.get(printerId.getServiceName());
+            if (service == null) {
+                return;
+            }
+            // Ask the service to start tracking.
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = service;
+            args.arg2 = printerId;
+            mHandler.obtainMessage(SessionHandler
+                    .MSG_START_PRINTER_STATE_TRACKING, args)
+                    .sendToTarget();
+        }
+
+        public final void stopPrinterStateTrackingLocked(PrinterId printerId) {
+            if (mIsDestroyed) {
+                Log.w(LOG_TAG, "Not stopping printer state tracking - session destroyed");
+                return;
+            }
+            // If printer discovery is not started - nothing to do.
+            if (mStartedPrinterDiscoveryTokens.isEmpty()) {
+                return;
+            }
+            // If we did not track this printer - nothing to do.
+            if (!mStateTrackedPrinters.remove(printerId)) {
+                return;
+            }
+            // No service - nothing to do.
+            RemotePrintService service = mActiveServices.get(printerId.getServiceName());
+            if (service == null) {
+                return;
+            }
+            // Ask the service to start tracking.
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = service;
+            args.arg2 = printerId;
+            mHandler.obtainMessage(SessionHandler
+                    .MSG_STOP_PRINTER_STATE_TRACKING, args)
+                    .sendToTarget();
+        }
+
+        public void onDestroyed() {
+            /* do nothing */
+        }
+
+        public void destroyLocked() {
+            if (mIsDestroyed) {
+                Log.w(LOG_TAG, "Not destroying - session destroyed");
+                return;
+            }
+            // Make sure printer tracking is stopped.
+            final int printerCount = mStateTrackedPrinters.size();
+            for (int i = 0; i < printerCount; i++) {
+                PrinterId printerId = mStateTrackedPrinters.get(i);
+                stopPrinterStateTracking(printerId);
+            }
+            // Make sure discovery is stopped.
+            final int observerCount = mStartedPrinterDiscoveryTokens.size();
+            for (int i = 0; i < observerCount; i++) {
+                IBinder token = mStartedPrinterDiscoveryTokens.get(i);
+                stopPrinterDiscoveryLocked(IPrinterDiscoveryObserver.Stub.asInterface(token));
+            }
+            // Tell the services we are done.
+            List<RemotePrintService> services = new ArrayList<RemotePrintService>(
+                    mActiveServices.values());
+            mHandler.obtainMessage(SessionHandler
+                    .MSG_DISPATCH_DESTROY_PRINTER_DISCOVERY_SESSION, services)
+                    .sendToTarget();
+        }
+
+        public void onPrintersAddedLocked(List<PrinterInfo> printers) {
+            if (DEBUG) {
+                Log.i(LOG_TAG, "onPrintersAddedLocked()");
+            }
+            if (mIsDestroyed) {
+                Log.w(LOG_TAG, "Not adding printers - session destroyed");
+                return;
+            }
+            List<PrinterInfo> addedPrinters = null;
+            final int addedPrinterCount = printers.size();
+            for (int i = 0; i < addedPrinterCount; i++) {
+                PrinterInfo printer = printers.get(i);
+                PrinterInfo oldPrinter = mPrinters.put(printer.getId(), printer);
+                if (oldPrinter == null || !oldPrinter.equals(printer)) {
+                    if (addedPrinters == null) {
+                        addedPrinters = new ArrayList<PrinterInfo>();
+                    }
+                    addedPrinters.add(printer);
+                }
+            }
+            if (addedPrinters != null) {
+                mHandler.obtainMessage(SessionHandler.MSG_DISPATCH_PRINTERS_ADDED,
+                        addedPrinters).sendToTarget();
+            }
+        }
+
+        public void onPrintersRemovedLocked(List<PrinterId> printerIds) {
+            if (DEBUG) {
+                Log.i(LOG_TAG, "onPrintersRemovedLocked()");
+            }
+            if (mIsDestroyed) {
+                Log.w(LOG_TAG, "Not removing printers - session destroyed");
+                return;
+            }
+            List<PrinterId> removedPrinterIds = null;
+            final int removedPrinterCount = printerIds.size();
+            for (int i = 0; i < removedPrinterCount; i++) {
+                PrinterId removedPrinterId = printerIds.get(i);
+                if (mPrinters.remove(removedPrinterId) != null) {
+                    if (removedPrinterIds == null) {
+                        removedPrinterIds = new ArrayList<PrinterId>();
+                    }
+                    removedPrinterIds.add(removedPrinterId);
+                }
+            }
+            if (removedPrinterIds != null) {
+                mHandler.obtainMessage(SessionHandler.MSG_DISPATCH_PRINTERS_REMOVED,
+                        removedPrinterIds).sendToTarget();
+            }
+        }
+
+        public void onServiceRemovedLocked(RemotePrintService service) {
+            if (mIsDestroyed) {
+                Log.w(LOG_TAG, "Not updating removed service - session destroyed");
+                return;
+            }
+            // Remove the reported and tracked printers for that service.
+            ComponentName serviceName = service.getComponentName();
+            removePrintersForServiceLocked(serviceName);
+            service.destroy();
+        }
+
+        public void onServiceDiedLocked(RemotePrintService service) {
+            // Remove the reported by that service.
+            removePrintersForServiceLocked(service.getComponentName());
+        }
+
+        public void onServiceAddedLocked(RemotePrintService service) {
+            if (mIsDestroyed) {
+                Log.w(LOG_TAG, "Not updating added service - session destroyed");
+                return;
+            }
+            // Tell the service to create a session.
+            mHandler.obtainMessage(
+                    SessionHandler.MSG_CREATE_PRINTER_DISCOVERY_SESSION,
+                    service).sendToTarget();
+            // If there are some observers that started discovery - tell the service.
+            if (mDiscoveryObservers.getRegisteredCallbackCount() > 0) {
+                mHandler.obtainMessage(
+                        SessionHandler.MSG_START_PRINTER_DISCOVERY,
+                        service).sendToTarget();
+            }
+        }
+
+        public void dump(PrintWriter pw, String prefix) {
+            pw.append(prefix).append("destroyed=")
+                    .append(String.valueOf(mDestroyed)).println();
+
+            pw.append(prefix).append("printDiscoveryInProgress=")
+                    .append(String.valueOf(!mStartedPrinterDiscoveryTokens.isEmpty())).println();
+
+            String tab = "  ";
+
+            pw.append(prefix).append(tab).append("printer discovery observers:").println();
+            final int observerCount = mDiscoveryObservers.beginBroadcast();
+            for (int i = 0; i < observerCount; i++) {
+                IPrinterDiscoveryObserver observer = mDiscoveryObservers.getBroadcastItem(i);
+                pw.append(prefix).append(prefix).append(observer.toString());
+                pw.println();
+            }
+            mDiscoveryObservers.finishBroadcast();
+
+            pw.append(prefix).append(tab).append("start discovery requests:").println();
+            final int tokenCount = this.mStartedPrinterDiscoveryTokens.size();
+            for (int i = 0; i < tokenCount; i++) {
+                IBinder token = mStartedPrinterDiscoveryTokens.get(i);
+                pw.append(prefix).append(tab).append(tab).append(token.toString()).println();
+            }
+
+            pw.append(prefix).append(tab).append("tracked printer requests:").println();
+            final int trackedPrinters = mStateTrackedPrinters.size();
+            for (int i = 0; i < trackedPrinters; i++) {
+                PrinterId printer = mStateTrackedPrinters.get(i);
+                pw.append(prefix).append(tab).append(tab).append(printer.toString()).println();
+            }
+
+            pw.append(prefix).append(tab).append("printers:").println();
+            final int pritnerCount = mPrinters.size();
+            for (int i = 0; i < pritnerCount; i++) {
+                PrinterInfo printer = mPrinters.valueAt(i);
+                pw.append(prefix).append(tab).append(tab).append(
+                        printer.toString()).println();
+            }
+        }
+
+        private void removePrintersForServiceLocked(ComponentName serviceName) {
+            // No printers - nothing to do.
+            if (mPrinters.isEmpty()) {
+                return;
+            }
+            // Remove the printers for that service.
+            List<PrinterId> removedPrinterIds = null;
+            final int printerCount = mPrinters.size();
+            for (int i = 0; i < printerCount; i++) {
+                PrinterId printerId = mPrinters.keyAt(i);
+                if (printerId.getServiceName().equals(serviceName)) {
+                    if (removedPrinterIds == null) {
+                        removedPrinterIds = new ArrayList<PrinterId>();
+                    }
+                    removedPrinterIds.add(printerId);
+                }
+            }
+            if (removedPrinterIds != null) {
+                final int removedPrinterCount = removedPrinterIds.size();
+                for (int i = 0; i < removedPrinterCount; i++) {
+                    mPrinters.remove(removedPrinterIds.get(i));
+                }
+                mHandler.obtainMessage(
+                        SessionHandler.MSG_DISPATCH_PRINTERS_REMOVED,
+                        removedPrinterIds).sendToTarget();
+            }
+        }
+
+        private void handleDispatchPrintersAdded(List<PrinterInfo> addedPrinters) {
+            final int observerCount = mDiscoveryObservers.beginBroadcast();
+            for (int i = 0; i < observerCount; i++) {
+                IPrinterDiscoveryObserver observer = mDiscoveryObservers.getBroadcastItem(i);
+                handlePrintersAdded(observer, addedPrinters);
+            }
+            mDiscoveryObservers.finishBroadcast();
+        }
+
+        private void handleDispatchPrintersRemoved(List<PrinterId> removedPrinterIds) {
+            final int observerCount = mDiscoveryObservers.beginBroadcast();
+            for (int i = 0; i < observerCount; i++) {
+                IPrinterDiscoveryObserver observer = mDiscoveryObservers.getBroadcastItem(i);
+                handlePrintersRemoved(observer, removedPrinterIds);
+            }
+            mDiscoveryObservers.finishBroadcast();
+        }
+
+        private void handleDispatchCreatePrinterDiscoverySession(
+                List<RemotePrintService> services) {
+            final int serviceCount = services.size();
+            for (int i = 0; i < serviceCount; i++) {
+                RemotePrintService service = services.get(i);
+                service.createPrinterDiscoverySession();
+            }
+        }
+
+        private void handleDispatchDestroyPrinterDiscoverySession(
+                List<RemotePrintService> services) {
+            final int serviceCount = services.size();
+            for (int i = 0; i < serviceCount; i++) {
+                RemotePrintService service = services.get(i);
+                service.destroyPrinterDiscoverySession();
+            }
+            onDestroyed();
+        }
+
+        private void handleDispatchStartPrinterDiscovery(
+                List<RemotePrintService> services, List<PrinterId> printerIds) {
+            final int serviceCount = services.size();
+            for (int i = 0; i < serviceCount; i++) {
+                RemotePrintService service = services.get(i);
+                service.startPrinterDiscovery(printerIds);
+            }
+        }
+
+        private void handleDispatchStopPrinterDiscovery(List<RemotePrintService> services) {
+            final int serviceCount = services.size();
+            for (int i = 0; i < serviceCount; i++) {
+                RemotePrintService service = services.get(i);
+                service.stopPrinterDiscovery();
+            }
+        }
+
+        private void handleValidatePrinters(RemotePrintService service,
+                List<PrinterId> printerIds) {
+            service.validatePrinters(printerIds);
+        }
+
+        private void handleStartPrinterStateTracking(RemotePrintService service,
+                PrinterId printerId) {
+            service.startPrinterStateTracking(printerId);
+        }
+
+        private void handleStopPrinterStateTracking(RemotePrintService service,
+                PrinterId printerId) {
+            service.stopPrinterStateTracking(printerId);
+        }
+
+        private void handlePrintersAdded(IPrinterDiscoveryObserver observer,
+            List<PrinterInfo> printers) {
+            try {
+                final int printerCount = printers.size();
+                if (printerCount <= MAX_ITEMS_PER_CALLBACK) {
+                    observer.onPrintersAdded(printers);
+                } else {
+                    // Send the added printers in chunks avoiding the binder transaction limit.
+                    final int transactionCount = (printerCount / MAX_ITEMS_PER_CALLBACK) + 1;
+                    for (int i = 0; i < transactionCount; i++) {
+                        final int start = i * MAX_ITEMS_PER_CALLBACK;
+                        final int end = Math.min(start + MAX_ITEMS_PER_CALLBACK, printerCount);
+                        List<PrinterInfo> subPrinters = printers.subList(start, end);
+                        observer.onPrintersAdded(subPrinters); 
+                    }
+                }
+            } catch (RemoteException re) {
+                Log.e(LOG_TAG, "Error sending added printers", re);
+            }
+        }
+
+        private void handlePrintersRemoved(IPrinterDiscoveryObserver observer,
+            List<PrinterId> printerIds) {
+            try {
+                final int printerCount = printerIds.size();
+                if (printerCount <= MAX_ITEMS_PER_CALLBACK) {
+                    observer.onPrintersRemoved(printerIds);
+                } else {
+                    // Send the added printers in chunks avoiding the binder transaction limit.
+                    final int transactionCount = (printerCount / MAX_ITEMS_PER_CALLBACK) + 1;
+                    for (int i = 0; i < transactionCount; i++) {
+                        final int start = i * MAX_ITEMS_PER_CALLBACK;
+                        final int end = Math.min(start + MAX_ITEMS_PER_CALLBACK, printerCount);
+                        List<PrinterId> subPrinterIds = printerIds.subList(start, end);
+                        observer.onPrintersRemoved(subPrinterIds);
+                    }
+               }
+            } catch (RemoteException re) {
+                Log.e(LOG_TAG, "Error sending added printers", re);
+            }
+        }
+
+        private final class SessionHandler extends Handler {
+            public static final int MSG_PRINTERS_ADDED = 1;
+            public static final int MSG_PRINTERS_REMOVED = 2;
+            public static final int MSG_DISPATCH_PRINTERS_ADDED = 3;
+            public static final int MSG_DISPATCH_PRINTERS_REMOVED = 4;
+
+            public static final int MSG_CREATE_PRINTER_DISCOVERY_SESSION = 5;
+            public static final int MSG_DESTROY_PRINTER_DISCOVERY_SESSION = 6;
+            public static final int MSG_START_PRINTER_DISCOVERY = 7;
+            public static final int MSG_STOP_PRINTER_DISCOVERY = 8;
+            public static final int MSG_DISPATCH_CREATE_PRINTER_DISCOVERY_SESSION = 9;
+            public static final int MSG_DISPATCH_DESTROY_PRINTER_DISCOVERY_SESSION = 10;
+            public static final int MSG_DISPATCH_START_PRINTER_DISCOVERY = 11;
+            public static final int MSG_DISPATCH_STOP_PRINTER_DISCOVERY = 12;
+            public static final int MSG_VALIDATE_PRINTERS = 13;
+            public static final int MSG_START_PRINTER_STATE_TRACKING = 14;
+            public static final int MSG_STOP_PRINTER_STATE_TRACKING = 15;
+            public static final int MSG_DESTROY_SERVICE = 16;
+
+            SessionHandler(Looper looper) {
+                super(looper, null, false);
+            }
+
+            @Override
+            @SuppressWarnings("unchecked")
+            public void handleMessage(Message message) {
+                switch (message.what) {
+                    case MSG_PRINTERS_ADDED: {
+                        SomeArgs args = (SomeArgs) message.obj;
+                        IPrinterDiscoveryObserver observer = (IPrinterDiscoveryObserver) args.arg1;
+                        List<PrinterInfo> addedPrinters = (List<PrinterInfo>) args.arg2;
+                        args.recycle();
+                        handlePrintersAdded(observer, addedPrinters);
+                    } break;
+
+                    case MSG_PRINTERS_REMOVED: {
+                        SomeArgs args = (SomeArgs) message.obj;
+                        IPrinterDiscoveryObserver observer = (IPrinterDiscoveryObserver) args.arg1;
+                        List<PrinterId> removedPrinterIds = (List<PrinterId>) args.arg2;
+                        args.recycle();
+                        handlePrintersRemoved(observer, removedPrinterIds);
+                    }
+
+                    case MSG_DISPATCH_PRINTERS_ADDED: {
+                        List<PrinterInfo> addedPrinters = (List<PrinterInfo>) message.obj;
+                        handleDispatchPrintersAdded(addedPrinters);
+                    } break;
+
+                    case MSG_DISPATCH_PRINTERS_REMOVED: {
+                        List<PrinterId> removedPrinterIds = (List<PrinterId>) message.obj;
+                        handleDispatchPrintersRemoved(removedPrinterIds);
+                    } break;
+
+                    case MSG_CREATE_PRINTER_DISCOVERY_SESSION: {
+                        RemotePrintService service = (RemotePrintService) message.obj;
+                        service.createPrinterDiscoverySession();
+                    } break;
+
+                    case MSG_DESTROY_PRINTER_DISCOVERY_SESSION: {
+                        RemotePrintService service = (RemotePrintService) message.obj;
+                        service.destroyPrinterDiscoverySession();
+                    } break;
+
+                    case MSG_START_PRINTER_DISCOVERY: {
+                        RemotePrintService service = (RemotePrintService) message.obj;
+                        service.startPrinterDiscovery(null);
+                    } break;
+
+                    case MSG_STOP_PRINTER_DISCOVERY: {
+                        RemotePrintService service = (RemotePrintService) message.obj;
+                        service.stopPrinterDiscovery();
+                    } break;
+
+                    case MSG_DISPATCH_CREATE_PRINTER_DISCOVERY_SESSION: {
+                        List<RemotePrintService> services = (List<RemotePrintService>) message.obj;
+                        handleDispatchCreatePrinterDiscoverySession(services);
+                    } break;
+
+                    case MSG_DISPATCH_DESTROY_PRINTER_DISCOVERY_SESSION: {
+                        List<RemotePrintService> services = (List<RemotePrintService>) message.obj;
+                        handleDispatchDestroyPrinterDiscoverySession(services);
+                    } break;
+
+                    case MSG_DISPATCH_START_PRINTER_DISCOVERY: {
+                        SomeArgs args = (SomeArgs) message.obj;
+                        List<RemotePrintService> services = (List<RemotePrintService>) args.arg1;
+                        List<PrinterId> printerIds = (List<PrinterId>) args.arg2;
+                        args.recycle();
+                        handleDispatchStartPrinterDiscovery(services, printerIds);
+                    } break;
+
+                    case MSG_DISPATCH_STOP_PRINTER_DISCOVERY: {
+                        List<RemotePrintService> services = (List<RemotePrintService>) message.obj;
+                        handleDispatchStopPrinterDiscovery(services);
+                    } break;
+
+                    case MSG_VALIDATE_PRINTERS: {
+                        SomeArgs args = (SomeArgs) message.obj;
+                        RemotePrintService service = (RemotePrintService) args.arg1;
+                        List<PrinterId> printerIds = (List<PrinterId>) args.arg2;
+                        args.recycle();
+                        handleValidatePrinters(service, printerIds);
+                    } break;
+
+                    case MSG_START_PRINTER_STATE_TRACKING: {
+                        SomeArgs args = (SomeArgs) message.obj;
+                        RemotePrintService service = (RemotePrintService) args.arg1;
+                        PrinterId printerId = (PrinterId) args.arg2;
+                        args.recycle();
+                        handleStartPrinterStateTracking(service, printerId);
+                    } break;
+
+                    case MSG_STOP_PRINTER_STATE_TRACKING: {
+                        SomeArgs args = (SomeArgs) message.obj;
+                        RemotePrintService service = (RemotePrintService) args.arg1;
+                        PrinterId printerId = (PrinterId) args.arg2;
+                        args.recycle();
+                        handleStopPrinterStateTracking(service, printerId);
+                    } break;
+
+                    case MSG_DESTROY_SERVICE: {
+                        RemotePrintService service = (RemotePrintService) message.obj;
+                        service.destroy();
+                    } break;
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/services/java/com/android/server/updates/IntentFirewallInstallReceiver.java b/services/java/com/android/server/updates/IntentFirewallInstallReceiver.java
index 9185903..0b54f92 100644
--- a/services/java/com/android/server/updates/IntentFirewallInstallReceiver.java
+++ b/services/java/com/android/server/updates/IntentFirewallInstallReceiver.java
@@ -21,7 +21,8 @@
 public class IntentFirewallInstallReceiver extends ConfigUpdateInstallReceiver {
 
     public IntentFirewallInstallReceiver() {
-        super(IntentFirewall.getRulesFile().getParent(), IntentFirewall.getRulesFile().getName(),
-                "metadata/", "version");
+        // TODO: should we dynamically generate a filename and store the name in metadata?
+        super(IntentFirewall.getRulesDir().getAbsolutePath(), "ifw.xml", "metadata/",
+                "gservices.version");
     }
 }
diff --git a/services/java/com/android/server/usb/UsbDebuggingManager.java b/services/java/com/android/server/usb/UsbDebuggingManager.java
index 93d3114..ce953a4 100644
--- a/services/java/com/android/server/usb/UsbDebuggingManager.java
+++ b/services/java/com/android/server/usb/UsbDebuggingManager.java
@@ -22,15 +22,14 @@
 import android.net.LocalSocket;
 import android.net.LocalSocketAddress;
 import android.os.Handler;
-import android.os.HandlerThread;
 import android.os.Environment;
 import android.os.FileUtils;
 import android.os.Looper;
 import android.os.Message;
-import android.os.Process;
 import android.os.SystemClock;
 import android.util.Slog;
 import android.util.Base64;
+import com.android.server.FgThread;
 
 import java.lang.Thread;
 import java.io.File;
@@ -54,7 +53,6 @@
 
     private final Context mContext;
     private final Handler mHandler;
-    private final HandlerThread mHandlerThread;
     private Thread mThread;
     private boolean mAdbEnabled = false;
     private String mFingerprints;
@@ -62,9 +60,7 @@
     private OutputStream mOutputStream = null;
 
     public UsbDebuggingManager(Context context) {
-        mHandlerThread = new HandlerThread("UsbDebuggingHandler");
-        mHandlerThread.start();
-        mHandler = new UsbDebuggingHandler(mHandlerThread.getLooper());
+        mHandler = new UsbDebuggingHandler(FgThread.get().getLooper());
         mContext = context;
     }
 
@@ -165,7 +161,7 @@
 
                     mAdbEnabled = true;
 
-                    mThread = new Thread(UsbDebuggingManager.this);
+                    mThread = new Thread(UsbDebuggingManager.this, TAG);
                     mThread.start();
 
                     break;
diff --git a/services/java/com/android/server/usb/UsbDeviceManager.java b/services/java/com/android/server/usb/UsbDeviceManager.java
index 87aa8cce..5a60de0 100644
--- a/services/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/java/com/android/server/usb/UsbDeviceManager.java
@@ -32,11 +32,9 @@
 import android.hardware.usb.UsbManager;
 import android.os.FileUtils;
 import android.os.Handler;
-import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.Message;
 import android.os.ParcelFileDescriptor;
-import android.os.Process;
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UEventObserver;
@@ -48,6 +46,7 @@
 import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.server.FgThread;
 
 import java.io.File;
 import java.io.FileDescriptor;
@@ -57,6 +56,7 @@
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Scanner;
 
@@ -158,11 +158,7 @@
 
         readOemUsbOverrideConfig();
 
-        // create a thread for our Handler
-        HandlerThread thread = new HandlerThread("UsbDeviceManager",
-                Process.THREAD_PRIORITY_BACKGROUND);
-        thread.start();
-        mHandler = new UsbHandler(thread.getLooper());
+        mHandler = new UsbHandler(FgThread.get().getLooper());
 
         if (nativeIsStartRequested()) {
             if (DEBUG) Slog.d(TAG, "accessory attached at boot");
@@ -245,7 +241,7 @@
         for (int i = 0; i < serialLength; i++) {
             address[i % (ETH_ALEN - 1) + 1] ^= (int)serial.charAt(i);
         }
-        String addrString = String.format("%02X:%02X:%02X:%02X:%02X:%02X",
+        String addrString = String.format(Locale.US, "%02X:%02X:%02X:%02X:%02X:%02X",
             address[0], address[1], address[2], address[3], address[4], address[5]);
         try {
             FileUtils.stringToFile(RNDIS_ETH_ADDR_PATH, addrString);
diff --git a/services/java/com/android/server/wifi/WifiService.java b/services/java/com/android/server/wifi/WifiService.java
index a70978e..5a24ebb 100644
--- a/services/java/com/android/server/wifi/WifiService.java
+++ b/services/java/com/android/server/wifi/WifiService.java
@@ -25,18 +25,20 @@
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.database.ContentObserver;
-import android.net.wifi.IWifiManager;
-import android.net.wifi.ScanResult;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
-import android.net.wifi.WifiStateMachine;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiWatchdogStateMachine;
 import android.net.DhcpInfo;
 import android.net.DhcpResults;
 import android.net.LinkAddress;
 import android.net.NetworkUtils;
 import android.net.RouteInfo;
+import android.net.wifi.IWifiManager;
+import android.net.wifi.ScanResult;
+import android.net.wifi.BatchedScanResult;
+import android.net.wifi.BatchedScanSettings;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiStateMachine;
+import android.net.wifi.WifiWatchdogStateMachine;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.Messenger;
@@ -48,16 +50,24 @@
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.WorkSource;
+import android.os.AsyncTask;
 import android.provider.Settings;
 import android.util.Log;
 import android.util.Slog;
 
+import java.io.FileNotFoundException;
+import java.io.BufferedReader;
 import java.io.FileDescriptor;
+import java.io.FileReader;
+import java.io.IOException;
 import java.io.PrintWriter;
+
 import java.net.InetAddress;
 import java.net.Inet4Address;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import com.android.internal.R;
@@ -114,6 +124,8 @@
     /* Tracks the persisted states for wi-fi & airplane mode */
     final WifiSettingsStore mSettingsStore;
 
+    final boolean mBatchedScanSupported;
+
     /**
      * Asynchronous channel to WifiStateMachine
      */
@@ -158,7 +170,20 @@
                 }
                 /* Client commands are forwarded to state machine */
                 case WifiManager.CONNECT_NETWORK:
-                case WifiManager.SAVE_NETWORK:
+                case WifiManager.SAVE_NETWORK: {
+                    WifiConfiguration config = (WifiConfiguration) msg.obj;
+                    if (config.isValid()) {
+                        mWifiStateMachine.sendMessage(Message.obtain(msg));
+                    } else {
+                        Slog.d(TAG, "ClientHandler.handleMessage ignoring msg=" + msg);
+                        if (msg.what == WifiManager.CONNECT_NETWORK) {
+                            replyFailed(msg, WifiManager.CONNECT_NETWORK_FAILED);
+                        } else {
+                            replyFailed(msg, WifiManager.SAVE_NETWORK_FAILED);
+                        }
+                    }
+                    break;
+                }
                 case WifiManager.FORGET_NETWORK:
                 case WifiManager.START_WPS:
                 case WifiManager.CANCEL_WPS:
@@ -173,6 +198,17 @@
                 }
             }
         }
+
+        private void replyFailed(Message msg, int what) {
+            Message reply = msg.obtain();
+            reply.what = what;
+            reply.arg1 = WifiManager.INVALID_ARGS;
+            try {
+                msg.replyTo.send(reply);
+            } catch (RemoteException e) {
+                // There's not much we can do if reply can't be sent!
+            }
+        }
     }
     private ClientHandler mClientHandler;
 
@@ -239,6 +275,9 @@
         mWifiController = new WifiController(mContext, this, wifiThread.getLooper());
         mWifiController.start();
 
+        mBatchedScanSupported = mContext.getResources().getBoolean(
+                R.bool.config_wifi_batched_scan_supported);
+
         registerForScanModeChange();
         mContext.registerReceiver(
                 new BroadcastReceiver() {
@@ -296,10 +335,168 @@
 
     /**
      * see {@link android.net.wifi.WifiManager#startScan()}
+     *
+     * <p>If workSource is null, all blame is given to the calling uid.
      */
-    public void startScan() {
+    public void startScan(WorkSource workSource) {
         enforceChangePermission();
-        mWifiStateMachine.startScan(Binder.getCallingUid());
+        if (workSource != null) {
+            enforceWorkSourcePermission();
+            // WifiManager currently doesn't use names, so need to clear names out of the
+            // supplied WorkSource to allow future WorkSource combining.
+            workSource.clearNames();
+        }
+        mWifiStateMachine.startScan(Binder.getCallingUid(), workSource);
+    }
+
+    private class BatchedScanRequest extends DeathRecipient {
+        BatchedScanSettings settings;
+        int uid;
+        int pid;
+
+        BatchedScanRequest(BatchedScanSettings settings, IBinder binder) {
+            super(0, null, binder, null);
+            this.settings = settings;
+            this.uid = getCallingUid();
+            this.pid = getCallingPid();
+        }
+        public void binderDied() {
+            stopBatchedScan(settings, mBinder);
+        }
+        public String toString() {
+            return "BatchedScanRequest{settings=" + settings + ", binder=" + mBinder + "}";
+        }
+
+        public boolean isSameApp() {
+            return (this.uid == getCallingUid() && this.pid == getCallingPid());
+        }
+    }
+
+    private final List<BatchedScanRequest> mBatchedScanners = new ArrayList<BatchedScanRequest>();
+
+    public boolean isBatchedScanSupported() {
+        return mBatchedScanSupported;
+    }
+
+    public void pollBatchedScan() {
+        enforceChangePermission();
+        if (mBatchedScanSupported == false) return;
+        mWifiStateMachine.requestBatchedScanPoll();
+    }
+
+    /**
+     * see {@link android.net.wifi.WifiManager#requestBatchedScan()}
+     */
+    public boolean requestBatchedScan(BatchedScanSettings requested, IBinder binder) {
+        enforceChangePermission();
+        if (mBatchedScanSupported == false) return false;
+        requested = new BatchedScanSettings(requested);
+        if (requested.isInvalid()) return false;
+        BatchedScanRequest r = new BatchedScanRequest(requested, binder);
+        synchronized(mBatchedScanners) {
+            mBatchedScanners.add(r);
+            resolveBatchedScannersLocked();
+        }
+        return true;
+    }
+
+    public List<BatchedScanResult> getBatchedScanResults(String callingPackage) {
+        enforceAccessPermission();
+        if (mBatchedScanSupported == false) return new ArrayList<BatchedScanResult>();
+        int userId = UserHandle.getCallingUserId();
+        int uid = Binder.getCallingUid();
+        long ident = Binder.clearCallingIdentity();
+        try {
+            if (mAppOps.noteOp(AppOpsManager.OP_WIFI_SCAN, uid, callingPackage)
+                    != AppOpsManager.MODE_ALLOWED) {
+                return new ArrayList<BatchedScanResult>();
+            }
+            int currentUser = ActivityManager.getCurrentUser();
+            if (userId != currentUser) {
+                return new ArrayList<BatchedScanResult>();
+            } else {
+                return mWifiStateMachine.syncGetBatchedScanResultsList();
+            }
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+
+    public void stopBatchedScan(BatchedScanSettings settings, IBinder binder) {
+        enforceChangePermission();
+        if (mBatchedScanSupported == false) return;
+        ArrayList<BatchedScanRequest> found = new ArrayList<BatchedScanRequest>();
+        synchronized(mBatchedScanners) {
+            for (BatchedScanRequest r : mBatchedScanners) {
+                if (r.isSameApp() && (settings == null || settings.equals(r.settings))) {
+                    found.add(r);
+                    if (settings != null) break;
+                }
+            }
+            for (BatchedScanRequest r : found) {
+                mBatchedScanners.remove(r);
+            }
+            if (found.size() != 0) {
+                resolveBatchedScannersLocked();
+            }
+        }
+    }
+
+    private void resolveBatchedScannersLocked() {
+        BatchedScanSettings setting = new BatchedScanSettings();
+        setting.scanIntervalSec = BatchedScanSettings.DEFAULT_INTERVAL_SEC;
+        int responsibleUid = 0;
+        setting.channelSet = new ArrayList<String>();
+
+        if (mBatchedScanners.size() == 0) {
+            mWifiStateMachine.setBatchedScanSettings(null, 0);
+            return;
+        }
+
+        for (BatchedScanRequest r : mBatchedScanners) {
+            BatchedScanSettings s = r.settings;
+            if (s.maxScansPerBatch != BatchedScanSettings.UNSPECIFIED &&
+                    s.maxScansPerBatch < setting.maxScansPerBatch) {
+                setting.maxScansPerBatch = s.maxScansPerBatch;
+                responsibleUid = r.uid;
+            }
+            if (s.maxApPerScan != BatchedScanSettings.UNSPECIFIED &&
+                    s.maxApPerScan > setting.maxApPerScan) {
+                setting.maxApPerScan = s.maxApPerScan;
+            }
+            if (s.scanIntervalSec != BatchedScanSettings.UNSPECIFIED &&
+                    s.scanIntervalSec < setting.scanIntervalSec) {
+                setting.scanIntervalSec = s.scanIntervalSec;
+                responsibleUid = r.uid;
+            }
+            if (s.maxApForDistance != BatchedScanSettings.UNSPECIFIED &&
+                    s.maxApForDistance > setting.maxApForDistance) {
+                setting.maxApForDistance = s.maxApForDistance;
+            }
+            if (s.channelSet != null) {
+                for (String i : s.channelSet) {
+                    if (setting.channelSet.contains(i) == false) setting.channelSet.add(i);
+                }
+            }
+        }
+        if (setting.channelSet.size() == 0) setting.channelSet = null;
+        if (setting.scanIntervalSec < BatchedScanSettings.MIN_INTERVAL_SEC) {
+            setting.scanIntervalSec = BatchedScanSettings.MIN_INTERVAL_SEC;
+        }
+        if (setting.maxScansPerBatch == BatchedScanSettings.UNSPECIFIED) {
+            setting.maxScansPerBatch = BatchedScanSettings.DEFAULT_SCANS_PER_BATCH;
+        }
+        if (setting.maxApPerScan == BatchedScanSettings.UNSPECIFIED) {
+            setting.maxApPerScan = BatchedScanSettings.DEFAULT_AP_PER_SCAN;
+        }
+        if (setting.scanIntervalSec == BatchedScanSettings.UNSPECIFIED) {
+            setting.scanIntervalSec = BatchedScanSettings.DEFAULT_INTERVAL_SEC;
+        }
+        if (setting.maxApForDistance == BatchedScanSettings.UNSPECIFIED) {
+            setting.maxApForDistance = BatchedScanSettings.DEFAULT_AP_FOR_DISTANCE;
+        }
+        mWifiStateMachine.setBatchedScanSettings(setting, responsibleUid);
     }
 
     private void enforceAccessPermission() {
@@ -313,6 +510,12 @@
 
     }
 
+    private void enforceWorkSourcePermission() {
+        mContext.enforceCallingPermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
+                                                "WifiService");
+
+    }
+
     private void enforceMulticastChangePermission() {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.CHANGE_WIFI_MULTICAST_STATE,
@@ -379,7 +582,11 @@
      */
     public void setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) {
         enforceChangePermission();
-        mWifiController.obtainMessage(CMD_SET_AP, enabled ? 1 : 0, 0, wifiConfig).sendToTarget();
+        if (wifiConfig.isValid()) {
+            mWifiController.obtainMessage(CMD_SET_AP, enabled ? 1 : 0, 0, wifiConfig).sendToTarget();
+        } else {
+            Slog.e(TAG, "Invalid WifiConfiguration");
+        }
     }
 
     /**
@@ -412,7 +619,11 @@
         enforceChangePermission();
         if (wifiConfig == null)
             return;
-        mWifiStateMachine.setWifiApConfiguration(wifiConfig);
+        if (wifiConfig.isValid()) {
+            mWifiStateMachine.setWifiApConfiguration(wifiConfig);
+        } else {
+            Slog.e(TAG, "Invalid WifiConfiguration");
+        }
     }
 
     /**
@@ -470,10 +681,15 @@
      */
     public int addOrUpdateNetwork(WifiConfiguration config) {
         enforceChangePermission();
-        if (mWifiStateMachineChannel != null) {
-            return mWifiStateMachine.syncAddOrUpdateNetwork(mWifiStateMachineChannel, config);
+        if (config.isValid()) {
+            if (mWifiStateMachineChannel != null) {
+                return mWifiStateMachine.syncAddOrUpdateNetwork(mWifiStateMachineChannel, config);
+            } else {
+                Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
+                return -1;
+            }
         } else {
-            Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
+            Slog.e(TAG, "bad network configuration");
             return -1;
         }
     }
@@ -551,11 +767,11 @@
         int userId = UserHandle.getCallingUserId();
         int uid = Binder.getCallingUid();
         long ident = Binder.clearCallingIdentity();
-        if (mAppOps.noteOp(AppOpsManager.OP_WIFI_SCAN, uid, callingPackage)
-                != AppOpsManager.MODE_ALLOWED) {
-            return new ArrayList<ScanResult>();
-        }
         try {
+            if (mAppOps.noteOp(AppOpsManager.OP_WIFI_SCAN, uid, callingPackage)
+                    != AppOpsManager.MODE_ALLOWED) {
+                return new ArrayList<ScanResult>();
+            }
             int currentUser = ActivityManager.getCurrentUser();
             if (userId != currentUser) {
                 return new ArrayList<ScanResult>();
@@ -749,6 +965,92 @@
     }
 
     /**
+     * enable TDLS for the local NIC to remote NIC
+     * The APPs don't know the remote MAC address to identify NIC though,
+     * so we need to do additional work to find it from remote IP address
+     */
+
+    class TdlsTaskParams {
+        public String remoteIpAddress;
+        public boolean enable;
+    }
+
+    class TdlsTask extends AsyncTask<TdlsTaskParams, Integer, Integer> {
+        @Override
+        protected Integer doInBackground(TdlsTaskParams... params) {
+
+            // Retrieve parameters for the call
+            TdlsTaskParams param = params[0];
+            String remoteIpAddress = param.remoteIpAddress.trim();
+            boolean enable = param.enable;
+
+            // Get MAC address of Remote IP
+            String macAddress = null;
+
+            BufferedReader reader = null;
+
+            try {
+                reader = new BufferedReader(new FileReader("/proc/net/arp"));
+
+                // Skip over the line bearing colum titles
+                String line = reader.readLine();
+
+                while ((line = reader.readLine()) != null) {
+                    String[] tokens = line.split("[ ]+");
+                    if (tokens.length < 6) {
+                        continue;
+                    }
+
+                    // ARP column format is
+                    // Address HWType HWAddress Flags Mask IFace
+                    String ip = tokens[0];
+                    String mac = tokens[3];
+
+                    if (remoteIpAddress.equals(ip)) {
+                        macAddress = mac;
+                        break;
+                    }
+                }
+
+                if (macAddress == null) {
+                    Slog.w(TAG, "Did not find remoteAddress {" + remoteIpAddress + "} in " +
+                            "/proc/net/arp");
+                } else {
+                    enableTdlsWithMacAddress(macAddress, enable);
+                }
+
+            } catch (FileNotFoundException e) {
+                Slog.e(TAG, "Could not open /proc/net/arp to lookup mac address");
+            } catch (IOException e) {
+                Slog.e(TAG, "Could not read /proc/net/arp to lookup mac address");
+            } finally {
+                try {
+                    if (reader != null) {
+                        reader.close();
+                    }
+                }
+                catch (IOException e) {
+                    // Do nothing
+                }
+            }
+
+            return 0;
+        }
+    }
+
+    public void enableTdls(String remoteAddress, boolean enable) {
+        TdlsTaskParams params = new TdlsTaskParams();
+        params.remoteIpAddress = remoteAddress;
+        params.enable = enable;
+        new TdlsTask().execute(params);
+    }
+
+
+    public void enableTdlsWithMacAddress(String remoteMacAddress, boolean enable) {
+        mWifiStateMachine.enableTdls(remoteMacAddress, enable);
+    }
+
+    /**
      * Get a reference to handler. This is used by a client to establish
      * an AsyncChannel communication with WifiService
      */
diff --git a/services/java/com/android/server/wm/AppWindowAnimator.java b/services/java/com/android/server/wm/AppWindowAnimator.java
index 6293dc6..3cccf1d 100644
--- a/services/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/java/com/android/server/wm/AppWindowAnimator.java
@@ -6,7 +6,6 @@
 import android.util.Slog;
 import android.util.TimeUtils;
 import android.view.Display;
-import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.WindowManagerPolicy;
 import android.view.animation.Animation;
diff --git a/services/java/com/android/server/wm/AppWindowToken.java b/services/java/com/android/server/wm/AppWindowToken.java
index fbb5013..8cc1d02 100644
--- a/services/java/com/android/server/wm/AppWindowToken.java
+++ b/services/java/com/android/server/wm/AppWindowToken.java
@@ -30,6 +30,10 @@
 import android.view.WindowManager;
 
 import java.io.PrintWriter;
+import java.util.ArrayList;
+
+class AppTokenList extends ArrayList<AppWindowToken> {
+}
 
 /**
  * Version of WindowToken that is specifically for a particular application (or
diff --git a/services/java/com/android/server/wm/BlackFrame.java b/services/java/com/android/server/wm/BlackFrame.java
index 774b165..5aa266d 100644
--- a/services/java/com/android/server/wm/BlackFrame.java
+++ b/services/java/com/android/server/wm/BlackFrame.java
@@ -22,7 +22,7 @@
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.util.Slog;
-import android.view.Surface;
+import android.view.Surface.OutOfResourcesException;
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
 
@@ -37,7 +37,7 @@
         final SurfaceControl surface;
 
         BlackSurface(SurfaceSession session, int layer, int l, int t, int r, int b, int layerStack)
-                throws SurfaceControl.OutOfResourcesException {
+                throws OutOfResourcesException {
             left = l;
             top = t;
             this.layer = layer;
@@ -62,6 +62,10 @@
                             "  BLACK " + surface + ": CREATE layer=" + layer);
         }
 
+        void setAlpha(float alpha) {
+            surface.setAlpha(alpha);
+        }
+
         void setMatrix(Matrix matrix) {
             mTmpMatrix.setTranslate(left, top);
             mTmpMatrix.postConcat(matrix);
@@ -93,6 +97,8 @@
     final float[] mTmpFloats = new float[9];
     final BlackSurface[] mBlackSurfaces = new BlackSurface[4];
 
+    final boolean mForceDefaultOrientation;
+
     public void printTo(String prefix, PrintWriter pw) {
         pw.print(prefix); pw.print("Outer: "); mOuterRect.printShortString(pw);
                 pw.print(" / Inner: "); mInnerRect.printShortString(pw);
@@ -106,10 +112,12 @@
         }
     }
 
-    public BlackFrame(SurfaceSession session, Rect outer, Rect inner,
-            int layer, final int layerStack) throws SurfaceControl.OutOfResourcesException {
+    public BlackFrame(SurfaceSession session, Rect outer, Rect inner, int layer, int layerStack,
+            boolean forceDefaultOrientation) throws OutOfResourcesException {
         boolean success = false;
 
+        mForceDefaultOrientation = forceDefaultOrientation;
+
         mOuterRect = new Rect(outer);
         mInnerRect = new Rect(inner);
         try {
@@ -162,6 +170,14 @@
         }
     }
 
+    public void setAlpha(float alpha) {
+        for (int i=0; i<mBlackSurfaces.length; i++) {
+            if (mBlackSurfaces[i] != null) {
+                mBlackSurfaces[i].setAlpha(alpha);
+            }
+        }
+    }
+
     public void setMatrix(Matrix matrix) {
         for (int i=0; i<mBlackSurfaces.length; i++) {
             if (mBlackSurfaces[i] != null) {
diff --git a/services/java/com/android/server/wm/DimLayer.java b/services/java/com/android/server/wm/DimLayer.java
index 9bd36ba..39e664f 100644
--- a/services/java/com/android/server/wm/DimLayer.java
+++ b/services/java/com/android/server/wm/DimLayer.java
@@ -3,10 +3,10 @@
 package com.android.server.wm;
 
 import android.graphics.PixelFormat;
+import android.graphics.Rect;
 import android.os.SystemClock;
 import android.util.Slog;
 import android.view.DisplayInfo;
-import android.view.Surface;
 import android.view.SurfaceControl;
 
 import java.io.PrintWriter;
@@ -27,8 +27,11 @@
     /** Last value passed to mDimSurface.setLayer() */
     int mLayer = -1;
 
-    /** Last values passed to mDimSurface.setSize() */
-    int mLastDimWidth, mLastDimHeight;
+    /** Next values to pass to mDimSurface.setPosition() and mDimSurface.setSize() */
+    Rect mBounds = new Rect();
+
+    /** Last values passed to mDimSurface.setPosition() and mDimSurface.setSize() */
+    Rect mLastBounds = new Rect();
 
     /** True after mDimSurface.show() has been called, false after mDimSurface.hide(). */
     private boolean mShowing = false;
@@ -45,9 +48,10 @@
     /** Time in milliseconds to take to transition from mStartAlpha to mTargetAlpha */
     long mDuration;
 
-    DimLayer(WindowManagerService service, int displayId) {
+    DimLayer(WindowManagerService service, DisplayContent displayContent) {
+        mDisplayContent = displayContent;
+        final int displayId = displayContent.getDisplayId();
         if (DEBUG) Slog.v(TAG, "Ctor: displayId=" + displayId);
-        mDisplayContent = service.getDisplayContentLocked(displayId);
         SurfaceControl.openTransaction();
         try {
             if (WindowManagerService.DEBUG_SURFACE_TRACE) {
@@ -117,6 +121,10 @@
         }
     }
 
+    void setBounds(Rect bounds) {
+        mBounds.set(bounds);
+    }
+
     /**
      * @param duration The time to test.
      * @return True if the duration would lead to an earlier end to the current animation.
@@ -152,6 +160,7 @@
             return;
         }
 
+        /*
         // Set surface size to screen size.
         final DisplayInfo info = mDisplayContent.getDisplayInfo();
         // Multiply by 1.5 so that rotating a frozen surface that includes this does not expose a
@@ -161,17 +170,17 @@
         // back off position so 1/4 of Surface is before and 1/4 is after.
         final float xPos = -1 * dw / 6;
         final float yPos = -1 * dh / 6;
+        */
 
-        if (mLastDimWidth != dw || mLastDimHeight != dh || mLayer != layer) {
+        if (!mLastBounds.equals(mBounds) || mLayer != layer) {
             try {
-                mDimSurface.setPosition(xPos, yPos);
-                mDimSurface.setSize(dw, dh);
+                mDimSurface.setPosition(mBounds.left, mBounds.top);
+                mDimSurface.setSize(mBounds.width(), mBounds.height());
                 mDimSurface.setLayer(layer);
             } catch (RuntimeException e) {
                 Slog.w(TAG, "Failure setting size or layer", e);
             }
-            mLastDimWidth = dw;
-            mLastDimHeight = dh;
+            mLastBounds.set(mBounds);
             mLayer = layer;
         }
 
@@ -255,15 +264,16 @@
     }
 
     public void printTo(String prefix, PrintWriter pw) {
-        pw.print(prefix); pw.print("mDimSurface="); pw.println(mDimSurface);
-        pw.print(prefix); pw.print(" mLayer="); pw.print(mLayer);
+        pw.print(prefix); pw.print("mDimSurface="); pw.print(mDimSurface);
+                pw.print(" mLayer="); pw.print(mLayer);
                 pw.print(" mAlpha="); pw.println(mAlpha);
-        pw.print(prefix); pw.print("mLastDimWidth="); pw.print(mLastDimWidth);
-                pw.print(" mLastDimWidth="); pw.println(mLastDimWidth);
-        pw.print(prefix); pw.print("Last animation: mStartTime="); pw.print(mStartTime);
+        pw.print(prefix); pw.print("mLastBounds="); pw.print(mLastBounds.toShortString());
+                pw.print(" mBounds="); pw.println(mBounds.toShortString());
+        pw.print(prefix); pw.print("Last animation: ");
                 pw.print(" mDuration="); pw.print(mDuration);
+                pw.print(" mStartTime="); pw.print(mStartTime);
                 pw.print(" curTime="); pw.println(SystemClock.uptimeMillis());
-        pw.print(" mStartAlpha="); pw.println(mStartAlpha);
-                pw.print(" mTargetAlpha="); pw.print(mTargetAlpha);
+        pw.print(prefix); pw.print(" mStartAlpha="); pw.print(mStartAlpha);
+                pw.print(" mTargetAlpha="); pw.println(mTargetAlpha);
     }
 }
diff --git a/services/java/com/android/server/wm/DisplayContent.java b/services/java/com/android/server/wm/DisplayContent.java
index 59e4b0e..beeb899 100644
--- a/services/java/com/android/server/wm/DisplayContent.java
+++ b/services/java/com/android/server/wm/DisplayContent.java
@@ -16,6 +16,15 @@
 
 package com.android.server.wm;
 
+import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
+import static com.android.server.wm.WindowManagerService.DEBUG_STACK;
+import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
+import static com.android.server.wm.WindowManagerService.TAG;
+
+import android.app.ActivityManager.StackBoxInfo;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.util.Slog;
 import android.view.Display;
 import android.view.DisplayInfo;
 
@@ -61,19 +70,66 @@
     private final DisplayInfo mDisplayInfo = new DisplayInfo();
     private final Display mDisplay;
 
+    Rect mBaseDisplayRect = new Rect();
+
     // Accessed directly by all users.
     boolean layoutNeeded;
     int pendingLayoutChanges;
     final boolean isDefaultDisplay;
 
     /**
-     * @param display May not be null.
+     * Window tokens that are in the process of exiting, but still
+     * on screen for animations.
      */
-    DisplayContent(Display display) {
+    final ArrayList<WindowToken> mExitingTokens = new ArrayList<WindowToken>();
+
+    /**
+     * Application tokens that are in the process of exiting, but still
+     * on screen for animations.
+     */
+    final AppTokenList mExitingAppTokens = new AppTokenList();
+
+    /** Array containing the home StackBox and possibly one more which would contain apps. Array
+     * is stored in display order with the current bottom stack at 0. */
+    private ArrayList<StackBox> mStackBoxes = new ArrayList<StackBox>();
+
+    /** True when the home StackBox is at the top of mStackBoxes, false otherwise. */
+    private TaskStack mHomeStack = null;
+
+    /** Sorted most recent at top, oldest at [0]. */
+    ArrayList<TaskStack> mStackHistory = new ArrayList<TaskStack>();
+
+    /** Detect user tapping outside of current focused stack bounds .*/
+    StackTapPointerEventListener mTapDetector;
+
+    /** Detect user tapping outside of current focused stack bounds .*/
+    Region mTouchExcludeRegion = new Region();
+
+    /** Save allocating when retrieving tasks */
+    ArrayList<Task> mTmpTasks = new ArrayList<Task>();
+
+    /** Save allocating when calculating rects */
+    Rect mTmpRect = new Rect();
+
+    final WindowManagerService mService;
+
+    /**
+     * @param display May not be null.
+     * @param service TODO(cmautner):
+     */
+    DisplayContent(Display display, WindowManagerService service) {
         mDisplay = display;
         mDisplayId = display.getDisplayId();
         display.getDisplayInfo(mDisplayInfo);
         isDefaultDisplay = mDisplayId == Display.DEFAULT_DISPLAY;
+        mService = service;
+
+        StackBox newBox = new StackBox(service, this, null);
+        mStackBoxes.add(newBox);
+        TaskStack newStack = new TaskStack(service, HOME_STACK_ID, this);
+        newStack.mStackBox = newBox;
+        newBox.mStack = newStack;
+        mHomeStack = newStack;
     }
 
     int getDisplayId() {
@@ -92,10 +148,291 @@
         return mDisplayInfo;
     }
 
-    public void updateDisplayInfo() {
+    /**
+     * Returns true if the specified UID has access to this display.
+     */
+    public boolean hasAccess(int uid) {
+        return mDisplay.hasAccess(uid);
+    }
+
+    boolean homeOnTop() {
+        return mStackBoxes.get(0).mStack != mHomeStack;
+    }
+
+    void moveStack(TaskStack stack, boolean toTop) {
+        mStackHistory.remove(stack);
+        mStackHistory.add(toTop ? mStackHistory.size() : 0, stack);
+    }
+
+    public boolean isPrivate() {
+        return (mDisplay.getFlags() & Display.FLAG_PRIVATE) != 0;
+    }
+
+    /**
+     * Retrieve the tasks on this display in stack order from the bottommost TaskStack up.
+     * @return All the Tasks, in order, on this display.
+     */
+    ArrayList<Task> getTasks() {
+        mTmpTasks.clear();
+        final int numStacks = mStackHistory.size();
+        for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
+            mTmpTasks.addAll(mStackHistory.get(stackNdx).getTasks());
+        }
+        if (WindowManagerService.DEBUG_LAYERS) Slog.i(TAG, "getTasks: mStackHistory=" +
+                mStackHistory);
+        return mTmpTasks;
+    }
+
+    TaskStack getHomeStack() {
+        return mHomeStack;
+    }
+
+    void updateDisplayInfo() {
         mDisplay.getDisplayInfo(mDisplayInfo);
     }
 
+    void getLogicalDisplayRect(Rect out) {
+        updateDisplayInfo();
+        // Uses same calculation as in LogicalDisplay#configureDisplayInTransactionLocked.
+        int width = mDisplayInfo.logicalWidth;
+        int left = (mBaseDisplayWidth - width) / 2;
+        int height = mDisplayInfo.logicalHeight;
+        int top = (mBaseDisplayHeight - height) / 2;
+        out.set(left, top, left + width, top + height);
+    }
+
+    /** @return The number of tokens in all of the Tasks on this display. */
+    int numTokens() {
+        getTasks();
+        int count = 0;
+        for (int taskNdx = mTmpTasks.size() - 1; taskNdx >= 0; --taskNdx) {
+            count += mTmpTasks.get(taskNdx).mAppTokens.size();
+        }
+        return count;
+    }
+
+    /** Refer to {@link WindowManagerService#createStack(int, int, int, float)} */
+    TaskStack createStack(int stackId, int relativeStackBoxId, int position, float weight) {
+        TaskStack newStack = null;
+        if (DEBUG_STACK) Slog.d(TAG, "createStack: stackId=" + stackId + " relativeStackBoxId="
+                + relativeStackBoxId + " position=" + position + " weight=" + weight);
+        if (stackId == HOME_STACK_ID) {
+            if (mStackBoxes.size() != 1) {
+                throw new IllegalArgumentException("createStack: HOME_STACK_ID (0) not first.");
+            }
+            newStack = mHomeStack;
+        } else {
+            int stackBoxNdx;
+            for (stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
+                final StackBox box = mStackBoxes.get(stackBoxNdx);
+                if (position == StackBox.TASK_STACK_GOES_OVER
+                        || position == StackBox.TASK_STACK_GOES_UNDER) {
+                    // Position indicates a new box is added at top level only.
+                    if (box.contains(relativeStackBoxId)) {
+                        StackBox newBox = new StackBox(mService, this, null);
+                        newStack = new TaskStack(mService, stackId, this);
+                        newStack.mStackBox = newBox;
+                        newBox.mStack = newStack;
+                        final int offset = position == StackBox.TASK_STACK_GOES_OVER ? 1 : 0;
+                        if (DEBUG_STACK) Slog.d(TAG, "createStack: inserting stack at " +
+                                (stackBoxNdx + offset));
+                        mStackBoxes.add(stackBoxNdx + offset, newBox);
+                        break;
+                    }
+                } else {
+                    // Remaining position values indicate a box must be split.
+                    newStack = box.split(stackId, relativeStackBoxId, position, weight);
+                    if (newStack != null) {
+                        break;
+                    }
+                }
+            }
+            if (stackBoxNdx < 0) {
+                throw new IllegalArgumentException("createStack: stackBoxId " + relativeStackBoxId
+                        + " not found.");
+            }
+        }
+        if (newStack != null) {
+            layoutNeeded = true;
+        }
+        return newStack;
+    }
+
+    /** Refer to {@link WindowManagerService#resizeStackBox(int, float)} */
+    boolean resizeStack(int stackBoxId, float weight) {
+        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
+            final StackBox box = mStackBoxes.get(stackBoxNdx);
+            if (box.resize(stackBoxId, weight)) {
+                layoutNeeded = true;
+                return true;
+            }
+        }
+        return false;
+    }
+
+    void addStackBox(StackBox box, boolean toTop) {
+        if (mStackBoxes.size() >= 2) {
+            throw new RuntimeException("addStackBox: Too many toplevel StackBoxes!");
+        }
+        mStackBoxes.add(toTop ? mStackBoxes.size() : 0, box);
+    }
+
+    void removeStackBox(StackBox box) {
+        if (DEBUG_STACK) Slog.d(TAG, "removeStackBox: box=" + box);
+        final TaskStack stack = box.mStack;
+        if (stack != null && stack.mStackId == HOME_STACK_ID) {
+            // Never delete the home stack, even if it is empty.
+            if (DEBUG_STACK) Slog.d(TAG, "removeStackBox: Not deleting home stack.");
+            return;
+        }
+        mStackBoxes.remove(box);
+    }
+
+    StackBoxInfo getStackBoxInfo(StackBox box) {
+        StackBoxInfo info = new StackBoxInfo();
+        info.stackBoxId = box.mStackBoxId;
+        info.weight = box.mWeight;
+        info.vertical = box.mVertical;
+        info.bounds = new Rect(box.mBounds);
+        if (box.mStack != null) {
+            info.stackId = box.mStack.mStackId;
+            // ActivityManagerService will fill in the StackInfo.
+        } else {
+            info.stackId = -1;
+            info.children = new StackBoxInfo[2];
+            info.children[0] = getStackBoxInfo(box.mFirst);
+            info.children[1] = getStackBoxInfo(box.mSecond);
+        }
+        return info;
+    }
+
+    ArrayList<StackBoxInfo> getStackBoxInfos() {
+        ArrayList<StackBoxInfo> list = new ArrayList<StackBoxInfo>();
+        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
+            list.add(getStackBoxInfo(mStackBoxes.get(stackBoxNdx)));
+        }
+        return list;
+    }
+
+    /**
+     * Move the home StackBox to the top or bottom of mStackBoxes. That is the only place
+     * it is allowed to be. This is a nop if the home StackBox is already in the correct position.
+     * @param toTop Move home to the top of mStackBoxes if true, to the bottom if false.
+     * @return true if a change was made, false otherwise.
+     */
+    boolean moveHomeStackBox(boolean toTop) {
+        if (DEBUG_STACK) Slog.d(TAG, "moveHomeStackBox: toTop=" + toTop);
+        switch (mStackBoxes.size()) {
+            case 0: throw new RuntimeException("moveHomeStackBox: No home StackBox!");
+            case 1: return false; // Only the home StackBox exists.
+            case 2:
+                if (homeOnTop() ^ toTop) {
+                    mStackBoxes.add(mStackBoxes.remove(0));
+                    return true;
+                }
+                return false;
+            default: throw new RuntimeException("moveHomeStackBox: Too many toplevel StackBoxes!");
+        }
+    }
+
+    /**
+     * Propagate the new bounds to all child stack boxes, applying weights as we move down.
+     * @param contentRect The bounds to apply at the top level.
+     */
+    boolean setStackBoxSize(Rect contentRect) {
+        boolean change = false;
+        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
+            change |= mStackBoxes.get(stackBoxNdx).setStackBoxSizes(contentRect, true);
+        }
+        return change;
+    }
+
+    Rect getStackBounds(int stackId) {
+        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
+            Rect bounds = mStackBoxes.get(stackBoxNdx).getStackBounds(stackId);
+            if (bounds != null) {
+                return bounds;
+            }
+        }
+        return null;
+    }
+
+    int stackIdFromPoint(int x, int y) {
+        StackBox topBox = mStackBoxes.get(mStackBoxes.size() - 1);
+        return topBox.stackIdFromPoint(x, y);
+    }
+
+    void setTouchExcludeRegion(TaskStack focusedStack) {
+        mTouchExcludeRegion.set(mBaseDisplayRect);
+        WindowList windows = getWindowList();
+        for (int i = windows.size() - 1; i >= 0; --i) {
+            final WindowState win = windows.get(i);
+            final TaskStack stack = win.getStack();
+            if (win.isVisibleLw() && stack != null && stack != focusedStack) {
+                mTmpRect.set(win.mVisibleFrame);
+                mTmpRect.intersect(win.mVisibleInsets);
+                mTouchExcludeRegion.op(mTmpRect, Region.Op.DIFFERENCE);
+            }
+        }
+    }
+
+    void switchUserStacks(int oldUserId, int newUserId) {
+        final WindowList windows = getWindowList();
+        for (int i = 0; i < windows.size(); i++) {
+            final WindowState win = windows.get(i);
+            if (win.isHiddenFromUserLocked()) {
+                if (DEBUG_VISIBILITY) Slog.w(TAG, "user changing " + newUserId + " hiding "
+                        + win + ", attrs=" + win.mAttrs.type + ", belonging to "
+                        + win.mOwnerUid);
+                win.hideLw(false);
+            }
+        }
+
+        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
+            mStackBoxes.get(stackBoxNdx).switchUserStacks(newUserId);
+        }
+    }
+
+    void resetAnimationBackgroundAnimator() {
+        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
+            mStackBoxes.get(stackBoxNdx).resetAnimationBackgroundAnimator();
+        }
+    }
+
+    boolean animateDimLayers() {
+        boolean result = false;
+        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
+            result |= mStackBoxes.get(stackBoxNdx).animateDimLayers();
+        }
+        return result;
+    }
+
+    void resetDimming() {
+        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
+            mStackBoxes.get(stackBoxNdx).resetDimming();
+        }
+    }
+
+    boolean isDimming() {
+        boolean result = false;
+        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
+            result |= mStackBoxes.get(stackBoxNdx).isDimming();
+        }
+        return result;
+    }
+
+    void stopDimmingIfNeeded() {
+        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
+            mStackBoxes.get(stackBoxNdx).stopDimmingIfNeeded();
+        }
+    }
+
+    void close() {
+        for (int stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
+            mStackBoxes.get(stackBoxNdx).close();
+        }
+    }
+
     public void dump(String prefix, PrintWriter pw) {
         pw.print(prefix); pw.print("Display: mDisplayId="); pw.println(mDisplayId);
         final String subPrefix = "  " + prefix;
@@ -119,7 +456,48 @@
             pw.print("x"); pw.print(mDisplayInfo.smallestNominalAppHeight);
             pw.print("-"); pw.print(mDisplayInfo.largestNominalAppWidth);
             pw.print("x"); pw.println(mDisplayInfo.largestNominalAppHeight);
-        pw.print(subPrefix); pw.print("layoutNeeded="); pw.print(layoutNeeded);
+            pw.print(subPrefix); pw.print("layoutNeeded="); pw.println(layoutNeeded);
+        for (int boxNdx = 0; boxNdx < mStackBoxes.size(); ++boxNdx) {
+            pw.print(prefix); pw.print("StackBox #"); pw.println(boxNdx);
+            mStackBoxes.get(boxNdx).dump(prefix + "  ", pw);
+        }
+        int ndx = numTokens();
+        if (ndx > 0) {
+            pw.println();
+            pw.println("  Application tokens in Z order:");
+            getTasks();
+            for (int taskNdx = mTmpTasks.size() - 1; taskNdx >= 0; --taskNdx) {
+                AppTokenList tokens = mTmpTasks.get(taskNdx).mAppTokens;
+                for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
+                    final AppWindowToken wtoken = tokens.get(tokenNdx);
+                    pw.print("  App #"); pw.print(ndx--);
+                            pw.print(' '); pw.print(wtoken); pw.println(":");
+                    wtoken.dump(pw, "    ");
+                }
+            }
+        }
+        if (mExitingTokens.size() > 0) {
+            pw.println();
+            pw.println("  Exiting tokens:");
+            for (int i=mExitingTokens.size()-1; i>=0; i--) {
+                WindowToken token = mExitingTokens.get(i);
+                pw.print("  Exiting #"); pw.print(i);
+                pw.print(' '); pw.print(token);
+                pw.println(':');
+                token.dump(pw, "    ");
+            }
+        }
+        if (mExitingAppTokens.size() > 0) {
+            pw.println();
+            pw.println("  Exiting application tokens:");
+            for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
+                WindowToken token = mExitingAppTokens.get(i);
+                pw.print("  Exiting App #"); pw.print(i);
+                  pw.print(' '); pw.print(token);
+                  pw.println(':');
+                  token.dump(pw, "    ");
+            }
+        }
         pw.println();
     }
 }
diff --git a/services/java/com/android/server/wm/DisplayMagnifier.java b/services/java/com/android/server/wm/DisplayMagnifier.java
index 0f51028..382d7b4 100644
--- a/services/java/com/android/server/wm/DisplayMagnifier.java
+++ b/services/java/com/android/server/wm/DisplayMagnifier.java
@@ -496,7 +496,7 @@
                     mWindowManager.getDefaultDisplay().getRealSize(mTempPoint);
                     surfaceControl = new SurfaceControl(mWindowManagerService.mFxSession, SURFACE_TITLE,
                             mTempPoint.x, mTempPoint.y, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
-                } catch (SurfaceControl.OutOfResourcesException oore) {
+                } catch (OutOfResourcesException oore) {
                     /* ignore */
                 }
                 mSurfaceControl = surfaceControl;
@@ -629,7 +629,7 @@
                         }
                     } catch (IllegalArgumentException iae) {
                         /* ignore */
-                    } catch (OutOfResourcesException oore) {
+                    } catch (Surface.OutOfResourcesException oore) {
                         /* ignore */
                     }
                     if (canvas == null) {
@@ -644,7 +644,7 @@
                     canvas.drawPath(path, mPaint);
 
                     mSurface.unlockCanvasAndPost(canvas);
-                    
+
                     if (mAlpha > 0) {
                         mSurfaceControl.show();
                     } else {
diff --git a/services/java/com/android/server/wm/FocusedStackFrame.java b/services/java/com/android/server/wm/FocusedStackFrame.java
new file mode 100644
index 0000000..365b277
--- /dev/null
+++ b/services/java/com/android/server/wm/FocusedStackFrame.java
@@ -0,0 +1,142 @@
+/*
+ * 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.server.wm;
+
+import static com.android.server.wm.WindowManagerService.DEBUG_STACK;
+import static com.android.server.wm.WindowManagerService.DEBUG_SURFACE_TRACE;
+
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.util.Slog;
+import android.view.Display;
+import android.view.Surface.OutOfResourcesException;
+import android.view.Surface;
+import android.view.SurfaceControl;
+import android.view.SurfaceSession;
+
+import com.android.server.wm.WindowStateAnimator.SurfaceTrace;
+
+class FocusedStackFrame {
+    private static final String TAG = "FocusedStackFrame";
+    private static final int THICKNESS = 10;
+    private static final float ALPHA = 0.3f;
+
+    private final SurfaceControl mSurfaceControl;
+    private final Surface mSurface = new Surface();
+    private final Rect mLastBounds = new Rect();
+    private final Rect mBounds = new Rect();
+    private final Rect mTmpDrawRect = new Rect();
+
+    public FocusedStackFrame(Display display, SurfaceSession session) {
+        SurfaceControl ctrl = null;
+        try {
+            if (DEBUG_SURFACE_TRACE) {
+                ctrl = new SurfaceTrace(session, "FocusedStackFrame",
+                    1, 1, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
+            } else {
+                ctrl = new SurfaceControl(session, "FocusedStackFrame",
+                    1, 1, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
+            }
+            ctrl.setLayerStack(display.getLayerStack());
+            ctrl.setAlpha(ALPHA);
+            mSurface.copyFrom(ctrl);
+        } catch (OutOfResourcesException e) {
+        }
+        mSurfaceControl = ctrl;
+    }
+
+    private void draw(Rect bounds, int color) {
+        if (DEBUG_STACK) Slog.i(TAG, "draw: bounds=" + bounds.toShortString() +
+                " color=" + Integer.toHexString(color));
+        mTmpDrawRect.set(bounds);
+        Canvas c = null;
+        try {
+            c = mSurface.lockCanvas(mTmpDrawRect);
+        } catch (IllegalArgumentException e) {
+        } catch (Surface.OutOfResourcesException e) {
+        }
+        if (c == null) {
+            return;
+        }
+
+        final int w = bounds.width();
+        final int h = bounds.height();
+
+        // Top
+        mTmpDrawRect.set(0, 0, w, THICKNESS);
+        c.clipRect(mTmpDrawRect, Region.Op.REPLACE);
+        c.drawColor(color);
+        // Left (not including Top or Bottom stripe).
+        mTmpDrawRect.set(0, THICKNESS, THICKNESS, h - THICKNESS);
+        c.clipRect(mTmpDrawRect, Region.Op.REPLACE);
+        c.drawColor(color);
+        // Right (not including Top or Bottom stripe).
+        mTmpDrawRect.set(w - THICKNESS, THICKNESS, w, h - THICKNESS);
+        c.clipRect(mTmpDrawRect, Region.Op.REPLACE);
+        c.drawColor(color);
+        // Bottom
+        mTmpDrawRect.set(0, h - THICKNESS, w, h);
+        c.clipRect(mTmpDrawRect, Region.Op.REPLACE);
+        c.drawColor(color);
+
+        mSurface.unlockCanvasAndPost(c);
+    }
+
+    private void positionSurface(Rect bounds) {
+        if (DEBUG_STACK) Slog.i(TAG, "positionSurface: bounds=" + bounds.toShortString());
+        mSurfaceControl.setSize(bounds.width(), bounds.height());
+        mSurfaceControl.setPosition(bounds.left, bounds.top);
+    }
+
+    // Note: caller responsible for being inside
+    // Surface.openTransaction() / closeTransaction()
+    public void setVisibility(boolean on) {
+        if (DEBUG_STACK) Slog.i(TAG, "setVisibility: on=" + on +
+                " mLastBounds=" + mLastBounds.toShortString() +
+                " mBounds=" + mBounds.toShortString());
+        if (mSurfaceControl == null) {
+            return;
+        }
+        if (on) {
+            if (!mLastBounds.equals(mBounds)) {
+                // Erase the previous rectangle.
+                positionSurface(mLastBounds);
+                draw(mLastBounds, Color.TRANSPARENT);
+                // Draw the latest rectangle.
+                positionSurface(mBounds);
+                draw(mBounds, Color.WHITE);
+                // Update the history.
+                mLastBounds.set(mBounds);
+            }
+            mSurfaceControl.show();
+        } else {
+            mSurfaceControl.hide();
+        }
+    }
+
+    public void setBounds(Rect bounds) {
+        if (DEBUG_STACK) Slog.i(TAG, "setBounds: bounds=" + bounds);
+        mBounds.set(bounds);
+    }
+
+    public void setLayer(int layer) {
+        mSurfaceControl.setLayer(layer);
+    }
+}
diff --git a/services/java/com/android/server/wm/InputMonitor.java b/services/java/com/android/server/wm/InputMonitor.java
index 0e36032..2e13fe2 100644
--- a/services/java/com/android/server/wm/InputMonitor.java
+++ b/services/java/com/android/server/wm/InputMonitor.java
@@ -66,6 +66,7 @@
      * 
      * Called by the InputManager.
      */
+    @Override
     public void notifyInputChannelBroken(InputWindowHandle inputWindowHandle) {
         if (inputWindowHandle == null) {
             return;
@@ -85,8 +86,9 @@
      * 
      * Called by the InputManager.
      */
+    @Override
     public long notifyANR(InputApplicationHandle inputApplicationHandle,
-            InputWindowHandle inputWindowHandle) {
+            InputWindowHandle inputWindowHandle, String reason) {
         AppWindowToken appWindowToken = null;
         WindowState windowState = null;
         boolean aboveSystem = false;
@@ -103,7 +105,8 @@
 
             if (windowState != null) {
                 Slog.i(WindowManagerService.TAG, "Input event dispatching timed out "
-                        + "sending to " + windowState.mAttrs.getTitle());
+                        + "sending to " + windowState.mAttrs.getTitle()
+                        + ".  Reason: " + reason);
                 // Figure out whether this window is layered above system windows.
                 // We need to do this here to help the activity manager know how to
                 // layer its ANR dialog.
@@ -112,19 +115,21 @@
                 aboveSystem = windowState.mBaseLayer > systemAlertLayer;
             } else if (appWindowToken != null) {
                 Slog.i(WindowManagerService.TAG, "Input event dispatching timed out "
-                        + "sending to application " + appWindowToken.stringName);
+                        + "sending to application " + appWindowToken.stringName
+                        + ".  Reason: " + reason);
             } else {
-                Slog.i(WindowManagerService.TAG, "Input event dispatching timed out.");
+                Slog.i(WindowManagerService.TAG, "Input event dispatching timed out "
+                        + ".  Reason: " + reason);
             }
 
-            mService.saveANRStateLocked(appWindowToken, windowState);
+            mService.saveANRStateLocked(appWindowToken, windowState, reason);
         }
 
         if (appWindowToken != null && appWindowToken.appToken != null) {
             try {
                 // Notify the activity manager about the timeout and let it decide whether
                 // to abort dispatching or keep waiting.
-                boolean abort = appWindowToken.appToken.keyDispatchingTimedOut();
+                boolean abort = appWindowToken.appToken.keyDispatchingTimedOut(reason);
                 if (! abort) {
                     // The activity manager declined to abort dispatching.
                     // Wait a bit longer and timeout again later.
@@ -137,7 +142,7 @@
                 // Notify the activity manager about the timeout and let it decide whether
                 // to abort dispatching or keep waiting.
                 long timeout = ActivityManagerNative.getDefault().inputDispatchingTimedOut(
-                        windowState.mSession.mPid, aboveSystem);
+                        windowState.mSession.mPid, aboveSystem, reason);
                 if (timeout >= 0) {
                     // The activity manager declined to abort dispatching.
                     // Wait a bit longer and timeout again later.
@@ -161,10 +166,20 @@
     }
 
     private void addInputWindowHandleLw(final InputWindowHandle inputWindowHandle,
-            final WindowState child, final int flags, final int type,
+            final WindowState child, int flags, final int type,
             final boolean isVisible, final boolean hasFocus, final boolean hasWallpaper) {
         // Add a window to our list of input windows.
         inputWindowHandle.name = child.toString();
+        final boolean modal = (flags & (WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)) == 0;
+        if (modal && child.mAppToken != null) {
+            // Limit the outer touch to the activity stack region.
+            flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
+            inputWindowHandle.touchableRegion.set(child.getStackBounds());
+        } else {
+            // Not modal or full screen modal
+            child.getTouchableRegion(inputWindowHandle.touchableRegion);
+        }
         inputWindowHandle.layoutParamsFlags = flags;
         inputWindowHandle.layoutParamsType = type;
         inputWindowHandle.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();
@@ -193,7 +208,6 @@
             inputWindowHandle.scaleFactor = 1;
         }
 
-        child.getTouchableRegion(inputWindowHandle.touchableRegion);
 
         addInputWindowHandleLw(inputWindowHandle);
     }
@@ -249,8 +263,7 @@
         // Add all windows on the default display.
         final int numDisplays = mService.mDisplayContents.size();
         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
-            final WindowList windows =
-                    mService.mDisplayContents.valueAt(displayNdx).getWindowList();
+            WindowList windows = mService.mDisplayContents.valueAt(displayNdx).getWindowList();
             for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
                 final WindowState child = windows.get(winNdx);
                 final InputChannel inputChannel = child.mInputChannel;
@@ -302,6 +315,7 @@
     }
 
     /* Notifies that the input device configuration has changed. */
+    @Override
     public void notifyConfigurationChanged() {
         mService.sendNewConfiguration();
 
@@ -327,12 +341,14 @@
     }
 
     /* Notifies that the lid switch changed state. */
+    @Override
     public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
         mService.mPolicy.notifyLidSwitchChanged(whenNanos, lidOpen);
     }
-    
+
     /* Provides an opportunity for the window manager policy to intercept early key
      * processing as soon as the key has been read from the device. */
+    @Override
     public int interceptKeyBeforeQueueing(
             KeyEvent event, int policyFlags, boolean isScreenOn) {
         return mService.mPolicy.interceptKeyBeforeQueueing(event, policyFlags, isScreenOn);
@@ -341,20 +357,23 @@
     /* Provides an opportunity for the window manager policy to intercept early
      * motion event processing when the screen is off since these events are normally
      * dropped. */
+    @Override
     public int interceptMotionBeforeQueueingWhenScreenOff(int policyFlags) {
         return mService.mPolicy.interceptMotionBeforeQueueingWhenScreenOff(policyFlags);
     }
 
     /* Provides an opportunity for the window manager policy to process a key before
      * ordinary dispatch. */
+    @Override
     public long interceptKeyBeforeDispatching(
             InputWindowHandle focus, KeyEvent event, int policyFlags) {
         WindowState windowState = focus != null ? (WindowState) focus.windowState : null;
         return mService.mPolicy.interceptKeyBeforeDispatching(windowState, event, policyFlags);
     }
-    
+
     /* Provides an opportunity for the window manager policy to process a key that
      * the application did not handle. */
+    @Override
     public KeyEvent dispatchUnhandledKey(
             InputWindowHandle focus, KeyEvent event, int policyFlags) {
         WindowState windowState = focus != null ? (WindowState) focus.windowState : null;
@@ -362,6 +381,7 @@
     }
 
     /* Callback to get pointer layer. */
+    @Override
     public int getPointerLayer() {
         return mService.mPolicy.windowTypeToLayerLw(WindowManager.LayoutParams.TYPE_POINTER)
                 * WindowManagerService.TYPE_LAYER_MULTIPLIER
@@ -372,7 +392,7 @@
      * Layer assignment is assumed to be complete by the time this is called.
      */
     public void setInputFocusLw(WindowState newWindow, boolean updateInputWindows) {
-        if (WindowManagerService.DEBUG_INPUT) {
+        if (WindowManagerService.DEBUG_FOCUS_LIGHT || WindowManagerService.DEBUG_INPUT) {
             Slog.d(WindowManagerService.TAG, "Input focus has changed to " + newWindow);
         }
 
@@ -392,7 +412,7 @@
             }
         }
     }
-    
+
     public void setFocusedAppLw(AppWindowToken newApp) {
         // Focused app has changed.
         if (newApp == null) {
@@ -405,7 +425,7 @@
             mService.mInputManager.setFocusedApplication(handle);
         }
     }
-    
+
     public void pauseDispatchingLw(WindowToken window) {
         if (! window.paused) {
             if (WindowManagerService.DEBUG_INPUT) {
diff --git a/services/java/com/android/server/wm/PointerEventDispatcher.java b/services/java/com/android/server/wm/PointerEventDispatcher.java
new file mode 100644
index 0000000..6b0e4c9
--- /dev/null
+++ b/services/java/com/android/server/wm/PointerEventDispatcher.java
@@ -0,0 +1,90 @@
+/*
+ * 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.server.wm;
+
+import android.view.InputChannel;
+import android.view.InputDevice;
+import android.view.InputEvent;
+import android.view.InputEventReceiver;
+import android.view.MotionEvent;
+import android.view.WindowManagerPolicy.PointerEventListener;
+
+import com.android.server.UiThread;
+
+import java.util.ArrayList;
+
+public class PointerEventDispatcher extends InputEventReceiver {
+    ArrayList<PointerEventListener> mListeners = new ArrayList<PointerEventListener>();
+    PointerEventListener[] mListenersArray = new PointerEventListener[0];
+
+    public PointerEventDispatcher(InputChannel inputChannel) {
+        super(inputChannel, UiThread.getHandler().getLooper());
+    }
+
+    @Override
+    public void onInputEvent(InputEvent event) {
+        try {
+            if (event instanceof MotionEvent
+                    && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+                final MotionEvent motionEvent = (MotionEvent)event;
+                PointerEventListener[] listeners;
+                synchronized (mListeners) {
+                    if (mListenersArray == null) {
+                        mListenersArray = new PointerEventListener[mListeners.size()];
+                        mListeners.toArray(mListenersArray);
+                    }
+                    listeners = mListenersArray;
+                }
+                for (int i = 0; i < listeners.length; ++i) {
+                    listeners[i].onPointerEvent(motionEvent);
+                }
+            }
+        } finally {
+            finishInputEvent(event, false);
+        }
+    }
+
+    /**
+     * Add the specified listener to the list.
+     * @param listener The listener to add.
+     */
+    public void registerInputEventListener(PointerEventListener listener) {
+        synchronized (mListeners) {
+            if (mListeners.contains(listener)) {
+                throw new IllegalStateException("registerInputEventListener: trying to register" +
+                        listener + " twice.");
+            }
+            mListeners.add(listener);
+            mListenersArray = null;
+        }
+    }
+
+    /**
+     * Remove the specified listener from the list.
+     * @param listener The listener to remove.
+     */
+    public void unregisterInputEventListener(PointerEventListener listener) {
+        synchronized (mListeners) {
+            if (!mListeners.contains(listener)) {
+                throw new IllegalStateException("registerInputEventListener: " + listener +
+                        " not registered.");
+            }
+            mListeners.remove(listener);
+            mListenersArray = null;
+        }
+    }
+}
diff --git a/services/java/com/android/server/wm/ScreenRotationAnimation.java b/services/java/com/android/server/wm/ScreenRotationAnimation.java
index b2fbec1..e630737 100644
--- a/services/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -26,6 +26,8 @@
 import android.graphics.Rect;
 import android.util.Slog;
 import android.view.Display;
+import android.view.DisplayInfo;
+import android.view.Surface.OutOfResourcesException;
 import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
@@ -43,7 +45,7 @@
     static final int FREEZE_LAYER = WindowManagerService.TYPE_LAYER_MULTIPLIER * 200;
 
     final Context mContext;
-    final Display mDisplay;
+    final DisplayContent mDisplayContent;
     SurfaceControl mSurfaceControl;
     BlackFrame mCustomBlackFrame;
     BlackFrame mExitingBlackFrame;
@@ -53,6 +55,8 @@
     int mOriginalRotation;
     int mOriginalWidth, mOriginalHeight;
     int mCurRotation;
+    Rect mOriginalDisplayRect = new Rect();
+    Rect mCurrentDisplayRect = new Rect();
 
     // For all animations, "exit" is for the UI elements that are going
     // away (that is the snapshot of the old screen), and "enter" is for
@@ -108,6 +112,7 @@
     boolean mAnimRunning;
     boolean mFinishAnimReady;
     long mFinishAnimStartTime;
+    boolean mForceDefaultOrientation;
 
     final Matrix mFrameInitialMatrix = new Matrix();
     final Matrix mSnapshotInitialMatrix = new Matrix();
@@ -186,14 +191,35 @@
         pw.print(prefix); pw.print("mExitFrameFinalMatrix=");
                 mExitFrameFinalMatrix.printShortString(pw);
                 pw.println();
+        pw.print(prefix); pw.print("mForceDefaultOrientation="); pw.print(mForceDefaultOrientation);
+        if (mForceDefaultOrientation) {
+            pw.print(" mOriginalDisplayRect="); pw.print(mOriginalDisplayRect.toShortString());
+            pw.print(" mCurrentDisplayRect="); pw.println(mCurrentDisplayRect.toShortString());
+        }
     }
 
-    public ScreenRotationAnimation(Context context, Display display, SurfaceSession session,
-            boolean inTransaction, int originalWidth, int originalHeight, int originalRotation) {
+    public ScreenRotationAnimation(Context context, DisplayContent displayContent,
+            SurfaceSession session, boolean inTransaction, boolean forceDefaultOrientation) {
         mContext = context;
-        mDisplay = display;
+        mDisplayContent = displayContent;
+        displayContent.getLogicalDisplayRect(mOriginalDisplayRect);
 
         // Screenshot does NOT include rotation!
+        final Display display = displayContent.getDisplay();
+        int originalRotation = display.getRotation();
+        final int originalWidth;
+        final int originalHeight;
+        DisplayInfo displayInfo = displayContent.getDisplayInfo();
+        if (forceDefaultOrientation) {
+            // Emulated orientation.
+            mForceDefaultOrientation = true;
+            originalWidth = displayContent.mBaseDisplayWidth;
+            originalHeight = displayContent.mBaseDisplayHeight;
+        } else {
+            // Normal situation
+            originalWidth = displayInfo.logicalWidth;
+            originalHeight = displayInfo.logicalHeight;
+        }
         if (originalRotation == Surface.ROTATION_90
                 || originalRotation == Surface.ROTATION_270) {
             mWidth = originalHeight;
@@ -219,6 +245,8 @@
                     mSurfaceControl = new SurfaceTrace(session, "ScreenshotSurface",
                             mWidth, mHeight,
                             PixelFormat.OPAQUE, SurfaceControl.HIDDEN);
+                    Slog.w(TAG, "ScreenRotationAnimation ctor: displayOffset="
+                            + mOriginalDisplayRect.toShortString());
                 } else {
                     mSurfaceControl = new SurfaceControl(session, "ScreenshotSurface",
                             mWidth, mHeight,
@@ -230,12 +258,12 @@
                 // FIXME: we should use the proper display
                 SurfaceControl.screenshot(SurfaceControl.getBuiltInDisplay(
                         SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN), sur);
-                mSurfaceControl.setLayerStack(mDisplay.getLayerStack());
+                mSurfaceControl.setLayerStack(display.getLayerStack());
                 mSurfaceControl.setLayer(FREEZE_LAYER + 1);
                 mSurfaceControl.setAlpha(0);
                 mSurfaceControl.show();
                 sur.destroy();
-            } catch (SurfaceControl.OutOfResourcesException e) {
+            } catch (OutOfResourcesException e) {
                 Slog.w(TAG, "Unable to allocate freeze surface", e);
             }
 
@@ -266,7 +294,14 @@
     private void setSnapshotTransformInTransaction(Matrix matrix, float alpha) {
         if (mSurfaceControl != null) {
             matrix.getValues(mTmpFloats);
-            mSurfaceControl.setPosition(mTmpFloats[Matrix.MTRANS_X], mTmpFloats[Matrix.MTRANS_Y]);
+            float x = mTmpFloats[Matrix.MTRANS_X];
+            float y = mTmpFloats[Matrix.MTRANS_Y];
+            if (mForceDefaultOrientation) {
+                mDisplayContent.getLogicalDisplayRect(mCurrentDisplayRect);
+                x -= mCurrentDisplayRect.left;
+                y -= mCurrentDisplayRect.top;
+            }
+            mSurfaceControl.setPosition(x, y);
             mSurfaceControl.setMatrix(
                     mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y],
                     mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]);
@@ -491,7 +526,7 @@
             mRotateFrameAnimation.scaleCurrentDuration(animationScale);
         }
 
-        final int layerStack = mDisplay.getLayerStack();
+        final int layerStack = mDisplayContent.getDisplay().getLayerStack();
         if (USE_CUSTOM_BLACK_FRAME && mCustomBlackFrame == null) {
             if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
                     WindowManagerService.TAG,
@@ -511,9 +546,9 @@
                         mOriginalWidth*2, mOriginalHeight*2);
                 Rect inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
                 mCustomBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER + 3,
-                        layerStack);
+                        layerStack, false);
                 mCustomBlackFrame.setMatrix(mFrameInitialMatrix);
-            } catch (SurfaceControl.OutOfResourcesException e) {
+            } catch (OutOfResourcesException e) {
                 Slog.w(TAG, "Unable to allocate black surface", e);
             } finally {
                 SurfaceControl.closeTransaction();
@@ -537,13 +572,23 @@
                 // we were last in.
                 createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix);
 
-                Rect outer = new Rect(-mOriginalWidth*1, -mOriginalHeight*1,
-                        mOriginalWidth*2, mOriginalHeight*2);
-                Rect inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
+                final Rect outer;
+                final Rect inner;
+                if (mForceDefaultOrientation) {
+                    // Going from a smaller Display to a larger Display, add curtains to sides
+                    // or top and bottom. Going from a larger to smaller display will result in
+                    // no BlackSurfaces being constructed.
+                    outer = mCurrentDisplayRect;
+                    inner = mOriginalDisplayRect;
+                } else {
+                    outer = new Rect(-mOriginalWidth*1, -mOriginalHeight*1,
+                            mOriginalWidth*2, mOriginalHeight*2);
+                    inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
+                }
                 mExitingBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER + 2,
-                        layerStack);
+                        layerStack, mForceDefaultOrientation);
                 mExitingBlackFrame.setMatrix(mFrameInitialMatrix);
-            } catch (SurfaceControl.OutOfResourcesException e) {
+            } catch (OutOfResourcesException e) {
                 Slog.w(TAG, "Unable to allocate black surface", e);
             } finally {
                 SurfaceControl.closeTransaction();
@@ -564,8 +609,8 @@
                         finalWidth*2, finalHeight*2);
                 Rect inner = new Rect(0, 0, finalWidth, finalHeight);
                 mEnteringBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER,
-                        layerStack);
-            } catch (SurfaceControl.OutOfResourcesException e) {
+                        layerStack, false);
+            } catch (OutOfResourcesException e) {
                 Slog.w(TAG, "Unable to allocate black surface", e);
             } finally {
                 SurfaceControl.closeTransaction();
@@ -850,7 +895,7 @@
                     && (mMoreStartEnter || mMoreStartExit || mMoreFinishEnter || mMoreFinishExit))
                 || (USE_CUSTOM_BLACK_FRAME
                         && (mMoreStartFrame || mMoreRotateFrame || mMoreFinishFrame))
-                || mMoreRotateEnter || mMoreRotateExit 
+                || mMoreRotateEnter || mMoreRotateExit
                 || !mFinishAnimReady;
 
         mSnapshotFinalMatrix.setConcat(mExitTransformation.getMatrix(), mSnapshotInitialMatrix);
@@ -888,6 +933,9 @@
             } else {
                 mExitFrameFinalMatrix.setConcat(mExitTransformation.getMatrix(), mFrameInitialMatrix);
                 mExitingBlackFrame.setMatrix(mExitFrameFinalMatrix);
+                if (mForceDefaultOrientation) {
+                    mExitingBlackFrame.setAlpha(mExitTransformation.getAlpha());
+                }
             }
         }
 
diff --git a/services/java/com/android/server/wm/StackBox.java b/services/java/com/android/server/wm/StackBox.java
new file mode 100644
index 0000000..d054e9a
--- /dev/null
+++ b/services/java/com/android/server/wm/StackBox.java
@@ -0,0 +1,418 @@
+/*
+ * 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.server.wm;
+
+import android.graphics.Rect;
+import android.util.Slog;
+
+import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
+import static com.android.server.wm.WindowManagerService.DEBUG_STACK;
+import static com.android.server.wm.WindowManagerService.TAG;
+
+import java.io.PrintWriter;
+
+public class StackBox {
+    /** Used with {@link WindowManagerService#createStack}. Dependent on Configuration LTR/RTL. */
+    public static final int TASK_STACK_GOES_BEFORE = 0;
+    /** Used with {@link WindowManagerService#createStack}. Dependent on Configuration LTR/RTL. */
+    public static final int TASK_STACK_GOES_AFTER = 1;
+    /** Used with {@link WindowManagerService#createStack}. Horizontal to left of. */
+    public static final int TASK_STACK_TO_LEFT_OF = 2;
+    /** Used with {@link WindowManagerService#createStack}. Horizontal to right of. */
+    public static final int TASK_STACK_TO_RIGHT_OF = 3;
+    /** Used with {@link WindowManagerService#createStack}. Vertical: lower t/b Rect values. */
+    public static final int TASK_STACK_GOES_ABOVE = 4;
+    /** Used with {@link WindowManagerService#createStack}. Vertical: higher t/b Rect values. */
+    public static final int TASK_STACK_GOES_BELOW = 5;
+    /** Used with {@link WindowManagerService#createStack}. Put on a higher layer on display. */
+    public static final int TASK_STACK_GOES_OVER = 6;
+    /** Used with {@link WindowManagerService#createStack}. Put on a lower layer on display. */
+    public static final int TASK_STACK_GOES_UNDER = 7;
+
+    static int sCurrentBoxId = 0;
+
+    /** Unique id for this box */
+    final int mStackBoxId;
+
+    /** The service */
+    final WindowManagerService mService;
+
+    /** The display this box sits in. */
+    final DisplayContent mDisplayContent;
+
+    /** Non-null indicates this is mFirst or mSecond of a parent StackBox. Null indicates this
+     * is this entire size of mDisplayContent. */
+    StackBox mParent;
+
+    /** First child, this is null exactly when mStack is non-null. */
+    StackBox mFirst;
+
+    /** Second child, this is null exactly when mStack is non-null. */
+    StackBox mSecond;
+
+    /** Stack of Tasks, this is null exactly when mFirst and mSecond are non-null. */
+    TaskStack mStack;
+
+    /** Content limits relative to the DisplayContent this sits in. */
+    Rect mBounds = new Rect();
+
+    /** Relative orientation of mFirst and mSecond. */
+    boolean mVertical;
+
+    /** Fraction of mBounds to devote to mFirst, remainder goes to mSecond */
+    float mWeight;
+
+    /** Dirty flag. Something inside this or some descendant of this has changed. */
+    boolean layoutNeeded;
+
+    /** True if this StackBox sits below the Status Bar. */
+    boolean mUnderStatusBar;
+
+    /** Used to keep from reallocating a temporary Rect for propagating bounds to child boxes */
+    Rect mTmpRect = new Rect();
+
+    StackBox(WindowManagerService service, DisplayContent displayContent, StackBox parent) {
+        synchronized (StackBox.class) {
+            mStackBoxId = sCurrentBoxId++;
+        }
+
+        mService = service;
+        mDisplayContent = displayContent;
+        mParent = parent;
+    }
+
+    /** Propagate #layoutNeeded bottom up. */
+    void makeDirty() {
+        layoutNeeded = true;
+        if (mParent != null) {
+            mParent.makeDirty();
+        }
+    }
+
+    /**
+     * Determine if a particular StackBox is this one or a descendant of this one.
+     * @param stackBoxId The StackBox being searched for.
+     * @return true if the specified StackBox matches this or one of its descendants.
+     */
+    boolean contains(int stackBoxId) {
+        return mStackBoxId == stackBoxId ||
+                (mStack == null &&  (mFirst.contains(stackBoxId) || mSecond.contains(stackBoxId)));
+    }
+
+    /**
+     * Return the stackId of the stack that intersects the passed point.
+     * @param x coordinate of point.
+     * @param y coordinate of point.
+     * @return -1 if point is outside of mBounds, otherwise the stackId of the containing stack.
+     */
+    int stackIdFromPoint(int x, int y) {
+        if (!mBounds.contains(x, y)) {
+            return -1;
+        }
+        if (mStack != null) {
+            return mStack.mStackId;
+        }
+        int stackId = mFirst.stackIdFromPoint(x, y);
+        if (stackId >= 0) {
+            return stackId;
+        }
+        return mSecond.stackIdFromPoint(x, y);
+    }
+
+    /** Determine if this StackBox is the first child or second child.
+     * @return true if this is the first child.
+     */
+    boolean isFirstChild() {
+        return mParent != null && mParent.mFirst == this;
+    }
+
+    /** Returns the bounds of the specified TaskStack if it is contained in this StackBox.
+     * @param stackId the TaskStack to find the bounds of.
+     * @return a new Rect with the bounds of stackId if it is within this StackBox, null otherwise.
+     */
+    Rect getStackBounds(int stackId) {
+        if (mStack != null) {
+            return mStack.mStackId == stackId ? new Rect(mBounds) : null;
+        }
+        Rect bounds = mFirst.getStackBounds(stackId);
+        if (bounds != null) {
+            return bounds;
+        }
+        return mSecond.getStackBounds(stackId);
+    }
+
+    /**
+     * Create a new TaskStack relative to a specified one by splitting the StackBox containing
+     * the specified TaskStack into two children. The size and position each of the new StackBoxes
+     * is determined by the passed parameters.
+     * @param stackId The id of the new TaskStack to create.
+     * @param relativeStackBoxId The id of the StackBox to place the new TaskStack next to.
+     * @param position One of the static TASK_STACK_GOES_xxx positions defined in this class.
+     * @param weight The percentage size of the parent StackBox to devote to the new TaskStack.
+     * @return The new TaskStack.
+     */
+    TaskStack split(int stackId, int relativeStackBoxId, int position, float weight) {
+        if (mStackBoxId != relativeStackBoxId) {
+            // This is not the targeted StackBox.
+            if (mStack != null) {
+                return null;
+            }
+            // Propagate the split to see if the targeted StackBox is in either sub box.
+            TaskStack stack = mFirst.split(stackId, relativeStackBoxId, position, weight);
+            if (stack != null) {
+                return stack;
+            }
+            return mSecond.split(stackId, relativeStackBoxId, position, weight);
+        }
+
+        // Found it!
+        TaskStack stack = new TaskStack(mService, stackId, mDisplayContent);
+        TaskStack firstStack;
+        TaskStack secondStack;
+        if (position == TASK_STACK_GOES_BEFORE) {
+            // TODO: Test Configuration here for LTR/RTL.
+            position = TASK_STACK_TO_LEFT_OF;
+        } else if (position == TASK_STACK_GOES_AFTER) {
+            // TODO: Test Configuration here for LTR/RTL.
+            position = TASK_STACK_TO_RIGHT_OF;
+        }
+        switch (position) {
+            default:
+            case TASK_STACK_TO_LEFT_OF:
+            case TASK_STACK_TO_RIGHT_OF:
+                mVertical = false;
+                if (position == TASK_STACK_TO_LEFT_OF) {
+                    mWeight = weight;
+                    firstStack = stack;
+                    secondStack = mStack;
+                } else {
+                    mWeight = 1.0f - weight;
+                    firstStack = mStack;
+                    secondStack = stack;
+                }
+                break;
+            case TASK_STACK_GOES_ABOVE:
+            case TASK_STACK_GOES_BELOW:
+                mVertical = true;
+                if (position == TASK_STACK_GOES_ABOVE) {
+                    mWeight = weight;
+                    firstStack = stack;
+                    secondStack = mStack;
+                } else {
+                    mWeight = 1.0f - weight;
+                    firstStack = mStack;
+                    secondStack = stack;
+                }
+                break;
+        }
+
+        mFirst = new StackBox(mService, mDisplayContent, this);
+        firstStack.mStackBox = mFirst;
+        mFirst.mStack = firstStack;
+
+        mSecond = new StackBox(mService, mDisplayContent, this);
+        secondStack.mStackBox = mSecond;
+        mSecond.mStack = secondStack;
+
+        mStack = null;
+        return stack;
+    }
+
+    /** Return the stackId of the first mFirst StackBox with a non-null mStack */
+    int getStackId() {
+        if (mStack != null) {
+            return mStack.mStackId;
+        }
+        return mFirst.getStackId();
+    }
+
+    /** Remove this box and propagate its sibling's content up to their parent.
+     * @return The first stackId of the resulting StackBox. */
+    int remove() {
+        if (mStack != null) {
+            if (DEBUG_STACK) Slog.i(TAG, "StackBox.remove: removing stackId=" + mStack.mStackId);
+            mDisplayContent.mStackHistory.remove(mStack);
+        }
+        mDisplayContent.layoutNeeded = true;
+
+        if (mParent == null) {
+            // This is the top-plane stack.
+            if (DEBUG_STACK) Slog.i(TAG, "StackBox.remove: removing top plane.");
+            mDisplayContent.removeStackBox(this);
+            return HOME_STACK_ID;
+        }
+
+        StackBox sibling = isFirstChild() ? mParent.mSecond : mParent.mFirst;
+        StackBox grandparent = mParent.mParent;
+        sibling.mParent = grandparent;
+        if (grandparent == null) {
+            // mParent is a top-plane stack. Now sibling will be.
+            if (DEBUG_STACK) Slog.i(TAG, "StackBox.remove: grandparent null");
+            mDisplayContent.removeStackBox(mParent);
+            mDisplayContent.addStackBox(sibling, true);
+        } else {
+            if (DEBUG_STACK) Slog.i(TAG, "StackBox.remove: grandparent getting sibling");
+            if (mParent.isFirstChild()) {
+                grandparent.mFirst = sibling;
+            } else {
+                grandparent.mSecond = sibling;
+            }
+        }
+        return sibling.getStackId();
+    }
+
+    boolean resize(int stackBoxId, float weight) {
+        if (mStackBoxId != stackBoxId) {
+            return mStack == null &&
+                    (mFirst.resize(stackBoxId, weight) || mSecond.resize(stackBoxId, weight));
+        }
+        // Don't change weight on topmost stack.
+        if (mParent != null) {
+            mParent.mWeight = isFirstChild() ? weight : 1.0f - weight;
+        }
+        return true;
+    }
+
+    /** If this is a terminal StackBox (contains a TaskStack) set the bounds.
+     * @param bounds The rectangle to set the bounds to.
+     * @param underStatusBar True if the StackBox is directly below the Status Bar.
+     * @return True if the bounds changed, false otherwise. */
+    boolean setStackBoxSizes(Rect bounds, boolean underStatusBar) {
+        boolean change = false;
+        if (mUnderStatusBar != underStatusBar) {
+            change = true;
+            mUnderStatusBar = underStatusBar;
+        }
+        if (mStack != null) {
+            change |= !mBounds.equals(bounds);
+            if (change) {
+                mBounds.set(bounds);
+                mStack.setBounds(bounds, underStatusBar);
+            }
+        } else {
+            mTmpRect.set(bounds);
+            if (mVertical) {
+                final int height = bounds.height();
+                int firstHeight = (int)(height * mWeight);
+                mTmpRect.bottom = bounds.top + firstHeight;
+                change |= mFirst.setStackBoxSizes(mTmpRect, underStatusBar);
+                mTmpRect.top = mTmpRect.bottom;
+                mTmpRect.bottom = bounds.top + height;
+                change |= mSecond.setStackBoxSizes(mTmpRect, false);
+            } else {
+                final int width = bounds.width();
+                int firstWidth = (int)(width * mWeight);
+                mTmpRect.right = bounds.left + firstWidth;
+                change |= mFirst.setStackBoxSizes(mTmpRect, underStatusBar);
+                mTmpRect.left = mTmpRect.right;
+                mTmpRect.right = bounds.left + width;
+                change |= mSecond.setStackBoxSizes(mTmpRect, underStatusBar);
+            }
+        }
+        return change;
+    }
+
+    void resetAnimationBackgroundAnimator() {
+        if (mStack != null) {
+            mStack.resetAnimationBackgroundAnimator();
+            return;
+        }
+        mFirst.resetAnimationBackgroundAnimator();
+        mSecond.resetAnimationBackgroundAnimator();
+    }
+
+    boolean animateDimLayers() {
+        if (mStack != null) {
+            return mStack.animateDimLayers();
+        }
+        boolean result = mFirst.animateDimLayers();
+        result |= mSecond.animateDimLayers();
+        return result;
+    }
+
+    void resetDimming() {
+        if (mStack != null) {
+            mStack.resetDimmingTag();
+            return;
+        }
+        mFirst.resetDimming();
+        mSecond.resetDimming();
+    }
+
+    boolean isDimming() {
+        if (mStack != null) {
+            return mStack.isDimming();
+        }
+        boolean result = mFirst.isDimming();
+        result |= mSecond.isDimming();
+        return result;
+    }
+
+    void stopDimmingIfNeeded() {
+        if (mStack != null) {
+            mStack.stopDimmingIfNeeded();
+            return;
+        }
+        mFirst.stopDimmingIfNeeded();
+        mSecond.stopDimmingIfNeeded();
+    }
+
+    void switchUserStacks(int userId) {
+        if (mStack != null) {
+            mStack.switchUser(userId);
+            return;
+        }
+        mFirst.switchUserStacks(userId);
+        mSecond.switchUserStacks(userId);
+    }
+
+    void close() {
+        if (mStack != null) {
+            mStack.mDimLayer.mDimSurface.destroy();
+            mStack.mAnimationBackgroundSurface.mDimSurface.destroy();
+            return;
+        }
+        mFirst.close();
+        mSecond.close();
+    }
+
+    public void dump(String prefix, PrintWriter pw) {
+        pw.print(prefix); pw.print("mParent="); pw.println(mParent);
+        pw.print(prefix); pw.print("mBounds="); pw.print(mBounds.toShortString());
+            pw.print(" mVertical="); pw.print(mVertical);
+            pw.print(" layoutNeeded="); pw.println(layoutNeeded);
+        if (mFirst != null) {
+            pw.print(prefix); pw.print("mFirst="); pw.println(System.identityHashCode(mFirst));
+            mFirst.dump(prefix + "  ", pw);
+            pw.print(prefix); pw.print("mSecond="); pw.println(System.identityHashCode(mSecond));
+            mSecond.dump(prefix + "  ", pw);
+        } else {
+            pw.print(prefix); pw.print("mStack="); pw.println(mStack);
+            mStack.dump(prefix + "  ", pw);
+        }
+    }
+
+    @Override
+    public String toString() {
+        if (mStack != null) {
+            return "Box{" + hashCode() + " stack=" + mStack.mStackId + "}";
+        }
+        return "Box{" + hashCode() + " parent=" + System.identityHashCode(mParent)
+                + " first=" + System.identityHashCode(mFirst)
+                + " second=" + System.identityHashCode(mSecond) + "}";
+    }
+}
diff --git a/services/java/com/android/server/wm/StackTapPointerEventListener.java b/services/java/com/android/server/wm/StackTapPointerEventListener.java
new file mode 100644
index 0000000..19d8ab3
--- /dev/null
+++ b/services/java/com/android/server/wm/StackTapPointerEventListener.java
@@ -0,0 +1,87 @@
+/*
+ * 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.server.wm;
+
+import android.graphics.Region;
+import android.view.DisplayInfo;
+import android.view.MotionEvent;
+import android.view.WindowManagerPolicy.PointerEventListener;
+
+import com.android.server.wm.WindowManagerService.H;
+
+public class StackTapPointerEventListener implements PointerEventListener {
+    private static final int TAP_TIMEOUT_MSEC = 300;
+    private static final float TAP_MOTION_SLOP_INCHES = 0.125f;
+
+    private final int mMotionSlop;
+    private float mDownX;
+    private float mDownY;
+    private int mPointerId;
+    final private Region mTouchExcludeRegion;
+    private final WindowManagerService mService;
+    private final DisplayContent mDisplayContent;
+
+    public StackTapPointerEventListener(WindowManagerService service,
+            DisplayContent displayContent) {
+        mService = service;
+        mDisplayContent = displayContent;
+        mTouchExcludeRegion = displayContent.mTouchExcludeRegion;
+        DisplayInfo info = displayContent.getDisplayInfo();
+        mMotionSlop = (int)(info.logicalDensityDpi * TAP_MOTION_SLOP_INCHES);
+    }
+
+    @Override
+    public void onPointerEvent(MotionEvent motionEvent) {
+        final int action = motionEvent.getAction();
+        switch (action & MotionEvent.ACTION_MASK) {
+            case MotionEvent.ACTION_DOWN:
+                mPointerId = motionEvent.getPointerId(0);
+                mDownX = motionEvent.getX();
+                mDownY = motionEvent.getY();
+                break;
+            case MotionEvent.ACTION_MOVE:
+                if (mPointerId >= 0) {
+                    int index = motionEvent.findPointerIndex(mPointerId);
+                    if ((motionEvent.getEventTime() - motionEvent.getDownTime()) > TAP_TIMEOUT_MSEC
+                            || (motionEvent.getX(index) - mDownX) > mMotionSlop
+                            || (motionEvent.getY(index) - mDownY) > mMotionSlop) {
+                        mPointerId = -1;
+                    }
+                }
+                break;
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_POINTER_UP: {
+                int index = (action & MotionEvent.ACTION_POINTER_INDEX_MASK)
+                        >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+                // Extract the index of the pointer that left the touch sensor
+                if (mPointerId == motionEvent.getPointerId(index)) {
+                    final int x = (int)motionEvent.getX(index);
+                    final int y = (int)motionEvent.getY(index);
+                    if ((motionEvent.getEventTime() - motionEvent.getDownTime())
+                            < TAP_TIMEOUT_MSEC
+                            && (x - mDownX) < mMotionSlop && (y - mDownY) < mMotionSlop
+                            && !mTouchExcludeRegion.contains(x, y)) {
+                        mService.mH.obtainMessage(H.TAP_OUTSIDE_STACK, x, y,
+                                mDisplayContent).sendToTarget();
+                    }
+                    mPointerId = -1;
+                }
+                break;
+            }
+        }
+    }
+}
diff --git a/services/java/com/android/server/wm/StartingData.java b/services/java/com/android/server/wm/StartingData.java
index 46bb480..7115b0f 100644
--- a/services/java/com/android/server/wm/StartingData.java
+++ b/services/java/com/android/server/wm/StartingData.java
@@ -25,17 +25,19 @@
     final CharSequence nonLocalizedLabel;
     final int labelRes;
     final int icon;
+    final int logo;
     final int windowFlags;
 
     StartingData(String _pkg, int _theme, CompatibilityInfo _compatInfo,
             CharSequence _nonLocalizedLabel,
-            int _labelRes, int _icon, int _windowFlags) {
+            int _labelRes, int _icon, int _logo, int _windowFlags) {
         pkg = _pkg;
         theme = _theme;
         compatInfo = _compatInfo;
         nonLocalizedLabel = _nonLocalizedLabel;
         labelRes = _labelRes;
         icon = _icon;
+        logo = _logo;
         windowFlags = _windowFlags;
     }
 }
\ No newline at end of file
diff --git a/services/java/com/android/server/wm/StrictModeFlash.java b/services/java/com/android/server/wm/StrictModeFlash.java
index 31628e3..fb5876b 100644
--- a/services/java/com/android/server/wm/StrictModeFlash.java
+++ b/services/java/com/android/server/wm/StrictModeFlash.java
@@ -23,6 +23,7 @@
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.view.Display;
+import android.view.Surface.OutOfResourcesException;
 import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
@@ -47,7 +48,7 @@
             ctrl.setPosition(0, 0);
             ctrl.show();
             mSurface.copyFrom(ctrl);
-        } catch (SurfaceControl.OutOfResourcesException e) {
+        } catch (OutOfResourcesException e) {
         }
         mSurfaceControl = ctrl;
         mDrawNeeded = true;
diff --git a/services/java/com/android/server/wm/Task.java b/services/java/com/android/server/wm/Task.java
new file mode 100644
index 0000000..d9acbb9
--- /dev/null
+++ b/services/java/com/android/server/wm/Task.java
@@ -0,0 +1,54 @@
+/*
+ * 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.server.wm;
+
+class Task {
+//    private final String TAG = "TaskGroup";
+    TaskStack mStack;
+    final AppTokenList mAppTokens = new AppTokenList();
+    final int taskId;
+    final int mUserId;
+
+    Task(AppWindowToken wtoken, TaskStack stack, int userId) {
+        taskId = wtoken.groupId;
+        mAppTokens.add(wtoken);
+        mStack = stack;
+        mUserId = userId;
+    }
+
+    DisplayContent getDisplayContent() {
+        return mStack.getDisplayContent();
+    }
+
+    void addAppToken(int addPos, AppWindowToken wtoken) {
+        mAppTokens.add(addPos, wtoken);
+    }
+
+    boolean removeAppToken(AppWindowToken wtoken) {
+        mAppTokens.remove(wtoken);
+        if (mAppTokens.size() == 0) {
+            mStack.removeTask(this);
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return "{taskId=" + taskId + " appTokens=" + mAppTokens + "}";
+    }
+}
diff --git a/services/java/com/android/server/wm/TaskGroup.java b/services/java/com/android/server/wm/TaskGroup.java
new file mode 100644
index 0000000..1f1dd58
--- /dev/null
+++ b/services/java/com/android/server/wm/TaskGroup.java
@@ -0,0 +1,31 @@
+/*
+ * 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.server.wm;
+
+import android.view.IApplicationToken;
+
+import java.util.ArrayList;
+
+public class TaskGroup {
+    public int taskId = -1;
+    public ArrayList<IApplicationToken> tokens = new ArrayList<IApplicationToken>();
+
+    @Override
+    public String toString() {
+        return "id=" + taskId + " tokens=" + tokens;
+    }
+}
diff --git a/services/java/com/android/server/wm/TaskStack.java b/services/java/com/android/server/wm/TaskStack.java
new file mode 100644
index 0000000..7bb6734
--- /dev/null
+++ b/services/java/com/android/server/wm/TaskStack.java
@@ -0,0 +1,310 @@
+/*
+ * 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.server.wm;
+
+import static com.android.server.wm.WindowManagerService.DEBUG_TASK_MOVEMENT;
+import static com.android.server.wm.WindowManagerService.TAG;
+
+import android.graphics.Rect;
+import android.os.Debug;
+import android.util.Slog;
+import android.util.TypedValue;
+
+import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+public class TaskStack {
+    /** Amount of time in milliseconds to animate the dim surface from one value to another,
+     * when no window animation is driving it. */
+    private static final int DEFAULT_DIM_DURATION = 200;
+
+    /** Unique identifier */
+    final int mStackId;
+
+    /** The service */
+    private final WindowManagerService mService;
+
+    /** The display this stack sits under. */
+    private final DisplayContent mDisplayContent;
+
+    /** The Tasks that define this stack. Oldest Tasks are at the bottom. The ordering must match
+     * mTaskHistory in the ActivityStack with the same mStackId */
+    private ArrayList<Task> mTasks = new ArrayList<Task>();
+
+    /** The StackBox this sits in. */
+    StackBox mStackBox;
+
+    /** Used to support {@link android.view.WindowManager.LayoutParams#FLAG_DIM_BEHIND} */
+    final DimLayer mDimLayer;
+
+    /** The particular window with FLAG_DIM_BEHIND set. If null, hide mDimLayer. */
+    WindowStateAnimator mDimWinAnimator;
+
+    /** Support for non-zero {@link android.view.animation.Animation#getBackgroundColor()} */
+    final DimLayer mAnimationBackgroundSurface;
+
+    /** The particular window with an Animation with non-zero background color. */
+    WindowStateAnimator mAnimationBackgroundAnimator;
+
+    /** Set to false at the start of performLayoutAndPlaceSurfaces. If it is still false by the end
+     * then stop any dimming. */
+    boolean mDimmingTag;
+
+    TaskStack(WindowManagerService service, int stackId, DisplayContent displayContent) {
+        mService = service;
+        mStackId = stackId;
+        mDisplayContent = displayContent;
+        final int displayId = displayContent.getDisplayId();
+        mDimLayer = new DimLayer(service, displayContent);
+        mAnimationBackgroundSurface = new DimLayer(service, displayContent);
+    }
+
+    DisplayContent getDisplayContent() {
+        return mDisplayContent;
+    }
+
+    ArrayList<Task> getTasks() {
+        return mTasks;
+    }
+
+    boolean isHomeStack() {
+        return mStackId == HOME_STACK_ID;
+    }
+
+    boolean hasSibling() {
+        return mStackBox.mParent != null;
+    }
+
+    /**
+     * Put a Task in this stack. Used for adding and moving.
+     * @param task The task to add.
+     * @param toTop Whether to add it to the top or bottom.
+     */
+    boolean addTask(Task task, boolean toTop) {
+        mStackBox.makeDirty();
+
+        int stackNdx;
+        if (!toTop) {
+            stackNdx = 0;
+        } else {
+            stackNdx = mTasks.size();
+            final int currentUserId = mService.mCurrentUserId;
+            if (task.mUserId != currentUserId) {
+                // Place the task below all current user tasks.
+                while (--stackNdx >= 0) {
+                    if (currentUserId != mTasks.get(stackNdx).mUserId) {
+                        break;
+                    }
+                }
+                ++stackNdx;
+            }
+        }
+        if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "addTask: task=" + task + " toTop=" + toTop
+                + " pos=" + stackNdx);
+        mTasks.add(stackNdx, task);
+
+        task.mStack = this;
+        return mDisplayContent.moveHomeStackBox(mStackId == HOME_STACK_ID);
+    }
+
+    boolean moveTaskToTop(Task task) {
+        if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "moveTaskToTop: task=" + task + " Callers="
+                + Debug.getCallers(6));
+        mTasks.remove(task);
+        return addTask(task, true);
+    }
+
+    boolean moveTaskToBottom(Task task) {
+        if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "moveTaskToBottom: task=" + task);
+        mTasks.remove(task);
+        return addTask(task, false);
+    }
+
+    /**
+     * Delete a Task from this stack. If it is the last Task in the stack, remove this stack from
+     * its parent StackBox and merge the parent.
+     * @param task The Task to delete.
+     */
+    void removeTask(Task task) {
+        if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "removeTask: task=" + task);
+        mStackBox.makeDirty();
+        mTasks.remove(task);
+    }
+
+    int remove() {
+        mAnimationBackgroundSurface.destroySurface();
+        mDimLayer.destroySurface();
+        return mStackBox.remove();
+    }
+
+    void resetAnimationBackgroundAnimator() {
+        mAnimationBackgroundAnimator = null;
+        mAnimationBackgroundSurface.hide();
+    }
+
+    private long getDimBehindFadeDuration(long duration) {
+        TypedValue tv = new TypedValue();
+        mService.mContext.getResources().getValue(
+                com.android.internal.R.fraction.config_dimBehindFadeDuration, tv, true);
+        if (tv.type == TypedValue.TYPE_FRACTION) {
+            duration = (long)tv.getFraction(duration, duration);
+        } else if (tv.type >= TypedValue.TYPE_FIRST_INT && tv.type <= TypedValue.TYPE_LAST_INT) {
+            duration = tv.data;
+        }
+        return duration;
+    }
+
+    boolean animateDimLayers() {
+        final int dimLayer;
+        final float dimAmount;
+        if (mDimWinAnimator == null) {
+            dimLayer = mDimLayer.getLayer();
+            dimAmount = 0;
+        } else {
+            dimLayer = mDimWinAnimator.mAnimLayer - WindowManagerService.LAYER_OFFSET_DIM;
+            dimAmount = mDimWinAnimator.mWin.mAttrs.dimAmount;
+        }
+        final float targetAlpha = mDimLayer.getTargetAlpha();
+        if (targetAlpha != dimAmount) {
+            if (mDimWinAnimator == null) {
+                mDimLayer.hide(DEFAULT_DIM_DURATION);
+            } else {
+                long duration = (mDimWinAnimator.mAnimating && mDimWinAnimator.mAnimation != null)
+                        ? mDimWinAnimator.mAnimation.computeDurationHint()
+                        : DEFAULT_DIM_DURATION;
+                if (targetAlpha > dimAmount) {
+                    duration = getDimBehindFadeDuration(duration);
+                }
+                mDimLayer.show(dimLayer, dimAmount, duration);
+            }
+        } else if (mDimLayer.getLayer() != dimLayer) {
+            mDimLayer.setLayer(dimLayer);
+        }
+        if (mDimLayer.isAnimating()) {
+            if (!mService.okToDisplay()) {
+                // Jump to the end of the animation.
+                mDimLayer.show();
+            } else {
+                return mDimLayer.stepAnimation();
+            }
+        }
+        return false;
+    }
+
+    void resetDimmingTag() {
+        mDimmingTag = false;
+    }
+
+    void setDimmingTag() {
+        mDimmingTag = true;
+    }
+
+    boolean testDimmingTag() {
+        return mDimmingTag;
+    }
+
+    boolean isDimming() {
+        return mDimLayer.isDimming();
+    }
+
+    boolean isDimming(WindowStateAnimator winAnimator) {
+        return mDimWinAnimator == winAnimator && mDimLayer.isDimming();
+    }
+
+    void startDimmingIfNeeded(WindowStateAnimator newWinAnimator) {
+        // Only set dim params on the highest dimmed layer.
+        final WindowStateAnimator existingDimWinAnimator = mDimWinAnimator;
+        // Don't turn on for an unshown surface, or for any layer but the highest dimmed layer.
+        if (newWinAnimator.mSurfaceShown && (existingDimWinAnimator == null
+                || !existingDimWinAnimator.mSurfaceShown
+                || existingDimWinAnimator.mAnimLayer < newWinAnimator.mAnimLayer)) {
+            mDimWinAnimator = newWinAnimator;
+        }
+    }
+
+    void stopDimmingIfNeeded() {
+        if (!mDimmingTag && isDimming()) {
+            mDimWinAnimator = null;
+        }
+    }
+
+    void setAnimationBackground(WindowStateAnimator winAnimator, int color) {
+        int animLayer = winAnimator.mAnimLayer;
+        if (mAnimationBackgroundAnimator == null
+                || animLayer < mAnimationBackgroundAnimator.mAnimLayer) {
+            mAnimationBackgroundAnimator = winAnimator;
+            animLayer = mService.adjustAnimationBackground(winAnimator);
+            mAnimationBackgroundSurface.show(animLayer - WindowManagerService.LAYER_OFFSET_DIM,
+                    ((color >> 24) & 0xff) / 255f, 0);
+        }
+    }
+
+    void setBounds(Rect bounds, boolean underStatusBar) {
+        mDimLayer.setBounds(bounds);
+        mAnimationBackgroundSurface.setBounds(bounds);
+
+        final ArrayList<WindowState> resizingWindows = mService.mResizingWindows;
+        for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
+            final ArrayList<AppWindowToken> activities = mTasks.get(taskNdx).mAppTokens;
+            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+                final ArrayList<WindowState> windows = activities.get(activityNdx).allAppWindows;
+                for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
+                    final WindowState win = windows.get(winNdx);
+                    if (!resizingWindows.contains(win)) {
+                        resizingWindows.add(win);
+                    }
+                    win.mUnderStatusBar = underStatusBar;
+                }
+            }
+        }
+    }
+
+    void switchUser(int userId) {
+        int top = mTasks.size();
+        for (int taskNdx = 0; taskNdx < top; ++taskNdx) {
+            Task task = mTasks.get(taskNdx);
+            if (task.mUserId == userId) {
+                mTasks.remove(taskNdx);
+                mTasks.add(task);
+                --top;
+            }
+        }
+    }
+
+    public void dump(String prefix, PrintWriter pw) {
+        pw.print(prefix); pw.print("mStackId="); pw.println(mStackId);
+        for (int taskNdx = 0; taskNdx < mTasks.size(); ++taskNdx) {
+            pw.print(prefix); pw.println(mTasks.get(taskNdx));
+        }
+        if (mAnimationBackgroundSurface.isDimming()) {
+            pw.print(prefix); pw.println("mWindowAnimationBackgroundSurface:");
+            mAnimationBackgroundSurface.printTo(prefix + "  ", pw);
+        }
+        if (mDimLayer.isDimming()) {
+            pw.print(prefix); pw.println("mDimLayer:");
+            mDimLayer.printTo(prefix, pw);
+            pw.print(prefix); pw.print("mDimWinAnimator="); pw.println(mDimWinAnimator);
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "{stackId=" + mStackId + " tasks=" + mTasks + "}";
+    }
+}
diff --git a/services/java/com/android/server/wm/Watermark.java b/services/java/com/android/server/wm/Watermark.java
index fedd314..e226e3d 100644
--- a/services/java/com/android/server/wm/Watermark.java
+++ b/services/java/com/android/server/wm/Watermark.java
@@ -27,10 +27,10 @@
 import android.util.Log;
 import android.util.TypedValue;
 import android.view.Display;
+import android.view.Surface.OutOfResourcesException;
 import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
-import android.view.Surface.OutOfResourcesException;
 
 /**
  * Displays a watermark on top of the window manager's windows.
@@ -119,7 +119,7 @@
             ctrl.setPosition(0, 0);
             ctrl.show();
             mSurface.copyFrom(ctrl);
-        } catch (SurfaceControl.OutOfResourcesException e) {
+        } catch (OutOfResourcesException e) {
         }
         mSurfaceControl = ctrl;
     }
@@ -144,11 +144,11 @@
             try {
                 c = mSurface.lockCanvas(dirty);
             } catch (IllegalArgumentException e) {
-            } catch (OutOfResourcesException e) {
+            } catch (Surface.OutOfResourcesException e) {
             }
             if (c != null) {
                 c.drawColor(0, PorterDuff.Mode.CLEAR);
-                
+
                 int deltaX = mDeltaX;
                 int deltaY = mDeltaY;
 
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index 4252857..ca87b4f 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -19,9 +19,7 @@
 import android.util.SparseArray;
 import android.util.SparseIntArray;
 import android.util.TimeUtils;
-import android.util.TypedValue;
 import android.view.Display;
-import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.WindowManagerPolicy;
 import android.view.animation.Animation;
@@ -38,10 +36,6 @@
 public class WindowAnimator {
     private static final String TAG = "WindowAnimator";
 
-    /** Amount of time in milliseconds to animate the dim surface from one value to another,
-     * when no window animation is driving it. */
-    static final int DEFAULT_DIM_DURATION = 200;
-
     final WindowManagerService mService;
     final Context mContext;
     final WindowManagerPolicy mPolicy;
@@ -50,8 +44,6 @@
 
     final Runnable mAnimationRunnable;
 
-    int mAdjResult;
-
     /** Time of current animation step. Reset on each iteration */
     long mCurrentTime;
 
@@ -72,7 +64,7 @@
     Object mLastWindowFreezeSource;
 
     SparseArray<DisplayContentsAnimator> mDisplayContentsAnimators =
-            new SparseArray<WindowAnimator.DisplayContentsAnimator>();
+            new SparseArray<WindowAnimator.DisplayContentsAnimator>(2);
 
     boolean mInitialized = false;
 
@@ -120,18 +112,10 @@
     void removeDisplayLocked(final int displayId) {
         final DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.get(displayId);
         if (displayAnimator != null) {
-            if (displayAnimator.mWindowAnimationBackgroundSurface != null) {
-                displayAnimator.mWindowAnimationBackgroundSurface.destroySurface();
-                displayAnimator.mWindowAnimationBackgroundSurface = null;
-            }
             if (displayAnimator.mScreenRotationAnimation != null) {
                 displayAnimator.mScreenRotationAnimation.kill();
                 displayAnimator.mScreenRotationAnimation = null;
             }
-            if (displayAnimator.mDimAnimator != null) {
-                displayAnimator.mDimAnimator.destroySurface();
-                displayAnimator.mDimAnimator = null;
-            }
         }
 
         mDisplayContentsAnimators.delete(displayId);
@@ -172,28 +156,33 @@
         }
     }
 
-    private void updateAppWindowsLocked() {
-        int i;
-        final ArrayList<AppWindowToken> appTokens = mService.mAnimatingAppTokens;
-        final int NAT = appTokens.size();
-        for (i=0; i<NAT; i++) {
-            final AppWindowAnimator appAnimator = appTokens.get(i).mAppAnimator;
-            final boolean wasAnimating = appAnimator.animation != null
-                    && appAnimator.animation != AppWindowAnimator.sDummyAnimation;
-            if (appAnimator.stepAnimationLocked(mCurrentTime)) {
-                mAnimating = true;
-            } else if (wasAnimating) {
-                // stopped animating, do one more pass through the layout
-                setAppLayoutChanges(appAnimator, WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER,
-                        "appToken " + appAnimator.mAppToken + " done");
-                if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
-                        "updateWindowsApps...: done animating " + appAnimator.mAppToken);
+    private void updateAppWindowsLocked(int displayId) {
+        final DisplayContent displayContent = mService.getDisplayContentLocked(displayId);
+        final ArrayList<Task> tasks = displayContent.getTasks();
+        final int numTasks = tasks.size();
+        for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
+            final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
+            final int numTokens = tokens.size();
+            for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) {
+                final AppWindowAnimator appAnimator = tokens.get(tokenNdx).mAppAnimator;
+                final boolean wasAnimating = appAnimator.animation != null
+                        && appAnimator.animation != AppWindowAnimator.sDummyAnimation;
+                if (appAnimator.stepAnimationLocked(mCurrentTime)) {
+                    mAnimating = true;
+                } else if (wasAnimating) {
+                    // stopped animating, do one more pass through the layout
+                    setAppLayoutChanges(appAnimator, WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER,
+                            "appToken " + appAnimator.mAppToken + " done");
+                    if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
+                            "updateWindowsApps...: done animating " + appAnimator.mAppToken);
+                }
             }
         }
 
-        final int NEAT = mService.mExitingAppTokens.size();
-        for (i=0; i<NEAT; i++) {
-            final AppWindowAnimator appAnimator = mService.mExitingAppTokens.get(i).mAppAnimator;
+        final AppTokenList exitingAppTokens = displayContent.mExitingAppTokens;
+        final int NEAT = exitingAppTokens.size();
+        for (int i = 0; i < NEAT; i++) {
+            final AppWindowAnimator appAnimator = exitingAppTokens.get(i).mAppAnimator;
             final boolean wasAnimating = appAnimator.animation != null
                     && appAnimator.animation != AppWindowAnimator.sDummyAnimation;
             if (appAnimator.stepAnimationLocked(mCurrentTime)) {
@@ -299,10 +288,13 @@
                                     wallpaperInUnForceHiding = true;
                                 }
                             }
-                            if (mCurrentFocus == null || mCurrentFocus.mLayer < win.mLayer) {
+                            final WindowState currentFocus = mService.mCurrentFocus;
+                            if (currentFocus == null || currentFocus.mLayer < win.mLayer) {
                                 // We are showing on to of the current
                                 // focus, so re-evaluate focus to make
                                 // sure it is correct.
+                                if (WindowManagerService.DEBUG_FOCUS_LIGHT) Slog.v(TAG,
+                                        "updateWindowsLocked: setting mFocusMayChange true");
                                 mService.mFocusMayChange = true;
                             }
                         }
@@ -359,11 +351,9 @@
     }
 
     private void updateWallpaperLocked(int displayId) {
-        final DisplayContentsAnimator displayAnimator =
-                getDisplayContentsAnimatorLocked(displayId);
+        mService.getDisplayContentLocked(displayId).resetAnimationBackgroundAnimator();
+
         final WindowList windows = mService.getWindowListLocked(displayId);
-        WindowStateAnimator windowAnimationBackground = null;
-        int windowAnimationBackgroundColor = 0;
         WindowState detachedWallpaper = null;
 
         for (int i = windows.size() - 1; i >= 0; i--) {
@@ -384,13 +374,9 @@
                             && winAnimator.mAnimation.getDetachWallpaper()) {
                         detachedWallpaper = win;
                     }
-                    final int backgroundColor = winAnimator.mAnimation.getBackgroundColor();
-                    if (backgroundColor != 0) {
-                        if (windowAnimationBackground == null || (winAnimator.mAnimLayer <
-                                windowAnimationBackground.mAnimLayer)) {
-                            windowAnimationBackground = winAnimator;
-                            windowAnimationBackgroundColor = backgroundColor;
-                        }
+                    final int color = winAnimator.mAnimation.getBackgroundColor();
+                    if (color != 0) {
+                        win.getStack().setAnimationBackground(winAnimator, color);
                     }
                 }
                 mAnimating = true;
@@ -407,13 +393,9 @@
                     detachedWallpaper = win;
                 }
 
-                final int backgroundColor = appAnimator.animation.getBackgroundColor();
-                if (backgroundColor != 0) {
-                    if (windowAnimationBackground == null || (winAnimator.mAnimLayer <
-                            windowAnimationBackground.mAnimLayer)) {
-                        windowAnimationBackground = winAnimator;
-                        windowAnimationBackgroundColor = backgroundColor;
-                    }
+                final int color = appAnimator.animation.getBackgroundColor();
+                if (color != 0) {
+                    win.getStack().setAnimationBackground(winAnimator, color);
                 }
             }
         } // end forall windows
@@ -425,68 +407,47 @@
             mWindowDetachedWallpaper = detachedWallpaper;
             mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
         }
-
-        if (windowAnimationBackgroundColor != 0) {
-            // If the window that wants black is the current wallpaper
-            // target, then the black goes *below* the wallpaper so we
-            // don't cause the wallpaper to suddenly disappear.
-            int animLayer = windowAnimationBackground.mAnimLayer;
-            WindowState win = windowAnimationBackground.mWin;
-            if (mService.mWallpaperTarget == win || mService.mLowerWallpaperTarget == win
-                    || mService.mUpperWallpaperTarget == win) {
-                final int N = windows.size();
-                for (int i = 0; i < N; i++) {
-                    WindowStateAnimator winAnimator = windows.get(i).mWinAnimator;
-                    if (winAnimator.mIsWallpaper) {
-                        animLayer = winAnimator.mAnimLayer;
-                        break;
-                    }
-                }
-            }
-
-            displayAnimator.mWindowAnimationBackgroundSurface.show(
-                    animLayer - WindowManagerService.LAYER_OFFSET_DIM,
-                    ((windowAnimationBackgroundColor >> 24) & 0xff) / 255f, 0);
-        } else {
-            displayAnimator.mWindowAnimationBackgroundSurface.hide();
-        }
     }
 
     /** See if any windows have been drawn, so they (and others associated with them) can now be
      *  shown. */
-    private void testTokenMayBeDrawnLocked() {
+    private void testTokenMayBeDrawnLocked(int displayId) {
         // See if any windows have been drawn, so they (and others
         // associated with them) can now be shown.
-        final ArrayList<AppWindowToken> appTokens = mService.mAnimatingAppTokens;
-        final int NT = appTokens.size();
-        for (int i=0; i<NT; i++) {
-            AppWindowToken wtoken = appTokens.get(i);
-            AppWindowAnimator appAnimator = wtoken.mAppAnimator;
-            final boolean allDrawn = wtoken.allDrawn;
-            if (allDrawn != appAnimator.allDrawn) {
-                appAnimator.allDrawn = allDrawn;
-                if (allDrawn) {
-                    // The token has now changed state to having all
-                    // windows shown...  what to do, what to do?
-                    if (appAnimator.freezingScreen) {
-                        appAnimator.showAllWindowsLocked();
-                        mService.unsetAppFreezingScreenLocked(wtoken, false, true);
-                        if (WindowManagerService.DEBUG_ORIENTATION) Slog.i(TAG,
-                                "Setting mOrientationChangeComplete=true because wtoken "
-                                + wtoken + " numInteresting=" + wtoken.numInterestingWindows
-                                + " numDrawn=" + wtoken.numDrawnWindows);
-                        // This will set mOrientationChangeComplete and cause a pass through layout.
-                        setAppLayoutChanges(appAnimator,
-                                WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER,
-                                "testTokenMayBeDrawnLocked: freezingScreen");
-                    } else {
-                        setAppLayoutChanges(appAnimator,
-                                WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM,
-                                "testTokenMayBeDrawnLocked");
+        final ArrayList<Task> tasks = mService.getDisplayContentLocked(displayId).getTasks();
+        final int numTasks = tasks.size();
+        for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
+            final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
+            final int numTokens = tokens.size();
+            for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) {
+                final AppWindowToken wtoken = tokens.get(tokenNdx);
+                AppWindowAnimator appAnimator = wtoken.mAppAnimator;
+                final boolean allDrawn = wtoken.allDrawn;
+                if (allDrawn != appAnimator.allDrawn) {
+                    appAnimator.allDrawn = allDrawn;
+                    if (allDrawn) {
+                        // The token has now changed state to having all
+                        // windows shown...  what to do, what to do?
+                        if (appAnimator.freezingScreen) {
+                            appAnimator.showAllWindowsLocked();
+                            mService.unsetAppFreezingScreenLocked(wtoken, false, true);
+                            if (WindowManagerService.DEBUG_ORIENTATION) Slog.i(TAG,
+                                    "Setting mOrientationChangeComplete=true because wtoken "
+                                    + wtoken + " numInteresting=" + wtoken.numInterestingWindows
+                                    + " numDrawn=" + wtoken.numDrawnWindows);
+                            // This will set mOrientationChangeComplete and cause a pass through layout.
+                            setAppLayoutChanges(appAnimator,
+                                    WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER,
+                                    "testTokenMayBeDrawnLocked: freezingScreen");
+                        } else {
+                            setAppLayoutChanges(appAnimator,
+                                    WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM,
+                                    "testTokenMayBeDrawnLocked");
 
-                        // We can now show all of the drawn windows!
-                        if (!mService.mOpeningApps.contains(wtoken)) {
-                            mAnimating |= appAnimator.showAllWindowsLocked();
+                            // We can now show all of the drawn windows!
+                            if (!mService.mOpeningApps.contains(wtoken)) {
+                                mAnimating |= appAnimator.showAllWindowsLocked();
+                            }
                         }
                     }
                 }
@@ -499,17 +460,6 @@
         updateWallpaperLocked(displayId);
     }
 
-    private long getDimBehindFadeDuration(long duration) {
-        TypedValue tv = new TypedValue();
-        mContext.getResources().getValue(
-            com.android.internal.R.fraction.config_dimBehindFadeDuration, tv, true);
-        if (tv.type == TypedValue.TYPE_FRACTION) {
-            duration = (long)tv.getFraction(duration, duration);
-        } else if (tv.type >= TypedValue.TYPE_FIRST_INT && tv.type <= TypedValue.TYPE_LAST_INT) {
-            duration = tv.data;
-        }
-        return duration;
-    }
 
     /** Locked on mService.mWindowMap. */
     private void animateLocked() {
@@ -530,11 +480,10 @@
         SurfaceControl.openTransaction();
         SurfaceControl.setAnimationTransaction();
         try {
-            updateAppWindowsLocked();
-
             final int numDisplays = mDisplayContentsAnimators.size();
             for (int i = 0; i < numDisplays; i++) {
                 final int displayId = mDisplayContentsAnimators.keyAt(i);
+                updateAppWindowsLocked(displayId);
                 DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i);
 
                 final ScreenRotationAnimation screenRotationAnimation =
@@ -560,53 +509,18 @@
                 }
             }
 
-            testTokenMayBeDrawnLocked();
-
             for (int i = 0; i < numDisplays; i++) {
                 final int displayId = mDisplayContentsAnimators.keyAt(i);
-                DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i);
+
+                testTokenMayBeDrawnLocked(displayId);
 
                 final ScreenRotationAnimation screenRotationAnimation =
-                        displayAnimator.mScreenRotationAnimation;
+                        mDisplayContentsAnimators.valueAt(i).mScreenRotationAnimation;
                 if (screenRotationAnimation != null) {
                     screenRotationAnimation.updateSurfacesInTransaction();
                 }
 
-                final DimLayer dimAnimator = displayAnimator.mDimAnimator;
-                final WindowStateAnimator winAnimator = displayAnimator.mDimWinAnimator;
-                final int dimLayer;
-                final float dimAmount;
-                if (winAnimator == null) {
-                    dimLayer = dimAnimator.getLayer();
-                    dimAmount = 0;
-                } else {
-                    dimLayer = winAnimator.mAnimLayer - WindowManagerService.LAYER_OFFSET_DIM;
-                    dimAmount = winAnimator.mWin.mAttrs.dimAmount;
-                }
-                final float targetAlpha = dimAnimator.getTargetAlpha();
-                if (targetAlpha != dimAmount) {
-                    if (winAnimator == null) {
-                        dimAnimator.hide(DEFAULT_DIM_DURATION);
-                    } else {
-                        long duration = (winAnimator.mAnimating && winAnimator.mAnimation != null)
-                                ? winAnimator.mAnimation.computeDurationHint()
-                                : DEFAULT_DIM_DURATION;
-                        if (targetAlpha > dimAmount) {
-                            duration = getDimBehindFadeDuration(duration);
-                        }
-                        dimAnimator.show(dimLayer, dimAmount, duration);
-                    }
-                } else if (dimAnimator.getLayer() != dimLayer) {
-                    dimAnimator.setLayer(dimLayer);
-                }
-                if (dimAnimator.isAnimating()) {
-                    if (!mService.okToDisplay()) {
-                        // Jump to the end of the animation.
-                        dimAnimator.show();
-                    } else {
-                        mAnimating |= dimAnimator.stepAnimation();
-                    }
-                }
+                mAnimating |= mService.getDisplayContentLocked(displayId).animateDimLayers();
 
                 //TODO (multidisplay): Magnification is supported only for the default display.
                 if (mService.mDisplayMagnifier != null && displayId == Display.DEFAULT_DISPLAY) {
@@ -614,6 +528,12 @@
                 }
             }
 
+            if (mAnimating) {
+                mService.scheduleAnimationLocked();
+            }
+
+            mService.setFocusedStackLayer();
+
             if (mService.mWatermark != null) {
                 mService.mWatermark.drawIfNeeded();
             }
@@ -647,9 +567,7 @@
             mService.requestTraversalLocked();
         }
 
-        if (mAnimating) {
-            mService.scheduleAnimationLocked();
-        } else if (wasAnimating) {
+        if (!mAnimating && wasAnimating) {
             mService.requestTraversalLocked();
         }
         if (WindowManagerService.DEBUG_WINDOW_TRACE) {
@@ -660,26 +578,6 @@
         }
     }
 
-    WindowState mCurrentFocus;
-    void setCurrentFocus(final WindowState currentFocus) {
-        mCurrentFocus = currentFocus;
-    }
-
-    boolean isDimmingLocked(int displayId) {
-        return getDisplayContentsAnimatorLocked(displayId).mDimAnimator.isDimming();
-    }
-
-    boolean isDimmingLocked(final WindowStateAnimator winAnimator) {
-        final int displayId = winAnimator.mWin.getDisplayId();
-        DisplayContentsAnimator displayAnimator =
-                getDisplayContentsAnimatorLocked(displayId);
-        if (displayAnimator != null) {
-            return displayAnimator.mDimWinAnimator == winAnimator
-                    && displayAnimator.mDimAnimator.isDimming();
-        }
-        return false;
-    }
-
     static String bulkUpdateParamsToString(int bulkUpdateParams) {
         StringBuilder builder = new StringBuilder(128);
         if ((bulkUpdateParams & LayoutFields.SET_UPDATE_ROTATION) != 0) {
@@ -717,18 +615,6 @@
                 pw.print(subPrefix); pw.print("Window #"); pw.print(j);
                         pw.print(": "); pw.println(wanim);
             }
-            if (displayAnimator.mWindowAnimationBackgroundSurface != null) {
-                if (dumpAll || displayAnimator.mWindowAnimationBackgroundSurface.isDimming()) {
-                    pw.print(subPrefix); pw.println("mWindowAnimationBackgroundSurface:");
-                    displayAnimator.mWindowAnimationBackgroundSurface.printTo(subSubPrefix, pw);
-                }
-            }
-            if (dumpAll || displayAnimator.mDimAnimator.isDimming()) {
-                pw.print(subPrefix); pw.println("mDimAnimator:");
-                displayAnimator.mDimAnimator.printTo(subSubPrefix, pw);
-                pw.print(subPrefix); pw.print("mDimWinAnimator=");
-                        pw.println(displayAnimator.mDimWinAnimator);
-            }
             if (displayAnimator.mScreenRotationAnimation != null) {
                 pw.print(subPrefix); pw.println("mScreenRotationAnimation:");
                 displayAnimator.mScreenRotationAnimation.printTo(subSubPrefix, pw);
@@ -771,7 +657,7 @@
 
     void setAppLayoutChanges(final AppWindowAnimator appAnimator, final int changes, String s) {
         // Used to track which displays layout changes have been done.
-        SparseIntArray displays = new SparseIntArray();
+        SparseIntArray displays = new SparseIntArray(2);
         WindowList windows = appAnimator.mAppToken.allAppWindows;
         for (int i = windows.size() - 1; i >= 0; i--) {
             final int displayId = windows.get(i).getDisplayId();
@@ -786,26 +672,10 @@
         }
     }
 
-    void setDimWinAnimatorLocked(int displayId, WindowStateAnimator newWinAnimator) {
-        DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.get(displayId);
-        if (newWinAnimator == null) {
-            displayAnimator.mDimWinAnimator = null;
-        } else {
-            // Only set dim params on the highest dimmed layer.
-            final WindowStateAnimator existingDimWinAnimator = displayAnimator.mDimWinAnimator;
-            // Don't turn on for an unshown surface, or for any layer but the highest dimmed layer.
-            if (newWinAnimator.mSurfaceShown && (existingDimWinAnimator == null
-                    || !existingDimWinAnimator.mSurfaceShown
-                    || existingDimWinAnimator.mAnimLayer < newWinAnimator.mAnimLayer)) {
-                displayAnimator.mDimWinAnimator = newWinAnimator;
-            }
-        }
-    }
-
     private DisplayContentsAnimator getDisplayContentsAnimatorLocked(int displayId) {
         DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.get(displayId);
         if (displayAnimator == null) {
-            displayAnimator = new DisplayContentsAnimator(displayId);
+            displayAnimator = new DisplayContentsAnimator();
             mDisplayContentsAnimators.put(displayId, displayAnimator);
         }
         return displayAnimator;
@@ -820,14 +690,6 @@
     }
 
     private class DisplayContentsAnimator {
-        DimLayer mDimAnimator = null;
-        WindowStateAnimator mDimWinAnimator = null;
-        DimLayer mWindowAnimationBackgroundSurface = null;
         ScreenRotationAnimation mScreenRotationAnimation = null;
-
-        public DisplayContentsAnimator(int displayId) {
-            mDimAnimator = new DimLayer(mService, displayId);
-            mWindowAnimationBackgroundSurface = new DimLayer(mService, displayId);
-        }
     }
 }
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index ce40e73..dbd42af 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -16,44 +16,27 @@
 
 package com.android.server.wm;
 
-import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
-import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
-import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
-import static android.view.WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
-import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
-import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
-import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
-import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
-import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
-import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
-import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
-import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
-import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
-import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
-import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD;
-import static android.view.WindowManager.LayoutParams.TYPE_RECENTS_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
-import static android.view.WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND;
-import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+import static android.view.WindowManager.LayoutParams.*;
+
+import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
 
 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
 
 import android.app.AppOpsManager;
 import android.util.TimeUtils;
 import android.view.IWindowId;
+
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.policy.PolicyManager;
 import com.android.internal.policy.impl.PhoneWindowManager;
+import com.android.internal.util.FastPrintWriter;
 import com.android.internal.view.IInputContext;
 import com.android.internal.view.IInputMethodClient;
 import com.android.internal.view.IInputMethodManager;
 import com.android.internal.view.WindowManagerPolicyThread;
 import com.android.server.AttributeCache;
 import com.android.server.EventLogTags;
+import com.android.server.UiThread;
 import com.android.server.Watchdog;
 import com.android.server.am.BatteryStatsService;
 import com.android.server.display.DisplayManagerService;
@@ -62,6 +45,7 @@
 import com.android.server.power.ShutdownThread;
 
 import android.Manifest;
+import android.app.ActivityManager.StackBoxInfo;
 import android.app.ActivityManagerNative;
 import android.app.IActivityManager;
 import android.app.StatusBarManager;
@@ -77,7 +61,6 @@
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
-import android.graphics.Color;
 import android.graphics.Matrix;
 import android.graphics.PixelFormat;
 import android.graphics.Point;
@@ -133,6 +116,7 @@
 import android.view.KeyEvent;
 import android.view.MagnificationSpec;
 import android.view.MotionEvent;
+import android.view.Surface.OutOfResourcesException;
 import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
@@ -143,6 +127,7 @@
 import android.view.WindowManagerPolicy;
 import android.view.WindowManager.LayoutParams;
 import android.view.WindowManagerPolicy.FakeWindow;
+import android.view.WindowManagerPolicy.PointerEventListener;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
 import android.view.animation.Transformation;
@@ -166,7 +151,6 @@
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
-import java.util.NoSuchElementException;
 
 /** {@hide} */
 public class WindowManagerService extends IWindowManager.Stub
@@ -176,6 +160,7 @@
     static final boolean DEBUG = false;
     static final boolean DEBUG_ADD_REMOVE = false;
     static final boolean DEBUG_FOCUS = false;
+    static final boolean DEBUG_FOCUS_LIGHT = DEBUG_FOCUS || true;
     static final boolean DEBUG_ANIM = false;
     static final boolean DEBUG_LAYOUT = false;
     static final boolean DEBUG_RESIZE = false;
@@ -200,6 +185,8 @@
     static final boolean DEBUG_LAYOUT_REPEATS = true;
     static final boolean DEBUG_SURFACE_TRACE = false;
     static final boolean DEBUG_WINDOW_TRACE = false;
+    static final boolean DEBUG_TASK_MOVEMENT = false;
+    static final boolean DEBUG_STACK = false;
     static final boolean SHOW_SURFACE_ALLOC = false;
     static final boolean SHOW_TRANSACTIONS = false;
     static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
@@ -234,6 +221,11 @@
     static final int LAYER_OFFSET_BLUR = 2;
 
     /**
+     * FocusedStackFrame layer is immediately above focused window.
+     */
+    static final int LAYER_OFFSET_FOCUSED_STACK = 1;
+
+    /**
      * Animation thumbnail is as far as possible below the window above
      * the thumbnail (or in other words as far as possible above the window
      * below it).
@@ -276,6 +268,12 @@
     // Default input dispatching timeout in nanoseconds.
     static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
 
+    /** Minimum value for createStack and resizeStack weight value */
+    public static final float STACK_WEIGHT_MIN = 0.2f;
+
+    /** Maximum value for createStack and resizeStack weight value */
+    public static final float STACK_WEIGHT_MAX = 0.8f;
+
     static final int UPDATE_FOCUS_NORMAL = 0;
     static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
     static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
@@ -284,6 +282,9 @@
     private static final String SYSTEM_SECURE = "ro.secure";
     private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
 
+    private static final String DENSITY_OVERRIDE = "ro.config.density_override";
+    private static final String SIZE_OVERRIDE = "ro.config.size_override";
+
     private static final int MAX_SCREENSHOT_RETRIES = 3;
 
     final private KeyguardDisableHandler mKeyguardDisableHandler;
@@ -337,34 +338,7 @@
     /**
      * Mapping from a token IBinder to a WindowToken object.
      */
-    final HashMap<IBinder, WindowToken> mTokenMap =
-            new HashMap<IBinder, WindowToken>();
-
-    /**
-     * Window tokens that are in the process of exiting, but still
-     * on screen for animations.
-     */
-    final ArrayList<WindowToken> mExitingTokens = new ArrayList<WindowToken>();
-
-    /**
-     * List controlling the ordering of windows in different applications which must
-     * be kept in sync with ActivityManager.
-     */
-    final ArrayList<AppWindowToken> mAppTokens = new ArrayList<AppWindowToken>();
-
-    /**
-     * AppWindowTokens in the Z order they were in at the start of an animation. Between
-     * animations this list is maintained in the exact order of mAppTokens. If tokens
-     * are added to mAppTokens during an animation an attempt is made to insert them at the same
-     * logical location in this list. Note that this list is always in sync with mWindows.
-     */
-    ArrayList<AppWindowToken> mAnimatingAppTokens = new ArrayList<AppWindowToken>();
-
-    /**
-     * Application tokens that are in the process of exiting, but still
-     * on screen for animations.
-     */
-    final ArrayList<AppWindowToken> mExitingAppTokens = new ArrayList<AppWindowToken>();
+    final HashMap<IBinder, WindowToken> mTokenMap = new HashMap<IBinder, WindowToken>();
 
     /**
      * List of window tokens that have finished starting their application,
@@ -437,6 +411,9 @@
     final SurfaceSession mFxSession;
     Watermark mWatermark;
     StrictModeFlash mStrictModeFlash;
+    FocusedStackFrame mFocusedStackFrame;
+
+    int mFocusedStackLayer;
 
     final float[] mTmpFloats = new float[9];
 
@@ -449,8 +426,8 @@
 
     String mLastANRState;
 
-    /** All DisplayDontents in the world, kept here */
-    SparseArray<DisplayContent> mDisplayContents = new SparseArray<DisplayContent>();
+    /** All DisplayContents in the world, kept here */
+    SparseArray<DisplayContent> mDisplayContents = new SparseArray<DisplayContent>(2);
 
     int mRotation = 0;
     int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -486,7 +463,7 @@
     // This is held as long as we have the screen frozen, to give us time to
     // perform a rotation animation when turning off shows the lock screen which
     // changes the orientation.
-    private PowerManager.WakeLock mScreenFrozenLock;
+    private final PowerManager.WakeLock mScreenFrozenLock;
 
     final AppTransition mAppTransition;
     boolean mStartingIconInTransition = false;
@@ -589,7 +566,6 @@
         Object mLastWindowFreezeSource = null;
         private Session mHoldScreen = null;
         private boolean mObscured = false;
-        boolean mDimming = false;
         private boolean mSyswin = false;
         private float mScreenBrightness = -1;
         private float mButtonBrightness = -1;
@@ -604,22 +580,6 @@
     }
     final LayoutFields mInnerFields = new LayoutFields();
 
-    static class AppWindowAnimParams {
-        AppWindowAnimator mAppAnimator;
-        ArrayList<WindowStateAnimator> mWinAnimators;
-
-        public AppWindowAnimParams(final AppWindowAnimator appAnimator) {
-            mAppAnimator = appAnimator;
-
-            final AppWindowToken atoken = appAnimator.mAppToken;
-            mWinAnimators = new ArrayList<WindowStateAnimator>();
-            final int N = atoken.allAppWindows.size();
-            for (int i = 0; i < N; i++) {
-                mWinAnimators.add(atoken.allAppWindows.get(i).mWinAnimator);
-            }
-        }
-    }
-
     boolean mAnimationScheduled;
 
     /** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this
@@ -631,6 +591,11 @@
 
     final WindowAnimator mAnimator;
 
+    SparseArray<Task> mTaskIdToTask = new SparseArray<Task>();
+    SparseArray<TaskStack> mStackIdToStack = new SparseArray<TaskStack>();
+
+    private final PointerEventDispatcher mPointerEventDispatcher;
+
     final class DragInputEventReceiver extends InputEventReceiver {
         public DragInputEventReceiver(InputChannel inputChannel, Looper looper) {
             super(inputChannel, looper);
@@ -701,7 +666,7 @@
     boolean mInTouchMode = true;
 
     private ViewServer mViewServer;
-    private ArrayList<WindowChangeListener> mWindowChangeListeners =
+    private final ArrayList<WindowChangeListener> mWindowChangeListeners =
         new ArrayList<WindowChangeListener>();
     private boolean mWindowsChanged = false;
 
@@ -722,8 +687,7 @@
 
     public static WindowManagerService main(final Context context,
             final PowerManagerService pm, final DisplayManagerService dm,
-            final InputManagerService im,
-            final Handler uiHandler, final Handler wmHandler,
+            final InputManagerService im, final Handler wmHandler,
             final boolean haveInputMethods, final boolean showBootMsgs,
             final boolean onlyCore) {
         final WindowManagerService[] holder = new WindowManagerService[1];
@@ -731,7 +695,7 @@
             @Override
             public void run() {
                 holder[0] = new WindowManagerService(context, pm, dm, im,
-                        uiHandler, haveInputMethods, showBootMsgs, onlyCore);
+                        haveInputMethods, showBootMsgs, onlyCore);
             }
         }, 0);
         return holder[0];
@@ -753,7 +717,6 @@
 
     private WindowManagerService(Context context, PowerManagerService pm,
             DisplayManagerService displayManager, InputManagerService inputManager,
-            Handler uiHandler,
             boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {
         mContext = context;
         mHaveInputMethods = haveInputMethods;
@@ -761,11 +724,15 @@
         mOnlyCore = onlyCore;
         mLimitedAlphaCompositing = context.getResources().getBoolean(
                 com.android.internal.R.bool.config_sf_limitedAlpha);
+        mInputManager = inputManager; // Must be before createDisplayContentLocked.
         mDisplayManagerService = displayManager;
         mHeadless = displayManager.isHeadless();
         mDisplaySettings = new DisplaySettings(context);
         mDisplaySettings.readSettingsLocked();
 
+        mPointerEventDispatcher = new PointerEventDispatcher(mInputManager.monitorInput(TAG));
+
+        mFxSession = new SurfaceSession();
         mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
         mDisplayManager.registerDisplayListener(this, null);
         Display[] displays = mDisplayManager.getDisplays();
@@ -812,11 +779,9 @@
                 | PowerManager.ON_AFTER_RELEASE, TAG);
         mHoldingScreenWakeLock.setReferenceCounted(false);
 
-        mInputManager = inputManager;
-        mFxSession = new SurfaceSession();
         mAnimator = new WindowAnimator(this);
 
-        initPolicy(uiHandler);
+        initPolicy(UiThread.getHandler());
 
         // Add ourself to the Watchdog monitors.
         Watchdog.getInstance().addMonitor(this);
@@ -824,6 +789,8 @@
         SurfaceControl.openTransaction();
         try {
             createWatermarkInTransaction();
+            mFocusedStackFrame = new FocusedStackFrame(
+                    getDefaultDisplayContentLocked().getDisplay(), mFxSession);
         } finally {
             SurfaceControl.closeTransaction();
         }
@@ -860,10 +827,14 @@
 
     private void placeWindowBefore(WindowState pos, WindowState window) {
         final WindowList windows = pos.getWindowList();
-        final int i = windows.indexOf(pos);
+        int i = windows.indexOf(pos);
         if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
             TAG, "Adding window " + window + " at "
             + i + " of " + windows.size() + " (before " + pos + ")");
+        if (i < 0) {
+            Slog.w(TAG, "placeWindowBefore: Unable to find " + pos + " in " + windows);
+            i = 0;
+        }
         windows.add(i, window);
         mWindowsChanged = true;
     }
@@ -920,217 +891,259 @@
         return -1;
     }
 
-    private void addWindowToListInOrderLocked(WindowState win, boolean addToToken) {
+    private int addAppWindowToListLocked(final WindowState win) {
         final IWindow client = win.mClient;
         final WindowToken token = win.mToken;
         final DisplayContent displayContent = win.mDisplayContent;
 
         final WindowList windows = win.getWindowList();
         final int N = windows.size();
-        final WindowState attached = win.mAttachedWindow;
-        int i;
         WindowList tokenWindowList = getTokenWindowsOnDisplay(token, displayContent);
-        if (attached == null) {
-            int tokenWindowsPos = 0;
-            int windowListPos = tokenWindowList.size();
-            if (token.appWindowToken != null) {
-                int index = windowListPos - 1;
-                if (index >= 0) {
-                    // If this application has existing windows, we
-                    // simply place the new window on top of them... but
-                    // keep the starting window on top.
-                    if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
-                        // Base windows go behind everything else.
-                        WindowState lowestWindow = tokenWindowList.get(0);
-                        placeWindowBefore(lowestWindow, win);
-                        tokenWindowsPos = indexOfWinInWindowList(lowestWindow, token.windows);
-                    } else {
-                        AppWindowToken atoken = win.mAppToken;
-                        WindowState lastWindow = tokenWindowList.get(index);
-                        if (atoken != null && lastWindow == atoken.startingWindow) {
-                            placeWindowBefore(lastWindow, win);
-                            tokenWindowsPos = indexOfWinInWindowList(lastWindow, token.windows);
-                        } else {
-                            int newIdx = findIdxBasedOnAppTokens(win);
-                            //there is a window above this one associated with the same
-                            //apptoken note that the window could be a floating window
-                            //that was created later or a window at the top of the list of
-                            //windows associated with this token.
-                            if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
-                                Slog.v(TAG, "Adding window " + win + " at "
-                                        + (newIdx + 1) + " of " + N);
-                            }
-                            windows.add(newIdx + 1, win);
-                            if (newIdx < 0) {
-                                // No window from token found on win's display.
-                                tokenWindowsPos = 0;
-                            } else {
-                                tokenWindowsPos = indexOfWinInWindowList(
-                                        windows.get(newIdx), token.windows) + 1;
-                            }
-                            mWindowsChanged = true;
-                        }
-                    }
+        int tokenWindowsPos = 0;
+        int windowListPos = tokenWindowList.size();
+        if (!tokenWindowList.isEmpty()) {
+            // If this application has existing windows, we
+            // simply place the new window on top of them... but
+            // keep the starting window on top.
+            if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
+                // Base windows go behind everything else.
+                WindowState lowestWindow = tokenWindowList.get(0);
+                placeWindowBefore(lowestWindow, win);
+                tokenWindowsPos = indexOfWinInWindowList(lowestWindow, token.windows);
+            } else {
+                AppWindowToken atoken = win.mAppToken;
+                WindowState lastWindow = tokenWindowList.get(windowListPos - 1);
+                if (atoken != null && lastWindow == atoken.startingWindow) {
+                    placeWindowBefore(lastWindow, win);
+                    tokenWindowsPos = indexOfWinInWindowList(lastWindow, token.windows);
                 } else {
-                    // No windows from this token on this display
-                    if (localLOGV) Slog.v(
-                        TAG, "Figuring out where to add app window "
-                        + client.asBinder() + " (token=" + token + ")");
-                    // Figure out where the window should go, based on the
-                    // order of applications.
-                    final int NA = mAnimatingAppTokens.size();
-                    WindowState pos = null;
-                    for (i=NA-1; i>=0; i--) {
-                        AppWindowToken t = mAnimatingAppTokens.get(i);
-                        if (t == token) {
-                            i--;
-                            break;
-                        }
-
-                        // We haven't reached the token yet; if this token
-                        // is not going to the bottom and has windows on this display, we can
-                        // use it as an anchor for when we do reach the token.
-                        tokenWindowList = getTokenWindowsOnDisplay(t, win.mDisplayContent);
-                        if (!t.sendingToBottom && tokenWindowList.size() > 0) {
-                            pos = tokenWindowList.get(0);
-                        }
-                    }
-                    // We now know the index into the apps.  If we found
-                    // an app window above, that gives us the position; else
-                    // we need to look some more.
-                    if (pos != null) {
-                        // Move behind any windows attached to this one.
-                        WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
-                        if (atoken != null) {
-                            tokenWindowList =
-                                    getTokenWindowsOnDisplay(atoken, win.mDisplayContent);
-                            final int NC = tokenWindowList.size();
-                            if (NC > 0) {
-                                WindowState bottom = tokenWindowList.get(0);
-                                if (bottom.mSubLayer < 0) {
-                                    pos = bottom;
-                                }
-                            }
-                        }
-                        placeWindowBefore(pos, win);
+                    int newIdx = findIdxBasedOnAppTokens(win);
+                    //there is a window above this one associated with the same
+                    //apptoken note that the window could be a floating window
+                    //that was created later or a window at the top of the list of
+                    //windows associated with this token.
+                    if (DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
+                            "Adding window " + win + " at " + (newIdx + 1) + " of " + N);
+                    windows.add(newIdx + 1, win);
+                    if (newIdx < 0) {
+                        // No window from token found on win's display.
+                        tokenWindowsPos = 0;
                     } else {
-                        // Continue looking down until we find the first
-                        // token that has windows on this display.
-                        while (i >= 0) {
-                            AppWindowToken t = mAnimatingAppTokens.get(i);
-                            tokenWindowList = getTokenWindowsOnDisplay(t, win.mDisplayContent);
-                            final int NW = tokenWindowList.size();
-                            if (NW > 0) {
-                                pos = tokenWindowList.get(NW-1);
-                                break;
-                            }
-                            i--;
-                        }
-                        if (pos != null) {
-                            // Move in front of any windows attached to this
-                            // one.
-                            WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
-                            if (atoken != null) {
-                                final int NC = atoken.windows.size();
-                                if (NC > 0) {
-                                    WindowState top = atoken.windows.get(NC-1);
-                                    if (top.mSubLayer >= 0) {
-                                        pos = top;
-                                    }
-                                }
-                            }
-                            placeWindowAfter(pos, win);
-                        } else {
-                            // Just search for the start of this layer.
-                            final int myLayer = win.mBaseLayer;
-                            for (i=0; i<N; i++) {
-                                WindowState w = windows.get(i);
-                                if (w.mBaseLayer > myLayer) {
-                                    break;
-                                }
-                            }
-                            if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
-                                Slog.v(TAG, "Adding window " + win + " at "
-                                        + i + " of " + N);
-                            }
-                            windows.add(i, win);
-                            mWindowsChanged = true;
+                        tokenWindowsPos = indexOfWinInWindowList(
+                                windows.get(newIdx), token.windows) + 1;
+                    }
+                    mWindowsChanged = true;
+                }
+            }
+            return tokenWindowsPos;
+        }
+
+        // No windows from this token on this display
+        if (localLOGV) Slog.v(TAG, "Figuring out where to add app window " + client.asBinder()
+                + " (token=" + token + ")");
+        // Figure out where the window should go, based on the
+        // order of applications.
+        WindowState pos = null;
+
+        final ArrayList<Task> tasks = displayContent.getTasks();
+        int taskNdx;
+        int tokenNdx = -1;
+        for (taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
+            AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
+            for (tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
+                final AppWindowToken t = tokens.get(tokenNdx);
+                if (t == token) {
+                    --tokenNdx;
+                    if (tokenNdx < 0) {
+                        --taskNdx;
+                        if (taskNdx >= 0) {
+                            tokenNdx = tasks.get(taskNdx).mAppTokens.size() - 1;
                         }
                     }
+                    break;
+                }
+
+                // We haven't reached the token yet; if this token
+                // is not going to the bottom and has windows on this display, we can
+                // use it as an anchor for when we do reach the token.
+                tokenWindowList = getTokenWindowsOnDisplay(t, displayContent);
+                if (!t.sendingToBottom && tokenWindowList.size() > 0) {
+                    pos = tokenWindowList.get(0);
+                }
+            }
+            if (tokenNdx >= 0) {
+                // early exit
+                break;
+            }
+        }
+
+        // We now know the index into the apps.  If we found
+        // an app window above, that gives us the position; else
+        // we need to look some more.
+        if (pos != null) {
+            // Move behind any windows attached to this one.
+            WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
+            if (atoken != null) {
+                tokenWindowList =
+                        getTokenWindowsOnDisplay(atoken, displayContent);
+                final int NC = tokenWindowList.size();
+                if (NC > 0) {
+                    WindowState bottom = tokenWindowList.get(0);
+                    if (bottom.mSubLayer < 0) {
+                        pos = bottom;
+                    }
+                }
+            }
+            placeWindowBefore(pos, win);
+            return tokenWindowsPos;
+        }
+
+        // Continue looking down until we find the first
+        // token that has windows on this display.
+        for ( ; taskNdx >= 0; --taskNdx) {
+            AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
+            for ( ; tokenNdx >= 0; --tokenNdx) {
+                final AppWindowToken t = tokens.get(tokenNdx);
+                tokenWindowList = getTokenWindowsOnDisplay(t, displayContent);
+                final int NW = tokenWindowList.size();
+                if (NW > 0) {
+                    pos = tokenWindowList.get(NW-1);
+                    break;
+                }
+            }
+            if (tokenNdx >= 0) {
+                // found
+                break;
+            }
+        }
+
+        if (pos != null) {
+            // Move in front of any windows attached to this
+            // one.
+            WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
+            if (atoken != null) {
+                final int NC = atoken.windows.size();
+                if (NC > 0) {
+                    WindowState top = atoken.windows.get(NC-1);
+                    if (top.mSubLayer >= 0) {
+                        pos = top;
+                    }
+                }
+            }
+            placeWindowAfter(pos, win);
+            return tokenWindowsPos;
+        }
+
+        // Just search for the start of this layer.
+        final int myLayer = win.mBaseLayer;
+        int i;
+        for (i = 0; i < N; i++) {
+            WindowState w = windows.get(i);
+            if (w.mBaseLayer > myLayer) {
+                break;
+            }
+        }
+        if (DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
+                "Adding window " + win + " at " + i + " of " + N);
+        windows.add(i, win);
+        mWindowsChanged = true;
+        return tokenWindowsPos;
+    }
+
+    private void addFreeWindowToListLocked(final WindowState win) {
+        final WindowList windows = win.getWindowList();
+
+        // Figure out where window should go, based on layer.
+        final int myLayer = win.mBaseLayer;
+        int i;
+        for (i = windows.size() - 1; i >= 0; i--) {
+            if (windows.get(i).mBaseLayer <= myLayer) {
+                break;
+            }
+        }
+        i++;
+        if (DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
+                "Adding window " + win + " at " + i + " of " + windows.size());
+        windows.add(i, win);
+        mWindowsChanged = true;
+    }
+
+    private void addAttachedWindowToListLocked(final WindowState win, boolean addToToken) {
+        final WindowToken token = win.mToken;
+        final DisplayContent displayContent = win.mDisplayContent;
+        final WindowState attached = win.mAttachedWindow;
+
+        WindowList tokenWindowList = getTokenWindowsOnDisplay(token, displayContent);
+
+        // Figure out this window's ordering relative to the window
+        // it is attached to.
+        final int NA = tokenWindowList.size();
+        final int sublayer = win.mSubLayer;
+        int largestSublayer = Integer.MIN_VALUE;
+        WindowState windowWithLargestSublayer = null;
+        int i;
+        for (i = 0; i < NA; i++) {
+            WindowState w = tokenWindowList.get(i);
+            final int wSublayer = w.mSubLayer;
+            if (wSublayer >= largestSublayer) {
+                largestSublayer = wSublayer;
+                windowWithLargestSublayer = w;
+            }
+            if (sublayer < 0) {
+                // For negative sublayers, we go below all windows
+                // in the same sublayer.
+                if (wSublayer >= sublayer) {
+                    if (addToToken) {
+                        if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
+                        token.windows.add(i, win);
+                    }
+                    placeWindowBefore(wSublayer >= 0 ? attached : w, win);
+                    break;
                 }
             } else {
-                // Figure out where window should go, based on layer.
-                final int myLayer = win.mBaseLayer;
-                for (i=N-1; i>=0; i--) {
-                    if (windows.get(i).mBaseLayer <= myLayer) {
-                        break;
+                // For positive sublayers, we go above all windows
+                // in the same sublayer.
+                if (wSublayer > sublayer) {
+                    if (addToToken) {
+                        if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
+                        token.windows.add(i, win);
                     }
+                    placeWindowBefore(w, win);
+                    break;
                 }
-                i++;
-                if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
-                        TAG, "Adding window " + win + " at "
-                        + i + " of " + N);
-                windows.add(i, win);
-                mWindowsChanged = true;
             }
+        }
+        if (i >= NA) {
+            if (addToToken) {
+                if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
+                token.windows.add(win);
+            }
+            if (sublayer < 0) {
+                placeWindowBefore(attached, win);
+            } else {
+                placeWindowAfter(largestSublayer >= 0
+                                 ? windowWithLargestSublayer
+                                 : attached,
+                                 win);
+            }
+        }
+    }
 
+    private void addWindowToListInOrderLocked(final WindowState win, boolean addToToken) {
+        if (win.mAttachedWindow == null) {
+            final WindowToken token = win.mToken;
+            int tokenWindowsPos = 0;
+            if (token.appWindowToken != null) {
+                tokenWindowsPos = addAppWindowToListLocked(win);
+            } else {
+                addFreeWindowToListLocked(win);
+            }
             if (addToToken) {
                 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
                 token.windows.add(tokenWindowsPos, win);
             }
-
         } else {
-            // Figure out this window's ordering relative to the window
-            // it is attached to.
-            final int NA = tokenWindowList.size();
-            final int sublayer = win.mSubLayer;
-            int largestSublayer = Integer.MIN_VALUE;
-            WindowState windowWithLargestSublayer = null;
-            for (i=0; i<NA; i++) {
-                WindowState w = tokenWindowList.get(i);
-                final int wSublayer = w.mSubLayer;
-                if (wSublayer >= largestSublayer) {
-                    largestSublayer = wSublayer;
-                    windowWithLargestSublayer = w;
-                }
-                if (sublayer < 0) {
-                    // For negative sublayers, we go below all windows
-                    // in the same sublayer.
-                    if (wSublayer >= sublayer) {
-                        if (addToToken) {
-                            if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
-                            token.windows.add(i, win);
-                        }
-                        placeWindowBefore(wSublayer >= 0 ? attached : w, win);
-                        break;
-                    }
-                } else {
-                    // For positive sublayers, we go above all windows
-                    // in the same sublayer.
-                    if (wSublayer > sublayer) {
-                        if (addToToken) {
-                            if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
-                            token.windows.add(i, win);
-                        }
-                        placeWindowBefore(w, win);
-                        break;
-                    }
-                }
-            }
-            if (i >= NA) {
-                if (addToToken) {
-                    if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
-                    token.windows.add(win);
-                }
-                if (sublayer < 0) {
-                    placeWindowBefore(attached, win);
-                } else {
-                    placeWindowAfter(largestSublayer >= 0
-                                     ? windowWithLargestSublayer
-                                     : attached,
-                                     win);
-                }
-            }
+            addAttachedWindowToListLocked(win, addToToken);
         }
 
         if (win.mAppToken != null && addToToken) {
@@ -1546,10 +1559,6 @@
         return true;
     }
 
-    void adjustInputMethodDialogsLocked() {
-        moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
-    }
-
     final boolean isWallpaperVisible(WindowState wallpaperTarget) {
         if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target " + wallpaperTarget + ", obscured="
                 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
@@ -1573,8 +1582,8 @@
 
         // TODO(multidisplay): Wallpapers on main screen only.
         final DisplayInfo displayInfo = getDefaultDisplayContentLocked().getDisplayInfo();
-        final int dw = displayInfo.appWidth;
-        final int dh = displayInfo.appHeight;
+        final int dw = displayInfo.logicalWidth;
+        final int dh = displayInfo.logicalHeight;
 
         // First find top-most window that has asked to be on top of the
         // wallpaper; all wallpapers go behind it.
@@ -1840,15 +1849,36 @@
                 // Now stick it in.
                 if (DEBUG_WALLPAPER_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
                     Slog.v(TAG, "Moving wallpaper " + wallpaper
-                            + " from " + oldIndex + " to " + foundI);
+                            + " from " + oldIndex + " to " + 0);
                 }
 
-                windows.add(foundI, wallpaper);
+                windows.add(0, wallpaper);
                 mWindowsChanged = true;
                 changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
             }
         }
 
+        /*
+        final TaskStack targetStack =
+                mWallpaperTarget == null ? null : mWallpaperTarget.getStack();
+        if ((changed & ADJUST_WALLPAPER_LAYERS_CHANGED) != 0 &&
+                targetStack != null && !targetStack.isHomeStack()) {
+            // If the wallpaper target is not on the home stack then make sure that all windows
+            // from other non-home stacks are above the wallpaper.
+            for (i = foundI - 1; i >= 0; --i) {
+                WindowState win = windows.get(i);
+                if (!win.isVisibleLw()) {
+                    continue;
+                }
+                final TaskStack winStack = win.getStack();
+                if (winStack != null && !winStack.isHomeStack() && winStack != targetStack) {
+                    windows.remove(i);
+                    windows.add(foundI + 1, win);
+                }
+            }
+        }
+        */
+
         if (targetChanged && DEBUG_WALLPAPER_LIGHT) {
             Slog.d(TAG, "New wallpaper: target=" + mWallpaperTarget
                     + " lower=" + mLowerWallpaperTarget + " upper="
@@ -1967,8 +1997,8 @@
     void updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
         final DisplayContent displayContent = changingTarget.mDisplayContent;
         final DisplayInfo displayInfo = displayContent.getDisplayInfo();
-        final int dw = displayInfo.appWidth;
-        final int dh = displayInfo.appHeight;
+        final int dw = displayInfo.logicalWidth;
+        final int dh = displayInfo.logicalHeight;
 
         WindowState target = mWallpaperTarget;
         if (target != null) {
@@ -2027,8 +2057,8 @@
         final boolean visible = isWallpaperVisible(mWallpaperTarget);
         final DisplayContent displayContent = mWallpaperTarget.mDisplayContent;
         final DisplayInfo displayInfo = displayContent.getDisplayInfo();
-        final int dw = displayInfo.appWidth;
-        final int dh = displayInfo.appHeight;
+        final int dw = displayInfo.logicalWidth;
+        final int dh = displayInfo.logicalHeight;
 
         int curTokenIndex = mWallpaperTokens.size();
         while (curTokenIndex > 0) {
@@ -2076,6 +2106,13 @@
 
             final DisplayContent displayContent = getDisplayContentLocked(displayId);
             if (displayContent == null) {
+                Slog.w(TAG, "Attempted to add window to a display that does not exist: "
+                        + displayId + ".  Aborting.");
+                return WindowManagerGlobal.ADD_INVALID_DISPLAY;
+            }
+            if (!displayContent.hasAccess(session.mUid)) {
+                Slog.w(TAG, "Attempted to add window to a display for which the application "
+                        + "does not have access: " + displayId + ".  Aborting.");
                 return WindowManagerGlobal.ADD_INVALID_DISPLAY;
             }
 
@@ -2099,6 +2136,11 @@
                 }
             }
 
+            if (type == TYPE_PRIVATE_PRESENTATION && !displayContent.isPrivate()) {
+                Slog.w(TAG, "Attempted to add private presentation window to a non-private display.  Aborting.");
+                return WindowManagerGlobal.ADD_PERMISSION_DENIED;
+            }
+
             boolean addToken = false;
             WindowToken token = mTokenMap.get(attrs.token);
             if (token == null) {
@@ -2223,7 +2265,7 @@
             } else if (type == TYPE_INPUT_METHOD_DIALOG) {
                 mInputMethodDialogs.add(win);
                 addWindowToListInOrderLocked(win, true);
-                adjustInputMethodDialogsLocked();
+                moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
                 imMayMove = false;
             } else {
                 addWindowToListInOrderLocked(win, true);
@@ -2312,11 +2354,11 @@
 
     public void removeWindowLocked(Session session, WindowState win) {
 
-        if (localLOGV || DEBUG_FOCUS) Slog.v(
+        if (localLOGV || DEBUG_FOCUS || DEBUG_FOCUS_LIGHT && win==mCurrentFocus) Slog.v(
             TAG, "Remove " + win + " client="
-            + Integer.toHexString(System.identityHashCode(
-                win.mClient.asBinder()))
-            + ", surface=" + win.mWinAnimator.mSurfaceControl);
+            + Integer.toHexString(System.identityHashCode(win.mClient.asBinder()))
+            + ", surface=" + win.mWinAnimator.mSurfaceControl,
+            new RuntimeException("here").fillInStackTrace());
 
         final long origId = Binder.clearCallingIdentity();
 
@@ -2366,7 +2408,6 @@
                 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
                         false /*updateInputWindows*/);
                 performLayoutAndPlaceSurfacesLocked();
-                mInputMonitor.updateInputWindowsLw(false /*force*/);
                 if (win.mAppToken != null) {
                     win.mAppToken.updateReportedVisibilityLocked();
                 }
@@ -2495,22 +2536,19 @@
 
     public void updateAppOpsState() {
         synchronized(mWindowMap) {
-            boolean changed = false;
-            for (int i=0; i<mDisplayContents.size(); i++) {
-                DisplayContent display = mDisplayContents.valueAt(i);
-                WindowList windows = display.getWindowList();
-                for (int j=0; j<windows.size(); j++) {
-                    final WindowState win = windows.get(j);
+            final int numDisplays = mDisplayContents.size();
+            for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+                final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
+                final int numWindows = windows.size();
+                for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
+                    final WindowState win = windows.get(winNdx);
                     if (win.mAppOp != AppOpsManager.OP_NONE) {
-                        changed |= win.setAppOpVisibilityLw(mAppOps.checkOpNoThrow(win.mAppOp,
-                                win.getOwningUid(),
-                                win.getOwningPackage()) == AppOpsManager.MODE_ALLOWED);
+                        final int mode = mAppOps.checkOpNoThrow(win.mAppOp, win.getOwningUid(),
+                                win.getOwningPackage());
+                        win.setAppOpVisibilityLw(mode == AppOpsManager.MODE_ALLOWED);
                     }
                 }
             }
-            if (changed) {
-                scheduleAnimationLocked();
-            }
         }
     }
 
@@ -2946,7 +2984,7 @@
             if (toBeDisplayed && win.mIsWallpaper) {
                 DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
                 updateWallpaperOffsetLocked(win,
-                        displayInfo.appWidth, displayInfo.appHeight, false);
+                        displayInfo.logicalWidth, displayInfo.logicalHeight, false);
             }
             if (win.mAppToken != null) {
                 win.mAppToken.updateReportedVisibilityLocked();
@@ -3157,35 +3195,70 @@
     // Application Window Tokens
     // -------------------------------------------------------------
 
-    public void validateAppTokens(List<IBinder> tokens) {
-        int v = tokens.size()-1;
-        int m = mAppTokens.size()-1;
-        while (v >= 0 && m >= 0) {
-            AppWindowToken atoken = mAppTokens.get(m);
-            if (atoken.removed) {
-                m--;
-                continue;
+    public void validateAppTokens(int stackId, List<TaskGroup> tasks) {
+        synchronized (mWindowMap) {
+            int t = tasks.size() - 1;
+            if (t < 0) {
+                Slog.w(TAG, "validateAppTokens: empty task list");
+                return;
             }
-            if (tokens.get(v) != atoken.token) {
-                Slog.w(TAG, "Tokens out of sync: external is " + tokens.get(v)
-                      + " @ " + v + ", internal is " + atoken.token + " @ " + m);
+
+            TaskGroup task = tasks.get(0);
+            int taskId = task.taskId;
+            Task targetTask = mTaskIdToTask.get(taskId);
+            DisplayContent displayContent = targetTask.getDisplayContent();
+            if (displayContent == null) {
+                Slog.w(TAG, "validateAppTokens: no Display for taskId=" + taskId);
+                return;
             }
-            v--;
-            m--;
-        }
-        while (v >= 0) {
-            Slog.w(TAG, "External token not found: " + tokens.get(v) + " @ " + v);
-            v--;
-        }
-        while (m >= 0) {
-            AppWindowToken atoken = mAppTokens.get(m);
-            if (!atoken.removed) {
-                Slog.w(TAG, "Invalid internal atoken: " + atoken.token + " @ " + m);
+
+            final ArrayList<Task> localTasks = mStackIdToStack.get(stackId).getTasks();
+            int taskNdx;
+            for (taskNdx = localTasks.size() - 1; taskNdx >= 0 && t >= 0; --taskNdx, --t) {
+                AppTokenList localTokens = localTasks.get(taskNdx).mAppTokens;
+                task = tasks.get(t);
+                List<IApplicationToken> tokens = task.tokens;
+
+                DisplayContent lastDisplayContent = displayContent;
+                displayContent = mTaskIdToTask.get(taskId).getDisplayContent();
+                if (displayContent != lastDisplayContent) {
+                    Slog.w(TAG, "validateAppTokens: displayContent changed in TaskGroup list!");
+                    return;
+                }
+
+                int tokenNdx;
+                int v;
+                for (tokenNdx = localTokens.size() - 1, v = task.tokens.size() - 1;
+                        tokenNdx >= 0 && v >= 0; ) {
+                    final AppWindowToken atoken = localTokens.get(tokenNdx);
+                    if (atoken.removed) {
+                        --tokenNdx;
+                        continue;
+                    }
+                    if (tokens.get(v) != atoken.token) {
+                        break;
+                    }
+                    --tokenNdx;
+                    v--;
+                }
+
+                if (tokenNdx >= 0 || v >= 0) {
+                    break;
+                }
             }
-            m--;
+
+            if (taskNdx >= 0 || t >= 0) {
+                Slog.w(TAG, "validateAppTokens: Mismatch! ActivityManager=" + tasks);
+                Slog.w(TAG, "validateAppTokens: Mismatch! WindowManager=" + localTasks);
+                Slog.w(TAG, "validateAppTokens: Mismatch! Callers=" + Debug.getCallers(4));
+            }
         }
     }
 
+    public void validateStackOrder(Integer[] remoteStackIds) {
+        // TODO:
+    }
+
     boolean checkCallingPermission(String permission, String func) {
         // Quick check: if the calling permission is me, it's all okay.
         if (Binder.getCallingPid() == Process.myPid()) {
@@ -3246,6 +3319,7 @@
 
         final long origId = Binder.clearCallingIdentity();
         synchronized(mWindowMap) {
+            DisplayContent displayContent = null;
             WindowToken wtoken = mTokenMap.remove(token);
             if (wtoken != null) {
                 boolean delayed = false;
@@ -3255,6 +3329,7 @@
 
                     for (int i=0; i<N; i++) {
                         WindowState win = wtoken.windows.get(i);
+                        displayContent = win.mDisplayContent;
 
                         if (win.mWinAnimator.isAnimating()) {
                             delayed = true;
@@ -3264,13 +3339,12 @@
                             win.mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_EXIT,
                                     false);
                             //TODO (multidisplay): Magnification is supported only for the default
-                            if (mDisplayMagnifier != null
-                                    && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
+                            if (mDisplayMagnifier != null && win.isDefaultDisplay()) {
                                 mDisplayMagnifier.onWindowTransitionLocked(win,
                                         WindowManagerPolicy.TRANSIT_EXIT);
                             }
                             changed = true;
-                            win.mDisplayContent.layoutNeeded = true;
+                            displayContent.layoutNeeded = true;
                         }
                     }
 
@@ -3283,7 +3357,7 @@
                     }
 
                     if (delayed) {
-                        mExitingTokens.add(wtoken);
+                        displayContent.mExitingTokens.add(wtoken);
                     } else if (wtoken.windowType == TYPE_WALLPAPER) {
                         mWallpaperTokens.remove(wtoken);
                     }
@@ -3297,27 +3371,9 @@
         Binder.restoreCallingIdentity(origId);
     }
 
-    /**
-     *  Find the location to insert a new AppWindowToken into the window-ordered app token list.
-     *  Note that mAppTokens.size() == mAnimatingAppTokens.size() + 1.
-     * @param addPos The location the token was inserted into in mAppTokens.
-     * @param atoken The token to insert.
-     */
-    private void addAppTokenToAnimating(final int addPos, final AppWindowToken atoken) {
-        if (addPos == 0 || addPos == mAnimatingAppTokens.size()) {
-            // It was inserted into the beginning or end of mAppTokens. Honor that.
-            mAnimatingAppTokens.add(addPos, atoken);
-            return;
-        }
-        // Find the item immediately above the mAppTokens insertion point and put the token
-        // immediately below that one in mAnimatingAppTokens.
-        final AppWindowToken aboveAnchor = mAppTokens.get(addPos + 1);
-        mAnimatingAppTokens.add(mAnimatingAppTokens.indexOf(aboveAnchor), atoken);
-    }
-
     @Override
-    public void addAppToken(int addPos, IApplicationToken token,
-            int groupId, int requestedOrientation, boolean fullscreen, boolean showWhenLocked) {
+    public void addAppToken(int addPos, IApplicationToken token, int taskId, int stackId,
+            int requestedOrientation, boolean fullscreen, boolean showWhenLocked, int userId) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "addAppToken()")) {
             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
@@ -3345,14 +3401,27 @@
             }
             atoken = new AppWindowToken(this, token);
             atoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
-            atoken.groupId = groupId;
+            atoken.groupId = taskId;
             atoken.appFullscreen = fullscreen;
             atoken.showWhenLocked = showWhenLocked;
             atoken.requestedOrientation = requestedOrientation;
             if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "addAppToken: " + atoken
-                    + " at " + addPos);
-            mAppTokens.add(addPos, atoken);
-            addAppTokenToAnimating(addPos, atoken);
+                    + " to stack=" + stackId + " task=" + taskId + " at " + addPos);
+
+            Task task = mTaskIdToTask.get(taskId);
+            if (task == null) {
+                TaskStack stack = mStackIdToStack.get(stackId);
+                if (stack == null) {
+                    throw new IllegalArgumentException("addAppToken: invalid stackId=" + stackId);
+                }
+                task = new Task(atoken, stack, userId);
+                stack.addTask(task, true);
+                stack.getDisplayContent().moveStack(stack, true);
+                mTaskIdToTask.put(taskId, task);
+            } else {
+                task.addAppToken(addPos, atoken);
+            }
+
             mTokenMap.put(token.asBinder(), atoken);
 
             // Application tokens start out hidden.
@@ -3371,12 +3440,21 @@
         }
 
         synchronized(mWindowMap) {
-            AppWindowToken atoken = findAppWindowToken(token);
+            final AppWindowToken atoken = findAppWindowToken(token);
             if (atoken == null) {
                 Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
                 return;
             }
+            Task oldTask = mTaskIdToTask.get(atoken.groupId);
+            oldTask.removeAppToken(atoken);
+
             atoken.groupId = groupId;
+            Task newTask = mTaskIdToTask.get(groupId);
+            if (newTask == null) {
+                throw new IllegalStateException("setAppGroupId: groupId=" + groupId
+                        + " does not exist");
+            }
+            newTask.mAppTokens.add(atoken);
         }
     }
 
@@ -3417,72 +3495,76 @@
     }
 
     public int getOrientationFromAppTokensLocked() {
-        int curGroup = 0;
         int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
         boolean findingBehind = false;
-        boolean haveGroup = false;
         boolean lastFullscreen = false;
-        for (int pos = mAppTokens.size() - 1; pos >= 0; pos--) {
-            AppWindowToken atoken = mAppTokens.get(pos);
+        // TODO: Multi window.
+        DisplayContent displayContent = getDefaultDisplayContentLocked();
+        final ArrayList<Task> tasks = displayContent.getTasks();
+        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
+            AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
+            final int firstToken = tokens.size() - 1;
+            for (int tokenNdx = firstToken; tokenNdx >= 0; --tokenNdx) {
+                final AppWindowToken atoken = tokens.get(tokenNdx);
 
-            if (DEBUG_APP_ORIENTATION) Slog.v(TAG, "Checking app orientation: " + atoken);
+                if (DEBUG_APP_ORIENTATION) Slog.v(TAG, "Checking app orientation: " + atoken);
 
-            // if we're about to tear down this window and not seek for
-            // the behind activity, don't use it for orientation
-            if (!findingBehind
-                    && (!atoken.hidden && atoken.hiddenRequested)) {
-                if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + atoken
-                        + " -- going to hide");
-                continue;
-            }
-
-            if (haveGroup == true && curGroup != atoken.groupId) {
-                // If we have hit a new application group, and the bottom
-                // of the previous group didn't explicitly say to use
-                // the orientation behind it, and the last app was
-                // full screen, then we'll stick with the
-                // user's orientation.
-                if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
-                        && lastFullscreen) {
-                    if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
-                            + " -- end of group, return " + lastOrientation);
-                    return lastOrientation;
+                // if we're about to tear down this window and not seek for
+                // the behind activity, don't use it for orientation
+                if (!findingBehind
+                        && (!atoken.hidden && atoken.hiddenRequested)) {
+                    if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + atoken
+                            + " -- going to hide");
+                    continue;
                 }
-            }
 
-            // We ignore any hidden applications on the top.
-            if (atoken.hiddenRequested || atoken.willBeHidden) {
-                if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + atoken
-                        + " -- hidden on top");
-                continue;
-            }
+                if (tokenNdx == firstToken) {
+                    // If we have hit a new Task, and the bottom
+                    // of the previous group didn't explicitly say to use
+                    // the orientation behind it, and the last app was
+                    // full screen, then we'll stick with the
+                    // user's orientation.
+                    if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
+                            && lastFullscreen) {
+                        if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
+                                + " -- end of group, return " + lastOrientation);
+                        return lastOrientation;
+                    }
+                }
 
-            if (!haveGroup) {
-                haveGroup = true;
-                curGroup = atoken.groupId;
-                lastOrientation = atoken.requestedOrientation;
-            }
+                // We ignore any hidden applications on the top.
+                if (atoken.hiddenRequested || atoken.willBeHidden) {
+                    if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + atoken
+                            + " -- hidden on top");
+                    continue;
+                }
 
-            int or = atoken.requestedOrientation;
-            // If this application is fullscreen, and didn't explicitly say
-            // to use the orientation behind it, then just take whatever
-            // orientation it has and ignores whatever is under it.
-            lastFullscreen = atoken.appFullscreen;
-            if (lastFullscreen
-                    && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
-                if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
-                        + " -- full screen, return " + or);
-                return or;
+                if (tokenNdx == 0) {
+                    // Last token in this task.
+                    lastOrientation = atoken.requestedOrientation;
+                }
+
+                int or = atoken.requestedOrientation;
+                // If this application is fullscreen, and didn't explicitly say
+                // to use the orientation behind it, then just take whatever
+                // orientation it has and ignores whatever is under it.
+                lastFullscreen = atoken.appFullscreen;
+                if (lastFullscreen
+                        && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
+                    if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
+                            + " -- full screen, return " + or);
+                    return or;
+                }
+                // If this application has requested an explicit orientation,
+                // then use it.
+                if (or != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
+                        && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
+                    if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
+                            + " -- explicitly set, return " + or);
+                    return or;
+                }
+                findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
             }
-            // If this application has requested an explicit orientation,
-            // then use it.
-            if (or != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
-                    && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
-                if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
-                        + " -- explicitly set, return " + or);
-                return or;
-            }
-            findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
         }
         if (DEBUG_ORIENTATION) Slog.v(TAG, "No app is requesting an orientation");
         return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -3531,9 +3613,10 @@
             if (computeScreenConfigurationLocked(mTempConfiguration)) {
                 if (currentConfig.diff(mTempConfiguration) != 0) {
                     mWaitingForConfig = true;
-                    getDefaultDisplayContentLocked().layoutNeeded = true;
+                    final DisplayContent displayContent = getDefaultDisplayContentLocked();
+                    displayContent.layoutNeeded = true;
                     int anim[] = new int[2];
-                    if (mAnimator.isDimmingLocked(Display.DEFAULT_DISPLAY)) {
+                    if (displayContent.isDimming()) {
                         anim[0] = anim[1] = 0;
                     } else {
                         mPolicy.selectRotationAnimationLw(anim);
@@ -3633,6 +3716,52 @@
         }
     }
 
+    /** Call while in a Surface transaction. */
+    void setFocusedStackLayer() {
+        mFocusedStackLayer = 0;
+        if (mFocusedApp != null) {
+            final WindowList windows = mFocusedApp.allAppWindows;
+            for (int i = windows.size() - 1; i >= 0; --i) {
+                final WindowState win = windows.get(i);
+                final int animLayer = win.mWinAnimator.mAnimLayer;
+                if (win.mAttachedWindow == null && win.isVisibleLw() &&
+                        animLayer > mFocusedStackLayer) {
+                    mFocusedStackLayer = animLayer + LAYER_OFFSET_FOCUSED_STACK;
+                }
+            }
+        }
+        if (DEBUG_LAYERS) Slog.v(TAG, "Setting FocusedStackFrame to layer=" +
+                mFocusedStackLayer);
+        mFocusedStackFrame.setLayer(mFocusedStackLayer);
+    }
+
+    void setFocusedStackFrame() {
+        final TaskStack stack;
+        if (mFocusedApp != null) {
+            Task task = mTaskIdToTask.get(mFocusedApp.groupId);
+            stack = task.mStack;
+            task.getDisplayContent().setTouchExcludeRegion(stack);
+        } else {
+            stack = null;
+        }
+        if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setFocusedStackFrame");
+        SurfaceControl.openTransaction();
+        try {
+            if (stack == null) {
+                mFocusedStackFrame.setVisibility(false);
+            } else {
+                final StackBox box = stack.mStackBox;
+                final Rect bounds = box.mBounds;
+                final boolean multipleStacks = box.mParent != null;
+                mFocusedStackFrame.setBounds(bounds);
+                mFocusedStackFrame.setVisibility(multipleStacks);
+            }
+        } finally {
+            SurfaceControl.closeTransaction();
+            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> CLOSE TRANSACTION setFocusedStackFrame");
+        }
+    }
+
     @Override
     public void setFocusedApp(IBinder token, boolean moveFocusNow) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
@@ -3643,7 +3772,7 @@
         synchronized(mWindowMap) {
             boolean changed = false;
             if (token == null) {
-                if (DEBUG_FOCUS) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
+                if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
                 changed = mFocusedApp != null;
                 mFocusedApp = null;
                 if (changed) {
@@ -3656,9 +3785,9 @@
                     return;
                 }
                 changed = mFocusedApp != newFocus;
+                if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "Set focused app to: " + newFocus
+                        + " old focus=" + mFocusedApp + " moveFocusNow=" + moveFocusNow);
                 mFocusedApp = newFocus;
-                if (DEBUG_FOCUS) Slog.v(TAG, "Set focused app to: " + mFocusedApp
-                        + " moveFocusNow=" + moveFocusNow);
                 if (changed) {
                     mInputMonitor.setFocusedAppLw(newFocus);
                 }
@@ -3767,7 +3896,7 @@
     @Override
     public void setAppStartingWindow(IBinder token, String pkg,
             int theme, CompatibilityInfo compatInfo,
-            CharSequence nonLocalizedLabel, int labelRes, int icon,
+            CharSequence nonLocalizedLabel, int labelRes, int icon, int logo,
             int windowFlags, IBinder transferFrom, boolean createIfNeeded) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "setAppStartingWindow()")) {
@@ -3968,7 +4097,7 @@
             if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Creating StartingData");
             mStartingIconInTransition = true;
             wtoken.startingData = new StartingData(pkg, theme, compatInfo, nonLocalizedLabel,
-                    labelRes, icon, windowFlags);
+                    labelRes, icon, logo, windowFlags);
             Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
             // Note: we really want to do sendMessageAtFrontOfQueue() because we
             // want to process the message ASAP, before any other queued
@@ -3997,6 +4126,14 @@
         }
     }
 
+    public void setAppFullscreen(IBinder token, boolean toOpaque) {
+        AppWindowToken atoken = findAppWindowToken(token);
+        if (atoken != null) {
+            atoken.appFullscreen = toOpaque;
+            requestTraversal();
+        }
+    }
+
     boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
             boolean visible, int transit, boolean performLayout) {
         boolean delayed = false;
@@ -4346,11 +4483,13 @@
                         TAG, "Removing app " + wtoken + " delayed=" + delayed
                         + " animation=" + wtoken.mAppAnimator.animation
                         + " animating=" + wtoken.mAppAnimator.animating);
+                final Task task = mTaskIdToTask.get(wtoken.groupId);
+                DisplayContent displayContent = task.getDisplayContent();
                 if (delayed) {
                     // set the token aside because it has an active animation to be finished
                     if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
                             "removeAppToken make exiting: " + wtoken);
-                    mExitingAppTokens.add(wtoken);
+                    displayContent.mExitingAppTokens.add(wtoken);
                 } else {
                     // Make sure there is no animation running on this token,
                     // so any windows associated with it will be removed as
@@ -4360,15 +4499,17 @@
                 }
                 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
                         "removeAppToken: " + wtoken);
-                mAppTokens.remove(wtoken);
-                mAnimatingAppTokens.remove(wtoken);
+
+                if (task.removeAppToken(wtoken)) {
+                    mTaskIdToTask.delete(wtoken.groupId);
+                }
                 wtoken.removed = true;
                 if (wtoken.startingData != null) {
                     startingToken = wtoken;
                 }
                 unsetAppFreezingScreenLocked(wtoken, true, true);
                 if (mFocusedApp == wtoken) {
-                    if (DEBUG_FOCUS) Slog.v(TAG, "Removing focused app token:" + wtoken);
+                    if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "Removing focused app token:" + wtoken);
                     mFocusedApp = null;
                     updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
                     mInputMonitor.setFocusedAppLw(null);
@@ -4413,14 +4554,19 @@
     }
 
     void dumpAppTokensLocked() {
-        for (int i=mAppTokens.size()-1; i>=0; i--) {
-            Slog.v(TAG, "  #" + i + ": " + mAppTokens.get(i).token);
-        }
-    }
-
-    void dumpAnimatingAppTokensLocked() {
-        for (int i=mAnimatingAppTokens.size()-1; i>=0; i--) {
-            Slog.v(TAG, "  #" + i + ": " + mAnimatingAppTokens.get(i).token);
+        final int numDisplays = mDisplayContents.size();
+        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+            final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
+            Slog.v(TAG, "  Display " + displayContent.getDisplayId());
+            final ArrayList<Task> tasks = displayContent.getTasks();
+            int i = displayContent.numTokens();
+            for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
+                AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
+                for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
+                    final AppWindowToken wtoken = tokens.get(tokenNdx);
+                    Slog.v(TAG, "  #" + --i + ": " + wtoken.token);
+                }
+            }
         }
     }
 
@@ -4430,66 +4576,79 @@
         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
             final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
             for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
-                final WindowState w = windows.get(winNdx);
-                Slog.v(TAG, "  #" + i++ + ": " + w);
+                Slog.v(TAG, "  #" + i++ + ": " + windows.get(winNdx));
             }
         }
     }
 
-    private int findWindowOffsetLocked(WindowList windows, int tokenPos) {
+    private int findAppWindowInsertionPointLocked(AppWindowToken target) {
+        final int taskId = target.groupId;
+        Task targetTask = mTaskIdToTask.get(taskId);
+        if (targetTask == null) {
+            Slog.w(TAG, "findAppWindowInsertionPointLocked: no Task for " + target + " taskId="
+                    + taskId);
+            return 0;
+        }
+        DisplayContent displayContent = targetTask.getDisplayContent();
+        if (displayContent == null) {
+            Slog.w(TAG, "findAppWindowInsertionPointLocked: no DisplayContent for " + target);
+            return 0;
+        }
+        final WindowList windows = displayContent.getWindowList();
         final int NW = windows.size();
 
-        if (tokenPos >= mAnimatingAppTokens.size()) {
-            int i = NW;
-            while (i > 0) {
-                i--;
-                WindowState win = windows.get(i);
-                if (win.getAppToken() != null) {
-                    return i+1;
-                }
-            }
-        }
-
-        while (tokenPos > 0) {
-            // Find the first app token below the new position that has
-            // a window displayed.
-            final AppWindowToken wtoken = mAppTokens.get(tokenPos-1);
-            if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows @ "
-                    + tokenPos + " -- " + wtoken.token);
-            if (wtoken.sendingToBottom) {
-                if (DEBUG_REORDER) Slog.v(TAG,
-                        "Skipping token -- currently sending to bottom");
-                tokenPos--;
+        boolean found = false;
+        final ArrayList<Task> tasks = displayContent.getTasks();
+        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
+            final Task task = tasks.get(taskNdx);
+            if (!found && task.taskId != taskId) {
                 continue;
             }
-            int i = wtoken.windows.size();
-            while (i > 0) {
-                i--;
-                WindowState win = wtoken.windows.get(i);
-                int j = win.mChildWindows.size();
-                while (j > 0) {
-                    j--;
-                    WindowState cwin = win.mChildWindows.get(j);
-                    if (cwin.mSubLayer >= 0) {
-                        for (int pos=NW-1; pos>=0; pos--) {
-                            if (windows.get(pos) == cwin) {
-                                if (DEBUG_REORDER) Slog.v(TAG,
-                                        "Found child win @" + (pos+1));
-                                return pos+1;
+            AppTokenList tokens = task.mAppTokens;
+            for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
+                final AppWindowToken wtoken = tokens.get(tokenNdx);
+                if (!found && wtoken == target) {
+                    found = true;
+                }
+                if (found) {
+                    // Find the first app token below the new position that has
+                    // a window displayed.
+                    if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows in " + wtoken.token);
+                    if (wtoken.sendingToBottom) {
+                        if (DEBUG_REORDER) Slog.v(TAG, "Skipping token -- currently sending to bottom");
+                        continue;
+                    }
+                    for (int i = wtoken.windows.size() - 1; i >= 0; --i) {
+                        WindowState win = wtoken.windows.get(i);
+                        for (int j = win.mChildWindows.size() - 1; j >= 0; --j) {
+                            WindowState cwin = win.mChildWindows.get(j);
+                            if (cwin.mSubLayer >= 0) {
+                                for (int pos = NW - 1; pos >= 0; pos--) {
+                                    if (windows.get(pos) == cwin) {
+                                        if (DEBUG_REORDER) Slog.v(TAG,
+                                                "Found child win @" + (pos + 1));
+                                        return pos + 1;
+                                    }
+                                }
+                            }
+                        }
+                        for (int pos = NW - 1; pos >= 0; pos--) {
+                            if (windows.get(pos) == win) {
+                                if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos + 1));
+                                return pos + 1;
                             }
                         }
                     }
                 }
-                for (int pos=NW-1; pos>=0; pos--) {
-                    if (windows.get(pos) == win) {
-                        if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos+1));
-                        return pos+1;
-                    }
-                }
             }
-            tokenPos--;
         }
-
+        // Never put an app window underneath wallpaper.
+        for (int pos = NW - 1; pos >= 0; pos--) {
+            if (windows.get(pos).mIsWallpaper) {
+                if (DEBUG_REORDER) Slog.v(TAG, "Found wallpaper @" + pos);
+                return pos + 1;
+            }
+        }
         return 0;
     }
 
@@ -4536,198 +4695,231 @@
         return index;
     }
 
-    @Override
-    public void moveAppToken(int index, IBinder token) {
-        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
-                "moveAppToken()")) {
-            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
-        }
-
-        synchronized(mWindowMap) {
-            if (DEBUG_REORDER) Slog.v(TAG, "Initial app tokens:");
-            if (DEBUG_REORDER) dumpAppTokensLocked();
-            final AppWindowToken wtoken = findAppWindowToken(token);
-            final int oldIndex = mAppTokens.indexOf(wtoken);
-            if (DEBUG_TOKEN_MOVEMENT || DEBUG_REORDER) Slog.v(TAG,
-                    "Start moving token " + wtoken + " initially at "
-                    + oldIndex);
-            if (oldIndex > index && mAppTransition.isTransitionSet()) {
-                // animation towards back has not started, copy old list for duration of animation.
-                mAnimatingAppTokens.clear();
-                mAnimatingAppTokens.addAll(mAppTokens);
-            }
-            if (wtoken == null || !mAppTokens.remove(wtoken)) {
-                Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
-                      + token + " (" + wtoken + ")");
-                return;
-            }
-            mAppTokens.add(index, wtoken);
-            if (DEBUG_REORDER) Slog.v(TAG, "Moved " + token + " to " + index + ":");
-            else if (DEBUG_TOKEN_MOVEMENT) Slog.v(TAG, "Moved " + token + " to " + index);
-            if (DEBUG_REORDER) dumpAppTokensLocked();
-            if (!mAppTransition.isTransitionSet()) {
-                // Not animating, bring animating app list in line with mAppTokens.
-                mAnimatingAppTokens.clear();
-                mAnimatingAppTokens.addAll(mAppTokens);
-
-                // Bring window ordering, window focus and input window in line with new app token
-                final long origId = Binder.clearCallingIdentity();
-                if (DEBUG_REORDER) Slog.v(TAG, "Removing windows in " + token + ":");
-                if (DEBUG_REORDER) dumpWindowsLocked();
-                if (tmpRemoveAppWindowsLocked(wtoken)) {
-                    if (DEBUG_REORDER) Slog.v(TAG, "Adding windows back in:");
-                    if (DEBUG_REORDER) dumpWindowsLocked();
-                    final int numDisplays = mDisplayContents.size();
-                    for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
-                        final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
-                        final WindowList windows = displayContent.getWindowList();
-                        final int pos = findWindowOffsetLocked(windows, index);
-                        final int newPos = reAddAppWindowsLocked(displayContent, pos, wtoken);
-                        if (pos != newPos) {
-                            displayContent.layoutNeeded = true;
-                        }
-                    }
-                    if (DEBUG_REORDER) Slog.v(TAG, "Final window list:");
-                    if (DEBUG_REORDER) dumpWindowsLocked();
-                    updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
-                            false /*updateInputWindows*/);
-                    mInputMonitor.setUpdateInputWindowsNeededLw();
-                    performLayoutAndPlaceSurfacesLocked();
-                    mInputMonitor.updateInputWindowsLw(false /*force*/);
+    private void moveHomeTasksLocked(boolean toTop) {
+        final DisplayContent displayContent = getDefaultDisplayContentLocked();
+        if (toTop ^ displayContent.homeOnTop()) {
+            final ArrayList<Task> tasks = displayContent.getHomeStack().getTasks();
+            final int numTasks = tasks.size();
+            for (int i = 0; i < numTasks; ++i) {
+                if (toTop) {
+                    // Keep pulling the bottom task off and moving it to the top.
+                    moveTaskToTop(tasks.get(0).taskId);
+                } else {
+                    // Keep pulling the top task off and moving it to the bottom.
+                    moveTaskToBottom(tasks.get(numTasks - 1).taskId);
                 }
-                Binder.restoreCallingIdentity(origId);
             }
         }
     }
 
-    private void removeAppTokensLocked(List<IBinder> tokens) {
-        // XXX This should be done more efficiently!
-        // (take advantage of the fact that both lists should be
-        // ordered in the same way.)
-        int N = tokens.size();
-        for (int i=0; i<N; i++) {
-            IBinder token = tokens.get(i);
-            final AppWindowToken wtoken = findAppWindowToken(token);
-            if (DEBUG_REORDER || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
-                    "Temporarily removing " + wtoken + " from " + mAppTokens.indexOf(wtoken));
-            if (!mAppTokens.remove(wtoken)) {
-                Slog.w(TAG, "Attempting to reorder token that doesn't exist: "
-                      + token + " (" + wtoken + ")");
-                i--;
-                N--;
-            }
-        }
-    }
+    private void moveStackWindowsLocked(TaskStack stack) {
+        DisplayContent displayContent = stack.getDisplayContent();
 
-    private void moveAppWindowsLocked(List<IBinder> tokens, int tokenPos) {
         // First remove all of the windows from the list.
-        final int N = tokens.size();
-        int i;
-        for (i=0; i<N; i++) {
-            WindowToken token = mTokenMap.get(tokens.get(i));
-            if (token != null) {
-                tmpRemoveAppWindowsLocked(token);
+        final ArrayList<Task> tasks = stack.getTasks();
+        final int numTasks = tasks.size();
+        for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
+            AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
+            final int numTokens = tokens.size();
+            for (int tokenNdx = numTokens - 1; tokenNdx >= 0; --tokenNdx) {
+                tmpRemoveAppWindowsLocked(tokens.get(tokenNdx));
             }
         }
 
         // And now add them back at the correct place.
-        final int numDisplays = mDisplayContents.size();
-        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
-            final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
-            final WindowList windows = displayContent.getWindowList();
-            // Where to start adding?
-            int pos = findWindowOffsetLocked(windows, tokenPos);
-            for (i=0; i<N; i++) {
-                WindowToken token = mTokenMap.get(tokens.get(i));
-                if (token != null) {
-                    final int newPos = reAddAppWindowsLocked(displayContent, pos, token);
+        // Where to start adding?
+        for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
+            AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
+            int pos = findAppWindowInsertionPointLocked(tokens.get(0));
+            final int numTokens = tokens.size();
+            for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) {
+                final AppWindowToken wtoken = tokens.get(tokenNdx);
+                if (wtoken != null) {
+                    final int newPos = reAddAppWindowsLocked(displayContent, pos, wtoken);
                     if (newPos != pos) {
                         displayContent.layoutNeeded = true;
                     }
                     pos = newPos;
                 }
             }
-            if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
-                    false /*updateInputWindows*/)) {
-                assignLayersLocked(windows);
-            }
+        }
+
+        if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
+                false /*updateInputWindows*/)) {
+            assignLayersLocked(displayContent.getWindowList());
         }
 
         mInputMonitor.setUpdateInputWindowsNeededLw();
-
-        // Note that the above updateFocusedWindowLocked used to sit here.
-
         performLayoutAndPlaceSurfacesLocked();
         mInputMonitor.updateInputWindowsLw(false /*force*/);
 
         //dump();
     }
 
-    @Override
-    public void moveAppTokensToTop(List<IBinder> tokens) {
-        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
-                "moveAppTokensToTop()")) {
-            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
-        }
-
+    public void moveTaskToTop(int taskId) {
         final long origId = Binder.clearCallingIdentity();
-        synchronized(mWindowMap) {
-            removeAppTokensLocked(tokens);
-            final int N = tokens.size();
-            for (int i=0; i<N; i++) {
-                AppWindowToken wt = findAppWindowToken(tokens.get(i));
-                if (wt != null) {
-                    if (DEBUG_TOKEN_MOVEMENT || DEBUG_REORDER) Slog.v(TAG,
-                            "Adding next to top: " + wt);
-                    mAppTokens.add(wt);
-                    if (mAppTransition.isTransitionSet()) {
-                        wt.sendingToBottom = false;
-                    }
+        try {
+            synchronized(mWindowMap) {
+                Task task = mTaskIdToTask.get(taskId);
+                if (task == null) {
+                    Slog.e(TAG, "moveTaskToTop: taskId=" + taskId + " not found in mTaskIdToTask");
+                    return;
                 }
+                final TaskStack stack = task.mStack;
+                final DisplayContent displayContent = task.getDisplayContent();
+                final boolean isHomeStackTask = stack.isHomeStack();
+                final boolean homeIsOnTop = displayContent.homeOnTop();
+                if (!isHomeStackTask && homeIsOnTop) {
+                    // First move move the home tasks all to the bottom to rearrange the windows.
+                    moveHomeTasksLocked(false);
+                    // Now move the stack itself.
+                    displayContent.moveHomeStackBox(false);
+                } else if (isHomeStackTask && !homeIsOnTop) {
+                    // Move the stack to the top.
+                    displayContent.moveHomeStackBox(true);
+                }
+                stack.moveTaskToTop(task);
+                displayContent.moveStack(stack, true);
+                moveStackWindowsLocked(stack);
             }
-
-            mAnimatingAppTokens.clear();
-            mAnimatingAppTokens.addAll(mAppTokens);
-            moveAppWindowsLocked(tokens, mAppTokens.size());
+        } finally {
+            Binder.restoreCallingIdentity(origId);
         }
-        Binder.restoreCallingIdentity(origId);
     }
 
-    @Override
-    public void moveAppTokensToBottom(List<IBinder> tokens) {
-        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
-                "moveAppTokensToBottom()")) {
-            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
-        }
-
+    public void moveTaskToBottom(int taskId) {
         final long origId = Binder.clearCallingIdentity();
-        synchronized(mWindowMap) {
-            final int N = tokens.size();
-            if (N > 0) {
-                // animating towards back, hang onto old list for duration of animation.
-                mAnimatingAppTokens.clear();
-                mAnimatingAppTokens.addAll(mAppTokens);
+        try {
+            synchronized(mWindowMap) {
+                Task task = mTaskIdToTask.get(taskId);
+                if (task == null) {
+                    Slog.e(TAG, "moveTaskToBottom: taskId=" + taskId
+                            + " not found in mTaskIdToTask");
+                    return;
+                }
+                final TaskStack stack = task.mStack;
+                stack.moveTaskToBottom(task);
+                task.getDisplayContent().moveStack(stack, false);
+                moveStackWindowsLocked(stack);
             }
-            removeAppTokensLocked(tokens);
-            int pos = 0;
-            for (int i=0; i<N; i++) {
-                AppWindowToken wt = findAppWindowToken(tokens.get(i));
-                if (wt != null) {
-                    if (DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
-                            "Adding next to bottom: " + wt + " at " + pos);
-                    mAppTokens.add(pos, wt);
-                    if (mAppTransition.isTransitionSet()) {
-                        wt.sendingToBottom = true;
-                    }
-                    pos++;
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
+    /**
+     * Create a new TaskStack and place it next to an existing stack.
+     * @param stackId The unique identifier of the new stack.
+     * @param relativeStackBoxId The existing stack that this stack goes before or after.
+     * @param position One of:
+     *      {@link StackBox#TASK_STACK_GOES_BEFORE}
+     *      {@link StackBox#TASK_STACK_GOES_AFTER}
+     *      {@link StackBox#TASK_STACK_GOES_ABOVE}
+     *      {@link StackBox#TASK_STACK_GOES_BELOW}
+     *      {@link StackBox#TASK_STACK_GOES_UNDER}
+     *      {@link StackBox#TASK_STACK_GOES_OVER}
+     * @param weight Relative weight for determining how big to make the new TaskStack.
+     */
+    public void createStack(int stackId, int relativeStackBoxId, int position, float weight) {
+        synchronized (mWindowMap) {
+            if (position <= StackBox.TASK_STACK_GOES_BELOW &&
+                    (weight < STACK_WEIGHT_MIN || weight > STACK_WEIGHT_MAX)) {
+                throw new IllegalArgumentException(
+                        "createStack: weight must be between " + STACK_WEIGHT_MIN + " and " +
+                        STACK_WEIGHT_MAX + ", weight=" + weight);
+            }
+            final int numDisplays = mDisplayContents.size();
+            for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+                final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
+                TaskStack stack = displayContent.createStack(stackId, relativeStackBoxId, position,
+                        weight);
+                if (stack != null) {
+                    mStackIdToStack.put(stackId, stack);
+                    displayContent.moveStack(stack, true);
+                    performLayoutAndPlaceSurfacesLocked();
+                    return;
                 }
             }
-
-            mAnimatingAppTokens.clear();
-            mAnimatingAppTokens.addAll(mAppTokens);
-            moveAppWindowsLocked(tokens, 0);
+            Slog.e(TAG, "createStack: Unable to find relativeStackBoxId=" + relativeStackBoxId);
         }
-        Binder.restoreCallingIdentity(origId);
+    }
+
+    public int removeStack(int stackId) {
+        synchronized (mWindowMap) {
+            final TaskStack stack = mStackIdToStack.get(stackId);
+            if (stack != null) {
+                mStackIdToStack.delete(stackId);
+                int nextStackId = stack.remove();
+                stack.getDisplayContent().layoutNeeded = true;
+                requestTraversalLocked();
+                return nextStackId;
+            }
+            if (DEBUG_STACK) Slog.i(TAG, "removeStack: could not find stackId=" + stackId);
+        }
+        return HOME_STACK_ID;
+    }
+
+    public void removeTask(int taskId) {
+        synchronized (mWindowMap) {
+            Task task = mTaskIdToTask.get(taskId);
+            if (task == null) {
+                if (DEBUG_STACK) Slog.i(TAG, "removeTask: could not find taskId=" + taskId);
+                return;
+            }
+            final TaskStack stack = task.mStack;
+            stack.removeTask(task);
+            stack.getDisplayContent().layoutNeeded = true;
+        }
+    }
+
+    public void addTask(int taskId, int stackId, boolean toTop) {
+        synchronized (mWindowMap) {
+            Task task = mTaskIdToTask.get(taskId);
+            if (task == null) {
+                return;
+            }
+            TaskStack stack = mStackIdToStack.get(stackId);
+            stack.addTask(task, toTop);
+            final DisplayContent displayContent = stack.getDisplayContent();
+            displayContent.layoutNeeded = true;
+            performLayoutAndPlaceSurfacesLocked();
+        }
+    }
+
+    public void resizeStackBox(int stackBoxId, float weight) {
+        if (weight < STACK_WEIGHT_MIN || weight > STACK_WEIGHT_MAX) {
+            throw new IllegalArgumentException(
+                    "resizeStack: weight must be between " + STACK_WEIGHT_MIN + " and " +
+                    STACK_WEIGHT_MAX + ", weight=" + weight);
+        }
+        synchronized (mWindowMap) {
+            final int numDisplays = mDisplayContents.size();
+            for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+                if (mDisplayContents.valueAt(displayNdx).resizeStack(stackBoxId, weight)) {
+                    performLayoutAndPlaceSurfacesLocked();
+                    return;
+                }
+            }
+        }
+        throw new IllegalArgumentException("resizeStack: stackBoxId " + stackBoxId
+                + " not found.");
+    }
+
+    public ArrayList<StackBoxInfo> getStackBoxInfos() {
+        synchronized(mWindowMap) {
+            return getDefaultDisplayContentLocked().getStackBoxInfos();
+        }
+    }
+
+    public Rect getStackBounds(int stackId) {
+        final int numDisplays = mDisplayContents.size();
+        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+            Rect bounds = mDisplayContents.valueAt(displayNdx).getStackBounds(stackId);
+            if (bounds != null) {
+                return bounds;
+            }
+        }
+        return null;
     }
 
     // -------------------------------------------------------------
@@ -4934,6 +5126,16 @@
                 mAnimatorDurationScale };
     }
 
+    @Override
+    public void registerPointerEventListener(PointerEventListener listener) {
+        mPointerEventDispatcher.registerInputEventListener(listener);
+    }
+
+    @Override
+    public void unregisterPointerEventListener(PointerEventListener listener) {
+        mPointerEventDispatcher.unregisterInputEventListener(listener);
+    }
+
     // Called by window manager policy. Not exposed externally.
     @Override
     public int getLidState() {
@@ -4953,12 +5155,6 @@
 
     // Called by window manager policy.  Not exposed externally.
     @Override
-    public InputChannel monitorInput(String inputChannelName) {
-        return mInputManager.monitorInput(inputChannelName);
-    }
-
-    // Called by window manager policy.  Not exposed externally.
-    @Override
     public void switchKeyboardLayout(int deviceId, int direction) {
         mInputManager.switchKeyboardLayout(deviceId, direction);
     }
@@ -4985,6 +5181,7 @@
 
     public void setCurrentUser(final int newUserId) {
         synchronized (mWindowMap) {
+            int oldUserId = mCurrentUserId;
             mCurrentUserId = newUserId;
             mAppTransition.setCurrentUser(newUserId);
             mPolicy.setCurrentUserLw(newUserId);
@@ -4993,16 +5190,8 @@
             final int numDisplays = mDisplayContents.size();
             for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
                 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
-                final WindowList windows = displayContent.getWindowList();
-                for (int i = 0; i < windows.size(); i++) {
-                    final WindowState win = windows.get(i);
-                    if (win.isHiddenFromUserLocked()) {
-                        Slog.w(TAG, "current user violation " + newUserId + " hiding "
-                                + win + ", attrs=" + win.mAttrs.type + ", belonging to "
-                                + win.mOwnerUid);
-                        win.hideLw(false);
-                    }
-                }
+                displayContent.switchUserStacks(oldUserId, newUserId);
+                rebuildAppWindowListLocked(displayContent);
             }
             performLayoutAndPlaceSurfacesLocked();
         }
@@ -5151,8 +5340,9 @@
             if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG, "******************** ENABLING SCREEN!");
             if (false) {
                 StringWriter sw = new StringWriter();
-                PrintWriter pw = new PrintWriter(sw);
+                PrintWriter pw = new FastPrintWriter(sw, false, 1024);
                 this.dump(null, pw, null);
+                pw.flush();
                 Slog.i(TAG, sw.toString());
             }
             try {
@@ -5356,6 +5546,7 @@
                 boolean including = false;
                 appWin = null;
                 final WindowList windows = displayContent.getWindowList();
+                final Rect stackBounds = new Rect();
                 for (int i = windows.size() - 1; i >= 0; i--) {
                     WindowState ws = windows.get(i);
                     if (!ws.mHasSurface) {
@@ -5378,6 +5569,7 @@
                                 continue;
                             }
                             appWin = ws;
+                            stackBounds.set(ws.getStackBounds());
                         }
                     }
 
@@ -5403,6 +5595,7 @@
                         int right = wf.right - cr.right;
                         int bottom = wf.bottom - cr.bottom;
                         frame.union(left, top, right, bottom);
+                        frame.intersect(stackBounds);
                     }
 
                     if (ws.mAppToken != null && ws.mAppToken.token == appToken &&
@@ -5446,9 +5639,11 @@
 
                 // Constrain thumbnail to smaller of screen width or height. Assumes aspect
                 // of thumbnail is the same as the screen (in landscape) or square.
+                scale = Math.max(width / (float) fw, height / (float) fh);
+                /*
                 float targetWidthScale = width / (float) fw;
                 float targetHeightScale = height / (float) fh;
-                if (dw <= dh) {
+                if (fw <= fh) {
                     scale = targetWidthScale;
                     // If aspect of thumbnail is the same as the screen (in landscape),
                     // select the slightly larger value so we fill the entire bitmap
@@ -5463,6 +5658,7 @@
                         scale = targetWidthScale;
                     }
                 }
+                */
 
                 // The screen shot will contain the entire screen.
                 dw = (int)(dw*scale);
@@ -5497,9 +5693,11 @@
         }
 
         Bitmap bm = Bitmap.createBitmap(width, height, rawss.getConfig());
+        frame.scale(scale);
         Matrix matrix = new Matrix();
         ScreenRotationAnimation.createRotationMatrix(rot, dw, dh, matrix);
-        matrix.postTranslate(-FloatMath.ceil(frame.left*scale), -FloatMath.ceil(frame.top*scale));
+        // TODO: Test for RTL vs. LTR and use frame.right-width instead of -frame.left
+        matrix.postTranslate(-FloatMath.ceil(frame.left), -FloatMath.ceil(frame.top));
         Canvas canvas = new Canvas(bm);
         canvas.drawColor(0xFF000000);
         canvas.drawBitmap(rawss, matrix, null);
@@ -5510,14 +5708,16 @@
             int[] buffer = new int[bm.getWidth() * bm.getHeight()];
             bm.getPixels(buffer, 0, bm.getWidth(), 0, 0, bm.getWidth(), bm.getHeight());
             boolean allBlack = true;
+            final int firstColor = buffer[0];
             for (int i = 0; i < buffer.length; i++) {
-                if (buffer[i] != Color.BLACK) {
+                if (buffer[i] != firstColor) {
                     allBlack = false;
                     break;
                 }
             }
             if (allBlack) {
-                Slog.i(TAG, "Screenshot " + appWin + " was all black! mSurfaceLayer=" +
+                Slog.i(TAG, "Screenshot " + appWin + " was monochrome(" +
+                        Integer.toHexString(firstColor) + ")! mSurfaceLayer=" +
                         (appWin != null ? appWin.mWinAnimator.mSurfaceLayer : "null") +
                         " minLayer=" + minLayer + " maxLayer=" + maxLayer);
             }
@@ -5709,9 +5909,10 @@
         mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
         mH.sendEmptyMessageDelayed(H.WINDOW_FREEZE_TIMEOUT, WINDOW_FREEZE_TIMEOUT_DURATION);
         mWaitingForConfig = true;
-        getDefaultDisplayContentLocked().layoutNeeded = true;
+        final DisplayContent displayContent = getDefaultDisplayContentLocked();
+        displayContent.layoutNeeded = true;
         final int[] anim = new int[2];
-        if (mAnimator.isDimmingLocked(Display.DEFAULT_DISPLAY)) {
+        if (displayContent.isDimming()) {
             anim[0] = anim[1] = 0;
         } else {
             mPolicy.selectRotationAnimationLw(anim);
@@ -5729,7 +5930,6 @@
         // the rotation animation for the new rotation.
         computeScreenConfigurationLocked(null);
 
-        final DisplayContent displayContent = getDefaultDisplayContentLocked();
         final DisplayInfo displayInfo = displayContent.getDisplayInfo();
         if (!inTransaction) {
             if (SHOW_TRANSACTIONS) {
@@ -6441,8 +6641,9 @@
             displayInfo.logicalDensityDpi = displayContent.mBaseDisplayDensity;
             displayInfo.appWidth = appWidth;
             displayInfo.appHeight = appHeight;
-            displayInfo.getLogicalMetrics(mRealDisplayMetrics, null);
-            displayInfo.getAppMetrics(mDisplayMetrics, null);
+            displayInfo.getLogicalMetrics(mRealDisplayMetrics,
+                    CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
+            displayInfo.getAppMetrics(mDisplayMetrics);
             mDisplayManagerService.setDisplayInfoOverrideFromWindowManager(
                     displayContent.getDisplayId(), displayInfo);
         }
@@ -6613,7 +6814,7 @@
                     } else {
                         Slog.w(TAG, "Drag already in progress");
                     }
-                } catch (SurfaceControl.OutOfResourcesException e) {
+                } catch (OutOfResourcesException e) {
                     Slog.e(TAG, "Can't allocate drag surface w=" + width + " h=" + height, e);
                     if (mDragState != null) {
                         mDragState.reset();
@@ -6748,15 +6949,18 @@
         synchronized(mWindowMap) {
             final DisplayContent displayContent = getDefaultDisplayContentLocked();
             readForcedDisplaySizeAndDensityLocked(displayContent);
-
             mDisplayReady = true;
+        }
+
+        try {
+            mActivityManager.updateConfiguration(null);
+        } catch (RemoteException e) {
+        }
+
+        synchronized(mWindowMap) {
             mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(
                     PackageManager.FEATURE_TOUCHSCREEN);
-
-            mPolicy.setInitialDisplaySize(displayContent.getDisplay(),
-                    displayContent.mInitialDisplayWidth,
-                    displayContent.mInitialDisplayHeight,
-                    displayContent.mInitialDisplayDensity);
+            configureDisplayPolicyLocked(getDefaultDisplayContentLocked());
         }
 
         try {
@@ -6783,6 +6987,8 @@
                     displayContent.mBaseDisplayWidth = displayContent.mInitialDisplayWidth;
                     displayContent.mBaseDisplayHeight = displayContent.mInitialDisplayHeight;
                     displayContent.mBaseDisplayDensity = displayContent.mInitialDisplayDensity;
+                    displayContent.mBaseDisplayRect.set(0, 0,
+                            displayContent.mBaseDisplayWidth, displayContent.mBaseDisplayHeight);
                 }
             }
         }
@@ -6844,6 +7050,8 @@
         public static final int DO_DISPLAY_CHANGED = 29;
 
         public static final int CLIENT_FREEZE_TIMEOUT = 30;
+        public static final int TAP_OUTSIDE_STACK = 31;
+        public static final int NOTIFY_ACTIVITY_DRAWN = 32;
 
         @Override
         public void handleMessage(Message msg) {
@@ -6863,8 +7071,8 @@
                             return;
                         }
                         mLastFocus = newFocus;
-                        //Slog.i(TAG, "Focus moving from " + lastFocus
-                        //        + " to " + newFocus);
+                        if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, "Focus moving from " + lastFocus +
+                                " to " + newFocus);
                         if (newFocus != null && lastFocus != null
                                 && !newFocus.isDisplayedLw()) {
                             //Slog.i(TAG, "Delaying loss of focus...");
@@ -6877,13 +7085,13 @@
                         //System.out.println("Changing focus from " + lastFocus
                         //                   + " to " + newFocus);
                         if (newFocus != null) {
-                            //Slog.i(TAG, "Gaining focus: " + newFocus);
+                            if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, "Gaining focus: " + newFocus);
                             newFocus.reportFocusChangedSerialized(true, mInTouchMode);
                             notifyFocusChanged();
                         }
 
                         if (lastFocus != null) {
-                            //Slog.i(TAG, "Losing focus: " + lastFocus);
+                            if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, "Losing focus: " + lastFocus);
                             lastFocus.reportFocusChangedSerialized(false, mInTouchMode);
                         }
                     }
@@ -6899,7 +7107,8 @@
 
                     final int N = losers.size();
                     for (int i=0; i<N; i++) {
-                        //Slog.i(TAG, "Losing delayed focus: " + losers.get(i));
+                        if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, "Losing delayed focus: " +
+                                losers.get(i));
                         losers.get(i).reportFocusChangedSerialized(false, mInTouchMode);
                     }
                 } break;
@@ -6927,7 +7136,7 @@
                     try {
                         view = mPolicy.addStartingWindow(
                             wtoken.token, sd.pkg, sd.theme, sd.compatInfo,
-                            sd.nonLocalizedLabel, sd.labelRes, sd.icon, sd.windowFlags);
+                            sd.nonLocalizedLabel, sd.labelRes, sd.icon, sd.logo, sd.windowFlags);
                     } catch (Exception e) {
                         Slog.w(TAG, "Exception when adding starting window", e);
                     }
@@ -7088,8 +7297,6 @@
                         if (mAppTransition.isTransitionSet()) {
                             if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** APP TRANSITION TIMEOUT");
                             mAppTransition.setTimeout();
-                            mAnimatingAppTokens.clear();
-                            mAnimatingAppTokens.addAll(mAppTokens);
                             performLayoutAndPlaceSurfacesLocked();
                         }
                     }
@@ -7134,13 +7341,16 @@
                 case APP_FREEZE_TIMEOUT: {
                     synchronized (mWindowMap) {
                         Slog.w(TAG, "App freeze timeout expired.");
-                        int i = mAppTokens.size();
-                        while (i > 0) {
-                            i--;
-                            AppWindowToken tok = mAppTokens.get(i);
-                            if (tok.mAppAnimator.freezingScreen) {
-                                Slog.w(TAG, "Force clearing freeze: " + tok);
-                                unsetAppFreezingScreenLocked(tok, true, true);
+                        DisplayContent displayContent = getDefaultDisplayContentLocked();
+                        final ArrayList<Task> tasks = displayContent.getTasks();
+                        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
+                            AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
+                            for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
+                                AppWindowToken tok = tokens.get(tokenNdx);
+                                if (tok.mAppAnimator.freezingScreen) {
+                                    Slog.w(TAG, "Force clearing freeze: " + tok);
+                                    unsetAppFreezingScreenLocked(tok, true, true);
+                                }
                             }
                         }
                     }
@@ -7262,6 +7472,26 @@
                         handleDisplayChangedLocked(msg.arg1);
                     }
                     break;
+
+                case TAP_OUTSIDE_STACK: {
+                    int stackId;
+                    synchronized (mWindowMap) {
+                        stackId = ((DisplayContent)msg.obj).stackIdFromPoint(msg.arg1, msg.arg2);
+                    }
+                    if (stackId >= 0) {
+                        try {
+                            mActivityManager.setFocusedStack(stackId);
+                        } catch (RemoteException e) {
+                        }
+                    }
+                }
+                break;
+                case NOTIFY_ACTIVITY_DRAWN:
+                    try {
+                        mActivityManager.notifyActivityDrawn((IBinder) msg.obj);
+                    } catch (RemoteException e) {
+                    }
+                    break;
             }
             if (DEBUG_WINDOW_TRACE) {
                 Slog.v(TAG, "handleMessage: exit");
@@ -7347,7 +7577,7 @@
     public void getInitialDisplaySize(int displayId, Point size) {
         synchronized (mWindowMap) {
             final DisplayContent displayContent = getDisplayContentLocked(displayId);
-            if (displayContent != null) {
+            if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
                 synchronized(displayContent.mDisplaySizeLock) {
                     size.x = displayContent.mInitialDisplayWidth;
                     size.y = displayContent.mInitialDisplayHeight;
@@ -7360,7 +7590,7 @@
     public void getBaseDisplaySize(int displayId, Point size) {
         synchronized (mWindowMap) {
             final DisplayContent displayContent = getDisplayContentLocked(displayId);
-            if (displayContent != null) {
+            if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
                 synchronized(displayContent.mDisplaySizeLock) {
                     size.x = displayContent.mBaseDisplayWidth;
                     size.y = displayContent.mBaseDisplayHeight;
@@ -7400,8 +7630,11 @@
     }
 
     private void readForcedDisplaySizeAndDensityLocked(final DisplayContent displayContent) {
-        final String sizeStr = Settings.Global.getString(mContext.getContentResolver(),
+        String sizeStr = Settings.Global.getString(mContext.getContentResolver(),
                 Settings.Global.DISPLAY_SIZE_FORCED);
+        if (sizeStr == null || sizeStr.length() == 0) {
+            sizeStr = SystemProperties.get(SIZE_OVERRIDE, null);
+        }
         if (sizeStr != null && sizeStr.length() > 0) {
             final int pos = sizeStr.indexOf(',');
             if (pos > 0 && sizeStr.lastIndexOf(',') == pos) {
@@ -7421,8 +7654,11 @@
                 }
             }
         }
-        final String densityStr = Settings.Global.getString(mContext.getContentResolver(),
+        String densityStr = Settings.Global.getString(mContext.getContentResolver(),
                 Settings.Global.DISPLAY_DENSITY_FORCED);
+        if (densityStr == null || densityStr.length() == 0) {
+            densityStr = SystemProperties.get(DENSITY_OVERRIDE, null);
+        }
         if (densityStr != null && densityStr.length() > 0) {
             int density;
             try {
@@ -7475,7 +7711,7 @@
     public int getInitialDisplayDensity(int displayId) {
         synchronized (mWindowMap) {
             final DisplayContent displayContent = getDisplayContentLocked(displayId);
-            if (displayContent != null) {
+            if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
                 synchronized(displayContent.mDisplaySizeLock) {
                     return displayContent.mInitialDisplayDensity;
                 }
@@ -7488,7 +7724,7 @@
     public int getBaseDisplayDensity(int displayId) {
         synchronized (mWindowMap) {
             final DisplayContent displayContent = getDisplayContentLocked(displayId);
-            if (displayContent != null) {
+            if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
                 synchronized(displayContent.mDisplaySizeLock) {
                     return displayContent.mBaseDisplayDensity;
                 }
@@ -7552,11 +7788,7 @@
     // displayContent must not be null
     private void reconfigureDisplayLocked(DisplayContent displayContent) {
         // TODO: Multidisplay: for now only use with default display.
-        mPolicy.setInitialDisplaySize(displayContent.getDisplay(),
-                displayContent.mBaseDisplayWidth,
-                displayContent.mBaseDisplayHeight,
-                displayContent.mBaseDisplayDensity);
-
+        configureDisplayPolicyLocked(displayContent);
         displayContent.layoutNeeded = true;
 
         boolean configChanged = updateOrientationFromAppTokensLocked(false);
@@ -7577,6 +7809,18 @@
         performLayoutAndPlaceSurfacesLocked();
     }
 
+    private void configureDisplayPolicyLocked(DisplayContent displayContent) {
+        mPolicy.setInitialDisplaySize(displayContent.getDisplay(),
+                displayContent.mBaseDisplayWidth,
+                displayContent.mBaseDisplayHeight,
+                displayContent.mBaseDisplayDensity);
+
+        DisplayInfo displayInfo = displayContent.getDisplayInfo();
+        mPolicy.setDisplayOverscan(displayContent.getDisplay(),
+                displayInfo.overscanLeft, displayInfo.overscanTop,
+                displayInfo.overscanRight, displayInfo.overscanBottom);
+    }
+
     @Override
     public void setOverscan(int displayId, int left, int top, int right, int bottom) {
         if (mContext.checkCallingOrSelfPermission(
@@ -7588,26 +7832,25 @@
         synchronized(mWindowMap) {
             DisplayContent displayContent = getDisplayContentLocked(displayId);
             if (displayContent != null) {
-                mDisplayManagerService.setOverscan(displayId, left, top, right, bottom);
-                final DisplayInfo displayInfo = displayContent.getDisplayInfo();
-                synchronized(displayContent.mDisplaySizeLock) {
-                    displayInfo.overscanLeft = left;
-                    displayInfo.overscanTop = top;
-                    displayInfo.overscanRight = right;
-                    displayInfo.overscanBottom = bottom;
-                }
-                mPolicy.setDisplayOverscan(displayContent.getDisplay(), left, top, right, bottom);
-                displayContent.layoutNeeded = true;
-                mDisplaySettings.setOverscanLocked(displayInfo.name, left, top, right, bottom);
-                mDisplaySettings.writeSettingsLocked();
-                performLayoutAndPlaceSurfacesLocked();
+                setOverscanLocked(displayContent, left, top, right, bottom);
             }
         }
     }
 
-    @Override
-    public boolean hasSystemNavBar() {
-        return mPolicy.hasSystemNavBar();
+    private void setOverscanLocked(DisplayContent displayContent,
+            int left, int top, int right, int bottom) {
+        final DisplayInfo displayInfo = displayContent.getDisplayInfo();
+        synchronized (displayContent.mDisplaySizeLock) {
+            displayInfo.overscanLeft = left;
+            displayInfo.overscanTop = top;
+            displayInfo.overscanRight = right;
+            displayInfo.overscanBottom = bottom;
+        }
+
+        mDisplaySettings.setOverscanLocked(displayInfo.name, left, top, right, bottom);
+        mDisplaySettings.writeSettingsLocked();
+
+        reconfigureDisplayLocked(displayContent);
     }
 
     // -------------------------------------------------------------
@@ -7650,7 +7893,8 @@
     final void rebuildAppWindowListLocked() {
         final int numDisplays = mDisplayContents.size();
         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
-            rebuildAppWindowListLocked(mDisplayContents.valueAt(displayNdx));
+            final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
+            rebuildAppWindowListLocked(displayContent);
         }
     }
 
@@ -7674,8 +7918,7 @@
                 win.mRebuilding = true;
                 mRebuildTmp[numRemoved] = win;
                 mWindowsChanged = true;
-                if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
-                        "Rebuild removing window: " + win);
+                if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Rebuild removing window: " + win);
                 NW--;
                 numRemoved++;
                 continue;
@@ -7696,26 +7939,33 @@
         // in the main app list, but still have windows shown.  We put them
         // in the back because now that the animation is over we no longer
         // will care about them.
-        int NT = mExitingAppTokens.size();
+        AppTokenList exitingAppTokens = displayContent.mExitingAppTokens;
+        int NT = exitingAppTokens.size();
         for (int j=0; j<NT; j++) {
-            i = reAddAppWindowsLocked(displayContent, i, mExitingAppTokens.get(j));
+            i = reAddAppWindowsLocked(displayContent, i, exitingAppTokens.get(j));
         }
 
         // And add in the still active app tokens in Z order.
-        NT = mAnimatingAppTokens.size();
-        for (int j=0; j<NT; j++) {
-            i = reAddAppWindowsLocked(displayContent, i, mAnimatingAppTokens.get(j));
+        final ArrayList<Task> tasks = displayContent.getTasks();
+        final int numTasks = tasks.size();
+        for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
+            final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
+            final int numTokens = tokens.size();
+            for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) {
+                final AppWindowToken wtoken = tokens.get(tokenNdx);
+                i = reAddAppWindowsLocked(displayContent, i, wtoken);
+            }
         }
 
         i -= lastBelow;
         if (i != numRemoved) {
-            Slog.w(TAG, "Rebuild removed " + numRemoved
-                    + " windows but added " + i);
+            Slog.w(TAG, "Rebuild removed " + numRemoved + " windows but added " + i,
+                    new RuntimeException("here").fillInStackTrace());
             for (i=0; i<numRemoved; i++) {
                 WindowState ws = mRebuildTmp[i];
                 if (ws.mRebuilding) {
                     StringWriter sw = new StringWriter();
-                    PrintWriter pw = new PrintWriter(sw);
+                    PrintWriter pw = new FastPrintWriter(sw, false, 1024);
                     ws.dump(pw, "", true);
                     pw.flush();
                     Slog.w(TAG, "This window was lost: " + ws);
@@ -7724,7 +7974,7 @@
                 }
             }
             Slog.w(TAG, "Current app token list:");
-            dumpAnimatingAppTokensLocked();
+            dumpAppTokensLocked();
             Slog.w(TAG, "Final window list:");
             dumpWindowsLocked();
         }
@@ -7736,11 +7986,8 @@
         int curLayer = 0;
         int i;
 
-        if (DEBUG_LAYERS) {
-            RuntimeException here = new RuntimeException("here");
-            here.fillInStackTrace();
-            Slog.v(TAG, "Assigning layers", here);
-        }
+        if (DEBUG_LAYERS) Slog.v(TAG, "Assigning layers based on windows=" + windows,
+                new RuntimeException("here").fillInStackTrace());
 
         boolean anyLayerChanged = false;
 
@@ -7761,13 +8008,14 @@
                 layerChanged = true;
                 anyLayerChanged = true;
             }
+            final AppWindowToken wtoken = w.mAppToken;
             oldLayer = winAnimator.mAnimLayer;
             if (w.mTargetAppToken != null) {
                 winAnimator.mAnimLayer =
                         w.mLayer + w.mTargetAppToken.mAppAnimator.animLayerAdjustment;
-            } else if (w.mAppToken != null) {
+            } else if (wtoken != null) {
                 winAnimator.mAnimLayer =
-                        w.mLayer + w.mAppToken.mAppAnimator.animLayerAdjustment;
+                        w.mLayer + wtoken.mAppAnimator.animLayerAdjustment;
             } else {
                 winAnimator.mAnimLayer = w.mLayer;
             }
@@ -7780,15 +8028,15 @@
                 layerChanged = true;
                 anyLayerChanged = true;
             }
-            if (layerChanged && mAnimator.isDimmingLocked(winAnimator)) {
-                // Force an animation pass just to update the mDimAnimator layer.
+            if (layerChanged && w.getStack().isDimming(winAnimator)) {
+                // Force an animation pass just to update the mDimLayer layer.
                 scheduleAnimationLocked();
             }
             if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
                     + "mBase=" + w.mBaseLayer
                     + " mLayer=" + w.mLayer
-                    + (w.mAppToken == null ?
-                            "" : " mAppLayer=" + w.mAppToken.mAppAnimator.animLayerAdjustment)
+                    + (wtoken == null ?
+                            "" : " mAppLayer=" + wtoken.mAppAnimator.animLayerAdjustment)
                     + " =mAnimLayer=" + winAnimator.mAnimLayer);
             //System.out.println(
             //    "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
@@ -7926,6 +8174,10 @@
             mScreenRect.set(0, 0, dw, dh);
         }
 
+        Rect contentRect = new Rect();
+        mPolicy.getContentRectLw(contentRect);
+        displayContent.setStackBoxSize(contentRect);
+
         int seq = mLayoutSeq+1;
         if (seq < 0) seq = 0;
         mLayoutSeq = seq;
@@ -8331,12 +8583,8 @@
                     mAppTransition.getStartingPoint(p);
                     appAnimator.thumbnailX = p.x;
                     appAnimator.thumbnailY = p.y;
-                } catch (SurfaceControl.OutOfResourcesException e) {
-                    Slog.e(TAG, "Can't allocate thumbnail surface w=" + dirty.width()
-                            + " h=" + dirty.height(), e);
-                    appAnimator.clearThumbnail();
-                } catch (Surface.OutOfResourcesException e) {
-                    Slog.e(TAG, "Can't allocate Canvas surface w=" + dirty.width()
+                } catch (OutOfResourcesException e) {
+                    Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w=" + dirty.width()
                             + " h=" + dirty.height(), e);
                     appAnimator.clearThumbnail();
                 }
@@ -8375,11 +8623,17 @@
 
         mAppTransition.setIdle();
         // Restore window app tokens to the ActivityManager views
-        for (int i = mAnimatingAppTokens.size() - 1; i >= 0; i--) {
-            mAnimatingAppTokens.get(i).sendingToBottom = false;
+        final DisplayContent displayContent = getDefaultDisplayContentLocked();
+        final ArrayList<Task> tasks = displayContent.getTasks();
+        final int numTasks = tasks.size();
+        for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
+            final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
+            final int numTokens = tokens.size();
+            for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) {
+                final AppWindowToken wtoken = tokens.get(tokenNdx);
+                wtoken.sendingToBottom = false;
+            }
         }
-        mAnimatingAppTokens.clear();
-        mAnimatingAppTokens.addAll(mAppTokens);
         rebuildAppWindowListLocked();
 
         changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
@@ -8418,7 +8672,7 @@
                     || winAnimator.mSurfaceResized
                     || configChanged) {
                 if (DEBUG_RESIZE || DEBUG_ORIENTATION) {
-                    Slog.v(TAG, "Resize reasons: "
+                    Slog.v(TAG, "Resize reasons for w=" + w + ": "
                             + " contentInsetsChanged=" + w.mContentInsetsChanged
                             + " " + w.mContentInsets.toShortString()
                             + " visibleInsetsChanged=" + w.mVisibleInsetsChanged
@@ -8529,30 +8783,36 @@
         if ((attrs.flags & FLAG_DIM_BEHIND) != 0
                 && w.isDisplayedLw()
                 && !w.mExiting) {
-            mInnerFields.mDimming = true;
             final WindowStateAnimator winAnimator = w.mWinAnimator;
-            if (!mAnimator.isDimmingLocked(winAnimator)) {
+            final TaskStack stack = w.getStack();
+            stack.setDimmingTag();
+            if (!stack.isDimming(winAnimator)) {
                 if (localLOGV) Slog.v(TAG, "Win " + w + " start dimming.");
-                startDimmingLocked(winAnimator, w.mExiting ? 0 : w.mAttrs.dimAmount);
+                stack.startDimmingIfNeeded(winAnimator);
             }
         }
     }
 
-    private void updateAllDrawnLocked() {
+    private void updateAllDrawnLocked(DisplayContent displayContent) {
         // See if any windows have been drawn, so they (and others
         // associated with them) can now be shown.
-        final ArrayList<AppWindowToken> appTokens = mAnimatingAppTokens;
-        final int NT = appTokens.size();
-        for (int i=0; i<NT; i++) {
-            AppWindowToken wtoken = appTokens.get(i);
-            if (!wtoken.allDrawn) {
-                int numInteresting = wtoken.numInterestingWindows;
-                if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
-                    if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
-                            "allDrawn: " + wtoken
-                            + " interesting=" + numInteresting
-                            + " drawn=" + wtoken.numDrawnWindows);
-                    wtoken.allDrawn = true;
+        final ArrayList<Task> tasks = displayContent.getTasks();
+        final int numTasks = tasks.size();
+        for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
+            final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
+            final int numTokens = tokens.size();
+            for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) {
+                final AppWindowToken wtoken = tokens.get(tokenNdx);
+                if (!wtoken.allDrawn) {
+                    int numInteresting = wtoken.numInterestingWindows;
+                    if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
+                        if (DEBUG_VISIBILITY) Slog.v(TAG,
+                                "allDrawn: " + wtoken
+                                + " interesting=" + numInteresting
+                                + " drawn=" + wtoken.numDrawnWindows);
+                        wtoken.allDrawn = true;
+                        mH.obtainMessage(H.NOTIFY_ACTIVITY_DRAWN, wtoken.token).sendToTarget();
+                    }
                 }
             }
         }
@@ -8576,13 +8836,17 @@
         }
 
         // Initialize state of exiting tokens.
-        for (i=mExitingTokens.size()-1; i>=0; i--) {
-            mExitingTokens.get(i).hasVisible = false;
-        }
+        final int numDisplays = mDisplayContents.size();
+        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+            final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
+            for (i=displayContent.mExitingTokens.size()-1; i>=0; i--) {
+                displayContent.mExitingTokens.get(i).hasVisible = false;
+            }
 
-        // Initialize state of exiting applications.
-        for (i=mExitingAppTokens.size()-1; i>=0; i--) {
-            mExitingAppTokens.get(i).hasVisible = false;
+            // Initialize state of exiting applications.
+            for (i=displayContent.mExitingAppTokens.size()-1; i>=0; i--) {
+                displayContent.mExitingAppTokens.get(i).hasVisible = false;
+            }
         }
 
         mInnerFields.mHoldScreen = null;
@@ -8611,11 +8875,10 @@
             }
 
             boolean focusDisplayed = false;
-            boolean updateAllDrawn = false;
 
-        final int numDisplays = mDisplayContents.size();
-        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+            for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
                 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
+                boolean updateAllDrawn = false;
                 WindowList windows = displayContent.getWindowList();
                 DisplayInfo displayInfo = displayContent.getDisplayInfo();
                 final int displayId = displayContent.getDisplayId();
@@ -8694,8 +8957,8 @@
                 } while (displayContent.pendingLayoutChanges != 0);
 
                 mInnerFields.mObscured = false;
-                mInnerFields.mDimming = false;
                 mInnerFields.mSyswin = false;
+                displayContent.resetDimming();
 
                 // Only used if default window
                 final boolean someoneLosingFocus = !mLosingFocus.isEmpty();
@@ -8712,7 +8975,7 @@
                         handleNotObscuredLocked(w, currentTime, innerDw, innerDh);
                     }
 
-                    if (!mInnerFields.mDimming) {
+                    if (!w.getStack().testDimmingTag()) {
                         handleFlagDimBehind(w, innerDw, innerDh);
                     }
 
@@ -8760,7 +9023,7 @@
                                 // make this happen.
                                 displayContent.pendingLayoutChanges |=
                                         WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
-                                if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
+                                if (DEBUG_LAYOUT_REPEATS) {
                                     debugLayoutRepeats(
                                         "dream and commitFinishDrawingLocked true",
                                         displayContent.pendingLayoutChanges);
@@ -8772,7 +9035,7 @@
                                 mInnerFields.mWallpaperMayChange = true;
                                 displayContent.pendingLayoutChanges |=
                                         WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
-                                if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
+                                if (DEBUG_LAYOUT_REPEATS) {
                                     debugLayoutRepeats(
                                         "wallpaper and commitFinishDrawingLocked true",
                                         displayContent.pendingLayoutChanges);
@@ -8798,8 +9061,7 @@
                             }
                             if ((w.isOnScreen() || winAnimator.mAttrType == TYPE_BASE_APPLICATION)
                                     && !w.mExiting && !w.mDestroying) {
-                                if (WindowManagerService.DEBUG_VISIBILITY ||
-                                        WindowManagerService.DEBUG_ORIENTATION) {
+                                if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
                                     Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
                                             + ", isAnimating=" + winAnimator.isAnimating());
                                     if (!w.isDrawnLw()) {
@@ -8816,8 +9078,7 @@
                                         atoken.numInterestingWindows++;
                                         if (w.isDrawnLw()) {
                                             atoken.numDrawnWindows++;
-                                            if (WindowManagerService.DEBUG_VISIBILITY ||
-                                                    WindowManagerService.DEBUG_ORIENTATION) Slog.v(TAG,
+                                            if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG,
                                                     "tokenMayBeDrawn: " + atoken
                                                     + " freezingScreen=" + atoken.mAppAnimator.freezingScreen
                                                     + " mAppFreezing=" + w.mAppFreezing);
@@ -8855,13 +9116,11 @@
                 mDisplayManagerService.setDisplayHasContent(displayId, hasUniqueContent,
                         true /* inTraversal, must call performTraversalInTrans... below */);
 
-                if (!mInnerFields.mDimming && mAnimator.isDimmingLocked(displayId)) {
-                    stopDimmingLocked(displayId);
-                }
-            }
+                getDisplayContentLocked(displayId).stopDimmingIfNeeded();
 
-            if (updateAllDrawn) {
-                updateAllDrawnLocked();
+                if (updateAllDrawn) {
+                    updateAllDrawnLocked(displayContent);
+                }
             }
 
             if (focusDisplayed) {
@@ -8918,8 +9177,7 @@
         mInnerFields.mWallpaperForceHidingChanged = false;
 
         if (mInnerFields.mWallpaperMayChange) {
-            if (WindowManagerService.DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
-                    "Wallpaper may change!  Adjusting");
+            if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Wallpaper may change!  Adjusting");
             defaultDisplay.pendingLayoutChanges |=
                     WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
             if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("WallpaperMayChange",
@@ -9032,30 +9290,37 @@
         }
 
         // Time to remove any exiting tokens?
-        for (i=mExitingTokens.size()-1; i>=0; i--) {
-            WindowToken token = mExitingTokens.get(i);
-            if (!token.hasVisible) {
-                mExitingTokens.remove(i);
-                if (token.windowType == TYPE_WALLPAPER) {
-                    mWallpaperTokens.remove(token);
+        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+            final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
+            ArrayList<WindowToken> exitingTokens = displayContent.mExitingTokens;
+            for (i = exitingTokens.size() - 1; i >= 0; i--) {
+                WindowToken token = exitingTokens.get(i);
+                if (!token.hasVisible) {
+                    exitingTokens.remove(i);
+                    if (token.windowType == TYPE_WALLPAPER) {
+                        mWallpaperTokens.remove(token);
+                    }
                 }
             }
-        }
 
-        // Time to remove any exiting applications?
-        for (i=mExitingAppTokens.size()-1; i>=0; i--) {
-            AppWindowToken token = mExitingAppTokens.get(i);
-            if (!token.hasVisible && !mClosingApps.contains(token)) {
-                // Make sure there is no animation running on this token,
-                // so any windows associated with it will be removed as
-                // soon as their animations are complete
-                token.mAppAnimator.clearAnimation();
-                token.mAppAnimator.animating = false;
-                if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
-                        "performLayout: App token exiting now removed" + token);
-                mAppTokens.remove(token);
-                mAnimatingAppTokens.remove(token);
-                mExitingAppTokens.remove(i);
+            // Time to remove any exiting applications?
+            AppTokenList exitingAppTokens = displayContent.mExitingAppTokens;
+            for (i = exitingAppTokens.size() - 1; i >= 0; i--) {
+                AppWindowToken token = exitingAppTokens.get(i);
+                if (!token.hasVisible && !mClosingApps.contains(token)) {
+                    // Make sure there is no animation running on this token,
+                    // so any windows associated with it will be removed as
+                    // soon as their animations are complete
+                    token.mAppAnimator.clearAnimation();
+                    token.mAppAnimator.animating = false;
+                    if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
+                            "performLayout: App token exiting now removed" + token);
+                    final Task task = mTaskIdToTask.get(token.groupId);
+                    if (task != null && task.removeAppToken(token)) {
+                        mTaskIdToTask.delete(token.groupId);
+                    }
+                    exitingAppTokens.remove(i);
+                }
             }
         }
 
@@ -9075,7 +9340,6 @@
             defaultDisplay.layoutNeeded = true;
         }
 
-        final int numDisplays = mDisplayContents.size();
         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
             final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
             if (displayContent.pendingLayoutChanges != 0) {
@@ -9146,6 +9410,8 @@
             }
         }
 
+        setFocusedStackFrame();
+
         // Check to see if we are now in a state where the screen should
         // be enabled, because the window obscured flags have changed.
         enableScreenIfNeededLocked();
@@ -9255,14 +9521,6 @@
         }
     }
 
-    void startDimmingLocked(final WindowStateAnimator winAnimator, final float target) {
-        mAnimator.setDimWinAnimatorLocked(winAnimator.mWin.getDisplayId(), winAnimator);
-    }
-
-    void stopDimmingLocked(int displayId) {
-        mAnimator.setDimWinAnimatorLocked(displayId, null);
-    }
-
     private boolean needsLayout() {
         final int numDisplays = mDisplayContents.size();
         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
@@ -9309,6 +9567,20 @@
         return doRequest;
     }
 
+    /** If a window that has an animation specifying a colored background and the current wallpaper
+     * is visible, then the color goes *below* the wallpaper so we don't cause the wallpaper to
+     * suddenly disappear. */
+    int adjustAnimationBackground(WindowStateAnimator winAnimator) {
+        WindowList windows = winAnimator.mWin.getWindowList();
+        for (int i = windows.size() - 1; i >= 0; --i) {
+            WindowState testWin = windows.get(i);
+            if (testWin.mIsWallpaper && testWin.isVisibleNow()) {
+                return testWin.mWinAnimator.mAnimLayer;
+            }
+        }
+        return winAnimator.mAnimLayer;
+    }
+
     boolean reclaimSomeSurfaceMemoryLocked(WindowStateAnimator winAnimator, String operation,
                                            boolean secure) {
         final SurfaceControl surface = winAnimator.mSurfaceControl;
@@ -9328,6 +9600,7 @@
             // window list to make sure we haven't left any dangling surfaces
             // around.
 
+            Slog.i(TAG, "Out of memory for surface!  Looking for leaks...");
             final int numDisplays = mDisplayContents.size();
             for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
                 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
@@ -9428,24 +9701,25 @@
             // change message pending.
             mH.removeMessages(H.REPORT_FOCUS_CHANGE);
             mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
-            if (localLOGV) Slog.v(
+            // TODO(multidisplay): Focused windows on default display only.
+            final DisplayContent displayContent = getDefaultDisplayContentLocked();
+            final boolean imWindowChanged = moveInputMethodWindowsIfNeededLocked(
+                    mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS
+                            && mode != UPDATE_FOCUS_WILL_PLACE_SURFACES);
+            if (imWindowChanged) {
+                displayContent.layoutNeeded = true;
+                newFocus = computeFocusedWindowLocked();
+            }
+
+            if (DEBUG_FOCUS_LIGHT || localLOGV) Slog.v(
                 TAG, "Changing focus from " + mCurrentFocus + " to " + newFocus);
             final WindowState oldFocus = mCurrentFocus;
             mCurrentFocus = newFocus;
-            mAnimator.setCurrentFocus(newFocus);
             mLosingFocus.remove(newFocus);
             int focusChanged = mPolicy.focusChangedLw(oldFocus, newFocus);
 
-            // TODO(multidisplay): Focused windows on default display only.
-            final DisplayContent displayContent = getDefaultDisplayContentLocked();
-
-            final WindowState imWindow = mInputMethodWindow;
-            if (newFocus != imWindow && oldFocus != imWindow) {
-                if (moveInputMethodWindowsIfNeededLocked(
-                        mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS &&
-                        mode != UPDATE_FOCUS_WILL_PLACE_SURFACES)) {
-                    displayContent.layoutNeeded = true;
-                }
+            if (imWindowChanged && oldFocus != mInputMethodWindow) {
+                // Focus of the input method window changed. Perform layout if needed.
                 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
                     performLayoutLockedInner(displayContent, true /*initial*/, updateInputWindows);
                     focusChanged &= ~WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
@@ -9498,8 +9772,20 @@
     }
 
     private WindowState findFocusedWindowLocked(DisplayContent displayContent) {
-        int nextAppIndex = mAppTokens.size()-1;
-        WindowToken nextApp = nextAppIndex >= 0 ? mAppTokens.get(nextAppIndex) : null;
+        // Set nextApp to the first app and set taskNdx and tokenNdx to point to the app following.
+        final ArrayList<Task> tasks = displayContent.getTasks();
+        int taskNdx = tasks.size() - 1;
+        AppTokenList tokens = taskNdx >= 0 ? tasks.get(taskNdx).mAppTokens : null;
+        int tokenNdx = tokens != null ? tokens.size() - 1 : -1;
+        WindowToken nextApp = tokenNdx >= 0 ? tokens.get(tokenNdx) : null;
+        --tokenNdx;
+        if (tokenNdx < 0) {
+            --taskNdx;
+            if (taskNdx >= 0) {
+                tokens = tasks.get(taskNdx).mAppTokens;
+                tokenNdx = tokens.size() - 1;
+            }
+        }
 
         final WindowList windows = displayContent.getWindowList();
         for (int i = windows.size() - 1; i >= 0; i--) {
@@ -9515,8 +9801,8 @@
 
             // If this window's application has been removed, just skip it.
             if (thisApp != null && (thisApp.removed || thisApp.sendingToBottom)) {
-                if (DEBUG_FOCUS) Slog.v(TAG, "Skipping app because " + (thisApp.removed
-                        ? "removed" : "sendingToBottom"));
+                if (DEBUG_FOCUS) Slog.v(TAG, "Skipping " + thisApp + " because "
+                        + (thisApp.removed ? "removed" : "sendingToBottom"));
                 continue;
             }
 
@@ -9525,18 +9811,24 @@
             // through the app tokens until we find its app.
             if (thisApp != null && nextApp != null && thisApp != nextApp
                     && win.mAttrs.type != TYPE_APPLICATION_STARTING) {
-                int origAppIndex = nextAppIndex;
-                while (nextAppIndex > 0) {
-                    if (nextApp == mFocusedApp) {
-                        // Whoops, we are below the focused app...  no focus
-                        // for you!
-                        if (localLOGV || DEBUG_FOCUS) Slog.v(
-                            TAG, "Reached focused app: " + mFocusedApp);
-                        return null;
+                final WindowToken origAppToken = nextApp;
+                final int origTaskNdx = taskNdx;
+                final int origTokenNdx = tokenNdx;
+                for ( ; taskNdx >= 0; --taskNdx) {
+                    tokens = tasks.get(taskNdx).mAppTokens;
+                    for ( ; tokenNdx >= 0; --tokenNdx) {
+                        if (nextApp == mFocusedApp) {
+                            // Whoops, we are below the focused app...  no focus for you!
+                            if (localLOGV || DEBUG_FOCUS) Slog.v(
+                                TAG, "findFocusedWindow: Reached focused app=" + mFocusedApp);
+                            return null;
+                        }
+                        nextApp = tokens.get(tokenNdx);
+                        if (nextApp == thisApp) {
+                            break;
+                        }
                     }
-                    nextAppIndex--;
-                    nextApp = mAppTokens.get(nextAppIndex);
-                    if (nextApp == thisApp) {
+                    if (thisApp == nextApp) {
                         break;
                     }
                 }
@@ -9544,18 +9836,21 @@
                     // Uh oh, the app token doesn't exist!  This shouldn't
                     // happen, but if it does we can get totally hosed...
                     // so restart at the original app.
-                    nextAppIndex = origAppIndex;
-                    nextApp = mAppTokens.get(nextAppIndex);
+                    nextApp = origAppToken;
+                    // return indices to same place.
+                    taskNdx = origTaskNdx;
+                    tokenNdx = origTokenNdx;
                 }
             }
 
             // Dispatch to this window if it is wants key events.
             if (win.canReceiveKeys()) {
-                if (DEBUG_FOCUS) Slog.v(
-                        TAG, "Found focus @ " + i + " = " + win);
+                if (DEBUG_FOCUS_LIGHT) Slog.v(
+                        TAG, "findFocusedWindow: Found new focus @ " + i + " = " + win);
                 return win;
             }
         }
+        if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "findFocusedWindow: No focusable windows.");
         return null;
     }
 
@@ -9604,11 +9899,8 @@
             }
 
             // TODO(multidisplay): rotation on main screen only.
-            final Display display = displayContent.getDisplay();
-            final DisplayInfo displayInfo = displayContent.getDisplayInfo();
-            screenRotationAnimation = new ScreenRotationAnimation(mContext,
-                    display, mFxSession, inTransaction, displayInfo.logicalWidth,
-                    displayInfo.logicalHeight, display.getRotation());
+            screenRotationAnimation = new ScreenRotationAnimation(mContext, displayContent,
+                    mFxSession, inTransaction, mPolicy.isDefaultOrientationForced());
             mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
         }
     }
@@ -9656,7 +9948,7 @@
             // TODO(multidisplay): rotation on main screen only.
             DisplayInfo displayInfo = displayContent.getDisplayInfo();
             // Get rotation animation again, with new top window
-            boolean isDimming = mAnimator.isDimmingLocked(Display.DEFAULT_DISPLAY);
+            boolean isDimming = displayContent.isDimming();
             if (!mPolicy.validateRotationAnimationLw(mExitAnimId, mEnterAnimId, isDimming)) {
                 mExitAnimId = mEnterAnimId = 0;
             }
@@ -9926,15 +10218,6 @@
                 }
             }
         }
-        if (mAppTokens.size() > 0) {
-            pw.println();
-            pw.println("  Application tokens in Z order:");
-            for (int i=mAppTokens.size()-1; i>=0; i--) {
-                pw.print("  App #"); pw.print(i);
-                        pw.print(' '); pw.print(mAppTokens.get(i)); pw.println(":");
-                mAppTokens.get(i).dump(pw, "    ");
-            }
-        }
         if (mFinishedStarting.size() > 0) {
             pw.println();
             pw.println("  Finishing start of application tokens:");
@@ -9950,51 +10233,6 @@
                 }
             }
         }
-        if (mExitingTokens.size() > 0) {
-            pw.println();
-            pw.println("  Exiting tokens:");
-            for (int i=mExitingTokens.size()-1; i>=0; i--) {
-                WindowToken token = mExitingTokens.get(i);
-                pw.print("  Exiting #"); pw.print(i);
-                        pw.print(' '); pw.print(token);
-                if (dumpAll) {
-                    pw.println(':');
-                    token.dump(pw, "    ");
-                } else {
-                    pw.println();
-                }
-            }
-        }
-        if (mExitingAppTokens.size() > 0) {
-            pw.println();
-            pw.println("  Exiting application tokens:");
-            for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
-                WindowToken token = mExitingAppTokens.get(i);
-                pw.print("  Exiting App #"); pw.print(i);
-                        pw.print(' '); pw.print(token);
-                if (dumpAll) {
-                    pw.println(':');
-                    token.dump(pw, "    ");
-                } else {
-                    pw.println();
-                }
-            }
-        }
-        if (mAppTransition.isRunning() && mAnimatingAppTokens.size() > 0) {
-            pw.println();
-            pw.println("  Application tokens during animation:");
-            for (int i=mAnimatingAppTokens.size()-1; i>=0; i--) {
-                WindowToken token = mAnimatingAppTokens.get(i);
-                pw.print("  App moving to bottom #"); pw.print(i);
-                        pw.print(' '); pw.print(token);
-                if (dumpAll) {
-                    pw.println(':');
-                    token.dump(pw, "    ");
-                } else {
-                    pw.println();
-                }
-            }
-        }
         if (mOpeningApps.size() > 0 || mClosingApps.size() > 0) {
             pw.println();
             if (mOpeningApps.size() > 0) {
@@ -10023,7 +10261,8 @@
         if (mDisplayReady) {
             final int numDisplays = mDisplayContents.size();
             for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
-                mDisplayContents.valueAt(displayNdx).dump("  ", pw);
+                final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
+                displayContent.dump("  ", pw);
             }
         } else {
             pw.println("  NO DISPLAY");
@@ -10259,7 +10498,8 @@
             synchronized(mWindowMap) {
                 final int numDisplays = mDisplayContents.size();
                 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
-                    final WindowList windowList = mDisplayContents.valueAt(displayNdx).getWindowList();
+                    final WindowList windowList =
+                            mDisplayContents.valueAt(displayNdx).getWindowList();
                     for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
                         final WindowState w = windowList.get(winNdx);
                         if (name != null) {
@@ -10300,10 +10540,12 @@
      *
      * @param appWindowToken The application that ANR'd, may be null.
      * @param windowState The window that ANR'd, may be null.
+     * @param reason The reason for the ANR, may be null.
      */
-    public void saveANRStateLocked(AppWindowToken appWindowToken, WindowState windowState) {
+    public void saveANRStateLocked(AppWindowToken appWindowToken, WindowState windowState,
+            String reason) {
         StringWriter sw = new StringWriter();
-        PrintWriter pw = new PrintWriter(sw);
+        PrintWriter pw = new FastPrintWriter(sw, false, 1024);
         pw.println("  ANR time: " + DateFormat.getInstance().format(new Date()));
         if (appWindowToken != null) {
             pw.println("  Application at fault: " + appWindowToken.stringName);
@@ -10311,6 +10553,9 @@
         if (windowState != null) {
             pw.println("  Window at fault: " + windowState.mAttrs.getTitle());
         }
+        if (reason != null) {
+            pw.println("  Reason: " + reason);
+        }
         pw.println();
         dumpWindowsNoHeaderLocked(pw, true, null);
         pw.close();
@@ -10472,19 +10717,29 @@
     }
 
     private DisplayContent newDisplayContentLocked(final Display display) {
-        DisplayContent displayContent = new DisplayContent(display);
-        mDisplayContents.put(display.getDisplayId(), displayContent);
+        DisplayContent displayContent = new DisplayContent(display, this);
+        final int displayId = display.getDisplayId();
+        mDisplayContents.put(displayId, displayContent);
+
+        DisplayInfo displayInfo = displayContent.getDisplayInfo();
         final Rect rect = new Rect();
-        DisplayInfo info = displayContent.getDisplayInfo();
-        mDisplaySettings.getOverscanLocked(info.name, rect);
-        info.overscanLeft = rect.left;
-        info.overscanTop = rect.top;
-        info.overscanRight = rect.right;
-        info.overscanBottom = rect.bottom;
-        mDisplayManagerService.setOverscan(display.getDisplayId(), rect.left, rect.top,
-                rect.right, rect.bottom);
-        mPolicy.setDisplayOverscan(displayContent.getDisplay(), rect.left, rect.top,
-                rect.right, rect.bottom);
+        mDisplaySettings.getOverscanLocked(displayInfo.name, rect);
+        synchronized (displayContent.mDisplaySizeLock) {
+            displayInfo.overscanLeft = rect.left;
+            displayInfo.overscanTop = rect.top;
+            displayInfo.overscanRight = rect.right;
+            displayInfo.overscanBottom = rect.bottom;
+            mDisplayManagerService.setDisplayInfoOverrideFromWindowManager(
+                    displayId, displayInfo);
+        }
+        configureDisplayPolicyLocked(displayContent);
+
+        // TODO: Create an input channel for each display with touch capability.
+        if (displayId == Display.DEFAULT_DISPLAY) {
+            displayContent.mTapDetector = new StackTapPointerEventListener(this, displayContent);
+            registerPointerEventListener(displayContent.mTapDetector);
+        }
+
         return displayContent;
     }
 
@@ -10492,7 +10747,7 @@
         if (display == null) {
             throw new IllegalArgumentException("getDisplayContent: display must not be null");
         }
-        newDisplayContentLocked(display);
+        getDisplayContentLocked(display.getDisplayId());
     }
 
     /**
@@ -10566,6 +10821,10 @@
         final DisplayContent displayContent = getDisplayContentLocked(displayId);
         if (displayContent != null) {
             mDisplayContents.delete(displayId);
+            displayContent.close();
+            if (displayId == Display.DEFAULT_DISPLAY) {
+                unregisterPointerEventListener(displayContent.mTapDetector);
+            }
             WindowList windows = displayContent.getWindowList();
             while (!windows.isEmpty()) {
                 final WindowState win = windows.get(windows.size() - 1);
@@ -10586,4 +10845,9 @@
             displayContent.updateDisplayInfo();
         }
     }
+
+    @Override
+    public Object getWindowManagerLock() {
+        return mWindowMap;
+    }
 }
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index da15856..64b5a09 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -16,6 +16,9 @@
 
 package com.android.server.wm;
 
+import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
+import static com.android.server.wm.WindowManagerService.DEBUG_LAYOUT;
+
 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
@@ -65,11 +68,6 @@
 final class WindowState implements WindowManagerPolicy.WindowState {
     static final String TAG = "WindowState";
 
-    static final boolean DEBUG_VISIBILITY = WindowManagerService.DEBUG_VISIBILITY;
-    static final boolean SHOW_TRANSACTIONS = WindowManagerService.SHOW_TRANSACTIONS;
-    static final boolean SHOW_LIGHT_TRANSACTIONS = WindowManagerService.SHOW_LIGHT_TRANSACTIONS;
-    static final boolean SHOW_SURFACE_ALLOC = WindowManagerService.SHOW_SURFACE_ALLOC;
-
     final WindowManagerService mService;
     final WindowManagerPolicy mPolicy;
     final Context mContext;
@@ -300,6 +298,10 @@
     /** When true this window can be displayed on screens owther than mOwnerUid's */
     private boolean mShowToOwnerOnly;
 
+    /** When true this window is at the top of the screen and should be layed out to extend under
+     * the status bar */
+    boolean mUnderStatusBar = true;
+
     WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
            WindowState attachedWindow, int appOp, int seq, WindowManager.LayoutParams a,
            int viewVisibility, final DisplayContent displayContent) {
@@ -459,14 +461,20 @@
     public void computeFrameLw(Rect pf, Rect df, Rect of, Rect cf, Rect vf) {
         mHaveFrame = true;
 
-        final Rect container = mContainingFrame;
-        container.set(pf);
+        TaskStack stack = mAppToken != null ? getStack() : null;
+        if (stack != null && stack.hasSibling()) {
+            mContainingFrame.set(getStackBounds(stack));
+            if (mUnderStatusBar) {
+                mContainingFrame.top = pf.top;
+            }
+        } else {
+            mContainingFrame.set(pf);
+        }
 
-        final Rect display = mDisplayFrame;
-        display.set(df);
+        mDisplayFrame.set(df);
 
-        final int pw = container.right - container.left;
-        final int ph = container.bottom - container.top;
+        final int pw = mContainingFrame.width();
+        final int ph = mContainingFrame.height();
 
         int w,h;
         if ((mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0) {
@@ -513,18 +521,12 @@
             mContentChanged = true;
         }
 
-        final Rect overscan = mOverscanFrame;
-        overscan.set(of);
+        mOverscanFrame.set(of);
+        mContentFrame.set(cf);
+        mVisibleFrame.set(vf);
 
-        final Rect content = mContentFrame;
-        content.set(cf);
-
-        final Rect visible = mVisibleFrame;
-        visible.set(vf);
-
-        final Rect frame = mFrame;
-        final int fw = frame.width();
-        final int fh = frame.height();
+        final int fw = mFrame.width();
+        final int fh = mFrame.height();
 
         //System.out.println("In: w=" + w + " h=" + h + " container=" +
         //                   container + " x=" + mAttrs.x + " y=" + mAttrs.y);
@@ -538,75 +540,69 @@
             y = mAttrs.y;
         }
 
-        Gravity.apply(mAttrs.gravity, w, h, container,
+        Gravity.apply(mAttrs.gravity, w, h, mContainingFrame,
                 (int) (x + mAttrs.horizontalMargin * pw),
-                (int) (y + mAttrs.verticalMargin * ph), frame);
+                (int) (y + mAttrs.verticalMargin * ph), mFrame);
 
         //System.out.println("Out: " + mFrame);
 
         // Now make sure the window fits in the overall display.
-        Gravity.applyDisplay(mAttrs.gravity, df, frame);
+        Gravity.applyDisplay(mAttrs.gravity, df, mFrame);
 
         // Make sure the content and visible frames are inside of the
         // final window frame.
-        if (content.left < frame.left) content.left = frame.left;
-        if (content.top < frame.top) content.top = frame.top;
-        if (content.right > frame.right) content.right = frame.right;
-        if (content.bottom > frame.bottom) content.bottom = frame.bottom;
-        if (visible.left < frame.left) visible.left = frame.left;
-        if (visible.top < frame.top) visible.top = frame.top;
-        if (visible.right > frame.right) visible.right = frame.right;
-        if (visible.bottom > frame.bottom) visible.bottom = frame.bottom;
+        mContentFrame.set(Math.max(mContentFrame.left, mFrame.left),
+                Math.max(mContentFrame.top, mFrame.top),
+                Math.min(mContentFrame.right, mFrame.right),
+                Math.min(mContentFrame.bottom, mFrame.bottom));
 
-        final Rect overscanInsets = mOverscanInsets;
-        overscanInsets.left = overscan.left > frame.left ? overscan.left-frame.left : 0;
-        overscanInsets.top = overscan.top > frame.top ? overscan.top-frame.top : 0;
-        overscanInsets.right = overscan.right < frame.right ? frame.right-overscan.right : 0;
-        overscanInsets.bottom = overscan.bottom < frame.bottom ? frame.bottom-overscan.bottom : 0;
+        mVisibleFrame.set(Math.max(mVisibleFrame.left, mFrame.left),
+                Math.max(mVisibleFrame.top, mFrame.top),
+                Math.min(mVisibleFrame.right, mFrame.right),
+                Math.min(mVisibleFrame.bottom, mFrame.bottom));
 
-        final Rect contentInsets = mContentInsets;
-        contentInsets.left = content.left-frame.left;
-        contentInsets.top = content.top-frame.top;
-        contentInsets.right = frame.right-content.right;
-        contentInsets.bottom = frame.bottom-content.bottom;
+        mOverscanInsets.set(Math.max(mOverscanFrame.left - mFrame.left, 0),
+                Math.max(mOverscanFrame.top - mFrame.top, 0),
+                Math.max(mFrame.right - mOverscanFrame.right, 0),
+                Math.max(mFrame.bottom - mOverscanFrame.bottom, 0));
 
-        final Rect visibleInsets = mVisibleInsets;
-        visibleInsets.left = visible.left-frame.left;
-        visibleInsets.top = visible.top-frame.top;
-        visibleInsets.right = frame.right-visible.right;
-        visibleInsets.bottom = frame.bottom-visible.bottom;
+        mContentInsets.set(mContentFrame.left - mFrame.left,
+                mContentFrame.top - mFrame.top,
+                mFrame.right - mContentFrame.right,
+                mFrame.bottom - mContentFrame.bottom);
 
-        mCompatFrame.set(frame);
+        mVisibleInsets.set(mVisibleFrame.left - mFrame.left,
+                mVisibleFrame.top - mFrame.top,
+                mFrame.right - mVisibleFrame.right,
+                mFrame.bottom - mVisibleFrame.bottom);
+
+        mCompatFrame.set(mFrame);
         if (mEnforceSizeCompat) {
             // If there is a size compatibility scale being applied to the
             // window, we need to apply this to its insets so that they are
             // reported to the app in its coordinate space.
-            overscanInsets.scale(mInvGlobalScale);
-            contentInsets.scale(mInvGlobalScale);
-            visibleInsets.scale(mInvGlobalScale);
+            mOverscanInsets.scale(mInvGlobalScale);
+            mContentInsets.scale(mInvGlobalScale);
+            mVisibleInsets.scale(mInvGlobalScale);
 
             // Also the scaled frame that we report to the app needs to be
             // adjusted to be in its coordinate space.
             mCompatFrame.scale(mInvGlobalScale);
         }
 
-        if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) {
+        if (mIsWallpaper && (fw != mFrame.width() || fh != mFrame.height())) {
             final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
-            mService.updateWallpaperOffsetLocked(this, displayInfo.appWidth, displayInfo.appHeight,
-                    false);
+            mService.updateWallpaperOffsetLocked(this,
+                    displayInfo.logicalWidth, displayInfo.logicalHeight, false);
         }
 
-        if (WindowManagerService.localLOGV) {
-            //if ("com.google.android.youtube".equals(mAttrs.packageName)
-            //        && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
-                Slog.v(TAG, "Resolving (mRequestedWidth="
-                        + mRequestedWidth + ", mRequestedheight="
-                        + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
-                        + "): frame=" + mFrame.toShortString()
-                        + " ci=" + contentInsets.toShortString()
-                        + " vi=" + visibleInsets.toShortString());
-            //}
-        }
+        if (DEBUG_LAYOUT || WindowManagerService.localLOGV) Slog.v(TAG,
+                "Resolving (mRequestedWidth="
+                + mRequestedWidth + ", mRequestedheight="
+                + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
+                + "): frame=" + mFrame.toShortString()
+                + " ci=" + mContentInsets.toShortString()
+                + " vi=" + mVisibleInsets.toShortString());
     }
 
     @Override
@@ -707,6 +703,28 @@
         return mDisplayContent.getDisplayId();
     }
 
+    TaskStack getStack() {
+        AppWindowToken wtoken = mAppToken == null ? mService.mFocusedApp : mAppToken;
+        if (wtoken != null) {
+            Task task = mService.mTaskIdToTask.get(wtoken.groupId);
+            if (task != null) {
+                return task.mStack;
+            }
+        }
+        return mDisplayContent.getHomeStack();
+    }
+
+    Rect getStackBounds() {
+        return getStackBounds(getStack());
+    }
+
+    private Rect getStackBounds(TaskStack stack) {
+        if (stack != null) {
+            return stack.mStackBox.mBounds;
+        }
+        return mFrame;
+    }
+
     public long getInputDispatchingTimeoutNanos() {
         return mAppToken != null
                 ? mAppToken.inputDispatchingTimeoutNanos
@@ -901,7 +919,8 @@
                 || (atoken == null && mRootToken.hidden)
                 || (atoken != null && (atoken.hiddenRequested || atoken.hidden))
                 || mAttachedHidden
-                || mExiting || mDestroying;
+                || (mExiting && !isAnimatingLw())
+                || mDestroying;
     }
 
     /**
@@ -968,12 +987,6 @@
         return configChanged;
     }
 
-    boolean isConfigDiff(int mask) {
-        return mConfiguration != mService.mCurConfiguration
-                && mConfiguration != null
-                && (mConfiguration.diff(mService.mCurConfiguration) & mask) != 0;
-    }
-
     void removeLocked() {
         disposeInputChannel();
 
@@ -1026,7 +1039,7 @@
                     Slog.i(TAG, "WIN DEATH: " + win);
                     if (win != null) {
                         mService.removeWindowLocked(mSession, win);
-                    } else if (WindowState.this.mHasSurface) {
+                    } else if (mHasSurface) {
                         Slog.e(TAG, "!!! LEAK !!! Window removed but surface still valid.");
                         mService.removeWindowLocked(mSession, WindowState.this);
                     }
@@ -1129,6 +1142,8 @@
             // we allow the display to be enabled now.
             mService.enableScreenIfNeededLocked();
             if (mService.mCurrentFocus == this) {
+                if (WindowManagerService.DEBUG_FOCUS_LIGHT) Slog.i(TAG,
+                        "WindowState.hideLw: setting mFocusMayChange true");
                 mService.mFocusMayChange = true;
             }
         }
@@ -1138,7 +1153,7 @@
         return true;
     }
 
-    public boolean setAppOpVisibilityLw(boolean state) {
+    public void setAppOpVisibilityLw(boolean state) {
         if (mAppOpVisibility != state) {
             mAppOpVisibility = state;
             if (state) {
@@ -1148,13 +1163,11 @@
                 // ops modifies they should only be hidden by policy due to the
                 // lock screen, and the user won't be changing this if locked.
                 // Plus it will quickly be fixed the next time we do a layout.
-                showLw(true, false);
+                showLw(true, true);
             } else {
-                hideLw(true, false);
+                hideLw(true, true);
             }
-            return true;
         }
-        return false;
     }
 
     @Override
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index c07174b..533f626 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -3,6 +3,16 @@
 package com.android.server.wm;
 
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+import static com.android.server.wm.WindowManagerService.DEBUG_ANIM;
+import static com.android.server.wm.WindowManagerService.DEBUG_LAYERS;
+import static com.android.server.wm.WindowManagerService.DEBUG_ORIENTATION;
+import static com.android.server.wm.WindowManagerService.DEBUG_STARTING_WINDOW;
+import static com.android.server.wm.WindowManagerService.DEBUG_SURFACE_TRACE;
+import static com.android.server.wm.WindowManagerService.SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
+import static com.android.server.wm.WindowManagerService.SHOW_LIGHT_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerService.SHOW_SURFACE_ALLOC;
+import static com.android.server.wm.WindowManagerService.localLOGV;
 import static com.android.server.wm.WindowManagerService.LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE;
 import static com.android.server.wm.WindowManagerService.LayoutFields.SET_TURN_ON_SCREEN;
 
@@ -19,7 +29,7 @@
 import android.view.Display;
 import android.view.DisplayInfo;
 import android.view.MagnificationSpec;
-import android.view.Surface;
+import android.view.Surface.OutOfResourcesException;
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
 import android.view.WindowManager;
@@ -35,30 +45,12 @@
 import java.util.ArrayList;
 
 class WinAnimatorList extends ArrayList<WindowStateAnimator> {
-    public WinAnimatorList() {
-        super();
-    }
-
-    public WinAnimatorList(WinAnimatorList other) {
-        super(other);
-    }
 }
 
 /**
  * Keep track of animations and surface operations for a single WindowState.
  **/
 class WindowStateAnimator {
-    static final boolean DEBUG_VISIBILITY = WindowManagerService.DEBUG_VISIBILITY;
-    static final boolean DEBUG_ANIM = WindowManagerService.DEBUG_ANIM;
-    static final boolean DEBUG_LAYERS = WindowManagerService.DEBUG_LAYERS;
-    static final boolean DEBUG_STARTING_WINDOW = WindowManagerService.DEBUG_STARTING_WINDOW;
-    static final boolean SHOW_TRANSACTIONS = WindowManagerService.SHOW_TRANSACTIONS;
-    static final boolean SHOW_LIGHT_TRANSACTIONS = WindowManagerService.SHOW_LIGHT_TRANSACTIONS;
-    static final boolean SHOW_SURFACE_ALLOC = WindowManagerService.SHOW_SURFACE_ALLOC;
-    static final boolean localLOGV = WindowManagerService.localLOGV;
-    static final boolean DEBUG_ORIENTATION = WindowManagerService.DEBUG_ORIENTATION;
-    static final boolean DEBUG_SURFACE_TRACE = WindowManagerService.DEBUG_SURFACE_TRACE;
-
     static final String TAG = "WindowStateAnimator";
 
     // Unchanging local convenience fields.
@@ -340,7 +332,7 @@
         mHasTransformation = false;
         mHasLocalTransformation = false;
         if (mWin.mPolicyVisibility != mWin.mPolicyVisibilityAfterAnim) {
-            if (WindowState.DEBUG_VISIBILITY) {
+            if (DEBUG_VISIBILITY) {
                 Slog.v(TAG, "Policy visibility changing after anim in " + this + ": "
                         + mWin.mPolicyVisibilityAfterAnim);
             }
@@ -348,6 +340,8 @@
             mWin.mDisplayContent.layoutNeeded = true;
             if (!mWin.mPolicyVisibility) {
                 if (mService.mCurrentFocus == mWin) {
+                    if (WindowManagerService.DEBUG_FOCUS_LIGHT) Slog.i(TAG,
+                            "setAnimationLocked: setting mFocusMayChange true");
                     mService.mFocusMayChange = true;
                 }
                 // Window is no longer visible -- make sure if we were waiting
@@ -407,7 +401,7 @@
         if (mSurfaceControl != null) {
             mService.mDestroySurface.add(mWin);
             mWin.mDestroying = true;
-            if (WindowState.SHOW_TRANSACTIONS) WindowManagerService.logSurface(
+            if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(
                 mWin, "HIDE (finishExit)", null);
             hide();
         }
@@ -489,7 +483,7 @@
         private final Rect mWindowCrop = new Rect();
         private boolean mShown = false;
         private int mLayerStack;
-        private String mName;
+        private final String mName;
 
         public SurfaceTrace(SurfaceSession s,
                        String name, int w, int h, int format, int flags)
@@ -503,22 +497,22 @@
 
         @Override
         public void setAlpha(float alpha) {
-            super.setAlpha(alpha);
-            if (alpha != mSurfaceTraceAlpha) {
-                mSurfaceTraceAlpha = alpha;
-                Slog.v(SURFACE_TAG, "setAlpha: " + this + ". Called by "
+            if (mSurfaceTraceAlpha != alpha) {
+                Slog.v(SURFACE_TAG, "setAlpha(" + alpha + "): OLD:" + this + ". Called by "
                         + Debug.getCallers(3));
+                mSurfaceTraceAlpha = alpha;
             }
+            super.setAlpha(alpha);
         }
 
         @Override
         public void setLayer(int zorder) {
-            super.setLayer(zorder);
             if (zorder != mLayer) {
-                mLayer = zorder;
-                Slog.v(SURFACE_TAG, "setLayer: " + this + ". Called by "
+                Slog.v(SURFACE_TAG, "setLayer(" + zorder + "): OLD:" + this + ". Called by "
                         + Debug.getCallers(3));
+                mLayer = zorder;
             }
+            super.setLayer(zorder);
 
             sSurfaces.remove(this);
             int i;
@@ -533,69 +527,68 @@
 
         @Override
         public void setPosition(float x, float y) {
-            super.setPosition(x, y);
             if (x != mPosition.x || y != mPosition.y) {
+                Slog.v(SURFACE_TAG, "setPosition(" + x + "," + y + "): OLD:" + this
+                        + ". Called by " + Debug.getCallers(3));
                 mPosition.set(x, y);
-                Slog.v(SURFACE_TAG, "setPosition: " + this + ". Called by "
-                        + Debug.getCallers(3));
             }
+            super.setPosition(x, y);
         }
 
         @Override
         public void setSize(int w, int h) {
-            super.setSize(w, h);
             if (w != mSize.x || h != mSize.y) {
-                mSize.set(w, h);
-                Slog.v(SURFACE_TAG, "setSize: " + this + ". Called by "
+                Slog.v(SURFACE_TAG, "setSize(" + w + "," + h + "): OLD:" + this + ". Called by "
                         + Debug.getCallers(3));
+                mSize.set(w, h);
             }
+            super.setSize(w, h);
         }
 
         @Override
         public void setWindowCrop(Rect crop) {
-            super.setWindowCrop(crop);
             if (crop != null) {
                 if (!crop.equals(mWindowCrop)) {
+                    Slog.v(SURFACE_TAG, "setWindowCrop(" + crop.toShortString() + "): OLD:" + this
+                            + ". Called by " + Debug.getCallers(3));
                     mWindowCrop.set(crop);
-                    Slog.v(SURFACE_TAG, "setWindowCrop: " + this + ". Called by "
-                            + Debug.getCallers(3));
                 }
             }
+            super.setWindowCrop(crop);
         }
 
         @Override
         public void setLayerStack(int layerStack) {
-            super.setLayerStack(layerStack);
             if (layerStack != mLayerStack) {
+                Slog.v(SURFACE_TAG, "setLayerStack(" + layerStack + "): OLD:" + this
+                        + ". Called by " + Debug.getCallers(3));
                 mLayerStack = layerStack;
-                Slog.v(SURFACE_TAG, "setLayerStack: " + this + ". Called by " + Debug.getCallers(3));
             }
+            super.setLayerStack(layerStack);
         }
 
         @Override
         public void hide() {
-            super.hide();
             if (mShown) {
+                Slog.v(SURFACE_TAG, "hide: OLD:" + this + ". Called by " + Debug.getCallers(3));
                 mShown = false;
-                Slog.v(SURFACE_TAG, "hide: " + this + ". Called by "
-                        + Debug.getCallers(3));
             }
+            super.hide();
         }
+
         @Override
         public void show() {
-            super.show();
             if (!mShown) {
+                Slog.v(SURFACE_TAG, "show: OLD:" + this + ". Called by " + Debug.getCallers(3));
                 mShown = true;
-                Slog.v(SURFACE_TAG, "show: " + this + ". Called by "
-                        + Debug.getCallers(3));
             }
+            super.show();
         }
 
         @Override
         public void destroy() {
             super.destroy();
-            Slog.v(SURFACE_TAG, "destroy: " + this + ". Called by "
-                    + Debug.getCallers(3));
+            Slog.v(SURFACE_TAG, "destroy: " + this + ". Called by " + Debug.getCallers(3));
             sSurfaces.remove(this);
         }
 
@@ -648,7 +641,7 @@
             if ((attrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
                 flags |= SurfaceControl.SECURE;
             }
-            if (WindowState.DEBUG_VISIBILITY) Slog.v(
+            if (DEBUG_VISIBILITY) Slog.v(
                 TAG, "Creating surface in session "
                 + mSession.mSurfaceSession + " window " + this
                 + " w=" + mWin.mCompatFrame.width()
@@ -704,7 +697,7 @@
                         + attrs.format + " flags=0x"
                         + Integer.toHexString(flags)
                         + " / " + this);
-            } catch (SurfaceControl.OutOfResourcesException e) {
+            } catch (OutOfResourcesException e) {
                 mWin.mHasSurface = false;
                 Slog.w(TAG, "OutOfResourcesException creating surface");
                 mService.reclaimSomeSurfaceMemoryLocked(this, "create", true);
@@ -1185,7 +1178,7 @@
                 mAnimator.setPendingLayoutChanges(displayId,
                         WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
                 if ((w.mAttrs.flags & LayoutParams.FLAG_DIM_BEHIND) != 0) {
-                    mService.startDimmingLocked(this, w.mExiting ? 0 : w.mAttrs.dimAmount);
+                    w.getStack().startDimmingIfNeeded(this);
                 }
             } catch (RuntimeException e) {
                 // If something goes wrong with the surface (such
@@ -1282,6 +1275,11 @@
                             if (mIsWallpaper) {
                                 mService.dispatchWallpaperVisibility(w, 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.mOrientationChanging = false;
                         }
diff --git a/services/java/com/android/server/wm/WindowToken.java b/services/java/com/android/server/wm/WindowToken.java
index bd0ace8..2267123 100644
--- a/services/java/com/android/server/wm/WindowToken.java
+++ b/services/java/com/android/server/wm/WindowToken.java
@@ -19,7 +19,6 @@
 import android.os.IBinder;
 
 import java.io.PrintWriter;
-import java.util.ArrayList;
 
 /**
  * Container of a set of related windows in the window manager.  Often this
diff --git a/services/jni/Android.mk b/services/jni/Android.mk
index b313d48..98e9b30 100644
--- a/services/jni/Android.mk
+++ b/services/jni/Android.mk
@@ -3,7 +3,8 @@
 
 LOCAL_SRC_FILES:= \
     com_android_server_AlarmManagerService.cpp \
-    com_android_server_BatteryService.cpp \
+    com_android_server_AssetAtlasService.cpp \
+    com_android_server_ConsumerIrService.cpp \
     com_android_server_input_InputApplicationHandle.cpp \
     com_android_server_input_InputManagerService.cpp \
     com_android_server_input_InputWindowHandle.cpp \
@@ -15,6 +16,7 @@
     com_android_server_UsbHostManager.cpp \
     com_android_server_VibratorService.cpp \
     com_android_server_location_GpsLocationProvider.cpp \
+    com_android_server_location_FlpHardwareProvider.cpp \
     com_android_server_connectivity_Vpn.cpp \
     onload.cpp
 
@@ -22,6 +24,7 @@
     $(JNI_H_INCLUDE) \
     frameworks/base/services \
     frameworks/base/core/jni \
+    frameworks/native/services \
     external/skia/include/core \
     libcore/include \
     libcore/include/libsuspend \
@@ -31,19 +34,25 @@
 LOCAL_SHARED_LIBRARIES := \
     libandroid_runtime \
     libandroidfw \
+    libbinder \
     libcutils \
     liblog \
     libhardware \
     libhardware_legacy \
     libnativehelper \
-    libsystem_server \
     libutils \
     libui \
     libinput \
+    libinputservice \
+    libsensorservice \
     libskia \
     libgui \
     libusbhost \
-    libsuspend
+    libsuspend \
+    libEGL \
+    libGLESv2
+
+LOCAL_CFLAGS += -DEGL_EGLEXT_PROTOTYPES -DGL_GLEXT_PROTOTYPES
 
 ifeq ($(WITH_MALLOC_LEAK_CHECK),true)
     LOCAL_CFLAGS += -DMALLOC_LEAK_CHECK
diff --git a/services/jni/com_android_server_AssetAtlasService.cpp b/services/jni/com_android_server_AssetAtlasService.cpp
new file mode 100644
index 0000000..885d21e
--- /dev/null
+++ b/services/jni/com_android_server_AssetAtlasService.cpp
@@ -0,0 +1,272 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "AssetAtlasService"
+
+#include "jni.h"
+#include "JNIHelp.h"
+
+#include <android_view_GraphicBuffer.h>
+#include <cutils/log.h>
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include <SkCanvas.h>
+#include <SkBitmap.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+// Defines
+// ----------------------------------------------------------------------------
+
+// Defines how long to wait for the GPU when uploading the atlas
+// This timeout is defined in nanoseconds (see EGL_KHR_fence_sync extension)
+#define FENCE_TIMEOUT 2000000000
+
+// ----------------------------------------------------------------------------
+// JNI Helpers
+// ----------------------------------------------------------------------------
+
+static struct {
+    jfieldID mFinalizer;
+    jfieldID mNativeCanvas;
+} gCanvasClassInfo;
+
+static struct {
+    jfieldID mNativeCanvas;
+} gCanvasFinalizerClassInfo;
+
+#define GET_INT(object, field) \
+    env->GetIntField(object, field)
+
+#define SET_INT(object, field, value) \
+    env->SetIntField(object, field, value)
+
+// ----------------------------------------------------------------------------
+// Canvas management
+// ----------------------------------------------------------------------------
+
+static inline void swapCanvasPtr(JNIEnv* env, jobject canvasObj, SkCanvas* newCanvas) {
+    jobject canvasFinalizerObj = env->GetObjectField(canvasObj, gCanvasClassInfo.mFinalizer);
+    SkCanvas* previousCanvas = reinterpret_cast<SkCanvas*>(
+            GET_INT(canvasObj, gCanvasClassInfo.mNativeCanvas));
+    SET_INT(canvasObj, gCanvasClassInfo.mNativeCanvas, (int) newCanvas);
+    SET_INT(canvasFinalizerObj, gCanvasFinalizerClassInfo.mNativeCanvas, (int) newCanvas);
+    SkSafeUnref(previousCanvas);
+}
+
+static SkBitmap* com_android_server_AssetAtlasService_acquireCanvas(JNIEnv* env, jobject,
+        jobject canvas, jint width, jint height) {
+
+    SkBitmap* bitmap = new SkBitmap;
+    bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height);
+    bitmap->allocPixels();
+    bitmap->eraseColor(0);
+
+    SkCanvas* nativeCanvas = SkNEW_ARGS(SkCanvas, (*bitmap));
+    swapCanvasPtr(env, canvas, nativeCanvas);
+
+    return bitmap;
+}
+
+static void com_android_server_AssetAtlasService_releaseCanvas(JNIEnv* env, jobject,
+        jobject canvas, SkBitmap* bitmap) {
+
+    SkCanvas* nativeCanvas = SkNEW(SkCanvas);
+    swapCanvasPtr(env, canvas, nativeCanvas);
+
+    delete bitmap;
+}
+
+#define CLEANUP_GL_AND_RETURN(result) \
+    if (fence != EGL_NO_SYNC_KHR) eglDestroySyncKHR(display, fence); \
+    if (image) eglDestroyImageKHR(display, image); \
+    if (texture) glDeleteTextures(1, &texture); \
+    if (surface != EGL_NO_SURFACE) eglDestroySurface(display, surface); \
+    if (context != EGL_NO_CONTEXT) eglDestroyContext(display, context); \
+    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); \
+    eglReleaseThread(); \
+    eglTerminate(display); \
+    return result;
+
+static jboolean com_android_server_AssetAtlasService_upload(JNIEnv* env, jobject,
+        jobject graphicBuffer, SkBitmap* bitmap) {
+
+    // The goal of this method is to copy the bitmap into the GraphicBuffer
+    // using the GPU to swizzle the texture content
+    sp<GraphicBuffer> buffer(graphicBufferForJavaObject(env, graphicBuffer));
+
+    if (buffer != NULL) {
+        EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+        if (display == EGL_NO_DISPLAY) return false;
+
+        EGLint major;
+        EGLint minor;
+        if (!eglInitialize(display, &major, &minor)) {
+            ALOGW("Could not initialize EGL");
+            return false;
+        }
+
+        // We're going to use a 1x1 pbuffer surface later on
+        // The configuration doesn't really matter for what we're trying to do
+        EGLint configAttrs[] = {
+                EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+                EGL_RED_SIZE, 8,
+                EGL_GREEN_SIZE, 8,
+                EGL_BLUE_SIZE, 8,
+                EGL_ALPHA_SIZE, 0,
+                EGL_DEPTH_SIZE, 0,
+                EGL_STENCIL_SIZE, 0,
+                EGL_NONE
+        };
+        EGLConfig configs[1];
+        EGLint configCount;
+        if (!eglChooseConfig(display, configAttrs, configs, 1, &configCount)) {
+            ALOGW("Could not select EGL configuration");
+            eglReleaseThread();
+            eglTerminate(display);
+            return false;
+        }
+        if (configCount <= 0) {
+            ALOGW("Could not find EGL configuration");
+            eglReleaseThread();
+            eglTerminate(display);
+            return false;
+        }
+
+        // These objects are initialized below but the default "null"
+        // values are used to cleanup properly at any point in the
+        // initialization sequence
+        GLuint texture = 0;
+        EGLImageKHR image = EGL_NO_IMAGE_KHR;
+        EGLSurface surface = EGL_NO_SURFACE;
+        EGLSyncKHR fence = EGL_NO_SYNC_KHR;
+
+        EGLint attrs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
+        EGLContext context = eglCreateContext(display, configs[0], EGL_NO_CONTEXT, attrs);
+        if (context == EGL_NO_CONTEXT) {
+            ALOGW("Could not create EGL context");
+            CLEANUP_GL_AND_RETURN(false);
+        }
+
+        // Create the 1x1 pbuffer
+        EGLint surfaceAttrs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE };
+        surface = eglCreatePbufferSurface(display, configs[0], surfaceAttrs);
+        if (surface == EGL_NO_SURFACE) {
+            ALOGW("Could not create EGL surface");
+            CLEANUP_GL_AND_RETURN(false);
+        }
+
+        if (!eglMakeCurrent(display, surface, surface, context)) {
+            ALOGW("Could not change current EGL context");
+            CLEANUP_GL_AND_RETURN(false);
+        }
+
+        // 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();
+        EGLint imageAttrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
+        image = eglCreateImageKHR(display, EGL_NO_CONTEXT,
+                EGL_NATIVE_BUFFER_ANDROID, clientBuffer, imageAttrs);
+        if (image == EGL_NO_IMAGE_KHR) {
+            ALOGW("Could not create EGL image");
+            CLEANUP_GL_AND_RETURN(false);
+        }
+
+        glGenTextures(1, &texture);
+        glBindTexture(GL_TEXTURE_2D, texture);
+        glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
+        if (glGetError() != GL_NO_ERROR) {
+            ALOGW("Could not create/bind texture");
+            CLEANUP_GL_AND_RETURN(false);
+        }
+
+        // Upload the content of the bitmap in the GraphicBuffer
+        glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel());
+        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap->width(), bitmap->height(),
+                GL_RGBA, GL_UNSIGNED_BYTE, bitmap->getPixels());
+        if (glGetError() != GL_NO_ERROR) {
+            ALOGW("Could not upload to texture");
+            CLEANUP_GL_AND_RETURN(false);
+        }
+
+        // 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
+        fence = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, NULL);
+        if (fence == EGL_NO_SYNC_KHR) {
+            ALOGW("Could not create sync fence %#x", eglGetError());
+            CLEANUP_GL_AND_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, fence,
+                EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, FENCE_TIMEOUT);
+        if (waitStatus != EGL_CONDITION_SATISFIED_KHR) {
+            ALOGW("Failed to wait for the fence %#x", eglGetError());
+            CLEANUP_GL_AND_RETURN(false);
+        }
+
+        CLEANUP_GL_AND_RETURN(true);
+    }
+
+    return false;
+}
+
+// ----------------------------------------------------------------------------
+// JNI Glue
+// ----------------------------------------------------------------------------
+
+#define FIND_CLASS(var, className) \
+        var = env->FindClass(className); \
+        LOG_FATAL_IF(! var, "Unable to find class " className);
+
+#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
+        var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
+        LOG_FATAL_IF(! var, "Unable to find field " fieldName);
+
+const char* const kClassPathName = "com/android/server/AssetAtlasService";
+
+static JNINativeMethod gMethods[] = {
+    { "nAcquireAtlasCanvas", "(Landroid/graphics/Canvas;II)I",
+            (void*) com_android_server_AssetAtlasService_acquireCanvas },
+    { "nReleaseAtlasCanvas", "(Landroid/graphics/Canvas;I)V",
+            (void*) com_android_server_AssetAtlasService_releaseCanvas },
+    { "nUploadAtlas", "(Landroid/view/GraphicBuffer;I)Z",
+            (void*) com_android_server_AssetAtlasService_upload },
+};
+
+int register_android_server_AssetAtlasService(JNIEnv* env) {
+    jclass clazz;
+
+    FIND_CLASS(clazz, "android/graphics/Canvas");
+    GET_FIELD_ID(gCanvasClassInfo.mFinalizer, clazz, "mFinalizer",
+            "Landroid/graphics/Canvas$CanvasFinalizer;");
+    GET_FIELD_ID(gCanvasClassInfo.mNativeCanvas, clazz, "mNativeCanvas", "I");
+
+    FIND_CLASS(clazz, "android/graphics/Canvas$CanvasFinalizer");
+    GET_FIELD_ID(gCanvasFinalizerClassInfo.mNativeCanvas, clazz, "mNativeCanvas", "I");
+
+    return jniRegisterNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
+}
+
+};
diff --git a/services/jni/com_android_server_BatteryService.cpp b/services/jni/com_android_server_BatteryService.cpp
deleted file mode 100644
index 433950d..0000000
--- a/services/jni/com_android_server_BatteryService.cpp
+++ /dev/null
@@ -1,471 +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.
- */
-
-#define LOG_TAG "BatteryService"
-
-#include "JNIHelp.h"
-#include "jni.h"
-#include <utils/Log.h>
-#include <utils/misc.h>
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <linux/ioctl.h>
-#include <utils/Vector.h>
-#include <utils/String8.h>
-
-namespace android {
-
-#define POWER_SUPPLY_PATH "/sys/class/power_supply"
-
-struct FieldIds {
-    // members
-    jfieldID mAcOnline;
-    jfieldID mUsbOnline;
-    jfieldID mWirelessOnline;
-    jfieldID mBatteryStatus;
-    jfieldID mBatteryHealth;
-    jfieldID mBatteryPresent;
-    jfieldID mBatteryLevel;
-    jfieldID mBatteryVoltage;
-    jfieldID mBatteryTemperature;
-    jfieldID mBatteryTechnology;
-};
-static FieldIds gFieldIds;
-
-struct BatteryManagerConstants {
-    jint statusUnknown;
-    jint statusCharging;
-    jint statusDischarging;
-    jint statusNotCharging;
-    jint statusFull;
-    jint healthUnknown;
-    jint healthGood;
-    jint healthOverheat;
-    jint healthDead;
-    jint healthOverVoltage;
-    jint healthUnspecifiedFailure;
-    jint healthCold;
-};
-static BatteryManagerConstants gConstants;
-
-struct PowerSupplyPaths {
-    String8 batteryStatusPath;
-    String8 batteryHealthPath;
-    String8 batteryPresentPath;
-    String8 batteryCapacityPath;
-    String8 batteryVoltagePath;
-    String8 batteryTemperaturePath;
-    String8 batteryTechnologyPath;
-};
-static PowerSupplyPaths gPaths;
-
-static Vector<String8> gChargerNames;
-
-static int gVoltageDivisor = 1;
-
-enum PowerSupplyType {
-     ANDROID_POWER_SUPPLY_TYPE_UNKNOWN = 0,
-     ANDROID_POWER_SUPPLY_TYPE_AC,
-     ANDROID_POWER_SUPPLY_TYPE_USB,
-     ANDROID_POWER_SUPPLY_TYPE_WIRELESS,
-     ANDROID_POWER_SUPPLY_TYPE_BATTERY
-};
-
-static jint getBatteryStatus(const char* status)
-{
-    switch (status[0]) {
-        case 'C': return gConstants.statusCharging;         // Charging
-        case 'D': return gConstants.statusDischarging;      // Discharging
-        case 'F': return gConstants.statusFull;             // Full
-        case 'N': return gConstants.statusNotCharging;      // Not charging
-        case 'U': return gConstants.statusUnknown;          // Unknown
-            
-        default: {
-            ALOGW("Unknown battery status '%s'", status);
-            return gConstants.statusUnknown;
-        }
-    }
-}
-
-static jint getBatteryHealth(const char* status)
-{
-    switch (status[0]) {
-        case 'C': return gConstants.healthCold;         // Cold
-        case 'D': return gConstants.healthDead;         // Dead
-        case 'G': return gConstants.healthGood;         // Good
-        case 'O': {
-            if (strcmp(status, "Overheat") == 0) {
-                return gConstants.healthOverheat;
-            } else if (strcmp(status, "Over voltage") == 0) {
-                return gConstants.healthOverVoltage;
-            }
-            ALOGW("Unknown battery health[1] '%s'", status);
-            return gConstants.healthUnknown;
-        }
-        
-        case 'U': {
-            if (strcmp(status, "Unspecified failure") == 0) {
-                return gConstants.healthUnspecifiedFailure;
-            } else if (strcmp(status, "Unknown") == 0) {
-                return gConstants.healthUnknown;
-            }
-            // fall through
-        }
-            
-        default: {
-            ALOGW("Unknown battery health[2] '%s'", status);
-            return gConstants.healthUnknown;
-        }
-    }
-}
-
-static int readFromFile(const String8& path, char* buf, size_t size)
-{
-    if (path.isEmpty())
-        return -1;
-    int fd = open(path.string(), O_RDONLY, 0);
-    if (fd == -1) {
-        ALOGE("Could not open '%s'", path.string());
-        return -1;
-    }
-    
-    ssize_t count = read(fd, buf, size);
-    if (count > 0) {
-        while (count > 0 && buf[count-1] == '\n')
-            count--;
-        buf[count] = '\0';
-    } else {
-        buf[0] = '\0';
-    } 
-
-    close(fd);
-    return count;
-}
-
-static void setBooleanField(JNIEnv* env, jobject obj, const String8& path, jfieldID fieldID)
-{
-    const int SIZE = 16;
-    char buf[SIZE];
-    
-    jboolean value = false;
-    if (readFromFile(path, buf, SIZE) > 0) {
-        if (buf[0] != '0') {
-            value = true;
-        }
-    }
-    env->SetBooleanField(obj, fieldID, value);
-}
-
-static void setIntField(JNIEnv* env, jobject obj, const String8& path, jfieldID fieldID)
-{
-    const int SIZE = 128;
-    char buf[SIZE];
-    
-    jint value = 0;
-    if (readFromFile(path, buf, SIZE) > 0) {
-        value = atoi(buf);
-    }
-    env->SetIntField(obj, fieldID, value);
-}
-
-static void setVoltageField(JNIEnv* env, jobject obj, const String8& path, jfieldID fieldID)
-{
-    const int SIZE = 128;
-    char buf[SIZE];
-
-    jint value = 0;
-    if (readFromFile(path, buf, SIZE) > 0) {
-        value = atoi(buf);
-        value /= gVoltageDivisor;
-    }
-    env->SetIntField(obj, fieldID, value);
-}
-
-static PowerSupplyType readPowerSupplyType(const String8& path) {
-    const int SIZE = 128;
-    char buf[SIZE];
-    int length = readFromFile(path, buf, SIZE);
-
-    if (length <= 0)
-        return ANDROID_POWER_SUPPLY_TYPE_UNKNOWN;
-    if (buf[length - 1] == '\n')
-        buf[length - 1] = 0;
-    if (strcmp(buf, "Battery") == 0)
-        return ANDROID_POWER_SUPPLY_TYPE_BATTERY;
-    else if (strcmp(buf, "Mains") == 0 || strcmp(buf, "USB_DCP") == 0 ||
-             strcmp(buf, "USB_CDP") == 0 || strcmp(buf, "USB_ACA") == 0)
-        return ANDROID_POWER_SUPPLY_TYPE_AC;
-    else if (strcmp(buf, "USB") == 0)
-        return ANDROID_POWER_SUPPLY_TYPE_USB;
-    else if (strcmp(buf, "Wireless") == 0)
-        return ANDROID_POWER_SUPPLY_TYPE_WIRELESS;
-    else
-        return ANDROID_POWER_SUPPLY_TYPE_UNKNOWN;
-}
-
-static void android_server_BatteryService_update(JNIEnv* env, jobject obj)
-{
-    setBooleanField(env, obj, gPaths.batteryPresentPath, gFieldIds.mBatteryPresent);
-    
-    setIntField(env, obj, gPaths.batteryCapacityPath, gFieldIds.mBatteryLevel);
-    setVoltageField(env, obj, gPaths.batteryVoltagePath, gFieldIds.mBatteryVoltage);
-    setIntField(env, obj, gPaths.batteryTemperaturePath, gFieldIds.mBatteryTemperature);
-    
-    const int SIZE = 128;
-    char buf[SIZE];
-    
-    if (readFromFile(gPaths.batteryStatusPath, buf, SIZE) > 0)
-        env->SetIntField(obj, gFieldIds.mBatteryStatus, getBatteryStatus(buf));
-    else
-        env->SetIntField(obj, gFieldIds.mBatteryStatus,
-                         gConstants.statusUnknown);
-    
-    if (readFromFile(gPaths.batteryHealthPath, buf, SIZE) > 0)
-        env->SetIntField(obj, gFieldIds.mBatteryHealth, getBatteryHealth(buf));
-
-    if (readFromFile(gPaths.batteryTechnologyPath, buf, SIZE) > 0)
-        env->SetObjectField(obj, gFieldIds.mBatteryTechnology, env->NewStringUTF(buf));
-
-    unsigned int i;
-    String8 path;
-    jboolean acOnline = false;
-    jboolean usbOnline = false;
-    jboolean wirelessOnline = false;
-
-    for (i = 0; i < gChargerNames.size(); i++) {
-        path.clear();
-        path.appendFormat("%s/%s/online", POWER_SUPPLY_PATH,
-                          gChargerNames[i].string());
-
-        if (readFromFile(path, buf, SIZE) > 0) {
-            if (buf[0] != '0') {
-                path.clear();
-                path.appendFormat("%s/%s/type", POWER_SUPPLY_PATH,
-                                  gChargerNames[i].string());
-                switch(readPowerSupplyType(path)) {
-                case ANDROID_POWER_SUPPLY_TYPE_AC:
-                    acOnline = true;
-                    break;
-                case ANDROID_POWER_SUPPLY_TYPE_USB:
-                    usbOnline = true;
-                    break;
-                case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
-                    wirelessOnline = true;
-                    break;
-                default:
-                    ALOGW("%s: Unknown power supply type",
-                          gChargerNames[i].string());
-                }
-            }
-        }
-    }
-
-    env->SetBooleanField(obj, gFieldIds.mAcOnline, acOnline);
-    env->SetBooleanField(obj, gFieldIds.mUsbOnline, usbOnline);
-    env->SetBooleanField(obj, gFieldIds.mWirelessOnline, wirelessOnline);
-}
-
-static JNINativeMethod sMethods[] = {
-     /* name, signature, funcPtr */
-        {"native_update", "()V", (void*)android_server_BatteryService_update},
-};
-
-int register_android_server_BatteryService(JNIEnv* env)
-{
-    String8 path;
-    struct dirent* entry;
-
-    DIR* dir = opendir(POWER_SUPPLY_PATH);
-    if (dir == NULL) {
-        ALOGE("Could not open %s\n", POWER_SUPPLY_PATH);
-    } else {
-        while ((entry = readdir(dir))) {
-            const char* name = entry->d_name;
-
-            // ignore "." and ".."
-            if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) {
-                continue;
-            }
-
-            char buf[20];
-            // Look for "type" file in each subdirectory
-            path.clear();
-            path.appendFormat("%s/%s/type", POWER_SUPPLY_PATH, name);
-            switch(readPowerSupplyType(path)) {
-            case ANDROID_POWER_SUPPLY_TYPE_AC:
-            case ANDROID_POWER_SUPPLY_TYPE_USB:
-            case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
-                path.clear();
-                path.appendFormat("%s/%s/online", POWER_SUPPLY_PATH, name);
-                if (access(path.string(), R_OK) == 0)
-                    gChargerNames.add(String8(name));
-                break;
-
-            case ANDROID_POWER_SUPPLY_TYPE_BATTERY:
-                path.clear();
-                path.appendFormat("%s/%s/status", POWER_SUPPLY_PATH, name);
-                if (access(path, R_OK) == 0)
-                    gPaths.batteryStatusPath = path;
-                path.clear();
-                path.appendFormat("%s/%s/health", POWER_SUPPLY_PATH, name);
-                if (access(path, R_OK) == 0)
-                    gPaths.batteryHealthPath = path;
-                path.clear();
-                path.appendFormat("%s/%s/present", POWER_SUPPLY_PATH, name);
-                if (access(path, R_OK) == 0)
-                    gPaths.batteryPresentPath = path;
-                path.clear();
-                path.appendFormat("%s/%s/capacity", POWER_SUPPLY_PATH, name);
-                if (access(path, R_OK) == 0)
-                    gPaths.batteryCapacityPath = path;
-
-                path.clear();
-                path.appendFormat("%s/%s/voltage_now", POWER_SUPPLY_PATH, name);
-                if (access(path, R_OK) == 0) {
-                    gPaths.batteryVoltagePath = path;
-                    // voltage_now is in microvolts, not millivolts
-                    gVoltageDivisor = 1000;
-                } else {
-                    path.clear();
-                    path.appendFormat("%s/%s/batt_vol", POWER_SUPPLY_PATH, name);
-                    if (access(path, R_OK) == 0)
-                            gPaths.batteryVoltagePath = path;
-                }
-
-                path.clear();
-                path.appendFormat("%s/%s/temp", POWER_SUPPLY_PATH, name);
-                if (access(path, R_OK) == 0) {
-                    gPaths.batteryTemperaturePath = path;
-                } else {
-                    path.clear();
-                    path.appendFormat("%s/%s/batt_temp", POWER_SUPPLY_PATH, name);
-                    if (access(path, R_OK) == 0)
-                            gPaths.batteryTemperaturePath = path;
-                }
-
-                path.clear();
-                path.appendFormat("%s/%s/technology", POWER_SUPPLY_PATH, name);
-                if (access(path, R_OK) == 0)
-                    gPaths.batteryTechnologyPath = path;
-                break;
-            }
-        }
-        closedir(dir);
-    }
-
-    if (!gChargerNames.size())
-        ALOGE("No charger supplies found");
-    if (!gPaths.batteryStatusPath)
-        ALOGE("batteryStatusPath not found");
-    if (!gPaths.batteryHealthPath)
-        ALOGE("batteryHealthPath not found");
-    if (!gPaths.batteryPresentPath)
-        ALOGE("batteryPresentPath not found");
-    if (!gPaths.batteryCapacityPath)
-        ALOGE("batteryCapacityPath not found");
-    if (!gPaths.batteryVoltagePath)
-        ALOGE("batteryVoltagePath not found");
-    if (!gPaths.batteryTemperaturePath)
-        ALOGE("batteryTemperaturePath not found");
-    if (!gPaths.batteryTechnologyPath)
-        ALOGE("batteryTechnologyPath not found");
-
-    jclass clazz = env->FindClass("com/android/server/BatteryService");
-
-    if (clazz == NULL) {
-        ALOGE("Can't find com/android/server/BatteryService");
-        return -1;
-    }
-    
-    gFieldIds.mAcOnline = env->GetFieldID(clazz, "mAcOnline", "Z");
-    gFieldIds.mUsbOnline = env->GetFieldID(clazz, "mUsbOnline", "Z");
-    gFieldIds.mWirelessOnline = env->GetFieldID(clazz, "mWirelessOnline", "Z");
-    gFieldIds.mBatteryStatus = env->GetFieldID(clazz, "mBatteryStatus", "I");
-    gFieldIds.mBatteryHealth = env->GetFieldID(clazz, "mBatteryHealth", "I");
-    gFieldIds.mBatteryPresent = env->GetFieldID(clazz, "mBatteryPresent", "Z");
-    gFieldIds.mBatteryLevel = env->GetFieldID(clazz, "mBatteryLevel", "I");
-    gFieldIds.mBatteryTechnology = env->GetFieldID(clazz, "mBatteryTechnology", "Ljava/lang/String;");
-    gFieldIds.mBatteryVoltage = env->GetFieldID(clazz, "mBatteryVoltage", "I");
-    gFieldIds.mBatteryTemperature = env->GetFieldID(clazz, "mBatteryTemperature", "I");
-
-    LOG_FATAL_IF(gFieldIds.mAcOnline == NULL, "Unable to find BatteryService.AC_ONLINE_PATH");
-    LOG_FATAL_IF(gFieldIds.mUsbOnline == NULL, "Unable to find BatteryService.USB_ONLINE_PATH");
-    LOG_FATAL_IF(gFieldIds.mWirelessOnline == NULL, "Unable to find BatteryService.WIRELESS_ONLINE_PATH");
-    LOG_FATAL_IF(gFieldIds.mBatteryStatus == NULL, "Unable to find BatteryService.BATTERY_STATUS_PATH");
-    LOG_FATAL_IF(gFieldIds.mBatteryHealth == NULL, "Unable to find BatteryService.BATTERY_HEALTH_PATH");
-    LOG_FATAL_IF(gFieldIds.mBatteryPresent == NULL, "Unable to find BatteryService.BATTERY_PRESENT_PATH");
-    LOG_FATAL_IF(gFieldIds.mBatteryLevel == NULL, "Unable to find BatteryService.BATTERY_CAPACITY_PATH");
-    LOG_FATAL_IF(gFieldIds.mBatteryVoltage == NULL, "Unable to find BatteryService.BATTERY_VOLTAGE_PATH");
-    LOG_FATAL_IF(gFieldIds.mBatteryTemperature == NULL, "Unable to find BatteryService.BATTERY_TEMPERATURE_PATH");
-    LOG_FATAL_IF(gFieldIds.mBatteryTechnology == NULL, "Unable to find BatteryService.BATTERY_TECHNOLOGY_PATH");
-    
-    clazz = env->FindClass("android/os/BatteryManager");
-    
-    if (clazz == NULL) {
-        ALOGE("Can't find android/os/BatteryManager");
-        return -1;
-    }
-    
-    gConstants.statusUnknown = env->GetStaticIntField(clazz, 
-            env->GetStaticFieldID(clazz, "BATTERY_STATUS_UNKNOWN", "I"));
-            
-    gConstants.statusCharging = env->GetStaticIntField(clazz, 
-            env->GetStaticFieldID(clazz, "BATTERY_STATUS_CHARGING", "I"));
-            
-    gConstants.statusDischarging = env->GetStaticIntField(clazz, 
-            env->GetStaticFieldID(clazz, "BATTERY_STATUS_DISCHARGING", "I"));
-    
-    gConstants.statusNotCharging = env->GetStaticIntField(clazz, 
-            env->GetStaticFieldID(clazz, "BATTERY_STATUS_NOT_CHARGING", "I"));
-    
-    gConstants.statusFull = env->GetStaticIntField(clazz, 
-            env->GetStaticFieldID(clazz, "BATTERY_STATUS_FULL", "I"));
-
-    gConstants.healthUnknown = env->GetStaticIntField(clazz, 
-            env->GetStaticFieldID(clazz, "BATTERY_HEALTH_UNKNOWN", "I"));
-
-    gConstants.healthGood = env->GetStaticIntField(clazz, 
-            env->GetStaticFieldID(clazz, "BATTERY_HEALTH_GOOD", "I"));
-
-    gConstants.healthOverheat = env->GetStaticIntField(clazz, 
-            env->GetStaticFieldID(clazz, "BATTERY_HEALTH_OVERHEAT", "I"));
-
-    gConstants.healthDead = env->GetStaticIntField(clazz, 
-            env->GetStaticFieldID(clazz, "BATTERY_HEALTH_DEAD", "I"));
-
-    gConstants.healthOverVoltage = env->GetStaticIntField(clazz, 
-            env->GetStaticFieldID(clazz, "BATTERY_HEALTH_OVER_VOLTAGE", "I"));
-            
-    gConstants.healthUnspecifiedFailure = env->GetStaticIntField(clazz, 
-            env->GetStaticFieldID(clazz, "BATTERY_HEALTH_UNSPECIFIED_FAILURE", "I"));
-    
-    gConstants.healthCold = env->GetStaticIntField(clazz,
-            env->GetStaticFieldID(clazz, "BATTERY_HEALTH_COLD", "I"));
-
-    return jniRegisterNativeMethods(env, "com/android/server/BatteryService", sMethods, NELEM(sMethods));
-}
-
-} /* namespace android */
diff --git a/services/jni/com_android_server_ConsumerIrService.cpp b/services/jni/com_android_server_ConsumerIrService.cpp
new file mode 100644
index 0000000..004c0aa
--- /dev/null
+++ b/services/jni/com_android_server_ConsumerIrService.cpp
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "ConsumerIrService"
+
+#include "jni.h"
+#include "JNIHelp.h"
+#include "android_runtime/AndroidRuntime.h"
+
+#include <stdlib.h>
+#include <utils/misc.h>
+#include <utils/Log.h>
+#include <hardware/hardware.h>
+#include <hardware/consumerir.h>
+#include <ScopedPrimitiveArray.h>
+
+namespace android {
+
+static jint halOpen(JNIEnv *env, jobject obj) {
+    hw_module_t const* module;
+    consumerir_device_t *dev;
+    int err;
+
+    err = hw_get_module(CONSUMERIR_HARDWARE_MODULE_ID, &module);
+    if (err != 0) {
+        ALOGE("Can't open consumer IR HW Module, error: %d", err);
+        return 0;
+    }
+
+    err = module->methods->open(module, CONSUMERIR_TRANSMITTER,
+            (hw_device_t **) &dev);
+    if (err < 0) {
+        ALOGE("Can't open consumer IR transmitter, error: %d", err);
+        return 0;
+    }
+
+    return reinterpret_cast<jint>(dev);
+}
+
+static jint halTransmit(JNIEnv *env, jobject obj, jint halObject,
+   jint carrierFrequency, jintArray pattern) {
+    int ret;
+
+    consumerir_device_t *dev = reinterpret_cast<consumerir_device_t*>(halObject);
+    ScopedIntArrayRO cPattern(env, pattern);
+    if (cPattern.get() == NULL) {
+        return -EINVAL;
+    }
+    jsize patternLength = cPattern.size();
+
+    ret = dev->transmit(dev, carrierFrequency, cPattern.get(), patternLength);
+
+    return reinterpret_cast<jint>(ret);
+}
+
+static jintArray halGetCarrierFrequencies(JNIEnv *env, jobject obj,
+    jint halObject) {
+    consumerir_device_t *dev = (consumerir_device_t *) halObject;
+    consumerir_freq_range_t *ranges;
+    int len;
+
+    len = dev->get_num_carrier_freqs(dev);
+    if (len <= 0)
+        return NULL;
+
+    ranges = new consumerir_freq_range_t[len];
+
+    len = dev->get_carrier_freqs(dev, len, ranges);
+    if (len <= 0) {
+        delete[] ranges;
+        return NULL;
+    }
+
+    int i;
+    ScopedIntArrayRW freqsOut(env, env->NewIntArray(len*2));
+    jint *arr = freqsOut.get();
+    if (arr == NULL) {
+        delete[] ranges;
+        return NULL;
+    }
+    for (i = 0; i < len; i++) {
+        arr[i*2] = ranges[i].min;
+        arr[i*2+1] = ranges[i].max;
+    }
+
+    delete[] ranges;
+    return freqsOut.getJavaArray();
+}
+
+static JNINativeMethod method_table[] = {
+    { "halOpen", "()I", (void *)halOpen },
+    { "halTransmit", "(II[I)I", (void *)halTransmit },
+    { "halGetCarrierFrequencies", "(I)[I", (void *)halGetCarrierFrequencies},
+};
+
+int register_android_server_ConsumerIrService(JNIEnv *env) {
+    return jniRegisterNativeMethods(env, "com/android/server/ConsumerIrService",
+            method_table, NELEM(method_table));
+}
+
+};
diff --git a/services/jni/com_android_server_SystemServer.cpp b/services/jni/com_android_server_SystemServer.cpp
index ae29405..0625544 100644
--- a/services/jni/com_android_server_SystemServer.cpp
+++ b/services/jni/com_android_server_SystemServer.cpp
@@ -13,19 +13,25 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
+#include <jni.h>
+#include <JNIHelp.h>
+
+#include <sensorservice/SensorService.h>
+
+#include <cutils/properties.h>
 #include <utils/Log.h>
 #include <utils/misc.h>
 
-#include "jni.h"
-#include "JNIHelp.h"
-
 namespace android {
 
-extern "C" int system_init();
-
-static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz)
-{
-    system_init();
+static void android_server_SystemServer_nativeInit(JNIEnv* env, jobject clazz) {
+    char propBuf[PROPERTY_VALUE_MAX];
+    property_get("system_init.startsensorservice", propBuf, "1");
+    if (strcmp(propBuf, "1") == 0) {
+        // Start the sensor service
+        SensorService::instantiate();
+    }
 }
 
 /*
@@ -33,7 +39,7 @@
  */
 static JNINativeMethod gMethods[] = {
     /* name, signature, funcPtr */
-    { "init1", "([Ljava/lang/String;)V", (void*) android_server_SystemServer_init1 },
+    { "nativeInit", "()V", (void*) android_server_SystemServer_nativeInit },
 };
 
 int register_android_server_SystemServer(JNIEnv* env)
@@ -43,5 +49,3 @@
 }
 
 }; // namespace android
-
-
diff --git a/services/jni/com_android_server_UsbDeviceManager.cpp b/services/jni/com_android_server_UsbDeviceManager.cpp
index 0014db5..3551733 100644
--- a/services/jni/com_android_server_UsbDeviceManager.cpp
+++ b/services/jni/com_android_server_UsbDeviceManager.cpp
@@ -20,6 +20,7 @@
 #include "jni.h"
 #include "JNIHelp.h"
 #include "android_runtime/AndroidRuntime.h"
+#include "android_runtime/Log.h"
 
 #include <stdio.h>
 #include <asm/byteorder.h>
diff --git a/services/jni/com_android_server_UsbHostManager.cpp b/services/jni/com_android_server_UsbHostManager.cpp
index d0a6cdf..639790b7 100644
--- a/services/jni/com_android_server_UsbHostManager.cpp
+++ b/services/jni/com_android_server_UsbHostManager.cpp
@@ -20,6 +20,7 @@
 #include "jni.h"
 #include "JNIHelp.h"
 #include "android_runtime/AndroidRuntime.h"
+#include "android_runtime/Log.h"
 #include "utils/Vector.h"
 
 #include <usbhost/usbhost.h>
diff --git a/services/jni/com_android_server_input_InputManagerService.cpp b/services/jni/com_android_server_input_InputManagerService.cpp
index 09e5be4..4ab2086 100644
--- a/services/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/jni/com_android_server_input_InputManagerService.cpp
@@ -29,6 +29,7 @@
 #include "jni.h"
 #include <limits.h>
 #include <android_runtime/AndroidRuntime.h>
+#include <android_runtime/Log.h>
 
 #include <utils/Log.h>
 #include <utils/Looper.h>
@@ -191,7 +192,8 @@
             uint32_t policyFlags);
     virtual void notifyConfigurationChanged(nsecs_t when);
     virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
-            const sp<InputWindowHandle>& inputWindowHandle);
+            const sp<InputWindowHandle>& inputWindowHandle,
+            const String8& reason);
     virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle);
     virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags);
     virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig);
@@ -553,7 +555,7 @@
 }
 
 nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
-        const sp<InputWindowHandle>& inputWindowHandle) {
+        const sp<InputWindowHandle>& inputWindowHandle, const String8& reason) {
 #if DEBUG_INPUT_DISPATCHER_POLICY
     ALOGD("notifyANR");
 #endif
@@ -564,15 +566,18 @@
             getInputApplicationHandleObjLocalRef(env, inputApplicationHandle);
     jobject inputWindowHandleObj =
             getInputWindowHandleObjLocalRef(env, inputWindowHandle);
+    jstring reasonObj = env->NewStringUTF(reason.string());
 
     jlong newTimeout = env->CallLongMethod(mServiceObj,
-                gServiceClassInfo.notifyANR, inputApplicationHandleObj, inputWindowHandleObj);
+                gServiceClassInfo.notifyANR, inputApplicationHandleObj, inputWindowHandleObj,
+                reasonObj);
     if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
         newTimeout = 0; // abort dispatch
     } else {
         assert(newTimeout >= 0);
     }
 
+    env->DeleteLocalRef(reasonObj);
     env->DeleteLocalRef(inputWindowHandleObj);
     env->DeleteLocalRef(inputApplicationHandleObj);
     return newTimeout;
@@ -1379,7 +1384,7 @@
 
     GET_METHOD_ID(gServiceClassInfo.notifyANR, clazz,
             "notifyANR",
-            "(Lcom/android/server/input/InputApplicationHandle;Lcom/android/server/input/InputWindowHandle;)J");
+            "(Lcom/android/server/input/InputApplicationHandle;Lcom/android/server/input/InputWindowHandle;Ljava/lang/String;)J");
 
     GET_METHOD_ID(gServiceClassInfo.filterInputEvent, clazz,
             "filterInputEvent", "(Landroid/view/InputEvent;I)Z");
diff --git a/services/jni/com_android_server_location_FlpHardwareProvider.cpp b/services/jni/com_android_server_location_FlpHardwareProvider.cpp
new file mode 100644
index 0000000..ac269eb
--- /dev/null
+++ b/services/jni/com_android_server_location_FlpHardwareProvider.cpp
@@ -0,0 +1,1001 @@
+/*
+ * 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/license/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "FlpHardwareProvider"
+#define LOG_NDEBUG  0
+
+#define WAKE_LOCK_NAME  "FLP"
+#define LOCATION_CLASS_NAME "android/location/Location"
+
+#include "jni.h"
+#include "JNIHelp.h"
+#include "android_runtime/AndroidRuntime.h"
+#include "android_runtime/Log.h"
+#include "hardware/fused_location.h"
+#include "hardware_legacy/power.h"
+
+static jobject sCallbacksObj = NULL;
+static JNIEnv *sCallbackEnv = NULL;
+static hw_device_t* sHardwareDevice = NULL;
+
+static jmethodID sOnLocationReport = NULL;
+static jmethodID sOnDataReport = NULL;
+static jmethodID sOnGeofenceTransition = NULL;
+static jmethodID sOnGeofenceMonitorStatus = NULL;
+static jmethodID sOnGeofenceAdd = NULL;
+static jmethodID sOnGeofenceRemove = NULL;
+static jmethodID sOnGeofencePause = NULL;
+static jmethodID sOnGeofenceResume = NULL;
+
+static const FlpLocationInterface* sFlpInterface = NULL;
+static const FlpDiagnosticInterface* sFlpDiagnosticInterface = NULL;
+static const FlpGeofencingInterface* sFlpGeofencingInterface = NULL;
+static const FlpDeviceContextInterface* sFlpDeviceContextInterface = NULL;
+
+namespace android {
+
+static inline void CheckExceptions(JNIEnv* env, const char* methodName) {
+  if(!env->ExceptionCheck()) {
+    return;
+  }
+
+  ALOGE("An exception was thrown by '%s'.", methodName);
+  LOGE_EX(env);
+  env->ExceptionClear();
+}
+
+static inline void ThrowOnError(
+    JNIEnv* env,
+    int resultCode,
+    const char* methodName) {
+  if(resultCode == FLP_RESULT_SUCCESS) {
+    return;
+  }
+
+  ALOGE("Error %d in '%s'", resultCode, methodName);
+  env->FatalError(methodName);
+}
+
+static bool IsValidCallbackThread() {
+  JNIEnv* env = AndroidRuntime::getJNIEnv();
+
+  if(sCallbackEnv == NULL || sCallbackEnv != env) {
+    ALOGE("CallbackThread check fail: env=%p, expected=%p", env, sCallbackEnv);
+    return false;
+  }
+
+  return true;
+}
+
+static int SetThreadEvent(ThreadEvent event) {
+  JavaVM* javaVm = AndroidRuntime::getJavaVM();
+
+  switch(event) {
+    case ASSOCIATE_JVM:
+    {
+      if(sCallbackEnv != NULL) {
+        ALOGE(
+            "Attempted to associate callback in '%s'. Callback already associated.",
+            __FUNCTION__
+            );
+        return FLP_RESULT_ERROR;
+      }
+
+      JavaVMAttachArgs args = {
+          JNI_VERSION_1_6,
+          "FLP Service Callback Thread",
+          /* group */ NULL
+      };
+
+      jint attachResult = javaVm->AttachCurrentThread(&sCallbackEnv, &args);
+      if (attachResult != 0) {
+        ALOGE("Callback thread attachment error: %d", attachResult);
+        return FLP_RESULT_ERROR;
+      }
+
+      ALOGV("Callback thread attached: %p", sCallbackEnv);
+      break;
+    }
+    case DISASSOCIATE_JVM:
+    {
+      if (!IsValidCallbackThread()) {
+        ALOGE(
+            "Attempted to dissasociate an unnownk callback thread : '%s'.",
+            __FUNCTION__
+            );
+        return FLP_RESULT_ERROR;
+      }
+
+      if (javaVm->DetachCurrentThread() != 0) {
+        return FLP_RESULT_ERROR;
+      }
+
+      sCallbackEnv = NULL;
+      break;
+    }
+    default:
+      ALOGE("Invalid ThreadEvent request %d", event);
+      return FLP_RESULT_ERROR;
+  }
+
+  return FLP_RESULT_SUCCESS;
+}
+
+/*
+ * Initializes the FlpHardwareProvider class from the native side by opening
+ * the HW module and obtaining the proper interfaces.
+ */
+static void ClassInit(JNIEnv* env, jclass clazz) {
+  // get references to the Java provider methods
+  sOnLocationReport = env->GetMethodID(
+      clazz,
+      "onLocationReport",
+      "([Landroid/location/Location;)V");
+  sOnDataReport = env->GetMethodID(
+      clazz,
+      "onDataReport",
+      "(Ljava/lang/String;)V"
+      );
+  sOnGeofenceTransition = env->GetMethodID(
+      clazz,
+      "onGeofenceTransition",
+      "(ILandroid/location/Location;IJI)V"
+      );
+  sOnGeofenceMonitorStatus = env->GetMethodID(
+      clazz,
+      "onGeofenceMonitorStatus",
+      "(IILandroid/location/Location;)V"
+      );
+  sOnGeofenceAdd = env->GetMethodID(clazz, "onGeofenceAdd", "(II)V");
+  sOnGeofenceRemove = env->GetMethodID(clazz, "onGeofenceRemove", "(II)V");
+  sOnGeofencePause = env->GetMethodID(clazz, "onGeofencePause", "(II)V");
+  sOnGeofenceResume = env->GetMethodID(clazz, "onGeofenceResume", "(II)V");
+}
+
+/*
+ * Helper function to unwrap a java object back into a FlpLocation structure.
+ */
+static void TranslateFromObject(
+    JNIEnv* env,
+    jobject locationObject,
+    FlpLocation& location) {
+  location.size = sizeof(FlpLocation);
+  location.flags = 0;
+
+  jclass locationClass = env->GetObjectClass(locationObject);
+
+  jmethodID getLatitude = env->GetMethodID(locationClass, "getLatitude", "()D");
+  location.latitude = env->CallDoubleMethod(locationObject, getLatitude);
+  jmethodID getLongitude = env->GetMethodID(locationClass, "getLongitude", "()D");
+  location.longitude = env->CallDoubleMethod(locationObject, getLongitude);
+  jmethodID getTime = env->GetMethodID(locationClass, "getTime", "()J");
+  location.timestamp = env->CallLongMethod(locationObject, getTime);
+  location.flags |= FLP_LOCATION_HAS_LAT_LONG;
+
+  jmethodID hasAltitude = env->GetMethodID(locationClass, "hasAltitude", "()Z");
+  if (env->CallBooleanMethod(locationObject, hasAltitude)) {
+    jmethodID getAltitude = env->GetMethodID(locationClass, "getAltitude", "()D");
+    location.altitude = env->CallDoubleMethod(locationObject, getAltitude);
+    location.flags |= FLP_LOCATION_HAS_ALTITUDE;
+  }
+
+  jmethodID hasSpeed = env->GetMethodID(locationClass, "hasSpeed", "()Z");
+  if (env->CallBooleanMethod(locationObject, hasSpeed)) {
+    jmethodID getSpeed = env->GetMethodID(locationClass, "getSpeed", "()F");
+    location.speed = env->CallFloatMethod(locationObject, getSpeed);
+    location.flags |= FLP_LOCATION_HAS_SPEED;
+  }
+
+  jmethodID hasBearing = env->GetMethodID(locationClass, "hasBearing", "()Z");
+  if (env->CallBooleanMethod(locationObject, hasBearing)) {
+    jmethodID getBearing = env->GetMethodID(locationClass, "getBearing", "()F");
+    location.bearing = env->CallFloatMethod(locationObject, getBearing);
+    location.flags |= FLP_LOCATION_HAS_BEARING;
+  }
+
+  jmethodID hasAccuracy = env->GetMethodID(locationClass, "hasAccuracy", "()Z");
+  if (env->CallBooleanMethod(locationObject, hasAccuracy)) {
+    jmethodID getAccuracy = env->GetMethodID(
+        locationClass,
+        "getAccuracy",
+        "()F"
+        );
+    location.accuracy = env->CallFloatMethod(locationObject, getAccuracy);
+    location.flags |= FLP_LOCATION_HAS_ACCURACY;
+  }
+
+  // TODO: wire sources_used if Location class exposes them
+
+  env->DeleteLocalRef(locationClass);
+}
+
+/*
+ * Helper function to unwrap FlpBatchOptions from the Java Runtime calls.
+ */
+static void TranslateFromObject(
+    JNIEnv* env,
+    jobject batchOptionsObject,
+    FlpBatchOptions& batchOptions) {
+  jclass batchOptionsClass = env->GetObjectClass(batchOptionsObject);
+
+  jmethodID getMaxPower = env->GetMethodID(
+      batchOptionsClass,
+      "getMaxPowerAllocationInMW",
+      "()D"
+      );
+  batchOptions.max_power_allocation_mW = env->CallDoubleMethod(
+      batchOptionsObject,
+      getMaxPower
+      );
+
+  jmethodID getPeriod = env->GetMethodID(
+      batchOptionsClass,
+      "getPeriodInNS",
+      "()J"
+      );
+  batchOptions.period_ns = env->CallLongMethod(batchOptionsObject, getPeriod);
+
+  jmethodID getSourcesToUse = env->GetMethodID(
+      batchOptionsClass,
+      "getSourcesToUse",
+      "()I"
+      );
+  batchOptions.sources_to_use = env->CallIntMethod(
+      batchOptionsObject,
+      getSourcesToUse
+      );
+
+  jmethodID getFlags = env->GetMethodID(batchOptionsClass, "getFlags", "()I");
+  batchOptions.flags = env->CallIntMethod(batchOptionsObject, getFlags);
+
+  env->DeleteLocalRef(batchOptionsClass);
+}
+
+/*
+ * Helper function to unwrap Geofence structures from the Java Runtime calls.
+ */
+static void TranslateGeofenceFromGeofenceHardwareRequestParcelable(
+    JNIEnv* env,
+    jobject geofenceRequestObject,
+    Geofence& geofence) {
+  jclass geofenceRequestClass = env->GetObjectClass(geofenceRequestObject);
+
+  jmethodID getId = env->GetMethodID(geofenceRequestClass, "getId", "()I");
+  geofence.geofence_id = env->CallIntMethod(geofenceRequestObject, getId);
+
+  jmethodID getType = env->GetMethodID(geofenceRequestClass, "getType", "()I");
+  // this works because GeofenceHardwareRequest.java and fused_location.h have
+  // the same notion of geofence types
+  GeofenceType type = (GeofenceType)env->CallIntMethod(geofenceRequestObject, getType);
+  if(type != TYPE_CIRCLE) {
+    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
+  }
+  geofence.data->type = type;
+  GeofenceCircle& circle = geofence.data->geofence.circle;
+
+  jmethodID getLatitude = env->GetMethodID(
+      geofenceRequestClass,
+      "getLatitude",
+      "()D");
+  circle.latitude = env->CallDoubleMethod(geofenceRequestObject, getLatitude);
+
+  jmethodID getLongitude = env->GetMethodID(
+      geofenceRequestClass,
+      "getLongitude",
+      "()D");
+  circle.longitude = env->CallDoubleMethod(geofenceRequestObject, getLongitude);
+
+  jmethodID getRadius = env->GetMethodID(geofenceRequestClass, "getRadius", "()D");
+  circle.radius_m = env->CallDoubleMethod(geofenceRequestObject, getRadius);
+
+  GeofenceOptions* options = geofence.options;
+  jmethodID getMonitorTransitions = env->GetMethodID(
+      geofenceRequestClass,
+      "getMonitorTransitions",
+      "()I");
+  options->monitor_transitions = env->CallIntMethod(
+      geofenceRequestObject,
+      getMonitorTransitions);
+
+  jmethodID getUnknownTimer = env->GetMethodID(
+      geofenceRequestClass,
+      "getUnknownTimer",
+      "()I");
+  options->unknown_timer_ms = env->CallIntMethod(geofenceRequestObject, getUnknownTimer);
+
+  jmethodID getNotificationResponsiveness = env->GetMethodID(
+      geofenceRequestClass,
+      "getNotificationResponsiveness",
+      "()I");
+  options->notification_responsivenes_ms = env->CallIntMethod(
+      geofenceRequestObject,
+      getNotificationResponsiveness);
+
+  jmethodID getLastTransition = env->GetMethodID(
+      geofenceRequestClass,
+      "getLastTransition",
+      "()I");
+  options->last_transition = env->CallIntMethod(geofenceRequestObject, getLastTransition);
+
+  // TODO: set data.sources_to_use when available
+
+  env->DeleteLocalRef(geofenceRequestClass);
+}
+
+/*
+ * Helper function to transform FlpLocation into a java object.
+ */
+static void TranslateToObject(const FlpLocation* location, jobject& locationObject) {
+  jclass locationClass = sCallbackEnv->FindClass(LOCATION_CLASS_NAME);
+  jmethodID locationCtor = sCallbackEnv->GetMethodID(
+      locationClass,
+      "<init>",
+      "(Ljava/lang/String;)V"
+      );
+
+  // the provider is set in the upper JVM layer
+  locationObject = sCallbackEnv->NewObject(locationClass, locationCtor, NULL);
+  jint flags = location->flags;
+
+  // set the valid information in the object
+  if (flags & FLP_LOCATION_HAS_LAT_LONG) {
+    jmethodID setLatitude = sCallbackEnv->GetMethodID(
+        locationClass,
+        "setLatitude",
+        "(D)V"
+        );
+    sCallbackEnv->CallVoidMethod(locationObject, setLatitude, location->latitude);
+
+    jmethodID setLongitude = sCallbackEnv->GetMethodID(
+        locationClass,
+        "setLongitude",
+        "(D)V"
+        );
+    sCallbackEnv->CallVoidMethod(
+        locationObject,
+        setLongitude,
+        location->longitude
+        );
+
+    jmethodID setTime = sCallbackEnv->GetMethodID(
+        locationClass,
+        "setTime",
+        "(J)V"
+        );
+    sCallbackEnv->CallVoidMethod(locationObject, setTime, location->timestamp);
+  }
+
+  if (flags & FLP_LOCATION_HAS_ALTITUDE) {
+    jmethodID setAltitude = sCallbackEnv->GetMethodID(
+        locationClass,
+        "setAltitude",
+        "(D)V"
+        );
+    sCallbackEnv->CallVoidMethod(locationObject, setAltitude, location->altitude);
+  }
+
+  if (flags & FLP_LOCATION_HAS_SPEED) {
+    jmethodID setSpeed = sCallbackEnv->GetMethodID(
+        locationClass,
+        "setSpeed",
+        "(F)V"
+        );
+    sCallbackEnv->CallVoidMethod(locationObject, setSpeed, location->speed);
+  }
+
+  if (flags & FLP_LOCATION_HAS_BEARING) {
+    jmethodID setBearing = sCallbackEnv->GetMethodID(
+        locationClass,
+        "setBearing",
+        "(F)V"
+        );
+    sCallbackEnv->CallVoidMethod(locationObject, setBearing, location->bearing);
+  }
+
+  if (flags & FLP_LOCATION_HAS_ACCURACY) {
+    jmethodID setAccuracy = sCallbackEnv->GetMethodID(
+        locationClass,
+        "setAccuracy",
+        "(F)V"
+        );
+    sCallbackEnv->CallVoidMethod(locationObject, setAccuracy, location->accuracy);
+  }
+
+  // TODO: wire FlpLocation::sources_used when needed
+
+  sCallbackEnv->DeleteLocalRef(locationClass);
+}
+
+/*
+ * Helper function to serialize FlpLocation structures.
+ */
+static void TranslateToObjectArray(
+    int32_t locationsCount,
+    FlpLocation** locations,
+    jobjectArray& locationsArray) {
+  jclass locationClass = sCallbackEnv->FindClass(LOCATION_CLASS_NAME);
+  locationsArray = sCallbackEnv->NewObjectArray(
+      locationsCount,
+      locationClass,
+      /* initialElement */ NULL
+      );
+
+  for (int i = 0; i < locationsCount; ++i) {
+    jobject locationObject = NULL;
+    TranslateToObject(locations[i], locationObject);
+    sCallbackEnv->SetObjectArrayElement(locationsArray, i, locationObject);
+    sCallbackEnv->DeleteLocalRef(locationObject);
+  }
+
+  sCallbackEnv->DeleteLocalRef(locationClass);
+}
+
+static void LocationCallback(int32_t locationsCount, FlpLocation** locations) {
+  if(!IsValidCallbackThread()) {
+    return;
+  }
+
+  if(locationsCount == 0 || locations == NULL) {
+    ALOGE(
+        "Invalid LocationCallback. Count: %d, Locations: %p",
+        locationsCount,
+        locations
+        );
+    return;
+  }
+
+  jobjectArray locationsArray = NULL;
+  TranslateToObjectArray(locationsCount, locations, locationsArray);
+
+  sCallbackEnv->CallVoidMethod(
+      sCallbacksObj,
+      sOnLocationReport,
+      locationsArray
+      );
+  CheckExceptions(sCallbackEnv, __FUNCTION__);
+
+  if(locationsArray != NULL) {
+    sCallbackEnv->DeleteLocalRef(locationsArray);
+  }
+}
+
+static void AcquireWakelock() {
+  acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
+}
+
+static void ReleaseWakelock() {
+  release_wake_lock(WAKE_LOCK_NAME);
+}
+
+FlpCallbacks sFlpCallbacks = {
+  sizeof(FlpCallbacks),
+  LocationCallback,
+  AcquireWakelock,
+  ReleaseWakelock,
+  SetThreadEvent
+};
+
+static void ReportData(char* data, int length) {
+  jstring stringData = NULL;
+
+  if(length != 0 && data != NULL) {
+    stringData = sCallbackEnv->NewString(reinterpret_cast<jchar*>(data), length);
+  } else {
+    ALOGE("Invalid ReportData callback. Length: %d, Data: %p", length, data);
+    return;
+  }
+
+  sCallbackEnv->CallVoidMethod(sCallbacksObj, sOnDataReport, stringData);
+  CheckExceptions(sCallbackEnv, __FUNCTION__);
+}
+
+FlpDiagnosticCallbacks sFlpDiagnosticCallbacks = {
+  sizeof(FlpDiagnosticCallbacks),
+  SetThreadEvent,
+  ReportData
+};
+
+static void GeofenceTransitionCallback(
+    int32_t geofenceId,
+    FlpLocation* location,
+    int32_t transition,
+    FlpUtcTime timestamp,
+    uint32_t sourcesUsed
+    ) {
+  if(!IsValidCallbackThread()) {
+    return;
+  }
+
+  if(location == NULL) {
+    ALOGE("GeofenceTransition received with invalid location: %p", location);
+    return;
+  }
+
+  jobject locationObject = NULL;
+  TranslateToObject(location, locationObject);
+
+  sCallbackEnv->CallVoidMethod(
+      sCallbacksObj,
+      sOnGeofenceTransition,
+      geofenceId,
+      locationObject,
+      transition,
+      timestamp,
+      sourcesUsed
+      );
+  CheckExceptions(sCallbackEnv, __FUNCTION__);
+
+  if(locationObject != NULL) {
+    sCallbackEnv->DeleteLocalRef(locationObject);
+  }
+}
+
+static void GeofenceMonitorStatusCallback(
+    int32_t status,
+    uint32_t source,
+    FlpLocation* lastLocation) {
+  if(!IsValidCallbackThread()) {
+    return;
+  }
+
+  jobject locationObject = NULL;
+  if(lastLocation != NULL) {
+    TranslateToObject(lastLocation, locationObject);
+  }
+
+  sCallbackEnv->CallVoidMethod(
+      sCallbacksObj,
+      sOnGeofenceMonitorStatus,
+      status,
+      source,
+      locationObject
+      );
+  CheckExceptions(sCallbackEnv, __FUNCTION__);
+
+  if(locationObject != NULL) {
+    sCallbackEnv->DeleteLocalRef(locationObject);
+  }
+}
+
+static void GeofenceAddCallback(int32_t geofenceId, int32_t result) {
+  if(!IsValidCallbackThread()) {
+    return;
+  }
+
+  sCallbackEnv->CallVoidMethod(sCallbacksObj, sOnGeofenceAdd, geofenceId, result);
+  CheckExceptions(sCallbackEnv, __FUNCTION__);
+}
+
+static void GeofenceRemoveCallback(int32_t geofenceId, int32_t result) {
+  if(!IsValidCallbackThread()) {
+    return;
+  }
+
+  sCallbackEnv->CallVoidMethod(
+      sCallbacksObj,
+      sOnGeofenceRemove,
+      geofenceId,
+      result
+      );
+  CheckExceptions(sCallbackEnv, __FUNCTION__);
+}
+
+static void GeofencePauseCallback(int32_t geofenceId, int32_t result) {
+  if(!IsValidCallbackThread()) {
+    return;
+  }
+
+  sCallbackEnv->CallVoidMethod(
+      sCallbacksObj,
+      sOnGeofencePause,
+      geofenceId,
+      result
+      );
+  CheckExceptions(sCallbackEnv, __FUNCTION__);
+}
+
+static void GeofenceResumeCallback(int32_t geofenceId, int32_t result) {
+  if(!IsValidCallbackThread()) {
+    return;
+  }
+
+  sCallbackEnv->CallVoidMethod(
+      sCallbacksObj,
+      sOnGeofenceResume,
+      geofenceId,
+      result
+      );
+  CheckExceptions(sCallbackEnv, __FUNCTION__);
+}
+
+FlpGeofenceCallbacks sFlpGeofenceCallbacks = {
+  sizeof(FlpGeofenceCallbacks),
+  GeofenceTransitionCallback,
+  GeofenceMonitorStatusCallback,
+  GeofenceAddCallback,
+  GeofenceRemoveCallback,
+  GeofencePauseCallback,
+  GeofenceResumeCallback,
+  SetThreadEvent
+};
+
+/*
+ * Initializes the Fused Location Provider in the native side. It ensures that
+ * the Flp interfaces are initialized properly.
+ */
+static void Init(JNIEnv* env, jobject obj) {
+  if(sHardwareDevice != NULL) {
+    ALOGD("Hardware Device already opened.");
+    return;
+  }
+
+  const hw_module_t* module = NULL;
+  int err = hw_get_module(FUSED_LOCATION_HARDWARE_MODULE_ID, &module);
+  if(err != 0) {
+    ALOGE("Error hw_get_module '%s': %d", FUSED_LOCATION_HARDWARE_MODULE_ID, err);
+    return;
+  }
+
+  err = module->methods->open(
+        module,
+        FUSED_LOCATION_HARDWARE_MODULE_ID, &sHardwareDevice);
+  if(err != 0) {
+    ALOGE("Error opening device '%s': %d", FUSED_LOCATION_HARDWARE_MODULE_ID, err);
+    return;
+  }
+
+  sFlpInterface = NULL;
+  flp_device_t* flp_device = reinterpret_cast<flp_device_t*>(sHardwareDevice);
+  sFlpInterface = flp_device->get_flp_interface(flp_device);
+
+  if(sFlpInterface != NULL) {
+    sFlpDiagnosticInterface = reinterpret_cast<const FlpDiagnosticInterface*>(
+        sFlpInterface->get_extension(FLP_DIAGNOSTIC_INTERFACE)
+        );
+
+    sFlpGeofencingInterface = reinterpret_cast<const FlpGeofencingInterface*>(
+        sFlpInterface->get_extension(FLP_GEOFENCING_INTERFACE)
+        );
+
+    sFlpDeviceContextInterface = reinterpret_cast<const FlpDeviceContextInterface*>(
+        sFlpInterface->get_extension(FLP_DEVICE_CONTEXT_INTERFACE)
+        );
+  }
+
+  if(sCallbacksObj == NULL) {
+    sCallbacksObj = env->NewGlobalRef(obj);
+  }
+
+  // initialize the Flp interfaces
+  if(sFlpInterface == NULL || sFlpInterface->init(&sFlpCallbacks) != 0) {
+    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
+  }
+
+  if(sFlpDiagnosticInterface != NULL) {
+    sFlpDiagnosticInterface->init(&sFlpDiagnosticCallbacks);
+  }
+
+  if(sFlpGeofencingInterface != NULL) {
+    sFlpGeofencingInterface->init(&sFlpGeofenceCallbacks);
+  }
+
+  // TODO: inject any device context if when needed
+}
+
+static jboolean IsSupported(JNIEnv* env, jclass clazz) {
+  return sFlpInterface != NULL;
+}
+
+static jint GetBatchSize(JNIEnv* env, jobject object) {
+  if(sFlpInterface == NULL) {
+    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
+  }
+
+  return sFlpInterface->get_batch_size();
+}
+
+static void StartBatching(
+    JNIEnv* env,
+    jobject object,
+    jint id,
+    jobject optionsObject) {
+  if(sFlpInterface == NULL || optionsObject == NULL) {
+    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
+  }
+
+  FlpBatchOptions options;
+  TranslateFromObject(env, optionsObject, options);
+  int result = sFlpInterface->start_batching(id, &options);
+  ThrowOnError(env, result, __FUNCTION__);
+}
+
+static void UpdateBatchingOptions(
+    JNIEnv* env,
+    jobject object,
+    jint id,
+    jobject optionsObject) {
+  if(sFlpInterface == NULL || optionsObject == NULL) {
+    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
+  }
+
+  FlpBatchOptions options;
+  TranslateFromObject(env, optionsObject, options);
+  int result = sFlpInterface->update_batching_options(id, &options);
+  ThrowOnError(env, result, __FUNCTION__);
+}
+
+static void StopBatching(JNIEnv* env, jobject object, jint id) {
+  if(sFlpInterface == NULL) {
+    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
+  }
+
+  sFlpInterface->stop_batching(id);
+}
+
+static void Cleanup(JNIEnv* env, jobject object) {
+  if(sFlpInterface == NULL) {
+    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
+  }
+
+  sFlpInterface->cleanup();
+
+  if(sCallbacksObj != NULL) {
+    env->DeleteGlobalRef(sCallbacksObj);
+    sCallbacksObj = NULL;
+  }
+
+  sFlpInterface = NULL;
+  sFlpDiagnosticInterface = NULL;
+  sFlpDeviceContextInterface = NULL;
+  sFlpGeofencingInterface = NULL;
+
+  if(sHardwareDevice != NULL) {
+    sHardwareDevice->close(sHardwareDevice);
+    sHardwareDevice = NULL;
+  }
+}
+
+static void GetBatchedLocation(JNIEnv* env, jobject object, jint lastNLocations) {
+  if(sFlpInterface == NULL) {
+    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
+  }
+
+  sFlpInterface->get_batched_location(lastNLocations);
+}
+
+static void InjectLocation(JNIEnv* env, jobject object, jobject locationObject) {
+  if(locationObject == NULL) {
+    ALOGE("Invalid location for injection: %p", locationObject);
+    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
+  }
+
+  if(sFlpInterface == NULL) {
+    // there is no listener, bail
+    return;
+  }
+
+  FlpLocation location;
+  TranslateFromObject(env, locationObject, location);
+  int result = sFlpInterface->inject_location(&location);
+  if (result != FLP_RESULT_SUCCESS) {
+    // do not throw but log, this operation should be fire and forget
+    ALOGE("Error %d in '%s'", result, __FUNCTION__);
+  }
+}
+
+static jboolean IsDiagnosticSupported() {
+  return sFlpDiagnosticInterface != NULL;
+}
+
+static void InjectDiagnosticData(JNIEnv* env, jobject object, jstring stringData) {
+  if(stringData == NULL) {
+    ALOGE("Invalid diagnostic data for injection: %p", stringData);
+    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
+  }
+
+  if(sFlpDiagnosticInterface == NULL) {
+    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
+  }
+
+  int length = env->GetStringLength(stringData);
+  const jchar* data = env->GetStringChars(stringData, /* isCopy */ NULL);
+  if(data == NULL) {
+    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
+  }
+
+  int result = sFlpDiagnosticInterface->inject_data((char*) data, length);
+  ThrowOnError(env, result, __FUNCTION__);
+}
+
+static jboolean IsDeviceContextSupported() {
+  return sFlpDeviceContextInterface != NULL;
+}
+
+static void InjectDeviceContext(JNIEnv* env, jobject object, jint enabledMask) {
+  if(sFlpDeviceContextInterface == NULL) {
+    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
+  }
+
+  int result = sFlpDeviceContextInterface->inject_device_context(enabledMask);
+  ThrowOnError(env, result, __FUNCTION__);
+}
+
+static jboolean IsGeofencingSupported() {
+  return sFlpGeofencingInterface != NULL;
+}
+
+static void AddGeofences(
+    JNIEnv* env,
+    jobject object,
+    jobjectArray geofenceRequestsArray) {
+  if(geofenceRequestsArray == NULL) {
+    ALOGE("Invalid Geofences to add: %p", geofenceRequestsArray);
+    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
+  }
+
+  if (sFlpGeofencingInterface == NULL) {
+    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
+  }
+
+  jint geofenceRequestsCount = env->GetArrayLength(geofenceRequestsArray);
+  if(geofenceRequestsCount == 0) {
+    return;
+  }
+
+  Geofence* geofences = new Geofence[geofenceRequestsCount];
+  if (geofences == NULL) {
+    ThrowOnError(env, FLP_RESULT_INSUFFICIENT_MEMORY, __FUNCTION__);
+  }
+
+  for (int i = 0; i < geofenceRequestsCount; ++i) {
+    geofences[i].data = new GeofenceData();
+    geofences[i].options = new GeofenceOptions();
+    jobject geofenceObject = env->GetObjectArrayElement(geofenceRequestsArray, i);
+
+    TranslateGeofenceFromGeofenceHardwareRequestParcelable(env, geofenceObject, geofences[i]);
+    env->DeleteLocalRef(geofenceObject);
+  }
+
+  sFlpGeofencingInterface->add_geofences(geofenceRequestsCount, &geofences);
+  if (geofences != NULL) {
+    for(int i = 0; i < geofenceRequestsCount; ++i) {
+      delete geofences[i].data;
+      delete geofences[i].options;
+    }
+    delete[] geofences;
+  }
+}
+
+static void PauseGeofence(JNIEnv* env, jobject object, jint geofenceId) {
+  if(sFlpGeofencingInterface == NULL) {
+    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
+  }
+
+  sFlpGeofencingInterface->pause_geofence(geofenceId);
+}
+
+static void ResumeGeofence(
+    JNIEnv* env,
+    jobject object,
+    jint geofenceId,
+    jint monitorTransitions) {
+  if(sFlpGeofencingInterface == NULL) {
+    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
+  }
+
+  sFlpGeofencingInterface->resume_geofence(geofenceId, monitorTransitions);
+}
+
+static void ModifyGeofenceOption(
+    JNIEnv* env,
+    jobject object,
+    jint geofenceId,
+    jint lastTransition,
+    jint monitorTransitions,
+    jint notificationResponsiveness,
+    jint unknownTimer,
+    jint sourcesToUse) {
+  if(sFlpGeofencingInterface == NULL) {
+    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
+  }
+
+  GeofenceOptions options = {
+      lastTransition,
+      monitorTransitions,
+      notificationResponsiveness,
+      unknownTimer,
+      (uint32_t)sourcesToUse
+  };
+
+  sFlpGeofencingInterface->modify_geofence_option(geofenceId, &options);
+}
+
+static void RemoveGeofences(
+    JNIEnv* env,
+    jobject object,
+    jintArray geofenceIdsArray) {
+  if(sFlpGeofencingInterface == NULL) {
+    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
+  }
+
+  jsize geofenceIdsCount = env->GetArrayLength(geofenceIdsArray);
+  jint* geofenceIds = env->GetIntArrayElements(geofenceIdsArray, /* isCopy */ NULL);
+  if(geofenceIds == NULL) {
+    ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__);
+  }
+
+  sFlpGeofencingInterface->remove_geofences(geofenceIdsCount, geofenceIds);
+}
+
+static JNINativeMethod sMethods[] = {
+  //{"name", "signature", functionPointer }
+  {"nativeClassInit", "()V", reinterpret_cast<void*>(ClassInit)},
+  {"nativeInit", "()V", reinterpret_cast<void*>(Init)},
+  {"nativeCleanup", "()V", reinterpret_cast<void*>(Cleanup)},
+  {"nativeIsSupported", "()Z", reinterpret_cast<void*>(IsSupported)},
+  {"nativeGetBatchSize", "()I", reinterpret_cast<void*>(GetBatchSize)},
+  {"nativeStartBatching",
+        "(ILandroid/location/FusedBatchOptions;)V",
+        reinterpret_cast<void*>(StartBatching)},
+  {"nativeUpdateBatchingOptions",
+        "(ILandroid/location/FusedBatchOptions;)V",
+        reinterpret_cast<void*>(UpdateBatchingOptions)},
+  {"nativeStopBatching", "(I)V", reinterpret_cast<void*>(StopBatching)},
+  {"nativeRequestBatchedLocation",
+        "(I)V",
+        reinterpret_cast<void*>(GetBatchedLocation)},
+  {"nativeInjectLocation",
+        "(Landroid/location/Location;)V",
+        reinterpret_cast<void*>(InjectLocation)},
+  {"nativeIsDiagnosticSupported",
+        "()Z",
+        reinterpret_cast<void*>(IsDiagnosticSupported)},
+  {"nativeInjectDiagnosticData",
+        "(Ljava/lang/String;)V",
+        reinterpret_cast<void*>(InjectDiagnosticData)},
+  {"nativeIsDeviceContextSupported",
+        "()Z",
+        reinterpret_cast<void*>(IsDeviceContextSupported)},
+  {"nativeInjectDeviceContext",
+        "(I)V",
+        reinterpret_cast<void*>(InjectDeviceContext)},
+  {"nativeIsGeofencingSupported",
+        "()Z",
+        reinterpret_cast<void*>(IsGeofencingSupported)},
+  {"nativeAddGeofences",
+        "([Landroid/hardware/location/GeofenceHardwareRequestParcelable;)V",
+        reinterpret_cast<void*>(AddGeofences)},
+  {"nativePauseGeofence", "(I)V", reinterpret_cast<void*>(PauseGeofence)},
+  {"nativeResumeGeofence", "(II)V", reinterpret_cast<void*>(ResumeGeofence)},
+  {"nativeModifyGeofenceOption",
+        "(IIIIII)V",
+        reinterpret_cast<void*>(ModifyGeofenceOption)},
+  {"nativeRemoveGeofences", "([I)V", reinterpret_cast<void*>(RemoveGeofences)}
+};
+
+/*
+ * Registration method invoked on JNI Load.
+ */
+int register_android_server_location_FlpHardwareProvider(JNIEnv* env) {
+  return jniRegisterNativeMethods(
+      env,
+      "com/android/server/location/FlpHardwareProvider",
+      sMethods,
+      NELEM(sMethods)
+      );
+}
+
+} /* name-space Android */
diff --git a/services/jni/com_android_server_location_GpsLocationProvider.cpp b/services/jni/com_android_server_location_GpsLocationProvider.cpp
index 98de12a..aec254b 100644
--- a/services/jni/com_android_server_location_GpsLocationProvider.cpp
+++ b/services/jni/com_android_server_location_GpsLocationProvider.cpp
@@ -26,6 +26,7 @@
 #include "utils/Log.h"
 #include "utils/misc.h"
 #include "android_runtime/AndroidRuntime.h"
+#include "android_runtime/Log.h"
 
 #include <string.h>
 #include <pthread.h>
diff --git a/services/jni/com_android_server_power_PowerManagerService.cpp b/services/jni/com_android_server_power_PowerManagerService.cpp
index 23c33af..151e134 100644
--- a/services/jni/com_android_server_power_PowerManagerService.cpp
+++ b/services/jni/com_android_server_power_PowerManagerService.cpp
@@ -26,13 +26,13 @@
 #include <limits.h>
 
 #include <android_runtime/AndroidRuntime.h>
+#include <android_runtime/Log.h>
 #include <utils/Timers.h>
 #include <utils/misc.h>
 #include <utils/String8.h>
 #include <utils/Log.h>
 #include <hardware/power.h>
 #include <hardware_legacy/power.h>
-#include <cutils/android_reboot.h>
 #include <suspend/autosuspend.h>
 
 #include "com_android_server_power_PowerManagerService.h"
@@ -189,22 +189,6 @@
     }
 }
 
-static void nativeShutdown(JNIEnv *env, jclass clazz) {
-    android_reboot(ANDROID_RB_POWEROFF, 0, 0);
-}
-
-static void nativeReboot(JNIEnv *env, jclass clazz, jstring reason) {
-    if (reason == NULL) {
-        android_reboot(ANDROID_RB_RESTART, 0, 0);
-    } else {
-        const char *chars = env->GetStringUTFChars(reason, NULL);
-        android_reboot(ANDROID_RB_RESTART2, 0, (char *) chars);
-        env->ReleaseStringUTFChars(reason, chars);  // In case it fails.
-    }
-    jniThrowIOException(env, errno);
-}
-
-
 // ----------------------------------------------------------------------------
 
 static JNINativeMethod gPowerManagerServiceMethods[] = {
@@ -221,10 +205,6 @@
             (void*) nativeSetInteractive },
     { "nativeSetAutoSuspend", "(Z)V",
             (void*) nativeSetAutoSuspend },
-    { "nativeShutdown", "()V",
-            (void*) nativeShutdown },
-    { "nativeReboot", "(Ljava/lang/String;)V",
-            (void*) nativeReboot },
 };
 
 #define FIND_CLASS(var, className) \
diff --git a/services/jni/onload.cpp b/services/jni/onload.cpp
index 423ebd1..efc34a2 100644
--- a/services/jni/onload.cpp
+++ b/services/jni/onload.cpp
@@ -21,7 +21,7 @@
 
 namespace android {
 int register_android_server_AlarmManagerService(JNIEnv* env);
-int register_android_server_BatteryService(JNIEnv* env);
+int register_android_server_ConsumerIrService(JNIEnv *env);
 int register_android_server_InputApplicationHandle(JNIEnv* env);
 int register_android_server_InputWindowHandle(JNIEnv* env);
 int register_android_server_InputManager(JNIEnv* env);
@@ -33,7 +33,9 @@
 int register_android_server_VibratorService(JNIEnv* env);
 int register_android_server_SystemServer(JNIEnv* env);
 int register_android_server_location_GpsLocationProvider(JNIEnv* env);
+int register_android_server_location_FlpHardwareProvider(JNIEnv* env);
 int register_android_server_connectivity_Vpn(JNIEnv* env);
+int register_android_server_AssetAtlasService(JNIEnv* env);
 };
 
 using namespace android;
@@ -56,13 +58,16 @@
     register_android_server_InputManager(env);
     register_android_server_LightsService(env);
     register_android_server_AlarmManagerService(env);
-    register_android_server_BatteryService(env);
     register_android_server_UsbDeviceManager(env);
     register_android_server_UsbHostManager(env);
     register_android_server_VibratorService(env);
     register_android_server_SystemServer(env);
     register_android_server_location_GpsLocationProvider(env);
+    register_android_server_location_FlpHardwareProvider(env);
     register_android_server_connectivity_Vpn(env);
+    register_android_server_AssetAtlasService(env);
+    register_android_server_ConsumerIrService(env);
+
 
     return JNI_VERSION_1_4;
 }
diff --git a/services/tests/servicestests/src/com/android/server/CountryDetectorServiceTest.java b/services/tests/servicestests/src/com/android/server/CountryDetectorServiceTest.java
index 17a1585..192c50c 100644
--- a/services/tests/servicestests/src/com/android/server/CountryDetectorServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/CountryDetectorServiceTest.java
@@ -66,7 +66,7 @@
 
     public void testAddRemoveListener() throws RemoteException {
         CountryDetectorServiceTester serviceTester = new CountryDetectorServiceTester(getContext());
-        serviceTester.systemReady();
+        serviceTester.systemRunning();
         waitForSystemReady(serviceTester);
         CountryListenerTester listenerTester = new CountryListenerTester();
         serviceTester.addCountryListener(listenerTester);
@@ -80,7 +80,7 @@
         CountryListenerTester listenerTesterA = new CountryListenerTester();
         CountryListenerTester listenerTesterB = new CountryListenerTester();
         Country country = new Country("US", Country.COUNTRY_SOURCE_NETWORK);
-        serviceTester.systemReady();
+        serviceTester.systemRunning();
         waitForSystemReady(serviceTester);
         serviceTester.addCountryListener(listenerTesterA);
         serviceTester.addCountryListener(listenerTesterB);
diff --git a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
new file mode 100644
index 0000000..56dd7c4
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
@@ -0,0 +1,175 @@
+/*
+ * 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 android.content.Context;
+import android.net.LocalSocket;
+import android.net.LocalServerSocket;
+import android.os.Binder;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import com.android.server.net.BaseNetworkObserver;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Tests for {@link NetworkManagementService}.
+ */
+@LargeTest
+public class NetworkManagementServiceTest extends AndroidTestCase {
+
+    private static final String SOCKET_NAME = "__test__NetworkManagementServiceTest";
+    private NetworkManagementService mNMService;
+    private LocalServerSocket mServerSocket;
+    private LocalSocket mSocket;
+    private OutputStream mOutputStream;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        // TODO: make this unnecessary. runtest might already make it unnecessary.
+        System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString());
+
+        // Set up a sheltered test environment.
+        BroadcastInterceptingContext context = new BroadcastInterceptingContext(getContext());
+        mServerSocket = new LocalServerSocket(SOCKET_NAME);
+
+        // Start the service and wait until it connects to our socket.
+        mNMService = NetworkManagementService.create(context, SOCKET_NAME);
+        mSocket = mServerSocket.accept();
+        mOutputStream = mSocket.getOutputStream();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        if (mSocket != null) mSocket.close();
+        if (mServerSocket != null) mServerSocket.close();
+        super.tearDown();
+    }
+
+    /**
+     * Sends a message on the netd socket and gives the events some time to make it back.
+     */
+    private void sendMessage(String message) throws IOException {
+        // Strings are null-terminated, so add "\0" at the end.
+        mOutputStream.write((message + "\0").getBytes());
+    }
+
+    private static <T> T expectSoon(T mock) {
+        return verify(mock, timeout(100));
+    }
+
+    /**
+     * Tests that network observers work properly.
+     */
+    public void testNetworkObservers() throws Exception {
+        BaseNetworkObserver observer = mock(BaseNetworkObserver.class);
+        doReturn(new Binder()).when(observer).asBinder();  // Used by registerObserver.
+        mNMService.registerObserver(observer);
+
+        // Forget everything that happened to the mock so far, so we can explicitly verify
+        // everything that happens and does not happen to it from now on.
+        reset(observer);
+
+        // Now send NetworkManagementService messages and ensure that the observer methods are
+        // called. After every valid message we expect a callback soon after; to ensure that
+        // invalid messages don't cause any callbacks, we call verifyNoMoreInteractions at the end.
+
+        /**
+         * Interface changes.
+         */
+        sendMessage("600 Iface added rmnet12");
+        expectSoon(observer).interfaceAdded("rmnet12");
+
+        sendMessage("600 Iface removed eth1");
+        expectSoon(observer).interfaceRemoved("eth1");
+
+        sendMessage("607 Iface removed eth1");
+        // Invalid code.
+
+        sendMessage("600 Iface borked lo down");
+        // Invalid event.
+
+        sendMessage("600 Iface changed clat4 up again");
+        // Extra tokens.
+
+        sendMessage("600 Iface changed clat4 up");
+        expectSoon(observer).interfaceStatusChanged("clat4", true);
+
+        sendMessage("600 Iface linkstate rmnet0 down");
+        expectSoon(observer).interfaceLinkStateChanged("rmnet0", false);
+
+        sendMessage("600 IFACE linkstate clat4 up");
+        // Invalid group.
+
+        /**
+         * Bandwidth control events.
+         */
+        sendMessage("601 limit alert data rmnet_usb0");
+        expectSoon(observer).limitReached("data", "rmnet_usb0");
+
+        sendMessage("601 invalid alert data rmnet0");
+        // Invalid group.
+
+        sendMessage("601 limit increased data rmnet0");
+        // Invalid event.
+
+
+        /**
+         * Interface class activity.
+         */
+        sendMessage("613 IfaceClass active rmnet0");
+        expectSoon(observer).interfaceClassDataActivityChanged("rmnet0", true);
+
+        sendMessage("613 IfaceClass idle eth0");
+        expectSoon(observer).interfaceClassDataActivityChanged("eth0", false);
+
+        sendMessage("613 IfaceClass reallyactive rmnet0");
+        expectSoon(observer).interfaceClassDataActivityChanged("rmnet0", false);
+
+        sendMessage("613 InterfaceClass reallyactive rmnet0");
+        // Invalid group.
+
+
+        /**
+         * IP address changes.
+         */
+        sendMessage("614 Address updated fe80::1/64 wlan0 128 253");
+        expectSoon(observer).addressUpdated("fe80::1/64", "wlan0", 128, 253);
+
+        // There is no "added".
+        sendMessage("614 Address added fe80::1/64 wlan0 128 253");
+        expectSoon(observer).addressRemoved("fe80::1/64", "wlan0", 128, 253);
+
+        sendMessage("614 Address removed 2001:db8::1/64 wlan0 1 0");
+        expectSoon(observer).addressRemoved("2001:db8::1/64", "wlan0", 1, 0);
+
+        sendMessage("666 Address added 2001:db8::1/64 wlan0 1 0");
+        // Invalid code.
+
+        // Make sure nothing else was called.
+        verifyNoMoreInteractions(observer);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
index cdc4d78..a1af8cb 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
@@ -40,7 +40,6 @@
 import static android.text.format.DateUtils.WEEK_IN_MILLIS;
 import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_POLL;
 import static org.easymock.EasyMock.anyLong;
-import static org.easymock.EasyMock.aryEq;
 import static org.easymock.EasyMock.capture;
 import static org.easymock.EasyMock.createMock;
 import static org.easymock.EasyMock.eq;
@@ -63,6 +62,7 @@
 import android.net.NetworkStatsHistory;
 import android.net.NetworkTemplate;
 import android.os.INetworkManagementService;
+import android.os.WorkSource;
 import android.telephony.TelephonyManager;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.LargeTest;
@@ -73,13 +73,13 @@
 import com.android.server.net.NetworkStatsService.NetworkStatsSettings;
 import com.android.server.net.NetworkStatsService.NetworkStatsSettings.Config;
 
+import libcore.io.IoUtils;
+
 import org.easymock.Capture;
 import org.easymock.EasyMock;
 
 import java.io.File;
 
-import libcore.io.IoUtils;
-
 /**
  * Tests for {@link NetworkStatsService}.
  */
@@ -878,8 +878,8 @@
         mAlarmManager.remove(isA(PendingIntent.class));
         expectLastCall().anyTimes();
 
-        mAlarmManager.setInexactRepeating(
-                eq(AlarmManager.ELAPSED_REALTIME), anyLong(), anyLong(), isA(PendingIntent.class));
+        mAlarmManager.set(eq(AlarmManager.ELAPSED_REALTIME), anyLong(), anyLong(), anyLong(),
+                isA(PendingIntent.class), isA(WorkSource.class));
         expectLastCall().atLeastOnce();
 
         mNetManager.setGlobalAlert(anyLong());
@@ -918,8 +918,7 @@
         expect(mNetManager.getNetworkStatsUidDetail(eq(UID_ALL))).andReturn(detail).atLeastOnce();
 
         // also include tethering details, since they are folded into UID
-        expect(mConnManager.getTetheredIfacePairs()).andReturn(tetherIfacePairs).atLeastOnce();
-        expect(mNetManager.getNetworkStatsTethering(aryEq(tetherIfacePairs)))
+        expect(mNetManager.getNetworkStatsTethering())
                 .andReturn(tetherStats).atLeastOnce();
     }
 
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 f2772c8..37176d6 100644
--- a/services/tests/servicestests/src/com/android/server/content/SyncOperationTest.java
+++ b/services/tests/servicestests/src/com/android/server/content/SyncOperationTest.java
@@ -14,9 +14,10 @@
  * limitations under the License.
  */
 
-package com.android.server;
+package com.android.server.content;
 
 import android.accounts.Account;
+import android.content.ContentResolver;
 import android.os.Bundle;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -48,7 +49,8 @@
                 SyncOperation.REASON_PERIODIC,
                 "authority1",
                 b1,
-                100,
+                100, /* run time from now*/
+                10, /* flex */
                 1000,
                 10000,
                 false);
@@ -60,6 +62,7 @@
                 "authority1",
                 b1,
                 200,
+                20,
                 2000,
                 20000,
                 false);
@@ -71,6 +74,7 @@
                 "authority2",
                 b1,
                 100,
+                10,
                 1000,
                 10000,
                 false);
@@ -82,6 +86,7 @@
                 "authority1",
                 b1,
                 100,
+                10,
                 1000,
                 10000,
                 false);
@@ -93,6 +98,7 @@
                 "authority1",
                 b2,
                 100,
+                10,
                 1000,
                 10000,
                 false);
@@ -102,4 +108,38 @@
         assertNotSame(op1.key, op4.key);
         assertNotSame(op1.key, op5.key);
     }
+
+    @SmallTest
+    public void testCompareTo() {
+        Account dummy = new Account("account1", "type1");
+        Bundle b1 = new Bundle();
+        final long unimportant = 0L;
+        long soon = 1000;
+        long soonFlex = 50;
+        long after = 1500;
+        long afterFlex = 100;
+        SyncOperation op1 = new SyncOperation(dummy, 0, 0, SyncOperation.REASON_PERIODIC,
+                "authority1", b1, soon, soonFlex, unimportant, unimportant, true);
+
+        // Interval disjoint from and after op1.
+        SyncOperation op2 = new SyncOperation(dummy, 0, 0, SyncOperation.REASON_PERIODIC,
+                "authority1", b1, after, afterFlex, unimportant, unimportant, true);
+
+        // Interval equivalent to op1, but expedited.
+        Bundle b2 = new Bundle();
+        b2.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
+        SyncOperation op3 = new SyncOperation(dummy, 0, 0, 0,
+                "authority1", b2, soon, soonFlex, unimportant, unimportant, true);
+
+        // Interval overlaps but not equivalent to op1.
+        SyncOperation op4 = new SyncOperation(dummy, 0, 0, SyncOperation.REASON_PERIODIC,
+                "authority1", b1, soon + 100, soonFlex + 100, unimportant, unimportant, true);
+
+        assertTrue(op1.compareTo(op2) == -1);
+        assertTrue("less than not transitive.", op2.compareTo(op1) == 1);
+        assertTrue(op1.compareTo(op3) == 1);
+        assertTrue("greater than not transitive. ", op3.compareTo(op1) == -1);
+        assertTrue("overlapping intervals not the same.", op1.compareTo(op4) == 0);
+        assertTrue("equality not transitive.", op4.compareTo(op1) == 0);
+    }
 }
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 8b00f2c2..e44652f 100644
--- a/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java
+++ b/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java
@@ -22,6 +22,7 @@
 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;
 import android.test.RenamingDelegatingContext;
@@ -39,13 +40,34 @@
 
 public class SyncStorageEngineTest extends AndroidTestCase {
 
+    protected Account account1;
+    protected String authority1 = "testprovider";
+    protected Bundle defaultBundle;
+    protected final int DEFAULT_USER = 0;
+    
+    MockContentResolver mockResolver;
+    SyncStorageEngine engine;
+    
     private File getSyncDir() {
         return new File(new File(getContext().getFilesDir(), "system"), "sync");
     }
 
+    @Override
+    public void setUp() {
+        account1 = new Account("a@example.com", "example.type");
+        // Default bundle.
+        defaultBundle = new Bundle();
+        defaultBundle.putInt("int_key", 0);
+        defaultBundle.putString("string_key", "hello");
+        // Set up storage engine.
+        mockResolver = new MockContentResolver();
+        engine = SyncStorageEngine.newTestInstance(
+                new TestContext(mockResolver, getContext()));
+    }
+
     /**
      * Test that we handle the case of a history row being old enough to purge before the
-     * correcponding sync is finished. This can happen if the clock changes while we are syncing.
+     * corresponding sync is finished. This can happen if the clock changes while we are syncing.
      *
      */
     // TODO: this test causes AidlTest to fail. Omit for now
@@ -68,7 +90,36 @@
     }
 
     /**
-     * Test that we can create, remove and retrieve periodic syncs
+     * Test persistence of pending operations.
+     */
+    @MediumTest
+    public void testPending() throws Exception {
+        SyncStorageEngine.PendingOperation pop =
+                new SyncStorageEngine.PendingOperation(account1, DEFAULT_USER,
+                        SyncOperation.REASON_PERIODIC, SyncStorageEngine.SOURCE_LOCAL,
+                        authority1, defaultBundle, false);
+        
+        engine.insertIntoPending(pop);
+        // Force engine to read from disk.
+        engine.clearAndReadState();
+
+        assert(engine.getPendingOperationCount() == 1);
+        List<SyncStorageEngine.PendingOperation> pops = engine.getPendingOperations();
+        SyncStorageEngine.PendingOperation popRetrieved = pops.get(0);
+        assertEquals(pop.account, popRetrieved.account);
+        assertEquals(pop.reason, popRetrieved.reason);
+        assertEquals(pop.userId, popRetrieved.userId);
+        assertEquals(pop.syncSource, popRetrieved.syncSource);
+        assertEquals(pop.authority, popRetrieved.authority);
+        assertEquals(pop.expedited, popRetrieved.expedited);
+        assertEquals(pop.serviceName, popRetrieved.serviceName);
+        assert(android.content.PeriodicSync.syncExtrasEquals(pop.extras, popRetrieved.extras));
+
+    }
+
+    /**
+     * Test that we can create, remove and retrieve periodic syncs. Backwards compatibility -
+     * periodic syncs with no flex time are no longer used.
      */
     @MediumTest
     public void testPeriodics() throws Exception {
@@ -87,22 +138,19 @@
         PeriodicSync sync3 = new PeriodicSync(account1, authority, extras2, period2);
         PeriodicSync sync4 = new PeriodicSync(account2, authority, extras2, period2);
 
-        MockContentResolver mockResolver = new MockContentResolver();
-
-        SyncStorageEngine engine = SyncStorageEngine.newTestInstance(
-                new TestContext(mockResolver, getContext()));
+        
 
         removePeriodicSyncs(engine, account1, 0, authority);
         removePeriodicSyncs(engine, account2, 0, authority);
         removePeriodicSyncs(engine, account1, 1, authority);
 
         // this should add two distinct periodic syncs for account1 and one for account2
-        engine.addPeriodicSync(sync1.account, 0, sync1.authority, sync1.extras, sync1.period);
-        engine.addPeriodicSync(sync2.account, 0, sync2.authority, sync2.extras, sync2.period);
-        engine.addPeriodicSync(sync3.account, 0, sync3.authority, sync3.extras, sync3.period);
-        engine.addPeriodicSync(sync4.account, 0, sync4.authority, sync4.extras, sync4.period);
+        engine.addPeriodicSync(sync1, 0);
+        engine.addPeriodicSync(sync2, 0);
+        engine.addPeriodicSync(sync3, 0);
+        engine.addPeriodicSync(sync4, 0);
         // add a second user
-        engine.addPeriodicSync(sync2.account, 1, sync2.authority, sync2.extras, sync2.period);
+        engine.addPeriodicSync(sync2, 1);
 
         List<PeriodicSync> syncs = engine.getPeriodicSyncs(account1, 0, authority);
 
@@ -111,7 +159,7 @@
         assertEquals(sync1, syncs.get(0));
         assertEquals(sync3, syncs.get(1));
 
-        engine.removePeriodicSync(sync1.account, 0, sync1.authority, sync1.extras);
+        engine.removePeriodicSync(sync1, 0);
 
         syncs = engine.getPeriodicSyncs(account1, 0, authority);
         assertEquals(1, syncs.size());
@@ -126,13 +174,72 @@
         assertEquals(sync2, syncs.get(0));
     }
 
-    private void removePeriodicSyncs(SyncStorageEngine engine, Account account, int userId,
-            String authority) {
-        engine.setIsSyncable(account, userId, authority,
-                engine.getIsSyncable(account, 0, authority));
+    /**
+     * Test that we can create, remove and retrieve periodic syncs with a provided flex time.
+     */
+    @MediumTest
+    public void testPeriodicsV2() throws Exception {
+        final Account account1 = new Account("a@example.com", "example.type");
+        final Account account2 = new Account("b@example.com", "example.type.2");
+        final String authority = "testprovider";
+        final Bundle extras1 = new Bundle();
+        extras1.putString("a", "1");
+        final Bundle extras2 = new Bundle();
+        extras2.putString("a", "2");
+        final int period1 = 200;
+        final int period2 = 1000;
+        final int flex1 = 10;
+        final int flex2 = 100;
+
+        PeriodicSync sync1 = new PeriodicSync(account1, authority, extras1, period1, flex1);
+        PeriodicSync sync2 = new PeriodicSync(account1, authority, extras2, period1, flex1);
+        PeriodicSync sync3 = new PeriodicSync(account1, authority, extras2, period2, flex2);
+        PeriodicSync sync4 = new PeriodicSync(account2, authority, extras2, period2, flex2);
+
+        MockContentResolver mockResolver = new MockContentResolver();
+
+        SyncStorageEngine engine = SyncStorageEngine.newTestInstance(
+                new TestContext(mockResolver, getContext()));
+
+        removePeriodicSyncs(engine, account1, 0, authority);
+        removePeriodicSyncs(engine, account2, 0, authority);
+        removePeriodicSyncs(engine, account1, 1, authority);
+
+        // This should add two distinct periodic syncs for account1 and one for account2
+        engine.addPeriodicSync(sync1, 0);
+        engine.addPeriodicSync(sync2, 0);
+        engine.addPeriodicSync(sync3, 0); // Should edit sync2 and update the period.
+        engine.addPeriodicSync(sync4, 0);
+        // add a second user
+        engine.addPeriodicSync(sync2, 1);
+
+        List<PeriodicSync> syncs = engine.getPeriodicSyncs(account1, 0, authority);
+
+        assertEquals(2, syncs.size());
+
+        assertEquals(sync1, syncs.get(0));
+        assertEquals(sync3, syncs.get(1));
+
+        engine.removePeriodicSync(sync1, 0);
+
+        syncs = engine.getPeriodicSyncs(account1, 0, authority);
+        assertEquals(1, syncs.size());
+        assertEquals(sync3, syncs.get(0));
+
+        syncs = engine.getPeriodicSyncs(account2, 0, authority);
+        assertEquals(1, syncs.size());
+        assertEquals(sync4, syncs.get(0));
+
+        syncs = engine.getPeriodicSyncs(sync2.account, 1, sync2.authority);
+        assertEquals(1, syncs.size());
+        assertEquals(sync2, syncs.get(0));
+    }
+
+    private void removePeriodicSyncs(SyncStorageEngine engine, Account account, int userId, String authority) {
+        engine.setIsSyncable(account, userId, authority, engine.getIsSyncable(account, 0, authority));
         List<PeriodicSync> syncs = engine.getPeriodicSyncs(account, userId, authority);
         for (PeriodicSync sync : syncs) {
-            engine.removePeriodicSync(sync.account, userId, sync.authority, sync.extras);
+            engine.removePeriodicSync(sync, userId);
         }
     }
 
@@ -154,12 +261,14 @@
         extras2.putParcelable("g", account1);
         final int period1 = 200;
         final int period2 = 1000;
+        final int flex1 = 10;
+        final int flex2 = 100;
 
-        PeriodicSync sync1 = new PeriodicSync(account1, authority1, extras1, period1);
-        PeriodicSync sync2 = new PeriodicSync(account1, authority1, extras2, period1);
-        PeriodicSync sync3 = new PeriodicSync(account1, authority2, extras1, period1);
-        PeriodicSync sync4 = new PeriodicSync(account1, authority2, extras2, period2);
-        PeriodicSync sync5 = new PeriodicSync(account2, authority1, extras1, period1);
+        PeriodicSync sync1 = new PeriodicSync(account1, authority1, extras1, period1, flex1);
+        PeriodicSync sync2 = new PeriodicSync(account1, authority1, extras2, period1, flex1);
+        PeriodicSync sync3 = new PeriodicSync(account1, authority2, extras1, period1, flex1);
+        PeriodicSync sync4 = new PeriodicSync(account1, authority2, extras2, period2, flex2);
+        PeriodicSync sync5 = new PeriodicSync(account2, authority1, extras1, period1, flex1);
 
         MockContentResolver mockResolver = new MockContentResolver();
 
@@ -185,11 +294,11 @@
         engine.setIsSyncable(account2, 0, authority2, 0);
         engine.setSyncAutomatically(account2, 0, authority2, true);
 
-        engine.addPeriodicSync(sync1.account, 0, sync1.authority, sync1.extras, sync1.period);
-        engine.addPeriodicSync(sync2.account, 0, sync2.authority, sync2.extras, sync2.period);
-        engine.addPeriodicSync(sync3.account, 0, sync3.authority, sync3.extras, sync3.period);
-        engine.addPeriodicSync(sync4.account, 0, sync4.authority, sync4.extras, sync4.period);
-        engine.addPeriodicSync(sync5.account, 0, sync5.authority, sync5.extras, sync5.period);
+        engine.addPeriodicSync(sync1, 0);
+        engine.addPeriodicSync(sync2, 0);
+        engine.addPeriodicSync(sync3, 0);
+        engine.addPeriodicSync(sync4, 0);
+        engine.addPeriodicSync(sync5, 0);
 
         engine.writeAllState();
         engine.clearAndReadState();
@@ -220,6 +329,131 @@
     }
 
     @MediumTest
+    /**
+     * V2 introduces flex time as well as service components.
+     * @throws Exception
+     */
+    public void testAuthorityParsingV2() throws Exception {
+        final Account account = new Account("account1", "type1");
+        final String authority1 = "auth1";
+        final String authority2 = "auth2";
+        final String authority3 = "auth3";
+
+        final long dayPoll = (60 * 60 * 24);
+        final long dayFuzz = 60;
+        final long thousandSecs = 1000;
+        final long thousandSecsFuzz = 100;
+        final Bundle extras = new Bundle();
+        PeriodicSync sync1 = new PeriodicSync(account, authority1, extras, dayPoll, dayFuzz);
+        PeriodicSync sync2 = new PeriodicSync(account, authority2, extras, dayPoll, dayFuzz);
+        PeriodicSync sync3 = new PeriodicSync(account, authority3, extras, dayPoll, dayFuzz);
+        PeriodicSync sync1s = new PeriodicSync(account, authority1, extras, thousandSecs, thousandSecsFuzz);
+        PeriodicSync sync2s = new PeriodicSync(account, authority2, extras, thousandSecs, thousandSecsFuzz);
+        PeriodicSync sync3s = new PeriodicSync(account, authority3, extras, thousandSecs, thousandSecsFuzz);
+        MockContentResolver mockResolver = new MockContentResolver();
+
+        final TestContext testContext = new TestContext(mockResolver, getContext());
+
+        byte[] accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+                + "<accounts version=\"2\" >\n"
+                + "<authority id=\"0\" user=\"0\" account=\"account1\" type=\"type1\" authority=\"auth1\" >"
+                + "\n<periodicSync period=\"" + dayPoll + "\" flex=\"" + dayFuzz + "\"/>"
+                + "\n</authority>"
+                + "<authority id=\"1\" user=\"0\" account=\"account1\" type=\"type1\" authority=\"auth2\" >"
+                + "\n<periodicSync period=\"" + dayPoll + "\" flex=\"" + dayFuzz + "\"/>"
+                + "\n</authority>"
+                // No user defaults to user 0 - all users.
+                + "<authority id=\"2\"            account=\"account1\" type=\"type1\" authority=\"auth3\" >"
+                + "\n<periodicSync period=\"" + dayPoll + "\" flex=\"" + dayFuzz + "\"/>"
+                + "\n</authority>"
+                + "<authority id=\"3\" user=\"1\" account=\"account1\" type=\"type1\" authority=\"auth3\" >"
+                + "\n<periodicSync period=\"" + dayPoll + "\" flex=\"" + dayFuzz + "\"/>"
+                + "\n</authority>"
+                + "</accounts>").getBytes();
+
+        File syncDir = getSyncDir();
+        syncDir.mkdirs();
+        AtomicFile accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml"));
+        FileOutputStream fos = accountInfoFile.startWrite();
+        fos.write(accountsFileData);
+        accountInfoFile.finishWrite(fos);
+
+        SyncStorageEngine engine = SyncStorageEngine.newTestInstance(testContext);
+
+        List<PeriodicSync> syncs = engine.getPeriodicSyncs(account, 0, authority1);
+        assertEquals("Got incorrect # of syncs", 1, syncs.size());
+        assertEquals(sync1, syncs.get(0));
+
+        syncs = engine.getPeriodicSyncs(account, 0, authority2);
+        assertEquals(1, syncs.size());
+        assertEquals(sync2, syncs.get(0));
+
+        syncs = engine.getPeriodicSyncs(account, 0, authority3);
+        assertEquals(1, syncs.size());
+        assertEquals(sync3, syncs.get(0));
+
+        syncs = engine.getPeriodicSyncs(account, 1, authority3);
+        assertEquals(1, syncs.size());
+        assertEquals(sync3, syncs.get(0));
+
+        // Test empty periodic data.
+        accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+                + "<accounts version=\"2\">\n"
+                + "<authority id=\"0\" account=\"account1\" type=\"type1\" authority=\"auth1\" />\n"
+                + "<authority id=\"1\" account=\"account1\" type=\"type1\" authority=\"auth2\" />\n"
+                + "<authority id=\"2\" account=\"account1\" type=\"type1\" authority=\"auth3\" />\n"
+                + "</accounts>\n").getBytes();
+
+        accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml"));
+        fos = accountInfoFile.startWrite();
+        fos.write(accountsFileData);
+        accountInfoFile.finishWrite(fos);
+
+        engine.clearAndReadState();
+
+        syncs = engine.getPeriodicSyncs(account, 0, authority1);
+        assertEquals(0, syncs.size());
+
+        syncs = engine.getPeriodicSyncs(account, 0, authority2);
+        assertEquals(0, syncs.size());
+
+        syncs = engine.getPeriodicSyncs(account, 0, authority3);
+        assertEquals(0, syncs.size());
+
+        accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+                + "<accounts version=\"2\">\n"
+                + "<authority id=\"0\" account=\"account1\" type=\"type1\" authority=\"auth1\">\n"
+                + "<periodicSync period=\"1000\" />\n"
+                + "</authority>"
+                + "<authority id=\"1\" account=\"account1\" type=\"type1\" authority=\"auth2\">\n"
+                + "<periodicSync period=\"1000\" />\n"
+                + "</authority>"
+                + "<authority id=\"2\" account=\"account1\" type=\"type1\" authority=\"auth3\">\n"
+                + "<periodicSync period=\"1000\" />\n"
+                + "</authority>"
+                + "</accounts>\n").getBytes();
+
+        accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml"));
+        fos = accountInfoFile.startWrite();
+        fos.write(accountsFileData);
+        accountInfoFile.finishWrite(fos);
+
+        engine.clearAndReadState();
+
+        syncs = engine.getPeriodicSyncs(account, 0, authority1);
+        assertEquals(1, syncs.size());
+        assertEquals(sync1s, syncs.get(0));
+
+        syncs = engine.getPeriodicSyncs(account, 0, authority2);
+        assertEquals(1, syncs.size());
+        assertEquals(sync2s, syncs.get(0));
+
+        syncs = engine.getPeriodicSyncs(account, 0, authority3);
+        assertEquals(1, syncs.size());
+        assertEquals(sync3s, syncs.get(0));
+    }
+
+    @MediumTest
     public void testAuthorityParsing() throws Exception {
         final Account account = new Account("account1", "type1");
         final String authority1 = "auth1";
@@ -256,7 +490,7 @@
 
         List<PeriodicSync> syncs = engine.getPeriodicSyncs(account, 0, authority1);
         assertEquals(1, syncs.size());
-        assertEquals(sync1, syncs.get(0));
+        assertEquals("expected sync1: " + sync1.toString() + " == sync 2" + syncs.get(0).toString(), sync1, syncs.get(0));
 
         syncs = engine.getPeriodicSyncs(account, 0, authority2);
         assertEquals(1, syncs.size());
@@ -451,6 +685,11 @@
     }
 
     @Override
+    public Resources getResources() {
+        return mRealContext.getResources();
+    }
+
+    @Override
     public File getFilesDir() {
         return mRealContext.getFilesDir();
     }
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 3ae2106..ab429fd 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -1805,7 +1805,7 @@
         String countryIso;
         CountryDetector detector = (CountryDetector) context.getSystemService(
                 Context.COUNTRY_DETECTOR);
-        if (detector != null) {
+        if (detector != null && detector.detectCountry() != null) {
             countryIso = detector.detectCountry().getCountryIso();
         } else {
             Locale locale = context.getResources().getConfiguration().locale;
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 4185aea..7d8b64f 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -309,7 +309,7 @@
      */
     public List<NeighboringCellInfo> getNeighboringCellInfo() {
         try {
-            return getITelephony().getNeighboringCellInfo(mContext.getBasePackageName());
+            return getITelephony().getNeighboringCellInfo(mContext.getOpPackageName());
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
@@ -412,12 +412,12 @@
         case RILConstants.NETWORK_MODE_GSM_UMTS:
         case RILConstants.NETWORK_MODE_LTE_GSM_WCDMA:
         case RILConstants.NETWORK_MODE_LTE_WCDMA:
+        case RILConstants.NETWORK_MODE_LTE_CMDA_EVDO_GSM_WCDMA:
             return PhoneConstants.PHONE_TYPE_GSM;
 
         // Use CDMA Phone for the global mode including CDMA
         case RILConstants.NETWORK_MODE_GLOBAL:
         case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO:
-        case RILConstants.NETWORK_MODE_LTE_CMDA_EVDO_GSM_WCDMA:
             return PhoneConstants.PHONE_TYPE_CDMA;
 
         case RILConstants.NETWORK_MODE_LTE_ONLY:
diff --git a/telephony/java/com/android/internal/telephony/CallerInfo.java b/telephony/java/com/android/internal/telephony/CallerInfo.java
index 228a630..6978551 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfo.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfo.java
@@ -49,10 +49,6 @@
     private static final String TAG = "CallerInfo";
     private static final boolean VDBG = Rlog.isLoggable(TAG, Log.VERBOSE);
 
-    public static final String UNKNOWN_NUMBER = "-1";
-    public static final String PRIVATE_NUMBER = "-2";
-    public static final String PAYPHONE_NUMBER = "-3";
-
     /**
      * Please note that, any one of these member variables can be null,
      * and any accesses to them should be prepared to handle such a case.
diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java
index e50cb95..4be11b8 100644
--- a/telephony/java/com/android/internal/telephony/DctConstants.java
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -109,7 +109,8 @@
     public static final int APN_IMS_ID = 5;
     public static final int APN_FOTA_ID = 6;
     public static final int APN_CBS_ID = 7;
-    public static final int APN_NUM_TYPES = 8;
+    public static final int APN_IA_ID = 8;
+    public static final int APN_NUM_TYPES = 9;
 
     public static final int DISABLED = 0;
     public static final int ENABLED = 1;
diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl
index 828e025..647f014 100644
--- a/telephony/java/com/android/internal/telephony/ISms.aidl
+++ b/telephony/java/com/android/internal/telephony/ISms.aidl
@@ -1,6 +1,5 @@
 /*
 ** Copyright 2007, The Android Open Source Project
-** Copyright (c) 2012, The Linux Foundation. All rights reserved.
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
@@ -216,26 +215,4 @@
      * Requires system permission.
      */
     void setPremiumSmsPermission(String packageName, int permission);
-
-    /**
-     * SMS over IMS is supported if IMS is registered and SMS is supported
-     * on IMS.
-     *
-     * @return true if SMS over IMS is supported, false otherwise
-     *
-     * @see #getImsSmsFormat()
-     */
-    boolean isImsSmsSupported();
-
-    /**
-     * Gets SMS format supported on IMS.  SMS over IMS format is
-     * either 3GPP or 3GPP2.
-     *
-     * @return android.telephony.SmsMessage.FORMAT_3GPP,
-     *         android.telephony.SmsMessage.FORMAT_3GPP2
-     *      or android.telephony.SmsMessage.FORMAT_UNKNOWN
-     *
-     * @see #isImsSmsSupported()
-     */
-    String getImsSmsFormat();
 }
diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java
index 16ea625..4a4a62b 100644
--- a/telephony/java/com/android/internal/telephony/PhoneConstants.java
+++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java
@@ -119,5 +119,7 @@
     public static final String APN_TYPE_IMS = "ims";
     /** APN type for CBS */
     public static final String APN_TYPE_CBS = "cbs";
+    /** APN type for IA Initial Attach APN */
+    public static final String APN_TYPE_IA = "ia";
 
 }
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 5a7f13a..9650b99 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -1,6 +1,5 @@
 /*
  * Copyright (C) 2006 The Android Open Source Project
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -263,8 +262,6 @@
     int RIL_REQUEST_VOICE_RADIO_TECH = 108;
     int RIL_REQUEST_GET_CELL_INFO_LIST = 109;
     int RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE = 110;
-    int RIL_REQUEST_IMS_REGISTRATION_STATE = 111;
-    int RIL_REQUEST_IMS_SEND_SMS = 112;
     int RIL_UNSOL_RESPONSE_BASE = 1000;
     int RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED = 1000;
     int RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED = 1001;
@@ -303,5 +300,4 @@
     int RIL_UNSOL_RIL_CONNECTED = 1034;
     int RIL_UNSOL_VOICE_RADIO_TECH_CHANGED = 1035;
     int RIL_UNSOL_CELL_INFO_LIST = 1036;
-    int RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED = 1037;
 }
diff --git a/telephony/java/com/android/internal/telephony/SmsConstants.java b/telephony/java/com/android/internal/telephony/SmsConstants.java
index a36697a..1ccdc3b 100644
--- a/telephony/java/com/android/internal/telephony/SmsConstants.java
+++ b/telephony/java/com/android/internal/telephony/SmsConstants.java
@@ -1,6 +1,5 @@
 /*
  * Copyright (C) 2012 The Android Open Source Project
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -63,12 +62,6 @@
     }
 
     /**
-     * Indicates unknown format SMS message.
-     * @hide pending API council approval
-     */
-    public static final String FORMAT_UNKNOWN = "unknown";
-
-    /**
      * Indicates a 3GPP format SMS message.
      * @hide pending API council approval
      */
diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
index 40a3c8f..a7baf1c 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
@@ -260,6 +260,23 @@
     public static final String ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS
             = "android.intent.action.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS";
 
+    /**
+     * Activity Action: Start this activity to invoke the carrier setup app.
+     * To filter the intent, see {@link #CATEGORY_MCCMNC_PREFIX}.
+     *
+     * <p class="note">Callers of this should hold the android.permission.INVOKE_CARRIER_SETUP
+     * permission.</p>
+     */
+    public static final String ACTION_CARRIER_SETUP = "android.intent.action.ACTION_CARRIER_SETUP";
+
+    /**
+     * A <em>prefix</em> for the MCC/MNC filtering used with {@link #ACTION_CARRIER_SETUP}.
+     * The MCC/MNC will be concatenated (zero-padded to 3 digits each) to create a final
+     * string of the form:
+     * <br />
+     * <code>android.intent.category.MCCMNC_310260</code>
+     */
+    public static final String CATEGORY_MCCMNC_PREFIX = "android.intent.category.MCCMNC_";
 
     /**
      * Broadcast Action: A "secret code" has been entered in the dialer. Secret codes are
diff --git a/test-runner/src/android/test/mock/MockContentProvider.java b/test-runner/src/android/test/mock/MockContentProvider.java
index 373f24a..28d52b0 100644
--- a/test-runner/src/android/test/mock/MockContentProvider.java
+++ b/test-runner/src/android/test/mock/MockContentProvider.java
@@ -83,13 +83,15 @@
         }
 
         @Override
-        public AssetFileDescriptor openAssetFile(String callingPackage, Uri url, String mode)
+        public AssetFileDescriptor openAssetFile(
+                String callingPackage, Uri url, String mode, ICancellationSignal signal)
                 throws RemoteException, FileNotFoundException {
             return MockContentProvider.this.openAssetFile(url, mode);
         }
 
         @Override
-        public ParcelFileDescriptor openFile(String callingPackage, Uri url, String mode)
+        public ParcelFileDescriptor openFile(
+                String callingPackage, Uri url, String mode, ICancellationSignal signal)
                 throws RemoteException, FileNotFoundException {
             return MockContentProvider.this.openFile(url, mode);
         }
@@ -126,7 +128,7 @@
 
         @Override
         public AssetFileDescriptor openTypedAssetFile(String callingPackage, Uri url,
-                String mimeType, Bundle opts)
+                String mimeType, Bundle opts, ICancellationSignal signal)
                 throws RemoteException, FileNotFoundException {
             return MockContentProvider.this.openTypedAssetFile(url, mimeType, opts);
         }
@@ -135,6 +137,16 @@
         public ICancellationSignal createCancellationSignal() throws RemoteException {
             return null;
         }
+
+        @Override
+        public Uri canonicalize(String callingPkg, Uri uri) throws RemoteException {
+            return MockContentProvider.this.canonicalize(uri);
+        }
+
+        @Override
+        public Uri uncanonicalize(String callingPkg, Uri uri) throws RemoteException {
+            return MockContentProvider.this.uncanonicalize(uri);
+        }
     }
     private final InversionIContentProvider mIContentProvider = new InversionIContentProvider();
 
diff --git a/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java
index 29d6e4d..0d9cd18 100644
--- a/test-runner/src/android/test/mock/MockContext.java
+++ b/test-runner/src/android/test/mock/MockContext.java
@@ -39,7 +39,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.UserHandle;
-import android.view.CompatibilityInfoHolder;
+import android.view.DisplayAdjustments;
 import android.view.Display;
 
 import java.io.File;
@@ -112,6 +112,12 @@
         throw new UnsupportedOperationException();
     }
 
+    /** @hide */
+    @Override
+    public String getOpPackageName() {
+        throw new UnsupportedOperationException();
+    }
+
     @Override
     public ApplicationInfo getApplicationInfo() {
         throw new UnsupportedOperationException();
@@ -574,7 +580,22 @@
 
     /** @hide */
     @Override
-    public CompatibilityInfoHolder getCompatibilityInfo(int displayId) {
+    public DisplayAdjustments getDisplayAdjustments(int displayId) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public File[] getExternalFilesDirs(String type) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public File[] getObbDirs() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public File[] getExternalCacheDirs() {
         throw new UnsupportedOperationException();
     }
 }
diff --git a/test-runner/src/android/test/mock/MockCursor.java b/test-runner/src/android/test/mock/MockCursor.java
index baa150a..5b8a4f4 100644
--- a/test-runner/src/android/test/mock/MockCursor.java
+++ b/test-runner/src/android/test/mock/MockCursor.java
@@ -177,17 +177,18 @@
         throw new UnsupportedOperationException("unimplemented mock method");
     }
 
-    @SuppressWarnings("deprecation")
     public void setNotificationUri(ContentResolver cr, Uri uri) {
         throw new UnsupportedOperationException("unimplemented mock method");
     }
 
-    @SuppressWarnings("deprecation")
+    public Uri getNotificationUri() {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
     public void unregisterContentObserver(ContentObserver observer) {
         throw new UnsupportedOperationException("unimplemented mock method");
     }
 
-    @SuppressWarnings("deprecation")
     public void unregisterDataSetObserver(DataSetObserver observer) {
         throw new UnsupportedOperationException("unimplemented mock method");
     }
diff --git a/test-runner/src/android/test/mock/MockIContentProvider.java b/test-runner/src/android/test/mock/MockIContentProvider.java
index 2b4fce6..c0dc7c3 100644
--- a/test-runner/src/android/test/mock/MockIContentProvider.java
+++ b/test-runner/src/android/test/mock/MockIContentProvider.java
@@ -61,11 +61,13 @@
         throw new UnsupportedOperationException("unimplemented mock method");
     }
 
-    public ParcelFileDescriptor openFile(String callingPackage, Uri url, String mode) {
+    public ParcelFileDescriptor openFile(
+            String callingPackage, Uri url, String mode, ICancellationSignal signal) {
         throw new UnsupportedOperationException("unimplemented mock method");
     }
 
-    public AssetFileDescriptor openAssetFile(String callingPackage, Uri uri, String mode) {
+    public AssetFileDescriptor openAssetFile(
+            String callingPackage, Uri uri, String mode, ICancellationSignal signal) {
         throw new UnsupportedOperationException("unimplemented mock method");
     }
 
@@ -104,7 +106,7 @@
     }
 
     public AssetFileDescriptor openTypedAssetFile(String callingPackage, Uri url, String mimeType,
-            Bundle opts) throws RemoteException, FileNotFoundException {
+            Bundle opts, ICancellationSignal signal) throws RemoteException, FileNotFoundException {
         throw new UnsupportedOperationException("unimplemented mock method");
     }
 
@@ -112,4 +114,14 @@
     public ICancellationSignal createCancellationSignal() throws RemoteException {
         throw new UnsupportedOperationException("unimplemented mock method");
     }
+
+    @Override
+    public Uri canonicalize(String callingPkg, Uri uri) throws RemoteException {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public Uri uncanonicalize(String callingPkg, Uri uri) throws RemoteException {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
 }
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index 20a26ab..5f944f6 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -45,6 +45,9 @@
 import android.content.res.XmlResourceParser;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
+import android.os.Binder;
+import android.os.RemoteException;
+import android.os.UserHandle;
 
 import java.util.List;
 
@@ -541,6 +544,12 @@
         throw new UnsupportedOperationException();
     }
 
+    /** @hide - hidden in superclass */
+    @Override
+    public ComponentName getHomeActivities(List<ResolveInfo> outActivities) {
+        throw new UnsupportedOperationException();
+    }
+
     @Override
     public String[] getSystemSharedLibraryNames() {
         throw new UnsupportedOperationException();
@@ -585,6 +594,23 @@
      * @hide
      */
     @Override
+    public boolean setApplicationBlockedSettingAsUser(String packageName, boolean blocked,
+            UserHandle user) {
+        return false;
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public boolean getApplicationBlockedSettingAsUser(String packageName, UserHandle user) {
+        return false;
+    }
+
+    /**
+     * @hide
+     */
+    @Override
     public int installExistingPackage(String packageName)
             throws NameNotFoundException {
         throw new UnsupportedOperationException();
diff --git a/tests/AccessoryDisplay/Android.mk b/tests/AccessoryDisplay/Android.mk
new file mode 100644
index 0000000..85cb309
--- /dev/null
+++ b/tests/AccessoryDisplay/Android.mk
@@ -0,0 +1,17 @@
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/AccessoryDisplay/README b/tests/AccessoryDisplay/README
new file mode 100644
index 0000000..5ce558c
--- /dev/null
+++ b/tests/AccessoryDisplay/README
@@ -0,0 +1,50 @@
+This directory contains sample code to test the use of virtual
+displays created over an Android Open Accessories Protocol link.
+
+--- DESCRIPTION ---
+
+There are two applications with two distinct roles: a sink
+and a source.
+
+1. Sink Application
+
+The role of the sink is to emulate an external display that happens
+to be connected using the USB accessory protocol.  Think of it as
+a monitor or video dock that the user will want to plug a phone into.
+
+The sink application uses the UsbDevice APIs to receive connections
+from the source device over USB.  The sink acts as a USB host
+in this arrangement and will provide power to the source.
+
+The sink application decodes encoded video from the source and
+displays it in a SurfaceView.  The sink also injects passes touch
+events to the source over USB HID.
+
+2. Source Application
+
+The role of the source is to present some content onto an external
+display that happens to be attached over USB.  This is the typical
+role that a phone or tablet might have when the user is trying to
+play content to an external monitor.
+
+The source application uses the UsbAccessory APIs to connect
+to the sink device over USB.  The source acts as a USB peripheral
+in this arrangement and will receive power from the sink.
+
+The source application uses the DisplayManager APIs to create
+a private virtual display which passes the framebuffer through
+an encoder and streams the output to the sink over USB.  Then
+the application opens a Presentation on the new virtual display
+and shows a silly cube animation.
+
+--- USAGE ---
+
+These applications should be installed on two separate Android
+devices which are then connected using a USB OTG cable.
+Remember that the sink device is functioning as the USB host
+so the USB OTG cable should be plugged directly into it.
+
+When connected, the applications should automatically launch
+on each device.  The source will then begin to project display
+contents to the sink.
+
diff --git a/tests/AccessoryDisplay/common/Android.mk b/tests/AccessoryDisplay/common/Android.mk
new file mode 100644
index 0000000..2d4de15
--- /dev/null
+++ b/tests/AccessoryDisplay/common/Android.mk
@@ -0,0 +1,23 @@
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+# Build the application.
+include $(CLEAR_VARS)
+LOCAL_MODULE := AccessoryDisplayCommon
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/tests/AccessoryDisplay/common/src/com/android/accessorydisplay/common/BufferPool.java b/tests/AccessoryDisplay/common/src/com/android/accessorydisplay/common/BufferPool.java
new file mode 100644
index 0000000..a6bb5c1
--- /dev/null
+++ b/tests/AccessoryDisplay/common/src/com/android/accessorydisplay/common/BufferPool.java
@@ -0,0 +1,92 @@
+/*
+ * 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.accessorydisplay.common;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Maintains a bounded pool of buffers.  Attempts to acquire buffers beyond the maximum
+ * count will block until other buffers are released.
+ */
+final class BufferPool {
+    private final int mInitialBufferSize;
+    private final int mMaxBufferSize;
+    private final ByteBuffer[] mBuffers;
+    private int mAllocated;
+    private int mAvailable;
+
+    public BufferPool(int initialBufferSize, int maxBufferSize, int maxBuffers) {
+        mInitialBufferSize = initialBufferSize;
+        mMaxBufferSize = maxBufferSize;
+        mBuffers = new ByteBuffer[maxBuffers];
+    }
+
+    public ByteBuffer acquire(int needed) {
+        synchronized (this) {
+            for (;;) {
+                if (mAvailable != 0) {
+                    mAvailable -= 1;
+                    return grow(mBuffers[mAvailable], needed);
+                }
+
+                if (mAllocated < mBuffers.length) {
+                    mAllocated += 1;
+                    return ByteBuffer.allocate(chooseCapacity(mInitialBufferSize, needed));
+                }
+
+                try {
+                    wait();
+                } catch (InterruptedException ex) {
+                }
+            }
+        }
+    }
+
+    public void release(ByteBuffer buffer) {
+        synchronized (this) {
+            buffer.clear();
+            mBuffers[mAvailable++] = buffer;
+            notifyAll();
+        }
+    }
+
+    public ByteBuffer grow(ByteBuffer buffer, int needed) {
+        int capacity = buffer.capacity();
+        if (capacity < needed) {
+            final ByteBuffer oldBuffer = buffer;
+            capacity = chooseCapacity(capacity, needed);
+            buffer = ByteBuffer.allocate(capacity);
+            oldBuffer.flip();
+            buffer.put(oldBuffer);
+        }
+        return buffer;
+    }
+
+    private int chooseCapacity(int capacity, int needed) {
+        while (capacity < needed) {
+            capacity *= 2;
+        }
+        if (capacity > mMaxBufferSize) {
+            if (needed > mMaxBufferSize) {
+                throw new IllegalArgumentException("Requested size " + needed
+                        + " is larger than maximum buffer size " + mMaxBufferSize + ".");
+            }
+            capacity = mMaxBufferSize;
+        }
+        return capacity;
+    }
+}
diff --git a/tests/AccessoryDisplay/common/src/com/android/accessorydisplay/common/Logger.java b/tests/AccessoryDisplay/common/src/com/android/accessorydisplay/common/Logger.java
new file mode 100644
index 0000000..e0b7e82
--- /dev/null
+++ b/tests/AccessoryDisplay/common/src/com/android/accessorydisplay/common/Logger.java
@@ -0,0 +1,25 @@
+/*
+ * 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.accessorydisplay.common;
+
+public abstract class Logger {
+    public abstract void log(String message);
+
+    public void logError(String message) {
+        log("ERROR: " + message);
+    }
+}
diff --git a/tests/AccessoryDisplay/common/src/com/android/accessorydisplay/common/Protocol.java b/tests/AccessoryDisplay/common/src/com/android/accessorydisplay/common/Protocol.java
new file mode 100644
index 0000000..46fee32
--- /dev/null
+++ b/tests/AccessoryDisplay/common/src/com/android/accessorydisplay/common/Protocol.java
@@ -0,0 +1,65 @@
+/*
+ * 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.accessorydisplay.common;
+
+/**
+ * Defines message types.
+ */
+public class Protocol {
+    // Message header.
+    //   0: service id (16 bits)
+    //   2: what (16 bits)
+    //   4: content size (32 bits)
+    //   8: ... content follows ...
+    static final int HEADER_SIZE = 8;
+
+    // Maximum size of a message envelope including the header and contents.
+    static final int MAX_ENVELOPE_SIZE = 64 * 1024;
+
+    /**
+     * Maximum message content size.
+     */
+    public static final int MAX_CONTENT_SIZE = MAX_ENVELOPE_SIZE - HEADER_SIZE;
+
+    public static final class DisplaySinkService {
+        private DisplaySinkService() { }
+
+        public static final int ID = 1;
+
+        // Query sink capabilities.
+        // Replies with sink available or not available.
+        public static final int MSG_QUERY = 1;
+
+        // Send MPEG2-TS H.264 encoded content.
+        public static final int MSG_CONTENT = 2;
+    }
+
+    public static final class DisplaySourceService {
+        private DisplaySourceService() { }
+
+        public static final int ID = 2;
+
+        // Sink is now available for use.
+        //   0: width (32 bits)
+        //   4: height (32 bits)
+        //   8: density dpi (32 bits)
+        public static final int MSG_SINK_AVAILABLE = 1;
+
+        // Sink is no longer available for use.
+        public static final int MSG_SINK_NOT_AVAILABLE = 2;
+    }
+}
diff --git a/tests/AccessoryDisplay/common/src/com/android/accessorydisplay/common/Service.java b/tests/AccessoryDisplay/common/src/com/android/accessorydisplay/common/Service.java
new file mode 100644
index 0000000..70b3806
--- /dev/null
+++ b/tests/AccessoryDisplay/common/src/com/android/accessorydisplay/common/Service.java
@@ -0,0 +1,71 @@
+/*
+ * 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.accessorydisplay.common;
+
+import com.android.accessorydisplay.common.Transport;
+
+import android.content.Context;
+import android.os.Looper;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Base implementation of a service that communicates over a transport.
+ * <p>
+ * This object's interface is single-threaded.  It is only intended to be
+ * accessed from the {@link Looper} thread on which the transport was created.
+ * </p>
+ */
+public abstract class Service implements Transport.Callback {
+    private final Context mContext;
+    private final Transport mTransport;
+    private final int mServiceId;
+
+    public Service(Context context, Transport transport, int serviceId) {
+        mContext = context;
+        mTransport = transport;
+        mServiceId = serviceId;
+    }
+
+    public Context getContext() {
+        return mContext;
+    }
+
+    public int getServiceId() {
+        return mServiceId;
+    }
+
+    public Transport getTransport() {
+        return mTransport;
+    }
+
+    public Logger getLogger() {
+        return mTransport.getLogger();
+    }
+
+    public void start() {
+        mTransport.registerService(mServiceId, this);
+    }
+
+    public void stop() {
+        mTransport.unregisterService(mServiceId);
+    }
+
+    @Override
+    public void onMessageReceived(int service, int what, ByteBuffer content) {
+    }
+}
diff --git a/tests/AccessoryDisplay/common/src/com/android/accessorydisplay/common/Transport.java b/tests/AccessoryDisplay/common/src/com/android/accessorydisplay/common/Transport.java
new file mode 100644
index 0000000..84897d3
--- /dev/null
+++ b/tests/AccessoryDisplay/common/src/com/android/accessorydisplay/common/Transport.java
@@ -0,0 +1,382 @@
+/*
+ * 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.accessorydisplay.common;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.util.SparseArray;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * A simple message transport.
+ * <p>
+ * This object's interface is thread-safe, however incoming messages
+ * are always delivered on the {@link Looper} thread on which the transport
+ * was created.
+ * </p>
+ */
+public abstract class Transport {
+    private static final int MAX_INPUT_BUFFERS = 8;
+
+    private final Logger mLogger;
+
+    // The transport thread looper and handler.
+    private final TransportHandler mHandler;
+
+    // Lock to guard all mutable state.
+    private final Object mLock = new Object();
+
+    // The output buffer.  Set to null when the transport is closed.
+    private ByteBuffer mOutputBuffer;
+
+    // The input buffer pool.
+    private BufferPool mInputBufferPool;
+
+    // The reader thread.  Initialized when reading starts.
+    private ReaderThread mThread;
+
+    // The list of callbacks indexed by service id.
+    private final SparseArray<Callback> mServices = new SparseArray<Callback>();
+
+    public Transport(Logger logger, int maxPacketSize) {
+        mLogger = logger;
+        mHandler = new TransportHandler();
+        mOutputBuffer = ByteBuffer.allocate(maxPacketSize);
+        mInputBufferPool = new BufferPool(
+                maxPacketSize, Protocol.MAX_ENVELOPE_SIZE, MAX_INPUT_BUFFERS);
+    }
+
+    /**
+     * Gets the logger for debugging.
+     */
+    public Logger getLogger() {
+        return mLogger;
+    }
+
+    /**
+     * Gets the handler on the transport's thread.
+     */
+    public Handler getHandler() {
+        return mHandler;
+    }
+
+    /**
+     * Closes the transport.
+     */
+    public void close() {
+        synchronized (mLock) {
+            if (mOutputBuffer != null) {
+                if (mThread == null) {
+                    ioClose();
+                } else {
+                    // If the thread was started then it will be responsible for
+                    // closing the stream when it quits because it may currently
+                    // be in the process of reading from the stream so we can't simply
+                    // shut it down right now.
+                    mThread.quit();
+                }
+                mOutputBuffer = null;
+            }
+        }
+    }
+
+    /**
+     * Sends a message.
+     *
+     * @param service The service to whom the message is addressed.
+     * @param what The message type.
+     * @param content The content, or null if there is none.
+     * @return True if the message was sent successfully, false if an error occurred.
+     */
+    public boolean sendMessage(int service, int what, ByteBuffer content) {
+        checkServiceId(service);
+        checkMessageId(what);
+
+        try {
+            synchronized (mLock) {
+                if (mOutputBuffer == null) {
+                    mLogger.logError("Send message failed because transport was closed.");
+                    return false;
+                }
+
+                final byte[] outputArray = mOutputBuffer.array();
+                final int capacity = mOutputBuffer.capacity();
+                mOutputBuffer.clear();
+                mOutputBuffer.putShort((short)service);
+                mOutputBuffer.putShort((short)what);
+                if (content == null) {
+                    mOutputBuffer.putInt(0);
+                } else {
+                    final int contentLimit = content.limit();
+                    int contentPosition = content.position();
+                    int contentRemaining = contentLimit - contentPosition;
+                    if (contentRemaining > Protocol.MAX_CONTENT_SIZE) {
+                        throw new IllegalArgumentException("Message content too large: "
+                                + contentRemaining + " > " + Protocol.MAX_CONTENT_SIZE);
+                    }
+                    mOutputBuffer.putInt(contentRemaining);
+                    while (contentRemaining != 0) {
+                        final int outputAvailable = capacity - mOutputBuffer.position();
+                        if (contentRemaining <= outputAvailable) {
+                            mOutputBuffer.put(content);
+                            break;
+                        }
+                        content.limit(contentPosition + outputAvailable);
+                        mOutputBuffer.put(content);
+                        content.limit(contentLimit);
+                        ioWrite(outputArray, 0, capacity);
+                        contentPosition += outputAvailable;
+                        contentRemaining -= outputAvailable;
+                        mOutputBuffer.clear();
+                    }
+                }
+                ioWrite(outputArray, 0, mOutputBuffer.position());
+                return true;
+            }
+        } catch (IOException ex) {
+            mLogger.logError("Send message failed: " + ex);
+            return false;
+        }
+    }
+
+    /**
+     * Starts reading messages on a separate thread.
+     */
+    public void startReading() {
+        synchronized (mLock) {
+            if (mOutputBuffer == null) {
+                throw new IllegalStateException("Transport has been closed");
+            }
+
+            mThread = new ReaderThread();
+            mThread.start();
+        }
+    }
+
+    /**
+     * Registers a service and provides a callback to receive messages.
+     *
+     * @param service The service id.
+     * @param callback The callback to use.
+     */
+    public void registerService(int service, Callback callback) {
+        checkServiceId(service);
+        if (callback == null) {
+            throw new IllegalArgumentException("callback must not be null");
+        }
+
+        synchronized (mLock) {
+            mServices.put(service, callback);
+        }
+    }
+
+    /**
+     * Unregisters a service.
+     *
+     * @param service The service to unregister.
+     */
+    public void unregisterService(int service) {
+        checkServiceId(service);
+
+        synchronized (mLock) {
+            mServices.remove(service);
+        }
+    }
+
+    private void dispatchMessageReceived(int service, int what, ByteBuffer content) {
+        final Callback callback;
+        synchronized (mLock) {
+            callback = mServices.get(service);
+        }
+        if (callback != null) {
+            callback.onMessageReceived(service, what, content);
+        } else {
+            mLogger.log("Discarding message " + what
+                    + " for unregistered service " + service);
+        }
+    }
+
+    private static void checkServiceId(int service) {
+        if (service < 0 || service > 0xffff) {
+            throw new IllegalArgumentException("service id out of range: " + service);
+        }
+    }
+
+    private static void checkMessageId(int what) {
+        if (what < 0 || what > 0xffff) {
+            throw new IllegalArgumentException("message id out of range: " + what);
+        }
+    }
+
+    // The IO methods must be safe to call on any thread.
+    // They may be called concurrently.
+    protected abstract void ioClose();
+    protected abstract int ioRead(byte[] buffer, int offset, int count)
+            throws IOException;
+    protected abstract void ioWrite(byte[] buffer, int offset, int count)
+            throws IOException;
+
+    /**
+     * Callback for services that handle received messages.
+     */
+    public interface Callback {
+        /**
+         * Indicates that a message was received.
+         *
+         * @param service The service to whom the message is addressed.
+         * @param what The message type.
+         * @param content The content, or null if there is none.
+         */
+        public void onMessageReceived(int service, int what, ByteBuffer content);
+    }
+
+    final class TransportHandler extends Handler {
+        @Override
+        public void handleMessage(Message msg) {
+            final ByteBuffer buffer = (ByteBuffer)msg.obj;
+            try {
+                final int limit = buffer.limit();
+                while (buffer.position() < limit) {
+                    final int service = buffer.getShort() & 0xffff;
+                    final int what = buffer.getShort() & 0xffff;
+                    final int contentSize = buffer.getInt();
+                    if (contentSize == 0) {
+                        dispatchMessageReceived(service, what, null);
+                    } else {
+                        final int end = buffer.position() + contentSize;
+                        buffer.limit(end);
+                        dispatchMessageReceived(service, what, buffer);
+                        buffer.limit(limit);
+                        buffer.position(end);
+                    }
+                }
+            } finally {
+                mInputBufferPool.release(buffer);
+            }
+        }
+    }
+
+    final class ReaderThread extends Thread {
+        // Set to true when quitting.
+        private volatile boolean mQuitting;
+
+        public ReaderThread() {
+            super("Accessory Display Transport");
+        }
+
+        @Override
+        public void run() {
+            loop();
+            ioClose();
+        }
+
+        private void loop() {
+            ByteBuffer buffer = null;
+            int length = Protocol.HEADER_SIZE;
+            int contentSize = -1;
+            outer: while (!mQuitting) {
+                // Get a buffer.
+                if (buffer == null) {
+                    buffer = mInputBufferPool.acquire(length);
+                } else {
+                    buffer = mInputBufferPool.grow(buffer, length);
+                }
+
+                // Read more data until needed number of bytes obtained.
+                int position = buffer.position();
+                int count;
+                try {
+                    count = ioRead(buffer.array(), position, buffer.capacity() - position);
+                    if (count < 0) {
+                        break; // end of stream
+                    }
+                } catch (IOException ex) {
+                    mLogger.logError("Read failed: " + ex);
+                    break; // error
+                }
+                position += count;
+                buffer.position(position);
+                if (contentSize < 0 && position >= Protocol.HEADER_SIZE) {
+                    contentSize = buffer.getInt(4);
+                    if (contentSize < 0 || contentSize > Protocol.MAX_CONTENT_SIZE) {
+                        mLogger.logError("Encountered invalid content size: " + contentSize);
+                        break; // malformed stream
+                    }
+                    length += contentSize;
+                }
+                if (position < length) {
+                    continue; // need more data
+                }
+
+                // There is at least one complete message in the buffer.
+                // Find the end of a contiguous chunk of complete messages.
+                int next = length;
+                int remaining;
+                for (;;) {
+                    length = Protocol.HEADER_SIZE;
+                    remaining = position - next;
+                    if (remaining < length) {
+                        contentSize = -1;
+                        break; // incomplete header, need more data
+                    }
+                    contentSize = buffer.getInt(next + 4);
+                    if (contentSize < 0 || contentSize > Protocol.MAX_CONTENT_SIZE) {
+                        mLogger.logError("Encountered invalid content size: " + contentSize);
+                        break outer; // malformed stream
+                    }
+                    length += contentSize;
+                    if (remaining < length) {
+                        break; // incomplete content, need more data
+                    }
+                    next += length;
+                }
+
+                // Post the buffer then don't modify it anymore.
+                // Now this is kind of sneaky.  We know that no other threads will
+                // be acquiring buffers from the buffer pool so we can keep on
+                // referring to this buffer as long as we don't modify its contents.
+                // This allows us to operate in a single-buffered mode if desired.
+                buffer.limit(next);
+                buffer.rewind();
+                mHandler.obtainMessage(0, buffer).sendToTarget();
+
+                // If there is an incomplete message at the end, then we will need
+                // to copy it to a fresh buffer before continuing.  In the single-buffered
+                // case, we may acquire the same buffer as before which is fine.
+                if (remaining == 0) {
+                    buffer = null;
+                } else {
+                    final ByteBuffer oldBuffer = buffer;
+                    buffer = mInputBufferPool.acquire(length);
+                    System.arraycopy(oldBuffer.array(), next, buffer.array(), 0, remaining);
+                    buffer.position(remaining);
+                }
+            }
+
+            if (buffer != null) {
+                mInputBufferPool.release(buffer);
+            }
+        }
+
+        public void quit() {
+            mQuitting = true;
+        }
+    }
+}
diff --git a/tests/AccessoryDisplay/sink/Android.mk b/tests/AccessoryDisplay/sink/Android.mk
new file mode 100644
index 0000000..772ce0c
--- /dev/null
+++ b/tests/AccessoryDisplay/sink/Android.mk
@@ -0,0 +1,25 @@
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+# Build the application.
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := AccessoryDisplaySink
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_RESOURCE_DIR = $(LOCAL_PATH)/res
+LOCAL_STATIC_JAVA_LIBRARIES := AccessoryDisplayCommon
+include $(BUILD_PACKAGE)
diff --git a/tests/AccessoryDisplay/sink/AndroidManifest.xml b/tests/AccessoryDisplay/sink/AndroidManifest.xml
new file mode 100644
index 0000000..72d498f
--- /dev/null
+++ b/tests/AccessoryDisplay/sink/AndroidManifest.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.accessorydisplay.sink" >
+
+    <uses-feature android:name="android.hardware.usb.host"/>
+    <uses-sdk android:minSdkVersion="18" />
+
+    <application android:label="@string/app_name"
+            android:icon="@drawable/ic_app"
+            android:hardwareAccelerated="true">
+
+        <activity android:name=".SinkActivity"
+                android:label="@string/app_name"
+                android:theme="@android:style/Theme.Holo">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/>
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+            <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
+                    android:resource="@xml/usb_device_filter"/>
+        </activity>
+
+    </application>
+</manifest>
diff --git a/tests/AccessoryDisplay/sink/res/drawable-hdpi/ic_app.png b/tests/AccessoryDisplay/sink/res/drawable-hdpi/ic_app.png
new file mode 100755
index 0000000..66a1984
--- /dev/null
+++ b/tests/AccessoryDisplay/sink/res/drawable-hdpi/ic_app.png
Binary files differ
diff --git a/tests/AccessoryDisplay/sink/res/drawable-mdpi/ic_app.png b/tests/AccessoryDisplay/sink/res/drawable-mdpi/ic_app.png
new file mode 100644
index 0000000..5ae7701
--- /dev/null
+++ b/tests/AccessoryDisplay/sink/res/drawable-mdpi/ic_app.png
Binary files differ
diff --git a/tests/AccessoryDisplay/sink/res/layout/sink_activity.xml b/tests/AccessoryDisplay/sink/res/layout/sink_activity.xml
new file mode 100644
index 0000000..6afb850
--- /dev/null
+++ b/tests/AccessoryDisplay/sink/res/layout/sink_activity.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="horizontal">
+    <LinearLayout
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:orientation="vertical">
+        <TextView android:id="@+id/fpsTextView"
+                android:layout_width="match_parent"
+                android:layout_height="64dp"
+                android:padding="4dp" />
+
+        <TextView android:id="@+id/logTextView"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent" />
+    </LinearLayout>
+
+    <FrameLayout
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="2">
+        <SurfaceView android:id="@+id/surfaceView"
+                android:layout_width="640px"
+                android:layout_height="480px" />
+    </FrameLayout>
+</LinearLayout>
diff --git a/tests/AccessoryDisplay/sink/res/values/strings.xml b/tests/AccessoryDisplay/sink/res/values/strings.xml
new file mode 100644
index 0000000..29cd001
--- /dev/null
+++ b/tests/AccessoryDisplay/sink/res/values/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name">Accessory Display Sink</string>
+</resources>
diff --git a/tests/AccessoryDisplay/sink/res/xml/usb_device_filter.xml b/tests/AccessoryDisplay/sink/res/xml/usb_device_filter.xml
new file mode 100644
index 0000000..e8fe929
--- /dev/null
+++ b/tests/AccessoryDisplay/sink/res/xml/usb_device_filter.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <!-- Match all devices -->
+    <usb-device />
+
+    <!-- Android USB accessory: accessory -->
+    <usb-device vendor-id="16601" product-id="11520" />
+    <!-- Android USB accessory: accessory + adb -->
+    <usb-device vendor-id="16601" product-id="11521" />
+</resources>
diff --git a/tests/AccessoryDisplay/sink/src/com/android/accessorydisplay/sink/DisplaySinkService.java b/tests/AccessoryDisplay/sink/src/com/android/accessorydisplay/sink/DisplaySinkService.java
new file mode 100644
index 0000000..daec845
--- /dev/null
+++ b/tests/AccessoryDisplay/sink/src/com/android/accessorydisplay/sink/DisplaySinkService.java
@@ -0,0 +1,240 @@
+/*
+ * 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.accessorydisplay.sink;
+
+import com.android.accessorydisplay.common.Protocol;
+import com.android.accessorydisplay.common.Service;
+import com.android.accessorydisplay.common.Transport;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.media.MediaCodec;
+import android.media.MediaCodec.BufferInfo;
+import android.media.MediaFormat;
+import android.os.Handler;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+import java.nio.ByteBuffer;
+
+public class DisplaySinkService extends Service implements SurfaceHolder.Callback {
+    private final ByteBuffer mBuffer = ByteBuffer.allocate(12);
+    private final Handler mTransportHandler;
+    private final int mDensityDpi;
+
+    private SurfaceView mSurfaceView;
+
+    // These fields are guarded by the following lock.
+    // This is to ensure that the surface lifecycle is respected.  Although decoding
+    // happens on the transport thread, we are not allowed to access the surface after
+    // it is destroyed by the UI thread so we need to stop the codec immediately.
+    private final Object mSurfaceAndCodecLock = new Object();
+    private Surface mSurface;
+    private int mSurfaceWidth;
+    private int mSurfaceHeight;
+    private MediaCodec mCodec;
+    private ByteBuffer[] mCodecInputBuffers;
+    private BufferInfo mCodecBufferInfo;
+
+    public DisplaySinkService(Context context, Transport transport, int densityDpi) {
+        super(context, transport, Protocol.DisplaySinkService.ID);
+        mTransportHandler = transport.getHandler();
+        mDensityDpi = densityDpi;
+    }
+
+    public void setSurfaceView(final SurfaceView surfaceView) {
+        if (mSurfaceView != surfaceView) {
+            final SurfaceView oldSurfaceView = mSurfaceView;
+            mSurfaceView = surfaceView;
+
+            if (oldSurfaceView != null) {
+                oldSurfaceView.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        final SurfaceHolder holder = oldSurfaceView.getHolder();
+                        holder.removeCallback(DisplaySinkService.this);
+                        updateSurfaceFromUi(null);
+                    }
+                });
+            }
+
+            if (surfaceView != null) {
+                surfaceView.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        final SurfaceHolder holder = surfaceView.getHolder();
+                        holder.addCallback(DisplaySinkService.this);
+                        updateSurfaceFromUi(holder);
+                    }
+                });
+            }
+        }
+    }
+
+    @Override
+    public void onMessageReceived(int service, int what, ByteBuffer content) {
+        switch (what) {
+            case Protocol.DisplaySinkService.MSG_QUERY: {
+                getLogger().log("Received MSG_QUERY.");
+                sendSinkStatus();
+                break;
+            }
+
+            case Protocol.DisplaySinkService.MSG_CONTENT: {
+                decode(content);
+                break;
+            }
+        }
+    }
+
+    @Override
+    public void surfaceCreated(SurfaceHolder holder) {
+        // Ignore.  Wait for surface changed event that follows.
+    }
+
+    @Override
+    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+        updateSurfaceFromUi(holder);
+    }
+
+    @Override
+    public void surfaceDestroyed(SurfaceHolder holder) {
+        updateSurfaceFromUi(null);
+    }
+
+    private void updateSurfaceFromUi(SurfaceHolder holder) {
+        Surface surface = null;
+        int width = 0, height = 0;
+        if (holder != null && !holder.isCreating()) {
+            surface = holder.getSurface();
+            if (surface.isValid()) {
+                final Rect frame = holder.getSurfaceFrame();
+                width = frame.width();
+                height = frame.height();
+            } else {
+                surface = null;
+            }
+        }
+
+        synchronized (mSurfaceAndCodecLock) {
+            if (mSurface == surface &&  mSurfaceWidth == width && mSurfaceHeight == height) {
+                return;
+            }
+
+            mSurface = surface;
+            mSurfaceWidth = width;
+            mSurfaceHeight = height;
+
+            if (mCodec != null) {
+                mCodec.stop();
+                mCodec = null;
+                mCodecInputBuffers = null;
+                mCodecBufferInfo = null;
+            }
+
+            if (mSurface != null) {
+                MediaFormat format = MediaFormat.createVideoFormat(
+                        "video/avc", mSurfaceWidth, mSurfaceHeight);
+                mCodec = MediaCodec.createDecoderByType("video/avc");
+                mCodec.configure(format, mSurface, null, 0);
+                mCodec.start();
+                mCodecBufferInfo = new BufferInfo();
+            }
+
+            mTransportHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    sendSinkStatus();
+                }
+            });
+        }
+    }
+
+    private void decode(ByteBuffer content) {
+        if (content == null) {
+            return;
+        }
+        synchronized (mSurfaceAndCodecLock) {
+            if (mCodec == null) {
+                return;
+            }
+
+            while (content.hasRemaining()) {
+                if (!provideCodecInputLocked(content)) {
+                    getLogger().log("Dropping content because there are no available buffers.");
+                    return;
+                }
+
+                consumeCodecOutputLocked();
+            }
+        }
+    }
+
+    private boolean provideCodecInputLocked(ByteBuffer content) {
+        final int index = mCodec.dequeueInputBuffer(0);
+        if (index < 0) {
+            return false;
+        }
+        if (mCodecInputBuffers == null) {
+            mCodecInputBuffers = mCodec.getInputBuffers();
+        }
+        final ByteBuffer buffer = mCodecInputBuffers[index];
+        final int capacity = buffer.capacity();
+        buffer.clear();
+        if (content.remaining() <= capacity) {
+            buffer.put(content);
+        } else {
+            final int limit = content.limit();
+            content.limit(content.position() + capacity);
+            buffer.put(content);
+            content.limit(limit);
+        }
+        buffer.flip();
+        mCodec.queueInputBuffer(index, 0, buffer.limit(), 0, 0);
+        return true;
+    }
+
+    private void consumeCodecOutputLocked() {
+        for (;;) {
+            final int index = mCodec.dequeueOutputBuffer(mCodecBufferInfo, 0);
+            if (index >= 0) {
+                mCodec.releaseOutputBuffer(index, true /*render*/);
+            } else if (index != MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED
+                    && index != MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
+                break;
+            }
+        }
+    }
+
+    private void sendSinkStatus() {
+        synchronized (mSurfaceAndCodecLock) {
+            if (mCodec != null) {
+                mBuffer.clear();
+                mBuffer.putInt(mSurfaceWidth);
+                mBuffer.putInt(mSurfaceHeight);
+                mBuffer.putInt(mDensityDpi);
+                mBuffer.flip();
+                getTransport().sendMessage(Protocol.DisplaySourceService.ID,
+                        Protocol.DisplaySourceService.MSG_SINK_AVAILABLE, mBuffer);
+            } else {
+                getTransport().sendMessage(Protocol.DisplaySourceService.ID,
+                        Protocol.DisplaySourceService.MSG_SINK_NOT_AVAILABLE, null);
+            }
+        }
+    }
+}
diff --git a/tests/AccessoryDisplay/sink/src/com/android/accessorydisplay/sink/SinkActivity.java b/tests/AccessoryDisplay/sink/src/com/android/accessorydisplay/sink/SinkActivity.java
new file mode 100644
index 0000000..6fe2cfb
--- /dev/null
+++ b/tests/AccessoryDisplay/sink/src/com/android/accessorydisplay/sink/SinkActivity.java
@@ -0,0 +1,508 @@
+/*
+ * 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.accessorydisplay.sink;
+
+import com.android.accessorydisplay.common.Logger;
+
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.hardware.usb.UsbConstants;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbDeviceConnection;
+import android.hardware.usb.UsbEndpoint;
+import android.hardware.usb.UsbInterface;
+import android.hardware.usb.UsbManager;
+import android.media.MediaCodec;
+import android.media.MediaCodec.BufferInfo;
+import android.media.MediaFormat;
+import android.os.Bundle;
+import android.text.method.ScrollingMovementMethod;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.View;
+import android.widget.TextView;
+
+import java.nio.ByteBuffer;
+import java.util.LinkedList;
+import java.util.Map;
+
+public class SinkActivity extends Activity {
+    private static final String TAG = "SinkActivity";
+
+    private static final String ACTION_USB_DEVICE_PERMISSION =
+            "com.android.accessorydisplay.sink.ACTION_USB_DEVICE_PERMISSION";
+
+    private static final String MANUFACTURER = "Android";
+    private static final String MODEL = "Accessory Display";
+    private static final String DESCRIPTION = "Accessory Display Sink Test Application";
+    private static final String VERSION = "1.0";
+    private static final String URI = "http://www.android.com/";
+    private static final String SERIAL = "0000000012345678";
+
+    private static final int MULTITOUCH_DEVICE_ID = 0;
+    private static final int MULTITOUCH_REPORT_ID = 1;
+    private static final int MULTITOUCH_MAX_CONTACTS = 1;
+
+    private UsbManager mUsbManager;
+    private DeviceReceiver mReceiver;
+    private TextView mLogTextView;
+    private TextView mFpsTextView;
+    private SurfaceView mSurfaceView;
+    private Logger mLogger;
+
+    private boolean mConnected;
+    private int mProtocolVersion;
+    private UsbDevice mDevice;
+    private UsbInterface mAccessoryInterface;
+    private UsbDeviceConnection mAccessoryConnection;
+    private UsbEndpoint mControlEndpoint;
+    private UsbAccessoryBulkTransport mTransport;
+
+    private boolean mAttached;
+    private DisplaySinkService mDisplaySinkService;
+
+    private final ByteBuffer mHidBuffer = ByteBuffer.allocate(4096);
+    private UsbHid.Multitouch mMultitouch;
+    private boolean mMultitouchEnabled;
+    private UsbHid.Multitouch.Contact[] mMultitouchContacts;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mUsbManager = (UsbManager)getSystemService(Context.USB_SERVICE);
+
+        setContentView(R.layout.sink_activity);
+
+        mLogTextView = (TextView) findViewById(R.id.logTextView);
+        mLogTextView.setMovementMethod(ScrollingMovementMethod.getInstance());
+        mLogger = new TextLogger();
+
+        mFpsTextView = (TextView) findViewById(R.id.fpsTextView);
+
+        mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView);
+        mSurfaceView.setOnTouchListener(new View.OnTouchListener() {
+            @Override
+            public boolean onTouch(View v, MotionEvent event) {
+                sendHidTouch(event);
+                return true;
+            }
+        });
+
+        mLogger.log("Waiting for accessory display source to be attached to USB...");
+
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
+        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
+        filter.addAction(ACTION_USB_DEVICE_PERMISSION);
+        mReceiver = new DeviceReceiver();
+        registerReceiver(mReceiver, filter);
+
+        Intent intent = getIntent();
+        if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
+            UsbDevice device = intent.<UsbDevice>getParcelableExtra(UsbManager.EXTRA_DEVICE);
+            if (device != null) {
+                onDeviceAttached(device);
+            }
+        } else {
+            Map<String, UsbDevice> devices = mUsbManager.getDeviceList();
+            if (devices != null) {
+                for (UsbDevice device : devices.values()) {
+                    onDeviceAttached(device);
+                }
+            }
+        }
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+
+        unregisterReceiver(mReceiver);
+    }
+
+    private void onDeviceAttached(UsbDevice device) {
+        mLogger.log("USB device attached: " + device);
+        if (!mConnected) {
+            connect(device);
+        }
+    }
+
+    private void onDeviceDetached(UsbDevice device) {
+        mLogger.log("USB device detached: " + device);
+        if (mConnected && device.equals(mDevice)) {
+            disconnect();
+        }
+    }
+
+    private void connect(UsbDevice device) {
+        if (mConnected) {
+            disconnect();
+        }
+
+        // Check whether we have permission to access the device.
+        if (!mUsbManager.hasPermission(device)) {
+            mLogger.log("Prompting the user for access to the device.");
+            Intent intent = new Intent(ACTION_USB_DEVICE_PERMISSION);
+            intent.setPackage(getPackageName());
+            PendingIntent pendingIntent = PendingIntent.getBroadcast(
+                    this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
+            mUsbManager.requestPermission(device, pendingIntent);
+            return;
+        }
+
+        // Claim the device.
+        UsbDeviceConnection conn = mUsbManager.openDevice(device);
+        if (conn == null) {
+            mLogger.logError("Could not obtain device connection.");
+            return;
+        }
+        UsbInterface iface = device.getInterface(0);
+        UsbEndpoint controlEndpoint = iface.getEndpoint(0);
+        if (!conn.claimInterface(iface, true)) {
+            mLogger.logError("Could not claim interface.");
+            return;
+        }
+        try {
+            // If already in accessory mode, then connect to the device.
+            if (isAccessory(device)) {
+                mLogger.log("Connecting to accessory...");
+
+                int protocolVersion = getProtocol(conn);
+                if (protocolVersion < 1) {
+                    mLogger.logError("Device does not support accessory protocol.");
+                    return;
+                }
+                mLogger.log("Protocol version: " + protocolVersion);
+
+                // Setup bulk endpoints.
+                UsbEndpoint bulkIn = null;
+                UsbEndpoint bulkOut = null;
+                for (int i = 0; i < iface.getEndpointCount(); i++) {
+                    UsbEndpoint ep = iface.getEndpoint(i);
+                    if (ep.getDirection() == UsbConstants.USB_DIR_IN) {
+                        if (bulkIn == null) {
+                            mLogger.log(String.format("Bulk IN endpoint: %d", i));
+                            bulkIn = ep;
+                        }
+                    } else {
+                        if (bulkOut == null) {
+                            mLogger.log(String.format("Bulk OUT endpoint: %d", i));
+                            bulkOut = ep;
+                        }
+                    }
+                }
+                if (bulkIn == null || bulkOut == null) {
+                    mLogger.logError("Unable to find bulk endpoints");
+                    return;
+                }
+
+                mLogger.log("Connected");
+                mConnected = true;
+                mDevice = device;
+                mProtocolVersion = protocolVersion;
+                mAccessoryInterface = iface;
+                mAccessoryConnection = conn;
+                mControlEndpoint = controlEndpoint;
+                mTransport = new UsbAccessoryBulkTransport(mLogger, conn, bulkIn, bulkOut);
+                if (mProtocolVersion >= 2) {
+                    registerHid();
+                }
+                startServices();
+                mTransport.startReading();
+                return;
+            }
+
+            // Do accessory negotiation.
+            mLogger.log("Attempting to switch device to accessory mode...");
+
+            // Send get protocol.
+            int protocolVersion = getProtocol(conn);
+            if (protocolVersion < 1) {
+                mLogger.logError("Device does not support accessory protocol.");
+                return;
+            }
+            mLogger.log("Protocol version: " + protocolVersion);
+
+            // Send identifying strings.
+            sendString(conn, UsbAccessoryConstants.ACCESSORY_STRING_MANUFACTURER, MANUFACTURER);
+            sendString(conn, UsbAccessoryConstants.ACCESSORY_STRING_MODEL, MODEL);
+            sendString(conn, UsbAccessoryConstants.ACCESSORY_STRING_DESCRIPTION, DESCRIPTION);
+            sendString(conn, UsbAccessoryConstants.ACCESSORY_STRING_VERSION, VERSION);
+            sendString(conn, UsbAccessoryConstants.ACCESSORY_STRING_URI, URI);
+            sendString(conn, UsbAccessoryConstants.ACCESSORY_STRING_SERIAL, SERIAL);
+
+            // Send start.
+            // The device should re-enumerate as an accessory.
+            mLogger.log("Sending accessory start request.");
+            int len = conn.controlTransfer(UsbConstants.USB_DIR_OUT | UsbConstants.USB_TYPE_VENDOR,
+                    UsbAccessoryConstants.ACCESSORY_START, 0, 0, null, 0, 10000);
+            if (len != 0) {
+                mLogger.logError("Device refused to switch to accessory mode.");
+            } else {
+                mLogger.log("Waiting for device to re-enumerate...");
+            }
+        } finally {
+            if (!mConnected) {
+                conn.releaseInterface(iface);
+            }
+        }
+    }
+
+    private void disconnect() {
+        mLogger.log("Disconnecting from device: " + mDevice);
+        stopServices();
+        unregisterHid();
+
+        mLogger.log("Disconnected.");
+        mConnected = false;
+        mDevice = null;
+        mAccessoryConnection = null;
+        mAccessoryInterface = null;
+        mControlEndpoint = null;
+        if (mTransport != null) {
+            mTransport.close();
+            mTransport = null;
+        }
+    }
+
+    private void registerHid() {
+        mLogger.log("Registering HID multitouch device.");
+
+        mMultitouch = new UsbHid.Multitouch(MULTITOUCH_REPORT_ID, MULTITOUCH_MAX_CONTACTS,
+                mSurfaceView.getWidth(), mSurfaceView.getHeight());
+
+        mHidBuffer.clear();
+        mMultitouch.generateDescriptor(mHidBuffer);
+        mHidBuffer.flip();
+
+        mLogger.log("HID descriptor size: " + mHidBuffer.limit());
+        mLogger.log("HID report size: " + mMultitouch.getReportSize());
+
+        final int maxPacketSize = mControlEndpoint.getMaxPacketSize();
+        mLogger.log("Control endpoint max packet size: " + maxPacketSize);
+        if (mMultitouch.getReportSize() > maxPacketSize) {
+            mLogger.logError("HID report is too big for this accessory.");
+            return;
+        }
+
+        int len = mAccessoryConnection.controlTransfer(
+                UsbConstants.USB_DIR_OUT | UsbConstants.USB_TYPE_VENDOR,
+                UsbAccessoryConstants.ACCESSORY_REGISTER_HID,
+                MULTITOUCH_DEVICE_ID, mHidBuffer.limit(), null, 0, 10000);
+        if (len != 0) {
+            mLogger.logError("Device rejected ACCESSORY_REGISTER_HID request.");
+            return;
+        }
+
+        while (mHidBuffer.hasRemaining()) {
+            int position = mHidBuffer.position();
+            int count = Math.min(mHidBuffer.remaining(), maxPacketSize);
+            len = mAccessoryConnection.controlTransfer(
+                    UsbConstants.USB_DIR_OUT | UsbConstants.USB_TYPE_VENDOR,
+                    UsbAccessoryConstants.ACCESSORY_SET_HID_REPORT_DESC,
+                    MULTITOUCH_DEVICE_ID, 0,
+                    mHidBuffer.array(), position, count, 10000);
+            if (len != count) {
+                mLogger.logError("Device rejected ACCESSORY_SET_HID_REPORT_DESC request.");
+                return;
+            }
+            mHidBuffer.position(position + count);
+        }
+
+        mLogger.log("HID device registered.");
+
+        mMultitouchEnabled = true;
+        if (mMultitouchContacts == null) {
+            mMultitouchContacts = new UsbHid.Multitouch.Contact[MULTITOUCH_MAX_CONTACTS];
+            for (int i = 0; i < MULTITOUCH_MAX_CONTACTS; i++) {
+                mMultitouchContacts[i] = new UsbHid.Multitouch.Contact();
+            }
+        }
+    }
+
+    private void unregisterHid() {
+        mMultitouch = null;
+        mMultitouchContacts = null;
+        mMultitouchEnabled = false;
+    }
+
+    private void sendHidTouch(MotionEvent event) {
+        if (mMultitouchEnabled) {
+            mLogger.log("Sending touch event: " + event);
+
+            switch (event.getActionMasked()) {
+                case MotionEvent.ACTION_DOWN:
+                case MotionEvent.ACTION_MOVE: {
+                    final int pointerCount =
+                            Math.min(MULTITOUCH_MAX_CONTACTS, event.getPointerCount());
+                    final int historySize = event.getHistorySize();
+                    for (int p = 0; p < pointerCount; p++) {
+                        mMultitouchContacts[p].id = event.getPointerId(p);
+                    }
+                    for (int h = 0; h < historySize; h++) {
+                        for (int p = 0; p < pointerCount; p++) {
+                            mMultitouchContacts[p].x = (int)event.getHistoricalX(p, h);
+                            mMultitouchContacts[p].y = (int)event.getHistoricalY(p, h);
+                        }
+                        sendHidTouchReport(pointerCount);
+                    }
+                    for (int p = 0; p < pointerCount; p++) {
+                        mMultitouchContacts[p].x = (int)event.getX(p);
+                        mMultitouchContacts[p].y = (int)event.getY(p);
+                    }
+                    sendHidTouchReport(pointerCount);
+                    break;
+                }
+
+                case MotionEvent.ACTION_CANCEL:
+                case MotionEvent.ACTION_UP:
+                    sendHidTouchReport(0);
+                    break;
+            }
+        }
+    }
+
+    private void sendHidTouchReport(int contactCount) {
+        mHidBuffer.clear();
+        mMultitouch.generateReport(mHidBuffer, mMultitouchContacts, contactCount);
+        mHidBuffer.flip();
+
+        int count = mHidBuffer.limit();
+        int len = mAccessoryConnection.controlTransfer(
+                UsbConstants.USB_DIR_OUT | UsbConstants.USB_TYPE_VENDOR,
+                UsbAccessoryConstants.ACCESSORY_SEND_HID_EVENT,
+                MULTITOUCH_DEVICE_ID, 0,
+                mHidBuffer.array(), 0, count, 10000);
+        if (len != count) {
+            mLogger.logError("Device rejected ACCESSORY_SEND_HID_EVENT request.");
+            return;
+        }
+    }
+
+    private void startServices() {
+        mDisplaySinkService = new DisplaySinkService(this, mTransport,
+                getResources().getConfiguration().densityDpi);
+        mDisplaySinkService.start();
+
+        if (mAttached) {
+            mDisplaySinkService.setSurfaceView(mSurfaceView);
+        }
+    }
+
+    private void stopServices() {
+        if (mDisplaySinkService != null) {
+            mDisplaySinkService.stop();
+            mDisplaySinkService = null;
+        }
+    }
+
+    @Override
+    public void onAttachedToWindow() {
+        super.onAttachedToWindow();
+
+        mAttached = true;
+        if (mDisplaySinkService != null) {
+            mDisplaySinkService.setSurfaceView(mSurfaceView);
+        }
+    }
+
+    @Override
+    public void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+
+        mAttached = false;
+        if (mDisplaySinkService != null) {
+            mDisplaySinkService.setSurfaceView(null);
+        }
+    }
+
+    private int getProtocol(UsbDeviceConnection conn) {
+        byte buffer[] = new byte[2];
+        int len = conn.controlTransfer(
+                UsbConstants.USB_DIR_IN | UsbConstants.USB_TYPE_VENDOR,
+                UsbAccessoryConstants.ACCESSORY_GET_PROTOCOL, 0, 0, buffer, 2, 10000);
+        if (len != 2) {
+            return -1;
+        }
+        return (buffer[1] << 8) | buffer[0];
+    }
+
+    private void sendString(UsbDeviceConnection conn, int index, String string) {
+        byte[] buffer = (string + "\0").getBytes();
+        int len = conn.controlTransfer(UsbConstants.USB_DIR_OUT | UsbConstants.USB_TYPE_VENDOR,
+                UsbAccessoryConstants.ACCESSORY_SEND_STRING, 0, index,
+                buffer, buffer.length, 10000);
+        if (len != buffer.length) {
+            mLogger.logError("Failed to send string " + index + ": \"" + string + "\"");
+        } else {
+            mLogger.log("Sent string " + index + ": \"" + string + "\"");
+        }
+    }
+
+    private static boolean isAccessory(UsbDevice device) {
+        final int vid = device.getVendorId();
+        final int pid = device.getProductId();
+        return vid == UsbAccessoryConstants.USB_ACCESSORY_VENDOR_ID
+                && (pid == UsbAccessoryConstants.USB_ACCESSORY_PRODUCT_ID
+                        || pid == UsbAccessoryConstants.USB_ACCESSORY_ADB_PRODUCT_ID);
+    }
+
+    class TextLogger extends Logger {
+        @Override
+        public void log(final String message) {
+            Log.d(TAG, message);
+
+            mLogTextView.post(new Runnable() {
+                @Override
+                public void run() {
+                    mLogTextView.append(message);
+                    mLogTextView.append("\n");
+                }
+            });
+        }
+    }
+
+    class DeviceReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            UsbDevice device = intent.<UsbDevice>getParcelableExtra(UsbManager.EXTRA_DEVICE);
+            if (device != null) {
+                String action = intent.getAction();
+                if (action.equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
+                    onDeviceAttached(device);
+                } else if (action.equals(UsbManager.ACTION_USB_DEVICE_DETACHED)) {
+                    onDeviceDetached(device);
+                } else if (action.equals(ACTION_USB_DEVICE_PERMISSION)) {
+                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
+                        mLogger.log("Device permission granted: " + device);
+                        onDeviceAttached(device);
+                    } else {
+                        mLogger.logError("Device permission denied: " + device);
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/tests/AccessoryDisplay/sink/src/com/android/accessorydisplay/sink/UsbAccessoryBulkTransport.java b/tests/AccessoryDisplay/sink/src/com/android/accessorydisplay/sink/UsbAccessoryBulkTransport.java
new file mode 100644
index 0000000..a15bfad
--- /dev/null
+++ b/tests/AccessoryDisplay/sink/src/com/android/accessorydisplay/sink/UsbAccessoryBulkTransport.java
@@ -0,0 +1,73 @@
+/*
+ * 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.accessorydisplay.sink;
+
+import com.android.accessorydisplay.common.Logger;
+import com.android.accessorydisplay.common.Transport;
+
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbDeviceConnection;
+import android.hardware.usb.UsbEndpoint;
+
+import java.io.IOException;
+
+/**
+ * Sends or receives messages using bulk endpoints associated with a {@link UsbDevice}
+ * that represents a USB accessory.
+ */
+public class UsbAccessoryBulkTransport extends Transport {
+    private static final int TIMEOUT_MILLIS = 1000;
+
+    private UsbDeviceConnection mConnection;
+    private UsbEndpoint mBulkInEndpoint;
+    private UsbEndpoint mBulkOutEndpoint;
+
+    public UsbAccessoryBulkTransport(Logger logger, UsbDeviceConnection connection,
+            UsbEndpoint bulkInEndpoint, UsbEndpoint bulkOutEndpoint) {
+        super(logger, 16384);
+        mConnection = connection;
+        mBulkInEndpoint = bulkInEndpoint;
+        mBulkOutEndpoint = bulkOutEndpoint;
+    }
+
+    @Override
+    protected void ioClose() {
+        mConnection = null;
+        mBulkInEndpoint = null;
+        mBulkOutEndpoint = null;
+    }
+
+    @Override
+    protected int ioRead(byte[] buffer, int offset, int count) throws IOException {
+        if (mConnection == null) {
+            throw new IOException("Connection was closed.");
+        }
+        return mConnection.bulkTransfer(mBulkInEndpoint, buffer, offset, count, -1);
+    }
+
+    @Override
+    protected void ioWrite(byte[] buffer, int offset, int count) throws IOException {
+        if (mConnection == null) {
+            throw new IOException("Connection was closed.");
+        }
+        int result = mConnection.bulkTransfer(mBulkOutEndpoint,
+                buffer, offset, count, TIMEOUT_MILLIS);
+        if (result < 0) {
+            throw new IOException("Bulk transfer failed.");
+        }
+    }
+}
diff --git a/tests/AccessoryDisplay/sink/src/com/android/accessorydisplay/sink/UsbAccessoryConstants.java b/tests/AccessoryDisplay/sink/src/com/android/accessorydisplay/sink/UsbAccessoryConstants.java
new file mode 100644
index 0000000..8197d6b
--- /dev/null
+++ b/tests/AccessoryDisplay/sink/src/com/android/accessorydisplay/sink/UsbAccessoryConstants.java
@@ -0,0 +1,135 @@
+/*
+ * 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.accessorydisplay.sink;
+
+// Constants from kernel include/linux/usb/f_accessory.h
+final class UsbAccessoryConstants {
+    /* Use Google Vendor ID when in accessory mode */
+    public static final int USB_ACCESSORY_VENDOR_ID = 0x18D1;
+
+    /* Product ID to use when in accessory mode */
+    public static final int USB_ACCESSORY_PRODUCT_ID = 0x2D00;
+
+    /* Product ID to use when in accessory mode and adb is enabled */
+    public static final int USB_ACCESSORY_ADB_PRODUCT_ID = 0x2D01;
+
+    /* Indexes for strings sent by the host via ACCESSORY_SEND_STRING */
+    public static final int ACCESSORY_STRING_MANUFACTURER = 0;
+    public static final int ACCESSORY_STRING_MODEL = 1;
+    public static final int ACCESSORY_STRING_DESCRIPTION = 2;
+    public static final int ACCESSORY_STRING_VERSION = 3;
+    public static final int ACCESSORY_STRING_URI = 4;
+    public static final int ACCESSORY_STRING_SERIAL = 5;
+
+    /* Control request for retrieving device's protocol version
+     *
+     *  requestType:    USB_DIR_IN | USB_TYPE_VENDOR
+     *  request:        ACCESSORY_GET_PROTOCOL
+     *  value:          0
+     *  index:          0
+     *  data            version number (16 bits little endian)
+     *                     1 for original accessory support
+     *                     2 adds HID and device to host audio support
+     */
+    public static final int ACCESSORY_GET_PROTOCOL = 51;
+
+    /* Control request for host to send a string to the device
+     *
+     *  requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
+     *  request:        ACCESSORY_SEND_STRING
+     *  value:          0
+     *  index:          string ID
+     *  data            zero terminated UTF8 string
+     *
+     *  The device can later retrieve these strings via the
+     *  ACCESSORY_GET_STRING_* ioctls
+     */
+    public static final int ACCESSORY_SEND_STRING = 52;
+
+    /* Control request for starting device in accessory mode.
+     * The host sends this after setting all its strings to the device.
+     *
+     *  requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
+     *  request:        ACCESSORY_START
+     *  value:          0
+     *  index:          0
+     *  data            none
+     */
+    public static final int ACCESSORY_START = 53;
+
+    /* Control request for registering a HID device.
+     * Upon registering, a unique ID is sent by the accessory in the
+     * value parameter. This ID will be used for future commands for
+     * the device
+     *
+     *  requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
+     *  request:        ACCESSORY_REGISTER_HID_DEVICE
+     *  value:          Accessory assigned ID for the HID device
+     *  index:          total length of the HID report descriptor
+     *  data            none
+     */
+    public static final int ACCESSORY_REGISTER_HID = 54;
+
+    /* Control request for unregistering a HID device.
+     *
+     *  requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
+     *  request:        ACCESSORY_REGISTER_HID
+     *  value:          Accessory assigned ID for the HID device
+     *  index:          0
+     *  data            none
+     */
+    public static final int ACCESSORY_UNREGISTER_HID = 55;
+
+    /* Control request for sending the HID report descriptor.
+     * If the HID descriptor is longer than the endpoint zero max packet size,
+     * the descriptor will be sent in multiple ACCESSORY_SET_HID_REPORT_DESC
+     * commands. The data for the descriptor must be sent sequentially
+     * if multiple packets are needed.
+     *
+     *  requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
+     *  request:        ACCESSORY_SET_HID_REPORT_DESC
+     *  value:          Accessory assigned ID for the HID device
+     *  index:          offset of data in descriptor
+     *                      (needed when HID descriptor is too big for one packet)
+     *  data            the HID report descriptor
+     */
+    public static final int ACCESSORY_SET_HID_REPORT_DESC = 56;
+
+    /* Control request for sending HID events.
+     *
+     *  requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
+     *  request:        ACCESSORY_SEND_HID_EVENT
+     *  value:          Accessory assigned ID for the HID device
+     *  index:          0
+     *  data            the HID report for the event
+     */
+    public static final int ACCESSORY_SEND_HID_EVENT = 57;
+
+    /* Control request for setting the audio mode.
+     *
+     *  requestType:    USB_DIR_OUT | USB_TYPE_VENDOR
+     *  request:        ACCESSORY_SET_AUDIO_MODE
+     *  value:          0 - no audio
+     *                     1 - device to host, 44100 16-bit stereo PCM
+     *  index:          0
+     *  data            none
+     */
+    public static final int ACCESSORY_SET_AUDIO_MODE = 58;
+
+    private UsbAccessoryConstants() {
+    }
+}
diff --git a/tests/AccessoryDisplay/sink/src/com/android/accessorydisplay/sink/UsbHid.java b/tests/AccessoryDisplay/sink/src/com/android/accessorydisplay/sink/UsbHid.java
new file mode 100644
index 0000000..b4fa1fd
--- /dev/null
+++ b/tests/AccessoryDisplay/sink/src/com/android/accessorydisplay/sink/UsbHid.java
@@ -0,0 +1,130 @@
+/*
+ * 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.accessorydisplay.sink;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Helper for creating USB HID descriptors and reports.
+ */
+final class UsbHid {
+    private UsbHid() {
+    }
+
+    /**
+     * Generates basic Windows 7 compatible HID multitouch descriptors and reports
+     * that should be supported by recent versions of the Linux hid-multitouch driver.
+     */
+    public static final class Multitouch {
+        private final int mReportId;
+        private final int mMaxContacts;
+        private final int mWidth;
+        private final int mHeight;
+
+        public Multitouch(int reportId, int maxContacts, int width, int height) {
+            mReportId = reportId;
+            mMaxContacts = maxContacts;
+            mWidth = width;
+            mHeight = height;
+        }
+
+        public void generateDescriptor(ByteBuffer buffer) {
+            buffer.put(new byte[] {
+                0x05, 0x0d,                         // USAGE_PAGE (Digitizers)
+                0x09, 0x04,                         // USAGE (Touch Screen)
+                (byte)0xa1, 0x01,                   // COLLECTION (Application)
+                (byte)0x85, (byte)mReportId,        //   REPORT_ID (Touch)
+                0x09, 0x22,                         //   USAGE (Finger)
+                (byte)0xa1, 0x00,                   //   COLLECTION (Physical)
+                0x09, 0x55,                         //     USAGE (Contact Count Maximum)
+                0x15, 0x00,                         //     LOGICAL_MINIMUM (0)
+                0x25, (byte)mMaxContacts,           //     LOGICAL_MAXIMUM (...)
+                0x75, 0x08,                         //     REPORT_SIZE (8)
+                (byte)0x95, 0x01,                   //     REPORT_COUNT (1)
+                (byte)0xb1, (byte)mMaxContacts,     //     FEATURE (Data,Var,Abs)
+                0x09, 0x54,                         //     USAGE (Contact Count)
+                (byte)0x81, 0x02,                   //     INPUT (Data,Var,Abs)
+            });
+            byte maxXLsb = (byte)(mWidth - 1);
+            byte maxXMsb = (byte)((mWidth - 1) >> 8);
+            byte maxYLsb = (byte)(mHeight - 1);
+            byte maxYMsb = (byte)((mHeight - 1) >> 8);
+            byte[] collection = new byte[] { 
+                0x05, 0x0d,                         //     USAGE_PAGE (Digitizers)
+                0x09, 0x22,                         //     USAGE (Finger)
+                (byte)0xa1, 0x02,                   //     COLLECTION (Logical)
+                0x09, 0x42,                         //       USAGE (Tip Switch)
+                0x15, 0x00,                         //       LOGICAL_MINIMUM (0)
+                0x25, 0x01,                         //       LOGICAL_MAXIMUM (1)
+                0x75, 0x01,                         //       REPORT_SIZE (1)
+                (byte)0x81, 0x02,                   //       INPUT (Data,Var,Abs)
+                0x09, 0x32,                         //       USAGE (In Range)
+                (byte)0x81, 0x02,                   //       INPUT (Data,Var,Abs)
+                0x09, 0x51,                         //       USAGE (Contact Identifier)
+                0x25, 0x3f,                         //       LOGICAL_MAXIMUM (63)
+                0x75, 0x06,                         //       REPORT_SIZE (6)
+                (byte)0x81, 0x02,                   //       INPUT (Data,Var,Abs)
+                0x05, 0x01,                         //       USAGE_PAGE (Generic Desktop)
+                0x09, 0x30,                         //       USAGE (X)
+                0x26, maxXLsb, maxXMsb,             //       LOGICAL_MAXIMUM (...)
+                0x75, 0x10,                         //       REPORT_SIZE (16)
+                (byte)0x81, 0x02,                   //       INPUT (Data,Var,Abs)
+                0x09, 0x31,                         //       USAGE (Y)
+                0x26, maxYLsb, maxYMsb,             //       LOGICAL_MAXIMUM (...)
+                (byte)0x81, 0x02,                   //       INPUT (Data,Var,Abs)
+                (byte)0xc0,                         //     END_COLLECTION
+            };
+            for (int i = 0; i < mMaxContacts; i++) {
+                buffer.put(collection);
+            }
+            buffer.put(new byte[] {
+                (byte)0xc0,                         //   END_COLLECTION
+                (byte)0xc0,                         // END_COLLECTION
+            });
+        }
+
+        public void generateReport(ByteBuffer buffer, Contact[] contacts, int contactCount) {
+            // Report Id
+            buffer.put((byte)mReportId);
+            // Contact Count
+            buffer.put((byte)contactCount);
+
+            for (int i = 0; i < contactCount; i++) {
+                final Contact contact = contacts[i];
+                // Tip Switch, In Range, Contact Identifier
+                buffer.put((byte)((contact.id << 2) | 0x03));
+                // X
+                buffer.put((byte)contact.x).put((byte)(contact.x >> 8));
+                // Y
+                buffer.put((byte)contact.y).put((byte)(contact.y >> 8));
+            }
+            for (int i = contactCount; i < mMaxContacts; i++) {
+                buffer.put((byte)0).put((byte)0).put((byte)0).put((byte)0).put((byte)0);
+            }
+        }
+
+        public int getReportSize() {
+            return 2 + mMaxContacts * 5;
+        }
+
+        public static final class Contact {
+            public int id; // range 0..63
+            public int x;
+            public int y;
+        }
+    }
+}
diff --git a/tests/AccessoryDisplay/source/Android.mk b/tests/AccessoryDisplay/source/Android.mk
new file mode 100644
index 0000000..5d1085d
--- /dev/null
+++ b/tests/AccessoryDisplay/source/Android.mk
@@ -0,0 +1,25 @@
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+# Build the application.
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := AccessoryDisplaySource
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_RESOURCE_DIR = $(LOCAL_PATH)/res
+LOCAL_STATIC_JAVA_LIBRARIES := AccessoryDisplayCommon
+include $(BUILD_PACKAGE)
diff --git a/tests/AccessoryDisplay/source/AndroidManifest.xml b/tests/AccessoryDisplay/source/AndroidManifest.xml
new file mode 100644
index 0000000..d3edcb8
--- /dev/null
+++ b/tests/AccessoryDisplay/source/AndroidManifest.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.accessorydisplay.source" >
+
+    <uses-feature android:name="android.hardware.usb.accessory"/>
+    <uses-sdk android:minSdkVersion="18" />
+
+    <application android:label="@string/app_name"
+            android:icon="@drawable/ic_app"
+            android:hardwareAccelerated="true">
+
+        <activity android:name=".SourceActivity"
+                android:label="@string/app_name"
+                android:theme="@android:style/Theme.Holo">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"/>
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+            <meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
+                    android:resource="@xml/usb_accessory_filter"/>
+        </activity>
+
+    </application>
+</manifest>
diff --git a/tests/AccessoryDisplay/source/res/drawable-hdpi/ic_app.png b/tests/AccessoryDisplay/source/res/drawable-hdpi/ic_app.png
new file mode 100755
index 0000000..66a1984
--- /dev/null
+++ b/tests/AccessoryDisplay/source/res/drawable-hdpi/ic_app.png
Binary files differ
diff --git a/tests/AccessoryDisplay/source/res/drawable-mdpi/ic_app.png b/tests/AccessoryDisplay/source/res/drawable-mdpi/ic_app.png
new file mode 100644
index 0000000..5ae7701
--- /dev/null
+++ b/tests/AccessoryDisplay/source/res/drawable-mdpi/ic_app.png
Binary files differ
diff --git a/tests/AccessoryDisplay/source/res/layout/presentation_content.xml b/tests/AccessoryDisplay/source/res/layout/presentation_content.xml
new file mode 100644
index 0000000..bf9566a
--- /dev/null
+++ b/tests/AccessoryDisplay/source/res/layout/presentation_content.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+    <android.opengl.GLSurfaceView android:id="@+id/surface_view"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent" />
+
+    <Button android:id="@+id/explode_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_centerHorizontal="true"
+            android:layout_alignParentBottom="true"
+            android:text="Explode!" />
+</RelativeLayout>
diff --git a/tests/AccessoryDisplay/source/res/layout/source_activity.xml b/tests/AccessoryDisplay/source/res/layout/source_activity.xml
new file mode 100644
index 0000000..ff2b818
--- /dev/null
+++ b/tests/AccessoryDisplay/source/res/layout/source_activity.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+    <TextView android:id="@+id/logTextView"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent" />
+</LinearLayout>
diff --git a/tests/AccessoryDisplay/source/res/values/strings.xml b/tests/AccessoryDisplay/source/res/values/strings.xml
new file mode 100644
index 0000000..0b488df
--- /dev/null
+++ b/tests/AccessoryDisplay/source/res/values/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name">Accessory Display Source</string>
+</resources>
diff --git a/tests/AccessoryDisplay/source/res/xml/usb_accessory_filter.xml b/tests/AccessoryDisplay/source/res/xml/usb_accessory_filter.xml
new file mode 100644
index 0000000..5313b4e
--- /dev/null
+++ b/tests/AccessoryDisplay/source/res/xml/usb_accessory_filter.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <!-- Match all devices -->
+    <usb-accessory manufacturer="Android" model="Accessory Display" />
+</resources>
diff --git a/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/DisplaySourceService.java b/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/DisplaySourceService.java
new file mode 100644
index 0000000..256f900
--- /dev/null
+++ b/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/DisplaySourceService.java
@@ -0,0 +1,246 @@
+/*
+ * 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.accessorydisplay.source;
+
+import com.android.accessorydisplay.common.Protocol;
+import com.android.accessorydisplay.common.Service;
+import com.android.accessorydisplay.common.Transport;
+
+import android.content.Context;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.VirtualDisplay;
+import android.media.MediaCodec;
+import android.media.MediaCodec.BufferInfo;
+import android.media.MediaCodecInfo;
+import android.media.MediaFormat;
+import android.os.Handler;
+import android.os.Message;
+import android.view.Display;
+import android.view.Surface;
+
+import java.nio.ByteBuffer;
+
+public class DisplaySourceService extends Service {
+    private static final int MSG_DISPATCH_DISPLAY_ADDED = 1;
+    private static final int MSG_DISPATCH_DISPLAY_REMOVED = 2;
+
+    private static final String DISPLAY_NAME = "Accessory Display";
+    private static final int BIT_RATE = 6000000;
+    private static final int FRAME_RATE = 30;
+    private static final int I_FRAME_INTERVAL = 10;
+
+    private final Callbacks mCallbacks;
+    private final ServiceHandler mHandler;
+    private final DisplayManager mDisplayManager;
+
+    private boolean mSinkAvailable;
+    private int mSinkWidth;
+    private int mSinkHeight;
+    private int mSinkDensityDpi;
+
+    private VirtualDisplayThread mVirtualDisplayThread;
+
+    public DisplaySourceService(Context context, Transport transport, Callbacks callbacks) {
+        super(context, transport, Protocol.DisplaySourceService.ID);
+        mCallbacks = callbacks;
+        mHandler = new ServiceHandler();
+        mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
+    }
+
+    @Override
+    public void start() {
+        super.start();
+
+        getLogger().log("Sending MSG_QUERY.");
+        getTransport().sendMessage(Protocol.DisplaySinkService.ID,
+                Protocol.DisplaySinkService.MSG_QUERY, null);
+    }
+
+    @Override
+    public void stop() {
+        super.stop();
+
+        handleSinkNotAvailable();
+    }
+
+    @Override
+    public void onMessageReceived(int service, int what, ByteBuffer content) {
+        switch (what) {
+            case Protocol.DisplaySourceService.MSG_SINK_AVAILABLE: {
+                getLogger().log("Received MSG_SINK_AVAILABLE");
+                if (content.remaining() >= 12) {
+                    final int width = content.getInt();
+                    final int height = content.getInt();
+                    final int densityDpi = content.getInt();
+                    if (width >= 0 && width <= 4096
+                            && height >= 0 && height <= 4096
+                            && densityDpi >= 60 && densityDpi <= 640) {
+                        handleSinkAvailable(width, height, densityDpi);
+                        return;
+                    }
+                }
+                getLogger().log("Receive invalid MSG_SINK_AVAILABLE message.");
+                break;
+            }
+
+            case Protocol.DisplaySourceService.MSG_SINK_NOT_AVAILABLE: {
+                getLogger().log("Received MSG_SINK_NOT_AVAILABLE");
+                handleSinkNotAvailable();
+                break;
+            }
+        }
+    }
+
+    private void handleSinkAvailable(int width, int height, int densityDpi) {
+        if (mSinkAvailable && mSinkWidth == width && mSinkHeight == height
+                && mSinkDensityDpi == densityDpi) {
+            return;
+        }
+
+        getLogger().log("Accessory display sink available: "
+                + "width=" + width + ", height=" + height
+                + ", densityDpi=" + densityDpi);
+        mSinkAvailable = true;
+        mSinkWidth = width;
+        mSinkHeight = height;
+        mSinkDensityDpi = densityDpi;
+        createVirtualDisplay();
+    }
+
+    private void handleSinkNotAvailable() {
+        getLogger().log("Accessory display sink not available.");
+
+        mSinkAvailable = false;
+        mSinkWidth = 0;
+        mSinkHeight = 0;
+        mSinkDensityDpi = 0;
+        releaseVirtualDisplay();
+    }
+
+    private void createVirtualDisplay() {
+        releaseVirtualDisplay();
+
+        mVirtualDisplayThread = new VirtualDisplayThread(
+                mSinkWidth, mSinkHeight, mSinkDensityDpi);
+        mVirtualDisplayThread.start();
+    }
+
+    private void releaseVirtualDisplay() {
+        if (mVirtualDisplayThread != null) {
+            mVirtualDisplayThread.quit();
+            mVirtualDisplayThread = null;
+        }
+    }
+
+    public interface Callbacks {
+        public void onDisplayAdded(Display display);
+        public void onDisplayRemoved(Display display);
+    }
+
+    private final class ServiceHandler extends Handler {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_DISPATCH_DISPLAY_ADDED: {
+                    mCallbacks.onDisplayAdded((Display)msg.obj);
+                    break;
+                }
+
+                case MSG_DISPATCH_DISPLAY_REMOVED: {
+                    mCallbacks.onDisplayRemoved((Display)msg.obj);
+                    break;
+                }
+            }
+        }
+    }
+
+    private final class VirtualDisplayThread extends Thread {
+        private static final int TIMEOUT_USEC = 1000000;
+
+        private final int mWidth;
+        private final int mHeight;
+        private final int mDensityDpi;
+
+        private volatile boolean mQuitting;
+
+        public VirtualDisplayThread(int width, int height, int densityDpi) {
+            mWidth = width;
+            mHeight = height;
+            mDensityDpi = densityDpi;
+        }
+
+        @Override
+        public void run() {
+            MediaFormat format = MediaFormat.createVideoFormat("video/avc", mWidth, mHeight);
+            format.setInteger(MediaFormat.KEY_COLOR_FORMAT,
+                    MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
+            format.setInteger(MediaFormat.KEY_BIT_RATE, BIT_RATE);
+            format.setInteger(MediaFormat.KEY_FRAME_RATE, FRAME_RATE);
+            format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, I_FRAME_INTERVAL);
+
+            MediaCodec codec = MediaCodec.createEncoderByType("video/avc");
+            codec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
+            Surface surface = codec.createInputSurface();
+            codec.start();
+
+            VirtualDisplay virtualDisplay = mDisplayManager.createVirtualDisplay(
+                    DISPLAY_NAME, mWidth, mHeight, mDensityDpi, surface, 0);
+            if (virtualDisplay != null) {
+                mHandler.obtainMessage(MSG_DISPATCH_DISPLAY_ADDED,
+                        virtualDisplay.getDisplay()).sendToTarget();
+
+                stream(codec);
+
+                mHandler.obtainMessage(MSG_DISPATCH_DISPLAY_REMOVED,
+                        virtualDisplay.getDisplay()).sendToTarget();
+                virtualDisplay.release();
+            }
+
+            codec.signalEndOfInputStream();
+            codec.stop();
+        }
+
+        public void quit() {
+            mQuitting = true;
+        }
+
+        private void stream(MediaCodec codec) {
+            BufferInfo info = new BufferInfo();
+            ByteBuffer[] buffers = null;
+            while (!mQuitting) {
+                int index = codec.dequeueOutputBuffer(info, TIMEOUT_USEC);
+                if (index >= 0) {
+                    if (buffers == null) {
+                        buffers = codec.getOutputBuffers();
+                    }
+
+                    ByteBuffer buffer = buffers[index];
+                    buffer.limit(info.offset + info.size);
+                    buffer.position(info.offset);
+
+                    getTransport().sendMessage(Protocol.DisplaySinkService.ID,
+                            Protocol.DisplaySinkService.MSG_CONTENT, buffer);
+                    codec.releaseOutputBuffer(index, false);
+                } else if (index == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
+                    buffers = null;
+                } else if (index == MediaCodec.INFO_TRY_AGAIN_LATER) {
+                    getLogger().log("Codec dequeue buffer timed out.");
+                }
+            }
+        }
+    }
+}
diff --git a/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/SourceActivity.java b/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/SourceActivity.java
new file mode 100644
index 0000000..c59c958
--- /dev/null
+++ b/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/SourceActivity.java
@@ -0,0 +1,257 @@
+/*
+ * 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.accessorydisplay.source;
+
+import com.android.accessorydisplay.common.Logger;
+import com.android.accessorydisplay.source.presentation.DemoPresentation;
+
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.hardware.usb.UsbAccessory;
+import android.hardware.usb.UsbManager;
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+import android.text.method.ScrollingMovementMethod;
+import android.util.Log;
+import android.view.Display;
+import android.widget.TextView;
+
+public class SourceActivity extends Activity {
+    private static final String TAG = "SourceActivity";
+
+    private static final String ACTION_USB_ACCESSORY_PERMISSION =
+            "com.android.accessorydisplay.source.ACTION_USB_ACCESSORY_PERMISSION";
+
+    private static final String MANUFACTURER = "Android";
+    private static final String MODEL = "Accessory Display";
+
+    private UsbManager mUsbManager;
+    private AccessoryReceiver mReceiver;
+    private TextView mLogTextView;
+    private Logger mLogger;
+    private Presenter mPresenter;
+
+    private boolean mConnected;
+    private UsbAccessory mAccessory;
+    private UsbAccessoryStreamTransport mTransport;
+
+    private DisplaySourceService mDisplaySourceService;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mUsbManager = (UsbManager)getSystemService(Context.USB_SERVICE);
+
+        setContentView(R.layout.source_activity);
+
+        mLogTextView = (TextView) findViewById(R.id.logTextView);
+        mLogTextView.setMovementMethod(ScrollingMovementMethod.getInstance());
+        mLogger = new TextLogger();
+        mPresenter = new Presenter();
+
+        mLogger.log("Waiting for accessory display sink to be attached to USB...");
+
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(UsbManager.ACTION_USB_ACCESSORY_ATTACHED);
+        filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
+        filter.addAction(ACTION_USB_ACCESSORY_PERMISSION);
+        mReceiver = new AccessoryReceiver();
+        registerReceiver(mReceiver, filter);
+
+        Intent intent = getIntent();
+        if (intent.getAction().equals(UsbManager.ACTION_USB_ACCESSORY_ATTACHED)) {
+            UsbAccessory accessory =
+                    (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
+            if (accessory != null) {
+                onAccessoryAttached(accessory);
+            }
+        } else {
+            UsbAccessory[] accessories = mUsbManager.getAccessoryList();
+            if (accessories != null) {
+                for (UsbAccessory accessory : accessories) {
+                    onAccessoryAttached(accessory);
+                }
+            }
+        }
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+
+        unregisterReceiver(mReceiver);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        //new DemoPresentation(this, getWindowManager().getDefaultDisplay()).show();
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+    }
+
+    private void onAccessoryAttached(UsbAccessory accessory) {
+        mLogger.log("USB accessory attached: " + accessory);
+        if (!mConnected) {
+            connect(accessory);
+        }
+    }
+
+    private void onAccessoryDetached(UsbAccessory accessory) {
+        mLogger.log("USB accessory detached: " + accessory);
+        if (mConnected && accessory.equals(mAccessory)) {
+            disconnect();
+        }
+    }
+
+    private void connect(UsbAccessory accessory) {
+        if (!isSink(accessory)) {
+            mLogger.log("Not connecting to USB accessory because it is not an accessory display sink: "
+                    + accessory);
+            return;
+        }
+
+        if (mConnected) {
+            disconnect();
+        }
+
+        // Check whether we have permission to access the accessory.
+        if (!mUsbManager.hasPermission(accessory)) {
+            mLogger.log("Prompting the user for access to the accessory.");
+            Intent intent = new Intent(ACTION_USB_ACCESSORY_PERMISSION);
+            intent.setPackage(getPackageName());
+            PendingIntent pendingIntent = PendingIntent.getBroadcast(
+                    this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
+            mUsbManager.requestPermission(accessory, pendingIntent);
+            return;
+        }
+
+        // Open the accessory.
+        ParcelFileDescriptor fd = mUsbManager.openAccessory(accessory);
+        if (fd == null) {
+            mLogger.logError("Could not obtain accessory connection.");
+            return;
+        }
+
+        // All set.
+        mLogger.log("Connected.");
+        mConnected = true;
+        mAccessory = accessory;
+        mTransport = new UsbAccessoryStreamTransport(mLogger, fd);
+        startServices();
+        mTransport.startReading();
+    }
+
+    private void disconnect() {
+        mLogger.log("Disconnecting from accessory: " + mAccessory);
+        stopServices();
+
+        mLogger.log("Disconnected.");
+        mConnected = false;
+        mAccessory = null;
+        if (mTransport != null) {
+            mTransport.close();
+            mTransport = null;
+        }
+    }
+
+    private void startServices() {
+        mDisplaySourceService = new DisplaySourceService(this, mTransport, mPresenter);
+        mDisplaySourceService.start();
+    }
+
+    private void stopServices() {
+        if (mDisplaySourceService != null) {
+            mDisplaySourceService.stop();
+            mDisplaySourceService = null;
+        }
+    }
+
+    private static boolean isSink(UsbAccessory accessory) {
+        return MANUFACTURER.equals(accessory.getManufacturer())
+                && MODEL.equals(accessory.getModel());
+    }
+
+    class TextLogger extends Logger {
+        @Override
+        public void log(final String message) {
+            Log.d(TAG, message);
+
+            mLogTextView.post(new Runnable() {
+                @Override
+                public void run() {
+                    mLogTextView.append(message);
+                    mLogTextView.append("\n");
+                }
+            });
+        }
+    }
+
+    class AccessoryReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            UsbAccessory accessory = intent.<UsbAccessory>getParcelableExtra(
+                    UsbManager.EXTRA_ACCESSORY);
+            if (accessory != null) {
+                String action = intent.getAction();
+                if (action.equals(UsbManager.ACTION_USB_ACCESSORY_ATTACHED)) {
+                    onAccessoryAttached(accessory);
+                } else if (action.equals(UsbManager.ACTION_USB_ACCESSORY_DETACHED)) {
+                    onAccessoryDetached(accessory);
+                } else if (action.equals(ACTION_USB_ACCESSORY_PERMISSION)) {
+                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
+                        mLogger.log("Accessory permission granted: " + accessory);
+                        onAccessoryAttached(accessory);
+                    } else {
+                        mLogger.logError("Accessory permission denied: " + accessory);
+                    }
+                }
+            }
+        }
+    }
+
+    class Presenter implements DisplaySourceService.Callbacks {
+        private DemoPresentation mPresentation;
+
+        @Override
+        public void onDisplayAdded(Display display) {
+            mLogger.log("Accessory display added: " + display);
+
+            mPresentation = new DemoPresentation(SourceActivity.this, display, mLogger);
+            mPresentation.show();
+        }
+
+        @Override
+        public void onDisplayRemoved(Display display) {
+            mLogger.log("Accessory display removed: " + display);
+
+            if (mPresentation != null) {
+                mPresentation.dismiss();
+                mPresentation = null;
+            }
+        }
+    }
+}
diff --git a/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/UsbAccessoryStreamTransport.java b/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/UsbAccessoryStreamTransport.java
new file mode 100644
index 0000000..c28f4359
--- /dev/null
+++ b/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/UsbAccessoryStreamTransport.java
@@ -0,0 +1,70 @@
+/*
+ * 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.accessorydisplay.source;
+
+import com.android.accessorydisplay.common.Logger;
+import com.android.accessorydisplay.common.Transport;
+
+import android.hardware.usb.UsbAccessory;
+import android.os.ParcelFileDescriptor;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ * Sends or receives messages over a file descriptor associated with a {@link UsbAccessory}.
+ */
+public class UsbAccessoryStreamTransport extends Transport {
+    private ParcelFileDescriptor mFd;
+    private FileInputStream mInputStream;
+    private FileOutputStream mOutputStream;
+
+    public UsbAccessoryStreamTransport(Logger logger, ParcelFileDescriptor fd) {
+        super(logger, 16384);
+        mFd = fd;
+        mInputStream = new FileInputStream(fd.getFileDescriptor());
+        mOutputStream = new FileOutputStream(fd.getFileDescriptor());
+    }
+
+    @Override
+    protected void ioClose() {
+        try {
+            mFd.close();
+        } catch (IOException ex) {
+        }
+        mFd = null;
+        mInputStream = null;
+        mOutputStream = null;
+    }
+
+    @Override
+    protected int ioRead(byte[] buffer, int offset, int count) throws IOException {
+        if (mInputStream == null) {
+            throw new IOException("Stream was closed.");
+        }
+        return mInputStream.read(buffer, offset, count);
+    }
+
+    @Override
+    protected void ioWrite(byte[] buffer, int offset, int count) throws IOException {
+        if (mOutputStream == null) {
+            throw new IOException("Stream was closed.");
+        }
+        mOutputStream.write(buffer, offset, count);
+    }
+}
diff --git a/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/presentation/Cube.java b/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/presentation/Cube.java
new file mode 100644
index 0000000..51d8da9
--- /dev/null
+++ b/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/presentation/Cube.java
@@ -0,0 +1,100 @@
+/*
+ * 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.accessorydisplay.source.presentation;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.IntBuffer;
+
+import javax.microedition.khronos.opengles.GL10;
+
+/**
+ * A vertex shaded cube.
+ */
+class Cube
+{
+    public Cube()
+    {
+        int one = 0x10000;
+        int vertices[] = {
+                -one, -one, -one,
+                one, -one, -one,
+                one,  one, -one,
+                -one,  one, -one,
+                -one, -one,  one,
+                one, -one,  one,
+                one,  one,  one,
+                -one,  one,  one,
+        };
+
+        int colors[] = {
+                0,    0,    0,  one,
+                one,    0,    0,  one,
+                one,  one,    0,  one,
+                0,  one,    0,  one,
+                0,    0,  one,  one,
+                one,    0,  one,  one,
+                one,  one,  one,  one,
+                0,  one,  one,  one,
+        };
+
+        byte indices[] = {
+                0, 4, 5,    0, 5, 1,
+                1, 5, 6,    1, 6, 2,
+                2, 6, 7,    2, 7, 3,
+                3, 7, 4,    3, 4, 0,
+                4, 7, 6,    4, 6, 5,
+                3, 0, 1,    3, 1, 2
+        };
+
+        // Buffers to be passed to gl*Pointer() functions
+        // must be direct, i.e., they must be placed on the
+        // native heap where the garbage collector cannot
+        // move them.
+        //
+        // Buffers with multi-byte datatypes (e.g., short, int, float)
+        // must have their byte order set to native order
+
+        ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
+        vbb.order(ByteOrder.nativeOrder());
+        mVertexBuffer = vbb.asIntBuffer();
+        mVertexBuffer.put(vertices);
+        mVertexBuffer.position(0);
+
+        ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length*4);
+        cbb.order(ByteOrder.nativeOrder());
+        mColorBuffer = cbb.asIntBuffer();
+        mColorBuffer.put(colors);
+        mColorBuffer.position(0);
+
+        mIndexBuffer = ByteBuffer.allocateDirect(indices.length);
+        mIndexBuffer.put(indices);
+        mIndexBuffer.position(0);
+    }
+
+    public void draw(GL10 gl)
+    {
+        gl.glFrontFace(GL10.GL_CW);
+        gl.glVertexPointer(3, GL10.GL_FIXED, 0, mVertexBuffer);
+        gl.glColorPointer(4, GL10.GL_FIXED, 0, mColorBuffer);
+        gl.glDrawElements(GL10.GL_TRIANGLES, 36, GL10.GL_UNSIGNED_BYTE, mIndexBuffer);
+    }
+
+    private IntBuffer   mVertexBuffer;
+    private IntBuffer   mColorBuffer;
+    private ByteBuffer  mIndexBuffer;
+}
diff --git a/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/presentation/CubeRenderer.java b/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/presentation/CubeRenderer.java
new file mode 100644
index 0000000..51dc82a
--- /dev/null
+++ b/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/presentation/CubeRenderer.java
@@ -0,0 +1,124 @@
+/*
+ * 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.accessorydisplay.source.presentation;
+
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.opengl.GLSurfaceView;
+
+/**
+ * Render a pair of tumbling cubes.
+ */
+
+public class CubeRenderer implements GLSurfaceView.Renderer {
+    private boolean mTranslucentBackground;
+    private Cube mCube;
+    private float mAngle;
+    private float mScale = 1.0f;
+    private boolean mExploding;
+
+    public CubeRenderer(boolean useTranslucentBackground) {
+        mTranslucentBackground = useTranslucentBackground;
+        mCube = new Cube();
+    }
+
+    public void explode() {
+        mExploding = true;
+    }
+
+    public void onDrawFrame(GL10 gl) {
+        /*
+         * Usually, the first thing one might want to do is to clear
+         * the screen. The most efficient way of doing this is to use
+         * glClear().
+         */
+
+        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
+
+        /*
+         * Now we're ready to draw some 3D objects
+         */
+
+        gl.glMatrixMode(GL10.GL_MODELVIEW);
+        gl.glLoadIdentity();
+        gl.glTranslatef(0, 0, -3.0f);
+        gl.glRotatef(mAngle,        0, 1, 0);
+        gl.glRotatef(mAngle*0.25f,  1, 0, 0);
+
+        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
+        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
+
+        gl.glScalef(mScale, mScale, mScale);
+        mCube.draw(gl);
+
+        gl.glRotatef(mAngle*2.0f, 0, 1, 1);
+        gl.glTranslatef(0.5f, 0.5f, 0.5f);
+
+        mCube.draw(gl);
+
+        mAngle += 1.2f;
+
+        if (mExploding) {
+            mScale *= 1.02f;
+            if (mScale > 4.0f) {
+                mScale = 1.0f;
+                mExploding = false;
+            }
+        }
+    }
+
+    public void onSurfaceChanged(GL10 gl, int width, int height) {
+         gl.glViewport(0, 0, width, height);
+
+         /*
+          * Set our projection matrix. This doesn't have to be done
+          * each time we draw, but usually a new projection needs to
+          * be set when the viewport is resized.
+          */
+
+         float ratio = (float) width / height;
+         gl.glMatrixMode(GL10.GL_PROJECTION);
+         gl.glLoadIdentity();
+         gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
+    }
+
+    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+        /*
+         * By default, OpenGL enables features that improve quality
+         * but reduce performance. One might want to tweak that
+         * especially on software renderer.
+         */
+        gl.glDisable(GL10.GL_DITHER);
+
+        /*
+         * Some one-time OpenGL initialization can be made here
+         * probably based on features of this particular context
+         */
+         gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
+                 GL10.GL_FASTEST);
+
+         if (mTranslucentBackground) {
+             gl.glClearColor(0,0,0,0);
+         } else {
+             gl.glClearColor(1,1,1,1);
+         }
+         gl.glEnable(GL10.GL_CULL_FACE);
+         gl.glShadeModel(GL10.GL_SMOOTH);
+         gl.glEnable(GL10.GL_DEPTH_TEST);
+    }
+}
diff --git a/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/presentation/DemoPresentation.java b/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/presentation/DemoPresentation.java
new file mode 100644
index 0000000..517b7fc
--- /dev/null
+++ b/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/presentation/DemoPresentation.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 com.android.accessorydisplay.source.presentation;
+
+import com.android.accessorydisplay.common.Logger;
+import com.android.accessorydisplay.source.R;
+
+import android.app.Presentation;
+import android.content.Context;
+import android.content.res.Resources;
+import android.opengl.GLSurfaceView;
+import android.os.Bundle;
+import android.view.Display;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.Button;
+
+/**
+ * The presentation to show on the accessory display.
+ * <p>
+ * Note that this display may have different metrics from the display on which
+ * the main activity is showing so we must be careful to use the presentation's
+ * own {@link Context} whenever we load resources.
+ * </p>
+ */
+public final class DemoPresentation extends Presentation {
+    private final Logger mLogger;
+
+    private GLSurfaceView mSurfaceView;
+    private CubeRenderer mRenderer;
+    private Button mExplodeButton;
+
+    public DemoPresentation(Context context, Display display, Logger logger) {
+        super(context, display);
+        mLogger = logger;
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        // Be sure to call the super class.
+        super.onCreate(savedInstanceState);
+
+        // Get the resources for the context of the presentation.
+        // Notice that we are getting the resources from the context of the presentation.
+        Resources r = getContext().getResources();
+
+        // Inflate the layout.
+        setContentView(R.layout.presentation_content);
+
+        // Set up the surface view for visual interest.
+        mRenderer = new CubeRenderer(false);
+        mSurfaceView = (GLSurfaceView)findViewById(R.id.surface_view);
+        mSurfaceView.setRenderer(mRenderer);
+
+        // Add a button.
+        mExplodeButton = (Button)findViewById(R.id.explode_button);
+        mExplodeButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                mRenderer.explode();
+            }
+        });
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        mLogger.log("Received touch event: " + event);
+        return super.onTouchEvent(event);
+    }
+}
\ No newline at end of file
diff --git a/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java b/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java
index c7cd975..d7a6c1d 100644
--- a/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java
+++ b/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java
@@ -182,7 +182,7 @@
         menu.add("Send!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
             @Override public boolean onMenuItemClick(MenuItem item) {
                 Intent intent = new Intent(ActivityTestMain.this, SingleUserReceiver.class);
-                sendOrderedBroadcast(intent, null, new BroadcastResultReceiver(), 
+                sendOrderedBroadcast(intent, null, new BroadcastResultReceiver(),
                         null, Activity.RESULT_OK, null, null);
                 return true;
             }
@@ -285,6 +285,12 @@
                 return true;
             }
         });
+        menu.add("HashArray").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
+            @Override public boolean onMenuItemClick(MenuItem item) {
+                ArrayMapTests.run();
+                return true;
+            }
+        });
         return true;
     }
 
diff --git a/tests/ActivityTests/src/com/google/android/test/activity/ArrayMapTests.java b/tests/ActivityTests/src/com/google/android/test/activity/ArrayMapTests.java
new file mode 100644
index 0000000..4ad6dc7
--- /dev/null
+++ b/tests/ActivityTests/src/com/google/android/test/activity/ArrayMapTests.java
@@ -0,0 +1,532 @@
+/*
+ * 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.google.android.test.activity;
+
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.Log;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+public class ArrayMapTests {
+    static final int OP_ADD = 1;
+    static final int OP_REM = 2;
+
+    static int[] OPS = new int[] {
+            OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD,
+            OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD,
+            OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM,
+            OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM,
+
+            OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD,
+            OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM,
+
+            OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD,
+            OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM,
+
+            OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD,
+            OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM,
+
+            OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD,
+            OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD,
+            OP_ADD, OP_ADD, OP_ADD,
+            OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM,
+            OP_REM, OP_REM, OP_REM,
+            OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM,
+    };
+
+    static int[] KEYS = new int[] {
+            // General adding and removing.
+             -1,    1900,    600,    200,   1200,   1500,   1800,    100,   1900,
+            2100,    300,    800,    600,   1100,   1300,   2000,   1000,   1400,
+             600,    -1,    1900,    600,    300,   2100,    200,    800,    800,
+            1800,   1500,   1300,   1100,   2000,   1400,   1000,   1200,   1900,
+
+            // Shrink when removing item from end.
+             100,    200,    300,    400,    500,    600,    700,    800,    900,
+             900,    800,    700,    600,    500,    400,    300,    200,    100,
+
+            // Shrink when removing item from middle.
+             100,    200,    300,    400,    500,    600,    700,    800,    900,
+             900,    800,    700,    600,    500,    400,    200,    300,    100,
+
+            // Shrink when removing item from front.
+             100,    200,    300,    400,    500,    600,    700,    800,    900,
+             900,    800,    700,    600,    500,    400,    100,    200,    300,
+
+            // Test hash collisions.
+             105,    106,    108,    104,    102,    102,    107,      5,    205,
+               4,    202,    203,      3,      5,    101,    109,    200,    201,
+               0,     -1,    100,
+             106,    108,    104,    102,    103,    105,    107,    101,    109,
+              -1,    100,      0,
+               4,      5,      3,      5,    200,    203,    202,    201,    205,
+    };
+
+    static class ControlledHash {
+        final int mValue;
+
+        ControlledHash(int value) {
+            mValue = value;
+        }
+
+        @Override
+        public final boolean equals(Object o) {
+            if (o == null) {
+                return false;
+            }
+            return mValue == ((ControlledHash)o).mValue;
+        }
+
+        @Override
+        public final int hashCode() {
+            return mValue/100;
+        }
+
+        @Override
+        public final String toString() {
+            return Integer.toString(mValue);
+        }
+    }
+
+    private static boolean compare(Object v1, Object v2) {
+        if (v1 == null) {
+            return v2 == null;
+        }
+        if (v2 == null) {
+            return false;
+        }
+        return v1.equals(v2);
+    }
+
+    private static boolean compareMaps(HashMap map, ArrayMap array) {
+        if (map.size() != array.size()) {
+            Log.e("test", "Bad size: expected " + map.size() + ", got " + array.size());
+            return false;
+        }
+
+        Set<Map.Entry> mapSet = map.entrySet();
+        for (Map.Entry entry : mapSet) {
+            Object expValue = entry.getValue();
+            Object gotValue = array.get(entry.getKey());
+            if (!compare(expValue, gotValue)) {
+                Log.e("test", "Bad value: expected " + expValue + ", got " + gotValue
+                        + " at key " + entry.getKey());
+                return false;
+            }
+        }
+
+        for (int i=0; i<array.size(); i++) {
+            Object gotValue = array.valueAt(i);
+            Object key = array.keyAt(i);
+            Object expValue = map.get(key);
+            if (!compare(expValue, gotValue)) {
+                Log.e("test", "Bad value: expected " + expValue + ", got " + gotValue
+                        + " at key " + key);
+                return false;
+            }
+        }
+
+        if (map.entrySet().hashCode() != array.entrySet().hashCode()) {
+            Log.e("test", "Entry set hash codes differ: map=0x"
+                    + Integer.toHexString(map.entrySet().hashCode()) + " array=0x"
+                    + Integer.toHexString(array.entrySet().hashCode()));
+            return false;
+        }
+
+        if (!map.entrySet().equals(array.entrySet())) {
+            Log.e("test", "Failed calling equals on map entry set against array set");
+            return false;
+        }
+
+        if (!array.entrySet().equals(map.entrySet())) {
+            Log.e("test", "Failed calling equals on array entry set against map set");
+            return false;
+        }
+
+        if (map.keySet().hashCode() != array.keySet().hashCode()) {
+            Log.e("test", "Key set hash codes differ: map=0x"
+                    + Integer.toHexString(map.keySet().hashCode()) + " array=0x"
+                    + Integer.toHexString(array.keySet().hashCode()));
+            return false;
+        }
+
+        if (!map.keySet().equals(array.keySet())) {
+            Log.e("test", "Failed calling equals on map key set against array set");
+            return false;
+        }
+
+        if (!array.keySet().equals(map.keySet())) {
+            Log.e("test", "Failed calling equals on array key set against map set");
+            return false;
+        }
+
+        if (!map.keySet().containsAll(array.keySet())) {
+            Log.e("test", "Failed map key set contains all of array key set");
+            return false;
+        }
+
+        if (!array.keySet().containsAll(map.keySet())) {
+            Log.e("test", "Failed array key set contains all of map key set");
+            return false;
+        }
+
+        if (!array.containsAll(map.keySet())) {
+            Log.e("test", "Failed array contains all of map key set");
+            return false;
+        }
+
+        if (!map.entrySet().containsAll(array.entrySet())) {
+            Log.e("test", "Failed map entry set contains all of array entry set");
+            return false;
+        }
+
+        if (!array.entrySet().containsAll(map.entrySet())) {
+            Log.e("test", "Failed array entry set contains all of map entry set");
+            return false;
+        }
+
+        return true;
+    }
+
+    private static boolean compareSets(HashSet set, ArraySet array) {
+        if (set.size() != array.size()) {
+            Log.e("test", "Bad size: expected " + set.size() + ", got " + array.size());
+            return false;
+        }
+
+        for (Object entry : set) {
+            if (!array.contains(entry)) {
+                Log.e("test", "Bad value: expected " + entry + " not found in ArraySet");
+                return false;
+            }
+        }
+
+        for (int i=0; i<array.size(); i++) {
+            Object entry = array.valueAt(i);
+            if (!set.contains(entry)) {
+                Log.e("test", "Bad value: unexpected " + entry + " in ArraySet");
+                return false;
+            }
+        }
+
+        int index = 0;
+        for (Object entry : array) {
+            Object realEntry = array.valueAt(index);
+            if (!compare(entry, realEntry)) {
+                Log.e("test", "Bad iterator: expected value " + realEntry + ", got " + entry
+                        + " at index " + index);
+                return false;
+            }
+            index++;
+        }
+
+        return true;
+    }
+
+    private static boolean validateArrayMap(ArrayMap array) {
+        Set<Map.Entry> entrySet = array.entrySet();
+        int index=0;
+        Iterator<Map.Entry> entryIt = entrySet.iterator();
+        while (entryIt.hasNext()) {
+            Map.Entry entry = entryIt.next();
+            Object value = entry.getKey();
+            Object realValue = array.keyAt(index);
+            if (!compare(realValue, value)) {
+                Log.e("test", "Bad array map entry set: expected key " + realValue
+                        + ", got " + value + " at index " + index);
+                return false;
+            }
+            value = entry.getValue();
+            realValue = array.valueAt(index);
+            if (!compare(realValue, value)) {
+                Log.e("test", "Bad array map entry set: expected value " + realValue
+                        + ", got " + value + " at index " + index);
+                return false;
+            }
+            index++;
+        }
+
+        index = 0;
+        Set keySet = array.keySet();
+        Iterator keyIt = keySet.iterator();
+        while (keyIt.hasNext()) {
+            Object value = keyIt.next();
+            Object realValue = array.keyAt(index);
+            if (!compare(realValue, value)) {
+                Log.e("test", "Bad array map key set: expected key " + realValue
+                        + ", got " + value + " at index " + index);
+                return false;
+            }
+            index++;
+        }
+
+        index = 0;
+        Collection valueCol = array.values();
+        Iterator valueIt = valueCol.iterator();
+        while (valueIt.hasNext()) {
+            Object value = valueIt.next();
+            Object realValue = array.valueAt(index);
+            if (!compare(realValue, value)) {
+                Log.e("test", "Bad array map value col: expected value " + realValue
+                        + ", got " + value + " at index " + index);
+                return false;
+            }
+            index++;
+        }
+
+        return true;
+    }
+
+    private static void dump(Map map, ArrayMap array) {
+        Log.e("test", "HashMap of " + map.size() + " entries:");
+        Set<Map.Entry> mapSet = map.entrySet();
+        for (Map.Entry entry : mapSet) {
+            Log.e("test", "    " + entry.getKey() + " -> " + entry.getValue());
+        }
+        Log.e("test", "ArrayMap of " + array.size() + " entries:");
+        for (int i=0; i<array.size(); i++) {
+            Log.e("test", "    " + array.keyAt(i) + " -> " + array.valueAt(i));
+        }
+    }
+
+    private static void dump(Set set, ArraySet array) {
+        Log.e("test", "HashSet of " + set.size() + " entries:");
+        for (Object entry : set) {
+            Log.e("test", "    " + entry);
+        }
+        Log.e("test", "ArraySet of " + array.size() + " entries:");
+        for (int i=0; i<array.size(); i++) {
+            Log.e("test", "    " + array.valueAt(i));
+        }
+    }
+
+    private static void dump(ArrayMap map1, ArrayMap map2) {
+        Log.e("test", "ArrayMap of " + map1.size() + " entries:");
+        Set<Map.Entry> mapSet = map1.entrySet();
+        for (int i=0; i<map2.size(); i++) {
+            Log.e("test", "    " + map1.keyAt(i) + " -> " + map1.valueAt(i));
+        }
+        Log.e("test", "ArrayMap of " + map2.size() + " entries:");
+        for (int i=0; i<map2.size(); i++) {
+            Log.e("test", "    " + map2.keyAt(i) + " -> " + map2.valueAt(i));
+        }
+    }
+
+    public static void run() {
+        HashMap<ControlledHash, Integer> hashMap = new HashMap<ControlledHash, Integer>();
+        ArrayMap<ControlledHash, Integer> arrayMap = new ArrayMap<ControlledHash, Integer>();
+        HashSet<ControlledHash> hashSet = new HashSet<ControlledHash>();
+        ArraySet<ControlledHash> arraySet = new ArraySet<ControlledHash>();
+
+        for (int i=0; i<OPS.length; i++) {
+            Integer oldHash;
+            Integer oldArray;
+            boolean hashChanged;
+            boolean arrayChanged;
+            ControlledHash key = KEYS[i] < 0 ? null : new ControlledHash(KEYS[i]);
+            switch (OPS[i]) {
+                case OP_ADD:
+                    Log.i("test", "Adding key: " + KEYS[i]);
+                    oldHash = hashMap.put(key, i);
+                    oldArray = arrayMap.put(key, i);
+                    hashChanged = hashSet.add(key);
+                    arrayChanged = arraySet.add(key);
+                    break;
+                case OP_REM:
+                    Log.i("test", "Removing key: " + KEYS[i]);
+                    oldHash = hashMap.remove(key);
+                    oldArray = arrayMap.remove(key);
+                    hashChanged = hashSet.remove(key);
+                    arrayChanged = arraySet.remove(key);
+                    break;
+                default:
+                    Log.e("test", "Bad operation " + OPS[i] + " @ " + i);
+                    return;
+            }
+            if (!compare(oldHash, oldArray)) {
+                Log.e("test", "Bad result: expected " + oldHash + ", got " + oldArray);
+                dump(hashMap, arrayMap);
+                return;
+            }
+            if (hashChanged != arrayChanged) {
+                Log.e("test", "Bad change: expected " + hashChanged + ", got " + arrayChanged);
+                dump(hashSet, arraySet);
+                return;
+            }
+            if (!validateArrayMap(arrayMap)) {
+                dump(hashMap, arrayMap);
+                return;
+            }
+            if (!compareMaps(hashMap, arrayMap)) {
+                dump(hashMap, arrayMap);
+                return;
+            }
+            if (!compareSets(hashSet, arraySet)) {
+                dump(hashSet, arraySet);
+                return;
+            }
+        }
+
+        arrayMap.put(new ControlledHash(50000), 100);
+        ControlledHash lookup = new ControlledHash(50000);
+        Iterator<ControlledHash> it = arrayMap.keySet().iterator();
+        while (it.hasNext()) {
+            if (it.next().equals(lookup)) {
+                it.remove();
+            }
+        }
+        if (arrayMap.containsKey(lookup)) {
+            Log.e("test", "Bad map iterator: didn't remove test key");
+            dump(hashMap, arrayMap);
+        }
+
+        arraySet.add(new ControlledHash(50000));
+        it = arraySet.iterator();
+        while (it.hasNext()) {
+            if (it.next().equals(lookup)) {
+                it.remove();
+            }
+        }
+        if (arraySet.contains(lookup)) {
+            Log.e("test", "Bad set iterator: didn't remove test key");
+            dump(hashSet, arraySet);
+        }
+
+        if (!equalsMapTest()) {
+            return;
+        }
+
+        if (!equalsSetTest()) {
+            return;
+        }
+
+        // map copy constructor test
+        ArrayMap newMap = new ArrayMap<Integer, String>();
+        for (int i = 0; i < 10; ++i) {
+            newMap.put(i, String.valueOf(i));
+        }
+        ArrayMap mapCopy = new ArrayMap(newMap);
+        if (!compare(mapCopy, newMap)) {
+            Log.e("test", "ArrayMap copy constructor failure: expected " +
+                    newMap + ", got " + mapCopy);
+            dump(newMap, mapCopy);
+            return;
+        }
+
+        // set copy constructor test
+        ArraySet newSet = new ArraySet<Integer>();
+        for (int i = 0; i < 10; ++i) {
+            newSet.add(i);
+        }
+        ArraySet setCopy = new ArraySet(newSet);
+        if (!compare(setCopy, newSet)) {
+            Log.e("test", "ArraySet copy constructor failure: expected " +
+                    newSet + ", got " + setCopy);
+            dump(newSet, setCopy);
+            return;
+        }
+
+        Log.e("test", "Test successful; printing final map.");
+        dump(hashMap, arrayMap);
+
+        Log.e("test", "Test successful; printing final set.");
+        dump(hashSet, arraySet);
+    }
+
+    private static boolean equalsMapTest() {
+        ArrayMap<Integer, String> map1 = new ArrayMap<Integer, String>();
+        ArrayMap<Integer, String> map2 = new ArrayMap<Integer, String>();
+        HashMap<Integer, String> map3 = new HashMap<Integer, String>();
+        if (!compare(map1, map2) || !compare(map1, map3) || !compare(map3, map2)) {
+            Log.e("test", "ArrayMap equals failure for empty maps " + map1 + ", " +
+                    map2 + ", " + map3);
+            return false;
+        }
+
+        for (int i = 0; i < 10; ++i) {
+            String value = String.valueOf(i);
+            map1.put(i, value);
+            map2.put(i, value);
+            map3.put(i, value);
+        }
+        if (!compare(map1, map2) || !compare(map1, map3) || !compare(map3, map2)) {
+            Log.e("test", "ArrayMap equals failure for populated maps " + map1 + ", " +
+                    map2 + ", " + map3);
+            return false;
+        }
+
+        map1.remove(0);
+        if (compare(map1, map2) || compare(map1, map3) || compare(map3, map1)) {
+            Log.e("test", "ArrayMap equals failure for map size " + map1 + ", " +
+                    map2 + ", " + map3);
+            return false;
+        }
+
+        map1.put(0, "-1");
+        if (compare(map1, map2) || compare(map1, map3) || compare(map3, map1)) {
+            Log.e("test", "ArrayMap equals failure for map contents " + map1 + ", " +
+                    map2 + ", " + map3);
+            return false;
+        }
+
+        return true;
+    }
+
+    private static boolean equalsSetTest() {
+        ArraySet<Integer> set1 = new ArraySet<Integer>();
+        ArraySet<Integer> set2 = new ArraySet<Integer>();
+        HashSet<Integer> set3 = new HashSet<Integer>();
+        if (!compare(set1, set2) || !compare(set1, set3) || !compare(set3, set2)) {
+            Log.e("test", "ArraySet equals failure for empty sets " + set1 + ", " +
+                    set2 + ", " + set3);
+            return false;
+        }
+
+        for (int i = 0; i < 10; ++i) {
+            set1.add(i);
+            set2.add(i);
+            set3.add(i);
+        }
+        if (!compare(set1, set2) || !compare(set1, set3) || !compare(set3, set2)) {
+            Log.e("test", "ArraySet equals failure for populated sets " + set1 + ", " +
+                    set2 + ", " + set3);
+            return false;
+        }
+
+        set1.remove(0);
+        if (compare(set1, set2) || compare(set1, set3) || compare(set3, set1)) {
+            Log.e("test", "ArraSet equals failure for set size " + set1 + ", " +
+                    set2 + ", " + set3);
+            return false;
+        }
+
+        set1.add(-1);
+        if (compare(set1, set2) || compare(set1, set3) || compare(set3, set1)) {
+            Log.e("test", "ArraySet equals failure for set contents " + set1 + ", " +
+                    set2 + ", " + set3);
+            return false;
+        }
+
+        return true;
+    }
+}
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/DisplayModifier.java b/tests/CanvasCompare/src/com/android/test/hwuicompare/DisplayModifier.java
index 9939c08..6ad01a0 100644
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/DisplayModifier.java
+++ b/tests/CanvasCompare/src/com/android/test/hwuicompare/DisplayModifier.java
@@ -224,7 +224,7 @@
                     put("rotate45", new DisplayModifier() {
                         @Override
                         public void modifyDrawing(Paint paint, Canvas canvas) {
-                            canvas.rotate(5);
+                            canvas.rotate(45);
                         }
                     });
                     put("rotate90", new DisplayModifier() {
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/ManualActivity.java b/tests/CanvasCompare/src/com/android/test/hwuicompare/ManualActivity.java
index 400dff0..405ff65 100644
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/ManualActivity.java
+++ b/tests/CanvasCompare/src/com/android/test/hwuicompare/ManualActivity.java
@@ -82,6 +82,7 @@
                         mCompareImageView.setImageBitmap(mCompareBitmap);
                         break;
                 }
+                mCompareImageView.getDrawable().setFilterBitmap(false);
                 mCompareImageView.invalidate();
             }
 
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/errorCalculator.rs b/tests/CanvasCompare/src/com/android/test/hwuicompare/errorCalculator.rs
index 668f61d..3681784 100644
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/errorCalculator.rs
+++ b/tests/CanvasCompare/src/com/android/test/hwuicompare/errorCalculator.rs
@@ -49,8 +49,8 @@
     float4 diff = idealPixel - givenPixel;
     float totalDiff = diff.x + diff.y + diff.z + diff.w;
     if (totalDiff < 0) {
-        v_out[0] = rsPackColorTo8888(0, 0, clamp(-totalDiff/2, 0, 1));
+        v_out[0] = rsPackColorTo8888(0, 0, clamp(-totalDiff/2.f, 0.f, 1.f));
     } else {
-        v_out[0] = rsPackColorTo8888(clamp(totalDiff/2, 0, 1), 0, 0);
+        v_out[0] = rsPackColorTo8888(clamp(totalDiff/2.f, 0.f, 1.f), 0, 0);
     }
 }
diff --git a/tests/DumpRenderTree/Android.mk b/tests/DumpRenderTree/Android.mk
deleted file mode 100644
index 505a436..0000000
--- a/tests/DumpRenderTree/Android.mk
+++ /dev/null
@@ -1,12 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-LOCAL_PACKAGE_NAME := DumpRenderTree
-
-include $(BUILD_PACKAGE)
diff --git a/tests/DumpRenderTree/AndroidManifest.xml b/tests/DumpRenderTree/AndroidManifest.xml
deleted file mode 100644
index bcb821b..0000000
--- a/tests/DumpRenderTree/AndroidManifest.xml
+++ /dev/null
@@ -1,46 +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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.dumprendertree">
-    <application android:name="HTMLHostApp">
-        <uses-library android:name="android.test.runner" />
-        <activity android:name="Menu" android:label="Dump Render Tree"
-          android:screenOrientation="portrait"
-          android:theme="@android:style/Theme.Light">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.TEST" />
-            </intent-filter>
-        </activity>
-        <activity android:name="TestShellActivity"
-          android:launchMode="singleTop"
-          android:hardwareAccelerated="true"
-          android:screenOrientation="portrait"
-          android:theme="@android:style/Theme.Light"/>
-        <activity android:name="ReliabilityTestActivity" android:screenOrientation="portrait"
-          android:theme="@android:style/Theme.Light"/>
-    </application>
-
-    <instrumentation android:name=".LayoutTestsAutoRunner"
-        android:targetPackage="com.android.dumprendertree"
-        android:label="Layout test automation runner"
-    />
-    <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.WRITE_SDCARD" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-    <uses-sdk android:minSdkVersion="5"
-              android:targetSdkVersion="5" />
-</manifest>
diff --git a/tests/DumpRenderTree/assets/results/layout_tests_crashed.txt b/tests/DumpRenderTree/assets/results/layout_tests_crashed.txt
deleted file mode 100644
index 89439d3..0000000
--- a/tests/DumpRenderTree/assets/results/layout_tests_crashed.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/basic-auth.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/failed-auth.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/cross-origin-authorization.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/cross-origin-no-authorization.html
diff --git a/tests/DumpRenderTree/assets/results/layout_tests_failed.txt b/tests/DumpRenderTree/assets/results/layout_tests_failed.txt
deleted file mode 100644
index 5b64b9a..0000000
--- a/tests/DumpRenderTree/assets/results/layout_tests_failed.txt
+++ /dev/null
@@ -1,1010 +0,0 @@
-/sdcard/android/layout_tests/accessibility/onclick-handlers.html
-/sdcard/android/layout_tests/accessibility/textarea-insertion-point-line-number.html
-/sdcard/android/layout_tests/accessibility/aria-readonly.html
-/sdcard/android/layout_tests/accessibility/radio-button-checkbox-size.html
-/sdcard/android/layout_tests/accessibility/th-as-title-ui.html
-/sdcard/android/layout_tests/accessibility/visible-elements.html
-/sdcard/android/layout_tests/accessibility/iframe-bastardization.html
-/sdcard/android/layout_tests/accessibility/button-press-action.html
-/sdcard/android/layout_tests/accessibility/img-aria-button-alt-tag.html
-/sdcard/android/layout_tests/accessibility/input-image-alt.html
-/sdcard/android/layout_tests/accessibility/radio-button-title-label.html
-/sdcard/android/layout_tests/accessibility/aria-hidden.html
-/sdcard/android/layout_tests/accessibility/secure-textfield-title-ui.html
-/sdcard/android/layout_tests/accessibility/canvas.html
-/sdcard/android/layout_tests/accessibility/textarea-selected-text-range.html
-/sdcard/android/layout_tests/accessibility/language-attribute.html
-/sdcard/android/layout_tests/accessibility/table-nofirstbody.html
-/sdcard/android/layout_tests/accessibility/editable-webarea-context-menu-point.html
-/sdcard/android/layout_tests/accessibility/table-modification-crash.html
-/sdcard/android/layout_tests/accessibility/aria-link-supports-press.html
-/sdcard/android/layout_tests/accessibility/table-notbody.html
-/sdcard/android/layout_tests/accessibility/ignore-spacer-elements.html
-/sdcard/android/layout_tests/accessibility/transformed-element.html
-/sdcard/android/layout_tests/accessibility/aria-disabled.html
-/sdcard/android/layout_tests/accessibility/placeholder.html
-/sdcard/android/layout_tests/accessibility/non-data-table-cell-title-ui-element.html
-/sdcard/android/layout_tests/accessibility/aria-label.html
-/sdcard/android/layout_tests/accessibility/textarea-line-for-index.html
-/sdcard/android/layout_tests/accessibility/nochildren-elements.html
-/sdcard/android/layout_tests/animations/keyframes-to-missing.html
-/sdcard/android/layout_tests/animations/animation-hit-test.html
-/sdcard/android/layout_tests/animations/animation-hit-test-transform.html
-/sdcard/android/layout_tests/animations/animation-controller-drt-api.html
-/sdcard/android/layout_tests/animations/keyframes-from-missing.html
-/sdcard/android/layout_tests/animations/change-keyframes-name.html
-/sdcard/android/layout_tests/animations/change-keyframes.html
-/sdcard/android/layout_tests/editing/style/remove-underline-from-stylesheet.html
-/sdcard/android/layout_tests/editing/style/remove-underline-in-bold.html
-/sdcard/android/layout_tests/editing/style/apply-through-end-of-document.html
-/sdcard/android/layout_tests/editing/inserting/typing-tab-designmode.html
-/sdcard/android/layout_tests/editing/inserting/space-after-removeformat.html
-/sdcard/android/layout_tests/editing/inserting/insert-thai-characters-001.html
-/sdcard/android/layout_tests/editing/inserting/5994480-2.html
-/sdcard/android/layout_tests/editing/execCommand/queryCommandState-01.html
-/sdcard/android/layout_tests/editing/execCommand/4128080-2.html
-/sdcard/android/layout_tests/editing/execCommand/indent-nested-lists-6.html
-/sdcard/android/layout_tests/editing/execCommand/enabling-and-selection.html
-/sdcard/android/layout_tests/editing/execCommand/insert-line-break-no-scroll.html
-/sdcard/android/layout_tests/editing/execCommand/indent-nested-lists-3.html
-/sdcard/android/layout_tests/editing/execCommand/enabling-and-selection-2.html
-/sdcard/android/layout_tests/editing/execCommand/delete-no-scroll.html
-/sdcard/android/layout_tests/editing/execCommand/forward-delete-no-scroll.html
-/sdcard/android/layout_tests/editing/execCommand/switch-list-type.html
-/sdcard/android/layout_tests/editing/execCommand/19089.html
-/sdcard/android/layout_tests/editing/execCommand/outdent-nested-lists-2.html
-/sdcard/android/layout_tests/editing/execCommand/unlink.html
-/sdcard/android/layout_tests/editing/execCommand/remove-list-1.html
-/sdcard/android/layout_tests/editing/execCommand/indent-nested-lists-5.html
-/sdcard/android/layout_tests/editing/execCommand/indent-nested-lists-2.html
-/sdcard/android/layout_tests/editing/execCommand/copy-without-selection.html
-/sdcard/android/layout_tests/editing/execCommand/outdent-nested-lists-4.html
-/sdcard/android/layout_tests/editing/execCommand/outdent-nested-lists-1.html
-/sdcard/android/layout_tests/editing/execCommand/findString-diacriticals.html
-/sdcard/android/layout_tests/editing/execCommand/indent-nested-lists-7.html
-/sdcard/android/layout_tests/editing/execCommand/createLink.html
-/sdcard/android/layout_tests/editing/execCommand/remove-list-items.html
-/sdcard/android/layout_tests/editing/execCommand/indent-nested-lists-4.html
-/sdcard/android/layout_tests/editing/execCommand/5939887.html
-/sdcard/android/layout_tests/editing/execCommand/insertHTML.html
-/sdcard/android/layout_tests/editing/execCommand/convert-style-elements-to-spans.html
-/sdcard/android/layout_tests/editing/execCommand/indent-nested-lists-1.html
-/sdcard/android/layout_tests/editing/execCommand/outdent-nested-lists-3.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-into-anchor-text.html
-/sdcard/android/layout_tests/editing/pasteboard/19644-1.html
-/sdcard/android/layout_tests/editing/pasteboard/copy-crash.html
-/sdcard/android/layout_tests/editing/pasteboard/5665299.html
-/sdcard/android/layout_tests/editing/pasteboard/file-input-files-access.html
-/sdcard/android/layout_tests/editing/pasteboard/get-data-text-plain-drop.html
-/sdcard/android/layout_tests/editing/pasteboard/get-data-text-plain-paste.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-blockquote-before-blockquote.html
-/sdcard/android/layout_tests/editing/pasteboard/5761530-1.html
-/sdcard/android/layout_tests/editing/pasteboard/copy-in-password-field.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-plaintext-user-select-none.html
-/sdcard/android/layout_tests/editing/pasteboard/drag-image-in-about-blank-frame.html
-/sdcard/android/layout_tests/editing/pasteboard/4744008.html
-/sdcard/android/layout_tests/editing/pasteboard/4922709.html
-/sdcard/android/layout_tests/editing/pasteboard/19644-2.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-text-013.html
-/sdcard/android/layout_tests/editing/pasteboard/5780697-2.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-double-nested-blockquote-before-blockquote.html
-/sdcard/android/layout_tests/editing/pasteboard/copy-paste-float.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-table-002.html
-/sdcard/android/layout_tests/editing/selection/click-outside-editable-div.html
-/sdcard/android/layout_tests/editing/selection/drag-text-delay.html
-/sdcard/android/layout_tests/editing/selection/anchor-focus3.html
-/sdcard/android/layout_tests/editing/selection/home-end.html
-/sdcard/android/layout_tests/editing/selection/user-drag-element-and-user-select-none.html
-/sdcard/android/layout_tests/editing/selection/drag-start-event-client-x-y.html
-/sdcard/android/layout_tests/editing/selection/extend-selection-bidi.html
-/sdcard/android/layout_tests/editing/selection/find-in-text-control.html
-/sdcard/android/layout_tests/editing/selection/5209984.html
-/sdcard/android/layout_tests/editing/selection/toString-1.html
-/sdcard/android/layout_tests/editing/selection/hit-test-anonymous.html
-/sdcard/android/layout_tests/editing/selection/move-begin-end.html
-/sdcard/android/layout_tests/editing/selection/doubleclick-whitespace-img-crash.html
-/sdcard/android/layout_tests/editing/selection/click-after-nested-block.html
-/sdcard/android/layout_tests/editing/selection/move-by-line-003.html
-/sdcard/android/layout_tests/editing/selection/skip-non-editable-1.html
-/sdcard/android/layout_tests/editing/selection/anchor-focus1.html
-/sdcard/android/layout_tests/editing/selection/getRangeAt.html
-/sdcard/android/layout_tests/editing/selection/select-all-textarea.html
-/sdcard/android/layout_tests/editing/selection/doubleclick-whitespace.html
-/sdcard/android/layout_tests/editing/selection/move-paragraph-document-edges.html
-/sdcard/android/layout_tests/editing/selection/after-line-break.html
-/sdcard/android/layout_tests/editing/selection/legal-positions.html
-/sdcard/android/layout_tests/editing/selection/extend-selection-after-double-click.html
-/sdcard/android/layout_tests/editing/selection/select-line.html
-/sdcard/android/layout_tests/editing/selection/doubleclick-whitespace-crash.html
-/sdcard/android/layout_tests/editing/selection/toString.html
-/sdcard/android/layout_tests/editing/selection/inactive-selection.html
-/sdcard/android/layout_tests/editing/selection/click-in-margins-inside-editable-div.html
-/sdcard/android/layout_tests/editing/selection/removeAllRanges.html
-/sdcard/android/layout_tests/editing/selection/skip-non-editable-2.html
-/sdcard/android/layout_tests/editing/selection/anchor-focus2.html
-/sdcard/android/layout_tests/editing/selection/click-in-padding-with-multiple-line-boxes.html
-/sdcard/android/layout_tests/editing/selection/click-before-and-after-table.html
-/sdcard/android/layout_tests/editing/undo/undo-iframe-location-change.html
-/sdcard/android/layout_tests/editing/deleting/pruning-after-merge-1.html
-/sdcard/android/layout_tests/editing/deleting/5546763.html
-/sdcard/android/layout_tests/editing/deleting/5729680.html
-/sdcard/android/layout_tests/editing/deleting/4916235-1.html
-/sdcard/android/layout_tests/editing/deleting/delete-ligature-001.html
-/sdcard/android/layout_tests/editing/deleting/delete-ligature-003.html
-/sdcard/android/layout_tests/editing/deleting/skip-virama-001.html
-/sdcard/android/layout_tests/editing/deleting/smart-editing-disabled.html
-/sdcard/android/layout_tests/editing/deleting/delete-ligature-002.html
-/sdcard/android/layout_tests/editing/deleting/delete-all-text-in-text-field-assertion.html
-/sdcard/android/layout_tests/editing/text-iterator/basic-iteration.html
-/sdcard/android/layout_tests/editing/text-iterator/thai-cursor-movement.html
-/sdcard/android/layout_tests/fast/replaced/table-percent-height-text-controls.html
-/sdcard/android/layout_tests/fast/replaced/image-map-2.html
-/sdcard/android/layout_tests/fast/replaced/image-map-bug16782.html
-/sdcard/android/layout_tests/fast/replaced/table-percent-height.html
-/sdcard/android/layout_tests/fast/replaced/image-map.html
-/sdcard/android/layout_tests/fast/dynamic/paused-event-dispatch.html
-/sdcard/android/layout_tests/fast/text/international/thai-offsetForPosition-inside-character.html
-/sdcard/android/layout_tests/fast/text/plain-text-line-breaks.html
-/sdcard/android/layout_tests/fast/text/offsetForPosition-cluster-at-zero.html
-/sdcard/android/layout_tests/fast/text/zero-width-characters.html
-/sdcard/android/layout_tests/fast/text/reset-drag-on-mouse-down.html
-/sdcard/android/layout_tests/fast/encoding/invalid-xml.html
-/sdcard/android/layout_tests/fast/encoding/char-decoding-mac.html
-/sdcard/android/layout_tests/fast/encoding/mailto-always-utf-8.html
-/sdcard/android/layout_tests/fast/encoding/percent-escaping.html
-/sdcard/android/layout_tests/fast/encoding/utf-32-big-endian-nobom.xml
-/sdcard/android/layout_tests/fast/encoding/hanarei-blog32-fc2-com.html
-/sdcard/android/layout_tests/fast/encoding/frame-default-enc.html
-/sdcard/android/layout_tests/fast/encoding/char-decoding.html
-/sdcard/android/layout_tests/fast/encoding/url-host-name-non-ascii.html
-/sdcard/android/layout_tests/fast/encoding/idn-security.html
-/sdcard/android/layout_tests/fast/encoding/utf-32-little-endian-nobom.xml
-/sdcard/android/layout_tests/fast/encoding/char-encoding-mac.html
-/sdcard/android/layout_tests/fast/encoding/charset-koi8-u.html
-/sdcard/android/layout_tests/fast/workers/worker-location.html
-/sdcard/android/layout_tests/fast/selectors/lang-inheritance.html
-/sdcard/android/layout_tests/fast/selectors/lang-vs-xml-lang.html
-/sdcard/android/layout_tests/fast/selectors/lang-inheritance2.html
-/sdcard/android/layout_tests/fast/overflow/scroll-vertical-not-horizontal.html
-/sdcard/android/layout_tests/fast/events/onunload.html
-/sdcard/android/layout_tests/fast/events/mouseup-outside-document.html
-/sdcard/android/layout_tests/fast/events/offsetX-offsetY.html
-/sdcard/android/layout_tests/fast/events/mouseover-mouseout.html
-/sdcard/android/layout_tests/fast/events/option-tab.html
-/sdcard/android/layout_tests/fast/events/popup-blocking-click-in-iframe.html
-/sdcard/android/layout_tests/fast/events/tabindex-focus-blur-all.html
-/sdcard/android/layout_tests/fast/events/onchange-passwordfield.html
-/sdcard/android/layout_tests/fast/events/drag-in-frames.html
-/sdcard/android/layout_tests/fast/events/frame-tab-focus.html
-/sdcard/android/layout_tests/fast/events/autoscroll-in-textfield.html
-/sdcard/android/layout_tests/fast/events/arrow-navigation.html
-/sdcard/android/layout_tests/fast/events/fire-scroll-event.html
-/sdcard/android/layout_tests/fast/events/attempt-scroll-with-no-scrollbars.html
-/sdcard/android/layout_tests/fast/events/mouseclick-target-and-positioning.html
-/sdcard/android/layout_tests/fast/events/anchor-empty-focus.html
-/sdcard/android/layout_tests/fast/events/input-image-scrolled-x-y.html
-/sdcard/android/layout_tests/fast/events/dblclick-addEventListener.html
-/sdcard/android/layout_tests/fast/events/frame-programmatic-focus.html
-/sdcard/android/layout_tests/fast/events/related-target.html
-/sdcard/android/layout_tests/fast/events/context-onmousedown-event.html
-/sdcard/android/layout_tests/fast/events/mouse-drag-from-frame-to-other-frame.html
-/sdcard/android/layout_tests/fast/events/prevent-drag-to-navigate.html
-/sdcard/android/layout_tests/fast/events/stop-load-in-unload-handler-using-window-stop.html
-/sdcard/android/layout_tests/fast/events/content-changed-during-drop.html
-/sdcard/android/layout_tests/fast/events/autoscroll-with-non-scrollable-parent.html
-/sdcard/android/layout_tests/fast/events/window-events-capture.html
-/sdcard/android/layout_tests/fast/events/onchange-click-hang.html
-/sdcard/android/layout_tests/fast/events/onload-webkit-before-webcore.html
-/sdcard/android/layout_tests/fast/events/window-events-bubble2.html
-/sdcard/android/layout_tests/fast/events/js-keyboard-event-creation.html
-/sdcard/android/layout_tests/fast/events/event-view-toString.html
-/sdcard/android/layout_tests/fast/events/onchange-select-popup.html
-/sdcard/android/layout_tests/fast/events/access-key-self-destruct.html
-/sdcard/android/layout_tests/fast/events/scrollbar-double-click.html
-/sdcard/android/layout_tests/fast/events/onunload-clears-onbeforeunload.html
-/sdcard/android/layout_tests/fast/events/stop-load-in-unload-handler-using-document-write.html
-/sdcard/android/layout_tests/fast/events/tabindex-focus-chain.html
-/sdcard/android/layout_tests/fast/events/capture-on-target.html
-/sdcard/android/layout_tests/fast/events/window-events-bubble.html
-/sdcard/android/layout_tests/fast/events/event-function-toString.html
-/sdcard/android/layout_tests/fast/events/right-click-focus.html
-/sdcard/android/layout_tests/fast/events/mouseup-from-button2.html
-/sdcard/android/layout_tests/fast/events/frame-click-focus.html
-/sdcard/android/layout_tests/fast/events/crash-on-mutate-during-drop.html
-/sdcard/android/layout_tests/fast/events/mouseout-on-window.html
-/sdcard/android/layout_tests/fast/events/keypress-insert-tab.html
-/sdcard/android/layout_tests/fast/events/mouseout-dead-subframe.html
-/sdcard/android/layout_tests/fast/events/onunload-not-on-body.html
-/sdcard/android/layout_tests/fast/events/mousemove-after-drag-over-scrollbar.html
-/sdcard/android/layout_tests/fast/events/contextmenu-scrolled-page-with-frame.html
-/sdcard/android/layout_tests/fast/events/drag-to-navigate.html
-/sdcard/android/layout_tests/fast/events/key-events-in-input-button.html
-/sdcard/android/layout_tests/fast/events/arrow-keys-on-body.html
-/sdcard/android/layout_tests/fast/events/ondragenter.html
-/sdcard/android/layout_tests/fast/events/pointer-events.html
-/sdcard/android/layout_tests/fast/events/scroll-to-anchor-in-overflow-hidden.html
-/sdcard/android/layout_tests/fast/events/autoscroll-nonscrollable-iframe-in-scrollable-div.html
-/sdcard/android/layout_tests/fast/events/keypress-focus-change.html
-/sdcard/android/layout_tests/fast/events/key-events-in-input-text.html
-/sdcard/android/layout_tests/fast/events/pointer-events-2.html
-/sdcard/android/layout_tests/fast/events/drag-outside-window.html
-/sdcard/android/layout_tests/fast/events/click-count.html
-/sdcard/android/layout_tests/fast/events/onchange-searchfield.html
-/sdcard/android/layout_tests/fast/events/special-key-events-in-input-text.html
-/sdcard/android/layout_tests/fast/events/mouse-drag-from-frame.html
-/sdcard/android/layout_tests/fast/events/keydown-keypress-preventDefault.html
-/sdcard/android/layout_tests/fast/events/onsearch-enter.html
-/sdcard/android/layout_tests/fast/events/mouse-click-events.html
-/sdcard/android/layout_tests/fast/events/mouseover-mouseout2.html
-/sdcard/android/layout_tests/fast/events/open-window-from-another-frame.html
-/sdcard/android/layout_tests/fast/events/resize-subframe.html
-/sdcard/android/layout_tests/fast/events/onchange-textfield.html
-/sdcard/android/layout_tests/fast/events/onclick-list-marker.html
-/sdcard/android/layout_tests/fast/events/anchor-image-scrolled-x-y.html
-/sdcard/android/layout_tests/fast/images/image-map-zoom.html
-/sdcard/android/layout_tests/fast/js/kde/Number.html
-/sdcard/android/layout_tests/fast/js/instanceof-operator.html
-/sdcard/android/layout_tests/fast/js/navigator-mimeTypes-length.html
-/sdcard/android/layout_tests/fast/js/global-constructors.html
-/sdcard/android/layout_tests/fast/js/convert-nan-to-bool.html
-/sdcard/android/layout_tests/fast/dom/HTMLDocument/hasFocus.html
-/sdcard/android/layout_tests/fast/dom/Document/early-document-access.html
-/sdcard/android/layout_tests/fast/dom/DOMException/XPathException.html
-/sdcard/android/layout_tests/fast/dom/HTMLScriptElement/nested-execution.html
-/sdcard/android/layout_tests/fast/dom/HTMLDataGridElement/DataGridColumns-dom.html
-/sdcard/android/layout_tests/fast/dom/HTMLDataGridElement/DataGridColumns-basic.html
-/sdcard/android/layout_tests/fast/dom/HTMLDataGridElement/DataGridColumns-dom-attributes.html
-/sdcard/android/layout_tests/fast/dom/HTMLDataGridElement/DataGridDataSource-basic.html
-/sdcard/android/layout_tests/fast/dom/getElementsByClassName/010.xml
-/sdcard/android/layout_tests/fast/dom/getElementsByClassName/011.xml
-/sdcard/android/layout_tests/fast/dom/Window/window-xy-properties.html
-/sdcard/android/layout_tests/fast/dom/Window/window-screen-properties.html
-/sdcard/android/layout_tests/fast/dom/Window/new-window-opener.html
-/sdcard/android/layout_tests/fast/dom/Window/dom-access-from-closure-window.html
-/sdcard/android/layout_tests/fast/dom/Window/window-resize.html
-/sdcard/android/layout_tests/fast/dom/Window/closure-access-after-navigation-window.html
-/sdcard/android/layout_tests/fast/dom/Window/Plug-ins.html
-/sdcard/android/layout_tests/fast/dom/Window/get-set-properties.html
-/sdcard/android/layout_tests/fast/dom/Window/window-scroll-arguments.html
-/sdcard/android/layout_tests/fast/dom/Window/window-lookup-precedence.html
-/sdcard/android/layout_tests/fast/dom/Window/window-resize-and-move-arguments.html
-/sdcard/android/layout_tests/fast/dom/Window/custom-constructors.html
-/sdcard/android/layout_tests/fast/dom/Window/webkitConvertPoint.html
-/sdcard/android/layout_tests/fast/dom/Window/window-properties.html
-/sdcard/android/layout_tests/fast/dom/Window/window-onFocus.html
-/sdcard/android/layout_tests/fast/dom/Window/dom-access-from-closure-iframe.html
-/sdcard/android/layout_tests/fast/dom/Window/window-early-properties.html
-/sdcard/android/layout_tests/fast/dom/StyleSheet/ownerNode-lifetime-2.html
-/sdcard/android/layout_tests/fast/dom/dom-constructors.html
-/sdcard/android/layout_tests/fast/dom/assign-to-window-status.html
-/sdcard/android/layout_tests/fast/dom/navigator-detached-no-crash.html
-/sdcard/android/layout_tests/fast/dom/object-embed-plugin-scripting.html
-/sdcard/android/layout_tests/fast/dom/node-filter-gc.html
-/sdcard/android/layout_tests/fast/dom/noscript-canvas-in-created-html-document.html
-/sdcard/android/layout_tests/fast/dom/getClientRects.html
-/sdcard/android/layout_tests/fast/dom/null-document-location-href-put-crash.html
-/sdcard/android/layout_tests/fast/dom/prototype-inheritance-2.html
-/sdcard/android/layout_tests/fast/dom/location-new-window-no-crash.html
-/sdcard/android/layout_tests/fast/dom/gc-9.html
-/sdcard/android/layout_tests/fast/dom/wrapper-classes.html
-/sdcard/android/layout_tests/fast/dom/document-width-height-force-layout.html
-/sdcard/android/layout_tests/fast/dom/client-width-height.html
-/sdcard/android/layout_tests/fast/dom/constructed-objects-prototypes.html
-/sdcard/android/layout_tests/fast/dom/global-constructors.html
-/sdcard/android/layout_tests/fast/dom/client-width-height-quirks.html
-/sdcard/android/layout_tests/fast/dom/javascript-url-crash-function.html
-/sdcard/android/layout_tests/fast/dom/getBoundingClientRect.html
-/sdcard/android/layout_tests/fast/dom/location-hash.html
-/sdcard/android/layout_tests/fast/dom/documenturi-can-hold-arbitrary-string.html
-/sdcard/android/layout_tests/fast/dom/documenturi-not-affected-by-base-tag.html
-/sdcard/android/layout_tests/fast/dom/open-and-close-by-DOM.html
-/sdcard/android/layout_tests/fast/dom/set-frame-src-while-running-script-in-frame.html
-/sdcard/android/layout_tests/fast/dom/prototype-inheritance.html
-/sdcard/android/layout_tests/fast/dom/getBoundingClientRect-getClientRects-relative-to-viewport.html
-/sdcard/android/layout_tests/fast/dom/frame-loading-via-document-write.html
-/sdcard/android/layout_tests/fast/xpath/py-dom-xpath/paths.html
-/sdcard/android/layout_tests/fast/xpath/py-dom-xpath/expressions.html
-/sdcard/android/layout_tests/fast/xpath/py-dom-xpath/predicates.html
-/sdcard/android/layout_tests/fast/xpath/py-dom-xpath/abbreviations.html
-/sdcard/android/layout_tests/fast/xpath/py-dom-xpath/axes.html
-/sdcard/android/layout_tests/fast/xpath/py-dom-xpath/functions.html
-/sdcard/android/layout_tests/fast/xpath/py-dom-xpath/nodetests.html
-/sdcard/android/layout_tests/fast/xpath/py-dom-xpath/data.html
-/sdcard/android/layout_tests/fast/xpath/4XPath/Borrowed/od_20000608.html
-/sdcard/android/layout_tests/fast/xpath/4XPath/Borrowed/namespace-nodes.html
-/sdcard/android/layout_tests/fast/xpath/4XPath/Borrowed/rs_20010831.html
-/sdcard/android/layout_tests/fast/xpath/4XPath/Borrowed/sr_20021217.html
-/sdcard/android/layout_tests/fast/xpath/4XPath/Borrowed/kd_20010423.html
-/sdcard/android/layout_tests/fast/xpath/4XPath/Borrowed/cz_20030217.html
-/sdcard/android/layout_tests/fast/xpath/4XPath/Core/test_boolean_expr.html
-/sdcard/android/layout_tests/fast/xpath/4XPath/Core/test_core_functions.html
-/sdcard/android/layout_tests/fast/xpath/4XPath/Core/test_location_path.html
-/sdcard/android/layout_tests/fast/xpath/4XPath/Core/test_node_test.html
-/sdcard/android/layout_tests/fast/xpath/4XPath/Core/test_literal_expr.html
-/sdcard/android/layout_tests/fast/xpath/4XPath/Core/test_predicate_list.html
-/sdcard/android/layout_tests/fast/xpath/4XPath/Core/test_parser.html
-/sdcard/android/layout_tests/fast/xpath/4XPath/Core/test_nodeset_expr.html
-/sdcard/android/layout_tests/fast/xpath/4XPath/Core/test_numeric_expr.html
-/sdcard/android/layout_tests/fast/xpath/4XPath/Core/test_step.html
-/sdcard/android/layout_tests/fast/xpath/detached-subtree-invalidate-iterator.html
-/sdcard/android/layout_tests/fast/xpath/ancestor-axis.html
-/sdcard/android/layout_tests/fast/xpath/string-value.html
-/sdcard/android/layout_tests/fast/xpath/id-simple.html
-/sdcard/android/layout_tests/fast/xpath/id-path.html
-/sdcard/android/layout_tests/fast/xpath/invalid-functions.html
-/sdcard/android/layout_tests/fast/xpath/xpath-namespaces.html
-/sdcard/android/layout_tests/fast/xpath/node-name-case-sensitivity.html
-/sdcard/android/layout_tests/fast/xpath/xpath-empty-string.html
-/sdcard/android/layout_tests/fast/xpath/attribute-node-predicate.html
-/sdcard/android/layout_tests/fast/xpath/nodeset-duplicates.html
-/sdcard/android/layout_tests/fast/xpath/name-null-namespace.html
-/sdcard/android/layout_tests/fast/xpath/implicit-node-args.html
-/sdcard/android/layout_tests/fast/xpath/text-nodes.html
-/sdcard/android/layout_tests/fast/xpath/complex-id.html
-/sdcard/android/layout_tests/fast/xpath/xpath-functional-test.html
-/sdcard/android/layout_tests/fast/xpath/attr-namespace.html
-/sdcard/android/layout_tests/fast/xpath/position.html
-/sdcard/android/layout_tests/fast/xpath/evaluate-twice.html
-/sdcard/android/layout_tests/fast/xpath/substring-after.html
-/sdcard/android/layout_tests/fast/xpath/empty-string-substring.html
-/sdcard/android/layout_tests/fast/xpath/document-order.html
-/sdcard/android/layout_tests/fast/xpath/reverse-axes.html
-/sdcard/android/layout_tests/fast/xpath/nan-to-boolean.html
-/sdcard/android/layout_tests/fast/forms/mailto/get-non-ascii-text-plain.html
-/sdcard/android/layout_tests/fast/forms/mailto/advanced-get.html
-/sdcard/android/layout_tests/fast/forms/mailto/get-non-ascii-text-plain-latin-1.html
-/sdcard/android/layout_tests/fast/forms/mailto/post-multiple-items-multipart-form-data.html
-/sdcard/android/layout_tests/fast/forms/mailto/get-multiple-items.html
-/sdcard/android/layout_tests/fast/forms/mailto/get-non-ascii-always-utf-8.html
-/sdcard/android/layout_tests/fast/forms/mailto/post-multiple-items.html
-/sdcard/android/layout_tests/fast/forms/mailto/post-append-query.html
-/sdcard/android/layout_tests/fast/forms/mailto/get-multiple-items-x-www-form-urlencoded.html
-/sdcard/android/layout_tests/fast/forms/mailto/get-overwrite-query.html
-/sdcard/android/layout_tests/fast/forms/mailto/post-multiple-items-x-www-form-urlencoded.html
-/sdcard/android/layout_tests/fast/forms/mailto/get-multiple-items-text-plain.html
-/sdcard/android/layout_tests/fast/forms/mailto/post-multiple-items-text-plain.html
-/sdcard/android/layout_tests/fast/forms/mailto/get-non-ascii.html
-/sdcard/android/layout_tests/fast/forms/mailto/post-text-plain-with-accept-charset.html
-/sdcard/android/layout_tests/fast/forms/mailto/post-text-plain.html
-/sdcard/android/layout_tests/fast/forms/mailto/advanced-put.html
-/sdcard/android/layout_tests/fast/forms/listbox-typeahead-scroll.html
-/sdcard/android/layout_tests/fast/forms/select-empty-list.html
-/sdcard/android/layout_tests/fast/forms/focus2.html
-/sdcard/android/layout_tests/fast/forms/legend-access-key.html
-/sdcard/android/layout_tests/fast/forms/focus-selection-textarea.html
-/sdcard/android/layout_tests/fast/forms/select-popup-pagekeys.html
-/sdcard/android/layout_tests/fast/forms/select-double-onchange.html
-/sdcard/android/layout_tests/fast/forms/button-enter-click.html
-/sdcard/android/layout_tests/fast/forms/autofocus-opera-003.html
-/sdcard/android/layout_tests/fast/forms/search-click-in-placeholder.html
-/sdcard/android/layout_tests/fast/forms/onselect-textfield.html
-/sdcard/android/layout_tests/fast/forms/textfield-onchange-deletion.html
-/sdcard/android/layout_tests/fast/forms/listbox-onchange.html
-/sdcard/android/layout_tests/fast/forms/button-spacebar-click.html
-/sdcard/android/layout_tests/fast/forms/search-cancel-button-mouseup.html
-/sdcard/android/layout_tests/fast/forms/get-file-upload.html
-/sdcard/android/layout_tests/fast/forms/select-enter-key.html
-/sdcard/android/layout_tests/fast/forms/drag-out-of-textarea.html
-/sdcard/android/layout_tests/fast/forms/option-mouseevents.html
-/sdcard/android/layout_tests/fast/forms/input-radio-checked-tab.html
-/sdcard/android/layout_tests/fast/forms/plaintext-mode-1.html
-/sdcard/android/layout_tests/fast/forms/input-select-on-click.html
-/sdcard/android/layout_tests/fast/forms/textarea-scrolled-endline-caret.html
-/sdcard/android/layout_tests/fast/forms/textarea-scrollbar-height.html
-/sdcard/android/layout_tests/fast/forms/textarea-type-spaces.html
-/sdcard/android/layout_tests/fast/forms/slider-mouse-events.html
-/sdcard/android/layout_tests/fast/forms/slider-onchange-event.html
-/sdcard/android/layout_tests/fast/forms/textarea-input-event.html
-/sdcard/android/layout_tests/fast/forms/search-delete-while-cancel-button-clicked.html
-/sdcard/android/layout_tests/fast/forms/select-accesskey.html
-/sdcard/android/layout_tests/fast/forms/password-doubleclick-selection.html
-/sdcard/android/layout_tests/fast/forms/textfield-inside-anchor.html
-/sdcard/android/layout_tests/fast/forms/slider-delete-while-dragging-thumb.html
-/sdcard/android/layout_tests/fast/forms/textfield-to-password-on-focus.html
-/sdcard/android/layout_tests/fast/forms/textarea-arrow-navigation.html
-/sdcard/android/layout_tests/fast/forms/search-abs-pos-cancel-button.html
-/sdcard/android/layout_tests/fast/forms/enter-clicks-buttons.html
-/sdcard/android/layout_tests/fast/forms/radio_checked_name.html
-/sdcard/android/layout_tests/fast/forms/search-hidden-cancel-button.html
-/sdcard/android/layout_tests/fast/forms/select-script-onchange.html
-/sdcard/android/layout_tests/fast/forms/textarea-paste-newline.html
-/sdcard/android/layout_tests/fast/forms/drag-into-textarea.html
-/sdcard/android/layout_tests/fast/forms/form-and-frame-interaction-retains-values.html
-/sdcard/android/layout_tests/fast/forms/slider-transformed.html
-/sdcard/android/layout_tests/fast/forms/focus-control-to-page.html
-/sdcard/android/layout_tests/fast/forms/select-type-ahead-non-latin.html
-/sdcard/android/layout_tests/fast/forms/focus-selection-input.html
-/sdcard/android/layout_tests/fast/forms/slider-zoomed.html
-/sdcard/android/layout_tests/fast/forms/search-event-delay.html
-/sdcard/android/layout_tests/fast/forms/empty-textarea-toggle-disabled.html
-/sdcard/android/layout_tests/fast/forms/25153.html
-/sdcard/android/layout_tests/fast/forms/select-cache-desynchronization.html
-/sdcard/android/layout_tests/fast/forms/check-box-enter-key.html
-/sdcard/android/layout_tests/fast/forms/button-state-restore.html
-/sdcard/android/layout_tests/fast/forms/access-key.html
-/sdcard/android/layout_tests/fast/forms/textarea-selection-preservation.html
-/sdcard/android/layout_tests/fast/forms/textarea-metrics.html
-/sdcard/android/layout_tests/fast/forms/onchange-enter-submit.html
-/sdcard/android/layout_tests/fast/forms/onselect-textarea.html
-/sdcard/android/layout_tests/fast/forms/listbox-selection.html
-/sdcard/android/layout_tests/fast/css/getComputedStyle/computed-style.html
-/sdcard/android/layout_tests/fast/css/getComputedStyle/computed-style-without-renderer.html
-/sdcard/android/layout_tests/fast/css/text-align.html
-/sdcard/android/layout_tests/fast/css/hover-affects-child.html
-/sdcard/android/layout_tests/fast/css/resize-single-axis.html
-/sdcard/android/layout_tests/fast/css/percent-character-as-value.html
-/sdcard/android/layout_tests/fast/css/uri-token-parsing.html
-/sdcard/android/layout_tests/fast/css/zoom-body-scroll.html
-/sdcard/android/layout_tests/fast/css/invalid-percentage-property.html
-/sdcard/android/layout_tests/fast/parser/external-entities-in-xslt.xml
-/sdcard/android/layout_tests/fast/parser/xml-declaration-missing-ending-mark.html
-/sdcard/android/layout_tests/fast/parser/tabindex-parsing.html
-/sdcard/android/layout_tests/fast/history/saves-state-after-fragment-nav.html
-/sdcard/android/layout_tests/fast/history/back-forward-is-asynchronous.html
-/sdcard/android/layout_tests/fast/history/window-open.html
-/sdcard/android/layout_tests/fast/history/history_reload.html
-/sdcard/android/layout_tests/fast/history/go-back-to-changed-name.html
-/sdcard/android/layout_tests/fast/loader/cancel-load-during-port-block-timer.html
-/sdcard/android/layout_tests/fast/loader/local-iFrame-source-from-local.html
-/sdcard/android/layout_tests/fast/loader/null-request-after-willSendRequest.html
-/sdcard/android/layout_tests/fast/loader/stop-provisional-loads.html
-/sdcard/android/layout_tests/fast/loader/location-port.html
-/sdcard/android/layout_tests/fast/loader/user-style-sheet-resource-load-callbacks.html
-/sdcard/android/layout_tests/fast/loader/policy-delegate-action-hit-test-zoomed.html
-/sdcard/android/layout_tests/fast/loader/subframe-navigate-during-main-frame-load.html
-/sdcard/android/layout_tests/fast/loader/onunload-form-submit-crash-2.html
-/sdcard/android/layout_tests/fast/loader/javascript-url-hierarchical-execution.html
-/sdcard/android/layout_tests/fast/loader/plain-text-document.html
-/sdcard/android/layout_tests/fast/loader/onunload-form-submit-crash.html
-/sdcard/android/layout_tests/fast/loader/subframe-self-close.html
-/sdcard/android/layout_tests/fast/loader/local-image-from-local.html
-/sdcard/android/layout_tests/fast/loader/local-CSS-from-local.html
-/sdcard/android/layout_tests/fast/loader/reload-policy-delegate.html
-/sdcard/android/layout_tests/fast/loader/local-JavaScript-from-local.html
-/sdcard/android/layout_tests/fast/loader/main-document-url-for-non-http-loads.html
-/sdcard/android/layout_tests/fast/loader/data-url-encoding-svg.html
-/sdcard/android/layout_tests/fast/loader/data-url-encoding-html.html
-/sdcard/android/layout_tests/fast/loader/opaque-base-url.html
-/sdcard/android/layout_tests/fast/xsl/sort-locale.xml
-/sdcard/android/layout_tests/fast/xsl/transformToFragment-XML-declaration.html
-/sdcard/android/layout_tests/fast/xsl/extra-lf-at-end.html
-/sdcard/android/layout_tests/fast/xsl/xslt-doc-noenc.xml
-/sdcard/android/layout_tests/fast/xsl/import-after-comment.xml
-/sdcard/android/layout_tests/fast/xsl/xslt-processor.html
-/sdcard/android/layout_tests/fast/xsl/sort-unicode.xml
-/sdcard/android/layout_tests/fast/xsl/default-html.html
-/sdcard/android/layout_tests/fast/xsl/nbsp-in-stylesheet.html
-/sdcard/android/layout_tests/fast/xsl/xslt-string-parameters.html
-/sdcard/android/layout_tests/fast/xsl/xslt-entity-enc.xml
-/sdcard/android/layout_tests/fast/xsl/xslt-text.html
-/sdcard/android/layout_tests/fast/xsl/xslt-nested-stylesheets.xml
-/sdcard/android/layout_tests/fast/xsl/xslt-url.xml
-/sdcard/android/layout_tests/fast/xsl/xslt-doc-enc.xml
-/sdcard/android/layout_tests/fast/xsl/xslt-recursion.xml
-/sdcard/android/layout_tests/fast/xsl/exslt-node-set.xml
-/sdcard/android/layout_tests/fast/xsl/subframe-location.html
-/sdcard/android/layout_tests/fast/xsl/xslt-second-level-import.xml
-/sdcard/android/layout_tests/fast/xsl/dtd-in-source-document.xml
-/sdcard/android/layout_tests/fast/xsl/xslt-fragment-in-empty-doc.html
-/sdcard/android/layout_tests/fast/xsl/mozilla-tests.xml
-/sdcard/android/layout_tests/fast/xmlhttprequest/xmlhttprequest-bad-mimetype.html
-/sdcard/android/layout_tests/fast/xmlhttprequest/xmlhttprequest-gc.html
-/sdcard/android/layout_tests/fast/canvas/canvas-alphaImageData-behavior.html
-/sdcard/android/layout_tests/fast/canvas/canvas-gradient-addStop-error.html
-/sdcard/android/layout_tests/fast/canvas/canvas-pattern-behaviour.html
-/sdcard/android/layout_tests/fast/canvas/canvas-transform-non-invertible.html
-/sdcard/android/layout_tests/fast/canvas/pointInPath.html
-/sdcard/android/layout_tests/fast/canvas/canvas-transform-infinity.html
-/sdcard/android/layout_tests/fast/canvas/translate-text.html
-/sdcard/android/layout_tests/fast/canvas/toDataURL-supportedTypes.html
-/sdcard/android/layout_tests/fast/canvas/canvas-getImageData.html
-/sdcard/android/layout_tests/fast/canvas/canvas-empty-image-pattern.html
-/sdcard/android/layout_tests/fast/canvas/canvas-transform-skewed.html
-/sdcard/android/layout_tests/fast/canvas/canvas-ImageData-behaviour.html
-/sdcard/android/layout_tests/fast/canvas/canvas-putImageData.html
-/sdcard/android/layout_tests/fast/canvas/canvas-pattern-modify.html
-/sdcard/android/layout_tests/fast/canvas/canvas-longlived-context.html
-/sdcard/android/layout_tests/fast/canvas/canvas-save-restore-with-path.html
-/sdcard/android/layout_tests/fast/canvas/canvas-transform-nan.html
-/sdcard/android/layout_tests/fast/canvas/canvas-pattern-transform.html
-/sdcard/android/layout_tests/fast/canvas/canvas-transform-identity.html
-/sdcard/android/layout_tests/fast/canvas/set-colors.html
-/sdcard/android/layout_tests/fast/canvas/canvas-transform-multiply.html
-/sdcard/android/layout_tests/fast/frames/viewsource-empty-attribute-value.html
-/sdcard/android/layout_tests/fast/frames/location-put-after-removal.html
-/sdcard/android/layout_tests/fast/frames/frame-deep-nested-resize.html
-/sdcard/android/layout_tests/fast/frames/iframe-window-focus.html
-/sdcard/android/layout_tests/fast/frames/frame-dead-region.html
-/sdcard/android/layout_tests/fast/frames/frameElement-widthheight.html
-/sdcard/android/layout_tests/fast/frames/removal-before-attach-crash.html
-/sdcard/android/layout_tests/fast/frames/frame-unload-crash.html
-/sdcard/android/layout_tests/fast/frames/frame-js-url-clientWidth.html
-/sdcard/android/layout_tests/fast/frames/iframe-js-url-clientWidth.html
-/sdcard/android/layout_tests/fast/frames/frame-length-fractional.html
-/sdcard/android/layout_tests/fast/frames/iframe-name-and-id.html
-/sdcard/android/layout_tests/fast/loading/subframe-removes-itself.html
-/sdcard/android/layout_tests/http/tests/media/video-seekable-stall.html
-/sdcard/android/layout_tests/http/tests/media/remove-while-loading.html
-/sdcard/android/layout_tests/http/tests/media/video-play-stall.html
-/sdcard/android/layout_tests/http/tests/media/video-play-stall-seek.html
-/sdcard/android/layout_tests/http/tests/plugins/npapi-response-headers.html
-/sdcard/android/layout_tests/http/tests/plugins/get-url.html
-/sdcard/android/layout_tests/http/tests/plugins/interrupted-get-url.html
-/sdcard/android/layout_tests/http/tests/plugins/post-url-file.html
-/sdcard/android/layout_tests/http/tests/plugins/cross-frame-object-access.html
-/sdcard/android/layout_tests/http/tests/plugins/local-geturl-from-remote.html
-/sdcard/android/layout_tests/http/tests/plugins/geturlnotify-from-npp-destroystream.html
-/sdcard/android/layout_tests/http/tests/mime/standard-mode-does-not-load-stylesheet-with-text-plain-and-css-extension.html
-/sdcard/android/layout_tests/http/tests/mime/standard-mode-does-not-load-stylesheet-with-text-plain.html
-/sdcard/android/layout_tests/http/tests/local/drag-over-remote-content.html
-/sdcard/android/layout_tests/http/tests/misc/image-blocked-src-change.html
-/sdcard/android/layout_tests/http/tests/misc/acid3.html
-/sdcard/android/layout_tests/http/tests/misc/dns-prefetch-control.html
-/sdcard/android/layout_tests/http/tests/misc/will-send-request-returns-null-on-redirect.html
-/sdcard/android/layout_tests/http/tests/misc/isindex-formdata.html
-/sdcard/android/layout_tests/http/tests/misc/image-blocked-src-no-change.html
-/sdcard/android/layout_tests/http/tests/misc/policy-delegate-called-twice.html
-/sdcard/android/layout_tests/http/tests/misc/window-dot-stop.html
-/sdcard/android/layout_tests/http/tests/misc/css-reject-any-type-in-strict-mode.html
-/sdcard/android/layout_tests/http/tests/misc/favicon-loads-with-images-disabled.html
-/sdcard/android/layout_tests/http/tests/misc/SVGFont-delayed-load.html
-/sdcard/android/layout_tests/http/tests/misc/location-test-xsl-style-sheet.xml
-/sdcard/android/layout_tests/http/tests/misc/redirect-to-external-url.html
-/sdcard/android/layout_tests/http/tests/misc/submit-get-in-utf7.html
-/sdcard/android/layout_tests/http/tests/cookies/simple-cookies-max-age.html
-/sdcard/android/layout_tests/http/tests/cookies/simple-cookies-expired.html
-/sdcard/android/layout_tests/http/tests/cookies/multiple-cookies.html
-/sdcard/android/layout_tests/http/tests/wml/access-target-path-deny.html
-/sdcard/android/layout_tests/http/tests/wml/post-data-to-server.html
-/sdcard/android/layout_tests/http/tests/wml/go-task-get-method-accept-charset.html
-/sdcard/android/layout_tests/http/tests/wml/access-target.html
-/sdcard/android/layout_tests/http/tests/wml/access-target-domain-deny.html
-/sdcard/android/layout_tests/http/tests/wml/go-task-post-method-accept-charset.html
-/sdcard/android/layout_tests/http/tests/wml/go-task-get-method.html
-/sdcard/android/layout_tests/http/tests/wml/go-task-post-method.html
-/sdcard/android/layout_tests/http/tests/navigation/success200-reload.html
-/sdcard/android/layout_tests/http/tests/navigation/redirect-cycle.html
-/sdcard/android/layout_tests/http/tests/navigation/reload-subframe-frame.html
-/sdcard/android/layout_tests/http/tests/navigation/window-open-adds-history-item.html
-/sdcard/android/layout_tests/http/tests/navigation/success200-goback.html
-/sdcard/android/layout_tests/http/tests/navigation/timerredirect-basic.html
-/sdcard/android/layout_tests/http/tests/navigation/lockedhistory-iframe.html
-/sdcard/android/layout_tests/http/tests/navigation/document-location-click-timeout.html
-/sdcard/android/layout_tests/http/tests/navigation/post-goback2.html
-/sdcard/android/layout_tests/http/tests/navigation/onload-navigation-iframe-timeout.html
-/sdcard/android/layout_tests/http/tests/navigation/location-assign-adds-history-item.html
-/sdcard/android/layout_tests/http/tests/navigation/anchor-goback.html
-/sdcard/android/layout_tests/http/tests/navigation/redirect-load-no-form-restoration.html
-/sdcard/android/layout_tests/http/tests/navigation/metaredirect-subframeload.html
-/sdcard/android/layout_tests/http/tests/navigation/javascriptlink-subframeload.html
-/sdcard/android/layout_tests/http/tests/navigation/metaredirect-basic.html
-/sdcard/android/layout_tests/http/tests/navigation/success200-subframeload.html
-/sdcard/android/layout_tests/http/tests/navigation/post-goback-same-url.html
-/sdcard/android/layout_tests/http/tests/navigation/restore-form-state-https.html
-/sdcard/android/layout_tests/http/tests/navigation/success200-frames.html
-/sdcard/android/layout_tests/http/tests/navigation/redirect302-basic.html
-/sdcard/android/layout_tests/http/tests/navigation/document-location-mouseover.html
-/sdcard/android/layout_tests/http/tests/navigation/redirect302-goback.html
-/sdcard/android/layout_tests/http/tests/navigation/anchor-subframeload.html
-/sdcard/android/layout_tests/http/tests/navigation/target-frame-from-window.html
-/sdcard/android/layout_tests/http/tests/navigation/slowmetaredirect-basic.html
-/sdcard/android/layout_tests/http/tests/navigation/reload-subframe-iframe.html
-/sdcard/android/layout_tests/http/tests/navigation/success200-loadsame.html
-/sdcard/android/layout_tests/http/tests/navigation/relativeanchor-basic.html
-/sdcard/android/layout_tests/http/tests/navigation/redirect302-subframeload.html
-/sdcard/android/layout_tests/http/tests/navigation/relativeanchor-goback.html
-/sdcard/android/layout_tests/http/tests/navigation/metaredirect-goback.html
-/sdcard/android/layout_tests/http/tests/navigation/redirect302-frames.html
-/sdcard/android/layout_tests/http/tests/navigation/multiple-back-forward-entries.html
-/sdcard/android/layout_tests/http/tests/navigation/javascriptlink-goback.html
-/sdcard/android/layout_tests/http/tests/navigation/success200-basic.html
-/sdcard/android/layout_tests/http/tests/navigation/postredirect-goback2.html
-/sdcard/android/layout_tests/http/tests/navigation/timerredirect-goback.html
-/sdcard/android/layout_tests/http/tests/navigation/location-href-set-adds-history-item.html
-/sdcard/android/layout_tests/http/tests/navigation/anchor-basic.html
-/sdcard/android/layout_tests/http/tests/navigation/document-location-click.html
-/sdcard/android/layout_tests/http/tests/navigation/onload-navigation-iframe.html
-/sdcard/android/layout_tests/http/tests/navigation/relativeanchor-frames.html
-/sdcard/android/layout_tests/http/tests/navigation/metaredirect-frames.html
-/sdcard/android/layout_tests/http/tests/navigation/location-replace-adds-history-item.html
-/sdcard/android/layout_tests/http/tests/navigation/success200-frames-loadsame.html
-/sdcard/android/layout_tests/http/tests/navigation/back-to-slow-frame.html
-/sdcard/android/layout_tests/http/tests/navigation/new-window-redirect-history.html
-/sdcard/android/layout_tests/http/tests/navigation/javascriptlink-basic.html
-/sdcard/android/layout_tests/http/tests/navigation/timerredirect-subframeload.html
-/sdcard/android/layout_tests/http/tests/navigation/location-set-adds-history-item.html
-/sdcard/android/layout_tests/http/tests/navigation/onload-navigation-iframe-2.html
-/sdcard/android/layout_tests/http/tests/navigation/reload-subframe-object.html
-/sdcard/android/layout_tests/http/tests/navigation/timerredirect-frames.html
-/sdcard/android/layout_tests/http/tests/navigation/slowtimerredirect-basic.html
-/sdcard/android/layout_tests/http/tests/navigation/window-open-adds-history-item2.html
-/sdcard/android/layout_tests/http/tests/navigation/document-location-onload.html
-/sdcard/android/layout_tests/http/tests/history/redirect-meta-refresh-2-seconds.html
-/sdcard/android/layout_tests/http/tests/history/redirect-js-location-assign-before-load.html
-/sdcard/android/layout_tests/http/tests/history/redirect-js-location-href-0-seconds.html
-/sdcard/android/layout_tests/http/tests/history/redirect-js-location-href-2-seconds.html
-/sdcard/android/layout_tests/http/tests/history/redirect-js-form-submit-0-seconds.html
-/sdcard/android/layout_tests/http/tests/history/redirect-js-form-submit-2-seconds.html
-/sdcard/android/layout_tests/http/tests/history/redirect-js-location-0-seconds.html
-/sdcard/android/layout_tests/http/tests/history/redirect-js-location-2-seconds.html
-/sdcard/android/layout_tests/http/tests/history/redirect-js-location-href-before-load.html
-/sdcard/android/layout_tests/http/tests/history/redirect-js-location-replace-0-seconds.html
-/sdcard/android/layout_tests/http/tests/history/redirect-js-location-replace-2-seconds.html
-/sdcard/android/layout_tests/http/tests/history/redirect-js-document-location-0-seconds.html
-/sdcard/android/layout_tests/http/tests/history/redirect-js-document-location-2-seconds.html
-/sdcard/android/layout_tests/http/tests/history/redirect-js-form-submit-before-load.html
-/sdcard/android/layout_tests/http/tests/history/redirect-js-location-assign-0-seconds.html
-/sdcard/android/layout_tests/http/tests/history/redirect-js-location-assign-2-seconds.html
-/sdcard/android/layout_tests/http/tests/history/redirect-js-location-before-load.html
-/sdcard/android/layout_tests/http/tests/history/redirect-js-location-replace-before-load.html
-/sdcard/android/layout_tests/http/tests/history/redirect-js-document-location-before-load.html
-/sdcard/android/layout_tests/http/tests/history/redirect-meta-refresh-0-seconds.html
-/sdcard/android/layout_tests/http/tests/cache/subresource-expiration.html
-/sdcard/android/layout_tests/http/tests/appcache/local-content.html
-/sdcard/android/layout_tests/http/tests/appcache/max-size.html
-/sdcard/android/layout_tests/http/tests/security/aboutBlank/xss-DENIED-set-opener.html
-/sdcard/android/layout_tests/http/tests/security/aboutBlank/xss-DENIED-navigate-opener-javascript-url.html
-/sdcard/android/layout_tests/http/tests/security/aboutBlank/xss-DENIED-navigate-opener-document-write.html
-/sdcard/android/layout_tests/http/tests/security/dataURL/xss-DENIED-from-javascript-url-window-open.html
-/sdcard/android/layout_tests/http/tests/security/dataURL/xss-DENIED-to-data-url-sub-frame-2-level.html
-/sdcard/android/layout_tests/http/tests/security/dataURL/xss-DENIED-from-data-url-in-foreign-domain-subframe.html
-/sdcard/android/layout_tests/http/tests/security/dataURL/xss-DENIED-from-data-url-in-foreign-domain-window-open.html
-/sdcard/android/layout_tests/http/tests/security/dataURL/xss-DENIED-to-data-url-in-foreign-domain-subframe-location-change.html
-/sdcard/android/layout_tests/http/tests/security/dataURL/xss-DENIED-from-data-url-sub-frame.html
-/sdcard/android/layout_tests/http/tests/security/dataURL/xss-DENIED-to-data-url-in-foreign-domain-subframe.html
-/sdcard/android/layout_tests/http/tests/security/dataURL/xss-DENIED-to-data-url-in-foreign-domain-window-open.html
-/sdcard/android/layout_tests/http/tests/security/dataURL/xss-DENIED-from-data-url-sub-frame-2-level.html
-/sdcard/android/layout_tests/http/tests/security/dataURL/xss-DENIED-to-data-url-sub-frame-uppercase.html
-/sdcard/android/layout_tests/http/tests/security/dataURL/xss-DENIED-to-data-url-window-open.html
-/sdcard/android/layout_tests/http/tests/security/dataURL/xss-DENIED-from-data-url-sub-frame-to-data-url-sub-frame.html
-/sdcard/android/layout_tests/http/tests/security/dataURL/xss-DENIED-from-data-url-to-data-url.html
-/sdcard/android/layout_tests/http/tests/security/dataURL/xss-DENIED-to-data-url-from-data-url.html
-/sdcard/android/layout_tests/http/tests/security/dataURL/xss-DENIED-to-data-url-sub-frame.html
-/sdcard/android/layout_tests/http/tests/security/clipboard/clipboard-file-access.html
-/sdcard/android/layout_tests/http/tests/security/isolatedWorld/image-prototype.html
-/sdcard/android/layout_tests/http/tests/security/isolatedWorld/body-properties.html
-/sdcard/android/layout_tests/http/tests/security/isolatedWorld/number-prototype.html
-/sdcard/android/layout_tests/http/tests/security/isolatedWorld/body-prototype.html
-/sdcard/android/layout_tests/http/tests/security/isolatedWorld/global-variables.html
-/sdcard/android/layout_tests/http/tests/security/isolatedWorld/location-prototype.html
-/sdcard/android/layout_tests/http/tests/security/isolatedWorld/image-properties.html
-/sdcard/android/layout_tests/http/tests/security/isolatedWorld/document-open.html
-/sdcard/android/layout_tests/http/tests/security/isolatedWorld/document-prototype.html
-/sdcard/android/layout_tests/http/tests/security/isolatedWorld/window-properties.html
-/sdcard/android/layout_tests/http/tests/security/isolatedWorld/location-properties.html
-/sdcard/android/layout_tests/http/tests/security/isolatedWorld/all-window-prototypes.html
-/sdcard/android/layout_tests/http/tests/security/isolatedWorld/click-event.html
-/sdcard/android/layout_tests/http/tests/security/isolatedWorld/all-window-properties.html
-/sdcard/android/layout_tests/http/tests/security/isolatedWorld/document-properties.html
-/sdcard/android/layout_tests/http/tests/security/isolatedWorld/string-prototype.html
-/sdcard/android/layout_tests/http/tests/security/isolatedWorld/object-prototype.html
-/sdcard/android/layout_tests/http/tests/security/listener/xss-window-onclick-addEventListener.html
-/sdcard/android/layout_tests/http/tests/security/listener/xss-window-onclick-shortcut.html
-/sdcard/android/layout_tests/http/tests/security/XFrameOptions/x-frame-options-deny-meta-tag-parent-same-origin-allow.html
-/sdcard/android/layout_tests/http/tests/security/XFrameOptions/x-frame-options-deny-meta-tag-parent-same-origin-deny.html
-/sdcard/android/layout_tests/http/tests/security/XFrameOptions/x-frame-options-deny-meta-tag-in-body.html
-/sdcard/android/layout_tests/http/tests/security/XFrameOptions/x-frame-options-deny-meta-tag.html
-/sdcard/android/layout_tests/http/tests/security/XFrameOptions/x-frame-options-parent-same-origin-allow.html
-/sdcard/android/layout_tests/http/tests/security/XFrameOptions/x-frame-options-parent-same-origin-deny.html
-/sdcard/android/layout_tests/http/tests/security/XFrameOptions/x-frame-options-deny.html
-/sdcard/android/layout_tests/http/tests/security/frameNavigation/xss-ALLOWED-targeted-subframe-navigation-change.html
-/sdcard/android/layout_tests/http/tests/security/frameNavigation/xss-DENIED-targeted-link-navigation.html
-/sdcard/android/layout_tests/http/tests/security/frameNavigation/xss-DENIED-plugin-navigation.html
-/sdcard/android/layout_tests/http/tests/security/javascriptURL/javascriptURL-execution-context-frame-src-setAttributeNode.html
-/sdcard/android/layout_tests/http/tests/security/javascriptURL/javascriptURL-execution-context-frame-src-setAttributeNodeNS.html
-/sdcard/android/layout_tests/http/tests/security/javascriptURL/javascriptURL-execution-context-iframe-src-setAttribute.html
-/sdcard/android/layout_tests/http/tests/security/javascriptURL/javascriptURL-execution-context-iframe-src-setAttributeNS.html
-/sdcard/android/layout_tests/http/tests/security/javascriptURL/javascriptURL-execution-context-iframe-src-setAttributeNode.html
-/sdcard/android/layout_tests/http/tests/security/javascriptURL/javascriptURL-execution-context-iframe-src-setAttributeNodeNS.html
-/sdcard/android/layout_tests/http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame-2-level.html
-/sdcard/android/layout_tests/http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-to-javscript-url.html
-/sdcard/android/layout_tests/http/tests/security/javascriptURL/xss-ALLOWED-to-javascript-url-from-javscript-url.html
-/sdcard/android/layout_tests/http/tests/security/javascriptURL/javascriptURL-execution-context-frame-src-getAttribute-value.html
-/sdcard/android/layout_tests/http/tests/security/javascriptURL/javascriptURL-execution-context-iframe-src-htmldom.html
-/sdcard/android/layout_tests/http/tests/security/javascriptURL/xss-ALLOWED-to-javascript-url-sub-frame-2-level.html
-/sdcard/android/layout_tests/http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-window-open.html
-/sdcard/android/layout_tests/http/tests/security/javascriptURL/xss-DENIED-from-javascript-url-in-foreign-domain-window-open.html
-/sdcard/android/layout_tests/http/tests/security/javascriptURL/javascriptURL-execution-context-frame-location-htmldom.html
-/sdcard/android/layout_tests/http/tests/security/javascriptURL/javascriptURL-execution-context-iframe-src-getAttribute-value.html
-/sdcard/android/layout_tests/http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame.html
-/sdcard/android/layout_tests/http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame-to-javascript-url-sub-frame.html
-/sdcard/android/layout_tests/http/tests/security/javascriptURL/xss-DENIED-to-javascript-url-in-foreign-domain-subframe.html
-/sdcard/android/layout_tests/http/tests/security/javascriptURL/xss-ALLOWED-to-javascript-url-window-open.html
-/sdcard/android/layout_tests/http/tests/security/javascriptURL/javascriptURL-execution-context-frame-src-htmldom.html
-/sdcard/android/layout_tests/http/tests/security/javascriptURL/xss-DENIED-to-javascript-url-in-foreign-domain-window-open.html
-/sdcard/android/layout_tests/http/tests/security/javascriptURL/xss-ALLOWED-to-javascript-url-sub-frame.html
-/sdcard/android/layout_tests/http/tests/security/javascriptURL/javascriptURL-execution-context-frame-src-setAttribute.html
-/sdcard/android/layout_tests/http/tests/security/javascriptURL/javascriptURL-execution-context-frame-src-setAttributeNS.html
-/sdcard/android/layout_tests/http/tests/security/javascriptURL/xss-DENIED-from-javascript-url-in-foreign-domain-subframe.html
-/sdcard/android/layout_tests/http/tests/security/originHeader/origin-header-for-empty.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/base-href-null-char.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/base-href-control-char.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/faux-script1.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/javascript-link-control-char.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/script-tag-convoluted.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/script-tag.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/dom-write-location.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/javascript-link-HTML-entities-control-char.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/object-embed-tag-control-char.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/javascript-link-null-char.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/anchor-url-dom-write-location.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/link-onclick-ampersand.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/script-tag-with-source-double-quote.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/script-tag-with-source-no-quote.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/base-href-safe3.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/http-equiv-utf-7-encoded.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/link-onclick-control-char.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/base-href-scheme-relative.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/script-tag-open-redirect.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/object-embed-tag-null-char.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/faux-script3.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/link-onclick-entities.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/script-tag-post.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/embed-tag-control-char.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/property-escape.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/script-tag-post-null-char.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/javascript-link-HTML-entities.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/script-tag-null-char.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/script-tag-addslashes-single-quote.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/dom-write-innerHTML.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/script-tag-with-source-entities.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/dom-write-location-inline-event.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/malformed-HTML.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/javascript-link-ampersand.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/link-onclick.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/anchor-url-dom-write-location-inline-event.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/base-href-safe2.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/anchor-url-dom-write-location-inline-event-null-char.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/dom-write-URL.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/script-tag-redirect.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/object-tag.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/script-tag-addslashes-backslash.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/dom-write-location-javascript-URL.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/embed-tag.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/faux-script2.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/anchor-url-dom-write-location-javascript-URL.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/script-tag-with-source-relative-scheme.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/img-onerror-tricky.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/javascript-link-HTML-entities-named.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/javascript-link-HTML-entities-null-char.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/script-tag-addslashes-null-char.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/link-opens-new-window.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/script-tag-utf-7-encoded.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/script-tag-utf-7.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/script-tag-with-source.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/script-tag-addslashes-double-quote.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/script-tag-safe.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/link-onclick-null-char.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/javascript-link.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/script-tag-control-char.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/script-tag-with-source-null-char.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/iframe-javascript-url.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/script-tag-src-redirect-safe.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/script-tag-with-source-control-char.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/get-from-iframe.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/inline-event-HTML-entities.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/post-from-iframe.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/script-tag-post-control-char.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/object-embed-tag.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/base-href.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/script-tag-entities.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/base-href-safe.html
-/sdcard/android/layout_tests/http/tests/security/xssAuditor/embed-tag-null-char.html
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-location-get-override.html
-/sdcard/android/layout_tests/http/tests/security/protocol-compare-case-insensitive.html
-/sdcard/android/layout_tests/http/tests/security/xss-DENIED-xsl-external-entity.xml
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-history-get-override.html
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-get-override.html
-/sdcard/android/layout_tests/http/tests/security/cross-origin-xsl-BLOCKED.html
-/sdcard/android/layout_tests/http/tests/security/local-iFrame-from-remote.html
-/sdcard/android/layout_tests/http/tests/security/credentials-in-referer.html
-/sdcard/android/layout_tests/http/tests/security/xss-DENIED-xsl-external-entity-redirect.xml
-/sdcard/android/layout_tests/http/tests/security/local-video-poster-from-remote.html
-/sdcard/android/layout_tests/http/tests/security/local-CSS-from-remote.html
-/sdcard/android/layout_tests/http/tests/security/local-user-CSS-from-remote.html
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-object-prototype.html
-/sdcard/android/layout_tests/http/tests/security/dataTransfer-set-data-file-url.html
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-enumeration.html
-/sdcard/android/layout_tests/http/tests/security/host-compare-case-insensitive.html
-/sdcard/android/layout_tests/http/tests/security/xss-DENIED-xsl-document.xml
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-protocol.html
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-private-browsing.html
-/sdcard/android/layout_tests/http/tests/security/feed-urls-from-remote.html
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-put.html
-/sdcard/android/layout_tests/http/tests/security/canvas-remote-read-svg-image.html
-/sdcard/android/layout_tests/http/tests/security/window-properties-clear-domain.html
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-callback-explicit-domain-DENY.html
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-get.html
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-port.html
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-document-direct.html
-/sdcard/android/layout_tests/http/tests/security/window-properties-pass.html
-/sdcard/android/layout_tests/http/tests/security/local-video-src-from-remote.html
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-history-put.html
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-child-explicit-domain.html
-/sdcard/android/layout_tests/http/tests/security/local-video-source-from-remote.html
-/sdcard/android/layout_tests/http/tests/security/drag-over-remote-content-iframe.html
-/sdcard/android/layout_tests/http/tests/security/local-JavaScript-from-remote.html
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-parent-explicit-domain.html
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-location-put.html
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-history-get.html
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-get-custom-property-cached.html
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-location-get.html
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-delete.html
-/sdcard/android/layout_tests/http/tests/security/xss-DENIED-xsl-document-redirect.xml
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-protocol-explicit-domain.html
-/sdcard/android/layout_tests/http/tests/security/window-properties-clear-port.html
-/sdcard/android/layout_tests/http/tests/security/frame-loading-via-document-write.html
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-port-explicit-domain.html
-/sdcard/android/layout_tests/http/tests/security/local-image-from-remote.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/workers/methods-async.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/workers/methods.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/web-apps/008.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/methods-async.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/methods.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/uri-resolution-opera-open-005.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/upload-onload-event.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/small-chunks-response-text.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/access-control-basic-non-simple-allow-async.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/uri-resolution-opera-open-009.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/frame-unload-abort-crash.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/access-control-basic-non-simple-deny-cached.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/xmlhttprequest-unsafe-redirect.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/uri-resolution-opera-open-006.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/upload-onprogress-event.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/access-control-basic-allow.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/cache-override.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/xhr-onunload.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/methods-lower-case.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/uri-resolution-opera-open-007.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/svg-created-by-xhr-disallowed-in-dashboard.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/uri-resolution-opera-open-004.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/xmlhttprequest-missing-file-exception.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/cookies.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/uri-resolution-opera-open-010.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/redirect-cross-origin-tripmine.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/origin-header-same-origin-get-sync.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/response-encoding.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/frame-load-cancelled-abort.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/upload-progress-events.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/xml-encoding.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/default-content-type-dashboard.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/abort-should-cancel-load.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/access-control-basic-whitelist-request-headers.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/uri-resolution-opera-open-008.html
-/sdcard/android/layout_tests/http/tests/loading/preload-img-test.html
-/sdcard/android/layout_tests/http/tests/loading/gmail-assert-on-load.html
-/sdcard/android/layout_tests/http/tests/loading/text-content-type-with-binary-extension.html
-/sdcard/android/layout_tests/http/tests/loading/basic.html
-/sdcard/android/layout_tests/http/tests/loading/slow-parsing-subframe.html
-/sdcard/android/layout_tests/http/tests/loading/deleted-host-in-resource-load-delegate-callback.html
-/sdcard/android/layout_tests/http/tests/loading/bad-scheme-subframe.html
-/sdcard/android/layout_tests/http/tests/loading/location-hash-reload-cycle.html
-/sdcard/android/layout_tests/http/tests/loading/bad-server-subframe.html
-/sdcard/android/layout_tests/http/tests/loading/empty-subframe.html
-/sdcard/android/layout_tests/http/tests/loading/redirect-methods.html
-/sdcard/android/layout_tests/media/video-error-does-not-exist.html
-/sdcard/android/layout_tests/media/audio-constructor.html
-/sdcard/android/layout_tests/media/video-play-empty-events.html
-/sdcard/android/layout_tests/media/video-append-source.html
-/sdcard/android/layout_tests/media/media-load-event.html
-/sdcard/android/layout_tests/media/unsupported-rtsp.html
-/sdcard/android/layout_tests/media/video-dom-autoplay.html
-/sdcard/android/layout_tests/media/video-currentTime-set2.html
-/sdcard/android/layout_tests/media/video-muted.html
-/sdcard/android/layout_tests/media/progress-event.html
-/sdcard/android/layout_tests/media/video-source-type.html
-/sdcard/android/layout_tests/media/audio-delete-while-step-button-clicked.html
-/sdcard/android/layout_tests/media/video-played-reset.html
-/sdcard/android/layout_tests/media/video-seek-past-end-playing.html
-/sdcard/android/layout_tests/media/video-dom-src.html
-/sdcard/android/layout_tests/media/remove-from-document.html
-/sdcard/android/layout_tests/media/video-loop.html
-/sdcard/android/layout_tests/media/video-src-change.html
-/sdcard/android/layout_tests/media/video-seekable.html
-/sdcard/android/layout_tests/media/video-played.html
-/sdcard/android/layout_tests/media/video-played-collapse.html
-/sdcard/android/layout_tests/media/video-click-dblckick-standalone.html
-/sdcard/android/layout_tests/media/video-can-play-type.html
-/sdcard/android/layout_tests/media/video-seeking.html
-/sdcard/android/layout_tests/media/video-controls-transformed.html
-/sdcard/android/layout_tests/media/video-controls-zoomed.html
-/sdcard/android/layout_tests/media/video-src-invalid-remove.html
-/sdcard/android/layout_tests/media/video-volume.html
-/sdcard/android/layout_tests/media/video-size.html
-/sdcard/android/layout_tests/media/controls-right-click-on-timebar.html
-/sdcard/android/layout_tests/media/video-currentTime.html
-/sdcard/android/layout_tests/media/audio-constructor-autobuffer.html
-/sdcard/android/layout_tests/media/broken-video.html
-/sdcard/android/layout_tests/media/video-buffered.html
-/sdcard/android/layout_tests/media/video-load-readyState.html
-/sdcard/android/layout_tests/media/video-load-networkState.html
-/sdcard/android/layout_tests/media/unsupported-tracks.html
-/sdcard/android/layout_tests/media/video-source-add-src.html
-/sdcard/android/layout_tests/media/video-seek-past-end-paused.html
-/sdcard/android/layout_tests/media/media-startTime.html
-/sdcard/android/layout_tests/media/video-source-error.html
-/sdcard/android/layout_tests/media/video-autoplay.html
-/sdcard/android/layout_tests/media/video-controls.html
-/sdcard/android/layout_tests/media/video-canvas-source.html
-/sdcard/android/layout_tests/media/video-timeupdate-during-playback.html
-/sdcard/android/layout_tests/media/video-currentTime-set.html
-/sdcard/android/layout_tests/media/controls-css-overload.html
-/sdcard/android/layout_tests/media/video-source-type-params.html
-/sdcard/android/layout_tests/media/event-attributes.html
-/sdcard/android/layout_tests/media/audio-data-url.html
-/sdcard/android/layout_tests/media/video-src-plus-source.html
-/sdcard/android/layout_tests/media/video-no-autoplay.html
-/sdcard/android/layout_tests/media/video-pause-empty-events.html
-/sdcard/android/layout_tests/media/video-document-types.html
-/sdcard/android/layout_tests/media/video-src-remove.html
-/sdcard/android/layout_tests/media/audio-delete-while-slider-thumb-clicked.html
-/sdcard/android/layout_tests/media/video-error-abort.html
-/sdcard/android/layout_tests/media/video-size-intrinsic-scale.html
-/sdcard/android/layout_tests/media/progress-event-total.html
-/sdcard/android/layout_tests/media/audio-constructor-src.html
-/sdcard/android/layout_tests/media/audio-mpeg-supported.html
-/sdcard/android/layout_tests/plugins/throw-on-dealloc.html
-/sdcard/android/layout_tests/plugins/invoke.html
-/sdcard/android/layout_tests/plugins/plugin-remove-subframe.html
-/sdcard/android/layout_tests/plugins/netscape-identifier-conversion.html
-/sdcard/android/layout_tests/plugins/netscape-invoke-browserfuncs.html
-/sdcard/android/layout_tests/plugins/call-as-function-test.html
-/sdcard/android/layout_tests/plugins/npruntime.html
-/sdcard/android/layout_tests/plugins/netscape-construct.html
-/sdcard/android/layout_tests/plugins/root-object-premature-delete-crash.html
-/sdcard/android/layout_tests/plugins/netscape-get-property-return-value.html
-/sdcard/android/layout_tests/plugins/mouse-events.html
-/sdcard/android/layout_tests/plugins/return-error-from-new-stream-doesnt-invoke-destroy-stream.html
-/sdcard/android/layout_tests/plugins/destroy-stream-twice.html
-/sdcard/android/layout_tests/plugins/jsobjc-simple.html
-/sdcard/android/layout_tests/plugins/embed-attributes-setting.html
-/sdcard/android/layout_tests/plugins/inner-html-display-none.html
-/sdcard/android/layout_tests/plugins/netscape-invoke-default.html
-/sdcard/android/layout_tests/plugins/undefined-property-crash.html
-/sdcard/android/layout_tests/plugins/netscape-plugin-map-data-to-src.html
-/sdcard/android/layout_tests/plugins/netscape-plugin-setwindow-size-2.html
-/sdcard/android/layout_tests/plugins/jsobjc-dom-wrappers.html
-/sdcard/android/layout_tests/plugins/plugin-javascript-access.html
-/sdcard/android/layout_tests/plugins/getintidentifier-special-values.html
-/sdcard/android/layout_tests/plugins/get-empty-url.html
-/sdcard/android/layout_tests/plugins/geturl-replace-query.html
-/sdcard/android/layout_tests/plugins/netscape-destroy-plugin-script-objects.html
-/sdcard/android/layout_tests/plugins/open-and-close-window-with-plugin.html
-/sdcard/android/layout_tests/plugins/netscape-enumerate.html
-/sdcard/android/layout_tests/plugins/get-url-that-the-resource-load-delegate-will-disallow.html
-/sdcard/android/layout_tests/plugins/netscape-plugin-setwindow-size.html
-/sdcard/android/layout_tests/plugins/embed-inside-object.html
-/sdcard/android/layout_tests/plugins/netscape-throw-exception.html
-/sdcard/android/layout_tests/plugins/get-url-with-blank-target.html
-/sdcard/android/layout_tests/plugins/bindings-test.html
-/sdcard/android/layout_tests/scrollbars/scrollbar-miss-mousemove-disabled.html
-/sdcard/android/layout_tests/security/set-form-autocomplete-attribute.html
-/sdcard/android/layout_tests/storage/execute-sql-args.html
-/sdcard/android/layout_tests/transitions/transition-shorthand-delay.html
-/sdcard/android/layout_tests/transitions/transition-drt-api-delay.html
-/sdcard/android/layout_tests/transitions/transition-hit-test.html
-/sdcard/android/layout_tests/transitions/opacity-transition-zindex.html
-/sdcard/android/layout_tests/transitions/interrupted-all-transition.html
-/sdcard/android/layout_tests/transitions/hang-with-bad-transition-list.html
-/sdcard/android/layout_tests/transitions/zero-duration-with-non-zero-delay-end.html
-/sdcard/android/layout_tests/transitions/remove-transition-style.html
-/sdcard/android/layout_tests/transitions/transition-hit-test-transform.html
-/sdcard/android/layout_tests/transitions/repeated-firing-background-color.html
-/sdcard/android/layout_tests/webarchive/loading/test-loading-archive.html
-/sdcard/android/layout_tests/wml/onenterforward-event.html
-/sdcard/android/layout_tests/wml/go-task-get-method-external-deck-with-href.html
-/sdcard/android/layout_tests/wml/option-element-onpick.html
-/sdcard/android/layout_tests/wml/enter-first-card-with-events.html
-/sdcard/android/layout_tests/wml/go-task-get-method-external-deck.html
-/sdcard/android/layout_tests/wml/go-task-get-method-same-deck.html
-/sdcard/android/layout_tests/wml/onenterforward-inline-event.html
-/sdcard/android/layout_tests/wml/ontimer-event.html
-/sdcard/android/layout_tests/wml/variable-reference-invalid-character.html
-/sdcard/android/layout_tests/wml/enter-card-with-events.html
-/sdcard/android/layout_tests/wml/ontimer-inline-event.html
-/sdcard/android/layout_tests/wml/select-element-variables.html
-/sdcard/android/layout_tests/wml/variable-reference-valid.html
-/sdcard/android/layout_tests/wml/access-target-deny.html
-/sdcard/android/layout_tests/wml/input-format.html
-/sdcard/android/layout_tests/wml/access-target.html
-/sdcard/android/layout_tests/wml/newcontext-same-deck.html
diff --git a/tests/DumpRenderTree/assets/results/layout_tests_nontext.txt b/tests/DumpRenderTree/assets/results/layout_tests_nontext.txt
deleted file mode 100644
index 665ef07..0000000
--- a/tests/DumpRenderTree/assets/results/layout_tests_nontext.txt
+++ /dev/null
@@ -1,4280 +0,0 @@
-/sdcard/android/layout_tests/accessibility/image-map1.html
-/sdcard/android/layout_tests/accessibility/aria-labelledby-on-input.html
-/sdcard/android/layout_tests/accessibility/aria-labelledby-stay-within.html
-/sdcard/android/layout_tests/accessibility/table-with-rules.html
-/sdcard/android/layout_tests/accessibility/aria-describedby-on-input.html
-/sdcard/android/layout_tests/accessibility/table-detection.html
-/sdcard/android/layout_tests/accessibility/table-with-aria-role.html
-/sdcard/android/layout_tests/accessibility/image-map2.html
-/sdcard/android/layout_tests/accessibility/table-cell-spans.html
-/sdcard/android/layout_tests/accessibility/table-cells.html
-/sdcard/android/layout_tests/accessibility/lists.html
-/sdcard/android/layout_tests/accessibility/plugin.html
-/sdcard/android/layout_tests/accessibility/table-sections.html
-/sdcard/android/layout_tests/accessibility/table-one-cell.html
-/sdcard/android/layout_tests/accessibility/internal-link-anchors2.html
-/sdcard/android/layout_tests/accessibility/radio-button-group-members.html
-/sdcard/android/layout_tests/accessibility/table-attributes.html
-/sdcard/android/layout_tests/accessibility/input-slider.html
-/sdcard/android/layout_tests/accessibility/aria-tables.html
-/sdcard/android/layout_tests/accessibility/legend.html
-/sdcard/android/layout_tests/accessibility/aria-roles.html
-/sdcard/android/layout_tests/animations/animation-drt-api-multiple-keyframes.html
-/sdcard/android/layout_tests/animations/animation-drt-api.html
-/sdcard/android/layout_tests/compositing/repaint/content-into-overflow.html
-/sdcard/android/layout_tests/compositing/repaint/overflow-into-content.html
-/sdcard/android/layout_tests/compositing/repaint/become-overlay-composited-layer.html
-/sdcard/android/layout_tests/compositing/repaint/layer-repaint-rects.html
-/sdcard/android/layout_tests/compositing/overflow/ancestor-overflow.html
-/sdcard/android/layout_tests/compositing/overflow/overflow-scroll.html
-/sdcard/android/layout_tests/compositing/overflow/overflow-positioning.html
-/sdcard/android/layout_tests/compositing/overflow/parent-overflow.html
-/sdcard/android/layout_tests/compositing/color-matching/image-color-matching.html
-/sdcard/android/layout_tests/compositing/geometry/root-layer-update.html
-/sdcard/android/layout_tests/compositing/geometry/outline-change.html
-/sdcard/android/layout_tests/compositing/reflections/reflection-on-composited.html
-/sdcard/android/layout_tests/compositing/self-painting-layers.html
-/sdcard/android/layout_tests/compositing/direct-image-compositing.html
-/sdcard/android/layout_tests/compositing/layers-inside-overflow-scroll.html
-/sdcard/android/layout_tests/compositing/generated-content.html
-/sdcard/android/layout_tests/compositing/sibling-positioning.html
-/sdcard/android/layout_tests/css1/color_and_background/background_color.html
-/sdcard/android/layout_tests/css1/color_and_background/color.html
-/sdcard/android/layout_tests/css1/color_and_background/background.html
-/sdcard/android/layout_tests/css1/color_and_background/background_repeat.html
-/sdcard/android/layout_tests/css1/color_and_background/background_image.html
-/sdcard/android/layout_tests/css1/color_and_background/background_position.html
-/sdcard/android/layout_tests/css1/color_and_background/background_attachment.html
-/sdcard/android/layout_tests/css1/pseudo/firstline.html
-/sdcard/android/layout_tests/css1/pseudo/pseudo_elements_in_selectors.html
-/sdcard/android/layout_tests/css1/pseudo/multiple_pseudo_elements.html
-/sdcard/android/layout_tests/css1/pseudo/firstletter.html
-/sdcard/android/layout_tests/css1/pseudo/anchor.html
-/sdcard/android/layout_tests/css1/text_properties/text_align.html
-/sdcard/android/layout_tests/css1/text_properties/line_height.html
-/sdcard/android/layout_tests/css1/text_properties/text_transform.html
-/sdcard/android/layout_tests/css1/text_properties/word_spacing.html
-/sdcard/android/layout_tests/css1/text_properties/letter_spacing.html
-/sdcard/android/layout_tests/css1/text_properties/vertical_align.html
-/sdcard/android/layout_tests/css1/text_properties/text_indent.html
-/sdcard/android/layout_tests/css1/text_properties/text_decoration.html
-/sdcard/android/layout_tests/css1/basic/containment.html
-/sdcard/android/layout_tests/css1/basic/id_as_selector.html
-/sdcard/android/layout_tests/css1/basic/comments.html
-/sdcard/android/layout_tests/css1/basic/class_as_selector.html
-/sdcard/android/layout_tests/css1/basic/contextual_selectors.html
-/sdcard/android/layout_tests/css1/basic/inheritance.html
-/sdcard/android/layout_tests/css1/basic/grouping.html
-/sdcard/android/layout_tests/css1/font_properties/font_weight.html
-/sdcard/android/layout_tests/css1/font_properties/font_size.html
-/sdcard/android/layout_tests/css1/font_properties/font.html
-/sdcard/android/layout_tests/css1/font_properties/font_style.html
-/sdcard/android/layout_tests/css1/font_properties/font_family.html
-/sdcard/android/layout_tests/css1/font_properties/font_variant.html
-/sdcard/android/layout_tests/css1/units/percentage_units.html
-/sdcard/android/layout_tests/css1/units/color_units.html
-/sdcard/android/layout_tests/css1/units/length_units.html
-/sdcard/android/layout_tests/css1/units/urls.html
-/sdcard/android/layout_tests/css1/cascade/important.html
-/sdcard/android/layout_tests/css1/cascade/cascade_order.html
-/sdcard/android/layout_tests/css1/box_properties/border_width.html
-/sdcard/android/layout_tests/css1/box_properties/margin.html
-/sdcard/android/layout_tests/css1/box_properties/width.html
-/sdcard/android/layout_tests/css1/box_properties/padding_left.html
-/sdcard/android/layout_tests/css1/box_properties/margin_left_inline.html
-/sdcard/android/layout_tests/css1/box_properties/clear.html
-/sdcard/android/layout_tests/css1/box_properties/border_left_width.html
-/sdcard/android/layout_tests/css1/box_properties/margin_left.html
-/sdcard/android/layout_tests/css1/box_properties/padding_top.html
-/sdcard/android/layout_tests/css1/box_properties/padding_bottom.html
-/sdcard/android/layout_tests/css1/box_properties/border_style_inline.html
-/sdcard/android/layout_tests/css1/box_properties/border_top_width_inline.html
-/sdcard/android/layout_tests/css1/box_properties/border_top_inline.html
-/sdcard/android/layout_tests/css1/box_properties/border_style.html
-/sdcard/android/layout_tests/css1/box_properties/border_top.html
-/sdcard/android/layout_tests/css1/box_properties/margin_bottom_inline.html
-/sdcard/android/layout_tests/css1/box_properties/border_bottom_width.html
-/sdcard/android/layout_tests/css1/box_properties/margin_bottom.html
-/sdcard/android/layout_tests/css1/box_properties/float_elements_in_series.html
-/sdcard/android/layout_tests/css1/box_properties/float_on_text_elements.html
-/sdcard/android/layout_tests/css1/box_properties/padding.html
-/sdcard/android/layout_tests/css1/box_properties/border_right_width_inline.html
-/sdcard/android/layout_tests/css1/box_properties/border_right_inline.html
-/sdcard/android/layout_tests/css1/box_properties/border_right_width.html
-/sdcard/android/layout_tests/css1/box_properties/margin_right.html
-/sdcard/android/layout_tests/css1/box_properties/border_width_inline.html
-/sdcard/android/layout_tests/css1/box_properties/border_inline.html
-/sdcard/android/layout_tests/css1/box_properties/clear_float.html
-/sdcard/android/layout_tests/css1/box_properties/border.html
-/sdcard/android/layout_tests/css1/box_properties/padding_left_inline.html
-/sdcard/android/layout_tests/css1/box_properties/border_left_width_inline.html
-/sdcard/android/layout_tests/css1/box_properties/border_left_inline.html
-/sdcard/android/layout_tests/css1/box_properties/padding_top_inline.html
-/sdcard/android/layout_tests/css1/box_properties/border_left.html
-/sdcard/android/layout_tests/css1/box_properties/padding_bottom_inline.html
-/sdcard/android/layout_tests/css1/box_properties/margin_top_inline.html
-/sdcard/android/layout_tests/css1/box_properties/border_top_width.html
-/sdcard/android/layout_tests/css1/box_properties/border_bottom_width_inline.html
-/sdcard/android/layout_tests/css1/box_properties/acid_test.html
-/sdcard/android/layout_tests/css1/box_properties/border_bottom_inline.html
-/sdcard/android/layout_tests/css1/box_properties/margin_top.html
-/sdcard/android/layout_tests/css1/box_properties/border_bottom.html
-/sdcard/android/layout_tests/css1/box_properties/padding_right_inline.html
-/sdcard/android/layout_tests/css1/box_properties/float_margin.html
-/sdcard/android/layout_tests/css1/box_properties/padding_right.html
-/sdcard/android/layout_tests/css1/box_properties/padding_inline.html
-/sdcard/android/layout_tests/css1/box_properties/float.html
-/sdcard/android/layout_tests/css1/box_properties/height.html
-/sdcard/android/layout_tests/css1/box_properties/margin_right_inline.html
-/sdcard/android/layout_tests/css1/box_properties/border_color_inline.html
-/sdcard/android/layout_tests/css1/box_properties/border_right.html
-/sdcard/android/layout_tests/css1/box_properties/border_color.html
-/sdcard/android/layout_tests/css1/box_properties/margin_inline.html
-/sdcard/android/layout_tests/css1/conformance/forward_compatible_parsing.html
-/sdcard/android/layout_tests/css1/formatting_model/floating_elements.html
-/sdcard/android/layout_tests/css1/formatting_model/horizontal_formatting.html
-/sdcard/android/layout_tests/css1/formatting_model/vertical_formatting.html
-/sdcard/android/layout_tests/css1/formatting_model/height_of_lines.html
-/sdcard/android/layout_tests/css1/formatting_model/inline_elements.html
-/sdcard/android/layout_tests/css1/formatting_model/canvas.html
-/sdcard/android/layout_tests/css1/formatting_model/replaced_elements.html
-/sdcard/android/layout_tests/css1/classification/list_style_type.html
-/sdcard/android/layout_tests/css1/classification/list_style_image.html
-/sdcard/android/layout_tests/css1/classification/list_style_position.html
-/sdcard/android/layout_tests/css1/classification/display.html
-/sdcard/android/layout_tests/css1/classification/list_style.html
-/sdcard/android/layout_tests/css1/classification/white_space.html
-/sdcard/android/layout_tests/css2.1/t040103-ident-03-c.html
-/sdcard/android/layout_tests/css2.1/t0804-c5509-padn-l-00-b-ag.html
-/sdcard/android/layout_tests/css2.1/t1205-c563-list-type-00-b.html
-/sdcard/android/layout_tests/css2.1/t090402-c42-ibx-pad-00-d-ag.html
-/sdcard/android/layout_tests/css2.1/t120401-scope-00-b.html
-/sdcard/android/layout_tests/css2.1/t010403-shand-border-00-c.html
-/sdcard/android/layout_tests/css2.1/t0805-c5518-ibrdr-t-00-a.html
-/sdcard/android/layout_tests/css2.1/t1202-counter-03-b.html
-/sdcard/android/layout_tests/css2.1/t1008-c44-ln-box-00-d-ag.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-14-d.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-34-d.html
-/sdcard/android/layout_tests/css2.1/t1204-implied-00-b.html
-/sdcard/android/layout_tests/css2.1/t1001-abs-pos-cb-03-b.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-54-d.html
-/sdcard/android/layout_tests/css2.1/t100801-c548-ln-ht-00-c-a.html
-/sdcard/android/layout_tests/css2.1/t0905-c5526-fltclr-00-c-ag.html
-/sdcard/android/layout_tests/css2.1/bogus-color-span.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-74-d.html
-/sdcard/android/layout_tests/css2.1/t0803-c5504-imrgn-l-03-b-a.html
-/sdcard/android/layout_tests/css2.1/t140201-c534-bgreps-04-c-ag.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-94-d.html
-/sdcard/android/layout_tests/css2.1/t0803-c5502-imrgn-r-03-b-a.html
-/sdcard/android/layout_tests/css2.1/t040307-syntax-01-b.html
-/sdcard/android/layout_tests/css2.1/t100801-c548-ln-ht-04-d-ag.html
-/sdcard/android/layout_tests/css2.1/t1508-c527-font-06-b.html
-/sdcard/android/layout_tests/css2.1/t040306-c63-color-00-b-ag.html
-/sdcard/android/layout_tests/css2.1/t1202-counters-02-b.html
-/sdcard/android/layout_tests/css2.1/t080301-c411-vt-mrgn-00-b.html
-/sdcard/android/layout_tests/css2.1/t010403-shand-font-03-b.html
-/sdcard/android/layout_tests/css2.1/t051103-c21-focus-ln-00-e-i.html
-/sdcard/android/layout_tests/css2.1/t120403-display-none-00-c.html
-/sdcard/android/layout_tests/css2.1/t0805-c5512-brdr-rw-01-b-g.html
-/sdcard/android/layout_tests/css2.1/t040103-ident-12-c.html
-/sdcard/android/layout_tests/css2.1/t0805-c5515-ibrdr-00-b.html
-/sdcard/android/layout_tests/css2.1/t0805-c5520-brdr-b-00-a.html
-/sdcard/android/layout_tests/css2.1/t1505-c524-font-var-00-b.html
-/sdcard/android/layout_tests/css2.1/t0509-c15-ids-00-a.html
-/sdcard/android/layout_tests/css2.1/t060403-c21-pseu-cls-00-e-i.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-03-d.html
-/sdcard/android/layout_tests/css2.1/t1202-counter-12-b.html
-/sdcard/android/layout_tests/css2.1/t0402-c71-fwd-parsing-04-f.html
-/sdcard/android/layout_tests/css2.1/t040303-c62-percent-00-b-ag.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-23-d.html
-/sdcard/android/layout_tests/css2.1/t140201-c535-bg-fixd-00-b-g.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-43-d.html
-/sdcard/android/layout_tests/css2.1/t1204-increment-02-c-o.html
-/sdcard/android/layout_tests/css2.1/t0602-c13-inh-underlin-00-e.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-63-d.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-83-d.html
-/sdcard/android/layout_tests/css2.1/t1202-counter-16-f.html
-/sdcard/android/layout_tests/css2.1/t040302-c61-phys-len-00-b.html
-/sdcard/android/layout_tests/css2.1/t0805-c5516-ibrdr-c-00-a.html
-/sdcard/android/layout_tests/css2.1/t0805-c5521-brdr-l-01-e.html
-/sdcard/android/layout_tests/css2.1/t100801-c544-valgn-03-d-agi.html
-/sdcard/android/layout_tests/css2.1/t040103-escapes-06-b.html
-/sdcard/android/layout_tests/css2.1/t0402-syntax-03-f.html
-/sdcard/android/layout_tests/css2.1/t050803-c14-classes-00-e.html
-/sdcard/android/layout_tests/css2.1/t140201-c537-bgfxps-00-c-ag.html
-/sdcard/android/layout_tests/css2.1/t1002-c5523-width-02-b-g.html
-/sdcard/android/layout_tests/css2.1/t1004-c5524-width-00-b-g.html
-/sdcard/android/layout_tests/css2.1/t1202-counters-11-b.html
-/sdcard/android/layout_tests/css2.1/t0803-c5504-imrgn-l-06-b-ag.html
-/sdcard/android/layout_tests/css2.1/t0805-c5522-brdr-02-e.html
-/sdcard/android/layout_tests/css2.1/t0511-c21-pseud-anch-00-e-i.html
-/sdcard/android/layout_tests/css2.1/t0804-c5508-ipadn-b-01-f-a.html
-/sdcard/android/layout_tests/css2.1/t0803-c5502-imrgn-r-04-b-ag.html
-/sdcard/android/layout_tests/css2.1/t040103-ident-01-c.html
-/sdcard/android/layout_tests/css2.1/t040102-keywords-00-b.html
-/sdcard/android/layout_tests/css2.1/t0505-c16-descendant-02-e.html
-/sdcard/android/layout_tests/css2.1/t1507-c526-font-sz-03-f-a.html
-/sdcard/android/layout_tests/css2.1/t1202-counters-09-b.html
-/sdcard/android/layout_tests/css2.1/t1204-root-e.html
-/sdcard/android/layout_tests/css2.1/t0905-c414-flt-fit-01-d-g.html
-/sdcard/android/layout_tests/css2.1/t1202-counter-01-b.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-12-d.html
-/sdcard/android/layout_tests/css2.1/t090501-c5525-flt-r-00-b-g.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-32-d.html
-/sdcard/android/layout_tests/css2.1/t1001-abs-pos-cb-01-b.html
-/sdcard/android/layout_tests/css2.1/t1004-c43-rpl-bbx-00-d-ag.html
-/sdcard/android/layout_tests/css2.1/t140201-c534-bgre-01-b-ag.html
-/sdcard/android/layout_tests/css2.1/t0804-c5509-ipadn-l-02-b-ag.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-52-d.html
-/sdcard/android/layout_tests/css2.1/t0805-c5512-brdr-rw-02-b.html
-/sdcard/android/layout_tests/css2.1/t040109-c17-comments-00-b.html
-/sdcard/android/layout_tests/css2.1/t0804-c5507-ipadn-r-00-b-ag.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-72-d.html
-/sdcard/android/layout_tests/css2.1/t140201-c534-bgreps-01-c-ag.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-92-d.html
-/sdcard/android/layout_tests/css2.1/t0905-c414-flt-01-d-g.html
-/sdcard/android/layout_tests/css2.1/t100801-c548-ln-ht-01-b-ag.html
-/sdcard/android/layout_tests/css2.1/t090501-c414-flt-03-b-g.html
-/sdcard/android/layout_tests/css2.1/t1204-multiple-01-c.html
-/sdcard/android/layout_tests/css2.1/t0803-c5505-mrgn-03-c-ag.html
-/sdcard/android/layout_tests/css2.1/t1508-c527-font-04-b.html
-/sdcard/android/layout_tests/css2.1/t1202-counters-00-b.html
-/sdcard/android/layout_tests/css2.1/t1602-c43-center-00-d-ag.html
-/sdcard/android/layout_tests/css2.1/t140201-c532-bgcolor-00-a.html
-/sdcard/android/layout_tests/css2.1/t0803-c5504-mrgn-l-03-c.html
-/sdcard/android/layout_tests/css2.1/t010403-shand-font-01-b.html
-/sdcard/android/layout_tests/css2.1/t1005-c5524-width-01-b-g.html
-/sdcard/android/layout_tests/css2.1/t1601-c547-indent-01-d.html
-/sdcard/android/layout_tests/css2.1/t040103-ident-10-c.html
-/sdcard/android/layout_tests/css2.1/t090501-c414-flt-01-b.html
-/sdcard/android/layout_tests/css2.1/t0803-c5505-mrgn-02-c.html
-/sdcard/android/layout_tests/css2.1/t0905-c414-flt-04-c.html
-/sdcard/android/layout_tests/css2.1/t051103-dom-hover-01-c-io.html
-/sdcard/android/layout_tests/css2.1/t1604-c542-letter-sp-00-b-a.html
-/sdcard/android/layout_tests/css2.1/t040103-ident-08-c.html
-/sdcard/android/layout_tests/css2.1/t120401-scope-02-c.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-01-d.html
-/sdcard/android/layout_tests/css2.1/t0402-c71-fwd-parsing-02-f.html
-/sdcard/android/layout_tests/css2.1/t1204-reset-00-c-o.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-21-d.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-41-d.html
-/sdcard/android/layout_tests/css2.1/t0905-c5525-fltwidth-01-c-g.html
-/sdcard/android/layout_tests/css2.1/t1507-c526-font-sz-00-b.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-61-d.html
-/sdcard/android/layout_tests/css2.1/t1202-counter-08-b.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-81-d.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-19-d.html
-/sdcard/android/layout_tests/css2.1/t040103-escapes-04-b.html
-/sdcard/android/layout_tests/css2.1/t1604-c541-word-sp-01-b-a.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-39-d.html
-/sdcard/android/layout_tests/css2.1/t1001-abs-pos-cb-08-b.html
-/sdcard/android/layout_tests/css2.1/t0402-syntax-01-f.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-59-d.html
-/sdcard/android/layout_tests/css2.1/t1205-c565-list-pos-00-b.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-79-d.html
-/sdcard/android/layout_tests/css2.1/t1508-c527-font-10-c.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-99-d.html
-/sdcard/android/layout_tests/css2.1/t0803-c5502-imrgn-r-01-b-ag.html
-/sdcard/android/layout_tests/css2.1/t040306-syntax-01-f.html
-/sdcard/android/layout_tests/css2.1/t1507-c526-font-sz-01-b-a.html
-/sdcard/android/layout_tests/css2.1/t040105-atrule-04-b.html
-/sdcard/android/layout_tests/css2.1/t0505-c16-descendant-00-e.html
-/sdcard/android/layout_tests/css2.1/t0805-c5513-brdr-bw-02-b.html
-/sdcard/android/layout_tests/css2.1/t0805-c5519-brdr-r-01-e.html
-/sdcard/android/layout_tests/css2.1/t1202-counters-07-b.html
-/sdcard/android/layout_tests/css2.1/t0804-c5510-padn-00-b-ag.html
-/sdcard/android/layout_tests/css2.1/t0805-c5517-ibrdr-s-00-a.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-10-d.html
-/sdcard/android/layout_tests/css2.1/t040105-import-00-b.html
-/sdcard/android/layout_tests/css2.1/t0804-c5509-ipadn-l-03-b-a.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-30-d.html
-/sdcard/android/layout_tests/css2.1/t0805-c5514-brdr-lw-02-b.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-50-d.html
-/sdcard/android/layout_tests/css2.1/t0804-c5507-ipadn-r-03-b-a.html
-/sdcard/android/layout_tests/css2.1/t1008-c44-ln-box-02-d-ag.html
-/sdcard/android/layout_tests/css2.1/t0805-c5512-brdr-rw-00-b.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-70-d.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-08-d.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-90-d.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-28-d.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-48-d.html
-/sdcard/android/layout_tests/css2.1/t0805-c5513-brdr-bw-01-b-g.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-68-d.html
-/sdcard/android/layout_tests/css2.1/t1402-c45-bg-canvas-00-b.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-88-d.html
-/sdcard/android/layout_tests/css2.1/t1508-c527-font-02-b.html
-/sdcard/android/layout_tests/css2.1/t0805-c5521-ibrdr-l-00-a.html
-/sdcard/android/layout_tests/css2.1/t0805-c5522-brdr-00-b.html
-/sdcard/android/layout_tests/css2.1/t1606-c562-white-sp-00-b-ag.html
-/sdcard/android/layout_tests/css2.1/t0905-c414-flt-02-c.html
-/sdcard/android/layout_tests/css2.1/t100801-c544-valgn-00-a-ag.html
-/sdcard/android/layout_tests/css2.1/t040103-ident-06-c.html
-/sdcard/android/layout_tests/css2.1/t0402-c71-fwd-parsing-00-f.html
-/sdcard/android/layout_tests/css2.1/t1204-reset-02-c-o.html
-/sdcard/android/layout_tests/css2.1/t0602-c13-inheritance-00-e.html
-/sdcard/android/layout_tests/css2.1/t090501-c414-flt-ln-02-d.html
-/sdcard/android/layout_tests/css2.1/t1205-c566-list-stl-01-c-g.html
-/sdcard/android/layout_tests/css2.1/t1202-counter-06-b.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-17-d.html
-/sdcard/android/layout_tests/css2.1/t100304-c43-rpl-bbx-00-d-g.html
-/sdcard/android/layout_tests/css2.1/t0803-c5504-mrgn-l-00-c-ag.html
-/sdcard/android/layout_tests/css2.1/t1205-c566-list-stl-00-e-ag.html
-/sdcard/android/layout_tests/css2.1/t0905-c5525-fltwidth-03-c-g.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-37-d.html
-/sdcard/android/layout_tests/css2.1/t1001-abs-pos-cb-06-b.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-57-d.html
-/sdcard/android/layout_tests/css2.1/t0804-c5510-padn-02-f.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-77-d.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-97-d.html
-/sdcard/android/layout_tests/css2.1/t0803-c5504-imrgn-l-00-b-ag.html
-/sdcard/android/layout_tests/css2.1/t090204-display-change-01-b-ao.html
-/sdcard/android/layout_tests/css2.1/t040302-c61-ex-len-00-b-a.html
-/sdcard/android/layout_tests/css2.1/t040105-atrule-02-b.html
-/sdcard/android/layout_tests/css2.1/t0805-c5513-brdr-bw-00-b.html
-/sdcard/android/layout_tests/css2.1/t1508-c527-font-09-b.html
-/sdcard/android/layout_tests/css2.1/t1202-counters-05-b.html
-/sdcard/android/layout_tests/css2.1/t0803-c5502-mrgn-r-02-c.html
-/sdcard/android/layout_tests/css2.1/t0803-c5502-imrgn-r-06-b-ag.html
-/sdcard/android/layout_tests/css2.1/t0804-c5507-padn-r-01-c-a.html
-/sdcard/android/layout_tests/css2.1/t090501-c414-flt-00-d.html
-/sdcard/android/layout_tests/css2.1/t1202-counters-17-d.html
-/sdcard/android/layout_tests/css2.1/t0803-c5504-mrgn-l-01-c-a.html
-/sdcard/android/layout_tests/css2.1/t0805-c5514-brdr-lw-00-b.html
-/sdcard/android/layout_tests/css2.1/t140201-c536-bgpos-01-b-ag.html
-/sdcard/android/layout_tests/css2.1/t100303-c412-blockw-00-d-ag.html
-/sdcard/android/layout_tests/css2.1/t120401-scope-04-d.html
-/sdcard/android/layout_tests/css2.1/t0804-c5506-ipadn-t-01-b-a.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-06-d.html
-/sdcard/android/layout_tests/css2.1/t1202-counter-15-b.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-26-d.html
-/sdcard/android/layout_tests/css2.1/t0805-c5521-brdr-l-00-a.html
-/sdcard/android/layout_tests/css2.1/t0805-c5511-brdr-tw-02-b.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-46-d.html
-/sdcard/android/layout_tests/css2.1/t0804-c5507-ipadn-r-02-b-ag.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-66-d.html
-/sdcard/android/layout_tests/css2.1/t140201-c534-bgreps-03-c-ag.html
-/sdcard/android/layout_tests/css2.1/t100801-c544-valgn-02-d-agi.html
-/sdcard/android/layout_tests/css2.1/t0804-c5509-ipadn-l-04-f-ag.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-86-d.html
-/sdcard/android/layout_tests/css2.1/t0805-c5512-ibrdr-rw-00-a.html
-/sdcard/android/layout_tests/css2.1/t1508-c527-font-00-b.html
-/sdcard/android/layout_tests/css2.1/t0905-c5525-fltblck-01-d.html
-/sdcard/android/layout_tests/css2.1/t0402-syntax-06-f.html
-/sdcard/android/layout_tests/css2.1/t100801-c548-ln-ht-03-d-ag.html
-/sdcard/android/layout_tests/css2.1/t0805-c5515-brdr-w-00-a.html
-/sdcard/android/layout_tests/css2.1/t051202-c24-first-lttr-00-b.html
-/sdcard/android/layout_tests/css2.1/t0511-c21-pseud-link-02-e.html
-/sdcard/android/layout_tests/css2.1/t0804-c5510-padn-01-e-a.html
-/sdcard/android/layout_tests/css2.1/t0905-c5525-fltinln-00-c-ag.html
-/sdcard/android/layout_tests/css2.1/t1202-counters-14-b.html
-/sdcard/android/layout_tests/css2.1/t0805-c5518-brdr-t-01-e.html
-/sdcard/android/layout_tests/css2.1/t040105-atkeyw-01-b.html
-/sdcard/android/layout_tests/css2.1/t0805-c5511-brdr-tw-01-b-g.html
-/sdcard/android/layout_tests/css2.1/t040103-ident-04-c.html
-/sdcard/android/layout_tests/css2.1/t1205-c563-list-type-01-b.html
-/sdcard/android/layout_tests/css2.1/t1202-counters-18-f.html
-/sdcard/android/layout_tests/css2.1/t0509-id-sel-syntax-01-f.html
-/sdcard/android/layout_tests/css2.1/t100801-c544-valgn-01-d-ag.html
-/sdcard/android/layout_tests/css2.1/t090501-c414-flt-ln-00-d.html
-/sdcard/android/layout_tests/css2.1/t1601-c547-indent-00-b-a.html
-/sdcard/android/layout_tests/css2.1/t1202-counter-04-b.html
-/sdcard/android/layout_tests/css2.1/t0905-c5525-flthw-00-c-g.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-15-d.html
-/sdcard/android/layout_tests/css2.1/t0805-c5522-brdr-01-b-g.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-35-d.html
-/sdcard/android/layout_tests/css2.1/t040103-escapes-00-b.html
-/sdcard/android/layout_tests/css2.1/t1001-abs-pos-cb-04-b.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-55-d.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-75-d.html
-/sdcard/android/layout_tests/css2.1/t1205-c564-list-img-00-b-g.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-95-d.html
-/sdcard/android/layout_tests/css2.1/t120403-visibility-00-c.html
-/sdcard/android/layout_tests/css2.1/t0803-c5502-imrgn-r-02-b-a.html
-/sdcard/android/layout_tests/css2.1/t051103-c21-activ-ln-00-e-i.html
-/sdcard/android/layout_tests/css2.1/t0801-c412-hz-box-00-b-a.html
-/sdcard/android/layout_tests/css2.1/t090501-c414-flt-02-d-g.html
-/sdcard/android/layout_tests/css2.1/t1605-c545-txttrans-00-b-ag.html
-/sdcard/android/layout_tests/css2.1/t040105-atrule-00-b.html
-/sdcard/android/layout_tests/css2.1/t100801-c548-leadin-00-d-a.html
-/sdcard/android/layout_tests/css2.1/t0803-c5504-imrgn-l-05-b-ag.html
-/sdcard/android/layout_tests/css2.1/t0804-c5508-ipadn-b-03-b-a.html
-/sdcard/android/layout_tests/css2.1/t1508-c527-font-07-b.html
-/sdcard/android/layout_tests/css2.1/t1202-counters-03-b.html
-/sdcard/android/layout_tests/css2.1/t040103-ident-13-c.html
-/sdcard/android/layout_tests/css2.1/t1204-order-01-d.html
-/sdcard/android/layout_tests/css2.1/t0804-c5510-ipadn-00-b-ag.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-04-d.html
-/sdcard/android/layout_tests/css2.1/t1202-counter-13-b.html
-/sdcard/android/layout_tests/css2.1/t140201-c534-bgre-00-b-ag.html
-/sdcard/android/layout_tests/css2.1/t1504-c523-font-style-00-b.html
-/sdcard/android/layout_tests/css2.1/t0804-c5509-ipadn-l-01-b-ag.html
-/sdcard/android/layout_tests/css2.1/t0803-c5502-mrgn-r-01-c-a.html
-/sdcard/android/layout_tests/css2.1/t1204-increment-01-c-o.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-24-d.html
-/sdcard/android/layout_tests/css2.1/t0805-c5511-brdr-tw-00-b.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-44-d.html
-/sdcard/android/layout_tests/css2.1/t140201-c534-bgreps-00-c-ag.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-64-d.html
-/sdcard/android/layout_tests/css2.1/t1204-implied-02-d.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-84-d.html
-/sdcard/android/layout_tests/css2.1/t0805-c5521-brdr-l-02-e.html
-/sdcard/android/layout_tests/css2.1/t040103-escapes-07-b.html
-/sdcard/android/layout_tests/css2.1/t0804-c5507-padn-r-02-f.html
-/sdcard/android/layout_tests/css2.1/t0402-syntax-04-f.html
-/sdcard/android/layout_tests/css2.1/t1002-c5523-width-01-b-g.html
-/sdcard/android/layout_tests/css2.1/t0805-c5519-brdr-r-00-a.html
-/sdcard/android/layout_tests/css2.1/t0511-c21-pseud-link-00-e.html
-/sdcard/android/layout_tests/css2.1/t1202-counters-12-b.html
-/sdcard/android/layout_tests/css2.1/t040103-ident-02-c.html
-/sdcard/android/layout_tests/css2.1/t040102-keywords-01-b.html
-/sdcard/android/layout_tests/css2.1/t0803-c5503-imrgn-b-00-b-a.html
-/sdcard/android/layout_tests/css2.1/t0805-c5513-ibrdr-bw-00-a.html
-/sdcard/android/layout_tests/css2.1/css1_forward_compatible_parsing.html
-/sdcard/android/layout_tests/css2.1/t0804-c5509-padn-l-03-f-g.html
-/sdcard/android/layout_tests/css2.1/t1202-counter-02-b.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-13-d.html
-/sdcard/android/layout_tests/css2.1/t0905-c5526-flthw-00-c-g.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-33-d.html
-/sdcard/android/layout_tests/css2.1/t1001-abs-pos-cb-02-b.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-53-d.html
-/sdcard/android/layout_tests/css2.1/t0805-c5512-brdr-rw-03-b.html
-/sdcard/android/layout_tests/css2.1/t040109-c17-comments-01-b.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-73-d.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-93-d.html
-/sdcard/android/layout_tests/css2.1/t0805-c5511-ibrdr-tw-00-a.html
-/sdcard/android/layout_tests/css2.1/t0803-c5504-imrgn-l-02-b-ag.html
-/sdcard/android/layout_tests/css2.1/t0803-c5502-imrgn-r-00-b-ag.html
-/sdcard/android/layout_tests/css2.1/t1508-c527-font-05-b.html
-/sdcard/android/layout_tests/css2.1/t1202-counters-01-b.html
-/sdcard/android/layout_tests/css2.1/t1005-c5524-width-00-b-g.html
-/sdcard/android/layout_tests/css2.1/t0905-c414-flt-wrap-01-d-g.html
-/sdcard/android/layout_tests/css2.1/t010403-shand-font-02-b.html
-/sdcard/android/layout_tests/css2.1/t0805-c5515-brdr-w-02-b.html
-/sdcard/android/layout_tests/css2.1/t060401-c32-cascading-00-b.html
-/sdcard/android/layout_tests/css2.1/t0905-c5525-fltcont-00-d-g.html
-/sdcard/android/layout_tests/css2.1/t040103-ident-11-c.html
-/sdcard/android/layout_tests/css2.1/t1202-counters-16-c.html
-/sdcard/android/layout_tests/css2.1/t0509-id-sel-syntax-02-b.html
-/sdcard/android/layout_tests/css2.1/t090501-c5525-flt-l-00-b-g.html
-/sdcard/android/layout_tests/css2.1/t040103-ident-09-c.html
-/sdcard/android/layout_tests/css2.1/t050201-c12-grouping-00-b.html
-/sdcard/android/layout_tests/css2.1/t120401-scope-03-c.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-02-d.html
-/sdcard/android/layout_tests/css2.1/t0905-c414-flt-wrap-00-e.html
-/sdcard/android/layout_tests/css2.1/t0402-c71-fwd-parsing-03-f.html
-/sdcard/android/layout_tests/css2.1/t1202-counter-11-b.html
-/sdcard/android/layout_tests/css2.1/t1506-c525-font-wt-00-b.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-22-d.html
-/sdcard/android/layout_tests/css2.1/t1008-c44-ln-box-01-d-ag.html
-/sdcard/android/layout_tests/css2.1/t0905-c5525-fltwidth-00-c-g.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-42-d.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-62-d.html
-/sdcard/android/layout_tests/css2.1/t0905-c5525-fltmult-00-d-g.html
-/sdcard/android/layout_tests/css2.1/t1401-c531-color-00-a.html
-/sdcard/android/layout_tests/css2.1/t0805-c5514-ibrdr-lw-00-a.html
-/sdcard/android/layout_tests/css2.1/t1202-counter-09-b.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-82-d.html
-/sdcard/android/layout_tests/css2.1/t1604-c541-word-sp-00-b-a.html
-/sdcard/android/layout_tests/css2.1/t0805-c5515-brdr-w-01-b-g.html
-/sdcard/android/layout_tests/css2.1/t0804-c5507-ipadn-r-04-b-ag.html
-/sdcard/android/layout_tests/css2.1/t1001-abs-pos-cb-09-b.html
-/sdcard/android/layout_tests/css2.1/t140201-c534-bgreps-05-c-ag.html
-/sdcard/android/layout_tests/css2.1/t0402-syntax-02-f.html
-/sdcard/android/layout_tests/css2.1/t0803-c5503-mrgn-b-00-b-a.html
-/sdcard/android/layout_tests/css2.1/t0805-c5517-brdr-s-00-c.html
-/sdcard/android/layout_tests/css2.1/t0805-c5514-brdr-lw-01-b-g.html
-/sdcard/android/layout_tests/css2.1/t100801-c42-ibx-ht-00-d-a.html
-/sdcard/android/layout_tests/css2.1/t040103-ident-00-c.html
-/sdcard/android/layout_tests/css2.1/t0805-c5513-brdr-bw-03-b.html
-/sdcard/android/layout_tests/css2.1/t0804-c5506-padn-t-00-b-a.html
-/sdcard/android/layout_tests/css2.1/t0505-c16-descendant-01-e.html
-/sdcard/android/layout_tests/css2.1/t0805-c5519-brdr-r-02-e.html
-/sdcard/android/layout_tests/css2.1/t1202-counters-08-b.html
-/sdcard/android/layout_tests/css2.1/t051103-c21-hover-ln-00-e-i.html
-/sdcard/android/layout_tests/css2.1/t120403-content-none-00-c.html
-/sdcard/android/layout_tests/css2.1/t1202-counter-00-b.html
-/sdcard/android/layout_tests/css2.1/t040105-import-01-b.html
-/sdcard/android/layout_tests/css2.1/t040103-case-01-c.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-11-d.html
-/sdcard/android/layout_tests/css2.1/t09-c5526c-display-00-e.html
-/sdcard/android/layout_tests/css2.1/t0905-c5525-fltblck-00-d-ag.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-31-d.html
-/sdcard/android/layout_tests/css2.1/t0805-c5514-brdr-lw-03-b.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-51-d.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-71-d.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-09-d.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-91-d.html
-/sdcard/android/layout_tests/css2.1/t0905-c5525-fltwrap-00-b.html
-/sdcard/android/layout_tests/css2.1/t0905-c414-flt-fit-00-d.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-29-d.html
-/sdcard/android/layout_tests/css2.1/t0803-c5505-mrgn-01-e-a.html
-/sdcard/android/layout_tests/css2.1/t0803-c5502-mrgn-r-00-c-ag.html
-/sdcard/android/layout_tests/css2.1/t1004-c43-rpl-ibx-00-d-ag.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-49-d.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-69-d.html
-/sdcard/android/layout_tests/css2.1/t1204-multiple-00-c.html
-/sdcard/android/layout_tests/css2.1/t140201-c533-bgimage-01-b-g.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-89-d.html
-/sdcard/android/layout_tests/css2.1/t1508-c527-font-03-b.html
-/sdcard/android/layout_tests/css2.1/t0803-c5504-mrgn-l-02-c.html
-/sdcard/android/layout_tests/css2.1/t0805-c5518-brdr-t-00-a.html
-/sdcard/android/layout_tests/css2.1/t010403-shand-font-00-b.html
-/sdcard/android/layout_tests/css2.1/t0510-c25-pseudo-elmnt-00-c.html
-/sdcard/android/layout_tests/css2.1/t0803-c5505-imrgn-00-a-ag.html
-/sdcard/android/layout_tests/css2.1/t0803-c5502-imrgn-r-05-b-ag.html
-/sdcard/android/layout_tests/css2.1/t060402-c31-important-00-b.html
-/sdcard/android/layout_tests/css2.1/t0905-c414-flt-00-d.html
-/sdcard/android/layout_tests/css2.1/t0905-c414-flt-03-c.html
-/sdcard/android/layout_tests/css2.1/t040103-ident-07-c.html
-/sdcard/android/layout_tests/css2.1/t1204-order-00-c.html
-/sdcard/android/layout_tests/css2.1/t120401-scope-01-c.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-00-d.html
-/sdcard/android/layout_tests/css2.1/t0402-c71-fwd-parsing-01-f.html
-/sdcard/android/layout_tests/css2.1/t1604-c542-letter-sp-01-b-a.html
-/sdcard/android/layout_tests/css2.1/t0805-c5520-brdr-b-01-e.html
-/sdcard/android/layout_tests/css2.1/t140201-c536-bgpos-00-b-ag.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-20-d.html
-/sdcard/android/layout_tests/css2.1/t0509-c15-ids-01-e.html
-/sdcard/android/layout_tests/css2.1/t1204-reset-01-c-o.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-40-d.html
-/sdcard/android/layout_tests/css2.1/t090501-c414-flt-ln-03-d.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-60-d.html
-/sdcard/android/layout_tests/css2.1/t0905-c5525-fltwidth-02-c-g.html
-/sdcard/android/layout_tests/css2.1/t0905-c5525-fltclr-00-c-ag.html
-/sdcard/android/layout_tests/css2.1/t1202-counter-07-b.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-80-d.html
-/sdcard/android/layout_tests/css2.1/t1204-implied-01-c.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-18-d.html
-/sdcard/android/layout_tests/css2.1/t0804-c5507-ipadn-r-01-b-ag.html
-/sdcard/android/layout_tests/css2.1/t040103-escapes-03-b.html
-/sdcard/android/layout_tests/css2.1/t140201-c534-bgreps-02-c-ag.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-38-d.html
-/sdcard/android/layout_tests/css2.1/t1001-abs-pos-cb-07-b.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-58-d.html
-/sdcard/android/layout_tests/css2.1/t0803-c5505-mrgn-00-b-ag.html
-/sdcard/android/layout_tests/css2.1/t100801-c544-valgn-04-d-agi.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-78-d.html
-/sdcard/android/layout_tests/css2.1/t100801-c548-ln-ht-02-b-ag.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-98-d.html
-/sdcard/android/layout_tests/css2.1/t0804-c5508-ipadn-b-00-b-a.html
-/sdcard/android/layout_tests/css2.1/t0804-c5509-padn-l-01-b-a.html
-/sdcard/android/layout_tests/css2.1/t040105-atrule-03-b.html
-/sdcard/android/layout_tests/css2.1/t1507-c526-font-sz-02-b-a.html
-/sdcard/android/layout_tests/css2.1/t0805-c5522-ibrdr-00-a.html
-/sdcard/android/layout_tests/css2.1/t0803-c5502-mrgn-r-03-c.html
-/sdcard/android/layout_tests/css2.1/t1202-counters-06-b.html
-/sdcard/android/layout_tests/css2.1/t0905-c5525-fltmrgn-00-c-ag.html
-/sdcard/android/layout_tests/css2.1/t051103-dom-hover-02-c-io.html
-/sdcard/android/layout_tests/css2.1/t0804-c5506-ipadn-t-00-b-a.html
-/sdcard/android/layout_tests/css2.1/t040304-c64-uri-00-a-g.html
-/sdcard/android/layout_tests/css2.1/t0803-c5501-mrgn-t-00-b-a.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-07-d.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-27-d.html
-/sdcard/android/layout_tests/css2.1/t0805-c5511-brdr-tw-03-b.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-47-d.html
-/sdcard/android/layout_tests/css2.1/t060403-c21-pseu-id-00-e-i.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-67-d.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-87-d.html
-/sdcard/android/layout_tests/css2.1/t1508-c527-font-01-b.html
-/sdcard/android/layout_tests/css2.1/t0603-c11-import-00-b.html
-/sdcard/android/layout_tests/css2.1/t0803-c5504-imrgn-l-04-b-ag.html
-/sdcard/android/layout_tests/css2.1/t1503-c522-font-family-00-b.html
-/sdcard/android/layout_tests/css2.1/t090501-c414-flt-ln-01-d-g.html
-/sdcard/android/layout_tests/css2.1/t0511-c21-pseud-link-03-e.html
-/sdcard/android/layout_tests/css2.1/t1202-counters-15-b.html
-/sdcard/android/layout_tests/css2.1/t040105-atkeyw-02-b.html
-/sdcard/android/layout_tests/css2.1/t0805-c5519-ibrdr-r-00-a.html
-/sdcard/android/layout_tests/css2.1/t040103-ident-05-c.html
-/sdcard/android/layout_tests/css2.1/t0602-inherit-bdr-pad-b-00.html
-/sdcard/android/layout_tests/css2.1/t040302-c61-rel-len-00-b-ag.html
-/sdcard/android/layout_tests/css2.1/t0804-c5507-padn-r-00-c-ag.html
-/sdcard/android/layout_tests/css2.1/t0804-c5509-ipadn-l-00-b-ag.html
-/sdcard/android/layout_tests/css2.1/t0805-c5520-ibrdr-b-00-a.html
-/sdcard/android/layout_tests/css2.1/t1202-counter-05-b.html
-/sdcard/android/layout_tests/css2.1/t1008-c44-ln-box-03-d-ag.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-16-d.html
-/sdcard/android/layout_tests/css2.1/t040103-escapes-01-b.html
-/sdcard/android/layout_tests/css2.1/t100304-c43-rpl-bbx-01-d-g.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-36-d.html
-/sdcard/android/layout_tests/css2.1/t1001-abs-pos-cb-05-b.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-56-d.html
-/sdcard/android/layout_tests/css2.1/t0804-c5509-padn-l-02-f.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-76-d.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-96-d.html
-/sdcard/android/layout_tests/css2.1/t051202-c26-psudo-nest-00-c.html
-/sdcard/android/layout_tests/css2.1/t040105-atrule-01-b.html
-/sdcard/android/layout_tests/css2.1/t0804-c5508-ipadn-b-02-b-a.html
-/sdcard/android/layout_tests/css2.1/t0803-c5501-imrgn-t-00-b-ag.html
-/sdcard/android/layout_tests/css2.1/t140201-c532-bgcolor-01-b.html
-/sdcard/android/layout_tests/css2.1/t1508-c527-font-08-b.html
-/sdcard/android/layout_tests/css2.1/t1202-counters-04-b.html
-/sdcard/android/layout_tests/css2.1/t040103-case-00-b.html
-/sdcard/android/layout_tests/css2.1/t1504-c543-txt-decor-00-d-g.html
-/sdcard/android/layout_tests/css2.1/t0805-c5516-brdr-c-00-a.html
-/sdcard/android/layout_tests/css2.1/t0804-c5506-ipadn-t-02-b-a.html
-/sdcard/android/layout_tests/css2.1/t1204-increment-00-c-o.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-05-d.html
-/sdcard/android/layout_tests/css2.1/t1202-counter-14-b.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-25-d.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-45-d.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-65-d.html
-/sdcard/android/layout_tests/css2.1/t040103-escapes-02-d.html
-/sdcard/android/layout_tests/css2.1/t1602-c546-txt-align-00-b.html
-/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-85-d.html
-/sdcard/android/layout_tests/css2.1/t040103-escapes-05-c.html
-/sdcard/android/layout_tests/css2.1/t040103-escapes-08-b.html
-/sdcard/android/layout_tests/css2.1/t0803-c5504-imrgn-l-01-b-ag.html
-/sdcard/android/layout_tests/css2.1/t1002-c5523-width-00-b-g.html
-/sdcard/android/layout_tests/css2.1/t0804-c5507-padn-r-03-f.html
-/sdcard/android/layout_tests/css2.1/t0402-syntax-05-f.html
-/sdcard/android/layout_tests/css2.1/t1205-c561-list-displ-00-b.html
-/sdcard/android/layout_tests/css2.1/t0511-c21-pseud-link-01-e.html
-/sdcard/android/layout_tests/css2.1/t051201-c23-first-line-00-b.html
-/sdcard/android/layout_tests/css2.1/t1202-counters-13-b.html
-/sdcard/android/layout_tests/css2.1/t140201-c533-bgimage-00-a.html
-/sdcard/android/layout_tests/css2.1/t040105-atkeyw-00-b.html
-/sdcard/android/layout_tests/css3/css3-modsel-33.html
-/sdcard/android/layout_tests/css3/css3-modsel-35.html
-/sdcard/android/layout_tests/css3/css3-modsel-36.html
-/sdcard/android/layout_tests/css3/css3-modsel-37.html
-/sdcard/android/layout_tests/editing/input/emacs-ctrl-o.html
-/sdcard/android/layout_tests/editing/style/style-3681552-fix-001.html
-/sdcard/android/layout_tests/editing/style/create-block-for-style-013.html
-/sdcard/android/layout_tests/editing/style/style-3690704-fix.html
-/sdcard/android/layout_tests/editing/style/create-block-for-style-005.html
-/sdcard/android/layout_tests/editing/style/style-boundary-002.html
-/sdcard/android/layout_tests/editing/style/remove-underline-after-paragraph.html
-/sdcard/android/layout_tests/editing/style/create-block-for-style-009.html
-/sdcard/android/layout_tests/editing/style/5228141.html
-/sdcard/android/layout_tests/editing/style/block-style-004.html
-/sdcard/android/layout_tests/editing/style/apple-style-editable-mix.html
-/sdcard/android/layout_tests/editing/style/unbold-in-bold.html
-/sdcard/android/layout_tests/editing/style/typing-style-001.html
-/sdcard/android/layout_tests/editing/style/relative-font-size-change-004.html
-/sdcard/android/layout_tests/editing/style/create-block-for-style-010.html
-/sdcard/android/layout_tests/editing/style/create-block-for-style-002.html
-/sdcard/android/layout_tests/editing/style/style-3681552-fix-002.html
-/sdcard/android/layout_tests/editing/style/create-block-for-style-006.html
-/sdcard/android/layout_tests/editing/style/style-boundary-003.html
-/sdcard/android/layout_tests/editing/style/block-style-001.html
-/sdcard/android/layout_tests/editing/style/smoosh-styles-001.html
-/sdcard/android/layout_tests/editing/style/font-family-with-space.html
-/sdcard/android/layout_tests/editing/style/5084241.html
-/sdcard/android/layout_tests/editing/style/5065910.html
-/sdcard/android/layout_tests/editing/style/block-style-005.html
-/sdcard/android/layout_tests/editing/style/remove-underline-across-paragraph-in-bold.html
-/sdcard/android/layout_tests/editing/style/5279521.html
-/sdcard/android/layout_tests/editing/style/non-inheritable-styles.html
-/sdcard/android/layout_tests/editing/style/5046875-1.html
-/sdcard/android/layout_tests/editing/style/style-3998892-fix.html
-/sdcard/android/layout_tests/editing/style/typing-style-002.html
-/sdcard/android/layout_tests/editing/style/relative-font-size-change-001.html
-/sdcard/android/layout_tests/editing/style/4916887.html
-/sdcard/android/layout_tests/editing/style/remove-underline-across-paragraph.html
-/sdcard/android/layout_tests/editing/style/create-block-for-style-011.html
-/sdcard/android/layout_tests/editing/style/create-block-for-style-003.html
-/sdcard/android/layout_tests/editing/style/remove-underline.html
-/sdcard/android/layout_tests/editing/style/create-block-for-style-007.html
-/sdcard/android/layout_tests/editing/style/style-boundary-004.html
-/sdcard/android/layout_tests/editing/style/5017613-1.html
-/sdcard/android/layout_tests/editing/style/block-style-002.html
-/sdcard/android/layout_tests/editing/style/block-style-006.html
-/sdcard/android/layout_tests/editing/style/fontsize-1.html
-/sdcard/android/layout_tests/editing/style/5046875-2.html
-/sdcard/android/layout_tests/editing/style/typing-style-003.html
-/sdcard/android/layout_tests/editing/style/relative-font-size-change-002.html
-/sdcard/android/layout_tests/editing/style/create-block-for-style-012.html
-/sdcard/android/layout_tests/editing/style/create-block-for-style-004.html
-/sdcard/android/layout_tests/editing/style/designmode.html
-/sdcard/android/layout_tests/editing/style/block-styles-007.html
-/sdcard/android/layout_tests/editing/style/style-boundary-001.html
-/sdcard/android/layout_tests/editing/style/create-block-for-style-008.html
-/sdcard/android/layout_tests/editing/style/style-boundary-005.html
-/sdcard/android/layout_tests/editing/style/5017613-2.html
-/sdcard/android/layout_tests/editing/style/underline.html
-/sdcard/android/layout_tests/editing/style/block-style-003.html
-/sdcard/android/layout_tests/editing/style/smoosh-styles-003.html
-/sdcard/android/layout_tests/editing/style/remove-underline-after-paragraph-in-bold.html
-/sdcard/android/layout_tests/editing/style/highlight.html
-/sdcard/android/layout_tests/editing/style/relative-font-size-change-003.html
-/sdcard/android/layout_tests/editing/style/table-selection.html
-/sdcard/android/layout_tests/editing/style/create-block-for-style-001.html
-/sdcard/android/layout_tests/editing/unsupported-content/table-delete-001.html
-/sdcard/android/layout_tests/editing/unsupported-content/table-type-after.html
-/sdcard/android/layout_tests/editing/unsupported-content/table-delete-002.html
-/sdcard/android/layout_tests/editing/unsupported-content/table-type-before.html
-/sdcard/android/layout_tests/editing/unsupported-content/table-delete-003.html
-/sdcard/android/layout_tests/editing/unsupported-content/list-delete-001.html
-/sdcard/android/layout_tests/editing/unsupported-content/list-type-after.html
-/sdcard/android/layout_tests/editing/unsupported-content/list-type-before.html
-/sdcard/android/layout_tests/editing/unsupported-content/list-delete-003.html
-/sdcard/android/layout_tests/editing/inserting/insert-div-011.html
-/sdcard/android/layout_tests/editing/inserting/4960120-1.html
-/sdcard/android/layout_tests/editing/inserting/insert-div-023.html
-/sdcard/android/layout_tests/editing/inserting/insert-paragraph-04.html
-/sdcard/android/layout_tests/editing/inserting/insert-div-007.html
-/sdcard/android/layout_tests/editing/inserting/5058163-2.html
-/sdcard/android/layout_tests/editing/inserting/insert-div-019.html
-/sdcard/android/layout_tests/editing/inserting/insert-br-at-tabspan-003.html
-/sdcard/android/layout_tests/editing/inserting/5607069-2.html
-/sdcard/android/layout_tests/editing/inserting/6633727.html
-/sdcard/android/layout_tests/editing/inserting/6703873.html
-/sdcard/android/layout_tests/editing/inserting/insert-br-quoted-003.html
-/sdcard/android/layout_tests/editing/inserting/insert-br-003.html
-/sdcard/android/layout_tests/editing/inserting/4875189-1.html
-/sdcard/android/layout_tests/editing/inserting/typing-003.html
-/sdcard/android/layout_tests/editing/inserting/insert-3907422-fix.html
-/sdcard/android/layout_tests/editing/inserting/insert-div-020.html
-/sdcard/android/layout_tests/editing/inserting/before-after-input-element.html
-/sdcard/android/layout_tests/editing/inserting/insert-div-004.html
-/sdcard/android/layout_tests/editing/inserting/insert-paragraph-01.html
-/sdcard/android/layout_tests/editing/inserting/insert-div-016.html
-/sdcard/android/layout_tests/editing/inserting/5510537.html
-/sdcard/android/layout_tests/editing/inserting/4959067.html
-/sdcard/android/layout_tests/editing/inserting/insert-br-008.html
-/sdcard/android/layout_tests/editing/inserting/insert-text-at-tabspan-001.html
-/sdcard/android/layout_tests/editing/inserting/insert-div-001.html
-/sdcard/android/layout_tests/editing/inserting/paragraph-separator-02.html
-/sdcard/android/layout_tests/editing/inserting/insert-div-013.html
-/sdcard/android/layout_tests/editing/inserting/insert-div-025.html
-/sdcard/android/layout_tests/editing/inserting/insert-3654864-fix.html
-/sdcard/android/layout_tests/editing/inserting/insert-div-009.html
-/sdcard/android/layout_tests/editing/inserting/return-key-with-selection-002.html
-/sdcard/android/layout_tests/editing/inserting/editable-html-element.html
-/sdcard/android/layout_tests/editing/inserting/5418891.html
-/sdcard/android/layout_tests/editing/inserting/insert-br-quoted-005.html
-/sdcard/android/layout_tests/editing/inserting/insert-tab-002.html
-/sdcard/android/layout_tests/editing/inserting/insert-br-005.html
-/sdcard/android/layout_tests/editing/inserting/line-break.html
-/sdcard/android/layout_tests/editing/inserting/5549929-3.html
-/sdcard/android/layout_tests/editing/inserting/typing-tab-designmode-forms.html
-/sdcard/android/layout_tests/editing/inserting/insert-div-010.html
-/sdcard/android/layout_tests/editing/inserting/insert-div-022.html
-/sdcard/android/layout_tests/editing/inserting/insert-paragraph-03.html
-/sdcard/android/layout_tests/editing/inserting/insert-div-006.html
-/sdcard/android/layout_tests/editing/inserting/5058163-1.html
-/sdcard/android/layout_tests/editing/inserting/insert-div-018.html
-/sdcard/android/layout_tests/editing/inserting/paragraph-separator-in-table-2.html
-/sdcard/android/layout_tests/editing/inserting/insert-br-at-tabspan-002.html
-/sdcard/android/layout_tests/editing/inserting/insert-br-quoted-002.html
-/sdcard/android/layout_tests/editing/inserting/insert-br-002.html
-/sdcard/android/layout_tests/editing/inserting/typing-002.html
-/sdcard/android/layout_tests/editing/inserting/insert-3800346-fix.html
-/sdcard/android/layout_tests/editing/inserting/typing-around-image-001.html
-/sdcard/android/layout_tests/editing/inserting/insert-text-at-tabspan-003.html
-/sdcard/android/layout_tests/editing/inserting/insert-text-with-newlines.html
-/sdcard/android/layout_tests/editing/inserting/insert-div-003.html
-/sdcard/android/layout_tests/editing/inserting/insert-div-015.html
-/sdcard/android/layout_tests/editing/inserting/insert-at-end-02.html
-/sdcard/android/layout_tests/editing/inserting/insert-div-027.html
-/sdcard/android/layout_tests/editing/inserting/insert-3659587-fix.html
-/sdcard/android/layout_tests/editing/inserting/insert-br-007.html
-/sdcard/android/layout_tests/editing/inserting/insert-tab-004.html
-/sdcard/android/layout_tests/editing/inserting/editable-inline-element.html
-/sdcard/android/layout_tests/editing/inserting/paragraph-separator-01.html
-/sdcard/android/layout_tests/editing/inserting/insert-3851164-fix.html
-/sdcard/android/layout_tests/editing/inserting/5156401-2.html
-/sdcard/android/layout_tests/editing/inserting/4960120-2.html
-/sdcard/android/layout_tests/editing/inserting/insert-div-012.html
-/sdcard/android/layout_tests/editing/inserting/insert-div-024.html
-/sdcard/android/layout_tests/editing/inserting/multiple-lines-selected.html
-/sdcard/android/layout_tests/editing/inserting/insert-div-008.html
-/sdcard/android/layout_tests/editing/inserting/insert-paragraph-05.html
-/sdcard/android/layout_tests/editing/inserting/insert-3778059-fix.html
-/sdcard/android/layout_tests/editing/inserting/return-key-with-selection-001.html
-/sdcard/android/layout_tests/editing/inserting/5607069-3.html
-/sdcard/android/layout_tests/editing/inserting/insert-br-quoted-004.html
-/sdcard/android/layout_tests/editing/inserting/insert-br-004.html
-/sdcard/android/layout_tests/editing/inserting/insert-tab-001.html
-/sdcard/android/layout_tests/editing/inserting/4875189-2.html
-/sdcard/android/layout_tests/editing/inserting/5549929-2.html
-/sdcard/android/layout_tests/editing/inserting/editing-empty-divs.html
-/sdcard/android/layout_tests/editing/inserting/insert-div-021.html
-/sdcard/android/layout_tests/editing/inserting/insert-div-005.html
-/sdcard/android/layout_tests/editing/inserting/insert-paragraph-02.html
-/sdcard/android/layout_tests/editing/inserting/insert-3786362-fix.html
-/sdcard/android/layout_tests/editing/inserting/insert-div-017.html
-/sdcard/android/layout_tests/editing/inserting/paragraph-separator-in-table-1.html
-/sdcard/android/layout_tests/editing/inserting/insert-br-at-tabspan-001.html
-/sdcard/android/layout_tests/editing/inserting/insert-space-in-empty-doc.html
-/sdcard/android/layout_tests/editing/inserting/insert-after-delete-001.html
-/sdcard/android/layout_tests/editing/inserting/insert-br-quoted-001.html
-/sdcard/android/layout_tests/editing/inserting/insert-br-001.html
-/sdcard/android/layout_tests/editing/inserting/typing-001.html
-/sdcard/android/layout_tests/editing/inserting/insert-br-009.html
-/sdcard/android/layout_tests/editing/inserting/4278698.html
-/sdcard/android/layout_tests/editing/inserting/insert-text-at-tabspan-002.html
-/sdcard/android/layout_tests/editing/inserting/5002441.html
-/sdcard/android/layout_tests/editing/inserting/insert-div-002.html
-/sdcard/android/layout_tests/editing/inserting/paragraph-separator-03.html
-/sdcard/android/layout_tests/editing/inserting/12882.html
-/sdcard/android/layout_tests/editing/inserting/insert-3775316-fix.html
-/sdcard/android/layout_tests/editing/inserting/insert-div-014.html
-/sdcard/android/layout_tests/editing/inserting/edited-whitespace-1.html
-/sdcard/android/layout_tests/editing/inserting/insert-at-end-01.html
-/sdcard/android/layout_tests/editing/inserting/insert-div-026.html
-/sdcard/android/layout_tests/editing/inserting/break-blockquote-after-delete.html
-/sdcard/android/layout_tests/editing/inserting/redo.html
-/sdcard/android/layout_tests/editing/inserting/4840662.html
-/sdcard/android/layout_tests/editing/inserting/typing-around-br-001.html
-/sdcard/android/layout_tests/editing/inserting/return-key-with-selection-003.html
-/sdcard/android/layout_tests/editing/inserting/insert-br-quoted-006.html
-/sdcard/android/layout_tests/editing/inserting/insert-tab-003.html
-/sdcard/android/layout_tests/editing/inserting/insert-br-006.html
-/sdcard/android/layout_tests/editing/execCommand/5142012-1.html
-/sdcard/android/layout_tests/editing/execCommand/hilitecolor.html
-/sdcard/android/layout_tests/editing/execCommand/format-block-with-braces.html
-/sdcard/android/layout_tests/editing/execCommand/outdent-blockquote-test3.html
-/sdcard/android/layout_tests/editing/execCommand/4920742-1.html
-/sdcard/android/layout_tests/editing/execCommand/4924441.html
-/sdcard/android/layout_tests/editing/execCommand/create-list-with-hr.html
-/sdcard/android/layout_tests/editing/execCommand/format-block-with-trailing-br.html
-/sdcard/android/layout_tests/editing/execCommand/remove-formatting-2.html
-/sdcard/android/layout_tests/editing/execCommand/outdent-selection.html
-/sdcard/android/layout_tests/editing/execCommand/strikethroughSelection.html
-/sdcard/android/layout_tests/editing/execCommand/5482023.html
-/sdcard/android/layout_tests/editing/execCommand/4786404-1.html
-/sdcard/android/layout_tests/editing/execCommand/remove-formatting.html
-/sdcard/android/layout_tests/editing/execCommand/findString.html
-/sdcard/android/layout_tests/editing/execCommand/italicizeByCharacter.html
-/sdcard/android/layout_tests/editing/execCommand/create-list-from-range-selection.html
-/sdcard/android/layout_tests/editing/execCommand/5190926.html
-/sdcard/android/layout_tests/editing/execCommand/insertHorizontalRule.html
-/sdcard/android/layout_tests/editing/execCommand/paste-1.html
-/sdcard/android/layout_tests/editing/execCommand/nsresponder-outdent.html
-/sdcard/android/layout_tests/editing/execCommand/toggle-compound-styles.html
-/sdcard/android/layout_tests/editing/execCommand/5080333-2.html
-/sdcard/android/layout_tests/editing/execCommand/outdent-blockquote-test2.html
-/sdcard/android/layout_tests/editing/execCommand/5049671.html
-/sdcard/android/layout_tests/editing/execCommand/4920488.html
-/sdcard/android/layout_tests/editing/execCommand/nsresponder-indent.html
-/sdcard/android/layout_tests/editing/execCommand/indent-list-item.html
-/sdcard/android/layout_tests/editing/execCommand/4916402.html
-/sdcard/android/layout_tests/editing/execCommand/5138441.html
-/sdcard/android/layout_tests/editing/execCommand/insert-list-empty-div.html
-/sdcard/android/layout_tests/editing/execCommand/5481523.html
-/sdcard/android/layout_tests/editing/execCommand/print.html
-/sdcard/android/layout_tests/editing/execCommand/4641880-2.html
-/sdcard/android/layout_tests/editing/execCommand/4580583-2.html
-/sdcard/android/layout_tests/editing/execCommand/remove-list-item-1.html
-/sdcard/android/layout_tests/editing/execCommand/5569741.html
-/sdcard/android/layout_tests/editing/execCommand/findString-2.html
-/sdcard/android/layout_tests/editing/execCommand/modifyForeColorByCharacter.html
-/sdcard/android/layout_tests/editing/execCommand/5142012-2.html
-/sdcard/android/layout_tests/editing/execCommand/find-after-replace.html
-/sdcard/android/layout_tests/editing/execCommand/outdent-blockquote-test4.html
-/sdcard/android/layout_tests/editing/execCommand/format-block.html
-/sdcard/android/layout_tests/editing/execCommand/5080333-1.html
-/sdcard/android/layout_tests/editing/execCommand/remove-list-from-range-selection.html
-/sdcard/android/layout_tests/editing/execCommand/outdent-blockquote-test1.html
-/sdcard/android/layout_tests/editing/execCommand/5136770.html
-/sdcard/android/layout_tests/editing/execCommand/4916541.html
-/sdcard/android/layout_tests/editing/execCommand/4786404-2.html
-/sdcard/android/layout_tests/editing/execCommand/insertImage.html
-/sdcard/android/layout_tests/editing/execCommand/insert-list-and-stitch.html
-/sdcard/android/layout_tests/editing/execCommand/5573879.html
-/sdcard/android/layout_tests/editing/execCommand/4641880-1.html
-/sdcard/android/layout_tests/editing/execCommand/4580583-1.html
-/sdcard/android/layout_tests/editing/execCommand/4747450.html
-/sdcard/android/layout_tests/editing/execCommand/format-block-from-range-selection.html
-/sdcard/android/layout_tests/editing/execCommand/indent-empty-root.html
-/sdcard/android/layout_tests/editing/execCommand/indent-selection.html
-/sdcard/android/layout_tests/editing/execCommand/selectAll.html
-/sdcard/android/layout_tests/editing/execCommand/paste-2.html
-/sdcard/android/layout_tests/editing/pasteboard/subframe-dragndrop-1.html
-/sdcard/android/layout_tests/editing/pasteboard/innerText-inline-table.html
-/sdcard/android/layout_tests/editing/pasteboard/5156401-1.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-list-001.html
-/sdcard/android/layout_tests/editing/pasteboard/4242293-1.html
-/sdcard/android/layout_tests/editing/pasteboard/5032095.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-line-endings-004.html
-/sdcard/android/layout_tests/editing/pasteboard/5247341.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-4035648-fix.html
-/sdcard/android/layout_tests/editing/pasteboard/4700297.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-text-003.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-blockquote-into-blockquote.html
-/sdcard/android/layout_tests/editing/pasteboard/drop-link.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-blockquote-into-blockquote-3.html
-/sdcard/android/layout_tests/editing/pasteboard/4944770-1.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-text-015.html
-/sdcard/android/layout_tests/editing/pasteboard/5075944.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-match-style-001.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-4039777-fix.html
-/sdcard/android/layout_tests/editing/pasteboard/merge-end-3.html
-/sdcard/android/layout_tests/editing/pasteboard/smart-paste-007.html
-/sdcard/android/layout_tests/editing/pasteboard/5483567.html
-/sdcard/android/layout_tests/editing/pasteboard/7955.html
-/sdcard/android/layout_tests/editing/pasteboard/merge-end-blockquote.html
-/sdcard/android/layout_tests/editing/pasteboard/testcase-9507.html
-/sdcard/android/layout_tests/editing/pasteboard/input-field-1.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-line-endings-001.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-text-at-tabspan-001.html
-/sdcard/android/layout_tests/editing/pasteboard/interchange-newline-2.html
-/sdcard/android/layout_tests/editing/pasteboard/block-wrappers-necessary.html
-/sdcard/android/layout_tests/editing/pasteboard/4861080.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-line-endings-009.html
-/sdcard/android/layout_tests/editing/pasteboard/merge-after-delete.html
-/sdcard/android/layout_tests/editing/pasteboard/5478250.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-text-012.html
-/sdcard/android/layout_tests/editing/pasteboard/prevent-block-nesting-01.html
-/sdcard/android/layout_tests/editing/pasteboard/8145-2.html
-/sdcard/android/layout_tests/editing/pasteboard/merge-end-borders.html
-/sdcard/android/layout_tests/editing/pasteboard/5027857.html
-/sdcard/android/layout_tests/editing/pasteboard/smart-paste-004.html
-/sdcard/android/layout_tests/editing/pasteboard/merge-start-list.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-text-008.html
-/sdcard/android/layout_tests/editing/pasteboard/4806874.html
-/sdcard/android/layout_tests/editing/pasteboard/emacs-ctrl-a-k-y.html
-/sdcard/android/layout_tests/editing/pasteboard/bad-placeholder.html
-/sdcard/android/layout_tests/editing/pasteboard/displaced-placeholder.html
-/sdcard/android/layout_tests/editing/pasteboard/5387578.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-blockquote-1.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-line-endings-010.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-line-endings-006.html
-/sdcard/android/layout_tests/editing/pasteboard/5601583-1.html
-/sdcard/android/layout_tests/editing/pasteboard/4947130.html
-/sdcard/android/layout_tests/editing/pasteboard/pasting-tabs.html
-/sdcard/android/layout_tests/editing/pasteboard/merge-after-delete-2.html
-/sdcard/android/layout_tests/editing/pasteboard/smart-paste-001.html
-/sdcard/android/layout_tests/editing/pasteboard/4076267-2.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-table-001.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-text-005.html
-/sdcard/android/layout_tests/editing/pasteboard/5089327.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-text-017.html
-/sdcard/android/layout_tests/editing/pasteboard/merge-end-5.html
-/sdcard/android/layout_tests/editing/pasteboard/drop-text-without-selection.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-text-at-tabspan-003.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-line-endings-003.html
-/sdcard/android/layout_tests/editing/pasteboard/drag-drop-modifies-page.html
-/sdcard/android/layout_tests/editing/pasteboard/emacs-ctrl-k-y-001.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-blockquote-after-blockquote.html
-/sdcard/android/layout_tests/editing/pasteboard/5071074.html
-/sdcard/android/layout_tests/editing/pasteboard/interchange-newline-4.html
-/sdcard/android/layout_tests/editing/pasteboard/styled-element-markup.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-4038267-fix.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-text-002.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-blockquote-into-blockquote-2.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-pre-002.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-text-014.html
-/sdcard/android/layout_tests/editing/pasteboard/drag-drop-dead-frame.html
-/sdcard/android/layout_tests/editing/pasteboard/merge-end-2.html
-/sdcard/android/layout_tests/editing/pasteboard/smart-paste-006.html
-/sdcard/android/layout_tests/editing/pasteboard/5368833.html
-/sdcard/android/layout_tests/editing/pasteboard/select-element-1.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-blockquote-3.html
-/sdcard/android/layout_tests/editing/pasteboard/4641033.html
-/sdcard/android/layout_tests/editing/pasteboard/drag-image-to-contenteditable-in-iframe.html
-/sdcard/android/layout_tests/editing/pasteboard/interchange-newline-1.html
-/sdcard/android/layout_tests/editing/pasteboard/copy-paste-bidi.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-line-endings-008.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-text-011.html
-/sdcard/android/layout_tests/editing/pasteboard/8145-1.html
-/sdcard/android/layout_tests/editing/pasteboard/smart-paste-003.html
-/sdcard/android/layout_tests/editing/pasteboard/5075944-3.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-table-003.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-TIFF.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-text-007.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-text-019.html
-/sdcard/android/layout_tests/editing/pasteboard/undoable-fragment-removes.html
-/sdcard/android/layout_tests/editing/pasteboard/nested-blocks-with-text-field.html
-/sdcard/android/layout_tests/editing/pasteboard/4989774.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-unrendered-select.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-line-endings-005.html
-/sdcard/android/layout_tests/editing/pasteboard/emacs-cntl-y-001.html
-/sdcard/android/layout_tests/editing/pasteboard/merge-after-delete-1.html
-/sdcard/android/layout_tests/editing/pasteboard/unrendered-br.html
-/sdcard/android/layout_tests/editing/pasteboard/4631972.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-text-004.html
-/sdcard/android/layout_tests/editing/pasteboard/quirks-mode-br-1.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-blockquote-into-blockquote-4.html
-/sdcard/android/layout_tests/editing/pasteboard/4944770-2.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-table-cells.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-text-016.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-match-style-002.html
-/sdcard/android/layout_tests/editing/pasteboard/merge-end-4.html
-/sdcard/android/layout_tests/editing/pasteboard/drag-selected-image-to-contenteditable.html
-/sdcard/android/layout_tests/editing/pasteboard/smart-paste-008.html
-/sdcard/android/layout_tests/editing/pasteboard/3976872.html
-/sdcard/android/layout_tests/editing/pasteboard/pasting-object.html
-/sdcard/android/layout_tests/editing/pasteboard/merge-end-list.html
-/sdcard/android/layout_tests/editing/pasteboard/copy-standalone-image.html
-/sdcard/android/layout_tests/editing/pasteboard/displaced-generic-placeholder.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-line-endings-002.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-text-at-tabspan-002.html
-/sdcard/android/layout_tests/editing/pasteboard/interchange-newline-3.html
-/sdcard/android/layout_tests/editing/pasteboard/5071074-2.html
-/sdcard/android/layout_tests/editing/pasteboard/display-block-on-spans.html
-/sdcard/android/layout_tests/editing/pasteboard/4242293.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-text-001.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-pre-001.html
-/sdcard/android/layout_tests/editing/pasteboard/merge-start-blockquote.html
-/sdcard/android/layout_tests/editing/pasteboard/merge-end-1.html
-/sdcard/android/layout_tests/editing/pasteboard/8145-3.html
-/sdcard/android/layout_tests/editing/pasteboard/5006779.html
-/sdcard/android/layout_tests/editing/pasteboard/smart-paste-005.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-text-009.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-blockquote-2.html
-/sdcard/android/layout_tests/editing/pasteboard/merge-end-table.html
-/sdcard/android/layout_tests/editing/pasteboard/5065605.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-line-endings-007.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-text-010.html
-/sdcard/android/layout_tests/editing/pasteboard/5028447.html
-/sdcard/android/layout_tests/editing/pasteboard/nested-blocks-with-text-area.html
-/sdcard/android/layout_tests/editing/pasteboard/4076267-3.html
-/sdcard/android/layout_tests/editing/pasteboard/4076267.html
-/sdcard/android/layout_tests/editing/pasteboard/smart-paste-002.html
-/sdcard/android/layout_tests/editing/pasteboard/5075944-2.html
-/sdcard/android/layout_tests/editing/pasteboard/5134759.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-text-006.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-text-018.html
-/sdcard/android/layout_tests/editing/pasteboard/paste-RTFD.html
-/sdcard/android/layout_tests/editing/pasteboard/cut-text-001.html
-/sdcard/android/layout_tests/editing/selection/mixed-editability-9.html
-/sdcard/android/layout_tests/editing/selection/fake-drag.html
-/sdcard/android/layout_tests/editing/selection/wrapped-line-caret-2.html
-/sdcard/android/layout_tests/editing/selection/unrendered-002.html
-/sdcard/android/layout_tests/editing/selection/3690703-2.html
-/sdcard/android/layout_tests/editing/selection/extend-by-character-005.html
-/sdcard/android/layout_tests/editing/selection/caret-rtl-2.html
-/sdcard/android/layout_tests/editing/selection/paragraph-granularity.html
-/sdcard/android/layout_tests/editing/selection/clear-selection.html
-/sdcard/android/layout_tests/editing/selection/mixed-editability-6.html
-/sdcard/android/layout_tests/editing/selection/drag-in-iframe.html
-/sdcard/android/layout_tests/editing/selection/unrendered-space.html
-/sdcard/android/layout_tests/editing/selection/extend-by-character-002.html
-/sdcard/android/layout_tests/editing/selection/4932260-2.html
-/sdcard/android/layout_tests/editing/selection/select-element-paragraph-boundary.html
-/sdcard/android/layout_tests/editing/selection/extend-by-sentence-001.html
-/sdcard/android/layout_tests/editing/selection/3690719.html
-/sdcard/android/layout_tests/editing/selection/editable-non-editable-crash.html
-/sdcard/android/layout_tests/editing/selection/mixed-editability-3.html
-/sdcard/android/layout_tests/editing/selection/replaced-boundaries-3.html
-/sdcard/android/layout_tests/editing/selection/move-by-sentence-linebreak.html
-/sdcard/android/layout_tests/editing/selection/move-by-character-005.html
-/sdcard/android/layout_tests/editing/selection/end-of-document.html
-/sdcard/android/layout_tests/editing/selection/selectNode.html
-/sdcard/android/layout_tests/editing/selection/editable-links.html
-/sdcard/android/layout_tests/editing/selection/extend-by-word-002.html
-/sdcard/android/layout_tests/editing/selection/move-by-character-002.html
-/sdcard/android/layout_tests/editing/selection/14971.html
-/sdcard/android/layout_tests/editing/selection/5131716-2.html
-/sdcard/android/layout_tests/editing/selection/5081257-1.html
-/sdcard/android/layout_tests/editing/selection/move-3875641-fix.html
-/sdcard/android/layout_tests/editing/selection/5099303.html
-/sdcard/android/layout_tests/editing/selection/move-by-line-002.html
-/sdcard/android/layout_tests/editing/selection/select-missing-image.html
-/sdcard/android/layout_tests/editing/selection/selection-3748164-fix.html
-/sdcard/android/layout_tests/editing/selection/4983858.html
-/sdcard/android/layout_tests/editing/selection/move-by-sentence-001.html
-/sdcard/android/layout_tests/editing/selection/table-caret-1.html
-/sdcard/android/layout_tests/editing/selection/move-by-word-001.html
-/sdcard/android/layout_tests/editing/selection/select-all-004.html
-/sdcard/android/layout_tests/editing/selection/5076323-2.html
-/sdcard/android/layout_tests/editing/selection/move-3875618-fix.html
-/sdcard/android/layout_tests/editing/selection/inline-table.html
-/sdcard/android/layout_tests/editing/selection/4895428-3.html
-/sdcard/android/layout_tests/editing/selection/caret-before-select.html
-/sdcard/android/layout_tests/editing/selection/select-all-001.html
-/sdcard/android/layout_tests/editing/selection/unrendered-003.html
-/sdcard/android/layout_tests/editing/selection/extend-by-character-006.html
-/sdcard/android/layout_tests/editing/selection/7152-1.html
-/sdcard/android/layout_tests/editing/selection/iframe.html
-/sdcard/android/layout_tests/editing/selection/mixed-editability-7.html
-/sdcard/android/layout_tests/editing/selection/select-all-iframe.html
-/sdcard/android/layout_tests/editing/selection/extend-by-character-003.html
-/sdcard/android/layout_tests/editing/selection/4932260-3.html
-/sdcard/android/layout_tests/editing/selection/4960116.html
-/sdcard/android/layout_tests/editing/selection/drag-to-contenteditable-iframe.html
-/sdcard/android/layout_tests/editing/selection/selectNodeContents.html
-/sdcard/android/layout_tests/editing/selection/mixed-editability-4.html
-/sdcard/android/layout_tests/editing/selection/focus-body.html
-/sdcard/android/layout_tests/editing/selection/designmode-no-caret.html
-/sdcard/android/layout_tests/editing/selection/5234383-1.html
-/sdcard/android/layout_tests/editing/selection/5232159.html
-/sdcard/android/layout_tests/editing/selection/4960137.html
-/sdcard/android/layout_tests/editing/selection/previous-line-position.html
-/sdcard/android/layout_tests/editing/selection/mixed-editability-1.html
-/sdcard/android/layout_tests/editing/selection/replaced-boundaries-1.html
-/sdcard/android/layout_tests/editing/selection/move-by-character-003.html
-/sdcard/android/layout_tests/editing/selection/4776665.html
-/sdcard/android/layout_tests/editing/selection/move-by-character-6.html
-/sdcard/android/layout_tests/editing/selection/image-before-linebreak.html
-/sdcard/android/layout_tests/editing/selection/move-between-blocks-no-001.html
-/sdcard/android/layout_tests/editing/selection/5131716-3.html
-/sdcard/android/layout_tests/editing/selection/5081257-2.html
-/sdcard/android/layout_tests/editing/selection/5354455-1.html
-/sdcard/android/layout_tests/editing/selection/expanding-selections2.html
-/sdcard/android/layout_tests/editing/selection/display-table-text.html
-/sdcard/android/layout_tests/editing/selection/13804.html
-/sdcard/android/layout_tests/editing/selection/table-caret-2.html
-/sdcard/android/layout_tests/editing/selection/expanding-selections.html
-/sdcard/android/layout_tests/editing/selection/node-removal-1.html
-/sdcard/android/layout_tests/editing/selection/5240265.html
-/sdcard/android/layout_tests/editing/selection/select-all-005.html
-/sdcard/android/layout_tests/editing/selection/5076323-3.html
-/sdcard/android/layout_tests/editing/selection/line-wrap-1.html
-/sdcard/android/layout_tests/editing/selection/replace-selection-1.html
-/sdcard/android/layout_tests/editing/selection/caret-rtl.html
-/sdcard/android/layout_tests/editing/selection/5109817.html
-/sdcard/android/layout_tests/editing/selection/5136696.html
-/sdcard/android/layout_tests/editing/selection/4397952.html
-/sdcard/android/layout_tests/editing/selection/caret-and-focus-ring.html
-/sdcard/android/layout_tests/editing/selection/4895428-4.html
-/sdcard/android/layout_tests/editing/selection/4947387.html
-/sdcard/android/layout_tests/editing/selection/select-from-textfield-outwards.html
-/sdcard/android/layout_tests/editing/selection/leave-requested-block.html
-/sdcard/android/layout_tests/editing/selection/select-all-002.html
-/sdcard/android/layout_tests/editing/selection/unrendered-004.html
-/sdcard/android/layout_tests/editing/selection/7152-2.html
-/sdcard/android/layout_tests/editing/selection/5195166-1.html
-/sdcard/android/layout_tests/editing/selection/editable-html-element.html
-/sdcard/android/layout_tests/editing/selection/4866671.html
-/sdcard/android/layout_tests/editing/selection/4895428-1.html
-/sdcard/android/layout_tests/editing/selection/mixed-editability-8.html
-/sdcard/android/layout_tests/editing/selection/wrapped-line-caret-1.html
-/sdcard/android/layout_tests/editing/selection/selection-actions.html
-/sdcard/android/layout_tests/editing/selection/4402375.html
-/sdcard/android/layout_tests/editing/selection/unrendered-001.html
-/sdcard/android/layout_tests/editing/selection/extend-by-character-004.html
-/sdcard/android/layout_tests/editing/selection/contenteditable-click-inside.html
-/sdcard/android/layout_tests/editing/selection/addRange.html
-/sdcard/android/layout_tests/editing/selection/mixed-editability-5.html
-/sdcard/android/layout_tests/editing/selection/5007143.html
-/sdcard/android/layout_tests/editing/selection/fake-doubleclick.html
-/sdcard/android/layout_tests/editing/selection/extend-by-character-001.html
-/sdcard/android/layout_tests/editing/selection/4932260-1.html
-/sdcard/android/layout_tests/editing/selection/5234383-2.html
-/sdcard/android/layout_tests/editing/selection/5057506.html
-/sdcard/android/layout_tests/editing/selection/focus_editable_html.html
-/sdcard/android/layout_tests/editing/selection/4818145.html
-/sdcard/android/layout_tests/editing/selection/move-backwords-by-word-001.html
-/sdcard/android/layout_tests/editing/selection/mixed-editability-2.html
-/sdcard/android/layout_tests/editing/selection/replaced-boundaries-2.html
-/sdcard/android/layout_tests/editing/selection/move-by-character-004.html
-/sdcard/android/layout_tests/editing/selection/4889598.html
-/sdcard/android/layout_tests/editing/selection/5131716-4.html
-/sdcard/android/layout_tests/editing/selection/3690703.html
-/sdcard/android/layout_tests/editing/selection/5333725.html
-/sdcard/android/layout_tests/editing/selection/5354455-2.html
-/sdcard/android/layout_tests/editing/selection/selection-background.html
-/sdcard/android/layout_tests/editing/selection/extend-by-word-001.html
-/sdcard/android/layout_tests/editing/selection/move-by-character-001.html
-/sdcard/android/layout_tests/editing/selection/doubleclick-crash.html
-/sdcard/android/layout_tests/editing/selection/table-caret-3.html
-/sdcard/android/layout_tests/editing/selection/5131716-1.html
-/sdcard/android/layout_tests/editing/selection/node-removal-2.html
-/sdcard/android/layout_tests/editing/selection/drag-select-1.html
-/sdcard/android/layout_tests/editing/selection/select-all-006.html
-/sdcard/android/layout_tests/editing/selection/after-line-wrap.html
-/sdcard/android/layout_tests/editing/selection/line-wrap-2.html
-/sdcard/android/layout_tests/editing/selection/move-by-line-001.html
-/sdcard/android/layout_tests/editing/selection/move-between-blocks-yes-001.html
-/sdcard/android/layout_tests/editing/selection/6476.html
-/sdcard/android/layout_tests/editing/selection/contains-boundaries.html
-/sdcard/android/layout_tests/editing/selection/click-start-of-line.html
-/sdcard/android/layout_tests/editing/selection/triple-click-in-pre.html
-/sdcard/android/layout_tests/editing/selection/move-past-trailing-space.html
-/sdcard/android/layout_tests/editing/selection/inline-closest-leaf-child.html
-/sdcard/android/layout_tests/editing/selection/5007143-2.html
-/sdcard/android/layout_tests/editing/selection/select-all-003.html
-/sdcard/android/layout_tests/editing/selection/5076323-1.html
-/sdcard/android/layout_tests/editing/selection/5057506-2.html
-/sdcard/android/layout_tests/editing/selection/4975120.html
-/sdcard/android/layout_tests/editing/selection/unrendered-005.html
-/sdcard/android/layout_tests/editing/selection/5195166-2.html
-/sdcard/android/layout_tests/editing/selection/select-box.html
-/sdcard/android/layout_tests/editing/selection/4895428-2.html
-/sdcard/android/layout_tests/editing/selection/word-granularity.html
-/sdcard/android/layout_tests/editing/undo/undo-misspellings.html
-/sdcard/android/layout_tests/editing/undo/undo-combined-delete.html
-/sdcard/android/layout_tests/editing/undo/undo-delete-boundary.html
-/sdcard/android/layout_tests/editing/undo/undo-forward-delete-boundary.html
-/sdcard/android/layout_tests/editing/undo/4063751.html
-/sdcard/android/layout_tests/editing/undo/redo-typing-001.html
-/sdcard/android/layout_tests/editing/undo/5378473.html
-/sdcard/android/layout_tests/editing/undo/undo-combined-delete-boundary.html
-/sdcard/android/layout_tests/editing/undo/undo-delete.html
-/sdcard/android/layout_tests/editing/undo/undo-forward-delete.html
-/sdcard/android/layout_tests/editing/undo/undo-typing-001.html
-/sdcard/android/layout_tests/editing/deleting/delete-3608462-fix.html
-/sdcard/android/layout_tests/editing/deleting/delete-image-001.html
-/sdcard/android/layout_tests/editing/deleting/delete-3928305-fix.html
-/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-012.html
-/sdcard/android/layout_tests/editing/deleting/5115601.html
-/sdcard/android/layout_tests/editing/deleting/deletionUI-single-instance.html
-/sdcard/android/layout_tests/editing/deleting/delete-block-contents-001.html
-/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-024.html
-/sdcard/android/layout_tests/editing/deleting/delete-after-span-ws-001.html
-/sdcard/android/layout_tests/editing/deleting/delete-line-011.html
-/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-008.html
-/sdcard/android/layout_tests/editing/deleting/delete-listitem-001.html
-/sdcard/android/layout_tests/editing/deleting/5300379.html
-/sdcard/android/layout_tests/editing/deleting/delete-line-007.html
-/sdcard/android/layout_tests/editing/deleting/5433862-2.html
-/sdcard/android/layout_tests/editing/deleting/5026848-1.html
-/sdcard/android/layout_tests/editing/deleting/delete-at-paragraph-boundaries-003.html
-/sdcard/android/layout_tests/editing/deleting/delete-br-012.html
-/sdcard/android/layout_tests/editing/deleting/delete-br-008.html
-/sdcard/android/layout_tests/editing/deleting/5206311-2.html
-/sdcard/android/layout_tests/editing/deleting/delete-at-start-or-end.html
-/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-021.html
-/sdcard/android/layout_tests/editing/deleting/delete-ws-fixup-004.html
-/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-005.html
-/sdcard/android/layout_tests/editing/deleting/delete-select-all-003.html
-/sdcard/android/layout_tests/editing/deleting/smart-delete-002.html
-/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-017.html
-/sdcard/android/layout_tests/editing/deleting/table-cells.html
-/sdcard/android/layout_tests/editing/deleting/5156801-2.html
-/sdcard/android/layout_tests/editing/deleting/delete-leading-ws-001.html
-/sdcard/android/layout_tests/editing/deleting/delete-line-004.html
-/sdcard/android/layout_tests/editing/deleting/delete-3857753-fix.html
-/sdcard/android/layout_tests/editing/deleting/delete-3959464-fix.html
-/sdcard/android/layout_tests/editing/deleting/delete-line-016.html
-/sdcard/android/layout_tests/editing/deleting/delete-trailing-ws-001.html
-/sdcard/android/layout_tests/editing/deleting/delete-br-005.html
-/sdcard/android/layout_tests/editing/deleting/delete-at-paragraph-boundaries-008.html
-/sdcard/android/layout_tests/editing/deleting/delete-tab-004.html
-/sdcard/android/layout_tests/editing/deleting/merge-whitespace-pre.html
-/sdcard/android/layout_tests/editing/deleting/delete-ws-fixup-001.html
-/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-002.html
-/sdcard/android/layout_tests/editing/deleting/delete-line-end-ws-002.html
-/sdcard/android/layout_tests/editing/deleting/merge-unrendered-space.html
-/sdcard/android/layout_tests/editing/deleting/delete-by-word-002.html
-/sdcard/android/layout_tests/editing/deleting/delete-image-003.html
-/sdcard/android/layout_tests/editing/deleting/delete-selection-001.html
-/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-014.html
-/sdcard/android/layout_tests/editing/deleting/merge-different-styles.html
-/sdcard/android/layout_tests/editing/deleting/delete-line-001.html
-/sdcard/android/layout_tests/editing/deleting/delete-block-contents-003.html
-/sdcard/android/layout_tests/editing/deleting/delete-after-span-ws-003.html
-/sdcard/android/layout_tests/editing/deleting/merge-into-empty-block-1.html
-/sdcard/android/layout_tests/editing/deleting/delete-line-013.html
-/sdcard/android/layout_tests/editing/deleting/delete-3865854-fix.html
-/sdcard/android/layout_tests/editing/deleting/delete-line-009.html
-/sdcard/android/layout_tests/editing/deleting/5026848-3.html
-/sdcard/android/layout_tests/editing/deleting/delete-at-paragraph-boundaries-005.html
-/sdcard/android/layout_tests/editing/deleting/delete-br-002.html
-/sdcard/android/layout_tests/editing/deleting/delete-tab-001.html
-/sdcard/android/layout_tests/editing/deleting/whitespace-pre-1.html
-/sdcard/android/layout_tests/editing/deleting/delete-block-table.html
-/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-011.html
-/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-023.html
-/sdcard/android/layout_tests/editing/deleting/delete-line-010.html
-/sdcard/android/layout_tests/editing/deleting/5032066.html
-/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-007.html
-/sdcard/android/layout_tests/editing/deleting/smart-delete-004.html
-/sdcard/android/layout_tests/editing/deleting/5144139-2.html
-/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-019.html
-/sdcard/android/layout_tests/editing/deleting/delete-line-006.html
-/sdcard/android/layout_tests/editing/deleting/5126166.html
-/sdcard/android/layout_tests/editing/deleting/delete-to-end-of-paragraph.html
-/sdcard/android/layout_tests/editing/deleting/5408255.html
-/sdcard/android/layout_tests/editing/deleting/5099303.html
-/sdcard/android/layout_tests/editing/deleting/4845371.html
-/sdcard/android/layout_tests/editing/deleting/delete-at-paragraph-boundaries-002.html
-/sdcard/android/layout_tests/editing/deleting/4922367.html
-/sdcard/android/layout_tests/editing/deleting/delete-br-011.html
-/sdcard/android/layout_tests/editing/deleting/delete-br-007.html
-/sdcard/android/layout_tests/editing/deleting/move-nodes-001.html
-/sdcard/android/layout_tests/editing/deleting/merge-no-br.html
-/sdcard/android/layout_tests/editing/deleting/delete-3800834-fix.html
-/sdcard/android/layout_tests/editing/deleting/delete-4038408-fix.html
-/sdcard/android/layout_tests/editing/deleting/5206311-1.html
-/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-020.html
-/sdcard/android/layout_tests/editing/deleting/delete-ws-fixup-003.html
-/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-004.html
-/sdcard/android/layout_tests/editing/deleting/delete-select-all-002.html
-/sdcard/android/layout_tests/editing/deleting/delete-contiguous-ws-001.html
-/sdcard/android/layout_tests/editing/deleting/delete-to-select-table.html
-/sdcard/android/layout_tests/editing/deleting/smart-delete-001.html
-/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-016.html
-/sdcard/android/layout_tests/editing/deleting/delete-line-003.html
-/sdcard/android/layout_tests/editing/deleting/delete-line-015.html
-/sdcard/android/layout_tests/editing/deleting/delete-at-paragraph-boundaries-011.html
-/sdcard/android/layout_tests/editing/deleting/5390681.html
-/sdcard/android/layout_tests/editing/deleting/delete-br-004.html
-/sdcard/android/layout_tests/editing/deleting/delete-at-paragraph-boundaries-007.html
-/sdcard/android/layout_tests/editing/deleting/forward-delete.html
-/sdcard/android/layout_tests/editing/deleting/delete-tab-003.html
-/sdcard/android/layout_tests/editing/deleting/collapse-whitespace-3587601-fix.html
-/sdcard/android/layout_tests/editing/deleting/pruning-after-merge-2.html
-/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-001.html
-/sdcard/android/layout_tests/editing/deleting/delete-line-end-ws-001.html
-/sdcard/android/layout_tests/editing/deleting/delete-by-word-001.html
-/sdcard/android/layout_tests/editing/deleting/delete-image-002.html
-/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-013.html
-/sdcard/android/layout_tests/editing/deleting/delete-block-contents-002.html
-/sdcard/android/layout_tests/editing/deleting/paragraph-in-preserveNewline.html
-/sdcard/android/layout_tests/editing/deleting/delete-after-span-ws-002.html
-/sdcard/android/layout_tests/editing/deleting/5272440.html
-/sdcard/android/layout_tests/editing/deleting/delete-line-012.html
-/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-009.html
-/sdcard/android/layout_tests/editing/deleting/delete-listitem-002.html
-/sdcard/android/layout_tests/editing/deleting/delete-character-001.html
-/sdcard/android/layout_tests/editing/deleting/delete-line-008.html
-/sdcard/android/layout_tests/editing/deleting/5483370.html
-/sdcard/android/layout_tests/editing/deleting/5026848-2.html
-/sdcard/android/layout_tests/editing/deleting/delete-br-001.html
-/sdcard/android/layout_tests/editing/deleting/delete-at-paragraph-boundaries-004.html
-/sdcard/android/layout_tests/editing/deleting/delete-br-013.html
-/sdcard/android/layout_tests/editing/deleting/5091898.html
-/sdcard/android/layout_tests/editing/deleting/delete-br-009.html
-/sdcard/android/layout_tests/editing/deleting/transpose-empty.html
-/sdcard/android/layout_tests/editing/deleting/merge-endOfParagraph.html
-/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-010.html
-/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-022.html
-/sdcard/android/layout_tests/editing/deleting/delete-3775172-fix.html
-/sdcard/android/layout_tests/editing/deleting/delete-mixed-editable-content-001.html
-/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-006.html
-/sdcard/android/layout_tests/editing/deleting/smart-delete-003.html
-/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-018.html
-/sdcard/android/layout_tests/editing/deleting/delete-line-005.html
-/sdcard/android/layout_tests/editing/deleting/delete-first-list-item.html
-/sdcard/android/layout_tests/editing/deleting/delete-line-017.html
-/sdcard/android/layout_tests/editing/deleting/delete-at-paragraph-boundaries-001.html
-/sdcard/android/layout_tests/editing/deleting/delete-trailing-ws-002.html
-/sdcard/android/layout_tests/editing/deleting/delete-br-010.html
-/sdcard/android/layout_tests/editing/deleting/delete-and-undo.html
-/sdcard/android/layout_tests/editing/deleting/delete-br-006.html
-/sdcard/android/layout_tests/editing/deleting/delete-at-paragraph-boundaries-009.html
-/sdcard/android/layout_tests/editing/deleting/delete-hr.html
-/sdcard/android/layout_tests/editing/deleting/delete-4083333-fix.html
-/sdcard/android/layout_tests/editing/deleting/delete-3608445-fix.html
-/sdcard/android/layout_tests/editing/deleting/delete-ws-fixup-002.html
-/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-003.html
-/sdcard/android/layout_tests/editing/deleting/delete-image-004.html
-/sdcard/android/layout_tests/editing/deleting/delete-select-all-001.html
-/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-015.html
-/sdcard/android/layout_tests/editing/deleting/delete-line-002.html
-/sdcard/android/layout_tests/editing/deleting/delete-line-014.html
-/sdcard/android/layout_tests/editing/deleting/merge-into-empty-block-2.html
-/sdcard/android/layout_tests/editing/deleting/delete-at-paragraph-boundaries-010.html
-/sdcard/android/layout_tests/editing/deleting/5390681-2.html
-/sdcard/android/layout_tests/editing/deleting/5369009.html
-/sdcard/android/layout_tests/editing/deleting/delete-br-003.html
-/sdcard/android/layout_tests/editing/deleting/delete-at-paragraph-boundaries-006.html
-/sdcard/android/layout_tests/editing/deleting/delete-tab-002.html
-/sdcard/android/layout_tests/editing/deleting/list-item-1.html
-/sdcard/android/layout_tests/editing/deleting/5168598.html
-/sdcard/android/layout_tests/editing/deleting/delete-3608430-fix.html
-/sdcard/android/layout_tests/editing/deleting/type-delete-after-quote.html
-/sdcard/android/layout_tests/editing/spelling/spelling.html
-/sdcard/android/layout_tests/editing/spelling/spellcheck-attribute.html
-/sdcard/android/layout_tests/editing/spelling/inline_spelling_markers.html
-/sdcard/android/layout_tests/editing/spelling/spelling-linebreak.html
-/sdcard/android/layout_tests/fast/media/mq-relative-constraints-05.html
-/sdcard/android/layout_tests/fast/media/mq-grid-02.html
-/sdcard/android/layout_tests/fast/media/mq-compound-query-02.html
-/sdcard/android/layout_tests/fast/media/mq-relative-constraints-09.html
-/sdcard/android/layout_tests/fast/media/mq-width-absolute-03.html
-/sdcard/android/layout_tests/fast/media/mq-invalid-media-feature-02.html
-/sdcard/android/layout_tests/fast/media/mq-simple-query-04.html
-/sdcard/android/layout_tests/fast/media/mq-min-pixel-ratio.html
-/sdcard/android/layout_tests/fast/media/implicit-media-all.html
-/sdcard/android/layout_tests/fast/media/media-descriptor-syntax-01.html
-/sdcard/android/layout_tests/fast/media/mq-simple-neg-query-03.html
-/sdcard/android/layout_tests/fast/media/viewport-media-query.html
-/sdcard/android/layout_tests/fast/media/media-descriptor-syntax-05.html
-/sdcard/android/layout_tests/fast/media/mq-invalid-syntax-01.html
-/sdcard/android/layout_tests/fast/media/mq-transition.html
-/sdcard/android/layout_tests/fast/media/mq-orientation.html
-/sdcard/android/layout_tests/fast/media/mq-invalid-syntax-05.html
-/sdcard/android/layout_tests/fast/media/mq-transform-04.html
-/sdcard/android/layout_tests/fast/media/mq-js-media-except-02.html
-/sdcard/android/layout_tests/fast/media/mq-relative-constraints-02.html
-/sdcard/android/layout_tests/fast/media/mq-js-stylesheet-media-03.html
-/sdcard/android/layout_tests/fast/media/mq-relative-constraints-06.html
-/sdcard/android/layout_tests/fast/media/mq-valueless.html
-/sdcard/android/layout_tests/fast/media/mq-compound-query-03.html
-/sdcard/android/layout_tests/fast/media/mq-simple-query-01.html
-/sdcard/android/layout_tests/fast/media/mq-invalid-media-feature-03.html
-/sdcard/android/layout_tests/fast/media/mq-width-absolute-04.html
-/sdcard/android/layout_tests/fast/media/mq-simple-query-05.html
-/sdcard/android/layout_tests/fast/media/mq-animation.html
-/sdcard/android/layout_tests/fast/media/media-descriptor-syntax-02.html
-/sdcard/android/layout_tests/fast/media/mq-simple-neg-query-04.html
-/sdcard/android/layout_tests/fast/media/media-type-syntax-01.html
-/sdcard/android/layout_tests/fast/media/media-descriptor-syntax-06.html
-/sdcard/android/layout_tests/fast/media/mq-invalid-syntax-02.html
-/sdcard/android/layout_tests/fast/media/mq-transform-01.html
-/sdcard/android/layout_tests/fast/media/monochrome.html
-/sdcard/android/layout_tests/fast/media/mq-pixel-ratio.html
-/sdcard/android/layout_tests/fast/media/mq-js-media-except-03.html
-/sdcard/android/layout_tests/fast/media/mq-relative-constraints-03.html
-/sdcard/android/layout_tests/fast/media/mq-js-stylesheet-media-04.html
-/sdcard/android/layout_tests/fast/media/mq-relative-constraints-07.html
-/sdcard/android/layout_tests/fast/media/mq-compound-query-04.html
-/sdcard/android/layout_tests/fast/media/mq-width-absolute-01.html
-/sdcard/android/layout_tests/fast/media/mq-simple-query-02.html
-/sdcard/android/layout_tests/fast/media/mq-invalid-media-feature-04.html
-/sdcard/android/layout_tests/fast/media/mq-max-pixel-ratio.html
-/sdcard/android/layout_tests/fast/media/mq-simple-neg-query-01.html
-/sdcard/android/layout_tests/fast/media/media-descriptor-syntax-03.html
-/sdcard/android/layout_tests/fast/media/mq-simple-neg-query-05.html
-/sdcard/android/layout_tests/fast/media/media-type-syntax-02.html
-/sdcard/android/layout_tests/fast/media/mq-transform-02.html
-/sdcard/android/layout_tests/fast/media/mq-invalid-syntax-03.html
-/sdcard/android/layout_tests/fast/media/mq-js-stylesheet-media-01.html
-/sdcard/android/layout_tests/fast/media/mq-relative-constraints-04.html
-/sdcard/android/layout_tests/fast/media/mq-grid-01.html
-/sdcard/android/layout_tests/fast/media/mq-compound-query-01.html
-/sdcard/android/layout_tests/fast/media/mq-min-constraint.html
-/sdcard/android/layout_tests/fast/media/mq-relative-constraints-08.html
-/sdcard/android/layout_tests/fast/media/mq-compound-query-05.html
-/sdcard/android/layout_tests/fast/media/mq-width-absolute-02.html
-/sdcard/android/layout_tests/fast/media/mq-invalid-media-feature-01.html
-/sdcard/android/layout_tests/fast/media/mq-simple-query-03.html
-/sdcard/android/layout_tests/fast/media/mq-js-media-forward-syntax.html
-/sdcard/android/layout_tests/fast/media/mq-simple-neg-query-02.html
-/sdcard/android/layout_tests/fast/media/media-descriptor-syntax-04.html
-/sdcard/android/layout_tests/fast/media/mq-aspect-ratio.html
-/sdcard/android/layout_tests/fast/media/mq-invalid-syntax-04.html
-/sdcard/android/layout_tests/fast/media/mq-transform-03.html
-/sdcard/android/layout_tests/fast/media/mq-js-media-except-01.html
-/sdcard/android/layout_tests/fast/media/mq-js-stylesheet-media-02.html
-/sdcard/android/layout_tests/fast/replaced/embed-display-none.html
-/sdcard/android/layout_tests/fast/replaced/width100percent-radio.html
-/sdcard/android/layout_tests/fast/replaced/selection-rect.html
-/sdcard/android/layout_tests/fast/replaced/applet-display-none.html
-/sdcard/android/layout_tests/fast/replaced/inline-box-wrapper-handover.html
-/sdcard/android/layout_tests/fast/replaced/maxheight-pxs.html
-/sdcard/android/layout_tests/fast/replaced/width100percent-searchfield.html
-/sdcard/android/layout_tests/fast/replaced/selection-rect-transform.html
-/sdcard/android/layout_tests/fast/replaced/minwidth-pxs.html
-/sdcard/android/layout_tests/fast/replaced/width100percent-textarea.html
-/sdcard/android/layout_tests/fast/replaced/maxwidth-pxs.html
-/sdcard/android/layout_tests/fast/replaced/absolute-position-percentage-height.html
-/sdcard/android/layout_tests/fast/replaced/004.html
-/sdcard/android/layout_tests/fast/replaced/applet-disabled-positioned.html
-/sdcard/android/layout_tests/fast/replaced/width100percent-checkbox.html
-/sdcard/android/layout_tests/fast/replaced/008.html
-/sdcard/android/layout_tests/fast/replaced/percent-height-in-anonymous-block-widget.html
-/sdcard/android/layout_tests/fast/replaced/maxheight-percent.html
-/sdcard/android/layout_tests/fast/replaced/minwidth-percent.html
-/sdcard/android/layout_tests/fast/replaced/maxwidth-percent.html
-/sdcard/android/layout_tests/fast/replaced/applet-rendering-java-disabled.html
-/sdcard/android/layout_tests/fast/replaced/width100percent-button.html
-/sdcard/android/layout_tests/fast/replaced/image-resize-width.html
-/sdcard/android/layout_tests/fast/replaced/absolute-image-sizing.html
-/sdcard/android/layout_tests/fast/replaced/001.html
-/sdcard/android/layout_tests/fast/replaced/005.html
-/sdcard/android/layout_tests/fast/replaced/object-display-none.html
-/sdcard/android/layout_tests/fast/replaced/absolute-position-percentage-width.html
-/sdcard/android/layout_tests/fast/replaced/object-align-hspace-vspace.html
-/sdcard/android/layout_tests/fast/replaced/width100percent-menulist.html
-/sdcard/android/layout_tests/fast/replaced/percent-height-in-anonymous-block-in-table.html
-/sdcard/android/layout_tests/fast/replaced/image-sizing.html
-/sdcard/android/layout_tests/fast/replaced/minheight-pxs.html
-/sdcard/android/layout_tests/fast/replaced/pdf-as-image.html
-/sdcard/android/layout_tests/fast/replaced/replaced-breaking-mixture.html
-/sdcard/android/layout_tests/fast/replaced/max-width-percent.html
-/sdcard/android/layout_tests/fast/replaced/002.html
-/sdcard/android/layout_tests/fast/replaced/006.html
-/sdcard/android/layout_tests/fast/replaced/minheight-percent.html
-/sdcard/android/layout_tests/fast/replaced/absolute-position-with-auto-width-and-left-and-right.html
-/sdcard/android/layout_tests/fast/replaced/selection-rect-in-table-cell.html
-/sdcard/android/layout_tests/fast/replaced/border-radius-clip.html
-/sdcard/android/layout_tests/fast/replaced/percent-height-in-anonymous-block.html
-/sdcard/android/layout_tests/fast/replaced/three-selects-break.html
-/sdcard/android/layout_tests/fast/replaced/image-tag.html
-/sdcard/android/layout_tests/fast/replaced/image-onload.html
-/sdcard/android/layout_tests/fast/replaced/replaced-breaking.html
-/sdcard/android/layout_tests/fast/replaced/width100percent-image.html
-/sdcard/android/layout_tests/fast/replaced/image-solid-color-with-alpha.html
-/sdcard/android/layout_tests/fast/replaced/003.html
-/sdcard/android/layout_tests/fast/replaced/replaced-child-of-absolute-with-auto-height.html
-/sdcard/android/layout_tests/fast/replaced/007.html
-/sdcard/android/layout_tests/fast/replaced/absolute-position-with-auto-height-and-top-and-bottom.html
-/sdcard/android/layout_tests/fast/replaced/width100percent-textfield.html
-/sdcard/android/layout_tests/fast/dynamic/positioned-movement-with-positioned-children.html
-/sdcard/android/layout_tests/fast/dynamic/subtree-table-cell-height.html
-/sdcard/android/layout_tests/fast/dynamic/move-node-with-selection.html
-/sdcard/android/layout_tests/fast/dynamic/create-renderer-for-whitespace-only-text.html
-/sdcard/android/layout_tests/fast/dynamic/outerHTML-doc.html
-/sdcard/android/layout_tests/fast/dynamic/window-scrollbars-test.html
-/sdcard/android/layout_tests/fast/dynamic/floating-to-positioned-2.html
-/sdcard/android/layout_tests/fast/dynamic/anchor-lock.html
-/sdcard/android/layout_tests/fast/dynamic/012.html
-/sdcard/android/layout_tests/fast/dynamic/004.html
-/sdcard/android/layout_tests/fast/dynamic/008.html
-/sdcard/android/layout_tests/fast/dynamic/float-no-longer-overhanging.html
-/sdcard/android/layout_tests/fast/dynamic/float-withdrawal-2.html
-/sdcard/android/layout_tests/fast/dynamic/float-in-trailing-whitespace-after-last-line-break.html
-/sdcard/android/layout_tests/fast/dynamic/selection-highlight-adjust.html
-/sdcard/android/layout_tests/fast/dynamic/subtree-no-common-root-static-y.html
-/sdcard/android/layout_tests/fast/dynamic/genContentDestroyChildren.html
-/sdcard/android/layout_tests/fast/dynamic/001.html
-/sdcard/android/layout_tests/fast/dynamic/link-href-change.html
-/sdcard/android/layout_tests/fast/dynamic/013.html
-/sdcard/android/layout_tests/fast/dynamic/005.html
-/sdcard/android/layout_tests/fast/dynamic/009.html
-/sdcard/android/layout_tests/fast/dynamic/float-withdrawal.html
-/sdcard/android/layout_tests/fast/dynamic/anonymous-block-layer-lost.html
-/sdcard/android/layout_tests/fast/dynamic/layer-hit-test-crash.html
-/sdcard/android/layout_tests/fast/dynamic/view-overflow.html
-/sdcard/android/layout_tests/fast/dynamic/window-resize-scrollbars-test.html
-/sdcard/android/layout_tests/fast/dynamic/010.html
-/sdcard/android/layout_tests/fast/dynamic/002.html
-/sdcard/android/layout_tests/fast/dynamic/014.html
-/sdcard/android/layout_tests/fast/dynamic/006.html
-/sdcard/android/layout_tests/fast/dynamic/flash-replacement-test.html
-/sdcard/android/layout_tests/fast/dynamic/insertAdjacentElement.html
-/sdcard/android/layout_tests/fast/dynamic/insert-before-table-part-in-continuation.html
-/sdcard/android/layout_tests/fast/dynamic/staticY.html
-/sdcard/android/layout_tests/fast/dynamic/anonymous-block-orphaned-lines.html
-/sdcard/android/layout_tests/fast/dynamic/noninlinebadness.html
-/sdcard/android/layout_tests/fast/dynamic/subtree-parent-static-y.html
-/sdcard/android/layout_tests/fast/dynamic/outerHTML-img.html
-/sdcard/android/layout_tests/fast/dynamic/staticY-marking-parents-regression.html
-/sdcard/android/layout_tests/fast/dynamic/floating-to-positioned.html
-/sdcard/android/layout_tests/fast/dynamic/subtree-boundary-percent-height.html
-/sdcard/android/layout_tests/fast/dynamic/011.html
-/sdcard/android/layout_tests/fast/dynamic/containing-block-change.html
-/sdcard/android/layout_tests/fast/dynamic/015.html
-/sdcard/android/layout_tests/fast/dynamic/007.html
-/sdcard/android/layout_tests/fast/text/firstline/001.html
-/sdcard/android/layout_tests/fast/text/firstline/002.html
-/sdcard/android/layout_tests/fast/text/firstline/003.html
-/sdcard/android/layout_tests/fast/text/international/hindi-spacing.html
-/sdcard/android/layout_tests/fast/text/international/bidi-L2-run-reordering.html
-/sdcard/android/layout_tests/fast/text/international/bidi-override.html
-/sdcard/android/layout_tests/fast/text/international/hindi-whitespace.html
-/sdcard/android/layout_tests/fast/text/international/bidi-european-terminators.html
-/sdcard/android/layout_tests/fast/text/international/bidi-LDB-2-formatting-characters.html
-/sdcard/android/layout_tests/fast/text/international/bidi-AN-after-L.html
-/sdcard/android/layout_tests/fast/text/international/bidi-LDB-2-CSS.html
-/sdcard/android/layout_tests/fast/text/international/bidi-control-chars-treated-as-ZWS.html
-/sdcard/android/layout_tests/fast/text/international/bidi-neutral-directionality-paragraph-start.html
-/sdcard/android/layout_tests/fast/text/international/bidi-linebreak-001.html
-/sdcard/android/layout_tests/fast/text/international/bidi-linebreak-003.html
-/sdcard/android/layout_tests/fast/text/international/002.html
-/sdcard/android/layout_tests/fast/text/international/bidi-explicit-embedding.html
-/sdcard/android/layout_tests/fast/text/international/rtl-white-space-pre-wrap.html
-/sdcard/android/layout_tests/fast/text/international/bidi-CS-after-AN.html
-/sdcard/android/layout_tests/fast/text/international/complex-character-based-fallback.html
-/sdcard/android/layout_tests/fast/text/international/wrap-CJK-001.html
-/sdcard/android/layout_tests/fast/text/international/bidi-listbox-atsui.html
-/sdcard/android/layout_tests/fast/text/international/thai-line-breaks.html
-/sdcard/android/layout_tests/fast/text/international/bidi-neutral-run.html
-/sdcard/android/layout_tests/fast/text/international/bidi-innertext.html
-/sdcard/android/layout_tests/fast/text/international/bidi-listbox.html
-/sdcard/android/layout_tests/fast/text/international/khmer-selection.html
-/sdcard/android/layout_tests/fast/text/international/thai-baht-space.html
-/sdcard/android/layout_tests/fast/text/international/rtl-caret.html
-/sdcard/android/layout_tests/fast/text/international/bidi-AN-after-empty-run.html
-/sdcard/android/layout_tests/fast/text/international/001.html
-/sdcard/android/layout_tests/fast/text/international/bidi-linebreak-002.html
-/sdcard/android/layout_tests/fast/text/international/danda-space.html
-/sdcard/android/layout_tests/fast/text/international/003.html
-/sdcard/android/layout_tests/fast/text/international/bidi-ignored-for-first-child-inline.html
-/sdcard/android/layout_tests/fast/text/international/bidi-layout-across-linebreak.html
-/sdcard/android/layout_tests/fast/text/international/bidi-menulist.html
-/sdcard/android/layout_tests/fast/text/international/bidi-LDB-2-HTML.html
-/sdcard/android/layout_tests/fast/text/whitespace/pre-wrap-overflow-selection.html
-/sdcard/android/layout_tests/fast/text/whitespace/pre-newline-box-test.html
-/sdcard/android/layout_tests/fast/text/whitespace/span-in-word-space-causes-overflow.html
-/sdcard/android/layout_tests/fast/text/whitespace/nowrap-clear-float.html
-/sdcard/android/layout_tests/fast/text/whitespace/pre-wrap-line-test.html
-/sdcard/android/layout_tests/fast/text/whitespace/010.html
-/sdcard/android/layout_tests/fast/text/whitespace/020.html
-/sdcard/android/layout_tests/fast/text/whitespace/002.html
-/sdcard/android/layout_tests/fast/text/whitespace/030.html
-/sdcard/android/layout_tests/fast/text/whitespace/012.html
-/sdcard/android/layout_tests/fast/text/whitespace/022.html
-/sdcard/android/layout_tests/fast/text/whitespace/004.html
-/sdcard/android/layout_tests/fast/text/whitespace/014.html
-/sdcard/android/layout_tests/fast/text/whitespace/024.html
-/sdcard/android/layout_tests/fast/text/whitespace/006.html
-/sdcard/android/layout_tests/fast/text/whitespace/016.html
-/sdcard/android/layout_tests/fast/text/whitespace/008.html
-/sdcard/android/layout_tests/fast/text/whitespace/026.html
-/sdcard/android/layout_tests/fast/text/whitespace/018.html
-/sdcard/android/layout_tests/fast/text/whitespace/028.html
-/sdcard/android/layout_tests/fast/text/whitespace/normal-after-nowrap-breaking.html
-/sdcard/android/layout_tests/fast/text/whitespace/pre-break-word.html
-/sdcard/android/layout_tests/fast/text/whitespace/nbsp-mode-and-linewraps.html
-/sdcard/android/layout_tests/fast/text/whitespace/001.html
-/sdcard/android/layout_tests/fast/text/whitespace/011.html
-/sdcard/android/layout_tests/fast/text/whitespace/tab-character-basics.html
-/sdcard/android/layout_tests/fast/text/whitespace/003.html
-/sdcard/android/layout_tests/fast/text/whitespace/021.html
-/sdcard/android/layout_tests/fast/text/whitespace/013.html
-/sdcard/android/layout_tests/fast/text/whitespace/023.html
-/sdcard/android/layout_tests/fast/text/whitespace/005.html
-/sdcard/android/layout_tests/fast/text/whitespace/015.html
-/sdcard/android/layout_tests/fast/text/whitespace/025.html
-/sdcard/android/layout_tests/fast/text/whitespace/007.html
-/sdcard/android/layout_tests/fast/text/whitespace/017.html
-/sdcard/android/layout_tests/fast/text/whitespace/pre-wrap-spaces-after-newline.html
-/sdcard/android/layout_tests/fast/text/whitespace/027.html
-/sdcard/android/layout_tests/fast/text/whitespace/009.html
-/sdcard/android/layout_tests/fast/text/whitespace/019.html
-/sdcard/android/layout_tests/fast/text/whitespace/pre-wrap-last-char.html
-/sdcard/android/layout_tests/fast/text/whitespace/029.html
-/sdcard/android/layout_tests/fast/text/basic/001.html
-/sdcard/android/layout_tests/fast/text/basic/002.html
-/sdcard/android/layout_tests/fast/text/basic/011.html
-/sdcard/android/layout_tests/fast/text/basic/generic-family-changes.html
-/sdcard/android/layout_tests/fast/text/basic/003.html
-/sdcard/android/layout_tests/fast/text/basic/012.html
-/sdcard/android/layout_tests/fast/text/basic/004.html
-/sdcard/android/layout_tests/fast/text/basic/013.html
-/sdcard/android/layout_tests/fast/text/basic/005.html
-/sdcard/android/layout_tests/fast/text/basic/014.html
-/sdcard/android/layout_tests/fast/text/basic/006.html
-/sdcard/android/layout_tests/fast/text/basic/015.html
-/sdcard/android/layout_tests/fast/text/basic/007.html
-/sdcard/android/layout_tests/fast/text/basic/008.html
-/sdcard/android/layout_tests/fast/text/basic/009.html
-/sdcard/android/layout_tests/fast/text/basic/generic-family-reset.html
-/sdcard/android/layout_tests/fast/text/in-rendered-text-rtl.html
-/sdcard/android/layout_tests/fast/text/selection-painted-separately.html
-/sdcard/android/layout_tests/fast/text/bidi-embedding-pop-and-push-same.html
-/sdcard/android/layout_tests/fast/text/wbr-in-pre-crash.html
-/sdcard/android/layout_tests/fast/text/atsui-spacing-features.html
-/sdcard/android/layout_tests/fast/text/textIteratorNilRenderer.html
-/sdcard/android/layout_tests/fast/text/drawBidiText.html
-/sdcard/android/layout_tests/fast/text/selection-hard-linebreak.html
-/sdcard/android/layout_tests/fast/text/word-break.html
-/sdcard/android/layout_tests/fast/text/break-word.html
-/sdcard/android/layout_tests/fast/text/font-initial.html
-/sdcard/android/layout_tests/fast/text/complex-text-opacity.html
-/sdcard/android/layout_tests/fast/text/stroking.html
-/sdcard/android/layout_tests/fast/text/midword-break-hang.html
-/sdcard/android/layout_tests/fast/text/atsui-partial-selection.html
-/sdcard/android/layout_tests/fast/text/embed-at-end-of-pre-wrap-line.html
-/sdcard/android/layout_tests/fast/text/atsui-multiple-renderers.html
-/sdcard/android/layout_tests/fast/text/shadow-translucent-fill.html
-/sdcard/android/layout_tests/fast/text/apply-start-width-after-skipped-text.html
-/sdcard/android/layout_tests/fast/text/capitalize-preserve-nbsp.html
-/sdcard/android/layout_tests/fast/text/updateNewFont.html
-/sdcard/android/layout_tests/fast/text/atsui-rtl-override-selection.html
-/sdcard/android/layout_tests/fast/text/align-center-rtl-spill.html
-/sdcard/android/layout_tests/fast/text/wbr.html
-/sdcard/android/layout_tests/fast/text/cg-vs-atsui.html
-/sdcard/android/layout_tests/fast/text/monospace-width-cache.html
-/sdcard/android/layout_tests/fast/text/soft-hyphen-2.html
-/sdcard/android/layout_tests/fast/text/atsui-pointtooffset-calls-cg.html
-/sdcard/android/layout_tests/fast/text/justified-selection.html
-/sdcard/android/layout_tests/fast/text/atsui-kerning-and-ligatures.html
-/sdcard/android/layout_tests/fast/text/wbr-pre.html
-/sdcard/android/layout_tests/fast/text/capitalize-boundaries.html
-/sdcard/android/layout_tests/fast/text/trailing-white-space.html
-/sdcard/android/layout_tests/fast/text/capitalize-empty-generated-string.html
-/sdcard/android/layout_tests/fast/text/stripNullFromText.html
-/sdcard/android/layout_tests/fast/text/letter-spacing-negative-opacity.html
-/sdcard/android/layout_tests/fast/text/atsui-small-caps-punctuation-size.html
-/sdcard/android/layout_tests/fast/text/word-break-soft-hyphen.html
-/sdcard/android/layout_tests/fast/text/fixed-pitch-control-characters.html
-/sdcard/android/layout_tests/fast/text/cg-fallback-bolding.html
-/sdcard/android/layout_tests/fast/text/line-breaks-after-white-space.html
-/sdcard/android/layout_tests/fast/text/text-letter-spacing.html
-/sdcard/android/layout_tests/fast/text/soft-hyphen-3.html
-/sdcard/android/layout_tests/fast/text/should-use-atsui.html
-/sdcard/android/layout_tests/fast/text/wide-zero-width-space.html
-/sdcard/android/layout_tests/fast/text/justified-selection-at-edge.html
-/sdcard/android/layout_tests/fast/text/trailing-white-space-2.html
-/sdcard/android/layout_tests/fast/text/word-break-run-rounding.html
-/sdcard/android/layout_tests/fast/text/softHyphen.html
-/sdcard/android/layout_tests/fast/text/delete-hard-break-character.html
-/sdcard/android/layout_tests/fast/text/line-breaks.html
-/sdcard/android/layout_tests/fast/text/wbr-styled.html
-/sdcard/android/layout_tests/fast/text/large-text-composed-char.html
-/sdcard/android/layout_tests/fast/text/shadow-no-blur.html
-/sdcard/android/layout_tests/fast/text/reset-emptyRun.html
-/sdcard/android/layout_tests/fast/text/word-space.html
-/sdcard/android/layout_tests/fast/text/midword-break-after-breakable-char.html
-/sdcard/android/layout_tests/fast/text/stroking-decorations.html
-/sdcard/android/layout_tests/fast/encoding/utf-16-little-endian.html
-/sdcard/android/layout_tests/fast/encoding/denormalised-voiced-japanese-chars.html
-/sdcard/android/layout_tests/fast/encoding/utf-16-no-bom.xml
-/sdcard/android/layout_tests/fast/encoding/utf-16-big-endian.html
-/sdcard/android/layout_tests/fast/encoding/xmacroman-encoding-test.html
-/sdcard/android/layout_tests/fast/encoding/invalid-UTF-8.html
-/sdcard/android/layout_tests/fast/multicol/float-avoidance.html
-/sdcard/android/layout_tests/fast/multicol/negativeColumnWidth.html
-/sdcard/android/layout_tests/fast/multicol/column-rules.html
-/sdcard/android/layout_tests/fast/multicol/column-rules-stacking.html
-/sdcard/android/layout_tests/fast/multicol/zeroColumnCount.html
-/sdcard/android/layout_tests/fast/multicol/columns-shorthand-parsing.html
-/sdcard/android/layout_tests/fast/multicol/float-multicol.html
-/sdcard/android/layout_tests/fast/doctypes/001.html
-/sdcard/android/layout_tests/fast/doctypes/002.html
-/sdcard/android/layout_tests/fast/doctypes/003.html
-/sdcard/android/layout_tests/fast/doctypes/004.html
-/sdcard/android/layout_tests/fast/css-generated-content/table-row-group-to-inline.html
-/sdcard/android/layout_tests/fast/css-generated-content/spellingToolTip-assert.html
-/sdcard/android/layout_tests/fast/css-generated-content/no-openclose-quote.html
-/sdcard/android/layout_tests/fast/css-generated-content/before-with-first-letter.html
-/sdcard/android/layout_tests/fast/css-generated-content/table-row-group-with-before.html
-/sdcard/android/layout_tests/fast/css-generated-content/010.html
-/sdcard/android/layout_tests/fast/css-generated-content/table-with-before.html
-/sdcard/android/layout_tests/fast/css-generated-content/002.html
-/sdcard/android/layout_tests/fast/css-generated-content/012.html
-/sdcard/android/layout_tests/fast/css-generated-content/004.html
-/sdcard/android/layout_tests/fast/css-generated-content/014.html
-/sdcard/android/layout_tests/fast/css-generated-content/016.html
-/sdcard/android/layout_tests/fast/css-generated-content/008.html
-/sdcard/android/layout_tests/fast/css-generated-content/after-order.html
-/sdcard/android/layout_tests/fast/css-generated-content/table-cell-before-content.html
-/sdcard/android/layout_tests/fast/css-generated-content/visibleContentHiddenParent.html
-/sdcard/android/layout_tests/fast/css-generated-content/inline-display-types.html
-/sdcard/android/layout_tests/fast/css-generated-content/positioned-background-hit-test-crash.html
-/sdcard/android/layout_tests/fast/css-generated-content/001.html
-/sdcard/android/layout_tests/fast/css-generated-content/011.html
-/sdcard/android/layout_tests/fast/css-generated-content/003.html
-/sdcard/android/layout_tests/fast/css-generated-content/beforeAfter-interdocument.html
-/sdcard/android/layout_tests/fast/css-generated-content/013.html
-/sdcard/android/layout_tests/fast/css-generated-content/005.html
-/sdcard/android/layout_tests/fast/css-generated-content/hover-style-change.html
-/sdcard/android/layout_tests/fast/css-generated-content/table-row-with-before.html
-/sdcard/android/layout_tests/fast/css-generated-content/absolute-position-inside-inline.html
-/sdcard/android/layout_tests/fast/css-generated-content/015.html
-/sdcard/android/layout_tests/fast/css-generated-content/hit-test-generated-content.html
-/sdcard/android/layout_tests/fast/css-generated-content/007.html
-/sdcard/android/layout_tests/fast/css-generated-content/009.html
-/sdcard/android/layout_tests/fast/css-generated-content/wbr-with-before-content.html
-/sdcard/android/layout_tests/fast/lists/decimal-leading-zero.html
-/sdcard/android/layout_tests/fast/lists/ol-display-types.html
-/sdcard/android/layout_tests/fast/lists/li-style-alpha-huge-value-crash.html
-/sdcard/android/layout_tests/fast/lists/ol-start-dynamic.html
-/sdcard/android/layout_tests/fast/lists/numeric-markers-outside-list.html
-/sdcard/android/layout_tests/fast/lists/marker-image-error.html
-/sdcard/android/layout_tests/fast/lists/marker-before-empty-inline.html
-/sdcard/android/layout_tests/fast/lists/list-marker-with-line-height.html
-/sdcard/android/layout_tests/fast/lists/scrolled-marker-paint.html
-/sdcard/android/layout_tests/fast/lists/li-values.html
-/sdcard/android/layout_tests/fast/lists/002.html
-/sdcard/android/layout_tests/fast/lists/dynamic-marker-crash.html
-/sdcard/android/layout_tests/fast/lists/list-item-line-height.html
-/sdcard/android/layout_tests/fast/lists/004.html
-/sdcard/android/layout_tests/fast/lists/drag-into-marker.html
-/sdcard/android/layout_tests/fast/lists/list-style-none-crash.html
-/sdcard/android/layout_tests/fast/lists/alpha-list-wrap.html
-/sdcard/android/layout_tests/fast/lists/006.html
-/sdcard/android/layout_tests/fast/lists/ol-start-parsing.html
-/sdcard/android/layout_tests/fast/lists/008.html
-/sdcard/android/layout_tests/fast/lists/inlineBoxWrapperNullCheck.html
-/sdcard/android/layout_tests/fast/lists/w3-list-styles.html
-/sdcard/android/layout_tests/fast/lists/item-not-in-list-line-wrapping.html
-/sdcard/android/layout_tests/fast/lists/olstart.html
-/sdcard/android/layout_tests/fast/lists/big-list-marker.html
-/sdcard/android/layout_tests/fast/lists/markers-in-selection.html
-/sdcard/android/layout_tests/fast/lists/list-style-type-dynamic-change.html
-/sdcard/android/layout_tests/fast/lists/001.html
-/sdcard/android/layout_tests/fast/lists/ordered-list-with-no-ol-tag.html
-/sdcard/android/layout_tests/fast/lists/003.html
-/sdcard/android/layout_tests/fast/lists/005.html
-/sdcard/android/layout_tests/fast/lists/li-br.html
-/sdcard/android/layout_tests/fast/lists/007.html
-/sdcard/android/layout_tests/fast/lists/009.html
-/sdcard/android/layout_tests/fast/transforms/transform-overflow.html
-/sdcard/android/layout_tests/fast/transforms/transforms-with-opacity.html
-/sdcard/android/layout_tests/fast/transforms/transformed-caret.html
-/sdcard/android/layout_tests/fast/transforms/bounding-rect-zoom.html
-/sdcard/android/layout_tests/fast/transforms/matrix-01.html
-/sdcard/android/layout_tests/fast/transforms/matrix-02.html
-/sdcard/android/layout_tests/fast/transforms/overflow-with-transform.html
-/sdcard/android/layout_tests/fast/transforms/transformed-document-element.html
-/sdcard/android/layout_tests/fast/transforms/transforms-with-zoom.html
-/sdcard/android/layout_tests/fast/transforms/transformed-focused-text-input.html
-/sdcard/android/layout_tests/fast/transforms/identity-matrix.html
-/sdcard/android/layout_tests/fast/transforms/transform-on-inline.html
-/sdcard/android/layout_tests/fast/transforms/transform-positioned-ancestor.html
-/sdcard/android/layout_tests/fast/transforms/skew-with-unitless-zero.html
-/sdcard/android/layout_tests/fast/transforms/transform-table-row.html
-/sdcard/android/layout_tests/fast/transforms/shadows.html
-/sdcard/android/layout_tests/fast/transforms/diamond.html
-/sdcard/android/layout_tests/fast/borders/borderRadiusSolid01.html
-/sdcard/android/layout_tests/fast/borders/borderRadiusDouble01.html
-/sdcard/android/layout_tests/fast/borders/block-mask-overlay-image.html
-/sdcard/android/layout_tests/fast/borders/borderRadiusDouble03.html
-/sdcard/android/layout_tests/fast/borders/borderRadiusSolid03.html
-/sdcard/android/layout_tests/fast/borders/border-color-inherit.html
-/sdcard/android/layout_tests/fast/borders/svg-as-border-image-2.html
-/sdcard/android/layout_tests/fast/borders/borderRadiusInvalidColor.html
-/sdcard/android/layout_tests/fast/borders/borderRadiusDotted02.html
-/sdcard/android/layout_tests/fast/borders/border-image-scale-transform.html
-/sdcard/android/layout_tests/fast/borders/border-fit.html
-/sdcard/android/layout_tests/fast/borders/borderRadiusArcs01.html
-/sdcard/android/layout_tests/fast/borders/borderRadiusDashed01.html
-/sdcard/android/layout_tests/fast/borders/borderRadiusDashed03.html
-/sdcard/android/layout_tests/fast/borders/fieldsetBorderRadius.html
-/sdcard/android/layout_tests/fast/borders/borderRadiusAllStylesAllCorners.html
-/sdcard/android/layout_tests/fast/borders/border-radius-split-inline.html
-/sdcard/android/layout_tests/fast/borders/border-radius-constraints.html
-/sdcard/android/layout_tests/fast/borders/borderRadiusGroove01.html
-/sdcard/android/layout_tests/fast/borders/border-image-omit-right-slice.html
-/sdcard/android/layout_tests/fast/borders/borderRadiusDouble02.html
-/sdcard/android/layout_tests/fast/borders/borderRadiusSolid02.html
-/sdcard/android/layout_tests/fast/borders/outline-offset-min-assert.html
-/sdcard/android/layout_tests/fast/borders/borderRadiusSolid04.html
-/sdcard/android/layout_tests/fast/borders/border-radius-huge-assert.html
-/sdcard/android/layout_tests/fast/borders/borderRadiusInset01.html
-/sdcard/android/layout_tests/fast/borders/borderRadiusDotted01.html
-/sdcard/android/layout_tests/fast/borders/borderRadiusOutset01.html
-/sdcard/android/layout_tests/fast/borders/svg-as-border-image.html
-/sdcard/android/layout_tests/fast/borders/borderRadiusDotted03.html
-/sdcard/android/layout_tests/fast/borders/border-image-border-radius.html
-/sdcard/android/layout_tests/fast/borders/borderRadiusDashed02.html
-/sdcard/android/layout_tests/fast/borders/borderRadiusRidge01.html
-/sdcard/android/layout_tests/fast/borders/border-image-rotate-transform.html
-/sdcard/android/layout_tests/fast/borders/inline-mask-overlay-image.html
-/sdcard/android/layout_tests/fast/borders/borderRadiusGroove02.html
-/sdcard/android/layout_tests/fast/borders/border-image-01.html
-/sdcard/android/layout_tests/fast/innerHTML/001.html
-/sdcard/android/layout_tests/fast/innerHTML/002.html
-/sdcard/android/layout_tests/fast/innerHTML/003.html
-/sdcard/android/layout_tests/fast/innerHTML/006.html
-/sdcard/android/layout_tests/fast/selectors/175a.html
-/sdcard/android/layout_tests/fast/selectors/155c.html
-/sdcard/android/layout_tests/fast/selectors/059.html
-/sdcard/android/layout_tests/fast/selectors/066b.html
-/sdcard/android/layout_tests/fast/selectors/168.html
-/sdcard/android/layout_tests/fast/selectors/177a.html
-/sdcard/android/layout_tests/fast/selectors/087b.html
-/sdcard/android/layout_tests/fast/selectors/020.html
-/sdcard/android/layout_tests/fast/selectors/012.html
-/sdcard/android/layout_tests/fast/selectors/040.html
-/sdcard/android/layout_tests/fast/selectors/004.html
-/sdcard/android/layout_tests/fast/selectors/032.html
-/sdcard/android/layout_tests/fast/selectors/060.html
-/sdcard/android/layout_tests/fast/selectors/016.html
-/sdcard/android/layout_tests/fast/selectors/044.html
-/sdcard/android/layout_tests/fast/selectors/008.html
-/sdcard/android/layout_tests/fast/selectors/072.html
-/sdcard/android/layout_tests/fast/selectors/064.html
-/sdcard/android/layout_tests/fast/selectors/056.html
-/sdcard/android/layout_tests/fast/selectors/018b.html
-/sdcard/android/layout_tests/fast/selectors/090b.html
-/sdcard/android/layout_tests/fast/selectors/045c.html
-/sdcard/android/layout_tests/fast/selectors/170d.html
-/sdcard/android/layout_tests/fast/selectors/157.html
-/sdcard/android/layout_tests/fast/selectors/039b.html
-/sdcard/android/layout_tests/fast/selectors/156b.html
-/sdcard/android/layout_tests/fast/selectors/175b.html
-/sdcard/android/layout_tests/fast/selectors/155d.html
-/sdcard/android/layout_tests/fast/selectors/167a.html
-/sdcard/android/layout_tests/fast/selectors/169.html
-/sdcard/android/layout_tests/fast/selectors/077b.html
-/sdcard/android/layout_tests/fast/selectors/177b.html
-/sdcard/android/layout_tests/fast/selectors/169a.html
-/sdcard/android/layout_tests/fast/selectors/001.html
-/sdcard/android/layout_tests/fast/selectors/021.html
-/sdcard/android/layout_tests/fast/selectors/unqualified-hover-quirks.html
-/sdcard/android/layout_tests/fast/selectors/013.html
-/sdcard/android/layout_tests/fast/selectors/041.html
-/sdcard/android/layout_tests/fast/selectors/021b.html
-/sdcard/android/layout_tests/fast/selectors/005.html
-/sdcard/android/layout_tests/fast/selectors/061.html
-/sdcard/android/layout_tests/fast/selectors/170.html
-/sdcard/android/layout_tests/fast/selectors/017.html
-/sdcard/android/layout_tests/fast/selectors/170a.html
-/sdcard/android/layout_tests/fast/selectors/009.html
-/sdcard/android/layout_tests/fast/selectors/045.html
-/sdcard/android/layout_tests/fast/selectors/154.html
-/sdcard/android/layout_tests/fast/selectors/044b.html
-/sdcard/android/layout_tests/fast/selectors/065.html
-/sdcard/android/layout_tests/fast/selectors/155a.html
-/sdcard/android/layout_tests/fast/selectors/166.html
-/sdcard/android/layout_tests/fast/selectors/158.html
-/sdcard/android/layout_tests/fast/selectors/077.html
-/sdcard/android/layout_tests/fast/selectors/175c.html
-/sdcard/android/layout_tests/fast/selectors/089.html
-/sdcard/android/layout_tests/fast/selectors/088b.html
-/sdcard/android/layout_tests/fast/selectors/nondeterministic-combinators.html
-/sdcard/android/layout_tests/fast/selectors/unqualified-hover-strict.html
-/sdcard/android/layout_tests/fast/selectors/010.html
-/sdcard/android/layout_tests/fast/selectors/002.html
-/sdcard/android/layout_tests/fast/selectors/014.html
-/sdcard/android/layout_tests/fast/selectors/042.html
-/sdcard/android/layout_tests/fast/selectors/006.html
-/sdcard/android/layout_tests/fast/selectors/034.html
-/sdcard/android/layout_tests/fast/selectors/062.html
-/sdcard/android/layout_tests/fast/selectors/007a.html
-/sdcard/android/layout_tests/fast/selectors/054.html
-/sdcard/android/layout_tests/fast/selectors/018.html
-/sdcard/android/layout_tests/fast/selectors/046.html
-/sdcard/android/layout_tests/fast/selectors/170b.html
-/sdcard/android/layout_tests/fast/selectors/072b.html
-/sdcard/android/layout_tests/fast/selectors/044c.html
-/sdcard/android/layout_tests/fast/selectors/038.html
-/sdcard/android/layout_tests/fast/selectors/155.html
-/sdcard/android/layout_tests/fast/selectors/066.html
-/sdcard/android/layout_tests/fast/selectors/058.html
-/sdcard/android/layout_tests/fast/selectors/155b.html
-/sdcard/android/layout_tests/fast/selectors/166a.html
-/sdcard/android/layout_tests/fast/selectors/167.html
-/sdcard/android/layout_tests/fast/selectors/159.html
-/sdcard/android/layout_tests/fast/selectors/168a.html
-/sdcard/android/layout_tests/fast/selectors/078b.html
-/sdcard/android/layout_tests/fast/selectors/011.html
-/sdcard/android/layout_tests/fast/selectors/003.html
-/sdcard/android/layout_tests/fast/selectors/015.html
-/sdcard/android/layout_tests/fast/selectors/043.html
-/sdcard/android/layout_tests/fast/selectors/160.html
-/sdcard/android/layout_tests/fast/selectors/063.html
-/sdcard/android/layout_tests/fast/selectors/043b.html
-/sdcard/android/layout_tests/fast/selectors/007b.html
-/sdcard/android/layout_tests/fast/selectors/027.html
-/sdcard/android/layout_tests/fast/selectors/019.html
-/sdcard/android/layout_tests/fast/selectors/083.html
-/sdcard/android/layout_tests/fast/selectors/045b.html
-/sdcard/android/layout_tests/fast/selectors/170c.html
-/sdcard/android/layout_tests/fast/selectors/044d.html
-/sdcard/android/layout_tests/fast/selectors/039.html
-/sdcard/android/layout_tests/fast/overflow/overflow-focus-ring.html
-/sdcard/android/layout_tests/fast/overflow/overflow-x-y.html
-/sdcard/android/layout_tests/fast/overflow/overflow-text-hit-testing.html
-/sdcard/android/layout_tests/fast/overflow/unreachable-overflow-rtl-bug.html
-/sdcard/android/layout_tests/fast/overflow/overflow-auto-position-absolute.html
-/sdcard/android/layout_tests/fast/overflow/scrollRevealButton.html
-/sdcard/android/layout_tests/fast/overflow/overflow-rtl-inline-scrollbar.html
-/sdcard/android/layout_tests/fast/overflow/002.html
-/sdcard/android/layout_tests/fast/overflow/overflow-rtl.html
-/sdcard/android/layout_tests/fast/overflow/004.html
-/sdcard/android/layout_tests/fast/overflow/overflow-stacking.html
-/sdcard/android/layout_tests/fast/overflow/006.html
-/sdcard/android/layout_tests/fast/overflow/border-radius-clipping.html
-/sdcard/android/layout_tests/fast/overflow/scrollbar-position-update.html
-/sdcard/android/layout_tests/fast/overflow/008.html
-/sdcard/android/layout_tests/fast/overflow/overflow-float-stacking.html
-/sdcard/android/layout_tests/fast/overflow/scroll-nested-positioned-layer-in-overflow.html
-/sdcard/android/layout_tests/fast/overflow/image-selection-highlight.html
-/sdcard/android/layout_tests/fast/overflow/childFocusRingClip.html
-/sdcard/android/layout_tests/fast/overflow/position-relative.html
-/sdcard/android/layout_tests/fast/overflow/dynamic-hidden.html
-/sdcard/android/layout_tests/fast/overflow/overflow_hidden.html
-/sdcard/android/layout_tests/fast/overflow/clip-rects-fixed-ancestor.html
-/sdcard/android/layout_tests/fast/overflow/infiniteRecursionGuard.html
-/sdcard/android/layout_tests/fast/overflow/float-in-relpositioned.html
-/sdcard/android/layout_tests/fast/overflow/table-overflow-float.html
-/sdcard/android/layout_tests/fast/overflow/003.xml
-/sdcard/android/layout_tests/fast/overflow/overflow-auto-table.html
-/sdcard/android/layout_tests/fast/overflow/unreachable-content-test.html
-/sdcard/android/layout_tests/fast/overflow/infiniteRecursion.html
-/sdcard/android/layout_tests/fast/overflow/001.html
-/sdcard/android/layout_tests/fast/overflow/hit-test-overflow-controls.html
-/sdcard/android/layout_tests/fast/overflow/005.html
-/sdcard/android/layout_tests/fast/overflow/007.html
-/sdcard/android/layout_tests/fast/overflow/overflow-with-local-background-attachment.html
-/sdcard/android/layout_tests/fast/overflow/hidden-scrollbar-resize.html
-/sdcard/android/layout_tests/fast/events/context-no-deselect.html
-/sdcard/android/layout_tests/fast/events/autoscroll.html
-/sdcard/android/layout_tests/fast/events/5056619.html
-/sdcard/android/layout_tests/fast/events/updateLayoutForHitTest.html
-/sdcard/android/layout_tests/fast/events/label-focus.html
-/sdcard/android/layout_tests/fast/events/keydown-1.html
-/sdcard/android/layout_tests/fast/events/onloadFrameCrash.html
-/sdcard/android/layout_tests/fast/events/event-listener-on-link.html
-/sdcard/android/layout_tests/fast/events/onload-re-entry.html
-/sdcard/android/layout_tests/fast/events/standalone-image-drag-to-editable.html
-/sdcard/android/layout_tests/fast/events/focusingUnloadedFrame.html
-/sdcard/android/layout_tests/fast/events/event-sender-mouse-moved.html
-/sdcard/android/layout_tests/fast/events/reveal-link-when-focused.html
-/sdcard/android/layout_tests/fast/events/mouseout-dead-node.html
-/sdcard/android/layout_tests/fast/html/keygen.html
-/sdcard/android/layout_tests/fast/html/marquee-scroll.html
-/sdcard/android/layout_tests/fast/html/link-rel-stylesheet.html
-/sdcard/android/layout_tests/fast/html/listing.html
-/sdcard/android/layout_tests/fast/images/svg-as-background.html
-/sdcard/android/layout_tests/fast/images/pdf-as-image-landscape.html
-/sdcard/android/layout_tests/fast/images/pdf-as-tiled-background.html
-/sdcard/android/layout_tests/fast/images/pdf-as-image.html
-/sdcard/android/layout_tests/fast/images/image-map-anchor-children.html
-/sdcard/android/layout_tests/fast/images/animated-gif-with-offsets.html
-/sdcard/android/layout_tests/fast/images/favicon-as-image.html
-/sdcard/android/layout_tests/fast/images/svg-width-100p-as-background.html
-/sdcard/android/layout_tests/fast/images/svg-as-tiled-background.html
-/sdcard/android/layout_tests/fast/images/svg-as-image.html
-/sdcard/android/layout_tests/fast/images/object-image.html
-/sdcard/android/layout_tests/fast/images/pdf-as-background.html
-/sdcard/android/layout_tests/fast/images/imagemap-case.html
-/sdcard/android/layout_tests/fast/images/svg-as-relative-image.html
-/sdcard/android/layout_tests/fast/images/embed-image.html
-/sdcard/android/layout_tests/fast/images/animated-svg-as-image.html
-/sdcard/android/layout_tests/fast/images/image-in-map.html
-/sdcard/android/layout_tests/fast/images/icon-decoding.html
-/sdcard/android/layout_tests/fast/inline-block/14498-positionForCoordinates.html
-/sdcard/android/layout_tests/fast/inline-block/001.html
-/sdcard/android/layout_tests/fast/inline-block/002.html
-/sdcard/android/layout_tests/fast/inline-block/003.html
-/sdcard/android/layout_tests/fast/inline-block/004.html
-/sdcard/android/layout_tests/fast/inline-block/005.html
-/sdcard/android/layout_tests/fast/inline-block/contenteditable-baseline.html
-/sdcard/android/layout_tests/fast/inline-block/006.html
-/sdcard/android/layout_tests/fast/inline-block/inline-block-vertical-align.html
-/sdcard/android/layout_tests/fast/inline-block/tricky-baseline.html
-/sdcard/android/layout_tests/fast/inline-block/overflow-clip.html
-/sdcard/android/layout_tests/fast/inspector/matchedrules.html
-/sdcard/android/layout_tests/fast/inspector/style.html
-/sdcard/android/layout_tests/fast/flexbox/010.html
-/sdcard/android/layout_tests/fast/flexbox/020.html
-/sdcard/android/layout_tests/fast/flexbox/002.html
-/sdcard/android/layout_tests/fast/flexbox/012.html
-/sdcard/android/layout_tests/fast/flexbox/022.html
-/sdcard/android/layout_tests/fast/flexbox/004.html
-/sdcard/android/layout_tests/fast/flexbox/014.html
-/sdcard/android/layout_tests/fast/flexbox/024.html
-/sdcard/android/layout_tests/fast/flexbox/006.html
-/sdcard/android/layout_tests/fast/flexbox/016.html
-/sdcard/android/layout_tests/fast/flexbox/026.html
-/sdcard/android/layout_tests/fast/flexbox/008.html
-/sdcard/android/layout_tests/fast/flexbox/018.html
-/sdcard/android/layout_tests/fast/flexbox/001.html
-/sdcard/android/layout_tests/fast/flexbox/011.html
-/sdcard/android/layout_tests/fast/flexbox/003.html
-/sdcard/android/layout_tests/fast/flexbox/021.html
-/sdcard/android/layout_tests/fast/flexbox/013.html
-/sdcard/android/layout_tests/fast/flexbox/005.html
-/sdcard/android/layout_tests/fast/flexbox/023.html
-/sdcard/android/layout_tests/fast/flexbox/015.html
-/sdcard/android/layout_tests/fast/flexbox/007.html
-/sdcard/android/layout_tests/fast/flexbox/025.html
-/sdcard/android/layout_tests/fast/flexbox/017.html
-/sdcard/android/layout_tests/fast/flexbox/009.html
-/sdcard/android/layout_tests/fast/flexbox/019.html
-/sdcard/android/layout_tests/fast/flexbox/flex-hang.html
-/sdcard/android/layout_tests/fast/tokenizer/missing-style-end-tag-1.html
-/sdcard/android/layout_tests/fast/tokenizer/002.html
-/sdcard/android/layout_tests/fast/tokenizer/missing-title-end-tag-2.html
-/sdcard/android/layout_tests/fast/tokenizer/script-after-frameset.html
-/sdcard/android/layout_tests/fast/tokenizer/missing-style-end-tag-2.html
-/sdcard/android/layout_tests/fast/tokenizer/external-script-document-write.html
-/sdcard/android/layout_tests/fast/tokenizer/script_extra_close.html
-/sdcard/android/layout_tests/fast/tokenizer/001.html
-/sdcard/android/layout_tests/fast/tokenizer/003.html
-/sdcard/android/layout_tests/fast/tokenizer/missing-title-end-tag-1.html
-/sdcard/android/layout_tests/fast/tokenizer/external-script-document-write_2.html
-/sdcard/android/layout_tests/fast/box-shadow/transform-fringing.html
-/sdcard/android/layout_tests/fast/box-shadow/spread.html
-/sdcard/android/layout_tests/fast/box-shadow/border-radius-big.html
-/sdcard/android/layout_tests/fast/box-shadow/inset.html
-/sdcard/android/layout_tests/fast/box-shadow/basic-shadows.html
-/sdcard/android/layout_tests/fast/js/exception-linenums-in-html-3.html
-/sdcard/android/layout_tests/fast/js/missing-style-end-tag-js.html
-/sdcard/android/layout_tests/fast/inline/continuation-outlines-with-layers.html
-/sdcard/android/layout_tests/fast/inline/inline-padding-disables-text-quirk.html
-/sdcard/android/layout_tests/fast/inline/emptyInlinesWithinLists.html
-/sdcard/android/layout_tests/fast/inline/drawStyledEmptyInlines.html
-/sdcard/android/layout_tests/fast/inline/long-wrapped-line.html
-/sdcard/android/layout_tests/fast/inline/inline-continuation-borders.html
-/sdcard/android/layout_tests/fast/inline/vertical-align-text-bottom.html
-/sdcard/android/layout_tests/fast/inline/25277-2.html
-/sdcard/android/layout_tests/fast/inline/25277.html
-/sdcard/android/layout_tests/fast/inline/drawStyledEmptyInlinesWithWS.html
-/sdcard/android/layout_tests/fast/inline/positionedLifetime.html
-/sdcard/android/layout_tests/fast/inline/dirtyLinesForInline.html
-/sdcard/android/layout_tests/fast/inline/001.html
-/sdcard/android/layout_tests/fast/inline/002.html
-/sdcard/android/layout_tests/fast/inline/inline-text-quirk-bpm.html
-/sdcard/android/layout_tests/fast/inline/inline-borders-with-bidi-override.html
-/sdcard/android/layout_tests/fast/inline/styledEmptyInlinesWithBRs.html
-/sdcard/android/layout_tests/fast/inline/continuation-outlines.html
-/sdcard/android/layout_tests/fast/inline/br-text-decoration.html
-/sdcard/android/layout_tests/fast/inline/outline-continuations.html
-/sdcard/android/layout_tests/fast/inline/percentage-margins.html
-/sdcard/android/layout_tests/fast/body-propagation/background-image/010.html
-/sdcard/android/layout_tests/fast/body-propagation/background-image/001.html
-/sdcard/android/layout_tests/fast/body-propagation/background-image/002.html
-/sdcard/android/layout_tests/fast/body-propagation/background-image/003.html
-/sdcard/android/layout_tests/fast/body-propagation/background-image/004.html
-/sdcard/android/layout_tests/fast/body-propagation/background-image/005.html
-/sdcard/android/layout_tests/fast/body-propagation/background-image/006.html
-/sdcard/android/layout_tests/fast/body-propagation/background-image/007.html
-/sdcard/android/layout_tests/fast/body-propagation/background-image/008.html
-/sdcard/android/layout_tests/fast/body-propagation/background-image/009.html
-/sdcard/android/layout_tests/fast/body-propagation/overflow/001.html
-/sdcard/android/layout_tests/fast/body-propagation/overflow/002.html
-/sdcard/android/layout_tests/fast/body-propagation/overflow/003.html
-/sdcard/android/layout_tests/fast/body-propagation/overflow/004.html
-/sdcard/android/layout_tests/fast/body-propagation/overflow/005.html
-/sdcard/android/layout_tests/fast/body-propagation/overflow/006.html
-/sdcard/android/layout_tests/fast/body-propagation/overflow/007.html
-/sdcard/android/layout_tests/fast/body-propagation/background-color/001.html
-/sdcard/android/layout_tests/fast/body-propagation/background-color/002.html
-/sdcard/android/layout_tests/fast/body-propagation/background-color/003.html
-/sdcard/android/layout_tests/fast/body-propagation/background-color/004.html
-/sdcard/android/layout_tests/fast/body-propagation/background-color/005.html
-/sdcard/android/layout_tests/fast/body-propagation/background-color/006.html
-/sdcard/android/layout_tests/fast/body-propagation/background-color/007.html
-/sdcard/android/layout_tests/fast/body-propagation/background-color/008.html
-/sdcard/android/layout_tests/fast/dom/HTMLTableElement/colSpan.html
-/sdcard/android/layout_tests/fast/dom/HTMLTableElement/createCaption.html
-/sdcard/android/layout_tests/fast/dom/HTMLDocument/frameless-location-bugzilla10837.html
-/sdcard/android/layout_tests/fast/dom/Element/null-offset-parent.html
-/sdcard/android/layout_tests/fast/dom/Element/class-attribute-whitespace.html
-/sdcard/android/layout_tests/fast/dom/HTMLLinkElement/pending-stylesheet-count.html
-/sdcard/android/layout_tests/fast/dom/HTMLStyleElement/insert-parser-generated.html
-/sdcard/android/layout_tests/fast/dom/HTMLTableColElement/resize-table-using-col-width.html
-/sdcard/android/layout_tests/fast/dom/HTMLInputElement/input-image-alt-text.html
-/sdcard/android/layout_tests/fast/dom/Window/open-existing-pop-up-blocking.html
-/sdcard/android/layout_tests/fast/dom/Window/btoa-pnglet.html
-/sdcard/android/layout_tests/fast/dom/HTMLObjectElement/vspace-hspace-as-number.html
-/sdcard/android/layout_tests/fast/dom/HTMLElement/bdo.html
-/sdcard/android/layout_tests/fast/dom/Range/surroundContents-1.html
-/sdcard/android/layout_tests/fast/dom/Range/create-contextual-fragment.html
-/sdcard/android/layout_tests/fast/dom/HTMLHeadElement/textInHead1.html
-/sdcard/android/layout_tests/fast/dom/HTMLHeadElement/textInHead2.html
-/sdcard/android/layout_tests/fast/dom/HTMLHeadElement/textInHead3.html
-/sdcard/android/layout_tests/fast/dom/HTMLHeadElement/textInHead4.html
-/sdcard/android/layout_tests/fast/dom/HTMLHeadElement/textInHead5.html
-/sdcard/android/layout_tests/fast/dom/HTMLHeadElement/head-link-style-href-check.html
-/sdcard/android/layout_tests/fast/dom/HTMLTextAreaElement/reset-textarea.html
-/sdcard/android/layout_tests/fast/dom/HTMLImageElement/image-alt-text.html
-/sdcard/android/layout_tests/fast/dom/dom-parse-serialize.html
-/sdcard/android/layout_tests/fast/dom/focus-contenteditable.html
-/sdcard/android/layout_tests/fast/dom/jsDevicePixelRatio.html
-/sdcard/android/layout_tests/fast/dom/isindex-001.html
-/sdcard/android/layout_tests/fast/dom/css-cached-import-rule.html
-/sdcard/android/layout_tests/fast/dom/dom-parse-serialize-display.html
-/sdcard/android/layout_tests/fast/dom/css-rule-functions.html
-/sdcard/android/layout_tests/fast/dom/createDocumentType.html
-/sdcard/android/layout_tests/fast/dom/clientWidthAfterDocumentIsRemoved.html
-/sdcard/android/layout_tests/fast/dom/css-inline-style-important.html
-/sdcard/android/layout_tests/fast/dom/replaceChild.html
-/sdcard/android/layout_tests/fast/dom/anchor-text.html
-/sdcard/android/layout_tests/fast/dom/importNodeHTML.html
-/sdcard/android/layout_tests/fast/dom/gc-10.html
-/sdcard/android/layout_tests/fast/dom/inner-text.html
-/sdcard/android/layout_tests/fast/dom/isindex-002.html
-/sdcard/android/layout_tests/fast/dom/outerText.html
-/sdcard/android/layout_tests/fast/dom/row-inner-text.html
-/sdcard/android/layout_tests/fast/dom/blur-contenteditable.html
-/sdcard/android/layout_tests/fast/dom/setPrimitiveValue.html
-/sdcard/android/layout_tests/fast/dom/delete-contents.html
-/sdcard/android/layout_tests/fast/dom/children-nodes.html
-/sdcard/android/layout_tests/fast/dom/css-mediarule-deleteRule-update.html
-/sdcard/android/layout_tests/fast/dom/attr_dead_doc.html
-/sdcard/android/layout_tests/fast/dom/clone-contents-0-end-offset.html
-/sdcard/android/layout_tests/fast/dom/comment-not-documentElement.html
-/sdcard/android/layout_tests/fast/dom/clone-node-dynamic-style.html
-/sdcard/android/layout_tests/fast/dom/css-mediarule-insertRule-update.html
-/sdcard/android/layout_tests/fast/dom/css-insert-import-rule.html
-/sdcard/android/layout_tests/fast/dom/stripNullFromTextNodes.html
-/sdcard/android/layout_tests/fast/gradients/crash-on-zero-radius.html
-/sdcard/android/layout_tests/fast/gradients/generated-gradients.html
-/sdcard/android/layout_tests/fast/gradients/background-clipped.html
-/sdcard/android/layout_tests/fast/gradients/list-item-gradient.html
-/sdcard/android/layout_tests/fast/gradients/border-image-gradient-sides-and-corners.html
-/sdcard/android/layout_tests/fast/gradients/simple-gradients.html
-/sdcard/android/layout_tests/fast/gradients/border-image-gradient.html
-/sdcard/android/layout_tests/fast/invalid/table-inside-stray-table-content.html
-/sdcard/android/layout_tests/fast/invalid/010.html
-/sdcard/android/layout_tests/fast/invalid/002.html
-/sdcard/android/layout_tests/fast/invalid/012.html
-/sdcard/android/layout_tests/fast/invalid/004.html
-/sdcard/android/layout_tests/fast/invalid/014.html
-/sdcard/android/layout_tests/fast/invalid/006.html
-/sdcard/android/layout_tests/fast/invalid/016.html
-/sdcard/android/layout_tests/fast/invalid/008.html
-/sdcard/android/layout_tests/fast/invalid/018.html
-/sdcard/android/layout_tests/fast/invalid/junk-data.xml
-/sdcard/android/layout_tests/fast/invalid/missing-dl-end-tag.html
-/sdcard/android/layout_tests/fast/invalid/td-inside-object.html
-/sdcard/android/layout_tests/fast/invalid/table-residual-style-crash.html
-/sdcard/android/layout_tests/fast/invalid/missing-font-end-tag.html
-/sdcard/android/layout_tests/fast/invalid/missing-dt-end-tag.html
-/sdcard/android/layout_tests/fast/invalid/020.xml
-/sdcard/android/layout_tests/fast/invalid/001.html
-/sdcard/android/layout_tests/fast/invalid/nestedh3s.html
-/sdcard/android/layout_tests/fast/invalid/011.html
-/sdcard/android/layout_tests/fast/invalid/003.html
-/sdcard/android/layout_tests/fast/invalid/021.html
-/sdcard/android/layout_tests/fast/invalid/013.html
-/sdcard/android/layout_tests/fast/invalid/005.html
-/sdcard/android/layout_tests/fast/invalid/015.html
-/sdcard/android/layout_tests/fast/invalid/007.html
-/sdcard/android/layout_tests/fast/invalid/residual-style.html
-/sdcard/android/layout_tests/fast/invalid/017.html
-/sdcard/android/layout_tests/fast/invalid/009.html
-/sdcard/android/layout_tests/fast/invalid/missing-address-end-tag.html
-/sdcard/android/layout_tests/fast/invalid/019.html
-/sdcard/android/layout_tests/fast/forms/input-width.html
-/sdcard/android/layout_tests/fast/forms/select-item-background-clip.html
-/sdcard/android/layout_tests/fast/forms/radio-nested-labels.html
-/sdcard/android/layout_tests/fast/forms/input-appearance-preventDefault.html
-/sdcard/android/layout_tests/fast/forms/input-double-click-selection-gap-bug.html
-/sdcard/android/layout_tests/fast/forms/preserveFormDuringResidualStyle.html
-/sdcard/android/layout_tests/fast/forms/input-text-option-delete.html
-/sdcard/android/layout_tests/fast/forms/textfield-overflow.html
-/sdcard/android/layout_tests/fast/forms/search-zoomed.html
-/sdcard/android/layout_tests/fast/forms/HTMLOptionElement_label02.html
-/sdcard/android/layout_tests/fast/forms/input-appearance-visibility.html
-/sdcard/android/layout_tests/fast/forms/search-vertical-alignment.html
-/sdcard/android/layout_tests/fast/forms/file-input-direction.html
-/sdcard/android/layout_tests/fast/forms/select-change-listbox-size.html
-/sdcard/android/layout_tests/fast/forms/002.html
-/sdcard/android/layout_tests/fast/forms/textarea-align.html
-/sdcard/android/layout_tests/fast/forms/control-restrict-line-height.html
-/sdcard/android/layout_tests/fast/forms/basic-textareas.html
-/sdcard/android/layout_tests/fast/forms/button-generated-content.html
-/sdcard/android/layout_tests/fast/forms/input-text-paste-maxlength.html
-/sdcard/android/layout_tests/fast/forms/select-display-none-style-resolve.html
-/sdcard/android/layout_tests/fast/forms/input-readonly-autoscroll.html
-/sdcard/android/layout_tests/fast/forms/thumbslider-no-parent-slider.html
-/sdcard/android/layout_tests/fast/forms/listbox-clip.html
-/sdcard/android/layout_tests/fast/forms/textarea-setinnerhtml.html
-/sdcard/android/layout_tests/fast/forms/input-align.html
-/sdcard/android/layout_tests/fast/forms/button-cannot-be-nested.html
-/sdcard/android/layout_tests/fast/forms/input-type-change.html
-/sdcard/android/layout_tests/fast/forms/menulist-option-wrap.html
-/sdcard/android/layout_tests/fast/forms/select-empty-option-height.html
-/sdcard/android/layout_tests/fast/forms/float-before-fieldset.html
-/sdcard/android/layout_tests/fast/forms/radio_checked.html
-/sdcard/android/layout_tests/fast/forms/input-appearance-focus.html
-/sdcard/android/layout_tests/fast/forms/input-value.html
-/sdcard/android/layout_tests/fast/forms/select-selected.html
-/sdcard/android/layout_tests/fast/forms/control-clip-overflow.html
-/sdcard/android/layout_tests/fast/forms/input-appearance-default-bkcolor.html
-/sdcard/android/layout_tests/fast/forms/HTMLOptionElement_label03.html
-/sdcard/android/layout_tests/fast/forms/button-default-title.html
-/sdcard/android/layout_tests/fast/forms/hidden-listbox.html
-/sdcard/android/layout_tests/fast/forms/input-baseline.html
-/sdcard/android/layout_tests/fast/forms/targeted-frame-submission.html
-/sdcard/android/layout_tests/fast/forms/003.html
-/sdcard/android/layout_tests/fast/forms/text-control-intrinsic-widths.html
-/sdcard/android/layout_tests/fast/forms/select-change-listbox-to-popup.html
-/sdcard/android/layout_tests/fast/forms/radio_checked_dynamic.html
-/sdcard/android/layout_tests/fast/forms/text-style-color.html
-/sdcard/android/layout_tests/fast/forms/button-sizes.html
-/sdcard/android/layout_tests/fast/forms/listbox-scrollbar-incremental-load.html
-/sdcard/android/layout_tests/fast/forms/password-placeholder.html
-/sdcard/android/layout_tests/fast/forms/button-style-color.html
-/sdcard/android/layout_tests/fast/forms/caret-rtl.html
-/sdcard/android/layout_tests/fast/forms/listbox-deselect-scroll.html
-/sdcard/android/layout_tests/fast/forms/select-initial-position.html
-/sdcard/android/layout_tests/fast/forms/placeholder-set-attribute.html
-/sdcard/android/layout_tests/fast/forms/radio-attr-order.html
-/sdcard/android/layout_tests/fast/forms/input-disabled-color.html
-/sdcard/android/layout_tests/fast/forms/fieldset-align.html
-/sdcard/android/layout_tests/fast/forms/select-baseline.html
-/sdcard/android/layout_tests/fast/forms/stuff-on-my-optgroup.html
-/sdcard/android/layout_tests/fast/forms/input-align-image.html
-/sdcard/android/layout_tests/fast/forms/option-index.html
-/sdcard/android/layout_tests/fast/forms/menulist-clip.html
-/sdcard/android/layout_tests/fast/forms/search-display-none-cancel-button.html
-/sdcard/android/layout_tests/fast/forms/HTMLOptionElement_label04.html
-/sdcard/android/layout_tests/fast/forms/input-appearance-disabled.html
-/sdcard/android/layout_tests/fast/forms/input-appearance-height.html
-/sdcard/android/layout_tests/fast/forms/004.html
-/sdcard/android/layout_tests/fast/forms/search-placeholder-value-changed.html
-/sdcard/android/layout_tests/fast/forms/input-field-text-truncated.html
-/sdcard/android/layout_tests/fast/forms/input-type-text-min-width.html
-/sdcard/android/layout_tests/fast/forms/slider-thumb-shared-style.html
-/sdcard/android/layout_tests/fast/forms/option-script.html
-/sdcard/android/layout_tests/fast/forms/input-paste-undo.html
-/sdcard/android/layout_tests/fast/forms/button-white-space.html
-/sdcard/android/layout_tests/fast/forms/slider-padding.html
-/sdcard/android/layout_tests/fast/forms/button-submit.html
-/sdcard/android/layout_tests/fast/forms/input-text-double-click.html
-/sdcard/android/layout_tests/fast/forms/form-hides-table.html
-/sdcard/android/layout_tests/fast/forms/listbox-width-change.html
-/sdcard/android/layout_tests/fast/forms/button-positioned.html
-/sdcard/android/layout_tests/fast/forms/control-clip.html
-/sdcard/android/layout_tests/fast/forms/listbox-hit-test-zoomed.html
-/sdcard/android/layout_tests/fast/forms/thumbslider-crash.html
-/sdcard/android/layout_tests/fast/forms/input-first-letter.html
-/sdcard/android/layout_tests/fast/forms/search-rtl.html
-/sdcard/android/layout_tests/fast/forms/isindex-placeholder.html
-/sdcard/android/layout_tests/fast/forms/plaintext-mode-2.html
-/sdcard/android/layout_tests/fast/forms/select-change-popup-to-listbox.html
-/sdcard/android/layout_tests/fast/forms/blankbuttons.html
-/sdcard/android/layout_tests/fast/forms/input-text-maxlength.html
-/sdcard/android/layout_tests/fast/forms/password-placeholder-text-security.html
-/sdcard/android/layout_tests/fast/forms/HTMLOptionElement_label05.html
-/sdcard/android/layout_tests/fast/forms/visual-hebrew-text-field.html
-/sdcard/android/layout_tests/fast/forms/005.html
-/sdcard/android/layout_tests/fast/forms/search-styled.html
-/sdcard/android/layout_tests/fast/forms/file-input-disabled.html
-/sdcard/android/layout_tests/fast/forms/select-disabled-appearance.html
-/sdcard/android/layout_tests/fast/forms/input-type-change2.html
-/sdcard/android/layout_tests/fast/forms/select-block-background.html
-/sdcard/android/layout_tests/fast/forms/select-dirty-parent-pref-widths.html
-/sdcard/android/layout_tests/fast/forms/range-thumb-height-percentage.html
-/sdcard/android/layout_tests/fast/forms/select-visual-hebrew.html
-/sdcard/android/layout_tests/fast/forms/textAreaLineHeight.html
-/sdcard/android/layout_tests/fast/forms/option-text-clip.html
-/sdcard/android/layout_tests/fast/forms/formmove.html
-/sdcard/android/layout_tests/fast/forms/textfield-outline.html
-/sdcard/android/layout_tests/fast/forms/button-text-transform.html
-/sdcard/android/layout_tests/fast/forms/textarea-scroll-height.html
-/sdcard/android/layout_tests/fast/forms/button-table-styles.html
-/sdcard/android/layout_tests/fast/forms/box-shadow-override.html
-/sdcard/android/layout_tests/fast/forms/checkbox-radio-onchange.html
-/sdcard/android/layout_tests/fast/forms/searchfield-heights.html
-/sdcard/android/layout_tests/fast/forms/input-spaces.html
-/sdcard/android/layout_tests/fast/forms/textarea-scrollbar.html
-/sdcard/android/layout_tests/fast/forms/minWidthPercent.html
-/sdcard/android/layout_tests/fast/forms/HTMLOptionElement_label06.html
-/sdcard/android/layout_tests/fast/forms/placeholder-pseudo-style.html
-/sdcard/android/layout_tests/fast/forms/menulist-width-change.html
-/sdcard/android/layout_tests/fast/forms/input-text-drag-down.html
-/sdcard/android/layout_tests/fast/forms/option-strip-whitespace.html
-/sdcard/android/layout_tests/fast/forms/006.html
-/sdcard/android/layout_tests/fast/forms/input-no-renderer.html
-/sdcard/android/layout_tests/fast/forms/input-text-click-outside.html
-/sdcard/android/layout_tests/fast/forms/input-text-scroll-left-on-blur.html
-/sdcard/android/layout_tests/fast/forms/form-element-geometry.html
-/sdcard/android/layout_tests/fast/forms/input-table.html
-/sdcard/android/layout_tests/fast/forms/textarea-scrolled-type.html
-/sdcard/android/layout_tests/fast/forms/select-align.html
-/sdcard/android/layout_tests/fast/forms/select-writing-direction-natural.html
-/sdcard/android/layout_tests/fast/forms/search-cancel-button-style-sharing.html
-/sdcard/android/layout_tests/fast/forms/tabbing-input-iframe.html
-/sdcard/android/layout_tests/fast/forms/hidden-input-file.html
-/sdcard/android/layout_tests/fast/forms/menulist-deselect-update.html
-/sdcard/android/layout_tests/fast/forms/slider-thumb-stylability.html
-/sdcard/android/layout_tests/fast/forms/input-readonly-dimmed.html
-/sdcard/android/layout_tests/fast/forms/input-appearance-width.html
-/sdcard/android/layout_tests/fast/forms/select-list-box-with-height.html
-/sdcard/android/layout_tests/fast/forms/textarea-rows-cols.html
-/sdcard/android/layout_tests/fast/forms/button-align.html
-/sdcard/android/layout_tests/fast/forms/input-appearance-readonly.html
-/sdcard/android/layout_tests/fast/forms/form-added-to-table.html
-/sdcard/android/layout_tests/fast/forms/menulist-no-overflow.html
-/sdcard/android/layout_tests/fast/forms/formmove2.html
-/sdcard/android/layout_tests/fast/forms/input-text-word-wrap.html
-/sdcard/android/layout_tests/fast/forms/listbox-selection-2.html
-/sdcard/android/layout_tests/fast/forms/input-readonly-empty.html
-/sdcard/android/layout_tests/fast/forms/HTMLOptionElement_label07.html
-/sdcard/android/layout_tests/fast/forms/007.html
-/sdcard/android/layout_tests/fast/forms/indeterminate.html
-/sdcard/android/layout_tests/fast/forms/negativeLineHeight.html
-/sdcard/android/layout_tests/fast/forms/select-style.html
-/sdcard/android/layout_tests/fast/forms/select-size.html
-/sdcard/android/layout_tests/fast/forms/menulist-separator-painting.html
-/sdcard/android/layout_tests/fast/forms/HTMLOptionElement_label01.html
-/sdcard/android/layout_tests/fast/forms/fieldset-with-float.html
-/sdcard/android/layout_tests/fast/forms/floating-textfield-relayout.html
-/sdcard/android/layout_tests/fast/forms/button-inner-block-reuse.html
-/sdcard/android/layout_tests/fast/forms/001.html
-/sdcard/android/layout_tests/fast/forms/input-text-click-inside.html
-/sdcard/android/layout_tests/fast/forms/input-appearance-selection.html
-/sdcard/android/layout_tests/fast/forms/menulist-narrow-width.html
-/sdcard/android/layout_tests/fast/forms/linebox-overflow-in-textarea-padding.html
-/sdcard/android/layout_tests/fast/forms/menulist-restrict-line-height.html
-/sdcard/android/layout_tests/fast/forms/textarea-width.html
-/sdcard/android/layout_tests/fast/forms/disabled-select-change-index.html
-/sdcard/android/layout_tests/fast/forms/formmove3.html
-/sdcard/android/layout_tests/fast/forms/placeholder-set-value.html
-/sdcard/android/layout_tests/fast/forms/input-text-self-emptying-click.html
-/sdcard/android/layout_tests/fast/forms/input-appearance-bkcolor.html
-/sdcard/android/layout_tests/fast/forms/search-transformed.html
-/sdcard/android/layout_tests/fast/forms/image-border.html
-/sdcard/android/layout_tests/fast/forms/encoding-test.html
-/sdcard/android/layout_tests/fast/forms/form-in-malformed-markup.html
-/sdcard/android/layout_tests/fast/forms/menulist-style-color.html
-/sdcard/android/layout_tests/fast/compact/001.html
-/sdcard/android/layout_tests/fast/compact/002.html
-/sdcard/android/layout_tests/fast/compact/003.html
-/sdcard/android/layout_tests/fast/clip/nestedTransparencyClip.html
-/sdcard/android/layout_tests/fast/clip/overflow-border-radius-clip.html
-/sdcard/android/layout_tests/fast/clip/outline-overflowClip.html
-/sdcard/android/layout_tests/fast/clip/001.html
-/sdcard/android/layout_tests/fast/clip/010.html
-/sdcard/android/layout_tests/fast/clip/002.html
-/sdcard/android/layout_tests/fast/clip/011.html
-/sdcard/android/layout_tests/fast/clip/003.html
-/sdcard/android/layout_tests/fast/clip/012.html
-/sdcard/android/layout_tests/fast/clip/004.html
-/sdcard/android/layout_tests/fast/clip/013.html
-/sdcard/android/layout_tests/fast/clip/005.html
-/sdcard/android/layout_tests/fast/clip/014.html
-/sdcard/android/layout_tests/fast/clip/006.html
-/sdcard/android/layout_tests/fast/clip/015.html
-/sdcard/android/layout_tests/fast/clip/016.html
-/sdcard/android/layout_tests/fast/clip/007.html
-/sdcard/android/layout_tests/fast/clip/008.html
-/sdcard/android/layout_tests/fast/clip/017.html
-/sdcard/android/layout_tests/fast/clip/009.html
-/sdcard/android/layout_tests/fast/table/border-collapsing/001.html
-/sdcard/android/layout_tests/fast/table/border-collapsing/002.html
-/sdcard/android/layout_tests/fast/table/border-collapsing/003.html
-/sdcard/android/layout_tests/fast/table/border-collapsing/004.html
-/sdcard/android/layout_tests/fast/table/border-collapsing/equal-precedence-resolution.html
-/sdcard/android/layout_tests/fast/table/border-collapsing/rtl-border-collapsing.html
-/sdcard/android/layout_tests/fast/table/border-collapsing/border-collapsing-head-foot.html
-/sdcard/android/layout_tests/fast/table/fixed-nested.html
-/sdcard/android/layout_tests/fast/table/frame-and-rules.html
-/sdcard/android/layout_tests/fast/table/empty-table-percent-height.html
-/sdcard/android/layout_tests/fast/table/100-percent-cell-width.html
-/sdcard/android/layout_tests/fast/table/stale-grid-crash.html
-/sdcard/android/layout_tests/fast/table/div-as-col-span.html
-/sdcard/android/layout_tests/fast/table/nobr.html
-/sdcard/android/layout_tests/fast/table/012.html
-/sdcard/android/layout_tests/fast/table/040.html
-/sdcard/android/layout_tests/fast/table/growCellForImageQuirk.html
-/sdcard/android/layout_tests/fast/table/024.html
-/sdcard/android/layout_tests/fast/table/cell-pref-width-invalidation.html
-/sdcard/android/layout_tests/fast/table/fixed-granular-cols.html
-/sdcard/android/layout_tests/fast/table/008.html
-/sdcard/android/layout_tests/fast/table/036.html
-/sdcard/android/layout_tests/fast/table/nested-percent-height-table.html
-/sdcard/android/layout_tests/fast/table/rules-attr-dynchange1.html
-/sdcard/android/layout_tests/fast/table/wide-column.html
-/sdcard/android/layout_tests/fast/table/fixed-with-auto-with-colspan.html
-/sdcard/android/layout_tests/fast/table/percent-heights.html
-/sdcard/android/layout_tests/fast/table/021.html
-/sdcard/android/layout_tests/fast/table/colspanMinWidth.html
-/sdcard/android/layout_tests/fast/table/005.html
-/sdcard/android/layout_tests/fast/table/033.html
-/sdcard/android/layout_tests/fast/table/floatingTablePaintBackground.html
-/sdcard/android/layout_tests/fast/table/017.html
-/sdcard/android/layout_tests/fast/table/029.html
-/sdcard/android/layout_tests/fast/table/cell-absolute-child.html
-/sdcard/android/layout_tests/fast/table/click-near-anonymous-table.html
-/sdcard/android/layout_tests/fast/table/auto-with-percent-height.html
-/sdcard/android/layout_tests/fast/table/insert-before-anonymous-ancestors.html
-/sdcard/android/layout_tests/fast/table/append-cells2.html
-/sdcard/android/layout_tests/fast/table/unused-percent-heights.html
-/sdcard/android/layout_tests/fast/table/max-width-integer-overflow.html
-/sdcard/android/layout_tests/fast/table/vertical-align-baseline-readjust.html
-/sdcard/android/layout_tests/fast/table/empty-row-crash.html
-/sdcard/android/layout_tests/fast/table/002.html
-/sdcard/android/layout_tests/fast/table/030.html
-/sdcard/android/layout_tests/fast/table/cell-width-auto.html
-/sdcard/android/layout_tests/fast/table/014.html
-/sdcard/android/layout_tests/fast/table/037.xml
-/sdcard/android/layout_tests/fast/table/large-width.html
-/sdcard/android/layout_tests/fast/table/026.html
-/sdcard/android/layout_tests/fast/table/unbreakable-images-quirk.html
-/sdcard/android/layout_tests/fast/table/038.html
-/sdcard/android/layout_tests/fast/table/dynamic-cellpadding.html
-/sdcard/android/layout_tests/fast/table/generated-caption.html
-/sdcard/android/layout_tests/fast/table/empty-cells.html
-/sdcard/android/layout_tests/fast/table/add-before-anonymous-child.html
-/sdcard/android/layout_tests/fast/table/011.html
-/sdcard/android/layout_tests/fast/table/table-display-types-strict.html
-/sdcard/android/layout_tests/fast/table/023.html
-/sdcard/android/layout_tests/fast/table/007.html
-/sdcard/android/layout_tests/fast/table/cellindex.html
-/sdcard/android/layout_tests/fast/table/035.html
-/sdcard/android/layout_tests/fast/table/colgroup-spanning-groups-rules.html
-/sdcard/android/layout_tests/fast/table/insert-row-before-form.html
-/sdcard/android/layout_tests/fast/table/rowspan-paint-order.html
-/sdcard/android/layout_tests/fast/table/rtl-cell-display-none-assert.html
-/sdcard/android/layout_tests/fast/table/insert-cell-before-form.html
-/sdcard/android/layout_tests/fast/table/replaced-percent-height.html
-/sdcard/android/layout_tests/fast/table/text-field-baseline.html
-/sdcard/android/layout_tests/fast/table/table-display-types.html
-/sdcard/android/layout_tests/fast/table/table-hspace-align-center.html
-/sdcard/android/layout_tests/fast/table/caption-relayout.html
-/sdcard/android/layout_tests/fast/table/020.html
-/sdcard/android/layout_tests/fast/table/fixed-table-non-cell-in-row.html
-/sdcard/android/layout_tests/fast/table/004.html
-/sdcard/android/layout_tests/fast/table/032.html
-/sdcard/android/layout_tests/fast/table/row-height-recalc.html
-/sdcard/android/layout_tests/fast/table/016.html
-/sdcard/android/layout_tests/fast/table/absolute-table-at-bottom.html
-/sdcard/android/layout_tests/fast/table/028.html
-/sdcard/android/layout_tests/fast/table/spanOverlapRepaint.html
-/sdcard/android/layout_tests/fast/table/invisible-cell-background.html
-/sdcard/android/layout_tests/fast/table/vertical-align-baseline.html
-/sdcard/android/layout_tests/fast/table/cell-coalescing.html
-/sdcard/android/layout_tests/fast/table/wide-colspan.html
-/sdcard/android/layout_tests/fast/table/rowindex.html
-/sdcard/android/layout_tests/fast/table/001.html
-/sdcard/android/layout_tests/fast/table/remove-td-display-none.html
-/sdcard/android/layout_tests/fast/table/013.html
-/sdcard/android/layout_tests/fast/table/041.html
-/sdcard/android/layout_tests/fast/table/colgroup-preceded-by-caption.html
-/sdcard/android/layout_tests/fast/table/025.html
-/sdcard/android/layout_tests/fast/table/giantCellspacing.html
-/sdcard/android/layout_tests/fast/table/009.html
-/sdcard/android/layout_tests/fast/table/edge-offsets.html
-/sdcard/android/layout_tests/fast/table/giantRowspan.html
-/sdcard/android/layout_tests/fast/table/inline-form-assert.html
-/sdcard/android/layout_tests/fast/table/overflowHidden.html
-/sdcard/android/layout_tests/fast/table/rules-attr-dynchange2.html
-/sdcard/android/layout_tests/fast/table/height-percent-test.html
-/sdcard/android/layout_tests/fast/table/multiple-percent-height-rows.html
-/sdcard/android/layout_tests/fast/table/giantRowspan2.html
-/sdcard/android/layout_tests/fast/table/010.html
-/sdcard/android/layout_tests/fast/table/tableInsideCaption.html
-/sdcard/android/layout_tests/fast/table/022.html
-/sdcard/android/layout_tests/fast/table/006.html
-/sdcard/android/layout_tests/fast/table/034.html
-/sdcard/android/layout_tests/fast/table/append-cells.html
-/sdcard/android/layout_tests/fast/table/018.html
-/sdcard/android/layout_tests/fast/table/percent-widths-stretch.html
-/sdcard/android/layout_tests/fast/table/prepend-in-anonymous-table.html
-/sdcard/android/layout_tests/fast/table/floating-th.html
-/sdcard/android/layout_tests/fast/table/empty-section-crash.html
-/sdcard/android/layout_tests/fast/table/form-with-table-style.html
-/sdcard/android/layout_tests/fast/table/003.html
-/sdcard/android/layout_tests/fast/table/031.html
-/sdcard/android/layout_tests/fast/table/015.html
-/sdcard/android/layout_tests/fast/table/027.html
-/sdcard/android/layout_tests/fast/table/039.html
-/sdcard/android/layout_tests/fast/css/counters/invalidate-cached-counter-node.html
-/sdcard/android/layout_tests/fast/css/counters/counter-text-security.html
-/sdcard/android/layout_tests/fast/css/counters/counter-text-transform.html
-/sdcard/android/layout_tests/fast/css/variables/multiple-term-test.html
-/sdcard/android/layout_tests/fast/css/variables/colors-test.html
-/sdcard/android/layout_tests/fast/css/variables/font-test.html
-/sdcard/android/layout_tests/fast/css/variables/multiple-blocks-test.html
-/sdcard/android/layout_tests/fast/css/variables/misplaced-variables-test.html
-/sdcard/android/layout_tests/fast/css/variables/invalid-variable-test.html
-/sdcard/android/layout_tests/fast/css/variables/misplaced-import-test.html
-/sdcard/android/layout_tests/fast/css/variables/import-test.html
-/sdcard/android/layout_tests/fast/css/variables/inline-style-test.html
-/sdcard/android/layout_tests/fast/css/variables/declaration-block-test.html
-/sdcard/android/layout_tests/fast/css/variables/margin-test.html
-/sdcard/android/layout_tests/fast/css/variables/set-variable-test.html
-/sdcard/android/layout_tests/fast/css/variables/override-test.html
-/sdcard/android/layout_tests/fast/css/variables/remove-variable-test.html
-/sdcard/android/layout_tests/fast/css/variables/variable-iteration-test.html
-/sdcard/android/layout_tests/fast/css/variables/image-test.html
-/sdcard/android/layout_tests/fast/css/variables/block-cycle-test.html
-/sdcard/android/layout_tests/fast/css/variables/shorthand-test.html
-/sdcard/android/layout_tests/fast/css/variables/print-test.html
-/sdcard/android/layout_tests/fast/css/namespaces/001.xml
-/sdcard/android/layout_tests/fast/css/namespaces/002.xml
-/sdcard/android/layout_tests/fast/css/namespaces/003.xml
-/sdcard/android/layout_tests/fast/css/namespaces/004.xml
-/sdcard/android/layout_tests/fast/css/namespaces/005.xml
-/sdcard/android/layout_tests/fast/css/namespaces/006.xml
-/sdcard/android/layout_tests/fast/css/namespaces/007.xml
-/sdcard/android/layout_tests/fast/css/font-face-in-media-rule.html
-/sdcard/android/layout_tests/fast/css/font-face-default-font.html
-/sdcard/android/layout_tests/fast/css/first-letter-float-after-float.html
-/sdcard/android/layout_tests/fast/css/invalidation-errors-2.html
-/sdcard/android/layout_tests/fast/css/line-height-negative.html
-/sdcard/android/layout_tests/fast/css/only-child-pseudo-class.html
-/sdcard/android/layout_tests/fast/css/008.html
-/sdcard/android/layout_tests/fast/css/first-of-type-pseudo-class.html
-/sdcard/android/layout_tests/fast/css/ZeroOpacityLayers2.html
-/sdcard/android/layout_tests/fast/css/target-fragment-match.html
-/sdcard/android/layout_tests/fast/css/attribute-selector-dynamic.xml
-/sdcard/android/layout_tests/fast/css/zoom-font-size.html
-/sdcard/android/layout_tests/fast/css/live-cssrules.html
-/sdcard/android/layout_tests/fast/css/005.html
-/sdcard/android/layout_tests/fast/css/first-letter-hover.html
-/sdcard/android/layout_tests/fast/css/clip-zooming.html
-/sdcard/android/layout_tests/fast/css/color-quirk.html
-/sdcard/android/layout_tests/fast/css/resize-corner-tracking-transformed.html
-/sdcard/android/layout_tests/fast/css/selector-set-attribute.html
-/sdcard/android/layout_tests/fast/css/attribute-selector-empty-value.html
-/sdcard/android/layout_tests/fast/css/line-height-overflow.html
-/sdcard/android/layout_tests/fast/css/002.html
-/sdcard/android/layout_tests/fast/css/empty-generated-content.html
-/sdcard/android/layout_tests/fast/css/border-radius-outline-offset.html
-/sdcard/android/layout_tests/fast/css/background-image-with-baseurl.html
-/sdcard/android/layout_tests/fast/css/hsla-color.html
-/sdcard/android/layout_tests/fast/css/first-letter-skip-out-of-flow.html
-/sdcard/android/layout_tests/fast/css/font-face-multiple-remote-sources.html
-/sdcard/android/layout_tests/fast/css/pseudo-cache-stale.html
-/sdcard/android/layout_tests/fast/css/hover-subselector.html
-/sdcard/android/layout_tests/fast/css/margin-bottom-form-element-strict.html
-/sdcard/android/layout_tests/fast/css/shadow-multiple.html
-/sdcard/android/layout_tests/fast/css/import_with_baseurl.html
-/sdcard/android/layout_tests/fast/css/list-outline.html
-/sdcard/android/layout_tests/fast/css/apple-prefix.html
-/sdcard/android/layout_tests/fast/css/line-height.html
-/sdcard/android/layout_tests/fast/css/first-letter-visibility.html
-/sdcard/android/layout_tests/fast/css/acid2.html
-/sdcard/android/layout_tests/fast/css/font_property_normal.html
-/sdcard/android/layout_tests/fast/css/css-imports.html
-/sdcard/android/layout_tests/fast/css/last-of-type-pseudo-class.html
-/sdcard/android/layout_tests/fast/css/last-child-pseudo-class.html
-/sdcard/android/layout_tests/fast/css/visibility-hit-test.html
-/sdcard/android/layout_tests/fast/css/absolute-poition-in-rtl-parent.html
-/sdcard/android/layout_tests/fast/css/content-dynamic.html
-/sdcard/android/layout_tests/fast/css/acid2-pixel.html
-/sdcard/android/layout_tests/fast/css/transition-color-unspecified.html
-/sdcard/android/layout_tests/fast/css/table-text-align-strict.html
-/sdcard/android/layout_tests/fast/css/transform-default-parameter.html
-/sdcard/android/layout_tests/fast/css/text-overflow-ellipsis-bidi.html
-/sdcard/android/layout_tests/fast/css/contentImage.html
-/sdcard/android/layout_tests/fast/css/value-list-out-of-bounds-crash.html
-/sdcard/android/layout_tests/fast/css/color-strict.html
-/sdcard/android/layout_tests/fast/css/ignore-text-zoom.html
-/sdcard/android/layout_tests/fast/css/max-height-none.html
-/sdcard/android/layout_tests/fast/css/invalidation-errors-3.html
-/sdcard/android/layout_tests/fast/css/empty-pseudo-class.html
-/sdcard/android/layout_tests/fast/css/begin-end-contain-selector-empty-value.html
-/sdcard/android/layout_tests/fast/css/find-next-layer.html
-/sdcard/android/layout_tests/fast/css/text-overflow-ellipsis.html
-/sdcard/android/layout_tests/fast/css/contentDiv.html
-/sdcard/android/layout_tests/fast/css/invalid-pseudo-classes.html
-/sdcard/android/layout_tests/fast/css/disabled-author-styles.html
-/sdcard/android/layout_tests/fast/css/text-security.html
-/sdcard/android/layout_tests/fast/css/font-weight-1.html
-/sdcard/android/layout_tests/fast/css/nested-floating-relative-position-percentages.html
-/sdcard/android/layout_tests/fast/css/margin-bottom-form-element-quirk.html
-/sdcard/android/layout_tests/fast/css/font-shorthand-weight-only.html
-/sdcard/android/layout_tests/fast/css/006.html
-/sdcard/android/layout_tests/fast/css/fieldset-display-row.html
-/sdcard/android/layout_tests/fast/css/border-height.html
-/sdcard/android/layout_tests/fast/css/css2-system-fonts.html
-/sdcard/android/layout_tests/fast/css/imageTileOpacity.html
-/sdcard/android/layout_tests/fast/css/font-face-remote.html
-/sdcard/android/layout_tests/fast/css/003.html
-/sdcard/android/layout_tests/fast/css/error-in-last-decl.html
-/sdcard/android/layout_tests/fast/css/zoom-property-parsing.html
-/sdcard/android/layout_tests/fast/css/style-outside-head.html
-/sdcard/android/layout_tests/fast/css/positioned-overflow-scroll.html
-/sdcard/android/layout_tests/fast/css/first-letter-capitalized.html
-/sdcard/android/layout_tests/fast/css/font-face-locally-installed.html
-/sdcard/android/layout_tests/fast/css/word-space-extra.html
-/sdcard/android/layout_tests/fast/css/first-letter-float.html
-/sdcard/android/layout_tests/fast/css/simple-selector-chain-parsing.html
-/sdcard/android/layout_tests/fast/css/xml-stylesheet-pi-not-in-prolog.xml
-/sdcard/android/layout_tests/fast/css/continuationCrash.html
-/sdcard/android/layout_tests/fast/css/vertical-align-lengths.html
-/sdcard/android/layout_tests/fast/css/first-child-pseudo-class.html
-/sdcard/android/layout_tests/fast/css/percent-top-value-with-relative-position.html
-/sdcard/android/layout_tests/fast/css/beforeSelectorOnCodeElement.html
-/sdcard/android/layout_tests/fast/css/getFloatValueForUnit.html
-/sdcard/android/layout_tests/fast/css/first-letter-detach.html
-/sdcard/android/layout_tests/fast/css/line-height-font-order.html
-/sdcard/android/layout_tests/fast/css/text-overflow-ellipsis-strict.html
-/sdcard/android/layout_tests/fast/css/font-face-unicode-range.html
-/sdcard/android/layout_tests/fast/css/layerZOrderCrash.html
-/sdcard/android/layout_tests/fast/css/compare-content-style.html
-/sdcard/android/layout_tests/fast/css/import-rule-regression-11590.html
-/sdcard/android/layout_tests/fast/css/last-child-style-sharing.html
-/sdcard/android/layout_tests/fast/css/css3-modsel-22.html
-/sdcard/android/layout_tests/fast/css/ex-after-font-variant.html
-/sdcard/android/layout_tests/fast/css/quirk-orphaned-units.html
-/sdcard/android/layout_tests/fast/css/outline-auto-location.html
-/sdcard/android/layout_tests/fast/css/margin-top-bottom-dynamic.html
-/sdcard/android/layout_tests/fast/css/font-face-descriptor-multiple-values.html
-/sdcard/android/layout_tests/fast/css/empty-body-test.html
-/sdcard/android/layout_tests/fast/css/007.html
-/sdcard/android/layout_tests/fast/css/link-outside-head.html
-/sdcard/android/layout_tests/fast/css/font-size-negative.html
-/sdcard/android/layout_tests/fast/css/rem-units-on-root.html
-/sdcard/android/layout_tests/fast/css/position-negative-top-margin.html
-/sdcard/android/layout_tests/fast/css/ZeroOpacityLayers.html
-/sdcard/android/layout_tests/fast/css/only-of-type-pseudo-class.html
-/sdcard/android/layout_tests/fast/css/004.html
-/sdcard/android/layout_tests/fast/css/rtl-ordering.html
-/sdcard/android/layout_tests/fast/css/affected-by-hover-after-style-change.html
-/sdcard/android/layout_tests/fast/css/resize-corner-tracking.html
-/sdcard/android/layout_tests/fast/css/invalidation-errors.html
-/sdcard/android/layout_tests/fast/css/background-shorthand-invalid-url.html
-/sdcard/android/layout_tests/fast/css/MarqueeLayoutTest.html
-/sdcard/android/layout_tests/fast/css/textCapitalizeEdgeCases.html
-/sdcard/android/layout_tests/fast/css/001.html
-/sdcard/android/layout_tests/fast/css/hsl-color.html
-/sdcard/android/layout_tests/fast/css/font-face-implicit-local-font.html
-/sdcard/android/layout_tests/fast/css/first-letter-recalculation.html
-/sdcard/android/layout_tests/fast/css/rem-dynamic-scaling.html
-/sdcard/android/layout_tests/fast/css/inline-properties-important.html
-/sdcard/android/layout_tests/fast/css/dynamic-sibling-selector.html
-/sdcard/android/layout_tests/fast/css/table-text-align-quirk.html
-/sdcard/android/layout_tests/fast/css/nth-child-dynamic.html
-/sdcard/android/layout_tests/fast/css/outline-auto-empty-rects.html
-/sdcard/android/layout_tests/fast/css/font-face-multiple-faces.html
-/sdcard/android/layout_tests/fast/css/rgb-float.html
-/sdcard/android/layout_tests/fast/css/pendingStylesheetFontSize.html
-/sdcard/android/layout_tests/fast/css/contentDivWithChildren.html
-/sdcard/android/layout_tests/fast/css/universal-hover-quirk.html
-/sdcard/android/layout_tests/fast/css/css3-nth-child.html
-/sdcard/android/layout_tests/fast/css/style-parsed-outside-head.html
-/sdcard/android/layout_tests/fast/css/percentage-non-integer.html
-/sdcard/android/layout_tests/fast/css/nested-layers-with-hover.html
-/sdcard/android/layout_tests/fast/css/negative-nth-child.html
-/sdcard/android/layout_tests/fast/box-sizing/panels-one.html
-/sdcard/android/layout_tests/fast/box-sizing/percentage-height.html
-/sdcard/android/layout_tests/fast/box-sizing/box-sizing.html
-/sdcard/android/layout_tests/fast/box-sizing/panels-two.html
-/sdcard/android/layout_tests/fast/block/basic/minheight.html
-/sdcard/android/layout_tests/fast/block/basic/min-pref-width-nowrap-floats.html
-/sdcard/android/layout_tests/fast/block/basic/fieldset-stretch-to-legend.html
-/sdcard/android/layout_tests/fast/block/basic/white-space-pre-wraps.html
-/sdcard/android/layout_tests/fast/block/basic/adding-near-anonymous-block.html
-/sdcard/android/layout_tests/fast/block/basic/quirk-percent-height-grandchild.html
-/sdcard/android/layout_tests/fast/block/basic/001.html
-/sdcard/android/layout_tests/fast/block/basic/010.html
-/sdcard/android/layout_tests/fast/block/basic/quirk-height.html
-/sdcard/android/layout_tests/fast/block/basic/020.html
-/sdcard/android/layout_tests/fast/block/basic/002.html
-/sdcard/android/layout_tests/fast/block/basic/011.html
-/sdcard/android/layout_tests/fast/block/basic/text-indent-rtl.html
-/sdcard/android/layout_tests/fast/block/basic/021.html
-/sdcard/android/layout_tests/fast/block/basic/003.html
-/sdcard/android/layout_tests/fast/block/basic/012.html
-/sdcard/android/layout_tests/fast/block/basic/013.html
-/sdcard/android/layout_tests/fast/block/basic/004.html
-/sdcard/android/layout_tests/fast/block/basic/014.html
-/sdcard/android/layout_tests/fast/block/basic/005.html
-/sdcard/android/layout_tests/fast/block/basic/015.html
-/sdcard/android/layout_tests/fast/block/basic/006.html
-/sdcard/android/layout_tests/fast/block/basic/016.html
-/sdcard/android/layout_tests/fast/block/basic/007.html
-/sdcard/android/layout_tests/fast/block/basic/008.html
-/sdcard/android/layout_tests/fast/block/basic/009.html
-/sdcard/android/layout_tests/fast/block/basic/018.html
-/sdcard/android/layout_tests/fast/block/basic/019.html
-/sdcard/android/layout_tests/fast/block/positioning/auto/001.html
-/sdcard/android/layout_tests/fast/block/positioning/auto/002.html
-/sdcard/android/layout_tests/fast/block/positioning/auto/003.html
-/sdcard/android/layout_tests/fast/block/positioning/auto/004.html
-/sdcard/android/layout_tests/fast/block/positioning/auto/005.html
-/sdcard/android/layout_tests/fast/block/positioning/auto/006.html
-/sdcard/android/layout_tests/fast/block/positioning/auto/007.html
-/sdcard/android/layout_tests/fast/block/positioning/059.html
-/sdcard/android/layout_tests/fast/block/positioning/negative-rel-position.html
-/sdcard/android/layout_tests/fast/block/positioning/absolute-in-inline-short-rtl.html
-/sdcard/android/layout_tests/fast/block/positioning/absolute-in-inline-short-ltr.html
-/sdcard/android/layout_tests/fast/block/positioning/fixed-positioning-scrollbar-bug.html
-/sdcard/android/layout_tests/fast/block/positioning/relative-overflow-replaced-float.html
-/sdcard/android/layout_tests/fast/block/positioning/absolute-positioned-overconstrained.html
-/sdcard/android/layout_tests/fast/block/positioning/absolute-in-inline-rtl-2.html
-/sdcard/android/layout_tests/fast/block/positioning/absolute-in-inline-ltr-2.html
-/sdcard/android/layout_tests/fast/block/positioning/020.html
-/sdcard/android/layout_tests/fast/block/positioning/012.html
-/sdcard/android/layout_tests/fast/block/positioning/004.html
-/sdcard/android/layout_tests/fast/block/positioning/040.html
-/sdcard/android/layout_tests/fast/block/positioning/absolute-position-direction-strict.html
-/sdcard/android/layout_tests/fast/block/positioning/032.html
-/sdcard/android/layout_tests/fast/block/positioning/060.html
-/sdcard/android/layout_tests/fast/block/positioning/024.html
-/sdcard/android/layout_tests/fast/block/positioning/052.html
-/sdcard/android/layout_tests/fast/block/positioning/016.html
-/sdcard/android/layout_tests/fast/block/positioning/044.html
-/sdcard/android/layout_tests/fast/block/positioning/008.html
-/sdcard/android/layout_tests/fast/block/positioning/036.html
-/sdcard/android/layout_tests/fast/block/positioning/028.html
-/sdcard/android/layout_tests/fast/block/positioning/056.html
-/sdcard/android/layout_tests/fast/block/positioning/048.html
-/sdcard/android/layout_tests/fast/block/positioning/absolute-position-direction-quirk.html
-/sdcard/android/layout_tests/fast/block/positioning/replaced-inside-fixed-top-bottom.html
-/sdcard/android/layout_tests/fast/block/positioning/pref-width-change.html
-/sdcard/android/layout_tests/fast/block/positioning/absolute-in-inline-ltr-3.html
-/sdcard/android/layout_tests/fast/block/positioning/absolute-in-inline-ltr.html
-/sdcard/android/layout_tests/fast/block/positioning/absolute-in-inline-rtl-3.html
-/sdcard/android/layout_tests/fast/block/positioning/absolute-in-inline-rtl.html
-/sdcard/android/layout_tests/fast/block/positioning/001.html
-/sdcard/android/layout_tests/fast/block/positioning/021.html
-/sdcard/android/layout_tests/fast/block/positioning/013.html
-/sdcard/android/layout_tests/fast/block/positioning/relative-overflow-block.html
-/sdcard/android/layout_tests/fast/block/positioning/005.html
-/sdcard/android/layout_tests/fast/block/positioning/041.html
-/sdcard/android/layout_tests/fast/block/positioning/033.html
-/sdcard/android/layout_tests/fast/block/positioning/025.html
-/sdcard/android/layout_tests/fast/block/positioning/061.html
-/sdcard/android/layout_tests/fast/block/positioning/017.html
-/sdcard/android/layout_tests/fast/block/positioning/053.html
-/sdcard/android/layout_tests/fast/block/positioning/009.html
-/sdcard/android/layout_tests/fast/block/positioning/045.html
-/sdcard/android/layout_tests/fast/block/positioning/037.html
-/sdcard/android/layout_tests/fast/block/positioning/029.html
-/sdcard/android/layout_tests/fast/block/positioning/057.html
-/sdcard/android/layout_tests/fast/block/positioning/049.html
-/sdcard/android/layout_tests/fast/block/positioning/absolute-with-html-border-quirks.html
-/sdcard/android/layout_tests/fast/block/positioning/leftmargin-topmargin.html
-/sdcard/android/layout_tests/fast/block/positioning/absolute-length-of-neg-666666.html
-/sdcard/android/layout_tests/fast/block/positioning/complex-percentage-height.html
-/sdcard/android/layout_tests/fast/block/positioning/auto-height-with-top-and-bottom.html
-/sdcard/android/layout_tests/fast/block/positioning/010.html
-/sdcard/android/layout_tests/fast/block/positioning/002.html
-/sdcard/android/layout_tests/fast/block/positioning/030.html
-/sdcard/android/layout_tests/fast/block/positioning/relayout-on-position-change.html
-/sdcard/android/layout_tests/fast/block/positioning/022.html
-/sdcard/android/layout_tests/fast/block/positioning/padding-percent.html
-/sdcard/android/layout_tests/fast/block/positioning/014.html
-/sdcard/android/layout_tests/fast/block/positioning/050.html
-/sdcard/android/layout_tests/fast/block/positioning/042.html
-/sdcard/android/layout_tests/fast/block/positioning/006.html
-/sdcard/android/layout_tests/fast/block/positioning/034.html
-/sdcard/android/layout_tests/fast/block/positioning/offsetLeft-offsetTop-borders.html
-/sdcard/android/layout_tests/fast/block/positioning/062.html
-/sdcard/android/layout_tests/fast/block/positioning/026.html
-/sdcard/android/layout_tests/fast/block/positioning/054.html
-/sdcard/android/layout_tests/fast/block/positioning/018.html
-/sdcard/android/layout_tests/fast/block/positioning/046.html
-/sdcard/android/layout_tests/fast/block/positioning/abs-inside-inline-rel.html
-/sdcard/android/layout_tests/fast/block/positioning/038.html
-/sdcard/android/layout_tests/fast/block/positioning/absolute-with-html-border-strict.html
-/sdcard/android/layout_tests/fast/block/positioning/058.html
-/sdcard/android/layout_tests/fast/block/positioning/negative-right-pos.html
-/sdcard/android/layout_tests/fast/block/positioning/relative-overconstrained.html
-/sdcard/android/layout_tests/fast/block/positioning/child-of-absolute-with-auto-height.html
-/sdcard/android/layout_tests/fast/block/positioning/relative-overflow-replaced.html
-/sdcard/android/layout_tests/fast/block/positioning/height-change.html
-/sdcard/android/layout_tests/fast/block/positioning/window-height-change.html
-/sdcard/android/layout_tests/fast/block/positioning/011.html
-/sdcard/android/layout_tests/fast/block/positioning/003.html
-/sdcard/android/layout_tests/fast/block/positioning/move-with-auto-width.html
-/sdcard/android/layout_tests/fast/block/positioning/031.html
-/sdcard/android/layout_tests/fast/block/positioning/023.html
-/sdcard/android/layout_tests/fast/block/positioning/051.html
-/sdcard/android/layout_tests/fast/block/positioning/015.html
-/sdcard/android/layout_tests/fast/block/positioning/043.html
-/sdcard/android/layout_tests/fast/block/positioning/007.html
-/sdcard/android/layout_tests/fast/block/positioning/035.html
-/sdcard/android/layout_tests/fast/block/positioning/027.html
-/sdcard/android/layout_tests/fast/block/positioning/055.html
-/sdcard/android/layout_tests/fast/block/positioning/019.html
-/sdcard/android/layout_tests/fast/block/positioning/047.html
-/sdcard/android/layout_tests/fast/block/positioning/039.html
-/sdcard/android/layout_tests/fast/block/positioning/inline-block-relposition.html
-/sdcard/android/layout_tests/fast/block/float/vertical-move-relayout.html
-/sdcard/android/layout_tests/fast/block/float/overlapping-floats-with-overflow-hidden.html
-/sdcard/android/layout_tests/fast/block/float/tableshifting.html
-/sdcard/android/layout_tests/fast/block/float/table-relayout.html
-/sdcard/android/layout_tests/fast/block/float/nested-clearance.html
-/sdcard/android/layout_tests/fast/block/float/br-with-clear-2.html
-/sdcard/android/layout_tests/fast/block/float/020.html
-/sdcard/android/layout_tests/fast/block/float/012.html
-/sdcard/android/layout_tests/fast/block/float/004.html
-/sdcard/android/layout_tests/fast/block/float/032.html
-/sdcard/android/layout_tests/fast/block/float/024.html
-/sdcard/android/layout_tests/fast/block/float/016.html
-/sdcard/android/layout_tests/fast/block/float/008.html
-/sdcard/android/layout_tests/fast/block/float/028.html
-/sdcard/android/layout_tests/fast/block/float/shrink-to-fit-width.html
-/sdcard/android/layout_tests/fast/block/float/clamped-right-float.html
-/sdcard/android/layout_tests/fast/block/float/independent-align-positioning.html
-/sdcard/android/layout_tests/fast/block/float/float-on-zero-height-line.html
-/sdcard/android/layout_tests/fast/block/float/nowrap-clear-min-width.html
-/sdcard/android/layout_tests/fast/block/float/overhanging-after-height-decrease-offsets.html
-/sdcard/android/layout_tests/fast/block/float/001.html
-/sdcard/android/layout_tests/fast/block/float/021.html
-/sdcard/android/layout_tests/fast/block/float/013.html
-/sdcard/android/layout_tests/fast/block/float/nopaint-after-layer-destruction2.html
-/sdcard/android/layout_tests/fast/block/float/005.html
-/sdcard/android/layout_tests/fast/block/float/033.html
-/sdcard/android/layout_tests/fast/block/float/025.html
-/sdcard/android/layout_tests/fast/block/float/017.html
-/sdcard/android/layout_tests/fast/block/float/009.html
-/sdcard/android/layout_tests/fast/block/float/float-in-float-hit-testing.html
-/sdcard/android/layout_tests/fast/block/float/029.html
-/sdcard/android/layout_tests/fast/block/float/4145535Crash.html
-/sdcard/android/layout_tests/fast/block/float/editable-text-overlapping-float.html
-/sdcard/android/layout_tests/fast/block/float/nestedAnonymousBlocks.html
-/sdcard/android/layout_tests/fast/block/float/intruding-painted-twice.html
-/sdcard/android/layout_tests/fast/block/float/010.html
-/sdcard/android/layout_tests/fast/block/float/002.html
-/sdcard/android/layout_tests/fast/block/float/dynamic-unfloat-pref-width.html
-/sdcard/android/layout_tests/fast/block/float/marquee-shrink-to-avoid-floats.html
-/sdcard/android/layout_tests/fast/block/float/030.html
-/sdcard/android/layout_tests/fast/block/float/022.html
-/sdcard/android/layout_tests/fast/block/float/014.html
-/sdcard/android/layout_tests/fast/block/float/006.html
-/sdcard/android/layout_tests/fast/block/float/relative-painted-twice.html
-/sdcard/android/layout_tests/fast/block/float/034.html
-/sdcard/android/layout_tests/fast/block/float/026.html
-/sdcard/android/layout_tests/fast/block/float/018.html
-/sdcard/android/layout_tests/fast/block/float/width-update-after-clear.html
-/sdcard/android/layout_tests/fast/block/float/nopaint-after-layer-destruction.html
-/sdcard/android/layout_tests/fast/block/float/float-in-float-painting.html
-/sdcard/android/layout_tests/fast/block/float/overhanging-after-height-decrease.html
-/sdcard/android/layout_tests/fast/block/float/float-avoidance.html
-/sdcard/android/layout_tests/fast/block/float/narrow-after-wide.html
-/sdcard/android/layout_tests/fast/block/float/multiple-float-positioning.html
-/sdcard/android/layout_tests/fast/block/float/br-with-clear.html
-/sdcard/android/layout_tests/fast/block/float/011.html
-/sdcard/android/layout_tests/fast/block/float/negative-margin-clear.html
-/sdcard/android/layout_tests/fast/block/float/003.html
-/sdcard/android/layout_tests/fast/block/float/031.html
-/sdcard/android/layout_tests/fast/block/float/023.html
-/sdcard/android/layout_tests/fast/block/float/015.html
-/sdcard/android/layout_tests/fast/block/float/007.html
-/sdcard/android/layout_tests/fast/block/float/035.html
-/sdcard/android/layout_tests/fast/block/float/027.html
-/sdcard/android/layout_tests/fast/block/float/019.html
-/sdcard/android/layout_tests/fast/block/float/nestedAnonymousBlocks2.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/059.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/empty-clear-blocks.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/010.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/negative-margins.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/002.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/020.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/101.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/030.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/012.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/040.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/022.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/004.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/103.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/032.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/006.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/042.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/016.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/034.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/062.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/044.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/026.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/018.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/028.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/056.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/038.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/058.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/100.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/001.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/011.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/102.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/021.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/003.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/031.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/005.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/041.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/104.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/033.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/015.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/025.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/043.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/035.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/017.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/027.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/045.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/063.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/037.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/019.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/055.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/029.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/039.html
-/sdcard/android/layout_tests/fast/block/margin-collapse/057.html
-/sdcard/android/layout_tests/fast/runin/generated.html
-/sdcard/android/layout_tests/fast/runin/001.html
-/sdcard/android/layout_tests/fast/runin/002.html
-/sdcard/android/layout_tests/fast/parser/comments.html
-/sdcard/android/layout_tests/fast/parser/title-error-test.html
-/sdcard/android/layout_tests/fast/parser/entity-comment-in-textarea.html
-/sdcard/android/layout_tests/fast/parser/parseCommentsInTitles.html
-/sdcard/android/layout_tests/fast/parser/open-comment-in-style.html
-/sdcard/android/layout_tests/fast/parser/document-write-option.html
-/sdcard/android/layout_tests/fast/parser/comment-in-textarea.html
-/sdcard/android/layout_tests/fast/parser/fonts.html
-/sdcard/android/layout_tests/fast/parser/comment-in-style.html
-/sdcard/android/layout_tests/fast/parser/comment-in-script.html
-/sdcard/android/layout_tests/fast/parser/broken-comments-vs-parsing-mode.html
-/sdcard/android/layout_tests/fast/parser/entity-comment-in-style.html
-/sdcard/android/layout_tests/fast/parser/xhtml-alternate-entities.xml
-/sdcard/android/layout_tests/fast/parser/nofoo-tags-inside-paragraph.html
-/sdcard/android/layout_tests/fast/parser/bad-xml-slash.html
-/sdcard/android/layout_tests/fast/parser/001.html
-/sdcard/android/layout_tests/fast/parser/open-comment-in-textarea.html
-/sdcard/android/layout_tests/fast/parser/tabs-in-scripts.html
-/sdcard/android/layout_tests/fast/parser/remove-block-in-residual-style.html
-/sdcard/android/layout_tests/fast/parser/style-script-head-test.html
-/sdcard/android/layout_tests/fast/layers/zindex-ridonkulous.html
-/sdcard/android/layout_tests/fast/layers/self-painting-outline.html
-/sdcard/android/layout_tests/fast/layers/positioned-inside-root-with-margins.html
-/sdcard/android/layout_tests/fast/layers/video-layer.html
-/sdcard/android/layout_tests/fast/layers/inline-dirty-z-order-lists.html
-/sdcard/android/layout_tests/fast/layers/layer-visibility-sublayer.html
-/sdcard/android/layout_tests/fast/layers/opacity-outline.html
-/sdcard/android/layout_tests/fast/layers/add-layer-with-nested-stacking.html
-/sdcard/android/layout_tests/fast/layers/layer-content-visibility-change.html
-/sdcard/android/layout_tests/fast/layers/normal-flow-hit-test.html
-/sdcard/android/layout_tests/fast/layers/remove-layer-with-nested-stacking.html
-/sdcard/android/layout_tests/fast/layers/layer-visibility.html
-/sdcard/android/layout_tests/fast/layers/zindex-inherit.html
-/sdcard/android/layout_tests/fast/layers/overflow-scroll-auto-switch.html
-/sdcard/android/layout_tests/fast/layers/opacity-transforms.html
-/sdcard/android/layout_tests/fast/layers/scroll-rect-to-visible.html
-/sdcard/android/layout_tests/fast/layers/opacity-stacking.html
-/sdcard/android/layout_tests/fast/layers/remove-only-this-layer-update.html
-/sdcard/android/layout_tests/fast/history/clicked-link-is-visited.html
-/sdcard/android/layout_tests/fast/backgrounds/repeat/mask-negative-offset-repeat.html
-/sdcard/android/layout_tests/fast/backgrounds/repeat/negative-offset-repeat.html
-/sdcard/android/layout_tests/fast/backgrounds/repeat/negative-offset-repeat-transformed.html
-/sdcard/android/layout_tests/fast/backgrounds/repeat/noRepeatCorrectClip.html
-/sdcard/android/layout_tests/fast/backgrounds/size/backgroundSize20.html
-/sdcard/android/layout_tests/fast/backgrounds/size/backgroundSize02.html
-/sdcard/android/layout_tests/fast/backgrounds/size/backgroundSize11.html
-/sdcard/android/layout_tests/fast/backgrounds/size/backgroundSize21.html
-/sdcard/android/layout_tests/fast/backgrounds/size/backgroundSize03.html
-/sdcard/android/layout_tests/fast/backgrounds/size/backgroundSize12.html
-/sdcard/android/layout_tests/fast/backgrounds/size/backgroundSize22.html
-/sdcard/android/layout_tests/fast/backgrounds/size/backgroundSize04.html
-/sdcard/android/layout_tests/fast/backgrounds/size/backgroundSize13.html
-/sdcard/android/layout_tests/fast/backgrounds/size/zero.html
-/sdcard/android/layout_tests/fast/backgrounds/size/backgroundSize05.html
-/sdcard/android/layout_tests/fast/backgrounds/size/backgroundSize14.html
-/sdcard/android/layout_tests/fast/backgrounds/size/backgroundSize06.html
-/sdcard/android/layout_tests/fast/backgrounds/size/backgroundSize15.html
-/sdcard/android/layout_tests/fast/backgrounds/size/backgroundSize07.html
-/sdcard/android/layout_tests/fast/backgrounds/size/backgroundSize16.html
-/sdcard/android/layout_tests/fast/backgrounds/size/backgroundSize08.html
-/sdcard/android/layout_tests/fast/backgrounds/size/backgroundSize17.html
-/sdcard/android/layout_tests/fast/backgrounds/size/backgroundSize09.html
-/sdcard/android/layout_tests/fast/backgrounds/size/backgroundSize18.html
-/sdcard/android/layout_tests/fast/backgrounds/size/backgroundSize19.html
-/sdcard/android/layout_tests/fast/backgrounds/size/backgroundSize10.html
-/sdcard/android/layout_tests/fast/backgrounds/size/backgroundSize01.html
-/sdcard/android/layout_tests/fast/backgrounds/svg-as-background-2.html
-/sdcard/android/layout_tests/fast/backgrounds/background-origin-root-element.html
-/sdcard/android/layout_tests/fast/backgrounds/svg-as-background-3.html
-/sdcard/android/layout_tests/fast/backgrounds/svg-as-background-4.html
-/sdcard/android/layout_tests/fast/backgrounds/svg-as-background-5.html
-/sdcard/android/layout_tests/fast/backgrounds/background-position-1.html
-/sdcard/android/layout_tests/fast/backgrounds/svg-as-background-6.html
-/sdcard/android/layout_tests/fast/backgrounds/opacity-on-document-element.html
-/sdcard/android/layout_tests/fast/backgrounds/background-clip-text.html
-/sdcard/android/layout_tests/fast/backgrounds/svg-as-mask.html
-/sdcard/android/layout_tests/fast/backgrounds/solid-color-context-restore.html
-/sdcard/android/layout_tests/fast/backgrounds/mask-composite.html
-/sdcard/android/layout_tests/fast/backgrounds/animated-svg-as-background.html
-/sdcard/android/layout_tests/fast/backgrounds/body-generated-image-propagated-to-root.html
-/sdcard/android/layout_tests/fast/backgrounds/001.html
-/sdcard/android/layout_tests/fast/backgrounds/animated-gif-as-background.html
-/sdcard/android/layout_tests/fast/backgrounds/background-position-rounding.html
-/sdcard/android/layout_tests/fast/backgrounds/bgCompositeCopy.html
-/sdcard/android/layout_tests/fast/backgrounds/background-inherit-color-bug.html
-/sdcard/android/layout_tests/fast/backgrounds/animated-svg-as-mask.html
-/sdcard/android/layout_tests/fast/backgrounds/svg-as-background-1.html
-/sdcard/android/layout_tests/fast/repaint/reflection-redraw.html
-/sdcard/android/layout_tests/fast/repaint/layer-full-repaint.html
-/sdcard/android/layout_tests/fast/repaint/subtree-root-clip.html
-/sdcard/android/layout_tests/fast/repaint/subtree-root-clip-3.html
-/sdcard/android/layout_tests/fast/repaint/layer-outline-horizontal.html
-/sdcard/android/layout_tests/fast/repaint/transform-layout-repaint.html
-/sdcard/android/layout_tests/fast/repaint/float-new-in-block.html
-/sdcard/android/layout_tests/fast/repaint/list-marker-2.html
-/sdcard/android/layout_tests/fast/repaint/layer-hide-when-needs-layout.html
-/sdcard/android/layout_tests/fast/repaint/layer-outline.html
-/sdcard/android/layout_tests/fast/repaint/table-section-overflow.html
-/sdcard/android/layout_tests/fast/repaint/body-background-image.html
-/sdcard/android/layout_tests/fast/repaint/shadow-multiple-strict-vertical.html
-/sdcard/android/layout_tests/fast/repaint/inline-outline-repaint.html
-/sdcard/android/layout_tests/fast/repaint/line-flow-with-floats-4.html
-/sdcard/android/layout_tests/fast/repaint/change-transform.html
-/sdcard/android/layout_tests/fast/repaint/fixed.html
-/sdcard/android/layout_tests/fast/repaint/line-flow-with-floats-8.html
-/sdcard/android/layout_tests/fast/repaint/erase-overflow.html
-/sdcard/android/layout_tests/fast/repaint/outline-child-repaint.html
-/sdcard/android/layout_tests/fast/repaint/float-overflow.html
-/sdcard/android/layout_tests/fast/repaint/containing-block-position-change.html
-/sdcard/android/layout_tests/fast/repaint/text-selection-rect-in-overflow.html
-/sdcard/android/layout_tests/fast/repaint/flexible-box-overflow-horizontal.html
-/sdcard/android/layout_tests/fast/repaint/table-cell-move.html
-/sdcard/android/layout_tests/fast/repaint/transform-absolute-child.html
-/sdcard/android/layout_tests/fast/repaint/line-flow-with-floats-10.html
-/sdcard/android/layout_tests/fast/repaint/opacity-change-on-overflow-float.html
-/sdcard/android/layout_tests/fast/repaint/float-move-during-layout.html
-/sdcard/android/layout_tests/fast/repaint/overflow-clip-subtree-layout.html
-/sdcard/android/layout_tests/fast/repaint/invisible-objects.html
-/sdcard/android/layout_tests/fast/repaint/shadow-multiple-strict-horizontal.html
-/sdcard/android/layout_tests/fast/repaint/focus-layers.html
-/sdcard/android/layout_tests/fast/repaint/inline-color-change.html
-/sdcard/android/layout_tests/fast/repaint/table-col-background.html
-/sdcard/android/layout_tests/fast/repaint/selection-after-remove.html
-/sdcard/android/layout_tests/fast/repaint/dynamic-table-vertical-alignment-change.html
-/sdcard/android/layout_tests/fast/repaint/flexible-box-overflow.html
-/sdcard/android/layout_tests/fast/repaint/table-two-pass-layout-overpaint.html
-/sdcard/android/layout_tests/fast/repaint/overflow-into-content.html
-/sdcard/android/layout_tests/fast/repaint/shadow-multiple-vertical.html
-/sdcard/android/layout_tests/fast/repaint/border-repaint-glitch.html
-/sdcard/android/layout_tests/fast/repaint/continuation-after-outline.html
-/sdcard/android/layout_tests/fast/repaint/intermediate-layout-position.html
-/sdcard/android/layout_tests/fast/repaint/table-section-repaint.html
-/sdcard/android/layout_tests/fast/repaint/clipped-relative.html
-/sdcard/android/layout_tests/fast/repaint/line-flow-with-floats-1.html
-/sdcard/android/layout_tests/fast/repaint/backgroundSizeRepaint.html
-/sdcard/android/layout_tests/fast/repaint/box-shadow-dynamic.html
-/sdcard/android/layout_tests/fast/repaint/line-flow-with-floats-5.html
-/sdcard/android/layout_tests/fast/repaint/text-shadow-horizontal.html
-/sdcard/android/layout_tests/fast/repaint/caret-outside-block.html
-/sdcard/android/layout_tests/fast/repaint/renderer-destruction-by-invalidateSelection-crash.html
-/sdcard/android/layout_tests/fast/repaint/line-flow-with-floats-9.html
-/sdcard/android/layout_tests/fast/repaint/float-in-new-block-with-layout-delta.html
-/sdcard/android/layout_tests/fast/repaint/transform-repaint-descendants.html
-/sdcard/android/layout_tests/fast/repaint/layout-state-relative.html
-/sdcard/android/layout_tests/fast/repaint/shadow-multiple-horizontal.html
-/sdcard/android/layout_tests/fast/repaint/border-fit-lines.html
-/sdcard/android/layout_tests/fast/repaint/repaint-resized-overflow.html
-/sdcard/android/layout_tests/fast/repaint/bugzilla-3509.html
-/sdcard/android/layout_tests/fast/repaint/inline-block-overflow.html
-/sdcard/android/layout_tests/fast/repaint/search-field-cancel.html
-/sdcard/android/layout_tests/fast/repaint/background-generated.html
-/sdcard/android/layout_tests/fast/repaint/bugzilla-6278.html
-/sdcard/android/layout_tests/fast/repaint/button-spurious-layout-hint.html
-/sdcard/android/layout_tests/fast/repaint/box-shadow-v.html
-/sdcard/android/layout_tests/fast/repaint/float-overflow-right.html
-/sdcard/android/layout_tests/fast/repaint/delete-into-nested-block.html
-/sdcard/android/layout_tests/fast/repaint/table-cell-collapsed-border.html
-/sdcard/android/layout_tests/fast/repaint/selection-after-delete.html
-/sdcard/android/layout_tests/fast/repaint/layout-state-only-positioned.html
-/sdcard/android/layout_tests/fast/repaint/lines-with-layout-delta.html
-/sdcard/android/layout_tests/fast/repaint/table-extra-bottom-grow.html
-/sdcard/android/layout_tests/fast/repaint/transform-relative-position.html
-/sdcard/android/layout_tests/fast/repaint/selection-gap-overflow-scroll.html
-/sdcard/android/layout_tests/fast/repaint/subtree-root-skipped.html
-/sdcard/android/layout_tests/fast/repaint/line-overflow.html
-/sdcard/android/layout_tests/fast/repaint/background-misaligned.html
-/sdcard/android/layout_tests/fast/repaint/line-flow-with-floats-2.html
-/sdcard/android/layout_tests/fast/repaint/text-append-dirty-lines.html
-/sdcard/android/layout_tests/fast/repaint/table-row.html
-/sdcard/android/layout_tests/fast/repaint/line-flow-with-floats-6.html
-/sdcard/android/layout_tests/fast/repaint/table-outer-border.html
-/sdcard/android/layout_tests/fast/repaint/transform-replaced-shadows.html
-/sdcard/android/layout_tests/fast/repaint/overflow-scroll-delete.html
-/sdcard/android/layout_tests/fast/repaint/layer-visibility.html
-/sdcard/android/layout_tests/fast/repaint/border-radius-repaint.html
-/sdcard/android/layout_tests/fast/repaint/table-collapsed-border.html
-/sdcard/android/layout_tests/fast/repaint/transform-translate.html
-/sdcard/android/layout_tests/fast/repaint/bugzilla-7235.html
-/sdcard/android/layout_tests/fast/repaint/reflection-repaint-test.html
-/sdcard/android/layout_tests/fast/repaint/4776765.html
-/sdcard/android/layout_tests/fast/repaint/selection-clear.html
-/sdcard/android/layout_tests/fast/repaint/bugzilla-6473.html
-/sdcard/android/layout_tests/fast/repaint/intermediate-layout-position-clip.html
-/sdcard/android/layout_tests/fast/repaint/focus-ring.html
-/sdcard/android/layout_tests/fast/repaint/table-cell-vertical-overflow.html
-/sdcard/android/layout_tests/fast/repaint/create-layer-repaint.html
-/sdcard/android/layout_tests/fast/repaint/subtree-root-clip-2.html
-/sdcard/android/layout_tests/fast/repaint/bugzilla-6388.html
-/sdcard/android/layout_tests/fast/repaint/overflow-outline-repaint.html
-/sdcard/android/layout_tests/fast/repaint/content-into-overflow.html
-/sdcard/android/layout_tests/fast/repaint/static-to-positioned.html
-/sdcard/android/layout_tests/fast/repaint/bugzilla-5699.html
-/sdcard/android/layout_tests/fast/repaint/transform-absolute-in-positioned-container.html
-/sdcard/android/layout_tests/fast/repaint/outline-repaint-glitch.html
-/sdcard/android/layout_tests/fast/repaint/overflow-delete-line.html
-/sdcard/android/layout_tests/fast/repaint/transform-disable-layoutstate.html
-/sdcard/android/layout_tests/fast/repaint/list-marker.html
-/sdcard/android/layout_tests/fast/repaint/line-flow-with-floats-3.html
-/sdcard/android/layout_tests/fast/repaint/line-flow-with-floats-7.html
-/sdcard/android/layout_tests/fast/repaint/outline-inset.html
-/sdcard/android/layout_tests/fast/repaint/box-shadow-h.html
-/sdcard/android/layout_tests/fast/repaint/4774354.html
-/sdcard/android/layout_tests/fast/repaint/clip-with-layout-delta.html
-/sdcard/android/layout_tests/fast/repaint/control-clip.html
-/sdcard/android/layout_tests/fast/repaint/selected-replaced.html
-/sdcard/android/layout_tests/fast/repaint/text-selection-rect-in-overflow-2.html
-/sdcard/android/layout_tests/fast/repaint/make-children-non-inline.html
-/sdcard/android/layout_tests/fast/repaint/text-shadow.html
-/sdcard/android/layout_tests/fast/repaint/outline-shrinking.html
-/sdcard/android/layout_tests/fast/repaint/layer-child-outline.html
-/sdcard/android/layout_tests/fast/loader/start-load-in-unload.html
-/sdcard/android/layout_tests/fast/loader/text-document-wrapping.html
-/sdcard/android/layout_tests/fast/xsl/document-function.xml
-/sdcard/android/layout_tests/fast/xsl/xslt-extra-content-at-end.xml
-/sdcard/android/layout_tests/fast/xsl/xslt-enc.xml
-/sdcard/android/layout_tests/fast/xsl/xslt_unicode.xml
-/sdcard/android/layout_tests/fast/xsl/xslt-import-depth.xml
-/sdcard/android/layout_tests/fast/xsl/xslt-enc16.xml
-/sdcard/android/layout_tests/fast/xsl/xslt-enc16to16.xml
-/sdcard/android/layout_tests/fast/xsl/xslt-missing-namespace-in-xslt.xml
-/sdcard/android/layout_tests/fast/xsl/xslt-enc-cyr.xml
-/sdcard/android/layout_tests/fast/xsl/xslt-relative-path.xml
-/sdcard/android/layout_tests/fast/xsl/xslt-mismatched-tags-in-xslt.xml
-/sdcard/android/layout_tests/fast/xsl/xslt-entity.xml
-/sdcard/android/layout_tests/fast/canvas/fillrect-gradient-zero-stops.html
-/sdcard/android/layout_tests/fast/canvas/canvas-transforms-during-path.html
-/sdcard/android/layout_tests/fast/canvas/drawImage.html
-/sdcard/android/layout_tests/fast/canvas/shadow-offset-7.html
-/sdcard/android/layout_tests/fast/canvas/image-pattern-rotate.html
-/sdcard/android/layout_tests/fast/canvas/shadow-offset-4.html
-/sdcard/android/layout_tests/fast/canvas/drawImage-with-globalAlpha.html
-/sdcard/android/layout_tests/fast/canvas/canvas-text-baseline.html
-/sdcard/android/layout_tests/fast/canvas/canvas-as-image-incremental-repaint.html
-/sdcard/android/layout_tests/fast/canvas/shadow-offset-1.html
-/sdcard/android/layout_tests/fast/canvas/canvas-size-change-after-layout.html
-/sdcard/android/layout_tests/fast/canvas/canvas-resize-reset.html
-/sdcard/android/layout_tests/fast/canvas/canvas-bg.html
-/sdcard/android/layout_tests/fast/canvas/zero-size-fill-rect.html
-/sdcard/android/layout_tests/fast/canvas/shadow-offset-6.html
-/sdcard/android/layout_tests/fast/canvas/patternfill-repeat.html
-/sdcard/android/layout_tests/fast/canvas/image-object-in-canvas.html
-/sdcard/android/layout_tests/fast/canvas/shadow-offset-3.html
-/sdcard/android/layout_tests/fast/canvas/canvas-composite.html
-/sdcard/android/layout_tests/fast/canvas/quadraticCurveTo.xml
-/sdcard/android/layout_tests/fast/canvas/gradient-add-second-start-end-stop.html
-/sdcard/android/layout_tests/fast/canvas/fill-stroke-clip-reset-path.html
-/sdcard/android/layout_tests/fast/canvas/canvas-text-alignment.html
-/sdcard/android/layout_tests/fast/canvas/canvas-incremental-repaint.html
-/sdcard/android/layout_tests/fast/canvas/canvas-bg-zoom.html
-/sdcard/android/layout_tests/fast/canvas/canvasDrawingIntoSelf.html
-/sdcard/android/layout_tests/fast/canvas/canvas-as-image.html
-/sdcard/android/layout_tests/fast/canvas/canvas-before-css.html
-/sdcard/android/layout_tests/fast/canvas/canvas-incremental-repaint-2.html
-/sdcard/android/layout_tests/fast/canvas/shadow-offset-5.html
-/sdcard/android/layout_tests/fast/canvas/fillrect_gradient.html
-/sdcard/android/layout_tests/fast/canvas/shadow-offset-2.html
-/sdcard/android/layout_tests/fast/frames/contentWindow_Frame.html
-/sdcard/android/layout_tests/fast/frames/onlyCommentInIFrame.html
-/sdcard/android/layout_tests/fast/frames/content-opacity-2.html
-/sdcard/android/layout_tests/fast/frames/frame-src-attribute.html
-/sdcard/android/layout_tests/fast/frames/frameElement-frame.html
-/sdcard/android/layout_tests/fast/frames/empty-cols-attribute.html
-/sdcard/android/layout_tests/fast/frames/iframe-scrolling-attribute.html
-/sdcard/android/layout_tests/fast/frames/inline-object-inside-frameset.html
-/sdcard/android/layout_tests/fast/frames/valid.html
-/sdcard/android/layout_tests/fast/frames/no-frame-borders.html
-/sdcard/android/layout_tests/fast/frames/empty-frame-src.html
-/sdcard/android/layout_tests/fast/frames/calculate-round.html
-/sdcard/android/layout_tests/fast/frames/frame-navigation.html
-/sdcard/android/layout_tests/fast/frames/001.html
-/sdcard/android/layout_tests/fast/frames/viewsource-on-image-file.html
-/sdcard/android/layout_tests/fast/frames/invalid.html
-/sdcard/android/layout_tests/fast/frames/frameset-style-recalc.html
-/sdcard/android/layout_tests/fast/frames/viewsource-attribute.html
-/sdcard/android/layout_tests/fast/frames/002.html
-/sdcard/android/layout_tests/fast/frames/calculate-relative.html
-/sdcard/android/layout_tests/fast/frames/calculate-order.html
-/sdcard/android/layout_tests/fast/frames/calculate-percentage.html
-/sdcard/android/layout_tests/fast/frames/content-opacity-1.html
-/sdcard/android/layout_tests/fast/frames/iframe-text-contents.html
-/sdcard/android/layout_tests/fast/frames/frame-scrolling-attribute.html
-/sdcard/android/layout_tests/fast/frames/contentWindow_iFrame.html
-/sdcard/android/layout_tests/fast/frames/calculate-fixed.html
-/sdcard/android/layout_tests/fast/frames/frame-element-name.html
-/sdcard/android/layout_tests/fast/frames/frame-set-whitespace-attributes.html
-/sdcard/android/layout_tests/fast/frames/iframe-with-frameborder.html
-/sdcard/android/layout_tests/fast/frames/frameElement-iframe.html
-/sdcard/android/layout_tests/fast/reflections/inline-crash.html
-/sdcard/android/layout_tests/fast/reflections/reflection-masks-opacity.html
-/sdcard/android/layout_tests/fast/reflections/reflection-nesting.html
-/sdcard/android/layout_tests/fast/reflections/reflection-overflow-hidden.html
-/sdcard/android/layout_tests/fast/reflections/table-cell.html
-/sdcard/android/layout_tests/fast/reflections/reflection-masks.html
-/sdcard/android/layout_tests/fast/reflections/reflection-direction.html
-/sdcard/android/layout_tests/fonts/cursive.html
-/sdcard/android/layout_tests/fonts/default.html
-/sdcard/android/layout_tests/fonts/monospace.html
-/sdcard/android/layout_tests/fonts/fantasy.html
-/sdcard/android/layout_tests/fonts/serif.html
-/sdcard/android/layout_tests/fonts/sans-serif.html
-/sdcard/android/layout_tests/http/tests/webarchive/test-css-url-encoding-shift-jis.html
-/sdcard/android/layout_tests/http/tests/webarchive/test-css-url-encoding.html
-/sdcard/android/layout_tests/http/tests/webarchive/test-css-url-encoding-utf-8.html
-/sdcard/android/layout_tests/http/tests/webarchive/test-preload-resources.html
-/sdcard/android/layout_tests/http/tests/multipart/invalid-image-data.html
-/sdcard/android/layout_tests/http/tests/multipart/invalid-image-data-standalone.html
-/sdcard/android/layout_tests/http/tests/local/file-url-sent-as-referer.html
-/sdcard/android/layout_tests/http/tests/misc/location-replace-crossdomain.html
-/sdcard/android/layout_tests/http/tests/misc/acid2.html
-/sdcard/android/layout_tests/http/tests/misc/acid2-pixel.html
-/sdcard/android/layout_tests/http/tests/misc/favicon-as-image.html
-/sdcard/android/layout_tests/http/tests/misc/generated-content-inside-table.html
-/sdcard/android/layout_tests/http/tests/misc/willCacheResponse-delegate-callback.html
-/sdcard/android/layout_tests/http/tests/misc/iframe404.html
-/sdcard/android/layout_tests/http/tests/misc/frame-access-during-load.html
-/sdcard/android/layout_tests/http/tests/navigation/postredirect-goback1.html
-/sdcard/android/layout_tests/http/tests/navigation/error404-subframeload.html
-/sdcard/android/layout_tests/http/tests/navigation/error404-basic.html
-/sdcard/android/layout_tests/http/tests/navigation/anchor-frames.html
-/sdcard/android/layout_tests/http/tests/navigation/postredirect-basic.html
-/sdcard/android/layout_tests/http/tests/navigation/post-goback1.html
-/sdcard/android/layout_tests/http/tests/navigation/post-basic.html
-/sdcard/android/layout_tests/http/tests/navigation/post-frames.html
-/sdcard/android/layout_tests/http/tests/navigation/error404-goback.html
-/sdcard/android/layout_tests/http/tests/navigation/javascriptlink-frames.html
-/sdcard/android/layout_tests/http/tests/navigation/postredirect-frames.html
-/sdcard/android/layout_tests/http/tests/navigation/error404-frames.html
-/sdcard/android/layout_tests/http/tests/loading/simple-subframe.html
-/sdcard/android/layout_tests/media/video-display-toggle.html
-/sdcard/android/layout_tests/media/video-transformed.html
-/sdcard/android/layout_tests/media/video-empty-source.html
-/sdcard/android/layout_tests/media/controls-strict.html
-/sdcard/android/layout_tests/media/audio-controls-rendering.html
-/sdcard/android/layout_tests/media/video-controls-visible-audio-only.html
-/sdcard/android/layout_tests/media/audio-no-installed-engines.html
-/sdcard/android/layout_tests/media/video-zoom.html
-/sdcard/android/layout_tests/media/video-zoom-controls.html
-/sdcard/android/layout_tests/media/video-controls-rendering.html
-/sdcard/android/layout_tests/media/controls-styling.html
-/sdcard/android/layout_tests/media/video-aspect-ratio.html
-/sdcard/android/layout_tests/media/controls-after-reload.html
-/sdcard/android/layout_tests/media/video-layer-crash.html
-/sdcard/android/layout_tests/plugins/netscape-dom-access.html
-/sdcard/android/layout_tests/plugins/embed-attributes-style.html
-/sdcard/android/layout_tests/printing/media-queries-print.html
-/sdcard/android/layout_tests/scrollbars/scrollbar-orientation.html
-/sdcard/android/layout_tests/scrollbars/scrollbar-buttons.html
-/sdcard/android/layout_tests/scrollbars/basic-scrollbar.html
-/sdcard/android/layout_tests/scrollbars/overflow-scrollbar-combinations.html
-/sdcard/android/layout_tests/scrollbars/disabled-scrollbar.html
-/sdcard/android/layout_tests/scrollbars/listbox-scrollbar-combinations.html
-/sdcard/android/layout_tests/security/block-test-no-port.html
-/sdcard/android/layout_tests/security/block-test.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/dom/insertTbodyRebuild1.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/dom/appendCellsRebuild1.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/dom/appendColGroup1.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/dom/appendCol1.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/dom/insertTbodyExpand1.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/dom/appendCells1.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug56024.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-14.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug11945.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-18.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug72393.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug23847.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug7121-2.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug27993-2.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug7243.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-3.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug1647.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-7.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug101759.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug2479-5.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug14007-1.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-11.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug1010.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-15.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug14159-2.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug25707.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug47163.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug91057.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug131020-3.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug19526.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug14489.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug73629.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug1725.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-4.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug106336.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-8.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug22122.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug10216.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug14007-2.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug106966.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug32205-4.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug42043.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug178855.xml
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-12.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug92868_1.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug21518.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug45621.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-16.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug65372.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug59252.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug29058-2.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug17826.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug67915-2.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug46268-4.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug1128.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug1164.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-1.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/97619.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-5.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug10140.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-9.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug32205-1.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug61042-1.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug104898.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug8499.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug9879-1.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug128876.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-13.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug58402-2.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug24880-1.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug85016.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-17.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug80762-2.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug18770.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug33784.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3105.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug1055-2.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug89315.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug92647-1.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug1262.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug7113.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-2.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3517.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug220653.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug4294.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-6.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug6933.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug51000.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug11331.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug61042-2.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-10.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/other/empty_cells.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/other/test4.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/core/col_span2.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/core/columns.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/core/captions1.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/core/cols1.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/core/backgrounds.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/core/captions2.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/core/captions3.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/core/conflicts.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/core/standards1.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/collapsing_borders/bug41262-5.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/collapsing_borders/bug41262-6.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/collapsing_borders/bug41262-1.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/x_table_frame_below.xml
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/backgr_position-table-cell.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_caption.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_dirty_reflow_row.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_hidden_tr.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/backgr_position-table-column.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/tables_caption_align_right.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/backgr_border-table-column-group.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/backgr_position-table-row-group.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_caption_hidden.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_style_reflow_row_sibling.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_frame_lhs.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_style_reflow_tbody.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_rules_rows.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/x_table_rules_all.xml
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_frame_above.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_style_reflow_table.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_frame_void.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/x_table_frame_hsides.xml
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_td_valign_top.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_caption_right.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_hidden_tbody.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/backgr_layers-show.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/x_caption_align_right.xml
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/backgr_border-table-cell.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_frame_below.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_style_reflow_table_caption.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_hidden_table.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/x_table_rules_cols.xml
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_style_reflow_cell.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/backgr_position-table-row.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_td_align_right.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/backgr_border-table-row.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_style_reflow_tbody_sibling.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_rules_cols.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/x_table_frame_border.xml
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/x_colgroup_width_px.xml
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_td_valign_bottom.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/backgr_border-table-quirks.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/x_table_frame_box.xml
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/x_table_rules_rows.xml
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_frame_hsides.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_caption_left.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/x_caption_align_left.xml
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_caption_hidden_table.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/backgr_border-table-row-group.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_caption_bottom.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/backgr_border-table.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_frame_rhs.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_frame_vsides.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_style_reflow_cell_sibling.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/backgr_layers-hide.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_td_valign_middle.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/tables_cellspacing_pct.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/backgr_position-table-column-group.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/x_table_frame_lhs.xml
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/backgr_fixed-bg.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_td_dynamic_deactivate.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_style_reflow_row.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/x_table_frame_rhs.xml
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/x_table_frame_above.xml
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/x_table_frame_vsides.xml
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_dirty_reflow.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_dirty_reflow_tbody.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/backgr_border-table-column.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_caption_top.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_dirty_reflow_table.html
-/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/tables_caption_align_left.html
-/sdcard/android/layout_tests/tables/mozilla/dom/deleteCellsRebuild1.html
-/sdcard/android/layout_tests/tables/mozilla/dom/deleteRowsShrink1.html
-/sdcard/android/layout_tests/tables/mozilla/dom/insertCellsRebuild1.html
-/sdcard/android/layout_tests/tables/mozilla/dom/insertCellsRebuild2.html
-/sdcard/android/layout_tests/tables/mozilla/dom/deleteCol1.html
-/sdcard/android/layout_tests/tables/mozilla/dom/deleteCol2.html
-/sdcard/android/layout_tests/tables/mozilla/dom/insertColGroups1.html
-/sdcard/android/layout_tests/tables/mozilla/dom/deleteCol3.html
-/sdcard/android/layout_tests/tables/mozilla/dom/insertColGroups2.html
-/sdcard/android/layout_tests/tables/mozilla/dom/deleteCellsShrink1.html
-/sdcard/android/layout_tests/tables/mozilla/dom/deleteTbodyExpand1.html
-/sdcard/android/layout_tests/tables/mozilla/dom/deleteCellsShrink2.html
-/sdcard/android/layout_tests/tables/mozilla/dom/tableDom.html
-/sdcard/android/layout_tests/tables/mozilla/dom/appendCol2.html
-/sdcard/android/layout_tests/tables/mozilla/dom/appendTbodyExpand1.html
-/sdcard/android/layout_tests/tables/mozilla/dom/deleteTbodyRebuild1.html
-/sdcard/android/layout_tests/tables/mozilla/dom/deleteColGroup1.html
-/sdcard/android/layout_tests/tables/mozilla/dom/deleteColGroup2.html
-/sdcard/android/layout_tests/tables/mozilla/dom/insertRowsExpand1.html
-/sdcard/android/layout_tests/tables/mozilla/dom/appendRowsExpand1.html
-/sdcard/android/layout_tests/tables/mozilla/dom/deleteRowsRebuild1.html
-/sdcard/android/layout_tests/tables/mozilla/dom/insertCols1.html
-/sdcard/android/layout_tests/tables/mozilla/dom/insertCols2.html
-/sdcard/android/layout_tests/tables/mozilla/dom/insertRowsRebuild1.html
-/sdcard/android/layout_tests/tables/mozilla/dom/insertCellsExpand1.html
-/sdcard/android/layout_tests/tables/mozilla/dom/insertCols3.html
-/sdcard/android/layout_tests/tables/mozilla/dom/insertCellsExpand2.html
-/sdcard/android/layout_tests/tables/mozilla/dom/insertCols4.html
-/sdcard/android/layout_tests/tables/mozilla/dom/insertCols5.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug30418.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug14159-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug46623-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug24661.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug30692.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug53690-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug88035-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug51727.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug81934.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug68912.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug60992.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug92647-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug120107.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug1271.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug28928.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug103533.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug4093.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug2267.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug92868.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug4429.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug5538.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug106816.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug10009.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug149275-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug32205-3.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug13118.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug1802s.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug10296-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug647.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug48028-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug72359.xml
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug25367.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug1430.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug1224.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug67915-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug45486.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug113424.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug108340.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug3454.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug2479-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug139524-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug4849-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug11321.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug2886.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug219693-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug42443.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug54450.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug269566.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug12709.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug80762-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug21918.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug1302.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug25663.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug55527.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug7112-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug1055-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug69382-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug17587.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug102145-3.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug2516.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug4803.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug19599.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug1188.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug3718.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug110566.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug106158-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug5188.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug215629.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug154780.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug137388-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug10039.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug5798.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug22246-3a.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug25074.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug27038-3.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/45621.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug25086.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug43854-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug34538.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug131020.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug7121-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug4501.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug53891.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug8032-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug46268-5.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug63785.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug113235-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug69187.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug9024.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug120364.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug109043.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug220536.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug1818-5.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug2973.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug222467.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug6674.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug99948.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug277062.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug127267.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug30332-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug10036.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug16012.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug2997.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug17130-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug650.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug14323.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug10565.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug52505.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug29314.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug13169.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug30559.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug29326.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug55545.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug46268-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug18359.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug3037-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug82946-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug55694.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug6304.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug3263.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug1818-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug101674.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug123862.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug221784-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug275625.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug106795.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug22513.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug57300.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug51037.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug119786.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug12908-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug15247.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug46623-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug34176.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug53690-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug24880.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug41890.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug88035-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug50695-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug1163-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug8411.xml
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug1802.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug3260.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug97138.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug9123-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug3309-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug3191.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug1296.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug222336.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug2773.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug8381.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug194024.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug2947.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug5838.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug60013.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug138725.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug11026.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug175455-4.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug58402-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug43039.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug48028-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug24627.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug35662.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug21299.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug26178.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug18664.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug23299.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug88524.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug48827.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug1318.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug4427.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug6184.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug11384s.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug5835.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug4576.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug2479-3.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug139524-3.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug133948.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug9879-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug11944.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug13196.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug20579.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug29058-3.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug96334.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug7112-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug60749.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug59354.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug69382-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug27993-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug57378.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug102145-4.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug98196.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug9072.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug2585.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug145572.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug137388-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug5799.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug157890.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug196870.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug22246-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug73321.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug18440.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug965.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug131020-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug43854-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug96343.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug46368-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug102145-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug8032-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug1067-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug2065.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug97383.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug113235-3.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug3681-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug9271-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug1809.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug2962.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug1818-6.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug2469.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug8950.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug133756-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug2886-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug159108.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug4849.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug25004.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug12910.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug43204.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug20804.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug23072.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug19061-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug10269-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug13526.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug52506.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug27038-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug46480-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug42187.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug2050.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug3103.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug39209.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug46268.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug46268-3.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug38916.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug82946-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug3037-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug4523.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug67864.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug8361.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug1818-3.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug2981-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug2684.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug4385.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug126742.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug12910-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug8858.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug709.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug16252.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug33137.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug45350.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug12908-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug92143.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug14159-3.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug50695-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug29429.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug1261.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug4520.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug46944.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/adforce_imgis_com.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug18955.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug227123.xml
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug3309-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug9123-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug7342.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug83786.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug4382.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug24200.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug641-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug625.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug32205-5.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug56201.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug32841.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug44505.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug45055-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug15544.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug40828.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug1800.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug6404.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug2509.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug2479-4.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug4739.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug139524-4.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug13105.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug149275-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug32205-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug12008.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug10296-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug727.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug278385.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug13484.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug15933.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug60807.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug93363.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug14929.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug86708.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug57828.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug11384q.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug2954.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug2479-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug139524-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug219693-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug137388-3.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug30273.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug22246-3.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug22246-2a.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug12384.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug44523.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug60804.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug86220.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug32447.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug17138.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug56405.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug26553.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug1220.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug29058-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug33855.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug29157.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug2123.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug19356.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug28933.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug46368-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug18558.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug102145-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug1067-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug1474.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug3681-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug4284.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug4527.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug9271-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug2296.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug106158-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug2757.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug128229.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug133756-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug5797.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug278266.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug23235.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug19061-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug10269-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug963.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug27038-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug12268.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug45055.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug7471.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug75250.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug46480-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug30985.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug46924.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug56563.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug23994.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug113235-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug99923.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug55789.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug2981-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug1818-4.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug7714.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug222846.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug68998.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug30332-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug17130-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug51140.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug23151.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug10633.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug24503.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug28341.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug47432.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug101201.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug17168.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug46268-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug78162.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug17548.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug100334.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug57828-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug1818-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug2763.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug1828.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug221784-1.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug3977.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug131020_iframe.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug641-2.html
-/sdcard/android/layout_tests/tables/mozilla/bugs/bug22019.html
-/sdcard/android/layout_tests/tables/mozilla/other/move_row.html
-/sdcard/android/layout_tests/tables/mozilla/other/nestedTables.html
-/sdcard/android/layout_tests/tables/mozilla/other/wa_table_tr_align.html
-/sdcard/android/layout_tests/tables/mozilla/other/ms.html
-/sdcard/android/layout_tests/tables/mozilla/other/cell_widths.html
-/sdcard/android/layout_tests/tables/mozilla/other/test3.html
-/sdcard/android/layout_tests/tables/mozilla/other/cellspacing.html
-/sdcard/android/layout_tests/tables/mozilla/other/nested2.html
-/sdcard/android/layout_tests/tables/mozilla/other/test6.html
-/sdcard/android/layout_tests/tables/mozilla/other/padding.html
-/sdcard/android/layout_tests/tables/mozilla/other/body_col.html
-/sdcard/android/layout_tests/tables/mozilla/other/wa_table_thtd_rowspan.html
-/sdcard/android/layout_tests/tables/mozilla/other/slashlogo.html
-/sdcard/android/layout_tests/tables/mozilla/images/adforce_imgis_com.html
-/sdcard/android/layout_tests/tables/mozilla/core/col_widths_auto_auto.html
-/sdcard/android/layout_tests/tables/mozilla/core/captions.html
-/sdcard/android/layout_tests/tables/mozilla/core/col_widths_fix_fixPer.html
-/sdcard/android/layout_tests/tables/mozilla/core/col_widths_auto_autoFix.html
-/sdcard/android/layout_tests/tables/mozilla/core/col_widths_auto_autoPer.html
-/sdcard/android/layout_tests/tables/mozilla/core/row_span.html
-/sdcard/android/layout_tests/tables/mozilla/core/cell_heights.html
-/sdcard/android/layout_tests/tables/mozilla/core/misc.html
-/sdcard/android/layout_tests/tables/mozilla/core/col_widths_auto_autoFixPer.html
-/sdcard/android/layout_tests/tables/mozilla/core/col_widths_auto_fix.html
-/sdcard/android/layout_tests/tables/mozilla/core/col_widths_auto_per.html
-/sdcard/android/layout_tests/tables/mozilla/core/col_widths_fix_auto.html
-/sdcard/android/layout_tests/tables/mozilla/core/col_span.html
-/sdcard/android/layout_tests/tables/mozilla/core/margins.html
-/sdcard/android/layout_tests/tables/mozilla/core/borders.html
-/sdcard/android/layout_tests/tables/mozilla/core/table_frame.html
-/sdcard/android/layout_tests/tables/mozilla/core/table_rules.html
-/sdcard/android/layout_tests/tables/mozilla/core/table_heights.html
-/sdcard/android/layout_tests/tables/mozilla/core/nested1.html
-/sdcard/android/layout_tests/tables/mozilla/core/col_widths_fix_autoFix.html
-/sdcard/android/layout_tests/tables/mozilla/core/col_widths_auto_fixPer.html
-/sdcard/android/layout_tests/tables/mozilla/core/col_widths_fix_autoPer.html
-/sdcard/android/layout_tests/tables/mozilla/core/bloomberg.html
-/sdcard/android/layout_tests/tables/mozilla/core/one_row.html
-/sdcard/android/layout_tests/tables/mozilla/core/table_widths.html
-/sdcard/android/layout_tests/tables/mozilla/core/col_widths_fix_autoFixPer.html
-/sdcard/android/layout_tests/tables/mozilla/core/box_sizing.html
-/sdcard/android/layout_tests/tables/mozilla/core/col_widths_fix_fix.html
-/sdcard/android/layout_tests/tables/mozilla/core/col_widths_fix_per.html
-/sdcard/android/layout_tests/tables/mozilla/collapsing_borders/bug41262-3.html
-/sdcard/android/layout_tests/tables/mozilla/collapsing_borders/bug41262-4.html
-/sdcard/android/layout_tests/tables/mozilla/collapsing_borders/bug127040.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_green.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tfoot_valign_top.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_olive.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_teal_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tr_align_center.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_colgroup_width_pct.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_class.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_olive_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_border_0.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/backgr_simple-table-row-group.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_maroon_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tfoot_align_center.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/colgroup_valign_baseline.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/colgroup_align_right.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_col_width_rel.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_lime.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/td_valign_baseline.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_navy.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tr_align_char.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_valign_top.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/backgr_simple-table-column.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tbody_valign_baseline.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_nowrap.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_id.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_style.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_bgcolor_rgb.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_green_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_caption_id.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/thead_align_char.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_thead_class.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_colgroup_span.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_bgcolor_rgb.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/th_valign_bottom.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_silver_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/table_rules_groups.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_col_valign_baseline.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_gray.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_align_center.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tbody_valign_bottom.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tr_bgcolor_rgb.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_cellspacing.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_width_px.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_navy_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_col_align_left.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/td_valign_middle.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tr_valign_middle.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_yellow.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tr_style.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_td_width.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_green.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/backgr_simple-table-cell.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tbody_align_left.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_silver.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/thead_valign_top.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_col_align_center.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_border_px.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_valign_bottom.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_thead_id.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_th_colspan.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_cellspacing_pct.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_td_nowrap.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tfoot_char.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_blue.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_navy.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_style.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tbody_align_center.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_lime_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/thead_align_right.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_aqua_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_colgroup_valign_bottom.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tfoot_align_left.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_rowspan.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_bgcolor_name.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_id.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_col_align_char.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_rowspan.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_navy_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tfoot_valign_middle.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_table.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_thead_valign_baseline.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_red.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_gray.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_align_right.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tfoot_align_justify.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_fuchsia.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_colgroup_align_right.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tfoot_align_right.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_white_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_col_align_justify.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_thead_valign_top.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tbody_align_justify.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tr_class.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_colgroup_align_left.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_maroon_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_rules_none.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/thead_valign_middle.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_caption_align_bot.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_cellpadding_pct.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_yellow_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_col_align_right.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_colspan.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_valign_top.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/thead_align_justify.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/th_valign_baseline.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_colspan.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/colgroup_align_left.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_colgroup_valign_baseline.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_nowrap.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_lime_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_aqua_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_td_align_left.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tfoot_align_char.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_align_justify.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_border_none.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_border_1.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/table_row_align_center.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tbody_align_right.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_th_align_left.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/td_valign_bottom.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_maroon.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/table_frame_border.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_class.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/thead_align_center.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_caption_style.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tfoot_valign_bottom.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_blue.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_col_width_px.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_align_center.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_valign_middle.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_silver_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_style.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_td_align_center.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_colgroup_width_rel.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/backgr_index.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_row_th_nowrap.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_black_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tr_id.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_colgroup_align_char.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tbody_align_left.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_colgroup_valign_middle.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_width.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_thead_align_justify.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tfoot_align_right.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_cellpadding_pct.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_gray_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_olive_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tr_valign_baseline.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_thead_align_right.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tfoot_valign_bottom.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_align_right.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_id.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_valign_baseline.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tbody_align_char.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tr_valign_top.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/body_col.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/backgr_simple-table-row.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_fuchsia.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_cellpadding.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/colgroup_align_center.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_caption_class.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_frame_void.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_td_align_right.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/thead_valign_bottom.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_td_rowspan.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tbody_align_char.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tbody_char.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_class.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_purple.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_rules_groups.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/backgr_simple-table.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tfoot_valign_middle.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_gray_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tfoot_style.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_align_left.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_class.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/colgroup_width_pct.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tbody_valign_top.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/body_tfoot.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/colgroup_span.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_width_pct.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tfoot_valign_baseline.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_yellow_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_align_left.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_height.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_white.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tr_align_justify.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_align_right.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_align_right.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tbody_valign_baseline.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/table_frame_box.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_yellow.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tr_align_right.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tfoot_align_left.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_width_px.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/thead_char.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_col_valign_top.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_col_valign_bottom.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/table_row_align_right.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_border_2.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_aqua.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_fuchsia_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tbody_valign_bottom.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/td_valign_top.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tfoot_id.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tfoot_valign_baseline.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/th_valign_top.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/col_span.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_align_left.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/table_row_align_left.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_purple_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tfoot_class.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_align_char.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_red_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_col_width_pct.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_green_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_valign_top.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_border.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_white_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/colgroup_valign_top.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_fuchsia_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_default.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_caption_align_bottom.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_silver.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_valign_bottom.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_align_center.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_red.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_black.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/table_overflow_td_dynamic_deactivate.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tfoot_valign_top.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_cellpadding.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/colgroup_valign_middle.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_th_align_right.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_th_rowspan.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_cellspacing.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/table_rules_none.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_white.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/colgroup_align_justify.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/table_rules_all.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_thead_valign_bottom.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_thead_align_left.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_blue_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_colgroup_valign_top.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_valign_middle.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_black_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/thead_align_left.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tbody_align_right.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_caption_align_top.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_col_valign_middle.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_align_left.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tbody_id.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_col_span.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_bgcolor_name.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_align_justify.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tbody_valign_middle.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_height.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_thead_align_center.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tbody_style.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_teal.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_td_height.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_olive.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_th_height.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/body_thead.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_colgroup_align_justify.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_maroon.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/backgr_simple-table-column-group.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/table_overflow_hidden_td.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_valign_middle.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_black.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/backgr_layers-opacity.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_style.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_th_align_center.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_thead_align_char.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tr_bgcolor_name.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_red_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_blue_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tbody_valign_top.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_lime.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/th_valign_middle.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_width_percent.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_width.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_teal_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_valign_baseline.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tbody_valign_middle.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/colgroup_width_px.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_valign_baseline.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_align_char.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/backgr_position-table.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tfoot_align_char.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_th_width.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tfoot_align_center.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tbody_align_justify.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_bgcolor_rgb.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_purple_rgb.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tbody_align_center.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/colgroup_valign_bottom.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_td_colspan.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_caption_align_top.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_align_center.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_thead_valign_middle.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_colgroup_align_center.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/thead_valign_baseline.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_thead_style.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tbody_class.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_border_3.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tr_align_left.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tr_valign_bottom.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/body_tbody.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_bgcolor_name.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_teal.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_tfoot_align_justify.xml
-/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_purple.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/tr_valign_bottom.html
-/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_id.xml
-/sdcard/android/layout_tests/transforms/2d/transform-borderbox.html
-/sdcard/android/layout_tests/transforms/2d/zoom-menulist.html
-/sdcard/android/layout_tests/transforms/2d/transform-origin-borderbox.html
-/sdcard/android/layout_tests/transforms/2d/compound-transforms-vs-containers.html
-/sdcard/android/layout_tests/transforms/3d/hit-testing/backface-hit-test.html
-/sdcard/android/layout_tests/transforms/3d/hit-testing/backface-no-transform-hit-test.html
-/sdcard/android/layout_tests/transforms/3d/hit-testing/rotated-hit-test.html
-/sdcard/android/layout_tests/transforms/3d/point-mapping/3d-point-mapping-origins.html
-/sdcard/android/layout_tests/transforms/3d/point-mapping/3d-point-mapping-deep.html
-/sdcard/android/layout_tests/transforms/3d/point-mapping/3d-point-mapping-coplanar.html
-/sdcard/android/layout_tests/transforms/3d/point-mapping/3d-point-mapping-preserve-3d.html
-/sdcard/android/layout_tests/transforms/3d/point-mapping/3d-point-mapping-2.html
-/sdcard/android/layout_tests/transforms/3d/point-mapping/3d-point-mapping-3.html
-/sdcard/android/layout_tests/transforms/3d/point-mapping/3d-point-mapping.html
-/sdcard/android/layout_tests/transforms/3d/point-mapping/3d-point-mapping-overlapping.html
-/sdcard/android/layout_tests/transforms/3d/general/perspective-units.html
-/sdcard/android/layout_tests/transforms/3d/general/perspective-non-layer.html
-/sdcard/android/layout_tests/transforms/no_transform_hit_testing.html
-/sdcard/android/layout_tests/transitions/transition-drt-api.html
-/sdcard/android/layout_tests/webarchive/loading/cache-expired-subresource.html
-/sdcard/android/layout_tests/webarchive/test-css-import.html
-/sdcard/android/layout_tests/webarchive/test-img-src.html
-/sdcard/android/layout_tests/webarchive/test-link-rel-icon.html
-/sdcard/android/layout_tests/webarchive/adopt-attribute-styled-body-webarchive.html
-/sdcard/android/layout_tests/webarchive/archive-empty-frame-dom.html
-/sdcard/android/layout_tests/webarchive/test-frameset.html
-/sdcard/android/layout_tests/webarchive/test-body-background.html
-/sdcard/android/layout_tests/webarchive/test-input-src.html
-/sdcard/android/layout_tests/webarchive/archive-empty-frame-source.html
-/sdcard/android/layout_tests/webarchive/doctype.html
-/sdcard/android/layout_tests/webarchive/test-css-url-resources-inline-styles.html
-/sdcard/android/layout_tests/webarchive/test-table-background.html
-/sdcard/android/layout_tests/webarchive/adopt-inline-styled-node-webarchive.html
-/sdcard/android/layout_tests/webarchive/test-object-data.html
-/sdcard/android/layout_tests/webarchive/test-css-url-resources-in-stylesheets.html
-/sdcard/android/layout_tests/webarchive/archive-with-unencoded-url.html
-/sdcard/android/layout_tests/webarchive/test-link-href.html
-/sdcard/android/layout_tests/webarchive/test-duplicate-resources.html
-/sdcard/android/layout_tests/webarchive/test-xml-stylesheet.xml
-/sdcard/android/layout_tests/webarchive/test-td-background.html
-/sdcard/android/layout_tests/webarchive/test-script-src.html
-/sdcard/android/layout_tests/webarchive/adopt-attribute-styled-node-webarchive.html
diff --git a/tests/DumpRenderTree/assets/results/layout_tests_passed.txt b/tests/DumpRenderTree/assets/results/layout_tests_passed.txt
deleted file mode 100644
index 942b647..0000000
--- a/tests/DumpRenderTree/assets/results/layout_tests_passed.txt
+++ /dev/null
@@ -1,2960 +0,0 @@
-/sdcard/android/layout_tests/accessibility/non-native-image-crash.html
-/sdcard/android/layout_tests/animations/animation-css-rule-types.html
-/sdcard/android/layout_tests/animations/animation-events-create.html
-/sdcard/android/layout_tests/animations/play-state.html
-/sdcard/android/layout_tests/animations/animation-start-event-destroy-renderer.html
-/sdcard/android/layout_tests/animations/combo-transform-translate+scale.html
-/sdcard/android/layout_tests/animations/transform-origin-vs-functions.html
-/sdcard/android/layout_tests/animations/simultaneous-start-transform.html
-/sdcard/android/layout_tests/animations/lineheight-animation.html
-/sdcard/android/layout_tests/animations/import.html
-/sdcard/android/layout_tests/animations/simultaneous-start-left.html
-/sdcard/android/layout_tests/animations/fill-unset-properties.html
-/sdcard/android/layout_tests/animations/multiple-keyframes.html
-/sdcard/android/layout_tests/animations/change-one-anim.html
-/sdcard/android/layout_tests/animations/keyframes-comma-separated.html
-/sdcard/android/layout_tests/animations/matrix-anim.html
-/sdcard/android/layout_tests/animations/keyframes-rule.html
-/sdcard/android/layout_tests/animations/generic-from-to.html
-/sdcard/android/layout_tests/animations/big-rotation.html
-/sdcard/android/layout_tests/animations/keyframe-timing-functions.html
-/sdcard/android/layout_tests/animations/transition-and-animation-1.html
-/sdcard/android/layout_tests/animations/computed-style.html
-/sdcard/android/layout_tests/animations/animation-iteration-event-destroy-renderer.html
-/sdcard/android/layout_tests/animations/keyframes.html
-/sdcard/android/layout_tests/animations/multiple-animations.html
-/sdcard/android/layout_tests/animations/animation-end-event-destroy-renderer.html
-/sdcard/android/layout_tests/animations/transition-and-animation-2.html
-/sdcard/android/layout_tests/animations/import-crash.html
-/sdcard/android/layout_tests/animations/empty-keyframes.html
-/sdcard/android/layout_tests/animations/width-using-ems.html
-/sdcard/android/layout_tests/animations/combo-transform-rotate+scale.html
-/sdcard/android/layout_tests/animations/keyframes-out-of-order.html
-/sdcard/android/layout_tests/css1/units/zero-duration-without-units.html
-/sdcard/android/layout_tests/css2.1/atrule_longest_match.html
-/sdcard/android/layout_tests/css3/khtml-background-size-0x0-bmp.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrlastchild.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_elementnormalize.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_noderemovechildnode.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_elementgetattributenodenull.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_namednodemapreturnfirstitem.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrparentnodenull.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_namednodemapreturnattrnode.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_elementsetattributenodenull.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_elementnormalize2.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_noderemovechild.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeinsertbeforeinvalidnodetype.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodechildnodesappendchild.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrfirstchild.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodevalue05.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatagetlength.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodedocumentnodename.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdataindexsizeerrinsertdataoffsetnegative.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_elementinvalidcharacterexception.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_textsplittexttwo.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrsetvalue1.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeclonegetparentnull.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_documentcreatetextnode.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_documentinvalidcharacterexceptioncreateelement.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodelistreturnlastitem.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrchildnodes1.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdataindexsizeerrdeletedataoffsetnegative.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodetextnodevalue.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_elementretrieveallattributes.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_documentinvalidcharacterexceptioncreateelement1.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_domimplementationfeaturenoversion.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrprevioussiblingnull.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_elementgetelementsbytagnamespecialvalue.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeappendchildnodeancestor.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrappendchild1.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_elementgetelementsbytagnamenomatch.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeappendchildgetnodename.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatadeletedataend.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatareplacedataexceedslengthofarg.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_notationssetnameditem1.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodereplacechildinvalidnodetype.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeinsertbeforenodename.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrinsertbefore7.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodereplacechild.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodegetprevioussiblingnull.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodehaschildnodesfalse.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_namednodemapreturnlastitem.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodegetfirstchildnull.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_notationsremovenameditem1.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeinsertbeforedocfragment.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdataappenddata.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeattributenodevalue.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrspecifiedvalue.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrgetvalue1.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodereplacechildnewchilddiffdocument.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_domimplementationfeaturenull.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdataindexsizeerrreplacedataoffsetnegative.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrinsertbefore1.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeinsertbeforenewchildexists.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodevalue06.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodelistindexnotzero.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_textwithnomarkup.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_entitiessetnameditem1.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrsetvalue2.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_documentgetelementsbytagnametotallength.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_documentinvalidcharacterexceptioncreateattribute1.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodelistindexgetlengthofemptylist.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_elementchangeattributevalue.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeattributenodetype.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodegetnextsiblingnull.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_namednodemapinuseattributeerr.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrchildnodes2.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrcreatetextnode2.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodechildnodesempty.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdataappenddatagetdata.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatareplacedataend.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodegetlastchildnull.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrcreatetextnode.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeclonefalsenocopytext.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeappendchild.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrappendchild2.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdataindexsizeerrreplacedataoffsetgreater.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodetextnodename.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeparentnode.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_namednodemapnotfounderr.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_elementretrieveattrvalue.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodereplacechildoldchildnonexistent.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeinsertbefore.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodehaschildnodes.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodecommentnodename.html
-/sdcard/android/layout_tests/dom/html/level1/core/documentinvalidcharacterexceptioncreateentref1.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrgetvalue2.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_elementretrievetagname.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrspecifiedvaluechanged.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeinsertbeforenewchilddiffdocument.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrinsertbefore2.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdataindexsizeerrreplacedatacountnegative.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatadeletedatabegining.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_documentcreateelement.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdataindexsizeerrinsertdataoffsetgreater.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_textparseintolistofelements.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodevalue07.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodegetownerdocumentnull.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatareplacedatamiddle.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeappendchildinvalidnodetype.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_elementremoveattributenode.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdataindexsizeerrsubstringoffsetgreater.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatadeletedatamiddle.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatasubstringexceedsvalue.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_documentgetrootnode.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatainsertdataend.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodedocumentnodetype.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeclonenodetrue.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_namednodemapchildnoderange.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_namednodemapnumberofnodes.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodevalue01.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_documentgetimplementation.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeappendchildchildexists.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrappendchild3.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_documentgetelementsbytagnamelength.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeelementnodeattributes.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdataindexsizeerrsubstringnegativeoffset.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_noderemovechildgetnodename.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdataindexsizeerrsubstringcountnegative.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_elementnotfounderr.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodedocumentfragmentnodename.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdataindexsizeerrdeletedataoffsetgreater.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatasubstringvalue.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodegetownerdocument.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_elementassociatedattribute.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_elementinvalidcharacterexception1.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_textindexsizeerroffsetoutofbounds.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatadeletedatagetlengthanddata.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodereplacechildnodeancestor.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodevalue08.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_textsplittextthree.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_documentcreateelementcasesensitive.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrinsertbefore3.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodedocumentnodeattribute.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdataindexsizeerrdeletedatacountnegative.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeelementnodevalue.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodereplacechildnewchildexists.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_domimplementationfeaturexml.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_elementreplaceexistingattributegevalue.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeelementnodename.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_elementcreatenewattribute.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodecommentnodevalue.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrnextsiblingnull.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrremovechild1.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_namednodemapwrongdocumenterr.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_namednodemapreturnnull.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodevalue02.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrappendchild4.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_elementinuseattributeerr.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodegetlastchild.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_elementgetattributenode.html
-/sdcard/android/layout_tests/dom/html/level1/core/documentgetdoctypenodtd.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_namednodemapsetnameditemreturnvalue.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatareplacedataexceedslengthofdata.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodetextnodetype.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeattributenodeattribute.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_documentgetdoctype.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_namednodemapsetnameditemthatexists.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_documentcreatedocumentfragment.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_commentgetcomment.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attreffectivevalue.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_textsplittextfour.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeinsertbeforenodeancestor.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrinsertbefore4.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_textindexsizeerrnegativeoffset.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodecommentnodetype.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodetextnodeattribute.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodedocumentnodevalue.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatadeletedataexceedslength.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_textsplittextone.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodedocumentfragmentnodevalue.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatagetdata.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatainsertdatabeginning.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodegetnextsibling.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodelistreturnfirstitem.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrremovechild2.html
-/sdcard/android/layout_tests/dom/html/level1/core/documentinvalidcharacterexceptioncreatepi.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodevalue03.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrappendchild5.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrhaschildnodes.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrreplacechild1.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrnormalize.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodedocumentfragmentnodetype.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_elementreplaceexistingattribute.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeappendchildnewchilddiffdocument.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodelisttraverselist.html
-/sdcard/android/layout_tests/dom/html/level1/core/documentinvalidcharacterexceptioncreateentref.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatasetnodevalue.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_entitiesremovenameditem1.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrinsertbefore5.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_elementgetelementsbytagname.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrcreatedocumentfragment.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrclonenode1.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_namednodemapremovenameditem.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_elementaddnewattribute.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodelistindexequalzero.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodechildnodes.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_elementgetelementempty.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatainsertdatamiddle.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_documentcreatecomment.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodegetprevioussibling.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeinsertbeforerefchildnonexistent.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_elementremoveattributeaftercreate.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_noderemovechildoldchildnonexistent.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_elementwrongdocumenterr.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatareplacedatabegining.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeattributenodename.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodecommentnodeattributes.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodevalue04.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_documentinvalidcharacterexceptioncreateattribute.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_elementremoveattribute.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrappendchild6.html
-/sdcard/android/layout_tests/dom/html/level1/core/documentinvalidcharacterexceptioncreatepi1.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeelementnodetype.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrname.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_namednodemapgetnameditem.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_elementgettagname.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_namednodemapsetnameditem.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeinsertbeforerefchildnull.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrreplacechild2.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeparentnodenull.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodecloneattributescopied.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeclonenodefalse.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodereplacechildnodename.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_elementgetelementsbytagnameaccessnodelist.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeclonetruecopytext.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_attrinsertbefore6.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodelistindexgetlength.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_elementreplaceattributewithself.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_documentcreateattribute.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeappendchilddocfragment.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_namednodemapsetnameditemwithnewvalue.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_documentgetelementsbytagnamevalue.html
-/sdcard/android/layout_tests/dom/html/level1/core/hc_nodegetfirstchild.html
-/sdcard/android/layout_tests/dom/html/level2/events/EventTargetCast01.html
-/sdcard/android/layout_tests/dom/html/level2/events/dispatchEvent12.html
-/sdcard/android/layout_tests/dom/html/level2/events/dispatchEvent04.html
-/sdcard/android/layout_tests/dom/html/level2/events/createEvent02.html
-/sdcard/android/layout_tests/dom/html/level2/events/dispatchEvent08.html
-/sdcard/android/layout_tests/dom/html/level2/events/initEvent04.html
-/sdcard/android/layout_tests/dom/html/level2/events/DocumentEventCast01.html
-/sdcard/android/layout_tests/dom/html/level2/events/dispatchEvent01.html
-/sdcard/android/layout_tests/dom/html/level2/events/dispatchEvent13.html
-/sdcard/android/layout_tests/dom/html/level2/events/dispatchEvent05.html
-/sdcard/android/layout_tests/dom/html/level2/events/initEvent01.html
-/sdcard/android/layout_tests/dom/html/level2/events/createEvent03.html
-/sdcard/android/layout_tests/dom/html/level2/events/initEvent05.html
-/sdcard/android/layout_tests/dom/html/level2/events/dispatchEvent09.html
-/sdcard/android/layout_tests/dom/html/level2/events/dispatchEvent10.html
-/sdcard/android/layout_tests/dom/html/level2/events/dispatchEvent02.html
-/sdcard/android/layout_tests/dom/html/level2/events/initEvent02.html
-/sdcard/android/layout_tests/dom/html/level2/events/dispatchEvent06.html
-/sdcard/android/layout_tests/dom/html/level2/events/createEvent04.html
-/sdcard/android/layout_tests/dom/html/level2/events/initEvent06.html
-/sdcard/android/layout_tests/dom/html/level2/events/dispatchEvent11.html
-/sdcard/android/layout_tests/dom/html/level2/events/dispatchEvent03.html
-/sdcard/android/layout_tests/dom/html/level2/events/createEvent01.html
-/sdcard/android/layout_tests/dom/html/level2/events/dispatchEvent07.html
-/sdcard/android/layout_tests/dom/html/level2/events/initEvent03.html
-/sdcard/android/layout_tests/dom/html/level2/events/createEvent05.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement06.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableColElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement87.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement08.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement04.html
-/sdcard/android/layout_tests/dom/html/level2/html/hasFeature04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement26.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement141.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLButtonElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement37.html
-/sdcard/android/layout_tests/dom/html/level2/html/table12.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLIsIndexElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLFrameSetElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLModElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement27.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement90.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement11.html
-/sdcard/android/layout_tests/dom/html/level2/html/table45.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement14.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTextAreaElement04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement08.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionsCollection01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement09.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLFrameElement08.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement124.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement40.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLParamElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLFormElement06.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAreaElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement08.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement30.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptGroupElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement73.html
-/sdcard/android/layout_tests/dom/html/level2/html/table28.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLIFrameElement08.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAnchorElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/anchor02.html
-/sdcard/android/layout_tests/dom/html/level2/html/object09.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement11.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement12.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement27.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement107.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionElement07.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement23.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLMetaElement04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLBodyElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement11.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument25.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement13.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement56.html
-/sdcard/android/layout_tests/dom/html/level2/html/table31.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLIFrameElement11.html
-/sdcard/android/layout_tests/dom/html/level2/html/object12.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement08.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement30.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableColElement05.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement89.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement110.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLLabelElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement06.html
-/sdcard/android/layout_tests/dom/html/level2/html/hasFeature06.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement28.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement143.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLBaseElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument08.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLButtonElement04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement39.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLIsIndexElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement11.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLModElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLCollection01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLImageElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement29.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement92.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement13.html
-/sdcard/android/layout_tests/dom/html/level2/html/table47.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement16.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTextAreaElement06.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAppletElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionsCollection03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument11.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement126.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement42.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLParamElement04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLFormElement08.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAreaElement05.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement75.html
-/sdcard/android/layout_tests/dom/html/level2/html/table50.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAnchorElement04.html
-/sdcard/android/layout_tests/dom/html/level2/html/anchor04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement13.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement14.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement29.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLScriptElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement109.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionElement09.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement25.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLBodyElement05.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement13.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument27.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement15.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement58.html
-/sdcard/android/layout_tests/dom/html/level2/html/table33.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLHeadingElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/area01.html
-/sdcard/android/layout_tests/dom/html/level2/html/object14.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableColElement07.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement32.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement112.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLLabelElement04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLDivElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement08.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLUListElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement145.html
-/sdcard/android/layout_tests/dom/html/level2/html/button01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLButtonElement06.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement61.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLLegendElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCaptionElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement13.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLCollection03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLImageElement04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableColElement10.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement94.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement15.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLFieldSetElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/table49.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLLIElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement18.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement11.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTextAreaElement08.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAppletElement04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionsCollection05.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument13.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement128.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLMapElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement44.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAreaElement07.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement77.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLLinkElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/table52.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement21.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTextAreaElement11.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAnchorElement06.html
-/sdcard/android/layout_tests/dom/html/level2/html/anchor06.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement15.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement16.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement131.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLParagraphElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLScriptElement04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement27.html
-/sdcard/android/layout_tests/dom/html/level2/html/table02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLBodyElement07.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement15.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement17.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement80.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/table35.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLHeadingElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement04.html
-/sdcard/android/layout_tests/dom/html/level2/html/area03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableColElement09.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement34.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement114.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement30.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLBodyElement10.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLStyleElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement20.html
-/sdcard/android/layout_tests/dom/html/level2/html/button03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLButtonElement08.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement63.html
-/sdcard/android/layout_tests/dom/html/level2/html/table18.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLLegendElement04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement15.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLCollection05.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableColElement12.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLImageElement06.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLFrameElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement96.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement17.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement13.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAppletElement06.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionsCollection07.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument15.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement46.html
-/sdcard/android/layout_tests/dom/html/level2/html/table21.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLIFrameElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/object02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement20.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLQuoteElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement79.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLLinkElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement100.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTextAreaElement13.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAnchorElement08.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement17.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement18.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement133.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLScriptElement06.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement29.html
-/sdcard/android/layout_tests/dom/html/level2/html/table04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLBodyElement09.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement17.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement19.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement82.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/table37.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLHeadingElement05.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement06.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAnchorElement11.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement20.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement21.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement36.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement116.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement32.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLBodyElement12.html
-/sdcard/android/layout_tests/dom/html/level2/html/basefont01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLStyleElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement20.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement22.html
-/sdcard/android/layout_tests/dom/html/level2/html/button05.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement65.html
-/sdcard/android/layout_tests/dom/html/level2/html/table40.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement17.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLCollection07.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLImageElement08.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLFrameElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement98.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement19.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement15.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAppletElement08.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLFormElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument17.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement05.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement48.html
-/sdcard/android/layout_tests/dom/html/level2/html/table23.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLIFrameElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/object04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement20.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLCollection10.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLImageElement11.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLPreElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement22.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLOListElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLLinkElement05.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement102.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTextAreaElement15.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAppletElement11.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement19.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument20.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement135.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement51.html
-/sdcard/android/layout_tests/dom/html/level2/html/table06.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLHeadElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement19.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement84.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement05.html
-/sdcard/android/layout_tests/dom/html/level2/html/table39.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement08.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAnchorElement13.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/hasFeature01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement23.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement38.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement118.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement34.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLBaseFontElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement24.html
-/sdcard/android/layout_tests/dom/html/level2/html/button07.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement67.html
-/sdcard/android/layout_tests/dom/html/level2/html/table42.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement11.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTextAreaElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement05.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement19.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLCollection09.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement06.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLFrameElement05.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement121.html
-/sdcard/android/layout_tests/dom/html/level2/html/dlist01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement17.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLFormElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement05.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument19.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement07.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement70.html
-/sdcard/android/layout_tests/dom/html/level2/html/table25.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLMenuElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLFontElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLIFrameElement05.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLCollection12.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement24.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLLinkElement07.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement104.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionElement04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement20.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLMetaElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument22.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement137.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLHRElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement10.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement53.html
-/sdcard/android/layout_tests/dom/html/level2/html/table08.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement05.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableColElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement86.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement07.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/hasFeature03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement25.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement140.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument05.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLButtonElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement36.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLBaseFontElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLFrameSetElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement26.html
-/sdcard/android/layout_tests/dom/html/level2/html/button09.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement10.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement69.html
-/sdcard/android/layout_tests/dom/html/level2/html/table44.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement13.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTextAreaElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement07.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement08.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLFrameElement07.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement123.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement19.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLParamElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLFormElement05.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAreaElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement07.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement09.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement72.html
-/sdcard/android/layout_tests/dom/html/level2/html/table27.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLIFrameElement07.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAnchorElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/anchor01.html
-/sdcard/android/layout_tests/dom/html/level2/html/object08.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement10.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement11.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement26.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement106.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLLinkElement09.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionElement06.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement22.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLMetaElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLBodyElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/body01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement10.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument24.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement139.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLHRElement04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement12.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement55.html
-/sdcard/android/layout_tests/dom/html/level2/html/table30.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLIFrameElement10.html
-/sdcard/android/layout_tests/dom/html/level2/html/object11.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement07.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableColElement04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement88.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement09.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLHtmlElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLLabelElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTitleElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement05.html
-/sdcard/android/layout_tests/dom/html/level2/html/hasFeature05.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement27.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement142.html
-/sdcard/android/layout_tests/dom/html/level2/html/doc01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument07.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLBaseElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLButtonElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/AppletsCollection.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement38.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLIsIndexElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement10.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLModElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLImageElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement28.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement91.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement12.html
-/sdcard/android/layout_tests/dom/html/level2/html/table46.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement15.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTextAreaElement05.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAppletElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement09.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement30.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionsCollection02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLFrameElement09.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument10.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement125.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement41.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLParamElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLFormElement07.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAreaElement04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement09.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement31.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptGroupElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement74.html
-/sdcard/android/layout_tests/dom/html/level2/html/table29.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLIFrameElement09.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAnchorElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/anchor03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement12.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement13.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement28.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLScriptElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement108.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionElement08.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement24.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLBodyElement04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLFormElement10.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement12.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument26.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement14.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement57.html
-/sdcard/android/layout_tests/dom/html/level2/html/table32.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/object13.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement09.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableColElement06.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement31.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement111.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLLabelElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement07.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement29.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement144.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument09.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLButtonElement05.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement60.html
-/sdcard/android/layout_tests/dom/html/level2/html/table15.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLLegendElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement12.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLCollection02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLModElement04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLImageElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement93.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement14.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLFieldSetElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/table48.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLLIElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement17.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement10.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTextAreaElement07.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAppletElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionsCollection04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument12.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement127.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement43.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLFormElement09.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAreaElement06.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement76.html
-/sdcard/android/layout_tests/dom/html/level2/html/table51.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement20.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTextAreaElement10.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAnchorElement05.html
-/sdcard/android/layout_tests/dom/html/level2/html/anchor05.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement14.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement15.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement130.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLScriptElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement26.html
-/sdcard/android/layout_tests/dom/html/level2/html/table01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLBodyElement06.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement14.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement16.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement59.html
-/sdcard/android/layout_tests/dom/html/level2/html/table34.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLHeadingElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/area02.html
-/sdcard/android/layout_tests/dom/html/level2/html/object15.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableColElement08.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement33.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement113.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement09.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLUListElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLBRElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/button02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLButtonElement07.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement62.html
-/sdcard/android/layout_tests/dom/html/level2/html/table17.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLLegendElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement14.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLCollection04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLImageElement05.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableColElement11.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement95.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement16.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement19.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement12.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTextAreaElement09.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAppletElement05.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionsCollection06.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument14.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement129.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLMapElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement45.html
-/sdcard/android/layout_tests/dom/html/level2/html/table20.html
-/sdcard/android/layout_tests/dom/html/level2/html/object01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAreaElement08.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement78.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLLinkElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/table53.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement22.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTextAreaElement12.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAnchorElement07.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement16.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement17.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement132.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLScriptElement05.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement28.html
-/sdcard/android/layout_tests/dom/html/level2/html/table03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLBodyElement08.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement16.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement18.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement81.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/table36.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLHeadingElement04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement05.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAnchorElement10.html
-/sdcard/android/layout_tests/dom/html/level2/html/area04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement20.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement35.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement115.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLDlistElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement31.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLBodyElement11.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLStyleElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement21.html
-/sdcard/android/layout_tests/dom/html/level2/html/button04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement64.html
-/sdcard/android/layout_tests/dom/html/level2/html/table19.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement16.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLCollection06.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLImageElement07.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLFrameElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement97.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement18.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement14.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAppletElement07.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument16.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement47.html
-/sdcard/android/layout_tests/dom/html/level2/html/table22.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLIFrameElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/object03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLImageElement10.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement21.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLOListElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLQuoteElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement101.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLLinkElement04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTextAreaElement14.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAnchorElement09.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAppletElement10.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement18.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement19.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement134.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLScriptElement07.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement50.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement18.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement83.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement04.html
-/sdcard/android/layout_tests/dom/html/level2/html/table38.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLHeadingElement06.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement07.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAnchorElement12.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement21.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement22.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement37.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement117.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement33.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLDirectoryElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement23.html
-/sdcard/android/layout_tests/dom/html/level2/html/button06.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement66.html
-/sdcard/android/layout_tests/dom/html/level2/html/table41.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement10.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement18.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLCollection08.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLImageElement09.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement40.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement05.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLFrameElement04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement99.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement120.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement16.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAppletElement09.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLFormElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument18.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement06.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement49.html
-/sdcard/android/layout_tests/dom/html/level2/html/table24.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLIFrameElement04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLFontElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/object05.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLCollection11.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLImageElement12.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement23.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLOListElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement103.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLLinkElement06.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument21.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement136.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLHRElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement52.html
-/sdcard/android/layout_tests/dom/html/level2/html/table07.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableColElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement85.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement06.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement09.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAnchorElement14.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/hasFeature02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement24.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement39.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement119.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement35.html
-/sdcard/android/layout_tests/dom/html/level2/html/table10.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLBaseFontElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement25.html
-/sdcard/android/layout_tests/dom/html/level2/html/button08.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement68.html
-/sdcard/android/layout_tests/dom/html/level2/html/table43.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement12.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTextAreaElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement06.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement07.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLFrameElement06.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement122.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement18.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLFormElement04.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLAreaElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement06.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement08.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement71.html
-/sdcard/android/layout_tests/dom/html/level2/html/table26.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLIFrameElement06.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLFontElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/object07.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement10.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement25.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement105.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLLinkElement08.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionElement05.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement21.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLMetaElement02.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLBodyElement01.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument23.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement138.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLHRElement03.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement11.html
-/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement54.html
-/sdcard/android/layout_tests/dom/html/level2/html/table09.html
-/sdcard/android/layout_tests/dom/html/level2/html/object10.html
-/sdcard/android/layout_tests/dom/html/level2/core/hc_notationsremovenameditemns1.html
-/sdcard/android/layout_tests/dom/html/level2/core/hc_entitiessetnameditemns1.html
-/sdcard/android/layout_tests/dom/html/level2/core/setAttributeNS10.html
-/sdcard/android/layout_tests/dom/html/level2/core/hc_nodedocumentfragmentnormalize2.html
-/sdcard/android/layout_tests/dom/html/level2/core/hc_namednodemapinvalidtype1.html
-/sdcard/android/layout_tests/dom/html/level2/core/createAttributeNS06.html
-/sdcard/android/layout_tests/dom/html/level2/core/createDocumentType04.html
-/sdcard/android/layout_tests/dom/html/level2/core/hc_notationssetnameditemns1.html
-/sdcard/android/layout_tests/dom/html/level2/core/hc_entitiesremovenameditemns1.html
-/sdcard/android/layout_tests/dom/html/level2/core/hc_nodedocumentfragmentnormalize1.html
-/sdcard/android/layout_tests/dom/html/level2/core/createDocument08.html
-/sdcard/android/layout_tests/editing/style/temporary-span-crash.html
-/sdcard/android/layout_tests/editing/style/4230923.html
-/sdcard/android/layout_tests/editing/style/textdecoration-outside-of-unsplittable-element.html
-/sdcard/android/layout_tests/editing/style/textdecoration-outside-of-rooteditable.html
-/sdcard/android/layout_tests/editing/style/highlight-insert-paragraph.html
-/sdcard/android/layout_tests/editing/inserting/6609479-1.html
-/sdcard/android/layout_tests/editing/inserting/6609479.html
-/sdcard/android/layout_tests/editing/inserting/5549929-1.html
-/sdcard/android/layout_tests/editing/inserting/font-size-clears-from-typing-style.html
-/sdcard/android/layout_tests/editing/inserting/6104369.html
-/sdcard/android/layout_tests/editing/inserting/return-with-object-element.html
-/sdcard/android/layout_tests/editing/inserting/5803706-2.html
-/sdcard/android/layout_tests/editing/inserting/5685601-2.html
-/sdcard/android/layout_tests/editing/inserting/5607069-1.html
-/sdcard/android/layout_tests/editing/inserting/insert-br-quoted-007.html
-/sdcard/android/layout_tests/editing/inserting/5803706-1.html
-/sdcard/android/layout_tests/editing/inserting/5685601-1.html
-/sdcard/android/layout_tests/editing/inserting/5994480.html
-/sdcard/android/layout_tests/editing/inserting/6104369-2.html
-/sdcard/android/layout_tests/editing/inserting/insert-before-link-1.html
-/sdcard/android/layout_tests/editing/inserting/5378847.html
-/sdcard/android/layout_tests/editing/inserting/5685601-3.html
-/sdcard/android/layout_tests/editing/inserting/6703873-2.html
-/sdcard/android/layout_tests/editing/execCommand/toggle-style-2.html
-/sdcard/android/layout_tests/editing/execCommand/19403.html
-/sdcard/android/layout_tests/editing/execCommand/indent-nested-div.html
-/sdcard/android/layout_tests/editing/execCommand/25256.html
-/sdcard/android/layout_tests/editing/execCommand/default-parameters.html
-/sdcard/android/layout_tests/editing/execCommand/5120591.html
-/sdcard/android/layout_tests/editing/execCommand/19455.html
-/sdcard/android/layout_tests/editing/execCommand/19087.html
-/sdcard/android/layout_tests/editing/execCommand/5543472-3.html
-/sdcard/android/layout_tests/editing/execCommand/5207369.html
-/sdcard/android/layout_tests/editing/execCommand/empty-span-removal.html
-/sdcard/android/layout_tests/editing/execCommand/4916583.html
-/sdcard/android/layout_tests/editing/execCommand/5658933-2.html
-/sdcard/android/layout_tests/editing/execCommand/5469868.html
-/sdcard/android/layout_tests/editing/execCommand/insert-list-with-id.html
-/sdcard/android/layout_tests/editing/execCommand/indent-div-inside-list.html
-/sdcard/android/layout_tests/editing/execCommand/5575101-1.html
-/sdcard/android/layout_tests/editing/execCommand/5432254-1.html
-/sdcard/android/layout_tests/editing/execCommand/indent-nested-blockquotes.html
-/sdcard/android/layout_tests/editing/execCommand/5062376.html
-/sdcard/android/layout_tests/editing/execCommand/indent-second-paragraph-in-blockquote.html
-/sdcard/android/layout_tests/editing/execCommand/findString-3.html
-/sdcard/android/layout_tests/editing/execCommand/toggle-text-decorations.html
-/sdcard/android/layout_tests/editing/execCommand/5142012-3.html
-/sdcard/android/layout_tests/editing/execCommand/indent-empty-table-cell.html
-/sdcard/android/layout_tests/editing/execCommand/5700414-1.html
-/sdcard/android/layout_tests/editing/execCommand/16049.html
-/sdcard/android/layout_tests/editing/execCommand/19653-1.html
-/sdcard/android/layout_tests/editing/execCommand/arguments-combinations.html
-/sdcard/android/layout_tests/editing/execCommand/5685604-1.html
-/sdcard/android/layout_tests/editing/execCommand/4128080-1.html
-/sdcard/android/layout_tests/editing/execCommand/5575101-3.html
-/sdcard/android/layout_tests/editing/execCommand/5119244.html
-/sdcard/android/layout_tests/editing/execCommand/5543472-2.html
-/sdcard/android/layout_tests/editing/execCommand/inline-style-after-indentoutdent.html
-/sdcard/android/layout_tests/editing/execCommand/5770834-1.html
-/sdcard/android/layout_tests/editing/execCommand/5483526.html
-/sdcard/android/layout_tests/editing/execCommand/5658933-1.html
-/sdcard/android/layout_tests/editing/execCommand/5164796.html
-/sdcard/android/layout_tests/editing/execCommand/6355786.html
-/sdcard/android/layout_tests/editing/execCommand/5604313.html
-/sdcard/android/layout_tests/editing/execCommand/19653-3.html
-/sdcard/android/layout_tests/editing/execCommand/outdent-regular-blockquote.html
-/sdcard/android/layout_tests/editing/execCommand/6444148.html
-/sdcard/android/layout_tests/editing/execCommand/5763082.html
-/sdcard/android/layout_tests/editing/execCommand/4976800.html
-/sdcard/android/layout_tests/editing/execCommand/4928635.html
-/sdcard/android/layout_tests/editing/execCommand/list-wrapping-image-crash.html
-/sdcard/android/layout_tests/editing/execCommand/4920742-2.html
-/sdcard/android/layout_tests/editing/execCommand/4917055.html
-/sdcard/android/layout_tests/editing/execCommand/5658933-3.html
-/sdcard/android/layout_tests/editing/execCommand/5575101-2.html
-/sdcard/android/layout_tests/editing/execCommand/5432254-2.html
-/sdcard/android/layout_tests/editing/execCommand/5144139-1.html
-/sdcard/android/layout_tests/editing/execCommand/5543472-1.html
-/sdcard/android/layout_tests/editing/execCommand/25320.html
-/sdcard/android/layout_tests/editing/execCommand/5210032.html
-/sdcard/android/layout_tests/editing/execCommand/12244.html
-/sdcard/android/layout_tests/editing/execCommand/15381.html
-/sdcard/android/layout_tests/editing/execCommand/5700414-2.html
-/sdcard/android/layout_tests/editing/execCommand/19653-2.html
-/sdcard/android/layout_tests/editing/execCommand/boldSelection.html
-/sdcard/android/layout_tests/editing/execCommand/4916235.html
-/sdcard/android/layout_tests/editing/execCommand/5458246.html
-/sdcard/android/layout_tests/editing/execCommand/toggle-styles.html
-/sdcard/android/layout_tests/editing/pasteboard/5761530-2.html
-/sdcard/android/layout_tests/editing/pasteboard/6018653.html
-/sdcard/android/layout_tests/editing/pasteboard/4930986-1.html
-/sdcard/android/layout_tests/editing/pasteboard/5780697-1.html
-/sdcard/android/layout_tests/editing/pasteboard/copy-crash-with-extraneous-attribute.html
-/sdcard/android/layout_tests/editing/pasteboard/4930986-3.html
-/sdcard/android/layout_tests/editing/pasteboard/5245519.html
-/sdcard/android/layout_tests/editing/pasteboard/copy-display-none.html
-/sdcard/android/layout_tests/editing/pasteboard/5521237.html
-/sdcard/android/layout_tests/editing/pasteboard/newlines-around-floating-or-positioned.html
-/sdcard/android/layout_tests/editing/pasteboard/5078739.html
-/sdcard/android/layout_tests/editing/pasteboard/createMarkup-assert.xml
-/sdcard/android/layout_tests/editing/pasteboard/4930986-2.html
-/sdcard/android/layout_tests/editing/pasteboard/4840662.html
-/sdcard/android/layout_tests/editing/pasteboard/5480736.html
-/sdcard/android/layout_tests/editing/selection/5825350-1.html
-/sdcard/android/layout_tests/editing/selection/selection-invalid-offset.html
-/sdcard/android/layout_tests/editing/selection/move-by-line-005.html
-/sdcard/android/layout_tests/editing/selection/rangeCount.html
-/sdcard/android/layout_tests/editing/selection/containsNode.html
-/sdcard/android/layout_tests/editing/selection/selectAllChildren.html
-/sdcard/android/layout_tests/editing/selection/cleared-by-relayout.html
-/sdcard/android/layout_tests/editing/selection/extend-selection.html
-/sdcard/android/layout_tests/editing/selection/5825350-2.html
-/sdcard/android/layout_tests/editing/selection/5794920-1.html
-/sdcard/android/layout_tests/editing/selection/deleteFromDocument.html
-/sdcard/android/layout_tests/editing/selection/5497643.html
-/sdcard/android/layout_tests/editing/selection/setBaseAndExtent-revert-selection.html
-/sdcard/android/layout_tests/editing/selection/crash-on-drag-with-mutation-events.html
-/sdcard/android/layout_tests/editing/selection/5714333.html
-/sdcard/android/layout_tests/editing/selection/select-all-user-select-none.html
-/sdcard/android/layout_tests/editing/selection/thai-word-at-document-end.html
-/sdcard/android/layout_tests/editing/selection/extend.html
-/sdcard/android/layout_tests/editing/selection/5241148.html
-/sdcard/android/layout_tests/editing/selection/5213963.html
-/sdcard/android/layout_tests/editing/selection/move-by-line-004.html
-/sdcard/android/layout_tests/editing/selection/extend-by-line-anonymous-content-crash.html
-/sdcard/android/layout_tests/editing/selection/5779984-1.html
-/sdcard/android/layout_tests/editing/undo/4059423-1.html
-/sdcard/android/layout_tests/editing/undo/4059423-2.html
-/sdcard/android/layout_tests/editing/undo/5658727.html
-/sdcard/android/layout_tests/editing/undo/5738768.html
-/sdcard/android/layout_tests/editing/deleting/25322-2.html
-/sdcard/android/layout_tests/editing/deleting/2610675-2.html
-/sdcard/android/layout_tests/editing/deleting/5847330-2.html
-/sdcard/android/layout_tests/editing/deleting/5156801.html
-/sdcard/android/layout_tests/editing/deleting/4866671.html
-/sdcard/android/layout_tests/editing/deleting/type-delete-after-quote-2.html
-/sdcard/android/layout_tests/editing/deleting/25322-1.html
-/sdcard/android/layout_tests/editing/deleting/merge-at-end-of-document.html
-/sdcard/android/layout_tests/editing/deleting/6026335.html
-/sdcard/android/layout_tests/editing/deleting/2610675-1.html
-/sdcard/android/layout_tests/editing/deleting/5847330-1.html
-/sdcard/android/layout_tests/editing/deleting/5433862-1.html
-/sdcard/android/layout_tests/editing/deleting/5495723.html
-/sdcard/android/layout_tests/editing/deleting/5290534.html
-/sdcard/android/layout_tests/editing/deleting/removeNodeCommand-assert.html
-/sdcard/android/layout_tests/editing/deleting/25322-3.html
-/sdcard/android/layout_tests/editing/deleting/2610675-3.html
-/sdcard/android/layout_tests/editing/deleting/5890684.html
-/sdcard/android/layout_tests/editing/deleting/in-visibly-empty-root.html
-/sdcard/android/layout_tests/editing/deleting/4875189.html
-/sdcard/android/layout_tests/fast/media/matchmedium-query-api.html
-/sdcard/android/layout_tests/fast/replaced/object-param-no-name.html
-/sdcard/android/layout_tests/fast/ruby/parse-rp.html
-/sdcard/android/layout_tests/fast/dynamic/subtree-common-root.html
-/sdcard/android/layout_tests/fast/dynamic/hovered-detach.html
-/sdcard/android/layout_tests/fast/dynamic/insertAdjacentHTML.html
-/sdcard/android/layout_tests/fast/dynamic/style-access-late-stylesheet-load.html
-/sdcard/android/layout_tests/fast/dynamic/insertAdjacentText.html
-/sdcard/android/layout_tests/fast/dynamic/insertAdjacentHTML-allowed-parents.html
-/sdcard/android/layout_tests/fast/dynamic/checkbox-selection-crash.html
-/sdcard/android/layout_tests/fast/dynamic/outerHTML-no-element.html
-/sdcard/android/layout_tests/fast/dynamic/5872671.html
-/sdcard/android/layout_tests/fast/dynamic/ancestor-to-absolute.html
-/sdcard/android/layout_tests/fast/dynamic/float-remove-above-line.html
-/sdcard/android/layout_tests/fast/dynamic/recursive-layout.html
-/sdcard/android/layout_tests/fast/dynamic/inline-to-block-crash.html
-/sdcard/android/layout_tests/fast/text/whitespace/nowrap-line-break-after-white-space.html
-/sdcard/android/layout_tests/fast/text/find-backwards.html
-/sdcard/android/layout_tests/fast/text/large-text-composed-char-dos.html
-/sdcard/android/layout_tests/fast/text/find-quotes.html
-/sdcard/android/layout_tests/fast/text/find-case-folding.html
-/sdcard/android/layout_tests/fast/text/text-shadow-extreme-value.html
-/sdcard/android/layout_tests/fast/text/find-hidden-text.html
-/sdcard/android/layout_tests/fast/text/line-breaks-after-ideographic-comma-or-full-stop.html
-/sdcard/android/layout_tests/fast/text/find-spaces.html
-/sdcard/android/layout_tests/fast/text/text-large-negative-letter-spacing-with-opacity.html
-/sdcard/android/layout_tests/fast/encoding/gbk/chinese.html
-/sdcard/android/layout_tests/fast/encoding/gbk/x-euc-cn.html
-/sdcard/android/layout_tests/fast/encoding/gbk/gb_2312-80.html
-/sdcard/android/layout_tests/fast/encoding/gbk/cn-gb.html
-/sdcard/android/layout_tests/fast/encoding/gbk/csgb2312.html
-/sdcard/android/layout_tests/fast/encoding/gbk/iso-ir-58.html
-/sdcard/android/layout_tests/fast/encoding/gbk/csgb231280.html
-/sdcard/android/layout_tests/fast/encoding/gbk/gb2312.html
-/sdcard/android/layout_tests/fast/encoding/gbk/gbk.html
-/sdcard/android/layout_tests/fast/encoding/gbk/x-gbk.html
-/sdcard/android/layout_tests/fast/encoding/gbk/EUC-CN.html
-/sdcard/android/layout_tests/fast/encoding/gbk/close-gbk-converter.html
-/sdcard/android/layout_tests/fast/encoding/hebrew/hebrew.html
-/sdcard/android/layout_tests/fast/encoding/hebrew/csISO88598I.html
-/sdcard/android/layout_tests/fast/encoding/hebrew/8859-8.html
-/sdcard/android/layout_tests/fast/encoding/hebrew/8859-8-e.html
-/sdcard/android/layout_tests/fast/encoding/hebrew/8859-8-i.html
-/sdcard/android/layout_tests/fast/encoding/hebrew/logical.html
-/sdcard/android/layout_tests/fast/encoding/hebrew/iso-ir-138.html
-/sdcard/android/layout_tests/fast/encoding/pseudo-xml-4.html
-/sdcard/android/layout_tests/fast/encoding/no-charset-on-dynamic-script-load.html
-/sdcard/android/layout_tests/fast/encoding/utf-32-little-endian-bom.html
-/sdcard/android/layout_tests/fast/encoding/bandai-co-jp-releases.html
-/sdcard/android/layout_tests/fast/encoding/utf-32-big-endian-bom.html
-/sdcard/android/layout_tests/fast/encoding/css-charset-evil.html
-/sdcard/android/layout_tests/fast/encoding/css-charset.html
-/sdcard/android/layout_tests/fast/encoding/xml-charset-utf16.html
-/sdcard/android/layout_tests/fast/encoding/pseudo-xml-3.html
-/sdcard/android/layout_tests/fast/encoding/tag-in-title.html
-/sdcard/android/layout_tests/fast/encoding/noscript-in-head.html
-/sdcard/android/layout_tests/fast/encoding/css-cached-bom.html
-/sdcard/android/layout_tests/fast/encoding/preload-encoding.html
-/sdcard/android/layout_tests/fast/encoding/charset-invalid.html
-/sdcard/android/layout_tests/fast/encoding/pseudo-tags-in-attributes.html
-/sdcard/android/layout_tests/fast/encoding/decoder-allow-null-chars.html
-/sdcard/android/layout_tests/fast/encoding/css-charset-dom.html
-/sdcard/android/layout_tests/fast/encoding/charset-utf16.html
-/sdcard/android/layout_tests/fast/encoding/char-encoding.html
-/sdcard/android/layout_tests/fast/encoding/css-link-charset.html
-/sdcard/android/layout_tests/fast/encoding/latin1-winlatin.html
-/sdcard/android/layout_tests/fast/encoding/high-bit-latin1.html
-/sdcard/android/layout_tests/fast/encoding/bom-in-content.html
-/sdcard/android/layout_tests/fast/encoding/bom-in-content-utf16.html
-/sdcard/android/layout_tests/fast/encoding/namespace-tolerance.html
-/sdcard/android/layout_tests/fast/encoding/misplaced-xml-declaration.html
-/sdcard/android/layout_tests/fast/encoding/euckr-name.html
-/sdcard/android/layout_tests/fast/encoding/charset-xuser-defined.html
-/sdcard/android/layout_tests/fast/encoding/pseudo-xml-2.html
-/sdcard/android/layout_tests/fast/encoding/floraexpress-ru.html
-/sdcard/android/layout_tests/fast/encoding/charset-cp1251.html
-/sdcard/android/layout_tests/fast/encoding/charset-unicode.html
-/sdcard/android/layout_tests/fast/encoding/meta-charset.html
-/sdcard/android/layout_tests/fast/encoding/xml-utf-8-default.xml
-/sdcard/android/layout_tests/fast/encoding/pseudo-xml.html
-/sdcard/android/layout_tests/fast/encoding/yahoo-mail.html
-/sdcard/android/layout_tests/fast/encoding/ahram-org-eg.html
-/sdcard/android/layout_tests/fast/encoding/script-in-head.html
-/sdcard/android/layout_tests/fast/encoding/mispositioned-meta.html
-/sdcard/android/layout_tests/fast/multicol/gap-non-negative.html
-/sdcard/android/layout_tests/fast/multicol/content-height-zero-crash.html
-/sdcard/android/layout_tests/fast/doctypes/doctype-at-end.html
-/sdcard/android/layout_tests/fast/doctypes/005-case-preserving.html
-/sdcard/android/layout_tests/fast/doctypes/doctype-in-element.html
-/sdcard/android/layout_tests/fast/doctypes/doctype-after-comment.html
-/sdcard/android/layout_tests/fast/doctypes/doctype-parsing.html
-/sdcard/android/layout_tests/fast/doctypes/html-doctype.html
-/sdcard/android/layout_tests/fast/cookies/local-file-can-set-cookies.html
-/sdcard/android/layout_tests/fast/css-generated-content/empty-content-with-float-crash.html
-/sdcard/android/layout_tests/fast/css-generated-content/reset-content-to-initial.html
-/sdcard/android/layout_tests/fast/workers/worker-close.html
-/sdcard/android/layout_tests/fast/workers/worker-context-gc.html
-/sdcard/android/layout_tests/fast/workers/worker-constructor.html
-/sdcard/android/layout_tests/fast/workers/worker-timeout.html
-/sdcard/android/layout_tests/fast/workers/worker-messageport.html
-/sdcard/android/layout_tests/fast/workers/worker-gc.html
-/sdcard/android/layout_tests/fast/workers/worker-replace-self.html
-/sdcard/android/layout_tests/fast/workers/worker-event-listener.html
-/sdcard/android/layout_tests/fast/workers/worker-cloneport.html
-/sdcard/android/layout_tests/fast/workers/worker-call.html
-/sdcard/android/layout_tests/fast/workers/worker-messageport-gc.html
-/sdcard/android/layout_tests/fast/workers/stress-js-execution.html
-/sdcard/android/layout_tests/fast/workers/worker-terminate.html
-/sdcard/android/layout_tests/fast/workers/use-machine-stack.html
-/sdcard/android/layout_tests/fast/workers/worker-navigator.html
-/sdcard/android/layout_tests/fast/workers/worker-script-error.html
-/sdcard/android/layout_tests/fast/workers/worker-replace-global-constructor.html
-/sdcard/android/layout_tests/fast/transforms/container-transform-crash.html
-/sdcard/android/layout_tests/fast/leaks/001.html
-/sdcard/android/layout_tests/fast/leaks/002.html
-/sdcard/android/layout_tests/fast/borders/border-radius-parsing.html
-/sdcard/android/layout_tests/fast/innerHTML/innerHTML-custom-tag.html
-/sdcard/android/layout_tests/fast/innerHTML/additional-inline-style.html
-/sdcard/android/layout_tests/fast/innerHTML/005.html
-/sdcard/android/layout_tests/fast/innerHTML/javascript-url.html
-/sdcard/android/layout_tests/fast/innerHTML/innerHTML-case.html
-/sdcard/android/layout_tests/fast/overflow/onscroll-layer-self-destruct.html
-/sdcard/android/layout_tests/fast/overflow/generated-content-crash.html
-/sdcard/android/layout_tests/fast/overflow/overflow-y-scroll.html
-/sdcard/android/layout_tests/fast/events/dispatch-to-handle-event.html
-/sdcard/android/layout_tests/fast/events/scroll-during-zoom-change.html
-/sdcard/android/layout_tests/fast/events/scroll-event-does-not-bubble.html
-/sdcard/android/layout_tests/fast/events/onload-after-document-close-with-subresource.html
-/sdcard/android/layout_tests/fast/events/message-channel-gc-4.html
-/sdcard/android/layout_tests/fast/events/message-channel-listener-circular-ownership.html
-/sdcard/android/layout_tests/fast/events/message-port-constructor-for-deleted-document.html
-/sdcard/android/layout_tests/fast/events/dispatchEvent-crash.html
-/sdcard/android/layout_tests/fast/events/programmatic-check-no-change-event.html
-/sdcard/android/layout_tests/fast/events/message-port-inactive-document.html
-/sdcard/android/layout_tests/fast/events/onunload-body-property.html
-/sdcard/android/layout_tests/fast/events/event-trace.html
-/sdcard/android/layout_tests/fast/events/init-event-after-dispatch.html
-/sdcard/android/layout_tests/fast/events/delayed-style-mutation-event-crash.html
-/sdcard/android/layout_tests/fast/events/keydown-keypress-focus-change.html
-/sdcard/android/layout_tests/fast/events/no-blur-on-page-leave.html
-/sdcard/android/layout_tests/fast/events/onload-name-collision.html
-/sdcard/android/layout_tests/fast/events/div-focus.html
-/sdcard/android/layout_tests/fast/events/overflow-events.html
-/sdcard/android/layout_tests/fast/events/create-document-crash-on-attach-event.html
-/sdcard/android/layout_tests/fast/events/no-blur-on-enter-button.html
-/sdcard/android/layout_tests/fast/events/keypress-removed-node.html
-/sdcard/android/layout_tests/fast/events/shadow-boundary-crossing.html
-/sdcard/android/layout_tests/fast/events/submit-reset-nested-bubble.html
-/sdcard/android/layout_tests/fast/events/message-port-deleted-frame.html
-/sdcard/android/layout_tests/fast/events/nested-event-remove-node-crash.html
-/sdcard/android/layout_tests/fast/events/onsubmit-bubbling.html
-/sdcard/android/layout_tests/fast/events/onload-fires-twice.html
-/sdcard/android/layout_tests/fast/events/message-port-no-wrapper.html
-/sdcard/android/layout_tests/fast/events/mousedown_in_scrollbar.html
-/sdcard/android/layout_tests/fast/events/onload-single-line-comment.html
-/sdcard/android/layout_tests/fast/events/message-channel-gc-2.html
-/sdcard/android/layout_tests/fast/events/window-load-capture.html
-/sdcard/android/layout_tests/fast/events/message-port-deleted-document.html
-/sdcard/android/layout_tests/fast/events/event-instanceof.html
-/sdcard/android/layout_tests/fast/events/message-channel-gc.html
-/sdcard/android/layout_tests/fast/events/event-creation.html
-/sdcard/android/layout_tests/fast/events/event-listener-sharing.html
-/sdcard/android/layout_tests/fast/events/caller-access-from-event-listener.html
-/sdcard/android/layout_tests/fast/events/stopPropagation-submit.html
-/sdcard/android/layout_tests/fast/events/remove-event-listener.html
-/sdcard/android/layout_tests/fast/events/mouseup-outside-button.html
-/sdcard/android/layout_tests/fast/events/iframe-object-onload.html
-/sdcard/android/layout_tests/fast/events/no-window-load.html
-/sdcard/android/layout_tests/fast/events/event-listener-html-non-html-confusion.html
-/sdcard/android/layout_tests/fast/events/onerror-bubbling.html
-/sdcard/android/layout_tests/fast/events/keydown-remove-frame.html
-/sdcard/android/layout_tests/fast/events/message-channel-gc-3.html
-/sdcard/android/layout_tests/fast/events/event-targets.html
-/sdcard/android/layout_tests/fast/events/space-scroll-event.html
-/sdcard/android/layout_tests/fast/events/onload-after-document-close-no-subresource.html
-/sdcard/android/layout_tests/fast/events/nested-window-event.html
-/sdcard/android/layout_tests/fast/events/selectstart-during-autoscroll.html
-/sdcard/android/layout_tests/fast/events/stopPropagation-checkbox.html
-/sdcard/android/layout_tests/fast/events/message-port-clone.html
-/sdcard/android/layout_tests/fast/events/tab-crash-with-image-map.html
-/sdcard/android/layout_tests/fast/events/simulated-key-state.html
-/sdcard/android/layout_tests/fast/events/init-event-null-view.html
-/sdcard/android/layout_tests/fast/events/init-events.html
-/sdcard/android/layout_tests/fast/events/onunload-window-property.html
-/sdcard/android/layout_tests/fast/events/message-port.html
-/sdcard/android/layout_tests/fast/html/tab-order.html
-/sdcard/android/layout_tests/fast/html/xhtml-serialize.html
-/sdcard/android/layout_tests/fast/html/empty-fragment-id-goto-top.html
-/sdcard/android/layout_tests/fast/html/script-allowed-types-languages.html
-/sdcard/android/layout_tests/fast/html/text-field-input-types.html
-/sdcard/android/layout_tests/fast/html/draggable.html
-/sdcard/android/layout_tests/fast/html/body-offset-properties.html
-/sdcard/android/layout_tests/fast/images/image-empty-data.html
-/sdcard/android/layout_tests/fast/images/text-content-crash.html
-/sdcard/android/layout_tests/fast/images/border.html
-/sdcard/android/layout_tests/fast/images/animated-background-image-crash.html
-/sdcard/android/layout_tests/fast/images/load-img-with-empty-src.html
-/sdcard/android/layout_tests/fast/images/text-content-crash-2.html
-/sdcard/android/layout_tests/fast/inspector/cssURLQuotes.html
-/sdcard/android/layout_tests/fast/flexbox/repaint-scrollbar.html
-/sdcard/android/layout_tests/fast/flexbox/inline-children-crash.html
-/sdcard/android/layout_tests/fast/tokenizer/nested-cached-scripts.html
-/sdcard/android/layout_tests/fast/tokenizer/image-empty-crash.html
-/sdcard/android/layout_tests/fast/tokenizer/lessthan-terminates-tags-and-attrs.html
-/sdcard/android/layout_tests/fast/tokenizer/ignore-tags-in-iframe.html
-/sdcard/android/layout_tests/fast/tokenizer/write-partial-entity.html
-/sdcard/android/layout_tests/fast/tokenizer/external-script-document-open.html
-/sdcard/android/layout_tests/fast/tokenizer/004.html
-/sdcard/android/layout_tests/fast/tokenizer/write-inline-script-open.html
-/sdcard/android/layout_tests/fast/tokenizer/write-external-script-open.html
-/sdcard/android/layout_tests/fast/tokenizer/doctype-search-reset.html
-/sdcard/android/layout_tests/fast/tokenizer/nested-multiple-scripts.html
-/sdcard/android/layout_tests/fast/tokenizer/nested-cached-scripts-and-stylesheet.html
-/sdcard/android/layout_tests/fast/tokenizer/ampersand-in-special-tag.html
-/sdcard/android/layout_tests/fast/tokenizer/write-unclosed-script.html
-/sdcard/android/layout_tests/fast/tokenizer/badscript.html
-/sdcard/android/layout_tests/fast/regex/quantified-assertions.html
-/sdcard/android/layout_tests/fast/regex/non-pattern-characters.html
-/sdcard/android/layout_tests/fast/regex/malformed-escapes.html
-/sdcard/android/layout_tests/fast/regex/early-acid3-86.html
-/sdcard/android/layout_tests/fast/regex/alternative-length-miscalculation.html
-/sdcard/android/layout_tests/fast/regex/test4.html
-/sdcard/android/layout_tests/fast/regex/non-capturing-backtracking.html
-/sdcard/android/layout_tests/fast/box-shadow/box-shadow-overflow-scroll.html
-/sdcard/android/layout_tests/fast/js/kde/Boolean.html
-/sdcard/android/layout_tests/fast/js/kde/garbage-n.html
-/sdcard/android/layout_tests/fast/js/kde/function.html
-/sdcard/android/layout_tests/fast/js/kde/function_length.html
-/sdcard/android/layout_tests/fast/js/kde/const.html
-/sdcard/android/layout_tests/fast/js/kde/constructor_length.html
-/sdcard/android/layout_tests/fast/js/kde/statements.html
-/sdcard/android/layout_tests/fast/js/kde/math.html
-/sdcard/android/layout_tests/fast/js/kde/assignments.html
-/sdcard/android/layout_tests/fast/js/kde/crash-1.html
-/sdcard/android/layout_tests/fast/js/kde/delete.html
-/sdcard/android/layout_tests/fast/js/kde/var_decl_init.html
-/sdcard/android/layout_tests/fast/js/kde/literals.html
-/sdcard/android/layout_tests/fast/js/kde/eval.html
-/sdcard/android/layout_tests/fast/js/kde/j-comment-3.html
-/sdcard/android/layout_tests/fast/js/kde/StringObject.html
-/sdcard/android/layout_tests/fast/js/kde/crash-2.html
-/sdcard/android/layout_tests/fast/js/kde/exception_propagation.html
-/sdcard/android/layout_tests/fast/js/kde/conditional.html
-/sdcard/android/layout_tests/fast/js/kde/scope.html
-/sdcard/android/layout_tests/fast/js/kde/parse.html
-/sdcard/android/layout_tests/fast/js/kde/function_arguments.html
-/sdcard/android/layout_tests/fast/js/kde/arguments-scope.html
-/sdcard/android/layout_tests/fast/js/kde/lval-exceptions.html
-/sdcard/android/layout_tests/fast/js/kde/operators.html
-/sdcard/android/layout_tests/fast/js/kde/Array.html
-/sdcard/android/layout_tests/fast/js/kde/md5-1.html
-/sdcard/android/layout_tests/fast/js/kde/object_prototype_tostring.html
-/sdcard/android/layout_tests/fast/js/kde/Date-setYear.html
-/sdcard/android/layout_tests/fast/js/kde/GlobalObject.html
-/sdcard/android/layout_tests/fast/js/kde/prototype_proto.html
-/sdcard/android/layout_tests/fast/js/kde/evil-n.html
-/sdcard/android/layout_tests/fast/js/kde/RegExp.html
-/sdcard/android/layout_tests/fast/js/kde/cast.html
-/sdcard/android/layout_tests/fast/js/kde/j-comment-4.html
-/sdcard/android/layout_tests/fast/js/kde/iteration.html
-/sdcard/android/layout_tests/fast/js/kde/comment-1.html
-/sdcard/android/layout_tests/fast/js/kde/string-2-n.html
-/sdcard/android/layout_tests/fast/js/kde/Prototype.html
-/sdcard/android/layout_tests/fast/js/kde/completion.html
-/sdcard/android/layout_tests/fast/js/kde/encode_decode_uri.html
-/sdcard/android/layout_tests/fast/js/kde/exceptions.html
-/sdcard/android/layout_tests/fast/js/kde/md5-2.html
-/sdcard/android/layout_tests/fast/js/kde/Error.html
-/sdcard/android/layout_tests/fast/js/kde/function_constructor.html
-/sdcard/android/layout_tests/fast/js/kde/object_prototype.html
-/sdcard/android/layout_tests/fast/js/kde/empty.html
-/sdcard/android/layout_tests/fast/js/kde/inbuilt_function_proto.html
-/sdcard/android/layout_tests/fast/js/kde/string-1-n.html
-/sdcard/android/layout_tests/fast/js/kde/func-decl.html
-/sdcard/android/layout_tests/fast/js/kde/comment-2.html
-/sdcard/android/layout_tests/fast/js/kde/inbuilt_function_tostring.html
-/sdcard/android/layout_tests/fast/js/kde/Object.html
-/sdcard/android/layout_tests/fast/js/kde/prototype_length.html
-/sdcard/android/layout_tests/fast/js/pic/cached-single-entry-transition.html
-/sdcard/android/layout_tests/fast/js/pic/cached-prototype-setter.html
-/sdcard/android/layout_tests/fast/js/pic/get-empty-string.html
-/sdcard/android/layout_tests/fast/js/pic/get-set-proxy-object.html
-/sdcard/android/layout_tests/fast/js/pic/rehash-poisons-structure.html
-/sdcard/android/layout_tests/fast/js/pic/cached-array-length-access.html
-/sdcard/android/layout_tests/fast/js/pic/cached-prototype-then-immediate.html
-/sdcard/android/layout_tests/fast/js/pic/cached-getter-setter.html
-/sdcard/android/layout_tests/fast/js/pic/cached-getter-dictionary-and-proto.html
-/sdcard/android/layout_tests/fast/js/pic/delete-global-object.html
-/sdcard/android/layout_tests/fast/js/pic/cached-deleted-properties.html
-/sdcard/android/layout_tests/fast/js/pic/dictionary-prototype.html
-/sdcard/android/layout_tests/fast/js/bitwise-and-on-undefined.html
-/sdcard/android/layout_tests/fast/js/exception-sequencing-binops.html
-/sdcard/android/layout_tests/fast/js/exception-thrown-from-eval-inside-closure.html
-/sdcard/android/layout_tests/fast/js/recursion-limit-equal.html
-/sdcard/android/layout_tests/fast/js/string_replace.html
-/sdcard/android/layout_tests/fast/js/ignored-result-ref-crash.html
-/sdcard/android/layout_tests/fast/js/function-toString-object-literals.html
-/sdcard/android/layout_tests/fast/js/numeric-conversion.html
-/sdcard/android/layout_tests/fast/js/select-options-remove.html
-/sdcard/android/layout_tests/fast/js/array-tostring-ignore-separator.html
-/sdcard/android/layout_tests/fast/js/exception-sequencing-binops2.html
-/sdcard/android/layout_tests/fast/js/function-declaration.html
-/sdcard/android/layout_tests/fast/js/number-toExponential.html
-/sdcard/android/layout_tests/fast/js/direct-entry-to-function-code.html
-/sdcard/android/layout_tests/fast/js/number-parsing-crash.html
-/sdcard/android/layout_tests/fast/js/vardecl-preserve-vardecl.html
-/sdcard/android/layout_tests/fast/js/unexpected-constant-crash.html
-/sdcard/android/layout_tests/fast/js/var-shadows-arg-gc-crash.html
-/sdcard/android/layout_tests/fast/js/arguments-bad-index.html
-/sdcard/android/layout_tests/fast/js/resize-array-assign.html
-/sdcard/android/layout_tests/fast/js/number-toString.html
-/sdcard/android/layout_tests/fast/js/this-non-object-proto.html
-/sdcard/android/layout_tests/fast/js/exception-thrown-from-new.html
-/sdcard/android/layout_tests/fast/js/cyclic-proto.html
-/sdcard/android/layout_tests/fast/js/vardecl-preserve-arguments.html
-/sdcard/android/layout_tests/fast/js/regexp-compile-crash.html
-/sdcard/android/layout_tests/fast/js/var-declarations-shadowing.html
-/sdcard/android/layout_tests/fast/js/ignored-result-null-comparison-crash.html
-/sdcard/android/layout_tests/fast/js/array-sort-reentrance.html
-/sdcard/android/layout_tests/fast/js/toString-for-var-decl.html
-/sdcard/android/layout_tests/fast/js/string-slice-abnormal-values.html
-/sdcard/android/layout_tests/fast/js/exception-linenums-in-html-1.html
-/sdcard/android/layout_tests/fast/js/do-while-without-semicolon.html
-/sdcard/android/layout_tests/fast/js/object-prototype-toLocaleString.html
-/sdcard/android/layout_tests/fast/js/function-redefinition.html
-/sdcard/android/layout_tests/fast/js/function-name.html
-/sdcard/android/layout_tests/fast/js/logical-or-jless.html
-/sdcard/android/layout_tests/fast/js/regexp-non-character.html
-/sdcard/android/layout_tests/fast/js/JSON-parse.html
-/sdcard/android/layout_tests/fast/js/assign.html
-/sdcard/android/layout_tests/fast/js/for-in-avoid-duplicates.html
-/sdcard/android/layout_tests/fast/js/math-transforms.html
-/sdcard/android/layout_tests/fast/js/sort-stability.html
-/sdcard/android/layout_tests/fast/js/try-catch-crash.html
-/sdcard/android/layout_tests/fast/js/duplicate-param-gc-crash.html
-/sdcard/android/layout_tests/fast/js/regexp-stack-overflow.html
-/sdcard/android/layout_tests/fast/js/function-argument-evaluation-before-exception.html
-/sdcard/android/layout_tests/fast/js/number-toprecision.html
-/sdcard/android/layout_tests/fast/js/string-property-iteration.html
-/sdcard/android/layout_tests/fast/js/do-while-semicolon.html
-/sdcard/android/layout_tests/fast/js/regexp-divequal.html
-/sdcard/android/layout_tests/fast/js/named-function-expression.html
-/sdcard/android/layout_tests/fast/js/array-iterate-backwards.html
-/sdcard/android/layout_tests/fast/js/constructor-attributes.html
-/sdcard/android/layout_tests/fast/js/array-some.html
-/sdcard/android/layout_tests/fast/js/missing-title-end-tag-js.html
-/sdcard/android/layout_tests/fast/js/object-extra-comma.html
-/sdcard/android/layout_tests/fast/js/number-tofixed.html
-/sdcard/android/layout_tests/fast/js/function-declarations-in-switch-statement.html
-/sdcard/android/layout_tests/fast/js/regexp-extended-characters-crash.html
-/sdcard/android/layout_tests/fast/js/typeof-codegen-crash.html
-/sdcard/android/layout_tests/fast/js/array-indexof.html
-/sdcard/android/layout_tests/fast/js/mod-crash.html
-/sdcard/android/layout_tests/fast/js/eval-keyword-vs-function.html
-/sdcard/android/layout_tests/fast/js/debugger.html
-/sdcard/android/layout_tests/fast/js/rehash-assign.html
-/sdcard/android/layout_tests/fast/js/object-prototype-constructor.html
-/sdcard/android/layout_tests/fast/js/function-call-aliased.html
-/sdcard/android/layout_tests/fast/js/string-replace-exception-crash.html
-/sdcard/android/layout_tests/fast/js/date-big-setmonth.html
-/sdcard/android/layout_tests/fast/js/array-enumerators-functions.html
-/sdcard/android/layout_tests/fast/js/exception-linenums-in-html-2.html
-/sdcard/android/layout_tests/fast/js/select-options-add.html
-/sdcard/android/layout_tests/fast/js/toString-dontEnum.html
-/sdcard/android/layout_tests/fast/js/toString-elision-trailing-comma.html
-/sdcard/android/layout_tests/fast/js/regexp-negative-special-characters.html
-/sdcard/android/layout_tests/fast/js/getter-setter-gc.html
-/sdcard/android/layout_tests/fast/js/string-substr.html
-/sdcard/android/layout_tests/fast/js/for-in-var-scope.html
-/sdcard/android/layout_tests/fast/js/exec-state-marking.html
-/sdcard/android/layout_tests/fast/js/primitive-method-this.html
-/sdcard/android/layout_tests/fast/js/string-sort.html
-/sdcard/android/layout_tests/fast/js/for-in-cached.html
-/sdcard/android/layout_tests/fast/js/delete-getters-setters.html
-/sdcard/android/layout_tests/fast/js/const-without-initializer.html
-/sdcard/android/layout_tests/fast/js/function-apply-aliased.html
-/sdcard/android/layout_tests/fast/js/sparse-array.html
-/sdcard/android/layout_tests/fast/js/same-origin-subframe-about-blank.html
-/sdcard/android/layout_tests/fast/js/nested-function-scope.html
-/sdcard/android/layout_tests/fast/js/function-constructor-single-line-comment.html
-/sdcard/android/layout_tests/fast/js/JSON-stringify.html
-/sdcard/android/layout_tests/fast/js/uncaught-exception-line-number.html
-/sdcard/android/layout_tests/fast/js/const.html
-/sdcard/android/layout_tests/fast/js/reparsing-semicolon-insertion.html
-/sdcard/android/layout_tests/fast/js/regexp-non-capturing-groups.html
-/sdcard/android/layout_tests/fast/js/has-own-property.html
-/sdcard/android/layout_tests/fast/js/window-location-href-file-urls.html
-/sdcard/android/layout_tests/fast/js/regexp-extended-characters-more.html
-/sdcard/android/layout_tests/fast/js/prefix-syntax.html
-/sdcard/android/layout_tests/fast/js/exceptions-thrown-in-callbacks.html
-/sdcard/android/layout_tests/fast/js/exception-with-handler-inside-eval-with-dynamic-scope.html
-/sdcard/android/layout_tests/fast/js/for-in-exeception.html
-/sdcard/android/layout_tests/fast/js/array-lastIndexOf.html
-/sdcard/android/layout_tests/fast/js/modify-non-references.html
-/sdcard/android/layout_tests/fast/js/exception-for-nonobject.html
-/sdcard/android/layout_tests/fast/js/regexp-find-first-asserted.html
-/sdcard/android/layout_tests/fast/js/sort-randomly.html
-/sdcard/android/layout_tests/fast/js/array-indexing.html
-/sdcard/android/layout_tests/fast/js/registerCachingAcrossBranchTargets.html
-/sdcard/android/layout_tests/fast/js/regexp-caching.html
-/sdcard/android/layout_tests/fast/js/typeof-syntax.html
-/sdcard/android/layout_tests/fast/js/regexp-character-match-out-of-order.html
-/sdcard/android/layout_tests/fast/js/date-toisostring.html
-/sdcard/android/layout_tests/fast/js/function-call-register-allocation.html
-/sdcard/android/layout_tests/fast/js/arguments.html
-/sdcard/android/layout_tests/fast/js/constant-folding.html
-/sdcard/android/layout_tests/fast/js/activation-object-function-lifetime.html
-/sdcard/android/layout_tests/fast/js/array-filter.html
-/sdcard/android/layout_tests/fast/js/implicit-global-to-global-reentry.html
-/sdcard/android/layout_tests/fast/js/array-reduceRight.html
-/sdcard/android/layout_tests/fast/js/array-foreach.html
-/sdcard/android/layout_tests/fast/js/regexp-many-brackets.html
-/sdcard/android/layout_tests/fast/js/activation-proto.html
-/sdcard/android/layout_tests/fast/js/toString-overrides.html
-/sdcard/android/layout_tests/fast/js/regexp-unicode-overflow.html
-/sdcard/android/layout_tests/fast/js/postfix-syntax.html
-/sdcard/android/layout_tests/fast/js/global-recursion-on-full-stack.html
-/sdcard/android/layout_tests/fast/js/closure-inside-extra-arg-call.html
-/sdcard/android/layout_tests/fast/js/number-cell-reuse.html
-/sdcard/android/layout_tests/fast/js/removing-Cf-characters.html
-/sdcard/android/layout_tests/fast/js/pretty-print.html
-/sdcard/android/layout_tests/fast/js/isPrototypeOf.html
-/sdcard/android/layout_tests/fast/js/prototypes.html
-/sdcard/android/layout_tests/fast/js/math.html
-/sdcard/android/layout_tests/fast/js/string-from-char-code.html
-/sdcard/android/layout_tests/fast/js/sort-no-jit-code-crash.html
-/sdcard/android/layout_tests/fast/js/eval-overriding.html
-/sdcard/android/layout_tests/fast/js/regexp-char-insensitive.html
-/sdcard/android/layout_tests/fast/js/array-float-delete.html
-/sdcard/android/layout_tests/fast/js/array-index-immediate-types.html
-/sdcard/android/layout_tests/fast/js/integer-extremes.html
-/sdcard/android/layout_tests/fast/js/console-non-string-values.html
-/sdcard/android/layout_tests/fast/js/regexp-non-bmp.html
-/sdcard/android/layout_tests/fast/js/regexp-range-bound-ffff.html
-/sdcard/android/layout_tests/fast/js/delete-then-put.html
-/sdcard/android/layout_tests/fast/js/nested-object-gc.html
-/sdcard/android/layout_tests/fast/js/string-replace-2.html
-/sdcard/android/layout_tests/fast/js/cached-eval-gc.html
-/sdcard/android/layout_tests/fast/js/property-getters-and-setters.html
-/sdcard/android/layout_tests/fast/js/array-reset-large-index.html
-/sdcard/android/layout_tests/fast/js/date-proto-generic-invocation.html
-/sdcard/android/layout_tests/fast/js/lastModified.html
-/sdcard/android/layout_tests/fast/js/encode-URI-test.html
-/sdcard/android/layout_tests/fast/js/codegen-loops-logical-nodes.html
-/sdcard/android/layout_tests/fast/js/string-capitalization.html
-/sdcard/android/layout_tests/fast/js/caller-property.html
-/sdcard/android/layout_tests/fast/js/regexp-overflow-too-big.html
-/sdcard/android/layout_tests/fast/js/repeat-cached-vm-reentry.html
-/sdcard/android/layout_tests/fast/js/date-DST-time-cusps.html
-/sdcard/android/layout_tests/fast/js/regexp-unicode-handling.html
-/sdcard/android/layout_tests/fast/js/unmatching-argument-count.html
-/sdcard/android/layout_tests/fast/js/text-field-resize.html
-/sdcard/android/layout_tests/fast/js/delete-multiple-global-blocks.html
-/sdcard/android/layout_tests/fast/js/eval-throw-return.html
-/sdcard/android/layout_tests/fast/js/duplicate-param-crash.html
-/sdcard/android/layout_tests/fast/js/switch-behaviour.html
-/sdcard/android/layout_tests/fast/js/delete-syntax.html
-/sdcard/android/layout_tests/fast/js/date-DST-pre-1970.html
-/sdcard/android/layout_tests/fast/js/array-splice.html
-/sdcard/android/layout_tests/fast/js/statement-list-register-crash.html
-/sdcard/android/layout_tests/fast/js/date-set-to-nan.html
-/sdcard/android/layout_tests/fast/js/code-serialize-paren.html
-/sdcard/android/layout_tests/fast/js/parse-backslash-before-newline.html
-/sdcard/android/layout_tests/fast/js/delete-function-parameter.html
-/sdcard/android/layout_tests/fast/js/exception-expression-offset.html
-/sdcard/android/layout_tests/fast/js/JSON-stringify-replacer.html
-/sdcard/android/layout_tests/fast/js/invalid-syntax-for-function.html
-/sdcard/android/layout_tests/fast/js/toString-and-valueOf-override.html
-/sdcard/android/layout_tests/fast/js/cyclic-prototypes.html
-/sdcard/android/layout_tests/fast/js/equality.html
-/sdcard/android/layout_tests/fast/js/order-of-operations.html
-/sdcard/android/layout_tests/fast/js/regexp-no-extensions.html
-/sdcard/android/layout_tests/fast/js/stack-unwinding.html
-/sdcard/android/layout_tests/fast/js/toString-try-else.html
-/sdcard/android/layout_tests/fast/js/reserved-words.html
-/sdcard/android/layout_tests/fast/js/function-dot-arguments-and-caller.html
-/sdcard/android/layout_tests/fast/js/do-while-expression-value.html
-/sdcard/android/layout_tests/fast/js/bom-in-file-retains-correct-offset.html
-/sdcard/android/layout_tests/fast/js/string-split-ignore-case.html
-/sdcard/android/layout_tests/fast/js/date-constructor.html
-/sdcard/android/layout_tests/fast/js/global-function-resolve.html
-/sdcard/android/layout_tests/fast/js/date-big-setdate.html
-/sdcard/android/layout_tests/fast/js/array-every.html
-/sdcard/android/layout_tests/fast/js/array-functions-non-arrays.html
-/sdcard/android/layout_tests/fast/js/function-toString-parentheses.html
-/sdcard/android/layout_tests/fast/js/while-expression-value.html
-/sdcard/android/layout_tests/fast/js/string-replace-3.html
-/sdcard/android/layout_tests/fast/js/avl-crash.html
-/sdcard/android/layout_tests/fast/js/vardecl-blocks-init.html
-/sdcard/android/layout_tests/fast/js/null-char-in-string.html
-/sdcard/android/layout_tests/fast/js/codegen-temporaries-multiple-global-blocks.html
-/sdcard/android/layout_tests/fast/js/char-at.html
-/sdcard/android/layout_tests/fast/js/function-constructor-newline-after-brace.html
-/sdcard/android/layout_tests/fast/js/propertyIsEnumerable.html
-/sdcard/android/layout_tests/fast/js/exception-thrown-from-equal.html
-/sdcard/android/layout_tests/fast/js/constructor.html
-/sdcard/android/layout_tests/fast/js/regexp-backreferences.html
-/sdcard/android/layout_tests/fast/js/regexp-overflow.html
-/sdcard/android/layout_tests/fast/js/var-declarations.html
-/sdcard/android/layout_tests/fast/js/continue-break-multiple-labels.html
-/sdcard/android/layout_tests/fast/js/toString-exception.html
-/sdcard/android/layout_tests/fast/js/regexp-test-null-string.html
-/sdcard/android/layout_tests/fast/js/date-parse-comments-test.html
-/sdcard/android/layout_tests/fast/js/select-options-remove-gc.html
-/sdcard/android/layout_tests/fast/js/implicit-call-with-global-reentry.html
-/sdcard/android/layout_tests/fast/js/array-tostring-and-join.html
-/sdcard/android/layout_tests/fast/js/function-names.html
-/sdcard/android/layout_tests/fast/js/primitive-property-access-edge-cases.html
-/sdcard/android/layout_tests/fast/js/date-preserve-milliseconds.html
-/sdcard/android/layout_tests/fast/js/sort-large-array.html
-/sdcard/android/layout_tests/fast/js/for-in-to-text.html
-/sdcard/android/layout_tests/fast/js/global-var-limit.html
-/sdcard/android/layout_tests/fast/js/static-scope-object.html
-/sdcard/android/layout_tests/fast/js/var-shadows-arg-crash.html
-/sdcard/android/layout_tests/fast/js/function-apply.html
-/sdcard/android/layout_tests/fast/js/array-reduce.html
-/sdcard/android/layout_tests/fast/js/function-prototype.html
-/sdcard/android/layout_tests/fast/js/tostring-exception-in-property-access.html
-/sdcard/android/layout_tests/fast/js/function-declaration-statement.html
-/sdcard/android/layout_tests/fast/js/large-expressions.html
-/sdcard/android/layout_tests/fast/js/date-negative-setmonth.html
-/sdcard/android/layout_tests/fast/js/reentrant-call-unwind.html
-/sdcard/android/layout_tests/fast/js/dictionary-no-cache.html
-/sdcard/android/layout_tests/fast/js/regexp-lastindex.html
-/sdcard/android/layout_tests/fast/js/finally-codegen-failure.html
-/sdcard/android/layout_tests/fast/js/instance-of-immediates.html
-/sdcard/android/layout_tests/fast/js/read-modify-eval.html
-/sdcard/android/layout_tests/fast/js/exception-thrown-from-function-with-lazy-activation.html
-/sdcard/android/layout_tests/fast/js/cyclic-ref-toString.html
-/sdcard/android/layout_tests/fast/js/function-toString-semicolon-insertion.html
-/sdcard/android/layout_tests/fast/js/exception-sequencing.html
-/sdcard/android/layout_tests/fast/js/date-big-constructor.html
-/sdcard/android/layout_tests/fast/js/gmail-re-re.html
-/sdcard/android/layout_tests/fast/js/deep-recursion-test.html
-/sdcard/android/layout_tests/fast/js/lexical-lookup-in-function-constructor.html
-/sdcard/android/layout_tests/fast/js/regexp-range-out-of-order.html
-/sdcard/android/layout_tests/fast/js/throw-from-array-sort.html
-/sdcard/android/layout_tests/fast/js/slash-lineterminator-parse.html
-/sdcard/android/layout_tests/fast/js/dot-node-base-exception.html
-/sdcard/android/layout_tests/fast/js/toString-stack-overflow.html
-/sdcard/android/layout_tests/fast/js/codegen-peephole-locals.html
-/sdcard/android/layout_tests/fast/js/constant-count.html
-/sdcard/android/layout_tests/fast/js/regexp-compile.html
-/sdcard/android/layout_tests/fast/js/declaration-in-block.html
-/sdcard/android/layout_tests/fast/js/eval-var-decl.html
-/sdcard/android/layout_tests/fast/js/eval-cross-window.html
-/sdcard/android/layout_tests/fast/js/function-decompilation-operators.html
-/sdcard/android/layout_tests/fast/js/sort-non-numbers.html
-/sdcard/android/layout_tests/fast/js/excessive-comma-usage.html
-/sdcard/android/layout_tests/fast/js/method-check.html
-/sdcard/android/layout_tests/fast/js/function-declarations.html
-/sdcard/android/layout_tests/fast/js/regexp-extended-characters-match.html
-/sdcard/android/layout_tests/fast/js/non-object-proto.html
-/sdcard/android/layout_tests/fast/js/toString-number-dot-expr.html
-/sdcard/android/layout_tests/fast/js/date-parse-test.html
-/sdcard/android/layout_tests/fast/js/exception-try-finally-scope-error.html
-/sdcard/android/layout_tests/fast/js/function-dot-arguments.html
-/sdcard/android/layout_tests/fast/js/toString-prefix-postfix-preserve-parens.html
-/sdcard/android/layout_tests/fast/js/regexp-ranges-and-escaped-hyphens.html
-/sdcard/android/layout_tests/fast/js/construct-global-object.html
-/sdcard/android/layout_tests/fast/js/array-holes.html
-/sdcard/android/layout_tests/fast/js/exception-linenums.html
-/sdcard/android/layout_tests/fast/js/codegen-temporaries.html
-/sdcard/android/layout_tests/fast/js/array-join-bug-11524.html
-/sdcard/android/layout_tests/fast/js/with-scope-gc.html
-/sdcard/android/layout_tests/fast/js/string-index-overflow.html
-/sdcard/android/layout_tests/fast/js/eval-cache-crash.html
-/sdcard/android/layout_tests/fast/js/array-map.html
-/sdcard/android/layout_tests/fast/js/exception-codegen-crash.html
-/sdcard/android/layout_tests/fast/js/comparefn-sort-stability.html
-/sdcard/android/layout_tests/fast/js/typeof-constant-string.html
-/sdcard/android/layout_tests/fast/js/navigator-plugins-crash.html
-/sdcard/android/layout_tests/fast/js/vardecl-preserve-parameters.html
-/sdcard/android/layout_tests/fast/inline/clean-after-removing-temp-boxes.html
-/sdcard/android/layout_tests/fast/inline/continuation-positioned-reparenting.html
-/sdcard/android/layout_tests/fast/dom/HTMLTableElement/early-acid3-65-excerpt.html
-/sdcard/android/layout_tests/fast/dom/HTMLTableElement/early-acid3-66-excerpt.html
-/sdcard/android/layout_tests/fast/dom/HTMLTableElement/cellpadding-attribute.html
-/sdcard/android/layout_tests/fast/dom/HTMLTableElement/insert-row.html
-/sdcard/android/layout_tests/fast/dom/HTMLTableElement/tBodies.html
-/sdcard/android/layout_tests/fast/dom/HTMLTableElement/rows.html
-/sdcard/android/layout_tests/fast/dom/HTMLDocument/activeElement.html
-/sdcard/android/layout_tests/fast/dom/HTMLDocument/hasFocus-frameless-crash.html
-/sdcard/android/layout_tests/fast/dom/HTMLDocument/writeln-call.html
-/sdcard/android/layout_tests/fast/dom/HTMLDocument/document-plugins.html
-/sdcard/android/layout_tests/fast/dom/HTMLDocument/title-get.html
-/sdcard/android/layout_tests/fast/dom/HTMLDocument/object-by-name-unknown-child-element.html
-/sdcard/android/layout_tests/fast/dom/HTMLDocument/object-by-name-or-id.html
-/sdcard/android/layout_tests/fast/dom/HTMLDocument/title-set.html
-/sdcard/android/layout_tests/fast/dom/HTMLDocument/write-multiple-calls.html
-/sdcard/android/layout_tests/fast/dom/HTMLDocument/document-special-properties.html
-/sdcard/android/layout_tests/fast/dom/HTMLDocument/url-getset.html
-/sdcard/android/layout_tests/fast/dom/HTMLDocument/write-call.html
-/sdcard/android/layout_tests/fast/dom/HTMLDocument/document-open-return-value.html
-/sdcard/android/layout_tests/fast/dom/HTMLDocument/writeln-multiple-calls.html
-/sdcard/android/layout_tests/fast/dom/HTMLLabelElement/form/test1.html
-/sdcard/android/layout_tests/fast/dom/Document/replace-child.html
-/sdcard/android/layout_tests/fast/dom/Document/title-property-creates-title-element.html
-/sdcard/android/layout_tests/fast/dom/Document/createElementNS-namespace-err.html
-/sdcard/android/layout_tests/fast/dom/Document/title-property-set-multiple-times.html
-/sdcard/android/layout_tests/fast/dom/Document/document-reopen.html
-/sdcard/android/layout_tests/fast/dom/Document/document-charset.html
-/sdcard/android/layout_tests/fast/dom/Document/replaceChild-null-oldChild.html
-/sdcard/android/layout_tests/fast/dom/Document/createAttributeNS-namespace-err.html
-/sdcard/android/layout_tests/fast/dom/Document/open-with-pending-load.html
-/sdcard/android/layout_tests/fast/dom/Document/document-write-doctype.html
-/sdcard/android/layout_tests/fast/dom/Document/doc-open-while-parsing.html
-/sdcard/android/layout_tests/fast/dom/HTMLSelectElement/named-options.html
-/sdcard/android/layout_tests/fast/dom/HTMLSelectElement/length-not-overridden.html
-/sdcard/android/layout_tests/fast/dom/HTMLSelectElement/options-collection-set-string-length.html
-/sdcard/android/layout_tests/fast/dom/HTMLSelectElement/listbox-select-reset.html
-/sdcard/android/layout_tests/fast/dom/HTMLSelectElement/options-collection-detached.html
-/sdcard/android/layout_tests/fast/dom/HTMLSelectElement/remove-element-from-within-focus-handler-crash.html
-/sdcard/android/layout_tests/fast/dom/Selection/getRangeAt.html
-/sdcard/android/layout_tests/fast/dom/HTMLMetaElement/meta-attributes.html
-/sdcard/android/layout_tests/fast/dom/Element/fixed-position-offset-parent.html
-/sdcard/android/layout_tests/fast/dom/Element/getAttribute-check-case-sensitivity.html
-/sdcard/android/layout_tests/fast/dom/Element/attr-param-typechecking.html
-/sdcard/android/layout_tests/fast/dom/Element/attribute-uppercase.html
-/sdcard/android/layout_tests/fast/dom/Element/element-traversal.html
-/sdcard/android/layout_tests/fast/dom/Element/onclick-case.html
-/sdcard/android/layout_tests/fast/dom/Element/offsetLeft-offsetTop-body-quirk.html
-/sdcard/android/layout_tests/fast/dom/Element/contains-method.html
-/sdcard/android/layout_tests/fast/dom/Element/scrollWidth.html
-/sdcard/android/layout_tests/fast/dom/Element/setAttribute-with-colon.html
-/sdcard/android/layout_tests/fast/dom/Element/setAttribute-case-insensitivity.html
-/sdcard/android/layout_tests/fast/dom/Element/dimension-properties-unrendered.html
-/sdcard/android/layout_tests/fast/dom/Element/offsetLeft-offsetTop-html.html
-/sdcard/android/layout_tests/fast/dom/Element/offsetTop-table-cell.html
-/sdcard/android/layout_tests/fast/dom/DOMException/EventException.html
-/sdcard/android/layout_tests/fast/dom/DOMException/prototype-object.html
-/sdcard/android/layout_tests/fast/dom/DOMException/RangeException.html
-/sdcard/android/layout_tests/fast/dom/HTMLButtonElement/value/getset.html
-/sdcard/android/layout_tests/fast/dom/HTMLScriptElement/script-for-attribute-unexpected-execution.html
-/sdcard/android/layout_tests/fast/dom/HTMLScriptElement/script-reexecution.html
-/sdcard/android/layout_tests/fast/dom/HTMLScriptElement/script-set-src.html
-/sdcard/android/layout_tests/fast/dom/HTMLScriptElement/script-load-events.html
-/sdcard/android/layout_tests/fast/dom/HTMLScriptElement/script-decoding-error-after-setting-src.html
-/sdcard/android/layout_tests/fast/dom/HTMLOptionElement/collection-setter-getter.html
-/sdcard/android/layout_tests/fast/dom/HTMLOptionElement/set-option-index-text.html
-/sdcard/android/layout_tests/fast/dom/HTMLOptionElement/option-text.html
-/sdcard/android/layout_tests/fast/dom/HTMLOptionElement/option-prototype.html
-/sdcard/android/layout_tests/fast/dom/NodeList/5725058-crash-scenario-1.html
-/sdcard/android/layout_tests/fast/dom/NodeList/5725058-crash-scenario-2.html
-/sdcard/android/layout_tests/fast/dom/NodeList/childNodes-reset-cache.html
-/sdcard/android/layout_tests/fast/dom/NodeList/5725058-crash-scenario-3.html
-/sdcard/android/layout_tests/fast/dom/NodeList/invalidate-node-lists-when-parsing.html
-/sdcard/android/layout_tests/fast/dom/NodeList/item-by-id-with-no-document.html
-/sdcard/android/layout_tests/fast/dom/NodeList/nodelist-item-with-name.html
-/sdcard/android/layout_tests/fast/dom/DOMImplementation/createDocument-namespace-err.html
-/sdcard/android/layout_tests/fast/dom/DOMImplementation/createDocumentType-err.html
-/sdcard/android/layout_tests/fast/dom/CSSStyleDeclaration/transition-property-names.html
-/sdcard/android/layout_tests/fast/dom/CSSStyleDeclaration/css-properties-case-sensitive.html
-/sdcard/android/layout_tests/fast/dom/CSSStyleDeclaration/empty-string-property.html
-/sdcard/android/layout_tests/fast/dom/Node/normalize.html
-/sdcard/android/layout_tests/fast/dom/Node/initial-values.html
-/sdcard/android/layout_tests/fast/dom/Node/DOMNodeRemovedEvent.html
-/sdcard/android/layout_tests/fast/dom/SelectorAPI/viewless-document.html
-/sdcard/android/layout_tests/fast/dom/SelectorAPI/caseID-almost-strict.html
-/sdcard/android/layout_tests/fast/dom/SelectorAPI/elementRoot.html
-/sdcard/android/layout_tests/fast/dom/SelectorAPI/caseID-strict.html
-/sdcard/android/layout_tests/fast/dom/SelectorAPI/not-supported-namespace-in-selector.html
-/sdcard/android/layout_tests/fast/dom/SelectorAPI/id-fastpath.html
-/sdcard/android/layout_tests/fast/dom/SelectorAPI/dumpNodeList.html
-/sdcard/android/layout_tests/fast/dom/SelectorAPI/caseTag.html
-/sdcard/android/layout_tests/fast/dom/SelectorAPI/undefined-null-stringify.html
-/sdcard/android/layout_tests/fast/dom/SelectorAPI/detached-element.html
-/sdcard/android/layout_tests/fast/dom/SelectorAPI/caseID.html
-/sdcard/android/layout_tests/fast/dom/SelectorAPI/bug-17313.html
-/sdcard/android/layout_tests/fast/dom/SelectorAPI/id-fastpath-almost-strict.html
-/sdcard/android/layout_tests/fast/dom/SelectorAPI/id-fastpath-strict.html
-/sdcard/android/layout_tests/fast/dom/SelectorAPI/dumpNodeList-almost-strict.html
-/sdcard/android/layout_tests/fast/dom/HTMLTableSectionElement/rows.html
-/sdcard/android/layout_tests/fast/dom/HTMLInputElement/checked-pseudo-selector.html
-/sdcard/android/layout_tests/fast/dom/HTMLInputElement/input-text-reset.html
-/sdcard/android/layout_tests/fast/dom/HTMLInputElement/size-as-number.html
-/sdcard/android/layout_tests/fast/dom/HTMLInputElement/duplicate-element-names.html
-/sdcard/android/layout_tests/fast/dom/HTMLInputElement/input-hidden-value.html
-/sdcard/android/layout_tests/fast/dom/HTMLInputElement/input-checked-reset.html
-/sdcard/android/layout_tests/fast/dom/HTMLInputElement/size-attribute.html
-/sdcard/android/layout_tests/fast/dom/getElementsByClassName/array/001.html
-/sdcard/android/layout_tests/fast/dom/getElementsByClassName/array/002.html
-/sdcard/android/layout_tests/fast/dom/getElementsByClassName/array/003.html
-/sdcard/android/layout_tests/fast/dom/getElementsByClassName/array/004.html
-/sdcard/android/layout_tests/fast/dom/getElementsByClassName/002.html
-/sdcard/android/layout_tests/fast/dom/getElementsByClassName/012.html
-/sdcard/android/layout_tests/fast/dom/getElementsByClassName/004.html
-/sdcard/android/layout_tests/fast/dom/getElementsByClassName/014.html
-/sdcard/android/layout_tests/fast/dom/getElementsByClassName/006.html
-/sdcard/android/layout_tests/fast/dom/getElementsByClassName/008.html
-/sdcard/android/layout_tests/fast/dom/getElementsByClassName/dumpNodeList.html
-/sdcard/android/layout_tests/fast/dom/getElementsByClassName/001.html
-/sdcard/android/layout_tests/fast/dom/getElementsByClassName/003.html
-/sdcard/android/layout_tests/fast/dom/getElementsByClassName/013.html
-/sdcard/android/layout_tests/fast/dom/getElementsByClassName/005.html
-/sdcard/android/layout_tests/fast/dom/getElementsByClassName/015.html
-/sdcard/android/layout_tests/fast/dom/getElementsByClassName/007.html
-/sdcard/android/layout_tests/fast/dom/getElementsByClassName/009.html
-/sdcard/android/layout_tests/fast/dom/TreeWalker/TreeWalker-currentNode.html
-/sdcard/android/layout_tests/fast/dom/HTMLDivElement/align/getset.html
-/sdcard/android/layout_tests/fast/dom/Text/replaceWholeText.html
-/sdcard/android/layout_tests/fast/dom/HTMLFormElement/adopt-assertion.html
-/sdcard/android/layout_tests/fast/dom/HTMLFormElement/document-deactivation-callback-crash.html
-/sdcard/android/layout_tests/fast/dom/HTMLFormElement/htmlformelement-indexed-getter.html
-/sdcard/android/layout_tests/fast/dom/HTMLFormElement/elements-not-in-document.html
-/sdcard/android/layout_tests/fast/dom/Window/Location/window-override-window-using-defineGetter.html
-/sdcard/android/layout_tests/fast/dom/Window/Location/window-override-location-using-defineGetter.html
-/sdcard/android/layout_tests/fast/dom/Window/Location/location-override-valueOf-using-with.html
-/sdcard/android/layout_tests/fast/dom/Window/Location/location-override-valueOf-on-proto-using-defineGetter.html
-/sdcard/android/layout_tests/fast/dom/Window/Location/window-shadow-location-using-string.html
-/sdcard/android/layout_tests/fast/dom/Window/Location/location-override-valueOf-on-proto-using-with.html
-/sdcard/android/layout_tests/fast/dom/Window/Location/location-override-toString.html
-/sdcard/android/layout_tests/fast/dom/Window/Location/location-override-valueOf-on-proto.html
-/sdcard/android/layout_tests/fast/dom/Window/Location/window-shadow-window-using-js-object-with-location-field.html
-/sdcard/android/layout_tests/fast/dom/Window/Location/window-shadow-location-using-js-object-with-toString.html
-/sdcard/android/layout_tests/fast/dom/Window/Location/location-override-toString-using-defineGetter.html
-/sdcard/android/layout_tests/fast/dom/Window/Location/location-override-valueOf.html
-/sdcard/android/layout_tests/fast/dom/Window/Location/location-override-toString-using-with.html
-/sdcard/android/layout_tests/fast/dom/Window/Location/location-override-toString-on-proto-using-defineGetter.html
-/sdcard/android/layout_tests/fast/dom/Window/Location/location-override-toString-on-proto-using-with.html
-/sdcard/android/layout_tests/fast/dom/Window/Location/location-override-toString-on-proto.html
-/sdcard/android/layout_tests/fast/dom/Window/Location/location-override-valueOf-using-defineGetter.html
-/sdcard/android/layout_tests/fast/dom/Window/window-closed-crash.html
-/sdcard/android/layout_tests/fast/dom/Window/window-function-name-getter-precedence.html
-/sdcard/android/layout_tests/fast/dom/Window/window-open-self.html
-/sdcard/android/layout_tests/fast/dom/Window/console-functions.html
-/sdcard/android/layout_tests/fast/dom/Window/window-postmessage-args.html
-/sdcard/android/layout_tests/fast/dom/Window/attr-constructor.html
-/sdcard/android/layout_tests/fast/dom/Window/window-remove-event-listener.html
-/sdcard/android/layout_tests/fast/dom/Window/window-frames-self-referential.html
-/sdcard/android/layout_tests/fast/dom/Window/redirect-with-timer.html
-/sdcard/android/layout_tests/fast/dom/Window/setting-properties-on-closed-window.html
-/sdcard/android/layout_tests/fast/dom/Window/window-open-parent.html
-/sdcard/android/layout_tests/fast/dom/Window/window-access-after-navigation.html
-/sdcard/android/layout_tests/fast/dom/Window/window-appendages-cleared.html
-/sdcard/android/layout_tests/fast/dom/Window/window-special-properties.html
-/sdcard/android/layout_tests/fast/dom/Window/window-custom-prototype.html
-/sdcard/android/layout_tests/fast/dom/Window/window-collection-length-no-crash.html
-/sdcard/android/layout_tests/fast/dom/Window/setTimeout-no-arguments.html
-/sdcard/android/layout_tests/fast/dom/Window/getMatchedCSSRules-null-crash.html
-/sdcard/android/layout_tests/fast/dom/Window/window-open-self-from-other-frame.html
-/sdcard/android/layout_tests/fast/dom/Window/window-custom-prototype-crash.html
-/sdcard/android/layout_tests/fast/dom/Window/setTimeout-string-argument.html
-/sdcard/android/layout_tests/fast/dom/Window/window-object-cross-frame-calls.html
-/sdcard/android/layout_tests/fast/dom/Window/window-location-replace-functions.html
-/sdcard/android/layout_tests/fast/dom/Window/dispatchEvent.html
-/sdcard/android/layout_tests/fast/dom/Window/window-function-frame-getter-precedence.html
-/sdcard/android/layout_tests/fast/dom/Window/atob-btoa.html
-/sdcard/android/layout_tests/fast/dom/Window/clear-timeout.html
-/sdcard/android/layout_tests/fast/dom/Window/window-early-properties-xhr.html
-/sdcard/android/layout_tests/fast/dom/Window/window-property-clearing.html
-/sdcard/android/layout_tests/fast/dom/Window/element-constructors-on-window.html
-/sdcard/android/layout_tests/fast/dom/Window/orphaned-frame-access.html
-/sdcard/android/layout_tests/fast/dom/Window/window-open-pending-url.html
-/sdcard/android/layout_tests/fast/dom/Window/window-resize-and-move-sub-frame.html
-/sdcard/android/layout_tests/fast/dom/Window/console-trace.html
-/sdcard/android/layout_tests/fast/dom/Window/alert-undefined.html
-/sdcard/android/layout_tests/fast/dom/Window/window-open-top.html
-/sdcard/android/layout_tests/fast/dom/Window/global-opener-function.html
-/sdcard/android/layout_tests/fast/dom/Window/window-property-shadowing.html
-/sdcard/android/layout_tests/fast/dom/Window/remove-timeout-crash.html
-/sdcard/android/layout_tests/fast/dom/Window/customized-property-survives-gc.html
-/sdcard/android/layout_tests/fast/dom/Window/timeout-callback-scope.html
-/sdcard/android/layout_tests/fast/dom/Window/window-property-shadowing-name.html
-/sdcard/android/layout_tests/fast/dom/Window/window-open-parent-no-parent.html
-/sdcard/android/layout_tests/fast/dom/Window/closure-access-after-navigation-iframe.html
-/sdcard/android/layout_tests/fast/dom/HTMLTableRowElement/cells.html
-/sdcard/android/layout_tests/fast/dom/HTMLTableRowElement/insertCell.html
-/sdcard/android/layout_tests/fast/dom/HTMLFontElement/size-attribute.html
-/sdcard/android/layout_tests/fast/dom/HTMLObjectElement/form/test1.html
-/sdcard/android/layout_tests/fast/dom/HTMLObjectElement/object-as-frame.html
-/sdcard/android/layout_tests/fast/dom/HTMLElement/innerHTML-selection-crash.html
-/sdcard/android/layout_tests/fast/dom/HTMLElement/set-inner-outer-optimization.html
-/sdcard/android/layout_tests/fast/dom/Range/compareBoundaryPoints-1.html
-/sdcard/android/layout_tests/fast/dom/Range/range-compareNode.html
-/sdcard/android/layout_tests/fast/dom/Range/range-comparePoint.html
-/sdcard/android/layout_tests/fast/dom/Range/acid3-surround-contents.html
-/sdcard/android/layout_tests/fast/dom/Range/mutation.html
-/sdcard/android/layout_tests/fast/dom/Range/deleted-range-endpoints.html
-/sdcard/android/layout_tests/fast/dom/Range/13000.html
-/sdcard/android/layout_tests/fast/dom/Range/range-processing-instructions.html
-/sdcard/android/layout_tests/fast/dom/Range/range-insertNode-separate-endContainer.html
-/sdcard/android/layout_tests/fast/dom/Range/range-intersectsNode.html
-/sdcard/android/layout_tests/fast/dom/Range/range-isPointInRange.html
-/sdcard/android/layout_tests/fast/dom/Range/compareBoundaryPoints-2.html
-/sdcard/android/layout_tests/fast/dom/Range/range-clone-empty.html
-/sdcard/android/layout_tests/fast/dom/Range/range-modifycontents.html
-/sdcard/android/layout_tests/fast/dom/Range/bug-19527.html
-/sdcard/android/layout_tests/fast/dom/Range/range-insertNode-splittext.html
-/sdcard/android/layout_tests/fast/dom/Range/surroundContents-check-boundary-points.html
-/sdcard/android/layout_tests/fast/dom/Range/range-exceptions.html
-/sdcard/android/layout_tests/fast/dom/HTMLHeadElement/head-check.html
-/sdcard/android/layout_tests/fast/dom/HTMLHtmlElement/set-version.html
-/sdcard/android/layout_tests/fast/dom/HTMLHtmlElement/duplicate-html-element-crash.html
-/sdcard/android/layout_tests/fast/dom/HTMLImageElement/image-lowsrc-getset.html
-/sdcard/android/layout_tests/fast/dom/HTMLImageElement/image-src-absolute-url.html
-/sdcard/android/layout_tests/fast/dom/HTMLImageElement/image-loading-gc.html
-/sdcard/android/layout_tests/fast/dom/HTMLImageElement/image-longdesc-absolute-url.html
-/sdcard/android/layout_tests/fast/dom/HTMLImageElement/constructor-mutation-event-dispatch.html
-/sdcard/android/layout_tests/fast/dom/HTMLImageElement/image-load-cross-document.html
-/sdcard/android/layout_tests/fast/dom/HTMLImageElement/image-without-renderer-width.html
-/sdcard/android/layout_tests/fast/dom/HTMLImageElement/image-natural-width-height.html
-/sdcard/android/layout_tests/fast/dom/StyleSheet/ownerNode-lifetime.html
-/sdcard/android/layout_tests/fast/dom/EntityReference/readonly-exceptions.html
-/sdcard/android/layout_tests/fast/dom/script-element-remove-self.html
-/sdcard/android/layout_tests/fast/dom/remove-named-attribute-crash.html
-/sdcard/android/layout_tests/fast/dom/style-sheet-candidate-remove-unrendered-document.html
-/sdcard/android/layout_tests/fast/dom/node-item.html
-/sdcard/android/layout_tests/fast/dom/clone-node-style.html
-/sdcard/android/layout_tests/fast/dom/script-element-without-frame-crash.html
-/sdcard/android/layout_tests/fast/dom/script-element-gc.html
-/sdcard/android/layout_tests/fast/dom/empty-hash-and-search.html
-/sdcard/android/layout_tests/fast/dom/duplicate-ids.html
-/sdcard/android/layout_tests/fast/dom/prototypes.html
-/sdcard/android/layout_tests/fast/dom/clone-node-form-elements.html
-/sdcard/android/layout_tests/fast/dom/import-attribute-node.html
-/sdcard/android/layout_tests/fast/dom/getter-on-window-object2.html
-/sdcard/android/layout_tests/fast/dom/objc-big-method-name.html
-/sdcard/android/layout_tests/fast/dom/importNode-prefix.html
-/sdcard/android/layout_tests/fast/dom/css-dom-read.html
-/sdcard/android/layout_tests/fast/dom/image-object.html
-/sdcard/android/layout_tests/fast/dom/gc-5.html
-/sdcard/android/layout_tests/fast/dom/cssTarget-crash.html
-/sdcard/android/layout_tests/fast/dom/DOMParser-assign-variable.html
-/sdcard/android/layout_tests/fast/dom/offset-parent-positioned-and-inline.html
-/sdcard/android/layout_tests/fast/dom/timer-clear-interval-in-handler.html
-/sdcard/android/layout_tests/fast/dom/implementation-createHTMLDocument.html
-/sdcard/android/layout_tests/fast/dom/iframe-document.html
-/sdcard/android/layout_tests/fast/dom/document-all-input.html
-/sdcard/android/layout_tests/fast/dom/getelementsbytagnamens-mixed-namespaces.html
-/sdcard/android/layout_tests/fast/dom/object-plugin-hides-properties.html
-/sdcard/android/layout_tests/fast/dom/gc-2.html
-/sdcard/android/layout_tests/fast/dom/computed-style-set-property.html
-/sdcard/android/layout_tests/fast/dom/inner-text-001.html
-/sdcard/android/layout_tests/fast/dom/css-selectorText.html
-/sdcard/android/layout_tests/fast/dom/replace-first-child.html
-/sdcard/android/layout_tests/fast/dom/select-selectedIndex-multiple.html
-/sdcard/android/layout_tests/fast/dom/importNode-null.html
-/sdcard/android/layout_tests/fast/dom/space-to-text.html
-/sdcard/android/layout_tests/fast/dom/css-set-property-exception.html
-/sdcard/android/layout_tests/fast/dom/java-applet-calls.html
-/sdcard/android/layout_tests/fast/dom/plugin-attributes-enumeration.html
-/sdcard/android/layout_tests/fast/dom/html-attribute-types.html
-/sdcard/android/layout_tests/fast/dom/resource-locations-in-created-html-document.html
-/sdcard/android/layout_tests/fast/dom/comment-document-fragment.html
-/sdcard/android/layout_tests/fast/dom/createAttribute-exception.html
-/sdcard/android/layout_tests/fast/dom/noscript-style.html
-/sdcard/android/layout_tests/fast/dom/serialize-cdata.html
-/sdcard/android/layout_tests/fast/dom/createDocument.html
-/sdcard/android/layout_tests/fast/dom/getelementbyname-invalidation.html
-/sdcard/android/layout_tests/fast/dom/setAttributeNS-empty-namespace.html
-/sdcard/android/layout_tests/fast/dom/capturing-event-listeners.html
-/sdcard/android/layout_tests/fast/dom/title-text-property.html
-/sdcard/android/layout_tests/fast/dom/null-page-show-modal-dialog-crash.html
-/sdcard/android/layout_tests/fast/dom/incompatible-operations.html
-/sdcard/android/layout_tests/fast/dom/inner-text-rtl.html
-/sdcard/android/layout_tests/fast/dom/createDocument-empty.html
-/sdcard/android/layout_tests/fast/dom/documenturi-assigned-junk-implies-baseuri-null.html
-/sdcard/android/layout_tests/fast/dom/option-properties.html
-/sdcard/android/layout_tests/fast/dom/background-shorthand-csstext.html
-/sdcard/android/layout_tests/fast/dom/Range-insertNode-crash.html
-/sdcard/android/layout_tests/fast/dom/NamedNodeMap-setNamedItem-crash.html
-/sdcard/android/layout_tests/fast/dom/early-frame-url.html
-/sdcard/android/layout_tests/fast/dom/everything-to-string.html
-/sdcard/android/layout_tests/fast/dom/attribute-empty-value-no-children.html
-/sdcard/android/layout_tests/fast/dom/length-attribute-mapping.html
-/sdcard/android/layout_tests/fast/dom/documenturi-loses-to-base-tag.html
-/sdcard/android/layout_tests/fast/dom/createDocumentType2.html
-/sdcard/android/layout_tests/fast/dom/gc-6.html
-/sdcard/android/layout_tests/fast/dom/attribute-case-sensitivity.html
-/sdcard/android/layout_tests/fast/dom/compatMode-Compat.html
-/sdcard/android/layout_tests/fast/dom/namespaces-1.html
-/sdcard/android/layout_tests/fast/dom/getter-on-window-object.html
-/sdcard/android/layout_tests/fast/dom/constructors-overriding.html
-/sdcard/android/layout_tests/fast/dom/defaultView.html
-/sdcard/android/layout_tests/fast/dom/collection-null-like-arguments.html
-/sdcard/android/layout_tests/fast/dom/gc-3.html
-/sdcard/android/layout_tests/fast/dom/event-attribute-availability.html
-/sdcard/android/layout_tests/fast/dom/select-selectedIndex.html
-/sdcard/android/layout_tests/fast/dom/compatMode-Strict.html
-/sdcard/android/layout_tests/fast/dom/attribute-downcast-right.html
-/sdcard/android/layout_tests/fast/dom/document-all-select.html
-/sdcard/android/layout_tests/fast/dom/wrapper-context.html
-/sdcard/android/layout_tests/fast/dom/anchor-backslash.html
-/sdcard/android/layout_tests/fast/dom/css-mediarule-functions.html
-/sdcard/android/layout_tests/fast/dom/gc-acid3.html
-/sdcard/android/layout_tests/fast/dom/duplicate-ids-document-order.html
-/sdcard/android/layout_tests/fast/dom/exception-no-frame-inline-script-crash.html
-/sdcard/android/layout_tests/fast/dom/XMLSerializer-doctype2.html
-/sdcard/android/layout_tests/fast/dom/dir-no-body.html
-/sdcard/android/layout_tests/fast/dom/null-document-window-open-crash.html
-/sdcard/android/layout_tests/fast/dom/css-RGBValue.html
-/sdcard/android/layout_tests/fast/dom/documentElement-null.html
-/sdcard/android/layout_tests/fast/dom/innerHTML-nbsp.html
-/sdcard/android/layout_tests/fast/dom/createElementNS-empty-namespace.html
-/sdcard/android/layout_tests/fast/dom/class-all-whitespace.html
-/sdcard/android/layout_tests/fast/dom/wrapper-identity.html
-/sdcard/android/layout_tests/fast/dom/null-document-location-assign-crash.html
-/sdcard/android/layout_tests/fast/dom/createElement.html
-/sdcard/android/layout_tests/fast/dom/createElement-with-column.xml
-/sdcard/android/layout_tests/fast/dom/simultaneouslyRegsiteredTimerFireOrder.html
-/sdcard/android/layout_tests/fast/dom/clone-node-form-elements-with-attr.html
-/sdcard/android/layout_tests/fast/dom/setAttributeNS.html
-/sdcard/android/layout_tests/fast/dom/anchor-toString.html
-/sdcard/android/layout_tests/fast/dom/dom-add-optionelement.html
-/sdcard/android/layout_tests/fast/dom/location-assign.html
-/sdcard/android/layout_tests/fast/dom/documenturi-affects-relative-paths.html
-/sdcard/android/layout_tests/fast/dom/javascript-backslash.html
-/sdcard/android/layout_tests/fast/dom/setAttribute-using-initial-input-value.html
-/sdcard/android/layout_tests/fast/dom/css-shortHands.html
-/sdcard/android/layout_tests/fast/dom/generic-form-element-assert.html
-/sdcard/android/layout_tests/fast/dom/dom-instanceof.html
-/sdcard/android/layout_tests/fast/dom/array-special-accessors-should-ignore-items.html
-/sdcard/android/layout_tests/fast/dom/element-attribute-js-null.html
-/sdcard/android/layout_tests/fast/dom/css-dom-read-2.html
-/sdcard/android/layout_tests/fast/dom/navigator-cookieEnabled-no-crash.html
-/sdcard/android/layout_tests/fast/dom/import-document-fragment.html
-/sdcard/android/layout_tests/fast/dom/setter-type-enforcement.html
-/sdcard/android/layout_tests/fast/dom/XMLSerializer.html
-/sdcard/android/layout_tests/fast/dom/navigator-vendorSub.html
-/sdcard/android/layout_tests/fast/dom/outerText-no-element.html
-/sdcard/android/layout_tests/fast/dom/replace-child-siblings.html
-/sdcard/android/layout_tests/fast/dom/xmlhttprequest-constructor-in-detached-document.html
-/sdcard/android/layout_tests/fast/dom/constants.html
-/sdcard/android/layout_tests/fast/dom/inner-text-with-no-renderer.html
-/sdcard/android/layout_tests/fast/dom/gc-7.html
-/sdcard/android/layout_tests/fast/dom/onerror-img.html
-/sdcard/android/layout_tests/fast/dom/document-attribute-js-null.html
-/sdcard/android/layout_tests/fast/dom/css-element-attribute-js-null.html
-/sdcard/android/layout_tests/fast/dom/gc-11.html
-/sdcard/android/layout_tests/fast/dom/mutation-event-remove-inserted-node.html
-/sdcard/android/layout_tests/fast/dom/constructors-cached.html
-/sdcard/android/layout_tests/fast/dom/null-chardata-crash.html
-/sdcard/android/layout_tests/fast/dom/compatMode-AlmostStrict.html
-/sdcard/android/layout_tests/fast/dom/createElement-with-column.html
-/sdcard/android/layout_tests/fast/dom/exception-no-frame-timeout-crash.html
-/sdcard/android/layout_tests/fast/dom/title-text-property-2.html
-/sdcard/android/layout_tests/fast/dom/no-elements.html
-/sdcard/android/layout_tests/fast/dom/non-numeric-values-numeric-parameters.html
-/sdcard/android/layout_tests/fast/dom/gc-4.html
-/sdcard/android/layout_tests/fast/dom/inner-width-height.html
-/sdcard/android/layout_tests/fast/dom/XMLSerializer-doctype.html
-/sdcard/android/layout_tests/fast/dom/createElementNS.html
-/sdcard/android/layout_tests/fast/dom/undetectable-document-all.html
-/sdcard/android/layout_tests/fast/dom/prototype-chain.html
-/sdcard/android/layout_tests/fast/dom/gc-1.html
-/sdcard/android/layout_tests/fast/dom/script-add.html
-/sdcard/android/layout_tests/fast/dom/select-selectedIndex-bug-12942.html
-/sdcard/android/layout_tests/fast/dom/text-control-crash-on-select.html
-/sdcard/android/layout_tests/fast/dom/frame-contentWindow-crash.html
-/sdcard/android/layout_tests/fast/dom/document_write_params.html
-/sdcard/android/layout_tests/fast/dom/namednodemap-namelookup.html
-/sdcard/android/layout_tests/fast/dom/null-document-location-replace-crash.html
-/sdcard/android/layout_tests/fast/dom/htmlcollection-detectability.html
-/sdcard/android/layout_tests/fast/dom/documenturi-assigned-junk-implies-relative-urls-do-not-resolve.html
-/sdcard/android/layout_tests/fast/dom/collection-namedItem-via-item.html
-/sdcard/android/layout_tests/fast/dom/set-inner-text-newlines.html
-/sdcard/android/layout_tests/fast/dom/document-dir-property.html
-/sdcard/android/layout_tests/fast/dom/undetectable-style-filter.html
-/sdcard/android/layout_tests/fast/dom/domListEnumeration.html
-/sdcard/android/layout_tests/fast/dom/destroy-selected-radio-button-crash.html
-/sdcard/android/layout_tests/fast/dom/tabindex-clamp.html
-/sdcard/android/layout_tests/fast/dom/iframe-contentWindow-crash.html
-/sdcard/android/layout_tests/fast/dom/comment-dom-node.html
-/sdcard/android/layout_tests/fast/dom/constructors-cached-navigate.html
-/sdcard/android/layout_tests/fast/dom/features.html
-/sdcard/android/layout_tests/fast/dom/canvasContext2d-element-attribute-js-null.html
-/sdcard/android/layout_tests/fast/dom/remove-style-element.html
-/sdcard/android/layout_tests/fast/dom/attribute-namespaces-get-set.html
-/sdcard/android/layout_tests/fast/dom/innerHTML-escaping-attribute.html
-/sdcard/android/layout_tests/fast/dom/null-document-location-put-crash.html
-/sdcard/android/layout_tests/fast/dom/ImageDocument-image-deletion.html
-/sdcard/android/layout_tests/fast/dom/document-scripts.html
-/sdcard/android/layout_tests/fast/dom/cloneNode.html
-/sdcard/android/layout_tests/fast/dom/onload-open.html
-/sdcard/android/layout_tests/fast/gradients/crash-on-remove.html
-/sdcard/android/layout_tests/fast/invalid/test-case-tr-th-td-should-not-close-dl-list.html
-/sdcard/android/layout_tests/fast/invalid/nestedh3s-rapidweaver.html
-/sdcard/android/layout_tests/fast/forms/HTMLOptionElement_selected.html
-/sdcard/android/layout_tests/fast/forms/option-value-and-label.html
-/sdcard/android/layout_tests/fast/forms/menulist-selection-reset.html
-/sdcard/android/layout_tests/fast/forms/ValidityState-customError-001.html
-/sdcard/android/layout_tests/fast/forms/textfield-focus-out.html
-/sdcard/android/layout_tests/fast/forms/willvalidate-000.html
-/sdcard/android/layout_tests/fast/forms/form-data-encoding-normalization-overrun.html
-/sdcard/android/layout_tests/fast/forms/textarea-trailing-newline.html
-/sdcard/android/layout_tests/fast/forms/ValidityState-patternMismatch-002.html
-/sdcard/android/layout_tests/fast/forms/selection-functions.html
-/sdcard/android/layout_tests/fast/forms/select-no-name.html
-/sdcard/android/layout_tests/fast/forms/multiple-selected-options-innerHTML.html
-/sdcard/android/layout_tests/fast/forms/input-named-action-overrides-action-attribute.html
-/sdcard/android/layout_tests/fast/forms/empty-get.html
-/sdcard/android/layout_tests/fast/forms/display-none-in-onchange-keyboard.html
-/sdcard/android/layout_tests/fast/forms/4628409.html
-/sdcard/android/layout_tests/fast/forms/numeric-input-name.html
-/sdcard/android/layout_tests/fast/forms/activate-and-disabled-elements.html
-/sdcard/android/layout_tests/fast/forms/tabs-with-modifiers.html
-/sdcard/android/layout_tests/fast/forms/form-get-multipart2.html
-/sdcard/android/layout_tests/fast/forms/ValidityState-002.html
-/sdcard/android/layout_tests/fast/forms/menulist-no-renderer-onmousedown.html
-/sdcard/android/layout_tests/fast/forms/select-replace-option.html
-/sdcard/android/layout_tests/fast/forms/textarea-setvalue-submit.html
-/sdcard/android/layout_tests/fast/forms/willvalidate-007.html
-/sdcard/android/layout_tests/fast/forms/double-focus.html
-/sdcard/android/layout_tests/fast/forms/ValidityState-valueMissing-004.html
-/sdcard/android/layout_tests/fast/forms/form-data-encoding-2.html
-/sdcard/android/layout_tests/fast/forms/inline-ignored-on-legend.html
-/sdcard/android/layout_tests/fast/forms/focus.html
-/sdcard/android/layout_tests/fast/forms/input-text-enter.html
-/sdcard/android/layout_tests/fast/forms/input-implicit-length-limit.html
-/sdcard/android/layout_tests/fast/forms/element-order.html
-/sdcard/android/layout_tests/fast/forms/ValidityState-customError-002.html
-/sdcard/android/layout_tests/fast/forms/form-post-urlencoded.html
-/sdcard/android/layout_tests/fast/forms/willvalidate-001.html
-/sdcard/android/layout_tests/fast/forms/ValidityState-patternMismatch-003.html
-/sdcard/android/layout_tests/fast/forms/8250.html
-/sdcard/android/layout_tests/fast/forms/var-name-conflict-in-form-event-handler.html
-/sdcard/android/layout_tests/fast/forms/listbox-select-all.html
-/sdcard/android/layout_tests/fast/forms/range-reset.html
-/sdcard/android/layout_tests/fast/forms/select-remove-option.html
-/sdcard/android/layout_tests/fast/forms/onselect-selectall.html
-/sdcard/android/layout_tests/fast/forms/input-select-webkit-user-select-none.html
-/sdcard/android/layout_tests/fast/forms/paste-multiline-text-input.html
-/sdcard/android/layout_tests/fast/forms/textarea-no-scroll-on-blur.html
-/sdcard/android/layout_tests/fast/forms/select-reset-multiple-selections-4-single-selection.html
-/sdcard/android/layout_tests/fast/forms/tab-in-input.html
-/sdcard/android/layout_tests/fast/forms/button-click-DOM.html
-/sdcard/android/layout_tests/fast/forms/submit-nil-value-field-assert.html
-/sdcard/android/layout_tests/fast/forms/domstring-replace-crash.html
-/sdcard/android/layout_tests/fast/forms/select-max-length.html
-/sdcard/android/layout_tests/fast/forms/form-get-multipart3.html
-/sdcard/android/layout_tests/fast/forms/select-out-of-bounds-index.html
-/sdcard/android/layout_tests/fast/forms/selected-index-assert.html
-/sdcard/android/layout_tests/fast/forms/legend-display-none.html
-/sdcard/android/layout_tests/fast/forms/form-collection-lookup.html
-/sdcard/android/layout_tests/fast/forms/autofocus-opera-004.html
-/sdcard/android/layout_tests/fast/forms/select-list-box-mouse-focus.html
-/sdcard/android/layout_tests/fast/forms/willvalidate-008.html
-/sdcard/android/layout_tests/fast/forms/ValidityState-valueMissing-005.html
-/sdcard/android/layout_tests/fast/forms/required-attribute-001.html
-/sdcard/android/layout_tests/fast/forms/select-index-setter.html
-/sdcard/android/layout_tests/fast/forms/option-change-single-selected.html
-/sdcard/android/layout_tests/fast/forms/listbox-scroll-after-options-removed.html
-/sdcard/android/layout_tests/fast/forms/ValidityState-customError-003.html
-/sdcard/android/layout_tests/fast/forms/input-selection-hidden.html
-/sdcard/android/layout_tests/fast/forms/willvalidate-002.html
-/sdcard/android/layout_tests/fast/forms/ValidityState-patternMismatch-004.html
-/sdcard/android/layout_tests/fast/forms/select-set-inner.html
-/sdcard/android/layout_tests/fast/forms/input-appearance-elementFromPoint.html
-/sdcard/android/layout_tests/fast/forms/missing-action.html
-/sdcard/android/layout_tests/fast/forms/listbox-typeahead-empty.html
-/sdcard/android/layout_tests/fast/forms/submit-to-url-fragment.html
-/sdcard/android/layout_tests/fast/forms/autofocus-opera-005.html
-/sdcard/android/layout_tests/fast/forms/willvalidate-009.html
-/sdcard/android/layout_tests/fast/forms/ValidityState-valueMissing-006.html
-/sdcard/android/layout_tests/fast/forms/old-names.html
-/sdcard/android/layout_tests/fast/forms/required-attribute-002.html
-/sdcard/android/layout_tests/fast/forms/add-and-remove-option.html
-/sdcard/android/layout_tests/fast/forms/focus-style-pending.html
-/sdcard/android/layout_tests/fast/forms/textarea-initial-caret-position.html
-/sdcard/android/layout_tests/fast/forms/input-type-change-in-onfocus-mouse.html
-/sdcard/android/layout_tests/fast/forms/mutation-event-recalc.html
-/sdcard/android/layout_tests/fast/forms/slow-click.html
-/sdcard/android/layout_tests/fast/forms/ValidityState-customError-004.html
-/sdcard/android/layout_tests/fast/forms/autofocus-attribute.html
-/sdcard/android/layout_tests/fast/forms/element-by-name.html
-/sdcard/android/layout_tests/fast/forms/willvalidate-003.html
-/sdcard/android/layout_tests/fast/forms/radio-button-no-change-event.html
-/sdcard/android/layout_tests/fast/forms/ValidityState-patternMismatch-005.html
-/sdcard/android/layout_tests/fast/forms/input-maxlength.html
-/sdcard/android/layout_tests/fast/forms/select-reset.html
-/sdcard/android/layout_tests/fast/forms/input-hit-test-border.html
-/sdcard/android/layout_tests/fast/forms/pattern-attribute-001.html
-/sdcard/android/layout_tests/fast/forms/range-default-value.html
-/sdcard/android/layout_tests/fast/forms/shadow-tree-exposure.html
-/sdcard/android/layout_tests/fast/forms/paste-into-textarea.html
-/sdcard/android/layout_tests/fast/forms/radio-no-theme-padding.html
-/sdcard/android/layout_tests/fast/forms/textfield-drag-into-disabled.html
-/sdcard/android/layout_tests/fast/forms/autofocus-opera-006.html
-/sdcard/android/layout_tests/fast/forms/saved-state-adoptNode-crash.html
-/sdcard/android/layout_tests/fast/forms/ValidityState-valueMissing-007.html
-/sdcard/android/layout_tests/fast/forms/radio-check-click-and-drag.html
-/sdcard/android/layout_tests/fast/forms/11423.html
-/sdcard/android/layout_tests/fast/forms/cursor-position.html
-/sdcard/android/layout_tests/fast/forms/input-changing-value.html
-/sdcard/android/layout_tests/fast/forms/willvalidate-004.html
-/sdcard/android/layout_tests/fast/forms/ValidityState-valueMissing-001.html
-/sdcard/android/layout_tests/fast/forms/ValidityState-patternMismatch-006.html
-/sdcard/android/layout_tests/fast/forms/button-in-forms-collection.html
-/sdcard/android/layout_tests/fast/forms/input-delete.html
-/sdcard/android/layout_tests/fast/forms/placeholder-non-textfield.html
-/sdcard/android/layout_tests/fast/forms/option-constructor-selected.html
-/sdcard/android/layout_tests/fast/forms/input-multiple.html
-/sdcard/android/layout_tests/fast/forms/input-zero-height-focus.html
-/sdcard/android/layout_tests/fast/forms/pattern-attribute-002.html
-/sdcard/android/layout_tests/fast/forms/textarea-linewrap-dynamic.html
-/sdcard/android/layout_tests/fast/forms/placeholder-dom-property.html
-/sdcard/android/layout_tests/fast/forms/select-width-font-change.html
-/sdcard/android/layout_tests/fast/forms/text-field-setvalue-crash.html
-/sdcard/android/layout_tests/fast/forms/form-get-multipart.html
-/sdcard/android/layout_tests/fast/forms/autofocus-opera-007.html
-/sdcard/android/layout_tests/fast/forms/select-type-ahead-list-box-no-selection.html
-/sdcard/android/layout_tests/fast/forms/ValidityState-valueMissing-008.html
-/sdcard/android/layout_tests/fast/forms/textarea-crlf.html
-/sdcard/android/layout_tests/fast/forms/remove-radio-button-assert.html
-/sdcard/android/layout_tests/fast/forms/text-set-value-crash.html
-/sdcard/android/layout_tests/fast/forms/autofocus-opera-001.html
-/sdcard/android/layout_tests/fast/forms/select-namedItem.html
-/sdcard/android/layout_tests/fast/forms/willvalidate-005.html
-/sdcard/android/layout_tests/fast/forms/ValidityState-valueMissing-002.html
-/sdcard/android/layout_tests/fast/forms/ValidityState-patternMismatch-007.html
-/sdcard/android/layout_tests/fast/forms/add-remove-option-modification-event.html
-/sdcard/android/layout_tests/fast/forms/input-type-change-in-onfocus-keyboard.html
-/sdcard/android/layout_tests/fast/forms/option-in-optgroup-removal.html
-/sdcard/android/layout_tests/fast/forms/form-data-encoding.html
-/sdcard/android/layout_tests/fast/forms/pattern-attribute-003.html
-/sdcard/android/layout_tests/fast/forms/ValidityState-patternMismatch-001.html
-/sdcard/android/layout_tests/fast/forms/textarea-default-value-leading-newline.html
-/sdcard/android/layout_tests/fast/forms/autofocus-opera-008.html
-/sdcard/android/layout_tests/fast/forms/add-remove-form-elements-stress-test.html
-/sdcard/android/layout_tests/fast/forms/ValidityState-valueMissing-009.html
-/sdcard/android/layout_tests/fast/forms/textarea-setvalue-without-renderer.html
-/sdcard/android/layout_tests/fast/forms/hidden-input-not-enabled.html
-/sdcard/android/layout_tests/fast/forms/input-appearance-maxlength.html
-/sdcard/android/layout_tests/fast/forms/ValidityState-001.html
-/sdcard/android/layout_tests/fast/forms/submit-with-base.html
-/sdcard/android/layout_tests/fast/forms/input-setvalue-selection.html
-/sdcard/android/layout_tests/fast/forms/autofocus-opera-002.html
-/sdcard/android/layout_tests/fast/forms/textarea-appearance-wrap.html
-/sdcard/android/layout_tests/fast/forms/add-selected-option.html
-/sdcard/android/layout_tests/fast/forms/willvalidate-006.html
-/sdcard/android/layout_tests/fast/forms/ValidityState-valueMissing-003.html
-/sdcard/android/layout_tests/fast/forms/textarea-hard-linewrap-empty.html
-/sdcard/android/layout_tests/fast/forms/document-write.html
-/sdcard/android/layout_tests/fast/table/incomplete-table-in-fragment-hang.html
-/sdcard/android/layout_tests/fast/table/section-in-table-before-misnested-text-crash-css.html
-/sdcard/android/layout_tests/fast/table/large-rowspan-crash.html
-/sdcard/android/layout_tests/fast/table/colgroup-relative.html
-/sdcard/android/layout_tests/fast/table/border-changes.html
-/sdcard/android/layout_tests/fast/table/table-row-compositing-repaint-crash.html
-/sdcard/android/layout_tests/fast/table/cell-in-row-before-misnested-text-crash-css.html
-/sdcard/android/layout_tests/fast/table/incomplete-table-in-fragment-2.html
-/sdcard/android/layout_tests/fast/table/rowindex-comment-nodes.html
-/sdcard/android/layout_tests/fast/table/td-display-nowrap.html
-/sdcard/android/layout_tests/fast/table/row-in-tbody-before-misnested-text-crash-css.html
-/sdcard/android/layout_tests/fast/table/empty-auto-column-zero-divide.html
-/sdcard/android/layout_tests/fast/table/form-in-tbody-before-misnested-text-crash-css.html
-/sdcard/android/layout_tests/fast/table/form-in-table-before-misnested-text-crash-css.html
-/sdcard/android/layout_tests/fast/table/destroy-cell-with-selection-crash.html
-/sdcard/android/layout_tests/fast/table/form-in-row-before-misnested-text-crash-css.html
-/sdcard/android/layout_tests/fast/css/counters/counter-function-input-2.html
-/sdcard/android/layout_tests/fast/css/counters/counter-function-input.html
-/sdcard/android/layout_tests/fast/css/counters/counter-number-input.html
-/sdcard/android/layout_tests/fast/css/variables/color-hex-test.html
-/sdcard/android/layout_tests/fast/css/variables/invalid-identifier.html
-/sdcard/android/layout_tests/fast/css/getComputedStyle/computed-style-negative-top.html
-/sdcard/android/layout_tests/fast/css/getComputedStyle/getComputedStyle-borderRadius.html
-/sdcard/android/layout_tests/fast/css/getComputedStyle/getComputedStyle-background-size.html
-/sdcard/android/layout_tests/fast/css/getComputedStyle/getComputedStyle-border-image.html
-/sdcard/android/layout_tests/fast/css/getComputedStyle/getComputedStyle-border-spacing.html
-/sdcard/android/layout_tests/fast/css/getComputedStyle/computed-style-font-family.html
-/sdcard/android/layout_tests/fast/css/getComputedStyle/getComputedStyle-zIndex-auto.html
-/sdcard/android/layout_tests/fast/css/getComputedStyle/getComputedStyle-transform.html
-/sdcard/android/layout_tests/fast/css/getComputedStyle/computed-style-display-none.html
-/sdcard/android/layout_tests/fast/css/getComputedStyle/getComputedStyle-background-position.html
-/sdcard/android/layout_tests/fast/css/getComputedStyle/getComputedStyle-text-overflow.html
-/sdcard/android/layout_tests/fast/css/getComputedStyle/getComputedStyle-border-box.html
-/sdcard/android/layout_tests/fast/css/getComputedStyle/getComputedStyle-relayout.html
-/sdcard/android/layout_tests/fast/css/getComputedStyle/getComputedStyle-text-decoration.html
-/sdcard/android/layout_tests/fast/css/media-rule-dyn.html
-/sdcard/android/layout_tests/fast/css/transform-function-lowercase-assert.html
-/sdcard/android/layout_tests/fast/css/word-break-user-modify-allowed-values.html
-/sdcard/android/layout_tests/fast/css/import-style-update.html
-/sdcard/android/layout_tests/fast/css/outline-invert-assertion.html
-/sdcard/android/layout_tests/fast/css/insertRule-font-face.html
-/sdcard/android/layout_tests/fast/css/readonly-pseudoclass-opera-004.html
-/sdcard/android/layout_tests/fast/css/zoom-in-length-round-trip.html
-/sdcard/android/layout_tests/fast/css/transform-inline-style-remove.html
-/sdcard/android/layout_tests/fast/css/padding-no-renderer.html
-/sdcard/android/layout_tests/fast/css/transition_shorthand_parsing.html
-/sdcard/android/layout_tests/fast/css/css-selector-text.html
-/sdcard/android/layout_tests/fast/css/dashboard-regions-attr-crash.html
-/sdcard/android/layout_tests/fast/css/readonly-pseudoclass-opera-001.html
-/sdcard/android/layout_tests/fast/css/pseudo-required-optional-006.html
-/sdcard/android/layout_tests/fast/css/font-property-priority.html
-/sdcard/android/layout_tests/fast/css/number-parsing-crash.html
-/sdcard/android/layout_tests/fast/css/device-aspect-ratio.html
-/sdcard/android/layout_tests/fast/css/pseudostyle-anonymous-text.html
-/sdcard/android/layout_tests/fast/css/css-properties-case-insensitive.html
-/sdcard/android/layout_tests/fast/css/sheet-collection-link.html
-/sdcard/android/layout_tests/fast/css/pseudo-required-optional-003.html
-/sdcard/android/layout_tests/fast/css/resize-value-compared.html
-/sdcard/android/layout_tests/fast/css/font-face-descriptor-multiple-values-parsing.html
-/sdcard/android/layout_tests/fast/css/hexColor-isDigit-assert.html
-/sdcard/android/layout_tests/fast/css/transform-inline-style.html
-/sdcard/android/layout_tests/fast/css/child-selector-implicit-tbody.html
-/sdcard/android/layout_tests/fast/css/outline-hidden-illegal-value.html
-/sdcard/android/layout_tests/fast/css/emptyStyleTag.html
-/sdcard/android/layout_tests/fast/css/stale-style-selector-crash-1.html
-/sdcard/android/layout_tests/fast/css/display-none-inline-style-change-crash.html
-/sdcard/android/layout_tests/fast/css/getPropertyValue-clip.html
-/sdcard/android/layout_tests/fast/css/border-image-crash.html
-/sdcard/android/layout_tests/fast/css/readonly-pseudoclass-opera-005.html
-/sdcard/android/layout_tests/fast/css/insertRule-media.html
-/sdcard/android/layout_tests/fast/css/html-attr-case-sensitivity.html
-/sdcard/android/layout_tests/fast/css/font-face-multiple-families.html
-/sdcard/android/layout_tests/fast/css/getPropertyValue-border.html
-/sdcard/android/layout_tests/fast/css/readonly-pseudoclass-opera-002.html
-/sdcard/android/layout_tests/fast/css/invalid-rule-value.html
-/sdcard/android/layout_tests/fast/css/max-device-aspect-ratio.html
-/sdcard/android/layout_tests/fast/css/background-currentcolor.html
-/sdcard/android/layout_tests/fast/css/pseudo-required-optional-004.html
-/sdcard/android/layout_tests/fast/css/orphaned_units_crash.html
-/sdcard/android/layout_tests/fast/css/invalid-cursor-property-crash.html
-/sdcard/android/layout_tests/fast/css/sheet-title.html
-/sdcard/android/layout_tests/fast/css/large-list-of-rules-crash.html
-/sdcard/android/layout_tests/fast/css/pseudo-required-optional-001.html
-/sdcard/android/layout_tests/fast/css/background-position-serialize.html
-/sdcard/android/layout_tests/fast/css/stale-style-selector-crash-2.html
-/sdcard/android/layout_tests/fast/css/webkit-marquee-speed-unit-in-quirksmode.html
-/sdcard/android/layout_tests/fast/css/CSSPrimitiveValue-exceptions.html
-/sdcard/android/layout_tests/fast/css/empty-script.html
-/sdcard/android/layout_tests/fast/css/mask-missing-image-crash.html
-/sdcard/android/layout_tests/fast/css/parse-timing-function-crash.html
-/sdcard/android/layout_tests/fast/css/background-position-inherit.html
-/sdcard/android/layout_tests/fast/css/readonly-pseudoclass-opera-003.html
-/sdcard/android/layout_tests/fast/css/font-family-builtins.html
-/sdcard/android/layout_tests/fast/css/remove-shorthand.html
-/sdcard/android/layout_tests/fast/css/overflow-property.html
-/sdcard/android/layout_tests/fast/css/pseudo-required-optional-005.html
-/sdcard/android/layout_tests/fast/css/min-device-aspect-ratio.html
-/sdcard/android/layout_tests/fast/css/nested-rule-parent-sheet.html
-/sdcard/android/layout_tests/fast/css/case-transform.html
-/sdcard/android/layout_tests/fast/css/number-parsing-crash-2.html
-/sdcard/android/layout_tests/fast/css/matrix-as-function-crash.html
-/sdcard/android/layout_tests/fast/css/pseudo-required-optional-002.html
-/sdcard/android/layout_tests/fast/css/attr-parsing.html
-/sdcard/android/layout_tests/fast/css/font-family-initial.html
-/sdcard/android/layout_tests/fast/css/small-caps-crash.html
-/sdcard/android/layout_tests/fast/css/max-height-and-max-width.html
-/sdcard/android/layout_tests/fast/css/legacy-opacity-styles.html
-/sdcard/android/layout_tests/fast/css/transition-timing-function.html
-/sdcard/android/layout_tests/fast/block/positioning/absolute-in-inline-rtl-4.html
-/sdcard/android/layout_tests/fast/block/float/selection-gap-clip-out-tiger-crash.html
-/sdcard/android/layout_tests/fast/block/float/crash-on-absolute-positioning.html
-/sdcard/android/layout_tests/fast/block/float/crash-replaced-display-block.html
-/sdcard/android/layout_tests/fast/parser/implicit-head-in-fragment-crash.html
-/sdcard/android/layout_tests/fast/parser/smart-quotes-in-tag.html
-/sdcard/android/layout_tests/fast/parser/entity-comment-in-iframe.html
-/sdcard/android/layout_tests/fast/parser/remove-node-stack.html
-/sdcard/android/layout_tests/fast/parser/remove-current-node-parent.html
-/sdcard/android/layout_tests/fast/parser/entity-end-iframe-tag.html
-/sdcard/android/layout_tests/fast/parser/nsup-entity.html
-/sdcard/android/layout_tests/fast/parser/block-nesting-cap.html
-/sdcard/android/layout_tests/fast/parser/residual-style-close-across-n-blocks.html
-/sdcard/android/layout_tests/fast/parser/tag-with-exclamation-point.html
-/sdcard/android/layout_tests/fast/parser/p-in-scope-strict.html
-/sdcard/android/layout_tests/fast/parser/entity-end-style-tag.html
-/sdcard/android/layout_tests/fast/parser/entity-end-xmp-tag.html
-/sdcard/android/layout_tests/fast/parser/external-entities.xml
-/sdcard/android/layout_tests/fast/parser/head-comment.html
-/sdcard/android/layout_tests/fast/parser/test-unicode-characters-in-attribute-name.html
-/sdcard/android/layout_tests/fast/parser/entity-end-textarea-tag.html
-/sdcard/android/layout_tests/fast/parser/script-tag-with-trailing-slash.html
-/sdcard/android/layout_tests/fast/parser/empty-text-resource.html
-/sdcard/android/layout_tests/fast/parser/comment-in-title.html
-/sdcard/android/layout_tests/fast/parser/residual-style-close-across-removed-block.html
-/sdcard/android/layout_tests/fast/parser/entity-comment-in-title.html
-/sdcard/android/layout_tests/fast/parser/entity-end-title-tag.html
-/sdcard/android/layout_tests/fast/parser/head-content-after-head-removal.html
-/sdcard/android/layout_tests/fast/parser/pre-first-line-break.html
-/sdcard/android/layout_tests/fast/parser/number-sign-in-map-name.html
-/sdcard/android/layout_tests/fast/parser/input-textarea-inside-select-element.html
-/sdcard/android/layout_tests/fast/parser/entity-end-script-tag.html
-/sdcard/android/layout_tests/fast/parser/area-in-div.html
-/sdcard/android/layout_tests/fast/parser/entity-surrogate-pairs.html
-/sdcard/android/layout_tests/fast/parser/eightdigithexentity.html
-/sdcard/android/layout_tests/fast/parser/parse-wbr.html
-/sdcard/android/layout_tests/fast/parser/open-comment-in-script-tricky.html
-/sdcard/android/layout_tests/fast/parser/head-element-for-yahoo-player.html
-/sdcard/android/layout_tests/fast/parser/hex-entities-length.html
-/sdcard/android/layout_tests/fast/parser/html-whitespace.html
-/sdcard/android/layout_tests/fast/parser/script-after-frameset-assert.html
-/sdcard/android/layout_tests/fast/parser/comment-in-iframe.html
-/sdcard/android/layout_tests/fast/parser/duplicate-html-body-element-IDs.html
-/sdcard/android/layout_tests/fast/parser/assertion-empty-attribute.html
-/sdcard/android/layout_tests/fast/parser/comment-in-script-tricky.html
-/sdcard/android/layout_tests/fast/parser/rewrite-form.html
-/sdcard/android/layout_tests/fast/parser/entity-comment-in-script-tricky.html
-/sdcard/android/layout_tests/fast/parser/head-parsing-19517.html
-/sdcard/android/layout_tests/fast/parser/entities-in-html.html
-/sdcard/android/layout_tests/fast/parser/remove-parser-current-node.html
-/sdcard/android/layout_tests/fast/parser/rewrite-map.html
-/sdcard/android/layout_tests/fast/parser/strict-img-in-map.html
-/sdcard/android/layout_tests/fast/parser/p-in-scope.html
-/sdcard/android/layout_tests/fast/layers/removed-by-scroll-handler.html
-/sdcard/android/layout_tests/fast/layers/generated-layer-scrollbar-crash.html
-/sdcard/android/layout_tests/fast/layers/zindex-hit-test.html
-/sdcard/android/layout_tests/fast/layers/resize-layer-deletion-crash.html
-/sdcard/android/layout_tests/fast/history/subframe-is-visited.html
-/sdcard/android/layout_tests/fast/loader/early-load-cancel.html
-/sdcard/android/layout_tests/fast/loader/iframe-recursive-synchronous-load.html
-/sdcard/android/layout_tests/fast/loader/local-css-allowed-in-strict-mode.html
-/sdcard/android/layout_tests/fast/loader/url-strip-cr-lf-tab.html
-/sdcard/android/layout_tests/fast/loader/hashchange-event.html
-/sdcard/android/layout_tests/fast/loader/unloadable-script.html
-/sdcard/android/layout_tests/fast/loader/url-parse-1.html
-/sdcard/android/layout_tests/fast/loader/redirect-with-open-subframe-2.html
-/sdcard/android/layout_tests/fast/loader/simultaneous-reloads-assert.html
-/sdcard/android/layout_tests/fast/loader/invalid-charset-on-script-crashes-loader.html
-/sdcard/android/layout_tests/fast/loader/javascript-url-encoding.html
-/sdcard/android/layout_tests/fast/loader/empty-embed-src-attribute.html
-/sdcard/android/layout_tests/fast/loader/charset-parse.html
-/sdcard/android/layout_tests/fast/loader/meta-refresh-vs-open.html
-/sdcard/android/layout_tests/fast/loader/submit-form-while-parsing-2.html
-/sdcard/android/layout_tests/fast/loader/url-data-replace-backslash.html
-/sdcard/android/layout_tests/fast/loader/redirect-with-open-subframe.html
-/sdcard/android/layout_tests/fast/loader/empty-ref-versus-no-ref.html
-/sdcard/android/layout_tests/fast/loader/javascript-url-encoding-2.html
-/sdcard/android/layout_tests/fast/loader/window-clearing.html
-/sdcard/android/layout_tests/fast/loader/frame-creation-removal.html
-/sdcard/android/layout_tests/fast/loader/external-script-URL-location.html
-/sdcard/android/layout_tests/fast/loader/link-no-URL.html
-/sdcard/android/layout_tests/fast/loader/loadInProgress.html
-/sdcard/android/layout_tests/fast/loader/inherit-charset-to-empty-frame.html
-/sdcard/android/layout_tests/fast/loader/font-face-empty.html
-/sdcard/android/layout_tests/fast/loader/goto-anchor-infinite-layout.html
-/sdcard/android/layout_tests/fast/loader/file-URL-with-port-number.html
-/sdcard/android/layout_tests/fast/xmlhttprequest/xmlhttprequest-default-attributes.html
-/sdcard/android/layout_tests/fast/xmlhttprequest/xmlhttprequest-missing-file-exception.html
-/sdcard/android/layout_tests/fast/xmlhttprequest/xmlhttprequest-invalid-values.html
-/sdcard/android/layout_tests/fast/xmlhttprequest/xmlhttprequest-html-response-encoding.html
-/sdcard/android/layout_tests/fast/xmlhttprequest/null-document-xmlhttprequest-open.html
-/sdcard/android/layout_tests/fast/xmlhttprequest/xmlhttprequest-nonexistent-file.html
-/sdcard/android/layout_tests/fast/xmlhttprequest/xmlhttprequest-open-after-iframe-onload-remove-self.html
-/sdcard/android/layout_tests/fast/canvas/pattern-with-transform.html
-/sdcard/android/layout_tests/fast/canvas/gradient-addColorStop-with-invalid-color.html
-/sdcard/android/layout_tests/fast/canvas/canvas-gradient-without-path.html
-/sdcard/android/layout_tests/fast/canvas/radialGradient-infinite-values.html
-/sdcard/android/layout_tests/fast/canvas/drawImage-with-negative-source-destination.html
-/sdcard/android/layout_tests/fast/canvas/drawImage-with-invalid-args.html
-/sdcard/android/layout_tests/fast/canvas/canvas-stroke-empty-fill.html
-/sdcard/android/layout_tests/fast/canvas/canvas-lineWidth.html
-/sdcard/android/layout_tests/fast/canvas/access-zero-sized-canvas.html
-/sdcard/android/layout_tests/fast/canvas/script-inside-canvas-fallback.html
-/sdcard/android/layout_tests/fast/canvas/unclosed-canvas-2.html
-/sdcard/android/layout_tests/fast/canvas/create-pattern-does-not-crash.html
-/sdcard/android/layout_tests/fast/canvas/gradient-with-clip.html
-/sdcard/android/layout_tests/fast/canvas/canvas-hides-fallback.html
-/sdcard/android/layout_tests/fast/canvas/arc-crash.html
-/sdcard/android/layout_tests/fast/canvas/canvas-modify-emptyPath.html
-/sdcard/android/layout_tests/fast/canvas/unclosed-canvas-4.html
-/sdcard/android/layout_tests/fast/canvas/canvas-invalid-fillstyle.html
-/sdcard/android/layout_tests/fast/canvas/unclosed-canvas-1.html
-/sdcard/android/layout_tests/fast/canvas/toDataURL-noData.html
-/sdcard/android/layout_tests/fast/canvas/canvas-with-incorrect-args.html
-/sdcard/android/layout_tests/fast/canvas/canvas-path-with-inf-nan-dimensions.html
-/sdcard/android/layout_tests/fast/canvas/canvas-radial-gradient-spreadMethod.html
-/sdcard/android/layout_tests/fast/canvas/canvas-set-properties-with-non-invertible-ctm.html
-/sdcard/android/layout_tests/fast/canvas/canvas-invalid-strokestyle.html
-/sdcard/android/layout_tests/fast/canvas/canvas-strokeRect.html
-/sdcard/android/layout_tests/fast/canvas/canvas-composite-alpha.html
-/sdcard/android/layout_tests/fast/canvas/canvas-transparency-and-composite.html
-/sdcard/android/layout_tests/fast/canvas/unclosed-canvas-3.html
-/sdcard/android/layout_tests/fast/canvas/linearGradient-infinite-values.html
-/sdcard/android/layout_tests/fast/canvas/canvas-setTransform.html
-/sdcard/android/layout_tests/fast/frames/frame-set-same-location.html
-/sdcard/android/layout_tests/fast/frames/viewsource-unfinished-tags.html
-/sdcard/android/layout_tests/fast/frames/set-unloaded-frame-location.html
-/sdcard/android/layout_tests/fast/frames/negative-remaining-length-crash.html
-/sdcard/android/layout_tests/fast/frames/frame-name-reset.html
-/sdcard/android/layout_tests/fast/frames/frame-set-same-src.html
-/sdcard/android/layout_tests/fast/frames/crash-removed-iframe.html
-/sdcard/android/layout_tests/fast/frames/empty-frame-document.html
-/sdcard/android/layout_tests/fast/frames/viewsource-plain-text-tags.html
-/sdcard/android/layout_tests/fast/frames/repaint-display-none-crash.html
-/sdcard/android/layout_tests/fast/frames/remove-frame-with-scrollbars-crash.html
-/sdcard/android/layout_tests/fast/frames/cross-site-this.html
-/sdcard/android/layout_tests/fast/frames/onload-remove-iframe-crash.html
-/sdcard/android/layout_tests/fast/frames/iframe-set-inner-html.html
-/sdcard/android/layout_tests/fast/frames/iframe-remove-after-id-change.html
-/sdcard/android/layout_tests/fast/frames/iframe-target.html
-/sdcard/android/layout_tests/fast/frames/viewsource-link-on-href-value.html
-/sdcard/android/layout_tests/fast/frames/hover-timer-crash.html
-/sdcard/android/layout_tests/fast/frames/iframe-no-src-set-location.html
-/sdcard/android/layout_tests/fast/frames/iframe-set-same-src.html
-/sdcard/android/layout_tests/fast/frames/iframe-double-attach.html
-/sdcard/android/layout_tests/fast/frames/iframe-set-same-location.html
-/sdcard/android/layout_tests/fast/frames/location-change.html
-/sdcard/android/layout_tests/fast/frames/frame-base-url.html
-/sdcard/android/layout_tests/fast/frames/iframe-display-none.html
-/sdcard/android/layout_tests/fast/frames/javascript-url-as-framesrc-crash.html
-/sdcard/android/layout_tests/fast/frames/frame-limit.html
-/sdcard/android/layout_tests/fast/frames/frame-display-none-focus.html
-/sdcard/android/layout_tests/fast/reflections/teardown-crash.html
-/sdcard/android/layout_tests/fast/reflections/reflection-computed-style.html
-/sdcard/android/layout_tests/fast/reflections/reflection-overflow-scroll.html
-/sdcard/android/layout_tests/http/tests/multipart/win-boundary-crash.html
-/sdcard/android/layout_tests/http/tests/multipart/stop-crash.html
-/sdcard/android/layout_tests/http/tests/mime/standard-mode-loads-stylesheet-with-text-css-and-invalid-type.html
-/sdcard/android/layout_tests/http/tests/mime/standard-mode-loads-stylesheet-with-empty-content-type.html
-/sdcard/android/layout_tests/http/tests/mime/standard-mode-loads-stylesheet-with-charset-and-css-extension.html
-/sdcard/android/layout_tests/http/tests/mime/standard-mode-loads-stylesheet-with-charset.html
-/sdcard/android/layout_tests/http/tests/local/style-access-before-stylesheet-loaded.html
-/sdcard/android/layout_tests/http/tests/local/stylesheet-and-script-load-order-http.html
-/sdcard/android/layout_tests/http/tests/local/link-stylesheet-preferred.html
-/sdcard/android/layout_tests/http/tests/local/stylesheet-and-script-load-order.html
-/sdcard/android/layout_tests/http/tests/misc/uncacheable-script-repeated.html
-/sdcard/android/layout_tests/http/tests/misc/embedCrasher.html
-/sdcard/android/layout_tests/http/tests/misc/multiple-submit.html
-/sdcard/android/layout_tests/http/tests/misc/empty-file-formdata.html
-/sdcard/android/layout_tests/http/tests/misc/submit-post-in-utf7.html
-/sdcard/android/layout_tests/http/tests/misc/text-refresh.html
-/sdcard/android/layout_tests/http/tests/misc/window-open-then-write.html
-/sdcard/android/layout_tests/http/tests/misc/submit-post-in-utf16be.html
-/sdcard/android/layout_tests/http/tests/misc/frame-default-enc-same-domain.html
-/sdcard/android/layout_tests/http/tests/misc/submit-post-in-utf32le.html
-/sdcard/android/layout_tests/http/tests/misc/iframe-domain-test.html
-/sdcard/android/layout_tests/http/tests/misc/frame-default-enc-different-domain.html
-/sdcard/android/layout_tests/http/tests/misc/css-accept-any-type.html
-/sdcard/android/layout_tests/http/tests/misc/url-in-utf7.html
-/sdcard/android/layout_tests/http/tests/misc/submit-get-in-utf32be.html
-/sdcard/android/layout_tests/http/tests/misc/meta-refresh-stray-single-quote.html
-/sdcard/android/layout_tests/http/tests/misc/canvas-pattern-from-incremental-image.html
-/sdcard/android/layout_tests/http/tests/misc/submit-get-in-utf16le.html
-/sdcard/android/layout_tests/http/tests/misc/url-in-utf32be.html
-/sdcard/android/layout_tests/http/tests/misc/timer-vs-loading.html
-/sdcard/android/layout_tests/http/tests/misc/font-face-in-multiple-segmented-faces.html
-/sdcard/android/layout_tests/http/tests/misc/url-in-utf16le.html
-/sdcard/android/layout_tests/http/tests/misc/refresh-meta-with-newline.html
-/sdcard/android/layout_tests/http/tests/misc/post-submit-button.html
-/sdcard/android/layout_tests/http/tests/misc/redirect-to-about-blank.html
-/sdcard/android/layout_tests/http/tests/misc/javascript-url-stop-loaders.html
-/sdcard/android/layout_tests/http/tests/misc/iframe-invalid-source-crash.html
-/sdcard/android/layout_tests/http/tests/misc/slow-preload-cancel.html
-/sdcard/android/layout_tests/http/tests/misc/object-image-error-with-onload.html
-/sdcard/android/layout_tests/http/tests/misc/image-error.html
-/sdcard/android/layout_tests/http/tests/misc/referrer.html
-/sdcard/android/layout_tests/http/tests/misc/cached-scripts.html
-/sdcard/android/layout_tests/http/tests/misc/empty-cookie.html
-/sdcard/android/layout_tests/http/tests/misc/submit-post-in-utf32be.html
-/sdcard/android/layout_tests/http/tests/misc/missing-style-sheet.html
-/sdcard/android/layout_tests/http/tests/misc/submit-post-in-utf16le.html
-/sdcard/android/layout_tests/http/tests/misc/submit-get-in-utf16be.html
-/sdcard/android/layout_tests/http/tests/misc/DOMContentLoaded-event.html
-/sdcard/android/layout_tests/http/tests/misc/onload-remove-iframe-crash-2.html
-/sdcard/android/layout_tests/http/tests/misc/submit-get-in-utf32le.html
-/sdcard/android/layout_tests/http/tests/misc/object-image-error.html
-/sdcard/android/layout_tests/http/tests/misc/createElementNamespace3.html
-/sdcard/android/layout_tests/http/tests/misc/url-in-utf16be.html
-/sdcard/android/layout_tests/http/tests/misc/url-in-utf32le.html
-/sdcard/android/layout_tests/http/tests/misc/crash-multiple-family-fontface.html
-/sdcard/android/layout_tests/http/tests/misc/BOM-override-script.html
-/sdcard/android/layout_tests/http/tests/misc/createElementNamespace1.xml
-/sdcard/android/layout_tests/http/tests/workers/text-encoding.html
-/sdcard/android/layout_tests/http/tests/workers/worker-redirect.html
-/sdcard/android/layout_tests/http/tests/workers/worker-importScripts.html
-/sdcard/android/layout_tests/http/tests/cookies/double-quoted-value-with-semi-colon.html
-/sdcard/android/layout_tests/http/tests/uri/resolve-encoding-relative.html
-/sdcard/android/layout_tests/http/tests/uri/escaped-entity.html
-/sdcard/android/layout_tests/http/tests/uri/utf8-path.html
-/sdcard/android/layout_tests/http/tests/navigation/changing-frame-hierarchy-in-onload.html
-/sdcard/android/layout_tests/http/tests/navigation/fallback-anchor-reload.html
-/sdcard/android/layout_tests/http/tests/navigation/back-send-referrer.html
-/sdcard/android/layout_tests/http/tests/incremental/slow-utf8-css.html
-/sdcard/android/layout_tests/http/tests/incremental/frame-focus-before-load.html
-/sdcard/android/layout_tests/http/tests/appcache/crash-when-navigating-away-then-back.html
-/sdcard/android/layout_tests/http/tests/appcache/offline-access.html
-/sdcard/android/layout_tests/http/tests/appcache/update-cache.html
-/sdcard/android/layout_tests/http/tests/appcache/manifest-with-empty-file.html
-/sdcard/android/layout_tests/http/tests/appcache/simple.html
-/sdcard/android/layout_tests/http/tests/appcache/wrong-signature-2.html
-/sdcard/android/layout_tests/http/tests/appcache/top-frame-3.html
-/sdcard/android/layout_tests/http/tests/appcache/online-whitelist.html
-/sdcard/android/layout_tests/http/tests/appcache/fallback.html
-/sdcard/android/layout_tests/http/tests/appcache/different-origin-manifest.html
-/sdcard/android/layout_tests/http/tests/appcache/empty-manifest.html
-/sdcard/android/layout_tests/http/tests/appcache/manifest-redirect.html
-/sdcard/android/layout_tests/http/tests/appcache/navigating-away-while-cache-attempt-in-progress.html
-/sdcard/android/layout_tests/http/tests/appcache/top-frame-4.html
-/sdcard/android/layout_tests/http/tests/appcache/wrong-signature.html
-/sdcard/android/layout_tests/http/tests/appcache/fail-on-update.html
-/sdcard/android/layout_tests/http/tests/appcache/foreign-iframe-main.html
-/sdcard/android/layout_tests/http/tests/appcache/xhr-foreign-resource.html
-/sdcard/android/layout_tests/http/tests/appcache/manifest-containing-itself.html
-/sdcard/android/layout_tests/http/tests/appcache/resource-redirect.html
-/sdcard/android/layout_tests/http/tests/appcache/idempotent-update.html
-/sdcard/android/layout_tests/http/tests/appcache/top-frame-1.html
-/sdcard/android/layout_tests/http/tests/appcache/main-resource-hash.html
-/sdcard/android/layout_tests/http/tests/appcache/manifest-parsing.html
-/sdcard/android/layout_tests/http/tests/appcache/404-manifest.html
-/sdcard/android/layout_tests/http/tests/appcache/wrong-content-type.html
-/sdcard/android/layout_tests/http/tests/appcache/resource-redirect-2.html
-/sdcard/android/layout_tests/http/tests/appcache/top-frame-2.html
-/sdcard/android/layout_tests/http/tests/appcache/404-resource.html
-/sdcard/android/layout_tests/http/tests/appcache/remove-cache.html
-/sdcard/android/layout_tests/http/tests/appcache/manifest-redirect-2.html
-/sdcard/android/layout_tests/http/tests/appcache/reload.html
-/sdcard/android/layout_tests/http/tests/appcache/cyrillic-uri.html
-/sdcard/android/layout_tests/http/tests/security/aboutBlank/security-context-alias.html
-/sdcard/android/layout_tests/http/tests/security/aboutBlank/security-context-write.html
-/sdcard/android/layout_tests/http/tests/security/aboutBlank/security-context-grandchildren-alias.html
-/sdcard/android/layout_tests/http/tests/security/aboutBlank/security-context-with-base-tag.html
-/sdcard/android/layout_tests/http/tests/security/aboutBlank/security-context.html
-/sdcard/android/layout_tests/http/tests/security/aboutBlank/window-open-self-about-blank.html
-/sdcard/android/layout_tests/http/tests/security/aboutBlank/security-context-grandchildren.html
-/sdcard/android/layout_tests/http/tests/security/aboutBlank/security-context-grandchildren-writeln-lexical.html
-/sdcard/android/layout_tests/http/tests/security/aboutBlank/security-context-window-open.html
-/sdcard/android/layout_tests/http/tests/security/aboutBlank/security-context-grandchildren-write-lexical.html
-/sdcard/android/layout_tests/http/tests/security/aboutBlank/security-context-grandchildren-lexical.html
-/sdcard/android/layout_tests/http/tests/security/aboutBlank/security-context-writeln.html
-/sdcard/android/layout_tests/http/tests/security/cookies/document-open.html
-/sdcard/android/layout_tests/http/tests/security/cookies/create-document.html
-/sdcard/android/layout_tests/http/tests/security/cookies/assign-document-url.html
-/sdcard/android/layout_tests/http/tests/security/cookies/basic.html
-/sdcard/android/layout_tests/http/tests/security/cookies/base-tag.html
-/sdcard/android/layout_tests/http/tests/security/cookies/base-about-blank.html
-/sdcard/android/layout_tests/http/tests/security/cookies/xmlhttprequest.html
-/sdcard/android/layout_tests/http/tests/security/listener/xss-JSTargetNode-onclick-shortcut.html
-/sdcard/android/layout_tests/http/tests/security/listener/xss-XMLHttpRequest-shortcut.html
-/sdcard/android/layout_tests/http/tests/security/listener/xss-JSTargetNode-onclick-addEventListener.html
-/sdcard/android/layout_tests/http/tests/security/listener/xss-XMLHttpRequest-addEventListener.html
-/sdcard/android/layout_tests/http/tests/security/MessagePort/event-listener-context.html
-/sdcard/android/layout_tests/http/tests/security/postMessage/delivery-order.html
-/sdcard/android/layout_tests/http/tests/security/postMessage/data-url-sends-null-origin.html
-/sdcard/android/layout_tests/http/tests/security/postMessage/origin-unaffected-by-base-tag.html
-/sdcard/android/layout_tests/http/tests/security/postMessage/origin-unaffected-by-document-domain.html
-/sdcard/android/layout_tests/http/tests/security/postMessage/javascript-page-still-sends-origin.html
-/sdcard/android/layout_tests/http/tests/security/postMessage/invalid-origin-throws-exception.html
-/sdcard/android/layout_tests/http/tests/security/postMessage/target-origin.html
-/sdcard/android/layout_tests/http/tests/security/frameNavigation/context-for-window-open.html
-/sdcard/android/layout_tests/http/tests/security/frameNavigation/context-for-location.html
-/sdcard/android/layout_tests/http/tests/security/frameNavigation/not-opener.html
-/sdcard/android/layout_tests/http/tests/security/frameNavigation/opener.html
-/sdcard/android/layout_tests/http/tests/security/frameNavigation/context-for-location-assign.html
-/sdcard/android/layout_tests/http/tests/security/frameNavigation/context-for-location-href.html
-/sdcard/android/layout_tests/http/tests/security/frameNavigation/xss-ALLOWED-parent-navigation-change.html
-/sdcard/android/layout_tests/http/tests/security/originHeader/origin-header-for-get.html
-/sdcard/android/layout_tests/http/tests/security/originHeader/origin-header-for-https.html
-/sdcard/android/layout_tests/http/tests/security/originHeader/origin-header-for-post.html
-/sdcard/android/layout_tests/http/tests/security/originHeader/origin-header-for-data.html
-/sdcard/android/layout_tests/http/tests/security/xss-DENIED-assign-location-hash.html
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-history-prototype.html
-/sdcard/android/layout_tests/http/tests/security/xss-DENIED-synchronous-form.html
-/sdcard/android/layout_tests/http/tests/security/canvas-remote-read-redirect-to-remote-image.html
-/sdcard/android/layout_tests/http/tests/security/xss-DENIED-assign-location-nonstandardProperty.html
-/sdcard/android/layout_tests/http/tests/security/xss-DENIED-assign-location-pathname.html
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-frames.html
-/sdcard/android/layout_tests/http/tests/security/object-literals.html
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-location-prototype.html
-/sdcard/android/layout_tests/http/tests/security/xss-DENIED-assign-location-search.html
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-selection.html
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-name-getter.html
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-call.html
-/sdcard/android/layout_tests/http/tests/security/xss-DENIED-assign-location-reload.html
-/sdcard/android/layout_tests/http/tests/security/xss-DENIED-invalid-domain-change.html
-/sdcard/android/layout_tests/http/tests/security/canvas-remote-read-remote-image.html
-/sdcard/android/layout_tests/http/tests/security/xss-DENIED-assign-location-protocol.html
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-first-time.html
-/sdcard/android/layout_tests/http/tests/security/xss-eval.html
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-DOMImplementation.html
-/sdcard/android/layout_tests/http/tests/security/xss-DENIED-assign-location-hostname.html
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-custom.html
-/sdcard/android/layout_tests/http/tests/security/xss-DENIED-assign-location-host.html
-/sdcard/android/layout_tests/http/tests/security/cross-frame-access-callback-explicit-domain-ALLOW.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/workers/xmlhttprequest-file-not-found.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/workers/abort-exception-assert.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/workers/close.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/web-apps/010.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/web-apps/002.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/web-apps/012.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/web-apps/004.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/web-apps/014.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/web-apps/018.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/web-apps/002-simple.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/web-apps/001.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/web-apps/011.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/web-apps/003.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/web-apps/013.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/web-apps/005.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/web-apps/015.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/web-apps/007.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/cross-site-denied-response.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/encode-request-url.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/access-control-basic-allow-async.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/access-control-basic-non-simple-allow.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/access-control-basic-allow-preflight-cache.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/inject-header.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/xmlhttprequest-LSProgressEvent-ProgressEvent-should-match.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/origin-header-same-origin-post-async.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/access-control-basic-denied.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/origin-header-cross-origin-post-sync.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/xmlhttprequest-InvalidStateException-getAllRequestHeaders.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/simple-cross-origin-denied-events-post-sync.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/binary-x-user-defined.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/onloadstart-event.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/xmlhttprequest-no-content-length-onProgress.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/readystatechange.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/xmlhttprequest-contenttype-empty.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/access-control-basic-post-fail-non-simple-content-type.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/xmlhttprequest-forbidden-methods-exception.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/access-control-basic-allow-preflight-cache-invalidation-by-method.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/serialize-document.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/onerror-event.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/close-window.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/redirect-cross-origin-post-sync.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/detaching-frame-2.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/encode-request-url-2.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/set-dangerous-headers.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/event-target.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/xmlhttprequest-addEventListener-onProgress.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/send-on-abort.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/document-domain-set.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/access-control-basic-allow-preflight-cache-timeout.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/xmlhttprequest-responseXML-exception.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/cross-site-denied-response-sync.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/upload-onloadstart-event.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/supported-xml-content-types.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/simple-cross-origin-denied-events.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/request-encoding.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/zero-length-response.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/connection-error-sync.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/access-control-basic-allow-access-control-origin-header-data-url.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/access-control-basic-allow-preflight-cache-invalidation-by-header.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/redirect-cross-origin.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/access-control-basic-allow-star.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/xmlhttprequest-crlf-getAllResponseHeader.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/event-listener-gc.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/interactive-state.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/state-after-network-error.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/abort-crash.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/get-dangerous-headers.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/xmlhttprequest-image-not-loaded.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/exceptions.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/xmlhttprequest-test-send-flag.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/origin-header-cross-origin-post-async.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/referer.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/xmlhttprequest-invalidHeader-getRequestHeader.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/infoOnProgressEvent.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/access-control-basic-allow-access-control-origin-header.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/docLoaderFrame.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/simple-cross-origin-denied-events-sync.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/post-content-type.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/access-control-basic-whitelist-response-headers.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/onabort-event.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/origin-header-same-origin-get-async.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/detaching-frame.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/redirect-cross-origin-sync.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/access-control-basic-get-fail-non-simple.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/zero-length-response-sync.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/access-control-basic-denied-preflight-cache.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/authorization-header.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/xmlhttprequest-post-crash.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/origin-header-cross-origin-get-sync.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/origin-header-cross-origin-get-async.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/redirect-cross-origin-sync-double.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/xmlhttprequest-abort-readyState-shouldDispatchEvent.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/xmlhttprequest-responseText-exception.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/redirect-cross-origin-2.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/xmlhttprequest-abort-readyState-shouldNotDispatchEvent.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/status-after-abort.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/XMLHttpRequestException.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/xmlhttprequest-onProgress-open-should-zero-length.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/broken-xml-encoding.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/simple-cross-origin-denied-events-post.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/extra-parameters.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/xmlhttprequest-multiple-open.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/xmlhttprequest-InvalidStateException-getRequestHeader.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/origin-header-same-origin-post-sync.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/cross-site-denied-response-sync-2.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/request-from-popup.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/redirect-cross-origin-post.html
-/sdcard/android/layout_tests/http/tests/xmlhttprequest/simple-cross-origin-progress-events.html
-/sdcard/android/layout_tests/http/tests/messaging/cross-domain-message-event-dispatch.html
-/sdcard/android/layout_tests/http/tests/messaging/cross-domain-message-send.html
-/sdcard/android/layout_tests/media/constructors.html
-/sdcard/android/layout_tests/media/video-poster.html
-/sdcard/android/layout_tests/media/video-source-media.html
-/sdcard/android/layout_tests/media/video-controls-with-mutation-event-handler.html
-/sdcard/android/layout_tests/media/video-src-set.html
-/sdcard/android/layout_tests/media/video-display-none-crash.html
-/sdcard/android/layout_tests/media/video-width-height.html
-/sdcard/android/layout_tests/media/video-source.html
-/sdcard/android/layout_tests/media/fallback.html
-/sdcard/android/layout_tests/media/remove-from-document-no-load.html
-/sdcard/android/layout_tests/media/before-load-member-access.html
-/sdcard/android/layout_tests/media/video-play-pause-events.html
-/sdcard/android/layout_tests/media/media-constants.html
-/sdcard/android/layout_tests/media/video-src-source.html
-/sdcard/android/layout_tests/media/video-play-pause-exception.html
-/sdcard/android/layout_tests/media/video-dom-autobuffer.html
-/sdcard/android/layout_tests/media/video-seek-no-src-exception.html
-/sdcard/android/layout_tests/media/video-src.html
-/sdcard/android/layout_tests/plugins/createScriptableObject-before-start.html
-/sdcard/android/layout_tests/plugins/return-error-from-new-stream-callback-in-full-frame-plugin.html
-/sdcard/android/layout_tests/scrollbars/scrollbar-crash-on-refresh.html
-/sdcard/android/layout_tests/scrollbars/scrollbar-miss-mousemove.html
-/sdcard/android/layout_tests/security/autocomplete-cleared-on-back.html
-/sdcard/android/layout_tests/storage/domstorage/localstorage/complex-keys.html
-/sdcard/android/layout_tests/storage/domstorage/localstorage/clear.html
-/sdcard/android/layout_tests/storage/domstorage/localstorage/enumerate-storage.html
-/sdcard/android/layout_tests/storage/domstorage/localstorage/remove-item.html
-/sdcard/android/layout_tests/storage/domstorage/localstorage/string-conversion.html
-/sdcard/android/layout_tests/storage/domstorage/localstorage/simple-events.html
-/sdcard/android/layout_tests/storage/domstorage/localstorage/delete-removal.html
-/sdcard/android/layout_tests/storage/domstorage/localstorage/window-open.html
-/sdcard/android/layout_tests/storage/domstorage/localstorage/index-get-and-set.html
-/sdcard/android/layout_tests/storage/domstorage/localstorage/onstorage-attribute-setattribute.html
-/sdcard/android/layout_tests/storage/domstorage/localstorage/onstorage-attribute-setwindow.html
-/sdcard/android/layout_tests/storage/domstorage/localstorage/simple-usage.html
-/sdcard/android/layout_tests/storage/domstorage/localstorage/onstorage-attribute-markup.html
-/sdcard/android/layout_tests/storage/domstorage/localstorage/enumerate-with-length-and-key.html
-/sdcard/android/layout_tests/storage/domstorage/localstorage/complex-values.html
-/sdcard/android/layout_tests/storage/domstorage/sessionstorage/index-get-and-set.html
-/sdcard/android/layout_tests/storage/domstorage/sessionstorage/onstorage-attribute-setattribute.html
-/sdcard/android/layout_tests/storage/domstorage/sessionstorage/onstorage-attribute-setwindow.html
-/sdcard/android/layout_tests/storage/domstorage/sessionstorage/clear.html
-/sdcard/android/layout_tests/storage/domstorage/sessionstorage/enumerate-storage.html
-/sdcard/android/layout_tests/storage/domstorage/sessionstorage/string-conversion.html
-/sdcard/android/layout_tests/storage/domstorage/sessionstorage/simple-usage.html
-/sdcard/android/layout_tests/storage/domstorage/sessionstorage/simple-events.html
-/sdcard/android/layout_tests/storage/domstorage/sessionstorage/onstorage-attribute-markup.html
-/sdcard/android/layout_tests/storage/domstorage/sessionstorage/enumerate-with-length-and-key.html
-/sdcard/android/layout_tests/storage/domstorage/sessionstorage/delete-removal.html
-/sdcard/android/layout_tests/storage/domstorage/sessionstorage/window-open.html
-/sdcard/android/layout_tests/storage/domstorage/window-attributes-exist.html
-/sdcard/android/layout_tests/storage/hash-change-with-xhr.html
-/sdcard/android/layout_tests/storage/open-database-empty-version.html
-/sdcard/android/layout_tests/storage/quota-tracking.html
-/sdcard/android/layout_tests/storage/close-during-stress-test.html
-/sdcard/android/layout_tests/storage/database-lock-after-reload.html
-/sdcard/android/layout_tests/storage/multiple-databases-garbage-collection.html
-/sdcard/android/layout_tests/storage/empty-statement.html
-/sdcard/android/layout_tests/storage/multiple-transactions.html
-/sdcard/android/layout_tests/storage/success-callback.html
-/sdcard/android/layout_tests/storage/transaction-error-callback.html
-/sdcard/android/layout_tests/storage/sql-data-types.html
-/sdcard/android/layout_tests/storage/transaction-callback-exception-crash.html
-/sdcard/android/layout_tests/transforms/2d/transform-2d.html
-/sdcard/android/layout_tests/transforms/2d/compound-2d-transforms.html
-/sdcard/android/layout_tests/transforms/2d/computed-style-origin.html
-/sdcard/android/layout_tests/transforms/2d/transform-accuracy.html
-/sdcard/android/layout_tests/transforms/2d/transform-value-types.html
-/sdcard/android/layout_tests/transforms/3d/hit-testing/hit-preserves-3d.html
-/sdcard/android/layout_tests/transitions/cancel-transition.html
-/sdcard/android/layout_tests/transitions/transition-end-event-all-properties.html
-/sdcard/android/layout_tests/transitions/transition-end-event-window.html
-/sdcard/android/layout_tests/transitions/transition-end-event-multiple-03.html
-/sdcard/android/layout_tests/transitions/text-indent-transition.html
-/sdcard/android/layout_tests/transitions/transition-end-event-set-none.html
-/sdcard/android/layout_tests/transitions/zero-duration-without-units.html
-/sdcard/android/layout_tests/transitions/min-max-width-height-transitions.html
-/sdcard/android/layout_tests/transitions/shorthand-transitions.html
-/sdcard/android/layout_tests/transitions/mask-transitions.html
-/sdcard/android/layout_tests/transitions/zero-duration-with-non-zero-delay-start.html
-/sdcard/android/layout_tests/transitions/zero-duration-in-list.html
-/sdcard/android/layout_tests/transitions/shorthand-border-transitions.html
-/sdcard/android/layout_tests/transitions/inherit-other-props.html
-/sdcard/android/layout_tests/transitions/transition-end-event-multiple-04.html
-/sdcard/android/layout_tests/transitions/background-transitions.html
-/sdcard/android/layout_tests/transitions/transition-duration-cleared-in-transitionend-crash.html
-/sdcard/android/layout_tests/transitions/interrupt-zero-duration.html
-/sdcard/android/layout_tests/transitions/retargetted-transition.html
-/sdcard/android/layout_tests/transitions/transition-end-event-left.html
-/sdcard/android/layout_tests/transitions/override-transition-crash.html
-/sdcard/android/layout_tests/transitions/transition-end-event-multiple-01.html
-/sdcard/android/layout_tests/transitions/matched-transform-functions.html
-/sdcard/android/layout_tests/transitions/transform-op-list-match.html
-/sdcard/android/layout_tests/transitions/transition-end-event-container.html
-/sdcard/android/layout_tests/transitions/interrupt-transform-transition.html
-/sdcard/android/layout_tests/transitions/transition-end-event-nested.html
-/sdcard/android/layout_tests/transitions/change-values-during-transition.html
-/sdcard/android/layout_tests/transitions/transition-end-event-attributes.html
-/sdcard/android/layout_tests/transitions/inherit.html
-/sdcard/android/layout_tests/transitions/transition-end-event-create.html
-/sdcard/android/layout_tests/transitions/shadow.html
-/sdcard/android/layout_tests/transitions/transition-end-event-multiple-02.html
-/sdcard/android/layout_tests/transitions/transition-end-event-transform.html
-/sdcard/android/layout_tests/transitions/start-transform-transition.html
-/sdcard/android/layout_tests/transitions/transition-timing-function.html
-/sdcard/android/layout_tests/transitions/transform-op-list-no-match.html
-/sdcard/android/layout_tests/transitions/bad-transition-shorthand-crash.html
-/sdcard/android/layout_tests/transitions/transition-end-event-destroy-renderer.html
-/sdcard/android/layout_tests/transitions/extra-transition.html
-/sdcard/android/layout_tests/traversal/hixie-node-iterator/010.xml
-/sdcard/android/layout_tests/traversal/hixie-node-iterator/001.xml
-/sdcard/android/layout_tests/traversal/hixie-node-iterator/002.xml
-/sdcard/android/layout_tests/traversal/hixie-node-iterator/003.xml
-/sdcard/android/layout_tests/traversal/hixie-node-iterator/004.xml
-/sdcard/android/layout_tests/traversal/hixie-node-iterator/005.xml
-/sdcard/android/layout_tests/traversal/hixie-node-iterator/006.xml
-/sdcard/android/layout_tests/traversal/hixie-node-iterator/007.xml
-/sdcard/android/layout_tests/traversal/hixie-node-iterator/008.xml
-/sdcard/android/layout_tests/traversal/hixie-node-iterator/009.xml
-/sdcard/android/layout_tests/traversal/node-iterator-003.html
-/sdcard/android/layout_tests/traversal/node-iterator-005.html
-/sdcard/android/layout_tests/traversal/node-iterator-007.html
-/sdcard/android/layout_tests/traversal/tree-walker-001.html
-/sdcard/android/layout_tests/traversal/node-iterator-009.html
-/sdcard/android/layout_tests/traversal/tree-walker-003.html
-/sdcard/android/layout_tests/traversal/tree-walker-005.html
-/sdcard/android/layout_tests/traversal/exception-forwarding.html
-/sdcard/android/layout_tests/traversal/stay-within-root.html
-/sdcard/android/layout_tests/traversal/node-iterator-002.html
-/sdcard/android/layout_tests/traversal/node-iterator-004.html
-/sdcard/android/layout_tests/traversal/node-iterator-006.html
-/sdcard/android/layout_tests/traversal/node-iterator-006a.html
-/sdcard/android/layout_tests/traversal/tree-walker-002.html
-/sdcard/android/layout_tests/traversal/node-iterator-008.html
-/sdcard/android/layout_tests/traversal/tree-walker-004.html
-/sdcard/android/layout_tests/traversal/tree-walker-006.html
-/sdcard/android/layout_tests/traversal/size-zero-run.html
-/sdcard/android/layout_tests/traversal/acid3-test-2.html
-/sdcard/android/layout_tests/traversal/tree-walker-filter-1.html
-/sdcard/android/layout_tests/traversal/node-iterator-001.html
diff --git a/tests/DumpRenderTree/assets/run_layout_tests.py b/tests/DumpRenderTree/assets/run_layout_tests.py
deleted file mode 100755
index 21c02ec..0000000
--- a/tests/DumpRenderTree/assets/run_layout_tests.py
+++ /dev/null
@@ -1,320 +0,0 @@
-#!/usr/bin/python
-
-"""Run layout tests using Android emulator and instrumentation.
-
-  First, you need to get an SD card or sdcard image that has layout tests on it.
-  Layout tests are in following directory:
-    /sdcard/webkit/layout_tests
-  For example, /sdcard/webkit/layout_tests/fast
-
-  Usage:
-    Run all tests under fast/ directory:
-      run_layout_tests.py, or
-      run_layout_tests.py fast
-
-    Run all tests under a sub directory:
-      run_layout_tests.py fast/dom
-
-    Run a single test:
-      run_layout_tests.py fast/dom/
-
-  After a merge, if there are changes of layout tests in SD card, you need to
-  use --refresh-test-list option *once* to re-generate test list on the card.
-
-  Some other options are:
-    --rebaseline generates expected layout tests results under /sdcard/webkit/expected_result/
-    --time-out-ms (default is 8000 millis) for each test
-    --adb-options="-e" passes option string to adb
-    --results-directory=..., (default is ./layout-test-results) directory name under which results are stored.
-    --js-engine the JavaScript engine currently in use, determines which set of Android-specific expected results we should use, should be 'jsc' or 'v8'
-"""
-
-import logging
-import optparse
-import os
-import subprocess
-import sys
-import time
-
-def CountLineNumber(filename):
-  """Compute the number of lines in a given file.
-
-  Args:
-    filename: a file name related to the current directory.
-  """
-
-  fp = open(os.path.abspath(filename), "r");
-  lines = 0
-  for line in fp.readlines():
-    lines = lines + 1
-  fp.close()
-  return lines
-
-def DumpRenderTreeFinished(adb_cmd):
-  """ Check if DumpRenderTree finished running tests
-
-  Args:
-    output: adb_cmd string
-  """
-
-  # pull /sdcard/webkit/running_test.txt, if the content is "#DONE", it's done
-  shell_cmd_str = adb_cmd + " shell cat /sdcard/webkit/running_test.txt"
-  adb_output = subprocess.Popen(shell_cmd_str, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0]
-  return adb_output.strip() == "#DONE"
-
-def DiffResults(marker, new_results, old_results, diff_results, strip_reason,
-                new_count_first=True):
-   """ Given two result files, generate diff and
-       write to diff_results file. All arguments are absolute paths
-       to files.
-   """
-   old_file = open(old_results, "r")
-   new_file = open(new_results, "r")
-   diff_file = open(diff_results, "a")
-
-   # Read lines from each file
-   ndict = new_file.readlines()
-   cdict = old_file.readlines()
-
-   # Write marker to diff file
-   diff_file.writelines(marker + "\n")
-   diff_file.writelines("###############\n")
-
-   # Strip reason from result lines
-   if strip_reason is True:
-     for i in range(0, len(ndict)):
-       ndict[i] = ndict[i].split(' ')[0] + "\n"
-     for i in range(0, len(cdict)):
-       cdict[i] = cdict[i].split(' ')[0] + "\n"
-
-   params = {
-       "new": [0, ndict, cdict, "+"],
-       "miss": [0, cdict, ndict, "-"]
-       }
-   if new_count_first:
-     order = ["new", "miss"]
-   else:
-     order = ["miss", "new"]
-
-   for key in order:
-     for line in params[key][1]:
-       if line not in params[key][2]:
-         if line[-1] != "\n":
-           line += "\n";
-         diff_file.writelines(params[key][3] + line)
-         params[key][0] += 1
-
-   logging.info(marker + "  >>> " + str(params["new"][0]) + " new, " +
-                str(params["miss"][0]) + " misses")
-
-   diff_file.writelines("\n\n")
-
-   old_file.close()
-   new_file.close()
-   diff_file.close()
-   return
-
-def CompareResults(ref_dir, results_dir):
-  """Compare results in two directories
-
-  Args:
-    ref_dir: the reference directory having layout results as references
-    results_dir: the results directory
-  """
-  logging.info("Comparing results to " + ref_dir)
-
-  diff_result = os.path.join(results_dir, "layout_tests_diff.txt")
-  if os.path.exists(diff_result):
-    os.remove(diff_result)
-
-  files=["crashed", "failed", "passed", "nontext"]
-  for f in files:
-    result_file_name = "layout_tests_" + f + ".txt"
-    DiffResults(f, os.path.join(results_dir, result_file_name),
-                os.path.join(ref_dir, result_file_name), diff_result,
-                False, f != "passed")
-  logging.info("Detailed diffs are in " + diff_result)
-
-def main(options, args):
-  """Run the tests. Will call sys.exit when complete.
-
-  Args:
-    options: a dictionary of command line options
-    args: a list of sub directories or files to test
-  """
-
-  # Set up logging format.
-  log_level = logging.INFO
-  if options.verbose:
-    log_level = logging.DEBUG
-  logging.basicConfig(level=log_level,
-                      format='%(message)s')
-
-  # Include all tests if none are specified.
-  if not args:
-    path = '/';
-  else:
-    path = ' '.join(args);
-
-  adb_cmd = "adb ";
-  if options.adb_options:
-    adb_cmd += options.adb_options
-
-  # Re-generate the test list if --refresh-test-list is on
-  if options.refresh_test_list:
-    logging.info("Generating test list.");
-    generate_test_list_cmd_str = adb_cmd + " shell am instrument -e class com.android.dumprendertree.LayoutTestsAutoTest#generateTestList -e path \"" + path + "\" -w com.android.dumprendertree/.LayoutTestsAutoRunner"
-    adb_output = subprocess.Popen(generate_test_list_cmd_str, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0]
-
-    if adb_output.find('Process crashed') != -1:
-       logging.info("Aborting because cannot generate test list.\n" + adb_output)
-       sys.exit(1)
-
-
-  logging.info("Running tests")
-
-  # Count crashed tests.
-  crashed_tests = []
-
-  timeout_ms = '15000'
-  if options.time_out_ms:
-    timeout_ms = options.time_out_ms
-
-  # Run test until it's done
-
-  run_layout_test_cmd_prefix = adb_cmd + " shell am instrument"
-
-  run_layout_test_cmd_postfix = " -e path \"" + path + "\" -e timeout " + timeout_ms
-  if options.rebaseline:
-    run_layout_test_cmd_postfix += " -e rebaseline true"
-
-  # If the JS engine is not specified on the command line, try reading the
-  # JS_ENGINE environment  variable, which is used by the build system in
-  # external/webkit/Android.mk.
-  js_engine = options.js_engine
-  if not js_engine and os.environ.has_key('JS_ENGINE'):
-    js_engine = os.environ['JS_ENGINE']
-  if js_engine:
-    run_layout_test_cmd_postfix += " -e jsengine " + js_engine
-
-  run_layout_test_cmd_postfix += " -w com.android.dumprendertree/.LayoutTestsAutoRunner"
-
-  # Call LayoutTestsAutoTest::startLayoutTests.
-  run_layout_test_cmd = run_layout_test_cmd_prefix + " -e class com.android.dumprendertree.LayoutTestsAutoTest#startLayoutTests" + run_layout_test_cmd_postfix
-
-  adb_output = subprocess.Popen(run_layout_test_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0]
-  while not DumpRenderTreeFinished(adb_cmd):
-    # Get the running_test.txt
-    logging.error("DumpRenderTree crashed, output:\n" + adb_output)
-
-    shell_cmd_str = adb_cmd + " shell cat /sdcard/webkit/running_test.txt"
-    crashed_test = ""
-    while not crashed_test:
-      (crashed_test, err) = subprocess.Popen(
-          shell_cmd_str, shell=True, stdout=subprocess.PIPE,
-          stderr=subprocess.PIPE).communicate()
-      crashed_test = crashed_test.strip()
-      if not crashed_test:
-        logging.error('Cannot get crashed test name, device offline?')
-        logging.error('stderr: ' + err)
-        logging.error('retrying in 10s...')
-        time.sleep(10)
-
-    logging.info(crashed_test + " CRASHED");
-    crashed_tests.append(crashed_test);
-
-    logging.info("Resuming layout test runner...");
-    # Call LayoutTestsAutoTest::resumeLayoutTests
-    run_layout_test_cmd = run_layout_test_cmd_prefix + " -e class com.android.dumprendertree.LayoutTestsAutoTest#resumeLayoutTests" + run_layout_test_cmd_postfix
-
-    adb_output = subprocess.Popen(run_layout_test_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0]
-
-  if adb_output.find('INSTRUMENTATION_FAILED') != -1:
-    logging.error("Error happened : " + adb_output)
-    sys.exit(1)
-
-  logging.debug(adb_output);
-  logging.info("Done\n");
-
-  # Pull results from /sdcard
-  results_dir = options.results_directory
-  if not os.path.exists(results_dir):
-    os.makedirs(results_dir)
-  if not os.path.isdir(results_dir):
-    logging.error("Cannot create results dir: " + results_dir);
-    sys.exit(1);
-
-  result_files = ["/sdcard/layout_tests_passed.txt",
-                  "/sdcard/layout_tests_failed.txt",
-                  "/sdcard/layout_tests_ignored.txt",
-                  "/sdcard/layout_tests_nontext.txt"]
-  for file in result_files:
-    shell_cmd_str = adb_cmd + " pull " + file + " " + results_dir
-    adb_output = subprocess.Popen(shell_cmd_str, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0]
-    logging.debug(adb_output)
-
-  # Create the crash list.
-  fp = open(results_dir + "/layout_tests_crashed.txt", "w");
-  for crashed_test in crashed_tests:
-    fp.writelines(crashed_test + '\n')
-  fp.close()
-
-  # Count the number of tests in each category.
-  passed_tests = CountLineNumber(results_dir + "/layout_tests_passed.txt")
-  logging.info(str(passed_tests) + " passed")
-  failed_tests = CountLineNumber(results_dir + "/layout_tests_failed.txt")
-  logging.info(str(failed_tests) + " failed")
-  ignored_tests = CountLineNumber(results_dir + "/layout_tests_ignored.txt")
-  logging.info(str(ignored_tests) + " ignored results")
-  crashed_tests = CountLineNumber(results_dir + "/layout_tests_crashed.txt")
-  logging.info(str(crashed_tests) + " crashed")
-  nontext_tests = CountLineNumber(results_dir + "/layout_tests_nontext.txt")
-  logging.info(str(nontext_tests) + " no dumpAsText")
-  logging.info(str(passed_tests + failed_tests + ignored_tests + crashed_tests + nontext_tests) + " TOTAL")
-
-  logging.info("Results are stored under: " + results_dir + "\n")
-
-  # Comparing results to references to find new fixes and regressions.
-  results_dir = os.path.abspath(options.results_directory)
-  ref_dir = options.ref_directory
-
-  # if ref_dir is null, cannonify ref_dir to the script dir.
-  if not ref_dir:
-    script_self = sys.argv[0]
-    script_dir = os.path.dirname(script_self)
-    ref_dir = os.path.join(script_dir, "results")
-
-  ref_dir = os.path.abspath(ref_dir)
-
-  CompareResults(ref_dir, results_dir)
-
-if '__main__' == __name__:
-  option_parser = optparse.OptionParser()
-  option_parser.add_option("", "--rebaseline", action="store_true",
-                           default=False,
-                           help="generate expected results for those tests not having one")
-  option_parser.add_option("", "--time-out-ms",
-                           default=None,
-                           help="set the timeout for each test")
-  option_parser.add_option("", "--verbose", action="store_true",
-                           default=False,
-                           help="include debug-level logging")
-  option_parser.add_option("", "--refresh-test-list", action="store_true",
-                           default=False,
-                           help="re-generate test list, it may take some time.")
-  option_parser.add_option("", "--adb-options",
-                           default=None,
-                           help="pass options to adb, such as -d -e, etc");
-  option_parser.add_option("", "--results-directory",
-                           default="layout-test-results",
-                           help="directory which results are stored.")
-  option_parser.add_option("", "--ref-directory",
-                           default=None,
-                           dest="ref_directory",
-                           help="directory where reference results are stored.")
-  option_parser.add_option("", "--js-engine",
-                           default=None,
-                           help="The JavaScript engine currently in use, which determines which set of Android-specific expected results we should use. Should be 'jsc' or 'v8'.");
-
-  options, args = option_parser.parse_args();
-  main(options, args)
diff --git a/tests/DumpRenderTree/assets/run_page_cycler.py b/tests/DumpRenderTree/assets/run_page_cycler.py
deleted file mode 100755
index f995086..0000000
--- a/tests/DumpRenderTree/assets/run_page_cycler.py
+++ /dev/null
@@ -1,163 +0,0 @@
-#!/usr/bin/python
-
-"""Run page cycler tests using Android instrumentation.
-
-  First, you need to get an SD card or sdcard image that has page cycler tests.
-
-  Usage:
-    Run a single page cycler test:
-      run_page_cycler.py "file:///sdcard/webkit/page_cycler/moz/start.html\?auto=1\&iterations=10"
-"""
-
-import logging
-import optparse
-import os
-import subprocess
-import sys
-import time
-
-
-
-def main(options, args):
-  """Run the tests. Will call sys.exit when complete.
-
-  """
-
-  # Set up logging format.
-  log_level = logging.INFO
-  if options.verbose:
-    log_level = logging.DEBUG
-  logging.basicConfig(level=log_level,
-                      format='%(message)s')
-
-  # Include all tests if none are specified.
-  if not args:
-    print "need a URL, e.g. file:///sdcard/webkit/page_cycler/moz/start.html\?auto=1\&iterations=10"
-    print "  or remote:android-browser-test:80/page_cycler/"
-    sys.exit(1)
-  else:
-    path = ' '.join(args);
-
-  if path[:7] == "remote:":
-    remote_path = path[7:]
-  else:
-    remote_path = None
-
-  adb_cmd = "adb ";
-  if options.adb_options:
-    adb_cmd += options.adb_options
-
-  logging.info("Running the test ...")
-
-  # Count crashed tests.
-  crashed_tests = []
-
-  timeout_ms = '0'
-  if options.time_out_ms:
-    timeout_ms = options.time_out_ms
-
-  # Run test until it's done
-
-  run_load_test_cmd_prefix = adb_cmd + " shell am instrument"
-  run_load_test_cmd_postfix = " -w com.android.dumprendertree/.LayoutTestsAutoRunner"
-
-  # Call LoadTestsAutoTest::runTest.
-  run_load_test_cmd = run_load_test_cmd_prefix + " -e class com.android.dumprendertree.LoadTestsAutoTest#runPageCyclerTest -e timeout " + timeout_ms
-
-  if remote_path:
-    if options.suite:
-      run_load_test_cmd += " -e suite %s -e forward %s " % (options.suite,
-                                                            remote_path)
-    else:
-      print "for network mode, need to specify --suite as well."
-      sys.exit(1)
-    if options.iteration:
-      run_load_test_cmd += " -e iteration %s" % options.iteration
-  else:
-    run_load_test_cmd += " -e path \"%s\" " % path
-
-
-  if options.drawtime:
-    run_load_test_cmd += " -e drawtime true "
-
-  if options.save_image:
-    run_load_test_cmd += " -e saveimage \"%s\"" % options.save_image
-
-  run_load_test_cmd += run_load_test_cmd_postfix
-
-  (adb_output, adb_error) = subprocess.Popen(run_load_test_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
-  fail_flag = False
-  for line in adb_output.splitlines():
-    line = line.strip()
-    if line.find('INSTRUMENTATION_CODE') == 0:
-      if not line[22:] == '-1':
-        fail_flag = True
-        break
-    if (line.find('INSTRUMENTATION_FAILED') != -1 or
-        line.find('Process crashed.') != -1):
-      fail_flag = True
-      break
-  if fail_flag:
-    logging.error("Error happened : " + adb_output)
-    sys.exit(1)
-
-  logging.info(adb_output);
-  logging.info(adb_error);
-  logging.info("Done\n");
-
-  # Pull results from /sdcard/load_test_result.txt
-  results_dir = options.results_directory
-  if not os.path.exists(results_dir):
-    os.makedirs(results_dir)
-  if not os.path.isdir(results_dir):
-    logging.error("Cannot create results dir: " + results_dir)
-    sys.exit(1)
-
-  result_file = "/sdcard/load_test_result.txt"
-  shell_cmd_str = adb_cmd + " pull " + result_file + " " + results_dir
-  (adb_output, err) = subprocess.Popen(
-      shell_cmd_str, shell=True,
-      stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
-  if not os.path.isfile(os.path.join(results_dir, "load_test_result.txt")):
-    logging.error("Failed to pull result file.")
-    logging.error("adb stdout:")
-    logging.error(adb_output)
-    logging.error("adb stderr:")
-    logging.error(err)
-  logging.info("Results are stored under: " + results_dir + "/load_test_result.txt\n")
-
-if '__main__' == __name__:
-  option_parser = optparse.OptionParser()
-  option_parser.add_option("-t", "--time-out-ms",
-                           default=None,
-                           help="set the timeout for each test")
-  option_parser.add_option("-v", "--verbose", action="store_true",
-                           default=False,
-                           help="include debug-level logging")
-  option_parser.add_option("-a", "--adb-options",
-                           default=None,
-                           help="pass options to adb, such as -d -e, etc");
-  option_parser.add_option("-r", "--results-directory",
-                           default="layout-test-results",
-                           help="directory which results are stored.")
-
-  option_parser.add_option("-d", "--drawtime", action="store_true",
-                           default=False,
-                           help="log draw time for each page rendered.")
-
-  option_parser.add_option("-s", "--save-image",
-                           default=None,
-                           help="stores rendered page to a location on device.")
-
-  option_parser.add_option("-u", "--suite",
-                           default=None,
-                           help="(for network mode) specify the suite to"
-                           " run by name")
-
-  option_parser.add_option("-i", "--iteration",
-                           default="5",
-                           help="(for network mode) specify how many iterations"
-                           " to run")
-
-  options, args = option_parser.parse_args();
-  main(options, args)
diff --git a/tests/DumpRenderTree/assets/run_reliability_tests.py b/tests/DumpRenderTree/assets/run_reliability_tests.py
deleted file mode 100755
index 59ac4a3..0000000
--- a/tests/DumpRenderTree/assets/run_reliability_tests.py
+++ /dev/null
@@ -1,276 +0,0 @@
-#!/usr/bin/python2.4
-
-"""Run reliability tests using Android instrumentation.
-
-  A test file consists of list web sites to test is needed as a parameter
-
-  Usage:
-    run_reliability_tests.py path/to/url/list
-"""
-
-import logging
-import optparse
-import os
-import subprocess
-import sys
-import time
-from Numeric import *
-
-TEST_LIST_FILE = "/sdcard/android/reliability_tests_list.txt"
-TEST_STATUS_FILE = "/sdcard/android/reliability_running_test.txt"
-TEST_TIMEOUT_FILE = "/sdcard/android/reliability_timeout_test.txt"
-TEST_LOAD_TIME_FILE = "/sdcard/android/reliability_load_time.txt"
-HTTP_URL_FILE = "urllist_http"
-HTTPS_URL_FILE = "urllist_https"
-NUM_URLS = 25
-
-
-def DumpRenderTreeFinished(adb_cmd):
-  """Check if DumpRenderTree finished running.
-
-  Args:
-    adb_cmd: adb command string
-
-  Returns:
-    True if DumpRenderTree has finished, False otherwise
-  """
-
-  # pull test status file and look for "#DONE"
-  shell_cmd_str = adb_cmd + " shell cat " + TEST_STATUS_FILE
-  adb_output = subprocess.Popen(shell_cmd_str,
-                                shell=True, stdout=subprocess.PIPE,
-                                stderr=subprocess.PIPE).communicate()[0]
-  return adb_output.strip() == "#DONE"
-
-
-def RemoveDeviceFile(adb_cmd, file_name):
-  shell_cmd_str = adb_cmd + " shell rm " + file_name
-  subprocess.Popen(shell_cmd_str,
-                   shell=True, stdout=subprocess.PIPE,
-                   stderr=subprocess.PIPE).communicate()
-
-
-def Bugreport(url, bugreport_dir, adb_cmd):
-  """Pull a bugreport from the device."""
-  bugreport_filename = "%s/reliability_bugreport_%d.txt" % (bugreport_dir,
-                                                            int(time.time()))
-
-  # prepend the report with url
-  handle = open(bugreport_filename, "w")
-  handle.writelines("Bugreport for crash in url - %s\n\n" % url)
-  handle.close()
-
-  cmd = "%s bugreport >> %s" % (adb_cmd, bugreport_filename)
-  os.system(cmd)
-
-
-def ProcessPageLoadTime(raw_log):
-  """Processes the raw page load time logged by test app."""
-  log_handle = open(raw_log, "r")
-  load_times = {}
-
-  for line in log_handle:
-    line = line.strip()
-    pair = line.split("|")
-    if len(pair) != 2:
-      logging.info("Line has more than one '|': " + line)
-      continue
-    if pair[0] not in load_times:
-      load_times[pair[0]] = []
-    try:
-      pair[1] = int(pair[1])
-    except ValueError:
-      logging.info("Lins has non-numeric load time: " + line)
-      continue
-    load_times[pair[0]].append(pair[1])
-
-  log_handle.close()
-
-  # rewrite the average time to file
-  log_handle = open(raw_log, "w")
-  for url, times in load_times.iteritems():
-    # calculate std
-    arr = array(times)
-    avg = average(arr)
-    d = arr - avg
-    std = sqrt(sum(d * d) / len(arr))
-    output = ("%-70s%-10d%-10d%-12.2f%-12.2f%s\n" %
-              (url, min(arr), max(arr), avg, std,
-               array2string(arr)))
-    log_handle.write(output)
-  log_handle.close()
-
-
-def main(options, args):
-  """Send the url list to device and start testing, restart if crashed."""
-
-  # Set up logging format.
-  log_level = logging.INFO
-  if options.verbose:
-    log_level = logging.DEBUG
-  logging.basicConfig(level=log_level,
-                      format="%(message)s")
-
-  # Include all tests if none are specified.
-  if not args:
-    print "Missing URL list file"
-    sys.exit(1)
-  else:
-    path = args[0]
-
-  if not options.crash_file:
-    print "Missing crash file name, use --crash-file to specify"
-    sys.exit(1)
-  else:
-    crashed_file = options.crash_file
-
-  if not options.timeout_file:
-    print "Missing timeout file, use --timeout-file to specify"
-    sys.exit(1)
-  else:
-    timedout_file = options.timeout_file
-
-  if not options.delay:
-    manual_delay = 0
-  else:
-    manual_delay = options.delay
-
-  if not options.bugreport:
-    bugreport_dir = "."
-  else:
-    bugreport_dir = options.bugreport
-  if not os.path.exists(bugreport_dir):
-    os.makedirs(bugreport_dir)
-  if not os.path.isdir(bugreport_dir):
-    logging.error("Cannot create results dir: " + bugreport_dir)
-    sys.exit(1)
-
-  adb_cmd = "adb "
-  if options.adb_options:
-    adb_cmd += options.adb_options + " "
-
-  # push url list to device
-  test_cmd = adb_cmd + " push \"" + path + "\" \"" + TEST_LIST_FILE + "\""
-  proc = subprocess.Popen(test_cmd, shell=True,
-                          stdout=subprocess.PIPE,
-                          stderr=subprocess.PIPE)
-  (adb_output, adb_error) = proc.communicate()
-  if proc.returncode != 0:
-    logging.error("failed to push url list to device.")
-    logging.error(adb_output)
-    logging.error(adb_error)
-    sys.exit(1)
-
-  # clean up previous results
-  RemoveDeviceFile(adb_cmd, TEST_STATUS_FILE)
-  RemoveDeviceFile(adb_cmd, TEST_TIMEOUT_FILE)
-  RemoveDeviceFile(adb_cmd, TEST_LOAD_TIME_FILE)
-
-  logging.info("Running the test ...")
-
-  # Count crashed tests.
-  crashed_tests = []
-
-  if options.time_out_ms:
-    timeout_ms = options.time_out_ms
-
-  # Run test until it's done
-  test_cmd_prefix = adb_cmd + " shell am instrument"
-  test_cmd_postfix = " -w com.android.dumprendertree/.LayoutTestsAutoRunner"
-
-  # Call ReliabilityTestsAutoTest#startReliabilityTests
-  test_cmd = (test_cmd_prefix + " -e class "
-              "com.android.dumprendertree.ReliabilityTest#"
-              "runReliabilityTest -e timeout %s -e delay %s" %
-              (str(timeout_ms), str(manual_delay)))
-
-  if options.logtime:
-    test_cmd += " -e logtime true"
-
-  test_cmd += test_cmd_postfix
-
-  adb_output = subprocess.Popen(test_cmd, shell=True,
-                                stdout=subprocess.PIPE,
-                                stderr=subprocess.PIPE).communicate()[0]
-  while not DumpRenderTreeFinished(adb_cmd):
-    logging.error("DumpRenderTree exited before all URLs are visited.")
-    shell_cmd_str = adb_cmd + " shell cat " + TEST_STATUS_FILE
-    crashed_test = ""
-    while not crashed_test:
-      (crashed_test, err) = subprocess.Popen(
-          shell_cmd_str, shell=True, stdout=subprocess.PIPE,
-          stderr=subprocess.PIPE).communicate()
-      crashed_test = crashed_test.strip()
-      if not crashed_test:
-        logging.error('Cannot get crashed test name, device offline?')
-        logging.error('stderr: ' + err)
-        logging.error('retrying in 10s...')
-        time.sleep(10)
-
-    logging.info(crashed_test + " CRASHED")
-    crashed_tests.append(crashed_test)
-    Bugreport(crashed_test, bugreport_dir, adb_cmd)
-    logging.info("Resuming reliability test runner...")
-
-    adb_output = subprocess.Popen(test_cmd, shell=True, stdout=subprocess.PIPE,
-                                  stderr=subprocess.PIPE).communicate()[0]
-
-  if (adb_output.find("INSTRUMENTATION_FAILED") != -1 or
-      adb_output.find("Process crashed.") != -1):
-    logging.error("Error happened : " + adb_output)
-    sys.exit(1)
-
-  logging.info(adb_output)
-  logging.info("Done\n")
-
-  if crashed_tests:
-    file_handle = open(crashed_file, "w")
-    file_handle.writelines("\n".join(crashed_tests))
-    logging.info("Crashed URL list stored in: " + crashed_file)
-    file_handle.close()
-  else:
-    logging.info("No crash found.")
-
-  # get timeout file from sdcard
-  test_cmd = (adb_cmd + "pull \"" + TEST_TIMEOUT_FILE + "\" \""
-              + timedout_file +  "\"")
-  subprocess.Popen(test_cmd, shell=True, stdout=subprocess.PIPE,
-                   stderr=subprocess.PIPE).communicate()
-
-  if options.logtime:
-    # get logged page load times from sdcard
-    test_cmd = (adb_cmd + "pull \"" + TEST_LOAD_TIME_FILE + "\" \""
-                + options.logtime +  "\"")
-    subprocess.Popen(test_cmd, shell=True, stdout=subprocess.PIPE,
-                     stderr=subprocess.PIPE).communicate()
-    ProcessPageLoadTime(options.logtime)
-
-
-if "__main__" == __name__:
-  option_parser = optparse.OptionParser()
-  option_parser.add_option("-t", "--time-out-ms",
-                           default=60000,
-                           help="set the timeout for each test")
-  option_parser.add_option("-v", "--verbose", action="store_true",
-                           default=False,
-                           help="include debug-level logging")
-  option_parser.add_option("-a", "--adb-options",
-                           default=None,
-                           help="pass options to adb, such as -d -e, etc")
-  option_parser.add_option("-c", "--crash-file",
-                           default="reliability_crashed_sites.txt",
-                           help="the list of sites that cause browser to crash")
-  option_parser.add_option("-f", "--timeout-file",
-                           default="reliability_timedout_sites.txt",
-                           help="the list of sites that timedout during test")
-  option_parser.add_option("-d", "--delay",
-                           default=0,
-                           help="add a manual delay between pages (in ms)")
-  option_parser.add_option("-b", "--bugreport",
-                           default=".",
-                           help="the directory to store bugreport for crashes")
-  option_parser.add_option("-l", "--logtime",
-                           default=None,
-                           help="Logs page load time for each url to the file")
-  opts, arguments = option_parser.parse_args()
-  main(opts, arguments)
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/CallbackProxy.java b/tests/DumpRenderTree/src/com/android/dumprendertree/CallbackProxy.java
deleted file mode 100644
index 9d621d6..0000000
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/CallbackProxy.java
+++ /dev/null
@@ -1,529 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dumprendertree;
-
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.webkit.WebStorage;
-
-import java.util.HashMap;
-
-public class CallbackProxy extends Handler implements EventSender, LayoutTestController {
-
-    private EventSender mEventSender;
-    private LayoutTestController mLayoutTestController;
-
-    private static final int EVENT_DOM_LOG = 1;
-    private static final int EVENT_FIRE_KBD = 2;
-    private static final int EVENT_KEY_DOWN_1 = 3;
-    private static final int EVENT_KEY_DOWN_2 = 4;
-    private static final int EVENT_LEAP = 5;
-    private static final int EVENT_MOUSE_CLICK = 6;
-    private static final int EVENT_MOUSE_DOWN = 7;
-    private static final int EVENT_MOUSE_MOVE = 8;
-    private static final int EVENT_MOUSE_UP = 9;
-    private static final int EVENT_TOUCH_START = 10;
-    private static final int EVENT_TOUCH_MOVE = 11;
-    private static final int EVENT_TOUCH_END = 12;
-    private static final int EVENT_TOUCH_CANCEL = 13;
-    private static final int EVENT_ADD_TOUCH_POINT = 14;
-    private static final int EVENT_UPDATE_TOUCH_POINT = 15;
-    private static final int EVENT_RELEASE_TOUCH_POINT = 16;
-    private static final int EVENT_CLEAR_TOUCH_POINTS = 17;
-    private static final int EVENT_CANCEL_TOUCH_POINT = 18;
-    private static final int EVENT_SET_TOUCH_MODIFIER = 19;
-    private static final int LAYOUT_CLEAR_LIST = 20;
-    private static final int LAYOUT_DISPLAY = 21;
-    private static final int LAYOUT_DUMP_TEXT = 22;
-    private static final int LAYOUT_DUMP_HISTORY = 23;
-    private static final int LAYOUT_DUMP_CHILD_SCROLL = 24;
-    private static final int LAYOUT_DUMP_EDIT_CB = 25;
-    private static final int LAYOUT_DUMP_SEL_RECT = 26;
-    private static final int LAYOUT_DUMP_TITLE_CHANGES = 27;
-    private static final int LAYOUT_KEEP_WEB_HISTORY = 28;
-    private static final int LAYOUT_NOTIFY_DONE = 29;
-    private static final int LAYOUT_QUEUE_BACK_NAV = 30;
-    private static final int LAYOUT_QUEUE_FWD_NAV = 31;
-    private static final int LAYOUT_QUEUE_LOAD = 32;
-    private static final int LAYOUT_QUEUE_RELOAD = 33;
-    private static final int LAYOUT_QUEUE_SCRIPT = 34;
-    private static final int LAYOUT_REPAINT_HORZ = 35;
-    private static final int LAYOUT_SET_ACCEPT_EDIT = 36;
-    private static final int LAYOUT_MAIN_FIRST_RESP = 37;
-    private static final int LAYOUT_SET_WINDOW_KEY = 38;
-    private static final int LAYOUT_TEST_REPAINT = 39;
-    private static final int LAYOUT_WAIT_UNTIL_DONE = 40;
-    private static final int LAYOUT_DUMP_DATABASE_CALLBACKS = 41;
-    private static final int LAYOUT_SET_CAN_OPEN_WINDOWS = 42;
-    private static final int OVERRIDE_PREFERENCE = 43;
-    private static final int LAYOUT_DUMP_CHILD_FRAMES_TEXT = 44;
-    private static final int SET_XSS_AUDITOR_ENABLED = 45;
-    
-    CallbackProxy(EventSender eventSender, 
-            LayoutTestController layoutTestController) {
-        mEventSender = eventSender;
-        mLayoutTestController = layoutTestController;
-    }
-    
-    public void handleMessage(Message msg) {
-        switch (msg.what) {
-        case EVENT_DOM_LOG:
-            mEventSender.enableDOMUIEventLogging(msg.arg1);
-            break;
-        case EVENT_FIRE_KBD:
-            mEventSender.fireKeyboardEventsToElement(msg.arg1);
-            break;
-        case EVENT_KEY_DOWN_1:
-            HashMap map = (HashMap) msg.obj;
-            mEventSender.keyDown((String) map.get("character"), 
-                    (String[]) map.get("withModifiers"));
-            break;
-
-        case EVENT_KEY_DOWN_2:
-            mEventSender.keyDown((String)msg.obj);
-            break;
-
-        case EVENT_LEAP:
-            mEventSender.leapForward(msg.arg1);
-            break;
-
-        case EVENT_MOUSE_CLICK:
-            mEventSender.mouseClick();
-            break;
-
-        case EVENT_MOUSE_DOWN:
-            mEventSender.mouseDown();
-            break;
-
-        case EVENT_MOUSE_MOVE:
-            mEventSender.mouseMoveTo(msg.arg1, msg.arg2);
-            break;
-
-        case EVENT_MOUSE_UP:
-            mEventSender.mouseUp();
-            break;
-
-        case EVENT_TOUCH_START:
-            mEventSender.touchStart();
-            break;
-
-        case EVENT_TOUCH_MOVE:
-            mEventSender.touchMove();
-            break;
-
-        case EVENT_TOUCH_END:
-            mEventSender.touchEnd();
-            break;
-
-        case EVENT_TOUCH_CANCEL:
-            mEventSender.touchCancel();
-            break;
-
-        case EVENT_ADD_TOUCH_POINT:
-            mEventSender.addTouchPoint(msg.arg1, msg.arg2);
-            break;
-
-        case EVENT_UPDATE_TOUCH_POINT:
-            Bundle args = (Bundle) msg.obj;
-            int x = args.getInt("x");
-            int y = args.getInt("y");
-            int id = args.getInt("id");
-            mEventSender.updateTouchPoint(id, x, y);
-            break;
-
-        case EVENT_SET_TOUCH_MODIFIER:
-            Bundle modifierArgs = (Bundle) msg.obj;
-            String modifier = modifierArgs.getString("modifier");
-            boolean enabled = modifierArgs.getBoolean("enabled");
-            mEventSender.setTouchModifier(modifier, enabled);
-            break;
-
-        case EVENT_RELEASE_TOUCH_POINT:
-            mEventSender.releaseTouchPoint(msg.arg1);
-            break;
-
-        case EVENT_CLEAR_TOUCH_POINTS:
-            mEventSender.clearTouchPoints();
-            break;
-
-        case EVENT_CANCEL_TOUCH_POINT:
-            mEventSender.cancelTouchPoint(msg.arg1);
-            break;
-
-        case LAYOUT_CLEAR_LIST:
-            mLayoutTestController.clearBackForwardList();
-            break;
-
-        case LAYOUT_DISPLAY:
-            mLayoutTestController.display();
-            break;
-
-        case LAYOUT_DUMP_TEXT:
-            mLayoutTestController.dumpAsText(msg.arg1 == 1);
-            break;
-
-        case LAYOUT_DUMP_CHILD_FRAMES_TEXT:
-            mLayoutTestController.dumpChildFramesAsText();
-            break;
-
-        case LAYOUT_DUMP_HISTORY:
-            mLayoutTestController.dumpBackForwardList();
-            break;
-
-        case LAYOUT_DUMP_CHILD_SCROLL:
-            mLayoutTestController.dumpChildFrameScrollPositions();
-            break;
-
-        case LAYOUT_DUMP_EDIT_CB:
-            mLayoutTestController.dumpEditingCallbacks();
-            break;
-
-        case LAYOUT_DUMP_SEL_RECT:
-            mLayoutTestController.dumpSelectionRect();
-            break;
-
-        case LAYOUT_DUMP_TITLE_CHANGES:
-            mLayoutTestController.dumpTitleChanges();
-            break;
-
-        case LAYOUT_KEEP_WEB_HISTORY:
-            mLayoutTestController.keepWebHistory();
-            break;
-
-        case LAYOUT_NOTIFY_DONE:
-            mLayoutTestController.notifyDone();
-            break;
-
-        case LAYOUT_QUEUE_BACK_NAV:
-            mLayoutTestController.queueBackNavigation(msg.arg1);
-            break;
-
-        case LAYOUT_QUEUE_FWD_NAV:
-            mLayoutTestController.queueForwardNavigation(msg.arg1);
-            break;
-
-        case LAYOUT_QUEUE_LOAD:
-            HashMap<String, String> loadMap = 
-                (HashMap<String, String>) msg.obj;
-            mLayoutTestController.queueLoad(loadMap.get("Url"), 
-                    loadMap.get("frameTarget"));
-            break;
-
-        case LAYOUT_QUEUE_RELOAD:
-            mLayoutTestController.queueReload();
-            break;
-
-        case LAYOUT_QUEUE_SCRIPT:
-            mLayoutTestController.queueScript((String)msg.obj);
-            break;
-
-        case LAYOUT_REPAINT_HORZ:
-            mLayoutTestController.repaintSweepHorizontally();
-            break;
-
-        case LAYOUT_SET_ACCEPT_EDIT:
-            mLayoutTestController.setAcceptsEditing(
-                    msg.arg1 == 1 ? true : false);
-            break;
-        case LAYOUT_MAIN_FIRST_RESP:
-            mLayoutTestController.setMainFrameIsFirstResponder(
-                    msg.arg1 == 1 ? true : false);
-            break;
-
-        case LAYOUT_SET_WINDOW_KEY:
-            mLayoutTestController.setWindowIsKey(
-                    msg.arg1 == 1 ? true : false);
-            break;
-
-        case LAYOUT_TEST_REPAINT:
-            mLayoutTestController.testRepaint();
-            break;
-
-        case LAYOUT_WAIT_UNTIL_DONE:
-            mLayoutTestController.waitUntilDone();
-            break;
-
-        case LAYOUT_DUMP_DATABASE_CALLBACKS:
-            mLayoutTestController.dumpDatabaseCallbacks();
-            break;
-
-        case LAYOUT_SET_CAN_OPEN_WINDOWS:
-            mLayoutTestController.setCanOpenWindows();
-            break;
-
-        case OVERRIDE_PREFERENCE:
-            String key = msg.getData().getString("key");
-            boolean value = msg.getData().getBoolean("value");
-            mLayoutTestController.overridePreference(key, value);
-            break;
-
-        case SET_XSS_AUDITOR_ENABLED:
-            mLayoutTestController.setXSSAuditorEnabled(msg.arg1 == 1);
-            break;
-        }
-    }
-
-    // EventSender Methods
-    
-    public void enableDOMUIEventLogging(int DOMNode) {
-        obtainMessage(EVENT_DOM_LOG, DOMNode, 0).sendToTarget();
-    }
-
-    public void fireKeyboardEventsToElement(int DOMNode) {
-        obtainMessage(EVENT_FIRE_KBD, DOMNode, 0).sendToTarget();
-    }
-
-    public void keyDown(String character, String[] withModifiers) {
-        // TODO Auto-generated method stub
-        HashMap map = new HashMap();
-        map.put("character", character);
-        map.put("withModifiers", withModifiers);
-        obtainMessage(EVENT_KEY_DOWN_1, map).sendToTarget();
-    }
-
-    public void keyDown(String character) {
-        obtainMessage(EVENT_KEY_DOWN_2, character).sendToTarget();
-    }
-
-    public void leapForward(int milliseconds) {
-        obtainMessage(EVENT_LEAP, milliseconds, 0).sendToTarget(); 
-    }
-
-    public void mouseClick() {
-        obtainMessage(EVENT_MOUSE_CLICK).sendToTarget();
-    }
-
-    public void mouseDown() {
-        obtainMessage(EVENT_MOUSE_DOWN).sendToTarget();
-    }
-
-    public void mouseMoveTo(int X, int Y) {
-        obtainMessage(EVENT_MOUSE_MOVE, X, Y).sendToTarget();
-    }
-
-    public void mouseUp() {
-        obtainMessage(EVENT_MOUSE_UP).sendToTarget();
-    }
-
-    public void touchStart() {
-        obtainMessage(EVENT_TOUCH_START).sendToTarget();
-    }
-
-    public void addTouchPoint(int x, int y) {
-        obtainMessage(EVENT_ADD_TOUCH_POINT, x, y).sendToTarget();
-    }
-
-    public void updateTouchPoint(int id, int x, int y) {
-        Bundle map = new Bundle();
-        map.putInt("x", x);
-        map.putInt("y", y);
-        map.putInt("id", id);
-        obtainMessage(EVENT_UPDATE_TOUCH_POINT, map).sendToTarget();
-    }
-
-    public void setTouchModifier(String modifier, boolean enabled) {
-        Bundle map = new Bundle();
-        map.putString("modifier", modifier);
-        map.putBoolean("enabled", enabled);
-        obtainMessage(EVENT_SET_TOUCH_MODIFIER, map).sendToTarget();
-    }
-
-    public void touchMove() {
-        obtainMessage(EVENT_TOUCH_MOVE).sendToTarget();
-    }
-
-    public void releaseTouchPoint(int id) {
-        obtainMessage(EVENT_RELEASE_TOUCH_POINT, id, 0).sendToTarget();
-    }
-
-    public void touchEnd() {
-        obtainMessage(EVENT_TOUCH_END).sendToTarget();
-    }
-
-    public void touchCancel() {
-        obtainMessage(EVENT_TOUCH_CANCEL).sendToTarget();
-    }
-
-
-    public void clearTouchPoints() {
-        obtainMessage(EVENT_CLEAR_TOUCH_POINTS).sendToTarget();
-    }
-
-    public void cancelTouchPoint(int id) {
-        obtainMessage(EVENT_CANCEL_TOUCH_POINT, id, 0).sendToTarget();
-    }
-    
-    // LayoutTestController Methods
-
-    public void clearBackForwardList() {
-        obtainMessage(LAYOUT_CLEAR_LIST).sendToTarget();
-    }
-
-    public void display() {
-        obtainMessage(LAYOUT_DISPLAY).sendToTarget();
-    }
-
-    public void dumpAsText() {
-        obtainMessage(LAYOUT_DUMP_TEXT, 0).sendToTarget();
-    }
-
-    public void dumpAsText(boolean enablePixelTests) {
-        obtainMessage(LAYOUT_DUMP_TEXT, enablePixelTests ? 1 : 0).sendToTarget();
-    }
-
-    public void dumpChildFramesAsText() {
-        obtainMessage(LAYOUT_DUMP_CHILD_FRAMES_TEXT).sendToTarget();
-    }
-
-    public void dumpBackForwardList() {
-        obtainMessage(LAYOUT_DUMP_HISTORY).sendToTarget();
-    }
-
-    public void dumpChildFrameScrollPositions() {
-        obtainMessage(LAYOUT_DUMP_CHILD_SCROLL).sendToTarget();
-    }
-
-    public void dumpEditingCallbacks() {
-        obtainMessage(LAYOUT_DUMP_EDIT_CB).sendToTarget(); 
-    }
-
-    public void dumpSelectionRect() {
-        obtainMessage(LAYOUT_DUMP_SEL_RECT).sendToTarget(); 
-    }
-
-    public void dumpTitleChanges() {
-        obtainMessage(LAYOUT_DUMP_TITLE_CHANGES).sendToTarget();
-    }
-
-    public void keepWebHistory() {
-        obtainMessage(LAYOUT_KEEP_WEB_HISTORY).sendToTarget();
-    }
-
-    public void notifyDone() {
-        obtainMessage(LAYOUT_NOTIFY_DONE).sendToTarget();
-    }
-
-    public void queueBackNavigation(int howfar) {
-        obtainMessage(LAYOUT_QUEUE_BACK_NAV, howfar, 0).sendToTarget();
-    }
-
-    public void queueForwardNavigation(int howfar) {
-        obtainMessage(LAYOUT_QUEUE_FWD_NAV, howfar, 0).sendToTarget();
-    }
-
-    public void queueLoad(String Url, String frameTarget) {
-        HashMap <String, String>map = new HashMap<String, String>();
-        map.put("Url", Url);
-        map.put("frameTarget", frameTarget);
-        obtainMessage(LAYOUT_QUEUE_LOAD, map).sendToTarget();
-    }
-
-    public void queueReload() {
-        obtainMessage(LAYOUT_QUEUE_RELOAD).sendToTarget();
-    }
-
-    public void queueScript(String scriptToRunInCurrentContext) {
-        obtainMessage(LAYOUT_QUEUE_SCRIPT, 
-                scriptToRunInCurrentContext).sendToTarget();
-    }
-
-    public void repaintSweepHorizontally() {
-        obtainMessage(LAYOUT_REPAINT_HORZ).sendToTarget();
-    }
-
-    public void setAcceptsEditing(boolean b) {
-        obtainMessage(LAYOUT_SET_ACCEPT_EDIT, b ? 1 : 0, 0).sendToTarget();
-    }
-
-    public void setMainFrameIsFirstResponder(boolean b) {
-        obtainMessage(LAYOUT_MAIN_FIRST_RESP, b ? 1 : 0, 0).sendToTarget();
-    }
-
-    public void setWindowIsKey(boolean b) {
-        obtainMessage(LAYOUT_SET_WINDOW_KEY, b ? 1 : 0, 0).sendToTarget();
-    }
-
-    public void testRepaint() {
-        obtainMessage(LAYOUT_TEST_REPAINT).sendToTarget(); 
-    }
-
-    public void waitUntilDone() {
-        obtainMessage(LAYOUT_WAIT_UNTIL_DONE).sendToTarget();
-    }
-
-    public void dumpDatabaseCallbacks() {
-        obtainMessage(LAYOUT_DUMP_DATABASE_CALLBACKS).sendToTarget();
-    }
-
-    public void clearAllDatabases() {
-        WebStorage.getInstance().deleteAllData();
-    }
-
-    public void setDatabaseQuota(long quota) {
-        WebStorage.getInstance().setQuotaForOrigin("file://", quota);
-    }
-
-    public void setAppCacheMaximumSize(long size) {
-        android.webkit.WebStorageClassic.getInstance().setAppCacheMaximumSize(size);
-    }
-
-    public void setCanOpenWindows() {
-        obtainMessage(LAYOUT_SET_CAN_OPEN_WINDOWS).sendToTarget();
-    }
-
-    public void setMockGeolocationPosition(double latitude,
-                                           double longitude,
-                                           double accuracy) {
-        // Configuration is in WebKit, so stay on WebCore thread, but go via the TestShellActivity
-        // as we need access to the Webview.
-        mLayoutTestController.setMockGeolocationPosition(latitude,
-                                                         longitude,
-                                                         accuracy);
-    }
-
-    public void setMockGeolocationError(int code, String message) {
-        // Configuration is in WebKit, so stay on WebCore thread, but go via the TestShellActivity
-        // as we need access to the Webview.
-        mLayoutTestController.setMockGeolocationError(code, message);
-    }
-
-    public void setGeolocationPermission(boolean allow) {
-        // Configuration is in WebKit, so stay on WebCore thread, but go via the TestShellActivity
-        // as we need access to the Webview.
-        mLayoutTestController.setGeolocationPermission(allow);
-    }
-
-    public void setMockDeviceOrientation(boolean canProvideAlpha, double alpha,
-            boolean canProvideBeta, double beta, boolean canProvideGamma, double gamma) {
-        // Configuration is in WebKit, so stay on WebCore thread, but go via the TestShellActivity
-        // as we need access to the Webview.
-        mLayoutTestController.setMockDeviceOrientation(canProvideAlpha, alpha, canProvideBeta, beta,
-                canProvideGamma, gamma);
-    }
-
-    public void overridePreference(String key, boolean value) {
-        Message message = obtainMessage(OVERRIDE_PREFERENCE);
-        message.getData().putString("key", key);
-        message.getData().putBoolean("value", value);
-        message.sendToTarget();
-    }
-
-    public void setXSSAuditorEnabled(boolean flag) {
-        obtainMessage(SET_XSS_AUDITOR_ENABLED, flag ? 1 : 0, 0).sendToTarget();
-    }
-}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/EventSender.java b/tests/DumpRenderTree/src/com/android/dumprendertree/EventSender.java
deleted file mode 100644
index 23cc8f5..0000000
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/EventSender.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dumprendertree;
-
-public interface EventSender {
-    	public void mouseDown();
-    	public void mouseUp();
-        public void mouseClick();
-        public void mouseMoveTo(int X, int Y);
-        public void leapForward(int milliseconds);
-        public void keyDown (String character, String[] withModifiers);
-        public void keyDown (String character);
-        public void enableDOMUIEventLogging(int DOMNode);
-        public void fireKeyboardEventsToElement(int DOMNode);
-        public void touchStart();
-        public void touchMove();
-        public void touchEnd();
-        public void touchCancel();
-        public void addTouchPoint(int x, int y);
-        public void updateTouchPoint(int id, int x, int y);
-        public void setTouchModifier(String modifier, boolean enabled);
-        public void releaseTouchPoint(int id);
-        public void clearTouchPoints();
-        public void cancelTouchPoint(int id);
-}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java b/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
deleted file mode 100644
index d373d8d..0000000
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dumprendertree;
-
-import java.util.Vector;
-import android.util.*;
-
-public class FileFilter {
-
-    private static final String LOGTAG = "FileFilter";
-
-    // Returns whether we should ignore this test and skip running it.
-    // Currently we use this only for tests that crash or hang DumpRenderTree.
-    // TODO: Fix these and eliminate this method.
-    public static boolean ignoreTest(String file) {
-        for (int i = 0; i < ignoreTestList.length; i++) {
-            if (file.endsWith(ignoreTestList[i])) {
-                Log.v(LOGTAG, "File path in list of ignored tests: " + file);
-                return true;
-            }
-        }
-        return false;
-    }
-
-    // Returns whether a directory does not contain layout tests and so can be
-    // ignored.
-    public static boolean isNonTestDir(String file) {
-        for (int i = 0; i < nonTestDirs.length; i++) {
-            if (file.endsWith(nonTestDirs[i])) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    // Returns whether we should ignore the result of this test.
-    public static boolean ignoreResult(String file) {
-        for (int i = 0; i < ignoreResultList.size(); i++) {
-            if (file.endsWith(ignoreResultList.get(i))) {
-                Log.v(LOGTAG, "File path in list of ignored results: " + file);
-                return true;
-            }
-        }
-        return false;
-    }
-
-    final static Vector<String> ignoreResultList = new Vector<String>();
-
-    static {
-        fillIgnoreResultList();
-    }
-
-    static final String[] nonTestDirs = {
-        ".", // ignore hidden directories and files
-        "resources", // ignore resource directories
-        ".svn", // don't run anything under .svn folder
-        "platform"  // No-Android specific tests
-    };
-
-    static final String[] ignoreTestList = {
-        "canvas/philip/tests/2d.drawImage.broken.html", // blocks test, http://b/2982500
-        "editing/selection/move-left-right.html", // Causes DumpRenderTree to hang
-        "fast/js/excessive-comma-usage.html", // Tests huge initializer list, causes OOM.
-        "fast/js/regexp-charclass-crash.html", // RegExp is too large, causing OOM
-        "fast/js/regexp-overflow.html", // Result is too large, causing OOM when reading by DRT, http://b/2697589
-        "fast/regex/test1.html", // Causes DumpRenderTree to hang with V8
-        "fast/regex/slow.html", // Causes DumpRenderTree to hang with V8
-    };
-
-    static void fillIgnoreResultList() {
-        // This first block of tests are for features for which Android
-        // should pass all tests. They are skipped only temporarily.
-        // TODO: Fix these failing tests and remove them from this list.
-        ignoreResultList.add("fast/dom/HTMLKeygenElement/keygen.html"); // Missing layoutTestController.shadowRoot()
-        ignoreResultList.add("fast/dom/Geolocation/window-close-crash.html"); // Missing layoutTestContoller.setCloseRemainingWindowsWhenComplete()
-        ignoreResultList.add("fast/dom/Geolocation/page-reload-cancel-permission-requests.html"); // Missing layoutTestController.numberOfPendingGeolocationPermissionRequests()
-        ignoreResultList.add("fast/dom/HTMLLinkElement/link-and-subresource-test.html"); // Missing layoutTestController.dumpResourceResponseMIMETypes()
-        ignoreResultList.add("fast/dom/HTMLLinkElement/prefetch.html"); // Missing layoutTestController.dumpResourceResponseMIMETypes()
-        ignoreResultList.add("fast/dom/HTMLLinkElement/subresource.html"); // Missing layoutTestController.dumpResourceResponseMIMETypes()
-        ignoreResultList.add("fast/encoding/char-decoding.html"); // fails in Java HTTP stack, see http://b/issue?id=3047156
-        ignoreResultList.add("fast/encoding/hanarei-blog32-fc2-com.html"); // fails in Java HTTP stack, see http://b/issue?id=3046986
-        ignoreResultList.add("fast/encoding/mailto-always-utf-8.html"); // Requires waitForPolicyDelegate(), see http://b/issue?id=3043468
-        ignoreResultList.add("fast/encoding/percent-escaping.html"); // fails in Java HTTP stack, see http://b/issue?id=3046984
-        ignoreResultList.add("http/tests/appcache/empty-manifest.html"); // flaky
-        ignoreResultList.add("http/tests/appcache/fallback.html"); // http://b/issue?id=2713004
-        ignoreResultList.add("http/tests/appcache/foreign-fallback.html"); // Flaky, may be due to DRT, see http://b/3285647
-        ignoreResultList.add("http/tests/appcache/foreign-iframe-main.html"); // flaky - skips states
-        ignoreResultList.add("http/tests/appcache/manifest-with-empty-file.html"); // flaky
-        ignoreResultList.add("http/tests/appcache/origin-quota.html"); // needs clearAllApplicationCaches(), see http://b/issue?id=2944196
-        ignoreResultList.add("storage/database-lock-after-reload.html"); // Succeeds but DumpRenderTree does not read result correctly
-        ignoreResultList.add("storage/hash-change-with-xhr.html"); // Succeeds but DumpRenderTree does not read result correctly
-        ignoreResultList.add("storage/open-database-creation-callback-isolated-world.html"); // Requires layoutTestController.evaluateScriptInIsolatedWorld()
-        ignoreResultList.add("storage/statement-error-callback-isolated-world.html"); // Requires layoutTestController.evaluateScriptInIsolatedWorld()
-        ignoreResultList.add("storage/statement-success-callback-isolated-world.html"); // Requires layoutTestController.evaluateScriptInIsolatedWorld()
-        ignoreResultList.add("storage/storageinfo-query-usage.html"); // Need window.webkitStorageInfo
-        ignoreResultList.add("storage/transaction-callback-isolated-world.html"); // Requires layoutTestController.evaluateScriptInIsolatedWorld()
-        ignoreResultList.add("storage/transaction-error-callback-isolated-world.html"); // Requires layoutTestController.evaluateScriptInIsolatedWorld()
-        ignoreResultList.add("storage/transaction-success-callback-isolated-world.html"); // Requires layoutTestController.evaluateScriptInIsolatedWorld()
-        ignoreResultList.add("storage/domstorage/localstorage/storagetracker/storage-tracker-1-prepare.html"); // Missing layoutTestController.originsWithLocalStorage()
-        ignoreResultList.add("storage/domstorage/localstorage/storagetracker/storage-tracker-2-create.html"); // Missing layoutTestController.originsWithLocalStorage()
-        ignoreResultList.add("storage/domstorage/localstorage/storagetracker/storage-tracker-3-delete-all.html"); // Missing layoutTestController.originsWithLocalStorage()
-        ignoreResultList.add("storage/domstorage/localstorage/storagetracker/storage-tracker-4-create.html"); // Missing layoutTestController.originsWithLocalStorage()
-        ignoreResultList.add("storage/domstorage/localstorage/storagetracker/storage-tracker-5-delete-one.html"); // Missing layoutTestController.originsWithLocalStorage()
-
-
-        // Expected failures due to unsupported features or tests unsuitable for Android.
-        ignoreResultList.add("fast/encoding/char-decoding-mac.html"); // Mac-specific encodings (also marked Won't Fix in Chromium, bug 7388)
-        ignoreResultList.add("fast/encoding/char-encoding-mac.html"); // Mac-specific encodings (also marked Won't Fix in Chromium, bug 7388)
-        ignoreResultList.add("fast/encoding/idn-security.html"); // Mac-specific IDN checks (also marked Won't Fix in Chromium, bug 21814)
-        ignoreResultList.add("fast/events/touch/basic-multi-touch-events.html"); // Requires multi-touch gestures not supported by Android system
-        ignoreResultList.add("fast/events/touch/touch-coords-in-zoom-and-scroll.html"); // Requires eventSender.zoomPageIn(),zoomPageOut()
-        ignoreResultList.add("fast/events/touch/touch-target.html"); // Requires multi-touch gestures not supported by Android system
-        ignoreResultList.add("fast/workers"); // workers not supported
-        ignoreResultList.add("http/tests/cookies/third-party-cookie-relaxing.html"); // We don't support conditional acceptance of third-party cookies
-        ignoreResultList.add("http/tests/eventsource/workers"); // workers not supported
-        ignoreResultList.add("http/tests/workers"); // workers not supported
-        ignoreResultList.add("http/tests/xmlhttprequest/workers"); // workers not supported
-        ignoreResultList.add("storage/domstorage/localstorage/private-browsing-affects-storage.html"); // private browsing not supported
-        ignoreResultList.add("storage/domstorage/sessionstorage/private-browsing-affects-storage.html"); // private browsing not supported
-        ignoreResultList.add("storage/indexeddb"); // indexeddb not supported
-        ignoreResultList.add("storage/private-browsing-noread-nowrite.html"); // private browsing not supported
-        ignoreResultList.add("storage/private-browsing-readonly.html"); // private browsing not supported
-        ignoreResultList.add("websocket/tests/workers"); // workers not supported
-        ignoreResultList.add("dom/xhtml/level2/html/htmldocument04.xhtml"); // /mnt/sdcard on SR uses lowercase filesystem, this test checks filename and is case senstive.
-        ignoreResultList.add("dom/html/level2/html/htmldocument04.html"); // ditto
-
-        // Expected failures due to missing expected results
-        ignoreResultList.add("dom/xhtml/level3/core/canonicalform08.xhtml");
-        ignoreResultList.add("dom/xhtml/level3/core/canonicalform09.xhtml");
-        ignoreResultList.add("dom/xhtml/level3/core/documentgetinputencoding03.xhtml");
-        ignoreResultList.add("dom/xhtml/level3/core/entitygetinputencoding02.xhtml");
-        ignoreResultList.add("dom/xhtml/level3/core/entitygetxmlversion02.xhtml");
-        ignoreResultList.add("dom/xhtml/level3/core/nodegetbaseuri05.xhtml");
-        ignoreResultList.add("dom/xhtml/level3/core/nodegetbaseuri07.xhtml");
-        ignoreResultList.add("dom/xhtml/level3/core/nodegetbaseuri09.xhtml");
-        ignoreResultList.add("dom/xhtml/level3/core/nodegetbaseuri10.xhtml");
-        ignoreResultList.add("dom/xhtml/level3/core/nodegetbaseuri11.xhtml");
-        ignoreResultList.add("dom/xhtml/level3/core/nodegetbaseuri15.xhtml");
-        ignoreResultList.add("dom/xhtml/level3/core/nodegetbaseuri17.xhtml");
-        ignoreResultList.add("dom/xhtml/level3/core/nodegetbaseuri18.xhtml");
-        ignoreResultList.add("dom/xhtml/level3/core/nodelookupnamespaceuri01.xhtml");
-        ignoreResultList.add("dom/xhtml/level3/core/nodelookupprefix19.xhtml");
-
-        // TODO: These need to be triaged
-        ignoreResultList.add("fast/css/case-transform.html"); // will not fix #619707
-        ignoreResultList.add("fast/dom/Element/offsetLeft-offsetTop-body-quirk.html"); // different screen size result in extra spaces in Apple compared to us
-        ignoreResultList.add("fast/dom/Window/Plug-ins.html"); // need test plugin
-        ignoreResultList.add("fast/dom/Window/window-screen-properties.html"); // pixel depth
-        ignoreResultList.add("fast/dom/Window/window-xy-properties.html"); // requires eventSender.mouseDown(),mouseUp()
-        ignoreResultList.add("fast/dom/attribute-namespaces-get-set.html"); // http://b/733229
-        ignoreResultList.add("fast/dom/object-embed-plugin-scripting.html"); // dynamic plugins not supported
-        ignoreResultList.add("fast/dom/tabindex-clamp.html"); // there is extra spacing in the file due to multiple input boxes fitting on one line on Apple, ours are wrapped. Space at line ends are stripped.
-        ignoreResultList.add("fast/events/anchor-image-scrolled-x-y.html"); // requires eventSender.mouseDown(),mouseUp()
-        ignoreResultList.add("fast/events/arrow-navigation.html"); // http://b/735233
-        ignoreResultList.add("fast/events/capture-on-target.html"); // requires eventSender.mouseDown(),mouseUp()
-        ignoreResultList.add("fast/events/dblclick-addEventListener.html"); // requires eventSender.mouseDown(),mouseUp()
-        ignoreResultList.add("fast/events/drag-in-frames.html"); // requires eventSender.mouseDown(),mouseUp()
-        ignoreResultList.add("fast/events/drag-outside-window.html"); // requires eventSender.mouseDown(),mouseUp()
-        ignoreResultList.add("fast/events/event-view-toString.html"); // requires eventSender.mouseDown(),mouseUp()
-        ignoreResultList.add("fast/events/frame-click-focus.html"); // requires eventSender.mouseDown(),mouseUp()
-        ignoreResultList.add("fast/events/frame-tab-focus.html"); // http://b/734308
-        ignoreResultList.add("fast/events/iframe-object-onload.html"); // there is extra spacing in the file due to multiple frame boxes fitting on one line on Apple, ours are wrapped. Space at line ends are stripped.
-        ignoreResultList.add("fast/events/input-image-scrolled-x-y.html"); // requires eventSender.mouseDown(),mouseUp()
-        ignoreResultList.add("fast/events/mouseclick-target-and-positioning.html"); // requires eventSender.mouseDown(),mouseUp()
-        ignoreResultList.add("fast/events/mouseover-mouseout.html"); // requires eventSender.mouseDown(),mouseUp()
-        ignoreResultList.add("fast/events/mouseover-mouseout2.html"); // requires eventSender.mouseDown(),mouseUp()
-        ignoreResultList.add("fast/events/mouseup-outside-button.html"); // requires eventSender.mouseDown(),mouseUp()
-        ignoreResultList.add("fast/events/mouseup-outside-document.html"); // requires eventSender.mouseDown(),mouseUp()
-        ignoreResultList.add("fast/events/onclick-list-marker.html"); // requires eventSender.mouseDown(),mouseUp()
-        ignoreResultList.add("fast/events/ondragenter.html"); // requires eventSender.mouseDown(),mouseUp()
-        ignoreResultList.add("fast/events/onload-webkit-before-webcore.html"); // missing space in textrun, ok as text is wrapped. ignore. #714933
-        ignoreResultList.add("fast/events/option-tab.html"); // http://b/734308
-        ignoreResultList.add("fast/events/window-events-bubble.html"); // requires eventSender.mouseDown(),mouseUp()
-        ignoreResultList.add("fast/events/window-events-bubble2.html"); // requires eventSender.mouseDown(),mouseUp()
-        ignoreResultList.add("fast/events/window-events-capture.html"); // requires eventSender.mouseDown(),mouseUp()
-        ignoreResultList.add("fast/forms/drag-into-textarea.html"); // requires eventSender.mouseDown(),mouseUp()
-        ignoreResultList.add("fast/forms/focus-control-to-page.html"); // http://b/716638
-        ignoreResultList.add("fast/forms/focus2.html"); // http://b/735111
-        ignoreResultList.add("fast/forms/form-data-encoding-2.html"); // charset convert. #516936 ignore, won't fix
-        ignoreResultList.add("fast/forms/form-data-encoding.html"); // charset convert. #516936 ignore, won't fix
-        ignoreResultList.add("fast/forms/input-appearance-maxlength.html"); // execCommand "insertText" not supported
-        ignoreResultList.add("fast/forms/input-select-on-click.html"); // requires eventSender.mouseDown(),mouseUp()
-        ignoreResultList.add("fast/forms/listbox-onchange.html"); // requires eventSender.mouseDown(),mouseUp()
-        ignoreResultList.add("fast/forms/listbox-selection.html"); // http://b/735116
-        ignoreResultList.add("fast/forms/onselect-textarea.html"); // requires eventSender.mouseMoveTo, mouseDown & mouseUp and abs. position of mouse to select a word. ignore, won't fix #716583
-        ignoreResultList.add("fast/forms/onselect-textfield.html"); // requires eventSender.mouseMoveTo, mouseDown & mouseUp and abs. position of mouse to select a word. ignore, won't fix #716583
-        ignoreResultList.add("fast/forms/plaintext-mode-1.html"); // not implemented queryCommandEnabled:BackColor, Undo & Redo
-        ignoreResultList.add("fast/forms/search-cancel-button-mouseup.html"); // requires eventSender.mouseDown(),mouseUp()
-        ignoreResultList.add("fast/forms/search-event-delay.html"); // http://b/735120
-        ignoreResultList.add("fast/forms/select-empty-list.html"); // requires eventSender.mouseDown(),mouseUp()
-        ignoreResultList.add("fast/forms/select-type-ahead-non-latin.html"); // http://b/735244
-        ignoreResultList.add("fast/forms/selected-index-assert.html"); // not capturing the console messages
-        ignoreResultList.add("fast/forms/selection-functions.html"); // there is extra spacing as the text areas and input boxes fit next to each other on Apple, but are wrapped on our screen.
-        ignoreResultList.add("fast/forms/textarea-appearance-wrap.html"); // Our text areas are a little thinner than Apples. Also RTL test failes
-        ignoreResultList.add("fast/forms/textarea-initial-caret-position.html"); // Text selection done differently on our platform. When a inputbox gets focus, the entire block is selected.
-        ignoreResultList.add("fast/forms/textarea-no-scroll-on-blur.html"); // Text selection done differently on our platform. When a inputbox gets focus, the entire block is selected.
-        ignoreResultList.add("fast/forms/textarea-paste-newline.html"); // Copy&Paste commands not supported
-        ignoreResultList.add("fast/forms/textarea-scrolled-endline-caret.html"); // requires eventSender.mouseDown(),mouseUp()
-        ignoreResultList.add("fast/frames/iframe-window-focus.html"); // http://b/735140
-        ignoreResultList.add("fast/frames/frameElement-widthheight.html"); // screen width&height are different
-        ignoreResultList.add("fast/frames/frame-js-url-clientWidth.html"); // screen width&height are different
-        ignoreResultList.add("fast/html/tab-order.html"); // http://b/719289
-        ignoreResultList.add("fast/js/navigator-mimeTypes-length.html"); // dynamic plugins not supported
-        ignoreResultList.add("fast/js/string-capitalization.html"); // http://b/516936
-        ignoreResultList.add("fast/loader/local-JavaScript-from-local.html"); // Requires LayoutTests to exist at /tmp/LayoutTests
-        ignoreResultList.add("fast/loader/local-iFrame-source-from-local.html"); // Requires LayoutTests to exist at /tmp/LayoutTests
-        ignoreResultList.add("fast/loader/opaque-base-url.html"); // extra spacing because iFrames rendered next to each other on Apple
-        ignoreResultList.add("fast/overflow/scroll-vertical-not-horizontal.html"); // http://b/735196
-        ignoreResultList.add("fast/parser/script-tag-with-trailing-slash.html"); // not capturing the console messages
-        ignoreResultList.add("fast/replaced/image-map.html"); // requires eventSender.mouseDown(),mouseUp()
-        ignoreResultList.add("fast/text/plain-text-line-breaks.html"); // extra spacing because iFrames rendered next to each other on Apple
-        ignoreResultList.add("profiler"); // profiler is not supported
-    }
-
-}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/FileList.java b/tests/DumpRenderTree/src/com/android/dumprendertree/FileList.java
deleted file mode 100644
index 4a47a0e..0000000
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/FileList.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dumprendertree;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.io.File;
-
-import android.app.AlertDialog;
-import android.app.ListActivity;
-import android.content.DialogInterface;
-import android.view.KeyEvent;
-import android.view.View;
-import android.widget.ListView;
-import android.widget.SimpleAdapter;
-import android.os.Bundle;
-import android.os.Environment;
-
-
-public abstract class FileList extends ListActivity
-{
-	public boolean onKeyDown(int keyCode, KeyEvent event) {
-		switch (keyCode)
-		{
-			case KeyEvent.KEYCODE_DPAD_LEFT:
-				if (mPath.length() > mBaseLength) {
-					File f = new File(mPath);
-					mFocusFile = f.getName();
-					mFocusIndex = 0;
-					f = f.getParentFile();
-					mPath = f.getPath();
-					updateList();
-					return true;
-				}
-				break;
-
-			case KeyEvent.KEYCODE_DPAD_RIGHT:
-				{
-					Map map = (Map) getListView().getItemAtPosition(getListView().getSelectedItemPosition());
-					String path = (String)map.get("path");
-					if ((new File(path)).isDirectory()) {
-						mPath = path;
-				        mFocusFile = null;
-						updateList();
-					} else {
-						processFile(path, false);
-					}
-                    return true;
-				}
-
-			default:
-				break;
-		}
-		return super.onKeyDown(keyCode, event);
-	}
-
-	public void onCreate(Bundle icicle)
-    {
-        super.onCreate(icicle);
-        setupPath();
-        updateList();
-    }
-
-    protected List getData()
-    {
-        List myData = new ArrayList<HashMap>();
-
-        File f = new File(mPath);
-        if (!f.exists()) {
-        	addItem(myData, "!LayoutTests path missing!", "");
-        	return myData;
-        }
-        String[] files = f.list();
-        Arrays.sort(files);
-
-        for (int i = 0; i < files.length; i++) {
-        	StringBuilder sb = new StringBuilder(mPath);
-        	sb.append(File.separatorChar);
-        	sb.append(files[i]);
-        	String path = sb.toString();
-        	File c = new File(path);
-        	if (fileFilter(c)) {
-	        	if (c.isDirectory()) {
-	        		addItem(myData, "<"+files[i]+">", path);
-	        		if (mFocusFile != null && mFocusFile.equals(files[i]))
-	        			mFocusIndex = myData.size()-1;
-	        	}
-	        	else
-	        	    addItem(myData, files[i], path);
-        	}
-        }
-
-        return myData;
-    }
-
-    protected void addItem(List<Map> data, String name, String path)
-    {
-        HashMap temp = new HashMap();
-        temp.put("title", name);
-        temp.put("path", path);
-        data.add(temp);
-    }
-
-    protected void onListItemClick(ListView l, View v, int position, long id)
-    {
-        Map map = (Map) l.getItemAtPosition(position);
-        final String path = (String)map.get("path");
-
-        if ((new File(path)).isDirectory()) {
-            final CharSequence[] items = {"Open", "Run"};
-            AlertDialog.Builder builder = new AlertDialog.Builder(this);
-            builder.setTitle("Select an Action");
-            builder.setSingleChoiceItems(items, -1,
-                    new DialogInterface.OnClickListener(){
-                public void onClick(DialogInterface dialog, int which) {
-                    switch (which) {
-                        case OPEN_DIRECTORY:
-                            dialog.dismiss();
-                            mPath = path;
-                            mFocusFile = null;
-                            updateList();
-                            break;
-                        case RUN_TESTS:
-                            dialog.dismiss();
-                            processDirectory(path, false);
-                            break;
-                    }
-                }
-            });
-            builder.create().show();
-        } else {
-            processFile(path, false);
-        }
-    }
-
-    /*
-     * This function is called when the user has selected a directory in the
-     * list and wants to perform an action on it instead of navigating into
-     * the directory.
-     */
-    abstract void processDirectory(String path, boolean selection);
-    /*
-     * This function is called when the user has selected a file in the
-     * file list. The selected file could be a file or a directory.
-     * The flag indicates if this was from a selection or not.
-     */
-    abstract void processFile(String filename, boolean selection);
-
-    /*
-     * This function is called when the file list is being built. Return
-     * true if the file is to be added to the file list.
-     */
-    abstract boolean fileFilter(File f);
-
-    protected void updateList() {
-        setListAdapter(new SimpleAdapter(this,
-                getData(),
-                android.R.layout.simple_list_item_1,
-                new String[] {"title"},
-                new int[] {android.R.id.text1}));
-        String title = mPath; //.substring(mBaseLength-11); // show the word LayoutTests
-        setTitle(title);
-        getListView().setSelection(mFocusIndex);
-    }
-
-    protected void setupPath() {
-        mPath = Environment.getExternalStorageDirectory() + "/webkit/layout_tests";
-        mBaseLength = mPath.length();
-    }
-
-    protected String mPath;
-    protected int mBaseLength;
-    protected String mFocusFile;
-    protected int mFocusIndex;
-
-    private final static int OPEN_DIRECTORY = 0;
-    private final static int RUN_TESTS = 1;
-
-}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java b/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java
deleted file mode 100644
index b7d2c26..0000000
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java
+++ /dev/null
@@ -1,225 +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.dumprendertree;
-
-import com.android.dumprendertree.forwarder.ForwardService;
-
-import android.os.Environment;
-import android.util.Log;
-
-import java.io.BufferedOutputStream;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.regex.Pattern;
-
-public class FsUtils {
-
-    private static final String LOGTAG = "FsUtils";
-    static final String EXTERNAL_DIR = Environment.getExternalStorageDirectory().toString();
-    static final String HTTP_TESTS_PREFIX =
-        EXTERNAL_DIR + "/webkit/layout_tests/http/tests/";
-    static final String HTTPS_TESTS_PREFIX =
-        EXTERNAL_DIR + "/webkit/layout_tests/http/tests/ssl/";
-    static final String HTTP_LOCAL_TESTS_PREFIX =
-        EXTERNAL_DIR + "/webkit/layout_tests/http/tests/local/";
-    static final String HTTP_MEDIA_TESTS_PREFIX =
-        EXTERNAL_DIR + "/webkit/layout_tests/http/tests/media/";
-    static final String HTTP_WML_TESTS_PREFIX =
-        EXTERNAL_DIR + "/webkit/layout_tests/http/tests/wml/";
-
-    private FsUtils() {
-        //no creation of instances
-    }
-
-    /**
-     * @return the number of tests in the list.
-     */
-    public static int writeLayoutTestListRecursively(BufferedOutputStream bos,
-            String dir, boolean ignoreResultsInDir) throws IOException {
-
-        int testCount = 0;
-        Log.v(LOGTAG, "Searching tests under " + dir);
-
-        File d = new File(dir);
-        if (!d.isDirectory()) {
-            throw new AssertionError("A directory expected, but got " + dir);
-        }
-        ignoreResultsInDir |= FileFilter.ignoreResult(dir);
-
-        String[] files = d.list();
-        for (int i = 0; i < files.length; i++) {
-            String s = dir + "/" + files[i];
-
-            File f = new File(s);
-            if (f.isDirectory()) {
-                // If this is not a test directory, we don't recurse into it.
-                if (!FileFilter.isNonTestDir(s)) {
-                    Log.v(LOGTAG, "Recursing on " + s);
-                    testCount += writeLayoutTestListRecursively(bos, s, ignoreResultsInDir);
-                }
-                continue;
-            }
-
-            // If this test should be ignored, we skip it completely.
-            if (FileFilter.ignoreTest(s)) {
-                Log.v(LOGTAG, "Ignoring: " + s);
-                continue;
-            }
-
-            if ((s.toLowerCase().endsWith(".html")
-                    || s.toLowerCase().endsWith(".xml")
-                    || s.toLowerCase().endsWith(".xhtml"))
-                    && !s.endsWith("TEMPLATE.html")) {
-                Log.v(LOGTAG, "Recording " + s);
-                bos.write(s.getBytes());
-                // If the result of this test should be ignored, we still run the test.
-                if (ignoreResultsInDir || FileFilter.ignoreResult(s)) {
-                    bos.write((" IGNORE_RESULT").getBytes());
-                }
-                bos.write('\n');
-                testCount++;
-            }
-        }
-        return testCount;
-    }
-
-    public static void updateTestStatus(String statusFile, String s) {
-        try {
-            BufferedOutputStream bos = new BufferedOutputStream(
-                    new FileOutputStream(statusFile));
-            bos.write(s.getBytes());
-            bos.close();
-        } catch (Exception e) {
-            Log.e(LOGTAG, "Cannot update file " + statusFile);
-        }
-    }
-
-    public static String readTestStatus(String statusFile) {
-        // read out the test name it stopped last time.
-        String status = null;
-        File testStatusFile = new File(statusFile);
-        if(testStatusFile.exists()) {
-            try {
-                BufferedReader inReader = new BufferedReader(
-                        new FileReader(testStatusFile));
-                status = inReader.readLine();
-                inReader.close();
-            } catch (IOException e) {
-                Log.e(LOGTAG, "Error reading test status.", e);
-            }
-        }
-        return status;
-    }
-
-    public static String getTestUrl(String path) {
-        String url = null;
-        if (!path.startsWith(HTTP_TESTS_PREFIX)) {
-            url = "file://" + path;
-        } else {
-            ForwardService.getForwardService().startForwardService();
-            if (path.startsWith(HTTPS_TESTS_PREFIX)) {
-                // still cut the URL after "http/tests/"
-                url = "https://127.0.0.1:8443/" + path.substring(HTTP_TESTS_PREFIX.length());
-            } else if (!path.startsWith(HTTP_LOCAL_TESTS_PREFIX)
-                    && !path.startsWith(HTTP_MEDIA_TESTS_PREFIX)
-                    && !path.startsWith(HTTP_WML_TESTS_PREFIX)) {
-                url = "http://127.0.0.1:8000/" + path.substring(HTTP_TESTS_PREFIX.length());
-            } else {
-                url = "file://" + path;
-            }
-        }
-        return url;
-    }
-
-    public static boolean diffIgnoreSpaces(String file1, String file2)  throws IOException {
-        BufferedReader br1 = new BufferedReader(new FileReader(file1));
-        BufferedReader br2 = new BufferedReader(new FileReader(file2));
-        boolean same = true;
-        Pattern trailingSpace = Pattern.compile("\\s+$");
-
-        while(true) {
-            String line1 = br1.readLine();
-            String line2 = br2.readLine();
-
-            if (line1 == null && line2 == null)
-                break;
-            if (line1 != null) {
-                line1 = trailingSpace.matcher(line1).replaceAll("");
-            } else {
-                line1 = "";
-            }
-            if (line2 != null) {
-                line2 = trailingSpace.matcher(line2).replaceAll("");
-            } else {
-                line2 = "";
-            }
-            if(!line1.equals(line2)) {
-                same = false;
-                break;
-            }
-        }
-
-        br1.close();
-        br2.close();
-
-        return same;
-    }
-
-    public static boolean isTestPageUrl(String url) {
-        int qmPostion = url.indexOf('?');
-        int slashPostion = url.lastIndexOf('/');
-        if (slashPostion < qmPostion) {
-            String fileName = url.substring(slashPostion + 1, qmPostion);
-            if ("index.html".equals(fileName)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public static String getLastSegmentInPath(String path) {
-        int endPos = path.lastIndexOf('/');
-        path = path.substring(0, endPos);
-        endPos = path.lastIndexOf('/');
-        return path.substring(endPos + 1);
-    }
-
-    public static void writeDrawTime(String fileName, String url, long[] times) {
-        StringBuffer lineBuffer = new StringBuffer();
-        // grab the last segment of path in url
-        lineBuffer.append(getLastSegmentInPath(url));
-        for (long time : times) {
-            lineBuffer.append('\t');
-            lineBuffer.append(time);
-        }
-        lineBuffer.append('\n');
-        String line = lineBuffer.toString();
-        Log.v(LOGTAG, "logging draw times: " + line);
-        try {
-            FileWriter fw = new FileWriter(fileName, true);
-            fw.write(line);
-            fw.close();
-        } catch (IOException ioe) {
-            Log.e(LOGTAG, "Failed to log draw times", ioe);
-        }
-    }
-
-}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/HTMLHostApp.java b/tests/DumpRenderTree/src/com/android/dumprendertree/HTMLHostApp.java
deleted file mode 100644
index f610f5a..0000000
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/HTMLHostApp.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dumprendertree;
-
-import android.app.Application;
-
-public class HTMLHostApp extends Application { 
-
-	public HTMLHostApp() {
-    }
-
-    public void onCreate() {
-    }
-
-    public void onTerminate() {
-    }
-	
-}
-
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestController.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestController.java
deleted file mode 100644
index c936a6c..0000000
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestController.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dumprendertree;
-
-public interface LayoutTestController {
-
-    public void dumpAsText(boolean enablePixelTests);
-    public void dumpChildFramesAsText();
-    public void waitUntilDone();
-    public void notifyDone();
-
-    // Force a redraw of the page
-    public void display();
-    // Used with pixel dumps of content
-    public void testRepaint();
-
-    // If the page title changes, add the information to the output.
-    public void dumpTitleChanges();
-    public void dumpBackForwardList();
-    public void dumpChildFrameScrollPositions();
-    public void dumpEditingCallbacks();
-
-    // Show/Hide window for window.onBlur() testing
-    public void setWindowIsKey(boolean b);
-    // Mac function, used to disable events going to the window
-    public void setMainFrameIsFirstResponder(boolean b);
-
-    public void dumpSelectionRect();
-
-    // invalidate and draw one line at a time of the web view.
-    public void repaintSweepHorizontally();
-    
-    // History testing functions
-    public void keepWebHistory();
-    public void clearBackForwardList();
-    // navigate after page load has finished
-    public void queueBackNavigation(int howfar);
-    public void queueForwardNavigation(int howfar);
-    
-    // Reload when the page load has finished
-    public void queueReload();
-    // Execute the provided script in current context when page load has finished.
-    public void queueScript(String scriptToRunInCurrentContext);
-    // Load the provided URL into the provided frame
-    public void queueLoad(String Url, String frameTarget);
-
-    public void setAcceptsEditing(boolean b);
-
-    // For storage tests
-    public void dumpDatabaseCallbacks();
-    public void setCanOpenWindows();
-
-    // For Geolocation tests
-    public void setGeolocationPermission(boolean allow);
-
-    public void overridePreference(String key, boolean value);
-
-    // For XSSAuditor tests
-    public void setXSSAuditorEnabled(boolean flag);
-
-    // For Geolocation tests
-    public void setMockGeolocationPosition(double latitude, double longitude, double accuracy);
-    public void setMockGeolocationError(int code, String message);
-
-    // For DeviceOrientation tests
-    public void setMockDeviceOrientation(boolean canProvideAlpha, double alpha,
-            boolean canProvideBeta, double beta, boolean canProvideGamma, double gamma);
-}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoRunner.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoRunner.java
deleted file mode 100644
index fb2a1f4..0000000
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoRunner.java
+++ /dev/null
@@ -1,80 +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.dumprendertree;
-
-import android.os.Bundle;
-import android.test.InstrumentationTestRunner;
-import android.test.InstrumentationTestSuite;
-
-import junit.framework.TestSuite;
-
-
-/**
- * Instrumentation Test Runner for all DumpRenderTree tests.
- *
- * Running all tests:
- *
- * adb shell am instrument \
- *   -w com.android.dumprendertree.LayoutTestsAutoRunner
- */
-
-public class LayoutTestsAutoRunner extends InstrumentationTestRunner {
-    @Override
-    public TestSuite getAllTests() {
-        TestSuite suite = new InstrumentationTestSuite(this);
-        suite.addTestSuite(LayoutTestsAutoTest.class);
-        suite.addTestSuite(LoadTestsAutoTest.class);
-        return suite;
-    }
-
-    @Override
-    public ClassLoader getLoader() {
-        return LayoutTestsAutoRunner.class.getClassLoader();
-    }
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        this.mTestPath = (String) icicle.get("path");
-        String timeout_str = (String) icicle.get("timeout");
-        if (timeout_str != null) {
-            try {
-                this.mTimeoutInMillis = Integer.parseInt(timeout_str);
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
-
-        String r = icicle.getString("rebaseline");
-        this.mRebaseline = (r != null && r.toLowerCase().equals("true"));
-
-        mJsEngine = icicle.getString("jsengine");
-
-        mPageCyclerSuite = icicle.getString("suite");
-        mPageCyclerForwardHost = icicle.getString("forward");
-        mPageCyclerIteration = icicle.getString("iteration", "5");
-
-        super.onCreate(icicle);
-    }
-
-    String mPageCyclerSuite;
-    String mPageCyclerForwardHost;
-    String mPageCyclerIteration;
-    String mTestPath;
-    int mTimeoutInMillis = 0;
-    boolean mRebaseline;
-    String mJsEngine;
-}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java
deleted file mode 100644
index 3fe4e70..0000000
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.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.dumprendertree;
-
-import com.android.dumprendertree.TestShellActivity.DumpDataType;
-import com.android.dumprendertree.forwarder.AdbUtils;
-import com.android.dumprendertree.forwarder.ForwardService;
-
-import android.content.Context;
-import android.content.Intent;
-import android.os.Environment;
-import android.test.ActivityInstrumentationTestCase2;
-import android.util.Log;
-
-import java.io.BufferedOutputStream;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Vector;
-
-// TestRecorder creates four files ...
-// - passing tests
-// - failing tests
-// - tests for which results are ignored
-// - tests with no text results available
-// TestRecorder does not have the ability to clear the results.
-class MyTestRecorder {
-    private BufferedOutputStream mBufferedOutputPassedStream;
-    private BufferedOutputStream mBufferedOutputFailedStream;
-    private BufferedOutputStream mBufferedOutputIgnoreResultStream;
-    private BufferedOutputStream mBufferedOutputNoResultStream;
-
-    public void passed(String layout_file) {
-        try {
-            mBufferedOutputPassedStream.write(layout_file.getBytes());
-            mBufferedOutputPassedStream.write('\n');
-            mBufferedOutputPassedStream.flush();
-        } catch(Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    public void failed(String layout_file) {
-        try {
-            mBufferedOutputFailedStream.write(layout_file.getBytes());
-            mBufferedOutputFailedStream.write('\n');
-            mBufferedOutputFailedStream.flush();
-        } catch(Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    public void ignoreResult(String layout_file) {
-        try {
-            mBufferedOutputIgnoreResultStream.write(layout_file.getBytes());
-            mBufferedOutputIgnoreResultStream.write('\n');
-            mBufferedOutputIgnoreResultStream.flush();
-        } catch(Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    public void noResult(String layout_file) {
-        try {
-            mBufferedOutputNoResultStream.write(layout_file.getBytes());
-            mBufferedOutputNoResultStream.write('\n');
-            mBufferedOutputNoResultStream.flush();
-        } catch(Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    public MyTestRecorder(boolean resume) {
-        try {
-            File externalDir = Environment.getExternalStorageDirectory();
-            File resultsPassedFile = new File(externalDir, "layout_tests_passed.txt");
-            File resultsFailedFile = new File(externalDir, "layout_tests_failed.txt");
-            File resultsIgnoreResultFile = new File(externalDir, "layout_tests_ignored.txt");
-            File noExpectedResultFile = new File(externalDir, "layout_tests_nontext.txt");
-
-            mBufferedOutputPassedStream =
-                new BufferedOutputStream(new FileOutputStream(resultsPassedFile, resume));
-            mBufferedOutputFailedStream =
-                new BufferedOutputStream(new FileOutputStream(resultsFailedFile, resume));
-            mBufferedOutputIgnoreResultStream =
-                new BufferedOutputStream(new FileOutputStream(resultsIgnoreResultFile, resume));
-            mBufferedOutputNoResultStream =
-                new BufferedOutputStream(new FileOutputStream(noExpectedResultFile, resume));
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    public void close() {
-        try {
-            mBufferedOutputPassedStream.close();
-            mBufferedOutputFailedStream.close();
-            mBufferedOutputIgnoreResultStream.close();
-            mBufferedOutputNoResultStream.close();
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-}
-
-
-public class LayoutTestsAutoTest extends ActivityInstrumentationTestCase2<TestShellActivity> {
-
-    private static final String LOGTAG = "LayoutTests";
-    static final int DEFAULT_TIMEOUT_IN_MILLIS = 5000;
-
-    static final String EXTERNAL_DIR = Environment.getExternalStorageDirectory().toString();
-    static final String LAYOUT_TESTS_ROOT = EXTERNAL_DIR + "/webkit/layout_tests/";
-    static final String LAYOUT_TESTS_RESULT_DIR = EXTERNAL_DIR + "/webkit/layout_tests_results/";
-    static final String ANDROID_EXPECTED_RESULT_DIR = EXTERNAL_DIR + "/webkit/expected_results/";
-    static final String LAYOUT_TESTS_LIST_FILE = EXTERNAL_DIR + "/webkit/layout_tests_list.txt";
-    static final String TEST_STATUS_FILE = EXTERNAL_DIR + "/webkit/running_test.txt";
-    static final String LAYOUT_TESTS_RESULTS_REFERENCE_FILES[] = {
-          "results/layout_tests_passed.txt",
-          "results/layout_tests_failed.txt",
-          "results/layout_tests_nontext.txt",
-          "results/layout_tests_crashed.txt",
-          "run_layout_tests.py"
-    };
-
-    static final String LAYOUT_RESULTS_FAILED_RESULT_FILE = "results/layout_tests_failed.txt";
-    static final String LAYOUT_RESULTS_NONTEXT_RESULT_FILE = "results/layout_tests_nontext.txt";
-    static final String LAYOUT_RESULTS_CRASHED_RESULT_FILE = "results/layout_tests_crashed.txt";
-    static final String LAYOUT_TESTS_RUNNER = "run_layout_tests.py";
-
-    private MyTestRecorder mResultRecorder;
-    private Vector<String> mTestList;
-    // Whether we should ignore the result for the corresponding test. Ordered same as mTestList.
-    private Vector<Boolean> mTestListIgnoreResult;
-    private boolean mRebaselineResults;
-    // The JavaScript engine currently in use. This determines which set of Android-specific
-    // expected test results we use.
-    private String mJsEngine;
-    private String mTestPathPrefix;
-    private boolean mFinished;
-    private int mTestCount;
-    private int mResumeIndex;
-
-    public LayoutTestsAutoTest() {
-      super(TestShellActivity.class);
-    }
-
-    private void getTestList() {
-        // Read test list.
-        try {
-            BufferedReader inReader = new BufferedReader(new FileReader(LAYOUT_TESTS_LIST_FILE));
-            String line = inReader.readLine();
-            while (line != null) {
-                if (line.startsWith(mTestPathPrefix)) {
-                    String[] components = line.split(" ");
-                    mTestList.add(components[0]);
-                    mTestListIgnoreResult.add(components.length > 1 && components[1].equals("IGNORE_RESULT"));
-                }
-                line = inReader.readLine();
-            }
-            inReader.close();
-            Log.v(LOGTAG, "Test list has " + mTestList.size() + " test(s).");
-        } catch (Exception e) {
-            Log.e(LOGTAG, "Error while reading test list : " + e.getMessage());
-        }
-        mTestCount = mTestList.size();
-    }
-
-    private void resumeTestList() {
-        // read out the test name it stoped last time.
-        try {
-            String line = FsUtils.readTestStatus(TEST_STATUS_FILE);
-            for (int i = 0; i < mTestList.size(); i++) {
-                if (mTestList.elementAt(i).equals(line)) {
-                    mTestList = new Vector<String>(mTestList.subList(i+1, mTestList.size()));
-                    mTestListIgnoreResult = new Vector<Boolean>(mTestListIgnoreResult.subList(i+1, mTestListIgnoreResult.size()));
-                    mResumeIndex = i + 1;
-                    break;
-                }
-            }
-        } catch (Exception e) {
-            Log.e(LOGTAG, "Error reading " + TEST_STATUS_FILE);
-        }
-    }
-
-    private void clearTestStatus() {
-        // Delete TEST_STATUS_FILE
-        try {
-            File f = new File(TEST_STATUS_FILE);
-            if (f.delete())
-                Log.v(LOGTAG, "Deleted " + TEST_STATUS_FILE);
-            else
-                Log.e(LOGTAG, "Fail to delete " + TEST_STATUS_FILE);
-        } catch (Exception e) {
-            Log.e(LOGTAG, "Fail to delete " + TEST_STATUS_FILE + " : " + e.getMessage());
-        }
-    }
-
-    private String getResultFile(String test) {
-        String shortName = test.substring(0, test.lastIndexOf('.'));
-        // Write actual results to result directory.
-        return shortName.replaceFirst(LAYOUT_TESTS_ROOT, LAYOUT_TESTS_RESULT_DIR) + "-result.txt";
-    }
-
-    // Gets the file which contains WebKit's expected results for this test.
-    private String getExpectedResultFile(String test) {
-        // The generic result is at <path>/<name>-expected.txt
-        // First try the Android-specific result at
-        // platform/android-<js-engine>/<path>/<name>-expected.txt
-        // then
-        // platform/android/<path>/<name>-expected.txt
-        int pos = test.lastIndexOf('.');
-        if (pos == -1)
-            return null;
-        String genericExpectedResult = test.substring(0, pos) + "-expected.txt";
-        String androidExpectedResultsDir = "platform/android-" + mJsEngine + "/";
-        String androidExpectedResult = genericExpectedResult.replaceFirst(LAYOUT_TESTS_ROOT,
-                LAYOUT_TESTS_ROOT + androidExpectedResultsDir);
-        File f = new File(androidExpectedResult);
-        if (f.exists())
-            return androidExpectedResult;
-        androidExpectedResultsDir = "platform/android/";
-        androidExpectedResult = genericExpectedResult.replaceFirst(LAYOUT_TESTS_ROOT,
-                LAYOUT_TESTS_ROOT + androidExpectedResultsDir);
-        f = new File(androidExpectedResult);
-        return f.exists() ? androidExpectedResult : genericExpectedResult;
-    }
-
-    // Gets the file which contains the actual results of running the test on
-    // Android, generated by a previous run which set a new baseline.
-    private String getAndroidExpectedResultFile(String expectedResultFile) {
-        return expectedResultFile.replaceFirst(LAYOUT_TESTS_ROOT, ANDROID_EXPECTED_RESULT_DIR);
-    }
-
-    // Wrap up
-    private void failedCase(String file) {
-        Log.w("Layout test: ", file + " failed");
-        mResultRecorder.failed(file);
-    }
-
-    private void passedCase(String file) {
-        Log.v("Layout test:", file + " passed");
-        mResultRecorder.passed(file);
-    }
-
-    private void ignoreResultCase(String file) {
-        Log.v("Layout test:", file + " ignore result");
-        mResultRecorder.ignoreResult(file);
-    }
-
-    private void noResultCase(String file) {
-        Log.v("Layout test:", file + " no expected result");
-        mResultRecorder.noResult(file);
-    }
-
-    private void processResult(String testFile, String actualResultFile, String expectedResultFile, boolean ignoreResult) {
-        Log.v(LOGTAG, "  Processing result: " + testFile);
-
-        if (ignoreResult) {
-            ignoreResultCase(testFile);
-            return;
-        }
-
-        File actual = new File(actualResultFile);
-        File expected = new File(expectedResultFile);
-        if (actual.exists() && expected.exists()) {
-            try {
-                if (FsUtils.diffIgnoreSpaces(actualResultFile, expectedResultFile)) {
-                    passedCase(testFile);
-                } else {
-                    failedCase(testFile);
-                }
-            } catch (FileNotFoundException ex) {
-                Log.e(LOGTAG, "File not found : " + ex.getMessage());
-            } catch (IOException ex) {
-                Log.e(LOGTAG, "IO Error : " + ex.getMessage());
-            }
-            return;
-        }
-
-        if (!expected.exists()) {
-            noResultCase(testFile);
-        }
-    }
-
-    private void runTestAndWaitUntilDone(TestShellActivity activity, String test, int timeout, boolean ignoreResult, int testNumber) {
-        activity.setCallback(new TestShellCallback() {
-            public void finished() {
-                synchronized (LayoutTestsAutoTest.this) {
-                    mFinished = true;
-                    LayoutTestsAutoTest.this.notifyAll();
-                }
-            }
-
-            public void timedOut(String url) {
-                Log.v(LOGTAG, "layout timeout: " + url);
-            }
-
-            @Override
-            public void dumpResult(String webViewDump) {
-            }
-        });
-
-        String resultFile = getResultFile(test);
-        if (resultFile == null) {
-            // Simply ignore this test.
-            return;
-        }
-        if (mRebaselineResults) {
-            String expectedResultFile = getExpectedResultFile(test);
-            File f = new File(expectedResultFile);
-            if (f.exists()) {
-                return;  // don't run test and don't overwrite default tests.
-            }
-
-            resultFile = getAndroidExpectedResultFile(expectedResultFile);
-        }
-
-        mFinished = false;
-        Intent intent = new Intent(Intent.ACTION_VIEW);
-        intent.setClass(activity, TestShellActivity.class);
-        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
-        intent.putExtra(TestShellActivity.TEST_URL, FsUtils.getTestUrl(test));
-        intent.putExtra(TestShellActivity.RESULT_FILE, resultFile);
-        intent.putExtra(TestShellActivity.TIMEOUT_IN_MILLIS, timeout);
-        intent.putExtra(TestShellActivity.TOTAL_TEST_COUNT, mTestCount);
-        intent.putExtra(TestShellActivity.CURRENT_TEST_NUMBER, testNumber);
-        intent.putExtra(TestShellActivity.STOP_ON_REF_ERROR, true);
-        activity.startActivity(intent);
-
-        // Wait until done.
-        synchronized (this) {
-            while(!mFinished){
-                try {
-                    this.wait();
-                } catch (InterruptedException e) { }
-            }
-        }
-
-        if (!mRebaselineResults) {
-            String expectedResultFile = getExpectedResultFile(test);
-            File f = new File(expectedResultFile);
-            if (!f.exists()) {
-                expectedResultFile = getAndroidExpectedResultFile(expectedResultFile);
-            }
-
-            processResult(test, resultFile, expectedResultFile, ignoreResult);
-        }
-    }
-
-    // Invokes running of layout tests
-    // and waits till it has finished running.
-    public void executeLayoutTests(boolean resume) {
-        LayoutTestsAutoRunner runner = (LayoutTestsAutoRunner) getInstrumentation();
-        // A convenient method to be called by another activity.
-
-        if (runner.mTestPath == null) {
-            Log.e(LOGTAG, "No test specified");
-            return;
-        }
-
-        this.mTestList = new Vector<String>();
-        this.mTestListIgnoreResult = new Vector<Boolean>();
-
-        // Read settings
-        mTestPathPrefix = (new File(LAYOUT_TESTS_ROOT + runner.mTestPath)).getAbsolutePath();
-        mRebaselineResults = runner.mRebaseline;
-        // V8 is the default JavaScript engine.
-        mJsEngine = runner.mJsEngine == null ? "v8" : runner.mJsEngine;
-
-        int timeout = runner.mTimeoutInMillis;
-        if (timeout <= 0) {
-            timeout = DEFAULT_TIMEOUT_IN_MILLIS;
-        }
-
-        this.mResultRecorder = new MyTestRecorder(resume);
-
-        if (!resume)
-            clearTestStatus();
-
-        getTestList();
-        if (resume)
-            resumeTestList();
-
-        TestShellActivity activity = getActivity();
-        activity.setDefaultDumpDataType(DumpDataType.EXT_REPR);
-
-        // Run tests.
-        for (int i = 0; i < mTestList.size(); i++) {
-            String s = mTestList.elementAt(i);
-            boolean ignoreResult = mTestListIgnoreResult.elementAt(i);
-            FsUtils.updateTestStatus(TEST_STATUS_FILE, s);
-            // Run tests
-            // i is 0 based, but test count is 1 based so add 1 to i here.
-            runTestAndWaitUntilDone(activity, s, runner.mTimeoutInMillis, ignoreResult,
-                    i + 1 + mResumeIndex);
-        }
-
-        FsUtils.updateTestStatus(TEST_STATUS_FILE, "#DONE");
-        ForwardService.getForwardService().stopForwardService();
-        activity.finish();
-    }
-
-    private String getTestPath() {
-        LayoutTestsAutoRunner runner = (LayoutTestsAutoRunner) getInstrumentation();
-
-        String test_path = LAYOUT_TESTS_ROOT;
-        if (runner.mTestPath != null) {
-            test_path += runner.mTestPath;
-        }
-        test_path = new File(test_path).getAbsolutePath();
-        Log.v("LayoutTestsAutoTest", " Test path : " + test_path);
-
-        return test_path;
-    }
-
-    public void generateTestList() {
-        try {
-            File tests_list = new File(LAYOUT_TESTS_LIST_FILE);
-            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(tests_list, false));
-            FsUtils.writeLayoutTestListRecursively(bos, getTestPath(), false); // Don't ignore results
-            bos.flush();
-            bos.close();
-       } catch (Exception e) {
-           Log.e(LOGTAG, "Error when creating test list: " + e.getMessage());
-       }
-    }
-
-    // Running all the layout tests at once sometimes
-    // causes the dumprendertree to run out of memory.
-    // So, additional tests are added to run the tests
-    // in chunks.
-    public void startLayoutTests() {
-        try {
-            File tests_list = new File(LAYOUT_TESTS_LIST_FILE);
-            if (!tests_list.exists())
-              generateTestList();
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-
-        executeLayoutTests(false);
-    }
-
-    public void resumeLayoutTests() {
-        executeLayoutTests(true);
-    }
-
-    public void copyResultsAndRunnerAssetsToCache() {
-        try {
-            Context targetContext = getInstrumentation().getTargetContext();
-            File cacheDir = targetContext.getCacheDir();
-
-            for( int i=0; i< LAYOUT_TESTS_RESULTS_REFERENCE_FILES.length; i++) {
-                InputStream in = targetContext.getAssets().open(
-                        LAYOUT_TESTS_RESULTS_REFERENCE_FILES[i]);
-                OutputStream out = new FileOutputStream(new File(cacheDir,
-                        LAYOUT_TESTS_RESULTS_REFERENCE_FILES[i]));
-
-                byte[] buf = new byte[2048];
-                int len;
-
-                while ((len = in.read(buf)) >= 0 ) {
-                    out.write(buf, 0, len);
-                }
-                out.close();
-                in.close();
-            }
-        }catch (IOException e) {
-          e.printStackTrace();
-        }
-
-    }
-
-}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java
deleted file mode 100644
index 4b86a0b..0000000
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java
+++ /dev/null
@@ -1,298 +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.dumprendertree;
-
-import com.android.dumprendertree.forwarder.AdbUtils;
-import com.android.dumprendertree.forwarder.ForwardServer;
-
-import android.app.Activity;
-import android.app.Instrumentation;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Debug;
-import android.os.Environment;
-import android.os.Process;
-import android.test.ActivityInstrumentationTestCase2;
-import android.util.Log;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class LoadTestsAutoTest extends ActivityInstrumentationTestCase2<TestShellActivity> {
-
-    private final static String LOGTAG = "LoadTest";
-    private final static String LOAD_TEST_RESULT =
-        Environment.getExternalStorageDirectory() + "/load_test_result.txt";
-    private final static int MAX_GC_WAIT_SEC = 10;
-    private final static int LOCAL_PORT = 17171;
-    private boolean mFinished;
-    static final String LOAD_TEST_RUNNER_FILES[] = {
-        "run_page_cycler.py"
-    };
-    private ForwardServer mForwardServer;
-
-    public LoadTestsAutoTest() {
-        super(TestShellActivity.class);
-    }
-
-    // This function writes the result of the layout test to
-    // Am status so that it can be picked up from a script.
-    public void passOrFailCallback(String file, boolean result) {
-        Instrumentation inst = getInstrumentation();
-        Bundle bundle = new Bundle();
-        bundle.putBoolean(file, result);
-        inst.sendStatus(0, bundle);
-    }
-
-    private String setUpForwarding(String forwardInfo, String suite, String iteration) throws IOException {
-        // read forwarding information first
-        Pattern forwardPattern = Pattern.compile("(.*):(\\d+)/(.*)/");
-        Matcher matcher = forwardPattern.matcher(forwardInfo);
-        if (!matcher.matches()) {
-            throw new RuntimeException("Invalid forward information");
-        }
-        String host = matcher.group(1);
-        int port = Integer.parseInt(matcher.group(2));
-        mForwardServer = new ForwardServer(LOCAL_PORT, AdbUtils.resolve(host), port);
-        mForwardServer.start();
-        return String.format("http://127.0.0.1:%d/%s/%s/start.html?auto=1&iterations=%s",
-                LOCAL_PORT, matcher.group(3), suite, iteration);
-    }
-
-    // Invokes running of layout tests
-    // and waits till it has finished running.
-    public void runPageCyclerTest() throws IOException {
-        LayoutTestsAutoRunner runner = (LayoutTestsAutoRunner) getInstrumentation();
-
-        if (runner.mPageCyclerSuite != null) {
-            // start forwarder to use page cycler suites hosted on external web server
-            if (runner.mPageCyclerForwardHost == null) {
-                throw new RuntimeException("no forwarder information provided");
-            }
-            runner.mTestPath = setUpForwarding(runner.mPageCyclerForwardHost,
-                    runner.mPageCyclerSuite, runner.mPageCyclerIteration);
-            Log.d(LOGTAG, "using path: " + runner.mTestPath);
-        }
-
-        if (runner.mTestPath == null) {
-            throw new RuntimeException("No test specified");
-        }
-
-        final TestShellActivity activity = (TestShellActivity) getActivity();
-
-        Log.v(LOGTAG, "About to run tests, calling gc first...");
-        freeMem();
-
-        // Run tests
-        runTestAndWaitUntilDone(activity, runner.mTestPath, runner.mTimeoutInMillis);
-
-        getInstrumentation().runOnMainSync(new Runnable() {
-
-            @Override
-            public void run() {
-                activity.clearCache();
-            }
-        });
-        if (mForwardServer != null) {
-            mForwardServer.stop();
-            mForwardServer = null;
-        }
-        try {
-            Thread.sleep(5000);
-        } catch (InterruptedException e) {
-        }
-        dumpMemoryInfo();
-
-        // Kill activity
-        activity.finish();
-    }
-
-    private void freeMem() {
-        Log.v(LOGTAG, "freeMem: calling gc...");
-        final CountDownLatch latch = new CountDownLatch(1);
-        @SuppressWarnings("unused")
-        Object dummy = new Object() {
-            // this object instance is used to track gc
-            @Override
-            protected void finalize() throws Throwable {
-                latch.countDown();
-                super.finalize();
-            }
-        };
-        dummy = null;
-        System.gc();
-        try {
-            if (!latch.await(MAX_GC_WAIT_SEC, TimeUnit.SECONDS)) {
-                Log.w(LOGTAG, "gc did not happen in 10s");
-            }
-        } catch (InterruptedException e) {
-            //ignore
-        }
-    }
-
-    private void printRow(PrintStream ps, String format, Object...objs) {
-        ps.println(String.format(format, objs));
-    }
-
-    private void dumpMemoryInfo() {
-        try {
-            freeMem();
-            Log.v(LOGTAG, "Dumping memory information.");
-
-            FileOutputStream out = new FileOutputStream(LOAD_TEST_RESULT, true);
-            PrintStream ps = new PrintStream(out);
-
-            ps.print("\n\n\n");
-            ps.println("** MEMINFO in pid " + Process.myPid()
-                    + " [com.android.dumprendertree] **");
-            String formatString = "%17s %8s %8s %8s %8s";
-
-            long nativeMax = Debug.getNativeHeapSize() / 1024;
-            long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
-            long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
-            Runtime runtime = Runtime.getRuntime();
-            long dalvikMax = runtime.totalMemory() / 1024;
-            long dalvikFree = runtime.freeMemory() / 1024;
-            long dalvikAllocated = dalvikMax - dalvikFree;
-
-
-            Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
-            Debug.getMemoryInfo(memInfo);
-
-            final int nativeShared = memInfo.nativeSharedDirty;
-            final int dalvikShared = memInfo.dalvikSharedDirty;
-            final int otherShared = memInfo.otherSharedDirty;
-
-            final int nativePrivate = memInfo.nativePrivateDirty;
-            final int dalvikPrivate = memInfo.dalvikPrivateDirty;
-            final int otherPrivate = memInfo.otherPrivateDirty;
-
-            printRow(ps, formatString, "", "native", "dalvik", "other", "total");
-            printRow(ps, formatString, "size:", nativeMax, dalvikMax, "N/A", nativeMax + dalvikMax);
-            printRow(ps, formatString, "allocated:", nativeAllocated, dalvikAllocated, "N/A",
-                    nativeAllocated + dalvikAllocated);
-            printRow(ps, formatString, "free:", nativeFree, dalvikFree, "N/A",
-                    nativeFree + dalvikFree);
-
-            printRow(ps, formatString, "(Pss):", memInfo.nativePss, memInfo.dalvikPss,
-                    memInfo.otherPss, memInfo.nativePss + memInfo.dalvikPss + memInfo.otherPss);
-
-            printRow(ps, formatString, "(shared dirty):", nativeShared, dalvikShared, otherShared,
-                    nativeShared + dalvikShared + otherShared);
-            printRow(ps, formatString, "(priv dirty):", nativePrivate, dalvikPrivate, otherPrivate,
-                    nativePrivate + dalvikPrivate + otherPrivate);
-            ps.print("\n\n\n");
-            ps.flush();
-            ps.close();
-            out.flush();
-            out.close();
-        } catch (IOException e) {
-            Log.e(LOGTAG, e.getMessage());
-        }
-    }
-
-    // A convenient method to be called by another activity.
-    private void runTestAndWaitUntilDone(TestShellActivity activity, String url, int timeout) {
-        activity.setCallback(new TestShellCallback() {
-            @Override
-            public void finished() {
-                synchronized (LoadTestsAutoTest.this) {
-                    mFinished = true;
-                    LoadTestsAutoTest.this.notifyAll();
-                }
-            }
-
-            @Override
-            public void timedOut(String url) {
-            }
-
-            @Override
-            public void dumpResult(String webViewDump) {
-                String lines[] = webViewDump.split("\\r?\\n");
-                for (String line : lines) {
-                    line = line.trim();
-                    // parse for a line like this:
-                    // totals:   9620.00 11947.00    10099.75    380.38
-                    // and return the 3rd number, which is mean
-                    if (line.startsWith("totals:")) {
-                        line = line.substring(7).trim(); // strip "totals:"
-                        String[] numbers = line.split("\\s+");
-                        if (numbers.length == 4) {
-                            Bundle b = new Bundle();
-                            b.putString("mean", numbers[2]);
-                            getInstrumentation().sendStatus(Activity.RESULT_FIRST_USER, b);
-                        }
-                    }
-                }
-            }
-        });
-
-        mFinished = false;
-        Intent intent = new Intent(Intent.ACTION_VIEW);
-        intent.setClass(activity, TestShellActivity.class);
-        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
-        intent.putExtra(TestShellActivity.TEST_URL, url);
-        intent.putExtra(TestShellActivity.TIMEOUT_IN_MILLIS, timeout);
-        intent.putExtra(TestShellActivity.RESULT_FILE, LOAD_TEST_RESULT);
-        activity.startActivity(intent);
-
-        // Wait until done.
-        synchronized (this) {
-            while(!mFinished) {
-                try {
-                    this.wait();
-                } catch (InterruptedException e) { }
-            }
-        }
-    }
-
-    public void copyRunnerAssetsToCache() {
-        try {
-            Context targetContext = getInstrumentation().getTargetContext();
-            File cacheDir = targetContext.getCacheDir();
-
-            for( int i=0; i< LOAD_TEST_RUNNER_FILES.length; i++) {
-                InputStream in = targetContext.getAssets().open(
-                        LOAD_TEST_RUNNER_FILES[i]);
-                OutputStream out = new FileOutputStream(
-                        new File(cacheDir, LOAD_TEST_RUNNER_FILES[i]));
-
-                byte[] buf = new byte[2048];
-                int len;
-
-                while ((len = in.read(buf)) >= 0 ) {
-                    out.write(buf, 0, len);
-                }
-                out.close();
-                in.close();
-            }
-        }catch (IOException e) {
-          e.printStackTrace();
-        }
-
-    }
-
-}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/Menu.java b/tests/DumpRenderTree/src/com/android/dumprendertree/Menu.java
deleted file mode 100644
index 0b00d65..0000000
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/Menu.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dumprendertree;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Environment;
-import android.util.Log;
-
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-
-public class Menu extends FileList {
-
-    private static final int MENU_START = 0x01;
-    private static String LOGTAG = "MenuActivity";
-    static final String LAYOUT_TESTS_LIST_FILE =
-        Environment.getExternalStorageDirectory() + "/android/layout_tests_list.txt";
-
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-    }
-
-    boolean fileFilter(File f) {
-    	if (f.getName().startsWith("."))
-    		return false;
-    	if (f.getName().equalsIgnoreCase("resources"))
-    		return false;
-    	if (f.isDirectory())
-    		return true;
-    	if (f.getPath().toLowerCase().endsWith("ml"))
-    		return true;
-    	return false;
-    }
-
-    void processFile(String filename, boolean selection) {
-        Intent intent = new Intent(Intent.ACTION_VIEW);
-        intent.setClass(this, TestShellActivity.class);
-        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
-        intent.putExtra(TestShellActivity.TEST_URL, "file://" + filename);
-        intent.putExtra(TestShellActivity.TOTAL_TEST_COUNT, 1);
-        intent.putExtra(TestShellActivity.CURRENT_TEST_NUMBER, 1);
-        startActivity(intent);
-    }
-
-    @Override
-    void processDirectory(String path, boolean selection) {
-        int testCount = generateTestList(path);
-        Intent intent = new Intent(Intent.ACTION_VIEW);
-        intent.setClass(this, TestShellActivity.class);
-        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
-        intent.putExtra(TestShellActivity.UI_AUTO_TEST, LAYOUT_TESTS_LIST_FILE);
-        intent.putExtra(TestShellActivity.TOTAL_TEST_COUNT, testCount);
-        // TestShellActivity will process this intent once and increment the test index
-        // before running the first test, so pass 0 here to allow for that.
-        intent.putExtra(TestShellActivity.CURRENT_TEST_NUMBER, 0);
-        startActivity(intent);
-    }
-
-    private int generateTestList(String path) {
-        int testCount = 0;
-        try {
-            File tests_list = new File(LAYOUT_TESTS_LIST_FILE);
-            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(tests_list, false));
-            testCount = FsUtils.writeLayoutTestListRecursively(
-                    bos, path, false); // Don't ignore results
-            bos.flush();
-            bos.close();
-       } catch (Exception e) {
-           Log.e(LOGTAG, "Error when creating test list: " + e.getMessage());
-       }
-       return testCount;
-    }
-
-}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTestActivity.java b/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTestActivity.java
deleted file mode 100644
index 22b587f..0000000
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTestActivity.java
+++ /dev/null
@@ -1,308 +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.dumprendertree;
-
-import android.app.Activity;
-import android.app.ActivityThread;
-import android.graphics.Bitmap;
-import android.net.http.SslError;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
-import android.view.ViewGroup;
-import android.webkit.HttpAuthHandler;
-import android.webkit.JsPromptResult;
-import android.webkit.JsResult;
-import android.webkit.SslErrorHandler;
-import android.webkit.WebChromeClient;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-import android.webkit.WebSettings.LayoutAlgorithm;
-import android.widget.LinearLayout;
-import android.widget.LinearLayout.LayoutParams;
-
-public class ReliabilityTestActivity extends Activity {
-
-    public static final String TEST_URL_ACTION = "com.andrdoid.dumprendertree.TestUrlAction";
-    public static final String PARAM_URL = "URL";
-    public static final String PARAM_TIMEOUT = "Timeout";
-    public static final int RESULT_TIMEOUT = 0xDEAD;
-    public static final int MSG_TIMEOUT = 0xC001;
-    public static final int MSG_NAVIGATE = 0xC002;
-    public static final String MSG_NAV_URL = "url";
-    public static final String MSG_NAV_LOGTIME = "logtime";
-
-    private static final String LOGTAG = "ReliabilityTestActivity";
-
-    private WebView webView;
-    private SimpleWebViewClient webViewClient;
-    private SimpleChromeClient chromeClient;
-    private Handler handler;
-    private boolean timeoutFlag;
-    private boolean logTime;
-    private boolean pageDone;
-    private Object pageDoneLock;
-    private int pageStartCount;
-    private int manualDelay;
-    private long startTime;
-    private long pageLoadTime;
-    private PageDoneRunner pageDoneRunner = new PageDoneRunner();
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        Log.v(LOGTAG, "onCreate, inst=" + Integer.toHexString(hashCode()));
-
-        LinearLayout contentView = new LinearLayout(this);
-        contentView.setOrientation(LinearLayout.VERTICAL);
-        setContentView(contentView);
-        setTitle("Idle");
-
-        webView = new WebView(this);
-        webView.getSettings().setJavaScriptEnabled(true);
-        webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(false);
-        webView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.NORMAL);
-
-        webViewClient = new SimpleWebViewClient();
-        chromeClient = new SimpleChromeClient();
-        webView.setWebViewClient(webViewClient);
-        webView.setWebChromeClient(chromeClient);
-
-        contentView.addView(webView, new LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                ViewGroup.LayoutParams.MATCH_PARENT, 0.0f));
-
-        handler = new Handler() {
-            @Override
-            public void handleMessage(Message msg) {
-                switch (msg.what) {
-                    case MSG_TIMEOUT:
-                        handleTimeout();
-                        return;
-                    case MSG_NAVIGATE:
-                        manualDelay = msg.arg2;
-                        navigate(msg.getData().getString(MSG_NAV_URL), msg.arg1);
-                        logTime = msg.getData().getBoolean(MSG_NAV_LOGTIME);
-                        return;
-                }
-            }
-        };
-
-        pageDoneLock = new Object();
-    }
-
-    public void reset() {
-        synchronized (pageDoneLock) {
-            pageDone = false;
-        }
-        timeoutFlag = false;
-        pageStartCount = 0;
-        chromeClient.resetJsTimeout();
-    }
-
-    private void navigate(String url, int timeout) {
-        if(url == null) {
-            Log.v(LOGTAG, "URL is null, cancelling...");
-            finish();
-        }
-        webView.stopLoading();
-        if(logTime) {
-            webView.clearCache(true);
-        }
-        startTime = System.currentTimeMillis();
-        Log.v(LOGTAG, "Navigating to URL: " + url);
-        webView.loadUrl(url);
-
-        if(timeout != 0) {
-            //set a timer with specified timeout (in ms)
-            handler.sendMessageDelayed(handler.obtainMessage(MSG_TIMEOUT),
-                    timeout);
-        }
-    }
-
-    @Override
-    protected void onDestroy() {
-        super.onDestroy();
-        Log.v(LOGTAG, "onDestroy, inst=" + Integer.toHexString(hashCode()));
-        webView.clearCache(true);
-        webView.destroy();
-    }
-
-    private boolean isPageDone() {
-        synchronized (pageDoneLock) {
-            return pageDone;
-        }
-    }
-
-    private void setPageDone(boolean pageDone) {
-        synchronized (pageDoneLock) {
-            this.pageDone = pageDone;
-            pageDoneLock.notifyAll();
-        }
-    }
-
-    private void handleTimeout() {
-        int progress = webView.getProgress();
-        webView.stopLoading();
-        Log.v(LOGTAG, "Page timeout triggered, progress = " + progress);
-        timeoutFlag = true;
-        handler.postDelayed(pageDoneRunner, manualDelay);
-    }
-
-    public boolean waitUntilDone() {
-        validateNotAppThread();
-        synchronized (pageDoneLock) {
-            while(!isPageDone()) {
-                try {
-                    pageDoneLock.wait();
-                } catch (InterruptedException ie) {
-                    //no-op
-                }
-            }
-        }
-        return timeoutFlag;
-    }
-
-    public Handler getHandler() {
-        return handler;
-    }
-
-    private final void validateNotAppThread() {
-        if (Looper.myLooper() == Looper.getMainLooper()) {
-            throw new RuntimeException(
-                "This method can not be called from the main application thread");
-        }
-    }
-
-    public long getPageLoadTime() {
-        return pageLoadTime;
-    }
-
-    class SimpleWebViewClient extends WebViewClient {
-
-        @Override
-        public void onReceivedError(WebView view, int errorCode, String description,
-                String failingUrl) {
-            Log.v(LOGTAG, "Received WebCore error: code=" + errorCode
-                    + ", description=" + description
-                    + ", url=" + failingUrl);
-        }
-
-        @Override
-        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
-            //ignore certificate error
-            Log.v(LOGTAG, "Received SSL error: " + error.toString());
-            handler.proceed();
-        }
-
-        @Override
-        public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host,
-                String realm) {
-            // cancel http auth request
-            handler.cancel();
-        }
-
-        @Override
-        public void onPageStarted(WebView view, String url, Bitmap favicon) {
-            pageStartCount++;
-            Log.v(LOGTAG, "onPageStarted: " + url);
-        }
-
-        @Override
-        public void onPageFinished(WebView view, String url) {
-            Log.v(LOGTAG, "onPageFinished: " + url);
-            // let handleTimeout take care of finishing the page
-            if(!timeoutFlag)
-                handler.postDelayed(new WebViewStatusChecker(), 500);
-        }
-    }
-
-    class SimpleChromeClient extends WebChromeClient {
-
-        private int timeoutCounter = 0;
-
-        @Override
-        public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
-            result.confirm();
-            return true;
-        }
-
-        @Override
-        public boolean onJsBeforeUnload(WebView view, String url, String message, JsResult result) {
-            result.confirm();
-            return true;
-        }
-
-        @Override
-        public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
-            result.confirm();
-            return true;
-        }
-
-        @Override
-        public boolean onJsPrompt(WebView view, String url, String message, String defaultValue,
-                JsPromptResult result) {
-            result.confirm();
-            return true;
-        }
-
-        @Override
-        public boolean onJsTimeout() {
-            timeoutCounter++;
-            Log.v(LOGTAG, "JavaScript timeout, count=" + timeoutCounter);
-            return timeoutCounter > 2;
-        }
-
-        public void resetJsTimeout() {
-            timeoutCounter = 0;
-        }
-
-        @Override
-        public void onReceivedTitle(WebView view, String title) {
-            ReliabilityTestActivity.this.setTitle(title);
-        }
-    }
-
-    class WebViewStatusChecker implements Runnable {
-
-        private int initialStartCount;
-
-        public WebViewStatusChecker() {
-            initialStartCount = pageStartCount;
-        }
-
-        public void run() {
-            if (initialStartCount == pageStartCount && !isPageDone()) {
-                handler.removeMessages(MSG_TIMEOUT);
-                webView.stopLoading();
-                handler.postDelayed(pageDoneRunner, manualDelay);
-            }
-        }
-    }
-
-    class PageDoneRunner implements Runnable {
-
-        public void run() {
-            Log.v(LOGTAG, "Finishing URL: " + webView.getUrl());
-            pageLoadTime = System.currentTimeMillis() - startTime;
-            setPageDone(true);
-        }
-    }
-}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
deleted file mode 100644
index 42d6457..0000000
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
+++ /dev/null
@@ -1,946 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dumprendertree;
-
-import com.android.dumprendertree.forwarder.ForwardService;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnClickListener;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.net.http.SslError;
-import android.os.Bundle;
-import android.os.Environment;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-import android.view.ViewGroup;
-import android.view.Window;
-import android.webkit.ConsoleMessage;
-import android.webkit.CookieManager;
-import android.webkit.GeolocationPermissions;
-import android.webkit.HttpAuthHandler;
-import android.webkit.JsPromptResult;
-import android.webkit.JsResult;
-import android.webkit.SslErrorHandler;
-import android.webkit.WebChromeClient;
-import android.webkit.WebSettings;
-import android.webkit.WebSettingsClassic;
-import android.webkit.WebStorage;
-import android.webkit.WebView;
-import android.webkit.WebViewClassic;
-import android.webkit.WebViewClient;
-import android.widget.LinearLayout;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Vector;
-
-public class TestShellActivity extends Activity implements LayoutTestController {
-
-    static enum DumpDataType {DUMP_AS_TEXT, EXT_REPR, NO_OP}
-
-    // String constants for use with layoutTestController.overridePreferences
-    private final String WEBKIT_OFFLINE_WEB_APPLICATION_CACHE_ENABLED =
-            "WebKitOfflineWebApplicationCacheEnabled";
-    private final String WEBKIT_USES_PAGE_CACHE_PREFERENCE_KEY = "WebKitUsesPageCachePreferenceKey";
-
-    public class AsyncHandler extends Handler {
-        @Override
-        public void handleMessage(Message msg) {
-            if (msg.what == MSG_TIMEOUT) {
-                mTimedOut = true;
-                mWebView.stopLoading();
-                if (mCallback != null)
-                    mCallback.timedOut(mWebView.getUrl());
-                if (!mRequestedWebKitData) {
-                    requestWebKitData();
-                } else {
-                    // if timed out and webkit data has been dumped before
-                    // finish directly
-                    finished();
-                }
-                return;
-            } else if (msg.what == MSG_WEBKIT_DATA) {
-                Log.v(LOGTAG, "Received WebView dump data");
-                mHandler.removeMessages(MSG_DUMP_TIMEOUT);
-                TestShellActivity.this.dump(mTimedOut, (String)msg.obj);
-                return;
-            } else if (msg.what == MSG_DUMP_TIMEOUT) {
-                throw new RuntimeException("WebView dump timeout, is it pegged?");
-            }
-            super.handleMessage(msg);
-        }
-    }
-
-    public void requestWebKitData() {
-        setDumpTimeout(DUMP_TIMEOUT_MS);
-        Message callback = mHandler.obtainMessage(MSG_WEBKIT_DATA);
-
-        if (mRequestedWebKitData)
-            throw new AssertionError("Requested webkit data twice: " + mWebView.getUrl());
-
-        mRequestedWebKitData = true;
-        Log.v(LOGTAG, "message sent to WebView to dump text.");
-        switch (mDumpDataType) {
-            case DUMP_AS_TEXT:
-                callback.arg1 = mDumpTopFrameAsText ? 1 : 0;
-                callback.arg2 = mDumpChildFramesAsText ? 1 : 0;
-                mWebViewClassic.documentAsText(callback);
-                break;
-            case EXT_REPR:
-                mWebViewClassic.externalRepresentation(callback);
-                break;
-            default:
-                finished();
-                break;
-        }
-    }
-
-    private void setDumpTimeout(long timeout) {
-        Log.v(LOGTAG, "setting dump timeout at " + timeout);
-        Message msg = mHandler.obtainMessage(MSG_DUMP_TIMEOUT);
-        mHandler.sendMessageDelayed(msg, timeout);
-    }
-
-    public void clearCache() {
-      mWebView.freeMemory();
-    }
-
-    @Override
-    protected void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        requestWindowFeature(Window.FEATURE_PROGRESS);
-
-        LinearLayout contentView = new LinearLayout(this);
-        contentView.setOrientation(LinearLayout.VERTICAL);
-        setContentView(contentView);
-
-        CookieManager.setAcceptFileSchemeCookies(true);
-        mWebView = new WebView(this);
-        mWebViewClassic = WebViewClassic.fromWebView(mWebView);
-        mEventSender = new WebViewEventSender(mWebView);
-        mCallbackProxy = new CallbackProxy(mEventSender, this);
-
-        mWebView.addJavascriptInterface(mCallbackProxy, "layoutTestController");
-        mWebView.addJavascriptInterface(mCallbackProxy, "eventSender");
-        setupWebViewForLayoutTests(mWebView, mCallbackProxy);
-
-        contentView.addView(mWebView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, 0.0f));
-
-        mWebView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);
-
-        // Expose window.gc function to JavaScript. JSC build exposes
-        // this function by default, but V8 requires the flag to turn it on.
-        // WebView::setJsFlags is noop in JSC build.
-        mWebViewClassic.setJsFlags("--expose_gc");
-
-        mHandler = new AsyncHandler();
-
-        Intent intent = getIntent();
-        if (intent != null) {
-            executeIntent(intent);
-        }
-
-        // This is asynchronous, but it gets processed by WebCore before it starts loading pages.
-        mWebViewClassic.setUseMockDeviceOrientation();
-    }
-
-    @Override
-    protected void onNewIntent(Intent intent) {
-        super.onNewIntent(intent);
-        executeIntent(intent);
-    }
-
-    private void executeIntent(Intent intent) {
-        resetTestStatus();
-        if (!Intent.ACTION_VIEW.equals(intent.getAction())) {
-            return;
-        }
-
-        mTotalTestCount = intent.getIntExtra(TOTAL_TEST_COUNT, mTotalTestCount);
-        mCurrentTestNumber = intent.getIntExtra(CURRENT_TEST_NUMBER, mCurrentTestNumber);
-
-        mTestUrl = intent.getStringExtra(TEST_URL);
-        if (mTestUrl == null) {
-            mUiAutoTestPath = intent.getStringExtra(UI_AUTO_TEST);
-            if(mUiAutoTestPath != null) {
-                beginUiAutoTest();
-            }
-            return;
-        }
-
-        mResultFile = intent.getStringExtra(RESULT_FILE);
-        mTimeoutInMillis = intent.getIntExtra(TIMEOUT_IN_MILLIS, 0);
-        mStopOnRefError = intent.getBooleanExtra(STOP_ON_REF_ERROR, false);
-        setTitle("Test " + mCurrentTestNumber + " of " + mTotalTestCount);
-        float ratio = (float)mCurrentTestNumber / mTotalTestCount;
-        int progress = (int)(ratio * Window.PROGRESS_END);
-        getWindow().setFeatureInt(Window.FEATURE_PROGRESS, progress);
-
-        Log.v(LOGTAG, "  Loading " + mTestUrl);
-
-        if (mTestUrl.contains("/dumpAsText/")) {
-            dumpAsText(false);
-        }
-
-        mWebView.loadUrl(mTestUrl);
-
-        if (mTimeoutInMillis > 0) {
-            // Create a timeout timer
-            Message m = mHandler.obtainMessage(MSG_TIMEOUT);
-            mHandler.sendMessageDelayed(m, mTimeoutInMillis);
-        }
-    }
-
-    private void beginUiAutoTest() {
-        try {
-            mTestListReader = new BufferedReader(
-                    new FileReader(mUiAutoTestPath));
-        } catch (IOException ioe) {
-            Log.e(LOGTAG, "Failed to open test list for read.", ioe);
-            finishUiAutoTest();
-            return;
-        }
-        moveToNextTest();
-    }
-
-    private void finishUiAutoTest() {
-        try {
-            if(mTestListReader != null)
-                mTestListReader.close();
-        } catch (IOException ioe) {
-            Log.w(LOGTAG, "Failed to close test list file.", ioe);
-        }
-        ForwardService.getForwardService().stopForwardService();
-        finished();
-    }
-
-    private void moveToNextTest() {
-        String url = null;
-        try {
-            url = mTestListReader.readLine();
-        } catch (IOException ioe) {
-            Log.e(LOGTAG, "Failed to read next test.", ioe);
-            finishUiAutoTest();
-            return;
-        }
-        if (url == null) {
-            mUiAutoTestPath = null;
-            finishUiAutoTest();
-            AlertDialog.Builder builder = new AlertDialog.Builder(this);
-            builder.setMessage("All tests finished. Exit?")
-                   .setCancelable(false)
-                   .setPositiveButton("Yes", new OnClickListener(){
-                       @Override
-                    public void onClick(DialogInterface dialog, int which) {
-                           TestShellActivity.this.finish();
-                       }
-                   })
-                   .setNegativeButton("No", new OnClickListener(){
-                       @Override
-                    public void onClick(DialogInterface dialog, int which) {
-                           dialog.cancel();
-                       }
-                   });
-            builder.create().show();
-            return;
-        }
-        Intent intent = new Intent(Intent.ACTION_VIEW);
-        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
-        intent.putExtra(TestShellActivity.TEST_URL, FsUtils.getTestUrl(url));
-        intent.putExtra(TestShellActivity.CURRENT_TEST_NUMBER, ++mCurrentTestNumber);
-        intent.putExtra(TIMEOUT_IN_MILLIS, 10000);
-        executeIntent(intent);
-    }
-
-    @Override
-    protected void onStop() {
-        super.onStop();
-        mWebView.stopLoading();
-    }
-
-    @Override
-    protected void onDestroy() {
-        super.onDestroy();
-        mWebView.destroy();
-        mWebView = null;
-        mWebViewClassic = null;
-    }
-
-    @Override
-    public void onLowMemory() {
-        super.onLowMemory();
-        Log.e(LOGTAG, "Low memory, clearing caches");
-        mWebView.freeMemory();
-    }
-
-    // Dump the page
-    public void dump(boolean timeout, String webkitData) {
-        mDumpWebKitData = true;
-        if (mResultFile == null || mResultFile.length() == 0) {
-            finished();
-            return;
-        }
-
-        if (mCallback != null) {
-            mCallback.dumpResult(webkitData);
-        }
-
-        try {
-            File parentDir = new File(mResultFile).getParentFile();
-            if (!parentDir.exists()) {
-                parentDir.mkdirs();
-            }
-
-            FileOutputStream os = new FileOutputStream(mResultFile);
-            if (timeout) {
-                Log.w("Layout test: Timeout", mResultFile);
-                os.write(TIMEOUT_STR.getBytes());
-                os.write('\n');
-            }
-            if (mDumpTitleChanges)
-                os.write(mTitleChanges.toString().getBytes());
-            if (mDialogStrings != null)
-                os.write(mDialogStrings.toString().getBytes());
-            mDialogStrings = null;
-            if (mDatabaseCallbackStrings != null)
-                os.write(mDatabaseCallbackStrings.toString().getBytes());
-            mDatabaseCallbackStrings = null;
-            if (mConsoleMessages != null)
-                os.write(mConsoleMessages.toString().getBytes());
-            mConsoleMessages = null;
-            if (webkitData != null)
-                os.write(webkitData.getBytes());
-            os.flush();
-            os.close();
-        } catch (IOException ex) {
-            Log.e(LOGTAG, "Cannot write to " + mResultFile + ", " + ex.getMessage());
-        }
-
-        finished();
-    }
-
-    public void setCallback(TestShellCallback callback) {
-        mCallback = callback;
-    }
-
-    public boolean finished() {
-        if (canMoveToNextTest()) {
-            mHandler.removeMessages(MSG_TIMEOUT);
-            if (mUiAutoTestPath != null) {
-                //don't really finish here
-                moveToNextTest();
-            } else {
-                if (mCallback != null) {
-                    mCallback.finished();
-                }
-            }
-            return true;
-        }
-        return false;
-    }
-
-    public void setDefaultDumpDataType(DumpDataType defaultDumpDataType) {
-        mDefaultDumpDataType = defaultDumpDataType;
-    }
-
-    // .......................................
-    // LayoutTestController Functions
-    @Override
-    public void dumpAsText(boolean enablePixelTests) {
-        // Added after webkit update to r63859. See trac.webkit.org/changeset/63730.
-        if (enablePixelTests) {
-            Log.v(LOGTAG, "dumpAsText(enablePixelTests == true) not implemented on Android!");
-        }
-
-        mDumpDataType = DumpDataType.DUMP_AS_TEXT;
-        mDumpTopFrameAsText = true;
-        if (mWebView != null) {
-            String url = mWebView.getUrl();
-            Log.v(LOGTAG, "dumpAsText called: "+url);
-        }
-    }
-
-    @Override
-    public void dumpChildFramesAsText() {
-        mDumpDataType = DumpDataType.DUMP_AS_TEXT;
-        mDumpChildFramesAsText = true;
-        if (mWebView != null) {
-            String url = mWebView.getUrl();
-            Log.v(LOGTAG, "dumpChildFramesAsText called: "+url);
-        }
-    }
-
-    @Override
-    public void waitUntilDone() {
-        mWaitUntilDone = true;
-        String url = mWebView.getUrl();
-        Log.v(LOGTAG, "waitUntilDone called: " + url);
-    }
-
-    @Override
-    public void notifyDone() {
-        String url = mWebView.getUrl();
-        Log.v(LOGTAG, "notifyDone called: " + url);
-        if (mWaitUntilDone) {
-            mWaitUntilDone = false;
-            if (!mRequestedWebKitData && !mTimedOut && !finished()) {
-                requestWebKitData();
-            }
-        }
-    }
-
-    @Override
-    public void display() {
-        mWebView.invalidate();
-    }
-
-    @Override
-    public void clearBackForwardList() {
-        mWebView.clearHistory();
-
-    }
-
-    @Override
-    public void dumpBackForwardList() {
-        //printf("\n============== Back Forward List ==============\n");
-        // mWebHistory
-        //printf("===============================================\n");
-
-    }
-
-    @Override
-    public void dumpChildFrameScrollPositions() {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void dumpEditingCallbacks() {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void dumpSelectionRect() {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void dumpTitleChanges() {
-        if (!mDumpTitleChanges) {
-            mTitleChanges = new StringBuffer();
-        }
-        mDumpTitleChanges = true;
-    }
-
-    @Override
-    public void keepWebHistory() {
-        if (!mKeepWebHistory) {
-            mWebHistory = new Vector();
-        }
-        mKeepWebHistory = true;
-    }
-
-    @Override
-    public void queueBackNavigation(int howfar) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void queueForwardNavigation(int howfar) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void queueLoad(String Url, String frameTarget) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void queueReload() {
-        mWebView.reload();
-    }
-
-    @Override
-    public void queueScript(String scriptToRunInCurrentContext) {
-        mWebView.loadUrl("javascript:"+scriptToRunInCurrentContext);
-    }
-
-    @Override
-    public void repaintSweepHorizontally() {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void setAcceptsEditing(boolean b) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void setMainFrameIsFirstResponder(boolean b) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void setWindowIsKey(boolean b) {
-        // This is meant to show/hide the window. The best I can find
-        // is setEnabled()
-        mWebView.setEnabled(b);
-    }
-
-    @Override
-    public void testRepaint() {
-        mWebView.invalidate();
-    }
-
-    @Override
-    public void dumpDatabaseCallbacks() {
-        Log.v(LOGTAG, "dumpDatabaseCallbacks called.");
-        mDumpDatabaseCallbacks = true;
-    }
-
-    @Override
-    public void setCanOpenWindows() {
-        Log.v(LOGTAG, "setCanOpenWindows called.");
-        mCanOpenWindows = true;
-    }
-
-    @Override
-    public void setMockGeolocationPosition(double latitude, double longitude, double accuracy) {
-        WebViewClassic.fromWebView(mWebView).setMockGeolocationPosition(latitude, longitude,
-                accuracy);
-    }
-
-    @Override
-    public void setMockGeolocationError(int code, String message) {
-        WebViewClassic.fromWebView(mWebView).setMockGeolocationError(code, message);
-    }
-
-    @Override
-    public void setGeolocationPermission(boolean allow) {
-        Log.v(LOGTAG, "setGeolocationPermission() allow=" + allow);
-        WebViewClassic.fromWebView(mWebView).setMockGeolocationPermission(allow);
-    }
-
-    @Override
-    public void setMockDeviceOrientation(boolean canProvideAlpha, double alpha,
-            boolean canProvideBeta, double beta, boolean canProvideGamma, double gamma) {
-        WebViewClassic.fromWebView(mWebView).setMockDeviceOrientation(canProvideAlpha, alpha,
-                canProvideBeta, beta, canProvideGamma, gamma);
-    }
-
-    @Override
-    public void overridePreference(String key, boolean value) {
-        // TODO: We should look up the correct WebView for the frame which
-        // called the layoutTestController method. Currently, we just use the
-        // WebView for the main frame. EventSender suffers from the same
-        // problem.
-        if (WEBKIT_OFFLINE_WEB_APPLICATION_CACHE_ENABLED.equals(key)) {
-            mWebViewClassic.getSettings().setAppCacheEnabled(value);
-        } else if (WEBKIT_USES_PAGE_CACHE_PREFERENCE_KEY.equals(key)) {
-            // Cache the maximum possible number of pages.
-            mWebViewClassic.getSettings().setPageCacheCapacity(Integer.MAX_VALUE);
-        } else {
-            Log.w(LOGTAG, "LayoutTestController.overridePreference(): " +
-                  "Unsupported preference '" + key + "'");
-        }
-    }
-
-    @Override
-    public void setXSSAuditorEnabled (boolean flag) {
-        mWebViewClassic.getSettings().setXSSAuditorEnabled(flag);
-    }
-
-    private final WebViewClient mViewClient = new WebViewClient(){
-        @Override
-        public void onPageFinished(WebView view, String url) {
-            Log.v(LOGTAG, "onPageFinished, url=" + url);
-            mPageFinished = true;
-
-            // Calling finished() will check if we've met all the conditions for completing
-            // this test and move to the next one if we are ready. Otherwise we ask WebCore to
-            // dump the page.
-            if (finished()) {
-                return;
-            }
-
-            if (!mWaitUntilDone && !mRequestedWebKitData && !mTimedOut) {
-                requestWebKitData();
-            } else {
-                if (mWaitUntilDone) {
-                    Log.v(LOGTAG, "page finished loading but waiting for notifyDone to be called: " + url);
-                }
-
-                if (mRequestedWebKitData) {
-                    Log.v(LOGTAG, "page finished loading but webkit data has already been requested: " + url);
-                }
-
-                if (mTimedOut) {
-                    Log.v(LOGTAG, "page finished loading but already timed out: " + url);
-                }
-            }
-
-            super.onPageFinished(view, url);
-        }
-
-        @Override
-        public void onPageStarted(WebView view, String url, Bitmap favicon) {
-            Log.v(LOGTAG, "onPageStarted, url=" + url);
-            mPageFinished = false;
-            super.onPageStarted(view, url, favicon);
-        }
-
-        @Override
-        public void onReceivedError(WebView view, int errorCode, String description,
-                String failingUrl) {
-            Log.v(LOGTAG, "onReceivedError, errorCode=" + errorCode
-                    + ", desc=" + description + ", url=" + failingUrl);
-            super.onReceivedError(view, errorCode, description, failingUrl);
-        }
-
-        @Override
-        public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler,
-                String host, String realm) {
-            if (handler.useHttpAuthUsernamePassword() && view != null) {
-                String[] credentials = view.getHttpAuthUsernamePassword(host, realm);
-                if (credentials != null && credentials.length == 2) {
-                    handler.proceed(credentials[0], credentials[1]);
-                    return;
-                }
-            }
-            handler.cancel();
-        }
-
-        @Override
-        public void onReceivedSslError(WebView view, SslErrorHandler handler,
-                SslError error) {
-            handler.proceed();
-        }
-    };
-
-
-    private final WebChromeClient mChromeClient = new WebChromeClient() {
-        @Override
-        public void onReceivedTitle(WebView view, String title) {
-            setTitle("Test " + mCurrentTestNumber + " of " + mTotalTestCount + ": "+ title);
-            if (mDumpTitleChanges) {
-                mTitleChanges.append("TITLE CHANGED: ");
-                mTitleChanges.append(title);
-                mTitleChanges.append("\n");
-            }
-        }
-
-        @Override
-        public boolean onJsAlert(WebView view, String url, String message,
-                JsResult result) {
-            if (mDialogStrings == null) {
-                mDialogStrings = new StringBuffer();
-            }
-            mDialogStrings.append("ALERT: ");
-            mDialogStrings.append(message);
-            mDialogStrings.append('\n');
-            result.confirm();
-            return true;
-        }
-
-        @Override
-        public boolean onJsConfirm(WebView view, String url, String message,
-                JsResult result) {
-            if (mDialogStrings == null) {
-                mDialogStrings = new StringBuffer();
-            }
-            mDialogStrings.append("CONFIRM: ");
-            mDialogStrings.append(message);
-            mDialogStrings.append('\n');
-            result.confirm();
-            return true;
-        }
-
-        @Override
-        public boolean onJsPrompt(WebView view, String url, String message,
-                String defaultValue, JsPromptResult result) {
-            if (mDialogStrings == null) {
-                mDialogStrings = new StringBuffer();
-            }
-            mDialogStrings.append("PROMPT: ");
-            mDialogStrings.append(message);
-            mDialogStrings.append(", default text: ");
-            mDialogStrings.append(defaultValue);
-            mDialogStrings.append('\n');
-            result.confirm();
-            return true;
-        }
-
-        @Override
-        public boolean onJsTimeout() {
-            Log.v(LOGTAG, "JavaScript timeout");
-            return false;
-        }
-
-        @Override
-        public void onExceededDatabaseQuota(String url_str,
-                String databaseIdentifier, long currentQuota,
-                long estimatedSize, long totalUsedQuota,
-                WebStorage.QuotaUpdater callback) {
-            if (mDumpDatabaseCallbacks) {
-                if (mDatabaseCallbackStrings == null) {
-                    mDatabaseCallbackStrings = new StringBuffer();
-                }
-
-                String protocol = "";
-                String host = "";
-                int port = 0;
-
-                try {
-                    URL url = new URL(url_str);
-                    protocol = url.getProtocol();
-                    host = url.getHost();
-                    if (url.getPort() > -1) {
-                        port = url.getPort();
-                    }
-                } catch (MalformedURLException e) {}
-
-                String databaseCallbackString =
-                        "UI DELEGATE DATABASE CALLBACK: " +
-                        "exceededDatabaseQuotaForSecurityOrigin:{" + protocol +
-                        ", " + host + ", " + port + "} database:" +
-                        databaseIdentifier + "\n";
-                Log.v(LOGTAG, "LOG: "+databaseCallbackString);
-                mDatabaseCallbackStrings.append(databaseCallbackString);
-            }
-            // Give 5MB more quota.
-            callback.updateQuota(currentQuota + 1024 * 1024 * 5);
-        }
-
-        @Override
-        public void onGeolocationPermissionsShowPrompt(String origin,
-                GeolocationPermissions.Callback callback) {
-            throw new RuntimeException(
-                    "The WebCore mock used by DRT should bypass the usual permissions flow.");
-        }
-
-        @Override
-        public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
-            String msg = "CONSOLE MESSAGE: line " + consoleMessage.lineNumber() + ": "
-                    + consoleMessage.message() + "\n";
-            if (mConsoleMessages == null) {
-                mConsoleMessages = new StringBuffer();
-            }
-            mConsoleMessages.append(msg);
-            Log.v(LOGTAG, "LOG: " + msg);
-            // the rationale here is that if there's an error of either type, and the test was
-            // waiting for "notifyDone" signal to finish, then there's no point in waiting
-            // anymore because the JS execution is already terminated at this point and a
-            // "notifyDone" will never come out so it's just wasting time till timeout kicks in
-            if ((msg.contains("Uncaught ReferenceError:") || msg.contains("Uncaught TypeError:"))
-                    && mWaitUntilDone && mStopOnRefError) {
-                Log.w(LOGTAG, "Terminating test case on uncaught ReferenceError or TypeError.");
-                mHandler.postDelayed(new Runnable() {
-                    @Override
-                    public void run() {
-                        notifyDone();
-                    }
-                }, 500);
-            }
-            return true;
-        }
-
-        @Override
-        public boolean onCreateWindow(WebView view, boolean dialog,
-                boolean userGesture, Message resultMsg) {
-            if (!mCanOpenWindows) {
-                // We can't open windows, so just send null back.
-                WebView.WebViewTransport transport =
-                        (WebView.WebViewTransport) resultMsg.obj;
-                transport.setWebView(null);
-                resultMsg.sendToTarget();
-                return true;
-            }
-
-            // We never display the new window, just create the view and
-            // allow it's content to execute and be recorded by the test
-            // runner.
-
-            HashMap<String, Object> jsIfaces = new HashMap<String, Object>();
-            jsIfaces.put("layoutTestController", mCallbackProxy);
-            jsIfaces.put("eventSender", mCallbackProxy);
-            WebView newWindowView = new NewWindowWebView(TestShellActivity.this, jsIfaces);
-            setupWebViewForLayoutTests(newWindowView, mCallbackProxy);
-            WebView.WebViewTransport transport =
-                    (WebView.WebViewTransport) resultMsg.obj;
-            transport.setWebView(newWindowView);
-            resultMsg.sendToTarget();
-            return true;
-        }
-
-        @Override
-        public void onCloseWindow(WebView view) {
-            view.destroy();
-        }
-    };
-
-    private static class NewWindowWebView extends WebView {
-        public NewWindowWebView(Context context, Map<String, Object> jsIfaces) {
-            super(context, null, 0, jsIfaces, false);
-        }
-    }
-
-    private void resetTestStatus() {
-        mWaitUntilDone = false;
-        mDumpDataType = mDefaultDumpDataType;
-        mDumpTopFrameAsText = false;
-        mDumpChildFramesAsText = false;
-        mTimedOut = false;
-        mDumpTitleChanges = false;
-        mRequestedWebKitData = false;
-        mDumpDatabaseCallbacks = false;
-        mCanOpenWindows = false;
-        mEventSender.resetMouse();
-        mEventSender.clearTouchPoints();
-        mEventSender.clearTouchMetaState();
-        mPageFinished = false;
-        mDumpWebKitData = false;
-        setDefaultWebSettings(mWebView);
-        CookieManager.getInstance().removeAllCookie();
-        mWebViewClassic.setUseMockGeolocation();
-    }
-
-    private boolean canMoveToNextTest() {
-        return (mDumpWebKitData && mPageFinished && !mWaitUntilDone) || mTimedOut;
-    }
-
-    private void setupWebViewForLayoutTests(WebView webview, CallbackProxy callbackProxy) {
-        if (webview == null) {
-            return;
-        }
-
-        setDefaultWebSettings(webview);
-
-        webview.setWebChromeClient(mChromeClient);
-        webview.setWebViewClient(mViewClient);
-        // Setting a touch interval of -1 effectively disables the optimisation in WebView
-        // that stops repeated touch events flooding WebCore. The Event Sender only sends a
-        // single event rather than a stream of events (like what would generally happen in
-        // a real use of touch events in a WebView)  and so if the WebView drops the event,
-        // the test will fail as the test expects one callback for every touch it synthesizes.
-        WebViewClassic.fromWebView(webview).setTouchInterval(-1);
-    }
-
-    public void setDefaultWebSettings(WebView webview) {
-        WebSettingsClassic settings = WebViewClassic.fromWebView(webview).getSettings();
-        settings.setAppCacheEnabled(true);
-        settings.setAppCachePath(getApplicationContext().getCacheDir().getPath());
-        settings.setAppCacheMaxSize(Long.MAX_VALUE);
-        settings.setJavaScriptEnabled(true);
-        settings.setJavaScriptCanOpenWindowsAutomatically(true);
-        settings.setSupportMultipleWindows(true);
-        settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);
-        settings.setDatabaseEnabled(true);
-        settings.setDatabasePath(getDir("databases",0).getAbsolutePath());
-        settings.setDomStorageEnabled(true);
-        settings.setWorkersEnabled(false);
-        settings.setXSSAuditorEnabled(false);
-        settings.setPageCacheCapacity(0);
-        settings.setProperty("use_minimal_memory", "false");
-        settings.setAllowUniversalAccessFromFileURLs(true);
-        settings.setAllowFileAccessFromFileURLs(true);
-    }
-
-    private WebViewClassic mWebViewClassic;
-    private WebView mWebView;
-    private WebViewEventSender mEventSender;
-    private AsyncHandler mHandler;
-    private TestShellCallback mCallback;
-
-    private CallbackProxy mCallbackProxy;
-
-    private String mTestUrl;
-    private String mResultFile;
-    private int mTimeoutInMillis;
-    private String mUiAutoTestPath;
-    private BufferedReader mTestListReader;
-    private int mTotalTestCount;
-    private int mCurrentTestNumber;
-    private boolean mStopOnRefError;
-
-    // States
-    private boolean mTimedOut;
-    private boolean mRequestedWebKitData;
-    private boolean mFinishedRunning;
-
-    // Layout test controller variables.
-    private DumpDataType mDumpDataType;
-    private DumpDataType mDefaultDumpDataType = DumpDataType.EXT_REPR;
-    private boolean mDumpTopFrameAsText;
-    private boolean mDumpChildFramesAsText;
-    private boolean mWaitUntilDone;
-    private boolean mDumpTitleChanges;
-    private StringBuffer mTitleChanges;
-    private StringBuffer mDialogStrings;
-    private boolean mKeepWebHistory;
-    private Vector mWebHistory;
-    private boolean mDumpDatabaseCallbacks;
-    private StringBuffer mDatabaseCallbackStrings;
-    private StringBuffer mConsoleMessages;
-    private boolean mCanOpenWindows;
-
-    private boolean mPageFinished = false;
-    private boolean mDumpWebKitData = false;
-
-    static final String TIMEOUT_STR = "**Test timeout";
-    static final long DUMP_TIMEOUT_MS = 100000; // 100s timeout for dumping webview content
-
-    static final int MSG_TIMEOUT = 0;
-    static final int MSG_WEBKIT_DATA = 1;
-    static final int MSG_DUMP_TIMEOUT = 2;
-
-    static final String LOGTAG="TestShell";
-
-    static final String TEST_URL = "TestUrl";
-    static final String RESULT_FILE = "ResultFile";
-    static final String TIMEOUT_IN_MILLIS = "TimeoutInMillis";
-    static final String UI_AUTO_TEST = "UiAutoTest";
-    static final String GET_DRAW_TIME = "GetDrawTime";
-    static final String SAVE_IMAGE = "SaveImage";
-    static final String TOTAL_TEST_COUNT = "TestCount";
-    static final String CURRENT_TEST_NUMBER = "TestNumber";
-    static final String STOP_ON_REF_ERROR = "StopOnReferenceError";
-
-    static final int DRAW_RUNS = 5;
-    static final String DRAW_TIME_LOG = Environment.getExternalStorageDirectory() +
-        "/android/page_draw_time.txt";
-}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellCallback.java b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellCallback.java
deleted file mode 100644
index 5220d579..0000000
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellCallback.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dumprendertree;
-
-public interface TestShellCallback {
-    public void finished();
-    public void dumpResult(String webViewDump);
-    public void timedOut(String url);
-}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/WebViewEventSender.java b/tests/DumpRenderTree/src/com/android/dumprendertree/WebViewEventSender.java
deleted file mode 100644
index 17345ae..0000000
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/WebViewEventSender.java
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dumprendertree;
-
-import android.os.SystemClock;
-import android.util.*;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.webkit.WebView;
-
-import java.util.Arrays;
-import java.util.Vector;
-
-public class WebViewEventSender implements EventSender {
-
-    private static final String LOGTAG = "WebViewEventSender";
-	
-    WebViewEventSender(WebView webView) {
-        mWebView = webView;
-        mWebView.getSettings().setBuiltInZoomControls(true);
-        mTouchPoints = new Vector<TouchPoint>();
-    }
-	
-	public void resetMouse() {
-		mouseX = mouseY = 0;
-	}
-
-	public void enableDOMUIEventLogging(int DOMNode) {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void fireKeyboardEventsToElement(int DOMNode) {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void keyDown(String character, String[] withModifiers) {
-        Log.e("EventSender", "KeyDown: " + character + "("
-                + character.getBytes()[0] + ") Modifiers: "
-                + Arrays.toString(withModifiers));
-        KeyEvent modifier = null;
-        if (withModifiers != null && withModifiers.length > 0) {
-            for (int i = 0; i < withModifiers.length; i++) {
-                int keyCode = modifierMapper(withModifiers[i]);
-                modifier = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
-                mWebView.onKeyDown(modifier.getKeyCode(), modifier);
-            }
-        }
-        int keyCode = keyMapper(character.toLowerCase().toCharArray()[0]);
-        KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
-        mWebView.onKeyDown(event.getKeyCode(), event);
-
-    }
-	
-	public void keyDown(String character) {
-        keyDown(character, null);
-	}
-
-	public void leapForward(int milliseconds) {
-		// TODO Auto-generated method stub
-
-	}
-
-	public void mouseClick() {
-		mouseDown();
-		mouseUp();
-	}
-
-    public void mouseDown() {
-        long ts = SystemClock.uptimeMillis();
-        MotionEvent event = MotionEvent.obtain(ts, ts, MotionEvent.ACTION_DOWN, mouseX, mouseY, 0);
-        mWebView.onTouchEvent(event);
-    }
-
-    public void mouseMoveTo(int X, int Y) {
-        mouseX= X;
-        mouseY= Y;
-    }
-
-     public void mouseUp() {
-        long ts = SystemClock.uptimeMillis();
-        MotionEvent event = MotionEvent.obtain(ts, ts, MotionEvent.ACTION_UP, mouseX, mouseY, 0);
-        mWebView.onTouchEvent(event);
-    }
-
-	// Assumes lowercase chars, case needs to be
-	// handled by calling function.
-	static int keyMapper(char c) {
-		// handle numbers
-		if (c >= '0' && c<= '9') {
-			int offset = c - '0';
-			return KeyEvent.KEYCODE_0 + offset;
-		}
-
-		// handle characters
-		if (c >= 'a' && c <= 'z') {
-			int offset = c - 'a';
-			return KeyEvent.KEYCODE_A + offset;
-		}
-
-		// handle all others
-		switch (c) {
-		case '*':
-			return KeyEvent.KEYCODE_STAR;
-		case '#':
-			return KeyEvent.KEYCODE_POUND;
-		case ',':
-			return KeyEvent.KEYCODE_COMMA;
-		case '.':
-			return KeyEvent.KEYCODE_PERIOD;
-		case '\t':
-			return KeyEvent.KEYCODE_TAB;
-		case ' ':
-			return KeyEvent.KEYCODE_SPACE;
-		case '\n':
-			return KeyEvent.KEYCODE_ENTER;
-		case '\b':
-        case 0x7F:
-			return KeyEvent.KEYCODE_DEL;
-		case '~':
-			return KeyEvent.KEYCODE_GRAVE;
-		case '-':
-			return KeyEvent.KEYCODE_MINUS;
-		case '=':
-			return KeyEvent.KEYCODE_EQUALS;
-		case '(':
-			return KeyEvent.KEYCODE_LEFT_BRACKET;
-		case ')':
-			return KeyEvent.KEYCODE_RIGHT_BRACKET;
-		case '\\':
-			return KeyEvent.KEYCODE_BACKSLASH;
-		case ';':
-			return KeyEvent.KEYCODE_SEMICOLON;
-		case '\'':
-			return KeyEvent.KEYCODE_APOSTROPHE;
-		case '/':
-			return KeyEvent.KEYCODE_SLASH;
-		default:
-			break;
-		}
-
-		return c;
-	}
-	
-	static int modifierMapper(String modifier) {
-		if (modifier.equals("ctrlKey")) {
-			return KeyEvent.KEYCODE_ALT_LEFT;
-		} else if (modifier.equals("shiftKey")) {
-			return KeyEvent.KEYCODE_SHIFT_LEFT;
-		} else if (modifier.equals("altKey")) {
-			return KeyEvent.KEYCODE_SYM;
-		} else if (modifier.equals("metaKey")) {
-			return KeyEvent.KEYCODE_UNKNOWN;
-		}
-		return KeyEvent.KEYCODE_UNKNOWN;
-	}
-
-    public void touchStart() {
-        final int numPoints = mTouchPoints.size();
-        if (numPoints == 0) {
-            return;
-        }
-
-        int[] pointerIds = new int[numPoints];
-        MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[numPoints];
-        long downTime = SystemClock.uptimeMillis();
-
-        for (int i = 0; i < numPoints; ++i) {
-            pointerIds[i] = mTouchPoints.get(i).getId();
-            pointerCoords[i] = new MotionEvent.PointerCoords();
-            pointerCoords[i].x = mTouchPoints.get(i).getX();
-            pointerCoords[i].y = mTouchPoints.get(i).getY();
-            mTouchPoints.get(i).setDownTime(downTime);
-        }
-
-        MotionEvent event = MotionEvent.obtain(downTime, downTime,
-            MotionEvent.ACTION_DOWN, numPoints, pointerIds, pointerCoords,
-            mTouchMetaState, 1.0f, 1.0f, 0, 0, 0, 0);
-
-        mWebView.onTouchEvent(event);
-    }
-
-    public void touchMove() {
-        final int numPoints = mTouchPoints.size();
-        if (numPoints == 0) {
-            return;
-        }
-
-        int[] pointerIds = new int[numPoints];
-        MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[numPoints];
-        int numMovedPoints = 0;
-        for (int i = 0; i < numPoints; ++i) {
-            TouchPoint tp = mTouchPoints.get(i);
-            if (tp.hasMoved()) {
-                pointerIds[numMovedPoints] = mTouchPoints.get(i).getId();
-                pointerCoords[i] = new MotionEvent.PointerCoords();
-                pointerCoords[numMovedPoints].x = mTouchPoints.get(i).getX();
-                pointerCoords[numMovedPoints].y = mTouchPoints.get(i).getY();
-                ++numMovedPoints;
-                tp.setMoved(false);
-            }
-        }
-
-        if (numMovedPoints == 0) {
-            return;
-        }
-
-        MotionEvent event = MotionEvent.obtain(mTouchPoints.get(0).downTime(),
-                SystemClock.uptimeMillis(), MotionEvent.ACTION_MOVE,
-                numMovedPoints, pointerIds, pointerCoords,
-                mTouchMetaState, 1.0f, 1.0f, 0, 0, 0, 0);
-        mWebView.onTouchEvent(event);
-    }
-
-    public void touchEnd() {
-        final int numPoints = mTouchPoints.size();
-        if (numPoints == 0) {
-            return;
-        }
-
-        int[] pointerIds = new int[numPoints];
-        MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[numPoints];
-
-        for (int i = 0; i < numPoints; ++i) {
-            pointerIds[i] = mTouchPoints.get(i).getId();
-            pointerCoords[i] = new MotionEvent.PointerCoords();
-            pointerCoords[i].x = mTouchPoints.get(i).getX();
-            pointerCoords[i].y = mTouchPoints.get(i).getY();
-        }
-
-        MotionEvent event = MotionEvent.obtain(mTouchPoints.get(0).downTime(),
-                SystemClock.uptimeMillis(), MotionEvent.ACTION_UP,
-                numPoints, pointerIds, pointerCoords,
-                mTouchMetaState, 1.0f, 1.0f, 0, 0, 0, 0);
-        mWebView.onTouchEvent(event);
-
-        for (int i = numPoints - 1; i >= 0; --i) {  // remove released points.
-            TouchPoint tp = mTouchPoints.get(i);
-            if (tp.isReleased()) {
-              mTouchPoints.remove(i);
-            }
-        }
-    }
-
-    public void touchCancel() {
-        final int numPoints = mTouchPoints.size();
-        if (numPoints == 0) {
-            return;
-        }
-
-        int[] pointerIds = new int[numPoints];
-        MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[numPoints];
-        long cancelTime = SystemClock.uptimeMillis();
-        int numCanceledPoints = 0;
-
-        for (int i = 0; i < numPoints; ++i) {
-            TouchPoint tp = mTouchPoints.get(i);
-            if (tp.cancelled()) {
-                pointerIds[numCanceledPoints] = mTouchPoints.get(i).getId();
-                pointerCoords[numCanceledPoints] = new MotionEvent.PointerCoords();
-                pointerCoords[numCanceledPoints].x = mTouchPoints.get(i).getX();
-                pointerCoords[numCanceledPoints].y = mTouchPoints.get(i).getY();
-                ++numCanceledPoints;
-            }
-        }
-
-        if (numCanceledPoints == 0) {
-            return;
-        }
-
-        MotionEvent event = MotionEvent.obtain(mTouchPoints.get(0).downTime(),
-            SystemClock.uptimeMillis(), MotionEvent.ACTION_CANCEL,
-            numCanceledPoints, pointerIds, pointerCoords,
-            mTouchMetaState, 1.0f, 1.0f, 0, 0, 0, 0);
-
-        mWebView.onTouchEvent(event);
-    }
-
-    public void cancelTouchPoint(int id) {
-        TouchPoint tp = mTouchPoints.get(id);
-        if (tp == null) {
-            return;
-        }
-
-        tp.cancel();
-    }
-
-    public void addTouchPoint(int x, int y) {
-        final int numPoints = mTouchPoints.size();
-        int id;
-        if (numPoints == 0) {
-          id = 0;
-        } else {
-          id = mTouchPoints.get(numPoints - 1).getId() + 1;
-        }
-
-        mTouchPoints.add(new TouchPoint(id, contentsToWindowX(x), contentsToWindowY(y)));
-    }
-
-    public void updateTouchPoint(int i, int x, int y) {
-        TouchPoint tp = mTouchPoints.get(i);
-        if (tp == null) {
-            return;
-        }
-
-        tp.update(contentsToWindowX(x), contentsToWindowY(y));
-        tp.setMoved(true);
-    }
-
-    public void setTouchModifier(String modifier, boolean enabled) {
-        int mask = 0;
-        if ("alt".equals(modifier.toLowerCase())) {
-            mask = KeyEvent.META_ALT_ON;
-        } else if ("shift".equals(modifier.toLowerCase())) {
-            mask = KeyEvent.META_SHIFT_ON;
-        } else if ("ctrl".equals(modifier.toLowerCase())) {
-            mask = KeyEvent.META_SYM_ON;
-        }
-
-        if (enabled) {
-            mTouchMetaState |= mask;
-        } else {
-            mTouchMetaState &= ~mask;
-        }
-    }
-
-    public void releaseTouchPoint(int id) {
-        TouchPoint tp = mTouchPoints.get(id);
-        if (tp == null) {
-            return;
-        }
-
-        tp.release();
-    }
-
-    public void clearTouchPoints() {
-        mTouchPoints.clear();
-    }
-
-    public void clearTouchMetaState() {
-        mTouchMetaState = 0;
-    }
-
-    private int contentsToWindowX(int x) {
-        return Math.round(x * mWebView.getScale()) - mWebView.getScrollX();
-    }
-
-    private int contentsToWindowY(int y) {
-        return Math.round(y * mWebView.getScale()) - mWebView.getScrollY();
-    }
-
-    private WebView mWebView = null;
-    private int mouseX;
-    private int mouseY;
-
-    private class TouchPoint {
-        private int mId;
-        private int mX;
-        private int mY;
-        private long mDownTime;
-        private boolean mReleased;
-        private boolean mMoved;
-        private boolean mCancelled;
-
-        public TouchPoint(int id, int x, int y) {
-            mId = id;
-            mX = x;
-            mY = y;
-            mReleased = false;
-            mMoved = false;
-            mCancelled = false;
-        }
-
-        public void setDownTime(long downTime) { mDownTime = downTime; }
-        public long downTime() { return mDownTime; }
-        public void cancel() { mCancelled = true; }
-
-        public boolean cancelled() { return mCancelled; }
-
-        public void release() { mReleased = true; }
-        public boolean isReleased() { return mReleased; }
-
-        public void setMoved(boolean moved) { mMoved = moved; }
-        public boolean hasMoved() { return mMoved; }
-
-        public int getId() { return mId; }
-        public int getX() { return mX; }
-        public int getY() { return mY; }
-
-        public void update(int x, int y) {
-            mX = x;
-            mY = y;
-        }
-    }
-
-    private Vector<TouchPoint> mTouchPoints;
-    private int mTouchMetaState;
-}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/AdbUtils.java b/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/AdbUtils.java
deleted file mode 100644
index c2ecf3a..0000000
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/AdbUtils.java
+++ /dev/null
@@ -1,127 +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.dumprendertree.forwarder;
-
-import android.util.Log;
-
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.Socket;
-
-public class AdbUtils {
-
-    private static final String ADB_OK = "OKAY";
-    private static final int ADB_PORT = 5037;
-    private static final String ADB_HOST = "127.0.0.1";
-    private static final int ADB_RESPONSE_SIZE = 4;
-
-    private static final String LOGTAG = "AdbUtils";
-
-    /**
-     *
-     * Convert integer format IP into xxx.xxx.xxx.xxx format
-     *
-     * @param host IP address in integer format
-     * @return human readable format
-     */
-    public static String convert(int host) {
-        return ((host >> 24) & 0xFF) + "."
-        + ((host >> 16) & 0xFF) + "."
-        + ((host >> 8) & 0xFF) + "."
-        + (host & 0xFF);
-    }
-
-    /**
-     *
-     * Resolve DNS name into IP address
-     *
-     * @param host DNS name
-     * @return IP address in integer format
-     * @throws IOException
-     */
-    public static int resolve(String host)  throws IOException {
-        Socket localSocket = new Socket(ADB_HOST, ADB_PORT);
-        DataInputStream dis = new DataInputStream(localSocket.getInputStream());
-        OutputStream os = localSocket.getOutputStream();
-        int count_read = 0;
-
-        if (localSocket == null || dis == null || os == null)
-            return -1;
-        String cmd = "dns:" + host;
-
-        if(!sendAdbCmd(dis, os, cmd))
-            return -1;
-
-        count_read = dis.readInt();
-        localSocket.close();
-        return count_read;
-    }
-
-    /**
-     *
-     * Send an ADB command using existing socket connection
-     *
-     * the streams provided must be from a socket connected to adbd already
-     *
-     * @param is input stream of the socket connection
-     * @param os output stream of the socket
-     * @param cmd the adb command to send
-     * @return if adb gave a success response
-     * @throws IOException
-     */
-    public static boolean sendAdbCmd(InputStream is, OutputStream os,
-            String cmd) throws IOException {
-        byte[] buf = new byte[ADB_RESPONSE_SIZE];
-
-        cmd = String.format("%04X", cmd.length()) + cmd;
-        os.write(cmd.getBytes());
-        int read = is.read(buf);
-        if(read != ADB_RESPONSE_SIZE || !ADB_OK.equals(new String(buf))) {
-            Log.w(LOGTAG, "adb cmd faild.");
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     *
-     * Get a tcp socket connection to specified IP address and port proxied by adb
-     *
-     * The proxying is transparent, e.g. if a socket is returned, then it can be written to and
-     * read from as if it is directly connected to the target
-     *
-     * @param remoteAddress IP address of the host to connect to
-     * @param remotePort port of the host to connect to
-     * @return a valid Socket instance if successful, null otherwise
-     */
-    public static Socket getForwardedSocket(int remoteAddress, int remotePort) {
-        try {
-            Socket socket = new Socket(ADB_HOST, ADB_PORT);
-            String cmd = "tcp:" + remotePort + ":" + convert(remoteAddress);
-            if(!sendAdbCmd(socket.getInputStream(), socket.getOutputStream(), cmd)) {
-                socket.close();
-                return null;
-            }
-            return socket;
-        } catch (IOException ioe) {
-            Log.w(LOGTAG, "error creating adb socket", ioe);
-            return null;
-        }
-    }
-}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/ForwardServer.java b/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/ForwardServer.java
deleted file mode 100644
index 14f8fbe..0000000
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/ForwardServer.java
+++ /dev/null
@@ -1,133 +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.dumprendertree.forwarder;
-
-import android.util.Log;
-
-import java.io.IOException;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- *
- * A port forwarding server. Listens at specified local port and forward the tcp communications to
- * external host/port via adb networking proxy.
- *
- */
-public class ForwardServer {
-
-    private static final String LOGTAG = "ForwardServer";
-
-    private int remotePort;
-    private int remoteAddress;
-    private int localPort;
-    private ServerSocket serverSocket;
-    private boolean started;
-
-    private Set<Forwarder> forwarders;
-
-    public ForwardServer(int localPort, int remoteAddress, int remotePort) {
-        this.localPort = localPort;
-        this.remoteAddress = remoteAddress;
-        this.remotePort = remotePort;
-        started = false;
-        forwarders = new HashSet<Forwarder>();
-    }
-
-    public synchronized void start() throws IOException {
-        if(!started) {
-            serverSocket = new ServerSocket(localPort);
-            Thread serverThread = new Thread(new ServerRunner(serverSocket));
-            serverThread.setName(LOGTAG);
-            serverThread.start();
-            started = true;
-        }
-    }
-
-    public synchronized void stop() {
-        if(started) {
-            synchronized (forwarders) {
-                for(Forwarder forwarder : forwarders)
-                    forwarder.stop();
-                forwarders.clear();
-            }
-            try {
-                serverSocket.close();
-            } catch (IOException ioe) {
-                Log.v(LOGTAG, "exception while closing", ioe);
-            } finally {
-                started = false;
-            }
-        }
-    }
-
-    public synchronized boolean isRunning() {
-        return started;
-    }
-
-    private class ServerRunner implements Runnable {
-
-        private ServerSocket socket;
-
-        public ServerRunner(ServerSocket socket) {
-            this.socket = socket;
-        }
-
-        public void run() {
-            try {
-                while (true) {
-                    Socket localSocket = socket.accept();
-                    Socket remoteSocket = AdbUtils.getForwardedSocket(remoteAddress, remotePort);
-                    if(remoteSocket == null) {
-                        try {
-                            localSocket.close();
-                        } catch (IOException ioe) {
-                            Log.w(LOGTAG, "error while closing socket", ioe);
-                        } finally {
-                            Log.w(LOGTAG, "failed to start forwarding from " + localSocket);
-                        }
-                    } else {
-                        Forwarder forwarder = new Forwarder(localSocket, remoteSocket,
-                                ForwardServer.this);
-                        forwarder.start();
-                    }
-                }
-            } catch (IOException ioe) {
-                return;
-            }
-        }
-    }
-
-    public void register(Forwarder forwarder) {
-        synchronized (forwarders) {
-            if(!forwarders.contains(forwarder)) {
-                forwarders.add(forwarder);
-            }
-        }
-    }
-
-    public void unregister(Forwarder recyclable) {
-        synchronized (forwarders) {
-            if(forwarders.contains(recyclable)) {
-                recyclable.stop();
-                forwarders.remove(recyclable);
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/ForwardService.java b/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/ForwardService.java
deleted file mode 100644
index 25dd04fd..0000000
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/ForwardService.java
+++ /dev/null
@@ -1,117 +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.dumprendertree.forwarder;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-
-import android.os.Environment;
-import android.util.Log;
-
-public class ForwardService {
-
-    private ForwardServer fs8000, fs8080, fs8443;
-
-    private static ForwardService inst;
-
-    private static final String LOGTAG = "ForwardService";
-
-    private static final String DEFAULT_TEST_HOST = "android-browser-test.mtv.corp.google.com";
-
-    private static final String FORWARD_HOST_CONF =
-        Environment.getExternalStorageDirectory() + "/drt_forward_host.txt";
-
-    private ForwardService() {
-        int addr = getForwardHostAddr();
-        if (addr != -1) {
-            fs8000 = new ForwardServer(8000, addr, 8000);
-            fs8080 = new ForwardServer(8080, addr, 8080);
-            fs8443 = new ForwardServer(8443, addr, 8443);
-        }
-    }
-
-    public static ForwardService getForwardService() {
-        if (inst == null) {
-            inst = new ForwardService();
-        }
-        return inst;
-    }
-
-    public void startForwardService() {
-        try {
-            if (fs8000 != null)
-                fs8000.start();
-            if (fs8080 != null)
-                fs8080.start();
-            if (fs8443 != null)
-                fs8443.start();
-        } catch (IOException ioe) {
-            Log.w(LOGTAG, "failed to start forwarder. http tests will fail.", ioe);
-            return;
-        }
-    }
-
-    public void stopForwardService() {
-        if (fs8000 != null) {
-            fs8000.stop();
-            fs8000 = null;
-        }
-        if (fs8080 != null) {
-            fs8080.stop();
-            fs8080 = null;
-        }
-        if (fs8443 != null) {
-            fs8443.stop();
-            fs8443 = null;
-        }
-        Log.v(LOGTAG, "forwarders stopped.");
-    }
-
-    private static int getForwardHostAddr() {
-        int addr = -1;
-        String host = null;
-        File forwardHostConf = new File(FORWARD_HOST_CONF);
-        if (forwardHostConf.isFile()) {
-            BufferedReader hostReader = null;
-            try {
-                hostReader = new BufferedReader(new FileReader(forwardHostConf));
-                host = hostReader.readLine();
-                Log.v(LOGTAG, "read forward host from file: " + host);
-            } catch (IOException ioe) {
-                Log.v(LOGTAG, "cannot read forward host from file", ioe);
-            } finally {
-                if (hostReader != null) {
-                    try {
-                        hostReader.close();
-                    } catch (IOException ioe) {
-                        // burn!!!
-                    }
-                }
-            }
-        }
-        if (host == null || host.length() == 0)
-            host = DEFAULT_TEST_HOST;
-        try {
-            addr = AdbUtils.resolve(host);
-        } catch (IOException ioe) {
-            Log.e(LOGTAG, "failed to resolve server address", ioe);
-        }
-        return addr;
-    }
-}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/Forwarder.java b/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/Forwarder.java
deleted file mode 100644
index a971e7b..0000000
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/Forwarder.java
+++ /dev/null
@@ -1,109 +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.dumprendertree.forwarder;
-
-import android.util.Log;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.Socket;
-
-/**
- *
- * Worker class for {@link ForwardServer}. A Forwarder will be created once the ForwardServer
- * accepts an incoming connection, and it will then forward the incoming/outgoing streams to a
- * connection already proxied by adb networking (see also {@link AdbUtils}).
- *
- */
-public class Forwarder {
-
-    private ForwardServer server;
-    private Socket from, to;
-
-    private static final String LOGTAG = "Forwarder";
-    private static final int BUFFER_SIZE = 16384;
-
-    public Forwarder (Socket from, Socket to, ForwardServer server) {
-        this.server = server;
-        this.from = from;
-        this.to = to;
-        server.register(this);
-    }
-
-    public void start() {
-        Thread outgoing = new Thread(new SocketPipe(from, to));
-        Thread incoming = new Thread(new SocketPipe(to, from));
-        outgoing.setName(LOGTAG);
-        incoming.setName(LOGTAG);
-        outgoing.start();
-        incoming.start();
-    }
-
-    public void stop() {
-        shutdown(from);
-        shutdown(to);
-    }
-
-    private void shutdown(Socket socket) {
-        try {
-            socket.shutdownInput();
-        } catch (IOException e) {
-            Log.v(LOGTAG, "Socket#shutdownInput", e);
-        }
-        try {
-            socket.shutdownOutput();
-        } catch (IOException e) {
-            Log.v(LOGTAG, "Socket#shutdownOutput", e);
-        }
-        try {
-            socket.close();
-        } catch (IOException e) {
-            Log.v(LOGTAG, "Socket#close", e);
-        }
-    }
-
-    private class SocketPipe implements Runnable {
-
-        private Socket in, out;
-
-        public SocketPipe(Socket in, Socket out) {
-            this.in = in;
-            this.out = out;
-        }
-
-        public void run() {
-            try {
-                int length;
-                InputStream is = in.getInputStream();
-                OutputStream os = out.getOutputStream();
-                byte[] buffer = new byte[BUFFER_SIZE];
-                while ((length = is.read(buffer)) > 0) {
-                    os.write(buffer, 0, length);
-                }
-            } catch (IOException ioe) {
-            } finally {
-                server.unregister(Forwarder.this);
-            }
-        }
-
-        @Override
-        public String toString() {
-            return "SocketPipe{" + in + "=>" + out  + "}";
-        }
-    }
-}
diff --git a/tests/DumpRenderTree2/Android.mk b/tests/DumpRenderTree2/Android.mk
deleted file mode 100644
index 81fc633..0000000
--- a/tests/DumpRenderTree2/Android.mk
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# Copyright (C) 2010 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-LOCAL_STATIC_JAVA_LIBRARIES := diff_match_patch
-
-LOCAL_PACKAGE_NAME := DumpRenderTree2
-
-include $(BUILD_PACKAGE)
\ No newline at end of file
diff --git a/tests/DumpRenderTree2/AndroidManifest.xml b/tests/DumpRenderTree2/AndroidManifest.xml
deleted file mode 100644
index ea6571e..0000000
--- a/tests/DumpRenderTree2/AndroidManifest.xml
+++ /dev/null
@@ -1,60 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.dumprendertree2">
-    <application>
-        <uses-library android:name="android.test.runner" />
-
-        <activity android:name=".ui.DirListActivity"
-                  android:label="Dump Render Tree 2"
-                  android:configChanges="orientation">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.TEST" />
-            </intent-filter>
-        </activity>
-
-        <!-- android:launchMode="singleTask" is there so we only have a one instance
-             of this activity. However, it doesn't seem to work exactly like described in the
-             documentation, because the behaviour of the application suggest
-             there is only a single task for all 3 activities. We don't understand
-             how exactly it all works, but at the moment it works just fine.
-             It can lead to some weird behaviour in the future. -->
-        <activity android:name=".TestsListActivity"
-                  android:label="Tests' list activity"
-                  android:launchMode="singleTask"
-                  android:configChanges="orientation">
-        </activity>
-
-        <activity android:name=".LayoutTestsExecutor"
-                  android:theme="@style/WhiteBackground"
-                  android:label="Layout tests' executor"
-                  android:process=":executor">
-        </activity>
-
-        <service android:name="ManagerService">
-        </service>
-    </application>
-
-    <instrumentation android:name="com.android.dumprendertree2.scriptsupport.ScriptTestRunner"
-                     android:targetPackage="com.android.dumprendertree2"
-                     android:label="Layout tests script runner" />
-
-    <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.WRITE_SDCARD" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-    <uses-permission android:name="android.permission.WAKE_LOCK" />
-</manifest>
diff --git a/tests/DumpRenderTree2/assets/run_apache2.py b/tests/DumpRenderTree2/assets/run_apache2.py
deleted file mode 100755
index 3806599..0000000
--- a/tests/DumpRenderTree2/assets/run_apache2.py
+++ /dev/null
@@ -1,163 +0,0 @@
-#!/usr/bin/python
-#
-# 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.
-#
-"""Start, stop, or restart apache2 server.
-
-  Apache2 must be installed with mod_php!
-
-  Usage:
-    run_apache2.py start|stop|restart
-"""
-
-import sys
-import os
-import subprocess
-import logging
-import optparse
-import time
-
-def main(run_cmd, options):
-  # Setup logging class
-  logging.basicConfig(level=logging.INFO, format='%(message)s')
-
-  if not run_cmd in ("start", "stop", "restart"):
-    logging.info("illegal argument: " + run_cmd)
-    logging.info("Usage: python run_apache2.py start|stop|restart")
-    return False
-
-  # Create /tmp/WebKit if it doesn't exist. This is needed for various files used by apache2
-  tmp_WebKit = os.path.join("/tmp", "WebKit")
-  if not os.path.exists(tmp_WebKit):
-    os.mkdir(tmp_WebKit)
-
-  # Get the path to android tree root based on the script location.
-  # Basically we go 5 levels up
-  parent = os.pardir
-  script_location = os.path.abspath(os.path.dirname(sys.argv[0]))
-  android_tree_root = os.path.join(script_location, parent, parent, parent, parent, parent)
-  android_tree_root = os.path.normpath(android_tree_root)
-
-  # If any of these is relative, then it's relative to ServerRoot (in our case android_tree_root)
-  webkit_path = os.path.join("external", "webkit")
-  if (options.tests_root_directory != None):
-    # if options.tests_root_directory is absolute, os.getcwd() is discarded!
-    layout_tests_path = os.path.normpath(os.path.join(os.getcwd(), options.tests_root_directory))
-  else:
-    layout_tests_path = os.path.join(webkit_path, "LayoutTests")
-  http_conf_path = os.path.join(layout_tests_path, "http", "conf")
-
-  # Prepare the command to set ${APACHE_RUN_USER} and ${APACHE_RUN_GROUP}
-  envvars_path = os.path.join("/etc", "apache2", "envvars")
-  export_envvars_cmd = "source " + envvars_path
-
-  error_log_path = os.path.join(tmp_WebKit, "apache2-error.log")
-  custom_log_path = os.path.join(tmp_WebKit, "apache2-access.log")
-
-  # Prepare the command to (re)start/stop the server with specified settings
-  apache2_restart_template = "apache2 -k %s"
-  directives  = " -c \"ServerRoot " + android_tree_root + "\""
-
-  # The default config in apache2-debian-httpd.conf listens on ports 8080 and
-  # 8443. We also need to listen on port 8000 for HTTP tests.
-  directives += " -c \"Listen 8000\""
-
-  # We use http/tests as the document root as the HTTP tests use hardcoded
-  # resources at the server root. We then use aliases to make available the
-  # complete set of tests and the required scripts.
-  directives += " -c \"DocumentRoot " + os.path.join(layout_tests_path, "http", "tests/") + "\""
-  directives += " -c \"Alias /LayoutTests " + layout_tests_path + "\""
-  directives += " -c \"Alias /Tools/DumpRenderTree/android " + \
-    os.path.join(webkit_path, "Tools", "DumpRenderTree", "android") + "\""
-  directives += " -c \"Alias /ThirdPartyProject.prop " + \
-    os.path.join(webkit_path, "ThirdPartyProject.prop") + "\""
-
-  # This directive is commented out in apache2-debian-httpd.conf for some reason
-  # However, it is useful to browse through tests in the browser, so it's added here.
-  # One thing to note is that because of problems with mod_dir and port numbers, mod_dir
-  # is turned off. That means that there _must_ be a trailing slash at the end of URL
-  # for auto indexes to work correctly.
-  directives += " -c \"LoadModule autoindex_module /usr/lib/apache2/modules/mod_autoindex.so\""
-
-  directives += " -c \"ErrorLog " + error_log_path +"\""
-  directives += " -c \"CustomLog " + custom_log_path + " combined\""
-  directives += " -c \"SSLCertificateFile " + os.path.join(http_conf_path, "webkit-httpd.pem") + \
-    "\""
-  directives += " -c \"User ${APACHE_RUN_USER}\""
-  directives += " -c \"Group ${APACHE_RUN_GROUP}\""
-  directives += " -C \"TypesConfig " + \
-    os.path.join(android_tree_root, http_conf_path, "mime.types") + "\""
-  conf_file_cmd = " -f " + \
-    os.path.join(android_tree_root, http_conf_path, "apache2-debian-httpd.conf")
-
-  # Try to execute the commands
-  logging.info("Will " + run_cmd + " apache2 server.")
-
-  # It is worth noting here that if the configuration file with which we restart the server points
-  # to a different PidFile it will not work and will result in a second apache2 instance.
-  if (run_cmd == 'restart'):
-    logging.info("First will stop...")
-    if execute_cmd(envvars_path, error_log_path,
-                   export_envvars_cmd + " && " + (apache2_restart_template % ('stop')) + directives + conf_file_cmd) == False:
-      logging.info("Failed to stop Apache2")
-      return False
-    logging.info("Stopped. Will start now...")
-    # We need to sleep breifly to avoid errors with apache being stopped and started too quickly
-    time.sleep(0.5)
-
-  if execute_cmd(envvars_path, error_log_path,
-                 export_envvars_cmd + " && " +
-                 (apache2_restart_template % (run_cmd)) + directives +
-                 conf_file_cmd) == False:
-    logging.info("Failed to start Apache2")
-    return False
-
-  logging.info("Successfully started")
-  return True
-
-def execute_cmd(envvars_path, error_log_path, cmd):
-  p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-  (out, err) = p.communicate()
-
-  # Output the stdout from the command to console
-  logging.info(out)
-
-  # Report any errors
-  if p.returncode != 0:
-    logging.info("!! ERRORS:")
-
-    if err.find(envvars_path) != -1:
-      logging.info(err)
-    elif err.find('command not found') != -1:
-      logging.info("apache2 is probably not installed")
-    else:
-      logging.info(err)
-      logging.info("Try looking in " + error_log_path + " for details")
-    return False
-
-  return True
-
-if __name__ == "__main__":
-  option_parser = optparse.OptionParser(usage="Usage: %prog [options] start|stop|restart")
-  option_parser.add_option("", "--tests-root-directory",
-                           help="The directory from which to take the tests, default is external/webkit/LayoutTests in this checkout of the Android tree")
-  options, args = option_parser.parse_args();
-
-  if len(args) < 1:
-    run_cmd = ""
-  else:
-    run_cmd = args[0]
-
-  main(run_cmd, options)
diff --git a/tests/DumpRenderTree2/assets/run_layout_tests.py b/tests/DumpRenderTree2/assets/run_layout_tests.py
deleted file mode 100755
index 161416a..0000000
--- a/tests/DumpRenderTree2/assets/run_layout_tests.py
+++ /dev/null
@@ -1,99 +0,0 @@
-#!/usr/bin/python
-
-"""Run layout tests on the device.
-
-  It runs the specified tests on the device, downloads the summaries to the temporary directory
-  and optionally shows the detailed results the host's default browser.
-
-  Usage:
-    run_layout_tests.py --show-results-in-browser test-relative-path
-"""
-
-import logging
-import optparse
-import os
-import re
-import sys
-import subprocess
-import tempfile
-import webbrowser
-
-import run_apache2
-
-#TODO: These should not be hardcoded
-RESULTS_ABSOLUTE_PATH = "/sdcard/layout-test-results/"
-DETAILS_HTML = "details.html"
-SUMMARY_TXT = "summary.txt"
-
-def main(path, options):
-  tmpdir = tempfile.gettempdir()
-
-  # Restart the server
-  if run_apache2.main("restart", options) == False:
-    return
-
-  # Run the tests in path
-  adb_cmd = "adb"
-  if options.serial:
-    adb_cmd += " -s " + options.serial
-  cmd = adb_cmd + " shell am instrument "
-  cmd += "-e class com.android.dumprendertree2.scriptsupport.Starter#startLayoutTests "
-  cmd += "-e path \"" + path + "\" "
-  cmd += "-w com.android.dumprendertree2/com.android.dumprendertree2.scriptsupport.ScriptTestRunner"
-
-  logging.info("Running the tests...")
-  logging.debug("Command = %s" % cmd)
-  (stdoutdata, stderrdata) = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
-  if stderrdata != "":
-    logging.info("Failed to start tests:\n%s", stderrdata)
-    return
-  if re.search("^INSTRUMENTATION_STATUS_CODE: -1", stdoutdata, re.MULTILINE) != None:
-    logging.info("Failed to run the tests. Is DumpRenderTree2 installed on the device?")
-    return
-  if re.search("^OK \([0-9]+ tests?\)", stdoutdata, re.MULTILINE) == None:
-    logging.info("DumpRenderTree2 failed to run correctly:\n%s", stdoutdata)
-    return
-
-  logging.info("Downloading the summaries...")
-
-  # Download the txt summary to tmp folder
-  summary_txt_tmp_path = os.path.join(tmpdir, SUMMARY_TXT)
-  cmd = "rm -f " + summary_txt_tmp_path + ";"
-  cmd += adb_cmd + " pull " + RESULTS_ABSOLUTE_PATH + SUMMARY_TXT + " " + summary_txt_tmp_path
-  subprocess.Popen(cmd, shell=True).wait()
-
-  # Download the html summary to tmp folder
-  details_html_tmp_path = os.path.join(tmpdir, DETAILS_HTML)
-  cmd = "rm -f " + details_html_tmp_path + ";"
-  cmd += adb_cmd + " pull " + RESULTS_ABSOLUTE_PATH + DETAILS_HTML + " " + details_html_tmp_path
-  subprocess.Popen(cmd, shell=True).wait()
-
-  # Print summary to console
-  logging.info("All done.\n")
-  cmd = "cat " + summary_txt_tmp_path
-  os.system(cmd)
-  logging.info("")
-
-  # Open the browser with summary
-  if options.show_results_in_browser != "false":
-    webbrowser.open(details_html_tmp_path)
-
-if __name__ == "__main__":
-  option_parser = optparse.OptionParser(usage="Usage: %prog [options] test-relative-path")
-  option_parser.add_option("", "--show-results-in-browser", default="true",
-                           help="Show the results the host's default web browser, default=true")
-  option_parser.add_option("", "--tests-root-directory",
-                           help="The directory from which to take the tests, default is external/webkit/LayoutTests in this checkout of the Android tree")
-  option_parser.add_option("-s", "--serial", default=None, help="Specify the serial number of device to run test on")
-  options, args = option_parser.parse_args();
-
-  logging.basicConfig(level=logging.INFO, format='%(message)s')
-
-  if len(args) > 1:
-    logging.fatal("Usage: run_layout_tests.py [options] test-relative-path")
-  else:
-    if len(args) < 1:
-      path = "";
-    else:
-      path = args[0]
-    main(path, options);
diff --git a/tests/DumpRenderTree2/res/drawable/folder.png b/tests/DumpRenderTree2/res/drawable/folder.png
deleted file mode 100644
index 5b3fcec..0000000
--- a/tests/DumpRenderTree2/res/drawable/folder.png
+++ /dev/null
Binary files differ
diff --git a/tests/DumpRenderTree2/res/drawable/runtest.png b/tests/DumpRenderTree2/res/drawable/runtest.png
deleted file mode 100644
index 910c654..0000000
--- a/tests/DumpRenderTree2/res/drawable/runtest.png
+++ /dev/null
Binary files differ
diff --git a/tests/DumpRenderTree2/res/layout/dirlist_row.xml b/tests/DumpRenderTree2/res/layout/dirlist_row.xml
deleted file mode 100644
index e5578a6..0000000
--- a/tests/DumpRenderTree2/res/layout/dirlist_row.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-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.
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="horizontal"
-    android:gravity="center_vertical"
-    android:layout_width="fill_parent"
-    android:layout_height="wrap_content">
-
-    <ImageView
-        android:id="@+id/icon"
-        android:layout_width="80px"
-        android:adjustViewBounds="true"
-        android:paddingLeft="15px"
-        android:paddingRight="15px"
-        android:paddingTop="15px"
-        android:paddingBottom="15px"
-        android:layout_height="wrap_content"
-    />
-
-    <TextView
-        android:id="@+id/label"
-        android:layout_width="fill_parent"
-        android:layout_height="wrap_content"
-        android:minHeight="60px"
-        android:gravity="center_vertical"
-        android:textSize="14sp"
-    />
-
-</LinearLayout>
\ No newline at end of file
diff --git a/tests/DumpRenderTree2/res/menu/gui_menu.xml b/tests/DumpRenderTree2/res/menu/gui_menu.xml
deleted file mode 100644
index a5b2b65..0000000
--- a/tests/DumpRenderTree2/res/menu/gui_menu.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-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.
--->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:id="@+id/run_all"
-          android:title="@string/run_all_tests" />
-</menu>
\ No newline at end of file
diff --git a/tests/DumpRenderTree2/res/values/strings.xml b/tests/DumpRenderTree2/res/values/strings.xml
deleted file mode 100644
index 0496404..0000000
--- a/tests/DumpRenderTree2/res/values/strings.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-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.
--->
-<resources>
-    <string name="dialog_run_abort_dir_title_prefix">Directory:</string>
-    <string name="dialog_run_abort_dir_msg">This will run all the tests in this directory and all
-            the subdirectories. It may take a few hours!</string>
-    <string name="dialog_run_abort_dir_ok_button">Run tests!</string>
-    <string name="dialog_run_abort_dir_abort_button">Abort</string>
-
-    <string name="dialog_progress_title">Loading items.</string>
-    <string name="dialog_progress_msg">Please wait...</string>
-
-    <string name="runner_preloading_title">Preloading tests...</string>
-
-    <string name="run_all_tests">Run all tests in the current directory</string>
-</resources>
\ No newline at end of file
diff --git a/tests/DumpRenderTree2/res/values/style.xml b/tests/DumpRenderTree2/res/values/style.xml
deleted file mode 100644
index 35f3419..0000000
--- a/tests/DumpRenderTree2/res/values/style.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-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.
--->
-<resources>
-    <style name="WhiteBackground">
-        <item name="android:background">@android:color/white</item>
-    </style>
-</resources>
\ No newline at end of file
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/AbstractResult.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/AbstractResult.java
deleted file mode 100644
index 614b03c..0000000
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/AbstractResult.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.dumprendertree2;
-
-import android.os.Bundle;
-import android.os.Message;
-import android.util.Log;
-import android.webkit.WebView;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-
-/**
- * A class that represent a result of the test. It is responsible for returning the result's
- * raw data and generating its own diff in HTML format.
- */
-public abstract class AbstractResult implements Comparable<AbstractResult>, Serializable {
-
-    private static final String LOG_TAG = "AbstractResult";
-
-    public enum TestType {
-        TEXT {
-            @Override
-            public AbstractResult createResult(Bundle bundle) {
-                return new TextResult(bundle);
-            }
-        },
-        RENDER_TREE {
-            @Override
-            public AbstractResult createResult(Bundle bundle) {
-                /** TODO: RenderTree tests are not yet supported */
-                return null;
-            }
-        };
-
-        public abstract AbstractResult createResult(Bundle bundle);
-    }
-
-    /**
-     * A code representing the result of comparing actual and expected results.
-     */
-    public enum ResultCode implements Serializable {
-        RESULTS_MATCH("Results match"),
-        RESULTS_DIFFER("Results differ"),
-        NO_EXPECTED_RESULT("No expected result"),
-        NO_ACTUAL_RESULT("No actual result");
-
-        private String mTitle;
-
-        private ResultCode(String title) {
-            mTitle = title;
-        }
-
-        @Override
-        public String toString() {
-            return mTitle;
-        }
-    }
-
-    String mAdditionalTextOutputString;
-
-    public int compareTo(AbstractResult another) {
-        return getRelativePath().compareTo(another.getRelativePath());
-    }
-
-    public void setAdditionalTextOutputString(String additionalTextOutputString) {
-        mAdditionalTextOutputString = additionalTextOutputString;
-    }
-
-    public String getAdditionalTextOutputString() {
-        return mAdditionalTextOutputString;
-    }
-
-    public byte[] getBytes() {
-        ByteArrayOutputStream baos = null;
-        ObjectOutputStream oos = null;
-        try {
-            try {
-                baos = new ByteArrayOutputStream();
-                oos = new ObjectOutputStream(baos);
-                oos.writeObject(this);
-            } finally {
-                if (baos != null) {
-                    baos.close();
-                }
-                if (oos != null) {
-                    oos.close();
-                }
-            }
-        } catch (IOException e) {
-            Log.e(LOG_TAG, "Unable to serialize result: " + getRelativePath(), e);
-        }
-
-        return baos == null ? null : baos.toByteArray();
-    }
-
-    public static AbstractResult create(byte[] bytes) {
-        ByteArrayInputStream bais = null;
-        ObjectInputStream ois = null;
-        AbstractResult result = null;
-        try {
-            try {
-                bais = new ByteArrayInputStream(bytes);
-                ois = new ObjectInputStream(bais);
-                result = (AbstractResult)ois.readObject();
-            } finally {
-                if (bais != null) {
-                    bais.close();
-                }
-                if (ois != null) {
-                    ois.close();
-                }
-            }
-        } catch (IOException e) {
-            Log.e(LOG_TAG, "Unable to deserialize result!", e);
-        } catch (ClassNotFoundException e) {
-            Log.e(LOG_TAG, "Unable to deserialize result!", e);
-        }
-        return result;
-    }
-
-    public void clearResults() {
-        mAdditionalTextOutputString = null;
-    }
-
-    /**
-     * Makes the result object obtain the results of the test from the webview
-     * and store them in the format that suits itself bests. This method is asynchronous.
-     * The message passed as a parameter is a message that should be sent to its target
-     * when the result finishes obtaining the result.
-     *
-     * @param webview
-     * @param resultObtainedMsg
-     */
-    public abstract void obtainActualResults(WebView webview, Message resultObtainedMsg);
-
-    public abstract void setExpectedImageResult(byte[] expectedResult);
-
-    public abstract void setExpectedImageResultPath(String relativePath);
-
-    public abstract String getExpectedImageResultPath();
-
-    public abstract void setExpectedTextResult(String expectedResult);
-
-    public abstract void setExpectedTextResultPath(String relativePath);
-
-    public abstract String getExpectedTextResultPath();
-
-    /**
-     * Returns result's image data that can be written to the disk. It can be null
-     * if there is an error of some sort or for example the test times out.
-     *
-     * <p> Some tests will not provide data (like text tests)
-     *
-     * @return
-     *      results image data
-     */
-    public abstract byte[] getActualImageResult();
-
-    /**
-     * Returns result's text data. It can be null
-     * if there is an error of some sort or for example the test times out.
-     *
-     * @return
-     *      results text data
-     */
-    public abstract String getActualTextResult();
-
-    /**
-     * Returns the status code representing the result of comparing actual and expected results.
-     *
-     * @return
-     *      the status code from comparing actual and expected results
-     */
-    public abstract ResultCode getResultCode();
-
-    /**
-     * Returns whether this test crashed.
-     *
-     * @return
-     *      whether this test crashed
-     */
-    public abstract boolean didCrash();
-
-    /**
-     * Returns whether this test timed out.
-     *
-     * @return
-     *      whether this test timed out
-     */
-    public abstract boolean didTimeOut();
-
-    /**
-     * Sets that this test timed out.
-     */
-    public abstract void setDidTimeOut();
-
-    /**
-     * Returns whether the test passed.
-     *
-     * @return
-     *      whether the test passed
-     */
-    public boolean didPass() {
-        // Tests that crash can't have timed out or have an actual result.
-        assert !(didCrash() && didTimeOut());
-        assert !(didCrash() && getResultCode() != ResultCode.NO_ACTUAL_RESULT);
-        return !didCrash() && !didTimeOut() && getResultCode() == ResultCode.RESULTS_MATCH;
-    }
-
-    /**
-     * Return the type of the result data.
-     *
-     * @return
-     *      the type of the result data.
-     */
-    public abstract TestType getType();
-
-    public abstract String getRelativePath();
-
-    /**
-     * Returns a piece of HTML code that presents a visual diff between a result and
-     * the expected result.
-     *
-     * @return
-     *      a piece of HTML code with a visual diff between the result and the expected result
-     */
-    public abstract String getDiffAsHtml();
-
-    public abstract Bundle getBundle();
-}
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/AdditionalTextOutput.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/AdditionalTextOutput.java
deleted file mode 100644
index bb9a916..0000000
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/AdditionalTextOutput.java
+++ /dev/null
@@ -1,119 +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.dumprendertree2;
-
-import android.util.Log;
-import android.webkit.ConsoleMessage;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-
-/**
- * A class that stores consoles messages, database callbacks, alert messages, etc.
- */
-public class AdditionalTextOutput {
-    private static final String LOG_TAG = "AdditionalTextOutput";
-
-    /**
-     * Ordering of enums is important as it determines ordering of the toString method!
-     * StringBuilders will be printed in the order the corresponding types appear here.
-     */
-    private enum OutputType {
-        JS_DIALOG,
-        EXCEEDED_DB_QUOTA_MESSAGE,
-        CONSOLE_MESSAGE;
-    }
-
-    StringBuilder[] mOutputs = new StringBuilder[OutputType.values().length];
-
-    private StringBuilder getStringBuilderForType(OutputType outputType) {
-        int index = outputType.ordinal();
-        if (mOutputs[index] == null) {
-            mOutputs[index] = new StringBuilder();
-        }
-        return mOutputs[index];
-    }
-
-    public void appendExceededDbQuotaMessage(String urlString, String databaseIdentifier) {
-        StringBuilder output = getStringBuilderForType(OutputType.EXCEEDED_DB_QUOTA_MESSAGE);
-
-        String protocol = "";
-        String host = "";
-        int port = 0;
-
-        try {
-            URL url = new URL(urlString);
-            protocol = url.getProtocol();
-            host = url.getHost();
-            if (url.getPort() > -1) {
-                port = url.getPort();
-            }
-        } catch (MalformedURLException e) {
-            Log.e(LOG_TAG, "urlString=" + urlString + " databaseIdentifier=" + databaseIdentifier,
-                    e);
-        }
-
-        output.append("UI DELEGATE DATABASE CALLBACK: ");
-        output.append("exceededDatabaseQuotaForSecurityOrigin:{");
-        output.append(protocol + ", " + host + ", " + port + "} ");
-        output.append("database:" + databaseIdentifier + "\n");
-    }
-
-    public void appendConsoleMessage(ConsoleMessage consoleMessage) {
-        StringBuilder output = getStringBuilderForType(OutputType.CONSOLE_MESSAGE);
-
-        output.append("CONSOLE MESSAGE: line " + consoleMessage.lineNumber());
-        output.append(": " + consoleMessage.message() + "\n");
-    }
-
-    public void appendJsAlert(String message) {
-        StringBuilder output = getStringBuilderForType(OutputType.JS_DIALOG);
-
-        output.append("ALERT: ");
-        output.append(message);
-        output.append('\n');
-    }
-
-    public void appendJsConfirm(String message) {
-        StringBuilder output = getStringBuilderForType(OutputType.JS_DIALOG);
-
-        output.append("CONFIRM: ");
-        output.append(message);
-        output.append('\n');
-    }
-
-    public void appendJsPrompt(String message, String defaultValue) {
-        StringBuilder output = getStringBuilderForType(OutputType.JS_DIALOG);
-
-        output.append("PROMPT: ");
-        output.append(message);
-        output.append(", default text: ");
-        output.append(defaultValue);
-        output.append('\n');
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder result = new StringBuilder();
-        for (int i = 0; i < mOutputs.length; i++) {
-            if (mOutputs[i] != null) {
-                result.append(mOutputs[i].toString());
-            }
-        }
-        return result.toString();
-    }
-}
\ No newline at end of file
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/CrashedDummyResult.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/CrashedDummyResult.java
deleted file mode 100644
index 4831168..0000000
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/CrashedDummyResult.java
+++ /dev/null
@@ -1,125 +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.dumprendertree2;
-
-import android.os.Bundle;
-import android.os.Message;
-import android.webkit.WebView;
-
-/**
- * A dummy class representing test that crashed.
- *
- * TODO: All the methods regarding expected results need implementing.
- */
-public class CrashedDummyResult extends AbstractResult {
-    String mRelativePath;
-
-    public CrashedDummyResult(String relativePath) {
-        mRelativePath = relativePath;
-    }
-
-    @Override
-    public byte[] getActualImageResult() {
-        return null;
-    }
-
-    @Override
-    public String getActualTextResult() {
-        return null;
-    }
-
-    @Override
-    public Bundle getBundle() {
-        /** TODO:  */
-        return null;
-    }
-
-    @Override
-    public String getDiffAsHtml() {
-        /** TODO: Probably show at least expected results */
-        return "Ooops, I crashed...";
-    }
-
-    @Override
-    public String getRelativePath() {
-        return mRelativePath;
-    }
-
-    @Override
-    public ResultCode getResultCode() {
-        return ResultCode.NO_ACTUAL_RESULT;
-    }
-
-    @Override
-    public boolean didCrash() {
-        return true;
-    }
-
-    @Override
-    public boolean didTimeOut() {
-        return false;
-    }
-
-    @Override
-    public void setDidTimeOut() {
-        /** This method is not applicable for this type of result */
-        assert false;
-    }
-
-    @Override
-    public TestType getType() {
-        return null;
-    }
-
-    @Override
-    public void obtainActualResults(WebView webview, Message resultObtainedMsg) {
-        /** This method is not applicable for this type of result */
-        assert false;
-    }
-
-    @Override
-    public void setExpectedImageResult(byte[] expectedResult) {
-        /** TODO */
-    }
-
-    @Override
-    public void setExpectedTextResult(String expectedResult) {
-        /** TODO */
-    }
-
-    @Override
-    public String getExpectedImageResultPath() {
-        /** TODO */
-        return null;
-    }
-
-    @Override
-    public String getExpectedTextResultPath() {
-        /** TODO */
-        return null;
-    }
-
-    @Override
-    public void setExpectedImageResultPath(String relativePath) {
-        /** TODO */
-    }
-
-    @Override
-    public void setExpectedTextResultPath(String relativePath) {
-        /** TODO */
-    }
-}
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/EventSender.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/EventSender.java
deleted file mode 100644
index 5b7cbc4..0000000
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/EventSender.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.dumprendertree2;
-
-import android.webkit.WebView;
-
-/**
- * A class that acts as a JS interface for webview to mock various touch events,
- * mouse actions and key presses.
- *
- * The methods here just call corresponding methods on EventSenderImpl
- * that contains the logic of how to execute the methods.
- */
-public class EventSender {
-    EventSenderImpl mEventSenderImpl = new EventSenderImpl();
-
-    public void reset(WebView webView) {
-        mEventSenderImpl.reset(webView);
-    }
-
-    public void enableDOMUIEventLogging(int domNode) {
-        mEventSenderImpl.enableDOMUIEventLogging(domNode);
-    }
-
-    public void fireKeyboardEventsToElement(int domNode) {
-        mEventSenderImpl.fireKeyboardEventsToElement(domNode);
-    }
-
-    public void keyDown(String character, String[] withModifiers) {
-        mEventSenderImpl.keyDown(character, withModifiers);
-    }
-
-    public void keyDown(String character) {
-        keyDown(character, null);
-    }
-
-    public void leapForward(int milliseconds) {
-        mEventSenderImpl.leapForward(milliseconds);
-    }
-
-    public void mouseClick() {
-        mEventSenderImpl.mouseClick();
-    }
-
-    public void mouseDown() {
-        mEventSenderImpl.mouseDown();
-    }
-
-    public void mouseMoveTo(int x, int y) {
-        mEventSenderImpl.mouseMoveTo(x, y);
-    }
-
-    public void mouseUp() {
-        mEventSenderImpl.mouseUp();
-    }
-
-    public void touchStart() {
-        mEventSenderImpl.touchStart();
-    }
-
-    public void addTouchPoint(int x, int y) {
-        mEventSenderImpl.addTouchPoint(x, y);
-    }
-
-    public void updateTouchPoint(int id, int x, int y) {
-        mEventSenderImpl.updateTouchPoint(id, x, y);
-    }
-
-    public void setTouchModifier(String modifier, boolean enabled) {
-        mEventSenderImpl.setTouchModifier(modifier, enabled);
-    }
-
-    public void touchMove() {
-        mEventSenderImpl.touchMove();
-    }
-
-    public void releaseTouchPoint(int id) {
-        mEventSenderImpl.releaseTouchPoint(id);
-    }
-
-    public void touchEnd() {
-        mEventSenderImpl.touchEnd();
-    }
-
-    public void touchCancel() {
-        mEventSenderImpl.touchCancel();
-    }
-
-    public void clearTouchPoints() {
-        mEventSenderImpl.clearTouchPoints();
-    }
-
-    public void cancelTouchPoint(int id) {
-        mEventSenderImpl.cancelTouchPoint(id);
-    }
-}
\ No newline at end of file
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/EventSenderImpl.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/EventSenderImpl.java
deleted file mode 100644
index af22039..0000000
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/EventSenderImpl.java
+++ /dev/null
@@ -1,590 +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.dumprendertree2;
-
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.SystemClock;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.webkit.WebView;
-
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * An implementation of EventSender
- */
-public class EventSenderImpl {
-    private static final String LOG_TAG = "EventSenderImpl";
-
-    private static final int MSG_ENABLE_DOM_UI_EVENT_LOGGING = 0;
-    private static final int MSG_FIRE_KEYBOARD_EVENTS_TO_ELEMENT = 1;
-    private static final int MSG_LEAP_FORWARD = 2;
-
-    private static final int MSG_KEY_DOWN = 3;
-
-    private static final int MSG_MOUSE_DOWN = 4;
-    private static final int MSG_MOUSE_UP = 5;
-    private static final int MSG_MOUSE_CLICK = 6;
-    private static final int MSG_MOUSE_MOVE_TO = 7;
-
-    private static final int MSG_ADD_TOUCH_POINT = 8;
-    private static final int MSG_TOUCH_START = 9;
-    private static final int MSG_UPDATE_TOUCH_POINT = 10;
-    private static final int MSG_TOUCH_MOVE = 11;
-    private static final int MSG_CLEAR_TOUCH_POINTS = 12;
-    private static final int MSG_TOUCH_CANCEL = 13;
-    private static final int MSG_RELEASE_TOUCH_POINT = 14;
-    private static final int MSG_TOUCH_END = 15;
-    private static final int MSG_SET_TOUCH_MODIFIER = 16;
-    private static final int MSG_CANCEL_TOUCH_POINT = 17;
-
-    private static class Point {
-        private int mX;
-        private int mY;
-
-        public Point(int x, int y) {
-            mX = x;
-            mY = y;
-        }
-        public int x() {
-            return mX;
-        }
-        public int y() {
-            return mY;
-        }
-    }
-
-    private Point createViewPointFromContentCoordinates(int x, int y) {
-        return new Point(Math.round(x * mWebView.getScale()) - mWebView.getScrollX(),
-                         Math.round(y * mWebView.getScale()) - mWebView.getScrollY());
-    }
-
-    public static class TouchPoint {
-        private int mId;
-        private Point mPoint;
-        private long mDownTime;
-        private boolean mReleased = false;
-        private boolean mMoved = false;
-        private boolean mCancelled = false;
-
-        public TouchPoint(int id, Point point) {
-            mId = id;
-            mPoint = point;
-        }
-
-        public int getId() {
-          return mId;
-        }
-
-        public int getX() {
-            return mPoint.x();
-        }
-
-        public int getY() {
-            return mPoint.y();
-        }
-
-        public boolean hasMoved() {
-            return mMoved;
-        }
-
-        public void move(Point point) {
-            mPoint = point;
-            mMoved = true;
-        }
-
-        public void resetHasMoved() {
-            mMoved = false;
-        }
-
-        public long getDownTime() {
-            return mDownTime;
-        }
-
-        public void setDownTime(long downTime) {
-            mDownTime = downTime;
-        }
-
-        public boolean isReleased() {
-            return mReleased;
-        }
-
-        public void release() {
-            mReleased = true;
-        }
-
-        public boolean isCancelled() {
-            return mCancelled;
-        }
-
-        public void cancel() {
-            mCancelled = true;
-        }
-    }
-
-    private List<TouchPoint> mTouchPoints;
-    private int mTouchMetaState;
-    private Point mMousePoint;
-
-    private WebView mWebView;
-
-    private Handler mEventSenderHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            Bundle bundle;
-            MotionEvent event;
-            long ts;
-
-            switch (msg.what) {
-                case MSG_ENABLE_DOM_UI_EVENT_LOGGING:
-                    /** TODO: implement */
-                    break;
-
-                case MSG_FIRE_KEYBOARD_EVENTS_TO_ELEMENT:
-                    /** TODO: implement */
-                    break;
-
-                case MSG_LEAP_FORWARD:
-                    /** TODO: implement */
-                    break;
-
-                case MSG_KEY_DOWN:
-                    bundle = (Bundle)msg.obj;
-                    String character = bundle.getString("character");
-                    String[] withModifiers = bundle.getStringArray("withModifiers");
-
-                    if (withModifiers != null && withModifiers.length > 0) {
-                        for (int i = 0; i < withModifiers.length; i++) {
-                            executeKeyEvent(KeyEvent.ACTION_DOWN,
-                                    modifierToKeyCode(withModifiers[i]));
-                        }
-                    }
-                    executeKeyEvent(KeyEvent.ACTION_DOWN,
-                            charToKeyCode(character.toLowerCase().toCharArray()[0]));
-                    break;
-
-                /** MOUSE */
-
-                case MSG_MOUSE_DOWN:
-                    if (mMousePoint != null) {
-                        ts = SystemClock.uptimeMillis();
-                        event = MotionEvent.obtain(ts, ts, MotionEvent.ACTION_DOWN, mMousePoint.x(), mMousePoint.y(), 0);
-                        mWebView.onTouchEvent(event);
-                    }
-                    break;
-
-                case MSG_MOUSE_UP:
-                    if (mMousePoint != null) {
-                        ts = SystemClock.uptimeMillis();
-                        event = MotionEvent.obtain(ts, ts, MotionEvent.ACTION_UP, mMousePoint.x(), mMousePoint.y(), 0);
-                        mWebView.onTouchEvent(event);
-                    }
-                    break;
-
-                case MSG_MOUSE_CLICK:
-                    mouseDown();
-                    mouseUp();
-                    break;
-
-                case MSG_MOUSE_MOVE_TO:
-                    mMousePoint = createViewPointFromContentCoordinates(msg.arg1, msg.arg2);
-                    break;
-
-                /** TOUCH */
-
-                case MSG_ADD_TOUCH_POINT:
-                    int numPoints = getTouchPoints().size();
-                    int id;
-                    if (numPoints == 0) {
-                        id = 0;
-                    } else {
-                        id = getTouchPoints().get(numPoints - 1).getId() + 1;
-                    }
-                    getTouchPoints().add(
-                            new TouchPoint(id, createViewPointFromContentCoordinates(msg.arg1, msg.arg2)));
-                    break;
-
-                case MSG_TOUCH_START:
-                    if (getTouchPoints().isEmpty()) {
-                        return;
-                    }
-                    for (int i = 0; i < getTouchPoints().size(); ++i) {
-                        getTouchPoints().get(i).setDownTime(SystemClock.uptimeMillis());
-                    }
-                    executeTouchEvent(MotionEvent.ACTION_DOWN);
-                    break;
-
-                case MSG_UPDATE_TOUCH_POINT:
-                    bundle = (Bundle)msg.obj;
-
-                    int index = bundle.getInt("id");
-                    if (index >= getTouchPoints().size()) {
-                        Log.w(LOG_TAG + "::MSG_UPDATE_TOUCH_POINT", "TouchPoint out of bounds: "
-                                + index);
-                        break;
-                    }
-
-                    getTouchPoints().get(index).move(
-                            createViewPointFromContentCoordinates(bundle.getInt("x"), bundle.getInt("y")));
-                    break;
-
-                case MSG_TOUCH_MOVE:
-                    /**
-                     * FIXME: At the moment we don't support multi-touch. Hence, we only examine
-                     * the first touch point. In future this method will need rewriting.
-                     */
-                    if (getTouchPoints().isEmpty()) {
-                        return;
-                    }
-                    executeTouchEvent(MotionEvent.ACTION_MOVE);
-                    for (int i = 0; i < getTouchPoints().size(); ++i) {
-                        getTouchPoints().get(i).resetHasMoved();
-                    }
-                    break;
-
-                case MSG_CANCEL_TOUCH_POINT:
-                    if (msg.arg1 >= getTouchPoints().size()) {
-                        Log.w(LOG_TAG + "::MSG_RELEASE_TOUCH_POINT", "TouchPoint out of bounds: "
-                                + msg.arg1);
-                        break;
-                    }
-
-                    getTouchPoints().get(msg.arg1).cancel();
-                    break;
-
-                case MSG_TOUCH_CANCEL:
-                    /**
-                     * FIXME: At the moment we don't support multi-touch. Hence, we only examine
-                     * the first touch point. In future this method will need rewriting.
-                     */
-                    if (getTouchPoints().isEmpty()) {
-                        return;
-                    }
-                    executeTouchEvent(MotionEvent.ACTION_CANCEL);
-                    break;
-
-                case MSG_RELEASE_TOUCH_POINT:
-                    if (msg.arg1 >= getTouchPoints().size()) {
-                        Log.w(LOG_TAG + "::MSG_RELEASE_TOUCH_POINT", "TouchPoint out of bounds: "
-                                + msg.arg1);
-                        break;
-                    }
-
-                    getTouchPoints().get(msg.arg1).release();
-                    break;
-
-                case MSG_TOUCH_END:
-                    /**
-                     * FIXME: At the moment we don't support multi-touch. Hence, we only examine
-                     * the first touch point. In future this method will need rewriting.
-                     */
-                    if (getTouchPoints().isEmpty()) {
-                        return;
-                    }
-                    executeTouchEvent(MotionEvent.ACTION_UP);
-                    // remove released points.
-                    for (int i = getTouchPoints().size() - 1; i >= 0; --i) {
-                        if (getTouchPoints().get(i).isReleased()) {
-                            getTouchPoints().remove(i);
-                        }
-                    }
-                    break;
-
-                case MSG_SET_TOUCH_MODIFIER:
-                    bundle = (Bundle)msg.obj;
-                    String modifier = bundle.getString("modifier");
-                    boolean enabled = bundle.getBoolean("enabled");
-
-                    int mask = 0;
-                    if ("alt".equals(modifier.toLowerCase())) {
-                        mask = KeyEvent.META_ALT_ON;
-                    } else if ("shift".equals(modifier.toLowerCase())) {
-                        mask = KeyEvent.META_SHIFT_ON;
-                    } else if ("ctrl".equals(modifier.toLowerCase())) {
-                        mask = KeyEvent.META_SYM_ON;
-                    }
-
-                    if (enabled) {
-                        mTouchMetaState |= mask;
-                    } else {
-                        mTouchMetaState &= ~mask;
-                    }
-
-                    break;
-
-                case MSG_CLEAR_TOUCH_POINTS:
-                    getTouchPoints().clear();
-                    break;
-
-                default:
-                    break;
-            }
-        }
-    };
-
-    public void reset(WebView webView) {
-        mWebView = webView;
-        mTouchPoints = null;
-        mTouchMetaState = 0;
-        mMousePoint = null;
-    }
-
-    public void enableDOMUIEventLogging(int domNode) {
-        Message msg = mEventSenderHandler.obtainMessage(MSG_ENABLE_DOM_UI_EVENT_LOGGING);
-        msg.arg1 = domNode;
-        msg.sendToTarget();
-    }
-
-    public void fireKeyboardEventsToElement(int domNode) {
-        Message msg = mEventSenderHandler.obtainMessage(MSG_FIRE_KEYBOARD_EVENTS_TO_ELEMENT);
-        msg.arg1 = domNode;
-        msg.sendToTarget();
-    }
-
-    public void leapForward(int milliseconds) {
-        Message msg = mEventSenderHandler.obtainMessage(MSG_LEAP_FORWARD);
-        msg.arg1 = milliseconds;
-        msg.sendToTarget();
-    }
-
-    public void keyDown(String character, String[] withModifiers) {
-        Bundle bundle = new Bundle();
-        bundle.putString("character", character);
-        bundle.putStringArray("withModifiers", withModifiers);
-        mEventSenderHandler.obtainMessage(MSG_KEY_DOWN, bundle).sendToTarget();
-    }
-
-    /** MOUSE */
-
-    public void mouseDown() {
-        mEventSenderHandler.sendEmptyMessage(MSG_MOUSE_DOWN);
-    }
-
-    public void mouseUp() {
-        mEventSenderHandler.sendEmptyMessage(MSG_MOUSE_UP);
-    }
-
-    public void mouseClick() {
-        mEventSenderHandler.sendEmptyMessage(MSG_MOUSE_CLICK);
-    }
-
-    public void mouseMoveTo(int x, int y) {
-        mEventSenderHandler.obtainMessage(MSG_MOUSE_MOVE_TO, x, y).sendToTarget();
-    }
-
-    /** TOUCH */
-
-    public void addTouchPoint(int x, int y) {
-        mEventSenderHandler.obtainMessage(MSG_ADD_TOUCH_POINT, x, y).sendToTarget();
-    }
-
-    public void touchStart() {
-        mEventSenderHandler.sendEmptyMessage(MSG_TOUCH_START);
-    }
-
-    public void updateTouchPoint(int id, int x, int y) {
-        Bundle bundle = new Bundle();
-        bundle.putInt("id", id);
-        bundle.putInt("x", x);
-        bundle.putInt("y", y);
-        mEventSenderHandler.obtainMessage(MSG_UPDATE_TOUCH_POINT, bundle).sendToTarget();
-    }
-
-    public void touchMove() {
-        mEventSenderHandler.sendEmptyMessage(MSG_TOUCH_MOVE);
-    }
-
-    public void cancelTouchPoint(int id) {
-        Message msg = mEventSenderHandler.obtainMessage(MSG_CANCEL_TOUCH_POINT);
-        msg.arg1 = id;
-        msg.sendToTarget();
-    }
-
-    public void touchCancel() {
-        mEventSenderHandler.sendEmptyMessage(MSG_TOUCH_CANCEL);
-    }
-
-    public void releaseTouchPoint(int id) {
-        Message msg = mEventSenderHandler.obtainMessage(MSG_RELEASE_TOUCH_POINT);
-        msg.arg1 = id;
-        msg.sendToTarget();
-    }
-
-    public void touchEnd() {
-        mEventSenderHandler.sendEmptyMessage(MSG_TOUCH_END);
-    }
-
-    public void setTouchModifier(String modifier, boolean enabled) {
-        Bundle bundle = new Bundle();
-        bundle.putString("modifier", modifier);
-        bundle.putBoolean("enabled", enabled);
-        mEventSenderHandler.obtainMessage(MSG_SET_TOUCH_MODIFIER, bundle).sendToTarget();
-    }
-
-    public void clearTouchPoints() {
-        mEventSenderHandler.sendEmptyMessage(MSG_CLEAR_TOUCH_POINTS);
-    }
-
-    private List<TouchPoint> getTouchPoints() {
-        if (mTouchPoints == null) {
-            mTouchPoints = new LinkedList<TouchPoint>();
-        }
-
-        return mTouchPoints;
-    }
-
-    private void executeTouchEvent(int action) {
-        int numPoints = getTouchPoints().size();
-        int[] pointerIds = new int[numPoints];
-        MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[numPoints];
-
-        for (int i = 0; i < numPoints; ++i) {
-            boolean isNeeded = false;
-            switch(action) {
-            case MotionEvent.ACTION_DOWN:
-            case MotionEvent.ACTION_UP:
-                isNeeded = true;
-                break;
-            case MotionEvent.ACTION_MOVE:
-                isNeeded = getTouchPoints().get(i).hasMoved();
-                break;
-            case MotionEvent.ACTION_CANCEL:
-                isNeeded = getTouchPoints().get(i).isCancelled();
-                break;
-            default:
-                Log.w(LOG_TAG + "::executeTouchEvent(),", "action not supported:" + action);
-                break;
-            }
-
-            numPoints = 0;
-            if (isNeeded) {
-                pointerIds[numPoints] = getTouchPoints().get(i).getId();
-                pointerCoords[numPoints] = new MotionEvent.PointerCoords();
-                pointerCoords[numPoints].x = getTouchPoints().get(i).getX();
-                pointerCoords[numPoints].y = getTouchPoints().get(i).getY();
-                ++numPoints;
-            }
-        }
-
-        if (numPoints == 0) {
-            return;
-        }
-
-        MotionEvent event = MotionEvent.obtain(mTouchPoints.get(0).getDownTime(),
-                SystemClock.uptimeMillis(), action,
-                numPoints, pointerIds, pointerCoords,
-                mTouchMetaState, 1.0f, 1.0f, 0, 0, 0, 0);
-
-        mWebView.onTouchEvent(event);
-    }
-
-    private void executeKeyEvent(int action, int keyCode) {
-        KeyEvent event = new KeyEvent(action, keyCode);
-        mWebView.onKeyDown(event.getKeyCode(), event);
-    }
-
-    /**
-     * Assumes lowercase chars, case needs to be handled by calling function.
-     */
-    private static int charToKeyCode(char c) {
-        // handle numbers
-        if (c >= '0' && c <= '9') {
-            int offset = c - '0';
-            return KeyEvent.KEYCODE_0 + offset;
-        }
-
-        // handle characters
-        if (c >= 'a' && c <= 'z') {
-            int offset = c - 'a';
-            return KeyEvent.KEYCODE_A + offset;
-        }
-
-        // handle all others
-        switch (c) {
-            case '*':
-                return KeyEvent.KEYCODE_STAR;
-
-            case '#':
-                return KeyEvent.KEYCODE_POUND;
-
-            case ',':
-                return KeyEvent.KEYCODE_COMMA;
-
-            case '.':
-                return KeyEvent.KEYCODE_PERIOD;
-
-            case '\t':
-                return KeyEvent.KEYCODE_TAB;
-
-            case ' ':
-                return KeyEvent.KEYCODE_SPACE;
-
-            case '\n':
-                return KeyEvent.KEYCODE_ENTER;
-
-            case '\b':
-            case 0x7F:
-                return KeyEvent.KEYCODE_DEL;
-
-            case '~':
-                return KeyEvent.KEYCODE_GRAVE;
-
-            case '-':
-                return KeyEvent.KEYCODE_MINUS;
-
-            case '=':
-                return KeyEvent.KEYCODE_EQUALS;
-
-            case '(':
-                return KeyEvent.KEYCODE_LEFT_BRACKET;
-
-            case ')':
-                return KeyEvent.KEYCODE_RIGHT_BRACKET;
-
-            case '\\':
-                return KeyEvent.KEYCODE_BACKSLASH;
-
-            case ';':
-                return KeyEvent.KEYCODE_SEMICOLON;
-
-            case '\'':
-                return KeyEvent.KEYCODE_APOSTROPHE;
-
-            case '/':
-                return KeyEvent.KEYCODE_SLASH;
-
-            default:
-                return c;
-        }
-    }
-
-    private static int modifierToKeyCode(String modifier) {
-        if (modifier.equals("ctrlKey")) {
-            return KeyEvent.KEYCODE_ALT_LEFT;
-        } else if (modifier.equals("shiftKey")) {
-            return KeyEvent.KEYCODE_SHIFT_LEFT;
-        } else if (modifier.equals("altKey")) {
-            return KeyEvent.KEYCODE_SYM;
-        }
-
-        return KeyEvent.KEYCODE_UNKNOWN;
-    }
-}
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/FileFilter.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/FileFilter.java
deleted file mode 100644
index 5360e3d..0000000
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/FileFilter.java
+++ /dev/null
@@ -1,313 +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.dumprendertree2;
-
-import android.util.Log;
-
-import com.android.dumprendertree2.forwarder.ForwarderManager;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.StringReader;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * A utility to filter out some files/directories from the views and tests that run.
- */
-public class FileFilter {
-    private static final String LOG_TAG = "FileFilter";
-
-    private static final String TEST_EXPECTATIONS_TXT_PATH =
-            "platform/android/test_expectations.txt";
-
-    private static final String HTTP_TESTS_PATH = "http/tests/";
-    private static final String SSL_PATH = "ssl/";
-
-    private static final String TOKEN_CRASH = "CRASH";
-    private static final String TOKEN_FAIL = "FAIL";
-    private static final String TOKEN_SLOW = "SLOW";
-
-    private final Set<String> mCrashList = new HashSet<String>();
-    private final Set<String> mFailList = new HashSet<String>();
-    private final Set<String> mSlowList = new HashSet<String>();
-
-    public FileFilter() {
-        loadTestExpectations();
-    }
-
-    private static final String trimTrailingSlashIfPresent(String path) {
-        File file = new File(path);
-        return file.getPath();
-    }
-
-    public void loadTestExpectations() {
-        URL url = null;
-        try {
-            url = new URL(ForwarderManager.getHostSchemePort(false) +
-                    "LayoutTests/" + TEST_EXPECTATIONS_TXT_PATH);
-        } catch (MalformedURLException e) {
-            assert false;
-        }
-
-        try {
-            InputStream inputStream = null;
-            BufferedReader bufferedReader = null;
-            try {
-                byte[] httpAnswer = FsUtils.readDataFromUrl(url);
-                if (httpAnswer == null) {
-                    Log.w(LOG_TAG, "loadTestExpectations(): File not found: " +
-                            TEST_EXPECTATIONS_TXT_PATH);
-                    return;
-                }
-                bufferedReader = new BufferedReader(new StringReader(
-                        new String(httpAnswer)));
-                String line;
-                String entry;
-                String[] parts;
-                String path;
-                Set<String> tokens;
-                while (true) {
-                    line = bufferedReader.readLine();
-                    if (line == null) {
-                        break;
-                    }
-
-                    /** Remove the comment and trim */
-                    entry = line.split("//", 2)[0].trim();
-
-                    /** Omit empty lines, advance to next line */
-                    if (entry.isEmpty()) {
-                        continue;
-                    }
-
-                    /** Split on whitespace into path part and the rest */
-                    parts = entry.split("\\s", 2);
-
-                    /** At this point parts.length >= 1 */
-                    if (parts.length == 1) {
-                        Log.w(LOG_TAG + "::reloadConfiguration",
-                                "There are no options specified for the test!");
-                        continue;
-                    }
-
-                    path = trimTrailingSlashIfPresent(parts[0]);
-
-                    /** Split on whitespace */
-                    tokens = new HashSet<String>(Arrays.asList(
-                            parts[1].split("\\s", 0)));
-
-                    /** Chose the right collections to add to */
-                    if (tokens.contains(TOKEN_CRASH)) {
-                        mCrashList.add(path);
-
-                        /** If test is on skip list we ignore any further options */
-                        continue;
-                    }
-
-                    if (tokens.contains(TOKEN_FAIL)) {
-                        mFailList.add(path);
-                    }
-                    if (tokens.contains(TOKEN_SLOW)) {
-                        mSlowList.add(path);
-                    }
-                }
-            } finally {
-                if (inputStream != null) {
-                    inputStream.close();
-                }
-                if (bufferedReader != null) {
-                    bufferedReader.close();
-                }
-            }
-        } catch (IOException e) {
-            Log.e(LOG_TAG, "url=" + url, e);
-        }
-    }
-
-    /**
-     * Checks if test is expected to crash.
-     *
-     * <p>
-     * Path given should relative within LayoutTests folder, e.g. fast/dom/foo.html
-     *
-     * @param testPath
-     *            - a relative path within LayoutTests folder
-     * @return if the test is supposed to be skipped
-     */
-    public boolean isCrash(String testPath) {
-        for (String prefix : getPrefixes(testPath)) {
-            if (mCrashList.contains(prefix)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Checks if test result is supposed to be "failed".
-     *
-     * <p>
-     * Path given should relative within LayoutTests folder, e.g. fast/dom/foo.html
-     *
-     * @param testPath
-     *            - a relative path within LayoutTests folder
-     * @return if the test result is supposed to be "failed"
-     */
-    public boolean isFail(String testPath) {
-        for (String prefix : getPrefixes(testPath)) {
-            if (mFailList.contains(prefix)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Checks if test is slow and should have timeout increased.
-     *
-     * <p>
-     * Path given should relative within LayoutTests folder, e.g. fast/dom/foo.html
-     *
-     * @param testPath
-     *            - a relative path within LayoutTests folder
-     * @return if the test is slow and should have timeout increased.
-     */
-    public boolean isSlow(String testPath) {
-        for (String prefix : getPrefixes(testPath)) {
-            if (mSlowList.contains(prefix)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Returns the list of all path prefixes of the given path.
-     *
-     * <p>
-     * e.g. this/is/a/path returns the list: this this/is this/is/a this/is/a/path
-     *
-     * @param path
-     * @return the list of all path prefixes of the given path.
-     */
-    private static List<String> getPrefixes(String path) {
-        File file = new File(path);
-        List<String> prefixes = new ArrayList<String>(8);
-
-        do {
-            prefixes.add(file.getPath());
-            file = file.getParentFile();
-        } while (file != null);
-
-        return prefixes;
-    }
-
-    /**
-     * Checks if the directory may contain tests or contains just helper files.
-     *
-     * @param dirName
-     * @return
-     *      if the directory may contain tests
-     */
-    public static boolean isTestDir(String dirName) {
-        return (!dirName.equals("script-tests")
-                && !dirName.equals("resources") && !dirName.startsWith("."));
-    }
-
-    /**
-     * Checks if the file is a test.
-     * Currently we run .html, .xhtml and .php tests.
-     *
-     * @warning You MUST also call isTestDir() on the parent directory before
-     * assuming that a file is a test.
-     *
-     * @param testName
-     * @return if the file is a test
-     */
-    public static boolean isTestFile(String testName) {
-        return testName.endsWith(".html")
-            || testName.endsWith(".xhtml")
-            || testName.endsWith(".php");
-    }
-
-    /**
-     * Return a URL of the test on the server.
-     *
-     * @param relativePath
-     * @param allowHttps Whether to allow the use of HTTPS, even if the file is in the SSL
-     *     directory.
-     * @return a URL of the test on the server
-     */
-    public static URL getUrl(String relativePath, boolean allowHttps) {
-        String urlBase = ForwarderManager.getHostSchemePort(false);
-
-        /**
-         * URL is formed differently for HTTP vs non-HTTP tests, because HTTP tests
-         * expect different document root. See run_apache2.py and .conf file for details
-         */
-        if (relativePath.startsWith(HTTP_TESTS_PATH)) {
-            relativePath = relativePath.substring(HTTP_TESTS_PATH.length());
-            if (relativePath.startsWith(SSL_PATH) && allowHttps) {
-                urlBase = ForwarderManager.getHostSchemePort(true);
-            }
-        } else {
-            relativePath = "LayoutTests/" + relativePath;
-        }
-
-        try {
-            return new URL(urlBase + relativePath);
-        } catch (MalformedURLException e) {
-            Log.e(LOG_TAG, "Malformed URL!", e);
-        }
-
-        return null;
-    }
-
-    /**
-     * If the path contains extension (e.g .foo at the end of the file) then it changes
-     * this (.foo) into newEnding (so it has to contain the dot if we want to preserve it).
-     *
-     * <p>If the path doesn't contain an extension, it adds the ending to the path.
-     *
-     * @param relativePath
-     * @param newEnding
-     * @return
-     *      a new path, containing the newExtension
-     */
-    public static String setPathEnding(String relativePath, String newEnding) {
-        int dotPos = relativePath.lastIndexOf('.');
-        if (dotPos == -1) {
-            return relativePath + newEnding;
-        }
-
-        return relativePath.substring(0, dotPos) + newEnding;
-    }
-}
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/FsUtils.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/FsUtils.java
deleted file mode 100644
index 54cbfda..0000000
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/FsUtils.java
+++ /dev/null
@@ -1,314 +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.dumprendertree2;
-
-import android.util.Log;
-
-import com.android.dumprendertree2.forwarder.ForwarderManager;
-
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.ResponseHandler;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.conn.ClientConnectionManager;
-import org.apache.http.conn.scheme.PlainSocketFactory;
-import org.apache.http.conn.scheme.Scheme;
-import org.apache.http.conn.scheme.SchemeRegistry;
-import org.apache.http.conn.ssl.SSLSocketFactory;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.HttpConnectionParams;
-import org.apache.http.params.HttpParams;
-import org.apache.http.util.EntityUtils;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.net.MalformedURLException;
-import java.net.SocketTimeoutException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- *
- */
-public class FsUtils {
-    public static final String LOG_TAG = "FsUtils";
-
-    private static final String SCRIPT_URL = ForwarderManager.getHostSchemePort(false) +
-            "Tools/DumpRenderTree/android/get_layout_tests_dir_contents.php";
-
-    private static final int HTTP_TIMEOUT_MS = 5000;
-
-    private static HttpClient sHttpClient;
-
-    private static HttpClient getHttpClient() {
-        if (sHttpClient == null) {
-            HttpParams params = new BasicHttpParams();
-
-            SchemeRegistry schemeRegistry = new SchemeRegistry();
-            schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(),
-                    ForwarderManager.HTTP_PORT));
-            schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(),
-                    ForwarderManager.HTTPS_PORT));
-
-            ClientConnectionManager connectionManager = new ThreadSafeClientConnManager(params,
-                    schemeRegistry);
-            sHttpClient = new DefaultHttpClient(connectionManager, params);
-            HttpConnectionParams.setSoTimeout(sHttpClient.getParams(), HTTP_TIMEOUT_MS);
-            HttpConnectionParams.setConnectionTimeout(sHttpClient.getParams(), HTTP_TIMEOUT_MS);
-        }
-        return sHttpClient;
-    }
-
-    public static void writeDataToStorage(File file, byte[] bytes, boolean append) {
-        Log.d(LOG_TAG, "writeDataToStorage(): " + file.getAbsolutePath());
-        try {
-            OutputStream outputStream = null;
-            try {
-                file.getParentFile().mkdirs();
-                file.createNewFile();
-                Log.d(LOG_TAG, "writeDataToStorage(): File created: " + file.getAbsolutePath());
-                outputStream = new FileOutputStream(file, append);
-                outputStream.write(bytes);
-            } finally {
-                if (outputStream != null) {
-                    outputStream.close();
-                }
-            }
-        } catch (IOException e) {
-            Log.e(LOG_TAG, "file.getAbsolutePath=" + file.getAbsolutePath() + " append=" + append,
-                    e);
-        }
-    }
-
-    public static byte[] readDataFromStorage(File file) {
-        if (!file.exists()) {
-            Log.d(LOG_TAG, "readDataFromStorage(): File does not exist: "
-                    + file.getAbsolutePath());
-            return null;
-        }
-
-        byte[] bytes = null;
-        try {
-            FileInputStream fis = null;
-            try {
-                fis = new FileInputStream(file);
-                bytes = new byte[(int)file.length()];
-                fis.read(bytes);
-            } finally {
-                if (fis != null) {
-                    fis.close();
-                }
-            }
-        } catch (IOException e) {
-            Log.e(LOG_TAG, "file.getAbsolutePath=" + file.getAbsolutePath(), e);
-        }
-
-        return bytes;
-    }
-
-    static class UrlDataGetter extends Thread {
-        private URL mUrl;
-        private byte[] mBytes;
-        private boolean mGetComplete;
-        public UrlDataGetter(URL url) {
-            mUrl = url;
-        }
-        public byte[] get() {
-            start();
-            synchronized(this) {
-                while (!mGetComplete) {
-                    try{
-                        wait();
-                    } catch(InterruptedException e) {
-                    }
-                }
-            }
-            return mBytes;
-        }
-        public synchronized void run() {
-            mGetComplete = false;
-            HttpGet httpRequest = new HttpGet(mUrl.toString());
-            ResponseHandler<byte[]> handler = new ResponseHandler<byte[]>() {
-                @Override
-                public byte[] handleResponse(HttpResponse response) throws IOException {
-                    if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
-                        return null;
-                    }
-                    HttpEntity entity = response.getEntity();
-                    return (entity == null ? null : EntityUtils.toByteArray(entity));
-                }
-            };
-
-            mBytes = null;
-            try {
-                /**
-                 * TODO: Not exactly sure why some requests hang indefinitely, but adding this
-                 * timeout (in static getter for http client) in loop helps.
-                 */
-                boolean timedOut;
-                do {
-                    timedOut = false;
-                    try {
-                        mBytes = getHttpClient().execute(httpRequest, handler);
-                    } catch (SocketTimeoutException e) {
-                        timedOut = true;
-                        Log.w(LOG_TAG, "Expected SocketTimeoutException: " + mUrl, e);
-                    }
-                } while (timedOut);
-            } catch (IOException e) {
-                Log.e(LOG_TAG, "url=" + mUrl, e);
-            }
-
-            mGetComplete = true;
-            notify();
-        }
-    }
-
-    public static byte[] readDataFromUrl(URL url) {
-        if (url == null) {
-            Log.w(LOG_TAG, "readDataFromUrl(): url is null!");
-            return null;
-        }
-
-        UrlDataGetter getter = new UrlDataGetter(url);
-        return getter.get();
-    }
-
-    public static List<String> getLayoutTestsDirContents(String dirRelativePath, boolean recurse,
-            boolean mode) {
-        String modeString = (mode ? "folders" : "files");
-
-        URL url = null;
-        try {
-            url = new URL(SCRIPT_URL +
-                    "?path=" + dirRelativePath +
-                    "&recurse=" + recurse +
-                    "&mode=" + modeString);
-        } catch (MalformedURLException e) {
-            Log.e(LOG_TAG, "path=" + dirRelativePath + " recurse=" + recurse + " mode=" +
-                    modeString, e);
-            return new LinkedList<String>();
-        }
-
-        HttpGet httpRequest = new HttpGet(url.toString());
-        ResponseHandler<LinkedList<String>> handler = new ResponseHandler<LinkedList<String>>() {
-            @Override
-            public LinkedList<String> handleResponse(HttpResponse response)
-                    throws IOException {
-                LinkedList<String> lines = new LinkedList<String>();
-
-                if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
-                    return lines;
-                }
-                HttpEntity entity = response.getEntity();
-                if (entity == null) {
-                    return lines;
-                }
-
-                BufferedReader reader =
-                        new BufferedReader(new InputStreamReader(entity.getContent()));
-                String line;
-                try {
-                    while ((line = reader.readLine()) != null) {
-                        lines.add(line);
-                    }
-                } finally {
-                    if (reader != null) {
-                        reader.close();
-                    }
-                }
-
-                return lines;
-            }
-        };
-
-        try {
-            return getHttpClient().execute(httpRequest, handler);
-        } catch (IOException e) {
-            Log.e(LOG_TAG, "getLayoutTestsDirContents(): HTTP GET failed for URL " + url);
-            return null;
-        }
-    }
-
-    public static void closeInputStream(InputStream inputStream) {
-        try {
-            if (inputStream != null) {
-                inputStream.close();
-            }
-        } catch (IOException e) {
-            Log.e(LOG_TAG, "Couldn't close stream!", e);
-        }
-    }
-
-    public static void closeOutputStream(OutputStream outputStream) {
-        try {
-            if (outputStream != null) {
-                outputStream.close();
-            }
-        } catch (IOException e) {
-            Log.e(LOG_TAG, "Couldn't close stream!", e);
-        }
-    }
-
-    public static List<String> loadTestListFromStorage(String path) {
-        List<String> list = new ArrayList<String>();
-        if (path != null && !path.isEmpty()) {
-            try {
-                File file = new File(path);
-                Log.d(LOG_TAG, "test list loaded from " + path);
-                BufferedReader reader = new BufferedReader(new FileReader(file));
-                String line = null;
-                while ((line = reader.readLine()) != null) {
-                    list.add(line);
-                }
-                reader.close();
-            } catch (IOException ioe) {
-                Log.e(LOG_TAG, "failed to load test list", ioe);
-            }
-        }
-        return list;
-    }
-
-    public static void saveTestListToStorage(File file, int start, List<String> testList) {
-        try {
-            BufferedWriter writer = new BufferedWriter(
-                    new FileWriter(file));
-            for (String line : testList.subList(start, testList.size())) {
-                writer.write(line + '\n');
-            }
-            writer.flush();
-            writer.close();
-        } catch (IOException e) {
-            Log.e(LOG_TAG, "failed to write test list", e);
-        }
-    }
-}
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestController.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestController.java
deleted file mode 100644
index c9c35ce..0000000
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestController.java
+++ /dev/null
@@ -1,116 +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.dumprendertree2;
-
-import android.net.Uri;
-import android.util.Log;
-import android.webkit.MockGeolocation;
-import android.webkit.WebStorage;
-
-import java.io.File;
-
-/**
- * A class that is registered as JS interface for webview in LayoutTestExecutor
- */
-public class LayoutTestController {
-    private static final String LOG_TAG = "LayoutTestController";
-
-    LayoutTestsExecutor mLayoutTestsExecutor;
-
-    public LayoutTestController(LayoutTestsExecutor layoutTestsExecutor) {
-        mLayoutTestsExecutor = layoutTestsExecutor;
-    }
-
-    public void clearAllDatabases() {
-        Log.i(LOG_TAG, "clearAllDatabases() called");
-        WebStorage.getInstance().deleteAllData();
-    }
-
-    public void dumpAsText() {
-        dumpAsText(false);
-    }
-
-    public void dumpAsText(boolean enablePixelTest) {
-        mLayoutTestsExecutor.dumpAsText(enablePixelTest);
-    }
-
-    public void dumpChildFramesAsText() {
-        mLayoutTestsExecutor.dumpChildFramesAsText();
-    }
-
-    public void dumpDatabaseCallbacks() {
-        mLayoutTestsExecutor.dumpDatabaseCallbacks();
-    }
-
-    public void notifyDone() {
-        mLayoutTestsExecutor.notifyDone();
-    }
-
-    public void overridePreference(String key, boolean value) {
-        mLayoutTestsExecutor.overridePreference(key, value);
-    }
-
-    public void setAppCacheMaximumSize(long size) {
-        Log.i(LOG_TAG, "setAppCacheMaximumSize() called with: " + size);
-        android.webkit.WebStorageClassic.getInstance().setAppCacheMaximumSize(size);
-    }
-
-    public void setCanOpenWindows() {
-        mLayoutTestsExecutor.setCanOpenWindows();
-    }
-
-    public void setDatabaseQuota(long quota) {
-        /** TODO: Reset this before every test! */
-        Log.i(LOG_TAG, "setDatabaseQuota() called with: " + quota);
-        WebStorage.getInstance().setQuotaForOrigin(Uri.fromFile(new File("")).toString(),
-                quota);
-    }
-
-    public void setMockGeolocationPosition(double latitude, double longitude, double accuracy) {
-        Log.i(LOG_TAG, "setMockGeolocationPosition(): " + "latitude=" + latitude +
-                " longitude=" + longitude + " accuracy=" + accuracy);
-        mLayoutTestsExecutor.setMockGeolocationPosition(latitude, longitude, accuracy);
-    }
-
-    public void setMockGeolocationError(int code, String message) {
-        Log.i(LOG_TAG, "setMockGeolocationError(): " + "code=" + code + " message=" + message);
-        mLayoutTestsExecutor.setMockGeolocationError(code, message);
-    }
-
-    public void setGeolocationPermission(boolean allow) {
-        mLayoutTestsExecutor.setGeolocationPermission(allow);
-    }
-
-    public void setMockDeviceOrientation(boolean canProvideAlpha, double alpha,
-            boolean canProvideBeta, double beta, boolean canProvideGamma, double gamma) {
-        // Configuration is in WebKit, so stay on WebCore thread, but go via LayoutTestsExecutor
-        // as we need access to the Webview.
-        Log.i(LOG_TAG, "setMockDeviceOrientation(" + canProvideAlpha +
-                ", " + alpha + ", " + canProvideBeta + ", " + beta + ", " + canProvideGamma +
-                ", " + gamma + ")");
-        mLayoutTestsExecutor.setMockDeviceOrientation(
-                canProvideAlpha, alpha, canProvideBeta, beta, canProvideGamma, gamma);
-    }
-
-    public void setXSSAuditorEnabled(boolean flag) {
-        mLayoutTestsExecutor.setXSSAuditorEnabled(flag);
-    }
-
-    public void waitUntilDone() {
-        mLayoutTestsExecutor.waitUntilDone();
-    }
-}
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java
deleted file mode 100644
index 25ac700..0000000
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java
+++ /dev/null
@@ -1,732 +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.dumprendertree2;
-
-import android.app.Activity;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.net.http.SslError;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.PowerManager;
-import android.os.PowerManager.WakeLock;
-import android.os.Process;
-import android.os.RemoteException;
-import android.util.Log;
-import android.view.Window;
-import android.webkit.ConsoleMessage;
-import android.webkit.GeolocationPermissions;
-import android.webkit.HttpAuthHandler;
-import android.webkit.JsPromptResult;
-import android.webkit.JsResult;
-import android.webkit.SslErrorHandler;
-import android.webkit.WebChromeClient;
-import android.webkit.WebSettings;
-import android.webkit.WebSettingsClassic;
-import android.webkit.WebStorage;
-import android.webkit.WebStorage.QuotaUpdater;
-import android.webkit.WebView;
-import android.webkit.WebViewClassic;
-import android.webkit.WebViewClient;
-
-import java.lang.Thread.UncaughtExceptionHandler;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-/**
- * This activity executes the test. It contains WebView and logic of LayoutTestController
- * functions. It runs in a separate process and sends the results of running the test
- * to ManagerService. The reason why is to handle crashing (test that crashes brings down
- * whole process with it).
- */
-public class LayoutTestsExecutor extends Activity {
-
-    private enum CurrentState {
-        IDLE,
-        RENDERING_PAGE,
-        WAITING_FOR_ASYNCHRONOUS_TEST,
-        OBTAINING_RESULT;
-
-        public boolean isRunningState() {
-            return this == CurrentState.RENDERING_PAGE ||
-                    this == CurrentState.WAITING_FOR_ASYNCHRONOUS_TEST;
-        }
-    }
-
-    private static final String LOG_TAG = "LayoutTestsExecutor";
-
-    public static final String EXTRA_TESTS_FILE = "TestsList";
-    public static final String EXTRA_TEST_INDEX = "TestIndex";
-
-    private static final int MSG_ACTUAL_RESULT_OBTAINED = 0;
-    private static final int MSG_TEST_TIMED_OUT = 1;
-
-    private static final int DEFAULT_TIME_OUT_MS = 15 * 1000;
-
-    /** A list of tests that remain to run since last crash */
-    private List<String> mTestsList;
-
-    /**
-     * This is a number of currently running test. It is 0-based and doesn't reset after
-     * the crash. Initial index is passed to LayoutTestsExecuter in the intent that starts
-     * it.
-     */
-    private int mCurrentTestIndex;
-
-    /** The total number of tests to run, doesn't reset after crash */
-    private int mTotalTestCount;
-
-    private WebView mCurrentWebView;
-    private String mCurrentTestRelativePath;
-    private String mCurrentTestUri;
-    private CurrentState mCurrentState = CurrentState.IDLE;
-
-    private boolean mCurrentTestTimedOut;
-    private AbstractResult mCurrentResult;
-    private AdditionalTextOutput mCurrentAdditionalTextOutput;
-
-    private LayoutTestController mLayoutTestController = new LayoutTestController(this);
-    private boolean mCanOpenWindows;
-    private boolean mDumpDatabaseCallbacks;
-
-    private EventSender mEventSender = new EventSender();
-
-    private WakeLock mScreenDimLock;
-
-    /** COMMUNICATION WITH ManagerService */
-
-    private Messenger mManagerServiceMessenger;
-
-    private ServiceConnection mServiceConnection = new ServiceConnection() {
-
-        @Override
-        public void onServiceConnected(ComponentName name, IBinder service) {
-            mManagerServiceMessenger = new Messenger(service);
-            startTests();
-        }
-
-        @Override
-        public void onServiceDisconnected(ComponentName name) {
-            /** TODO */
-        }
-    };
-
-    private final Handler mResultHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_ACTUAL_RESULT_OBTAINED:
-                    onActualResultsObtained();
-                    break;
-
-                case MSG_TEST_TIMED_OUT:
-                    onTestTimedOut();
-                    break;
-
-                default:
-                    break;
-            }
-        }
-    };
-
-    /** WEBVIEW CONFIGURATION */
-
-    private WebViewClient mWebViewClient = new WebViewClient() {
-        @Override
-        public void onPageFinished(WebView view, String url) {
-            /** Some tests fire up many page loads, we don't want to detect them */
-            if (!url.equals(mCurrentTestUri)) {
-                return;
-            }
-
-            if (mCurrentState == CurrentState.RENDERING_PAGE) {
-                onTestFinished();
-            }
-        }
-
-         @Override
-         public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler,
-                 String host, String realm) {
-             if (handler.useHttpAuthUsernamePassword() && view != null) {
-                 String[] credentials = view.getHttpAuthUsernamePassword(host, realm);
-                 if (credentials != null && credentials.length == 2) {
-                     handler.proceed(credentials[0], credentials[1]);
-                     return;
-                 }
-             }
-             handler.cancel();
-         }
-
-         @Override
-         public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
-             // We ignore SSL errors. In particular, the certificate used by the LayoutTests server
-             // produces an error as it lacks a CN field.
-             handler.proceed();
-         }
-    };
-
-    private WebChromeClient mWebChromeClient = new WebChromeClient() {
-        @Override
-        public void onExceededDatabaseQuota(String url, String databaseIdentifier,
-                long currentQuota, long estimatedSize, long totalUsedQuota,
-                QuotaUpdater quotaUpdater) {
-            /** TODO: This should be recorded as part of the text result */
-            /** TODO: The quota should also probably be reset somehow for every test? */
-            if (mDumpDatabaseCallbacks) {
-                getCurrentAdditionalTextOutput().appendExceededDbQuotaMessage(url,
-                        databaseIdentifier);
-            }
-            quotaUpdater.updateQuota(currentQuota + 5 * 1024 * 1024);
-        }
-
-        @Override
-        public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
-            getCurrentAdditionalTextOutput().appendJsAlert(message);
-            result.confirm();
-            return true;
-        }
-
-        @Override
-        public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
-            getCurrentAdditionalTextOutput().appendJsConfirm(message);
-            result.confirm();
-            return true;
-        }
-
-        @Override
-        public boolean onJsPrompt(WebView view, String url, String message, String defaultValue,
-                JsPromptResult result) {
-            getCurrentAdditionalTextOutput().appendJsPrompt(message, defaultValue);
-            result.confirm();
-            return true;
-        }
-
-        @Override
-        public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
-            getCurrentAdditionalTextOutput().appendConsoleMessage(consoleMessage);
-            return true;
-        }
-
-        @Override
-        public boolean onCreateWindow(WebView view, boolean dialog, boolean userGesture,
-                Message resultMsg) {
-            WebView.WebViewTransport transport = (WebView.WebViewTransport)resultMsg.obj;
-            /** By default windows cannot be opened, so just send null back. */
-            WebView newWindowWebView = null;
-
-            if (mCanOpenWindows) {
-                /**
-                 * We never display the new window, just create the view and allow it's content to
-                 * execute and be recorded by the executor.
-                 */
-                newWindowWebView = createWebViewWithJavascriptInterfaces();
-                setupWebView(newWindowWebView);
-            }
-
-            transport.setWebView(newWindowWebView);
-            resultMsg.sendToTarget();
-            return true;
-        }
-
-        @Override
-        public void onGeolocationPermissionsShowPrompt(String origin,
-                GeolocationPermissions.Callback callback) {
-            throw new RuntimeException(
-                    "The WebCore mock used by DRT should bypass the usual permissions flow.");
-        }
-    };
-
-    /** IMPLEMENTATION */
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        /**
-         * It detects the crash by catching all the uncaught exceptions. However, we
-         * still have to kill the process, because after catching the exception the
-         * activity remains in a strange state, where intents don't revive it.
-         * However, we send the message to the service to speed up the rebooting
-         * (we don't have to wait for time-out to kick in).
-         */
-        Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
-            @Override
-            public void uncaughtException(Thread thread, Throwable e) {
-                Log.w(LOG_TAG,
-                        "onTestCrashed(): " + mCurrentTestRelativePath + " thread=" + thread, e);
-
-                try {
-                    Message serviceMsg =
-                            Message.obtain(null, ManagerService.MSG_CURRENT_TEST_CRASHED);
-
-                    mManagerServiceMessenger.send(serviceMsg);
-                } catch (RemoteException e2) {
-                    Log.e(LOG_TAG, "mCurrentTestRelativePath=" + mCurrentTestRelativePath, e2);
-                }
-
-                Process.killProcess(Process.myPid());
-            }
-        });
-
-        requestWindowFeature(Window.FEATURE_PROGRESS);
-
-        Intent intent = getIntent();
-        mTestsList = FsUtils.loadTestListFromStorage(intent.getStringExtra(EXTRA_TESTS_FILE));
-        mCurrentTestIndex = intent.getIntExtra(EXTRA_TEST_INDEX, -1);
-        mTotalTestCount = mCurrentTestIndex + mTestsList.size();
-
-        PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
-        mScreenDimLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK
-                | PowerManager.ON_AFTER_RELEASE, "WakeLock in LayoutTester");
-        mScreenDimLock.acquire();
-
-        bindService(new Intent(this, ManagerService.class), mServiceConnection,
-                Context.BIND_AUTO_CREATE);
-    }
-
-    private void reset() {
-        WebView previousWebView = mCurrentWebView;
-
-        resetLayoutTestController();
-
-        mCurrentTestTimedOut = false;
-        mCurrentResult = null;
-        mCurrentAdditionalTextOutput = null;
-
-        mCurrentWebView = createWebViewWithJavascriptInterfaces();
-        // When we create the first WebView, we need to pause to wait for the WebView thread to spin
-        // and up and for it to register its message handlers.
-        if (previousWebView == null) {
-            try {
-                Thread.currentThread().sleep(1000);
-            } catch (Exception e) {}
-        }
-        setupWebView(mCurrentWebView);
-
-        mEventSender.reset(mCurrentWebView);
-
-        setContentView(mCurrentWebView);
-        if (previousWebView != null) {
-            Log.d(LOG_TAG + "::reset", "previousWebView != null");
-            previousWebView.destroy();
-        }
-    }
-
-    private static class WebViewWithJavascriptInterfaces extends WebView {
-        public WebViewWithJavascriptInterfaces(
-                Context context, Map<String, Object> javascriptInterfaces) {
-            super(context,
-                  null, // attribute set
-                  0, // default style resource ID
-                  javascriptInterfaces,
-                  false); // is private browsing
-        }
-    }
-    private WebView createWebViewWithJavascriptInterfaces() {
-        Map<String, Object> javascriptInterfaces = new HashMap<String, Object>();
-        javascriptInterfaces.put("layoutTestController", mLayoutTestController);
-        javascriptInterfaces.put("eventSender", mEventSender);
-        return new WebViewWithJavascriptInterfaces(this, javascriptInterfaces);
-    }
-
-    private void setupWebView(WebView webView) {
-        webView.setWebViewClient(mWebViewClient);
-        webView.setWebChromeClient(mWebChromeClient);
-
-        /**
-         * Setting a touch interval of -1 effectively disables the optimisation in WebView
-         * that stops repeated touch events flooding WebCore. The Event Sender only sends a
-         * single event rather than a stream of events (like what would generally happen in
-         * a real use of touch events in a WebView)  and so if the WebView drops the event,
-         * the test will fail as the test expects one callback for every touch it synthesizes.
-         */
-        WebViewClassic webViewClassic = WebViewClassic.fromWebView(webView);
-        webViewClassic.setTouchInterval(-1);
-
-        webViewClassic.clearCache(true);
-
-        WebSettingsClassic webViewSettings = webViewClassic.getSettings();
-        webViewSettings.setAppCacheEnabled(true);
-        webViewSettings.setAppCachePath(getApplicationContext().getCacheDir().getPath());
-        // Use of larger values causes unexplained AppCache database corruption.
-        // TODO: Investigate what's really going on here.
-        webViewSettings.setAppCacheMaxSize(100 * 1024 * 1024);
-        webViewSettings.setJavaScriptEnabled(true);
-        webViewSettings.setJavaScriptCanOpenWindowsAutomatically(true);
-        webViewSettings.setSupportMultipleWindows(true);
-        webViewSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);
-        webViewSettings.setDatabaseEnabled(true);
-        webViewSettings.setDatabasePath(getDir("databases", 0).getAbsolutePath());
-        webViewSettings.setDomStorageEnabled(true);
-        webViewSettings.setWorkersEnabled(false);
-        webViewSettings.setXSSAuditorEnabled(false);
-        webViewSettings.setPageCacheCapacity(0);
-
-        // This is asynchronous, but it gets processed by WebCore before it starts loading pages.
-        WebViewClassic.fromWebView(mCurrentWebView).setUseMockGeolocation();
-        WebViewClassic.fromWebView(mCurrentWebView).setUseMockDeviceOrientation();
-
-        // Must do this after setting the AppCache path.
-        WebStorage.getInstance().deleteAllData();
-    }
-
-    private void startTests() {
-        // This is called when the tests are started and after each crash.
-        // We only send the reset message in the former case.
-        if (mCurrentTestIndex <= 0) {
-            sendResetMessage();
-        }
-        if (mCurrentTestIndex == 0) {
-            sendFirstTestMessage();
-        }
-
-        runNextTest();
-    }
-
-    private void sendResetMessage() {
-        try {
-            Message serviceMsg = Message.obtain(null, ManagerService.MSG_RESET);
-            mManagerServiceMessenger.send(serviceMsg);
-        } catch (RemoteException e) {
-            Log.e(LOG_TAG, "Error sending message to manager service:", e);
-        }
-    }
-
-    private void sendFirstTestMessage() {
-        try {
-            Message serviceMsg = Message.obtain(null, ManagerService.MSG_FIRST_TEST);
-
-            Bundle bundle = new Bundle();
-            bundle.putString("firstTest", mTestsList.get(0));
-            bundle.putInt("index", mCurrentTestIndex);
-
-            serviceMsg.setData(bundle);
-            mManagerServiceMessenger.send(serviceMsg);
-        } catch (RemoteException e) {
-            Log.e(LOG_TAG, "Error sending message to manager service:", e);
-        }
-    }
-
-    private void runNextTest() {
-        assert mCurrentState == CurrentState.IDLE : "mCurrentState = " + mCurrentState.name();
-
-        if (mTestsList.isEmpty()) {
-            onAllTestsFinished();
-            return;
-        }
-
-        mCurrentTestRelativePath = mTestsList.remove(0);
-
-        Log.i(LOG_TAG, "runNextTest(): Start: " + mCurrentTestRelativePath +
-                " (" + mCurrentTestIndex + ")");
-
-        mCurrentTestUri = FileFilter.getUrl(mCurrentTestRelativePath, true).toString();
-
-        reset();
-
-        /** Start time-out countdown and the test */
-        mCurrentState = CurrentState.RENDERING_PAGE;
-        mResultHandler.sendEmptyMessageDelayed(MSG_TEST_TIMED_OUT, DEFAULT_TIME_OUT_MS);
-        mCurrentWebView.loadUrl(mCurrentTestUri);
-    }
-
-    private void onTestTimedOut() {
-        assert mCurrentState.isRunningState() : "mCurrentState = " + mCurrentState.name();
-
-        Log.w(LOG_TAG, "onTestTimedOut(): " + mCurrentTestRelativePath);
-        mCurrentTestTimedOut = true;
-
-        /**
-         * While it is theoretically possible that the test times out because
-         * of webview becoming unresponsive, it is very unlikely. Therefore it's
-         * assumed that obtaining results (that calls various webview methods)
-         * will not itself hang.
-         */
-        obtainActualResultsFromWebView();
-    }
-
-    private void onTestFinished() {
-        assert mCurrentState.isRunningState() : "mCurrentState = " + mCurrentState.name();
-
-        Log.i(LOG_TAG, "onTestFinished(): " + mCurrentTestRelativePath);
-        mResultHandler.removeMessages(MSG_TEST_TIMED_OUT);
-        obtainActualResultsFromWebView();
-    }
-
-    private void obtainActualResultsFromWebView() {
-        /**
-         * If the result has not been set by the time the test finishes we create
-         * a default type of result.
-         */
-        if (mCurrentResult == null) {
-            /** TODO: Default type should be RenderTreeResult. We don't support it now. */
-            mCurrentResult = new TextResult(mCurrentTestRelativePath);
-        }
-
-        mCurrentState = CurrentState.OBTAINING_RESULT;
-
-        if (mCurrentTestTimedOut) {
-            mCurrentResult.setDidTimeOut();
-        }
-        mCurrentResult.obtainActualResults(mCurrentWebView,
-                mResultHandler.obtainMessage(MSG_ACTUAL_RESULT_OBTAINED));
-    }
-
-    private void onActualResultsObtained() {
-        assert mCurrentState == CurrentState.OBTAINING_RESULT
-                : "mCurrentState = " + mCurrentState.name();
-
-        Log.i(LOG_TAG, "onActualResultsObtained(): " + mCurrentTestRelativePath);
-        mCurrentState = CurrentState.IDLE;
-
-        reportResultToService();
-        mCurrentTestIndex++;
-        updateProgressBar();
-        runNextTest();
-    }
-
-    private void reportResultToService() {
-        if (mCurrentAdditionalTextOutput != null) {
-            mCurrentResult.setAdditionalTextOutputString(mCurrentAdditionalTextOutput.toString());
-        }
-
-        try {
-            Message serviceMsg =
-                    Message.obtain(null, ManagerService.MSG_PROCESS_ACTUAL_RESULTS);
-
-            Bundle bundle = mCurrentResult.getBundle();
-            bundle.putInt("testIndex", mCurrentTestIndex);
-            if (!mTestsList.isEmpty()) {
-                bundle.putString("nextTest", mTestsList.get(0));
-            }
-
-            serviceMsg.setData(bundle);
-            mManagerServiceMessenger.send(serviceMsg);
-        } catch (RemoteException e) {
-            Log.e(LOG_TAG, "mCurrentTestRelativePath=" + mCurrentTestRelativePath, e);
-        }
-    }
-
-    private void updateProgressBar() {
-        getWindow().setFeatureInt(Window.FEATURE_PROGRESS,
-                mCurrentTestIndex * Window.PROGRESS_END / mTotalTestCount);
-        setTitle(mCurrentTestIndex * 100 / mTotalTestCount + "% " +
-                "(" + mCurrentTestIndex + "/" + mTotalTestCount + ")");
-    }
-
-    private void onAllTestsFinished() {
-        mScreenDimLock.release();
-
-        try {
-            Message serviceMsg =
-                    Message.obtain(null, ManagerService.MSG_ALL_TESTS_FINISHED);
-            mManagerServiceMessenger.send(serviceMsg);
-        } catch (RemoteException e) {
-            Log.e(LOG_TAG, "mCurrentTestRelativePath=" + mCurrentTestRelativePath, e);
-        }
-
-        unbindService(mServiceConnection);
-    }
-
-    private AdditionalTextOutput getCurrentAdditionalTextOutput() {
-        if (mCurrentAdditionalTextOutput == null) {
-            mCurrentAdditionalTextOutput = new AdditionalTextOutput();
-        }
-        return mCurrentAdditionalTextOutput;
-    }
-
-    /** LAYOUT TEST CONTROLLER */
-
-    private static final int MSG_WAIT_UNTIL_DONE = 0;
-    private static final int MSG_NOTIFY_DONE = 1;
-    private static final int MSG_DUMP_AS_TEXT = 2;
-    private static final int MSG_DUMP_CHILD_FRAMES_AS_TEXT = 3;
-    private static final int MSG_SET_CAN_OPEN_WINDOWS = 4;
-    private static final int MSG_DUMP_DATABASE_CALLBACKS = 5;
-    private static final int MSG_OVERRIDE_PREFERENCE = 6;
-    private static final int MSG_SET_XSS_AUDITOR_ENABLED = 7;
-
-    /** String constants for use with layoutTestController.overridePreference() */
-    private final String WEBKIT_OFFLINE_WEB_APPLICATION_CACHE_ENABLED =
-            "WebKitOfflineWebApplicationCacheEnabled";
-    private final String WEBKIT_USES_PAGE_CACHE_PREFERENCE_KEY = "WebKitUsesPageCachePreferenceKey";
-
-    Handler mLayoutTestControllerHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            assert mCurrentState.isRunningState() : "mCurrentState = " + mCurrentState.name();
-
-            switch (msg.what) {
-                case MSG_DUMP_AS_TEXT:
-                    if (mCurrentResult == null) {
-                        mCurrentResult = new TextResult(mCurrentTestRelativePath);
-                    }
-                    assert mCurrentResult instanceof TextResult
-                            : "mCurrentResult instanceof" + mCurrentResult.getClass().getName();
-                    break;
-
-                case MSG_DUMP_CHILD_FRAMES_AS_TEXT:
-                    /** If dumpAsText was not called we assume that the result should be text */
-                    if (mCurrentResult == null) {
-                        mCurrentResult = new TextResult(mCurrentTestRelativePath);
-                    }
-
-                    assert mCurrentResult instanceof TextResult
-                            : "mCurrentResult instanceof" + mCurrentResult.getClass().getName();
-
-                    ((TextResult)mCurrentResult).setDumpChildFramesAsText(true);
-                    break;
-
-                case MSG_DUMP_DATABASE_CALLBACKS:
-                    mDumpDatabaseCallbacks = true;
-                    break;
-
-                case MSG_NOTIFY_DONE:
-                    if (mCurrentState == CurrentState.WAITING_FOR_ASYNCHRONOUS_TEST) {
-                        onTestFinished();
-                    }
-                    break;
-
-                case MSG_OVERRIDE_PREFERENCE:
-                    /**
-                     * TODO: We should look up the correct WebView for the frame which
-                     * called the layoutTestController method. Currently, we just use the
-                     * WebView for the main frame. EventSender suffers from the same
-                     * problem.
-                     */
-                    String key = msg.getData().getString("key");
-                    boolean value = msg.getData().getBoolean("value");
-                    if (WEBKIT_OFFLINE_WEB_APPLICATION_CACHE_ENABLED.equals(key)) {
-                        WebViewClassic.fromWebView(mCurrentWebView).getSettings().
-                                setAppCacheEnabled(value);
-                    } else if (WEBKIT_USES_PAGE_CACHE_PREFERENCE_KEY.equals(key)) {
-                        // Cache the maximum possible number of pages.
-                        WebViewClassic.fromWebView(mCurrentWebView).getSettings().
-                                setPageCacheCapacity(Integer.MAX_VALUE);
-                    } else {
-                        Log.w(LOG_TAG, "LayoutTestController.overridePreference(): " +
-                              "Unsupported preference '" + key + "'");
-                    }
-                    break;
-
-                case MSG_SET_CAN_OPEN_WINDOWS:
-                    mCanOpenWindows = true;
-                    break;
-
-                case MSG_SET_XSS_AUDITOR_ENABLED:
-                    WebViewClassic.fromWebView(mCurrentWebView).getSettings().
-                            setXSSAuditorEnabled(msg.arg1 == 1);
-                    break;
-
-                case MSG_WAIT_UNTIL_DONE:
-                    mCurrentState = CurrentState.WAITING_FOR_ASYNCHRONOUS_TEST;
-                    break;
-
-                default:
-                    assert false : "msg.what=" + msg.what;
-                    break;
-            }
-        }
-    };
-
-    private void resetLayoutTestController() {
-        mCanOpenWindows = false;
-        mDumpDatabaseCallbacks = false;
-    }
-
-    public void dumpAsText(boolean enablePixelTest) {
-        Log.i(LOG_TAG, mCurrentTestRelativePath + ": dumpAsText(" + enablePixelTest + ") called");
-        /** TODO: Implement */
-        if (enablePixelTest) {
-            Log.w(LOG_TAG, "enablePixelTest not implemented, switching to false");
-        }
-        mLayoutTestControllerHandler.sendEmptyMessage(MSG_DUMP_AS_TEXT);
-    }
-
-    public void dumpChildFramesAsText() {
-        Log.i(LOG_TAG, mCurrentTestRelativePath + ": dumpChildFramesAsText() called");
-        mLayoutTestControllerHandler.sendEmptyMessage(MSG_DUMP_CHILD_FRAMES_AS_TEXT);
-    }
-
-    public void dumpDatabaseCallbacks() {
-        Log.i(LOG_TAG, mCurrentTestRelativePath + ": dumpDatabaseCallbacks() called");
-        mLayoutTestControllerHandler.sendEmptyMessage(MSG_DUMP_DATABASE_CALLBACKS);
-    }
-
-    public void notifyDone() {
-        Log.i(LOG_TAG, mCurrentTestRelativePath + ": notifyDone() called");
-        mLayoutTestControllerHandler.sendEmptyMessage(MSG_NOTIFY_DONE);
-    }
-
-    public void overridePreference(String key, boolean value) {
-        Log.i(LOG_TAG, mCurrentTestRelativePath + ": overridePreference(" + key + ", " + value +
-        ") called");
-        Message msg = mLayoutTestControllerHandler.obtainMessage(MSG_OVERRIDE_PREFERENCE);
-        msg.getData().putString("key", key);
-        msg.getData().putBoolean("value", value);
-        msg.sendToTarget();
-    }
-
-    public void setCanOpenWindows() {
-        Log.i(LOG_TAG, mCurrentTestRelativePath + ": setCanOpenWindows() called");
-        mLayoutTestControllerHandler.sendEmptyMessage(MSG_SET_CAN_OPEN_WINDOWS);
-    }
-
-    public void setMockGeolocationPosition(double latitude, double longitude, double accuracy) {
-        WebViewClassic.fromWebView(mCurrentWebView).setMockGeolocationPosition(latitude, longitude,
-                accuracy);
-    }
-
-    public void setMockGeolocationError(int code, String message) {
-        WebViewClassic.fromWebView(mCurrentWebView).setMockGeolocationError(code, message);
-    }
-
-    public void setGeolocationPermission(boolean allow) {
-        Log.i(LOG_TAG, mCurrentTestRelativePath + ": setGeolocationPermission(" + allow +
-                ") called");
-        WebViewClassic.fromWebView(mCurrentWebView).setMockGeolocationPermission(allow);
-    }
-
-    public void setMockDeviceOrientation(boolean canProvideAlpha, double alpha,
-            boolean canProvideBeta, double beta, boolean canProvideGamma, double gamma) {
-        Log.i(LOG_TAG, mCurrentTestRelativePath + ": setMockDeviceOrientation(" + canProvideAlpha +
-                ", " + alpha + ", " + canProvideBeta + ", " + beta + ", " + canProvideGamma +
-                ", " + gamma + ")");
-        WebViewClassic.fromWebView(mCurrentWebView).setMockDeviceOrientation(canProvideAlpha,
-                alpha, canProvideBeta, beta, canProvideGamma, gamma);
-    }
-
-    public void setXSSAuditorEnabled(boolean flag) {
-        Log.i(LOG_TAG, mCurrentTestRelativePath + ": setXSSAuditorEnabled(" + flag + ") called");
-        Message msg = mLayoutTestControllerHandler.obtainMessage(MSG_SET_XSS_AUDITOR_ENABLED);
-        msg.arg1 = flag ? 1 : 0;
-        msg.sendToTarget();
-    }
-
-    public void waitUntilDone() {
-        Log.i(LOG_TAG, mCurrentTestRelativePath + ": waitUntilDone() called");
-        mLayoutTestControllerHandler.sendEmptyMessage(MSG_WAIT_UNTIL_DONE);
-    }
-
-}
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/ManagerService.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/ManagerService.java
deleted file mode 100644
index 4783cc7..0000000
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/ManagerService.java
+++ /dev/null
@@ -1,293 +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.dumprendertree2;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Environment;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.Messenger;
-import android.util.Log;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A service that handles managing the results of tests, informing of crashes, generating
- * summaries, etc.
- */
-public class ManagerService extends Service {
-
-    private static final String LOG_TAG = "ManagerService";
-
-    private static final int MSG_CRASH_TIMEOUT_EXPIRED = 0;
-    private static final int MSG_SUMMARIZER_DONE = 1;
-
-    private static final int CRASH_TIMEOUT_MS = 20 * 1000;
-
-    /** TODO: make it a setting */
-    static final String RESULTS_ROOT_DIR_PATH =
-            Environment.getExternalStorageDirectory() + File.separator + "layout-test-results";
-
-    /** TODO: Make it a setting */
-    private static final List<String> EXPECTED_RESULT_LOCATION_RELATIVE_DIR_PREFIXES =
-            new ArrayList<String>(3);
-    {
-        EXPECTED_RESULT_LOCATION_RELATIVE_DIR_PREFIXES.add("platform" + File.separator +
-                "android-v8" + File.separator);
-        EXPECTED_RESULT_LOCATION_RELATIVE_DIR_PREFIXES.add("platform" + File.separator +
-                "android" + File.separator);
-        EXPECTED_RESULT_LOCATION_RELATIVE_DIR_PREFIXES.add("");
-    }
-
-    /** TODO: Make these settings */
-    private static final String TEXT_RESULT_EXTENSION = "txt";
-    private static final String IMAGE_RESULT_EXTENSION = "png";
-
-    static final int MSG_PROCESS_ACTUAL_RESULTS = 0;
-    static final int MSG_ALL_TESTS_FINISHED = 1;
-    static final int MSG_FIRST_TEST = 2;
-    static final int MSG_CURRENT_TEST_CRASHED = 3;
-    static final int MSG_RESET = 4;
-
-    /**
-     * This handler is purely for IPC. It is used to create mMessenger
-     * that generates a binder returned in onBind method.
-     */
-    private Handler mIncomingHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_RESET:
-                    mSummarizer.reset();
-                    break;
-
-                case MSG_FIRST_TEST:
-                    Bundle bundle = msg.getData();
-                    ensureNextTestSetup(bundle.getString("firstTest"), bundle.getInt("index"));
-                    break;
-
-                case MSG_PROCESS_ACTUAL_RESULTS:
-                    Log.d(LOG_TAG,"mIncomingHandler: " + msg.getData().getString("relativePath"));
-                    onActualResultsObtained(msg.getData());
-                    break;
-
-                case MSG_CURRENT_TEST_CRASHED:
-                    mInternalMessagesHandler.removeMessages(MSG_CRASH_TIMEOUT_EXPIRED);
-                    onTestCrashed();
-                    break;
-
-                case MSG_ALL_TESTS_FINISHED:
-                    /** We run it in a separate thread to avoid ANR */
-                    new Thread() {
-                        @Override
-                        public void run() {
-                            mSummarizer.setTestsRelativePath(mAllTestsRelativePath);
-                            Message msg = Message.obtain(mInternalMessagesHandler,
-                                    MSG_SUMMARIZER_DONE);
-                            mSummarizer.summarize(msg);
-                        }
-                    }.start();
-            }
-        }
-    };
-
-    private Messenger mMessenger = new Messenger(mIncomingHandler);
-
-    private Handler mInternalMessagesHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_CRASH_TIMEOUT_EXPIRED:
-                    onTestCrashed();
-                    break;
-
-                case MSG_SUMMARIZER_DONE:
-                    Intent intent = new Intent(ManagerService.this, TestsListActivity.class);
-                    intent.setAction(Intent.ACTION_SHUTDOWN);
-                    /** This flag is needed because we send the intent from the service */
-                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                    startActivity(intent);
-                    break;
-            }
-        }
-    };
-
-    private Summarizer mSummarizer;
-
-    private String mCurrentlyRunningTest;
-    private int mCurrentlyRunningTestIndex;
-
-    /**
-     * These are implementation details of getExpectedResultPath() used to reduce the number
-     * of requests required to the host server.
-     */
-    private String mLastExpectedResultPathRequested;
-    private String mLastExpectedResultPathFetched;
-
-    private String mAllTestsRelativePath;
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-
-        mSummarizer = new Summarizer(RESULTS_ROOT_DIR_PATH, getApplicationContext());
-    }
-
-    @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        mAllTestsRelativePath = intent.getStringExtra("path");
-        assert mAllTestsRelativePath != null;
-        return START_STICKY;
-    }
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        return mMessenger.getBinder();
-    }
-
-    private void onActualResultsObtained(Bundle bundle) {
-        mInternalMessagesHandler.removeMessages(MSG_CRASH_TIMEOUT_EXPIRED);
-        ensureNextTestSetup(bundle.getString("nextTest"), bundle.getInt("testIndex") + 1);
-
-        AbstractResult results =
-                AbstractResult.TestType.valueOf(bundle.getString("type")).createResult(bundle);
-
-        Log.i(LOG_TAG, "onActualResultObtained: " + results.getRelativePath());
-        handleResults(results);
-    }
-
-    private void ensureNextTestSetup(String nextTest, int index) {
-        if (nextTest == null) {
-            Log.w(LOG_TAG, "ensureNextTestSetup(): nextTest=null");
-            return;
-        }
-
-        mCurrentlyRunningTest = nextTest;
-        mCurrentlyRunningTestIndex = index;
-        mInternalMessagesHandler.sendEmptyMessageDelayed(MSG_CRASH_TIMEOUT_EXPIRED, CRASH_TIMEOUT_MS);
-    }
-
-    /**
-     * This sends an intent to TestsListActivity to restart LayoutTestsExecutor.
-     * The more detailed description of the flow is in the comment of onNewIntent
-     * method in TestsListActivity.
-     */
-    private void onTestCrashed() {
-        handleResults(new CrashedDummyResult(mCurrentlyRunningTest));
-
-        Log.w(LOG_TAG, "onTestCrashed(): " + mCurrentlyRunningTest +
-                " (" + mCurrentlyRunningTestIndex + ")");
-
-        Intent intent = new Intent(this, TestsListActivity.class);
-        intent.setAction(Intent.ACTION_REBOOT);
-        /** This flag is needed because we send the intent from the service */
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        intent.putExtra("crashedTestIndex", mCurrentlyRunningTestIndex);
-        startActivity(intent);
-    }
-
-    private void handleResults(AbstractResult results) {
-        String relativePath = results.getRelativePath();
-        results.setExpectedTextResult(getExpectedTextResult(relativePath));
-        results.setExpectedTextResultPath(getExpectedTextResultPath(relativePath));
-        results.setExpectedImageResult(getExpectedImageResult(relativePath));
-        results.setExpectedImageResultPath(getExpectedImageResultPath(relativePath));
-
-        dumpActualTextResult(results);
-        dumpActualImageResult(results);
-
-        mSummarizer.appendTest(results);
-    }
-
-    private void dumpActualTextResult(AbstractResult result) {
-        String testPath = result.getRelativePath();
-        String actualTextResult = result.getActualTextResult();
-        if (actualTextResult == null) {
-            return;
-        }
-
-        String resultPath = FileFilter.setPathEnding(testPath, "-actual." + TEXT_RESULT_EXTENSION);
-        FsUtils.writeDataToStorage(new File(RESULTS_ROOT_DIR_PATH, resultPath),
-                actualTextResult.getBytes(), false);
-    }
-
-    private void dumpActualImageResult(AbstractResult result) {
-        String testPath = result.getRelativePath();
-        byte[] actualImageResult = result.getActualImageResult();
-        if (actualImageResult == null) {
-            return;
-        }
-
-        String resultPath = FileFilter.setPathEnding(testPath,
-                "-actual." + IMAGE_RESULT_EXTENSION);
-        FsUtils.writeDataToStorage(new File(RESULTS_ROOT_DIR_PATH, resultPath),
-                actualImageResult, false);
-    }
-
-    public String getExpectedTextResult(String relativePath) {
-        byte[] result = getExpectedResult(relativePath, TEXT_RESULT_EXTENSION);
-        if (result != null) {
-            return new String(result);
-        }
-        return null;
-    }
-
-    public byte[] getExpectedImageResult(String relativePath) {
-        return getExpectedResult(relativePath, IMAGE_RESULT_EXTENSION);
-    }
-
-    private byte[] getExpectedResult(String relativePath, String extension) {
-        String originalRelativePath =
-                FileFilter.setPathEnding(relativePath, "-expected." + extension);
-        mLastExpectedResultPathRequested = originalRelativePath;
-
-        byte[] bytes = null;
-        List<String> locations = EXPECTED_RESULT_LOCATION_RELATIVE_DIR_PREFIXES;
-
-        int size = EXPECTED_RESULT_LOCATION_RELATIVE_DIR_PREFIXES.size();
-        for (int i = 0; bytes == null && i < size; i++) {
-            relativePath = locations.get(i) + originalRelativePath;
-            bytes = FsUtils.readDataFromUrl(FileFilter.getUrl(relativePath, false));
-        }
-
-        mLastExpectedResultPathFetched = bytes == null ? null : relativePath;
-        return bytes;
-    }
-
-    private String getExpectedTextResultPath(String relativePath) {
-        return getExpectedResultPath(relativePath, TEXT_RESULT_EXTENSION);
-    }
-
-    private String getExpectedImageResultPath(String relativePath) {
-        return getExpectedResultPath(relativePath, IMAGE_RESULT_EXTENSION);
-    }
-
-    private String getExpectedResultPath(String relativePath, String extension) {
-        String originalRelativePath =
-            FileFilter.setPathEnding(relativePath, "-expected." + extension);
-        if (!originalRelativePath.equals(mLastExpectedResultPathRequested)) {
-            getExpectedResult(relativePath, extension);
-        }
-
-        return mLastExpectedResultPathFetched;
-    }
-}
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/Summarizer.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/Summarizer.java
deleted file mode 100644
index bae8e6b..0000000
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/Summarizer.java
+++ /dev/null
@@ -1,578 +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.dumprendertree2;
-
-import android.content.Context;
-import android.content.res.AssetManager;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.os.Build;
-import android.os.Message;
-import android.util.DisplayMetrics;
-import android.util.Log;
-
-import com.android.dumprendertree2.forwarder.ForwarderManager;
-
-import java.io.File;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URL;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * A class that collects information about tests that ran and can create HTML
- * files with summaries and easy navigation.
- */
-public class Summarizer {
-
-    private static final String LOG_TAG = "Summarizer";
-
-    private static final String CSS =
-            "<style type=\"text/css\">" +
-            "* {" +
-            "       font-family: Verdana;" +
-            "       border: 0;" +
-            "       margin: 0;" +
-            "       padding: 0;}" +
-            "body {" +
-            "       margin: 10px;}" +
-            "h1 {" +
-            "       font-size: 24px;" +
-            "       margin: 4px 0 4px 0;}" +
-            "h2 {" +
-            "       font-size:18px;" +
-            "       text-transform: uppercase;" +
-            "       margin: 20px 0 3px 0;}" +
-            "h3, h3 a {" +
-            "       font-size: 14px;" +
-            "       color: black;" +
-            "       text-decoration: none;" +
-            "       margin-top: 4px;" +
-            "       margin-bottom: 2px;}" +
-            "h3 a span.path {" +
-            "       text-decoration: underline;}" +
-            "h3 span.tri {" +
-            "       text-decoration: none;" +
-            "       float: left;" +
-            "       width: 20px;}" +
-            "h3 span.sqr {" +
-            "       text-decoration: none;" +
-            "       float: left;" +
-            "       width: 20px;}" +
-            "h3 span.sqr_pass {" +
-            "       color: #8ee100;}" +
-            "h3 span.sqr_fail {" +
-            "       color: #c30000;}" +
-            "span.source {" +
-            "       display: block;" +
-            "       font-size: 10px;" +
-            "       color: #888;" +
-            "       margin-left: 20px;" +
-            "       margin-bottom: 1px;}" +
-            "span.source a {" +
-            "       font-size: 10px;" +
-            "       color: #888;}" +
-            "h3 img {" +
-            "       width: 8px;" +
-            "       margin-right: 4px;}" +
-            "div.diff {" +
-            "       margin-bottom: 25px;}" +
-            "div.diff a {" +
-            "       font-size: 12px;" +
-            "       color: #888;}" +
-            "table.visual_diff {" +
-            "       border-bottom: 0px solid;" +
-            "       border-collapse: collapse;" +
-            "       width: 100%;" +
-            "       margin-bottom: 2px;}" +
-            "table.visual_diff tr.headers td {" +
-            "       border-bottom: 1px solid;" +
-            "       border-top: 0;" +
-            "       padding-bottom: 3px;}" +
-            "table.visual_diff tr.results td {" +
-            "       border-top: 1px dashed;" +
-            "       border-right: 1px solid;" +
-            "       font-size: 15px;" +
-            "       vertical-align: top;}" +
-            "table.visual_diff tr.results td.line_count {" +
-            "       background-color:#aaa;" +
-            "       min-width:20px;" +
-            "       text-align: right;" +
-            "       border-right: 1px solid;" +
-            "       border-left: 1px solid;" +
-            "       padding: 2px 1px 2px 0px;}" +
-            "table.visual_diff tr.results td.line {" +
-            "       padding: 2px 0px 2px 4px;" +
-            "       border-right: 1px solid;" +
-            "       width: 49.8%;}" +
-            "table.visual_diff tr.footers td {" +
-            "       border-top: 1px solid;" +
-            "       border-bottom: 0;}" +
-            "table.visual_diff tr td.space {" +
-            "       border: 0;" +
-            "       width: 0.4%}" +
-            "div.space {" +
-            "       margin-top:4px;}" +
-            "span.eql {" +
-            "       background-color: #f3f3f3;}" +
-            "span.del {" +
-            "       background-color: #ff8888; }" +
-            "span.ins {" +
-            "       background-color: #88ff88; }" +
-            "table.summary {" +
-            "       border: 1px solid black;" +
-            "       margin-top: 20px;}" +
-            "table.summary td {" +
-            "       padding: 3px;}" +
-            "span.listItem {" +
-            "       font-size: 11px;" +
-            "       font-weight: normal;" +
-            "       text-transform: uppercase;" +
-            "       padding: 3px;" +
-            "       -webkit-border-radius: 4px;}" +
-            "span." + AbstractResult.ResultCode.RESULTS_DIFFER.name() + "{" +
-            "       background-color: #ccc;" +
-            "       color: black;}" +
-            "span." + AbstractResult.ResultCode.NO_EXPECTED_RESULT.name() + "{" +
-            "       background-color: #a700e4;" +
-            "       color: #fff;}" +
-            "span.timed_out {" +
-            "       background-color: #f3cb00;" +
-            "       color: black;}" +
-            "span.crashed {" +
-            "       background-color: #c30000;" +
-            "       color: #fff;}" +
-            "span.noLtc {" +
-            "       background-color: #944000;" +
-            "       color: #fff;}" +
-            "span.noEventSender {" +
-            "       background-color: #815600;" +
-            "       color: #fff;}" +
-            "</style>";
-
-    private static final String SCRIPT =
-            "<script type=\"text/javascript\">" +
-            "    function toggleDisplay(id) {" +
-            "        element = document.getElementById(id);" +
-            "        triangle = document.getElementById('tri.' + id);" +
-            "        if (element.style.display == 'none') {" +
-            "            element.style.display = 'inline';" +
-            "            triangle.innerHTML = '&#x25bc; ';" +
-            "        } else {" +
-            "            element.style.display = 'none';" +
-            "            triangle.innerHTML = '&#x25b6; ';" +
-            "        }" +
-            "    }" +
-            "</script>";
-
-    /** TODO: Make it a setting */
-    private static final String HTML_DETAILS_RELATIVE_PATH = "details.html";
-    private static final String TXT_SUMMARY_RELATIVE_PATH = "summary.txt";
-
-    private static final int RESULTS_PER_DUMP = 500;
-    private static final int RESULTS_PER_DB_ACCESS = 50;
-
-    private int mCrashedTestsCount = 0;
-    private List<AbstractResult> mUnexpectedFailures = new ArrayList<AbstractResult>();
-    private List<AbstractResult> mExpectedFailures = new ArrayList<AbstractResult>();
-    private List<AbstractResult> mExpectedPasses = new ArrayList<AbstractResult>();
-    private List<AbstractResult> mUnexpectedPasses = new ArrayList<AbstractResult>();
-
-    private Cursor mUnexpectedFailuresCursor;
-    private Cursor mExpectedFailuresCursor;
-    private Cursor mUnexpectedPassesCursor;
-    private Cursor mExpectedPassesCursor;
-
-    private FileFilter mFileFilter;
-    private String mResultsRootDirPath;
-    private String mTestsRelativePath;
-    private Date mDate;
-
-    private int mResultsSinceLastHtmlDump = 0;
-    private int mResultsSinceLastDbAccess = 0;
-
-    private SummarizerDBHelper mDbHelper;
-
-    public Summarizer(String resultsRootDirPath, Context context) {
-        mFileFilter = new FileFilter();
-        mResultsRootDirPath = resultsRootDirPath;
-
-        /**
-         * We don't run the database I/O in a separate thread to avoid consumer/producer problem
-         * and to simplify code.
-         */
-        mDbHelper = new SummarizerDBHelper(context);
-        mDbHelper.open();
-    }
-
-    public static URI getDetailsUri() {
-        return new File(ManagerService.RESULTS_ROOT_DIR_PATH + File.separator +
-                HTML_DETAILS_RELATIVE_PATH).toURI();
-    }
-
-    public void appendTest(AbstractResult result) {
-        String relativePath = result.getRelativePath();
-
-        if (result.didCrash()) {
-            mCrashedTestsCount++;
-        }
-
-        if (result.didPass()) {
-            result.clearResults();
-            if (mFileFilter.isFail(relativePath)) {
-                mUnexpectedPasses.add(result);
-            } else {
-                mExpectedPasses.add(result);
-            }
-        } else {
-            if (mFileFilter.isFail(relativePath)) {
-                mExpectedFailures.add(result);
-            } else {
-                mUnexpectedFailures.add(result);
-            }
-        }
-
-        if (++mResultsSinceLastDbAccess == RESULTS_PER_DB_ACCESS) {
-            persistLists();
-            clearLists();
-        }
-    }
-
-    private void clearLists() {
-        mUnexpectedFailures.clear();
-        mExpectedFailures.clear();
-        mUnexpectedPasses.clear();
-        mExpectedPasses.clear();
-    }
-
-    private void persistLists() {
-        persistListToTable(mUnexpectedFailures, SummarizerDBHelper.UNEXPECTED_FAILURES_TABLE);
-        persistListToTable(mExpectedFailures, SummarizerDBHelper.EXPECTED_FAILURES_TABLE);
-        persistListToTable(mUnexpectedPasses, SummarizerDBHelper.UNEXPECTED_PASSES_TABLE);
-        persistListToTable(mExpectedPasses, SummarizerDBHelper.EXPECTED_PASSES_TABLE);
-        mResultsSinceLastDbAccess = 0;
-    }
-
-    private void persistListToTable(List<AbstractResult> results, String table) {
-        for (AbstractResult abstractResult : results) {
-            mDbHelper.insertAbstractResult(abstractResult, table);
-        }
-    }
-
-    public void setTestsRelativePath(String testsRelativePath) {
-        mTestsRelativePath = testsRelativePath;
-    }
-
-    public void summarize(Message onFinishMessage) {
-        persistLists();
-        clearLists();
-
-        mUnexpectedFailuresCursor =
-            mDbHelper.getAbstractResults(SummarizerDBHelper.UNEXPECTED_FAILURES_TABLE);
-        mUnexpectedPassesCursor =
-            mDbHelper.getAbstractResults(SummarizerDBHelper.UNEXPECTED_PASSES_TABLE);
-        mExpectedFailuresCursor =
-            mDbHelper.getAbstractResults(SummarizerDBHelper.EXPECTED_FAILURES_TABLE);
-        mExpectedPassesCursor =
-            mDbHelper.getAbstractResults(SummarizerDBHelper.EXPECTED_PASSES_TABLE);
-
-        String webKitRevision = getWebKitRevision();
-        createHtmlDetails(webKitRevision);
-        createTxtSummary(webKitRevision);
-
-        clearLists();
-        mUnexpectedFailuresCursor.close();
-        mUnexpectedPassesCursor.close();
-        mExpectedFailuresCursor.close();
-        mExpectedPassesCursor.close();
-
-        onFinishMessage.sendToTarget();
-    }
-
-    public void reset() {
-        mCrashedTestsCount = 0;
-        clearLists();
-        mDbHelper.reset();
-        mDate = new Date();
-    }
-
-    private void dumpHtmlToFile(StringBuilder html, boolean append) {
-        FsUtils.writeDataToStorage(new File(mResultsRootDirPath, HTML_DETAILS_RELATIVE_PATH),
-                html.toString().getBytes(), append);
-        html.setLength(0);
-        mResultsSinceLastHtmlDump = 0;
-    }
-
-    private void createTxtSummary(String webKitRevision) {
-        StringBuilder txt = new StringBuilder();
-
-        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
-        txt.append("Path: " + mTestsRelativePath + "\n");
-        txt.append("Date: " + dateFormat.format(mDate) + "\n");
-        txt.append("Build fingerprint: " + Build.FINGERPRINT + "\n");
-        txt.append("WebKit version: " + getWebKitVersionFromUserAgentString() + "\n");
-        txt.append("WebKit revision: " + webKitRevision + "\n");
-
-        txt.append("TOTAL:                     " + getTotalTestCount() + "\n");
-        txt.append("CRASHED (among all tests): " + mCrashedTestsCount + "\n");
-        txt.append("UNEXPECTED FAILURES:       " + mUnexpectedFailuresCursor.getCount() + "\n");
-        txt.append("UNEXPECTED PASSES:         " + mUnexpectedPassesCursor.getCount() + "\n");
-        txt.append("EXPECTED FAILURES:         " + mExpectedFailuresCursor.getCount() + "\n");
-        txt.append("EXPECTED PASSES:           " + mExpectedPassesCursor.getCount() + "\n");
-
-        FsUtils.writeDataToStorage(new File(mResultsRootDirPath, TXT_SUMMARY_RELATIVE_PATH),
-                txt.toString().getBytes(), false);
-    }
-
-    private void createHtmlDetails(String webKitRevision) {
-        StringBuilder html = new StringBuilder();
-
-        html.append("<html><head>");
-        html.append(CSS);
-        html.append(SCRIPT);
-        html.append("</head><body>");
-
-        createTopSummaryTable(webKitRevision, html);
-        dumpHtmlToFile(html, false);
-
-        createResultsList(html, "Unexpected failures", mUnexpectedFailuresCursor);
-        createResultsList(html, "Unexpected passes", mUnexpectedPassesCursor);
-        createResultsList(html, "Expected failures", mExpectedFailuresCursor);
-        createResultsList(html, "Expected passes", mExpectedPassesCursor);
-
-        html.append("</body></html>");
-        dumpHtmlToFile(html, true);
-    }
-
-    private int getTotalTestCount() {
-        return mUnexpectedFailuresCursor.getCount() +
-                mUnexpectedPassesCursor.getCount() +
-                mExpectedPassesCursor.getCount() +
-                mExpectedFailuresCursor.getCount();
-    }
-
-    private String getWebKitVersionFromUserAgentString() {
-        Resources resources = new Resources(new AssetManager(), new DisplayMetrics(),
-                new Configuration());
-        String userAgent =
-                resources.getString(com.android.internal.R.string.web_user_agent);
-
-        Matcher matcher = Pattern.compile("AppleWebKit/([0-9]+?\\.[0-9])").matcher(userAgent);
-        if (matcher.find()) {
-            return matcher.group(1);
-        }
-        return "unknown";
-    }
-
-    private String getWebKitRevision() {
-        URL url = null;
-        try {
-            url = new URL(ForwarderManager.getHostSchemePort(false) + "ThirdPartyProject.prop");
-        } catch (MalformedURLException e) {
-            assert false;
-        }
-
-        String thirdPartyProjectContents = new String(FsUtils.readDataFromUrl(url));
-        Matcher matcher = Pattern.compile("^version=([0-9]+)", Pattern.MULTILINE).matcher(
-                thirdPartyProjectContents);
-        if (matcher.find()) {
-            return matcher.group(1);
-        }
-        return "unknown";
-    }
-
-    private void createTopSummaryTable(String webKitRevision, StringBuilder html) {
-        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
-        html.append("<h1>" + "Layout tests' results for: " +
-                (mTestsRelativePath.equals("") ? "all tests" : mTestsRelativePath) + "</h1>");
-        html.append("<h3>" + "Date: " + dateFormat.format(new Date()) + "</h3>");
-        html.append("<h3>" + "Build fingerprint: " + Build.FINGERPRINT + "</h3>");
-        html.append("<h3>" + "WebKit version: " + getWebKitVersionFromUserAgentString() + "</h3>");
-
-        html.append("<h3>" + "WebKit revision: ");
-        html.append("<a href=\"http://trac.webkit.org/browser/trunk?rev=" + webKitRevision +
-                "\" target=\"_blank\"><span class=\"path\">" + webKitRevision + "</span></a>");
-        html.append("</h3>");
-
-        html.append("<table class=\"summary\">");
-        createSummaryTableRow(html, "TOTAL", getTotalTestCount());
-        createSummaryTableRow(html, "CRASHED (among all tests)", mCrashedTestsCount);
-        createSummaryTableRow(html, "UNEXPECTED FAILURES", mUnexpectedFailuresCursor.getCount());
-        createSummaryTableRow(html, "UNEXPECTED PASSES", mUnexpectedPassesCursor.getCount());
-        createSummaryTableRow(html, "EXPECTED FAILURES", mExpectedFailuresCursor.getCount());
-        createSummaryTableRow(html, "EXPECTED PASSES", mExpectedPassesCursor.getCount());
-        html.append("</table>");
-    }
-
-    private void createSummaryTableRow(StringBuilder html, String caption, int size) {
-        html.append("<tr>");
-        html.append("    <td>" + caption + "</td>");
-        html.append("    <td>" + size + "</td>");
-        html.append("</tr>");
-    }
-
-    private void createResultsList(
-            StringBuilder html, String title, Cursor cursor) {
-        String relativePath;
-        String id = "";
-        AbstractResult.ResultCode resultCode;
-
-        html.append("<h2>" + title + " [" + cursor.getCount() + "]</h2>");
-
-        if (!cursor.moveToFirst()) {
-            return;
-        }
-
-        AbstractResult result;
-        do {
-            result = SummarizerDBHelper.getAbstractResult(cursor);
-
-            relativePath = result.getRelativePath();
-            resultCode = result.getResultCode();
-
-            html.append("<h3>");
-
-            /**
-             * Technically, two different paths could end up being the same, because
-             * ':' is a valid  character in a path. However, it is probably not going
-             * to cause any problems in this case
-             */
-            id = relativePath.replace(File.separator, ":");
-
-            /** Write the test name */
-            if (resultCode == AbstractResult.ResultCode.RESULTS_DIFFER) {
-                html.append("<a href=\"#\" onClick=\"toggleDisplay('" + id + "');");
-                html.append("return false;\">");
-                html.append("<span class=\"tri\" id=\"tri." + id + "\">&#x25b6; </span>");
-                html.append("<span class=\"path\">" + relativePath + "</span>");
-                html.append("</a>");
-            } else {
-                html.append("<a href=\"" + getViewSourceUrl(result.getRelativePath()).toString() + "\"");
-                html.append(" target=\"_blank\">");
-                html.append("<span class=\"sqr sqr_" + (result.didPass() ? "pass" : "fail"));
-                html.append("\">&#x25a0; </span>");
-                html.append("<span class=\"path\">" + result.getRelativePath() + "</span>");
-                html.append("</a>");
-            }
-
-            if (!result.didPass()) {
-                appendTags(html, result);
-            }
-
-            html.append("</h3>");
-            appendExpectedResultsSources(result, html);
-
-            if (resultCode == AbstractResult.ResultCode.RESULTS_DIFFER) {
-                html.append("<div class=\"diff\" style=\"display: none;\" id=\"" + id + "\">");
-                html.append(result.getDiffAsHtml());
-                html.append("<a href=\"#\" onClick=\"toggleDisplay('" + id + "');");
-                html.append("return false;\">Hide</a>");
-                html.append(" | ");
-                html.append("<a href=\"" + getViewSourceUrl(relativePath).toString() + "\"");
-                html.append(" target=\"_blank\">Show source</a>");
-                html.append("</div>");
-            }
-
-            html.append("<div class=\"space\"></div>");
-
-            if (++mResultsSinceLastHtmlDump == RESULTS_PER_DUMP) {
-                dumpHtmlToFile(html, true);
-            }
-
-            cursor.moveToNext();
-        } while (!cursor.isAfterLast());
-    }
-
-    private void appendTags(StringBuilder html, AbstractResult result) {
-        /** Tag tests which crash, time out or where results don't match */
-        if (result.didCrash()) {
-            html.append(" <span class=\"listItem crashed\">Crashed</span>");
-        } else {
-            if (result.didTimeOut()) {
-                html.append(" <span class=\"listItem timed_out\">Timed out</span>");
-            }
-            AbstractResult.ResultCode resultCode = result.getResultCode();
-            if (resultCode != AbstractResult.ResultCode.RESULTS_MATCH) {
-                html.append(" <span class=\"listItem " + resultCode.name() + "\">");
-                html.append(resultCode.toString());
-                html.append("</span>");
-            }
-        }
-
-        /** Detect missing LTC function */
-        String additionalTextOutputString = result.getAdditionalTextOutputString();
-        if (additionalTextOutputString != null &&
-                additionalTextOutputString.contains("com.android.dumprendertree") &&
-                additionalTextOutputString.contains("has no method")) {
-            if (additionalTextOutputString.contains("LayoutTestController")) {
-                html.append(" <span class=\"listItem noLtc\">LTC function missing</span>");
-            }
-            if (additionalTextOutputString.contains("EventSender")) {
-                html.append(" <span class=\"listItem noEventSender\">");
-                html.append("ES function missing</span>");
-            }
-        }
-    }
-
-    private static final void appendExpectedResultsSources(AbstractResult result,
-            StringBuilder html) {
-        String textSource = result.getExpectedTextResultPath();
-        String imageSource = result.getExpectedImageResultPath();
-
-        if (result.didCrash()) {
-            html.append("<span class=\"source\">Did not look for expected results</span>");
-            return;
-        }
-
-        if (textSource == null) {
-            // Show if a text result is missing. We may want to revisit this decision when we add
-            // support for image results.
-            html.append("<span class=\"source\">Expected textual result missing</span>");
-        } else {
-            html.append("<span class=\"source\">Expected textual result from: ");
-            html.append("<a href=\"" + ForwarderManager.getHostSchemePort(false) + "LayoutTests/" +
-                    textSource + "\"");
-            html.append(" target=\"_blank\">");
-            html.append(textSource + "</a></span>");
-        }
-        if (imageSource != null) {
-            html.append("<span class=\"source\">Expected image result from: ");
-            html.append("<a href=\"" + ForwarderManager.getHostSchemePort(false) + "LayoutTests/" +
-                    imageSource + "\"");
-            html.append(" target=\"_blank\">");
-            html.append(imageSource + "</a></span>");
-        }
-    }
-
-    private static final URL getViewSourceUrl(String relativePath) {
-        URL url = null;
-        try {
-            url = new URL("http", "localhost", ForwarderManager.HTTP_PORT,
-                    "/Tools/DumpRenderTree/android/view_source.php?src=" +
-                    relativePath);
-        } catch (MalformedURLException e) {
-            assert false : "relativePath=" + relativePath;
-        }
-        return url;
-    }
-}
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/SummarizerDBHelper.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/SummarizerDBHelper.java
deleted file mode 100644
index 23e13ec..0000000
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/SummarizerDBHelper.java
+++ /dev/null
@@ -1,129 +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.dumprendertree2;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.SQLException;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * A basic class that wraps database accesses inside itself and provides functionality to
- * store and retrieve AbstractResults.
- */
-public class SummarizerDBHelper {
-    private static final String KEY_ID = "id";
-    private static final String KEY_PATH = "path";
-    private static final String KEY_BYTES = "bytes";
-
-    private static final String DATABASE_NAME = "SummarizerDB";
-    private static final int DATABASE_VERSION = 1;
-
-    static final String EXPECTED_FAILURES_TABLE = "expectedFailures";
-    static final String UNEXPECTED_FAILURES_TABLE = "unexpectedFailures";
-    static final String EXPECTED_PASSES_TABLE = "expextedPasses";
-    static final String UNEXPECTED_PASSES_TABLE = "unexpextedPasses";
-    private static final Set<String> TABLES_NAMES = new HashSet<String>();
-    {
-        TABLES_NAMES.add(EXPECTED_FAILURES_TABLE);
-        TABLES_NAMES.add(EXPECTED_PASSES_TABLE);
-        TABLES_NAMES.add(UNEXPECTED_FAILURES_TABLE);
-        TABLES_NAMES.add(UNEXPECTED_PASSES_TABLE);
-    }
-
-    private static final void createTables(SQLiteDatabase db) {
-        String cmd;
-        for (String tableName : TABLES_NAMES) {
-            cmd = "create table " + tableName + " ("
-                    + KEY_ID + " integer primary key autoincrement, "
-                    + KEY_PATH + " text not null, "
-                    + KEY_BYTES + " blob not null);";
-            db.execSQL(cmd);
-        }
-    }
-
-    private static final void dropTables(SQLiteDatabase db) {
-        for (String tableName : TABLES_NAMES) {
-            db.execSQL("DROP TABLE IF EXISTS " + tableName);
-        }
-    }
-
-    private static class DatabaseHelper extends SQLiteOpenHelper {
-        DatabaseHelper(Context context) {
-            super(context, DATABASE_NAME, null, DATABASE_VERSION);
-        }
-
-        @Override
-        public void onCreate(SQLiteDatabase db) {
-            dropTables(db);
-            createTables(db);
-        }
-
-        @Override
-        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-            /** NOOP for now, because we will never upgrade the db */
-        }
-
-        public void reset(SQLiteDatabase db) {
-            dropTables(db);
-            createTables(db);
-        }
-    }
-
-    private DatabaseHelper mDbHelper;
-    private SQLiteDatabase mDb;
-
-    private final Context mContext;
-
-    public SummarizerDBHelper(Context ctx) {
-        mContext = ctx;
-        mDbHelper = new DatabaseHelper(mContext);
-    }
-
-    public void reset() {
-        mDbHelper.reset(this.mDb);
-    }
-
-    public void open() throws SQLException {
-        mDb = mDbHelper.getWritableDatabase();
-    }
-
-    public void close() {
-        mDbHelper.close();
-    }
-
-    public void insertAbstractResult(AbstractResult result, String table) {
-        ContentValues cv = new ContentValues();
-        cv.put(KEY_PATH, result.getRelativePath());
-        cv.put(KEY_BYTES, result.getBytes());
-        mDb.insert(table, null, cv);
-    }
-
-    public Cursor getAbstractResults(String table) throws SQLException {
-        return mDb.query(false, table, new String[] {KEY_BYTES}, null, null, null, null,
-                KEY_PATH + " ASC", null);
-    }
-
-    public static AbstractResult getAbstractResult(Cursor cursor) {
-        return AbstractResult.create(cursor.getBlob(cursor.getColumnIndex(KEY_BYTES)));
-    }
-}
\ No newline at end of file
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/TestsListActivity.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/TestsListActivity.java
deleted file mode 100644
index e374c1b..0000000
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/TestsListActivity.java
+++ /dev/null
@@ -1,203 +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.dumprendertree2;
-
-import com.android.dumprendertree2.scriptsupport.OnEverythingFinishedCallback;
-
-import android.app.Activity;
-import android.app.ProgressDialog;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.view.Gravity;
-import android.view.Window;
-import android.webkit.WebView;
-import android.widget.Toast;
-
-import java.io.File;
-import java.util.ArrayList;
-
-/**
- * An Activity that generates a list of tests and sends the intent to
- * LayoutTestsExecuter to run them. It also restarts the LayoutTestsExecuter
- * after it crashes.
- */
-public class TestsListActivity extends Activity {
-
-    private static final int MSG_TEST_LIST_PRELOADER_DONE = 0;
-
-    /** Constants for adding extras to an intent */
-    public static final String EXTRA_TEST_PATH = "TestPath";
-
-    private static ProgressDialog sProgressDialog;
-
-    private Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_TEST_LIST_PRELOADER_DONE:
-                    sProgressDialog.dismiss();
-                    mTestsList = (ArrayList<String>)msg.obj;
-                    mTotalTestCount = mTestsList.size();
-                    restartExecutor(0);
-                    break;
-            }
-        }
-    };
-
-    private ArrayList<String> mTestsList;
-    private int mTotalTestCount;
-
-    private OnEverythingFinishedCallback mOnEverythingFinishedCallback;
-    private boolean mEverythingFinished;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        /** Prepare the progress dialog */
-        sProgressDialog = new ProgressDialog(TestsListActivity.this);
-        sProgressDialog.setCancelable(false);
-        sProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
-        sProgressDialog.setTitle(R.string.dialog_progress_title);
-        sProgressDialog.setMessage(getText(R.string.dialog_progress_msg));
-
-        requestWindowFeature(Window.FEATURE_PROGRESS);
-
-        Intent intent = getIntent();
-        if (!intent.getAction().equals(Intent.ACTION_RUN)) {
-            return;
-        }
-        String path = intent.getStringExtra(EXTRA_TEST_PATH);
-
-        sProgressDialog.show();
-        Message doneMsg = Message.obtain(mHandler, MSG_TEST_LIST_PRELOADER_DONE);
-
-        Intent serviceIntent = new Intent(this, ManagerService.class);
-        serviceIntent.putExtra("path", path);
-        startService(serviceIntent);
-
-        new TestsListPreloaderThread(path, doneMsg).start();
-    }
-
-    @Override
-    protected void onNewIntent(Intent intent) {
-        if (intent.getAction().equals(Intent.ACTION_REBOOT)) {
-            onCrashIntent(intent);
-        } else if (intent.getAction().equals(Intent.ACTION_SHUTDOWN)) {
-            onEverythingFinishedIntent(intent);
-        }
-    }
-
-    /**
-     * This method handles an intent that comes from ManageService when crash is detected.
-     * The intent contains an index in mTestsList of the test that crashed. TestsListActivity
-     * restarts the LayoutTestsExecutor from the following test in mTestsList, by sending
-     * an intent to it. This new intent contains a list of remaining tests to run,
-     * total count of all tests, and the index of the first test to run after restarting.
-     * LayoutTestExecutor runs then as usual, sending reports to ManagerService. If it
-     * detects the crash it sends a new intent and the flow repeats.
-     */
-    private void onCrashIntent(Intent intent) {
-        int nextTestToRun = intent.getIntExtra("crashedTestIndex", -1) + 1;
-        if (nextTestToRun > 0 && nextTestToRun <= mTotalTestCount) {
-            restartExecutor(nextTestToRun);
-        }
-    }
-
-    public void registerOnEverythingFinishedCallback(OnEverythingFinishedCallback callback) {
-        mOnEverythingFinishedCallback = callback;
-        if (mEverythingFinished) {
-            mOnEverythingFinishedCallback.onFinished();
-        }
-    }
-
-    private void onEverythingFinishedIntent(Intent intent) {
-        Toast toast = Toast.makeText(this,
-                "All tests finished.\nPress back key to return to the tests' list.",
-                Toast.LENGTH_LONG);
-        toast.setGravity(Gravity.CENTER, -40, 0);
-        toast.show();
-
-        /** Show the details to the user */
-        WebView webView = new WebView(this);
-        webView.getSettings().setJavaScriptEnabled(true);
-        webView.getSettings().setBuiltInZoomControls(true);
-        webView.getSettings().setEnableSmoothTransition(true);
-        /** This enables double-tap to zoom */
-        webView.getSettings().setUseWideViewPort(true);
-
-        setContentView(webView);
-        webView.loadUrl(Summarizer.getDetailsUri().toString());
-
-        mEverythingFinished = true;
-        if (mOnEverythingFinishedCallback != null) {
-            mOnEverythingFinishedCallback.onFinished();
-        }
-    }
-
-    /**
-     * This, together with android:configChanges="orientation" in manifest file, prevents
-     * the activity from restarting on orientation change.
-     */
-    @Override
-    public void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-    }
-
-    @Override
-    protected void onSaveInstanceState(Bundle outState) {
-        outState.putStringArrayList("testsList", mTestsList);
-        outState.putInt("totalCount", mTotalTestCount);
-
-        super.onSaveInstanceState(outState);
-    }
-
-    @Override
-    protected void onRestoreInstanceState(Bundle savedInstanceState) {
-        super.onRestoreInstanceState(savedInstanceState);
-
-        mTestsList = savedInstanceState.getStringArrayList("testsList");
-        mTotalTestCount = savedInstanceState.getInt("totalCount");
-    }
-
-    /**
-     * (Re)starts the executer activity from the given test number (inclusive, 0-based).
-     * This number is an index in mTestsList, not the sublist passed in the intent.
-     *
-     * @param startFrom
-     *      test index in mTestsList to start the tests from (inclusive, 0-based)
-     */
-    private void restartExecutor(int startFrom) {
-        Intent intent = new Intent();
-        intent.setClass(this, LayoutTestsExecutor.class);
-        intent.setAction(Intent.ACTION_RUN);
-
-        if (startFrom < mTotalTestCount) {
-            File testListFile = new File(getExternalFilesDir(null), "test_list.txt");
-            FsUtils.saveTestListToStorage(testListFile, startFrom, mTestsList);
-            intent.putExtra(LayoutTestsExecutor.EXTRA_TESTS_FILE, testListFile.getAbsolutePath());
-            intent.putExtra(LayoutTestsExecutor.EXTRA_TEST_INDEX, startFrom);
-        } else {
-            intent.putExtra(LayoutTestsExecutor.EXTRA_TESTS_FILE, "");
-        }
-
-        startActivity(intent);
-    }
-}
\ No newline at end of file
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/TestsListPreloaderThread.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/TestsListPreloaderThread.java
deleted file mode 100644
index ab98830..0000000
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/TestsListPreloaderThread.java
+++ /dev/null
@@ -1,114 +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.dumprendertree2;
-
-import android.os.Environment;
-import android.os.Message;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * A Thread that is responsible for generating a lists of tests to run.
- */
-public class TestsListPreloaderThread extends Thread {
-
-    private static final String LOG_TAG = "TestsListPreloaderThread";
-
-    /** A list containing relative paths of tests to run */
-    private ArrayList<String> mTestsList = new ArrayList<String>();
-
-    private FileFilter mFileFilter;
-
-    /**
-     * A relative path to the directory with the tests we want to run or particular test.
-     * Used up to and including preloadTests().
-     */
-    private String mRelativePath;
-
-    private Message mDoneMsg;
-
-    /**
-     * The given path must be relative to the root dir.
-     *
-     * @param path
-     * @param doneMsg
-     */
-    public TestsListPreloaderThread(String path, Message doneMsg) {
-        mRelativePath = path;
-        mDoneMsg = doneMsg;
-    }
-
-    @Override
-    public void run() {
-        mFileFilter = new FileFilter();
-        if (FileFilter.isTestFile(mRelativePath)) {
-            mTestsList.add(mRelativePath);
-        } else {
-            loadTestsFromUrl(mRelativePath);
-        }
-
-        mDoneMsg.obj = mTestsList;
-        mDoneMsg.sendToTarget();
-    }
-
-    /**
-     * Loads all the tests from the given directories and all the subdirectories
-     * into mTestsList.
-     *
-     * @param dirRelativePath
-     */
-    private void loadTestsFromUrl(String rootRelativePath) {
-        LinkedList<String> directoriesList = new LinkedList<String>();
-        directoriesList.add(rootRelativePath);
-
-        String relativePath;
-        String itemName;
-        while (!directoriesList.isEmpty()) {
-            relativePath = directoriesList.removeFirst();
-
-            List<String> dirRelativePaths = FsUtils.getLayoutTestsDirContents(relativePath, false, true);
-            if (dirRelativePaths != null) {
-                for (String dirRelativePath : dirRelativePaths) {
-                    itemName = new File(dirRelativePath).getName();
-                    if (FileFilter.isTestDir(itemName)) {
-                        directoriesList.add(dirRelativePath);
-                    }
-                }
-            }
-
-            List<String> testRelativePaths = FsUtils.getLayoutTestsDirContents(relativePath, false, false);
-            if (testRelativePaths != null) {
-                for (String testRelativePath : testRelativePaths) {
-                    itemName = new File(testRelativePath).getName();
-                    if (FileFilter.isTestFile(itemName)) {
-                        /** We choose to skip all the tests that are expected to crash. */
-                        if (!mFileFilter.isCrash(testRelativePath)) {
-                            mTestsList.add(testRelativePath);
-                        } else {
-                            /**
-                             * TODO: Summarizer is now in service - figure out how to send the info.
-                             * Previously: mSummarizer.addSkippedTest(relativePath);
-                             */
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java
deleted file mode 100644
index fd1c0ad..0000000
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.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 com.android.dumprendertree2;
-
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.webkit.WebView;
-import android.webkit.WebViewClassic;
-
-import name.fraser.neil.plaintext.diff_match_patch;
-
-import java.util.LinkedList;
-
-/**
- * A result object for which the expected output is text. It does not have an image
- * expected result.
- *
- * <p>Created if layoutTestController.dumpAsText() was called.
- */
-public class TextResult extends AbstractResult {
-
-    private static final int MSG_DOCUMENT_AS_TEXT = 0;
-
-    private String mExpectedResult;
-    private String mExpectedResultPath;
-    private String mActualResult;
-    private String mRelativePath;
-    private boolean mDidTimeOut;
-    private ResultCode mResultCode;
-    transient private Message mResultObtainedMsg;
-
-    private boolean mDumpChildFramesAsText;
-
-    transient private Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            if (msg.what == MSG_DOCUMENT_AS_TEXT) {
-                mActualResult = (String)msg.obj;
-                mResultObtainedMsg.sendToTarget();
-            }
-        }
-    };
-
-    public TextResult(String relativePath) {
-        mRelativePath = relativePath;
-    }
-
-    public void setDumpChildFramesAsText(boolean dumpChildFramesAsText) {
-        mDumpChildFramesAsText = dumpChildFramesAsText;
-    }
-
-    /**
-     * Used to recreate the Result when received by the service.
-     *
-     * @param bundle
-     *      bundle with data used to recreate the result
-     */
-    public TextResult(Bundle bundle) {
-        mExpectedResult = bundle.getString("expectedTextualResult");
-        mExpectedResultPath = bundle.getString("expectedTextualResultPath");
-        mActualResult = bundle.getString("actualTextualResult");
-        setAdditionalTextOutputString(bundle.getString("additionalTextOutputString"));
-        mRelativePath = bundle.getString("relativePath");
-        mDidTimeOut = bundle.getBoolean("didTimeOut");
-    }
-
-    @Override
-    public void clearResults() {
-        super.clearResults();
-        mExpectedResult = null;
-        mActualResult = null;
-    }
-
-    @Override
-    public ResultCode getResultCode() {
-        if (mResultCode == null) {
-            mResultCode = resultsMatch() ? AbstractResult.ResultCode.RESULTS_MATCH
-                    : AbstractResult.ResultCode.RESULTS_DIFFER;
-        }
-        return mResultCode;
-    }
-
-    private boolean resultsMatch() {
-        assert mExpectedResult != null;
-        assert mActualResult != null;
-        // Trim leading and trailing empty lines, as other WebKit platforms do.
-        String leadingEmptyLines = "^\\n+";
-        String trailingEmptyLines = "\\n+$";
-        String trimmedExpectedResult = mExpectedResult.replaceFirst(leadingEmptyLines, "")
-                .replaceFirst(trailingEmptyLines, "");
-        String trimmedActualResult = mActualResult.replaceFirst(leadingEmptyLines, "")
-                .replaceFirst(trailingEmptyLines, "");
-        return trimmedExpectedResult.equals(trimmedActualResult);
-    }
-
-    @Override
-    public boolean didCrash() {
-        return false;
-    }
-
-    @Override
-    public boolean didTimeOut() {
-        return mDidTimeOut;
-    }
-
-    @Override
-    public void setDidTimeOut() {
-        mDidTimeOut = true;
-    }
-
-    @Override
-    public byte[] getActualImageResult() {
-        return null;
-    }
-
-    @Override
-    public String getActualTextResult() {
-        String additionalTextResultString = getAdditionalTextOutputString();
-        if (additionalTextResultString != null) {
-            return additionalTextResultString + mActualResult;
-        }
-
-        return mActualResult;
-    }
-
-    @Override
-    public void setExpectedImageResult(byte[] expectedResult) {
-        /** This method is not applicable to this type of result */
-    }
-
-    @Override
-    public void setExpectedImageResultPath(String relativePath) {
-        /** This method is not applicable to this type of result */
-    }
-
-    @Override
-    public String getExpectedImageResultPath() {
-        /** This method is not applicable to this type of result */
-        return null;
-    }
-
-    @Override
-    public void setExpectedTextResultPath(String relativePath) {
-        mExpectedResultPath = relativePath;
-    }
-
-    @Override
-    public String getExpectedTextResultPath() {
-        return mExpectedResultPath;
-    }
-
-    @Override
-    public void setExpectedTextResult(String expectedResult) {
-        // For text results, we use an empty string for the expected result when none is
-        // present, as other WebKit platforms do.
-        mExpectedResult = expectedResult == null ? "" : expectedResult;
-    }
-
-    @Override
-    public String getDiffAsHtml() {
-        assert mExpectedResult != null;
-        assert mActualResult != null;
-
-        StringBuilder html = new StringBuilder();
-        html.append("<table class=\"visual_diff\">");
-        html.append("    <tr class=\"headers\">");
-        html.append("        <td colspan=\"2\">Expected result:</td>");
-        html.append("        <td class=\"space\"></td>");
-        html.append("        <td colspan=\"2\">Actual result:</td>");
-        html.append("    </tr>");
-
-        appendDiffHtml(html);
-
-        html.append("    <tr class=\"footers\">");
-        html.append("        <td colspan=\"2\"></td>");
-        html.append("        <td class=\"space\"></td>");
-        html.append("        <td colspan=\"2\"></td>");
-        html.append("    </tr>");
-        html.append("</table>");
-
-        return html.toString();
-    }
-
-    private void appendDiffHtml(StringBuilder html) {
-        LinkedList<diff_match_patch.Diff> diffs =
-                new diff_match_patch().diff_main(mExpectedResult, mActualResult);
-
-        diffs = VisualDiffUtils.splitDiffsOnNewline(diffs);
-
-        LinkedList<String> expectedLines = new LinkedList<String>();
-        LinkedList<Integer> expectedLineNums = new LinkedList<Integer>();
-        LinkedList<String> actualLines = new LinkedList<String>();
-        LinkedList<Integer> actualLineNums = new LinkedList<Integer>();
-
-        VisualDiffUtils.generateExpectedResultLines(diffs, expectedLineNums, expectedLines);
-        VisualDiffUtils.generateActualResultLines(diffs, actualLineNums, actualLines);
-        // TODO: We should use a map for each line number and lines pair.
-        assert expectedLines.size() == expectedLineNums.size();
-        assert actualLines.size() == actualLineNums.size();
-        assert expectedLines.size() == actualLines.size();
-
-        html.append(VisualDiffUtils.getHtml(expectedLineNums, expectedLines,
-                actualLineNums, actualLines));
-    }
-
-    @Override
-    public TestType getType() {
-        return TestType.TEXT;
-    }
-
-    @Override
-    public void obtainActualResults(WebView webview, Message resultObtainedMsg) {
-        mResultObtainedMsg = resultObtainedMsg;
-        Message msg = mHandler.obtainMessage(MSG_DOCUMENT_AS_TEXT);
-
-        /**
-         * arg1 - should dump top frame as text
-         * arg2 - should dump child frames as text
-         */
-        msg.arg1 = 1;
-        msg.arg2 = mDumpChildFramesAsText ? 1 : 0;
-        WebViewClassic.fromWebView(webview).documentAsText(msg);
-    }
-
-    @Override
-    public Bundle getBundle() {
-        Bundle bundle = new Bundle();
-        bundle.putString("expectedTextualResult", mExpectedResult);
-        bundle.putString("expectedTextualResultPath", mExpectedResultPath);
-        bundle.putString("actualTextualResult", getActualTextResult());
-        bundle.putString("additionalTextOutputString", getAdditionalTextOutputString());
-        bundle.putString("relativePath", mRelativePath);
-        bundle.putBoolean("didTimeOut", mDidTimeOut);
-        bundle.putString("type", getType().name());
-        return bundle;
-    }
-
-    @Override
-    public String getRelativePath() {
-        return mRelativePath;
-    }
-}
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/VisualDiffUtils.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/VisualDiffUtils.java
deleted file mode 100644
index d7f7313..0000000
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/VisualDiffUtils.java
+++ /dev/null
@@ -1,214 +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.dumprendertree2;
-
-import name.fraser.neil.plaintext.diff_match_patch;
-
-import java.util.LinkedList;
-
-/**
- * Helper methods fo TextResult.getDiffAsHtml()
- */
-public class VisualDiffUtils {
-
-    private static final int DONT_PRINT_LINE_NUMBER = -1;
-
-    /**
-     * Preprocesses the list of diffs so that new line characters appear only at the end of
-     * diff.text
-     *
-     * @param diffs
-     * @return
-     *      LinkedList of diffs where new line character appears only on the end of
-     *      diff.text
-     */
-    public static LinkedList<diff_match_patch.Diff> splitDiffsOnNewline(
-            LinkedList<diff_match_patch.Diff> diffs) {
-        LinkedList<diff_match_patch.Diff> newDiffs = new LinkedList<diff_match_patch.Diff>();
-
-        String[] parts;
-        int lengthMinusOne;
-        for (diff_match_patch.Diff diff : diffs) {
-            parts = diff.text.split("\n", -1);
-            if (parts.length == 1) {
-                newDiffs.add(diff);
-                continue;
-            }
-
-            lengthMinusOne = parts.length - 1;
-            for (int i = 0; i < lengthMinusOne; i++) {
-                newDiffs.add(new diff_match_patch.Diff(diff.operation, parts[i] + "\n"));
-            }
-            if (!parts[lengthMinusOne].isEmpty()) {
-                newDiffs.add(new diff_match_patch.Diff(diff.operation, parts[lengthMinusOne]));
-            }
-        }
-
-        return newDiffs;
-    }
-
-    public static void generateExpectedResultLines(LinkedList<diff_match_patch.Diff> diffs,
-            LinkedList<Integer> lineNums, LinkedList<String> lines) {
-        String delSpan = "<span class=\"del\">";
-        String eqlSpan = "<span class=\"eql\">";
-
-        String line = "";
-        int i = 1;
-        diff_match_patch.Diff diff;
-        int size = diffs.size();
-        boolean isLastDiff;
-        for (int j = 0; j < size; j++) {
-            diff = diffs.get(j);
-            isLastDiff = j == size - 1;
-            switch (diff.operation) {
-                case DELETE:
-                    line = processDiff(diff, lineNums, lines, line, i, delSpan, isLastDiff);
-                    if (line.equals("")) {
-                        i++;
-                    }
-                    break;
-
-                case INSERT:
-                    // If the line is currently empty and this insertion is the entire line, the
-                    // expected line is absent, so it has no line number.
-                    if (diff.text.endsWith("\n") || isLastDiff) {
-                        lineNums.add(line.equals("") ? DONT_PRINT_LINE_NUMBER : i++);
-                        lines.add(line);
-                        line = "";
-                    }
-                    break;
-
-                case EQUAL:
-                    line = processDiff(diff, lineNums, lines, line, i, eqlSpan, isLastDiff);
-                    if (line.equals("")) {
-                        i++;
-                    }
-                    break;
-            }
-        }
-    }
-
-    public static void generateActualResultLines(LinkedList<diff_match_patch.Diff> diffs,
-            LinkedList<Integer> lineNums, LinkedList<String> lines) {
-        String insSpan = "<span class=\"ins\">";
-        String eqlSpan = "<span class=\"eql\">";
-
-        String line = "";
-        int i = 1;
-        diff_match_patch.Diff diff;
-        int size = diffs.size();
-        boolean isLastDiff;
-        for (int j = 0; j < size; j++) {
-            diff = diffs.get(j);
-            isLastDiff = j == size - 1;
-            switch (diff.operation) {
-                case INSERT:
-                    line = processDiff(diff, lineNums, lines, line, i, insSpan, isLastDiff);
-                    if (line.equals("")) {
-                        i++;
-                    }
-                    break;
-
-                case DELETE:
-                    // If the line is currently empty and deletion is the entire line, the
-                    // actual line is absent, so it has no line number.
-                    if (diff.text.endsWith("\n") || isLastDiff) {
-                        lineNums.add(line.equals("") ? DONT_PRINT_LINE_NUMBER : i++);
-                        lines.add(line);
-                        line = "";
-                    }
-                    break;
-
-                case EQUAL:
-                    line = processDiff(diff, lineNums, lines, line, i, eqlSpan, isLastDiff);
-                    if (line.equals("")) {
-                        i++;
-                    }
-                    break;
-            }
-        }
-    }
-
-    /**
-     * Generate or append a line for a given diff and add it to given collections if necessary.
-     * It puts diffs in HTML spans.
-     *
-     * @param diff
-     * @param lineNums
-     * @param lines
-     * @param line
-     * @param i
-     * @param begSpan
-     * @param forceOutputLine Force the current line to be output
-     * @return
-     */
-    public static String processDiff(diff_match_patch.Diff diff, LinkedList<Integer> lineNums,
-            LinkedList<String> lines, String line, int i, String begSpan, boolean forceOutputLine) {
-        String endSpan = "</span>";
-        String br = "&nbsp;";
-
-        if (diff.text.endsWith("\n") || forceOutputLine) {
-            lineNums.add(i);
-            /** TODO: Think of better way to replace stuff */
-            line += begSpan + diff.text.replace("  ", "&nbsp;&nbsp;")
-                    + endSpan + br;
-            lines.add(line);
-            line = "";
-        } else {
-            line += begSpan + diff.text.replace("  ", "&nbsp;&nbsp;") + endSpan;
-        }
-
-        return line;
-    }
-
-    public static String getHtml(LinkedList<Integer> lineNums1, LinkedList<String> lines1,
-            LinkedList<Integer> lineNums2, LinkedList<String> lines2) {
-        StringBuilder html = new StringBuilder();
-        int lineNum;
-        int size = lines1.size();
-        for (int i = 0; i < size; i++) {
-            html.append("<tr class=\"results\">");
-
-            html.append("    <td class=\"line_count\">");
-            lineNum = lineNums1.removeFirst();
-            if (lineNum > 0) {
-                html.append(lineNum);
-            }
-            html.append("    </td>");
-
-            html.append("    <td class=\"line\">");
-            html.append(lines1.removeFirst());
-            html.append("    </td>");
-
-            html.append("    <td class=\"space\"></td>");
-
-            html.append("    <td class=\"line_count\">");
-            lineNum = lineNums2.removeFirst();
-            if (lineNum > 0) {
-                html.append(lineNum);
-            }
-            html.append("    </td>");
-
-            html.append("    <td class=\"line\">");
-            html.append(lines2.removeFirst());
-            html.append("    </td>");
-
-            html.append("</tr>");
-        }
-        return html.toString();
-    }
-}
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/AdbUtils.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/AdbUtils.java
deleted file mode 100644
index 224509d..0000000
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/AdbUtils.java
+++ /dev/null
@@ -1,75 +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.dumprendertree2.forwarder;
-
-import android.util.Log;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.Socket;
-
-/**
- * The utility class that can setup a socket allowing the device to communicate with remote
- * machines through the machine that the device is connected to via adb.
- */
-public class AdbUtils {
-    private static final String LOG_TAG = "AdbUtils";
-
-    private static final String ADB_OK = "OKAY";
-    private static final int ADB_PORT = 5037;
-    private static final String ADB_HOST = "127.0.0.1";
-    private static final int ADB_RESPONSE_SIZE = 4;
-
-    /**
-     * Creates a new socket that can be configured to serve as a transparent proxy to a
-     * remote machine. This can be achieved by calling configureSocket()
-     *
-     * @return a socket that can be configured to link to remote machine
-     * @throws IOException
-     */
-    public static Socket createSocket() throws IOException{
-        return new Socket(ADB_HOST, ADB_PORT);
-    }
-
-    /**
-     * Configures the connection to serve as a transparent proxy to a remote machine.
-     * The given streams must belong to a socket created by createSocket().
-     *
-     * @param inputStream inputStream of the socket we want to configure
-     * @param outputStream outputStream of the socket we want to configure
-     * @param remoteAddress address of the remote machine (as you would type in a browser
-     *      in a machine that the device is connected to via adb)
-     * @param remotePort port on which to connect
-     * @return if the configuration suceeded
-     * @throws IOException
-     */
-    public static boolean configureConnection(InputStream inputStream, OutputStream outputStream,
-            String remoteAddress, int remotePort) throws IOException {
-        String cmd = "tcp:" + remotePort + ":" + remoteAddress;
-        cmd = String.format("%04X", cmd.length()) + cmd;
-
-        byte[] buf = new byte[ADB_RESPONSE_SIZE];
-        outputStream.write(cmd.getBytes());
-        int read = inputStream.read(buf);
-        if (read != ADB_RESPONSE_SIZE || !ADB_OK.equals(new String(buf))) {
-            Log.w(LOG_TAG, "adb cmd failed.");
-            return false;
-        }
-        return true;
-    }
-}
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/ConnectionHandler.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/ConnectionHandler.java
deleted file mode 100644
index f19cd41..0000000
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/ConnectionHandler.java
+++ /dev/null
@@ -1,172 +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.dumprendertree2.forwarder;
-
-import android.util.Log;
-
-import com.android.dumprendertree2.FsUtils;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.Socket;
-
-/**
- * Worker class for {@link Forwarder}. A ConnectionHandler will be created once the Forwarder
- * accepts an incoming connection, and it will then forward the incoming/outgoing streams to a
- * connection already proxied by adb networking (see also {@link AdbUtils}).
- */
-public class ConnectionHandler {
-
-    private static final String LOG_TAG = "ConnectionHandler";
-
-    public static interface OnFinishedCallback {
-        public void onFinished();
-    }
-
-    private class SocketPipeThread extends Thread {
-
-        private InputStream mInputStream;
-        private OutputStream mOutputStream;
-
-        public SocketPipeThread(InputStream inputStream, OutputStream outputStream) {
-            mInputStream = inputStream;
-            mOutputStream = outputStream;
-            setName("SocketPipeThread: " + getName());
-        }
-
-        @Override
-        public void run() {
-            byte[] buffer = new byte[4096];
-            int length;
-            while (true) {
-                try {
-                    if ((length = mInputStream.read(buffer)) < 0) {
-                        break;
-                    }
-                    mOutputStream.write(buffer, 0, length);
-                } catch (IOException e) {
-                    /** This exception means one of the streams is closed */
-                    Log.v(LOG_TAG, this.toString(), e);
-                    break;
-                }
-            }
-
-            synchronized (mThreadsRunning) {
-                mThreadsRunning--;
-                if (mThreadsRunning == 0) {
-                    ConnectionHandler.this.stop();
-                    mOnFinishedCallback.onFinished();
-                }
-            }
-        }
-
-        @Override
-        public String toString() {
-            return getName();
-        }
-    }
-
-    private Integer mThreadsRunning;
-
-    private Socket mFromSocket, mToSocket;
-    private SocketPipeThread mFromToPipe, mToFromPipe;
-    private InputStream mFromSocketInputStream, mToSocketInputStream;
-    private OutputStream mFromSocketOutputStream, mToSocketOutputStream;
-
-    private int mPort;
-    private String mRemoteMachineIpAddress;
-
-    private OnFinishedCallback mOnFinishedCallback;
-
-    public ConnectionHandler(String remoteMachineIp, int port, Socket fromSocket, Socket toSocket)
-            throws IOException {
-        mRemoteMachineIpAddress = remoteMachineIp;
-        mPort = port;
-
-        mFromSocket = fromSocket;
-        mToSocket = toSocket;
-
-        try {
-            mFromSocketInputStream = mFromSocket.getInputStream();
-            mToSocketInputStream = mToSocket.getInputStream();
-            mFromSocketOutputStream = mFromSocket.getOutputStream();
-            mToSocketOutputStream = mToSocket.getOutputStream();
-            AdbUtils.configureConnection(mToSocketInputStream, mToSocketOutputStream,
-                    mRemoteMachineIpAddress, mPort);
-        } catch (IOException e) {
-            Log.e(LOG_TAG, "Unable to start ConnectionHandler", e);
-            closeStreams();
-            throw e;
-        }
-
-        mFromToPipe = new SocketPipeThread(mFromSocketInputStream, mToSocketOutputStream);
-        mToFromPipe = new SocketPipeThread(mToSocketInputStream, mFromSocketOutputStream);
-    }
-
-    public void registerOnConnectionHandlerFinishedCallback(OnFinishedCallback callback) {
-        mOnFinishedCallback = callback;
-    }
-
-    private void closeStreams() {
-        FsUtils.closeInputStream(mFromSocketInputStream);
-        FsUtils.closeInputStream(mToSocketInputStream);
-        FsUtils.closeOutputStream(mFromSocketOutputStream);
-        FsUtils.closeOutputStream(mToSocketOutputStream);
-    }
-
-    public void start() {
-        /** We have 2 threads running, one for each pipe, that we start here. */
-        mThreadsRunning = 2;
-        mFromToPipe.start();
-        mToFromPipe.start();
-    }
-
-    public void stop() {
-        shutdown(mFromSocket);
-        shutdown(mToSocket);
-    }
-
-    private void shutdown(Socket socket) {
-        synchronized (mFromToPipe) {
-            synchronized (mToFromPipe) {
-                /** This will stop the while loop in the run method */
-                try {
-                    if (!socket.isInputShutdown()) {
-                        socket.shutdownInput();
-                    }
-                } catch (IOException e) {
-                    Log.e(LOG_TAG, "mFromToPipe=" + mFromToPipe + " mToFromPipe=" + mToFromPipe, e);
-                }
-                try {
-                    if (!socket.isOutputShutdown()) {
-                        socket.shutdownOutput();
-                    }
-                } catch (IOException e) {
-                    Log.e(LOG_TAG, "mFromToPipe=" + mFromToPipe + " mToFromPipe=" + mToFromPipe, e);
-                }
-                try {
-                    if (!socket.isClosed()) {
-                        socket.close();
-                    }
-                } catch (IOException e) {
-                    Log.e(LOG_TAG, "mFromToPipe=" + mFromToPipe + " mToFromPipe=" + mToFromPipe, e);
-                }
-            }
-        }
-    }
-}
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/Forwarder.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/Forwarder.java
deleted file mode 100644
index ce22fa0..0000000
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/Forwarder.java
+++ /dev/null
@@ -1,132 +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.dumprendertree2.forwarder;
-
-import android.util.Log;
-
-import java.io.IOException;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * A port forwarding server. Listens on localhost on specified port and forwards the tcp
- * communications to external socket via adb networking proxy.
- */
-public class Forwarder extends Thread {
-    private static final String LOG_TAG = "Forwarder";
-
-    private int mPort;
-    private String mRemoteMachineIpAddress;
-
-    private ServerSocket mServerSocket;
-
-    private Set<ConnectionHandler> mConnectionHandlers = new HashSet<ConnectionHandler>();
-
-    public Forwarder(int port, String remoteMachineIpAddress) {
-        mPort = port;
-        mRemoteMachineIpAddress = remoteMachineIpAddress;
-    }
-
-    @Override
-    public void start() {
-        Log.i(LOG_TAG, "start(): Starting fowarder on port: " + mPort);
-
-        try {
-            mServerSocket = new ServerSocket(mPort);
-        } catch (IOException e) {
-            Log.e(LOG_TAG, "mPort=" + mPort, e);
-            return;
-        }
-
-        super.start();
-    }
-
-    @Override
-    public void run() {
-        while (true) {
-            Socket localSocket;
-            try {
-                localSocket = mServerSocket.accept();
-            } catch (IOException e) {
-                /** This most likely means that mServerSocket is already closed */
-                Log.w(LOG_TAG, "mPort=" + mPort, e);
-                break;
-            }
-
-            Socket remoteSocket = null;
-            final ConnectionHandler connectionHandler;
-            try {
-                remoteSocket = AdbUtils.createSocket();
-                connectionHandler = new ConnectionHandler(
-                        mRemoteMachineIpAddress, mPort, localSocket, remoteSocket);
-            } catch (IOException exception) {
-                try {
-                    localSocket.close();
-                } catch (IOException e) {
-                    Log.e(LOG_TAG, "mPort=" + mPort, e);
-                }
-                if (remoteSocket != null) {
-                    try {
-                        remoteSocket.close();
-                    } catch (IOException e) {
-                        Log.e(LOG_TAG, "mPort=" + mPort, e);
-                    }
-                }
-                continue;
-            }
-
-            /**
-             * We have to close the sockets after the ConnectionHandler finishes, so we
-             * don't get "Too may open files" exception. We also remove the ConnectionHandler
-             * from the collection to avoid memory issues.
-             * */
-            ConnectionHandler.OnFinishedCallback callback =
-                    new ConnectionHandler.OnFinishedCallback() {
-                @Override
-                public void onFinished() {
-                    synchronized (this) {
-                        if (!mConnectionHandlers.remove(connectionHandler)) {
-                            assert false : "removeConnectionHandler(): not in the collection";
-                        }
-                    }
-                }
-            };
-            connectionHandler.registerOnConnectionHandlerFinishedCallback(callback);
-
-            synchronized (this) {
-                mConnectionHandlers.add(connectionHandler);
-            }
-            connectionHandler.start();
-        }
-
-        synchronized (this) {
-            for (ConnectionHandler connectionHandler : mConnectionHandlers) {
-                connectionHandler.stop();
-            }
-        }
-    }
-
-    public void finish() {
-        try {
-            mServerSocket.close();
-        } catch (IOException e) {
-            Log.e(LOG_TAG, "mPort=" + mPort, e);
-        }
-    }
-}
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/ForwarderManager.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/ForwarderManager.java
deleted file mode 100644
index cff436ff..0000000
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/forwarder/ForwarderManager.java
+++ /dev/null
@@ -1,123 +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.dumprendertree2.forwarder;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-import android.util.Log;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * A simple class to start and stop Forwarders running on some ports.
- *
- * It uses a singleton pattern and is thread safe.
- */
-public class ForwarderManager {
-    private static final String LOG_TAG = "ForwarderManager";
-
-    /**
-     * The IP address of the server serving the tests.
-     */
-    private static final String HOST_IP = "127.0.0.1";
-
-    /**
-     * We use these ports because other webkit platforms do. They are set up in
-     * external/webkit/LayoutTests/http/conf/apache2-debian-httpd.conf
-     */
-    public static final int HTTP_PORT = 8000;
-    public static final int HTTPS_PORT = 8443;
-
-    private static ForwarderManager forwarderManager;
-
-    private Set<Forwarder> mForwarders;
-    private boolean mIsStarted;
-
-    private ForwarderManager() {
-        mForwarders = new HashSet<Forwarder>(2);
-        mForwarders.add(new Forwarder(HTTP_PORT, HOST_IP));
-        mForwarders.add(new Forwarder(HTTPS_PORT, HOST_IP));
-    }
-
-    /**
-     * Returns the main part of the URL with the trailing slash
-     *
-     * @param isHttps
-     * @return
-     */
-    public static final String getHostSchemePort(boolean isHttps) {
-        int port;
-        String protocol;
-        if (isHttps) {
-            protocol = "https";
-            port = HTTPS_PORT;
-        } else {
-            protocol = "http";
-            port = HTTP_PORT;
-        }
-
-        URL url = null;
-        try {
-            url = new URL(protocol, HOST_IP, port, "/");
-        } catch (MalformedURLException e) {
-            assert false : "isHttps=" + isHttps;
-        }
-
-        return url.toString();
-    }
-
-    public static synchronized ForwarderManager getForwarderManager() {
-        if (forwarderManager == null) {
-            forwarderManager = new ForwarderManager();
-        }
-        return forwarderManager;
-    }
-
-    @Override
-    public Object clone() throws CloneNotSupportedException {
-        throw new CloneNotSupportedException();
-    }
-
-    public synchronized void start() {
-        if (mIsStarted) {
-            Log.w(LOG_TAG, "start(): ForwarderManager already running! NOOP.");
-            return;
-        }
-
-        for (Forwarder forwarder : mForwarders) {
-            forwarder.start();
-        }
-
-        mIsStarted = true;
-        Log.i(LOG_TAG, "ForwarderManager started.");
-    }
-
-    public synchronized void stop() {
-        if (!mIsStarted) {
-            Log.w(LOG_TAG, "stop(): ForwarderManager already stopped! NOOP.");
-            return;
-        }
-
-        for (Forwarder forwarder : mForwarders) {
-            forwarder.finish();
-        }
-
-        mIsStarted = false;
-        Log.i(LOG_TAG, "ForwarderManager stopped.");
-    }
-}
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/scriptsupport/OnEverythingFinishedCallback.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/scriptsupport/OnEverythingFinishedCallback.java
deleted file mode 100644
index e1d4364..0000000
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/scriptsupport/OnEverythingFinishedCallback.java
+++ /dev/null
@@ -1,25 +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.dumprendertree2.scriptsupport;
-
-/**
- * Callback used to inform scriptsupport.Starter that everything is finished and
- * we can exit
- */
-public interface OnEverythingFinishedCallback {
-    public void onFinished();
-}
\ No newline at end of file
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/scriptsupport/ScriptTestRunner.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/scriptsupport/ScriptTestRunner.java
deleted file mode 100644
index 78f58d5..0000000
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/scriptsupport/ScriptTestRunner.java
+++ /dev/null
@@ -1,37 +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.dumprendertree2.scriptsupport;
-
-import android.os.Bundle;
-import android.test.InstrumentationTestRunner;
-
-/**
- * Extends InstrumentationTestRunner to allow the script to pass arguments to the application
- */
-public class ScriptTestRunner extends InstrumentationTestRunner {
-    String mTestsRelativePath;
-
-    @Override
-    public void onCreate(Bundle arguments) {
-        mTestsRelativePath = arguments.getString("path");
-        super.onCreate(arguments);
-    }
-
-    public String getTestsRelativePath() {
-        return mTestsRelativePath;
-    }
-}
\ No newline at end of file
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/scriptsupport/Starter.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/scriptsupport/Starter.java
deleted file mode 100644
index 6f41a0f..0000000
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/scriptsupport/Starter.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 com.android.dumprendertree2.scriptsupport;
-
-import android.content.Intent;
-import android.test.ActivityInstrumentationTestCase2;
-import android.util.Log;
-
-import com.android.dumprendertree2.TestsListActivity;
-import com.android.dumprendertree2.forwarder.ForwarderManager;
-
-/**
- * A class which provides methods that can be invoked by a script running on the host machine to
- * run the tests.
- *
- * It starts a TestsListActivity and does not return until all the tests finish executing.
- */
-public class Starter extends ActivityInstrumentationTestCase2<TestsListActivity> {
-    private static final String LOG_TAG = "Starter";
-    private boolean mEverythingFinished;
-
-    public Starter() {
-        super(TestsListActivity.class);
-    }
-
-    /**
-     * This method is called from adb to start executing the tests. It doesn't return
-     * until everything is finished so that the script can wait for the end if it needs
-     * to.
-     */
-    public void startLayoutTests() {
-        ScriptTestRunner runner = (ScriptTestRunner)getInstrumentation();
-        String relativePath = runner.getTestsRelativePath();
-
-        ForwarderManager.getForwarderManager().start();
-
-        Intent intent = new Intent();
-        intent.setClassName("com.android.dumprendertree2", "TestsListActivity");
-        intent.setAction(Intent.ACTION_RUN);
-        intent.putExtra(TestsListActivity.EXTRA_TEST_PATH, relativePath);
-        setActivityIntent(intent);
-        getActivity().registerOnEverythingFinishedCallback(new OnEverythingFinishedCallback() {
-            /** This method is safe to call on any thread */
-            @Override
-            public void onFinished() {
-                synchronized (Starter.this) {
-                    mEverythingFinished = true;
-                    Starter.this.notifyAll();
-                }
-            }
-        });
-
-        synchronized (this) {
-            while (!mEverythingFinished) {
-                try {
-                    this.wait();
-                } catch (InterruptedException e) {
-                    Log.e(LOG_TAG, "startLayoutTests()", e);
-                }
-            }
-        }
-
-        ForwarderManager.getForwarderManager().stop();
-    }
-}
\ No newline at end of file
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/ui/DirListActivity.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/ui/DirListActivity.java
deleted file mode 100644
index 5de69a7..0000000
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/ui/DirListActivity.java
+++ /dev/null
@@ -1,426 +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.dumprendertree2.ui;
-
-import com.android.dumprendertree2.FileFilter;
-import com.android.dumprendertree2.FsUtils;
-import com.android.dumprendertree2.TestsListActivity;
-import com.android.dumprendertree2.R;
-import com.android.dumprendertree2.forwarder.ForwarderManager;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.ListActivity;
-import android.app.ProgressDialog;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.os.Bundle;
-import android.os.Environment;
-import android.os.Handler;
-import android.os.Message;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.ImageView;
-import android.widget.ListView;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * An Activity that allows navigating through tests folders and choosing folders or tests to run.
- */
-public class DirListActivity extends ListActivity {
-
-    private static final String LOG_TAG = "DirListActivity";
-
-    /** TODO: This is just a guess - think of a better way to achieve it */
-    private static final int MEAN_TITLE_CHAR_SIZE = 13;
-
-    private static final int PROGRESS_DIALOG_DELAY_MS = 200;
-
-    /** Code for the dialog, used in showDialog and onCreateDialog */
-    private static final int DIALOG_RUN_ABORT_DIR = 0;
-
-    /** Messages codes */
-    private static final int MSG_LOADED_ITEMS = 0;
-    private static final int MSG_SHOW_PROGRESS_DIALOG = 1;
-
-    private static final CharSequence NO_RESPONSE_MESSAGE =
-            "No response from host when getting directory contents. Is the host server running?";
-
-    /** Initialized lazily before first sProgressDialog.show() */
-    private static ProgressDialog sProgressDialog;
-
-    private ListView mListView;
-
-    /** This is a relative path! */
-    private String mCurrentDirPath;
-
-    /**
-     * A thread responsible for loading the contents of the directory from sd card
-     * and sending them via Message to main thread that then loads them into
-     * ListView
-     */
-    private class LoadListItemsThread extends Thread {
-        private Handler mHandler;
-        private String mRelativePath;
-
-        public LoadListItemsThread(String relativePath, Handler handler) {
-            mRelativePath = relativePath;
-            mHandler = handler;
-        }
-
-        @Override
-        public void run() {
-            Message msg = mHandler.obtainMessage(MSG_LOADED_ITEMS);
-            msg.obj = getDirList(mRelativePath);
-            mHandler.sendMessage(msg);
-        }
-    }
-
-    /**
-     * Very simple object to use inside ListView as an item.
-     */
-    private static class ListItem implements Comparable<ListItem> {
-        private String mRelativePath;
-        private String mName;
-        private boolean mIsDirectory;
-
-        public ListItem(String relativePath, boolean isDirectory) {
-            mRelativePath = relativePath;
-            mName = new File(relativePath).getName();
-            mIsDirectory = isDirectory;
-        }
-
-        public boolean isDirectory() {
-            return mIsDirectory;
-        }
-
-        public String getRelativePath() {
-            return mRelativePath;
-        }
-
-        public String getName() {
-            return mName;
-        }
-
-        @Override
-        public int compareTo(ListItem another) {
-            return mRelativePath.compareTo(another.getRelativePath());
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (!(o instanceof ListItem)) {
-                return false;
-            }
-
-            return mRelativePath.equals(((ListItem)o).getRelativePath());
-        }
-
-        @Override
-        public int hashCode() {
-            return mRelativePath.hashCode();
-        }
-
-    }
-
-    /**
-     * A custom adapter that sets the proper icon and label in the list view.
-     */
-    private static class DirListAdapter extends ArrayAdapter<ListItem> {
-        private Activity mContext;
-        private ListItem[] mItems;
-
-        public DirListAdapter(Activity context, ListItem[] items) {
-            super(context, R.layout.dirlist_row, items);
-
-            mContext = context;
-            mItems = items;
-        }
-
-        @Override
-        public View getView(int position, View convertView, ViewGroup parent) {
-            LayoutInflater inflater = mContext.getLayoutInflater();
-            View row = inflater.inflate(R.layout.dirlist_row, null);
-
-            TextView label = (TextView)row.findViewById(R.id.label);
-            label.setText(mItems[position].getName());
-
-            ImageView icon = (ImageView)row.findViewById(R.id.icon);
-            if (mItems[position].isDirectory()) {
-                icon.setImageResource(R.drawable.folder);
-            } else {
-                icon.setImageResource(R.drawable.runtest);
-            }
-
-            return row;
-        }
-    }
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        ForwarderManager.getForwarderManager().start();
-
-        mListView = getListView();
-
-        mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
-            @Override
-            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-                ListItem item = (ListItem)parent.getItemAtPosition(position);
-
-                if (item.isDirectory()) {
-                    showDir(item.getRelativePath());
-                } else {
-                    /** Run the test */
-                    runAllTestsUnder(item.getRelativePath());
-                }
-            }
-        });
-
-        mListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
-            @Override
-            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
-                ListItem item = (ListItem)parent.getItemAtPosition(position);
-
-                if (item.isDirectory()) {
-                    Bundle arguments = new Bundle(1);
-                    arguments.putString("name", item.getName());
-                    arguments.putString("relativePath", item.getRelativePath());
-                    showDialog(DIALOG_RUN_ABORT_DIR, arguments);
-                } else {
-                    /** TODO: Maybe show some info about a test? */
-                }
-
-                return true;
-            }
-        });
-
-        /** All the paths are relative to test root dir where possible */
-        showDir("");
-    }
-
-    private void runAllTestsUnder(String relativePath) {
-        Intent intent = new Intent();
-        intent.setClass(DirListActivity.this, TestsListActivity.class);
-        intent.setAction(Intent.ACTION_RUN);
-        intent.putExtra(TestsListActivity.EXTRA_TEST_PATH, relativePath);
-        startActivity(intent);
-    }
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        MenuInflater inflater = getMenuInflater();
-        inflater.inflate(R.menu.gui_menu, menu);
-        return true;
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-            case R.id.run_all:
-                runAllTestsUnder(mCurrentDirPath);
-                return true;
-            default:
-                return super.onOptionsItemSelected(item);
-        }
-    }
-
-    @Override
-    /**
-     * Moves to the parent directory if one exists. Does not allow to move above
-     * the test 'root' directory.
-     */
-    public void onBackPressed() {
-        File currentDirParent = new File(mCurrentDirPath).getParentFile();
-        if (currentDirParent != null) {
-            showDir(currentDirParent.getPath());
-        } else {
-            showDir("");
-        }
-    }
-
-    /**
-     * Prevents the activity from recreating on change of orientation. The title needs to
-     * be recalculated.
-     */
-    @Override
-    public void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-
-        setTitle(shortenTitle(mCurrentDirPath));
-    }
-
-    @Override
-    protected Dialog onCreateDialog(int id, final Bundle args) {
-        Dialog dialog = null;
-        AlertDialog.Builder builder = new AlertDialog.Builder(this);
-
-        switch (id) {
-            case DIALOG_RUN_ABORT_DIR:
-                builder.setTitle(getText(R.string.dialog_run_abort_dir_title_prefix) + " " +
-                        args.getString("name"));
-                builder.setMessage(R.string.dialog_run_abort_dir_msg);
-                builder.setCancelable(true);
-
-                builder.setPositiveButton(R.string.dialog_run_abort_dir_ok_button,
-                        new DialogInterface.OnClickListener() {
-                    @Override
-                    public void onClick(DialogInterface dialog, int which) {
-                        removeDialog(DIALOG_RUN_ABORT_DIR);
-                        runAllTestsUnder(args.getString("relativePath"));
-                    }
-                });
-
-                builder.setNegativeButton(R.string.dialog_run_abort_dir_abort_button,
-                        new DialogInterface.OnClickListener() {
-                    @Override
-                    public void onClick(DialogInterface dialog, int which) {
-                        removeDialog(DIALOG_RUN_ABORT_DIR);
-                    }
-                });
-
-                dialog = builder.create();
-                dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
-                    @Override
-                    public void onCancel(DialogInterface dialog) {
-                        removeDialog(DIALOG_RUN_ABORT_DIR);
-                    }
-                });
-                break;
-        }
-
-        return dialog;
-    }
-
-    /**
-     * Loads the contents of dir into the list view.
-     *
-     * @param dirPath
-     *      directory to load into list view
-     */
-    private void showDir(String dirPath) {
-        mCurrentDirPath = dirPath;
-
-        /** Show progress dialog with a delay */
-        final Handler delayedDialogHandler = new Handler() {
-            @Override
-            public void handleMessage(Message msg) {
-                if (msg.what == MSG_SHOW_PROGRESS_DIALOG) {
-                    if (sProgressDialog == null) {
-                        sProgressDialog = new ProgressDialog(DirListActivity.this);
-                        sProgressDialog.setCancelable(false);
-                        sProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
-                        sProgressDialog.setTitle(R.string.dialog_progress_title);
-                        sProgressDialog.setMessage(getText(R.string.dialog_progress_msg));
-                    }
-                    sProgressDialog.show();
-                }
-            }
-        };
-        Message msgShowDialog = delayedDialogHandler.obtainMessage(MSG_SHOW_PROGRESS_DIALOG);
-        delayedDialogHandler.sendMessageDelayed(msgShowDialog, PROGRESS_DIALOG_DELAY_MS);
-
-        /** Delegate loading contents from SD card to a new thread */
-        new LoadListItemsThread(mCurrentDirPath, new Handler() {
-            @Override
-            public void handleMessage(Message msg) {
-                if (msg.what == MSG_LOADED_ITEMS) {
-                    setTitle(shortenTitle(mCurrentDirPath));
-                    delayedDialogHandler.removeMessages(MSG_SHOW_PROGRESS_DIALOG);
-                    if (sProgressDialog != null) {
-                        sProgressDialog.dismiss();
-                    }
-                    if (msg.obj == null) {
-                        Toast.makeText(DirListActivity.this, NO_RESPONSE_MESSAGE,
-                                Toast.LENGTH_LONG).show();
-                    } else {
-                        setListAdapter(new DirListAdapter(DirListActivity.this,
-                                (ListItem[])msg.obj));
-                    }
-                }
-            }
-        }).start();
-    }
-
-    /**
-     * TODO: find a neat way to determine number of characters that fit in the title
-     * bar.
-     * */
-    private String shortenTitle(String title) {
-        if (title.equals("")) {
-            return "Tests' root dir:";
-        }
-        int charCount = mListView.getWidth() / MEAN_TITLE_CHAR_SIZE;
-
-        if (title.length() > charCount) {
-            return "..." + title.substring(title.length() - charCount);
-        } else {
-            return title;
-        }
-    }
-
-    /**
-     * Return the array with contents of the given directory.
-     * First it contains the subfolders, then the files. Both sorted
-     * alphabetically.
-     *
-     * The dirPath is relative.
-     */
-    private ListItem[] getDirList(String dirPath) {
-        List<ListItem> subDirs = new ArrayList<ListItem>();
-        List<ListItem> subFiles = new ArrayList<ListItem>();
-
-        List<String> dirRelativePaths = FsUtils.getLayoutTestsDirContents(dirPath, false, true);
-        if (dirRelativePaths == null) {
-            return null;
-        }
-        for (String dirRelativePath : dirRelativePaths) {
-            if (FileFilter.isTestDir(new File(dirRelativePath).getName())) {
-                subDirs.add(new ListItem(dirRelativePath, true));
-            }
-        }
-
-        List<String> testRelativePaths = FsUtils.getLayoutTestsDirContents(dirPath, false, false);
-        if (testRelativePaths == null) {
-            return null;
-        }
-        for (String testRelativePath : testRelativePaths) {
-            if (FileFilter.isTestFile(new File(testRelativePath).getName())) {
-                subFiles.add(new ListItem(testRelativePath, false));
-            }
-        }
-
-        /** Concatenate the two lists */
-        subDirs.addAll(subFiles);
-
-        return subDirs.toArray(new ListItem[subDirs.size()]);
-    }
-}
diff --git a/tests/FrameworkPerf/src/com/android/frameworkperf/TestService.java b/tests/FrameworkPerf/src/com/android/frameworkperf/TestService.java
index 5f4f006..309ce34 100644
--- a/tests/FrameworkPerf/src/com/android/frameworkperf/TestService.java
+++ b/tests/FrameworkPerf/src/com/android/frameworkperf/TestService.java
@@ -21,7 +21,11 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.RandomAccessFile;
+import java.lang.String;
+import java.util.HashMap;
+import java.util.Random;
 
+import android.util.ArrayMap;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -142,6 +146,18 @@
             new LoadRecycleLargeBitmapOp(),
             new LoadSmallScaledBitmapOp(),
             new LoadLargeScaledBitmapOp(),
+            new GrowTinyHashMapOp(),
+            new GrowTinyArrayMapOp(),
+            new GrowSmallHashMapOp(),
+            new GrowSmallArrayMapOp(),
+            new GrowLargeHashMapOp(),
+            new GrowLargeArrayMapOp(),
+            new LookupTinyHashMapOp(),
+            new LookupTinyArrayMapOp(),
+            new LookupSmallHashMapOp(),
+            new LookupSmallArrayMapOp(),
+            new LookupLargeHashMapOp(),
+            new LookupLargeArrayMapOp(),
     };
 
     static final int CMD_START_TEST = 1;
@@ -1111,4 +1127,196 @@
             mFile.delete();
         }
     }
+
+    static abstract class GenericMapOp extends Op {
+        final int mSize;
+        String[] mKeys;
+        String[] mValues;
+
+        GenericMapOp(String name, String longName, int size) {
+            super(name, longName);
+            mSize = size;
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mKeys = new String[mSize];
+            mValues = new String[mSize];
+            Random random = new Random(0);
+            for (int i=0; i<mSize; i++) {
+                int chars = random.nextInt(10);
+                StringBuilder builder = new StringBuilder(chars);
+                for (int j=0; j<chars; j++) {
+                    builder.append('a' + random.nextInt(100));
+                }
+                mKeys[i] = builder.toString();
+                mValues[i] = Integer.toString(i);
+            }
+        }
+
+        int getOpsPerRun() {
+            return mSize;
+        }
+    }
+
+    static class GrowTinyHashMapOp extends GenericMapOp {
+        GrowTinyHashMapOp() {
+            super("GrowTinyHashMap", "Add 5 items to a HashMap", 5);
+        }
+
+        boolean onRun() {
+            HashMap<String, String> map = new HashMap<String, String>();
+            for (int i=0; i<mSize; i++) {
+                map.put(mKeys[i], mValues[i]);
+            }
+            return true;
+        }
+    }
+
+    static class GrowTinyArrayMapOp extends GenericMapOp {
+        GrowTinyArrayMapOp() {
+            super("GrowTinyArrayMap", "Add 5 items to a ArrayMap", 5);
+        }
+
+        boolean onRun() {
+            ArrayMap<String, String> map = new ArrayMap<String, String>();
+            for (int i=0; i<mSize; i++) {
+                map.put(mKeys[i], mValues[i]);
+            }
+            return true;
+        }
+    }
+
+    static class GrowSmallHashMapOp extends GenericMapOp {
+        GrowSmallHashMapOp() {
+            super("GrowSmallHashMap", "Add 100 items to a HashMap", 100);
+        }
+
+        boolean onRun() {
+            HashMap<String, String> map = new HashMap<String, String>();
+            for (int i=0; i<mSize; i++) {
+                map.put(mKeys[i], mValues[i]);
+            }
+            return true;
+        }
+    }
+
+    static class GrowSmallArrayMapOp extends GenericMapOp {
+        GrowSmallArrayMapOp() {
+            super("GrowSmallArrayMap", "Add 100 items to a ArrayMap", 100);
+        }
+
+        boolean onRun() {
+            ArrayMap<String, String> map = new ArrayMap<String, String>();
+            for (int i=0; i<mSize; i++) {
+                map.put(mKeys[i], mValues[i]);
+            }
+            return true;
+        }
+    }
+
+    static class GrowLargeHashMapOp extends GenericMapOp {
+        GrowLargeHashMapOp() {
+            super("GrowLargeHashMap", "Add 10000 items to a HashMap", 10000);
+        }
+
+        boolean onRun() {
+            HashMap<String, String> map = new HashMap<String, String>();
+            for (int i=0; i<mSize; i++) {
+                map.put(mKeys[i], mValues[i]);
+            }
+            return true;
+        }
+    }
+
+    static class GrowLargeArrayMapOp extends GenericMapOp {
+        GrowLargeArrayMapOp() {
+            super("GrowLargeArrayMap", "Add 10000 items to a ArrayMap", 10000);
+        }
+
+        boolean onRun() {
+            ArrayMap<String, String> map = new ArrayMap<String, String>();
+            for (int i=0; i<mSize; i++) {
+                map.put(mKeys[i], mValues[i]);
+            }
+            return true;
+        }
+    }
+
+    static class LookupTinyHashMapOp extends LookupSmallHashMapOp {
+        LookupTinyHashMapOp() {
+            super("LookupTinyHashMap", "Lookup items in 5 entry HashMap", 5);
+        }
+    }
+
+    static class LookupTinyArrayMapOp extends LookupSmallArrayMapOp {
+        LookupTinyArrayMapOp() {
+            super("LookupTinyArrayMap", "Lookup items in 5 entry ArrayMap", 5);
+        }
+    }
+
+    static class LookupSmallHashMapOp extends GenericMapOp {
+        HashMap<String, String> mHashMap;
+
+        LookupSmallHashMapOp() {
+            super("LookupSmallHashMap", "Lookup items in 100 entry HashMap", 100);
+        }
+
+        LookupSmallHashMapOp(String name, String longname, int size) {
+            super(name, longname, size);
+        }
+
+        void onInit(Context context, boolean foreground) {
+            super.onInit(context, foreground);
+            mHashMap = new HashMap<String, String>();
+            for (int i=0; i<mSize; i++) {
+                mHashMap.put(mKeys[i], mValues[i]);
+            }
+        }
+
+        boolean onRun() {
+            for (int i=0; i<mSize; i++) {
+                mHashMap.get(mKeys[i]);
+            }
+            return true;
+        }
+    }
+
+    static class LookupSmallArrayMapOp extends GenericMapOp {
+        ArrayMap<String, String> mArrayMap;
+
+        LookupSmallArrayMapOp() {
+            super("LookupSmallArrayMap", "Lookup items in 100 entry ArrayMap", 100);
+        }
+
+        LookupSmallArrayMapOp(String name, String longname, int size) {
+            super(name, longname, size);
+        }
+
+        void onInit(Context context, boolean foreground) {
+            super.onInit(context, foreground);
+            mArrayMap = new ArrayMap<String, String>();
+            for (int i=0; i<mSize; i++) {
+                mArrayMap.put(mKeys[i], mValues[i]);
+            }
+        }
+
+        boolean onRun() {
+            for (int i=0; i<mSize; i++) {
+                mArrayMap.get(mKeys[i]);
+            }
+            return true;
+        }
+    }
+
+    static class LookupLargeHashMapOp extends LookupSmallHashMapOp {
+        LookupLargeHashMapOp() {
+            super("LookupLargeHashMap", "Lookup items in 10000 entry HashMap", 10000);
+        }
+    }
+
+    static class LookupLargeArrayMapOp extends LookupSmallArrayMapOp {
+        LookupLargeArrayMapOp() {
+            super("LookupLargeArrayMap", "Lookup items in 10000 entry ArrayMap", 10000);
+        }
+    }
 }
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index 46a539e..1bb0db0 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -41,6 +41,26 @@
         </activity>
 
         <activity
+                android:name="PathOpsActivity"
+                android:label="Path/Ops"
+                android:theme="@android:style/Theme.Holo.Light">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="com.android.test.hwui.TEST" />
+            </intent-filter>
+        </activity>
+
+        <activity
+                android:name="AssetsAtlasActivity"
+                android:label="Atlas/Framework"
+                android:theme="@android:style/Theme.Holo.Light">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="com.android.test.hwui.TEST" />
+            </intent-filter>
+        </activity>
+
+        <activity
                 android:name="ScaledTextActivity"
                 android:label="Text/Scaled"
                 android:theme="@android:style/Theme.Holo.Light">
@@ -725,7 +745,7 @@
                 android:name="PathsCacheActivity"
                 android:label="Path/Cache">
             <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
+                <action android:name="android.intent.action.MAIN" />`
                 <category android:name="com.android.test.hwui.TEST" />
             </intent-filter>
         </activity>
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/AssetsAtlasActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/AssetsAtlasActivity.java
new file mode 100644
index 0000000..df7e3bb
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/AssetsAtlasActivity.java
@@ -0,0 +1,66 @@
+/*
+ * 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.test.hwui;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.view.View;
+import com.android.internal.R;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class AssetsAtlasActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(new BitmapsView(this));
+    }
+
+    static class BitmapsView extends View {
+        private final Bitmap mBitmap;
+
+        BitmapsView(Context c) {
+            super(c);
+
+            Drawable d = c.getResources().getDrawable(R.drawable.text_select_handle_left);
+            mBitmap = ((BitmapDrawable) d).getBitmap();
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            super.onDraw(canvas);
+
+            final Matrix matrix = new Matrix();
+            matrix.setScale(0.5f, 0.5f);
+
+            final Rect src = new Rect(0, 0, mBitmap.getWidth() / 2, mBitmap.getHeight() / 2);
+            final Rect dst = new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
+
+            canvas.drawBitmap(mBitmap, 0.0f, 0.0f, null);
+            canvas.translate(0.0f, mBitmap.getHeight());
+            canvas.drawBitmap(mBitmap, matrix, null);
+            canvas.translate(0.0f, mBitmap.getHeight());
+            canvas.drawBitmap(mBitmap, src, dst, null);
+        }
+    }
+}
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ClipRegion2Activity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ClipRegion2Activity.java
index 066e35c..fe4d602 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/ClipRegion2Activity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ClipRegion2Activity.java
@@ -48,7 +48,7 @@
     }
 
     public static class RegionView extends FrameLayout {
-        private final Region mRegion = new Region();
+        private Region mRegion = new Region();
         private float mClipPosition = 0.0f;
 
         public RegionView(Context c) {
@@ -69,9 +69,7 @@
 
             canvas.save();
 
-            mRegion.setEmpty();
-            mRegion.op(0, 0, getWidth(), getHeight(),
-                    Region.Op.REPLACE);
+            mRegion.set(0, 0, getWidth(), getHeight());
             mRegion.op(getWidth() / 4, getHeight() / 4, 3 * getWidth() / 4, 3 * getHeight() / 4,
                     Region.Op.DIFFERENCE);
 
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ListActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ListActivity.java
index 13b6129..db6421e 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/ListActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ListActivity.java
@@ -20,19 +20,15 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.os.Bundle;
-import android.os.Environment;
 import android.util.DisplayMetrics;
 import android.view.ContextMenu;
 import android.view.View;
-import android.view.ViewDebug;
 import android.view.ViewGroup;
 import android.widget.ArrayAdapter;
 import android.widget.ListAdapter;
 import android.widget.ListView;
 import android.widget.TextView;
 
-import java.io.File;
-
 @SuppressWarnings({"UnusedDeclaration"})
 public class ListActivity extends Activity {
     private static final String[] DATA_LIST = {
@@ -86,7 +82,7 @@
 
         ListAdapter adapter = new SimpleListAdapter(this);
 
-        ListView list = (ListView) findViewById(R.id.list);
+        final ListView list = (ListView) findViewById(R.id.list);
         list.setAdapter(adapter);
         
         registerForContextMenu(list);
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/PathOpsActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/PathOpsActivity.java
new file mode 100644
index 0000000..b9927ac
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/PathOpsActivity.java
@@ -0,0 +1,87 @@
+/*
+ * 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.test.hwui;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class PathOpsActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        final PathsView view = new PathsView(this);
+        setContentView(view);
+    }
+
+    public static class PathsView extends View {
+        private final Paint mPaint;
+        private Path[] mPaths;
+        private float mSize;
+
+
+        public PathsView(Context c) {
+            super(c);
+
+            mPaint = new Paint();
+            mPaint.setAntiAlias(true);
+            mPaint.setStyle(Paint.Style.FILL);
+            mPaint.setColor(Color.RED);
+        }
+
+        @Override
+        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+            super.onSizeChanged(w, h, oldw, oldh);
+
+            Path.Op[] ops = Path.Op.values();
+            mPaths = new Path[ops.length];
+
+            mSize = w / (ops.length * 2.0f);
+
+            Path p1 = new Path();
+            p1.addRect(0.0f, 0.0f, mSize, mSize, Path.Direction.CW);
+
+            Path p2 = new Path();
+            p2.addCircle(mSize, mSize, mSize / 2.0f, Path.Direction.CW);
+
+            for (int i = 0; i < ops.length; i++) {
+                mPaths[i] = new Path();
+                if (!mPaths[i].op(p1, p2, ops[i])) {
+                    Log.d("PathOps", ops[i].name() + " failed!");
+                }
+            }
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            super.onDraw(canvas);
+
+            canvas.translate(mSize * 0.2f, getHeight() / 2.0f);
+            for (Path path : mPaths) {
+                canvas.drawPath(path, mPaint);
+                canvas.translate(mSize * 1.8f, 0.0f);
+            }
+        }
+    }
+}
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/PathsCacheActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/PathsCacheActivity.java
index 9f97311..c1e7f4a 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/PathsCacheActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/PathsCacheActivity.java
@@ -88,8 +88,6 @@
         @Override
         protected void onDraw(Canvas canvas) {
             super.onDraw(canvas);
-            
-            Log.d("OpenGLRenderer", "Start frame");
 
             canvas.drawARGB(255, 255, 255, 255);
 
@@ -104,6 +102,13 @@
             canvas.drawPath(mPath, mMediumPaint);
             canvas.drawPath(mPath, mMediumPaint);
 
+            mPath.reset();
+            buildPath(mPath);
+
+            canvas.translate(30.0f, 30.0f);
+            canvas.drawPath(mPath, mMediumPaint);
+            canvas.drawPath(mPath, mMediumPaint);
+
             canvas.restore();
 
             for (int i = 0; i < mRandom.nextInt(20); i++) {
diff --git a/tests/RenderScriptTests/Fountain/src/com/example/android/rs/fountain/FountainView.java b/tests/RenderScriptTests/Fountain/src/com/example/android/rs/fountain/FountainView.java
index ba09421..98cec55 100644
--- a/tests/RenderScriptTests/Fountain/src/com/example/android/rs/fountain/FountainView.java
+++ b/tests/RenderScriptTests/Fountain/src/com/example/android/rs/fountain/FountainView.java
@@ -20,7 +20,7 @@
 import java.util.ArrayList;
 import java.util.concurrent.Semaphore;
 
-import android.renderscript.RSTextureView;
+import android.renderscript.RSSurfaceView;
 import android.renderscript.RenderScript;
 import android.renderscript.RenderScriptGL;
 
@@ -39,7 +39,7 @@
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 
-public class FountainView extends RSTextureView {
+public class FountainView extends RSSurfaceView {
 
     public FountainView(Context context) {
         super(context);
@@ -49,13 +49,12 @@
     private RenderScriptGL mRS;
     private FountainRS mRender;
 
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        android.util.Log.e("rs", "onAttachedToWindow");
+    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+        super.surfaceChanged(holder, format, w, h);
         if (mRS == null) {
             RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
             mRS = createRenderScriptGL(sc);
+            mRS.setSurface(holder, w, h);
             mRender = new FountainRS();
             mRender.init(mRS, getResources());
         }
@@ -63,8 +62,6 @@
 
     @Override
     protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        android.util.Log.e("rs", "onDetachedFromWindow");
         if (mRS != null) {
             mRS = null;
             destroyRenderScriptGL();
diff --git a/tests/RenderScriptTests/FountainFbo/src/com/example/android/rs/fountainfbo/FountainFboView.java b/tests/RenderScriptTests/FountainFbo/src/com/example/android/rs/fountainfbo/FountainFboView.java
index 6e40da3..8636717 100644
--- a/tests/RenderScriptTests/FountainFbo/src/com/example/android/rs/fountainfbo/FountainFboView.java
+++ b/tests/RenderScriptTests/FountainFbo/src/com/example/android/rs/fountainfbo/FountainFboView.java
@@ -17,12 +17,13 @@
 package com.example.android.rs.fountainfbo;
 
 
-import android.renderscript.RSTextureView;
+import android.renderscript.RSSurfaceView;
 import android.renderscript.RenderScriptGL;
 import android.content.Context;
+import android.view.SurfaceHolder;
 import android.view.MotionEvent;
 
-public class FountainFboView extends RSTextureView {
+public class FountainFboView extends RSSurfaceView {
 
     public FountainFboView(Context context) {
         super(context);
@@ -31,13 +32,12 @@
     private RenderScriptGL mRS;
     private FountainFboRS mRender;
 
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        android.util.Log.e("rs", "onAttachedToWindow");
+    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+        super.surfaceChanged(holder, format, w, h);
         if (mRS == null) {
             RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
             mRS = createRenderScriptGL(sc);
+            mRS.setSurface(holder, w, h);
             mRender = new FountainFboRS();
             mRender.init(mRS, getResources());
         }
diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/PerformanceTest.java b/tests/TileBenchmark/src/com/test/tilebenchmark/PerformanceTest.java
deleted file mode 100644
index 5763ad3..0000000
--- a/tests/TileBenchmark/src/com/test/tilebenchmark/PerformanceTest.java
+++ /dev/null
@@ -1,320 +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.test.tilebenchmark;
-
-import com.test.tilebenchmark.ProfileActivity.ProfileCallback;
-
-import java.io.File;
-import java.util.HashMap;
-import java.util.Map;
-
-import android.content.res.Resources;
-import android.os.Bundle;
-import android.os.Environment;
-import android.test.ActivityInstrumentationTestCase2;
-import android.util.Log;
-import android.webkit.WebSettings;
-import android.widget.Spinner;
-
-public class PerformanceTest extends
-        ActivityInstrumentationTestCase2<ProfileActivity> {
-
-    public static class AnimStat {
-        double aggVal = 0;
-        double aggSqrVal = 0;
-        double count = 0;
-    }
-
-    private class StatAggregator extends PlaybackGraphs {
-        private HashMap<String, Double> mDataMap = new HashMap<String, Double>();
-        private HashMap<String, AnimStat> mAnimDataMap = new HashMap<String, AnimStat>();
-        private int mCount = 0;
-
-
-        public void aggregate() {
-            boolean inAnimTests = mAnimTests != null;
-            Resources resources = mWeb.getResources();
-            String animFramerateString = resources.getString(R.string.animation_framerate);
-            for (Map.Entry<String, Double> e : mSingleStats.entrySet()) {
-                String name = e.getKey();
-                if (inAnimTests) {
-                    if (name.equals(animFramerateString)) {
-                        // in animation testing phase, record animation framerate and aggregate
-                        // stats, differentiating on values of mAnimTestNr and mDoubleBuffering
-                        String fullName = ANIM_TEST_NAMES[mAnimTestNr] + " " + name;
-                        fullName += mDoubleBuffering ? " tiled" : " webkit";
-
-                        if (!mAnimDataMap.containsKey(fullName)) {
-                            mAnimDataMap.put(fullName, new AnimStat());
-                        }
-                        AnimStat statVals = mAnimDataMap.get(fullName);
-                        statVals.aggVal += e.getValue();
-                        statVals.aggSqrVal += e.getValue() * e.getValue();
-                        statVals.count += 1;
-                    }
-                } else {
-                    double aggVal = mDataMap.containsKey(name)
-                            ? mDataMap.get(name) : 0;
-                    mDataMap.put(name, aggVal + e.getValue());
-                }
-            }
-
-            if (inAnimTests) {
-                return;
-            }
-
-            mCount++;
-            for (int metricIndex = 0; metricIndex < Metrics.length; metricIndex++) {
-                for (int statIndex = 0; statIndex < Stats.length; statIndex++) {
-                    String metricLabel = resources.getString(
-                            Metrics[metricIndex].getLabelId());
-                    String statLabel = resources.getString(
-                            Stats[statIndex].getLabelId());
-
-                    String label = metricLabel + " " + statLabel;
-                    double aggVal = mDataMap.containsKey(label) ? mDataMap
-                            .get(label) : 0;
-
-                    aggVal += mStats[metricIndex][statIndex];
-                    mDataMap.put(label, aggVal);
-                }
-            }
-
-        }
-
-        // build the final bundle of results
-        public Bundle getBundle() {
-            Bundle b = new Bundle();
-            int count = (0 == mCount) ? Integer.MAX_VALUE : mCount;
-            for (Map.Entry<String, Double> e : mDataMap.entrySet()) {
-                b.putDouble(e.getKey(), e.getValue() / count);
-            }
-
-            for (Map.Entry<String, AnimStat> e : mAnimDataMap.entrySet()) {
-                String statName = e.getKey();
-                AnimStat statVals = e.getValue();
-
-                double avg = statVals.aggVal/statVals.count;
-                double stdDev = Math.sqrt((statVals.aggSqrVal / statVals.count) - avg * avg);
-
-                b.putDouble(statName, avg);
-                b.putDouble(statName + " STD DEV", stdDev);
-            }
-
-            return b;
-        }
-    }
-
-    ProfileActivity mActivity;
-    ProfiledWebView mWeb;
-    Spinner mMovementSpinner;
-    StatAggregator mStats;
-
-    private static final String LOGTAG = "PerformanceTest";
-    private static final String TEST_LOCATION = "webkit/page_cycler";
-    private static final String URL_PREFIX = "file://";
-    private static final String URL_POSTFIX = "/index.html?skip=true";
-    private static final int MAX_ITERATIONS = 4;
-    private static final String SCROLL_TEST_DIRS[] = {
-        "alexa25_2011"
-    };
-    private static final String ANIM_TEST_DIRS[] = {
-        "dhtml"
-    };
-
-    public PerformanceTest() {
-        super(ProfileActivity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mActivity = getActivity();
-        mWeb = (ProfiledWebView) mActivity.findViewById(R.id.web);
-        mMovementSpinner = (Spinner) mActivity.findViewById(R.id.movement);
-        mStats = new StatAggregator();
-
-        // use mStats as a condition variable between the UI thread and
-        // this(the testing) thread
-        mActivity.setCallback(new ProfileCallback() {
-            @Override
-            public void profileCallback(RunData data) {
-                mStats.setData(data);
-                synchronized (mStats) {
-                    mStats.notify();
-                }
-            }
-        });
-
-    }
-
-    private boolean loadUrl(final String url) {
-        try {
-            Log.d(LOGTAG, "test starting for url " + url);
-            mActivity.runOnUiThread(new Runnable() {
-                @Override
-                public void run() {
-                    mWeb.loadUrl(url);
-                }
-            });
-            synchronized (mStats) {
-                mStats.wait();
-            }
-
-            mStats.aggregate();
-        } catch (InterruptedException e) {
-            e.printStackTrace();
-            return false;
-        }
-        return true;
-    }
-
-    private boolean validTest(String nextTest) {
-        // if testing animations, test must be in mAnimTests
-        if (mAnimTests == null)
-            return true;
-
-        for (String test : mAnimTests) {
-            if (test.equals(nextTest)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean runIteration(String[] testDirs) {
-        File sdFile = Environment.getExternalStorageDirectory();
-        for (String testDirName : testDirs) {
-            File testDir = new File(sdFile, TEST_LOCATION + "/" + testDirName);
-            Log.d(LOGTAG, "Testing dir: '" + testDir.getAbsolutePath()
-                    + "', exists=" + testDir.exists());
-
-            for (File siteDir : testDir.listFiles()) {
-                if (!siteDir.isDirectory() || !validTest(siteDir.getName())) {
-                    continue;
-                }
-
-                if (!loadUrl(URL_PREFIX + siteDir.getAbsolutePath()
-                        + URL_POSTFIX)) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    private boolean  runTestDirs(String[] testDirs) {
-        for (int i = 0; i < MAX_ITERATIONS; i++)
-            if (!runIteration(testDirs)) {
-                return false;
-            }
-        return true;
-    }
-
-    private void pushDoubleBuffering() {
-        getInstrumentation().runOnMainSync(new Runnable() {
-            public void run() {
-                mWeb.setDoubleBuffering(mDoubleBuffering);
-            }
-        });
-    }
-
-    private void setScrollingTestingMode(final boolean scrolled) {
-        getInstrumentation().runOnMainSync(new Runnable() {
-            public void run() {
-                mMovementSpinner.setSelection(scrolled ? 0 : 2);
-            }
-        });
-    }
-
-
-    private String[] mAnimTests = null;
-    private int mAnimTestNr = -1;
-    private boolean mDoubleBuffering = true;
-    private static final String[] ANIM_TEST_NAMES = {
-        "slow", "fast"
-    };
-    private static final String[][] ANIM_TESTS = {
-        {"scrolling", "replaceimages", "layers5", "layers1"},
-        {"slidingballs", "meter", "slidein", "fadespacing", "colorfade",
-                "mozilla", "movingtext", "diagball", "zoom", "imageslide"},
-    };
-
-    private boolean checkMedia() {
-        String state = Environment.getExternalStorageState();
-
-        if (!Environment.MEDIA_MOUNTED.equals(state)
-                && !Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
-            Log.d(LOGTAG, "ARG Can't access sd card!");
-            // Can't read the SD card, fail and die!
-            getInstrumentation().sendStatus(1, null);
-            return false;
-        }
-        return true;
-    }
-
-    public void testMetrics() {
-        setScrollingTestingMode(true);
-        if (checkMedia() && runTestDirs(SCROLL_TEST_DIRS)) {
-            getInstrumentation().sendStatus(0, mStats.getBundle());
-        } else {
-            getInstrumentation().sendStatus(1, null);
-        }
-    }
-
-    public void testMetricsMinimalMemory() {
-        mActivity.runOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                mWeb.setUseMinimalMemory(true);
-            }
-        });
-
-        setScrollingTestingMode(true);
-        if (checkMedia() && runTestDirs(SCROLL_TEST_DIRS)) {
-            getInstrumentation().sendStatus(0, mStats.getBundle());
-        } else {
-            getInstrumentation().sendStatus(1, null);
-        }
-    }
-
-    private boolean runAnimationTests() {
-        for (int doubleBuffer = 0; doubleBuffer <= 1; doubleBuffer++) {
-            mDoubleBuffering = doubleBuffer == 1;
-            pushDoubleBuffering();
-            for (mAnimTestNr = 0; mAnimTestNr < ANIM_TESTS.length; mAnimTestNr++) {
-                mAnimTests = ANIM_TESTS[mAnimTestNr];
-                if (!runTestDirs(ANIM_TEST_DIRS)) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    public void testAnimations() {
-        // instead of autoscrolling, load each page until either an timer fires,
-        // or the animation signals complete via javascript
-        setScrollingTestingMode(false);
-
-        if (checkMedia() && runAnimationTests()) {
-            getInstrumentation().sendStatus(0, mStats.getBundle());
-        } else {
-            getInstrumentation().sendStatus(1, null);
-        }
-    }
-}
diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackActivity.java b/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackActivity.java
deleted file mode 100644
index 1eb1c00..0000000
--- a/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackActivity.java
+++ /dev/null
@@ -1,173 +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.test.tilebenchmark;
-
-import android.app.Activity;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.view.GestureDetector.SimpleOnGestureListener;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.Button;
-import android.widget.SeekBar;
-import android.widget.SeekBar.OnSeekBarChangeListener;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-
-/**
- * Interface for playing back WebView tile rendering status. Draws viewport and
- * states of tiles and statistics for off-line analysis.
- */
-public class PlaybackActivity extends Activity {
-    private static final float SCROLL_SCALER = 0.125f;
-
-    PlaybackView mPlaybackView;
-    SeekBar mSeekBar;
-    Button mForward;
-    Button mBackward;
-    TextView mFrameDisplay;
-
-    private int mFrame = -1;
-    private int mFrameMax;
-
-    private class TouchFrameChangeListener extends SimpleOnGestureListener {
-        float mDist = 0;
-
-        @Override
-        public boolean onScroll(MotionEvent e1, MotionEvent e2,
-                float distanceX, float distanceY) {
-            // aggregate scrolls so that small ones can add up
-            mDist += distanceY * SCROLL_SCALER;
-            int intComponent = (int) Math.floor(Math.abs(mDist));
-            if (intComponent >= 1) {
-                int scrollDist = (mDist > 0) ? intComponent : -intComponent;
-                setFrame(null, mFrame + scrollDist);
-                mDist -= scrollDist;
-            }
-            return super.onScroll(e1, e2, distanceX, distanceY);
-        }
-    };
-
-    private class SeekFrameChangeListener implements OnSeekBarChangeListener {
-        @Override
-        public void onStopTrackingTouch(SeekBar seekBar) {
-        }
-
-        @Override
-        public void onStartTrackingTouch(SeekBar seekBar) {
-        }
-
-        @Override
-        public void onProgressChanged(SeekBar seekBar, int progress,
-                boolean fromUser) {
-            setFrame(seekBar, progress);
-        }
-    };
-
-    private class LoadFileTask extends AsyncTask<String, Void, RunData> {
-        @Override
-        protected RunData doInBackground(String... params) {
-            RunData data = null;
-            try {
-                FileInputStream fis = openFileInput(params[0]);
-                ObjectInputStream in = new ObjectInputStream(fis);
-                data = (RunData) in.readObject();
-                in.close();
-            } catch (IOException ex) {
-                ex.printStackTrace();
-            } catch (ClassNotFoundException ex) {
-                ex.printStackTrace();
-            }
-            return data;
-        }
-
-        @Override
-        protected void onPostExecute(RunData data) {
-            if (data == null) {
-                Toast.makeText(getApplicationContext(),
-                        getResources().getString(R.string.error_no_data),
-                        Toast.LENGTH_LONG).show();
-                return;
-            }
-            mPlaybackView.setData(data);
-
-            mFrameMax = data.frames.length - 1;
-            mSeekBar.setMax(mFrameMax);
-
-            setFrame(null, 0);
-        }
-    }
-
-    private void setFrame(View changer, int f) {
-        if (f < 0) {
-            f = 0;
-        } else if (f > mFrameMax) {
-            f = mFrameMax;
-        }
-
-        if (mFrame == f) {
-            return;
-        }
-
-        mFrame = f;
-        mForward.setEnabled(mFrame != mFrameMax);
-        mBackward.setEnabled(mFrame != 0);
-        if (changer != mSeekBar) {
-            mSeekBar.setProgress(mFrame);
-        }
-        mFrameDisplay.setText(Integer.toString(mFrame));
-        mPlaybackView.setFrame(mFrame);
-    };
-
-    /** Called when the activity is first created. */
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.playback);
-
-        mPlaybackView = (PlaybackView) findViewById(R.id.playback);
-        mSeekBar = (SeekBar) findViewById(R.id.seek_bar);
-        mForward = (Button) findViewById(R.id.forward);
-        mBackward = (Button) findViewById(R.id.backward);
-        mFrameDisplay = (TextView) findViewById(R.id.frame_display);
-
-        mForward.setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                setFrame(v, mFrame + 1);
-            }
-        });
-
-        mBackward.setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                setFrame(v, mFrame - 1);
-            }
-        });
-
-        mSeekBar.setOnSeekBarChangeListener(new SeekFrameChangeListener());
-
-        mPlaybackView.setOnGestureListener(new TouchFrameChangeListener());
-
-        new LoadFileTask().execute(ProfileActivity.TEMP_FILENAME);
-    }
-}
diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java b/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java
deleted file mode 100644
index 065e86f..0000000
--- a/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java
+++ /dev/null
@@ -1,306 +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.test.tilebenchmark;
-
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.graphics.drawable.ShapeDrawable;
-
-import com.test.tilebenchmark.RunData.TileData;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-
-public class PlaybackGraphs {
-    private static final int BAR_WIDTH = PlaybackView.TILE_SCALE * 3;
-    private static final float CANVAS_SCALE = 0.2f;
-    private static final double IDEAL_FRAMES = 60;
-    private static final int LABELOFFSET = 100;
-    private static Paint whiteLabels;
-
-    private static double viewportCoverage(TileData view, TileData tile) {
-        if (tile.left < (view.right * view.scale)
-                && tile.right >= (view.left * view.scale)
-                && tile.top < (view.bottom * view.scale)
-                && tile.bottom >= (view.top * view.scale)) {
-            return 1.0f;
-        }
-        return 0.0f;
-    }
-
-    protected interface MetricGen {
-        public double getValue(TileData[] frame);
-
-        public double getMax();
-
-        public int getLabelId();
-    };
-
-    protected static MetricGen[] Metrics = new MetricGen[] {
-            new MetricGen() {
-                // framerate graph
-                @Override
-                public double getValue(TileData[] frame) {
-                    int renderTimeUS = frame[0].level;
-                    return 1.0e6f / renderTimeUS;
-                }
-
-                @Override
-                public double getMax() {
-                    return IDEAL_FRAMES;
-                }
-
-                @Override
-                public int getLabelId() {
-                    return R.string.frames_per_second;
-                }
-            }, new MetricGen() {
-                // coverage graph
-                @Override
-                public double getValue(TileData[] frame) {
-                    double total = 0, totalCount = 0;
-                    for (int tileID = 1; tileID < frame.length; tileID++) {
-                        TileData data = frame[tileID];
-                        double coverage = viewportCoverage(frame[0], data);
-                        total += coverage * (data.isReady ? 100 : 0);
-                        totalCount += coverage;
-                    }
-                    if (totalCount == 0) {
-                        return -1;
-                    }
-                    return total / totalCount;
-                }
-
-                @Override
-                public double getMax() {
-                    return 100;
-                }
-
-                @Override
-                public int getLabelId() {
-                    return R.string.viewport_coverage;
-                }
-            }
-    };
-
-    protected interface StatGen {
-        public double getValue(double sortedValues[]);
-
-        public int getLabelId();
-    }
-
-    public static double getPercentile(double sortedValues[], double ratioAbove) {
-        if (sortedValues.length == 0)
-            return -1;
-
-        double index = ratioAbove * (sortedValues.length - 1);
-        int intIndex = (int) Math.floor(index);
-        if (index == intIndex) {
-            return sortedValues[intIndex];
-        }
-        double alpha = index - intIndex;
-        return sortedValues[intIndex] * (1 - alpha)
-                + sortedValues[intIndex + 1] * (alpha);
-    }
-
-    public static double getMean(double sortedValues[]) {
-        if (sortedValues.length == 0)
-            return -1;
-
-        double agg = 0;
-        for (double val : sortedValues) {
-            agg += val;
-        }
-        return agg / sortedValues.length;
-    }
-
-    public static double getStdDev(double sortedValues[]) {
-        if (sortedValues.length == 0)
-            return -1;
-
-        double agg = 0;
-        double sqrAgg = 0;
-        for (double val : sortedValues) {
-            agg += val;
-            sqrAgg += val*val;
-        }
-        double mean = agg / sortedValues.length;
-        return Math.sqrt((sqrAgg / sortedValues.length) - (mean * mean));
-    }
-
-    protected static StatGen[] Stats = new StatGen[] {
-            new StatGen() {
-                @Override
-                public double getValue(double[] sortedValues) {
-                    return getPercentile(sortedValues, 0.25);
-                }
-
-                @Override
-                public int getLabelId() {
-                    return R.string.percentile_25;
-                }
-            }, new StatGen() {
-                @Override
-                public double getValue(double[] sortedValues) {
-                    return getPercentile(sortedValues, 0.5);
-                }
-
-                @Override
-                public int getLabelId() {
-                    return R.string.percentile_50;
-                }
-            }, new StatGen() {
-                @Override
-                public double getValue(double[] sortedValues) {
-                    return getPercentile(sortedValues, 0.75);
-                }
-
-                @Override
-                public int getLabelId() {
-                    return R.string.percentile_75;
-                }
-            }, new StatGen() {
-                @Override
-                public double getValue(double[] sortedValues) {
-                    return getStdDev(sortedValues);
-                }
-
-                @Override
-                public int getLabelId() {
-                    return R.string.std_dev;
-                }
-            }, new StatGen() {
-                @Override
-                public double getValue(double[] sortedValues) {
-                    return getMean(sortedValues);
-                }
-
-                @Override
-                public int getLabelId() {
-                    return R.string.mean;
-                }
-            },
-    };
-
-    public PlaybackGraphs() {
-        whiteLabels = new Paint();
-        whiteLabels.setColor(Color.WHITE);
-        whiteLabels.setTextSize(PlaybackView.TILE_SCALE / 3);
-    }
-
-    private ArrayList<ShapeDrawable> mShapes = new ArrayList<ShapeDrawable>();
-    protected final double[][] mStats = new double[Metrics.length][Stats.length];
-    protected HashMap<String, Double> mSingleStats;
-
-    private void gatherFrameMetric(int metricIndex, double metricValues[], RunData data) {
-        // create graph out of rectangles, one per frame
-        int lastBar = 0;
-        for (int frameIndex = 0; frameIndex < data.frames.length; frameIndex++) {
-            TileData frame[] = data.frames[frameIndex];
-            int newBar = (int)((frame[0].top + frame[0].bottom) * frame[0].scale / 2.0f);
-
-            MetricGen s = Metrics[metricIndex];
-            double absoluteValue = s.getValue(frame);
-            double relativeValue = absoluteValue / s.getMax();
-            relativeValue = Math.min(1,relativeValue);
-            relativeValue = Math.max(0,relativeValue);
-            int rightPos = (int) (-BAR_WIDTH * metricIndex);
-            int leftPos = (int) (-BAR_WIDTH * (metricIndex + relativeValue));
-
-            ShapeDrawable graphBar = new ShapeDrawable();
-            graphBar.getPaint().setColor(Color.BLUE);
-            graphBar.setBounds(leftPos, lastBar, rightPos, newBar);
-
-            mShapes.add(graphBar);
-            metricValues[frameIndex] = absoluteValue;
-            lastBar = newBar;
-        }
-    }
-
-    public void setData(RunData data) {
-        mShapes.clear();
-        double metricValues[] = new double[data.frames.length];
-
-        mSingleStats = data.singleStats;
-
-        if (data.frames.length == 0) {
-            return;
-        }
-
-        for (int metricIndex = 0; metricIndex < Metrics.length; metricIndex++) {
-            // calculate metric based on list of frames
-            gatherFrameMetric(metricIndex, metricValues, data);
-
-            // store aggregate statistics per metric (median, and similar)
-            Arrays.sort(metricValues);
-            for (int statIndex = 0; statIndex < Stats.length; statIndex++) {
-                mStats[metricIndex][statIndex] =
-                        Stats[statIndex].getValue(metricValues);
-            }
-        }
-    }
-
-    public void drawVerticalShiftedShapes(Canvas canvas,
-            ArrayList<ShapeDrawable> shapes) {
-        // Shapes drawn here are drawn relative to the viewRect
-        Rect viewRect = shapes.get(shapes.size() - 1).getBounds();
-        canvas.translate(0, 5 * PlaybackView.TILE_SCALE - viewRect.top);
-
-        for (ShapeDrawable shape : mShapes) {
-            shape.draw(canvas);
-        }
-        for (ShapeDrawable shape : shapes) {
-            shape.draw(canvas);
-        }
-    }
-
-    public void draw(Canvas canvas, ArrayList<ShapeDrawable> shapes,
-            ArrayList<String> strings, Resources resources) {
-        canvas.scale(CANVAS_SCALE, CANVAS_SCALE);
-
-        canvas.translate(BAR_WIDTH * Metrics.length, 0);
-
-        canvas.save();
-        drawVerticalShiftedShapes(canvas, shapes);
-        canvas.restore();
-
-        for (int metricIndex = 0; metricIndex < Metrics.length; metricIndex++) {
-            String label = resources.getString(
-                    Metrics[metricIndex].getLabelId());
-            int xPos = (metricIndex + 1) * -BAR_WIDTH;
-            int yPos = LABELOFFSET;
-            canvas.drawText(label, xPos, yPos, whiteLabels);
-            for (int statIndex = 0; statIndex < Stats.length; statIndex++) {
-                String statLabel = resources.getString(
-                        Stats[statIndex].getLabelId()).substring(0,3);
-                label = statLabel + " " + resources.getString(
-                        R.string.format_stat, mStats[metricIndex][statIndex]);
-                yPos = LABELOFFSET + (1 + statIndex) * PlaybackView.TILE_SCALE
-                        / 2;
-                canvas.drawText(label, xPos, yPos, whiteLabels);
-            }
-        }
-        for (int stringIndex = 0; stringIndex < strings.size(); stringIndex++) {
-            int yPos = LABELOFFSET + stringIndex * PlaybackView.TILE_SCALE / 2;
-            canvas.drawText(strings.get(stringIndex), 0, yPos, whiteLabels);
-        }
-    }
-}
diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackView.java b/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackView.java
deleted file mode 100644
index 5459c1f..0000000
--- a/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackView.java
+++ /dev/null
@@ -1,224 +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.test.tilebenchmark;
-
-import android.animation.ArgbEvaluator;
-import android.animation.ObjectAnimator;
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.drawable.ShapeDrawable;
-import android.util.AttributeSet;
-import android.view.GestureDetector;
-import android.view.GestureDetector.OnGestureListener;
-import android.view.MotionEvent;
-import android.view.View;
-
-import com.test.tilebenchmark.RunData.TileData;
-
-import java.util.ArrayList;
-
-public class PlaybackView extends View {
-    public static final int TILE_SCALE = 256;
-    private static final int INVAL_FLAG = -2;
-    private static final int INVAL_CYCLE = 250;
-
-    private Paint levelPaint = null, coordPaint = null, goldPaint = null;
-    private PlaybackGraphs mGraphs;
-
-    private ArrayList<ShapeDrawable> mTempShapes = new ArrayList<ShapeDrawable>();
-    private RunData mProfData = null;
-    private GestureDetector mGestureDetector = null;
-    private ArrayList<String> mRenderStrings = new ArrayList<String>();
-
-    private class TileDrawable extends ShapeDrawable {
-        TileData tile;
-        String label;
-
-        public TileDrawable(TileData t, int colorId) {
-            this.tile = t;
-            getPaint().setColor(getResources().getColor(colorId));
-            if (colorId == R.color.ready_tile
-                    || colorId == R.color.unready_tile) {
-
-                label = (int) (t.left / TILE_SCALE) + ", "
-                        + (int) (t.top / TILE_SCALE);
-                // ignore scale value for tiles
-                setBounds(t.left, t.top,
-                        t.right, t.bottom);
-            } else {
-                setBounds((int) (t.left * t.scale),
-                        (int) (t.top * t.scale),
-                        (int) (t.right * t.scale),
-                        (int) (t.bottom * t.scale));
-            }
-        }
-
-        @SuppressWarnings("unused")
-        public void setColor(int color) {
-            getPaint().setColor(color);
-        }
-
-        @Override
-        public void draw(Canvas canvas) {
-            super.draw(canvas);
-            if (label != null) {
-                canvas.drawText(Integer.toString(tile.level), getBounds().left,
-                        getBounds().bottom, levelPaint);
-                canvas.drawText(label, getBounds().left,
-                        ((getBounds().bottom + getBounds().top) / 2),
-                        coordPaint);
-            }
-        }
-    }
-
-    public PlaybackView(Context context) {
-        super(context);
-        init();
-    }
-
-    public PlaybackView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        init();
-    }
-
-    public PlaybackView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        init();
-    }
-
-    public void setOnGestureListener(OnGestureListener gl) {
-        mGestureDetector = new GestureDetector(getContext(), gl);
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent event) {
-        mGestureDetector.onTouchEvent(event);
-        return true;
-    }
-
-    private void init() {
-        levelPaint = new Paint();
-        levelPaint.setColor(Color.WHITE);
-        levelPaint.setTextSize(TILE_SCALE / 2);
-        coordPaint = new Paint();
-        coordPaint.setColor(Color.BLACK);
-        coordPaint.setTextSize(TILE_SCALE / 3);
-        goldPaint = new Paint();
-        goldPaint.setColor(0xffa0e010);
-        mGraphs = new PlaybackGraphs();
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        super.onDraw(canvas);
-
-        if (mTempShapes == null || mTempShapes.isEmpty()) {
-            return;
-        }
-
-        mGraphs.draw(canvas, mTempShapes, mRenderStrings, getResources());
-        invalidate(); // may have animations, force redraw
-    }
-
-    private String statString(int labelId, int value) {
-        return getResources().getString(R.string.format_stat_name,
-                getResources().getString(labelId), value);
-    }
-    private String tileString(int formatStringId, TileData t) {
-        return getResources().getString(formatStringId,
-                t.left, t.top, t.right, t.bottom);
-    }
-
-    public int setFrame(int frame) {
-        if (mProfData == null || mProfData.frames.length == 0) {
-            return 0;
-        }
-
-        int readyTiles = 0, unreadyTiles = 0, unplacedTiles = 0, numInvals = 0;
-        mTempShapes.clear();
-        mRenderStrings.clear();
-
-        // create tile shapes (as they're drawn on bottom)
-        for (TileData t : mProfData.frames[frame]) {
-            if (t == mProfData.frames[frame][0]){
-                // viewport 'tile', add coords to render strings
-                mRenderStrings.add(tileString(R.string.format_view_pos, t));
-            } else  if (t.level != INVAL_FLAG) {
-                int colorId;
-                if (t.isReady) {
-                    readyTiles++;
-                    colorId = R.color.ready_tile;
-                } else {
-                    unreadyTiles++;
-                    colorId = R.color.unready_tile;
-                }
-                if (t.left < 0 || t.top < 0) {
-                    unplacedTiles++;
-                }
-                mTempShapes.add(new TileDrawable(t, colorId));
-            } else {
-                // inval 'tile', count and add coords to render strings
-                numInvals++;
-                mRenderStrings.add(tileString(R.string.format_inval_pos, t));
-            }
-        }
-
-        // create invalidate shapes (drawn above tiles)
-        int invalId = 0;
-        for (TileData t : mProfData.frames[frame]) {
-            if (t.level == INVAL_FLAG && t != mProfData.frames[frame][0]) {
-                TileDrawable invalShape = new TileDrawable(t,
-                        R.color.inval_region_start);
-                ValueAnimator tileAnimator = ObjectAnimator.ofInt(invalShape,
-                        "color",
-                        getResources().getColor(R.color.inval_region_start),
-                        getResources().getColor(R.color.inval_region_stop));
-                tileAnimator.setDuration(numInvals * INVAL_CYCLE);
-                tileAnimator.setEvaluator(new ArgbEvaluator());
-                tileAnimator.setRepeatCount(ValueAnimator.INFINITE);
-                tileAnimator.setRepeatMode(ValueAnimator.RESTART);
-                float delay = (float) (invalId) * INVAL_CYCLE;
-                tileAnimator.setStartDelay((int) delay);
-                invalId++;
-                tileAnimator.start();
-
-                mTempShapes.add(invalShape);
-            }
-        }
-
-        mRenderStrings.add(statString(R.string.ready_tiles, readyTiles));
-        mRenderStrings.add(statString(R.string.unready_tiles, unreadyTiles));
-        mRenderStrings.add(statString(R.string.unplaced_tiles, unplacedTiles));
-        mRenderStrings.add(statString(R.string.number_invalidates, numInvals));
-
-        // draw view rect (using first TileData object, on top)
-        TileDrawable viewShape = new TileDrawable(mProfData.frames[frame][0],
-                R.color.view);
-        mTempShapes.add(viewShape);
-        this.invalidate();
-        return frame;
-    }
-
-    public void setData(RunData tileProfilingData) {
-        mProfData = tileProfilingData;
-
-        mGraphs.setData(mProfData);
-    }
-}
diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/ProfileActivity.java b/tests/TileBenchmark/src/com/test/tilebenchmark/ProfileActivity.java
deleted file mode 100644
index 2e77157..0000000
--- a/tests/TileBenchmark/src/com/test/tilebenchmark/ProfileActivity.java
+++ /dev/null
@@ -1,337 +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.test.tilebenchmark;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.CountDownTimer;
-import android.util.Log;
-import android.util.Pair;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemSelectedListener;
-import android.widget.ArrayAdapter;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.Spinner;
-import android.widget.TextView;
-import android.widget.TextView.OnEditorActionListener;
-import android.widget.ToggleButton;
-
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.ObjectOutputStream;
-
-/**
- * Interface for profiling the webview's scrolling, with simple controls on how
- * to scroll, and what content to load.
- */
-public class ProfileActivity extends Activity {
-
-    private static final int TIMED_RECORD_MILLIS = 2000;
-
-    public interface ProfileCallback {
-        public void profileCallback(RunData data);
-    }
-
-    public static final String TEMP_FILENAME = "profile.tiles";
-
-    Button mInspectButton;
-    ToggleButton mCaptureButton;
-    Spinner mVelocitySpinner;
-    Spinner mMovementSpinner;
-    EditText mUrl;
-    ProfiledWebView mWeb;
-    ProfileCallback mCallback;
-
-    LoggingWebViewClient mLoggingWebViewClient = new LoggingWebViewClient();
-    AutoLoggingWebViewClient mAutoLoggingWebViewClient = new AutoLoggingWebViewClient();
-    TimedLoggingWebViewClient mTimedLoggingWebViewClient = new TimedLoggingWebViewClient();
-
-    private enum TestingState {
-        NOT_TESTING,
-        PRE_TESTING,
-        START_TESTING,
-        STOP_TESTING,
-        SAVED_TESTING
-    };
-
-    private class VelocitySelectedListener implements OnItemSelectedListener {
-        @Override
-        public void onItemSelected(AdapterView<?> parent, View view,
-                int position, long id) {
-            String speedStr = parent.getItemAtPosition(position).toString();
-            int speedInt = Integer.parseInt(speedStr);
-            mWeb.setAutoScrollSpeed(speedInt);
-        }
-
-        @Override
-        public void onNothingSelected(AdapterView<?> parent) {
-        }
-    }
-
-    private class MovementSelectedListener implements OnItemSelectedListener {
-        @Override
-        public void onItemSelected(AdapterView<?> parent, View view,
-                int position, long id) {
-            String movementStr = parent.getItemAtPosition(position).toString();
-            if (movementStr == getResources().getString(R.string.movement_auto_scroll)) {
-                mWeb.setWebViewClient(mAutoLoggingWebViewClient);
-                mCaptureButton.setEnabled(false);
-                mVelocitySpinner.setEnabled(true);
-            } else if (movementStr == getResources().getString(R.string.movement_manual)) {
-                mWeb.setWebViewClient(mLoggingWebViewClient);
-                mCaptureButton.setEnabled(true);
-                mVelocitySpinner.setEnabled(false);
-            } else if (movementStr == getResources().getString(R.string.movement_timed)) {
-                mWeb.setWebViewClient(mTimedLoggingWebViewClient);
-                mCaptureButton.setEnabled(false);
-                mVelocitySpinner.setEnabled(false);
-            }
-        }
-
-        @Override
-        public void onNothingSelected(AdapterView<?> parent) {
-        }
-    }
-
-    private class LoggingWebViewClient extends WebViewClient {
-        @Override
-        public boolean shouldOverrideUrlLoading(WebView view, String url) {
-            return false;
-        }
-
-        @Override
-        public void onPageStarted(WebView view, String url, Bitmap favicon) {
-            super.onPageStarted(view, url, favicon);
-            mUrl.setText(url);
-        }
-
-        @Override
-        public void onPageFinished(WebView view, String url) {
-            super.onPageFinished(view, url);
-            view.requestFocus();
-            ((ProfiledWebView)view).onPageFinished();
-        }
-    }
-
-    private class AutoLoggingWebViewClient extends LoggingWebViewClient {
-        @Override
-        public void onPageFinished(WebView view, String url) {
-            super.onPageFinished(view, url);
-            startViewProfiling(true);
-        }
-
-        @Override
-        public void onPageStarted(WebView view, String url, Bitmap favicon) {
-            super.onPageStarted(view, url, favicon);
-            setTestingState(TestingState.PRE_TESTING);
-        }
-    }
-
-    private class TimedLoggingWebViewClient extends LoggingWebViewClient {
-        @Override
-        public void onPageFinished(WebView view, String url) {
-            super.onPageFinished(view, url);
-            startViewProfiling(false);
-
-            // after a fixed time after page finished, stop testing
-            new CountDownTimer(TIMED_RECORD_MILLIS, TIMED_RECORD_MILLIS) {
-                @Override
-                public void onTick(long millisUntilFinished) {
-                }
-
-                @Override
-                public void onFinish() {
-                    mWeb.stopScrollTest();
-                }
-            }.start();
-        }
-
-        @Override
-        public void onPageStarted(WebView view, String url, Bitmap favicon) {
-            super.onPageStarted(view, url, favicon);
-            setTestingState(TestingState.PRE_TESTING);
-        }
-    }
-
-    private class StoreFileTask extends
-            AsyncTask<Pair<String, RunData>, Void, Void> {
-
-        @Override
-        protected Void doInBackground(Pair<String, RunData>... params) {
-            try {
-                FileOutputStream fos = openFileOutput(params[0].first,
-                        Context.MODE_PRIVATE);
-                ObjectOutputStream out = new ObjectOutputStream(fos);
-                out.writeObject(params[0].second);
-                out.close();
-            } catch (IOException ex) {
-                ex.printStackTrace();
-            }
-            return null;
-        }
-
-        @Override
-        protected void onPostExecute(Void v) {
-            setTestingState(TestingState.SAVED_TESTING);
-        }
-    }
-
-    public void setTestingState(TestingState state) {
-        switch (state) {
-            case NOT_TESTING:
-                mUrl.setBackgroundResource(R.color.background_not_testing);
-                mInspectButton.setEnabled(true);
-                mMovementSpinner.setEnabled(true);
-                break;
-            case PRE_TESTING:
-                mInspectButton.setEnabled(false);
-                mMovementSpinner.setEnabled(false);
-                break;
-            case START_TESTING:
-                mCaptureButton.setChecked(true);
-                mUrl.setBackgroundResource(R.color.background_start_testing);
-                mInspectButton.setEnabled(false);
-                mMovementSpinner.setEnabled(false);
-                break;
-            case STOP_TESTING:
-                mCaptureButton.setChecked(false);
-                mUrl.setBackgroundResource(R.color.background_stop_testing);
-                break;
-            case SAVED_TESTING:
-                mInspectButton.setEnabled(true);
-                mMovementSpinner.setEnabled(true);
-                break;
-        }
-    }
-
-    /** auto - automatically scroll. */
-    private void startViewProfiling(boolean auto) {
-        // toggle capture button to indicate capture state to user
-        mWeb.startScrollTest(mCallback, auto);
-        setTestingState(TestingState.START_TESTING);
-    }
-
-    /** Called when the activity is first created. */
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.main);
-        mInspectButton = (Button) findViewById(R.id.inspect);
-        mCaptureButton = (ToggleButton) findViewById(R.id.capture);
-        mVelocitySpinner = (Spinner) findViewById(R.id.velocity);
-        mMovementSpinner = (Spinner) findViewById(R.id.movement);
-        mUrl = (EditText) findViewById(R.id.url);
-        mWeb = (ProfiledWebView) findViewById(R.id.web);
-        setCallback(new ProfileCallback() {
-            @SuppressWarnings("unchecked")
-            @Override
-            public void profileCallback(RunData data) {
-                new StoreFileTask().execute(new Pair<String, RunData>(
-                        TEMP_FILENAME, data));
-                Log.d("ProfileActivity", "stored " + data.frames.length + " frames in file");
-                setTestingState(TestingState.STOP_TESTING);
-            }
-        });
-
-        // Inspect button (opens PlaybackActivity)
-        mInspectButton.setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                startActivity(new Intent(ProfileActivity.this,
-                        PlaybackActivity.class));
-            }
-        });
-
-        // Velocity spinner
-        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
-                this, R.array.velocity_array,
-                android.R.layout.simple_spinner_item);
-        adapter.setDropDownViewResource(
-                android.R.layout.simple_spinner_dropdown_item);
-        mVelocitySpinner.setAdapter(adapter);
-        mVelocitySpinner.setOnItemSelectedListener(
-                new VelocitySelectedListener());
-        mVelocitySpinner.setSelection(3);
-
-        // Movement spinner
-        String content[] = {
-                getResources().getString(R.string.movement_auto_scroll),
-                getResources().getString(R.string.movement_manual),
-                getResources().getString(R.string.movement_timed)
-        };
-        adapter = new ArrayAdapter<CharSequence>(this,
-                android.R.layout.simple_spinner_item, content);
-        adapter.setDropDownViewResource(
-                android.R.layout.simple_spinner_dropdown_item);
-        mMovementSpinner.setAdapter(adapter);
-        mMovementSpinner.setOnItemSelectedListener(
-                new MovementSelectedListener());
-        mMovementSpinner.setSelection(0);
-
-        // Capture toggle button
-        mCaptureButton.setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                if (mCaptureButton.isChecked()) {
-                    startViewProfiling(false);
-                } else {
-                    mWeb.stopScrollTest();
-                }
-            }
-        });
-
-        // Custom profiling WebView
-        mWeb.init(this);
-        mWeb.setWebViewClient(new LoggingWebViewClient());
-
-        // URL text entry
-        mUrl.setOnEditorActionListener(new OnEditorActionListener() {
-            public boolean onEditorAction(TextView v, int actionId,
-                    KeyEvent event) {
-                String url = mUrl.getText().toString();
-                mWeb.loadUrl(url);
-                mWeb.requestFocus();
-                return true;
-            }
-        });
-
-        setTestingState(TestingState.NOT_TESTING);
-    }
-
-    public void setCallback(ProfileCallback callback) {
-        mCallback = callback;
-    }
-
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        if ((keyCode == KeyEvent.KEYCODE_BACK) && mWeb.canGoBack()) {
-            mWeb.goBack();
-            return true;
-        }
-        return super.onKeyDown(keyCode, event);
-    }
-}
diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java b/tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java
deleted file mode 100644
index d3b572c..0000000
--- a/tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java
+++ /dev/null
@@ -1,252 +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.test.tilebenchmark;
-
-import android.content.Context;
-import android.os.CountDownTimer;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.webkit.WebSettingsClassic;
-import android.webkit.WebView;
-import android.webkit.WebViewClassic;
-
-import java.util.ArrayList;
-
-import com.test.tilebenchmark.ProfileActivity.ProfileCallback;
-import com.test.tilebenchmark.RunData.TileData;
-
-public class ProfiledWebView extends WebView implements WebViewClassic.PageSwapDelegate {
-    private static final String LOGTAG = "ProfiledWebView";
-
-    private int mSpeed;
-
-    private boolean mIsTesting = false;
-    private boolean mIsScrolling = false;
-    private ProfileCallback mCallback;
-    private long mContentInvalMillis;
-    private static final int LOAD_STALL_MILLIS = 2000; // nr of millis after load,
-                                                       // before test is forced
-
-    // ignore anim end events until this many millis after load
-    private static final long ANIM_SAFETY_THRESHOLD = 200;
-    private long mLoadTime;
-    private long mAnimationTime;
-
-    public ProfiledWebView(Context context) {
-        super(context);
-    }
-
-    public ProfiledWebView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public ProfiledWebView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    public ProfiledWebView(Context context, AttributeSet attrs, int defStyle,
-            boolean privateBrowsing) {
-        super(context, attrs, defStyle, privateBrowsing);
-    }
-
-    private class JavaScriptInterface {
-        Context mContext;
-
-        /** Instantiate the interface and set the context */
-        JavaScriptInterface(Context c) {
-            mContext = c;
-        }
-
-        public void animationComplete() {
-            mAnimationTime = System.currentTimeMillis();
-        }
-    }
-
-    public void init(Context c) {
-        WebSettingsClassic settings = getWebViewClassic().getSettings();
-        settings.setJavaScriptEnabled(true);
-        settings.setSupportZoom(true);
-        settings.setEnableSmoothTransition(true);
-        settings.setBuiltInZoomControls(true);
-        settings.setLoadWithOverviewMode(true);
-        settings.setProperty("use_minimal_memory", "false"); // prefetch tiles, as browser does
-        addJavascriptInterface(new JavaScriptInterface(c), "Android");
-        mAnimationTime = 0;
-        mLoadTime = 0;
-    }
-
-    public void setUseMinimalMemory(boolean minimal) {
-        WebSettingsClassic settings = getWebViewClassic().getSettings();
-        settings.setProperty("use_minimal_memory", minimal ? "true" : "false");
-    }
-
-    public void onPageFinished() {
-        mLoadTime = System.currentTimeMillis();
-    }
-
-    @Override
-    protected void onDraw(android.graphics.Canvas canvas) {
-        if (mIsTesting && mIsScrolling) {
-            if (canScrollVertically(1)) {
-                scrollBy(0, mSpeed);
-            } else {
-                stopScrollTest();
-                mIsScrolling = false;
-            }
-        }
-        super.onDraw(canvas);
-    }
-
-    /*
-     * Called once the page is loaded to start scrolling for evaluating tiles.
-     * If autoScrolling isn't set, stop must be called manually. Before
-     * scrolling, invalidate all content and redraw it, measuring time taken.
-     */
-    public void startScrollTest(ProfileCallback callback, boolean autoScrolling) {
-        mCallback = callback;
-        mIsTesting = false;
-        mIsScrolling = false;
-        WebSettingsClassic settings = getWebViewClassic().getSettings();
-        settings.setProperty("tree_updates", "0");
-
-
-        if (autoScrolling) {
-            // after a while, force it to start even if the pages haven't swapped
-            new CountDownTimer(LOAD_STALL_MILLIS, LOAD_STALL_MILLIS) {
-                @Override
-                public void onTick(long millisUntilFinished) {
-                }
-
-                @Override
-                public void onFinish() {
-                    // invalidate all content, and kick off redraw
-                    Log.d("ProfiledWebView",
-                            "kicking off test with callback registration, and tile discard...");
-                    getWebViewClassic().discardAllTextures();
-                    invalidate();
-                    mIsScrolling = true;
-                    mContentInvalMillis = System.currentTimeMillis();
-                }
-            }.start();
-        } else {
-            mIsTesting = true;
-            getWebViewClassic().tileProfilingStart();
-        }
-    }
-
-    /*
-     * Called after the manual contentInvalidateAll, after the tiles have all
-     * been redrawn.
-     * From PageSwapDelegate.
-     */
-    @Override
-    public void onPageSwapOccurred(boolean startAnim) {
-        if (!mIsTesting && mIsScrolling) {
-            // kick off testing
-            mContentInvalMillis = System.currentTimeMillis() - mContentInvalMillis;
-            Log.d("ProfiledWebView", "REDRAW TOOK " + mContentInvalMillis + "millis");
-            mIsTesting = true;
-            invalidate(); // ensure a redraw so that auto-scrolling can occur
-            getWebViewClassic().tileProfilingStart();
-        }
-    }
-
-    private double animFramerate() {
-        WebSettingsClassic settings = getWebViewClassic().getSettings();
-        String updatesString = settings.getProperty("tree_updates");
-        int updates = (updatesString == null) ? -1 : Integer.parseInt(updatesString);
-
-        long animationTime;
-        if (mAnimationTime == 0 || mAnimationTime - mLoadTime < ANIM_SAFETY_THRESHOLD) {
-            animationTime = System.currentTimeMillis() - mLoadTime;
-        } else {
-            animationTime = mAnimationTime - mLoadTime;
-        }
-
-        return updates * 1000.0 / animationTime;
-    }
-
-    public void setDoubleBuffering(boolean useDoubleBuffering) {
-        WebSettingsClassic settings = getWebViewClassic().getSettings();
-        settings.setProperty("use_double_buffering", useDoubleBuffering ? "true" : "false");
-    }
-
-    /*
-     * Called once the page has stopped scrolling
-     */
-    public void stopScrollTest() {
-        getWebViewClassic().tileProfilingStop();
-        mIsTesting = false;
-
-        if (mCallback == null) {
-            getWebViewClassic().tileProfilingClear();
-            return;
-        }
-
-        RunData data = new RunData(getWebViewClassic().tileProfilingNumFrames());
-        // record the time spent (before scrolling) rendering the page
-        data.singleStats.put(getResources().getString(R.string.render_millis),
-                (double)mContentInvalMillis);
-
-        // record framerate
-        double framerate = animFramerate();
-        Log.d(LOGTAG, "anim framerate was "+framerate);
-        data.singleStats.put(getResources().getString(R.string.animation_framerate),
-                framerate);
-
-        for (int frame = 0; frame < data.frames.length; frame++) {
-            data.frames[frame] = new TileData[
-                    getWebViewClassic().tileProfilingNumTilesInFrame(frame)];
-            for (int tile = 0; tile < data.frames[frame].length; tile++) {
-                int left = getWebViewClassic().tileProfilingGetInt(frame, tile, "left");
-                int top = getWebViewClassic().tileProfilingGetInt(frame, tile, "top");
-                int right = getWebViewClassic().tileProfilingGetInt(frame, tile, "right");
-                int bottom = getWebViewClassic().tileProfilingGetInt(frame, tile, "bottom");
-
-                boolean isReady = getWebViewClassic().tileProfilingGetInt(
-                        frame, tile, "isReady") == 1;
-                int level = getWebViewClassic().tileProfilingGetInt(frame, tile, "level");
-
-                float scale = getWebViewClassic().tileProfilingGetFloat(frame, tile, "scale");
-
-                data.frames[frame][tile] = data.new TileData(left, top, right, bottom,
-                        isReady, level, scale);
-            }
-        }
-        getWebViewClassic().tileProfilingClear();
-
-        mCallback.profileCallback(data);
-    }
-
-    @Override
-    public void loadUrl(String url) {
-        mAnimationTime = 0;
-        mLoadTime = 0;
-        if (!url.startsWith("http://") && !url.startsWith("file://")) {
-            url = "http://" + url;
-        }
-        super.loadUrl(url);
-    }
-
-    public void setAutoScrollSpeed(int speedInt) {
-        mSpeed = speedInt;
-    }
-
-    public WebViewClassic getWebViewClassic() {
-        return WebViewClassic.fromWebView(this);
-    }
-}
diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/RunData.java b/tests/TileBenchmark/src/com/test/tilebenchmark/RunData.java
deleted file mode 100644
index 5e48afd..0000000
--- a/tests/TileBenchmark/src/com/test/tilebenchmark/RunData.java
+++ /dev/null
@@ -1,54 +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.test.tilebenchmark;
-
-import java.io.Serializable;
-import java.util.HashMap;
-
-public class RunData implements Serializable {
-    public TileData[][] frames;
-    public HashMap<String, Double> singleStats = new HashMap<String, Double>();
-
-    public RunData(int frames) {
-        this.frames = new TileData[frames][];
-    }
-
-    public class TileData implements Serializable {
-        public int left, top, right, bottom;
-        public boolean isReady;
-        public int level;
-        public float scale;
-
-        public TileData(int left, int top, int right, int bottom,
-                boolean isReady, int level, float scale) {
-            this.left = left;
-            this.right = right;
-            this.top = top;
-            this.bottom = bottom;
-            this.isReady = isReady;
-            this.level = level;
-            this.scale = scale;
-        }
-
-        public String toString() {
-            return "Tile (" + left + "," + top + ")->("
-                    + right + "," + bottom + ")"
-                    + (isReady ? "ready" : "NOTready") + " at scale " + scale;
-        }
-    }
-
-}
diff --git a/tests/TransitionTests/Android.mk b/tests/TransitionTests/Android.mk
new file mode 100644
index 0000000..22fa638
--- /dev/null
+++ b/tests/TransitionTests/Android.mk
@@ -0,0 +1,18 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := TransitionTests
+
+LOCAL_STATIC_JAVA_LIBRARIES += android-common
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+include $(BUILD_PACKAGE)
+
+# Use the following include to make our test apk.
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/TransitionTests/AndroidManifest.xml b/tests/TransitionTests/AndroidManifest.xml
new file mode 100644
index 0000000..35e7b69
--- /dev/null
+++ b/tests/TransitionTests/AndroidManifest.xml
@@ -0,0 +1,253 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.transitiontests"
+          android:versionCode="1"
+          android:versionName="1.0">
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <application
+            android:icon="@drawable/icon"
+            android:label="@string/app_name"
+            android:hardwareAccelerated="true"
+            android:theme="@style/AppTheme">
+        <activity android:label="@string/states_test1"
+                  android:name="ScenesTestv21">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="@string/states_test_auto_targets"
+                  android:name="ScenesTestAutoTargets">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="@string/states_test_auto_transition"
+                  android:name="ScenesTestAutoTransition">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="@string/states_test_auto_transition2"
+                  android:name="ScenesTestAutoTransition2">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="@string/contacts_expansion"
+                  android:name="ContactsExpansion">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="Demo0"
+                  android:name="Demo0">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="Demo1"
+                  android:name="Demo1">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="Demo2"
+                  android:name="Demo2">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="Demo3"
+                  android:name="Demo3">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="Demo4"
+                  android:name="Demo4">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="Demo5"
+                  android:name="Demo5">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="LoginActivity"
+                  android:name="LoginActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="LoginActivityFromResources"
+                  android:name="LoginActivityFromResources">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="OverlayTest"
+                  android:name="OverlayTest">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="ResourceLoadingTest"
+                  android:name="ResourceLoadingTest">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="FadingTest"
+                  android:name="FadingTest">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="UniqueIds"
+                  android:name="UniqueIds">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="HitRectBug"
+                  android:name="HitRectBug">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="SequenceTest"
+                  android:name="SequenceTest">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="SequenceTestSimple"
+                  android:name="SequenceTestSimple">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="ChangingText"
+                  android:name="ChangingText">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="ClippingText"
+                  android:name="ClippingText">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="ListViewAddRemove"
+                  android:name="ListViewAddRemove">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="ListViewAddRemoveNoTransition"
+                  android:name="ListViewAddRemoveNoTransition">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="CrossFadeDemo"
+                  android:name="CrossFadeDemo">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="Reparenting"
+                  android:name="Reparenting">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="SurfaceAndTextureViews"
+                  android:name="SurfaceAndTextureViews">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="InstanceTargets"
+                  android:name="InstanceTargets">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="InterruptionTest"
+                  android:name="InterruptionTest">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="DelayedTransition"
+                  android:name="DelayedTransition">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="FadingHierachy"
+                  android:name=".FadingHierarchy">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="HierarchicalMove"
+                  android:name=".HierarchicalMove">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="CrossfadeImage"
+                  android:name=".CrossfadeImage">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:label="CrossfadeMultiple"
+                  android:name=".CrossfadeMultiple">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+    </application>
+
+</manifest>
diff --git a/tests/TransitionTests/res/drawable-hdpi/icon.png b/tests/TransitionTests/res/drawable-hdpi/icon.png
new file mode 100644
index 0000000..8074c4c
--- /dev/null
+++ b/tests/TransitionTests/res/drawable-hdpi/icon.png
Binary files differ
diff --git a/tests/TransitionTests/res/drawable-ldpi/icon.png b/tests/TransitionTests/res/drawable-ldpi/icon.png
new file mode 100644
index 0000000..1095584
--- /dev/null
+++ b/tests/TransitionTests/res/drawable-ldpi/icon.png
Binary files differ
diff --git a/tests/TransitionTests/res/drawable-mdpi/icon.png b/tests/TransitionTests/res/drawable-mdpi/icon.png
new file mode 100644
index 0000000..a07c69f
--- /dev/null
+++ b/tests/TransitionTests/res/drawable-mdpi/icon.png
Binary files differ
diff --git a/tests/TransitionTests/res/drawable-nodpi/arrow_thumbnail.png b/tests/TransitionTests/res/drawable-nodpi/arrow_thumbnail.png
new file mode 100644
index 0000000..5cae8f2
--- /dev/null
+++ b/tests/TransitionTests/res/drawable-nodpi/arrow_thumbnail.png
Binary files differ
diff --git a/tests/TransitionTests/res/drawable-nodpi/self_portrait_square.jpg b/tests/TransitionTests/res/drawable-nodpi/self_portrait_square.jpg
new file mode 100644
index 0000000..8cce1c1
--- /dev/null
+++ b/tests/TransitionTests/res/drawable-nodpi/self_portrait_square.jpg
Binary files differ
diff --git a/tests/TransitionTests/res/drawable-nodpi/self_portrait_square_100.jpg b/tests/TransitionTests/res/drawable-nodpi/self_portrait_square_100.jpg
new file mode 100644
index 0000000..26c0a85
--- /dev/null
+++ b/tests/TransitionTests/res/drawable-nodpi/self_portrait_square_100.jpg
Binary files differ
diff --git a/tests/TransitionTests/res/drawable-nodpi/self_portrait_square_200.jpg b/tests/TransitionTests/res/drawable-nodpi/self_portrait_square_200.jpg
new file mode 100644
index 0000000..f18ae5b
--- /dev/null
+++ b/tests/TransitionTests/res/drawable-nodpi/self_portrait_square_200.jpg
Binary files differ
diff --git a/tests/TransitionTests/res/drawable-nodpi/self_portrait_square_400.jpg b/tests/TransitionTests/res/drawable-nodpi/self_portrait_square_400.jpg
new file mode 100644
index 0000000..3923fd1
--- /dev/null
+++ b/tests/TransitionTests/res/drawable-nodpi/self_portrait_square_400.jpg
Binary files differ
diff --git a/tests/TransitionTests/res/layout/activity_login.xml b/tests/TransitionTests/res/layout/activity_login.xml
new file mode 100644
index 0000000..2aaafc0
--- /dev/null
+++ b/tests/TransitionTests/res/layout/activity_login.xml
@@ -0,0 +1,86 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/container"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <TextView
+        android:id="@+id/password"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignRight="@+id/username"
+        android:layout_below="@+id/username"
+        android:layout_marginTop="30dp"
+        android:textColor="#7f7f7f"
+        android:text="@string/password"
+        android:textAppearance="?android:attr/textAppearanceLarge" />
+
+    <EditText
+        android:id="@+id/usernameEdit"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignTop="@+id/username"
+        android:layout_marginLeft="14dp"
+        android:layout_toRightOf="@+id/username"
+        android:ems="10" />
+
+    <TextView
+        android:id="@+id/username"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentTop="true"
+        android:layout_marginLeft="20dp"
+        android:layout_marginTop="51dp"
+        android:text="@string/username"
+        android:textAppearance="?android:attr/textAppearanceLarge" />
+
+    <EditText
+        android:id="@+id/passwordEdit"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignBaseline="@+id/password"
+        android:layout_alignBottom="@+id/password"
+        android:layout_alignLeft="@+id/usernameEdit"
+        android:layout_alignParentRight="true"
+        android:editable="false"
+        android:ems="10" >
+
+        <requestFocus />
+    </EditText>
+
+    <Button
+        android:id="@+id/cancel"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_marginBottom="14dp"
+        android:layout_toLeftOf="@+id/passwordEdit"
+        android:onClick="sendMessage"
+        android:text="@string/cancel" />
+
+    <Button
+        android:id="@+id/submit"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignBaseline="@+id/cancel"
+        android:layout_alignBottom="@+id/cancel"
+        android:layout_alignLeft="@+id/passwordEdit"
+        android:layout_marginLeft="41dp"
+        android:onClick="sendMessage"
+        android:text="@string/submit" />
+
+    <TextView
+        android:id="@+id/newuser"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/passwordEdit"
+        android:layout_centerHorizontal="true"
+        android:layout_marginTop="16dp"
+        android:textColor="#0000ff"
+        android:text="@string/new_user"
+        android:clickable="true"
+        android:onClick="sendMessage"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textStyle="italic" />
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/button_template.xml b/tests/TransitionTests/res/layout/button_template.xml
new file mode 100644
index 0000000..9b867f2
--- /dev/null
+++ b/tests/TransitionTests/res/layout/button_template.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<Button xmlns:android="http://schemas.android.com/apk/res/android"
+              android:onClick="sendMessage"
+              android:id="@+id/button"
+              android:layout_width="wrap_content"
+              android:layout_height="wrap_content">
+
+</Button>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/changing_text_1.xml b/tests/TransitionTests/res/layout/changing_text_1.xml
new file mode 100644
index 0000000..88086a3
--- /dev/null
+++ b/tests/TransitionTests/res/layout/changing_text_1.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:id="@+id/container"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/submit"
+            android:onClick="sendMessage"
+            android:id="@+id/sceneSwitchButton"/>
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/shortText1"
+            android:background="#8f8f8f"
+            android:id="@+id/textview1"/>
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/buttona"
+            android:text="@string/button"/>
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/longText1"
+            android:background="#8f8f8f"
+            android:id="@+id/textview2"/>
+
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/buttonb"
+            android:text="@string/button"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/changing_text_2.xml b/tests/TransitionTests/res/layout/changing_text_2.xml
new file mode 100644
index 0000000..91fdfef
--- /dev/null
+++ b/tests/TransitionTests/res/layout/changing_text_2.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:id="@+id/container"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/submit"
+            android:onClick="sendMessage"
+            android:id="@+id/sceneSwitchButton"/>
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/longText2"
+            android:background="#8f8f8f"
+            android:id="@+id/textview1"/>
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/buttona"
+            android:text="@string/button"/>
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/shortText2"
+            android:background="#8f8f8f"
+            android:id="@+id/textview2"/>
+
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/buttonb"
+            android:text="@string/button"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/clipping_text_1.xml b/tests/TransitionTests/res/layout/clipping_text_1.xml
new file mode 100644
index 0000000..5fe45ab
--- /dev/null
+++ b/tests/TransitionTests/res/layout/clipping_text_1.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:id="@+id/container"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/submit"
+            android:onClick="sendMessage"
+            android:id="@+id/sceneSwitchButton"/>
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/shortText1"
+            android:background="#8f8f8f"
+            android:id="@+id/textview1"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/clipping_text_2.xml b/tests/TransitionTests/res/layout/clipping_text_2.xml
new file mode 100644
index 0000000..3a0e3f4
--- /dev/null
+++ b/tests/TransitionTests/res/layout/clipping_text_2.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:id="@+id/container"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+    <Button
+            android:layout_width="500dip"
+            android:layout_height="wrap_content"
+            android:text="@string/submit"
+            android:onClick="sendMessage"
+            android:id="@+id/sceneSwitchButton"/>
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/longText2"
+            android:background="#8f8f8f"
+            android:id="@+id/textview1"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/contact_collapsed.xml b/tests/TransitionTests/res/layout/contact_collapsed.xml
new file mode 100644
index 0000000..bfa97df
--- /dev/null
+++ b/tests/TransitionTests/res/layout/contact_collapsed.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="horizontal"
+              android:background="#fff"
+              android:layout_width="fill_parent"
+              android:id="@+id/topContainer"
+              android:layout_height="wrap_content">
+    <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/contact_arrow"
+            android:src="@drawable/arrow_thumbnail"/>
+    <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/contact_picture"/>
+    <LinearLayout android:orientation="vertical"
+                  android:layout_width="0dip"
+                  android:id="@+id/itemContainer"
+                  android:background="#ccc"
+                  android:layout_weight="1"
+                  android:layout_height="wrap_content">
+        <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:id="@+id/contact_name"/>
+        <LinearLayout android:orientation="vertical"
+                      android:visibility="gone"
+                      android:id="@+id/expanded_info"
+                      android:layout_width="wrap_content"
+                      android:layout_height="wrap_content">
+            <TextView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:id="@+id/contact_street"/>
+            <TextView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:id="@+id/contact_city"/>
+            <TextView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:id="@+id/contact_phone"/>
+            <TextView
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:id="@+id/contact_email"/>
+        </LinearLayout>
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/contact_expanded.xml b/tests/TransitionTests/res/layout/contact_expanded.xml
new file mode 100644
index 0000000..4007d4a
--- /dev/null
+++ b/tests/TransitionTests/res/layout/contact_expanded.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="horizontal"
+              android:background="#fff"
+              android:layout_width="fill_parent"
+              android:layout_height="fill_parent">
+    <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/contact_arrow"
+            android:src="@drawable/arrow_thumbnail"/>
+    <LinearLayout android:orientation="vertical"
+                  android:layout_width="fill_parent"
+                  android:layout_height="fill_parent">
+        <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:id="@+id/contact_name"/>
+        <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:id="@+id/contact_street"/>
+        <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:id="@+id/contact_city"/>
+        <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:id="@+id/contact_phone"/>
+        <TextView
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:id="@+id/contact_email"/>
+    </LinearLayout>
+    <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/contact_picture"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/contacts_list.xml b/tests/TransitionTests/res/layout/contacts_list.xml
new file mode 100644
index 0000000..d38704c
--- /dev/null
+++ b/tests/TransitionTests/res/layout/contacts_list.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:id="@+id/contactsContainer"
+              android:layout_width="fill_parent"
+              android:layout_height="fill_parent">
+
+
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/crossfade.xml b/tests/TransitionTests/res/layout/crossfade.xml
new file mode 100644
index 0000000..d766ce1
--- /dev/null
+++ b/tests/TransitionTests/res/layout/crossfade.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="fill_parent"
+              android:layout_height="fill_parent"
+              android:id="@+id/container">
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:onClick="sendMessage"
+            android:id="@+id/button"/>
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/shortText1"
+            android:id="@+id/textview"/>
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/longText1"
+            android:id="@+id/textview1"/>
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/someText"
+            android:id="@+id/textview2"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/crossfade_1.xml b/tests/TransitionTests/res/layout/crossfade_1.xml
new file mode 100644
index 0000000..4cc5bc9
--- /dev/null
+++ b/tests/TransitionTests/res/layout/crossfade_1.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="fill_parent"
+              android:layout_height="fill_parent"
+              android:id="@+id/container">
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:onClick="sendMessage"
+            android:id="@+id/button"/>
+
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/shortText2"
+            android:id="@+id/textview"/>
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/longText2"
+            android:id="@+id/textview1"/>
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/someText"
+            android:id="@+id/textview2"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/crossfade_image.xml b/tests/TransitionTests/res/layout/crossfade_image.xml
new file mode 100644
index 0000000..c46327a
--- /dev/null
+++ b/tests/TransitionTests/res/layout/crossfade_image.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:id="@+id/container"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+    <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/self_portrait_square_100"
+            android:onClick="sendMessage"
+            android:id="@+id/contact_picture"/>
+    <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/self_portrait_square_100"
+            android:onClick="sendMessage"
+            android:id="@+id/contact_picture1"/>
+    <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/self_portrait_square_100"
+            android:onClick="sendMessage"
+            android:id="@+id/contact_picture2"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/crossfade_multiple.xml b/tests/TransitionTests/res/layout/crossfade_multiple.xml
new file mode 100644
index 0000000..ca32ecb
--- /dev/null
+++ b/tests/TransitionTests/res/layout/crossfade_multiple.xml
@@ -0,0 +1,84 @@
+<?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">
+
+    <RadioGroup android:orientation="horizontal"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content">
+        <RadioButton android:layout_width="wrap_content"
+                     android:layout_height="wrap_content"
+                     android:onClick="changeTransitionType"
+                     android:id="@+id/reveal"
+                     android:text="@string/reveal"/>
+        <RadioButton android:layout_width="wrap_content"
+                     android:layout_height="wrap_content"
+                     android:onClick="changeTransitionType"
+                     android:id="@+id/crossfade"
+                     android:text="@string/crossfade"/>
+        <RadioButton android:layout_width="wrap_content"
+                     android:layout_height="wrap_content"
+                     android:onClick="changeTransitionType"
+                     android:id="@+id/inout"
+                     android:text="@string/inout"/>
+        <RadioButton android:layout_width="wrap_content"
+                     android:layout_height="wrap_content"
+                     android:onClick="changeTransitionType"
+                     android:id="@+id/textfade1"
+                     android:text="@string/textfade1"/>
+        <RadioButton android:layout_width="wrap_content"
+                     android:layout_height="wrap_content"
+                     android:onClick="changeTransitionType"
+                     android:id="@+id/textfade2"
+                     android:text="@string/textfade2"/>
+    </RadioGroup>
+    <LinearLayout android:orientation="horizontal"
+                  android:layout_width="match_parent"
+                  android:layout_height="wrap_content">
+        <Button
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:onClick="sendMessage"
+                android:text="@string/state1"
+                android:id="@+id/button1"/>
+        <Button
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:onClick="sendMessage"
+                android:text="@string/state2"
+                android:id="@+id/button2"/>
+        <Button
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:onClick="sendMessage"
+                android:text="@string/state3"
+                android:id="@+id/button3"/>
+    </LinearLayout>
+
+    <LinearLayout android:orientation="vertical"
+                  android:id="@+id/container"
+                  android:layout_width="match_parent"
+                  android:layout_height="match_parent">
+        <Button
+                android:layout_width="100dip"
+                android:layout_height="100dip"
+                android:textSize="40dip"
+                android:text="@string/a"
+                android:id="@+id/button"/>
+        <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textSize="40dip"
+                android:text="@string/state1"
+                android:id="@+id/textview"/>
+        <ImageView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:src="@drawable/self_portrait_square_100"
+                android:onClick="sendMessage"
+                android:id="@+id/imageview"/>
+    </LinearLayout>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/fading_hierarchy.xml b/tests/TransitionTests/res/layout/fading_hierarchy.xml
new file mode 100644
index 0000000..a24a6b6
--- /dev/null
+++ b/tests/TransitionTests/res/layout/fading_hierarchy.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:id="@+id/container"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/submit"
+            android:onClick="sendMessage"
+            android:id="@+id/sceneSwitchButton"/>
+    <LinearLayout
+            android:orientation="horizontal"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content">
+        <Button
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/button"/>
+        <LinearLayout
+                android:orientation="vertical"
+                android:id="@+id/removingContainer"
+                android:layout_width="wrap_content"
+                android:layout_height="200dip">
+            <Button
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/removingButton"
+                    android:id="@+id/removingButton"/>
+        </LinearLayout>
+        <Button
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/button"/>
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/fading_test.xml b/tests/TransitionTests/res/layout/fading_test.xml
new file mode 100644
index 0000000..3728b5e
--- /dev/null
+++ b/tests/TransitionTests/res/layout/fading_test.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:id="@+id/container"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/submit"
+            android:onClick="sendMessage"
+            android:id="@+id/sceneSwitchButton"/>
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/removingButton"
+            android:id="@+id/removingButton"/>
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/invisibleButton"
+            android:id="@+id/invisibleButton"/>
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/goneButton"
+            android:id="@+id/goneButton"/>
+
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/button"
+            android:text="@string/button"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/fading_test_scene_2.xml b/tests/TransitionTests/res/layout/fading_test_scene_2.xml
new file mode 100644
index 0000000..baf5b4d
--- /dev/null
+++ b/tests/TransitionTests/res/layout/fading_test_scene_2.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:id="@+id/container"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/submit"
+            android:onClick="sendMessage"
+            android:id="@+id/sceneSwitchButton"/>
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/invisibleButton"
+            android:visibility="invisible"
+            android:id="@+id/invisibleButton"/>
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/goneButton"
+            android:visibility="gone"
+            android:id="@+id/goneButton"/>
+
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/button"
+            android:text="@string/button"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/fading_test_simple.xml b/tests/TransitionTests/res/layout/fading_test_simple.xml
new file mode 100644
index 0000000..d201eca
--- /dev/null
+++ b/tests/TransitionTests/res/layout/fading_test_simple.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:id="@+id/container"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/submit"
+            android:onClick="sendMessage"
+            android:id="@+id/sceneSwitchButton"/>
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/removingButton"
+            android:id="@+id/removingButton"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/fading_test_simple2.xml b/tests/TransitionTests/res/layout/fading_test_simple2.xml
new file mode 100644
index 0000000..80f3f94
--- /dev/null
+++ b/tests/TransitionTests/res/layout/fading_test_simple2.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:id="@+id/container"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="50dip"
+            android:text="@string/submit"
+            android:onClick="sendMessage"
+            android:id="@+id/sceneSwitchButton"/>
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/removingButton"
+            android:visibility="invisible"
+            android:id="@+id/removingButton"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/hierarchical_move.xml b/tests/TransitionTests/res/layout/hierarchical_move.xml
new file mode 100644
index 0000000..1e70ba9
--- /dev/null
+++ b/tests/TransitionTests/res/layout/hierarchical_move.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:id="@+id/container"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/submit"
+            android:onClick="sendMessage"
+            android:id="@+id/sceneSwitchButton"/>
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/button0"
+            android:id="@+id/button0"/>
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/button1"
+            android:id="@+id/button1"/>
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/button2"
+            android:id="@+id/button2"/>
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/button3"
+            android:id="@+id/button3"/>
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/button4"
+            android:id="@+id/button4"/>
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/button5"
+            android:id="@+id/button5"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/incorrect_password.xml b/tests/TransitionTests/res/layout/incorrect_password.xml
new file mode 100644
index 0000000..af59618
--- /dev/null
+++ b/tests/TransitionTests/res/layout/incorrect_password.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/container"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" >
+
+    <Button
+        android:id="@+id/okay"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_centerHorizontal="true"
+        android:layout_marginBottom="164dp"
+        android:onClick="sendMessage"
+        android:text="@string/okay" />
+
+    <TextView
+        android:id="@+id/incorrectpassword"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_above="@+id/okay"
+        android:layout_centerHorizontal="true"
+        android:layout_marginBottom="93dp"
+        android:text="@string/incorrect_password"
+        android:textAppearance="?android:attr/textAppearanceLarge" />
+
+    <TextView
+        android:id="@+id/tryagain"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignTop="@+id/incorrectpassword"
+        android:layout_centerHorizontal="true"
+        android:layout_marginTop="35dp"
+        android:text="@string/try_again"
+        android:textAppearance="?android:attr/textAppearanceLarge" />
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/instance_targets.xml b/tests/TransitionTests/res/layout/instance_targets.xml
new file mode 100644
index 0000000..5677d52
--- /dev/null
+++ b/tests/TransitionTests/res/layout/instance_targets.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:id="@+id/container">
+
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentLeft="true"
+            android:onClick="sendMessage"
+            android:id="@+id/button0"/>
+
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_below="@+id/button0"
+            android:onClick="sendMessage"
+            android:id="@+id/button1"/>
+
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_below="@+id/button1"
+            android:onClick="sendMessage"
+            android:id="@+id/button2"/>
+
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_below="@+id/button2"
+            android:onClick="sendMessage"
+            android:id="@+id/button3"/>
+
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/interruption.xml b/tests/TransitionTests/res/layout/interruption.xml
new file mode 100644
index 0000000..9fdb27a
--- /dev/null
+++ b/tests/TransitionTests/res/layout/interruption.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:id="@+id/container"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+    <RadioGroup android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical">
+        <RadioButton android:id="@+id/scene1RB"
+                     android:layout_width="wrap_content"
+                     android:layout_height="wrap_content"
+                     android:text="@string/state1"
+                     android:onClick="onRadioButtonClicked"/>
+        <RadioButton android:id="@+id/scene2RB"
+                     android:layout_width="wrap_content"
+                     android:layout_height="wrap_content"
+                     android:text="@string/state2"
+                     android:onClick="onRadioButtonClicked"/>
+        <RadioButton android:id="@+id/scene3RB"
+                     android:layout_width="wrap_content"
+                     android:layout_height="wrap_content"
+                     android:text="@string/state3"
+                     android:onClick="onRadioButtonClicked"/>
+        <RadioButton android:id="@+id/scene4RB"
+                     android:layout_width="wrap_content"
+                     android:layout_height="wrap_content"
+                     android:text="@string/state4"
+                     android:onClick="onRadioButtonClicked"/>
+    </RadioGroup>
+
+    <LinearLayout
+            android:orientation="vertical"
+            android:id="@+id/sceneRoot"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent">
+
+        <include layout="@layout/interruption_inner_1"/>
+
+    </LinearLayout>
+
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/interruption_inner_1.xml b/tests/TransitionTests/res/layout/interruption_inner_1.xml
new file mode 100644
index 0000000..f82dfb0
--- /dev/null
+++ b/tests/TransitionTests/res/layout/interruption_inner_1.xml
@@ -0,0 +1,20 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:id="@+id/buttonContainer">
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/button"
+            android:layout_alignParentTop="true"
+            android:layout_alignParentLeft="true"
+            android:text="@string/state1"/>
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/button1"
+            android:layout_alignLeft="@+id/button"
+            android:layout_below="@+id/button"
+            android:text="@string/state1"/>
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/interruption_inner_2.xml b/tests/TransitionTests/res/layout/interruption_inner_2.xml
new file mode 100644
index 0000000..e6821d6
--- /dev/null
+++ b/tests/TransitionTests/res/layout/interruption_inner_2.xml
@@ -0,0 +1,20 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:id="@+id/buttonContainer">
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentTop="true"
+            android:id="@+id/button"
+            android:layout_alignParentRight="true"
+            android:text="@string/state2"/>
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/button1"
+            android:layout_alignLeft="@+id/button"
+            android:layout_below="@+id/button"
+            android:text="@string/state2"/>
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/interruption_inner_3.xml b/tests/TransitionTests/res/layout/interruption_inner_3.xml
new file mode 100644
index 0000000..4e40150
--- /dev/null
+++ b/tests/TransitionTests/res/layout/interruption_inner_3.xml
@@ -0,0 +1,20 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:id="@+id/buttonContainer">
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/button"
+            android:layout_alignParentBottom="true"
+            android:layout_alignParentLeft="true"
+            android:text="@string/state3"/>
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/button1"
+            android:layout_alignLeft="@+id/button"
+            android:layout_above="@+id/button"
+            android:text="@string/state3"/>
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/interruption_inner_4.xml b/tests/TransitionTests/res/layout/interruption_inner_4.xml
new file mode 100644
index 0000000..8c3661e
--- /dev/null
+++ b/tests/TransitionTests/res/layout/interruption_inner_4.xml
@@ -0,0 +1,20 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:id="@+id/buttonContainer">
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/button"
+            android:layout_alignParentBottom="true"
+            android:layout_alignParentRight="true"
+            android:text="@string/state4"/>
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/button1"
+            android:layout_alignLeft="@+id/button"
+            android:layout_above="@+id/button"
+            android:text="@string/state4"/>
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/list_view_add_remove.xml b/tests/TransitionTests/res/layout/list_view_add_remove.xml
new file mode 100644
index 0000000..230511f
--- /dev/null
+++ b/tests/TransitionTests/res/layout/list_view_add_remove.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:id="@+id/container"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+    <ListView
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:id="@+id/listview"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/login_password.xml b/tests/TransitionTests/res/layout/login_password.xml
new file mode 100644
index 0000000..1e75694
--- /dev/null
+++ b/tests/TransitionTests/res/layout/login_password.xml
@@ -0,0 +1,86 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/container"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".LoginActivity" >
+
+    <TextView
+        android:id="@+id/password"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignRight="@+id/username"
+        android:layout_below="@+id/username"
+        android:layout_marginTop="30dp"
+        android:text="@string/password"
+        android:textAppearance="?android:attr/textAppearanceLarge" />
+
+    <EditText
+        android:id="@+id/usernameEdit"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignTop="@+id/username"
+        android:layout_marginLeft="14dp"
+        android:layout_toRightOf="@+id/username"
+        android:ems="10" />
+
+    <TextView
+        android:id="@+id/username"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentTop="true"
+        android:layout_marginLeft="20dp"
+        android:layout_marginTop="51dp"
+        android:text="@string/username"
+        android:textAppearance="?android:attr/textAppearanceLarge" />
+
+    <EditText
+        android:id="@+id/passwordEdit"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignBaseline="@+id/password"
+        android:layout_alignBottom="@+id/password"
+        android:layout_alignLeft="@+id/usernameEdit"
+        android:layout_alignParentRight="true"
+        android:ems="10" >
+
+        <requestFocus />
+    </EditText>
+
+    <Button
+        android:id="@+id/cancel"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_marginBottom="14dp"
+        android:layout_toLeftOf="@+id/passwordEdit"
+        android:onClick="sendMessage"
+        android:text="@string/cancel" />
+
+    <Button
+        android:id="@+id/submit"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignBaseline="@+id/cancel"
+        android:layout_alignBottom="@+id/cancel"
+        android:layout_alignLeft="@+id/passwordEdit"
+        android:layout_marginLeft="41dp"
+        android:onClick="sendMessage"
+        android:text="@string/submit" />
+
+    <TextView
+        android:id="@+id/newuser"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/passwordEdit"
+        android:layout_centerHorizontal="true"
+        android:layout_marginTop="16dp"
+        android:textColor="#0000ff"
+        android:text="@string/new_user"
+        android:clickable="true"
+        android:onClick="sendMessage"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textStyle="italic" />
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/main.xml b/tests/TransitionTests/res/layout/main.xml
new file mode 100644
index 0000000..b42318e
--- /dev/null
+++ b/tests/TransitionTests/res/layout/main.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:id="@+id/container">
+    <Button
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:id="@+id/button"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/new_user.xml b/tests/TransitionTests/res/layout/new_user.xml
new file mode 100644
index 0000000..f8dfab06
--- /dev/null
+++ b/tests/TransitionTests/res/layout/new_user.xml
@@ -0,0 +1,92 @@
+<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:id="@+id/container"
+    tools:context=".LoginActivity" >
+
+    <TextView
+        android:id="@+id/password"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignRight="@+id/username"
+        android:layout_below="@+id/username"
+        android:layout_marginTop="30dp"
+        android:text="@string/password"
+        android:textAppearance="?android:attr/textAppearanceLarge" />
+
+    <EditText
+        android:id="@+id/usernameEdit"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignTop="@+id/username"
+        android:layout_marginLeft="14dp"
+        android:layout_toRightOf="@+id/username"
+        android:ems="10" />
+
+    <TextView
+        android:id="@+id/username"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentTop="true"
+        android:layout_marginLeft="20dp"
+        android:layout_marginTop="51dp"
+        android:text="@string/username"
+        android:textAppearance="?android:attr/textAppearanceLarge" />
+
+    <EditText
+        android:id="@+id/passwordEdit"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignBaseline="@+id/password"
+        android:layout_alignBottom="@+id/password"
+        android:layout_alignLeft="@+id/usernameEdit"
+        android:layout_alignParentRight="true"
+        android:ems="10" >
+
+        <requestFocus />
+    </EditText>
+
+    <Button
+        android:id="@+id/cancel"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_marginBottom="14dp"
+        android:layout_toLeftOf="@+id/passwordEdit"
+        android:onClick="sendMessage"
+        android:text="@string/cancel" />
+
+    <Button
+        android:id="@+id/submit"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignBaseline="@+id/cancel"
+        android:layout_alignBottom="@+id/cancel"
+        android:layout_alignLeft="@+id/passwordEdit"
+        android:layout_marginLeft="41dp"
+        android:onClick="sendMessage"
+        android:text="@string/submit" />
+
+    <EditText
+        android:id="@+id/retypeEdit"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignBaseline="@+id/retype"
+        android:layout_alignBottom="@+id/retype"
+        android:layout_alignLeft="@+id/passwordEdit"
+        android:layout_alignParentRight="true"
+        android:ems="10" />
+
+    <TextView
+        android:id="@+id/retype"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/passwordEdit"
+        android:layout_marginTop="26dp"
+        android:layout_toLeftOf="@+id/usernameEdit"
+        android:text="@string/retype"
+        android:textAppearance="?android:attr/textAppearanceLarge" />
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/overlay_test.xml b/tests/TransitionTests/res/layout/overlay_test.xml
new file mode 100644
index 0000000..edd0393
--- /dev/null
+++ b/tests/TransitionTests/res/layout/overlay_test.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:id="@+id/container"
+              android:layout_width="fill_parent"
+              android:layout_height="fill_parent">
+
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/button"
+            android:text="@string/start"
+            android:onClick="onClick"/>
+
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/fadingButton"
+            android:id="@+id/fadingButton"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/reparenting.xml b/tests/TransitionTests/res/layout/reparenting.xml
new file mode 100644
index 0000000..b3bfbb9
--- /dev/null
+++ b/tests/TransitionTests/res/layout/reparenting.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="fill_parent"
+              android:layout_height="fill_parent"
+              android:id="@+id/container">
+    <LinearLayout
+            android:orientation="horizontal"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/container1"/>
+    <LinearLayout
+            android:orientation="vertical"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/container2"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/resources_test_layout.xml b/tests/TransitionTests/res/layout/resources_test_layout.xml
new file mode 100644
index 0000000..48affa0
--- /dev/null
+++ b/tests/TransitionTests/res/layout/resources_test_layout.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ImageView
+    src="@drawable/icon"/>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/results_screen.xml b/tests/TransitionTests/res/layout/results_screen.xml
new file mode 100644
index 0000000..8550a5e
--- /dev/null
+++ b/tests/TransitionTests/res/layout/results_screen.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="fill_parent"
+              android:layout_height="fill_parent"
+              android:background="#7f7f7f"
+              android:id="@+id/container">
+    <LinearLayout android:orientation="horizontal"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:layout_gravity="top|right"
+                  android:id="@+id/searchContainer">
+        <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/searchText"
+                android:id="@+id/searchText"/>
+        <Button
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/searchButton"
+                android:onClick="sendMessage"
+                android:id="@+id/searchButton"/>
+    </LinearLayout>
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:text="@string/resultsTitle"
+            android:id="@+id/resultsText"/>
+    <LinearLayout android:layout_width="match_parent"
+            android:layout_height="0dip"
+            android:layout_weight="1"
+            android:orientation="vertical"
+            android:id="@+id/resultsList">
+        <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/placeholder"/>
+        <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/placeholder"/>
+        <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/placeholder"/>
+        <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/placeholder"/>
+        <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/placeholder"/>
+        <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/placeholder"/>
+        <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/placeholder"/>
+
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/search_screen.xml b/tests/TransitionTests/res/layout/search_screen.xml
new file mode 100644
index 0000000..947702b
--- /dev/null
+++ b/tests/TransitionTests/res/layout/search_screen.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="fill_parent"
+              android:layout_height="fill_parent"
+              android:background="#000000"
+              android:id="@+id/container">
+    <LinearLayout android:orientation="horizontal"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:layout_gravity="center"
+                  android:id="@+id/searchContainer">
+        <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/searchText"
+                android:id="@+id/searchText"/>
+        <Button
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/searchButton"
+                android:onClick="sendMessage"
+                android:id="@+id/searchButton"/>
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/success.xml b/tests/TransitionTests/res/layout/success.xml
new file mode 100644
index 0000000..9c265ef
--- /dev/null
+++ b/tests/TransitionTests/res/layout/success.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/container"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" >
+
+    <TextView
+            android:id="@+id/loginsuccessful"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_centerHorizontal="true"
+            android:layout_marginBottom="93dp"
+            android:text="@string/login_successful"
+            android:textAppearance="?android:attr/textAppearanceLarge" />
+
+    <TextView
+            android:id="@+id/firstactivityscreen"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignTop="@+id/loginsuccessful"
+            android:layout_centerHorizontal="true"
+            android:layout_marginTop="35dp"
+            android:text="@string/first_activity_screen"
+            android:textAppearance="?android:attr/textAppearanceLarge" />
+
+    <Button
+            android:id="@+id/reset"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentBottom="true"
+            android:layout_centerHorizontal="true"
+            android:layout_marginBottom="164dp"
+            android:onClick="sendMessage"
+            android:text="@string/reset" />
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/surface_texture_views.xml b/tests/TransitionTests/res/layout/surface_texture_views.xml
new file mode 100644
index 0000000..9260bc0
--- /dev/null
+++ b/tests/TransitionTests/res/layout/surface_texture_views.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:id="@+id/container"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+    <Button
+            android:text="@string/toggle"
+            android:id="@+id/toggleButton"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/two_buttons.xml b/tests/TransitionTests/res/layout/two_buttons.xml
new file mode 100644
index 0000000..23d59f8
--- /dev/null
+++ b/tests/TransitionTests/res/layout/two_buttons.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="fill_parent"
+              android:layout_height="fill_parent"
+              android:id="@+id/container">
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/button1"/>
+    <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/button2"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/unique_id_test.xml b/tests/TransitionTests/res/layout/unique_id_test.xml
new file mode 100644
index 0000000..9b7eb10
--- /dev/null
+++ b/tests/TransitionTests/res/layout/unique_id_test.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:id="@+id/container"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/layout/username_taken.xml b/tests/TransitionTests/res/layout/username_taken.xml
new file mode 100644
index 0000000..9484e69
--- /dev/null
+++ b/tests/TransitionTests/res/layout/username_taken.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/container"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" >
+
+    <Button
+            android:id="@+id/okay"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentBottom="true"
+            android:layout_centerHorizontal="true"
+            android:layout_marginBottom="164dp"
+            android:onClick="sendMessage"
+            android:text="@string/okay" />
+
+    <TextView
+            android:id="@+id/usernametaken"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_above="@+id/okay"
+            android:layout_centerHorizontal="true"
+            android:layout_marginBottom="93dp"
+            android:text="@string/username_taken"
+            android:textAppearance="?android:attr/textAppearanceLarge" />
+
+    <TextView
+            android:id="@+id/textView2"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignTop="@+id/usernametaken"
+            android:layout_centerHorizontal="true"
+            android:layout_marginTop="35dp"
+            android:text="@string/try_again"
+            android:textAppearance="?android:attr/textAppearanceLarge" />
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/transition/colorizer_transition.xml b/tests/TransitionTests/res/transition/colorizer_transition.xml
new file mode 100644
index 0000000..12f4be7
--- /dev/null
+++ b/tests/TransitionTests/res/transition/colorizer_transition.xml
@@ -0,0 +1,6 @@
+<recolor xmlns:android="http://schemas.android.com/apk/res/android">
+    <targets>
+        <target android:targetId="@id/password"/>
+        <target android:targetId="@id/passwordEdit"/>
+    </targets>
+</recolor>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/transition/fader.xml b/tests/TransitionTests/res/transition/fader.xml
new file mode 100644
index 0000000..c71fd94
--- /dev/null
+++ b/tests/TransitionTests/res/transition/fader.xml
@@ -0,0 +1 @@
+<fade/>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/transition/login_slider_transition.xml b/tests/TransitionTests/res/transition/login_slider_transition.xml
new file mode 100644
index 0000000..2317857
--- /dev/null
+++ b/tests/TransitionTests/res/transition/login_slider_transition.xml
@@ -0,0 +1,22 @@
+<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
+    <slide>
+        <targets>
+            <target android:targetId="@id/retype"/>
+            <target android:targetId="@id/retypeEdit"/>
+        </targets>
+    </slide>
+    <recolor>
+        <targets>
+            <target android:targetId="@id/password"/>
+            <target android:targetId="@id/passwordEdit"/>
+        </targets>
+    </recolor>
+    <fade/>
+</transitionSet>
+
+<!--
+                TransitionSet slider = new TransitionSet();
+        slider.addTransition(new Slide(R.id.retype, R.id.retypeEdit));
+        slider.addTransition(new Recolor(R.id.password, R.id.passwordEdit));
+        slider.addTransition(new Fade());
+-->
\ No newline at end of file
diff --git a/tests/TransitionTests/res/transition/login_transition_mgr.xml b/tests/TransitionTests/res/transition/login_transition_mgr.xml
new file mode 100644
index 0000000..5d07be0
--- /dev/null
+++ b/tests/TransitionTests/res/transition/login_transition_mgr.xml
@@ -0,0 +1,14 @@
+<transitionManager xmlns:android="http://schemas.android.com/apk/res/android">
+    <transition android:fromScene="@layout/activity_login" android:toScene="@layout/new_user"
+                android:transition="@transition/login_slider_transition"/>
+    <transition android:fromScene="@layout/login_password" android:toScene="@layout/new_user"
+                android:transition="@transition/login_slider_transition"/>
+    <transition android:fromScene="@layout/new_user" android:toScene="@layout/activity_login"
+                android:transition="@transition/login_slider_transition"/>
+    <transition android:fromScene="@layout/new_user" android:toScene="@layout/login_password"
+                android:transition="@transition/login_slider_transition"/>
+    <transition android:fromScene="@layout/activity_login" android:toScene="@layout/login_password"
+                android:transition="@transition/colorizer_transition"/>
+    <transition android:fromScene="@layout/login_password" android:toScene="@layout/activity_login"
+                android:transition="@transition/colorizer_transition"/>
+</transitionManager>
diff --git a/tests/TransitionTests/res/transition/mover.xml b/tests/TransitionTests/res/transition/mover.xml
new file mode 100644
index 0000000..b23d2a5
--- /dev/null
+++ b/tests/TransitionTests/res/transition/mover.xml
@@ -0,0 +1 @@
+<changeBounds/>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/transition/mover_fader.xml b/tests/TransitionTests/res/transition/mover_fader.xml
new file mode 100644
index 0000000..ef11676
--- /dev/null
+++ b/tests/TransitionTests/res/transition/mover_fader.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
+    <fade/>
+    <changeBounds/>
+</transitionSet>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/transition/my_scene.xml b/tests/TransitionTests/res/transition/my_scene.xml
new file mode 100644
index 0000000..b8278c9
--- /dev/null
+++ b/tests/TransitionTests/res/transition/my_scene.xml
@@ -0,0 +1,3 @@
+<scene >
+
+</scene>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/transition/my_transition.xml b/tests/TransitionTests/res/transition/my_transition.xml
new file mode 100644
index 0000000..022313c
--- /dev/null
+++ b/tests/TransitionTests/res/transition/my_transition.xml
@@ -0,0 +1,20 @@
+<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
+    <fade></fade>
+    <transitionSet>
+        <changeBounds android:duration="500">
+            <targets>
+                <target android:targetId="@id/container"/>
+                <target android:targetId="@id/resultsList"/>
+            </targets>
+        </changeBounds>
+        <transitionSet>
+            <targets>
+                <target android:targetId="@id/container"/>
+                <target android:targetId="@id/resultsList"/>
+            </targets>
+            <fade android:startOffset="25"/>
+        </transitionSet>
+        <recolor/>
+    </transitionSet>
+    <changeBounds/>
+</transitionSet>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/transition/my_transition_mgr.xml b/tests/TransitionTests/res/transition/my_transition_mgr.xml
new file mode 100644
index 0000000..5d8f799
--- /dev/null
+++ b/tests/TransitionTests/res/transition/my_transition_mgr.xml
@@ -0,0 +1,6 @@
+<transitionManager xmlns:android="http://schemas.android.com/apk/res/android">
+    <transition android:fromScene="@layout/search_screen" android:toScene="@layout/results_screen"
+                android:transition="@transition/mover_fader"/>
+    <transition android:fromScene="@layout/results_screen" android:toScene="@layout/search_screen"
+                android:transition="@transition/mover_fader"/>
+</transitionManager>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/transition/username_taken_scene.xml b/tests/TransitionTests/res/transition/username_taken_scene.xml
new file mode 100644
index 0000000..b2f050e
--- /dev/null
+++ b/tests/TransitionTests/res/transition/username_taken_scene.xml
@@ -0,0 +1,2 @@
+<scene xmlns:android="http://schemas.android.com/apk/res/android"
+       android:layout="@layout/username_taken"/>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/values-v11/styles.xml b/tests/TransitionTests/res/values-v11/styles.xml
new file mode 100644
index 0000000..541752f
--- /dev/null
+++ b/tests/TransitionTests/res/values-v11/styles.xml
@@ -0,0 +1,11 @@
+<resources>
+
+    <!--
+        Base application theme for API 11+. This theme completely replaces
+        AppBaseTheme from res/values/styles.xml on API 11+ devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Holo.Light">
+        <!-- API 11 theme customizations can go here. -->
+    </style>
+
+</resources>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/values-v14/styles.xml b/tests/TransitionTests/res/values-v14/styles.xml
new file mode 100644
index 0000000..f20e015
--- /dev/null
+++ b/tests/TransitionTests/res/values-v14/styles.xml
@@ -0,0 +1,12 @@
+<resources>
+
+    <!--
+        Base application theme for API 14+. This theme completely replaces
+        AppBaseTheme from BOTH res/values/styles.xml and
+        res/values-v11/styles.xml on API 14+ devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
+        <!-- API 14 theme customizations can go here. -->
+    </style>
+
+</resources>
\ No newline at end of file
diff --git a/tests/TransitionTests/res/values/strings.xml b/tests/TransitionTests/res/values/strings.xml
new file mode 100644
index 0000000..9cf7a94
--- /dev/null
+++ b/tests/TransitionTests/res/values/strings.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">StatesTest</string>
+    <string name="states_test1">StatesTestv21</string>
+    <string name="states_test_auto_targets">StatesTestAutoTargets</string>
+    <string name="states_test_auto_transition">StatesTestAutoTransition</string>
+    <string name="states_test_auto_transition2">StatesTestAutoTransition2</string>
+    <string name="contacts_expansion">ContactsExpansion</string>
+    <string name="states_test3">StatesTest3</string>
+    <string name="states_test4">StatesTest4</string>
+    <string name="states_test5">StatesTest5</string>
+    <string name="states_test6">StatesTest6</string>
+    <string name="button">Button</string>
+    <string name="searchButton">Search</string>
+    <string name="searchText">This is some text</string>
+    <string name="resultsTitle">Search Results</string>
+    <string name="placeholder">Blah Blah Blah</string>
+    <string name="username">Username:</string>
+    <string name="password">Password:</string>
+    <string name="retype">Retype:</string>
+    <string name="new_user">New User?</string>
+    <string name="incorrect_password">Incorrect password:</string>
+    <string name="try_again">Please try again.</string>
+    <string name="login_successful">Success!</string>
+    <string name="first_activity_screen">First activity screen</string>
+    <string name="username_taken">Username taken:</string>
+    <string name="cancel">Cancel</string>
+    <string name="submit">Submit</string>
+    <string name="okay">Okay</string>
+    <string name="reset">Reset</string>
+    <string name="fadingButton">Fading Button</string>
+    <string name="removingButton">Removing Button</string>
+    <string name="invisibleButton">invisible Button</string>
+    <string name="goneButton">Gone Button</string>
+    <string name="start">Start</string>
+    <string name="toggle">Toggle State</string>
+    <string name="someText">This is some text</string>
+    <string name="shortText1">This is some short text</string>
+    <string name="shortText2">Not much text here</string>
+    <string name="longText1">This is the beginning of the Spring of my discontent. In the event of a real emergency, you would be notified by email. Fear not, for death comes swiftly.</string>
+    <string name="longText2">When do we get to eat? I like all things, especially following strong leaders, and mangy cats. Break glass in emergency. The purpose of a framework is to provide the facilities and functionality of a powerful toolkit with the simplicity of a refrigerator.</string>
+    <string name="state1">State 1</string>
+    <string name="state2">State 2</string>
+    <string name="state3">State 3</string>
+    <string name="state4">State 4</string>
+    <string name="button0">Button 0</string>
+    <string name="button1">Button 1</string>
+    <string name="button2">Button 2</string>
+    <string name="button3">Button 3</string>
+    <string name="button4">Button 4</string>
+    <string name="button5">Button 5</string>
+    <string name="a">A</string>
+    <string name="b">B</string>
+    <string name="c">C</string>
+    <string name="reveal">Reveal</string>
+    <string name="crossfade">Crossfade</string>
+    <string name="inout">In/Out</string>
+    <string name="textfade1">T1</string>
+    <string name="textfade2">T2</string>
+</resources>
diff --git a/tests/TransitionTests/res/values/styles.xml b/tests/TransitionTests/res/values/styles.xml
new file mode 100644
index 0000000..4a10ca4
--- /dev/null
+++ b/tests/TransitionTests/res/values/styles.xml
@@ -0,0 +1,20 @@
+<resources>
+
+    <!--
+        Base application theme, dependent on API level. This theme is replaced
+        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Light">
+        <!--
+            Theme customizations available in newer API levels can go in
+            res/values-vXX/styles.xml, while customizations related to
+            backward-compatibility can go here.
+        -->
+    </style>
+
+    <!-- Application theme. -->
+    <style name="AppTheme" parent="AppBaseTheme">
+        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
+    </style>
+
+</resources>
\ No newline at end of file
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ChangingText.java b/tests/TransitionTests/src/com/android/transitiontests/ChangingText.java
new file mode 100644
index 0000000..a1ddd74
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/ChangingText.java
@@ -0,0 +1,61 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.transition.ChangeBounds;
+import android.transition.TextChange;
+import android.transition.TransitionManager;
+
+public class ChangingText extends Activity {
+
+    Scene mScene1, mScene2;
+    ViewGroup mSceneRoot;
+    TransitionSet mChanger;
+    Scene mCurrentScene;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.changing_text_1);
+
+        View container = findViewById(R.id.container);
+        mSceneRoot = (ViewGroup) container.getParent();
+
+        mScene1 = Scene.getSceneForLayout(mSceneRoot, R.layout.changing_text_1, this);
+        mScene2 = Scene.getSceneForLayout(mSceneRoot, R.layout.changing_text_2, this);
+
+        mChanger = new TransitionSet().setOrdering(TransitionSet.ORDERING_TOGETHER);
+        mChanger.addTransition(new ChangeBounds()).addTransition(new TextChange());
+
+        mCurrentScene = mScene1;
+    }
+
+    public void sendMessage(View view) {
+        if (mCurrentScene == mScene1) {
+            TransitionManager.go(mScene2, mChanger);
+            mCurrentScene = mScene2;
+        } else {
+            TransitionManager.go(mScene1, mChanger);
+            mCurrentScene = mScene1;
+        }
+    }
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ClippingText.java b/tests/TransitionTests/src/com/android/transitiontests/ClippingText.java
new file mode 100644
index 0000000..85702fa
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/ClippingText.java
@@ -0,0 +1,68 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.transition.ChangeBounds;
+import android.view.View;
+import android.view.ViewGroup;
+import android.transition.Scene;
+import android.widget.Button;
+import android.transition.Fade;
+import android.transition.TextChange;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
+
+public class ClippingText extends Activity {
+
+    Button mRemovingButton, mInvisibleButton, mGoneButton;
+    Scene mScene1, mScene2;
+    ViewGroup mSceneRoot;
+    //    static Fade sFade = new Fade(R.id.removingButton, R.id.invisibleButton, R.id.goneButton);
+    Fade fader;
+    TransitionSet mChanger;
+    Scene mCurrentScene;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.clipping_text_1);
+
+        View container = (View) findViewById(R.id.container);
+        mSceneRoot = (ViewGroup) container.getParent();
+
+        mScene1 = Scene.getSceneForLayout(mSceneRoot, R.layout.clipping_text_1, this);
+        mScene2 = Scene.getSceneForLayout(mSceneRoot, R.layout.clipping_text_2, this);
+
+        mChanger = new TransitionSet().setOrdering(TransitionSet.ORDERING_TOGETHER);
+        ChangeBounds changeBounds = new ChangeBounds();
+        changeBounds.setResizeClip(true);
+        mChanger.addTransition(changeBounds).addTransition(new TextChange());
+
+        mCurrentScene = mScene1;
+    }
+
+    public void sendMessage(View view) {
+        if (mCurrentScene == mScene1) {
+            TransitionManager.go(mScene2, mChanger);
+            mCurrentScene = mScene2;
+        } else {
+            TransitionManager.go(mScene1, mChanger);
+            mCurrentScene = mScene1;
+        }
+    }
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ContactsExpansion.java b/tests/TransitionTests/src/com/android/transitiontests/ContactsExpansion.java
new file mode 100644
index 0000000..f687da3
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/ContactsExpansion.java
@@ -0,0 +1,124 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.transition.ChangeBounds;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.transition.Fade;
+import android.transition.Scene;
+import android.transition.Transition;
+import android.transition.TransitionSet;
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.transition.Crossfade;
+import android.transition.Rotate;
+import android.transition.TransitionManager;
+
+public class ContactsExpansion extends Activity {
+
+    String contactsData[] = {
+            "Alan Green", "56 Bob Street", "Boston, MA 02134", "617-555-5555", "blatt@blatt.com",
+            "Bob Foonman", "92 The Avenue", "Chico, CA 78456", "510-555-5556", "bob@jerk.com",
+            "Tracey Sue", "95 Houses Street", "San Jose, CA 96504", "415-555-5557", "ts@thing.com",
+    };
+
+    View currentItem = null;
+
+    TransitionSet mMyAutoTransition = new TransitionSet().
+            setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.contacts_list);
+        ViewGroup contactsContainer = (ViewGroup) findViewById(R.id.contactsContainer);
+
+        int contactsIndex = 0;
+        addContact(contactsContainer, contactsIndex, R.drawable.self_portrait_square_100);
+        contactsIndex += 5;
+        addContact(contactsContainer, contactsIndex, R.drawable.self_portrait_square_100);
+        contactsIndex += 5;
+        addContact(contactsContainer, contactsIndex, R.drawable.self_portrait_square_100);
+
+    }
+
+    private void addContact(ViewGroup container, int dataIndex, int thumbnailID) {
+        LayoutInflater inflater = (LayoutInflater)
+                getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        View contactItem = inflater.inflate(R.layout.contact_collapsed, container, false);
+        ImageView thumbnailView = (ImageView) contactItem.findViewById(R.id.contact_picture);
+        thumbnailView.setImageResource(thumbnailID);
+        ((TextView)contactItem.findViewById(R.id.contact_name)).setText(contactsData[dataIndex++]);
+        ((TextView)contactItem.findViewById(R.id.contact_street)).
+                setText(contactsData[dataIndex++]);
+        ((TextView)contactItem.findViewById(R.id.contact_city)).setText(contactsData[dataIndex++]);
+        ((TextView)contactItem.findViewById(R.id.contact_phone)).setText(contactsData[dataIndex++]);
+        ((TextView)contactItem.findViewById(R.id.contact_email)).setText(contactsData[dataIndex++]);
+        container.addView(contactItem);
+
+        final TransitionSet myTransition = new TransitionSet();
+        myTransition.addTransition(new Fade(Fade.IN)).
+                addTransition(new Rotate().addTarget(R.id.contact_arrow)).
+                addTransition(new ChangeBounds()).
+                addTransition(new Fade(Fade.OUT)).
+                addTransition(new Crossfade().addTarget(R.id.contact_picture));
+        final ToggleScene toggleScene = new ToggleScene(container, myTransition);
+        contactItem.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                currentItem = v;
+                toggleScene.changeToScene();
+            }
+        });
+    }
+
+    class ToggleScene {
+        boolean expanded = false;
+        Scene mScene;
+        Transition mTransition;
+
+        ToggleScene(ViewGroup rootView, Transition transition) {
+            mScene = new Scene(rootView);
+            mTransition = transition;
+            mScene.setEnterAction(new Runnable() {
+                @Override
+                public void run() {
+                    if (currentItem != null) {
+                        System.out.println("onsceneChanged: currentItem = " + currentItem);
+                        View expandedContainer = currentItem.findViewById(R.id.expanded_info);
+                        expandedContainer.setVisibility(expanded ? View.GONE : View.VISIBLE);
+                        ImageView thumbnailView =
+                                (ImageView) currentItem.findViewById(R.id.contact_picture);
+                        thumbnailView.setImageResource(expanded ? R.drawable.self_portrait_square_100 :
+                                R.drawable.self_portrait_square_200);
+                        ImageView arrow = (ImageView) currentItem.findViewById(R.id.contact_arrow);
+                        arrow.setRotation(expanded ? 0 : 90);
+                        expanded = !expanded;
+                    }
+                }
+            });
+        }
+
+        void changeToScene() {
+            TransitionManager.go(mScene, mTransition);
+        }
+    };
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/CrossFadeDemo.java b/tests/TransitionTests/src/com/android/transitiontests/CrossFadeDemo.java
new file mode 100644
index 0000000..5bb0e77
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/CrossFadeDemo.java
@@ -0,0 +1,69 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.transition.ChangeBounds;
+import android.view.View;
+import android.view.ViewGroup;
+import android.transition.Crossfade;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
+
+
+public class CrossFadeDemo extends Activity {
+
+    ViewGroup mSceneRoot;
+    static int mCurrentScene;
+    Scene mScene1, mScene2;
+    TransitionManager mTransitionManager;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.crossfade);
+
+        View container = (View) findViewById(R.id.container);
+        mSceneRoot = (ViewGroup) container.getParent();
+
+        mScene1 = Scene.getSceneForLayout(mSceneRoot, R.layout.crossfade, this);
+        mScene2 = Scene.getSceneForLayout(mSceneRoot, R.layout.crossfade_1, this);
+
+        Crossfade crossfade = new Crossfade();
+        crossfade.setFadeBehavior(Crossfade.FADE_BEHAVIOR_CROSSFADE);
+        crossfade.setResizeBehavior(Crossfade.RESIZE_BEHAVIOR_NONE);
+        crossfade.addTarget(R.id.textview).addTarget(R.id.textview1).
+                addTarget(R.id.textview2);
+        mTransitionManager = new TransitionManager();
+        TransitionSet moveCrossFade = new TransitionSet();
+        moveCrossFade.addTransition(crossfade).addTransition(new ChangeBounds());
+        mTransitionManager.setTransition(mScene1, moveCrossFade);
+        mTransitionManager.setTransition(mScene2, moveCrossFade);
+        mCurrentScene = 1;
+    }
+
+    public void sendMessage(View view) {
+        if (mCurrentScene == 1) {
+            mTransitionManager.transitionTo(mScene2);
+            mCurrentScene = 2;
+        } else {
+            mTransitionManager.transitionTo(mScene1);
+            mCurrentScene = 1;
+        }
+    }
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/CrossfadeImage.java b/tests/TransitionTests/src/com/android/transitiontests/CrossfadeImage.java
new file mode 100644
index 0000000..1f278b9
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/CrossfadeImage.java
@@ -0,0 +1,68 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.transition.Crossfade;
+import android.transition.ChangeBounds;
+import android.transition.Scene;
+import android.transition.Transition;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
+import android.widget.ImageView;
+
+public class CrossfadeImage extends Activity {
+    ViewGroup mSceneRoot;
+    static int mCurrentScene;
+    Scene mScene1, mScene2;
+    TransitionManager mTransitionManager;
+    boolean mExpanded = false;
+    Transition mTransition;
+    ImageView mImageView;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.crossfade_image);
+
+        ViewGroup container = (ViewGroup) findViewById(R.id.container);
+        mSceneRoot = container;
+
+        mImageView = (ImageView) findViewById(R.id.contact_picture);
+        mImageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
+
+        Crossfade mCrossfade = new Crossfade();
+        mCrossfade.addTarget(R.id.contact_picture);
+
+        TransitionSet group = new TransitionSet();
+        group.setDuration(1500);
+        group.addTransition(mCrossfade).addTransition(new ChangeBounds());
+        mTransition = group;
+    }
+
+    public void sendMessage(View view) {
+        TransitionManager.beginDelayedTransition(mSceneRoot, mTransition);
+        if (mExpanded) {
+            mImageView.setImageResource(R.drawable.self_portrait_square_100);
+        } else {
+            mImageView.setImageResource(R.drawable.self_portrait_square_200);
+        }
+        mExpanded = !mExpanded;
+    }
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/CrossfadeMultiple.java b/tests/TransitionTests/src/com/android/transitiontests/CrossfadeMultiple.java
new file mode 100644
index 0000000..d784f75
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/CrossfadeMultiple.java
@@ -0,0 +1,140 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.transition.ChangeBounds;
+import android.view.View;
+import android.view.ViewGroup;
+import android.transition.Crossfade;
+import android.transition.TextChange;
+import android.transition.Transition;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import static android.widget.LinearLayout.LayoutParams;
+
+public class CrossfadeMultiple extends Activity {
+    ViewGroup mSceneRoot;
+    static int mCurrentScene;
+    TransitionManager mTransitionManager;
+    Transition mTransition;
+    ImageView mImageView;
+    TextView mTextView;
+    Button mButton;
+    Crossfade mCrossfade;
+    TransitionSet mCrossfadeGroup;
+    TransitionSet mTextChangeGroup1, mTextChangeGroup2;
+    TransitionSet mInOutGroup;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.crossfade_multiple);
+
+        ViewGroup container = (ViewGroup) findViewById(R.id.container);
+        mSceneRoot = container;
+
+        mButton = (Button) findViewById(R.id.button);
+        mImageView = (ImageView) findViewById(R.id.imageview);
+        mTextView = (TextView) findViewById(R.id.textview);
+
+        mCrossfade = new Crossfade();
+        mCrossfade.addTarget(R.id.button).addTarget(R.id.textview).addTarget(R.id.imageview);
+
+        mCrossfadeGroup = new TransitionSet();
+        mCrossfadeGroup.setDuration(300);
+        mCrossfadeGroup.addTransition(mCrossfade).addTransition(new ChangeBounds());
+        mTransition = mCrossfadeGroup;
+
+        mInOutGroup = new TransitionSet();
+        Crossfade inOut = new Crossfade();
+        inOut.setDuration(300);
+        inOut.setFadeBehavior(Crossfade.FADE_BEHAVIOR_OUT_IN);
+        ChangeBounds changeBounds = new ChangeBounds();
+        changeBounds.setStartDelay(150);
+        changeBounds.setDuration(0);
+        mInOutGroup.addTransition(inOut).addTransition(changeBounds);
+
+        mTextChangeGroup1 = new TransitionSet();
+        TextChange textChangeInOut = new TextChange();
+        textChangeInOut.setChangeBehavior(TextChange.CHANGE_BEHAVIOR_OUT_IN);
+        mTextChangeGroup1.addTransition(textChangeInOut).addTransition(new ChangeBounds());
+
+        mTextChangeGroup2 = new TransitionSet();
+        mTextChangeGroup2.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+        TextChange textChangeOut = new TextChange();
+        textChangeOut.setChangeBehavior(TextChange.CHANGE_BEHAVIOR_OUT);
+        TextChange textChangeIn = new TextChange();
+        textChangeIn.setChangeBehavior(TextChange.CHANGE_BEHAVIOR_IN);
+        mTextChangeGroup2.addTransition(textChangeOut).addTransition(new ChangeBounds()).
+                addTransition(textChangeIn);
+    }
+
+    public void sendMessage(View view) {
+        TransitionManager.beginDelayedTransition(mSceneRoot, mTransition);
+        int id = view.getId();
+        LayoutParams params = null;
+        switch (id) {
+            case R.id.button1:
+                params = new LayoutParams(200, 200);
+                mButton.setText("A");
+                mTextView.setText("1111111");
+                mImageView.setImageResource(R.drawable.self_portrait_square_100);
+                break;
+            case R.id.button2:
+                params = new LayoutParams(400, 200);
+                mButton.setText("B");
+                mTextView.setText("2222222");
+                mImageView.setImageResource(R.drawable.self_portrait_square_200);
+                break;
+            case R.id.button3:
+                params = new LayoutParams(200, 400);
+                mButton.setText("C");
+                mTextView.setText("3333333");
+                mImageView.setImageResource(R.drawable.self_portrait_square_400);
+                break;
+        }
+        mButton.setLayoutParams(params);
+    }
+
+    public void changeTransitionType(View view) {
+        int id = view.getId();
+        switch (id) {
+            case R.id.reveal:
+                mCrossfade.setFadeBehavior(Crossfade.FADE_BEHAVIOR_REVEAL);
+                mTransition = mCrossfadeGroup;
+                break;
+            case R.id.crossfade:
+                mCrossfade.setFadeBehavior(Crossfade.FADE_BEHAVIOR_CROSSFADE);
+                mTransition = mCrossfadeGroup;
+                break;
+            case R.id.inout:
+                mTransition = mInOutGroup;
+                break;
+            case R.id.textfade1:
+                mTransition = mTextChangeGroup1;
+                break;
+            case R.id.textfade2:
+                mTransition = mTextChangeGroup2;
+                break;
+        }
+    }
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/DelayedTransition.java b/tests/TransitionTests/src/com/android/transitiontests/DelayedTransition.java
new file mode 100644
index 0000000..fe5f05a
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/DelayedTransition.java
@@ -0,0 +1,66 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.transition.TransitionManager;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import static android.widget.LinearLayout.LayoutParams;
+
+public class DelayedTransition extends Activity {
+
+    private static final int SEARCH_SCREEN = 0;
+    private static final int RESULTS_SCREEN = 1;
+    ViewGroup mSceneRoot;
+    static int mCurrentScene;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.two_buttons);
+
+        final Button button1 = (Button) findViewById(R.id.button1);
+        final Button button2 = (Button) findViewById(R.id.button2);
+        final LinearLayout container = (LinearLayout) findViewById(R.id.container);
+        button1.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                int buttonWidth = button1.getWidth();
+                int containerWidth = container.getWidth();
+                if (buttonWidth < containerWidth) {
+                    TransitionManager.beginDelayedTransition(container, null);
+                    button1.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
+                            LayoutParams.WRAP_CONTENT));
+                    TransitionManager.beginDelayedTransition(container, null);
+                    button2.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
+                            LayoutParams.MATCH_PARENT));
+                } else {
+                    TransitionManager.beginDelayedTransition(container, null);
+                    button1.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
+                            LayoutParams.WRAP_CONTENT));
+                    TransitionManager.beginDelayedTransition(container, null);
+                    button2.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
+                            LayoutParams.WRAP_CONTENT));
+                }
+            }
+        });
+    }
+
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/Demo0.java b/tests/TransitionTests/src/com/android/transitiontests/Demo0.java
new file mode 100644
index 0000000..d52ab1d
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/Demo0.java
@@ -0,0 +1,59 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+
+public class Demo0 extends Activity {
+
+    private static final int SEARCH_SCREEN = 0;
+    private static final int RESULTS_SCREEN = 1;
+    ViewGroup mSceneRoot;
+    static int mCurrentScene;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.search_screen);
+
+        View container = (View) findViewById(R.id.container);
+        mSceneRoot = (ViewGroup) container.getParent();
+
+        mCurrentScene = SEARCH_SCREEN;
+    }
+
+    public void sendMessage(View view) {
+        if (mCurrentScene == RESULTS_SCREEN) {
+            mSceneRoot.removeAllViews();
+            LayoutInflater inflater = (LayoutInflater)
+                    getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+            inflater.inflate(R.layout.search_screen, mSceneRoot);
+            mCurrentScene = SEARCH_SCREEN;
+        } else {
+            mSceneRoot.removeAllViews();
+            LayoutInflater inflater = (LayoutInflater)
+                    getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+            inflater.inflate(R.layout.results_screen, mSceneRoot);
+            mCurrentScene = RESULTS_SCREEN;
+        }
+    }
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/Demo1.java b/tests/TransitionTests/src/com/android/transitiontests/Demo1.java
new file mode 100644
index 0000000..5b5eb15
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/Demo1.java
@@ -0,0 +1,88 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.transition.Fade;
+import android.transition.ChangeBounds;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
+
+
+public class Demo1 extends Activity {
+    ViewGroup mSceneRoot;
+    static Scene mCurrentScene;
+    boolean mFirstTime = true;
+    Scene mSearchScreen, mResultsScreen;
+    TransitionManager mTransitionManager = null;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.search_screen);
+
+        View container = (View) findViewById(R.id.container);
+        mSceneRoot = (ViewGroup) container.getParent();
+
+//        mResultsScreen = new MyScene(mSceneRoot, R.layout.results_screen);
+//        mSearchScreen = new MyScene(mSceneRoot, R.layout.search_screen);
+        mResultsScreen = new Scene(mSceneRoot);
+        mResultsScreen.setEnterAction(new Runnable() {
+            @Override
+            public void run() {
+                LayoutInflater inflater = (LayoutInflater)
+                        getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+                inflater.inflate(R.layout.results_screen, mSceneRoot);
+            }
+        });
+        mSearchScreen = new Scene(mSceneRoot);
+        mSearchScreen.setEnterAction(new Runnable() {
+            @Override
+            public void run() {
+                LayoutInflater inflater = (LayoutInflater)
+                        getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+                inflater.inflate(R.layout.search_screen, mSceneRoot);
+            }
+        });
+
+    }
+
+    public void sendMessage(View view) {
+        if (mFirstTime) {
+            mFirstTime = false;
+            TransitionSet transition = new TransitionSet();
+            transition.addTransition(new Fade().addTarget(R.id.resultsText).
+                    addTarget(R.id.resultsList)).
+                    addTransition(new ChangeBounds().addTarget(R.id.searchContainer));
+            mTransitionManager = new TransitionManager();
+            mTransitionManager.setTransition(mSearchScreen, transition);
+            mTransitionManager.setTransition(mResultsScreen, transition);
+        }
+        if (mCurrentScene == mResultsScreen) {
+            mTransitionManager.transitionTo(mSearchScreen);
+            mCurrentScene = mSearchScreen;
+        } else {
+            mTransitionManager.transitionTo(mResultsScreen);
+            mCurrentScene = mResultsScreen;
+        }
+    }
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/Demo2.java b/tests/TransitionTests/src/com/android/transitiontests/Demo2.java
new file mode 100644
index 0000000..0f3257b
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/Demo2.java
@@ -0,0 +1,76 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.transition.Fade;
+import android.transition.ChangeBounds;
+import android.transition.Recolor;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
+
+public class Demo2 extends Activity {
+    ViewGroup mSceneRoot;
+    static Scene mCurrentScene;
+    boolean mFirstTime = true;
+    Scene mSearchScreen, mResultsScreen;
+    TransitionManager mTransitionManager = null;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.search_screen);
+
+        View container = (View) findViewById(R.id.container);
+        mSceneRoot = (ViewGroup) container.getParent();
+
+    }
+
+    public void sendMessage(View view) {
+        if (mFirstTime) {
+            mFirstTime = false;
+            // Non-resource approach of creating scenes
+//        mSearchScreen = new Scene(this, mSceneRoot, R.layout.search_screen);
+//        mResultsScreen = new Scene(this, mSceneRoot, R.layout.results_screen);
+            try {
+                mSearchScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
+                mResultsScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
+            } catch (Exception e) {
+                System.out.println("Problem loading scene resource: " + e);
+            }
+
+            TransitionSet transition = new TransitionSet();
+            transition.addTransition(new Fade().addTarget(R.id.resultsText).
+                    addTarget(R.id.resultsList)).
+                    addTransition(new ChangeBounds().addTarget(R.id.searchContainer)).
+                    addTransition(new Recolor().addTarget(R.id.container));
+            mTransitionManager = new TransitionManager();
+            mTransitionManager.setTransition(mSearchScreen, transition);
+            mTransitionManager.setTransition(mResultsScreen, transition);
+        }
+        if (mCurrentScene == mResultsScreen) {
+            mTransitionManager.transitionTo(mSearchScreen);
+            mCurrentScene = mSearchScreen;
+        } else {
+            mTransitionManager.transitionTo(mResultsScreen);
+            mCurrentScene = mResultsScreen;
+        }
+    }
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/Demo3.java b/tests/TransitionTests/src/com/android/transitiontests/Demo3.java
new file mode 100644
index 0000000..0ffa1f5
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/Demo3.java
@@ -0,0 +1,64 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.transition.ChangeBounds;
+import android.view.View;
+import android.view.ViewGroup;
+import android.transition.Fade;
+import android.transition.Recolor;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
+
+
+public class Demo3 extends Activity {
+    ViewGroup mSceneRoot;
+    static Scene mCurrentScene;
+    Scene mSearchScreen, mResultsScreen;
+    TransitionManager mTransitionManager = null;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.search_screen);
+
+        View container = (View) findViewById(R.id.container);
+        mSceneRoot = (ViewGroup) container.getParent();
+
+        mSearchScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
+        mResultsScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.results_screen, this);
+
+        TransitionSet transition = new TransitionSet();
+        transition.addTransition(new Fade()).addTransition(new ChangeBounds()).addTransition(new Recolor());
+
+        mTransitionManager = new TransitionManager();
+        mTransitionManager.setTransition(mSearchScreen, transition);
+        mTransitionManager.setTransition(mResultsScreen, transition);
+    }
+
+    public void sendMessage(View view) {
+        if (mCurrentScene == mResultsScreen) {
+            mTransitionManager.transitionTo(mSearchScreen);
+            mCurrentScene = mSearchScreen;
+        } else {
+            mTransitionManager.transitionTo(mResultsScreen);
+            mCurrentScene = mResultsScreen;
+        }
+    }
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/Demo4.java b/tests/TransitionTests/src/com/android/transitiontests/Demo4.java
new file mode 100644
index 0000000..3aadbb0
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/Demo4.java
@@ -0,0 +1,75 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.transition.ChangeBounds;
+import android.view.View;
+import android.view.ViewGroup;
+import android.transition.Fade;
+import android.transition.Recolor;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
+
+
+public class Demo4 extends Activity {
+    ViewGroup mSceneRoot;
+    static Scene mCurrentScene;
+    Scene mSearchScreen, mResultsScreen;
+    TransitionManager mTransitionManager = null;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.search_screen);
+
+        View container = (View) findViewById(R.id.container);
+        mSceneRoot = (ViewGroup) container.getParent();
+
+        mSearchScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
+        mResultsScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.results_screen, this);
+
+        TransitionSet transitionToResults = new TransitionSet();
+        Fade fade = new Fade();
+        fade.addTarget(R.id.resultsText).addTarget(R.id.resultsList);
+        fade.setStartDelay(300);
+        fade.setDuration(1000);
+        transitionToResults.addTransition(fade).
+                addTransition(new ChangeBounds().addTarget(R.id.searchContainer)).
+                addTransition(new Recolor().addTarget(R.id.container));
+
+        TransitionSet transitionToSearch = new TransitionSet();
+        transitionToSearch.addTransition(fade).
+                addTransition(new ChangeBounds().addTarget(R.id.searchContainer)).
+                addTransition(new Recolor().addTarget(R.id.container));
+
+        mTransitionManager = new TransitionManager();
+        mTransitionManager.setTransition(mSearchScreen, transitionToSearch);
+        mTransitionManager.setTransition(mResultsScreen, transitionToResults);
+    }
+
+    public void sendMessage(View view) {
+        if (mCurrentScene == mResultsScreen) {
+            mTransitionManager.transitionTo(mSearchScreen);
+            mCurrentScene = mSearchScreen;
+        } else {
+            mTransitionManager.transitionTo(mResultsScreen);
+            mCurrentScene = mResultsScreen;
+        }
+    }
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/Demo5.java b/tests/TransitionTests/src/com/android/transitiontests/Demo5.java
new file mode 100644
index 0000000..c36abda
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/Demo5.java
@@ -0,0 +1,53 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.transition.Scene;
+import android.transition.TransitionManager;
+
+
+public class Demo5 extends Activity {
+    ViewGroup mSceneRoot;
+    static Scene mCurrentScene;
+    Scene mSearchScreen, mResultsScreen;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.search_screen);
+
+        View container = (View) findViewById(R.id.container);
+        mSceneRoot = (ViewGroup) container.getParent();
+
+        mSearchScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
+        mResultsScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.results_screen, this);
+
+    }
+
+    public void sendMessage(View view) {
+        if (mCurrentScene == mResultsScreen) {
+            TransitionManager.go(mSearchScreen);
+            mCurrentScene = mSearchScreen;
+        } else {
+            TransitionManager.go(mResultsScreen);
+            mCurrentScene = mResultsScreen;
+        }
+    }
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/FadingHierarchy.java b/tests/TransitionTests/src/com/android/transitiontests/FadingHierarchy.java
new file mode 100644
index 0000000..d497abe
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/FadingHierarchy.java
@@ -0,0 +1,53 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.transition.TransitionManager;
+import android.widget.Button;
+
+public class FadingHierarchy extends Activity {
+
+    ViewGroup mRemovingContainer, mContainer;
+    Button mRemovingButton;
+    boolean mVisible = true;
+    ViewGroup mInnerContainerParent;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.fading_hierarchy);
+
+        mContainer = (ViewGroup) findViewById(R.id.container);
+        mRemovingContainer = (ViewGroup) findViewById(R.id.removingContainer);
+        mInnerContainerParent = (ViewGroup) mRemovingContainer.getParent();
+
+        mRemovingButton = (Button) findViewById(R.id.removingButton);
+    }
+
+    public void sendMessage(View view) {
+        TransitionManager.beginDelayedTransition(mContainer, null);
+        if (mVisible) {
+            mInnerContainerParent.removeView(mRemovingContainer);
+        } else {
+            mInnerContainerParent.addView(mRemovingContainer);
+        }
+        mVisible = !mVisible;
+    }
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/FadingTest.java b/tests/TransitionTests/src/com/android/transitiontests/FadingTest.java
new file mode 100644
index 0000000..29fb868
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/FadingTest.java
@@ -0,0 +1,77 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.transition.Scene;
+import android.widget.Button;
+import android.transition.Fade;
+import android.transition.TransitionManager;
+
+
+public class FadingTest extends Activity {
+
+    Button mRemovingButton, mInvisibleButton, mGoneButton;
+    Scene mScene1, mScene2;
+    ViewGroup mSceneRoot;
+    static Fade sFade = new Fade();
+    Scene mCurrentScene;
+
+    static {
+        sFade.addTarget(R.id.removingButton).addTarget(R.id.invisibleButton).
+                addTarget(R.id.goneButton);
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.fading_test);
+
+        View container = (View) findViewById(R.id.container);
+        mSceneRoot = (ViewGroup) container.getParent();
+
+
+        mRemovingButton = (Button) findViewById(R.id.removingButton);
+        mInvisibleButton = (Button) findViewById(R.id.invisibleButton);
+        mGoneButton = (Button) findViewById(R.id.goneButton);
+
+        mGoneButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                mGoneButton.setAlpha(mGoneButton.getAlpha() < 1 ? 1 : .6f);
+            }
+        });
+
+        mScene1 = Scene.getSceneForLayout(mSceneRoot, R.layout.fading_test, this);
+        mScene2 = Scene.getSceneForLayout(mSceneRoot, R.layout.fading_test_scene_2, this);
+
+        mCurrentScene = mScene1;
+    }
+
+    public void sendMessage(View view) {
+        if (mCurrentScene == mScene1) {
+            TransitionManager.go(mScene2);
+            mCurrentScene = mScene2;
+        } else {
+            TransitionManager.go(mScene1);
+            mCurrentScene = mScene1;
+        }
+    }
+
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/HierarchicalMove.java b/tests/TransitionTests/src/com/android/transitiontests/HierarchicalMove.java
new file mode 100644
index 0000000..1146e20
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/HierarchicalMove.java
@@ -0,0 +1,108 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.transition.ChangeBounds;
+import android.view.View;
+import android.view.ViewGroup;
+import android.transition.Transition;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
+import android.widget.Button;
+
+import static android.widget.LinearLayout.LayoutParams;
+
+public class HierarchicalMove extends Activity {
+
+    Button[] buttons = new Button[6];
+    ViewGroup mSceneRoot;
+    boolean wide = false;
+    Transition mTransition;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.hierarchical_move);
+
+        View container = (View) findViewById(R.id.container);
+        mSceneRoot = (ViewGroup) container.getParent();
+
+        buttons[0] = (Button) findViewById(R.id.button0);
+        buttons[1] = (Button) findViewById(R.id.button1);
+        buttons[2] = (Button) findViewById(R.id.button2);
+        buttons[3] = (Button) findViewById(R.id.button3);
+        buttons[4] = (Button) findViewById(R.id.button4);
+        buttons[5] = (Button) findViewById(R.id.button5);
+
+        // Move button0, then buttons 1/2 together, then buttons 3/4/5 sequentially:
+        // group (seq)
+        //    Move 0
+        //    group (seq)
+        //       group (together)
+        //          Move 1
+        //          Move 2
+        //       group (sequentially)
+        //          Move 3
+        //          Move 4/5
+        TransitionSet rootTransition = new TransitionSet().
+                setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+
+        // button0
+        Transition move0 = new ChangeBounds();
+        move0.addTarget(buttons[0]);
+
+        // buttons 1/2/3/4/5
+        TransitionSet group12345 = new TransitionSet().
+                setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+
+        // buttons 1/2
+        TransitionSet group12 = new TransitionSet().
+                setOrdering(TransitionSet.ORDERING_TOGETHER);
+        ChangeBounds changeBounds1 = new ChangeBounds();
+        changeBounds1.addTarget(buttons[1]);
+        ChangeBounds changeBounds2 = new ChangeBounds();
+        changeBounds2.addTarget(buttons[2]);
+        group12.addTransition(changeBounds1).addTransition(changeBounds2);
+
+        TransitionSet group345 = new TransitionSet().
+                setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+        ChangeBounds changeBounds3 = new ChangeBounds();
+        changeBounds3.addTarget(buttons[3]);
+        ChangeBounds changeBounds45 = new ChangeBounds();
+        changeBounds45.addTarget(buttons[4]).addTarget(buttons[5]);
+        group345.addTransition(changeBounds3).addTransition(changeBounds45);
+
+        group12345.addTransition(move0).addTransition(group12).addTransition(group345);
+
+        rootTransition.addTransition(group12345);
+        rootTransition.setDuration(1000);
+        mTransition = rootTransition;
+
+    }
+
+    public void sendMessage(View view) {
+        TransitionManager.beginDelayedTransition(mSceneRoot, mTransition);
+        int widthSpec = wide ? LayoutParams.WRAP_CONTENT : LayoutParams.MATCH_PARENT;
+        LayoutParams params = new LayoutParams(widthSpec, LayoutParams.WRAP_CONTENT);
+        for (int i = 0; i < buttons.length; ++i) {
+            buttons[i].setLayoutParams(params);
+        }
+        wide = !wide;
+    }
+
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/HitRectBug.java b/tests/TransitionTests/src/com/android/transitiontests/HitRectBug.java
new file mode 100644
index 0000000..9f19405
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/HitRectBug.java
@@ -0,0 +1,91 @@
+/*
+ * 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.transitiontests;
+
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.RelativeLayout;
+
+
+public class HitRectBug extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState)
+    {
+        super.onCreate(savedInstanceState);
+        setContentView(new TestDrawingView(this));
+    }
+
+    public static class TestDrawingView extends RelativeLayout
+    {
+        private Rect mRect = new Rect();
+        private Paint mPaint;
+        private ImageView mImageView;
+
+        public TestDrawingView(Context context)
+        {
+            super(context);
+            setWillNotDraw(false);
+
+            mPaint = new Paint();
+            mPaint.setColor(Color.RED);
+            mPaint.setStyle(Paint.Style.STROKE);
+
+            mImageView = new ImageView(context);
+            mImageView.setLeft(100);
+            mImageView.setRight(200);
+            mImageView.setImageResource(R.drawable.self_portrait_square);
+            mImageView.setScaleX(3);
+            mImageView.setScaleY(3);
+//            mImageView.setRotation(145);
+
+            ObjectAnimator anim = ObjectAnimator.ofFloat(mImageView, View.ROTATION, 0, 360);
+            anim.setRepeatCount(ValueAnimator.INFINITE);
+            anim.setDuration(5000);
+            anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+                @Override
+                public void onAnimationUpdate(ValueAnimator animation) {
+                    invalidate();
+                }
+            });
+            anim.start();
+            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(128, 128);
+            params.addRule(RelativeLayout.CENTER_IN_PARENT);
+            addView(mImageView, params);
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas)
+        {
+            super.onDraw(canvas);
+        }
+
+        @Override
+        protected void dispatchDraw(Canvas canvas) {
+            super.dispatchDraw(canvas);
+            mImageView.getHitRect(mRect);
+            canvas.drawRect(mRect, mPaint);
+        }
+    }
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/InstanceTargets.java b/tests/TransitionTests/src/com/android/transitiontests/InstanceTargets.java
new file mode 100644
index 0000000..a06ba8f
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/InstanceTargets.java
@@ -0,0 +1,60 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.transition.ChangeBounds;
+import android.transition.TransitionManager;
+import android.widget.Button;
+
+import static android.widget.RelativeLayout.ALIGN_PARENT_LEFT;
+import static android.widget.RelativeLayout.ALIGN_PARENT_RIGHT;
+import static android.widget.RelativeLayout.LayoutParams;
+
+public class InstanceTargets extends Activity {
+
+    ViewGroup mSceneRoot;
+    static int mCurrentScene;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.instance_targets);
+
+        View container = (View) findViewById(R.id.container);
+        mSceneRoot = (ViewGroup) container;
+    }
+
+    public void sendMessage(final View view) {
+        TransitionManager.beginDelayedTransition(mSceneRoot, new ChangeBounds().addTarget(view));
+        for (int i = 0; i < mSceneRoot.getChildCount(); ++i) {
+            Button button = (Button) mSceneRoot.getChildAt(i);
+            LayoutParams params = (LayoutParams) button.getLayoutParams();
+            int rules[] = params.getRules();
+            if (rules[ALIGN_PARENT_RIGHT] != 0) {
+                params.removeRule(ALIGN_PARENT_RIGHT);
+                params.addRule(ALIGN_PARENT_LEFT);
+            } else {
+                params.removeRule(ALIGN_PARENT_LEFT);
+                params.addRule(ALIGN_PARENT_RIGHT);
+            }
+            button.setLayoutParams(params);
+        }
+    }
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/InterruptionTest.java b/tests/TransitionTests/src/com/android/transitiontests/InterruptionTest.java
new file mode 100644
index 0000000..c26e93f
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/InterruptionTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.transition.ChangeBounds;
+import android.view.View;
+import android.view.ViewGroup;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
+import android.widget.RadioButton;
+
+public class InterruptionTest extends Activity {
+
+    RadioButton mScene1RB, mScene2RB, mScene3RB, mScene4RB;
+    private Scene mScene1;
+    private Scene mScene2;
+    private Scene mScene3;
+    private Scene mScene4;
+    TransitionSet mSequencedMove = new TransitionSet().
+            setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.interruption);
+
+        ViewGroup sceneRoot = (ViewGroup) findViewById(R.id.sceneRoot);
+
+        mScene1 = Scene.getSceneForLayout(sceneRoot, R.layout.interruption_inner_1, this);
+        mScene2 = Scene.getSceneForLayout(sceneRoot, R.layout.interruption_inner_2, this);
+        mScene3 = Scene.getSceneForLayout(sceneRoot, R.layout.interruption_inner_3, this);
+        mScene4 = Scene.getSceneForLayout(sceneRoot, R.layout.interruption_inner_4, this);
+
+        mScene1RB = (RadioButton) findViewById(R.id.scene1RB);
+        mScene2RB = (RadioButton) findViewById(R.id.scene2RB);
+        mScene3RB = (RadioButton) findViewById(R.id.scene3RB);
+        mScene4RB = (RadioButton) findViewById(R.id.scene4RB);
+
+        ChangeBounds changeBounds1 = new ChangeBounds();
+        changeBounds1.addTarget(R.id.button);
+        ChangeBounds changeBounds2 = new ChangeBounds();
+        changeBounds2.addTarget(R.id.button1);
+
+        mSequencedMove.addTransition(changeBounds1).addTransition(changeBounds2);
+        mSequencedMove.setDuration(1000);
+    }
+
+    public void onRadioButtonClicked(View clickedButton) {
+        if (clickedButton == mScene1RB) {
+            TransitionManager.go(mScene1, mSequencedMove);
+        } else if (clickedButton == mScene2RB) {
+            TransitionManager.go(mScene2, mSequencedMove);
+        } else if (clickedButton == mScene3RB) {
+            TransitionManager.go(mScene3, mSequencedMove);
+        } else {
+            TransitionManager.go(mScene4, mSequencedMove);
+        }
+    }
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ListViewAddRemove.java b/tests/TransitionTests/src/com/android/transitiontests/ListViewAddRemove.java
new file mode 100644
index 0000000..6629770
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/ListViewAddRemove.java
@@ -0,0 +1,167 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewTreeObserver;
+import android.transition.Fade;
+import android.transition.Scene;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.transition.AutoTransition;
+import android.transition.ChangeBounds;
+import android.transition.Transition;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+public class ListViewAddRemove extends Activity {
+
+    final ArrayList<String> numList = new ArrayList<String>();
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.list_view_add_remove);
+
+        final LinearLayout container = (LinearLayout) findViewById(R.id.container);
+
+        final ListView listview = (ListView) findViewById(R.id.listview);
+        for (int i = 0; i < 200; ++i) {
+            numList.add(Integer.toString(i));
+        }
+        final StableArrayAdapter adapter = new StableArrayAdapter(this,
+                android.R.layout.simple_list_item_1, numList);
+        listview.setAdapter(adapter);
+
+        final ViewTreeObserver observer = container.getViewTreeObserver();
+        observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+            public void onGlobalLayout() {
+                System.out.println("-------------------------------------");
+                System.out.println("onLayoutListener: listview view tops: ");
+                for (int i = 0; i < listview.getChildCount(); ++i) {
+                    TextView view = (TextView) listview.getChildAt(i);
+                    System.out.println("    " + view.getText() + ": " + view.getTop());
+                }
+            }
+        });
+
+        final Scene mySceneChanger = new Scene(listview);
+
+        mySceneChanger.setEnterAction(new Runnable() {
+            @Override
+            public void run() {
+                numList.remove(mItemToDelete);
+                adapter.notifyDataSetChanged();
+            }
+        });
+        final Transition myTransition = new AutoTransition();
+        final TransitionSet noFadeIn = new TransitionSet().
+                setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+        Fade fadeIn = new Fade(Fade.IN);
+        fadeIn.setDuration(50);
+        noFadeIn.addTransition(new Fade(Fade.OUT)).addTransition(new ChangeBounds()).addTransition(fadeIn);
+
+        myTransition.addListener(new Transition.TransitionListenerAdapter() {
+            @Override
+            public void onTransitionStart(Transition transition) {
+                System.out.println("---------ListView Tops: Before--------");
+                for (int i = 0; i < listview.getChildCount(); ++i) {
+                    TextView view = (TextView) listview.getChildAt(i);
+                    int position = listview.getPositionForView(view);
+                }
+            }
+
+            @Override
+            public void onTransitionEnd(Transition transition) {
+                System.out.println("---------ListView Tops: After--------");
+                for (int i = 0; i < listview.getChildCount(); ++i) {
+                    TextView view = (TextView) listview.getChildAt(i);
+                    int position = listview.getPositionForView(view);
+                    if (view.hasTransientState()) {
+//                        view.setHasTransientState(false);
+                    }
+                }
+                myTransition.removeListener(this);
+            }
+        });
+
+        listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+
+            @Override
+            public void onItemClick(AdapterView<?> parent, final View view, int position, long id) {
+                System.out.println("---------ListView Tops: OnClick--------");
+                String item = (String) parent.getItemAtPosition(position);
+                for (int i = 0; i < listview.getChildCount(); ++i) {
+                    TextView v = (TextView) listview.getChildAt(i);
+                    if (!item.equals(v.getText())) {
+//                        v.setHasTransientState(true);
+                    }
+                }
+//                listview.setHasTransientState(true);
+                mItemToDelete = item;
+//                numList.remove(item);
+                TransitionManager.go(mySceneChanger, noFadeIn);
+//                view.postDelayed(new Runnable() {
+//                    @Override
+//                    public void run() {
+//                        for (int i = 0; i < listview.getChildCount(); ++i) {
+//                            TextView v = (TextView) listview.getChildAt(i);
+//                            v.setHasTransientState(false);
+//                        }
+//                    }
+//                }, 200);
+            }
+
+        });
+    }
+
+    String mItemToDelete = null;
+
+    private class StableArrayAdapter extends ArrayAdapter<String> {
+
+        HashMap<String, Integer> mIdMap = new HashMap<String, Integer>();
+
+        public StableArrayAdapter(Context context, int textViewResourceId,
+                List<String> objects) {
+            super(context, textViewResourceId, objects);
+            for (int i = 0; i < objects.size(); ++i) {
+                mIdMap.put(objects.get(i), i);
+            }
+        }
+
+        @Override
+        public long getItemId(int position) {
+            String item = getItem(position);
+            return mIdMap.get(item);
+        }
+
+        @Override
+        public boolean hasStableIds() {
+            return true;
+        }
+
+    }
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ListViewAddRemoveNoTransition.java b/tests/TransitionTests/src/com/android/transitiontests/ListViewAddRemoveNoTransition.java
new file mode 100644
index 0000000..4eeba4d
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/ListViewAddRemoveNoTransition.java
@@ -0,0 +1,103 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import android.widget.TextView;
+
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+public class ListViewAddRemoveNoTransition extends Activity {
+
+    final ArrayList<String> numList = new ArrayList<String>();
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.list_view_add_remove);
+
+        final LinearLayout container = (LinearLayout) findViewById(R.id.container);
+
+        final ListView listview = (ListView) findViewById(R.id.listview);
+        for (int i = 0; i < 200; ++i) {
+            numList.add(Integer.toString(i));
+        }
+        final StableArrayAdapter adapter = new StableArrayAdapter(this,
+                android.R.layout.simple_list_item_1, numList);
+        listview.setAdapter(adapter);
+
+        listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+
+            @Override
+            public void onItemClick(AdapterView<?> parent, final View view, int position, long id) {
+                String item = (String) parent.getItemAtPosition(position);
+                for (int i = 0; i < listview.getChildCount(); ++i) {
+                    TextView v = (TextView) listview.getChildAt(i);
+                    if (!item.equals(v.getText())) {
+                        v.setHasTransientState(true);
+                    }
+                }
+                numList.remove(item);
+                adapter.notifyDataSetChanged();
+                view.postDelayed(new Runnable() {
+                    @Override
+                    public void run() {
+                        for (int i = 0; i < listview.getChildCount(); ++i) {
+                            TextView v = (TextView) listview.getChildAt(i);
+                            v.setHasTransientState(false);
+                        }
+                    }
+                }, 200);
+            }
+
+        });
+    }
+
+    private class StableArrayAdapter extends ArrayAdapter<String> {
+
+        HashMap<String, Integer> mIdMap = new HashMap<String, Integer>();
+
+        public StableArrayAdapter(Context context, int textViewResourceId,
+                List<String> objects) {
+            super(context, textViewResourceId, objects);
+            for (int i = 0; i < objects.size(); ++i) {
+                mIdMap.put(objects.get(i), i);
+            }
+        }
+
+        @Override
+        public long getItemId(int position) {
+            String item = getItem(position);
+            return mIdMap.get(item);
+        }
+
+        @Override
+        public boolean hasStableIds() {
+            return true;
+        }
+
+    }
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/LoginActivity.java b/tests/TransitionTests/src/com/android/transitiontests/LoginActivity.java
new file mode 100644
index 0000000..92bbb85
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/LoginActivity.java
@@ -0,0 +1,105 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.transition.Scene;
+import android.widget.TextView;
+import android.transition.Fade;
+import android.transition.Recolor;
+import android.transition.Slide;
+import android.transition.Transition;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
+
+
+public class LoginActivity extends Activity {
+    ViewGroup mSceneRoot;
+    Scene mCurrentScene;
+    TransitionManager mTransitionManager;
+    Scene mLoginScene, mPasswordScene, mIncorrectPasswordScene, mSuccessScene, mUsernameTakenScene,
+            mNewUserScene;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_login);
+        View container = (View) findViewById(R.id.container);
+        mSceneRoot = (ViewGroup) container.getParent();
+
+        mLoginScene = Scene.getSceneForLayout(mSceneRoot, R.layout.activity_login, this);
+        mPasswordScene = Scene.getSceneForLayout(mSceneRoot, R.layout.login_password, this);
+        mIncorrectPasswordScene = Scene.getSceneForLayout(mSceneRoot, R.layout.incorrect_password, this);
+        mUsernameTakenScene = Scene.getSceneForLayout(mSceneRoot, R.layout.username_taken, this);
+        mSuccessScene = Scene.getSceneForLayout(mSceneRoot, R.layout.success, this);
+        mNewUserScene = Scene.getSceneForLayout(mSceneRoot, R.layout.new_user, this);
+
+        mTransitionManager = new TransitionManager();
+
+        // Custom transitions in/out of NewUser screen - slide in the 2nd password UI
+        TransitionSet slider = new TransitionSet();
+        slider.addTransition(new Slide().addTarget(R.id.retype).addTarget(R.id.retypeEdit));
+        slider.addTransition(new Recolor().addTarget(R.id.password).
+                addTarget(R.id.passwordEdit));
+        slider.addTransition(new Fade());
+        mTransitionManager.setTransition(mLoginScene, mNewUserScene, slider);
+        mTransitionManager.setTransition(mPasswordScene, mNewUserScene, slider);
+        mTransitionManager.setTransition(mNewUserScene, mLoginScene, slider);
+        mTransitionManager.setTransition(mNewUserScene, mPasswordScene, slider);
+
+        // Custom transitions with recoloring password field
+        Transition colorizer = new Recolor().addTarget(R.id.password).
+                addTarget(R.id.passwordEdit);
+        mTransitionManager.setTransition(mLoginScene, mPasswordScene, colorizer);
+        mTransitionManager.setTransition(mPasswordScene, mLoginScene, colorizer);
+
+        mCurrentScene = mLoginScene;
+    }
+
+    public void applyScene(Scene scene) {
+        mTransitionManager.transitionTo(scene);
+        mCurrentScene = scene;
+    }
+
+    public void sendMessage(View view) {
+        TextView textView = (TextView) view;
+        CharSequence text = textView.getText();
+        if (text.equals("Cancel")) {
+            applyScene(mLoginScene);
+        } else if (text.equals("Submit")) {
+            if (mCurrentScene == mLoginScene) {
+                applyScene(mPasswordScene);
+            } else if (mCurrentScene == mPasswordScene) {
+                applyScene(Math.random() < .5 ? mSuccessScene : mIncorrectPasswordScene);
+            } else if (mCurrentScene == mNewUserScene) {
+                applyScene(Math.random() < .5 ? mSuccessScene : mUsernameTakenScene);
+            }
+        } else if (text.equals("New User?")) {
+            applyScene(mNewUserScene);
+        } else if (text.equals("Okay")) {
+            if (mCurrentScene == mIncorrectPasswordScene) {
+                applyScene(mPasswordScene);
+            } else { // username taken scene
+                applyScene(mNewUserScene);
+            }
+        } else if (text.equals("Reset")) {
+            applyScene(mLoginScene);
+        }
+    }
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/LoginActivityFromResources.java b/tests/TransitionTests/src/com/android/transitiontests/LoginActivityFromResources.java
new file mode 100644
index 0000000..600c791
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/LoginActivityFromResources.java
@@ -0,0 +1,91 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.transition.Scene;
+import android.transition.TransitionInflater;
+import android.widget.TextView;
+import android.transition.TransitionManager;
+
+
+public class LoginActivityFromResources extends Activity {
+    ViewGroup mSceneRoot;
+    Scene mCurrentScene;
+    TransitionManager mTransitionManager = null;
+    Scene mLoginScene, mPasswordScene, mIncorrectPasswordScene, mSuccessScene, mUsernameTakenScene,
+            mNewUserScene;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_login);
+        View container = findViewById(R.id.container);
+        mSceneRoot = (ViewGroup) container.getParent();
+
+    }
+
+    public void applyScene(Scene scene) {
+        mTransitionManager.transitionTo(scene);
+        mCurrentScene = scene;
+    }
+
+    public void sendMessage(View view) {
+        if (mTransitionManager == null) {
+            TransitionInflater inflater = TransitionInflater.from(this);
+
+            mLoginScene = Scene.getSceneForLayout(mSceneRoot, R.layout.activity_login, this);
+            mPasswordScene = Scene.getSceneForLayout(mSceneRoot, R.layout.login_password, this);
+            mIncorrectPasswordScene = Scene.getSceneForLayout(mSceneRoot, R.layout
+                    .incorrect_password, this);
+            mUsernameTakenScene = Scene.getSceneForLayout(mSceneRoot, R.layout.username_taken, this);
+            mSuccessScene = Scene.getSceneForLayout(mSceneRoot, R.layout.success, this);
+            mNewUserScene = Scene.getSceneForLayout(mSceneRoot, R.layout.new_user, this);
+
+            mTransitionManager =
+                    inflater.inflateTransitionManager(R.transition.login_transition_mgr,
+                            mSceneRoot);
+
+            mCurrentScene = mLoginScene;
+        }
+        TextView textView = (TextView) view;
+        CharSequence text = textView.getText();
+        if (text.equals("Cancel")) {
+            applyScene(mLoginScene);
+        } else if (text.equals("Submit")) {
+            if (mCurrentScene == mLoginScene) {
+                applyScene(mPasswordScene);
+            } else if (mCurrentScene == mPasswordScene) {
+                applyScene(Math.random() < .5 ? mSuccessScene : mIncorrectPasswordScene);
+            } else if (mCurrentScene == mNewUserScene) {
+                applyScene(Math.random() < .5 ? mSuccessScene : mUsernameTakenScene);
+            }
+        } else if (text.equals("New User?")) {
+            applyScene(mNewUserScene);
+        } else if (text.equals("Okay")) {
+            if (mCurrentScene == mIncorrectPasswordScene) {
+                applyScene(mPasswordScene);
+            } else { // username taken scene
+                applyScene(mNewUserScene);
+            }
+        } else if (text.equals("Reset")) {
+            applyScene(mLoginScene);
+        }
+    }
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/OverlayTest.java b/tests/TransitionTests/src/com/android/transitiontests/OverlayTest.java
new file mode 100644
index 0000000..ef8cd37
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/OverlayTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+
+
+public class OverlayTest extends Activity {
+
+    ViewGroup mContainer;
+    ViewGroup mRoot;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.overlay_test);
+
+        mContainer = (ViewGroup) findViewById(R.id.container);
+        mRoot = (ViewGroup) mContainer.getParent();
+    }
+
+    public void onClick(View view) {
+        final Button fadingButton = (Button) findViewById(R.id.fadingButton);
+        if (fadingButton != null) {
+            mContainer.removeView(fadingButton);
+            mRoot.getOverlay().add(fadingButton);
+            fadingButton.animate().alpha(0).setDuration(1000).withEndAction(new Runnable() {
+                @Override
+                public void run() {
+                    fadingButton.setAlpha(1);
+                    mRoot.getOverlay().remove(fadingButton);
+                    mContainer.addView(fadingButton);
+                }
+            });
+        }
+    }
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/Reparenting.java b/tests/TransitionTests/src/com/android/transitiontests/Reparenting.java
new file mode 100644
index 0000000..1ee8621
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/Reparenting.java
@@ -0,0 +1,75 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.transition.ChangeBounds;
+import android.view.View;
+import android.view.ViewGroup;
+import android.transition.Scene;
+import android.transition.TransitionManager;
+import android.widget.Button;
+
+public class Reparenting extends Activity {
+
+    ViewGroup mSceneRoot;
+    ViewGroup mContainer1, mContainer2;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.reparenting);
+
+        ViewGroup container = (ViewGroup) findViewById(R.id.container);
+        mContainer1 = (ViewGroup) findViewById(R.id.container1);
+        mContainer2 = (ViewGroup) findViewById(R.id.container2);
+        System.out.println("container 1 and 2 " + mContainer1 + ", " + mContainer2);
+
+        setupButtons(0, mContainer1);
+        setupButtons(3, mContainer2);
+
+        mSceneRoot = container;
+    }
+
+    private void setupButtons(int startIndex, ViewGroup parent) {
+        for (int i = startIndex; i < (startIndex + 3); ++i) {
+            Button button = new Button(this);
+            button.setText(Integer.toString(i));
+            button.setOnClickListener(mButtonListener);
+            parent.addView(button);
+        }
+    }
+
+    private View.OnClickListener mButtonListener = new View.OnClickListener() {
+        @Override
+        public void onClick(final View v) {
+            Scene newScene = new Scene(mSceneRoot);
+            newScene.setEnterAction(new Runnable() {
+                @Override
+                public void run() {
+                    ViewGroup oldParent = (ViewGroup) v.getParent();
+                    ViewGroup newParent = oldParent == mContainer1 ? mContainer2 : mContainer1;
+                    oldParent.removeView(v);
+                    newParent.addView(v);
+                }
+            });
+            ChangeBounds reparent = new ChangeBounds();
+            reparent.setReparent(true);
+            TransitionManager.go(newScene, reparent);
+        }
+    };
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ResourceLoadingTest.java b/tests/TransitionTests/src/com/android/transitiontests/ResourceLoadingTest.java
new file mode 100644
index 0000000..1aee258
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/ResourceLoadingTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.transition.Scene;
+import android.transition.TransitionInflater;
+import android.transition.Transition;
+import android.transition.TransitionManager;
+
+
+public class ResourceLoadingTest extends Activity {
+
+    private static final int SEARCH_SCREEN = 0;
+    private static final int RESULTS_SCREEN = 1;
+    ViewGroup mSceneRoot;
+    static int mCurrentScene;
+    TransitionManager mTransitionManager = null;
+    TransitionInflater mInflater;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.search_screen);
+
+        View container = (View) findViewById(R.id.container);
+        mSceneRoot = (ViewGroup) container.getParent();
+
+        mCurrentScene = SEARCH_SCREEN;
+
+        mInflater = TransitionInflater.from(this);
+    }
+
+    public void sendMessage(View view) {
+        if (mTransitionManager == null) {
+            try {
+                TransitionInflater inflater = TransitionInflater.from(this);
+                mTransitionManager =
+                        inflater.inflateTransitionManager(R.transition.my_transition_mgr,
+                                mSceneRoot);
+                Scene loadedScene = new Scene(mSceneRoot);
+                System.out.println("loadedScene = " + loadedScene);
+                Transition loadedTransition = inflater.inflateTransition(R.transition.my_transition);
+                System.out.println("loadedTransition = " + loadedTransition);
+            } catch (Exception e) {
+                System.out.println("Problem loading scene resource: " + e);
+            }
+        }
+        if (mCurrentScene == RESULTS_SCREEN) {
+            Scene scene = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
+            mTransitionManager.transitionTo(scene);
+            mCurrentScene = SEARCH_SCREEN;
+        } else {
+            Scene scene = Scene.getSceneForLayout(mSceneRoot, R.layout.results_screen, this);
+            mTransitionManager.transitionTo(scene);
+            mCurrentScene = RESULTS_SCREEN;
+        }
+    }
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTargets.java b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTargets.java
new file mode 100644
index 0000000..7504058
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTargets.java
@@ -0,0 +1,65 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.transition.ChangeBounds;
+import android.view.View;
+import android.view.ViewGroup;
+import android.transition.Fade;
+import android.transition.Recolor;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
+
+
+public class ScenesTestAutoTargets extends Activity {
+    ViewGroup mSceneRoot;
+    static Scene mCurrentScene;
+    TransitionManager mTransitionManager = null;
+    Scene mResultsScreen, mSearchScreen;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.search_screen);
+
+        View container = (View) findViewById(R.id.container);
+        mSceneRoot = (ViewGroup) container.getParent();
+
+        mSearchScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
+        mResultsScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.results_screen, this);
+
+        TransitionSet transition = new TransitionSet();
+        transition.addTransition(new Fade()).addTransition(new ChangeBounds()).addTransition(new Recolor());
+
+        mTransitionManager = new TransitionManager();
+        mTransitionManager.setTransition(mSearchScreen, transition);
+        mTransitionManager.setTransition(mResultsScreen, transition);
+    }
+
+    public void sendMessage(View view) {
+        if (mCurrentScene == mResultsScreen) {
+            mTransitionManager.transitionTo(mSearchScreen);
+            mCurrentScene = mSearchScreen;
+        } else {
+            mTransitionManager.transitionTo(mResultsScreen);
+            mCurrentScene = mResultsScreen;
+        }
+    }
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTransition.java b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTransition.java
new file mode 100644
index 0000000..23b28ec
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTransition.java
@@ -0,0 +1,56 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.transition.AutoTransition;
+import android.transition.Scene;
+import android.transition.Transition;
+import android.transition.TransitionManager;
+
+
+public class ScenesTestAutoTransition extends Activity {
+    ViewGroup mSceneRoot;
+    static Scene mCurrentScene;
+    Transition mTransition = new AutoTransition();
+    Scene mResultsScreen, mSearchScreen;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.search_screen);
+
+        View container = (View) findViewById(R.id.container);
+        mSceneRoot = (ViewGroup) container.getParent();
+
+        mSearchScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
+        mResultsScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.results_screen, this);
+    }
+
+    public void sendMessage(View view) {
+        if (mCurrentScene == mResultsScreen) {
+            TransitionManager.go(mSearchScreen, mTransition);
+            mCurrentScene = mSearchScreen;
+        } else {
+            TransitionManager.go(mResultsScreen, mTransition);
+            mCurrentScene = mResultsScreen;
+        }
+    }
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTransition2.java b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTransition2.java
new file mode 100644
index 0000000..5a9fa9d
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTransition2.java
@@ -0,0 +1,54 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.transition.Scene;
+import android.transition.TransitionManager;
+
+
+public class ScenesTestAutoTransition2 extends Activity {
+    ViewGroup mSceneRoot;
+    static Scene mCurrentScene;
+
+    Scene mResultsScreen, mSearchScreen;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.search_screen);
+
+        View container = (View) findViewById(R.id.container);
+        mSceneRoot = (ViewGroup) container.getParent();
+
+        mSearchScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
+        mResultsScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.results_screen, this);
+    }
+
+    public void sendMessage(View view) {
+        if (mCurrentScene == mResultsScreen) {
+            TransitionManager.go(mSearchScreen);
+            mCurrentScene = mSearchScreen;
+        } else {
+            TransitionManager.go(mResultsScreen);
+            mCurrentScene = mResultsScreen;
+        }
+    }
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ScenesTestv21.java b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestv21.java
new file mode 100644
index 0000000..ecf5ef3
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestv21.java
@@ -0,0 +1,75 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.transition.ChangeBounds;
+import android.view.View;
+import android.view.ViewGroup;
+import android.transition.Fade;
+import android.transition.Recolor;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
+
+
+public class ScenesTestv21 extends Activity {
+    ViewGroup mSceneRoot;
+    static Scene mCurrentScene;
+    TransitionManager mTransitionManager = null;
+    Scene mResultsScreen, mSearchScreen;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.search_screen);
+
+        View container = (View) findViewById(R.id.container);
+        mSceneRoot = (ViewGroup) container.getParent();
+
+        mSearchScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
+        mResultsScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.results_screen, this);
+
+        TransitionSet transitionToResults = new TransitionSet();
+        Fade fade = new Fade();
+        fade.addTarget(R.id.resultsText).addTarget(R.id.resultsList);
+        fade.setStartDelay(300);
+        transitionToResults.addTransition(fade);
+        transitionToResults.addTransition(new ChangeBounds().addTarget(R.id.searchContainer));
+        transitionToResults.addTransition(new Recolor().addTarget(R.id.container));
+
+        TransitionSet transitionToSearch = new TransitionSet();
+        transitionToSearch.addTransition(new Fade().addTarget(R.id.resultsText).
+                addTarget(R.id.resultsList));
+        transitionToSearch.addTransition(new ChangeBounds().addTarget(R.id.searchContainer));
+        transitionToSearch.addTransition(new Recolor().addTarget(R.id.container));
+        mTransitionManager = new TransitionManager();
+        mTransitionManager.setTransition(mSearchScreen, transitionToSearch);
+        mTransitionManager.setTransition(mResultsScreen, transitionToResults);
+    }
+
+    public void sendMessage(View view) {
+        if (mCurrentScene == mResultsScreen) {
+            mTransitionManager.transitionTo(mSearchScreen);
+            mCurrentScene = mSearchScreen;
+        } else {
+            mTransitionManager.transitionTo(mResultsScreen);
+            mCurrentScene = mResultsScreen;
+        }
+    }
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/SequenceTest.java b/tests/TransitionTests/src/com/android/transitiontests/SequenceTest.java
new file mode 100644
index 0000000..c550e92
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/SequenceTest.java
@@ -0,0 +1,80 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.transition.Scene;
+import android.transition.Transition;
+import android.transition.TransitionSet;
+import android.widget.Button;
+import android.transition.Fade;
+import android.transition.ChangeBounds;
+import android.transition.TransitionManager;
+
+
+public class SequenceTest extends Activity {
+
+    Button mRemovingButton, mInvisibleButton, mGoneButton;
+    Scene mScene1, mScene2;
+    ViewGroup mSceneRoot;
+    TransitionSet sequencedFade, reverseSequencedFade;
+    Scene mCurrentScene;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.fading_test);
+
+        View container = (View) findViewById(R.id.container);
+        mSceneRoot = (ViewGroup) container.getParent();
+
+        mRemovingButton = (Button) findViewById(R.id.removingButton);
+        mInvisibleButton = (Button) findViewById(R.id.invisibleButton);
+        mGoneButton = (Button) findViewById(R.id.goneButton);
+
+        mScene1 = Scene.getSceneForLayout(mSceneRoot, R.layout.fading_test, this);
+        mScene2 = Scene.getSceneForLayout(mSceneRoot, R.layout.fading_test_scene_2, this);
+
+        Transition fade1 = new Fade().addTarget(R.id.removingButton);
+        Transition fade2 = new Fade().addTarget(R.id.invisibleButton);
+        Transition fade3 = new Fade().addTarget(R.id.goneButton);
+        TransitionSet fader = new TransitionSet().
+                setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+        fader.addTransition(fade1).addTransition(fade2).addTransition(fade3).
+                addTransition(new ChangeBounds());
+        sequencedFade = fader;
+
+        reverseSequencedFade = new TransitionSet().
+                setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+        reverseSequencedFade.addTransition(new ChangeBounds()).addTransition(fade3).addTransition(fade2).
+                addTransition(fade1);
+
+        mCurrentScene = mScene1;
+    }
+
+    public void sendMessage(View view) {
+        if (mCurrentScene == mScene1) {
+            TransitionManager.go(mScene2, sequencedFade);
+            mCurrentScene = mScene2;
+        } else {
+            TransitionManager.go(mScene1, reverseSequencedFade);
+            mCurrentScene = mScene1;
+        }
+    }
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/SequenceTestSimple.java b/tests/TransitionTests/src/com/android/transitiontests/SequenceTestSimple.java
new file mode 100644
index 0000000..92b169e
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/SequenceTestSimple.java
@@ -0,0 +1,75 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.transition.ChangeBounds;
+import android.view.View;
+import android.view.ViewGroup;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.widget.Button;
+import android.transition.Fade;
+import android.transition.Transition;
+import android.transition.TransitionManager;
+
+
+public class SequenceTestSimple extends Activity {
+
+    Button mRemovingButton, mInvisibleButton, mGoneButton;
+    Scene mScene1, mScene2;
+    ViewGroup mSceneRoot;
+    Transition sequencedFade;
+    TransitionSet sequencedFadeReverse;
+    Scene mCurrentScene;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.fading_test_simple);
+
+        View container = (View) findViewById(R.id.container);
+        mSceneRoot = (ViewGroup) container.getParent();
+
+        mRemovingButton = (Button) findViewById(R.id.removingButton);
+
+        mScene1 = Scene.getSceneForLayout(mSceneRoot, R.layout.fading_test_simple, this);
+        mScene2 = Scene.getSceneForLayout(mSceneRoot, R.layout.fading_test_simple2, this);
+
+        TransitionSet fader = new TransitionSet().
+                setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+        fader.addTransition(new Fade().addTarget(R.id.removingButton));
+        fader.addTransition(new ChangeBounds().addTarget(R.id.sceneSwitchButton));
+        sequencedFade = fader;
+
+        sequencedFadeReverse = new TransitionSet().
+                setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+        sequencedFadeReverse.addTransition(new ChangeBounds().addTarget(R.id.sceneSwitchButton));
+        sequencedFadeReverse.addTransition(new Fade().addTarget(R.id.removingButton));
+
+        mCurrentScene = mScene1;
+    }
+
+    public void sendMessage(View view) {
+        if (mCurrentScene == mScene1) {
+            TransitionManager.go(mScene2, sequencedFade);
+            mCurrentScene = mScene2;
+        } else {
+            TransitionManager.go(mScene1, sequencedFadeReverse);
+            mCurrentScene = mScene1;
+        }
+    }}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/SurfaceAndTextureViews.java b/tests/TransitionTests/src/com/android/transitiontests/SurfaceAndTextureViews.java
new file mode 100644
index 0000000..9b246ad
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/SurfaceAndTextureViews.java
@@ -0,0 +1,195 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.SurfaceTexture;
+import android.os.Bundle;
+import android.util.AttributeSet;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.TextureView;
+import android.view.View;
+import android.view.ViewGroup;
+import android.transition.Crossfade;
+import android.transition.ChangeBounds;
+import android.transition.Scene;
+import android.transition.TransitionSet;
+import android.transition.TransitionManager;
+import android.widget.Button;
+
+import static android.widget.LinearLayout.LayoutParams;
+
+public class SurfaceAndTextureViews extends Activity {
+
+    SimpleView mView;
+    SimpleSurfaceView mSurfaceView;
+    SimpleTextureView mTextureView;
+    private static final int SMALL_SIZE = 200;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.surface_texture_views);
+
+        final ViewGroup container = (ViewGroup) findViewById(R.id.container);
+        Button toggleButton = (Button) findViewById(R.id.toggleButton);
+
+        mView = new SimpleView(this);
+        mView.setId(0);
+        mView.setLayoutParams(new LayoutParams(SMALL_SIZE, SMALL_SIZE));
+        container.addView(mView);
+
+        mSurfaceView = new SimpleSurfaceView(this);
+        mSurfaceView.setId(1);
+        mSurfaceView.setLayoutParams(new LayoutParams(SMALL_SIZE, SMALL_SIZE));
+        container.addView(mSurfaceView);
+
+        mTextureView = new SimpleTextureView(this);
+        mTextureView.setId(2);
+        mTextureView.setLayoutParams(new LayoutParams(SMALL_SIZE, SMALL_SIZE));
+        container.addView(mTextureView);
+
+        final TransitionSet transition = new TransitionSet();
+        transition.addTransition(new ChangeBounds()).addTransition(new Crossfade().addTarget(0).
+                addTarget(1).addTarget(2));
+
+        toggleButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Scene newScene = new Scene(container);
+                newScene.setEnterAction(new Runnable() {
+                    @Override
+                    public void run() {
+                        if (mView.getWidth() <= SMALL_SIZE) {
+                            mView.setLayoutParams(new LayoutParams(SMALL_SIZE * 2, SMALL_SIZE));
+                            mSurfaceView.setLayoutParams(new LayoutParams(SMALL_SIZE * 2, SMALL_SIZE));
+                            mTextureView.setLayoutParams(new LayoutParams(SMALL_SIZE * 2, SMALL_SIZE));
+                            mView.mColor = SimpleView.LARGE_COLOR;
+                            mSurfaceView.mColor = SimpleSurfaceView.LARGE_COLOR;
+                            mTextureView.mColor = SimpleTextureView.LARGE_COLOR;
+                        } else {
+                            mView.setLayoutParams(new LayoutParams(SMALL_SIZE, SMALL_SIZE));
+                            mSurfaceView.setLayoutParams(new LayoutParams(SMALL_SIZE, SMALL_SIZE));
+                            mTextureView.setLayoutParams(new LayoutParams(SMALL_SIZE, SMALL_SIZE));
+                            mView.mColor = SimpleView.SMALL_COLOR;
+                            mSurfaceView.mColor = SimpleSurfaceView.SMALL_COLOR;
+                            mTextureView.mColor = SimpleTextureView.SMALL_COLOR;
+                        }
+                    }
+                });
+                TransitionManager.go(newScene, transition);
+            }
+        });
+
+    }
+
+    static private class SimpleView extends View {
+        static final int SMALL_COLOR = Color.BLUE;
+        static final int LARGE_COLOR = Color.YELLOW;
+        int mColor = SMALL_COLOR;
+
+        private SimpleView(Context context) {
+            super(context);
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            canvas.drawColor(mColor);
+        }
+    }
+
+    static private class SimpleSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
+
+        static final int SMALL_COLOR = Color.GREEN;
+        static final int LARGE_COLOR = Color.GRAY;
+        int mColor = SMALL_COLOR;
+        SurfaceHolder mHolder = null;
+
+        private SimpleSurfaceView(Context context) {
+            super(context);
+            SurfaceHolder holder = getHolder();
+            holder.addCallback(this);
+        }
+
+
+        @Override
+        public void surfaceCreated(SurfaceHolder holder) {
+            System.out.println("surfaceCreated");
+        }
+
+        @Override
+        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+            System.out.println("surfaceChanged: w h = " + width + ", " + height);
+            Canvas canvas = holder.lockCanvas();
+            canvas.drawColor(mColor);
+            holder.unlockCanvasAndPost(canvas);
+        }
+
+        @Override
+        public void surfaceDestroyed(SurfaceHolder holder) {
+            System.out.println("surfaceDestroyed");
+        }
+    }
+
+    static private class SimpleTextureView extends TextureView implements TextureView.SurfaceTextureListener {
+
+        static final int SMALL_COLOR = Color.RED;
+        static final int LARGE_COLOR = Color.CYAN;
+        int mColor = SMALL_COLOR;
+
+        private SimpleTextureView(Context context) {
+            super(context);
+            setSurfaceTextureListener(this);
+        }
+
+        private SimpleTextureView(Context context, AttributeSet attrs) {
+            super(context, attrs);
+            setSurfaceTextureListener(this);
+        }
+
+        private SimpleTextureView(Context context, AttributeSet attrs, int defStyle) {
+            super(context, attrs, defStyle);
+            setSurfaceTextureListener(this);
+        }
+
+        @Override
+        public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
+            System.out.println("SurfaceTexture available");
+        }
+
+        @Override
+        public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
+            System.out.println("SurfaceTexture size changed to " + width + ", " + height);
+            Canvas canvas = lockCanvas();
+            canvas.drawColor(mColor);
+            unlockCanvasAndPost(canvas);
+        }
+
+        @Override
+        public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
+            return false;
+        }
+
+        @Override
+        public void onSurfaceTextureUpdated(SurfaceTexture surface) {
+            System.out.println("SurfaceTexture updated");
+        }
+    }
+}
diff --git a/tests/TransitionTests/src/com/android/transitiontests/UniqueIds.java b/tests/TransitionTests/src/com/android/transitiontests/UniqueIds.java
new file mode 100644
index 0000000..c824956
--- /dev/null
+++ b/tests/TransitionTests/src/com/android/transitiontests/UniqueIds.java
@@ -0,0 +1,85 @@
+/*
+ * 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.transitiontests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.transition.Scene;
+import android.transition.Transition;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.transition.TransitionManager;
+
+
+import java.util.HashMap;
+
+public class UniqueIds extends Activity {
+    ViewGroup mSceneRoot;
+    static Scene mCurrentScene;
+    TransitionManager mTransitionManager = null;
+    HashMap<Button, ToggleScene> mSceneMap = new HashMap<Button, ToggleScene>();
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.unique_id_test);
+
+        LinearLayout container = (LinearLayout) findViewById(R.id.container);
+        LayoutInflater inflater = getLayoutInflater();
+        Button button = (Button) inflater.inflate(R.layout.button_template, null);
+        container.addView(button);
+        ToggleScene scene = new ToggleScene(container, button);
+        mSceneMap.put(button, scene);
+        button = (Button) inflater.inflate(R.layout.button_template, null);
+        container.addView(button);
+        scene = new ToggleScene(container, button);
+        mSceneMap.put(button, scene);
+    }
+
+    public void sendMessage(View view) {
+        mSceneMap.get(view).changeToScene();
+    }
+
+    class ToggleScene {
+        Scene mScene;
+        Transition mTransition;
+        Button mButton;
+
+        ToggleScene(ViewGroup rootView, Button button) {
+            mScene = new Scene(rootView);
+            mButton = button;
+            mScene.setEnterAction(new Runnable() {
+                @Override
+                public void run() {
+                    if (mButton.getLeft() == 0) {
+                        mButton.offsetLeftAndRight(500);
+                    } else {
+                        int width = mButton.getWidth();
+                        mButton.setLeft(0);
+                        mButton.setRight(width);
+                    }
+                }
+            });
+        }
+
+        void changeToScene() {
+            TransitionManager.go(mScene);
+        }
+    }
+}
diff --git a/tests/TtsTests/src/com/android/speech/tts/TextToSpeechTests.java b/tests/TtsTests/src/com/android/speech/tts/TextToSpeechTests.java
index b736e9f..9c2cf41 100644
--- a/tests/TtsTests/src/com/android/speech/tts/TextToSpeechTests.java
+++ b/tests/TtsTests/src/com/android/speech/tts/TextToSpeechTests.java
@@ -70,6 +70,8 @@
         // Test 1 :Tests that calls to onLoadLanguage( ) are delegated through to the
         // service without any caching or intermediate steps.
         mTts.setLanguage(new Locale("eng", "USA", "variant"));
+        LittleMock.verify(delegate, LittleMock.times(1)).onIsLanguageAvailable(
+                "eng", "USA", "variant");
         LittleMock.verify(delegate, LittleMock.times(1)).onLoadLanguage(
                 "eng", "USA", "variant");
     }
@@ -82,6 +84,8 @@
         // Test 2 : Tests that when the language is successfully set
         // like above (returns LANG_COUNTRY_AVAILABLE). That the
         // request language changes from that point on.
+        LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).when(delegate).onIsLanguageAvailable(
+                "eng", "USA", "variant");
         LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).when(delegate).onLoadLanguage(
                 "eng", "USA", "variant");
         mTts.setLanguage(new Locale("eng", "USA", "variant"));
@@ -103,6 +107,8 @@
         // TEST 3 : Tests that the language that is set does not change when the
         // engine reports it could not load the specified language.
         LittleMock.doReturn(TextToSpeech.LANG_NOT_SUPPORTED).when(
+                delegate).onIsLanguageAvailable("fra", "FRA", "");
+        LittleMock.doReturn(TextToSpeech.LANG_NOT_SUPPORTED).when(
                 delegate).onLoadLanguage("fra", "FRA", "");
         mTts.setLanguage(Locale.FRANCE);
         blockingCallSpeak("le fou barre", delegate);
@@ -116,38 +122,6 @@
         assertEquals("", req2.getValue().getVariant());
     }
 
-
-    public void testGetLanguage_invalidReturnValues() {
-        IDelegate delegate = LittleMock.mock(IDelegate.class);
-        MockableTextToSpeechService.setMocker(delegate);
-
-        // Test1: Simple end to end test. Ensure that bad return values
-        // are dealt with appropriately.
-        LittleMock.doReturn(null).when(delegate).onGetLanguage();
-        Locale returnVal = mTts.getLanguage();
-        assertNull(returnVal);
-
-
-        // Bad value 2. An array of length < 3.
-        LittleMock.doReturn(new String[] {"eng", "usa"}).when(delegate).onGetLanguage();
-        returnVal = mTts.getLanguage();
-        assertNull(returnVal);
-    }
-
-    public void testGetLanguage_validReturnValues() {
-        IDelegate delegate = LittleMock.mock(IDelegate.class);
-        MockableTextToSpeechService.setMocker(delegate);
-
-        // A correct value.
-        LittleMock.doReturn(new String[] {"eng", "usa", ""}).when(delegate).onGetLanguage();
-        Locale returnVal = mTts.getLanguage();
-
-        // Note: This is not the same as Locale.US . Well tough luck for
-        // being the only component of the entire framework that standardized
-        // three letter country and language codes.
-        assertEquals(new Locale("eng", "USA", ""), returnVal);
-    }
-
     public void testIsLanguageAvailable() {
         IDelegate delegate = LittleMock.mock(IDelegate.class);
         MockableTextToSpeechService.setMocker(delegate);
diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
index 746ac06..e4c4214 100644
--- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
@@ -93,7 +93,7 @@
         }
         
         try {
-            mWm.addAppToken(0, null, 0, 0, false, false);
+            mWm.addAppToken(0, null, 0, 0, 0, false, false, 0);
             fail("IWindowManager.addAppToken did not throw SecurityException as"
                     + " expected");
         } catch (SecurityException e) {
@@ -164,7 +164,7 @@
         }
         
         try {
-            mWm.setAppStartingWindow(null, "foo", 0, null, null, 0, 0, 0, null, false);
+            mWm.setAppStartingWindow(null, "foo", 0, null, null, 0, 0, 0, 0, null, false);
             fail("IWindowManager.setAppStartingWindow did not throw SecurityException as"
                     + " expected");
         } catch (SecurityException e) {
@@ -222,37 +222,7 @@
         } catch (RemoteException e) {
             fail("Unexpected remote exception");
         }
-        
-        try {
-            mWm.moveAppToken(0, null);
-            fail("IWindowManager.moveAppToken did not throw SecurityException as"
-                    + " expected");
-        } catch (SecurityException e) {
-            // expected
-        } catch (RemoteException e) {
-            fail("Unexpected remote exception");
-        }
-        
-        try {
-            mWm.moveAppTokensToTop(null);
-            fail("IWindowManager.moveAppTokensToTop did not throw SecurityException as"
-                    + " expected");
-        } catch (SecurityException e) {
-            // expected
-        } catch (RemoteException e) {
-            fail("Unexpected remote exception");
-        }
-        
-        try {
-            mWm.moveAppTokensToBottom(null);
-            fail("IWindowManager.moveAppTokensToBottom did not throw SecurityException as"
-                    + " expected");
-        } catch (SecurityException e) {
-            // expected
-        } catch (RemoteException e) {
-            fail("Unexpected remote exception");
-        }
-	}    
+    }
 
     @SmallTest
     public void testDISABLE_KEYGUARD() {
diff --git a/tools/aapt/Android.mk b/tools/aapt/Android.mk
index 9b1658a..452c60a 100644
--- a/tools/aapt/Android.mk
+++ b/tools/aapt/Android.mk
@@ -7,10 +7,8 @@
 # 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 := \
+aapt_src_files := \
 	AaptAssets.cpp \
 	Command.cpp \
 	CrunchCache.cpp \
@@ -24,23 +22,29 @@
 	ResourceTable.cpp \
 	Images.cpp \
 	Resource.cpp \
+    pseudolocalize.cpp \
     SourcePos.cpp \
+	WorkQueue.cpp \
     ZipEntry.cpp \
-    ZipFile.cpp
+    ZipFile.cpp \
+	qsort_r_compat.c
 
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(aapt_src_files)
 
 LOCAL_CFLAGS += -Wno-format-y2k
 ifeq (darwin,$(HOST_OS))
 LOCAL_CFLAGS += -D_DARWIN_UNLIMITED_STREAMS
 endif
 
+LOCAL_CFLAGS += -DSTATIC_ANDROIDFW_FOR_TOOLS
 
 LOCAL_C_INCLUDES += external/libpng
 LOCAL_C_INCLUDES += external/zlib
-LOCAL_C_INCLUDES += build/libs/host/include
 
 LOCAL_STATIC_LIBRARIES := \
-	libhost \
 	libandroidfw \
 	libutils \
 	libcutils \
@@ -64,4 +68,36 @@
 
 include $(BUILD_HOST_EXECUTABLE)
 
+# aapt for running on the device
+# =========================================================
+ifneq ($(SDK_ONLY),true)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(aapt_src_files)
+
+LOCAL_MODULE := aapt
+
+LOCAL_C_INCLUDES += bionic
+LOCAL_C_INCLUDES += bionic/libstdc++/include
+LOCAL_C_INCLUDES += external/stlport/stlport
+LOCAL_C_INCLUDES += external/libpng
+LOCAL_C_INCLUDES += external/zlib
+
+LOCAL_CFLAGS += -Wno-non-virtual-dtor
+
+LOCAL_SHARED_LIBRARIES := \
+        libandroidfw \
+        libutils \
+        libcutils \
+        libpng \
+        liblog \
+        libz
+
+LOCAL_STATIC_LIBRARIES := \
+        libstlport_static \
+        libexpat_static
+
+include $(BUILD_EXECUTABLE)
+endif
+
 endif # TARGET_BUILD_APPS
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index cadac02..1e3b058 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -621,6 +621,7 @@
             bool isLauncherActivity = false;
             bool isSearchable = false;
             bool withinApplication = false;
+            bool withinSupportsInput = false;
             bool withinReceiver = false;
             bool withinService = false;
             bool withinIntentFilter = false;
@@ -711,11 +712,26 @@
             String8 activityIcon;
             String8 receiverName;
             String8 serviceName;
+            Vector<String8> supportedInput;
             while ((code=tree.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
                 if (code == ResXMLTree::END_TAG) {
                     depth--;
                     if (depth < 2) {
+                        if (withinSupportsInput && !supportedInput.isEmpty()) {
+                            printf("supports-input: '");
+                            const size_t N = supportedInput.size();
+                            for (size_t i=0; i<N; i++) {
+                                printf("%s", supportedInput[i].string());
+                                if (i != N - 1) {
+                                    printf("' '");
+                                } else {
+                                    printf("'\n");
+                                }
+                            }
+                            supportedInput.clear();
+                        }
                         withinApplication = false;
+                        withinSupportsInput = false;
                     } else if (depth < 3) {
                         if (withinActivity && isMainActivity && isLauncherActivity) {
                             const char *aName = getComponentName(pkg, activityName);
@@ -910,6 +926,8 @@
                             printf(" reqFiveWayNav='%d'", reqFiveWayNav);
                         }
                         printf("\n");
+                    } else if (tag == "supports-input") {
+                        withinSupportsInput = true;
                     } else if (tag == "supports-screens") {
                         smallScreen = getIntegerAttribute(tree,
                                 SMALL_SCREEN_ATTR, NULL, 1);
@@ -1086,66 +1104,85 @@
                             }
                         }
                     }
-                } else if (depth == 3 && withinApplication) {
+                } else if (depth == 3) {
                     withinActivity = false;
                     withinReceiver = false;
                     withinService = false;
                     hasIntentFilter = false;
-                    if(tag == "activity") {
-                        withinActivity = true;
-                        activityName = getAttribute(tree, NAME_ATTR, &error);
-                        if (error != "") {
-                            fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", error.string());
-                            goto bail;
-                        }
+                    if (withinApplication) {
+                        if(tag == "activity") {
+                            withinActivity = true;
+                            activityName = getAttribute(tree, NAME_ATTR, &error);
+                            if (error != "") {
+                                fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n",
+                                        error.string());
+                                goto bail;
+                            }
 
-                        activityLabel = getResolvedAttribute(&res, tree, LABEL_ATTR, &error);
-                        if (error != "") {
-                            fprintf(stderr, "ERROR getting 'android:label' attribute: %s\n", error.string());
-                            goto bail;
-                        }
+                            activityLabel = getResolvedAttribute(&res, tree, LABEL_ATTR, &error);
+                            if (error != "") {
+                                fprintf(stderr, "ERROR getting 'android:label' attribute: %s\n",
+                                        error.string());
+                                goto bail;
+                            }
 
-                        activityIcon = getResolvedAttribute(&res, tree, ICON_ATTR, &error);
-                        if (error != "") {
-                            fprintf(stderr, "ERROR getting 'android:icon' attribute: %s\n", error.string());
-                            goto bail;
-                        }
+                            activityIcon = getResolvedAttribute(&res, tree, ICON_ATTR, &error);
+                            if (error != "") {
+                                fprintf(stderr, "ERROR getting 'android:icon' attribute: %s\n",
+                                        error.string());
+                                goto bail;
+                            }
 
-                        int32_t orien = getResolvedIntegerAttribute(&res, tree,
-                                SCREEN_ORIENTATION_ATTR, &error);
-                        if (error == "") {
-                            if (orien == 0 || orien == 6 || orien == 8) {
-                                // Requests landscape, sensorLandscape, or reverseLandscape.
-                                reqScreenLandscapeFeature = true;
-                            } else if (orien == 1 || orien == 7 || orien == 9) {
-                                // Requests portrait, sensorPortrait, or reversePortrait.
-                                reqScreenPortraitFeature = true;
+                            int32_t orien = getResolvedIntegerAttribute(&res, tree,
+                                    SCREEN_ORIENTATION_ATTR, &error);
+                            if (error == "") {
+                                if (orien == 0 || orien == 6 || orien == 8) {
+                                    // Requests landscape, sensorLandscape, or reverseLandscape.
+                                    reqScreenLandscapeFeature = true;
+                                } else if (orien == 1 || orien == 7 || orien == 9) {
+                                    // Requests portrait, sensorPortrait, or reversePortrait.
+                                    reqScreenPortraitFeature = true;
+                                }
+                            }
+                        } else if (tag == "uses-library") {
+                            String8 libraryName = getAttribute(tree, NAME_ATTR, &error);
+                            if (error != "") {
+                                fprintf(stderr,
+                                        "ERROR getting 'android:name' attribute for uses-library"
+                                        " %s\n", error.string());
+                                goto bail;
+                            }
+                            int req = getIntegerAttribute(tree,
+                                    REQUIRED_ATTR, NULL, 1);
+                            printf("uses-library%s:'%s'\n",
+                                    req ? "" : "-not-required", libraryName.string());
+                        } else if (tag == "receiver") {
+                            withinReceiver = true;
+                            receiverName = getAttribute(tree, NAME_ATTR, &error);
+
+                            if (error != "") {
+                                fprintf(stderr,
+                                        "ERROR getting 'android:name' attribute for receiver:"
+                                        " %s\n", error.string());
+                                goto bail;
+                            }
+                        } else if (tag == "service") {
+                            withinService = true;
+                            serviceName = getAttribute(tree, NAME_ATTR, &error);
+
+                            if (error != "") {
+                                fprintf(stderr, "ERROR getting 'android:name' attribute for"
+                                        " service: %s\n", error.string());
+                                goto bail;
                             }
                         }
-                    } else if (tag == "uses-library") {
-                        String8 libraryName = getAttribute(tree, NAME_ATTR, &error);
-                        if (error != "") {
-                            fprintf(stderr, "ERROR getting 'android:name' attribute for uses-library: %s\n", error.string());
-                            goto bail;
-                        }
-                        int req = getIntegerAttribute(tree,
-                                REQUIRED_ATTR, NULL, 1);
-                        printf("uses-library%s:'%s'\n",
-                                req ? "" : "-not-required", libraryName.string());
-                    } else if (tag == "receiver") {
-                        withinReceiver = true;
-                        receiverName = getAttribute(tree, NAME_ATTR, &error);
-
-                        if (error != "") {
-                            fprintf(stderr, "ERROR getting 'android:name' attribute for receiver: %s\n", error.string());
-                            goto bail;
-                        }
-                    } else if (tag == "service") {
-                        withinService = true;
-                        serviceName = getAttribute(tree, NAME_ATTR, &error);
-
-                        if (error != "") {
-                            fprintf(stderr, "ERROR getting 'android:name' attribute for service: %s\n", error.string());
+                    } else if (withinSupportsInput && tag == "input-type") {
+                        String8 name = getAttribute(tree, NAME_ATTR, &error);
+                        if (name != "" && error == "") {
+                            supportedInput.add(name);
+                        } else {
+                            fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n",
+                                    error.string());
                             goto bail;
                         }
                     }
diff --git a/tools/aapt/Package.cpp b/tools/aapt/Package.cpp
index 3930117..872d95c 100644
--- a/tools/aapt/Package.cpp
+++ b/tools/aapt/Package.cpp
@@ -8,10 +8,13 @@
 #include "ResourceTable.h"
 #include "ResourceFilter.h"
 
+#include <androidfw/misc.h>
+
 #include <utils/Log.h>
 #include <utils/threads.h>
 #include <utils/List.h>
 #include <utils/Errors.h>
+#include <utils/misc.h>
 
 #include <sys/types.h>
 #include <dirent.h>
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index 6168bbd..08ad7a0 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -14,7 +14,7 @@
 #include "FileFinder.h"
 #include "CacheUpdater.h"
 
-#include <utils/WorkQueue.h>
+#include "WorkQueue.h"
 
 #if HAVE_PRINTF_ZD
 #  define ZD "%zd"
@@ -172,6 +172,7 @@
 bool isValidResourceType(const String8& type)
 {
     return type == "anim" || type == "animator" || type == "interpolator"
+        || type == "transition"
         || type == "drawable" || type == "layout"
         || type == "values" || type == "xml" || type == "raw"
         || type == "color" || type == "menu" || type == "mipmap";
@@ -932,6 +933,7 @@
     sp<ResourceTypeSet> anims;
     sp<ResourceTypeSet> animators;
     sp<ResourceTypeSet> interpolators;
+    sp<ResourceTypeSet> transitions;
     sp<ResourceTypeSet> xmls;
     sp<ResourceTypeSet> raws;
     sp<ResourceTypeSet> colors;
@@ -943,6 +945,7 @@
     ASSIGN_IT(anim);
     ASSIGN_IT(animator);
     ASSIGN_IT(interpolator);
+    ASSIGN_IT(transition);
     ASSIGN_IT(xml);
     ASSIGN_IT(raw);
     ASSIGN_IT(color);
@@ -965,6 +968,7 @@
             !applyFileOverlay(bundle, assets, &anims, "anim") ||
             !applyFileOverlay(bundle, assets, &animators, "animator") ||
             !applyFileOverlay(bundle, assets, &interpolators, "interpolator") ||
+            !applyFileOverlay(bundle, assets, &transitions, "transition") ||
             !applyFileOverlay(bundle, assets, &xmls, "xml") ||
             !applyFileOverlay(bundle, assets, &raws, "raw") ||
             !applyFileOverlay(bundle, assets, &colors, "color") ||
@@ -1024,6 +1028,13 @@
         }
     }
 
+    if (transitions != NULL) {
+        err = makeFileResources(bundle, assets, &table, transitions, "transition");
+        if (err != NO_ERROR) {
+            hasErrors = true;
+        }
+    }
+
     if (interpolators != NULL) {
         err = makeFileResources(bundle, assets, &table, interpolators, "interpolator");
         if (err != NO_ERROR) {
@@ -1168,6 +1179,21 @@
         err = NO_ERROR;
     }
 
+    if (transitions != NULL) {
+        ResourceDirIterator it(transitions, String8("transition"));
+        while ((err=it.next()) == NO_ERROR) {
+            err = compileXmlFile(assets, it.getFile(), &table, xmlFlags);
+            if (err != NO_ERROR) {
+                hasErrors = true;
+            }
+        }
+
+        if (err < NO_ERROR) {
+            hasErrors = true;
+        }
+        err = NO_ERROR;
+    }
+
     if (xmls != NULL) {
         ResourceDirIterator it(xmls, String8("xml"));
         while ((err=it.next()) == NO_ERROR) {
diff --git a/tools/aapt/StringPool.cpp b/tools/aapt/StringPool.cpp
index 839eda5..158b391 100644
--- a/tools/aapt/StringPool.cpp
+++ b/tools/aapt/StringPool.cpp
@@ -9,7 +9,7 @@
 
 #include <utils/ByteOrder.h>
 #include <utils/SortedVector.h>
-#include <cutils/qsort_r_compat.h>
+#include "qsort_r_compat.h"
 
 #if HAVE_PRINTF_ZD
 #  define ZD "%zd"
diff --git a/tools/aapt/StringPool.h b/tools/aapt/StringPool.h
index 16050b2..1b3abfd 100644
--- a/tools/aapt/StringPool.h
+++ b/tools/aapt/StringPool.h
@@ -12,7 +12,6 @@
 
 #include <androidfw/ResourceTypes.h>
 #include <utils/String16.h>
-#include <utils/TextOutput.h>
 #include <utils/TypeHelpers.h>
 
 #include <sys/types.h>
diff --git a/tools/aapt/WorkQueue.cpp b/tools/aapt/WorkQueue.cpp
new file mode 100644
index 0000000..24a962f
--- /dev/null
+++ b/tools/aapt/WorkQueue.cpp
@@ -0,0 +1,171 @@
+/*
+ * 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.
+ */
+
+// #define LOG_NDEBUG 0
+#define LOG_TAG "WorkQueue"
+
+#include <utils/Log.h>
+#include "WorkQueue.h"
+
+namespace android {
+
+// --- WorkQueue ---
+
+WorkQueue::WorkQueue(size_t maxThreads, bool canCallJava) :
+        mMaxThreads(maxThreads), mCanCallJava(canCallJava),
+        mCanceled(false), mFinished(false), mIdleThreads(0) {
+}
+
+WorkQueue::~WorkQueue() {
+    if (!cancel()) {
+        finish();
+    }
+}
+
+status_t WorkQueue::schedule(WorkUnit* workUnit, size_t backlog) {
+    AutoMutex _l(mLock);
+
+    if (mFinished || mCanceled) {
+        return INVALID_OPERATION;
+    }
+
+    if (mWorkThreads.size() < mMaxThreads
+            && mIdleThreads < mWorkUnits.size() + 1) {
+        sp<WorkThread> workThread = new WorkThread(this, mCanCallJava);
+        status_t status = workThread->run("WorkQueue::WorkThread");
+        if (status) {
+            return status;
+        }
+        mWorkThreads.add(workThread);
+        mIdleThreads += 1;
+    } else if (backlog) {
+        while (mWorkUnits.size() >= mMaxThreads * backlog) {
+            mWorkDequeuedCondition.wait(mLock);
+            if (mFinished || mCanceled) {
+                return INVALID_OPERATION;
+            }
+        }
+    }
+
+    mWorkUnits.add(workUnit);
+    mWorkChangedCondition.broadcast();
+    return OK;
+}
+
+status_t WorkQueue::cancel() {
+    AutoMutex _l(mLock);
+
+    return cancelLocked();
+}
+
+status_t WorkQueue::cancelLocked() {
+    if (mFinished) {
+        return INVALID_OPERATION;
+    }
+
+    if (!mCanceled) {
+        mCanceled = true;
+
+        size_t count = mWorkUnits.size();
+        for (size_t i = 0; i < count; i++) {
+            delete mWorkUnits.itemAt(i);
+        }
+        mWorkUnits.clear();
+        mWorkChangedCondition.broadcast();
+        mWorkDequeuedCondition.broadcast();
+    }
+    return OK;
+}
+
+status_t WorkQueue::finish() {
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        if (mFinished) {
+            return INVALID_OPERATION;
+        }
+
+        mFinished = true;
+        mWorkChangedCondition.broadcast();
+    } // release lock
+
+    // It is not possible for the list of work threads to change once the mFinished
+    // flag has been set, so we can access mWorkThreads outside of the lock here.
+    size_t count = mWorkThreads.size();
+    for (size_t i = 0; i < count; i++) {
+        mWorkThreads.itemAt(i)->join();
+    }
+    mWorkThreads.clear();
+    return OK;
+}
+
+bool WorkQueue::threadLoop() {
+    WorkUnit* workUnit;
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        for (;;) {
+            if (mCanceled) {
+                return false;
+            }
+
+            if (!mWorkUnits.isEmpty()) {
+                workUnit = mWorkUnits.itemAt(0);
+                mWorkUnits.removeAt(0);
+                mIdleThreads -= 1;
+                mWorkDequeuedCondition.broadcast();
+                break;
+            }
+
+            if (mFinished) {
+                return false;
+            }
+
+            mWorkChangedCondition.wait(mLock);
+        }
+    } // release lock
+
+    bool shouldContinue = workUnit->run();
+    delete workUnit;
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        mIdleThreads += 1;
+
+        if (!shouldContinue) {
+            cancelLocked();
+            return false;
+        }
+    } // release lock
+
+    return true;
+}
+
+// --- WorkQueue::WorkThread ---
+
+WorkQueue::WorkThread::WorkThread(WorkQueue* workQueue, bool canCallJava) :
+        Thread(canCallJava), mWorkQueue(workQueue) {
+}
+
+WorkQueue::WorkThread::~WorkThread() {
+}
+
+bool WorkQueue::WorkThread::threadLoop() {
+    return mWorkQueue->threadLoop();
+}
+
+};  // namespace android
diff --git a/tools/aapt/WorkQueue.h b/tools/aapt/WorkQueue.h
new file mode 100644
index 0000000..d38f05d
--- /dev/null
+++ b/tools/aapt/WorkQueue.h
@@ -0,0 +1,119 @@
+/*]
+ * 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.
+ */
+
+#ifndef AAPT_WORK_QUEUE_H
+#define AAPT_WORK_QUEUE_H
+
+#include <utils/Errors.h>
+#include <utils/Vector.h>
+#include <utils/threads.h>
+
+namespace android {
+
+/*
+ * A threaded work queue.
+ *
+ * This class is designed to make it easy to run a bunch of isolated work
+ * units in parallel, using up to the specified number of threads.
+ * To use it, write a loop to post work units to the work queue, then synchronize
+ * on the queue at the end.
+ */
+class WorkQueue {
+public:
+    class WorkUnit {
+    public:
+        WorkUnit() { }
+        virtual ~WorkUnit() { }
+
+        /*
+         * Runs the work unit.
+         * If the result is 'true' then the work queue continues scheduling work as usual.
+         * If the result is 'false' then the work queue is canceled.
+         */
+        virtual bool run() = 0;
+    };
+
+    /* Creates a work queue with the specified maximum number of work threads. */
+    WorkQueue(size_t maxThreads, bool canCallJava = true);
+
+    /* Destroys the work queue.
+     * Cancels pending work and waits for all remaining threads to complete.
+     */
+    ~WorkQueue();
+
+    /* Posts a work unit to run later.
+     * If the work queue has been canceled or is already finished, returns INVALID_OPERATION
+     * and does not take ownership of the work unit (caller must destroy it itself).
+     * Otherwise, returns OK and takes ownership of the work unit (the work queue will
+     * destroy it automatically).
+     *
+     * For flow control, this method blocks when the size of the pending work queue is more
+     * 'backlog' times the number of threads.  This condition reduces the rate of entry into
+     * the pending work queue and prevents it from growing much more rapidly than the
+     * work threads can actually handle.
+     *
+     * If 'backlog' is 0, then no throttle is applied.
+     */
+    status_t schedule(WorkUnit* workUnit, size_t backlog = 2);
+
+    /* Cancels all pending work.
+     * If the work queue is already finished, returns INVALID_OPERATION.
+     * If the work queue is already canceled, returns OK and does nothing else.
+     * Otherwise, returns OK, discards all pending work units and prevents additional
+     * work units from being scheduled.
+     *
+     * Call finish() after cancel() to wait for all remaining work to complete.
+     */
+    status_t cancel();
+
+    /* Waits for all work to complete.
+     * If the work queue is already finished, returns INVALID_OPERATION.
+     * Otherwise, waits for all work to complete and returns OK.
+     */
+    status_t finish();
+
+private:
+    class WorkThread : public Thread {
+    public:
+        WorkThread(WorkQueue* workQueue, bool canCallJava);
+        virtual ~WorkThread();
+
+    private:
+        virtual bool threadLoop();
+
+        WorkQueue* const mWorkQueue;
+    };
+
+    status_t cancelLocked();
+    bool threadLoop(); // called from each work thread
+
+    const size_t mMaxThreads;
+    const bool mCanCallJava;
+
+    Mutex mLock;
+    Condition mWorkChangedCondition;
+    Condition mWorkDequeuedCondition;
+
+    bool mCanceled;
+    bool mFinished;
+    size_t mIdleThreads;
+    Vector<sp<WorkThread> > mWorkThreads;
+    Vector<WorkUnit*> mWorkUnits;
+};
+
+}; // namespace android
+
+#endif // AAPT_WORK_QUEUE_H
diff --git a/tools/aapt/XMLNode.cpp b/tools/aapt/XMLNode.cpp
index dcbe7db..a663ad5 100644
--- a/tools/aapt/XMLNode.cpp
+++ b/tools/aapt/XMLNode.cpp
@@ -6,8 +6,8 @@
 
 #include "XMLNode.h"
 #include "ResourceTable.h"
+#include "pseudolocalize.h"
 
-#include <host/pseudolocalize.h>
 #include <utils/ByteOrder.h>
 #include <errno.h>
 #include <string.h>
diff --git a/tools/aapt/ZipFile.cpp b/tools/aapt/ZipFile.cpp
index 3994c31..8057068 100644
--- a/tools/aapt/ZipFile.cpp
+++ b/tools/aapt/ZipFile.cpp
@@ -20,8 +20,8 @@
 
 #define LOG_TAG "zip"
 
+#include <androidfw/ZipUtils.h>
 #include <utils/Log.h>
-#include <utils/ZipUtils.h>
 
 #include "ZipFile.h"
 
diff --git a/tools/aapt/pseudolocalize.cpp b/tools/aapt/pseudolocalize.cpp
new file mode 100644
index 0000000..9e50c5a
--- /dev/null
+++ b/tools/aapt/pseudolocalize.cpp
@@ -0,0 +1,119 @@
+#include "pseudolocalize.h"
+
+using namespace std;
+
+static const char*
+pseudolocalize_char(char c)
+{
+    switch (c) {
+        case 'a':   return "\xc4\x83";
+        case 'b':   return "\xcf\x84";
+        case 'c':   return "\xc4\x8b";
+        case 'd':   return "\xc4\x8f";
+        case 'e':   return "\xc4\x99";
+        case 'f':   return "\xc6\x92";
+        case 'g':   return "\xc4\x9d";
+        case 'h':   return "\xd1\x9b";
+        case 'i':   return "\xcf\x8a";
+        case 'j':   return "\xc4\xb5";
+        case 'k':   return "\xc4\xb8";
+        case 'l':   return "\xc4\xba";
+        case 'm':   return "\xe1\xb8\xbf";
+        case 'n':   return "\xd0\xb8";
+        case 'o':   return "\xcf\x8c";
+        case 'p':   return "\xcf\x81";
+        case 'q':   return "\x51";
+        case 'r':   return "\xd2\x91";
+        case 's':   return "\xc5\xa1";
+        case 't':   return "\xd1\x82";
+        case 'u':   return "\xce\xb0";
+        case 'v':   return "\x56";
+        case 'w':   return "\xe1\xba\x85";
+        case 'x':   return "\xd1\x85";
+        case 'y':   return "\xe1\xbb\xb3";
+        case 'z':   return "\xc5\xba";
+        case 'A':   return "\xc3\x85";
+        case 'B':   return "\xce\xb2";
+        case 'C':   return "\xc4\x88";
+        case 'D':   return "\xc4\x90";
+        case 'E':   return "\xd0\x84";
+        case 'F':   return "\xce\x93";
+        case 'G':   return "\xc4\x9e";
+        case 'H':   return "\xc4\xa6";
+        case 'I':   return "\xd0\x87";
+        case 'J':   return "\xc4\xb5";
+        case 'K':   return "\xc4\xb6";
+        case 'L':   return "\xc5\x81";
+        case 'M':   return "\xe1\xb8\xbe";
+        case 'N':   return "\xc5\x83";
+        case 'O':   return "\xce\x98";
+        case 'P':   return "\xcf\x81";
+        case 'Q':   return "\x71";
+        case 'R':   return "\xd0\xaf";
+        case 'S':   return "\xc8\x98";
+        case 'T':   return "\xc5\xa6";
+        case 'U':   return "\xc5\xa8";
+        case 'V':   return "\xce\xbd";
+        case 'W':   return "\xe1\xba\x84";
+        case 'X':   return "\xc3\x97";
+        case 'Y':   return "\xc2\xa5";
+        case 'Z':   return "\xc5\xbd";
+        default:    return NULL;
+    }
+}
+
+/**
+ * Converts characters so they look like they've been localized.
+ *
+ * Note: This leaves escape sequences untouched so they can later be
+ * processed by ResTable::collectString in the normal way.
+ */
+string
+pseudolocalize_string(const string& source)
+{
+    const char* s = source.c_str();
+    string result;
+    const size_t I = source.length();
+    for (size_t i=0; i<I; i++) {
+        char c = s[i];
+        if (c == '\\') {
+            if (i<I-1) {
+                result += '\\';
+                i++;
+                c = s[i];
+                switch (c) {
+                    case 'u':
+                        // this one takes up 5 chars
+                        result += string(s+i, 5);
+                        i += 4;
+                        break;
+                    case 't':
+                    case 'n':
+                    case '#':
+                    case '@':
+                    case '?':
+                    case '"':
+                    case '\'':
+                    case '\\':
+                    default:
+                        result += c;
+                        break;
+                }
+            } else {
+                result += c;
+            }
+        } else {
+            const char* p = pseudolocalize_char(c);
+            if (p != NULL) {
+                result += p;
+            } else {
+                result += c;
+            }
+        }
+    }
+
+    //printf("result=\'%s\'\n", result.c_str());
+    return result;
+}
+
+
diff --git a/tools/aapt/pseudolocalize.h b/tools/aapt/pseudolocalize.h
new file mode 100644
index 0000000..94cb034
--- /dev/null
+++ b/tools/aapt/pseudolocalize.h
@@ -0,0 +1,9 @@
+#ifndef HOST_PSEUDOLOCALIZE_H
+#define HOST_PSEUDOLOCALIZE_H
+
+#include <string>
+
+std::string pseudolocalize_string(const std::string& source);
+
+#endif // HOST_PSEUDOLOCALIZE_H
+
diff --git a/tools/aapt/qsort_r_compat.c b/tools/aapt/qsort_r_compat.c
new file mode 100644
index 0000000..2a8dbe8
--- /dev/null
+++ b/tools/aapt/qsort_r_compat.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include "qsort_r_compat.h"
+
+/*
+ * Note: This code is only used on the host, and is primarily here for
+ * Mac OS compatibility. Apparently, glibc and Apple's libc disagree on
+ * the parameter order for qsort_r.
+ */
+
+#if HAVE_BSD_QSORT_R
+
+/*
+ * BSD qsort_r parameter order is as we have defined here.
+ */
+
+void qsort_r_compat(void* base, size_t nel, size_t width, void* thunk,
+        int (*compar)(void*, const void* , const void*)) {
+    qsort_r(base, nel, width, thunk, compar);
+}
+
+#elif HAVE_GNU_QSORT_R
+
+/*
+ * GNU qsort_r parameter order places the thunk parameter last.
+ */
+
+struct compar_data {
+    void* thunk;
+    int (*compar)(void*, const void* , const void*);
+};
+
+static int compar_wrapper(const void* a, const void* b, void* data) {
+    struct compar_data* compar_data = (struct compar_data*)data;
+    return compar_data->compar(compar_data->thunk, a, b);
+}
+
+void qsort_r_compat(void* base, size_t nel, size_t width, void* thunk,
+        int (*compar)(void*, const void* , const void*)) {
+    struct compar_data compar_data;
+    compar_data.thunk = thunk;
+    compar_data.compar = compar;
+    qsort_r(base, nel, width, compar_wrapper, &compar_data);
+}
+
+#else
+
+/*
+ * Emulate qsort_r using thread local storage to access the thunk data.
+ */
+
+#include <cutils/threads.h>
+
+static thread_store_t compar_data_key = THREAD_STORE_INITIALIZER;
+
+struct compar_data {
+    void* thunk;
+    int (*compar)(void*, const void* , const void*);
+};
+
+static int compar_wrapper(const void* a, const void* b) {
+    struct compar_data* compar_data = (struct compar_data*)thread_store_get(&compar_data_key);
+    return compar_data->compar(compar_data->thunk, a, b);
+}
+
+void qsort_r_compat(void* base, size_t nel, size_t width, void* thunk,
+        int (*compar)(void*, const void* , const void*)) {
+    struct compar_data compar_data;
+    compar_data.thunk = thunk;
+    compar_data.compar = compar;
+    thread_store_set(&compar_data_key, &compar_data, NULL);
+    qsort(base, nel, width, compar_wrapper);
+}
+
+#endif
diff --git a/tools/aapt/qsort_r_compat.h b/tools/aapt/qsort_r_compat.h
new file mode 100644
index 0000000..e14f999
--- /dev/null
+++ b/tools/aapt/qsort_r_compat.h
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+/*
+ * Provides a portable version of qsort_r, called qsort_r_compat, which is a
+ * reentrant variant of qsort that passes a user data pointer to its comparator.
+ * This implementation follows the BSD parameter convention.
+ */
+
+#ifndef ___QSORT_R_COMPAT_H
+#define ___QSORT_R_COMPAT_H
+
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void qsort_r_compat(void* base, size_t nel, size_t width, void* thunk,
+        int (*compar)(void*, const void* , const void* ));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ___QSORT_R_COMPAT_H
diff --git a/tools/aidl/aidl.cpp b/tools/aidl/aidl.cpp
index 071a8d7..b8a4803 100644
--- a/tools/aidl/aidl.cpp
+++ b/tools/aidl/aidl.cpp
@@ -673,6 +673,16 @@
 
     fprintf(to, "\n");
 
+    // Output "<imported_file>: " so make won't fail if the imported file has
+    // been deleted, moved or renamed in incremental build.
+    import = g_imports;
+    while (import) {
+        if (import->filename) {
+            fprintf(to, "%s :\n", import->filename);
+        }
+        import = import->next;
+    }
+
     fclose(to);
 }
 
diff --git a/tools/layoutlib/Android.mk b/tools/layoutlib/Android.mk
index b27ce0e..4e73568 100644
--- a/tools/layoutlib/Android.mk
+++ b/tools/layoutlib/Android.mk
@@ -25,8 +25,8 @@
 # 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_framework_dep := $(call java-lib-deps,framework-base)
+built_framework_classes := $(call java-lib-files,framework-base)
 
 built_core_dep := $(call java-lib-deps,core)
 built_core_classes := $(call java-lib-files,core)
diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java
index 5256b58..04ce9d0 100644
--- a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java
@@ -24,10 +24,13 @@
 
 import android.content.res.BridgeResources.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
@@ -98,8 +101,12 @@
         //TODO support rescaling
 
         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);
+            }
         }
 
         try {
@@ -112,7 +119,7 @@
                         npis, true /*is9Patch*/, false /*convert*/);
 
                 // get the bitmap and chunk objects.
-                bm = Bitmap_Delegate.createBitmap(ninePatch.getImage(), true /*isMutable*/,
+                bm = Bitmap_Delegate.createBitmap(ninePatch.getImage(), bitmapCreateFlags,
                         density);
                 NinePatchChunk chunk = ninePatch.getChunk();
 
@@ -127,7 +134,7 @@
                 padding.bottom = paddingarray[3];
             } else {
                 // load the bitmap directly.
-                bm = Bitmap_Delegate.createBitmap(is, true, density);
+                bm = Bitmap_Delegate.createBitmap(is, bitmapCreateFlags, density);
             }
         } catch (IOException e) {
             Bridge.getLog().error(null,"Failed to load image" , e, null);
diff --git a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
index 96616aa..ec284ac 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
@@ -33,6 +33,8 @@
 import java.io.OutputStream;
 import java.nio.Buffer;
 import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.Set;
 
 import javax.imageio.ImageIO;
 
@@ -51,6 +53,10 @@
  */
 public final class Bitmap_Delegate {
 
+    public enum BitmapCreateFlags {
+        PREMULTIPLIED, MUTABLE
+    }
+
     // ---- delegate manager ----
     private static final DelegateManager<Bitmap_Delegate> sManager =
             new DelegateManager<Bitmap_Delegate>(Bitmap_Delegate.class);
@@ -93,10 +99,25 @@
      */
     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()
+     */
+    public static Bitmap createBitmap(File input, Set<BitmapCreateFlags> createFlags,
+            Density density) throws IOException {
         // create a delegate with the content of the file.
         Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input), Config.ARGB_8888);
 
-        return createBitmap(delegate, isMutable, density.getDpiValue());
+        return createBitmap(delegate, createFlags, density.getDpiValue());
     }
 
     /**
@@ -111,10 +132,26 @@
      */
     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 createFlags
+     * @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, isMutable, density.getDpiValue());
+        return createBitmap(delegate, createFlags, density.getDpiValue());
     }
 
     /**
@@ -129,10 +166,26 @@
      */
     public static Bitmap createBitmap(BufferedImage image, boolean isMutable,
             Density density) throws IOException {
+        return createBitmap(image, getPremultipliedBitmapCreateFlags(isMutable), density);
+    }
+
+    /**
+     * Creates and returns a {@link Bitmap} initialized with the given {@link BufferedImage}
+     *
+     * @param image the bitmap content
+     * @param createFlags
+     * @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) throws IOException {
         // create a delegate with the given image.
         Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ARGB_8888);
 
-        return createBitmap(delegate, isMutable, density.getDpiValue());
+        return createBitmap(delegate, createFlags, density.getDpiValue());
     }
 
     /**
@@ -203,7 +256,7 @@
 
     @LayoutlibDelegate
     /*package*/ static Bitmap nativeCreate(int[] colors, int offset, int stride, int width,
-            int height, int nativeConfig, boolean mutable) {
+            int height, int nativeConfig, boolean isMutable) {
         int imageType = getBufferedImageType(nativeConfig);
 
         // create the image
@@ -216,7 +269,8 @@
         // create a delegate with the content of the stream.
         Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.nativeToConfig(nativeConfig));
 
-        return createBitmap(delegate, mutable, Bitmap.getDefaultDensity());
+        return createBitmap(delegate, getPremultipliedBitmapCreateFlags(isMutable),
+                            Bitmap.getDefaultDensity());
     }
 
     @LayoutlibDelegate
@@ -244,7 +298,8 @@
         // create a delegate with the content of the stream.
         Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.nativeToConfig(nativeConfig));
 
-        return createBitmap(delegate, isMutable, Bitmap.getDefaultDensity());
+        return createBitmap(delegate, getPremultipliedBitmapCreateFlags(isMutable),
+                Bitmap.getDefaultDensity());
     }
 
     @LayoutlibDelegate
@@ -464,7 +519,7 @@
         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, false /*isMutable*/,
+        return createBitmap(delegate, EnumSet.of(BitmapCreateFlags.MUTABLE),
                 Density.DEFAULT_DENSITY /*density*/);
     }
 
@@ -546,13 +601,27 @@
         mConfig = config;
     }
 
-    private static Bitmap createBitmap(Bitmap_Delegate delegate, boolean isMutable, int density) {
+    private static Bitmap createBitmap(Bitmap_Delegate delegate,
+            Set<BitmapCreateFlags> createFlags, int density) {
         // get its native_int
         int 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, null /* buffer */, isMutable, null /*ninePatchChunk*/,
-                density);
+        return new Bitmap(nativeInt, null /* buffer */, 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;
     }
 
     /**
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
index da18864..62b47bd 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
@@ -1075,14 +1075,6 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static void native_drawPicture(int nativeCanvas,
-                                                  int nativePicture) {
-        // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                "Canvas.drawPicture is not supported.", null, null /*data*/);
-    }
-
-    @LayoutlibDelegate
     /*package*/ static void finalizer(int nativeCanvas) {
         // get the delegate from the native int so that it can be disposed.
         Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index 434b131..f0c3a75 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -49,15 +49,13 @@
     private final Configuration mConfig;
     private final DisplayMetrics mMetrics;
     private final int mRotation;
-    private final boolean mHasSystemNavBar;
     private final boolean mHasNavigationBar;
 
     public IWindowManagerImpl(Configuration config, DisplayMetrics metrics, int rotation,
-            boolean hasSystemNavBar, boolean hasNavigationBar) {
+            boolean hasNavigationBar) {
         mConfig = config;
         mMetrics = metrics;
         mRotation = rotation;
-        mHasSystemNavBar = hasSystemNavBar;
         mHasNavigationBar = hasNavigationBar;
     }
 
@@ -79,16 +77,11 @@
         return mHasNavigationBar;
     }
 
-    @Override
-    public boolean hasSystemNavBar() throws RemoteException {
-        return mHasSystemNavBar;
-    }
-
     // ---- unused implementation of IWindowManager ----
 
     @Override
-    public void addAppToken(int arg0, IApplicationToken arg1, int arg2, int arg3, boolean arg4,
-                            boolean arg5)
+    public void addAppToken(int arg0, IApplicationToken arg1, int arg2, int arg3, int arg4,
+            boolean arg5, boolean arg6, int arg7)
             throws RemoteException {
         // TODO Auto-generated method stub
 
@@ -211,24 +204,6 @@
     }
 
     @Override
-    public void moveAppToken(int arg0, IBinder arg1) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void moveAppTokensToBottom(List<IBinder> arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void moveAppTokensToTop(List<IBinder> arg0) throws RemoteException {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
     public IWindowSession openSession(IInputMethodClient arg0, IInputContext arg1)
             throws RemoteException {
         // TODO Auto-generated method stub
@@ -322,7 +297,7 @@
 
     @Override
     public void setAppStartingWindow(IBinder arg0, String arg1, int arg2, CompatibilityInfo arg3,
-            CharSequence arg4, int arg5, int arg6, int arg7, IBinder arg8, boolean arg9)
+            CharSequence arg4, int arg5, int arg6, int arg7, int arg8, IBinder arg9, boolean arg10)
             throws RemoteException {
         // TODO Auto-generated method stub
     }
diff --git a/tools/layoutlib/bridge/src/android/webkit/WebView.java b/tools/layoutlib/bridge/src/android/webkit/WebView.java
index 3b66188..202f204 100644
--- a/tools/layoutlib/bridge/src/android/webkit/WebView.java
+++ b/tools/layoutlib/bridge/src/android/webkit/WebView.java
@@ -99,14 +99,6 @@
     public static void disablePlatformNotifications() {
     }
 
-    public WebBackForwardList saveState(Bundle outState) {
-        return null;
-    }
-
-    public WebBackForwardList restoreState(Bundle inState) {
-        return null;
-    }
-
     public void loadUrl(String url) {
     }
 
@@ -213,10 +205,6 @@
     public void clearSslPreferences() {
     }
 
-    public WebBackForwardList copyBackForwardList() {
-        return null;
-    }
-
     public static String findAddress(String addr) {
         return null;
     }
@@ -236,10 +224,6 @@
     public void addJavascriptInterface(Object obj, String interfaceName) {
     }
 
-    public WebSettings getSettings() {
-        return null;
-    }
-
     public View getZoomControls() {
         return null;
     }
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
index 4aea38f..01740b1 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
@@ -81,14 +81,16 @@
     }
 
     @Override
-    public AssetFileDescriptor openAssetFile(String callingPackage, Uri arg0, String arg1)
+    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)
+    public ParcelFileDescriptor openFile(
+            String callingPackage, Uri arg0, String arg1, ICancellationSignal signal)
             throws RemoteException, FileNotFoundException {
         // TODO Auto-generated method stub
         return null;
@@ -122,7 +124,7 @@
 
     @Override
     public AssetFileDescriptor openTypedAssetFile(String callingPackage, Uri arg0, String arg1,
-            Bundle arg2) throws RemoteException, FileNotFoundException {
+            Bundle arg2, ICancellationSignal signal) throws RemoteException, FileNotFoundException {
         // TODO Auto-generated method stub
         return null;
     }
@@ -132,4 +134,14 @@
         // 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;
+    }
 }
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
index 99aa228..b9294ab 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -67,8 +67,8 @@
 import android.util.DisplayMetrics;
 import android.util.TypedValue;
 import android.view.BridgeInflater;
-import android.view.CompatibilityInfoHolder;
 import android.view.Display;
+import android.view.DisplayAdjustments;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.WindowManager;
@@ -1090,6 +1090,12 @@
     }
 
     @Override
+    public String getOpPackageName() {
+        // pass
+        return null;
+    }
+
+    @Override
     public ApplicationInfo getApplicationInfo() {
         return mApplicationInfo;
     }
@@ -1398,7 +1404,7 @@
     }
 
     @Override
-    public CompatibilityInfoHolder getCompatibilityInfo(int displayId) {
+    public DisplayAdjustments getDisplayAdjustments(int displayId) {
         // pass
         return null;
     }
@@ -1410,4 +1416,22 @@
     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];
+    }
 }
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
index d6abbaa..3cf5ed5 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java
@@ -63,7 +63,7 @@
     }
 
     @Override
-    public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(InputMethodInfo arg0,
+    public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(String arg0,
             boolean arg1) throws RemoteException {
         // TODO Auto-generated method stub
         return null;
@@ -203,6 +203,12 @@
     }
 
     @Override
+        public boolean shouldOfferSwitchingToNextInputMethod(IBinder arg0) throws RemoteException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
     public void updateStatusIcon(IBinder arg0, String arg1, int arg2) throws RemoteException {
         // TODO Auto-generated method stub
 
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
index 1ccbc40..6fd5acc 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
@@ -39,7 +39,7 @@
     }
 
     @Override
-    public void acquireWakeLock(IBinder arg0, int arg1, String arg2, WorkSource arg3)
+    public void acquireWakeLock(IBinder arg0, int arg1, String arg2, String arg2_5, WorkSource arg3)
             throws RemoteException {
         // pass for now.
     }
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
index 9ddbbf1..57771e3 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -192,11 +192,10 @@
         findNavigationBar(resources, metrics);
 
         // FIXME: find those out, and possibly add them to the render params
-        boolean hasSystemNavBar = true;
         boolean hasNavigationBar = true;
         IWindowManager iwm = new IWindowManagerImpl(getContext().getConfiguration(),
                 metrics, Surface.ROTATION_0,
-                hasSystemNavBar, hasNavigationBar);
+                hasNavigationBar);
         WindowManagerGlobal_Delegate.setWindowManagerService(iwm);
 
         // build the inflater and parser.
diff --git a/tools/obbtool/Android.mk b/tools/obbtool/Android.mk
index ad8de69..9ff56d6 100644
--- a/tools/obbtool/Android.mk
+++ b/tools/obbtool/Android.mk
@@ -18,8 +18,8 @@
 #LOCAL_C_INCLUDES +=
 
 LOCAL_STATIC_LIBRARIES := \
-	libutils \
 	libandroidfw \
+	libutils \
 	libcutils \
 	liblog
 
diff --git a/tools/preload/Policy.java b/tools/preload/Policy.java
index ca0291b..af46820 100644
--- a/tools/preload/Policy.java
+++ b/tools/preload/Policy.java
@@ -81,8 +81,9 @@
         return SERVICES.contains(processName);
     }
 
-    /**Reports if the given class should be preloaded. */
+    /** Reports if the given class should be preloaded. */
     public static boolean isPreloadable(LoadedClass clazz) {
-        return clazz.systemClass && !EXCLUDED_CLASSES.contains(clazz.name);
+        return clazz.systemClass && !EXCLUDED_CLASSES.contains(clazz.name)
+                && !clazz.name.endsWith("$NoPreloadHolder");
     }
 }
diff --git a/tools/validatekeymaps/Android.mk b/tools/validatekeymaps/Android.mk
index 90fbc08..9af721d 100644
--- a/tools/validatekeymaps/Android.mk
+++ b/tools/validatekeymaps/Android.mk
@@ -15,10 +15,8 @@
 
 LOCAL_CFLAGS := -Wall -Werror
 
-#LOCAL_C_INCLUDES +=
-
 LOCAL_STATIC_LIBRARIES := \
-	libandroidfw \
+	libinput \
 	libutils \
 	libcutils \
 	liblog
diff --git a/tools/validatekeymaps/Main.cpp b/tools/validatekeymaps/Main.cpp
index 91e4fda..5b45c55 100644
--- a/tools/validatekeymaps/Main.cpp
+++ b/tools/validatekeymaps/Main.cpp
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-#include <androidfw/KeyCharacterMap.h>
-#include <androidfw/KeyLayoutMap.h>
-#include <androidfw/VirtualKeyMap.h>
+#include <input/KeyCharacterMap.h>
+#include <input/KeyLayoutMap.h>
+#include <input/VirtualKeyMap.h>
 #include <utils/PropertyMap.h>
 #include <utils/String8.h>
 
diff --git a/wifi/java/android/net/wifi/BatchedScanResult.aidl b/wifi/java/android/net/wifi/BatchedScanResult.aidl
new file mode 100644
index 0000000..a70bc0a
--- /dev/null
+++ b/wifi/java/android/net/wifi/BatchedScanResult.aidl
@@ -0,0 +1,19 @@
+/**
+ * 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.net.wifi;
+
+parcelable BatchedScanResult;
diff --git a/wifi/java/android/net/wifi/BatchedScanResult.java b/wifi/java/android/net/wifi/BatchedScanResult.java
new file mode 100644
index 0000000..eb4e0276
--- /dev/null
+++ b/wifi/java/android/net/wifi/BatchedScanResult.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+import android.os.Parcelable;
+import android.os.Parcel;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Describes the Results of a batched set of wifi scans where the firmware performs many
+ * scans and stores the timestamped results without waking the main processor each time.
+ * @hide pending review
+ */
+public class BatchedScanResult implements Parcelable {
+    private static final String TAG = "BatchedScanResult";
+
+    /** Inidcates this scan was interrupted and may only have partial results. */
+    public boolean truncated;
+
+    /** The result of this particular scan. */
+    public final List<ScanResult> scanResults = new ArrayList<ScanResult>();
+
+
+    public BatchedScanResult() {
+    }
+
+    public BatchedScanResult(BatchedScanResult source) {
+        truncated = source.truncated;
+        for (ScanResult s : source.scanResults) scanResults.add(new ScanResult(s));
+    }
+
+    @Override
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+
+        sb.append("BatchedScanResult: ").
+                append("truncated: ").append(String.valueOf(truncated)).
+                append("scanResults: [");
+        for (ScanResult s : scanResults) {
+            sb.append(" <").append(s.toString()).append("> ");
+        }
+        sb.append(" ]");
+        return sb.toString();
+    }
+
+    /** Implement the Parcelable interface {@hide} */
+    public int describeContents() {
+        return 0;
+    }
+
+    /** Implement the Parcelable interface {@hide} */
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(truncated ? 1 : 0);
+        dest.writeInt(scanResults.size());
+        for (ScanResult s : scanResults) {
+            s.writeToParcel(dest, flags);
+        }
+    }
+
+    /** Implement the Parcelable interface {@hide} */
+    public static final Creator<BatchedScanResult> CREATOR =
+        new Creator<BatchedScanResult>() {
+            public BatchedScanResult createFromParcel(Parcel in) {
+                BatchedScanResult result = new BatchedScanResult();
+                result.truncated = (in.readInt() == 1);
+                int count = in.readInt();
+                while (count-- > 0) {
+                    result.scanResults.add(ScanResult.CREATOR.createFromParcel(in));
+                }
+                return result;
+            }
+
+            public BatchedScanResult[] newArray(int size) {
+                return new BatchedScanResult[size];
+            }
+        };
+}
diff --git a/wifi/java/android/net/wifi/BatchedScanSettings.aidl b/wifi/java/android/net/wifi/BatchedScanSettings.aidl
new file mode 100644
index 0000000..8cfc508
--- /dev/null
+++ b/wifi/java/android/net/wifi/BatchedScanSettings.aidl
@@ -0,0 +1,19 @@
+/**
+ * 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.net.wifi;
+
+parcelable BatchedScanSettings;
diff --git a/wifi/java/android/net/wifi/BatchedScanSettings.java b/wifi/java/android/net/wifi/BatchedScanSettings.java
new file mode 100644
index 0000000..44a2ab4
--- /dev/null
+++ b/wifi/java/android/net/wifi/BatchedScanSettings.java
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+import android.os.Parcelable;
+import android.os.Parcel;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * Describes the settings for batched wifi scans where the firmware performs many
+ * scans and stores the timestamped results without waking the main processor each time.
+ * This can give information over time with minimal battery impact.
+ * @hide pending review
+ */
+public class BatchedScanSettings implements Parcelable {
+    private static final String TAG = "BatchedScanSettings";
+
+    /** Used to indicate no preference for an int value */
+    public final static int UNSPECIFIED = Integer.MAX_VALUE;
+
+    // TODO - make MIN/mAX dynamic and gservices adjustable.
+    public final static int MIN_SCANS_PER_BATCH = 2;
+    public final static int MAX_SCANS_PER_BATCH = 255;
+    public final static int DEFAULT_SCANS_PER_BATCH = MAX_SCANS_PER_BATCH;
+
+    public final static int MIN_AP_PER_SCAN = 2;
+    public final static int MAX_AP_PER_SCAN = 255;
+    public final static int DEFAULT_AP_PER_SCAN = 16;
+
+    public final static int MIN_INTERVAL_SEC = 0;
+    public final static int MAX_INTERVAL_SEC = 3600;
+    public final static int DEFAULT_INTERVAL_SEC = 30;
+
+    public final static int MIN_AP_FOR_DISTANCE = 0;
+    public final static int MAX_AP_FOR_DISTANCE = MAX_AP_PER_SCAN;
+    public final static int DEFAULT_AP_FOR_DISTANCE = 0;
+
+    public final static int MAX_WIFI_CHANNEL = 196;
+
+    /** The expected number of scans per batch.  Note that the firmware may drop scans
+     *  leading to fewer scans during the normal batch scan duration.  This value need not
+     *  be specified (may be set to {@link UNSPECIFIED}) by the application and we will try
+     *  to scan as many times as the firmware can support.  If another app requests fewer
+     *  scans per batch we will attempt to honor that.
+     */
+    public int maxScansPerBatch;
+
+    /** The maximum desired AP listed per scan.  Fewer AP may be returned if that's all
+     *  that the driver detected.  If another application requests more AP per scan that
+     *  will take precedence.  The if more channels are detected than we request, the APs
+     *  with the lowest signal strength will be dropped.
+     */
+    public int maxApPerScan;
+
+    /** The channels used in the scan.  If all channels should be used, {@code null} may be
+     *  specified.  If another application requests more channels or all channels, that
+     *  will take precedence.
+     */
+    public Collection<String> channelSet;
+
+    /** The time between the start of two sequential scans, in seconds.  If another
+     *  application requests more frequent scans, that will take precedence.  If this
+     * value is less than the duration of a scan, the next scan should start immediately.
+     */
+    public int scanIntervalSec;
+
+    /** The number of the best (strongest signal) APs for which the firmware will
+     *  attempt to get distance information (RTT).  Not all firmware supports this
+     *  feature, so it may be ignored.  If another application requests a greater
+     *  number, that will take precedence.
+     */
+    public int maxApForDistance;
+
+    public BatchedScanSettings() {
+        clear();
+    }
+
+    public void clear() {
+        maxScansPerBatch = UNSPECIFIED;
+        maxApPerScan = UNSPECIFIED;
+        channelSet = null;
+        scanIntervalSec = UNSPECIFIED;
+        maxApForDistance = UNSPECIFIED;
+    }
+
+    public BatchedScanSettings(BatchedScanSettings source) {
+        maxScansPerBatch = source.maxScansPerBatch;
+        maxApPerScan = source.maxApPerScan;
+        if (source.channelSet != null) {
+            channelSet = new ArrayList(source.channelSet);
+        }
+        scanIntervalSec = source.scanIntervalSec;
+        maxApForDistance = source.maxApForDistance;
+    }
+
+    private boolean channelSetIsValid() {
+        if (channelSet == null || channelSet.isEmpty()) return true;
+        for (String channel : channelSet) {
+            try {
+                int i = Integer.parseInt(channel);
+                if (i > 0 && i <= MAX_WIFI_CHANNEL) continue;
+            } catch (NumberFormatException e) {}
+            if (channel.equals("A") || channel.equals("B")) continue;
+            return false;
+        }
+        return true;
+    }
+    /** @hide */
+    public boolean isInvalid() {
+        if (maxScansPerBatch != UNSPECIFIED && (maxScansPerBatch < MIN_SCANS_PER_BATCH ||
+                maxScansPerBatch > MAX_SCANS_PER_BATCH)) return true;
+        if (maxApPerScan != UNSPECIFIED && (maxApPerScan < MIN_AP_PER_SCAN ||
+                maxApPerScan > MAX_AP_PER_SCAN)) return true;
+        if (channelSetIsValid() == false) return true;
+        if (scanIntervalSec != UNSPECIFIED && (scanIntervalSec < MIN_INTERVAL_SEC ||
+                scanIntervalSec > MAX_INTERVAL_SEC)) return true;
+        if (maxApForDistance != UNSPECIFIED && (maxApForDistance < MIN_AP_FOR_DISTANCE ||
+                maxApForDistance > MAX_AP_FOR_DISTANCE)) return true;
+        return false;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof BatchedScanSettings == false) return false;
+        BatchedScanSettings o = (BatchedScanSettings)obj;
+        if (maxScansPerBatch != o.maxScansPerBatch ||
+              maxApPerScan != o.maxApPerScan ||
+              scanIntervalSec != o.scanIntervalSec ||
+              maxApForDistance != o.maxApForDistance) return false;
+        if (channelSet == null) {
+            return (o.channelSet == null);
+        }
+        return channelSet.equals(o.channelSet);
+    }
+
+    @Override
+    public int hashCode() {
+        return maxScansPerBatch +
+                (maxApPerScan * 3) +
+                (scanIntervalSec * 5) +
+                (maxApForDistance * 7) +
+                (channelSet.hashCode() * 11);
+    }
+
+    @Override
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        String none = "<none>";
+
+        sb.append("BatchScanSettings [maxScansPerBatch: ").
+                append(maxScansPerBatch == UNSPECIFIED ? none : maxScansPerBatch).
+                append(", maxApPerScan: ").append(maxApPerScan == UNSPECIFIED? none : maxApPerScan).
+                append(", scanIntervalSec: ").
+                append(scanIntervalSec == UNSPECIFIED ? none : scanIntervalSec).
+                append(", maxApForDistance: ").
+                append(maxApForDistance == UNSPECIFIED ? none : maxApForDistance).
+                append(", channelSet: ");
+        if (channelSet == null) {
+            sb.append("ALL");
+        } else {
+            sb.append("<");
+            for (String channel : channelSet) {
+                sb.append(" " + channel);
+            }
+            sb.append(">");
+        }
+        sb.append("]");
+        return sb.toString();
+    }
+
+    /** Implement the Parcelable interface {@hide} */
+    public int describeContents() {
+        return 0;
+    }
+
+    /** Implement the Parcelable interface {@hide} */
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(maxScansPerBatch);
+        dest.writeInt(maxApPerScan);
+        dest.writeInt(scanIntervalSec);
+        dest.writeInt(maxApForDistance);
+        dest.writeInt(channelSet == null ? 0 : channelSet.size());
+        if (channelSet != null) {
+            for (String channel : channelSet) dest.writeString(channel);
+        }
+    }
+
+    /** Implement the Parcelable interface {@hide} */
+    public static final Creator<BatchedScanSettings> CREATOR =
+        new Creator<BatchedScanSettings>() {
+            public BatchedScanSettings createFromParcel(Parcel in) {
+                BatchedScanSettings settings = new BatchedScanSettings();
+                settings.maxScansPerBatch = in.readInt();
+                settings.maxApPerScan = in.readInt();
+                settings.scanIntervalSec = in.readInt();
+                settings.maxApForDistance = in.readInt();
+                int channelCount = in.readInt();
+                if (channelCount > 0) {
+                    settings.channelSet = new ArrayList(channelCount);
+                    while (channelCount-- > 0) {
+                        settings.channelSet.add(in.readString());
+                    }
+                }
+                return settings;
+            }
+
+            public BatchedScanSettings[] newArray(int size) {
+                return new BatchedScanSettings[size];
+            }
+        };
+}
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 547ae95..4f68ca0 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -16,8 +16,10 @@
 
 package android.net.wifi;
 
-import android.net.wifi.WifiInfo;
+import android.net.wifi.BatchedScanResult;
+import android.net.wifi.BatchedScanSettings;
 import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiInfo;
 import android.net.wifi.ScanResult;
 import android.net.DhcpInfo;
 
@@ -43,7 +45,7 @@
 
     boolean pingSupplicant();
 
-    void startScan();
+    void startScan(in WorkSource ws);
 
     List<ScanResult> getScanResults(String callingPackage);
 
@@ -110,5 +112,19 @@
     String getConfigFile();
 
     void captivePortalCheckComplete();
+
+    void enableTdls(String remoteIPAddress, boolean enable);
+
+    void enableTdlsWithMacAddress(String remoteMacAddress, boolean enable);
+
+    boolean requestBatchedScan(in BatchedScanSettings requested, IBinder binder);
+
+    void stopBatchedScan(in BatchedScanSettings requested, IBinder binder);
+
+    List<BatchedScanResult> getBatchedScanResults(String callingPackage);
+
+    boolean isBatchedScanSupported();
+
+    void pollBatchedScan();
 }
 
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index 9977419..12729d2 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -54,7 +54,26 @@
      * Time Synchronization Function (tsf) timestamp in microseconds when
      * this result was last seen.
      */
-     public long timestamp;
+    public long timestamp;
+
+    /**
+     * The approximate distance to the AP in centimeter, if available.  Else
+     * {@link UNSPECIFIED}.
+     * {@hide}
+     */
+    public int distanceCm;
+
+    /**
+     * The standard deviation of the distance to the AP, if available.
+     * Else {@link UNSPECIFIED}.
+     * {@hide}
+     */
+    public int distanceSdCm;
+
+    /**
+     * {@hide}
+     */
+    public final static int UNSPECIFIED = -1;
 
     /** {@hide} */
     public ScanResult(WifiSsid wifiSsid, String BSSID, String caps, int level, int frequency,
@@ -66,8 +85,23 @@
         this.level = level;
         this.frequency = frequency;
         this.timestamp = tsf;
+        this.distanceCm = UNSPECIFIED;
+        this.distanceSdCm = UNSPECIFIED;
     }
 
+    /** {@hide} */
+    public ScanResult(WifiSsid wifiSsid, String BSSID, String caps, int level, int frequency,
+            long tsf, int distCm, int distSdCm) {
+        this.wifiSsid = wifiSsid;
+        this.SSID = (wifiSsid != null) ? wifiSsid.toString() : WifiSsid.NONE;
+        this.BSSID = BSSID;
+        this.capabilities = caps;
+        this.level = level;
+        this.frequency = frequency;
+        this.timestamp = tsf;
+        this.distanceCm = distCm;
+        this.distanceSdCm = distSdCm;
+    }
 
     /** copy constructor {@hide} */
     public ScanResult(ScanResult source) {
@@ -79,6 +113,8 @@
             level = source.level;
             frequency = source.frequency;
             timestamp = source.timestamp;
+            distanceCm = source.distanceCm;
+            distanceSdCm = source.distanceSdCm;
         }
     }
 
@@ -100,6 +136,11 @@
             append(", timestamp: ").
             append(timestamp);
 
+        sb.append(", distance: ").append((distanceCm != UNSPECIFIED ? distanceCm : "?")).
+                append("(cm)");
+        sb.append(", distanceSd: ").append((distanceSdCm != UNSPECIFIED ? distanceSdCm : "?")).
+                append("(cm)");
+
         return sb.toString();
     }
 
@@ -121,6 +162,8 @@
         dest.writeInt(level);
         dest.writeInt(frequency);
         dest.writeLong(timestamp);
+        dest.writeInt(distanceCm);
+        dest.writeInt(distanceSdCm);
     }
 
     /** Implement the Parcelable interface {@hide} */
@@ -137,7 +180,9 @@
                     in.readString(),
                     in.readInt(),
                     in.readInt(),
-                    in.readLong()
+                    in.readLong(),
+                    in.readInt(),
+                    in.readInt()
                 );
             }
 
diff --git a/wifi/java/android/net/wifi/WifiConfigStore.java b/wifi/java/android/net/wifi/WifiConfigStore.java
index 9418de1..f79a4a6 100644
--- a/wifi/java/android/net/wifi/WifiConfigStore.java
+++ b/wifi/java/android/net/wifi/WifiConfigStore.java
@@ -31,22 +31,28 @@
 import android.net.wifi.NetworkUpdateResult;
 import static android.net.wifi.WifiConfiguration.INVALID_NETWORK_ID;
 import android.os.Environment;
+import android.os.FileObserver;
 import android.os.Message;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.UserHandle;
 import android.security.KeyStore;
 import android.text.TextUtils;
+import android.util.LocalLog;
 import android.util.Log;
 
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
 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.FileReader;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.net.InetAddress;
@@ -108,7 +114,10 @@
 
     private Context mContext;
     private static final String TAG = "WifiConfigStore";
-    private static final boolean DBG = false;
+    private static final boolean DBG = true;
+    private static final boolean VDBG = false;
+
+    private static final String SUPPLICANT_CONFIG_FILE = "/data/misc/wifi/wpa_supplicant.conf";
 
     /* configured networks with network id as the key */
     private HashMap<Integer, WifiConfiguration> mConfiguredNetworks =
@@ -141,17 +150,46 @@
     private static final String PROXY_SETTINGS_KEY = "proxySettings";
     private static final String PROXY_HOST_KEY = "proxyHost";
     private static final String PROXY_PORT_KEY = "proxyPort";
+    private static final String PROXY_PAC_FILE = "proxyPac";
     private static final String EXCLUSION_LIST_KEY = "exclusionList";
     private static final String EOS = "eos";
 
+    private final LocalLog mLocalLog;
+    private final WpaConfigFileObserver mFileObserver;
+
     private WifiNative mWifiNative;
     private final KeyStore mKeyStore = KeyStore.getInstance();
 
     WifiConfigStore(Context c, WifiNative wn) {
         mContext = c;
         mWifiNative = wn;
+
+        if (VDBG) {
+            mLocalLog = mWifiNative.getLocalLog();
+            mFileObserver = new WpaConfigFileObserver();
+            mFileObserver.startWatching();
+        } else {
+            mLocalLog = null;
+            mFileObserver = null;
+        }
     }
 
+    class WpaConfigFileObserver extends FileObserver {
+
+        public WpaConfigFileObserver() {
+            super(SUPPLICANT_CONFIG_FILE, CLOSE_WRITE);
+        }
+
+        @Override
+        public void onEvent(int event, String path) {
+            if (event == CLOSE_WRITE) {
+                File file = new File(SUPPLICANT_CONFIG_FILE);
+                if (VDBG) localLog("wpa_supplicant.conf changed; new size = " + file.length());
+            }
+        }
+    }
+
+
     /**
      * Fetch the list of configured networks
      * and enable all stored networks in supplicant.
@@ -211,6 +249,7 @@
      * @return false if the network id is invalid
      */
     boolean selectNetwork(int netId) {
+        if (VDBG) localLog("selectNetwork", netId);
         if (netId == INVALID_NETWORK_ID) return false;
 
         // Reset the priority of each network at start or if it goes too high.
@@ -247,6 +286,7 @@
      * @return network update result
      */
     NetworkUpdateResult saveNetwork(WifiConfiguration config) {
+        if (VDBG) localLog("saveNetwork", config.networkId);
         // A new network cannot have null SSID
         if (config == null || (config.networkId == INVALID_NETWORK_ID &&
                 config.SSID == null)) {
@@ -295,6 +335,7 @@
      * @return {@code true} if it succeeds, {@code false} otherwise
      */
     boolean forgetNetwork(int netId) {
+        if (VDBG) localLog("forgetNetwork", netId);
         if (mWifiNative.removeNetwork(netId)) {
             mWifiNative.saveConfig();
             removeConfigAndSendBroadcastIfNeeded(netId);
@@ -315,11 +356,12 @@
      * @return network Id
      */
     int addOrUpdateNetwork(WifiConfiguration config) {
+        if (VDBG) localLog("addOrUpdateNetwork", config.networkId);
         NetworkUpdateResult result = addOrUpdateNetworkNative(config);
         if (result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID) {
             sendConfiguredNetworksChangedBroadcast(mConfiguredNetworks.get(result.getNetworkId()),
                     result.isNewNetwork ? WifiManager.CHANGE_REASON_ADDED :
-                        WifiManager.CHANGE_REASON_CONFIG_CHANGE);
+                            WifiManager.CHANGE_REASON_CONFIG_CHANGE);
         }
         return result.getNetworkId();
     }
@@ -334,6 +376,7 @@
      * @return {@code true} if it succeeds, {@code false} otherwise
      */
     boolean removeNetwork(int netId) {
+        if (VDBG) localLog("removeNetwork", netId);
         boolean ret = mWifiNative.removeNetwork(netId);
         if (ret) {
             removeConfigAndSendBroadcastIfNeeded(netId);
@@ -368,8 +411,10 @@
     boolean enableNetwork(int netId, boolean disableOthers) {
         boolean ret = enableNetworkWithoutBroadcast(netId, disableOthers);
         if (disableOthers) {
+            if (VDBG) localLog("enableNetwork(disableOthers=true) ", netId);
             sendConfiguredNetworksChangedBroadcast();
         } else {
+            if (VDBG) localLog("enableNetwork(disableOthers=false) ", netId);
             WifiConfiguration enabledNetwork = null;
             synchronized(mConfiguredNetworks) {
                 enabledNetwork = mConfiguredNetworks.get(netId);
@@ -396,6 +441,7 @@
     }
 
     void disableAllNetworks() {
+        if (VDBG) localLog("disableAllNetworks");
         boolean networkDisabled = false;
         for(WifiConfiguration config : mConfiguredNetworks.values()) {
             if(config != null && config.status != Status.DISABLED) {
@@ -428,6 +474,7 @@
      * @return {@code true} if it succeeds, {@code false} otherwise
      */
     boolean disableNetwork(int netId, int reason) {
+        if (VDBG) localLog("disableNetwork", netId);
         boolean ret = mWifiNative.disableNetwork(netId);
         WifiConfiguration network = null;
         WifiConfiguration config = mConfiguredNetworks.get(netId);
@@ -618,6 +665,7 @@
             try {
                 config.networkId = Integer.parseInt(result[0]);
             } catch(NumberFormatException e) {
+                loge("Failed to read network-id '" + result[0] + "'");
                 continue;
             }
             if (result.length > 3) {
@@ -636,12 +684,46 @@
             }
             config.ipAssignment = IpAssignment.DHCP;
             config.proxySettings = ProxySettings.NONE;
-            mConfiguredNetworks.put(config.networkId, config);
-            mNetworkIds.put(configKey(config), config.networkId);
+
+            if (mNetworkIds.containsKey(configKey(config))) {
+                // That SSID is already known, just ignore this duplicate entry
+                if (VDBG) localLog("discarded duplicate network", config.networkId);
+            } else {
+                mConfiguredNetworks.put(config.networkId, config);
+                mNetworkIds.put(configKey(config), config.networkId);
+                if (VDBG) localLog("loaded configured network", config.networkId);
+            }
         }
 
         readIpAndProxyConfigurations();
         sendConfiguredNetworksChangedBroadcast();
+
+        if (VDBG) localLog("loadConfiguredNetworks loaded " + mNetworkIds.size() + " networks");
+
+        if (mNetworkIds.size() == 0) {
+            // no networks? Lets log if the wpa_supplicant.conf file contents
+            BufferedReader reader = null;
+            try {
+                reader = new BufferedReader(new FileReader(SUPPLICANT_CONFIG_FILE));
+                if (VDBG) localLog("--- Begin wpa_supplicant.conf Contents ---");
+                for (String line = reader.readLine(); line != null; line = reader.readLine()) {
+                    if (VDBG) localLog(line);
+                }
+                if (VDBG) localLog("--- End wpa_supplicant.conf Contents ---");
+            } catch (FileNotFoundException e) {
+                if (VDBG) localLog("Could not open " + SUPPLICANT_CONFIG_FILE + ", " + e);
+            } catch (IOException e) {
+                if (VDBG) localLog("Could not read " + SUPPLICANT_CONFIG_FILE + ", " + e);
+            } finally {
+                try {
+                    if (reader != null) {
+                        reader.close();
+                    }
+                } catch (IOException e) {
+                    // Just ignore the fact that we couldn't close
+                }
+            }
+        }
     }
 
     /* Mark all networks except specified netId as disabled */
@@ -771,6 +853,14 @@
                                 out.writeUTF(exclusionList);
                                 writeToFile = true;
                                 break;
+                            case PAC:
+                                ProxyProperties proxyPacProperties = linkProperties.getHttpProxy();
+                                out.writeUTF(PROXY_SETTINGS_KEY);
+                                out.writeUTF(config.proxySettings.toString());
+                                out.writeUTF(PROXY_PAC_FILE);
+                                out.writeUTF(proxyPacProperties.getPacFileUrl());
+                                writeToFile = true;
+                                break;
                             case NONE:
                                 out.writeUTF(PROXY_SETTINGS_KEY);
                                 out.writeUTF(config.proxySettings.toString());
@@ -838,6 +928,7 @@
                 ProxySettings proxySettings = ProxySettings.NONE;
                 LinkProperties linkProperties = new LinkProperties();
                 String proxyHost = null;
+                String pacFileUrl = null;
                 int proxyPort = -1;
                 String exclusionList = null;
                 String key;
@@ -879,6 +970,8 @@
                             proxyHost = in.readUTF();
                         } else if (key.equals(PROXY_PORT_KEY)) {
                             proxyPort = in.readInt();
+                        } else if (key.equals(PROXY_PAC_FILE)) {
+                            pacFileUrl = in.readUTF();
                         } else if (key.equals(EXCLUSION_LIST_KEY)) {
                             exclusionList = in.readUTF();
                         } else if (key.equals(EOS)) {
@@ -920,6 +1013,12 @@
                                     new ProxyProperties(proxyHost, proxyPort, exclusionList);
                                 linkProperties.setHttpProxy(proxyProperties);
                                 break;
+                            case PAC:
+                                config.proxySettings = proxySettings;
+                                ProxyProperties proxyPacProperties = 
+                                        new ProxyProperties(pacFileUrl);
+                                linkProperties.setHttpProxy(proxyPacProperties);
+                                break;
                             case NONE:
                                 config.proxySettings = proxySettings;
                                 break;
@@ -954,6 +1053,9 @@
          * network configuration. Otherwise, the networkId should
          * refer to an existing configuration.
          */
+
+        if (VDBG) localLog("addOrUpdateNetworkNative " + config.getPrintableSsid());
+
         int netId = config.networkId;
         boolean newNetwork = false;
         // networkId of INVALID_NETWORK_ID means we want to create a new network
@@ -1247,6 +1349,7 @@
 
         switch (newConfig.proxySettings) {
             case STATIC:
+            case PAC:
                 ProxyProperties newHttpProxy = newConfig.linkProperties.getHttpProxy();
                 ProxyProperties currentHttpProxy = currentConfig.linkProperties.getHttpProxy();
 
@@ -1558,6 +1661,12 @@
             pw.println(conf);
         }
         pw.println();
+
+        if (mLocalLog != null) {
+            pw.println("WifiConfigStore - Log Begin ----");
+            mLocalLog.dump(fd, pw, args);
+            pw.println("WifiConfigStore - Log End ----");
+        }
     }
 
     public String getConfigFile() {
@@ -1571,4 +1680,28 @@
     private void log(String s) {
         Log.d(TAG, s);
     }
+
+    private void localLog(String s) {
+        if (mLocalLog != null) {
+            mLocalLog.log(s);
+        }
+    }
+
+    private void localLog(String s, int netId) {
+        if (mLocalLog == null) {
+            return;
+        }
+
+        WifiConfiguration config;
+        synchronized(mConfiguredNetworks) {
+            config = mConfiguredNetworks.get(netId);
+        }
+
+        if (config != null) {
+            mLocalLog.log(s + " " + config.getPrintableSsid());
+        } else {
+            mLocalLog.log(s + " " + netId);
+        }
+    }
+
 }
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index bd8f0eb..2ce584b 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -312,7 +312,10 @@
         STATIC,
         /* no proxy details are assigned, this is used to indicate
          * that any existing proxy settings should be retained */
-        UNASSIGNED
+        UNASSIGNED,
+        /* Use a Pac based proxy.
+         */
+        PAC
     }
     /**
      * @hide
@@ -345,6 +348,20 @@
         linkProperties = new LinkProperties();
     }
 
+    /**
+     * indicates whether the configuration is valid
+     * @return true if valid, false otherwise
+     * @hide
+     */
+    public boolean isValid() {
+        if (allowedKeyManagement.cardinality() > 1) {
+            return false;
+        }
+
+        // TODO: Add more checks
+        return true;
+    }
+
     @Override
     public String toString() {
         StringBuilder sbuf = new StringBuilder();
diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
index 4bee937..e357804a 100644
--- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
+++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
@@ -721,7 +721,13 @@
         String value = mFields.get(key);
         // Uninitialized or known to be empty after reading from supplicant
         if (TextUtils.isEmpty(value) || EMPTY_VALUE.equals(value)) return "";
-        return removeDoubleQuotes(value).substring(prefix.length());
+
+        value = removeDoubleQuotes(value);
+        if (value.startsWith(prefix)) {
+            return value.substring(prefix.length());
+        } else {
+            return value;
+        }
     }
 
     /** Set a value with an optional prefix at key
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index a3c172a..3223cb3 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -32,8 +32,10 @@
 import android.util.Log;
 import android.util.SparseArray;
 
+import java.net.InetAddress;
 import java.util.concurrent.CountDownLatch;
 
+import com.android.internal.R;
 import com.android.internal.util.AsyncChannel;
 import com.android.internal.util.Protocol;
 
@@ -364,6 +366,14 @@
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String SCAN_RESULTS_AVAILABLE_ACTION = "android.net.wifi.SCAN_RESULTS";
     /**
+     * A batch of access point scans has been completed and the results areavailable.
+     * Call {@link #getBatchedScanResults()} to obtain the results.
+     * @hide pending review
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String BATCHED_SCAN_RESULTS_AVAILABLE_ACTION =
+            "android.net.wifi.BATCHED_RESULTS";
+    /**
      * The RSSI (signal strength) has changed.
      * @see #EXTRA_NEW_RSSI
      */
@@ -758,13 +768,107 @@
      */
     public boolean startScan() {
         try {
-            mService.startScan();
+            final WorkSource workSource = null;
+            mService.startScan(workSource);
             return true;
         } catch (RemoteException e) {
             return false;
         }
     }
 
+    /** @hide */
+    public boolean startScan(WorkSource workSource) {
+        try {
+            mService.startScan(workSource);
+            return true;
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Request a batched scan for access points.  To end your requested batched scan,
+     * call stopBatchedScan with the same Settings.
+     *
+     * If there are mulitple requests for batched scans, the more demanding settings will
+     * take precidence.
+     *
+     * @param requested {@link BatchedScanSettings} the scan settings requested.
+     * @return false on known error
+     * @hide
+     */
+    public boolean requestBatchedScan(BatchedScanSettings requested) {
+        try {
+            return mService.requestBatchedScan(requested, new Binder());
+        } catch (RemoteException e) { return false; }
+    }
+
+    /**
+     * Check if the Batched Scan feature is supported.
+     *
+     * @return false if not supported.
+     * @hide
+     */
+    public boolean isBatchedScanSupported() {
+        try {
+            return mService.isBatchedScanSupported();
+        } catch (RemoteException e) { return false; }
+    }
+
+    /**
+     * End a requested batch scan for this applicaiton.  Note that batched scan may
+     * still occur if other apps are using them.
+     *
+     * @param requested {@link BatchedScanSettings} the scan settings you previously requested
+     *        and now wish to stop.  A value of null here will stop all scans requested by the
+     *        calling App.
+     * @hide
+     */
+    public void stopBatchedScan(BatchedScanSettings requested) {
+        try {
+            mService.stopBatchedScan(requested, new Binder());
+        } catch (RemoteException e) {}
+    }
+
+    /**
+     * Retrieve the latest batched scan result.  This should be called immediately after
+     * {@link BATCHED_SCAN_RESULTS_AVAILABLE_ACTION} is received.
+     * @hide
+     */
+    public List<BatchedScanResult> getBatchedScanResults() {
+        try {
+            return mService.getBatchedScanResults(mContext.getOpPackageName());
+        } catch (RemoteException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Force a re-reading of batched scan results.  This will attempt
+     * to read more information from the chip, but will do so at the expense
+     * of previous data.  Rate limited to the current scan frequency.
+     *
+     * pollBatchedScan will always wait 1 period from the start of the batch
+     * before trying to read from the chip, so if your #scans/batch == 1 this will
+     * have no effect.
+     *
+     * If you had already waited 1 period before calling, this should have
+     * immediate (though async) effect.
+     *
+     * If you call before that 1 period is up this will set up a timer and fetch
+     * results when the 1 period is up.
+     *
+     * Servicing a pollBatchedScan request (immediate or after timed delay) starts a
+     * new batch, so if you were doing 10 scans/batch and called in the 4th scan, you
+     * would get data in the 4th and then again 10 scans later.
+     * @hide
+     */
+    public void pollBatchedScan() {
+        try {
+            mService.pollBatchedScan();
+        } catch (RemoteException e) { }
+    }
+
     /**
      * Return dynamic information about the current Wi-Fi connection, if any is active.
      * @return the Wi-Fi information, contained in {@link WifiInfo}.
@@ -783,7 +887,7 @@
      */
     public List<ScanResult> getScanResults() {
         try {
-            return mService.getScanResults(mContext.getBasePackageName());
+            return mService.getScanResults(mContext.getOpPackageName());
         } catch (RemoteException e) {
             return null;
         }
@@ -1132,6 +1236,49 @@
         }
     }
 
+
+    /**
+     * Enable/Disable TDLS on a specific local route.
+     *
+     * <p>
+     * TDLS enables two wireless endpoints to talk to each other directly
+     * without going through the access point that is managing the local
+     * network. It saves bandwidth and improves quality of the link.
+     * </p>
+     * <p>
+     * This API enables/disables the option of using TDLS. If enabled, the
+     * underlying hardware is free to use TDLS or a hop through the access
+     * point. If disabled, existing TDLS session is torn down and
+     * hardware is restricted to use access point for transferring wireless
+     * packets. Default value for all routes is 'disabled', meaning restricted
+     * to use access point for transferring packets.
+     * </p>
+     *
+     * @param remoteIPAddress IP address of the endpoint to setup TDLS with
+     * @param enable true = setup and false = tear down TDLS
+     */
+    public void setTdlsEnabled(InetAddress remoteIPAddress, boolean enable) {
+        try {
+            mService.enableTdls(remoteIPAddress.getHostAddress(), enable);
+        } catch (RemoteException e) {
+            // Just ignore the exception
+        }
+    }
+
+    /**
+     * Similar to {@link #setTdlsEnabled(InetAddress, boolean) }, except
+     * this version allows you to specify remote endpoint with a MAC address.
+     * @param remoteMacAddress MAC address of the remote endpoint such as 00:00:0c:9f:f2:ab
+     * @param enable true = setup and false = tear down TDLS
+     */
+    public void setTdlsEnabledWithMacAddress(String remoteMacAddress, boolean enable) {
+        try {
+            mService.enableTdlsWithMacAddress(remoteMacAddress, enable);
+        } catch (RemoteException e) {
+            // Just ignore the exception
+        }
+    }
+
     /* TODO: deprecate synchronous API and open up the following API */
 
     private static final int BASE = Protocol.BASE_WIFI_MANAGER;
@@ -1223,6 +1370,13 @@
     /** WPS timed out {@hide} */
     public static final int WPS_TIMED_OUT               = 7;
 
+    /**
+     * Passed with {@link ActionListener#onFailure}.
+     * Indicates that the operation failed due to invalid inputs
+     * @hide
+     */
+    public static final int INVALID_ARGS                = 8;
+
     /** Interface for callback invocation on an application action {@hide} */
     public interface ActionListener {
         /** The operation succeeded */
diff --git a/wifi/java/android/net/wifi/WifiMonitor.java b/wifi/java/android/net/wifi/WifiMonitor.java
index fe3c709..6817777 100644
--- a/wifi/java/android/net/wifi/WifiMonitor.java
+++ b/wifi/java/android/net/wifi/WifiMonitor.java
@@ -32,7 +32,10 @@
 import com.android.internal.util.Protocol;
 import com.android.internal.util.StateMachine;
 
+import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.regex.Pattern;
 import java.util.regex.Matcher;
 
@@ -44,6 +47,7 @@
  */
 public class WifiMonitor {
 
+    private static final boolean DBG = false;
     private static final String TAG = "WifiMonitor";
 
     /** Events we receive from the supplicant daemon */
@@ -279,9 +283,6 @@
     /* AP-STA-DISCONNECTED 42:fc:89:a8:96:09 */
     private static final String AP_STA_DISCONNECTED_STR = "AP-STA-DISCONNECTED";
 
-    private final StateMachine mStateMachine;
-    private final WifiNative mWifiNative;
-
     /* Supplicant events reported to a state machine */
     private static final int BASE = Protocol.BASE_WIFI_MONITOR;
 
@@ -347,164 +348,332 @@
     private static final String WPA_RECV_ERROR_STR = "recv error";
 
     /**
-     * Tracks consecutive receive errors
-     */
-    private int mRecvErrors = 0;
-
-    /**
      * Max errors before we close supplicant connection
      */
     private static final int MAX_RECV_ERRORS    = 10;
 
+    private final String mInterfaceName;
+    private final WifiNative mWifiNative;
+    private final StateMachine mWifiStateMachine;
+    private boolean mMonitoring;
+
     public WifiMonitor(StateMachine wifiStateMachine, WifiNative wifiNative) {
-        mStateMachine = wifiStateMachine;
+        if (DBG) Log.d(TAG, "Creating WifiMonitor");
         mWifiNative = wifiNative;
+        mInterfaceName = wifiNative.mInterfaceName;
+        mWifiStateMachine = wifiStateMachine;
+        mMonitoring = false;
+
+        WifiMonitorSingleton.getMonitor().registerInterfaceMonitor(mInterfaceName, this);
     }
 
     public void startMonitoring() {
-        new MonitorThread().start();
+        WifiMonitorSingleton.getMonitor().startMonitoring(mInterfaceName);
     }
 
-    class MonitorThread extends Thread {
-        public MonitorThread() {
-            super("WifiMonitor");
+    public void stopMonitoring() {
+        WifiMonitorSingleton.getMonitor().stopMonitoring(mInterfaceName);
+    }
+
+    public void stopSupplicant() {
+        WifiMonitorSingleton.getMonitor().stopSupplicant();
+    }
+
+    public void killSupplicant(boolean p2pSupported) {
+        WifiMonitorSingleton.getMonitor().killSupplicant(p2pSupported);
+    }
+
+    private static class WifiMonitorSingleton {
+        private static Object sSingletonLock = new Object();
+        private static WifiMonitorSingleton sWifiMonitorSingleton = null;
+        private HashMap<String, WifiMonitor> mIfaceMap = new HashMap<String, WifiMonitor>();
+        private boolean mConnected = false;
+        private WifiNative mWifiNative;
+
+        private WifiMonitorSingleton() {
         }
 
-        public void run() {
+        static WifiMonitorSingleton getMonitor() {
+            if (DBG) Log.d(TAG, "WifiMonitorSingleton gotten");
+            synchronized (sSingletonLock) {
+                if (sWifiMonitorSingleton == null) {
+                    if (DBG) Log.d(TAG, "WifiMonitorSingleton created");
+                    sWifiMonitorSingleton = new WifiMonitorSingleton();
+                }
+            }
+            return sWifiMonitorSingleton;
+        }
 
-            if (connectToSupplicant()) {
-                // Send a message indicating that it is now possible to send commands
-                // to the supplicant
-                mStateMachine.sendMessage(SUP_CONNECTION_EVENT);
-            } else {
-                mStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);
+        public synchronized void startMonitoring(String iface) {
+            WifiMonitor m = mIfaceMap.get(iface);
+            if (m == null) {
+                Log.e(TAG, "startMonitor called with unknown iface=" + iface);
                 return;
             }
 
+            Log.d(TAG, "startMonitoring(" + iface + ") with mConnected = " + mConnected);
+
+            if (mConnected) {
+                m.mMonitoring = true;
+                m.mWifiStateMachine.sendMessage(SUP_CONNECTION_EVENT);
+            } else {
+                if (DBG) Log.d(TAG, "connecting to supplicant");
+                int connectTries = 0;
+                while (true) {
+                    if (mWifiNative.connectToSupplicant()) {
+                        m.mMonitoring = true;
+                        m.mWifiStateMachine.sendMessage(SUP_CONNECTION_EVENT);
+                        new MonitorThread(mWifiNative, this).start();
+                        mConnected = true;
+                        break;
+                    }
+                    if (connectTries++ < 5) {
+                        try {
+                            Thread.sleep(1000);
+                        } catch (InterruptedException ignore) {
+                        }
+                    } else {
+                        mIfaceMap.remove(iface);
+                        m.mWifiStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);
+                        Log.e(TAG, "startMonitoring(" + iface + ") failed!");
+                        break;
+                    }
+                }
+            }
+        }
+
+        public synchronized void stopMonitoring(String iface) {
+            WifiMonitor m = mIfaceMap.get(iface);
+            if (DBG) Log.d(TAG, "stopMonitoring(" + iface + ") = " + m.mWifiStateMachine);
+            m.mMonitoring = false;
+            m.mWifiStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);
+        }
+
+        public synchronized void registerInterfaceMonitor(String iface, WifiMonitor m) {
+            if (DBG) Log.d(TAG, "registerInterface(" + iface + "+" + m.mWifiStateMachine + ")");
+            mIfaceMap.put(iface, m);
+            if (mWifiNative == null) {
+                mWifiNative = m.mWifiNative;
+            }
+        }
+
+        public synchronized void unregisterInterfaceMonitor(String iface) {
+            // REVIEW: When should we call this? If this isn't called, then WifiMonitor
+            // objects will remain in the mIfaceMap; and won't ever get deleted
+
+            WifiMonitor m = mIfaceMap.remove(iface);
+            if (DBG) Log.d(TAG, "unregisterInterface(" + iface + "+" + m.mWifiStateMachine + ")");
+        }
+
+        public synchronized void stopSupplicant() {
+            mWifiNative.stopSupplicant();
+        }
+
+        public synchronized void killSupplicant(boolean p2pSupported) {
+            mWifiNative.killSupplicant(p2pSupported);
+            mConnected = false;
+            Iterator<Map.Entry<String, WifiMonitor>> it = mIfaceMap.entrySet().iterator();
+            while (it.hasNext()) {
+                Map.Entry<String, WifiMonitor> e = it.next();
+                WifiMonitor m = e.getValue();
+                m.mMonitoring = false;
+            }
+        }
+
+        private synchronized WifiMonitor getMonitor(String iface) {
+            return mIfaceMap.get(iface);
+        }
+    }
+
+    private static class MonitorThread extends Thread {
+        private final WifiNative mWifiNative;
+        private final WifiMonitorSingleton mWifiMonitorSingleton;
+        private int mRecvErrors = 0;
+        private StateMachine mStateMachine = null;
+
+        public MonitorThread(WifiNative wifiNative, WifiMonitorSingleton wifiMonitorSingleton) {
+            super("WifiMonitor");
+            mWifiNative = wifiNative;
+            mWifiMonitorSingleton = wifiMonitorSingleton;
+        }
+
+        public void run() {
             //noinspection InfiniteLoopStatement
             for (;;) {
                 String eventStr = mWifiNative.waitForEvent();
 
                 // Skip logging the common but mostly uninteresting scan-results event
-                if (false && eventStr.indexOf(SCAN_RESULTS_STR) == -1) {
+                if (DBG && eventStr.indexOf(SCAN_RESULTS_STR) == -1) {
                     Log.d(TAG, "Event [" + eventStr + "]");
                 }
-                if (!eventStr.startsWith(EVENT_PREFIX_STR)) {
-                    if (eventStr.startsWith(WPA_EVENT_PREFIX_STR) &&
-                            0 < eventStr.indexOf(PASSWORD_MAY_BE_INCORRECT_STR)) {
-                        mStateMachine.sendMessage(AUTHENTICATION_FAILURE_EVENT);
-                    } else if (eventStr.startsWith(WPS_SUCCESS_STR)) {
-                        mStateMachine.sendMessage(WPS_SUCCESS_EVENT);
-                    } else if (eventStr.startsWith(WPS_FAIL_STR)) {
-                        handleWpsFailEvent(eventStr);
-                    } else if (eventStr.startsWith(WPS_OVERLAP_STR)) {
-                        mStateMachine.sendMessage(WPS_OVERLAP_EVENT);
-                    } else if (eventStr.startsWith(WPS_TIMEOUT_STR)) {
-                        mStateMachine.sendMessage(WPS_TIMEOUT_EVENT);
-                    } else if (eventStr.startsWith(P2P_EVENT_PREFIX_STR)) {
-                        handleP2pEvents(eventStr);
-                    } else if (eventStr.startsWith(HOST_AP_EVENT_PREFIX_STR)) {
-                        handleHostApEvents(eventStr);
-                    }
-                    continue;
-                }
 
-                String eventName = eventStr.substring(EVENT_PREFIX_LEN_STR);
-                int nameEnd = eventName.indexOf(' ');
-                if (nameEnd != -1)
-                    eventName = eventName.substring(0, nameEnd);
-                if (eventName.length() == 0) {
-                    if (false) Log.i(TAG, "Received wpa_supplicant event with empty event name");
-                    continue;
-                }
-                /*
-                 * Map event name into event enum
-                 */
-                int event;
-                if (eventName.equals(CONNECTED_STR))
-                    event = CONNECTED;
-                else if (eventName.equals(DISCONNECTED_STR))
-                    event = DISCONNECTED;
-                else if (eventName.equals(STATE_CHANGE_STR))
-                    event = STATE_CHANGE;
-                else if (eventName.equals(SCAN_RESULTS_STR))
-                    event = SCAN_RESULTS;
-                else if (eventName.equals(LINK_SPEED_STR))
-                    event = LINK_SPEED;
-                else if (eventName.equals(TERMINATING_STR))
-                    event = TERMINATING;
-                else if (eventName.equals(DRIVER_STATE_STR))
-                    event = DRIVER_STATE;
-                else if (eventName.equals(EAP_FAILURE_STR))
-                    event = EAP_FAILURE;
-                else if (eventName.equals(ASSOC_REJECT_STR))
-                    event = ASSOC_REJECT;
-                else
-                    event = UNKNOWN;
+                String iface = "p2p0";
+                WifiMonitor m = null;
+                mStateMachine = null;
 
-                String eventData = eventStr;
-                if (event == DRIVER_STATE || event == LINK_SPEED)
-                    eventData = eventData.split(" ")[1];
-                else if (event == STATE_CHANGE || event == EAP_FAILURE) {
-                    int ind = eventStr.indexOf(" ");
-                    if (ind != -1) {
-                        eventData = eventStr.substring(ind + 1);
+                if (eventStr.startsWith("IFNAME=")) {
+                    int space = eventStr.indexOf(' ');
+                    if (space != -1) {
+                        iface = eventStr.substring(7,space);
+                        m = mWifiMonitorSingleton.getMonitor(iface);
+                        if (m == null && iface.startsWith("p2p-")) {
+                            // p2p interfaces are created dynamically, but we have
+                            // only one P2p state machine monitoring all of them; look
+                            // for it explicitly, and send messages there ..
+                            m = mWifiMonitorSingleton.getMonitor("p2p0");
+                        }
+                        eventStr = eventStr.substring(space + 1);
                     }
                 } else {
-                    int ind = eventStr.indexOf(" - ");
-                    if (ind != -1) {
-                        eventData = eventStr.substring(ind + 3);
+                    // events without prefix belong to p2p0 monitor
+                    m = mWifiMonitorSingleton.getMonitor("p2p0");
+                }
+
+                if (m != null) {
+                    if (m.mMonitoring) {
+                        mStateMachine = m.mWifiStateMachine;
+                    } else {
+                        if (DBG) Log.d(TAG, "Dropping event because monitor (" + iface +
+                                            ") is stopped");
+                        continue;
                     }
                 }
 
-                if (event == STATE_CHANGE) {
-                    handleSupplicantStateChange(eventData);
-                } else if (event == DRIVER_STATE) {
-                    handleDriverEvent(eventData);
-                } else if (event == TERMINATING) {
-                    /**
-                     * Close the supplicant connection if we see
-                     * too many recv errors
-                     */
-                    if (eventData.startsWith(WPA_RECV_ERROR_STR)) {
-                        if (++mRecvErrors > MAX_RECV_ERRORS) {
-                            if (false) {
-                                Log.d(TAG, "too many recv errors, closing connection");
-                            }
-                        } else {
-                            continue;
+                if (mStateMachine != null) {
+                    if (dispatchEvent(eventStr)) {
+                        break;
+                    }
+                } else {
+                    if (DBG) Log.d(TAG, "Sending to all monitors because there's no interface id");
+                    boolean done = false;
+                    Iterator<Map.Entry<String, WifiMonitor>> it =
+                            mWifiMonitorSingleton.mIfaceMap.entrySet().iterator();
+                    while (it.hasNext()) {
+                        Map.Entry<String, WifiMonitor> e = it.next();
+                        m = e.getValue();
+                        mStateMachine = m.mWifiStateMachine;
+                        if (dispatchEvent(eventStr)) {
+                            done = true;
                         }
                     }
 
-                    // notify and exit
-                    mStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);
-                    break;
-                } else if (event == EAP_FAILURE) {
-                    if (eventData.startsWith(EAP_AUTH_FAILURE_STR)) {
-                        mStateMachine.sendMessage(AUTHENTICATION_FAILURE_EVENT);
+                    if (done) {
+                        // After this thread terminates, we'll no longer
+                        // be connected to the supplicant
+                        if (DBG) Log.d(TAG, "Disconnecting from the supplicant, no more events");
+                        mWifiMonitorSingleton.mConnected = false;
+                        break;
                     }
-                } else if (event == ASSOC_REJECT) {
-                        mStateMachine.sendMessage(ASSOCIATION_REJECTION_EVENT);
-                } else {
-                    handleEvent(event, eventData);
                 }
-                mRecvErrors = 0;
             }
         }
 
-        private boolean connectToSupplicant() {
-            int connectTries = 0;
+        /* @return true if the event was supplicant disconnection */
+        private boolean dispatchEvent(String eventStr) {
 
-            while (true) {
-                if (mWifiNative.connectToSupplicant()) {
-                    return true;
+            if (!eventStr.startsWith(EVENT_PREFIX_STR)) {
+                if (eventStr.startsWith(WPA_EVENT_PREFIX_STR) &&
+                        0 < eventStr.indexOf(PASSWORD_MAY_BE_INCORRECT_STR)) {
+                    mStateMachine.sendMessage(AUTHENTICATION_FAILURE_EVENT);
+                } else if (eventStr.startsWith(WPS_SUCCESS_STR)) {
+                    mStateMachine.sendMessage(WPS_SUCCESS_EVENT);
+                } else if (eventStr.startsWith(WPS_FAIL_STR)) {
+                    handleWpsFailEvent(eventStr);
+                } else if (eventStr.startsWith(WPS_OVERLAP_STR)) {
+                    mStateMachine.sendMessage(WPS_OVERLAP_EVENT);
+                } else if (eventStr.startsWith(WPS_TIMEOUT_STR)) {
+                    mStateMachine.sendMessage(WPS_TIMEOUT_EVENT);
+                } else if (eventStr.startsWith(P2P_EVENT_PREFIX_STR)) {
+                    handleP2pEvents(eventStr);
+                } else if (eventStr.startsWith(HOST_AP_EVENT_PREFIX_STR)) {
+                    handleHostApEvents(eventStr);
                 }
-                if (connectTries++ < 5) {
-                    nap(1);
-                } else {
-                    break;
+                else {
+                    if (DBG) Log.w(TAG, "couldn't identify event type - " + eventStr);
+                }
+                return false;
+            }
+
+            String eventName = eventStr.substring(EVENT_PREFIX_LEN_STR);
+            int nameEnd = eventName.indexOf(' ');
+            if (nameEnd != -1)
+                eventName = eventName.substring(0, nameEnd);
+            if (eventName.length() == 0) {
+                if (DBG) Log.i(TAG, "Received wpa_supplicant event with empty event name");
+                return false;
+            }
+            /*
+             * Map event name into event enum
+             */
+            int event;
+            if (eventName.equals(CONNECTED_STR))
+                event = CONNECTED;
+            else if (eventName.equals(DISCONNECTED_STR))
+                event = DISCONNECTED;
+            else if (eventName.equals(STATE_CHANGE_STR))
+                event = STATE_CHANGE;
+            else if (eventName.equals(SCAN_RESULTS_STR))
+                event = SCAN_RESULTS;
+            else if (eventName.equals(LINK_SPEED_STR))
+                event = LINK_SPEED;
+            else if (eventName.equals(TERMINATING_STR))
+                event = TERMINATING;
+            else if (eventName.equals(DRIVER_STATE_STR))
+                event = DRIVER_STATE;
+            else if (eventName.equals(EAP_FAILURE_STR))
+                event = EAP_FAILURE;
+            else if (eventName.equals(ASSOC_REJECT_STR))
+                event = ASSOC_REJECT;
+            else
+                event = UNKNOWN;
+
+            String eventData = eventStr;
+            if (event == DRIVER_STATE || event == LINK_SPEED)
+                eventData = eventData.split(" ")[1];
+            else if (event == STATE_CHANGE || event == EAP_FAILURE) {
+                int ind = eventStr.indexOf(" ");
+                if (ind != -1) {
+                    eventData = eventStr.substring(ind + 1);
+                }
+            } else {
+                int ind = eventStr.indexOf(" - ");
+                if (ind != -1) {
+                    eventData = eventStr.substring(ind + 3);
                 }
             }
+
+            if (event == STATE_CHANGE) {
+                handleSupplicantStateChange(eventData);
+            } else if (event == DRIVER_STATE) {
+                handleDriverEvent(eventData);
+            } else if (event == TERMINATING) {
+                /**
+                 * Close the supplicant connection if we see
+                 * too many recv errors
+                 */
+                if (eventData.startsWith(WPA_RECV_ERROR_STR)) {
+                    if (++mRecvErrors > MAX_RECV_ERRORS) {
+                        if (DBG) {
+                            Log.d(TAG, "too many recv errors, closing connection");
+                        }
+                    } else {
+                        return false;
+                    }
+                }
+
+                // notify and exit
+                mStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);
+                return true;
+            } else if (event == EAP_FAILURE) {
+                if (eventData.startsWith(EAP_AUTH_FAILURE_STR)) {
+                    mStateMachine.sendMessage(AUTHENTICATION_FAILURE_EVENT);
+                }
+            } else if (event == ASSOC_REJECT) {
+                mStateMachine.sendMessage(ASSOCIATION_REJECTION_EVENT);
+            } else {
+                handleEvent(event, eventData);
+            }
+            mRecvErrors = 0;
             return false;
         }
 
@@ -723,71 +892,60 @@
             }
             notifySupplicantStateChange(networkId, wifiSsid, BSSID, newSupplicantState);
         }
-    }
 
-    private void handleNetworkStateChange(NetworkInfo.DetailedState newState, String data) {
-        String BSSID = null;
-        int networkId = -1;
-        if (newState == NetworkInfo.DetailedState.CONNECTED) {
-            Matcher match = mConnectedEventPattern.matcher(data);
-            if (!match.find()) {
-                if (false) Log.d(TAG, "Could not find BSSID in CONNECTED event string");
-            } else {
-                BSSID = match.group(1);
-                try {
-                    networkId = Integer.parseInt(match.group(2));
-                } catch (NumberFormatException e) {
-                    networkId = -1;
+        private void handleNetworkStateChange(NetworkInfo.DetailedState newState, String data) {
+            String BSSID = null;
+            int networkId = -1;
+            if (newState == NetworkInfo.DetailedState.CONNECTED) {
+                Matcher match = mConnectedEventPattern.matcher(data);
+                if (!match.find()) {
+                    if (DBG) Log.d(TAG, "Could not find BSSID in CONNECTED event string");
+                } else {
+                    BSSID = match.group(1);
+                    try {
+                        networkId = Integer.parseInt(match.group(2));
+                    } catch (NumberFormatException e) {
+                        networkId = -1;
+                    }
                 }
+                notifyNetworkStateChange(newState, BSSID, networkId);
             }
         }
-        notifyNetworkStateChange(newState, BSSID, networkId);
-    }
 
-    /**
-     * Send the state machine a notification that the state of Wifi connectivity
-     * has changed.
-     * @param networkId the configured network on which the state change occurred
-     * @param newState the new network state
-     * @param BSSID when the new state is {@link DetailedState#CONNECTED
-     * NetworkInfo.DetailedState.CONNECTED},
-     * this is the MAC address of the access point. Otherwise, it
-     * is {@code null}.
-     */
-    void notifyNetworkStateChange(NetworkInfo.DetailedState newState, String BSSID, int netId) {
-        if (newState == NetworkInfo.DetailedState.CONNECTED) {
-            Message m = mStateMachine.obtainMessage(NETWORK_CONNECTION_EVENT,
-                    netId, 0, BSSID);
-            mStateMachine.sendMessage(m);
-        } else {
-            Message m = mStateMachine.obtainMessage(NETWORK_DISCONNECTION_EVENT,
-                    netId, 0, BSSID);
-            mStateMachine.sendMessage(m);
+        /**
+         * Send the state machine a notification that the state of Wifi connectivity
+         * has changed.
+         * @param networkId the configured network on which the state change occurred
+         * @param newState the new network state
+         * @param BSSID when the new state is {@link DetailedState#CONNECTED
+         * NetworkInfo.DetailedState.CONNECTED},
+         * this is the MAC address of the access point. Otherwise, it
+         * is {@code null}.
+         */
+        void notifyNetworkStateChange(NetworkInfo.DetailedState newState, String BSSID, int netId) {
+            if (newState == NetworkInfo.DetailedState.CONNECTED) {
+                Message m = mStateMachine.obtainMessage(NETWORK_CONNECTION_EVENT,
+                        netId, 0, BSSID);
+                mStateMachine.sendMessage(m);
+            } else {
+                Message m = mStateMachine.obtainMessage(NETWORK_DISCONNECTION_EVENT,
+                        netId, 0, BSSID);
+                mStateMachine.sendMessage(m);
+            }
         }
-    }
 
-    /**
-     * Send the state machine a notification that the state of the supplicant
-     * has changed.
-     * @param networkId the configured network on which the state change occurred
-     * @param wifiSsid network name
-     * @param BSSID network address
-     * @param newState the new {@code SupplicantState}
-     */
-    void notifySupplicantStateChange(int networkId, WifiSsid wifiSsid, String BSSID,
-            SupplicantState newState) {
-        mStateMachine.sendMessage(mStateMachine.obtainMessage(SUPPLICANT_STATE_CHANGE_EVENT,
-                new StateChangeResult(networkId, wifiSsid, BSSID, newState)));
-    }
-
-    /**
-     * Sleep for a period of time.
-     * @param secs the number of seconds to sleep
-     */
-    private static void nap(int secs) {
-        try {
-            Thread.sleep(secs * 1000);
-        } catch (InterruptedException ignore) {
+        /**
+         * Send the state machine a notification that the state of the supplicant
+         * has changed.
+         * @param networkId the configured network on which the state change occurred
+         * @param wifiSsid network name
+         * @param BSSID network address
+         * @param newState the new {@code SupplicantState}
+         */
+        void notifySupplicantStateChange(int networkId, WifiSsid wifiSsid, String BSSID,
+                SupplicantState newState) {
+            mStateMachine.sendMessage(mStateMachine.obtainMessage(SUPPLICANT_STATE_CHANGE_EVENT,
+                    new StateChangeResult(networkId, wifiSsid, BSSID, newState)));
         }
     }
 }
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index f637e89..520668e 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -20,10 +20,12 @@
 import android.net.wifi.p2p.WifiP2pGroup;
 import android.text.TextUtils;
 import android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
+import android.util.LocalLog;
 import android.util.Log;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Locale;
 
 /**
  * Native calls for bring up/shut down of the supplicant daemon and for
@@ -37,6 +39,7 @@
 public class WifiNative {
 
     private static final boolean DBG = false;
+    private static final boolean VDBG = false;
     private final String mTAG;
     private static final int DEFAULT_GROUP_OWNER_INTENT     = 6;
 
@@ -47,7 +50,13 @@
     static final int SCAN_WITHOUT_CONNECTION_SETUP          = 1;
     static final int SCAN_WITH_CONNECTION_SETUP             = 2;
 
-    String mInterface = "";
+    // Hold this lock before calling supplicant - it is required to
+    // mutually exclude access from Wifi and P2p state machines
+    static final Object mLock = new Object();
+
+    public final String mInterfaceName;
+    public final String mInterfacePrefix;
+
     private boolean mSuspendOptEnabled = false;
 
     public native static boolean loadDriver();
@@ -62,52 +71,108 @@
        or when the supplicant is hung */
     public native static boolean killSupplicant(boolean p2pSupported);
 
-    private native boolean connectToSupplicant(String iface);
+    private native boolean connectToSupplicantNative();
 
-    private native void closeSupplicantConnection(String iface);
+    private native void closeSupplicantConnectionNative();
 
     /**
      * Wait for the supplicant to send an event, returning the event string.
      * @return the event string sent by the supplicant.
      */
-    private native String waitForEvent(String iface);
+    private native String waitForEventNative();
 
-    private native boolean doBooleanCommand(String iface, String command);
+    private native boolean doBooleanCommandNative(String command);
 
-    private native int doIntCommand(String iface, String command);
+    private native int doIntCommandNative(String command);
 
-    private native String doStringCommand(String iface, String command);
+    private native String doStringCommandNative(String command);
 
-    public WifiNative(String iface) {
-        mInterface = iface;
-        mTAG = "WifiNative-" + iface;
+    public WifiNative(String interfaceName) {
+        mInterfaceName = interfaceName;
+        mTAG = "WifiNative-" + interfaceName;
+        if (!interfaceName.equals("p2p0")) {
+            mInterfacePrefix = "IFNAME=" + interfaceName + " ";
+        } else {
+            // commands for p2p0 interface don't need prefix
+            mInterfacePrefix = "";
+        }
+    }
+
+    private static final LocalLog mLocalLog = new LocalLog(1024);
+
+    // hold mLock before accessing mCmdIdLock
+    private int mCmdId;
+
+    public LocalLog getLocalLog() {
+        return mLocalLog;
+    }
+
+    private int getNewCmdIdLocked() {
+        return mCmdId++;
+    }
+
+    private void localLog(String s) {
+        if (mLocalLog != null)
+            mLocalLog.log(mInterfaceName + ": " + s);
     }
 
     public boolean connectToSupplicant() {
-        return connectToSupplicant(mInterface);
+        // No synchronization necessary .. it is implemented in WifiMonitor
+        if (VDBG) localLog(mInterfacePrefix + "connectToSupplicant");
+        return connectToSupplicantNative();
     }
 
     public void closeSupplicantConnection() {
-        closeSupplicantConnection(mInterface);
+        if (VDBG) localLog(mInterfacePrefix + "closeSupplicantConnection");
+        closeSupplicantConnectionNative();
     }
 
     public String waitForEvent() {
-        return waitForEvent(mInterface);
+        // No synchronization necessary .. it is implemented in WifiMonitor
+        return waitForEventNative();
     }
 
     private boolean doBooleanCommand(String command) {
         if (DBG) Log.d(mTAG, "doBoolean: " + command);
-        return doBooleanCommand(mInterface, command);
+        synchronized (mLock) {
+            int cmdId = getNewCmdIdLocked();
+            if (VDBG) localLog(cmdId + "->" + mInterfacePrefix + command);
+            boolean result = doBooleanCommandNative(mInterfacePrefix + command);
+            if (VDBG) localLog(cmdId + "<-" + result);
+            if (DBG) Log.d(mTAG, "   returned " + result);
+            return result;
+        }
     }
 
     private int doIntCommand(String command) {
         if (DBG) Log.d(mTAG, "doInt: " + command);
-        return doIntCommand(mInterface, command);
+        synchronized (mLock) {
+            int cmdId = getNewCmdIdLocked();
+            if (VDBG) localLog(cmdId + "->" + mInterfacePrefix + command);
+            int result = doIntCommandNative(mInterfacePrefix + command);
+            if (VDBG) localLog(cmdId + "<-" + result);
+            if (DBG) Log.d(mTAG, "   returned " + result);
+            return result;
+        }
     }
 
     private String doStringCommand(String command) {
         if (DBG) Log.d(mTAG, "doString: " + command);
-        return doStringCommand(mInterface, command);
+        synchronized (mLock) {
+            int cmdId = getNewCmdIdLocked();
+            if (VDBG) localLog(cmdId + "->" + mInterfacePrefix + command);
+            String result = doStringCommandNative(mInterfacePrefix + command);
+            if (VDBG) localLog(cmdId + "<-" + result);
+            if (DBG) Log.d(mTAG, "   returned " + result);
+            return result;
+        }
+    }
+
+    private String doStringCommandWithoutLogging(String command) {
+        if (DBG) Log.d(mTAG, "doString: " + command);
+        synchronized (mLock) {
+            return doStringCommandNative(mInterfacePrefix + command);
+        }
     }
 
     public boolean ping() {
@@ -150,7 +215,9 @@
 
     public String getNetworkVariable(int netId, String name) {
         if (TextUtils.isEmpty(name)) return null;
-        return doStringCommand("GET_NETWORK " + netId + " " + name);
+
+        // GET_NETWORK will likely flood the logs ...
+        return doStringCommandWithoutLogging("GET_NETWORK " + netId + " " + name);
     }
 
     public boolean removeNetwork(int netId) {
@@ -213,7 +280,47 @@
      * MASK=<N> see wpa_supplicant/src/common/wpa_ctrl.h for details
      */
     public String scanResults(int sid) {
-        return doStringCommand("BSS RANGE=" + sid + "- MASK=0x21987");
+        return doStringCommandWithoutLogging("BSS RANGE=" + sid + "- MASK=0x21987");
+    }
+
+    /**
+     * Format of command
+     * DRIVER WLS_BATCHING SET SCANFREQ=x MSCAN=r BESTN=y CHANNEL=<z, w, t> RTT=s
+     * where x is an ascii representation of an integer number of seconds between scans
+     *       r is an ascii representation of an integer number of scans per batch
+     *       y is an ascii representation of an integer number of the max AP to remember per scan
+     *       z, w, t represent a 1..n size list of channel numbers and/or 'A', 'B' values
+     *           indicating entire ranges of channels
+     *       s is an ascii representation of an integer number of highest-strength AP
+     *           for which we'd like approximate distance reported
+     *
+     * The return value is an ascii integer representing a guess of the number of scans
+     * the firmware can remember before it runs out of buffer space or -1 on error
+     */
+    public String setBatchedScanSettings(BatchedScanSettings settings) {
+        if (settings == null) return doStringCommand("DRIVER WLS_BATCHING STOP");
+        String cmd = "DRIVER WLS_BATCHING SET SCANFREQ=" + settings.scanIntervalSec;
+        cmd += " MSCAN=" + settings.maxScansPerBatch;
+        if (settings.maxApPerScan != BatchedScanSettings.UNSPECIFIED) {
+            cmd += " BESTN=" + settings.maxApPerScan;
+        }
+        if (settings.channelSet != null && !settings.channelSet.isEmpty()) {
+            cmd += " CHANNEL=<";
+            int i = 0;
+            for (String channel : settings.channelSet) {
+                cmd += (i > 0 ? "," : "") + channel;
+                ++i;
+            }
+            cmd += ">";
+        }
+        if (settings.maxApForDistance != BatchedScanSettings.UNSPECIFIED) {
+            cmd += " RTT=" + settings.maxApForDistance;
+        }
+        return doStringCommand(cmd);
+    }
+
+    public String getBatchedScanResults() {
+        return doStringCommand("DRIVER WLS_BATCHING GET");
     }
 
     public boolean startDriver() {
@@ -355,7 +462,7 @@
     }
 
     public boolean setCountryCode(String countryCode) {
-        return doBooleanCommand("DRIVER COUNTRY " + countryCode);
+        return doBooleanCommand("DRIVER COUNTRY " + countryCode.toUpperCase(Locale.ROOT));
     }
 
     public void enableBackgroundScan(boolean enable) {
@@ -370,6 +477,15 @@
         doBooleanCommand("SCAN_INTERVAL " + scanInterval);
     }
 
+    public void startTdls(String macAddr, boolean enable) {
+        if (enable) {
+            doBooleanCommand("TDLS_DISCOVER " + macAddr);
+            doBooleanCommand("TDLS_SETUP " + macAddr);
+        } else {
+            doBooleanCommand("TDLS_TEARDOWN " + macAddr);
+        }
+    }
+
     /** Example output:
      * RSSI=-65
      * LINKSPEED=48
@@ -377,7 +493,7 @@
      * FREQUENCY=0
      */
     public String signalPoll() {
-        return doStringCommand("SIGNAL_POLL");
+        return doStringCommandWithoutLogging("SIGNAL_POLL");
     }
 
     /** Example outout:
@@ -388,6 +504,10 @@
         return doStringCommand("PKTCNT_POLL");
     }
 
+    public void bssFlush() {
+        doBooleanCommand("BSS_FLUSH 0");
+    }
+
     public boolean startWpsPbc(String bssid) {
         if (TextUtils.isEmpty(bssid)) {
             return doBooleanCommand("WPS_PBC");
@@ -397,10 +517,12 @@
     }
 
     public boolean startWpsPbc(String iface, String bssid) {
-        if (TextUtils.isEmpty(bssid)) {
-            return doBooleanCommand("WPS_PBC interface=" + iface);
-        } else {
-            return doBooleanCommand("WPS_PBC interface=" + iface + " " + bssid);
+        synchronized (mLock) {
+            if (TextUtils.isEmpty(bssid)) {
+                return doBooleanCommandNative("IFNAME=" + iface + " WPS_PBC");
+            } else {
+                return doBooleanCommandNative("IFNAME=" + iface + " WPS_PBC " + bssid);
+            }
         }
     }
 
@@ -411,7 +533,9 @@
 
     public boolean startWpsPinKeypad(String iface, String pin) {
         if (TextUtils.isEmpty(pin)) return false;
-        return doBooleanCommand("WPS_PIN interface=" + iface + " any " + pin);
+        synchronized (mLock) {
+            return doBooleanCommandNative("IFNAME=" + iface + " WPS_PIN any " + pin);
+        }
     }
 
 
@@ -424,10 +548,12 @@
     }
 
     public String startWpsPinDisplay(String iface, String bssid) {
-        if (TextUtils.isEmpty(bssid)) {
-            return doStringCommand("WPS_PIN interface=" + iface + " any");
-        } else {
-            return doStringCommand("WPS_PIN interface=" + iface + " " + bssid);
+        synchronized (mLock) {
+            if (TextUtils.isEmpty(bssid)) {
+                return doStringCommandNative("IFNAME=" + iface + " WPS_PIN any");
+            } else {
+                return doStringCommandNative("IFNAME=" + iface + " WPS_PIN " + bssid);
+            }
         }
     }
 
@@ -479,7 +605,9 @@
     }
 
     public boolean setP2pGroupIdle(String iface, int time) {
-        return doBooleanCommand("SET interface=" + iface + " p2p_group_idle " + time);
+        synchronized (mLock) {
+            return doBooleanCommandNative("IFNAME=" + iface + " SET p2p_group_idle " + time);
+        }
     }
 
     public void setPowerSave(boolean enabled) {
@@ -491,10 +619,12 @@
     }
 
     public boolean setP2pPowerSave(String iface, boolean enabled) {
-        if (enabled) {
-            return doBooleanCommand("P2P_SET interface=" + iface + " ps 1");
-        } else {
-            return doBooleanCommand("P2P_SET interface=" + iface + " ps 0");
+        synchronized (mLock) {
+            if (enabled) {
+                return doBooleanCommandNative("IFNAME=" + iface + " P2P_SET ps 1");
+            } else {
+                return doBooleanCommandNative("IFNAME=" + iface + " P2P_SET ps 0");
+            }
         }
     }
 
@@ -540,6 +670,37 @@
         return doBooleanCommand("P2P_LISTEN " + timeout);
     }
 
+    public boolean p2pExtListen(boolean enable, int period, int interval) {
+        if (enable && interval < period) {
+            return false;
+        }
+        return doBooleanCommand("P2P_EXT_LISTEN"
+                    + (enable ? (" " + period + " " + interval) : ""));
+    }
+
+    public boolean p2pSetChannel(int lc, int oc) {
+        if (DBG) Log.d(mTAG, "p2pSetChannel: lc="+lc+", oc="+oc);
+
+        if (lc >=1 && lc <= 11) {
+            if (!doBooleanCommand("P2P_SET listen_channel " + lc)) {
+                return false;
+            }
+        } else if (lc != 0) {
+            return false;
+        }
+
+        if (oc >= 1 && oc <= 165 ) {
+            int freq = (oc <= 14 ? 2407 : 5000) + oc * 5;
+            return doBooleanCommand("P2P_SET disallow_freq 1000-"
+                    + (freq - 5) + "," + (freq + 5) + "-6000");
+        } else if (oc == 0) {
+            /* oc==0 disables "P2P_SET disallow_freq" (enables all freqs) */
+            return doBooleanCommand("P2P_SET disallow_freq \"\"");
+        }
+
+        return false;
+    }
+
     public boolean p2pFlush() {
         return doBooleanCommand("P2P_FLUSH");
     }
@@ -632,7 +793,9 @@
 
     public boolean p2pGroupRemove(String iface) {
         if (TextUtils.isEmpty(iface)) return false;
-        return doBooleanCommand("P2P_GROUP_REMOVE " + iface);
+        synchronized (mLock) {
+            return doBooleanCommandNative("IFNAME=" + iface + " P2P_GROUP_REMOVE " + iface);
+        }
     }
 
     public boolean p2pReject(String deviceAddress) {
diff --git a/wifi/java/android/net/wifi/WifiSsid.java b/wifi/java/android/net/wifi/WifiSsid.java
index 55e9b2d..a35a34b 100644
--- a/wifi/java/android/net/wifi/WifiSsid.java
+++ b/wifi/java/android/net/wifi/WifiSsid.java
@@ -27,6 +27,7 @@
 import java.nio.charset.CharsetDecoder;
 import java.nio.charset.CoderResult;
 import java.nio.charset.CodingErrorAction;
+import java.util.Locale;
 
 /**
  * Stores SSID octets and handles conversion.
@@ -199,7 +200,7 @@
         String out = "0x";
         byte[] ssidbytes = getOctets();
         for (int i = 0; i < octets.size(); i++) {
-            out += String.format("%02x", ssidbytes[i]);
+            out += String.format(Locale.US, "%02x", ssidbytes[i]);
         }
         return out;
     }
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 3a7834d..ad89716 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -51,9 +51,11 @@
 import android.net.NetworkInfo;
 import android.net.NetworkInfo.DetailedState;
 import android.net.NetworkUtils;
+import android.net.RouteInfo;
 import android.net.wifi.WpsResult.Status;
 import android.net.wifi.p2p.WifiP2pManager;
 import android.net.wifi.p2p.WifiP2pService;
+import android.os.BatteryStats;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.INetworkManagementService;
@@ -63,10 +65,12 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.WorkSource;
 import android.provider.Settings;
+import android.util.Log;
 import android.util.LruCache;
 import android.text.TextUtils;
 
@@ -77,12 +81,14 @@
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
 
+import com.android.server.net.BaseNetworkObserver;
+
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.net.InetAddress;
+import java.net.Inet6Address;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Locale;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.Iterator;
@@ -121,6 +127,13 @@
     private static final int SCAN_RESULT_CACHE_SIZE = 80;
     private final LruCache<String, ScanResult> mScanResultCache;
 
+    /* Batch scan results */
+    private final List<BatchedScanResult> mBatchedScanResults =
+            new ArrayList<BatchedScanResult>();
+    private int mBatchedScanOwnerUid = UNKNOWN_SCAN_SOURCE;
+    private int mExpectedBatchedScans = 0;
+    private long mBatchedScanMinPollTime = 0;
+
     /* Chipset supports background scan */
     private final boolean mBackgroundScanSupported;
 
@@ -189,8 +202,19 @@
     /* Tracks sequence number on a driver time out */
     private int mDriverStartToken = 0;
 
+    /**
+     * The link properties of the wifi interface.
+     * Do not modify this directly; use updateLinkProperties instead.
+     */
     private LinkProperties mLinkProperties;
 
+    /**
+     * Subset of link properties coming from netlink.
+     * Currently includes IPv4 and IPv6 addresses. In the future will also include IPv6 DNS servers
+     * and domains obtained from router advertisements (RFC 6106).
+     */
+    private final LinkProperties mNetlinkLinkProperties;
+
     /* Tracks sequence number on a periodic scan message */
     private int mPeriodicScanToken = 0;
 
@@ -206,9 +230,43 @@
     private SupplicantStateTracker mSupplicantStateTracker;
     private DhcpStateMachine mDhcpStateMachine;
 
+    private class InterfaceObserver extends BaseNetworkObserver {
+        private WifiStateMachine mWifiStateMachine;
+
+        InterfaceObserver(WifiStateMachine wifiStateMachine) {
+            super();
+            mWifiStateMachine = wifiStateMachine;
+        }
+
+        @Override
+        public void addressUpdated(String address, String iface, int flags, int scope) {
+            if (mWifiStateMachine.mInterfaceName.equals(iface)) {
+                if (DBG) {
+                    log("addressUpdated: " + address + " on " + iface +
+                        " flags " + flags + " scope " + scope);
+                }
+                mWifiStateMachine.sendMessage(CMD_IP_ADDRESS_UPDATED, new LinkAddress(address));
+            }
+        }
+
+        @Override
+        public void addressRemoved(String address, String iface, int flags, int scope) {
+            if (mWifiStateMachine.mInterfaceName.equals(iface)) {
+                if (DBG) {
+                    log("addressRemoved: " + address + " on " + iface +
+                        " flags " + flags + " scope " + scope);
+                }
+                mWifiStateMachine.sendMessage(CMD_IP_ADDRESS_REMOVED, new LinkAddress(address));
+            }
+        }
+    }
+
+    private InterfaceObserver mInterfaceObserver;
+
     private AlarmManager mAlarmManager;
     private PendingIntent mScanIntent;
     private PendingIntent mDriverStopIntent;
+    private PendingIntent mBatchedScanIntervalIntent;
 
     /* Tracks current frequency mode */
     private AtomicInteger mFrequencyBand = new AtomicInteger(WifiManager.WIFI_FREQUENCY_BAND_AUTO);
@@ -337,6 +395,8 @@
     static final int CMD_SET_FREQUENCY_BAND               = BASE + 90;
     /* Enable background scan for configured networks */
     static final int CMD_ENABLE_BACKGROUND_SCAN           = BASE + 91;
+    /* Enable TDLS on a specific MAC address */
+    static final int CMD_ENABLE_TDLS                      = BASE + 92;
 
     /* Commands from/to the SupplicantStateTracker */
     /* Reset the supplicant state tracker */
@@ -352,6 +412,20 @@
 
     public static final int CMD_BOOT_COMPLETED            = BASE + 134;
 
+    /* change the batch scan settings.
+     * arg1 = responsible UID
+     * obj = the new settings
+     */
+    public static final int CMD_SET_BATCHED_SCAN          = BASE + 135;
+    public static final int CMD_START_NEXT_BATCHED_SCAN   = BASE + 136;
+    public static final int CMD_POLL_BATCHED_SCAN         = BASE + 137;
+
+    /* Link configuration (IP address, DNS, ...) changes */
+    /* An new IP address was added to our interface, or an existing IP address was updated */
+    static final int CMD_IP_ADDRESS_UPDATED               = BASE + 140;
+    /* An IP address was removed from our interface */
+    static final int CMD_IP_ADDRESS_REMOVED               = BASE + 141;
+
     public static final int CONNECT_MODE                   = 1;
     public static final int SCAN_ONLY_MODE                 = 2;
     public static final int SCAN_ONLY_WITH_WIFI_OFF_MODE   = 3;
@@ -516,6 +590,8 @@
     private static final String ACTION_DELAYED_DRIVER_STOP =
         "com.android.server.WifiManager.action.DELAYED_DRIVER_STOP";
 
+    private static final String ACTION_REFRESH_BATCHED_SCAN =
+            "com.android.server.WifiManager.action.REFRESH_BATCHED_SCAN";
     /**
      * Keep track of whether WIFI is running.
      */
@@ -538,14 +614,17 @@
 
     private final IBatteryStats mBatteryStats;
 
+    private BatchedScanSettings mBatchedScanSettings = null;
+
+
     public WifiStateMachine(Context context, String wlanInterface) {
         super("WifiStateMachine");
-
         mContext = context;
         mInterfaceName = wlanInterface;
 
         mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, NETWORKTYPE, "");
-        mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo"));
+        mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
+                BatteryStats.SERVICE_NAME));
 
         IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
         mNwService = INetworkManagementService.Stub.asInterface(b);
@@ -560,19 +639,29 @@
         mSupplicantStateTracker = new SupplicantStateTracker(context, this, mWifiConfigStore,
                 getHandler());
         mLinkProperties = new LinkProperties();
+        mNetlinkLinkProperties = new LinkProperties();
 
         mWifiP2pManager = (WifiP2pManager) mContext.getSystemService(Context.WIFI_P2P_SERVICE);
 
         mNetworkInfo.setIsAvailable(false);
-        mLinkProperties.clear();
         mLastBssid = null;
         mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
         mLastSignalLevel = -1;
 
+        mInterfaceObserver = new InterfaceObserver(this);
+        try {
+            mNwService.registerObserver(mInterfaceObserver);
+        } catch (RemoteException e) {
+            loge("Couldn't register interface observer: " + e.toString());
+        }
+
         mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
         Intent scanIntent = new Intent(ACTION_START_SCAN, null);
         mScanIntent = PendingIntent.getBroadcast(mContext, SCAN_REQUEST, scanIntent, 0);
 
+        Intent batchedIntent = new Intent(ACTION_REFRESH_BATCHED_SCAN, null);
+        mBatchedScanIntervalIntent = PendingIntent.getBroadcast(mContext, 0, batchedIntent, 0);
+
         mDefaultFrameworkScanIntervalMs = mContext.getResources().getInteger(
                 R.integer.config_wifi_framework_scan_interval);
 
@@ -604,27 +693,31 @@
                 new BroadcastReceiver() {
                     @Override
                     public void onReceive(Context context, Intent intent) {
-                        startScan(UNKNOWN_SCAN_SOURCE);
+                        final WorkSource workSource = null;
+                        startScan(UNKNOWN_SCAN_SOURCE, workSource);
                     }
                 },
                 new IntentFilter(ACTION_START_SCAN));
 
-        IntentFilter screenFilter = new IntentFilter();
-        screenFilter.addAction(Intent.ACTION_SCREEN_ON);
-        screenFilter.addAction(Intent.ACTION_SCREEN_OFF);
-        BroadcastReceiver screenReceiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                String action = intent.getAction();
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_SCREEN_ON);
+        filter.addAction(Intent.ACTION_SCREEN_OFF);
+        filter.addAction(ACTION_REFRESH_BATCHED_SCAN);
+        mContext.registerReceiver(
+                new BroadcastReceiver() {
+                    @Override
+                    public void onReceive(Context context, Intent intent) {
+                        String action = intent.getAction();
 
-                if (action.equals(Intent.ACTION_SCREEN_ON)) {
-                    handleScreenStateChanged(true);
-                } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
-                    handleScreenStateChanged(false);
-                }
-            }
-        };
-        mContext.registerReceiver(screenReceiver, screenFilter);
+                        if (action.equals(Intent.ACTION_SCREEN_ON)) {
+                            handleScreenStateChanged(true);
+                        } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
+                            handleScreenStateChanged(false);
+                        } else if (action.equals(ACTION_REFRESH_BATCHED_SCAN)) {
+                            startNextBatchedScanAsync();
+                        }
+                    }
+                }, filter);
 
         mContext.registerReceiver(
                 new BroadcastReceiver() {
@@ -691,7 +784,7 @@
 
         setInitialState(mInitialState);
 
-        setLogRecSize(300);
+        setLogRecSize(2000);
         setLogOnlyTransitions(false);
         if (DBG) setDbg(true);
 
@@ -722,15 +815,314 @@
     }
 
     /**
-     * TODO: doc
+     * Initiate a wifi scan.  If workSource is not null, blame is given to it,
+     * otherwise blame is given to callingUid.
+     *
+     * @param callingUid The uid initiating the wifi scan.  Blame will be given
+     *                   here unless workSource is specified.
+     * @param workSource If not null, blame is given to workSource.
      */
-    public void startScan(int callingUid) {
-        sendMessage(CMD_START_SCAN, callingUid);
+    public void startScan(int callingUid, WorkSource workSource) {
+        sendMessage(CMD_START_SCAN, callingUid, 0, workSource);
     }
 
-    private void noteScanStart(int callingUid) {
-        if (mScanWorkSource == null && callingUid != UNKNOWN_SCAN_SOURCE) {
-            mScanWorkSource = new WorkSource(callingUid);
+    /**
+     * start or stop batched scanning using the given settings
+     */
+    public void setBatchedScanSettings(BatchedScanSettings settings, int callingUid) {
+        sendMessage(CMD_SET_BATCHED_SCAN, callingUid, 0, settings);
+    }
+
+    public List<BatchedScanResult> syncGetBatchedScanResultsList() {
+        synchronized (mBatchedScanResults) {
+            List<BatchedScanResult> batchedScanList =
+                    new ArrayList<BatchedScanResult>(mBatchedScanResults.size());
+            for(BatchedScanResult result: mBatchedScanResults) {
+                batchedScanList.add(new BatchedScanResult(result));
+            }
+            return batchedScanList;
+        }
+    }
+
+    public void requestBatchedScanPoll() {
+        sendMessage(CMD_POLL_BATCHED_SCAN);
+    }
+
+    private void startBatchedScan() {
+        // first grab any existing data
+        retrieveBatchedScanData();
+
+        mAlarmManager.cancel(mBatchedScanIntervalIntent);
+
+        String scansExpected = mWifiNative.setBatchedScanSettings(mBatchedScanSettings);
+
+        try {
+            mExpectedBatchedScans = Integer.parseInt(scansExpected);
+            setNextBatchedAlarm(mExpectedBatchedScans);
+        } catch (NumberFormatException e) {
+            stopBatchedScan();
+            loge("Exception parsing WifiNative.setBatchedScanSettings response " + e);
+        }
+    }
+
+    // called from BroadcastListener
+    private void startNextBatchedScanAsync() {
+        sendMessage(CMD_START_NEXT_BATCHED_SCAN);
+    }
+
+    private void startNextBatchedScan() {
+        // first grab any existing data
+        retrieveBatchedScanData();
+
+        setNextBatchedAlarm(mExpectedBatchedScans);
+    }
+
+    private void handleBatchedScanPollRequest() {
+        if (DBG) {
+            log("handleBatchedScanPoll Request - mBatchedScanMinPollTime=" +
+                    mBatchedScanMinPollTime + " , mBatchedScanSettings=" +
+                    mBatchedScanSettings);
+        }
+        // if there is no appropriate PollTime that's because we either aren't
+        // batching or we've already set a time for a poll request
+        if (mBatchedScanMinPollTime == 0) return;
+        if (mBatchedScanSettings == null) return;
+
+        long now = System.currentTimeMillis();
+
+        if (now > mBatchedScanMinPollTime) {
+            // do the poll and reset our timers
+            startNextBatchedScan();
+        } else {
+            mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, mBatchedScanMinPollTime,
+                    mBatchedScanIntervalIntent);
+            mBatchedScanMinPollTime = 0;
+        }
+    }
+
+    // return true if new/different
+    private boolean recordBatchedScanSettings(BatchedScanSettings settings) {
+        if (DBG) log("set batched scan to " + settings);
+        if (settings != null) {
+            // TODO - noteBatchedScanStart(message.arg1);
+            if (settings.equals(mBatchedScanSettings)) return false;
+        } else {
+            if (mBatchedScanSettings == null) return false;
+            // TODO - noteBatchedScanStop(message.arg1);
+        }
+        mBatchedScanSettings = settings;
+        return true;
+    }
+
+    private void stopBatchedScan() {
+        mAlarmManager.cancel(mBatchedScanIntervalIntent);
+        retrieveBatchedScanData();
+        mWifiNative.setBatchedScanSettings(null);
+    }
+
+    private void setNextBatchedAlarm(int scansExpected) {
+
+        if (mBatchedScanSettings == null || scansExpected < 1) return;
+
+        mBatchedScanMinPollTime = System.currentTimeMillis() +
+                mBatchedScanSettings.scanIntervalSec * 1000;
+
+        if (mBatchedScanSettings.maxScansPerBatch < scansExpected) {
+            scansExpected = mBatchedScanSettings.maxScansPerBatch;
+        }
+
+        int secToFull = mBatchedScanSettings.scanIntervalSec;
+        secToFull *= scansExpected;
+
+        int debugPeriod = SystemProperties.getInt("wifi.batchedScan.pollPeriod", 0);
+        if (debugPeriod > 0) secToFull = debugPeriod;
+
+        // set the alarm to do the next poll.  We set it a little short as we'd rather
+        // wake up wearly than miss a scan due to buffer overflow
+        mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()
+                + ((secToFull - (mBatchedScanSettings.scanIntervalSec / 2)) * 1000),
+                mBatchedScanIntervalIntent);
+    }
+
+    /**
+     * Start reading new scan data
+     * Data comes in as:
+     * "scancount=5\n"
+     * "nextcount=5\n"
+     *   "apcount=3\n"
+     *   "trunc\n" (optional)
+     *     "bssid=...\n"
+     *     "ssid=...\n"
+     *     "freq=...\n" (in Mhz)
+     *     "level=...\n"
+     *     "dist=...\n" (in cm)
+     *     "distsd=...\n" (standard deviation, in cm)
+     *     "===="
+     *     "bssid=...\n"
+     *     etc
+     *     "===="
+     *     "bssid=...\n"
+     *     etc
+     *     "%%%%"
+     *   "apcount=2\n"
+     *     "bssid=...\n"
+     *     etc
+     *     "%%%%
+     *   etc
+     *   "----"
+     */
+    private final static boolean DEBUG_PARSE = false;
+    private void retrieveBatchedScanData() {
+        String rawData = mWifiNative.getBatchedScanResults();
+        if (DEBUG_PARSE) log("rawData = " + rawData);
+        mBatchedScanMinPollTime = 0;
+        if (rawData == null || rawData.equalsIgnoreCase("OK")) {
+            loge("Unexpected BatchedScanResults :" + rawData);
+            return;
+        }
+
+        int scanCount = 0;
+        final String END_OF_BATCHES = "----";
+        final String SCANCOUNT = "scancount=";
+        final String TRUNCATED = "trunc";
+        final String AGE = "age=";
+        final String DIST = "dist=";
+        final String DISTSD = "distSd=";
+
+        String splitData[] = rawData.split("\n");
+        int n = 0;
+        if (splitData[n].startsWith(SCANCOUNT)) {
+            try {
+                scanCount = Integer.parseInt(splitData[n++].substring(SCANCOUNT.length()));
+            } catch (NumberFormatException e) {
+                loge("scancount parseInt Exception from " + splitData[n]);
+            }
+        } else log("scancount not found");
+        if (scanCount == 0) {
+            loge("scanCount==0 - aborting");
+            return;
+        }
+
+        final Intent intent = new Intent(WifiManager.BATCHED_SCAN_RESULTS_AVAILABLE_ACTION);
+        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+
+        synchronized (mBatchedScanResults) {
+            mBatchedScanResults.clear();
+            BatchedScanResult batchedScanResult = new BatchedScanResult();
+
+            String bssid = null;
+            WifiSsid wifiSsid = null;
+            int level = 0;
+            int freq = 0;
+            int dist, distSd;
+            long tsf = 0;
+            dist = distSd = ScanResult.UNSPECIFIED;
+            long now = SystemClock.elapsedRealtime();
+
+            while (true) {
+                while (n < splitData.length) {
+                    if (DEBUG_PARSE) logd("parsing " + splitData[n]);
+                    if (splitData[n].equals(END_OF_BATCHES)) {
+                        if (n+1 != splitData.length) {
+                            loge("didn't consume " + (splitData.length-n));
+                        }
+                        if (mBatchedScanResults.size() > 0) {
+                            mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
+                        }
+                        logd("retrieveBatchedScanResults X");
+                        return;
+                    }
+                    if ((splitData[n].equals(END_STR)) || splitData[n].equals(DELIMITER_STR)) {
+                        if (bssid != null) {
+                            batchedScanResult.scanResults.add(new ScanResult(
+                                    wifiSsid, bssid, "", level, freq, tsf, dist, distSd));
+                            wifiSsid = null;
+                            bssid = null;
+                            level = 0;
+                            freq = 0;
+                            tsf = 0;
+                            dist = distSd = ScanResult.UNSPECIFIED;
+                        }
+                        if (splitData[n].equals(END_STR)) {
+                            if (batchedScanResult.scanResults.size() != 0) {
+                                mBatchedScanResults.add(batchedScanResult);
+                                batchedScanResult = new BatchedScanResult();
+                            } else {
+                                logd("Found empty batch");
+                            }
+                        }
+                    } else if (splitData[n].equals(TRUNCATED)) {
+                        batchedScanResult.truncated = true;
+                    } else if (splitData[n].startsWith(BSSID_STR)) {
+                        bssid = splitData[n].substring(BSSID_STR.length());
+                    } else if (splitData[n].startsWith(FREQ_STR)) {
+                        try {
+                            freq = Integer.parseInt(splitData[n].substring(FREQ_STR.length()));
+                        } catch (NumberFormatException e) {
+                            loge("Invalid freqency: " + splitData[n]);
+                            freq = 0;
+                        }
+                    } else if (splitData[n].startsWith(AGE)) {
+                        try {
+                            tsf = now - Long.parseLong(splitData[n].substring(AGE.length()));
+                            tsf *= 1000; // convert mS -> uS
+                        } catch (NumberFormatException e) {
+                            loge("Invalid timestamp: " + splitData[n]);
+                            tsf = 0;
+                        }
+                    } else if (splitData[n].startsWith(SSID_STR)) {
+                        wifiSsid = WifiSsid.createFromAsciiEncoded(
+                                splitData[n].substring(SSID_STR.length()));
+                    } else if (splitData[n].startsWith(LEVEL_STR)) {
+                        try {
+                            level = Integer.parseInt(splitData[n].substring(LEVEL_STR.length()));
+                            if (level > 0) level -= 256;
+                        } catch (NumberFormatException e) {
+                            loge("Invalid level: " + splitData[n]);
+                            level = 0;
+                        }
+                    } else if (splitData[n].startsWith(DIST)) {
+                        try {
+                            dist = Integer.parseInt(splitData[n].substring(DIST.length()));
+                        } catch (NumberFormatException e) {
+                            loge("Invalid distance: " + splitData[n]);
+                            dist = ScanResult.UNSPECIFIED;
+                        }
+                    } else if (splitData[n].startsWith(DISTSD)) {
+                        try {
+                            distSd = Integer.parseInt(splitData[n].substring(DISTSD.length()));
+                        } catch (NumberFormatException e) {
+                            loge("Invalid distanceSd: " + splitData[n]);
+                            distSd = ScanResult.UNSPECIFIED;
+                        }
+                    } else {
+                        loge("Unable to parse batched scan result line: " + splitData[n]);
+                    }
+                    n++;
+                }
+                rawData = mWifiNative.getBatchedScanResults();
+                if (DEBUG_PARSE) log("reading more data:\n" + rawData);
+                if (rawData == null) {
+                    loge("Unexpected null BatchedScanResults");
+                    return;
+                }
+                splitData = rawData.split("\n");
+                if (splitData.length == 0 || splitData[0].equals("ok")) {
+                    loge("batch scan results just ended!");
+                    if (mBatchedScanResults.size() > 0) {
+                        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
+                    }
+                    return;
+                }
+                n = 0;
+            }
+        }
+    }
+
+    // If workSource is not null, blame is given to it, otherwise blame is given to callingUid.
+    private void noteScanStart(int callingUid, WorkSource workSource) {
+        if (mScanWorkSource == null && (callingUid != UNKNOWN_SCAN_SOURCE || workSource != null)) {
+            mScanWorkSource = workSource != null ? workSource : new WorkSource(callingUid);
             try {
                 mBatteryStats.noteWifiScanStartedFromSource(mScanWorkSource);
             } catch (RemoteException e) {
@@ -877,6 +1269,7 @@
      * TODO: doc
      */
     public void setOperationalMode(int mode) {
+        if (DBG) log("setting operational mode to " + String.valueOf(mode));
         sendMessage(CMD_SET_OPERATIONAL_MODE, mode, 0);
     }
 
@@ -1056,6 +1449,7 @@
                     countryCode);
         }
         sendMessage(CMD_SET_COUNTRY_CODE, countryCode);
+        mWifiP2pChannel.sendMessage(WifiP2pService.SET_COUNTRY_CODE, countryCode);
     }
 
     /**
@@ -1073,6 +1467,14 @@
     }
 
     /**
+     * Enable TDLS for a specific MAC address
+     */
+    public void enableTdls(String remoteMacAddress, boolean enable) {
+        int enabler = enable ? 1 : 0;
+        sendMessage(CMD_ENABLE_TDLS, enabler, 0, remoteMacAddress);
+    }
+
+    /**
      * Returns the operational frequency band
      */
     public int getFrequencyBand() {
@@ -1584,19 +1986,82 @@
         }
     }
 
-    private void configureLinkProperties() {
-        if (mWifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
-            mLinkProperties = mWifiConfigStore.getLinkProperties(mLastNetworkId);
-        } else {
-            synchronized (mDhcpResultsLock) {
-                if ((mDhcpResults != null) && (mDhcpResults.linkProperties != null)) {
-                    mLinkProperties = mDhcpResults.linkProperties;
+    /**
+     * Updates mLinkProperties by merging information from various sources.
+     *
+     * This is needed because the information in mLinkProperties comes from multiple sources (DHCP,
+     * netlink, static configuration, ...). When one of these sources of information has updated
+     * link properties, we can't just assign them to mLinkProperties or we'd lose track of the
+     * information that came from other sources. Instead, when one of those sources has new
+     * information, we update the object that tracks the information from that source and then
+     * call this method to apply the change to mLinkProperties.
+     *
+     * The information in mLinkProperties is currently obtained as follows:
+     * - Interface name: set in the constructor.
+     * - IPv4 and IPv6 addresses: netlink, via mInterfaceObserver.
+     * - IPv4 routes, DNS servers, and domains: DHCP.
+     * - HTTP proxy: the wifi config store.
+     */
+    private void updateLinkProperties() {
+        LinkProperties newLp = new LinkProperties();
+
+        // Interface name and proxy are locally configured.
+        newLp.setInterfaceName(mInterfaceName);
+        newLp.setHttpProxy(mWifiConfigStore.getProxyProperties(mLastNetworkId));
+
+        // IPv4 and IPv6 addresses come from netlink.
+        newLp.setLinkAddresses(mNetlinkLinkProperties.getLinkAddresses());
+
+        // For now, routing and DNS only come from DHCP or static configuration. In the future,
+        // we'll need to merge IPv6 DNS servers and domains coming from netlink.
+        synchronized (mDhcpResultsLock) {
+            // Even when we're using static configuration, we don't need to look at the config
+            // store, because static IP configuration also populates mDhcpResults.
+            if ((mDhcpResults != null) && (mDhcpResults.linkProperties != null)) {
+                LinkProperties lp = mDhcpResults.linkProperties;
+                for (RouteInfo route: lp.getRoutes()) {
+                    newLp.addRoute(route);
                 }
+                for (InetAddress dns: lp.getDnses()) {
+                    newLp.addDns(dns);
+                }
+                newLp.setDomains(lp.getDomains());
             }
-            mLinkProperties.setHttpProxy(mWifiConfigStore.getProxyProperties(mLastNetworkId));
         }
-        mLinkProperties.setInterfaceName(mInterfaceName);
-        if (DBG) log("netId=" + mLastNetworkId  + " Link configured: " + mLinkProperties);
+
+        // If anything has changed, and we're already connected, send out a notification.
+        // If we're still connecting, apps will be notified when we connect.
+        if (!newLp.equals(mLinkProperties)) {
+            if (DBG) {
+                log("Link configuration changed for netId: " + mLastNetworkId
+                        + " old: " + mLinkProperties + "new: " + newLp);
+            }
+            mLinkProperties = newLp;
+            if (getNetworkDetailedState() == DetailedState.CONNECTED) {
+                sendLinkConfigurationChangedBroadcast();
+            }
+        }
+    }
+
+    /**
+     * Clears all our link properties.
+     */
+    private void clearLinkProperties() {
+        // If the network used DHCP, clear the LinkProperties we stored in the config store.
+        if (!mWifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
+            mWifiConfigStore.clearLinkProperties(mLastNetworkId);
+        }
+
+        // Clear the link properties obtained from DHCP and netlink.
+        synchronized(mDhcpResultsLock) {
+            if (mDhcpResults != null && mDhcpResults.linkProperties != null) {
+                mDhcpResults.linkProperties.clear();
+            }
+        }
+        mNetlinkLinkProperties.clear();
+
+        // Now clear the merged link properties.
+        mLinkProperties.clear();
     }
 
     private int getMaxDhcpRetries() {
@@ -1719,16 +2184,11 @@
         mWifiConfigStore.updateStatus(mLastNetworkId, DetailedState.DISCONNECTED);
 
         /* Clear network properties */
-        mLinkProperties.clear();
+        clearLinkProperties();
 
         /* send event to CM & network change broadcast */
         sendNetworkStateChangeBroadcast(mLastBssid);
 
-        /* Clear IP settings if the network used DHCP */
-        if (!mWifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
-            mWifiConfigStore.clearLinkProperties(mLastNetworkId);
-        }
-
         mLastBssid= null;
         mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
     }
@@ -1737,8 +2197,7 @@
         /* Socket connection can be lost when we do a graceful shutdown
         * or when the driver is hung. Ensure supplicant is stopped here.
         */
-        mWifiNative.killSupplicant(mP2pSupported);
-        mWifiNative.closeSupplicantConnection();
+        mWifiMonitor.killSupplicant(mP2pSupported);
         sendSupplicantConnectionChangedBroadcast(false);
         setWifiState(WIFI_STATE_DISABLED);
     }
@@ -1828,20 +2287,7 @@
         }
         mWifiInfo.setInetAddress(addr);
         mWifiInfo.setMeteredHint(dhcpResults.hasMeteredHint());
-        if (getNetworkDetailedState() == DetailedState.CONNECTED) {
-            //DHCP renewal in connected state
-            linkProperties.setHttpProxy(mWifiConfigStore.getProxyProperties(mLastNetworkId));
-            if (!linkProperties.equals(mLinkProperties)) {
-                if (DBG) {
-                    log("Link configuration changed for netId: " + mLastNetworkId
-                            + " old: " + mLinkProperties + "new: " + linkProperties);
-                }
-                mLinkProperties = linkProperties;
-                sendLinkConfigurationChangedBroadcast();
-            }
-        } else {
-            configureLinkProperties();
-        }
+        updateLinkProperties();
     }
 
     private void handleFailedIpConfiguration() {
@@ -1960,6 +2406,15 @@
                         sendMessageAtFrontOfQueue(CMD_SET_COUNTRY_CODE, countryCode);
                     }
                     break;
+                case CMD_SET_BATCHED_SCAN:
+                    recordBatchedScanSettings((BatchedScanSettings)message.obj);
+                    break;
+                case CMD_POLL_BATCHED_SCAN:
+                    handleBatchedScanPollRequest();
+                    break;
+                case CMD_START_NEXT_BATCHED_SCAN:
+                    startNextBatchedScan();
+                    break;
                     /* Discard */
                 case CMD_START_SCAN:
                 case CMD_START_SUPPLICANT:
@@ -2058,6 +2513,17 @@
                     mTemporarilyDisconnectWifi = (message.arg1 == 1);
                     replyToMessage(message, WifiP2pService.DISCONNECT_WIFI_RESPONSE);
                     break;
+                case CMD_IP_ADDRESS_UPDATED:
+                    // addLinkAddress is a no-op if called more than once with the same address.
+                    if (mNetlinkLinkProperties.addLinkAddress((LinkAddress) message.obj)) {
+                        updateLinkProperties();
+                    }
+                    break;
+                case CMD_IP_ADDRESS_REMOVED:
+                    if (mNetlinkLinkProperties.removeLinkAddress((LinkAddress) message.obj)) {
+                        updateLinkProperties();
+                    }
+                    break;
                 default:
                     loge("Error! unhandled message" + message);
                     break;
@@ -2120,7 +2586,7 @@
                         * Avoids issues with drivers that do not handle interface down
                         * on a running supplicant properly.
                         */
-                        mWifiNative.killSupplicant(mP2pSupported);
+                        mWifiMonitor.killSupplicant(mP2pSupported);
                         if(mWifiNative.startSupplicant(mP2pSupported)) {
                             setWifiState(WIFI_STATE_ENABLING);
                             if (DBG) log("Supplicant start successful");
@@ -2203,7 +2669,7 @@
                 case WifiMonitor.SUP_DISCONNECTION_EVENT:
                     if (++mSupplicantRestartCount <= SUPPLICANT_RESTART_TRIES) {
                         loge("Failed to setup control channel, restart supplicant");
-                        mWifiNative.killSupplicant(mP2pSupported);
+                        mWifiMonitor.killSupplicant(mP2pSupported);
                         transitionTo(mInitialState);
                         sendMessageDelayed(CMD_START_SUPPLICANT, SUPPLICANT_RESTART_INTERVAL_MSECS);
                     } else {
@@ -2310,9 +2776,7 @@
             }
 
             if (DBG) log("stopping supplicant");
-            if (!mWifiNative.stopSupplicant()) {
-                loge("Failed to stop supplicant");
-            }
+            mWifiMonitor.stopSupplicant();
 
             /* Send ourselves a delayed message to indicate failure after a wait time */
             sendMessageDelayed(obtainMessage(CMD_STOP_SUPPLICANT_FAILED,
@@ -2453,13 +2917,20 @@
                 mWifiNative.stopFilteringMulticastV4Packets();
             }
 
+            if (mBatchedScanSettings != null) {
+                startBatchedScan();
+            }
+
             if (mOperationalMode != CONNECT_MODE) {
                 mWifiNative.disconnect();
                 transitionTo(mScanModeState);
             } else {
                 /* Driver stop may have disabled networks, enable right after start */
                 mWifiConfigStore.enableAllNetworks();
+
+                if (DBG) log("Attempting to reconnect to wifi network ..");
                 mWifiNative.reconnect();
+
                 // Status pulls in the current supplicant state and network connection state
                 // events over the monitor connection. This helps framework sync up with
                 // current supplicant state
@@ -2491,13 +2962,17 @@
         public boolean processMessage(Message message) {
             switch(message.what) {
                 case CMD_START_SCAN:
-                    noteScanStart(message.arg1);
+                    noteScanStart(message.arg1, (WorkSource) message.obj);
                     startScanNative(WifiNative.SCAN_WITH_CONNECTION_SETUP);
                     break;
+                case CMD_SET_BATCHED_SCAN:
+                    recordBatchedScanSettings((BatchedScanSettings)message.obj);
+                    startBatchedScan();
+                    break;
                 case CMD_SET_COUNTRY_CODE:
                     String country = (String) message.obj;
                     if (DBG) log("set country code " + country);
-                    if (!mWifiNative.setCountryCode(country.toUpperCase(Locale.ROOT))) {
+                    if (!mWifiNative.setCountryCode(country)) {
                         loge("Failed to set country code " + country);
                     }
                     break;
@@ -2506,6 +2981,8 @@
                     if (DBG) log("set frequency band " + band);
                     if (mWifiNative.setBand(band)) {
                         mFrequencyBand.set(band);
+                        // flush old data - like scan results
+                        mWifiNative.bssFlush();
                         //Fetch the latest scan results when frequency band is set
                         startScanNative(WifiNative.SCAN_WITH_CONNECTION_SETUP);
                     } else {
@@ -2602,6 +3079,13 @@
                         setSuspendOptimizationsNative(SUSPEND_DUE_TO_HIGH_PERF, true);
                     }
                     break;
+                case CMD_ENABLE_TDLS:
+                    if (message.obj != null) {
+                        String remoteAddress = (String) message.obj;
+                        boolean enable = (message.arg1 == 1);
+                        mWifiNative.startTdls(remoteAddress, enable);
+                    }
+                    break;
                 default:
                     return NOT_HANDLED;
             }
@@ -2613,6 +3097,10 @@
             updateBatteryWorkSource(null);
             mScanResults = new ArrayList<ScanResult>();
 
+            if (mBatchedScanSettings != null) {
+                stopBatchedScan();
+            }
+
             final Intent intent = new Intent(WifiManager.WIFI_SCAN_AVAILABLE);
             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
             intent.putExtra(WifiManager.EXTRA_SCAN_AVAILABLE, WIFI_STATE_DISABLED);
@@ -2768,7 +3256,7 @@
                 // Handle scan. All the connection related commands are
                 // handled only in ConnectModeState
                 case CMD_START_SCAN:
-                    noteScanStart(message.arg1);
+                    noteScanStart(message.arg1, (WorkSource) message.obj);
                     startScanNative(WifiNative.SCAN_WITHOUT_CONNECTION_SETUP);
                     break;
                 default:
@@ -3034,7 +3522,7 @@
                     break;
                 case CMD_START_SCAN:
                     /* Do not attempt to connect when we are already connected */
-                    noteScanStart(message.arg1);
+                    noteScanStart(message.arg1, (WorkSource) message.obj);
                     startScanNative(WifiNative.SCAN_WITHOUT_CONNECTION_SETUP);
                     break;
                     /* Ignore connection to same network */
@@ -3054,8 +3542,7 @@
                         }
                         if (result.hasProxyChanged()) {
                             log("Reconfiguring proxy on connection");
-                            configureLinkProperties();
-                            sendLinkConfigurationChangedBroadcast();
+                            updateLinkProperties();
                         }
                     }
 
@@ -3109,13 +3596,14 @@
         @Override
         public void enter() {
             if (!mWifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
+                // TODO: If we're switching between static IP configuration and DHCP, remove the
+                // static configuration first.
                 startDhcp();
             } else {
                 // stop any running dhcp before assigning static IP
                 stopDhcp();
                 DhcpResults dhcpResults = new DhcpResults(
                         mWifiConfigStore.getLinkProperties(mLastNetworkId));
-                dhcpResults.linkProperties.setInterfaceName(mInterfaceName);
                 InterfaceConfiguration ifcg = new InterfaceConfiguration();
                 Iterator<LinkAddress> addrs =
                         dhcpResults.linkProperties.getLinkAddresses().iterator();
@@ -3358,7 +3846,7 @@
                     if (mP2pConnected.get()) break;
                     if (message.arg1 == mPeriodicScanToken &&
                             mWifiConfigStore.getConfiguredNetworks().size() == 0) {
-                        sendMessage(CMD_START_SCAN, UNKNOWN_SCAN_SOURCE);
+                        sendMessage(CMD_START_SCAN, UNKNOWN_SCAN_SOURCE, 0, (WorkSource) null);
                         sendMessageDelayed(obtainMessage(CMD_NO_NETWORKS_PERIODIC_SCAN,
                                     ++mPeriodicScanToken, 0), mSupplicantScanIntervalMs);
                     }
@@ -3697,6 +4185,7 @@
                     if (!isWifiTethered(stateChange.active)) {
                         loge("Tethering reports wifi as untethered!, shut down soft Ap");
                         setHostApRunning(null, false);
+                        setHostApRunning(null, true);
                     }
                     return HANDLED;
                 case CMD_STOP_AP:
@@ -3787,7 +4276,7 @@
     /**
      * arg2 on the source message has a unique id that needs to be retained in replies
      * to match the request
-     *
+
      * see WifiManager for details
      */
     private Message obtainMessageWithArg2(Message srcMsg) {
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index 461dedb..615c893 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -20,11 +20,14 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.net.BaseNetworkStateTracker;
 import android.net.LinkCapabilities;
+import android.net.LinkQualityInfo;
 import android.net.LinkProperties;
 import android.net.NetworkInfo;
 import android.net.NetworkInfo.DetailedState;
-import android.net.NetworkStateTracker;
+import android.net.SamplingDataTracker;
+import android.net.WifiLinkQualityInfo;
 import android.os.Handler;
 import android.os.Message;
 import android.os.Messenger;
@@ -37,7 +40,7 @@
  *
  * @hide
  */
-public class WifiStateTracker implements NetworkStateTracker {
+public class WifiStateTracker extends BaseNetworkStateTracker {
 
     private static final String NETWORKTYPE = "WIFI";
     private static final String TAG = "WifiStateTracker";
@@ -48,17 +51,17 @@
     private AtomicBoolean mPrivateDnsRouteSet = new AtomicBoolean(false);
     private AtomicBoolean mDefaultRouteSet = new AtomicBoolean(false);
 
-    private LinkProperties mLinkProperties;
-    private LinkCapabilities mLinkCapabilities;
-    private NetworkInfo mNetworkInfo;
     private NetworkInfo.State mLastState = NetworkInfo.State.UNKNOWN;
 
+    private WifiInfo mWifiInfo;
+
     /* For sending events to connectivity service handler */
     private Handler mCsHandler;
-    private Context mContext;
     private BroadcastReceiver mWifiStateReceiver;
     private WifiManager mWifiManager;
 
+    private SamplingDataTracker mSamplingDataTracker = new SamplingDataTracker();
+
     public WifiStateTracker(int netType, String networkName) {
         mNetworkInfo = new NetworkInfo(netType, 0, networkName, "");
         mLinkProperties = new LinkProperties();
@@ -174,6 +177,7 @@
     /**
      * Fetch NetworkInfo for the network
      */
+    @Override
     public NetworkInfo getNetworkInfo() {
         return new NetworkInfo(mNetworkInfo);
     }
@@ -181,6 +185,7 @@
     /**
      * Fetch LinkProperties for the network
      */
+    @Override
     public LinkProperties getLinkProperties() {
         return new LinkProperties(mLinkProperties);
     }
@@ -191,11 +196,48 @@
      *
      * @return a copy of this connections capabilities, may be empty but never null.
      */
+    @Override
     public LinkCapabilities getLinkCapabilities() {
         return new LinkCapabilities(mLinkCapabilities);
     }
 
     /**
+     * Return link info
+     * @return an object of type WifiLinkQualityInfo
+     */
+    @Override
+    public LinkQualityInfo getLinkQualityInfo() {
+        if (mNetworkInfo == null) {
+            // no data available yet; just return
+            return null;
+        }
+
+        WifiLinkQualityInfo li = new WifiLinkQualityInfo();
+        li.setNetworkType(mNetworkInfo.getType());
+
+        synchronized(mSamplingDataTracker.mSamplingDataLock) {
+            mSamplingDataTracker.setCommonLinkQualityInfoFields(li);
+            li.setTxGood(mSamplingDataTracker.getSampledTxPacketCount());
+            li.setTxBad(mSamplingDataTracker.getSampledTxPacketErrorCount());
+        }
+
+        // li.setTheoreticalRxBandwidth(??);
+        // li.setTheoreticalTxBandwidth(??);
+
+        if (mWifiInfo != null) {
+            li.setBssid(mWifiInfo.getBSSID());
+
+            int rssi = mWifiInfo.getRssi();
+            li.setRssi(rssi);
+
+            li.setNormalizedSignalStrength(mWifiManager.calculateSignalLevel(rssi,
+                    LinkQualityInfo.NORMALIZED_SIGNAL_STRENGTH_RANGE));
+        }
+
+        return li;
+    }
+
+    /**
      * Check if default route is set
      */
     public boolean isDefaultRouteSet() {
@@ -224,6 +266,7 @@
             if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
                 mNetworkInfo = (NetworkInfo) intent.getParcelableExtra(
                         WifiManager.EXTRA_NETWORK_INFO);
+
                 mLinkProperties = intent.getParcelableExtra(
                         WifiManager.EXTRA_LINK_PROPERTIES);
                 if (mLinkProperties == null) {
@@ -234,7 +277,9 @@
                 if (mLinkCapabilities == null) {
                     mLinkCapabilities = new LinkCapabilities();
                 }
-                // don't want to send redundent state messages
+
+                mWifiInfo = intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO);
+                // don't want to send redundant state messages
                 // but send portal check detailed state notice
                 NetworkInfo.State state = mNetworkInfo.getState();
                 if (mLastState == state &&
@@ -242,13 +287,15 @@
                     return;
                 } else {
                     mLastState = state;
+                    /* lets not sample traffic data across state changes */
+                    mSamplingDataTracker.resetSamplingData();
                 }
+
                 Message msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED,
                         new NetworkInfo(mNetworkInfo));
                 msg.sendToTarget();
             } else if (intent.getAction().equals(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION)) {
-                mLinkProperties = (LinkProperties) intent.getParcelableExtra(
-                        WifiManager.EXTRA_LINK_PROPERTIES);
+                mLinkProperties = intent.getParcelableExtra(WifiManager.EXTRA_LINK_PROPERTIES);
                 Message msg = mCsHandler.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo);
                 msg.sendToTarget();
             }
@@ -273,4 +320,15 @@
     public void supplyMessenger(Messenger messenger) {
         // not supported on this network
     }
+
+    @Override
+    public void startSampling(SamplingDataTracker.SamplingSnapshot s) {
+        mSamplingDataTracker.startSampling(s);
+    }
+
+    @Override
+    public void stopSampling(SamplingDataTracker.SamplingSnapshot s) {
+        mSamplingDataTracker.stopSampling(s);
+    }
 }
+
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
index 737ab91..4988b92 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -30,6 +30,7 @@
 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.IBinder;
 import android.os.Handler;
 import android.os.Looper;
@@ -430,6 +431,28 @@
     /** @hide */
     public static final int START_WPS_SUCCEEDED                     = BASE + 64;
 
+    /** @hide */
+    public static final int START_LISTEN                            = BASE + 65;
+    /** @hide */
+    public static final int START_LISTEN_FAILED                     = BASE + 66;
+    /** @hide */
+    public static final int START_LISTEN_SUCCEEDED                  = BASE + 67;
+
+    /** @hide */
+    public static final int STOP_LISTEN                             = BASE + 68;
+    /** @hide */
+    public static final int STOP_LISTEN_FAILED                      = BASE + 69;
+    /** @hide */
+    public static final int STOP_LISTEN_SUCCEEDED                   = BASE + 70;
+
+    /** @hide */
+    public static final int SET_CHANNEL                             = BASE + 71;
+    /** @hide */
+    public static final int SET_CHANNEL_FAILED                      = BASE + 72;
+    /** @hide */
+    public static final int SET_CHANNEL_SUCCEEDED                   = BASE + 73;
+
+
     /**
      * Create a new WifiP2pManager instance. Applications use
      * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
@@ -667,6 +690,9 @@
                     case DELETE_PERSISTENT_GROUP_FAILED:
                     case SET_WFD_INFO_FAILED:
                     case START_WPS_FAILED:
+                    case START_LISTEN_FAILED:
+                    case STOP_LISTEN_FAILED:
+                    case SET_CHANNEL_FAILED:
                         if (listener != null) {
                             ((ActionListener) listener).onFailure(message.arg1);
                         }
@@ -689,6 +715,9 @@
                     case DELETE_PERSISTENT_GROUP_SUCCEEDED:
                     case SET_WFD_INFO_SUCCEEDED:
                     case START_WPS_SUCCEEDED:
+                    case START_LISTEN_SUCCEEDED:
+                    case STOP_LISTEN_SUCCEEDED:
+                    case SET_CHANNEL_SUCCEEDED:
                         if (listener != null) {
                             ((ActionListener) listener).onSuccess();
                         }
@@ -955,6 +984,22 @@
         c.mAsyncChannel.sendMessage(REMOVE_GROUP, 0, c.putListener(listener));
     }
 
+    /** @hide */
+    public void listen(Channel c, boolean enable, ActionListener listener) {
+        checkChannel(c);
+        c.mAsyncChannel.sendMessage(enable ? START_LISTEN : STOP_LISTEN,
+                0, c.putListener(listener));
+    }
+
+    /** @hide */
+    public void setWifiP2pChannels(Channel c, int lc, int oc, ActionListener listener) {
+        checkChannel(c);
+        Bundle p2pChannels = new Bundle();
+        p2pChannels.putInt("lc", lc);
+        p2pChannels.putInt("oc", oc);
+        c.mAsyncChannel.sendMessage(SET_CHANNEL, 0, c.putListener(listener), p2pChannels);
+    }
+
     /**
      * Start a Wi-Fi Protected Setup (WPS) session.
      *
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index 68a082a..625ffb8 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -48,6 +48,7 @@
 import android.net.wifi.p2p.nsd.WifiP2pServiceRequest;
 import android.net.wifi.p2p.nsd.WifiP2pServiceResponse;
 import android.os.Binder;
+import android.os.Bundle;
 import android.os.IBinder;
 import android.os.INetworkManagementService;
 import android.os.Handler;
@@ -173,6 +174,9 @@
     //   msg.obj  = StateMachine to send to when blocked
     public static final int BLOCK_DISCOVERY                 =   BASE + 15;
 
+    // set country code
+    public static final int SET_COUNTRY_CODE                =   BASE + 16;
+
     public static final int ENABLED                         = 1;
     public static final int DISABLED                        = 0;
 
@@ -628,6 +632,10 @@
                 case DhcpStateMachine.CMD_ON_QUIT:
                 case WifiMonitor.P2P_PROV_DISC_FAILURE_EVENT:
                 case SET_MIRACAST_MODE:
+                case WifiP2pManager.START_LISTEN:
+                case WifiP2pManager.STOP_LISTEN:
+                case WifiP2pManager.SET_CHANNEL:
+                case SET_COUNTRY_CODE:
                     break;
                 case WifiStateMachine.CMD_ENABLE_P2P:
                     // Enable is lazy and has no response
@@ -729,7 +737,16 @@
                     replyToMessage(message, WifiP2pManager.START_WPS_FAILED,
                             WifiP2pManager.P2P_UNSUPPORTED);
                     break;
-               default:
+                case WifiP2pManager.START_LISTEN:
+                    replyToMessage(message, WifiP2pManager.START_LISTEN_FAILED,
+                            WifiP2pManager.P2P_UNSUPPORTED);
+                    break;
+                case WifiP2pManager.STOP_LISTEN:
+                    replyToMessage(message, WifiP2pManager.STOP_LISTEN_FAILED,
+                            WifiP2pManager.P2P_UNSUPPORTED);
+                    break;
+
+                default:
                     return NOT_HANDLED;
             }
             return HANDLED;
@@ -858,7 +875,7 @@
                     }
                     if (mGroups.clear()) sendP2pPersistentGroupsChangedBroadcast();
 
-                    mWifiNative.closeSupplicantConnection();
+                    mWifiMonitor.stopMonitoring();
                     transitionTo(mP2pDisablingState);
                     break;
                 case WifiP2pManager.SET_DEVICE_NAME:
@@ -1022,6 +1039,39 @@
                 case SET_MIRACAST_MODE:
                     mWifiNative.setMiracastMode(message.arg1);
                     break;
+                case WifiP2pManager.START_LISTEN:
+                    if (DBG) logd(getName() + " start listen mode");
+                    mWifiNative.p2pFlush();
+                    if (mWifiNative.p2pExtListen(true, 500, 500)) {
+                        replyToMessage(message, WifiP2pManager.START_LISTEN_SUCCEEDED);
+                    } else {
+                        replyToMessage(message, WifiP2pManager.START_LISTEN_FAILED);
+                    }
+                    break;
+                case WifiP2pManager.STOP_LISTEN:
+                    if (DBG) logd(getName() + " stop listen mode");
+                    if (mWifiNative.p2pExtListen(false, 0, 0)) {
+                        replyToMessage(message, WifiP2pManager.STOP_LISTEN_SUCCEEDED);
+                    } else {
+                        replyToMessage(message, WifiP2pManager.STOP_LISTEN_FAILED);
+                    }
+                    mWifiNative.p2pFlush();
+                    break;
+                case WifiP2pManager.SET_CHANNEL:
+                    Bundle p2pChannels = (Bundle) message.obj;
+                    int lc = p2pChannels.getInt("lc", 0);
+                    int oc = p2pChannels.getInt("oc", 0);
+                    if (DBG) logd(getName() + " set listen and operating channel");
+                    if (mWifiNative.p2pSetChannel(lc, oc)) {
+                        replyToMessage(message, WifiP2pManager.SET_CHANNEL_SUCCEEDED);
+                    } else {
+                        replyToMessage(message, WifiP2pManager.SET_CHANNEL_FAILED);
+                    }
+                    break;
+                case SET_COUNTRY_CODE:
+                    String countryCode = (String) message.obj;
+                    mWifiNative.setCountryCode(countryCode);
+                    break;
                 default:
                    return NOT_HANDLED;
             }
@@ -1171,6 +1221,35 @@
                         mWifiNative.p2pGroupRemove(mGroup.getInterface());
                     }
                     break;
+                case WifiP2pManager.START_LISTEN:
+                    if (DBG) logd(getName() + " start listen mode");
+                    mWifiNative.p2pFlush();
+                    if (mWifiNative.p2pExtListen(true, 500, 500)) {
+                        replyToMessage(message, WifiP2pManager.START_LISTEN_SUCCEEDED);
+                    } else {
+                        replyToMessage(message, WifiP2pManager.START_LISTEN_FAILED);
+                    }
+                    break;
+                case WifiP2pManager.STOP_LISTEN:
+                    if (DBG) logd(getName() + " stop listen mode");
+                    if (mWifiNative.p2pExtListen(false, 0, 0)) {
+                        replyToMessage(message, WifiP2pManager.STOP_LISTEN_SUCCEEDED);
+                    } else {
+                        replyToMessage(message, WifiP2pManager.STOP_LISTEN_FAILED);
+                    }
+                    mWifiNative.p2pFlush();
+                    break;
+                case WifiP2pManager.SET_CHANNEL:
+                    Bundle p2pChannels = (Bundle) message.obj;
+                    int lc = p2pChannels.getInt("lc", 0);
+                    int oc = p2pChannels.getInt("oc", 0);
+                    if (DBG) logd(getName() + " set listen and operating channel");
+                    if (mWifiNative.p2pSetChannel(lc, oc)) {
+                        replyToMessage(message, WifiP2pManager.SET_CHANNEL_SUCCEEDED);
+                    } else {
+                        replyToMessage(message, WifiP2pManager.SET_CHANNEL_FAILED);
+                    }
+                    break;
                 default:
                     return NOT_HANDLED;
             }
@@ -2466,6 +2545,12 @@
         mServiceTransactionId = 0;
         mServiceDiscReqId = null;
 
+        String countryCode = Settings.Global.getString(mContext.getContentResolver(),
+                Settings.Global.WIFI_COUNTRY_CODE);
+        if (countryCode != null && !countryCode.isEmpty()) {
+            mP2pStateMachine.sendMessage(SET_COUNTRY_CODE, countryCode);
+        }
+
         updatePersistentNetworks(RELOAD);
     }
 
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
index 1ba991e..d65d03e 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pWfdInfo.java
@@ -19,6 +19,8 @@
 import android.os.Parcelable;
 import android.os.Parcel;
 
+import java.util.Locale;
+
 /**
  * A class representing Wifi Display information for a device
  * @hide
@@ -135,7 +137,8 @@
     }
 
     public String getDeviceInfoHex() {
-        return String.format("%04x%04x%04x%04x", 6, mDeviceInfo, mCtrlPort, mMaxThroughput);
+        return String.format(
+                Locale.US, "%04x%04x%04x%04x", 6, mDeviceInfo, mCtrlPort, mMaxThroughput);
     }
 
     public String toString() {
diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java
index 9879d4e..a4118dc 100644
--- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java
+++ b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pDnsSdServiceInfo.java
@@ -127,7 +127,7 @@
         sb.append(" ");
 
         byte[] data = instanceName.getBytes();
-        sb.append(String.format("%02x", data.length));
+        sb.append(String.format(Locale.US, "%02x", data.length));
         sb.append(WifiP2pServiceInfo.bin2HexStr(data));
         // This is the start point of this response.
         // Therefore, it indicates the request domain name.
@@ -187,8 +187,8 @@
             dnsName = dnsName.toLowerCase(Locale.ROOT); // TODO: is this right?
         }
         sb.append(compressDnsName(dnsName));
-        sb.append(String.format("%04x", dnsType));
-        sb.append(String.format("%02x", version));
+        sb.append(String.format(Locale.US, "%04x", dnsType));
+        sb.append(String.format(Locale.US, "%02x", version));
 
         return sb.toString();
     }
@@ -215,7 +215,7 @@
             int i = dnsName.indexOf('.');
             if (i == -1) {
                 if (dnsName.length() > 0) {
-                    sb.append(String.format("%02x", dnsName.length()));
+                    sb.append(String.format(Locale.US, "%02x", dnsName.length()));
                     sb.append(WifiP2pServiceInfo.bin2HexStr(dnsName.getBytes()));
                 }
                 // for a sequence of labels ending in a zero octet
@@ -225,7 +225,7 @@
 
             String name = dnsName.substring(0, i);
             dnsName = dnsName.substring(i + 1);
-            sb.append(String.format("%02x", name.length()));
+            sb.append(String.format(Locale.US, "%02x", name.length()));
             sb.append(WifiP2pServiceInfo.bin2HexStr(name.getBytes()));
         }
         return sb.toString();
diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java
index eabd8e5..7462b85c 100644
--- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java
+++ b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceRequest.java
@@ -136,10 +136,10 @@
     public String getSupplicantQuery() {
         StringBuffer sb = new StringBuffer();
         // length is retained as little endian format.
-        sb.append(String.format("%02x", (mLength) & 0xff));
-        sb.append(String.format("%02x", (mLength >> 8) & 0xff));
-        sb.append(String.format("%02x", mProtocolType));
-        sb.append(String.format("%02x", mTransId));
+        sb.append(String.format(Locale.US, "%02x", (mLength) & 0xff));
+        sb.append(String.format(Locale.US, "%02x", (mLength >> 8) & 0xff));
+        sb.append(String.format(Locale.US, "%02x", mProtocolType));
+        sb.append(String.format(Locale.US, "%02x", mTransId));
         if (mQuery != null) {
             sb.append(mQuery);
         }
diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceInfo.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceInfo.java
index 40a0d61..a4cdfd9 100644
--- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceInfo.java
+++ b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceInfo.java
@@ -18,6 +18,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Locale;
 import java.util.UUID;
 
 /**
@@ -98,7 +99,7 @@
     private static String createSupplicantQuery(String uuid, String data) {
         StringBuffer sb = new StringBuffer();
         sb.append("upnp ");
-        sb.append(String.format("%02x ", VERSION_1_0));
+        sb.append(String.format(Locale.US, "%02x ", VERSION_1_0));
         sb.append("uuid:");
         sb.append(uuid);
         if (data != null) {
diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceRequest.java b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceRequest.java
index b5cf144..98e447e 100644
--- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceRequest.java
+++ b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pUpnpServiceRequest.java
@@ -18,6 +18,8 @@
 
 import android.net.wifi.p2p.WifiP2pManager;
 
+import java.util.Locale;
+
 /**
  * A class for creating a Upnp service discovery request for use with
  * {@link WifiP2pManager#addServiceRequest} and {@link WifiP2pManager#removeServiceRequest}
@@ -73,7 +75,7 @@
             throw new IllegalArgumentException("search target cannot be null");
         }
         StringBuffer sb = new StringBuffer();
-        sb.append(String.format("%02x", WifiP2pUpnpServiceInfo.VERSION_1_0));
+        sb.append(String.format(Locale.US, "%02x", WifiP2pUpnpServiceInfo.VERSION_1_0));
         sb.append(WifiP2pServiceInfo.bin2HexStr(st.getBytes()));
         return new WifiP2pUpnpServiceRequest(sb.toString());
     }